From 01a3d9823ea07a748b902b66177de7cc58333c99 Mon Sep 17 00:00:00 2001 From: Lukas Hering Date: Sat, 7 Nov 2026 23:15:56 -0500 Subject: [PATCH 1/5] scaffolding --- agent/opentelemetry-agent/README.rst | 0 agent/opentelemetry-agent/pyproject.toml | 51 +++++++++++++++++++ .../src/opentelemetry/agent/__init__.py | 0 .../opentelemetry/agent/_vendor/README.rst | 0 .../agent/_vendor/requirements.txt | 12 +++++ .../src/opentelemetry/agent/version.py | 4 ++ agent/opentelemetry-agent/vendor.in | 1 + agent/opentelemetry-vendor/README.rst | 0 agent/opentelemetry-vendor/pyproject.toml | 44 ++++++++++++++++ .../src/opentelemetry/vendor/__init__.py | 0 .../src/opentelemetry/vendor/cli.py | 3 ++ pyproject.toml | 4 ++ uv.lock | 15 +++++- 13 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 agent/opentelemetry-agent/README.rst create mode 100644 agent/opentelemetry-agent/pyproject.toml create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/README.rst create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/version.py create mode 100644 agent/opentelemetry-agent/vendor.in create mode 100644 agent/opentelemetry-vendor/README.rst create mode 100644 agent/opentelemetry-vendor/pyproject.toml create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/__init__.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py diff --git a/agent/opentelemetry-agent/README.rst b/agent/opentelemetry-agent/README.rst new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/pyproject.toml b/agent/opentelemetry-agent/pyproject.toml new file mode 100644 index 00000000000..2eff4b058ef --- /dev/null +++ b/agent/opentelemetry-agent/pyproject.toml @@ -0,0 +1,51 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-agent" +dynamic = ["version"] +description = "OpenTelemetry Python Agent" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.10" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Framework :: OpenTelemetry", + "Intended Audience :: Developers", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", +] +dependencies = [] + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/agent/opentelemetry-agent" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" + +[tool.opentelemetry-vendor] +destination = "src/opentelemetry/agent/_vendor/" +requirements = "src/opentelemetry/agent/_vendor/requirements.txt" +namespace = "opentelemetry.agent._vendor" +protected-files = ["__init__.py", "README.rst", "requirements.txt"] +patches-dir = "patches" +sbom-file = "src/opentelemetry/agent/_vendor/bom.cdx.json" + +[tool.hatch.version] +path = "src/opentelemetry/agent/version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/README.rst b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/README.rst new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt new file mode 100644 index 00000000000..b2a8820999b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt @@ -0,0 +1,12 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --python 3.10 --universal vendor.in -o src/opentelemetry/agent/_vendor/requirements.txt +certifi==2026.10.23 + # via requests +charset-normalizer==3.5.2 + # via requests +idna==3.20 + # via requests +requests==2.34.2 + # via -r vendor.in +urllib3==2.8.0 + # via requests diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/version.py new file mode 100644 index 00000000000..b83363231d3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/version.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.67b0.dev" diff --git a/agent/opentelemetry-agent/vendor.in b/agent/opentelemetry-agent/vendor.in new file mode 100644 index 00000000000..f2293605cf1 --- /dev/null +++ b/agent/opentelemetry-agent/vendor.in @@ -0,0 +1 @@ +requests diff --git a/agent/opentelemetry-vendor/README.rst b/agent/opentelemetry-vendor/README.rst new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-vendor/pyproject.toml b/agent/opentelemetry-vendor/pyproject.toml new file mode 100644 index 00000000000..40bf6d2ba76 --- /dev/null +++ b/agent/opentelemetry-vendor/pyproject.toml @@ -0,0 +1,44 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-vendor" +version = "0.0.0" # Not published to PyPI +description = "An internal CLI tool for vendoring packages for OpenTelemetry Python" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.10" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Framework :: OpenTelemetry", + "Intended Audience :: Developers", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Private :: Do Not Upload", +] +dependencies = [ +] + +[project.scripts] +opentelemetry-vendor = "opentelemetry.vendor.cli:main" + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-vendor" +Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/__init__.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py new file mode 100644 index 00000000000..04f5d1fe172 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py @@ -0,0 +1,3 @@ + +def main() -> None: + print("Hello world") \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index eb2b5d5f46c..c3d911c381b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ dependencies = [ "opentelemetry-util-genai", "opentelemetry-instrumentation-vertexai[instruments]", "opentelemetry-instrumentation-openai-v2[instruments]", + "opentelemetry-vendor", ] @@ -138,6 +139,8 @@ opentelemetry-util-http = { workspace = true } opentelemetry-util-genai = { workspace = true } opentelemetry-instrumentation-vertexai = { workspace = true } opentelemetry-instrumentation-openai-v2 = { workspace = true } +opentelemetry-vendor = { workspace = true } +opentelemetry-agent = { workspace = true } # https://docs.astral.sh/uv/reference/settings/#workspace [tool.uv.workspace] @@ -149,6 +152,7 @@ members = [ "opentelemetry-distro", "propagator/*", "util/*", + "agent/*", ] [tool.ruff] diff --git a/uv.lock b/uv.lock index 516cff18b11..90b62418aa0 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 5 +revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.14'", @@ -11,6 +11,7 @@ resolution-markers = [ [manifest] members = [ + "opentelemetry-agent", "opentelemetry-distro", "opentelemetry-exporter-credential-provider-gcp", "opentelemetry-exporter-prometheus-remote-write", @@ -76,6 +77,7 @@ members = [ "opentelemetry-python-contrib", "opentelemetry-util-genai", "opentelemetry-util-http", + "opentelemetry-vendor", ] [[package]] @@ -2804,6 +2806,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1e/2e/2e96ca6928951fe1d16744c22dc1355eda1dd5b0dd920ca1d3ab602929f8/openai_agents-0.17.7-py3-none-any.whl", hash = "sha256:51b5ae43756eea37032e430f95979ba3999af6b1ade397df6c0ffeaf1939646a", size = 856074, upload-time = "2026-06-24T05:15:31.741Z" }, ] +[[package]] +name = "opentelemetry-agent" +source = { editable = "agent/opentelemetry-agent" } + [[package]] name = "opentelemetry-api" version = "1.44.0.dev0" @@ -4392,6 +4398,7 @@ dependencies = [ { name = "opentelemetry-test-utils" }, { name = "opentelemetry-util-genai" }, { name = "opentelemetry-util-http" }, + { name = "opentelemetry-vendor" }, ] [package.dev-dependencies] @@ -4485,6 +4492,7 @@ requires-dist = [ { name = "opentelemetry-test-utils", git = "https://github.com/open-telemetry/opentelemetry-python?subdirectory=tests%2Fopentelemetry-test-utils&branch=main" }, { name = "opentelemetry-util-genai", editable = "util/opentelemetry-util-genai" }, { name = "opentelemetry-util-http", editable = "util/opentelemetry-util-http" }, + { name = "opentelemetry-vendor", editable = "agent/opentelemetry-vendor" }, ] [package.metadata.requires-dev] @@ -4571,6 +4579,11 @@ provides-extras = ["test", "upload"] name = "opentelemetry-util-http" source = { editable = "util/opentelemetry-util-http" } +[[package]] +name = "opentelemetry-vendor" +version = "0.0.0" +source = { editable = "agent/opentelemetry-vendor" } + [[package]] name = "packaging" version = "26.3" From 4c8d863980266b264d3ab38ab776c7e196704e75 Mon Sep 17 00:00:00 2001 From: Lukas Hering Date: Sun, 8 Nov 2026 00:10:45 -0500 Subject: [PATCH 2/5] stash --- agent/opentelemetry-agent/pyproject.toml | 19 ++ agent/opentelemetry-vendor/pyproject.toml | 6 + .../src/opentelemetry/vendor/cli.py | 70 ++++- .../src/opentelemetry/vendor/config.py | 106 ++++++++ .../src/opentelemetry/vendor/download.py | 96 +++++++ .../src/opentelemetry/vendor/errors.py | 8 + .../src/opentelemetry/vendor/metadata.py | 131 ++++++++++ .../src/opentelemetry/vendor/output.py | 68 +++++ .../src/opentelemetry/vendor/sbom.py | 63 +++++ .../src/opentelemetry/vendor/sync.py | 130 ++++++++++ agent/opentelemetry-vendor/tests/__init__.py | 0 agent/opentelemetry-vendor/tests/conftest.py | 28 ++ agent/opentelemetry-vendor/tests/helpers.py | 48 ++++ agent/opentelemetry-vendor/tests/test_cli.py | 171 +++++++++++++ .../opentelemetry-vendor/tests/test_config.py | 98 +++++++ .../tests/test_download.py | 128 ++++++++++ .../tests/test_metadata.py | 152 +++++++++++ agent/opentelemetry-vendor/tests/test_sbom.py | 62 +++++ agent/opentelemetry-vendor/tests/test_sync.py | 92 +++++++ uv.lock | 240 ++++++++++++++++++ 20 files changed, 1715 insertions(+), 1 deletion(-) create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/errors.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/output.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py create mode 100644 agent/opentelemetry-vendor/tests/__init__.py create mode 100644 agent/opentelemetry-vendor/tests/conftest.py create mode 100644 agent/opentelemetry-vendor/tests/helpers.py create mode 100644 agent/opentelemetry-vendor/tests/test_cli.py create mode 100644 agent/opentelemetry-vendor/tests/test_config.py create mode 100644 agent/opentelemetry-vendor/tests/test_download.py create mode 100644 agent/opentelemetry-vendor/tests/test_metadata.py create mode 100644 agent/opentelemetry-vendor/tests/test_sbom.py create mode 100644 agent/opentelemetry-vendor/tests/test_sync.py diff --git a/agent/opentelemetry-agent/pyproject.toml b/agent/opentelemetry-agent/pyproject.toml index 2eff4b058ef..143d4c21579 100644 --- a/agent/opentelemetry-agent/pyproject.toml +++ b/agent/opentelemetry-agent/pyproject.toml @@ -34,7 +34,26 @@ Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" destination = "src/opentelemetry/agent/_vendor/" requirements = "src/opentelemetry/agent/_vendor/requirements.txt" namespace = "opentelemetry.agent._vendor" +python-version = "3.10" protected-files = ["__init__.py", "README.rst", "requirements.txt"] +drop = [ + # Typing markers, tests and CLI entry points aren't used by the agent. + "**/py.typed", + "**/__main__.py", + "certifi/tests", + "charset_normalizer/cli", + "idna/cli.py", + # Debug-report helper (`python -m requests.help`); imports pyOpenSSL/cryptography. + "requests/help.py", + # Optional urllib3 integrations that would import the user's packages. Their imports are + # guarded: SOCKS proxies raise InvalidSchema in requests (no PySocks), pyOpenSSL is only + # used without SNI, emscripten only on Pyodide, and HTTP/2 (h2) only after an explicit + # urllib3.http2.inject_into_urllib3(). + "urllib3/contrib/socks.py", + "urllib3/contrib/pyopenssl.py", + "urllib3/contrib/emscripten", + "urllib3/http2/connection.py", +] patches-dir = "patches" sbom-file = "src/opentelemetry/agent/_vendor/bom.cdx.json" diff --git a/agent/opentelemetry-vendor/pyproject.toml b/agent/opentelemetry-vendor/pyproject.toml index 40bf6d2ba76..997b760121c 100644 --- a/agent/opentelemetry-vendor/pyproject.toml +++ b/agent/opentelemetry-vendor/pyproject.toml @@ -26,6 +26,12 @@ classifiers = [ "Private :: Do Not Upload", ] dependencies = [ + "cyclonedx-python-lib[json-validation] >= 11.0, < 12.0", + "packageurl-python >= 0.11, < 1.0", + "pip >= 25.0, < 27.0", + "rich >= 13.0, < 16.0", + "typer >= 0.15, < 1.0", + "tomli >= 2.0, < 3.0; python_version < '3.11'", ] [project.scripts] diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py index 04f5d1fe172..3959627bab3 100644 --- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py @@ -1,3 +1,71 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from pathlib import Path +from typing import Annotated, NoReturn + +import typer + +from opentelemetry.vendor import output +from opentelemetry.vendor import sync as _sync +from opentelemetry.vendor.config import load_config +from opentelemetry.vendor.errors import VendorError + +app = typer.Typer(no_args_is_help=True) + +ProjectDir = Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=False, + resolve_path=True, + help="Directory containing the pyproject.toml to vendor for.", + ), +] +Quiet = Annotated[bool, typer.Option("--quiet", "-q", help="Only print errors.")] +Verbose = Annotated[ + bool, + typer.Option("--verbose", "-v", help="Show pip output and every file removed."), +] + + +@app.callback() +def _callback() -> None: + """Vendor third-party packages into an OpenTelemetry Python package.""" + + +@app.command() +def sync(project_dir: ProjectDir, quiet: Quiet = False, verbose: Verbose = False) -> None: + """Sync the vendored packages of PROJECT_DIR.""" + _configure_output(quiet, verbose) + try: + _sync.sync(load_config(project_dir)) + except VendorError as exc: + _fail(exc) + + +@app.command() +def clean(project_dir: ProjectDir, quiet: Quiet = False, verbose: Verbose = False) -> None: + """Remove vendored packages from PROJECT_DIR, keeping protected files.""" + _configure_output(quiet, verbose) + try: + _sync.clean(load_config(project_dir)) + except VendorError as exc: + _fail(exc) + + +def _configure_output(quiet: bool, verbose: bool) -> None: + if quiet and verbose: + raise typer.BadParameter("--quiet and --verbose cannot be used together") + output.configure(quiet=quiet, verbose=verbose) + + +def _fail(exc: VendorError) -> NoReturn: + typer.echo(f"error: {exc}", err=True) + raise typer.Exit(code=1) from exc + def main() -> None: - print("Hello world") \ No newline at end of file + app() diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py new file mode 100644 index 00000000000..aed98483189 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py @@ -0,0 +1,106 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Loading of the ``[tool.opentelemetry-vendor]`` configuration table.""" + +from __future__ import annotations + +import sys +from collections.abc import Collection, Mapping +from dataclasses import dataclass +from pathlib import Path, PurePosixPath +from typing import Any + +from opentelemetry.vendor.errors import VendorError + +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + +_PYPROJECT = "pyproject.toml" +_TOOL_NAME = "opentelemetry-vendor" + + +class ConfigError(VendorError): + """Raised when the vendoring configuration is missing or invalid.""" + + +@dataclass(frozen=True) +class VendorConfig: + project_dir: Path + destination: Path + requirements: Path + namespace: str + python_version: str + protected_files: Collection[str] + drop: Collection[str] + patches_dir: Path | None + sbom_file: Path | None + + +def load_config(project_dir: Path) -> VendorConfig: + """Read and validate ``[tool.opentelemetry-vendor]`` from ``project_dir``.""" + project_dir = project_dir.resolve() + pyproject = project_dir / _PYPROJECT + try: + with pyproject.open("rb") as file: + data = tomllib.load(file) + except FileNotFoundError as exc: + raise ConfigError(f"{pyproject} does not exist") from exc + except tomllib.TOMLDecodeError as exc: + raise ConfigError(f"{pyproject} is not valid TOML: {exc}") from exc + + table = data.get("tool", {}).get(_TOOL_NAME) + if not isinstance(table, dict): + raise ConfigError(f"{pyproject} has no [tool.{_TOOL_NAME}] table") + + destination = (project_dir / _require_str(table, "destination")).resolve() + if destination == project_dir or not destination.is_relative_to(project_dir): + raise ConfigError(f"'destination' must be a directory inside {project_dir}, got {destination}") + + patches_dir = _optional_str(table, "patches-dir") + sbom_file = _optional_str(table, "sbom-file") + return VendorConfig( + project_dir=project_dir, + destination=destination, + requirements=project_dir / _require_str(table, "requirements"), + namespace=_require_str(table, "namespace"), + python_version=_optional_str(table, "python-version") or f"{sys.version_info.major}.{sys.version_info.minor}", + protected_files=_str_list(table, "protected-files"), + drop=_drop_patterns(table), + patches_dir=project_dir / patches_dir if patches_dir else None, + sbom_file=project_dir / sbom_file if sbom_file else None, + ) + + +def _require_str(table: Mapping[str, Any], key: str) -> str: + value = _optional_str(table, key) + if value is None: + raise ConfigError(f"missing required key '{key}'") + return value + + +def _optional_str(table: Mapping[str, Any], key: str) -> str | None: + value = table.get(key) + if value is None: + return None + if not isinstance(value, str) or not value: + raise ConfigError(f"'{key}' must be a non-empty string") + return value + + +def _drop_patterns(table: Mapping[str, Any]) -> tuple[str, ...]: + patterns = _str_list(table, "drop") + for pattern in patterns: + path = PurePosixPath(pattern) + if not pattern or path.is_absolute() or ".." in path.parts: + raise ConfigError(f"'drop' pattern {pattern!r} must be relative to destination") + return patterns + + +def _str_list(table: Mapping[str, Any], key: str) -> tuple[str, ...]: + value = table.get(key, []) + if not isinstance(value, list) or not all(isinstance(item, str) for item in value): + raise ConfigError(f"'{key}' must be a list of strings") + return tuple(value) diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py new file mode 100644 index 00000000000..0ce89573bba --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py @@ -0,0 +1,96 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Download pure-Python wheels and unpack them into the vendor directory.""" + +from __future__ import annotations + +import subprocess +import sys +import zipfile +from collections.abc import Collection +from pathlib import Path + +from opentelemetry.vendor import output +from opentelemetry.vendor.errors import VendorError + + +class DownloadError(VendorError): + """Raised when downloading or unpacking vendored packages fails.""" + + +def download_wheels(requirements: Path, python_version: str, dest: Path) -> list[Path]: + """Download a pure-Python wheel for each requirement, without dependencies. + + Only ``py3-none-any`` style wheels are accepted so compiled extensions + (which cannot be rewritten into the vendor namespace) are never vendored. + """ + result = subprocess.run( + [ + sys.executable, + "-m", + "pip", + "download", + "--no-deps", + "--only-binary=:all:", + "--platform", + "any", + "--implementation", + "py", + "--abi", + "none", + "--python-version", + python_version, + "--disable-pip-version-check", + "--dest", + str(dest), + "-r", + str(requirements), + ], + capture_output=True, + text=True, + check=False, + ) + if result.returncode != 0: + raise DownloadError( + f"pip download failed (exit code {result.returncode}). Every " + "requirement must have a pure-Python (py3-none-any) wheel.\n" + f"{result.stderr.strip()}" + ) + output.detail(result.stdout.strip()) + wheels = sorted(dest.glob("*.whl")) + for wheel in wheels: + _check_pure_python(wheel) + return wheels + + +def _check_pure_python(wheel: Path) -> None: + # Wheel filenames end in {python tag}-{abi tag}-{platform tag}.whl + _, abi_tag, platform_tag = wheel.stem.rsplit("-", 3)[-3:] + if abi_tag != "none" or platform_tag != "any": + raise DownloadError(f"{wheel.name} is not a pure-Python wheel") + + +def unpack_wheels(wheels: Collection[Path], destination: Path) -> dict[Path, Path]: + """Extract ``wheels`` into ``destination``, refusing to overwrite files. + + Returns a mapping of each wheel to its unpacked ``*.dist-info`` directory. + """ + destination.mkdir(parents=True, exist_ok=True) + dist_infos: dict[Path, Path] = {} + for wheel in wheels: + with zipfile.ZipFile(wheel) as archive: + dist_info_names = { + top for top in (name.split("/", 1)[0] for name in archive.namelist()) if top.endswith(".dist-info") + } + if len(dist_info_names) != 1: + raise DownloadError( + f"{wheel.name} must contain exactly one .dist-info directory, found {sorted(dist_info_names)}" + ) + dist_infos[wheel] = destination / dist_info_names.pop() + for member in archive.infolist(): + target = destination / member.filename + if not member.is_dir() and target.exists(): + raise DownloadError(f"{wheel.name} would overwrite {target}") + archive.extract(member, destination) + return dist_infos diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/errors.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/errors.py new file mode 100644 index 00000000000..d2ea3e1e5f4 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/errors.py @@ -0,0 +1,8 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + + +class VendorError(Exception): + """Base class for errors reported to the user by ``opentelemetry-vendor``.""" diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py new file mode 100644 index 00000000000..3450a08da58 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py @@ -0,0 +1,131 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Collect metadata from unpacked ``*.dist-info`` directories.""" + +from __future__ import annotations + +import hashlib +import re +import shutil +from collections.abc import Collection, Mapping +from dataclasses import dataclass +from importlib.metadata import PathDistribution +from pathlib import Path + +from opentelemetry.vendor.errors import VendorError + +_LICENSE_FILE_PATTERN = re.compile(r"^(LICEN[CS]E|COPYING|NOTICE|AUTHORS)", re.IGNORECASE) +_LICENSE_CLASSIFIER_PREFIX = "License :: " + + +@dataclass(frozen=True) +class VendoredPackage: + name: str + """Canonical (PEP 503) distribution name.""" + version: str + sha256: str + """SHA-256 of the downloaded wheel.""" + license_expression: str | None + top_level_names: Collection[str] + """Top-level importable module and package names.""" + license_files: Mapping[str, Path] + """Vendored license file name -> source file inside ``dist_info``.""" + dist_info: Path + + +def read_package(wheel: Path, dist_info: Path) -> VendoredPackage: + """Read the metadata needed for vendoring from an unpacked dist-info.""" + distribution = PathDistribution(dist_info) + metadata = distribution.metadata + name = _canonicalize_name(metadata["Name"]) + return VendoredPackage( + name=name, + version=metadata["Version"], + sha256=hashlib.sha256(wheel.read_bytes()).hexdigest(), + license_expression=_license_expression( + metadata.get("License-Expression"), + metadata.get("License"), + metadata.get_all("Classifier") or [], + ), + top_level_names=_top_level_names(distribution, dist_info), + license_files=_license_files(name, dist_info, metadata.get_all("License-File") or []), + dist_info=dist_info, + ) + + +def copy_license_files(packages: Collection[VendoredPackage], destination: Path) -> None: + """Copy every package's license files into ``destination``.""" + for package in packages: + for target_name, source in package.license_files.items(): + target = destination / target_name + if target.exists(): + raise VendorError(f"license file {target} for {package.name} already exists") + shutil.copyfile(source, target) + + +def remove_dist_info(packages: Collection[VendoredPackage]) -> None: + for package in packages: + shutil.rmtree(package.dist_info) + + +def _canonicalize_name(name: str) -> str: + return re.sub(r"[-_.]+", "-", name).lower() + + +def _license_expression(expression: str | None, license_field: str | None, classifiers: Collection[str]) -> str | None: + if expression: + return expression.strip() + # The legacy License field sometimes holds the full license text. + if license_field and "\n" not in license_field.strip(): + return license_field.strip() + names = [ + classifier.rsplit(" :: ", 1)[-1] + for classifier in classifiers + if classifier.startswith(_LICENSE_CLASSIFIER_PREFIX) + ] + return " OR ".join(names) if names else None + + +def _top_level_names(distribution: PathDistribution, dist_info: Path) -> tuple[str, ...]: + files = distribution.files + if files is None: + raise VendorError(f"{dist_info.name} has no RECORD file") + names: set[str] = set() + for file in files: + top = file.parts[0] + if top == ".." or top.endswith((".dist-info", ".data")): + continue + if top == "__pycache__": + continue + if len(file.parts) == 1: + if not top.endswith(".py"): + continue + top = top.removesuffix(".py") + if top.isidentifier(): + names.add(top) + return tuple(sorted(names)) + + +def _license_files(name: str, dist_info: Path, declared: Collection[str]) -> dict[str, Path]: + sources: dict[str, Path] = {} + if declared: + # PEP 639 puts License-File paths under .dist-info/licenses/; older + # tools put them directly in .dist-info/. + for relative in declared: + for base in (dist_info / "licenses", dist_info): + if (base / relative).is_file(): + sources[relative] = base / relative + break + else: + raise VendorError(f"{dist_info.name} declares missing license file {relative}") + else: + for path in sorted(dist_info.rglob("*")): + if path.is_file() and _LICENSE_FILE_PATTERN.match(path.name): + base = dist_info / "licenses" + if not path.is_relative_to(base): + base = dist_info + sources[path.relative_to(base).as_posix()] = path + if not sources: + raise VendorError(f"{dist_info.name} does not contain a license file") + return {f"{name}.{relative.replace('/', '.')}": path for relative, path in sources.items()} diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/output.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/output.py new file mode 100644 index 00000000000..99c69f999e8 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/output.py @@ -0,0 +1,68 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Progress output for the ``opentelemetry-vendor`` commands.""" + +from __future__ import annotations + +from collections.abc import Collection +from dataclasses import dataclass + +from rich.console import Console +from rich.markup import escape +from rich.status import Status +from rich.table import Table + +from opentelemetry.vendor.metadata import VendoredPackage + +# Progress goes to stderr so stdout stays clean for future machine-readable output. +_console = Console(stderr=True, highlight=False) + + +@dataclass +class _Settings: + verbose: bool = False + + +_settings = _Settings() + + +def configure(*, quiet: bool, verbose: bool) -> None: + _console.quiet = quiet + _settings.verbose = verbose + + +def step(message: str) -> None: + """Report a completed step.""" + _console.print(f"[green]✔[/] {escape(message)}") + + +def detail(message: str) -> None: + """Report a detail, only shown with ``--verbose``.""" + if _settings.verbose: + for line in message.splitlines(): + _console.print(f" [dim]{escape(line)}[/]", soft_wrap=True) + + +def status(message: str) -> Status: + """A spinner shown while a long-running step is in progress.""" + return _console.status(escape(message)) + + +def package_table(packages: Collection[VendoredPackage]) -> None: + table = Table("Package", "Version", "License", "Modules", box=None) + for package in sorted(packages, key=lambda package: package.name): + table.add_row( + package.name, + package.version, + package.license_expression or "-", + ", ".join(package.top_level_names), + ) + _console.print() + _console.print(table) + + +def plural(count: int, singular: str, plural_form: str | None = None) -> str: + if count == 1: + return f"{count} {singular}" + return f"{count} {plural_form or singular + 's'}" diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py new file mode 100644 index 00000000000..bb13f384ee3 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py @@ -0,0 +1,63 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Generate a CycloneDX SBOM for the vendored packages.""" + +from __future__ import annotations + +import json +import uuid +from collections.abc import Collection +from pathlib import Path + +from cyclonedx.contrib.license.factories import LicenseFactory +from cyclonedx.model import HashAlgorithm, HashType +from cyclonedx.model.bom import Bom +from cyclonedx.model.component import Component, ComponentType +from cyclonedx.output.json import JsonV1Dot6 +from cyclonedx.schema import SchemaVersion +from cyclonedx.validation.json import JsonStrictValidator +from packageurl import PackageURL + +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.metadata import VendoredPackage + + +def write_sbom(packages: Collection[VendoredPackage], path: Path) -> None: + """Write a CycloneDX 1.6 JSON SBOM describing ``packages`` to ``path``. + + The output is deterministic: syncing the same requirements twice produces + an identical file. + """ + ordered = sorted(packages, key=lambda package: package.name) + license_factory = LicenseFactory() + components = [_component(package, license_factory) for package in ordered] + identity = "\n".join(f"{package.name} {package.version} {package.sha256}" for package in ordered) + bom = Bom( + components=components, + serial_number=uuid.uuid5(uuid.NAMESPACE_URL, identity), + ) + + document = json.loads(JsonV1Dot6(bom).output_as_string()) + # The timestamp is optional; dropping it keeps re-syncs diff-free. + document["metadata"].pop("timestamp", None) + output = json.dumps(document, indent=2) + "\n" + + error = JsonStrictValidator(SchemaVersion.V1_6).validate_str(output) + if error is not None: + raise VendorError(f"generated SBOM is invalid: {error}") + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(output) + + +def _component(package: VendoredPackage, license_factory: LicenseFactory) -> Component: + purl = PackageURL(type="pypi", name=package.name, version=package.version) + return Component( + type=ComponentType.LIBRARY, + name=package.name, + version=package.version, + purl=purl, + bom_ref=purl.to_string(), + hashes=[HashType(alg=HashAlgorithm.SHA_256, content=package.sha256)], + licenses=[license_factory.make_from_string(package.license_expression)] if package.license_expression else None, + ) diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py new file mode 100644 index 00000000000..191017bc8cf --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py @@ -0,0 +1,130 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""The ``sync`` command: (re)populate a project's vendor directory.""" + +from __future__ import annotations + +import shutil +import tempfile +from collections.abc import Collection +from pathlib import Path + +from opentelemetry.vendor import output +from opentelemetry.vendor.config import VendorConfig +from opentelemetry.vendor.download import download_wheels, unpack_wheels +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.metadata import ( + VendoredPackage, + copy_license_files, + read_package, + remove_dist_info, +) +from opentelemetry.vendor.sbom import write_sbom + + +def clean_destination(destination: Path, protected_files: Collection[str]) -> list[Path]: + """Remove everything in ``destination`` except top-level ``protected_files``. + + Returns the removed entries. + """ + destination.mkdir(parents=True, exist_ok=True) + removed = [] + for entry in sorted(destination.iterdir()): + if entry.name in protected_files: + continue + _remove(entry, destination) + removed.append(entry) + return removed + + +def drop_paths(destination: Path, patterns: Collection[str]) -> list[Path]: + """Remove files and directories in ``destination`` matching glob ``patterns``. + + Matches inside top-level ``*.dist-info`` directories are ignored, and a + pattern that matches nothing is an error so stale config is noticed. + Returns the removed paths. + """ + matches: set[Path] = set() + for pattern in patterns: + matched = { + path + for path in destination.glob(pattern) + if not path.relative_to(destination).parts[0].endswith(".dist-info") + } + if not matched: + raise VendorError(f"drop pattern {pattern!r} matched nothing") + matches |= matched + + removed = [] + for path in sorted(matches): + # Already gone when an ancestor directory was dropped. + if any(parent in matches for parent in path.parents): + continue + _remove(path, destination) + removed.append(path) + return removed + + +def clean(config: VendorConfig) -> None: + """Empty ``config.destination``, keeping protected files.""" + removed = clean_destination(config.destination, config.protected_files) + entries = output.plural(len(removed), "entry", "entries") + output.step(f"Cleaned {_display(config.destination, config)} ({entries} removed)") + + +def sync(config: VendorConfig) -> list[VendoredPackage]: + """Re-vendor ``config``'s requirements and return the vendored packages.""" + destination = config.destination + clean(config) + + with tempfile.TemporaryDirectory() as tmp: + count = _count_requirements(config.requirements) + with output.status(f"Downloading {output.plural(count, 'requirement')}…"): + wheels = download_wheels(config.requirements, config.python_version, Path(tmp)) + output.step(f"Downloaded {output.plural(len(wheels), 'wheel')}") + + dist_infos = unpack_wheels(wheels, destination) + packages = [read_package(wheel, dist_info) for wheel, dist_info in dist_infos.items()] + output.step(f"Unpacked {output.plural(len(packages), 'wheel')}") + + if config.drop: + dropped = drop_paths(destination, config.drop) + output.step(f"Dropped {output.plural(len(dropped), 'path')}") + + copy_license_files(packages, destination) + license_count = sum(len(package.license_files) for package in packages) + output.step(f"Copied {output.plural(license_count, 'license file')}") + + if config.sbom_file is not None: + write_sbom(packages, config.sbom_file) + output.step(f"Wrote SBOM {_display(config.sbom_file, config)}") + + remove_dist_info(packages) + output.package_table(packages) + return packages + + +def _remove(path: Path, destination: Path) -> None: + display = path.relative_to(destination).as_posix() + if path.is_dir() and not path.is_symlink(): + shutil.rmtree(path) + display += "/" + else: + path.unlink() + output.detail(f"removed {display}") + + +def _display(path: Path, config: VendorConfig) -> str: + if path.is_relative_to(config.project_dir): + return path.relative_to(config.project_dir).as_posix() + return str(path) + + +def _count_requirements(requirements: Path) -> int: + try: + text = requirements.read_text() + except FileNotFoundError as exc: + raise VendorError(f"requirements file {requirements} does not exist") from exc + lines = (line.strip() for line in text.splitlines()) + return sum(1 for line in lines if line and not line.startswith(("#", "-"))) diff --git a/agent/opentelemetry-vendor/tests/__init__.py b/agent/opentelemetry-vendor/tests/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-vendor/tests/conftest.py b/agent/opentelemetry-vendor/tests/conftest.py new file mode 100644 index 00000000000..6afb104c84a --- /dev/null +++ b/agent/opentelemetry-vendor/tests/conftest.py @@ -0,0 +1,28 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from pathlib import Path + +import pytest + +VALID_CONFIG = """ +[tool.opentelemetry-vendor] +destination = "src/pkg/_vendor/" +requirements = "src/pkg/_vendor/requirements.txt" +namespace = "pkg._vendor" +python-version = "3.10" +protected-files = ["__init__.py", "requirements.txt"] +patches-dir = "patches" +sbom-file = "src/pkg/_vendor/bom.cdx.json" +""" + + +@pytest.fixture(name="project_dir") +def fixture_project_dir(tmp_path: Path) -> Path: + (tmp_path / "pyproject.toml").write_text(VALID_CONFIG) + destination = tmp_path / "src/pkg/_vendor" + destination.mkdir(parents=True) + (destination / "requirements.txt").write_text("# comment\nsix==1.0\n # via -r vendor.in\n") + return tmp_path diff --git a/agent/opentelemetry-vendor/tests/helpers.py b/agent/opentelemetry-vendor/tests/helpers.py new file mode 100644 index 00000000000..4bf6e1b02b9 --- /dev/null +++ b/agent/opentelemetry-vendor/tests/helpers.py @@ -0,0 +1,48 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import zipfile +from collections.abc import Collection, Mapping +from pathlib import Path + +DEFAULT_LICENSES: Mapping[str, str] = {"licenses/LICENSE": "license text"} + + +def make_zip(path: Path, members: Collection[str]) -> Path: + """Create a zip archive at ``path`` containing empty ``members``.""" + with zipfile.ZipFile(path, "w") as archive: + for member in members: + archive.writestr(member, "") + return path + + +def make_wheel( + directory: Path, + name: str, + version: str, + members: Collection[str] = (), + *, + metadata: str = "", + licenses: Mapping[str, str] = DEFAULT_LICENSES, + tag: str = "py3-none-any", +) -> Path: + """Create a minimal but valid wheel with METADATA, RECORD and licenses. + + ``metadata`` is appended to the METADATA headers; ``licenses`` maps paths + relative to the dist-info directory to their contents. + """ + dist_info = f"{name.replace('-', '_')}-{version}.dist-info" + files = {member: "" for member in members} + files[f"{dist_info}/METADATA"] = f"Metadata-Version: 2.4\nName: {name}\nVersion: {version}\n{metadata}" + for relative, content in licenses.items(): + files[f"{dist_info}/{relative}"] = content + record = f"{dist_info}/RECORD" + files[record] = "".join(f"{path},,\n" for path in [*files, record]) + + wheel = directory / f"{name.replace('-', '_')}-{version}-{tag}.whl" + with zipfile.ZipFile(wheel, "w") as archive: + for path, content in files.items(): + archive.writestr(path, content) + return wheel diff --git a/agent/opentelemetry-vendor/tests/test_cli.py b/agent/opentelemetry-vendor/tests/test_cli.py new file mode 100644 index 00000000000..f3435168ee7 --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_cli.py @@ -0,0 +1,171 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import json +from pathlib import Path + +import pytest +from typer.testing import CliRunner + +from opentelemetry.vendor import sync as sync_module +from opentelemetry.vendor.cli import app +from opentelemetry.vendor.download import DownloadError + +from .helpers import make_wheel + +# A fixed width keeps rich from wrapping lines in the captured output. +runner = CliRunner(env={"COLUMNS": "200"}) + + +def _fake_download(monkeypatch: pytest.MonkeyPatch, members: list[str] | None = None) -> None: + def fake_download_wheels(requirements: Path, python_version: str, dest: Path) -> list[Path]: + assert requirements.name == "requirements.txt" + assert python_version == "3.10" + return [ + make_wheel( + dest, + "six", + "1.0", + members or ["six.py"], + metadata="License-Expression: MIT\n", + ) + ] + + monkeypatch.setattr(sync_module, "download_wheels", fake_download_wheels) + + +def test_sync(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + destination = project_dir / "src/pkg/_vendor" + (destination / "stale.py").write_text("") + _fake_download(monkeypatch) + + result = runner.invoke(app, ["sync", str(project_dir)]) + + assert result.exit_code == 0, result.output + assert sorted(p.name for p in destination.iterdir()) == [ + "bom.cdx.json", + "requirements.txt", + "six.LICENSE", + "six.py", + ] + bom = json.loads((destination / "bom.cdx.json").read_text()) + assert [c["purl"] for c in bom["components"]] == ["pkg:pypi/six@1.0"] + lines = result.output.splitlines() + assert lines[:5] == [ + "✔ Cleaned src/pkg/_vendor (1 entry removed)", + "✔ Downloaded 1 wheel", + "✔ Unpacked 1 wheel", + "✔ Copied 1 license file", + "✔ Wrote SBOM src/pkg/_vendor/bom.cdx.json", + ] + assert lines[-1].split() == ["six", "1.0", "MIT", "six"] + + +def test_sync_drop(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + 'drop = ["*-stubs", "**/py.typed"]\n') + _fake_download(monkeypatch, ["six/__init__.py", "six/py.typed", "six-stubs/__init__.pyi"]) + + result = runner.invoke(app, ["sync", str(project_dir)]) + + assert result.exit_code == 0, result.output + destination = project_dir / "src/pkg/_vendor" + assert not (destination / "six-stubs").exists() + assert not (destination / "six/py.typed").exists() + assert (destination / "six/__init__.py").exists() + assert "✔ Dropped 2 paths" in result.output + + +def test_sync_verbose(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + (project_dir / "src/pkg/_vendor/stale.py").write_text("") + _fake_download(monkeypatch) + + result = runner.invoke(app, ["sync", str(project_dir), "--verbose"]) + + assert result.exit_code == 0, result.output + assert "removed " in result.output + assert "stale.py" in result.output + + +def test_sync_quiet(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + _fake_download(monkeypatch) + + result = runner.invoke(app, ["sync", str(project_dir), "-q"]) + + assert result.exit_code == 0, result.output + assert result.output == "" + + +def test_sync_quiet_and_verbose(project_dir: Path) -> None: + result = runner.invoke(app, ["sync", str(project_dir), "-q", "-v"]) + + assert result.exit_code == 2 + assert "cannot be used together" in result.output + + +def test_sync_download_error(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + def fake_download_wheels(requirements: Path, python_version: str, dest: Path) -> list[Path]: + raise DownloadError("no wheel for foo") + + monkeypatch.setattr(sync_module, "download_wheels", fake_download_wheels) + + result = runner.invoke(app, ["sync", str(project_dir), "--quiet"]) + + assert result.exit_code == 1 + # Errors are printed even with --quiet. + assert result.output == "error: no wheel for foo\n" + + +def test_sync_missing_requirements(project_dir: Path) -> None: + (project_dir / "src/pkg/_vendor/requirements.txt").unlink() + + result = runner.invoke(app, ["sync", str(project_dir)]) + + assert result.exit_code == 1 + assert "requirements.txt does not exist" in result.output + + +def test_sync_invalid_config(tmp_path: Path) -> None: + (tmp_path / "pyproject.toml").write_text("[project]\nname = 'x'\n") + + result = runner.invoke(app, ["sync", str(tmp_path)]) + + assert result.exit_code == 1 + assert "no [tool.opentelemetry-vendor] table" in result.output + + +def test_sync_missing_directory(tmp_path: Path) -> None: + result = runner.invoke(app, ["sync", str(tmp_path / "missing")]) + + assert result.exit_code != 0 + + +def test_clean(project_dir: Path) -> None: + destination = project_dir / "src/pkg/_vendor" + (destination / "requests").mkdir() + (destination / "requests/__init__.py").write_text("") + (destination / "requests.LICENSE").write_text("") + (destination / "__init__.py").write_text("") + (destination / "requirements.txt").write_text("requests==2.0\n") + + result = runner.invoke(app, ["clean", str(project_dir)]) + + assert result.exit_code == 0, result.output + assert sorted(p.name for p in destination.iterdir()) == [ + "__init__.py", + "requirements.txt", + ] + assert (destination / "requirements.txt").read_text() == "requests==2.0\n" + assert result.output == "✔ Cleaned src/pkg/_vendor (2 entries removed)\n" + + +def test_clean_invalid_config(tmp_path: Path) -> None: + (tmp_path / "pyproject.toml").write_text("[project]\nname = 'x'\n") + + result = runner.invoke(app, ["clean", str(tmp_path)]) + + assert result.exit_code == 1 + assert "error: " in result.output + assert "no [tool.opentelemetry-vendor] table" in result.output diff --git a/agent/opentelemetry-vendor/tests/test_config.py b/agent/opentelemetry-vendor/tests/test_config.py new file mode 100644 index 00000000000..c6d015a1bcd --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_config.py @@ -0,0 +1,98 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import sys +from pathlib import Path + +import pytest + +from opentelemetry.vendor.config import ConfigError, load_config + + +def test_load_config(project_dir: Path) -> None: + config = load_config(project_dir) + + root = project_dir.resolve() + assert config.project_dir == root + assert config.destination == root / "src/pkg/_vendor" + assert config.requirements == root / "src/pkg/_vendor/requirements.txt" + assert config.namespace == "pkg._vendor" + assert config.python_version == "3.10" + assert tuple(config.protected_files) == ("__init__.py", "requirements.txt") + assert config.patches_dir == root / "patches" + assert config.sbom_file == root / "src/pkg/_vendor/bom.cdx.json" + + +def test_load_config_optional_keys(tmp_path: Path) -> None: + (tmp_path / "pyproject.toml").write_text( + "[tool.opentelemetry-vendor]\n" + 'destination = "_vendor"\n' + 'requirements = "requirements.txt"\n' + 'namespace = "_vendor"\n' + ) + + config = load_config(tmp_path) + + assert tuple(config.protected_files) == () + assert tuple(config.drop) == () + assert config.python_version == (f"{sys.version_info.major}.{sys.version_info.minor}") + assert config.patches_dir is None + assert config.sbom_file is None + + +@pytest.mark.parametrize( + ("content", "message"), + [ + ("[project]\nname = 'x'\n", r"no \[tool.opentelemetry-vendor\] table"), + ( + '[tool.opentelemetry-vendor]\nrequirements = "r.txt"\nnamespace = "v"\n', + "missing required key 'destination'", + ), + ( + '[tool.opentelemetry-vendor]\ndestination = 1\nrequirements = "r.txt"\nnamespace = "v"\n', + "'destination' must be a non-empty string", + ), + ( + '[tool.opentelemetry-vendor]\ndestination = "v"\n' + 'requirements = "r.txt"\nnamespace = "v"\nprotected-files = "x"\n', + "'protected-files' must be a list of strings", + ), + ( + '[tool.opentelemetry-vendor]\ndestination = "../v"\nrequirements = "r.txt"\nnamespace = "v"\n', + "'destination' must be a directory inside", + ), + ( + '[tool.opentelemetry-vendor]\ndestination = "."\nrequirements = "r.txt"\nnamespace = "v"\n', + "'destination' must be a directory inside", + ), + ("not toml [", "is not valid TOML"), + ], +) +def test_load_config_invalid(tmp_path: Path, content: str, message: str) -> None: + (tmp_path / "pyproject.toml").write_text(content) + + with pytest.raises(ConfigError, match=message): + load_config(tmp_path) + + +def test_load_config_missing_pyproject(tmp_path: Path) -> None: + with pytest.raises(ConfigError, match="does not exist"): + load_config(tmp_path) + + +def test_load_config_drop(project_dir: Path) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + 'drop = ["wrapt-stubs", "**/py.typed"]\n') + + assert tuple(load_config(project_dir).drop) == ("wrapt-stubs", "**/py.typed") + + +@pytest.mark.parametrize("pattern", ["", "/abs", "../outside", "a/../../b"]) +def test_load_config_invalid_drop(project_dir: Path, pattern: str) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + f"drop = [{pattern!r}]\n") + + with pytest.raises(ConfigError, match="must be relative to destination"): + load_config(project_dir) diff --git a/agent/opentelemetry-vendor/tests/test_download.py b/agent/opentelemetry-vendor/tests/test_download.py new file mode 100644 index 00000000000..fd8eb70708f --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_download.py @@ -0,0 +1,128 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import subprocess +import sys +from collections.abc import Callable, Sequence +from pathlib import Path + +import pytest + +from opentelemetry.vendor.download import ( + DownloadError, + download_wheels, + unpack_wheels, +) + +from .helpers import make_wheel, make_zip + + +def _fake_run( + returncode: int, wheel_names: Sequence[str], stderr: str = "" +) -> tuple[list[list[str]], Callable[..., subprocess.CompletedProcess[str]]]: + calls: list[list[str]] = [] + + def run(args: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]: + calls.append(args) + dest = Path(args[args.index("--dest") + 1]) + for name in wheel_names: + make_zip(dest / name, []) + return subprocess.CompletedProcess(args, returncode, "", stderr) + + return calls, run + + +def test_download_wheels(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + requirements = tmp_path / "requirements.txt" + calls, run = _fake_run(0, ["requests-2.0-py3-none-any.whl", "six-1.0-py2.py3-none-any.whl"]) + monkeypatch.setattr(subprocess, "run", run) + + wheels = download_wheels(requirements, "3.10", tmp_path) + + assert [w.name for w in wheels] == [ + "requests-2.0-py3-none-any.whl", + "six-1.0-py2.py3-none-any.whl", + ] + assert calls == [ + [ + sys.executable, + "-m", + "pip", + "download", + "--no-deps", + "--only-binary=:all:", + "--platform", + "any", + "--implementation", + "py", + "--abi", + "none", + "--python-version", + "3.10", + "--disable-pip-version-check", + "--dest", + str(tmp_path), + "-r", + str(requirements), + ] + ] + + +def test_download_wheels_pip_failure(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + _, run = _fake_run(1, [], stderr="No matching distribution found for foo") + monkeypatch.setattr(subprocess, "run", run) + + with pytest.raises(DownloadError, match="No matching distribution found"): + download_wheels(tmp_path / "requirements.txt", "3.10", tmp_path) + + +def test_download_wheels_rejects_platform_wheel(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + _, run = _fake_run(0, ["wrapt-2.0-cp312-cp312-linux_x86_64.whl"]) + monkeypatch.setattr(subprocess, "run", run) + + with pytest.raises(DownloadError, match="not a pure-Python wheel"): + download_wheels(tmp_path / "requirements.txt", "3.10", tmp_path) + + +def test_unpack_wheels_shared_namespace(tmp_path: Path) -> None: + destination = tmp_path / "_vendor" + protobuf = make_wheel(tmp_path, "protobuf", "7.0", ["google/protobuf/__init__.py"]) + common_protos = make_wheel(tmp_path, "googleapis-common-protos", "1.0", ["google/api/__init__.py"]) + + dist_infos = unpack_wheels([protobuf, common_protos], destination) + + assert dist_infos == { + protobuf: destination / "protobuf-7.0.dist-info", + common_protos: destination / "googleapis_common_protos-1.0.dist-info", + } + assert (destination / "google/protobuf/__init__.py").is_file() + assert (destination / "google/api/__init__.py").is_file() + assert (destination / "protobuf-7.0.dist-info/METADATA").is_file() + + +def test_unpack_wheels_refuses_to_overwrite(tmp_path: Path) -> None: + destination = tmp_path / "_vendor" + destination.mkdir() + (destination / "requirements.txt").write_text("keep") + wheel = make_wheel(tmp_path, "bad", "1.0", ["requirements.txt"]) + + with pytest.raises(DownloadError, match="would overwrite"): + unpack_wheels([wheel], destination) + + assert (destination / "requirements.txt").read_text() == "keep" + + +@pytest.mark.parametrize( + "members", + [ + ["bad/__init__.py"], + ["a-1.0.dist-info/METADATA", "b-1.0.dist-info/METADATA"], + ], +) +def test_unpack_wheels_requires_one_dist_info(tmp_path: Path, members: list[str]) -> None: + wheel = make_zip(tmp_path / "bad-1.0-py3-none-any.whl", members) + + with pytest.raises(DownloadError, match="exactly one .dist-info"): + unpack_wheels([wheel], tmp_path / "_vendor") diff --git a/agent/opentelemetry-vendor/tests/test_metadata.py b/agent/opentelemetry-vendor/tests/test_metadata.py new file mode 100644 index 00000000000..61125531303 --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_metadata.py @@ -0,0 +1,152 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import hashlib +from pathlib import Path + +import pytest + +from opentelemetry.vendor.download import unpack_wheels +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.metadata import ( + VendoredPackage, + copy_license_files, + read_package, + remove_dist_info, +) + +from .helpers import make_wheel + + +def _read(tmp_path: Path, wheel: Path) -> VendoredPackage: + destination = tmp_path / "_vendor" + ((wheel, dist_info),) = unpack_wheels([wheel], destination).items() + return read_package(wheel, dist_info) + + +def test_read_package(tmp_path: Path) -> None: + wheel = make_wheel( + tmp_path, + "Charset_Normalizer", + "3.5.2", + [ + "charset_normalizer/__init__.py", + "charset_normalizer/cli/__init__.py", + "six.py", + "README.md", + "wrapt-stubs/__init__.pyi", + "__pycache__/six.cpython-312.pyc", + "charset_normalizer-3.5.2.data/scripts/normalizer", + ], + metadata="License-Expression: MIT\nLicense-File: LICENSE\n", + ) + + package = _read(tmp_path, wheel) + + dist_info = tmp_path / "_vendor/Charset_Normalizer-3.5.2.dist-info" + assert package == VendoredPackage( + name="charset-normalizer", + version="3.5.2", + sha256=hashlib.sha256(wheel.read_bytes()).hexdigest(), + license_expression="MIT", + top_level_names=("charset_normalizer", "six"), + license_files={"charset-normalizer.LICENSE": dist_info / "licenses/LICENSE"}, + dist_info=dist_info, + ) + + +@pytest.mark.parametrize( + ("metadata", "expected"), + [ + ("License-Expression: Apache-2.0\nLicense: MIT\n", "Apache-2.0"), + ("License: MPL-2.0\n", "MPL-2.0"), + ( + "License: line one\n line two\nClassifier: License :: OSI Approved :: MIT License\n", + "MIT License", + ), + ( + "Classifier: License :: OSI Approved :: MIT License\n" + "Classifier: Programming Language :: Python\n" + "Classifier: License :: OSI Approved :: BSD License\n", + "MIT License OR BSD License", + ), + ("", None), + ], +) +def test_read_package_license_expression(tmp_path: Path, metadata: str, expected: str | None) -> None: + wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"], metadata=metadata) + + assert _read(tmp_path, wheel).license_expression == expected + + +def test_read_package_legacy_license_files(tmp_path: Path) -> None: + wheel = make_wheel( + tmp_path, + "pkg", + "1.0", + ["pkg.py"], + licenses={ + "LICENSE.txt": "", + "NOTICE": "", + "licenses/vendor/COPYING": "", + "entry_points.txt": "", + }, + ) + + package = _read(tmp_path, wheel) + + assert sorted(package.license_files) == [ + "pkg.LICENSE.txt", + "pkg.NOTICE", + "pkg.vendor.COPYING", + ] + + +def test_read_package_license_file_in_dist_info_root(tmp_path: Path) -> None: + wheel = make_wheel( + tmp_path, + "pkg", + "1.0", + ["pkg.py"], + metadata="License-File: LICENSE.md\n", + licenses={"LICENSE.md": ""}, + ) + + assert sorted(_read(tmp_path, wheel).license_files) == ["pkg.LICENSE.md"] + + +def test_read_package_missing_declared_license_file(tmp_path: Path) -> None: + wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"], metadata="License-File: LICENSE\n", licenses={}) + + with pytest.raises(VendorError, match="declares missing license file LICENSE"): + _read(tmp_path, wheel) + + +def test_read_package_without_license_file(tmp_path: Path) -> None: + wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"], licenses={}) + + with pytest.raises(VendorError, match="does not contain a license file"): + _read(tmp_path, wheel) + + +def test_copy_license_files_and_remove_dist_info(tmp_path: Path) -> None: + destination = tmp_path / "_vendor" + wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"], licenses={"licenses/LICENSE": "text"}) + package = _read(tmp_path, wheel) + + copy_license_files([package], destination) + remove_dist_info([package]) + + assert (destination / "pkg.LICENSE").read_text() == "text" + assert sorted(p.name for p in destination.iterdir()) == ["pkg.LICENSE", "pkg.py"] + + +def test_copy_license_files_collision(tmp_path: Path) -> None: + destination = tmp_path / "_vendor" + package = _read(tmp_path, make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"])) + (destination / "pkg.LICENSE").write_text("existing") + + with pytest.raises(VendorError, match="already exists"): + copy_license_files([package], destination) diff --git a/agent/opentelemetry-vendor/tests/test_sbom.py b/agent/opentelemetry-vendor/tests/test_sbom.py new file mode 100644 index 00000000000..addb52c13a4 --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_sbom.py @@ -0,0 +1,62 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import hashlib +import json +from pathlib import Path + +from opentelemetry.vendor.metadata import VendoredPackage +from opentelemetry.vendor.sbom import write_sbom + + +def _package(name: str, version: str, license_expression: str | None) -> VendoredPackage: + return VendoredPackage( + name=name, + version=version, + sha256=hashlib.sha256(name.encode()).hexdigest(), + license_expression=license_expression, + top_level_names=(name,), + license_files={}, + dist_info=Path(f"{name}-{version}.dist-info"), + ) + + +PACKAGES = [ + _package("urllib3", "2.8.0", "MIT"), + _package("certifi", "2026.10.23", "MPL-2.0"), + _package("idna", "3.20", "BSD-3-Clause OR MIT"), + _package("legacy", "1.0", "MIT License"), + _package("unknown", "0.1", None), +] + + +def test_write_sbom(tmp_path: Path) -> None: + path = tmp_path / "nested/bom.cdx.json" + + write_sbom(PACKAGES, path) + + bom = json.loads(path.read_text()) + assert bom["bomFormat"] == "CycloneDX" + assert bom["specVersion"] == "1.6" + assert "timestamp" not in bom["metadata"] + components = {c["name"]: c for c in bom["components"]} + assert list(components) == ["certifi", "idna", "legacy", "unknown", "urllib3"] + assert components["urllib3"]["purl"] == "pkg:pypi/urllib3@2.8.0" + assert components["urllib3"]["version"] == "2.8.0" + assert components["urllib3"]["type"] == "library" + assert components["urllib3"]["hashes"] == [{"alg": "SHA-256", "content": hashlib.sha256(b"urllib3").hexdigest()}] + assert components["urllib3"]["licenses"] == [{"license": {"id": "MIT"}}] + assert components["idna"]["licenses"] == [{"expression": "BSD-3-Clause OR MIT"}] + assert components["legacy"]["licenses"] == [{"license": {"name": "MIT License"}}] + assert "licenses" not in components["unknown"] + + +def test_write_sbom_is_deterministic(tmp_path: Path) -> None: + first, second = tmp_path / "first.json", tmp_path / "second.json" + + write_sbom(PACKAGES, first) + write_sbom(list(reversed(PACKAGES)), second) + + assert first.read_bytes() == second.read_bytes() diff --git a/agent/opentelemetry-vendor/tests/test_sync.py b/agent/opentelemetry-vendor/tests/test_sync.py new file mode 100644 index 00000000000..b737ccf13b6 --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_sync.py @@ -0,0 +1,92 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from pathlib import Path + +import pytest + +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.sync import clean_destination, drop_paths + + +def test_clean_destination_keeps_protected_files(tmp_path: Path) -> None: + destination = tmp_path / "_vendor" + destination.mkdir() + (destination / "__init__.py").write_text("") + (destination / "requirements.txt").write_text("requests==1.0\n") + (destination / "six.py").write_text("") + package = destination / "requests" + package.mkdir() + (package / "__init__.py").write_text("") + outside = tmp_path / "outside" + outside.mkdir() + (outside / "keep.txt").write_text("") + (destination / "link").symlink_to(outside, target_is_directory=True) + + removed = clean_destination(destination, ["__init__.py", "requirements.txt"]) + + assert sorted(p.name for p in destination.iterdir()) == [ + "__init__.py", + "requirements.txt", + ] + assert (destination / "requirements.txt").read_text() == "requests==1.0\n" + assert [p.name for p in removed] == ["link", "requests", "six.py"] + # The symlink is removed without following it. + assert (outside / "keep.txt").exists() + + +def test_clean_destination_creates_missing_directory(tmp_path: Path) -> None: + destination = tmp_path / "a" / "_vendor" + + clean_destination(destination, []) + + assert destination.is_dir() + + +def _make_tree(root: Path, files: list[str]) -> None: + for file in files: + (root / file).parent.mkdir(parents=True, exist_ok=True) + (root / file).write_text("") + + +def test_drop_paths(tmp_path: Path) -> None: + _make_tree( + tmp_path, + [ + "wrapt/__init__.py", + "wrapt/py.typed", + "wrapt-stubs/__init__.pyi", + "wrapt-stubs/py.typed", + "google/protobuf/py.typed", + "wrapt-2.0.dist-info/METADATA", + ], + ) + + removed = drop_paths(tmp_path, ["*-stubs", "**/py.typed"]) + + # wrapt-stubs/py.typed matches too, but is removed with its parent. + assert [p.relative_to(tmp_path).as_posix() for p in removed] == [ + "google/protobuf/py.typed", + "wrapt/py.typed", + "wrapt-stubs", + ] + assert (tmp_path / "wrapt/__init__.py").exists() + assert (tmp_path / "wrapt-2.0.dist-info/METADATA").exists() + + +def test_drop_paths_unmatched_pattern(tmp_path: Path) -> None: + _make_tree(tmp_path, ["wrapt/__init__.py"]) + + with pytest.raises(VendorError, match="'missing' matched nothing"): + drop_paths(tmp_path, ["missing"]) + + +def test_drop_paths_ignores_dist_info(tmp_path: Path) -> None: + _make_tree(tmp_path, ["wrapt-2.0.dist-info/METADATA"]) + + with pytest.raises(VendorError, match="matched nothing"): + drop_paths(tmp_path, ["**/METADATA"]) + + assert (tmp_path / "wrapt-2.0.dist-info/METADATA").exists() diff --git a/uv.lock b/uv.lock index 90b62418aa0..536f28dac75 100644 --- a/uv.lock +++ b/uv.lock @@ -445,6 +445,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494", size = 125813, upload-time = "2026-07-12T20:29:05.763Z" }, ] +[[package]] +name = "arrow" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931, upload-time = "2025-10-18T17:46:46.761Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" }, +] + [[package]] name = "asgiref" version = "3.11.1" @@ -594,6 +607,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, ] +[[package]] +name = "boolean-py" +version = "5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/cf/85379f13b76f3a69bca86b60237978af17d6aa0bc5998978c3b8cf05abb2/boolean_py-5.0.tar.gz", hash = "sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95", size = 37047, upload-time = "2025-04-03T10:39:49.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl", hash = "sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9", size = 26577, upload-time = "2025-04-03T10:39:48.449Z" }, +] + [[package]] name = "boto3" version = "1.43.0" @@ -1171,6 +1193,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/b5/c2c5fce26f0ee40d21bafe7f191d29a34b35a65ac4fe8a1191d1983612e9/cryptography-50.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c99c003e088647b8a5b7c145d6f78c335f6348332b62e142d411c4b63d1460b9", size = 3813796, upload-time = "2026-07-31T14:25:02.298Z" }, ] +[[package]] +name = "cyclonedx-python-lib" +version = "11.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "license-expression" }, + { name = "packageurl-python" }, + { name = "py-serializable" }, + { name = "sortedcontainers" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/40/6509e6cfd7f2f3255501690f46375fdd224949e21fd1e96f4f4c8a9041b1/cyclonedx_python_lib-11.12.0.tar.gz", hash = "sha256:16767c4039de90c04e9f03348f8f0ed4b8ff842eaa7eefcad3a95685f970dacf", size = 1445378, upload-time = "2026-08-13T07:52:18.675Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/f0/b2cb999244f2f4194df63ecff6939228178fa63a33be809c412684ca8db7/cyclonedx_python_lib-11.12.0-py3-none-any.whl", hash = "sha256:0e807521a921a5c3cb8ce1153f8a61d29eedfe76a46aac2796b7c6b573391a54", size = 529453, upload-time = "2026-08-13T07:52:16.836Z" }, +] + +[package.optional-dependencies] +json-validation = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "referencing" }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + [[package]] name = "deprecated" version = "1.3.1" @@ -1385,6 +1438,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/9c/34f6962f9b9e9c71f6e5ed806e0d0ff03c9d1b0b2340088a0cf4bce09b18/flask-3.1.3-py3-none-any.whl", hash = "sha256:f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c", size = 103424, upload-time = "2026-02-19T05:00:56.027Z" }, ] +[[package]] +name = "fqdn" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/01/248d44fbda9e78fa1a7b5a475194bef4c4a3e285db286419f3bb42f2efdf/fqdn-1.6.0.tar.gz", hash = "sha256:e39bf62e2a9481aa2cb780554fdfd944dd8ee5f230eb831684d539cbafed8de2", size = 130737, upload-time = "2026-09-28T05:43:35.482Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/d5/a8f9149b97cced9e1f4bff92ff0b6206120e2c853ae774d7020d6ecd8fa8/fqdn-1.6.0-py3-none-any.whl", hash = "sha256:6c793c312ccfa29981e1135b3ef5e1277ebe639731a6b0f7350d90e96e63f0b4", size = 12569, upload-time = "2026-09-28T05:43:33.951Z" }, +] + [[package]] name = "frozenlist" version = "1.8.0" @@ -2084,6 +2146,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6c/0c/f37b6a241f0759b7653ffa7213889d89ad49a2b76eb2ddf3b57b2738c347/iso8601-2.1.0-py3-none-any.whl", hash = "sha256:aac4145c4dcb66ad8b648a02830f5e2ff6c24af20f4f482689be402db2429242", size = 7545, upload-time = "2023-10-03T00:25:32.304Z" }, ] +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, +] + [[package]] name = "itsdangerous" version = "2.2.0" @@ -2260,6 +2334,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/2f/967ba146e6d58cf6a652da73885f52fc68001525b4197effc174321d70b4/jmespath-1.1.0-py3-none-any.whl", hash = "sha256:a5663118de4908c91729bea0acadca56526eb2698e83de10cd116ae0f4e97c64", size = 20419, upload-time = "2026-01-22T16:35:24.919Z" }, ] +[[package]] +name = "jsonpointer" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/93/f6/d1109cbb2c7cb692b432071802028052ba8d275c613c1a1cce427bc62c97/jsonpointer-3.10.tar.gz", hash = "sha256:69349c0e738c93e9efa501397091f49ad302ae686293effd05d7755c06f88ef0", size = 19950, upload-time = "2026-11-06T11:39:07.229Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/66/25cbb926e981a849d1cfcd36817fba6bfa5e9b6a2944c41230fe83ff25d2/jsonpointer-3.10-py3-none-any.whl", hash = "sha256:3b08b9e5239f1b683e31c9561c350d75ce3fa8cdd407130ca8491fdb0c9e56f3", size = 10376, upload-time = "2026-11-06T11:39:06.069Z" }, +] + [[package]] name = "jsonschema" version = "4.26.0" @@ -2276,6 +2359,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, ] +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + [[package]] name = "jsonschema-specifications" version = "2025.9.1" @@ -2331,6 +2427,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/0f/834427d8c03ff1d7e867d3db3d176470c64871753252b21b4f4897d1fa45/kombu-5.6.2-py3-none-any.whl", hash = "sha256:efcfc559da324d41d61ca311b0c64965ea35b4c55cc04ee36e55386145dace93", size = 214219, upload-time = "2025-12-29T20:30:05.74Z" }, ] +[[package]] +name = "lark" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, +] + [[package]] name = "legacy-cgi" version = "2.6.4" @@ -2340,6 +2445,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8c/7e/e7394eeb49a41cc514b3eb49020223666cbf40d86f5721c2f07871e6d84a/legacy_cgi-2.6.4-py3-none-any.whl", hash = "sha256:7e235ce58bf1e25d1fc9b2d299015e4e2cd37305eccafec1e6bac3fc04b878cd", size = 20035, upload-time = "2025-10-27T05:20:04.289Z" }, ] +[[package]] +name = "license-expression" +version = "30.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "boolean-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/71/d89bb0e71b1415453980fd32315f2a037aad9f7f70f695c7cec7035feb13/license_expression-30.4.4.tar.gz", hash = "sha256:73448f0aacd8d0808895bdc4b2c8e01a8d67646e4188f887375398c761f340fd", size = 186402, upload-time = "2025-07-22T11:13:32.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl", hash = "sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4", size = 120615, upload-time = "2025-07-22T11:13:31.217Z" }, +] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -4583,6 +4700,33 @@ source = { editable = "util/opentelemetry-util-http" } name = "opentelemetry-vendor" version = "0.0.0" source = { editable = "agent/opentelemetry-vendor" } +dependencies = [ + { name = "cyclonedx-python-lib", extra = ["json-validation"] }, + { name = "packageurl-python" }, + { name = "pip" }, + { name = "rich" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typer" }, +] + +[package.metadata] +requires-dist = [ + { name = "cyclonedx-python-lib", extras = ["json-validation"], specifier = ">=11.0,<12.0" }, + { name = "packageurl-python", specifier = ">=0.11,<1.0" }, + { name = "pip", specifier = ">=25.0,<27.0" }, + { name = "rich", specifier = ">=13.0,<16.0" }, + { name = "tomli", marker = "python_full_version < '3.11'", specifier = ">=2.0,<3.0" }, + { name = "typer", specifier = ">=0.15,<1.0" }, +] + +[[package]] +name = "packageurl-python" +version = "0.17.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/d6/3b5a4e3cfaef7a53869a26ceb034d1ff5e5c27c814ce77260a96d50ab7bb/packageurl_python-0.17.6.tar.gz", hash = "sha256:1252ce3a102372ca6f86eb968e16f9014c4ba511c5c37d95a7f023e2ca6e5c25", size = 50618, upload-time = "2025-11-24T15:20:17.998Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/2f/c7277b7615a93f51b5fbc1eacfc1b75e8103370e786fd8ce2abf6e5c04ab/packageurl_python-0.17.6-py3-none-any.whl", hash = "sha256:31a85c2717bc41dd818f3c62908685ff9eebcb68588213745b14a6ee9e7df7c9", size = 36776, upload-time = "2025-11-24T15:20:16.962Z" }, +] [[package]] name = "packaging" @@ -4996,6 +5140,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/be/b732c8418ffa5bcfda002890f5dc4c869fc17db66ff11f53b17cfe44afc0/psycopg2_binary-2.9.12-cp314-cp314-win_amd64.whl", hash = "sha256:f12ae41fcafadb39b2785e64a40f9db05d6de2ac114077457e0e7c597f3af980", size = 2848762, upload-time = "2026-04-20T23:35:46.421Z" }, ] +[[package]] +name = "py-serializable" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "defusedxml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/8c/cad9596066de835b304be48b0eefa30dae1834afae6e670805831cc05ea2/py_serializable-2.2.0.tar.gz", hash = "sha256:8e4fa02e8de819c0488ccdb69c2d3109274adcf224c02357fd8729cb12727aab", size = 52608, upload-time = "2026-11-06T13:43:39.943Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/56/94f6a9ac81193713e6be0d41c62d6b916b53c814c05d8b3a0d90976db0d6/py_serializable-2.2.0-py3-none-any.whl", hash = "sha256:2cce775abc5aac12115f9ff572a145c7276d04a770090334bd4e51ed9c782415", size = 23101, upload-time = "2026-11-06T13:43:38.593Z" }, +] + [[package]] name = "pyasn1" version = "0.6.5" @@ -5770,6 +5926,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" }, ] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" }, +] + [[package]] name = "rfc3986" version = "2.0.0" @@ -5779,6 +5947,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", size = 31326, upload-time = "2022-01-10T00:52:29.594Z" }, ] +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, +] + +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, +] + [[package]] name = "rich" version = "15.0.0" @@ -6126,6 +6315,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6", size = 1062021, upload-time = "2026-02-06T21:10:37.175Z" }, ] +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + [[package]] name = "six" version = "1.17.0" @@ -6144,6 +6342,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] +[[package]] +name = "sortedcontainers" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, +] + [[package]] name = "sqlalchemy" version = "2.0.51" @@ -6562,6 +6769,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/96/08/ddcdc06225eaad6de0e48e1002b06d919dbde20582d0662c7af51308e5d6/twine-7.0.0-py3-none-any.whl", hash = "sha256:b854164df26db268af05f49aa5c0344b10e27a494343ff05b1e0bad3b135f5a7", size = 43204, upload-time = "2026-07-27T15:58:59.26Z" }, ] +[[package]] +name = "typer" +version = "0.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "rich" }, + { name = "shellingham" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ad/8f/21021859316f44289101638dc74d82e13d722d8533e4b8708a3ab7c8461a/typer-0.28.0.tar.gz", hash = "sha256:69ab84ef79fd601cff071bbd2566d855ecadfd93adbc4b3360b9924359bdd857", size = 205415, upload-time = "2026-11-06T08:37:19.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/98/8ef60c7cd773dbab9d276a4c7bff505913a25b61acd8a9ef01ceeb70f554/typer-0.28.0-py3-none-any.whl", hash = "sha256:afd18929180b706c5e9a239f53c3c8136903553c0c2d460598bbaa924191d4ab", size = 123253, upload-time = "2026-11-06T08:37:18.611Z" }, +] + [[package]] name = "typing-extensions" version = "4.16.0" @@ -6604,6 +6826,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/a4/017a7a6cbe387d961a688ec31364ae60a5c4e22c96ae9921b79a947c855d/tzlocal-5.4.4-py3-none-any.whl", hash = "sha256:aae09f0126a8a86fa736be266eb4a471380d26a0de3bc14844e7821fee3e2a15", size = 18115, upload-time = "2026-06-29T08:03:38.666Z" }, ] +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, +] + [[package]] name = "urllib3" version = "2.8.0" @@ -6711,6 +6942,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/96/42/3e5985a0a7e57de470b320c6d6a1a67c844f6737a587f3d44dd13d1819e7/wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85", size = 323166, upload-time = "2026-06-29T18:11:09.888Z" }, ] +[[package]] +name = "webcolors" +version = "25.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491, upload-time = "2025-10-31T07:51:03.977Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905, upload-time = "2025-10-31T07:51:01.778Z" }, +] + [[package]] name = "webob" version = "1.8.11" From bc7926b701edd3574cb9cedd76bf749a025acdf9 Mon Sep 17 00:00:00 2001 From: Lukas Hering Date: Sun, 8 Nov 2026 16:15:09 -0500 Subject: [PATCH 3/5] stash --- .../patches/certifi-resources.patch | 40 +++ .../patches/protobuf-pure-python.patch | 116 +++++++ .../patches/requests-chardet.patch | 46 +++ .../patches/requests-packages.patch | 37 +++ agent/opentelemetry-agent/pyproject.toml | 31 +- .../agent/_vendor/requirements.txt | 206 +++++++++++- agent/opentelemetry-agent/vendor.in | 2 + agent/opentelemetry-vendor/README.rst | 60 ++++ agent/opentelemetry-vendor/pyproject.toml | 1 + .../src/opentelemetry/vendor/checks.py | 231 +++++++++++++ .../src/opentelemetry/vendor/cli.py | 15 +- .../src/opentelemetry/vendor/config.py | 38 ++- .../src/opentelemetry/vendor/download.py | 1 + .../src/opentelemetry/vendor/patches.py | 104 ++++++ .../src/opentelemetry/vendor/rewrite.py | 210 ++++++++++++ .../src/opentelemetry/vendor/sbom.py | 40 ++- .../src/opentelemetry/vendor/sync.py | 142 +++++++- agent/opentelemetry-vendor/tests/conftest.py | 5 +- .../opentelemetry-vendor/tests/test_checks.py | 300 +++++++++++++++++ agent/opentelemetry-vendor/tests/test_cli.py | 156 ++++++++- .../opentelemetry-vendor/tests/test_config.py | 73 +++- .../tests/test_patches.py | 169 ++++++++++ .../tests/test_rewrite.py | 313 ++++++++++++++++++ agent/opentelemetry-vendor/tests/test_sbom.py | 19 ++ agent/opentelemetry-vendor/tests/test_sync.py | 36 +- uv.lock | 94 ++++++ 26 files changed, 2441 insertions(+), 44 deletions(-) create mode 100644 agent/opentelemetry-agent/patches/certifi-resources.patch create mode 100644 agent/opentelemetry-agent/patches/protobuf-pure-python.patch create mode 100644 agent/opentelemetry-agent/patches/requests-chardet.patch create mode 100644 agent/opentelemetry-agent/patches/requests-packages.patch create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/patches.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py create mode 100644 agent/opentelemetry-vendor/tests/test_checks.py create mode 100644 agent/opentelemetry-vendor/tests/test_patches.py create mode 100644 agent/opentelemetry-vendor/tests/test_rewrite.py diff --git a/agent/opentelemetry-agent/patches/certifi-resources.patch b/agent/opentelemetry-agent/patches/certifi-resources.patch new file mode 100644 index 00000000000..50f5a6e1ef0 --- /dev/null +++ b/agent/opentelemetry-agent/patches/certifi-resources.patch @@ -0,0 +1,40 @@ +Look up the CA bundle in the vendored certifi package. + +Upstream passes the top-level name "certifi" to importlib.resources, which would import +the application's certifi (or fail if it isn't installed). __package__ resolves to the +vendored package. + +diff --git a/certifi/core.py b/certifi/core.py +--- a/certifi/core.py ++++ b/certifi/core.py +@@ -37,14 +37,14 @@ if sys.version_info >= (3, 11): + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. +- _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem")) ++ _CACERT_CTX = as_file(files(__package__).joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: +- return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii") ++ return files(__package__).joinpath("cacert.pem").read_text(encoding="ascii") + + else: + +@@ -73,11 +73,11 @@ else: + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. +- _CACERT_CTX = get_path("certifi", "cacert.pem") ++ _CACERT_CTX = get_path(__package__, "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: +- return read_text("certifi", "cacert.pem", encoding="ascii") ++ return read_text(__package__, "cacert.pem", encoding="ascii") diff --git a/agent/opentelemetry-agent/patches/protobuf-pure-python.patch b/agent/opentelemetry-agent/patches/protobuf-pure-python.patch new file mode 100644 index 00000000000..fc8fb9da565 --- /dev/null +++ b/agent/opentelemetry-agent/patches/protobuf-pure-python.patch @@ -0,0 +1,116 @@ +Force the pure-Python protobuf implementation in the vendored copy. + +Upstream probes for the upb/cpp C extensions with importlib.import_module("google._upb._message") +and friends, which imports the application's protobuf by its top-level name (and then warns that +the vendored upb is unavailable), and honours PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which is meant +for the application's protobuf: "cpp" makes descriptor.py import the missing vendored pyext and +crash. Only the pure-Python implementation is vendored, so select it unconditionally. + +diff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/internal/api_implementation.py +--- a/google/protobuf/internal/api_implementation.py ++++ b/google/protobuf/internal/api_implementation.py +@@ -6,7 +6,6 @@ + # https://developers.google.com/open-source/licenses/bsd + """Determine which implementation of the protobuf API is used in this process.""" + +-import importlib + import os + import sys + import warnings +@@ -24,90 +23,15 @@ def _ApiVersionToImplementationType(api_version): + return None + + +-_implementation_type = None +-try: +- # pylint: disable=g-import-not-at-top +- from opentelemetry.agent._vendor.google.protobuf.internal import _api_implementation +- # The compile-time constants in the _api_implementation module can be used to +- # switch to a certain implementation of the Python API at build time. +- _implementation_type = _ApiVersionToImplementationType( +- _api_implementation.api_version +- ) +-except ImportError: +- pass # Unspecified by compiler flags. +- +- +-def _CanImport(mod_name): +- try: +- mod = importlib.import_module(mod_name) +- # Work around a known issue in the classic bootstrap .par import hook. +- if not mod: +- raise ImportError(mod_name + ' import succeeded but was None') +- return True +- except ImportError: +- return False +- +- +-if _implementation_type is None: +- if _CanImport('google._upb._message'): +- _implementation_type = 'upb' +- elif _CanImport('google.protobuf.pyext._message'): +- _implementation_type = 'cpp' +- else: +- _implementation_type = 'python' +- +-# This environment variable can be used to switch to a certain implementation +-# of the Python API, overriding the compile-time constants in the +-# _api_implementation module. Right now only 'python', 'cpp' and 'upb' are +-# valid values. Any other value will raise error. +-_implementation_type = os.getenv( +- 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', _implementation_type +-) +- +-if _implementation_type not in ('python', 'cpp', 'upb'): +- raise ValueError( +- 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION {0} is not ' +- "supported. Please set to 'python', 'cpp' or " +- "'upb'.".format(_implementation_type) +- ) +- +-if 'PyPy' in sys.version and _implementation_type == 'cpp': +- warnings.warn( +- 'PyPy does not work yet with cpp protocol buffers. ' +- 'Falling back to the python implementation.' +- ) +- _implementation_type = 'python' ++# The vendored copy ships only the pure-Python implementation. Don't probe for the ++# C extensions, which would import the application's google._upb / google.protobuf.pyext ++# by their top-level names, and don't follow PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which ++# configures the application's protobuf (e.g. "cpp" would make descriptor.py import the ++# missing vendored pyext._message). ++_implementation_type = 'python' + + _c_module = None + +-if _implementation_type == 'cpp': +- try: +- # pylint: disable=g-import-not-at-top +- from opentelemetry.agent._vendor.google.protobuf.pyext import _message +- +- sys.modules['google3.net.proto2.python.internal.cpp._message'] = _message +- _c_module = _message +- del _message +- except ImportError: +- # TODO: fail back to python +- warnings.warn('Selected implementation cpp is not available.') +- pass +- +-if _implementation_type == 'upb': +- try: +- # pylint: disable=g-import-not-at-top +- from opentelemetry.agent._vendor.google._upb import _message +- +- _c_module = _message +- del _message +- except ImportError: +- warnings.warn( +- 'Selected implementation upb is not available. ' +- 'Falling back to the python implementation.' +- ) +- _implementation_type = 'python' +- pass +- + # Detect if serialization should be deterministic by default + try: + # The presence of this module in a build allows the proto implementation to diff --git a/agent/opentelemetry-agent/patches/requests-chardet.patch b/agent/opentelemetry-agent/patches/requests-chardet.patch new file mode 100644 index 00000000000..dd05afa6d6d --- /dev/null +++ b/agent/opentelemetry-agent/patches/requests-chardet.patch @@ -0,0 +1,46 @@ +Use the vendored charset_normalizer instead of looking up chardet. + +Upstream prefers an installed chardet (via importlib.import_module and a version +import), which would load the application's package. + +diff --git a/requests/__init__.py b/requests/__init__.py +--- a/requests/__init__.py ++++ b/requests/__init__.py +@@ -51,10 +51,8 @@ try: + except ImportError: + charset_normalizer_version = None + +-try: +- from chardet import __version__ as chardet_version # type: ignore[import-not-found] +-except ImportError: +- chardet_version = None ++# Only the vendored charset_normalizer is used, never the application's chardet. ++chardet_version = None + + + def check_compatibility( +diff --git a/requests/compat.py b/requests/compat.py +--- a/requests/compat.py ++++ b/requests/compat.py +@@ -34,19 +34,8 @@ except (TypeError, AttributeError): + # ------------------- + + +-def _resolve_char_detection() -> ModuleType | None: +- """Find supported character detection libraries.""" +- chardet = None +- for lib in ("chardet", "charset_normalizer"): +- if chardet is None: +- try: +- chardet = importlib.import_module(lib) +- except ImportError: +- pass +- return chardet +- +- +-chardet = _resolve_char_detection() ++# Always use the vendored charset_normalizer, never the application's chardet. ++from opentelemetry.agent._vendor import charset_normalizer as chardet + + # ------- + # Pythons diff --git a/agent/opentelemetry-agent/patches/requests-packages.patch b/agent/opentelemetry-agent/patches/requests-packages.patch new file mode 100644 index 00000000000..fd76330cfcc --- /dev/null +++ b/agent/opentelemetry-agent/patches/requests-packages.patch @@ -0,0 +1,37 @@ +Disable the requests.packages compatibility aliases. + +Upstream imports urllib3/idna/chardet by their top-level names and registers them as +`requests.packages.*` in the global sys.modules, which would load and alias the +application's own packages. + +diff --git a/requests/packages.py b/requests/packages.py +--- a/requests/packages.py ++++ b/requests/packages.py +@@ -1,23 +1,4 @@ +-import sys +- +-from .compat import chardet +- +-# This code exists for backwards compatibility reasons. +-# I don't like it either. Just look the other way. :) +- +-for package in ("urllib3", "idna"): +- locals()[package] = __import__(package) +- # This traversal is apparently necessary such that the identities are +- # preserved (requests.packages.urllib3.* is urllib3.*) +- for mod in list(sys.modules): +- if mod == package or mod.startswith(f"{package}."): +- sys.modules[f"requests.packages.{mod}"] = sys.modules[mod] +- +-if chardet is not None: +- target = chardet.__name__ +- for mod in list(sys.modules): +- if mod == target or mod.startswith(f"{target}."): +- imported_mod = sys.modules[mod] +- sys.modules[f"requests.packages.{mod}"] = imported_mod +- mod = mod.replace(target, "chardet") +- sys.modules[f"requests.packages.{mod}"] = imported_mod ++# The upstream module imports urllib3, idna and chardet by their top-level names and ++# registers them as `requests.packages.*` in the global sys.modules. In the vendored copy ++# that would load (and alias) the application's own packages, so the backwards ++# compatibility aliases are disabled. diff --git a/agent/opentelemetry-agent/pyproject.toml b/agent/opentelemetry-agent/pyproject.toml index 143d4c21579..452831696c5 100644 --- a/agent/opentelemetry-agent/pyproject.toml +++ b/agent/opentelemetry-agent/pyproject.toml @@ -53,10 +53,39 @@ drop = [ "urllib3/contrib/pyopenssl.py", "urllib3/contrib/emscripten", "urllib3/http2/connection.py", + # protobuf: benchmarks and test helpers (import google_benchmark/numpy/unittest_pb2), the protoc + # plugin API, and the cpp implementation shim (unused: the pure-Python implementation is forced + # by patches/protobuf-pure-python.patch). + "google/protobuf/internal/*_benchmark.py", + "google/protobuf/internal/testing_refleaks.py", + "google/protobuf/testdata", + "google/protobuf/compiler", + "google/protobuf/pyext", +] +# Applied in order after imports are rewritten; paths inside the patches are relative to destination. +patches = [ + "patches/requests-packages.patch", + "patches/requests-chardet.patch", + "patches/certifi-resources.patch", + "patches/protobuf-pure-python.patch", ] -patches-dir = "patches" sbom-file = "src/opentelemetry/agent/_vendor/bom.cdx.json" +# Files whose findings from the vendored-code checks have been reviewed, per check. +[tool.opentelemetry-vendor.allow] +dynamic-imports = [ + # Only imports stdlib codec modules (encodings.*, _codecs_*). + "charset_normalizer/cd.py", + "charset_normalizer/utils.py", +] +side-effects = [ + # Warning filters only target requests' and urllib3's own warning classes. + "requests/__init__.py", + "urllib3/__init__.py", + # set_environ() temporarily sets an environment variable and restores it. + "requests/utils.py", +] + [tool.hatch.version] path = "src/opentelemetry/agent/version.py" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt index b2a8820999b..3c12e957441 100644 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt @@ -1,12 +1,206 @@ # This file was autogenerated by uv via the following command: -# uv pip compile --python 3.10 --universal vendor.in -o src/opentelemetry/agent/_vendor/requirements.txt -certifi==2026.10.23 +# uv pip compile --python 3.10 --universal --generate-hashes vendor.in -o src/opentelemetry/agent/_vendor/requirements.txt +certifi==2026.10.23 \ + --hash=sha256:a9895e6e2758b371e0545e321a3a8fd1fcfd9829ada8824a936dfb16aaaf36cd \ + --hash=sha256:e9b54de76e530bb6cf0ccd036787103acb58fd42ba930ea8bf948ddbaa2f61d1 # via requests -charset-normalizer==3.5.2 +charset-normalizer==3.5.2 \ + --hash=sha256:01077390b03f7988f11d700a2194e69b119741a86b1a638b1db88891e3eced8e \ + --hash=sha256:01b0c0d2262a9e28e8484a278c7e1b5d650e3ac8cf2683d2967e25899f208bdf \ + --hash=sha256:04851f73ae72b8413dddadb16a49dfee95263553741fd42d546f7d66907e6be5 \ + --hash=sha256:0521c5665880b33d603717defa76c094048900010897909952397feb3039da56 \ + --hash=sha256:0774bf9bf620249fee3e0b8b9fd3065de213be30f3aa94ce2494b3b638949e26 \ + --hash=sha256:0891b9d3903c5571c03771ca669a4b0ec5618ca722a5c957d3d29cd4e5062848 \ + --hash=sha256:0c951d5e6dd9c2ff60609476752bee49da4206adde960ebc247766937f72e718 \ + --hash=sha256:0fed1d06615f022ee3b13caf5e8b180cfea32bb2c5aded8a9d44277afc040f93 \ + --hash=sha256:114e4d0c92d618409ed82a99e22b5c5e768fe995f2973f78265f4524f49d4640 \ + --hash=sha256:11912e4bb14baae7c5d8791aa55ba0a3a03ec6729073307b0f57270abaa713d3 \ + --hash=sha256:11a4d68a6ecda3292cb1e50239e111543ba5d709bb62a6b4ea1afcfa729d8875 \ + --hash=sha256:124fbf1a8ff966d87ae05bb8bd45a71f966055ed8bba320d0c7cf450bc5f4d0e \ + --hash=sha256:1461ac396c4fdb983a675f20aa555624f0ee18ac83d832b9244ffff3d8055275 \ + --hash=sha256:1503bccbeb36d5527790c3930327704c39af22de3112f1b1666a9f3ce15ee204 \ + --hash=sha256:15bb4005af6320d259dc7593ca84a38d7fe06a421dbcf7b910ae23979101e787 \ + --hash=sha256:15c44f7edfd477b06f517a5cc317fc1707edb9de2c865f43d4b6513907473234 \ + --hash=sha256:16fa0eccf81304b79c5cd87f9271c3b85dd9dd99245e4422ae9c0dd45e0f99d3 \ + --hash=sha256:183b88127acdb4fabe59d951ab424faf1af7b63cdbb5f776186c1ea2ffcaed98 \ + --hash=sha256:195c26fb65950f8fce54e26349852b7bdd7c5f120aeefbcc440b8a20faaed4a3 \ + --hash=sha256:1afb975bd5d68d5ce9f6b6d44fdf2f7e34b895a35e95708a7a91b20a3b51d187 \ + --hash=sha256:1b4cbc7c3491ccb4aa17fcd8165649d01cf39f76de1696da8631b5f71b85401d \ + --hash=sha256:1bc0baf5ef96b6ede57d47f4b8fe4d9d84019c3bfcbeb20a41edc6a6ee341f1f \ + --hash=sha256:1c50fe28bbc2ced33386f298650d91218076c05420e6cbd790b913adc41659e7 \ + --hash=sha256:1db38f4c5496827c1a501846d64d14c3b80c7e6714e406cd7dc36a9899fa1011 \ + --hash=sha256:211d5a3eb6af8f513b8d4ca19a8c1b7accab1b5f0d3175f9826b03c1a920dc1f \ + --hash=sha256:23851fb4e1b85ed3f6c2a27b777cdfe2e19fb5b38429a8faf38c7542b7665869 \ + --hash=sha256:254eb48b9fa5ee9898a3c445825a1f340fe53712a098904b39b0bddba8ea3cb1 \ + --hash=sha256:2625388c6c754520c37abaf3b41eb34d1cc4a373f457898f08606c8e362b891d \ + --hash=sha256:281cb91036248400f4cc957495cccd44c275c2e0c5854f7e45ac5cf7dc193847 \ + --hash=sha256:28a15fdad492a99b6eccfaaed66ef3f74050680545ea61ec8b2f4c538f1f1320 \ + --hash=sha256:28b4f0d66fb834ff90f28209ac7bce77868c45d8c93e26f906709d9b7c2e1af9 \ + --hash=sha256:2a925889534b3748302dae5dead07cc13480de1dac3aea80a941b729b471ef93 \ + --hash=sha256:2b7b3bbfb4fe8ef40600792d762fbaa9057559f9d3fad209525b7a22b99e91fd \ + --hash=sha256:2c9ad19a6cfcd5ea5c0d41161d22f9df1dcc277e9bef2751391334546a314c00 \ + --hash=sha256:2cc961b171b3f3440f410489ab3573e86aea8736134ebbb40ea1338b7f0831bc \ + --hash=sha256:2ce45c6627b22c47e390bc91a41c3d13032192e699fa0bea96e9671b373d69b0 \ + --hash=sha256:2e06a3a98f916dd41d27f3105e02e7a40181c98c94b9158733d03a6f80506c09 \ + --hash=sha256:304d5463e65a35d7bb0850550e0780395395f6fcf452f04db7d5ca7cecc425ac \ + --hash=sha256:304d8e4d493af723536393eee0c689eb7813f4a474c8b479dee63f1fdd98f621 \ + --hash=sha256:30fcd120b732aa79317f08dee04d7de0847822e4cf7ee0e9f445bb958832252c \ + --hash=sha256:31f3930700408d211f13378ccbe1c40845d8da54bd0681fac3a9b5aae81c7aa8 \ + --hash=sha256:34276fd796040bf0993ab33a369aa572e6979c7aab225a88893667ad8eac8f7a \ + --hash=sha256:355ad8011081dec5412240c087a9a0c9d4d5039f3ed11a3f13e18c2b29b56c51 \ + --hash=sha256:38a873987f3be698494da8b2e3085e29da02da7b633dce73e79c699a113d7bf0 \ + --hash=sha256:39de2a259fc954455c57274dc94c79d5842774e1247a016aff30bc0efed0f4ef \ + --hash=sha256:3d14b50de6bf4d0edf857a9386836846f982b8f524e188e2e68b96d702bcf4aa \ + --hash=sha256:3d21b8b13c7592db2ac5e544a6d83187b995257472b0c9e8351b6d507ae37ed6 \ + --hash=sha256:3d31298449090ab8d47b7b1b2a555ff73cac7ed438a08b7ac160980c7ebed649 \ + --hash=sha256:3ddacd27458c45bdacd6bd6db644bfb730efbf9e830310186e3045c9c5be8fb2 \ + --hash=sha256:3df041de8887954562c9b261cba85ca0e9ded74048daf125f45edcfaa4832229 \ + --hash=sha256:40ab6bffa02ae10a0581e6c198be7d2d8ca5c2a0c64e4ed3465d766df457573e \ + --hash=sha256:4275811936e2f06feff5e598fb42a1b7ae852da8e39605211892b56b81a34efd \ + --hash=sha256:443eae2bf318abeaf6f15d785138f71fd6de770e99a92158b8b814265e079115 \ + --hash=sha256:447441e76ec720b15e64418d32e092297340387053047c7c694f579efb0ee1d9 \ + --hash=sha256:4495c5002a7b28557e7e222e77e0b661183e432b7d6d2e788101e3f240e05b8c \ + --hash=sha256:44bd4fbb29dfbeba60e7d2bd000c59e4b21ddb3cc53912b14048d37092706d7c \ + --hash=sha256:4685902cf26edf013ed7a3da0f426ebba7a00ebb9541386d835afbf002c11cab \ + --hash=sha256:498dc3188ca05a68231ac3fdbfc7f57eb67e1343c30e0fea17f8218c1599b253 \ + --hash=sha256:4c2b5031f63e331e3839b40aed2dd6f191e9c07edbde303e7876846ea1946995 \ + --hash=sha256:4d48f2d08b9de5864e2c8744d4461b862fb149a18274abc8b698c45975573438 \ + --hash=sha256:4f87960d57feabfb618e4e0af6e7371645fa26a277860739d6e5d6e0012c92f0 \ + --hash=sha256:50e3adfb96fc189eb27b1cf62d3b598b89b4bb0420d93a3d3e42e137409011be \ + --hash=sha256:51cf45226a9b588d0d2b4880c62d686934b63ab0bd79ca23ab0e9762eb27441b \ + --hash=sha256:52aa6992700996af31f375de0c6bacd402b0097fe40b53c426b9f51a90ebabc7 \ + --hash=sha256:55ea99acb17b9325618de155a0cd6a2e8f5d10be008113e1d433bbb58db543b2 \ + --hash=sha256:56bc200a365efb37383b7852e4cc5898d3b2da5987289b543956cf8cad71018a \ + --hash=sha256:588461c2e8384d309bd63e5826019b6977bc66d629b99ac8737bb795d7b2cb5a \ + --hash=sha256:58ca3755ee7ff7f59b57789ec9833c9de9ea275405cdd240eda1f193112e398a \ + --hash=sha256:58f361dcbab699cf8f42db3f47c8e7fd1036f138c23a5d08de9fde5f425a730c \ + --hash=sha256:598a11a2c7ebaa5334bf698bf29568c9c390abac6a154d8170fedecd1cea38c5 \ + --hash=sha256:59f63901b0031c3136cf64704dcb21de0bbae62ce2c9529bc39d27665463de37 \ + --hash=sha256:5cde776b7cc66e4f6c99612cea4aa7269aa65863f7a15841b2c264f103822f4e \ + --hash=sha256:5e2b6b57e9733d39f0c9fd3185efa6b8e29652c4cd8fe94180272cf6ed9a78c4 \ + --hash=sha256:5fb29fb8cd1a46c27a1bf9613ad5ec2599310d46b4025d9556404a6b6a292800 \ + --hash=sha256:6045373d5a89a5ec71afde535db987ca28e76dfa276c2d4c818265b375d4b055 \ + --hash=sha256:619799369eeef6366ed3e8755a5670f4f2f0fb6b30a0fd7264dc0fdc2357058e \ + --hash=sha256:62588a277bfb59def052abd940703fa35107152bf479781a878617d60faf8fb5 \ + --hash=sha256:62603db9a7caa0802eaa28c1c46fecd7b3a263a774069c24c3c28c302448721c \ + --hash=sha256:65cd72beeeca9d3aaea1201e5923859f308f952f9c71de93f06063c79f0f7a3b \ + --hash=sha256:68eb192d85ab8e5f6ec69c2bc6ac0179fbf04a5ac1569d12fbef74883fe102d0 \ + --hash=sha256:6bd128f206a7752ae1f2ab6c61bf8a24ba28913a10df8b14c2637b973ff97a80 \ + --hash=sha256:6be488a102b8cf28d0391d8c4ba7748938ae28b78ad901f8585520fca33ead1a \ + --hash=sha256:7218e8f32b0956cfcd048fd42d9d5779809745ca1d86113ca56f66e7ae1549c4 \ + --hash=sha256:7441d755b7ab94f8d4eb3e43ec05482d760842fd263d003a99102d742cd835e2 \ + --hash=sha256:749e97e1b32313717a565abbe321bc2190bc8b35f1a67e4cdbc7c56c8d8ffe58 \ + --hash=sha256:75a3ceed0724d625d64b86ca20aba182e4df462e04c2414fc941c0f523f06aac \ + --hash=sha256:780fbe7cab297b81dad9fb8dc5eb003c0468ffb0d9e5f65068c53a34661a96bc \ + --hash=sha256:78456a747de8dc58360ffa581f30a002baf5aa28cb262536545e91f113ed7639 \ + --hash=sha256:7967d08cf06dee78443b874f98c98036f624f3a4e73e11f9f64f5be4d25393cf \ + --hash=sha256:7a881931aa470808df94a8c380eed2bbbc76cd9dc622310f99665658c821eb6d \ + --hash=sha256:7dcd882da75ef9adf94903b1e3b9419e8aa8fb4c7396822b834b9ef7fb96954f \ + --hash=sha256:7e841fb9010836c992c9f12fcbd43a831de93a5f726fc1ccd8ca1d0268c5014c \ + --hash=sha256:7fdde2c9fd9e3eca40631e024664cf2584272cc8f96308cbe5fdfc930f51d8bc \ + --hash=sha256:8024d00c3faf3fc0c16e07a69f4405e8eac7cc0ab15f65fe6cf43827c4cf72b4 \ + --hash=sha256:80d02b6f04e92601a081dd97b23d3128033098bff5d35d392ddcc0476ea11253 \ + --hash=sha256:838dcc90063569a0448120554591a1d6c4a4ffe11babf048908793154ab86ade \ + --hash=sha256:849df64e889b2e17230d58410a03dba311a65b163508fd33679b2b737d4b7858 \ + --hash=sha256:87475fabc8d9996fd9c27debb395e642e8c838d78a00b6e932227a0e06b81e26 \ + --hash=sha256:87e50a3e7cb90af586b6c5faf23e302a970415ac73bd7bd90a515a04b427ef96 \ + --hash=sha256:89b53f3cda69831909888e0494f4fa0bcd3537e3e138dabeb620bd6ad946bae8 \ + --hash=sha256:8a893cc101149f80a653f82062ebc95b34525a2614382e1da5458fe7c6997249 \ + --hash=sha256:8b2bfab86aa71ae13aa41a6a26aab338e0db2b8bc75434b05aea89e011ff35a4 \ + --hash=sha256:8d86d6fc60743dc916eb79e2eb1ec4818e21e427731543af40a3021851174a13 \ + --hash=sha256:915563965d418f986e7e145accc592eae9e1a1be3566ff98a05d7a9ec42a76e1 \ + --hash=sha256:92888bb3187c5ba50500b00b3b310c9f2c651709d28036077680cb5255450a03 \ + --hash=sha256:93223adc95033dd47133a46ccfc316a0139176fd79085762e27202ec56018f03 \ + --hash=sha256:9373ad13ef0d2c0fb761e04e55bfdee5a08b52cef2c882c8fbe9935b1517152e \ + --hash=sha256:9409a8bf35cf78353942504b24a57de3d75b708997a1e4bd8db71ac8633ce364 \ + --hash=sha256:9b7f416ff0978e2f2249330527f0ad6fa02f4932e6199692d3b52da2048c19e4 \ + --hash=sha256:9bde855991b7e362c146535e3136a50bfaffc0487d38b33ca7e5edefc6e23849 \ + --hash=sha256:9cae88599c7219005d879f98e5ed53341e9a122af585e1091200358a3003d2a0 \ + --hash=sha256:9cf9b1a857e25c4baceeb3624e92a56df3668f398c4acba74e174d81fb4d1d3a \ + --hash=sha256:9f56f72050826f63dcee7a7f55b0a77168cb3bfc553fd405e7f8f9ece75a4036 \ + --hash=sha256:a090bb2c68df85450502e3e20d665e3a5af9c65a84d6508ed477badd49166fd3 \ + --hash=sha256:a192e2c40070d92c3ccf777e3a5c4ff515573cd2bb7ed0c537fdadbbec5bbf21 \ + --hash=sha256:a19a731138fc27d5682277d3b9df22855cea1239bce7fcec5f78f42ef2d1f3c3 \ + --hash=sha256:a66c3bc5ab1f0ff2164fc9965ddd611ff0802173f4b9d24554c563f6ab7e1d6e \ + --hash=sha256:a815775b6c38d4e0ff7bcffbeba67feded90202bb6a226b8dd35f1c855217413 \ + --hash=sha256:a89012d6d5476ee112d20d998570ed58df2260a852afb1758809cd6900411d21 \ + --hash=sha256:ae4f5fea5b8b8ccff88238cc8569303e5ee95efae67fa62922a311397a71f346 \ + --hash=sha256:b6856554c4f44d79fc2307d5768854310a8f0096e501c75637542c82292b0429 \ + --hash=sha256:b6b751274acb69d77b3323d6b7dbaa3c7fdfc1eb829b7eb61d262f32e1af9685 \ + --hash=sha256:b736353c0a625bbd5fcec108576e2385db3496f4f771f785ff32e108d3c3bc45 \ + --hash=sha256:b7fd005a73d9e657273b7a10dc71a9e03c8fb9ee6999798d6918ce095b81ac7f \ + --hash=sha256:b91363207bd9dc966a691e959bb47f64b30f7ac4b072be9968b366982f7db77c \ + --hash=sha256:ba0b1d2620edf869789c3879223f52bf2afc5d31b3cb47cc57b3a12c05e2aa9d \ + --hash=sha256:bbbfc8e28816f19d7c0f1816664980c0a9875d01b27cdf8eedddb639d9e108ad \ + --hash=sha256:bd16aabe4a02a297c23417aa17ac6299dbd8c49f673bcd645b4929b11f5a4400 \ + --hash=sha256:c0afc6800ba57ccc350374c5bd6150419915d95ce93cdbab2d783d75eaf30ecb \ + --hash=sha256:c6708715abcf3c73b99508253e961a9967f02fe536532834149574eda6de0d1c \ + --hash=sha256:c7c9ab723cde841fefb34efbad91e87f00a674b1fe1cd0784fde742bf2c154dc \ + --hash=sha256:c8f3d67aeaf55f017982b73683f0e7342ba2f6635a78f69ce89ebb26aa411e5c \ + --hash=sha256:c9790464842f85f437dbbb54417eda1e0e6bfc52dd8d22d6fd1c994b73b2dc74 \ + --hash=sha256:ca403d7e4798f525fdfc78e258820419cbbd0f0ecbab9de7840e3c017cf6b8cf \ + --hash=sha256:d008d90a7f2471519aef0c90dfbe73b3e6e4d5e66ac48e19154c17e89e98b604 \ + --hash=sha256:d19fbd981a488e22cd04883659ca6b08f50b5974f9fd7c95655ef6a043e5893f \ + --hash=sha256:d1befeed746d247c81127bb14de9dc3d30edb6e5976d34f83f86ed262b1d9105 \ + --hash=sha256:d2374b62878abb00cd8309b32af6c0b715cd02dec0ca74ef12e5069bdc64144a \ + --hash=sha256:d376bbd28b3a8999db1a103b3b388aee6f1ddeb3e51bc2172993efdcd86e064d \ + --hash=sha256:d4a7319f304a774bed22115bc891618e45f85065ab44ea6acd07d274e750519a \ + --hash=sha256:d6734d2ef8a50fbf8445c139477da401f50d62a0606bf00e20ec6d87773fefb1 \ + --hash=sha256:d760fe2a4d7c3b226cb9026d6a842868d52a7901bd98420e1baf14e80da85cf5 \ + --hash=sha256:d913de495d90407cd859d263bee2e5d1a4ed3eb6573c04e70d9ec619a7cbed7f \ + --hash=sha256:db19d07e2e0129e974a0e65d0064fc222a446cd5122c2fd4184d2af9fc734a9e \ + --hash=sha256:dca9ab98072a5a54ebacebdc45f53e645336b320c667410b061be1ca588ae709 \ + --hash=sha256:ddc7dacc8ece3a182e7f15cb862d1fd616b46d076cb1ae9dd232b2c38b655874 \ + --hash=sha256:ddf19c062bea7a0cc80f519243d2c01dd091be0cf952a0750d4ad576709559f5 \ + --hash=sha256:def79fa35ef0cef8d2accec024f4fdc7ead3012ff02f5215c783f39f03ef8cfc \ + --hash=sha256:df29a0a7107f7011e77f4eebdddec4c7331e24d787a0b21a46d63bdf7445da95 \ + --hash=sha256:e09a3942ecbdee5cce73ea9d42da82b81b72ac1bf031ce069b93b5adf4eac8cd \ + --hash=sha256:e242bb1c5e76e97dfa9e7f209a71e93a01d7f19ffdd5cfbb2e2d55b4f08f8ab0 \ + --hash=sha256:e243bd13217235fc7290c621941c3f5cc8b66e4872495be821d7436ba2fb838d \ + --hash=sha256:e2af3aad578aa6bd1384bcf4750fc285e5a9de53f40b7d41e5a0bf748edeb2b3 \ + --hash=sha256:e4e81e09c1578b8df602e3db08b0b3ea0a6947ad612f52bf8dc5ea8d47691f0c \ + --hash=sha256:e54da4baf05720032d527874d40b65fa4d7e5c6c6a43d0c3adbeffcaf275a2b3 \ + --hash=sha256:e80e6c2f55656b4824d72065abb4ddd6a525c74bd78a0aab5d9fc2cf4fb5af50 \ + --hash=sha256:ed2a239c0ea213acc1908150a3037257083c7c083128f1a4cec2ec4b97dca491 \ + --hash=sha256:ed905975ab14056a2e5eb1c376cb2e1ebc5396baf84163939c518556fccde9f5 \ + --hash=sha256:ee21e28f0430bd6dc9086c6e525d5e818a44a5ad19720c8a0ef766792f3eb5e5 \ + --hash=sha256:ee43c17b173d46a3212baa6ead3ae258eeabdae48c263a01ccf0218c366dd655 \ + --hash=sha256:ef4fcbf3327382cd4c9f540babd61248208af7b93eec4de397b4d5f58a09e288 \ + --hash=sha256:eff0ac9dbe711a4aee69bf04a83896aa9b85f19641264053a9f6d48573abb7dd \ + --hash=sha256:f0aa869112ef88429ae17820d99c3dd9504c9e9c671d3c246f3d7442cb051084 \ + --hash=sha256:f3c96f633825733f735c5a9cf21d21a257d8e1edf0b1cee0a064b9c424ca0f7d \ + --hash=sha256:f5833ad231be5eb6553de524a70f48d71b2c8563101750531e0b80184e175cd4 \ + --hash=sha256:f5ec61164adcec446f8969a3358ec3f9b26bbda3b9213e5586d219afa8df2915 \ + --hash=sha256:f7d486c83842422badd511868fd8a9a20e9407ace71564b6af47ce7e60a336c1 \ + --hash=sha256:fb9e68df06293761f9fe66ade60a9bc6d0f5e42b8acf2939a9158af86ab0e5bd \ + --hash=sha256:fc14a032f813bf5fe624d991960ea83e9715adc27e4c1830a2361eb1d02ac341 \ + --hash=sha256:fcff63213e8e6e47770541a4607175404f47cbb3ebea7b6058cc82d524a0e424 \ + --hash=sha256:fd1fbe0f116b6e55da77aca2c6ddcddcfac2186cbf78bdebf40fc156efca389d \ + --hash=sha256:fe9753dfee015c570d73df76f899f18444d41388bffcde097deba51c4fadbb9f # via requests -idna==3.20 +idna==3.20 \ + --hash=sha256:a7db850025b95ded1eae8a46181a1a6c56c92c96f0e2b005d9ff8dc0210cab44 \ + --hash=sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c # via requests -requests==2.34.2 +protobuf==7.36.2 \ + --hash=sha256:497d0463ff3316681da6c0b9e8d06cb465d61abce00b613ab42226175644d1bb \ + --hash=sha256:89f23aa53c24553a2416fd4fd1ec06f74fa42b14b546d8883128813f775bbfd2 \ + --hash=sha256:912c1221170e16c08d1f086762f563dd61ff83c18b5fa6652952dfaded66f728 \ + --hash=sha256:a300819d441e078a5608c0d3c709796bb548136058fda017ae51d425b44fd353 \ + --hash=sha256:bdb3a345d48db958e6ce1f18e508beb0cc981d64f24088427549c866cd039f1e \ + --hash=sha256:cbc70b17ee27e28894c7fee8bb04be1abead49e936bc70eb60052531eee2079e \ + --hash=sha256:e11e1f0180583a2af89db6a2ecd9e8dc40aa6d2988ca175bfd0e6d12ea72d74e \ + --hash=sha256:f4fee11ec330d238b34a05c9b675f693c20415d1c5bd7d5320cc2f8a798eb9cf # via -r vendor.in -urllib3==2.8.0 +requests==2.34.2 \ + --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \ + --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed + # via -r vendor.in +typing-extensions==4.16.0 \ + --hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \ + --hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5 + # via -r vendor.in +urllib3==2.8.0 \ + --hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \ + --hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63 # via requests diff --git a/agent/opentelemetry-agent/vendor.in b/agent/opentelemetry-agent/vendor.in index f2293605cf1..ddde19a7e46 100644 --- a/agent/opentelemetry-agent/vendor.in +++ b/agent/opentelemetry-agent/vendor.in @@ -1 +1,3 @@ requests +typing-extensions>=4.6.0 +protobuf<8.0 diff --git a/agent/opentelemetry-vendor/README.rst b/agent/opentelemetry-vendor/README.rst index e69de29bb2d..e785696f593 100644 --- a/agent/opentelemetry-vendor/README.rst +++ b/agent/opentelemetry-vendor/README.rst @@ -0,0 +1,60 @@ +OpenTelemetry Vendor +==================== + +Patches +------- + +Vendored packages can be modified with patch files listed, in order, under the ``patches`` key of +``[tool.opentelemetry-vendor]`` (paths relative to the project directory). ``sync`` applies them with +``git apply`` after imports have been rewritten, so they are written against the rewritten code and the paths +inside them are relative to ``destination``. All patches are applied, or none are. + +Text above the first ``diff --git`` line is ignored by ``git apply``; use it to explain why the patch exists. +Each patch is recorded in the SBOM as the pedigree of the package it modifies. + +To write a patch: + +1. Run ``opentelemetry-vendor sync PROJECT_DIR`` and commit (or stage) the vendored files. +2. Edit the vendored files. +3. Run ``git diff --relative= > patches/.patch`` from the project directory and add an + explanation at the top. +4. Add the patch to ``patches`` and run ``sync`` again to check that it applies. + +Checks +------ + +After rewriting and patching, ``sync`` checks the vendored code for anything that escapes the vendor +namespace and fails on findings that haven't been reviewed: + +* ``imports``: an absolute import of a vendored package (e.g. added by a patch). Always an error. +* ``dynamic-imports``: ``__import__``, ``importlib.import_module``, ``importlib.resources`` lookups and + ``sys.modules`` writes that can load modules by their top-level names. +* ``logger-names``: ``logging.getLogger("")`` calls left after rewriting. +* ``module-names``: vendored module names left in protobuf builder calls of generated ``*_pb2`` code + (``BuildTopDescriptorsAndMessages(DESCRIPTOR, "", ...)``), which set the classes' ``__module__``. +* ``side-effects``: changes to process-global state: warning filters and environment variables. + +Fix a finding with a patch, or, once reviewed, add its file (relative to ``destination``) under the +finding's kind in ``[tool.opentelemetry-vendor.allow]`` with a comment explaining why it's safe. An entry +that no longer matches anything is an error, so the list stays current. + +Requirements must be pinned with hashes (``--generate-hashes``); ``pip`` then verifies every downloaded +wheel. + +If ``sync`` fails, the destination is cleaned back to its protected files, so a half-built tree (unpatched +code, ``*.dist-info`` directories) is never left behind. The ``*.dist-info`` directories are always removed: +their license files and metadata are captured in the copied license files and the SBOM, their ``RECORD`` no +longer matches the rewritten code, and ``importlib.metadata`` can't find them inside a package anyway. + +Upgrading vendored packages +--------------------------- + +1. Edit ``vendor.in``, then re-run the ``uv pip compile ... --generate-hashes`` command recorded at the top + of the requirements file to update the pins and hashes. +2. Run ``opentelemetry-vendor sync PROJECT_DIR``. +3. If a patch no longer applies, re-create it with the patch workflow above against the new version (or + remove it if upstream fixed the issue). +4. Review new check findings: patch them, or add the file to ``[tool.opentelemetry-vendor.allow]``. Remove + allow entries that ``sync`` reports as unused. +5. Review the diff of the vendored files and the SBOM, then run + ``opentelemetry-vendor sync --check PROJECT_DIR`` to confirm the committed files match ``sync``. diff --git a/agent/opentelemetry-vendor/pyproject.toml b/agent/opentelemetry-vendor/pyproject.toml index 997b760121c..152ec83dc8e 100644 --- a/agent/opentelemetry-vendor/pyproject.toml +++ b/agent/opentelemetry-vendor/pyproject.toml @@ -27,6 +27,7 @@ classifiers = [ ] dependencies = [ "cyclonedx-python-lib[json-validation] >= 11.0, < 12.0", + "libcst >= 1.5, < 2.0", "packageurl-python >= 0.11, < 1.0", "pip >= 25.0, < 27.0", "rich >= 13.0, < 16.0", diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py new file mode 100644 index 00000000000..2f1fc46d908 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py @@ -0,0 +1,231 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Check the final vendored tree (after rewriting and patching) for code that escapes the vendor namespace. + +Each finding has a kind: + +* ``imports``: an absolute import of a vendored package left over, e.g. added by a + patch. Always an error. +* ``dynamic-imports``: ``__import__``, ``importlib.import_module``, + ``importlib.resources`` lookups and ``sys.modules`` writes that can load or + register modules by their top-level (non-vendored) names. +* ``logger-names``: ``logging.getLogger`` calls with a vendored-name literal left + over, e.g. added by a patch; they log to the application's logger. +* ``module-names``: protobuf builder calls (in generated ``*_pb2`` code) with a + vendored module-name literal left over; the generated classes' ``__module__`` + would point at the application's package. +* ``side-effects``: changes to process-global state shared with the application: + warning filters and environment variables. + +Findings of every kind except ``imports`` can be allowed per file after review. +Names are resolved through imports, so aliases such as ``import sys as _sys`` are +recognized. +""" + +from __future__ import annotations + +from collections.abc import Collection, Mapping +from dataclasses import dataclass +from pathlib import Path + +import libcst as cst +from libcst.helpers import get_full_name_for_node +from libcst.metadata import MetadataWrapper, PositionProvider, QualifiedNameProvider + +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.rewrite import BUILD_TOP_DESCRIPTORS, alias_name, is_vendored, parse_file + +IMPORTS = "imports" +DYNAMIC_IMPORTS = "dynamic-imports" +LOGGER_NAMES = "logger-names" +MODULE_NAMES = "module-names" +SIDE_EFFECTS = "side-effects" +ALLOWABLE_KINDS = (DYNAMIC_IMPORTS, LOGGER_NAMES, MODULE_NAMES, SIDE_EFFECTS) +"""Finding kinds that can be allowed per file in ``[tool.opentelemetry-vendor.allow]``.""" +_KINDS = (IMPORTS, *ALLOWABLE_KINDS) +ALLOW_TABLE = "[tool.opentelemetry-vendor.allow]" + +_IMPORT_FUNCTIONS = frozenset({"builtins.__import__", "importlib.import_module"}) +# importlib.resources functions taking a package (anchor) as their first argument. +_RESOURCE_FUNCTIONS = frozenset( + f"importlib.resources.{name}" + for name in ("files", "path", "read_text", "read_binary", "open_text", "open_binary", "contents", "is_resource") +) +# Names that resolve to the calling (vendored) module at runtime. +_SELF_ANCHORS = frozenset({"__name__", "__package__"}) +_MAPPING_MUTATORS = ("update", "setdefault", "pop", "popitem", "clear") +_SYS_MODULES = "sys.modules" +_SYS_MODULES_MUTATORS = frozenset(f"{_SYS_MODULES}.{method}" for method in _MAPPING_MUTATORS) +_GET_LOGGER = "logging.getLogger" +_OS_ENVIRON = "os.environ" +_SIDE_EFFECT_FUNCTIONS = frozenset( + { + "warnings.simplefilter", + "warnings.filterwarnings", + "warnings.resetwarnings", + "os.putenv", + "os.unsetenv", + *(f"{_OS_ENVIRON}.{method}" for method in _MAPPING_MUTATORS), + } +) + + +@dataclass(frozen=True) +class Finding: + kind: str + path: str + """POSIX path relative to the vendor destination.""" + line: int + code: str + + def __str__(self) -> str: + return f"{self.path}:{self.line}: {self.code}" + + +class _TreeChecker(cst.CSTVisitor): + METADATA_DEPENDENCIES = (PositionProvider, QualifiedNameProvider) + + def __init__(self, module: cst.Module, path: str, names: Collection[str]) -> None: + super().__init__() + self.module = module + self.path = path + self.names = names + self.found: list[Finding] = [] + + def visit_Import(self, node: cst.Import) -> None: + if any(is_vendored(alias_name(alias), self.names) for alias in node.names): + self._add(IMPORTS, node) + + def visit_ImportFrom(self, node: cst.ImportFrom) -> None: + if node.relative or node.module is None: + return + module = get_full_name_for_node(node.module) + if module is not None and is_vendored(module, self.names): + self._add(IMPORTS, node) + + def visit_Call(self, node: cst.Call) -> None: + functions = self._qualified_names(node.func) + if ( + functions & _SYS_MODULES_MUTATORS + or (functions & _IMPORT_FUNCTIONS and not self._is_safe_literal(node)) + or (functions & _RESOURCE_FUNCTIONS and not self._is_safe_resource_anchor(node)) + ): + self._add(DYNAMIC_IMPORTS, node) + if _GET_LOGGER in functions and self._is_vendored_literal(node, 0): + self._add(LOGGER_NAMES, node) + # Also matches the builder after its import was rewritten into the vendor namespace. + if any( + function == BUILD_TOP_DESCRIPTORS or function.endswith(f".{BUILD_TOP_DESCRIPTORS}") + for function in functions + ) and self._is_vendored_literal(node, 1): + self._add(MODULE_NAMES, node) + if functions & _SIDE_EFFECT_FUNCTIONS: + self._add(SIDE_EFFECTS, node) + + def visit_Assign(self, node: cst.Assign) -> None: + self._check_targets(node, [target.target for target in node.targets]) + + def visit_AnnAssign(self, node: cst.AnnAssign) -> None: + self._check_targets(node, [node.target]) + + def visit_AugAssign(self, node: cst.AugAssign) -> None: + self._check_targets(node, [node.target]) + + def visit_Del(self, node: cst.Del) -> None: + self._check_targets(node, [node.target]) + + def _check_targets(self, node: cst.CSTNode, targets: Collection[cst.BaseExpression]) -> None: + if any(self._writes_mapping(target, _SYS_MODULES) for target in targets): + self._add(DYNAMIC_IMPORTS, node) + if any(self._writes_mapping(target, _OS_ENVIRON) for target in targets): + self._add(SIDE_EFFECTS, node) + + def _qualified_names(self, node: cst.CSTNode) -> set[str]: + return {name.name for name in self.get_metadata(QualifiedNameProvider, node, set())} + + def _writes_mapping(self, target: cst.BaseExpression, mapping: str) -> bool: + if isinstance(target, (cst.Tuple, cst.List)): + return any(self._writes_mapping(element.value, mapping) for element in target.elements) + return isinstance(target, cst.Subscript) and mapping in self._qualified_names(target.value) + + def _is_safe_literal(self, node: cst.Call) -> bool: + """Whether the first argument is a string literal of a relative or non-vendored module.""" + if not node.args or node.args[0].keyword is not None: + return False + argument = node.args[0].value + if not isinstance(argument, cst.SimpleString): + return False + module = argument.evaluated_value + if not isinstance(module, str): + return False + return module.startswith(".") or not is_vendored(module, self.names) + + def _is_vendored_literal(self, node: cst.Call, position: int) -> bool: + """Whether the positional argument at ``position`` is a string literal naming a vendored module.""" + if len(node.args) <= position or node.args[position].keyword is not None: + return False + argument = node.args[position].value + if not isinstance(argument, cst.SimpleString): + return False + value = argument.evaluated_value + return isinstance(value, str) and not value.startswith(".") and is_vendored(value, self.names) + + def _is_safe_resource_anchor(self, node: cst.Call) -> bool: + """Whether the anchor is omitted, the calling module, or a non-vendored string literal.""" + if not node.args or node.args[0].keyword is not None: + return not node.args + argument = node.args[0].value + if isinstance(argument, cst.Name) and argument.value in _SELF_ANCHORS: + return True + return self._is_safe_literal(node) + + def _add(self, kind: str, node: cst.CSTNode) -> None: + line = self.get_metadata(PositionProvider, node).start.line + code = " ".join(self.module.code_for_node(node).split()) + self.found.append(Finding(kind=kind, path=self.path, line=line, code=code)) + + +def find_issues(destination: Path, names: Collection[str]) -> list[Finding]: + """Find code escaping the vendor namespace in every ``.py`` file under ``destination``.""" + found: list[Finding] = [] + for path in sorted(destination.rglob("*.py")): + wrapper = MetadataWrapper(parse_file(path)) + checker = _TreeChecker(wrapper.module, path.relative_to(destination).as_posix(), names) + wrapper.visit(checker) + found.extend(checker.found) + return found + + +def check_vendored_tree( + destination: Path, names: Collection[str], allow: Mapping[str, Collection[str]] +) -> list[Finding]: + """Raise ``VendorError`` for findings outside the ``allow``-ed files of their kind, or for unused entries. + + ``allow`` maps a kind from ``ALLOWABLE_KINDS`` to destination-relative file paths. + Returns the allowed findings. + """ + found = find_issues(destination, names) + allowed = [ + finding for finding in found if finding.kind in ALLOWABLE_KINDS and finding.path in allow.get(finding.kind, ()) + ] + unallowed = [finding for finding in found if finding not in allowed] + if unallowed: + sections = [] + for kind in _KINDS: + lines = [f" {finding}" for finding in unallowed if finding.kind == kind] + if not lines: + continue + hint = ( + "imports of vendored packages must be rewritten; check the patches" + if kind == IMPORTS + else f"patch them or add the file to {ALLOW_TABLE} {kind}" + ) + sections.append(f" {kind} ({hint}):\n" + "\n".join(lines)) + raise VendorError("vendored code escapes the vendor namespace:\n" + "\n".join(sections)) + for kind, entries in allow.items(): + paths = {finding.path for finding in found if finding.kind == kind} + for entry in entries: + if entry not in paths: + raise VendorError(f"{ALLOW_TABLE} {kind} entry {entry!r} matched nothing") + return allowed diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py index 3959627bab3..626cae3baf1 100644 --- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py @@ -24,6 +24,13 @@ help="Directory containing the pyproject.toml to vendor for.", ), ] +Check = Annotated[ + bool, + typer.Option( + "--check", + help="Only check that the vendored files match what sync would produce; change nothing.", + ), +] Quiet = Annotated[bool, typer.Option("--quiet", "-q", help="Only print errors.")] Verbose = Annotated[ bool, @@ -37,11 +44,15 @@ def _callback() -> None: @app.command() -def sync(project_dir: ProjectDir, quiet: Quiet = False, verbose: Verbose = False) -> None: +def sync(project_dir: ProjectDir, check: Check = False, quiet: Quiet = False, verbose: Verbose = False) -> None: """Sync the vendored packages of PROJECT_DIR.""" _configure_output(quiet, verbose) try: - _sync.sync(load_config(project_dir)) + config = load_config(project_dir) + if check: + _sync.check(config) + else: + _sync.sync(config) except VendorError as exc: _fail(exc) diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py index aed98483189..fcd2f8f5ef3 100644 --- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py @@ -11,6 +11,7 @@ from pathlib import Path, PurePosixPath from typing import Any +from opentelemetry.vendor.checks import ALLOW_TABLE, ALLOWABLE_KINDS, DYNAMIC_IMPORTS from opentelemetry.vendor.errors import VendorError if sys.version_info >= (3, 11): @@ -35,7 +36,10 @@ class VendorConfig: python_version: str protected_files: Collection[str] drop: Collection[str] - patches_dir: Path | None + allow: Mapping[str, Collection[str]] + """Check kind -> files (relative to ``destination``) whose findings of that kind have been reviewed.""" + patches: Collection[Path] + """Patch files, applied in order after imports are rewritten.""" sbom_file: Path | None @@ -59,7 +63,6 @@ def load_config(project_dir: Path) -> VendorConfig: if destination == project_dir or not destination.is_relative_to(project_dir): raise ConfigError(f"'destination' must be a directory inside {project_dir}, got {destination}") - patches_dir = _optional_str(table, "patches-dir") sbom_file = _optional_str(table, "sbom-file") return VendorConfig( project_dir=project_dir, @@ -68,12 +71,25 @@ def load_config(project_dir: Path) -> VendorConfig: namespace=_require_str(table, "namespace"), python_version=_optional_str(table, "python-version") or f"{sys.version_info.major}.{sys.version_info.minor}", protected_files=_str_list(table, "protected-files"), - drop=_drop_patterns(table), - patches_dir=project_dir / patches_dir if patches_dir else None, + drop=_relative_paths(table, "drop"), + allow=_allow(table), + patches=tuple(project_dir / patch for patch in _str_list(table, "patches")), sbom_file=project_dir / sbom_file if sbom_file else None, ) +def _allow(table: Mapping[str, Any]) -> dict[str, tuple[str, ...]]: + if "allow-dynamic-imports" in table: + raise ConfigError(f"'allow-dynamic-imports' moved to {ALLOW_TABLE} {DYNAMIC_IMPORTS}") + allow = table.get("allow", {}) + if not isinstance(allow, dict): + raise ConfigError(f"'allow' must be a table ({ALLOW_TABLE})") + unknown = sorted(set(allow) - set(ALLOWABLE_KINDS)) + if unknown: + raise ConfigError(f"unknown {ALLOW_TABLE} keys {unknown}; expected some of {list(ALLOWABLE_KINDS)}") + return {kind: _relative_paths(allow, kind) for kind in allow} + + def _require_str(table: Mapping[str, Any], key: str) -> str: value = _optional_str(table, key) if value is None: @@ -90,13 +106,13 @@ def _optional_str(table: Mapping[str, Any], key: str) -> str | None: return value -def _drop_patterns(table: Mapping[str, Any]) -> tuple[str, ...]: - patterns = _str_list(table, "drop") - for pattern in patterns: - path = PurePosixPath(pattern) - if not pattern or path.is_absolute() or ".." in path.parts: - raise ConfigError(f"'drop' pattern {pattern!r} must be relative to destination") - return patterns +def _relative_paths(table: Mapping[str, Any], key: str) -> tuple[str, ...]: + paths = _str_list(table, key) + for entry in paths: + path = PurePosixPath(entry) + if not entry or path.is_absolute() or ".." in path.parts: + raise ConfigError(f"'{key}' entry {entry!r} must be relative to destination") + return paths def _str_list(table: Mapping[str, Any], key: str) -> tuple[str, ...]: diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py index 0ce89573bba..ea8a923e075 100644 --- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py @@ -44,6 +44,7 @@ def download_wheels(requirements: Path, python_version: str, dest: Path) -> list "--disable-pip-version-check", "--dest", str(dest), + # sync requires every requirement to carry --hash, which turns on pip's hash-checking mode. "-r", str(requirements), ], diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/patches.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/patches.py new file mode 100644 index 00000000000..29343ff9832 --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/patches.py @@ -0,0 +1,104 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Apply patch files to the vendored packages with ``git apply``.""" + +from __future__ import annotations + +import os +import re +import shutil +import subprocess +from collections.abc import Collection +from dataclasses import dataclass +from pathlib import Path, PurePosixPath + +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.metadata import VendoredPackage + +_GIT_DIFF_HEADER = re.compile(r"^diff --git a/(\S+) b/(\S+)$", re.MULTILINE) +_NEW_FILE_HEADER = re.compile(r"^\+\+\+ b/(\S+)$", re.MULTILINE) + + +@dataclass(frozen=True) +class VendorPatch: + path: Path + text: str + files: tuple[str, ...] + """POSIX paths, relative to the vendor destination, that the patch touches.""" + + +def read_patches(paths: Collection[Path]) -> list[VendorPatch]: + """Read patch files, in order, and the destination-relative files each one touches.""" + patches = [] + for path in paths: + try: + text = path.read_text() + except FileNotFoundError as exc: + raise VendorError(f"patch {path} does not exist") from exc + files: set[str] = set() + for old, new in _GIT_DIFF_HEADER.findall(text): + files |= {old, new} + if not files: + files = set(_NEW_FILE_HEADER.findall(text)) + if not files: + raise VendorError(f"patch {path} contains no changes") + patches.append(VendorPatch(path=path, text=text, files=tuple(sorted(files)))) + return patches + + +def apply_patches(destination: Path, patches: Collection[VendorPatch]) -> None: + """Apply ``patches`` in order to ``destination``; nothing is applied if any patch fails.""" + git = shutil.which("git") + if git is None: + raise VendorError("applying patches requires git on PATH") + # Feed all patches to git as one input: `git apply` then applies them as a series (later patches see earlier + # changes) and atomically. Given several patch files instead, git writes each file's changes before reading + # the next one, and `--check` checks every file against the unpatched tree. + patches = list(patches) + error = _git_apply(git, destination, patches) + if error is None: + return + # Find the first patch that breaks the series, to name it in the error. + for index, patch in enumerate(patches): + prefix_error = _git_apply(git, destination, patches[: index + 1], "--check") + if prefix_error is not None: + raise VendorError(f"patch {patch.path} does not apply:\n{prefix_error}") + raise VendorError(f"patches do not apply:\n{error}") + + +def _git_apply(git: str, destination: Path, patches: Collection[VendorPatch], *args: str) -> str | None: + """Run ``git apply`` on the concatenated ``patches``; return git's error output on failure.""" + series = "".join(patch.text if patch.text.endswith("\n") else f"{patch.text}\n" for patch in patches) + # Inside a work tree, git reads patch paths relative to the repository root and silently skips files + # outside the current directory. Stop repository discovery at the destination so paths are always + # relative to it. + env = os.environ | {"GIT_CEILING_DIRECTORIES": str(destination.resolve().parent)} + result = subprocess.run( + [git, "apply", *args], + input=series, + cwd=destination, + env=env, + capture_output=True, + text=True, + check=False, + ) + return result.stderr.strip() if result.returncode != 0 else None + + +def patches_by_package( + patches: Collection[VendorPatch], packages: Collection[VendoredPackage] +) -> dict[str, list[VendorPatch]]: + """Map each package name to the patches that touch its files.""" + owners = {top_level: package.name for package in packages for top_level in package.top_level_names} + result: dict[str, list[VendorPatch]] = {} + for patch in patches: + names: set[str] = set() + for file in patch.files: + top = PurePosixPath(file).parts[0].removesuffix(".py") + if top not in owners: + raise VendorError(f"patch {patch.path} touches {file}, which belongs to no vendored package") + names.add(owners[top]) + for name in sorted(names): + result.setdefault(name, []).append(patch) + return result diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py new file mode 100644 index 00000000000..9afccd18c1b --- /dev/null +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py @@ -0,0 +1,210 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Rewrite imports, logger names and module names of vendored packages to point into the vendor namespace.""" + +from __future__ import annotations + +import re +from collections.abc import Collection +from dataclasses import dataclass +from pathlib import Path + +import libcst as cst +from libcst.helpers import get_full_name_for_node +from libcst.metadata import MetadataWrapper, QualifiedNameProvider + +from opentelemetry.vendor.errors import VendorError + +_GET_LOGGER = "logging.getLogger" +BUILD_TOP_DESCRIPTORS = "google.protobuf.internal.builder.BuildTopDescriptorsAndMessages" +"""Called by protoc-generated ``*_pb2`` modules with their module name, which becomes the classes' ``__module__``.""" +# Callee -> (position of the module-name argument, RewriteResult counter). +_MODULE_NAME_ARGUMENTS = {_GET_LOGGER: (0, "loggers"), BUILD_TOP_DESCRIPTORS: (1, "modules")} +_DOTTED_NAME = re.compile(r"[A-Za-z_]\w*(\.[A-Za-z_]\w*)*") + + +@dataclass(frozen=True) +class RewriteResult: + files: int + """Number of files with at least one rewritten import.""" + imports: int + """Number of rewritten imported module names.""" + loggers: int = 0 + """Number of rewritten logger-name string literals.""" + modules: int = 0 + """Number of rewritten module-name string literals (protobuf generated code).""" + + +class _ImportTransformer(cst.CSTTransformer): + """Move absolute imports of vendored ``names`` under ``namespace``. + + ``from X import Y`` becomes ``from namespace.X import Y``. Plain imports keep + binding the same local name: ``import X`` becomes ``from namespace import X``, + ``import X.Y as Z`` becomes ``from namespace.X import Y as Z`` and ``import X.Y`` + becomes ``from namespace import X`` plus ``import namespace.X.Y`` to load the + submodule. A line containing an expanded import is split into one statement per line. + + Logger names are namespaced too, so vendored code doesn't log to (or configure) the + application's loggers: a vendored-name string literal passed to ``logging.getLogger`` + or used as a parameter default (e.g. ``name: str = "X"``) becomes ``"namespace.X"``. + So are the module names protoc-generated code passes to protobuf's builder, which + become the generated classes' ``__module__`` (used by pickle, for example). + """ + + METADATA_DEPENDENCIES = (QualifiedNameProvider,) + + def __init__(self, namespace: str, names: Collection[str]) -> None: + super().__init__() + self.namespace = namespace + self.names = names + self.count = 0 + self.loggers = 0 + self.modules = 0 + self._expanded = False + + def leave_Call(self, original_node: cst.Call, updated_node: cst.Call) -> cst.Call: + qualified_names = {name.name for name in self.get_metadata(QualifiedNameProvider, original_node.func, set())} + for function, (position, counter) in _MODULE_NAME_ARGUMENTS.items(): + if function not in qualified_names or len(updated_node.args) <= position: + continue + arguments = list(updated_node.args) + argument = arguments[position] + if argument.keyword is not None or not isinstance(argument.value, cst.SimpleString): + return updated_node + namespaced = self._namespaced_module_name(argument.value) + if namespaced is None: + return updated_node + setattr(self, counter, getattr(self, counter) + 1) + arguments[position] = argument.with_changes(value=namespaced) + return updated_node.with_changes(args=arguments) + return updated_node + + def leave_Param(self, original_node: cst.Param, updated_node: cst.Param) -> cst.Param: + if not isinstance(updated_node.default, cst.SimpleString): + return updated_node + namespaced = self._namespaced_module_name(updated_node.default) + if namespaced is None: + return updated_node + self.loggers += 1 + return updated_node.with_changes(default=namespaced) + + def _namespaced_module_name(self, node: cst.SimpleString) -> cst.SimpleString | None: + value = node.evaluated_value + if not isinstance(value, str) or not _DOTTED_NAME.fullmatch(value) or not is_vendored(value, self.names): + return None + return node.with_changes(value=f"{node.prefix}{node.quote}{self.namespace}.{value}{node.quote}") + + def leave_ImportFrom(self, original_node: cst.ImportFrom, updated_node: cst.ImportFrom) -> cst.ImportFrom: + if updated_node.relative or updated_node.module is None: + return updated_node + module = get_full_name_for_node(updated_node.module) + if module is None or not is_vendored(module, self.names): + return updated_node + self.count += 1 + return updated_node.with_changes(module=_dotted_name(f"{self.namespace}.{module}")) + + def leave_Import( + self, original_node: cst.Import, updated_node: cst.Import + ) -> cst.BaseSmallStatement | cst.FlattenSentinel[cst.BaseSmallStatement]: + if not any(is_vendored(alias_name(alias), self.names) for alias in updated_node.names): + return updated_node + statements: list[cst.BaseSmallStatement] = [] + for alias in updated_node.names: + name = alias_name(alias) + if is_vendored(name, self.names): + statements.extend(self._rewrite_alias(name, alias.asname)) + self.count += 1 + else: + statements.append(cst.Import(names=[alias.with_changes(comma=cst.MaybeSentinel.DEFAULT)])) + statements[-1] = statements[-1].with_changes(semicolon=updated_node.semicolon) + if len(statements) == 1: + return statements[0] + self._expanded = True + return cst.FlattenSentinel(statements) + + def visit_SimpleStatementLine(self, node: cst.SimpleStatementLine) -> None: + self._expanded = False + + def leave_SimpleStatementLine( + self, original_node: cst.SimpleStatementLine, updated_node: cst.SimpleStatementLine + ) -> cst.SimpleStatementLine | cst.FlattenSentinel[cst.SimpleStatementLine]: + if not self._expanded: + return updated_node + lines = [ + cst.SimpleStatementLine(body=[statement.with_changes(semicolon=cst.MaybeSentinel.DEFAULT)]) + for statement in updated_node.body + ] + lines[0] = lines[0].with_changes(leading_lines=updated_node.leading_lines) + lines[-1] = lines[-1].with_changes(trailing_whitespace=updated_node.trailing_whitespace) + return cst.FlattenSentinel(lines) + + def _rewrite_alias(self, name: str, asname: cst.AsName | None) -> list[cst.BaseSmallStatement]: + package, _, attribute = name.rpartition(".") + if asname is not None: + # import X as Z -> from ns import X as Z; import X.Y as Z -> from ns.X import Y as Z + module = f"{self.namespace}.{package}" if package else self.namespace + return [_import_from(module, attribute, asname)] + top_level = name.split(".", 1)[0] + statements: list[cst.BaseSmallStatement] = [_import_from(self.namespace, top_level, None)] + if package: + # Binding X alone does not load the X.Y submodule. + statements.append(cst.Import(names=[cst.ImportAlias(name=_dotted_name(f"{self.namespace}.{name}"))])) + return statements + + +def rewrite_source(source: str, namespace: str, names: Collection[str]) -> str: + """Return ``source`` with imports and logger names of vendored ``names`` moved under ``namespace``.""" + return MetadataWrapper(cst.parse_module(source)).visit(_ImportTransformer(namespace, names)).code + + +def rewrite_imports(destination: Path, namespace: str, names: Collection[str]) -> RewriteResult: + """Rewrite imports and logger names of vendored ``names`` in every ``.py`` file under ``destination``. + + Raises ``VendorError`` if a file cannot be parsed. Leftover vendored imports are + reported by ``opentelemetry.vendor.checks``, which runs after patches. + """ + files = 0 + imports = 0 + loggers = 0 + modules = 0 + for path in sorted(destination.rglob("*.py")): + transformer = _ImportTransformer(namespace, names) + rewritten = MetadataWrapper(parse_file(path)).visit(transformer) + if transformer.count or transformer.loggers or transformer.modules: + path.write_bytes(rewritten.bytes) + files += 1 + imports += transformer.count + loggers += transformer.loggers + modules += transformer.modules + return RewriteResult(files=files, imports=imports, loggers=loggers, modules=modules) + + +def parse_file(path: Path) -> cst.Module: + try: + return cst.parse_module(path.read_bytes()) + except cst.ParserSyntaxError as exc: + raise VendorError(f"cannot parse {path}: {exc}") from exc + + +def is_vendored(name: str, names: Collection[str]) -> bool: + """Whether dotted module ``name`` belongs to one of the vendored top-level ``names``.""" + return name.split(".", 1)[0] in names + + +def alias_name(alias: cst.ImportAlias) -> str: + """The dotted module name of an ``import`` statement alias.""" + # ImportAlias names in `import` statements are always Name or Attribute nodes. + return get_full_name_for_node(alias.name) or "" + + +def _import_from(module: str, name: str, asname: cst.AsName | None) -> cst.ImportFrom: + return cst.ImportFrom(module=_dotted_name(module), names=[cst.ImportAlias(name=cst.Name(name), asname=asname)]) + + +def _dotted_name(name: str) -> cst.Attribute | cst.Name: + first, *rest = name.split(".") + node: cst.Attribute | cst.Name = cst.Name(first) + for part in rest: + node = cst.Attribute(value=node, attr=cst.Name(part)) + return node diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py index bb13f384ee3..2674773d2e1 100644 --- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py @@ -5,15 +5,16 @@ from __future__ import annotations +import hashlib import json import uuid -from collections.abc import Collection +from collections.abc import Collection, Mapping from pathlib import Path from cyclonedx.contrib.license.factories import LicenseFactory -from cyclonedx.model import HashAlgorithm, HashType +from cyclonedx.model import AttachedText, HashAlgorithm, HashType from cyclonedx.model.bom import Bom -from cyclonedx.model.component import Component, ComponentType +from cyclonedx.model.component import Component, ComponentType, Diff, Patch, PatchClassification, Pedigree from cyclonedx.output.json import JsonV1Dot6 from cyclonedx.schema import SchemaVersion from cyclonedx.validation.json import JsonStrictValidator @@ -21,18 +22,33 @@ from opentelemetry.vendor.errors import VendorError from opentelemetry.vendor.metadata import VendoredPackage +from opentelemetry.vendor.patches import VendorPatch -def write_sbom(packages: Collection[VendoredPackage], path: Path) -> None: +def write_sbom( + packages: Collection[VendoredPackage], + path: Path, + patches: Mapping[str, Collection[VendorPatch]] | None = None, +) -> None: """Write a CycloneDX 1.6 JSON SBOM describing ``packages`` to ``path``. + ``patches`` maps package names to the patches applied to them, recorded as + the component's pedigree. + The output is deterministic: syncing the same requirements twice produces an identical file. """ ordered = sorted(packages, key=lambda package: package.name) license_factory = LicenseFactory() - components = [_component(package, license_factory) for package in ordered] - identity = "\n".join(f"{package.name} {package.version} {package.sha256}" for package in ordered) + patches = patches or {} + components = [_component(package, license_factory, patches.get(package.name, ())) for package in ordered] + identity = "\n".join( + " ".join( + [package.name, package.version, package.sha256] + + [hashlib.sha256(patch.text.encode()).hexdigest() for patch in patches.get(package.name, ())] + ) + for package in ordered + ) bom = Bom( components=components, serial_number=uuid.uuid5(uuid.NAMESPACE_URL, identity), @@ -50,7 +66,9 @@ def write_sbom(packages: Collection[VendoredPackage], path: Path) -> None: path.write_text(output) -def _component(package: VendoredPackage, license_factory: LicenseFactory) -> Component: +def _component( + package: VendoredPackage, license_factory: LicenseFactory, patches: Collection[VendorPatch] +) -> Component: purl = PackageURL(type="pypi", name=package.name, version=package.version) return Component( type=ComponentType.LIBRARY, @@ -60,4 +78,12 @@ def _component(package: VendoredPackage, license_factory: LicenseFactory) -> Com bom_ref=purl.to_string(), hashes=[HashType(alg=HashAlgorithm.SHA_256, content=package.sha256)], licenses=[license_factory.make_from_string(package.license_expression)] if package.license_expression else None, + pedigree=Pedigree( + patches=[ + Patch(type=PatchClassification.UNOFFICIAL, diff=Diff(text=AttachedText(content=patch.text))) + for patch in patches + ] + ) + if patches + else None, ) diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py index 191017bc8cf..2a8fc91706a 100644 --- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py +++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py @@ -5,12 +5,15 @@ from __future__ import annotations +import dataclasses +import re import shutil import tempfile from collections.abc import Collection from pathlib import Path from opentelemetry.vendor import output +from opentelemetry.vendor.checks import check_vendored_tree from opentelemetry.vendor.config import VendorConfig from opentelemetry.vendor.download import download_wheels, unpack_wheels from opentelemetry.vendor.errors import VendorError @@ -20,6 +23,8 @@ read_package, remove_dist_info, ) +from opentelemetry.vendor.patches import apply_patches, patches_by_package, read_patches +from opentelemetry.vendor.rewrite import RewriteResult, rewrite_imports from opentelemetry.vendor.sbom import write_sbom @@ -75,12 +80,21 @@ def clean(config: VendorConfig) -> None: def sync(config: VendorConfig) -> list[VendoredPackage]: """Re-vendor ``config``'s requirements and return the vendored packages.""" - destination = config.destination + # Validate requirements before cleaning, so a bad file leaves the vendored tree intact. + requirements = read_requirements(config.requirements) clean(config) + try: + return _populate(config, requirements) + except BaseException: + # Never leave a half-built tree (unpatched code, *.dist-info, ...) behind: back to the protected files only. + clean_destination(config.destination, config.protected_files) + raise + +def _populate(config: VendorConfig, requirements: Collection[str]) -> list[VendoredPackage]: + destination = config.destination with tempfile.TemporaryDirectory() as tmp: - count = _count_requirements(config.requirements) - with output.status(f"Downloading {output.plural(count, 'requirement')}…"): + with output.status(f"Downloading {output.plural(len(requirements), 'requirement')}…"): wheels = download_wheels(config.requirements, config.python_version, Path(tmp)) output.step(f"Downloaded {output.plural(len(wheels), 'wheel')}") @@ -92,12 +106,25 @@ def sync(config: VendorConfig) -> list[VendoredPackage]: dropped = drop_paths(destination, config.drop) output.step(f"Dropped {output.plural(len(dropped), 'path')}") + names = {name for package in packages for name in package.top_level_names} + rewritten = rewrite_imports(destination, config.namespace, names) + output.step(f"Rewrote {_rewrite_summary(rewritten)} in {output.plural(rewritten.files, 'file')}") + patches = read_patches(config.patches) + if patches: + apply_patches(destination, patches) + for patch in patches: + output.detail(f"applied {_display(patch.path, config)}") + output.step(f"Applied {output.plural(len(patches), 'patch', 'patches')}") + + for finding in check_vendored_tree(destination, names, config.allow): + output.detail(f"allowed {finding.kind} {finding}") + copy_license_files(packages, destination) license_count = sum(len(package.license_files) for package in packages) output.step(f"Copied {output.plural(license_count, 'license file')}") if config.sbom_file is not None: - write_sbom(packages, config.sbom_file) + write_sbom(packages, config.sbom_file, patches_by_package(patches, packages)) output.step(f"Wrote SBOM {_display(config.sbom_file, config)}") remove_dist_info(packages) @@ -105,6 +132,85 @@ def sync(config: VendorConfig) -> list[VendoredPackage]: return packages +_REQUIREMENT_NAME = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]*") + + +def _rewrite_summary(rewritten: RewriteResult) -> str: + parts = [output.plural(rewritten.imports, "import")] + if rewritten.loggers: + parts.append(output.plural(rewritten.loggers, "logger name")) + if rewritten.modules: + parts.append(output.plural(rewritten.modules, "module name")) + return parts[0] if len(parts) == 1 else f"{', '.join(parts[:-1])} and {parts[-1]}" + + +def check(config: VendorConfig) -> None: + """Raise ``VendorError`` if the vendored files differ from what ``sync`` would produce. + + Syncs into a temporary directory and compares it, file by file, with ``config.destination`` + (and ``config.sbom_file`` when it lives outside the destination). Nothing in the project is changed. + """ + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + expected = root / "destination" + expected.mkdir() + for name in config.protected_files: + source = config.destination / name + if source.is_dir(): + shutil.copytree(source, expected / name) + elif source.exists(): + shutil.copy2(source, expected / name) + sbom_file = None + sbom_outside = config.sbom_file is not None and not config.sbom_file.is_relative_to(config.destination) + if config.sbom_file is not None: + sbom_file = ( + root / "sbom" / config.sbom_file.name + if sbom_outside + else expected / config.sbom_file.relative_to(config.destination) + ) + sync(dataclasses.replace(config, destination=expected, sbom_file=sbom_file)) + + differences = _diff_trees(config.destination, expected, config.protected_files) + if sbom_outside and config.sbom_file is not None and sbom_file is not None: + display = _display(config.sbom_file, config) + if not config.sbom_file.exists(): + differences.append(f"+ {display}") + elif config.sbom_file.read_bytes() != sbom_file.read_bytes(): + differences.append(f"~ {display}") + + if differences: + lines = "\n".join(f" {difference}" for difference in differences) + raise VendorError(f"vendored files are out of date (run opentelemetry-vendor sync):\n{lines}") + output.step("Vendored files are up to date") + + +def _diff_trees(actual: Path, expected: Path, protected_files: Collection[str]) -> list[str]: + """Describe how ``actual`` must change to match ``expected``: ``+`` added, ``-`` removed, ``~`` changed.""" + actual_files = _tree_files(actual, protected_files) + expected_files = _tree_files(expected, protected_files) + differences = [] + for path in sorted(actual_files | expected_files): + if path not in actual_files: + differences.append(f"+ {path}") + elif path not in expected_files: + differences.append(f"- {path}") + elif (actual / path).read_bytes() != (expected / path).read_bytes(): + differences.append(f"~ {path}") + return differences + + +def _tree_files(root: Path, protected_files: Collection[str]) -> set[str]: + if not root.is_dir(): + return set() + files = set() + for path in root.rglob("*"): + relative = path.relative_to(root) + if relative.parts[0] in protected_files or "__pycache__" in relative.parts or path.is_dir(): + continue + files.add(relative.as_posix()) + return files + + def _remove(path: Path, destination: Path) -> None: display = path.relative_to(destination).as_posix() if path.is_dir() and not path.is_symlink(): @@ -121,10 +227,32 @@ def _display(path: Path, config: VendorConfig) -> str: return str(path) -def _count_requirements(requirements: Path) -> int: +def read_requirements(requirements: Path) -> list[str]: + """Return the logical requirement lines of ``requirements``, each of which must be pinned by hash. + + Continuation lines (ending in ``\\``) are joined; comments and option lines are skipped. + """ try: text = requirements.read_text() except FileNotFoundError as exc: raise VendorError(f"requirements file {requirements} does not exist") from exc - lines = (line.strip() for line in text.splitlines()) - return sum(1 for line in lines if line and not line.startswith(("#", "-"))) + logical_lines: list[str] = [] + pending = "" + for physical in text.splitlines(): + stripped = physical.split(" #", 1)[0].strip() + # Like pip, a comment line ends a continuation. + if stripped.endswith("\\") and not stripped.startswith("#"): + pending += stripped[:-1] + " " + continue + logical_lines.append(pending + ("" if stripped.startswith("#") else stripped)) + pending = "" + logical_lines.append(pending) + lines = [" ".join(line.split()) for line in logical_lines if line.strip() and not line.strip().startswith("-")] + for line in lines: + if "--hash=" not in line: + name = _REQUIREMENT_NAME.match(line) + label = name.group() if name else line + raise VendorError( + f"requirement {label!r} in {requirements} has no --hash; compile it with --generate-hashes" + ) + return lines diff --git a/agent/opentelemetry-vendor/tests/conftest.py b/agent/opentelemetry-vendor/tests/conftest.py index 6afb104c84a..d5742aef5c1 100644 --- a/agent/opentelemetry-vendor/tests/conftest.py +++ b/agent/opentelemetry-vendor/tests/conftest.py @@ -14,7 +14,6 @@ namespace = "pkg._vendor" python-version = "3.10" protected-files = ["__init__.py", "requirements.txt"] -patches-dir = "patches" sbom-file = "src/pkg/_vendor/bom.cdx.json" """ @@ -24,5 +23,7 @@ def fixture_project_dir(tmp_path: Path) -> Path: (tmp_path / "pyproject.toml").write_text(VALID_CONFIG) destination = tmp_path / "src/pkg/_vendor" destination.mkdir(parents=True) - (destination / "requirements.txt").write_text("# comment\nsix==1.0\n # via -r vendor.in\n") + (destination / "requirements.txt").write_text( + "# comment\nsix==1.0 \\\n --hash=sha256:0123456789abcdef\n # via -r vendor.in\n" + ) return tmp_path diff --git a/agent/opentelemetry-vendor/tests/test_checks.py b/agent/opentelemetry-vendor/tests/test_checks.py new file mode 100644 index 00000000000..a8172aea55c --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_checks.py @@ -0,0 +1,300 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from pathlib import Path + +import pytest + +from opentelemetry.vendor.checks import ( + DYNAMIC_IMPORTS, + IMPORTS, + LOGGER_NAMES, + MODULE_NAMES, + SIDE_EFFECTS, + Finding, + check_vendored_tree, + find_issues, +) +from opentelemetry.vendor.errors import VendorError + +NAMES = frozenset({"idna", "urllib3"}) + +# Imports used by the test sources; names are resolved through them. +HEADER = """\ +import importlib +import logging +import os +import warnings +import warnings as w +from os import environ +import importlib.resources +import sys +import sys as _sys +from importlib import import_module +from importlib import import_module as im +from importlib.resources import as_file, files, read_text +from importlib.resources import path as get_path +""" +SOURCE_LINE = HEADER.count("\n") + 1 + + +@pytest.mark.parametrize( + ("source", "code"), + [ + pytest.param("__import__(package)", "__import__(package)", id="import-variable"), + pytest.param("__import__('urllib3')", "__import__('urllib3')", id="import-vendored-literal"), + pytest.param("__import__(name='os')", "__import__(name='os')", id="import-keyword"), + pytest.param( + "importlib.import_module('idna.core')", + "importlib.import_module('idna.core')", + id="import-module-vendored-literal", + ), + pytest.param( + "import_module(f'encodings.{x}')", + "import_module(f'encodings.{x}')", + id="import-module-f-string", + ), + pytest.param( + "import_module('encod' 'ings')", + "import_module('encod' 'ings')", + id="import-module-concatenated", + ), + pytest.param("sys.modules['x'] = m", "sys.modules['x'] = m", id="sys-modules-assign"), + pytest.param("a = sys.modules['x'] = m", "a = sys.modules['x'] = m", id="sys-modules-chained-assign"), + pytest.param("sys.modules['x'], b = m, n", "sys.modules['x'], b = m, n", id="sys-modules-tuple-assign"), + pytest.param("sys.modules['x']: T = m", "sys.modules['x']: T = m", id="sys-modules-ann-assign"), + pytest.param("sys.modules['x'] |= m", "sys.modules['x'] |= m", id="sys-modules-aug-assign"), + pytest.param("del sys.modules['x']", "del sys.modules['x']", id="sys-modules-del"), + pytest.param("del a, sys.modules['x']", "del a, sys.modules['x']", id="sys-modules-del-tuple"), + pytest.param("sys.modules.update({})", "sys.modules.update({})", id="sys-modules-update"), + pytest.param("sys.modules.setdefault('x', m)", "sys.modules.setdefault('x', m)", id="sys-modules-setdefault"), + pytest.param("sys.modules.pop('x')", "sys.modules.pop('x')", id="sys-modules-pop"), + pytest.param( + "sys.modules[\n 'x'\n] = m", + "sys.modules[ 'x' ] = m", + id="multiline-collapsed", + ), + pytest.param("im(package)", "im(package)", id="import-module-alias"), + pytest.param("_sys.modules['x'] = m", "_sys.modules['x'] = m", id="sys-modules-alias"), + pytest.param("_sys.modules.pop('x')", "_sys.modules.pop('x')", id="sys-modules-alias-pop"), + pytest.param("files('urllib3')", "files('urllib3')", id="files-vendored-literal"), + pytest.param( + "importlib.resources.files('idna.core')", + "importlib.resources.files('idna.core')", + id="files-attribute", + ), + pytest.param( + "as_file(files('urllib3').joinpath('x'))", + "files('urllib3')", + id="as-file-wrapping-files", + ), + pytest.param("files(package)", "files(package)", id="files-variable"), + pytest.param("get_path('urllib3', 'x')", "get_path('urllib3', 'x')", id="legacy-path-alias"), + pytest.param("read_text(name, 'x')", "read_text(name, 'x')", id="legacy-read-text-variable"), + pytest.param( + "importlib.resources.is_resource(anchor='idna', name='x')", + "importlib.resources.is_resource(anchor='idna', name='x')", + id="legacy-keyword-anchor", + ), + pytest.param( + "def f():\n from importlib.resources import read_binary\n return read_binary('idna', 'x')", + "read_binary('idna', 'x')", + id="legacy-local-import", + ), + ], +) +def test_find_issues_dynamic_imports(tmp_path: Path, source: str, code: str) -> None: + (tmp_path / "pkg").mkdir() + (tmp_path / "pkg" / "mod.py").write_text(f"{HEADER}{source}\n") + + [finding] = find_issues(tmp_path, NAMES) + + assert finding.kind == DYNAMIC_IMPORTS + assert finding.path == "pkg/mod.py" + assert finding.line >= SOURCE_LINE + assert finding.code == code + + +@pytest.mark.parametrize( + "source", + [ + pytest.param("__import__('os')", id="import-stdlib-literal"), + pytest.param("__import__('urllib3x')", id="import-prefix-collision"), + pytest.param("importlib.import_module('.sub', __package__)", id="import-module-relative"), + pytest.param("import_module('encodings.utf_8')", id="import-module-stdlib-literal"), + pytest.param("m = sys.modules[name]", id="sys-modules-read"), + pytest.param("for m in list(sys.modules): pass", id="sys-modules-iterate"), + pytest.param("sys.modules.get('x')", id="sys-modules-get"), + pytest.param("cache['x'] = m", id="other-subscript"), + pytest.param('"""__import__(package)"""\n# sys.modules["x"] = m', id="docstring-and-comment"), + pytest.param("files(__package__)", id="files-package"), + pytest.param("files(__name__)", id="files-name"), + pytest.param("files()", id="files-calling-module"), + pytest.param("files('os')", id="files-stdlib-literal"), + pytest.param("as_file(files(__package__).joinpath('x'))", id="as-file-package"), + pytest.param("get_path(__package__, 'cacert.pem')", id="legacy-path-package"), + pytest.param("self.read_text('urllib3')", id="method-named-like-resource-function"), + pytest.param("import_module_x('urllib3')", id="other-function"), + pytest.param("warnings.warn('x')", id="warnings-warn"), + pytest.param("with warnings.catch_warnings(): pass", id="warnings-catch"), + pytest.param("value = os.environ['x']", id="environ-read"), + pytest.param("os.environ.get('x')", id="environ-get"), + pytest.param("env = dict(os.environ)\nenv['x'] = '1'", id="environ-copy"), + pytest.param("import urllib3x\nfrom . import urllib3\nfrom .urllib3 import a", id="non-vendored-imports"), + pytest.param("from opentelemetry.agent._vendor import urllib3", id="namespaced-import"), + pytest.param("logging.getLogger(__name__)", id="logger-dunder-name"), + pytest.param("logging.getLogger(name)", id="logger-variable"), + pytest.param("logging.getLogger('opentelemetry.agent._vendor.urllib3')", id="logger-namespaced"), + ], +) +def test_find_issues_ignores(tmp_path: Path, source: str) -> None: + (tmp_path / "mod.py").write_text(f"{HEADER}{source}\n") + + assert find_issues(tmp_path, NAMES) == [] + + +@pytest.mark.parametrize( + "source", + [ + pytest.param("def files(name): pass\nfiles('urllib3')", id="local-function-named-files"), + pytest.param("import_module('urllib3')\nsys.modules['x'] = m", id="names-not-imported"), + pytest.param("simplefilter('ignore')\nenviron['x'] = '1'", id="side-effect-names-not-imported"), + ], +) +def test_find_issues_ignores_unresolved_names(tmp_path: Path, source: str) -> None: + (tmp_path / "mod.py").write_text(f"{source}\n") + + assert find_issues(tmp_path, NAMES) == [] + + +@pytest.mark.parametrize( + ("source", "kind", "code"), + [ + pytest.param("import urllib3", IMPORTS, "import urllib3", id="import"), + pytest.param("import os, urllib3.util as u", IMPORTS, "import os, urllib3.util as u", id="import-multiple"), + pytest.param("from idna import core", IMPORTS, "from idna import core", id="from-import"), + pytest.param( + "warnings.simplefilter('ignore', Warning)", + SIDE_EFFECTS, + "warnings.simplefilter('ignore', Warning)", + id="simplefilter", + ), + pytest.param( + "w.filterwarnings('ignore')", SIDE_EFFECTS, "w.filterwarnings('ignore')", id="filterwarnings-alias" + ), + pytest.param("warnings.resetwarnings()", SIDE_EFFECTS, "warnings.resetwarnings()", id="resetwarnings"), + pytest.param("os.environ['x'] = '1'", SIDE_EFFECTS, "os.environ['x'] = '1'", id="environ-assign"), + pytest.param("environ['x'] = '1'", SIDE_EFFECTS, "environ['x'] = '1'", id="environ-from-import"), + pytest.param("del os.environ['x']", SIDE_EFFECTS, "del os.environ['x']", id="environ-del"), + pytest.param("os.environ['x'] += '1'", SIDE_EFFECTS, "os.environ['x'] += '1'", id="environ-aug-assign"), + pytest.param("os.environ.update(x='1')", SIDE_EFFECTS, "os.environ.update(x='1')", id="environ-update"), + pytest.param("environ.pop('x')", SIDE_EFFECTS, "environ.pop('x')", id="environ-pop"), + pytest.param("os.putenv('x', '1')", SIDE_EFFECTS, "os.putenv('x', '1')", id="putenv"), + pytest.param("os.unsetenv('x')", SIDE_EFFECTS, "os.unsetenv('x')", id="unsetenv"), + pytest.param( + "logging.getLogger('urllib3.pool')", + LOGGER_NAMES, + "logging.getLogger('urllib3.pool')", + id="vendored-logger-name", + ), + ], +) +def test_find_issues(tmp_path: Path, source: str, kind: str, code: str) -> None: + (tmp_path / "mod.py").write_text(f"{HEADER}{source}\n") + + assert find_issues(tmp_path, NAMES) == [Finding(kind=kind, path="mod.py", line=SOURCE_LINE, code=code)] + + +def test_check_vendored_tree_allowed(tmp_path: Path) -> None: + (tmp_path / "pkg").mkdir() + (tmp_path / "pkg" / "packages.py").write_text( + "import sys, warnings\n__import__(package)\nsys.modules[k] = m\nwarnings.simplefilter('ignore')\n" + ) + (tmp_path / "clean.py").write_text("import os\n") + + allowed = check_vendored_tree( + tmp_path, NAMES, {DYNAMIC_IMPORTS: ["pkg/packages.py"], SIDE_EFFECTS: ["pkg/packages.py"]} + ) + + assert [(finding.kind, str(finding)) for finding in allowed] == [ + (DYNAMIC_IMPORTS, "pkg/packages.py:2: __import__(package)"), + (DYNAMIC_IMPORTS, "pkg/packages.py:3: sys.modules[k] = m"), + (SIDE_EFFECTS, "pkg/packages.py:4: warnings.simplefilter('ignore')"), + ] + + +def test_check_vendored_tree_allow_is_per_kind(tmp_path: Path) -> None: + (tmp_path / "a.py").write_text("import os, sys\nsys.modules['x'] = m\nos.environ['x'] = '1'\n") + + with pytest.raises(VendorError) as exc_info: + check_vendored_tree(tmp_path, NAMES, {DYNAMIC_IMPORTS: ["a.py"]}) + + assert str(exc_info.value) == ( + "vendored code escapes the vendor namespace:\n" + " side-effects (patch them or add the file to [tool.opentelemetry-vendor.allow] side-effects):\n" + " a.py:3: os.environ['x'] = '1'" + ) + + +def test_check_vendored_tree_unallowed(tmp_path: Path) -> None: + (tmp_path / "a.py").write_text("__import__(package)\nimport urllib3\n") + (tmp_path / "b.py").write_text("import importlib\nimportlib.import_module(name)\n") + + with pytest.raises(VendorError) as exc_info: + check_vendored_tree(tmp_path, NAMES, {IMPORTS: ["a.py"]}) + + assert str(exc_info.value) == ( + "vendored code escapes the vendor namespace:\n" + " imports (imports of vendored packages must be rewritten; check the patches):\n" + " a.py:2: import urllib3\n" + " dynamic-imports (patch them or add the file to [tool.opentelemetry-vendor.allow] dynamic-imports):\n" + " a.py:1: __import__(package)\n" + " b.py:2: importlib.import_module(name)" + ) + + +def test_check_vendored_tree_unused_entry(tmp_path: Path) -> None: + (tmp_path / "a.py").write_text("import sys\nsys.modules['x'] = m\n") + + with pytest.raises( + VendorError, match=r"\[tool.opentelemetry-vendor.allow\] side-effects entry 'a.py' matched nothing" + ): + check_vendored_tree(tmp_path, NAMES, {DYNAMIC_IMPORTS: ["a.py"], SIDE_EFFECTS: ["a.py"]}) + + +def test_check_vendored_tree_unparsable_file(tmp_path: Path) -> None: + (tmp_path / "broken.py").write_text("__import__(\n") + + with pytest.raises(VendorError, match=r"cannot parse .*broken\.py"): + check_vendored_tree(tmp_path, NAMES, {}) + + +@pytest.mark.parametrize( + ("builder_import", "module_name", "flagged"), + [ + pytest.param("from google.protobuf.internal import builder", "google.protobuf.any_pb2", True, id="leftover"), + pytest.param( + "from opentelemetry.agent._vendor.google.protobuf.internal import builder", + "google.protobuf.any_pb2", + True, + id="leftover-after-import-rewrite", + ), + pytest.param( + "from opentelemetry.agent._vendor.google.protobuf.internal import builder", + "opentelemetry.agent._vendor.google.protobuf.any_pb2", + False, + id="namespaced", + ), + ], +) +def test_find_issues_protobuf_module_names( + tmp_path: Path, builder_import: str, module_name: str, flagged: bool +) -> None: + call = f"builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, {module_name!r}, _globals)" + (tmp_path / "x_pb2.py").write_text(f"{builder_import}\n{call}\n") + + findings = [finding for finding in find_issues(tmp_path, NAMES | {"google"}) if finding.kind != IMPORTS] + + assert findings == ([Finding(kind=MODULE_NAMES, path="x_pb2.py", line=2, code=call)] if flagged else []) diff --git a/agent/opentelemetry-vendor/tests/test_cli.py b/agent/opentelemetry-vendor/tests/test_cli.py index f3435168ee7..b72c86fd616 100644 --- a/agent/opentelemetry-vendor/tests/test_cli.py +++ b/agent/opentelemetry-vendor/tests/test_cli.py @@ -4,6 +4,7 @@ from __future__ import annotations import json +import shutil from pathlib import Path import pytest @@ -53,10 +54,11 @@ def test_sync(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: bom = json.loads((destination / "bom.cdx.json").read_text()) assert [c["purl"] for c in bom["components"]] == ["pkg:pypi/six@1.0"] lines = result.output.splitlines() - assert lines[:5] == [ + assert lines[:6] == [ "✔ Cleaned src/pkg/_vendor (1 entry removed)", "✔ Downloaded 1 wheel", "✔ Unpacked 1 wheel", + "✔ Rewrote 0 imports in 0 files", "✔ Copied 1 license file", "✔ Wrote SBOM src/pkg/_vendor/bom.cdx.json", ] @@ -169,3 +171,155 @@ def test_clean_invalid_config(tmp_path: Path) -> None: assert result.exit_code == 1 assert "error: " in result.output assert "no [tool.opentelemetry-vendor] table" in result.output + + +def test_sync_patches(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + (project_dir / "patches").mkdir() + (project_dir / "patches/six.patch").write_text( + "diff --git a/six/__init__.py b/six/__init__.py\n" + "--- a/six/__init__.py\n" + "+++ b/six/__init__.py\n" + "@@ -0,0 +1 @@\n" + "+patched = True\n" + ) + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + 'patches = ["patches/six.patch"]\n') + _fake_download(monkeypatch, ["six/__init__.py"]) + + result = runner.invoke(app, ["sync", str(project_dir), "--verbose"]) + + assert result.exit_code == 0, result.output + destination = project_dir / "src/pkg/_vendor" + assert (destination / "six/__init__.py").read_text() == "patched = True\n" + assert "applied patches/six.patch" in result.output + assert "✔ Applied 1 patch" in result.output + bom = json.loads((destination / "bom.cdx.json").read_text()) + assert bom["components"][0]["pedigree"]["patches"][0]["type"] == "unofficial" + + +def test_sync_patch_does_not_apply(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + (project_dir / "patches").mkdir() + (project_dir / "patches/six.patch").write_text( + "diff --git a/six.py b/six.py\n--- a/six.py\n+++ b/six.py\n@@ -1 +1 @@\n-old\n+new\n" + ) + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + 'patches = ["patches/six.patch"]\n') + _fake_download(monkeypatch) + + result = runner.invoke(app, ["sync", str(project_dir)]) + + assert result.exit_code == 1 + assert "six.patch does not apply:" in result.output + + +def test_sync_patch_adding_vendored_import(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + (project_dir / "patches").mkdir() + (project_dir / "patches/six.patch").write_text( + "diff --git a/six/__init__.py b/six/__init__.py\n" + "--- a/six/__init__.py\n" + "+++ b/six/__init__.py\n" + "@@ -0,0 +1 @@\n" + "+import six.moves\n" + ) + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + 'patches = ["patches/six.patch"]\n') + _fake_download(monkeypatch, ["six/__init__.py"]) + + result = runner.invoke(app, ["sync", str(project_dir)]) + + assert result.exit_code == 1 + assert "imports of vendored packages must be rewritten" in result.output + assert "six/__init__.py:1: import six.moves" in result.output + + +def test_sync_requirement_without_hash_keeps_tree(project_dir: Path) -> None: + destination = project_dir / "src/pkg/_vendor" + (destination / "requirements.txt").write_text("six==1.0\n") + (destination / "six.py").write_text("vendored = True\n") + + result = runner.invoke(app, ["sync", str(project_dir)]) + + assert result.exit_code == 1 + assert "requirement 'six'" in result.output + assert "has no --hash" in result.output + assert (destination / "six.py").read_text() == "vendored = True\n" + + +def _fake_stable_download(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None: + # Build the wheel once: like a real index, every download returns identical bytes. + cache = tmp_path / "wheel-cache" + cache.mkdir() + wheel = make_wheel(cache, "six", "1.0", ["six/__init__.py"], metadata="License-Expression: MIT\n") + + def fake_download_wheels(requirements: Path, python_version: str, dest: Path) -> list[Path]: + return [Path(shutil.copy(wheel, dest))] + + monkeypatch.setattr(sync_module, "download_wheels", fake_download_wheels) + + +def test_sync_check_up_to_date(project_dir: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None: + _fake_stable_download(monkeypatch, tmp_path) + assert runner.invoke(app, ["sync", str(project_dir)]).exit_code == 0 + + result = runner.invoke(app, ["sync", "--check", str(project_dir)]) + + assert result.exit_code == 0, result.output + assert result.output.splitlines()[-1] == "✔ Vendored files are up to date" + + +def test_sync_check_out_of_date(project_dir: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None: + _fake_stable_download(monkeypatch, tmp_path) + assert runner.invoke(app, ["sync", str(project_dir)]).exit_code == 0 + destination = project_dir / "src/pkg/_vendor" + (destination / "six/__init__.py").write_text("edited = True\n") + (destination / "six.LICENSE").unlink() + (destination / "extra.py").write_text("") + (destination / "six/__pycache__").mkdir() + (destination / "six/__pycache__/x.pyc").write_text("") + + result = runner.invoke(app, ["sync", "--check", str(project_dir)]) + + assert result.exit_code == 1 + assert result.output.endswith( + "error: vendored files are out of date (run opentelemetry-vendor sync):\n" + " - extra.py\n" + " + six.LICENSE\n" + " ~ six/__init__.py\n" + ) + # --check never changes the project. + assert (destination / "six/__init__.py").read_text() == "edited = True\n" + assert (destination / "extra.py").exists() + assert not (destination / "six.LICENSE").exists() + + +def test_sync_check_sbom_outside_destination( + project_dir: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path +) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text().replace("src/pkg/_vendor/bom.cdx.json", "bom.cdx.json")) + _fake_stable_download(monkeypatch, tmp_path) + assert runner.invoke(app, ["sync", str(project_dir)]).exit_code == 0 + assert runner.invoke(app, ["sync", "--check", str(project_dir)]).exit_code == 0 + (project_dir / "bom.cdx.json").write_text("{}") + + result = runner.invoke(app, ["sync", "--check", str(project_dir)]) + + assert result.exit_code == 1 + assert " ~ bom.cdx.json\n" in result.output + + +def test_sync_failure_cleans_destination(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None: + (project_dir / "patches").mkdir() + (project_dir / "patches/six.patch").write_text( + "diff --git a/six.py b/six.py\n--- a/six.py\n+++ b/six.py\n@@ -1 +1 @@\n-old\n+new\n" + ) + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + 'patches = ["patches/six.patch"]\n') + _fake_download(monkeypatch) + + result = runner.invoke(app, ["sync", str(project_dir)]) + + assert result.exit_code == 1 + assert "does not apply" in result.output + # Neither the unpacked package nor its *.dist-info is left behind. + assert sorted(p.name for p in (project_dir / "src/pkg/_vendor").iterdir()) == ["requirements.txt"] diff --git a/agent/opentelemetry-vendor/tests/test_config.py b/agent/opentelemetry-vendor/tests/test_config.py index c6d015a1bcd..5e80e86d1c1 100644 --- a/agent/opentelemetry-vendor/tests/test_config.py +++ b/agent/opentelemetry-vendor/tests/test_config.py @@ -21,7 +21,6 @@ def test_load_config(project_dir: Path) -> None: assert config.namespace == "pkg._vendor" assert config.python_version == "3.10" assert tuple(config.protected_files) == ("__init__.py", "requirements.txt") - assert config.patches_dir == root / "patches" assert config.sbom_file == root / "src/pkg/_vendor/bom.cdx.json" @@ -37,8 +36,9 @@ def test_load_config_optional_keys(tmp_path: Path) -> None: assert tuple(config.protected_files) == () assert tuple(config.drop) == () + assert config.allow == {} assert config.python_version == (f"{sys.version_info.major}.{sys.version_info.minor}") - assert config.patches_dir is None + assert tuple(config.patches) == () assert config.sbom_file is None @@ -59,6 +59,11 @@ def test_load_config_optional_keys(tmp_path: Path) -> None: 'requirements = "r.txt"\nnamespace = "v"\nprotected-files = "x"\n', "'protected-files' must be a list of strings", ), + ( + '[tool.opentelemetry-vendor]\ndestination = "v"\n' + 'requirements = "r.txt"\nnamespace = "v"\npatches = "a.patch"\n', + "'patches' must be a list of strings", + ), ( '[tool.opentelemetry-vendor]\ndestination = "../v"\nrequirements = "r.txt"\nnamespace = "v"\n', "'destination' must be a directory inside", @@ -77,6 +82,14 @@ def test_load_config_invalid(tmp_path: Path, content: str, message: str) -> None load_config(tmp_path) +def test_load_config_patches(project_dir: Path) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + 'patches = ["patches/b.patch", "patches/a.patch"]\n') + + root = project_dir.resolve() + assert tuple(load_config(project_dir).patches) == (root / "patches/b.patch", root / "patches/a.patch") + + def test_load_config_missing_pyproject(tmp_path: Path) -> None: with pytest.raises(ConfigError, match="does not exist"): load_config(tmp_path) @@ -89,10 +102,58 @@ def test_load_config_drop(project_dir: Path) -> None: assert tuple(load_config(project_dir).drop) == ("wrapt-stubs", "**/py.typed") -@pytest.mark.parametrize("pattern", ["", "/abs", "../outside", "a/../../b"]) -def test_load_config_invalid_drop(project_dir: Path, pattern: str) -> None: +@pytest.mark.parametrize("entry", ["", "/abs", "../outside", "a/../../b"]) +def test_load_config_invalid_drop(project_dir: Path, entry: str) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + f"drop = [{entry!r}]\n") + + with pytest.raises(ConfigError, match="'drop' entry .* must be relative to destination"): + load_config(project_dir) + + +def test_load_config_allow(project_dir: Path) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text( + pyproject.read_text() + + '[tool.opentelemetry-vendor.allow]\ndynamic-imports = ["a.py"]\nside-effects = ["b/c.py", "d.py"]\n' + + 'module-names = ["e_pb2.py"]\n' + ) + + assert load_config(project_dir).allow == { + "dynamic-imports": ("a.py",), + "side-effects": ("b/c.py", "d.py"), + "module-names": ("e_pb2.py",), + } + + +@pytest.mark.parametrize( + ("content", "message"), + [ + ( + '[tool.opentelemetry-vendor.allow]\ndynamic-imports = ["../a.py"]\n', + "'dynamic-imports' entry '../a.py' must be relative", + ), + ('[tool.opentelemetry-vendor.allow]\nside-effects = "a.py"\n', "'side-effects' must be a list of strings"), + ( + '[tool.opentelemetry-vendor.allow]\nimports = ["a.py"]\n', + r"unknown \[tool.opentelemetry-vendor.allow\] keys \['imports'\]", + ), + ('allow = ["a.py"]\n', r"'allow' must be a table"), + ], +) +def test_load_config_invalid_allow(project_dir: Path, content: str, message: str) -> None: + pyproject = project_dir / "pyproject.toml" + pyproject.write_text(pyproject.read_text() + content) + + with pytest.raises(ConfigError, match=message): + load_config(project_dir) + + +def test_load_config_moved_allow_dynamic_imports(project_dir: Path) -> None: pyproject = project_dir / "pyproject.toml" - pyproject.write_text(pyproject.read_text() + f"drop = [{pattern!r}]\n") + pyproject.write_text(pyproject.read_text() + 'allow-dynamic-imports = ["a.py"]\n') - with pytest.raises(ConfigError, match="must be relative to destination"): + with pytest.raises( + ConfigError, match=r"'allow-dynamic-imports' moved to \[tool.opentelemetry-vendor.allow\] dynamic-imports" + ): load_config(project_dir) diff --git a/agent/opentelemetry-vendor/tests/test_patches.py b/agent/opentelemetry-vendor/tests/test_patches.py new file mode 100644 index 00000000000..99d6c2aed2a --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_patches.py @@ -0,0 +1,169 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import hashlib +import subprocess +from pathlib import Path + +import pytest + +from opentelemetry.vendor import patches as patches_module +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.metadata import VendoredPackage +from opentelemetry.vendor.patches import VendorPatch, apply_patches, patches_by_package, read_patches + +FIRST = """\ +Use the vendored module. + +diff --git a/pkg/mod.py b/pkg/mod.py +--- a/pkg/mod.py ++++ b/pkg/mod.py +@@ -1,2 +1,2 @@ +-a = 1 ++a = 2 + b = 1 +""" + +SECOND = """\ +diff --git a/pkg/mod.py b/pkg/mod.py +--- a/pkg/mod.py ++++ b/pkg/mod.py +@@ -1,2 +1,2 @@ + a = 2 +-b = 1 ++b = 2 +""" + +NEW_FILE = """\ +diff --git a/six.py b/six.py +new file mode 100644 +--- /dev/null ++++ b/six.py +@@ -0,0 +1 @@ ++x = 1 +""" + +NOT_APPLICABLE = """\ +diff --git a/pkg/mod.py b/pkg/mod.py +--- a/pkg/mod.py ++++ b/pkg/mod.py +@@ -1,2 +1,2 @@ +-a = 3 ++a = 4 + b = 1 +""" + + +def _write_patches(directory: Path, *texts: str) -> list[Path]: + paths = [] + for index, text in enumerate(texts): + path = directory / f"{index}.patch" + path.write_text(text) + paths.append(path) + return paths + + +@pytest.fixture(name="destination") +def fixture_destination(tmp_path: Path) -> Path: + destination = tmp_path / "_vendor" + (destination / "pkg").mkdir(parents=True) + (destination / "pkg/mod.py").write_text("a = 1\nb = 1\n") + return destination + + +def test_read_patches(tmp_path: Path) -> None: + paths = _write_patches(tmp_path, FIRST, NEW_FILE) + + patches = read_patches(paths) + + assert patches == [ + VendorPatch(path=paths[0], text=FIRST, files=("pkg/mod.py",)), + VendorPatch(path=paths[1], text=NEW_FILE, files=("six.py",)), + ] + + +def test_read_patches_plain_unified_diff(tmp_path: Path) -> None: + paths = _write_patches(tmp_path, FIRST.split("diff --git a/pkg/mod.py b/pkg/mod.py\n", 1)[1]) + + assert read_patches(paths)[0].files == ("pkg/mod.py",) + + +def test_read_patches_missing(tmp_path: Path) -> None: + with pytest.raises(VendorError, match=r"patch .*missing\.patch does not exist"): + read_patches([tmp_path / "missing.patch"]) + + +@pytest.mark.parametrize("text", ["", "Only a description.\n"]) +def test_read_patches_without_changes(tmp_path: Path, text: str) -> None: + with pytest.raises(VendorError, match=r"patch .*0\.patch contains no changes"): + read_patches(_write_patches(tmp_path, text)) + + +def test_apply_patches_in_order(tmp_path: Path, destination: Path) -> None: + patches = read_patches(_write_patches(tmp_path, FIRST, SECOND, NEW_FILE)) + + apply_patches(destination, patches) + + assert (destination / "pkg/mod.py").read_text() == "a = 2\nb = 2\n" + assert (destination / "six.py").read_text() == "x = 1\n" + + +def test_apply_patches_is_atomic(tmp_path: Path, destination: Path) -> None: + patches = read_patches(_write_patches(tmp_path, NEW_FILE, NOT_APPLICABLE)) + + with pytest.raises(VendorError, match=r"patch .*1\.patch does not apply:\n.*pkg/mod\.py"): + apply_patches(destination, patches) + + assert (destination / "pkg/mod.py").read_text() == "a = 1\nb = 1\n" + assert not (destination / "six.py").exists() + + +def test_apply_patches_requires_git(tmp_path: Path, destination: Path, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setattr(patches_module.shutil, "which", lambda name: None) + + with pytest.raises(VendorError, match="applying patches requires git on PATH"): + apply_patches(destination, read_patches(_write_patches(tmp_path, FIRST))) + + +def _package(name: str, *top_level_names: str) -> VendoredPackage: + return VendoredPackage( + name=name, + version="1.0", + sha256=hashlib.sha256(name.encode()).hexdigest(), + license_expression=None, + top_level_names=top_level_names, + license_files={}, + dist_info=Path(f"{name}-1.0.dist-info"), + ) + + +def test_patches_by_package() -> None: + package_patch = VendorPatch(path=Path("a.patch"), text="", files=("pkg/mod.py",)) + module_patch = VendorPatch(path=Path("b.patch"), text="", files=("six.py",)) + spanning_patch = VendorPatch(path=Path("c.patch"), text="", files=("pkg/other.py", "six.py")) + packages = [_package("my-pkg", "pkg"), _package("six", "six"), _package("unpatched", "unpatched")] + + result = patches_by_package([package_patch, module_patch, spanning_patch], packages) + + assert result == {"my-pkg": [package_patch, spanning_patch], "six": [module_patch, spanning_patch]} + + +def test_patches_by_package_unknown_file() -> None: + patch = VendorPatch(path=Path("a.patch"), text="", files=("other/mod.py",)) + + with pytest.raises( + VendorError, match=r"patch a\.patch touches other/mod\.py, which belongs to no vendored package" + ): + patches_by_package([patch], [_package("six", "six")]) + + +def test_apply_patches_inside_git_work_tree(tmp_path: Path, destination: Path) -> None: + # git would otherwise read patch paths relative to the repository root and silently skip them. + subprocess.run(["git", "init", "-q", str(tmp_path)], check=True) + patches = read_patches(_write_patches(tmp_path, FIRST)) + + apply_patches(destination, patches) + + assert (destination / "pkg/mod.py").read_text() == "a = 2\nb = 1\n" diff --git a/agent/opentelemetry-vendor/tests/test_rewrite.py b/agent/opentelemetry-vendor/tests/test_rewrite.py new file mode 100644 index 00000000000..79842d7657a --- /dev/null +++ b/agent/opentelemetry-vendor/tests/test_rewrite.py @@ -0,0 +1,313 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from pathlib import Path + +import pytest + +from opentelemetry.vendor.errors import VendorError +from opentelemetry.vendor.rewrite import RewriteResult, rewrite_imports, rewrite_source + +NAMESPACE = "opentelemetry.agent._vendor" +NAMES = frozenset({"idna", "requests", "urllib3"}) + + +@pytest.mark.parametrize( + ("source", "expected"), + [ + pytest.param( + "from urllib3 import PoolManager\n", + "from opentelemetry.agent._vendor.urllib3 import PoolManager\n", + id="package", + ), + pytest.param( + "from urllib3.util.retry import Retry\n", + "from opentelemetry.agent._vendor.urllib3.util.retry import Retry\n", + id="submodule", + ), + pytest.param( + "from requests import Session as S, get\n", + "from opentelemetry.agent._vendor.requests import Session as S, get\n", + id="aliases", + ), + pytest.param( + "from urllib3.exceptions import *\n", + "from opentelemetry.agent._vendor.urllib3.exceptions import *\n", + id="star", + ), + pytest.param( + "from urllib3 import ( # comment\n PoolManager, # pool\n Timeout,\n)\n", + "from opentelemetry.agent._vendor.urllib3 import ( # comment\n PoolManager, # pool\n Timeout,\n)\n", + id="parenthesized-multiline", + ), + pytest.param( + "def f():\n from urllib3 import Timeout\n", + "def f():\n from opentelemetry.agent._vendor.urllib3 import Timeout\n", + id="function", + ), + pytest.param( + "try:\n from urllib3 import a\nexcept ImportError:\n pass\n", + "try:\n from opentelemetry.agent._vendor.urllib3 import a\nexcept ImportError:\n pass\n", + id="try", + ), + pytest.param( + "if TYPE_CHECKING:\n from requests import Session\n", + "if TYPE_CHECKING:\n from opentelemetry.agent._vendor.requests import Session\n", + id="type-checking", + ), + pytest.param( + "from os import path\nfrom urllib3 import a\n", + "from os import path\nfrom opentelemetry.agent._vendor.urllib3 import a\n", + id="mixed", + ), + pytest.param( + "import urllib3\n", + "from opentelemetry.agent._vendor import urllib3\n", + id="import", + ), + pytest.param( + "import urllib3 as u3\n", + "from opentelemetry.agent._vendor import urllib3 as u3\n", + id="import-as", + ), + pytest.param( + "import urllib3.contrib.socks\n", + "from opentelemetry.agent._vendor import urllib3\nimport opentelemetry.agent._vendor.urllib3.contrib.socks\n", + id="import-submodule", + ), + pytest.param( + "import urllib3.contrib.socks as socks\n", + "from opentelemetry.agent._vendor.urllib3.contrib import socks as socks\n", + id="import-submodule-as", + ), + pytest.param( + "import urllib3, os\n", + "from opentelemetry.agent._vendor import urllib3\nimport os\n", + id="import-multiple", + ), + pytest.param( + "import urllib3.util\nimport urllib3.exceptions\n", + "from opentelemetry.agent._vendor import urllib3\n" + "import opentelemetry.agent._vendor.urllib3.util\n" + "from opentelemetry.agent._vendor import urllib3\n" + "import opentelemetry.agent._vendor.urllib3.exceptions\n", + id="import-submodules-repeat-binding", + ), + pytest.param( + "def f():\n import idna\n return idna\n", + "def f():\n from opentelemetry.agent._vendor import idna\n return idna\n", + id="import-function", + ), + pytest.param( + "def f():\n try:\n import idna\n except ImportError:\n pass\n", + "def f():\n try:\n from opentelemetry.agent._vendor import idna\n except ImportError:\n pass\n", + id="import-try", + ), + pytest.param( + "try: import idna, urllib3.util\nexcept ImportError: pass\n", + "try: from opentelemetry.agent._vendor import idna; from opentelemetry.agent._vendor import urllib3; " + "import opentelemetry.agent._vendor.urllib3.util\nexcept ImportError: pass\n", + id="import-one-line-suite", + ), + pytest.param( + "import urllib3.util; x = 1\n", + "from opentelemetry.agent._vendor import urllib3\nimport opentelemetry.agent._vendor.urllib3.util\nx = 1\n", + id="import-semicolon-line-split", + ), + pytest.param( + "x = 1\n\n# leading\nimport os, idna # trailing\n", + "x = 1\n\n# leading\nimport os\nfrom opentelemetry.agent._vendor import idna # trailing\n", + id="import-comments", + ), + pytest.param( + "if True:\n import urllib3.util # trailing\n y = 2\n", + "if True:\n from opentelemetry.agent._vendor import urllib3\n" + " import opentelemetry.agent._vendor.urllib3.util # trailing\n y = 2\n", + id="import-indented-split", + ), + ], +) +def test_rewrite_source(source: str, expected: str) -> None: + assert rewrite_source(source, NAMESPACE, NAMES) == expected + + +@pytest.mark.parametrize( + "source", + [ + pytest.param("from . import util\n", id="relative-package"), + pytest.param("from .urllib3 import a\n", id="relative-vendored-name"), + pytest.param("from ..requests import a\n", id="relative-parent"), + pytest.param("from os import path\n", id="unrelated"), + pytest.param("from requestsx import a\n", id="prefix-collision"), + pytest.param("from __future__ import annotations\n", id="future"), + pytest.param("import os, sys\n", id="import-unrelated"), + pytest.param("import requestsx\nimport requestsx.a\n", id="import-prefix-collision"), + pytest.param("import opentelemetry.agent._vendor.urllib3.util\n", id="import-already-vendored"), + pytest.param('"""\nimport urllib3\n"""\n# import urllib3\n', id="docstring-and-comment"), + pytest.param("from opentelemetry.agent._vendor.urllib3 import a\n", id="already-vendored"), + ], +) +def test_rewrite_source_unchanged(source: str) -> None: + assert rewrite_source(source, NAMESPACE, NAMES) == source + + +def test_rewrite_imports(tmp_path: Path) -> None: + (tmp_path / "urllib3" / "util").mkdir(parents=True) + (tmp_path / "__init__.py").write_text("") + (tmp_path / "urllib3" / "__init__.py").write_text("from .util import a\n") + (tmp_path / "urllib3" / "util" / "retry.py").write_bytes( + b"# -*- coding: latin-1 -*-\r\nfrom urllib3 import a\r\nfrom urllib3.exceptions import b\r\ns = '\xe9'\r\n" + ) + (tmp_path / "requests.py").write_text("from urllib3 import c\n") + (tmp_path / "notes.txt").write_text("from urllib3 import d\n") + + result = rewrite_imports(tmp_path, NAMESPACE, NAMES) + + assert result == RewriteResult(files=2, imports=3) + assert (tmp_path / "urllib3" / "util" / "retry.py").read_bytes() == ( + b"# -*- coding: latin-1 -*-\r\n" + b"from opentelemetry.agent._vendor.urllib3 import a\r\n" + b"from opentelemetry.agent._vendor.urllib3.exceptions import b\r\n" + b"s = '\xe9'\r\n" + ) + assert (tmp_path / "requests.py").read_text() == "from opentelemetry.agent._vendor.urllib3 import c\n" + assert (tmp_path / "urllib3" / "__init__.py").read_text() == "from .util import a\n" + assert (tmp_path / "notes.txt").read_text() == "from urllib3 import d\n" + + +def test_rewrite_imports_leaves_unchanged_files_untouched(tmp_path: Path) -> None: + path = tmp_path / "module.py" + path.write_text("from os import path\n") + mtime = path.stat().st_mtime_ns + + result = rewrite_imports(tmp_path, NAMESPACE, NAMES) + + assert result == RewriteResult(files=0, imports=0) + assert path.stat().st_mtime_ns == mtime + + +def test_rewrite_imports_counts_module_names(tmp_path: Path) -> None: + (tmp_path / "module.py").write_text("import urllib3, idna, os\nfrom urllib3 import a, b\n") + + result = rewrite_imports(tmp_path, NAMESPACE, NAMES) + + assert result == RewriteResult(files=1, imports=3) + + +def test_rewrite_imports_reports_unparsable_file(tmp_path: Path) -> None: + path = tmp_path / "broken.py" + path.write_text("from urllib3 import (\n") + + with pytest.raises(VendorError, match="cannot parse .*broken.py"): + rewrite_imports(tmp_path, NAMESPACE, NAMES) + + +@pytest.mark.parametrize( + ("source", "expected"), + [ + pytest.param( + 'import logging\nlogger = logging.getLogger("urllib3")\n', + 'import logging\nlogger = logging.getLogger("opentelemetry.agent._vendor.urllib3")\n', + id="get-logger", + ), + pytest.param( + "import logging\nlogging.getLogger('idna.core').addHandler(h)\n", + "import logging\nlogging.getLogger('opentelemetry.agent._vendor.idna.core').addHandler(h)\n", + id="get-logger-submodule-quote-style", + ), + pytest.param( + 'from logging import getLogger as gl\ngl("requests", x)\n', + 'from logging import getLogger as gl\ngl("opentelemetry.agent._vendor.requests", x)\n', + id="get-logger-alias", + ), + pytest.param( + 'def f(name: str = "urllib3", level=1):\n pass\n', + 'def f(name: str = "opentelemetry.agent._vendor.urllib3", level=1):\n pass\n', + id="parameter-default", + ), + ], +) +def test_rewrite_source_logger_names(source: str, expected: str) -> None: + assert rewrite_source(source, NAMESPACE, NAMES) == expected + + +@pytest.mark.parametrize( + "source", + [ + pytest.param("import logging\nlogging.getLogger(__name__)\n", id="dunder-name"), + pytest.param('import logging\nlogging.getLogger("urllib3x")\n', id="prefix-collision"), + pytest.param('import logging\nlogging.getLogger("urllib3 pool")\n', id="not-a-dotted-name"), + pytest.param('import logging\nlogging.getLogger(b"urllib3")\n', id="bytes"), + pytest.param('import logging\nlogging.getLogger(name="urllib3")\n', id="keyword"), + pytest.param('getLogger("urllib3")\n', id="get-logger-not-imported"), + pytest.param('print("urllib3")\nx = {"urllib3": 1}\n', id="other-strings"), + pytest.param('def f(x="urllib3 is great"):\n pass\n', id="parameter-default-sentence"), + pytest.param('"""urllib3 docs"""\n', id="docstring"), + ], +) +def test_rewrite_source_logger_names_unchanged(source: str) -> None: + assert rewrite_source(source, NAMESPACE, NAMES) == source + + +def test_rewrite_imports_counts_logger_names(tmp_path: Path) -> None: + (tmp_path / "module.py").write_text( + 'import logging\nimport urllib3\nlogging.getLogger("urllib3")\ndef f(name="idna"): pass\n' + ) + (tmp_path / "loggers_only.py").write_text('import logging\nlogging.getLogger("requests")\n') + + result = rewrite_imports(tmp_path, NAMESPACE, NAMES) + + assert result == RewriteResult(files=2, imports=1, loggers=3) + + +PB2_HEADER = "from google.protobuf.internal import builder as _builder\n" + + +@pytest.mark.parametrize( + ("call", "expected"), + [ + pytest.param( + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.any_pb2', _globals)", + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.any_pb2', _globals)", + id="generated-module-name", + ), + pytest.param( + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'my_protos.trace_pb2', _globals)", + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'my_protos.trace_pb2', _globals)", + id="non-vendored-module", + ), + pytest.param( + "_builder.BuildTopDescriptorsAndMessages('google.protobuf', DESCRIPTOR, _globals)", + "_builder.BuildTopDescriptorsAndMessages('google.protobuf', DESCRIPTOR, _globals)", + id="first-argument", + ), + pytest.param( + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, module_name, _globals)", + "_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, module_name, _globals)", + id="variable", + ), + ], +) +def test_rewrite_source_protobuf_module_names(call: str, expected: str) -> None: + names = NAMES | {"google"} + expected_header = "from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder\n" + + assert rewrite_source(f"{PB2_HEADER}{call}\n", NAMESPACE, names) == f"{expected_header}{expected}\n" + + +def test_rewrite_source_protobuf_builder_not_imported() -> None: + source = "def BuildTopDescriptorsAndMessages(*args): pass\nBuildTopDescriptorsAndMessages(D, 'google.x_pb2', g)\n" + + assert rewrite_source(source, NAMESPACE, NAMES | {"google"}) == source + + +def test_rewrite_imports_counts_protobuf_module_names(tmp_path: Path) -> None: + (tmp_path / "any_pb2.py").write_text( + f"{PB2_HEADER}_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.any_pb2', _globals)\n" + ) + + result = rewrite_imports(tmp_path, NAMESPACE, NAMES | {"google"}) + + assert result == RewriteResult(files=1, imports=1, modules=1) diff --git a/agent/opentelemetry-vendor/tests/test_sbom.py b/agent/opentelemetry-vendor/tests/test_sbom.py index addb52c13a4..01e2316c112 100644 --- a/agent/opentelemetry-vendor/tests/test_sbom.py +++ b/agent/opentelemetry-vendor/tests/test_sbom.py @@ -8,6 +8,7 @@ from pathlib import Path from opentelemetry.vendor.metadata import VendoredPackage +from opentelemetry.vendor.patches import VendorPatch from opentelemetry.vendor.sbom import write_sbom @@ -60,3 +61,21 @@ def test_write_sbom_is_deterministic(tmp_path: Path) -> None: write_sbom(list(reversed(PACKAGES)), second) assert first.read_bytes() == second.read_bytes() + + +def test_write_sbom_records_patches(tmp_path: Path) -> None: + unpatched, patched = tmp_path / "unpatched.json", tmp_path / "patched.json" + text = "Disable aliases.\n\ndiff --git a/urllib3/a.py b/urllib3/a.py\n" + patch = VendorPatch(path=Path("urllib3.patch"), text=text, files=("urllib3/a.py",)) + + write_sbom(PACKAGES, unpatched) + write_sbom(PACKAGES, patched, {"urllib3": [patch]}) + + unpatched_bom, patched_bom = json.loads(unpatched.read_text()), json.loads(patched.read_text()) + components = {c["name"]: c for c in patched_bom["components"]} + assert components["urllib3"]["pedigree"] == { + "patches": [{"type": "unofficial", "diff": {"text": {"content": text, "contentType": "text/plain"}}}] + } + assert "pedigree" not in components["idna"] + assert all("pedigree" not in c for c in unpatched_bom["components"]) + assert patched_bom["serialNumber"] != unpatched_bom["serialNumber"] diff --git a/agent/opentelemetry-vendor/tests/test_sync.py b/agent/opentelemetry-vendor/tests/test_sync.py index b737ccf13b6..8826dc5e6ec 100644 --- a/agent/opentelemetry-vendor/tests/test_sync.py +++ b/agent/opentelemetry-vendor/tests/test_sync.py @@ -8,7 +8,7 @@ import pytest from opentelemetry.vendor.errors import VendorError -from opentelemetry.vendor.sync import clean_destination, drop_paths +from opentelemetry.vendor.sync import clean_destination, drop_paths, read_requirements def test_clean_destination_keeps_protected_files(tmp_path: Path) -> None: @@ -90,3 +90,37 @@ def test_drop_paths_ignores_dist_info(tmp_path: Path) -> None: drop_paths(tmp_path, ["**/METADATA"]) assert (tmp_path / "wrapt-2.0.dist-info/METADATA").exists() + + +def test_read_requirements(tmp_path: Path) -> None: + requirements = tmp_path / "requirements.txt" + requirements.write_text( + "# This file was autogenerated by uv\n" + "--index-url https://example.invalid/simple\n" + "certifi==2026.10.23 \\\n" + " --hash=sha256:aaa \\\n" + " --hash=sha256:bbb\n" + " # via requests\n" + "\n" + "idna==3.20 --hash=sha256:ccc # trailing comment\n" + ) + + assert read_requirements(requirements) == [ + "certifi==2026.10.23 --hash=sha256:aaa --hash=sha256:bbb", + "idna==3.20 --hash=sha256:ccc", + ] + + +def test_read_requirements_requires_hashes(tmp_path: Path) -> None: + requirements = tmp_path / "requirements.txt" + requirements.write_text("certifi==1.0 --hash=sha256:aaa\ncharset-normalizer==3.5.2 ; python_version >= '3.10'\n") + + with pytest.raises( + VendorError, match=r"requirement 'charset-normalizer' in .* has no --hash; compile it with --generate-hashes" + ): + read_requirements(requirements) + + +def test_read_requirements_missing(tmp_path: Path) -> None: + with pytest.raises(VendorError, match="does not exist"): + read_requirements(tmp_path / "requirements.txt") diff --git a/uv.lock b/uv.lock index 536f28dac75..c517e223b59 100644 --- a/uv.lock +++ b/uv.lock @@ -2445,6 +2445,74 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8c/7e/e7394eeb49a41cc514b3eb49020223666cbf40d86f5721c2f07871e6d84a/legacy_cgi-2.6.4-py3-none-any.whl", hash = "sha256:7e235ce58bf1e25d1fc9b2d299015e4e2cd37305eccafec1e6bac3fc04b878cd", size = 20035, upload-time = "2025-10-27T05:20:04.289Z" }, ] +[[package]] +name = "libcst" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml", marker = "python_full_version != '3.13.*'" }, + { name = "pyyaml-ft", marker = "python_full_version == '3.13.*'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/c0/098e5c91ff1537f00c85a6438b6cb1863d17144680cc91f47c87f104a200/libcst-1.9.0.tar.gz", hash = "sha256:087b58a9afe076bb08e2d726478e1f16cb928d67ffa9092817e033c335de522a", size = 914739, upload-time = "2026-07-29T21:28:43.153Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/b3/23144dcd9f9cd6f6150058653ecd0357c6b09361656ebd286165a5d76d34/libcst-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5705f664266742b8d9323db714f58cf06a6cde739eb09fd9ca31cd233f9806e5", size = 2055037, upload-time = "2026-07-29T19:24:27.708Z" }, + { url = "https://files.pythonhosted.org/packages/5d/87/164a9bac39a817b505d27cf4490e6f66b2a1b8adb6b4e022b1ef4613bcfe/libcst-1.9.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:7dcddfb4905c5ef90a6fdc58dccbc049faf0056b68161042fc1e0526b20cba05", size = 2210166, upload-time = "2026-07-29T19:24:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/1c/cb/b5aeaefbe471c4225c145c15c3bac96d67b0641a5e3ec9b871c62858c88c/libcst-1.9.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cc84aee3c293a012db722aa2d6ea87be524646852684a5a4e54c1fb98ea9072f", size = 2260568, upload-time = "2026-07-29T19:24:31.021Z" }, + { url = "https://files.pythonhosted.org/packages/ab/0f/351dcd23629732e35e716e13ad536a193124cda075ac5e59dc866503447b/libcst-1.9.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:329ffda6b0ef708ff22876f982ec886a509c8f73ac1ccb0190693d35cb09aa0f", size = 2276024, upload-time = "2026-07-29T19:24:32.393Z" }, + { url = "https://files.pythonhosted.org/packages/74/f5/0da2b60137a6290ba7dda902b32da64d46c9a5107aa002da578f8b1ff8c8/libcst-1.9.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5302fc698ef863e1a2fb540e95793b3d5a96abc89aa6423ee9c389d7d7ec5eab", size = 2384413, upload-time = "2026-07-29T19:24:33.983Z" }, + { url = "https://files.pythonhosted.org/packages/8f/80/7e48d2fc1afda13a6de50ab6f8340dbd104fd6c9bcd2ff11dec66e320f2c/libcst-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:a6615b036694f6906e30dc018b5b34898cff7ff760ab549f9dea1ada4f53495b", size = 2110204, upload-time = "2026-07-29T19:24:35.491Z" }, + { url = "https://files.pythonhosted.org/packages/42/87/52c88c7ba873011526aa35b8fa0cf55d50effe967c999e7cb688155c5691/libcst-1.9.0-cp310-cp310-win_arm64.whl", hash = "sha256:dacc583bcd8db56e457ae559b910673c6b5df66f694d1f1154ce0b3982158d17", size = 1988757, upload-time = "2026-07-29T19:24:37.053Z" }, + { url = "https://files.pythonhosted.org/packages/53/36/b45e6950878d9143f95db609432031ac688b311aa14450a8df239c648c45/libcst-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cdbafbc992b38ea005ef37e20243c4177879020c82d414789fbb7fa22d6d3a9", size = 2054911, upload-time = "2026-07-29T19:24:38.542Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d8/1c1ae22e05fbc763dc5a4e4c3cab356166913ef19d2c2da42e6f1be5c98c/libcst-1.9.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3f735e3acb3afc75d50803fde1598b467bf05d12d6854025df4398aebd75a14c", size = 2209147, upload-time = "2026-07-29T19:24:40.039Z" }, + { url = "https://files.pythonhosted.org/packages/84/e1/0d5eaeac4dadd34fcd9ea154d0a6e5ce10c9fec0e02c73f807a16475b8b0/libcst-1.9.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:951f13c193e590fc88c9582a5341a130fe53ecece51043cff4bd54e25a5e022d", size = 2260355, upload-time = "2026-07-29T19:24:41.423Z" }, + { url = "https://files.pythonhosted.org/packages/71/b2/45ce33c6bca5c1961a90f2999138741daa0dc8cf6fe8b122c0ca2502632d/libcst-1.9.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bc6aa3e7f21315dbe9868c0d13ffaac309514e8c816320c5f91230fa5b21df92", size = 2275659, upload-time = "2026-07-29T19:24:42.828Z" }, + { url = "https://files.pythonhosted.org/packages/bb/b1/936d2f17d93fb160579ff56ca671d26154209bbc07ea8645eb11db1f9633/libcst-1.9.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f101e0bf8638eba80694ecc3c3abb5309eb488f5271427536cb379c5c1e0ba9e", size = 2383467, upload-time = "2026-07-29T19:24:44.397Z" }, + { url = "https://files.pythonhosted.org/packages/e7/59/db667f15d62cb22c75b24f6b13c4151292aa1889a64ff9abce92f60d5a97/libcst-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:77d9303572cf0fbd0a2eb71aff167a4246541f43bf58b781b35b9d0bbab80ddc", size = 2109985, upload-time = "2026-07-29T19:24:45.966Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a8/99926865cd3f97c0cffc71cd38152c883b7ae666eb8327d355f01bddb33a/libcst-1.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:4090105fa4ad114766d0f8b34418d9a3b359bc8645da860a447e19770b5705d1", size = 1988559, upload-time = "2026-07-29T19:24:47.528Z" }, + { url = "https://files.pythonhosted.org/packages/b0/bb/d22c37c33dfe18084634f5ef89f8f0749ffe7b6e0ad312722aafd86bbbdb/libcst-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cd1a3500c41784075c4946a995d5ad89f68fa0d226b63ff3c4d78f6ea6dd23e5", size = 2043159, upload-time = "2026-07-29T19:24:49.013Z" }, + { url = "https://files.pythonhosted.org/packages/10/b8/2dedef84d72e7271119217503b69ed6dc5d0b2077685e163caae669d9c70/libcst-1.9.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:611cebd3bbc2014576f4dcc7b845b3c594c96ddc287a3db9b78f22eff156a7d3", size = 2203245, upload-time = "2026-07-29T19:24:50.399Z" }, + { url = "https://files.pythonhosted.org/packages/e8/90/e02ac2dad647423f947bb11f8322bfdba8ccfdd380e6c7b695add2d1acd4/libcst-1.9.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:8d731abe1307720ea1a52d447555e8443a6d130e0e520243c0634a58f6edbc9d", size = 2255388, upload-time = "2026-07-29T19:24:52.21Z" }, + { url = "https://files.pythonhosted.org/packages/13/5f/6089a51518cfd2ff40950eb26bcc36951d7b6d4f4213568aa0290265aff7/libcst-1.9.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8bc5351d92ca6ac1cc32e097700e1161ad1ceaa4d9b2cca5abadb1e94576b325", size = 2268982, upload-time = "2026-07-29T19:24:53.562Z" }, + { url = "https://files.pythonhosted.org/packages/ed/78/26881ec466fb70cbc129dca26ccb5a52a0061face2c5822e4b61f00f9699/libcst-1.9.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03165a264653bb77f6a11b412ae09c08bdb0c25864f3b8d42b816ac64b9d4b9e", size = 2378174, upload-time = "2026-07-29T19:24:55.175Z" }, + { url = "https://files.pythonhosted.org/packages/e1/7a/a4dba5f11faf12a12ffba06d18019987851aab33b590242a602ffd4fb1bd/libcst-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:b755ed4a4bc2faee849b54820023137d60d4c199e0a0822f0ff0c1bc49e49b48", size = 2103462, upload-time = "2026-07-29T19:24:56.966Z" }, + { url = "https://files.pythonhosted.org/packages/f5/13/57cb129093e0d6744b3c914ba6cbbdf51ed1b2c823882936c553a3a0cf1b/libcst-1.9.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e50576bad7d56459d9792cd0b0dfe5469dad13646e9a9c0a8b1ba20b269f332", size = 1979825, upload-time = "2026-07-29T19:24:58.403Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b1/befc0544283bb3923a928accf79ed685e5a725524bdb3491826670affc07/libcst-1.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8b9df30f524317b097dc53065b25dda33d6a4cc3c7c8bf4fc83ca7559c58cc0", size = 2043754, upload-time = "2026-07-29T19:24:59.885Z" }, + { url = "https://files.pythonhosted.org/packages/45/50/fef7c172a8457c95894edf5fb04805024899cdfea41fa01b0636587b79e1/libcst-1.9.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:e465a7bc9c2b9533eb9e06d2391f8819f811b5112919d4064c9fb8565aaafa08", size = 2203548, upload-time = "2026-07-29T19:25:01.323Z" }, + { url = "https://files.pythonhosted.org/packages/18/ff/764cd2be1fd99d774fc44039c319dc0ed1d9d9afeaa02759a05121cccd4b/libcst-1.9.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:8504b422c95676a8c27b517e1ac01413ece91bf356865c587ca9bdcd5708a2f7", size = 2255274, upload-time = "2026-07-29T19:25:02.764Z" }, + { url = "https://files.pythonhosted.org/packages/34/a7/474748a27a02fa83e3556b260d5f5236ca48164fa7beffecf3b2cad24dca/libcst-1.9.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bcb9f9d4fcfe2ec7a40d2c26e03a538d5d9dc189c38551eb3f94ab661afee7c0", size = 2269126, upload-time = "2026-07-29T19:25:04.158Z" }, + { url = "https://files.pythonhosted.org/packages/8a/b7/655e45363b8cf87b91e41e060b21c89e5316c7ef36eb14a1a498b27bb71e/libcst-1.9.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e8d671c39a431c309476099b8ec811e412503ec0f4465f6fc907cb51c70e8e6b", size = 2378602, upload-time = "2026-07-29T19:25:06.424Z" }, + { url = "https://files.pythonhosted.org/packages/db/13/6da63f0902ece43bf9d737017251ad7ad06edd9d3c4e1856450403cb4473/libcst-1.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:4d382fba04077eb556a1ea4295a4482e192aa93639c5a07ba0885841965ea0c0", size = 2103486, upload-time = "2026-07-29T19:25:07.979Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ff/dccb1a55e38b4e47256a97242d61d2bef5366c744faf88fb087d4fa0f995/libcst-1.9.0-cp313-cp313-win_arm64.whl", hash = "sha256:a621e261990148c1cfbe26c1798bd2375c131cf358a44a7a4659fc41c1a336e1", size = 1979907, upload-time = "2026-07-29T19:25:09.532Z" }, + { url = "https://files.pythonhosted.org/packages/65/2a/4943c71d90975bc59034a057dea346b365c276f308c1d31f5cf2bd85492d/libcst-1.9.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:eccf4c57d273cdd3fe1c67b72cf9bb1bbd4547aa011824e96ccf5b7136057aa4", size = 2044529, upload-time = "2026-07-29T19:25:11.04Z" }, + { url = "https://files.pythonhosted.org/packages/be/ed/1168b98c2a0f338be3a44753647baab051feaf6167cc887bf4447f8fd920/libcst-1.9.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:32395244edfe6538e0ea2bf82051d60103d3f54861274805c4fb3745efb70a85", size = 2203519, upload-time = "2026-07-29T19:25:12.543Z" }, + { url = "https://files.pythonhosted.org/packages/25/7d/2eaa697a80f899bcf2245680bbfcc1e478eb3b3328c21d4b2880bdf00dac/libcst-1.9.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:444e84c76cd035cd2fe136838c1a524d34b08216521f6f5093df8a6f6cfa5799", size = 2255879, upload-time = "2026-07-29T19:25:14.137Z" }, + { url = "https://files.pythonhosted.org/packages/90/03/793b9fd96dd52d202f5f2b88d7e54f05ebed767d1bb3b32395a1817bf6ab/libcst-1.9.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bb5d0946f2b4c6711b5d69fe4f833b364f9e7a1a2b08f88b98619dc18975099a", size = 2269807, upload-time = "2026-07-29T19:25:15.647Z" }, + { url = "https://files.pythonhosted.org/packages/a3/f4/1bc7aaea03971c45e8a885fed9fc1c73176dbbd00b0296a3cde9529bafd6/libcst-1.9.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:45808c03528b3ad40b14095348a918e08d98c47b4a125d631cb78e817c0a5b16", size = 2378171, upload-time = "2026-07-29T19:25:17.289Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f7/bc49e367d2bc8817213594dd52cf6b2da2dbbda90b5382d60653999274ac/libcst-1.9.0-cp314-cp314-win_amd64.whl", hash = "sha256:568288cdbfe3b4ca3ae4852cb0a439ff053dd54c841bc4995bf2b71238b5de40", size = 2177847, upload-time = "2026-07-29T19:25:19.35Z" }, + { url = "https://files.pythonhosted.org/packages/87/80/4d81577a22e6d535d1a3409f3a1c6903e09036f0e17fc47f92169dbc3501/libcst-1.9.0-cp314-cp314-win_arm64.whl", hash = "sha256:107593af46945593e7825821793393262bc4fa1d3ea24c3ed487b61269bbbdf8", size = 2058134, upload-time = "2026-07-29T19:25:20.769Z" }, + { url = "https://files.pythonhosted.org/packages/d1/7f/c3f3a0e7a1a2adaa76e815e82a7814d6bfe7d49432276bba652248c68d0b/libcst-1.9.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f6248cb07444ab9a6733a855737a9febed8b9adca51347019348b09a3ac7dfe9", size = 2036102, upload-time = "2026-07-29T19:25:22.212Z" }, + { url = "https://files.pythonhosted.org/packages/4e/af/2f5543255b2c7d749b966adeccc6bfb1652cf8b425afb913d0f3f025a865/libcst-1.9.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:496c24e0d3240bc7da45dae543aff3f5b6509978c39262d6b84ed2fb999dded2", size = 2194806, upload-time = "2026-07-29T19:25:24.017Z" }, + { url = "https://files.pythonhosted.org/packages/cb/5b/03f4cddce426d005e208b39ea7b2d456e667cdee0f1891360f0fc8430f20/libcst-1.9.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ea490fa8540503db5f321f0268becab46eb50f710e8cec8041e241fd66f6874f", size = 2246762, upload-time = "2026-07-29T19:25:25.365Z" }, + { url = "https://files.pythonhosted.org/packages/d8/31/9d5fe1e43dc3dbcc74f70f3e0e73fcdd8d84effc1059d8b45974f0d0d2eb/libcst-1.9.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:50ab94bb2524b419056d4003032b8c67102ac800f8d85b3c4260a01746d94dbb", size = 2259633, upload-time = "2026-07-29T19:25:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2b/6752b28d88c3a19b3bc0b9e1838443b6760d5c862b4f4b37955402659e24/libcst-1.9.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a2faaf92500d0226358125630f5aab4758e8aad3f2d70a10892ec3c700781a54", size = 2368043, upload-time = "2026-07-29T19:25:28.344Z" }, + { url = "https://files.pythonhosted.org/packages/e2/94/775825b2637f8ab05694b6a4b3802ae6783b4e799f9b58d2400c7e2d4369/libcst-1.9.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c7b548512db25af9c2997a95fa731bd6b6928ecbad6c0915d7482d8bb42d34f", size = 2176432, upload-time = "2026-07-29T19:25:29.921Z" }, + { url = "https://files.pythonhosted.org/packages/fb/3d/88ad67427c6fd9db929e087912b0a540e5140e5cb77e7ca4170edaac8531/libcst-1.9.0-cp314-cp314t-win_arm64.whl", hash = "sha256:497d5329345f1f5df84e41b0bbd00204b64a2fd30dfe3cfaeaebca633a31e877", size = 2052931, upload-time = "2026-07-29T19:25:31.397Z" }, + { url = "https://files.pythonhosted.org/packages/39/e4/ad790b043a38b10cea13166c8dd716654ad8b227c20f12eebf6326191cd9/libcst-1.9.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:a5068bf6114f6f4d79af7a6c80a28d1deb50441150ea1db13b5458ab34bec159", size = 2043987, upload-time = "2026-08-11T05:54:02.122Z" }, + { url = "https://files.pythonhosted.org/packages/15/6b/d3cd8275cc54ffc9817ade91442b3e6e9edd1a4518bd4e6dda13e3152dbe/libcst-1.9.0-cp315-cp315-manylinux_2_28_aarch64.whl", hash = "sha256:7acfd18adcdd32dcf41ce676cf121002afcbe9ad2c72dc0c18d78465beedc228", size = 2204003, upload-time = "2026-08-11T05:54:04.031Z" }, + { url = "https://files.pythonhosted.org/packages/da/62/87eddccb11d5d221d50ac4fff4b6e9b8d48c547028d01f7d0fbc5c8a1d75/libcst-1.9.0-cp315-cp315-manylinux_2_28_x86_64.whl", hash = "sha256:86361e2b426bd1b403e52375703c8b764e226e571adcb30442510710681edbf0", size = 2256053, upload-time = "2026-08-11T05:54:06.228Z" }, + { url = "https://files.pythonhosted.org/packages/18/53/a44126aeb9fca8b4e342e0cc803ea00ca8f6cd5712619a7897b3eba13797/libcst-1.9.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:8c14abe844bec8b021111b3985474e49f5af799c020e8e40dedcac87c97a40c5", size = 2270576, upload-time = "2026-08-11T05:54:08.01Z" }, + { url = "https://files.pythonhosted.org/packages/bb/51/3af3dd44b117d66486e0ed61e43a16b7fc8cc5c372e1dd4ca0e70b888d46/libcst-1.9.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:8930971d2299b7006bb5d10c10038f44efb6da89d5bca2823595e31a9cdb96af", size = 2378573, upload-time = "2026-08-11T05:54:10.093Z" }, + { url = "https://files.pythonhosted.org/packages/fc/e8/e545087d298dbf6494e84a8092f0f5dbd62eedacabd4ecd6b364367b4804/libcst-1.9.0-cp315-cp315-win_amd64.whl", hash = "sha256:5891ce9cff815077614f509e3a23888c5ddb8081d6188e8ba1172c0ccc369022", size = 2177937, upload-time = "2026-08-11T05:54:12.168Z" }, + { url = "https://files.pythonhosted.org/packages/84/17/93a00a8e03494a84db102dd0e3d35b8876b1084ca2c194b331a168d86eb1/libcst-1.9.0-cp315-cp315-win_arm64.whl", hash = "sha256:1260b5d070a3324447a53a00387225a55472a62077ce01922d30a2a78cc4b138", size = 2058633, upload-time = "2026-08-11T05:54:13.817Z" }, + { url = "https://files.pythonhosted.org/packages/d7/00/c3751b12eb81822ea0b6131d374a98bc6c024c4b9ec5f6ea8f53dc23e967/libcst-1.9.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:02ee2dbdb5c218116f16a021350fc267a14be205b50d81c33f5d73857ab6fbf7", size = 2036178, upload-time = "2026-08-11T05:54:15.545Z" }, + { url = "https://files.pythonhosted.org/packages/2f/12/48ff486eb5adc593f4818569e8896b74b672414ab4722a74b17e4c4cf31e/libcst-1.9.0-cp315-cp315t-manylinux_2_28_aarch64.whl", hash = "sha256:3e5b684191a0462b2d40a73261ea7f4da6a49e7a030b7e0fceca46bebb51dfe5", size = 2195496, upload-time = "2026-08-11T05:54:17.625Z" }, + { url = "https://files.pythonhosted.org/packages/51/18/b13a4669864d41a4801fed7b86ede1049dc9a1e1dde250a7ee1f9c3b1285/libcst-1.9.0-cp315-cp315t-manylinux_2_28_x86_64.whl", hash = "sha256:2b150c4f298fe54eb0fe73abf71f57db74d070796140a8c206c9615b6861f01e", size = 2245769, upload-time = "2026-08-11T05:54:19.343Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c7/cf2d46744825e84afbd7228fdeeea8d23cf6c4b2074253c27efb7705c653/libcst-1.9.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:50b913e37187f00a6fb88962009364e1cf1b1284aa1762304f34b52b972f2218", size = 2260576, upload-time = "2026-08-11T05:54:21.444Z" }, + { url = "https://files.pythonhosted.org/packages/d1/4d/5433d3d62250b2e4325938db101766bcab2a006819684713bcccb6259a88/libcst-1.9.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:9f92c75283030fd58fb7d6e560168a00381e0e3368ec8a026a3ec8a828a05f93", size = 2368709, upload-time = "2026-08-11T05:54:23.276Z" }, + { url = "https://files.pythonhosted.org/packages/87/39/9f0e1690727623f99489895db0e42048a3e1e8cea0627517c593e437fd83/libcst-1.9.0-cp315-cp315t-win_amd64.whl", hash = "sha256:4adf97bb1aff8039b0bd4991e2f838be6e4fad552821b26b71a5d1a653c2582f", size = 2177866, upload-time = "2026-08-11T05:54:25.144Z" }, + { url = "https://files.pythonhosted.org/packages/cd/79/9dc7811883e67ea771057e8937bc536eb3e77f3635fc5a93cd85b6fe1ea8/libcst-1.9.0-cp315-cp315t-win_arm64.whl", hash = "sha256:8f0dd08a5773d7051e105250b2a2c73d8065ea9b2d68e7e1bdc5244660e75f93", size = 2052908, upload-time = "2026-08-11T05:54:26.835Z" }, +] + [[package]] name = "license-expression" version = "30.4.4" @@ -4702,6 +4770,7 @@ version = "0.0.0" source = { editable = "agent/opentelemetry-vendor" } dependencies = [ { name = "cyclonedx-python-lib", extra = ["json-validation"] }, + { name = "libcst" }, { name = "packageurl-python" }, { name = "pip" }, { name = "rich" }, @@ -4712,6 +4781,7 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "cyclonedx-python-lib", extras = ["json-validation"], specifier = ">=11.0,<12.0" }, + { name = "libcst", specifier = ">=1.5,<2.0" }, { name = "packageurl-python", specifier = ">=0.11,<1.0" }, { name = "pip", specifier = ">=25.0,<27.0" }, { name = "rich", specifier = ">=13.0,<16.0" }, @@ -5819,6 +5889,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] +[[package]] +name = "pyyaml-ft" +version = "8.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/eb/5a0d575de784f9a1f94e2b1288c6886f13f34185e13117ed530f32b6f8a8/pyyaml_ft-8.0.0.tar.gz", hash = "sha256:0c947dce03954c7b5d38869ed4878b2e6ff1d44b08a0d84dc83fdad205ae39ab", size = 141057, upload-time = "2025-06-10T15:32:15.613Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/ba/a067369fe61a2e57fb38732562927d5bae088c73cb9bb5438736a9555b29/pyyaml_ft-8.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8c1306282bc958bfda31237f900eb52c9bedf9b93a11f82e1aab004c9a5657a6", size = 187027, upload-time = "2025-06-10T15:31:48.722Z" }, + { url = "https://files.pythonhosted.org/packages/ad/c5/a3d2020ce5ccfc6aede0d45bcb870298652ac0cf199f67714d250e0cdf39/pyyaml_ft-8.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:30c5f1751625786c19de751e3130fc345ebcba6a86f6bddd6e1285342f4bbb69", size = 176146, upload-time = "2025-06-10T15:31:50.584Z" }, + { url = "https://files.pythonhosted.org/packages/e3/bb/23a9739291086ca0d3189eac7cd92b4d00e9fdc77d722ab610c35f9a82ba/pyyaml_ft-8.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fa992481155ddda2e303fcc74c79c05eddcdbc907b888d3d9ce3ff3e2adcfb0", size = 746792, upload-time = "2025-06-10T15:31:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c2/e8825f4ff725b7e560d62a3609e31d735318068e1079539ebfde397ea03e/pyyaml_ft-8.0.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cec6c92b4207004b62dfad1f0be321c9f04725e0f271c16247d8b39c3bf3ea42", size = 786772, upload-time = "2025-06-10T15:31:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/35/be/58a4dcae8854f2fdca9b28d9495298fd5571a50d8430b1c3033ec95d2d0e/pyyaml_ft-8.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06237267dbcab70d4c0e9436d8f719f04a51123f0ca2694c00dd4b68c338e40b", size = 778723, upload-time = "2025-06-10T15:31:56.093Z" }, + { url = "https://files.pythonhosted.org/packages/86/ed/fed0da92b5d5d7340a082e3802d84c6dc9d5fa142954404c41a544c1cb92/pyyaml_ft-8.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8a7f332bc565817644cdb38ffe4739e44c3e18c55793f75dddb87630f03fc254", size = 758478, upload-time = "2025-06-10T15:31:58.314Z" }, + { url = "https://files.pythonhosted.org/packages/f0/69/ac02afe286275980ecb2dcdc0156617389b7e0c0a3fcdedf155c67be2b80/pyyaml_ft-8.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7d10175a746be65f6feb86224df5d6bc5c049ebf52b89a88cf1cd78af5a367a8", size = 799159, upload-time = "2025-06-10T15:31:59.675Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ac/c492a9da2e39abdff4c3094ec54acac9747743f36428281fb186a03fab76/pyyaml_ft-8.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:58e1015098cf8d8aec82f360789c16283b88ca670fe4275ef6c48c5e30b22a96", size = 158779, upload-time = "2025-06-10T15:32:01.029Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9b/41998df3298960d7c67653669f37710fa2d568a5fc933ea24a6df60acaf6/pyyaml_ft-8.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e64fa5f3e2ceb790d50602b2fd4ec37abbd760a8c778e46354df647e7c5a4ebb", size = 191331, upload-time = "2025-06-10T15:32:02.602Z" }, + { url = "https://files.pythonhosted.org/packages/0f/16/2710c252ee04cbd74d9562ebba709e5a284faeb8ada88fcda548c9191b47/pyyaml_ft-8.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8d445bf6ea16bb93c37b42fdacfb2f94c8e92a79ba9e12768c96ecde867046d1", size = 182879, upload-time = "2025-06-10T15:32:04.466Z" }, + { url = "https://files.pythonhosted.org/packages/9a/40/ae8163519d937fa7bfa457b6f78439cc6831a7c2b170e4f612f7eda71815/pyyaml_ft-8.0.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c56bb46b4fda34cbb92a9446a841da3982cdde6ea13de3fbd80db7eeeab8b49", size = 811277, upload-time = "2025-06-10T15:32:06.214Z" }, + { url = "https://files.pythonhosted.org/packages/f9/66/28d82dbff7f87b96f0eeac79b7d972a96b4980c1e445eb6a857ba91eda00/pyyaml_ft-8.0.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dab0abb46eb1780da486f022dce034b952c8ae40753627b27a626d803926483b", size = 831650, upload-time = "2025-06-10T15:32:08.076Z" }, + { url = "https://files.pythonhosted.org/packages/e8/df/161c4566facac7d75a9e182295c223060373d4116dead9cc53a265de60b9/pyyaml_ft-8.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd48d639cab5ca50ad957b6dd632c7dd3ac02a1abe0e8196a3c24a52f5db3f7a", size = 815755, upload-time = "2025-06-10T15:32:09.435Z" }, + { url = "https://files.pythonhosted.org/packages/05/10/f42c48fa5153204f42eaa945e8d1fd7c10d6296841dcb2447bf7da1be5c4/pyyaml_ft-8.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:052561b89d5b2a8e1289f326d060e794c21fa068aa11255fe71d65baf18a632e", size = 810403, upload-time = "2025-06-10T15:32:11.051Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d2/e369064aa51009eb9245399fd8ad2c562bd0bcd392a00be44b2a824ded7c/pyyaml_ft-8.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3bb4b927929b0cb162fb1605392a321e3333e48ce616cdcfa04a839271373255", size = 835581, upload-time = "2025-06-10T15:32:12.897Z" }, + { url = "https://files.pythonhosted.org/packages/c0/28/26534bed77109632a956977f60d8519049f545abc39215d086e33a61f1f2/pyyaml_ft-8.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:de04cfe9439565e32f178106c51dd6ca61afaa2907d143835d501d84703d3793", size = 171579, upload-time = "2025-06-10T15:32:14.34Z" }, +] + [[package]] name = "readme-renderer" version = "46.0" From 3e429f20ee37720952a38aada029c8626d3c8189 Mon Sep 17 00:00:00 2001 From: Lukas Hering Date: Mon, 9 Nov 2026 11:32:38 -0500 Subject: [PATCH 4/5] stash --- .gitignore | 1 + agent/opentelemetry-agent/README.rst | 29 + agent/opentelemetry-agent/hatch_build.py | 45 + .../native-build-requirements.in | 2 + .../native-build-requirements.txt | 6 + .../patches/native/protobuf-upb.patch | 53 + .../patches/otel-configuration-loader.patch | 190 + .../patches/otel-distro-http-protocol.patch | 17 + .../patches/otel-importlib-metadata.patch | 69 + .../patches/otel-sdk-vendored-names.patch | 65 + ...on.patch => protobuf-implementation.patch} | 45 +- .../patches/ruamel-yaml-pure.patch | 24 + agent/opentelemetry-agent/pyproject.toml | 95 +- .../certifi-2026.10.23.dist-info/METADATA | 79 + .../METADATA | 892 + .../fastjsonschema-2.22.3.dist-info/METADATA | 60 + .../METADATA | 215 + .../_metadata/idna-3.20.dist-info/METADATA | 176 + .../METADATA | 43 + .../entry_points.txt | 15 + .../METADATA | 73 + .../METADATA | 50 + .../entry_points.txt | 5 + .../METADATA | 64 + .../entry_points.txt | 3 + .../METADATA | 52 + .../METADATA | 48 + .../METADATA | 56 + .../entry_points.txt | 8 + .../METADATA | 85 + .../entry_points.txt | 8 + .../METADATA | 51 + .../METADATA | 71 + .../entry_points.txt | 8 + .../METADATA | 54 + .../entry_points.txt | 2 + .../METADATA | 183 + .../entry_points.txt | 2 + .../METADATA | 54 + .../entry_points.txt | 2 + .../METADATA | 48 + .../entry_points.txt | 3 + .../METADATA | 63 + .../METADATA | 61 + .../METADATA | 47 + .../entry_points.txt | 38 + .../METADATA | 61 + .../METADATA | 93 + .../packaging-26.3.dist-info/METADATA | 112 + .../METADATA | 56 + .../protobuf-7.36.2.dist-info/METADATA | 17 + .../requests-2.34.2.dist-info/METADATA | 120 + .../ruamel_yaml-0.19.1.dist-info/METADATA | 317 + .../METADATA | 73 + .../urllib3-2.8.0.dist-info/METADATA | 175 + .../_metadata/wrapt-2.5.2.dist-info/METADATA | 193 + .../opentelemetry/agent/_vendor/bom.cdx.json | 845 + .../agent/_vendor/certifi.LICENSE | 20 + .../agent/_vendor/certifi/__init__.py | 4 + .../agent/_vendor/certifi/cacert.pem | 3885 ++++ .../agent/_vendor/certifi/core.py | 83 + .../agent/_vendor/charset-normalizer.LICENSE | 21 + .../_vendor/charset_normalizer/__init__.py | 48 + .../agent/_vendor/charset_normalizer/api.py | 934 + .../agent/_vendor/charset_normalizer/cd.py | 467 + .../_vendor/charset_normalizer/constant.py | 2497 +++ .../_vendor/charset_normalizer/legacy.py | 79 + .../agent/_vendor/charset_normalizer/md.py | 1065 + .../_vendor/charset_normalizer/models.py | 387 + .../agent/_vendor/charset_normalizer/utils.py | 452 + .../_vendor/charset_normalizer/version.py | 8 + .../agent/_vendor/fastjsonschema.AUTHORS | 11 + .../agent/_vendor/fastjsonschema.LICENSE | 27 + .../agent/_vendor/fastjsonschema/__init__.py | 386 + .../agent/_vendor/fastjsonschema/draft04.py | 686 + .../agent/_vendor/fastjsonschema/draft06.py | 222 + .../agent/_vendor/fastjsonschema/draft07.py | 138 + .../agent/_vendor/fastjsonschema/draft2019.py | 15 + .../_vendor/fastjsonschema/exceptions.py | 75 + .../agent/_vendor/fastjsonschema/generator.py | 429 + .../agent/_vendor/fastjsonschema/indent.py | 42 + .../_vendor/fastjsonschema/ref_resolver.py | 219 + .../agent/_vendor/fastjsonschema/version.py | 1 + .../_vendor/google/api/annotations.proto | 31 + .../_vendor/google/api/annotations_pb2.py | 55 + .../_vendor/google/api/annotations_pb2.pyi | 24 + .../agent/_vendor/google/api/auth.proto | 238 + .../agent/_vendor/google/api/auth_pb2.py | 61 + .../agent/_vendor/google/api/auth_pb2.pyi | 120 + .../agent/_vendor/google/api/backend.proto | 196 + .../agent/_vendor/google/api/backend_pb2.py | 65 + .../agent/_vendor/google/api/backend_pb2.pyi | 106 + .../agent/_vendor/google/api/billing.proto | 77 + .../agent/_vendor/google/api/billing_pb2.py | 53 + .../agent/_vendor/google/api/billing_pb2.pyi | 50 + .../agent/_vendor/google/api/client.proto | 598 + .../agent/_vendor/google/api/client_pb2.py | 118 + .../agent/_vendor/google/api/client_pb2.pyi | 498 + .../_vendor/google/api/config_change.proto | 84 + .../_vendor/google/api/config_change_pb2.py | 57 + .../_vendor/google/api/config_change_pb2.pyi | 65 + .../agent/_vendor/google/api/consumer.proto | 82 + .../agent/_vendor/google/api/consumer_pb2.py | 55 + .../agent/_vendor/google/api/consumer_pb2.pyi | 62 + .../agent/_vendor/google/api/context.proto | 92 + .../agent/_vendor/google/api/context_pb2.py | 53 + .../agent/_vendor/google/api/context_pb2.pyi | 60 + .../agent/_vendor/google/api/control.proto | 41 + .../agent/_vendor/google/api/control_pb2.py | 53 + .../agent/_vendor/google/api/control_pb2.pyi | 43 + .../_vendor/google/api/distribution.proto | 213 + .../_vendor/google/api/distribution_pb2.py | 68 + .../_vendor/google/api/distribution_pb2.pyi | 147 + .../_vendor/google/api/documentation.proto | 168 + .../_vendor/google/api/documentation_pb2.py | 57 + .../_vendor/google/api/documentation_pb2.pyi | 86 + .../agent/_vendor/google/api/endpoint.proto | 69 + .../agent/_vendor/google/api/endpoint_pb2.py | 51 + .../agent/_vendor/google/api/endpoint_pb2.pyi | 41 + .../_vendor/google/api/error_reason.proto | 807 + .../_vendor/google/api/error_reason_pb2.py | 53 + .../_vendor/google/api/error_reason_pb2.pyi | 112 + .../_vendor/google/api/field_behavior.proto | 104 + .../_vendor/google/api/field_behavior_pb2.py | 55 + .../_vendor/google/api/field_behavior_pb2.pyi | 45 + .../agent/_vendor/google/api/field_info.proto | 106 + .../_vendor/google/api/field_info_pb2.py | 59 + .../_vendor/google/api/field_info_pb2.pyi | 60 + .../agent/_vendor/google/api/http.proto | 370 + .../agent/_vendor/google/api/http_pb2.py | 55 + .../agent/_vendor/google/api/http_pb2.pyi | 94 + .../agent/_vendor/google/api/httpbody.proto | 80 + .../agent/_vendor/google/api/httpbody_pb2.py | 53 + .../agent/_vendor/google/api/httpbody_pb2.pyi | 41 + .../agent/_vendor/google/api/label.proto | 47 + .../agent/_vendor/google/api/label_pb2.py | 53 + .../agent/_vendor/google/api/label_pb2.pyi | 47 + .../_vendor/google/api/launch_stage.proto | 72 + .../_vendor/google/api/launch_stage_pb2.py | 53 + .../_vendor/google/api/launch_stage_pb2.pyi | 40 + .../agent/_vendor/google/api/log.proto | 54 + .../agent/_vendor/google/api/log_pb2.py | 53 + .../agent/_vendor/google/api/log_pb2.pyi | 47 + .../agent/_vendor/google/api/logging.proto | 81 + .../agent/_vendor/google/api/logging_pb2.py | 53 + .../agent/_vendor/google/api/logging_pb2.pyi | 57 + .../agent/_vendor/google/api/metric.proto | 287 + .../agent/_vendor/google/api/metric_pb2.py | 80 + .../agent/_vendor/google/api/metric_pb2.pyi | 199 + .../google/api/monitored_resource.proto | 129 + .../google/api/monitored_resource_pb2.py | 72 + .../google/api/monitored_resource_pb2.pyi | 104 + .../agent/_vendor/google/api/monitoring.proto | 107 + .../_vendor/google/api/monitoring_pb2.py | 55 + .../_vendor/google/api/monitoring_pb2.pyi | 57 + .../agent/_vendor/google/api/policy.proto | 82 + .../agent/_vendor/google/api/policy_pb2.py | 55 + .../agent/_vendor/google/api/policy_pb2.pyi | 57 + .../agent/_vendor/google/api/quota.proto | 184 + .../agent/_vendor/google/api/quota_pb2.py | 63 + .../agent/_vendor/google/api/quota_pb2.pyi | 116 + .../agent/_vendor/google/api/resource.proto | 242 + .../agent/_vendor/google/api/resource_pb2.py | 59 + .../agent/_vendor/google/api/resource_pb2.pyi | 93 + .../agent/_vendor/google/api/routing.proto | 465 + .../agent/_vendor/google/api/routing_pb2.py | 55 + .../agent/_vendor/google/api/routing_pb2.pyi | 49 + .../agent/_vendor/google/api/service.proto | 190 + .../agent/_vendor/google/api/service_pb2.py | 76 + .../agent/_vendor/google/api/service_pb2.pyi | 170 + .../_vendor/google/api/source_info.proto | 31 + .../_vendor/google/api/source_info_pb2.py | 55 + .../_vendor/google/api/source_info_pb2.pyi | 34 + .../_vendor/google/api/system_parameter.proto | 96 + .../google/api/system_parameter_pb2.py | 57 + .../google/api/system_parameter_pb2.pyi | 60 + .../agent/_vendor/google/api/usage.proto | 76 + .../agent/_vendor/google/api/usage_pb2.py | 53 + .../agent/_vendor/google/api/usage_pb2.pyi | 55 + .../agent/_vendor/google/api/visibility.proto | 112 + .../_vendor/google/api/visibility_pb2.py | 57 + .../_vendor/google/api/visibility_pb2.pyi | 56 + .../google/cloud/common_resources.proto | 52 + .../google/cloud/common_resources_pb2.py | 53 + .../google/cloud/common_resources_pb2.pyi | 21 + .../google/cloud/extended_operations.proto | 150 + .../google/cloud/extended_operations_pb2.py | 60 + .../google/cloud/extended_operations_pb2.pyi | 45 + .../google/cloud/location/locations.proto | 108 + .../google/cloud/location/locations_pb2.py | 87 + .../google/cloud/location/locations_pb2.pyi | 96 + .../gapic/metadata/gapic_metadata.proto | 98 + .../gapic/metadata/gapic_metadata_pb2.py | 78 + .../gapic/metadata/gapic_metadata_pb2.pyi | 122 + .../google/logging/type/http_request.proto | 95 + .../google/logging/type/http_request_pb2.py | 60 + .../google/logging/type/http_request_pb2.pyi | 94 + .../google/logging/type/log_severity.proto | 71 + .../google/logging/type/log_severity_pb2.py | 58 + .../google/logging/type/log_severity_pb2.pyi | 42 + .../google/longrunning/operations_grpc.py | 20 + .../google/longrunning/operations_grpc_pb2.py | 16 + .../google/longrunning/operations_pb2.py | 45 + .../google/longrunning/operations_proto.proto | 265 + .../google/longrunning/operations_proto.py | 6 + .../longrunning/operations_proto_pb2.py | 111 + .../longrunning/operations_proto_pb2.pyi | 136 + .../agent/_vendor/google/protobuf/__init__.py | 10 + .../agent/_vendor/google/protobuf/any.py | 52 + .../agent/_vendor/google/protobuf/any_pb2.py | 37 + .../agent/_vendor/google/protobuf/api_pb2.py | 47 + .../_vendor/google/protobuf/descriptor.py | 1669 ++ .../google/protobuf/descriptor_database.py | 186 + .../_vendor/google/protobuf/descriptor_pb2.py | 3465 ++++ .../google/protobuf/descriptor_pool.py | 1468 ++ .../agent/_vendor/google/protobuf/duration.py | 100 + .../_vendor/google/protobuf/duration_pb2.py | 37 + .../_vendor/google/protobuf/empty_pb2.py | 37 + .../_vendor/google/protobuf/field_mask_pb2.py | 37 + .../google/protobuf/internal/__init__.py | 6 + .../protobuf/internal/api_implementation.py | 72 + .../google/protobuf/internal/builder.py | 123 + .../google/protobuf/internal/containers.py | 826 + .../google/protobuf/internal/decoder.py | 1127 + .../google/protobuf/internal/encoder.py | 931 + .../protobuf/internal/enum_type_wrapper.py | 128 + .../protobuf/internal/extension_dict.py | 209 + .../google/protobuf/internal/field_mask.py | 352 + .../protobuf/internal/message_listener.py | 56 + .../internal/python_edition_defaults.py | 5 + .../protobuf/internal/python_message.py | 1778 ++ .../google/protobuf/internal/type_checkers.py | 465 + .../protobuf/internal/well_known_types.py | 707 + .../google/protobuf/internal/wire_format.py | 255 + .../protobuf/json_enumvalue_options_pb2.py | 40 + .../_vendor/google/protobuf/json_format.py | 1247 ++ .../google/protobuf/json_options_pb2.py | 37 + .../agent/_vendor/google/protobuf/message.py | 467 + .../google/protobuf/message_factory.py | 188 + .../agent/_vendor/google/protobuf/proto.py | 153 + .../_vendor/google/protobuf/proto_builder.py | 117 + .../_vendor/google/protobuf/proto_json.py | 81 + .../_vendor/google/protobuf/proto_text.py | 118 + .../_vendor/google/protobuf/pyext/__init__.py | 0 .../google/protobuf/pyext/cpp_message.py | 46 + .../_vendor/google/protobuf/reflection.py | 36 + .../google/protobuf/runtime_version.py | 105 + .../google/protobuf/service_reflection.py | 284 + .../google/protobuf/source_context_pb2.py | 37 + .../_vendor/google/protobuf/struct_pb2.py | 47 + .../google/protobuf/symbol_database.py | 178 + .../_vendor/google/protobuf/text_encoding.py | 111 + .../_vendor/google/protobuf/text_format.py | 2089 ++ .../_vendor/google/protobuf/timestamp.py | 112 + .../_vendor/google/protobuf/timestamp_pb2.py | 37 + .../agent/_vendor/google/protobuf/type_pb2.py | 53 + .../_vendor/google/protobuf/unknown_fields.py | 93 + .../_vendor/google/protobuf/util/__init__.py | 0 .../_vendor/google/protobuf/wrappers_pb2.py | 53 + .../agent/_vendor/google/rpc/code.proto | 186 + .../agent/_vendor/google/rpc/code_pb2.py | 51 + .../agent/_vendor/google/rpc/code_pb2.pyi | 58 + .../rpc/context/attribute_context.proto | 350 + .../rpc/context/attribute_context_pb2.py | 97 + .../rpc/context/attribute_context_pb2.pyi | 326 + .../google/rpc/context/audit_context.proto | 48 + .../google/rpc/context/audit_context_pb2.py | 60 + .../google/rpc/context/audit_context_pb2.pyi | 51 + .../_vendor/google/rpc/error_details.proto | 363 + .../_vendor/google/rpc/error_details_pb2.py | 91 + .../_vendor/google/rpc/error_details_pb2.pyi | 250 + .../agent/_vendor/google/rpc/http.proto | 64 + .../agent/_vendor/google/rpc/http_pb2.py | 55 + .../agent/_vendor/google/rpc/http_pb2.pyi | 71 + .../agent/_vendor/google/rpc/status.proto | 48 + .../agent/_vendor/google/rpc/status_pb2.py | 53 + .../agent/_vendor/google/rpc/status_pb2.pyi | 41 + .../_vendor/google/type/calendar_period.proto | 56 + .../google/type/calendar_period_pb2.py | 53 + .../google/type/calendar_period_pb2.pyi | 40 + .../agent/_vendor/google/type/color.proto | 173 + .../agent/_vendor/google/type/color_pb2.py | 53 + .../agent/_vendor/google/type/color_pb2.pyi | 42 + .../agent/_vendor/google/type/date.proto | 54 + .../agent/_vendor/google/type/date_pb2.py | 51 + .../agent/_vendor/google/type/date_pb2.pyi | 36 + .../agent/_vendor/google/type/datetime.proto | 104 + .../agent/_vendor/google/type/datetime_pb2.py | 57 + .../_vendor/google/type/datetime_pb2.pyi | 80 + .../agent/_vendor/google/type/dayofweek.proto | 50 + .../_vendor/google/type/dayofweek_pb2.py | 53 + .../_vendor/google/type/dayofweek_pb2.pyi | 40 + .../agent/_vendor/google/type/decimal.proto | 93 + .../agent/_vendor/google/type/decimal_pb2.py | 51 + .../agent/_vendor/google/type/decimal_pb2.pyi | 27 + .../agent/_vendor/google/type/expr.proto | 73 + .../agent/_vendor/google/type/expr_pb2.py | 51 + .../agent/_vendor/google/type/expr_pb2.pyi | 39 + .../agent/_vendor/google/type/fraction.proto | 33 + .../agent/_vendor/google/type/fraction_pb2.py | 53 + .../_vendor/google/type/fraction_pb2.pyi | 31 + .../agent/_vendor/google/type/interval.proto | 45 + .../agent/_vendor/google/type/interval_pb2.py | 55 + .../_vendor/google/type/interval_pb2.pyi | 41 + .../agent/_vendor/google/type/latlng.proto | 36 + .../agent/_vendor/google/type/latlng_pb2.py | 51 + .../agent/_vendor/google/type/latlng_pb2.pyi | 31 + .../_vendor/google/type/localized_text.proto | 36 + .../_vendor/google/type/localized_text_pb2.py | 53 + .../google/type/localized_text_pb2.pyi | 31 + .../agent/_vendor/google/type/money.proto | 41 + .../agent/_vendor/google/type/money_pb2.py | 51 + .../agent/_vendor/google/type/money_pb2.pyi | 36 + .../agent/_vendor/google/type/month.proto | 65 + .../agent/_vendor/google/type/month_pb2.py | 51 + .../agent/_vendor/google/type/month_pb2.pyi | 50 + .../_vendor/google/type/phone_number.proto | 118 + .../_vendor/google/type/phone_number_pb2.py | 55 + .../_vendor/google/type/phone_number_pb2.pyi | 48 + .../_vendor/google/type/postal_address.proto | 134 + .../_vendor/google/type/postal_address_pb2.py | 53 + .../google/type/postal_address_pb2.pyi | 74 + .../_vendor/google/type/quaternion.proto | 94 + .../_vendor/google/type/quaternion_pb2.py | 53 + .../_vendor/google/type/quaternion_pb2.pyi | 39 + .../agent/_vendor/google/type/timeofday.proto | 47 + .../_vendor/google/type/timeofday_pb2.py | 53 + .../_vendor/google/type/timeofday_pb2.pyi | 39 + .../_vendor/googleapis-common-protos.LICENSE | 202 + .../agent/_vendor/idna.LICENSE.md | 31 + .../agent/_vendor/idna/__init__.py | 47 + .../opentelemetry/agent/_vendor/idna/codec.py | 225 + .../agent/_vendor/idna/compat.py | 43 + .../opentelemetry/agent/_vendor/idna/core.py | 863 + .../agent/_vendor/idna/idnadata.py | 1933 ++ .../agent/_vendor/idna/intranges.py | 55 + .../agent/_vendor/idna/package_data.py | 1 + .../agent/_vendor/idna/uts46data.py | 17117 ++++++++++++++++ .../agent/_vendor/opentelemetry-api.LICENSE | 201 + .../opentelemetry-configuration.LICENSE | 201 + .../_vendor/opentelemetry-distro.LICENSE | 201 + ...ntelemetry-exporter-http-transport.LICENSE | 201 + ...opentelemetry-exporter-otlp-common.LICENSE | 201 + ...elemetry-exporter-otlp-json-common.LICENSE | 201 + ...ntelemetry-exporter-otlp-json-file.LICENSE | 201 + ...ntelemetry-exporter-otlp-json-http.LICENSE | 201 + ...lemetry-exporter-otlp-proto-common.LICENSE | 201 + ...telemetry-exporter-otlp-proto-http.LICENSE | 201 + .../opentelemetry-exporter-prometheus.LICENSE | 201 + ...try-instrumentation-aiohttp-client.LICENSE | 201 + .../opentelemetry-instrumentation.LICENSE | 201 + .../opentelemetry-propagator-b3.LICENSE | 201 + .../_vendor/opentelemetry-proto-json.LICENSE | 201 + .../agent/_vendor/opentelemetry-proto.LICENSE | 201 + .../agent/_vendor/opentelemetry-sdk.LICENSE | 201 + ...opentelemetry-semantic-conventions.LICENSE | 201 + .../_vendor/opentelemetry-util-http.LICENSE | 201 + .../_vendor/opentelemetry/_logs/__init__.py | 47 + .../opentelemetry/_logs/_internal/__init__.py | 484 + .../opentelemetry/_logs/severity/__init__.py | 44 + .../opentelemetry/attributes/__init__.py | 243 + .../_vendor/opentelemetry/baggage/__init__.py | 122 + .../baggage/propagation/__init__.py | 179 + .../opentelemetry/configuration/README.md | 30 + .../opentelemetry/configuration/__init__.py | 44 + .../opentelemetry/configuration/_common.py | 228 + .../configuration/_conversion.py | 137 + .../configuration/_exceptions.py | 53 + .../configuration/_logger_provider.py | 386 + .../configuration/_meter_provider.py | 656 + .../configuration/_propagator.py | 102 + .../opentelemetry/configuration/_resource.py | 219 + .../opentelemetry/configuration/_sdk.py | 108 + .../configuration/_tracer_provider.py | 524 + .../configuration/file/__init__.py | 58 + .../configuration/file/_env_substitution.py | 82 + .../configuration/file/_loader.py | 376 + .../configuration/instrumentation.py | 73 + .../opentelemetry/configuration/models.py | 803 + .../opentelemetry/configuration/schema.json | 2576 +++ .../configuration/version/__init__.py | 4 + .../_vendor/opentelemetry/context/__init__.py | 147 + .../_vendor/opentelemetry/context/context.py | 65 + .../context/contextvars_context.py | 43 + .../_vendor/opentelemetry/distro/__init__.py | 32 + .../_vendor/opentelemetry/distro/version.py | 4 + .../environment_variables/__init__.py | 72 + .../exporter/http/transport/__init__.py | 73 + .../exporter/http/transport/_base.py | 91 + .../exporter/http/transport/_requests.py | 118 + .../exporter/http/transport/_urllib3.py | 133 + .../http/transport/version/__init__.py | 4 + .../exporter/otlp/common/__init__.py | 2 + .../exporter/otlp/common/_aggregation.py | 112 + .../exporter/otlp/common/_exporter_metrics.py | 152 + .../exporter/otlp/common/http.py | 248 + .../exporter/otlp/common/version/__init__.py | 4 + .../exporter/otlp/json/common/__init__.py | 2 + .../otlp/json/common/_internal/__init__.py | 98 + .../common/_internal/_log_encoder/__init__.py | 89 + .../_internal/metrics_encoder/__init__.py | 372 + .../_internal/trace_encoder/__init__.py | 159 + .../exporter/otlp/json/common/_log_encoder.py | 8 + .../otlp/json/common/metrics_encoder.py | 8 + .../otlp/json/common/trace_encoder.py | 8 + .../otlp/json/common/version/__init__.py | 4 + .../exporter/otlp/json/file/__init__.py | 73 + .../exporter/otlp/json/file/_internal.py | 80 + .../exporter/otlp/json/file/_log_exporter.py | 70 + .../otlp/json/file/metric_exporter.py | 94 + .../exporter/otlp/json/file/trace_exporter.py | 64 + .../otlp/json/file/version/__init__.py | 4 + .../exporter/otlp/json/http/__init__.py | 79 + .../exporter/otlp/json/http/_internal.py | 137 + .../exporter/otlp/json/http/_log_exporter.py | 134 + .../otlp/json/http/metric_exporter.py | 165 + .../exporter/otlp/json/http/trace_exporter.py | 128 + .../otlp/json/http/version/__init__.py | 4 + .../exporter/otlp/proto/common/__init__.py | 7 + .../otlp/proto/common/_internal/__init__.py | 121 + .../common/_internal/_log_encoder/__init__.py | 87 + .../_internal/metrics_encoder/__init__.py | 348 + .../_internal/trace_encoder/__init__.py | 175 + .../otlp/proto/common/_log_encoder.py | 9 + .../otlp/proto/common/metrics_encoder.py | 9 + .../otlp/proto/common/trace_encoder.py | 9 + .../otlp/proto/common/version/__init__.py | 4 + .../exporter/otlp/proto/http/__init__.py | 75 + .../otlp/proto/http/_common/__init__.py | 211 + .../otlp/proto/http/_log_exporter/__init__.py | 223 + .../proto/http/metric_exporter/__init__.py | 611 + .../proto/http/trace_exporter/__init__.py | 219 + .../http/trace_exporter/encoder/__init__.py | 55 + .../otlp/proto/http/version/__init__.py | 4 + .../exporter/prometheus/__init__.py | 523 + .../exporter/prometheus/_mapping.py | 126 + .../exporter/prometheus/version/__init__.py | 4 + .../instrumentation/_labeler/__init__.py | 88 + .../_labeler/_internal/__init__.py | 250 + .../opentelemetry/instrumentation/_semconv.py | 725 + .../aiohttp_client/__init__.py | 721 + .../instrumentation/aiohttp_client/package.py | 9 + .../instrumentation/aiohttp_client/version.py | 4 + .../auto_instrumentation/__init__.py | 168 + .../auto_instrumentation/_load.py | 153 + .../auto_instrumentation/sitecustomize.py | 6 + .../instrumentation/bootstrap.py | 166 + .../instrumentation/bootstrap_gen.py | 70 + .../opentelemetry/instrumentation/cidict.py | 71 + .../instrumentation/dependencies.py | 209 + .../opentelemetry/instrumentation/distro.py | 59 + .../instrumentation/environment_variables.py | 32 + .../instrumentation/instrumentor.py | 136 + .../instrumentation/log_utils.py | 65 + .../instrumentation/propagators.py | 113 + .../instrumentation/sqlcommenter_utils.py | 92 + .../opentelemetry/instrumentation/utils.py | 214 + .../opentelemetry/instrumentation/version.py | 4 + .../_vendor/opentelemetry/metrics/__init__.py | 121 + .../metrics/_internal/__init__.py | 892 + .../metrics/_internal/instrument.py | 540 + .../metrics/_internal/observation.py | 51 + .../opentelemetry/propagate/__init__.py | 171 + .../opentelemetry/propagators/_envcarrier.py | 94 + .../opentelemetry/propagators/b3/__init__.py | 182 + .../propagators/b3/version/__init__.py | 4 + .../opentelemetry/propagators/composite.py | 78 + .../opentelemetry/propagators/textmap.py | 181 + .../_vendor/opentelemetry/proto/__init__.py | 0 .../opentelemetry/proto/collector/__init__.py | 0 .../collector/logs/v1/logs_service_pb2.py | 34 + .../collector/logs/v1/logs_service_pb2.pyi | 117 + .../proto/collector/metrics/__init__.py | 0 .../proto/collector/metrics/v1/__init__.py | 0 .../metrics/v1/metrics_service_pb2.py | 34 + .../metrics/v1/metrics_service_pb2.pyi | 117 + .../v1development/profiles_service_pb2.py | 34 + .../v1development/profiles_service_pb2.pyi | 123 + .../proto/collector/trace/__init__.py | 0 .../proto/collector/trace/v1/__init__.py | 0 .../collector/trace/v1/trace_service_pb2.py | 34 + .../collector/trace/v1/trace_service_pb2.pyi | 117 + .../opentelemetry/proto/common/__init__.py | 0 .../opentelemetry/proto/common/v1/__init__.py | 0 .../proto/common/v1/common_pb2.py | 37 + .../proto/common/v1/common_pb2.pyi | 280 + .../opentelemetry/proto/logs/v1/logs_pb2.py | 39 + .../opentelemetry/proto/logs/v1/logs_pb2.pyi | 365 + .../opentelemetry/proto/metrics/__init__.py | 0 .../proto/metrics/v1/__init__.py | 0 .../proto/metrics/v1/metrics_pb2.py | 63 + .../proto/metrics/v1/metrics_pb2.pyi | 1177 ++ .../profiles/v1development/profiles_pb2.py | 55 + .../profiles/v1development/profiles_pb2.pyi | 800 + .../opentelemetry/proto/resource/__init__.py | 0 .../proto/resource/v1/__init__.py | 0 .../proto/resource/v1/resource_pb2.py | 28 + .../proto/resource/v1/resource_pb2.pyi | 70 + .../opentelemetry/proto/trace/__init__.py | 0 .../opentelemetry/proto/trace/v1/__init__.py | 0 .../opentelemetry/proto/trace/v1/trace_pb2.py | 47 + .../proto/trace/v1/trace_pb2.pyi | 586 + .../opentelemetry/proto/version/__init__.py | 4 + .../opentelemetry/proto_json/__init__.py | 0 .../opentelemetry/proto_json/_json_codec.py | 250 + .../proto_json/collector/__init__.py | 0 .../proto_json/collector/logs/__init__.py | 0 .../proto_json/collector/logs/v1/__init__.py | 0 .../collector/logs/v1/logs_service.py | 148 + .../proto_json/collector/metrics/__init__.py | 0 .../collector/metrics/v1/__init__.py | 0 .../collector/metrics/v1/metrics_service.py | 148 + .../proto_json/collector/profiles/__init__.py | 0 .../profiles/v1development/__init__.py | 0 .../v1development/profiles_service.py | 153 + .../proto_json/collector/trace/__init__.py | 0 .../proto_json/collector/trace/v1/__init__.py | 0 .../collector/trace/v1/trace_service.py | 148 + .../proto_json/common/__init__.py | 0 .../proto_json/common/v1/__init__.py | 0 .../proto_json/common/v1/common.py | 348 + .../opentelemetry/proto_json/logs/__init__.py | 0 .../proto_json/logs/v1/__init__.py | 0 .../opentelemetry/proto_json/logs/v1/logs.py | 304 + .../proto_json/metrics/__init__.py | 0 .../proto_json/metrics/v1/__init__.py | 0 .../proto_json/metrics/v1/metrics.py | 1000 + .../proto_json/profiles/__init__.py | 0 .../profiles/v1development/__init__.py | 0 .../profiles/v1development/profiles.py | 816 + .../proto_json/resource/__init__.py | 0 .../proto_json/resource/v1/__init__.py | 0 .../proto_json/resource/v1/resource.py | 71 + .../proto_json/trace/__init__.py | 0 .../proto_json/trace/v1/__init__.py | 0 .../proto_json/trace/v1/trace.py | 497 + .../proto_json/version/__init__.py | 4 + .../_vendor/opentelemetry/sdk/__init__.pyi | 18 + .../sdk/_configuration/__init__.py | 676 + .../opentelemetry/sdk/_logs/__init__.py | 32 + .../sdk/_logs/_internal/__init__.py | 1092 + .../sdk/_logs/_internal/_exceptions.py | 114 + .../sdk/_logs/_internal/_logger_metrics.py | 37 + .../sdk/_logs/_internal/export/__init__.py | 392 + .../export/in_memory_log_exporter.py | 53 + .../sdk/_logs/export/__init__.py | 32 + .../sdk/_shared_internal/__init__.py | 237 + .../_shared_internal/_processor_metrics.py | 140 + .../sdk/environment_variables/__init__.py | 863 + .../sdk/environment_variables/_internal.py | 26 + .../sdk/error_handler/__init__.py | 128 + .../opentelemetry/sdk/metrics/__init__.py | 49 + .../sdk/metrics/_internal/__init__.py | 660 + .../_internal/_view_instrument_match.py | 217 + .../sdk/metrics/_internal/aggregation.py | 1354 ++ .../sdk/metrics/_internal/exceptions.py | 6 + .../metrics/_internal/exemplar/__init__.py | 28 + .../metrics/_internal/exemplar/exemplar.py | 33 + .../_internal/exemplar/exemplar_filter.py | 120 + .../_internal/exemplar/exemplar_reservoir.py | 291 + .../exponential_histogram/__init__.py | 0 .../exponential_histogram/buckets.py | 177 + .../exponential_histogram/mapping/__init__.py | 94 + .../exponential_histogram/mapping/errors.py | 15 + .../mapping/exponent_mapping.py | 145 + .../exponential_histogram/mapping/ieee_754.md | 175 + .../exponential_histogram/mapping/ieee_754.py | 106 + .../mapping/logarithm_mapping.py | 123 + .../sdk/metrics/_internal/export/__init__.py | 608 + .../export/_metric_reader_metrics.py | 54 + .../sdk/metrics/_internal/instrument.py | 400 + .../sdk/metrics/_internal/measurement.py | 54 + .../metrics/_internal/measurement_consumer.py | 145 + .../_internal/metric_reader_storage.py | 285 + .../sdk/metrics/_internal/point.py | 240 + .../metrics/_internal/sdk_configuration.py | 20 + .../sdk/metrics/_internal/view.py | 194 + .../sdk/metrics/export/__init__.py | 61 + .../sdk/metrics/view/__init__.py | 24 + .../opentelemetry/sdk/resources/__init__.py | 776 + .../opentelemetry/sdk/trace/__init__.py | 1426 ++ .../trace/_sampling_experimental/__init__.py | 22 + .../_sampling_experimental/_always_off.py | 44 + .../_sampling_experimental/_always_on.py | 44 + .../_sampling_experimental/_composable.py | 49 + .../_parent_threshold.py | 72 + .../_sampling_experimental/_rule_based.py | 271 + .../trace/_sampling_experimental/_sampler.py | 88 + .../_sampling_experimental/_trace_state.py | 121 + .../_sampling_experimental/_traceid_ratio.py | 67 + .../sdk/trace/_sampling_experimental/_util.py | 23 + .../sdk/trace/_tracer_metrics.py | 103 + .../sdk/trace/export/__init__.py | 316 + .../trace/export/in_memory_span_exporter.py | 56 + .../opentelemetry/sdk/trace/id_generator.py | 72 + .../opentelemetry/sdk/trace/sampling.py | 488 + .../opentelemetry/sdk/util/__init__.py | 140 + .../opentelemetry/sdk/util/__init__.pyi | 76 + .../opentelemetry/sdk/util/_configurator.py | 28 + .../opentelemetry/sdk/util/instrumentation.py | 191 + .../opentelemetry/sdk/version/__init__.py | 4 + .../_vendor/opentelemetry/semconv/__init__.py | 0 .../_incubating/attributes/app_attributes.py | 90 + .../attributes/artifact_attributes.py | 51 + .../_incubating/attributes/aws_attributes.py | 316 + .../_incubating/attributes/az_attributes.py | 14 + .../attributes/azure_attributes.py | 76 + .../attributes/browser_attributes.py | 104 + .../attributes/cassandra_attributes.py | 60 + .../_incubating/attributes/cicd_attributes.py | 152 + .../attributes/client_attributes.py | 14 + .../attributes/cloud_attributes.py | 156 + .../attributes/cloudevents_attributes.py | 29 + .../attributes/cloudfoundry_attributes.py | 107 + .../_incubating/attributes/code_attributes.py | 54 + .../attributes/container_attributes.py | 114 + .../_incubating/attributes/cpu_attributes.py | 34 + .../attributes/cpython_attributes.py | 19 + .../_incubating/attributes/db_attributes.py | 574 + .../attributes/deployment_attributes.py | 53 + .../attributes/destination_attributes.py | 15 + .../attributes/device_attributes.py | 43 + .../_incubating/attributes/disk_attributes.py | 17 + .../_incubating/attributes/dns_attributes.py | 15 + .../attributes/elasticsearch_attributes.py | 9 + .../attributes/enduser_attributes.py | 32 + .../attributes/error_attributes.py | 25 + .../attributes/event_attributes.py | 9 + .../attributes/exception_attributes.py | 24 + .../_incubating/attributes/faas_attributes.py | 150 + .../attributes/feature_flag_attributes.py | 119 + .../_incubating/attributes/file_attributes.py | 125 + .../_incubating/attributes/gcp_attributes.py | 234 + .../attributes/gen_ai_attributes.py | 459 + .../_incubating/attributes/geo_attributes.py | 57 + .../attributes/graphql_attributes.py | 30 + .../attributes/heroku_attributes.py | 19 + .../_incubating/attributes/host_attributes.py | 102 + .../_incubating/attributes/http_attributes.py | 190 + .../_incubating/attributes/hw_attributes.py | 243 + .../attributes/jsonrpc_attributes.py | 16 + .../_incubating/attributes/k8s_attributes.py | 721 + .../attributes/linux_attributes.py | 20 + .../_incubating/attributes/log_attributes.py | 50 + .../attributes/mainframe_attributes.py | 9 + .../_incubating/attributes/mcp_attributes.py | 83 + .../attributes/message_attributes.py | 35 + .../attributes/messaging_attributes.py | 327 + .../_incubating/attributes/net_attributes.py | 106 + .../attributes/network_attributes.py | 209 + .../_incubating/attributes/nfs_attributes.py | 14 + .../_incubating/attributes/oci_attributes.py | 11 + .../attributes/onc_rpc_attributes.py | 24 + .../attributes/openai_attributes.py | 47 + .../attributes/openshift_attributes.py | 14 + .../attributes/opentracing_attributes.py | 18 + .../attributes/oracle_attributes.py | 47 + .../attributes/oracle_cloud_attributes.py | 10 + .../_incubating/attributes/os_attributes.py | 57 + .../_incubating/attributes/otel_attributes.py | 145 + .../attributes/other_attributes.py | 20 + .../_incubating/attributes/peer_attributes.py | 9 + .../_incubating/attributes/pool_attributes.py | 9 + .../attributes/pprof_attributes.py | 62 + .../attributes/process_attributes.py | 253 + .../attributes/profile_attributes.py | 39 + .../_incubating/attributes/rpc_attributes.py | 264 + .../attributes/security_rule_attributes.py | 45 + .../attributes/server_attributes.py | 14 + .../attributes/service_attributes.py | 52 + .../attributes/session_attributes.py | 14 + .../attributes/source_attributes.py | 15 + .../attributes/system_attributes.py | 242 + .../attributes/telemetry_attributes.py | 64 + .../_incubating/attributes/test_attributes.py | 47 + .../attributes/thread_attributes.py | 33 + .../_incubating/attributes/tls_attributes.py | 158 + .../_incubating/attributes/url_attributes.py | 76 + .../attributes/user_agent_attributes.py | 47 + .../_incubating/attributes/user_attributes.py | 35 + .../_incubating/attributes/vcs_attributes.py | 218 + .../attributes/webengine_attributes.py | 19 + .../_incubating/attributes/zos_attributes.py | 14 + .../_incubating/metrics/azure_metrics.py | 40 + .../_incubating/metrics/cicd_metrics.py | 94 + .../_incubating/metrics/container_metrics.py | 281 + .../_incubating/metrics/cpu_metrics.py | 58 + .../_incubating/metrics/cpython_metrics.py | 60 + .../semconv/_incubating/metrics/db_metrics.py | 356 + .../_incubating/metrics/dns_metrics.py | 23 + .../_incubating/metrics/faas_metrics.py | 159 + .../_incubating/metrics/gen_ai_metrics.py | 111 + .../_incubating/metrics/http_metrics.py | 176 + .../semconv/_incubating/metrics/hw_metrics.py | 755 + .../_incubating/metrics/k8s_metrics.py | 2952 +++ .../_incubating/metrics/mcp_metrics.py | 66 + .../_incubating/metrics/messaging_metrics.py | 169 + .../_incubating/metrics/nfs_metrics.py | 290 + .../_incubating/metrics/openshift_metrics.py | 442 + .../_incubating/metrics/otel_metrics.py | 443 + .../_incubating/metrics/process_metrics.py | 286 + .../_incubating/metrics/rpc_metrics.py | 194 + .../_incubating/metrics/system_metrics.py | 835 + .../_incubating/metrics/vcs_metrics.py | 193 + .../semconv/attributes/__init__.py | 0 .../semconv/attributes/client_attributes.py | 16 + .../semconv/attributes/code_attributes.py | 44 + .../attributes/container_attributes.py | 25 + .../semconv/attributes/db_attributes.py | 134 + .../attributes/deployment_attributes.py | 28 + .../semconv/attributes/error_attributes.py | 40 + .../attributes/exception_attributes.py | 32 + .../semconv/attributes/http_attributes.py | 127 + .../semconv/attributes/k8s_attributes.py | 362 + .../semconv/attributes/network_attributes.py | 73 + .../semconv/attributes/otel_attributes.py | 38 + .../semconv/attributes/server_attributes.py | 16 + .../semconv/attributes/service_attributes.py | 53 + .../attributes/telemetry_attributes.py | 67 + .../semconv/attributes/url_attributes.py | 88 + .../attributes/user_agent_attributes.py | 9 + .../opentelemetry/semconv/metrics/__init__.py | 191 + .../semconv/metrics/db_metrics.py | 13 + .../semconv/metrics/http_metrics.py | 20 + .../semconv/resource/__init__.py | 875 + .../_vendor/opentelemetry/semconv/schemas.py | 118 + .../opentelemetry/semconv/trace/__init__.py | 2164 ++ .../opentelemetry/semconv/version/__init__.py | 4 + .../_vendor/opentelemetry/trace/__init__.py | 661 + .../trace/propagation/__init__.py | 37 + .../trace/propagation/tracecontext.py | 126 + .../agent/_vendor/opentelemetry/trace/span.py | 616 + .../_vendor/opentelemetry/trace/status.py | 68 + .../_vendor/opentelemetry/util/_decorator.py | 75 + .../opentelemetry/util/_importlib_metadata.py | 58 + .../agent/_vendor/opentelemetry/util/_once.py | 36 + .../_vendor/opentelemetry/util/_providers.py | 42 + .../opentelemetry/util/http/__init__.py | 351 + .../opentelemetry/util/http/constants.py | 23 + .../opentelemetry/util/http/httplib.py | 186 + .../opentelemetry/util/http/version.py | 4 + .../agent/_vendor/opentelemetry/util/re.py | 93 + .../agent/_vendor/opentelemetry/util/types.py | 28 + .../_vendor/opentelemetry/version/__init__.py | 4 + .../agent/_vendor/packaging.LICENSE | 3 + .../agent/_vendor/packaging.LICENSE.APACHE | 177 + .../agent/_vendor/packaging.LICENSE.BSD | 23 + .../agent/_vendor/packaging/__init__.py | 15 + .../agent/_vendor/packaging/_elffile.py | 108 + .../agent/_vendor/packaging/_manylinux.py | 278 + .../agent/_vendor/packaging/_musllinux.py | 88 + .../agent/_vendor/packaging/_parser.py | 418 + .../agent/_vendor/packaging/_ranges.py | 836 + .../agent/_vendor/packaging/_structures.py | 33 + .../agent/_vendor/packaging/_tokenizer.py | 200 + .../_vendor/packaging/dependency_groups.py | 335 + .../agent/_vendor/packaging/direct_url.py | 349 + .../agent/_vendor/packaging/errors.py | 94 + .../_vendor/packaging/licenses/__init__.py | 198 + .../agent/_vendor/packaging/licenses/_spdx.py | 799 + .../agent/_vendor/packaging/markers.py | 576 + .../agent/_vendor/packaging/metadata.py | 1054 + .../agent/_vendor/packaging/pylock.py | 943 + .../agent/_vendor/packaging/ranges.py | 2067 ++ .../agent/_vendor/packaging/requirements.py | 192 + .../agent/_vendor/packaging/specifiers.py | 1457 ++ .../agent/_vendor/packaging/tags.py | 1053 + .../agent/_vendor/packaging/utils.py | 370 + .../agent/_vendor/packaging/version.py | 1252 ++ .../agent/_vendor/prometheus-client.LICENSE | 201 + .../agent/_vendor/prometheus-client.NOTICE | 5 + .../_vendor/prometheus_client/__init__.py | 75 + .../agent/_vendor/prometheus_client/asgi.py | 40 + .../prometheus_client/bridge/__init__.py | 0 .../prometheus_client/bridge/graphite.py | 94 + .../prometheus_client/context_managers.py | 83 + .../agent/_vendor/prometheus_client/core.py | 35 + .../_vendor/prometheus_client/decorator.py | 427 + .../_vendor/prometheus_client/exposition.py | 828 + .../_vendor/prometheus_client/gc_collector.py | 45 + .../_vendor/prometheus_client/metrics.py | 804 + .../_vendor/prometheus_client/metrics_core.py | 415 + .../_vendor/prometheus_client/mmap_dict.py | 145 + .../_vendor/prometheus_client/multiprocess.py | 183 + .../prometheus_client/openmetrics/__init__.py | 0 .../openmetrics/exposition.py | 287 + .../prometheus_client/openmetrics/parser.py | 653 + .../agent/_vendor/prometheus_client/parser.py | 370 + .../prometheus_client/platform_collector.py | 59 + .../prometheus_client/process_collector.py | 101 + .../_vendor/prometheus_client/registry.py | 178 + .../_vendor/prometheus_client/samples.py | 74 + .../agent/_vendor/prometheus_client/utils.py | 36 + .../_vendor/prometheus_client/validation.py | 124 + .../agent/_vendor/prometheus_client/values.py | 163 + .../agent/_vendor/protobuf.LICENSE | 32 + .../agent/_vendor/requests.LICENSE | 175 + .../agent/_vendor/requests.NOTICE | 2 + .../agent/_vendor/requests/__init__.py | 217 + .../agent/_vendor/requests/__version__.py | 14 + .../agent/_vendor/requests/_internal_utils.py | 51 + .../agent/_vendor/requests/_types.py | 183 + .../agent/_vendor/requests/adapters.py | 748 + .../agent/_vendor/requests/api.py | 180 + .../agent/_vendor/requests/auth.py | 354 + .../agent/_vendor/requests/certs.py | 18 + .../agent/_vendor/requests/compat.py | 102 + .../agent/_vendor/requests/cookies.py | 625 + .../agent/_vendor/requests/exceptions.py | 162 + .../agent/_vendor/requests/hooks.py | 48 + .../agent/_vendor/requests/models.py | 1180 ++ .../agent/_vendor/requests/packages.py | 4 + .../agent/_vendor/requests/sessions.py | 920 + .../agent/_vendor/requests/status_codes.py | 128 + .../agent/_vendor/requests/structures.py | 130 + .../agent/_vendor/requests/utils.py | 1155 ++ .../agent/_vendor/requirements.txt | 268 +- .../agent/_vendor/ruamel-yaml.LICENSE | 21 + .../agent/_vendor/ruamel/yaml/__init__.py | 51 + .../agent/_vendor/ruamel/yaml/anchor.py | 20 + .../agent/_vendor/ruamel/yaml/comments.py | 1208 ++ .../agent/_vendor/ruamel/yaml/compat.py | 236 + .../agent/_vendor/ruamel/yaml/composer.py | 246 + .../_vendor/ruamel/yaml/configobjwalker.py | 17 + .../agent/_vendor/ruamel/yaml/constructor.py | 1724 ++ .../agent/_vendor/ruamel/yaml/docinfo.py | 130 + .../agent/_vendor/ruamel/yaml/dumper.py | 220 + .../agent/_vendor/ruamel/yaml/emitter.py | 1802 ++ .../agent/_vendor/ruamel/yaml/error.py | 328 + .../agent/_vendor/ruamel/yaml/events.py | 266 + .../agent/_vendor/ruamel/yaml/loader.py | 92 + .../agent/_vendor/ruamel/yaml/main.py | 1519 ++ .../agent/_vendor/ruamel/yaml/mergevalue.py | 39 + .../agent/_vendor/ruamel/yaml/nodes.py | 149 + .../agent/_vendor/ruamel/yaml/parser.py | 862 + .../agent/_vendor/ruamel/yaml/reader.py | 277 + .../agent/_vendor/ruamel/yaml/representer.py | 1139 + .../agent/_vendor/ruamel/yaml/resolver.py | 392 + .../agent/_vendor/ruamel/yaml/scalarbool.py | 43 + .../agent/_vendor/ruamel/yaml/scalarfloat.py | 105 + .../agent/_vendor/ruamel/yaml/scalarint.py | 124 + .../agent/_vendor/ruamel/yaml/scalarstring.py | 142 + .../agent/_vendor/ruamel/yaml/scanner.py | 2390 +++ .../agent/_vendor/ruamel/yaml/serializer.py | 233 + .../agent/_vendor/ruamel/yaml/tag.py | 126 + .../agent/_vendor/ruamel/yaml/timestamp.py | 63 + .../agent/_vendor/ruamel/yaml/tokens.py | 384 + .../agent/_vendor/ruamel/yaml/util.py | 264 + .../agent/_vendor/typing-extensions.LICENSE | 279 + .../agent/_vendor/typing_extensions.py | 4422 ++++ .../agent/_vendor/urllib3.LICENSE.txt | 21 + .../agent/_vendor/urllib3/__init__.py | 211 + .../agent/_vendor/urllib3/_base_connection.py | 167 + .../agent/_vendor/urllib3/_collections.py | 490 + .../agent/_vendor/urllib3/_request_methods.py | 278 + .../agent/_vendor/urllib3/_version.py | 24 + .../agent/_vendor/urllib3/connection.py | 1204 ++ .../agent/_vendor/urllib3/connectionpool.py | 1211 ++ .../agent/_vendor/urllib3/contrib/__init__.py | 0 .../agent/_vendor/urllib3/exceptions.py | 335 + .../agent/_vendor/urllib3/fields.py | 341 + .../agent/_vendor/urllib3/filepost.py | 89 + .../agent/_vendor/urllib3/http2/__init__.py | 53 + .../agent/_vendor/urllib3/http2/probe.py | 87 + .../agent/_vendor/urllib3/poolmanager.py | 677 + .../agent/_vendor/urllib3/response.py | 1526 ++ .../agent/_vendor/urllib3/util/__init__.py | 42 + .../agent/_vendor/urllib3/util/connection.py | 137 + .../agent/_vendor/urllib3/util/proxy.py | 43 + .../agent/_vendor/urllib3/util/request.py | 299 + .../agent/_vendor/urllib3/util/response.py | 101 + .../agent/_vendor/urllib3/util/retry.py | 569 + .../agent/_vendor/urllib3/util/ssl_.py | 481 + .../urllib3/util/ssl_match_hostname.py | 153 + .../_vendor/urllib3/util/ssltransport.py | 271 + .../agent/_vendor/urllib3/util/timeout.py | 275 + .../agent/_vendor/urllib3/util/url.py | 577 + .../agent/_vendor/urllib3/util/util.py | 42 + .../agent/_vendor/urllib3/util/wait.py | 124 + .../agent/_vendor/wrapt-stubs/__init__.pyi | 841 + .../opentelemetry/agent/_vendor/wrapt.LICENSE | 24 + .../agent/_vendor/wrapt/__init__.py | 130 + .../agent/_vendor/wrapt/__wrapt__.py | 42 + .../agent/_vendor/wrapt/_wrappers.c | 5892 ++++++ .../agent/_vendor/wrapt/arguments.py | 55 + .../agent/_vendor/wrapt/caching.py | 234 + .../agent/_vendor/wrapt/decorators.py | 488 + .../opentelemetry/agent/_vendor/wrapt/doc.py | 128 + .../agent/_vendor/wrapt/exceptions.py | 69 + .../agent/_vendor/wrapt/importer.py | 314 + .../agent/_vendor/wrapt/patches.py | 851 + .../agent/_vendor/wrapt/proxies.py | 386 + .../agent/_vendor/wrapt/signature.py | 270 + .../agent/_vendor/wrapt/synchronization.py | 540 + .../agent/_vendor/wrapt/weakrefs.py | 170 + .../agent/_vendor/wrapt/wrappers.py | 1287 ++ .../tests/test_hatch_build.py | 63 + .../tests/test_vendored_otel.py | 148 + agent/opentelemetry-agent/vendor-excludes.txt | 5 + agent/opentelemetry-agent/vendor.in | 22 + agent/opentelemetry-vendor/README.rst | 52 +- .../src/opentelemetry/vendor/checks.py | 147 +- .../src/opentelemetry/vendor/cli.py | 22 + .../src/opentelemetry/vendor/config.py | 47 +- .../src/opentelemetry/vendor/download.py | 36 + .../src/opentelemetry/vendor/entry_points.py | 110 + .../src/opentelemetry/vendor/metadata.py | 26 +- .../src/opentelemetry/vendor/native.py | 265 + .../src/opentelemetry/vendor/rewrite.py | 42 +- .../src/opentelemetry/vendor/sbom.py | 62 +- .../src/opentelemetry/vendor/sync.py | 28 +- agent/opentelemetry-vendor/tests/helpers.py | 6 +- .../opentelemetry-vendor/tests/test_checks.py | 104 +- agent/opentelemetry-vendor/tests/test_cli.py | 64 + .../opentelemetry-vendor/tests/test_config.py | 78 + .../tests/test_entry_points.py | 152 + .../tests/test_metadata.py | 29 + .../opentelemetry-vendor/tests/test_native.py | 234 + .../tests/test_rewrite.py | 78 +- 919 files changed, 210759 insertions(+), 100 deletions(-) create mode 100644 agent/opentelemetry-agent/hatch_build.py create mode 100644 agent/opentelemetry-agent/native-build-requirements.in create mode 100644 agent/opentelemetry-agent/native-build-requirements.txt create mode 100644 agent/opentelemetry-agent/patches/native/protobuf-upb.patch create mode 100644 agent/opentelemetry-agent/patches/otel-configuration-loader.patch create mode 100644 agent/opentelemetry-agent/patches/otel-distro-http-protocol.patch create mode 100644 agent/opentelemetry-agent/patches/otel-importlib-metadata.patch create mode 100644 agent/opentelemetry-agent/patches/otel-sdk-vendored-names.patch rename agent/opentelemetry-agent/patches/{protobuf-pure-python.patch => protobuf-implementation.patch} (74%) create mode 100644 agent/opentelemetry-agent/patches/ruamel-yaml-pure.patch create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/enum_type_wrapper.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/util/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/contrib/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py create mode 100644 agent/opentelemetry-agent/tests/test_hatch_build.py create mode 100644 agent/opentelemetry-agent/tests/test_vendored_otel.py create mode 100644 agent/opentelemetry-agent/vendor-excludes.txt create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/entry_points.py create mode 100644 agent/opentelemetry-vendor/src/opentelemetry/vendor/native.py create mode 100644 agent/opentelemetry-vendor/tests/test_entry_points.py create mode 100644 agent/opentelemetry-vendor/tests/test_native.py diff --git a/.gitignore b/.gitignore index 6c3e08c1176..421d7b34af0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # C extensions *.so +*.pyd # Packages *.egg diff --git a/agent/opentelemetry-agent/README.rst b/agent/opentelemetry-agent/README.rst index e69de29bb2d..e118657a81a 100644 --- a/agent/opentelemetry-agent/README.rst +++ b/agent/opentelemetry-agent/README.rst @@ -0,0 +1,29 @@ +OpenTelemetry Python Agent +========================== + +A self-contained OpenTelemetry distribution: the API, SDK, exporters, the auto-instrumentation framework +and instrumentations, with all their dependencies vendored under ``opentelemetry.agent._vendor``. It can be +installed into any Python 3.10+ environment without affecting (or being affected by) the application's own +packages. + +Usage +----- + +:: + + pip install opentelemetry-agent + opentelemetry-instrument python app.py + +``opentelemetry-instrument`` takes the same options and ``OTEL_*`` environment variables as the one from +``opentelemetry-instrumentation``. The ``otlp`` exporter uses ``http/protobuf``: the gRPC exporters aren't +included. + +Isolation +--------- + +* Only the vendored plugins (exporters, propagators, samplers, resource detectors) and instrumentations are + discovered; OpenTelemetry packages installed in the application's environment aren't used. +* The application's own ``opentelemetry-api`` (if any) is a separate copy: spans and metrics it records + don't reach the agent's providers. +* ``opentelemetry-instrumentation`` installs an ``opentelemetry-instrument`` script as well; when both are + installed, the package installed last owns it. diff --git a/agent/opentelemetry-agent/hatch_build.py b/agent/opentelemetry-agent/hatch_build.py new file mode 100644 index 00000000000..8ad3c50c359 --- /dev/null +++ b/agent/opentelemetry-agent/hatch_build.py @@ -0,0 +1,45 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Tag the wheel as platform-specific when native extensions were built into the vendor tree. + +`opentelemetry-vendor build-native` (run before the wheel build) compiles stable-ABI (abi3) +extensions into ``_vendor``. Without them, the wheel is pure Python (``py3-none-any``). +""" + +from __future__ import annotations + +import sysconfig +from pathlib import Path +from typing import Any + +from hatchling.builders.hooks.plugin.interface import BuildHookInterface + +VENDOR_DIR = Path("src/opentelemetry/agent/_vendor") +EXTENSION_SUFFIXES = (".so", ".pyd") + + +class CustomBuildHook(BuildHookInterface): + def initialize(self, version: str, build_data: dict[str, Any]) -> None: + if self.target_name != "wheel": + return + root = Path(self.root) + extensions = sorted( + path.relative_to(root).as_posix() + for path in (root / VENDOR_DIR).rglob("*") + if path.is_file() and path.name.endswith(EXTENSION_SUFFIXES) + ) + if not extensions: + return + not_abi3 = [path for path in extensions if not (".abi3." in path or path.endswith(".pyd"))] + if not_abi3: + raise ValueError(f"vendored extensions must use the stable ABI (abi3): {not_abi3}") + abi3_tag = self.config.get("abi3-tag", "cp310") + # Same platform tag as setuptools' bdist_wheel: the interpreter's deployment target (e.g. + # macosx_11_0_arm64), not the build machine's OS version. Linux tags (linux_x86_64) are + # meant to be repaired to manylinux/musllinux by auditwheel (cibuildwheel). + platform = sysconfig.get_platform().replace("-", "_").replace(".", "_") + build_data["pure_python"] = False + build_data["tag"] = f"{abi3_tag}-abi3-{platform}" + # Compiled extensions are gitignored, which hatch would otherwise exclude. + build_data["artifacts"].extend(extensions) diff --git a/agent/opentelemetry-agent/native-build-requirements.in b/agent/opentelemetry-agent/native-build-requirements.in new file mode 100644 index 00000000000..797312dee0c --- /dev/null +++ b/agent/opentelemetry-agent/native-build-requirements.in @@ -0,0 +1,2 @@ +# Build-time requirements of the native extensions (see [tool.opentelemetry-vendor.native]). +setuptools diff --git a/agent/opentelemetry-agent/native-build-requirements.txt b/agent/opentelemetry-agent/native-build-requirements.txt new file mode 100644 index 00000000000..3f5c5f29d38 --- /dev/null +++ b/agent/opentelemetry-agent/native-build-requirements.txt @@ -0,0 +1,6 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --python 3.10 --universal --generate-hashes native-build-requirements.in -o native-build-requirements.txt +setuptools==84.2.1 \ + --hash=sha256:3ff8b3b5492a0aa66960f4419365a86b84e013070d4313e4d4a6894f5d64d6bc \ + --hash=sha256:ca140b45d5325a9478f880e351484f62fef15f336462e449ca0c03c873d589c2 + # via -r native-build-requirements.in diff --git a/agent/opentelemetry-agent/patches/native/protobuf-upb.patch b/agent/opentelemetry-agent/patches/native/protobuf-upb.patch new file mode 100644 index 00000000000..491f4ff1332 --- /dev/null +++ b/agent/opentelemetry-agent/patches/native/protobuf-upb.patch @@ -0,0 +1,53 @@ +Build protobuf's upb extension under the agent's vendor namespace, as abi3. + +The extension's module name, its type names (their __module__) and the Python modules it imports by +absolute name all come from the PYUPB_* macros in python/protobuf.h; they are moved under +opentelemetry.agent._vendor so the vendored extension never imports (or poses as) the application's +protobuf. PYUPB_DESCRIPTOR_PROTO_PACKAGE is a protobuf package name (google.protobuf.FileDescriptorProto, +...), not a Python module, and stays. setup.py builds the extension under the new name with the limited +API (cp310-abi3), like upstream's Bazel-built wheels. + +diff --git a/python/protobuf.h b/python/protobuf.h +--- a/python/protobuf.h ++++ b/python/protobuf.h +@@ -22,12 +22,12 @@ + #include "upb/mem/arena.h" + #include "upb/reflection/def.h" + +-#define PYUPB_PROTOBUF_PUBLIC_PACKAGE "google.protobuf" +-#define PYUPB_PROTOBUF_INTERNAL_PACKAGE "google.protobuf.internal" ++#define PYUPB_PROTOBUF_PUBLIC_PACKAGE "opentelemetry.agent._vendor.google.protobuf" ++#define PYUPB_PROTOBUF_INTERNAL_PACKAGE "opentelemetry.agent._vendor.google.protobuf.internal" + #define PYUPB_DESCRIPTOR_PROTO_PACKAGE "google.protobuf" +-#define PYUPB_MODULE_NAME "google._upb._message" ++#define PYUPB_MODULE_NAME "opentelemetry.agent._vendor.google._upb._message" + +-#define PYUPB_DESCRIPTOR_MODULE "google.protobuf.descriptor_pb2" ++#define PYUPB_DESCRIPTOR_MODULE "opentelemetry.agent._vendor.google.protobuf.descriptor_pb2" + #define PYUPB_RETURN_OOM return PyErr_SetNone(PyExc_MemoryError), NULL + + struct PyUpb_WeakMap; +diff --git a/setup.py b/setup.py +--- a/setup.py ++++ b/setup.py +@@ -84,13 +84,19 @@ setup( + install_requires=[], + ext_modules=[ + Extension( +- 'google._upb._message', ++ # Vendored by opentelemetry-agent under its private namespace. ++ 'opentelemetry.agent._vendor.google._upb._message', + srcs, + include_dirs=[current_dir, os.path.join(current_dir, 'utf8_range')], + language='c', + extra_link_args=extra_link_args, + extra_compile_args=extra_compile_args, ++ # One stable-ABI build for CPython 3.10+, like upstream's abi3 wheels. It ++ # must be compiled against Python 3.10 headers. ++ define_macros=[('Py_LIMITED_API', '0x030A0000')], ++ py_limited_api=True, + ) + ], ++ options={'bdist_wheel': {'py_limited_api': 'cp310'}}, + python_requires='>=3.10', + ) diff --git a/agent/opentelemetry-agent/patches/otel-configuration-loader.patch b/agent/opentelemetry-agent/patches/otel-configuration-loader.patch new file mode 100644 index 00000000000..14ac9f19dc0 --- /dev/null +++ b/agent/opentelemetry-agent/patches/otel-configuration-loader.patch @@ -0,0 +1,190 @@ +Parse and validate configuration files with ruamel.yaml and fastjsonschema. + +opentelemetry-configuration uses pyyaml and jsonschema, which have no pure-Python wheels (jsonschema needs +rpds-py), so they are excluded (vendor-excludes.txt) and the vendored, pure-Python ruamel.yaml and +fastjsonschema stand in for them: + +* YAML: ruamel.yaml's PyYAML-style SafeLoader (with the same Node classes, resolve() and + construct_document()). It resolves scalars with the YAML 1.2 core schema, which the configuration + spec requires (PyYAML implements YAML 1.1, where e.g. "on" and "no" are booleans). +* Schema: a fastjsonschema validator compiled once. Its draft 2019-09 generator, used for the 2020-12 + $schema, covers every keyword the schema uses ($ref into $defs, oneOf, exclusiveMinimum, ...). + Errors map to the same ConfigurationError messages. + +The schema is also read relative to this file rather than with importlib.resources.files( +"opentelemetry.configuration"), which would resolve the application's package. + +diff --git a/opentelemetry/configuration/file/_loader.py b/opentelemetry/configuration/file/_loader.py +index dfa0037..44029a9 100644 +--- a/opentelemetry/configuration/file/_loader.py ++++ b/opentelemetry/configuration/file/_loader.py +@@ -3,7 +3,6 @@ + + """Configuration file loading and parsing.""" + +-import importlib.resources + import json + import logging + import os +@@ -14,32 +13,23 @@ from typing import Any + from opentelemetry.agent._vendor.opentelemetry.configuration._conversion import _dict_to_dataclass + from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( + ConfigurationError, +- MissingDependencyError, + ) + from opentelemetry.agent._vendor.opentelemetry.configuration.file._env_substitution import ( + substitute_env_vars, + ) + from opentelemetry.agent._vendor.opentelemetry.configuration.models import OpenTelemetryConfiguration + +-try: +- import yaml +-except ImportError as exc: +- raise MissingDependencyError( +- package="pyyaml", +- feature="File configuration", +- install_name="opentelemetry-sdk", +- extras="file-configuration", +- ) from exc +- +-try: +- import jsonschema +-except ImportError as exc: +- raise MissingDependencyError( +- package="jsonschema", +- feature="File configuration", +- install_name="opentelemetry-sdk", +- extras="file-configuration", +- ) from exc ++# opentelemetry-agent: pyyaml and jsonschema have no pure-Python wheels (jsonschema needs rpds-py), ++# so the vendored ruamel.yaml (its pure-Python, PyYAML-style loader API) and fastjsonschema stand in. ++from opentelemetry.agent._vendor import fastjsonschema ++from opentelemetry.agent._vendor.ruamel.yaml import nodes as _yaml_nodes ++from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError ++from opentelemetry.agent._vendor.ruamel.yaml.loader import SafeLoader as _RuamelSafeLoader ++ ++ ++class SafeLoader(_RuamelSafeLoader): ++ # Only ruamel.yaml's YAML class sets the composer's nesting limit; 0 means none, like PyYAML. ++ max_depth = 0 + + # Schema version vendored in schema.json. ``file_format`` values are accepted + # per the configuration spec's versioning rules: the major version must match, +@@ -50,15 +40,24 @@ _SUPPORTED_SCHEMA_MAJOR = 1 + _SUPPORTED_SCHEMA_MINOR = 1 + + _schema_cache: list[dict] = [] ++_validator_cache: list[Any] = [] + + + def _get_schema() -> dict: + if not _schema_cache: +- schema_path = importlib.resources.files("opentelemetry.configuration") / "schema.json" ++ # opentelemetry-agent: resolve the schema relative to this (vendored) package, not by name. ++ schema_path = Path(__file__).resolve().parent.parent / "schema.json" + _schema_cache.append(json.loads(schema_path.read_text(encoding="utf-8"))) + return _schema_cache[0] + + ++def _get_validator() -> Any: ++ # Compiling the schema generates and executes Python code; do it once. ++ if not _validator_cache: ++ _validator_cache.append(fastjsonschema.compile(_get_schema())) ++ return _validator_cache[0] ++ ++ + _logger = logging.getLogger(__name__) + + _YAML_STR_TAG = "tag:yaml.org,2002:str" +@@ -73,8 +72,8 @@ _STANDALONE_ENV_REF = re.compile(r"\A\$\{[A-Za-z_][A-Za-z0-9_]*(?::-[^}]*)?\}\Z" + + + def _substitute_env_in_yaml_node( +- node: yaml.Node, +- loader: yaml.SafeLoader, ++ node: _yaml_nodes.Node, ++ loader: SafeLoader, + visited: set[int] | None = None, + ): + """Apply env-var substitution to string configuration values in a node tree. +@@ -120,7 +119,7 @@ def _substitute_env_in_yaml_node( + # The parser hands this function the value node of attribute_count_limit, + # which has value="${LIMIT}", tag=str, style=None (plain/unquoted). Then: + # +- # 1. isinstance(node, yaml.ScalarNode) -> True: it is a leaf value. ++ # 1. isinstance(node, ScalarNode) -> True: it is a leaf value. + # 2. node.tag == _YAML_STR_TAG -> True: "${LIMIT}" is not a number or + # bool, so the parser tagged it str. We substitute in place, giving + # node.value = "100". +@@ -131,7 +130,7 @@ def _substitute_env_in_yaml_node( + # + # Counter-cases that reach check 3 but stop there: "${LIMIT}" quoted fails + # the style test; x${LIMIT} fails the regex. Both keep the str tag. +- if isinstance(node, yaml.ScalarNode): ++ if isinstance(node, _yaml_nodes.ScalarNode): + # A ``ScalarNode`` is a leaf -- one configuration value. Only a + # ``str``-tagged one can hold a ``${VAR}`` reference (nodes the parser + # already typed as int, float, bool or null cannot), so those are the +@@ -153,12 +152,12 @@ def _substitute_env_in_yaml_node( + # str) YAML would assign to ``node.value``; the ``(True, False)`` + # implicit-flag pair marks it as a plain scalar so that + # type-guessing applies, exactly as during normal parsing. +- node.tag = loader.resolve(yaml.ScalarNode, node.value, (True, False)) +- elif isinstance(node, yaml.SequenceNode): ++ node.tag = loader.resolve(_yaml_nodes.ScalarNode, node.value, (True, False)) ++ elif isinstance(node, _yaml_nodes.SequenceNode): + # A sequence (list): each item is itself a value node -- recurse. + for item in node.value: + _substitute_env_in_yaml_node(item, loader, visited) +- elif isinstance(node, yaml.MappingNode): ++ elif isinstance(node, _yaml_nodes.MappingNode): + # A mapping (dict): recurse into values only; keys are not + # substitution candidates per the spec. A merge key (``<<: *base``) + # appears here as an ordinary pair whose value node is the anchored +@@ -197,7 +196,8 @@ def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLik + try: + if suffix == ".json": + return _substitute_env_in_json_value(json.loads(content)) +- yaml_loader = yaml.SafeLoader(content) ++ # YAML 1.2 core schema, as the configuration spec requires (PyYAML implements YAML 1.1). ++ yaml_loader = SafeLoader(content) + try: + root_node = yaml_loader.get_single_node() + if root_node is None: +@@ -206,7 +206,7 @@ def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLik + return yaml_loader.construct_document(root_node) + finally: + yaml_loader.dispose() +- except yaml.YAMLError as exc: ++ except YAMLError as exc: + _logger.exception("Failed to parse YAML from %s", file_path) + raise ConfigurationError(f"Failed to parse YAML: {exc}") from exc + except json.JSONDecodeError as exc: +@@ -294,19 +294,17 @@ def _validate_schema(data: dict) -> None: + ConfigurationError: If the data does not conform to the schema. + """ + try: +- jsonschema.validate( +- instance=data, +- schema=_get_schema(), +- cls=jsonschema.Draft202012Validator, +- ) +- except jsonschema.ValidationError as exc: ++ _get_validator()(data) ++ except fastjsonschema.JsonSchemaValueException as exc: ++ # The path starts with the root's name ("data"). ++ path = exc.path[1:] + raise ConfigurationError( +- f"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in exc.absolute_path)})" +- if exc.absolute_path ++ f"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in path)})" ++ if path + else f"Configuration does not match schema: {exc.message}" + ) from exc +- except jsonschema.SchemaError as exc: +- raise ConfigurationError(f"Invalid configuration schema: {exc.message}") from exc ++ except fastjsonschema.JsonSchemaDefinitionException as exc: ++ raise ConfigurationError(f"Invalid configuration schema: {exc}") from exc + + + def _validate_file_format(data: dict) -> None: diff --git a/agent/opentelemetry-agent/patches/otel-distro-http-protocol.patch b/agent/opentelemetry-agent/patches/otel-distro-http-protocol.patch new file mode 100644 index 00000000000..765b4a46a0e --- /dev/null +++ b/agent/opentelemetry-agent/patches/otel-distro-http-protocol.patch @@ -0,0 +1,17 @@ +Default the distro's OTLP protocol to http/protobuf. + +The distro defaults OTEL_EXPORTER_OTLP_PROTOCOL to grpc, but the gRPC exporters aren't vendored +(grpcio has no pure-Python wheel). With http/protobuf the SDK resolves the "otlp" exporter to the +vendored otlp_proto_http one. An explicitly set OTEL_EXPORTER_OTLP_PROTOCOL still wins. + +diff --git a/opentelemetry/distro/__init__.py b/opentelemetry/distro/__init__.py +index 4d00198..6165e7a 100644 +--- a/opentelemetry/distro/__init__.py ++++ b/opentelemetry/distro/__init__.py +@@ -28,4 +28,5 @@ class OpenTelemetryDistro(BaseDistro): + os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp") + os.environ.setdefault(OTEL_METRICS_EXPORTER, "otlp") + os.environ.setdefault(OTEL_LOGS_EXPORTER, "otlp") +- os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, "grpc") ++ # opentelemetry-agent: the gRPC exporters aren't vendored (grpcio has no pure-Python wheel). ++ os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, "http/protobuf") diff --git a/agent/opentelemetry-agent/patches/otel-importlib-metadata.patch b/agent/opentelemetry-agent/patches/otel-importlib-metadata.patch new file mode 100644 index 00000000000..5019da80e26 --- /dev/null +++ b/agent/opentelemetry-agent/patches/otel-importlib-metadata.patch @@ -0,0 +1,69 @@ +Scope OpenTelemetry's entry point lookups to the vendored distributions. + +All OpenTelemetry plugin discovery (distro, configurator, instrumentors, exporters, samplers, +propagators, resource detectors, HTTP transports) goes through opentelemetry.util._importlib_metadata. +Upstream it reads every installed distribution's entry points: the vendored copies have no +dist-info on sys.path, and the application's OpenTelemetry plugins point at un-vendored modules. +opentelemetry-vendor sync keeps the vendored distributions' METADATA and namespaced entry points in +_vendor/_metadata (metadata-dir); entry_points() and distributions() only search there. + +version() and requires() keep looking at the application's distributions: instrumentors check that the +installed version of the library they patch matches their "instruments" requirements. + +diff --git a/opentelemetry/util/_importlib_metadata.py b/opentelemetry/util/_importlib_metadata.py +index 656afbb..c7c5399 100644 +--- a/opentelemetry/util/_importlib_metadata.py ++++ b/opentelemetry/util/_importlib_metadata.py +@@ -11,38 +11,35 @@ It also normalizes minor differences across python versions 3.10+. References to + - https://github.com/open-telemetry/opentelemetry-python/pull/5203 + """ + +-import itertools ++import os + from functools import cache + from importlib.metadata import ( + Distribution, + EntryPoint, + EntryPoints, + PackageNotFoundError, +- distributions, + requires, + version, + ) +-from importlib.metadata import entry_points as original_entry_points +-from typing import Any ++from importlib.metadata import distributions as _all_distributions ++from typing import Any, Iterable ++ ++# opentelemetry-agent: entry points are only looked up in the vendored distributions' metadata ++# (written to _vendor/_metadata by opentelemetry-vendor sync), never in the application's, whose ++# OpenTelemetry plugins point at un-vendored modules. version() and requires() still see the ++# application's distributions: instrumentors check the installed versions of the libraries they patch. ++_VENDORED_METADATA_PATH = [ ++ os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "_metadata") ++] + + +-def _as_entry_points(eps: Any) -> EntryPoints: +- # Python versions greater than 3.11 return EntryPoints. +- if isinstance(eps, EntryPoints): +- return eps +- # In Python 3.10 and 3.11 entry_points() returns +- # a dict-like SelectableGroups object. +- # Use dict.values() instead of eps.values() to avoid the DeprecationWarning +- # that SelectableGroups raises when calling .values(). +- if isinstance(eps, dict): +- return EntryPoints(itertools.chain.from_iterable(dict.values(eps))) +- # This case should be unreachable, but is included as a fallback. +- return EntryPoints(ep for group in eps.groups for ep in eps.select(group=group)) ++def distributions(**kwargs: Any) -> Iterable[Distribution]: ++ return _all_distributions(path=_VENDORED_METADATA_PATH, **kwargs) + + + @cache + def _original_entry_points_cached() -> EntryPoints: +- return _as_entry_points(original_entry_points()) ++ return EntryPoints(entry_point for dist in distributions() for entry_point in dist.entry_points) + + + def entry_points(**params) -> EntryPoints: diff --git a/agent/opentelemetry-agent/patches/otel-sdk-vendored-names.patch b/agent/opentelemetry-agent/patches/otel-sdk-vendored-names.patch new file mode 100644 index 00000000000..96839c2b639 --- /dev/null +++ b/agent/opentelemetry-agent/patches/otel-sdk-vendored-names.patch @@ -0,0 +1,65 @@ +Report upstream module names from the vendored SDK. + +Instrumentations name their tracers, meters and loggers after their module (get_tracer(__name__)), +which is opentelemetry.agent._vendor.opentelemetry... once vendored. InstrumentationScope (and the +deprecated InstrumentationInfo) strip the vendor prefix, so telemetry reports the same scope names as +the upstream packages, e.g. opentelemetry.instrumentation.aiohttp_client. + +The TracerProvider's warning filter for its own InstrumentationInfo deprecation names its module by +string; use __name__ so it matches the vendored module rather than the application's SDK. + +diff --git a/opentelemetry/sdk/trace/__init__.py b/opentelemetry/sdk/trace/__init__.py +index 06fd2b3..1f7ab18 100644 +--- a/opentelemetry/sdk/trace/__init__.py ++++ b/opentelemetry/sdk/trace/__init__.py +@@ -1351,7 +1351,8 @@ class TracerProvider(trace_api.TracerProvider): + "ignore", + message=(r"You should use InstrumentationScope. Deprecated since version 1.11.1."), + category=DeprecationWarning, +- module="opentelemetry.sdk.trace", ++ # opentelemetry-agent: match this (vendored) module, not the application's SDK. ++ module=__name__, + ) + + instrumentation_info = InstrumentationInfo( +diff --git a/opentelemetry/sdk/util/instrumentation.py b/opentelemetry/sdk/util/instrumentation.py +index ac64c2d..9cf8491 100644 +--- a/opentelemetry/sdk/util/instrumentation.py ++++ b/opentelemetry/sdk/util/instrumentation.py +@@ -13,6 +13,18 @@ from opentelemetry.agent._vendor.opentelemetry.util.types import ( # TODO: see + ) + + ++# opentelemetry-agent: instrumentations vendored under the agent's namespace name their scope after ++# their module (get_tracer(__name__)); report the upstream module name instead, e.g. ++# "opentelemetry.instrumentation.aiohttp_client" rather than "opentelemetry.agent._vendor.opentelemetry...". ++_VENDOR_PREFIX = __name__.removesuffix("opentelemetry.sdk.util.instrumentation") ++ ++ ++def _unvendored_name(name: str) -> str: ++ if isinstance(name, str) and name.startswith(_VENDOR_PREFIX): ++ return name[len(_VENDOR_PREFIX) :] ++ return name ++ ++ + class InstrumentationInfo: + """Immutable information about an instrumentation library module. + +@@ -29,7 +41,7 @@ class InstrumentationInfo: + version: str | None = None, + schema_url: str | None = None, + ): +- self._name = name ++ self._name = _unvendored_name(name) + self._version = version + if schema_url is None: + schema_url = "" +@@ -92,7 +104,7 @@ class InstrumentationScope: + schema_url: str | None = None, + attributes: Attributes = None, + ) -> None: +- self._name = name ++ self._name = _unvendored_name(name) + self._version = version + if schema_url is None: + schema_url = "" diff --git a/agent/opentelemetry-agent/patches/protobuf-pure-python.patch b/agent/opentelemetry-agent/patches/protobuf-implementation.patch similarity index 74% rename from agent/opentelemetry-agent/patches/protobuf-pure-python.patch rename to agent/opentelemetry-agent/patches/protobuf-implementation.patch index fc8fb9da565..b6e56eb791c 100644 --- a/agent/opentelemetry-agent/patches/protobuf-pure-python.patch +++ b/agent/opentelemetry-agent/patches/protobuf-implementation.patch @@ -1,10 +1,11 @@ -Force the pure-Python protobuf implementation in the vendored copy. +Select the vendored protobuf implementation: upb when built, else pure Python. Upstream probes for the upb/cpp C extensions with importlib.import_module("google._upb._message") -and friends, which imports the application's protobuf by its top-level name (and then warns that -the vendored upb is unavailable), and honours PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which is meant -for the application's protobuf: "cpp" makes descriptor.py import the missing vendored pyext and -crash. Only the pure-Python implementation is vendored, so select it unconditionally. +and friends, which imports the application's protobuf by its top-level name, and honours +PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which is meant for the application's protobuf: "cpp" makes +descriptor.py import the missing vendored pyext and crash. Only the vendored upb extension (included in +platform builds of the agent, see patches/native/protobuf-upb.patch) is considered; otherwise the +pure-Python implementation is used. diff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/internal/api_implementation.py --- a/google/protobuf/internal/api_implementation.py @@ -17,13 +18,18 @@ diff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/in import os import sys import warnings -@@ -24,90 +23,15 @@ def _ApiVersionToImplementationType(api_version): +@@ -24,89 +23,19 @@ def _ApiVersionToImplementationType(api_version): return None -_implementation_type = None --try: -- # pylint: disable=g-import-not-at-top ++# Only the vendored upb extension is considered (platform builds of the agent include it; ++# the pure-Python build doesn't). Never probe for the application's google._upb / ++# google.protobuf.pyext by their top-level names, and don't follow ++# PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which configures the application's protobuf ++# (e.g. "cpp" would make descriptor.py import the missing vendored pyext._message). + try: + # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf.internal import _api_implementation - # The compile-time constants in the _api_implementation module can be used to - # switch to a certain implementation of the Python API at build time. @@ -67,22 +73,19 @@ diff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/in - "supported. Please set to 'python', 'cpp' or " - "'upb'.".format(_implementation_type) - ) -- ++ from opentelemetry.agent._vendor.google._upb import _message as _c_module + -if 'PyPy' in sys.version and _implementation_type == 'cpp': - warnings.warn( - 'PyPy does not work yet with cpp protocol buffers. ' - 'Falling back to the python implementation.' - ) -- _implementation_type = 'python' -+# The vendored copy ships only the pure-Python implementation. Don't probe for the -+# C extensions, which would import the application's google._upb / google.protobuf.pyext -+# by their top-level names, and don't follow PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which -+# configures the application's protobuf (e.g. "cpp" would make descriptor.py import the -+# missing vendored pyext._message). -+_implementation_type = 'python' - - _c_module = None - ++ _implementation_type = 'upb' ++except ImportError: + _implementation_type = 'python' +- +-_c_module = None +- -if _implementation_type == 'cpp': - try: - # pylint: disable=g-import-not-at-top @@ -110,7 +113,7 @@ diff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/in - ) - _implementation_type = 'python' - pass -- ++ _c_module = None + # Detect if serialization should be deterministic by default try: - # The presence of this module in a build allows the proto implementation to diff --git a/agent/opentelemetry-agent/patches/ruamel-yaml-pure.patch b/agent/opentelemetry-agent/patches/ruamel-yaml-pure.patch new file mode 100644 index 00000000000..7fe8173f686 --- /dev/null +++ b/agent/opentelemetry-agent/patches/ruamel-yaml-pure.patch @@ -0,0 +1,24 @@ +Never load the libyaml binding in the vendored ruamel.yaml. + +ruamel.yaml imports the optional C parser and emitter from the _ruamel_yaml extension module +(ruamel.yaml.clib), which would be the application's, not vendored. ruamel/yaml/cyaml.py is dropped; this +patch makes main.py fall back to the pure-Python implementation unconditionally. + +diff --git a/ruamel/yaml/main.py b/ruamel/yaml/main.py +index fdf7c72..5e23910 100644 +--- a/ruamel/yaml/main.py ++++ b/ruamel/yaml/main.py +@@ -42,10 +42,9 @@ if False: # MYPY + from types import TracebackType + from pathlib import Path + +-try: +- from _ruamel_yaml import CParser, CEmitter # type: ignore +-except: # NOQA +- CParser = CEmitter = None ++# opentelemetry-agent: always use the pure-Python parser and emitter; the libyaml binding ++# (_ruamel_yaml) would be the application's, not vendored. ++CParser = CEmitter = None + + # import io + diff --git a/agent/opentelemetry-agent/pyproject.toml b/agent/opentelemetry-agent/pyproject.toml index 452831696c5..68f7fdaaa5b 100644 --- a/agent/opentelemetry-agent/pyproject.toml +++ b/agent/opentelemetry-agent/pyproject.toml @@ -26,6 +26,10 @@ classifiers = [ ] dependencies = [] +[project.scripts] +# The vendored opentelemetry-instrument: its sitecustomize hook imports the vendored auto-instrumentation. +opentelemetry-instrument = "opentelemetry.agent._vendor.opentelemetry.instrumentation.auto_instrumentation:run" + [project.urls] Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/agent/opentelemetry-agent" Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib" @@ -53,23 +57,46 @@ drop = [ "urllib3/contrib/pyopenssl.py", "urllib3/contrib/emscripten", "urllib3/http2/connection.py", - # protobuf: benchmarks and test helpers (import google_benchmark/numpy/unittest_pb2), the protoc - # plugin API, and the cpp implementation shim (unused: the pure-Python implementation is forced - # by patches/protobuf-pure-python.patch). + # protobuf: benchmarks and test helpers (import google_benchmark/numpy/unittest_pb2) and the protoc + # plugin API. google/protobuf/pyext is kept: its cpp_message.py wraps the vendored upb extension. "google/protobuf/internal/*_benchmark.py", "google/protobuf/internal/testing_refleaks.py", "google/protobuf/testdata", "google/protobuf/compiler", - "google/protobuf/pyext", + # gRPC service stubs (import grpcio, which isn't vendored: no pure-Python wheel). + "google/longrunning/operations_pb2_grpc.py", + "opentelemetry/proto/collector/**/*_pb2_grpc.py", + # prometheus_client integrations with web frameworks the agent doesn't use (import the application's + # aiohttp, Django and Twisted). + "prometheus_client/aiohttp", + "prometheus_client/django", + "prometheus_client/twisted", + # ruamel.yaml's libyaml binding wrappers and the build script of its optional C extension. + "ruamel/yaml/cyaml.py", + "ruamel/yaml/clibz", ] # Applied in order after imports are rewritten; paths inside the patches are relative to destination. patches = [ "patches/requests-packages.patch", "patches/requests-chardet.patch", "patches/certifi-resources.patch", - "patches/protobuf-pure-python.patch", + "patches/protobuf-implementation.patch", + "patches/otel-importlib-metadata.patch", + "patches/otel-sdk-vendored-names.patch", + "patches/otel-distro-http-protocol.patch", + "patches/otel-configuration-loader.patch", + "patches/ruamel-yaml-pure.patch", ] sbom-file = "src/opentelemetry/agent/_vendor/bom.cdx.json" +# Scoped METADATA and namespaced entry points for the vendored importlib.metadata lookups; see +# patches/otel-importlib-metadata.patch. +metadata-dir = "_metadata" + +# These wheels declare Apache-2.0 but ship no license file; use the repository's (identical) Apache-2.0 text. +[tool.opentelemetry-vendor.license-files] +opentelemetry-configuration = "../../LICENSE" +opentelemetry-distro = "../../LICENSE" +opentelemetry-util-http = "../../LICENSE" # Files whose findings from the vendored-code checks have been reviewed, per check. [tool.opentelemetry-vendor.allow] @@ -77,15 +104,66 @@ dynamic-imports = [ # Only imports stdlib codec modules (encodings.*, _codecs_*). "charset_normalizer/cd.py", "charset_normalizer/utils.py", + # Instrumentation imports (and wrapt patches) the application's libraries by module name: intended. + "opentelemetry/instrumentation/utils.py", + "wrapt/importer.py", + "wrapt/patches.py", + "wrapt/proxies.py", + # Python-object tags of ruamel.yaml's unsafe constructors; the configuration loader uses SafeLoader. + "ruamel/yaml/constructor.py", + # YAML(plug_ins=...): the vendored tree has no plug-ins and the agent doesn't pass any. + "ruamel/yaml/main.py", ] side-effects = [ - # Warning filters only target requests' and urllib3's own warning classes. + # Warning filters only target the vendored packages' own warning classes (or, for the SDK's + # TracerProvider, its own vendored module; see patches/otel-sdk-vendored-names.patch). + "opentelemetry/sdk/_logs/_internal/__init__.py", + "opentelemetry/sdk/trace/__init__.py", "requests/__init__.py", + "ruamel/yaml/error.py", "urllib3/__init__.py", # set_environ() temporarily sets an environment variable and restores it. "requests/utils.py", + # Configuring the process through OTEL_* environment variables (and PYTHONPATH for the + # sitecustomize hook) is what the distro and opentelemetry-instrument are for. + "opentelemetry/distro/__init__.py", + "opentelemetry/instrumentation/auto_instrumentation/__init__.py", + # Copies the deprecated prometheus_multiproc_dir variable to PROMETHEUS_MULTIPROC_DIR when set. + "prometheus_client/multiprocess.py", + "prometheus_client/values.py", +] +external-imports = [ + # Instrumentations import and patch the application's libraries: that's what they are for. + "opentelemetry/instrumentation/*", + # Optional, guarded imports of the application's packages: + # - gRPC exporters from file configuration fail with a ConfigurationError (they aren't vendored); + "opentelemetry/configuration/_logger_provider.py", + "opentelemetry/configuration/_meter_provider.py", + "opentelemetry/configuration/_tracer_provider.py", + # - psutil for the process resource detector's process.* attributes; + "opentelemetry/sdk/resources/__init__.py", + # - numpy, only when the application converts a repeated field with numpy.asarray(); + "google/protobuf/internal/containers.py", + # - snappy for Prometheus remote-write compression; + "prometheus_client/exposition.py", + # - cryptography (version warning), simplejson and _typeshed (type checking only); + "requests/__init__.py", + "requests/compat.py", + "requests/cookies.py", + # - ordereddict (Python 2 fallback) and configobj (configobj_walker(), unused); + "ruamel/yaml/compat.py", + "ruamel/yaml/util.py", + # - brotli and zstandard content decoding. + "urllib3/response.py", + "urllib3/util/request.py", ] +# Native extensions, built from the sdist by `opentelemetry-vendor build-native` for platform wheels. +[tool.opentelemetry-vendor.native.protobuf] +# Builds google._upb._message as opentelemetry.agent._vendor.google._upb._message (abi3). +patches = ["patches/native/protobuf-upb.patch"] +build-requirements = "native-build-requirements.txt" + [tool.hatch.version] path = "src/opentelemetry/agent/version.py" @@ -97,3 +175,8 @@ include = [ [tool.hatch.build.targets.wheel] packages = ["src/opentelemetry"] + +# Tags the wheel cp310-abi3- when `opentelemetry-vendor build-native` built extensions +# into the vendor tree; otherwise it stays py3-none-any. +[tool.hatch.build.targets.wheel.hooks.custom] +abi3-tag = "cp310" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA new file mode 100644 index 00000000000..fce48f0bc79 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA @@ -0,0 +1,79 @@ +Metadata-Version: 2.4 +Name: certifi +Version: 2026.10.23 +Summary: Python package for providing Mozilla's CA Bundle. +Home-page: https://github.com/certifi/python-certifi +Author: Kenneth Reitz +Author-email: me@kennethreitz.com +License: MPL-2.0 +Project-URL: Source, https://github.com/certifi/python-certifi +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) +Classifier: Natural Language :: English +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Requires-Python: >=3.7 +License-File: LICENSE +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: home-page +Dynamic: license +Dynamic: license-file +Dynamic: project-url +Dynamic: requires-python +Dynamic: summary + +Certifi: Python SSL Certificates +================================ + +Certifi provides Mozilla's carefully curated collection of Root Certificates for +validating the trustworthiness of SSL certificates while verifying the identity +of TLS hosts. It has been extracted from the `Requests`_ project. + +Installation +------------ + +``certifi`` is available on PyPI. Simply install it with ``pip``:: + + $ pip install certifi + +Usage +----- + +To reference the installed certificate authority (CA) bundle, you can use the +built-in function:: + + >>> import certifi + + >>> certifi.where() + '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' + +Or from the command line:: + + $ python -m certifi + /usr/local/lib/python3.7/site-packages/certifi/cacert.pem + +Enjoy! + +.. _`Requests`: https://requests.readthedocs.io/en/latest/ + +Addition/Removal of Certificates +-------------------------------- + +Certifi does not support any addition/removal or other modification of the +CA trust store content. This project is intended to provide a reliable and +highly portable root of trust to python deployments. Look to upstream projects +for methods to use alternate trust. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA new file mode 100644 index 00000000000..d15b68acb1e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA @@ -0,0 +1,892 @@ +Metadata-Version: 2.4 +Name: charset-normalizer +Version: 3.5.2 +Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet. +Author-email: "Ahmed R. TAHRI" +Maintainer-email: "Ahmed R. TAHRI" +License: MIT +Project-URL: Changelog, https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md +Project-URL: Documentation, https://charset-normalizer.readthedocs.io/ +Project-URL: Code, https://github.com/jawah/charset_normalizer +Project-URL: Issue tracker, https://github.com/jawah/charset_normalizer/issues +Keywords: encoding,charset,charset-detector,detector,normalization,unicode,chardet,detect +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient +Classifier: Environment :: WebAssembly +Classifier: Environment :: WebAssembly :: Emscripten +Classifier: Topic :: Text Processing :: Linguistic +Classifier: Topic :: Utilities +Classifier: Typing :: Typed +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +License-File: LICENSE +Provides-Extra: unicode-backport +Dynamic: license-file + +

Charset Detection, for Everyone 👋

+ +

+ The Real First Universal Charset Detector
+ + + + + Download Count Total + + + + +

+

+ Featured Packages
+ + Static Badge + + + Static Badge + +

+

+ In other language (unofficial port - by the community)
+ + Static Badge + +

+ +> A library that helps you read text from an unknown charset encoding.
Motivated by `chardet`, +> I'm trying to resolve the issue by taking a new approach. +> All IANA character set names for which the Python core library provides codecs are supported. +> You can also register your own set of codecs, and yes, it would work as-is. + +This project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**. + +| Feature | [Chardet](https://github.com/chardet/chardet) | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) | +|--------------------------------------------------|:---------------------------------------------:|:-----------------------------------------------------------------------------------------------:|:-----------------------------------------------:| +| `Fast` | ✅ | ✅ | ✅ | +| `Fast on large content (uncapped)` | ❌ | ✅ | ❌ | +| `Universal`[^1] | ❌ | ✅ | ❌ | +| `Reliable` **without** distinguishable standards | ✅ | ✅ | ✅ | +| `Reliable` **with** distinguishable standards | ✅ | ✅ | ✅ | +| `License` | _0BSD_[^2]
_disputed_ | MIT | MPL-1.1
_restrictive_ | +| `Native Python` | ✅ | ✅ | ❌ | +| `Detect spoken language` | ✅ | ✅ | N/A | +| `UnicodeDecodeError Safety` | ❌ | ✅ | ❌ | +| `Whl Size` | ~1200 kB | ~250 kB | ~200 kB | +| `Supported Encoding` | 99 | [99](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings) | 40 | +| `Can register custom encoding` | ❌ | ✅ | ❌ | + +

+Reading Normalized TextCat Reading Text +

+ +[^1]: They are clearly using specific code for a specific encoding even if covering most of them. +[^2]: Chardet 7 replaced the historical LGPL-licensed implementation with an AI-assisted rewrite, initially distributed under MIT and later under 0BSD. The original author [contests](https://github.com/chardet/chardet/issues/327) that the rewrite was sufficiently independent to permit relicensing, while Chardet's maintainer maintains that it is a new, non-derivative implementation. A separate [discussion](https://github.com/chardet/chardet/issues/334) raises questions about copyright ownership and licensing of substantially AI-generated code. Neither unresolved question is presented here as settled law. The concern is broader than whether ideas, APIs, or observable behavior are copyrightable. Independent implementations are essential to open-source competition. The ethical question is whether a maintainer with extensive access to a reciprocal project's source, architecture, tests, behavior, community, and reputation can use an LLM to recreate the same product under the same package identity, then treat the generated implementation as a provenance reset that extinguishes the project's reciprocal licensing obligations and contributor expectations. Responsible AI use in open source requires more than producing text that differs from the historical source: it requires transparent provenance, respect for project lineage, meaningful attribution, accountable human review, and consideration for the social agreement under which earlier contributors participated. If automated rewriting becomes an accepted way to retain a project's name, users, and accumulated reputation while discarding its reciprocal license, it risks weakening the trust and incentives on which FOSS depends. Early Chardet 7.x development and evaluation also incorporated files originating from charset-normalizer's test corpus. Results measured on data that influenced implementation or model development are not independent validation. Charset-normalizer has been MIT-licensed since inception and originates from a continuous human-designed, encoding-agnostic project history. AI assistance may be used, but every proposed change remains subject to maintainer review, adjustment, testing, and accountability; AI is an engineering aid, not a mechanism for erasing provenance or project lineage. An attentive eye will see that some aspects lead by us are magically found in Chardet. + +## ⚡ Performance + +This package offer similar performances in general against Chardet. Expect 10X faster with large contents when you uncap Chardet max_bytes default assumption. + +| Package | Accuracy | Mean per file (ms) | +|--------------------|:--------:|:---------------------:| +| Chardet | 99 % | 0.4 ms[^4] 0.6 ms[^5] | +| charset-normalizer | 98 % | 0.4 ms | +| cchardet[^3] | 94 % | 0.6 ms | + +_Well, sub-ms detectors made them extremely discrete in the overall runtime. +Competitors can still win individual measurements, especially capped Chardet on +small-file median latency. But when performance, accuracy, binary handling, validation +strength, portability, and maintainability are considered together, charset-normalizer +is the stronger package._ + +| Package | 99th percentile | 95th percentile | 50th percentile | +|--------------------|:--------------------:|:---------------:|:---------------:| +| Chardet | 2.5 ms[^4] 4.2ms[^5] | 1 ms | 0.2 ms | +| charset-normalizer | 2.7 ms | 1.5 ms | 0.2 ms | +| cchardet | 2.7 ms | 2 ms | 0.3 ms | + +_updated as of August 2026 using CPython 3.12, Charset-Normalizer 3.5.1, and Chardet 7.5 inside a (libc Debian) container. The host CPU is a 13th gen Intel mobile CPU. We'll no longer update regularly those since the sub-ms changes aren't meaningful to anyone anymore._ + +> Stats are generated using 477 files using default parameters. More details on used files, see GHA workflows. +> And yes, these results might change at any time. The dataset can be updated to include more files. +> The actual delays heavily depends on your CPU capabilities. The factors should remain the same. +> Chardet claims on his documentation to have a greater accuracy than us based on the dataset they trained Chardet on(...) +> Whereas charset-normalizer don't train on anything, our solution is based on a completely different algorithm, still heuristic +> through, it does not need weights across every encoding tables. + +[^3]: cchardet main repository/package was discontinued. we're relying on a known fork namely faust-cchardet. the idea remained the same: uchardet bindings. +[^4]: Chardet does not feed the complete body but rather a limited part of it, because the algorithm doesn't scale properly with larger samples. Feeding the whole content slow things to 0.8 ms (from the 0.5ms avg). While we do not skip content in order for us to guarantee a usable result each and every time. We attempted to feed a 272 MiB UTF-8 (Reddit archive on comments/posts) file in Chardet uncapped and waited 3.4s while Charset-Normalizer took 0.3s, this is a 10-fold speedup. +[^5]: Uncapped max_bytes (no truncating of content) + +## ✨ Installation + +Using pip: + +```sh +pip install charset-normalizer -U +``` + +## 🚀 Basic Usage + +### CLI +This package comes with a CLI. + +``` +usage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD] + file [file ...] + +The Real First Universal Charset Detector. Discover originating encoding used +on text file. Normalize text to unicode. + +positional arguments: + files File(s) to be analysed + +optional arguments: + -h, --help show this help message and exit + -v, --verbose Display complementary information about file if any. + Stdout will contain logs about the detection process. + -a, --with-alternative + Output complementary possibilities if any. Top-level + JSON WILL be a list. + -n, --normalize Permit to normalize input file. If not set, program + does not write anything. + -m, --minimal Only output the charset detected to STDOUT. Disabling + JSON output. + -r, --replace Replace file when trying to normalize it instead of + creating a new one. + -f, --force Replace file without asking if you are sure, use this + flag with caution. + -t THRESHOLD, --threshold THRESHOLD + Define a custom maximum amount of chaos allowed in + decoded content. 0. <= chaos <= 1. + --version Show version information and exit. +``` + +```bash +normalizer ./data/sample.1.fr.srt +``` + +or + +```bash +python -m charset_normalizer ./data/sample.1.fr.srt +``` + +🎉 Since version 1.4.0 the CLI produce easily usable stdout result in JSON format. + +```json +{ + "path": "/home/default/projects/charset_normalizer/data/sample.1.fr.srt", + "encoding": "cp1252", + "encoding_aliases": [ + "1252", + "windows_1252" + ], + "alternative_encodings": [ + "cp1254", + "cp1256", + "cp1258", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + "mbcs" + ], + "language": "French", + "alphabets": [ + "Basic Latin", + "Latin-1 Supplement" + ], + "has_sig_or_bom": false, + "chaos": 0.149, + "coherence": 97.152, + "unicode_path": null, + "is_preferred": true +} +``` + +### Python +*Just print out normalized text* +```python +from charset_normalizer import from_path + +results = from_path('./my_subtitle.srt') + +print(str(results.best())) +``` + +*Upgrade your code without effort* +```python +from charset_normalizer import detect +``` + +The above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible. + +See the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/) + +## 😇 Why + +When I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a +reliable alternative using a completely different method. Also! I never back down on a good challenge! + +I **don't care** about the **originating charset** encoding, because **two different tables** can +produce **two identical rendered string.** +What I want is to get readable text, the best I can. + +In a way, **I'm brute forcing text decoding.** How cool is that ? 😎 + +Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair Unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode. + +## 🍰 How + + - Discard all charset encoding table that could not fit the binary content. + - Measure noise, or the mess once opened (by chunks) with a corresponding charset encoding. + - Extract matches with the lowest mess detected. + - Additionally, we measure coherence / probe for a language. + +**Wait a minute**, what is noise/mess and coherence according to **YOU ?** + +*Noise :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then +**I established** some ground rules about **what is obvious** when **it seems like** a mess (aka. defining noise in rendered text). + I know that my interpretation of what is noise is probably incomplete, feel free to contribute in order to + improve or rewrite it. + +*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought +that intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design. + +## ⚡ Known limitations + + - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters)) + - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content. + +## ⚠️ About Python EOLs + +**If you are running:** + +- Python >=2.7,<3.5: Unsupported +- Python 3.5: charset-normalizer < 2.1 +- Python 3.6: charset-normalizer < 3.1 + +Upgrade your Python interpreter as soon as possible. + +## 👤 Contributing + +Contributions, issues and feature requests are very much welcome.
+Feel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute. + +## 📝 License + +Copyright © [Ahmed TAHRI @Ousret](https://github.com/Ousret).
+This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed. + +Characters frequencies used in this project © 2012 [Denny Vrandečić](http://simia.net/letters/) + +## 💼 For Enterprise + +Professional support for charset-normalizer is available as part of the [Tidelift +Subscription][1]. Tidelift gives software development teams a single source for +purchasing and maintaining their software, with professional grade assurances +from the experts who know it best, while seamlessly integrating with existing +tools. + +[1]: https://tidelift.com/subscription/pkg/pypi-charset-normalizer?utm_source=pypi-charset-normalizer&utm_medium=readme + +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7297/badge)](https://www.bestpractices.dev/projects/7297) + +# Changelog +All notable changes to charset-normalizer will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [3.5.2](https://github.com/Ousret/charset_normalizer/compare/3.5.1...3.5.2) (2026-09-29) + +### Changed + +- Raised the Cython upper bound to `<3.4` for native builds. The bound remains `<3.3` for + `abi3` builds to preserve compatibility with the Python 3.7 Limited API. + +### Fixed + +- Valid UTF-8 Chinese JSON incorrectly detected as PTCP154 due to excessive noise penalties + for uncommon CJK characters. (#796) +- Supported encodings without aliases failing name resolution or being ignored in charset + declarations. (#800) + +## [3.5.1](https://github.com/Ousret/charset_normalizer/compare/3.5.0...3.5.1) (2026-08-15) + +### Changed +- Raised upper bound of setuptools to v84 (#794) +- Cache performance access optimization for our CharInfo struct (prebuilt only). + +### Fixed +- No longer decoding large content when the noise detector output give a high entropy. + Only impacted large content input >1M bytes. + +## [3.5.0](https://github.com/Ousret/charset_normalizer/compare/3.4.9...3.5.0) (2026-08-12) + +### Added +- Explicit support for Python 3.15 + +### Fixed +- Comparing a CharsetMatch to a non-alias encoding strings (#773) +- Return 0.0 CharsetMatch.multi_byte_usage for empty payloads instead of crashing (#774) +- A file with both a charset declaration and BOM/SIG did not verify first the BOM/SIG charset. +- iso2022* cases misdetected due to a flaw in our multibyte chunking logic. + +### Changed +- Replaced the optional mypyc build with Cython extensions while retaining the + pure Python fallback. The previous engine (mypyc) started to hit rough limit around + the optimization of our noise/coherence detector while Cython allows us to + steer the engine toward the right generated optimized sources. + This change SHOULD not impact bundler (e.g. Pyinstaller) as the module are + immediately discoverable (i.e. not hidden import like mypyc did). + Moreover, a long wished distribution is the abi3 wheels, this will allow us + to no longer rush each year when a new Python interpreter is released. + We still distribute the interpreter specific wheels for faster performance. +- Applied micro-optimization on several utils. +- CharsetMatches no longer sort on each match insertion. + +### Misc +- Removed an old performance optimization attempt in apy.py (success_fast_tracked+payload_result_cache). + +## [3.4.9](https://github.com/Ousret/charset_normalizer/compare/3.4.8...3.4.9) (2026-07-07) + +### Fixed +- Regression in our fallback path leading to a decode error. (#771) + We've yanked 3.4.8 as a result of that bug. + +## [3.4.8](https://github.com/Ousret/charset_normalizer/compare/3.4.7...3.4.8) (2026-07-06) + +### Fixed +- Wall import time due to cascade codec imports for our multibyte first sort of iana supported codecs (#742) +- Unnecessary json import at runtime (#753) +- Inverse capitalization not seen by noise detector (#731) + +### Changed +- No longer holding a global cache for our noise / coherence measurements. Relax RSS memory usage. +- Micro-optimizations in our noise / coherence measurements. +- No longer using regex search by default for our preemptive charset mark algorithm. +- Raised upperbound of setuptools to v83. +- Raised upperbound of mypy(c) to v2.1. + +### Removed +- Redundant UTF7 BOM marker (#730) + +## [3.4.7](https://github.com/Ousret/charset_normalizer/compare/3.4.6...3.4.7) (2026-04-02) + +### Changed +- Pre-built optimized version using mypy[c] v1.20. +- Relax `setuptools` constraint to `setuptools>=68,<82.1`. + +### Fixed +- Correctly remove SIG remnant in utf-7 decoded string. (#718) (#716) + +## [3.4.6](https://github.com/Ousret/charset_normalizer/compare/3.4.5...3.4.6) (2026-03-15) + +### Changed +- Flattened the logic in `charset_normalizer.md` for higher performance. Removed `eligible(..)` and `feed(...)` + in favor of `feed_info(...)`. +- Raised upper bound for mypy[c] to 1.20, for our optimized version. +- Updated `UNICODE_RANGES_COMBINED` using Unicode blocks v17. + +### Fixed +- Edge case where noise difference between two candidates can be almost insignificant. (#672) +- CLI `--normalize` writing to wrong path when passing multiple files in. (#702) + +### Misc +- Freethreaded pre-built wheels now shipped in PyPI starting with 3.14t. (#616) + +## [3.4.5](https://github.com/Ousret/charset_normalizer/compare/3.4.4...3.4.5) (2026-03-06) + +### Changed +- Update `setuptools` constraint to `setuptools>=68,<=82`. +- Raised upper bound of mypyc for the optional pre-built extension to v1.19.1 + +### Fixed +- Add explicit link to lib math in our optimized build. (#692) +- Logger level not restored correctly for empty byte sequences. (#701) +- TypeError when passing bytearray to from_bytes. (#703) + +### Misc +- Applied safe micro-optimizations in both our noise detector and language detector. +- Rewrote the `query_yes_no` function (inside CLI) to avoid using ambiguous licensed code. +- Added `cd.py` submodule into mypyc optional compilation to reduce further the performance impact. + +## [3.4.4](https://github.com/Ousret/charset_normalizer/compare/3.4.2...3.4.4) (2025-10-13) + +### Changed +- Bound `setuptools` to a specific constraint `setuptools>=68,<=81`. +- Raised upper bound of mypyc for the optional pre-built extension to v1.18.2 + +### Removed +- `setuptools-scm` as a build dependency. + +### Misc +- Enforced hashes in `dev-requirements.txt` and created `ci-requirements.txt` for security purposes. +- Additional pre-built wheels for riscv64, s390x, and armv7l architectures. +- Restore ` multiple.intoto.jsonl` in GitHub releases in addition to individual attestation file per wheel. + +## [3.4.3](https://github.com/Ousret/charset_normalizer/compare/3.4.2...3.4.3) (2025-08-09) + +### Changed +- mypy(c) is no longer a required dependency at build time if `CHARSET_NORMALIZER_USE_MYPYC` isn't set to `1`. (#595) (#583) +- automatically lower confidence on small bytes samples that are not Unicode in `detect` output legacy function. (#391) + +### Added +- Custom build backend to overcome inability to mark mypy as an optional dependency in the build phase. +- Support for Python 3.14 + +### Fixed +- sdist archive contained useless directories. +- automatically fallback on valid UTF-16 or UTF-32 even if the md says it's noisy. (#633) + +### Misc +- SBOM are automatically published to the relevant GitHub release to comply with regulatory changes. + Each published wheel comes with its SBOM. We choose CycloneDX as the format. +- Prebuilt optimized wheel are no longer distributed by default for CPython 3.7 due to a change in cibuildwheel. + +## [3.4.2](https://github.com/Ousret/charset_normalizer/compare/3.4.1...3.4.2) (2025-05-02) + +### Fixed +- Addressed the DeprecationWarning in our CLI regarding `argparse.FileType` by backporting the target class into the package. (#591) +- Improved the overall reliability of the detector with CJK Ideographs. (#605) (#587) + +### Changed +- Optional mypyc compilation upgraded to version 1.15 for Python >= 3.8 + +## [3.4.1](https://github.com/Ousret/charset_normalizer/compare/3.4.0...3.4.1) (2024-12-24) + +### Changed +- Project metadata are now stored using `pyproject.toml` instead of `setup.cfg` using setuptools as the build backend. +- Enforce annotation delayed loading for a simpler and consistent types in the project. +- Optional mypyc compilation upgraded to version 1.14 for Python >= 3.8 + +### Added +- pre-commit configuration. +- noxfile. + +### Removed +- `build-requirements.txt` as per using `pyproject.toml` native build configuration. +- `bin/integration.py` and `bin/serve.py` in favor of downstream integration test (see noxfile). +- `setup.cfg` in favor of `pyproject.toml` metadata configuration. +- Unused `utils.range_scan` function. + +### Fixed +- Converting content to Unicode bytes may insert `utf_8` instead of preferred `utf-8`. (#572) +- Deprecation warning "'count' is passed as positional argument" when converting to Unicode bytes on Python 3.13+ + +## [3.4.0](https://github.com/Ousret/charset_normalizer/compare/3.3.2...3.4.0) (2024-10-08) + +### Added +- Argument `--no-preemptive` in the CLI to prevent the detector to search for hints. +- Support for Python 3.13 (#512) + +### Fixed +- Relax the TypeError exception thrown when trying to compare a CharsetMatch with anything else than a CharsetMatch. +- Improved the general reliability of the detector based on user feedbacks. (#520) (#509) (#498) (#407) (#537) +- Declared charset in content (preemptive detection) not changed when converting to utf-8 bytes. (#381) + +## [3.3.2](https://github.com/Ousret/charset_normalizer/compare/3.3.1...3.3.2) (2023-10-31) + +### Fixed +- Unintentional memory usage regression when using large payload that match several encoding (#376) +- Regression on some detection case showcased in the documentation (#371) + +### Added +- Noise (md) probe that identify malformed arabic representation due to the presence of letters in isolated form (credit to my wife) + +## [3.3.1](https://github.com/Ousret/charset_normalizer/compare/3.3.0...3.3.1) (2023-10-22) + +### Changed +- Optional mypyc compilation upgraded to version 1.6.1 for Python >= 3.8 +- Improved the general detection reliability based on reports from the community + +## [3.3.0](https://github.com/Ousret/charset_normalizer/compare/3.2.0...3.3.0) (2023-09-30) + +### Added +- Allow to execute the CLI (e.g. normalizer) through `python -m charset_normalizer.cli` or `python -m charset_normalizer` +- Support for 9 forgotten encoding that are supported by Python but unlisted in `encoding.aliases` as they have no alias (#323) + +### Removed +- (internal) Redundant utils.is_ascii function and unused function is_private_use_only +- (internal) charset_normalizer.assets is moved inside charset_normalizer.constant + +### Changed +- (internal) Unicode code blocks in constants are updated using the latest v15.0.0 definition to improve detection +- Optional mypyc compilation upgraded to version 1.5.1 for Python >= 3.8 + +### Fixed +- Unable to properly sort CharsetMatch when both chaos/noise and coherence were close due to an unreachable condition in \_\_lt\_\_ (#350) + +## [3.2.0](https://github.com/Ousret/charset_normalizer/compare/3.1.0...3.2.0) (2023-06-07) + +### Changed +- Typehint for function `from_path` no longer enforce `PathLike` as its first argument +- Minor improvement over the global detection reliability + +### Added +- Introduce function `is_binary` that relies on main capabilities, and optimized to detect binaries +- Propagate `enable_fallback` argument throughout `from_bytes`, `from_path`, and `from_fp` that allow a deeper control over the detection (default True) +- Explicit support for Python 3.12 + +### Fixed +- Edge case detection failure where a file would contain 'very-long' camel cased word (Issue #289) + +## [3.1.0](https://github.com/Ousret/charset_normalizer/compare/3.0.1...3.1.0) (2023-03-06) + +### Added +- Argument `should_rename_legacy` for legacy function `detect` and disregard any new arguments without errors (PR #262) + +### Removed +- Support for Python 3.6 (PR #260) + +### Changed +- Optional speedup provided by mypy/c 1.0.1 + +## [3.0.1](https://github.com/Ousret/charset_normalizer/compare/3.0.0...3.0.1) (2022-11-18) + +### Fixed +- Multi-bytes cutter/chunk generator did not always cut correctly (PR #233) + +### Changed +- Speedup provided by mypy/c 0.990 on Python >= 3.7 + +## [3.0.0](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.0) (2022-10-20) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it +- Sphinx warnings when generating the documentation + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [3.0.0rc1](https://github.com/Ousret/charset_normalizer/compare/3.0.0b2...3.0.0rc1) (2022-10-18) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' + +## [3.0.0b2](https://github.com/Ousret/charset_normalizer/compare/3.0.0b1...3.0.0b2) (2022-08-21) + +### Added +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Removed +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) + +### Fixed +- Sphinx warnings when generating the documentation + +## [3.0.0b1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...3.0.0b1) (2022-08-15) + +### Changed +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Removed +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [2.1.1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...2.1.1) (2022-08-19) + +### Deprecated +- Function `normalize` scheduled for removal in 3.0 + +### Changed +- Removed useless call to decode in fn is_unprintable (#206) + +### Fixed +- Third-party library (i18n xgettext) crashing not recognizing utf_8 (PEP 263) with underscore from [@aleksandernovikov](https://github.com/aleksandernovikov) (#204) + +## [2.1.0](https://github.com/Ousret/charset_normalizer/compare/2.0.12...2.1.0) (2022-06-19) + +### Added +- Output the Unicode table version when running the CLI with `--version` (PR #194) + +### Changed +- Reuse decoded buffer for single byte character sets from [@nijel](https://github.com/nijel) (PR #175) +- Fixing some performance bottlenecks from [@deedy5](https://github.com/deedy5) (PR #183) + +### Fixed +- Workaround potential bug in cpython with Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space (PR #175) +- CLI default threshold aligned with the API threshold from [@oleksandr-kuzmenko](https://github.com/oleksandr-kuzmenko) (PR #181) + +### Removed +- Support for Python 3.5 (PR #192) + +### Deprecated +- Use of backport unicodedata from `unicodedata2` as Python is quickly catching up, scheduled for removal in 3.0 (PR #194) + +## [2.0.12](https://github.com/Ousret/charset_normalizer/compare/2.0.11...2.0.12) (2022-02-12) + +### Fixed +- ASCII miss-detection on rare cases (PR #170) + +## [2.0.11](https://github.com/Ousret/charset_normalizer/compare/2.0.10...2.0.11) (2022-01-30) + +### Added +- Explicit support for Python 3.11 (PR #164) + +### Changed +- The logging behavior have been completely reviewed, now using only TRACE and DEBUG levels (PR #163 #165) + +## [2.0.10](https://github.com/Ousret/charset_normalizer/compare/2.0.9...2.0.10) (2022-01-04) + +### Fixed +- Fallback match entries might lead to UnicodeDecodeError for large bytes sequence (PR #154) + +### Changed +- Skipping the language-detection (CD) on ASCII (PR #155) + +## [2.0.9](https://github.com/Ousret/charset_normalizer/compare/2.0.8...2.0.9) (2021-12-03) + +### Changed +- Moderating the logging impact (since 2.0.8) for specific environments (PR #147) + +### Fixed +- Wrong logging level applied when setting kwarg `explain` to True (PR #146) + +## [2.0.8](https://github.com/Ousret/charset_normalizer/compare/2.0.7...2.0.8) (2021-11-24) +### Changed +- Improvement over Vietnamese detection (PR #126) +- MD improvement on trailing data and long foreign (non-pure latin) data (PR #124) +- Efficiency improvements in cd/alphabet_languages from [@adbar](https://github.com/adbar) (PR #122) +- call sum() without an intermediary list following PEP 289 recommendations from [@adbar](https://github.com/adbar) (PR #129) +- Code style as refactored by Sourcery-AI (PR #131) +- Minor adjustment on the MD around european words (PR #133) +- Remove and replace SRTs from assets / tests (PR #139) +- Initialize the library logger with a `NullHandler` by default from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Setting kwarg `explain` to True will add provisionally (bounded to function lifespan) a specific stream handler (PR #135) + +### Fixed +- Fix large (misleading) sequence giving UnicodeDecodeError (PR #137) +- Avoid using too insignificant chunk (PR #137) + +### Added +- Add and expose function `set_logging_handler` to configure a specific StreamHandler from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Add `CHANGELOG.md` entries, format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) (PR #141) + +## [2.0.7](https://github.com/Ousret/charset_normalizer/compare/2.0.6...2.0.7) (2021-10-11) +### Added +- Add support for Kazakh (Cyrillic) language detection (PR #109) + +### Changed +- Further, improve inferring the language from a given single-byte code page (PR #112) +- Vainly trying to leverage PEP263 when PEP3120 is not supported (PR #116) +- Refactoring for potential performance improvements in loops from [@adbar](https://github.com/adbar) (PR #113) +- Various detection improvement (MD+CD) (PR #117) + +### Removed +- Remove redundant logging entry about detected language(s) (PR #115) + +### Fixed +- Fix a minor inconsistency between Python 3.5 and other versions regarding language detection (PR #117 #102) + +## [2.0.6](https://github.com/Ousret/charset_normalizer/compare/2.0.5...2.0.6) (2021-09-18) +### Fixed +- Unforeseen regression with the loss of the backward-compatibility with some older minor of Python 3.5.x (PR #100) +- Fix CLI crash when using --minimal output in certain cases (PR #103) + +### Changed +- Minor improvement to the detection efficiency (less than 1%) (PR #106 #101) + +## [2.0.5](https://github.com/Ousret/charset_normalizer/compare/2.0.4...2.0.5) (2021-09-14) +### Changed +- The project now comply with: flake8, mypy, isort and black to ensure a better overall quality (PR #81) +- The BC-support with v1.x was improved, the old staticmethods are restored (PR #82) +- The Unicode detection is slightly improved (PR #93) +- Add syntax sugar \_\_bool\_\_ for results CharsetMatches list-container (PR #91) + +### Removed +- The project no longer raise warning on tiny content given for detection, will be simply logged as warning instead (PR #92) + +### Fixed +- In some rare case, the chunks extractor could cut in the middle of a multi-byte character and could mislead the mess detection (PR #95) +- Some rare 'space' characters could trip up the UnprintablePlugin/Mess detection (PR #96) +- The MANIFEST.in was not exhaustive (PR #78) + +## [2.0.4](https://github.com/Ousret/charset_normalizer/compare/2.0.3...2.0.4) (2021-07-30) +### Fixed +- The CLI no longer raise an unexpected exception when no encoding has been found (PR #70) +- Fix accessing the 'alphabets' property when the payload contains surrogate characters (PR #68) +- The logger could mislead (explain=True) on detected languages and the impact of one MBCS match (PR #72) +- Submatch factoring could be wrong in rare edge cases (PR #72) +- Multiple files given to the CLI were ignored when publishing results to STDOUT. (After the first path) (PR #72) +- Fix line endings from CRLF to LF for certain project files (PR #67) + +### Changed +- Adjust the MD to lower the sensitivity, thus improving the global detection reliability (PR #69 #76) +- Allow fallback on specified encoding if any (PR #71) + +## [2.0.3](https://github.com/Ousret/charset_normalizer/compare/2.0.2...2.0.3) (2021-07-16) +### Changed +- Part of the detection mechanism has been improved to be less sensitive, resulting in more accurate detection results. Especially ASCII. (PR #63) +- According to the community wishes, the detection will fall back on ASCII or UTF-8 in a last-resort case. (PR #64) + +## [2.0.2](https://github.com/Ousret/charset_normalizer/compare/2.0.1...2.0.2) (2021-07-15) +### Fixed +- Empty/Too small JSON payload miss-detection fixed. Report from [@tseaver](https://github.com/tseaver) (PR #59) + +### Changed +- Don't inject unicodedata2 into sys.modules from [@akx](https://github.com/akx) (PR #57) + +## [2.0.1](https://github.com/Ousret/charset_normalizer/compare/2.0.0...2.0.1) (2021-07-13) +### Fixed +- Make it work where there isn't a filesystem available, dropping assets frequencies.json. Report from [@sethmlarson](https://github.com/sethmlarson). (PR #55) +- Using explain=False permanently disable the verbose output in the current runtime (PR #47) +- One log entry (language target preemptive) was not show in logs when using explain=True (PR #47) +- Fix undesired exception (ValueError) on getitem of instance CharsetMatches (PR #52) + +### Changed +- Public function normalize default args values were not aligned with from_bytes (PR #53) + +### Added +- You may now use charset aliases in cp_isolation and cp_exclusion arguments (PR #47) + +## [2.0.0](https://github.com/Ousret/charset_normalizer/compare/1.4.1...2.0.0) (2021-07-02) +### Changed +- 4x to 5 times faster than the previous 1.4.0 release. At least 2x faster than Chardet. +- Accent has been made on UTF-8 detection, should perform rather instantaneous. +- The backward compatibility with Chardet has been greatly improved. The legacy detect function returns an identical charset name whenever possible. +- The detection mechanism has been slightly improved, now Turkish content is detected correctly (most of the time) +- The program has been rewritten to ease the readability and maintainability. (+Using static typing)+ +- utf_7 detection has been reinstated. + +### Removed +- This package no longer require anything when used with Python 3.5 (Dropped cached_property) +- Removed support for these languages: Catalan, Esperanto, Kazakh, Baque, Volapük, Azeri, Galician, Nynorsk, Macedonian, and Serbocroatian. +- The exception hook on UnicodeDecodeError has been removed. + +### Deprecated +- Methods coherence_non_latin, w_counter, chaos_secondary_pass of the class CharsetMatch are now deprecated and scheduled for removal in v3.0 + +### Fixed +- The CLI output used the relative path of the file(s). Should be absolute. + +## [1.4.1](https://github.com/Ousret/charset_normalizer/compare/1.4.0...1.4.1) (2021-05-28) +### Fixed +- Logger configuration/usage no longer conflict with others (PR #44) + +## [1.4.0](https://github.com/Ousret/charset_normalizer/compare/1.3.9...1.4.0) (2021-05-21) +### Removed +- Using standard logging instead of using the package loguru. +- Dropping nose test framework in favor of the maintained pytest. +- Choose to not use dragonmapper package to help with gibberish Chinese/CJK text. +- Require cached_property only for Python 3.5 due to constraint. Dropping for every other interpreter version. +- Stop support for UTF-7 that does not contain a SIG. +- Dropping PrettyTable, replaced with pure JSON output in CLI. + +### Fixed +- BOM marker in a CharsetNormalizerMatch instance could be False in rare cases even if obviously present. Due to the sub-match factoring process. +- Not searching properly for the BOM when trying utf32/16 parent codec. + +### Changed +- Improving the package final size by compressing frequencies.json. +- Huge improvement over the larges payload. + +### Added +- CLI now produces JSON consumable output. +- Return ASCII if given sequences fit. Given reasonable confidence. + +## [1.3.9](https://github.com/Ousret/charset_normalizer/compare/1.3.8...1.3.9) (2021-05-13) + +### Fixed +- In some very rare cases, you may end up getting encode/decode errors due to a bad bytes payload (PR #40) + +## [1.3.8](https://github.com/Ousret/charset_normalizer/compare/1.3.7...1.3.8) (2021-05-12) + +### Fixed +- Empty given payload for detection may cause an exception if trying to access the `alphabets` property. (PR #39) + +## [1.3.7](https://github.com/Ousret/charset_normalizer/compare/1.3.6...1.3.7) (2021-05-12) + +### Fixed +- The legacy detect function should return UTF-8-SIG if sig is present in the payload. (PR #38) + +## [1.3.6](https://github.com/Ousret/charset_normalizer/compare/1.3.5...1.3.6) (2021-02-09) + +### Changed +- Amend the previous release to allow prettytable 2.0 (PR #35) + +## [1.3.5](https://github.com/Ousret/charset_normalizer/compare/1.3.4...1.3.5) (2021-02-08) + +### Fixed +- Fix error while using the package with a python pre-release interpreter (PR #33) + +### Changed +- Dependencies refactoring, constraints revised. + +### Added +- Add python 3.9 and 3.10 to the supported interpreters + +MIT License + +Copyright (c) 2025 TAHRI Ahmed R. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA new file mode 100644 index 00000000000..c77e94b778f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.4 +Name: fastjsonschema +Version: 2.22.3 +Summary: Fastest Python implementation of JSON schema +Home-page: https://github.com/horejsek/python-fastjsonschema +Author: Michal Horejsek +Author-email: fastjsonschema@horejsek.com +License: BSD-3-Clause +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Typing :: Typed +Requires-Python: >=3.10 +License-File: LICENSE +License-File: AUTHORS +Provides-Extra: devel +Requires-Dist: colorama; extra == "devel" +Requires-Dist: jsonschema; extra == "devel" +Requires-Dist: json-spec; extra == "devel" +Requires-Dist: pylint; extra == "devel" +Requires-Dist: pytest; extra == "devel" +Requires-Dist: pytest-benchmark; extra == "devel" +Requires-Dist: pytest-cache; extra == "devel" +Requires-Dist: validictory; extra == "devel" +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: home-page +Dynamic: license +Dynamic: license-file +Dynamic: provides-extra +Dynamic: requires-python +Dynamic: summary + +=========================== +Fast JSON schema for Python +=========================== + +|PyPI| |Pythons| + +.. |PyPI| image:: https://img.shields.io/pypi/v/fastjsonschema.svg + :alt: PyPI version + :target: https://pypi.python.org/pypi/fastjsonschema + +.. |Pythons| image:: https://img.shields.io/pypi/pyversions/fastjsonschema.svg + :alt: Supported Python versions + :target: https://pypi.python.org/pypi/fastjsonschema + +See `documentation `_. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA new file mode 100644 index 00000000000..28e5ebb3a1a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA @@ -0,0 +1,215 @@ +Metadata-Version: 2.4 +Name: googleapis-common-protos +Version: 1.76.0 +Summary: Common protobufs used in Google APIs +Author-email: Google LLC +License-Expression: Apache-2.0 +Project-URL: Repository, https://github.com/googleapis/google-cloud-python/tree/main/packages/googleapis-common-protos +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Operating System :: OS Independent +Classifier: Topic :: Internet +Requires-Python: >=3.10 +Description-Content-Type: text/x-rst +License-File: LICENSE +Requires-Dist: protobuf<8.0.0,>=6.33.5 +Provides-Extra: grpc +Requires-Dist: grpcio<2.0.0,>=1.59.0; extra == "grpc" +Dynamic: license-file + +Python Client for Service Config +================================ + +|stable| |pypi| |versions| + +- `Client Library Documentation`_ + +.. |stable| image:: https://img.shields.io/badge/support-stable-gold.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels +.. |pypi| image:: https://img.shields.io/pypi/v/googleapis-common-protos.svg + :target: https://pypi.org/project/googleapis-common-protos/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/googleapis-common-protos.svg + :target: https://pypi.org/project/googleapis-common-protos/ +.. _Client Library Documentation: https://github.com/googleapis/google-cloud-python/tree/main/packages/googleapis-common-protos/summary_overview + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. `Set up Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +Installation +~~~~~~~~~~~~ + +Install this library in a virtual environment using `venv`_. `venv`_ is a tool that +creates isolated Python environments. These isolated environments can have separate +versions of Python packages, which allows you to isolate one project's dependencies +from the dependencies of other projects. + +With `venv`_, it's possible to install this library without needing system +install permissions, and without clashing with the installed system +dependencies. + +.. _`venv`: https://docs.python.org/3/library/venv.html + + +Code samples and snippets +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Code samples and snippets live in the `samples/`_ folder. + +.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/googleapis-common-protos/samples + + +Supported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^ +Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of +Python. + +Python >= 3.10, including 3.14 + +.. _active: https://devguide.python.org/devcycle/#in-development-main-branch +.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches + +Unsupported Python Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Python <= 3.9 + + +If you are using an `end-of-life`_ +version of Python, we recommend that you update as soon as possible to an actively supported version. + +.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches + +Mac/Linux +^^^^^^^^^ + +.. code-block:: console + + python3 -m venv + source /bin/activate + pip install googleapis-common-protos + + +Windows +^^^^^^^ + +.. code-block:: console + + py -m venv + .\\Scripts\activate + pip install googleapis-common-protos + +Next Steps +~~~~~~~~~~ + +- Read the `Client Library Documentation`_ for Service Config + to see other available methods on the client. +- View this `README`_ to see the full list of Cloud + APIs that we cover. + +.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst + +Logging +------- + +This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. +Note the following: + +#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. +#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. +#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. + +Simple, environment-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google +logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged +messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging +event. + +A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. + +- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. +- Invalid logging scopes: :code:`foo`, :code:`123`, etc. + +**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. + +Environment-Based Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Enabling the default handler for all Google-based loggers + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google + +- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: console + + export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 + + +Advanced, code-based configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also configure a valid logging scope using Python's standard `logging` mechanism. + +Code-Based Examples +^^^^^^^^^^^^^^^^^^^ + +- Configuring a handler for all Google-based loggers + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): + +.. code-block:: python + + import logging + + from google.cloud import library_v1 + + base_logger = logging.getLogger("google.cloud.library_v1") + base_logger.addHandler(logging.StreamHandler()) + base_logger.setLevel(logging.DEBUG) + +Logging details +~~~~~~~~~~~~~~~ + +#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root + logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set + :code:`logging.getLogger("google").propagate = True` in your code. +#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for + one library, but decide you need to also set up environment-based logging configuration for another library. + + #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual + if the code -based configuration gets applied first. + +#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get + executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. + (This is the reason for 2.i. above.) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA new file mode 100644 index 00000000000..edbc446bb4e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA @@ -0,0 +1,176 @@ +Metadata-Version: 2.5 +Name: idna +Version: 3.20 +Summary: Internationalized Domain Names in Applications (IDNA) +Author-email: Kim Davies +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-Expression: BSD-3-Clause +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +License-File: LICENSE.md +Requires-Dist: ruff >= 0.16.0 ; extra == "all" +Requires-Dist: mypy >= 1.11.2 ; extra == "all" +Requires-Dist: ty >= 0.0.37 ; extra == "all" +Requires-Dist: pytest >= 8.3.2 ; extra == "all" +Requires-Dist: hypothesis >= 6.141.1 ; extra == "all" +Requires-Dist: coverage >= 7.10.0 ; extra == "all" +Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.md +Project-URL: Issue tracker, https://github.com/kjd/idna/issues +Project-URL: Source, https://github.com/kjd/idna +Provides-Extra: all +Import-Name: idna + +# Internationalized Domain Names in Applications (IDNA) + +Support for [Internationalized Domain Names in Applications +(IDNA)](https://tools.ietf.org/html/rfc5891) and [Unicode IDNA +Compatibility Processing](https://unicode.org/reports/tr46/). It +supersedes the standard library's `encodings.idna`, which only +implements the 2003 specification, offering broader script coverage and +limiting domains with known security vulnerabilities. + +## Usage + +Package may be installed from [PyPI](https://pypi.org/project/idna/) via +the typical methods (e.g. `python3 -m pip install idna`) + +For typical usage, the `encode` and `decode` functions will take a +domain name argument and perform a conversion to ASCII-compatible encoding +(known as A-labels), or to Unicode strings (known as U-labels) +respectively. + +```pycon +>>> import idna +>>> idna.encode('ドメイン.テスト') +b'xn--eckwd4c7c.xn--zckzah' +>>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) +ドメイン.テスト +``` + +Conversions can be applied at a per-label basis using the `ulabel` or +`alabel` functions for specialized use cases. + + +### Compatibility Mapping (UTS #46) + +This library provides support for [Unicode IDNA Compatibility +Processing](https://unicode.org/reports/tr46/) which normalizes input from +different potential ways a user may input a domain prior to performing the IDNA +conversion operations. This functionality, known as a +[mapping](https://tools.ietf.org/html/rfc5895), is considered by the +specification to be a local user-interface issue distinct from IDNA +conversion functionality. + +For example, "Königsgäßchen" is not a permissible label as capital letters +are not allowed. UTS #46 will convert this into lower case prior to applying +the IDNA conversion. + +```pycon +>>> import idna +>>> idna.encode('Königsgäßchen') +... +idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed +>>> idna.encode('Königsgäßchen', uts46=True) +b'xn--knigsgchen-b4a3dun' +>>> idna.decode('xn--knigsgchen-b4a3dun') +'königsgäßchen' +``` + +When performing a decode operation for display purposes, `decode()` +accepts a `display=True` argument that leaves any `xn--` label that +fails to decode unchanged. This is useful for user interface display +where a domain is in use, the A-label form can be presented when it +is not a valid IDN. + + +## Exceptions + +All errors raised during conversion derive from the `idna.IDNAError` +base class. The more specific exceptions are: + +* `idna.IDNABidiError` — raised when a label contains an illegal + combination of left-to-right and right-to-left characters. +* `idna.InvalidCodepoint` — raised when a label contains a codepoint + that is INVALID for IDNA. +* `idna.InvalidCodepointContext` — raised when a CONTEXTO or CONTEXTJ + codepoint appears in a position whose contextual requirements are + not satisfied. + +Exceptions carry machine-readable attributes so that applications do +not need to parse the message: `code` is a short, stable identifier +for the rule that failed (such as `disallowed_codepoint` or +`label_too_long`); and, when the failure can be attributed to a +particular character, `text` (the label or domain being validated), +`codepoint` (the offending codepoint as an integer) and `position` +are set. + + +## Command-line tool + +The package supports command-line usage to convert domain names +between their Unicode and ASCII-compatible forms. It can be run either +as a module (`python3 -m idna`) or, once installed (such as with `uv +tool` or `pipx`), via the `idna` script: + +```bash +$ uv tool install idna +$ idna xn--e1afmkfd.xn--p1ai +пример.рф +$ idna пример.рф +xn--e1afmkfd.xn--p1ai +``` + +Mode can be specified with `-e`/`--encode` or `-d`/`--decode`, otherwise +it will be chosen automatically based on the first input. Multiple +domains can be supplied either as arguments or through standard input. +UTS #46 mapping is applied by default, which lets the tool accept +inputs that aren't strictly valid IDNA 2008 by normalising them first, +pass `--strict` to disable UTS #46. + +Conversion failures are reported on stderr together with the +offending input; processing continues with the remaining domains and +the tool exits with a non-zero status if any conversion failed. + + +## Additional Notes + +* **Python version support**. This library supports Python 3.9 and higher. + As this library serves as a low-level toolkit for a variety of + applications, we strive to support all versions of Python that are + not beyond end-of-life. Free-threaded Python is also supported, + as the library holds no mutable global state the functions can be + called concurrently from multiple threads. + +* **Unicode version**. The IDNA and UTS #46 lookup tables are generated + from a specific Unicode release. Some Unicode data depends on the + running Python's `unicodedata` module, so on an older Python a + character new to Unicode may be rejected as unknown even if this + library knows about it. + +* **Emoji**. It is an occasional request to support emoji domains in + this library. Encoding of symbols like emoji is expressly prohibited by + the IDNA technical standard, and emoji domains are broadly phased + out across the domain industry due to associated security risks. + +* **Regenerating lookup tables**. The IDNA and UTS #46 functionality + relies upon pre-calculated lookup tables, generated using the + `idna-data` script in [`tools/`](tools/README.md). + diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA new file mode 100644 index 00000000000..b4fbdfc3362 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA @@ -0,0 +1,43 @@ +Metadata-Version: 2.5 +Name: opentelemetry-api +Version: 1.45.2 +Summary: OpenTelemetry Python API +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-api +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: OpenTelemetry +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Typing :: Typed +Requires-Python: >=3.10 +Requires-Dist: typing-extensions>=4.5.0 +Description-Content-Type: text/x-rst + +OpenTelemetry Python API +============================================================================ + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-api.svg + :target: https://pypi.org/project/opentelemetry-api/ + +Installation +------------ + +:: + + pip install opentelemetry-api + +References +---------- + +* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt new file mode 100644 index 00000000000..cbeb844d96f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt @@ -0,0 +1,15 @@ +[opentelemetry_context] +contextvars_context = opentelemetry.agent._vendor.opentelemetry.context.contextvars_context:ContextVarsRuntimeContext + +[opentelemetry_environment_variables] +api = opentelemetry.agent._vendor.opentelemetry.environment_variables + +[opentelemetry_meter_provider] +default_meter_provider = opentelemetry.agent._vendor.opentelemetry.metrics:NoOpMeterProvider + +[opentelemetry_propagator] +baggage = opentelemetry.agent._vendor.opentelemetry.baggage.propagation:W3CBaggagePropagator +tracecontext = opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext:TraceContextTextMapPropagator + +[opentelemetry_tracer_provider] +default_tracer_provider = opentelemetry.agent._vendor.opentelemetry.trace:NoOpTracerProvider diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..f994cf53667 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA @@ -0,0 +1,73 @@ +Metadata-Version: 2.5 +Name: opentelemetry-configuration +Version: 0.66b2 +Summary: OpenTelemetry Python Declarative Configuration (experimental) +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-configuration +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +Classifier: Development Status :: 3 - Alpha +Classifier: Framework :: OpenTelemetry +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Typing :: Typed +Requires-Python: >=3.10 +Requires-Dist: jsonschema>=4.0 +Requires-Dist: opentelemetry-api==1.45.2 +Requires-Dist: opentelemetry-sdk==1.45.2 +Requires-Dist: pyyaml>=5.4 +Description-Content-Type: text/x-rst + +OpenTelemetry Python SDK Declarative Configuration +=================================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-configuration.svg + :target: https://pypi.org/project/opentelemetry-configuration/ + +.. warning:: + + This package is **experimental**. The API surface, type names, and behaviour + may change between minor versions. Pin a specific version in production. + +This package implements the `OpenTelemetry declarative configuration +specification `_ for +the Python SDK. It parses a YAML or JSON configuration file (or +programmatically-constructed configuration model) into typed dataclasses and +applies the result to the global SDK providers. + +The standard activation path is the ``OTEL_CONFIG_FILE`` environment variable, +which the SDK's configurator picks up automatically. Set the variable and run +your app under ``opentelemetry-instrument``; no code change is required. + +For programmatic use: + +.. code-block:: python + + from opentelemetry.configuration import configure_sdk, load_config_file + + config = load_config_file("otel-config.yaml") + configure_sdk(config) + +Installation +------------ + +:: + + pip install opentelemetry-configuration + +References +---------- + +* `OpenTelemetry declarative configuration specification + `_ +* `Language support status matrix + `_ +* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..8d5e3a7a367 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA @@ -0,0 +1,50 @@ +Metadata-Version: 2.5 +Name: opentelemetry-distro +Version: 0.66b2 +Summary: OpenTelemetry Python Distro +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-distro +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Typing :: Typed +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api~=1.12 +Requires-Dist: opentelemetry-instrumentation==0.66b2 +Requires-Dist: opentelemetry-sdk~=1.13 +Provides-Extra: otlp +Requires-Dist: opentelemetry-exporter-otlp==1.45.2; extra == 'otlp' +Description-Content-Type: text/x-rst + +OpenTelemetry Distro +==================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-distro.svg + :target: https://pypi.org/project/opentelemetry-distro/ + +Installation +------------ + +:: + + pip install opentelemetry-distro + + +This package provides entrypoints to configure OpenTelemetry. + +References +---------- + +* `OpenTelemetry Project `_ +* `Example using opentelemetry-distro `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt new file mode 100644 index 00000000000..fe9f6356a4e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[opentelemetry_configurator] +configurator = opentelemetry.agent._vendor.opentelemetry.distro:OpenTelemetryConfigurator + +[opentelemetry_distro] +distro = opentelemetry.agent._vendor.opentelemetry.distro:OpenTelemetryDistro diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..c997785745a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA @@ -0,0 +1,64 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-http-transport +Version: 0.66b2 +Summary: OpenTelemetry Exporters HTTP transport +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-http-transport +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api~=1.15 +Provides-Extra: requests +Requires-Dist: requests~=2.25; extra == 'requests' +Provides-Extra: urllib3 +Requires-Dist: urllib3>=1.26; extra == 'urllib3' +Description-Content-Type: text/x-rst + +OpenTelemetry Exporters HTTP Transport +====================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-http-transport.svg + :target: https://pypi.org/project/opentelemetry-exporter-http-transport/ + +This package provides shared HTTP transport abstractions used by OpenTelemetry exporters. + +The package has **no required dependencies**. The ``requests`` and ``urllib3`` +transports are available as optional extras. + +Installation +------------ + +Core package (no HTTP backend included):: + + pip install opentelemetry-exporter-http-transport + +With the ``requests`` backend:: + + pip install opentelemetry-exporter-http-transport[requests] + +With the ``urllib3`` backend:: + + pip install opentelemetry-exporter-http-transport[urllib3] + + +References +---------- + +* `OpenTelemetry `_ +* `OpenTelemetry Protocol Specification `_ +* `requests `_ +* `urllib3 `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt new file mode 100644 index 00000000000..db7882341ec --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[opentelemetry_http_transport] +requests = opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._requests:RequestsHTTPTransport +urllib3 = opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._urllib3:Urllib3HTTPTransport diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..968b0660afc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA @@ -0,0 +1,52 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-otlp-common +Version: 0.66b2 +Summary: OpenTelemetry OTLP HTTP export utilities +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-common +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-sdk~=1.45.2 +Provides-Extra: http +Requires-Dist: opentelemetry-exporter-http-transport==0.66b2; extra == 'http' +Description-Content-Type: text/x-rst + +OpenTelemetry OTLP Utilities +=============================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-common.svg + :target: https://pypi.org/project/opentelemetry-exporter-otlp-common/ + +OpenTelemetry OTLP export utilities. + +This package is intended to be used by OpenTelemetry signal exporters (traces, metrics, +logs) that send telemetry with OTLP. Currently, all functionality in this package +is marked as internal and is not intended for use directly by application developers. + +Installation +------------ + +:: + + pip install opentelemetry-exporter-otlp-common + +References +---------- + +* `OpenTelemetry `_ +* `OTLP Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..f8cefaafa0a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA @@ -0,0 +1,48 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-otlp-json-common +Version: 0.66b2 +Summary: OpenTelemetry JSON encoding +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-json-common +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-proto-json==0.66b2 +Requires-Dist: opentelemetry-sdk~=1.45.2 +Description-Content-Type: text/x-rst + +OpenTelemetry JSON Encoding +=============================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-json-common.svg + :target: https://pypi.org/project/opentelemetry-exporter-otlp-json-common/ + +This library is provided as a convenience to encode to OTLP JSON. + +Installation +------------ + +:: + + pip install opentelemetry-exporter-otlp-json-common + + +References +---------- + +* `OpenTelemetry `_ +* `OpenTelemetry Protocol Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..96439e059d4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA @@ -0,0 +1,56 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-otlp-json-file +Version: 0.66b2 +Summary: OpenTelemetry JSON File Exporter +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-json-file +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-exporter-otlp-common==0.66b2 +Requires-Dist: opentelemetry-exporter-otlp-json-common==0.66b2 +Requires-Dist: opentelemetry-sdk~=1.45.2 +Description-Content-Type: text/x-rst + +OpenTelemetry JSON File Exporter +================================ + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-json-file.svg + :target: https://pypi.org/project/opentelemetry-exporter-otlp-json-file/ + +This library exports telemetry as OTLP JSON to a file-like text stream, such +as a file or stdout. + +The exporter writes newline delimited OTLP JSON records for file-based +collection workflows. + +Installation +------------ + +:: + + pip install opentelemetry-exporter-otlp-json-file + + +References +---------- + +* `OpenTelemetry Project `_ +* `OpenTelemetry Protocol File Exporter `_ +* `OTLP Specification `_ +* `OTLP JSON Encoding Specification `_ +* `JSON Lines `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt new file mode 100644 index 00000000000..e4216b3db77 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt @@ -0,0 +1,8 @@ +[opentelemetry_logs_exporter] +otlp_json_file = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._log_exporter:FileLogExporter + +[opentelemetry_metrics_exporter] +otlp_json_file = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.metric_exporter:FileMetricExporter + +[opentelemetry_traces_exporter] +otlp_json_file = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.trace_exporter:FileSpanExporter diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..243c38d1f7a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA @@ -0,0 +1,85 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-otlp-json-http +Version: 0.66b2 +Summary: OpenTelemetry OTLP JSON Exporter +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-json-http +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-exporter-http-transport[urllib3]==0.66b2 +Requires-Dist: opentelemetry-exporter-otlp-common==0.66b2 +Requires-Dist: opentelemetry-exporter-otlp-json-common==0.66b2 +Requires-Dist: opentelemetry-proto-json==0.66b2 +Requires-Dist: opentelemetry-sdk~=1.45.2 +Description-Content-Type: text/x-rst + +OpenTelemetry Collector JSON over HTTP Exporter +================================================ + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-json-http.svg + :target: https://pypi.org/project/opentelemetry-exporter-otlp-json-http/ + +This library exports OpenTelemetry traces, metrics and logs using the +OpenTelemetry Protocol (OTLP) JSON encoding over HTTP. It can be used to +send data to any backend that accepts OTLP JSON such as the OpenTelemetry +Collector. + +Installation +------------ + +:: + + pip install opentelemetry-exporter-otlp-json-http + + +Usage +----- + +.. code:: python + + from opentelemetry import trace + from opentelemetry.exporter.otlp.json.http import OTLPSpanExporter + from opentelemetry.sdk.resources import Resource + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchSpanProcessor + + resource = Resource.create({ + "service.name": "service" + }) + + trace.set_tracer_provider(TracerProvider(resource=resource)) + tracer = trace.get_tracer(__name__) + + otlp_exporter = OTLPSpanExporter() + + span_processor = BatchSpanProcessor(otlp_exporter) + + trace.get_tracer_provider().add_span_processor(span_processor) + + with tracer.start_as_current_span("foo"): + print("Hello world!") + + +References +---------- + +* `OpenTelemetry OTLP Exporters `_ +* `OpenTelemetry Collector `_ +* `OpenTelemetry `_ +* `OpenTelemetry Protocol Specification `_ +* `OTLP JSON Encoding Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt new file mode 100644 index 00000000000..7b536dbd717 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt @@ -0,0 +1,8 @@ +[opentelemetry_logs_exporter] +otlp_json_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._log_exporter:OTLPLogExporter + +[opentelemetry_metrics_exporter] +otlp_json_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.metric_exporter:OTLPMetricExporter + +[opentelemetry_traces_exporter] +otlp_json_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.trace_exporter:OTLPSpanExporter diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA new file mode 100644 index 00000000000..fccb1c28a26 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA @@ -0,0 +1,51 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-otlp-proto-common +Version: 1.45.2 +Summary: OpenTelemetry Protobuf encoding +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-common +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-proto==1.45.2 +Description-Content-Type: text/x-rst + +OpenTelemetry Protobuf Encoding +=============================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-proto-common.svg + :target: https://pypi.org/project/opentelemetry-exporter-otlp-proto-common/ + +This library is provided as a convenience to encode to Protobuf. Currently used by: + +* opentelemetry-exporter-otlp-proto-grpc +* opentelemetry-exporter-otlp-proto-http + + +Installation +------------ + +:: + + pip install opentelemetry-exporter-otlp-proto-common + + +References +---------- + +* `OpenTelemetry `_ +* `OpenTelemetry Protocol Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA new file mode 100644 index 00000000000..f954db2a7de --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA @@ -0,0 +1,71 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-otlp-proto-http +Version: 1.45.2 +Summary: OpenTelemetry Collector Protobuf over HTTP Exporter +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-http +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: googleapis-common-protos~=1.52 +Requires-Dist: opentelemetry-api~=1.15 +Requires-Dist: opentelemetry-exporter-http-transport[requests]==0.66b2 +Requires-Dist: opentelemetry-exporter-otlp-common==0.66b2 +Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.45.2 +Requires-Dist: opentelemetry-proto==1.45.2 +Requires-Dist: opentelemetry-sdk~=1.45.2 +Requires-Dist: requests~=2.7 +Requires-Dist: typing-extensions>=4.5.0 +Provides-Extra: gcp-auth +Requires-Dist: opentelemetry-exporter-credential-provider-gcp>=0.59b0; extra == 'gcp-auth' +Provides-Extra: requests +Requires-Dist: opentelemetry-exporter-http-transport[requests]==0.66b2; extra == 'requests' +Requires-Dist: requests~=2.7; extra == 'requests' +Description-Content-Type: text/x-rst + +OpenTelemetry Collector Protobuf over HTTP Exporter +=================================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-proto-http.svg + :target: https://pypi.org/project/opentelemetry-exporter-otlp-proto-http/ + +This library allows to export data to the OpenTelemetry Collector using the OpenTelemetry Protocol using Protobuf over HTTP. + +Installation +------------ + +:: + + pip install opentelemetry-exporter-otlp-proto-http + +To use a custom ``requests.Session`` (for example to configure authentication), pass it to the exporter: + +.. code-block:: python + + import requests + from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter + + exporter = OTLPSpanExporter(session=requests.Session()) + + +References +---------- + +* `OpenTelemetry Collector Exporter `_ +* `OpenTelemetry Collector `_ +* `OpenTelemetry `_ +* `OpenTelemetry Protocol Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt new file mode 100644 index 00000000000..90e636b44ff --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt @@ -0,0 +1,8 @@ +[opentelemetry_logs_exporter] +otlp_proto_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._log_exporter:OTLPLogExporter + +[opentelemetry_metrics_exporter] +otlp_proto_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.metric_exporter:OTLPMetricExporter + +[opentelemetry_traces_exporter] +otlp_proto_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.trace_exporter:OTLPSpanExporter diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..0f52dc8a6d5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA @@ -0,0 +1,54 @@ +Metadata-Version: 2.5 +Name: opentelemetry-exporter-prometheus +Version: 0.66b2 +Summary: Prometheus Metric Exporter for OpenTelemetry +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-prometheus +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: OpenTelemetry +Classifier: Framework :: OpenTelemetry :: Exporters +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api~=1.12 +Requires-Dist: opentelemetry-sdk~=1.45.2 +Requires-Dist: prometheus-client<1.0.0,>=0.5.0 +Description-Content-Type: text/x-rst + +OpenTelemetry Prometheus Exporter +================================= + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-prometheus.svg + :target: https://pypi.org/project/opentelemetry-exporter-prometheus/ + +This library allows to export metrics data to `Prometheus `_. + +Installation +------------ + +:: + + pip install opentelemetry-exporter-prometheus + +Limitations +----------- + +* No multiprocessing support: The Prometheus exporter is not designed to operate in multiprocessing environments (see `#3747 `_). + +References +---------- + +* `OpenTelemetry Prometheus Exporter `_ +* `Prometheus `_ +* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt new file mode 100644 index 00000000000..8c6d2fe3079 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[opentelemetry_metrics_exporter] +prometheus = opentelemetry.agent._vendor.opentelemetry.exporter.prometheus:_AutoPrometheusMetricReader diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..ed292af545f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA @@ -0,0 +1,183 @@ +Metadata-Version: 2.5 +Name: opentelemetry-instrumentation +Version: 0.66b2 +Summary: Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-instrumentation +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api~=1.4 +Requires-Dist: opentelemetry-semantic-conventions==0.66b2 +Requires-Dist: packaging>=18.0 +Requires-Dist: wrapt<3.0.0,>=1.0.0 +Description-Content-Type: text/x-rst + +OpenTelemetry Instrumentation +============================= + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation.svg + :target: https://pypi.org/project/opentelemetry-instrumentation/ + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation + + +This package provides commands that help automatically instrument a program: + +.. note:: + You need to install a distro package to get auto instrumentation working. The ``opentelemetry-distro`` + package contains the default distro and configurator and automatically configures some of the common options for users. + For more info about ``opentelemetry-distro`` check `here `__ + :: + + pip install "opentelemetry-distro[otlp]" + + When creating a custom distro and/or configurator, be sure to add entry points for each under ``opentelemetry_distro`` and ``opentelemetry_configurator`` respectfully. + If you have entry points for multiple distros or configurators present in your environment, you should specify the entry point name of the distro and configurator you want to be used via the ``OTEL_PYTHON_DISTRO`` and ``OTEL_PYTHON_CONFIGURATOR`` environment variables. + + +opentelemetry-bootstrap +----------------------- + +:: + + opentelemetry-bootstrap [-a |--action=][install|requirements] + +This command install default instrumentation packages and detects active Python site-packages +to figure out which instrumentation packages the user might want to install. By default, it +prints out a list of the default and detected instrumentation packages that can be added to a +requirements.txt file. It also supports installing the packages when run with +:code:`--action=install` or :code:`-a install` flag. All default and detectable +instrumentation packages are defined `here `__. + + +opentelemetry-instrument +------------------------ + +:: + + opentelemetry-instrument python program.py + +The instrument command will try to automatically detect packages used by your python program +and when possible, apply automatic tracing instrumentation on them. This means your program +will get automatic distributed tracing without having to make any code changes. This will +also configure a global tracer and tracing exporter as well as a meter and meter exporter. +By default, the instrument command will use the OTLP exporter but this can be overridden. + +The command supports the following configuration options as CLI arguments and environment +variables: + + +* ``--traces_exporter`` or ``OTEL_TRACES_EXPORTER`` +* ``--metrics_exporter`` or ``OTEL_METRICS_EXPORTER`` +* ``--distro`` or ``OTEL_PYTHON_DISTRO`` +* ``--configurator`` or ``OTEL_PYTHON_CONFIGURATOR`` + +The exporter options define what exporter destination to use and can be set to one or more +exporter names (see below). You can pass multiple values to configure multiple exporters +(e.g., ``zipkin_json,otlp``). + + - Defaults to ``otlp``. + - Can be set to ``none`` to disable automatic tracer initialization. + - Can be set to ``console`` to display JSON results locally. + +Trace exporter names: + + - jaeger_proto + - jaeger_thrift + - opencensus + - otlp + - otlp_proto_grpc (``deprecated``) + - otlp_proto_http (``deprecated``) + - zipkin_json + - zipkin_proto + +Metric exporter names: + + - otlp + - otlp_proto_grpc (``deprecated``) + - prometheus + +Note: The default transport protocol for ``otlp`` is gRPC. + +* ``--id-generator`` or ``OTEL_PYTHON_ID_GENERATOR`` + +Used to specify which IDs Generator to use for the global Tracer Provider. By default, it +will use the random IDs generator. + +The code in ``program.py`` needs to use one of the packages for which there is +an OpenTelemetry integration. For a list of the available integrations please +check `here `_ + +* ``OTEL_PYTHON_DISABLED_INSTRUMENTATIONS`` + +If set by the user, opentelemetry-instrument will read this environment variable to disable specific instrumentations. +e.g OTEL_PYTHON_DISABLED_INSTRUMENTATIONS="requests,django" + +If the variables contains ``*`` as member no instrumentation will be enabled. + +* ``OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH`` + +If set by the user to ``patch_all`` , opentelemetry instrument will call the gevent monkeypatching method ``patch_all``. +This is considered experimental but can be useful to instrument gevent applications. +e.g OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH=patch_all + + +Examples +^^^^^^^^ + +:: + + opentelemetry-instrument --traces_exporter console flask run --port=3000 + +The above command will pass ``--traces_exporter console`` to the instrument command and ``--port=3000`` to ``flask run``. + +:: + + opentelemetry-instrument --traces_exporter zipkin_json,otlp celery -A tasks worker --loglevel=info + +The above command will configure global trace provider, attach zipkin and otlp exporters to it and then +start celery with the rest of the arguments. + +:: + + opentelemetry-instrument --id_generator random flask run --port=3000 + +The above command will configure the global trace provider to use the Random IDs Generator, and then +pass ``--port=3000`` to ``flask run``. + +Programmatic Auto-instrumentation +--------------------------------- + +:: + + from opentelemetry.instrumentation import auto_instrumentation + auto_instrumentation.initialize() + + +If you are in an environment where you cannot use opentelemetry-instrument to inject auto-instrumentation you can do so programmatically with +the code above. Please note that some instrumentations may require the ``initialize()`` method to be called before the library they +instrument is imported. + +References +---------- + +* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt new file mode 100644 index 00000000000..bc231f53300 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[opentelemetry_environment_variables] +instrumentation = opentelemetry.agent._vendor.opentelemetry.instrumentation.environment_variables diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..c8a15ebe07c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA @@ -0,0 +1,54 @@ +Metadata-Version: 2.5 +Name: opentelemetry-instrumentation-aiohttp-client +Version: 0.66b2 +Summary: OpenTelemetry aiohttp client instrumentation +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aiohttp-client +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api~=1.12 +Requires-Dist: opentelemetry-instrumentation==0.66b2 +Requires-Dist: opentelemetry-semantic-conventions==0.66b2 +Requires-Dist: opentelemetry-util-http==0.66b2 +Requires-Dist: wrapt<3.0.0,>=1.0.0 +Provides-Extra: instruments +Requires-Dist: aiohttp~=3.0; extra == 'instruments' +Description-Content-Type: text/x-rst + +OpenTelemetry aiohttp client Integration +======================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-aiohttp-client.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-aiohttp-client/ + +This library allows tracing HTTP requests made by the +`aiohttp client `_ library. + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation-aiohttp-client + +References +---------- + +* `OpenTelemetry aiohttp client Instrumentation `_ +* `aiohttp Tracing Reference `_ +* `OpenTelemetry Project `_ +* `OpenTelemetry Python Examples `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt new file mode 100644 index 00000000000..36da1631192 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[opentelemetry_instrumentor] +aiohttp-client = opentelemetry.agent._vendor.opentelemetry.instrumentation.aiohttp_client:AioHttpClientInstrumentor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA new file mode 100644 index 00000000000..33116e71c92 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA @@ -0,0 +1,48 @@ +Metadata-Version: 2.5 +Name: opentelemetry-propagator-b3 +Version: 1.45.2 +Summary: OpenTelemetry B3 Propagator +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/propagator/opentelemetry-propagator-b3 +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: OpenTelemetry +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Typing :: Typed +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api~=1.3 +Requires-Dist: typing-extensions>=4.5.0 +Description-Content-Type: text/x-rst + +OpenTelemetry B3 Propagator +=========================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-propagator-b3.svg + :target: https://pypi.org/project/opentelemetry-propagator-b3/ + +This library provides a propagator for the B3 format + +Installation +------------ + +:: + + pip install opentelemetry-propagator-b3 + + +References +---------- + +* `OpenTelemetry `_ +* `B3 format `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt new file mode 100644 index 00000000000..c3eb07abc06 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[opentelemetry_propagator] +b3 = opentelemetry.agent._vendor.opentelemetry.propagators.b3:B3SingleFormat +b3multi = opentelemetry.agent._vendor.opentelemetry.propagators.b3:B3MultiFormat diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA new file mode 100644 index 00000000000..9c4992f10ba --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA @@ -0,0 +1,63 @@ +Metadata-Version: 2.5 +Name: opentelemetry-proto +Version: 1.45.2 +Summary: OpenTelemetry Python Proto +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-proto +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: OpenTelemetry +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: protobuf<8.0,>=5.0 +Description-Content-Type: text/x-rst + +OpenTelemetry Python Proto +========================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-proto.svg + :target: https://pypi.org/project/opentelemetry-proto/ + +This library contains the generated code for OpenTelemetry protobuf data model. The code in the current +package was generated using the v1.10.0 release_ of opentelemetry-proto. + +.. _release: https://github.com/open-telemetry/opentelemetry-proto/releases/tag/v1.10.0 + +Installation +------------ + +:: + + pip install opentelemetry-proto + +Code Generation +--------------- + +These files were generated automatically from code in opentelemetry-proto_. +To regenerate the code, run ``../scripts/proto_codegen.sh``. + +To build against a new release or specific commit of opentelemetry-proto_, +update the ``PROTO_REPO_BRANCH_OR_COMMIT`` variable in +``../scripts/proto_codegen.sh``. Then run the script and commit the changes +as well as any fixes needed in the OTLP exporter. + +.. _opentelemetry-proto: https://github.com/open-telemetry/opentelemetry-proto + + +References +---------- + +* `OpenTelemetry Project `_ +* `OpenTelemetry Proto `_ +* `proto_codegen.sh script `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..6ed6c74c2e0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA @@ -0,0 +1,61 @@ +Metadata-Version: 2.5 +Name: opentelemetry-proto-json +Version: 0.66b2 +Summary: OpenTelemetry Python Json Proto +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-proto-json +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 4 - Beta +Classifier: Framework :: OpenTelemetry +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Description-Content-Type: text/x-rst + +OpenTelemetry Python Proto JSON +================================ + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-proto-json.svg + :target: https://pypi.org/project/opentelemetry-proto-json/ + +This library contains the generated code for OpenTelemetry protobuf data model with JSON encoding support. The code in the current package was generated using the v1.10.0 release_ of opentelemetry-proto and includes definitions for the OpenTelemetry JSON Protobuf encoding specification. + +.. _release: https://github.com/open-telemetry/opentelemetry-proto/releases/tag/v1.10.0 + +Installation +------------ + +:: + + pip install opentelemetry-proto-json + +Code Generation +--------------- + +These files were generated automatically using the custom protoc plugin opentelemetry-codegen-json_ from code in opentelemetry-proto_. +To regenerate the code, run ``../scripts/proto_codegen_json.sh``. + +To build against a new release or specific commit of opentelemetry-proto_, +update the ``PROTO_REPO_BRANCH_OR_COMMIT`` variable in +``../scripts/proto_codegen_json.sh``. Then run the script and commit the changes +as well as any fixes needed in the OTLP exporter. + +.. _opentelemetry-codegen-json: https://github.com/open-telemetry/opentelemetry-python/tree/main/codegen/opentelemetry-codegen-json +.. _opentelemetry-proto: https://github.com/open-telemetry/opentelemetry-proto + +References +---------- + +* `OpenTelemetry Project `_ +* `OpenTelemetry Proto `_ +* `OTLP JSON Encoding Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA new file mode 100644 index 00000000000..1d729d35c7f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA @@ -0,0 +1,47 @@ +Metadata-Version: 2.5 +Name: opentelemetry-sdk +Version: 1.45.2 +Summary: OpenTelemetry Python SDK +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-sdk +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: OpenTelemetry +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Typing :: Typed +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api==1.45.2 +Requires-Dist: opentelemetry-semantic-conventions==0.66b2 +Requires-Dist: typing-extensions>=4.5.0 +Provides-Extra: file-configuration +Requires-Dist: opentelemetry-configuration==0.66b2; extra == 'file-configuration' +Description-Content-Type: text/x-rst + +OpenTelemetry Python SDK +============================================================================ + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-sdk.svg + :target: https://pypi.org/project/opentelemetry-sdk/ + +Installation +------------ + +:: + + pip install opentelemetry-sdk + +References +---------- + +* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt new file mode 100644 index 00000000000..cd7169588ba --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt @@ -0,0 +1,38 @@ +[opentelemetry_environment_variables] +sdk = opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables + +[opentelemetry_id_generator] +random = opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator:RandomIdGenerator + +[opentelemetry_logger_provider] +sdk_logger_provider = opentelemetry.agent._vendor.opentelemetry.sdk._logs:LoggerProvider + +[opentelemetry_logs_exporter] +console = opentelemetry.agent._vendor.opentelemetry.sdk._logs.export:ConsoleLogRecordExporter + +[opentelemetry_meter_provider] +sdk_meter_provider = opentelemetry.agent._vendor.opentelemetry.sdk.metrics:MeterProvider + +[opentelemetry_metrics_exporter] +console = opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export:ConsoleMetricExporter + +[opentelemetry_resource_detector] +host = opentelemetry.agent._vendor.opentelemetry.sdk.resources:_HostResourceDetector +os = opentelemetry.agent._vendor.opentelemetry.sdk.resources:OsResourceDetector +otel = opentelemetry.agent._vendor.opentelemetry.sdk.resources:OTELResourceDetector +process = opentelemetry.agent._vendor.opentelemetry.sdk.resources:ProcessResourceDetector +service_instance = opentelemetry.agent._vendor.opentelemetry.sdk.resources:ServiceInstanceIdResourceDetector + +[opentelemetry_tracer_provider] +sdk_tracer_provider = opentelemetry.agent._vendor.opentelemetry.sdk.trace:TracerProvider + +[opentelemetry_traces_exporter] +console = opentelemetry.agent._vendor.opentelemetry.sdk.trace.export:ConsoleSpanExporter + +[opentelemetry_traces_sampler] +always_off = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_AlwaysOff +always_on = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_AlwaysOn +parentbased_always_off = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_ParentBasedAlwaysOff +parentbased_always_on = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_ParentBasedAlwaysOn +parentbased_traceidratio = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:ParentBasedTraceIdRatio +traceidratio = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:TraceIdRatioBased diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..86aaf5fd11f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA @@ -0,0 +1,61 @@ +Metadata-Version: 2.5 +Name: opentelemetry-semantic-conventions +Version: 0.66b2 +Summary: OpenTelemetry Semantic Conventions +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-semantic-conventions +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +License-File: LICENSE +Classifier: Development Status :: 5 - Production/Stable +Classifier: Framework :: OpenTelemetry +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Requires-Dist: opentelemetry-api==1.45.2 +Requires-Dist: typing-extensions>=4.5.0 +Description-Content-Type: text/x-rst + +OpenTelemetry Semantic Conventions +================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-semantic-conventions.svg + :target: https://pypi.org/project/opentelemetry-semantic-conventions/ + +This library contains generated code for the semantic conventions defined by the OpenTelemetry specification. + +Installation +------------ + +:: + + pip install opentelemetry-semantic-conventions + +Code Generation +--------------- + +These files were generated automatically from code in semconv_. +To regenerate the code, run ``../scripts/semconv/generate.sh``. + +To build against a new release or specific commit of opentelemetry-specification_, +update the ``SPEC_VERSION`` variable in +``../scripts/semconv/generate.sh``. Then run the script and commit the changes. + +.. _opentelemetry-specification: https://github.com/open-telemetry/opentelemetry-specification +.. _semconv: https://github.com/open-telemetry/opentelemetry-python/tree/main/scripts/semconv + + +References +---------- + +* `OpenTelemetry Project `_ +* `OpenTelemetry Semantic Conventions Definitions `_ +* `generate.sh script `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA new file mode 100644 index 00000000000..4daea2c52c7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA @@ -0,0 +1,93 @@ +Metadata-Version: 2.5 +Name: opentelemetry-util-http +Version: 0.66b2 +Summary: Web util for OpenTelemetry +Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/util/opentelemetry-util-http +Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib +Author-email: OpenTelemetry Authors +License-Expression: Apache-2.0 +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Description-Content-Type: text/x-rst + +OpenTelemetry Util HTTP +======================= + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-util-http.svg + :target: https://pypi.org/project/opentelemetry-util-http/ + + +This library provides ASGI, WSGI middleware and other HTTP-related +functionality that is common to instrumented web frameworks (such as Django, +Starlette, FastAPI, etc.) to track requests timing through OpenTelemetry. + +Installation +------------ + +:: + + pip install opentelemetry-util-http + + +Usage (Quart) +------------- + +.. code-block:: python + + from quart import Quart + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + + app = Quart(__name__) + app.asgi_app = OpenTelemetryMiddleware(app.asgi_app) + + @app.route("/") + async def hello(): + return "Hello!" + + if __name__ == "__main__": + app.run(debug=True) + + +Usage (Django 3.0) +------------------ + +Modify the application's ``asgi.py`` file as shown below. + +.. code-block:: python + + import os + from django.core.asgi import get_asgi_application + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'asgi_example.settings') + + application = get_asgi_application() + application = OpenTelemetryMiddleware(application) + + +Usage (Raw ASGI) +---------------- + +.. code-block:: python + + from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware + + app = ... # An ASGI application. + app = OpenTelemetryMiddleware(app) + + +References +---------- + +* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA new file mode 100644 index 00000000000..9a85a75b1f5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA @@ -0,0 +1,112 @@ +Metadata-Version: 2.4 +Name: packaging +Version: 26.3 +Summary: Core utilities for Python packages +Author-email: Donald Stufft +Requires-Python: >=3.9 +Description-Content-Type: text/x-rst +License-Expression: Apache-2.0 OR BSD-2-Clause +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient +Classifier: Typing :: Typed +License-File: LICENSE +License-File: LICENSE.APACHE +License-File: LICENSE.BSD +Project-URL: Documentation, https://packaging.pypa.io/ +Project-URL: Source, https://github.com/pypa/packaging + +packaging +========= + +.. start-intro + +Reusable core utilities for various Python Packaging +`interoperability specifications `_. + +This library provides utilities that implement the interoperability +specifications which have clearly one correct behaviour (eg: :pep:`440`) +or benefit greatly from having a single shared implementation (eg: :pep:`425`). + +.. end-intro + +The ``packaging`` project includes the following: version handling, specifiers, +markers, requirements, tags, metadata, lockfiles, utilities. + +Documentation +------------- + +The `documentation`_ provides information and the API for the following: + +- Version Handling +- Specifiers +- Markers +- Licenses +- Requirements +- Metadata +- Tags +- Lockfiles (pylock) +- Direct URL helpers +- Dependency groups +- Errors +- Utilities + +Installation +------------ + +Use ``pip`` to install these utilities:: + + pip install packaging + +The ``packaging`` library uses calendar-based versioning (``YY.N``). + +Discussion +---------- + +If you run into bugs, you can file them in our `issue tracker`_. + +You can also join discussions on `GitHub Discussions`_ to ask questions or get involved. + +.. _`documentation`: https://packaging.pypa.io/ +.. _`issue tracker`: https://github.com/pypa/packaging/issues +.. _`GitHub Discussions`: https://github.com/pypa/packaging/discussions + + +Code of Conduct +--------------- + +Everyone interacting in the packaging project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_. + +.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md + +Contributing +------------ + +The ``CONTRIBUTING.rst`` file outlines how to contribute to this project as +well as how to report a potential security issue. The documentation for this +project also covers information about `project development`_ and `security`_. + +.. _`project development`: https://packaging.pypa.io/en/latest/development/ +.. _`security`: https://packaging.pypa.io/en/latest/security/ + +Project History +--------------- + +Please review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for +recent changes and project history. + +.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/ + diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA new file mode 100644 index 00000000000..83c1c59e321 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA @@ -0,0 +1,56 @@ +Metadata-Version: 2.4 +Name: prometheus_client +Version: 0.26.0 +Summary: Python client for the Prometheus monitoring system. +Author-email: The Prometheus Authors +License-Expression: Apache-2.0 AND BSD-2-Clause +Project-URL: Homepage, https://github.com/prometheus/client_python +Project-URL: Documentation, https://prometheus.github.io/client_python/ +Keywords: prometheus,monitoring,instrumentation,client +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: Intended Audience :: System Administrators +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: System :: Monitoring +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-File: LICENSE +License-File: NOTICE +Provides-Extra: twisted +Requires-Dist: twisted; extra == "twisted" +Provides-Extra: aiohttp +Requires-Dist: aiohttp; extra == "aiohttp" +Provides-Extra: django +Requires-Dist: django; extra == "django" +Dynamic: license-file + +# Prometheus Python Client + +The official Python client for [Prometheus](https://prometheus.io). + +## Installation + +``` +pip install prometheus-client +``` + +This package can be found on [PyPI](https://pypi.python.org/pypi/prometheus_client). + +## Documentation + +Documentation is available on https://prometheus.github.io/client_python + +## Links + +* [Releases](https://github.com/prometheus/client_python/releases): The releases page shows the history of the project and acts as a changelog. +* [PyPI](https://pypi.python.org/pypi/prometheus_client) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA new file mode 100644 index 00000000000..ee1cbed7414 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA @@ -0,0 +1,17 @@ +Metadata-Version: 2.1 +Name: protobuf +Author: protobuf@googlegroups.com +Author-email: protobuf@googlegroups.com +Home-page: https://developers.google.com/protocol-buffers/ +License: 3-Clause BSD License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Version: 7.36.2 + +UNKNOWN diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA new file mode 100644 index 00000000000..cfc3f948ea8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA @@ -0,0 +1,120 @@ +Metadata-Version: 2.4 +Name: requests +Version: 2.34.2 +Summary: Python HTTP for Humans. +Author-email: Kenneth Reitz +Maintainer-email: Ian Stapleton Cordasco , Nate Prewitt +License: Apache-2.0 +Project-URL: Documentation, https://requests.readthedocs.io +Project-URL: Source, https://github.com/psf/requests +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Natural Language :: English +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries +Requires-Python: >=3.10 +Description-Content-Type: text/markdown +License-File: LICENSE +License-File: NOTICE +Requires-Dist: charset_normalizer<4,>=2 +Requires-Dist: idna<4,>=2.5 +Requires-Dist: urllib3<3,>=1.26 +Requires-Dist: certifi>=2023.5.7 +Provides-Extra: security +Provides-Extra: socks +Requires-Dist: PySocks!=1.5.7,>=1.5.6; extra == "socks" +Provides-Extra: use-chardet-on-py3 +Requires-Dist: chardet<8,>=3.0.2; extra == "use-chardet-on-py3" +Dynamic: license-file + +# Requests + +[![Version](https://img.shields.io/pypi/v/requests.svg?maxAge=86400)](https://pypi.org/project/requests/) +[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests) +[![Downloads](https://static.pepy.tech/badge/requests/month)](https://pepy.tech/project/requests) +[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors) +[![Documentation](https://readthedocs.org/projects/requests/badge/?version=latest)](https://requests.readthedocs.io) + +**Requests** is a simple, yet elegant, HTTP library. + +```python +>>> import requests +>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass')) +>>> r.status_code +200 +>>> r.headers['content-type'] +'application/json; charset=utf8' +>>> r.encoding +'utf-8' +>>> r.text +'{"authenticated": true, ...' +>>> r.json() +{'authenticated': True, ...} +``` + +Requests allows you to send HTTP/1.1 requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data — but nowadays, just use the `json` method! + +Requests is one of the most downloaded Python packages today, pulling in around `300M downloads / week` — according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `4,000,000+` repositories. + +## Installing Requests and Supported Versions + +Requests is available on PyPI: + +```console +$ python -m pip install requests +``` + +Requests officially supports Python 3.10+. + +## Supported Features & Best–Practices + +Requests is ready for the demands of building robust and reliable HTTP–speaking applications, for the needs of today. + +- Keep-Alive & Connection Pooling +- International Domains and URLs +- Sessions with Cookie Persistence +- Browser-style TLS/SSL Verification +- Basic & Digest Authentication +- Familiar `dict`–like Cookies +- Automatic Content Decompression and Decoding +- Multi-part File Uploads +- SOCKS Proxy Support +- Connection Timeouts +- Streaming Downloads +- Automatic honoring of `.netrc` +- Chunked HTTP Requests + +## Cloning the repository + +When cloning the Requests repository, you may need to add the `-c +fetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit timestamp (see +[this issue](https://github.com/psf/requests/issues/2690) for more background): + +```shell +git clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git +``` + +You can also apply this setting to your global Git config: + +```shell +git config --global fetch.fsck.badTimezone ignore +``` + +--- + +[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA new file mode 100644 index 00000000000..1340d3623fa --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA @@ -0,0 +1,317 @@ +Metadata-Version: 2.4 +Name: ruamel.yaml +Version: 0.19.1 +Summary: ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order +Author: Anthon van der Neut +Author-email: a.van.der.neut@ruamel.eu +License: MIT +Project-URL: Home, https://sourceforge.net/p/ruamel-yaml/ +Project-URL: Source, https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/ +Project-URL: Tracker, https://sourceforge.net/p/ruamel-yaml/tickets/ +Project-URL: Documentation, https://yaml.dev/doc/ruamel.yaml +Keywords: yaml 1.2 parser round-trip preserve quotes order config +Classifier: Development Status :: 4 - Beta +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup +Classifier: Typing :: Typed +Requires-Python: >=3.9 +Description-Content-Type: text/markdown; charset=UTF-8; variant=CommonMark +License-File: LICENSE +Provides-Extra: oldlibyaml +Requires-Dist: ruamel.yaml.clib; platform_python_implementation == "CPython" and extra == "oldlibyaml" +Provides-Extra: libyaml +Requires-Dist: ruamel.yaml.clibz>=0.3.7; platform_python_implementation == "CPython" and extra == "libyaml" +Provides-Extra: jinja2 +Requires-Dist: ruamel.yaml.jinja2>=0.2; extra == "jinja2" +Provides-Extra: docs +Requires-Dist: ryd; extra == "docs" +Requires-Dist: mercurial>5.7; extra == "docs" +Dynamic: author +Dynamic: author-email +Dynamic: classifier +Dynamic: description +Dynamic: description-content-type +Dynamic: keywords +Dynamic: license +Dynamic: license-file +Dynamic: project-url +Dynamic: provides-extra +Dynamic: requires-python +Dynamic: summary + +# ruamel.yaml + +`ruamel.yaml` is a YAML 1.2 loader/dumper package for Python. + +| | | +| - | - | +| version |0.19.0 | +| updated |2025-01-02 | +| documentation |https://yaml.dev/doc/ruamel.yaml | +| repository |https://sourceforge.net/projects/ruamel-yaml | +| pypi |https://pypi.org/project/ruamel.yaml | + + +## breaking changes, that may make future uploads to PyPI impossible + +*If you are interested in future upgrades of `ruamel.yaml` +please check the [documentation on installing](https://yaml.dev/doc/ruamel.yaml/install/), +since at some point I might not be able to upload a new version to PyPI with updated information.* + +`ruamel.yaml` was intentionally named as `yaml` in a namespace `ruamel`. The namespace allows the installation +name to correspond unchanged to how the package is imported, reduces the number of links I have to create +in site-packages of a Python install during development, as well as providing a recognisable set of packages +my company releases to the public. + +However, after uploading version 0.18.7, I got an email from PyPI, about having to change the project name +to `ruamel_yaml` to comply with PEP 625, sometime in the future. The email doesn't say if namespace packages are +no longer allowed, or how to deal with the very real clash with the pre-existing package `ruamel_yaml`. + +I might not be able to adapt `ruamel.yaml`, in +a way that does not negatively affect the 0.5 million daily downloads (and my own usage of the package) in time. +My experience with other such service downgrades (Bitbucket, Readthedocs), has not been entirely positive. + +----- + + + +Starting with 0.19.1 `ruamel.yaml` no longer has a dependency on `ruamel.yaml.clibz` +nor on the old `ruamel.yaml.clib`. + +Some deployment issues were reported on 0.19.0, due to the lack of proper pinning of the +`ruamel.yaml` version used. Most of these issues had to do with +the environment not having updated `setuptools` installed and the build +dependency `setuptools-zig` for `ruamel.yaml.clibz` not being invoked, with +Python falling back to invoking gcc (which was even less likely to be installed). + +The already indicated simple solution of using: + +``` + python -m pip install --no-deps ruamel.yaml ruamel.yaml.clib + +``` +turned out not to work for at least one setup. + +As I am not aware that you can create an install requirement that removes +a dependency, the default (Cython) dependency is removed and you should +use `ruamel.yaml[libyaml]` resp. `ruamel.yaml[oldlibyaml]` as your requirements. +(this is the preferred way over using `ruamel.yaml.clibz` and `ruamel.yaml.clib` +directly). +If you are using `ruamel.yaml` in its default (round-trip, `YAML(typ='rt')`) mode, +there is currently no advantage of installing either optional extension. + + +The C sources are functionally unchanged, +but they are now always compiled (using `setuptools-zig` and `ziglang`) on your system, +instead of being downloaded as pre-compiled wheels (if available). +For this to function properly your Python (virtual) environment needs to have +an up-to-date version of `setuptools` and `wheels` pre-installed. + +The code to load `ruamel.yaml.clib` has priority over `ruamel.yaml.clibz` +if both are installed. +This compatibility will at least be available during the 0.19 `ruamel.yaml` series +(so pin your usage of `ruamel.yaml` if necessary and report any problems). + +The motivitation for this change is the availability, +and easy of use, of Zig as the toolchain +(in the form of `ziglang` on PyPi), so lenghty, non-optimized, +pre-compilation and uploading to PyPI, +is no longer necessary. +The time spent on creating ~60 wheels +and even more time wasted on dealing with CI providers (Appveyor +not being updated to support 3.14, Github CI being slow, +and charging for the use of your own computer, +etc). + +The split out of `ruamel.yaml.clib` after the 0.15.100 release, +was also motivated by the time spent +on generating .whl files even if only Python code was changed. +The use of `ziglang` and `setuptools-zig` does make re-integration of the C sources +into `ruamel.yaml` feasable, but there are no plans yet to make this happen. + +The test matrix for `ruamel.yaml.clibz`, of course still has many dimensions: +``` + Python versions: 3.9 - 3.14 + OS-es: Linux, Alpine (musl), macOS, Windows + Architectures: Intel/AMD, Arm (and others), in 64 and some also in 32 bit versions + Zig version: ziglang < 0.16 is taken from PyPI +``` + +I try to test as much of the combinations as possible, +trying at least all supported Python versions, +including freethreading, +on macOS-arm64, +Linux arm64 (via docker containers), +Ubuntu Linux-Intel, +Linux musl intel (docker). +And at least one Python version along each of the indicated positions of the +dimensions above (e.g. Windows10 64bit was tested with Python 3.14, but I +could not test the RISC-V architecture). +As with generating .whl files previously +(which I could not all test myself) +I partly have to rely on the process of compilation/generation being likely correct, +and feedback from actual users, +of exotic (for me) platforms, is of course welcome. + +There is new section, +in the documentation, +on the security of processing unchecked input. + +------- + +The potentially breaking change announced for the 0.18 series, in that `YAML(typ='unsafe')` +was going to be deprecated (now pending), has not yet been implemented, but is still considered. +If you only use `unsafe` to dump, please use the new `YAML(typ='full')`, the result of that can be *safely* +loaded with a default instance `YAML()`, as that will get you inspectable, tagged, scalars, instead of +executed Python functions/classes. (You should probably add constructors for what you actually need, +but I do consider adding a `ruamel.yaml.unsafe` package that will re-add the `typ='unsafe'` option. +*Please adjust/pin your dependencies accordingly if necessary.* + +------- + +Version 0.18.16 was the last one tested to be working with Python 3.8. +Version 0.18.9 was the last one tested to be working with Python 3.7. +Version 0.17.21 was the last one tested to be working on Python 3.5 and 3.6. +The 0.16.13 release was the last that was tested to be working on Python 2.7. + + +There are two extra plug-in packages +(`ruamel.yaml.bytes` and `ruamel.yaml.string`) +for those not wanting to do the streaming to a +`io.BytesIO/StringIO` buffer themselves. + +If your package uses `ruamel.yaml` and is not listed on PyPI, drop me an +email, preferably with some information on how you use the package (or a +link to the repository) and I'll keep you informed when the status of +the API is stable enough to make the transition. + +For packaging purposes you can use a download of the [tar balls of tagged source](https://yaml.dev/ruamel-dl-tagged-releases) + + + + + + + + + +0.19.0 (2025-01-02): + +- removed dependency on `ruamel.yaml.clibz` + +0.19.0 (2025-12-31): + +- changed dependency on `ruamel.yaml.clib` to `ruamel.yaml.clibz` which includes support for free-threading (revisited after a bug report by [Ahmed Moustafa](https://sourceforge.net/u/aemous/profile/) and some insistance by [Nathan Goldbaum](https://sourceforge.net/u/ngoldbaum/profile/) +- added `.max_depth` to `YAML()` instance. If set to a (positive) number this limits the recursion, so loading does throw a `MaxDepthExceededError`. Based on comments by Benjamin Oberdorfer via email. This also triggered the new documenation section on processing unchecked input. + +0.18.17 (2025-12-17): + +- try to load C functions from `_ruamel_yaml_clibz` first. + +0.18.16 (2025-10-22): + +- root level block style scalars that started with a directives-end marker or a document-end marker, are now indented 2 spaces. +- merged fix for accessing end_marks on Tokens provided by [Toknak](https://sourceforge.net/u/taknok/) + +0.18.15 (2025-08-19): + +- duplicate merge keys are never allowed (not even with .allow_duplicate_keys = True +- merge keys now keep there position if a key before the merge key gets deleted (previously a key after the merge key would move before it) + +0.18.14 (2025-06-09): + +- Fix issue with constructing dataclasses that have a default factoryi attribute, but were missing a mapping value for that attribute. Reported by [Victor Prieto](https://sourceforge.net/u/vsprieto/profile/) +- the tagged release tar files can now also be downloaded from https://yaml.dev/ruamel-dl-tagged-releases/ please adjust if you use https://sourceforge.net/projects/ruamel-dl-tagged-releases/files/ as that repository in sourceforge will no longer be updated from some later date. + +0.18.13 (2025-06-06): + +- Fix line wrapping on plain scalars not observing width correctly. Issue 529, reported by [Sebastien Vermeille](https://sourceforge.net/u/svermeille/profile/) +- Fix sha256 and length in RECORD files. Reported by [Evan](https://sourceforge.net/u/bempelise/profile/) + +0.18.12 (2025-05-30): + +- fix additional issue with extra space in double quoted string. Reported by [Saugat Pachhai](https://sourceforge.net/u/skshetry/profile/) +- fix duplicate key url, now pointing to yaml.dev. Reported by [Hugo](https://sourceforge.net/u/hugovk/profile/) +- fix broken RECORD file, which was a problem for uv, not pip. Reported by [konstin](https://sourceforge.net/u/konstin/profile/) + +0.18.11 (2025-05-19): + +- function `load_yaml_guess_indent` now takes an option `yaml` argument so you can provide an already created/configured `YAML` instance +- Sequence item indicator with both comment/empty line before indicator **and** comment before sequence item, could not move comment and raise `NotImplementedError`. Reported by [Karsten Tessarzik](https://sourceforge.net/u/kars10/profile/). +- missing f for f-string (reported by π, via email) +- fixed issue with extra space in double quoted dump (reported by [Jan Möller](https://sourceforge.net/u/redfiredragon/profile/)) + +0.18.10 (2025-01-06): + +- implemented changes to the setup.py for Python 3.14 as suggested by [Miro Hrončok](https://sourceforge.net/u/hroncok/profile/) in merge requests (MR not merged as those files are copied in from `develop` config) + +0.18.9 (2025-01-05): + +- fix issue with roundtripping 0 in YAML 1.1 reported by [Peter Law](https://sourceforge.net/u/peterjclaw/profile/) + +0.18.8 (2025-01-02): + +- added warning to README.md that PyPI might block updates due to breaking changes + +0.18.7 (2024-12-30): + +- fixes for README (reported by [Kees Bakker](https://sourceforge.net/u/keesb/profile/)) +- fixes preserving anchor on scalar integer `0` (issue reported by (Mor Peled)[https://sourceforge.net/u/morp/profile/] and also in a question by [Ravi](https://stackoverflow.com/users/6550398/ravi) on [Stackoverflow](https://stackoverflow.com/a/79306830/1307905)) +- fix for formatting of README suggested by [Michael R. Crusoe](https://sourceforge.net/u/crusoe/profile/) + +0.18.6 (2024-02-07): + +- fixed an issue with dataclass loading when the fields were collections (bug found as a result of a question by [FibroMyAlgebra](https://stackoverflow.com/users/6855070/fibromyalgebra) on [StackOverflow](https://stackoverflow.com/a/77485786/1307905)) +- fixed an issue loading dataclasses with `InitVar` fields when `from __future__ import annotations` was used to delay evaluation of typing. + +0.18.5 (2023-11-03): + +- there is some indication that dependent packages have been pinned to use specific (tested) and just install the latest even in Python versions that have end-of-life + +0.18.4 (2023-11-01): + +- YAML() instance has a `doc_infos` attribute which is a cumulative list of DocInfo instances (one for `load()`, one per document for `load_all()`). DocInfo instances contain version information (requested, directive) and tag directive information +- fix issue that the YAML instance tags attribute was not reset between documents, resulting in mixing of tag directives of multiple documents. Now only provides tag directive information on latest document after loading. This means tags for dumping must be set **again** after a document is loaded with the same instance. (because of this tags will be removed in a favour of a different mechanism in the future) +- fix issue with multiple document intermixing YAML 1.2 and YAML 1.1, the VersionedResolver now resets +- fix issue with disappearing comment when next token was Tag (still can't have both a comment before a tag and after a tag, before node) + +0.18.3 (2023-10-29): + +- fix issue with spurious newline on first item after comment + nested block sequence +- additional links in the metadata on PyPI (Reported, with pointers how to fix, by [Sorin](https://sourceforge.net/u/ssbarnea/profile/)). + +0.18.2 (2023-10-24): + +- calling the deprecated functions now raises an `AttributeError` with the, somewhat more informative, orginal warning message. Instead of calling `sys.exit(1)` + +0.18.1 (2023-10-24): + +- calling the deprecated functions now always displays the warning message. (reported by [Trend Lloyd](https://sourceforge.net/u/lathiat2/profile/)) + +0.18.0 (2023-10-23): + +- the **functions** `scan`, `parse`, `compose`, `load`, `emit`, `serialize`, `dump` and their variants (`_all`, `safe_`, `round_trip_`, etc) have been deprecated (the same named **methods** on `YAML()` instances are, of course, still there. +- `YAML(typ='unsafe')` now issues a `PendingDeprecationWarning`. This will become deprecated in the 0.18 series +(probably before the end of 2023). +You can use `YAML(typ='full')` to dump unregistered Python classes/functions. +For loading you'll have to register your classes/functions +if you want the old, unsafe, functionality. You can still load any tag, like `!!python/name:posix.system', **safely** +with the (default) round-trip parser. +- fix for `bytes-like object is required not 'str' while dumping binary streams`. This was reported, analysed and a fix provided by [Vit Zikmund](https://sourceforge.net/u/tlwhitec/profile/) + + +------------------------------------------------------------------------ + +For older changes see the file +[CHANGES](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/CHANGES) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA new file mode 100644 index 00000000000..97fd818b909 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA @@ -0,0 +1,73 @@ +Metadata-Version: 2.4 +Name: typing_extensions +Version: 4.16.0 +Summary: Backported and Experimental Type Hints for Python 3.9+ +Keywords: annotations,backport,checker,checking,function,hinting,hints,type,typechecking,typehinting,typehints,typing +Author-email: "Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee" +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-Expression: PSF-2.0 +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Topic :: Software Development +License-File: LICENSE +Project-URL: Bug Tracker, https://github.com/python/typing_extensions/issues +Project-URL: Changes, https://github.com/python/typing_extensions/blob/main/CHANGELOG.md +Project-URL: Documentation, https://typing-extensions.readthedocs.io/ +Project-URL: Home, https://github.com/python/typing_extensions +Project-URL: Q & A, https://github.com/python/typing/discussions +Project-URL: Repository, https://github.com/python/typing_extensions + +# Typing Extensions + +[![Chat at https://gitter.im/python/typing](https://badges.gitter.im/python/typing.svg)](https://gitter.im/python/typing) + +[Documentation](https://typing-extensions.readthedocs.io/en/latest/#) – +[PyPI](https://pypi.org/project/typing-extensions/) + +## Overview + +The `typing_extensions` module serves two related purposes: + +- Enable use of new type system features on older Python versions. For example, + `typing.TypeGuard` is new in Python 3.10, but `typing_extensions` allows + users on previous Python versions to use it too. +- Enable experimentation with new type system PEPs before they are accepted and + added to the `typing` module. + +`typing_extensions` is treated specially by static type checkers such as +mypy and pyright. Objects defined in `typing_extensions` are treated the same +way as equivalent forms in `typing`. + +`typing_extensions` uses +[Semantic Versioning](https://semver.org/). The +major version will be incremented only for backwards-incompatible changes. +Therefore, it's safe to depend +on `typing_extensions` like this: `typing_extensions ~=x.y`, +where `x.y` is the first version that includes all features you need. +[This](https://packaging.python.org/en/latest/specifications/version-specifiers/#compatible-release) +is equivalent to `typing_extensions >=x.y, <(x+1)`. Do not depend on `~= x.y.z` +unless you really know what you're doing; that defeats the purpose of +semantic versioning. + +## Included items + +See [the documentation](https://typing-extensions.readthedocs.io/en/latest/#) for a +complete listing of module contents. + +## Contributing + +See [CONTRIBUTING.md](https://github.com/python/typing_extensions/blob/main/CONTRIBUTING.md) +for how to contribute to `typing_extensions`. + diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA new file mode 100644 index 00000000000..88f02623b28 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA @@ -0,0 +1,175 @@ +Metadata-Version: 2.5 +Name: urllib3 +Version: 2.8.0 +Summary: HTTP library with thread-safe connection pooling, file post, and more. +Project-URL: Changelog, https://github.com/urllib3/urllib3/blob/main/CHANGES.rst +Project-URL: Documentation, https://urllib3.readthedocs.io +Project-URL: Code, https://github.com/urllib3/urllib3 +Project-URL: Issue tracker, https://github.com/urllib3/urllib3/issues +Project-URL: Security policy, https://urllib3.readthedocs.io/en/latest/security.html +Author-email: Andrey Petrov +Maintainer-email: Seth Michael Larson , Quentin Pradet , Illia Volochii +License-Expression: MIT +License-File: LICENSE.txt +Keywords: filepost,http,httplib,https,pooling,ssl,threadsafe,urllib +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries +Requires-Python: >=3.10 +Provides-Extra: brotli +Requires-Dist: brotli>=1.2.0; (platform_python_implementation == 'CPython') and extra == 'brotli' +Requires-Dist: brotlicffi>=1.2.0.0; (platform_python_implementation != 'CPython') and extra == 'brotli' +Provides-Extra: h2 +Requires-Dist: h2<5,>=4; extra == 'h2' +Provides-Extra: socks +Requires-Dist: pysocks!=1.5.7,<2.0,>=1.5.6; extra == 'socks' +Provides-Extra: zstd +Requires-Dist: backports-zstd>=1.0.0; (python_version < '3.14') and extra == 'zstd' +Description-Content-Type: text/markdown + +

+ +![urllib3](https://github.com/urllib3/urllib3/raw/main/docs/_static/banner_github.svg) + +

+ +

+ PyPI Version + Python Versions + Join our Discord + Coverage Status + Build Status on GitHub + Documentation Status
+ OpenSSF Scorecard + SLSA 3 + CII Best Practices +

+ +urllib3 is a powerful, *user-friendly* HTTP client for Python. +urllib3 brings many critical features that are missing from the Python +standard libraries: + +- Thread safety. +- Connection pooling. +- Client-side SSL/TLS verification. +- File uploads with multipart encoding. +- Helpers for retrying requests and dealing with HTTP redirects. +- Support for gzip, deflate, brotli, and zstd encoding. +- Proxy support for HTTP and SOCKS. +- 100% test coverage. + +... and many more features, but most importantly: Our maintainers have a 15+ +year track record of maintaining urllib3 with the highest code standards and +attention to security and safety. + +[Much of the Python ecosystem already uses urllib3](https://urllib3.readthedocs.io/en/stable/#who-uses) +and you should too. + + +## Installing + +urllib3 can be installed with [pip](https://pip.pypa.io): + +```bash +$ python -m pip install urllib3 +``` + +Alternatively, you can grab the latest source code from [GitHub](https://github.com/urllib3/urllib3): + +```bash +$ git clone https://github.com/urllib3/urllib3.git +$ cd urllib3 +$ pip install . +``` + +## Getting Started + +urllib3 is easy to use: + +```python3 +>>> import urllib3 +>>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt") +>>> resp.status +200 +>>> resp.data +b"User-agent: *\nDisallow: /deny\n" +``` + +urllib3 has usage and reference documentation at [urllib3.readthedocs.io](https://urllib3.readthedocs.io). + + +## Community + +urllib3 has a [community Discord channel](https://discord.gg/urllib3) for asking questions and +collaborating with other contributors. Drop by and say hello 👋 + + +## Contributing + +urllib3 welcomes contributions. Please read our +[contributing documentation](https://urllib3.readthedocs.io/en/latest/contributing.html) +before starting work. + +Check for existing pull requests addressing the same issue, and share feedback +and suggestions in the existing pull request and issue. Duplicate pull +requests, including alternative solutions, will be rejected without review +unless a maintainer has approved opening an alternative pull request in +advance. + + +## Security Disclosures + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure with maintainers. + +See the repository +[Security Policy](https://urllib3.readthedocs.io/en/latest/security.html) +for more details. + + +## Maintainers + +Meet our maintainers since 2008: + +- Current Lead: [@illia-v](https://github.com/illia-v) (Illia Volochii) +- [@sethmlarson](https://github.com/sethmlarson) (Seth M. Larson) +- [@pquentin](https://github.com/pquentin) (Quentin Pradet) +- [@theacodes](https://github.com/theacodes) (Thea Flowers) +- [@haikuginger](https://github.com/haikuginger) (Jess Shapiro) +- [@lukasa](https://github.com/lukasa) (Cory Benfield) +- [@sigmavirus24](https://github.com/sigmavirus24) (Ian Stapleton Cordasco) +- [@shazow](https://github.com/shazow) (Andrey Petrov) + +👋 + + +## Sponsorship + +If your company benefits from this library, please consider [sponsoring its +development](https://urllib3.readthedocs.io/en/latest/sponsors.html). + + +## For Enterprise + +Professional support for urllib3 is available as part of the [Tidelift +Subscription][1]. Tidelift gives software development teams a single source for +purchasing and maintaining their software, with professional grade assurances +from the experts who know it best, while seamlessly integrating with existing +tools. + +[1]: https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=readme diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA new file mode 100644 index 00000000000..8a0c2cbc88b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA @@ -0,0 +1,193 @@ +Metadata-Version: 2.4 +Name: wrapt +Version: 2.5.2 +Summary: Module for decorators, wrappers and monkey patching. +Author-email: Graham Dumpleton +License-Expression: BSD-2-Clause +Project-URL: Homepage, https://github.com/GrahamDumpleton/wrapt +Project-URL: Bug Tracker, https://github.com/GrahamDumpleton/wrapt/issues/ +Project-URL: Changelog, https://wrapt.readthedocs.io/en/latest/changes.html +Project-URL: Documentation, https://wrapt.readthedocs.io/ +Keywords: wrapper,proxy,decorator +Classifier: Development Status :: 5 - Production/Stable +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: 3.15 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=3.9 +Description-Content-Type: text/x-rst +License-File: LICENSE +Provides-Extra: dev +Requires-Dist: pytest; extra == "dev" +Requires-Dist: setuptools; extra == "dev" +Dynamic: license-file + +.. image:: https://raw.githubusercontent.com/GrahamDumpleton/wrapt/develop/docs/_static/wrapt-logo.svg + :alt: wrapt + :width: 182px + +wrapt +===== + +|PyPI| |Documentation| + +A Python module for decorators, wrappers and monkey patching. + +Overview +-------- + +The **wrapt** module provides a transparent object proxy for Python, which can be used as the basis for the construction of function wrappers and decorator functions. + +The **wrapt** module focuses very much on correctness. It goes way beyond existing mechanisms such as ``functools.wraps()`` to ensure that decorators preserve introspectability, signatures, type checking abilities etc. The decorators that can be constructed using this module will work in far more scenarios than typical decorators and provide more predictable and consistent behaviour. + +To ensure that the overhead is as minimal as possible, a C extension module is used for performance critical components. An automatic fallback to a pure Python implementation is also provided where a target system does not have a compiler to allow the C extension to be compiled. + +Key Features +------------ + +* **Universal decorators** that work with functions, methods, classmethods, staticmethods, and classes +* **Transparent object proxies** for advanced wrapping scenarios +* **Monkey patching utilities** for safe runtime modifications +* **C extension** for optimal performance with Python fallback +* **Comprehensive introspection preservation** (signatures, annotations, etc.) +* **Thread-safe decorator implementations** + +Installation +------------ + +Install from PyPI using pip:: + + pip install wrapt + +Supported Python Versions +-------------------------- + +* Python 3.9+ +* CPython and PyPy implementations + +Documentation +------------- + +For comprehensive documentation, examples, and advanced usage patterns, visit: + +* https://wrapt.readthedocs.io/ + +Quick Start +----------- + +To implement your decorator you need to first define a wrapper function. +This will be called each time a decorated function is called. The wrapper +function needs to take four positional arguments: + +* ``wrapped`` - The wrapped function which in turns needs to be called by your wrapper function. +* ``instance`` - The object to which the wrapped function was bound when it was called. +* ``args`` - The list of positional arguments supplied when the decorated function was called. +* ``kwargs`` - The dictionary of keyword arguments supplied when the decorated function was called. + +The wrapper function would do whatever it needs to, but would usually in +turn call the wrapped function that is passed in via the ``wrapped`` +argument. + +The decorator ``@wrapt.decorator`` then needs to be applied to the wrapper +function to convert it into a decorator which can in turn be applied to +other functions. + +.. code-block:: python + + import wrapt + + @wrapt.decorator + def pass_through(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + + @pass_through + def function(): + pass + +If you wish to implement a decorator which accepts arguments, then wrap the +definition of the decorator in a function closure. Any arguments supplied +to the outer function when the decorator is applied, will be available to +the inner wrapper when the wrapped function is called. + +.. code-block:: python + + import wrapt + + def with_arguments(myarg1, myarg2): + @wrapt.decorator + def wrapper(wrapped, instance, args, kwargs): + return wrapped(*args, **kwargs) + return wrapper + + @with_arguments(1, 2) + def function(): + pass + +When applied to a normal function or static method, the wrapper function +when called will be passed ``None`` as the ``instance`` argument. + +When applied to an instance method, the wrapper function when called will +be passed the instance of the class the method is being called on as the +``instance`` argument. This will be the case even when the instance method +was called explicitly via the class and the instance passed as the first +argument. That is, the instance will never be passed as part of ``args``. + +When applied to a class method, the wrapper function when called will be +passed the class type as the ``instance`` argument. + +When applied to a class, the wrapper function when called will be passed +``None`` as the ``instance`` argument. The ``wrapped`` argument in this +case will be the class. + +The above rules can be summarised with the following example. + +.. code-block:: python + + import inspect + + @wrapt.decorator + def universal(wrapped, instance, args, kwargs): + if instance is None: + if inspect.isclass(wrapped): + # Decorator was applied to a class. + return wrapped(*args, **kwargs) + else: + # Decorator was applied to a function or staticmethod. + return wrapped(*args, **kwargs) + else: + if inspect.isclass(instance): + # Decorator was applied to a classmethod. + return wrapped(*args, **kwargs) + else: + # Decorator was applied to an instancemethod. + return wrapped(*args, **kwargs) + +Using these checks it is therefore possible to create a universal decorator +that can be applied in all situations. It is no longer necessary to create +different variants of decorators for normal functions and instance methods, +or use additional wrappers to convert a function decorator into one that +will work for instance methods. + +In all cases, the wrapped function passed to the wrapper function is called +in the same way, with ``args`` and ``kwargs`` being passed. The +``instance`` argument doesn't need to be used in calling the wrapped +function. + +Links +----- + +* **Documentation**: https://wrapt.readthedocs.io/ +* **Source Code**: https://github.com/GrahamDumpleton/wrapt +* **Bug Reports**: https://github.com/GrahamDumpleton/wrapt/issues/ +* **Changelog**: https://wrapt.readthedocs.io/en/latest/changes.html + +.. |PyPI| image:: https://img.shields.io/pypi/v/wrapt.svg?logo=python&cacheSeconds=3600 + :target: https://pypi.python.org/pypi/wrapt +.. |Documentation| image:: https://img.shields.io/badge/docs-wrapt.readthedocs.io-blue.svg + :target: https://wrapt.readthedocs.io/ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json new file mode 100644 index 00000000000..c3dec118ec2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json @@ -0,0 +1,845 @@ +{ + "components": [ + { + "bom-ref": "pkg:pypi/certifi@2026.10.23", + "hashes": [ + { + "alg": "SHA-256", + "content": "e9b54de76e530bb6cf0ccd036787103acb58fd42ba930ea8bf948ddbaa2f61d1" + } + ], + "licenses": [ + { + "license": { + "id": "MPL-2.0" + } + } + ], + "name": "certifi", + "pedigree": { + "patches": [ + { + "diff": { + "text": { + "content": "Look up the CA bundle in the vendored certifi package.\n\nUpstream passes the top-level name \"certifi\" to importlib.resources, which would import\nthe application's certifi (or fail if it isn't installed). __package__ resolves to the\nvendored package.\n\ndiff --git a/certifi/core.py b/certifi/core.py\n--- a/certifi/core.py\n+++ b/certifi/core.py\n@@ -37,14 +37,14 @@ if sys.version_info >= (3, 11):\n # We also have to hold onto the actual context manager, because\n # it will do the cleanup whenever it gets garbage collected, so\n # we will also store that at the global level as well.\n- _CACERT_CTX = as_file(files(\"certifi\").joinpath(\"cacert.pem\"))\n+ _CACERT_CTX = as_file(files(__package__).joinpath(\"cacert.pem\"))\n _CACERT_PATH = str(_CACERT_CTX.__enter__())\n atexit.register(exit_cacert_ctx)\n \n return _CACERT_PATH\n \n def contents() -> str:\n- return files(\"certifi\").joinpath(\"cacert.pem\").read_text(encoding=\"ascii\")\n+ return files(__package__).joinpath(\"cacert.pem\").read_text(encoding=\"ascii\")\n \n else:\n \n@@ -73,11 +73,11 @@ else:\n # We also have to hold onto the actual context manager, because\n # it will do the cleanup whenever it gets garbage collected, so\n # we will also store that at the global level as well.\n- _CACERT_CTX = get_path(\"certifi\", \"cacert.pem\")\n+ _CACERT_CTX = get_path(__package__, \"cacert.pem\")\n _CACERT_PATH = str(_CACERT_CTX.__enter__())\n atexit.register(exit_cacert_ctx)\n \n return _CACERT_PATH\n \n def contents() -> str:\n- return read_text(\"certifi\", \"cacert.pem\", encoding=\"ascii\")\n+ return read_text(__package__, \"cacert.pem\", encoding=\"ascii\")\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + } + ] + }, + "purl": "pkg:pypi/certifi@2026.10.23", + "type": "library", + "version": "2026.10.23" + }, + { + "bom-ref": "pkg:pypi/charset-normalizer@3.5.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "b6b751274acb69d77b3323d6b7dbaa3c7fdfc1eb829b7eb61d262f32e1af9685" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "charset-normalizer", + "purl": "pkg:pypi/charset-normalizer@3.5.2", + "type": "library", + "version": "3.5.2" + }, + { + "bom-ref": "pkg:pypi/fastjsonschema@2.22.3", + "hashes": [ + { + "alg": "SHA-256", + "content": "f670b443830b75aca3f00b75949efa20f4b2a80302ec7a21505c28dd54cffd43" + } + ], + "licenses": [ + { + "license": { + "id": "BSD-3-Clause" + } + } + ], + "name": "fastjsonschema", + "purl": "pkg:pypi/fastjsonschema@2.22.3", + "type": "library", + "version": "2.22.3" + }, + { + "bom-ref": "pkg:pypi/googleapis-common-protos@1.76.0", + "hashes": [ + { + "alg": "SHA-256", + "content": "59e13344a9f3651aa201a03e2bee815a3bf43a4baf1f9ff8a9b62a840ce25fac" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "googleapis-common-protos", + "purl": "pkg:pypi/googleapis-common-protos@1.76.0", + "type": "library", + "version": "1.76.0" + }, + { + "bom-ref": "pkg:pypi/idna@3.20", + "hashes": [ + { + "alg": "SHA-256", + "content": "ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c" + } + ], + "licenses": [ + { + "license": { + "id": "BSD-3-Clause" + } + } + ], + "name": "idna", + "purl": "pkg:pypi/idna@3.20", + "type": "library", + "version": "3.20" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-api@1.45.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "2cbd737377e710ee740d261c94e93fa0f08e6d037c18f17513cc0a2d94479a34" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-api", + "purl": "pkg:pypi/opentelemetry-api@1.45.2", + "type": "library", + "version": "1.45.2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-configuration@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "de7f1b5682cab12d35f22330f025ed5a54d2a8151515eede5b0a3ed9629dcc61" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-configuration", + "purl": "pkg:pypi/opentelemetry-configuration@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-distro@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "a488231479bbc17f5c34d4ef740e9285fa8f8cd1114f73078cac9d8520eacfbd" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-distro", + "purl": "pkg:pypi/opentelemetry-distro@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-http-transport@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "fd5f5b490c099acda1cd7b909d5e8981436bf18cc8c6098d302d114c271720e9" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-http-transport", + "purl": "pkg:pypi/opentelemetry-exporter-http-transport@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-common@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "ace86efb75489f925f1ef809856ae5f0c7db534e4afdc624530222228b1236a5" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-otlp-common", + "purl": "pkg:pypi/opentelemetry-exporter-otlp-common@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-json-common@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "6e83ba9312edb60fc1d4929b73457e8cca7579db4b4492b32cb71a1a8ddecdc7" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-otlp-json-common", + "purl": "pkg:pypi/opentelemetry-exporter-otlp-json-common@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-json-file@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "a500f13bcc7760a74b5db7ece7d72ec8a78e0b515539fec81705970cb2efd7ca" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-otlp-json-file", + "purl": "pkg:pypi/opentelemetry-exporter-otlp-json-file@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-json-http@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "56a91c92e09c83c01d07380f48df6f649f3ce89fd47aa8c4862ef84de8e47ddb" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-otlp-json-http", + "purl": "pkg:pypi/opentelemetry-exporter-otlp-json-http@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-common@1.45.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "af483b24217028892f017096731b794b196b785025d2e6808874720fd0b05a80" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-otlp-proto-common", + "purl": "pkg:pypi/opentelemetry-exporter-otlp-proto-common@1.45.2", + "type": "library", + "version": "1.45.2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-http@1.45.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "6e4d025138829d0ee57946930c2ccad6491ad4d92a958e9c7eea69278fe60cfc" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-otlp-proto-http", + "purl": "pkg:pypi/opentelemetry-exporter-otlp-proto-http@1.45.2", + "type": "library", + "version": "1.45.2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-exporter-prometheus@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "b73998788aa30bec3bfe20fae312650878adb59f6563ed8bf37c188cb450a189" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-exporter-prometheus", + "purl": "pkg:pypi/opentelemetry-exporter-prometheus@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-instrumentation@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "fa9ccfdab147a14af8107d19ef0a7b5015675273c5adced7a1fc38f28b42ec4c" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-instrumentation", + "purl": "pkg:pypi/opentelemetry-instrumentation@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-instrumentation-aiohttp-client@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "33c51743ca225c2405b81b40ac744697804aef44b530f64d1f524c9a9cd3dca2" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-instrumentation-aiohttp-client", + "purl": "pkg:pypi/opentelemetry-instrumentation-aiohttp-client@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-propagator-b3@1.45.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "86c7f921a8390c0f7d88a27450765b6d075a3579f2592baa623723e9e527a1b8" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-propagator-b3", + "purl": "pkg:pypi/opentelemetry-propagator-b3@1.45.2", + "type": "library", + "version": "1.45.2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-proto@1.45.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "03a7ca1b43f89fd5b965d5975902bb2515c0c86e2428b456836e9a6149c6235a" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-proto", + "purl": "pkg:pypi/opentelemetry-proto@1.45.2", + "type": "library", + "version": "1.45.2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-proto-json@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "4da45dc527e68bc00fd4d16773c58b6a9a229ebb7a8dce997403414eaa03b3bb" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-proto-json", + "purl": "pkg:pypi/opentelemetry-proto-json@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-sdk@1.45.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "ff974ea70ee4f1d51e2ec152db37c2b626c7bf82bb3f7d86114fd8704e7199c6" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-sdk", + "purl": "pkg:pypi/opentelemetry-sdk@1.45.2", + "type": "library", + "version": "1.45.2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-semantic-conventions@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "4cbe61e5f9275d57ab31708446e7938ef4291ebbe6a7fca6f7a629c5acae87d8" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-semantic-conventions", + "purl": "pkg:pypi/opentelemetry-semantic-conventions@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/opentelemetry-util-http@0.66b2", + "hashes": [ + { + "alg": "SHA-256", + "content": "c4bb5d6744e60353bcaa3e325bc529a1515346b51cb4d9c8e5b730579337e06d" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "opentelemetry-util-http", + "pedigree": { + "patches": [ + { + "diff": { + "text": { + "content": "Default the distro's OTLP protocol to http/protobuf.\n\nThe distro defaults OTEL_EXPORTER_OTLP_PROTOCOL to grpc, but the gRPC exporters aren't vendored\n(grpcio has no pure-Python wheel). With http/protobuf the SDK resolves the \"otlp\" exporter to the\nvendored otlp_proto_http one. An explicitly set OTEL_EXPORTER_OTLP_PROTOCOL still wins.\n\ndiff --git a/opentelemetry/distro/__init__.py b/opentelemetry/distro/__init__.py\nindex 4d00198..6165e7a 100644\n--- a/opentelemetry/distro/__init__.py\n+++ b/opentelemetry/distro/__init__.py\n@@ -28,4 +28,5 @@ class OpenTelemetryDistro(BaseDistro):\n os.environ.setdefault(OTEL_TRACES_EXPORTER, \"otlp\")\n os.environ.setdefault(OTEL_METRICS_EXPORTER, \"otlp\")\n os.environ.setdefault(OTEL_LOGS_EXPORTER, \"otlp\")\n- os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, \"grpc\")\n+ # opentelemetry-agent: the gRPC exporters aren't vendored (grpcio has no pure-Python wheel).\n+ os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, \"http/protobuf\")\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + }, + { + "diff": { + "text": { + "content": "Parse and validate configuration files with ruamel.yaml and fastjsonschema.\n\nopentelemetry-configuration uses pyyaml and jsonschema, which have no pure-Python wheels (jsonschema needs\nrpds-py), so they are excluded (vendor-excludes.txt) and the vendored, pure-Python ruamel.yaml and\nfastjsonschema stand in for them:\n\n* YAML: ruamel.yaml's PyYAML-style SafeLoader (with the same Node classes, resolve() and\n construct_document()). It resolves scalars with the YAML 1.2 core schema, which the configuration\n spec requires (PyYAML implements YAML 1.1, where e.g. \"on\" and \"no\" are booleans).\n* Schema: a fastjsonschema validator compiled once. Its draft 2019-09 generator, used for the 2020-12\n $schema, covers every keyword the schema uses ($ref into $defs, oneOf, exclusiveMinimum, ...).\n Errors map to the same ConfigurationError messages.\n\nThe schema is also read relative to this file rather than with importlib.resources.files(\n\"opentelemetry.configuration\"), which would resolve the application's package.\n\ndiff --git a/opentelemetry/configuration/file/_loader.py b/opentelemetry/configuration/file/_loader.py\nindex dfa0037..44029a9 100644\n--- a/opentelemetry/configuration/file/_loader.py\n+++ b/opentelemetry/configuration/file/_loader.py\n@@ -3,7 +3,6 @@\n \n \"\"\"Configuration file loading and parsing.\"\"\"\n \n-import importlib.resources\n import json\n import logging\n import os\n@@ -14,32 +13,23 @@ from typing import Any\n from opentelemetry.agent._vendor.opentelemetry.configuration._conversion import _dict_to_dataclass\n from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import (\n ConfigurationError,\n- MissingDependencyError,\n )\n from opentelemetry.agent._vendor.opentelemetry.configuration.file._env_substitution import (\n substitute_env_vars,\n )\n from opentelemetry.agent._vendor.opentelemetry.configuration.models import OpenTelemetryConfiguration\n \n-try:\n- import yaml\n-except ImportError as exc:\n- raise MissingDependencyError(\n- package=\"pyyaml\",\n- feature=\"File configuration\",\n- install_name=\"opentelemetry-sdk\",\n- extras=\"file-configuration\",\n- ) from exc\n-\n-try:\n- import jsonschema\n-except ImportError as exc:\n- raise MissingDependencyError(\n- package=\"jsonschema\",\n- feature=\"File configuration\",\n- install_name=\"opentelemetry-sdk\",\n- extras=\"file-configuration\",\n- ) from exc\n+# opentelemetry-agent: pyyaml and jsonschema have no pure-Python wheels (jsonschema needs rpds-py),\n+# so the vendored ruamel.yaml (its pure-Python, PyYAML-style loader API) and fastjsonschema stand in.\n+from opentelemetry.agent._vendor import fastjsonschema\n+from opentelemetry.agent._vendor.ruamel.yaml import nodes as _yaml_nodes\n+from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError\n+from opentelemetry.agent._vendor.ruamel.yaml.loader import SafeLoader as _RuamelSafeLoader\n+\n+\n+class SafeLoader(_RuamelSafeLoader):\n+ # Only ruamel.yaml's YAML class sets the composer's nesting limit; 0 means none, like PyYAML.\n+ max_depth = 0\n \n # Schema version vendored in schema.json. ``file_format`` values are accepted\n # per the configuration spec's versioning rules: the major version must match,\n@@ -50,15 +40,24 @@ _SUPPORTED_SCHEMA_MAJOR = 1\n _SUPPORTED_SCHEMA_MINOR = 1\n \n _schema_cache: list[dict] = []\n+_validator_cache: list[Any] = []\n \n \n def _get_schema() -> dict:\n if not _schema_cache:\n- schema_path = importlib.resources.files(\"opentelemetry.configuration\") / \"schema.json\"\n+ # opentelemetry-agent: resolve the schema relative to this (vendored) package, not by name.\n+ schema_path = Path(__file__).resolve().parent.parent / \"schema.json\"\n _schema_cache.append(json.loads(schema_path.read_text(encoding=\"utf-8\")))\n return _schema_cache[0]\n \n \n+def _get_validator() -> Any:\n+ # Compiling the schema generates and executes Python code; do it once.\n+ if not _validator_cache:\n+ _validator_cache.append(fastjsonschema.compile(_get_schema()))\n+ return _validator_cache[0]\n+\n+\n _logger = logging.getLogger(__name__)\n \n _YAML_STR_TAG = \"tag:yaml.org,2002:str\"\n@@ -73,8 +72,8 @@ _STANDALONE_ENV_REF = re.compile(r\"\\A\\$\\{[A-Za-z_][A-Za-z0-9_]*(?::-[^}]*)?\\}\\Z\"\n \n \n def _substitute_env_in_yaml_node(\n- node: yaml.Node,\n- loader: yaml.SafeLoader,\n+ node: _yaml_nodes.Node,\n+ loader: SafeLoader,\n visited: set[int] | None = None,\n ):\n \"\"\"Apply env-var substitution to string configuration values in a node tree.\n@@ -120,7 +119,7 @@ def _substitute_env_in_yaml_node(\n # The parser hands this function the value node of attribute_count_limit,\n # which has value=\"${LIMIT}\", tag=str, style=None (plain/unquoted). Then:\n #\n- # 1. isinstance(node, yaml.ScalarNode) -> True: it is a leaf value.\n+ # 1. isinstance(node, ScalarNode) -> True: it is a leaf value.\n # 2. node.tag == _YAML_STR_TAG -> True: \"${LIMIT}\" is not a number or\n # bool, so the parser tagged it str. We substitute in place, giving\n # node.value = \"100\".\n@@ -131,7 +130,7 @@ def _substitute_env_in_yaml_node(\n #\n # Counter-cases that reach check 3 but stop there: \"${LIMIT}\" quoted fails\n # the style test; x${LIMIT} fails the regex. Both keep the str tag.\n- if isinstance(node, yaml.ScalarNode):\n+ if isinstance(node, _yaml_nodes.ScalarNode):\n # A ``ScalarNode`` is a leaf -- one configuration value. Only a\n # ``str``-tagged one can hold a ``${VAR}`` reference (nodes the parser\n # already typed as int, float, bool or null cannot), so those are the\n@@ -153,12 +152,12 @@ def _substitute_env_in_yaml_node(\n # str) YAML would assign to ``node.value``; the ``(True, False)``\n # implicit-flag pair marks it as a plain scalar so that\n # type-guessing applies, exactly as during normal parsing.\n- node.tag = loader.resolve(yaml.ScalarNode, node.value, (True, False))\n- elif isinstance(node, yaml.SequenceNode):\n+ node.tag = loader.resolve(_yaml_nodes.ScalarNode, node.value, (True, False))\n+ elif isinstance(node, _yaml_nodes.SequenceNode):\n # A sequence (list): each item is itself a value node -- recurse.\n for item in node.value:\n _substitute_env_in_yaml_node(item, loader, visited)\n- elif isinstance(node, yaml.MappingNode):\n+ elif isinstance(node, _yaml_nodes.MappingNode):\n # A mapping (dict): recurse into values only; keys are not\n # substitution candidates per the spec. A merge key (``<<: *base``)\n # appears here as an ordinary pair whose value node is the anchored\n@@ -197,7 +196,8 @@ def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLik\n try:\n if suffix == \".json\":\n return _substitute_env_in_json_value(json.loads(content))\n- yaml_loader = yaml.SafeLoader(content)\n+ # YAML 1.2 core schema, as the configuration spec requires (PyYAML implements YAML 1.1).\n+ yaml_loader = SafeLoader(content)\n try:\n root_node = yaml_loader.get_single_node()\n if root_node is None:\n@@ -206,7 +206,7 @@ def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLik\n return yaml_loader.construct_document(root_node)\n finally:\n yaml_loader.dispose()\n- except yaml.YAMLError as exc:\n+ except YAMLError as exc:\n _logger.exception(\"Failed to parse YAML from %s\", file_path)\n raise ConfigurationError(f\"Failed to parse YAML: {exc}\") from exc\n except json.JSONDecodeError as exc:\n@@ -294,19 +294,17 @@ def _validate_schema(data: dict) -> None:\n ConfigurationError: If the data does not conform to the schema.\n \"\"\"\n try:\n- jsonschema.validate(\n- instance=data,\n- schema=_get_schema(),\n- cls=jsonschema.Draft202012Validator,\n- )\n- except jsonschema.ValidationError as exc:\n+ _get_validator()(data)\n+ except fastjsonschema.JsonSchemaValueException as exc:\n+ # The path starts with the root's name (\"data\").\n+ path = exc.path[1:]\n raise ConfigurationError(\n- f\"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in exc.absolute_path)})\"\n- if exc.absolute_path\n+ f\"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in path)})\"\n+ if path\n else f\"Configuration does not match schema: {exc.message}\"\n ) from exc\n- except jsonschema.SchemaError as exc:\n- raise ConfigurationError(f\"Invalid configuration schema: {exc.message}\") from exc\n+ except fastjsonschema.JsonSchemaDefinitionException as exc:\n+ raise ConfigurationError(f\"Invalid configuration schema: {exc}\") from exc\n \n \n def _validate_file_format(data: dict) -> None:\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + }, + { + "diff": { + "text": { + "content": "Report upstream module names from the vendored SDK.\n\nInstrumentations name their tracers, meters and loggers after their module (get_tracer(__name__)),\nwhich is opentelemetry.agent._vendor.opentelemetry... once vendored. InstrumentationScope (and the\ndeprecated InstrumentationInfo) strip the vendor prefix, so telemetry reports the same scope names as\nthe upstream packages, e.g. opentelemetry.instrumentation.aiohttp_client.\n\nThe TracerProvider's warning filter for its own InstrumentationInfo deprecation names its module by\nstring; use __name__ so it matches the vendored module rather than the application's SDK.\n\ndiff --git a/opentelemetry/sdk/trace/__init__.py b/opentelemetry/sdk/trace/__init__.py\nindex 06fd2b3..1f7ab18 100644\n--- a/opentelemetry/sdk/trace/__init__.py\n+++ b/opentelemetry/sdk/trace/__init__.py\n@@ -1351,7 +1351,8 @@ class TracerProvider(trace_api.TracerProvider):\n \"ignore\",\n message=(r\"You should use InstrumentationScope. Deprecated since version 1.11.1.\"),\n category=DeprecationWarning,\n- module=\"opentelemetry.sdk.trace\",\n+ # opentelemetry-agent: match this (vendored) module, not the application's SDK.\n+ module=__name__,\n )\n \n instrumentation_info = InstrumentationInfo(\ndiff --git a/opentelemetry/sdk/util/instrumentation.py b/opentelemetry/sdk/util/instrumentation.py\nindex ac64c2d..9cf8491 100644\n--- a/opentelemetry/sdk/util/instrumentation.py\n+++ b/opentelemetry/sdk/util/instrumentation.py\n@@ -13,6 +13,18 @@ from opentelemetry.agent._vendor.opentelemetry.util.types import ( # TODO: see\n )\n \n \n+# opentelemetry-agent: instrumentations vendored under the agent's namespace name their scope after\n+# their module (get_tracer(__name__)); report the upstream module name instead, e.g.\n+# \"opentelemetry.instrumentation.aiohttp_client\" rather than \"opentelemetry.agent._vendor.opentelemetry...\".\n+_VENDOR_PREFIX = __name__.removesuffix(\"opentelemetry.sdk.util.instrumentation\")\n+\n+\n+def _unvendored_name(name: str) -> str:\n+ if isinstance(name, str) and name.startswith(_VENDOR_PREFIX):\n+ return name[len(_VENDOR_PREFIX) :]\n+ return name\n+\n+\n class InstrumentationInfo:\n \"\"\"Immutable information about an instrumentation library module.\n \n@@ -29,7 +41,7 @@ class InstrumentationInfo:\n version: str | None = None,\n schema_url: str | None = None,\n ):\n- self._name = name\n+ self._name = _unvendored_name(name)\n self._version = version\n if schema_url is None:\n schema_url = \"\"\n@@ -92,7 +104,7 @@ class InstrumentationScope:\n schema_url: str | None = None,\n attributes: Attributes = None,\n ) -> None:\n- self._name = name\n+ self._name = _unvendored_name(name)\n self._version = version\n if schema_url is None:\n schema_url = \"\"\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + }, + { + "diff": { + "text": { + "content": "Scope OpenTelemetry's entry point lookups to the vendored distributions.\n\nAll OpenTelemetry plugin discovery (distro, configurator, instrumentors, exporters, samplers,\npropagators, resource detectors, HTTP transports) goes through opentelemetry.util._importlib_metadata.\nUpstream it reads every installed distribution's entry points: the vendored copies have no\ndist-info on sys.path, and the application's OpenTelemetry plugins point at un-vendored modules.\nopentelemetry-vendor sync keeps the vendored distributions' METADATA and namespaced entry points in\n_vendor/_metadata (metadata-dir); entry_points() and distributions() only search there.\n\nversion() and requires() keep looking at the application's distributions: instrumentors check that the\ninstalled version of the library they patch matches their \"instruments\" requirements.\n\ndiff --git a/opentelemetry/util/_importlib_metadata.py b/opentelemetry/util/_importlib_metadata.py\nindex 656afbb..c7c5399 100644\n--- a/opentelemetry/util/_importlib_metadata.py\n+++ b/opentelemetry/util/_importlib_metadata.py\n@@ -11,38 +11,35 @@ It also normalizes minor differences across python versions 3.10+. References to\n - https://github.com/open-telemetry/opentelemetry-python/pull/5203\n \"\"\"\n \n-import itertools\n+import os\n from functools import cache\n from importlib.metadata import (\n Distribution,\n EntryPoint,\n EntryPoints,\n PackageNotFoundError,\n- distributions,\n requires,\n version,\n )\n-from importlib.metadata import entry_points as original_entry_points\n-from typing import Any\n+from importlib.metadata import distributions as _all_distributions\n+from typing import Any, Iterable\n+\n+# opentelemetry-agent: entry points are only looked up in the vendored distributions' metadata\n+# (written to _vendor/_metadata by opentelemetry-vendor sync), never in the application's, whose\n+# OpenTelemetry plugins point at un-vendored modules. version() and requires() still see the\n+# application's distributions: instrumentors check the installed versions of the libraries they patch.\n+_VENDORED_METADATA_PATH = [\n+ os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), \"_metadata\")\n+]\n \n \n-def _as_entry_points(eps: Any) -> EntryPoints:\n- # Python versions greater than 3.11 return EntryPoints.\n- if isinstance(eps, EntryPoints):\n- return eps\n- # In Python 3.10 and 3.11 entry_points() returns\n- # a dict-like SelectableGroups object.\n- # Use dict.values() instead of eps.values() to avoid the DeprecationWarning\n- # that SelectableGroups raises when calling .values().\n- if isinstance(eps, dict):\n- return EntryPoints(itertools.chain.from_iterable(dict.values(eps)))\n- # This case should be unreachable, but is included as a fallback.\n- return EntryPoints(ep for group in eps.groups for ep in eps.select(group=group))\n+def distributions(**kwargs: Any) -> Iterable[Distribution]:\n+ return _all_distributions(path=_VENDORED_METADATA_PATH, **kwargs)\n \n \n @cache\n def _original_entry_points_cached() -> EntryPoints:\n- return _as_entry_points(original_entry_points())\n+ return EntryPoints(entry_point for dist in distributions() for entry_point in dist.entry_points)\n \n \n def entry_points(**params) -> EntryPoints:\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + } + ] + }, + "purl": "pkg:pypi/opentelemetry-util-http@0.66b2", + "type": "library", + "version": "0.66b2" + }, + { + "bom-ref": "pkg:pypi/packaging@26.3", + "hashes": [ + { + "alg": "SHA-256", + "content": "d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 OR BSD-2-Clause" + } + ], + "name": "packaging", + "purl": "pkg:pypi/packaging@26.3", + "type": "library", + "version": "26.3" + }, + { + "bom-ref": "pkg:pypi/prometheus-client@0.26.0", + "hashes": [ + { + "alg": "SHA-256", + "content": "fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6" + } + ], + "licenses": [ + { + "expression": "Apache-2.0 AND BSD-2-Clause" + } + ], + "name": "prometheus-client", + "purl": "pkg:pypi/prometheus-client@0.26.0", + "type": "library", + "version": "0.26.0" + }, + { + "bom-ref": "pkg:pypi/protobuf@7.36.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "bdb3a345d48db958e6ce1f18e508beb0cc981d64f24088427549c866cd039f1e" + } + ], + "licenses": [ + { + "license": { + "name": "3-Clause BSD License" + } + } + ], + "name": "protobuf", + "pedigree": { + "patches": [ + { + "diff": { + "text": { + "content": "Select the vendored protobuf implementation: upb when built, else pure Python.\n\nUpstream probes for the upb/cpp C extensions with importlib.import_module(\"google._upb._message\")\nand friends, which imports the application's protobuf by its top-level name, and honours\nPROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which is meant for the application's protobuf: \"cpp\" makes\ndescriptor.py import the missing vendored pyext and crash. Only the vendored upb extension (included in\nplatform builds of the agent, see patches/native/protobuf-upb.patch) is considered; otherwise the\npure-Python implementation is used.\n\ndiff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/internal/api_implementation.py\n--- a/google/protobuf/internal/api_implementation.py\n+++ b/google/protobuf/internal/api_implementation.py\n@@ -6,7 +6,6 @@\n # https://developers.google.com/open-source/licenses/bsd\n \"\"\"Determine which implementation of the protobuf API is used in this process.\"\"\"\n \n-import importlib\n import os\n import sys\n import warnings\n@@ -24,89 +23,19 @@ def _ApiVersionToImplementationType(api_version):\n return None\n \n \n-_implementation_type = None\n+# Only the vendored upb extension is considered (platform builds of the agent include it;\n+# the pure-Python build doesn't). Never probe for the application's google._upb /\n+# google.protobuf.pyext by their top-level names, and don't follow\n+# PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which configures the application's protobuf\n+# (e.g. \"cpp\" would make descriptor.py import the missing vendored pyext._message).\n try:\n # pylint: disable=g-import-not-at-top\n- from opentelemetry.agent._vendor.google.protobuf.internal import _api_implementation\n- # The compile-time constants in the _api_implementation module can be used to\n- # switch to a certain implementation of the Python API at build time.\n- _implementation_type = _ApiVersionToImplementationType(\n- _api_implementation.api_version\n- )\n-except ImportError:\n- pass # Unspecified by compiler flags.\n-\n-\n-def _CanImport(mod_name):\n- try:\n- mod = importlib.import_module(mod_name)\n- # Work around a known issue in the classic bootstrap .par import hook.\n- if not mod:\n- raise ImportError(mod_name + ' import succeeded but was None')\n- return True\n- except ImportError:\n- return False\n-\n-\n-if _implementation_type is None:\n- if _CanImport('google._upb._message'):\n- _implementation_type = 'upb'\n- elif _CanImport('google.protobuf.pyext._message'):\n- _implementation_type = 'cpp'\n- else:\n- _implementation_type = 'python'\n-\n-# This environment variable can be used to switch to a certain implementation\n-# of the Python API, overriding the compile-time constants in the\n-# _api_implementation module. Right now only 'python', 'cpp' and 'upb' are\n-# valid values. Any other value will raise error.\n-_implementation_type = os.getenv(\n- 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', _implementation_type\n-)\n-\n-if _implementation_type not in ('python', 'cpp', 'upb'):\n- raise ValueError(\n- 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION {0} is not '\n- \"supported. Please set to 'python', 'cpp' or \"\n- \"'upb'.\".format(_implementation_type)\n- )\n+ from opentelemetry.agent._vendor.google._upb import _message as _c_module\n \n-if 'PyPy' in sys.version and _implementation_type == 'cpp':\n- warnings.warn(\n- 'PyPy does not work yet with cpp protocol buffers. '\n- 'Falling back to the python implementation.'\n- )\n+ _implementation_type = 'upb'\n+except ImportError:\n _implementation_type = 'python'\n-\n-_c_module = None\n-\n-if _implementation_type == 'cpp':\n- try:\n- # pylint: disable=g-import-not-at-top\n- from opentelemetry.agent._vendor.google.protobuf.pyext import _message\n-\n- sys.modules['google3.net.proto2.python.internal.cpp._message'] = _message\n- _c_module = _message\n- del _message\n- except ImportError:\n- # TODO: fail back to python\n- warnings.warn('Selected implementation cpp is not available.')\n- pass\n-\n-if _implementation_type == 'upb':\n- try:\n- # pylint: disable=g-import-not-at-top\n- from opentelemetry.agent._vendor.google._upb import _message\n-\n- _c_module = _message\n- del _message\n- except ImportError:\n- warnings.warn(\n- 'Selected implementation upb is not available. '\n- 'Falling back to the python implementation.'\n- )\n- _implementation_type = 'python'\n- pass\n+ _c_module = None\n \n # Detect if serialization should be deterministic by default\n try:\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + } + ] + }, + "purl": "pkg:pypi/protobuf@7.36.2", + "type": "library", + "version": "7.36.2" + }, + { + "bom-ref": "pkg:pypi/requests@2.34.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0" + } + } + ], + "name": "requests", + "pedigree": { + "patches": [ + { + "diff": { + "text": { + "content": "Disable the requests.packages compatibility aliases.\n\nUpstream imports urllib3/idna/chardet by their top-level names and registers them as\n`requests.packages.*` in the global sys.modules, which would load and alias the\napplication's own packages.\n\ndiff --git a/requests/packages.py b/requests/packages.py\n--- a/requests/packages.py\n+++ b/requests/packages.py\n@@ -1,23 +1,4 @@\n-import sys\n-\n-from .compat import chardet\n-\n-# This code exists for backwards compatibility reasons.\n-# I don't like it either. Just look the other way. :)\n-\n-for package in (\"urllib3\", \"idna\"):\n- locals()[package] = __import__(package)\n- # This traversal is apparently necessary such that the identities are\n- # preserved (requests.packages.urllib3.* is urllib3.*)\n- for mod in list(sys.modules):\n- if mod == package or mod.startswith(f\"{package}.\"):\n- sys.modules[f\"requests.packages.{mod}\"] = sys.modules[mod]\n-\n-if chardet is not None:\n- target = chardet.__name__\n- for mod in list(sys.modules):\n- if mod == target or mod.startswith(f\"{target}.\"):\n- imported_mod = sys.modules[mod]\n- sys.modules[f\"requests.packages.{mod}\"] = imported_mod\n- mod = mod.replace(target, \"chardet\")\n- sys.modules[f\"requests.packages.{mod}\"] = imported_mod\n+# The upstream module imports urllib3, idna and chardet by their top-level names and\n+# registers them as `requests.packages.*` in the global sys.modules. In the vendored copy\n+# that would load (and alias) the application's own packages, so the backwards\n+# compatibility aliases are disabled.\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + }, + { + "diff": { + "text": { + "content": "Use the vendored charset_normalizer instead of looking up chardet.\n\nUpstream prefers an installed chardet (via importlib.import_module and a version\nimport), which would load the application's package.\n\ndiff --git a/requests/__init__.py b/requests/__init__.py\n--- a/requests/__init__.py\n+++ b/requests/__init__.py\n@@ -51,10 +51,8 @@ try:\n except ImportError:\n charset_normalizer_version = None\n \n-try:\n- from chardet import __version__ as chardet_version # type: ignore[import-not-found]\n-except ImportError:\n- chardet_version = None\n+# Only the vendored charset_normalizer is used, never the application's chardet.\n+chardet_version = None\n \n \n def check_compatibility(\ndiff --git a/requests/compat.py b/requests/compat.py\n--- a/requests/compat.py\n+++ b/requests/compat.py\n@@ -34,19 +34,8 @@ except (TypeError, AttributeError):\n # -------------------\n \n \n-def _resolve_char_detection() -> ModuleType | None:\n- \"\"\"Find supported character detection libraries.\"\"\"\n- chardet = None\n- for lib in (\"chardet\", \"charset_normalizer\"):\n- if chardet is None:\n- try:\n- chardet = importlib.import_module(lib)\n- except ImportError:\n- pass\n- return chardet\n-\n-\n-chardet = _resolve_char_detection()\n+# Always use the vendored charset_normalizer, never the application's chardet.\n+from opentelemetry.agent._vendor import charset_normalizer as chardet\n \n # -------\n # Pythons\n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + } + ] + }, + "purl": "pkg:pypi/requests@2.34.2", + "type": "library", + "version": "2.34.2" + }, + { + "bom-ref": "pkg:pypi/ruamel-yaml@0.19.1", + "hashes": [ + { + "alg": "SHA-256", + "content": "27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "ruamel-yaml", + "pedigree": { + "patches": [ + { + "diff": { + "text": { + "content": "Never load the libyaml binding in the vendored ruamel.yaml.\n\nruamel.yaml imports the optional C parser and emitter from the _ruamel_yaml extension module\n(ruamel.yaml.clib), which would be the application's, not vendored. ruamel/yaml/cyaml.py is dropped; this\npatch makes main.py fall back to the pure-Python implementation unconditionally.\n\ndiff --git a/ruamel/yaml/main.py b/ruamel/yaml/main.py\nindex fdf7c72..5e23910 100644\n--- a/ruamel/yaml/main.py\n+++ b/ruamel/yaml/main.py\n@@ -42,10 +42,9 @@ if False: # MYPY\n from types import TracebackType\n from pathlib import Path\n \n-try:\n- from _ruamel_yaml import CParser, CEmitter # type: ignore\n-except: # NOQA\n- CParser = CEmitter = None\n+# opentelemetry-agent: always use the pure-Python parser and emitter; the libyaml binding\n+# (_ruamel_yaml) would be the application's, not vendored.\n+CParser = CEmitter = None\n \n # import io\n \n", + "contentType": "text/plain" + } + }, + "type": "unofficial" + } + ] + }, + "purl": "pkg:pypi/ruamel-yaml@0.19.1", + "type": "library", + "version": "0.19.1" + }, + { + "bom-ref": "pkg:pypi/typing-extensions@4.16.0", + "hashes": [ + { + "alg": "SHA-256", + "content": "481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8" + } + ], + "licenses": [ + { + "license": { + "id": "PSF-2.0" + } + } + ], + "name": "typing-extensions", + "purl": "pkg:pypi/typing-extensions@4.16.0", + "type": "library", + "version": "4.16.0" + }, + { + "bom-ref": "pkg:pypi/urllib3@2.8.0", + "hashes": [ + { + "alg": "SHA-256", + "content": "0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3" + } + ], + "licenses": [ + { + "license": { + "id": "MIT" + } + } + ], + "name": "urllib3", + "purl": "pkg:pypi/urllib3@2.8.0", + "type": "library", + "version": "2.8.0" + }, + { + "bom-ref": "pkg:pypi/wrapt@2.5.2", + "hashes": [ + { + "alg": "SHA-256", + "content": "61eb54e9540ea522c2c4752a57549a83d3c67e6704ed708403d28e067aaf90f0" + } + ], + "licenses": [ + { + "license": { + "id": "BSD-2-Clause" + } + } + ], + "name": "wrapt", + "purl": "pkg:pypi/wrapt@2.5.2", + "type": "library", + "version": "2.5.2" + } + ], + "dependencies": [ + { + "ref": "pkg:pypi/certifi@2026.10.23" + }, + { + "ref": "pkg:pypi/charset-normalizer@3.5.2" + }, + { + "ref": "pkg:pypi/fastjsonschema@2.22.3" + }, + { + "ref": "pkg:pypi/googleapis-common-protos@1.76.0" + }, + { + "ref": "pkg:pypi/idna@3.20" + }, + { + "ref": "pkg:pypi/opentelemetry-api@1.45.2" + }, + { + "ref": "pkg:pypi/opentelemetry-configuration@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-distro@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-http-transport@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-otlp-common@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-otlp-json-common@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-otlp-json-file@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-otlp-json-http@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-common@1.45.2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-http@1.45.2" + }, + { + "ref": "pkg:pypi/opentelemetry-exporter-prometheus@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-instrumentation-aiohttp-client@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-instrumentation@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-propagator-b3@1.45.2" + }, + { + "ref": "pkg:pypi/opentelemetry-proto-json@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-proto@1.45.2" + }, + { + "ref": "pkg:pypi/opentelemetry-sdk@1.45.2" + }, + { + "ref": "pkg:pypi/opentelemetry-semantic-conventions@0.66b2" + }, + { + "ref": "pkg:pypi/opentelemetry-util-http@0.66b2" + }, + { + "ref": "pkg:pypi/packaging@26.3" + }, + { + "ref": "pkg:pypi/prometheus-client@0.26.0" + }, + { + "ref": "pkg:pypi/protobuf@7.36.2" + }, + { + "ref": "pkg:pypi/requests@2.34.2" + }, + { + "ref": "pkg:pypi/ruamel-yaml@0.19.1" + }, + { + "ref": "pkg:pypi/typing-extensions@4.16.0" + }, + { + "ref": "pkg:pypi/urllib3@2.8.0" + }, + { + "ref": "pkg:pypi/wrapt@2.5.2" + } + ], + "metadata": {}, + "serialNumber": "urn:uuid:68c0eaa7-7e90-530a-b51b-92b28a55e1b4", + "version": 1, + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6" +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE new file mode 100644 index 00000000000..62b076cdee5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE @@ -0,0 +1,20 @@ +This package contains a modified version of ca-bundle.crt: + +ca-bundle.crt -- Bundle of CA Root Certificates + +This is a bundle of X.509 certificates of public Certificate Authorities +(CA). These were automatically extracted from Mozilla's root certificates +file (certdata.txt). This file can be found in the mozilla source tree: +https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt +It contains the certificates in PEM format and therefore +can be directly used with curl / libcurl / php_curl, or with +an Apache+mod_ssl webserver for SSL client authentication. +Just configure this file as the SSLCACertificateFile.# + +***** BEGIN LICENSE BLOCK ***** +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain +one at http://mozilla.org/MPL/2.0/. + +***** END LICENSE BLOCK ***** +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py new file mode 100644 index 00000000000..1a9a755b6b6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py @@ -0,0 +1,4 @@ +from .core import contents, where + +__all__ = ["contents", "where"] +__version__ = "2026.10.23" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem new file mode 100644 index 00000000000..7b1cc2d81b6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem @@ -0,0 +1,3885 @@ + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL +BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ +SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n +a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 +NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT +CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u +Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO +dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI +VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV +9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY +2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY +vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt +bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb +x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ +l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK +TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj +Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw +DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG +7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk +MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr +gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk +GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS +3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm +Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ +l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c +JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP +L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa +LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG +mpv0 +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- + +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" +# Serial: 131542671362353147877283741781055151509 +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy +v+c= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Label: "GlobalSign Root R46" +# Serial: 1552617688466950547958867513931858518042577 +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Label: "GlobalSign Root E46" +# Serial: 1552617690338932563915843282459653771421763 +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Label: "ANF Secure Server Root CA" +# Serial: 996390341000653745 +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV +BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk +YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV +BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN +MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF +UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD +VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v +dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj +cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q +yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH +2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX +H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL +zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR +p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz +W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ +SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn +LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 +n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B +u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L +9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej +rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK +pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 +vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq +OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ +/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 +2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI ++PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 +MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo +tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= +-----END CERTIFICATE----- + +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum EC-384 CA" +# Serial: 160250656287871593594747141429395092468 +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Root CA" +# Serial: 40870380103424195783807378461123655149 +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd +-----BEGIN CERTIFICATE----- +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6 +MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu +MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV +BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw +MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg +U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ +n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q +p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq +NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF +8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3 +HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa +mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi +7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF +ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P +qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ +v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6 +Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD +ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4 +WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo +zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR +5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ +GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf +5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq +0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D +P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM +qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP +0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf +E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb +-----END CERTIFICATE----- + +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Label: "TunTrust Root CA" +# Serial: 108534058042236574382096126452369648152337120275 +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS RSA Root CA 2021" +# Serial: 76817823531813593706434026085292783742 +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU +63ZTGI0RmLo= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS ECC Root CA 2021" +# Serial: 137515985548005187474074462014555733966 +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication ECC RootCA1" +# Serial: 15446673492073852651 +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA1" +# Serial: 113562791157148395269083148143378328608 +# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 +# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a +# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU +MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI +T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz +MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF +SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh +bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z +xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ +spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 +58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR +at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll +5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq +nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK +V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ +pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO +z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn +jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ +WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF +7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli +awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u ++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 +X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN +SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo +P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI ++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz +znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 +eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 +YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy +r/6zcCwupvI= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA2" +# Serial: 58605626836079930195615843123109055211 +# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c +# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 +# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw +CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ +VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy +MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ +TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS +b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B +IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ ++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK +sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA +94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B +43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root E46" +# Serial: 88989738453351742415770396670917916916 +# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 +# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a +# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root R46" +# Serial: 156256931880233212765902055439220583700 +# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 +# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 +# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS RSA Root CA 2022" +# Serial: 148535279242832292258835760425842727825 +# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da +# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca +# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS ECC Root CA 2022" +# Serial: 26605119622390491762507526719404364228 +# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 +# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 +# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA ECC TLS 2021" +# Serial: 81873346711060652204712539181482831616 +# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 +# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd +# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w +LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w +CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 +MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF +Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X +tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 +AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 +KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD +aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu +CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo +9H1/IISpQuQo +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA RSA TLS 2021" +# Serial: 111436099570196163832749341232207667876 +# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 +# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 +# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM +MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx +MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 +MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD +QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z +4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv +Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ +kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs +GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln +nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh +3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD +0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy +geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 +ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB +c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI +pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs +o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ +qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw +xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM +rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 +AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR +0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY +o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 +dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE +oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G3" +# Serial: 576386314500428537169965010905813481816650257167 +# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04 +# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7 +# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08 +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM +BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp +ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe +Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw +IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU +cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS +T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK +AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 +nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep +qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA +yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs +hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX +zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv +kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT +f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA +uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB +o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih +MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 +wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 +XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 +JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j +ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV +VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx +xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on +AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d +7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj +gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV ++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo +FGWsJwt0ivKH +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G4" +# Serial: 451799571007117016466790293371524403291602933463 +# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb +# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a +# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw +WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y +MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD +VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz +dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx +s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw +LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD +pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE +AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR +UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj +/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS ECC Root 2020" +# Serial: 72082518505882327255703894282316633856 +# MD5 Fingerprint: c1:ab:fe:6a:10:2c:03:8d:bc:1c:22:32:c0:85:a7:fd +# SHA1 Fingerprint: c0:f8:96:c5:a9:3b:01:06:21:07:da:18:42:48:bc:e9:9d:88:d5:ec +# SHA256 Fingerprint: 57:8a:f4:de:d0:85:3f:4e:59:98:db:4a:ea:f9:cb:ea:8d:94:5f:60:b6:20:a3:8d:1a:3c:13:b2:bc:7b:a8:e1 +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw +CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH +bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw +MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx +JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE +AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O +tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP +f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA +MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di +z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn +27iQ7t0l +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS RSA Root 2023" +# Serial: 44676229530606711399881795178081572759 +# MD5 Fingerprint: bf:5b:eb:54:40:cd:48:71:c4:20:8d:7d:de:0a:42:f2 +# SHA1 Fingerprint: 54:d3:ac:b3:bd:57:56:f6:85:9d:ce:e5:c3:21:e2:d4:ad:83:d0:93 +# SHA256 Fingerprint: ef:c6:5c:ad:bb:59:ad:b6:ef:e8:4d:a2:23:11:b3:56:24:b7:1b:3b:1e:a0:da:8b:66:55:17:4e:c8:97:86:46 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj +MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0 +eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy +MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC +REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG +A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9 +cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV +cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA +U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6 +Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug +BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy +8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J +co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg +8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8 +rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12 +mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg ++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX +gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ +pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm +9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw +M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd +GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+ +CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t +xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+ +w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK +L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj +X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q +ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm +dTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA CYBER Root CA" +# Serial: 85076849864375384482682434040119489222 +# MD5 Fingerprint: 0b:33:a0:97:52:95:d4:a9:fd:bb:db:6e:a3:55:5b:51 +# SHA1 Fingerprint: f6:b1:1c:1a:83:38:e9:7b:db:b3:a8:c8:33:24:e0:2d:9c:7f:26:66 +# SHA256 Fingerprint: 3f:63:bb:28:14:be:17:4e:c8:b6:43:9c:f0:8d:6d:56:f0:b7:c4:05:88:3a:56:48:a3:34:42:4d:6b:3e:c5:58 +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ +MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290 +IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5 +WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO +LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P +40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF +avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/ +34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i +JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu +j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf +Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP +2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA +S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA +oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC +kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW +5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd +BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t +tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn +68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn +TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t +RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx +f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI +Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz +8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4 +NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX +xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6 +t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA14" +# Serial: 575790784512929437950770173562378038616896959179 +# MD5 Fingerprint: 71:0d:72:fa:92:19:65:5e:89:04:ac:16:33:f0:bc:d5 +# SHA1 Fingerprint: dd:50:c0:f7:79:b3:64:2e:74:a2:b8:9d:9f:d3:40:dd:bb:f0:f2:4f +# SHA256 Fingerprint: 4b:00:9c:10:34:49:4f:9a:b5:6b:ba:3b:a1:d6:27:31:fc:4d:20:d8:95:5a:dc:ec:10:a9:25:60:72:61:e3:38 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM +BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u +LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw +NzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD +eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS +b290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh1oq/ +FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOg +vlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy +6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo +/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9J +kdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ +0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXib +y8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac +18izju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs +0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIAB +SMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVL +ApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk +86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ib +ed87hwriZLoAymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopT +zfFP7ELyk+OZpDc8h7hi2/DsHzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHS +DCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPGFrojutzdfhrGe0K22VoF3Jpf1d+4 +2kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6qnsb58Nn4DSEC5MUo +FlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/OfVy +K4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6 +dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl +Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB +365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c +JRNItX+S +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA15" +# Serial: 126083514594751269499665114766174399806381178503 +# MD5 Fingerprint: 13:30:fc:c4:62:a6:a9:de:b5:c1:68:af:b5:d2:31:47 +# SHA1 Fingerprint: cb:ba:83:c8:c1:5a:5d:f1:f9:73:6f:ca:d7:ef:28:13:06:4a:07:7d +# SHA256 Fingerprint: e7:78:f0:f0:95:fe:84:37:29:cd:1a:00:82:17:9e:53:14:a9:c2:91:44:28:05:e1:fb:1d:8f:b6:b8:88:6c:3a +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw +UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM +dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy +NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl +cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290 +IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4 +wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR +ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT +9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp +4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6 +bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 2 2023" +# Serial: 153168538924886464690566649552453098598 +# MD5 Fingerprint: e1:09:ed:d3:60:d4:56:1b:47:1f:b7:0c:5f:1b:5f:85 +# SHA1 Fingerprint: 2d:b0:70:ee:71:94:af:69:68:17:db:79:ce:58:9f:a0:6b:96:f7:87 +# SHA256 Fingerprint: 05:52:e6:f8:3f:df:65:e8:fa:96:70:e6:66:df:28:a4:e2:13:40:b5:10:cb:e5:25:66:f9:7c:4f:b9:4b:2b:d1 +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI +MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE +LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw +OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi +MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr +i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE +gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8 +k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT +Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl +2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U +cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP +/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS +uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+ +0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N +DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+ +XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61 +GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG +OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI +FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n +riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR +VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc +LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn +4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD +hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG +koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46 +ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS +Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80 +knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ +hJ65bvspmZDogNOfJA== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. +# Label: "TrustAsia TLS ECC Root CA" +# Serial: 310892014698942880364840003424242768478804666567 +# MD5 Fingerprint: 09:48:04:77:d2:fc:65:93:71:66:b1:11:95:4f:06:8c +# SHA1 Fingerprint: b5:ec:39:f3:a1:66:37:ae:c3:05:94:57:e2:be:11:be:b7:a1:7f:36 +# SHA256 Fingerprint: c0:07:6b:9e:f0:53:1f:b1:a6:56:d6:7c:4e:be:97:cd:5d:ba:a4:1e:f4:45:98:ac:c2:48:98:78:c9:2d:87:11 +-----BEGIN CERTIFICATE----- +MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMw +WDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQw +NTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBYMQswCQYDVQQGEwJDTjElMCMGA1UE +ChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1c3RB +c2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/pVs/ +AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDp +guMqWzJ8S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAw +DgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01 +L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15KeAIxAKORh/IRM4PDwYqR +OkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. +# Label: "TrustAsia TLS RSA Root CA" +# Serial: 160405846464868906657516898462547310235378010780 +# MD5 Fingerprint: 3b:9e:c3:86:0f:34:3c:6b:c5:46:c4:8e:1d:e7:19:12 +# SHA1 Fingerprint: a5:46:50:c5:62:ea:95:9a:1a:a7:04:6f:17:58:c7:29:53:3d:03:fa +# SHA256 Fingerprint: 06:c0:8d:7d:af:d8:76:97:1e:b1:12:4f:e6:7f:84:7e:c0:c7:a1:58:d3:ea:53:cb:e9:40:e2:ea:97:91:f4:c3 +-----BEGIN CERTIFICATE----- +MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEM +BQAwWDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp +ZXMsIEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcN +MjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2WjBYMQswCQYDVQQGEwJDTjElMCMG +A1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1 +c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC +AgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+ +NmDQDIPNlOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJ +Q1DNDX3eRA5gEk9bNb2/mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561 +HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fkzv93uMltrOXVmPGZLmzjyUT5tUMnCE32 +ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYozza/+lcK7Fs/6TAWe8Tb +xNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyrz2I8sMeX +i9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQ +UNoyIBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+j +TnhMmCWr8n4uIF6CFabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DT +bE3txci3OE9kxJRMT6DNrqXGJyV1J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8 +S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnTq1mt1tve1CuBAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZylomkadFK/hT +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3 +Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4 +iqME3mmL5Dw8veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt +7DlK9RME7I10nYEKqG/odv6LTytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp +2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHxtlotJnMnlvm5P1vQiJ3koP26TpUJ +g3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp27RIGAAtvKLEiUUj +pQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87qqA8M +pugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongP +XvPKnbwbPKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIwe +SsCI3zWQzj8C9GRh3sfIB5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0 +ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNzFrwFuHnYWa8G5z9nODmxfKuU4CkUpijy +323imttUQ/hHWKNddBWcwauwxzQ= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 2 2023" +# Serial: 139766439402180512324132425437959641711 +# MD5 Fingerprint: 96:b4:78:09:f0:09:cb:77:eb:bb:1b:4d:6f:36:bc:b6 +# SHA1 Fingerprint: a5:5b:d8:47:6c:8f:19:f7:4c:f4:6d:6b:b6:c2:79:82:22:df:54:8b +# SHA256 Fingerprint: 8e:82:21:b2:e7:d4:00:78:36:a1:67:2f:0d:cc:29:9c:33:bc:07:d3:16:f1:32:fa:1a:20:6d:58:71:50:f1:ce +-----BEGIN CERTIFICATE----- +MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI +MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE +LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw +OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi +MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK +F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE +7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe +EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6 +lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb +RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV +jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc +jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx +TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ +ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk +hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF +NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH +kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG +OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y +XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14 +QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4 +pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q +3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU +t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX +cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8 +ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT +2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs +7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP +gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst +Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh +XBxvWHZks/wCuPWdCg== +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG +# Subject: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG +# Label: "SwissSign RSA TLS Root CA 2022 - 1" +# Serial: 388078645722908516278762308316089881486363258315 +# MD5 Fingerprint: 16:2e:e4:19:76:81:85:ba:8e:91:58:f1:15:ef:72:39 +# SHA1 Fingerprint: 81:34:0a:be:4c:cd:ce:cc:e7:7d:cc:8a:d4:57:e2:45:a0:77:5d:ce +# SHA256 Fingerprint: 19:31:44:f4:31:e0:fd:db:74:07:17:d4:de:92:6a:57:11:33:88:4b:43:60:d3:0e:27:29:13:cb:e6:60:ce:41 +-----BEGIN CERTIFICATE----- +MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE +AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx +MTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxT +d2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0EgVExTIFJvb3QgQ0Eg +MjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmjiC8NX +vDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7 +LCTLf5ImgKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX +5XH8irCRIFucdFJtrhUnWXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyE +EPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlfGUEGjw5NBuBwQCMBauTLE5tzrE0USJIt +/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36qOTw7D59Ke4LKa2/KIj4x +0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLOEGrOyvi5 +KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM +0ZPlEuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shd +OxtYk8EXlFXIC+OCeYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrta +clXvyFu1cvh43zcgTFeRc5JzrBh3Q4IgaezprClG5QtO+DdziZaKHG29777YtvTK +wP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQABo2MwYTAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow4UD2p8P98Q+4 +DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL +BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO3 +10aewCoSPY6WlkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgz +Hqp41eZUBDqyggmNzhYzWUUo8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQ +iJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zpy1FVCypM9fJkT6lc/2cyjlUtMoIc +gC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3CjlvrzG4ngRhZi0Rjn9UM +ZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6MOuhF +LhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJp +zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td +Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0 +rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO +gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ +-----END CERTIFICATE----- + +# Issuer: CN=OISTE Server Root ECC G1 O=OISTE Foundation +# Subject: CN=OISTE Server Root ECC G1 O=OISTE Foundation +# Label: "OISTE Server Root ECC G1" +# Serial: 47819833811561661340092227008453318557 +# MD5 Fingerprint: 42:a7:d2:35:ae:02:92:db:19:76:08:de:2f:05:b4:d4 +# SHA1 Fingerprint: 3b:f6:8b:09:ae:2a:92:7b:ba:e3:8d:3f:11:95:d9:e6:44:0c:45:e2 +# SHA256 Fingerprint: ee:c9:97:c0:c3:0f:21:6f:7e:3b:8b:30:7d:2b:ae:42:41:2d:75:3f:c8:21:9d:af:d1:52:0b:25:72:85:0f:49 +-----BEGIN CERTIFICATE----- +MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQsw +CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY +T0lTVEUgU2VydmVyIFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUy +NDE0NDIyN1owSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRp +b24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IEVDQyBHMTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPoH7d5qVi2+GXROiFPqOujvqQy +cvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4LrQ95SjeHIC6XG4N +2xml4z+cKrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQ3 +TYhlz/w9itWj8UnATgwQb0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9C +tJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCpKjAd0MKfkFFR +QD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxgZzFDJe0CMQCSia7pXGKD +YmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE Server Root RSA G1 O=OISTE Foundation +# Subject: CN=OISTE Server Root RSA G1 O=OISTE Foundation +# Label: "OISTE Server Root RSA G1" +# Serial: 113845518112613905024960613408179309848 +# MD5 Fingerprint: 23:a7:9e:d4:70:b8:b9:14:57:41:8a:7e:44:59:e2:68 +# SHA1 Fingerprint: f7:00:34:25:94:88:68:31:e4:34:87:3f:70:fe:86:b3:86:9f:f0:6e +# SHA256 Fingerprint: 9a:e3:62:32:a5:18:9f:fd:db:35:3d:fd:26:52:0c:01:53:95:d2:27:77:da:c5:9d:b5:7b:98:c0:89:a6:51:e6 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBL +MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE +AwwYT0lTVEUgU2VydmVyIFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4 +MDUyNDE0MzcxNVowSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5k +YXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IFJTQSBHMTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuCz/vlNwvn1ZatkOhLKdxVYOPM +vLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnwYx4M0rH/1ow00O7b +rEi56rAUjtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8JnduodgsIUzk +ik/HEzxux9UTl7Ko2yRpg1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4z +O8vbUZeUapU8zhhabkvG/AePLhq5SvdkNCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8R +tOpXaZ+0AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY+m0o/DjH40ytas7ZTpOS +jswMZ78LS5bOZmdTaMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+lKXHiHUh +sd4JJCpM4rzsTGdHwimIuQq6+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+Ho +mnqT8eDI278n5mUpezbgMxVz8p1rhAhoKzYHKyfMeNhqhw5HdPSqoBNdZH702xSu ++zrkL8Fl47l6QGzwBrd7KJvX4V84c5Ss2XCTLdyEr0YconosP4EmQufU2MVshGYR +i3drVByjtdgQ8K4p92cIiBdcuJd5z+orKu5YM+Vt6SmqZQENghPsJQtdLEByFSnT +kCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU +8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC77EUOSh+1sbM2 +zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33 +I3K5Ce+SrScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG +5D1rd9QhEOP28yBOqb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8 +qyiWXmFcuCIzGEgWUOrKL+mlSdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dP +AGav9LEDOr4SfEE15fSmG0eLy3n31r8Xbk5l8PjaV8GUgeV6Vg27Rn9vkf195hfk +gSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2abtNUOshD+FKrDgHGdPY3ofRRs +YWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNqqYY1 +9tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7ph6N/Ome +/msVuduCmsuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3 +J8tRd/iWkx7P8nd9H0aTolkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2 +wq1yVAb+axj5d9spLFKebXd7Yv0PTY6YMjAwcRLWJTXjn/hvnLXrahut6hDTlhZy +BiElxky8j3C7DOReIoMt0r7+hVu05L0= +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. +# Subject: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. +# Label: "e-Szigno TLS Root CA 2023" +# Serial: 71934828665710877219916191754 +# MD5 Fingerprint: 6a:e9:99:74:a5:da:5e:f1:d9:2e:f2:c8:d1:86:8b:71 +# SHA1 Fingerprint: 6f:9a:d5:d5:df:e8:2c:eb:be:37:07:ee:4f:4f:52:58:29:41:d1:fe +# SHA256 Fingerprint: b4:91:41:50:2d:00:66:3d:74:0f:2e:7e:c3:40:c5:28:00:96:26:66:12:1a:36:d0:9c:f7:dd:2b:90:38:4f:b4 +-----BEGIN CERTIFICATE----- +MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xFzAVBgNVBGEMDlZBVEhVLTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBU +TFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0MDAwMFoXDTM4MDcxNzE0MDAwMFow +dTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYwFAYDVQQKDA1NaWNy +b3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZZS1T +emlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAE +AGgP36J8PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFS +AL/fjO1ZrTJlqwlZULUZwmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/v +SzUaQ49CE0y5LBqcvjC2xN7cS53kpDzLLtmt3999Cd8ukv+ho2MwYTAPBgNVHRMB +Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUWYQCYlpGePVd3I8K +ECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0UwCgYIKoZI +zj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpt +y7Ve7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZl +C9p2x1L/Cx6AcCIwwzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6 +uWWL +-----END CERTIFICATE----- + +# Issuer: CN=SECOM TLS RSA Root CA 2024 O=SECOM Trust Systems Co., Ltd. +# Subject: CN=SECOM TLS RSA Root CA 2024 O=SECOM Trust Systems Co., Ltd. +# Label: "SECOM TLS RSA Root CA 2024" +# Serial: 17188327524208271538 +# MD5 Fingerprint: d0:a4:db:32:eb:44:98:d2:62:0b:3e:bc:4d:7c:5c:e9 +# SHA1 Fingerprint: fb:97:96:7c:ef:8d:98:63:06:c0:3b:b6:11:f8:e0:13:97:a2:98:d3 +# SHA256 Fingerprint: 14:35:f2:25:c5:d2:52:d7:a2:19:48:cc:3c:e6:2a:ec:fa:88:00:1e:3d:d7:2d:1c:c3:55:51:00:eb:37:2f:93 +-----BEGIN CERTIFICATE----- +MIIFmjCCA4KgAwIBAgIJAO6JNNDLgOCyMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNV +BAYTAkpQMSYwJAYDVQQKEx1TRUNPTSBUcnVzdCBTeXN0ZW1zIENvLiwgTHRkLjEj +MCEGA1UEAxMaU0VDT00gVExTIFJTQSBSb290IENBIDIwMjQwHhcNMjQwMTMxMDUx +MTU1WhcNNDkwMTE0MDUxMTU1WjBaMQswCQYDVQQGEwJKUDEmMCQGA1UEChMdU0VD +T00gVHJ1c3QgU3lzdGVtcyBDby4sIEx0ZC4xIzAhBgNVBAMTGlNFQ09NIFRMUyBS +U0EgUm9vdCBDQSAyMDI0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA +4TjizUwzxbInq8Tx11gaFYNk5fO+34y7TyM4neh0UgL5JIZbJNLTz2x//L/B71+5 +m6X6nGIr7d4lFJBGtjO677hXOz93zkcWaUTm3VbOAjBlt4YWxlcccBHXuZ7o3Q+4 +R+ormrBdHeJ1CTUEG8ttQbKIl3G7OZYbnH8/pP8cjPub/0kDVNuMzp7xsVRROOis +Qt53fMoJLlYgoebbuMphOqMCtjkJ7R6efEMfLp8UAVi9ZaLRn76ET/CJkk925ndu +uufC4BatS4mnXFmxN0vUXb0ij9B8O/D8gixQEsVSD4GK8FWRPh3bVd/6bzdkHGJj +y21XI0yejVomZUbRrOfNuz0boPGV1pt18fFC39IHQEth3OFqb5NDO3L+A9bNqTgA +yUgRmIn4ucgDc/Ri/Km3V51ueZjy1/yk0qwJVadAVVrCt56iNeXOyEvzJADGgDQ8 +E1Pdaqct8Cynz/47ReQM62vFYO08wcQkrjmX/tesiko1V1yyaf6EfPzUFzmaGy9x +vkCwdbm15EdTolOjE0H2Vb5/APDOyCFEokiYGmXTLdAUl0wKZ4IyjkHGzy0jhpaX +EXE/GJcEvI6VzEchjaBL03EJ0h9pG4OqeIOycKvAo3A+TbetyfsrgYyHzU0a7/qU +jGat1AAq1nVljMpKqpinPTsf/d9H39FTUeJL7TpzzjUCAwEAAaNjMGEwHQYDVR0O +BBYEFCzrchKOWHdkNRVWNQFXB6l9DTbmMB8GA1UdIwQYMBaAFCzrchKOWHdkNRVW +NQFXB6l9DTbmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBDAUAA4ICAQAVwsvluSafaez5tFPR/hRTBzRxEyMMQF3XJXCVi3yegZyK +oec7hmE6jx2ZM8KgM1kn2yJRwFXHX8zUW9nBLEDWc4wuE8LrlZqhGZM9pJQXGmGz +ResDJV6JgRBna+j4sA1M7yIdlvL0sAfFXFCTRaWTD4E1V99RLrFzWfTcC+e180hD +uNMpqOEo46+lMeW/Wvh7ifOQs+kiK0O2gHxQDNxslSavnCs4V7l8HRDJ2La10o70 +Bo7VLzf1W8MBvv0VTnxB+NjT5qTAbhGFh9Gvp4BaJpmdUf0C5CEP6dbQlfgxWfzY +r69yVT6dPQB+GFEaY03IMY+AcBCs+om1fNxrQXt9zoofMBNFbLhvpNH/JsXWdGUz +fNbO12uswTa5wah8LB18FTQN2/zPHYmvBEoLuyUgZ09VNLJo5YA0kXItVYkLjMe2 +SixzK4scUHv81IK99I91DWx7FwMVKw2xgFp+ZLYB2dnpQQrqwlW64glHUcK2N9BD +snjLSxeZ+UPECh9RxH4WAcKiZW+cqaKMmhP2WBfR4IcR7NOL32ml11ds87hhV1CZ +WWFCJAcCidYZz6CZa8exzHojP9SB5RH0/v1KdHAisqhSjtJl/UIAHIQ48elOn8wr +TdFap4Yb5aHglmMeNx+fAIhDluWVfxTO7H4dTPU+SFVRMLAh+wwKZfqb94nMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=SECOM TLS ECC Root CA 2024 O=SECOM Trust Systems Co., Ltd. +# Subject: CN=SECOM TLS ECC Root CA 2024 O=SECOM Trust Systems Co., Ltd. +# Label: "SECOM TLS ECC Root CA 2024" +# Serial: 9329818985461676612 +# MD5 Fingerprint: 99:d3:9d:e4:d2:b1:2d:f0:2a:04:67:85:f3:df:46:d6 +# SHA1 Fingerprint: 7a:1f:22:2d:72:b2:c3:19:87:44:db:61:69:e8:a6:4b:d7:0d:44:0e +# SHA256 Fingerprint: 6a:b2:ab:75:f5:1c:b4:f4:f0:15:62:03:fb:f6:f6:46:23:2f:51:4b:e0:59:f6:28:33:30:8b:82:b4:d7:2d:b1 +-----BEGIN CERTIFICATE----- +MIICTDCCAdGgAwIBAgIJAIF6LO+PI3pEMAoGCCqGSM49BAMDMFoxCzAJBgNVBAYT +AkpQMSYwJAYDVQQKEx1TRUNPTSBUcnVzdCBTeXN0ZW1zIENvLiwgTHRkLjEjMCEG +A1UEAxMaU0VDT00gVExTIEVDQyBSb290IENBIDIwMjQwHhcNMjQwMTMxMDU1MjM0 +WhcNNDkwMTE0MDU1MjM0WjBaMQswCQYDVQQGEwJKUDEmMCQGA1UEChMdU0VDT00g +VHJ1c3QgU3lzdGVtcyBDby4sIEx0ZC4xIzAhBgNVBAMTGlNFQ09NIFRMUyBFQ0Mg +Um9vdCBDQSAyMDI0MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7NzFMtu9dzQXSNC1 +2fabk0+GlC5finB3R7XaZonRUd20aFiWObtuNBCLUZSfk6QXAE55BjEXsXQ/NG8y +UqicXjsu9ksDK3JZBgCwLOVh6+nwJXTvso/dEj/GUYH5mBdoo2MwYTAdBgNVHQ4E +FgQUO3YReyl04k4GTFaCQNAhL3qzydUwHwYDVR0jBBgwFoAUO3YReyl04k4GTFaC +QNAhL3qzydUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZI +zj0EAwMDaQAwZgIxAN3ib8fi1pMYtAPjMilB5e5/H+t5CL0xPL+cZ5oTTZuSCjpA +n1v7F/VAr8bFxQXAowIxAKsBVO1ACFp7skwzPvdv1EUY5a897WGLT4lb+bjxFAWy +l8wDcZJdwGZ/pAHxt1AJ1g== +-----END CERTIFICATE----- + +# Issuer: CN=Telia EC TLS Root CA v3 O=Telia Company AB +# Subject: CN=Telia EC TLS Root CA v3 O=Telia Company AB +# Label: "Telia EC TLS Root CA v3" +# Serial: 8028200332079443110287896228123317 +# MD5 Fingerprint: b6:fa:6a:5c:42:fb:c5:67:72:c0:e0:2f:72:fb:5a:44 +# SHA1 Fingerprint: b4:d6:07:c2:a5:95:bc:5b:f4:67:4d:c9:dc:6f:6f:0a:00:7a:a5:35 +# SHA256 Fingerprint: 09:8e:08:a9:1d:bb:f7:74:78:b9:6c:ce:b8:9b:14:13:a5:da:37:b7:c8:62:60:6a:95:5d:eb:07:17:9f:43:26 +-----BEGIN CERTIFICATE----- +MIICMjCCAbegAwIBAgIPAYvSIlRjTQSLbOVHH9K1MAoGCCqGSM49BAMDMEoxCzAJ +BgNVBAYTAlNFMRkwFwYDVQQKDBBUZWxpYSBDb21wYW55IEFCMSAwHgYDVQQDDBdU +ZWxpYSBFQyBUTFMgUm9vdCBDQSB2MzAeFw0yMzExMTUwODU1MjZaFw00ODA1MjMx +MTAwMDBaMEoxCzAJBgNVBAYTAlNFMRkwFwYDVQQKDBBUZWxpYSBDb21wYW55IEFC +MSAwHgYDVQQDDBdUZWxpYSBFQyBUTFMgUm9vdCBDQSB2MzB2MBAGByqGSM49AgEG +BSuBBAAiA2IABMHIlhVDLbmFKUpW0iK4dpryT6emYOeS31JPwWnWPmkWRrAkTbPX +40sQfHI9mpR7Rbktu3ngg6W+BBSXSechtMCnBmWXj/EaVlmV5cY1jD2HoTfhBQ3A +acpCNMLJK4NpZaNjMGEwHwYDVR0jBBgwFoAU1GToQ4g6cy/QGnGCNgtehd7H3kMw +HQYDVR0OBBYEFNRk6EOIOnMv0BpxgjYLXoXex95DMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2kAMGYCMQCXAUdS/9bbJ8A1JYaG +f/bWt/s7Ta0ot5Ulno8OjSNYRWQIlS4tVWldvTAVA7heOFgCMQCvKr8+Z2Rn+OBr +5UHzlgBObpad1LuwNTRcdNgUJxIWadcki+UBLEi1/AURKV5md2M= +-----END CERTIFICATE----- + +# Issuer: CN=Telia RSA TLS Root CA v3 O=Telia Company AB +# Subject: CN=Telia RSA TLS Root CA v3 O=Telia Company AB +# Label: "Telia RSA TLS Root CA v3" +# Serial: 8028214673410753541795188766939845 +# MD5 Fingerprint: f4:8b:9c:f3:f8:63:cf:dc:25:8f:b4:bb:a2:e9:9d:e2 +# SHA1 Fingerprint: b5:2e:88:4e:40:c1:11:fb:50:c7:e2:4f:ac:18:2b:bd:68:15:d2:34 +# SHA256 Fingerprint: d1:3d:b1:29:4c:45:eb:c6:fc:86:c6:bb:f6:9f:a2:9b:df:e6:92:df:f7:c7:13:c2:43:c7:a9:56:c6:a2:28:4c +-----BEGIN CERTIFICATE----- +MIIFgjCCA2qgAwIBAgIPAYvSUKtCVSxHWr2h3BrFMA0GCSqGSIb3DQEBDAUAMEsx +CzAJBgNVBAYTAlNFMRkwFwYDVQQKDBBUZWxpYSBDb21wYW55IEFCMSEwHwYDVQQD +DBhUZWxpYSBSU0EgVExTIFJvb3QgQ0EgdjMwHhcNMjMxMTE1MDk0NzQyWhcNNDgw +NTIzMTEwMDAwWjBLMQswCQYDVQQGEwJTRTEZMBcGA1UECgwQVGVsaWEgQ29tcGFu +eSBBQjEhMB8GA1UEAwwYVGVsaWEgUlNBIFRMUyBSb290IENBIHYzMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsV89KG19hCf4S1Fvk8D3TyDERhmcvx8F +7Kmb4WATx3ije1id3KHxRE0TKmcNCbAQ57bvHFEYa4hR2l20VjVadExqOW+2ld99 +MbEiO+jRVOz+BbxLxJnmGwCqI+BfuTjjVReDxsxjQvjgBsClaO/sm5i70nlZcWGR +tIkvWDK3NNkT5RtwXc/O8NTFVpbUqT6cRjIj3olAblR+lRf4Ffy5o+Q9fabjYn9Z +9S4itruElcEFf9Ljk7fwdTycT/rvJW9w/B3G2a3r0f/zXNOVruIBcqE6pkSospAC +U2bG42fYKrbM/GWnp7u+p9Frz4jaNwpb4YHuEeS8BratNcP8X62jXIvvKHxlsMDJ +Cnb4U8JzFOLsU6mohVY58BdZrvi0Gk9UOuqmgoG6dskHoksjZTlK61D/InzmEoA1 +yAYJFDVysjRxDUOu9cAwANbqmq77WIFL6BpnZgVqPtMfG6wN8BrTKdapvilVsYR5 +9BFgIsAVBMxrGh+W+QcvmJafUpASvlArKvVG2FI4i6PiLjSBT0+6F6EQLrYqefOQ +F/fBNEXb+njUQ0SUVrAqtH4Y+OjCI/a4/JJQppxeemZcQ0SUShgiI5AM5xHO5iya +UrTjYH4zxUz9j+1FEbDH/xpstr1gXBykspup+hRTaJcbA+UbpJqtWZndAPddJmt6 +YJQ+dU3pDu8CAwEAAaNjMGEwHwYDVR0jBBgwFoAUsMep0t2yKFZzBJSMFFxIbzdS +kqgwHQYDVR0OBBYEFLDHqdLdsihWcwSUjBRcSG83UpKoMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQBdYzFsNGDRk7bR +/AgRKq+5637YuOW+w6uhpoS0VnKMUpyHCwku86hEvqivakPtfmlm4bFwt++sb/8O +XsWBqtfbXMaBNDTZl8XRMJuLWOW2JrbKkRzgG0eBUcvsadG1rrhbmZqYvFXaAZO7 +o4TdOZzxhBB5GOAWWXB3IeraNP4J63zyo9n8Gqw3sJBG44em5hoYjBffP+npibys +lnslRi4L6xHsCYj/Pab+OlqbMCB6v+sTCLeEIukRVzoR9aQ45pEK7Z1QBnSsbAKQ +tss0JKD9d/mX143H1xePjPhTXlv5JCkhrcj+SShz0P9+EHoWe6m9lyUEOIVn0rp+ +yVJWNbmyDv3VkwFxHC1ApSQsgSimjGQ4wtr6cSmordYxkV+Ro8lOIIhRksXPyDk2 +7gW6IjUXCkZKpxFjkL3jiBSc8SkxnwCWtXg8xwNwdFVNBGLCCuJnsneYXjJNqzRq +UcoGwzsvF3Qi/ZnHUNvISdevlgIAXL4Wvrxaqvoa01wB+GCfs57RTGE4TvAGhKNK +us8K3hRT1BSpigzMIRzSxtAOrqPN6j//QSmW9f8Jcncri4j2ihSpVrFU0NdNkMhZ +eAKidTFPsxCVFuW4Aniz7jqiw5sWtjbQrlW035izIEU4sYwQoC1Nx0Svy+mMTRai +50LqFQ+A1/Hq6xHHDNx7CI83d23Erw== +-----END CERTIFICATE----- diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py new file mode 100644 index 00000000000..79132e4501c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py @@ -0,0 +1,83 @@ +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem or its contents. +""" +import sys +import atexit + +def exit_cacert_ctx() -> None: + _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr] + + +if sys.version_info >= (3, 11): + + from importlib.resources import as_file, files + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = as_file(files(__package__).joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: + return files(__package__).joinpath("cacert.pem").read_text(encoding="ascii") + +else: + + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the + # file in cases where we're inside of a zipimport situation until + # someone actually calls where(), but we don't want to re-extract + # the file on every call of where(), so we'll do it once then store + # it in a global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you + # to manage the cleanup of this file, so it doesn't actually + # return a path, it returns a context manager that will give + # you the path when you enter it and will do any cleanup when + # you leave it. In the common case of not needing a temporary + # file, it will just return the file system location and the + # __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path(__package__, "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: + return read_text(__package__, "cacert.pem", encoding="ascii") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE new file mode 100644 index 00000000000..9725772c796 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 TAHRI Ahmed R. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py new file mode 100644 index 00000000000..73dcff44460 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py @@ -0,0 +1,48 @@ +""" +Charset-Normalizer +~~~~~~~~~~~~~~ +The Real First Universal Charset Detector. +A library that helps you read text from an unknown charset encoding. +Motivated by chardet, This package is trying to resolve the issue by taking a new approach. +All IANA character set names for which the Python core library provides codecs are supported. + +Basic usage: + >>> from charset_normalizer import from_bytes + >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8')) + >>> best_guess = results.best() + >>> str(best_guess) + 'Bсеки човек има право на образование. Oбразованието!' + +Others methods and usages are available - see the full documentation +at . +:copyright: (c) Ahmed TAHRI +:license: MIT, see LICENSE for more details. +""" + +from __future__ import annotations + +import logging + +from .api import from_bytes, from_fp, from_path, is_binary +from .legacy import detect +from .models import CharsetMatch, CharsetMatches +from .utils import set_logging_handler +from .version import VERSION, __version__ + +__all__ = ( + "from_fp", + "from_path", + "from_bytes", + "is_binary", + "detect", + "CharsetMatch", + "CharsetMatches", + "__version__", + "VERSION", + "set_logging_handler", +) + +# Attach a NullHandler to the top level logger by default +# https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library + +logging.getLogger("opentelemetry.agent._vendor.charset_normalizer").addHandler(logging.NullHandler()) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py new file mode 100644 index 00000000000..40366a5807c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py @@ -0,0 +1,934 @@ +from __future__ import annotations + +import logging +from functools import lru_cache +from os import PathLike +from typing import BinaryIO + +from .cd import ( + coherence_ratio, + encoding_languages, + mb_encoding_languages, + merge_coherence_ratios, +) +from .constant import ( + IANA_SUPPORTED, + IANA_SUPPORTED_SIMILAR, + TOO_BIG_SEQUENCE, + TOO_SMALL_SEQUENCE, + TRACE, +) +from .md import mess_ratio +from .models import CharsetMatch, CharsetMatches +from .utils import ( + any_specified_encoding, + cut_sequence_chunks, + iana_name, + identify_sig_or_bom, + is_multi_byte_encoding, + should_strip_sig_or_bom, +) + +logger = logging.getLogger("opentelemetry.agent._vendor.charset_normalizer") +explain_handler = logging.StreamHandler() +explain_handler.setFormatter( + logging.Formatter("%(asctime)s | %(levelname)s | %(message)s") +) + +# Pre-compute a reordered encoding list: multibyte first, then single-byte. +# This allows the mb_definitive_match optimization to fire earlier, skipping +# all single-byte encodings for genuine CJK content. Multibyte codecs +# hard-fail (UnicodeDecodeError) on single-byte data almost instantly, so +# testing them first costs negligible time for non-CJK files. +# Stable sort on a boolean key: multibyte (False) first, IANA order kept +# within each group. +IANA_SUPPORTED_MB_FIRST: list[str] = sorted( + IANA_SUPPORTED, key=lambda encoding: not is_multi_byte_encoding(encoding) +) + + +def from_bytes( + sequences: bytes | bytearray, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.2, + cp_isolation: list[str] | None = None, + cp_exclusion: list[str] | None = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> CharsetMatches: + """ + Given a raw bytes sequence, return the best possibles charset usable to render str objects. + If there is no results, it is a strong indicator that the source is binary/not text. + By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence. + And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. + + The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page + but never take it for granted. Can improve the performance. + + You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that + purpose. + + This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. + By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' + toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. + Custom logging format and handler can be set manually. + """ + + if not isinstance(sequences, (bytearray, bytes)): + raise TypeError( + "Expected object of type bytes or bytearray, got: {}".format( + type(sequences) + ) + ) + + if explain: + previous_logger_level: int = logger.level + logger.addHandler(explain_handler) + logger.setLevel(TRACE) + + length: int = len(sequences) + + if length == 0: + logger.debug("Encoding detection on empty bytes, assuming utf_8 intention.") + if explain: # Defensive: ensure exit path clean handler + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")]) + + if cp_isolation is not None: + logger.log( + TRACE, + "cp_isolation is set. use this flag for debugging purpose. " + "limited list of encoding allowed : %s.", + ", ".join(cp_isolation), + ) + cp_isolation = [iana_name(cp, False) for cp in cp_isolation] + else: + cp_isolation = [] + + if cp_exclusion is not None: + logger.log( + TRACE, + "cp_exclusion is set. use this flag for debugging purpose. " + "limited list of encoding excluded : %s.", + ", ".join(cp_exclusion), + ) + cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion] + else: + cp_exclusion = [] + + if length <= (chunk_size * steps): + logger.log( + TRACE, + "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.", + steps, + chunk_size, + length, + ) + steps = 1 + chunk_size = length + + if steps > 1 and length / steps < chunk_size: + chunk_size = int(length / steps) + + is_too_small_sequence: bool = len(sequences) < TOO_SMALL_SEQUENCE + is_too_large_sequence: bool = len(sequences) >= TOO_BIG_SEQUENCE + + if is_too_small_sequence: + logger.log( + TRACE, + "Trying to detect encoding from a tiny portion of (%i) byte(s).", + length, + ) + elif is_too_large_sequence: + logger.log( + TRACE, + "Using lazy str decoding because the payload is quite large, (%i) byte(s).", + length, + ) + + prioritized_encodings: list[str] = [] + + specified_encoding: str | None = ( + any_specified_encoding(sequences) if preemptive_behaviour else None + ) + + if specified_encoding is not None: + prioritized_encodings.append(specified_encoding) + logger.log( + TRACE, + "Detected declarative mark in sequence. Priority +1 given for %s.", + specified_encoding, + ) + + tested: set[str] = set() + tested_but_hard_failure: list[str] = [] + tested_but_soft_failure: list[str] = [] + soft_failure_skip: set[str] = set() + + # Avoid unoptimized RSS usage. + # this cache is mostly interesting for + # local usage. Garbage collected at the + # end. Like it should. + cached_mess_ratio = lru_cache(maxsize=None)(mess_ratio) + cached_coherence_ratio = lru_cache(maxsize=None)(coherence_ratio) + + # When a definitive result (chaos=0.0 and good coherence) is found after testing + # the prioritized encodings (ascii, utf_8), we can significantly reduce the remaining + # work. Encodings that target completely different language families (e.g., Cyrillic + # when the definitive match is Latin) are skipped entirely. + # Additionally, for same-family encodings that pass chaos probing, we reuse the + # definitive match's coherence ratios instead of recomputing them — a major savings + # since coherence_ratio accounts for ~30% of total time on slow Latin files. + definitive_match_found: bool = False + definitive_target_languages: set[str] = set() + # After the definitive match fires, we cap the number of additional same-family + # single-byte encodings that pass chaos probing. Once we've accumulated enough + # good candidates (N), further same-family SB encodings are unlikely to produce + # a better best() result and just waste mess_ratio + coherence_ratio time. + # The first encoding to trigger the definitive match is NOT counted (it's already in). + post_definitive_sb_success_count: int = 0 + POST_DEFINITIVE_SB_CAP: int = 7 + + # When a non-UTF multibyte encoding passes chaos probing with significant multibyte + # content (decoded length < 98% of raw length), skip all remaining single-byte encodings. + # Rationale: multi-byte decoders (CJK) have strict byte-sequence validation — if they + # decode without error AND pass chaos probing with substantial multibyte content, the + # data is genuinely multibyte encoded. Single-byte encodings will always decode (every + # byte maps to something) but waste time on mess_ratio before failing. + # The 98% threshold prevents false triggers on files that happen to have a few valid + # multibyte pairs (e.g., cp424/_ude_1.txt where big5 decodes with 99% ratio). + mb_definitive_match_found: bool = False + + fallback_ascii: CharsetMatch | None = None + fallback_u8: CharsetMatch | None = None + fallback_specified: CharsetMatch | None = None + + results: CharsetMatches = CharsetMatches() + + early_stop_results: CharsetMatches = CharsetMatches() + + sig_encoding, sig_payload = identify_sig_or_bom(sequences) + + if sig_encoding is not None: + prioritized_encodings.insert(0, sig_encoding) + logger.log( + TRACE, + "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.", + len(sig_payload), + sig_encoding, + ) + + prioritized_encodings.append("ascii") + + if "utf_8" not in prioritized_encodings: + prioritized_encodings.append("utf_8") + + for encoding_iana in prioritized_encodings + IANA_SUPPORTED_MB_FIRST: + if cp_isolation and encoding_iana not in cp_isolation: + continue + + if cp_exclusion and encoding_iana in cp_exclusion: + continue + + if encoding_iana in tested: + continue + + tested.add(encoding_iana) + + decoded_payload: str | None = None + bom_or_sig_available: bool = sig_encoding == encoding_iana + strip_sig_or_bom: bool = bom_or_sig_available and should_strip_sig_or_bom( + encoding_iana + ) + + if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", + encoding_iana, + ) + continue + if encoding_iana in {"utf_7"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because detection is unreliable without BOM/SIG.", + encoding_iana, + ) + continue + + # Skip encodings similar to ones that already soft-failed (high mess ratio). + # Checked BEFORE the expensive decode attempt. + if encoding_iana in soft_failure_skip: + logger.log( + TRACE, + "%s is deemed too similar to a code page that was already considered unsuited. Continuing!", + encoding_iana, + ) + continue + + try: + is_multi_byte_decoder: bool = is_multi_byte_encoding(encoding_iana) + except (ModuleNotFoundError, ImportError): # Defensive: + logger.log( + TRACE, + "Encoding %s does not provide an IncrementalDecoder", + encoding_iana, + ) + continue + + # When we've already found a definitive match (chaos=0.0 with good coherence) + # after testing the prioritized encodings, skip encodings that target + # completely different language families. This avoids running expensive + # mess_ratio + coherence_ratio on clearly unrelated candidates (e.g., Cyrillic + # when the definitive match is Latin-based). + if definitive_match_found: + if not is_multi_byte_decoder: + enc_languages = set(encoding_languages(encoding_iana)) + else: + enc_languages = set(mb_encoding_languages(encoding_iana)) + if not enc_languages.intersection(definitive_target_languages): + logger.log( + TRACE, + "Skipping %s: definitive match already found, this encoding targets different languages (%s vs %s).", + encoding_iana, + enc_languages, + definitive_target_languages, + ) + continue + + # After the definitive match, cap the number of additional same-family + # single-byte encodings that pass chaos probing. This avoids testing the + # tail of rare, low-value same-family encodings (mac_iceland, cp860, etc.) + # that almost never change best() but each cost ~1-2ms of mess_ratio + coherence. + if ( + definitive_match_found + and not is_multi_byte_decoder + and post_definitive_sb_success_count >= POST_DEFINITIVE_SB_CAP + ): + logger.log( + TRACE, + "Skipping %s: already accumulated %d same-family results after definitive match (cap=%d).", + encoding_iana, + post_definitive_sb_success_count, + POST_DEFINITIVE_SB_CAP, + ) + continue + + # When a multibyte encoding with significant multibyte content has already + # passed chaos probing, skip all single-byte encodings. They will either fail + # chaos probing (wasting mess_ratio time) or produce inferior results. + if mb_definitive_match_found and not is_multi_byte_decoder: + logger.log( + TRACE, + "Skipping single-byte %s: multi-byte definitive match already found.", + encoding_iana, + ) + continue + + # Single-byte candidates of regular size defer the expensive whole + # payload decode until after chunk probing: single-byte codecs are + # stateless (1 byte == 1 char) so decoding chunk slices is provably + # identical to slicing the decoded payload, and candidates rejected + # by chaos probing (the common case) never pay the full decode nor + # the payload hash. + deferred_decoding: bool = ( + not is_multi_byte_decoder and not is_too_large_sequence + ) + + try: + if is_too_large_sequence and not is_multi_byte_decoder: + str( + ( + sequences[: int(50e4)] + if not strip_sig_or_bom + else sequences[len(sig_payload) : int(50e4)] + ), + encoding=encoding_iana, + ) + elif not deferred_decoding: + # UTF-7 BOM is encoded in modified Base64 whose byte boundary + # can overlap with the next character. Stripping raw SIG bytes + # before decoding may leave stray bytes that decode as garbage. + # Decode the full sequence and remove the leading BOM char instead. + # see https://github.com/jawah/charset_normalizer/issues/718 + # and https://github.com/jawah/charset_normalizer/issues/716 + if encoding_iana == "utf_7" and bom_or_sig_available: + decoded_payload = str( + sequences, + encoding=encoding_iana, + ) + if decoded_payload and decoded_payload[0] == "\ufeff": + decoded_payload = decoded_payload[1:] + else: + decoded_payload = str( + ( + sequences + if not strip_sig_or_bom + else sequences[len(sig_payload) :] + ), + encoding=encoding_iana, + ) + except (UnicodeDecodeError, LookupError) as e: + if not isinstance(e, LookupError): + logger.log( + TRACE, + "Code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + r_ = range( + 0 if not bom_or_sig_available else len(sig_payload), + length, + int(length / steps), + ) + + multi_byte_bonus: bool = ( + is_multi_byte_decoder + and decoded_payload is not None + and len(decoded_payload) < length + ) + + if multi_byte_bonus: + logger.log( + TRACE, + "Code page %s is a multi byte encoding table and it appear that at least one character " + "was encoded using n-bytes.", + encoding_iana, + ) + + max_chunk_gave_up: int = int(len(r_) / 4) + + max_chunk_gave_up = max(max_chunk_gave_up, 2) + early_stop_count: int = 0 + lazy_str_hard_failure = False + + md_chunks: list[str] = [] + md_ratios = [] + + try: + for chunk in cut_sequence_chunks( + sequences, + encoding_iana, + r_, + chunk_size, + bom_or_sig_available, + strip_sig_or_bom, + sig_payload, + is_multi_byte_decoder, + decoded_payload, + deferred_decoding, + ): + md_chunks.append(chunk) + + md_ratios.append( + cached_mess_ratio( + chunk, + threshold, + explain and 1 <= len(cp_isolation) <= 2, + ) + ) + + if md_ratios[-1] >= threshold: + early_stop_count += 1 + + if (early_stop_count >= max_chunk_gave_up) or ( + bom_or_sig_available and not strip_sig_or_bom + ): + break + except ( + UnicodeDecodeError, + LookupError, + ) as e: # Lazy str loading may have missed something there + if deferred_decoding: + # Deferred single-byte validation failed on a chunk (or the + # codec is unavailable on this interpreter build): identical + # outcome and bookkeeping to the eager full-decode failure. + logger.log( + TRACE, + "Code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + logger.log( + TRACE, + "LazyStr Loading: After MD chunk decode, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + early_stop_count = max_chunk_gave_up + lazy_str_hard_failure = True + + mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0 + + # We might want to check the sequence again with the whole content, + # but only if initial MD tests passed. + if ( + not lazy_str_hard_failure + and is_too_large_sequence + and not is_multi_byte_decoder + and mean_mess_ratio < threshold + and early_stop_count < max_chunk_gave_up + ): + try: + sequences[int(50e3) :].decode(encoding_iana, errors="strict") + except UnicodeDecodeError as e: + logger.log( + TRACE, + "LazyStr Loading: After final lookup, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up: + tested_but_soft_failure.append(encoding_iana) + if encoding_iana in IANA_SUPPORTED_SIMILAR: + soft_failure_skip.update(IANA_SUPPORTED_SIMILAR[encoding_iana]) + logger.log( + TRACE, + "%s was excluded because of initial chaos probing. Gave up %i time(s). " + "Computed mean chaos is %f %%.", + encoding_iana, + early_stop_count, + round(mean_mess_ratio * 100, ndigits=3), + ) + # Preparing those fallbacks in case we got nothing. + if ( + enable_fallback + and encoding_iana + in ["ascii", "utf_8", specified_encoding, "utf_16", "utf_32"] + and not lazy_str_hard_failure + ): + # Always fully decode payload before. + # We've missed a UnicodeDecodeError proof + # while issuing release 3.4.8 + # see https://github.com/jawah/charset_normalizer/issues/771 + if decoded_payload is None: + try: + decoded_payload = str( + ( + sequences + if not strip_sig_or_bom + else sequences[len(sig_payload) :] + ), + encoding=encoding_iana, + ) + except (UnicodeDecodeError, LookupError): + logger.log( + TRACE, + "%s does not decode the whole payload: fallback entry withheld.", + encoding_iana, + ) + continue + if is_too_large_sequence: + # Don't retain huge payload in RAM. + decoded_payload = None + + fallback_entry = CharsetMatch( + sequences, + encoding_iana, + threshold, + bom_or_sig_available, + [], + decoded_payload, + preemptive_declaration=specified_encoding, + ) + if encoding_iana == specified_encoding: + fallback_specified = fallback_entry + elif encoding_iana == "ascii": + fallback_ascii = fallback_entry + else: + fallback_u8 = fallback_entry + continue + + if deferred_decoding: + # The candidate passed chaos probing: perform the whole payload + # decode (validation + payload reuse) that was deferred earlier. + try: + decoded_payload = str( + ( + sequences + if not strip_sig_or_bom + else sequences[len(sig_payload) :] + ), + encoding=encoding_iana, + ) + except (UnicodeDecodeError, LookupError) as e: + logger.log( + TRACE, + "Code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + logger.log( + TRACE, + "%s passed initial chaos probing. Mean measured chaos is %f %%", + encoding_iana, + round(mean_mess_ratio * 100, ndigits=3), + ) + + if not is_multi_byte_decoder: + target_languages: list[str] = encoding_languages(encoding_iana) + else: + target_languages = mb_encoding_languages(encoding_iana) + + if target_languages: + logger.log( + TRACE, + "%s should target any language(s) of %s", + encoding_iana, + target_languages, + ) + + cd_ratios = [] + + # Run coherence detection on all chunks. We previously tried limiting to + # 1-2 chunks for post-definitive encodings to save time, but this caused + # coverage regressions by producing unrepresentative coherence scores. + # The SB cap and language-family skip optimizations provide sufficient + # speedup without sacrificing coherence accuracy. + if encoding_iana != "ascii": + # We shall skip the CD when its about ASCII + # Most of the time its not relevant to run "language-detection" on it. + lg_inclusion: str | None = ( + ",".join(target_languages) if target_languages else None + ) + + for chunk in md_chunks: + chunk_languages = cached_coherence_ratio( + chunk, + language_threshold, + lg_inclusion, + ) + + cd_ratios.append(chunk_languages) + + cd_ratios_merged = merge_coherence_ratios(cd_ratios) + + if cd_ratios_merged: + logger.log( + TRACE, + "We detected language %s using %s", + cd_ratios_merged, + encoding_iana, + ) + + current_match = CharsetMatch( + sequences, + encoding_iana, + mean_mess_ratio, + bom_or_sig_available, + cd_ratios_merged, + ( + decoded_payload + if ( + not is_too_large_sequence + or encoding_iana in [specified_encoding, "ascii", "utf_8"] + ) + else None + ), + preemptive_declaration=specified_encoding, + ) + + results.append(current_match) + + # Count post-definitive same-family SB successes for the early termination cap. + # Only count low-mess encodings (< 2%) toward the cap. High-mess encodings are + # marginal results that shouldn't prevent better-quality candidates from being + # tested. For example, iso8859_4 (mess=0%) should not be skipped just because + # 7 high-mess Latin encodings (cp1252 at 8%, etc.) were tried first. + if ( + definitive_match_found + and not is_multi_byte_decoder + and mean_mess_ratio < 0.02 + ): + post_definitive_sb_success_count += 1 + + if ( + encoding_iana in [specified_encoding, "ascii", "utf_8"] + and mean_mess_ratio < 0.1 + ): + # If md says nothing to worry about, then... stop immediately! + if mean_mess_ratio == 0.0: + logger.debug( + "Encoding detection: %s is most likely the one.", + current_match.encoding, + ) + if explain: # Defensive: ensure exit path clean handler + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([current_match]) + + early_stop_results.append(current_match) + + if ( + len(early_stop_results) + and (specified_encoding is None or specified_encoding in tested) + and "ascii" in tested + and "utf_8" in tested + ): + probable_result = early_stop_results.best() + assert probable_result is not None + logger.debug( + "Encoding detection: %s is most likely the one.", + probable_result.encoding, + ) + if explain: # Defensive: ensure exit path clean handler + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + + return CharsetMatches([probable_result]) + + # Once we find a result with good coherence (>= 0.5) after testing the + # prioritized encodings (ascii, utf_8), activate "definitive mode": skip + # encodings that target completely different language families. This avoids + # running expensive mess_ratio + coherence_ratio on clearly unrelated + # candidates (e.g., Cyrillic encodings when the match is Latin-based). + # We require coherence >= 0.5 to avoid false positives (e.g., cp1251 decoding + # Hebrew text with 0.0 chaos but wrong language detection at coherence 0.33). + if not definitive_match_found and not is_multi_byte_decoder: + best_coherence = ( + max((v for _, v in cd_ratios_merged), default=0.0) + if cd_ratios_merged + else 0.0 + ) + if best_coherence >= 0.5 and "ascii" in tested and "utf_8" in tested: + definitive_match_found = True + definitive_target_languages.update(target_languages) + logger.log( + TRACE, + "Definitive match found: %s (chaos=%.3f, coherence=%.2f). Encodings targeting different language families will be skipped.", + encoding_iana, + mean_mess_ratio, + best_coherence, + ) + + # When a non-UTF multibyte encoding passes chaos probing with significant + # multibyte content (decoded < 98% of raw), activate mb_definitive_match. + # This skips all remaining single-byte encodings which would either soft-fail + # (running expensive mess_ratio for nothing) or produce inferior results. + if ( + not mb_definitive_match_found + and is_multi_byte_decoder + and multi_byte_bonus + and decoded_payload is not None + and len(decoded_payload) < length * 0.98 + and encoding_iana + not in { + "utf_8", + "utf_8_sig", + "utf_16", + "utf_16_be", + "utf_16_le", + "utf_32", + "utf_32_be", + "utf_32_le", + "utf_7", + } + and "ascii" in tested + and "utf_8" in tested + ): + mb_definitive_match_found = True + logger.log( + TRACE, + "Multi-byte definitive match: %s (chaos=%.3f, decoded=%d/%d=%.1f%%). Single-byte encodings will be skipped.", + encoding_iana, + mean_mess_ratio, + len(decoded_payload), + length, + len(decoded_payload) / length * 100, + ) + + if encoding_iana == sig_encoding: + logger.debug( + "Encoding detection: %s is most likely the one as we detected a BOM or SIG within " + "the beginning of the sequence.", + encoding_iana, + ) + if explain: # Defensive: ensure exit path clean handler + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([results[encoding_iana]]) + + if len(results) == 0: + if fallback_u8 or fallback_ascii or fallback_specified: + logger.log( + TRACE, + "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.", + ) + + if fallback_specified: + logger.debug( + "Encoding detection: %s will be used as a fallback match", + fallback_specified.encoding, + ) + results.append(fallback_specified) + elif ( + (fallback_u8 and fallback_ascii is None) + or ( + fallback_u8 + and fallback_ascii + and fallback_u8.fingerprint != fallback_ascii.fingerprint + ) + or (fallback_u8 is not None) + ): + logger.debug("Encoding detection: utf_8 will be used as a fallback match") + results.append(fallback_u8) + elif fallback_ascii: + logger.debug("Encoding detection: ascii will be used as a fallback match") + results.append(fallback_ascii) + + if results: + logger.debug( + "Encoding detection: Found %s as plausible (best-candidate) for content. With %i alternatives.", + results.best().encoding, # type: ignore + len(results) - 1, + ) + else: + logger.debug("Encoding detection: Unable to determine any suitable charset.") + + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + + return results + + +def from_fp( + fp: BinaryIO, + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: list[str] | None = None, + cp_exclusion: list[str] | None = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but using a file pointer that is already ready. + Will not close the file pointer. + """ + return from_bytes( + fp.read(), + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + language_threshold, + enable_fallback, + ) + + +def from_path( + path: str | bytes | PathLike, # type: ignore[type-arg] + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: list[str] | None = None, + cp_exclusion: list[str] | None = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = True, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. + Can raise IOError. + """ + with open(path, "rb") as fp: + return from_fp( + fp, + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + language_threshold, + enable_fallback, + ) + + +def is_binary( + fp_or_path_or_payload: PathLike | str | BinaryIO | bytes, # type: ignore[type-arg] + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: list[str] | None = None, + cp_exclusion: list[str] | None = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = False, +) -> bool: + """ + Detect if the given input (file, bytes, or path) points to a binary file. aka. not a string. + Based on the same main heuristic algorithms and default kwargs at the sole exception that fallbacks match + are disabled to be stricter around ASCII-compatible but unlikely to be a string. + """ + if isinstance(fp_or_path_or_payload, (str, PathLike)): + guesses = from_path( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + elif isinstance( + fp_or_path_or_payload, + ( + bytes, + bytearray, + ), + ): + guesses = from_bytes( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + else: + guesses = from_fp( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + + return not guesses diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py new file mode 100644 index 00000000000..7a9344f1e5a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py @@ -0,0 +1,467 @@ +from __future__ import annotations + +import importlib +from codecs import IncrementalDecoder +from functools import lru_cache + +from .constant import ( + FREQUENCIES, + KO_NAMES, + LANGUAGE_SUPPORTED_COUNT, + TOO_SMALL_SEQUENCE, + ZH_NAMES, + _FREQUENCIES_SET, + _FREQUENCIES_RANK, +) +from .md import _ASCII_CHAR_INFO, _char_info, is_suspiciously_successive_range +from .models import CoherenceMatches +from .utils import ( + is_multi_byte_encoding, + is_unicode_range_secondary, +) + + +def encoding_unicode_range(iana_name: str) -> list[str]: + """ + Return associated unicode ranges in a single byte code page. + """ + if is_multi_byte_encoding(iana_name): + raise OSError( # Defensive: + "Function not supported on multi-byte code page" + ) + + decoder = importlib.import_module(f"encodings.{iana_name}").IncrementalDecoder + + p: IncrementalDecoder = decoder(errors="ignore") + seen_ranges: dict[str, int] = {} + character_count: int = 0 + + for i in range(0x40, 0xFF): + chunk: str = p.decode(bytes([i])) + + if chunk: + chunk_codepoint = ord(chunk) + character_range: str | None = ( + _ASCII_CHAR_INFO[chunk_codepoint].range + if chunk_codepoint < 128 + else _char_info(chunk).range + ) + + if character_range is None: + continue + + if not is_unicode_range_secondary(character_range): + if character_range not in seen_ranges: + seen_ranges[character_range] = 0 + seen_ranges[character_range] += 1 + character_count += 1 + + return sorted( + [ + character_range + for character_range in seen_ranges + if seen_ranges[character_range] / character_count >= 0.15 + ] + ) + + +def unicode_range_languages(primary_range: str) -> list[str]: + """ + Return inferred languages used with a unicode range. + """ + languages: list[str] = [] + + for language, characters in FREQUENCIES.items(): + for character in characters: + codepoint = ord(character) + info = ( + _ASCII_CHAR_INFO[codepoint] + if codepoint < 128 + else _char_info(character) + ) + if info.range == primary_range: + languages.append(language) + break + + return languages + + +@lru_cache() +def encoding_languages(iana_name: str) -> list[str]: + """ + Single-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + try: + unicode_ranges: list[str] = encoding_unicode_range(iana_name) + except ImportError: # Defensive: encoding unavailable on this build. + return [] + + primary_range: str | None = None + + for specified_range in unicode_ranges: + if "Latin" not in specified_range: + primary_range = specified_range + break + + if primary_range is None: + return ["Latin Based"] + + return unicode_range_languages(primary_range) + + +@lru_cache() +def mb_encoding_languages(iana_name: str) -> list[str]: + """ + Multi-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + if ( + iana_name.startswith("shift_") + or iana_name.startswith("iso2022_jp") + or iana_name.startswith("euc_j") + or iana_name == "cp932" + ): + return ["Japanese"] + if iana_name.startswith("gb") or iana_name in ZH_NAMES: + return ["Chinese"] + if iana_name.startswith("iso2022_kr") or iana_name in KO_NAMES: + return ["Korean"] + + return [] + + +@lru_cache(maxsize=LANGUAGE_SUPPORTED_COUNT) +def get_target_features(language: str) -> tuple[bool, bool]: + """ + Determine main aspects from a supported language if it contains accents and if is pure Latin. + """ + target_have_accents: bool = False + target_pure_latin: bool = True + + for character in FREQUENCIES[language]: + codepoint = ord(character) + info = _ASCII_CHAR_INFO[codepoint] if codepoint < 128 else _char_info(character) + if not target_have_accents and info.accentuated: + target_have_accents = True + if target_pure_latin and not info.latin: + target_pure_latin = False + + return target_have_accents, target_pure_latin + + +def alphabet_languages( + characters: list[str], ignore_non_latin: bool = False +) -> list[str]: + """ + Return associated languages associated to given characters. + """ + languages: list[tuple[str, float]] = [] + + characters_set: frozenset[str] = frozenset(characters) + source_have_accents = False + for character in characters: + codepoint = ord(character) + info = _ASCII_CHAR_INFO[codepoint] if codepoint < 128 else _char_info(character) + if info.accentuated: + source_have_accents = True + break + + for language, language_characters in FREQUENCIES.items(): + target_have_accents, target_pure_latin = get_target_features(language) + + if ignore_non_latin and not target_pure_latin: + continue + + if not target_have_accents and source_have_accents: + continue + + character_count: int = len(language_characters) + + character_match_count: int = len(_FREQUENCIES_SET[language] & characters_set) + + ratio: float = character_match_count / character_count + + if ratio >= 0.2: + languages.append((language, ratio)) + + languages = sorted(languages, key=lambda x: x[1], reverse=True) + + return [compatible_language[0] for compatible_language in languages] + + +def characters_popularity_compare( + language: str, ordered_characters: list[str] +) -> float: + """ + Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language. + The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit). + Beware that is function is not strict on the match in order to ease the detection. (Meaning close match is 1.) + """ + if language not in FREQUENCIES: + raise ValueError(f"{language} not available") # Defensive: + + character_approved_count: int = 0 + lang_rank: dict[str, int] = _FREQUENCIES_RANK[language] + + ordered_characters_count: int = len(ordered_characters) + target_language_characters_count: int = len(FREQUENCIES[language]) + + large_alphabet: bool = target_language_characters_count > 26 + large_alphabet_threshold: float = target_language_characters_count / 3 + + expected_projection_ratio: float = ( + target_language_characters_count / ordered_characters_count + ) + + # Single pass: characters present in the language vocabulary, as + # (language rank, popularity rank) pairs. The scoring below only ever + # needs ranks, never the characters themselves. + common_lr: list[int] = [] + common_orr: list[int] = [] + for popularity_rank, character in enumerate(ordered_characters): + language_rank = lang_rank.get(character) + if language_rank is not None: + common_lr.append(language_rank) + common_orr.append(popularity_rank) + + for character_rank_in_language, character_rank in zip(common_lr, common_orr): + character_rank_projection: int = int(character_rank * expected_projection_ratio) + + if ( + not large_alphabet + and abs(character_rank_projection - character_rank_in_language) > 4 + ): + continue + + if ( + large_alphabet + and abs(character_rank_projection - character_rank_in_language) + < large_alphabet_threshold + ): + character_approved_count += 1 + continue + + if character_rank_in_language == 0: + # before_match_count is structurally 0 here (no pair can have a + # smaller language rank): the historic "before <= 4" acceptance + # always holds. (The symmetric "after_len == 0" case is + # impossible: language ranks are strictly below the language + # character count, hence after_len >= 1.) + character_approved_count += 1 + continue + + after_len: int = target_language_characters_count - character_rank_in_language + + # Count how many characters appear "before" in both orderings, and + # how many appear "at or after" in both orderings. Both counts grow + # monotonically and the approval thresholds + # (before / rank >= 0.4 or after / after_len >= 0.4) are known + # upfront, expressed below as exact integer comparisons: exit as + # soon as one is crossed. + before_match_count: int = 0 + after_match_count: int = 0 + + for lr_i, orr_i in zip(common_lr, common_orr): + if lr_i < character_rank_in_language: + if orr_i < character_rank: + before_match_count += 1 + if 5 * before_match_count >= 2 * character_rank_in_language: + character_approved_count += 1 + break + else: + if orr_i >= character_rank: + after_match_count += 1 + if 5 * after_match_count >= 2 * after_len: + character_approved_count += 1 + break + + return character_approved_count / len(ordered_characters) + + +def alpha_unicode_split(decoded_sequence: str) -> list[str]: + """ + Given a decoded text sequence, return a list of str. Unicode range / alphabet separation. + Ex. a text containing English/Latin with a bit a Hebrew will return two items in the resulting list; + One containing the latin letters and the other hebrew. + """ + layers: dict[str, list[str]] = {} + + # Fast path: track single-layer key to skip dict iteration for single-script text. + single_layer_key: str | None = None + multi_layer: bool = False + + # Cache the last character_range and its resolved layer to avoid repeated + # is_suspiciously_successive_range calls for consecutive same-range chars. + prev_character_range: str | None = None + prev_layer_target: str | None = None + + for character in decoded_sequence: + # Reuse the per-codepoint CharInfo cache: info.alpha and info.range + # are computed with the very same str.isalpha() / unicode_range() + # calls this loop historically made per character occurrence. + codepoint: int = ord(character) + if codepoint < 128: + info = _ASCII_CHAR_INFO[codepoint] + else: + info = _char_info(character) + + if not info.alpha: + continue + + character_range: str | None = info.range + + if character_range is None: + continue + + # Fast path: same range as previous character → reuse cached layer target. + if character_range == prev_character_range: + if prev_layer_target is not None: + layers[prev_layer_target].append(character) + continue + + layer_target_range: str | None = None + + if multi_layer: + for discovered_range in layers: + if not is_suspiciously_successive_range( + discovered_range, character_range + ): + layer_target_range = discovered_range + break + elif single_layer_key is not None: + if not is_suspiciously_successive_range(single_layer_key, character_range): + layer_target_range = single_layer_key + + if layer_target_range is None: + layer_target_range = character_range + + if layer_target_range not in layers: + layers[layer_target_range] = [] + if single_layer_key is None: + single_layer_key = layer_target_range + else: + multi_layer = True + + layers[layer_target_range].append(character) + + # Cache for next iteration + prev_character_range = character_range + prev_layer_target = layer_target_range + + return ["".join(chars).lower() for chars in layers.values()] + + +def merge_coherence_ratios(results: list[CoherenceMatches]) -> CoherenceMatches: + """ + This function merge results previously given by the function coherence_ratio. + The return type is the same as coherence_ratio. + """ + per_language_ratios: dict[str, list[float]] = {} + for result in results: + for sub_result in result: + language, ratio = sub_result + if language not in per_language_ratios: + per_language_ratios[language] = [ratio] + continue + per_language_ratios[language].append(ratio) + + merge = [ + ( + language, + round( + sum(per_language_ratios[language]) / len(per_language_ratios[language]), + 4, + ), + ) + for language in per_language_ratios + ] + + return sorted(merge, key=lambda x: x[1], reverse=True) + + +def filter_alt_coherence_matches(results: CoherenceMatches) -> CoherenceMatches: + """ + We shall NOT return "English—" in CoherenceMatches because it is an alternative + of "English". This function only keeps the best match and remove the em-dash in it. + """ + index_results: dict[str, list[float]] = dict() + + for result in results: + language, ratio = result + no_em_name: str = language.replace("—", "") + + if no_em_name not in index_results: + index_results[no_em_name] = [] + + index_results[no_em_name].append(ratio) + + if any(len(index_results[e]) > 1 for e in index_results): + filtered_results: CoherenceMatches = [] + + for language in index_results: + filtered_results.append((language, max(index_results[language]))) + + return filtered_results + + return results + + +def coherence_ratio( + decoded_sequence: str, threshold: float = 0.1, lg_inclusion: str | None = None +) -> CoherenceMatches: + """ + Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers. + A layer = Character extraction by alphabets/ranges. + """ + + results: list[tuple[str, float]] = [] + ignore_non_latin: bool = False + + sufficient_match_count: int = 0 + + lg_inclusion_list = lg_inclusion.split(",") if lg_inclusion is not None else [] + if "Latin Based" in lg_inclusion_list: + ignore_non_latin = True + lg_inclusion_list.remove("Latin Based") + + for layer in alpha_unicode_split(decoded_sequence): + # Native counting + stable sort reproduce Counter.most_common() + # ordering exactly (ties keep first-appearance order) without the + # interpreted Counter machinery in the compiled hot path. + char_counts: dict[str, int] = {} + for layer_character in layer: + char_counts[layer_character] = char_counts.get(layer_character, 0) + 1 + + character_count: int = len(layer) + + if character_count <= TOO_SMALL_SEQUENCE: + continue + + popular_character_ordered: list[str] = [ + item[0] + for item in sorted( + char_counts.items(), key=lambda item: item[1], reverse=True + ) + ] + + for language in lg_inclusion_list or alphabet_languages( + popular_character_ordered, ignore_non_latin + ): + ratio: float = characters_popularity_compare( + language, popular_character_ordered + ) + + if ratio < threshold: + continue + elif ratio >= 0.8: + sufficient_match_count += 1 + + results.append((language, round(ratio, 4))) + + if sufficient_match_count >= 3: + break + + return sorted( + filter_alt_coherence_matches(results), key=lambda x: x[1], reverse=True + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py new file mode 100644 index 00000000000..f038336cbf6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py @@ -0,0 +1,2497 @@ +from __future__ import annotations + +from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE +from encodings.aliases import aliases +from re import IGNORECASE +from re import compile as re_compile + +# Contain for each eligible encoding a list of/item bytes SIG/BOM +ENCODING_MARKS: dict[str, bytes | list[bytes]] = { + "utf_8": BOM_UTF8, + "utf_7": [ + b"\x2b\x2f\x76\x38", + b"\x2b\x2f\x76\x39", + b"\x2b\x2f\x76\x2b", + b"\x2b\x2f\x76\x2f", + ], + "gb18030": b"\x84\x31\x95\x33", + "utf_32": [BOM_UTF32_BE, BOM_UTF32_LE], + "utf_16": [BOM_UTF16_BE, BOM_UTF16_LE], +} + +TOO_SMALL_SEQUENCE: int = 32 +TOO_BIG_SEQUENCE: int = int(10e6) + +UTF8_MAXIMAL_ALLOCATION: int = 1_112_064 + +# Up-to-date Unicode ucd/17.0.0 +UNICODE_RANGES_COMBINED: dict[str, range] = { + "Control character": range(32), + "Basic Latin": range(32, 128), + "Latin-1 Supplement": range(128, 256), + "Latin Extended-A": range(256, 384), + "Latin Extended-B": range(384, 592), + "IPA Extensions": range(592, 688), + "Spacing Modifier Letters": range(688, 768), + "Combining Diacritical Marks": range(768, 880), + "Greek and Coptic": range(880, 1024), + "Cyrillic": range(1024, 1280), + "Cyrillic Supplement": range(1280, 1328), + "Armenian": range(1328, 1424), + "Hebrew": range(1424, 1536), + "Arabic": range(1536, 1792), + "Syriac": range(1792, 1872), + "Arabic Supplement": range(1872, 1920), + "Thaana": range(1920, 1984), + "NKo": range(1984, 2048), + "Samaritan": range(2048, 2112), + "Mandaic": range(2112, 2144), + "Syriac Supplement": range(2144, 2160), + "Arabic Extended-B": range(2160, 2208), + "Arabic Extended-A": range(2208, 2304), + "Devanagari": range(2304, 2432), + "Bengali": range(2432, 2560), + "Gurmukhi": range(2560, 2688), + "Gujarati": range(2688, 2816), + "Oriya": range(2816, 2944), + "Tamil": range(2944, 3072), + "Telugu": range(3072, 3200), + "Kannada": range(3200, 3328), + "Malayalam": range(3328, 3456), + "Sinhala": range(3456, 3584), + "Thai": range(3584, 3712), + "Lao": range(3712, 3840), + "Tibetan": range(3840, 4096), + "Myanmar": range(4096, 4256), + "Georgian": range(4256, 4352), + "Hangul Jamo": range(4352, 4608), + "Ethiopic": range(4608, 4992), + "Ethiopic Supplement": range(4992, 5024), + "Cherokee": range(5024, 5120), + "Unified Canadian Aboriginal Syllabics": range(5120, 5760), + "Ogham": range(5760, 5792), + "Runic": range(5792, 5888), + "Tagalog": range(5888, 5920), + "Hanunoo": range(5920, 5952), + "Buhid": range(5952, 5984), + "Tagbanwa": range(5984, 6016), + "Khmer": range(6016, 6144), + "Mongolian": range(6144, 6320), + "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6400), + "Limbu": range(6400, 6480), + "Tai Le": range(6480, 6528), + "New Tai Lue": range(6528, 6624), + "Khmer Symbols": range(6624, 6656), + "Buginese": range(6656, 6688), + "Tai Tham": range(6688, 6832), + "Combining Diacritical Marks Extended": range(6832, 6912), + "Balinese": range(6912, 7040), + "Sundanese": range(7040, 7104), + "Batak": range(7104, 7168), + "Lepcha": range(7168, 7248), + "Ol Chiki": range(7248, 7296), + "Cyrillic Extended-C": range(7296, 7312), + "Georgian Extended": range(7312, 7360), + "Sundanese Supplement": range(7360, 7376), + "Vedic Extensions": range(7376, 7424), + "Phonetic Extensions": range(7424, 7552), + "Phonetic Extensions Supplement": range(7552, 7616), + "Combining Diacritical Marks Supplement": range(7616, 7680), + "Latin Extended Additional": range(7680, 7936), + "Greek Extended": range(7936, 8192), + "General Punctuation": range(8192, 8304), + "Superscripts and Subscripts": range(8304, 8352), + "Currency Symbols": range(8352, 8400), + "Combining Diacritical Marks for Symbols": range(8400, 8448), + "Letterlike Symbols": range(8448, 8528), + "Number Forms": range(8528, 8592), + "Arrows": range(8592, 8704), + "Mathematical Operators": range(8704, 8960), + "Miscellaneous Technical": range(8960, 9216), + "Control Pictures": range(9216, 9280), + "Optical Character Recognition": range(9280, 9312), + "Enclosed Alphanumerics": range(9312, 9472), + "Box Drawing": range(9472, 9600), + "Block Elements": range(9600, 9632), + "Geometric Shapes": range(9632, 9728), + "Miscellaneous Symbols": range(9728, 9984), + "Dingbats": range(9984, 10176), + "Miscellaneous Mathematical Symbols-A": range(10176, 10224), + "Supplemental Arrows-A": range(10224, 10240), + "Braille Patterns": range(10240, 10496), + "Supplemental Arrows-B": range(10496, 10624), + "Miscellaneous Mathematical Symbols-B": range(10624, 10752), + "Supplemental Mathematical Operators": range(10752, 11008), + "Miscellaneous Symbols and Arrows": range(11008, 11264), + "Glagolitic": range(11264, 11360), + "Latin Extended-C": range(11360, 11392), + "Coptic": range(11392, 11520), + "Georgian Supplement": range(11520, 11568), + "Tifinagh": range(11568, 11648), + "Ethiopic Extended": range(11648, 11744), + "Cyrillic Extended-A": range(11744, 11776), + "Supplemental Punctuation": range(11776, 11904), + "CJK Radicals Supplement": range(11904, 12032), + "Kangxi Radicals": range(12032, 12256), + "Ideographic Description Characters": range(12272, 12288), + "CJK Symbols and Punctuation": range(12288, 12352), + "Hiragana": range(12352, 12448), + "Katakana": range(12448, 12544), + "Bopomofo": range(12544, 12592), + "Hangul Compatibility Jamo": range(12592, 12688), + "Kanbun": range(12688, 12704), + "Bopomofo Extended": range(12704, 12736), + "CJK Strokes": range(12736, 12784), + "Katakana Phonetic Extensions": range(12784, 12800), + "Enclosed CJK Letters and Months": range(12800, 13056), + "CJK Compatibility": range(13056, 13312), + "CJK Unified Ideographs Extension A": range(13312, 19904), + "Yijing Hexagram Symbols": range(19904, 19968), + "CJK Unified Ideographs": range(19968, 40960), + "Yi Syllables": range(40960, 42128), + "Yi Radicals": range(42128, 42192), + "Lisu": range(42192, 42240), + "Vai": range(42240, 42560), + "Cyrillic Extended-B": range(42560, 42656), + "Bamum": range(42656, 42752), + "Modifier Tone Letters": range(42752, 42784), + "Latin Extended-D": range(42784, 43008), + "Syloti Nagri": range(43008, 43056), + "Common Indic Number Forms": range(43056, 43072), + "Phags-pa": range(43072, 43136), + "Saurashtra": range(43136, 43232), + "Devanagari Extended": range(43232, 43264), + "Kayah Li": range(43264, 43312), + "Rejang": range(43312, 43360), + "Hangul Jamo Extended-A": range(43360, 43392), + "Javanese": range(43392, 43488), + "Myanmar Extended-B": range(43488, 43520), + "Cham": range(43520, 43616), + "Myanmar Extended-A": range(43616, 43648), + "Tai Viet": range(43648, 43744), + "Meetei Mayek Extensions": range(43744, 43776), + "Ethiopic Extended-A": range(43776, 43824), + "Latin Extended-E": range(43824, 43888), + "Cherokee Supplement": range(43888, 43968), + "Meetei Mayek": range(43968, 44032), + "Hangul Syllables": range(44032, 55216), + "Hangul Jamo Extended-B": range(55216, 55296), + "High Surrogates": range(55296, 56192), + "High Private Use Surrogates": range(56192, 56320), + "Low Surrogates": range(56320, 57344), + "Private Use Area": range(57344, 63744), + "CJK Compatibility Ideographs": range(63744, 64256), + "Alphabetic Presentation Forms": range(64256, 64336), + "Arabic Presentation Forms-A": range(64336, 65024), + "Variation Selectors": range(65024, 65040), + "Vertical Forms": range(65040, 65056), + "Combining Half Marks": range(65056, 65072), + "CJK Compatibility Forms": range(65072, 65104), + "Small Form Variants": range(65104, 65136), + "Arabic Presentation Forms-B": range(65136, 65280), + "Halfwidth and Fullwidth Forms": range(65280, 65520), + "Specials": range(65520, 65536), + "Linear B Syllabary": range(65536, 65664), + "Linear B Ideograms": range(65664, 65792), + "Aegean Numbers": range(65792, 65856), + "Ancient Greek Numbers": range(65856, 65936), + "Ancient Symbols": range(65936, 66000), + "Phaistos Disc": range(66000, 66048), + "Lycian": range(66176, 66208), + "Carian": range(66208, 66272), + "Coptic Epact Numbers": range(66272, 66304), + "Old Italic": range(66304, 66352), + "Gothic": range(66352, 66384), + "Old Permic": range(66384, 66432), + "Ugaritic": range(66432, 66464), + "Old Persian": range(66464, 66528), + "Deseret": range(66560, 66640), + "Shavian": range(66640, 66688), + "Osmanya": range(66688, 66736), + "Osage": range(66736, 66816), + "Elbasan": range(66816, 66864), + "Caucasian Albanian": range(66864, 66928), + "Vithkuqi": range(66928, 67008), + "Todhri": range(67008, 67072), + "Linear A": range(67072, 67456), + "Latin Extended-F": range(67456, 67520), + "Cypriot Syllabary": range(67584, 67648), + "Imperial Aramaic": range(67648, 67680), + "Palmyrene": range(67680, 67712), + "Nabataean": range(67712, 67760), + "Hatran": range(67808, 67840), + "Phoenician": range(67840, 67872), + "Lydian": range(67872, 67904), + "Sidetic": range(67904, 67936), + "Meroitic Hieroglyphs": range(67968, 68000), + "Meroitic Cursive": range(68000, 68096), + "Kharoshthi": range(68096, 68192), + "Old South Arabian": range(68192, 68224), + "Old North Arabian": range(68224, 68256), + "Manichaean": range(68288, 68352), + "Avestan": range(68352, 68416), + "Inscriptional Parthian": range(68416, 68448), + "Inscriptional Pahlavi": range(68448, 68480), + "Psalter Pahlavi": range(68480, 68528), + "Old Turkic": range(68608, 68688), + "Old Hungarian": range(68736, 68864), + "Hanifi Rohingya": range(68864, 68928), + "Garay": range(68928, 69008), + "Rumi Numeral Symbols": range(69216, 69248), + "Yezidi": range(69248, 69312), + "Arabic Extended-C": range(69312, 69376), + "Old Sogdian": range(69376, 69424), + "Sogdian": range(69424, 69488), + "Old Uyghur": range(69488, 69552), + "Chorasmian": range(69552, 69600), + "Elymaic": range(69600, 69632), + "Brahmi": range(69632, 69760), + "Kaithi": range(69760, 69840), + "Sora Sompeng": range(69840, 69888), + "Chakma": range(69888, 69968), + "Mahajani": range(69968, 70016), + "Sharada": range(70016, 70112), + "Sinhala Archaic Numbers": range(70112, 70144), + "Khojki": range(70144, 70224), + "Multani": range(70272, 70320), + "Khudawadi": range(70320, 70400), + "Grantha": range(70400, 70528), + "Tulu-Tigalari": range(70528, 70656), + "Newa": range(70656, 70784), + "Tirhuta": range(70784, 70880), + "Siddham": range(71040, 71168), + "Modi": range(71168, 71264), + "Mongolian Supplement": range(71264, 71296), + "Takri": range(71296, 71376), + "Myanmar Extended-C": range(71376, 71424), + "Ahom": range(71424, 71504), + "Dogra": range(71680, 71760), + "Warang Citi": range(71840, 71936), + "Dives Akuru": range(71936, 72032), + "Nandinagari": range(72096, 72192), + "Zanabazar Square": range(72192, 72272), + "Soyombo": range(72272, 72368), + "Unified Canadian Aboriginal Syllabics Extended-A": range(72368, 72384), + "Pau Cin Hau": range(72384, 72448), + "Devanagari Extended-A": range(72448, 72544), + "Sharada Supplement": range(72544, 72576), + "Sunuwar": range(72640, 72704), + "Bhaiksuki": range(72704, 72816), + "Marchen": range(72816, 72896), + "Masaram Gondi": range(72960, 73056), + "Gunjala Gondi": range(73056, 73136), + "Tolong Siki": range(73136, 73200), + "Makasar": range(73440, 73472), + "Kawi": range(73472, 73568), + "Lisu Supplement": range(73648, 73664), + "Tamil Supplement": range(73664, 73728), + "Cuneiform": range(73728, 74752), + "Cuneiform Numbers and Punctuation": range(74752, 74880), + "Early Dynastic Cuneiform": range(74880, 75088), + "Cypro-Minoan": range(77712, 77824), + "Egyptian Hieroglyphs": range(77824, 78896), + "Egyptian Hieroglyph Format Controls": range(78896, 78944), + "Egyptian Hieroglyphs Extended-A": range(78944, 82944), + "Anatolian Hieroglyphs": range(82944, 83584), + "Gurung Khema": range(90368, 90432), + "Bamum Supplement": range(92160, 92736), + "Mro": range(92736, 92784), + "Tangsa": range(92784, 92880), + "Bassa Vah": range(92880, 92928), + "Pahawh Hmong": range(92928, 93072), + "Kirat Rai": range(93504, 93568), + "Medefaidrin": range(93760, 93856), + "Beria Erfe": range(93856, 93920), + "Miao": range(93952, 94112), + "Ideographic Symbols and Punctuation": range(94176, 94208), + "Tangut": range(94208, 100352), + "Tangut Components": range(100352, 101120), + "Khitan Small Script": range(101120, 101632), + "Tangut Supplement": range(101632, 101760), + "Tangut Components Supplement": range(101760, 101888), + "Kana Extended-B": range(110576, 110592), + "Kana Supplement": range(110592, 110848), + "Kana Extended-A": range(110848, 110896), + "Small Kana Extension": range(110896, 110960), + "Nushu": range(110960, 111360), + "Duployan": range(113664, 113824), + "Shorthand Format Controls": range(113824, 113840), + "Symbols for Legacy Computing Supplement": range(117760, 118464), + "Miscellaneous Symbols Supplement": range(118464, 118528), + "Znamenny Musical Notation": range(118528, 118736), + "Byzantine Musical Symbols": range(118784, 119040), + "Musical Symbols": range(119040, 119296), + "Ancient Greek Musical Notation": range(119296, 119376), + "Kaktovik Numerals": range(119488, 119520), + "Mayan Numerals": range(119520, 119552), + "Tai Xuan Jing Symbols": range(119552, 119648), + "Counting Rod Numerals": range(119648, 119680), + "Mathematical Alphanumeric Symbols": range(119808, 120832), + "Sutton SignWriting": range(120832, 121520), + "Latin Extended-G": range(122624, 122880), + "Glagolitic Supplement": range(122880, 122928), + "Cyrillic Extended-D": range(122928, 123024), + "Nyiakeng Puachue Hmong": range(123136, 123216), + "Toto": range(123536, 123584), + "Wancho": range(123584, 123648), + "Nag Mundari": range(124112, 124160), + "Ol Onal": range(124368, 124416), + "Tai Yo": range(124608, 124672), + "Ethiopic Extended-B": range(124896, 124928), + "Mende Kikakui": range(124928, 125152), + "Adlam": range(125184, 125280), + "Indic Siyaq Numbers": range(126064, 126144), + "Ottoman Siyaq Numbers": range(126208, 126288), + "Arabic Mathematical Alphabetic Symbols": range(126464, 126720), + "Mahjong Tiles": range(126976, 127024), + "Domino Tiles": range(127024, 127136), + "Playing Cards": range(127136, 127232), + "Enclosed Alphanumeric Supplement": range(127232, 127488), + "Enclosed Ideographic Supplement": range(127488, 127744), + "Miscellaneous Symbols and Pictographs": range(127744, 128512), + "Emoticons": range(128512, 128592), + "Ornamental Dingbats": range(128592, 128640), + "Transport and Map Symbols": range(128640, 128768), + "Alchemical Symbols": range(128768, 128896), + "Geometric Shapes Extended": range(128896, 129024), + "Supplemental Arrows-C": range(129024, 129280), + "Supplemental Symbols and Pictographs": range(129280, 129536), + "Chess Symbols": range(129536, 129648), + "Symbols and Pictographs Extended-A": range(129648, 129792), + "Symbols for Legacy Computing": range(129792, 130048), + "CJK Unified Ideographs Extension B": range(131072, 173792), + "CJK Unified Ideographs Extension C": range(173824, 177984), + "CJK Unified Ideographs Extension D": range(177984, 178208), + "CJK Unified Ideographs Extension E": range(178208, 183984), + "CJK Unified Ideographs Extension F": range(183984, 191472), + "CJK Unified Ideographs Extension I": range(191472, 192096), + "CJK Compatibility Ideographs Supplement": range(194560, 195104), + "CJK Unified Ideographs Extension G": range(196608, 201552), + "CJK Unified Ideographs Extension H": range(201552, 205744), + "CJK Unified Ideographs Extension J": range(205744, 210048), + "Tags": range(917504, 917632), + "Variation Selectors Supplement": range(917760, 918000), + "Supplementary Private Use Area-A": range(983040, 1048576), + "Supplementary Private Use Area-B": range(1048576, 1114112), +} + +# Canonical family for every Unicode range above. Keep this exhaustive and +# explicit: official block names are labels, not a grammar we should parse. +_RANGE_FAMILIES: dict[str, str] = { + "Control character": "Control character", + "Basic Latin": "Latin", + "Latin-1 Supplement": "Latin", + "Latin Extended-A": "Latin", + "Latin Extended-B": "Latin", + "IPA Extensions": "IPA", + "Spacing Modifier Letters": "Spacing Modifier Letters", + "Combining Diacritical Marks": "Combining", + "Greek and Coptic": "Greek", + "Cyrillic": "Cyrillic", + "Cyrillic Supplement": "Cyrillic", + "Armenian": "Armenian", + "Hebrew": "Hebrew", + "Arabic": "Arabic", + "Syriac": "Syriac", + "Arabic Supplement": "Arabic", + "Thaana": "Thaana", + "NKo": "NKo", + "Samaritan": "Samaritan", + "Mandaic": "Mandaic", + "Syriac Supplement": "Syriac", + "Arabic Extended-B": "Arabic", + "Arabic Extended-A": "Arabic", + "Devanagari": "Devanagari", + "Bengali": "Bengali", + "Gurmukhi": "Gurmukhi", + "Gujarati": "Gujarati", + "Oriya": "Oriya", + "Tamil": "Tamil", + "Telugu": "Telugu", + "Kannada": "Kannada", + "Malayalam": "Malayalam", + "Sinhala": "Sinhala", + "Thai": "Thai", + "Lao": "Lao", + "Tibetan": "Tibetan", + "Myanmar": "Myanmar", + "Georgian": "Georgian", + "Hangul Jamo": "Hangul", + "Ethiopic": "Ethiopic", + "Ethiopic Supplement": "Ethiopic", + "Cherokee": "Cherokee", + "Unified Canadian Aboriginal Syllabics": "Unified Canadian Aboriginal Syllabics", + "Ogham": "Ogham", + "Runic": "Runic", + "Tagalog": "Tagalog", + "Hanunoo": "Hanunoo", + "Buhid": "Buhid", + "Tagbanwa": "Tagbanwa", + "Khmer": "Khmer", + "Mongolian": "Mongolian", + "Unified Canadian Aboriginal Syllabics Extended": "Unified Canadian Aboriginal Syllabics", + "Limbu": "Limbu", + "Tai Le": "Tai Le", + "New Tai Lue": "New Tai Lue", + "Khmer Symbols": "Khmer", + "Buginese": "Buginese", + "Tai Tham": "Tai Tham", + "Combining Diacritical Marks Extended": "Combining", + "Balinese": "Balinese", + "Sundanese": "Sundanese", + "Batak": "Batak", + "Lepcha": "Lepcha", + "Ol Chiki": "Ol Chiki", + "Cyrillic Extended-C": "Cyrillic", + "Georgian Extended": "Georgian", + "Sundanese Supplement": "Sundanese", + "Vedic Extensions": "Vedic", + "Phonetic Extensions": "Phonetic", + "Phonetic Extensions Supplement": "Phonetic", + "Combining Diacritical Marks Supplement": "Combining", + "Latin Extended Additional": "Latin", + "Greek Extended": "Greek", + "General Punctuation": "Punctuation", + "Superscripts and Subscripts": "Superscripts and Subscripts", + "Currency Symbols": "Currency Symbols", + "Combining Diacritical Marks for Symbols": "Combining", + "Letterlike Symbols": "Letterlike Symbols", + "Number Forms": "Number Forms", + "Arrows": "Arrows", + "Mathematical Operators": "Mathematical", + "Miscellaneous Technical": "Miscellaneous Technical", + "Control Pictures": "Control Pictures", + "Optical Character Recognition": "Optical Character Recognition", + "Enclosed Alphanumerics": "Enclosed Alphanumerics", + "Box Drawing": "Box Drawing", + "Block Elements": "Block Elements", + "Geometric Shapes": "Geometric Shapes", + "Miscellaneous Symbols": "Miscellaneous Symbols", + "Dingbats": "Dingbats", + "Miscellaneous Mathematical Symbols-A": "Mathematical", + "Supplemental Arrows-A": "Arrows", + "Braille Patterns": "Braille", + "Supplemental Arrows-B": "Arrows", + "Miscellaneous Mathematical Symbols-B": "Mathematical", + "Supplemental Mathematical Operators": "Mathematical", + "Miscellaneous Symbols and Arrows": "Miscellaneous Symbols and Arrows", + "Glagolitic": "Glagolitic", + "Latin Extended-C": "Latin", + "Coptic": "Coptic", + "Georgian Supplement": "Georgian", + "Tifinagh": "Tifinagh", + "Ethiopic Extended": "Ethiopic", + "Cyrillic Extended-A": "Cyrillic", + "Supplemental Punctuation": "Punctuation", + "CJK Radicals Supplement": "CJK", + "Kangxi Radicals": "CJK", + "Ideographic Description Characters": "CJK", + "CJK Symbols and Punctuation": "CJK", + "Hiragana": "Hiragana", + "Katakana": "Katakana", + "Bopomofo": "Bopomofo", + "Hangul Compatibility Jamo": "Hangul", + "Kanbun": "Kanbun", + "Bopomofo Extended": "Bopomofo", + "CJK Strokes": "CJK", + "Katakana Phonetic Extensions": "Katakana", + "Enclosed CJK Letters and Months": "CJK", + "CJK Compatibility": "CJK", + "CJK Unified Ideographs Extension A": "CJK", + "Yijing Hexagram Symbols": "Yijing Hexagram Symbols", + "CJK Unified Ideographs": "CJK", + "Yi Syllables": "Yi", + "Yi Radicals": "Yi", + "Lisu": "Lisu", + "Vai": "Vai", + "Cyrillic Extended-B": "Cyrillic", + "Bamum": "Bamum", + "Modifier Tone Letters": "Phonetic", + "Latin Extended-D": "Latin", + "Syloti Nagri": "Syloti Nagri", + "Common Indic Number Forms": "Common Indic Number Forms", + "Phags-pa": "Phags-pa", + "Saurashtra": "Saurashtra", + "Devanagari Extended": "Devanagari", + "Kayah Li": "Kayah Li", + "Rejang": "Rejang", + "Hangul Jamo Extended-A": "Hangul", + "Javanese": "Javanese", + "Myanmar Extended-B": "Myanmar", + "Cham": "Cham", + "Myanmar Extended-A": "Myanmar", + "Tai Viet": "Tai Viet", + "Meetei Mayek Extensions": "Meetei Mayek", + "Ethiopic Extended-A": "Ethiopic", + "Latin Extended-E": "Latin", + "Cherokee Supplement": "Cherokee", + "Meetei Mayek": "Meetei Mayek", + "Hangul Syllables": "Hangul", + "Hangul Jamo Extended-B": "Hangul", + "High Surrogates": "Surrogates", + "High Private Use Surrogates": "Surrogates", + "Low Surrogates": "Surrogates", + "Private Use Area": "Private Use", + "CJK Compatibility Ideographs": "CJK", + "Alphabetic Presentation Forms": "Alphabetic Presentation Forms", + "Arabic Presentation Forms-A": "Arabic", + "Variation Selectors": "Variation Selectors", + "Vertical Forms": "CJK", + "Combining Half Marks": "Combining", + "CJK Compatibility Forms": "CJK", + "Small Form Variants": "CJK", + "Arabic Presentation Forms-B": "Arabic", + "Halfwidth and Fullwidth Forms": "Halfwidth and Fullwidth Forms", + "Specials": "Specials", + "Linear B Syllabary": "Linear B", + "Linear B Ideograms": "Linear B", + "Aegean Numbers": "Aegean Numbers", + "Ancient Greek Numbers": "Greek", + "Ancient Symbols": "Ancient Symbols", + "Phaistos Disc": "Phaistos Disc", + "Lycian": "Lycian", + "Carian": "Carian", + "Coptic Epact Numbers": "Coptic", + "Old Italic": "Old Italic", + "Gothic": "Gothic", + "Old Permic": "Old Permic", + "Ugaritic": "Ugaritic", + "Old Persian": "Old Persian", + "Deseret": "Deseret", + "Shavian": "Shavian", + "Osmanya": "Osmanya", + "Osage": "Osage", + "Elbasan": "Elbasan", + "Caucasian Albanian": "Caucasian Albanian", + "Vithkuqi": "Vithkuqi", + "Todhri": "Todhri", + "Linear A": "Linear A", + "Latin Extended-F": "Latin", + "Cypriot Syllabary": "Cypriot", + "Imperial Aramaic": "Imperial Aramaic", + "Palmyrene": "Palmyrene", + "Nabataean": "Nabataean", + "Hatran": "Hatran", + "Phoenician": "Phoenician", + "Lydian": "Lydian", + "Sidetic": "Sidetic", + "Meroitic Hieroglyphs": "Meroitic", + "Meroitic Cursive": "Meroitic", + "Kharoshthi": "Kharoshthi", + "Old South Arabian": "Old South Arabian", + "Old North Arabian": "Old North Arabian", + "Manichaean": "Manichaean", + "Avestan": "Avestan", + "Inscriptional Parthian": "Parthian", + "Inscriptional Pahlavi": "Pahlavi", + "Psalter Pahlavi": "Pahlavi", + "Old Turkic": "Old Turkic", + "Old Hungarian": "Old Hungarian", + "Hanifi Rohingya": "Hanifi Rohingya", + "Garay": "Garay", + "Rumi Numeral Symbols": "Arabic", + "Yezidi": "Yezidi", + "Arabic Extended-C": "Arabic", + "Old Sogdian": "Sogdian", + "Sogdian": "Sogdian", + "Old Uyghur": "Old Uyghur", + "Chorasmian": "Chorasmian", + "Elymaic": "Elymaic", + "Brahmi": "Brahmi", + "Kaithi": "Kaithi", + "Sora Sompeng": "Sora Sompeng", + "Chakma": "Chakma", + "Mahajani": "Mahajani", + "Sharada": "Sharada", + "Sinhala Archaic Numbers": "Sinhala", + "Khojki": "Khojki", + "Multani": "Multani", + "Khudawadi": "Khudawadi", + "Grantha": "Grantha", + "Tulu-Tigalari": "Tulu-Tigalari", + "Newa": "Newa", + "Tirhuta": "Tirhuta", + "Siddham": "Siddham", + "Modi": "Modi", + "Mongolian Supplement": "Mongolian", + "Takri": "Takri", + "Myanmar Extended-C": "Myanmar", + "Ahom": "Ahom", + "Dogra": "Dogra", + "Warang Citi": "Warang Citi", + "Dives Akuru": "Dives Akuru", + "Nandinagari": "Nandinagari", + "Zanabazar Square": "Zanabazar Square", + "Soyombo": "Soyombo", + "Unified Canadian Aboriginal Syllabics Extended-A": "Unified Canadian Aboriginal Syllabics", + "Pau Cin Hau": "Pau Cin Hau", + "Devanagari Extended-A": "Devanagari", + "Sharada Supplement": "Sharada", + "Sunuwar": "Sunuwar", + "Bhaiksuki": "Bhaiksuki", + "Marchen": "Marchen", + "Masaram Gondi": "Masaram Gondi", + "Gunjala Gondi": "Gunjala Gondi", + "Tolong Siki": "Tolong Siki", + "Makasar": "Makasar", + "Kawi": "Kawi", + "Lisu Supplement": "Lisu", + "Tamil Supplement": "Tamil", + "Cuneiform": "Cuneiform", + "Cuneiform Numbers and Punctuation": "Cuneiform", + "Early Dynastic Cuneiform": "Cuneiform", + "Cypro-Minoan": "Cypro-Minoan", + "Egyptian Hieroglyphs": "Egyptian Hieroglyphs", + "Egyptian Hieroglyph Format Controls": "Egyptian Hieroglyphs", + "Egyptian Hieroglyphs Extended-A": "Egyptian Hieroglyphs", + "Anatolian Hieroglyphs": "Anatolian Hieroglyphs", + "Gurung Khema": "Gurung Khema", + "Bamum Supplement": "Bamum", + "Mro": "Mro", + "Tangsa": "Tangsa", + "Bassa Vah": "Bassa Vah", + "Pahawh Hmong": "Pahawh Hmong", + "Kirat Rai": "Kirat Rai", + "Medefaidrin": "Medefaidrin", + "Beria Erfe": "Beria Erfe", + "Miao": "Miao", + "Ideographic Symbols and Punctuation": "CJK", + "Tangut": "Tangut", + "Tangut Components": "Tangut", + "Khitan Small Script": "Khitan Small Script", + "Tangut Supplement": "Tangut", + "Tangut Components Supplement": "Tangut", + "Kana Extended-B": "Kana", + "Kana Supplement": "Kana", + "Kana Extended-A": "Kana", + "Small Kana Extension": "Kana", + "Nushu": "Nushu", + "Duployan": "Duployan", + "Shorthand Format Controls": "Shorthand Format Controls", + "Symbols for Legacy Computing Supplement": "Symbols for Legacy Computing", + "Miscellaneous Symbols Supplement": "Miscellaneous Symbols", + "Znamenny Musical Notation": "Znamenny Musical Notation", + "Byzantine Musical Symbols": "Byzantine Musical Symbols", + "Musical Symbols": "Musical Symbols", + "Ancient Greek Musical Notation": "Greek", + "Kaktovik Numerals": "Kaktovik Numerals", + "Mayan Numerals": "Mayan Numerals", + "Tai Xuan Jing Symbols": "Tai Xuan Jing Symbols", + "Counting Rod Numerals": "Counting Rod Numerals", + "Mathematical Alphanumeric Symbols": "Mathematical", + "Sutton SignWriting": "Sutton SignWriting", + "Latin Extended-G": "Latin", + "Glagolitic Supplement": "Glagolitic", + "Cyrillic Extended-D": "Cyrillic", + "Nyiakeng Puachue Hmong": "Nyiakeng Puachue Hmong", + "Toto": "Toto", + "Wancho": "Wancho", + "Nag Mundari": "Nag Mundari", + "Ol Onal": "Ol Onal", + "Tai Yo": "Tai Yo", + "Ethiopic Extended-B": "Ethiopic", + "Mende Kikakui": "Mende Kikakui", + "Adlam": "Adlam", + "Indic Siyaq Numbers": "Indic Siyaq Numbers", + "Ottoman Siyaq Numbers": "Ottoman Siyaq Numbers", + "Arabic Mathematical Alphabetic Symbols": "Arabic", + "Mahjong Tiles": "Mahjong Tiles", + "Domino Tiles": "Domino Tiles", + "Playing Cards": "Playing Cards", + "Enclosed Alphanumeric Supplement": "Enclosed Alphanumerics", + "Enclosed Ideographic Supplement": "CJK", + "Miscellaneous Symbols and Pictographs": "Pictographs", + "Emoticons": "Emoticons", + "Ornamental Dingbats": "Dingbats", + "Transport and Map Symbols": "Pictographs", + "Alchemical Symbols": "Alchemical Symbols", + "Geometric Shapes Extended": "Geometric Shapes", + "Supplemental Arrows-C": "Arrows", + "Supplemental Symbols and Pictographs": "Pictographs", + "Chess Symbols": "Chess Symbols", + "Symbols and Pictographs Extended-A": "Pictographs", + "Symbols for Legacy Computing": "Symbols for Legacy Computing", + "CJK Unified Ideographs Extension B": "CJK", + "CJK Unified Ideographs Extension C": "CJK", + "CJK Unified Ideographs Extension D": "CJK", + "CJK Unified Ideographs Extension E": "CJK", + "CJK Unified Ideographs Extension F": "CJK", + "CJK Unified Ideographs Extension I": "CJK", + "CJK Compatibility Ideographs Supplement": "CJK", + "CJK Unified Ideographs Extension G": "CJK", + "CJK Unified Ideographs Extension H": "CJK", + "CJK Unified Ideographs Extension J": "CJK", + "Tags": "Tags", + "Variation Selectors Supplement": "Variation Selectors", + "Supplementary Private Use Area-A": "Private Use", + "Supplementary Private Use Area-B": "Private Use", +} + + +class CompatibleFamillyRange: + __slots__ = ("_families",) + + def __init__(self, familly_a: str, familly_b: str) -> None: + self._families: frozenset[str] = frozenset((familly_a, familly_b)) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CompatibleFamillyRange): + return NotImplemented + + return self._families == other._families + + def __hash__(self) -> int: + return hash(self._families) + + +_COMPATIBLE_RANGE_FAMILIES: frozenset[CompatibleFamillyRange] = frozenset( + { + CompatibleFamillyRange("CJK", "Hiragana"), + CompatibleFamillyRange("CJK", "Katakana"), + CompatibleFamillyRange("CJK", "Kana"), + CompatibleFamillyRange("CJK", "Bopomofo"), + CompatibleFamillyRange("CJK", "Kanbun"), + CompatibleFamillyRange("Hiragana", "Katakana"), + CompatibleFamillyRange("Hiragana", "Kana"), + CompatibleFamillyRange("Katakana", "Kana"), + CompatibleFamillyRange("CJK", "Hangul"), + CompatibleFamillyRange("Latin", "IPA"), + CompatibleFamillyRange("Latin", "Phonetic"), + CompatibleFamillyRange("IPA", "Phonetic"), + CompatibleFamillyRange("Latin", "Spacing Modifier Letters"), + CompatibleFamillyRange("IPA", "Spacing Modifier Letters"), + CompatibleFamillyRange("Phonetic", "Spacing Modifier Letters"), + CompatibleFamillyRange("Alphabetic Presentation Forms", "Latin"), + CompatibleFamillyRange("Alphabetic Presentation Forms", "Armenian"), + CompatibleFamillyRange("Alphabetic Presentation Forms", "Hebrew"), + CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Latin"), + CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "CJK"), + CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Hiragana"), + CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Katakana"), + CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Kana"), + CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Hangul"), + } +) + +_COMPATIBLE_WITH_ANY_RANGE_FAMILIES: frozenset[str] = frozenset( + {"Combining", "Variation Selectors", "Emoticons", "Pictographs"} +) + +_BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES: frozenset[str] = frozenset( + {"CJK", "Hangul", "Hiragana", "Katakana", "Kana", "Bopomofo", "Kanbun"} +) + + +UNICODE_SECONDARY_RANGE_KEYWORD: list[str] = [ + "Supplement", + "Extended", + "Extensions", + "Modifier", + "Marks", + "Punctuation", + "Symbols", + "Forms", + "Operators", + "Miscellaneous", + "Drawing", + "Block", + "Shapes", + "Supplemental", + "Tags", +] + +RE_POSSIBLE_ENCODING_INDICATION = re_compile( + r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", + IGNORECASE, +) + +IANA_NO_ALIASES = [ + "cp720", + "cp737", + "cp856", + "cp874", + "cp875", + "cp1006", + "koi8_r", + "koi8_t", + "koi8_u", +] + +IANA_SUPPORTED: list[str] = sorted( + filter( + lambda x: not x.endswith("_codec") and x not in {"rot_13", "tactis", "mbcs"}, + list(set(aliases.values())) + IANA_NO_ALIASES, + ) +) + +IANA_SUPPORTED_COUNT: int = len(IANA_SUPPORTED) + +# pre-computed code page that are similar using the function cp_similarity. +IANA_SUPPORTED_SIMILAR: dict[str, list[str]] = { + "cp037": ["cp1026", "cp1140", "cp273", "cp500"], + "cp1026": ["cp037", "cp1140", "cp273", "cp500"], + "cp1125": ["cp866"], + "cp1140": ["cp037", "cp1026", "cp273", "cp500"], + "cp1250": ["iso8859_2"], + "cp1251": ["kz1048", "ptcp154"], + "cp1252": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1253": ["iso8859_7"], + "cp1254": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1257": ["iso8859_13"], + "cp273": ["cp037", "cp1026", "cp1140", "cp500"], + "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"], + "cp500": ["cp037", "cp1026", "cp1140", "cp273"], + "cp850": ["cp437", "cp857", "cp858", "cp865"], + "cp857": ["cp850", "cp858", "cp865"], + "cp858": ["cp437", "cp850", "cp857", "cp865"], + "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"], + "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"], + "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"], + "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"], + "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"], + "cp866": ["cp1125"], + "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"], + "iso8859_11": ["tis_620"], + "iso8859_13": ["cp1257"], + "iso8859_14": [ + "iso8859_10", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_15": [ + "cp1252", + "cp1254", + "iso8859_10", + "iso8859_14", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_16": [ + "iso8859_14", + "iso8859_15", + "iso8859_2", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"], + "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"], + "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"], + "iso8859_7": ["cp1253"], + "iso8859_9": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "latin_1", + ], + "kz1048": ["cp1251", "ptcp154"], + "latin_1": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "iso8859_9", + ], + "mac_iceland": ["mac_roman", "mac_turkish"], + "mac_roman": ["mac_iceland", "mac_turkish"], + "mac_turkish": ["mac_iceland", "mac_roman"], + "ptcp154": ["cp1251", "kz1048"], + "tis_620": ["iso8859_11"], +} + + +CHARDET_CORRESPONDENCE: dict[str, str] = { + "iso2022_kr": "ISO-2022-KR", + "iso2022_jp": "ISO-2022-JP", + "euc_kr": "EUC-KR", + "tis_620": "TIS-620", + "utf_32": "UTF-32", + "euc_jp": "EUC-JP", + "koi8_r": "KOI8-R", + "iso8859_1": "ISO-8859-1", + "iso8859_2": "ISO-8859-2", + "iso8859_5": "ISO-8859-5", + "iso8859_6": "ISO-8859-6", + "iso8859_7": "ISO-8859-7", + "iso8859_8": "ISO-8859-8", + "utf_16": "UTF-16", + "cp855": "IBM855", + "mac_cyrillic": "MacCyrillic", + "gb2312": "GB2312", + "gb18030": "GB18030", + "cp932": "CP932", + "cp866": "IBM866", + "utf_8": "utf-8", + "utf_8_sig": "UTF-8-SIG", + "shift_jis": "SHIFT_JIS", + "big5": "Big5", + "cp1250": "windows-1250", + "cp1251": "windows-1251", + "cp1252": "Windows-1252", + "cp1253": "windows-1253", + "cp1255": "windows-1255", + "cp1256": "windows-1256", + "cp1254": "Windows-1254", + "cp949": "CP949", +} + + +COMMON_SAFE_ASCII_CHARACTERS: frozenset[str] = frozenset( + { + "<", + ">", + "=", + ":", + "/", + "&", + ";", + "{", + "}", + "[", + "]", + ",", + "|", + '"', + "-", + "(", + ")", + } +) + +# Sample character sets — replace with full lists if needed +COMMON_CHINESE_CHARACTERS = "的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严龙飞" + +COMMON_JAPANESE_CHARACTERS = "日一国年大十二本中長出三時行見月分後前生五間上東四今金九入学高円子外八六下来気小七山話女北午百書先名川千水半男西電校語土木聞食車何南万毎白天母火右読友左休父雨" + +COMMON_KOREAN_CHARACTERS = "一二三四五六七八九十百千萬上下左右中人女子大小山川日月火水木金土父母天地國名年時文校學生" + +# Combine all into a frozenset +COMMON_CJK_CHARACTERS = frozenset( + "".join( + [ + COMMON_CHINESE_CHARACTERS, + COMMON_JAPANESE_CHARACTERS, + COMMON_KOREAN_CHARACTERS, + ] + ) +) + +KO_NAMES: frozenset[str] = frozenset({"johab", "cp949", "euc_kr"}) +ZH_NAMES: frozenset[str] = frozenset({"big5", "cp950", "big5hkscs", "hz"}) + +# Logging LEVEL below DEBUG +TRACE: int = 5 + + +# Language label that contain the em dash "—" +# character are to be considered alternative seq to origin +FREQUENCIES: dict[str, list[str]] = { + "English": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "u", + "m", + "f", + "p", + "g", + "w", + "y", + "b", + "v", + "k", + "x", + "j", + "z", + "q", + ], + "English—": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "m", + "u", + "f", + "p", + "g", + "w", + "b", + "y", + "v", + "k", + "j", + "x", + "z", + "q", + ], + "German": [ + "e", + "n", + "i", + "r", + "s", + "t", + "a", + "d", + "h", + "u", + "l", + "g", + "o", + "c", + "m", + "b", + "f", + "k", + "w", + "z", + "p", + "v", + "ü", + "ä", + "ö", + "j", + ], + "French": [ + "e", + "a", + "s", + "n", + "i", + "t", + "r", + "l", + "u", + "o", + "d", + "c", + "p", + "m", + "é", + "v", + "g", + "f", + "b", + "h", + "q", + "à", + "x", + "è", + "y", + "j", + ], + "Dutch": [ + "e", + "n", + "a", + "i", + "r", + "t", + "o", + "d", + "s", + "l", + "g", + "h", + "v", + "m", + "u", + "k", + "c", + "p", + "b", + "w", + "j", + "z", + "f", + "y", + "x", + "ë", + ], + "Italian": [ + "e", + "i", + "a", + "o", + "n", + "l", + "t", + "r", + "s", + "c", + "d", + "u", + "p", + "m", + "g", + "v", + "f", + "b", + "z", + "h", + "q", + "è", + "à", + "k", + "y", + "ò", + ], + "Polish": [ + "a", + "i", + "o", + "e", + "n", + "r", + "z", + "w", + "s", + "c", + "t", + "k", + "y", + "d", + "p", + "m", + "u", + "l", + "j", + "ł", + "g", + "b", + "h", + "ą", + "ę", + "ó", + ], + "Spanish": [ + "e", + "a", + "o", + "n", + "s", + "r", + "i", + "l", + "d", + "t", + "c", + "u", + "m", + "p", + "b", + "g", + "v", + "f", + "y", + "ó", + "h", + "q", + "í", + "j", + "z", + "á", + ], + "Russian": [ + "о", + "е", + "а", + "и", + "н", + "т", + "с", + "р", + "в", + "л", + "к", + "м", + "д", + "п", + "у", + "г", + "я", + "ы", + "з", + "б", + "й", + "ь", + "ч", + "х", + "ж", + "ц", + ], + # Jap-Kanji + "Japanese": [ + "日", + "一", + "人", + "年", + "大", + "十", + "二", + "本", + "中", + "長", + "出", + "三", + "時", + "行", + "見", + "月", + "分", + "後", + "前", + "生", + "五", + "間", + "上", + "東", + "四", + "今", + "金", + "九", + "入", + "学", + "高", + "円", + "子", + "外", + "八", + "六", + "下", + "来", + "気", + "小", + "七", + "山", + "話", + "女", + "北", + "午", + "百", + "書", + "先", + "名", + "川", + "千", + "水", + "半", + "男", + "西", + "電", + "校", + "語", + "土", + "木", + "聞", + "食", + "車", + "何", + "南", + "万", + "毎", + "白", + "天", + "母", + "火", + "右", + "読", + "友", + "左", + "休", + "父", + "雨", + ], + # Jap-Katakana + "Japanese—": [ + "ー", + "ン", + "ス", + "・", + "ル", + "ト", + "リ", + "イ", + "ア", + "ラ", + "ッ", + "ク", + "ド", + "シ", + "レ", + "ジ", + "タ", + "フ", + "ロ", + "カ", + "テ", + "マ", + "ィ", + "グ", + "バ", + "ム", + "プ", + "オ", + "コ", + "デ", + "ニ", + "ウ", + "メ", + "サ", + "ビ", + "ナ", + "ブ", + "ャ", + "エ", + "ュ", + "チ", + "キ", + "ズ", + "ダ", + "パ", + "ミ", + "ェ", + "ョ", + "ハ", + "セ", + "ベ", + "ガ", + "モ", + "ツ", + "ネ", + "ボ", + "ソ", + "ノ", + "ァ", + "ヴ", + "ワ", + "ポ", + "ペ", + "ピ", + "ケ", + "ゴ", + "ギ", + "ザ", + "ホ", + "ゲ", + "ォ", + "ヤ", + "ヒ", + "ユ", + "ヨ", + "ヘ", + "ゼ", + "ヌ", + "ゥ", + "ゾ", + "ヶ", + "ヂ", + "ヲ", + "ヅ", + "ヵ", + "ヱ", + "ヰ", + "ヮ", + "ヽ", + "゠", + "ヾ", + "ヷ", + "ヿ", + "ヸ", + "ヹ", + "ヺ", + ], + # Jap-Hiragana + "Japanese——": [ + "の", + "に", + "る", + "た", + "と", + "は", + "し", + "い", + "を", + "で", + "て", + "が", + "な", + "れ", + "か", + "ら", + "さ", + "っ", + "り", + "す", + "あ", + "も", + "こ", + "ま", + "う", + "く", + "よ", + "き", + "ん", + "め", + "お", + "け", + "そ", + "つ", + "だ", + "や", + "え", + "ど", + "わ", + "ち", + "み", + "せ", + "じ", + "ば", + "へ", + "び", + "ず", + "ろ", + "ほ", + "げ", + "む", + "べ", + "ひ", + "ょ", + "ゆ", + "ぶ", + "ご", + "ゃ", + "ね", + "ふ", + "ぐ", + "ぎ", + "ぼ", + "ゅ", + "づ", + "ざ", + "ぞ", + "ぬ", + "ぜ", + "ぱ", + "ぽ", + "ぷ", + "ぴ", + "ぃ", + "ぁ", + "ぇ", + "ぺ", + "ゞ", + "ぢ", + "ぉ", + "ぅ", + "ゐ", + "ゝ", + "ゑ", + "゛", + "゜", + "ゎ", + "ゔ", + "゚", + "ゟ", + "゙", + "ゕ", + "ゖ", + ], + "Portuguese": [ + "a", + "e", + "o", + "s", + "i", + "r", + "d", + "n", + "t", + "m", + "u", + "c", + "l", + "p", + "g", + "v", + "b", + "f", + "h", + "ã", + "q", + "é", + "ç", + "á", + "z", + "í", + ], + "Swedish": [ + "e", + "a", + "n", + "r", + "t", + "s", + "i", + "l", + "d", + "o", + "m", + "k", + "g", + "v", + "h", + "f", + "u", + "p", + "ä", + "c", + "b", + "ö", + "å", + "y", + "j", + "x", + ], + "Chinese": [ + "的", + "一", + "是", + "不", + "了", + "在", + "人", + "有", + "我", + "他", + "这", + "个", + "们", + "中", + "来", + "上", + "大", + "为", + "和", + "国", + "地", + "到", + "以", + "说", + "时", + "要", + "就", + "出", + "会", + "可", + "也", + "你", + "对", + "生", + "能", + "而", + "子", + "那", + "得", + "于", + "着", + "下", + "自", + "之", + "年", + "过", + "发", + "后", + "作", + "里", + "用", + "道", + "行", + "所", + "然", + "家", + "种", + "事", + "成", + "方", + "多", + "经", + "么", + "去", + "法", + "学", + "如", + "都", + "同", + "现", + "当", + "没", + "动", + "面", + "起", + "看", + "定", + "天", + "分", + "还", + "进", + "好", + "小", + "部", + "其", + "些", + "主", + "样", + "理", + "心", + "她", + "本", + "前", + "开", + "但", + "因", + "只", + "从", + "想", + "实", + ], + "Ukrainian": [ + "о", + "а", + "н", + "і", + "и", + "р", + "в", + "т", + "е", + "с", + "к", + "л", + "у", + "д", + "м", + "п", + "з", + "я", + "ь", + "б", + "г", + "й", + "ч", + "х", + "ц", + "ї", + ], + "Norwegian": [ + "e", + "r", + "n", + "t", + "a", + "s", + "i", + "o", + "l", + "d", + "g", + "k", + "m", + "v", + "f", + "p", + "u", + "b", + "h", + "å", + "y", + "j", + "ø", + "c", + "æ", + "w", + ], + "Finnish": [ + "a", + "i", + "n", + "t", + "e", + "s", + "l", + "o", + "u", + "k", + "ä", + "m", + "r", + "v", + "j", + "h", + "p", + "y", + "d", + "ö", + "g", + "c", + "b", + "f", + "w", + "z", + ], + "Vietnamese": [ + "n", + "h", + "t", + "i", + "c", + "g", + "a", + "o", + "u", + "m", + "l", + "r", + "à", + "đ", + "s", + "e", + "v", + "p", + "b", + "y", + "ư", + "d", + "á", + "k", + "ộ", + "ế", + ], + "Czech": [ + "o", + "e", + "a", + "n", + "t", + "s", + "i", + "l", + "v", + "r", + "k", + "d", + "u", + "m", + "p", + "í", + "c", + "h", + "z", + "á", + "y", + "j", + "b", + "ě", + "é", + "ř", + ], + "Hungarian": [ + "e", + "a", + "t", + "l", + "s", + "n", + "k", + "r", + "i", + "o", + "z", + "á", + "é", + "g", + "m", + "b", + "y", + "v", + "d", + "h", + "u", + "p", + "j", + "ö", + "f", + "c", + ], + "Korean": [ + "이", + "다", + "에", + "의", + "는", + "로", + "하", + "을", + "가", + "고", + "지", + "서", + "한", + "은", + "기", + "으", + "년", + "대", + "사", + "시", + "를", + "리", + "도", + "인", + "스", + "일", + ], + "Indonesian": [ + "a", + "n", + "e", + "i", + "r", + "t", + "u", + "s", + "d", + "k", + "m", + "l", + "g", + "p", + "b", + "o", + "h", + "y", + "j", + "c", + "w", + "f", + "v", + "z", + "x", + "q", + ], + "Turkish": [ + "a", + "e", + "i", + "n", + "r", + "l", + "ı", + "k", + "d", + "t", + "s", + "m", + "y", + "u", + "o", + "b", + "ü", + "ş", + "v", + "g", + "z", + "h", + "c", + "p", + "ç", + "ğ", + ], + "Romanian": [ + "e", + "i", + "a", + "r", + "n", + "t", + "u", + "l", + "o", + "c", + "s", + "d", + "p", + "m", + "ă", + "f", + "v", + "î", + "g", + "b", + "ș", + "ț", + "z", + "h", + "â", + "j", + ], + "Farsi": [ + "ا", + "ی", + "ر", + "د", + "ن", + "ه", + "و", + "م", + "ت", + "ب", + "س", + "ل", + "ک", + "ش", + "ز", + "ف", + "گ", + "ع", + "خ", + "ق", + "ج", + "آ", + "پ", + "ح", + "ط", + "ص", + ], + "Arabic": [ + "ا", + "ل", + "ي", + "م", + "و", + "ن", + "ر", + "ت", + "ب", + "ة", + "ع", + "د", + "س", + "ف", + "ه", + "ك", + "ق", + "أ", + "ح", + "ج", + "ش", + "ط", + "ص", + "ى", + "خ", + "إ", + ], + "Danish": [ + "e", + "r", + "n", + "t", + "a", + "i", + "s", + "d", + "l", + "o", + "g", + "m", + "k", + "f", + "v", + "u", + "b", + "h", + "p", + "å", + "y", + "ø", + "æ", + "c", + "j", + "w", + ], + "Serbian": [ + "а", + "и", + "о", + "е", + "н", + "р", + "с", + "у", + "т", + "к", + "ј", + "в", + "д", + "м", + "п", + "л", + "г", + "з", + "б", + "a", + "i", + "e", + "o", + "n", + "ц", + "ш", + ], + "Lithuanian": [ + "i", + "a", + "s", + "o", + "r", + "e", + "t", + "n", + "u", + "k", + "m", + "l", + "p", + "v", + "d", + "j", + "g", + "ė", + "b", + "y", + "ų", + "š", + "ž", + "c", + "ą", + "į", + ], + "Slovene": [ + "e", + "a", + "i", + "o", + "n", + "r", + "s", + "l", + "t", + "j", + "v", + "k", + "d", + "p", + "m", + "u", + "z", + "b", + "g", + "h", + "č", + "c", + "š", + "ž", + "f", + "y", + ], + "Slovak": [ + "o", + "a", + "e", + "n", + "i", + "r", + "v", + "t", + "s", + "l", + "k", + "d", + "m", + "p", + "u", + "c", + "h", + "j", + "b", + "z", + "á", + "y", + "ý", + "í", + "č", + "é", + ], + "Hebrew": [ + "י", + "ו", + "ה", + "ל", + "ר", + "ב", + "ת", + "מ", + "א", + "ש", + "נ", + "ע", + "ם", + "ד", + "ק", + "ח", + "פ", + "ס", + "כ", + "ג", + "ט", + "צ", + "ן", + "ז", + "ך", + ], + "Bulgarian": [ + "а", + "и", + "о", + "е", + "н", + "т", + "р", + "с", + "в", + "л", + "к", + "д", + "п", + "м", + "з", + "г", + "я", + "ъ", + "у", + "б", + "ч", + "ц", + "й", + "ж", + "щ", + "х", + ], + "Croatian": [ + "a", + "i", + "o", + "e", + "n", + "r", + "j", + "s", + "t", + "u", + "k", + "l", + "v", + "d", + "m", + "p", + "g", + "z", + "b", + "c", + "č", + "h", + "š", + "ž", + "ć", + "f", + ], + "Hindi": [ + "क", + "र", + "स", + "न", + "त", + "म", + "ह", + "प", + "य", + "ल", + "व", + "ज", + "द", + "ग", + "ब", + "श", + "ट", + "अ", + "ए", + "थ", + "भ", + "ड", + "च", + "ध", + "ष", + "इ", + ], + "Estonian": [ + "a", + "i", + "e", + "s", + "t", + "l", + "u", + "n", + "o", + "k", + "r", + "d", + "m", + "v", + "g", + "p", + "j", + "h", + "ä", + "b", + "õ", + "ü", + "f", + "c", + "ö", + "y", + ], + "Thai": [ + "า", + "น", + "ร", + "อ", + "ก", + "เ", + "ง", + "ม", + "ย", + "ล", + "ว", + "ด", + "ท", + "ส", + "ต", + "ะ", + "ป", + "บ", + "ค", + "ห", + "แ", + "จ", + "พ", + "ช", + "ข", + "ใ", + ], + "Greek": [ + "α", + "τ", + "ο", + "ι", + "ε", + "ν", + "ρ", + "σ", + "κ", + "η", + "π", + "ς", + "υ", + "μ", + "λ", + "ί", + "ό", + "ά", + "γ", + "έ", + "δ", + "ή", + "ω", + "χ", + "θ", + "ύ", + ], + "Tamil": [ + "க", + "த", + "ப", + "ட", + "ர", + "ம", + "ல", + "ன", + "வ", + "ற", + "ய", + "ள", + "ச", + "ந", + "இ", + "ண", + "அ", + "ஆ", + "ழ", + "ங", + "எ", + "உ", + "ஒ", + "ஸ", + ], + "Kazakh": [ + "а", + "ы", + "е", + "н", + "т", + "р", + "л", + "і", + "д", + "с", + "м", + "қ", + "к", + "о", + "б", + "и", + "у", + "ғ", + "ж", + "ң", + "з", + "ш", + "й", + "п", + "г", + "ө", + ], +} + +LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES) + +# Bit flags for unified character classification. +# A single unicodedata.name() call sets all relevant flags at once. +_LATIN: int = 1 +_ACCENTUATED: int = 1 << 1 +_CJK: int = 1 << 2 +_HANGUL: int = 1 << 3 +_KATAKANA: int = 1 << 4 +_HIRAGANA: int = 1 << 5 +_THAI: int = 1 << 6 +_ARABIC: int = 1 << 7 +_ARABIC_ISOLATED_FORM: int = 1 << 8 +_HALFWIDTH_KATAKANA: int = 1 << 9 +_LIGATURE: int = 1 << 10 +_SUPERSCRIPT: int = 1 << 11 +_SENTENCE_OPEN_PUNCTUATION: int = 1 << 12 + +_ACCENT_KEYWORDS: tuple[str, ...] = ( + "WITH GRAVE", + "WITH ACUTE", + "WITH CEDILLA", + "WITH DIAERESIS", + "WITH CIRCUMFLEX", + "WITH TILDE", + "WITH MACRON", + "WITH RING ABOVE", +) + +# Pre-built lookup structures for FREQUENCIES (computed once at import time). +# character -> rank mapping per language (replaces list .index() calls). +_FREQUENCIES_RANK: dict[str, dict[str, int]] = { + lang: {char: rank for rank, char in enumerate(chars)} + for lang, chars in FREQUENCIES.items() +} + +# frozenset per language (avoids rebuilding set() per call). +_FREQUENCIES_SET: dict[str, frozenset[str]] = { + lang: frozenset(chars) for lang, chars in FREQUENCIES.items() +} + +# prebuilt list of secondary range names. +_SECONDARY_RANGE_NAMES: frozenset[str] = frozenset( + range_name + for range_name in UNICODE_RANGES_COMBINED + if any(keyword in range_name for keyword in UNICODE_SECONDARY_RANGE_KEYWORD) +) + +_KNOWN_MB_DECODERS: frozenset[str] = frozenset( + { + "utf_8", + "utf_8_sig", + "utf_16", + "utf_16_be", + "utf_16_le", + "utf_32", + "utf_32_le", + "utf_32_be", + "utf_7", + } +) + +_KNOWN_MB_CLASSES: frozenset[str] = frozenset( + { + "_codecs_cn", + "_codecs_hk", + "_codecs_iso2022", + "_codecs_jp", + "_codecs_kr", + "_codecs_tw", + } +) + +_IANA_NAMES: dict[str, str] = { + **aliases, + **{iana_name: iana_name for iana_name in aliases.values()}, + **{iana_name: iana_name for iana_name in IANA_NO_ALIASES}, +} +_MULTIBYTE_SEARCH_RADIUS: int = 32768 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py new file mode 100644 index 00000000000..4f17e8577f3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any +from warnings import warn + +from .api import from_bytes +from .constant import CHARDET_CORRESPONDENCE, TOO_SMALL_SEQUENCE + +if TYPE_CHECKING: + from typing import TypedDict + + class ResultDict(TypedDict): + encoding: str | None + language: str + confidence: float | None + + +def detect( + byte_str: bytes, should_rename_legacy: bool = False, **kwargs: Any +) -> ResultDict: + """ + chardet legacy method + Detect the encoding of the given byte string. It should be mostly backward-compatible. + Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it) + This function is deprecated and should be used to migrate your project easily, consult the documentation for + further information. Not planned for removal. + + :param byte_str: The byte sequence to examine. + :param should_rename_legacy: Should we rename legacy encodings + to their more modern equivalents? + """ + if len(kwargs): + warn( + f"charset-normalizer disregard arguments '{','.join(list(kwargs.keys()))}' in legacy function detect()" + ) + + if not isinstance(byte_str, (bytearray, bytes)): + raise TypeError( # pragma: nocover + f"Expected object of type bytes or bytearray, got: {type(byte_str)}" + ) + + if isinstance(byte_str, bytearray): + byte_str = bytes(byte_str) + + r = from_bytes(byte_str).best() + + encoding = r.encoding if r is not None else None + language = r.language if r is not None and r.language != "Unknown" else "" + confidence = 1.0 - r.chaos if r is not None else None + + # automatically lower confidence + # on small bytes samples. + # https://github.com/jawah/charset_normalizer/issues/391 + if ( + confidence is not None + and confidence >= 0.9 + and encoding + not in { + "utf_8", + "ascii", + } + and not r.bom # type: ignore[union-attr] + and len(byte_str) < TOO_SMALL_SEQUENCE + ): + confidence -= 0.2 + + # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process + # but chardet does return 'utf-8-sig' and it is a valid codec name. + if r is not None and encoding == "utf_8" and r.bom: + encoding += "_sig" + + if not should_rename_legacy and encoding in CHARDET_CORRESPONDENCE: + encoding = CHARDET_CORRESPONDENCE[encoding] + + return { + "encoding": encoding, + "language": language, + "confidence": confidence, + } diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py new file mode 100644 index 00000000000..6bd214f51d8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py @@ -0,0 +1,1065 @@ +from __future__ import annotations + +from functools import lru_cache +from logging import getLogger + + +from .constant import ( + COMMON_CJK_CHARACTERS, + COMMON_SAFE_ASCII_CHARACTERS, + TRACE, + CompatibleFamillyRange, + _ACCENTUATED, + _ARABIC, + _ARABIC_ISOLATED_FORM, + _BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES, + _CJK, + _COMPATIBLE_RANGE_FAMILIES, + _COMPATIBLE_WITH_ANY_RANGE_FAMILIES, + _HANGUL, + _HALFWIDTH_KATAKANA, + _HIRAGANA, + _KATAKANA, + _LATIN, + _LIGATURE, + _RANGE_FAMILIES, + _SENTENCE_OPEN_PUNCTUATION, + _SUPERSCRIPT, + _THAI, +) +from .utils import ( + _character_flags, + is_emoticon, + is_punctuation, + is_separator, + is_symbol, + remove_accent, + unicode_range, +) + +# Combined bitmask for CJK/Hangul/Katakana/Hiragana/Thai glyph detection. +_GLYPH_MASK: int = _CJK | _HANGUL | _KATAKANA | _HIRAGANA | _THAI + + +class CharInfo: + """Pre-computed character properties shared across all detectors.""" + + __slots__ = ( + "character", + "printable", + "alpha", + "upper", + "lower", + "space", + "digit", + "is_ascii", + "case_variable", + "flags", + "accentuated", + "latin", + "is_cjk", + "is_katakana", + "is_halfwidth_katakana", + "is_arabic", + "is_ligature", + "is_superscript", + "is_sentence_open_punctuation", + "is_glyph", + "punct", + "sym", + "range", + "sep", + "emoticon", + "safe", + "common_cjk", + "unaccented", + ) + + character: str + printable: bool + alpha: bool + upper: bool + lower: bool + space: bool + digit: bool + is_ascii: bool + case_variable: bool + flags: int + accentuated: bool + latin: bool + is_cjk: bool + is_katakana: bool + is_halfwidth_katakana: bool + is_arabic: bool + is_ligature: bool + is_superscript: bool + is_sentence_open_punctuation: bool + is_glyph: bool + punct: bool + sym: bool + range: str | None + sep: bool + emoticon: bool + safe: bool + common_cjk: bool + unaccented: str + + def __init__(self, character: str) -> None: + """Compute all properties for *character* (built once per codepoint, + every branch assigns every slot).""" + self.character = character + + # ASCII fast-path: for characters with ord < 128, we can skip + # _character_flags() entirely and derive most properties from ord. + o: int = ord(character) + if o < 128: + self.is_ascii = True + self.accentuated = False + self.unaccented = character + self.emoticon = False + self.common_cjk = False + self.safe = character in COMMON_SAFE_ASCII_CHARACTERS + self.is_cjk = False + self.is_katakana = False + self.is_halfwidth_katakana = False + self.is_arabic = False + self.is_ligature = False + self.is_superscript = False + self.is_sentence_open_punctuation = False + self.is_glyph = False + # ASCII alpha: a-z (97-122) or A-Z (65-90) + if 65 <= o <= 90: + # Uppercase ASCII letter + self.alpha = True + self.upper = True + self.lower = False + self.space = False + self.digit = False + self.printable = True + self.case_variable = True + self.flags = _LATIN + self.latin = True + self.punct = False + self.sym = False + elif 97 <= o <= 122: + # Lowercase ASCII letter + self.alpha = True + self.upper = False + self.lower = True + self.space = False + self.digit = False + self.printable = True + self.case_variable = True + self.flags = _LATIN + self.latin = True + self.punct = False + self.sym = False + elif 48 <= o <= 57: + # ASCII digit 0-9 + self.alpha = False + self.upper = False + self.lower = False + self.space = False + self.digit = True + self.printable = True + self.case_variable = False + self.flags = 0 + self.latin = False + self.punct = False + self.sym = False + elif o == 32 or (9 <= o <= 13): + # Space, tab, newline, etc. + self.alpha = False + self.upper = False + self.lower = False + self.space = True + self.digit = False + self.printable = o == 32 + self.case_variable = False + self.flags = 0 + self.latin = False + self.punct = False + self.sym = False + else: + # Other ASCII (punctuation, symbols, control chars) + self.printable = character.isprintable() + self.alpha = False + self.upper = False + self.lower = False + self.space = False + self.digit = False + self.case_variable = False + self.flags = 0 + self.latin = False + self.punct = is_punctuation(character) if self.printable else False + self.sym = is_symbol(character) if self.printable else False + else: + # Non-ASCII path + self.is_ascii = False + self.safe = False + self.printable = character.isprintable() + self.alpha = character.isalpha() + self.upper = character.isupper() + self.lower = character.islower() + self.space = character.isspace() + self.digit = character.isdigit() + self.case_variable = self.lower != self.upper + + # Flag-based classification (single unicodedata.name() call, lru-cached) + flags: int = _character_flags(character) + if self.alpha: + self.emoticon = False + else: + self.emoticon = is_emoticon(character) + self.flags = flags + self.accentuated = bool(flags & _ACCENTUATED) + self.latin = bool(flags & _LATIN) + self.is_cjk = bool(flags & _CJK) + self.is_katakana = bool(flags & _KATAKANA) + self.is_halfwidth_katakana = bool(flags & _HALFWIDTH_KATAKANA) + self.is_arabic = bool(flags & _ARABIC) + self.is_ligature = bool(flags & _LIGATURE) + self.is_superscript = bool(flags & _SUPERSCRIPT) + self.is_sentence_open_punctuation = bool(flags & _SENTENCE_OPEN_PUNCTUATION) + self.is_glyph = bool(flags & _GLYPH_MASK) + + if self.latin and self.accentuated: + self.unaccented = remove_accent(character) + else: + self.unaccented = character + + self.common_cjk = self.is_cjk and character in COMMON_CJK_CHARACTERS + + # Eagerly compute punct and sym (avoids property dispatch overhead + # on 300K+ accesses in the hot loop). + if self.printable: + self.punct = is_punctuation(character) + self.sym = is_symbol(character) + else: + self.punct = False + self.sym = False + + self.range = unicode_range(character) + self.sep = is_separator(character) + + +# Per-codepoint cache of CharInfo instances +# At most UTF-8 size allocated. +@lru_cache(maxsize=None) +def _char_info(character: str) -> CharInfo: + """Build (once per codepoint) and cache the CharInfo for *character*.""" + return CharInfo(character) + + +# ASCII table indexed by codepoint. +_ASCII_CHAR_INFO: list[CharInfo] = [ + CharInfo(chr(_codepoint)) for _codepoint in range(128) +] + + +class MessDetectorPlugin: + """ + Base abstract class used for mess detection plugins. + All detectors MUST extend and implement given methods. + """ + + __slots__ = () + + def feed_info(self, character: str, info: CharInfo) -> None: + """ + The main routine to be executed upon character. + Insert the logic in witch the text would be considered chaotic. + """ + raise NotImplementedError # Defensive: + + def reset(self) -> None: # Defensive: + """ + Permit to reset the plugin to the initial state. + """ + raise NotImplementedError + + @property + def ratio(self) -> float: + """ + Compute the chaos ratio based on what your feed() has seen. + Must NOT be lower than 0.; No restriction gt 0. + """ + raise NotImplementedError # Defensive: + + +class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): + __slots__ = ( + "_punctuation_count", + "_symbol_count", + "_character_count", + "_last_printable_char", + ) + + def __init__(self) -> None: + self._punctuation_count: int = 0 + self._symbol_count: int = 0 + self._character_count: int = 0 + + self._last_printable_char: str | None = None + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + self._character_count += 1 + + if character != self._last_printable_char and not info.safe: + if info.punct: + self._punctuation_count += 1 + elif not info.digit and info.sym and not info.emoticon: + self._symbol_count += 2 + + self._last_printable_char = character + + def reset(self) -> None: # Abstract + self._punctuation_count = 0 + self._character_count = 0 + self._symbol_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + ratio_of_punctuation: float = ( + self._punctuation_count + self._symbol_count + ) / self._character_count + + return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 + + +class TooManyAccentuatedPlugin(MessDetectorPlugin): + __slots__ = ("_character_count", "_accentuated_count") + + def __init__(self) -> None: + self._character_count: int = 0 + self._accentuated_count: int = 0 + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + self._character_count += 1 + + if info.accentuated: + self._accentuated_count += 1 + + def reset(self) -> None: # Abstract + self._character_count = 0 + self._accentuated_count = 0 + + @property + def ratio(self) -> float: + if self._character_count < 8: + return 0.0 + + ratio_of_accentuation: float = self._accentuated_count / self._character_count + return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 + + +class UnprintablePlugin(MessDetectorPlugin): + __slots__ = ("_unprintable_count", "_character_count", "_has_escape") + + def __init__(self) -> None: + self._unprintable_count: int = 0 + self._character_count: int = 0 + self._has_escape: bool = False + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + if character == "\x1b": + self._has_escape = True + + if ( + not info.printable + and not info.space + and character != "\x1a" + and character != "\ufeff" + ): + self._unprintable_count += 1 + self._character_count += 1 + + def reset(self) -> None: # Abstract + self._unprintable_count = 0 + self._has_escape = False + + @property + def ratio(self) -> float: + if self._character_count == 0: # Defensive: + return 0.0 + + if self._has_escape: + return 1.0 + + return (self._unprintable_count * 8) / self._character_count + + +class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): + __slots__ = ( + "_successive_count", + "_character_count", + "_last_latin_character", + "_last_was_accentuated", + ) + + def __init__(self) -> None: + self._successive_count: int = 0 + self._character_count: int = 0 + + self._last_latin_character: CharInfo | None = None + self._last_was_accentuated: bool = False + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + self._character_count += 1 + if ( + self._last_latin_character is not None + and info.accentuated + and self._last_was_accentuated + ): + if info.upper and self._last_latin_character.upper: + self._successive_count += 1 + if info.unaccented == self._last_latin_character.unaccented: + self._successive_count += 1 + self._last_latin_character = info + self._last_was_accentuated = info.accentuated + + def reset(self) -> None: # Abstract + self._successive_count = 0 + self._character_count = 0 + self._last_latin_character = None + self._last_was_accentuated = False + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return (self._successive_count * 2) / self._character_count + + +class SuspiciousRange(MessDetectorPlugin): + __slots__ = ( + "_suspicious_successive_range_count", + "_character_count", + "_last_printable_seen", + "_last_printable_range", + ) + + def __init__(self) -> None: + self._suspicious_successive_range_count: int = 0 + self._character_count: int = 0 + self._last_printable_seen: str | None = None + self._last_printable_range: str | None = None + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + self._character_count += 1 + + if info.space or info.punct or info.safe: + self._last_printable_seen = None + self._last_printable_range = None + return + + if self._last_printable_seen is None: + self._last_printable_seen = character + self._last_printable_range = info.range + return + + unicode_range_a: str | None = self._last_printable_range + unicode_range_b: str | None = info.range + + # Identical non-None ranges can never be suspicious. + if unicode_range_a != unicode_range_b or unicode_range_a is None: + if is_suspiciously_successive_range(unicode_range_a, unicode_range_b): + self._suspicious_successive_range_count += 1 + + self._last_printable_seen = character + self._last_printable_range = unicode_range_b + + def reset(self) -> None: # Abstract + self._character_count = 0 + self._suspicious_successive_range_count = 0 + self._last_printable_seen = None + self._last_printable_range = None + + @property + def ratio(self) -> float: + if self._character_count <= 13: + return 0.0 + + ratio_of_suspicious_range_usage: float = ( + self._suspicious_successive_range_count * 2 + ) / self._character_count + + return ratio_of_suspicious_range_usage + + +class SuperWeirdWordPlugin(MessDetectorPlugin): + __slots__ = ( + "_word_count", + "_bad_word_count", + "_foreign_long_count", + "_is_current_word_bad", + "_foreign_long_watch", + "_character_count", + "_bad_character_count", + "_buffer_length", + "_buffer_last_char", + "_buffer_last_char_accentuated", + "_buffer_accent_count", + "_buffer_glyph_count", + "_buffer_upper_count", + "_buffer_first_lower", + "_buffer_has_non_ascii", + "_buffer_last_char_ligature", + "_buffer_has_internal_ligature", + "_is_current_word_invalid", + "_invalid_word_count", + ) + + def __init__(self) -> None: + self._word_count: int = 0 + self._bad_word_count: int = 0 + self._foreign_long_count: int = 0 + + self._is_current_word_bad: bool = False + self._foreign_long_watch: bool = False + + self._character_count: int = 0 + self._bad_character_count: int = 0 + + self._buffer_length: int = 0 + self._buffer_last_char: str | None = None + self._buffer_last_char_accentuated: bool = False + self._buffer_accent_count: int = 0 + self._buffer_glyph_count: int = 0 + self._buffer_upper_count: int = 0 + self._buffer_first_lower: bool = False + self._buffer_has_non_ascii: bool = False + self._buffer_last_char_ligature: bool = False + self._buffer_has_internal_ligature: bool = False + self._is_current_word_invalid: bool = False + self._invalid_word_count: int = 0 + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + if info.alpha: + if self._buffer_last_char_ligature: + self._buffer_has_internal_ligature = True + self._buffer_last_char_ligature = info.is_ligature + if self._buffer_length == 0: + self._buffer_first_lower = info.lower + self._buffer_length += 1 + self._buffer_last_char = character + + if info.upper: + self._buffer_upper_count += 1 + if not info.is_ascii: + self._buffer_has_non_ascii = True + + self._buffer_last_char_accentuated = info.accentuated + + if info.accentuated: + self._buffer_accent_count += 1 + if info.is_glyph: + self._buffer_glyph_count += 1 + elif not self._foreign_long_watch and (not info.latin or info.accentuated): + self._foreign_long_watch = True + return + if not self._buffer_length: + return + if info.is_sentence_open_punctuation or ( + info.is_superscript and self._buffer_has_internal_ligature + ): + self._is_current_word_bad = True + self._is_current_word_invalid = True + if info.space or info.punct or info.sep: + self._word_count += 1 + buffer_length: int = self._buffer_length + + self._character_count += buffer_length + + if buffer_length >= 4: + if self._buffer_accent_count / buffer_length >= 0.5: + self._is_current_word_bad = True + elif ( + self._buffer_last_char_accentuated + and self._buffer_last_char.isupper() # type: ignore[union-attr] + and self._buffer_upper_count != buffer_length + ): + self._foreign_long_count += 1 + self._is_current_word_bad = True + elif self._buffer_glyph_count == 1: + self._is_current_word_bad = True + self._foreign_long_count += 1 + elif ( + self._buffer_has_non_ascii + and self._buffer_first_lower + and self._buffer_upper_count == buffer_length - 1 + ): + # Inverse capitalization detector. + # No natural writing produces such words. + # see https://github.com/jawah/charset_normalizer/issues/731 + self._foreign_long_count += 1 + self._is_current_word_bad = True + if buffer_length >= 24 and self._foreign_long_watch: + probable_camel_cased: bool = ( + self._buffer_upper_count > 0 + and self._buffer_upper_count / buffer_length <= 0.3 + ) + + if not probable_camel_cased: + self._foreign_long_count += 1 + self._is_current_word_bad = True + + if self._is_current_word_bad: + self._bad_word_count += 1 + self._bad_character_count += buffer_length + self._is_current_word_bad = False + if self._is_current_word_invalid: + self._invalid_word_count += 1 + self._is_current_word_invalid = False + + self._foreign_long_watch = False + self._buffer_length = 0 + self._buffer_last_char = None + self._buffer_last_char_accentuated = False + self._buffer_accent_count = 0 + self._buffer_glyph_count = 0 + self._buffer_upper_count = 0 + self._buffer_first_lower = False + self._buffer_has_non_ascii = False + self._buffer_last_char_ligature = False + self._buffer_has_internal_ligature = False + elif ( + character not in {"<", ">", "-", "=", "~", "|", "_"} + and not info.digit + and info.sym + ): + self._is_current_word_bad = True + self._buffer_length += 1 + self._buffer_last_char = character + self._buffer_last_char_accentuated = False + + def reset(self) -> None: # Abstract + self._buffer_length = 0 + self._buffer_last_char = None + self._buffer_last_char_accentuated = False + self._is_current_word_bad = False + self._foreign_long_watch = False + self._bad_word_count = 0 + self._word_count = 0 + self._character_count = 0 + self._bad_character_count = 0 + self._foreign_long_count = 0 + self._buffer_accent_count = 0 + self._buffer_glyph_count = 0 + self._buffer_upper_count = 0 + self._buffer_first_lower = False + self._buffer_has_non_ascii = False + self._buffer_last_char_ligature = False + self._buffer_has_internal_ligature = False + self._is_current_word_invalid = False + self._invalid_word_count = 0 + + @property + def ratio(self) -> float: + if self._invalid_word_count: + return 1.0 + + if self._word_count <= 10 and self._foreign_long_count == 0: + return 0.0 + + return self._bad_character_count / self._character_count + + +class CjkUncommonPlugin(MessDetectorPlugin): + """ + Detect messy CJK text that probably means nothing. + """ + + __slots__ = ("_character_count", "_uncommon_count") + + def __init__(self) -> None: + self._character_count: int = 0 + self._uncommon_count: int = 0 + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + self._character_count += 1 + + if not info.common_cjk: + self._uncommon_count += 1 + + def reset(self) -> None: # Abstract + self._character_count = 0 + self._uncommon_count = 0 + + @property + def ratio(self) -> float: + if self._character_count < 4: + return 0.0 + + uncommon_form_usage: float = ( + 2 * self._uncommon_count - self._character_count + ) / (5 * max(self._character_count, 16)) + + # we can be pretty sure it's garbage when uncommon characters are widely + # used. otherwise it could just be traditional chinese for example. + return max(0.0, uncommon_form_usage) + + +class SuspiciousKatakanaPlugin(MessDetectorPlugin): + """Detect implausible halfwidth Katakana and uncommon CJK combinations.""" + + __slots__ = ( + "_katakana_count", + "_halfwidth_katakana_count", + "_cjk_count", + "_uncommon_cjk_count", + ) + + def __init__(self) -> None: + self._katakana_count: int = 0 + self._halfwidth_katakana_count: int = 0 + self._cjk_count: int = 0 + self._uncommon_cjk_count: int = 0 + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + if info.is_katakana: + self._katakana_count += 1 + if info.is_halfwidth_katakana: + self._halfwidth_katakana_count += 1 + return + + self._cjk_count += 1 + if not info.common_cjk: + self._uncommon_cjk_count += 1 + + def reset(self) -> None: # Abstract + self._katakana_count = 0 + self._halfwidth_katakana_count = 0 + self._cjk_count = 0 + self._uncommon_cjk_count = 0 + + @property + def ratio(self) -> float: + if ( + self._halfwidth_katakana_count >= 4 + and self._halfwidth_katakana_count == self._katakana_count + and 3 <= self._cjk_count == self._uncommon_cjk_count + ): + return 1.0 + + return 0.0 + + +class ArchaicUpperLowerPlugin(MessDetectorPlugin): + __slots__ = ( + "_buf", + "_character_count_since_last_sep", + "_successive_upper_lower_count", + "_successive_upper_lower_count_final", + "_character_count", + "_last_alpha_seen_upper", + "_last_alpha_seen_lower", + "_current_ascii_only", + ) + + def __init__(self) -> None: + self._buf: bool = False + + self._character_count_since_last_sep: int = 0 + + self._successive_upper_lower_count: int = 0 + self._successive_upper_lower_count_final: int = 0 + + self._character_count: int = 0 + + self._last_alpha_seen_upper: bool = False + self._last_alpha_seen_lower: bool = False + self._current_ascii_only: bool = True + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + is_concerned: bool = info.alpha and info.case_variable + chunk_sep: bool = not is_concerned + + if chunk_sep and self._character_count_since_last_sep > 0: + if ( + self._character_count_since_last_sep <= 64 + and not info.digit + and not self._current_ascii_only + ): + self._successive_upper_lower_count_final += ( + self._successive_upper_lower_count + ) + + self._successive_upper_lower_count = 0 + self._character_count_since_last_sep = 0 + self._buf = False + self._character_count += 1 + self._current_ascii_only = True + + return + + if self._current_ascii_only and not info.is_ascii: + self._current_ascii_only = False + + if self._character_count_since_last_sep > 0: + if (info.upper and self._last_alpha_seen_lower) or ( + info.lower and self._last_alpha_seen_upper + ): + if self._buf: + self._successive_upper_lower_count += 2 + self._buf = False + else: + self._buf = True + else: + self._buf = False + + self._character_count += 1 + self._character_count_since_last_sep += 1 + self._last_alpha_seen_upper = info.upper + self._last_alpha_seen_lower = info.lower + + def reset(self) -> None: # Abstract + self._character_count = 0 + self._character_count_since_last_sep = 0 + self._successive_upper_lower_count = 0 + self._successive_upper_lower_count_final = 0 + self._last_alpha_seen_upper = False + self._last_alpha_seen_lower = False + self._buf = False + self._current_ascii_only = True + + @property + def ratio(self) -> float: + if self._character_count == 0: # Defensive: + return 0.0 + + return self._successive_upper_lower_count_final / self._character_count + + +class ArabicIsolatedFormPlugin(MessDetectorPlugin): + __slots__ = ("_character_count", "_isolated_form_count") + + def __init__(self) -> None: + self._character_count: int = 0 + self._isolated_form_count: int = 0 + + def reset(self) -> None: # Abstract + self._character_count = 0 + self._isolated_form_count = 0 + + def feed_info(self, character: str, info: CharInfo) -> None: + """Optimized feed using pre-computed character info.""" + self._character_count += 1 + + if info.flags & _ARABIC_ISOLATED_FORM: + self._isolated_form_count += 1 + + @property + def ratio(self) -> float: + if self._character_count < 8: + return 0.0 + + isolated_form_usage: float = self._isolated_form_count / self._character_count + + return isolated_form_usage + + +@lru_cache(maxsize=None) +def is_suspiciously_successive_range( + unicode_range_a: str | None, unicode_range_b: str | None +) -> bool: + """ + Determine if two Unicode ranges seen next to each other can be considered suspicious. + """ + if unicode_range_a is None or unicode_range_b is None: + return True + + familly_a: str = _RANGE_FAMILIES[unicode_range_a] + familly_b: str = _RANGE_FAMILIES[unicode_range_b] + + if familly_a == familly_b: + return False + + if ( + familly_a in _COMPATIBLE_WITH_ANY_RANGE_FAMILIES + or familly_b in _COMPATIBLE_WITH_ANY_RANGE_FAMILIES + ): + return False + + if CompatibleFamillyRange(familly_a, familly_b) in _COMPATIBLE_RANGE_FAMILIES: + return False + + # Basic Latin is commonly interspersed with East Asian scripts, but the + # compatibility must not extend to every range in the Latin family. + if unicode_range_a == "Basic Latin": + return familly_b not in _BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES + + if unicode_range_b == "Basic Latin": + return familly_a not in _BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES + + return True + + +def mess_ratio( + decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False +) -> float: + """ + Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier. + """ + + seq_len: int = len(decoded_sequence) + + if seq_len < 511: + step: int = 32 + elif seq_len < 1024: + step = 64 + else: + step = 128 + + # str.isascii() is O(1) (the flag lives in the str header). Seven of the + # ten detectors provably keep a 0.0 ratio on ASCII-only input and are + # therefore not fed at all. + is_pure_ascii: bool = decoded_sequence.isascii() + + # Cached per-codepoint character properties (see CharInfo). ASCII + # characters resolve through the immutable import-time table; anything + # else goes through the lru_cache-backed slow path. + ascii_info = _ASCII_CHAR_INFO + char_info = _char_info + + mean_mess_ratio: float + info: CharInfo + + # Create each detector as a named local variable (unrolled from the generic loop). + # This eliminates per-character iteration over the detector list and + # per-character eligible() virtual dispatch, while keeping every plugin class + # intact and fully readable. + d_sp: TooManySymbolOrPunctuationPlugin = TooManySymbolOrPunctuationPlugin() + d_ta: TooManyAccentuatedPlugin = TooManyAccentuatedPlugin() + d_up: UnprintablePlugin = UnprintablePlugin() + d_sda: SuspiciousDuplicateAccentPlugin = SuspiciousDuplicateAccentPlugin() + d_sr: SuspiciousRange = SuspiciousRange() + d_sw: SuperWeirdWordPlugin = SuperWeirdWordPlugin() + d_cu: CjkUncommonPlugin = CjkUncommonPlugin() + d_sk: SuspiciousKatakanaPlugin = SuspiciousKatakanaPlugin() + d_au: ArchaicUpperLowerPlugin = ArchaicUpperLowerPlugin() + d_ai: ArabicIsolatedFormPlugin = ArabicIsolatedFormPlugin() + + # Local references avoid repeated bound-method creation in the hot loop. + d_sp_feed = d_sp.feed_info + d_ta_feed = d_ta.feed_info + d_up_feed = d_up.feed_info + d_sda_feed = d_sda.feed_info + d_sr_feed = d_sr.feed_info + d_sw_feed = d_sw.feed_info + d_cu_feed = d_cu.feed_info + d_sk_feed = d_sk.feed_info + d_au_feed = d_au.feed_info + d_ai_feed = d_ai.feed_info + + for block_start in range(0, seq_len, step): + for character in decoded_sequence[block_start : block_start + step]: + # Character properties computed once per distinct codepoint + # (shared across all plugins and all mess_ratio calls). + # ord() doubles as the ASCII table index. + codepoint: int = ord(character) + if codepoint < 128: + info = ascii_info[codepoint] + else: + info = char_info(character) + + # Detectors with eligible() == always True + d_up_feed(character, info) + d_sw_feed(character, info) + + if is_pure_ascii: + # The seven remaining detectors provably stay at 0.0 (see above). + if info.printable: + d_sp_feed(character, info) + continue + + d_au_feed(character, info) + + # Detectors with eligible() == isprintable + if info.printable: + d_sp_feed(character, info) + d_sr_feed(character, info) + + # Detectors with eligible() == isalpha + if info.alpha: + d_ta_feed(character, info) + # SuspiciousDuplicateAccent: isalpha() and is_latin() + if info.latin: + d_sda_feed(character, info) + # CjkUncommon and SuspiciousKatakana: is_cjk() + if info.is_cjk: + d_cu_feed(character, info) + d_sk_feed(character, info) + elif info.is_katakana: + d_sk_feed(character, info) + # ArabicIsolatedForm: is_arabic() + if info.is_arabic: + d_ai_feed(character, info) + + mean_mess_ratio = ( + d_sp.ratio + + d_ta.ratio + + d_up.ratio + + d_sda.ratio + + d_sr.ratio + + d_sw.ratio + + d_cu.ratio + + d_sk.ratio + + d_au.ratio + + d_ai.ratio + ) + + if mean_mess_ratio >= maximum_threshold: + break + else: + # Flush last word buffer in SuperWeirdWordPlugin via trailing newline. + nl_info = ascii_info[10] # "\n" + d_sw_feed("\n", nl_info) + if not is_pure_ascii: + d_au_feed("\n", nl_info) + d_up_feed("\n", nl_info) + + mean_mess_ratio = ( + d_sp.ratio + + d_ta.ratio + + d_up.ratio + + d_sda.ratio + + d_sr.ratio + + d_sw.ratio + + d_cu.ratio + + d_sk.ratio + + d_au.ratio + + d_ai.ratio + ) + + if debug: # Defensive: + logger = getLogger("opentelemetry.agent._vendor.charset_normalizer") + + logger.log( + TRACE, + "Mess-detector extended-analysis start. " + f"intermediary_mean_mess_ratio_calc={step} mean_mess_ratio={mean_mess_ratio} " + f"maximum_threshold={maximum_threshold}", + ) + + if seq_len > 16: + logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}") + logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}") + + for dt in [d_sp, d_ta, d_up, d_sda, d_sr, d_sw, d_cu, d_sk, d_au, d_ai]: + logger.log(TRACE, f"{dt.__class__}: {dt.ratio}") + + return round(mean_mess_ratio, 3) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py new file mode 100644 index 00000000000..9b081a66b91 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py @@ -0,0 +1,387 @@ +from __future__ import annotations + +from encodings.aliases import aliases +from re import sub +from typing import Any, Iterator, List, Tuple + +from .constant import RE_POSSIBLE_ENCODING_INDICATION, TOO_BIG_SEQUENCE +from .utils import iana_name, is_multi_byte_encoding, unicode_range + + +class CharsetMatch: + def __init__( + self, + payload: bytes | bytearray, + guessed_encoding: str, + mean_mess_ratio: float, + has_sig_or_bom: bool, + languages: CoherenceMatches, + decoded_payload: str | None = None, + preemptive_declaration: str | None = None, + ): + self._payload: bytes | bytearray = payload + + self._encoding: str = guessed_encoding + self._mean_mess_ratio: float = mean_mess_ratio + self._languages: CoherenceMatches = languages + self._has_sig_or_bom: bool = has_sig_or_bom + self._unicode_ranges: list[str] | None = None + + self._leaves: list[CharsetMatch] = [] + self._mean_coherence_ratio: float = 0.0 + + self._output_payload: bytes | None = None + self._output_encoding: str | None = None + + self._string: str | None = decoded_payload + + self._preemptive_declaration: str | None = preemptive_declaration + + def __eq__(self, other: object) -> bool: + if not isinstance(other, CharsetMatch): + if isinstance(other, str): + # Use non-strict iana_name so an operand that is not a known + # encoding alias compares unequal instead of raising, keeping + # __eq__ total as the data model requires (mirrors the lookup + # in CharsetMatches.__getitem__). + return iana_name(other, False) == self.encoding + return False + return self.encoding == other.encoding and self.fingerprint == other.fingerprint + + def __lt__(self, other: object) -> bool: + """ + Implemented to make sorted available upon CharsetMatches items. + """ + if not isinstance(other, CharsetMatch): + raise ValueError + + chaos_difference: float = abs(self.chaos - other.chaos) + coherence_difference: float = abs(self.coherence - other.coherence) + + # Below 0.5% difference --> Use Coherence + if chaos_difference < 0.005 and coherence_difference > 0.02: + return self.coherence > other.coherence + elif chaos_difference < 0.005 and coherence_difference <= 0.02: + # When having a difficult decision, use the result that decoded as many multi-byte as possible. + # preserve RAM usage! + if len(self._payload) >= TOO_BIG_SEQUENCE: + return self.chaos < other.chaos + return self.multi_byte_usage > other.multi_byte_usage + + return self.chaos < other.chaos + + @property + def multi_byte_usage(self) -> float: + # Empty payloads are valid (from_bytes(b"") returns a match); avoid /0. + raw_len = len(self.raw) + if raw_len == 0: + return 0.0 + return 1.0 - (len(str(self)) / raw_len) + + def __str__(self) -> str: + # Lazy Str Loading + if self._string is None: + self._string = str(self._payload, self._encoding, "strict") + # UTF-7 BOM is encoded in modified Base64 whose byte boundary + # can overlap with the next character, so raw-byte stripping + # is unreliable. Strip the decoded BOM character instead. + if ( + self._has_sig_or_bom + and self._encoding == "utf_7" + and self._string + and self._string[0] == "\ufeff" + ): + self._string = self._string[1:] + return self._string + + def __repr__(self) -> str: + return f"" + + def add_submatch(self, other: CharsetMatch) -> None: + if not isinstance(other, CharsetMatch) or other == self: + raise ValueError( + "Unable to add instance <{}> as a submatch of a CharsetMatch".format( + other.__class__ + ) + ) + + other._string = None # Unload RAM usage; dirty trick. + self._leaves.append(other) + + @property + def encoding(self) -> str: + return self._encoding + + @property + def encoding_aliases(self) -> list[str]: + """ + Encoding name are known by many name, using this could help when searching for IBM855 when it's listed as CP855. + """ + also_known_as: list[str] = [] + for u, p in aliases.items(): + if self.encoding == u: + also_known_as.append(p) + elif self.encoding == p: + also_known_as.append(u) + return also_known_as + + @property + def bom(self) -> bool: + return self._has_sig_or_bom + + @property + def byte_order_mark(self) -> bool: + return self._has_sig_or_bom + + @property + def languages(self) -> list[str]: + """ + Return the complete list of possible languages found in decoded sequence. + Usually not really useful. Returned list may be empty even if 'language' property return something != 'Unknown'. + """ + return [e[0] for e in self._languages] + + @property + def language(self) -> str: + """ + Most probable language found in decoded sequence. If none were detected or inferred, the property will return + "Unknown". + """ + if not self._languages: + # Trying to infer the language based on the given encoding + # Its either English or we should not pronounce ourselves in certain cases. + if "ascii" in self.could_be_from_charset: + return "English" + + # doing it there to avoid circular import + from opentelemetry.agent._vendor.charset_normalizer.cd import encoding_languages, mb_encoding_languages + + languages = ( + mb_encoding_languages(self.encoding) + if is_multi_byte_encoding(self.encoding) + else encoding_languages(self.encoding) + ) + + if len(languages) == 0 or "Latin Based" in languages: + return "Unknown" + + return languages[0] + + return self._languages[0][0] + + @property + def chaos(self) -> float: + return self._mean_mess_ratio + + @property + def coherence(self) -> float: + if not self._languages: + return 0.0 + return self._languages[0][1] + + @property + def percent_chaos(self) -> float: + return round(self.chaos * 100, ndigits=3) + + @property + def percent_coherence(self) -> float: + return round(self.coherence * 100, ndigits=3) + + @property + def raw(self) -> bytes | bytearray: + """ + Original untouched bytes. + """ + return self._payload + + @property + def submatch(self) -> list[CharsetMatch]: + return self._leaves + + @property + def has_submatch(self) -> bool: + return len(self._leaves) > 0 + + @property + def alphabets(self) -> list[str]: + if self._unicode_ranges is not None: + return self._unicode_ranges + # list detected ranges + detected_ranges: list[str | None] = [unicode_range(char) for char in str(self)] + # filter and sort + self._unicode_ranges = sorted(list({r for r in detected_ranges if r})) + return self._unicode_ranges + + @property + def could_be_from_charset(self) -> list[str]: + """ + The complete list of encoding that output the exact SAME str result and therefore could be the originating + encoding. + This list does include the encoding available in property 'encoding'. + """ + return [self._encoding] + [m.encoding for m in self._leaves] + + def output(self, encoding: str = "utf_8") -> bytes: + """ + Method to get re-encoded bytes payload using given target encoding. Default to UTF-8. + Any errors will be simply ignored by the encoder NOT replaced. + """ + if self._output_encoding is None or self._output_encoding != encoding: + self._output_encoding = encoding + decoded_string = str(self) + if ( + self._preemptive_declaration is not None + and self._preemptive_declaration.lower() + not in ["utf-8", "utf8", "utf_8"] + ): + patched_header = sub( + RE_POSSIBLE_ENCODING_INDICATION, + lambda m: m.string[m.span()[0] : m.span()[1]].replace( + m.groups()[0], + iana_name(self._output_encoding).replace("_", "-"), # type: ignore[arg-type] + ), + decoded_string[:8192], + count=1, + ) + + decoded_string = patched_header + decoded_string[8192:] + + self._output_payload = decoded_string.encode(encoding, "replace") + + return self._output_payload # type: ignore + + @property + def fingerprint(self) -> int: + """ + Retrieve a hash fingerprint of the decoded payload, used for deduplication. + """ + return hash(str(self)) + + +class CharsetMatches: + """ + Container with every CharsetMatch items ordered by default from most probable to the less one. + Act like a list(iterable) but does not implements all related methods. + """ + + def __init__(self, results: list[CharsetMatch] | None = None): + self._results: list[CharsetMatch] = sorted(results) if results else [] + self._is_sorted: bool = True + + def _ensure_sorted(self) -> None: + if not self._is_sorted: + self._results.sort() + self._is_sorted = True + + def __iter__(self) -> Iterator[CharsetMatch]: + self._ensure_sorted() + yield from self._results + + def __getitem__(self, item: int | str) -> CharsetMatch: + """ + Retrieve a single item either by its position or encoding name (alias may be used here). + Raise KeyError upon invalid index or encoding not present in results. + """ + if isinstance(item, int): + self._ensure_sorted() + return self._results[item] + if isinstance(item, str): + item = iana_name(item, False) + for result in self._results: + if item in result.could_be_from_charset: + return result + raise KeyError + + def __len__(self) -> int: + return len(self._results) + + def __bool__(self) -> bool: + return len(self._results) > 0 + + def append(self, item: CharsetMatch) -> None: + """ + Insert a single match. Will be inserted accordingly to preserve sort. + Can be inserted as a submatch. + """ + if not isinstance(item, CharsetMatch): + raise ValueError( + "Cannot append instance '{}' to CharsetMatches".format( + str(item.__class__) + ) + ) + # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) + if len(item.raw) < TOO_BIG_SEQUENCE: + for match in self._results: + if match.fingerprint == item.fingerprint and match.chaos == item.chaos: + match.add_submatch(item) + return + self._results.append(item) + self._is_sorted = False + + def best(self) -> CharsetMatch | None: + """ + Simply return the first match. Strict equivalent to matches[0]. + """ + if not self._results: + return None + self._ensure_sorted() + return self._results[0] + + def first(self) -> CharsetMatch | None: + """ + Redundant method, call the method best(). Kept for BC reasons. + """ + return self.best() + + +CoherenceMatch = Tuple[str, float] +CoherenceMatches = List[CoherenceMatch] + + +class CliDetectionResult: + def __init__( + self, + path: str, + encoding: str | None, + encoding_aliases: list[str], + alternative_encodings: list[str], + language: str, + alphabets: list[str], + has_sig_or_bom: bool, + chaos: float, + coherence: float, + unicode_path: str | None, + is_preferred: bool, + ): + self.path: str = path + self.unicode_path: str | None = unicode_path + self.encoding: str | None = encoding + self.encoding_aliases: list[str] = encoding_aliases + self.alternative_encodings: list[str] = alternative_encodings + self.language: str = language + self.alphabets: list[str] = alphabets + self.has_sig_or_bom: bool = has_sig_or_bom + self.chaos: float = chaos + self.coherence: float = coherence + self.is_preferred: bool = is_preferred + + @property + def __dict__(self) -> dict[str, Any]: # type: ignore + return { + "path": self.path, + "encoding": self.encoding, + "encoding_aliases": self.encoding_aliases, + "alternative_encodings": self.alternative_encodings, + "language": self.language, + "alphabets": self.alphabets, + "has_sig_or_bom": self.has_sig_or_bom, + "chaos": self.chaos, + "coherence": self.coherence, + "unicode_path": self.unicode_path, + "is_preferred": self.is_preferred, + } + + def to_json(self) -> str: + from json import dumps + + return dumps(self.__dict__, ensure_ascii=True, indent=4) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py new file mode 100644 index 00000000000..34d3f8fc3db --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py @@ -0,0 +1,452 @@ +from __future__ import annotations + +import importlib +import logging +import unicodedata +from bisect import bisect_right +from codecs import IncrementalDecoder +from functools import lru_cache +from typing import Generator + +from .constant import ( + ENCODING_MARKS, + IANA_SUPPORTED_SIMILAR, + RE_POSSIBLE_ENCODING_INDICATION, + UNICODE_RANGES_COMBINED, + _SECONDARY_RANGE_NAMES, + COMMON_CJK_CHARACTERS, + _LATIN, + _CJK, + _HANGUL, + _KATAKANA, + _HIRAGANA, + _HALFWIDTH_KATAKANA, + _THAI, + _ARABIC, + _ARABIC_ISOLATED_FORM, + _LIGATURE, + _SUPERSCRIPT, + _SENTENCE_OPEN_PUNCTUATION, + _ACCENT_KEYWORDS, + _ACCENTUATED, + _KNOWN_MB_DECODERS, + _KNOWN_MB_CLASSES, + _IANA_NAMES, + _MULTIBYTE_SEARCH_RADIUS, +) + + +def _character_flags(character: str) -> int: + """Compute all name-based classification flags with a single unicodedata.name() call.""" + try: + desc: str = unicodedata.name(character) + except ValueError: + return 0 + + flags: int = 0 + + if "LATIN" in desc: + flags |= _LATIN + if "CJK" in desc: + flags |= _CJK + if "HANGUL" in desc: + flags |= _HANGUL + if "KATAKANA" in desc: + flags |= _KATAKANA + if "HALFWIDTH" in desc: + flags |= _HALFWIDTH_KATAKANA + if "HIRAGANA" in desc: + flags |= _HIRAGANA + if "THAI" in desc: + flags |= _THAI + if "ARABIC" in desc: + flags |= _ARABIC + if "ISOLATED FORM" in desc: + flags |= _ARABIC_ISOLATED_FORM + if "LIGATURE" in desc or desc.endswith("LETTER AE"): + flags |= _LIGATURE + if "SUPERSCRIPT" in desc: + flags |= _SUPERSCRIPT + if desc in {"INVERTED QUESTION MARK", "INVERTED EXCLAMATION MARK"}: + flags |= _SENTENCE_OPEN_PUNCTUATION + + for kw in _ACCENT_KEYWORDS: + if kw in desc: + flags |= _ACCENTUATED + break + + return flags + + +def is_accentuated(character: str) -> bool: + return bool(_character_flags(character) & _ACCENTUATED) + + +def remove_accent(character: str) -> str: + decomposed: str = unicodedata.decomposition(character) + if not decomposed: + return character + + codes: list[str] = decomposed.split(" ") + + return chr(int(codes[0], 16)) + + +# Pre-built sorted lookup table for O(log n) binary search in unicode_range(). +# Each entry is (range_start, range_end_exclusive, range_name). +_UNICODE_RANGES_SORTED: list[tuple[int, int, str]] = sorted( + (ord_range.start, ord_range.stop, name) + for name, ord_range in UNICODE_RANGES_COMBINED.items() +) +_UNICODE_RANGE_STARTS: list[int] = [e[0] for e in _UNICODE_RANGES_SORTED] + + +def unicode_range(character: str) -> str | None: + """ + Retrieve the Unicode range official name from a single character. + """ + character_ord: int = ord(character) + + if character_ord < 32: + return "Control character" + if character_ord < 128: + return "Basic Latin" + + # Binary search: find the rightmost range whose start <= character_ord + idx = bisect_right(_UNICODE_RANGE_STARTS, character_ord) - 1 + if idx >= 0: + start, stop, name = _UNICODE_RANGES_SORTED[idx] + if character_ord < stop: + return name + + return None + + +def is_latin(character: str) -> bool: + return bool(_character_flags(character) & _LATIN) + + +def is_punctuation(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "P" in character_category: + return True + + character_range: str | None = unicode_range(character) + + if character_range is None: + return False + + return "Punctuation" in character_range + + +def is_symbol(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "S" in character_category or "N" in character_category: + return True + + character_range: str | None = unicode_range(character) + + if character_range is None: + return False + + return "Forms" in character_range and character_category != "Lo" + + +def is_emoticon(character: str) -> bool: + character_range: str | None = unicode_range(character) + + if character_range is None: + return False + + return "Emoticons" in character_range or "Pictographs" in character_range + + +def is_separator(character: str) -> bool: + if character.isspace() or character in {"|", "+", "<", ">"}: + return True + + character_category: str = unicodedata.category(character) + + return "Z" in character_category or character_category in {"Po", "Pd", "Pc"} + + +def is_case_variable(character: str) -> bool: + return character.islower() != character.isupper() + + +def is_cjk(character: str) -> bool: + return bool(_character_flags(character) & _CJK) + + +def is_hiragana(character: str) -> bool: + return bool(_character_flags(character) & _HIRAGANA) + + +def is_katakana(character: str) -> bool: + return bool(_character_flags(character) & _KATAKANA) + + +def is_hangul(character: str) -> bool: + return bool(_character_flags(character) & _HANGUL) + + +def is_thai(character: str) -> bool: + return bool(_character_flags(character) & _THAI) + + +def is_arabic(character: str) -> bool: + return bool(_character_flags(character) & _ARABIC) + + +def is_arabic_isolated_form(character: str) -> bool: + return bool(_character_flags(character) & _ARABIC_ISOLATED_FORM) + + +def is_cjk_uncommon(character: str) -> bool: + return character not in COMMON_CJK_CHARACTERS + + +def is_unicode_range_secondary(range_name: str) -> bool: + return range_name in _SECONDARY_RANGE_NAMES + + +def is_unprintable(character: str) -> bool: + return ( + not character.isspace() # includes \n \t \r \v + and not character.isprintable() + and character != "\x1a" # Why? Its the ASCII substitute character. + and character != "\ufeff" # bug discovered in Python, + # Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space. + ) + + +def any_specified_encoding( + sequence: bytes | bytearray, search_zone: int = 8192 +) -> str | None: + """ + Extract using ASCII-only decoder any specified encoding in the first n-bytes. + """ + if not isinstance(sequence, (bytes, bytearray)): + raise TypeError + + seq_len: int = len(sequence) + + # Cheap literal pre-filter. + search_bytes = sequence[: min(seq_len, search_zone)] + lowered_bytes = search_bytes.lower() + if b"coding" not in lowered_bytes and b"charset" not in lowered_bytes: + return None + + decoded_zone: str = search_bytes.decode("ascii", errors="ignore") + + for match in RE_POSSIBLE_ENCODING_INDICATION.finditer(decoded_zone): + specified_encoding = match.group(1).lower().replace("-", "_") + encoding_iana = _IANA_NAMES.get(specified_encoding) + if encoding_iana is not None: + return encoding_iana + + return None + + +@lru_cache(maxsize=None) +def is_multi_byte_encoding(name: str) -> bool: + """ + Verify is a specific encoding is a multi byte one based on it IANA name + """ + if name in _KNOWN_MB_DECODERS: + return True + + # Besides the Unicode family above, every multibyte codec shipped with + # Python is implemented by _multibytecodec through exactly one of the six + # cjkcodecs providers below. Probing those providers directly (getcodec) + # classifies a name without importing its "encodings." module: + # classifying the whole IANA_SUPPORTED list would otherwise import many + # modules and dominate "import charset_normalizer" wall time. + # see https://github.com/jawah/charset_normalizer/issues/742 + for provider in _KNOWN_MB_CLASSES: + try: + importlib.import_module(provider).getcodec(name) # type: ignore[attr-defined] + except (ImportError, AttributeError, LookupError): # Defensive: edge cases + continue + return True + + return False + + +def identify_sig_or_bom(sequence: bytes | bytearray) -> tuple[str | None, bytes]: + """ + Identify and extract SIG/BOM in given sequence. + """ + + for iana_encoding in ENCODING_MARKS: + marks: bytes | list[bytes] = ENCODING_MARKS[iana_encoding] + + if isinstance(marks, bytes): + marks = [marks] + + for mark in marks: + if sequence.startswith(mark): + return iana_encoding, mark + + return None, b"" + + +def should_strip_sig_or_bom(iana_encoding: str) -> bool: + return iana_encoding not in {"utf_16", "utf_32"} + + +def iana_name(cp_name: str, strict: bool = True) -> str: + """Returns the Python normalized encoding name (Not the IANA official name).""" + cp_name = cp_name.lower().replace("-", "_") + + encoding_iana = _IANA_NAMES.get(cp_name) + if encoding_iana is not None: + return encoding_iana + + if strict: + raise ValueError(f"Unable to retrieve IANA for '{cp_name}'") + + return cp_name + + +def cp_similarity(iana_name_a: str, iana_name_b: str) -> float: + if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b): + return 0.0 + + decoder_a = importlib.import_module(f"encodings.{iana_name_a}").IncrementalDecoder + decoder_b = importlib.import_module(f"encodings.{iana_name_b}").IncrementalDecoder + + id_a: IncrementalDecoder = decoder_a(errors="ignore") + id_b: IncrementalDecoder = decoder_b(errors="ignore") + + character_match_count: int = 0 + + for i in range(256): + to_be_decoded: bytes = bytes([i]) + if id_a.decode(to_be_decoded) == id_b.decode(to_be_decoded): + character_match_count += 1 + + return character_match_count / 256 + + +def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool: + """ + Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using + the function cp_similarity. + """ + return ( + iana_name_a in IANA_SUPPORTED_SIMILAR + and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] + ) + + +def set_logging_handler( + name: str = "opentelemetry.agent._vendor.charset_normalizer", + level: int = logging.INFO, + format_string: str = "%(asctime)s | %(levelname)s | %(message)s", +) -> None: + logger = logging.getLogger(name) + logger.setLevel(level) + + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(format_string)) + logger.addHandler(handler) + + +def cut_sequence_chunks( + sequences: bytes | bytearray, + encoding_iana: str, + offsets: range, + chunk_size: int, + bom_or_sig_available: bool, + strip_sig_or_bom: bool, + sig_payload: bytes, + is_multi_byte_decoder: bool, + decoded_payload: str | None = None, + deferred_decoding: bool = False, +) -> Generator[str, None, None]: + # iso2022 codec is stateful, generic mb cuter isn't going to cut it! + if decoded_payload and encoding_iana.startswith("iso2022_"): + decoded_length = len(decoded_payload) + sequence_length = len(sequences) + for i in offsets: + decoded_offset = i * decoded_length // sequence_length + chunk = decoded_payload[decoded_offset : decoded_offset + chunk_size] + if not chunk: + break + yield chunk + elif decoded_payload and not is_multi_byte_decoder: + for i in offsets: + chunk = decoded_payload[i : i + chunk_size] + if not chunk: + break + yield chunk + elif deferred_decoding: + # Deferred single-byte probing: the whole payload is not decoded + # yet. Single-byte codecs are stateless (1 byte == 1 char), hence + # decode(base)[i:j] == decode(base[i:j]): slicing the raw bytes + # yields exactly the chunks the branch above would have produced, + # short trailing chunks included, and raises UnicodeDecodeError on + # invalid bytes just like the whole-payload decode would. + base_bytes = ( + sequences if not strip_sig_or_bom else sequences[len(sig_payload) :] + ) + for i in offsets: + cut_sequence = base_bytes[i : i + chunk_size] + if not cut_sequence: + break + yield str(cut_sequence, encoding_iana) + else: + for i in offsets: + chunk_end = i + chunk_size + if chunk_end > len(sequences) + 8: + continue + + cut_sequence = sequences[i : i + chunk_size] + + if bom_or_sig_available and not strip_sig_or_bom: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode( + encoding_iana, + errors="ignore" if is_multi_byte_decoder else "strict", + ) + + # multi-byte bad cutting detector and adjustment + # not the cleanest way to perform that fix but clever enough for now. + if is_multi_byte_decoder and i > 0: + chunk_partial_size_chk: int = min(chunk_size, 16) + chunk_prefix = chunk[:chunk_partial_size_chk] + found_nearby = False + + if decoded_payload: + decoded_length = len(decoded_payload) + expected_offset = i * decoded_length // len(sequences) + search_start = max(0, expected_offset - _MULTIBYTE_SEARCH_RADIUS) + search_end = min( + decoded_length, expected_offset + _MULTIBYTE_SEARCH_RADIUS + ) + found_nearby = ( + decoded_payload.find(chunk_prefix, search_start, search_end) + >= 0 + ) + + if ( + decoded_payload + and not found_nearby + and chunk_prefix not in decoded_payload + ): + for j in range(i, i - 4, -1): + cut_sequence = sequences[j:chunk_end] + + if bom_or_sig_available and not strip_sig_or_bom: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode(encoding_iana, errors="ignore") + + if chunk[:chunk_partial_size_chk] in decoded_payload: + break + + yield chunk diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py new file mode 100644 index 00000000000..c362b2c0fe2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py @@ -0,0 +1,8 @@ +""" +Expose version +""" + +from __future__ import annotations + +__version__ = "3.5.2" +VERSION = __version__.split(".") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS new file mode 100644 index 00000000000..c26fdd231d6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS @@ -0,0 +1,11 @@ +MAINTAINER +Michal Hořejšek + +CONTRIBUTORS +anentropic +Antti Jokipii +bcaller +Frederik Petersen +Guillaume Desvé +Kris Molendyke +David Majda diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE new file mode 100644 index 00000000000..1d77bbf99f3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2018, Michal Horejsek +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + Neither the name of the {organization} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py new file mode 100644 index 00000000000..87215ffd003 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py @@ -0,0 +1,386 @@ +# ___ +# \./ DANGER: This project implements some code generation +# .--.O.--. techniques involving string concatenation. +# \/ \/ If you look at it, you might die. +# + +r""" +Installation +************ + +.. code-block:: bash + + pip install fastjsonschema + +Support only for Python 3.3 and higher. + +About +***** + +``fastjsonschema`` implements validation of JSON documents by JSON schema. +The library implements JSON schema drafts 04, 06, and 07. The main purpose is +to have a really fast implementation. See some numbers: + + * Probably the most popular, ``jsonschema``, can take up to 5 seconds for valid + inputs and 1.2 seconds for invalid inputs. + * Second most popular, ``json-spec``, is even worse with up to 7.2 and 1.7 seconds. + * Last ``validictory``, now deprecated, is much better with 370 or 23 milliseconds, + but it does not follow all standards, and it can be still slow for some purposes. + +With this library you can gain big improvements as ``fastjsonschema`` takes +only about 25 milliseconds for valid inputs and 2 milliseconds for invalid ones. +Pretty amazing, right? :-) + +Technically it works by generating the most stupid code on the fly, which is fast but +is hard to write by hand. The best efficiency is achieved when a validator is compiled +once and used many times, of course. It works similarly like regular expressions. But +you can also generate the code to a file, which is even slightly faster. + +You can run the performance benchmarks on your computer or server with the included +script: + +.. code-block:: bash + + $ make performance + fast_compiled valid ==> 0.0993900 + fast_compiled invalid ==> 0.0041089 + fast_compiled_without_exc valid ==> 0.0465258 + fast_compiled_without_exc invalid ==> 0.0023688 + fast_file valid ==> 0.0989483 + fast_file invalid ==> 0.0041104 + fast_not_compiled valid ==> 11.9572681 + fast_not_compiled invalid ==> 2.9512092 + jsonschema valid ==> 5.2233240 + jsonschema invalid ==> 1.3227916 + jsonschema_compiled valid ==> 0.4447982 + jsonschema_compiled invalid ==> 0.0231333 + jsonspec valid ==> 4.1450569 + jsonspec invalid ==> 1.0485777 + validictory valid ==> 0.2730411 + validictory invalid ==> 0.0183669 + +This library follows and implements `JSON schema draft-04, draft-06, and draft-07 +`_. Sometimes it's not perfectly clear, so I recommend also +check out this `understanding JSON schema `_. + +Note that there are some differences compared to JSON schema standard: + + * Regular expressions are full Python ones, not only what JSON schema allows. It's easier + to allow everything, and also it's faster to compile without limits. So keep in mind that when + you will use a more advanced regular expression, it may not work with other libraries or in + other languages. + * Because Python matches new line for a dollar in regular expressions (``a$`` matches ``a`` and ``a\\n``), + instead of ``$`` is used ``\Z`` and all dollars in your regular expression are changed to ``\\Z`` + as well. When you want to use dollar as regular character, you have to escape it (``\$``). + * JSON schema says you can use keyword ``default`` for providing default values. This implementation + uses that and always returns transformed input data. + +Usage +***** + +.. code-block:: python + + import fastjsonschema + + point_schema = { + "type": "object", + "properties": { + "x": { + "type": "number", + }, + "y": { + "type": "number", + }, + }, + "required": ["x", "y"], + "additionalProperties": False, + } + + point_validator = fastjsonschema.compile(point_schema) + try: + point_validator({"x": 1.0, "y": 2.0}) + except fastjsonschema.JsonSchemaException as e: + print(f"Data failed validation: {e}") + +API +*** +""" +from collections.abc import Callable, Mapping +from functools import partial, update_wrapper +from typing import Any + +from .draft04 import CodeGeneratorDraft04 +from .draft06 import CodeGeneratorDraft06 +from .draft07 import CodeGeneratorDraft07 +from .draft2019 import CodeGeneratorDraft2019 +from .exceptions import ( + JsonSchemaException, + JsonSchemaValueException, + JsonSchemaValuesException, + JsonSchemaDefinitionException, +) +from .ref_resolver import RefResolver +from .version import VERSION + +__all__ = ( + 'VERSION', + 'JsonSchemaException', + 'JsonSchemaValueException', + 'JsonSchemaValuesException', + 'JsonSchemaDefinitionException', + 'validate', + 'compile', + 'compile_to_code', +) + + +Definition = dict[str, Any] | bool +Handlers = Mapping[str, Callable[[str], Any]] +Formats = Mapping[str, str | Callable[[Any], bool]] +Validator = Callable[..., Any] + + +def validate( + definition: Definition, + data: Any, + handlers: Handlers = {}, + formats: Formats = {}, + use_default: bool = True, + use_formats: bool = True, + detailed_exceptions: bool = True, + fast_fail: bool = True, +) -> Any: + """ + Validation function for lazy programmers or for use cases when you need + to call validation only once, so you do not have to compile it first. + Use it only when you do not care about performance (even though it will + be still faster than alternative implementations). + + .. code-block:: python + + import fastjsonschema + + fastjsonschema.validate({'type': 'string'}, 'hello') + # same as: compile({'type': 'string'})('hello') + + Preferred is to use :any:`compile` function. + + The ``handlers`` parameter controls resolution of remote ``$ref`` URIs; see + :any:`compile` for details and security considerations when schemas are not + fully trusted. + """ + return compile(definition, handlers, formats, use_default, use_formats, detailed_exceptions, fast_fail)(data) + + +#TODO: Change use_default to False when upgrading to version 3. +# pylint: disable=redefined-builtin,dangerous-default-value,exec-used +def compile( + definition: Definition, + handlers: Handlers = {}, + formats: Formats = {}, + use_default: bool = True, + use_formats: bool = True, + detailed_exceptions: bool = True, + fast_fail: bool = True, +) -> Validator: + """ + Generates validation function for validating JSON schema passed in ``definition``. + Example: + + .. code-block:: python + + import fastjsonschema + + validate = fastjsonschema.compile({'type': 'string'}) + validate('hello') + + This implementation supports keyword ``default`` (can be turned off + by passing `use_default=False`): + + .. code-block:: python + + validate = fastjsonschema.compile({ + 'type': 'object', + 'properties': { + 'a': {'type': 'number', 'default': 42}, + }, + }) + + data = validate({}) + assert data == {'a': 42} + + Supported implementations are draft-04, draft-06 and draft-07. Which version + should be used is determined by `$draft` in your ``definition``. When not + specified, the latest implementation is used (draft-07). + + .. code-block:: python + + validate = fastjsonschema.compile({ + '$schema': 'http://json-schema.org/draft-04/schema', + 'type': 'number', + }) + + You can pass mapping from URI scheme to function that should be used to + retrieve remote references used in your ``definition`` in parameter + ``handlers``. When no handler is registered for a scheme, the URI is + fetched automatically via :mod:`urllib` (for example ``http``, ``https``, + or ``file`` URLs). + + .. warning:: + + Do not compile or validate untrusted schemas without custom + ``handlers``. A schema containing ``$ref`` can trigger outbound HTTP + requests to arbitrary URLs, including internal or loopback addresses + (server-side request forgery). Provide ``handlers`` to restrict which + URIs are resolved, or pre-resolve references before passing the schema + to this library. + + .. code-block:: python + + def http_handler(uri): + if not uri.startswith('https://schemas.example.com/'): + raise ValueError('ref not allowed') + import urllib.request + with urllib.request.urlopen(uri) as response: + return json.loads(response.read()) + + validate = fastjsonschema.compile(definition, handlers={ + 'http': http_handler, + 'https': http_handler, + }) + + Also, you can pass mapping for custom formats. Key is the name of your + formatter and value can be regular expression, which will be compiled or + callback returning `bool` (or you can raise your own exception). + + .. code-block:: python + + validate = fastjsonschema.compile(definition, formats={ + 'foo': r'foo|bar', + 'bar': lambda value: value in ('foo', 'bar'), + }) + + Note that formats are automatically used as assertions. It can be turned + off by passing `use_formats=False`. When disabled, custom formats are + disabled as well. (Added in 2.19.0.) + + If you don't need detailed exceptions, you can turn the details off and gain + additional performance by passing `detailed_exceptions=False`. + + By default, the execution stops with the first validation error. If you need + to collect all the errors, turn this off by passing `fast_fail=False`. + + Exception :any:`JsonSchemaDefinitionException` is raised when generating the + code fails (bad definition). + + Exception :any:`JsonSchemaValueException` is raised from generated function when + validation fails (data do not follow the definition). + + Exception :any:`JsonSchemaValuesException` is raised from generated function when + validation fails (data do not follow the definition) contatining all the errors + (when fast_fail is set to `False`). + """ + resolver, code_generator = _factory( + definition, + handlers, + formats, + use_default, + use_formats, + detailed_exceptions, + fast_fail, + ) + global_state = code_generator.global_state + # Do not pass local state so it can recursively call itself. + exec(code_generator.func_code, global_state) + func = global_state[resolver.get_scope_name()] + if formats: + return update_wrapper(partial(func, custom_formats=formats), func) + return func + + +# pylint: disable=dangerous-default-value +def compile_to_code( + definition: Definition, + handlers: Handlers = {}, + formats: Formats = {}, + use_default: bool = True, + use_formats: bool = True, + detailed_exceptions: bool = True, + fast_fail: bool = True, +) -> str: + """ + Generates validation code for validating JSON schema passed in ``definition``. + Example: + + .. code-block:: python + + import fastjsonschema + + code = fastjsonschema.compile_to_code({'type': 'string'}) + with open('your_file.py', 'w') as f: + f.write(code) + + You can also use it as a script: + + .. code-block:: bash + + echo "{'type': 'string'}" | python3 -m fastjsonschema > your_file.py + python3 -m fastjsonschema "{'type': 'string'}" > your_file.py + + Exception :any:`JsonSchemaDefinitionException` is raised when generating the + code fails (bad definition). + + Remote ``$ref`` URIs are resolved the same way as in :any:`compile`; see its + documentation for ``handlers`` and security considerations. + """ + _, code_generator = _factory( + definition, + handlers, + formats, + use_default, + use_formats, + detailed_exceptions, + fast_fail, + ) + return ( + 'VERSION = "' + VERSION + '"\n' + + code_generator.global_state_code + '\n' + + code_generator.func_code + ) + + +def _factory( + definition: Definition, + handlers: Handlers, + formats: Formats = {}, + use_default: bool = True, + use_formats: bool = True, + detailed_exceptions: bool = True, + fast_fail: bool = True, +) -> tuple[RefResolver, CodeGeneratorDraft04]: + resolver = RefResolver.from_schema(definition, handlers=handlers, store={}) + code_generator = _get_code_generator_class(definition)( + definition, + resolver=resolver, + formats=formats, + use_default=use_default, + use_formats=use_formats, + detailed_exceptions=detailed_exceptions, + fast_fail=fast_fail, + ) + return resolver, code_generator + + +def _get_code_generator_class(schema: Definition) -> type[CodeGeneratorDraft04]: + # Schema in from draft-06 can be just the boolean value. + if isinstance(schema, dict): + schema_version = schema.get('$schema', '') + if 'draft-04' in schema_version: + return CodeGeneratorDraft04 + if 'draft-06' in schema_version: + return CodeGeneratorDraft06 + if 'draft-07' in schema_version: + return CodeGeneratorDraft07 + if 'draft/2019' in schema_version or 'draft-2019' in schema_version: + return CodeGeneratorDraft2019 + return CodeGeneratorDraft2019 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py new file mode 100644 index 00000000000..9d8eca36f5e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py @@ -0,0 +1,686 @@ +import decimal +import re + +from .exceptions import JsonSchemaDefinitionException +from .generator import VALIDATION_EXCEPTIONS, CodeGenerator, enforce_list, repr_default + + +JSON_TYPE_TO_PYTHON_TYPE = { + 'null': 'NoneType', + 'boolean': 'bool', + 'number': 'int, float, Decimal', + 'integer': 'int', + 'string': 'str', + 'array': 'list, tuple', + 'object': 'dict', +} + +DOLLAR_FINDER = re.compile(r"(? {maxLength}:'): + self.exc('{name} must be shorter than or equal to {maxLength} characters', rule='maxLength') + + def generate_pattern(self): + with self.l('if isinstance({variable}, str):'): + pattern = self._definition['pattern'] + safe_pattern = self.e(pattern) + end_of_string_fixed_pattern = DOLLAR_FINDER.sub(r'\\Z', pattern) + self._compile_regexps[pattern] = re.compile(end_of_string_fixed_pattern) + with self.l('if not REGEX_PATTERNS[{}].search({variable}):', repr(pattern)): + self.exc('{name} must match pattern {}', safe_pattern, rule='pattern') + + def generate_format(self): + """ + Means that value have to be in specified format. For example date, email or other. + + .. code-block:: python + + {'format': 'email'} + + Valid value for this definition is user@example.com but not @username + """ + if not self._use_formats: + return + format_ = self._definition['format'] + if format_ not in self._custom_formats and format_ not in self.FORMAT_REGEXS and format_ != 'regex': + return + with self.l('if isinstance({variable}, str):'): + # Checking custom formats - user is allowed to override default formats. + if format_ in self._custom_formats: + custom_format = self._custom_formats[format_] + if isinstance(custom_format, str): + self._generate_format(format_, format_ + '_re_pattern', custom_format) + else: + with self.l('if not custom_formats["{}"]({variable}):', format_): + self.exc('{name} must be {}', format_, rule='format') + elif format_ in self.FORMAT_REGEXS: + format_regex = self.FORMAT_REGEXS[format_] + self._generate_format(format_, format_ + '_re_pattern', format_regex) + # Format regex is used only in meta schemas. + elif format_ == 'regex': + self._extra_imports_lines = ['import re'] + with self.l('try:', optimize=False): + self.l('re.compile({variable})') + with self.l('except Exception:'): + self.exc('{name} must be a valid regex', rule='format') + + + def _generate_format(self, format_name, regexp_name, regexp): + if self._definition['format'] == format_name: + if not regexp_name in self._compile_regexps: + self._compile_regexps[regexp_name] = re.compile(regexp) + with self.l('if not REGEX_PATTERNS["{}"].match({variable}):', regexp_name): + self.exc('{name} must be {}', format_name, rule='format') + + def generate_minimum(self): + with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): + if not isinstance(self._definition['minimum'], (int, float, decimal.Decimal)): + raise JsonSchemaDefinitionException('minimum must be a number') + if self._definition.get('exclusiveMinimum', False): + with self.l('if {variable} <= {minimum}:'): + self.exc('{name} must be bigger than {minimum}', rule='minimum') + else: + with self.l('if {variable} < {minimum}:'): + self.exc('{name} must be bigger than or equal to {minimum}', rule='minimum') + + def generate_maximum(self): + with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): + if not isinstance(self._definition['maximum'], (int, float, decimal.Decimal)): + raise JsonSchemaDefinitionException('maximum must be a number') + if self._definition.get('exclusiveMaximum', False): + with self.l('if {variable} >= {maximum}:'): + self.exc('{name} must be smaller than {maximum}', rule='maximum') + else: + with self.l('if {variable} > {maximum}:'): + self.exc('{name} must be smaller than or equal to {maximum}', rule='maximum') + + def generate_multiple_of(self): + with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): + if not isinstance(self._definition['multipleOf'], (int, float, decimal.Decimal)): + raise JsonSchemaDefinitionException('multipleOf must be a number') + # Integer division through a float loses precision or can overflow. + with self.l('if isinstance({variable}, int) and isinstance({multipleOf}, int):'): + with self.l('if {variable} % {multipleOf} != 0:'): + self.exc('{name} must be multiple of {multipleOf}', rule='multipleOf') + with self.l('else:'): + # For proper multiplication check of floats we need to use decimals, + # because for example 19.01 / 0.01 = 1901.0000000000002. + if isinstance(self._definition['multipleOf'], float): + self.l('quotient = Decimal(repr({variable})) / Decimal(repr({multipleOf}))') + else: + self.l('quotient = {variable} / {multipleOf}') + with self.l('if int(quotient) != quotient:'): + self.exc('{name} must be multiple of {multipleOf}', rule='multipleOf') + # For example, 1e308 / 0.123456789 + with self.l('if {variable} / {multipleOf} == float("inf"):'): + self.exc('inifinity reached', rule='multipleOf') + + def generate_min_items(self): + self.create_variable_is_list() + with self.l('if {variable}_is_list:'): + if not isinstance(self._definition['minItems'], (int, float)): + raise JsonSchemaDefinitionException('minItems must be a number') + self.create_variable_with_length() + with self.l('if {variable}_len < {minItems}:'): + self.exc('{name} must contain at least {minItems} items', rule='minItems') + + def generate_max_items(self): + self.create_variable_is_list() + with self.l('if {variable}_is_list:'): + if not isinstance(self._definition['maxItems'], (int, float)): + raise JsonSchemaDefinitionException('maxItems must be a number') + self.create_variable_with_length() + with self.l('if {variable}_len > {maxItems}:'): + self.exc('{name} must contain less than or equal to {maxItems} items', rule='maxItems') + + def generate_unique_items(self): + """ + With Python 3.4 module ``timeit`` recommended this solutions: + + .. code-block:: python + + >>> timeit.timeit("len(x) > len(set(x))", "x=range(100)+range(100)", number=100000) + 0.5839540958404541 + >>> timeit.timeit("len({}.fromkeys(x)) == len(x)", "x=range(100)+range(100)", number=100000) + 0.7094449996948242 + >>> timeit.timeit("seen = set(); any(i in seen or seen.add(i) for i in x)", "x=range(100)+range(100)", number=100000) + 2.0819358825683594 + >>> timeit.timeit("np.unique(x).size == len(x)", "x=range(100)+range(100); import numpy as np", number=100000) + 2.1439831256866455 + """ + unique_definition = self._definition['uniqueItems'] + if not unique_definition: + return + + self.create_variable_is_list() + with self.l('if {variable}_is_list:'): + self.l( + 'def fn(var): ' + 'return frozenset(dict((k, fn(v)) ' + 'for k, v in var.items()).items()) ' + 'if hasattr(var, "items") else tuple(fn(v) ' + 'for v in var) ' + 'if isinstance(var, (dict, list)) else (bool, var) ' + 'if isinstance(var, bool) else var') + self.create_variable_with_length() + with self.l('if {variable}_len > len(set(fn({variable}_x) for {variable}_x in {variable})):'): + self.exc('{name} must contain unique items', rule='uniqueItems') + + def generate_items(self): + """ + Means array is valid only when all items are valid by this definition. + + .. code-block:: python + + { + 'items': [ + {'type': 'integer'}, + {'type': 'string'}, + ], + } + + Valid arrays are those with integers or strings, nothing else. + + Since draft 06 definition can be also boolean. True means nothing, False + means everything is invalid. + """ + items_definition = self._definition['items'] + if items_definition is True: + return + + self.create_variable_is_list() + with self.l('if {variable}_is_list:'): + self.create_variable_with_length() + if items_definition is False: + with self.l('if {variable}:'): + self.exc('{name} must not be there', rule='items') + elif isinstance(items_definition, list): + for idx, item_definition in enumerate(items_definition): + with self.l('if {variable}_len > {}:', idx): + self.l('{variable}__{0} = {variable}[{0}]', idx) + self.generate_func_code_block( + item_definition, + '{}__{}'.format(self._variable, idx), + '{}[{}]'.format(self._variable_name, idx), + ) + if self._use_default and isinstance(item_definition, dict) and 'default' in item_definition: + self.l('else: {variable}.append({})', repr_default(item_definition['default'])) + + if 'additionalItems' in self._definition: + if self._definition['additionalItems'] is False: + with self.l('if {variable}_len > {}:', len(items_definition)): + self.exc('{name} must contain only specified items', rule='items') + else: + with self.l('for {variable}_x, {variable}_item in enumerate({variable}[{0}:], {0}):', len(items_definition)): + code_len = len(self._code) + self.generate_func_code_block( + self._definition['additionalItems'], + '{}_item'.format(self._variable), + '{}[{{{}_x}}]'.format(self._variable_name, self._variable), + ) + if len(self._code) == code_len: + self.l('pass') + else: + if items_definition: + with self.l('for {variable}_x, {variable}_item in enumerate({variable}):'): + code_len = len(self._code) + self.generate_func_code_block( + items_definition, + '{}_item'.format(self._variable), + '{}[{{{}_x}}]'.format(self._variable_name, self._variable), + ) + if len(self._code) == code_len: + self.l('pass') + + def generate_min_properties(self): + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + if not isinstance(self._definition['minProperties'], (int, float)): + raise JsonSchemaDefinitionException('minProperties must be a number') + self.create_variable_with_length() + with self.l('if {variable}_len < {minProperties}:'): + self.exc('{name} must contain at least {minProperties} properties', rule='minProperties') + + def generate_max_properties(self): + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + if not isinstance(self._definition['maxProperties'], (int, float)): + raise JsonSchemaDefinitionException('maxProperties must be a number') + self.create_variable_with_length() + with self.l('if {variable}_len > {maxProperties}:'): + self.exc('{name} must contain less than or equal to {maxProperties} properties', rule='maxProperties') + + def generate_required(self): + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + if not isinstance(self._definition['required'], (list, tuple)): + raise JsonSchemaDefinitionException('required must be an array') + if len(self._definition['required']) != len(set(self._definition['required'])): + raise JsonSchemaDefinitionException('required must contain unique elements') + if not self._definition.get('additionalProperties', True): + not_possible = [ + prop + for prop in self._definition['required'] + if + prop not in self._definition.get('properties', {}) + and not any(re.search(regex, prop) for regex in self._definition.get('patternProperties', {})) + ] + if not_possible: + raise JsonSchemaDefinitionException('{}: items {} are required but not allowed'.format(self._variable, not_possible)) + self.l('{variable}__missing_keys = set({required}) - {variable}.keys()') + with self.l('if {variable}__missing_keys:'): + dynamic = 'str(sorted({variable}__missing_keys)) + " properties"' + self.exc('{name} must contain ', self.e(self._definition['required']), rule='required', append_to_msg=dynamic) + + def generate_properties(self): + """ + Means object with defined keys. + + .. code-block:: python + + { + 'properties': { + 'key': {'type': 'number'}, + }, + } + + Valid object is containing key called 'key' and value any number. + """ + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + self.create_variable_keys() + for key, prop_definition in self._definition['properties'].items(): + key_name = re.sub(r'($[^a-zA-Z]|[^a-zA-Z0-9])', '', key) + if not isinstance(prop_definition, (dict, bool)): + raise JsonSchemaDefinitionException('{}[{}] must be object'.format(self._variable, key_name)) + with self.l('if "{}" in {variable}_keys:', self.e(key)): + self.l('{variable}_keys.remove("{}")', self.e(key)) + self.l('{variable}__{0} = {variable}["{1}"]', key_name, self.e(key)) + self.generate_func_code_block( + prop_definition, + '{}__{}'.format(self._variable, key_name), + '{}.{}'.format(self._variable_name, self.e(key).replace('{', '{{').replace('}', '}}')), + clear_variables=True, + ) + if self._use_default and isinstance(prop_definition, dict) and 'default' in prop_definition: + self.l('else: {variable}["{}"] = {}', self.e(key), repr_default(prop_definition['default'])) + + def generate_pattern_properties(self): + """ + Means object with defined keys as patterns. + + .. code-block:: python + + { + 'patternProperties': { + '^x': {'type': 'number'}, + }, + } + + Valid object is containing key starting with a 'x' and value any number. + """ + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + self.create_variable_keys() + pattern_prop_definition = self._definition['patternProperties'] + if pattern_prop_definition == {}: + return + for pattern, definition in pattern_prop_definition.items(): + self._compile_regexps[pattern] = re.compile(pattern) + with self.l('for {variable}_key, {variable}_val in {variable}.items():'): + for pattern, definition in self._definition['patternProperties'].items(): + with self.l('if REGEX_PATTERNS[{}].search({variable}_key):', repr(pattern)): + with self.l('if {variable}_key in {variable}_keys:'): + self.l('{variable}_keys.remove({variable}_key)') + self.generate_func_code_block( + definition, + '{}_val'.format(self._variable), + '{}.{{{}_key}}'.format(self._variable_name, self._variable), + clear_variables=True, + ) + + def generate_additional_properties(self): + """ + Means object with keys with values defined by definition. + + .. code-block:: python + + { + 'properties': { + 'key': {'type': 'number'}, + } + 'additionalProperties': {'type': 'string'}, + } + + Valid object is containing key called 'key' and it's value any number and + any other key with any string. + """ + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + self.create_variable_keys() + add_prop_definition = self._definition["additionalProperties"] + if add_prop_definition is True or add_prop_definition == {}: + return + if add_prop_definition: + properties_keys = list(self._definition.get("properties", {}).keys()) + with self.l('for {variable}_key in {variable}_keys:'): + with self.l('if {variable}_key not in {}:', properties_keys): + self.l('{variable}_value = {variable}.get({variable}_key)') + self.generate_func_code_block( + add_prop_definition, + '{}_value'.format(self._variable), + '{}.{{{}_key}}'.format(self._variable_name, self._variable), + ) + else: + with self.l('if {variable}_keys:'): + self.exc('{name} must not contain "+str({variable}_keys)+" properties', rule='additionalProperties') + + def generate_dependencies(self): + """ + Means when object has property, it needs to have also other property. + + .. code-block:: python + + { + 'dependencies': { + 'bar': ['foo'], + }, + } + + Valid object is containing only foo, both bar and foo or none of them, but not + object with only bar. + + Since draft 06 definition can be boolean or empty array. True and empty array + means nothing, False means that key cannot be there at all. + """ + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + is_empty = True + for key, values in self._definition["dependencies"].items(): + if values == [] or values is True: + continue + is_empty = False + with self.l('if "{}" in {variable}:', self.e(key)): + if values is False: + self.exc('{} in {name} must not be there', self.e(key), rule='dependencies') + elif isinstance(values, list): + for value in values: + with self.l('if "{}" not in {variable}:', self.e(value)): + self.exc('{name} missing dependency {} for {}', self.e(value), self.e(key), rule='dependencies') + else: + code_len = len(self._code) + self.generate_func_code_block(values, self._variable, self._variable_name, clear_variables=True) + if len(self._code) == code_len: + self.l('pass') + if is_empty: + self.l('pass') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py new file mode 100644 index 00000000000..30eb517ad43 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py @@ -0,0 +1,222 @@ +import decimal +from .draft04 import CodeGeneratorDraft04, JSON_TYPE_TO_PYTHON_TYPE +from .exceptions import JsonSchemaDefinitionException +from .generator import VALIDATION_EXCEPTIONS, enforce_list + + +class CodeGeneratorDraft06(CodeGeneratorDraft04): + FORMAT_REGEXS = dict(CodeGeneratorDraft04.FORMAT_REGEXS, **{ + 'json-pointer': r'^(/(([^/~])|(~[01]))*)*\Z', + 'uri-reference': r'^(\w+:(\/?\/?))?[^#\\\s]*(#[^\\\s]*)?\Z', + 'uri-template': ( + r'^(?:(?:[^\x00-\x20\"\'<>%\\^`{|}]|%[0-9a-f]{2})|' + r'\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+' + r'(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+' + r'(?::[1-9][0-9]{0,3}|\*)?)*\})*\Z' + ), + }) + + def __init__( + self, + definition, + resolver=None, + formats={}, + use_default=True, + use_formats=True, + detailed_exceptions=True, + fast_fail=True, + ): + super().__init__(definition, resolver, formats, use_default, use_formats, detailed_exceptions, fast_fail) + self._json_keywords_to_function.update(( + ('exclusiveMinimum', self.generate_exclusive_minimum), + ('exclusiveMaximum', self.generate_exclusive_maximum), + ('propertyNames', self.generate_property_names), + ('contains', self.generate_contains), + ('const', self.generate_const), + )) + + def _generate_func_code_block(self, definition): + if isinstance(definition, bool): + return self.generate_boolean_schema() + elif '$ref' in definition: + # needed because ref overrides any sibling keywords + return self.generate_ref() + return self.run_generate_functions(definition) + + def generate_boolean_schema(self): + """ + Means that schema can be specified by boolean. + True means everything is valid, False everything is invalid. + """ + if self._definition is True: + self.l('pass') + if self._definition is False: + self.exc('{name} must not be there') + + def generate_type(self): + """ + Validation of type. Can be one type or list of types. + + Since draft 06 a float without fractional part is an integer. + + .. code-block:: python + + {'type': 'string'} + {'type': ['string', 'number']} + """ + types = enforce_list(self._definition['type']) + try: + python_types = ', '.join(JSON_TYPE_TO_PYTHON_TYPE[t] for t in types) + except KeyError as exc: + raise JsonSchemaDefinitionException('Unknown type') from exc + + extra = '' + + if 'integer' in types: + extra += ' and not (isinstance({variable}, float) and {variable}.is_integer())'.format( + variable=self._variable, + ) + + if ('number' in types or 'integer' in types) and 'boolean' not in types: + extra += ' or isinstance({variable}, bool)'.format(variable=self._variable) + + with self.l('if not isinstance({variable}, ({})){}:', python_types, extra): + self.exc('{name} must be {}', ' or '.join(types), rule='type') + + def generate_minimum(self): + """ + Since draft 06 exclusiveMinimum is a number validated on its own, + so minimum is always inclusive. + """ + with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): + if not isinstance(self._definition['minimum'], (int, float, decimal.Decimal)): + raise JsonSchemaDefinitionException('minimum must be a number') + with self.l('if {variable} < {minimum}:'): + self.exc('{name} must be bigger than or equal to {minimum}', rule='minimum') + + def generate_maximum(self): + """ + Since draft 06 exclusiveMaximum is a number validated on its own, + so maximum is always inclusive. + """ + with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): + if not isinstance(self._definition['maximum'], (int, float, decimal.Decimal)): + raise JsonSchemaDefinitionException('maximum must be a number') + with self.l('if {variable} > {maximum}:'): + self.exc('{name} must be smaller than or equal to {maximum}', rule='maximum') + + def generate_exclusive_minimum(self): + with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): + if not isinstance(self._definition['exclusiveMinimum'], (int, float, decimal.Decimal)): + raise JsonSchemaDefinitionException('exclusiveMinimum must be an integer, a float or a decimal') + with self.l('if {variable} <= {exclusiveMinimum}:'): + self.exc('{name} must be bigger than {exclusiveMinimum}', rule='exclusiveMinimum') + + def generate_exclusive_maximum(self): + with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): + if not isinstance(self._definition['exclusiveMaximum'], (int, float, decimal.Decimal)): + raise JsonSchemaDefinitionException('exclusiveMaximum must be an integer, a float or a decimal') + with self.l('if {variable} >= {exclusiveMaximum}:'): + self.exc('{name} must be smaller than {exclusiveMaximum}', rule='exclusiveMaximum') + + def generate_property_names(self): + """ + Means that keys of object must to follow this definition. + + .. code-block:: python + + { + 'propertyNames': { + 'maxLength': 3, + }, + } + + Valid keys of object for this definition are foo, bar, ... but not foobar for example. + """ + property_names_definition = self._definition.get('propertyNames', {}) + if property_names_definition is True: + pass + elif property_names_definition is False: + self.create_variable_is_dict() + with self.l('if {variable}_is_dict and {variable}:'): + self.exc('{name} must not be there', rule='propertyNames') + else: + self.create_variable_is_dict() + with self.l('if {variable}_is_dict:'): + self.create_variable_with_length() + with self.l('if {variable}_len != 0:'): + self.l('{variable}_property_names = True') + with self.l('for {variable}_key in {variable}:'): + with self.l('try:'): + code_len = len(self._code) + with self.trial_validation(): + self.generate_func_code_block( + property_names_definition, + '{}_key'.format(self._variable), + self._variable_name, + clear_variables=True, + ) + if len(self._code) == code_len: + self.l('pass') + with self.l('except {}:', VALIDATION_EXCEPTIONS): + self.l('{variable}_property_names = False') + with self.l('if not {variable}_property_names:'): + self.exc('{name} must be named by propertyName definition', rule='propertyNames') + + def generate_contains(self): + """ + Means that array must contain at least one defined item. + + .. code-block:: python + + { + 'contains': { + 'type': 'number', + }, + } + + Valid array is any with at least one number. + """ + self.create_variable_is_list() + with self.l('if {variable}_is_list:'): + contains_definition = self._definition['contains'] + + if contains_definition is False: + self.exc('{name} is always invalid', rule='contains') + elif contains_definition is True: + with self.l('if not {variable}:'): + self.exc('{name} must not be empty', rule='contains') + else: + self.l('{variable}_contains = False') + with self.l('for {variable}_key in {variable}:'): + with self.l('try:'): + with self.trial_validation(): + self.generate_func_code_block( + contains_definition, + '{}_key'.format(self._variable), + self._variable_name, + clear_variables=True, + ) + self.l('{variable}_contains = True') + self.l('break') + self.l('except {}: pass', VALIDATION_EXCEPTIONS) + + with self.l('if not {variable}_contains:'): + self.exc('{name} must contain one of contains definition', rule='contains') + + def generate_const(self): + """ + Means that value is valid when is equeal to const definition. + + .. code-block:: python + + { + 'const': 42, + } + + Only valid value is 42 in this example. + """ + const = self._definition['const'] + match = self._enum_value_matches(self._variable, const) + with self.l('if not ({}):', match): + self.exc('{name} must be same as const definition: {definition_rule}', rule='const') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py new file mode 100644 index 00000000000..86476e7cdb9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py @@ -0,0 +1,138 @@ +from .draft04 import DATE_REGEX +from .draft06 import CodeGeneratorDraft06 +from .generator import VALIDATION_EXCEPTIONS + + +class CodeGeneratorDraft07(CodeGeneratorDraft06): + FORMAT_REGEXS = dict(CodeGeneratorDraft06.FORMAT_REGEXS, **{ + 'date': r'^(?:' + DATE_REGEX + r')\Z', + 'iri': r'^\w+:(\/?\/?)[^\s]+\Z', + 'iri-reference': r'^(\w+:(\/?\/?))?[^#\\\s]*(#[^\\\s]*)?\Z', + 'idn-email': r'^[^@]+@[^@]+\.[^@]+\Z', + # pylint: disable=line-too-long + 'idn-hostname': r'^(?!-)(xn--)?[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.(?!-)(xn--)?([a-zA-Z0-9\-]{1,50}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,})$', + 'relative-json-pointer': r'^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)\Z', + #'regex': r'', + 'time': ( + r'^(?P[01]?\d|2[0-3]):(?P[0-5]?\d)' + r'(?::(?P[0-5]?\d|60)(?:\.(?P\d{1,6}))?' + r'([zZ]|[+-](?:[01]\d|2[0-3]):[0-5]\d)?)?\Z' + ), + }) + + def __init__( + self, + definition, + resolver=None, + formats={}, + use_default=True, + use_formats=True, + detailed_exceptions=True, + fast_fail=True + ): + super().__init__(definition, resolver, formats, use_default, use_formats, detailed_exceptions, fast_fail) + # pylint: disable=duplicate-code + self._json_keywords_to_function.update(( + ('if', self.generate_if_then_else), + ('contentEncoding', self.generate_content_encoding), + ('contentMediaType', self.generate_content_media_type), + )) + + def generate_if_then_else(self): + """ + Implementation of if-then-else. + + .. code-block:: python + + { + 'if': { + 'exclusiveMaximum': 0, + }, + 'then': { + 'minimum': -10, + }, + 'else': { + 'multipleOf': 2, + }, + } + + Valid values are any between -10 and 0 or any multiplication of two. + """ + with self.l('try:', optimize=False): + code_len = len(self._code) + with self.trial_validation(): + self.generate_func_code_block( + self._definition['if'], + self._variable, + self._variable_name, + clear_variables=True + ) + if len(self._code) == code_len: + self.l('pass') + with self.l('except {}:', VALIDATION_EXCEPTIONS): + if 'else' in self._definition: + code_len = len(self._code) + self.generate_func_code_block( + self._definition['else'], + self._variable, + self._variable_name, + clear_variables=True + ) + if len(self._code) == code_len: + self.l('pass') + else: + self.l('pass') + if 'then' in self._definition: + with self.l('else:'): + code_len = len(self._code) + self.generate_func_code_block( + self._definition['then'], + self._variable, + self._variable_name, + clear_variables=True + ) + if len(self._code) == code_len: + self.l('pass') + + def generate_content_encoding(self): + """ + Means decoding value when it's encoded by base64. + + .. code-block:: python + + { + 'contentEncoding': 'base64', + } + """ + if self._definition['contentEncoding'] == 'base64': + with self.l('if isinstance({variable}, str):'): + with self.l('try:'): + self.l('import base64') + self.l('{variable} = base64.b64decode({variable})') + with self.l('except Exception:'): + self.exc('{name} must be encoded by base64') + with self.l('if {variable} == "":'): + self.exc('contentEncoding must be base64') + + def generate_content_media_type(self): + """ + Means loading value when it's specified as JSON. + + .. code-block:: python + + { + 'contentMediaType': 'application/json', + } + """ + if self._definition['contentMediaType'] == 'application/json': + with self.l('if isinstance({variable}, bytes):'): + with self.l('try:'): + self.l('{variable} = {variable}.decode("utf-8")') + with self.l('except Exception:'): + self.exc('{name} must encoded by utf8') + with self.l('if isinstance({variable}, str):'): + with self.l('try:'): + self.l('import json') + self.l('{variable} = json.loads({variable})') + with self.l('except Exception:'): + self.exc('{name} must be valid JSON') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py new file mode 100644 index 00000000000..85c9c128dc2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py @@ -0,0 +1,15 @@ +from .draft07 import CodeGeneratorDraft07 + + +class CodeGeneratorDraft2019(CodeGeneratorDraft07): + FORMAT_REGEXS = dict(CodeGeneratorDraft07.FORMAT_REGEXS, **{ + 'uuid': r'^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\Z', + # ISO 8601 duration from RFC 3339 Appendix A + 'duration': ( + r'^P(?!$)' + r'(?:' + r'[0-9]+W' + r'|(?:[0-9]+Y)?(?:[0-9]+M)?(?:[0-9]+D)?(?:T(?=[0-9])(?:[0-9]+H)?(?:[0-9]+M)?(?:[0-9]+S)?)?' + r')\Z' + ), + }) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py new file mode 100644 index 00000000000..1d0d448566b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py @@ -0,0 +1,75 @@ +import re +from typing import Any + + +SPLIT_RE = re.compile(r'[\.\[\]]+') + + +class JsonSchemaException(ValueError): + """ + Base exception of ``fastjsonschema`` library. + """ + + +class JsonSchemaValueException(JsonSchemaException): + """ + Exception raised by validation function. Available properties: + + * ``message`` containing human-readable information what is wrong + (e.g. ``data.property[index] must be smaller than or equal to 42``), + * invalid ``value`` (e.g. ``60``), + * ``name`` of a path in the data structure (e.g. ``data.property[index]``), + * ``path`` as an array in the data structure (e.g. ``['data', 'property', 'index']``), + * the whole ``definition`` which the ``value`` has to fulfil (e.g. ``{'type': 'number', 'maximum': 42}``), + * ``rule`` which the ``value`` is breaking (e.g. ``maximum``) + * and ``rule_definition`` (e.g. ``42``). + + .. versionchanged:: 2.14.0 + Added all extra properties. + """ + + def __init__( + self, + message: str, + value: Any = None, + name: str | None = None, + definition: Any = None, + rule: str | None = None, + ) -> None: + super().__init__(message) + self.message = message + self.value = value + self.name = name + self.definition = definition + self.rule = rule + + @property + def path(self) -> list[str]: + return [item for item in SPLIT_RE.split(self.name or '') if item != ''] + + @property + def rule_definition(self) -> Any: + if not self.rule or not self.definition: + return None + return self.definition.get(self.rule) + + +class JsonSchemaValuesException(JsonSchemaException): + """ + Exception raised by validation function when ``fast_fail`` is turned off. + Available properties: + + * ``errors`` containing all :any:`JsonSchemaValueException` found in the data + * and ``message`` joining messages of all the errors. + """ + + def __init__(self, errors: list[JsonSchemaValueException]) -> None: + self.message = '; '.join(error.message for error in errors) + super().__init__(self.message) + self.errors = errors + + +class JsonSchemaDefinitionException(JsonSchemaException): + """ + Exception raised by generator of validation function. + """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py new file mode 100644 index 00000000000..951eddad485 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py @@ -0,0 +1,429 @@ +from collections import OrderedDict +from contextlib import contextmanager +from decimal import Decimal +import re + +from .exceptions import JsonSchemaValueException, JsonSchemaValuesException, JsonSchemaDefinitionException +from .indent import indent +from .ref_resolver import RefResolver + +# Both mean "this subschema did not match": a subschema behind a $ref becomes its own +# function, which reports through JsonSchemaValuesException while errors are collected. +VALIDATION_EXCEPTIONS = '(JsonSchemaValueException, JsonSchemaValuesException)' + + +def enforce_list(variable): + if isinstance(variable, list): + return variable + return [variable] + + +# pylint: disable=too-many-instance-attributes,too-many-public-methods +class CodeGenerator: + """ + This class is not supposed to be used directly. Anything + inside of this class can be changed without noticing. + + This class generates code of validation function from JSON + schema object as string. Example: + + .. code-block:: python + + CodeGenerator(json_schema_definition).func_code + """ + + INDENT = 4 # spaces + + def __init__(self, definition, resolver=None, detailed_exceptions=True, fast_fail=True): + self._code = [] + self._compile_regexps = {} + self._custom_formats = {} + self._detailed_exceptions = detailed_exceptions + self._fast_fail = fast_fail + + # Any extra library should be here to be imported only once. + # Lines are imports to be printed in the file and objects + # key-value pair to pass to compile function directly. + self._extra_imports_lines = [ + "from decimal import Decimal", + ] + self._extra_imports_objects = { + "Decimal": Decimal, + } + + self._variables = {} + self._scope_stack = [] + self._scope_counter = 0 + self._last_closed_scope = None + self._indent = 0 + self._indent_last_line = None + self._variable = None + self._variable_name = None + self._root_definition = definition + self._definition = None + + # map schema URIs to validation function names for functions + # that are not yet generated, but need to be generated + self._needed_validation_functions = {} + # validation function names that are already done + self._validation_functions_done = set() + + if resolver is None: + resolver = RefResolver.from_schema(definition, store={}) + self._resolver = resolver + + # add main function to `self._needed_validation_functions` + self._needed_validation_functions[self._resolver.get_uri()] = self._resolver.get_scope_name() + + self._json_keywords_to_function = OrderedDict() + + @property + def func_code(self): + """ + Returns generated code of whole validation function as string. + """ + self._generate_func_code() + + return '\n'.join(self._code) + + @property + def global_state(self): + """ + Returns global variables for generating function from ``func_code``. Includes + compiled regular expressions and imports, so it does not have to do it every + time when validation function is called. + """ + self._generate_func_code() + + return dict( + **self._extra_imports_objects, + REGEX_PATTERNS=self._compile_regexps, + re=re, + JsonSchemaValueException=JsonSchemaValueException, + JsonSchemaValuesException=JsonSchemaValuesException, + ) + + @property + def global_state_code(self): + """ + Returns global variables for generating function from ``func_code`` as code. + Includes compiled regular expressions and imports. + """ + self._generate_func_code() + + if not self._compile_regexps: + return '\n'.join(self._extra_imports_lines + [ + 'from fastjsonschema import JsonSchemaValueException, JsonSchemaValuesException', + '', + '', + ]) + return '\n'.join(self._extra_imports_lines + [ + 'import re', + 'from fastjsonschema import JsonSchemaValueException, JsonSchemaValuesException', + '', + '', + 'REGEX_PATTERNS = ' + serialize_regexes(self._compile_regexps), + '', + ]) + + + def _generate_func_code(self): + if not self._code: + self.generate_func_code() + + def generate_func_code(self): + """ + Creates base code of validation function and calls helper + for creating code by definition. + """ + self.l('NoneType = type(None)') + # Generate parts that are referenced and not yet generated + while self._needed_validation_functions: + # During generation of validation function, could be needed to generate + # new one that is added again to `_needed_validation_functions`. + # Therefore usage of while instead of for loop. + uri, name = self._needed_validation_functions.popitem() + self.generate_validation_function(uri, name) + + def generate_validation_function(self, uri, name): + """ + Generate validation function for given uri with given name + """ + self._validation_functions_done.add(uri) + self.l('') + with self._resolver.resolving(uri) as definition: + with self.l('def {}(data, custom_formats={{}}, name_prefix=None):', name): + if not self._fast_fail: + self.l('errors = []') + self.generate_func_code_block(definition, 'data', 'data', clear_variables=True) + if not self._fast_fail: + self.l('if errors: raise JsonSchemaValuesException(errors)') + self.l('return data') + + def generate_func_code_block(self, definition, variable, variable_name, clear_variables=False): + """ + Creates validation rules for current definition. + + Returns the number of validation rules generated as code. + """ + backup = self._definition, self._variable, self._variable_name + self._definition, self._variable, self._variable_name = definition, variable, variable_name + if clear_variables: + backup_variables = self._variables + self._variables = {} + + count = self._generate_func_code_block(definition) + + self._definition, self._variable, self._variable_name = backup + if clear_variables: + self._variables = backup_variables + + return count + + @contextmanager + def trial_validation(self): + """ + Subschemas of anyOf, oneOf, not, if, contains and propertyNames are only tried out. + Their failure is control flow for the surrounding ``try``, not an error to report, + so they have to raise even when ``fast_fail`` is off. + """ + fast_fail, self._fast_fail = self._fast_fail, True + try: + yield + finally: + self._fast_fail = fast_fail + + def _generate_func_code_block(self, definition): + if not isinstance(definition, dict): + raise JsonSchemaDefinitionException("definition must be an object") + if '$ref' in definition: + # needed because ref overrides any sibling keywords + return self.generate_ref() + return self.run_generate_functions(definition) + + def run_generate_functions(self, definition): + """Returns the number of generate functions that were executed.""" + count = 0 + for key, func in self._json_keywords_to_function.items(): + if key in definition: + func() + count += 1 + return count + + def generate_ref(self): + """ + Ref can be link to remote or local definition. + + .. code-block:: python + + {'$ref': 'http://json-schema.org/draft-04/schema#'} + { + 'properties': { + 'foo': {'type': 'integer'}, + 'bar': {'$ref': '#/properties/foo'} + } + } + """ + with self._resolver.in_scope(self._definition['$ref']): + name = self._resolver.get_scope_name() + uri = self._resolver.get_uri() + if uri not in self._validation_functions_done: + self._needed_validation_functions[uri] = name + # call validation function + assert self._variable_name.startswith("data") + path = self._variable_name[4:] + name_arg = '(name_prefix or "data") + "{}"'.format(path) + if '{' in name_arg or '}' in name_arg: + name_arg = name_arg + '.format(**locals())' + if self._fast_fail: + self.l('{}({variable}, custom_formats, {name_arg})', name, name_arg=name_arg) + else: + # The referenced function collects into its own list, so merge it into ours + # instead of letting it abort the validation of the rest of the document. + with self.l('try:', optimize=False): + self.l('{}({variable}, custom_formats, {name_arg})', name, name_arg=name_arg) + with self.l('except JsonSchemaValuesException as e:'): + self.l('errors.extend(e.errors)') + + + # pylint: disable=invalid-name + @indent + def l(self, line, *args, **kwds): + """ + Short-cut of line. Used for inserting line. It's formated with parameters + ``variable``, ``variable_name`` (as ``name`` for short-cut), all keys from + current JSON schema ``definition`` and also passed arguments in ``args`` + and named ``kwds``. + + .. code-block:: python + + self.l('if {variable} not in {enum}: raise JsonSchemaValueException("Wrong!")') + + When you want to indent block, use it as context manager. For example: + + .. code-block:: python + + with self.l('if {variable} not in {enum}:'): + self.l('raise JsonSchemaValueException("Wrong!")') + """ + spaces = ' ' * self.INDENT * self._indent + + name = self._variable_name + if name: + # Add name_prefix to the name when it is being outputted. + assert name.startswith('data') + name = '" + (name_prefix or "data") + "' + name[4:] + if '{' in name or '}' in name: + name = name + '".format(**locals()) + "' + + context = dict( + self._definition if self._definition and self._definition is not True else {}, + variable=self._variable, + name=name, + **kwds + ) + line = line.format(*args, **context) + line = line.replace('\n', '\\n').replace('\r', '\\r') + self._code.append(spaces + line) + return line + + def e(self, string): + """ + Short-cut of escape. Used for inserting user values into a string message. + + .. code-block:: python + + self.l('raise JsonSchemaValueException("Variable: {}")', self.e(variable)) + """ + if isinstance(string, str): + return string.encode('unicode_escape').decode('ascii').replace('"', '\\"') + return str(string).replace('"', '\\"') + + def exc(self, msg, *args, append_to_msg=None, rule=None): + """ + Short-cut for creating raising exception in the code. + """ + if not self._detailed_exceptions: + if self._fast_fail: + self.l('raise JsonSchemaValueException("'+msg+'")', *args) + else: + self.l('errors.append(JsonSchemaValueException("'+msg+'"))', *args) + return + + arg = '"'+msg+'"' + if append_to_msg: + arg += ' + (' + append_to_msg + ')' + # pylint: disable=line-too-long + msg = ( + 'raise JsonSchemaValueException('+arg+', value={variable}, name="{name}", definition={definition}, rule={rule})' + if self._fast_fail else + 'errors.append(JsonSchemaValueException('+arg+', value={variable}, name="{name}", definition={definition}, rule={rule}))' + ) + definition = self._expand_refs(self._definition) + definition_rule = self.e(definition.get(rule) if isinstance(definition, dict) else None) + self.l(msg, *args, definition=repr_default(definition), rule=repr(rule), definition_rule=definition_rule) + + def _expand_refs(self, definition): + if isinstance(definition, list): + return [self._expand_refs(v) for v in definition] + if not isinstance(definition, dict): + return definition + if "$ref" in definition and isinstance(definition["$ref"], str): + with self._resolver.resolving(definition["$ref"]) as schema: + return schema + return {k: self._expand_refs(v) for k, v in definition.items()} + + def _is_variable_in_scope(self, variable_name): + """ + Whether ``variable_name`` was already defined in a block enclosing the + current one, and is therefore still bound here. A variable defined in a + sibling block is not, because that block may not have been entered. + """ + scope = self._variables.get(variable_name) + if scope is None: + return False + return tuple(self._scope_stack[:len(scope)]) == scope + + def create_variable_with_length(self): + """ + Append code for creating variable with length of that variable + (for example length of list or dictionary) with name ``{variable}_len``. + It can be called several times and always it's done only when that variable + still does not exists. + """ + variable_name = '{}_len'.format(self._variable) + if self._is_variable_in_scope(variable_name): + return + self._variables[variable_name] = tuple(self._scope_stack) + self.l('{variable}_len = len({variable})') + + def create_variable_keys(self): + """ + Append code for creating variable with keys of that variable (dictionary) + with a name ``{variable}_keys``. Similar to `create_variable_with_length`. + """ + variable_name = '{}_keys'.format(self._variable) + if self._is_variable_in_scope(variable_name): + return + self._variables[variable_name] = tuple(self._scope_stack) + self.l('{variable}_keys = set({variable}.keys())') + + def create_variable_is_list(self): + """ + Append code for creating variable with bool if it's instance of list + with a name ``{variable}_is_list``. Similar to `create_variable_with_length`. + """ + variable_name = '{}_is_list'.format(self._variable) + if self._is_variable_in_scope(variable_name): + return + self._variables[variable_name] = tuple(self._scope_stack) + self.l('{variable}_is_list = isinstance({variable}, (list, tuple))') + + def create_variable_is_dict(self): + """ + Append code for creating variable with bool if it's instance of list + with a name ``{variable}_is_dict``. Similar to `create_variable_with_length`. + """ + variable_name = '{}_is_dict'.format(self._variable) + if self._is_variable_in_scope(variable_name): + return + self._variables[variable_name] = tuple(self._scope_stack) + self.l('{variable}_is_dict = isinstance({variable}, dict)') + + +def serialize_regexes(patterns_dict): + # Unfortunately using `pprint.pformat` is causing errors + # specially with big regexes + regex_patterns = ( + repr(k) + ": " + repr_regex(v) + for k, v in patterns_dict.items() + ) + return '{\n ' + ",\n ".join(regex_patterns) + "\n}" + + +def repr_default(value): + """ + Like ``repr``, but renders non-finite floats as valid Python source. + + ``repr(float('nan'))`` is ``'nan'``, which is not a name available in the + generated code, so a schema default of NaN or infinity has to be written + out as a ``float(...)`` call instead. + """ + if isinstance(value, float) and (value != value or value in (float('inf'), float('-inf'))): + return "float({!r})".format(str(value)) + if isinstance(value, list): + return '[' + ', '.join(repr_default(item) for item in value) + ']' + if isinstance(value, tuple): + return '(' + ''.join(repr_default(item) + ', ' for item in value) + ')' + if isinstance(value, dict): + return '{' + ', '.join( + '{}: {}'.format(repr_default(k), repr_default(v)) for k, v in value.items() + ) + '}' + return repr(value) + + +def repr_regex(regex): + all_flags = ("A", "I", "DEBUG", "L", "M", "S", "X") + flags = " | ".join(f"re.{f}" for f in all_flags if regex.flags & getattr(re, f)) + flags = ", " + flags if flags else "" + return "re.compile({!r}{})".format(regex.pattern, flags) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py new file mode 100644 index 00000000000..9cc011aa805 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py @@ -0,0 +1,42 @@ +# pylint: disable=protected-access + +def indent(func): + """ + Decorator for allowing to use method as normal method or with + context manager for auto-indenting code blocks. + """ + def wrapper(self, line, *args, optimize=True, **kwds): + last_line = self._indent_last_line + line = func(self, line, *args, **kwds) + # When two blocks have the same condition (such as value has to be dict), + # do the check only once and keep it under one block. + merged = optimize and last_line == line + if merged: + self._code.pop() + self._indent_last_line = line + return Indent(self, line, merged=merged) + return wrapper + + +class Indent: + def __init__(self, instance, line, merged=False): + self.instance = instance + self.line = line + self.merged = merged + + def __enter__(self): + self.instance._indent += 1 + # A merged block is a continuation of the block just closed, so it keeps + # its scope; otherwise this is a new scope and variables defined in it + # are not visible to sibling blocks. + if self.merged and self.instance._last_closed_scope is not None: + scope = self.instance._last_closed_scope + else: + self.instance._scope_counter += 1 + scope = self.instance._scope_counter + self.instance._scope_stack.append(scope) + + def __exit__(self, type_, value, traceback): + self.instance._indent -= 1 + self.instance._last_closed_scope = self.instance._scope_stack.pop() + self.instance._indent_last_line = self.line diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py new file mode 100644 index 00000000000..67fcbdd541d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py @@ -0,0 +1,219 @@ +# pylint: disable=import-outside-toplevel + +""" +JSON Schema URI resolution scopes and dereferencing + +https://tools.ietf.org/id/draft-zyp-json-schema-04.html#rfc.section.7 + +Code adapted from https://github.com/Julian/jsonschema +""" + +import contextlib +import json +import re +import sys +from collections.abc import Callable, Iterator, Mapping +from typing import Any +from urllib import parse as urlparse +from urllib.parse import unquote + +from .exceptions import JsonSchemaDefinitionException + +MAX_SCHEMA_WALK_DEPTH = min(500, sys.getrecursionlimit() // 2) + + +def get_id(schema: dict[str, Any]) -> str: + """ + Originally ID was `id` and since v7 it's `$id`. + """ + return schema.get('$id', schema.get('id', '')) + + +def resolve_path(schema: Any, fragment: str) -> Any: + """ + Return definition from path. + + Path is unescaped according https://tools.ietf.org/html/rfc6901 + """ + fragment = fragment.lstrip('/') + parts = unquote(fragment).split('/') if fragment else [] + for part in parts: + part = part.replace('~1', '/').replace('~0', '~') + if isinstance(schema, list): + schema = schema[int(part)] + elif part in schema: + schema = schema[part] + else: + raise JsonSchemaDefinitionException('Unresolvable ref: {}'.format(part)) + return schema + + +def normalize(uri: str) -> str: + return urlparse.urlsplit(uri).geturl() + + +def resolve_remote(uri: str, handlers: Mapping[str, Callable[[str], Any]]) -> Any: + """ + Resolve a remote ``uri``. + + .. note:: + + urllib library is used to fetch requests from the remote ``uri`` + if handlers does notdefine otherwise. + """ + scheme = urlparse.urlsplit(uri).scheme + if scheme in handlers: + result = handlers[scheme](uri) + else: + from urllib.request import urlopen + + with urlopen(uri) as response: + encoding = response.info().get_content_charset() or 'utf-8' + try: + result = json.loads(response.read().decode(encoding),) + except ValueError as exc: + raise JsonSchemaDefinitionException('{} failed to decode'.format(uri)) from exc + return result + + +class RefResolver: + """ + Resolve JSON References. + """ + + # pylint: disable=dangerous-default-value,too-many-arguments + def __init__( + self, + base_uri: str, + schema: dict[str, Any] | bool, + store: dict[str, Any] = {}, + cache: bool = True, + handlers: Mapping[str, Callable[[str], Any]] = {}, + ) -> None: + """ + `base_uri` is URI of the referring document from the `schema`. + `store` is an dictionary that will be used to cache the fetched schemas + (if `cache=True`). + + Please notice that you can have caching problems when compiling schemas + with colliding `$ref`. To force overwriting use `cache=False` or + explicitly pass the `store` argument (with a brand new dictionary) + """ + self.base_uri = base_uri + self.resolution_scope = base_uri + self.schema = schema + self.store = store + self.cache = cache + self.handlers = handlers + self._walked_uris: set[str] = set() + self.walk(schema) + self._walked_uris.add(normalize(base_uri) if base_uri else '') + + @classmethod + def from_schema( + cls, + schema: dict[str, Any] | bool, + handlers: Mapping[str, Callable[[str], Any]] = {}, + **kwargs: Any, + ) -> 'RefResolver': + """ + Construct a resolver from a JSON schema object. + """ + return cls( + get_id(schema) if isinstance(schema, dict) else '', + schema, + handlers=handlers, + **kwargs + ) + + @contextlib.contextmanager + def in_scope(self, scope: str) -> Iterator[None]: + """ + Context manager to handle current scope. + """ + old_scope = self.resolution_scope + self.resolution_scope = urlparse.urljoin(old_scope, scope) + try: + yield + finally: + self.resolution_scope = old_scope + + @contextlib.contextmanager + def resolving(self, ref: str) -> Iterator[Any]: + """ + Context manager which resolves a JSON ``ref`` and enters the + resolution scope of this ref. + """ + new_uri = urlparse.urljoin(self.resolution_scope, ref) + uri, fragment = urlparse.urldefrag(new_uri) + + document_uri = uri or self.base_uri + + if uri and normalize(uri) in self.store: + schema = self.store[normalize(uri)] + elif not uri or uri == self.base_uri: + schema = self.schema + else: + schema = resolve_remote(uri, self.handlers) + if self.cache: + self.store[normalize(uri)] = schema + + old_base_uri, old_schema = self.base_uri, self.schema + self.base_uri, self.schema = document_uri, schema + try: + with self.in_scope(document_uri): + self._ensure_walked(document_uri, schema) + if fragment and not fragment.startswith('/'): + plain_name = normalize(urlparse.urljoin(document_uri, '#' + fragment)) + if plain_name in self.store: + yield self.store[plain_name] + return + raise JsonSchemaDefinitionException('Unresolvable ref: {}'.format(fragment)) + yield resolve_path(schema, fragment) + finally: + self.base_uri, self.schema = old_base_uri, old_schema + + def _ensure_walked(self, uri: str, schema: Any) -> None: + normalized = normalize(uri) if uri else '' + if normalized in self._walked_uris: + return + self.walk(schema, rewrite_refs=False) + self._walked_uris.add(normalized) + + def get_uri(self) -> str: + return normalize(self.resolution_scope) + + def get_scope_name(self) -> str: + """ + Get current scope and return it as a valid function name. + """ + name = 'validate_' + unquote(self.resolution_scope).replace('~1', '_').replace('~0', '_').replace('"', '') + name = re.sub(r'($[^a-zA-Z]|[^a-zA-Z0-9])', '_', name) + name = name.lower().rstrip('_') + return name + + def walk(self, node: dict[str, Any] | bool, depth: int = 0, rewrite_refs: bool = True) -> None: + """ + Walk thru schema and dereferencing ``id`` and ``$ref`` instances + """ + if depth >= MAX_SCHEMA_WALK_DEPTH: + raise JsonSchemaDefinitionException( + 'Schema is too deeply nested (maximum depth is {})'.format(MAX_SCHEMA_WALK_DEPTH) + ) + + if isinstance(node, bool): + pass + elif '$ref' in node and isinstance(node['$ref'], str): + if rewrite_refs: + ref = node['$ref'] + node['$ref'] = urlparse.urljoin(self.resolution_scope, ref) + elif ('$id' in node or 'id' in node) and isinstance(get_id(node), str): + with self.in_scope(get_id(node)): + self.store[normalize(self.resolution_scope)] = node + for _, item in node.items(): + if isinstance(item, dict): + self.walk(item, depth + 1, rewrite_refs) + else: + for _, item in node.items(): + if isinstance(item, dict): + self.walk(item, depth + 1, rewrite_refs) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py new file mode 100644 index 00000000000..9cb373a2fc9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py @@ -0,0 +1 @@ +VERSION = '2.22.3' diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto new file mode 100644 index 00000000000..417edd8fa19 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py new file mode 100644 index 00000000000..615b761fbf2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/annotations.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/annotations.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +from opentelemetry.agent._vendor.google.api import http_pb2 as google_dot_api_dot_http__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1cgoogle/api/annotations.proto\x12\ngoogle.api\x1a\x15google/api/http.proto\x1a google/protobuf/descriptor.proto:E\n\x04http\x12\x1e.google.protobuf.MethodOptions\x18\xb0\xca\xbc" \x01(\x0b\x32\x14.google.api.HttpRuleBn\n\x0e\x63om.google.apiB\x10\x41nnotationsProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.annotations_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\020AnnotationsProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi new file mode 100644 index 00000000000..4c4afeb9545 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi @@ -0,0 +1,24 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 + +from google.api import http_pb2 as _http_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor +HTTP_FIELD_NUMBER: _ClassVar[int] +http: _descriptor.FieldDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto new file mode 100644 index 00000000000..9b025bac156 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto @@ -0,0 +1,238 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "AuthProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Authentication` defines the authentication configuration for API methods +// provided by an API service. +// +// Example: +// +// name: calendar.googleapis.com +// authentication: +// providers: +// - id: google_calendar_auth +// jwks_uri: https://www.googleapis.com/oauth2/v1/certs +// issuer: https://securetoken.google.com +// rules: +// - selector: "*" +// requirements: +// provider_id: google_calendar_auth +// - selector: google.calendar.Delegate +// oauth: +// canonical_scopes: https://www.googleapis.com/auth/calendar.read +message Authentication { + // A list of authentication rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated AuthenticationRule rules = 3; + + // Defines a set of authentication providers that a service supports. + repeated AuthProvider providers = 4; +} + +// Authentication rules for the service. +// +// By default, if a method has any authentication requirements, every request +// must include a valid credential matching one of the requirements. +// It's an error to include more than one kind of credential in a single +// request. +// +// If a method doesn't have any auth requirements, request credentials will be +// ignored. +message AuthenticationRule { + // Selects the methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // The requirements for OAuth credentials. + OAuthRequirements oauth = 2; + + // If true, the service accepts API keys without any other credential. + // This flag only applies to HTTP and gRPC requests. + bool allow_without_credential = 5; + + // Requirements for additional authentication providers. + repeated AuthRequirement requirements = 7; +} + +// Specifies a location to extract JWT from an API request. +message JwtLocation { + oneof in { + // Specifies HTTP header name to extract JWT token. + string header = 1; + + // Specifies URL query parameter name to extract JWT token. + string query = 2; + + // Specifies cookie name to extract JWT token. + string cookie = 4; + } + + // The value prefix. The value format is "value_prefix{token}" + // Only applies to "in" header type. Must be empty for "in" query type. + // If not empty, the header value has to match (case sensitive) this prefix. + // If not matched, JWT will not be extracted. If matched, JWT will be + // extracted after the prefix is removed. + // + // For example, for "Authorization: Bearer {JWT}", + // value_prefix="Bearer " with a space at the end. + string value_prefix = 3; +} + +// Configuration for an authentication provider, including support for +// [JSON Web Token +// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32). +message AuthProvider { + // The unique identifier of the auth provider. It will be referred to by + // `AuthRequirement.provider_id`. + // + // Example: "bookstore_auth". + string id = 1; + + // Identifies the principal that issued the JWT. See + // https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.1 + // Usually a URL or an email address. + // + // Example: https://securetoken.google.com + // Example: 1234567-compute@developer.gserviceaccount.com + string issuer = 2; + + // URL of the provider's public key set to validate signature of the JWT. See + // [OpenID + // Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). + // Optional if the key set document: + // - can be retrieved from + // [OpenID + // Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) + // of the issuer. + // - can be inferred from the email domain of the issuer (e.g. a Google + // service account). + // + // Example: https://www.googleapis.com/oauth2/v1/certs + string jwks_uri = 3; + + // The list of JWT + // [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). + // that are allowed to access. A JWT containing any of these audiences will + // be accepted. When this setting is absent, JWTs with audiences: + // - "https://[service.name]/[google.protobuf.Api.name]" + // - "https://[service.name]/" + // will be accepted. + // For example, if no audiences are in the setting, LibraryService API will + // accept JWTs with the following audiences: + // - + // https://library-example.googleapis.com/google.example.library.v1.LibraryService + // - https://library-example.googleapis.com/ + // + // Example: + // + // audiences: bookstore_android.apps.googleusercontent.com, + // bookstore_web.apps.googleusercontent.com + string audiences = 4; + + // Redirect URL if JWT token is required but not present or is expired. + // Implement authorizationUrl of securityDefinitions in OpenAPI spec. + string authorization_url = 5; + + // Defines the locations to extract the JWT. For now it is only used by the + // Cloud Endpoints to store the OpenAPI extension [x-google-jwt-locations] + // (https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#x-google-jwt-locations) + // + // JWT locations can be one of HTTP headers, URL query parameters or + // cookies. The rule is that the first match wins. + // + // If not specified, default to use following 3 locations: + // 1) Authorization: Bearer + // 2) x-goog-iap-jwt-assertion + // 3) access_token query parameter + // + // Default locations can be specified as followings: + // jwt_locations: + // - header: Authorization + // value_prefix: "Bearer " + // - header: x-goog-iap-jwt-assertion + // - query: access_token + repeated JwtLocation jwt_locations = 6; +} + +// OAuth scopes are a way to define data and permissions on data. For example, +// there are scopes defined for "Read-only access to Google Calendar" and +// "Access to Cloud Platform". Users can consent to a scope for an application, +// giving it permission to access that data on their behalf. +// +// OAuth scope specifications should be fairly coarse grained; a user will need +// to see and understand the text description of what your scope means. +// +// In most cases: use one or at most two OAuth scopes for an entire family of +// products. If your product has multiple APIs, you should probably be sharing +// the OAuth scope across all of those APIs. +// +// When you need finer grained OAuth consent screens: talk with your product +// management about how developers will use them in practice. +// +// Please note that even though each of the canonical scopes is enough for a +// request to be accepted and passed to the backend, a request can still fail +// due to the backend requiring additional scopes or permissions. +message OAuthRequirements { + // The list of publicly documented OAuth scopes that are allowed access. An + // OAuth token containing any of these scopes will be accepted. + // + // + // Example: + // + // canonical_scopes: https://www.googleapis.com/auth/calendar, + // https://www.googleapis.com/auth/calendar.read + string canonical_scopes = 1; +} + +// User-defined authentication requirements, including support for +// [JSON Web Token +// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32). +message AuthRequirement { + // [id][google.api.AuthProvider.id] from authentication provider. + // + // Example: + // + // provider_id: bookstore_auth + string provider_id = 1; + + // NOTE: This will be deprecated soon, once AuthProvider.audiences is + // implemented and accepted in all the runtime components. + // + // The list of JWT + // [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). + // that are allowed to access. A JWT containing any of these audiences will + // be accepted. When this setting is absent, only JWTs with audience + // "https://[Service_name][google.api.Service.name]/[API_name][google.protobuf.Api.name]" + // will be accepted. For example, if no audiences are in the setting, + // LibraryService API will only accept JWTs with the following audience + // "https://library-example.googleapis.com/google.example.library.v1.LibraryService". + // + // Example: + // + // audiences: bookstore_android.apps.googleusercontent.com, + // bookstore_web.apps.googleusercontent.com + string audiences = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py new file mode 100644 index 00000000000..c183866907c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/auth.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/auth.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x15google/api/auth.proto\x12\ngoogle.api"l\n\x0e\x41uthentication\x12-\n\x05rules\x18\x03 \x03(\x0b\x32\x1e.google.api.AuthenticationRule\x12+\n\tproviders\x18\x04 \x03(\x0b\x32\x18.google.api.AuthProvider"\xa9\x01\n\x12\x41uthenticationRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12,\n\x05oauth\x18\x02 \x01(\x0b\x32\x1d.google.api.OAuthRequirements\x12 \n\x18\x61llow_without_credential\x18\x05 \x01(\x08\x12\x31\n\x0crequirements\x18\x07 \x03(\x0b\x32\x1b.google.api.AuthRequirement"^\n\x0bJwtLocation\x12\x10\n\x06header\x18\x01 \x01(\tH\x00\x12\x0f\n\x05query\x18\x02 \x01(\tH\x00\x12\x10\n\x06\x63ookie\x18\x04 \x01(\tH\x00\x12\x14\n\x0cvalue_prefix\x18\x03 \x01(\tB\x04\n\x02in"\x9a\x01\n\x0c\x41uthProvider\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06issuer\x18\x02 \x01(\t\x12\x10\n\x08jwks_uri\x18\x03 \x01(\t\x12\x11\n\taudiences\x18\x04 \x01(\t\x12\x19\n\x11\x61uthorization_url\x18\x05 \x01(\t\x12.\n\rjwt_locations\x18\x06 \x03(\x0b\x32\x17.google.api.JwtLocation"-\n\x11OAuthRequirements\x12\x18\n\x10\x63\x61nonical_scopes\x18\x01 \x01(\t"9\n\x0f\x41uthRequirement\x12\x13\n\x0bprovider_id\x18\x01 \x01(\t\x12\x11\n\taudiences\x18\x02 \x01(\tBk\n\x0e\x63om.google.apiB\tAuthProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.auth_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\tAuthProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_AUTHENTICATION"]._serialized_start = 37 + _globals["_AUTHENTICATION"]._serialized_end = 145 + _globals["_AUTHENTICATIONRULE"]._serialized_start = 148 + _globals["_AUTHENTICATIONRULE"]._serialized_end = 317 + _globals["_JWTLOCATION"]._serialized_start = 319 + _globals["_JWTLOCATION"]._serialized_end = 413 + _globals["_AUTHPROVIDER"]._serialized_start = 416 + _globals["_AUTHPROVIDER"]._serialized_end = 570 + _globals["_OAUTHREQUIREMENTS"]._serialized_start = 572 + _globals["_OAUTHREQUIREMENTS"]._serialized_end = 617 + _globals["_AUTHREQUIREMENT"]._serialized_start = 619 + _globals["_AUTHREQUIREMENT"]._serialized_end = 676 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi new file mode 100644 index 00000000000..421473a3972 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi @@ -0,0 +1,120 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Authentication(_message.Message): + __slots__ = ("rules", "providers") + RULES_FIELD_NUMBER: _ClassVar[int] + PROVIDERS_FIELD_NUMBER: _ClassVar[int] + rules: _containers.RepeatedCompositeFieldContainer[AuthenticationRule] + providers: _containers.RepeatedCompositeFieldContainer[AuthProvider] + def __init__( + self, + rules: _Optional[_Iterable[_Union[AuthenticationRule, _Mapping]]] = ..., + providers: _Optional[_Iterable[_Union[AuthProvider, _Mapping]]] = ..., + ) -> None: ... + +class AuthenticationRule(_message.Message): + __slots__ = ("selector", "oauth", "allow_without_credential", "requirements") + SELECTOR_FIELD_NUMBER: _ClassVar[int] + OAUTH_FIELD_NUMBER: _ClassVar[int] + ALLOW_WITHOUT_CREDENTIAL_FIELD_NUMBER: _ClassVar[int] + REQUIREMENTS_FIELD_NUMBER: _ClassVar[int] + selector: str + oauth: OAuthRequirements + allow_without_credential: bool + requirements: _containers.RepeatedCompositeFieldContainer[AuthRequirement] + def __init__( + self, + selector: _Optional[str] = ..., + oauth: _Optional[_Union[OAuthRequirements, _Mapping]] = ..., + allow_without_credential: _Optional[bool] = ..., + requirements: _Optional[_Iterable[_Union[AuthRequirement, _Mapping]]] = ..., + ) -> None: ... + +class JwtLocation(_message.Message): + __slots__ = ("header", "query", "cookie", "value_prefix") + HEADER_FIELD_NUMBER: _ClassVar[int] + QUERY_FIELD_NUMBER: _ClassVar[int] + COOKIE_FIELD_NUMBER: _ClassVar[int] + VALUE_PREFIX_FIELD_NUMBER: _ClassVar[int] + header: str + query: str + cookie: str + value_prefix: str + def __init__( + self, + header: _Optional[str] = ..., + query: _Optional[str] = ..., + cookie: _Optional[str] = ..., + value_prefix: _Optional[str] = ..., + ) -> None: ... + +class AuthProvider(_message.Message): + __slots__ = ( + "id", + "issuer", + "jwks_uri", + "audiences", + "authorization_url", + "jwt_locations", + ) + ID_FIELD_NUMBER: _ClassVar[int] + ISSUER_FIELD_NUMBER: _ClassVar[int] + JWKS_URI_FIELD_NUMBER: _ClassVar[int] + AUDIENCES_FIELD_NUMBER: _ClassVar[int] + AUTHORIZATION_URL_FIELD_NUMBER: _ClassVar[int] + JWT_LOCATIONS_FIELD_NUMBER: _ClassVar[int] + id: str + issuer: str + jwks_uri: str + audiences: str + authorization_url: str + jwt_locations: _containers.RepeatedCompositeFieldContainer[JwtLocation] + def __init__( + self, + id: _Optional[str] = ..., + issuer: _Optional[str] = ..., + jwks_uri: _Optional[str] = ..., + audiences: _Optional[str] = ..., + authorization_url: _Optional[str] = ..., + jwt_locations: _Optional[_Iterable[_Union[JwtLocation, _Mapping]]] = ..., + ) -> None: ... + +class OAuthRequirements(_message.Message): + __slots__ = ("canonical_scopes",) + CANONICAL_SCOPES_FIELD_NUMBER: _ClassVar[int] + canonical_scopes: str + def __init__(self, canonical_scopes: _Optional[str] = ...) -> None: ... + +class AuthRequirement(_message.Message): + __slots__ = ("provider_id", "audiences") + PROVIDER_ID_FIELD_NUMBER: _ClassVar[int] + AUDIENCES_FIELD_NUMBER: _ClassVar[int] + provider_id: str + audiences: str + def __init__( + self, provider_id: _Optional[str] = ..., audiences: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto new file mode 100644 index 00000000000..7bff445a341 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto @@ -0,0 +1,196 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "BackendProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Backend` defines the backend configuration for a service. +message Backend { + // A list of API backend rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated BackendRule rules = 1; +} + +// A backend rule provides configuration for an individual API element. +message BackendRule { + // Path Translation specifies how to combine the backend address with the + // request path in order to produce the appropriate forwarding URL for the + // request. + // + // Path Translation is applicable only to HTTP-based backends. Backends which + // do not accept requests over HTTP/HTTPS should leave `path_translation` + // unspecified. + enum PathTranslation { + PATH_TRANSLATION_UNSPECIFIED = 0; + + // Use the backend address as-is, with no modification to the path. If the + // URL pattern contains variables, the variable names and values will be + // appended to the query string. If a query string parameter and a URL + // pattern variable have the same name, this may result in duplicate keys in + // the query string. + // + // # Examples + // + // Given the following operation config: + // + // Method path: /api/company/{cid}/user/{uid} + // Backend address: https://example.cloudfunctions.net/getUser + // + // Requests to the following request paths will call the backend at the + // translated path: + // + // Request path: /api/company/widgetworks/user/johndoe + // Translated: + // https://example.cloudfunctions.net/getUser?cid=widgetworks&uid=johndoe + // + // Request path: /api/company/widgetworks/user/johndoe?timezone=EST + // Translated: + // https://example.cloudfunctions.net/getUser?timezone=EST&cid=widgetworks&uid=johndoe + CONSTANT_ADDRESS = 1; + + // The request path will be appended to the backend address. + // + // # Examples + // + // Given the following operation config: + // + // Method path: /api/company/{cid}/user/{uid} + // Backend address: https://example.appspot.com + // + // Requests to the following request paths will call the backend at the + // translated path: + // + // Request path: /api/company/widgetworks/user/johndoe + // Translated: + // https://example.appspot.com/api/company/widgetworks/user/johndoe + // + // Request path: /api/company/widgetworks/user/johndoe?timezone=EST + // Translated: + // https://example.appspot.com/api/company/widgetworks/user/johndoe?timezone=EST + APPEND_PATH_TO_ADDRESS = 2; + } + + // Selects the methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // The address of the API backend. + // + // The scheme is used to determine the backend protocol and security. + // The following schemes are accepted: + // + // SCHEME PROTOCOL SECURITY + // http:// HTTP None + // https:// HTTP TLS + // grpc:// gRPC None + // grpcs:// gRPC TLS + // + // It is recommended to explicitly include a scheme. Leaving out the scheme + // may cause constrasting behaviors across platforms. + // + // If the port is unspecified, the default is: + // - 80 for schemes without TLS + // - 443 for schemes with TLS + // + // For HTTP backends, use [protocol][google.api.BackendRule.protocol] + // to specify the protocol version. + string address = 2; + + // The number of seconds to wait for a response from a request. The default + // varies based on the request protocol and deployment environment. + double deadline = 3; + + // Deprecated, do not use. + double min_deadline = 4 [deprecated = true]; + + // The number of seconds to wait for the completion of a long running + // operation. The default is no deadline. + double operation_deadline = 5; + + // Path translation specifies how to combine the backend address with the + // request path in order to produce the appropriate forwarding URL for the + // request. See [PathTranslation][google.api.BackendRule.PathTranslation] for + // more details. + PathTranslation path_translation = 6; + + // Authentication settings used by the backend. + // + // These are typically used to provide service management functionality to + // a backend served on a publicly-routable URL. The `authentication` + // details should match the authentication behavior used by the backend. + // + // For example, specifying `jwt_audience` implies that the backend expects + // authentication via a JWT. + // + // When authentication is unspecified, the resulting behavior is the same + // as `disable_auth` set to `true`. + // + // Refer to https://developers.google.com/identity/protocols/OpenIDConnect for + // JWT ID token. + oneof authentication { + // The JWT audience is used when generating a JWT ID token for the backend. + // This ID token will be added in the HTTP "authorization" header, and sent + // to the backend. + string jwt_audience = 7; + + // When disable_auth is true, a JWT ID token won't be generated and the + // original "Authorization" HTTP header will be preserved. If the header is + // used to carry the original token and is expected by the backend, this + // field must be set to true to preserve the header. + bool disable_auth = 8; + } + + // The protocol used for sending a request to the backend. + // The supported values are "http/1.1" and "h2". + // + // The default value is inferred from the scheme in the + // [address][google.api.BackendRule.address] field: + // + // SCHEME PROTOCOL + // http:// http/1.1 + // https:// http/1.1 + // grpc:// h2 + // grpcs:// h2 + // + // For secure HTTP backends (https://) that support HTTP/2, set this field + // to "h2" for improved performance. + // + // Configuring this field to non-default values is only supported for secure + // HTTP backends. This field will be ignored for all other backends. + // + // See + // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids + // for more details on the supported values. + string protocol = 9; + + // The map between request protocol and the backend address. + map overrides_by_request_protocol = 10; + + // The load balancing policy used for connection to the application backend. + // + // Defined as an arbitrary string to accomondate custom load balancing + // policies supported by the underlying channel, but suggest most users use + // one of the standard policies, such as the default, "RoundRobin". + string load_balancing_policy = 11; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py new file mode 100644 index 00000000000..454d236c79a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/backend.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/backend.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x18google/api/backend.proto\x12\ngoogle.api"1\n\x07\x42\x61\x63kend\x12&\n\x05rules\x18\x01 \x03(\x0b\x32\x17.google.api.BackendRule"\xd1\x04\n\x0b\x42\x61\x63kendRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08\x64\x65\x61\x64line\x18\x03 \x01(\x01\x12\x18\n\x0cmin_deadline\x18\x04 \x01(\x01\x42\x02\x18\x01\x12\x1a\n\x12operation_deadline\x18\x05 \x01(\x01\x12\x41\n\x10path_translation\x18\x06 \x01(\x0e\x32\'.google.api.BackendRule.PathTranslation\x12\x16\n\x0cjwt_audience\x18\x07 \x01(\tH\x00\x12\x16\n\x0c\x64isable_auth\x18\x08 \x01(\x08H\x00\x12\x10\n\x08protocol\x18\t \x01(\t\x12^\n\x1doverrides_by_request_protocol\x18\n \x03(\x0b\x32\x37.google.api.BackendRule.OverridesByRequestProtocolEntry\x12\x1d\n\x15load_balancing_policy\x18\x0b \x01(\t\x1aZ\n\x1fOverridesByRequestProtocolEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.google.api.BackendRule:\x02\x38\x01"e\n\x0fPathTranslation\x12 \n\x1cPATH_TRANSLATION_UNSPECIFIED\x10\x00\x12\x14\n\x10\x43ONSTANT_ADDRESS\x10\x01\x12\x1a\n\x16\x41PPEND_PATH_TO_ADDRESS\x10\x02\x42\x10\n\x0e\x61uthenticationBn\n\x0e\x63om.google.apiB\x0c\x42\x61\x63kendProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.backend_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\014BackendProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY"]._loaded_options = None + _globals[ + "_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY" + ]._serialized_options = b"8\001" + _globals["_BACKENDRULE"].fields_by_name["min_deadline"]._loaded_options = None + _globals["_BACKENDRULE"].fields_by_name[ + "min_deadline" + ]._serialized_options = b"\030\001" + _globals["_BACKEND"]._serialized_start = 40 + _globals["_BACKEND"]._serialized_end = 89 + _globals["_BACKENDRULE"]._serialized_start = 92 + _globals["_BACKENDRULE"]._serialized_end = 685 + _globals["_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY"]._serialized_start = 474 + _globals["_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY"]._serialized_end = 564 + _globals["_BACKENDRULE_PATHTRANSLATION"]._serialized_start = 566 + _globals["_BACKENDRULE_PATHTRANSLATION"]._serialized_end = 667 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi new file mode 100644 index 00000000000..162a4bd8761 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi @@ -0,0 +1,106 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class Backend(_message.Message): + __slots__ = ("rules",) + RULES_FIELD_NUMBER: _ClassVar[int] + rules: _containers.RepeatedCompositeFieldContainer[BackendRule] + def __init__( + self, rules: _Optional[_Iterable[_Union[BackendRule, _Mapping]]] = ... + ) -> None: ... + +class BackendRule(_message.Message): + __slots__ = ( + "selector", + "address", + "deadline", + "min_deadline", + "operation_deadline", + "path_translation", + "jwt_audience", + "disable_auth", + "protocol", + "overrides_by_request_protocol", + "load_balancing_policy", + ) + class PathTranslation(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + PATH_TRANSLATION_UNSPECIFIED: _ClassVar[BackendRule.PathTranslation] + CONSTANT_ADDRESS: _ClassVar[BackendRule.PathTranslation] + APPEND_PATH_TO_ADDRESS: _ClassVar[BackendRule.PathTranslation] + + PATH_TRANSLATION_UNSPECIFIED: BackendRule.PathTranslation + CONSTANT_ADDRESS: BackendRule.PathTranslation + APPEND_PATH_TO_ADDRESS: BackendRule.PathTranslation + class OverridesByRequestProtocolEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: BackendRule + def __init__( + self, + key: _Optional[str] = ..., + value: _Optional[_Union[BackendRule, _Mapping]] = ..., + ) -> None: ... + + SELECTOR_FIELD_NUMBER: _ClassVar[int] + ADDRESS_FIELD_NUMBER: _ClassVar[int] + DEADLINE_FIELD_NUMBER: _ClassVar[int] + MIN_DEADLINE_FIELD_NUMBER: _ClassVar[int] + OPERATION_DEADLINE_FIELD_NUMBER: _ClassVar[int] + PATH_TRANSLATION_FIELD_NUMBER: _ClassVar[int] + JWT_AUDIENCE_FIELD_NUMBER: _ClassVar[int] + DISABLE_AUTH_FIELD_NUMBER: _ClassVar[int] + PROTOCOL_FIELD_NUMBER: _ClassVar[int] + OVERRIDES_BY_REQUEST_PROTOCOL_FIELD_NUMBER: _ClassVar[int] + LOAD_BALANCING_POLICY_FIELD_NUMBER: _ClassVar[int] + selector: str + address: str + deadline: float + min_deadline: float + operation_deadline: float + path_translation: BackendRule.PathTranslation + jwt_audience: str + disable_auth: bool + protocol: str + overrides_by_request_protocol: _containers.MessageMap[str, BackendRule] + load_balancing_policy: str + def __init__( + self, + selector: _Optional[str] = ..., + address: _Optional[str] = ..., + deadline: _Optional[float] = ..., + min_deadline: _Optional[float] = ..., + operation_deadline: _Optional[float] = ..., + path_translation: _Optional[_Union[BackendRule.PathTranslation, str]] = ..., + jwt_audience: _Optional[str] = ..., + disable_auth: _Optional[bool] = ..., + protocol: _Optional[str] = ..., + overrides_by_request_protocol: _Optional[_Mapping[str, BackendRule]] = ..., + load_balancing_policy: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto new file mode 100644 index 00000000000..2b86bb61e42 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto @@ -0,0 +1,77 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "BillingProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Billing related configuration of the service. +// +// The following example shows how to configure monitored resources and metrics +// for billing, `consumer_destinations` is the only supported destination and +// the monitored resources need at least one label key +// `cloud.googleapis.com/location` to indicate the location of the billing +// usage, using different monitored resources between monitoring and billing is +// recommended so they can be evolved independently: +// +// +// monitored_resources: +// - type: library.googleapis.com/billing_branch +// labels: +// - key: cloud.googleapis.com/location +// description: | +// Predefined label to support billing location restriction. +// - key: city +// description: | +// Custom label to define the city where the library branch is located +// in. +// - key: name +// description: Custom label to define the name of the library branch. +// metrics: +// - name: library.googleapis.com/book/borrowed_count +// metric_kind: DELTA +// value_type: INT64 +// unit: "1" +// billing: +// consumer_destinations: +// - monitored_resource: library.googleapis.com/billing_branch +// metrics: +// - library.googleapis.com/book/borrowed_count +message Billing { + // Configuration of a specific billing destination (Currently only support + // bill against consumer project). + message BillingDestination { + // The monitored resource type. The type must be defined in + // [Service.monitored_resources][google.api.Service.monitored_resources] + // section. + string monitored_resource = 1; + + // Names of the metrics to report to this billing destination. + // Each name must be defined in + // [Service.metrics][google.api.Service.metrics] section. + repeated string metrics = 2; + } + + // Billing configurations for sending metrics to the consumer project. + // There can be multiple consumer destinations per service, each one must have + // a different monitored resource type. A metric can be used in at most + // one consumer destination. + repeated BillingDestination consumer_destinations = 8; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py new file mode 100644 index 00000000000..d70bf097b3b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/billing.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/billing.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x18google/api/billing.proto\x12\ngoogle.api"\x93\x01\n\x07\x42illing\x12\x45\n\x15\x63onsumer_destinations\x18\x08 \x03(\x0b\x32&.google.api.Billing.BillingDestination\x1a\x41\n\x12\x42illingDestination\x12\x1a\n\x12monitored_resource\x18\x01 \x01(\t\x12\x0f\n\x07metrics\x18\x02 \x03(\tBn\n\x0e\x63om.google.apiB\x0c\x42illingProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.billing_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\014BillingProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_BILLING"]._serialized_start = 41 + _globals["_BILLING"]._serialized_end = 188 + _globals["_BILLING_BILLINGDESTINATION"]._serialized_start = 123 + _globals["_BILLING_BILLINGDESTINATION"]._serialized_end = 188 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi new file mode 100644 index 00000000000..f50e8794e18 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi @@ -0,0 +1,50 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Billing(_message.Message): + __slots__ = ("consumer_destinations",) + class BillingDestination(_message.Message): + __slots__ = ("monitored_resource", "metrics") + MONITORED_RESOURCE_FIELD_NUMBER: _ClassVar[int] + METRICS_FIELD_NUMBER: _ClassVar[int] + monitored_resource: str + metrics: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + monitored_resource: _Optional[str] = ..., + metrics: _Optional[_Iterable[str]] = ..., + ) -> None: ... + + CONSUMER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] + consumer_destinations: _containers.RepeatedCompositeFieldContainer[ + Billing.BillingDestination + ] + def __init__( + self, + consumer_destinations: _Optional[ + _Iterable[_Union[Billing.BillingDestination, _Mapping]] + ] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto new file mode 100644 index 00000000000..332e0d086dc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto @@ -0,0 +1,598 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/launch_stage.proto"; +import "google/protobuf/descriptor.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "ClientProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // A definition of a client library method signature. + // + // In client libraries, each proto RPC corresponds to one or more methods + // which the end user is able to call, and calls the underlying RPC. + // Normally, this method receives a single argument (a struct or instance + // corresponding to the RPC request object). Defining this field will + // add one or more overloads providing flattened or simpler method signatures + // in some languages. + // + // The fields on the method signature are provided as a comma-separated + // string. + // + // For example, the proto RPC and annotation: + // + // rpc CreateSubscription(CreateSubscriptionRequest) + // returns (Subscription) { + // option (google.api.method_signature) = "name,topic"; + // } + // + // Would add the following Java overload (in addition to the method accepting + // the request object): + // + // public final Subscription createSubscription(String name, String topic) + // + // The following backwards-compatibility guidelines apply: + // + // * Adding this annotation to an unannotated method is backwards + // compatible. + // * Adding this annotation to a method which already has existing + // method signature annotations is backwards compatible if and only if + // the new method signature annotation is last in the sequence. + // * Modifying or removing an existing method signature annotation is + // a breaking change. + // * Re-ordering existing method signature annotations is a breaking + // change. + repeated string method_signature = 1051; +} + +extend google.protobuf.ServiceOptions { + // The hostname for this service. + // This should be specified with no prefix or protocol. + // + // Example: + // + // service Foo { + // option (google.api.default_host) = "foo.googleapi.com"; + // ... + // } + string default_host = 1049; + + // OAuth scopes needed for the client. + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform"; + // ... + // } + // + // If there is more than one scope, use a comma-separated string: + // + // Example: + // + // service Foo { + // option (google.api.oauth_scopes) = \ + // "https://www.googleapis.com/auth/cloud-platform," + // "https://www.googleapis.com/auth/monitoring"; + // ... + // } + string oauth_scopes = 1050; + + // The API version of this service, which should be sent by version-aware + // clients to the service. This allows services to abide by the schema and + // behavior of the service at the time this API version was deployed. + // The format of the API version must be treated as opaque by clients. + // Services may use a format with an apparent structure, but clients must + // not rely on this to determine components within an API version, or attempt + // to construct other valid API versions. Note that this is for upcoming + // functionality and may not be implemented for all services. + // + // Example: + // + // service Foo { + // option (google.api.api_version) = "v1_20230821_preview"; + // } + string api_version = 525000001; +} + +// Required information for every language. +message CommonLanguageSettings { + // Link to automatically generated reference documentation. Example: + // https://cloud.google.com/nodejs/docs/reference/asset/latest + string reference_docs_uri = 1 [deprecated = true]; + + // The destination where API teams want this client library to be published. + repeated ClientLibraryDestination destinations = 2; + + // Configuration for which RPCs should be generated in the GAPIC client. + // + // Note: This field should not be used in most cases. + SelectiveGapicGeneration selective_gapic_generation = 3; +} + +// Details about how and where to publish client libraries. +message ClientLibrarySettings { + // Version of the API to apply these settings to. This is the full protobuf + // package for the API, ending in the version element. + // Examples: "google.cloud.speech.v1" and "google.spanner.admin.database.v1". + string version = 1; + + // Launch stage of this version of the API. + LaunchStage launch_stage = 2; + + // When using transport=rest, the client request will encode enums as + // numbers rather than strings. + bool rest_numeric_enums = 3; + + // Settings for legacy Java features, supported in the Service YAML. + JavaSettings java_settings = 21; + + // Settings for C++ client libraries. + CppSettings cpp_settings = 22; + + // Settings for PHP client libraries. + PhpSettings php_settings = 23; + + // Settings for Python client libraries. + PythonSettings python_settings = 24; + + // Settings for Node client libraries. + NodeSettings node_settings = 25; + + // Settings for .NET client libraries. + DotnetSettings dotnet_settings = 26; + + // Settings for Ruby client libraries. + RubySettings ruby_settings = 27; + + // Settings for Go client libraries. + GoSettings go_settings = 28; +} + +// This message configures the settings for publishing [Google Cloud Client +// libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) +// generated from the service config. +message Publishing { + // A list of API method settings, e.g. the behavior for methods that use the + // long-running operation pattern. + repeated MethodSettings method_settings = 2; + + // Link to a *public* URI where users can report issues. Example: + // https://issuetracker.google.com/issues/new?component=190865&template=1161103 + string new_issue_uri = 101; + + // Link to product home page. Example: + // https://cloud.google.com/asset-inventory/docs/overview + string documentation_uri = 102; + + // Used as a tracking tag when collecting data about the APIs developer + // relations artifacts like docs, packages delivered to package managers, + // etc. Example: "speech". + string api_short_name = 103; + + // GitHub label to apply to issues and pull requests opened for this API. + string github_label = 104; + + // GitHub teams to be added to CODEOWNERS in the directory in GitHub + // containing source code for the client libraries for this API. + repeated string codeowner_github_teams = 105; + + // A prefix used in sample code when demarking regions to be included in + // documentation. + string doc_tag_prefix = 106; + + // For whom the client library is being published. + ClientLibraryOrganization organization = 107; + + // Client library settings. If the same version string appears multiple + // times in this list, then the last one wins. Settings from earlier + // settings with the same version string are discarded. + repeated ClientLibrarySettings library_settings = 109; + + // Optional link to proto reference documentation. Example: + // https://cloud.google.com/pubsub/lite/docs/reference/rpc + string proto_reference_documentation_uri = 110; + + // Optional link to REST reference documentation. Example: + // https://cloud.google.com/pubsub/lite/docs/reference/rest + string rest_reference_documentation_uri = 111; +} + +// Settings for Java client libraries. +message JavaSettings { + // The package name to use in Java. Clobbers the java_package option + // set in the protobuf. This should be used **only** by APIs + // who have already set the language_settings.java.package_name" field + // in gapic.yaml. API teams should use the protobuf java_package option + // where possible. + // + // Example of a YAML configuration:: + // + // publishing: + // library_settings: + // java_settings: + // library_package: com.google.cloud.pubsub.v1 + string library_package = 1; + + // Configure the Java class name to use instead of the service's for its + // corresponding generated GAPIC client. Keys are fully-qualified + // service names as they appear in the protobuf (including the full + // the language_settings.java.interface_names" field in gapic.yaml. API + // teams should otherwise use the service name as it appears in the + // protobuf. + // + // Example of a YAML configuration:: + // + // publishing: + // java_settings: + // service_class_names: + // - google.pubsub.v1.Publisher: TopicAdmin + // - google.pubsub.v1.Subscriber: SubscriptionAdmin + map service_class_names = 2; + + // Some settings. + CommonLanguageSettings common = 3; +} + +// Settings for C++ client libraries. +message CppSettings { + // Some settings. + CommonLanguageSettings common = 1; +} + +// Settings for Php client libraries. +message PhpSettings { + // Some settings. + CommonLanguageSettings common = 1; + + // The package name to use in Php. Clobbers the php_namespace option + // set in the protobuf. This should be used **only** by APIs + // who have already set the language_settings.php.package_name" field + // in gapic.yaml. API teams should use the protobuf php_namespace option + // where possible. + // + // Example of a YAML configuration:: + // + // publishing: + // library_settings: + // php_settings: + // library_package: Google\Cloud\PubSub\V1 + string library_package = 2; +} + +// Settings for Python client libraries. +message PythonSettings { + // Experimental features to be included during client library generation. + // These fields will be deprecated once the feature graduates and is enabled + // by default. + message ExperimentalFeatures { + // Enables generation of asynchronous REST clients if `rest` transport is + // enabled. By default, asynchronous REST clients will not be generated. + // This feature will be enabled by default 1 month after launching the + // feature in preview packages. + bool rest_async_io_enabled = 1; + + // Enables generation of protobuf code using new types that are more + // Pythonic which are included in `protobuf>=5.29.x`. This feature will be + // enabled by default 1 month after launching the feature in preview + // packages. + bool protobuf_pythonic_types_enabled = 2; + + // Disables generation of an unversioned Python package for this client + // library. This means that the module names will need to be versioned in + // import statements. For example `import google.cloud.library_v2` instead + // of `import google.cloud.library`. + bool unversioned_package_disabled = 3; + } + + // Some settings. + CommonLanguageSettings common = 1; + + // Experimental features to be included during client library generation. + ExperimentalFeatures experimental_features = 2; +} + +// Settings for Node client libraries. +message NodeSettings { + // Some settings. + CommonLanguageSettings common = 1; +} + +// Settings for Dotnet client libraries. +message DotnetSettings { + // Some settings. + CommonLanguageSettings common = 1; + + // Map from original service names to renamed versions. + // This is used when the default generated types + // would cause a naming conflict. (Neither name is + // fully-qualified.) + // Example: Subscriber to SubscriberServiceApi. + map renamed_services = 2; + + // Map from full resource types to the effective short name + // for the resource. This is used when otherwise resource + // named from different services would cause naming collisions. + // Example entry: + // "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" + map renamed_resources = 3; + + // List of full resource types to ignore during generation. + // This is typically used for API-specific Location resources, + // which should be handled by the generator as if they were actually + // the common Location resources. + // Example entry: "documentai.googleapis.com/Location" + repeated string ignored_resources = 4; + + // Namespaces which must be aliased in snippets due to + // a known (but non-generator-predictable) naming collision + repeated string forced_namespace_aliases = 5; + + // Method signatures (in the form "service.method(signature)") + // which are provided separately, so shouldn't be generated. + // Snippets *calling* these methods are still generated, however. + repeated string handwritten_signatures = 6; +} + +// Settings for Ruby client libraries. +message RubySettings { + // Some settings. + CommonLanguageSettings common = 1; +} + +// Settings for Go client libraries. +message GoSettings { + // Some settings. + CommonLanguageSettings common = 1; + + // Map of service names to renamed services. Keys are the package relative + // service names and values are the name to be used for the service client + // and call options. + // + // Example: + // + // publishing: + // go_settings: + // renamed_services: + // Publisher: TopicAdmin + map renamed_services = 2; +} + +// Describes the generator configuration for a method. +message MethodSettings { + // Describes settings to use when generating API methods that use the + // long-running operation pattern. + // All default values below are from those used in the client library + // generators (e.g. + // [Java](https://github.com/googleapis/gapic-generator-java/blob/04c2faa191a9b5a10b92392fe8482279c4404803/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java)). + message LongRunning { + // Initial delay after which the first poll request will be made. + // Default value: 5 seconds. + google.protobuf.Duration initial_poll_delay = 1; + + // Multiplier to gradually increase delay between subsequent polls until it + // reaches max_poll_delay. + // Default value: 1.5. + float poll_delay_multiplier = 2; + + // Maximum time between two subsequent poll requests. + // Default value: 45 seconds. + google.protobuf.Duration max_poll_delay = 3; + + // Total polling timeout. + // Default value: 5 minutes. + google.protobuf.Duration total_poll_timeout = 4; + } + + // The fully qualified name of the method, for which the options below apply. + // This is used to find the method to apply the options. + // + // Example: + // + // publishing: + // method_settings: + // - selector: google.storage.control.v2.StorageControl.CreateFolder + // # method settings for CreateFolder... + string selector = 1; + + // Describes settings to use for long-running operations when generating + // API methods for RPCs. Complements RPCs that use the annotations in + // google/longrunning/operations.proto. + // + // Example of a YAML configuration:: + // + // publishing: + // method_settings: + // - selector: google.cloud.speech.v2.Speech.BatchRecognize + // long_running: + // initial_poll_delay: 60s # 1 minute + // poll_delay_multiplier: 1.5 + // max_poll_delay: 360s # 6 minutes + // total_poll_timeout: 54000s # 90 minutes + LongRunning long_running = 2; + + // List of top-level fields of the request message, that should be + // automatically populated by the client libraries based on their + // (google.api.field_info).format. Currently supported format: UUID4. + // + // Example of a YAML configuration: + // + // publishing: + // method_settings: + // - selector: google.example.v1.ExampleService.CreateExample + // auto_populated_fields: + // - request_id + repeated string auto_populated_fields = 3; + + // Batching configuration for an API method in client libraries. + // + // Example of a YAML configuration: + // + // publishing: + // method_settings: + // - selector: google.example.v1.ExampleService.BatchCreateExample + // batching: + // element_count_threshold: 1000 + // request_byte_threshold: 100000000 + // delay_threshold_millis: 10 + BatchingConfigProto batching = 4; +} + +// The organization for which the client libraries are being published. +// Affects the url where generated docs are published, etc. +enum ClientLibraryOrganization { + // Not useful. + CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED = 0; + + // Google Cloud Platform Org. + CLOUD = 1; + + // Ads (Advertising) Org. + ADS = 2; + + // Photos Org. + PHOTOS = 3; + + // Street View Org. + STREET_VIEW = 4; + + // Shopping Org. + SHOPPING = 5; + + // Geo Org. + GEO = 6; + + // Generative AI - https://developers.generativeai.google + GENERATIVE_AI = 7; +} + +// To where should client libraries be published? +enum ClientLibraryDestination { + // Client libraries will neither be generated nor published to package + // managers. + CLIENT_LIBRARY_DESTINATION_UNSPECIFIED = 0; + + // Generate the client library in a repo under github.com/googleapis, + // but don't publish it to package managers. + GITHUB = 10; + + // Publish the library to package managers like nuget.org and npmjs.com. + PACKAGE_MANAGER = 20; +} + +// This message is used to configure the generation of a subset of the RPCs in +// a service for client libraries. +// +// Note: This feature should not be used in most cases. +message SelectiveGapicGeneration { + // An allowlist of the fully qualified names of RPCs that should be included + // on public client surfaces. + repeated string methods = 1; + + // Setting this to true indicates to the client generators that methods + // that would be excluded from the generation should instead be generated + // in a way that indicates these methods should not be consumed by + // end users. How this is expressed is up to individual language + // implementations to decide. Some examples may be: added annotations, + // obfuscated identifiers, or other language idiomatic patterns. + bool generate_omitted_as_internal = 2; +} + +// `BatchingConfigProto` defines the batching configuration for an API method. +message BatchingConfigProto { + // The thresholds which trigger a batched request to be sent. + BatchingSettingsProto thresholds = 1; + + // The request and response fields used in batching. + BatchingDescriptorProto batch_descriptor = 2; +} + +// `BatchingSettingsProto` specifies a set of batching thresholds, each of +// which acts as a trigger to send a batch of messages as a request. At least +// one threshold must be positive nonzero. +message BatchingSettingsProto { + // The number of elements of a field collected into a batch which, if + // exceeded, causes the batch to be sent. + int32 element_count_threshold = 1; + + // The aggregated size of the batched field which, if exceeded, causes the + // batch to be sent. This size is computed by aggregating the sizes of the + // request field to be batched, not of the entire request message. + int64 request_byte_threshold = 2; + + // The duration after which a batch should be sent, starting from the addition + // of the first message to that batch. + google.protobuf.Duration delay_threshold = 3; + + // The maximum number of elements collected in a batch that could be accepted + // by server. + int32 element_count_limit = 4; + + // The maximum size of the request that could be accepted by server. + int32 request_byte_limit = 5; + + // The maximum number of elements allowed by flow control. + int32 flow_control_element_limit = 6; + + // The maximum size of data allowed by flow control. + int32 flow_control_byte_limit = 7; + + // The behavior to take when the flow control limit is exceeded. + FlowControlLimitExceededBehaviorProto flow_control_limit_exceeded_behavior = + 8; +} + +// The behavior to take when the flow control limit is exceeded. +enum FlowControlLimitExceededBehaviorProto { + // Default behavior, system-defined. + UNSET_BEHAVIOR = 0; + + // Stop operation, raise error. + THROW_EXCEPTION = 1; + + // Pause operation until limit clears. + BLOCK = 2; + + // Continue operation, disregard limit. + IGNORE = 3; +} + +// `BatchingDescriptorProto` specifies the fields of the request message to be +// used for batching, and, optionally, the fields of the response message to be +// used for demultiplexing. +message BatchingDescriptorProto { + // The repeated field in the request message to be aggregated by batching. + string batched_field = 1; + + // A list of the fields in the request message. Two requests will be batched + // together only if the values of every field specified in + // `request_discriminator_fields` is equal between the two requests. + repeated string discriminator_fields = 2; + + // Optional. When present, indicates the field in the response message to be + // used to demultiplex the response into multiple response messages, in + // correspondence with the multiple request messages originally batched + // together. + string subresponse_field = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py new file mode 100644 index 00000000000..363109cbf50 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/client.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/client.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 +from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 + +from opentelemetry.agent._vendor.google.api import launch_stage_pb2 as google_dot_api_dot_launch__stage__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x17google/api/client.proto\x12\ngoogle.api\x1a\x1dgoogle/api/launch_stage.proto\x1a google/protobuf/descriptor.proto\x1a\x1egoogle/protobuf/duration.proto"\xbe\x01\n\x16\x43ommonLanguageSettings\x12\x1e\n\x12reference_docs_uri\x18\x01 \x01(\tB\x02\x18\x01\x12:\n\x0c\x64\x65stinations\x18\x02 \x03(\x0e\x32$.google.api.ClientLibraryDestination\x12H\n\x1aselective_gapic_generation\x18\x03 \x01(\x0b\x32$.google.api.SelectiveGapicGeneration"\xfb\x03\n\x15\x43lientLibrarySettings\x12\x0f\n\x07version\x18\x01 \x01(\t\x12-\n\x0claunch_stage\x18\x02 \x01(\x0e\x32\x17.google.api.LaunchStage\x12\x1a\n\x12rest_numeric_enums\x18\x03 \x01(\x08\x12/\n\rjava_settings\x18\x15 \x01(\x0b\x32\x18.google.api.JavaSettings\x12-\n\x0c\x63pp_settings\x18\x16 \x01(\x0b\x32\x17.google.api.CppSettings\x12-\n\x0cphp_settings\x18\x17 \x01(\x0b\x32\x17.google.api.PhpSettings\x12\x33\n\x0fpython_settings\x18\x18 \x01(\x0b\x32\x1a.google.api.PythonSettings\x12/\n\rnode_settings\x18\x19 \x01(\x0b\x32\x18.google.api.NodeSettings\x12\x33\n\x0f\x64otnet_settings\x18\x1a \x01(\x0b\x32\x1a.google.api.DotnetSettings\x12/\n\rruby_settings\x18\x1b \x01(\x0b\x32\x18.google.api.RubySettings\x12+\n\x0bgo_settings\x18\x1c \x01(\x0b\x32\x16.google.api.GoSettings"\xa8\x03\n\nPublishing\x12\x33\n\x0fmethod_settings\x18\x02 \x03(\x0b\x32\x1a.google.api.MethodSettings\x12\x15\n\rnew_issue_uri\x18\x65 \x01(\t\x12\x19\n\x11\x64ocumentation_uri\x18\x66 \x01(\t\x12\x16\n\x0e\x61pi_short_name\x18g \x01(\t\x12\x14\n\x0cgithub_label\x18h \x01(\t\x12\x1e\n\x16\x63odeowner_github_teams\x18i \x03(\t\x12\x16\n\x0e\x64oc_tag_prefix\x18j \x01(\t\x12;\n\x0corganization\x18k \x01(\x0e\x32%.google.api.ClientLibraryOrganization\x12;\n\x10library_settings\x18m \x03(\x0b\x32!.google.api.ClientLibrarySettings\x12)\n!proto_reference_documentation_uri\x18n \x01(\t\x12(\n rest_reference_documentation_uri\x18o \x01(\t"\xe3\x01\n\x0cJavaSettings\x12\x17\n\x0flibrary_package\x18\x01 \x01(\t\x12L\n\x13service_class_names\x18\x02 \x03(\x0b\x32/.google.api.JavaSettings.ServiceClassNamesEntry\x12\x32\n\x06\x63ommon\x18\x03 \x01(\x0b\x32".google.api.CommonLanguageSettings\x1a\x38\n\x16ServiceClassNamesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"A\n\x0b\x43ppSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings"Z\n\x0bPhpSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12\x17\n\x0flibrary_package\x18\x02 \x01(\t"\x9b\x02\n\x0ePythonSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12N\n\x15\x65xperimental_features\x18\x02 \x01(\x0b\x32/.google.api.PythonSettings.ExperimentalFeatures\x1a\x84\x01\n\x14\x45xperimentalFeatures\x12\x1d\n\x15rest_async_io_enabled\x18\x01 \x01(\x08\x12\'\n\x1fprotobuf_pythonic_types_enabled\x18\x02 \x01(\x08\x12$\n\x1cunversioned_package_disabled\x18\x03 \x01(\x08"B\n\x0cNodeSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings"\xaa\x03\n\x0e\x44otnetSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12I\n\x10renamed_services\x18\x02 \x03(\x0b\x32/.google.api.DotnetSettings.RenamedServicesEntry\x12K\n\x11renamed_resources\x18\x03 \x03(\x0b\x32\x30.google.api.DotnetSettings.RenamedResourcesEntry\x12\x19\n\x11ignored_resources\x18\x04 \x03(\t\x12 \n\x18\x66orced_namespace_aliases\x18\x05 \x03(\t\x12\x1e\n\x16handwritten_signatures\x18\x06 \x03(\t\x1a\x36\n\x14RenamedServicesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x37\n\x15RenamedResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"B\n\x0cRubySettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings"\xbf\x01\n\nGoSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12\x45\n\x10renamed_services\x18\x02 \x03(\x0b\x32+.google.api.GoSettings.RenamedServicesEntry\x1a\x36\n\x14RenamedServicesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\x82\x03\n\x0eMethodSettings\x12\x10\n\x08selector\x18\x01 \x01(\t\x12<\n\x0clong_running\x18\x02 \x01(\x0b\x32&.google.api.MethodSettings.LongRunning\x12\x1d\n\x15\x61uto_populated_fields\x18\x03 \x03(\t\x12\x31\n\x08\x62\x61tching\x18\x04 \x01(\x0b\x32\x1f.google.api.BatchingConfigProto\x1a\xcd\x01\n\x0bLongRunning\x12\x35\n\x12initial_poll_delay\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x1d\n\x15poll_delay_multiplier\x18\x02 \x01(\x02\x12\x31\n\x0emax_poll_delay\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x35\n\x12total_poll_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration"Q\n\x18SelectiveGapicGeneration\x12\x0f\n\x07methods\x18\x01 \x03(\t\x12$\n\x1cgenerate_omitted_as_internal\x18\x02 \x01(\x08"\x8b\x01\n\x13\x42\x61tchingConfigProto\x12\x35\n\nthresholds\x18\x01 \x01(\x0b\x32!.google.api.BatchingSettingsProto\x12=\n\x10\x62\x61tch_descriptor\x18\x02 \x01(\x0b\x32#.google.api.BatchingDescriptorProto"\xeb\x02\n\x15\x42\x61tchingSettingsProto\x12\x1f\n\x17\x65lement_count_threshold\x18\x01 \x01(\x05\x12\x1e\n\x16request_byte_threshold\x18\x02 \x01(\x03\x12\x32\n\x0f\x64\x65lay_threshold\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x1b\n\x13\x65lement_count_limit\x18\x04 \x01(\x05\x12\x1a\n\x12request_byte_limit\x18\x05 \x01(\x05\x12"\n\x1a\x66low_control_element_limit\x18\x06 \x01(\x05\x12\x1f\n\x17\x66low_control_byte_limit\x18\x07 \x01(\x05\x12_\n$flow_control_limit_exceeded_behavior\x18\x08 \x01(\x0e\x32\x31.google.api.FlowControlLimitExceededBehaviorProto"i\n\x17\x42\x61tchingDescriptorProto\x12\x15\n\rbatched_field\x18\x01 \x01(\t\x12\x1c\n\x14\x64iscriminator_fields\x18\x02 \x03(\t\x12\x19\n\x11subresponse_field\x18\x03 \x01(\t*\xa3\x01\n\x19\x43lientLibraryOrganization\x12+\n\'CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED\x10\x00\x12\t\n\x05\x43LOUD\x10\x01\x12\x07\n\x03\x41\x44S\x10\x02\x12\n\n\x06PHOTOS\x10\x03\x12\x0f\n\x0bSTREET_VIEW\x10\x04\x12\x0c\n\x08SHOPPING\x10\x05\x12\x07\n\x03GEO\x10\x06\x12\x11\n\rGENERATIVE_AI\x10\x07*g\n\x18\x43lientLibraryDestination\x12*\n&CLIENT_LIBRARY_DESTINATION_UNSPECIFIED\x10\x00\x12\n\n\x06GITHUB\x10\n\x12\x13\n\x0fPACKAGE_MANAGER\x10\x14*g\n%FlowControlLimitExceededBehaviorProto\x12\x12\n\x0eUNSET_BEHAVIOR\x10\x00\x12\x13\n\x0fTHROW_EXCEPTION\x10\x01\x12\t\n\x05\x42LOCK\x10\x02\x12\n\n\x06IGNORE\x10\x03:9\n\x10method_signature\x12\x1e.google.protobuf.MethodOptions\x18\x9b\x08 \x03(\t:6\n\x0c\x64\x65\x66\x61ult_host\x12\x1f.google.protobuf.ServiceOptions\x18\x99\x08 \x01(\t:6\n\x0coauth_scopes\x12\x1f.google.protobuf.ServiceOptions\x18\x9a\x08 \x01(\t:8\n\x0b\x61pi_version\x12\x1f.google.protobuf.ServiceOptions\x18\xc1\xba\xab\xfa\x01 \x01(\tBi\n\x0e\x63om.google.apiB\x0b\x43lientProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.client_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\013ClientProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" + _globals["_COMMONLANGUAGESETTINGS"].fields_by_name[ + "reference_docs_uri" + ]._loaded_options = None + _globals["_COMMONLANGUAGESETTINGS"].fields_by_name[ + "reference_docs_uri" + ]._serialized_options = b"\030\001" + _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._loaded_options = None + _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._serialized_options = b"8\001" + _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._loaded_options = None + _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._serialized_options = b"8\001" + _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._loaded_options = None + _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._serialized_options = b"8\001" + _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._loaded_options = None + _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._serialized_options = b"8\001" + _globals["_CLIENTLIBRARYORGANIZATION"]._serialized_start = 3788 + _globals["_CLIENTLIBRARYORGANIZATION"]._serialized_end = 3951 + _globals["_CLIENTLIBRARYDESTINATION"]._serialized_start = 3953 + _globals["_CLIENTLIBRARYDESTINATION"]._serialized_end = 4056 + _globals["_FLOWCONTROLLIMITEXCEEDEDBEHAVIORPROTO"]._serialized_start = 4058 + _globals["_FLOWCONTROLLIMITEXCEEDEDBEHAVIORPROTO"]._serialized_end = 4161 + _globals["_COMMONLANGUAGESETTINGS"]._serialized_start = 137 + _globals["_COMMONLANGUAGESETTINGS"]._serialized_end = 327 + _globals["_CLIENTLIBRARYSETTINGS"]._serialized_start = 330 + _globals["_CLIENTLIBRARYSETTINGS"]._serialized_end = 837 + _globals["_PUBLISHING"]._serialized_start = 840 + _globals["_PUBLISHING"]._serialized_end = 1264 + _globals["_JAVASETTINGS"]._serialized_start = 1267 + _globals["_JAVASETTINGS"]._serialized_end = 1494 + _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._serialized_start = 1438 + _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._serialized_end = 1494 + _globals["_CPPSETTINGS"]._serialized_start = 1496 + _globals["_CPPSETTINGS"]._serialized_end = 1561 + _globals["_PHPSETTINGS"]._serialized_start = 1563 + _globals["_PHPSETTINGS"]._serialized_end = 1653 + _globals["_PYTHONSETTINGS"]._serialized_start = 1656 + _globals["_PYTHONSETTINGS"]._serialized_end = 1939 + _globals["_PYTHONSETTINGS_EXPERIMENTALFEATURES"]._serialized_start = 1807 + _globals["_PYTHONSETTINGS_EXPERIMENTALFEATURES"]._serialized_end = 1939 + _globals["_NODESETTINGS"]._serialized_start = 1941 + _globals["_NODESETTINGS"]._serialized_end = 2007 + _globals["_DOTNETSETTINGS"]._serialized_start = 2010 + _globals["_DOTNETSETTINGS"]._serialized_end = 2436 + _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._serialized_start = 2325 + _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._serialized_end = 2379 + _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._serialized_start = 2381 + _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._serialized_end = 2436 + _globals["_RUBYSETTINGS"]._serialized_start = 2438 + _globals["_RUBYSETTINGS"]._serialized_end = 2504 + _globals["_GOSETTINGS"]._serialized_start = 2507 + _globals["_GOSETTINGS"]._serialized_end = 2698 + _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._serialized_start = 2325 + _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._serialized_end = 2379 + _globals["_METHODSETTINGS"]._serialized_start = 2701 + _globals["_METHODSETTINGS"]._serialized_end = 3087 + _globals["_METHODSETTINGS_LONGRUNNING"]._serialized_start = 2882 + _globals["_METHODSETTINGS_LONGRUNNING"]._serialized_end = 3087 + _globals["_SELECTIVEGAPICGENERATION"]._serialized_start = 3089 + _globals["_SELECTIVEGAPICGENERATION"]._serialized_end = 3170 + _globals["_BATCHINGCONFIGPROTO"]._serialized_start = 3173 + _globals["_BATCHINGCONFIGPROTO"]._serialized_end = 3312 + _globals["_BATCHINGSETTINGSPROTO"]._serialized_start = 3315 + _globals["_BATCHINGSETTINGSPROTO"]._serialized_end = 3678 + _globals["_BATCHINGDESCRIPTORPROTO"]._serialized_start = 3680 + _globals["_BATCHINGDESCRIPTORPROTO"]._serialized_end = 3785 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi new file mode 100644 index 00000000000..c25654fb9a2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi @@ -0,0 +1,498 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf import duration_pb2 as _duration_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +from google.api import launch_stage_pb2 as _launch_stage_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class ClientLibraryOrganization(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED: _ClassVar[ClientLibraryOrganization] + CLOUD: _ClassVar[ClientLibraryOrganization] + ADS: _ClassVar[ClientLibraryOrganization] + PHOTOS: _ClassVar[ClientLibraryOrganization] + STREET_VIEW: _ClassVar[ClientLibraryOrganization] + SHOPPING: _ClassVar[ClientLibraryOrganization] + GEO: _ClassVar[ClientLibraryOrganization] + GENERATIVE_AI: _ClassVar[ClientLibraryOrganization] + +class ClientLibraryDestination(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + CLIENT_LIBRARY_DESTINATION_UNSPECIFIED: _ClassVar[ClientLibraryDestination] + GITHUB: _ClassVar[ClientLibraryDestination] + PACKAGE_MANAGER: _ClassVar[ClientLibraryDestination] + +class FlowControlLimitExceededBehaviorProto( + int, metaclass=_enum_type_wrapper.EnumTypeWrapper +): + __slots__ = () + UNSET_BEHAVIOR: _ClassVar[FlowControlLimitExceededBehaviorProto] + THROW_EXCEPTION: _ClassVar[FlowControlLimitExceededBehaviorProto] + BLOCK: _ClassVar[FlowControlLimitExceededBehaviorProto] + IGNORE: _ClassVar[FlowControlLimitExceededBehaviorProto] + +CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED: ClientLibraryOrganization +CLOUD: ClientLibraryOrganization +ADS: ClientLibraryOrganization +PHOTOS: ClientLibraryOrganization +STREET_VIEW: ClientLibraryOrganization +SHOPPING: ClientLibraryOrganization +GEO: ClientLibraryOrganization +GENERATIVE_AI: ClientLibraryOrganization +CLIENT_LIBRARY_DESTINATION_UNSPECIFIED: ClientLibraryDestination +GITHUB: ClientLibraryDestination +PACKAGE_MANAGER: ClientLibraryDestination +UNSET_BEHAVIOR: FlowControlLimitExceededBehaviorProto +THROW_EXCEPTION: FlowControlLimitExceededBehaviorProto +BLOCK: FlowControlLimitExceededBehaviorProto +IGNORE: FlowControlLimitExceededBehaviorProto +METHOD_SIGNATURE_FIELD_NUMBER: _ClassVar[int] +method_signature: _descriptor.FieldDescriptor +DEFAULT_HOST_FIELD_NUMBER: _ClassVar[int] +default_host: _descriptor.FieldDescriptor +OAUTH_SCOPES_FIELD_NUMBER: _ClassVar[int] +oauth_scopes: _descriptor.FieldDescriptor +API_VERSION_FIELD_NUMBER: _ClassVar[int] +api_version: _descriptor.FieldDescriptor + +class CommonLanguageSettings(_message.Message): + __slots__ = ("reference_docs_uri", "destinations", "selective_gapic_generation") + REFERENCE_DOCS_URI_FIELD_NUMBER: _ClassVar[int] + DESTINATIONS_FIELD_NUMBER: _ClassVar[int] + SELECTIVE_GAPIC_GENERATION_FIELD_NUMBER: _ClassVar[int] + reference_docs_uri: str + destinations: _containers.RepeatedScalarFieldContainer[ClientLibraryDestination] + selective_gapic_generation: SelectiveGapicGeneration + def __init__( + self, + reference_docs_uri: _Optional[str] = ..., + destinations: _Optional[_Iterable[_Union[ClientLibraryDestination, str]]] = ..., + selective_gapic_generation: _Optional[ + _Union[SelectiveGapicGeneration, _Mapping] + ] = ..., + ) -> None: ... + +class ClientLibrarySettings(_message.Message): + __slots__ = ( + "version", + "launch_stage", + "rest_numeric_enums", + "java_settings", + "cpp_settings", + "php_settings", + "python_settings", + "node_settings", + "dotnet_settings", + "ruby_settings", + "go_settings", + ) + VERSION_FIELD_NUMBER: _ClassVar[int] + LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] + REST_NUMERIC_ENUMS_FIELD_NUMBER: _ClassVar[int] + JAVA_SETTINGS_FIELD_NUMBER: _ClassVar[int] + CPP_SETTINGS_FIELD_NUMBER: _ClassVar[int] + PHP_SETTINGS_FIELD_NUMBER: _ClassVar[int] + PYTHON_SETTINGS_FIELD_NUMBER: _ClassVar[int] + NODE_SETTINGS_FIELD_NUMBER: _ClassVar[int] + DOTNET_SETTINGS_FIELD_NUMBER: _ClassVar[int] + RUBY_SETTINGS_FIELD_NUMBER: _ClassVar[int] + GO_SETTINGS_FIELD_NUMBER: _ClassVar[int] + version: str + launch_stage: _launch_stage_pb2.LaunchStage + rest_numeric_enums: bool + java_settings: JavaSettings + cpp_settings: CppSettings + php_settings: PhpSettings + python_settings: PythonSettings + node_settings: NodeSettings + dotnet_settings: DotnetSettings + ruby_settings: RubySettings + go_settings: GoSettings + def __init__( + self, + version: _Optional[str] = ..., + launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., + rest_numeric_enums: _Optional[bool] = ..., + java_settings: _Optional[_Union[JavaSettings, _Mapping]] = ..., + cpp_settings: _Optional[_Union[CppSettings, _Mapping]] = ..., + php_settings: _Optional[_Union[PhpSettings, _Mapping]] = ..., + python_settings: _Optional[_Union[PythonSettings, _Mapping]] = ..., + node_settings: _Optional[_Union[NodeSettings, _Mapping]] = ..., + dotnet_settings: _Optional[_Union[DotnetSettings, _Mapping]] = ..., + ruby_settings: _Optional[_Union[RubySettings, _Mapping]] = ..., + go_settings: _Optional[_Union[GoSettings, _Mapping]] = ..., + ) -> None: ... + +class Publishing(_message.Message): + __slots__ = ( + "method_settings", + "new_issue_uri", + "documentation_uri", + "api_short_name", + "github_label", + "codeowner_github_teams", + "doc_tag_prefix", + "organization", + "library_settings", + "proto_reference_documentation_uri", + "rest_reference_documentation_uri", + ) + METHOD_SETTINGS_FIELD_NUMBER: _ClassVar[int] + NEW_ISSUE_URI_FIELD_NUMBER: _ClassVar[int] + DOCUMENTATION_URI_FIELD_NUMBER: _ClassVar[int] + API_SHORT_NAME_FIELD_NUMBER: _ClassVar[int] + GITHUB_LABEL_FIELD_NUMBER: _ClassVar[int] + CODEOWNER_GITHUB_TEAMS_FIELD_NUMBER: _ClassVar[int] + DOC_TAG_PREFIX_FIELD_NUMBER: _ClassVar[int] + ORGANIZATION_FIELD_NUMBER: _ClassVar[int] + LIBRARY_SETTINGS_FIELD_NUMBER: _ClassVar[int] + PROTO_REFERENCE_DOCUMENTATION_URI_FIELD_NUMBER: _ClassVar[int] + REST_REFERENCE_DOCUMENTATION_URI_FIELD_NUMBER: _ClassVar[int] + method_settings: _containers.RepeatedCompositeFieldContainer[MethodSettings] + new_issue_uri: str + documentation_uri: str + api_short_name: str + github_label: str + codeowner_github_teams: _containers.RepeatedScalarFieldContainer[str] + doc_tag_prefix: str + organization: ClientLibraryOrganization + library_settings: _containers.RepeatedCompositeFieldContainer[ClientLibrarySettings] + proto_reference_documentation_uri: str + rest_reference_documentation_uri: str + def __init__( + self, + method_settings: _Optional[_Iterable[_Union[MethodSettings, _Mapping]]] = ..., + new_issue_uri: _Optional[str] = ..., + documentation_uri: _Optional[str] = ..., + api_short_name: _Optional[str] = ..., + github_label: _Optional[str] = ..., + codeowner_github_teams: _Optional[_Iterable[str]] = ..., + doc_tag_prefix: _Optional[str] = ..., + organization: _Optional[_Union[ClientLibraryOrganization, str]] = ..., + library_settings: _Optional[ + _Iterable[_Union[ClientLibrarySettings, _Mapping]] + ] = ..., + proto_reference_documentation_uri: _Optional[str] = ..., + rest_reference_documentation_uri: _Optional[str] = ..., + ) -> None: ... + +class JavaSettings(_message.Message): + __slots__ = ("library_package", "service_class_names", "common") + class ServiceClassNamesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + LIBRARY_PACKAGE_FIELD_NUMBER: _ClassVar[int] + SERVICE_CLASS_NAMES_FIELD_NUMBER: _ClassVar[int] + COMMON_FIELD_NUMBER: _ClassVar[int] + library_package: str + service_class_names: _containers.ScalarMap[str, str] + common: CommonLanguageSettings + def __init__( + self, + library_package: _Optional[str] = ..., + service_class_names: _Optional[_Mapping[str, str]] = ..., + common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., + ) -> None: ... + +class CppSettings(_message.Message): + __slots__ = ("common",) + COMMON_FIELD_NUMBER: _ClassVar[int] + common: CommonLanguageSettings + def __init__( + self, common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ... + ) -> None: ... + +class PhpSettings(_message.Message): + __slots__ = ("common", "library_package") + COMMON_FIELD_NUMBER: _ClassVar[int] + LIBRARY_PACKAGE_FIELD_NUMBER: _ClassVar[int] + common: CommonLanguageSettings + library_package: str + def __init__( + self, + common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., + library_package: _Optional[str] = ..., + ) -> None: ... + +class PythonSettings(_message.Message): + __slots__ = ("common", "experimental_features") + class ExperimentalFeatures(_message.Message): + __slots__ = ( + "rest_async_io_enabled", + "protobuf_pythonic_types_enabled", + "unversioned_package_disabled", + ) + REST_ASYNC_IO_ENABLED_FIELD_NUMBER: _ClassVar[int] + PROTOBUF_PYTHONIC_TYPES_ENABLED_FIELD_NUMBER: _ClassVar[int] + UNVERSIONED_PACKAGE_DISABLED_FIELD_NUMBER: _ClassVar[int] + rest_async_io_enabled: bool + protobuf_pythonic_types_enabled: bool + unversioned_package_disabled: bool + def __init__( + self, + rest_async_io_enabled: _Optional[bool] = ..., + protobuf_pythonic_types_enabled: _Optional[bool] = ..., + unversioned_package_disabled: _Optional[bool] = ..., + ) -> None: ... + + COMMON_FIELD_NUMBER: _ClassVar[int] + EXPERIMENTAL_FEATURES_FIELD_NUMBER: _ClassVar[int] + common: CommonLanguageSettings + experimental_features: PythonSettings.ExperimentalFeatures + def __init__( + self, + common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., + experimental_features: _Optional[ + _Union[PythonSettings.ExperimentalFeatures, _Mapping] + ] = ..., + ) -> None: ... + +class NodeSettings(_message.Message): + __slots__ = ("common",) + COMMON_FIELD_NUMBER: _ClassVar[int] + common: CommonLanguageSettings + def __init__( + self, common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ... + ) -> None: ... + +class DotnetSettings(_message.Message): + __slots__ = ( + "common", + "renamed_services", + "renamed_resources", + "ignored_resources", + "forced_namespace_aliases", + "handwritten_signatures", + ) + class RenamedServicesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + class RenamedResourcesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + COMMON_FIELD_NUMBER: _ClassVar[int] + RENAMED_SERVICES_FIELD_NUMBER: _ClassVar[int] + RENAMED_RESOURCES_FIELD_NUMBER: _ClassVar[int] + IGNORED_RESOURCES_FIELD_NUMBER: _ClassVar[int] + FORCED_NAMESPACE_ALIASES_FIELD_NUMBER: _ClassVar[int] + HANDWRITTEN_SIGNATURES_FIELD_NUMBER: _ClassVar[int] + common: CommonLanguageSettings + renamed_services: _containers.ScalarMap[str, str] + renamed_resources: _containers.ScalarMap[str, str] + ignored_resources: _containers.RepeatedScalarFieldContainer[str] + forced_namespace_aliases: _containers.RepeatedScalarFieldContainer[str] + handwritten_signatures: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., + renamed_services: _Optional[_Mapping[str, str]] = ..., + renamed_resources: _Optional[_Mapping[str, str]] = ..., + ignored_resources: _Optional[_Iterable[str]] = ..., + forced_namespace_aliases: _Optional[_Iterable[str]] = ..., + handwritten_signatures: _Optional[_Iterable[str]] = ..., + ) -> None: ... + +class RubySettings(_message.Message): + __slots__ = ("common",) + COMMON_FIELD_NUMBER: _ClassVar[int] + common: CommonLanguageSettings + def __init__( + self, common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ... + ) -> None: ... + +class GoSettings(_message.Message): + __slots__ = ("common", "renamed_services") + class RenamedServicesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + COMMON_FIELD_NUMBER: _ClassVar[int] + RENAMED_SERVICES_FIELD_NUMBER: _ClassVar[int] + common: CommonLanguageSettings + renamed_services: _containers.ScalarMap[str, str] + def __init__( + self, + common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., + renamed_services: _Optional[_Mapping[str, str]] = ..., + ) -> None: ... + +class MethodSettings(_message.Message): + __slots__ = ("selector", "long_running", "auto_populated_fields", "batching") + class LongRunning(_message.Message): + __slots__ = ( + "initial_poll_delay", + "poll_delay_multiplier", + "max_poll_delay", + "total_poll_timeout", + ) + INITIAL_POLL_DELAY_FIELD_NUMBER: _ClassVar[int] + POLL_DELAY_MULTIPLIER_FIELD_NUMBER: _ClassVar[int] + MAX_POLL_DELAY_FIELD_NUMBER: _ClassVar[int] + TOTAL_POLL_TIMEOUT_FIELD_NUMBER: _ClassVar[int] + initial_poll_delay: _duration_pb2.Duration + poll_delay_multiplier: float + max_poll_delay: _duration_pb2.Duration + total_poll_timeout: _duration_pb2.Duration + def __init__( + self, + initial_poll_delay: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + poll_delay_multiplier: _Optional[float] = ..., + max_poll_delay: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + total_poll_timeout: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + ) -> None: ... + + SELECTOR_FIELD_NUMBER: _ClassVar[int] + LONG_RUNNING_FIELD_NUMBER: _ClassVar[int] + AUTO_POPULATED_FIELDS_FIELD_NUMBER: _ClassVar[int] + BATCHING_FIELD_NUMBER: _ClassVar[int] + selector: str + long_running: MethodSettings.LongRunning + auto_populated_fields: _containers.RepeatedScalarFieldContainer[str] + batching: BatchingConfigProto + def __init__( + self, + selector: _Optional[str] = ..., + long_running: _Optional[_Union[MethodSettings.LongRunning, _Mapping]] = ..., + auto_populated_fields: _Optional[_Iterable[str]] = ..., + batching: _Optional[_Union[BatchingConfigProto, _Mapping]] = ..., + ) -> None: ... + +class SelectiveGapicGeneration(_message.Message): + __slots__ = ("methods", "generate_omitted_as_internal") + METHODS_FIELD_NUMBER: _ClassVar[int] + GENERATE_OMITTED_AS_INTERNAL_FIELD_NUMBER: _ClassVar[int] + methods: _containers.RepeatedScalarFieldContainer[str] + generate_omitted_as_internal: bool + def __init__( + self, + methods: _Optional[_Iterable[str]] = ..., + generate_omitted_as_internal: _Optional[bool] = ..., + ) -> None: ... + +class BatchingConfigProto(_message.Message): + __slots__ = ("thresholds", "batch_descriptor") + THRESHOLDS_FIELD_NUMBER: _ClassVar[int] + BATCH_DESCRIPTOR_FIELD_NUMBER: _ClassVar[int] + thresholds: BatchingSettingsProto + batch_descriptor: BatchingDescriptorProto + def __init__( + self, + thresholds: _Optional[_Union[BatchingSettingsProto, _Mapping]] = ..., + batch_descriptor: _Optional[_Union[BatchingDescriptorProto, _Mapping]] = ..., + ) -> None: ... + +class BatchingSettingsProto(_message.Message): + __slots__ = ( + "element_count_threshold", + "request_byte_threshold", + "delay_threshold", + "element_count_limit", + "request_byte_limit", + "flow_control_element_limit", + "flow_control_byte_limit", + "flow_control_limit_exceeded_behavior", + ) + ELEMENT_COUNT_THRESHOLD_FIELD_NUMBER: _ClassVar[int] + REQUEST_BYTE_THRESHOLD_FIELD_NUMBER: _ClassVar[int] + DELAY_THRESHOLD_FIELD_NUMBER: _ClassVar[int] + ELEMENT_COUNT_LIMIT_FIELD_NUMBER: _ClassVar[int] + REQUEST_BYTE_LIMIT_FIELD_NUMBER: _ClassVar[int] + FLOW_CONTROL_ELEMENT_LIMIT_FIELD_NUMBER: _ClassVar[int] + FLOW_CONTROL_BYTE_LIMIT_FIELD_NUMBER: _ClassVar[int] + FLOW_CONTROL_LIMIT_EXCEEDED_BEHAVIOR_FIELD_NUMBER: _ClassVar[int] + element_count_threshold: int + request_byte_threshold: int + delay_threshold: _duration_pb2.Duration + element_count_limit: int + request_byte_limit: int + flow_control_element_limit: int + flow_control_byte_limit: int + flow_control_limit_exceeded_behavior: FlowControlLimitExceededBehaviorProto + def __init__( + self, + element_count_threshold: _Optional[int] = ..., + request_byte_threshold: _Optional[int] = ..., + delay_threshold: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + element_count_limit: _Optional[int] = ..., + request_byte_limit: _Optional[int] = ..., + flow_control_element_limit: _Optional[int] = ..., + flow_control_byte_limit: _Optional[int] = ..., + flow_control_limit_exceeded_behavior: _Optional[ + _Union[FlowControlLimitExceededBehaviorProto, str] + ] = ..., + ) -> None: ... + +class BatchingDescriptorProto(_message.Message): + __slots__ = ("batched_field", "discriminator_fields", "subresponse_field") + BATCHED_FIELD_FIELD_NUMBER: _ClassVar[int] + DISCRIMINATOR_FIELDS_FIELD_NUMBER: _ClassVar[int] + SUBRESPONSE_FIELD_FIELD_NUMBER: _ClassVar[int] + batched_field: str + discriminator_fields: _containers.RepeatedScalarFieldContainer[str] + subresponse_field: str + def __init__( + self, + batched_field: _Optional[str] = ..., + discriminator_fields: _Optional[_Iterable[str]] = ..., + subresponse_field: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto new file mode 100644 index 00000000000..b6792b9a50a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto @@ -0,0 +1,84 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/configchange;configchange"; +option java_multiple_files = true; +option java_outer_classname = "ConfigChangeProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Output generated from semantically comparing two versions of a service +// configuration. +// +// Includes detailed information about a field that have changed with +// applicable advice about potential consequences for the change, such as +// backwards-incompatibility. +message ConfigChange { + // Object hierarchy path to the change, with levels separated by a '.' + // character. For repeated fields, an applicable unique identifier field is + // used for the index (usually selector, name, or id). For maps, the term + // 'key' is used. If the field has no unique identifier, the numeric index + // is used. + // Examples: + // - visibility.rules[selector=="google.LibraryService.ListBooks"].restriction + // - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value + // - logging.producer_destinations[0] + string element = 1; + + // Value of the changed object in the old Service configuration, + // in JSON format. This field will not be populated if ChangeType == ADDED. + string old_value = 2; + + // Value of the changed object in the new Service configuration, + // in JSON format. This field will not be populated if ChangeType == REMOVED. + string new_value = 3; + + // The type for this change, either ADDED, REMOVED, or MODIFIED. + ChangeType change_type = 4; + + // Collection of advice provided for this change, useful for determining the + // possible impact of this change. + repeated Advice advices = 5; +} + +// Generated advice about this change, used for providing more +// information about how a change will affect the existing service. +message Advice { + // Useful description for why this advice was applied and what actions should + // be taken to mitigate any implied risks. + string description = 2; +} + +// Classifies set of possible modifications to an object in the service +// configuration. +enum ChangeType { + // No value was provided. + CHANGE_TYPE_UNSPECIFIED = 0; + + // The changed object exists in the 'new' service configuration, but not + // in the 'old' service configuration. + ADDED = 1; + + // The changed object exists in the 'old' service configuration, but not + // in the 'new' service configuration. + REMOVED = 2; + + // The changed object exists in both service configurations, but its value + // is different. + MODIFIED = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py new file mode 100644 index 00000000000..4214edfa424 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/config_change.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/config_change.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1egoogle/api/config_change.proto\x12\ngoogle.api"\x97\x01\n\x0c\x43onfigChange\x12\x0f\n\x07\x65lement\x18\x01 \x01(\t\x12\x11\n\told_value\x18\x02 \x01(\t\x12\x11\n\tnew_value\x18\x03 \x01(\t\x12+\n\x0b\x63hange_type\x18\x04 \x01(\x0e\x32\x16.google.api.ChangeType\x12#\n\x07\x61\x64vices\x18\x05 \x03(\x0b\x32\x12.google.api.Advice"\x1d\n\x06\x41\x64vice\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t*O\n\nChangeType\x12\x1b\n\x17\x43HANGE_TYPE_UNSPECIFIED\x10\x00\x12\t\n\x05\x41\x44\x44\x45\x44\x10\x01\x12\x0b\n\x07REMOVED\x10\x02\x12\x0c\n\x08MODIFIED\x10\x03\x42q\n\x0e\x63om.google.apiB\x11\x43onfigChangeProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/configchange;configchange\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.config_change_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\021ConfigChangeProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/configchange;configchange\242\002\004GAPI" + _globals["_CHANGETYPE"]._serialized_start = 231 + _globals["_CHANGETYPE"]._serialized_end = 310 + _globals["_CONFIGCHANGE"]._serialized_start = 47 + _globals["_CONFIGCHANGE"]._serialized_end = 198 + _globals["_ADVICE"]._serialized_start = 200 + _globals["_ADVICE"]._serialized_end = 229 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi new file mode 100644 index 00000000000..3c7f2c3d27f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi @@ -0,0 +1,65 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class ChangeType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + CHANGE_TYPE_UNSPECIFIED: _ClassVar[ChangeType] + ADDED: _ClassVar[ChangeType] + REMOVED: _ClassVar[ChangeType] + MODIFIED: _ClassVar[ChangeType] + +CHANGE_TYPE_UNSPECIFIED: ChangeType +ADDED: ChangeType +REMOVED: ChangeType +MODIFIED: ChangeType + +class ConfigChange(_message.Message): + __slots__ = ("element", "old_value", "new_value", "change_type", "advices") + ELEMENT_FIELD_NUMBER: _ClassVar[int] + OLD_VALUE_FIELD_NUMBER: _ClassVar[int] + NEW_VALUE_FIELD_NUMBER: _ClassVar[int] + CHANGE_TYPE_FIELD_NUMBER: _ClassVar[int] + ADVICES_FIELD_NUMBER: _ClassVar[int] + element: str + old_value: str + new_value: str + change_type: ChangeType + advices: _containers.RepeatedCompositeFieldContainer[Advice] + def __init__( + self, + element: _Optional[str] = ..., + old_value: _Optional[str] = ..., + new_value: _Optional[str] = ..., + change_type: _Optional[_Union[ChangeType, str]] = ..., + advices: _Optional[_Iterable[_Union[Advice, _Mapping]]] = ..., + ) -> None: ... + +class Advice(_message.Message): + __slots__ = ("description",) + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + description: str + def __init__(self, description: _Optional[str] = ...) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto new file mode 100644 index 00000000000..303604900b9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto @@ -0,0 +1,82 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "ConsumerProto"; +option java_package = "com.google.api"; + +// A descriptor for defining project properties for a service. One service may +// have many consumer projects, and the service may want to behave differently +// depending on some properties on the project. For example, a project may be +// associated with a school, or a business, or a government agency, a business +// type property on the project may affect how a service responds to the client. +// This descriptor defines which properties are allowed to be set on a project. +// +// Example: +// +// project_properties: +// properties: +// - name: NO_WATERMARK +// type: BOOL +// description: Allows usage of the API without watermarks. +// - name: EXTENDED_TILE_CACHE_PERIOD +// type: INT64 +message ProjectProperties { + // List of per consumer project-specific properties. + repeated Property properties = 1; +} + +// Defines project properties. +// +// API services can define properties that can be assigned to consumer projects +// so that backends can perform response customization without having to make +// additional calls or maintain additional storage. For example, Maps API +// defines properties that controls map tile cache period, or whether to embed a +// watermark in a result. +// +// These values can be set via API producer console. Only API providers can +// define and set these properties. +message Property { + // Supported data type of the property values + enum PropertyType { + // The type is unspecified, and will result in an error. + UNSPECIFIED = 0; + + // The type is `int64`. + INT64 = 1; + + // The type is `bool`. + BOOL = 2; + + // The type is `string`. + STRING = 3; + + // The type is 'double'. + DOUBLE = 4; + } + + // The name of the property (a.k.a key). + string name = 1; + + // The type of this property. + PropertyType type = 2; + + // The description of the property + string description = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py new file mode 100644 index 00000000000..05fc69243e5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/consumer.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/consumer.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x19google/api/consumer.proto\x12\ngoogle.api"=\n\x11ProjectProperties\x12(\n\nproperties\x18\x01 \x03(\x0b\x32\x14.google.api.Property"\xac\x01\n\x08Property\x12\x0c\n\x04name\x18\x01 \x01(\t\x12/\n\x04type\x18\x02 \x01(\x0e\x32!.google.api.Property.PropertyType\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"L\n\x0cPropertyType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\t\n\x05INT64\x10\x01\x12\x08\n\x04\x42OOL\x10\x02\x12\n\n\x06STRING\x10\x03\x12\n\n\x06\x44OUBLE\x10\x04\x42h\n\x0e\x63om.google.apiB\rConsumerProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.consumer_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\rConsumerProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig" + _globals["_PROJECTPROPERTIES"]._serialized_start = 41 + _globals["_PROJECTPROPERTIES"]._serialized_end = 102 + _globals["_PROPERTY"]._serialized_start = 105 + _globals["_PROPERTY"]._serialized_end = 277 + _globals["_PROPERTY_PROPERTYTYPE"]._serialized_start = 201 + _globals["_PROPERTY_PROPERTYTYPE"]._serialized_end = 277 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi new file mode 100644 index 00000000000..4e990bff7bf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi @@ -0,0 +1,62 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class ProjectProperties(_message.Message): + __slots__ = ("properties",) + PROPERTIES_FIELD_NUMBER: _ClassVar[int] + properties: _containers.RepeatedCompositeFieldContainer[Property] + def __init__( + self, properties: _Optional[_Iterable[_Union[Property, _Mapping]]] = ... + ) -> None: ... + +class Property(_message.Message): + __slots__ = ("name", "type", "description") + class PropertyType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + UNSPECIFIED: _ClassVar[Property.PropertyType] + INT64: _ClassVar[Property.PropertyType] + BOOL: _ClassVar[Property.PropertyType] + STRING: _ClassVar[Property.PropertyType] + DOUBLE: _ClassVar[Property.PropertyType] + + UNSPECIFIED: Property.PropertyType + INT64: Property.PropertyType + BOOL: Property.PropertyType + STRING: Property.PropertyType + DOUBLE: Property.PropertyType + NAME_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + name: str + type: Property.PropertyType + description: str + def __init__( + self, + name: _Optional[str] = ..., + type: _Optional[_Union[Property.PropertyType, str]] = ..., + description: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto new file mode 100644 index 00000000000..c1704f1e999 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto @@ -0,0 +1,92 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "ContextProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Context` defines which contexts an API requests. +// +// Example: +// +// context: +// rules: +// - selector: "*" +// requested: +// - google.rpc.context.ProjectContext +// - google.rpc.context.OriginContext +// +// The above specifies that all methods in the API request +// `google.rpc.context.ProjectContext` and +// `google.rpc.context.OriginContext`. +// +// Available context types are defined in package +// `google.rpc.context`. +// +// This also provides mechanism to allowlist any protobuf message extension that +// can be sent in grpc metadata using “x-goog-ext--bin” and +// “x-goog-ext--jspb” format. For example, list any service +// specific protobuf types that can appear in grpc metadata as follows in your +// yaml file: +// +// Example: +// +// context: +// rules: +// - selector: "google.example.library.v1.LibraryService.CreateBook" +// allowed_request_extensions: +// - google.foo.v1.NewExtension +// allowed_response_extensions: +// - google.foo.v1.NewExtension +// +// You can also specify extension ID instead of fully qualified extension name +// here. +message Context { + // A list of RPC context rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated ContextRule rules = 1; +} + +// A context rule provides information about the context for an individual API +// element. +message ContextRule { + // Selects the methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // A list of full type names of requested contexts, only the requested context + // will be made available to the backend. + repeated string requested = 2; + + // A list of full type names of provided contexts. It is used to support + // propagating HTTP headers and ETags from the response extension. + repeated string provided = 3; + + // A list of full type names or extension IDs of extensions allowed in grpc + // side channel from client to backend. + repeated string allowed_request_extensions = 4; + + // A list of full type names or extension IDs of extensions allowed in grpc + // side channel from backend to client. + repeated string allowed_response_extensions = 5; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py new file mode 100644 index 00000000000..d69b6772f76 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/context.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/context.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x18google/api/context.proto\x12\ngoogle.api"1\n\x07\x43ontext\x12&\n\x05rules\x18\x01 \x03(\x0b\x32\x17.google.api.ContextRule"\x8d\x01\n\x0b\x43ontextRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x11\n\trequested\x18\x02 \x03(\t\x12\x10\n\x08provided\x18\x03 \x03(\t\x12"\n\x1a\x61llowed_request_extensions\x18\x04 \x03(\t\x12#\n\x1b\x61llowed_response_extensions\x18\x05 \x03(\tBn\n\x0e\x63om.google.apiB\x0c\x43ontextProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.context_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\014ContextProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_CONTEXT"]._serialized_start = 40 + _globals["_CONTEXT"]._serialized_end = 89 + _globals["_CONTEXTRULE"]._serialized_start = 92 + _globals["_CONTEXTRULE"]._serialized_end = 233 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi new file mode 100644 index 00000000000..65612dbd1ae --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi @@ -0,0 +1,60 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Context(_message.Message): + __slots__ = ("rules",) + RULES_FIELD_NUMBER: _ClassVar[int] + rules: _containers.RepeatedCompositeFieldContainer[ContextRule] + def __init__( + self, rules: _Optional[_Iterable[_Union[ContextRule, _Mapping]]] = ... + ) -> None: ... + +class ContextRule(_message.Message): + __slots__ = ( + "selector", + "requested", + "provided", + "allowed_request_extensions", + "allowed_response_extensions", + ) + SELECTOR_FIELD_NUMBER: _ClassVar[int] + REQUESTED_FIELD_NUMBER: _ClassVar[int] + PROVIDED_FIELD_NUMBER: _ClassVar[int] + ALLOWED_REQUEST_EXTENSIONS_FIELD_NUMBER: _ClassVar[int] + ALLOWED_RESPONSE_EXTENSIONS_FIELD_NUMBER: _ClassVar[int] + selector: str + requested: _containers.RepeatedScalarFieldContainer[str] + provided: _containers.RepeatedScalarFieldContainer[str] + allowed_request_extensions: _containers.RepeatedScalarFieldContainer[str] + allowed_response_extensions: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + selector: _Optional[str] = ..., + requested: _Optional[_Iterable[str]] = ..., + provided: _Optional[_Iterable[str]] = ..., + allowed_request_extensions: _Optional[_Iterable[str]] = ..., + allowed_response_extensions: _Optional[_Iterable[str]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto new file mode 100644 index 00000000000..c0dc0cdc3d2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto @@ -0,0 +1,41 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/policy.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "ControlProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Selects and configures the service controller used by the service. +// +// Example: +// +// control: +// environment: servicecontrol.googleapis.com +message Control { + // The service controller environment to use. If empty, no control plane + // features (like quota and billing) will be enabled. The recommended value + // for most services is servicecontrol.googleapis.com. + string environment = 1; + + // Defines policies applying to the API methods of the service. + repeated MethodPolicy method_policies = 4; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py new file mode 100644 index 00000000000..d9780a126b1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/control.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/control.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.api import policy_pb2 as google_dot_api_dot_policy__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x18google/api/control.proto\x12\ngoogle.api\x1a\x17google/api/policy.proto"Q\n\x07\x43ontrol\x12\x13\n\x0b\x65nvironment\x18\x01 \x01(\t\x12\x31\n\x0fmethod_policies\x18\x04 \x03(\x0b\x32\x18.google.api.MethodPolicyBn\n\x0e\x63om.google.apiB\x0c\x43ontrolProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.control_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\014ControlProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_CONTROL"]._serialized_start = 65 + _globals["_CONTROL"]._serialized_end = 146 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi new file mode 100644 index 00000000000..789dc6c0536 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi @@ -0,0 +1,43 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +from google.api import policy_pb2 as _policy_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class Control(_message.Message): + __slots__ = ("environment", "method_policies") + ENVIRONMENT_FIELD_NUMBER: _ClassVar[int] + METHOD_POLICIES_FIELD_NUMBER: _ClassVar[int] + environment: str + method_policies: _containers.RepeatedCompositeFieldContainer[ + _policy_pb2.MethodPolicy + ] + def __init__( + self, + environment: _Optional[str] = ..., + method_policies: _Optional[ + _Iterable[_Union[_policy_pb2.MethodPolicy, _Mapping]] + ] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto new file mode 100644 index 00000000000..51cf36ef4f9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto @@ -0,0 +1,213 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/distribution;distribution"; +option java_multiple_files = true; +option java_outer_classname = "DistributionProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Distribution` contains summary statistics for a population of values. It +// optionally contains a histogram representing the distribution of those values +// across a set of buckets. +// +// The summary statistics are the count, mean, sum of the squared deviation from +// the mean, the minimum, and the maximum of the set of population of values. +// The histogram is based on a sequence of buckets and gives a count of values +// that fall into each bucket. The boundaries of the buckets are given either +// explicitly or by formulas for buckets of fixed or exponentially increasing +// widths. +// +// Although it is not forbidden, it is generally a bad idea to include +// non-finite values (infinities or NaNs) in the population of values, as this +// will render the `mean` and `sum_of_squared_deviation` fields meaningless. +message Distribution { + // The range of the population values. + message Range { + // The minimum of the population values. + double min = 1; + + // The maximum of the population values. + double max = 2; + } + + // `BucketOptions` describes the bucket boundaries used to create a histogram + // for the distribution. The buckets can be in a linear sequence, an + // exponential sequence, or each bucket can be specified explicitly. + // `BucketOptions` does not include the number of values in each bucket. + // + // A bucket has an inclusive lower bound and exclusive upper bound for the + // values that are counted for that bucket. The upper bound of a bucket must + // be strictly greater than the lower bound. The sequence of N buckets for a + // distribution consists of an underflow bucket (number 0), zero or more + // finite buckets (number 1 through N - 2) and an overflow bucket (number N - + // 1). The buckets are contiguous: the lower bound of bucket i (i > 0) is the + // same as the upper bound of bucket i - 1. The buckets span the whole range + // of finite values: lower bound of the underflow bucket is -infinity and the + // upper bound of the overflow bucket is +infinity. The finite buckets are + // so-called because both bounds are finite. + message BucketOptions { + // Specifies a linear sequence of buckets that all have the same width + // (except overflow and underflow). Each bucket represents a constant + // absolute uncertainty on the specific value in the bucket. + // + // There are `num_finite_buckets + 2` (= N) buckets. Bucket `i` has the + // following boundaries: + // + // Upper bound (0 <= i < N-1): offset + (width * i). + // + // Lower bound (1 <= i < N): offset + (width * (i - 1)). + message Linear { + // Must be greater than 0. + int32 num_finite_buckets = 1; + + // Must be greater than 0. + double width = 2; + + // Lower bound of the first bucket. + double offset = 3; + } + + // Specifies an exponential sequence of buckets that have a width that is + // proportional to the value of the lower bound. Each bucket represents a + // constant relative uncertainty on a specific value in the bucket. + // + // There are `num_finite_buckets + 2` (= N) buckets. Bucket `i` has the + // following boundaries: + // + // Upper bound (0 <= i < N-1): scale * (growth_factor ^ i). + // + // Lower bound (1 <= i < N): scale * (growth_factor ^ (i - 1)). + message Exponential { + // Must be greater than 0. + int32 num_finite_buckets = 1; + + // Must be greater than 1. + double growth_factor = 2; + + // Must be greater than 0. + double scale = 3; + } + + // Specifies a set of buckets with arbitrary widths. + // + // There are `size(bounds) + 1` (= N) buckets. Bucket `i` has the following + // boundaries: + // + // Upper bound (0 <= i < N-1): bounds[i] + // Lower bound (1 <= i < N); bounds[i - 1] + // + // The `bounds` field must contain at least one element. If `bounds` has + // only one element, then there are no finite buckets, and that single + // element is the common boundary of the overflow and underflow buckets. + message Explicit { + // The values must be monotonically increasing. + repeated double bounds = 1; + } + + // Exactly one of these three fields must be set. + oneof options { + // The linear bucket. + Linear linear_buckets = 1; + + // The exponential buckets. + Exponential exponential_buckets = 2; + + // The explicit buckets. + Explicit explicit_buckets = 3; + } + } + + // Exemplars are example points that may be used to annotate aggregated + // distribution values. They are metadata that gives information about a + // particular value added to a Distribution bucket, such as a trace ID that + // was active when a value was added. They may contain further information, + // such as a example values and timestamps, origin, etc. + message Exemplar { + // Value of the exemplar point. This value determines to which bucket the + // exemplar belongs. + double value = 1; + + // The observation (sampling) time of the above value. + google.protobuf.Timestamp timestamp = 2; + + // Contextual information about the example value. Examples are: + // + // Trace: type.googleapis.com/google.monitoring.v3.SpanContext + // + // Literal string: type.googleapis.com/google.protobuf.StringValue + // + // Labels dropped during aggregation: + // type.googleapis.com/google.monitoring.v3.DroppedLabels + // + // There may be only a single attachment of any given message type in a + // single exemplar, and this is enforced by the system. + repeated google.protobuf.Any attachments = 3; + } + + // The number of values in the population. Must be non-negative. This value + // must equal the sum of the values in `bucket_counts` if a histogram is + // provided. + int64 count = 1; + + // The arithmetic mean of the values in the population. If `count` is zero + // then this field must be zero. + double mean = 2; + + // The sum of squared deviations from the mean of the values in the + // population. For values x_i this is: + // + // Sum[i=1..n]((x_i - mean)^2) + // + // Knuth, "The Art of Computer Programming", Vol. 2, page 232, 3rd edition + // describes Welford's method for accumulating this sum in one pass. + // + // If `count` is zero then this field must be zero. + double sum_of_squared_deviation = 3; + + // If specified, contains the range of the population values. The field + // must not be present if the `count` is zero. + Range range = 4; + + // Defines the histogram bucket boundaries. If the distribution does not + // contain a histogram, then omit this field. + BucketOptions bucket_options = 6; + + // The number of values in each bucket of the histogram, as described in + // `bucket_options`. If the distribution does not have a histogram, then omit + // this field. If there is a histogram, then the sum of the values in + // `bucket_counts` must equal the value in the `count` field of the + // distribution. + // + // If present, `bucket_counts` should contain N values, where N is the number + // of buckets specified in `bucket_options`. If you supply fewer than N + // values, the remaining values are assumed to be 0. + // + // The order of the values in `bucket_counts` follows the bucket numbering + // schemes described for the three bucket types. The first value must be the + // count for the underflow bucket (number 0). The next N-2 values are the + // counts for the finite buckets (number 1 through N-2). The N'th value in + // `bucket_counts` is the count for the overflow bucket (number N-1). + repeated int64 bucket_counts = 7; + + // Must be in increasing order of `value` field. + repeated Exemplar exemplars = 10; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py new file mode 100644 index 00000000000..a1aa7aad0ce --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/distribution.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/distribution.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from opentelemetry.agent._vendor.google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1dgoogle/api/distribution.proto\x12\ngoogle.api\x1a\x19google/protobuf/any.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\xd9\x06\n\x0c\x44istribution\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12\x0c\n\x04mean\x18\x02 \x01(\x01\x12 \n\x18sum_of_squared_deviation\x18\x03 \x01(\x01\x12-\n\x05range\x18\x04 \x01(\x0b\x32\x1e.google.api.Distribution.Range\x12>\n\x0e\x62ucket_options\x18\x06 \x01(\x0b\x32&.google.api.Distribution.BucketOptions\x12\x15\n\rbucket_counts\x18\x07 \x03(\x03\x12\x34\n\texemplars\x18\n \x03(\x0b\x32!.google.api.Distribution.Exemplar\x1a!\n\x05Range\x12\x0b\n\x03min\x18\x01 \x01(\x01\x12\x0b\n\x03max\x18\x02 \x01(\x01\x1a\xb5\x03\n\rBucketOptions\x12G\n\x0elinear_buckets\x18\x01 \x01(\x0b\x32-.google.api.Distribution.BucketOptions.LinearH\x00\x12Q\n\x13\x65xponential_buckets\x18\x02 \x01(\x0b\x32\x32.google.api.Distribution.BucketOptions.ExponentialH\x00\x12K\n\x10\x65xplicit_buckets\x18\x03 \x01(\x0b\x32/.google.api.Distribution.BucketOptions.ExplicitH\x00\x1a\x43\n\x06Linear\x12\x1a\n\x12num_finite_buckets\x18\x01 \x01(\x05\x12\r\n\x05width\x18\x02 \x01(\x01\x12\x0e\n\x06offset\x18\x03 \x01(\x01\x1aO\n\x0b\x45xponential\x12\x1a\n\x12num_finite_buckets\x18\x01 \x01(\x05\x12\x15\n\rgrowth_factor\x18\x02 \x01(\x01\x12\r\n\x05scale\x18\x03 \x01(\x01\x1a\x1a\n\x08\x45xplicit\x12\x0e\n\x06\x62ounds\x18\x01 \x03(\x01\x42\t\n\x07options\x1as\n\x08\x45xemplar\x12\r\n\x05value\x18\x01 \x01(\x01\x12-\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x0b\x61ttachments\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyBq\n\x0e\x63om.google.apiB\x11\x44istributionProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/distribution;distribution\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.distribution_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\021DistributionProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/distribution;distribution\242\002\004GAPI" + _globals["_DISTRIBUTION"]._serialized_start = 106 + _globals["_DISTRIBUTION"]._serialized_end = 963 + _globals["_DISTRIBUTION_RANGE"]._serialized_start = 373 + _globals["_DISTRIBUTION_RANGE"]._serialized_end = 406 + _globals["_DISTRIBUTION_BUCKETOPTIONS"]._serialized_start = 409 + _globals["_DISTRIBUTION_BUCKETOPTIONS"]._serialized_end = 846 + _globals["_DISTRIBUTION_BUCKETOPTIONS_LINEAR"]._serialized_start = 659 + _globals["_DISTRIBUTION_BUCKETOPTIONS_LINEAR"]._serialized_end = 726 + _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPONENTIAL"]._serialized_start = 728 + _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPONENTIAL"]._serialized_end = 807 + _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPLICIT"]._serialized_start = 809 + _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPLICIT"]._serialized_end = 835 + _globals["_DISTRIBUTION_EXEMPLAR"]._serialized_start = 848 + _globals["_DISTRIBUTION_EXEMPLAR"]._serialized_end = 963 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi new file mode 100644 index 00000000000..5b3ca23e142 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi @@ -0,0 +1,147 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import timestamp_pb2 as _timestamp_pb2 +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Distribution(_message.Message): + __slots__ = ( + "count", + "mean", + "sum_of_squared_deviation", + "range", + "bucket_options", + "bucket_counts", + "exemplars", + ) + class Range(_message.Message): + __slots__ = ("min", "max") + MIN_FIELD_NUMBER: _ClassVar[int] + MAX_FIELD_NUMBER: _ClassVar[int] + min: float + max: float + def __init__( + self, min: _Optional[float] = ..., max: _Optional[float] = ... + ) -> None: ... + + class BucketOptions(_message.Message): + __slots__ = ("linear_buckets", "exponential_buckets", "explicit_buckets") + class Linear(_message.Message): + __slots__ = ("num_finite_buckets", "width", "offset") + NUM_FINITE_BUCKETS_FIELD_NUMBER: _ClassVar[int] + WIDTH_FIELD_NUMBER: _ClassVar[int] + OFFSET_FIELD_NUMBER: _ClassVar[int] + num_finite_buckets: int + width: float + offset: float + def __init__( + self, + num_finite_buckets: _Optional[int] = ..., + width: _Optional[float] = ..., + offset: _Optional[float] = ..., + ) -> None: ... + + class Exponential(_message.Message): + __slots__ = ("num_finite_buckets", "growth_factor", "scale") + NUM_FINITE_BUCKETS_FIELD_NUMBER: _ClassVar[int] + GROWTH_FACTOR_FIELD_NUMBER: _ClassVar[int] + SCALE_FIELD_NUMBER: _ClassVar[int] + num_finite_buckets: int + growth_factor: float + scale: float + def __init__( + self, + num_finite_buckets: _Optional[int] = ..., + growth_factor: _Optional[float] = ..., + scale: _Optional[float] = ..., + ) -> None: ... + + class Explicit(_message.Message): + __slots__ = ("bounds",) + BOUNDS_FIELD_NUMBER: _ClassVar[int] + bounds: _containers.RepeatedScalarFieldContainer[float] + def __init__(self, bounds: _Optional[_Iterable[float]] = ...) -> None: ... + + LINEAR_BUCKETS_FIELD_NUMBER: _ClassVar[int] + EXPONENTIAL_BUCKETS_FIELD_NUMBER: _ClassVar[int] + EXPLICIT_BUCKETS_FIELD_NUMBER: _ClassVar[int] + linear_buckets: Distribution.BucketOptions.Linear + exponential_buckets: Distribution.BucketOptions.Exponential + explicit_buckets: Distribution.BucketOptions.Explicit + def __init__( + self, + linear_buckets: _Optional[ + _Union[Distribution.BucketOptions.Linear, _Mapping] + ] = ..., + exponential_buckets: _Optional[ + _Union[Distribution.BucketOptions.Exponential, _Mapping] + ] = ..., + explicit_buckets: _Optional[ + _Union[Distribution.BucketOptions.Explicit, _Mapping] + ] = ..., + ) -> None: ... + + class Exemplar(_message.Message): + __slots__ = ("value", "timestamp", "attachments") + VALUE_FIELD_NUMBER: _ClassVar[int] + TIMESTAMP_FIELD_NUMBER: _ClassVar[int] + ATTACHMENTS_FIELD_NUMBER: _ClassVar[int] + value: float + timestamp: _timestamp_pb2.Timestamp + attachments: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] + def __init__( + self, + value: _Optional[float] = ..., + timestamp: _Optional[ + _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] + ] = ..., + attachments: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., + ) -> None: ... + + COUNT_FIELD_NUMBER: _ClassVar[int] + MEAN_FIELD_NUMBER: _ClassVar[int] + SUM_OF_SQUARED_DEVIATION_FIELD_NUMBER: _ClassVar[int] + RANGE_FIELD_NUMBER: _ClassVar[int] + BUCKET_OPTIONS_FIELD_NUMBER: _ClassVar[int] + BUCKET_COUNTS_FIELD_NUMBER: _ClassVar[int] + EXEMPLARS_FIELD_NUMBER: _ClassVar[int] + count: int + mean: float + sum_of_squared_deviation: float + range: Distribution.Range + bucket_options: Distribution.BucketOptions + bucket_counts: _containers.RepeatedScalarFieldContainer[int] + exemplars: _containers.RepeatedCompositeFieldContainer[Distribution.Exemplar] + def __init__( + self, + count: _Optional[int] = ..., + mean: _Optional[float] = ..., + sum_of_squared_deviation: _Optional[float] = ..., + range: _Optional[_Union[Distribution.Range, _Mapping]] = ..., + bucket_options: _Optional[_Union[Distribution.BucketOptions, _Mapping]] = ..., + bucket_counts: _Optional[_Iterable[int]] = ..., + exemplars: _Optional[_Iterable[_Union[Distribution.Exemplar, _Mapping]]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto new file mode 100644 index 00000000000..a730ab89a5f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto @@ -0,0 +1,168 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "DocumentationProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Documentation` provides the information for describing a service. +// +// Example: +//
documentation:
+//   summary: >
+//     The Google Calendar API gives access
+//     to most calendar features.
+//   pages:
+//   - name: Overview
+//     content: (== include google/foo/overview.md ==)
+//   - name: Tutorial
+//     content: (== include google/foo/tutorial.md ==)
+//     subpages:
+//     - name: Java
+//       content: (== include google/foo/tutorial_java.md ==)
+//   rules:
+//   - selector: google.calendar.Calendar.Get
+//     description: >
+//       ...
+//   - selector: google.calendar.Calendar.Put
+//     description: >
+//       ...
+// 
+// Documentation is provided in markdown syntax. In addition to +// standard markdown features, definition lists, tables and fenced +// code blocks are supported. Section headers can be provided and are +// interpreted relative to the section nesting of the context where +// a documentation fragment is embedded. +// +// Documentation from the IDL is merged with documentation defined +// via the config at normalization time, where documentation provided +// by config rules overrides IDL provided. +// +// A number of constructs specific to the API platform are supported +// in documentation text. +// +// In order to reference a proto element, the following +// notation can be used: +//
[fully.qualified.proto.name][]
+// To override the display text used for the link, this can be used: +//
[display text][fully.qualified.proto.name]
+// Text can be excluded from doc using the following notation: +//
(-- internal comment --)
+// +// A few directives are available in documentation. Note that +// directives must appear on a single line to be properly +// identified. The `include` directive includes a markdown file from +// an external source: +//
(== include path/to/file ==)
+// The `resource_for` directive marks a message to be the resource of +// a collection in REST view. If it is not specified, tools attempt +// to infer the resource from the operations in a collection: +//
(== resource_for v1.shelves.books ==)
+// The directive `suppress_warning` does not directly affect documentation +// and is documented together with service config validation. +message Documentation { + // A short description of what the service does. The summary must be plain + // text. It becomes the overview of the service displayed in Google Cloud + // Console. + // NOTE: This field is equivalent to the standard field `description`. + string summary = 1; + + // The top level pages for the documentation set. + repeated Page pages = 5; + + // A list of documentation rules that apply to individual API elements. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated DocumentationRule rules = 3; + + // The URL to the root of documentation. + string documentation_root_url = 4; + + // Specifies the service root url if the default one (the service name + // from the yaml file) is not suitable. This can be seen in any fully + // specified service urls as well as sections that show a base that other + // urls are relative to. + string service_root_url = 6; + + // Declares a single overview page. For example: + //
documentation:
+  //   summary: ...
+  //   overview: (== include overview.md ==)
+  // 
+ // This is a shortcut for the following declaration (using pages style): + //
documentation:
+  //   summary: ...
+  //   pages:
+  //   - name: Overview
+  //     content: (== include overview.md ==)
+  // 
+ // Note: you cannot specify both `overview` field and `pages` field. + string overview = 2; +} + +// A documentation rule provides information about individual API elements. +message DocumentationRule { + // The selector is a comma-separated list of patterns for any element such as + // a method, a field, an enum value. Each pattern is a qualified name of the + // element which may end in "*", indicating a wildcard. Wildcards are only + // allowed at the end and for a whole component of the qualified name, + // i.e. "foo.*" is ok, but not "foo.b*" or "foo.*.bar". A wildcard will match + // one or more components. To specify a default for all applicable elements, + // the whole pattern "*" is used. + string selector = 1; + + // Description of the selected proto element (e.g. a message, a method, a + // 'service' definition, or a field). Defaults to leading & trailing comments + // taken from the proto source definition of the proto element. + string description = 2; + + // Deprecation description of the selected element(s). It can be provided if + // an element is marked as `deprecated`. + string deprecation_description = 3; +} + +// Represents a documentation page. A page can contain subpages to represent +// nested documentation set structure. +message Page { + // The name of the page. It will be used as an identity of the page to + // generate URI of the page, text of the link to this page in navigation, + // etc. The full page name (start from the root page name to this page + // concatenated with `.`) can be used as reference to the page in your + // documentation. For example: + //
pages:
+  // - name: Tutorial
+  //   content: (== include tutorial.md ==)
+  //   subpages:
+  //   - name: Java
+  //     content: (== include tutorial_java.md ==)
+  // 
+ // You can reference `Java` page using Markdown reference link syntax: + // `[Java][Tutorial.Java]`. + string name = 1; + + // The Markdown content of the page. You can use ```(== include {path} + // ==)``` to include content from a Markdown file. The content can be used + // to produce the documentation page such as HTML format page. + string content = 2; + + // Subpages of this page. The order of subpages specified here will be + // honored in the generated docset. + repeated Page subpages = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py new file mode 100644 index 00000000000..29ce1122a95 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/documentation.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/documentation.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1egoogle/api/documentation.proto\x12\ngoogle.api"\xbb\x01\n\rDocumentation\x12\x0f\n\x07summary\x18\x01 \x01(\t\x12\x1f\n\x05pages\x18\x05 \x03(\x0b\x32\x10.google.api.Page\x12,\n\x05rules\x18\x03 \x03(\x0b\x32\x1d.google.api.DocumentationRule\x12\x1e\n\x16\x64ocumentation_root_url\x18\x04 \x01(\t\x12\x18\n\x10service_root_url\x18\x06 \x01(\t\x12\x10\n\x08overview\x18\x02 \x01(\t"[\n\x11\x44ocumentationRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x1f\n\x17\x64\x65precation_description\x18\x03 \x01(\t"I\n\x04Page\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\t\x12"\n\x08subpages\x18\x03 \x03(\x0b\x32\x10.google.api.PageBt\n\x0e\x63om.google.apiB\x12\x44ocumentationProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.documentation_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\022DocumentationProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_DOCUMENTATION"]._serialized_start = 47 + _globals["_DOCUMENTATION"]._serialized_end = 234 + _globals["_DOCUMENTATIONRULE"]._serialized_start = 236 + _globals["_DOCUMENTATIONRULE"]._serialized_end = 327 + _globals["_PAGE"]._serialized_start = 329 + _globals["_PAGE"]._serialized_end = 402 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi new file mode 100644 index 00000000000..f5e066d5c0b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi @@ -0,0 +1,86 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Documentation(_message.Message): + __slots__ = ( + "summary", + "pages", + "rules", + "documentation_root_url", + "service_root_url", + "overview", + ) + SUMMARY_FIELD_NUMBER: _ClassVar[int] + PAGES_FIELD_NUMBER: _ClassVar[int] + RULES_FIELD_NUMBER: _ClassVar[int] + DOCUMENTATION_ROOT_URL_FIELD_NUMBER: _ClassVar[int] + SERVICE_ROOT_URL_FIELD_NUMBER: _ClassVar[int] + OVERVIEW_FIELD_NUMBER: _ClassVar[int] + summary: str + pages: _containers.RepeatedCompositeFieldContainer[Page] + rules: _containers.RepeatedCompositeFieldContainer[DocumentationRule] + documentation_root_url: str + service_root_url: str + overview: str + def __init__( + self, + summary: _Optional[str] = ..., + pages: _Optional[_Iterable[_Union[Page, _Mapping]]] = ..., + rules: _Optional[_Iterable[_Union[DocumentationRule, _Mapping]]] = ..., + documentation_root_url: _Optional[str] = ..., + service_root_url: _Optional[str] = ..., + overview: _Optional[str] = ..., + ) -> None: ... + +class DocumentationRule(_message.Message): + __slots__ = ("selector", "description", "deprecation_description") + SELECTOR_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + DEPRECATION_DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + selector: str + description: str + deprecation_description: str + def __init__( + self, + selector: _Optional[str] = ..., + description: _Optional[str] = ..., + deprecation_description: _Optional[str] = ..., + ) -> None: ... + +class Page(_message.Message): + __slots__ = ("name", "content", "subpages") + NAME_FIELD_NUMBER: _ClassVar[int] + CONTENT_FIELD_NUMBER: _ClassVar[int] + SUBPAGES_FIELD_NUMBER: _ClassVar[int] + name: str + content: str + subpages: _containers.RepeatedCompositeFieldContainer[Page] + def __init__( + self, + name: _Optional[str] = ..., + content: _Optional[str] = ..., + subpages: _Optional[_Iterable[_Union[Page, _Mapping]]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto new file mode 100644 index 00000000000..047cf54d515 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto @@ -0,0 +1,69 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "EndpointProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Endpoint` describes a network address of a service that serves a set of +// APIs. It is commonly known as a service endpoint. A service may expose +// any number of service endpoints, and all service endpoints share the same +// service definition, such as quota limits and monitoring metrics. +// +// Example: +// +// type: google.api.Service +// name: library-example.googleapis.com +// endpoints: +// # Declares network address `https://library-example.googleapis.com` +// # for service `library-example.googleapis.com`. The `https` scheme +// # is implicit for all service endpoints. Other schemes may be +// # supported in the future. +// - name: library-example.googleapis.com +// allow_cors: false +// - name: content-staging-library-example.googleapis.com +// # Allows HTTP OPTIONS calls to be passed to the API frontend, for it +// # to decide whether the subsequent cross-origin request is allowed +// # to proceed. +// allow_cors: true +message Endpoint { + // The canonical name of this endpoint. + string name = 1; + + // Aliases for this endpoint, these will be served by the same UrlMap as the + // parent endpoint, and will be provisioned in the GCP stack for the Regional + // Endpoints. + repeated string aliases = 2; + + // The specification of an Internet routable address of API frontend that will + // handle requests to this [API + // Endpoint](https://cloud.google.com/apis/design/glossary). It should be + // either a valid IPv4 address or a fully-qualified domain name. For example, + // "8.8.8.8" or "myservice.appspot.com". + string target = 101; + + // Allowing + // [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka + // cross-domain traffic, would allow the backends served from this endpoint to + // receive and respond to HTTP OPTIONS requests. The response will be used by + // the browser to determine whether the subsequent cross-origin request is + // allowed to proceed. + bool allow_cors = 5; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py new file mode 100644 index 00000000000..7785d9750af --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/endpoint.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/endpoint.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x19google/api/endpoint.proto\x12\ngoogle.api"M\n\x08\x45ndpoint\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x61liases\x18\x02 \x03(\t\x12\x0e\n\x06target\x18\x65 \x01(\t\x12\x12\n\nallow_cors\x18\x05 \x01(\x08\x42o\n\x0e\x63om.google.apiB\rEndpointProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.endpoint_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\rEndpointProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_ENDPOINT"]._serialized_start = 41 + _globals["_ENDPOINT"]._serialized_end = 118 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi new file mode 100644 index 00000000000..8141e33c1f9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi @@ -0,0 +1,41 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Endpoint(_message.Message): + __slots__ = ("name", "aliases", "target", "allow_cors") + NAME_FIELD_NUMBER: _ClassVar[int] + ALIASES_FIELD_NUMBER: _ClassVar[int] + TARGET_FIELD_NUMBER: _ClassVar[int] + ALLOW_CORS_FIELD_NUMBER: _ClassVar[int] + name: str + aliases: _containers.RepeatedScalarFieldContainer[str] + target: str + allow_cors: bool + def __init__( + self, + name: _Optional[str] = ..., + aliases: _Optional[_Iterable[str]] = ..., + target: _Optional[str] = ..., + allow_cors: _Optional[bool] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto new file mode 100644 index 00000000000..3b4826e5f74 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto @@ -0,0 +1,807 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/error_reason;error_reason"; +option java_multiple_files = true; +option java_outer_classname = "ErrorReasonProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the supported values for `google.rpc.ErrorInfo.reason` for the +// `googleapis.com` error domain. This error domain is reserved for [Service +// Infrastructure](https://cloud.google.com/service-infrastructure/docs/overview). +// For each error info of this domain, the metadata key "service" refers to the +// logical identifier of an API service, such as "pubsub.googleapis.com". The +// "consumer" refers to the entity that consumes an API Service. It typically is +// a Google project that owns the client application or the server resource, +// such as "projects/123". Other metadata keys are specific to each error +// reason. For more information, see the definition of the specific error +// reason. +enum ErrorReason { + // Do not use this default value. + ERROR_REASON_UNSPECIFIED = 0; + + // The request is calling a disabled service for a consumer. + // + // Example of an ErrorInfo when the consumer "projects/123" contacting + // "pubsub.googleapis.com" service which is disabled: + // + // { "reason": "SERVICE_DISABLED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "pubsub.googleapis.com" + // } + // } + // + // This response indicates the "pubsub.googleapis.com" has been disabled in + // "projects/123". + SERVICE_DISABLED = 1; + + // The request whose associated billing account is disabled. + // + // Example of an ErrorInfo when the consumer "projects/123" fails to contact + // "pubsub.googleapis.com" service because the associated billing account is + // disabled: + // + // { "reason": "BILLING_DISABLED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "pubsub.googleapis.com" + // } + // } + // + // This response indicates the billing account associated has been disabled. + BILLING_DISABLED = 2; + + // The request is denied because the provided [API + // key](https://cloud.google.com/docs/authentication/api-keys) is invalid. It + // may be in a bad format, cannot be found, or has been expired). + // + // Example of an ErrorInfo when the request is contacting + // "storage.googleapis.com" service with an invalid API key: + // + // { "reason": "API_KEY_INVALID", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // } + // } + API_KEY_INVALID = 3; + + // The request is denied because it violates [API key API + // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_api_restrictions). + // + // Example of an ErrorInfo when the consumer "projects/123" fails to call the + // "storage.googleapis.com" service because this service is restricted in the + // API key: + // + // { "reason": "API_KEY_SERVICE_BLOCKED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com" + // } + // } + API_KEY_SERVICE_BLOCKED = 4; + + // The request is denied because it violates [API key HTTP + // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_http_restrictions). + // + // Example of an ErrorInfo when the consumer "projects/123" fails to call + // "storage.googleapis.com" service because the http referrer of the request + // violates API key HTTP restrictions: + // + // { "reason": "API_KEY_HTTP_REFERRER_BLOCKED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com", + // } + // } + API_KEY_HTTP_REFERRER_BLOCKED = 7; + + // The request is denied because it violates [API key IP address + // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). + // + // Example of an ErrorInfo when the consumer "projects/123" fails to call + // "storage.googleapis.com" service because the caller IP of the request + // violates API key IP address restrictions: + // + // { "reason": "API_KEY_IP_ADDRESS_BLOCKED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com", + // } + // } + API_KEY_IP_ADDRESS_BLOCKED = 8; + + // The request is denied because it violates [API key Android application + // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). + // + // Example of an ErrorInfo when the consumer "projects/123" fails to call + // "storage.googleapis.com" service because the request from the Android apps + // violates the API key Android application restrictions: + // + // { "reason": "API_KEY_ANDROID_APP_BLOCKED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com" + // } + // } + API_KEY_ANDROID_APP_BLOCKED = 9; + + // The request is denied because it violates [API key iOS application + // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). + // + // Example of an ErrorInfo when the consumer "projects/123" fails to call + // "storage.googleapis.com" service because the request from the iOS apps + // violates the API key iOS application restrictions: + // + // { "reason": "API_KEY_IOS_APP_BLOCKED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com" + // } + // } + API_KEY_IOS_APP_BLOCKED = 13; + + // The request is denied because there is not enough rate quota for the + // consumer. + // + // Example of an ErrorInfo when the consumer "projects/123" fails to contact + // "pubsub.googleapis.com" service because consumer's rate quota usage has + // reached the maximum value set for the quota limit + // "ReadsPerMinutePerProject" on the quota metric + // "pubsub.googleapis.com/read_requests": + // + // { "reason": "RATE_LIMIT_EXCEEDED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "pubsub.googleapis.com", + // "quota_metric": "pubsub.googleapis.com/read_requests", + // "quota_limit": "ReadsPerMinutePerProject" + // } + // } + // + // Example of an ErrorInfo when the consumer "projects/123" checks quota on + // the service "dataflow.googleapis.com" and hits the organization quota + // limit "DefaultRequestsPerMinutePerOrganization" on the metric + // "dataflow.googleapis.com/default_requests". + // + // { "reason": "RATE_LIMIT_EXCEEDED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "dataflow.googleapis.com", + // "quota_metric": "dataflow.googleapis.com/default_requests", + // "quota_limit": "DefaultRequestsPerMinutePerOrganization" + // } + // } + RATE_LIMIT_EXCEEDED = 5; + + // The request is denied because there is not enough resource quota for the + // consumer. + // + // Example of an ErrorInfo when the consumer "projects/123" fails to contact + // "compute.googleapis.com" service because consumer's resource quota usage + // has reached the maximum value set for the quota limit "VMsPerProject" + // on the quota metric "compute.googleapis.com/vms": + // + // { "reason": "RESOURCE_QUOTA_EXCEEDED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "compute.googleapis.com", + // "quota_metric": "compute.googleapis.com/vms", + // "quota_limit": "VMsPerProject" + // } + // } + // + // Example of an ErrorInfo when the consumer "projects/123" checks resource + // quota on the service "dataflow.googleapis.com" and hits the organization + // quota limit "jobs-per-organization" on the metric + // "dataflow.googleapis.com/job_count". + // + // { "reason": "RESOURCE_QUOTA_EXCEEDED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "dataflow.googleapis.com", + // "quota_metric": "dataflow.googleapis.com/job_count", + // "quota_limit": "jobs-per-organization" + // } + // } + RESOURCE_QUOTA_EXCEEDED = 6; + + // The request whose associated billing account address is in a tax restricted + // location, violates the local tax restrictions when creating resources in + // the restricted region. + // + // Example of an ErrorInfo when creating the Cloud Storage Bucket in the + // container "projects/123" under a tax restricted region + // "locations/asia-northeast3": + // + // { "reason": "LOCATION_TAX_POLICY_VIOLATED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com", + // "location": "locations/asia-northeast3" + // } + // } + // + // This response indicates creating the Cloud Storage Bucket in + // "locations/asia-northeast3" violates the location tax restriction. + LOCATION_TAX_POLICY_VIOLATED = 10; + + // The request is denied because the caller does not have required permission + // on the user project "projects/123" or the user project is invalid. For more + // information, check the [userProject System + // Parameters](https://cloud.google.com/apis/docs/system-parameters). + // + // Example of an ErrorInfo when the caller is calling Cloud Storage service + // with insufficient permissions on the user project: + // + // { "reason": "USER_PROJECT_DENIED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com" + // } + // } + USER_PROJECT_DENIED = 11; + + // The request is denied because the consumer "projects/123" is suspended due + // to Terms of Service(Tos) violations. Check [Project suspension + // guidelines](https://cloud.google.com/resource-manager/docs/project-suspension-guidelines) + // for more information. + // + // Example of an ErrorInfo when calling Cloud Storage service with the + // suspended consumer "projects/123": + // + // { "reason": "CONSUMER_SUSPENDED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com" + // } + // } + CONSUMER_SUSPENDED = 12; + + // The request is denied because the associated consumer is invalid. It may be + // in a bad format, cannot be found, or have been deleted. + // + // Example of an ErrorInfo when calling Cloud Storage service with the + // invalid consumer "projects/123": + // + // { "reason": "CONSUMER_INVALID", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com" + // } + // } + CONSUMER_INVALID = 14; + + // The request is denied because it violates [VPC Service + // Controls](https://cloud.google.com/vpc-service-controls/docs/overview). + // The 'uid' field is a random generated identifier that customer can use it + // to search the audit log for a request rejected by VPC Service Controls. For + // more information, please refer [VPC Service Controls + // Troubleshooting](https://cloud.google.com/vpc-service-controls/docs/troubleshooting#unique-id) + // + // Example of an ErrorInfo when the consumer "projects/123" fails to call + // Cloud Storage service because the request is prohibited by the VPC Service + // Controls. + // + // { "reason": "SECURITY_POLICY_VIOLATED", + // "domain": "googleapis.com", + // "metadata": { + // "uid": "123456789abcde", + // "consumer": "projects/123", + // "service": "storage.googleapis.com" + // } + // } + SECURITY_POLICY_VIOLATED = 15; + + // The request is denied because the provided access token has expired. + // + // Example of an ErrorInfo when the request is calling Cloud Storage service + // with an expired access token: + // + // { "reason": "ACCESS_TOKEN_EXPIRED", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // "method": "google.storage.v1.Storage.GetObject" + // } + // } + ACCESS_TOKEN_EXPIRED = 16; + + // The request is denied because the provided access token doesn't have at + // least one of the acceptable scopes required for the API. Please check + // [OAuth 2.0 Scopes for Google + // APIs](https://developers.google.com/identity/protocols/oauth2/scopes) for + // the list of the OAuth 2.0 scopes that you might need to request to access + // the API. + // + // Example of an ErrorInfo when the request is calling Cloud Storage service + // with an access token that is missing required scopes: + // + // { "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // "method": "google.storage.v1.Storage.GetObject" + // } + // } + ACCESS_TOKEN_SCOPE_INSUFFICIENT = 17; + + // The request is denied because the account associated with the provided + // access token is in an invalid state, such as disabled or deleted. + // For more information, see https://cloud.google.com/docs/authentication. + // + // Warning: For privacy reasons, the server may not be able to disclose the + // email address for some accounts. The client MUST NOT depend on the + // availability of the `email` attribute. + // + // Example of an ErrorInfo when the request is to the Cloud Storage API with + // an access token that is associated with a disabled or deleted [service + // account](http://cloud/iam/docs/service-accounts): + // + // { "reason": "ACCOUNT_STATE_INVALID", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // "method": "google.storage.v1.Storage.GetObject", + // "email": "user@123.iam.gserviceaccount.com" + // } + // } + ACCOUNT_STATE_INVALID = 18; + + // The request is denied because the type of the provided access token is not + // supported by the API being called. + // + // Example of an ErrorInfo when the request is to the Cloud Storage API with + // an unsupported token type. + // + // { "reason": "ACCESS_TOKEN_TYPE_UNSUPPORTED", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // "method": "google.storage.v1.Storage.GetObject" + // } + // } + ACCESS_TOKEN_TYPE_UNSUPPORTED = 19; + + // The request is denied because the request doesn't have any authentication + // credentials. For more information regarding the supported authentication + // strategies for Google Cloud APIs, see + // https://cloud.google.com/docs/authentication. + // + // Example of an ErrorInfo when the request is to the Cloud Storage API + // without any authentication credentials. + // + // { "reason": "CREDENTIALS_MISSING", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // "method": "google.storage.v1.Storage.GetObject" + // } + // } + CREDENTIALS_MISSING = 20; + + // The request is denied because the provided project owning the resource + // which acts as the [API + // consumer](https://cloud.google.com/apis/design/glossary#api_consumer) is + // invalid. It may be in a bad format or empty. + // + // Example of an ErrorInfo when the request is to the Cloud Functions API, + // but the offered resource project in the request in a bad format which can't + // perform the ListFunctions method. + // + // { "reason": "RESOURCE_PROJECT_INVALID", + // "domain": "googleapis.com", + // "metadata": { + // "service": "cloudfunctions.googleapis.com", + // "method": + // "google.cloud.functions.v1.CloudFunctionsService.ListFunctions" + // } + // } + RESOURCE_PROJECT_INVALID = 21; + + // The request is denied because the provided session cookie is missing, + // invalid or failed to decode. + // + // Example of an ErrorInfo when the request is calling Cloud Storage service + // with a SID cookie which can't be decoded. + // + // { "reason": "SESSION_COOKIE_INVALID", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // "method": "google.storage.v1.Storage.GetObject", + // "cookie": "SID" + // } + // } + SESSION_COOKIE_INVALID = 23; + + // The request is denied because the user is from a Google Workspace customer + // that blocks their users from accessing a particular service. + // + // Example scenario: https://support.google.com/a/answer/9197205?hl=en + // + // Example of an ErrorInfo when access to Google Cloud Storage service is + // blocked by the Google Workspace administrator: + // + // { "reason": "USER_BLOCKED_BY_ADMIN", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com", + // "method": "google.storage.v1.Storage.GetObject", + // } + // } + USER_BLOCKED_BY_ADMIN = 24; + + // The request is denied because the resource service usage is restricted + // by administrators according to the organization policy constraint. + // For more information see + // https://cloud.google.com/resource-manager/docs/organization-policy/restricting-services. + // + // Example of an ErrorInfo when access to Google Cloud Storage service is + // restricted by Resource Usage Restriction policy: + // + // { "reason": "RESOURCE_USAGE_RESTRICTION_VIOLATED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/project-123", + // "service": "storage.googleapis.com" + // } + // } + RESOURCE_USAGE_RESTRICTION_VIOLATED = 25; + + // Unimplemented. Do not use. + // + // The request is denied because it contains unsupported system parameters in + // URL query parameters or HTTP headers. For more information, + // see https://cloud.google.com/apis/docs/system-parameters + // + // Example of an ErrorInfo when access "pubsub.googleapis.com" service with + // a request header of "x-goog-user-ip": + // + // { "reason": "SYSTEM_PARAMETER_UNSUPPORTED", + // "domain": "googleapis.com", + // "metadata": { + // "service": "pubsub.googleapis.com" + // "parameter": "x-goog-user-ip" + // } + // } + SYSTEM_PARAMETER_UNSUPPORTED = 26; + + // The request is denied because it violates Org Restriction: the requested + // resource does not belong to allowed organizations specified in + // "X-Goog-Allowed-Resources" header. + // + // Example of an ErrorInfo when accessing a GCP resource that is restricted by + // Org Restriction for "pubsub.googleapis.com" service. + // + // { + // reason: "ORG_RESTRICTION_VIOLATION" + // domain: "googleapis.com" + // metadata { + // "consumer":"projects/123456" + // "service": "pubsub.googleapis.com" + // } + // } + ORG_RESTRICTION_VIOLATION = 27; + + // The request is denied because "X-Goog-Allowed-Resources" header is in a bad + // format. + // + // Example of an ErrorInfo when + // accessing "pubsub.googleapis.com" service with an invalid + // "X-Goog-Allowed-Resources" request header. + // + // { + // reason: "ORG_RESTRICTION_HEADER_INVALID" + // domain: "googleapis.com" + // metadata { + // "consumer":"projects/123456" + // "service": "pubsub.googleapis.com" + // } + // } + ORG_RESTRICTION_HEADER_INVALID = 28; + + // Unimplemented. Do not use. + // + // The request is calling a service that is not visible to the consumer. + // + // Example of an ErrorInfo when the consumer "projects/123" contacting + // "pubsub.googleapis.com" service which is not visible to the consumer. + // + // { "reason": "SERVICE_NOT_VISIBLE", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "pubsub.googleapis.com" + // } + // } + // + // This response indicates the "pubsub.googleapis.com" is not visible to + // "projects/123" (or it may not exist). + SERVICE_NOT_VISIBLE = 29; + + // The request is related to a project for which GCP access is suspended. + // + // Example of an ErrorInfo when the consumer "projects/123" fails to contact + // "pubsub.googleapis.com" service because GCP access is suspended: + // + // { "reason": "GCP_SUSPENDED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "pubsub.googleapis.com" + // } + // } + // + // This response indicates the associated GCP account has been suspended. + GCP_SUSPENDED = 30; + + // The request violates the location policies when creating resources in + // the restricted region. + // + // Example of an ErrorInfo when creating the Cloud Storage Bucket by + // "projects/123" for service storage.googleapis.com: + // + // { "reason": "LOCATION_POLICY_VIOLATED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "storage.googleapis.com", + // } + // } + // + // This response indicates creating the Cloud Storage Bucket in + // "locations/asia-northeast3" violates at least one location policy. + // The troubleshooting guidance is provided in the Help links. + LOCATION_POLICY_VIOLATED = 31; + + // The request is denied because origin request header is missing. + // + // Example of an ErrorInfo when + // accessing "pubsub.googleapis.com" service with an empty "Origin" request + // header. + // + // { + // reason: "MISSING_ORIGIN" + // domain: "googleapis.com" + // metadata { + // "consumer":"projects/123456" + // "service": "pubsub.googleapis.com" + // } + // } + MISSING_ORIGIN = 33; + + // The request is denied because the request contains more than one credential + // type that are individually acceptable, but not together. The customer + // should retry their request with only one set of credentials. + // + // Example of an ErrorInfo when + // accessing "pubsub.googleapis.com" service with overloaded credentials. + // + // { + // reason: "OVERLOADED_CREDENTIALS" + // domain: "googleapis.com" + // metadata { + // "consumer":"projects/123456" + // "service": "pubsub.googleapis.com" + // } + // } + OVERLOADED_CREDENTIALS = 34; + + // The request whose associated location violates the location org policy + // restrictions when creating resources in the restricted region. + // + // Example of an ErrorInfo when creating the Cloud Storage Bucket in the + // container "projects/123" under a restricted region + // "locations/asia-northeast3": + // + // { + // "reason": "LOCATION_ORG_POLICY_VIOLATED", + // "domain": "googleapis.com", + // "metadata": { + // "resource": "projects/123", + // "location": "locations/asia-northeast3" + // } + // } + // + // This response indicates creating the Cloud Storage Bucket in + // "locations/asia-northeast3" violates the location org policy restriction. + LOCATION_ORG_POLICY_VIOLATED = 35; + + // The request is denied because it access data of regulated customers using + // TLS 1.0 and 1.1. + // + // Example of an ErrorInfo when accessing a GCP resource "projects/123" that + // is restricted by TLS Version Restriction for "pubsub.googleapis.com" + // service. + // + // { + // "reason": "TLS_ORG_POLICY_VIOLATED", + // "domain": "googleapis.com", + // "metadata": { + // "service": "pubsub.googleapis.com" + // "resource": "projects/123", + // "policyName": "constraints/gcp.restrictTLSVersion", + // "tlsVersion": "TLS_VERSION_1" + // } + // } + TLS_ORG_POLICY_VIOLATED = 36; + + // The request is denied because the associated project has exceeded the + // emulator quota limit. + // + // Example of an ErrorInfo when the associated "projects/123" has exceeded the + // emulator quota limit. + // + // { + // "reason": "EMULATOR_QUOTA_EXCEEDED", + // "domain": "googleapis.com", + // "metadata": { + // "service": "pubsub.googleapis.com" + // "consumer": "projects/123" + // } + // } + EMULATOR_QUOTA_EXCEEDED = 38; + + // The request is denied because the associated application credential header + // is invalid for an Android applications. + // + // Example of an ErrorInfo when the request from an Android application to the + // "pubsub.googleapis.com" with an invalid application credential header. + // + // { + // "reason": "CREDENTIAL_ANDROID_APP_INVALID", + // "domain": "googleapis.com", + // "metadata": { + // "service": "pubsub.googleapis.com" + // } + // } + CREDENTIAL_ANDROID_APP_INVALID = 39; + + // The request is denied because IAM permission on resource is denied. + // + // Example of an ErrorInfo when the IAM permission `aiplatform.datasets.list` + // is denied on resource `projects/123`. + // + // { + // "reason": "IAM_PERMISSION_DENIED", + // "domain": "googleapis.com", + // "metadata": { + // "resource": "projects/123" + // "permission": "aiplatform.datasets.list" + // } + // } + IAM_PERMISSION_DENIED = 41; + + // The request is denied because it contains the invalid JWT token. + // + // Example of an ErrorInfo when the request contains an invalid JWT token for + // service `storage.googleapis.com`. + // + // { + // "reason": "JWT_TOKEN_INVALID", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com" + // } + // } + JWT_TOKEN_INVALID = 42; + + // The request is denied because it contains credential with type that is + // unsupported. + // + // Example of an ErrorInfo when the request contains an unsupported credential + // type for service `storage.googleapis.com`. + // + // { + // "reason": "CREDENTIAL_TYPE_UNSUPPORTED", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com" + // } + // } + CREDENTIAL_TYPE_UNSUPPORTED = 43; + + // The request is denied because it contains unsupported account type. + // + // Example of an ErrorInfo when the request contains an unsupported account + // type for service `storage.googleapis.com`. + // + // { + // "reason": "ACCOUNT_TYPE_UNSUPPORTED", + // "domain": "googleapis.com", + // "metadata": { + // "service": "storage.googleapis.com" + // } + // } + ACCOUNT_TYPE_UNSUPPORTED = 44; + + // The request is denied because the API endpoint is restricted by + // administrators according to the organization policy constraint. + // For more information see + // https://cloud.google.com/assured-workloads/docs/restrict-endpoint-usage. + // + // Example of an ErrorInfo when access to Google Cloud Storage service is + // restricted by Restrict Endpoint Usage policy: + // + // { + // "reason": "ENDPOINT_USAGE_RESTRICTION_VIOLATED", + // "domain": "googleapis.com/policies/endpointUsageRestriction", + // "metadata": { + // "policy_name": "constraints/gcp.restrictEndpointUsage", + // "checked_value": "storage.googleapis.com" + // "consumer": "organization/123" + // "service": "storage.googleapis.com" + // } + // } + ENDPOINT_USAGE_RESTRICTION_VIOLATED = 45; + + // The request is denied because the TLS Cipher Suite is restricted by + // administrators according to the organization policy constraint. + // For more information see + // https://cloud.google.com/assured-workloads/docs/restrict-tls-cipher-suites + // + // Example of an ErrorInfo when access to Google Cloud BigQuery service is + // restricted by Restrict TLS Cipher Suites policy: + // + // { + // "reason": "TLS_CIPHER_RESTRICTION_VIOLATED", + // "domain": "googleapis.com/policies/tlsCipherRestriction", + // "metadata": { + // "policy_name": "constraints/gcp.restrictTLSCipherSuites", + // "checked_value": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + // "consumer": "organization/123" + // "service": "bigquery.googleapis.com" + // } + // } + TLS_CIPHER_RESTRICTION_VIOLATED = 46; + + // The request is denied because the MCP activation check fails. + // + // Example of an ErrorInfo when the container "projects/123" contacting + // "pubsub.googleapis.com" service which is disabled by MCP: + // + // { "reason": "MCP_SERVER_DISABLED", + // "domain": "googleapis.com", + // "metadata": { + // "consumer": "projects/123", + // "service": "pubsub.googleapis.com" + // } + // } + // + // This response indicates the "pubsub.googleapis.com" has been disabled in + // "projects/123" for MCP. + MCP_SERVER_DISABLED = 47; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py new file mode 100644 index 00000000000..59874ac81e7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/error_reason.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/error_reason.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n\x1dgoogle/api/error_reason.proto\x12\ngoogle.api*\x92\n\n\x0b\x45rrorReason\x12\x1c\n\x18\x45RROR_REASON_UNSPECIFIED\x10\x00\x12\x14\n\x10SERVICE_DISABLED\x10\x01\x12\x14\n\x10\x42ILLING_DISABLED\x10\x02\x12\x13\n\x0f\x41PI_KEY_INVALID\x10\x03\x12\x1b\n\x17\x41PI_KEY_SERVICE_BLOCKED\x10\x04\x12!\n\x1d\x41PI_KEY_HTTP_REFERRER_BLOCKED\x10\x07\x12\x1e\n\x1a\x41PI_KEY_IP_ADDRESS_BLOCKED\x10\x08\x12\x1f\n\x1b\x41PI_KEY_ANDROID_APP_BLOCKED\x10\t\x12\x1b\n\x17\x41PI_KEY_IOS_APP_BLOCKED\x10\r\x12\x17\n\x13RATE_LIMIT_EXCEEDED\x10\x05\x12\x1b\n\x17RESOURCE_QUOTA_EXCEEDED\x10\x06\x12 \n\x1cLOCATION_TAX_POLICY_VIOLATED\x10\n\x12\x17\n\x13USER_PROJECT_DENIED\x10\x0b\x12\x16\n\x12\x43ONSUMER_SUSPENDED\x10\x0c\x12\x14\n\x10\x43ONSUMER_INVALID\x10\x0e\x12\x1c\n\x18SECURITY_POLICY_VIOLATED\x10\x0f\x12\x18\n\x14\x41\x43\x43\x45SS_TOKEN_EXPIRED\x10\x10\x12#\n\x1f\x41\x43\x43\x45SS_TOKEN_SCOPE_INSUFFICIENT\x10\x11\x12\x19\n\x15\x41\x43\x43OUNT_STATE_INVALID\x10\x12\x12!\n\x1d\x41\x43\x43\x45SS_TOKEN_TYPE_UNSUPPORTED\x10\x13\x12\x17\n\x13\x43REDENTIALS_MISSING\x10\x14\x12\x1c\n\x18RESOURCE_PROJECT_INVALID\x10\x15\x12\x1a\n\x16SESSION_COOKIE_INVALID\x10\x17\x12\x19\n\x15USER_BLOCKED_BY_ADMIN\x10\x18\x12'\n#RESOURCE_USAGE_RESTRICTION_VIOLATED\x10\x19\x12 \n\x1cSYSTEM_PARAMETER_UNSUPPORTED\x10\x1a\x12\x1d\n\x19ORG_RESTRICTION_VIOLATION\x10\x1b\x12\"\n\x1eORG_RESTRICTION_HEADER_INVALID\x10\x1c\x12\x17\n\x13SERVICE_NOT_VISIBLE\x10\x1d\x12\x11\n\rGCP_SUSPENDED\x10\x1e\x12\x1c\n\x18LOCATION_POLICY_VIOLATED\x10\x1f\x12\x12\n\x0eMISSING_ORIGIN\x10!\x12\x1a\n\x16OVERLOADED_CREDENTIALS\x10\"\x12 \n\x1cLOCATION_ORG_POLICY_VIOLATED\x10#\x12\x1b\n\x17TLS_ORG_POLICY_VIOLATED\x10$\x12\x1b\n\x17\x45MULATOR_QUOTA_EXCEEDED\x10&\x12\"\n\x1e\x43REDENTIAL_ANDROID_APP_INVALID\x10'\x12\x19\n\x15IAM_PERMISSION_DENIED\x10)\x12\x15\n\x11JWT_TOKEN_INVALID\x10*\x12\x1f\n\x1b\x43REDENTIAL_TYPE_UNSUPPORTED\x10+\x12\x1c\n\x18\x41\x43\x43OUNT_TYPE_UNSUPPORTED\x10,\x12'\n#ENDPOINT_USAGE_RESTRICTION_VIOLATED\x10-\x12#\n\x1fTLS_CIPHER_RESTRICTION_VIOLATED\x10.\x12\x17\n\x13MCP_SERVER_DISABLED\x10/Bp\n\x0e\x63om.google.apiB\x10\x45rrorReasonProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/error_reason;error_reason\xa2\x02\x04GAPIb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.error_reason_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\020ErrorReasonProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/error_reason;error_reason\242\002\004GAPI" + _globals["_ERRORREASON"]._serialized_start = 46 + _globals["_ERRORREASON"]._serialized_end = 1344 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi new file mode 100644 index 00000000000..9450370e6a9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi @@ -0,0 +1,112 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class ErrorReason(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + ERROR_REASON_UNSPECIFIED: _ClassVar[ErrorReason] + SERVICE_DISABLED: _ClassVar[ErrorReason] + BILLING_DISABLED: _ClassVar[ErrorReason] + API_KEY_INVALID: _ClassVar[ErrorReason] + API_KEY_SERVICE_BLOCKED: _ClassVar[ErrorReason] + API_KEY_HTTP_REFERRER_BLOCKED: _ClassVar[ErrorReason] + API_KEY_IP_ADDRESS_BLOCKED: _ClassVar[ErrorReason] + API_KEY_ANDROID_APP_BLOCKED: _ClassVar[ErrorReason] + API_KEY_IOS_APP_BLOCKED: _ClassVar[ErrorReason] + RATE_LIMIT_EXCEEDED: _ClassVar[ErrorReason] + RESOURCE_QUOTA_EXCEEDED: _ClassVar[ErrorReason] + LOCATION_TAX_POLICY_VIOLATED: _ClassVar[ErrorReason] + USER_PROJECT_DENIED: _ClassVar[ErrorReason] + CONSUMER_SUSPENDED: _ClassVar[ErrorReason] + CONSUMER_INVALID: _ClassVar[ErrorReason] + SECURITY_POLICY_VIOLATED: _ClassVar[ErrorReason] + ACCESS_TOKEN_EXPIRED: _ClassVar[ErrorReason] + ACCESS_TOKEN_SCOPE_INSUFFICIENT: _ClassVar[ErrorReason] + ACCOUNT_STATE_INVALID: _ClassVar[ErrorReason] + ACCESS_TOKEN_TYPE_UNSUPPORTED: _ClassVar[ErrorReason] + CREDENTIALS_MISSING: _ClassVar[ErrorReason] + RESOURCE_PROJECT_INVALID: _ClassVar[ErrorReason] + SESSION_COOKIE_INVALID: _ClassVar[ErrorReason] + USER_BLOCKED_BY_ADMIN: _ClassVar[ErrorReason] + RESOURCE_USAGE_RESTRICTION_VIOLATED: _ClassVar[ErrorReason] + SYSTEM_PARAMETER_UNSUPPORTED: _ClassVar[ErrorReason] + ORG_RESTRICTION_VIOLATION: _ClassVar[ErrorReason] + ORG_RESTRICTION_HEADER_INVALID: _ClassVar[ErrorReason] + SERVICE_NOT_VISIBLE: _ClassVar[ErrorReason] + GCP_SUSPENDED: _ClassVar[ErrorReason] + LOCATION_POLICY_VIOLATED: _ClassVar[ErrorReason] + MISSING_ORIGIN: _ClassVar[ErrorReason] + OVERLOADED_CREDENTIALS: _ClassVar[ErrorReason] + LOCATION_ORG_POLICY_VIOLATED: _ClassVar[ErrorReason] + TLS_ORG_POLICY_VIOLATED: _ClassVar[ErrorReason] + EMULATOR_QUOTA_EXCEEDED: _ClassVar[ErrorReason] + CREDENTIAL_ANDROID_APP_INVALID: _ClassVar[ErrorReason] + IAM_PERMISSION_DENIED: _ClassVar[ErrorReason] + JWT_TOKEN_INVALID: _ClassVar[ErrorReason] + CREDENTIAL_TYPE_UNSUPPORTED: _ClassVar[ErrorReason] + ACCOUNT_TYPE_UNSUPPORTED: _ClassVar[ErrorReason] + ENDPOINT_USAGE_RESTRICTION_VIOLATED: _ClassVar[ErrorReason] + TLS_CIPHER_RESTRICTION_VIOLATED: _ClassVar[ErrorReason] + MCP_SERVER_DISABLED: _ClassVar[ErrorReason] + +ERROR_REASON_UNSPECIFIED: ErrorReason +SERVICE_DISABLED: ErrorReason +BILLING_DISABLED: ErrorReason +API_KEY_INVALID: ErrorReason +API_KEY_SERVICE_BLOCKED: ErrorReason +API_KEY_HTTP_REFERRER_BLOCKED: ErrorReason +API_KEY_IP_ADDRESS_BLOCKED: ErrorReason +API_KEY_ANDROID_APP_BLOCKED: ErrorReason +API_KEY_IOS_APP_BLOCKED: ErrorReason +RATE_LIMIT_EXCEEDED: ErrorReason +RESOURCE_QUOTA_EXCEEDED: ErrorReason +LOCATION_TAX_POLICY_VIOLATED: ErrorReason +USER_PROJECT_DENIED: ErrorReason +CONSUMER_SUSPENDED: ErrorReason +CONSUMER_INVALID: ErrorReason +SECURITY_POLICY_VIOLATED: ErrorReason +ACCESS_TOKEN_EXPIRED: ErrorReason +ACCESS_TOKEN_SCOPE_INSUFFICIENT: ErrorReason +ACCOUNT_STATE_INVALID: ErrorReason +ACCESS_TOKEN_TYPE_UNSUPPORTED: ErrorReason +CREDENTIALS_MISSING: ErrorReason +RESOURCE_PROJECT_INVALID: ErrorReason +SESSION_COOKIE_INVALID: ErrorReason +USER_BLOCKED_BY_ADMIN: ErrorReason +RESOURCE_USAGE_RESTRICTION_VIOLATED: ErrorReason +SYSTEM_PARAMETER_UNSUPPORTED: ErrorReason +ORG_RESTRICTION_VIOLATION: ErrorReason +ORG_RESTRICTION_HEADER_INVALID: ErrorReason +SERVICE_NOT_VISIBLE: ErrorReason +GCP_SUSPENDED: ErrorReason +LOCATION_POLICY_VIOLATED: ErrorReason +MISSING_ORIGIN: ErrorReason +OVERLOADED_CREDENTIALS: ErrorReason +LOCATION_ORG_POLICY_VIOLATED: ErrorReason +TLS_ORG_POLICY_VIOLATED: ErrorReason +EMULATOR_QUOTA_EXCEEDED: ErrorReason +CREDENTIAL_ANDROID_APP_INVALID: ErrorReason +IAM_PERMISSION_DENIED: ErrorReason +JWT_TOKEN_INVALID: ErrorReason +CREDENTIAL_TYPE_UNSUPPORTED: ErrorReason +ACCOUNT_TYPE_UNSUPPORTED: ErrorReason +ENDPOINT_USAGE_RESTRICTION_VIOLATED: ErrorReason +TLS_CIPHER_RESTRICTION_VIOLATED: ErrorReason +MCP_SERVER_DISABLED: ErrorReason diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto new file mode 100644 index 00000000000..51f4c7d447c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto @@ -0,0 +1,104 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "FieldBehaviorProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.FieldOptions { + // A designation of a specific field behavior (required, output only, etc.) + // in protobuf messages. + // + // Examples: + // + // string name = 1 [(google.api.field_behavior) = REQUIRED]; + // State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; + // google.protobuf.Duration ttl = 1 + // [(google.api.field_behavior) = INPUT_ONLY]; + // google.protobuf.Timestamp expire_time = 1 + // [(google.api.field_behavior) = OUTPUT_ONLY, + // (google.api.field_behavior) = IMMUTABLE]; + repeated google.api.FieldBehavior field_behavior = 1052; +} + +// An indicator of the behavior of a given field (for example, that a field +// is required in requests, or given as output but ignored as input). +// This **does not** change the behavior in protocol buffers itself; it only +// denotes the behavior and may affect how API tooling handles the field. +// +// Note: This enum **may** receive new values in the future. +enum FieldBehavior { + // Conventional default for enums. Do not use this. + FIELD_BEHAVIOR_UNSPECIFIED = 0; + + // Specifically denotes a field as optional. + // While all fields in protocol buffers are optional, this may be specified + // for emphasis if appropriate. + OPTIONAL = 1; + + // Denotes a field as required. + // This indicates that the field **must** be provided as part of the request, + // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + REQUIRED = 2; + + // Denotes a field as output only. + // This indicates that the field is provided in responses, but including the + // field in a request does nothing (the server *must* ignore it and + // *must not* throw an error as a result of the field's presence). + OUTPUT_ONLY = 3; + + // Denotes a field as input only. + // This indicates that the field is provided in requests, and the + // corresponding field is not included in output. + INPUT_ONLY = 4; + + // Denotes a field as immutable. + // This indicates that the field may be set once in a request to create a + // resource, but may not be changed thereafter. + IMMUTABLE = 5; + + // Denotes that a (repeated) field is an unordered list. + // This indicates that the service may provide the elements of the list + // in any arbitrary order, rather than the order the user originally + // provided. Additionally, the list's order may or may not be stable. + UNORDERED_LIST = 6; + + // Denotes that this field returns a non-empty default value if not set. + // This indicates that if the user provides the empty value in a request, + // a non-empty value will be returned. The user will not be aware of what + // non-empty value to expect. + NON_EMPTY_DEFAULT = 7; + + // Denotes that the field in a resource (a message annotated with + // google.api.resource) is used in the resource name to uniquely identify the + // resource. For AIP-compliant APIs, this should only be applied to the + // `name` field on the resource. + // + // This behavior should not be applied to references to other resources within + // the message. + // + // The identifier field of resources often have different field behavior + // depending on the request it is embedded in (e.g. for Create methods name + // is optional and unused, while for Update methods it is required). Instead + // of method-specific annotations, only `IDENTIFIER` is required. + IDENTIFIER = 8; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py new file mode 100644 index 00000000000..25b1acee045 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/field_behavior.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/field_behavior.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n\x1fgoogle/api/field_behavior.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto*\xb6\x01\n\rFieldBehavior\x12\x1e\n\x1a\x46IELD_BEHAVIOR_UNSPECIFIED\x10\x00\x12\x0c\n\x08OPTIONAL\x10\x01\x12\x0c\n\x08REQUIRED\x10\x02\x12\x0f\n\x0bOUTPUT_ONLY\x10\x03\x12\x0e\n\nINPUT_ONLY\x10\x04\x12\r\n\tIMMUTABLE\x10\x05\x12\x12\n\x0eUNORDERED_LIST\x10\x06\x12\x15\n\x11NON_EMPTY_DEFAULT\x10\x07\x12\x0e\n\nIDENTIFIER\x10\x08:Q\n\x0e\x66ield_behavior\x12\x1d.google.protobuf.FieldOptions\x18\x9c\x08 \x03(\x0e\x32\x19.google.api.FieldBehaviorBp\n\x0e\x63om.google.apiB\x12\x46ieldBehaviorProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.field_behavior_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\022FieldBehaviorProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" + _globals["_FIELDBEHAVIOR"]._serialized_start = 82 + _globals["_FIELDBEHAVIOR"]._serialized_end = 264 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi new file mode 100644 index 00000000000..c67ed0382d3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi @@ -0,0 +1,45 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class FieldBehavior(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + FIELD_BEHAVIOR_UNSPECIFIED: _ClassVar[FieldBehavior] + OPTIONAL: _ClassVar[FieldBehavior] + REQUIRED: _ClassVar[FieldBehavior] + OUTPUT_ONLY: _ClassVar[FieldBehavior] + INPUT_ONLY: _ClassVar[FieldBehavior] + IMMUTABLE: _ClassVar[FieldBehavior] + UNORDERED_LIST: _ClassVar[FieldBehavior] + NON_EMPTY_DEFAULT: _ClassVar[FieldBehavior] + IDENTIFIER: _ClassVar[FieldBehavior] + +FIELD_BEHAVIOR_UNSPECIFIED: FieldBehavior +OPTIONAL: FieldBehavior +REQUIRED: FieldBehavior +OUTPUT_ONLY: FieldBehavior +INPUT_ONLY: FieldBehavior +IMMUTABLE: FieldBehavior +UNORDERED_LIST: FieldBehavior +NON_EMPTY_DEFAULT: FieldBehavior +IDENTIFIER: FieldBehavior +FIELD_BEHAVIOR_FIELD_NUMBER: _ClassVar[int] +field_behavior: _descriptor.FieldDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto new file mode 100644 index 00000000000..64387fde139 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto @@ -0,0 +1,106 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "FieldInfoProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.FieldOptions { + // Rich semantic descriptor of an API field beyond the basic typing. + // + // Examples: + // + // string request_id = 1 [(google.api.field_info).format = UUID4]; + // string old_ip_address = 2 [(google.api.field_info).format = IPV4]; + // string new_ip_address = 3 [(google.api.field_info).format = IPV6]; + // string actual_ip_address = 4 [ + // (google.api.field_info).format = IPV4_OR_IPV6 + // ]; + // google.protobuf.Any generic_field = 5 [ + // (google.api.field_info).referenced_types = {type_name: "ActualType"}, + // (google.api.field_info).referenced_types = {type_name: "OtherType"}, + // ]; + // google.protobuf.Any generic_user_input = 5 [ + // (google.api.field_info).referenced_types = {type_name: "*"}, + // ]; + google.api.FieldInfo field_info = 291403980; +} + +// Rich semantic information of an API field beyond basic typing. +message FieldInfo { + // The standard format of a field value. The supported formats are all backed + // by either an RFC defined by the IETF or a Google-defined AIP. + enum Format { + // Default, unspecified value. + FORMAT_UNSPECIFIED = 0; + + // Universally Unique Identifier, version 4, value as defined by + // https://datatracker.ietf.org/doc/html/rfc4122. The value may be + // normalized to entirely lowercase letters. For example, the value + // `F47AC10B-58CC-0372-8567-0E02B2C3D479` would be normalized to + // `f47ac10b-58cc-0372-8567-0e02b2c3d479`. + UUID4 = 1; + + // Internet Protocol v4 value as defined by [RFC + // 791](https://datatracker.ietf.org/doc/html/rfc791). The value may be + // condensed, with leading zeros in each octet stripped. For example, + // `001.022.233.040` would be condensed to `1.22.233.40`. + IPV4 = 2; + + // Internet Protocol v6 value as defined by [RFC + // 2460](https://datatracker.ietf.org/doc/html/rfc2460). The value may be + // normalized to entirely lowercase letters with zeros compressed, following + // [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952). For example, + // the value `2001:0DB8:0::0` would be normalized to `2001:db8::`. + IPV6 = 3; + + // An IP address in either v4 or v6 format as described by the individual + // values defined herein. See the comments on the IPV4 and IPV6 types for + // allowed normalizations of each. + IPV4_OR_IPV6 = 4; + } + + // The standard format of a field value. This does not explicitly configure + // any API consumer, just documents the API's format for the field it is + // applied to. + Format format = 1; + + // The type(s) that the annotated, generic field may represent. + // + // Currently, this must only be used on fields of type `google.protobuf.Any`. + // Supporting other generic types may be considered in the future. + repeated TypeReference referenced_types = 2; +} + +// A reference to a message type, for use in [FieldInfo][google.api.FieldInfo]. +message TypeReference { + // The name of the type that the annotated, generic field may represent. + // If the type is in the same protobuf package, the value can be the simple + // message name e.g., `"MyMessage"`. Otherwise, the value must be the + // fully-qualified message name e.g., `"google.library.v1.Book"`. + // + // If the type(s) are unknown to the service (e.g. the field accepts generic + // user input), use the wildcard `"*"` to denote this behavior. + // + // See [AIP-202](https://google.aip.dev/202#type-references) for more details. + string type_name = 1; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py new file mode 100644 index 00000000000..98b495ae3b5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/field_info.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/field_info.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1bgoogle/api/field_info.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"\xc1\x01\n\tFieldInfo\x12,\n\x06\x66ormat\x18\x01 \x01(\x0e\x32\x1c.google.api.FieldInfo.Format\x12\x33\n\x10referenced_types\x18\x02 \x03(\x0b\x32\x19.google.api.TypeReference"Q\n\x06\x46ormat\x12\x16\n\x12\x46ORMAT_UNSPECIFIED\x10\x00\x12\t\n\x05UUID4\x10\x01\x12\x08\n\x04IPV4\x10\x02\x12\x08\n\x04IPV6\x10\x03\x12\x10\n\x0cIPV4_OR_IPV6\x10\x04""\n\rTypeReference\x12\x11\n\ttype_name\x18\x01 \x01(\t:L\n\nfield_info\x12\x1d.google.protobuf.FieldOptions\x18\xcc\xf1\xf9\x8a\x01 \x01(\x0b\x32\x15.google.api.FieldInfoBl\n\x0e\x63om.google.apiB\x0e\x46ieldInfoProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.field_info_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\016FieldInfoProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" + _globals["_FIELDINFO"]._serialized_start = 78 + _globals["_FIELDINFO"]._serialized_end = 271 + _globals["_FIELDINFO_FORMAT"]._serialized_start = 190 + _globals["_FIELDINFO_FORMAT"]._serialized_end = 271 + _globals["_TYPEREFERENCE"]._serialized_start = 273 + _globals["_TYPEREFERENCE"]._serialized_end = 307 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi new file mode 100644 index 00000000000..4ccc4744a7e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi @@ -0,0 +1,60 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor +FIELD_INFO_FIELD_NUMBER: _ClassVar[int] +field_info: _descriptor.FieldDescriptor + +class FieldInfo(_message.Message): + __slots__ = ("format", "referenced_types") + class Format(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + FORMAT_UNSPECIFIED: _ClassVar[FieldInfo.Format] + UUID4: _ClassVar[FieldInfo.Format] + IPV4: _ClassVar[FieldInfo.Format] + IPV6: _ClassVar[FieldInfo.Format] + IPV4_OR_IPV6: _ClassVar[FieldInfo.Format] + + FORMAT_UNSPECIFIED: FieldInfo.Format + UUID4: FieldInfo.Format + IPV4: FieldInfo.Format + IPV6: FieldInfo.Format + IPV4_OR_IPV6: FieldInfo.Format + FORMAT_FIELD_NUMBER: _ClassVar[int] + REFERENCED_TYPES_FIELD_NUMBER: _ClassVar[int] + format: FieldInfo.Format + referenced_types: _containers.RepeatedCompositeFieldContainer[TypeReference] + def __init__( + self, + format: _Optional[_Union[FieldInfo.Format, str]] = ..., + referenced_types: _Optional[_Iterable[_Union[TypeReference, _Mapping]]] = ..., + ) -> None: ... + +class TypeReference(_message.Message): + __slots__ = ("type_name",) + TYPE_NAME_FIELD_NUMBER: _ClassVar[int] + type_name: str + def __init__(self, type_name: _Optional[str] = ...) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto new file mode 100644 index 00000000000..bb3af8e56a0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto @@ -0,0 +1,370 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// - HTTP: `GET /v1/messages/123456` +// - gRPC: `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// - HTTP: `GET /v1/messages/123456?revision=2&sub.subfield=foo` +// - gRPC: `GetMessage(message_id: "123456" revision: 2 sub: +// SubMessage(subfield: "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` +// - gRPC: `UpdateMessage(message_id: "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` +// - gRPC: `UpdateMessage(message_id: "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// - HTTP: `GET /v1/messages/123456` +// - gRPC: `GetMessage(message_id: "123456")` +// +// - HTTP: `GET /v1/users/me/messages/123456` +// - gRPC: `GetMessage(user_id: "me" message_id: "123456")` +// +// Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They +// are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL +// query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP +// request body, all +// fields are passed via URL path and URL query parameters. +// +// Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// The following example selects a gRPC method and applies an `HttpRule` to it: +// +// http: +// rules: +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py new file mode 100644 index 00000000000..baed2dbed8c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/http.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/http.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x15google/api/http.proto\x12\ngoogle.api"T\n\x04Http\x12#\n\x05rules\x18\x01 \x03(\x0b\x32\x14.google.api.HttpRule\x12\'\n\x1f\x66ully_decode_reserved_expansion\x18\x02 \x01(\x08"\x81\x02\n\x08HttpRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\r\n\x03get\x18\x02 \x01(\tH\x00\x12\r\n\x03put\x18\x03 \x01(\tH\x00\x12\x0e\n\x04post\x18\x04 \x01(\tH\x00\x12\x10\n\x06\x64\x65lete\x18\x05 \x01(\tH\x00\x12\x0f\n\x05patch\x18\x06 \x01(\tH\x00\x12/\n\x06\x63ustom\x18\x08 \x01(\x0b\x32\x1d.google.api.CustomHttpPatternH\x00\x12\x0c\n\x04\x62ody\x18\x07 \x01(\t\x12\x15\n\rresponse_body\x18\x0c \x01(\t\x12\x31\n\x13\x61\x64\x64itional_bindings\x18\x0b \x03(\x0b\x32\x14.google.api.HttpRuleB\t\n\x07pattern"/\n\x11\x43ustomHttpPattern\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\tBg\n\x0e\x63om.google.apiB\tHttpProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.http_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\tHttpProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" + _globals["_HTTP"]._serialized_start = 37 + _globals["_HTTP"]._serialized_end = 121 + _globals["_HTTPRULE"]._serialized_start = 124 + _globals["_HTTPRULE"]._serialized_end = 381 + _globals["_CUSTOMHTTPPATTERN"]._serialized_start = 383 + _globals["_CUSTOMHTTPPATTERN"]._serialized_end = 430 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi new file mode 100644 index 00000000000..2dafa8fc029 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi @@ -0,0 +1,94 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Http(_message.Message): + __slots__ = ("rules", "fully_decode_reserved_expansion") + RULES_FIELD_NUMBER: _ClassVar[int] + FULLY_DECODE_RESERVED_EXPANSION_FIELD_NUMBER: _ClassVar[int] + rules: _containers.RepeatedCompositeFieldContainer[HttpRule] + fully_decode_reserved_expansion: bool + def __init__( + self, + rules: _Optional[_Iterable[_Union[HttpRule, _Mapping]]] = ..., + fully_decode_reserved_expansion: _Optional[bool] = ..., + ) -> None: ... + +class HttpRule(_message.Message): + __slots__ = ( + "selector", + "get", + "put", + "post", + "delete", + "patch", + "custom", + "body", + "response_body", + "additional_bindings", + ) + SELECTOR_FIELD_NUMBER: _ClassVar[int] + GET_FIELD_NUMBER: _ClassVar[int] + PUT_FIELD_NUMBER: _ClassVar[int] + POST_FIELD_NUMBER: _ClassVar[int] + DELETE_FIELD_NUMBER: _ClassVar[int] + PATCH_FIELD_NUMBER: _ClassVar[int] + CUSTOM_FIELD_NUMBER: _ClassVar[int] + BODY_FIELD_NUMBER: _ClassVar[int] + RESPONSE_BODY_FIELD_NUMBER: _ClassVar[int] + ADDITIONAL_BINDINGS_FIELD_NUMBER: _ClassVar[int] + selector: str + get: str + put: str + post: str + delete: str + patch: str + custom: CustomHttpPattern + body: str + response_body: str + additional_bindings: _containers.RepeatedCompositeFieldContainer[HttpRule] + def __init__( + self, + selector: _Optional[str] = ..., + get: _Optional[str] = ..., + put: _Optional[str] = ..., + post: _Optional[str] = ..., + delete: _Optional[str] = ..., + patch: _Optional[str] = ..., + custom: _Optional[_Union[CustomHttpPattern, _Mapping]] = ..., + body: _Optional[str] = ..., + response_body: _Optional[str] = ..., + additional_bindings: _Optional[_Iterable[_Union[HttpRule, _Mapping]]] = ..., + ) -> None: ... + +class CustomHttpPattern(_message.Message): + __slots__ = ("kind", "path") + KIND_FIELD_NUMBER: _ClassVar[int] + PATH_FIELD_NUMBER: _ClassVar[int] + kind: str + path: str + def __init__( + self, kind: _Optional[str] = ..., path: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto new file mode 100644 index 00000000000..3fd226a987f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto @@ -0,0 +1,80 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/any.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; +option java_multiple_files = true; +option java_outer_classname = "HttpBodyProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Message that represents an arbitrary HTTP body. It should only be used for +// payload formats that can't be represented as JSON, such as raw binary or +// an HTML page. +// +// +// This message can be used both in streaming and non-streaming API methods in +// the request as well as the response. +// +// It can be used as a top-level request field, which is convenient if one +// wants to extract parameters from either the URL or HTTP template into the +// request fields and also want access to the raw HTTP body. +// +// Example: +// +// message GetResourceRequest { +// // A unique request id. +// string request_id = 1; +// +// // The raw HTTP body is bound to this field. +// google.api.HttpBody http_body = 2; +// +// } +// +// service ResourceService { +// rpc GetResource(GetResourceRequest) +// returns (google.api.HttpBody); +// rpc UpdateResource(google.api.HttpBody) +// returns (google.protobuf.Empty); +// +// } +// +// Example with streaming methods: +// +// service CaldavService { +// rpc GetCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// rpc UpdateCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// +// } +// +// Use of this type only changes how the request and response bodies are +// handled, all other features will continue to work unchanged. +message HttpBody { + // The HTTP Content-Type header value specifying the content type of the body. + string content_type = 1; + + // The HTTP request/response body as raw binary. + bytes data = 2; + + // Application specific response metadata. Must be set in the first response + // for streaming APIs. + repeated google.protobuf.Any extensions = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py new file mode 100644 index 00000000000..78e7ba6030e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/httpbody.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/httpbody.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x19google/api/httpbody.proto\x12\ngoogle.api\x1a\x19google/protobuf/any.proto"X\n\x08HttpBody\x12\x14\n\x0c\x63ontent_type\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12(\n\nextensions\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyBe\n\x0e\x63om.google.apiB\rHttpBodyProtoP\x01Z;google.golang.org/genproto/googleapis/api/httpbody;httpbody\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.httpbody_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\rHttpBodyProtoP\001Z;google.golang.org/genproto/googleapis/api/httpbody;httpbody\242\002\004GAPI" + _globals["_HTTPBODY"]._serialized_start = 68 + _globals["_HTTPBODY"]._serialized_end = 156 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi new file mode 100644 index 00000000000..eed5062fd19 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi @@ -0,0 +1,41 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class HttpBody(_message.Message): + __slots__ = ("content_type", "data", "extensions") + CONTENT_TYPE_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + EXTENSIONS_FIELD_NUMBER: _ClassVar[int] + content_type: str + data: bytes + extensions: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] + def __init__( + self, + content_type: _Optional[str] = ..., + data: _Optional[bytes] = ..., + extensions: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto new file mode 100644 index 00000000000..5d77c708824 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto @@ -0,0 +1,47 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/label;label"; +option java_multiple_files = true; +option java_outer_classname = "LabelProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// A description of a label. +message LabelDescriptor { + // Value types that can be used as label values. + enum ValueType { + // A variable-length string. This is the default. + STRING = 0; + + // Boolean; true or false. + BOOL = 1; + + // A 64-bit signed integer. + INT64 = 2; + } + + // The label key. + string key = 1; + + // The type of data that can be assigned to the label. + ValueType value_type = 2; + + // A human-readable description for the label. + string description = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py new file mode 100644 index 00000000000..cb3a441a503 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/label.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/label.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x16google/api/label.proto\x12\ngoogle.api"\x9c\x01\n\x0fLabelDescriptor\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x39\n\nvalue_type\x18\x02 \x01(\x0e\x32%.google.api.LabelDescriptor.ValueType\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t",\n\tValueType\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x42OOL\x10\x01\x12\t\n\x05INT64\x10\x02\x42\\\n\x0e\x63om.google.apiB\nLabelProtoP\x01Z5google.golang.org/genproto/googleapis/api/label;label\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.label_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\nLabelProtoP\001Z5google.golang.org/genproto/googleapis/api/label;label\242\002\004GAPI" + _globals["_LABELDESCRIPTOR"]._serialized_start = 39 + _globals["_LABELDESCRIPTOR"]._serialized_end = 195 + _globals["_LABELDESCRIPTOR_VALUETYPE"]._serialized_start = 151 + _globals["_LABELDESCRIPTOR_VALUETYPE"]._serialized_end = 195 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi new file mode 100644 index 00000000000..ca9a0b71406 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi @@ -0,0 +1,47 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class LabelDescriptor(_message.Message): + __slots__ = ("key", "value_type", "description") + class ValueType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + STRING: _ClassVar[LabelDescriptor.ValueType] + BOOL: _ClassVar[LabelDescriptor.ValueType] + INT64: _ClassVar[LabelDescriptor.ValueType] + + STRING: LabelDescriptor.ValueType + BOOL: LabelDescriptor.ValueType + INT64: LabelDescriptor.ValueType + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_TYPE_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + key: str + value_type: LabelDescriptor.ValueType + description: str + def __init__( + self, + key: _Optional[str] = ..., + value_type: _Optional[_Union[LabelDescriptor.ValueType, str]] = ..., + description: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto new file mode 100644 index 00000000000..0fff247bd8f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto @@ -0,0 +1,72 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api;api"; +option java_multiple_files = true; +option java_outer_classname = "LaunchStageProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// The launch stage as defined by [Google Cloud Platform +// Launch Stages](https://cloud.google.com/terms/launch-stages). +enum LaunchStage { + // Do not use this default value. + LAUNCH_STAGE_UNSPECIFIED = 0; + + // The feature is not yet implemented. Users can not use it. + UNIMPLEMENTED = 6; + + // Prelaunch features are hidden from users and are only visible internally. + PRELAUNCH = 7; + + // Early Access features are limited to a closed group of testers. To use + // these features, you must sign up in advance and sign a Trusted Tester + // agreement (which includes confidentiality provisions). These features may + // be unstable, changed in backward-incompatible ways, and are not + // guaranteed to be released. + EARLY_ACCESS = 1; + + // Alpha is a limited availability test for releases before they are cleared + // for widespread use. By Alpha, all significant design issues are resolved + // and we are in the process of verifying functionality. Alpha customers + // need to apply for access, agree to applicable terms, and have their + // projects allowlisted. Alpha releases don't have to be feature complete, + // no SLAs are provided, and there are no technical support obligations, but + // they will be far enough along that customers can actually use them in + // test environments or for limited-use tests -- just like they would in + // normal production cases. + ALPHA = 2; + + // Beta is the point at which we are ready to open a release for any + // customer to use. There are no SLA or technical support obligations in a + // Beta release. Products will be complete from a feature perspective, but + // may have some open outstanding issues. Beta releases are suitable for + // limited production use cases. + BETA = 3; + + // GA features are open to all developers and are considered stable and + // fully qualified for production use. + GA = 4; + + // Deprecated features are scheduled to be shut down and removed. For more + // information, see the "Deprecation Policy" section of our [Terms of + // Service](https://cloud.google.com/terms/) + // and the [Google Cloud Platform Subject to the Deprecation + // Policy](https://cloud.google.com/terms/deprecation) documentation. + DEPRECATED = 5; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py new file mode 100644 index 00000000000..7e0bc0586a9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/launch_stage.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/launch_stage.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n\x1dgoogle/api/launch_stage.proto\x12\ngoogle.api*\x8c\x01\n\x0bLaunchStage\x12\x1c\n\x18LAUNCH_STAGE_UNSPECIFIED\x10\x00\x12\x11\n\rUNIMPLEMENTED\x10\x06\x12\r\n\tPRELAUNCH\x10\x07\x12\x10\n\x0c\x45\x41RLY_ACCESS\x10\x01\x12\t\n\x05\x41LPHA\x10\x02\x12\x08\n\x04\x42\x45TA\x10\x03\x12\x06\n\x02GA\x10\x04\x12\x0e\n\nDEPRECATED\x10\x05\x42Z\n\x0e\x63om.google.apiB\x10LaunchStageProtoP\x01Z-google.golang.org/genproto/googleapis/api;api\xa2\x02\x04GAPIb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.launch_stage_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\020LaunchStageProtoP\001Z-google.golang.org/genproto/googleapis/api;api\242\002\004GAPI" + _globals["_LAUNCHSTAGE"]._serialized_start = 46 + _globals["_LAUNCHSTAGE"]._serialized_end = 186 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi new file mode 100644 index 00000000000..bdbe119a889 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class LaunchStage(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + LAUNCH_STAGE_UNSPECIFIED: _ClassVar[LaunchStage] + UNIMPLEMENTED: _ClassVar[LaunchStage] + PRELAUNCH: _ClassVar[LaunchStage] + EARLY_ACCESS: _ClassVar[LaunchStage] + ALPHA: _ClassVar[LaunchStage] + BETA: _ClassVar[LaunchStage] + GA: _ClassVar[LaunchStage] + DEPRECATED: _ClassVar[LaunchStage] + +LAUNCH_STAGE_UNSPECIFIED: LaunchStage +UNIMPLEMENTED: LaunchStage +PRELAUNCH: LaunchStage +EARLY_ACCESS: LaunchStage +ALPHA: LaunchStage +BETA: LaunchStage +GA: LaunchStage +DEPRECATED: LaunchStage diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto new file mode 100644 index 00000000000..2f13e72750b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto @@ -0,0 +1,54 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/label.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "LogProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// A description of a log type. Example in YAML format: +// +// - name: library.googleapis.com/activity_history +// description: The history of borrowing and returning library items. +// display_name: Activity +// labels: +// - key: /customer_id +// description: Identifier of a library customer +message LogDescriptor { + // The name of the log. It must be less than 512 characters long and can + // include the following characters: upper- and lower-case alphanumeric + // characters [A-Za-z0-9], and punctuation characters including + // slash, underscore, hyphen, period [/_-.]. + string name = 1; + + // The set of labels that are available to describe a specific log entry. + // Runtime requests that contain labels not specified here are + // considered invalid. + repeated LabelDescriptor labels = 2; + + // A human-readable description of this log. This information appears in + // the documentation and can contain details. + string description = 3; + + // The human-readable name for this log. This information appears on + // the user interface and should be concise. + string display_name = 4; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py new file mode 100644 index 00000000000..ef3f554be63 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/log.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/log.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.api import label_pb2 as google_dot_api_dot_label__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x14google/api/log.proto\x12\ngoogle.api\x1a\x16google/api/label.proto"u\n\rLogDescriptor\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x06labels\x18\x02 \x03(\x0b\x32\x1b.google.api.LabelDescriptor\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\tBj\n\x0e\x63om.google.apiB\x08LogProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.log_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\010LogProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_LOGDESCRIPTOR"]._serialized_start = 60 + _globals["_LOGDESCRIPTOR"]._serialized_end = 177 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi new file mode 100644 index 00000000000..76948cac3d3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi @@ -0,0 +1,47 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +from google.api import label_pb2 as _label_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class LogDescriptor(_message.Message): + __slots__ = ("name", "labels", "description", "display_name") + NAME_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] + name: str + labels: _containers.RepeatedCompositeFieldContainer[_label_pb2.LabelDescriptor] + description: str + display_name: str + def __init__( + self, + name: _Optional[str] = ..., + labels: _Optional[ + _Iterable[_Union[_label_pb2.LabelDescriptor, _Mapping]] + ] = ..., + description: _Optional[str] = ..., + display_name: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto new file mode 100644 index 00000000000..7a82de9acb6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto @@ -0,0 +1,81 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "LoggingProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Logging configuration of the service. +// +// The following example shows how to configure logs to be sent to the +// producer and consumer projects. In the example, the `activity_history` +// log is sent to both the producer and consumer projects, whereas the +// `purchase_history` log is only sent to the producer project. +// +// monitored_resources: +// - type: library.googleapis.com/branch +// labels: +// - key: /city +// description: The city where the library branch is located in. +// - key: /name +// description: The name of the branch. +// logs: +// - name: activity_history +// labels: +// - key: /customer_id +// - name: purchase_history +// logging: +// producer_destinations: +// - monitored_resource: library.googleapis.com/branch +// logs: +// - activity_history +// - purchase_history +// consumer_destinations: +// - monitored_resource: library.googleapis.com/branch +// logs: +// - activity_history +message Logging { + // Configuration of a specific logging destination (the producer project + // or the consumer project). + message LoggingDestination { + // The monitored resource type. The type must be defined in the + // [Service.monitored_resources][google.api.Service.monitored_resources] + // section. + string monitored_resource = 3; + + // Names of the logs to be sent to this destination. Each name must + // be defined in the [Service.logs][google.api.Service.logs] section. If the + // log name is not a domain scoped name, it will be automatically prefixed + // with the service name followed by "/". + repeated string logs = 1; + } + + // Logging configurations for sending logs to the producer project. + // There can be multiple producer destinations, each one must have a + // different monitored resource type. A log can be used in at most + // one producer destination. + repeated LoggingDestination producer_destinations = 1; + + // Logging configurations for sending logs to the consumer project. + // There can be multiple consumer destinations, each one must have a + // different monitored resource type. A log can be used in at most + // one consumer destination. + repeated LoggingDestination consumer_destinations = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py new file mode 100644 index 00000000000..22bcad2bf73 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/logging.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/logging.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x18google/api/logging.proto\x12\ngoogle.api"\xd7\x01\n\x07Logging\x12\x45\n\x15producer_destinations\x18\x01 \x03(\x0b\x32&.google.api.Logging.LoggingDestination\x12\x45\n\x15\x63onsumer_destinations\x18\x02 \x03(\x0b\x32&.google.api.Logging.LoggingDestination\x1a>\n\x12LoggingDestination\x12\x1a\n\x12monitored_resource\x18\x03 \x01(\t\x12\x0c\n\x04logs\x18\x01 \x03(\tBn\n\x0e\x63om.google.apiB\x0cLoggingProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.logging_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\014LoggingProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_LOGGING"]._serialized_start = 41 + _globals["_LOGGING"]._serialized_end = 256 + _globals["_LOGGING_LOGGINGDESTINATION"]._serialized_start = 194 + _globals["_LOGGING_LOGGINGDESTINATION"]._serialized_end = 256 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi new file mode 100644 index 00000000000..aa29c856c97 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi @@ -0,0 +1,57 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Logging(_message.Message): + __slots__ = ("producer_destinations", "consumer_destinations") + class LoggingDestination(_message.Message): + __slots__ = ("monitored_resource", "logs") + MONITORED_RESOURCE_FIELD_NUMBER: _ClassVar[int] + LOGS_FIELD_NUMBER: _ClassVar[int] + monitored_resource: str + logs: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + monitored_resource: _Optional[str] = ..., + logs: _Optional[_Iterable[str]] = ..., + ) -> None: ... + + PRODUCER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] + CONSUMER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] + producer_destinations: _containers.RepeatedCompositeFieldContainer[ + Logging.LoggingDestination + ] + consumer_destinations: _containers.RepeatedCompositeFieldContainer[ + Logging.LoggingDestination + ] + def __init__( + self, + producer_destinations: _Optional[ + _Iterable[_Union[Logging.LoggingDestination, _Mapping]] + ] = ..., + consumer_destinations: _Optional[ + _Iterable[_Union[Logging.LoggingDestination, _Mapping]] + ] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto new file mode 100644 index 00000000000..b7fb82a9bb6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto @@ -0,0 +1,287 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/label.proto"; +import "google/api/launch_stage.proto"; +import "google/protobuf/duration.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/metric;metric"; +option java_multiple_files = true; +option java_outer_classname = "MetricProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines a metric type and its schema. Once a metric descriptor is created, +// deleting or altering it stops data collection and makes the metric type's +// existing data unusable. +// +message MetricDescriptor { + // The kind of measurement. It describes how the data is reported. + // For information on setting the start time and end time based on + // the MetricKind, see [TimeInterval][google.monitoring.v3.TimeInterval]. + enum MetricKind { + // Do not use this default value. + METRIC_KIND_UNSPECIFIED = 0; + + // An instantaneous measurement of a value. + GAUGE = 1; + + // The change in a value during a time interval. + DELTA = 2; + + // A value accumulated over a time interval. Cumulative + // measurements in a time series should have the same start time + // and increasing end times, until an event resets the cumulative + // value to zero and sets a new start time for the following + // points. + CUMULATIVE = 3; + } + + // The value type of a metric. + enum ValueType { + // Do not use this default value. + VALUE_TYPE_UNSPECIFIED = 0; + + // The value is a boolean. + // This value type can be used only if the metric kind is `GAUGE`. + BOOL = 1; + + // The value is a signed 64-bit integer. + INT64 = 2; + + // The value is a double precision floating point number. + DOUBLE = 3; + + // The value is a text string. + // This value type can be used only if the metric kind is `GAUGE`. + STRING = 4; + + // The value is a [`Distribution`][google.api.Distribution]. + DISTRIBUTION = 5; + + // The value is money. + MONEY = 6; + } + + // Additional annotations that can be used to guide the usage of a metric. + message MetricDescriptorMetadata { + // The resource hierarchy level of the timeseries data of a metric. + enum TimeSeriesResourceHierarchyLevel { + // Do not use this default value. + TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED = 0; + + // Scopes a metric to a project. + PROJECT = 1; + + // Scopes a metric to an organization. + ORGANIZATION = 2; + + // Scopes a metric to a folder. + FOLDER = 3; + } + + // Deprecated. Must use the + // [MetricDescriptor.launch_stage][google.api.MetricDescriptor.launch_stage] + // instead. + LaunchStage launch_stage = 1 [deprecated = true]; + + // The sampling period of metric data points. For metrics which are written + // periodically, consecutive data points are stored at this time interval, + // excluding data loss due to errors. Metrics with a higher granularity have + // a smaller sampling period. + google.protobuf.Duration sample_period = 2; + + // The delay of data points caused by ingestion. Data points older than this + // age are guaranteed to be ingested and available to be read, excluding + // data loss due to errors. + google.protobuf.Duration ingest_delay = 3; + + // The scope of the timeseries data of the metric. + repeated TimeSeriesResourceHierarchyLevel + time_series_resource_hierarchy_level = 4; + } + + // The resource name of the metric descriptor. + string name = 1; + + // The metric type, including its DNS name prefix. The type is not + // URL-encoded. All user-defined metric types have the DNS name + // `custom.googleapis.com` or `external.googleapis.com`. Metric types should + // use a natural hierarchical grouping. For example: + // + // "custom.googleapis.com/invoice/paid/amount" + // "external.googleapis.com/prometheus/up" + // "appengine.googleapis.com/http/server/response_latencies" + string type = 8; + + // The set of labels that can be used to describe a specific + // instance of this metric type. For example, the + // `appengine.googleapis.com/http/server/response_latencies` metric + // type has a label for the HTTP response code, `response_code`, so + // you can look at latencies for successful responses or just + // for responses that failed. + repeated LabelDescriptor labels = 2; + + // Whether the metric records instantaneous values, changes to a value, etc. + // Some combinations of `metric_kind` and `value_type` might not be supported. + MetricKind metric_kind = 3; + + // Whether the measurement is an integer, a floating-point number, etc. + // Some combinations of `metric_kind` and `value_type` might not be supported. + ValueType value_type = 4; + + // The units in which the metric value is reported. It is only applicable + // if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` + // defines the representation of the stored metric values. + // + // Different systems might scale the values to be more easily displayed (so a + // value of `0.02kBy` _might_ be displayed as `20By`, and a value of + // `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is + // `kBy`, then the value of the metric is always in thousands of bytes, no + // matter how it might be displayed. + // + // If you want a custom metric to record the exact number of CPU-seconds used + // by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is + // `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 + // CPU-seconds, then the value is written as `12005`. + // + // Alternatively, if you want a custom metric to record data in a more + // granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is + // `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), + // or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). + // + // The supported units are a subset of [The Unified Code for Units of + // Measure](https://unitsofmeasure.org/ucum.html) standard: + // + // **Basic units (UNIT)** + // + // * `bit` bit + // * `By` byte + // * `s` second + // * `min` minute + // * `h` hour + // * `d` day + // * `1` dimensionless + // + // **Prefixes (PREFIX)** + // + // * `k` kilo (10^3) + // * `M` mega (10^6) + // * `G` giga (10^9) + // * `T` tera (10^12) + // * `P` peta (10^15) + // * `E` exa (10^18) + // * `Z` zetta (10^21) + // * `Y` yotta (10^24) + // + // * `m` milli (10^-3) + // * `u` micro (10^-6) + // * `n` nano (10^-9) + // * `p` pico (10^-12) + // * `f` femto (10^-15) + // * `a` atto (10^-18) + // * `z` zepto (10^-21) + // * `y` yocto (10^-24) + // + // * `Ki` kibi (2^10) + // * `Mi` mebi (2^20) + // * `Gi` gibi (2^30) + // * `Ti` tebi (2^40) + // * `Pi` pebi (2^50) + // + // **Grammar** + // + // The grammar also includes these connectors: + // + // * `/` division or ratio (as an infix operator). For examples, + // `kBy/{email}` or `MiBy/10ms` (although you should almost never + // have `/s` in a metric `unit`; rates should always be computed at + // query time from the underlying cumulative or delta value). + // * `.` multiplication or composition (as an infix operator). For + // examples, `GBy.d` or `k{watt}.h`. + // + // The grammar for a unit is as follows: + // + // Expression = Component { "." Component } { "/" Component } ; + // + // Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] + // | Annotation + // | "1" + // ; + // + // Annotation = "{" NAME "}" ; + // + // Notes: + // + // * `Annotation` is just a comment if it follows a `UNIT`. If the annotation + // is used alone, then the unit is equivalent to `1`. For examples, + // `{request}/s == 1/s`, `By{transmitted}/s == By/s`. + // * `NAME` is a sequence of non-blank printable ASCII characters not + // containing `{` or `}`. + // * `1` represents a unitary [dimensionless + // unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such + // as in `1/s`. It is typically used when none of the basic units are + // appropriate. For example, "new users per day" can be represented as + // `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new + // users). Alternatively, "thousands of page views per day" would be + // represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric + // value of `5.3` would mean "5300 page views per day"). + // * `%` represents dimensionless value of 1/100, and annotates values giving + // a percentage (so the metric values are typically in the range of 0..100, + // and a metric value `3` means "3 percent"). + // * `10^2.%` indicates a metric contains a ratio, typically in the range + // 0..1, that will be multiplied by 100 and displayed as a percentage + // (so a metric value `0.03` means "3 percent"). + string unit = 5; + + // A detailed description of the metric, which can be used in documentation. + string description = 6; + + // A concise name for the metric, which can be displayed in user interfaces. + // Use sentence case without an ending period, for example "Request count". + // This field is optional but it is recommended to be set for any metrics + // associated with user-visible concepts, such as Quota. + string display_name = 7; + + // Optional. Metadata which can be used to guide usage of the metric. + MetricDescriptorMetadata metadata = 10; + + // Optional. The launch stage of the metric definition. + LaunchStage launch_stage = 12; + + // Read-only. If present, then a [time + // series][google.monitoring.v3.TimeSeries], which is identified partially by + // a metric type and a + // [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that + // is associated with this metric type can only be associated with one of the + // monitored resource types listed here. + repeated string monitored_resource_types = 13; +} + +// A specific metric, identified by specifying values for all of the +// labels of a [`MetricDescriptor`][google.api.MetricDescriptor]. +message Metric { + // An existing metric type, see + // [google.api.MetricDescriptor][google.api.MetricDescriptor]. For example, + // `custom.googleapis.com/invoice/paid/amount`. + string type = 3; + + // The set of label values that uniquely identify this metric. All + // labels listed in the `MetricDescriptor` must be assigned values. + map labels = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py new file mode 100644 index 00000000000..97d2225df82 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/metric.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/metric.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 + +from opentelemetry.agent._vendor.google.api import label_pb2 as google_dot_api_dot_label__pb2 +from opentelemetry.agent._vendor.google.api import launch_stage_pb2 as google_dot_api_dot_launch__stage__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x17google/api/metric.proto\x12\ngoogle.api\x1a\x16google/api/label.proto\x1a\x1dgoogle/api/launch_stage.proto\x1a\x1egoogle/protobuf/duration.proto"\xac\x08\n\x10MetricDescriptor\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x08 \x01(\t\x12+\n\x06labels\x18\x02 \x03(\x0b\x32\x1b.google.api.LabelDescriptor\x12<\n\x0bmetric_kind\x18\x03 \x01(\x0e\x32\'.google.api.MetricDescriptor.MetricKind\x12:\n\nvalue_type\x18\x04 \x01(\x0e\x32&.google.api.MetricDescriptor.ValueType\x12\x0c\n\x04unit\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x07 \x01(\t\x12G\n\x08metadata\x18\n \x01(\x0b\x32\x35.google.api.MetricDescriptor.MetricDescriptorMetadata\x12-\n\x0claunch_stage\x18\x0c \x01(\x0e\x32\x17.google.api.LaunchStage\x12 \n\x18monitored_resource_types\x18\r \x03(\t\x1a\xbd\x03\n\x18MetricDescriptorMetadata\x12\x31\n\x0claunch_stage\x18\x01 \x01(\x0e\x32\x17.google.api.LaunchStageB\x02\x18\x01\x12\x30\n\rsample_period\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12/\n\x0cingest_delay\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x84\x01\n$time_series_resource_hierarchy_level\x18\x04 \x03(\x0e\x32V.google.api.MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel"\x83\x01\n TimeSeriesResourceHierarchyLevel\x12\x34\n0TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED\x10\x00\x12\x0b\n\x07PROJECT\x10\x01\x12\x10\n\x0cORGANIZATION\x10\x02\x12\n\n\x06\x46OLDER\x10\x03"O\n\nMetricKind\x12\x1b\n\x17METRIC_KIND_UNSPECIFIED\x10\x00\x12\t\n\x05GAUGE\x10\x01\x12\t\n\x05\x44\x45LTA\x10\x02\x12\x0e\n\nCUMULATIVE\x10\x03"q\n\tValueType\x12\x1a\n\x16VALUE_TYPE_UNSPECIFIED\x10\x00\x12\x08\n\x04\x42OOL\x10\x01\x12\t\n\x05INT64\x10\x02\x12\n\n\x06\x44OUBLE\x10\x03\x12\n\n\x06STRING\x10\x04\x12\x10\n\x0c\x44ISTRIBUTION\x10\x05\x12\t\n\x05MONEY\x10\x06"u\n\x06Metric\x12\x0c\n\x04type\x18\x03 \x01(\t\x12.\n\x06labels\x18\x02 \x03(\x0b\x32\x1e.google.api.Metric.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42_\n\x0e\x63om.google.apiB\x0bMetricProtoP\x01Z7google.golang.org/genproto/googleapis/api/metric;metric\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.metric_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\013MetricProtoP\001Z7google.golang.org/genproto/googleapis/api/metric;metric\242\002\004GAPI" + _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"].fields_by_name[ + "launch_stage" + ]._loaded_options = None + _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"].fields_by_name[ + "launch_stage" + ]._serialized_options = b"\030\001" + _globals["_METRIC_LABELSENTRY"]._loaded_options = None + _globals["_METRIC_LABELSENTRY"]._serialized_options = b"8\001" + _globals["_METRICDESCRIPTOR"]._serialized_start = 127 + _globals["_METRICDESCRIPTOR"]._serialized_end = 1195 + _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"]._serialized_start = 554 + _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"]._serialized_end = 999 + _globals[ + "_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA_TIMESERIESRESOURCEHIERARCHYLEVEL" + ]._serialized_start = 868 + _globals[ + "_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA_TIMESERIESRESOURCEHIERARCHYLEVEL" + ]._serialized_end = 999 + _globals["_METRICDESCRIPTOR_METRICKIND"]._serialized_start = 1001 + _globals["_METRICDESCRIPTOR_METRICKIND"]._serialized_end = 1080 + _globals["_METRICDESCRIPTOR_VALUETYPE"]._serialized_start = 1082 + _globals["_METRICDESCRIPTOR_VALUETYPE"]._serialized_end = 1195 + _globals["_METRIC"]._serialized_start = 1197 + _globals["_METRIC"]._serialized_end = 1314 + _globals["_METRIC_LABELSENTRY"]._serialized_start = 1269 + _globals["_METRIC_LABELSENTRY"]._serialized_end = 1314 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi new file mode 100644 index 00000000000..6da69754a09 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi @@ -0,0 +1,199 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import duration_pb2 as _duration_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +from google.api import label_pb2 as _label_pb2 +from google.api import launch_stage_pb2 as _launch_stage_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class MetricDescriptor(_message.Message): + __slots__ = ( + "name", + "type", + "labels", + "metric_kind", + "value_type", + "unit", + "description", + "display_name", + "metadata", + "launch_stage", + "monitored_resource_types", + ) + class MetricKind(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + METRIC_KIND_UNSPECIFIED: _ClassVar[MetricDescriptor.MetricKind] + GAUGE: _ClassVar[MetricDescriptor.MetricKind] + DELTA: _ClassVar[MetricDescriptor.MetricKind] + CUMULATIVE: _ClassVar[MetricDescriptor.MetricKind] + + METRIC_KIND_UNSPECIFIED: MetricDescriptor.MetricKind + GAUGE: MetricDescriptor.MetricKind + DELTA: MetricDescriptor.MetricKind + CUMULATIVE: MetricDescriptor.MetricKind + class ValueType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + VALUE_TYPE_UNSPECIFIED: _ClassVar[MetricDescriptor.ValueType] + BOOL: _ClassVar[MetricDescriptor.ValueType] + INT64: _ClassVar[MetricDescriptor.ValueType] + DOUBLE: _ClassVar[MetricDescriptor.ValueType] + STRING: _ClassVar[MetricDescriptor.ValueType] + DISTRIBUTION: _ClassVar[MetricDescriptor.ValueType] + MONEY: _ClassVar[MetricDescriptor.ValueType] + + VALUE_TYPE_UNSPECIFIED: MetricDescriptor.ValueType + BOOL: MetricDescriptor.ValueType + INT64: MetricDescriptor.ValueType + DOUBLE: MetricDescriptor.ValueType + STRING: MetricDescriptor.ValueType + DISTRIBUTION: MetricDescriptor.ValueType + MONEY: MetricDescriptor.ValueType + class MetricDescriptorMetadata(_message.Message): + __slots__ = ( + "launch_stage", + "sample_period", + "ingest_delay", + "time_series_resource_hierarchy_level", + ) + class TimeSeriesResourceHierarchyLevel( + int, metaclass=_enum_type_wrapper.EnumTypeWrapper + ): + __slots__ = () + TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED: _ClassVar[ + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ] + PROJECT: _ClassVar[ + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ] + ORGANIZATION: _ClassVar[ + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ] + FOLDER: _ClassVar[ + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ] + + TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED: ( + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ) + PROJECT: ( + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ) + ORGANIZATION: ( + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ) + FOLDER: ( + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ) + LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] + SAMPLE_PERIOD_FIELD_NUMBER: _ClassVar[int] + INGEST_DELAY_FIELD_NUMBER: _ClassVar[int] + TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_FIELD_NUMBER: _ClassVar[int] + launch_stage: _launch_stage_pb2.LaunchStage + sample_period: _duration_pb2.Duration + ingest_delay: _duration_pb2.Duration + time_series_resource_hierarchy_level: _containers.RepeatedScalarFieldContainer[ + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel + ] + def __init__( + self, + launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., + sample_period: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + ingest_delay: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + time_series_resource_hierarchy_level: _Optional[ + _Iterable[ + _Union[ + MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel, + str, + ] + ] + ] = ..., + ) -> None: ... + + NAME_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + METRIC_KIND_FIELD_NUMBER: _ClassVar[int] + VALUE_TYPE_FIELD_NUMBER: _ClassVar[int] + UNIT_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] + MONITORED_RESOURCE_TYPES_FIELD_NUMBER: _ClassVar[int] + name: str + type: str + labels: _containers.RepeatedCompositeFieldContainer[_label_pb2.LabelDescriptor] + metric_kind: MetricDescriptor.MetricKind + value_type: MetricDescriptor.ValueType + unit: str + description: str + display_name: str + metadata: MetricDescriptor.MetricDescriptorMetadata + launch_stage: _launch_stage_pb2.LaunchStage + monitored_resource_types: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + name: _Optional[str] = ..., + type: _Optional[str] = ..., + labels: _Optional[ + _Iterable[_Union[_label_pb2.LabelDescriptor, _Mapping]] + ] = ..., + metric_kind: _Optional[_Union[MetricDescriptor.MetricKind, str]] = ..., + value_type: _Optional[_Union[MetricDescriptor.ValueType, str]] = ..., + unit: _Optional[str] = ..., + description: _Optional[str] = ..., + display_name: _Optional[str] = ..., + metadata: _Optional[ + _Union[MetricDescriptor.MetricDescriptorMetadata, _Mapping] + ] = ..., + launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., + monitored_resource_types: _Optional[_Iterable[str]] = ..., + ) -> None: ... + +class Metric(_message.Message): + __slots__ = ("type", "labels") + class LabelsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + TYPE_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + type: str + labels: _containers.ScalarMap[str, str] + def __init__( + self, type: _Optional[str] = ..., labels: _Optional[_Mapping[str, str]] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto new file mode 100644 index 00000000000..eaf1f1280be --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto @@ -0,0 +1,129 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/label.proto"; +import "google/api/launch_stage.proto"; +import "google/protobuf/struct.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/monitoredres;monitoredres"; +option java_multiple_files = true; +option java_outer_classname = "MonitoredResourceProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// An object that describes the schema of a +// [MonitoredResource][google.api.MonitoredResource] object using a type name +// and a set of labels. For example, the monitored resource descriptor for +// Google Compute Engine VM instances has a type of +// `"gce_instance"` and specifies the use of the labels `"instance_id"` and +// `"zone"` to identify particular VM instances. +// +// Different APIs can support different monitored resource types. APIs generally +// provide a `list` method that returns the monitored resource descriptors used +// by the API. +// +message MonitoredResourceDescriptor { + // Optional. The resource name of the monitored resource descriptor: + // `"projects/{project_id}/monitoredResourceDescriptors/{type}"` where + // {type} is the value of the `type` field in this object and + // {project_id} is a project ID that provides API-specific context for + // accessing the type. APIs that do not use project information can use the + // resource name format `"monitoredResourceDescriptors/{type}"`. + string name = 5; + + // Required. The monitored resource type. For example, the type + // `"cloudsql_database"` represents databases in Google Cloud SQL. + // For a list of types, see [Monitored resource + // types](https://cloud.google.com/monitoring/api/resources) + // and [Logging resource + // types](https://cloud.google.com/logging/docs/api/v2/resource-list). + string type = 1; + + // Optional. A concise name for the monitored resource type that might be + // displayed in user interfaces. It should be a Title Cased Noun Phrase, + // without any article or other determiners. For example, + // `"Google Cloud SQL Database"`. + string display_name = 2; + + // Optional. A detailed description of the monitored resource type that might + // be used in documentation. + string description = 3; + + // Required. A set of labels used to describe instances of this monitored + // resource type. For example, an individual Google Cloud SQL database is + // identified by values for the labels `"database_id"` and `"zone"`. + repeated LabelDescriptor labels = 4; + + // Optional. The launch stage of the monitored resource definition. + LaunchStage launch_stage = 7; +} + +// An object representing a resource that can be used for monitoring, logging, +// billing, or other purposes. Examples include virtual machine instances, +// databases, and storage devices such as disks. The `type` field identifies a +// [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] object +// that describes the resource's schema. Information in the `labels` field +// identifies the actual resource and its attributes according to the schema. +// For example, a particular Compute Engine VM instance could be represented by +// the following object, because the +// [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] for +// `"gce_instance"` has labels +// `"project_id"`, `"instance_id"` and `"zone"`: +// +// { "type": "gce_instance", +// "labels": { "project_id": "my-project", +// "instance_id": "12345678901234", +// "zone": "us-central1-a" }} +message MonitoredResource { + // Required. The monitored resource type. This field must match + // the `type` field of a + // [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] + // object. For example, the type of a Compute Engine VM instance is + // `gce_instance`. Some descriptors include the service name in the type; for + // example, the type of a Datastream stream is + // `datastream.googleapis.com/Stream`. + string type = 1; + + // Required. Values for all of the labels listed in the associated monitored + // resource descriptor. For example, Compute Engine VM instances use the + // labels `"project_id"`, `"instance_id"`, and `"zone"`. + map labels = 2; +} + +// Auxiliary metadata for a [MonitoredResource][google.api.MonitoredResource] +// object. [MonitoredResource][google.api.MonitoredResource] objects contain the +// minimum set of information to uniquely identify a monitored resource +// instance. There is some other useful auxiliary metadata. Monitoring and +// Logging use an ingestion pipeline to extract metadata for cloud resources of +// all types, and store the metadata in this message. +message MonitoredResourceMetadata { + // Output only. Values for predefined system metadata labels. + // System labels are a kind of metadata extracted by Google, including + // "machine_image", "vpc", "subnet_id", + // "security_group", "name", etc. + // System label values can be only strings, Boolean values, or a list of + // strings. For example: + // + // { "name": "my-test-instance", + // "security_group": ["a", "b", "c"], + // "spot_instance": false } + google.protobuf.Struct system_labels = 1; + + // Output only. A map of user-defined metadata labels. + map user_labels = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py new file mode 100644 index 00000000000..2268a4cb7d7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/monitored_resource.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/monitored_resource.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 + +from opentelemetry.agent._vendor.google.api import label_pb2 as google_dot_api_dot_label__pb2 +from opentelemetry.agent._vendor.google.api import launch_stage_pb2 as google_dot_api_dot_launch__stage__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n#google/api/monitored_resource.proto\x12\ngoogle.api\x1a\x16google/api/label.proto\x1a\x1dgoogle/api/launch_stage.proto\x1a\x1cgoogle/protobuf/struct.proto"\xc0\x01\n\x1bMonitoredResourceDescriptor\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12+\n\x06labels\x18\x04 \x03(\x0b\x32\x1b.google.api.LabelDescriptor\x12-\n\x0claunch_stage\x18\x07 \x01(\x0e\x32\x17.google.api.LaunchStage"\x8b\x01\n\x11MonitoredResource\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x39\n\x06labels\x18\x02 \x03(\x0b\x32).google.api.MonitoredResource.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\xca\x01\n\x19MonitoredResourceMetadata\x12.\n\rsystem_labels\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12J\n\x0buser_labels\x18\x02 \x03(\x0b\x32\x35.google.api.MonitoredResourceMetadata.UserLabelsEntry\x1a\x31\n\x0fUserLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42v\n\x0e\x63om.google.apiB\x16MonitoredResourceProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/monitoredres;monitoredres\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.monitored_resource_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\026MonitoredResourceProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/monitoredres;monitoredres\242\002\004GAPI" + _globals["_MONITOREDRESOURCE_LABELSENTRY"]._loaded_options = None + _globals["_MONITOREDRESOURCE_LABELSENTRY"]._serialized_options = b"8\001" + _globals["_MONITOREDRESOURCEMETADATA_USERLABELSENTRY"]._loaded_options = None + _globals[ + "_MONITOREDRESOURCEMETADATA_USERLABELSENTRY" + ]._serialized_options = b"8\001" + _globals["_MONITOREDRESOURCEDESCRIPTOR"]._serialized_start = 137 + _globals["_MONITOREDRESOURCEDESCRIPTOR"]._serialized_end = 329 + _globals["_MONITOREDRESOURCE"]._serialized_start = 332 + _globals["_MONITOREDRESOURCE"]._serialized_end = 471 + _globals["_MONITOREDRESOURCE_LABELSENTRY"]._serialized_start = 426 + _globals["_MONITOREDRESOURCE_LABELSENTRY"]._serialized_end = 471 + _globals["_MONITOREDRESOURCEMETADATA"]._serialized_start = 474 + _globals["_MONITOREDRESOURCEMETADATA"]._serialized_end = 676 + _globals["_MONITOREDRESOURCEMETADATA_USERLABELSENTRY"]._serialized_start = 627 + _globals["_MONITOREDRESOURCEMETADATA_USERLABELSENTRY"]._serialized_end = 676 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi new file mode 100644 index 00000000000..5e125018a18 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi @@ -0,0 +1,104 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf.internal import containers as _containers + +from google.api import label_pb2 as _label_pb2 +from google.api import launch_stage_pb2 as _launch_stage_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class MonitoredResourceDescriptor(_message.Message): + __slots__ = ( + "name", + "type", + "display_name", + "description", + "labels", + "launch_stage", + ) + NAME_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] + name: str + type: str + display_name: str + description: str + labels: _containers.RepeatedCompositeFieldContainer[_label_pb2.LabelDescriptor] + launch_stage: _launch_stage_pb2.LaunchStage + def __init__( + self, + name: _Optional[str] = ..., + type: _Optional[str] = ..., + display_name: _Optional[str] = ..., + description: _Optional[str] = ..., + labels: _Optional[ + _Iterable[_Union[_label_pb2.LabelDescriptor, _Mapping]] + ] = ..., + launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., + ) -> None: ... + +class MonitoredResource(_message.Message): + __slots__ = ("type", "labels") + class LabelsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + TYPE_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + type: str + labels: _containers.ScalarMap[str, str] + def __init__( + self, type: _Optional[str] = ..., labels: _Optional[_Mapping[str, str]] = ... + ) -> None: ... + +class MonitoredResourceMetadata(_message.Message): + __slots__ = ("system_labels", "user_labels") + class UserLabelsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + SYSTEM_LABELS_FIELD_NUMBER: _ClassVar[int] + USER_LABELS_FIELD_NUMBER: _ClassVar[int] + system_labels: _struct_pb2.Struct + user_labels: _containers.ScalarMap[str, str] + def __init__( + self, + system_labels: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., + user_labels: _Optional[_Mapping[str, str]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto new file mode 100644 index 00000000000..b939a0ca2a5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto @@ -0,0 +1,107 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "MonitoringProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Monitoring configuration of the service. +// +// The example below shows how to configure monitored resources and metrics +// for monitoring. In the example, a monitored resource and two metrics are +// defined. The `library.googleapis.com/book/returned_count` metric is sent +// to both producer and consumer projects, whereas the +// `library.googleapis.com/book/num_overdue` metric is only sent to the +// consumer project. +// +// monitored_resources: +// - type: library.googleapis.com/Branch +// display_name: "Library Branch" +// description: "A branch of a library." +// launch_stage: GA +// labels: +// - key: resource_container +// description: "The Cloud container (ie. project id) for the Branch." +// - key: location +// description: "The location of the library branch." +// - key: branch_id +// description: "The id of the branch." +// metrics: +// - name: library.googleapis.com/book/returned_count +// display_name: "Books Returned" +// description: "The count of books that have been returned." +// launch_stage: GA +// metric_kind: DELTA +// value_type: INT64 +// unit: "1" +// labels: +// - key: customer_id +// description: "The id of the customer." +// - name: library.googleapis.com/book/num_overdue +// display_name: "Books Overdue" +// description: "The current number of overdue books." +// launch_stage: GA +// metric_kind: GAUGE +// value_type: INT64 +// unit: "1" +// labels: +// - key: customer_id +// description: "The id of the customer." +// monitoring: +// producer_destinations: +// - monitored_resource: library.googleapis.com/Branch +// metrics: +// - library.googleapis.com/book/returned_count +// consumer_destinations: +// - monitored_resource: library.googleapis.com/Branch +// metrics: +// - library.googleapis.com/book/returned_count +// - library.googleapis.com/book/num_overdue +message Monitoring { + // Configuration of a specific monitoring destination (the producer project + // or the consumer project). + message MonitoringDestination { + // The monitored resource type. The type must be defined in + // [Service.monitored_resources][google.api.Service.monitored_resources] + // section. + string monitored_resource = 1; + + // Types of the metrics to report to this monitoring destination. + // Each type must be defined in + // [Service.metrics][google.api.Service.metrics] section. + repeated string metrics = 2; + } + + // Monitoring configurations for sending metrics to the producer project. + // There can be multiple producer destinations. A monitored resource type may + // appear in multiple monitoring destinations if different aggregations are + // needed for different sets of metrics associated with that monitored + // resource type. A monitored resource and metric pair may only be used once + // in the Monitoring configuration. + repeated MonitoringDestination producer_destinations = 1; + + // Monitoring configurations for sending metrics to the consumer project. + // There can be multiple consumer destinations. A monitored resource type may + // appear in multiple monitoring destinations if different aggregations are + // needed for different sets of metrics associated with that monitored + // resource type. A monitored resource and metric pair may only be used once + // in the Monitoring configuration. + repeated MonitoringDestination consumer_destinations = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py new file mode 100644 index 00000000000..35ace5a6670 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/monitoring.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/monitoring.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1bgoogle/api/monitoring.proto\x12\ngoogle.api"\xec\x01\n\nMonitoring\x12K\n\x15producer_destinations\x18\x01 \x03(\x0b\x32,.google.api.Monitoring.MonitoringDestination\x12K\n\x15\x63onsumer_destinations\x18\x02 \x03(\x0b\x32,.google.api.Monitoring.MonitoringDestination\x1a\x44\n\x15MonitoringDestination\x12\x1a\n\x12monitored_resource\x18\x01 \x01(\t\x12\x0f\n\x07metrics\x18\x02 \x03(\tBq\n\x0e\x63om.google.apiB\x0fMonitoringProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.monitoring_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\017MonitoringProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_MONITORING"]._serialized_start = 44 + _globals["_MONITORING"]._serialized_end = 280 + _globals["_MONITORING_MONITORINGDESTINATION"]._serialized_start = 212 + _globals["_MONITORING_MONITORINGDESTINATION"]._serialized_end = 280 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi new file mode 100644 index 00000000000..b6eade82800 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi @@ -0,0 +1,57 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Monitoring(_message.Message): + __slots__ = ("producer_destinations", "consumer_destinations") + class MonitoringDestination(_message.Message): + __slots__ = ("monitored_resource", "metrics") + MONITORED_RESOURCE_FIELD_NUMBER: _ClassVar[int] + METRICS_FIELD_NUMBER: _ClassVar[int] + monitored_resource: str + metrics: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + monitored_resource: _Optional[str] = ..., + metrics: _Optional[_Iterable[str]] = ..., + ) -> None: ... + + PRODUCER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] + CONSUMER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] + producer_destinations: _containers.RepeatedCompositeFieldContainer[ + Monitoring.MonitoringDestination + ] + consumer_destinations: _containers.RepeatedCompositeFieldContainer[ + Monitoring.MonitoringDestination + ] + def __init__( + self, + producer_destinations: _Optional[ + _Iterable[_Union[Monitoring.MonitoringDestination, _Mapping]] + ] = ..., + consumer_destinations: _Optional[ + _Iterable[_Union[Monitoring.MonitoringDestination, _Mapping]] + ] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto new file mode 100644 index 00000000000..c925fdc4272 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto @@ -0,0 +1,82 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "PolicyProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.FieldOptions { + // See [FieldPolicy][]. + google.api.FieldPolicy field_policy = 158361448; +} + +extend google.protobuf.MethodOptions { + // See [MethodPolicy][]. + google.api.MethodPolicy method_policy = 161893301; +} + +// Google API Policy Annotation +// +// This message defines a simple API policy annotation that can be used to +// annotate API request and response message fields with applicable policies. +// One field may have multiple applicable policies that must all be satisfied +// before a request can be processed. This policy annotation is used to +// generate the overall policy that will be used for automatic runtime +// policy enforcement and documentation generation. +message FieldPolicy { + // Selects one or more request or response message fields to apply this + // `FieldPolicy`. + // + // When a `FieldPolicy` is used in proto annotation, the selector must + // be left as empty. The service config generator will automatically fill + // the correct value. + // + // When a `FieldPolicy` is used in service config, the selector must be a + // comma-separated string with valid request or response field paths, + // such as "foo.bar" or "foo.bar,foo.baz". + string selector = 1; + + // Specifies the required permission(s) for the resource referred to by the + // field. It requires the field contains a valid resource reference, and + // the request must pass the permission checks to proceed. For example, + // "resourcemanager.projects.get". + string resource_permission = 2; + + // Specifies the resource type for the resource referred to by the field. + string resource_type = 3; +} + +// Defines policies applying to an RPC method. +message MethodPolicy { + // Selects a method to which these policies should be enforced, for example, + // "google.pubsub.v1.Subscriber.CreateSubscription". + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + // + // NOTE: This field must not be set in the proto annotation. It will be + // automatically filled by the service config compiler . + string selector = 9; + + // Policies that are applicable to the request message. + repeated FieldPolicy request_policies = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py new file mode 100644 index 00000000000..f974f4fa200 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/policy.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/policy.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x17google/api/policy.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"S\n\x0b\x46ieldPolicy\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x1b\n\x13resource_permission\x18\x02 \x01(\t\x12\x15\n\rresource_type\x18\x03 \x01(\t"S\n\x0cMethodPolicy\x12\x10\n\x08selector\x18\t \x01(\t\x12\x31\n\x10request_policies\x18\x02 \x03(\x0b\x32\x17.google.api.FieldPolicy:O\n\x0c\x66ield_policy\x12\x1d.google.protobuf.FieldOptions\x18\xe8\xce\xc1K \x01(\x0b\x32\x17.google.api.FieldPolicy:R\n\rmethod_policy\x12\x1e.google.protobuf.MethodOptions\x18\xb5\x97\x99M \x01(\x0b\x32\x18.google.api.MethodPolicyBm\n\x0e\x63om.google.apiB\x0bPolicyProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.policy_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\013PolicyProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_FIELDPOLICY"]._serialized_start = 73 + _globals["_FIELDPOLICY"]._serialized_end = 156 + _globals["_METHODPOLICY"]._serialized_start = 158 + _globals["_METHODPOLICY"]._serialized_end = 241 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi new file mode 100644 index 00000000000..2c5fe960d98 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi @@ -0,0 +1,57 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor +FIELD_POLICY_FIELD_NUMBER: _ClassVar[int] +field_policy: _descriptor.FieldDescriptor +METHOD_POLICY_FIELD_NUMBER: _ClassVar[int] +method_policy: _descriptor.FieldDescriptor + +class FieldPolicy(_message.Message): + __slots__ = ("selector", "resource_permission", "resource_type") + SELECTOR_FIELD_NUMBER: _ClassVar[int] + RESOURCE_PERMISSION_FIELD_NUMBER: _ClassVar[int] + RESOURCE_TYPE_FIELD_NUMBER: _ClassVar[int] + selector: str + resource_permission: str + resource_type: str + def __init__( + self, + selector: _Optional[str] = ..., + resource_permission: _Optional[str] = ..., + resource_type: _Optional[str] = ..., + ) -> None: ... + +class MethodPolicy(_message.Message): + __slots__ = ("selector", "request_policies") + SELECTOR_FIELD_NUMBER: _ClassVar[int] + REQUEST_POLICIES_FIELD_NUMBER: _ClassVar[int] + selector: str + request_policies: _containers.RepeatedCompositeFieldContainer[FieldPolicy] + def __init__( + self, + selector: _Optional[str] = ..., + request_policies: _Optional[_Iterable[_Union[FieldPolicy, _Mapping]]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto new file mode 100644 index 00000000000..29ae86ed467 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto @@ -0,0 +1,184 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "QuotaProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Quota configuration helps to achieve fairness and budgeting in service +// usage. +// +// The metric based quota configuration works this way: +// - The service configuration defines a set of metrics. +// - For API calls, the quota.metric_rules maps methods to metrics with +// corresponding costs. +// - The quota.limits defines limits on the metrics, which will be used for +// quota checks at runtime. +// +// An example quota configuration in yaml format: +// +// quota: +// limits: +// +// - name: apiWriteQpsPerProject +// metric: library.googleapis.com/write_calls +// unit: "1/min/{project}" # rate limit for consumer projects +// values: +// STANDARD: 10000 +// +// +// (The metric rules bind all methods to the read_calls metric, +// except for the UpdateBook and DeleteBook methods. These two methods +// are mapped to the write_calls metric, with the UpdateBook method +// consuming at twice rate as the DeleteBook method.) +// metric_rules: +// - selector: "*" +// metric_costs: +// library.googleapis.com/read_calls: 1 +// - selector: google.example.library.v1.LibraryService.UpdateBook +// metric_costs: +// library.googleapis.com/write_calls: 2 +// - selector: google.example.library.v1.LibraryService.DeleteBook +// metric_costs: +// library.googleapis.com/write_calls: 1 +// +// Corresponding Metric definition: +// +// metrics: +// - name: library.googleapis.com/read_calls +// display_name: Read requests +// metric_kind: DELTA +// value_type: INT64 +// +// - name: library.googleapis.com/write_calls +// display_name: Write requests +// metric_kind: DELTA +// value_type: INT64 +// +// +message Quota { + // List of QuotaLimit definitions for the service. + repeated QuotaLimit limits = 3; + + // List of MetricRule definitions, each one mapping a selected method to one + // or more metrics. + repeated MetricRule metric_rules = 4; +} + +// Bind API methods to metrics. Binding a method to a metric causes that +// metric's configured quota behaviors to apply to the method call. +message MetricRule { + // Selects the methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // Metrics to update when the selected methods are called, and the associated + // cost applied to each metric. + // + // The key of the map is the metric name, and the values are the amount + // increased for the metric against which the quota limits are defined. + // The value must not be negative. + map metric_costs = 2; +} + +// `QuotaLimit` defines a specific limit that applies over a specified duration +// for a limit type. There can be at most one limit for a duration and limit +// type combination defined within a `QuotaGroup`. +message QuotaLimit { + // Name of the quota limit. + // + // The name must be provided, and it must be unique within the service. The + // name can only include alphanumeric characters as well as '-'. + // + // The maximum length of the limit name is 64 characters. + string name = 6; + + // Optional. User-visible, extended description for this quota limit. + // Should be used only when more context is needed to understand this limit + // than provided by the limit's display name (see: `display_name`). + string description = 2; + + // Default number of tokens that can be consumed during the specified + // duration. This is the number of tokens assigned when a client + // application developer activates the service for his/her project. + // + // Specifying a value of 0 will block all requests. This can be used if you + // are provisioning quota to selected consumers and blocking others. + // Similarly, a value of -1 will indicate an unlimited quota. No other + // negative values are allowed. + // + // Used by group-based quotas only. + int64 default_limit = 3; + + // Maximum number of tokens that can be consumed during the specified + // duration. Client application developers can override the default limit up + // to this maximum. If specified, this value cannot be set to a value less + // than the default limit. If not specified, it is set to the default limit. + // + // To allow clients to apply overrides with no upper bound, set this to -1, + // indicating unlimited maximum quota. + // + // Used by group-based quotas only. + int64 max_limit = 4; + + // Free tier value displayed in the Developers Console for this limit. + // The free tier is the number of tokens that will be subtracted from the + // billed amount when billing is enabled. + // This field can only be set on a limit with duration "1d", in a billable + // group; it is invalid on any other limit. If this field is not set, it + // defaults to 0, indicating that there is no free tier for this service. + // + // Used by group-based quotas only. + int64 free_tier = 7; + + // Duration of this limit in textual notation. Must be "100s" or "1d". + // + // Used by group-based quotas only. + string duration = 5; + + // The name of the metric this quota limit applies to. The quota limits with + // the same metric will be checked together during runtime. The metric must be + // defined within the service config. + string metric = 8; + + // Specify the unit of the quota limit. It uses the same syntax as + // [MetricDescriptor.unit][google.api.MetricDescriptor.unit]. The supported + // unit kinds are determined by the quota backend system. + // + // Here are some examples: + // * "1/min/{project}" for quota per minute per project. + // + // Note: the order of unit components is insignificant. + // The "1" at the beginning is required to follow the metric unit syntax. + string unit = 9; + + // Tiered limit values. You must specify this as a key:value pair, with an + // integer value that is the maximum number of requests allowed for the + // specified unit. Currently only STANDARD is supported. + map values = 10; + + // User-visible display name for this limit. + // Optional. If not set, the UI will provide a default display name based on + // the quota configuration. This field can be used to override the default + // display name generated from the configuration. + string display_name = 12; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py new file mode 100644 index 00000000000..237f7a5cfd7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/quota.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/quota.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x16google/api/quota.proto\x12\ngoogle.api"]\n\x05Quota\x12&\n\x06limits\x18\x03 \x03(\x0b\x32\x16.google.api.QuotaLimit\x12,\n\x0cmetric_rules\x18\x04 \x03(\x0b\x32\x16.google.api.MetricRule"\x91\x01\n\nMetricRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12=\n\x0cmetric_costs\x18\x02 \x03(\x0b\x32\'.google.api.MetricRule.MetricCostsEntry\x1a\x32\n\x10MetricCostsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01"\x95\x02\n\nQuotaLimit\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x15\n\rdefault_limit\x18\x03 \x01(\x03\x12\x11\n\tmax_limit\x18\x04 \x01(\x03\x12\x11\n\tfree_tier\x18\x07 \x01(\x03\x12\x10\n\x08\x64uration\x18\x05 \x01(\t\x12\x0e\n\x06metric\x18\x08 \x01(\t\x12\x0c\n\x04unit\x18\t \x01(\t\x12\x32\n\x06values\x18\n \x03(\x0b\x32".google.api.QuotaLimit.ValuesEntry\x12\x14\n\x0c\x64isplay_name\x18\x0c \x01(\t\x1a-\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01\x42l\n\x0e\x63om.google.apiB\nQuotaProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.quota_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\nQuotaProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_METRICRULE_METRICCOSTSENTRY"]._loaded_options = None + _globals["_METRICRULE_METRICCOSTSENTRY"]._serialized_options = b"8\001" + _globals["_QUOTALIMIT_VALUESENTRY"]._loaded_options = None + _globals["_QUOTALIMIT_VALUESENTRY"]._serialized_options = b"8\001" + _globals["_QUOTA"]._serialized_start = 38 + _globals["_QUOTA"]._serialized_end = 131 + _globals["_METRICRULE"]._serialized_start = 134 + _globals["_METRICRULE"]._serialized_end = 279 + _globals["_METRICRULE_METRICCOSTSENTRY"]._serialized_start = 229 + _globals["_METRICRULE_METRICCOSTSENTRY"]._serialized_end = 279 + _globals["_QUOTALIMIT"]._serialized_start = 282 + _globals["_QUOTALIMIT"]._serialized_end = 559 + _globals["_QUOTALIMIT_VALUESENTRY"]._serialized_start = 514 + _globals["_QUOTALIMIT_VALUESENTRY"]._serialized_end = 559 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi new file mode 100644 index 00000000000..2c70590ab90 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi @@ -0,0 +1,116 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Quota(_message.Message): + __slots__ = ("limits", "metric_rules") + LIMITS_FIELD_NUMBER: _ClassVar[int] + METRIC_RULES_FIELD_NUMBER: _ClassVar[int] + limits: _containers.RepeatedCompositeFieldContainer[QuotaLimit] + metric_rules: _containers.RepeatedCompositeFieldContainer[MetricRule] + def __init__( + self, + limits: _Optional[_Iterable[_Union[QuotaLimit, _Mapping]]] = ..., + metric_rules: _Optional[_Iterable[_Union[MetricRule, _Mapping]]] = ..., + ) -> None: ... + +class MetricRule(_message.Message): + __slots__ = ("selector", "metric_costs") + class MetricCostsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: int + def __init__( + self, key: _Optional[str] = ..., value: _Optional[int] = ... + ) -> None: ... + + SELECTOR_FIELD_NUMBER: _ClassVar[int] + METRIC_COSTS_FIELD_NUMBER: _ClassVar[int] + selector: str + metric_costs: _containers.ScalarMap[str, int] + def __init__( + self, + selector: _Optional[str] = ..., + metric_costs: _Optional[_Mapping[str, int]] = ..., + ) -> None: ... + +class QuotaLimit(_message.Message): + __slots__ = ( + "name", + "description", + "default_limit", + "max_limit", + "free_tier", + "duration", + "metric", + "unit", + "values", + "display_name", + ) + class ValuesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: int + def __init__( + self, key: _Optional[str] = ..., value: _Optional[int] = ... + ) -> None: ... + + NAME_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + DEFAULT_LIMIT_FIELD_NUMBER: _ClassVar[int] + MAX_LIMIT_FIELD_NUMBER: _ClassVar[int] + FREE_TIER_FIELD_NUMBER: _ClassVar[int] + DURATION_FIELD_NUMBER: _ClassVar[int] + METRIC_FIELD_NUMBER: _ClassVar[int] + UNIT_FIELD_NUMBER: _ClassVar[int] + VALUES_FIELD_NUMBER: _ClassVar[int] + DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] + name: str + description: str + default_limit: int + max_limit: int + free_tier: int + duration: str + metric: str + unit: str + values: _containers.ScalarMap[str, int] + display_name: str + def __init__( + self, + name: _Optional[str] = ..., + description: _Optional[str] = ..., + default_limit: _Optional[int] = ..., + max_limit: _Optional[int] = ..., + free_tier: _Optional[int] = ..., + duration: _Optional[str] = ..., + metric: _Optional[str] = ..., + unit: _Optional[str] = ..., + values: _Optional[_Mapping[str, int]] = ..., + display_name: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto new file mode 100644 index 00000000000..2a5213bb08a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto @@ -0,0 +1,242 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "ResourceProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.FieldOptions { + // An annotation that describes a resource reference, see + // [ResourceReference][]. + google.api.ResourceReference resource_reference = 1055; +} + +extend google.protobuf.FileOptions { + // An annotation that describes a resource definition without a corresponding + // message; see [ResourceDescriptor][]. + repeated google.api.ResourceDescriptor resource_definition = 1053; +} + +extend google.protobuf.MessageOptions { + // An annotation that describes a resource definition, see + // [ResourceDescriptor][]. + google.api.ResourceDescriptor resource = 1053; +} + +// A simple descriptor of a resource type. +// +// ResourceDescriptor annotates a resource message (either by means of a +// protobuf annotation or use in the service config), and associates the +// resource's schema, the resource type, and the pattern of the resource name. +// +// Example: +// +// message Topic { +// // Indicates this message defines a resource schema. +// // Declares the resource type in the format of {service}/{kind}. +// // For Kubernetes resources, the format is {api group}/{kind}. +// option (google.api.resource) = { +// type: "pubsub.googleapis.com/Topic" +// pattern: "projects/{project}/topics/{topic}" +// }; +// } +// +// The ResourceDescriptor Yaml config will look like: +// +// resources: +// - type: "pubsub.googleapis.com/Topic" +// pattern: "projects/{project}/topics/{topic}" +// +// Sometimes, resources have multiple patterns, typically because they can +// live under multiple parents. +// +// Example: +// +// message LogEntry { +// option (google.api.resource) = { +// type: "logging.googleapis.com/LogEntry" +// pattern: "projects/{project}/logs/{log}" +// pattern: "folders/{folder}/logs/{log}" +// pattern: "organizations/{organization}/logs/{log}" +// pattern: "billingAccounts/{billing_account}/logs/{log}" +// }; +// } +// +// The ResourceDescriptor Yaml config will look like: +// +// resources: +// - type: 'logging.googleapis.com/LogEntry' +// pattern: "projects/{project}/logs/{log}" +// pattern: "folders/{folder}/logs/{log}" +// pattern: "organizations/{organization}/logs/{log}" +// pattern: "billingAccounts/{billing_account}/logs/{log}" +message ResourceDescriptor { + // A description of the historical or future-looking state of the + // resource pattern. + enum History { + // The "unset" value. + HISTORY_UNSPECIFIED = 0; + + // The resource originally had one pattern and launched as such, and + // additional patterns were added later. + ORIGINALLY_SINGLE_PATTERN = 1; + + // The resource has one pattern, but the API owner expects to add more + // later. (This is the inverse of ORIGINALLY_SINGLE_PATTERN, and prevents + // that from being necessary once there are multiple patterns.) + FUTURE_MULTI_PATTERN = 2; + } + + // A flag representing a specific style that a resource claims to conform to. + enum Style { + // The unspecified value. Do not use. + STYLE_UNSPECIFIED = 0; + + // This resource is intended to be "declarative-friendly". + // + // Declarative-friendly resources must be more strictly consistent, and + // setting this to true communicates to tools that this resource should + // adhere to declarative-friendly expectations. + // + // Note: This is used by the API linter (linter.aip.dev) to enable + // additional checks. + DECLARATIVE_FRIENDLY = 1; + } + + // The resource type. It must be in the format of + // {service_name}/{resource_type_kind}. The `resource_type_kind` must be + // singular and must not include version numbers. + // + // Example: `storage.googleapis.com/Bucket` + // + // The value of the resource_type_kind must follow the regular expression + // /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and + // should use PascalCase (UpperCamelCase). The maximum number of + // characters allowed for the `resource_type_kind` is 100. + string type = 1; + + // Optional. The relative resource name pattern associated with this resource + // type. The DNS prefix of the full resource name shouldn't be specified here. + // + // The path pattern must follow the syntax, which aligns with HTTP binding + // syntax: + // + // Template = Segment { "/" Segment } ; + // Segment = LITERAL | Variable ; + // Variable = "{" LITERAL "}" ; + // + // Examples: + // + // - "projects/{project}/topics/{topic}" + // - "projects/{project}/knowledgeBases/{knowledge_base}" + // + // The components in braces correspond to the IDs for each resource in the + // hierarchy. It is expected that, if multiple patterns are provided, + // the same component name (e.g. "project") refers to IDs of the same + // type of resource. + repeated string pattern = 2; + + // Optional. The field on the resource that designates the resource name + // field. If omitted, this is assumed to be "name". + string name_field = 3; + + // Optional. The historical or future-looking state of the resource pattern. + // + // Example: + // + // // The InspectTemplate message originally only supported resource + // // names with organization, and project was added later. + // message InspectTemplate { + // option (google.api.resource) = { + // type: "dlp.googleapis.com/InspectTemplate" + // pattern: + // "organizations/{organization}/inspectTemplates/{inspect_template}" + // pattern: "projects/{project}/inspectTemplates/{inspect_template}" + // history: ORIGINALLY_SINGLE_PATTERN + // }; + // } + History history = 4; + + // The plural name used in the resource name and permission names, such as + // 'projects' for the resource name of 'projects/{project}' and the permission + // name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception + // to this is for Nested Collections that have stuttering names, as defined + // in [AIP-122](https://google.aip.dev/122#nested-collections), where the + // collection ID in the resource name pattern does not necessarily directly + // match the `plural` value. + // + // It is the same concept of the `plural` field in k8s CRD spec + // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ + // + // Note: The plural form is required even for singleton resources. See + // https://aip.dev/156 + string plural = 5; + + // The same concept of the `singular` field in k8s CRD spec + // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ + // Such as "project" for the `resourcemanager.googleapis.com/Project` type. + string singular = 6; + + // Style flag(s) for this resource. + // These indicate that a resource is expected to conform to a given + // style. See the specific style flags for additional information. + repeated Style style = 10; +} + +// Defines a proto annotation that describes a string field that refers to +// an API resource. +message ResourceReference { + // The resource type that the annotated field references. + // + // Example: + // + // message Subscription { + // string topic = 2 [(google.api.resource_reference) = { + // type: "pubsub.googleapis.com/Topic" + // }]; + // } + // + // Occasionally, a field may reference an arbitrary resource. In this case, + // APIs use the special value * in their resource reference. + // + // Example: + // + // message GetIamPolicyRequest { + // string resource = 2 [(google.api.resource_reference) = { + // type: "*" + // }]; + // } + string type = 1; + + // The resource type of a child collection that the annotated field + // references. This is useful for annotating the `parent` field that + // doesn't have a fixed resource type. + // + // Example: + // + // message ListLogEntriesRequest { + // string parent = 1 [(google.api.resource_reference) = { + // child_type: "logging.googleapis.com/LogEntry" + // }; + // } + string child_type = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py new file mode 100644 index 00000000000..a11f17a44ad --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/resource.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/resource.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x19google/api/resource.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"\xee\x02\n\x12ResourceDescriptor\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x03(\t\x12\x12\n\nname_field\x18\x03 \x01(\t\x12\x37\n\x07history\x18\x04 \x01(\x0e\x32&.google.api.ResourceDescriptor.History\x12\x0e\n\x06plural\x18\x05 \x01(\t\x12\x10\n\x08singular\x18\x06 \x01(\t\x12\x33\n\x05style\x18\n \x03(\x0e\x32$.google.api.ResourceDescriptor.Style"[\n\x07History\x12\x17\n\x13HISTORY_UNSPECIFIED\x10\x00\x12\x1d\n\x19ORIGINALLY_SINGLE_PATTERN\x10\x01\x12\x18\n\x14\x46UTURE_MULTI_PATTERN\x10\x02"8\n\x05Style\x12\x15\n\x11STYLE_UNSPECIFIED\x10\x00\x12\x18\n\x14\x44\x45\x43LARATIVE_FRIENDLY\x10\x01"5\n\x11ResourceReference\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x12\n\nchild_type\x18\x02 \x01(\t:Y\n\x12resource_reference\x12\x1d.google.protobuf.FieldOptions\x18\x9f\x08 \x01(\x0b\x32\x1d.google.api.ResourceReference:Z\n\x13resource_definition\x12\x1c.google.protobuf.FileOptions\x18\x9d\x08 \x03(\x0b\x32\x1e.google.api.ResourceDescriptor:R\n\x08resource\x12\x1f.google.protobuf.MessageOptions\x18\x9d\x08 \x01(\x0b\x32\x1e.google.api.ResourceDescriptorBk\n\x0e\x63om.google.apiB\rResourceProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.resource_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\rResourceProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" + _globals["_RESOURCEDESCRIPTOR"]._serialized_start = 76 + _globals["_RESOURCEDESCRIPTOR"]._serialized_end = 442 + _globals["_RESOURCEDESCRIPTOR_HISTORY"]._serialized_start = 293 + _globals["_RESOURCEDESCRIPTOR_HISTORY"]._serialized_end = 384 + _globals["_RESOURCEDESCRIPTOR_STYLE"]._serialized_start = 386 + _globals["_RESOURCEDESCRIPTOR_STYLE"]._serialized_end = 442 + _globals["_RESOURCEREFERENCE"]._serialized_start = 444 + _globals["_RESOURCEREFERENCE"]._serialized_end = 497 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi new file mode 100644 index 00000000000..806682cdb3d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi @@ -0,0 +1,93 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor +RESOURCE_REFERENCE_FIELD_NUMBER: _ClassVar[int] +resource_reference: _descriptor.FieldDescriptor +RESOURCE_DEFINITION_FIELD_NUMBER: _ClassVar[int] +resource_definition: _descriptor.FieldDescriptor +RESOURCE_FIELD_NUMBER: _ClassVar[int] +resource: _descriptor.FieldDescriptor + +class ResourceDescriptor(_message.Message): + __slots__ = ( + "type", + "pattern", + "name_field", + "history", + "plural", + "singular", + "style", + ) + class History(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + HISTORY_UNSPECIFIED: _ClassVar[ResourceDescriptor.History] + ORIGINALLY_SINGLE_PATTERN: _ClassVar[ResourceDescriptor.History] + FUTURE_MULTI_PATTERN: _ClassVar[ResourceDescriptor.History] + + HISTORY_UNSPECIFIED: ResourceDescriptor.History + ORIGINALLY_SINGLE_PATTERN: ResourceDescriptor.History + FUTURE_MULTI_PATTERN: ResourceDescriptor.History + class Style(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + STYLE_UNSPECIFIED: _ClassVar[ResourceDescriptor.Style] + DECLARATIVE_FRIENDLY: _ClassVar[ResourceDescriptor.Style] + + STYLE_UNSPECIFIED: ResourceDescriptor.Style + DECLARATIVE_FRIENDLY: ResourceDescriptor.Style + TYPE_FIELD_NUMBER: _ClassVar[int] + PATTERN_FIELD_NUMBER: _ClassVar[int] + NAME_FIELD_FIELD_NUMBER: _ClassVar[int] + HISTORY_FIELD_NUMBER: _ClassVar[int] + PLURAL_FIELD_NUMBER: _ClassVar[int] + SINGULAR_FIELD_NUMBER: _ClassVar[int] + STYLE_FIELD_NUMBER: _ClassVar[int] + type: str + pattern: _containers.RepeatedScalarFieldContainer[str] + name_field: str + history: ResourceDescriptor.History + plural: str + singular: str + style: _containers.RepeatedScalarFieldContainer[ResourceDescriptor.Style] + def __init__( + self, + type: _Optional[str] = ..., + pattern: _Optional[_Iterable[str]] = ..., + name_field: _Optional[str] = ..., + history: _Optional[_Union[ResourceDescriptor.History, str]] = ..., + plural: _Optional[str] = ..., + singular: _Optional[str] = ..., + style: _Optional[_Iterable[_Union[ResourceDescriptor.Style, str]]] = ..., + ) -> None: ... + +class ResourceReference(_message.Message): + __slots__ = ("type", "child_type") + TYPE_FIELD_NUMBER: _ClassVar[int] + CHILD_TYPE_FIELD_NUMBER: _ClassVar[int] + type: str + child_type: str + def __init__( + self, type: _Optional[str] = ..., child_type: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto new file mode 100644 index 00000000000..020d32f7b71 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto @@ -0,0 +1,465 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "RoutingProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See RoutingRule. + google.api.RoutingRule routing = 72295729; +} + +// Specifies the routing information that should be sent along with the request +// in the form of routing header. +// **NOTE:** All service configuration rules follow the "last one wins" order. +// +// The examples below will apply to an RPC which has the following request type: +// +// Message Definition: +// +// message Request { +// // The name of the Table +// // Values can be of the following formats: +// // - `projects//tables/` +// // - `projects//instances//tables/
` +// // - `region//zones//tables/
` +// string table_name = 1; +// +// // This value specifies routing for replication. +// // It can be in the following formats: +// // - `profiles/` +// // - a legacy `profile_id` that can be any string +// string app_profile_id = 2; +// } +// +// Example message: +// +// { +// table_name: projects/proj_foo/instances/instance_bar/table/table_baz, +// app_profile_id: profiles/prof_qux +// } +// +// The routing header consists of one or multiple key-value pairs. The order of +// the key-value pairs is undefined, the order of the `routing_parameters` in +// the `RoutingRule` only matters for the evaluation order of the path +// templates when `field` is the same. See the examples below for more details. +// +// Every key and value in the routing header must be percent-encoded, +// and joined together in the following format: `key1=value1&key2=value2`. +// The examples below skip the percent-encoding for readability. +// +// Example 1 +// +// Extracting a field from the request to put into the routing header +// unchanged, with the key equal to the field name. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `app_profile_id`. +// routing_parameters { +// field: "app_profile_id" +// } +// }; +// +// result: +// +// x-goog-request-params: app_profile_id=profiles/prof_qux +// +// Example 2 +// +// Extracting a field from the request to put into the routing header +// unchanged, with the key different from the field name. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `app_profile_id`, but name it `routing_id` in the header. +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// }; +// +// result: +// +// x-goog-request-params: routing_id=profiles/prof_qux +// +// Example 3 +// +// Extracting a field from the request to put into the routing +// header, while matching a path template syntax on the field's value. +// +// NB: it is more useful to send nothing than to send garbage for the purpose +// of dynamic routing, since garbage pollutes cache. Thus the matching. +// +// Sub-example 3a +// +// The field matches the template. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `table_name`, if it's well-formed (with project-based +// // syntax). +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=projects/*/instances/*/**}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// table_name=projects/proj_foo/instances/instance_bar/table/table_baz +// +// Sub-example 3b +// +// The field does not match the template. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `table_name`, if it's well-formed (with region-based +// // syntax). +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=regions/*/zones/*/**}" +// } +// }; +// +// result: +// +// +// +// Sub-example 3c +// +// Multiple alternative conflictingly named path templates are +// specified. The one that matches is used to construct the header. +// +// annotation: +// +// option (google.api.routing) = { +// // Take the `table_name`, if it's well-formed, whether +// // using the region- or projects-based syntax. +// +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=regions/*/zones/*/**}" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{table_name=projects/*/instances/*/**}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// table_name=projects/proj_foo/instances/instance_bar/table/table_baz +// +// Example 4 +// +// Extracting a single routing header key-value pair by matching a +// template syntax on (a part of) a single request field. +// +// annotation: +// +// option (google.api.routing) = { +// // Take just the project id from the `table_name` field. +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// }; +// +// result: +// +// x-goog-request-params: routing_id=projects/proj_foo +// +// Example 5 +// +// Extracting a single routing header key-value pair by matching +// several conflictingly named path templates on (parts of) a single request +// field. The last template to match "wins" the conflict. +// +// annotation: +// +// option (google.api.routing) = { +// // If the `table_name` does not have instances information, +// // take just the project id for routing. +// // Otherwise take project + instance. +// +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*/instances/*}/**" +// } +// }; +// +// result: +// +// x-goog-request-params: +// routing_id=projects/proj_foo/instances/instance_bar +// +// Example 6 +// +// Extracting multiple routing header key-value pairs by matching +// several non-conflicting path templates on (parts of) a single request field. +// +// Sub-example 6a +// +// Make the templates strict, so that if the `table_name` does not +// have an instance information, nothing is sent. +// +// annotation: +// +// option (google.api.routing) = { +// // The routing code needs two keys instead of one composite +// // but works only for the tables with the "project-instance" name +// // syntax. +// +// routing_parameters { +// field: "table_name" +// path_template: "{project_id=projects/*}/instances/*/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "projects/*/{instance_id=instances/*}/**" +// } +// }; +// +// result: +// +// x-goog-request-params: +// project_id=projects/proj_foo&instance_id=instances/instance_bar +// +// Sub-example 6b +// +// Make the templates loose, so that if the `table_name` does not +// have an instance information, just the project id part is sent. +// +// annotation: +// +// option (google.api.routing) = { +// // The routing code wants two keys instead of one composite +// // but will work with just the `project_id` for tables without +// // an instance in the `table_name`. +// +// routing_parameters { +// field: "table_name" +// path_template: "{project_id=projects/*}/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "projects/*/{instance_id=instances/*}/**" +// } +// }; +// +// result (is the same as 6a for our example message because it has the instance +// information): +// +// x-goog-request-params: +// project_id=projects/proj_foo&instance_id=instances/instance_bar +// +// Example 7 +// +// Extracting multiple routing header key-value pairs by matching +// several path templates on multiple request fields. +// +// NB: note that here there is no way to specify sending nothing if one of the +// fields does not match its template. E.g. if the `table_name` is in the wrong +// format, the `project_id` will not be sent, but the `routing_id` will be. +// The backend routing code has to be aware of that and be prepared to not +// receive a full complement of keys if it expects multiple. +// +// annotation: +// +// option (google.api.routing) = { +// // The routing needs both `project_id` and `routing_id` +// // (from the `app_profile_id` field) for routing. +// +// routing_parameters { +// field: "table_name" +// path_template: "{project_id=projects/*}/**" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// project_id=projects/proj_foo&routing_id=profiles/prof_qux +// +// Example 8 +// +// Extracting a single routing header key-value pair by matching +// several conflictingly named path templates on several request fields. The +// last template to match "wins" the conflict. +// +// annotation: +// +// option (google.api.routing) = { +// // The `routing_id` can be a project id or a region id depending on +// // the table name format, but only if the `app_profile_id` is not set. +// // If `app_profile_id` is set it should be used instead. +// +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=regions/*}/**" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// }; +// +// result: +// +// x-goog-request-params: routing_id=profiles/prof_qux +// +// Example 9 +// +// Bringing it all together. +// +// annotation: +// +// option (google.api.routing) = { +// // For routing both `table_location` and a `routing_id` are needed. +// // +// // table_location can be either an instance id or a region+zone id. +// // +// // For `routing_id`, take the value of `app_profile_id` +// // - If it's in the format `profiles/`, send +// // just the `` part. +// // - If it's any other literal, send it as is. +// // If the `app_profile_id` is empty, and the `table_name` starts with +// // the project_id, send that instead. +// +// routing_parameters { +// field: "table_name" +// path_template: "projects/*/{table_location=instances/*}/tables/*" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{table_location=regions/*/zones/*}/tables/*" +// } +// routing_parameters { +// field: "table_name" +// path_template: "{routing_id=projects/*}/**" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "{routing_id=**}" +// } +// routing_parameters { +// field: "app_profile_id" +// path_template: "profiles/{routing_id=*}" +// } +// }; +// +// result: +// +// x-goog-request-params: +// table_location=instances/instance_bar&routing_id=prof_qux +message RoutingRule { + // A collection of Routing Parameter specifications. + // **NOTE:** If multiple Routing Parameters describe the same key + // (via the `path_template` field or via the `field` field when + // `path_template` is not provided), "last one wins" rule + // determines which Parameter gets used. + // See the examples for more details. + repeated RoutingParameter routing_parameters = 2; +} + +// A projection from an input message to the GRPC or REST header. +message RoutingParameter { + // A request field to extract the header key-value pair from. + string field = 1; + + // A pattern matching the key-value field. Optional. + // If not specified, the whole field specified in the `field` field will be + // taken as value, and its name used as key. If specified, it MUST contain + // exactly one named segment (along with any number of unnamed segments) The + // pattern will be matched over the field specified in the `field` field, then + // if the match is successful: + // - the name of the single named segment will be used as a header name, + // - the match value of the segment will be used as a header value; + // if the match is NOT successful, nothing will be sent. + // + // Example: + // + // -- This is a field in the request message + // | that the header value will be extracted from. + // | + // | -- This is the key name in the + // | | routing header. + // V | + // field: "table_name" v + // path_template: "projects/*/{table_location=instances/*}/tables/*" + // ^ ^ + // | | + // In the {} brackets is the pattern that -- | + // specifies what to extract from the | + // field as a value to be sent. | + // | + // The string in the field must match the whole pattern -- + // before brackets, inside brackets, after brackets. + // + // When looking at this specific example, we can see that: + // - A key-value pair with the key `table_location` + // and the value matching `instances/*` should be added + // to the x-goog-request-params routing header. + // - The value is extracted from the request message's `table_name` field + // if it matches the full pattern specified: + // `projects/*/instances/*/tables/*`. + // + // **NB:** If the `path_template` field is not provided, the key name is + // equal to the field name, and the whole field should be sent as a value. + // This makes the pattern for the field and the value functionally equivalent + // to `**`, and the configuration + // + // { + // field: "table_name" + // } + // + // is a functionally equivalent shorthand to: + // + // { + // field: "table_name" + // path_template: "{table_name=**}" + // } + // + // See Example 1 for more details. + string path_template = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py new file mode 100644 index 00000000000..0356b505025 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/routing.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/routing.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x18google/api/routing.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"G\n\x0bRoutingRule\x12\x38\n\x12routing_parameters\x18\x02 \x03(\x0b\x32\x1c.google.api.RoutingParameter"8\n\x10RoutingParameter\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x15\n\rpath_template\x18\x02 \x01(\t:K\n\x07routing\x12\x1e.google.protobuf.MethodOptions\x18\xb1\xca\xbc" \x01(\x0b\x32\x17.google.api.RoutingRuleBj\n\x0e\x63om.google.apiB\x0cRoutingProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.routing_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\014RoutingProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" + _globals["_ROUTINGRULE"]._serialized_start = 74 + _globals["_ROUTINGRULE"]._serialized_end = 145 + _globals["_ROUTINGPARAMETER"]._serialized_start = 147 + _globals["_ROUTINGPARAMETER"]._serialized_end = 203 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi new file mode 100644 index 00000000000..39fe16e5659 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi @@ -0,0 +1,49 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor +ROUTING_FIELD_NUMBER: _ClassVar[int] +routing: _descriptor.FieldDescriptor + +class RoutingRule(_message.Message): + __slots__ = ("routing_parameters",) + ROUTING_PARAMETERS_FIELD_NUMBER: _ClassVar[int] + routing_parameters: _containers.RepeatedCompositeFieldContainer[RoutingParameter] + def __init__( + self, + routing_parameters: _Optional[ + _Iterable[_Union[RoutingParameter, _Mapping]] + ] = ..., + ) -> None: ... + +class RoutingParameter(_message.Message): + __slots__ = ("field", "path_template") + FIELD_FIELD_NUMBER: _ClassVar[int] + PATH_TEMPLATE_FIELD_NUMBER: _ClassVar[int] + field: str + path_template: str + def __init__( + self, field: _Optional[str] = ..., path_template: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto new file mode 100644 index 00000000000..9952ca0e8d5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto @@ -0,0 +1,190 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/auth.proto"; +import "google/api/backend.proto"; +import "google/api/billing.proto"; +import "google/api/client.proto"; +import "google/api/context.proto"; +import "google/api/control.proto"; +import "google/api/documentation.proto"; +import "google/api/endpoint.proto"; +import "google/api/http.proto"; +import "google/api/log.proto"; +import "google/api/logging.proto"; +import "google/api/metric.proto"; +import "google/api/monitored_resource.proto"; +import "google/api/monitoring.proto"; +import "google/api/quota.proto"; +import "google/api/source_info.proto"; +import "google/api/system_parameter.proto"; +import "google/api/usage.proto"; +import "google/protobuf/api.proto"; +import "google/protobuf/type.proto"; +import "google/protobuf/wrappers.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "ServiceProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Service` is the root object of Google API service configuration (service +// config). It describes the basic information about a logical service, +// such as the service name and the user-facing title, and delegates other +// aspects to sub-sections. Each sub-section is either a proto message or a +// repeated proto message that configures a specific aspect, such as auth. +// For more information, see each proto message definition. +// +// Example: +// +// type: google.api.Service +// name: calendar.googleapis.com +// title: Google Calendar API +// apis: +// - name: google.calendar.v3.Calendar +// +// visibility: +// rules: +// - selector: "google.calendar.v3.*" +// restriction: PREVIEW +// backend: +// rules: +// - selector: "google.calendar.v3.*" +// address: calendar.example.com +// +// authentication: +// providers: +// - id: google_calendar_auth +// jwks_uri: https://www.googleapis.com/oauth2/v1/certs +// issuer: https://securetoken.google.com +// rules: +// - selector: "*" +// requirements: +// provider_id: google_calendar_auth +message Service { + // The service name, which is a DNS-like logical identifier for the + // service, such as `calendar.googleapis.com`. The service name + // typically goes through DNS verification to make sure the owner + // of the service also owns the DNS name. + string name = 1; + + // The product title for this service, it is the name displayed in Google + // Cloud Console. + string title = 2; + + // The Google project that owns this service. + string producer_project_id = 22; + + // A unique ID for a specific instance of this message, typically assigned + // by the client for tracking purpose. Must be no longer than 63 characters + // and only lower case letters, digits, '.', '_' and '-' are allowed. If + // empty, the server may choose to generate one instead. + string id = 33; + + // A list of API interfaces exported by this service. Only the `name` field + // of the [google.protobuf.Api][google.protobuf.Api] needs to be provided by + // the configuration author, as the remaining fields will be derived from the + // IDL during the normalization process. It is an error to specify an API + // interface here which cannot be resolved against the associated IDL files. + repeated google.protobuf.Api apis = 3; + + // A list of all proto message types included in this API service. + // Types referenced directly or indirectly by the `apis` are automatically + // included. Messages which are not referenced but shall be included, such as + // types used by the `google.protobuf.Any` type, should be listed here by + // name by the configuration author. Example: + // + // types: + // - name: google.protobuf.Int32 + repeated google.protobuf.Type types = 4; + + // A list of all enum types included in this API service. Enums referenced + // directly or indirectly by the `apis` are automatically included. Enums + // which are not referenced but shall be included should be listed here by + // name by the configuration author. Example: + // + // enums: + // - name: google.someapi.v1.SomeEnum + repeated google.protobuf.Enum enums = 5; + + // Additional API documentation. + Documentation documentation = 6; + + // API backend configuration. + Backend backend = 8; + + // HTTP configuration. + Http http = 9; + + // Quota configuration. + Quota quota = 10; + + // Auth configuration. + Authentication authentication = 11; + + // Context configuration. + Context context = 12; + + // Configuration controlling usage of this service. + Usage usage = 15; + + // Configuration for network endpoints. If this is empty, then an endpoint + // with the same name as the service is automatically generated to service all + // defined APIs. + repeated Endpoint endpoints = 18; + + // Configuration for the service control plane. + Control control = 21; + + // Defines the logs used by this service. + repeated LogDescriptor logs = 23; + + // Defines the metrics used by this service. + repeated MetricDescriptor metrics = 24; + + // Defines the monitored resources used by this service. This is required + // by the `Service.monitoring` and `Service.logging` configurations. + repeated MonitoredResourceDescriptor monitored_resources = 25; + + // Billing configuration. + Billing billing = 26; + + // Logging configuration. + Logging logging = 27; + + // Monitoring configuration. + Monitoring monitoring = 28; + + // System parameter configuration. + SystemParameters system_parameters = 29; + + // Output only. The source information for this configuration if available. + SourceInfo source_info = 37; + + // Settings for [Google Cloud Client + // libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) + // generated from APIs defined as protocol buffers. + Publishing publishing = 45; + + // Obsolete. Do not use. + // + // This field has no semantic meaning. The service config compiler always + // sets this field to `3`. + google.protobuf.UInt32Value config_version = 20; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py new file mode 100644 index 00000000000..ac0c1db283c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/service.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/service.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import api_pb2 as google_dot_protobuf_dot_api__pb2 +from opentelemetry.agent._vendor.google.protobuf import type_pb2 as google_dot_protobuf_dot_type__pb2 +from opentelemetry.agent._vendor.google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 + +from opentelemetry.agent._vendor.google.api import auth_pb2 as google_dot_api_dot_auth__pb2 +from opentelemetry.agent._vendor.google.api import backend_pb2 as google_dot_api_dot_backend__pb2 +from opentelemetry.agent._vendor.google.api import billing_pb2 as google_dot_api_dot_billing__pb2 +from opentelemetry.agent._vendor.google.api import client_pb2 as google_dot_api_dot_client__pb2 +from opentelemetry.agent._vendor.google.api import context_pb2 as google_dot_api_dot_context__pb2 +from opentelemetry.agent._vendor.google.api import control_pb2 as google_dot_api_dot_control__pb2 +from opentelemetry.agent._vendor.google.api import documentation_pb2 as google_dot_api_dot_documentation__pb2 +from opentelemetry.agent._vendor.google.api import endpoint_pb2 as google_dot_api_dot_endpoint__pb2 +from opentelemetry.agent._vendor.google.api import http_pb2 as google_dot_api_dot_http__pb2 +from opentelemetry.agent._vendor.google.api import log_pb2 as google_dot_api_dot_log__pb2 +from opentelemetry.agent._vendor.google.api import logging_pb2 as google_dot_api_dot_logging__pb2 +from opentelemetry.agent._vendor.google.api import metric_pb2 as google_dot_api_dot_metric__pb2 +from opentelemetry.agent._vendor.google.api import ( + monitored_resource_pb2 as google_dot_api_dot_monitored__resource__pb2, +) +from opentelemetry.agent._vendor.google.api import monitoring_pb2 as google_dot_api_dot_monitoring__pb2 +from opentelemetry.agent._vendor.google.api import quota_pb2 as google_dot_api_dot_quota__pb2 +from opentelemetry.agent._vendor.google.api import source_info_pb2 as google_dot_api_dot_source__info__pb2 +from opentelemetry.agent._vendor.google.api import system_parameter_pb2 as google_dot_api_dot_system__parameter__pb2 +from opentelemetry.agent._vendor.google.api import usage_pb2 as google_dot_api_dot_usage__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n\x18google/api/service.proto\x12\ngoogle.api\x1a\x15google/api/auth.proto\x1a\x18google/api/backend.proto\x1a\x18google/api/billing.proto\x1a\x17google/api/client.proto\x1a\x18google/api/context.proto\x1a\x18google/api/control.proto\x1a\x1egoogle/api/documentation.proto\x1a\x19google/api/endpoint.proto\x1a\x15google/api/http.proto\x1a\x14google/api/log.proto\x1a\x18google/api/logging.proto\x1a\x17google/api/metric.proto\x1a#google/api/monitored_resource.proto\x1a\x1bgoogle/api/monitoring.proto\x1a\x16google/api/quota.proto\x1a\x1cgoogle/api/source_info.proto\x1a!google/api/system_parameter.proto\x1a\x16google/api/usage.proto\x1a\x19google/protobuf/api.proto\x1a\x1agoogle/protobuf/type.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\x82\x08\n\x07Service\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x1b\n\x13producer_project_id\x18\x16 \x01(\t\x12\n\n\x02id\x18! \x01(\t\x12\"\n\x04\x61pis\x18\x03 \x03(\x0b\x32\x14.google.protobuf.Api\x12$\n\x05types\x18\x04 \x03(\x0b\x32\x15.google.protobuf.Type\x12$\n\x05\x65nums\x18\x05 \x03(\x0b\x32\x15.google.protobuf.Enum\x12\x30\n\rdocumentation\x18\x06 \x01(\x0b\x32\x19.google.api.Documentation\x12$\n\x07\x62\x61\x63kend\x18\x08 \x01(\x0b\x32\x13.google.api.Backend\x12\x1e\n\x04http\x18\t \x01(\x0b\x32\x10.google.api.Http\x12 \n\x05quota\x18\n \x01(\x0b\x32\x11.google.api.Quota\x12\x32\n\x0e\x61uthentication\x18\x0b \x01(\x0b\x32\x1a.google.api.Authentication\x12$\n\x07\x63ontext\x18\x0c \x01(\x0b\x32\x13.google.api.Context\x12 \n\x05usage\x18\x0f \x01(\x0b\x32\x11.google.api.Usage\x12'\n\tendpoints\x18\x12 \x03(\x0b\x32\x14.google.api.Endpoint\x12$\n\x07\x63ontrol\x18\x15 \x01(\x0b\x32\x13.google.api.Control\x12'\n\x04logs\x18\x17 \x03(\x0b\x32\x19.google.api.LogDescriptor\x12-\n\x07metrics\x18\x18 \x03(\x0b\x32\x1c.google.api.MetricDescriptor\x12\x44\n\x13monitored_resources\x18\x19 \x03(\x0b\x32'.google.api.MonitoredResourceDescriptor\x12$\n\x07\x62illing\x18\x1a \x01(\x0b\x32\x13.google.api.Billing\x12$\n\x07logging\x18\x1b \x01(\x0b\x32\x13.google.api.Logging\x12*\n\nmonitoring\x18\x1c \x01(\x0b\x32\x16.google.api.Monitoring\x12\x37\n\x11system_parameters\x18\x1d \x01(\x0b\x32\x1c.google.api.SystemParameters\x12+\n\x0bsource_info\x18% \x01(\x0b\x32\x16.google.api.SourceInfo\x12*\n\npublishing\x18- \x01(\x0b\x32\x16.google.api.Publishing\x12\x34\n\x0e\x63onfig_version\x18\x14 \x01(\x0b\x32\x1c.google.protobuf.UInt32ValueBn\n\x0e\x63om.google.apiB\x0cServiceProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.service_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\014ServiceProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_SERVICE"]._serialized_start = 614 + _globals["_SERVICE"]._serialized_end = 1640 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi new file mode 100644 index 00000000000..93b393abfb7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi @@ -0,0 +1,170 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import api_pb2 as _api_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import type_pb2 as _type_pb2 +from google.protobuf import wrappers_pb2 as _wrappers_pb2 +from google.protobuf.internal import containers as _containers + +from google.api import auth_pb2 as _auth_pb2 +from google.api import backend_pb2 as _backend_pb2 +from google.api import billing_pb2 as _billing_pb2 +from google.api import client_pb2 as _client_pb2 +from google.api import context_pb2 as _context_pb2 +from google.api import control_pb2 as _control_pb2 +from google.api import documentation_pb2 as _documentation_pb2 +from google.api import endpoint_pb2 as _endpoint_pb2 +from google.api import http_pb2 as _http_pb2 +from google.api import log_pb2 as _log_pb2 +from google.api import logging_pb2 as _logging_pb2 +from google.api import metric_pb2 as _metric_pb2 +from google.api import monitored_resource_pb2 as _monitored_resource_pb2 +from google.api import monitoring_pb2 as _monitoring_pb2 +from google.api import quota_pb2 as _quota_pb2 +from google.api import source_info_pb2 as _source_info_pb2 +from google.api import system_parameter_pb2 as _system_parameter_pb2 +from google.api import usage_pb2 as _usage_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class Service(_message.Message): + __slots__ = ( + "name", + "title", + "producer_project_id", + "id", + "apis", + "types", + "enums", + "documentation", + "backend", + "http", + "quota", + "authentication", + "context", + "usage", + "endpoints", + "control", + "logs", + "metrics", + "monitored_resources", + "billing", + "logging", + "monitoring", + "system_parameters", + "source_info", + "publishing", + "config_version", + ) + NAME_FIELD_NUMBER: _ClassVar[int] + TITLE_FIELD_NUMBER: _ClassVar[int] + PRODUCER_PROJECT_ID_FIELD_NUMBER: _ClassVar[int] + ID_FIELD_NUMBER: _ClassVar[int] + APIS_FIELD_NUMBER: _ClassVar[int] + TYPES_FIELD_NUMBER: _ClassVar[int] + ENUMS_FIELD_NUMBER: _ClassVar[int] + DOCUMENTATION_FIELD_NUMBER: _ClassVar[int] + BACKEND_FIELD_NUMBER: _ClassVar[int] + HTTP_FIELD_NUMBER: _ClassVar[int] + QUOTA_FIELD_NUMBER: _ClassVar[int] + AUTHENTICATION_FIELD_NUMBER: _ClassVar[int] + CONTEXT_FIELD_NUMBER: _ClassVar[int] + USAGE_FIELD_NUMBER: _ClassVar[int] + ENDPOINTS_FIELD_NUMBER: _ClassVar[int] + CONTROL_FIELD_NUMBER: _ClassVar[int] + LOGS_FIELD_NUMBER: _ClassVar[int] + METRICS_FIELD_NUMBER: _ClassVar[int] + MONITORED_RESOURCES_FIELD_NUMBER: _ClassVar[int] + BILLING_FIELD_NUMBER: _ClassVar[int] + LOGGING_FIELD_NUMBER: _ClassVar[int] + MONITORING_FIELD_NUMBER: _ClassVar[int] + SYSTEM_PARAMETERS_FIELD_NUMBER: _ClassVar[int] + SOURCE_INFO_FIELD_NUMBER: _ClassVar[int] + PUBLISHING_FIELD_NUMBER: _ClassVar[int] + CONFIG_VERSION_FIELD_NUMBER: _ClassVar[int] + name: str + title: str + producer_project_id: str + id: str + apis: _containers.RepeatedCompositeFieldContainer[_api_pb2.Api] + types: _containers.RepeatedCompositeFieldContainer[_type_pb2.Type] + enums: _containers.RepeatedCompositeFieldContainer[_type_pb2.Enum] + documentation: _documentation_pb2.Documentation + backend: _backend_pb2.Backend + http: _http_pb2.Http + quota: _quota_pb2.Quota + authentication: _auth_pb2.Authentication + context: _context_pb2.Context + usage: _usage_pb2.Usage + endpoints: _containers.RepeatedCompositeFieldContainer[_endpoint_pb2.Endpoint] + control: _control_pb2.Control + logs: _containers.RepeatedCompositeFieldContainer[_log_pb2.LogDescriptor] + metrics: _containers.RepeatedCompositeFieldContainer[_metric_pb2.MetricDescriptor] + monitored_resources: _containers.RepeatedCompositeFieldContainer[ + _monitored_resource_pb2.MonitoredResourceDescriptor + ] + billing: _billing_pb2.Billing + logging: _logging_pb2.Logging + monitoring: _monitoring_pb2.Monitoring + system_parameters: _system_parameter_pb2.SystemParameters + source_info: _source_info_pb2.SourceInfo + publishing: _client_pb2.Publishing + config_version: _wrappers_pb2.UInt32Value + def __init__( + self, + name: _Optional[str] = ..., + title: _Optional[str] = ..., + producer_project_id: _Optional[str] = ..., + id: _Optional[str] = ..., + apis: _Optional[_Iterable[_Union[_api_pb2.Api, _Mapping]]] = ..., + types: _Optional[_Iterable[_Union[_type_pb2.Type, _Mapping]]] = ..., + enums: _Optional[_Iterable[_Union[_type_pb2.Enum, _Mapping]]] = ..., + documentation: _Optional[ + _Union[_documentation_pb2.Documentation, _Mapping] + ] = ..., + backend: _Optional[_Union[_backend_pb2.Backend, _Mapping]] = ..., + http: _Optional[_Union[_http_pb2.Http, _Mapping]] = ..., + quota: _Optional[_Union[_quota_pb2.Quota, _Mapping]] = ..., + authentication: _Optional[_Union[_auth_pb2.Authentication, _Mapping]] = ..., + context: _Optional[_Union[_context_pb2.Context, _Mapping]] = ..., + usage: _Optional[_Union[_usage_pb2.Usage, _Mapping]] = ..., + endpoints: _Optional[_Iterable[_Union[_endpoint_pb2.Endpoint, _Mapping]]] = ..., + control: _Optional[_Union[_control_pb2.Control, _Mapping]] = ..., + logs: _Optional[_Iterable[_Union[_log_pb2.LogDescriptor, _Mapping]]] = ..., + metrics: _Optional[ + _Iterable[_Union[_metric_pb2.MetricDescriptor, _Mapping]] + ] = ..., + monitored_resources: _Optional[ + _Iterable[ + _Union[_monitored_resource_pb2.MonitoredResourceDescriptor, _Mapping] + ] + ] = ..., + billing: _Optional[_Union[_billing_pb2.Billing, _Mapping]] = ..., + logging: _Optional[_Union[_logging_pb2.Logging, _Mapping]] = ..., + monitoring: _Optional[_Union[_monitoring_pb2.Monitoring, _Mapping]] = ..., + system_parameters: _Optional[ + _Union[_system_parameter_pb2.SystemParameters, _Mapping] + ] = ..., + source_info: _Optional[_Union[_source_info_pb2.SourceInfo, _Mapping]] = ..., + publishing: _Optional[_Union[_client_pb2.Publishing, _Mapping]] = ..., + config_version: _Optional[_Union[_wrappers_pb2.UInt32Value, _Mapping]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto new file mode 100644 index 00000000000..1d4094e13d5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto @@ -0,0 +1,31 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/any.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "SourceInfoProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Source information used to create a Service Config +message SourceInfo { + // All files used during config generation. + repeated google.protobuf.Any source_files = 1; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py new file mode 100644 index 00000000000..a25eebdf54d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/source_info.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/source_info.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1cgoogle/api/source_info.proto\x12\ngoogle.api\x1a\x19google/protobuf/any.proto"8\n\nSourceInfo\x12*\n\x0csource_files\x18\x01 \x03(\x0b\x32\x14.google.protobuf.AnyBq\n\x0e\x63om.google.apiB\x0fSourceInfoProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.source_info_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\017SourceInfoProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_SOURCEINFO"]._serialized_start = 71 + _globals["_SOURCEINFO"]._serialized_end = 127 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi new file mode 100644 index 00000000000..f21bfe427d0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi @@ -0,0 +1,34 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class SourceInfo(_message.Message): + __slots__ = ("source_files",) + SOURCE_FILES_FIELD_NUMBER: _ClassVar[int] + source_files: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] + def __init__( + self, source_files: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto new file mode 100644 index 00000000000..5ab1f37e1b6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto @@ -0,0 +1,96 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "SystemParameterProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// ### System parameter configuration +// +// A system parameter is a special kind of parameter defined by the API +// system, not by an individual API. It is typically mapped to an HTTP header +// and/or a URL query parameter. This configuration specifies which methods +// change the names of the system parameters. +message SystemParameters { + // Define system parameters. + // + // The parameters defined here will override the default parameters + // implemented by the system. If this field is missing from the service + // config, default system parameters will be used. Default system parameters + // and names is implementation-dependent. + // + // Example: define api key for all methods + // + // system_parameters + // rules: + // - selector: "*" + // parameters: + // - name: api_key + // url_query_parameter: api_key + // + // + // Example: define 2 api key names for a specific method. + // + // system_parameters + // rules: + // - selector: "/ListShelves" + // parameters: + // - name: api_key + // http_header: Api-Key1 + // - name: api_key + // http_header: Api-Key2 + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated SystemParameterRule rules = 1; +} + +// Define a system parameter rule mapping system parameter definitions to +// methods. +message SystemParameterRule { + // Selects the methods to which this rule applies. Use '*' to indicate all + // methods in all APIs. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // Define parameters. Multiple names may be defined for a parameter. + // For a given method call, only one of them should be used. If multiple + // names are used the behavior is implementation-dependent. + // If none of the specified names are present the behavior is + // parameter-dependent. + repeated SystemParameter parameters = 2; +} + +// Define a parameter's name and location. The parameter may be passed as either +// an HTTP header or a URL query parameter, and if both are passed the behavior +// is implementation-dependent. +message SystemParameter { + // Define the name of the parameter, such as "api_key" . It is case sensitive. + string name = 1; + + // Define the HTTP header name to use for the parameter. It is case + // insensitive. + string http_header = 2; + + // Define the URL query parameter name to use for the parameter. It is case + // sensitive. + string url_query_parameter = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py new file mode 100644 index 00000000000..550fd972fa2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/system_parameter.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/system_parameter.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n!google/api/system_parameter.proto\x12\ngoogle.api"B\n\x10SystemParameters\x12.\n\x05rules\x18\x01 \x03(\x0b\x32\x1f.google.api.SystemParameterRule"X\n\x13SystemParameterRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12/\n\nparameters\x18\x02 \x03(\x0b\x32\x1b.google.api.SystemParameter"Q\n\x0fSystemParameter\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0bhttp_header\x18\x02 \x01(\t\x12\x1b\n\x13url_query_parameter\x18\x03 \x01(\tBv\n\x0e\x63om.google.apiB\x14SystemParameterProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.system_parameter_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\024SystemParameterProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_SYSTEMPARAMETERS"]._serialized_start = 49 + _globals["_SYSTEMPARAMETERS"]._serialized_end = 115 + _globals["_SYSTEMPARAMETERRULE"]._serialized_start = 117 + _globals["_SYSTEMPARAMETERRULE"]._serialized_end = 205 + _globals["_SYSTEMPARAMETER"]._serialized_start = 207 + _globals["_SYSTEMPARAMETER"]._serialized_end = 288 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi new file mode 100644 index 00000000000..14b7b286b96 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi @@ -0,0 +1,60 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class SystemParameters(_message.Message): + __slots__ = ("rules",) + RULES_FIELD_NUMBER: _ClassVar[int] + rules: _containers.RepeatedCompositeFieldContainer[SystemParameterRule] + def __init__( + self, rules: _Optional[_Iterable[_Union[SystemParameterRule, _Mapping]]] = ... + ) -> None: ... + +class SystemParameterRule(_message.Message): + __slots__ = ("selector", "parameters") + SELECTOR_FIELD_NUMBER: _ClassVar[int] + PARAMETERS_FIELD_NUMBER: _ClassVar[int] + selector: str + parameters: _containers.RepeatedCompositeFieldContainer[SystemParameter] + def __init__( + self, + selector: _Optional[str] = ..., + parameters: _Optional[_Iterable[_Union[SystemParameter, _Mapping]]] = ..., + ) -> None: ... + +class SystemParameter(_message.Message): + __slots__ = ("name", "http_header", "url_query_parameter") + NAME_FIELD_NUMBER: _ClassVar[int] + HTTP_HEADER_FIELD_NUMBER: _ClassVar[int] + URL_QUERY_PARAMETER_FIELD_NUMBER: _ClassVar[int] + name: str + http_header: str + url_query_parameter: str + def __init__( + self, + name: _Optional[str] = ..., + http_header: _Optional[str] = ..., + url_query_parameter: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto new file mode 100644 index 00000000000..df1b93b39fd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto @@ -0,0 +1,76 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "UsageProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Configuration controlling usage of a service. +message Usage { + // Requirements that must be satisfied before a consumer project can use the + // service. Each requirement is of the form /; + // for example 'serviceusage.googleapis.com/billing-enabled'. + // + // For Google APIs, a Terms of Service requirement must be included here. + // Google Cloud APIs must include "serviceusage.googleapis.com/tos/cloud". + // Other Google APIs should include + // "serviceusage.googleapis.com/tos/universal". Additional ToS can be + // included based on the business needs. + repeated string requirements = 1; + + // A list of usage rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated UsageRule rules = 6; + + // The full resource name of a channel used for sending notifications to the + // service producer. + // + // Google Service Management currently only supports + // [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) as a notification + // channel. To use Google Cloud Pub/Sub as the channel, this must be the name + // of a Cloud Pub/Sub topic that uses the Cloud Pub/Sub topic name format + // documented in https://cloud.google.com/pubsub/docs/overview. + string producer_notification_channel = 7; +} + +// Usage configuration rules for the service. +message UsageRule { + // Selects the methods to which this rule applies. Use '*' to indicate all + // methods in all APIs. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // Use this rule to configure unregistered calls for the service. Unregistered + // calls are calls that do not contain consumer project identity. + // (Example: calls that do not contain an API key). + // + // WARNING: By default, API methods do not allow unregistered calls, and each + // method call must be identified by a consumer project identity. + bool allow_unregistered_calls = 2; + + // If true, the selected method should skip service control and the control + // plane features, such as quota and billing, will not be available. + // This flag is used by Google Cloud Endpoints to bypass checks for internal + // methods, such as service health check methods. + bool skip_service_control = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py new file mode 100644 index 00000000000..c718660a19c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/usage.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/usage.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x16google/api/usage.proto\x12\ngoogle.api"j\n\x05Usage\x12\x14\n\x0crequirements\x18\x01 \x03(\t\x12$\n\x05rules\x18\x06 \x03(\x0b\x32\x15.google.api.UsageRule\x12%\n\x1dproducer_notification_channel\x18\x07 \x01(\t"]\n\tUsageRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12 \n\x18\x61llow_unregistered_calls\x18\x02 \x01(\x08\x12\x1c\n\x14skip_service_control\x18\x03 \x01(\x08\x42l\n\x0e\x63om.google.apiB\nUsageProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.usage_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\nUsageProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" + _globals["_USAGE"]._serialized_start = 38 + _globals["_USAGE"]._serialized_end = 144 + _globals["_USAGERULE"]._serialized_start = 146 + _globals["_USAGERULE"]._serialized_end = 239 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi new file mode 100644 index 00000000000..444b29e10bb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi @@ -0,0 +1,55 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Usage(_message.Message): + __slots__ = ("requirements", "rules", "producer_notification_channel") + REQUIREMENTS_FIELD_NUMBER: _ClassVar[int] + RULES_FIELD_NUMBER: _ClassVar[int] + PRODUCER_NOTIFICATION_CHANNEL_FIELD_NUMBER: _ClassVar[int] + requirements: _containers.RepeatedScalarFieldContainer[str] + rules: _containers.RepeatedCompositeFieldContainer[UsageRule] + producer_notification_channel: str + def __init__( + self, + requirements: _Optional[_Iterable[str]] = ..., + rules: _Optional[_Iterable[_Union[UsageRule, _Mapping]]] = ..., + producer_notification_channel: _Optional[str] = ..., + ) -> None: ... + +class UsageRule(_message.Message): + __slots__ = ("selector", "allow_unregistered_calls", "skip_service_control") + SELECTOR_FIELD_NUMBER: _ClassVar[int] + ALLOW_UNREGISTERED_CALLS_FIELD_NUMBER: _ClassVar[int] + SKIP_SERVICE_CONTROL_FIELD_NUMBER: _ClassVar[int] + selector: str + allow_unregistered_calls: bool + skip_service_control: bool + def __init__( + self, + selector: _Optional[str] = ..., + allow_unregistered_calls: _Optional[bool] = ..., + skip_service_control: _Optional[bool] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto new file mode 100644 index 00000000000..fb5cac6f266 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto @@ -0,0 +1,112 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/visibility;visibility"; +option java_multiple_files = true; +option java_outer_classname = "VisibilityProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.EnumOptions { + // See `VisibilityRule`. + google.api.VisibilityRule enum_visibility = 72295727; +} + +extend google.protobuf.EnumValueOptions { + // See `VisibilityRule`. + google.api.VisibilityRule value_visibility = 72295727; +} + +extend google.protobuf.FieldOptions { + // See `VisibilityRule`. + google.api.VisibilityRule field_visibility = 72295727; +} + +extend google.protobuf.MessageOptions { + // See `VisibilityRule`. + google.api.VisibilityRule message_visibility = 72295727; +} + +extend google.protobuf.MethodOptions { + // See `VisibilityRule`. + google.api.VisibilityRule method_visibility = 72295727; +} + +extend google.protobuf.ServiceOptions { + // See `VisibilityRule`. + google.api.VisibilityRule api_visibility = 72295727; +} + +// `Visibility` restricts service consumer's access to service elements, +// such as whether an application can call a visibility-restricted method. +// The restriction is expressed by applying visibility labels on service +// elements. The visibility labels are elsewhere linked to service consumers. +// +// A service can define multiple visibility labels, but a service consumer +// should be granted at most one visibility label. Multiple visibility +// labels for a single service consumer are not supported. +// +// If an element and all its parents have no visibility label, its visibility +// is unconditionally granted. +// +// Example: +// +// visibility: +// rules: +// - selector: google.calendar.Calendar.EnhancedSearch +// restriction: PREVIEW +// - selector: google.calendar.Calendar.Delegate +// restriction: INTERNAL +// +// Here, all methods are publicly visible except for the restricted methods +// EnhancedSearch and Delegate. +message Visibility { + // A list of visibility rules that apply to individual API elements. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated VisibilityRule rules = 1; +} + +// A visibility rule provides visibility configuration for an individual API +// element. +message VisibilityRule { + // Selects methods, messages, fields, enums, etc. to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // A comma-separated list of visibility labels that apply to the `selector`. + // Any of the listed labels can be used to grant the visibility. + // + // If a rule has multiple labels, removing one of the labels but not all of + // them can break clients. + // + // Example: + // + // visibility: + // rules: + // - selector: google.calendar.Calendar.EnhancedSearch + // restriction: INTERNAL, PREVIEW + // + // Removing INTERNAL from this restriction will break clients that rely on + // this method and only had access to it through INTERNAL. + string restriction = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py new file mode 100644 index 00000000000..317306612cf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/api/visibility.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/visibility.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1bgoogle/api/visibility.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"7\n\nVisibility\x12)\n\x05rules\x18\x01 \x03(\x0b\x32\x1a.google.api.VisibilityRule"7\n\x0eVisibilityRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x13\n\x0brestriction\x18\x02 \x01(\t:T\n\x0f\x65num_visibility\x12\x1c.google.protobuf.EnumOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:Z\n\x10value_visibility\x12!.google.protobuf.EnumValueOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:V\n\x10\x66ield_visibility\x12\x1d.google.protobuf.FieldOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:Z\n\x12message_visibility\x12\x1f.google.protobuf.MessageOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:X\n\x11method_visibility\x12\x1e.google.protobuf.MethodOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:V\n\x0e\x61pi_visibility\x12\x1f.google.protobuf.ServiceOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRuleBk\n\x0e\x63om.google.apiB\x0fVisibilityProtoP\x01Z?google.golang.org/genproto/googleapis/api/visibility;visibility\xa2\x02\x04GAPIb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.api.visibility_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.apiB\017VisibilityProtoP\001Z?google.golang.org/genproto/googleapis/api/visibility;visibility\242\002\004GAPI" + _globals["_VISIBILITY"]._serialized_start = 77 + _globals["_VISIBILITY"]._serialized_end = 132 + _globals["_VISIBILITYRULE"]._serialized_start = 134 + _globals["_VISIBILITYRULE"]._serialized_end = 189 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi new file mode 100644 index 00000000000..c4d32773bd7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi @@ -0,0 +1,56 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor +ENUM_VISIBILITY_FIELD_NUMBER: _ClassVar[int] +enum_visibility: _descriptor.FieldDescriptor +VALUE_VISIBILITY_FIELD_NUMBER: _ClassVar[int] +value_visibility: _descriptor.FieldDescriptor +FIELD_VISIBILITY_FIELD_NUMBER: _ClassVar[int] +field_visibility: _descriptor.FieldDescriptor +MESSAGE_VISIBILITY_FIELD_NUMBER: _ClassVar[int] +message_visibility: _descriptor.FieldDescriptor +METHOD_VISIBILITY_FIELD_NUMBER: _ClassVar[int] +method_visibility: _descriptor.FieldDescriptor +API_VISIBILITY_FIELD_NUMBER: _ClassVar[int] +api_visibility: _descriptor.FieldDescriptor + +class Visibility(_message.Message): + __slots__ = ("rules",) + RULES_FIELD_NUMBER: _ClassVar[int] + rules: _containers.RepeatedCompositeFieldContainer[VisibilityRule] + def __init__( + self, rules: _Optional[_Iterable[_Union[VisibilityRule, _Mapping]]] = ... + ) -> None: ... + +class VisibilityRule(_message.Message): + __slots__ = ("selector", "restriction") + SELECTOR_FIELD_NUMBER: _ClassVar[int] + RESTRICTION_FIELD_NUMBER: _ClassVar[int] + selector: str + restriction: str + def __init__( + self, selector: _Optional[str] = ..., restriction: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto new file mode 100644 index 00000000000..cd44c547460 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto @@ -0,0 +1,52 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains stub messages for common resources in GCP. +// It is not intended to be directly generated, and is instead used by +// other tooling to be able to match common resource patterns. +syntax = "proto3"; + +package google.cloud; + +import "google/api/resource.proto"; + + +option (google.api.resource_definition) = { + type: "cloudresourcemanager.googleapis.com/Project" + pattern: "projects/{project}" +}; + + +option (google.api.resource_definition) = { + type: "cloudresourcemanager.googleapis.com/Organization" + pattern: "organizations/{organization}" +}; + + +option (google.api.resource_definition) = { + type: "cloudresourcemanager.googleapis.com/Folder" + pattern: "folders/{folder}" +}; + + +option (google.api.resource_definition) = { + type: "cloudbilling.googleapis.com/BillingAccount" + pattern: "billingAccounts/{billing_account}" +}; + +option (google.api.resource_definition) = { + type: "locations.googleapis.com/Location" + pattern: "projects/{project}/locations/{location}" +}; + diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py new file mode 100644 index 00000000000..fdae0c85efa --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/cloud/common_resources.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/cloud/common_resources.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.api import resource_pb2 as google_dot_api_dot_resource__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n#google/cloud/common_resources.proto\x12\x0cgoogle.cloud\x1a\x19google/api/resource.protoB\xf9\x02\xea\x41\x41\n+cloudresourcemanager.googleapis.com/Project\x12\x12projects/{project}\xea\x41P\n0cloudresourcemanager.googleapis.com/Organization\x12\x1corganizations/{organization}\xea\x41>\n*cloudresourcemanager.googleapis.com/Folder\x12\x10\x66olders/{folder}\xea\x41O\n*cloudbilling.googleapis.com/BillingAccount\x12!billingAccounts/{billing_account}\xea\x41L\n!locations.googleapis.com/Location\x12'projects/{project}/locations/{location}b\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.cloud.common_resources_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\352AA\n+cloudresourcemanager.googleapis.com/Project\022\022projects/{project}\352AP\n0cloudresourcemanager.googleapis.com/Organization\022\034organizations/{organization}\352A>\n*cloudresourcemanager.googleapis.com/Folder\022\020folders/{folder}\352AO\n*cloudbilling.googleapis.com/BillingAccount\022!billingAccounts/{billing_account}\352AL\n!locations.googleapis.com/Location\022'projects/{project}/locations/{location}" +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi new file mode 100644 index 00000000000..524a461dc1f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi @@ -0,0 +1,21 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor + +from google.api import resource_pb2 as _resource_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto new file mode 100644 index 00000000000..69f44ddac85 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto @@ -0,0 +1,150 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains custom annotations that are used by GAPIC generators to +// handle Long Running Operation methods (LRO) that are NOT compliant with +// https://google.aip.dev/151. These annotations are public for technical +// reasons only. Please DO NOT USE them in your protos. +syntax = "proto3"; + +package google.cloud; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/cloud/extendedops;extendedops"; +option java_multiple_files = true; +option java_outer_classname = "ExtendedOperationsProto"; +option java_package = "com.google.cloud"; +option objc_class_prefix = "GAPI"; + +// FieldOptions to match corresponding fields in the initial request, +// polling request and operation response messages. +// +// Example: +// +// In an API-specific operation message: +// +// message MyOperation { +// string http_error_message = 1 [(operation_field) = ERROR_MESSAGE]; +// int32 http_error_status_code = 2 [(operation_field) = ERROR_CODE]; +// string id = 3 [(operation_field) = NAME]; +// Status status = 4 [(operation_field) = STATUS]; +// } +// +// In a polling request message (the one which is used to poll for an LRO +// status): +// +// message MyPollingRequest { +// string operation = 1 [(operation_response_field) = "id"]; +// string project = 2; +// string region = 3; +// } +// +// In an initial request message (the one which starts an LRO): +// +// message MyInitialRequest { +// string my_project = 2 [(operation_request_field) = "project"]; +// string my_region = 3 [(operation_request_field) = "region"]; +// } +// +extend google.protobuf.FieldOptions { + // A field annotation that maps fields in an API-specific Operation object to + // their standard counterparts in google.longrunning.Operation. See + // OperationResponseMapping enum definition. + OperationResponseMapping operation_field = 1149; + + // A field annotation that maps fields in the initial request message + // (the one which started the LRO) to their counterparts in the polling + // request message. For non-standard LRO, the polling response may be missing + // some of the information needed to make a subsequent polling request. The + // missing information (for example, project or region ID) is contained in the + // fields of the initial request message that this annotation must be applied + // to. The string value of the annotation corresponds to the name of the + // counterpart field in the polling request message that the annotated field's + // value will be copied to. + string operation_request_field = 1150; + + // A field annotation that maps fields in the polling request message to their + // counterparts in the initial and/or polling response message. The initial + // and the polling methods return an API-specific Operation object. Some of + // the fields from that response object must be reused in the subsequent + // request (like operation name/ID) to fully identify the polled operation. + // This annotation must be applied to the fields in the polling request + // message, the string value of the annotation must correspond to the name of + // the counterpart field in the Operation response object whose value will be + // copied to the annotated field. + string operation_response_field = 1151; +} + +// MethodOptions to identify the actual service and method used for operation +// status polling. +// +// Example: +// +// In a method, which starts an LRO: +// +// service MyService { +// rpc Foo(MyInitialRequest) returns (MyOperation) { +// option (operation_service) = "MyPollingService"; +// } +// } +// +// In a polling method: +// +// service MyPollingService { +// rpc Get(MyPollingRequest) returns (MyOperation) { +// option (operation_polling_method) = true; +// } +// } +extend google.protobuf.MethodOptions { + // A method annotation that maps an LRO method (the one which starts an LRO) + // to the service, which will be used to poll for the operation status. The + // annotation must be applied to the method which starts an LRO, the string + // value of the annotation must correspond to the name of the service used to + // poll for the operation status. + string operation_service = 1249; + + // A method annotation that marks methods that can be used for polling + // operation status (e.g. the MyPollingService.Get(MyPollingRequest) method). + bool operation_polling_method = 1250; +} + +// An enum to be used to mark the essential (for polling) fields in an +// API-specific Operation object. A custom Operation object may contain many +// different fields, but only few of them are essential to conduct a successful +// polling process. +enum OperationResponseMapping { + // Do not use. + UNDEFINED = 0; + + // A field in an API-specific (custom) Operation object which carries the same + // meaning as google.longrunning.Operation.name. + NAME = 1; + + // A field in an API-specific (custom) Operation object which carries the same + // meaning as google.longrunning.Operation.done. If the annotated field is of + // an enum type, `annotated_field_name == EnumType.DONE` semantics should be + // equivalent to `Operation.done == true`. If the annotated field is of type + // boolean, then it should follow the same semantics as Operation.done. + // Otherwise, a non-empty value should be treated as `Operation.done == true`. + STATUS = 2; + + // A field in an API-specific (custom) Operation object which carries the same + // meaning as google.longrunning.Operation.error.code. + ERROR_CODE = 3; + + // A field in an API-specific (custom) Operation object which carries the same + // meaning as google.longrunning.Operation.error.message. + ERROR_MESSAGE = 4; +} \ No newline at end of file diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py new file mode 100644 index 00000000000..bf2c7eb3fa8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/cloud/extended_operations.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + "", + "google/cloud/extended_operations.proto", +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n&google/cloud/extended_operations.proto\x12\x0cgoogle.cloud\x1a google/protobuf/descriptor.proto*b\n\x18OperationResponseMapping\x12\r\n\tUNDEFINED\x10\x00\x12\x08\n\x04NAME\x10\x01\x12\n\n\x06STATUS\x10\x02\x12\x0e\n\nERROR_CODE\x10\x03\x12\x11\n\rERROR_MESSAGE\x10\x04:_\n\x0foperation_field\x12\x1d.google.protobuf.FieldOptions\x18\xfd\x08 \x01(\x0e\x32&.google.cloud.OperationResponseMapping:?\n\x17operation_request_field\x12\x1d.google.protobuf.FieldOptions\x18\xfe\x08 \x01(\t:@\n\x18operation_response_field\x12\x1d.google.protobuf.FieldOptions\x18\xff\x08 \x01(\t::\n\x11operation_service\x12\x1e.google.protobuf.MethodOptions\x18\xe1\t \x01(\t:A\n\x18operation_polling_method\x12\x1e.google.protobuf.MethodOptions\x18\xe2\t \x01(\x08\x42y\n\x10\x63om.google.cloudB\x17\x45xtendedOperationsProtoP\x01ZCgoogle.golang.org/genproto/googleapis/cloud/extendedops;extendedops\xa2\x02\x04GAPIb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.cloud.extended_operations_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\020com.google.cloudB\027ExtendedOperationsProtoP\001ZCgoogle.golang.org/genproto/googleapis/cloud/extendedops;extendedops\242\002\004GAPI" + _globals["_OPERATIONRESPONSEMAPPING"]._serialized_start = 90 + _globals["_OPERATIONRESPONSEMAPPING"]._serialized_end = 188 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi new file mode 100644 index 00000000000..8f29d450773 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi @@ -0,0 +1,45 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class OperationResponseMapping(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + UNDEFINED: _ClassVar[OperationResponseMapping] + NAME: _ClassVar[OperationResponseMapping] + STATUS: _ClassVar[OperationResponseMapping] + ERROR_CODE: _ClassVar[OperationResponseMapping] + ERROR_MESSAGE: _ClassVar[OperationResponseMapping] + +UNDEFINED: OperationResponseMapping +NAME: OperationResponseMapping +STATUS: OperationResponseMapping +ERROR_CODE: OperationResponseMapping +ERROR_MESSAGE: OperationResponseMapping +OPERATION_FIELD_FIELD_NUMBER: _ClassVar[int] +operation_field: _descriptor.FieldDescriptor +OPERATION_REQUEST_FIELD_FIELD_NUMBER: _ClassVar[int] +operation_request_field: _descriptor.FieldDescriptor +OPERATION_RESPONSE_FIELD_FIELD_NUMBER: _ClassVar[int] +operation_response_field: _descriptor.FieldDescriptor +OPERATION_SERVICE_FIELD_NUMBER: _ClassVar[int] +operation_service: _descriptor.FieldDescriptor +OPERATION_POLLING_METHOD_FIELD_NUMBER: _ClassVar[int] +operation_polling_method: _descriptor.FieldDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto new file mode 100644 index 00000000000..36a0b0e89dd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto @@ -0,0 +1,108 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.cloud.location; + +import "google/api/annotations.proto"; +import "google/protobuf/any.proto"; +import "google/api/client.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/cloud/location;location"; +option java_multiple_files = true; +option java_outer_classname = "LocationsProto"; +option java_package = "com.google.cloud.location"; + +// An abstract interface that provides location-related information for +// a service. Service-specific metadata is provided through the +// [Location.metadata][google.cloud.location.Location.metadata] field. +service Locations { + option (google.api.default_host) = "cloud.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Lists information about the supported locations for this service. + rpc ListLocations(ListLocationsRequest) returns (ListLocationsResponse) { + option (google.api.http) = { + get: "/v1/{name=locations}" + additional_bindings { + get: "/v1/{name=projects/*}/locations" + } + }; + } + + // Gets information about a location. + rpc GetLocation(GetLocationRequest) returns (Location) { + option (google.api.http) = { + get: "/v1/{name=locations/*}" + additional_bindings { + get: "/v1/{name=projects/*/locations/*}" + } + }; + } +} + +// The request message for [Locations.ListLocations][google.cloud.location.Locations.ListLocations]. +message ListLocationsRequest { + // The resource that owns the locations collection, if applicable. + string name = 1; + + // The standard list filter. + string filter = 2; + + // The standard list page size. + int32 page_size = 3; + + // The standard list page token. + string page_token = 4; +} + +// The response message for [Locations.ListLocations][google.cloud.location.Locations.ListLocations]. +message ListLocationsResponse { + // A list of locations that matches the specified filter in the request. + repeated Location locations = 1; + + // The standard List next-page token. + string next_page_token = 2; +} + +// The request message for [Locations.GetLocation][google.cloud.location.Locations.GetLocation]. +message GetLocationRequest { + // Resource name for the location. + string name = 1; +} + +// A resource that represents Google Cloud Platform location. +message Location { + // Resource name for the location, which may vary between implementations. + // For example: `"projects/example-project/locations/us-east1"` + string name = 1; + + // The canonical id for this location. For example: `"us-east1"`. + string location_id = 4; + + // The friendly name for this location, typically a nearby city name. + // For example, "Tokyo". + string display_name = 5; + + // Cross-service attributes for the location. For example + // + // {"cloud.googleapis.com/region": "us-east1"} + map labels = 2; + + // Service-specific metadata. For example the available capacity at the given + // location. + google.protobuf.Any metadata = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py new file mode 100644 index 00000000000..b7de50539ba --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/cloud/location/locations.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + "", + "google/cloud/location/locations.proto", +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 + +from opentelemetry.agent._vendor.google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 +from opentelemetry.agent._vendor.google.api import client_pb2 as google_dot_api_dot_client__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n%google/cloud/location/locations.proto\x12\x15google.cloud.location\x1a\x1cgoogle/api/annotations.proto\x1a\x19google/protobuf/any.proto\x1a\x17google/api/client.proto"[\n\x14ListLocationsRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\x12\x11\n\tpage_size\x18\x03 \x01(\x05\x12\x12\n\npage_token\x18\x04 \x01(\t"d\n\x15ListLocationsResponse\x12\x32\n\tlocations\x18\x01 \x03(\x0b\x32\x1f.google.cloud.location.Location\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t""\n\x12GetLocationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"\xd7\x01\n\x08Location\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0blocation_id\x18\x04 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x05 \x01(\t\x12;\n\x06labels\x18\x02 \x03(\x0b\x32+.google.cloud.location.Location.LabelsEntry\x12&\n\x08metadata\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x32\xa4\x03\n\tLocations\x12\xab\x01\n\rListLocations\x12+.google.cloud.location.ListLocationsRequest\x1a,.google.cloud.location.ListLocationsResponse"?\x82\xd3\xe4\x93\x02\x39\x12\x14/v1/{name=locations}Z!\x12\x1f/v1/{name=projects/*}/locations\x12\x9e\x01\n\x0bGetLocation\x12).google.cloud.location.GetLocationRequest\x1a\x1f.google.cloud.location.Location"C\x82\xd3\xe4\x93\x02=\x12\x16/v1/{name=locations/*}Z#\x12!/v1/{name=projects/*/locations/*}\x1aH\xca\x41\x14\x63loud.googleapis.com\xd2\x41.https://www.googleapis.com/auth/cloud-platformBo\n\x19\x63om.google.cloud.locationB\x0eLocationsProtoP\x01Z=google.golang.org/genproto/googleapis/cloud/location;location\xf8\x01\x01\x62\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.cloud.location.locations_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\031com.google.cloud.locationB\016LocationsProtoP\001Z=google.golang.org/genproto/googleapis/cloud/location;location\370\001\001" + _globals["_LOCATION_LABELSENTRY"]._loaded_options = None + _globals["_LOCATION_LABELSENTRY"]._serialized_options = b"8\001" + _globals["_LOCATIONS"]._loaded_options = None + _globals[ + "_LOCATIONS" + ]._serialized_options = b"\312A\024cloud.googleapis.com\322A.https://www.googleapis.com/auth/cloud-platform" + _globals["_LOCATIONS"].methods_by_name["ListLocations"]._loaded_options = None + _globals["_LOCATIONS"].methods_by_name[ + "ListLocations" + ]._serialized_options = b"\202\323\344\223\0029\022\024/v1/{name=locations}Z!\022\037/v1/{name=projects/*}/locations" + _globals["_LOCATIONS"].methods_by_name["GetLocation"]._loaded_options = None + _globals["_LOCATIONS"].methods_by_name[ + "GetLocation" + ]._serialized_options = b"\202\323\344\223\002=\022\026/v1/{name=locations/*}Z#\022!/v1/{name=projects/*/locations/*}" + _globals["_LISTLOCATIONSREQUEST"]._serialized_start = 146 + _globals["_LISTLOCATIONSREQUEST"]._serialized_end = 237 + _globals["_LISTLOCATIONSRESPONSE"]._serialized_start = 239 + _globals["_LISTLOCATIONSRESPONSE"]._serialized_end = 339 + _globals["_GETLOCATIONREQUEST"]._serialized_start = 341 + _globals["_GETLOCATIONREQUEST"]._serialized_end = 375 + _globals["_LOCATION"]._serialized_start = 378 + _globals["_LOCATION"]._serialized_end = 593 + _globals["_LOCATION_LABELSENTRY"]._serialized_start = 548 + _globals["_LOCATION_LABELSENTRY"]._serialized_end = 593 + _globals["_LOCATIONS"]._serialized_start = 596 + _globals["_LOCATIONS"]._serialized_end = 1016 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi new file mode 100644 index 00000000000..7454a9da707 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi @@ -0,0 +1,96 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +from google.api import annotations_pb2 as _annotations_pb2 +from google.api import client_pb2 as _client_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class ListLocationsRequest(_message.Message): + __slots__ = ("name", "filter", "page_size", "page_token") + NAME_FIELD_NUMBER: _ClassVar[int] + FILTER_FIELD_NUMBER: _ClassVar[int] + PAGE_SIZE_FIELD_NUMBER: _ClassVar[int] + PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] + name: str + filter: str + page_size: int + page_token: str + def __init__( + self, + name: _Optional[str] = ..., + filter: _Optional[str] = ..., + page_size: _Optional[int] = ..., + page_token: _Optional[str] = ..., + ) -> None: ... + +class ListLocationsResponse(_message.Message): + __slots__ = ("locations", "next_page_token") + LOCATIONS_FIELD_NUMBER: _ClassVar[int] + NEXT_PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] + locations: _containers.RepeatedCompositeFieldContainer[Location] + next_page_token: str + def __init__( + self, + locations: _Optional[_Iterable[_Union[Location, _Mapping]]] = ..., + next_page_token: _Optional[str] = ..., + ) -> None: ... + +class GetLocationRequest(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + +class Location(_message.Message): + __slots__ = ("name", "location_id", "display_name", "labels", "metadata") + class LabelsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + NAME_FIELD_NUMBER: _ClassVar[int] + LOCATION_ID_FIELD_NUMBER: _ClassVar[int] + DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + name: str + location_id: str + display_name: str + labels: _containers.ScalarMap[str, str] + metadata: _any_pb2.Any + def __init__( + self, + name: _Optional[str] = ..., + location_id: _Optional[str] = ..., + display_name: _Optional[str] = ..., + labels: _Optional[_Mapping[str, str]] = ..., + metadata: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto new file mode 100644 index 00000000000..0f2855c15a6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto @@ -0,0 +1,98 @@ +// Copyright 2020 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +syntax = "proto3"; + +package google.gapic.metadata; + +option csharp_namespace = "Google.Gapic.Metadata"; +option go_package = "google.golang.org/genproto/googleapis/gapic/metadata;metadata"; +option java_multiple_files = true; +option java_outer_classname = "GapicMetadataProto"; +option java_package = "com.google.gapic.metadata"; +option php_namespace = "Google\\Gapic\\Metadata"; +option ruby_package = "Google::Gapic::Metadata"; + +// Metadata about a GAPIC library service for a specific combination of API, +// version, and computer language. +message GapicMetadata { + // Schema version of this proto. Current value: 1.0 + string schema = 1; + + // Any human-readable comments to be included in this file. + string comment = 2; + + // Computer language of this generated language. This must be + // spelled out as it spoken in English, with no capitalization or + // separators (e.g. "csharp", "nodejs"). + string language = 3; + + // The proto package containing the API definition for which this + // GAPIC library was generated. + string proto_package = 4; + + // The language-specific library package for this GAPIC library. + string library_package = 5; + + // A map from each proto-defined service to ServiceForTransports, + // which allows listing information about transport-specific + // implementations of the service. + // + // The key is the name of the service as it appears in the .proto + // file. + map services = 6; + + // A map from a transport name to ServiceAsClient, which allows + // listing information about the client objects that implement the + // parent RPC service for the specified transport. + message ServiceForTransport { + // Map of transport name to ServiceAsClient. The key name is the transport, + // lower-cased with no separators (e.g. "grpc", "rest"). + map clients = 1; + + // The API version for the interface definition found in the + // `google.api.api_version` annotation of this proto-defined service during + // code generation. + // This is the value populated by the client in the API version request + // parameter as per + // [AIP-4236](https://google.aip.dev/client-libraries/4236). + string api_version = 2; + } + + // Information about a specific client implementing a proto-defined service. + message ServiceAsClient { + // The name of the library client formatted as it appears in the source code + string library_client = 1; + + // A mapping from each proto-defined RPC name to the the list of + // methods in library_client that implement it. There can be more + // than one library_client method for each RPC. RPCs with no + // library_client methods need not be included. + // + // The key name is the name of the RPC as defined and formatted in + // the proto file. + map rpcs = 2; + } + + // List of GAPIC client methods implementing the proto-defined RPC + // for the transport and service specified in the containing + // structures. + message MethodList { + // List of methods for a specific proto-service client in the + // GAPIC. These names should be formatted as they appear in the + // source code. + repeated string methods = 1; + } +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py new file mode 100644 index 00000000000..f269f536cd7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/gapic/metadata/gapic_metadata.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + "", + "google/gapic/metadata/gapic_metadata.proto", +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n*google/gapic/metadata/gapic_metadata.proto\x12\x15google.gapic.metadata"\x85\x06\n\rGapicMetadata\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12\x0f\n\x07\x63omment\x18\x02 \x01(\t\x12\x10\n\x08language\x18\x03 \x01(\t\x12\x15\n\rproto_package\x18\x04 \x01(\t\x12\x17\n\x0flibrary_package\x18\x05 \x01(\t\x12\x44\n\x08services\x18\x06 \x03(\x0b\x32\x32.google.gapic.metadata.GapicMetadata.ServicesEntry\x1ai\n\rServicesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.google.gapic.metadata.GapicMetadata.ServiceForTransport:\x02\x38\x01\x1a\xe8\x01\n\x13ServiceForTransport\x12V\n\x07\x63lients\x18\x01 \x03(\x0b\x32\x45.google.gapic.metadata.GapicMetadata.ServiceForTransport.ClientsEntry\x12\x13\n\x0b\x61pi_version\x18\x02 \x01(\t\x1a\x64\n\x0c\x43lientsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x43\n\x05value\x18\x02 \x01(\x0b\x32\x34.google.gapic.metadata.GapicMetadata.ServiceAsClient:\x02\x38\x01\x1a\xd5\x01\n\x0fServiceAsClient\x12\x16\n\x0elibrary_client\x18\x01 \x01(\t\x12L\n\x04rpcs\x18\x02 \x03(\x0b\x32>.google.gapic.metadata.GapicMetadata.ServiceAsClient.RpcsEntry\x1a\\\n\tRpcsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12>\n\x05value\x18\x02 \x01(\x0b\x32/.google.gapic.metadata.GapicMetadata.MethodList:\x02\x38\x01\x1a\x1d\n\nMethodList\x12\x0f\n\x07methods\x18\x01 \x03(\tB\xba\x01\n\x19\x63om.google.gapic.metadataB\x12GapicMetadataProtoP\x01Z=google.golang.org/genproto/googleapis/gapic/metadata;metadata\xaa\x02\x15Google.Gapic.Metadata\xca\x02\x15Google\\Gapic\\Metadata\xea\x02\x17Google::Gapic::Metadatab\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.gapic.metadata.gapic_metadata_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\031com.google.gapic.metadataB\022GapicMetadataProtoP\001Z=google.golang.org/genproto/googleapis/gapic/metadata;metadata\252\002\025Google.Gapic.Metadata\312\002\025Google\\Gapic\\Metadata\352\002\027Google::Gapic::Metadata" + _globals["_GAPICMETADATA_SERVICESENTRY"]._loaded_options = None + _globals["_GAPICMETADATA_SERVICESENTRY"]._serialized_options = b"8\001" + _globals["_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY"]._loaded_options = None + _globals[ + "_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY" + ]._serialized_options = b"8\001" + _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._loaded_options = None + _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._serialized_options = b"8\001" + _globals["_GAPICMETADATA"]._serialized_start = 70 + _globals["_GAPICMETADATA"]._serialized_end = 843 + _globals["_GAPICMETADATA_SERVICESENTRY"]._serialized_start = 256 + _globals["_GAPICMETADATA_SERVICESENTRY"]._serialized_end = 361 + _globals["_GAPICMETADATA_SERVICEFORTRANSPORT"]._serialized_start = 364 + _globals["_GAPICMETADATA_SERVICEFORTRANSPORT"]._serialized_end = 596 + _globals["_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY"]._serialized_start = 496 + _globals["_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY"]._serialized_end = 596 + _globals["_GAPICMETADATA_SERVICEASCLIENT"]._serialized_start = 599 + _globals["_GAPICMETADATA_SERVICEASCLIENT"]._serialized_end = 812 + _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._serialized_start = 720 + _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._serialized_end = 812 + _globals["_GAPICMETADATA_METHODLIST"]._serialized_start = 814 + _globals["_GAPICMETADATA_METHODLIST"]._serialized_end = 843 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi new file mode 100644 index 00000000000..85b594cbc02 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi @@ -0,0 +1,122 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class GapicMetadata(_message.Message): + __slots__ = ( + "schema", + "comment", + "language", + "proto_package", + "library_package", + "services", + ) + class ServicesEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: GapicMetadata.ServiceForTransport + def __init__( + self, + key: _Optional[str] = ..., + value: _Optional[_Union[GapicMetadata.ServiceForTransport, _Mapping]] = ..., + ) -> None: ... + + class ServiceForTransport(_message.Message): + __slots__ = ("clients", "api_version") + class ClientsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: GapicMetadata.ServiceAsClient + def __init__( + self, + key: _Optional[str] = ..., + value: _Optional[_Union[GapicMetadata.ServiceAsClient, _Mapping]] = ..., + ) -> None: ... + + CLIENTS_FIELD_NUMBER: _ClassVar[int] + API_VERSION_FIELD_NUMBER: _ClassVar[int] + clients: _containers.MessageMap[str, GapicMetadata.ServiceAsClient] + api_version: str + def __init__( + self, + clients: _Optional[_Mapping[str, GapicMetadata.ServiceAsClient]] = ..., + api_version: _Optional[str] = ..., + ) -> None: ... + + class ServiceAsClient(_message.Message): + __slots__ = ("library_client", "rpcs") + class RpcsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: GapicMetadata.MethodList + def __init__( + self, + key: _Optional[str] = ..., + value: _Optional[_Union[GapicMetadata.MethodList, _Mapping]] = ..., + ) -> None: ... + + LIBRARY_CLIENT_FIELD_NUMBER: _ClassVar[int] + RPCS_FIELD_NUMBER: _ClassVar[int] + library_client: str + rpcs: _containers.MessageMap[str, GapicMetadata.MethodList] + def __init__( + self, + library_client: _Optional[str] = ..., + rpcs: _Optional[_Mapping[str, GapicMetadata.MethodList]] = ..., + ) -> None: ... + + class MethodList(_message.Message): + __slots__ = ("methods",) + METHODS_FIELD_NUMBER: _ClassVar[int] + methods: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, methods: _Optional[_Iterable[str]] = ...) -> None: ... + + SCHEMA_FIELD_NUMBER: _ClassVar[int] + COMMENT_FIELD_NUMBER: _ClassVar[int] + LANGUAGE_FIELD_NUMBER: _ClassVar[int] + PROTO_PACKAGE_FIELD_NUMBER: _ClassVar[int] + LIBRARY_PACKAGE_FIELD_NUMBER: _ClassVar[int] + SERVICES_FIELD_NUMBER: _ClassVar[int] + schema: str + comment: str + language: str + proto_package: str + library_package: str + services: _containers.MessageMap[str, GapicMetadata.ServiceForTransport] + def __init__( + self, + schema: _Optional[str] = ..., + comment: _Optional[str] = ..., + language: _Optional[str] = ..., + proto_package: _Optional[str] = ..., + library_package: _Optional[str] = ..., + services: _Optional[_Mapping[str, GapicMetadata.ServiceForTransport]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto new file mode 100644 index 00000000000..b31522b69c7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto @@ -0,0 +1,95 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.logging.type; + +import "google/protobuf/duration.proto"; + +option csharp_namespace = "Google.Cloud.Logging.Type"; +option go_package = "google.golang.org/genproto/googleapis/logging/type;ltype"; +option java_multiple_files = true; +option java_outer_classname = "HttpRequestProto"; +option java_package = "com.google.logging.type"; +option php_namespace = "Google\\Cloud\\Logging\\Type"; +option ruby_package = "Google::Cloud::Logging::Type"; + +// A common proto for logging HTTP requests. Only contains semantics +// defined by the HTTP specification. Product-specific logging +// information MUST be defined in a separate message. +message HttpRequest { + // The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`. + string request_method = 1; + + // The scheme (http, https), the host name, the path and the query + // portion of the URL that was requested. + // Example: `"http://example.com/some/info?color=red"`. + string request_url = 2; + + // The size of the HTTP request message in bytes, including the request + // headers and the request body. + int64 request_size = 3; + + // The response code indicating the status of response. + // Examples: 200, 404. + int32 status = 4; + + // The size of the HTTP response message sent back to the client, in bytes, + // including the response headers and the response body. + int64 response_size = 5; + + // The user agent sent by the client. Example: + // `"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET + // CLR 1.0.3705)"`. + string user_agent = 6; + + // The IP address (IPv4 or IPv6) of the client that issued the HTTP + // request. This field can include port information. Examples: + // `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. + string remote_ip = 7; + + // The IP address (IPv4 or IPv6) of the origin server that the request was + // sent to. This field can include port information. Examples: + // `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. + string server_ip = 13; + + // The referer URL of the request, as defined in + // [HTTP/1.1 Header Field + // Definitions](https://datatracker.ietf.org/doc/html/rfc2616#section-14.36). + string referer = 8; + + // The request processing latency on the server, from the time the request was + // received until the response was sent. + google.protobuf.Duration latency = 14; + + // Whether or not a cache lookup was attempted. + bool cache_lookup = 11; + + // Whether or not an entity was served from cache + // (with or without validation). + bool cache_hit = 9; + + // Whether or not the response was validated with the origin server before + // being served from cache. This field is only meaningful if `cache_hit` is + // True. + bool cache_validated_with_origin_server = 10; + + // The number of HTTP response bytes inserted into cache. Set only when a + // cache fill was attempted. + int64 cache_fill_bytes = 12; + + // Protocol used for the request. Examples: "HTTP/1.1", "HTTP/2", "websocket" + string protocol = 15; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py new file mode 100644 index 00000000000..560ae78b3cd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/logging/type/http_request.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + "", + "google/logging/type/http_request.proto", +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n&google/logging/type/http_request.proto\x12\x13google.logging.type\x1a\x1egoogle/protobuf/duration.proto"\xef\x02\n\x0bHttpRequest\x12\x16\n\x0erequest_method\x18\x01 \x01(\t\x12\x13\n\x0brequest_url\x18\x02 \x01(\t\x12\x14\n\x0crequest_size\x18\x03 \x01(\x03\x12\x0e\n\x06status\x18\x04 \x01(\x05\x12\x15\n\rresponse_size\x18\x05 \x01(\x03\x12\x12\n\nuser_agent\x18\x06 \x01(\t\x12\x11\n\tremote_ip\x18\x07 \x01(\t\x12\x11\n\tserver_ip\x18\r \x01(\t\x12\x0f\n\x07referer\x18\x08 \x01(\t\x12*\n\x07latency\x18\x0e \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x14\n\x0c\x63\x61\x63he_lookup\x18\x0b \x01(\x08\x12\x11\n\tcache_hit\x18\t \x01(\x08\x12*\n"cache_validated_with_origin_server\x18\n \x01(\x08\x12\x18\n\x10\x63\x61\x63he_fill_bytes\x18\x0c \x01(\x03\x12\x10\n\x08protocol\x18\x0f \x01(\tB\xbe\x01\n\x17\x63om.google.logging.typeB\x10HttpRequestProtoP\x01Z8google.golang.org/genproto/googleapis/logging/type;ltype\xaa\x02\x19Google.Cloud.Logging.Type\xca\x02\x19Google\\Cloud\\Logging\\Type\xea\x02\x1cGoogle::Cloud::Logging::Typeb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.logging.type.http_request_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\027com.google.logging.typeB\020HttpRequestProtoP\001Z8google.golang.org/genproto/googleapis/logging/type;ltype\252\002\031Google.Cloud.Logging.Type\312\002\031Google\\Cloud\\Logging\\Type\352\002\034Google::Cloud::Logging::Type" + _globals["_HTTPREQUEST"]._serialized_start = 96 + _globals["_HTTPREQUEST"]._serialized_end = 463 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi new file mode 100644 index 00000000000..5a05ecfb46a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi @@ -0,0 +1,94 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import duration_pb2 as _duration_pb2 +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class HttpRequest(_message.Message): + __slots__ = ( + "request_method", + "request_url", + "request_size", + "status", + "response_size", + "user_agent", + "remote_ip", + "server_ip", + "referer", + "latency", + "cache_lookup", + "cache_hit", + "cache_validated_with_origin_server", + "cache_fill_bytes", + "protocol", + ) + REQUEST_METHOD_FIELD_NUMBER: _ClassVar[int] + REQUEST_URL_FIELD_NUMBER: _ClassVar[int] + REQUEST_SIZE_FIELD_NUMBER: _ClassVar[int] + STATUS_FIELD_NUMBER: _ClassVar[int] + RESPONSE_SIZE_FIELD_NUMBER: _ClassVar[int] + USER_AGENT_FIELD_NUMBER: _ClassVar[int] + REMOTE_IP_FIELD_NUMBER: _ClassVar[int] + SERVER_IP_FIELD_NUMBER: _ClassVar[int] + REFERER_FIELD_NUMBER: _ClassVar[int] + LATENCY_FIELD_NUMBER: _ClassVar[int] + CACHE_LOOKUP_FIELD_NUMBER: _ClassVar[int] + CACHE_HIT_FIELD_NUMBER: _ClassVar[int] + CACHE_VALIDATED_WITH_ORIGIN_SERVER_FIELD_NUMBER: _ClassVar[int] + CACHE_FILL_BYTES_FIELD_NUMBER: _ClassVar[int] + PROTOCOL_FIELD_NUMBER: _ClassVar[int] + request_method: str + request_url: str + request_size: int + status: int + response_size: int + user_agent: str + remote_ip: str + server_ip: str + referer: str + latency: _duration_pb2.Duration + cache_lookup: bool + cache_hit: bool + cache_validated_with_origin_server: bool + cache_fill_bytes: int + protocol: str + def __init__( + self, + request_method: _Optional[str] = ..., + request_url: _Optional[str] = ..., + request_size: _Optional[int] = ..., + status: _Optional[int] = ..., + response_size: _Optional[int] = ..., + user_agent: _Optional[str] = ..., + remote_ip: _Optional[str] = ..., + server_ip: _Optional[str] = ..., + referer: _Optional[str] = ..., + latency: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + cache_lookup: _Optional[bool] = ..., + cache_hit: _Optional[bool] = ..., + cache_validated_with_origin_server: _Optional[bool] = ..., + cache_fill_bytes: _Optional[int] = ..., + protocol: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto new file mode 100644 index 00000000000..406b8173a3a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto @@ -0,0 +1,71 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.logging.type; + +option csharp_namespace = "Google.Cloud.Logging.Type"; +option go_package = "google.golang.org/genproto/googleapis/logging/type;ltype"; +option java_multiple_files = true; +option java_outer_classname = "LogSeverityProto"; +option java_package = "com.google.logging.type"; +option objc_class_prefix = "GLOG"; +option php_namespace = "Google\\Cloud\\Logging\\Type"; +option ruby_package = "Google::Cloud::Logging::Type"; + +// The severity of the event described in a log entry, expressed as one of the +// standard severity levels listed below. For your reference, the levels are +// assigned the listed numeric values. The effect of using numeric values other +// than those listed is undefined. +// +// You can filter for log entries by severity. For example, the following +// filter expression will match log entries with severities `INFO`, `NOTICE`, +// and `WARNING`: +// +// severity > DEBUG AND severity <= WARNING +// +// If you are writing log entries, you should map other severity encodings to +// one of these standard levels. For example, you might map all of Java's FINE, +// FINER, and FINEST levels to `LogSeverity.DEBUG`. You can preserve the +// original severity level in the log entry payload if you wish. +enum LogSeverity { + // (0) The log entry has no assigned severity level. + DEFAULT = 0; + + // (100) Debug or trace information. + DEBUG = 100; + + // (200) Routine information, such as ongoing status or performance. + INFO = 200; + + // (300) Normal but significant events, such as start up, shut down, or + // a configuration change. + NOTICE = 300; + + // (400) Warning events might cause problems. + WARNING = 400; + + // (500) Error events are likely to cause problems. + ERROR = 500; + + // (600) Critical events cause more severe problems or outages. + CRITICAL = 600; + + // (700) A person must take an action immediately. + ALERT = 700; + + // (800) One or more systems are unusable. + EMERGENCY = 800; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py new file mode 100644 index 00000000000..009b1602e3e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/logging/type/log_severity.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + "", + "google/logging/type/log_severity.proto", +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n&google/logging/type/log_severity.proto\x12\x13google.logging.type*\x82\x01\n\x0bLogSeverity\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x64\x12\t\n\x04INFO\x10\xc8\x01\x12\x0b\n\x06NOTICE\x10\xac\x02\x12\x0c\n\x07WARNING\x10\x90\x03\x12\n\n\x05\x45RROR\x10\xf4\x03\x12\r\n\x08\x43RITICAL\x10\xd8\x04\x12\n\n\x05\x41LERT\x10\xbc\x05\x12\x0e\n\tEMERGENCY\x10\xa0\x06\x42\xc5\x01\n\x17\x63om.google.logging.typeB\x10LogSeverityProtoP\x01Z8google.golang.org/genproto/googleapis/logging/type;ltype\xa2\x02\x04GLOG\xaa\x02\x19Google.Cloud.Logging.Type\xca\x02\x19Google\\Cloud\\Logging\\Type\xea\x02\x1cGoogle::Cloud::Logging::Typeb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.logging.type.log_severity_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\027com.google.logging.typeB\020LogSeverityProtoP\001Z8google.golang.org/genproto/googleapis/logging/type;ltype\242\002\004GLOG\252\002\031Google.Cloud.Logging.Type\312\002\031Google\\Cloud\\Logging\\Type\352\002\034Google::Cloud::Logging::Type" + _globals["_LOGSEVERITY"]._serialized_start = 64 + _globals["_LOGSEVERITY"]._serialized_end = 194 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi new file mode 100644 index 00000000000..eeafb8ed88d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi @@ -0,0 +1,42 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class LogSeverity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + DEFAULT: _ClassVar[LogSeverity] + DEBUG: _ClassVar[LogSeverity] + INFO: _ClassVar[LogSeverity] + NOTICE: _ClassVar[LogSeverity] + WARNING: _ClassVar[LogSeverity] + ERROR: _ClassVar[LogSeverity] + CRITICAL: _ClassVar[LogSeverity] + ALERT: _ClassVar[LogSeverity] + EMERGENCY: _ClassVar[LogSeverity] + +DEFAULT: LogSeverity +DEBUG: LogSeverity +INFO: LogSeverity +NOTICE: LogSeverity +WARNING: LogSeverity +ERROR: LogSeverity +CRITICAL: LogSeverity +ALERT: LogSeverity +EMERGENCY: LogSeverity diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py new file mode 100644 index 00000000000..7daa5f84590 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py @@ -0,0 +1,20 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This module is provided for backwards compatibility with +# googleapis-common-protos <= 1.5.0, where this was the import path. + +from __future__ import absolute_import + +from opentelemetry.agent._vendor.google.longrunning.operations_grpc_pb2 import * # noqa: F401, F403 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py new file mode 100644 index 00000000000..51bf99d5a26 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py @@ -0,0 +1,16 @@ +# This module is provided for backwards compatibility with +# googleapis-common-protos <= 1.52.0, where this import path contained +# all of the message and gRPC definitions. + +from opentelemetry.agent._vendor.google.longrunning.operations_pb2_grpc import * +from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import * +from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import ( + _CANCELOPERATIONREQUEST, + _DELETEOPERATIONREQUEST, + _GETOPERATIONREQUEST, + _LISTOPERATIONSREQUEST, + _LISTOPERATIONSRESPONSE, + _OPERATION, + _OPERATIONINFO, + _OPERATIONS, +) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py new file mode 100644 index 00000000000..81758b841a7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py @@ -0,0 +1,45 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Safe implementation of long-running operations with and without gRPC. + +Multiplexes between versions of long-running operations with and without gRPC. +The former is preferred, but not possible in all environments (such as Google +AppEngine Standard). +""" + +try: + from opentelemetry.agent._vendor.google.longrunning.operations_grpc_pb2 import * + from opentelemetry.agent._vendor.google.longrunning.operations_grpc_pb2 import ( + _CANCELOPERATIONREQUEST, + _DELETEOPERATIONREQUEST, + _GETOPERATIONREQUEST, + _LISTOPERATIONSREQUEST, + _LISTOPERATIONSRESPONSE, + _OPERATION, + _OPERATIONINFO, + _OPERATIONS, + ) +except ImportError: + from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import * + from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import ( + _CANCELOPERATIONREQUEST, + _DELETEOPERATIONREQUEST, + _GETOPERATIONREQUEST, + _LISTOPERATIONSREQUEST, + _LISTOPERATIONSRESPONSE, + _OPERATION, + _OPERATIONINFO, + _OPERATIONS, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto new file mode 100644 index 00000000000..63df207d258 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto @@ -0,0 +1,265 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.longrunning; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/descriptor.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/empty.proto"; +import "google/rpc/status.proto"; + +option csharp_namespace = "Google.LongRunning"; +option go_package = "cloud.google.com/go/longrunning/autogen/longrunningpb;longrunningpb"; +option java_multiple_files = true; +option java_outer_classname = "OperationsProto"; +option java_package = "com.google.longrunning"; +option objc_class_prefix = "GLRUN"; +option php_namespace = "Google\\LongRunning"; + +extend google.protobuf.MethodOptions { + // Additional information regarding long-running operations. + // In particular, this specifies the types that are returned from + // long-running operations. + // + // Required for methods that return `google.longrunning.Operation`; invalid + // otherwise. + google.longrunning.OperationInfo operation_info = 1049; +} + +// Manages long-running operations with an API service. +// +// When an API method normally takes long time to complete, it can be designed +// to return [Operation][google.longrunning.Operation] to the client, and the +// client can use this interface to receive the real response asynchronously by +// polling the operation resource, or pass the operation resource to another API +// (such as Pub/Sub API) to receive the response. Any API service that returns +// long-running operations should implement the `Operations` interface so +// developers can have a consistent client experience. +service Operations { + option (google.api.default_host) = "longrunning.googleapis.com"; + + // Lists operations that match the specified filter in the request. If the + // server doesn't support this method, it returns `UNIMPLEMENTED`. + rpc ListOperations(ListOperationsRequest) returns (ListOperationsResponse) { + option (google.api.http) = { + get: "/v1/{name=operations}" + }; + option (google.api.method_signature) = "name,filter"; + } + + // Gets the latest state of a long-running operation. Clients can use this + // method to poll the operation result at intervals as recommended by the API + // service. + rpc GetOperation(GetOperationRequest) returns (Operation) { + option (google.api.http) = { + get: "/v1/{name=operations/**}" + }; + option (google.api.method_signature) = "name"; + } + + // Deletes a long-running operation. This method indicates that the client is + // no longer interested in the operation result. It does not cancel the + // operation. If the server doesn't support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. + rpc DeleteOperation(DeleteOperationRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/v1/{name=operations/**}" + }; + option (google.api.method_signature) = "name"; + } + + // Starts asynchronous cancellation on a long-running operation. The server + // makes a best effort to cancel the operation, but success is not + // guaranteed. If the server doesn't support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. Clients can use + // [Operations.GetOperation][google.longrunning.Operations.GetOperation] or + // other methods to check whether the cancellation succeeded or whether the + // operation completed despite cancellation. On successful cancellation, + // the operation is not deleted; instead, it becomes an operation with + // an [Operation.error][google.longrunning.Operation.error] value with a + // [google.rpc.Status.code][google.rpc.Status.code] of `1`, corresponding to + // `Code.CANCELLED`. + rpc CancelOperation(CancelOperationRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + post: "/v1/{name=operations/**}:cancel" + body: "*" + }; + option (google.api.method_signature) = "name"; + } + + // Waits until the specified long-running operation is done or reaches at most + // a specified timeout, returning the latest state. If the operation is + // already done, the latest state is immediately returned. If the timeout + // specified is greater than the default HTTP/RPC timeout, the HTTP/RPC + // timeout is used. If the server does not support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. + // Note that this method is on a best-effort basis. It may return the latest + // state before the specified timeout (including immediately), meaning even an + // immediate response is no guarantee that the operation is done. + rpc WaitOperation(WaitOperationRequest) returns (Operation) {} +} + +// This resource represents a long-running operation that is the result of a +// network API call. +message Operation { + // The server-assigned name, which is only unique within the same service that + // originally returns it. If you use the default HTTP mapping, the + // `name` should be a resource name ending with `operations/{unique_id}`. + string name = 1; + + // Service-specific metadata associated with the operation. It typically + // contains progress information and common metadata such as create time. + // Some services might not provide such metadata. Any method that returns a + // long-running operation should document the metadata type, if any. + google.protobuf.Any metadata = 2; + + // If the value is `false`, it means the operation is still in progress. + // If `true`, the operation is completed, and either `error` or `response` is + // available. + bool done = 3; + + // The operation result, which can be either an `error` or a valid `response`. + // If `done` == `false`, neither `error` nor `response` is set. + // If `done` == `true`, exactly one of `error` or `response` can be set. + // Some services might not provide the result. + oneof result { + // The error result of the operation in case of failure or cancellation. + google.rpc.Status error = 4; + + // The normal, successful response of the operation. If the original + // method returns no data on success, such as `Delete`, the response is + // `google.protobuf.Empty`. If the original method is standard + // `Get`/`Create`/`Update`, the response should be the resource. For other + // methods, the response should have the type `XxxResponse`, where `Xxx` + // is the original method name. For example, if the original method name + // is `TakeSnapshot()`, the inferred response type is + // `TakeSnapshotResponse`. + google.protobuf.Any response = 5; + } +} + +// The request message for +// [Operations.GetOperation][google.longrunning.Operations.GetOperation]. +message GetOperationRequest { + // The name of the operation resource. + string name = 1; +} + +// The request message for +// [Operations.ListOperations][google.longrunning.Operations.ListOperations]. +message ListOperationsRequest { + // The name of the operation's parent resource. + string name = 4; + + // The standard list filter. + string filter = 1; + + // The standard list page size. + int32 page_size = 2; + + // The standard list page token. + string page_token = 3; + + // When set to `true`, operations that are reachable are returned as normal, + // and those that are unreachable are returned in the + // [ListOperationsResponse.unreachable] field. + // + // This can only be `true` when reading across collections e.g. when `parent` + // is set to `"projects/example/locations/-"`. + // + // This field is not by default supported and will result in an + // `UNIMPLEMENTED` error if set unless explicitly documented otherwise in + // service or product specific documentation. + bool return_partial_success = 5; +} + +// The response message for +// [Operations.ListOperations][google.longrunning.Operations.ListOperations]. +message ListOperationsResponse { + // A list of operations that matches the specified filter in the request. + repeated Operation operations = 1; + + // The standard List next-page token. + string next_page_token = 2; + + // Unordered list. Unreachable resources. Populated when the request sets + // `ListOperationsRequest.return_partial_success` and reads across + // collections e.g. when attempting to list all resources across all supported + // locations. + repeated string unreachable = 3 + [(google.api.field_behavior) = UNORDERED_LIST]; +} + +// The request message for +// [Operations.CancelOperation][google.longrunning.Operations.CancelOperation]. +message CancelOperationRequest { + // The name of the operation resource to be cancelled. + string name = 1; +} + +// The request message for +// [Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation]. +message DeleteOperationRequest { + // The name of the operation resource to be deleted. + string name = 1; +} + +// The request message for +// [Operations.WaitOperation][google.longrunning.Operations.WaitOperation]. +message WaitOperationRequest { + // The name of the operation resource to wait on. + string name = 1; + + // The maximum duration to wait before timing out. If left blank, the wait + // will be at most the time permitted by the underlying HTTP/RPC protocol. + // If RPC context deadline is also specified, the shorter one will be used. + google.protobuf.Duration timeout = 2; +} + +// A message representing the message types used by a long-running operation. +// +// Example: +// +// rpc Export(ExportRequest) returns (google.longrunning.Operation) { +// option (google.longrunning.operation_info) = { +// response_type: "ExportResponse" +// metadata_type: "ExportMetadata" +// }; +// } +message OperationInfo { + // Required. The message name of the primary return type for this + // long-running operation. + // This type will be used to deserialize the LRO's response. + // + // If the response is in a different package from the rpc, a fully-qualified + // message name must be used (e.g. `google.protobuf.Struct`). + // + // Note: Altering this value constitutes a breaking change. + string response_type = 1; + + // Required. The message name of the metadata type for this long-running + // operation. + // + // If the response is in a different package from the rpc, a fully-qualified + // message name must be used (e.g. `google.protobuf.Struct`). + // + // Note: Altering this value constitutes a breaking change. + string metadata_type = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py new file mode 100644 index 00000000000..cd708839d89 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py @@ -0,0 +1,6 @@ +# This module is provided for backwards compatibility with +# googleapis-common-protos <= 1.5.0, where this was the import path. + +from __future__ import absolute_import + +from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import * # noqa: F401, F403 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py new file mode 100644 index 00000000000..f83b1977393 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/longrunning/operations.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/longrunning/operations.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 +from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 +from opentelemetry.agent._vendor.google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 + +from opentelemetry.agent._vendor.google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 +from opentelemetry.agent._vendor.google.api import client_pb2 as google_dot_api_dot_client__pb2 +from opentelemetry.agent._vendor.google.api import field_behavior_pb2 as google_dot_api_dot_field__behavior__pb2 +from opentelemetry.agent._vendor.google.rpc import status_pb2 as google_dot_rpc_dot_status__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n#google/longrunning/operations.proto\x12\x12google.longrunning\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/protobuf/any.proto\x1a google/protobuf/descriptor.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x17google/rpc/status.proto"\xa8\x01\n\tOperation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x08metadata\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\x12#\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x12.google.rpc.StatusH\x00\x12(\n\x08response\x18\x05 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x08\n\x06result"#\n\x13GetOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"|\n\x15ListOperationsRequest\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x01 \x01(\t\x12\x11\n\tpage_size\x18\x02 \x01(\x05\x12\x12\n\npage_token\x18\x03 \x01(\t\x12\x1e\n\x16return_partial_success\x18\x05 \x01(\x08"~\n\x16ListOperationsResponse\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.google.longrunning.Operation\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\x12\x18\n\x0bunreachable\x18\x03 \x03(\tB\x03\xe0\x41\x06"&\n\x16\x43\x61ncelOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"&\n\x16\x44\x65leteOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"P\n\x14WaitOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12*\n\x07timeout\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration"=\n\rOperationInfo\x12\x15\n\rresponse_type\x18\x01 \x01(\t\x12\x15\n\rmetadata_type\x18\x02 \x01(\t2\xaa\x05\n\nOperations\x12\x94\x01\n\x0eListOperations\x12).google.longrunning.ListOperationsRequest\x1a*.google.longrunning.ListOperationsResponse"+\xda\x41\x0bname,filter\x82\xd3\xe4\x93\x02\x17\x12\x15/v1/{name=operations}\x12\x7f\n\x0cGetOperation\x12\'.google.longrunning.GetOperationRequest\x1a\x1d.google.longrunning.Operation"\'\xda\x41\x04name\x82\xd3\xe4\x93\x02\x1a\x12\x18/v1/{name=operations/**}\x12~\n\x0f\x44\x65leteOperation\x12*.google.longrunning.DeleteOperationRequest\x1a\x16.google.protobuf.Empty"\'\xda\x41\x04name\x82\xd3\xe4\x93\x02\x1a*\x18/v1/{name=operations/**}\x12\x88\x01\n\x0f\x43\x61ncelOperation\x12*.google.longrunning.CancelOperationRequest\x1a\x16.google.protobuf.Empty"1\xda\x41\x04name\x82\xd3\xe4\x93\x02$"\x1f/v1/{name=operations/**}:cancel:\x01*\x12Z\n\rWaitOperation\x12(.google.longrunning.WaitOperationRequest\x1a\x1d.google.longrunning.Operation"\x00\x1a\x1d\xca\x41\x1alongrunning.googleapis.com:Z\n\x0eoperation_info\x12\x1e.google.protobuf.MethodOptions\x18\x99\x08 \x01(\x0b\x32!.google.longrunning.OperationInfoB\xa2\x01\n\x16\x63om.google.longrunningB\x0fOperationsProtoP\x01ZCcloud.google.com/go/longrunning/autogen/longrunningpb;longrunningpb\xa2\x02\x05GLRUN\xaa\x02\x12Google.LongRunning\xca\x02\x12Google\\LongRunningb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.longrunning.operations_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\026com.google.longrunningB\017OperationsProtoP\001ZCcloud.google.com/go/longrunning/autogen/longrunningpb;longrunningpb\242\002\005GLRUN\252\002\022Google.LongRunning\312\002\022Google\\LongRunning" + _globals["_LISTOPERATIONSRESPONSE"].fields_by_name[ + "unreachable" + ]._loaded_options = None + _globals["_LISTOPERATIONSRESPONSE"].fields_by_name[ + "unreachable" + ]._serialized_options = b"\340A\006" + _globals["_OPERATIONS"]._loaded_options = None + _globals["_OPERATIONS"]._serialized_options = b"\312A\032longrunning.googleapis.com" + _globals["_OPERATIONS"].methods_by_name["ListOperations"]._loaded_options = None + _globals["_OPERATIONS"].methods_by_name[ + "ListOperations" + ]._serialized_options = ( + b"\332A\013name,filter\202\323\344\223\002\027\022\025/v1/{name=operations}" + ) + _globals["_OPERATIONS"].methods_by_name["GetOperation"]._loaded_options = None + _globals["_OPERATIONS"].methods_by_name[ + "GetOperation" + ]._serialized_options = ( + b"\332A\004name\202\323\344\223\002\032\022\030/v1/{name=operations/**}" + ) + _globals["_OPERATIONS"].methods_by_name["DeleteOperation"]._loaded_options = None + _globals["_OPERATIONS"].methods_by_name[ + "DeleteOperation" + ]._serialized_options = ( + b"\332A\004name\202\323\344\223\002\032*\030/v1/{name=operations/**}" + ) + _globals["_OPERATIONS"].methods_by_name["CancelOperation"]._loaded_options = None + _globals["_OPERATIONS"].methods_by_name[ + "CancelOperation" + ]._serialized_options = ( + b'\332A\004name\202\323\344\223\002$"\037/v1/{name=operations/**}:cancel:\001*' + ) + _globals["_OPERATION"]._serialized_start = 295 + _globals["_OPERATION"]._serialized_end = 463 + _globals["_GETOPERATIONREQUEST"]._serialized_start = 465 + _globals["_GETOPERATIONREQUEST"]._serialized_end = 500 + _globals["_LISTOPERATIONSREQUEST"]._serialized_start = 502 + _globals["_LISTOPERATIONSREQUEST"]._serialized_end = 626 + _globals["_LISTOPERATIONSRESPONSE"]._serialized_start = 628 + _globals["_LISTOPERATIONSRESPONSE"]._serialized_end = 754 + _globals["_CANCELOPERATIONREQUEST"]._serialized_start = 756 + _globals["_CANCELOPERATIONREQUEST"]._serialized_end = 794 + _globals["_DELETEOPERATIONREQUEST"]._serialized_start = 796 + _globals["_DELETEOPERATIONREQUEST"]._serialized_end = 834 + _globals["_WAITOPERATIONREQUEST"]._serialized_start = 836 + _globals["_WAITOPERATIONREQUEST"]._serialized_end = 916 + _globals["_OPERATIONINFO"]._serialized_start = 918 + _globals["_OPERATIONINFO"]._serialized_end = 979 + _globals["_OPERATIONS"]._serialized_start = 982 + _globals["_OPERATIONS"]._serialized_end = 1664 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi new file mode 100644 index 00000000000..e56b84a361d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi @@ -0,0 +1,136 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pb2 as _descriptor_pb2 +from google.protobuf import duration_pb2 as _duration_pb2 +from google.protobuf import empty_pb2 as _empty_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +from google.api import annotations_pb2 as _annotations_pb2 +from google.api import client_pb2 as _client_pb2 +from google.api import field_behavior_pb2 as _field_behavior_pb2 +from google.rpc import status_pb2 as _status_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor +OPERATION_INFO_FIELD_NUMBER: _ClassVar[int] +operation_info: _descriptor.FieldDescriptor + +class Operation(_message.Message): + __slots__ = ("name", "metadata", "done", "error", "response") + NAME_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + DONE_FIELD_NUMBER: _ClassVar[int] + ERROR_FIELD_NUMBER: _ClassVar[int] + RESPONSE_FIELD_NUMBER: _ClassVar[int] + name: str + metadata: _any_pb2.Any + done: bool + error: _status_pb2.Status + response: _any_pb2.Any + def __init__( + self, + name: _Optional[str] = ..., + metadata: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., + done: _Optional[bool] = ..., + error: _Optional[_Union[_status_pb2.Status, _Mapping]] = ..., + response: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., + ) -> None: ... + +class GetOperationRequest(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + +class ListOperationsRequest(_message.Message): + __slots__ = ("name", "filter", "page_size", "page_token", "return_partial_success") + NAME_FIELD_NUMBER: _ClassVar[int] + FILTER_FIELD_NUMBER: _ClassVar[int] + PAGE_SIZE_FIELD_NUMBER: _ClassVar[int] + PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] + RETURN_PARTIAL_SUCCESS_FIELD_NUMBER: _ClassVar[int] + name: str + filter: str + page_size: int + page_token: str + return_partial_success: bool + def __init__( + self, + name: _Optional[str] = ..., + filter: _Optional[str] = ..., + page_size: _Optional[int] = ..., + page_token: _Optional[str] = ..., + return_partial_success: _Optional[bool] = ..., + ) -> None: ... + +class ListOperationsResponse(_message.Message): + __slots__ = ("operations", "next_page_token", "unreachable") + OPERATIONS_FIELD_NUMBER: _ClassVar[int] + NEXT_PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] + UNREACHABLE_FIELD_NUMBER: _ClassVar[int] + operations: _containers.RepeatedCompositeFieldContainer[Operation] + next_page_token: str + unreachable: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + operations: _Optional[_Iterable[_Union[Operation, _Mapping]]] = ..., + next_page_token: _Optional[str] = ..., + unreachable: _Optional[_Iterable[str]] = ..., + ) -> None: ... + +class CancelOperationRequest(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + +class DeleteOperationRequest(_message.Message): + __slots__ = ("name",) + NAME_FIELD_NUMBER: _ClassVar[int] + name: str + def __init__(self, name: _Optional[str] = ...) -> None: ... + +class WaitOperationRequest(_message.Message): + __slots__ = ("name", "timeout") + NAME_FIELD_NUMBER: _ClassVar[int] + TIMEOUT_FIELD_NUMBER: _ClassVar[int] + name: str + timeout: _duration_pb2.Duration + def __init__( + self, + name: _Optional[str] = ..., + timeout: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + ) -> None: ... + +class OperationInfo(_message.Message): + __slots__ = ("response_type", "metadata_type") + RESPONSE_TYPE_FIELD_NUMBER: _ClassVar[int] + METADATA_TYPE_FIELD_NUMBER: _ClassVar[int] + response_type: str + metadata_type: str + def __init__( + self, response_type: _Optional[str] = ..., metadata_type: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py new file mode 100644 index 00000000000..2273ed8da80 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py @@ -0,0 +1,10 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +# Copyright 2007 Google Inc. All Rights Reserved. + +__version__ = '7.36.2' diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py new file mode 100644 index 00000000000..19c09e2079f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py @@ -0,0 +1,52 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +"""Contains the Any helper APIs.""" + +from typing import Optional, TypeVar + +from opentelemetry.agent._vendor.google.protobuf import descriptor +from opentelemetry.agent._vendor.google.protobuf.message import Message + +from opentelemetry.agent._vendor.google.protobuf.any_pb2 import Any + +_MessageT = TypeVar('_MessageT', bound=Message) + + +def pack( + msg: Message, + type_url_prefix: Optional[str] = 'type.googleapis.com/', + deterministic: Optional[bool] = None, +) -> Any: + any_msg = Any() + any_msg.Pack( + msg=msg, type_url_prefix=type_url_prefix, deterministic=deterministic + ) + return any_msg + + +def unpack(any_msg: Any, msg: Message) -> bool: + return any_msg.Unpack(msg=msg) + + +def unpack_as(any_msg: Any, message_type: type[_MessageT]) -> _MessageT: + unpacked = message_type() + if unpack(any_msg, unpacked): + return unpacked + else: + raise TypeError( + f'Attempted to unpack {type_name(any_msg)} to' + f' {message_type.__qualname__}' + ) + + +def type_name(any_msg: Any) -> str: + return any_msg.TypeName() + + +def is_type(any_msg: Any, des: descriptor.Descriptor) -> bool: + return any_msg.Is(des) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py new file mode 100644 index 00000000000..1b31d6dc7b7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/any.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/any.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/any.proto\x12\x0fgoogle.protobuf\"6\n\x03\x41ny\x12\x19\n\x08type_url\x18\x01 \x01(\tR\x07typeUrl\x12\x14\n\x05value\x18\x02 \x01(\x0cR\x05valueBv\n\x13\x63om.google.protobufB\x08\x41nyProtoP\x01Z,google.golang.org/protobuf/types/known/anypb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.any_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\010AnyProtoP\001Z,google.golang.org/protobuf/types/known/anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_ANY']._serialized_start=46 + _globals['_ANY']._serialized_end=100 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py new file mode 100644 index 00000000000..492256f31d1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/api.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/api.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 +from opentelemetry.agent._vendor.google.protobuf import type_pb2 as google_dot_protobuf_dot_type__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/api.proto\x12\x0fgoogle.protobuf\x1a$google/protobuf/source_context.proto\x1a\x1agoogle/protobuf/type.proto\"\xdb\x02\n\x03\x41pi\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x31\n\x07methods\x18\x02 \x03(\x0b\x32\x17.google.protobuf.MethodR\x07methods\x12\x31\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x18\n\x07version\x18\x04 \x01(\tR\x07version\x12\x45\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContextR\rsourceContext\x12.\n\x06mixins\x18\x06 \x03(\x0b\x32\x16.google.protobuf.MixinR\x06mixins\x12/\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.SyntaxR\x06syntax\x12\x18\n\x07\x65\x64ition\x18\x08 \x01(\tR\x07\x65\x64ition\"\xd4\x02\n\x06Method\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12(\n\x10request_type_url\x18\x02 \x01(\tR\x0erequestTypeUrl\x12+\n\x11request_streaming\x18\x03 \x01(\x08R\x10requestStreaming\x12*\n\x11response_type_url\x18\x04 \x01(\tR\x0fresponseTypeUrl\x12-\n\x12response_streaming\x18\x05 \x01(\x08R\x11responseStreaming\x12\x31\n\x07options\x18\x06 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x33\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.SyntaxB\x02\x18\x01R\x06syntax\x12\x1c\n\x07\x65\x64ition\x18\x08 \x01(\tB\x02\x18\x01R\x07\x65\x64ition\"/\n\x05Mixin\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n\x04root\x18\x02 \x01(\tR\x04rootBv\n\x13\x63om.google.protobufB\x08\x41piProtoP\x01Z,google.golang.org/protobuf/types/known/apipb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.api_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\010ApiProtoP\001Z,google.golang.org/protobuf/types/known/apipb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_METHOD'].fields_by_name['syntax']._loaded_options = None + _globals['_METHOD'].fields_by_name['syntax']._serialized_options = b'\030\001' + _globals['_METHOD'].fields_by_name['edition']._loaded_options = None + _globals['_METHOD'].fields_by_name['edition']._serialized_options = b'\030\001' + _globals['_API']._serialized_start=113 + _globals['_API']._serialized_end=460 + _globals['_METHOD']._serialized_start=463 + _globals['_METHOD']._serialized_end=803 + _globals['_MIXIN']._serialized_start=805 + _globals['_MIXIN']._serialized_end=852 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py new file mode 100644 index 00000000000..436de6d1293 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py @@ -0,0 +1,1669 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Descriptors essentially contain exactly the information found in a .proto + +file, in types that make this information accessible in Python. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import abc +import binascii +import os +import threading +import warnings + +from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation + +_USE_C_DESCRIPTORS = False +if api_implementation.Type() != 'python': + # pylint: disable=protected-access + _message = api_implementation._c_module + # TODO: Remove this import after fix api_implementation + if _message is None: + from opentelemetry.agent._vendor.google.protobuf.pyext import _message + _USE_C_DESCRIPTORS = True + + +class Error(Exception): + """Base error for this module.""" + + +class TypeTransformationError(Error): + """Error transforming between python proto type and corresponding C++ type.""" + + +if _USE_C_DESCRIPTORS: + # This metaclass allows to override the behavior of code like + # isinstance(my_descriptor, FieldDescriptor) + # and make it return True when the descriptor is an instance of the extension + # type written in C++. + class DescriptorMetaclass(type): + + def __instancecheck__(cls, obj): + if super(DescriptorMetaclass, cls).__instancecheck__(obj): + return True + if isinstance(obj, cls._C_DESCRIPTOR_CLASS): + return True + return False + +else: + # The standard metaclass; nothing changes. + DescriptorMetaclass = abc.ABCMeta + + +class _Lock(object): + """Wrapper class of threading.Lock(), which is allowed by 'with'.""" + + def __new__(cls): + self = object.__new__(cls) + self._lock = threading.Lock() # pylint: disable=protected-access + return self + + def __enter__(self): + self._lock.acquire() + + def __exit__(self, exc_type, exc_value, exc_tb): + self._lock.release() + + +_lock = threading.Lock() + + +def _Deprecated( + name, + alternative='get/find descriptors from generated code or query the descriptor_pool', +): + if _Deprecated.count > 0: + _Deprecated.count -= 1 + warnings.warn( + 'Call to deprecated %s, use %s instead.' % (name, alternative), + category=DeprecationWarning, + stacklevel=3, + ) + + +# These must match the values in descriptor.proto, but we can't use them +# directly because we sometimes need to reference them in feature helpers +# below *during* the build of descriptor.proto. +_FEATURESET_MESSAGE_ENCODING_DELIMITED = 2 +_FEATURESET_FIELD_PRESENCE_IMPLICIT = 2 +_FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED = 3 +_FEATURESET_REPEATED_FIELD_ENCODING_PACKED = 1 +_FEATURESET_ENUM_TYPE_CLOSED = 2 + +# Deprecated warnings will print 100 times at most which should be enough for +# users to notice and do not cause timeout. +_Deprecated.count = 100 + +_internal_create_key = object() + + +class DescriptorBase(metaclass=DescriptorMetaclass): + """Descriptors base class. + + This class is the base of all descriptor classes. It provides common options + related functionality. + + Attributes: + has_options: True if the descriptor has non-default options. Usually it is + not necessary to read this -- just call GetOptions() which will happily + return the default instance. However, it's sometimes useful for + efficiency, and also useful inside the protobuf implementation to avoid + some bootstrapping issues. + file (FileDescriptor): Reference to file info. + """ + + if _USE_C_DESCRIPTORS: + # The class, or tuple of classes, that are considered as "virtual + # subclasses" of this descriptor class. + _C_DESCRIPTOR_CLASS = () + + def __init__(self, file, options, serialized_options, options_class_name): + """Initialize the descriptor given its options message and the name of the + + class of the options message. The name of the class is required in case + the options message is None and has to be created. + """ + self._features = None + self.file = file + self._original_options = options + # These two fields are duplicated as a compatibility shim for old gencode + # that resets them. In 26.x (cl/580304039) we renamed _options to, + # _loaded_options breaking backwards compatibility. + self._options = self._loaded_options = None + self._options_class_name = options_class_name + self._serialized_options = serialized_options + + # Does this descriptor have non-default options? + self.has_options = (self._original_options is not None) or ( + self._serialized_options is not None + ) + + @property + @abc.abstractmethod + def _parent(self): + pass + + def _InferLegacyFeatures(self, edition, options, features): + """Infers features from proto2/proto3 syntax so that editions logic can be used everywhere. + + Args: + edition: The edition to infer features for. + options: The options for this descriptor that are being processed. + features: The feature set object to modify with inferred features. + """ + pass + + def _GetFeatures(self): + if not self._features: + self._LazyLoadOptions() + return self._features + + def _ResolveFeatures(self, edition, raw_options): + """Resolves features from the raw options of this descriptor. + + Args: + edition: The edition to use for feature defaults. + raw_options: The options for this descriptor that are being processed. + + Returns: + A fully resolved feature set for making runtime decisions. + """ + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + if self._parent: + features = descriptor_pb2.FeatureSet() + features.CopyFrom(self._parent._GetFeatures()) + else: + features = self.file.pool._CreateDefaultFeatures(edition) + unresolved = descriptor_pb2.FeatureSet() + unresolved.CopyFrom(raw_options.features) + self._InferLegacyFeatures(edition, raw_options, unresolved) + features.MergeFrom(unresolved) + + # Use the feature cache to reduce memory bloat. + return self.file.pool._InternFeatures(features) + + def _LazyLoadOptions(self): + """Lazily initializes descriptor options towards the end of the build.""" + if self._options and self._loaded_options == self._options: + # If neither has been reset by gencode, use the cache. + return + + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + if not hasattr(descriptor_pb2, self._options_class_name): + raise RuntimeError( + 'Unknown options class name %s!' % self._options_class_name + ) + options_class = getattr(descriptor_pb2, self._options_class_name) + features = None + edition = self.file._edition + + if not self.has_options: + if not self._features: + features = self._ResolveFeatures( + descriptor_pb2.Edition.Value(edition), options_class() + ) + with _lock: + self._options = self._loaded_options = options_class() + if not self._features: + self._features = features + else: + if not self._serialized_options: + options = self._original_options + else: + options = _ParseOptions(options_class(), self._serialized_options) + + if not self._features: + features = self._ResolveFeatures( + descriptor_pb2.Edition.Value(edition), options + ) + with _lock: + self._options = self._loaded_options = options + if not self._features: + self._features = features + if options.HasField('features'): + options.ClearField('features') + if not options.SerializeToString(): + self._options = self._loaded_options = options_class() + self.has_options = False + + def GetOptions(self): + """Retrieves descriptor options. + + Returns: + The options set on this descriptor. + """ + # If either has been reset by gencode, reload options. + if not self._options or not self._loaded_options: + self._LazyLoadOptions() + if ( + self._options + and hasattr(self._options, '_SetFrozen') + and not getattr(self._options, '_frozen', False) + ): + self._options._SetFrozen() + return self._options + + +class _NestedDescriptorBase(DescriptorBase): + """Common class for descriptors that can be nested.""" + + def __init__( + self, + options, + options_class_name, + name, + full_name, + file, + containing_type, + serialized_start=None, + serialized_end=None, + serialized_options=None, + ): + """Constructor. + + Args: + options: Protocol message options or None to use default message options. + options_class_name (str): The class name of the above options. + name (str): Name of this protocol message type. + full_name (str): Fully-qualified name of this protocol message type, which + will include protocol "package" name and the name of any enclosing + types. + containing_type: if provided, this is a nested descriptor, with this + descriptor as parent, otherwise None. + serialized_start: The start index (inclusive) in block in the + file.serialized_pb that describes this descriptor. + serialized_end: The end index (exclusive) in block in the + file.serialized_pb that describes this descriptor. + serialized_options: Protocol message serialized options or None. + """ + super(_NestedDescriptorBase, self).__init__( + file, options, serialized_options, options_class_name + ) + + self.name = name + # TODO: Add function to calculate full_name instead of having it in + # memory? + self.full_name = full_name + self.containing_type = containing_type + + self._serialized_start = serialized_start + self._serialized_end = serialized_end + + def CopyToProto(self, proto): + """Copies this to the matching proto in descriptor_pb2. + + Args: + proto: An empty proto instance from descriptor_pb2. + + Raises: + Error: If self couldn't be serialized, due to to few constructor + arguments. + """ + if ( + self.file is not None + and self._serialized_start is not None + and self._serialized_end is not None + ): + proto.ParseFromString( + self.file.serialized_pb[self._serialized_start : self._serialized_end] + ) + else: + raise Error('Descriptor does not contain serialization.') + + +class Descriptor(_NestedDescriptorBase): + """Descriptor for a protocol message type. + + Attributes: + name (str): Name of this protocol message type. + full_name (str): Fully-qualified name of this protocol message type, which + will include protocol "package" name and the name of any enclosing + types. + containing_type (Descriptor): Reference to the descriptor of the type + containing us, or None if this is top-level. + fields (list[FieldDescriptor]): Field descriptors for all fields in this + type. + fields_by_number (dict(int, FieldDescriptor)): Same + :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by + "number" attribute in each FieldDescriptor. + fields_by_name (dict(str, FieldDescriptor)): Same :class:`FieldDescriptor` + objects as in :attr:`fields`, but indexed by "name" attribute in each + :class:`FieldDescriptor`. + nested_types (list[Descriptor]): Descriptor references for all protocol + message types nested within this one. + nested_types_by_name (dict(str, Descriptor)): Same Descriptor objects as + in :attr:`nested_types`, but indexed by "name" attribute in each + Descriptor. + enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references for + all enums contained within this type. + enum_types_by_name (dict(str, EnumDescriptor)): Same + :class:`EnumDescriptor` objects as in :attr:`enum_types`, but indexed by + "name" attribute in each EnumDescriptor. + enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping from + enum value name to :class:`EnumValueDescriptor` for that value. + extensions (list[FieldDescriptor]): All extensions defined directly within + this message type (NOT within a nested type). + extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor + objects as :attr:`extensions`, but indexed by "name" attribute of each + FieldDescriptor. + is_extendable (bool): Does this type define any extension ranges? + oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields + in this message. + oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in + :attr:`oneofs`, but indexed by "name" attribute. + file (FileDescriptor): Reference to file descriptor. + is_map_entry: If the message type is a map entry. + """ + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.Descriptor + + def __new__( + cls, + name=None, + full_name=None, + filename=None, + containing_type=None, + fields=None, + nested_types=None, + enum_types=None, + extensions=None, + options=None, + serialized_options=None, + is_extendable=True, + extension_ranges=None, + oneofs=None, + file=None, # pylint: disable=redefined-builtin + serialized_start=None, + serialized_end=None, + syntax=None, + is_map_entry=False, + create_key=None, + ): + _message.Message._CheckCalledFromGeneratedFile() + return _message.default_pool.FindMessageTypeByName(full_name) + + # NOTE: The file argument redefining a builtin is nothing we can + # fix right now since we don't know how many clients already rely on the + # name of the argument. + def __init__( + self, + name, + full_name, + filename, + containing_type, + fields, + nested_types, + enum_types, + extensions, + options=None, + serialized_options=None, + is_extendable=True, + extension_ranges=None, + oneofs=None, + file=None, + serialized_start=None, + serialized_end=None, # pylint: disable=redefined-builtin + syntax=None, + is_map_entry=False, + create_key=None, + ): + """Arguments to __init__() are as described in the description + + of Descriptor fields above. + + Note that filename is an obsolete argument, that is not used anymore. + Please use file.name to access this as an attribute. + """ + if create_key is not _internal_create_key: + _Deprecated('create function Descriptor()') + + super(Descriptor, self).__init__( + options, + 'MessageOptions', + name, + full_name, + file, + containing_type, + serialized_start=serialized_start, + serialized_end=serialized_end, + serialized_options=serialized_options, + ) + + # We have fields in addition to fields_by_name and fields_by_number, + # so that: + # 1. Clients can index fields by "order in which they're listed." + # 2. Clients can easily iterate over all fields with the terse + # syntax: for f in descriptor.fields: ... + self.fields = fields + for field in self.fields: + field.containing_type = self + field.file = file + self.fields_by_number = dict((f.number, f) for f in fields) + self.fields_by_name = dict((f.name, f) for f in fields) + self._fields_by_camelcase_name = None + + self.nested_types = nested_types + for nested_type in nested_types: + nested_type.containing_type = self + self.nested_types_by_name = dict((t.name, t) for t in nested_types) + + self.enum_types = enum_types + for enum_type in self.enum_types: + enum_type.containing_type = self + self.enum_types_by_name = dict((t.name, t) for t in enum_types) + self.enum_values_by_name = dict( + (v.name, v) for t in enum_types for v in t.values + ) + + self.extensions = extensions + for extension in self.extensions: + extension.extension_scope = self + self.extensions_by_name = dict((f.name, f) for f in extensions) + self.is_extendable = is_extendable + self.extension_ranges = extension_ranges + self.oneofs = oneofs if oneofs is not None else [] + self.oneofs_by_name = dict((o.name, o) for o in self.oneofs) + for oneof in self.oneofs: + oneof.containing_type = self + oneof.file = file + self._is_map_entry = is_map_entry + + @property + def _parent(self): + return self.containing_type or self.file + + @property + def fields_by_camelcase_name(self): + """Same FieldDescriptor objects as in :attr:`fields`, but indexed by + + :attr:`FieldDescriptor.camelcase_name`. + """ + if self._fields_by_camelcase_name is None: + self._fields_by_camelcase_name = dict( + (f.camelcase_name, f) for f in self.fields + ) + return self._fields_by_camelcase_name + + def EnumValueName(self, enum, value): + """Returns the string name of an enum value. + + This is just a small helper method to simplify a common operation. + + Args: + enum: string name of the Enum. + value: int, value of the enum. + + Returns: + string name of the enum value. + + Raises: + KeyError if either the Enum doesn't exist or the value is not a valid + value for the enum. + """ + return self.enum_types_by_name[enum].values_by_number[value].name + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.DescriptorProto. + + Args: + proto: An empty descriptor_pb2.DescriptorProto. + """ + # This function is overridden to give a better doc comment. + super(Descriptor, self).CopyToProto(proto) + + +# TODO: We should have aggressive checking here, +# for example: +# * If you specify a repeated field, you should not be allowed +# to specify a default value. +# * [Other examples here as needed]. +# +# TODO: for this and other *Descriptor classes, we +# might also want to lock things down aggressively (e.g., +# prevent clients from setting the attributes). Having +# stronger invariants here in general will reduce the number +# of runtime checks we must do in reflection.py... +class FieldDescriptor(DescriptorBase): + """Descriptor for a single field in a .proto file. + + Attributes: + name (str): Name of this field, exactly as it appears in .proto. + full_name (str): Name of this field, including containing scope. This is + particularly relevant for extensions. + index (int): Dense, 0-indexed index giving the order that this field + textually appears within its message in the .proto file. + number (int): Tag number declared for this field in the .proto file. + type (int): (One of the TYPE_* constants below) Declared type. + cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to + represent this field. + label (int): (One of the LABEL_* constants below) Tells whether this field + is optional, required, or repeated. + has_default_value (bool): True if this field has a default value defined, + otherwise false. + default_value (Varies): Default value of this field. Only meaningful for + non-repeated scalar fields. Repeated fields should always set this to [], + and non-repeated composite fields should always set this to None. + containing_type (Descriptor): Descriptor of the protocol message type that + contains this field. Set by the Descriptor constructor if we're passed + into one. Somewhat confusingly, for extension fields, this is the + descriptor of the EXTENDED message, not the descriptor of the message + containing this field. (See is_extension and extension_scope below). + message_type (Descriptor): If a composite field, a descriptor of the message + type contained in this field. Otherwise, this is None. + enum_type (EnumDescriptor): If this field contains an enum, a descriptor of + that enum. Otherwise, this is None. + is_extension: True iff this describes an extension field. + extension_scope (Descriptor): Only meaningful if is_extension is True. Gives + the message that immediately contains this extension field. Will be None + iff we're a top-level (file-level) extension field. + options (descriptor_pb2.FieldOptions): Protocol message field options or + None to use default field options. + containing_oneof (OneofDescriptor): If the field is a member of a oneof + union, contains its descriptor. Otherwise, None. + file (FileDescriptor): Reference to file descriptor. + """ + + # Must be consistent with C++ FieldDescriptor::Type enum in + # descriptor.h. + # + # TODO: Find a way to eliminate this repetition. + TYPE_DOUBLE = 1 + TYPE_FLOAT = 2 + TYPE_INT64 = 3 + TYPE_UINT64 = 4 + TYPE_INT32 = 5 + TYPE_FIXED64 = 6 + TYPE_FIXED32 = 7 + TYPE_BOOL = 8 + TYPE_STRING = 9 + TYPE_GROUP = 10 + TYPE_MESSAGE = 11 + TYPE_BYTES = 12 + TYPE_UINT32 = 13 + TYPE_ENUM = 14 + TYPE_SFIXED32 = 15 + TYPE_SFIXED64 = 16 + TYPE_SINT32 = 17 + TYPE_SINT64 = 18 + MAX_TYPE = 18 + + # Must be consistent with C++ FieldDescriptor::CppType enum in + # descriptor.h. + # + # TODO: Find a way to eliminate this repetition. + CPPTYPE_INT32 = 1 + CPPTYPE_INT64 = 2 + CPPTYPE_UINT32 = 3 + CPPTYPE_UINT64 = 4 + CPPTYPE_DOUBLE = 5 + CPPTYPE_FLOAT = 6 + CPPTYPE_BOOL = 7 + CPPTYPE_ENUM = 8 + CPPTYPE_STRING = 9 + CPPTYPE_MESSAGE = 10 + MAX_CPPTYPE = 10 + + _PYTHON_TO_CPP_PROTO_TYPE_MAP = { + TYPE_DOUBLE: CPPTYPE_DOUBLE, + TYPE_FLOAT: CPPTYPE_FLOAT, + TYPE_ENUM: CPPTYPE_ENUM, + TYPE_INT64: CPPTYPE_INT64, + TYPE_SINT64: CPPTYPE_INT64, + TYPE_SFIXED64: CPPTYPE_INT64, + TYPE_UINT64: CPPTYPE_UINT64, + TYPE_FIXED64: CPPTYPE_UINT64, + TYPE_INT32: CPPTYPE_INT32, + TYPE_SFIXED32: CPPTYPE_INT32, + TYPE_SINT32: CPPTYPE_INT32, + TYPE_UINT32: CPPTYPE_UINT32, + TYPE_FIXED32: CPPTYPE_UINT32, + TYPE_BYTES: CPPTYPE_STRING, + TYPE_STRING: CPPTYPE_STRING, + TYPE_BOOL: CPPTYPE_BOOL, + TYPE_MESSAGE: CPPTYPE_MESSAGE, + TYPE_GROUP: CPPTYPE_MESSAGE, + } + + # Must be consistent with C++ FieldDescriptor::Label enum in + # descriptor.h. + # + # TODO: Find a way to eliminate this repetition. + LABEL_OPTIONAL = 1 + LABEL_REQUIRED = 2 + LABEL_REPEATED = 3 + MAX_LABEL = 3 + + # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber, + # and kLastReservedNumber in descriptor.h + MAX_FIELD_NUMBER = (1 << 29) - 1 + FIRST_RESERVED_FIELD_NUMBER = 19000 + LAST_RESERVED_FIELD_NUMBER = 19999 + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.FieldDescriptor + + def __new__( + cls, + name, + full_name, + index, + number, + type, + cpp_type, + label, + default_value, + message_type, + enum_type, + containing_type, + is_extension, + extension_scope, + options=None, + serialized_options=None, + has_default_value=True, + containing_oneof=None, + json_name=None, + file=None, + create_key=None, + ): # pylint: disable=redefined-builtin + _message.Message._CheckCalledFromGeneratedFile() + if is_extension: + return _message.default_pool.FindExtensionByName(full_name) + else: + return _message.default_pool.FindFieldByName(full_name) + + def __init__( + self, + name, + full_name, + index, + number, + type, + cpp_type, + label, + default_value, + message_type, + enum_type, + containing_type, + is_extension, + extension_scope, + options=None, + serialized_options=None, + has_default_value=True, + containing_oneof=None, + json_name=None, + file=None, + create_key=None, + ): # pylint: disable=redefined-builtin + """The arguments are as described in the description of FieldDescriptor + + attributes above. + + Note that containing_type may be None, and may be set later if necessary + (to deal with circular references between message types, for example). + Likewise for extension_scope. + """ + if create_key is not _internal_create_key: + _Deprecated('create function FieldDescriptor()') + + super(FieldDescriptor, self).__init__( + file, options, serialized_options, 'FieldOptions' + ) + self.name = name + self.full_name = full_name + self._camelcase_name = None + if json_name is None: + self.json_name = _ToJsonName(name) + else: + self.json_name = json_name + self.index = index + self.number = number + self._type = type + self.cpp_type = cpp_type + self._label = label + self.has_default_value = has_default_value + self.default_value = default_value + self.containing_type = containing_type + self.message_type = message_type + self.enum_type = enum_type + self.is_extension = is_extension + self.extension_scope = extension_scope + self.containing_oneof = containing_oneof + if api_implementation.Type() == 'python': + self._cdescriptor = None + else: + if is_extension: + self._cdescriptor = _message.default_pool.FindExtensionByName(full_name) + else: + self._cdescriptor = _message.default_pool.FindFieldByName(full_name) + + @property + def _parent(self): + if self.containing_oneof: + return self.containing_oneof + if self.is_extension: + return self.extension_scope or self.file + return self.containing_type + + def _InferLegacyFeatures(self, edition, options, features): + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + if edition >= descriptor_pb2.Edition.EDITION_2023: + return + + if self._label == FieldDescriptor.LABEL_REQUIRED: + features.field_presence = ( + descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED + ) + + if self._type == FieldDescriptor.TYPE_GROUP: + features.message_encoding = ( + descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED + ) + + if options.HasField('packed'): + features.repeated_field_encoding = ( + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED + if options.packed + else descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED + ) + + @property + def type(self): + if ( + self._GetFeatures().message_encoding + == _FEATURESET_MESSAGE_ENCODING_DELIMITED + and self.message_type + and not self.message_type.GetOptions().map_entry + and not self.containing_type.GetOptions().map_entry + ): + return FieldDescriptor.TYPE_GROUP + return self._type + + @type.setter + def type(self, val): + self._type = val + + @property + def is_required(self): + """Returns if the field is required.""" + return ( + self._GetFeatures().field_presence + == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED + ) + + @property + def is_repeated(self): + """Returns if the field is repeated.""" + return self._label == FieldDescriptor.LABEL_REPEATED + + @property + def camelcase_name(self): + """Camelcase name of this field. + + Returns: + str: the name in CamelCase. + """ + if self._camelcase_name is None: + self._camelcase_name = _ToCamelCase(self.name) + return self._camelcase_name + + @property + def has_presence(self): + """Whether the field distinguishes between unpopulated and default values. + + Raises: + RuntimeError: singular field that is not linked with message nor file. + """ + if self.is_repeated: + return False + if ( + self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE + or self.is_extension + or self.containing_oneof + ): + return True + + return ( + self._GetFeatures().field_presence + != _FEATURESET_FIELD_PRESENCE_IMPLICIT + ) + + @property + def is_packed(self): + """Returns if the field is packed.""" + if not self.is_repeated: + return False + field_type = self.type + if ( + field_type == FieldDescriptor.TYPE_STRING + or field_type == FieldDescriptor.TYPE_GROUP + or field_type == FieldDescriptor.TYPE_MESSAGE + or field_type == FieldDescriptor.TYPE_BYTES + ): + return False + + return ( + self._GetFeatures().repeated_field_encoding + == _FEATURESET_REPEATED_FIELD_ENCODING_PACKED + ) + + @staticmethod + def ProtoTypeToCppProtoType(proto_type): + """Converts from a Python proto type to a C++ Proto Type. + + The Python ProtocolBuffer classes specify both the 'Python' datatype and the + 'C++' datatype - and they're not the same. This helper method should + translate from one to another. + + Args: + proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) + + Returns: + int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. + Raises: + TypeTransformationError: when the Python proto type isn't known. + """ + try: + return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] + except KeyError: + raise TypeTransformationError('Unknown proto_type: %s' % proto_type) + + +class EnumDescriptor(_NestedDescriptorBase): + """Descriptor for an enum defined in a .proto file. + + Attributes: + name (str): Name of the enum type. + full_name (str): Full name of the type, including package name and any + enclosing type(s). + values (list[EnumValueDescriptor]): List of the values in this enum. + values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, but + indexed by the "name" field of each EnumValueDescriptor. + values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`, + but indexed by the "number" field of each EnumValueDescriptor. + containing_type (Descriptor): Descriptor of the immediate containing type of + this enum, or None if this is an enum defined at the top level in a .proto + file. Set by Descriptor's constructor if we're passed into one. + file (FileDescriptor): Reference to file descriptor. + options (descriptor_pb2.EnumOptions): Enum options message or None to use + default enum options. + """ + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.EnumDescriptor + + def __new__( + cls, + name, + full_name, + filename, + values, + containing_type=None, + options=None, + serialized_options=None, + file=None, # pylint: disable=redefined-builtin + serialized_start=None, + serialized_end=None, + create_key=None, + ): + _message.Message._CheckCalledFromGeneratedFile() + return _message.default_pool.FindEnumTypeByName(full_name) + + def __init__( + self, + name, + full_name, + filename, + values, + containing_type=None, + options=None, + serialized_options=None, + file=None, # pylint: disable=redefined-builtin + serialized_start=None, + serialized_end=None, + create_key=None, + ): + """Arguments are as described in the attribute description above. + + Note that filename is an obsolete argument, that is not used anymore. + Please use file.name to access this as an attribute. + """ + if create_key is not _internal_create_key: + _Deprecated('create function EnumDescriptor()') + + super(EnumDescriptor, self).__init__( + options, + 'EnumOptions', + name, + full_name, + file, + containing_type, + serialized_start=serialized_start, + serialized_end=serialized_end, + serialized_options=serialized_options, + ) + + self.values = values + for value in self.values: + value.file = file + value.type = self + self.values_by_name = dict((v.name, v) for v in values) + # Values are reversed to ensure that the first alias is retained. + self.values_by_number = dict((v.number, v) for v in reversed(values)) + + @property + def _parent(self): + return self.containing_type or self.file + + @property + def is_closed(self): + """Returns true whether this is a "closed" enum. + + This means that it: + - Has a fixed set of values, rather than being equivalent to an int32. + - Encountering values not in this set causes them to be treated as unknown + fields. + - The first value (i.e., the default) may be nonzero. + + WARNING: Some runtimes currently have a quirk where non-closed enums are + treated as closed when used as the type of fields defined in a + `syntax = proto2;` file. This quirk is not present in all runtimes; as of + writing, we know that: + + - C++, Java, and C++-based Python share this quirk. + - UPB and UPB-based Python do not. + - PHP and Ruby treat all enums as open regardless of declaration. + + Care should be taken when using this function to respect the target + runtime's enum handling quirks. + """ + return self._GetFeatures().enum_type == _FEATURESET_ENUM_TYPE_CLOSED + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.EnumDescriptorProto. + + Args: + proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. + """ + # This function is overridden to give a better doc comment. + super(EnumDescriptor, self).CopyToProto(proto) + + +class EnumValueDescriptor(DescriptorBase): + """Descriptor for a single value within an enum. + + Attributes: + name (str): Name of this value. + index (int): Dense, 0-indexed index giving the order that this value appears + textually within its enum in the .proto file. + number (int): Actual number assigned to this enum value. + type (EnumDescriptor): :class:`EnumDescriptor` to which this value belongs. + Set by :class:`EnumDescriptor`'s constructor if we're passed into one. + options (descriptor_pb2.EnumValueOptions): Enum value options message or + None to use default enum value options options. + """ + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor + + def __new__( + cls, + name, + index, + number, + type=None, # pylint: disable=redefined-builtin + options=None, + serialized_options=None, + create_key=None, + ): + _message.Message._CheckCalledFromGeneratedFile() + # There is no way we can build a complete EnumValueDescriptor with the + # given parameters (the name of the Enum is not known, for example). + # Fortunately generated files just pass it to the EnumDescriptor() + # constructor, which will ignore it, so returning None is good enough. + return None + + def __init__( + self, + name, + index, + number, + type=None, # pylint: disable=redefined-builtin + options=None, + serialized_options=None, + create_key=None, + ): + """Arguments are as described in the attribute description above.""" + if create_key is not _internal_create_key: + _Deprecated('create function EnumValueDescriptor()') + + super(EnumValueDescriptor, self).__init__( + type.file if type else None, + options, + serialized_options, + 'EnumValueOptions', + ) + self.name = name + self.index = index + self.number = number + self.type = type + + @property + def _parent(self): + return self.type + + +class OneofDescriptor(DescriptorBase): + """Descriptor for a oneof field. + + Attributes: + name (str): Name of the oneof field. + full_name (str): Full name of the oneof field, including package name. + index (int): 0-based index giving the order of the oneof field inside its + containing type. + containing_type (Descriptor): :class:`Descriptor` of the protocol message + type that contains this field. Set by the :class:`Descriptor` constructor + if we're passed into one. + fields (list[FieldDescriptor]): The list of field descriptors this oneof can + contain. + """ + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.OneofDescriptor + + def __new__( + cls, + name, + full_name, + index, + containing_type, + fields, + options=None, + serialized_options=None, + create_key=None, + ): + _message.Message._CheckCalledFromGeneratedFile() + return _message.default_pool.FindOneofByName(full_name) + + def __init__( + self, + name, + full_name, + index, + containing_type, + fields, + options=None, + serialized_options=None, + create_key=None, + ): + """Arguments are as described in the attribute description above.""" + if create_key is not _internal_create_key: + _Deprecated('create function OneofDescriptor()') + + super(OneofDescriptor, self).__init__( + containing_type.file if containing_type else None, + options, + serialized_options, + 'OneofOptions', + ) + self.name = name + self.full_name = full_name + self.index = index + self.containing_type = containing_type + self.fields = fields + + @property + def _parent(self): + return self.containing_type + + +class ServiceDescriptor(_NestedDescriptorBase): + """Descriptor for a service. + + Attributes: + name (str): Name of the service. + full_name (str): Full name of the service, including package name. + index (int): 0-indexed index giving the order that this services definition + appears within the .proto file. + methods (list[MethodDescriptor]): List of methods provided by this service. + methods_by_name (dict(str, MethodDescriptor)): Same + :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but + indexed by "name" attribute in each :class:`MethodDescriptor`. + options (descriptor_pb2.ServiceOptions): Service options message or None to + use default service options. + file (FileDescriptor): Reference to file info. + """ + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor + + def __new__( + cls, + name=None, + full_name=None, + index=None, + methods=None, + options=None, + serialized_options=None, + file=None, # pylint: disable=redefined-builtin + serialized_start=None, + serialized_end=None, + create_key=None, + ): + _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access + return _message.default_pool.FindServiceByName(full_name) + + def __init__( + self, + name, + full_name, + index, + methods, + options=None, + serialized_options=None, + file=None, # pylint: disable=redefined-builtin + serialized_start=None, + serialized_end=None, + create_key=None, + ): + if create_key is not _internal_create_key: + _Deprecated('create function ServiceDescriptor()') + + super(ServiceDescriptor, self).__init__( + options, + 'ServiceOptions', + name, + full_name, + file, + None, + serialized_start=serialized_start, + serialized_end=serialized_end, + serialized_options=serialized_options, + ) + self.index = index + self.methods = methods + self.methods_by_name = dict((m.name, m) for m in methods) + # Set the containing service for each method in this service. + for method in self.methods: + method.file = self.file + method.containing_service = self + + @property + def _parent(self): + return self.file + + def FindMethodByName(self, name): + """Searches for the specified method, and returns its descriptor. + + Args: + name (str): Name of the method. + + Returns: + MethodDescriptor: The descriptor for the requested method. + + Raises: + KeyError: if the method cannot be found in the service. + """ + return self.methods_by_name[name] + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.ServiceDescriptorProto. + + Args: + proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. + """ + # This function is overridden to give a better doc comment. + super(ServiceDescriptor, self).CopyToProto(proto) + + +class MethodDescriptor(DescriptorBase): + """Descriptor for a method in a service. + + Attributes: + name (str): Name of the method within the service. + full_name (str): Full name of method. + index (int): 0-indexed index of the method inside the service. + containing_service (ServiceDescriptor): The service that contains this + method. + input_type (Descriptor): The descriptor of the message that this method + accepts. + output_type (Descriptor): The descriptor of the message that this method + returns. + client_streaming (bool): Whether this method uses client streaming. + server_streaming (bool): Whether this method uses server streaming. + options (descriptor_pb2.MethodOptions or None): Method options message, or + None to use default method options. + """ + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.MethodDescriptor + + def __new__( + cls, + name, + full_name, + index, + containing_service, + input_type, + output_type, + client_streaming=False, + server_streaming=False, + options=None, + serialized_options=None, + create_key=None, + ): + _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access + return _message.default_pool.FindMethodByName(full_name) + + def __init__( + self, + name, + full_name, + index, + containing_service, + input_type, + output_type, + client_streaming=False, + server_streaming=False, + options=None, + serialized_options=None, + create_key=None, + ): + """The arguments are as described in the description of MethodDescriptor + + attributes above. + + Note that containing_service may be None, and may be set later if necessary. + """ + if create_key is not _internal_create_key: + _Deprecated('create function MethodDescriptor()') + + super(MethodDescriptor, self).__init__( + containing_service.file if containing_service else None, + options, + serialized_options, + 'MethodOptions', + ) + self.name = name + self.full_name = full_name + self.index = index + self.containing_service = containing_service + self.input_type = input_type + self.output_type = output_type + self.client_streaming = client_streaming + self.server_streaming = server_streaming + + @property + def _parent(self): + return self.containing_service + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.MethodDescriptorProto. + + Args: + proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto. + + Raises: + Error: If self couldn't be serialized, due to too few constructor + arguments. + """ + if self.containing_service is not None: + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + service_proto = descriptor_pb2.ServiceDescriptorProto() + self.containing_service.CopyToProto(service_proto) + proto.CopyFrom(service_proto.method[self.index]) + else: + raise Error('Descriptor does not contain a service.') + + +class FileDescriptor(DescriptorBase): + """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. + + Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and + :attr:`dependencies` fields are only set by the + :py:mod:`google.protobuf.message_factory` module, and not by the generated + proto code. + + Attributes: + name (str): Name of file, relative to root of source tree. + package (str): Name of the package + edition (Edition): Enum value indicating edition of the file + serialized_pb (bytes): Byte string of serialized + :class:`descriptor_pb2.FileDescriptorProto`. + dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` + objects this :class:`FileDescriptor` depends on. + public_dependencies (list[FileDescriptor]): A subset of + :attr:`dependencies`, which were declared as "public". + message_types_by_name (dict(str, Descriptor)): Mapping from message names to + their :class:`Descriptor`. + enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to + their :class:`EnumDescriptor`. + extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension + names declared at file scope to their :class:`FieldDescriptor`. + services_by_name (dict(str, ServiceDescriptor)): Mapping from services' + names to their :class:`ServiceDescriptor`. + pool (DescriptorPool): The pool this descriptor belongs to. When not passed + to the constructor, the global default pool is used. + """ + + if _USE_C_DESCRIPTORS: + _C_DESCRIPTOR_CLASS = _message.FileDescriptor + + def __new__( + cls, + name, + package, + options=None, + serialized_options=None, + serialized_pb=None, + dependencies=None, + public_dependencies=None, + syntax=None, + edition=None, + pool=None, + create_key=None, + ): + # FileDescriptor() is called from various places, not only from generated + # files, to register dynamic proto files and messages. + # pylint: disable=g-explicit-bool-comparison + if serialized_pb: + return _message.default_pool.AddSerializedFile(serialized_pb) + else: + return super(FileDescriptor, cls).__new__(cls) + + def __init__( + self, + name, + package, + options=None, + serialized_options=None, + serialized_pb=None, + dependencies=None, + public_dependencies=None, + syntax=None, + edition=None, + pool=None, + create_key=None, + ): + """Constructor.""" + if create_key is not _internal_create_key: + _Deprecated('create function FileDescriptor()') + + super(FileDescriptor, self).__init__( + self, options, serialized_options, 'FileOptions' + ) + + if edition and edition != 'EDITION_UNKNOWN': + self._edition = edition + elif syntax == 'proto3': + self._edition = 'EDITION_PROTO3' + else: + self._edition = 'EDITION_PROTO2' + + if pool is None: + from opentelemetry.agent._vendor.google.protobuf import descriptor_pool + + pool = descriptor_pool.Default() + self.pool = pool + self.message_types_by_name = {} + self.name = name + self.package = package + self.serialized_pb = serialized_pb + + self.enum_types_by_name = {} + self.extensions_by_name = {} + self.services_by_name = {} + self.dependencies = dependencies or [] + self.public_dependencies = public_dependencies or [] + + def CopyToProto(self, proto): + """Copies this to a descriptor_pb2.FileDescriptorProto. + + Args: + proto: An empty descriptor_pb2.FileDescriptorProto. + """ + proto.ParseFromString(self.serialized_pb) + + @property + def _parent(self): + return None + + +def _ParseOptions(message, string): + """Parses serialized options. + + This helper function is used to parse serialized options in generated + proto2 files. It must not be used outside proto2. + """ + message.ParseFromString(string) + return message + + +def _ToCamelCase(name): + """Converts name to camel-case and returns it.""" + capitalize_next = False + result = [] + + for c in name: + if c == '_': + if result: + capitalize_next = True + elif capitalize_next: + result.append(c.upper()) + capitalize_next = False + else: + result += c + + # Lower-case the first letter. + if result and result[0].isupper(): + result[0] = result[0].lower() + return ''.join(result) + + +def _OptionsOrNone(descriptor_proto): + """Returns the value of the field `options`, or None if it is not set.""" + if descriptor_proto.HasField('options'): + return descriptor_proto.options + else: + return None + + +def _ToJsonName(name): + """Converts name to Json name and returns it.""" + capitalize_next = False + result = [] + + for c in name: + if c == '_': + capitalize_next = True + elif capitalize_next: + result.append(c.upper()) + capitalize_next = False + else: + result += c + + return ''.join(result) + + +def MakeDescriptor( + desc_proto, + package='', + build_file_if_cpp=True, + syntax=None, + edition=None, + file_desc=None, +): + """Make a protobuf Descriptor given a DescriptorProto protobuf. + + Handles nested descriptors. Note that this is limited to the scope of defining + a message inside of another message. Composite fields can currently only be + resolved if the message is defined in the same scope as the field. + + Args: + desc_proto: The descriptor_pb2.DescriptorProto protobuf message. + package: Optional package name for the new message Descriptor (string). + build_file_if_cpp: Update the C++ descriptor pool if api matches. Set to + False on recursion, so no duplicates are created. + syntax: The syntax/semantics that should be used. Set to "proto3" to get + proto3 field presence semantics. + edition: The edition that should be used if syntax is "edition". + file_desc: A FileDescriptor to place this descriptor into. + + Returns: + A Descriptor for protobuf messages. + """ + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + # Generate a random name for this proto file to prevent conflicts with any + # imported ones. We need to specify a file name so the descriptor pool + # accepts our FileDescriptorProto, but it is not important what that file + # name is actually set to. + proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') + + if package: + file_name = os.path.join(package.replace('.', '/'), proto_name + '.proto') + else: + file_name = proto_name + '.proto' + + if api_implementation.Type() != 'python' and build_file_if_cpp: + # The C++ implementation requires all descriptors to be backed by the same + # definition in the C++ descriptor pool. To do this, we build a + # FileDescriptorProto with the same definition as this descriptor and build + # it into the pool. + file_descriptor_proto = descriptor_pb2.FileDescriptorProto() + file_descriptor_proto.message_type.add().MergeFrom(desc_proto) + + if package: + file_descriptor_proto.package = package + file_descriptor_proto.name = file_name + + _message.default_pool.Add(file_descriptor_proto) + result = _message.default_pool.FindFileByName(file_descriptor_proto.name) + + if _USE_C_DESCRIPTORS: + return result.message_types_by_name[desc_proto.name] + + if file_desc is None: + file_desc = FileDescriptor( + pool=None, + name=file_name, + package=package, + syntax=syntax, + edition=edition, + options=None, + serialized_pb='', + dependencies=[], + public_dependencies=[], + create_key=_internal_create_key, + ) + full_message_name = [desc_proto.name] + if package: + full_message_name.insert(0, package) + + # Create Descriptors for enum types + enum_types = {} + for enum_proto in desc_proto.enum_type: + full_name = '.'.join(full_message_name + [enum_proto.name]) + enum_desc = EnumDescriptor( + enum_proto.name, + full_name, + None, + [ + EnumValueDescriptor( + enum_val.name, + ii, + enum_val.number, + create_key=_internal_create_key, + ) + for ii, enum_val in enumerate(enum_proto.value) + ], + file=file_desc, + create_key=_internal_create_key, + ) + enum_types[full_name] = enum_desc + + # Create Descriptors for nested types + nested_types = {} + for nested_proto in desc_proto.nested_type: + full_name = '.'.join(full_message_name + [nested_proto.name]) + # Nested types are just those defined inside of the message, not all types + # used by fields in the message, so no loops are possible here. + nested_desc = MakeDescriptor( + nested_proto, + package='.'.join(full_message_name), + build_file_if_cpp=False, + syntax=syntax, + edition=edition, + file_desc=file_desc, + ) + nested_types[full_name] = nested_desc + + fields = [] + for field_proto in desc_proto.field: + full_name = '.'.join(full_message_name + [field_proto.name]) + enum_desc = None + nested_desc = None + if field_proto.json_name: + json_name = field_proto.json_name + else: + json_name = None + if field_proto.HasField('type_name'): + type_name = field_proto.type_name + full_type_name = '.'.join( + full_message_name + [type_name[type_name.rfind('.') + 1 :]] + ) + if full_type_name in nested_types: + nested_desc = nested_types[full_type_name] + elif full_type_name in enum_types: + enum_desc = enum_types[full_type_name] + # Else type_name references a non-local type, which isn't implemented + field = FieldDescriptor( + field_proto.name, + full_name, + field_proto.number - 1, + field_proto.number, + field_proto.type, + FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), + field_proto.label, + None, + nested_desc, + enum_desc, + None, + False, + None, + options=_OptionsOrNone(field_proto), + has_default_value=False, + json_name=json_name, + file=file_desc, + create_key=_internal_create_key, + ) + fields.append(field) + + desc_name = '.'.join(full_message_name) + return Descriptor( + desc_proto.name, + desc_name, + None, + None, + fields, + list(nested_types.values()), + list(enum_types.values()), + [], + options=_OptionsOrNone(desc_proto), + file=file_desc, + create_key=_internal_create_key, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py new file mode 100644 index 00000000000..ce0033efedb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py @@ -0,0 +1,186 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Provides a container for DescriptorProtos.""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +from typing import Dict, Iterator, Optional +import warnings + + +class Error(Exception): + pass + + +class DescriptorDatabaseConflictingDefinitionError(Error): + """Raised when a proto is added with the same name & different descriptor.""" + + +class DescriptorDatabase(object): + """A container accepting FileDescriptorProtos and maps DescriptorProtos.""" + + def __init__(self) -> None: + self._file_desc_protos_by_file: Dict[ + str, 'descriptor_pb2.FileDescriptorProto' + ] = {} + self._file_desc_protos_by_symbol: Dict[ + str, 'descriptor_pb2.FileDescriptorProto' + ] = {} + + def Add(self, file_desc_proto: 'descriptor_pb2.FileDescriptorProto') -> None: + """Adds the FileDescriptorProto and its types to this database. + + Args: + file_desc_proto: The FileDescriptorProto to add. + + Raises: + DescriptorDatabaseConflictingDefinitionError: if an attempt is made to + add a proto with the same name but different definition than an + existing proto in the database. + """ + proto_name = file_desc_proto.name + if proto_name not in self._file_desc_protos_by_file: + self._file_desc_protos_by_file[proto_name] = file_desc_proto + elif self._file_desc_protos_by_file[proto_name] != file_desc_proto: + raise DescriptorDatabaseConflictingDefinitionError( + '%s already added, but with different descriptor.' % proto_name + ) + else: + return + + # Add all the top-level descriptors to the index. + package = file_desc_proto.package + for message in file_desc_proto.message_type: + for name in _ExtractSymbols(message, package): + self._AddSymbol(name, file_desc_proto) + for enum in file_desc_proto.enum_type: + self._AddSymbol( + ('.'.join((package, enum.name)) if package else enum.name), + file_desc_proto, + ) + for enum_value in enum.value: + self._file_desc_protos_by_symbol[ + '.'.join((package, enum_value.name)) if package else enum_value.name + ] = file_desc_proto + for extension in file_desc_proto.extension: + self._AddSymbol( + ('.'.join((package, extension.name)) if package else extension.name), + file_desc_proto, + ) + for service in file_desc_proto.service: + self._AddSymbol( + ('.'.join((package, service.name)) if package else service.name), + file_desc_proto, + ) + + def FindFileByName(self, name: str) -> 'descriptor_pb2.FileDescriptorProto': + """Finds the file descriptor proto by file name. + + Typically the file name is a relative path ending to a .proto file. The + proto with the given name will have to have been added to this database + using the Add method or else an error will be raised. + + Args: + name: The file name to find. + + Returns: + The file descriptor proto matching the name. + + Raises: + KeyError if no file by the given name was added. + """ + + return self._file_desc_protos_by_file[name] + + def FindFileContainingSymbol( + self, symbol: str + ) -> 'descriptor_pb2.FileDescriptorProto': + """Finds the file descriptor proto containing the specified symbol. + + The symbol should be a fully qualified name including the file descriptor's + package and any containing messages. Some examples: + + 'some.package.name.Message' + 'some.package.name.Message.NestedEnum' + 'some.package.name.Message.some_field' + + The file descriptor proto containing the specified symbol must be added to + this database using the Add method or else an error will be raised. + + Args: + symbol: The fully qualified symbol name. + + Returns: + The file descriptor proto containing the symbol. + + Raises: + KeyError if no file contains the specified symbol. + """ + symbol = symbol.lstrip('.') + try: + return self._file_desc_protos_by_symbol[symbol] + except KeyError: + # Fields, enum values, and nested extensions are not in + # _file_desc_protos_by_symbol. Try to find the top level + # descriptor. Non-existent nested symbol under a valid top level + # descriptor can also be found. The behavior is the same with + # protobuf C++. + top_level, _, _ = symbol.rpartition('.') + try: + return self._file_desc_protos_by_symbol[top_level] + except KeyError: + # Raise the original symbol as a KeyError for better diagnostics. + raise KeyError(symbol) + + def FindFileContainingExtension( + self, + extendee_name: str, + extension_number: int, # pylint: disable=unused-argument + ) -> Optional['descriptor_pb2.FileDescriptorProto']: + # TODO: implement this API. + return None + + def FindAllExtensionNumbers(self, extendee_name: str) -> list[int]: # pylint: disable=unused-argument + # TODO: implement this API. + return [] + + def _AddSymbol( + self, name: str, file_desc_proto: 'descriptor_pb2.FileDescriptorProto' + ) -> None: + if name in self._file_desc_protos_by_symbol: + warn_msg = ( + 'Conflict register for file "' + + file_desc_proto.name + + '": ' + + name + + ' is already defined in file "' + + self._file_desc_protos_by_symbol[name].name + + '"' + ) + warnings.warn(warn_msg, RuntimeWarning) + self._file_desc_protos_by_symbol[name] = file_desc_proto + + +def _ExtractSymbols( + desc_proto: 'descriptor_pb2.DescriptorProto', package: str +) -> Iterator[str]: + """Pulls out all the symbols from a descriptor proto. + + Args: + desc_proto: The proto to extract symbols from. + package: The package containing the descriptor type. + + Yields: + The fully qualified name found in the descriptor. + """ + message_name = package + '.' + desc_proto.name if package else desc_proto.name + yield message_name + for nested_type in desc_proto.nested_type: + for symbol in _ExtractSymbols(nested_type, message_name): + yield symbol + for enum_type in desc_proto.enum_type: + yield '.'.join((message_name, enum_type.name)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py new file mode 100644 index 00000000000..31ed13939da --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py @@ -0,0 +1,3465 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/descriptor.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/descriptor.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR = _descriptor.FileDescriptor( + name='google/protobuf/descriptor.proto', + package='google.protobuf', + syntax='proto2', + edition='EDITION_PROTO2', + serialized_options=b'\n\023com.google.protobufB\020DescriptorProtosH\001Z-google.golang.org/protobuf/types/descriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Reflection', + create_key=_descriptor._internal_create_key, + serialized_pb=b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"[\n\x11\x46ileDescriptorSet\x12\x38\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProtoR\x04\x66ile*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xc5\x05\n\x13\x46ileDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n\x07package\x18\x02 \x01(\tR\x07package\x12\x1e\n\ndependency\x18\x03 \x03(\tR\ndependency\x12+\n\x11public_dependency\x18\n \x03(\x05R\x10publicDependency\x12\'\n\x0fweak_dependency\x18\x0b \x03(\x05R\x0eweakDependency\x12+\n\x11option_dependency\x18\x0f \x03(\tR\x10optionDependency\x12\x43\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\x0bmessageType\x12\x41\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12\x41\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProtoR\x07service\x12\x43\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x36\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptionsR\x07options\x12I\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfoR\x0esourceCodeInfo\x12\x16\n\x06syntax\x18\x0c \x01(\tR\x06syntax\x12\x32\n\x07\x65\x64ition\x18\x0e \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\"\xfc\x06\n\x0f\x44\x65scriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12;\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\x05\x66ield\x12\x43\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x41\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\nnestedType\x12\x41\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12X\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRangeR\x0e\x65xtensionRange\x12\x44\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProtoR\toneofDecl\x12\x39\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptionsR\x07options\x12U\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\n \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x0b \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1az\n\x0e\x45xtensionRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\x12@\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptionsR\x07options\x1a\x37\n\rReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\xd4\x04\n\x15\x45xtensionRangeOptions\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x12Y\n\x0b\x64\x65\x63laration\x18\x02 \x03(\x0b\x32\x32.google.protobuf.ExtensionRangeOptions.DeclarationB\x03\x88\x01\x02R\x0b\x64\x65\x63laration\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12m\n\x0cverification\x18\x03 \x01(\x0e\x32\x38.google.protobuf.ExtensionRangeOptions.VerificationState:\nUNVERIFIEDB\x03\x88\x01\x02R\x0cverification\x1a\x94\x01\n\x0b\x44\x65\x63laration\x12\x16\n\x06number\x18\x01 \x01(\x05R\x06number\x12\x1b\n\tfull_name\x18\x02 \x01(\tR\x08\x66ullName\x12\x12\n\x04type\x18\x03 \x01(\tR\x04type\x12\x1a\n\x08reserved\x18\x05 \x01(\x08R\x08reserved\x12\x1a\n\x08repeated\x18\x06 \x01(\x08R\x08repeatedJ\x04\x08\x04\x10\x05\"4\n\x11VerificationState\x12\x0f\n\x0b\x44\x45\x43LARATION\x10\x00\x12\x0e\n\nUNVERIFIED\x10\x01*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xc1\x06\n\x14\x46ieldDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x03 \x01(\x05R\x06number\x12\x41\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.LabelR\x05label\x12>\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.TypeR\x04type\x12\x1b\n\ttype_name\x18\x06 \x01(\tR\x08typeName\x12\x1a\n\x08\x65xtendee\x18\x02 \x01(\tR\x08\x65xtendee\x12#\n\rdefault_value\x18\x07 \x01(\tR\x0c\x64\x65\x66\x61ultValue\x12\x1f\n\x0boneof_index\x18\t \x01(\x05R\noneofIndex\x12\x1b\n\tjson_name\x18\n \x01(\tR\x08jsonName\x12\x37\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptionsR\x07options\x12\'\n\x0fproto3_optional\x18\x11 \x01(\x08R\x0eproto3Optional\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REPEATED\x10\x03\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\"c\n\x14OneofDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x37\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptionsR\x07options\"\xa6\x03\n\x13\x45numDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12?\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProtoR\x05value\x12\x36\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptionsR\x07options\x12]\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\x05 \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x06 \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1a;\n\x11\x45numReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\x83\x01\n\x18\x45numValueDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x02 \x01(\x05R\x06number\x12;\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptionsR\x07options\"\xb5\x01\n\x16ServiceDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12>\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProtoR\x06method\x12\x39\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptionsR\x07optionsJ\x04\x08\x04\x10\x05R\x06stream\"\x89\x02\n\x15MethodDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1d\n\ninput_type\x18\x02 \x01(\tR\tinputType\x12\x1f\n\x0boutput_type\x18\x03 \x01(\tR\noutputType\x12\x38\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptionsR\x07options\x12\x30\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lseR\x0f\x63lientStreaming\x12\x30\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lseR\x0fserverStreaming\"\x8c\x0c\n\x0b\x46ileOptions\x12!\n\x0cjava_package\x18\x01 \x01(\tR\x0bjavaPackage\x12\x30\n\x14java_outer_classname\x18\x08 \x01(\tR\x12javaOuterClassname\x12\xf9\x01\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lseB\xc1\x01\xb2\x01\xbd\x01\x08\xe6\x07 \xe9\x07*\xb4\x01This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.R\x11javaMultipleFiles\x12\x44\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01R\x19javaGenerateEqualsAndHash\x12:\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lseR\x13javaStringCheckUtf8\x12S\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEEDR\x0boptimizeFor\x12\x1d\n\ngo_package\x18\x0b \x01(\tR\tgoPackage\x12\x35\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lseR\x11\x63\x63GenericServices\x12\x39\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lseR\x13javaGenericServices\x12\x35\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lseR\x11pyGenericServices\x12%\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\xbf\x01\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04trueB\x8e\x01\xb2\x01\x8a\x01 \xea\x07*\x84\x01\x63\x63_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.R\x0e\x63\x63\x45nableArenas\x12*\n\x11objc_class_prefix\x18$ \x01(\tR\x0fobjcClassPrefix\x12)\n\x10\x63sharp_namespace\x18% \x01(\tR\x0f\x63sharpNamespace\x12!\n\x0cswift_prefix\x18\' \x01(\tR\x0bswiftPrefix\x12(\n\x10php_class_prefix\x18( \x01(\tR\x0ephpClassPrefix\x12#\n\rphp_namespace\x18) \x01(\tR\x0cphpNamespace\x12\x34\n\x16php_metadata_namespace\x18, \x01(\tR\x14phpMetadataNamespace\x12!\n\x0cruby_package\x18- \x01(\tR\x0brubyPackage\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08*\x10+J\x04\x08&\x10\'R\x14php_generic_services\"\xfc\x03\n\x0eMessageOptions\x12<\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lseR\x14messageSetWireFormat\x12L\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lseR\x1cnoStandardDescriptorAccessor\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1b\n\tmap_entry\x18\x07 \x01(\x08R\x08mapEntry\x12V\n&deprecated_legacy_json_field_conflicts\x18\x0b \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xce\r\n\x0c\x46ieldOptions\x12\x41\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRINGR\x05\x63type\x12\x16\n\x06packed\x18\x02 \x01(\x08R\x06packed\x12G\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMALR\x06jstype\x12\x19\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lseR\x04lazy\x12.\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lseR\x0eunverifiedLazy\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1d\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lseB\x02\x18\x01R\x04weak\x12(\n\x0c\x64\x65\x62ug_redact\x18\x10 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12K\n\tretention\x18\x11 \x01(\x0e\x32-.google.protobuf.FieldOptions.OptionRetentionR\tretention\x12H\n\x07targets\x18\x13 \x03(\x0e\x32..google.protobuf.FieldOptions.OptionTargetTypeR\x07targets\x12W\n\x10\x65\x64ition_defaults\x18\x14 \x03(\x0b\x32,.google.protobuf.FieldOptions.EditionDefaultR\x0f\x65\x64itionDefaults\x12\x37\n\x08\x66\x65\x61tures\x18\x15 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12U\n\x0f\x66\x65\x61ture_support\x18\x16 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x1aZ\n\x0e\x45\x64itionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value\x1a\xbb\x02\n\x0e\x46\x65\x61tureSupport\x12G\n\x12\x65\x64ition_introduced\x18\x01 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionIntroduced\x12G\n\x12\x65\x64ition_deprecated\x18\x02 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionDeprecated\x12/\n\x13\x64\x65precation_warning\x18\x03 \x01(\tR\x12\x64\x65precationWarning\x12\x41\n\x0f\x65\x64ition_removed\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0e\x65\x64itionRemoved\x12#\n\rremoval_error\x18\x05 \x01(\tR\x0cremovalError\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02\"U\n\x0fOptionRetention\x12\x15\n\x11RETENTION_UNKNOWN\x10\x00\x12\x15\n\x11RETENTION_RUNTIME\x10\x01\x12\x14\n\x10RETENTION_SOURCE\x10\x02\"\x8c\x02\n\x10OptionTargetType\x12\x17\n\x13TARGET_TYPE_UNKNOWN\x10\x00\x12\x14\n\x10TARGET_TYPE_FILE\x10\x01\x12\x1f\n\x1bTARGET_TYPE_EXTENSION_RANGE\x10\x02\x12\x17\n\x13TARGET_TYPE_MESSAGE\x10\x03\x12\x15\n\x11TARGET_TYPE_FIELD\x10\x04\x12\x15\n\x11TARGET_TYPE_ONEOF\x10\x05\x12\x14\n\x10TARGET_TYPE_ENUM\x10\x06\x12\x1a\n\x16TARGET_TYPE_ENUM_ENTRY\x10\x07\x12\x17\n\x13TARGET_TYPE_SERVICE\x10\x08\x12\x16\n\x12TARGET_TYPE_METHOD\x10\t*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x12\x10\x13\"\xb4\x01\n\x0cOneofOptions\x12\x37\n\x08\x66\x65\x61tures\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd9\x02\n\x0b\x45numOptions\x12\x1f\n\x0b\x61llow_alias\x18\x02 \x01(\x08R\nallowAlias\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12V\n&deprecated_legacy_json_field_conflicts\x18\x06 \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x07 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"\xe0\x02\n\x10\x45numValueOptions\x12%\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x37\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12(\n\x0c\x64\x65\x62ug_redact\x18\x03 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12U\n\x0f\x66\x65\x61ture_support\x18\x04 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xdd\x01\n\x0eServiceOptions\x12\x37\n\x08\x66\x65\x61tures\x18\" \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xa1\x03\n\rMethodOptions\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12q\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWNR\x10idempotencyLevel\x12\x37\n\x08\x66\x65\x61tures\x18# \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9a\x03\n\x13UninterpretedOption\x12\x41\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePartR\x04name\x12)\n\x10identifier_value\x18\x03 \x01(\tR\x0fidentifierValue\x12,\n\x12positive_int_value\x18\x04 \x01(\x04R\x10positiveIntValue\x12,\n\x12negative_int_value\x18\x05 \x01(\x03R\x10negativeIntValue\x12!\n\x0c\x64ouble_value\x18\x06 \x01(\x01R\x0b\x64oubleValue\x12!\n\x0cstring_value\x18\x07 \x01(\x0cR\x0bstringValue\x12\'\n\x0f\x61ggregate_value\x18\x08 \x01(\tR\x0e\x61ggregateValue\x1aJ\n\x08NamePart\x12\x1b\n\tname_part\x18\x01 \x02(\tR\x08namePart\x12!\n\x0cis_extension\x18\x02 \x02(\x08R\x0bisExtension\"\xfd\x11\n\nFeatureSet\x12\x91\x01\n\x0e\x66ield_presence\x18\x01 \x01(\x0e\x32).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPLICIT\x18\x84\x07\xa2\x01\r\x12\x08IMPLICIT\x18\xe7\x07\xa2\x01\r\x12\x08\x45XPLICIT\x18\xe8\x07\xb2\x01\x03\x08\xe8\x07R\rfieldPresence\x12l\n\tenum_type\x18\x02 \x01(\x0e\x32$.google.protobuf.FeatureSet.EnumTypeB)\x88\x01\x01\x98\x01\x06\x98\x01\x01\xa2\x01\x0b\x12\x06\x43LOSED\x18\x84\x07\xa2\x01\t\x12\x04OPEN\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x08\x65numType\x12\x98\x01\n\x17repeated_field_encoding\x18\x03 \x01(\x0e\x32\x31.google.protobuf.FeatureSet.RepeatedFieldEncodingB-\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPANDED\x18\x84\x07\xa2\x01\x0b\x12\x06PACKED\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x15repeatedFieldEncoding\x12~\n\x0futf8_validation\x18\x04 \x01(\x0e\x32*.google.protobuf.FeatureSet.Utf8ValidationB)\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\t\x12\x04NONE\x18\x84\x07\xa2\x01\x0b\x12\x06VERIFY\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x0eutf8Validation\x12~\n\x10message_encoding\x18\x05 \x01(\x0e\x32+.google.protobuf.FeatureSet.MessageEncodingB&\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\x14\x12\x0fLENGTH_PREFIXED\x18\x84\x07\xb2\x01\x03\x08\xe8\x07R\x0fmessageEncoding\x12\x82\x01\n\x0bjson_format\x18\x06 \x01(\x0e\x32&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\x07\xa2\x01\n\x12\x05\x41LLOW\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\njsonFormat\x12\xbc\x01\n\x14\x65nforce_naming_style\x18\x07 \x01(\x0e\x32..google.protobuf.FeatureSet.EnforceNamingStyleBZ\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\x07\x98\x01\x08\x98\x01\t\xa2\x01\x11\x12\x0cSTYLE_LEGACY\x18\x84\x07\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\x07\xa2\x01\x0e\x12\tSTYLE2026\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x12\x65nforceNamingStyle\x12\xc7\x01\n\x19\x64\x65\x66\x61ult_symbol_visibility\x18\x08 \x01(\x0e\x32\x45.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityBD\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\nEXPORT_ALL\x18\x84\x07\xa2\x01\x15\x12\x10\x45XPORT_TOP_LEVEL\x18\xe9\x07\xa2\x01\x0b\x12\x06STRICT\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x17\x64\x65\x66\x61ultSymbolVisibility\x12\xc3\x01\n\x14\x65nforce_proto_limits\x18\t \x01(\x0e\x32\x41.google.protobuf.FeatureSet.ProtoLimitsFeature.EnforceProtoLimitsBN\x88\x01\x02\x98\x01\x06\x98\x01\x03\x98\x01\x04\x98\x01\x05\xa2\x01\x1e\x12\x19LEGACY_NO_EXPLICIT_LIMITS\x18\x84\x07\xa2\x01\x15\x12\x10PROTO_LIMITS2026\x18\xea\x07\xb2\x01\x03\x08\xea\x07R\x12\x65nforceProtoLimits\x1a\xa1\x01\n\x11VisibilityFeature\"\x81\x01\n\x17\x44\x65\x66\x61ultSymbolVisibility\x12%\n!DEFAULT_SYMBOL_VISIBILITY_UNKNOWN\x10\x00\x12\x0e\n\nEXPORT_ALL\x10\x01\x12\x14\n\x10\x45XPORT_TOP_LEVEL\x10\x02\x12\r\n\tLOCAL_ALL\x10\x03\x12\n\n\x06STRICT\x10\x04J\x08\x08\x01\x10\x80\x80\x80\x80\x02\x1ay\n\x12ProtoLimitsFeature\"c\n\x12\x45nforceProtoLimits\x12\x18\n\x14PROTO_LIMITS_UNKNOWN\x10\x00\x12\x1d\n\x19LEGACY_NO_EXPLICIT_LIMITS\x10\x01\x12\x14\n\x10PROTO_LIMITS2026\x10\x02\"\\\n\rFieldPresence\x12\x1a\n\x16\x46IELD_PRESENCE_UNKNOWN\x10\x00\x12\x0c\n\x08\x45XPLICIT\x10\x01\x12\x0c\n\x08IMPLICIT\x10\x02\x12\x13\n\x0fLEGACY_REQUIRED\x10\x03\"7\n\x08\x45numType\x12\x15\n\x11\x45NUM_TYPE_UNKNOWN\x10\x00\x12\x08\n\x04OPEN\x10\x01\x12\n\n\x06\x43LOSED\x10\x02\"V\n\x15RepeatedFieldEncoding\x12#\n\x1fREPEATED_FIELD_ENCODING_UNKNOWN\x10\x00\x12\n\n\x06PACKED\x10\x01\x12\x0c\n\x08\x45XPANDED\x10\x02\"I\n\x0eUtf8Validation\x12\x1b\n\x17UTF8_VALIDATION_UNKNOWN\x10\x00\x12\n\n\x06VERIFY\x10\x02\x12\x08\n\x04NONE\x10\x03\"\x04\x08\x01\x10\x01\"S\n\x0fMessageEncoding\x12\x1c\n\x18MESSAGE_ENCODING_UNKNOWN\x10\x00\x12\x13\n\x0fLENGTH_PREFIXED\x10\x01\x12\r\n\tDELIMITED\x10\x02\"H\n\nJsonFormat\x12\x17\n\x13JSON_FORMAT_UNKNOWN\x10\x00\x12\t\n\x05\x41LLOW\x10\x01\x12\x16\n\x12LEGACY_BEST_EFFORT\x10\x02\"f\n\x12\x45nforceNamingStyle\x12 \n\x1c\x45NFORCE_NAMING_STYLE_UNKNOWN\x10\x00\x12\r\n\tSTYLE2024\x10\x01\x12\x10\n\x0cSTYLE_LEGACY\x10\x02\x12\r\n\tSTYLE2026\x10\x03*\x06\x08\xe8\x07\x10\x8bN*\x06\x08\x8bN\x10\x90N*\x06\x08\x90N\x10\x91NJ\x06\x08\xe7\x07\x10\xe8\x07\"\xef\x03\n\x12\x46\x65\x61tureSetDefaults\x12X\n\x08\x64\x65\x66\x61ults\x18\x01 \x03(\x0b\x32<.google.protobuf.FeatureSetDefaults.FeatureSetEditionDefaultR\x08\x64\x65\x66\x61ults\x12\x41\n\x0fminimum_edition\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0eminimumEdition\x12\x41\n\x0fmaximum_edition\x18\x05 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0emaximumEdition\x1a\xf8\x01\n\x18\x46\x65\x61tureSetEditionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12N\n\x14overridable_features\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x13overridableFeatures\x12\x42\n\x0e\x66ixed_features\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\rfixedFeaturesJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03R\x08\x66\x65\x61tures\"\xb5\x02\n\x0eSourceCodeInfo\x12\x44\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.LocationR\x08location\x1a\xce\x01\n\x08Location\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x16\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01R\x04span\x12)\n\x10leading_comments\x18\x03 \x01(\tR\x0fleadingComments\x12+\n\x11trailing_comments\x18\x04 \x01(\tR\x10trailingComments\x12:\n\x19leading_detached_comments\x18\x06 \x03(\tR\x17leadingDetachedComments*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xd0\x02\n\x11GeneratedCodeInfo\x12M\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.AnnotationR\nannotation\x1a\xeb\x01\n\nAnnotation\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x1f\n\x0bsource_file\x18\x02 \x01(\tR\nsourceFile\x12\x14\n\x05\x62\x65gin\x18\x03 \x01(\x05R\x05\x62\x65gin\x12\x10\n\x03\x65nd\x18\x04 \x01(\x05R\x03\x65nd\x12R\n\x08semantic\x18\x05 \x01(\x0e\x32\x36.google.protobuf.GeneratedCodeInfo.Annotation.SemanticR\x08semantic\"(\n\x08Semantic\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03SET\x10\x01\x12\t\n\x05\x41LIAS\x10\x02*\xd1\x02\n\x07\x45\x64ition\x12\x13\n\x0f\x45\x44ITION_UNKNOWN\x10\x00\x12\x13\n\x0e\x45\x44ITION_LEGACY\x10\x84\x07\x12\x13\n\x0e\x45\x44ITION_PROTO2\x10\xe6\x07\x12\x13\n\x0e\x45\x44ITION_PROTO3\x10\xe7\x07\x12\x11\n\x0c\x45\x44ITION_2023\x10\xe8\x07\x12\x11\n\x0c\x45\x44ITION_2024\x10\xe9\x07\x12\x11\n\x0c\x45\x44ITION_2026\x10\xea\x07\x12\x15\n\x10\x45\x44ITION_UNSTABLE\x10\x8fN\x12\x17\n\x13\x45\x44ITION_1_TEST_ONLY\x10\x01\x12\x17\n\x13\x45\x44ITION_2_TEST_ONLY\x10\x02\x12\x1d\n\x17\x45\x44ITION_99997_TEST_ONLY\x10\x9d\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99998_TEST_ONLY\x10\x9e\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99999_TEST_ONLY\x10\x9f\x8d\x06\x12\x13\n\x0b\x45\x44ITION_MAX\x10\xff\xff\xff\xff\x07*U\n\x10SymbolVisibility\x12\x14\n\x10VISIBILITY_UNSET\x10\x00\x12\x14\n\x10VISIBILITY_LOCAL\x10\x01\x12\x15\n\x11VISIBILITY_EXPORT\x10\x02\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection' + ) +else: + DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"[\n\x11\x46ileDescriptorSet\x12\x38\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProtoR\x04\x66ile*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xc5\x05\n\x13\x46ileDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n\x07package\x18\x02 \x01(\tR\x07package\x12\x1e\n\ndependency\x18\x03 \x03(\tR\ndependency\x12+\n\x11public_dependency\x18\n \x03(\x05R\x10publicDependency\x12\'\n\x0fweak_dependency\x18\x0b \x03(\x05R\x0eweakDependency\x12+\n\x11option_dependency\x18\x0f \x03(\tR\x10optionDependency\x12\x43\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\x0bmessageType\x12\x41\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12\x41\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProtoR\x07service\x12\x43\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x36\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptionsR\x07options\x12I\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfoR\x0esourceCodeInfo\x12\x16\n\x06syntax\x18\x0c \x01(\tR\x06syntax\x12\x32\n\x07\x65\x64ition\x18\x0e \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\"\xfc\x06\n\x0f\x44\x65scriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12;\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\x05\x66ield\x12\x43\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x41\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\nnestedType\x12\x41\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12X\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRangeR\x0e\x65xtensionRange\x12\x44\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProtoR\toneofDecl\x12\x39\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptionsR\x07options\x12U\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\n \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x0b \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1az\n\x0e\x45xtensionRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\x12@\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptionsR\x07options\x1a\x37\n\rReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\xd4\x04\n\x15\x45xtensionRangeOptions\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x12Y\n\x0b\x64\x65\x63laration\x18\x02 \x03(\x0b\x32\x32.google.protobuf.ExtensionRangeOptions.DeclarationB\x03\x88\x01\x02R\x0b\x64\x65\x63laration\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12m\n\x0cverification\x18\x03 \x01(\x0e\x32\x38.google.protobuf.ExtensionRangeOptions.VerificationState:\nUNVERIFIEDB\x03\x88\x01\x02R\x0cverification\x1a\x94\x01\n\x0b\x44\x65\x63laration\x12\x16\n\x06number\x18\x01 \x01(\x05R\x06number\x12\x1b\n\tfull_name\x18\x02 \x01(\tR\x08\x66ullName\x12\x12\n\x04type\x18\x03 \x01(\tR\x04type\x12\x1a\n\x08reserved\x18\x05 \x01(\x08R\x08reserved\x12\x1a\n\x08repeated\x18\x06 \x01(\x08R\x08repeatedJ\x04\x08\x04\x10\x05\"4\n\x11VerificationState\x12\x0f\n\x0b\x44\x45\x43LARATION\x10\x00\x12\x0e\n\nUNVERIFIED\x10\x01*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xc1\x06\n\x14\x46ieldDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x03 \x01(\x05R\x06number\x12\x41\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.LabelR\x05label\x12>\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.TypeR\x04type\x12\x1b\n\ttype_name\x18\x06 \x01(\tR\x08typeName\x12\x1a\n\x08\x65xtendee\x18\x02 \x01(\tR\x08\x65xtendee\x12#\n\rdefault_value\x18\x07 \x01(\tR\x0c\x64\x65\x66\x61ultValue\x12\x1f\n\x0boneof_index\x18\t \x01(\x05R\noneofIndex\x12\x1b\n\tjson_name\x18\n \x01(\tR\x08jsonName\x12\x37\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptionsR\x07options\x12\'\n\x0fproto3_optional\x18\x11 \x01(\x08R\x0eproto3Optional\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REPEATED\x10\x03\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\"c\n\x14OneofDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x37\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptionsR\x07options\"\xa6\x03\n\x13\x45numDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12?\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProtoR\x05value\x12\x36\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptionsR\x07options\x12]\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\x05 \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x06 \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1a;\n\x11\x45numReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\x83\x01\n\x18\x45numValueDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x02 \x01(\x05R\x06number\x12;\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptionsR\x07options\"\xb5\x01\n\x16ServiceDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12>\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProtoR\x06method\x12\x39\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptionsR\x07optionsJ\x04\x08\x04\x10\x05R\x06stream\"\x89\x02\n\x15MethodDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1d\n\ninput_type\x18\x02 \x01(\tR\tinputType\x12\x1f\n\x0boutput_type\x18\x03 \x01(\tR\noutputType\x12\x38\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptionsR\x07options\x12\x30\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lseR\x0f\x63lientStreaming\x12\x30\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lseR\x0fserverStreaming\"\x8c\x0c\n\x0b\x46ileOptions\x12!\n\x0cjava_package\x18\x01 \x01(\tR\x0bjavaPackage\x12\x30\n\x14java_outer_classname\x18\x08 \x01(\tR\x12javaOuterClassname\x12\xf9\x01\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lseB\xc1\x01\xb2\x01\xbd\x01\x08\xe6\x07 \xe9\x07*\xb4\x01This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.R\x11javaMultipleFiles\x12\x44\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01R\x19javaGenerateEqualsAndHash\x12:\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lseR\x13javaStringCheckUtf8\x12S\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEEDR\x0boptimizeFor\x12\x1d\n\ngo_package\x18\x0b \x01(\tR\tgoPackage\x12\x35\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lseR\x11\x63\x63GenericServices\x12\x39\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lseR\x13javaGenericServices\x12\x35\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lseR\x11pyGenericServices\x12%\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\xbf\x01\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04trueB\x8e\x01\xb2\x01\x8a\x01 \xea\x07*\x84\x01\x63\x63_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.R\x0e\x63\x63\x45nableArenas\x12*\n\x11objc_class_prefix\x18$ \x01(\tR\x0fobjcClassPrefix\x12)\n\x10\x63sharp_namespace\x18% \x01(\tR\x0f\x63sharpNamespace\x12!\n\x0cswift_prefix\x18\' \x01(\tR\x0bswiftPrefix\x12(\n\x10php_class_prefix\x18( \x01(\tR\x0ephpClassPrefix\x12#\n\rphp_namespace\x18) \x01(\tR\x0cphpNamespace\x12\x34\n\x16php_metadata_namespace\x18, \x01(\tR\x14phpMetadataNamespace\x12!\n\x0cruby_package\x18- \x01(\tR\x0brubyPackage\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08*\x10+J\x04\x08&\x10\'R\x14php_generic_services\"\xfc\x03\n\x0eMessageOptions\x12<\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lseR\x14messageSetWireFormat\x12L\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lseR\x1cnoStandardDescriptorAccessor\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1b\n\tmap_entry\x18\x07 \x01(\x08R\x08mapEntry\x12V\n&deprecated_legacy_json_field_conflicts\x18\x0b \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xce\r\n\x0c\x46ieldOptions\x12\x41\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRINGR\x05\x63type\x12\x16\n\x06packed\x18\x02 \x01(\x08R\x06packed\x12G\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMALR\x06jstype\x12\x19\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lseR\x04lazy\x12.\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lseR\x0eunverifiedLazy\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1d\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lseB\x02\x18\x01R\x04weak\x12(\n\x0c\x64\x65\x62ug_redact\x18\x10 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12K\n\tretention\x18\x11 \x01(\x0e\x32-.google.protobuf.FieldOptions.OptionRetentionR\tretention\x12H\n\x07targets\x18\x13 \x03(\x0e\x32..google.protobuf.FieldOptions.OptionTargetTypeR\x07targets\x12W\n\x10\x65\x64ition_defaults\x18\x14 \x03(\x0b\x32,.google.protobuf.FieldOptions.EditionDefaultR\x0f\x65\x64itionDefaults\x12\x37\n\x08\x66\x65\x61tures\x18\x15 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12U\n\x0f\x66\x65\x61ture_support\x18\x16 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x1aZ\n\x0e\x45\x64itionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value\x1a\xbb\x02\n\x0e\x46\x65\x61tureSupport\x12G\n\x12\x65\x64ition_introduced\x18\x01 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionIntroduced\x12G\n\x12\x65\x64ition_deprecated\x18\x02 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionDeprecated\x12/\n\x13\x64\x65precation_warning\x18\x03 \x01(\tR\x12\x64\x65precationWarning\x12\x41\n\x0f\x65\x64ition_removed\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0e\x65\x64itionRemoved\x12#\n\rremoval_error\x18\x05 \x01(\tR\x0cremovalError\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02\"U\n\x0fOptionRetention\x12\x15\n\x11RETENTION_UNKNOWN\x10\x00\x12\x15\n\x11RETENTION_RUNTIME\x10\x01\x12\x14\n\x10RETENTION_SOURCE\x10\x02\"\x8c\x02\n\x10OptionTargetType\x12\x17\n\x13TARGET_TYPE_UNKNOWN\x10\x00\x12\x14\n\x10TARGET_TYPE_FILE\x10\x01\x12\x1f\n\x1bTARGET_TYPE_EXTENSION_RANGE\x10\x02\x12\x17\n\x13TARGET_TYPE_MESSAGE\x10\x03\x12\x15\n\x11TARGET_TYPE_FIELD\x10\x04\x12\x15\n\x11TARGET_TYPE_ONEOF\x10\x05\x12\x14\n\x10TARGET_TYPE_ENUM\x10\x06\x12\x1a\n\x16TARGET_TYPE_ENUM_ENTRY\x10\x07\x12\x17\n\x13TARGET_TYPE_SERVICE\x10\x08\x12\x16\n\x12TARGET_TYPE_METHOD\x10\t*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x12\x10\x13\"\xb4\x01\n\x0cOneofOptions\x12\x37\n\x08\x66\x65\x61tures\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd9\x02\n\x0b\x45numOptions\x12\x1f\n\x0b\x61llow_alias\x18\x02 \x01(\x08R\nallowAlias\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12V\n&deprecated_legacy_json_field_conflicts\x18\x06 \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x07 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"\xe0\x02\n\x10\x45numValueOptions\x12%\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x37\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12(\n\x0c\x64\x65\x62ug_redact\x18\x03 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12U\n\x0f\x66\x65\x61ture_support\x18\x04 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xdd\x01\n\x0eServiceOptions\x12\x37\n\x08\x66\x65\x61tures\x18\" \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xa1\x03\n\rMethodOptions\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12q\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWNR\x10idempotencyLevel\x12\x37\n\x08\x66\x65\x61tures\x18# \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9a\x03\n\x13UninterpretedOption\x12\x41\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePartR\x04name\x12)\n\x10identifier_value\x18\x03 \x01(\tR\x0fidentifierValue\x12,\n\x12positive_int_value\x18\x04 \x01(\x04R\x10positiveIntValue\x12,\n\x12negative_int_value\x18\x05 \x01(\x03R\x10negativeIntValue\x12!\n\x0c\x64ouble_value\x18\x06 \x01(\x01R\x0b\x64oubleValue\x12!\n\x0cstring_value\x18\x07 \x01(\x0cR\x0bstringValue\x12\'\n\x0f\x61ggregate_value\x18\x08 \x01(\tR\x0e\x61ggregateValue\x1aJ\n\x08NamePart\x12\x1b\n\tname_part\x18\x01 \x02(\tR\x08namePart\x12!\n\x0cis_extension\x18\x02 \x02(\x08R\x0bisExtension\"\xfd\x11\n\nFeatureSet\x12\x91\x01\n\x0e\x66ield_presence\x18\x01 \x01(\x0e\x32).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPLICIT\x18\x84\x07\xa2\x01\r\x12\x08IMPLICIT\x18\xe7\x07\xa2\x01\r\x12\x08\x45XPLICIT\x18\xe8\x07\xb2\x01\x03\x08\xe8\x07R\rfieldPresence\x12l\n\tenum_type\x18\x02 \x01(\x0e\x32$.google.protobuf.FeatureSet.EnumTypeB)\x88\x01\x01\x98\x01\x06\x98\x01\x01\xa2\x01\x0b\x12\x06\x43LOSED\x18\x84\x07\xa2\x01\t\x12\x04OPEN\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x08\x65numType\x12\x98\x01\n\x17repeated_field_encoding\x18\x03 \x01(\x0e\x32\x31.google.protobuf.FeatureSet.RepeatedFieldEncodingB-\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPANDED\x18\x84\x07\xa2\x01\x0b\x12\x06PACKED\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x15repeatedFieldEncoding\x12~\n\x0futf8_validation\x18\x04 \x01(\x0e\x32*.google.protobuf.FeatureSet.Utf8ValidationB)\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\t\x12\x04NONE\x18\x84\x07\xa2\x01\x0b\x12\x06VERIFY\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x0eutf8Validation\x12~\n\x10message_encoding\x18\x05 \x01(\x0e\x32+.google.protobuf.FeatureSet.MessageEncodingB&\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\x14\x12\x0fLENGTH_PREFIXED\x18\x84\x07\xb2\x01\x03\x08\xe8\x07R\x0fmessageEncoding\x12\x82\x01\n\x0bjson_format\x18\x06 \x01(\x0e\x32&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\x07\xa2\x01\n\x12\x05\x41LLOW\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\njsonFormat\x12\xbc\x01\n\x14\x65nforce_naming_style\x18\x07 \x01(\x0e\x32..google.protobuf.FeatureSet.EnforceNamingStyleBZ\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\x07\x98\x01\x08\x98\x01\t\xa2\x01\x11\x12\x0cSTYLE_LEGACY\x18\x84\x07\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\x07\xa2\x01\x0e\x12\tSTYLE2026\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x12\x65nforceNamingStyle\x12\xc7\x01\n\x19\x64\x65\x66\x61ult_symbol_visibility\x18\x08 \x01(\x0e\x32\x45.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityBD\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\nEXPORT_ALL\x18\x84\x07\xa2\x01\x15\x12\x10\x45XPORT_TOP_LEVEL\x18\xe9\x07\xa2\x01\x0b\x12\x06STRICT\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x17\x64\x65\x66\x61ultSymbolVisibility\x12\xc3\x01\n\x14\x65nforce_proto_limits\x18\t \x01(\x0e\x32\x41.google.protobuf.FeatureSet.ProtoLimitsFeature.EnforceProtoLimitsBN\x88\x01\x02\x98\x01\x06\x98\x01\x03\x98\x01\x04\x98\x01\x05\xa2\x01\x1e\x12\x19LEGACY_NO_EXPLICIT_LIMITS\x18\x84\x07\xa2\x01\x15\x12\x10PROTO_LIMITS2026\x18\xea\x07\xb2\x01\x03\x08\xea\x07R\x12\x65nforceProtoLimits\x1a\xa1\x01\n\x11VisibilityFeature\"\x81\x01\n\x17\x44\x65\x66\x61ultSymbolVisibility\x12%\n!DEFAULT_SYMBOL_VISIBILITY_UNKNOWN\x10\x00\x12\x0e\n\nEXPORT_ALL\x10\x01\x12\x14\n\x10\x45XPORT_TOP_LEVEL\x10\x02\x12\r\n\tLOCAL_ALL\x10\x03\x12\n\n\x06STRICT\x10\x04J\x08\x08\x01\x10\x80\x80\x80\x80\x02\x1ay\n\x12ProtoLimitsFeature\"c\n\x12\x45nforceProtoLimits\x12\x18\n\x14PROTO_LIMITS_UNKNOWN\x10\x00\x12\x1d\n\x19LEGACY_NO_EXPLICIT_LIMITS\x10\x01\x12\x14\n\x10PROTO_LIMITS2026\x10\x02\"\\\n\rFieldPresence\x12\x1a\n\x16\x46IELD_PRESENCE_UNKNOWN\x10\x00\x12\x0c\n\x08\x45XPLICIT\x10\x01\x12\x0c\n\x08IMPLICIT\x10\x02\x12\x13\n\x0fLEGACY_REQUIRED\x10\x03\"7\n\x08\x45numType\x12\x15\n\x11\x45NUM_TYPE_UNKNOWN\x10\x00\x12\x08\n\x04OPEN\x10\x01\x12\n\n\x06\x43LOSED\x10\x02\"V\n\x15RepeatedFieldEncoding\x12#\n\x1fREPEATED_FIELD_ENCODING_UNKNOWN\x10\x00\x12\n\n\x06PACKED\x10\x01\x12\x0c\n\x08\x45XPANDED\x10\x02\"I\n\x0eUtf8Validation\x12\x1b\n\x17UTF8_VALIDATION_UNKNOWN\x10\x00\x12\n\n\x06VERIFY\x10\x02\x12\x08\n\x04NONE\x10\x03\"\x04\x08\x01\x10\x01\"S\n\x0fMessageEncoding\x12\x1c\n\x18MESSAGE_ENCODING_UNKNOWN\x10\x00\x12\x13\n\x0fLENGTH_PREFIXED\x10\x01\x12\r\n\tDELIMITED\x10\x02\"H\n\nJsonFormat\x12\x17\n\x13JSON_FORMAT_UNKNOWN\x10\x00\x12\t\n\x05\x41LLOW\x10\x01\x12\x16\n\x12LEGACY_BEST_EFFORT\x10\x02\"f\n\x12\x45nforceNamingStyle\x12 \n\x1c\x45NFORCE_NAMING_STYLE_UNKNOWN\x10\x00\x12\r\n\tSTYLE2024\x10\x01\x12\x10\n\x0cSTYLE_LEGACY\x10\x02\x12\r\n\tSTYLE2026\x10\x03*\x06\x08\xe8\x07\x10\x8bN*\x06\x08\x8bN\x10\x90N*\x06\x08\x90N\x10\x91NJ\x06\x08\xe7\x07\x10\xe8\x07\"\xef\x03\n\x12\x46\x65\x61tureSetDefaults\x12X\n\x08\x64\x65\x66\x61ults\x18\x01 \x03(\x0b\x32<.google.protobuf.FeatureSetDefaults.FeatureSetEditionDefaultR\x08\x64\x65\x66\x61ults\x12\x41\n\x0fminimum_edition\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0eminimumEdition\x12\x41\n\x0fmaximum_edition\x18\x05 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0emaximumEdition\x1a\xf8\x01\n\x18\x46\x65\x61tureSetEditionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12N\n\x14overridable_features\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x13overridableFeatures\x12\x42\n\x0e\x66ixed_features\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\rfixedFeaturesJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03R\x08\x66\x65\x61tures\"\xb5\x02\n\x0eSourceCodeInfo\x12\x44\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.LocationR\x08location\x1a\xce\x01\n\x08Location\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x16\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01R\x04span\x12)\n\x10leading_comments\x18\x03 \x01(\tR\x0fleadingComments\x12+\n\x11trailing_comments\x18\x04 \x01(\tR\x10trailingComments\x12:\n\x19leading_detached_comments\x18\x06 \x03(\tR\x17leadingDetachedComments*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xd0\x02\n\x11GeneratedCodeInfo\x12M\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.AnnotationR\nannotation\x1a\xeb\x01\n\nAnnotation\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x1f\n\x0bsource_file\x18\x02 \x01(\tR\nsourceFile\x12\x14\n\x05\x62\x65gin\x18\x03 \x01(\x05R\x05\x62\x65gin\x12\x10\n\x03\x65nd\x18\x04 \x01(\x05R\x03\x65nd\x12R\n\x08semantic\x18\x05 \x01(\x0e\x32\x36.google.protobuf.GeneratedCodeInfo.Annotation.SemanticR\x08semantic\"(\n\x08Semantic\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03SET\x10\x01\x12\t\n\x05\x41LIAS\x10\x02*\xd1\x02\n\x07\x45\x64ition\x12\x13\n\x0f\x45\x44ITION_UNKNOWN\x10\x00\x12\x13\n\x0e\x45\x44ITION_LEGACY\x10\x84\x07\x12\x13\n\x0e\x45\x44ITION_PROTO2\x10\xe6\x07\x12\x13\n\x0e\x45\x44ITION_PROTO3\x10\xe7\x07\x12\x11\n\x0c\x45\x44ITION_2023\x10\xe8\x07\x12\x11\n\x0c\x45\x44ITION_2024\x10\xe9\x07\x12\x11\n\x0c\x45\x44ITION_2026\x10\xea\x07\x12\x15\n\x10\x45\x44ITION_UNSTABLE\x10\x8fN\x12\x17\n\x13\x45\x44ITION_1_TEST_ONLY\x10\x01\x12\x17\n\x13\x45\x44ITION_2_TEST_ONLY\x10\x02\x12\x1d\n\x17\x45\x44ITION_99997_TEST_ONLY\x10\x9d\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99998_TEST_ONLY\x10\x9e\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99999_TEST_ONLY\x10\x9f\x8d\x06\x12\x13\n\x0b\x45\x44ITION_MAX\x10\xff\xff\xff\xff\x07*U\n\x10SymbolVisibility\x12\x14\n\x10VISIBILITY_UNSET\x10\x00\x12\x14\n\x10VISIBILITY_LOCAL\x10\x01\x12\x15\n\x11VISIBILITY_EXPORT\x10\x02\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection') + +_globals = globals() +if not _descriptor._USE_C_DESCRIPTORS: + _EDITION = _descriptor.EnumDescriptor( + name='Edition', + full_name='google.protobuf.Edition', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='EDITION_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_LEGACY', index=1, number=900, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_PROTO2', index=2, number=998, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_PROTO3', index=3, number=999, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_2023', index=4, number=1000, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_2024', index=5, number=1001, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_2026', index=6, number=1002, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_UNSTABLE', index=7, number=9999, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_1_TEST_ONLY', index=8, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_2_TEST_ONLY', index=9, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_99997_TEST_ONLY', index=10, number=99997, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_99998_TEST_ONLY', index=11, number=99998, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_99999_TEST_ONLY', index=12, number=99999, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EDITION_MAX', index=13, number=2147483647, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_EDITION) + + _SYMBOLVISIBILITY = _descriptor.EnumDescriptor( + name='SymbolVisibility', + full_name='google.protobuf.SymbolVisibility', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='VISIBILITY_UNSET', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='VISIBILITY_LOCAL', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='VISIBILITY_EXPORT', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_SYMBOLVISIBILITY) + + _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE = _descriptor.EnumDescriptor( + name='VerificationState', + full_name='google.protobuf.ExtensionRangeOptions.VerificationState', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='DECLARATION', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='UNVERIFIED', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE) + + _FIELDDESCRIPTORPROTO_TYPE = _descriptor.EnumDescriptor( + name='Type', + full_name='google.protobuf.FieldDescriptorProto.Type', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='TYPE_DOUBLE', index=0, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_FLOAT', index=1, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_INT64', index=2, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_UINT64', index=3, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_INT32', index=4, number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_FIXED64', index=5, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_FIXED32', index=6, number=7, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_BOOL', index=7, number=8, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_STRING', index=8, number=9, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_GROUP', index=9, number=10, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_MESSAGE', index=10, number=11, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_BYTES', index=11, number=12, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_UINT32', index=12, number=13, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_ENUM', index=13, number=14, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_SFIXED32', index=14, number=15, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_SFIXED64', index=15, number=16, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_SINT32', index=16, number=17, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TYPE_SINT64', index=17, number=18, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_TYPE) + + _FIELDDESCRIPTORPROTO_LABEL = _descriptor.EnumDescriptor( + name='Label', + full_name='google.protobuf.FieldDescriptorProto.Label', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='LABEL_OPTIONAL', index=0, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LABEL_REPEATED', index=1, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LABEL_REQUIRED', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_LABEL) + + _FILEOPTIONS_OPTIMIZEMODE = _descriptor.EnumDescriptor( + name='OptimizeMode', + full_name='google.protobuf.FileOptions.OptimizeMode', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='SPEED', index=0, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CODE_SIZE', index=1, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LITE_RUNTIME', index=2, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FILEOPTIONS_OPTIMIZEMODE) + + _FIELDOPTIONS_CTYPE = _descriptor.EnumDescriptor( + name='CType', + full_name='google.protobuf.FieldOptions.CType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='STRING', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CORD', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='STRING_PIECE', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_CTYPE) + + _FIELDOPTIONS_JSTYPE = _descriptor.EnumDescriptor( + name='JSType', + full_name='google.protobuf.FieldOptions.JSType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='JS_NORMAL', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='JS_STRING', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='JS_NUMBER', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_JSTYPE) + + _FIELDOPTIONS_OPTIONRETENTION = _descriptor.EnumDescriptor( + name='OptionRetention', + full_name='google.protobuf.FieldOptions.OptionRetention', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='RETENTION_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RETENTION_RUNTIME', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='RETENTION_SOURCE', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_OPTIONRETENTION) + + _FIELDOPTIONS_OPTIONTARGETTYPE = _descriptor.EnumDescriptor( + name='OptionTargetType', + full_name='google.protobuf.FieldOptions.OptionTargetType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_FILE', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_EXTENSION_RANGE', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_MESSAGE', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_FIELD', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_ONEOF', index=5, number=5, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_ENUM', index=6, number=6, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_ENUM_ENTRY', index=7, number=7, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_SERVICE', index=8, number=8, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='TARGET_TYPE_METHOD', index=9, number=9, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_OPTIONTARGETTYPE) + + _METHODOPTIONS_IDEMPOTENCYLEVEL = _descriptor.EnumDescriptor( + name='IdempotencyLevel', + full_name='google.protobuf.MethodOptions.IdempotencyLevel', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='IDEMPOTENCY_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='NO_SIDE_EFFECTS', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='IDEMPOTENT', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_IDEMPOTENCYLEVEL) + + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY = _descriptor.EnumDescriptor( + name='DefaultSymbolVisibility', + full_name='google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='DEFAULT_SYMBOL_VISIBILITY_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EXPORT_ALL', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EXPORT_TOP_LEVEL', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LOCAL_ALL', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='STRICT', index=4, number=4, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY) + + _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS = _descriptor.EnumDescriptor( + name='EnforceProtoLimits', + full_name='google.protobuf.FeatureSet.ProtoLimitsFeature.EnforceProtoLimits', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='PROTO_LIMITS_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LEGACY_NO_EXPLICIT_LIMITS', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PROTO_LIMITS2026', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS) + + _FEATURESET_FIELDPRESENCE = _descriptor.EnumDescriptor( + name='FieldPresence', + full_name='google.protobuf.FeatureSet.FieldPresence', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='FIELD_PRESENCE_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EXPLICIT', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='IMPLICIT', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LEGACY_REQUIRED', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_FIELDPRESENCE) + + _FEATURESET_ENUMTYPE = _descriptor.EnumDescriptor( + name='EnumType', + full_name='google.protobuf.FeatureSet.EnumType', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='ENUM_TYPE_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='OPEN', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='CLOSED', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_ENUMTYPE) + + _FEATURESET_REPEATEDFIELDENCODING = _descriptor.EnumDescriptor( + name='RepeatedFieldEncoding', + full_name='google.protobuf.FeatureSet.RepeatedFieldEncoding', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='REPEATED_FIELD_ENCODING_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='PACKED', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='EXPANDED', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_REPEATEDFIELDENCODING) + + _FEATURESET_UTF8VALIDATION = _descriptor.EnumDescriptor( + name='Utf8Validation', + full_name='google.protobuf.FeatureSet.Utf8Validation', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='UTF8_VALIDATION_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='VERIFY', index=1, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='NONE', index=2, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_UTF8VALIDATION) + + _FEATURESET_MESSAGEENCODING = _descriptor.EnumDescriptor( + name='MessageEncoding', + full_name='google.protobuf.FeatureSet.MessageEncoding', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='MESSAGE_ENCODING_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LENGTH_PREFIXED', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='DELIMITED', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_MESSAGEENCODING) + + _FEATURESET_JSONFORMAT = _descriptor.EnumDescriptor( + name='JsonFormat', + full_name='google.protobuf.FeatureSet.JsonFormat', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='JSON_FORMAT_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ALLOW', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='LEGACY_BEST_EFFORT', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_JSONFORMAT) + + _FEATURESET_ENFORCENAMINGSTYLE = _descriptor.EnumDescriptor( + name='EnforceNamingStyle', + full_name='google.protobuf.FeatureSet.EnforceNamingStyle', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='ENFORCE_NAMING_STYLE_UNKNOWN', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='STYLE2024', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='STYLE_LEGACY', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='STYLE2026', index=3, number=3, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_FEATURESET_ENFORCENAMINGSTYLE) + + _GENERATEDCODEINFO_ANNOTATION_SEMANTIC = _descriptor.EnumDescriptor( + name='Semantic', + full_name='google.protobuf.GeneratedCodeInfo.Annotation.Semantic', + filename=None, + file=DESCRIPTOR, + create_key=_descriptor._internal_create_key, + values=[ + _descriptor.EnumValueDescriptor( + name='NONE', index=0, number=0, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='SET', index=1, number=1, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + _descriptor.EnumValueDescriptor( + name='ALIAS', index=2, number=2, + serialized_options=None, + type=None, + create_key=_descriptor._internal_create_key), + ], + containing_type=None, + serialized_options=None, + ) + _sym_db.RegisterEnumDescriptor(_GENERATEDCODEINFO_ANNOTATION_SEMANTIC) + + + _FILEDESCRIPTORSET = _descriptor.Descriptor( + name='FileDescriptorSet', + full_name='google.protobuf.FileDescriptorSet', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='file', full_name='google.protobuf.FileDescriptorSet.file', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='file', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(536000000, 536000001), ], + oneofs=[ + ], + ) + + + _FILEDESCRIPTORPROTO = _descriptor.Descriptor( + name='FileDescriptorProto', + full_name='google.protobuf.FileDescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.FileDescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='package', full_name='google.protobuf.FileDescriptorProto.package', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='package', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='dependency', full_name='google.protobuf.FileDescriptorProto.dependency', index=2, + number=3, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='dependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='public_dependency', full_name='google.protobuf.FileDescriptorProto.public_dependency', index=3, + number=10, type=5, cpp_type=1, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='publicDependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='weak_dependency', full_name='google.protobuf.FileDescriptorProto.weak_dependency', index=4, + number=11, type=5, cpp_type=1, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='weakDependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='option_dependency', full_name='google.protobuf.FileDescriptorProto.option_dependency', index=5, + number=15, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='optionDependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_type', full_name='google.protobuf.FileDescriptorProto.message_type', index=6, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='messageType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='enum_type', full_name='google.protobuf.FileDescriptorProto.enum_type', index=7, + number=5, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='enumType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='service', full_name='google.protobuf.FileDescriptorProto.service', index=8, + number=6, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='service', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='extension', full_name='google.protobuf.FileDescriptorProto.extension', index=9, + number=7, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='extension', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.FileDescriptorProto.options', index=10, + number=8, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='source_code_info', full_name='google.protobuf.FileDescriptorProto.source_code_info', index=11, + number=9, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='sourceCodeInfo', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='syntax', full_name='google.protobuf.FileDescriptorProto.syntax', index=12, + number=12, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='syntax', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='edition', full_name='google.protobuf.FileDescriptorProto.edition', index=13, + number=14, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='edition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _DESCRIPTORPROTO_EXTENSIONRANGE = _descriptor.Descriptor( + name='ExtensionRange', + full_name='google.protobuf.DescriptorProto.ExtensionRange', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='start', full_name='google.protobuf.DescriptorProto.ExtensionRange.start', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='start', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='end', full_name='google.protobuf.DescriptorProto.ExtensionRange.end', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.DescriptorProto.ExtensionRange.options', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _DESCRIPTORPROTO_RESERVEDRANGE = _descriptor.Descriptor( + name='ReservedRange', + full_name='google.protobuf.DescriptorProto.ReservedRange', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='start', full_name='google.protobuf.DescriptorProto.ReservedRange.start', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='start', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='end', full_name='google.protobuf.DescriptorProto.ReservedRange.end', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _DESCRIPTORPROTO = _descriptor.Descriptor( + name='DescriptorProto', + full_name='google.protobuf.DescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.DescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='field', full_name='google.protobuf.DescriptorProto.field', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='field', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='extension', full_name='google.protobuf.DescriptorProto.extension', index=2, + number=6, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='extension', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='nested_type', full_name='google.protobuf.DescriptorProto.nested_type', index=3, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='nestedType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='enum_type', full_name='google.protobuf.DescriptorProto.enum_type', index=4, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='enumType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='extension_range', full_name='google.protobuf.DescriptorProto.extension_range', index=5, + number=5, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='extensionRange', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='oneof_decl', full_name='google.protobuf.DescriptorProto.oneof_decl', index=6, + number=8, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='oneofDecl', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.DescriptorProto.options', index=7, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reserved_range', full_name='google.protobuf.DescriptorProto.reserved_range', index=8, + number=9, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='reservedRange', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reserved_name', full_name='google.protobuf.DescriptorProto.reserved_name', index=9, + number=10, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='reservedName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='visibility', full_name='google.protobuf.DescriptorProto.visibility', index=10, + number=11, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='visibility', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, _DESCRIPTORPROTO_RESERVEDRANGE, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _EXTENSIONRANGEOPTIONS_DECLARATION = _descriptor.Descriptor( + name='Declaration', + full_name='google.protobuf.ExtensionRangeOptions.Declaration', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='number', full_name='google.protobuf.ExtensionRangeOptions.Declaration.number', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='number', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='full_name', full_name='google.protobuf.ExtensionRangeOptions.Declaration.full_name', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='fullName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='type', full_name='google.protobuf.ExtensionRangeOptions.Declaration.type', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='type', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reserved', full_name='google.protobuf.ExtensionRangeOptions.Declaration.reserved', index=3, + number=5, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='reserved', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='repeated', full_name='google.protobuf.ExtensionRangeOptions.Declaration.repeated', index=4, + number=6, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='repeated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _EXTENSIONRANGEOPTIONS = _descriptor.Descriptor( + name='ExtensionRangeOptions', + full_name='google.protobuf.ExtensionRangeOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.ExtensionRangeOptions.uninterpreted_option', index=0, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='declaration', full_name='google.protobuf.ExtensionRangeOptions.declaration', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\002', json_name='declaration', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.ExtensionRangeOptions.features', index=2, + number=50, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='verification', full_name='google.protobuf.ExtensionRangeOptions.verification', index=3, + number=3, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=1, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\002', json_name='verification', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_EXTENSIONRANGEOPTIONS_DECLARATION, ], + enum_types=[ + _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE, + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _FIELDDESCRIPTORPROTO = _descriptor.Descriptor( + name='FieldDescriptorProto', + full_name='google.protobuf.FieldDescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.FieldDescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='number', full_name='google.protobuf.FieldDescriptorProto.number', index=1, + number=3, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='number', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='label', full_name='google.protobuf.FieldDescriptorProto.label', index=2, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=1, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='label', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='type', full_name='google.protobuf.FieldDescriptorProto.type', index=3, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=1, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='type', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='type_name', full_name='google.protobuf.FieldDescriptorProto.type_name', index=4, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='typeName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='extendee', full_name='google.protobuf.FieldDescriptorProto.extendee', index=5, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='extendee', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='default_value', full_name='google.protobuf.FieldDescriptorProto.default_value', index=6, + number=7, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='defaultValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='oneof_index', full_name='google.protobuf.FieldDescriptorProto.oneof_index', index=7, + number=9, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='oneofIndex', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='json_name', full_name='google.protobuf.FieldDescriptorProto.json_name', index=8, + number=10, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='jsonName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=9, + number=8, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='proto3_optional', full_name='google.protobuf.FieldDescriptorProto.proto3_optional', index=10, + number=17, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='proto3Optional', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _FIELDDESCRIPTORPROTO_TYPE, + _FIELDDESCRIPTORPROTO_LABEL, + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _ONEOFDESCRIPTORPROTO = _descriptor.Descriptor( + name='OneofDescriptorProto', + full_name='google.protobuf.OneofDescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.OneofDescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.OneofDescriptorProto.options', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE = _descriptor.Descriptor( + name='EnumReservedRange', + full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='start', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.start', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='start', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='end', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.end', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _ENUMDESCRIPTORPROTO = _descriptor.Descriptor( + name='EnumDescriptorProto', + full_name='google.protobuf.EnumDescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.EnumDescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='value', full_name='google.protobuf.EnumDescriptorProto.value', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='value', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.EnumDescriptorProto.options', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reserved_range', full_name='google.protobuf.EnumDescriptorProto.reserved_range', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='reservedRange', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='reserved_name', full_name='google.protobuf.EnumDescriptorProto.reserved_name', index=4, + number=5, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='reservedName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='visibility', full_name='google.protobuf.EnumDescriptorProto.visibility', index=5, + number=6, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='visibility', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _ENUMVALUEDESCRIPTORPROTO = _descriptor.Descriptor( + name='EnumValueDescriptorProto', + full_name='google.protobuf.EnumValueDescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.EnumValueDescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='number', full_name='google.protobuf.EnumValueDescriptorProto.number', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='number', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.EnumValueDescriptorProto.options', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _SERVICEDESCRIPTORPROTO = _descriptor.Descriptor( + name='ServiceDescriptorProto', + full_name='google.protobuf.ServiceDescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.ServiceDescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='method', full_name='google.protobuf.ServiceDescriptorProto.method', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='method', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.ServiceDescriptorProto.options', index=2, + number=3, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _METHODDESCRIPTORPROTO = _descriptor.Descriptor( + name='MethodDescriptorProto', + full_name='google.protobuf.MethodDescriptorProto', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.MethodDescriptorProto.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='input_type', full_name='google.protobuf.MethodDescriptorProto.input_type', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='inputType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='output_type', full_name='google.protobuf.MethodDescriptorProto.output_type', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='outputType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='options', full_name='google.protobuf.MethodDescriptorProto.options', index=3, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='client_streaming', full_name='google.protobuf.MethodDescriptorProto.client_streaming', index=4, + number=5, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='clientStreaming', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='server_streaming', full_name='google.protobuf.MethodDescriptorProto.server_streaming', index=5, + number=6, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='serverStreaming', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _FILEOPTIONS = _descriptor.Descriptor( + name='FileOptions', + full_name='google.protobuf.FileOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='java_package', full_name='google.protobuf.FileOptions.java_package', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='javaPackage', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='java_outer_classname', full_name='google.protobuf.FileOptions.java_outer_classname', index=1, + number=8, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='javaOuterClassname', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='java_multiple_files', full_name='google.protobuf.FileOptions.java_multiple_files', index=2, + number=10, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\262\001\275\001\010\346\007 \351\007*\264\001This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.', json_name='javaMultipleFiles', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='java_generate_equals_and_hash', full_name='google.protobuf.FileOptions.java_generate_equals_and_hash', index=3, + number=20, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\030\001', json_name='javaGenerateEqualsAndHash', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='java_string_check_utf8', full_name='google.protobuf.FileOptions.java_string_check_utf8', index=4, + number=27, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='javaStringCheckUtf8', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=5, + number=9, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=1, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='optimizeFor', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='go_package', full_name='google.protobuf.FileOptions.go_package', index=6, + number=11, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='goPackage', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=7, + number=16, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='ccGenericServices', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=8, + number=17, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='javaGenericServices', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=9, + number=18, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='pyGenericServices', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecated', full_name='google.protobuf.FileOptions.deprecated', index=10, + number=23, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='cc_enable_arenas', full_name='google.protobuf.FileOptions.cc_enable_arenas', index=11, + number=31, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=True, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\262\001\212\001 \352\007*\204\001cc_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.', json_name='ccEnableArenas', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='objc_class_prefix', full_name='google.protobuf.FileOptions.objc_class_prefix', index=12, + number=36, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='objcClassPrefix', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='csharp_namespace', full_name='google.protobuf.FileOptions.csharp_namespace', index=13, + number=37, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='csharpNamespace', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='swift_prefix', full_name='google.protobuf.FileOptions.swift_prefix', index=14, + number=39, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='swiftPrefix', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='php_class_prefix', full_name='google.protobuf.FileOptions.php_class_prefix', index=15, + number=40, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='phpClassPrefix', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='php_namespace', full_name='google.protobuf.FileOptions.php_namespace', index=16, + number=41, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='phpNamespace', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='php_metadata_namespace', full_name='google.protobuf.FileOptions.php_metadata_namespace', index=17, + number=44, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='phpMetadataNamespace', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='ruby_package', full_name='google.protobuf.FileOptions.ruby_package', index=18, + number=45, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='rubyPackage', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.FileOptions.features', index=19, + number=50, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=20, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _FILEOPTIONS_OPTIMIZEMODE, + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _MESSAGEOPTIONS = _descriptor.Descriptor( + name='MessageOptions', + full_name='google.protobuf.MessageOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='message_set_wire_format', full_name='google.protobuf.MessageOptions.message_set_wire_format', index=0, + number=1, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='messageSetWireFormat', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='no_standard_descriptor_accessor', full_name='google.protobuf.MessageOptions.no_standard_descriptor_accessor', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='noStandardDescriptorAccessor', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecated', full_name='google.protobuf.MessageOptions.deprecated', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='map_entry', full_name='google.protobuf.MessageOptions.map_entry', index=3, + number=7, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='mapEntry', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecated_legacy_json_field_conflicts', full_name='google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts', index=4, + number=11, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\030\001', json_name='deprecatedLegacyJsonFieldConflicts', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.MessageOptions.features', index=5, + number=12, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=6, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _FIELDOPTIONS_EDITIONDEFAULT = _descriptor.Descriptor( + name='EditionDefault', + full_name='google.protobuf.FieldOptions.EditionDefault', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='edition', full_name='google.protobuf.FieldOptions.EditionDefault.edition', index=0, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='edition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='value', full_name='google.protobuf.FieldOptions.EditionDefault.value', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='value', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _FIELDOPTIONS_FEATURESUPPORT = _descriptor.Descriptor( + name='FeatureSupport', + full_name='google.protobuf.FieldOptions.FeatureSupport', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='edition_introduced', full_name='google.protobuf.FieldOptions.FeatureSupport.edition_introduced', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='editionIntroduced', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='edition_deprecated', full_name='google.protobuf.FieldOptions.FeatureSupport.edition_deprecated', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='editionDeprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecation_warning', full_name='google.protobuf.FieldOptions.FeatureSupport.deprecation_warning', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecationWarning', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='edition_removed', full_name='google.protobuf.FieldOptions.FeatureSupport.edition_removed', index=3, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='editionRemoved', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='removal_error', full_name='google.protobuf.FieldOptions.FeatureSupport.removal_error', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='removalError', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _FIELDOPTIONS = _descriptor.Descriptor( + name='FieldOptions', + full_name='google.protobuf.FieldOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='ctype', full_name='google.protobuf.FieldOptions.ctype', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='ctype', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='packed', full_name='google.protobuf.FieldOptions.packed', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='packed', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='jstype', full_name='google.protobuf.FieldOptions.jstype', index=2, + number=6, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='jstype', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='lazy', full_name='google.protobuf.FieldOptions.lazy', index=3, + number=5, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='lazy', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='unverified_lazy', full_name='google.protobuf.FieldOptions.unverified_lazy', index=4, + number=15, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='unverifiedLazy', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=5, + number=3, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='weak', full_name='google.protobuf.FieldOptions.weak', index=6, + number=10, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\030\001', json_name='weak', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='debug_redact', full_name='google.protobuf.FieldOptions.debug_redact', index=7, + number=16, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='debugRedact', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='retention', full_name='google.protobuf.FieldOptions.retention', index=8, + number=17, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='retention', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='targets', full_name='google.protobuf.FieldOptions.targets', index=9, + number=19, type=14, cpp_type=8, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='targets', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='edition_defaults', full_name='google.protobuf.FieldOptions.edition_defaults', index=10, + number=20, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='editionDefaults', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.FieldOptions.features', index=11, + number=21, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='feature_support', full_name='google.protobuf.FieldOptions.feature_support', index=12, + number=22, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='featureSupport', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.FieldOptions.uninterpreted_option', index=13, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_FIELDOPTIONS_EDITIONDEFAULT, _FIELDOPTIONS_FEATURESUPPORT, ], + enum_types=[ + _FIELDOPTIONS_CTYPE, + _FIELDOPTIONS_JSTYPE, + _FIELDOPTIONS_OPTIONRETENTION, + _FIELDOPTIONS_OPTIONTARGETTYPE, + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _ONEOFOPTIONS = _descriptor.Descriptor( + name='OneofOptions', + full_name='google.protobuf.OneofOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.OneofOptions.features', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.OneofOptions.uninterpreted_option', index=1, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _ENUMOPTIONS = _descriptor.Descriptor( + name='EnumOptions', + full_name='google.protobuf.EnumOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='allow_alias', full_name='google.protobuf.EnumOptions.allow_alias', index=0, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='allowAlias', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecated', full_name='google.protobuf.EnumOptions.deprecated', index=1, + number=3, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecated_legacy_json_field_conflicts', full_name='google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts', index=2, + number=6, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\030\001', json_name='deprecatedLegacyJsonFieldConflicts', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.EnumOptions.features', index=3, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=4, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _ENUMVALUEOPTIONS = _descriptor.Descriptor( + name='EnumValueOptions', + full_name='google.protobuf.EnumValueOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='deprecated', full_name='google.protobuf.EnumValueOptions.deprecated', index=0, + number=1, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.EnumValueOptions.features', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='debug_redact', full_name='google.protobuf.EnumValueOptions.debug_redact', index=2, + number=3, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='debugRedact', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='feature_support', full_name='google.protobuf.EnumValueOptions.feature_support', index=3, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='featureSupport', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=4, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _SERVICEOPTIONS = _descriptor.Descriptor( + name='ServiceOptions', + full_name='google.protobuf.ServiceOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.ServiceOptions.features', index=0, + number=34, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='deprecated', full_name='google.protobuf.ServiceOptions.deprecated', index=1, + number=33, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=2, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _METHODOPTIONS = _descriptor.Descriptor( + name='MethodOptions', + full_name='google.protobuf.MethodOptions', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='deprecated', full_name='google.protobuf.MethodOptions.deprecated', index=0, + number=33, type=8, cpp_type=7, label=1, + has_default_value=True, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='idempotency_level', full_name='google.protobuf.MethodOptions.idempotency_level', index=1, + number=34, type=14, cpp_type=8, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='idempotencyLevel', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='features', full_name='google.protobuf.MethodOptions.features', index=2, + number=35, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=3, + number=999, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _METHODOPTIONS_IDEMPOTENCYLEVEL, + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(990, 999), (1000, 536870912), ], + oneofs=[ + ], + ) + + + _UNINTERPRETEDOPTION_NAMEPART = _descriptor.Descriptor( + name='NamePart', + full_name='google.protobuf.UninterpretedOption.NamePart', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name_part', full_name='google.protobuf.UninterpretedOption.NamePart.name_part', index=0, + number=1, type=9, cpp_type=9, label=2, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='namePart', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='is_extension', full_name='google.protobuf.UninterpretedOption.NamePart.is_extension', index=1, + number=2, type=8, cpp_type=7, label=2, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='isExtension', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _UNINTERPRETEDOPTION = _descriptor.Descriptor( + name='UninterpretedOption', + full_name='google.protobuf.UninterpretedOption', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='google.protobuf.UninterpretedOption.name', index=0, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='identifier_value', full_name='google.protobuf.UninterpretedOption.identifier_value', index=1, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='identifierValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='positive_int_value', full_name='google.protobuf.UninterpretedOption.positive_int_value', index=2, + number=4, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='positiveIntValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='negative_int_value', full_name='google.protobuf.UninterpretedOption.negative_int_value', index=3, + number=5, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='negativeIntValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='double_value', full_name='google.protobuf.UninterpretedOption.double_value', index=4, + number=6, type=1, cpp_type=5, label=1, + has_default_value=False, default_value=float(0), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='doubleValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='string_value', full_name='google.protobuf.UninterpretedOption.string_value', index=5, + number=7, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=b"", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='stringValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='aggregate_value', full_name='google.protobuf.UninterpretedOption.aggregate_value', index=6, + number=8, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='aggregateValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_UNINTERPRETEDOPTION_NAMEPART, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _FEATURESET_VISIBILITYFEATURE = _descriptor.Descriptor( + name='VisibilityFeature', + full_name='google.protobuf.FeatureSet.VisibilityFeature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY, + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _FEATURESET_PROTOLIMITSFEATURE = _descriptor.Descriptor( + name='ProtoLimitsFeature', + full_name='google.protobuf.FeatureSet.ProtoLimitsFeature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS, + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _FEATURESET = _descriptor.Descriptor( + name='FeatureSet', + full_name='google.protobuf.FeatureSet', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='field_presence', full_name='google.protobuf.FeatureSet.field_presence', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPLICIT\030\204\007\242\001\r\022\010IMPLICIT\030\347\007\242\001\r\022\010EXPLICIT\030\350\007\262\001\003\010\350\007', json_name='fieldPresence', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='enum_type', full_name='google.protobuf.FeatureSet.enum_type', index=1, + number=2, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\001\230\001\006\230\001\001\242\001\013\022\006CLOSED\030\204\007\242\001\t\022\004OPEN\030\347\007\262\001\003\010\350\007', json_name='enumType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='repeated_field_encoding', full_name='google.protobuf.FeatureSet.repeated_field_encoding', index=2, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPANDED\030\204\007\242\001\013\022\006PACKED\030\347\007\262\001\003\010\350\007', json_name='repeatedFieldEncoding', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='utf8_validation', full_name='google.protobuf.FeatureSet.utf8_validation', index=3, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\t\022\004NONE\030\204\007\242\001\013\022\006VERIFY\030\347\007\262\001\003\010\350\007', json_name='utf8Validation', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='message_encoding', full_name='google.protobuf.FeatureSet.message_encoding', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\024\022\017LENGTH_PREFIXED\030\204\007\262\001\003\010\350\007', json_name='messageEncoding', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='json_format', full_name='google.protobuf.FeatureSet.json_format', index=5, + number=6, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\001\230\001\003\230\001\006\230\001\001\242\001\027\022\022LEGACY_BEST_EFFORT\030\204\007\242\001\n\022\005ALLOW\030\347\007\262\001\003\010\350\007', json_name='jsonFormat', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='enforce_naming_style', full_name='google.protobuf.FeatureSet.enforce_naming_style', index=6, + number=7, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\002\230\001\001\230\001\002\230\001\003\230\001\004\230\001\005\230\001\006\230\001\007\230\001\010\230\001\t\242\001\021\022\014STYLE_LEGACY\030\204\007\242\001\016\022\tSTYLE2024\030\351\007\242\001\016\022\tSTYLE2026\030\352\007\262\001\003\010\351\007', json_name='enforceNamingStyle', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='default_symbol_visibility', full_name='google.protobuf.FeatureSet.default_symbol_visibility', index=7, + number=8, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\002\230\001\001\242\001\017\022\nEXPORT_ALL\030\204\007\242\001\025\022\020EXPORT_TOP_LEVEL\030\351\007\242\001\013\022\006STRICT\030\352\007\262\001\003\010\351\007', json_name='defaultSymbolVisibility', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='enforce_proto_limits', full_name='google.protobuf.FeatureSet.enforce_proto_limits', index=8, + number=9, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\210\001\002\230\001\006\230\001\003\230\001\004\230\001\005\242\001\036\022\031LEGACY_NO_EXPLICIT_LIMITS\030\204\007\242\001\025\022\020PROTO_LIMITS2026\030\352\007\262\001\003\010\352\007', json_name='enforceProtoLimits', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_FEATURESET_VISIBILITYFEATURE, _FEATURESET_PROTOLIMITSFEATURE, ], + enum_types=[ + _FEATURESET_FIELDPRESENCE, + _FEATURESET_ENUMTYPE, + _FEATURESET_REPEATEDFIELDENCODING, + _FEATURESET_UTF8VALIDATION, + _FEATURESET_MESSAGEENCODING, + _FEATURESET_JSONFORMAT, + _FEATURESET_ENFORCENAMINGSTYLE, + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(1000, 9995), (9995, 10000), (10000, 10001), ], + oneofs=[ + ], + ) + + + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT = _descriptor.Descriptor( + name='FeatureSetEditionDefault', + full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='edition', full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition', index=0, + number=3, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='edition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='overridable_features', full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features', index=1, + number=4, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='overridableFeatures', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='fixed_features', full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features', index=2, + number=5, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='fixedFeatures', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _FEATURESETDEFAULTS = _descriptor.Descriptor( + name='FeatureSetDefaults', + full_name='google.protobuf.FeatureSetDefaults', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='defaults', full_name='google.protobuf.FeatureSetDefaults.defaults', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='defaults', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='minimum_edition', full_name='google.protobuf.FeatureSetDefaults.minimum_edition', index=1, + number=4, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='minimumEdition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='maximum_edition', full_name='google.protobuf.FeatureSetDefaults.maximum_edition', index=2, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='maximumEdition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + + _SOURCECODEINFO_LOCATION = _descriptor.Descriptor( + name='Location', + full_name='google.protobuf.SourceCodeInfo.Location', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='path', full_name='google.protobuf.SourceCodeInfo.Location.path', index=0, + number=1, type=5, cpp_type=1, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\020\001', json_name='path', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='span', full_name='google.protobuf.SourceCodeInfo.Location.span', index=1, + number=2, type=5, cpp_type=1, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\020\001', json_name='span', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='leading_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_comments', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='leadingComments', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='trailing_comments', full_name='google.protobuf.SourceCodeInfo.Location.trailing_comments', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='trailingComments', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='leading_detached_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_detached_comments', index=4, + number=6, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='leadingDetachedComments', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _SOURCECODEINFO = _descriptor.Descriptor( + name='SourceCodeInfo', + full_name='google.protobuf.SourceCodeInfo', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='location', full_name='google.protobuf.SourceCodeInfo.location', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='location', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_SOURCECODEINFO_LOCATION, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=True, + extension_ranges=[(536000000, 536000001), ], + oneofs=[ + ], + ) + + + _GENERATEDCODEINFO_ANNOTATION = _descriptor.Descriptor( + name='Annotation', + full_name='google.protobuf.GeneratedCodeInfo.Annotation', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='path', full_name='google.protobuf.GeneratedCodeInfo.Annotation.path', index=0, + number=1, type=5, cpp_type=1, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=b'\020\001', json_name='path', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='source_file', full_name='google.protobuf.GeneratedCodeInfo.Annotation.source_file', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=b"".decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='sourceFile', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='begin', full_name='google.protobuf.GeneratedCodeInfo.Annotation.begin', index=2, + number=3, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='begin', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='end', full_name='google.protobuf.GeneratedCodeInfo.Annotation.end', index=3, + number=4, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='semantic', full_name='google.protobuf.GeneratedCodeInfo.Annotation.semantic', index=4, + number=5, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='semantic', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _GENERATEDCODEINFO_ANNOTATION_SEMANTIC, + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _GENERATEDCODEINFO = _descriptor.Descriptor( + name='GeneratedCodeInfo', + full_name='google.protobuf.GeneratedCodeInfo', + filename=None, + file=DESCRIPTOR, + containing_type=None, + create_key=_descriptor._internal_create_key, + fields=[ + _descriptor.FieldDescriptor( + name='annotation', full_name='google.protobuf.GeneratedCodeInfo.annotation', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, json_name='annotation', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + ], + extensions=[ + ], + nested_types=[_GENERATEDCODEINFO_ANNOTATION, ], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + ) + + _FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO + _FILEDESCRIPTORPROTO.fields_by_name['message_type'].message_type = _DESCRIPTORPROTO + _FILEDESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO + _FILEDESCRIPTORPROTO.fields_by_name['service'].message_type = _SERVICEDESCRIPTORPROTO + _FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO + _FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS + _FILEDESCRIPTORPROTO.fields_by_name['source_code_info'].message_type = _SOURCECODEINFO + _FILEDESCRIPTORPROTO.fields_by_name['edition'].enum_type = _EDITION + _DESCRIPTORPROTO_EXTENSIONRANGE.fields_by_name['options'].message_type = _EXTENSIONRANGEOPTIONS + _DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO + _DESCRIPTORPROTO_RESERVEDRANGE.containing_type = _DESCRIPTORPROTO + _DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO + _DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO + _DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO + _DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO + _DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE + _DESCRIPTORPROTO.fields_by_name['oneof_decl'].message_type = _ONEOFDESCRIPTORPROTO + _DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS + _DESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _DESCRIPTORPROTO_RESERVEDRANGE + _DESCRIPTORPROTO.fields_by_name['visibility'].enum_type = _SYMBOLVISIBILITY + _EXTENSIONRANGEOPTIONS_DECLARATION.containing_type = _EXTENSIONRANGEOPTIONS + _EXTENSIONRANGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _EXTENSIONRANGEOPTIONS.fields_by_name['declaration'].message_type = _EXTENSIONRANGEOPTIONS_DECLARATION + _EXTENSIONRANGEOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _EXTENSIONRANGEOPTIONS.fields_by_name['verification'].enum_type = _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE + _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE.containing_type = _EXTENSIONRANGEOPTIONS + _FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL + _FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE + _FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS + _FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO + _FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO + _ONEOFDESCRIPTORPROTO.fields_by_name['options'].message_type = _ONEOFOPTIONS + _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.containing_type = _ENUMDESCRIPTORPROTO + _ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO + _ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS + _ENUMDESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE + _ENUMDESCRIPTORPROTO.fields_by_name['visibility'].enum_type = _SYMBOLVISIBILITY + _ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS + _SERVICEDESCRIPTORPROTO.fields_by_name['method'].message_type = _METHODDESCRIPTORPROTO + _SERVICEDESCRIPTORPROTO.fields_by_name['options'].message_type = _SERVICEOPTIONS + _METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS + _FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE + _FILEOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS + _MESSAGEOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _FIELDOPTIONS_EDITIONDEFAULT.fields_by_name['edition'].enum_type = _EDITION + _FIELDOPTIONS_EDITIONDEFAULT.containing_type = _FIELDOPTIONS + _FIELDOPTIONS_FEATURESUPPORT.fields_by_name['edition_introduced'].enum_type = _EDITION + _FIELDOPTIONS_FEATURESUPPORT.fields_by_name['edition_deprecated'].enum_type = _EDITION + _FIELDOPTIONS_FEATURESUPPORT.fields_by_name['edition_removed'].enum_type = _EDITION + _FIELDOPTIONS_FEATURESUPPORT.containing_type = _FIELDOPTIONS + _FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE + _FIELDOPTIONS.fields_by_name['jstype'].enum_type = _FIELDOPTIONS_JSTYPE + _FIELDOPTIONS.fields_by_name['retention'].enum_type = _FIELDOPTIONS_OPTIONRETENTION + _FIELDOPTIONS.fields_by_name['targets'].enum_type = _FIELDOPTIONS_OPTIONTARGETTYPE + _FIELDOPTIONS.fields_by_name['edition_defaults'].message_type = _FIELDOPTIONS_EDITIONDEFAULT + _FIELDOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _FIELDOPTIONS.fields_by_name['feature_support'].message_type = _FIELDOPTIONS_FEATURESUPPORT + _FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS + _FIELDOPTIONS_JSTYPE.containing_type = _FIELDOPTIONS + _FIELDOPTIONS_OPTIONRETENTION.containing_type = _FIELDOPTIONS + _FIELDOPTIONS_OPTIONTARGETTYPE.containing_type = _FIELDOPTIONS + _ONEOFOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _ONEOFOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _ENUMOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _ENUMVALUEOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _ENUMVALUEOPTIONS.fields_by_name['feature_support'].message_type = _FIELDOPTIONS_FEATURESUPPORT + _ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _SERVICEOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _METHODOPTIONS.fields_by_name['idempotency_level'].enum_type = _METHODOPTIONS_IDEMPOTENCYLEVEL + _METHODOPTIONS.fields_by_name['features'].message_type = _FEATURESET + _METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION + _METHODOPTIONS_IDEMPOTENCYLEVEL.containing_type = _METHODOPTIONS + _UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION + _UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART + _FEATURESET_VISIBILITYFEATURE.containing_type = _FEATURESET + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.containing_type = _FEATURESET_VISIBILITYFEATURE + _FEATURESET_PROTOLIMITSFEATURE.containing_type = _FEATURESET + _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.containing_type = _FEATURESET_PROTOLIMITSFEATURE + _FEATURESET.fields_by_name['field_presence'].enum_type = _FEATURESET_FIELDPRESENCE + _FEATURESET.fields_by_name['enum_type'].enum_type = _FEATURESET_ENUMTYPE + _FEATURESET.fields_by_name['repeated_field_encoding'].enum_type = _FEATURESET_REPEATEDFIELDENCODING + _FEATURESET.fields_by_name['utf8_validation'].enum_type = _FEATURESET_UTF8VALIDATION + _FEATURESET.fields_by_name['message_encoding'].enum_type = _FEATURESET_MESSAGEENCODING + _FEATURESET.fields_by_name['json_format'].enum_type = _FEATURESET_JSONFORMAT + _FEATURESET.fields_by_name['enforce_naming_style'].enum_type = _FEATURESET_ENFORCENAMINGSTYLE + _FEATURESET.fields_by_name['default_symbol_visibility'].enum_type = _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY + _FEATURESET.fields_by_name['enforce_proto_limits'].enum_type = _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS + _FEATURESET_FIELDPRESENCE.containing_type = _FEATURESET + _FEATURESET_ENUMTYPE.containing_type = _FEATURESET + _FEATURESET_REPEATEDFIELDENCODING.containing_type = _FEATURESET + _FEATURESET_UTF8VALIDATION.containing_type = _FEATURESET + _FEATURESET_MESSAGEENCODING.containing_type = _FEATURESET + _FEATURESET_JSONFORMAT.containing_type = _FEATURESET + _FEATURESET_ENFORCENAMINGSTYLE.containing_type = _FEATURESET + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields_by_name['edition'].enum_type = _EDITION + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields_by_name['overridable_features'].message_type = _FEATURESET + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields_by_name['fixed_features'].message_type = _FEATURESET + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.containing_type = _FEATURESETDEFAULTS + _FEATURESETDEFAULTS.fields_by_name['defaults'].message_type = _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT + _FEATURESETDEFAULTS.fields_by_name['minimum_edition'].enum_type = _EDITION + _FEATURESETDEFAULTS.fields_by_name['maximum_edition'].enum_type = _EDITION + _SOURCECODEINFO_LOCATION.containing_type = _SOURCECODEINFO + _SOURCECODEINFO.fields_by_name['location'].message_type = _SOURCECODEINFO_LOCATION + _GENERATEDCODEINFO_ANNOTATION.fields_by_name['semantic'].enum_type = _GENERATEDCODEINFO_ANNOTATION_SEMANTIC + _GENERATEDCODEINFO_ANNOTATION.containing_type = _GENERATEDCODEINFO + _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.containing_type = _GENERATEDCODEINFO_ANNOTATION + _GENERATEDCODEINFO.fields_by_name['annotation'].message_type = _GENERATEDCODEINFO_ANNOTATION + DESCRIPTOR.message_types_by_name['FileDescriptorSet'] = _FILEDESCRIPTORSET + DESCRIPTOR.message_types_by_name['FileDescriptorProto'] = _FILEDESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['DescriptorProto'] = _DESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['ExtensionRangeOptions'] = _EXTENSIONRANGEOPTIONS + DESCRIPTOR.message_types_by_name['FieldDescriptorProto'] = _FIELDDESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['OneofDescriptorProto'] = _ONEOFDESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['EnumDescriptorProto'] = _ENUMDESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['EnumValueDescriptorProto'] = _ENUMVALUEDESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['ServiceDescriptorProto'] = _SERVICEDESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['MethodDescriptorProto'] = _METHODDESCRIPTORPROTO + DESCRIPTOR.message_types_by_name['FileOptions'] = _FILEOPTIONS + DESCRIPTOR.message_types_by_name['MessageOptions'] = _MESSAGEOPTIONS + DESCRIPTOR.message_types_by_name['FieldOptions'] = _FIELDOPTIONS + DESCRIPTOR.message_types_by_name['OneofOptions'] = _ONEOFOPTIONS + DESCRIPTOR.message_types_by_name['EnumOptions'] = _ENUMOPTIONS + DESCRIPTOR.message_types_by_name['EnumValueOptions'] = _ENUMVALUEOPTIONS + DESCRIPTOR.message_types_by_name['ServiceOptions'] = _SERVICEOPTIONS + DESCRIPTOR.message_types_by_name['MethodOptions'] = _METHODOPTIONS + DESCRIPTOR.message_types_by_name['UninterpretedOption'] = _UNINTERPRETEDOPTION + DESCRIPTOR.message_types_by_name['FeatureSet'] = _FEATURESET + DESCRIPTOR.message_types_by_name['FeatureSetDefaults'] = _FEATURESETDEFAULTS + DESCRIPTOR.message_types_by_name['SourceCodeInfo'] = _SOURCECODEINFO + DESCRIPTOR.message_types_by_name['GeneratedCodeInfo'] = _GENERATEDCODEINFO + DESCRIPTOR.enum_types_by_name['Edition'] = _EDITION + DESCRIPTOR.enum_types_by_name['SymbolVisibility'] = _SYMBOLVISIBILITY + _sym_db.RegisterFileDescriptor(DESCRIPTOR) + + class _ResolvedFeatures: + def __init__(self, features = None, **kwargs): + if features: + for k, v in features.FIELDS.items(): + setattr(self, k, getattr(features, k)) + else: + for k, v in kwargs.items(): + setattr(self, k, v) + DESCRIPTOR._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORSET._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORSET.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEDESCRIPTORPROTO.fields[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO_EXTENSIONRANGE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO_EXTENSIONRANGE.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO_EXTENSIONRANGE.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO_EXTENSIONRANGE.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO_RESERVEDRANGE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO_RESERVEDRANGE.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _DESCRIPTORPROTO_RESERVEDRANGE.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_DECLARATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_DECLARATION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_DECLARATION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_DECLARATION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_DECLARATION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_DECLARATION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ONEOFDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ONEOFDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ONEOFDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[14]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[15]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[16]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[17]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[18]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[19]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS.fields[20]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _MESSAGEOPTIONS.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS.fields[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_EDITIONDEFAULT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_EDITIONDEFAULT.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_EDITIONDEFAULT.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_FEATURESUPPORT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_FEATURESUPPORT.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_FEATURESUPPORT.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_FEATURESUPPORT.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_FEATURESUPPORT.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_FEATURESUPPORT.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ONEOFOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ONEOFOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ONEOFOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _ENUMVALUEOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SERVICEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION_NAMEPART._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION_NAMEPART.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["LEGACY_REQUIRED"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _UNINTERPRETEDOPTION_NAMEPART.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["LEGACY_REQUIRED"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_VISIBILITYFEATURE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_PROTOLIMITSFEATURE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO_LOCATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO_LOCATION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["PACKED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO_LOCATION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["PACKED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO_LOCATION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO_LOCATION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SOURCECODEINFO_LOCATION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["PACKED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[14]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[15]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[16]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_TYPE.values[17]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_LABEL._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_LABEL.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_LABEL.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDDESCRIPTORPROTO_LABEL.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS_OPTIMIZEMODE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS_OPTIMIZEMODE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS_OPTIMIZEMODE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FILEOPTIONS_OPTIMIZEMODE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_CTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_CTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_CTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_CTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_JSTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_JSTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_JSTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_JSTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONRETENTION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONRETENTION.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONRETENTION.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONRETENTION.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FIELDOPTIONS_OPTIONTARGETTYPE.values[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS_IDEMPOTENCYLEVEL._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS_IDEMPOTENCYLEVEL.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS_IDEMPOTENCYLEVEL.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _METHODOPTIONS_IDEMPOTENCYLEVEL.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_FIELDPRESENCE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_FIELDPRESENCE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_FIELDPRESENCE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_FIELDPRESENCE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_FIELDPRESENCE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENUMTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENUMTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENUMTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENUMTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_REPEATEDFIELDENCODING._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_REPEATEDFIELDENCODING.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_REPEATEDFIELDENCODING.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_REPEATEDFIELDENCODING.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_UTF8VALIDATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_UTF8VALIDATION.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_UTF8VALIDATION.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_UTF8VALIDATION.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_MESSAGEENCODING._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_MESSAGEENCODING.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_MESSAGEENCODING.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_MESSAGEENCODING.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_JSONFORMAT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_JSONFORMAT.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_JSONFORMAT.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_JSONFORMAT.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENFORCENAMINGSTYLE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENFORCENAMINGSTYLE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENFORCENAMINGSTYLE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENFORCENAMINGSTYLE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_ENFORCENAMINGSTYLE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION_SEMANTIC._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _EDITION.values[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SYMBOLVISIBILITY._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SYMBOLVISIBILITY.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SYMBOLVISIBILITY.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) + _SYMBOLVISIBILITY.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) +else: + _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.descriptor_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\020DescriptorProtosH\001Z-google.golang.org/protobuf/types/descriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Reflection' + _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['declaration']._loaded_options = None + _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['declaration']._serialized_options = b'\210\001\002' + _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['verification']._loaded_options = None + _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['verification']._serialized_options = b'\210\001\002' + _globals['_FILEOPTIONS'].fields_by_name['java_multiple_files']._loaded_options = None + _globals['_FILEOPTIONS'].fields_by_name['java_multiple_files']._serialized_options = b'\262\001\275\001\010\346\007 \351\007*\264\001This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.' + _globals['_FILEOPTIONS'].fields_by_name['java_generate_equals_and_hash']._loaded_options = None + _globals['_FILEOPTIONS'].fields_by_name['java_generate_equals_and_hash']._serialized_options = b'\030\001' + _globals['_FILEOPTIONS'].fields_by_name['cc_enable_arenas']._loaded_options = None + _globals['_FILEOPTIONS'].fields_by_name['cc_enable_arenas']._serialized_options = b'\262\001\212\001 \352\007*\204\001cc_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.' + _globals['_MESSAGEOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._loaded_options = None + _globals['_MESSAGEOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._serialized_options = b'\030\001' + _globals['_FIELDOPTIONS'].fields_by_name['weak']._loaded_options = None + _globals['_FIELDOPTIONS'].fields_by_name['weak']._serialized_options = b'\030\001' + _globals['_ENUMOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._loaded_options = None + _globals['_ENUMOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._serialized_options = b'\030\001' + _globals['_FEATURESET'].fields_by_name['field_presence']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['field_presence']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPLICIT\030\204\007\242\001\r\022\010IMPLICIT\030\347\007\242\001\r\022\010EXPLICIT\030\350\007\262\001\003\010\350\007' + _globals['_FEATURESET'].fields_by_name['enum_type']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['enum_type']._serialized_options = b'\210\001\001\230\001\006\230\001\001\242\001\013\022\006CLOSED\030\204\007\242\001\t\022\004OPEN\030\347\007\262\001\003\010\350\007' + _globals['_FEATURESET'].fields_by_name['repeated_field_encoding']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['repeated_field_encoding']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPANDED\030\204\007\242\001\013\022\006PACKED\030\347\007\262\001\003\010\350\007' + _globals['_FEATURESET'].fields_by_name['utf8_validation']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['utf8_validation']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\t\022\004NONE\030\204\007\242\001\013\022\006VERIFY\030\347\007\262\001\003\010\350\007' + _globals['_FEATURESET'].fields_by_name['message_encoding']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['message_encoding']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\024\022\017LENGTH_PREFIXED\030\204\007\262\001\003\010\350\007' + _globals['_FEATURESET'].fields_by_name['json_format']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['json_format']._serialized_options = b'\210\001\001\230\001\003\230\001\006\230\001\001\242\001\027\022\022LEGACY_BEST_EFFORT\030\204\007\242\001\n\022\005ALLOW\030\347\007\262\001\003\010\350\007' + _globals['_FEATURESET'].fields_by_name['enforce_naming_style']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['enforce_naming_style']._serialized_options = b'\210\001\002\230\001\001\230\001\002\230\001\003\230\001\004\230\001\005\230\001\006\230\001\007\230\001\010\230\001\t\242\001\021\022\014STYLE_LEGACY\030\204\007\242\001\016\022\tSTYLE2024\030\351\007\242\001\016\022\tSTYLE2026\030\352\007\262\001\003\010\351\007' + _globals['_FEATURESET'].fields_by_name['default_symbol_visibility']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['default_symbol_visibility']._serialized_options = b'\210\001\002\230\001\001\242\001\017\022\nEXPORT_ALL\030\204\007\242\001\025\022\020EXPORT_TOP_LEVEL\030\351\007\242\001\013\022\006STRICT\030\352\007\262\001\003\010\351\007' + _globals['_FEATURESET'].fields_by_name['enforce_proto_limits']._loaded_options = None + _globals['_FEATURESET'].fields_by_name['enforce_proto_limits']._serialized_options = b'\210\001\002\230\001\006\230\001\003\230\001\004\230\001\005\242\001\036\022\031LEGACY_NO_EXPLICIT_LIMITS\030\204\007\242\001\025\022\020PROTO_LIMITS2026\030\352\007\262\001\003\010\352\007' + _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['path']._loaded_options = None + _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['path']._serialized_options = b'\020\001' + _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['span']._loaded_options = None + _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['span']._serialized_options = b'\020\001' + _globals['_GENERATEDCODEINFO_ANNOTATION'].fields_by_name['path']._loaded_options = None + _globals['_GENERATEDCODEINFO_ANNOTATION'].fields_by_name['path']._serialized_options = b'\020\001' + _globals['_EDITION']._serialized_start=13504 + _globals['_EDITION']._serialized_end=13841 + _globals['_SYMBOLVISIBILITY']._serialized_start=13843 + _globals['_SYMBOLVISIBILITY']._serialized_end=13928 + _globals['_FILEDESCRIPTORSET']._serialized_start=53 + _globals['_FILEDESCRIPTORSET']._serialized_end=144 + _globals['_FILEDESCRIPTORPROTO']._serialized_start=147 + _globals['_FILEDESCRIPTORPROTO']._serialized_end=856 + _globals['_DESCRIPTORPROTO']._serialized_start=859 + _globals['_DESCRIPTORPROTO']._serialized_end=1751 + _globals['_DESCRIPTORPROTO_EXTENSIONRANGE']._serialized_start=1572 + _globals['_DESCRIPTORPROTO_EXTENSIONRANGE']._serialized_end=1694 + _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_start=1696 + _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_end=1751 + _globals['_EXTENSIONRANGEOPTIONS']._serialized_start=1754 + _globals['_EXTENSIONRANGEOPTIONS']._serialized_end=2350 + _globals['_EXTENSIONRANGEOPTIONS_DECLARATION']._serialized_start=2129 + _globals['_EXTENSIONRANGEOPTIONS_DECLARATION']._serialized_end=2277 + _globals['_EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE']._serialized_start=2279 + _globals['_EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE']._serialized_end=2331 + _globals['_FIELDDESCRIPTORPROTO']._serialized_start=2353 + _globals['_FIELDDESCRIPTORPROTO']._serialized_end=3186 + _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_start=2807 + _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_end=3117 + _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_start=3119 + _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_end=3186 + _globals['_ONEOFDESCRIPTORPROTO']._serialized_start=3188 + _globals['_ONEOFDESCRIPTORPROTO']._serialized_end=3287 + _globals['_ENUMDESCRIPTORPROTO']._serialized_start=3290 + _globals['_ENUMDESCRIPTORPROTO']._serialized_end=3712 + _globals['_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE']._serialized_start=3653 + _globals['_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE']._serialized_end=3712 + _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_start=3715 + _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_end=3846 + _globals['_SERVICEDESCRIPTORPROTO']._serialized_start=3849 + _globals['_SERVICEDESCRIPTORPROTO']._serialized_end=4030 + _globals['_METHODDESCRIPTORPROTO']._serialized_start=4033 + _globals['_METHODDESCRIPTORPROTO']._serialized_end=4298 + _globals['_FILEOPTIONS']._serialized_start=4301 + _globals['_FILEOPTIONS']._serialized_end=5849 + _globals['_FILEOPTIONS_OPTIMIZEMODE']._serialized_start=5738 + _globals['_FILEOPTIONS_OPTIMIZEMODE']._serialized_end=5796 + _globals['_MESSAGEOPTIONS']._serialized_start=5852 + _globals['_MESSAGEOPTIONS']._serialized_end=6360 + _globals['_FIELDOPTIONS']._serialized_start=6363 + _globals['_FIELDOPTIONS']._serialized_end=8105 + _globals['_FIELDOPTIONS_EDITIONDEFAULT']._serialized_start=7204 + _globals['_FIELDOPTIONS_EDITIONDEFAULT']._serialized_end=7294 + _globals['_FIELDOPTIONS_FEATURESUPPORT']._serialized_start=7297 + _globals['_FIELDOPTIONS_FEATURESUPPORT']._serialized_end=7612 + _globals['_FIELDOPTIONS_CTYPE']._serialized_start=7614 + _globals['_FIELDOPTIONS_CTYPE']._serialized_end=7661 + _globals['_FIELDOPTIONS_JSTYPE']._serialized_start=7663 + _globals['_FIELDOPTIONS_JSTYPE']._serialized_end=7716 + _globals['_FIELDOPTIONS_OPTIONRETENTION']._serialized_start=7718 + _globals['_FIELDOPTIONS_OPTIONRETENTION']._serialized_end=7803 + _globals['_FIELDOPTIONS_OPTIONTARGETTYPE']._serialized_start=7806 + _globals['_FIELDOPTIONS_OPTIONTARGETTYPE']._serialized_end=8074 + _globals['_ONEOFOPTIONS']._serialized_start=8108 + _globals['_ONEOFOPTIONS']._serialized_end=8288 + _globals['_ENUMOPTIONS']._serialized_start=8291 + _globals['_ENUMOPTIONS']._serialized_end=8636 + _globals['_ENUMVALUEOPTIONS']._serialized_start=8639 + _globals['_ENUMVALUEOPTIONS']._serialized_end=8991 + _globals['_SERVICEOPTIONS']._serialized_start=8994 + _globals['_SERVICEOPTIONS']._serialized_end=9215 + _globals['_METHODOPTIONS']._serialized_start=9218 + _globals['_METHODOPTIONS']._serialized_end=9635 + _globals['_METHODOPTIONS_IDEMPOTENCYLEVEL']._serialized_start=9536 + _globals['_METHODOPTIONS_IDEMPOTENCYLEVEL']._serialized_end=9616 + _globals['_UNINTERPRETEDOPTION']._serialized_start=9638 + _globals['_UNINTERPRETEDOPTION']._serialized_end=10048 + _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_start=9974 + _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_end=10048 + _globals['_FEATURESET']._serialized_start=10051 + _globals['_FEATURESET']._serialized_end=12352 + _globals['_FEATURESET_VISIBILITYFEATURE']._serialized_start=11459 + _globals['_FEATURESET_VISIBILITYFEATURE']._serialized_end=11620 + _globals['_FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY']._serialized_start=11481 + _globals['_FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY']._serialized_end=11610 + _globals['_FEATURESET_PROTOLIMITSFEATURE']._serialized_start=11622 + _globals['_FEATURESET_PROTOLIMITSFEATURE']._serialized_end=11743 + _globals['_FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS']._serialized_start=11644 + _globals['_FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS']._serialized_end=11743 + _globals['_FEATURESET_FIELDPRESENCE']._serialized_start=11745 + _globals['_FEATURESET_FIELDPRESENCE']._serialized_end=11837 + _globals['_FEATURESET_ENUMTYPE']._serialized_start=11839 + _globals['_FEATURESET_ENUMTYPE']._serialized_end=11894 + _globals['_FEATURESET_REPEATEDFIELDENCODING']._serialized_start=11896 + _globals['_FEATURESET_REPEATEDFIELDENCODING']._serialized_end=11982 + _globals['_FEATURESET_UTF8VALIDATION']._serialized_start=11984 + _globals['_FEATURESET_UTF8VALIDATION']._serialized_end=12057 + _globals['_FEATURESET_MESSAGEENCODING']._serialized_start=12059 + _globals['_FEATURESET_MESSAGEENCODING']._serialized_end=12142 + _globals['_FEATURESET_JSONFORMAT']._serialized_start=12144 + _globals['_FEATURESET_JSONFORMAT']._serialized_end=12216 + _globals['_FEATURESET_ENFORCENAMINGSTYLE']._serialized_start=12218 + _globals['_FEATURESET_ENFORCENAMINGSTYLE']._serialized_end=12320 + _globals['_FEATURESETDEFAULTS']._serialized_start=12355 + _globals['_FEATURESETDEFAULTS']._serialized_end=12850 + _globals['_FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT']._serialized_start=12602 + _globals['_FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT']._serialized_end=12850 + _globals['_SOURCECODEINFO']._serialized_start=12853 + _globals['_SOURCECODEINFO']._serialized_end=13162 + _globals['_SOURCECODEINFO_LOCATION']._serialized_start=12942 + _globals['_SOURCECODEINFO_LOCATION']._serialized_end=13148 + _globals['_GENERATEDCODEINFO']._serialized_start=13165 + _globals['_GENERATEDCODEINFO']._serialized_end=13501 + _globals['_GENERATEDCODEINFO_ANNOTATION']._serialized_start=13266 + _globals['_GENERATEDCODEINFO_ANNOTATION']._serialized_end=13501 + _globals['_GENERATEDCODEINFO_ANNOTATION_SEMANTIC']._serialized_start=13461 + _globals['_GENERATEDCODEINFO_ANNOTATION_SEMANTIC']._serialized_end=13501 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py new file mode 100644 index 00000000000..cd7092f7fd4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py @@ -0,0 +1,1468 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Provides DescriptorPool to use as a container for proto2 descriptors. + +The DescriptorPool is used in conjection with a DescriptorDatabase to maintain +a collection of protocol buffer descriptors for use when dynamically creating +message types at runtime. + +For most applications protocol buffers should be used via modules generated by +the protocol buffer compiler tool. This should only be used when the type of +protocol buffers used in an application or library cannot be predetermined. + +Below is a straightforward example on how to use this class:: + + pool = DescriptorPool() + file_descriptor_protos = [ ... ] + for file_descriptor_proto in file_descriptor_protos: + pool.Add(file_descriptor_proto) + my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType') + +The message descriptor can be used in conjunction with the message_factory +module in order to create a protocol buffer class that can be encoded and +decoded. + +If you want to get a Python class for the specified proto, use the +helper functions inside google.protobuf.message_factory +directly instead of this class. +""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +import collections +import threading +import warnings + +from opentelemetry.agent._vendor.google.protobuf import descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_database +from opentelemetry.agent._vendor.google.protobuf import text_encoding +from opentelemetry.agent._vendor.google.protobuf.internal import python_edition_defaults +from opentelemetry.agent._vendor.google.protobuf.internal import python_message + +_USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-access + + +def _NormalizeFullyQualifiedName(name): + """Remove leading period from fully-qualified type name. + + Due to b/13860351 in descriptor_database.py, types in the root namespace are + generated with a leading period. This function removes that prefix. + + Args: + name (str): The fully-qualified symbol name. + + Returns: + str: The normalized fully-qualified symbol name. + """ + return name.lstrip('.') + + +def _OptionsOrNone(descriptor_proto): + """Returns the value of the field `options`, or None if it is not set.""" + if descriptor_proto.HasField('options'): + return descriptor_proto.options + else: + return None + + +def _IsMessageSetExtension(field): + return ( + field.is_extension + and field.containing_type.has_options + and field.containing_type.GetOptions().message_set_wire_format + and field.type == descriptor.FieldDescriptor.TYPE_MESSAGE + and not field.is_required + and not field.is_repeated + ) + + +_edition_defaults_lock = threading.Lock() + + +class DescriptorPool(object): + """A collection of protobufs dynamically constructed by descriptor protos.""" + + if _USE_C_DESCRIPTORS: + + def __new__(cls, descriptor_db=None): + # pylint: disable=protected-access + return descriptor._message.DescriptorPool(descriptor_db) + + def __init__( + self, descriptor_db=None, use_deprecated_legacy_json_field_conflicts=False + ): + """Initializes a Pool of proto buffs. + + The descriptor_db argument to the constructor is provided to allow + specialized file descriptor proto lookup code to be triggered on demand. An + example would be an implementation which will read and compile a file + specified in a call to FindFileByName() and not require the call to Add() + at all. Results from this database will be cached internally here as well. + + Args: + descriptor_db: A secondary source of file descriptors. + use_deprecated_legacy_json_field_conflicts: Unused, for compatibility with + C++. + """ + + self._internal_db = descriptor_database.DescriptorDatabase() + self._descriptor_db = descriptor_db + self._descriptors = {} + self._enum_descriptors = {} + self._service_descriptors = {} + self._file_descriptors = {} + self._toplevel_extensions = {} + self._top_enum_values = {} + # We store extensions in two two-level mappings: The first key is the + # descriptor of the message being extended, the second key is the extension + # full name or its tag number. + self._extensions_by_name = collections.defaultdict(dict) + self._extensions_by_number = collections.defaultdict(dict) + self._serialized_edition_defaults = ( + python_edition_defaults._PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS + ) + self._edition_defaults = None + self._feature_cache = dict() + + def _CheckConflictRegister(self, desc, desc_name, file_name): + """Check if the descriptor name conflicts with another of the same name. + + Args: + desc: Descriptor of a message, enum, service, extension or enum value. + desc_name (str): the full name of desc. + file_name (str): The file name of descriptor. + """ + for register, descriptor_type in [ + (self._descriptors, descriptor.Descriptor), + (self._enum_descriptors, descriptor.EnumDescriptor), + (self._service_descriptors, descriptor.ServiceDescriptor), + (self._toplevel_extensions, descriptor.FieldDescriptor), + (self._top_enum_values, descriptor.EnumValueDescriptor), + ]: + if desc_name in register: + old_desc = register[desc_name] + if isinstance(old_desc, descriptor.EnumValueDescriptor): + old_file = old_desc.type.file.name + else: + old_file = old_desc.file.name + + if not isinstance(desc, descriptor_type) or (old_file != file_name): + error_msg = ( + 'Conflict register for file "' + + file_name + + '": ' + + desc_name + + ' is already defined in file "' + + old_file + + '". Please fix the conflict by adding ' + 'package name on the proto file, or use different ' + 'name for the duplication.' + ) + if isinstance(desc, descriptor.EnumValueDescriptor): + error_msg += ( + '\nNote: enum values appear as ' + 'siblings of the enum type instead of ' + 'children of it.' + ) + + raise TypeError(error_msg) + + return + + def Add(self, file_desc_proto): + """Adds the FileDescriptorProto and its types to this pool. + + Args: + file_desc_proto (FileDescriptorProto): The file descriptor to add. + """ + + self._internal_db.Add(file_desc_proto) + + def AddSerializedFile(self, serialized_file_desc_proto): + """Adds the FileDescriptorProto and its types to this pool. + + Args: + serialized_file_desc_proto (bytes): A bytes string, serialization of the + :class:`FileDescriptorProto` to add. + + Returns: + FileDescriptor: Descriptor for the added file. + """ + + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString( + serialized_file_desc_proto + ) + file_desc = self._ConvertFileProtoToFileDescriptor(file_desc_proto) + file_desc.serialized_pb = serialized_file_desc_proto + return file_desc + + # Never call this method. It is for internal usage only. + def _AddDescriptor(self, desc): + """Adds a Descriptor to the pool, non-recursively. + + If the Descriptor contains nested messages or enums, the caller must + explicitly register them. This method also registers the FileDescriptor + associated with the message. + + Args: + desc: A Descriptor. + """ + if not isinstance(desc, descriptor.Descriptor): + raise TypeError('Expected instance of descriptor.Descriptor.') + + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) + + self._descriptors[desc.full_name] = desc + self._AddFileDescriptor(desc.file) + + # Never call this method. It is for internal usage only. + def _AddEnumDescriptor(self, enum_desc): + """Adds an EnumDescriptor to the pool. + + This method also registers the FileDescriptor associated with the enum. + + Args: + enum_desc: An EnumDescriptor. + """ + + if not isinstance(enum_desc, descriptor.EnumDescriptor): + raise TypeError('Expected instance of descriptor.EnumDescriptor.') + + file_name = enum_desc.file.name + self._CheckConflictRegister(enum_desc, enum_desc.full_name, file_name) + self._enum_descriptors[enum_desc.full_name] = enum_desc + + # Top enum values need to be indexed. + # Count the number of dots to see whether the enum is toplevel or nested + # in a message. We cannot use enum_desc.containing_type at this stage. + if enum_desc.file.package: + top_level = ( + enum_desc.full_name.count('.') - enum_desc.file.package.count('.') + == 1 + ) + else: + top_level = enum_desc.full_name.count('.') == 0 + if top_level: + file_name = enum_desc.file.name + package = enum_desc.file.package + for enum_value in enum_desc.values: + full_name = _NormalizeFullyQualifiedName( + '.'.join((package, enum_value.name)) + ) + self._CheckConflictRegister(enum_value, full_name, file_name) + self._top_enum_values[full_name] = enum_value + self._AddFileDescriptor(enum_desc.file) + + # Never call this method. It is for internal usage only. + def _AddServiceDescriptor(self, service_desc): + """Adds a ServiceDescriptor to the pool. + + Args: + service_desc: A ServiceDescriptor. + """ + + if not isinstance(service_desc, descriptor.ServiceDescriptor): + raise TypeError('Expected instance of descriptor.ServiceDescriptor.') + + self._CheckConflictRegister( + service_desc, service_desc.full_name, service_desc.file.name + ) + self._service_descriptors[service_desc.full_name] = service_desc + + # Never call this method. It is for internal usage only. + def _AddExtensionDescriptor(self, extension): + """Adds a FieldDescriptor describing an extension to the pool. + + Args: + extension: A FieldDescriptor. + + Raises: + AssertionError: when another extension with the same number extends the + same message. + TypeError: when the specified extension is not a + descriptor.FieldDescriptor. + """ + if not ( + isinstance(extension, descriptor.FieldDescriptor) + and extension.is_extension + ): + raise TypeError('Expected an extension descriptor.') + + if extension.extension_scope is None: + self._CheckConflictRegister( + extension, extension.full_name, extension.file.name + ) + self._toplevel_extensions[extension.full_name] = extension + + try: + existing_desc = self._extensions_by_number[extension.containing_type][ + extension.number + ] + except KeyError: + pass + else: + if extension is not existing_desc: + raise AssertionError( + 'Extensions "%s" and "%s" both try to extend message type "%s" ' + 'with field number %d.' + % ( + extension.full_name, + existing_desc.full_name, + extension.containing_type.full_name, + extension.number, + ) + ) + + self._extensions_by_number[extension.containing_type][ + extension.number + ] = extension + self._extensions_by_name[extension.containing_type][ + extension.full_name + ] = extension + + # Also register MessageSet extensions with the type name. + if _IsMessageSetExtension(extension): + self._extensions_by_name[extension.containing_type][ + extension.message_type.full_name + ] = extension + + if hasattr(extension.containing_type, '_concrete_class'): + python_message._AttachFieldHelpers( + extension.containing_type._concrete_class, extension + ) + + # Never call this method. It is for internal usage only. + def _InternalAddFileDescriptor(self, file_desc): + """Adds a FileDescriptor to the pool, non-recursively. + + If the FileDescriptor contains messages or enums, the caller must explicitly + register them. + + Args: + file_desc: A FileDescriptor. + """ + + self._AddFileDescriptor(file_desc) + + def _AddFileDescriptor(self, file_desc): + """Adds a FileDescriptor to the pool, non-recursively. + + If the FileDescriptor contains messages or enums, the caller must explicitly + register them. + + Args: + file_desc: A FileDescriptor. + """ + + if not isinstance(file_desc, descriptor.FileDescriptor): + raise TypeError('Expected instance of descriptor.FileDescriptor.') + self._file_descriptors[file_desc.name] = file_desc + + def FindFileByName(self, file_name): + """Gets a FileDescriptor by file name. + + Args: + file_name (str): The path to the file to get a descriptor for. + + Returns: + FileDescriptor: The descriptor for the named file. + + Raises: + KeyError: if the file cannot be found in the pool. + """ + + try: + return self._file_descriptors[file_name] + except KeyError: + pass + + try: + file_proto = self._internal_db.FindFileByName(file_name) + except KeyError as error: + if self._descriptor_db: + file_proto = self._descriptor_db.FindFileByName(file_name) + else: + raise error + if not file_proto: + raise KeyError('Cannot find a file named %s' % file_name) + return self._ConvertFileProtoToFileDescriptor(file_proto) + + def FindFileContainingSymbol(self, symbol): + """Gets the FileDescriptor for the file containing the specified symbol. + + Args: + symbol (str): The name of the symbol to search for. + + Returns: + FileDescriptor: Descriptor for the file that contains the specified + symbol. + + Raises: + KeyError: if the file cannot be found in the pool. + """ + + symbol = _NormalizeFullyQualifiedName(symbol) + try: + return self._InternalFindFileContainingSymbol(symbol) + except KeyError: + pass + + try: + # Try fallback database. Build and find again if possible. + self._FindFileContainingSymbolInDb(symbol) + return self._InternalFindFileContainingSymbol(symbol) + except KeyError: + raise KeyError('Cannot find a file containing %s' % symbol) + + def _InternalFindFileContainingSymbol(self, symbol): + """Gets the already built FileDescriptor containing the specified symbol. + + Args: + symbol (str): The name of the symbol to search for. + + Returns: + FileDescriptor: Descriptor for the file that contains the specified + symbol. + + Raises: + KeyError: if the file cannot be found in the pool. + """ + try: + return self._descriptors[symbol].file + except KeyError: + pass + + try: + return self._enum_descriptors[symbol].file + except KeyError: + pass + + try: + return self._service_descriptors[symbol].file + except KeyError: + pass + + try: + return self._top_enum_values[symbol].type.file + except KeyError: + pass + + try: + return self._toplevel_extensions[symbol].file + except KeyError: + pass + + # Try fields, enum values and nested extensions inside a message. + top_name, _, sub_name = symbol.rpartition('.') + try: + message = self.FindMessageTypeByName(top_name) + assert ( + sub_name in message.extensions_by_name + or sub_name in message.fields_by_name + or sub_name in message.enum_values_by_name + ) + return message.file + except (KeyError, AssertionError): + raise KeyError('Cannot find a file containing %s' % symbol) + + def FindMessageTypeByName(self, full_name): + """Loads the named descriptor from the pool. + + Args: + full_name (str): The full name of the descriptor to load. + + Returns: + Descriptor: The descriptor for the named type. + + Raises: + KeyError: if the message cannot be found in the pool. + """ + + full_name = _NormalizeFullyQualifiedName(full_name) + if full_name not in self._descriptors: + self._FindFileContainingSymbolInDb(full_name) + return self._descriptors[full_name] + + def FindEnumTypeByName(self, full_name): + """Loads the named enum descriptor from the pool. + + Args: + full_name (str): The full name of the enum descriptor to load. + + Returns: + EnumDescriptor: The enum descriptor for the named type. + + Raises: + KeyError: if the enum cannot be found in the pool. + """ + + full_name = _NormalizeFullyQualifiedName(full_name) + if full_name not in self._enum_descriptors: + self._FindFileContainingSymbolInDb(full_name) + return self._enum_descriptors[full_name] + + def FindFieldByName(self, full_name): + """Loads the named field descriptor from the pool. + + Args: + full_name (str): The full name of the field descriptor to load. + + Returns: + FieldDescriptor: The field descriptor for the named field. + + Raises: + KeyError: if the field cannot be found in the pool. + """ + full_name = _NormalizeFullyQualifiedName(full_name) + message_name, _, field_name = full_name.rpartition('.') + message_descriptor = self.FindMessageTypeByName(message_name) + return message_descriptor.fields_by_name[field_name] + + def FindOneofByName(self, full_name): + """Loads the named oneof descriptor from the pool. + + Args: + full_name (str): The full name of the oneof descriptor to load. + + Returns: + OneofDescriptor: The oneof descriptor for the named oneof. + + Raises: + KeyError: if the oneof cannot be found in the pool. + """ + full_name = _NormalizeFullyQualifiedName(full_name) + message_name, _, oneof_name = full_name.rpartition('.') + message_descriptor = self.FindMessageTypeByName(message_name) + return message_descriptor.oneofs_by_name[oneof_name] + + def FindExtensionByName(self, full_name): + """Loads the named extension descriptor from the pool. + + Args: + full_name (str): The full name of the extension descriptor to load. + + Returns: + FieldDescriptor: The field descriptor for the named extension. + + Raises: + KeyError: if the extension cannot be found in the pool. + """ + full_name = _NormalizeFullyQualifiedName(full_name) + try: + # The proto compiler does not give any link between the FileDescriptor + # and top-level extensions unless the FileDescriptorProto is added to + # the DescriptorDatabase, but this can impact memory usage. + # So we registered these extensions by name explicitly. + return self._toplevel_extensions[full_name] + except KeyError: + pass + message_name, _, extension_name = full_name.rpartition('.') + try: + # Most extensions are nested inside a message. + scope = self.FindMessageTypeByName(message_name) + except KeyError: + # Some extensions are defined at file scope. + scope = self._FindFileContainingSymbolInDb(full_name) + return scope.extensions_by_name[extension_name] + + def FindExtensionByNumber(self, message_descriptor, number): + """Gets the extension of the specified message with the specified number. + + Extensions have to be registered to this pool by calling :func:`Add` or + :func:`AddExtensionDescriptor`. + + Args: + message_descriptor (Descriptor): descriptor of the extended message. + number (int): Number of the extension field. + + Returns: + FieldDescriptor: The descriptor for the extension. + + Raises: + KeyError: when no extension with the given number is known for the + specified message. + """ + try: + return self._extensions_by_number[message_descriptor][number] + except KeyError: + self._TryLoadExtensionFromDB(message_descriptor, number) + return self._extensions_by_number[message_descriptor][number] + + def FindAllExtensions(self, message_descriptor): + """Gets all the known extensions of a given message. + + Extensions have to be registered to this pool by build related + :func:`Add` or :func:`AddExtensionDescriptor`. + + Args: + message_descriptor (Descriptor): Descriptor of the extended message. + + Returns: + list[FieldDescriptor]: Field descriptors describing the extensions. + """ + # Fallback to descriptor db if FindAllExtensionNumbers is provided. + if self._descriptor_db and hasattr( + self._descriptor_db, 'FindAllExtensionNumbers' + ): + full_name = message_descriptor.full_name + try: + all_numbers = self._descriptor_db.FindAllExtensionNumbers(full_name) + except: + pass + else: + if isinstance(all_numbers, list): + for number in all_numbers: + if number in self._extensions_by_number[message_descriptor]: + continue + self._TryLoadExtensionFromDB(message_descriptor, number) + else: + warnings.warn( + 'FindAllExtensionNumbers() on fall back DB must return a list,' + ' not {0}'.format(type(all_numbers)) + ) + + return list(self._extensions_by_number[message_descriptor].values()) + + def _TryLoadExtensionFromDB(self, message_descriptor, number): + """Try to Load extensions from descriptor db. + + Args: + message_descriptor: descriptor of the extended message. + number: the extension number that needs to be loaded. + """ + if not self._descriptor_db: + return + # Only supported when FindFileContainingExtension is provided. + if not hasattr(self._descriptor_db, 'FindFileContainingExtension'): + return + + full_name = message_descriptor.full_name + file_proto = None + try: + file_proto = self._descriptor_db.FindFileContainingExtension( + full_name, number + ) + except: + return + + if file_proto is None: + return + + try: + self._ConvertFileProtoToFileDescriptor(file_proto) + except: + warn_msg = 'Unable to load proto file %s for extension number %d.' % ( + file_proto.name, + number, + ) + warnings.warn(warn_msg, RuntimeWarning) + + def FindServiceByName(self, full_name): + """Loads the named service descriptor from the pool. + + Args: + full_name (str): The full name of the service descriptor to load. + + Returns: + ServiceDescriptor: The service descriptor for the named service. + + Raises: + KeyError: if the service cannot be found in the pool. + """ + full_name = _NormalizeFullyQualifiedName(full_name) + if full_name not in self._service_descriptors: + self._FindFileContainingSymbolInDb(full_name) + return self._service_descriptors[full_name] + + def FindMethodByName(self, full_name): + """Loads the named service method descriptor from the pool. + + Args: + full_name (str): The full name of the method descriptor to load. + + Returns: + MethodDescriptor: The method descriptor for the service method. + + Raises: + KeyError: if the method cannot be found in the pool. + """ + full_name = _NormalizeFullyQualifiedName(full_name) + service_name, _, method_name = full_name.rpartition('.') + service_descriptor = self.FindServiceByName(service_name) + return service_descriptor.methods_by_name[method_name] + + def SetFeatureSetDefaults(self, defaults): + """Sets the default feature mappings used during the build. + + Args: + defaults: a FeatureSetDefaults message containing the new mappings. + """ + if self._edition_defaults is not None: + raise ValueError( + "Feature set defaults can't be changed once the pool has started" + ' building!' + ) + + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + if not isinstance(defaults, descriptor_pb2.FeatureSetDefaults): + raise TypeError('SetFeatureSetDefaults called with invalid type') + + if defaults.minimum_edition > defaults.maximum_edition: + raise ValueError( + 'Invalid edition range %s to %s' + % ( + descriptor_pb2.Edition.Name(defaults.minimum_edition), + descriptor_pb2.Edition.Name(defaults.maximum_edition), + ) + ) + + prev_edition = descriptor_pb2.Edition.EDITION_UNKNOWN + for d in defaults.defaults: + if d.edition == descriptor_pb2.Edition.EDITION_UNKNOWN: + raise ValueError('Invalid edition EDITION_UNKNOWN specified') + if prev_edition >= d.edition: + raise ValueError( + 'Feature set defaults are not strictly increasing. %s is greater' + ' than or equal to %s' + % ( + descriptor_pb2.Edition.Name(prev_edition), + descriptor_pb2.Edition.Name(d.edition), + ) + ) + prev_edition = d.edition + self._edition_defaults = defaults + + def _CreateDefaultFeatures(self, edition): + """Creates a FeatureSet message with defaults for a specific edition. + + Args: + edition: the edition to generate defaults for. + + Returns: + A FeatureSet message with defaults for a specific edition. + """ + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + with _edition_defaults_lock: + if not self._edition_defaults: + self._edition_defaults = descriptor_pb2.FeatureSetDefaults() + self._edition_defaults.ParseFromString( + self._serialized_edition_defaults + ) + + if edition < self._edition_defaults.minimum_edition: + raise TypeError( + 'Edition %s is earlier than the minimum supported edition %s!' + % ( + descriptor_pb2.Edition.Name(edition), + descriptor_pb2.Edition.Name( + self._edition_defaults.minimum_edition + ), + ) + ) + if ( + edition > self._edition_defaults.maximum_edition + and edition != descriptor_pb2.EDITION_UNSTABLE + ): + raise TypeError( + 'Edition %s is later than the maximum supported edition %s!' + % ( + descriptor_pb2.Edition.Name(edition), + descriptor_pb2.Edition.Name( + self._edition_defaults.maximum_edition + ), + ) + ) + found = None + for d in self._edition_defaults.defaults: + if d.edition > edition: + break + found = d + if found is None: + raise TypeError( + 'No valid default found for edition %s!' + % descriptor_pb2.Edition.Name(edition) + ) + + defaults = descriptor_pb2.FeatureSet() + defaults.CopyFrom(found.fixed_features) + defaults.MergeFrom(found.overridable_features) + return defaults + + def _InternFeatures(self, features): + serialized = features.SerializeToString() + with _edition_defaults_lock: + cached = self._feature_cache.get(serialized) + if cached is None: + self._feature_cache[serialized] = features + cached = features + return cached + + def _FindFileContainingSymbolInDb(self, symbol): + """Finds the file in descriptor DB containing the specified symbol. + + Args: + symbol (str): The name of the symbol to search for. + + Returns: + FileDescriptor: The file that contains the specified symbol. + + Raises: + KeyError: if the file cannot be found in the descriptor database. + """ + try: + file_proto = self._internal_db.FindFileContainingSymbol(symbol) + except KeyError as error: + if self._descriptor_db: + file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) + else: + raise error + if not file_proto: + raise KeyError('Cannot find a file containing %s' % symbol) + return self._ConvertFileProtoToFileDescriptor(file_proto) + + def _ConvertFileProtoToFileDescriptor(self, file_proto): + """Creates a FileDescriptor from a proto or returns a cached copy. + + This method also has the side effect of loading all the symbols found in + the file into the appropriate dictionaries in the pool. + + Args: + file_proto: The proto to convert. + + Returns: + A FileDescriptor matching the passed in proto. + """ + if file_proto.name not in self._file_descriptors: + built_deps = list(self._GetDeps(file_proto.dependency)) + direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] + public_deps = [direct_deps[i] for i in file_proto.public_dependency] + + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 + + file_descriptor = descriptor.FileDescriptor( + pool=self, + name=file_proto.name, + package=file_proto.package, + syntax=file_proto.syntax, + edition=descriptor_pb2.Edition.Name(file_proto.edition), + options=_OptionsOrNone(file_proto), + serialized_pb=file_proto.SerializeToString(), + dependencies=direct_deps, + public_dependencies=public_deps, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + scope = {} + + # This loop extracts all the message and enum types from all the + # dependencies of the file_proto. This is necessary to create the + # scope of available message types when defining the passed in + # file proto. + for dependency in built_deps: + scope.update( + self._ExtractSymbols(dependency.message_types_by_name.values()) + ) + scope.update( + (_PrefixWithDot(enum.full_name), enum) + for enum in dependency.enum_types_by_name.values() + ) + + for message_type in file_proto.message_type: + message_desc = self._ConvertMessageDescriptor( + message_type, + file_proto.package, + file_descriptor, + scope, + file_proto.syntax, + ) + file_descriptor.message_types_by_name[message_desc.name] = message_desc + + for enum_type in file_proto.enum_type: + file_descriptor.enum_types_by_name[enum_type.name] = ( + self._ConvertEnumDescriptor( + enum_type, + file_proto.package, + file_descriptor, + None, + scope, + True, + ) + ) + + for index, extension_proto in enumerate(file_proto.extension): + extension_desc = self._MakeFieldDescriptor( + extension_proto, + file_proto.package, + index, + file_descriptor, + is_extension=True, + ) + extension_desc.containing_type = self._GetTypeFromScope( + file_descriptor.package, extension_proto.extendee, scope + ) + self._SetFieldType( + extension_proto, extension_desc, file_descriptor.package, scope + ) + file_descriptor.extensions_by_name[extension_desc.name] = extension_desc + + for desc_proto in file_proto.message_type: + self._SetAllFieldTypes(file_proto.package, desc_proto, scope) + + if file_proto.package: + desc_proto_prefix = _PrefixWithDot(file_proto.package) + else: + desc_proto_prefix = '' + + for desc_proto in file_proto.message_type: + desc = self._GetTypeFromScope(desc_proto_prefix, desc_proto.name, scope) + file_descriptor.message_types_by_name[desc_proto.name] = desc + + for index, service_proto in enumerate(file_proto.service): + file_descriptor.services_by_name[service_proto.name] = ( + self._MakeServiceDescriptor( + service_proto, index, scope, file_proto.package, file_descriptor + ) + ) + + self._file_descriptors[file_proto.name] = file_descriptor + + # Add extensions to the pool + def AddExtensionForNested(message_type): + for nested in message_type.nested_types: + AddExtensionForNested(nested) + for extension in message_type.extensions: + self._AddExtensionDescriptor(extension) + + file_desc = self._file_descriptors[file_proto.name] + for extension in file_desc.extensions_by_name.values(): + self._AddExtensionDescriptor(extension) + for message_type in file_desc.message_types_by_name.values(): + AddExtensionForNested(message_type) + + return file_desc + + def _ConvertMessageDescriptor( + self, desc_proto, package=None, file_desc=None, scope=None, syntax=None + ): + """Adds the proto to the pool in the specified package. + + Args: + desc_proto: The descriptor_pb2.DescriptorProto protobuf message. + package: The package the proto should be located in. + file_desc: The file containing this message. + scope: Dict mapping short and full symbols to message and enum types. + syntax: string indicating syntax of the file ("proto2" or "proto3") + + Returns: + The added descriptor. + """ + + if package: + desc_name = '.'.join((package, desc_proto.name)) + else: + desc_name = desc_proto.name + + if file_desc is None: + file_name = None + else: + file_name = file_desc.name + + if scope is None: + scope = {} + + nested = [ + self._ConvertMessageDescriptor( + nested, desc_name, file_desc, scope, syntax + ) + for nested in desc_proto.nested_type + ] + enums = [ + self._ConvertEnumDescriptor( + enum, desc_name, file_desc, None, scope, False + ) + for enum in desc_proto.enum_type + ] + fields = [ + self._MakeFieldDescriptor(field, desc_name, index, file_desc) + for index, field in enumerate(desc_proto.field) + ] + extensions = [ + self._MakeFieldDescriptor( + extension, desc_name, index, file_desc, is_extension=True + ) + for index, extension in enumerate(desc_proto.extension) + ] + oneofs = [ + # pylint: disable=g-complex-comprehension + descriptor.OneofDescriptor( + desc.name, + '.'.join((desc_name, desc.name)), + index, + None, + [], + _OptionsOrNone(desc), + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + for index, desc in enumerate(desc_proto.oneof_decl) + ] + extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] + if extension_ranges: + is_extendable = True + else: + is_extendable = False + desc = descriptor.Descriptor( + name=desc_proto.name, + full_name=desc_name, + filename=file_name, + containing_type=None, + fields=fields, + oneofs=oneofs, + nested_types=nested, + enum_types=enums, + extensions=extensions, + options=_OptionsOrNone(desc_proto), + is_extendable=is_extendable, + extension_ranges=extension_ranges, + file=file_desc, + serialized_start=None, + serialized_end=None, + is_map_entry=desc_proto.options.map_entry, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + for nested in desc.nested_types: + nested.containing_type = desc + for enum in desc.enum_types: + enum.containing_type = desc + for field_index, field_desc in enumerate(desc_proto.field): + if field_desc.HasField('oneof_index'): + oneof_index = field_desc.oneof_index + oneofs[oneof_index].fields.append(fields[field_index]) + fields[field_index].containing_oneof = oneofs[oneof_index] + + scope[_PrefixWithDot(desc_name)] = desc + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) + self._descriptors[desc_name] = desc + return desc + + def _ConvertEnumDescriptor( + self, + enum_proto, + package=None, + file_desc=None, + containing_type=None, + scope=None, + top_level=False, + ): + """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf. + + Args: + enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message. + package: Optional package name for the new message EnumDescriptor. + file_desc: The file containing the enum descriptor. + containing_type: The type containing this enum. + scope: Scope containing available types. + top_level: If True, the enum is a top level symbol. If False, the enum is + defined inside a message. + + Returns: + The added descriptor + """ + + if package: + enum_name = '.'.join((package, enum_proto.name)) + else: + enum_name = enum_proto.name + + if file_desc is None: + file_name = None + else: + file_name = file_desc.name + + values = [ + self._MakeEnumValueDescriptor(value, index) + for index, value in enumerate(enum_proto.value) + ] + desc = descriptor.EnumDescriptor( + name=enum_proto.name, + full_name=enum_name, + filename=file_name, + file=file_desc, + values=values, + containing_type=containing_type, + options=_OptionsOrNone(enum_proto), + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + scope['.%s' % enum_name] = desc + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) + self._enum_descriptors[enum_name] = desc + + # Add top level enum values. + if top_level: + for value in values: + full_name = _NormalizeFullyQualifiedName( + '.'.join((package, value.name)) + ) + self._CheckConflictRegister(value, full_name, file_name) + self._top_enum_values[full_name] = value + + return desc + + def _MakeFieldDescriptor( + self, field_proto, message_name, index, file_desc, is_extension=False + ): + """Creates a field descriptor from a FieldDescriptorProto. + + For message and enum type fields, this method will do a look up + in the pool for the appropriate descriptor for that type. If it + is unavailable, it will fall back to the _source function to + create it. If this type is still unavailable, construction will + fail. + + Args: + field_proto: The proto describing the field. + message_name: The name of the containing message. + index: Index of the field + file_desc: The file containing the field descriptor. + is_extension: Indication that this field is for an extension. + + Returns: + An initialized FieldDescriptor object + """ + + if message_name: + full_name = '.'.join((message_name, field_proto.name)) + else: + full_name = field_proto.name + + if field_proto.json_name: + json_name = field_proto.json_name + else: + json_name = None + + return descriptor.FieldDescriptor( + name=field_proto.name, + full_name=full_name, + index=index, + number=field_proto.number, + type=field_proto.type, + cpp_type=None, + message_type=None, + enum_type=None, + containing_type=None, + label=field_proto.label, + has_default_value=False, + default_value=None, + is_extension=is_extension, + extension_scope=None, + options=_OptionsOrNone(field_proto), + json_name=json_name, + file=file_desc, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + + def _SetAllFieldTypes(self, package, desc_proto, scope): + """Sets all the descriptor's fields's types. + + This method also sets the containing types on any extensions. + + Args: + package: The current package of desc_proto. + desc_proto: The message descriptor to update. + scope: Enclosing scope of available types. + """ + + package = _PrefixWithDot(package) + + main_desc = self._GetTypeFromScope(package, desc_proto.name, scope) + + if package == '.': + nested_package = _PrefixWithDot(desc_proto.name) + else: + nested_package = '.'.join([package, desc_proto.name]) + + for field_proto, field_desc in zip(desc_proto.field, main_desc.fields): + self._SetFieldType(field_proto, field_desc, nested_package, scope) + + for extension_proto, extension_desc in zip( + desc_proto.extension, main_desc.extensions + ): + extension_desc.containing_type = self._GetTypeFromScope( + nested_package, extension_proto.extendee, scope + ) + self._SetFieldType(extension_proto, extension_desc, nested_package, scope) + + for nested_type in desc_proto.nested_type: + self._SetAllFieldTypes(nested_package, nested_type, scope) + + def _SetFieldType(self, field_proto, field_desc, package, scope): + """Sets the field's type, cpp_type, message_type and enum_type. + + Args: + field_proto: Data about the field in proto format. + field_desc: The descriptor to modify. + package: The package the field's container is in. + scope: Enclosing scope of available types. + """ + if field_proto.type_name: + desc = self._GetTypeFromScope(package, field_proto.type_name, scope) + else: + desc = None + + if not field_proto.HasField('type'): + if isinstance(desc, descriptor.Descriptor): + field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE + else: + field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM + + field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType( + field_proto.type + ) + + if ( + field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE + or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP + ): + field_desc.message_type = desc + + if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: + field_desc.enum_type = desc + + if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED: + field_desc.has_default_value = False + field_desc.default_value = [] + elif field_proto.HasField('default_value'): + field_desc.has_default_value = True + if ( + field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE + or field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT + ): + field_desc.default_value = float(field_proto.default_value) + elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: + field_desc.default_value = field_proto.default_value + elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: + field_desc.default_value = field_proto.default_value.lower() == 'true' + elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: + field_desc.default_value = field_desc.enum_type.values_by_name[ + field_proto.default_value + ].number + elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: + field_desc.default_value = text_encoding.CUnescape( + field_proto.default_value + ) + elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: + field_desc.default_value = None + else: + # All other types are of the "int" type. + field_desc.default_value = int(field_proto.default_value) + else: + field_desc.has_default_value = False + if ( + field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE + or field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT + ): + field_desc.default_value = 0.0 + elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: + field_desc.default_value = '' + elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: + field_desc.default_value = False + elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: + field_desc.default_value = field_desc.enum_type.values[0].number + elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: + field_desc.default_value = b'' + elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: + field_desc.default_value = None + elif field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP: + field_desc.default_value = None + else: + # All other types are of the "int" type. + field_desc.default_value = 0 + + field_desc.type = field_proto.type + + def _MakeEnumValueDescriptor(self, value_proto, index): + """Creates a enum value descriptor object from a enum value proto. + + Args: + value_proto: The proto describing the enum value. + index: The index of the enum value. + + Returns: + An initialized EnumValueDescriptor object. + """ + + return descriptor.EnumValueDescriptor( + name=value_proto.name, + index=index, + number=value_proto.number, + options=_OptionsOrNone(value_proto), + type=None, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + + def _MakeServiceDescriptor( + self, service_proto, service_index, scope, package, file_desc + ): + """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto. + + Args: + service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message. + service_index: The index of the service in the File. + scope: Dict mapping short and full symbols to message and enum types. + package: Optional package name for the new message EnumDescriptor. + file_desc: The file containing the service descriptor. + + Returns: + The added descriptor. + """ + + if package: + service_name = '.'.join((package, service_proto.name)) + else: + service_name = service_proto.name + + methods = [ + self._MakeMethodDescriptor( + method_proto, service_name, package, scope, index + ) + for index, method_proto in enumerate(service_proto.method) + ] + desc = descriptor.ServiceDescriptor( + name=service_proto.name, + full_name=service_name, + index=service_index, + methods=methods, + options=_OptionsOrNone(service_proto), + file=file_desc, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + self._CheckConflictRegister(desc, desc.full_name, desc.file.name) + self._service_descriptors[service_name] = desc + return desc + + def _MakeMethodDescriptor( + self, method_proto, service_name, package, scope, index + ): + """Creates a method descriptor from a MethodDescriptorProto. + + Args: + method_proto: The proto describing the method. + service_name: The name of the containing service. + package: Optional package name to look up for types. + scope: Scope containing available types. + index: Index of the method in the service. + + Returns: + An initialized MethodDescriptor object. + """ + full_name = '.'.join((service_name, method_proto.name)) + input_type = self._GetTypeFromScope(package, method_proto.input_type, scope) + output_type = self._GetTypeFromScope( + package, method_proto.output_type, scope + ) + return descriptor.MethodDescriptor( + name=method_proto.name, + full_name=full_name, + index=index, + containing_service=None, + input_type=input_type, + output_type=output_type, + client_streaming=method_proto.client_streaming, + server_streaming=method_proto.server_streaming, + options=_OptionsOrNone(method_proto), + # pylint: disable=protected-access + create_key=descriptor._internal_create_key, + ) + + def _ExtractSymbols(self, descriptors): + """Pulls out all the symbols from descriptor protos. + + Args: + descriptors: The messages to extract descriptors from. + + Yields: + A two element tuple of the type name and descriptor object. + """ + + for desc in descriptors: + yield (_PrefixWithDot(desc.full_name), desc) + for symbol in self._ExtractSymbols(desc.nested_types): + yield symbol + for enum in desc.enum_types: + yield (_PrefixWithDot(enum.full_name), enum) + + def _GetDeps(self, dependencies, visited=None): + """Recursively finds dependencies for file protos. + + Args: + dependencies: The names of the files being depended on. + visited: The names of files already found. + + Yields: + Each direct and indirect dependency. + """ + + visited = visited or set() + for dependency in dependencies: + if dependency not in visited: + visited.add(dependency) + dep_desc = self.FindFileByName(dependency) + yield dep_desc + public_files = [d.name for d in dep_desc.public_dependencies] + yield from self._GetDeps(public_files, visited) + + def _GetTypeFromScope(self, package, type_name, scope): + """Finds a given type name in the current scope. + + Args: + package: The package the proto should be located in. + type_name: The name of the type to be found in the scope. + scope: Dict mapping short and full symbols to message and enum types. + + Returns: + The descriptor for the requested type. + """ + if type_name not in scope: + components = _PrefixWithDot(package).split('.') + while components: + possible_match = '.'.join(components + [type_name]) + if possible_match in scope: + type_name = possible_match + break + else: + components.pop(-1) + return scope[type_name] + + +def _PrefixWithDot(name): + return name if name.startswith('.') else '.%s' % name + + +if _USE_C_DESCRIPTORS: + # TODO: This pool could be constructed from Python code, when we + # support a flag like 'use_cpp_generated_pool=True'. + # pylint: disable=protected-access + _DEFAULT = descriptor._message.default_pool +else: + _DEFAULT = DescriptorPool() + + +def Default(): + return _DEFAULT diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py new file mode 100644 index 00000000000..da6d2f3187f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py @@ -0,0 +1,100 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +"""Contains the Duration helper APIs.""" + +import datetime + +from opentelemetry.agent._vendor.google.protobuf.duration_pb2 import Duration + + +def from_json_string(value: str) -> Duration: + """Converts a string to Duration. + + Args: + value: A string to be converted. The string must end with 's'. Any + fractional digits (or none) are accepted as long as they fit into + precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s" + + Raises: + ValueError: On parsing problems. + """ + duration = Duration() + duration.FromJsonString(value) + return duration + + +def from_microseconds(micros: float) -> Duration: + """Converts microseconds to Duration.""" + duration = Duration() + duration.FromMicroseconds(micros) + return duration + + +def from_milliseconds(millis: float) -> Duration: + """Converts milliseconds to Duration.""" + duration = Duration() + duration.FromMilliseconds(millis) + return duration + + +def from_nanoseconds(nanos: float) -> Duration: + """Converts nanoseconds to Duration.""" + duration = Duration() + duration.FromNanoseconds(nanos) + return duration + + +def from_seconds(seconds: float) -> Duration: + """Converts seconds to Duration.""" + duration = Duration() + duration.FromSeconds(seconds) + return duration + + +def from_timedelta(td: datetime.timedelta) -> Duration: + """Converts timedelta to Duration.""" + duration = Duration() + duration.FromTimedelta(td) + return duration + + +def to_json_string(duration: Duration) -> str: + """Converts Duration to string format. + + Returns: + A string converted from self. The string format will contains + 3, 6, or 9 fractional digits depending on the precision required to + represent the exact Duration value. For example: "1s", "1.010s", + "1.000000100s", "-3.100s" + """ + return duration.ToJsonString() + + +def to_microseconds(duration: Duration) -> int: + """Converts a Duration to microseconds.""" + return duration.ToMicroseconds() + + +def to_milliseconds(duration: Duration) -> int: + """Converts a Duration to milliseconds.""" + return duration.ToMilliseconds() + + +def to_nanoseconds(duration: Duration) -> int: + """Converts a Duration to nanoseconds.""" + return duration.ToNanoseconds() + + +def to_seconds(duration: Duration) -> int: + """Converts a Duration to seconds.""" + return duration.ToSeconds() + + +def to_timedelta(duration: Duration) -> datetime.timedelta: + """Converts Duration to timedelta.""" + return duration.ToTimedelta() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py new file mode 100644 index 00000000000..42bcce9c456 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/duration.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/duration.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/duration.proto\x12\x0fgoogle.protobuf\":\n\x08\x44uration\x12\x18\n\x07seconds\x18\x01 \x01(\x03R\x07seconds\x12\x14\n\x05nanos\x18\x02 \x01(\x05R\x05nanosB\x83\x01\n\x13\x63om.google.protobufB\rDurationProtoP\x01Z1google.golang.org/protobuf/types/known/durationpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.duration_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\rDurationProtoP\001Z1google.golang.org/protobuf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_DURATION']._serialized_start=51 + _globals['_DURATION']._serialized_end=109 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py new file mode 100644 index 00000000000..4c0ea6d2df6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/empty.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/empty.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bgoogle/protobuf/empty.proto\x12\x0fgoogle.protobuf\"\x07\n\x05\x45mptyB}\n\x13\x63om.google.protobufB\nEmptyProtoP\x01Z.google.golang.org/protobuf/types/known/emptypb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.empty_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\nEmptyProtoP\001Z.google.golang.org/protobuf/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_EMPTY']._serialized_start=48 + _globals['_EMPTY']._serialized_end=55 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py new file mode 100644 index 00000000000..5c7fd0002b1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/field_mask.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/field_mask.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/field_mask.proto\x12\x0fgoogle.protobuf\"!\n\tFieldMask\x12\x14\n\x05paths\x18\x01 \x03(\tR\x05pathsB\x85\x01\n\x13\x63om.google.protobufB\x0e\x46ieldMaskProtoP\x01Z2google.golang.org/protobuf/types/known/fieldmaskpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.field_mask_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\016FieldMaskProtoP\001Z2google.golang.org/protobuf/types/known/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_FIELDMASK']._serialized_start=53 + _globals['_FIELDMASK']._serialized_end=86 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py new file mode 100644 index 00000000000..80d99fe5b1f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py @@ -0,0 +1,6 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py new file mode 100644 index 00000000000..ae716eea5d8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py @@ -0,0 +1,72 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Determine which implementation of the protobuf API is used in this process.""" + +import os +import sys +import warnings + +_GOOGLE3_PYTHON_UPB_DEFAULT = True + + +def _ApiVersionToImplementationType(api_version): + if api_version == 2: + return 'cpp' + if api_version == 1: + raise ValueError('api_version=1 is no longer supported.') + if api_version == 0: + return 'python' + return None + + +# Only the vendored upb extension is considered (platform builds of the agent include it; +# the pure-Python build doesn't). Never probe for the application's google._upb / +# google.protobuf.pyext by their top-level names, and don't follow +# PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which configures the application's protobuf +# (e.g. "cpp" would make descriptor.py import the missing vendored pyext._message). +try: + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google._upb import _message as _c_module + + _implementation_type = 'upb' +except ImportError: + _implementation_type = 'python' + _c_module = None + +# Detect if serialization should be deterministic by default +try: + # The presence of this module in a build allows the proto implementation to + # be upgraded merely via build deps. + # + # NOTE: Merely importing this automatically enables deterministic proto + # serialization for C++ code, but we still need to export it as a boolean so + # that we can do the same for `_implementation_type == 'python'`. + # + # NOTE2: It is possible for C++ code to enable deterministic serialization by + # default _without_ affecting Python code, if the C++ implementation is not in + # use by this module. That is intended behavior, so we don't actually expose + # this boolean outside of this module. + # + # pylint: disable=g-import-not-at-top,unused-import + from opentelemetry.agent._vendor.google.protobuf import enable_deterministic_proto_serialization + + _python_deterministic_proto_serialization = True +except ImportError: + _python_deterministic_proto_serialization = False + + +# Usage of this function is discouraged. Clients shouldn't care which +# implementation of the API is in use. Note that there is no guarantee +# that differences between APIs will be maintained. +# Please don't use this function if possible. +def Type(): + return _implementation_type + + +# For internal use only +def IsPythonDefaultSerializationDeterministic(): + return _python_deterministic_proto_serialization diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py new file mode 100644 index 00000000000..c8e81f9a218 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py @@ -0,0 +1,123 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Builds descriptors, message classes and services for generated _pb2.py. + +This file is only called in python generated _pb2.py files. It builds +descriptors, message classes and services that users can directly use +in generated code. +""" + +__author__ = 'jieluo@google.com (Jie Luo)' + +from opentelemetry.agent._vendor.google.protobuf import message as _message +from opentelemetry.agent._vendor.google.protobuf import reflection as _reflection +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import enum_type_wrapper +from opentelemetry.agent._vendor.google.protobuf.internal import python_message + +_sym_db = _symbol_database.Default() + + +def _BuildNestedDescriptors(module, msg_des, prefix): + for name, nested_msg in msg_des.nested_types_by_name.items(): + module_name = prefix + name.upper() + module[module_name] = nested_msg + _BuildNestedDescriptors(module, nested_msg, module_name + '_') + for enum_des in msg_des.enum_types: + module[prefix + enum_des.name.upper()] = enum_des + + +def BuildMessageAndEnumDescriptors(file_des, module): + """Builds message and enum descriptors. + + Args: + file_des: FileDescriptor of the .proto file + module: Generated _pb2 module + """ + for name, msg_des in file_des.message_types_by_name.items(): + module_name = '_' + name.upper() + module[module_name] = msg_des + _BuildNestedDescriptors(module, msg_des, module_name + '_') + + +def _BuildMessage(module_name, msg_des, prefix): + create_dict = {} + for name, nested_msg in msg_des.nested_types_by_name.items(): + create_dict[name] = _BuildMessage( + module_name, nested_msg, prefix + msg_des.name + '.' + ) + create_dict['DESCRIPTOR'] = msg_des + create_dict['__module__'] = module_name + create_dict['__qualname__'] = prefix + msg_des.name + message_class = _reflection.GeneratedProtocolMessageType( + msg_des.name, (_message.Message,), create_dict + ) + _sym_db.RegisterMessage(message_class) + return message_class + + +def BuildTopDescriptorsAndMessages(file_des, module_name, module): + """Builds top level descriptors and message classes. + + Args: + file_des: FileDescriptor of the .proto file + module_name: str, the name of generated _pb2 module + module: Generated _pb2 module + """ + + # top level enums + for name, enum_des in file_des.enum_types_by_name.items(): + module['_' + name.upper()] = enum_des + module[name] = enum_type_wrapper.EnumTypeWrapper(enum_des) + for enum_value in enum_des.values: + module[enum_value.name] = enum_value.number + + # top level extensions + for name, extension_des in file_des.extensions_by_name.items(): + module[name.upper() + '_FIELD_NUMBER'] = extension_des.number + module[name] = extension_des + + # services + for name, service in file_des.services_by_name.items(): + module['_' + name.upper()] = service + + # Build messages. + for name, msg_des in file_des.message_types_by_name.items(): + module[name] = _BuildMessage(module_name, msg_des, '') + + +def AddHelpersToExtensions(file_des): + """no-op to keep old generated code work with new runtime. + + Args: + file_des: FileDescriptor of the .proto file + """ + # TODO: Remove this on-op + return + + +def BuildServices(file_des, module_name, module): + """Builds services classes and services stub class. + + Args: + file_des: FileDescriptor of the .proto file + module_name: str, the name of generated _pb2 module + module: Generated _pb2 module + """ + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import service_reflection + # pylint: enable=g-import-not-at-top + for name, service in file_des.services_by_name.items(): + module[name] = service_reflection.GeneratedServiceType( + name, (), dict(DESCRIPTOR=service, __module__=module_name) + ) + stub_name = name + '_Stub' + module[stub_name] = service_reflection.GeneratedServiceStubType( + stub_name, + (module[name],), + dict(DESCRIPTOR=service, __module__=module_name), + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py new file mode 100644 index 00000000000..18539ae1c2d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py @@ -0,0 +1,826 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains container classes to represent different protocol buffer types. + +This file defines container classes which represent categories of protocol +buffer field types which need extra maintenance. Currently these categories +are: + +- Repeated scalar fields - These are all repeated fields which aren't + composite (e.g. they are of simple types like int32, string, etc). +- Repeated composite fields - Repeated fields which are composite. This + includes groups and nested messages. +""" + +import collections.abc +import copy +import pickle +import warnings +from typing import ( + Any, + Iterable, + Iterator, + List, + MutableMapping, + MutableSequence, + NoReturn, + Optional, + Sequence, + TypeVar, + Union, + overload, +) + +_T = TypeVar('_T') +_K = TypeVar('_K') +_V = TypeVar('_V') + +from opentelemetry.agent._vendor.google.protobuf.descriptor import FieldDescriptor +from opentelemetry.agent._vendor.google.protobuf import message + + +def _CheckFrozen(is_frozen: bool, msg: str) -> None: + if is_frozen: + warnings.warn( + 'Mutating messages or containers returned by GetOptions() is' + ' deprecated and will raise an exception in a future release.', + category=FutureWarning, + stacklevel=3, + ) + + +class BaseContainer(Sequence[_T]): + """Base container class.""" + + # Minimizes memory usage and disallows assignment to other attributes. + __slots__ = ['_message_listener', '_values', '_frozen'] + + def __init__(self, message_listener: Any) -> None: + """Args: + + message_listener: A MessageListener implementation. + The RepeatedScalarFieldContainer will call this object's + Modified() method when it is modified. + """ + self._message_listener = message_listener + self._values = [] + self._frozen = False + + @overload + def __getitem__(self, key: int) -> _T: + ... + + @overload + def __getitem__(self, key: slice) -> List[_T]: + ... + + def __getitem__(self, key): + """Retrieves item by the specified key.""" + return self._values[key] + + def __len__(self) -> int: + """Returns the number of elements in the container.""" + return len(self._values) + + def __ne__(self, other: Any) -> bool: + """Checks if another instance isn't equal to this one.""" + # The concrete classes should define __eq__. + return not self == other + + __hash__ = None + + def __repr__(self) -> str: + return repr(self._values) + + def _SetFrozen(self) -> None: + self._frozen = True + + def _AssureWritable(self) -> 'BaseContainer[_T]': + _CheckFrozen(self._frozen, 'Container is immutable') + return self + + def sort(self, *args, **kwargs) -> None: + self._AssureWritable() + # Continue to support the old sort_function keyword argument. + # This is expected to be a rare occurrence, so use LBYL to avoid + # the overhead of actually catching KeyError. + if 'sort_function' in kwargs: + kwargs['cmp'] = kwargs.pop('sort_function') + self._values.sort(*args, **kwargs) + + def reverse(self) -> None: + self._AssureWritable() + self._values.reverse() + + +# TODO: Remove this. BaseContainer does *not* conform to +# MutableSequence, only its subclasses do. +collections.abc.MutableSequence.register(BaseContainer) + + +class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]): + """Simple, type-checked, list-like container for holding repeated scalars.""" + + # Disallows assignment to other attributes. + __slots__ = ['_type_checker', '_field'] + + def __init__( + self, + message_listener: Any, + type_checker: Any, + field: Any = None, + ) -> None: + """Args: + + message_listener: A MessageListener implementation. The + RepeatedScalarFieldContainer will call this object's Modified() method + when it is modified. + type_checker: A type_checkers.ValueChecker instance to run on elements + inserted into this container. + """ + super().__init__(message_listener) + self._type_checker = type_checker + self._field = field + + def append(self, value: _T) -> None: + """Appends an item to the list. Similar to list.append().""" + self._AssureWritable() + self._values.append(self._type_checker.CheckValue(value)) + if not self._message_listener.dirty: + self._message_listener.Modified() + + def insert(self, key: int, value: _T) -> None: + """Inserts the item at the specified position. Similar to list.insert().""" + self._AssureWritable() + self._values.insert(key, self._type_checker.CheckValue(value)) + if not self._message_listener.dirty: + self._message_listener.Modified() + + def extend(self, elem_seq: Iterable[_T]) -> None: + """Extends by appending the given iterable. Similar to list.extend().""" + self._AssureWritable() + elem_seq_iter = iter(elem_seq) + new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter] + if new_values: + self._values.extend(new_values) + self._message_listener.Modified() + + def MergeFrom( + self, + other: Union['RepeatedScalarFieldContainer[_T]', Iterable[_T]], + ) -> None: + """Appends the contents of another repeated field of the same type to this + + one. We do not check the types of the individual fields. + """ + self._AssureWritable() + self._values.extend(other) + self._message_listener.Modified() + + def remove(self, elem: _T): + """Removes an item from the list. Similar to list.remove().""" + self._AssureWritable() + self._values.remove(elem) + self._message_listener.Modified() + + def pop(self, key: Optional[int] = -1) -> _T: + """Removes and returns an item at a given index. Similar to list.pop().""" + self._AssureWritable() + value = self._values[key] + self.__delitem__(key) + return value + + @overload + def __setitem__(self, key: int, value: _T) -> None: + ... + + @overload + def __setitem__(self, key: slice, value: Iterable[_T]) -> None: + ... + + def __setitem__(self, key, value) -> None: + """Sets the item on the specified position.""" + self._AssureWritable() + if isinstance(key, slice): + if key.step is not None: + raise ValueError('Extended slices not supported') + self._values[key] = map(self._type_checker.CheckValue, value) + self._message_listener.Modified() + else: + self._values[key] = self._type_checker.CheckValue(value) + self._message_listener.Modified() + + def __delitem__(self, key: Union[int, slice]) -> None: + """Deletes the item at the specified position.""" + self._AssureWritable() + del self._values[key] + self._message_listener.Modified() + + def __eq__(self, other: Any) -> bool: + """Compares the current instance with another one.""" + if self is other: + return True + # Special case for the same type which should be common and fast. + if isinstance(other, self.__class__): + return other._values == self._values + # We are presumably comparing against some other sequence type. + return other == self._values + + def __deepcopy__( + self, + unused_memo: Any = None, + ) -> 'RepeatedScalarFieldContainer[_T]': + clone = RepeatedScalarFieldContainer( + copy.deepcopy(self._message_listener), self._type_checker, self._field + ) + clone.MergeFrom(self) + return clone + + def __reduce__(self, **kwargs) -> NoReturn: + raise pickle.PickleError( + "Can't pickle repeated scalar fields, convert to list first" + ) + + def __array__(self, dtype=None, copy=None): + import numpy as np + + if dtype is None: + cpp_type = self._field.cpp_type + if cpp_type == FieldDescriptor.CPPTYPE_INT32: + dtype = np.int32 + elif cpp_type == FieldDescriptor.CPPTYPE_INT64: + dtype = np.int64 + elif cpp_type == FieldDescriptor.CPPTYPE_UINT32: + dtype = np.uint32 + elif cpp_type == FieldDescriptor.CPPTYPE_UINT64: + dtype = np.uint64 + elif cpp_type == FieldDescriptor.CPPTYPE_DOUBLE: + dtype = np.float64 + elif cpp_type == FieldDescriptor.CPPTYPE_FLOAT: + dtype = np.float32 + elif cpp_type == FieldDescriptor.CPPTYPE_BOOL: + dtype = np.bool + elif cpp_type == FieldDescriptor.CPPTYPE_ENUM: + dtype = np.int32 + elif self._field.type == FieldDescriptor.TYPE_BYTES: + dtype = 'S' + elif self._field.type == FieldDescriptor.TYPE_STRING: + dtype = str + else: + raise SystemError( + 'Code should never reach here: message type detected in' + ' RepeatedScalarFieldContainer' + ) + return np.array(self._values, dtype=dtype, copy=True) + + +# TODO: Constrain T to be a subtype of Message. +class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]): + """Simple, list-like container for holding repeated composite fields.""" + + # Disallows assignment to other attributes. + __slots__ = ['_message_descriptor'] + + def __init__(self, message_listener: Any, message_descriptor: Any) -> None: + """Note that we pass in a descriptor instead of the generated directly, + + since at the time we construct a _RepeatedCompositeFieldContainer we + haven't yet necessarily initialized the type that will be contained in the + container. + + Args: + message_listener: A MessageListener implementation. The + RepeatedCompositeFieldContainer will call this object's Modified() + method when it is modified. + message_descriptor: A Descriptor instance describing the protocol type + that should be present in this container. We'll use the _concrete_class + field of this descriptor when the client calls add(). + """ + super().__init__(message_listener) + self._message_descriptor = message_descriptor + + def _SetFrozen(self) -> None: + super()._SetFrozen() + for val in self._values: + val._SetFrozen() + + def add(self, **kwargs: Any) -> _T: + """Adds a new element at the end of the list and returns it. + + Keyword arguments may be used to initialize the element. + """ + self._AssureWritable() + new_element = self._message_descriptor._concrete_class(**kwargs) + new_element._SetListener(self._message_listener) + self._values.append(new_element) + if not self._message_listener.dirty: + self._message_listener.Modified() + return new_element + + def append(self, value: _T) -> None: + """Appends one element by copying the message.""" + self._AssureWritable() + new_element = self._message_descriptor._concrete_class() + new_element._SetListener(self._message_listener) + new_element.CopyFrom(value) + self._values.append(new_element) + if not self._message_listener.dirty: + self._message_listener.Modified() + + def insert(self, key: int, value: _T) -> None: + """Inserts the item at the specified position by copying.""" + self._AssureWritable() + new_element = self._message_descriptor._concrete_class() + new_element._SetListener(self._message_listener) + new_element.CopyFrom(value) + self._values.insert(key, new_element) + if not self._message_listener.dirty: + self._message_listener.Modified() + + def extend(self, elem_seq: Iterable[_T]) -> None: + """Extends by appending the given sequence of elements of the same type + + as this one, copying each individual message. + """ + self._AssureWritable() + message_class = self._message_descriptor._concrete_class + listener = self._message_listener + values = self._values + for message in elem_seq: + new_element = message_class() + new_element._SetListener(listener) + new_element.MergeFrom(message) + values.append(new_element) + listener.Modified() + + def MergeFrom( + self, + other: Union['RepeatedCompositeFieldContainer[_T]', Iterable[_T]], + ) -> None: + """Appends the contents of another repeated field of the same type to this + + one, copying each individual message. + """ + self._AssureWritable() + self.extend(other) + + def remove(self, elem: _T) -> None: + """Removes an item from the list. Similar to list.remove().""" + self._AssureWritable() + self._values.remove(elem) + self._message_listener.Modified() + + def pop(self, key: Optional[int] = -1) -> _T: + """Removes and returns an item at a given index. Similar to list.pop().""" + self._AssureWritable() + value = self._values[key] + self.__delitem__(key) + return value + + @overload + def __setitem__(self, key: int, value: _T) -> None: + ... + + @overload + def __setitem__(self, key: slice, value: Iterable[_T]) -> None: + ... + + def __setitem__(self, key, value): + # This method is implemented to make RepeatedCompositeFieldContainer + # structurally compatible with typing.MutableSequence. It is + # otherwise unsupported and will always raise an error. + raise TypeError( + f'{self.__class__.__name__} object does not support item assignment' + ) + + def __delitem__(self, key: Union[int, slice]) -> None: + """Deletes the item at the specified position.""" + self._AssureWritable() + del self._values[key] + self._message_listener.Modified() + + def __eq__(self, other: Any) -> bool: + """Compares the current instance with another one.""" + if self is other: + return True + if not isinstance(other, self.__class__): + raise TypeError( + 'Can only compare repeated composite fields against ' + 'other repeated composite fields.' + ) + return self._values == other._values + + +class ScalarMap(MutableMapping[_K, _V]): + """Simple, type-checked, dict-like container for holding repeated scalars.""" + + # Disallows assignment to other attributes. + __slots__ = [ + '_key_checker', + '_value_checker', + '_values', + '_message_listener', + '_entry_descriptor', + '_frozen', + ] + + def __init__( + self, + message_listener: Any, + key_checker: Any, + value_checker: Any, + entry_descriptor: Any, + ) -> None: + """Args: + + message_listener: A MessageListener implementation. + The ScalarMap will call this object's Modified() method when it + is modified. + key_checker: A type_checkers.ValueChecker instance to run on keys + inserted into this container. + value_checker: A type_checkers.ValueChecker instance to run on values + inserted into this container. + entry_descriptor: The MessageDescriptor of a map entry: key and value. + """ + self._message_listener = message_listener + self._key_checker = key_checker + self._value_checker = value_checker + self._entry_descriptor = entry_descriptor + self._values = {} + self._frozen = False + + def _SetFrozen(self) -> None: + self._frozen = True + + def _AssureWritable(self) -> 'ScalarMap[_K, _V]': + _CheckFrozen(self._frozen, 'Map is immutable') + return self + + def __getitem__(self, key: _K) -> _V: + key = self._key_checker.CheckValue(key) + try: + return self._values[key] + except KeyError: + self._AssureWritable() + val = self._value_checker.DefaultValue() + self._values[key] = val + return val + + def __contains__(self, item: _K) -> bool: + # We check the key's type to match the strong-typing flavor of the API. + # Also this makes it easier to match the behavior of the C++ implementation. + item = self._key_checker.CheckValue(item) + return item in self._values + + @overload + def get(self, key: _K) -> Optional[_V]: + ... + + @overload + def get(self, key: _K, default: _T) -> Union[_V, _T]: + ... + + # We need to override this explicitly, because our defaultdict-like behavior + # will make the default implementation (from our base class) always insert + # the key. + def get(self, key, default=None): + checked_key = self._key_checker.CheckValue(key) + if checked_key in self._values: + return self[checked_key] + else: + return default + + def __setitem__(self, key: _K, value: _V) -> _T: + self._AssureWritable() + checked_key = self._key_checker.CheckValue(key) + checked_value = self._value_checker.CheckValue(value) + self._values[checked_key] = checked_value + self._message_listener.Modified() + + def __delitem__(self, key: _K) -> None: + self._AssureWritable() + checked_key = self._key_checker.CheckValue(key) + del self._values[checked_key] + self._message_listener.Modified() + + def __len__(self) -> int: + return len(self._values) + + def __iter__(self) -> Iterator[_K]: + return iter(self._values) + + def __repr__(self) -> str: + return repr(self._values) + + def setdefault(self, key: _K, value: Optional[_V] = None) -> _V: + self._AssureWritable() + checked_key = self._key_checker.CheckValue(key) + if value == None: + raise ValueError('The value for scalar map setdefault must be set.') + if checked_key not in self._values: + self.__setitem__(checked_key, value) + return self[key] + + def MergeFrom(self, other: 'ScalarMap[_K, _V]') -> None: + self._AssureWritable() + self._values.update(other._values) + self._message_listener.Modified() + + def InvalidateIterators(self) -> None: + # It appears that the only way to reliably invalidate iterators to + # self._values is to ensure that its size changes. + original = self._values + self._values = original.copy() + original[None] = None + + # This is defined in the abstract base, but we can do it much more cheaply. + def clear(self) -> None: + self._AssureWritable() + self._values.clear() + self._message_listener.Modified() + + def GetEntryClass(self) -> Any: + return self._entry_descriptor._concrete_class + + +class MessageMap(MutableMapping[_K, _V]): + """Simple, type-checked, dict-like container for with submessage values.""" + + # Disallows assignment to other attributes. + __slots__ = [ + '_key_checker', + '_values', + '_message_listener', + '_message_descriptor', + '_entry_descriptor', + '_frozen', + ] + + def __init__( + self, + message_listener: Any, + message_descriptor: Any, + key_checker: Any, + entry_descriptor: Any, + ) -> None: + """Args: + + message_listener: A MessageListener implementation. + The ScalarMap will call this object's Modified() method when it + is modified. + key_checker: A type_checkers.ValueChecker instance to run on keys + inserted into this container. + value_checker: A type_checkers.ValueChecker instance to run on values + inserted into this container. + entry_descriptor: The MessageDescriptor of a map entry: key and value. + """ + self._message_listener = message_listener + self._message_descriptor = message_descriptor + self._key_checker = key_checker + self._entry_descriptor = entry_descriptor + self._values = {} + self._frozen = False + + def _SetFrozen(self) -> None: + self._frozen = True + for val in self._values.values(): + val._SetFrozen() + + def _AssureWritable(self) -> 'MessageMap[_K, _V]': + _CheckFrozen(self._frozen, 'Map is immutable') + return self + + def __getitem__(self, key: _K) -> _V: + key = self._key_checker.CheckValue(key) + try: + return self._values[key] + except KeyError: + self._AssureWritable() + new_element = self._message_descriptor._concrete_class() + new_element._SetListener(self._message_listener) + self._values[key] = new_element + self._message_listener.Modified() + return new_element + + def get_or_create(self, key: _K) -> _V: + """get_or_create() is an alias for getitem (ie. map[key]). + + Args: + key: The key to get or create in the map. + + This is useful in cases where you want to be explicit that the call is + mutating the map. This can avoid lint errors for statements like this + that otherwise would appear to be pointless statements: + + msg.my_map[key] + """ + return self[key] + + @overload + def get(self, key: _K) -> Optional[_V]: + ... + + @overload + def get(self, key: _K, default: _T) -> Union[_V, _T]: + ... + + # We need to override this explicitly, because our defaultdict-like behavior + # will make the default implementation (from our base class) always insert + # the key. + def get(self, key, default=None): + if key in self: + return self[key] + else: + return default + + def __contains__(self, item: _K) -> bool: + item = self._key_checker.CheckValue(item) + return item in self._values + + def __setitem__(self, key: _K, value: _V) -> NoReturn: + self._AssureWritable() + raise ValueError('May not set values directly, call my_map[key].foo = 5') + + def __delitem__(self, key: _K) -> None: + self._AssureWritable() + key = self._key_checker.CheckValue(key) + del self._values[key] + self._message_listener.Modified() + + def __len__(self) -> int: + return len(self._values) + + def __iter__(self) -> Iterator[_K]: + return iter(self._values) + + def __repr__(self) -> str: + return repr(self._values) + + def setdefault(self, key: _K, value: Optional[_V] = None) -> _V: + self._AssureWritable() + raise NotImplementedError( + 'Set message map value directly is not supported, call' + ' my_map[key].foo = 5' + ) + + def MergeFrom(self, other: 'MessageMap[_K, _V]') -> None: + self._AssureWritable() + # pylint: disable=protected-access + for key in other._values: + # According to documentation: "When parsing from the wire or when merging, + # if there are duplicate map keys the last key seen is used". + if key in self: + del self[key] + self[key].CopyFrom(other[key]) + # self._message_listener.Modified() not required here, because + # mutations to submessages already propagate. + + def InvalidateIterators(self) -> None: + # It appears that the only way to reliably invalidate iterators to + # self._values is to ensure that its size changes. + original = self._values + self._values = original.copy() + original[None] = None + + # This is defined in the abstract base, but we can do it much more cheaply. + def clear(self) -> None: + self._AssureWritable() + self._values.clear() + self._message_listener.Modified() + + def GetEntryClass(self) -> Any: + return self._entry_descriptor._concrete_class + + +class _UnknownField: + """A parsed unknown field.""" + + # Disallows assignment to other attributes. + __slots__ = ['_field_number', '_wire_type', '_data'] + + def __init__(self, field_number, wire_type, data): + self._field_number = field_number + self._wire_type = wire_type + self._data = data + return + + def __lt__(self, other): + # pylint: disable=protected-access + return self._field_number < other._field_number + + def __eq__(self, other): + if self is other: + return True + # pylint: disable=protected-access + return ( + self._field_number == other._field_number + and self._wire_type == other._wire_type + and self._data == other._data + ) + + +class UnknownFieldRef: # pylint: disable=missing-class-docstring + + def __init__(self, parent, index): + self._parent = parent + self._index = index + + def _check_valid(self): + if not self._parent: + raise ValueError( + 'UnknownField does not exist. The parent message might be cleared.' + ) + if self._index >= len(self._parent): + raise ValueError( + 'UnknownField does not exist. The parent message might be cleared.' + ) + + @property + def field_number(self): + self._check_valid() + # pylint: disable=protected-access + return self._parent._internal_get(self._index)._field_number + + @property + def wire_type(self): + self._check_valid() + # pylint: disable=protected-access + return self._parent._internal_get(self._index)._wire_type + + @property + def data(self): + self._check_valid() + # pylint: disable=protected-access + return self._parent._internal_get(self._index)._data + + +class UnknownFieldSet: + """UnknownField container""" + + # Disallows assignment to other attributes. + __slots__ = ['_values'] + + def __init__(self): + self._values = [] + + def __getitem__(self, index): + if self._values is None: + raise ValueError( + 'UnknownFields does not exist. The parent message might be cleared.' + ) + size = len(self._values) + if index < 0: + index += size + if index < 0 or index >= size: + raise IndexError('index %d out of range'.index) + + return UnknownFieldRef(self, index) + + def _internal_get(self, index): + return self._values[index] + + def __len__(self): + if self._values is None: + raise ValueError( + 'UnknownFields does not exist. The parent message might be cleared.' + ) + return len(self._values) + + def _add(self, field_number, wire_type, data): + unknown_field = _UnknownField(field_number, wire_type, data) + self._values.append(unknown_field) + return unknown_field + + def __iter__(self): + for i in range(len(self)): + yield UnknownFieldRef(self, i) + + def _extend(self, other): + if other is None: + return + # pylint: disable=protected-access + self._values.extend(other._values) + + def __eq__(self, other): + if self is other: + return True + # Sort unknown fields because their order shouldn't + # affect equality test. + values = list(self._values) + if other is None: + return not values + values.sort() + # pylint: disable=protected-access + other_values = sorted(other._values) + return values == other_values + + def _clear(self): + for value in self._values: + # pylint: disable=protected-access + if isinstance(value._data, UnknownFieldSet): + value._data._clear() # pylint: disable=protected-access + self._values = None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py new file mode 100644 index 00000000000..a4a425a61b4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py @@ -0,0 +1,1127 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Code for decoding protocol buffer primitives. + +This code is very similar to encoder.py -- read the docs for that module first. + +A "decoder" is a function with the signature: + Decode(buffer, pos, end, message, field_dict) +The arguments are: + buffer: The string containing the encoded message. + pos: The current position in the string. + end: The position in the string where the current message ends. May be + less than len(buffer) if we're reading a sub-message. + message: The message object into which we're parsing. + field_dict: message._fields (avoids a hashtable lookup). +The decoder reads the field and stores it into field_dict, returning the new +buffer position. A decoder for a repeated field may proactively decode all of +the elements of that field, if they appear consecutively. + +Note that decoders may throw any of the following: + IndexError: Indicates a truncated message. + struct.error: Unpacking of a fixed-width field failed. + message.DecodeError: Other errors. + +Decoders are expected to raise an exception if they are called with pos > end. +This allows callers to be lax about bounds checking: it's fineto read past +"end" as long as you are sure that someone else will notice and throw an +exception later on. + +Something up the call stack is expected to catch IndexError and struct.error +and convert them to message.DecodeError. + +Decoders are constructed using decoder constructors with the signature: + MakeDecoder(field_number, is_repeated, is_packed, key, new_default) +The arguments are: + field_number: The field number of the field we want to decode. + is_repeated: Is the field a repeated field? (bool) + is_packed: Is the field a packed field? (bool) + key: The key to use when looking up the field within field_dict. + (This is actually the FieldDescriptor but nothing in this + file should depend on that.) + new_default: A function which takes a message object as a parameter and + returns a new instance of the default value for this field. + (This is called for repeated fields and sub-messages, when an + instance does not already exist.) + +As with encoders, we define a decoder constructor for every type of field. +Then, for every field of every message class we construct an actual decoder. +That decoder goes into a dict indexed by tag, so when we decode a message +we repeatedly read a tag, look up the corresponding decoder, and invoke it. +""" + +__author__ = 'kenton@google.com (Kenton Varda)' + +import math +import numbers +import struct + +from opentelemetry.agent._vendor.google.protobuf import message +from opentelemetry.agent._vendor.google.protobuf.internal import containers +from opentelemetry.agent._vendor.google.protobuf.internal import encoder +from opentelemetry.agent._vendor.google.protobuf.internal import wire_format + +# This is not for optimization, but rather to avoid conflicts with local +# variables named "message". +_DecodeError = message.DecodeError + + +def IsDefaultScalarValue(value): + """Returns whether or not a scalar value is the default value of its type. + + Specifically, this should be used to determine presence of implicit-presence + fields, where we disallow custom defaults. + + Args: + value: A scalar value to check. + + Returns: + True if the value is equivalent to a default value, False otherwise. + """ + if isinstance(value, numbers.Number) and math.copysign(1.0, value) < 0: + # Special case for negative zero, where "truthiness" fails to give the right + # answer. + return False + + # Normally, we can just use Python's boolean conversion. + return not value + + +def _VarintDecoder(mask, result_type): + """Return an encoder for a basic varint value (does not include tag). + + Decoded values will be bitwise-anded with the given mask before being + returned, e.g. to limit them to 32 bits. The returned decoder does not + take the usual "end" parameter -- the caller is expected to do bounds checking + after the fact (often the caller can defer such checking until later). The + decoder returns a (value, new_pos) pair. + """ + + def DecodeVarint(buffer, pos: int = None): + result = 0 + shift = 0 + while 1: + if pos is None: + # Read from BytesIO + try: + b = buffer.read(1)[0] + except IndexError as e: + if shift == 0: + # End of BytesIO. + return None + else: + raise ValueError('Fail to read varint %s' % str(e)) + else: + b = buffer[pos] + pos += 1 + result |= (b & 0x7F) << shift + if not (b & 0x80): + result &= mask + result = result_type(result) + return result if pos is None else (result, pos) + shift += 7 + if shift >= 64: + raise _DecodeError('Too many bytes when decoding varint.') + + return DecodeVarint + + +def _SignedVarintDecoder(bits, result_type): + """Like _VarintDecoder() but decodes signed values.""" + + signbit = 1 << (bits - 1) + mask = (1 << bits) - 1 + + def DecodeVarint(buffer, pos): + result = 0 + shift = 0 + while 1: + b = buffer[pos] + result |= (b & 0x7F) << shift + pos += 1 + if not (b & 0x80): + result &= mask + result = (result ^ signbit) - signbit + result = result_type(result) + return (result, pos) + shift += 7 + if shift >= 64: + raise _DecodeError('Too many bytes when decoding varint.') + + return DecodeVarint + + +# All 32-bit and 64-bit values are represented as int. +_DecodeVarint = _VarintDecoder((1 << 64) - 1, int) +_DecodeSignedVarint = _SignedVarintDecoder(64, int) + +# Use these versions for values which must be limited to 32 bits. +_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int) +_DecodeSignedVarint32 = _SignedVarintDecoder(32, int) + + +def ReadTag(buffer, pos): + """Read a tag from the memoryview, and return a (tag_bytes, new_pos) tuple. + + We return the raw bytes of the tag rather than decoding them. The raw + bytes can then be used to look up the proper decoder. This effectively allows + us to trade some work that would be done in pure-python (decoding a varint) + for work that is done in C (searching for a byte string in a hash table). + In a low-level language it would be much cheaper to decode the varint and + use that, but not in Python. + + Args: + buffer: memoryview object of the encoded bytes + pos: int of the current position to start from + + Returns: + Tuple[bytes, int] of the tag data and new position. + """ + start = pos + while buffer[pos] & 0x80: + pos += 1 + pos += 1 + + tag_bytes = buffer[start:pos].tobytes() + return tag_bytes, pos + + +def DecodeTag(tag_bytes): + """Decode a tag from the bytes. + + Args: + tag_bytes: the bytes of the tag + + Returns: + Tuple[int, int] of the tag field number and wire type. + """ + tag, _ = _DecodeVarint(tag_bytes, 0) + return wire_format.UnpackTag(tag) + + +# -------------------------------------------------------------------- + + +def _SimpleDecoder(wire_type, decode_value): + """Return a constructor for a decoder for fields of a particular type. + + Args: + wire_type: The field's wire type. + decode_value: A function which decodes an individual value, e.g. + _DecodeVarint() + """ + + def SpecificDecoder( + field_number, + is_repeated, + is_packed, + key, + new_default, + clear_if_default=False, + ): + if is_packed: + local_DecodeVarint = _DecodeVarint + + def DecodePackedField( + buffer, pos, end, message, field_dict, current_depth=0 + ): + del current_depth # unused + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + endpoint, pos = local_DecodeVarint(buffer, pos) + endpoint += pos + if endpoint > end: + raise _DecodeError('Truncated message.') + while pos < endpoint: + element, pos = decode_value(buffer, pos) + value.append(element) + if pos > endpoint: + del value[-1] # Discard corrupt value. + raise _DecodeError('Packed element was truncated.') + return pos + + return DecodePackedField + elif is_repeated: + tag_bytes = encoder.TagBytes(field_number, wire_type) + tag_len = len(tag_bytes) + + def DecodeRepeatedField( + buffer, pos, end, message, field_dict, current_depth=0 + ): + del current_depth # unused + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + element, new_pos = decode_value(buffer, pos) + value.append(element) + # Predict that the next tag is another copy of the same repeated + # field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos >= end: + # Prediction failed. Return. + if new_pos > end: + raise _DecodeError('Truncated message.') + return new_pos + + return DecodeRepeatedField + else: + + def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): + del current_depth # unused + new_value, pos = decode_value(buffer, pos) + if pos > end: + raise _DecodeError('Truncated message.') + if clear_if_default and IsDefaultScalarValue(new_value): + field_dict.pop(key, None) + else: + field_dict[key] = new_value + return pos + + return DecodeField + + return SpecificDecoder + + +def _ModifiedDecoder(wire_type, decode_value, modify_value): + """Like SimpleDecoder but additionally invokes modify_value on every value + + before storing it. Usually modify_value is ZigZagDecode. + """ + + # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but + # not enough to make a significant difference. + + def InnerDecode(buffer, pos): + result, new_pos = decode_value(buffer, pos) + return (modify_value(result), new_pos) + + return _SimpleDecoder(wire_type, InnerDecode) + + +def _StructPackDecoder(wire_type, format): + """Return a constructor for a decoder for a fixed-width field. + + Args: + wire_type: The field's wire type. + format: The format string to pass to struct.unpack(). + """ + + value_size = struct.calcsize(format) + local_unpack = struct.unpack + + # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but + # not enough to make a significant difference. + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + + def InnerDecode(buffer, pos): + new_pos = pos + value_size + result = local_unpack(format, buffer[pos:new_pos])[0] + return (result, new_pos) + + return _SimpleDecoder(wire_type, InnerDecode) + + +def _FloatDecoder(): + """Returns a decoder for a float field. + + This code works around a bug in struct.unpack for non-finite 32-bit + floating-point values. + """ + + local_unpack = struct.unpack + + def InnerDecode(buffer, pos): + """Decode serialized float to a float and new position. + + Args: + buffer: memoryview of the serialized bytes + pos: int, position in the memory view to start at. + + Returns: + Tuple[float, int] of the deserialized float value and new position + in the serialized data. + """ + # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign + # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand. + new_pos = pos + 4 + float_bytes = buffer[pos:new_pos].tobytes() + + # If this value has all its exponent bits set, then it's non-finite. + # In Python 2.4, struct.unpack will convert it to a finite 64-bit value. + # To avoid that, we parse it specially. + if float_bytes[3:4] in b'\x7F\xFF' and float_bytes[2:3] >= b'\x80': + # If at least one significand bit is set... + if float_bytes[0:3] != b'\x00\x00\x80': + return (math.nan, new_pos) + # If sign bit is set... + if float_bytes[3:4] == b'\xFF': + return (-math.inf, new_pos) + return (math.inf, new_pos) + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + result = local_unpack('= b'\xF0') + and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0') + ): + return (math.nan, new_pos) + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + result = local_unpack(' end: + raise _DecodeError('Truncated message.') + while pos < endpoint: + value_start_pos = pos + element, pos = _DecodeSignedVarint32(buffer, pos) + # pylint: disable=protected-access + if element in enum_type.values_by_number: + value.append(element) + else: + if not message._unknown_fields: + message._unknown_fields = [] + tag_bytes = encoder.TagBytes( + field_number, wire_format.WIRETYPE_VARINT + ) + + message._unknown_fields.append( + (tag_bytes, buffer[value_start_pos:pos].tobytes()) + ) + # pylint: enable=protected-access + if pos > endpoint: + if element in enum_type.values_by_number: + del value[-1] # Discard corrupt value. + else: + del message._unknown_fields[-1] + # pylint: enable=protected-access + raise _DecodeError('Packed element was truncated.') + return pos + + return DecodePackedField + elif is_repeated: + tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) + tag_len = len(tag_bytes) + + def DecodeRepeatedField( + buffer, pos, end, message, field_dict, current_depth=0 + ): + """Decode serialized repeated enum to its value and a new position. + + Args: + buffer: memoryview of the serialized bytes. + pos: int, position in the memory view to start at. + end: int, end position of serialized data + message: Message object to store unknown fields in + field_dict: Map[Descriptor, Any] to store decoded values in. + + Returns: + int, new position in serialized data. + """ + del current_depth # unused + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + element, new_pos = _DecodeSignedVarint32(buffer, pos) + # pylint: disable=protected-access + if element in enum_type.values_by_number: + value.append(element) + else: + if not message._unknown_fields: + message._unknown_fields = [] + message._unknown_fields.append( + (tag_bytes, buffer[pos:new_pos].tobytes()) + ) + # pylint: enable=protected-access + # Predict that the next tag is another copy of the same repeated + # field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos >= end: + # Prediction failed. Return. + if new_pos > end: + raise _DecodeError('Truncated message.') + return new_pos + + return DecodeRepeatedField + else: + + def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): + """Decode serialized repeated enum to its value and a new position. + + Args: + buffer: memoryview of the serialized bytes. + pos: int, position in the memory view to start at. + end: int, end position of serialized data + message: Message object to store unknown fields in + field_dict: Map[Descriptor, Any] to store decoded values in. + + Returns: + int, new position in serialized data. + """ + del current_depth # unused + value_start_pos = pos + enum_value, pos = _DecodeSignedVarint32(buffer, pos) + if pos > end: + raise _DecodeError('Truncated message.') + if clear_if_default and IsDefaultScalarValue(enum_value): + field_dict.pop(key, None) + return pos + # pylint: disable=protected-access + if enum_value in enum_type.values_by_number: + field_dict[key] = enum_value + else: + if not message._unknown_fields: + message._unknown_fields = [] + tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) + message._unknown_fields.append( + (tag_bytes, buffer[value_start_pos:pos].tobytes()) + ) + # pylint: enable=protected-access + return pos + + return DecodeField + + +# -------------------------------------------------------------------- + +Int32Decoder = _SimpleDecoder( + wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32 +) + +Int64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint) + +UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) +UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint) + +SInt32Decoder = _ModifiedDecoder( + wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode +) +SInt64Decoder = _ModifiedDecoder( + wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode +) + +# Note that Python conveniently guarantees that when using the '<' prefix on +# formats, they will also have the same size across all platforms (as opposed +# to without the prefix, where their sizes depend on the C compiler's basic +# type sizes). +Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, ' end: + raise _DecodeError('Truncated string.') + value.append(_ConvertToUnicode(buffer[pos:new_pos])) + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + + return DecodeRepeatedField + else: + + def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): + del current_depth # unused + size, pos = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + if clear_if_default and IsDefaultScalarValue(size): + field_dict.pop(key, None) + else: + field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) + return new_pos + + return DecodeField + + +def BytesDecoder( + field_number, + is_repeated, + is_packed, + key, + new_default, + clear_if_default=False, +): + """Returns a decoder for a bytes field.""" + + local_DecodeVarint = _DecodeVarint + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes( + field_number, wire_format.WIRETYPE_LENGTH_DELIMITED + ) + tag_len = len(tag_bytes) + + def DecodeRepeatedField( + buffer, pos, end, message, field_dict, current_depth=0 + ): + del current_depth # unused + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + size, pos = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + value.append(buffer[pos:new_pos].tobytes()) + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + + return DecodeRepeatedField + else: + + def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): + del current_depth # unused + size, pos = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated string.') + if clear_if_default and IsDefaultScalarValue(size): + field_dict.pop(key, None) + else: + field_dict[key] = buffer[pos:new_pos].tobytes() + return new_pos + + return DecodeField + + +def GroupDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a group field.""" + + end_tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_END_GROUP) + end_tag_len = len(end_tag_bytes) + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_START_GROUP) + tag_len = len(tag_bytes) + + def DecodeRepeatedField( + buffer, pos, end, message, field_dict, current_depth=0 + ): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read sub-message. + current_depth += 1 + if current_depth > _recursion_limit: + raise _DecodeError( + 'Error parsing message: too many levels of nesting.' + ) + pos = value.add()._InternalParse(buffer, pos, end, current_depth) + current_depth -= 1 + # Read end tag. + new_pos = pos + end_tag_len + if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: + raise _DecodeError('Missing group end tag.') + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + + return DecodeRepeatedField + else: + + def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read sub-message. + current_depth += 1 + if current_depth > _recursion_limit: + raise _DecodeError('Error parsing message: too many levels of nesting.') + pos = value._InternalParse(buffer, pos, end, current_depth) + current_depth -= 1 + # Read end tag. + new_pos = pos + end_tag_len + if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: + raise _DecodeError('Missing group end tag.') + return new_pos + + return DecodeField + + +def MessageDecoder(field_number, is_repeated, is_packed, key, new_default): + """Returns a decoder for a message field.""" + + local_DecodeVarint = _DecodeVarint + + assert not is_packed + if is_repeated: + tag_bytes = encoder.TagBytes( + field_number, wire_format.WIRETYPE_LENGTH_DELIMITED + ) + tag_len = len(tag_bytes) + + def DecodeRepeatedField( + buffer, pos, end, message, field_dict, current_depth=0 + ): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + # Read length. + size, pos = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated message.') + # Read sub-message. + current_depth += 1 + if current_depth > _recursion_limit: + raise _DecodeError( + 'Error parsing message: too many levels of nesting.' + ) + if ( + value.add()._InternalParse(buffer, pos, new_pos, current_depth) + != new_pos + ): + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + current_depth -= 1 + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + + return DecodeRepeatedField + else: + + def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + # Read length. + size, pos = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated message.') + # Read sub-message. + current_depth += 1 + if current_depth > _recursion_limit: + raise _DecodeError('Error parsing message: too many levels of nesting.') + if value._InternalParse(buffer, pos, new_pos, current_depth) != new_pos: + # The only reason _InternalParse would return early is if it encountered + # an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + current_depth -= 1 + return new_pos + + return DecodeField + + +# -------------------------------------------------------------------- + +MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP) + + +def MessageSetItemDecoder(descriptor): + """Returns a decoder for a MessageSet item. + + The parameter is the message Descriptor. + + The message set message looks like this: + message MessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required string message = 3; + } + } + """ + + type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) + message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) + item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) + + local_ReadTag = ReadTag + local_DecodeVarint = _DecodeVarint + + def DecodeItem(buffer, pos, end, message, field_dict, current_depth=0): + """Decode serialized message set to its value and new position. + + Args: + buffer: memoryview of the serialized bytes. + pos: int, position in the memory view to start at. + end: int, end position of serialized data + message: Message object to store unknown fields in + field_dict: Map[Descriptor, Any] to store decoded values in. + + Returns: + int, new position in serialized data. + """ + message_set_item_start = pos + type_id = -1 + message_start = -1 + message_end = -1 + + # Technically, type_id and message can appear in any order, so we need + # a little loop here. + while 1: + tag_bytes, pos = local_ReadTag(buffer, pos) + if tag_bytes == type_id_tag_bytes: + type_id, pos = local_DecodeVarint(buffer, pos) + elif tag_bytes == message_tag_bytes: + size, message_start = local_DecodeVarint(buffer, pos) + pos = message_end = message_start + size + elif tag_bytes == item_end_tag_bytes: + break + else: + field_number, wire_type = DecodeTag(tag_bytes) + _, pos = _DecodeUnknownField(buffer, pos, end, field_number, wire_type) + if pos == -1: + raise _DecodeError('Unexpected end-group tag.') + + if pos > end: + raise _DecodeError('Truncated message.') + + if type_id == -1: + raise _DecodeError('MessageSet item missing type_id.') + if message_start == -1: + raise _DecodeError('MessageSet item missing message.') + + extension = message.Extensions._FindExtensionByNumber(type_id) + # pylint: disable=protected-access + if extension is not None: + value = field_dict.get(extension) + if value is None: + message_type = extension.message_type + if not hasattr(message_type, '_concrete_class'): + message_factory.GetMessageClass(message_type) + value = field_dict.setdefault(extension, message_type._concrete_class()) + current_depth += 1 + if current_depth > _recursion_limit: + raise _DecodeError('Error parsing message: too many levels of nesting.') + if ( + value._InternalParse( + buffer, message_start, message_end, current_depth + ) + != message_end + ): + # The only reason _InternalParse would return early is if it encountered + # an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + current_depth -= 1 + else: + if not message._unknown_fields: + message._unknown_fields = [] + message._unknown_fields.append( + (MESSAGE_SET_ITEM_TAG, buffer[message_set_item_start:pos].tobytes()) + ) + # pylint: enable=protected-access + + return pos + + return DecodeItem + + +def UnknownMessageSetItemDecoder(): + """Returns a decoder for a Unknown MessageSet item.""" + + type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) + message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) + item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) + + def DecodeUnknownItem(buffer): + pos = 0 + end = len(buffer) + message_start = -1 + message_end = -1 + while 1: + tag_bytes, pos = ReadTag(buffer, pos) + if tag_bytes == type_id_tag_bytes: + type_id, pos = _DecodeVarint(buffer, pos) + elif tag_bytes == message_tag_bytes: + size, message_start = _DecodeVarint(buffer, pos) + pos = message_end = message_start + size + elif tag_bytes == item_end_tag_bytes: + break + else: + field_number, wire_type = DecodeTag(tag_bytes) + _, pos = _DecodeUnknownField(buffer, pos, end, field_number, wire_type) + if pos == -1: + raise _DecodeError('Unexpected end-group tag.') + + if pos > end: + raise _DecodeError('Truncated message.') + + if type_id == -1: + raise _DecodeError('MessageSet item missing type_id.') + if message_start == -1: + raise _DecodeError('MessageSet item missing message.') + + return (type_id, buffer[message_start:message_end].tobytes()) + + return DecodeUnknownItem + + +# -------------------------------------------------------------------- + + +def MapDecoder(field_descriptor, new_default, is_message_map): + """Returns a decoder for a map field.""" + + key = field_descriptor + tag_bytes = encoder.TagBytes( + field_descriptor.number, wire_format.WIRETYPE_LENGTH_DELIMITED + ) + tag_len = len(tag_bytes) + local_DecodeVarint = _DecodeVarint + # Can't read _concrete_class yet; might not be initialized. + message_type = field_descriptor.message_type + + def DecodeMap(buffer, pos, end, message, field_dict, current_depth=0): + submsg = message_type._concrete_class() + value = field_dict.get(key) + if value is None: + value = field_dict.setdefault(key, new_default(message)) + while 1: + # Read length. + size, pos = local_DecodeVarint(buffer, pos) + new_pos = pos + size + if new_pos > end: + raise _DecodeError('Truncated message.') + # Read sub-message. + submsg.Clear() + current_depth += 1 + if current_depth > _recursion_limit: + raise _DecodeError('Error parsing message: too many levels of nesting.') + if submsg._InternalParse(buffer, pos, new_pos, current_depth) != new_pos: + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise _DecodeError('Unexpected end-group tag.') + current_depth -= 1 + + if is_message_map: + value[submsg.key].CopyFrom(submsg.value) + else: + value[submsg.key] = submsg.value + + # Predict that the next tag is another copy of the same repeated field. + pos = new_pos + tag_len + if buffer[new_pos:pos] != tag_bytes or new_pos == end: + # Prediction failed. Return. + return new_pos + + return DecodeMap + + +def _DecodeFixed64(buffer, pos): + """Decode a fixed64.""" + new_pos = pos + 8 + return (struct.unpack('= _recursion_limit: + raise _DecodeError('Error parsing message: too many levels of nesting.') + data, pos = _DecodeUnknownFieldSet(buffer, pos, end_pos, current_depth) + current_depth -= 1 + # Check end tag. + if buffer[pos - len(end_tag_bytes) : pos] != end_tag_bytes: + raise _DecodeError('Missing group end tag.') + elif wire_type == wire_format.WIRETYPE_END_GROUP: + return (0, -1) + else: + raise _DecodeError('Wrong wire type in tag.') + + if pos > end_pos: + raise _DecodeError('Truncated message.') + + return (data, pos) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py new file mode 100644 index 00000000000..6ae91bab46a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py @@ -0,0 +1,931 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Code for encoding protocol message primitives. + +Contains the logic for encoding every logical protocol field type +into one of the 5 physical wire types. + +This code is designed to push the Python interpreter's performance to the +limits. + +The basic idea is that at startup time, for every field (i.e. every +FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The +sizer takes a value of this field's type and computes its byte size. The +encoder takes a writer function and a value. It encodes the value into byte +strings and invokes the writer function to write those strings. Typically the +writer function is the write() method of a BytesIO. + +We try to do as much work as possible when constructing the writer and the +sizer rather than when calling them. In particular: +* We copy any needed global functions to local variables, so that we do not need + to do costly global table lookups at runtime. +* Similarly, we try to do any attribute lookups at startup time if possible. +* Every field's tag is encoded to bytes at startup, since it can't change at + runtime. +* Whatever component of the field size we can compute at startup, we do. +* We *avoid* sharing code if doing so would make the code slower and not sharing + does not burden us too much. For example, encoders for repeated fields do + not just call the encoders for singular fields in a loop because this would + add an extra function call overhead for every loop iteration; instead, we + manually inline the single-value encoder into the loop. +* If a Python function lacks a return statement, Python actually generates + instructions to pop the result of the last statement off the stack, push + None onto the stack, and then return that. If we really don't care what + value is returned, then we can save two instructions by returning the + result of the last statement. It looks funny but it helps. +* We assume that type and bounds checking has happened at a higher level. +""" + +__author__ = 'kenton@google.com (Kenton Varda)' + +import struct + +from opentelemetry.agent._vendor.google.protobuf.internal import wire_format + +# This will overflow and thus become IEEE-754 "infinity". We would use +# "float('inf')" but it doesn't work on Windows pre-Python-2.6. +_POS_INF = 1e10000 +_NEG_INF = -_POS_INF + + +def _VarintSize(value): + """Compute the size of a varint value.""" + if value <= 0x7F: + return 1 + if value <= 0x3FFF: + return 2 + if value <= 0x1FFFFF: + return 3 + if value <= 0xFFFFFFF: + return 4 + if value <= 0x7FFFFFFFF: + return 5 + if value <= 0x3FFFFFFFFFF: + return 6 + if value <= 0x1FFFFFFFFFFFF: + return 7 + if value <= 0xFFFFFFFFFFFFFF: + return 8 + if value <= 0x7FFFFFFFFFFFFFFF: + return 9 + return 10 + + +def _SignedVarintSize(value): + """Compute the size of a signed varint value.""" + if value < 0: + return 10 + if value <= 0x7F: + return 1 + if value <= 0x3FFF: + return 2 + if value <= 0x1FFFFF: + return 3 + if value <= 0xFFFFFFF: + return 4 + if value <= 0x7FFFFFFFF: + return 5 + if value <= 0x3FFFFFFFFFF: + return 6 + if value <= 0x1FFFFFFFFFFFF: + return 7 + if value <= 0xFFFFFFFFFFFFFF: + return 8 + if value <= 0x7FFFFFFFFFFFFFFF: + return 9 + return 10 + + +def _TagSize(field_number): + """Returns the number of bytes required to serialize a tag with this field + + number. + """ + # Just pass in type 0, since the type won't affect the tag+type size. + return _VarintSize(wire_format.PackTag(field_number, 0)) + + +# -------------------------------------------------------------------- +# In this section we define some generic sizers. Each of these functions +# takes parameters specific to a particular field type, e.g. int32 or fixed64. +# It returns another function which in turn takes parameters specific to a +# particular field, e.g. the field number and whether it is repeated or packed. +# Look at the next section to see how these are used. + + +def _SimpleSizer(compute_value_size): + """A sizer which uses the function compute_value_size to compute the size of + + each value. Typically compute_value_size is _VarintSize. + """ + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + + def PackedFieldSize(value): + result = 0 + for element in value: + result += compute_value_size(element) + return result + local_VarintSize(result) + tag_size + + return PackedFieldSize + elif is_repeated: + + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += compute_value_size(element) + return result + + return RepeatedFieldSize + else: + + def FieldSize(value): + return tag_size + compute_value_size(value) + + return FieldSize + + return SpecificSizer + + +def _ModifiedSizer(compute_value_size, modify_value): + """Like SimpleSizer, but modify_value is invoked on each value before it is + + passed to compute_value_size. modify_value is typically ZigZagEncode. + """ + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + + def PackedFieldSize(value): + result = 0 + for element in value: + result += compute_value_size(modify_value(element)) + return result + local_VarintSize(result) + tag_size + + return PackedFieldSize + elif is_repeated: + + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += compute_value_size(modify_value(element)) + return result + + return RepeatedFieldSize + else: + + def FieldSize(value): + return tag_size + compute_value_size(modify_value(value)) + + return FieldSize + + return SpecificSizer + + +def _FixedSizer(value_size): + """Like _SimpleSizer except for a fixed-size field. + + The input is the size of one value. + """ + + def SpecificSizer(field_number, is_repeated, is_packed): + tag_size = _TagSize(field_number) + if is_packed: + local_VarintSize = _VarintSize + + def PackedFieldSize(value): + result = len(value) * value_size + return result + local_VarintSize(result) + tag_size + + return PackedFieldSize + elif is_repeated: + element_size = value_size + tag_size + + def RepeatedFieldSize(value): + return len(value) * element_size + + return RepeatedFieldSize + else: + field_size = value_size + tag_size + + def FieldSize(value): + return field_size + + return FieldSize + + return SpecificSizer + + +# ==================================================================== +# Here we declare a sizer constructor for each field type. Each "sizer +# constructor" is a function that takes (field_number, is_repeated, is_packed) +# as parameters and returns a sizer, which in turn takes a field value as +# a parameter and returns its encoded size. + +Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize) + +UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize) + +SInt32Sizer = SInt64Sizer = _ModifiedSizer( + _SignedVarintSize, wire_format.ZigZagEncode +) + +Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4) +Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8) + +BoolSizer = _FixedSizer(1) + + +def StringSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a string field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + local_len = len + assert not is_packed + if is_repeated: + + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = local_len(element.encode('utf-8')) + result += local_VarintSize(l) + l + return result + + return RepeatedFieldSize + else: + + def FieldSize(value): + l = local_len(value.encode('utf-8')) + return tag_size + local_VarintSize(l) + l + + return FieldSize + + +def BytesSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a bytes field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + local_len = len + assert not is_packed + if is_repeated: + + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = local_len(element) + result += local_VarintSize(l) + l + return result + + return RepeatedFieldSize + else: + + def FieldSize(value): + l = local_len(value) + return tag_size + local_VarintSize(l) + l + + return FieldSize + + +def GroupSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a group field.""" + + tag_size = _TagSize(field_number) * 2 + assert not is_packed + if is_repeated: + + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + result += element.ByteSize() + return result + + return RepeatedFieldSize + else: + + def FieldSize(value): + return tag_size + value.ByteSize() + + return FieldSize + + +def MessageSizer(field_number, is_repeated, is_packed): + """Returns a sizer for a message field.""" + + tag_size = _TagSize(field_number) + local_VarintSize = _VarintSize + assert not is_packed + if is_repeated: + + def RepeatedFieldSize(value): + result = tag_size * len(value) + for element in value: + l = element.ByteSize() + result += local_VarintSize(l) + l + return result + + return RepeatedFieldSize + else: + + def FieldSize(value): + l = value.ByteSize() + return tag_size + local_VarintSize(l) + l + + return FieldSize + + +# -------------------------------------------------------------------- +# MessageSet is special: it needs custom logic to compute its size properly. + + +def MessageSetItemSizer(field_number): + """Returns a sizer for extensions of MessageSet. + + The message set message looks like this: + message MessageSet { + repeated group Item = 1 { + required int32 type_id = 2; + required string message = 3; + } + } + """ + static_size = ( + _TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) + _TagSize(3) + ) + local_VarintSize = _VarintSize + + def FieldSize(value): + l = value.ByteSize() + return static_size + local_VarintSize(l) + l + + return FieldSize + + +# -------------------------------------------------------------------- +# Map is special: it needs custom logic to compute its size properly. + + +def MapSizer(field_descriptor, key_sizer, value_sizer): + """Returns a sizer for a map field.""" + + def FieldSize(map_value): + tag_size = _TagSize(field_descriptor.number) + local_VarintSize = _VarintSize + + total = 0 + for key in map_value: + val = map_value[key] + entry_size = key_sizer(key) + value_sizer(val) + total += tag_size + local_VarintSize(entry_size) + entry_size + + return total + + return FieldSize + + +# ==================================================================== +# Encoders! + + +def _VarintEncoder(): + """Return an encoder for a basic varint value (does not include tag).""" + + local_int2byte = struct.Struct('>B').pack + + def EncodeVarint(write, value, unused_deterministic=None): + bits = value & 0x7F + value >>= 7 + while value: + write(local_int2byte(0x80 | bits)) + bits = value & 0x7F + value >>= 7 + return write(local_int2byte(bits)) + + return EncodeVarint + + +def _SignedVarintEncoder(): + """Return an encoder for a basic signed varint value (does not include + + tag). + """ + + local_int2byte = struct.Struct('>B').pack + + def EncodeSignedVarint(write, value, unused_deterministic=None): + if value < 0: + value += 1 << 64 + bits = value & 0x7F + value >>= 7 + while value: + write(local_int2byte(0x80 | bits)) + bits = value & 0x7F + value >>= 7 + return write(local_int2byte(bits)) + + return EncodeSignedVarint + + +_EncodeVarint = _VarintEncoder() +_EncodeSignedVarint = _SignedVarintEncoder() + + +def _VarintBytes(value): + """Encode the given integer as a varint and return the bytes. + + This is only called at startup time so it doesn't need to be fast. + """ + + pieces = [] + _EncodeVarint(pieces.append, value, True) + return b''.join(pieces) + + +def TagBytes(field_number, wire_type): + """Encode the given tag and return the bytes. Only called at startup.""" + + return bytes(_VarintBytes(wire_format.PackTag(field_number, wire_type))) + + +# -------------------------------------------------------------------- +# As with sizers (see above), we have a number of common encoder +# implementations. + + +def _SimpleEncoder(wire_type, encode_value, compute_value_size): + """Return a constructor for an encoder for fields of a particular type. + + Args: + wire_type: The field's wire type, for encoding tags. + encode_value: A function which encodes an individual value, e.g. + _EncodeVarint(). + compute_value_size: A function which computes the size of an individual + value, e.g. _VarintSize(). + """ + + def SpecificEncoder(field_number, is_repeated, is_packed): + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + + def EncodePackedField(write, value, deterministic): + write(tag_bytes) + size = 0 + for element in value: + size += compute_value_size(element) + local_EncodeVarint(write, size, deterministic) + for element in value: + encode_value(write, element, deterministic) + + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeRepeatedField(write, value, deterministic): + for element in value: + write(tag_bytes) + encode_value(write, element, deterministic) + + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeField(write, value, deterministic): + write(tag_bytes) + return encode_value(write, value, deterministic) + + return EncodeField + + return SpecificEncoder + + +def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): + """Like SimpleEncoder but additionally invokes modify_value on every value + + before passing it to encode_value. Usually modify_value is ZigZagEncode. + """ + + def SpecificEncoder(field_number, is_repeated, is_packed): + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + + def EncodePackedField(write, value, deterministic): + write(tag_bytes) + size = 0 + for element in value: + size += compute_value_size(modify_value(element)) + local_EncodeVarint(write, size, deterministic) + for element in value: + encode_value(write, modify_value(element), deterministic) + + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeRepeatedField(write, value, deterministic): + for element in value: + write(tag_bytes) + encode_value(write, modify_value(element), deterministic) + + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeField(write, value, deterministic): + write(tag_bytes) + return encode_value(write, modify_value(value), deterministic) + + return EncodeField + + return SpecificEncoder + + +def _StructPackEncoder(wire_type, format): + """Return a constructor for an encoder for a fixed-width field. + + Args: + wire_type: The field's wire type, for encoding tags. + format: The format string to pass to struct.pack(). + """ + + value_size = struct.calcsize(format) + + def SpecificEncoder(field_number, is_repeated, is_packed): + local_struct_pack = struct.pack + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + + def EncodePackedField(write, value, deterministic): + write(tag_bytes) + local_EncodeVarint(write, len(value) * value_size, deterministic) + for element in value: + write(local_struct_pack(format, element)) + + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeRepeatedField(write, value, unused_deterministic=None): + for element in value: + write(tag_bytes) + write(local_struct_pack(format, element)) + + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeField(write, value, unused_deterministic=None): + write(tag_bytes) + return write(local_struct_pack(format, value)) + + return EncodeField + + return SpecificEncoder + + +def _FloatingPointEncoder(wire_type, format): + """Return a constructor for an encoder for float fields. + + This is like StructPackEncoder, but catches errors that may be due to + passing non-finite floating-point values to struct.pack, and makes a + second attempt to encode those values. + + Args: + wire_type: The field's wire type, for encoding tags. + format: The format string to pass to struct.pack(). + """ + + value_size = struct.calcsize(format) + if value_size == 4: + + def EncodeNonFiniteOrRaise(write, value): + # Remember that the serialized form uses little-endian byte order. + if value == _POS_INF: + write(b'\x00\x00\x80\x7F') + elif value == _NEG_INF: + write(b'\x00\x00\x80\xFF') + elif value != value: # NaN + write(b'\x00\x00\xC0\x7F') + else: + raise + + elif value_size == 8: + + def EncodeNonFiniteOrRaise(write, value): + if value == _POS_INF: + write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F') + elif value == _NEG_INF: + write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF') + elif value != value: # NaN + write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F') + else: + raise + + else: + raise ValueError( + "Can't encode floating-point values that are " + '%d bytes long (only 4 or 8)' % value_size + ) + + def SpecificEncoder(field_number, is_repeated, is_packed): + local_struct_pack = struct.pack + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + + def EncodePackedField(write, value, deterministic): + write(tag_bytes) + local_EncodeVarint(write, len(value) * value_size, deterministic) + for element in value: + # This try/except block is going to be faster than any code that + # we could write to check whether element is finite. + try: + write(local_struct_pack(format, element)) + except SystemError: + EncodeNonFiniteOrRaise(write, element) + + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeRepeatedField(write, value, unused_deterministic=None): + for element in value: + write(tag_bytes) + try: + write(local_struct_pack(format, element)) + except SystemError: + EncodeNonFiniteOrRaise(write, element) + + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + + def EncodeField(write, value, unused_deterministic=None): + write(tag_bytes) + try: + write(local_struct_pack(format, value)) + except SystemError: + EncodeNonFiniteOrRaise(write, value) + + return EncodeField + + return SpecificEncoder + + +# ==================================================================== +# Here we declare an encoder constructor for each field type. These work +# very similarly to sizer constructors, described earlier. + +Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder( + wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize +) + +UInt32Encoder = UInt64Encoder = _SimpleEncoder( + wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize +) + +SInt32Encoder = SInt64Encoder = _ModifiedEncoder( + wire_format.WIRETYPE_VARINT, + _EncodeVarint, + _VarintSize, + wire_format.ZigZagEncode, +) + +# Note that Python conveniently guarantees that when using the '<' prefix on +# formats, they will also have the same size across all platforms (as opposed +# to without the prefix, where their sizes depend on the C compiler's basic +# type sizes). +Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, ' str + ValueType = int + + def __init__(self, enum_type): + """Inits EnumTypeWrapper with an EnumDescriptor.""" + self._enum_type = enum_type + self.DESCRIPTOR = enum_type # pylint: disable=invalid-name + + def Name(self, number): # pylint: disable=invalid-name + """Returns a string containing the name of an enum value.""" + try: + return self._enum_type.values_by_number[number].name + except KeyError: + pass # fall out to break exception chaining + + if not isinstance(number, int): + raise TypeError( + 'Enum value for {} must be an int, but got {} {!r}.'.format( + self._enum_type.name, type(number), number + ) + ) + else: + # repr here to handle the odd case when you pass in a boolean. + raise ValueError( + 'Enum {} has no name defined for value {!r}'.format( + self._enum_type.name, number + ) + ) + + def Value(self, name): # pylint: disable=invalid-name + """Returns the value corresponding to the given enum name.""" + try: + return self._enum_type.values_by_name[name].number + except KeyError: + pass # fall out to break exception chaining + raise ValueError( + 'Enum {} has no value defined for name {!r}'.format( + self._enum_type.name, name + ) + ) + + def keys(self): + """Return a list of the string names in the enum. + + Returns: + A list of strs, in the order they were defined in the .proto file. + """ + + return [ + value_descriptor.name for value_descriptor in self._enum_type.values + ] + + def values(self): + """Return a list of the integer values in the enum. + + Returns: + A list of ints, in the order they were defined in the .proto file. + """ + + return [ + value_descriptor.number for value_descriptor in self._enum_type.values + ] + + def items(self): + """Return a list of the (name, value) pairs of the enum. + + Returns: + A list of (str, int) pairs, in the order they were defined + in the .proto file. + """ + return [ + (value_descriptor.name, value_descriptor.number) + for value_descriptor in self._enum_type.values + ] + + def __getattr__(self, name): + """Returns the value corresponding to the given enum name.""" + try: + return ( + super(EnumTypeWrapper, self) + .__getattribute__('_enum_type') + .values_by_name[name] + .number + ) + except KeyError: + pass # fall out to break exception chaining + raise AttributeError( + 'Enum {} has no value defined for name {!r}'.format( + self._enum_type.name, name + ) + ) + + def __or__(self, other): + """Returns the union type of self and other.""" + if sys.version_info >= (3, 10): + return type(self) | other + else: + raise NotImplementedError( + 'You may not use | on EnumTypes (or classes) below python 3.10' + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py new file mode 100644 index 00000000000..16613ea70ed --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py @@ -0,0 +1,209 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains _ExtensionDict class to represent extensions.""" + +from opentelemetry.agent._vendor.google.protobuf.descriptor import FieldDescriptor +from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers + + +def _VerifyExtensionHandle(message, extension_handle): + """Verify that the given extension handle is valid.""" + + if not isinstance(extension_handle, FieldDescriptor): + raise KeyError( + 'HasExtension() expects an extension handle, got: %s' % extension_handle + ) + + if not extension_handle.is_extension: + raise KeyError('"%s" is not an extension.' % extension_handle.full_name) + + if not extension_handle.containing_type: + raise KeyError( + '"%s" is missing a containing_type.' % extension_handle.full_name + ) + + if extension_handle.containing_type is not message.DESCRIPTOR: + raise KeyError( + 'Extension "%s" extends message type "%s", but this ' + 'message is of type "%s".' + % ( + extension_handle.full_name, + extension_handle.containing_type.full_name, + message.DESCRIPTOR.full_name, + ) + ) + + +# TODO: Unify error handling of "unknown extension" crap. +# TODO: Support iteritems()-style iteration over all +# extensions with the "has" bits turned on? +class _ExtensionDict(object): + """Dict-like container for Extension fields on proto instances. + + Note that in all cases we expect extension handles to be + FieldDescriptors. + """ + + def __init__(self, extended_message): + """Args: + + extended_message: Message instance for which we are the Extensions dict. + """ + self._extended_message = extended_message + + def __getitem__(self, extension_handle): + """Returns the current value of the given extension handle.""" + + _VerifyExtensionHandle(self._extended_message, extension_handle) + + result = self._extended_message._fields.get(extension_handle) + if result is not None: + return result + + if extension_handle.is_repeated: + result = extension_handle._default_constructor(self._extended_message) + elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: + message_type = extension_handle.message_type + if not hasattr(message_type, '_concrete_class'): + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import message_factory + + message_factory.GetMessageClass(message_type) + if not hasattr(extension_handle.message_type, '_concrete_class'): + from opentelemetry.agent._vendor.google.protobuf import message_factory + + message_factory.GetMessageClass(extension_handle.message_type) + result = extension_handle.message_type._concrete_class() + try: + result._SetListener(self._extended_message._listener_for_children) + except ReferenceError: + pass + else: + # Singular scalar -- just return the default without inserting into the + # dict. + return extension_handle.default_value + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + if self._extended_message._frozen: + result._SetFrozen() + result = self._extended_message._fields.setdefault(extension_handle, result) + + return result + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + + my_fields = self._extended_message.ListFields() + other_fields = other._extended_message.ListFields() + + # Get rid of non-extension fields. + my_fields = [field for field in my_fields if field.is_extension] + other_fields = [field for field in other_fields if field.is_extension] + + return my_fields == other_fields + + def __ne__(self, other): + return not self == other + + def __len__(self): + fields = self._extended_message.ListFields() + # Get rid of non-extension fields. + extension_fields = [field for field in fields if field[0].is_extension] + return len(extension_fields) + + def __hash__(self): + raise TypeError('unhashable object') + + # Note that this is only meaningful for non-repeated, scalar extension + # fields. Note also that we may have to call _Modified() when we do + # successfully set a field this way, to set any necessary "has" bits in the + # ancestors of the extended message. + def __setitem__(self, extension_handle, value): + """If extension_handle specifies a non-repeated, scalar extension + + field, sets the value of that field. + """ + + _VerifyExtensionHandle(self._extended_message, extension_handle) + + self._extended_message._AssureWritable() + + if ( + extension_handle.is_repeated + or extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE + ): + raise TypeError( + 'Cannot assign to extension "%s" because it is a repeated or ' + 'composite type.' + % extension_handle.full_name + ) + + # It's slightly wasteful to lookup the type checker each time, + # but we expect this to be a vanishingly uncommon case anyway. + type_checker = type_checkers.GetTypeChecker(extension_handle) + # pylint: disable=protected-access + self._extended_message._fields[extension_handle] = type_checker.CheckValue( + value + ) + self._extended_message._Modified() + + def __delitem__(self, extension_handle): + self._extended_message.ClearExtension(extension_handle) + + def _FindExtensionByName(self, name): + """Tries to find a known extension with the specified name. + + Args: + name: Extension full name. + + Returns: + Extension field descriptor. + """ + descriptor = self._extended_message.DESCRIPTOR + extensions = descriptor.file.pool._extensions_by_name[descriptor] + return extensions.get(name, None) + + def _FindExtensionByNumber(self, number): + """Tries to find a known extension with the field number. + + Args: + number: Extension field number. + + Returns: + Extension field descriptor. + """ + descriptor = self._extended_message.DESCRIPTOR + extensions = descriptor.file.pool._extensions_by_number[descriptor] + return extensions.get(number, None) + + def __iter__(self): + # Return a generator over the populated extension fields + return ( + f[0] for f in self._extended_message.ListFields() if f[0].is_extension + ) + + def __contains__(self, extension_handle): + _VerifyExtensionHandle(self._extended_message, extension_handle) + + if extension_handle not in self._extended_message._fields: + return False + + if extension_handle.is_repeated: + return bool(self._extended_message._fields.get(extension_handle)) + + if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: + value = self._extended_message._fields.get(extension_handle) + # pylint: disable=protected-access + return value is not None and value._is_present_in_parent + + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py new file mode 100644 index 00000000000..27b176e351c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py @@ -0,0 +1,352 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains FieldMask class.""" + +from opentelemetry.agent._vendor.google.protobuf.descriptor import FieldDescriptor + + +class FieldMask(object): + """Class for FieldMask message type.""" + + __slots__ = () + + def ToJsonString(self): + """Converts FieldMask to string according to ProtoJSON spec.""" + camelcase_paths = [] + for path in self.paths: + camelcase_paths.append(_SnakeCaseToCamelCase(path)) + return ','.join(camelcase_paths) + + def FromJsonString(self, value): + """Converts string to FieldMask according to ProtoJSON spec.""" + if not isinstance(value, str): + raise ValueError('FieldMask JSON value not a string: {!r}'.format(value)) + self.Clear() + if value: + for path in value.split(','): + self.paths.append(_CamelCaseToSnakeCase(path)) + + def IsValidForDescriptor(self, message_descriptor): + """Checks whether the FieldMask is valid for Message Descriptor.""" + for path in self.paths: + if not _IsValidPath(message_descriptor, path): + return False + return True + + def AllFieldsFromDescriptor(self, message_descriptor): + """Gets all direct fields of Message Descriptor to FieldMask.""" + self.Clear() + for field in message_descriptor.fields: + self.paths.append(field.name) + + def CanonicalFormFromMask(self, mask): + """Converts a FieldMask to the canonical form. + + Removes paths that are covered by another path. For example, + "foo.bar" is covered by "foo" and will be removed if "foo" + is also in the FieldMask. Then sorts all paths in alphabetical order. + + Args: + mask: The original FieldMask to be converted. + """ + tree = _FieldMaskTree(mask) + tree.ToFieldMask(self) + + def Union(self, mask1, mask2): + """Merges mask1 and mask2 into this FieldMask.""" + _CheckFieldMaskMessage(mask1) + _CheckFieldMaskMessage(mask2) + tree = _FieldMaskTree(mask1) + tree.MergeFromFieldMask(mask2) + tree.ToFieldMask(self) + + def Intersect(self, mask1, mask2): + """Intersects mask1 and mask2 into this FieldMask.""" + _CheckFieldMaskMessage(mask1) + _CheckFieldMaskMessage(mask2) + tree = _FieldMaskTree(mask1) + intersection = _FieldMaskTree() + for path in mask2.paths: + tree.IntersectPath(path, intersection) + intersection.ToFieldMask(self) + + def MergeMessage( + self, + source, + destination, + replace_message_field=False, + replace_repeated_field=False, + ): + """Merges fields specified in FieldMask from source to destination. + + Args: + source: Source message. + destination: The destination message to be merged into. + replace_message_field: Replace message field if True. Merge message field + if False. + replace_repeated_field: Replace repeated field if True. Append elements of + repeated field if False. + """ + tree = _FieldMaskTree(self) + tree.MergeMessage( + source, destination, replace_message_field, replace_repeated_field + ) + + +def _IsValidPath(message_descriptor, path): + """Checks whether the path is valid for Message Descriptor.""" + parts = path.split('.') + last = parts.pop() + for name in parts: + field = message_descriptor.fields_by_name.get(name) + if ( + field is None + or field.is_repeated + or field.type != FieldDescriptor.TYPE_MESSAGE + ): + return False + message_descriptor = field.message_type + return last in message_descriptor.fields_by_name + + +def _CheckFieldMaskMessage(message): + """Raises ValueError if message is not a FieldMask.""" + message_descriptor = message.DESCRIPTOR + if ( + message_descriptor.name != 'FieldMask' + or message_descriptor.file.name != 'google/protobuf/field_mask.proto' + ): + raise ValueError( + 'Message {0} is not a FieldMask.'.format(message_descriptor.full_name) + ) + + +def _SnakeCaseToCamelCase(path_name): + """Converts a path name from snake_case to camelCase.""" + result = [] + after_underscore = False + for c in path_name: + if c.isupper(): + raise ValueError( + 'Fail to print FieldMask to Json string: Path name ' + '{0} must not contain uppercase letters.'.format(path_name) + ) + if after_underscore: + if c.islower(): + result.append(c.upper()) + after_underscore = False + else: + raise ValueError( + 'Fail to print FieldMask to Json string: The ' + 'character after a "_" must be a lowercase letter ' + 'in path name {0}.'.format(path_name) + ) + elif c == '_': + after_underscore = True + else: + result += c + + if after_underscore: + raise ValueError( + 'Fail to print FieldMask to Json string: Trailing "_" ' + 'in path name {0}.'.format(path_name) + ) + return ''.join(result) + + +def _CamelCaseToSnakeCase(path_name): + """Converts a field name from camelCase to snake_case.""" + result = [] + for c in path_name: + if c == '_': + raise ValueError( + 'Fail to parse FieldMask: Path name ' + '{0} must not contain "_"s.'.format(path_name) + ) + if c.isupper(): + result += '_' + result += c.lower() + else: + result += c + return ''.join(result) + + +class _FieldMaskTree(object): + """Represents a FieldMask in a tree structure. + + For example, given a FieldMask "foo.bar,foo.baz,bar.baz", + the FieldMaskTree will be: + [_root] -+- foo -+- bar + | | + | +- baz + | + +- bar --- baz + In the tree, each leaf node represents a field path. + """ + + __slots__ = ('_root',) + + def __init__(self, field_mask=None): + """Initializes the tree by FieldMask.""" + self._root = {} + if field_mask: + self.MergeFromFieldMask(field_mask) + + def MergeFromFieldMask(self, field_mask): + """Merges a FieldMask to the tree.""" + for path in field_mask.paths: + self.AddPath(path) + + def AddPath(self, path): + """Adds a field path into the tree. + + If the field path to add is a sub-path of an existing field path + in the tree (i.e., a leaf node), it means the tree already matches + the given path so nothing will be added to the tree. If the path + matches an existing non-leaf node in the tree, that non-leaf node + will be turned into a leaf node with all its children removed because + the path matches all the node's children. Otherwise, a new path will + be added. + + Args: + path: The field path to add. + """ + node = self._root + for name in path.split('.'): + if name not in node: + node[name] = {} + elif not node[name]: + # Pre-existing empty node implies we already have this entire tree. + return + node = node[name] + # Remove any sub-trees we might have had. + node.clear() + + def ToFieldMask(self, field_mask): + """Converts the tree to a FieldMask.""" + field_mask.Clear() + _AddFieldPaths(self._root, '', field_mask) + + def IntersectPath(self, path, intersection): + """Calculates the intersection part of a field path with this tree. + + Args: + path: The field path to calculates. + intersection: The out tree to record the intersection part. + """ + node = self._root + for name in path.split('.'): + if name not in node: + return + elif not node[name]: + intersection.AddPath(path) + return + node = node[name] + intersection.AddLeafNodes(path, node) + + def AddLeafNodes(self, prefix, node): + """Adds leaf nodes begin with prefix to this tree.""" + if not node: + self.AddPath(prefix) + return + stack = [(prefix, node)] + while stack: + current_prefix, current_node = stack.pop() + if not current_node: + self.AddPath(current_prefix) + continue + for name in current_node: + child_path = current_prefix + '.' + name + stack.append((child_path, current_node[name])) + + def MergeMessage( + self, source, destination, replace_message, replace_repeated + ): + """Merge all fields specified by this tree from source to destination.""" + _MergeMessage( + self._root, source, destination, replace_message, replace_repeated + ) + + +def _StrConvert(value): + """Converts value to str if it is not.""" + # This file is imported by c extension and some methods like ClearField + # requires string for the field name. py2/py3 has different text + # type and may use unicode. + if not isinstance(value, str): + return value.encode('utf-8') + return value + + +def _MergeMessage(node, source, destination, replace_message, replace_repeated): + """Merge all fields specified by a sub-tree from source to destination.""" + stack = [(node, source, destination)] + while stack: + current_node, current_source, current_destination = stack.pop() + source_descriptor = current_source.DESCRIPTOR + for name in current_node: + child = current_node[name] + field = source_descriptor.fields_by_name[name] + if field is None: + raise ValueError( + "Error: Can't find field {0} in message {1}.".format( + name, source_descriptor.full_name + ) + ) + if child: + # Sub-paths are only allowed for singular message fields. + if ( + field.is_repeated + or field.cpp_type != FieldDescriptor.CPPTYPE_MESSAGE + ): + raise ValueError( + 'Error: Field {0} in message {1} is not a singular ' + 'message field and cannot have sub-fields.'.format( + name, source_descriptor.full_name + ) + ) + if current_source.HasField(name): + stack.append(( + child, + getattr(current_source, name), + getattr(current_destination, name), + )) + continue + if field.is_repeated: + if replace_repeated: + current_destination.ClearField(_StrConvert(name)) + repeated_source = getattr(current_source, name) + repeated_destination = getattr(current_destination, name) + repeated_destination.MergeFrom(repeated_source) + else: + if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: + if replace_message: + current_destination.ClearField(_StrConvert(name)) + if current_source.HasField(name): + getattr(current_destination, name).MergeFrom( + getattr(current_source, name) + ) + elif not field.has_presence or current_source.HasField(name): + setattr(current_destination, name, getattr(current_source, name)) + else: + current_destination.ClearField(_StrConvert(name)) + + +def _AddFieldPaths(node, prefix, field_mask): + """Adds the field paths descended from node to field_mask.""" + stack = [(node, prefix)] + while stack: + current_node, current_prefix = stack.pop() + if not current_node and current_prefix: + field_mask.paths.append(current_prefix) + continue + for name in sorted(current_node, reverse=True): + if current_prefix: + child_path = current_prefix + '.' + name + else: + child_path = name + stack.append((current_node[name], child_path)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py new file mode 100644 index 00000000000..7abb851d7c2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py @@ -0,0 +1,56 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +"""Defines a listener interface for observing certain + +state transitions on Message objects. + +Also defines a null implementation of this interface. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + + +class MessageListener(object): + """Listens for modifications made to a message. + + Meant to be registered via Message._SetListener(). + + Attributes: + dirty: If True, then calling Modified() would be a no-op. This can be used + to avoid these calls entirely in the common case. + """ + + def Modified(self): + """Called every time the message is modified in such a way that the parent + + message may need to be updated. This currently means either: + (a) The message was modified for the first time, so the parent message + should henceforth mark the message as present. + (b) The message's cached byte size became dirty -- i.e. the message was + modified for the first time after a previous call to ByteSize(). + Therefore the parent should also mark its byte size as dirty. + Note that (a) implies (b), since new objects start out with a client cached + size (zero). However, we document (a) explicitly because it is important. + + Modified() will *only* be called in response to one of these two events -- + not every time the sub-message is modified. + + Note that if the listener's |dirty| attribute is true, then calling + Modified at the moment would be a no-op, so it can be skipped. Performance- + sensitive callers should check this attribute directly before calling since + it will be true most of the time. + """ + + raise NotImplementedError + + +class NullMessageListener(object): + """No-op MessageListener implementation.""" + + def Modified(self): + pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py new file mode 100644 index 00000000000..a6b7741c58a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py @@ -0,0 +1,5 @@ +""" +This file contains the serialized FeatureSetDefaults object corresponding to +the Pure Python runtime. This is used for feature resolution under Editions. +""" +_PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS = b"\n\031\030\204\007\"\000*\022\010\001\020\002\030\002 \003(\0010\0028\002@\001H\001\n\031\030\347\007\"\000*\022\010\002\020\001\030\001 \002(\0010\0018\002@\001H\001\n\031\030\350\007\"\014\010\001\020\001\030\001 \002(\0010\001*\0068\002@\001H\001\n\031\030\351\007\"\020\010\001\020\001\030\001 \002(\0010\0018\001@\002*\002H\001\n\031\030\352\007\"\022\010\001\020\001\030\001 \002(\0010\0018\003@\004H\002*\000 \346\007(\352\007" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py new file mode 100644 index 00000000000..556e3f4ab0d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py @@ -0,0 +1,1778 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +# This code is meant to work on Python 2.4 and above only. +# +# TODO: Helpers for verbose, common checks like seeing if a +# descriptor's cpp_type is CPPTYPE_MESSAGE. +"""Contains a metaclass and helper functions used to create + +protocol message classes from Descriptor objects at runtime. + +Recall that a metaclass is the "type" of a class. +(A class is to a metaclass what an instance is to a class.) + +In this case, we use the GeneratedProtocolMessageType metaclass +to inject all the useful functionality into the classes +output by the protocol compiler at compile-time. + +The upshot of all this is that the real implementation +details for ALL pure-Python protocol buffers are *here in +this file*. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import datetime +from io import BytesIO +import math +import struct +import sys +import warnings +import weakref + +from opentelemetry.agent._vendor.google.protobuf import descriptor as descriptor_mod +from opentelemetry.agent._vendor.google.protobuf import message as message_mod +from opentelemetry.agent._vendor.google.protobuf import text_format + +# We use "as" to avoid name collisions with variables. +from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation +from opentelemetry.agent._vendor.google.protobuf.internal import containers +from opentelemetry.agent._vendor.google.protobuf.internal import decoder +from opentelemetry.agent._vendor.google.protobuf.internal import encoder +from opentelemetry.agent._vendor.google.protobuf.internal import enum_type_wrapper +from opentelemetry.agent._vendor.google.protobuf.internal import extension_dict +from opentelemetry.agent._vendor.google.protobuf.internal import message_listener as message_listener_mod +from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers +from opentelemetry.agent._vendor.google.protobuf.internal import well_known_types +from opentelemetry.agent._vendor.google.protobuf.internal import wire_format + +_FieldDescriptor = descriptor_mod.FieldDescriptor +_AnyFullTypeName = 'google.protobuf.Any' +_StructFullTypeName = 'google.protobuf.Struct' +_ListValueFullTypeName = 'google.protobuf.ListValue' +_ExtensionDict = extension_dict._ExtensionDict + + +class GeneratedProtocolMessageType(type): + """Metaclass for protocol message classes created at runtime from Descriptors. + + We add implementations for all methods described in the Message class. We + also create properties to allow getting/setting all fields in the protocol + message. Finally, we create slots to prevent users from accidentally + "setting" nonexistent fields in the protocol message, which then wouldn't get + serialized / deserialized properly. + + The protocol compiler currently uses this metaclass to create protocol + message classes at runtime. Clients can also manually create their own + classes at runtime, as in this example: + + mydescriptor = Descriptor(.....) + factory = symbol_database.Default() + factory.pool.AddDescriptor(mydescriptor) + MyProtoClass = message_factory.GetMessageClass(mydescriptor) + myproto_instance = MyProtoClass() + myproto.foo_field = 23 + ... + """ + + # Must be consistent with the protocol-compiler code in + # proto2/compiler/internal/generator.*. + _DESCRIPTOR_KEY = 'DESCRIPTOR' + + def __new__(cls, name, bases, dictionary): + """Custom allocation for runtime-generated class types. + + We override __new__ because this is apparently the only place + where we can meaningfully set __slots__ on the class we're creating(?). + (The interplay between metaclasses and slots is not very well-documented). + + Args: + name: Name of the class (ignored, but required by the metaclass protocol). + bases: Base classes of the class we're constructing. (Should be + message.Message). We ignore this field, but it's required by the + metaclass protocol + dictionary: The class dictionary of the class we're constructing. + dictionary[_DESCRIPTOR_KEY] must contain a Descriptor object describing + this protocol message type. + + Returns: + Newly-allocated class. + + Raises: + RuntimeError: Generated code only work with python cpp extension. + """ + descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] + + if isinstance(descriptor, str): + raise RuntimeError( + 'The generated code only work with python cpp ' + 'extension, but it is using pure python runtime.' + ) + + # If a concrete class already exists for this descriptor, don't try to + # create another. Doing so will break any messages that already exist with + # the existing class. + # + # The C++ implementation appears to have its own internal `PyMessageFactory` + # to achieve similar results. + # + # This most commonly happens in `text_format.py` when using descriptors from + # a custom pool; it calls message_factory.GetMessageClass() on a + # descriptor which already has an existing concrete class. + new_class = getattr(descriptor, '_concrete_class', None) + if new_class: + return new_class + + if descriptor.full_name in well_known_types.WKTBASES: + bases += (well_known_types.WKTBASES[descriptor.full_name],) + _AddClassAttributesForNestedExtensions(descriptor, dictionary) + _AddSlots(descriptor, dictionary) + + superclass = super(GeneratedProtocolMessageType, cls) + new_class = superclass.__new__(cls, name, bases, dictionary) + return new_class + + def __init__(cls, name, bases, dictionary): + """Here we perform the majority of our work on the class. + + We add enum getters, an __init__ method, implementations of all Message + methods, and properties for all fields in the protocol type. + + Args: + name: Name of the class (ignored, but required by the metaclass protocol). + bases: Base classes of the class we're constructing. (Should be + message.Message). We ignore this field, but it's required by the + metaclass protocol + dictionary: The class dictionary of the class we're constructing. + dictionary[_DESCRIPTOR_KEY] must contain a Descriptor object describing + this protocol message type. + """ + descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] + + # If this is an _existing_ class looked up via `_concrete_class` in the + # __new__ method above, then we don't need to re-initialize anything. + existing_class = getattr(descriptor, '_concrete_class', None) + if existing_class: + assert existing_class is cls, ( + 'Duplicate `GeneratedProtocolMessageType` created for descriptor %r' + % (descriptor.full_name) + ) + return + + cls._message_set_decoders_by_tag = {} + cls._fields_by_tag = {} + if ( + descriptor.has_options + and descriptor.GetOptions().message_set_wire_format + ): + cls._message_set_decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( + decoder.MessageSetItemDecoder(descriptor), + None, + ) + + # Attach stuff to each FieldDescriptor for quick lookup later on. + for field in descriptor.fields: + _AttachFieldHelpers(cls, field) + + if descriptor.is_extendable and hasattr(descriptor.file, 'pool'): + extensions = descriptor.file.pool.FindAllExtensions(descriptor) + for ext in extensions: + _AttachFieldHelpers(cls, ext) + + descriptor._concrete_class = cls # pylint: disable=protected-access + _AddEnumValues(descriptor, cls) + _AddInitMethod(descriptor, cls) + _AddPropertiesForFields(descriptor, cls) + _AddPropertiesForExtensions(descriptor, cls) + _AddStaticMethods(cls) + _AddMessageMethods(descriptor, cls) + _AddPrivateHelperMethods(descriptor, cls) + + superclass = super(GeneratedProtocolMessageType, cls) + superclass.__init__(name, bases, dictionary) + + +# Stateless helpers for GeneratedProtocolMessageType below. +# Outside clients should not access these directly. +# +# I opted not to make any of these methods on the metaclass, to make it more +# clear that I'm not really using any state there and to keep clients from +# thinking that they have direct access to these construction helpers. + + +def _PropertyName(proto_field_name): + """Returns the name of the public property attribute which + + clients can use to get and (in some cases) set the value + of a protocol message field. + + Args: + proto_field_name: The protocol message field name, exactly as it appears (or + would appear) in a .proto file. + """ + # TODO: Escape Python keywords (e.g., yield), and test this support. + # nnorwitz makes my day by writing: + # """ + # FYI. See the keyword module in the stdlib. This could be as simple as: + # + # if keyword.iskeyword(proto_field_name): + # return proto_field_name + "_" + # return proto_field_name + # """ + # Kenton says: The above is a BAD IDEA. People rely on being able to use + # getattr() and setattr() to reflectively manipulate field values. If we + # rename the properties, then every such user has to also make sure to apply + # the same transformation. Note that currently if you name a field "yield", + # you can still access it just fine using getattr/setattr -- it's not even + # that cumbersome to do so. + # TODO: Remove this method entirely if/when everyone agrees with my + # position. + return proto_field_name + + +def _AddSlots(message_descriptor, dictionary): + """Adds a __slots__ entry to dictionary, containing the names of all valid + + attributes for this message type. + + Args: + message_descriptor: A Descriptor instance describing this message type. + dictionary: Class dictionary to which we'll add a '__slots__' entry. + """ + dictionary['__slots__'] = [ + '_cached_byte_size', + '_cached_byte_size_dirty', + '_fields', + '_unknown_fields', + '_is_present_in_parent', + '_listener', + '_listener_for_children', + '__weakref__', + '_oneofs', + '_frozen', + ] + + +def _IsMessageSetExtension(field): + return ( + field.is_extension + and field.containing_type.has_options + and field.containing_type.GetOptions().message_set_wire_format + and field.type == _FieldDescriptor.TYPE_MESSAGE + and not field.is_required + and not field.is_repeated + ) + + +def _IsMapField(field): + return ( + field.type == _FieldDescriptor.TYPE_MESSAGE + and field.message_type._is_map_entry + ) + + +def _IsMessageMapField(field): + value_type = field.message_type.fields_by_name['value'] + return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE + + +def _AttachFieldHelpers(cls, field_descriptor): + field_descriptor._default_constructor = _DefaultValueConstructorForField( + field_descriptor + ) + + def AddFieldByTag(wiretype, is_packed): + tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) + cls._fields_by_tag[tag_bytes] = (field_descriptor, is_packed) + + AddFieldByTag( + type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], False + ) + + if field_descriptor.is_repeated and wire_format.IsTypePackable( + field_descriptor.type + ): + # To support wire compatibility of adding packed = true, add a decoder for + # packed values regardless of the field's options. + AddFieldByTag(wire_format.WIRETYPE_LENGTH_DELIMITED, True) + + +def _MaybeAddEncoder(cls, field_descriptor): + if hasattr(field_descriptor, '_encoder'): + return + is_repeated = field_descriptor.is_repeated + is_map_entry = _IsMapField(field_descriptor) + is_packed = field_descriptor.is_packed + + if is_map_entry: + key_descriptor = field_descriptor.message_type.fields_by_name['key'] + value_descriptor = field_descriptor.message_type.fields_by_name['value'] + + key_sizer = type_checkers.TYPE_TO_SIZER[key_descriptor.type]( + key_descriptor.number, False, False + ) + value_sizer = type_checkers.TYPE_TO_SIZER[value_descriptor.type]( + value_descriptor.number, False, False + ) + + key_encoder = type_checkers.TYPE_TO_ENCODER[key_descriptor.type]( + key_descriptor.number, False, False + ) + value_encoder = type_checkers.TYPE_TO_ENCODER[value_descriptor.type]( + value_descriptor.number, False, False + ) + + field_encoder = encoder.MapEncoder( + field_descriptor, key_encoder, value_encoder, key_sizer, value_sizer + ) + sizer = encoder.MapSizer(field_descriptor, key_sizer, value_sizer) + elif _IsMessageSetExtension(field_descriptor): + field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) + sizer = encoder.MessageSetItemSizer(field_descriptor.number) + else: + field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed + ) + sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed + ) + + field_descriptor._sizer = sizer + field_descriptor._encoder = field_encoder + + +def _MaybeAddDecoder(cls, field_descriptor): + if hasattr(field_descriptor, '_decoders'): + return + + is_repeated = field_descriptor.is_repeated + is_map_entry = _IsMapField(field_descriptor) + helper_decoders = {} + + def AddDecoder(is_packed): + decode_type = field_descriptor.type + if ( + decode_type == _FieldDescriptor.TYPE_ENUM + and not field_descriptor.enum_type.is_closed + ): + decode_type = _FieldDescriptor.TYPE_INT32 + + oneof_descriptor = None + if field_descriptor.containing_oneof is not None: + oneof_descriptor = field_descriptor + + if is_map_entry: + is_message_map = _IsMessageMapField(field_descriptor) + + field_decoder = decoder.MapDecoder( + field_descriptor, + _GetInitializeDefaultForMap(field_descriptor), + is_message_map, + ) + elif decode_type == _FieldDescriptor.TYPE_STRING: + field_decoder = decoder.StringDecoder( + field_descriptor.number, + is_repeated, + is_packed, + field_descriptor, + field_descriptor._default_constructor, + not field_descriptor.has_presence, + ) + elif field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( + field_descriptor.number, + is_repeated, + is_packed, + field_descriptor, + field_descriptor._default_constructor, + ) + else: + field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( + field_descriptor.number, + is_repeated, + is_packed, + # pylint: disable=protected-access + field_descriptor, + field_descriptor._default_constructor, + not field_descriptor.has_presence, + ) + + helper_decoders[is_packed] = field_decoder + + AddDecoder(False) + + if is_repeated and wire_format.IsTypePackable(field_descriptor.type): + # To support wire compatibility of adding packed = true, add a decoder for + # packed values regardless of the field's options. + AddDecoder(True) + + field_descriptor._decoders = helper_decoders + + +def _AddClassAttributesForNestedExtensions(descriptor, dictionary): + extensions = descriptor.extensions_by_name + for extension_name, extension_field in extensions.items(): + assert extension_name not in dictionary + dictionary[extension_name] = extension_field + + +def _AddEnumValues(descriptor, cls): + """Sets class-level attributes for all enum fields defined in this message. + + Also exporting a class-level object that can name enum values. + + Args: + descriptor: Descriptor object for this message type. + cls: Class we're constructing for this message type. + """ + for enum_type in descriptor.enum_types: + setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type)) + for enum_value in enum_type.values: + setattr(cls, enum_value.name, enum_value.number) + + +def _GetInitializeDefaultForMap(field): + if not field.is_repeated: + raise ValueError('map_entry set on non-repeated field %s' % (field.name)) + fields_by_name = field.message_type.fields_by_name + key_checker = type_checkers.GetTypeChecker(fields_by_name['key']) + + value_field = fields_by_name['value'] + if _IsMessageMapField(field): + + def MakeMessageMapDefault(message): + return containers.MessageMap( + message._listener_for_children, + value_field.message_type, + key_checker, + field.message_type, + ) + + return MakeMessageMapDefault + else: + value_checker = type_checkers.GetTypeChecker(value_field) + + def MakePrimitiveMapDefault(message): + return containers.ScalarMap( + message._listener_for_children, + key_checker, + value_checker, + field.message_type, + ) + + return MakePrimitiveMapDefault + + +def _DefaultValueConstructorForField(field): + """Returns a function which returns a default value for a field. + + Args: + field: FieldDescriptor object for this field. + + The returned function has one argument: + message: Message instance containing this field, or a weakref proxy + of same. + + That function in turn returns a default value for this field. The default + value may refer back to |message| via a weak reference. + """ + + if _IsMapField(field): + return _GetInitializeDefaultForMap(field) + + if field.is_repeated: + if field.has_default_value and field.default_value != []: + raise ValueError( + 'Repeated field default value not empty list: %s' + % (field.default_value) + ) + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + # We can't look at _concrete_class yet since it might not have + # been set. (Depends on order in which we initialize the classes). + message_type = field.message_type + + def MakeRepeatedMessageDefault(message): + return containers.RepeatedCompositeFieldContainer( + message._listener_for_children, field.message_type + ) + + return MakeRepeatedMessageDefault + else: + type_checker = type_checkers.GetTypeChecker(field) + + def MakeRepeatedScalarDefault(message): + return containers.RepeatedScalarFieldContainer( + message._listener_for_children, type_checker, field + ) + + return MakeRepeatedScalarDefault + + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + message_type = field.message_type + + def MakeSubMessageDefault(message): + # _concrete_class may not yet be initialized. + if not hasattr(message_type, '_concrete_class'): + from opentelemetry.agent._vendor.google.protobuf import message_factory + + message_factory.GetMessageClass(message_type) + result = message_type._concrete_class() + result._SetListener( + _OneofListener(message, field) + if field.containing_oneof is not None + else message._listener_for_children + ) + return result + + return MakeSubMessageDefault + + def MakeScalarDefault(message): + # TODO: This may be broken since there may not be + # default_value. Combine with has_default_value somehow. + return field.default_value + + return MakeScalarDefault + + +def _ReraiseTypeErrorWithFieldName(message_name, field_name): + """Re-raise the currently-handled TypeError with the field name added.""" + exc = sys.exc_info()[1] + if len(exc.args) == 1 and type(exc) is TypeError: + # simple TypeError; add field name to exception message + exc = TypeError('%s for field %s.%s' % (str(exc), message_name, field_name)) + + # re-raise possibly-amended exception with original traceback: + raise exc.with_traceback(sys.exc_info()[2]) + + +def _AddInitMethod(message_descriptor, cls): + """Adds an __init__ method to cls.""" + + def _GetIntegerEnumValue(enum_type, value): + """Convert a string or integer enum value to an integer. + + If the value is a string, it is converted to the enum value in + enum_type with the same name. If the value is not a string, it's + returned as-is. (No conversion or bounds-checking is done.) + """ + if isinstance(value, str): + try: + return enum_type.values_by_name[value].number + except KeyError: + raise ValueError( + 'Enum type %s: unknown label "%s"' % (enum_type.full_name, value) + ) + return value + + def init(self, **kwargs): + + def init_wkt_or_merge(field, msg, value): + if isinstance(value, message_mod.Message): + msg.MergeFrom(value) + elif ( + isinstance(value, dict) + and field.message_type.full_name == _StructFullTypeName + ): + msg.Clear() + if len(value) == 1 and 'fields' in value: + try: + msg.update(value) + except: + msg.Clear() + msg.__init__(**value) + else: + msg.update(value) + elif hasattr(msg, '_internal_assign'): + msg._internal_assign(value) + else: + raise TypeError( + 'Message field {0}.{1} must be initialized with a ' + 'dict or instance of same class, got {2}.'.format( + message_descriptor.name, + field.name, + type(value).__name__, + ) + ) + + self._cached_byte_size = 0 + self._cached_byte_size_dirty = len(kwargs) > 0 + self._fields = {} + # Contains a mapping from oneof field descriptors to the descriptor + # of the currently set field in that oneof field. + self._oneofs = {} + + # _unknown_fields is () when empty for efficiency, and will be turned into + # a list if fields are added. + self._unknown_fields = () + self._is_present_in_parent = False + self._listener = message_listener_mod.NullMessageListener() + self._listener_for_children = _Listener(self) + self._frozen = False + for field_name, field_value in kwargs.items(): + field = _GetFieldByName(message_descriptor, field_name) + if field is None: + raise TypeError( + '%s() got an unexpected keyword argument "%s"' + % (message_descriptor.name, field_name) + ) + if field_value is None: + # field=None is the same as no field at all. + continue + if field.is_repeated: + field_copy = field._default_constructor(self) + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite + if _IsMapField(field): + if _IsMessageMapField(field): + for key in field_value: + item_value = field_value[key] + if isinstance(item_value, dict): + field_copy[key].__init__(**item_value) + else: + field_copy[key].MergeFrom(item_value) + else: + field_copy.update(field_value) + else: + for val in field_value: + if isinstance(val, dict) and ( + field.message_type.full_name != _StructFullTypeName + ): + field_copy.add(**val) + else: + new_msg = field_copy.add() + init_wkt_or_merge(field, new_msg, val) + else: # Scalar + if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: + field_value = [ + _GetIntegerEnumValue(field.enum_type, val) + for val in field_value + ] + field_copy.extend(field_value) + self._fields[field] = field_copy + elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + field_copy = field._default_constructor(self) + if isinstance(field_value, dict) and ( + field.message_type.full_name != _StructFullTypeName + ): + new_val = field.message_type._concrete_class(**field_value) + field_copy.MergeFrom(new_val) + else: + try: + init_wkt_or_merge(field, field_copy, field_value) + except TypeError: + _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) + self._fields[field] = field_copy + else: + if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: + field_value = _GetIntegerEnumValue(field.enum_type, field_value) + try: + setattr(self, field_name, field_value) + except TypeError: + _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) + + init.__module__ = None + init.__doc__ = None + cls.__init__ = init + + +def _GetFieldByName(message_descriptor, field_name): + """Returns a field descriptor by field name. + + Args: + message_descriptor: A Descriptor describing all fields in message. + field_name: The name of the field to retrieve. + + Returns: + The field descriptor associated with the field name. + """ + try: + return message_descriptor.fields_by_name[field_name] + except KeyError: + raise ValueError( + 'Protocol message %s has no "%s" field.' + % (message_descriptor.name, field_name) + ) + + +def _AddPropertiesForFields(descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + for field in descriptor.fields: + _AddPropertiesForField(field, cls) + + if descriptor.is_extendable: + # _ExtensionDict is just an adaptor with no state so we allocate a new one + # every time it is accessed. + cls.Extensions = property(lambda self: _ExtensionDict(self)) + + +def _AddPropertiesForField(field, cls): + """Adds a public property for a protocol message field. + + Clients can use this property to get and (in the case of non-repeated scalar + fields) directly set the value of a protocol message field. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + # Catch it if we add other types that we should + # handle specially here. + assert _FieldDescriptor.MAX_CPPTYPE == 10 + + constant_name = field.name.upper() + '_FIELD_NUMBER' + setattr(cls, constant_name, field.number) + + if field.is_repeated: + _AddPropertiesForRepeatedField(field, cls) + elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + _AddPropertiesForNonRepeatedCompositeField(field, cls) + else: + _AddPropertiesForNonRepeatedScalarField(field, cls) + + +class _FieldProperty(property): + __slots__ = ('DESCRIPTOR',) + + def __init__(self, descriptor, getter, setter, doc): + property.__init__(self, getter, setter, doc=doc) + self.DESCRIPTOR = descriptor + + +def _AddPropertiesForRepeatedField(field, cls): + """Adds a public property for a "repeated" protocol message field. + + Clients can use this property to get the value of the field, which will be + either a RepeatedScalarFieldContainer or RepeatedCompositeFieldContainer (see + below). + + Note that when clients add values to these containers, we perform + type-checking in the case of repeated scalar fields, and we also set any + necessary "has" bits as a side-effect. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + + def getter(self): + field_value = self._fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + if self._frozen: + field_value._SetFrozen() + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) + return field_value + + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + + # We define a setter just so we can throw an exception with a more + # helpful error message. + def setter(self, new_value): + raise AttributeError( + 'Assignment not allowed to repeated field ' + '"%s" in protocol message object.' % proto_field_name + ) + + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) + + +def _AddPropertiesForNonRepeatedScalarField(field, cls): + """Adds a public property for a nonrepeated, scalar protocol message field. + + Clients can use this property to get and directly set the value of the field. + Note that when the client sets the value of a field by using this property, + all necessary "has" bits are set as a side-effect, and we also perform + type-checking. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + type_checker = type_checkers.GetTypeChecker(field) + default_value = field.default_value + + def getter(self): + # TODO: This may be broken since there may not be + # default_value. Combine with has_default_value somehow. + return self._fields.get(field, default_value) + + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + + def field_setter(self, new_value): + self._AssureWritable() + # pylint: disable=protected-access + # Testing the value for truthiness captures all of the implicit presence + # defaults (0, 0.0, enum 0, and False), except for -0.0. + try: + new_value = type_checker.CheckValue(new_value) + except TypeError as e: + raise TypeError( + 'Cannot set %s to %.1024r: %s' % (field.full_name, new_value, e) + ) + if not field.has_presence and decoder.IsDefaultScalarValue(new_value): + self._fields.pop(field, None) + else: + self._fields[field] = new_value + # Check _cached_byte_size_dirty inline to improve performance, since scalar + # setters are called frequently. + if not self._cached_byte_size_dirty: + self._Modified() + + if field.containing_oneof: + + def setter(self, new_value): + field_setter(self, new_value) + self._UpdateOneofState(field) + + else: + setter = field_setter + + setter.__module__ = None + setter.__doc__ = 'Setter for %s.' % proto_field_name + + # Add a property to encapsulate the getter/setter. + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) + + +def _AddPropertiesForNonRepeatedCompositeField(field, cls): + """Adds a public property for a nonrepeated, composite protocol message field. + + A composite field is a "group" or "message" field. + + Clients can use this property to get the value of the field, but cannot + assign to the property directly. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + # TODO: Remove duplication with similar method + # for non-repeated scalars. + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + + def getter(self): + field_value = self._fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + if self._frozen: + field_value._SetFrozen() + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) + return field_value + + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + + # We define a setter just so we can throw an exception with a more + # helpful error message. + def setter(self, new_value): + self._AssureWritable() + if field.message_type.full_name == 'google.protobuf.Timestamp': + getter(self) + self._fields[field].FromDatetime(new_value) + elif field.message_type.full_name == 'google.protobuf.Duration': + getter(self) + self._fields[field].FromTimedelta(new_value) + elif field.message_type.full_name == _StructFullTypeName: + getter(self) + self._fields[field].Clear() + self._fields[field].update(new_value) + elif field.message_type.full_name == _ListValueFullTypeName: + getter(self) + self._fields[field].Clear() + self._fields[field].extend(new_value) + else: + raise AttributeError( + 'Assignment not allowed to composite field ' + '"%s" in protocol message object.' % proto_field_name + ) + + # Add a property to encapsulate the getter. + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) + + +def _AddPropertiesForExtensions(descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + extensions = descriptor.extensions_by_name + for extension_name, extension_field in extensions.items(): + constant_name = extension_name.upper() + '_FIELD_NUMBER' + setattr(cls, constant_name, extension_field.number) + + # TODO: Migrate all users of these attributes to functions like + # pool.FindExtensionByNumber(descriptor). + if descriptor.file is not None: + # TODO: Use cls.MESSAGE_FACTORY.pool when available. + pool = descriptor.file.pool + + +def _AddStaticMethods(cls): + + def RegisterExtension(_): + """no-op to keep generated code <=4.23 working with new runtimes.""" + # This was originally removed in 5.26 (cl/595989309). + pass + + cls.RegisterExtension = staticmethod(RegisterExtension) + + def FromString(s): + message = cls() + message.MergeFromString(s) + return message + + cls.FromString = staticmethod(FromString) + + +def _IsPresent(item): + """Given a (FieldDescriptor, value) tuple from _fields, return true if the + + value should be included in the list returned by ListFields(). + """ + + if item[0].is_repeated: + return bool(item[1]) + elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + return item[1]._is_present_in_parent + else: + return True + + +def _AddListFieldsMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def ListFields(self): + all_fields = [item for item in self._fields.items() if _IsPresent(item)] + all_fields.sort(key=lambda item: item[0].number) + return all_fields + + cls.ListFields = ListFields + + +def _AddHasFieldMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + hassable_fields = {} + for field in message_descriptor.fields: + if field.is_repeated: + continue + # For proto3, only submessages and fields inside a oneof have presence. + if not field.has_presence: + continue + hassable_fields[field.name] = field + + # Has methods are supported for oneof descriptors. + for oneof in message_descriptor.oneofs: + hassable_fields[oneof.name] = oneof + + def HasField(self, field_name): + try: + field = hassable_fields[field_name] + except KeyError as exc: + raise ValueError( + 'Protocol message %s has no non-repeated field "%s" ' + 'nor has presence is not available for this field.' + % (message_descriptor.full_name, field_name) + ) from exc + + if isinstance(field, descriptor_mod.OneofDescriptor): + try: + return HasField(self, self._oneofs[field].name) + except KeyError: + return False + else: + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(field) + return value is not None and value._is_present_in_parent + else: + return field in self._fields + + cls.HasField = HasField + + +def _AddClearFieldMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def ClearField(self, field_name): + self._AssureWritable() + try: + field = message_descriptor.fields_by_name[field_name] + except KeyError: + try: + field = message_descriptor.oneofs_by_name[field_name] + if field in self._oneofs: + field = self._oneofs[field] + else: + return + except KeyError: + raise ValueError( + 'Protocol message %s has no "%s" field.' + % (message_descriptor.name, field_name) + ) + + if field in self._fields: + # To match the C++ implementation, we need to invalidate iterators + # for map fields when ClearField() happens. + if hasattr(self._fields[field], 'InvalidateIterators'): + self._fields[field].InvalidateIterators() + + # Note: If the field is a sub-message, its listener will still point + # at us. That's fine, because the worst than can happen is that it + # will call _Modified() and invalidate our byte size. Big deal. + del self._fields[field] + + if self._oneofs.get(field.containing_oneof, None) is field: + del self._oneofs[field.containing_oneof] + + # Always call _Modified() -- even if nothing was changed, this is + # a mutating method, and thus calling it should cause the field to become + # present in the parent message. + self._Modified() + + cls.ClearField = ClearField + + +def _AddClearExtensionMethod(cls): + """Helper for _AddMessageMethods().""" + + def ClearExtension(self, field_descriptor): + self._AssureWritable() + extension_dict._VerifyExtensionHandle(self, field_descriptor) + + # Similar to ClearField(), above. + if field_descriptor in self._fields: + del self._fields[field_descriptor] + self._Modified() + + cls.ClearExtension = ClearExtension + + +def _AddHasExtensionMethod(cls): + """Helper for _AddMessageMethods().""" + + def HasExtension(self, field_descriptor): + extension_dict._VerifyExtensionHandle(self, field_descriptor) + if field_descriptor.is_repeated: + raise KeyError('"%s" is repeated.' % field_descriptor.full_name) + + if field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(field_descriptor) + return value is not None and value._is_present_in_parent + else: + return field_descriptor in self._fields + + cls.HasExtension = HasExtension + + +def _InternalUnpackAny(msg): + """Unpacks Any message and returns the unpacked message. + + This internal method is different from public Any Unpack method which takes + the target message as argument. _InternalUnpackAny method does not have + target message type and need to find the message type in descriptor pool. + + Args: + msg: An Any message to be unpacked. + + Returns: + The unpacked message. + """ + # TODO: Don't use the factory of generated messages. + # To make Any work with custom factories, use the message factory of the + # parent message. + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import symbol_database + + factory = symbol_database.Default() + + type_url = msg.type_url + + if not type_url: + return None + + # TODO: For now we just strip the hostname. Better logic will be + # required. + type_name = type_url.split('/')[-1] + descriptor = factory.pool.FindMessageTypeByName(type_name) + + if descriptor is None: + return None + + # Unable to import message_factory at top because of circular import. + # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf import message_factory + + message_class = message_factory.GetMessageClass(descriptor) + message = message_class() + + message.ParseFromString(msg.value) + return message + + +def _AddEqualsMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def __eq__(self, other): + if self.DESCRIPTOR.full_name == _ListValueFullTypeName and isinstance( + other, list + ): + return self._internal_compare(other) + if self.DESCRIPTOR.full_name == _StructFullTypeName and isinstance( + other, dict + ): + return self._internal_compare(other) + + if ( + not isinstance(other, message_mod.Message) + or other.DESCRIPTOR != self.DESCRIPTOR + ): + return NotImplemented + + if self is other: + return True + + if self.DESCRIPTOR.full_name == _AnyFullTypeName: + any_a = _InternalUnpackAny(self) + any_b = _InternalUnpackAny(other) + if any_a and any_b: + return any_a == any_b + + if not self.ListFields() == other.ListFields(): + return False + + # TODO: Fix UnknownFieldSet to consider MessageSet extensions, + # then use it for the comparison. + unknown_fields = list(self._unknown_fields) + unknown_fields.sort() + other_unknown_fields = list(other._unknown_fields) + other_unknown_fields.sort() + return unknown_fields == other_unknown_fields + + cls.__eq__ = __eq__ + + +def _AddStrMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def __str__(self): + return text_format.MessageToString(self) + + cls.__str__ = __str__ + + +def _AddReprMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def __repr__(self): + return text_format.MessageToString(self) + + cls.__repr__ = __repr__ + + +def _AddUnicodeMethod(unused_message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def __unicode__(self): + return text_format.MessageToString(self, as_utf8=True).decode('utf-8') + + cls.__unicode__ = __unicode__ + + +def _AddContainsMethod(message_descriptor, cls): + + if message_descriptor.full_name == 'google.protobuf.Struct': + + def __contains__(self, key): + return key in self.fields + + elif message_descriptor.full_name == 'google.protobuf.ListValue': + + def __contains__(self, value): + return value in self.items() + + else: + + def __contains__(self, field): + return self.HasField(field) + + cls.__contains__ = __contains__ + + +def _BytesForNonRepeatedElement(value, field_number, field_type): + """Returns the number of bytes needed to serialize a non-repeated element. + + The returned byte count includes space for tag information and any other + additional space associated with serializing value. + + Args: + value: Value we're serializing. + field_number: Field number of this value. (Since the field number is stored + as part of a varint-encoded tag, this has an impact on the total bytes + required to serialize the value). + field_type: The type of the field. One of the TYPE_* constants within + FieldDescriptor. + """ + try: + fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] + return fn(field_number, value) + except KeyError: + raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) + + +def _AddByteSizeMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def ByteSize(self): + if not self._cached_byte_size_dirty: + return self._cached_byte_size + + size = 0 + descriptor = self.DESCRIPTOR + if descriptor._is_map_entry: + # Fields of map entry should always be serialized. + key_field = descriptor.fields_by_name['key'] + _MaybeAddEncoder(cls, key_field) + size = key_field._sizer(self.key) + value_field = descriptor.fields_by_name['value'] + _MaybeAddEncoder(cls, value_field) + size += value_field._sizer(self.value) + else: + for field_descriptor, field_value in self.ListFields(): + _MaybeAddEncoder(cls, field_descriptor) + size += field_descriptor._sizer(field_value) + for tag_bytes, value_bytes in self._unknown_fields: + size += len(tag_bytes) + len(value_bytes) + + self._cached_byte_size = size + self._cached_byte_size_dirty = False + self._listener_for_children.dirty = False + return size + + cls.ByteSize = ByteSize + + +def _AddSerializeToStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def SerializeToString(self, **kwargs): + # Check if the message has all of its required fields set. + if not self.IsInitialized(): + raise message_mod.EncodeError( + 'Message %s is missing required fields: %s' + % ( + self.DESCRIPTOR.full_name, + ','.join(self.FindInitializationErrors()), + ) + ) + return self.SerializePartialToString(**kwargs) + + cls.SerializeToString = SerializeToString + + +def _AddSerializePartialToStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def SerializePartialToString(self, **kwargs): + out = BytesIO() + self._InternalSerialize(out.write, **kwargs) + return out.getvalue() + + cls.SerializePartialToString = SerializePartialToString + + def InternalSerialize(self, write_bytes, deterministic=None): + if deterministic is None: + deterministic = ( + api_implementation.IsPythonDefaultSerializationDeterministic() + ) + else: + deterministic = bool(deterministic) + + descriptor = self.DESCRIPTOR + if descriptor._is_map_entry: + # Fields of map entry should always be serialized. + key_field = descriptor.fields_by_name['key'] + _MaybeAddEncoder(cls, key_field) + key_field._encoder(write_bytes, self.key, deterministic) + value_field = descriptor.fields_by_name['value'] + _MaybeAddEncoder(cls, value_field) + value_field._encoder(write_bytes, self.value, deterministic) + else: + for field_descriptor, field_value in self.ListFields(): + _MaybeAddEncoder(cls, field_descriptor) + field_descriptor._encoder(write_bytes, field_value, deterministic) + for tag_bytes, value_bytes in self._unknown_fields: + write_bytes(tag_bytes) + write_bytes(value_bytes) + + cls._InternalSerialize = InternalSerialize + + +def _AddMergeFromStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def MergeFromString(self, serialized): + self._AssureWritable() + serialized = memoryview(serialized) + length = len(serialized) + try: + if self._InternalParse(serialized, 0, length) != length: + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise message_mod.DecodeError('Unexpected end-group tag.') + except (IndexError, TypeError): + # Now ord(buf[p:p+1]) == ord('') gets TypeError. + raise message_mod.DecodeError('Truncated message.') + except struct.error as e: + raise message_mod.DecodeError(e) + return length # Return this for legacy reasons. + + cls.MergeFromString = MergeFromString + + fields_by_tag = cls._fields_by_tag + message_set_decoders_by_tag = cls._message_set_decoders_by_tag + + def InternalParse(self, buffer, pos, end, current_depth=0): + """Create a message from serialized bytes. + + Args: + self: Message, instance of the proto message object. + buffer: memoryview of the serialized data. + pos: int, position to start in the serialized data. + end: int, end position of the serialized data. + + Returns: + Message object. + """ + # Guard against internal misuse, since this function is called internally + # quite extensively, and its easy to accidentally pass bytes. + assert isinstance(buffer, memoryview) + self._Modified() + field_dict = self._fields + while pos != end: + tag_bytes, new_pos = decoder.ReadTag(buffer, pos) + field_decoder, field_des = message_set_decoders_by_tag.get( + tag_bytes, (None, None) + ) + if field_decoder: + pos = field_decoder( + buffer, new_pos, end, self, field_dict, current_depth + ) + continue + field_des, is_packed = fields_by_tag.get(tag_bytes, (None, None)) + if field_des is None: + if not self._unknown_fields: # pylint: disable=protected-access + self._unknown_fields = [] # pylint: disable=protected-access + field_number, wire_type = decoder.DecodeTag(tag_bytes) + if field_number == 0: + raise message_mod.DecodeError('Field number 0 is illegal.') + data, new_pos = decoder._DecodeUnknownField( + buffer, new_pos, end, field_number, wire_type + ) # pylint: disable=protected-access + if new_pos == -1: + return pos + self._unknown_fields.append( + (tag_bytes, buffer[pos + len(tag_bytes) : new_pos].tobytes()) + ) + pos = new_pos + else: + _MaybeAddDecoder(cls, field_des) + field_decoder = field_des._decoders[is_packed] + pos = field_decoder( + buffer, new_pos, end, self, field_dict, current_depth + ) + if field_des.containing_oneof: + self._UpdateOneofState(field_des) + return pos + + cls._InternalParse = InternalParse + + +def _AddIsInitializedMethod(message_descriptor, cls): + """Adds the IsInitialized and FindInitializationError methods to the + + protocol message class. + """ + + required_fields = [ + field for field in message_descriptor.fields if field.is_required + ] + + def IsInitialized(self, errors=None): + """Checks if all required fields of a message are set. + + Args: + errors: A list which, if provided, will be populated with the field paths + of all missing required fields. + + Returns: + True iff the specified message has all required fields set. + """ + + # Performance is critical so we avoid HasField() and ListFields(). + + for field in required_fields: + if field not in self._fields or ( + field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE + and not self._fields[field]._is_present_in_parent + ): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + + for field, value in list(self._fields.items()): # dict can change size! + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.is_repeated: + if field.message_type._is_map_entry: + continue + for element in value: + if not element.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + elif value._is_present_in_parent and not value.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + + return True + + cls.IsInitialized = IsInitialized + + def FindInitializationErrors(self): + """Finds required fields which are not initialized. + + Returns: + A list of strings. Each string is a path to an uninitialized field from + the top-level message, e.g. "foo.bar[5].baz". + """ + + errors = [] # simplify things + + for field in required_fields: + if not self.HasField(field.name): + errors.append(field.name) + + for field, value in self.ListFields(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.is_extension: + name = '(%s)' % field.full_name + else: + name = field.name + + if _IsMapField(field): + if _IsMessageMapField(field): + for key in value: + element = value[key] + prefix = '%s[%s].' % (name, key) + sub_errors = element.FindInitializationErrors() + errors += [prefix + error for error in sub_errors] + else: + # ScalarMaps can't have any initialization errors. + pass + elif field.is_repeated: + for i in range(len(value)): + element = value[i] + prefix = '%s[%d].' % (name, i) + sub_errors = element.FindInitializationErrors() + errors += [prefix + error for error in sub_errors] + else: + prefix = name + '.' + sub_errors = value.FindInitializationErrors() + errors += [prefix + error for error in sub_errors] + + return errors + + cls.FindInitializationErrors = FindInitializationErrors + + +def _FullyQualifiedClassName(klass): + module = klass.__module__ + name = getattr(klass, '__qualname__', klass.__name__) + if module in (None, 'builtins', '__builtin__'): + return name + return module + '.' + name + + +def _AddMergeFromMethod(cls): + CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE + + def MergeFrom(self, msg): + self._AssureWritable() + if not isinstance(msg, cls): + raise TypeError( + 'Parameter to MergeFrom() must be instance of same class: ' + 'expected %s got %s.' + % ( + _FullyQualifiedClassName(cls), + _FullyQualifiedClassName(msg.__class__), + ) + ) + + assert msg is not self + self._Modified() + + fields = self._fields + + for field, value in msg._fields.items(): + if field.is_repeated: + field_value = fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + fields[field] = field_value + field_value.MergeFrom(value) + elif field.cpp_type == CPPTYPE_MESSAGE: + if value._is_present_in_parent: + field_value = fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + fields[field] = field_value + field_value.MergeFrom(value) + else: + self._fields[field] = value + if field.containing_oneof: + self._UpdateOneofState(field) + + if msg._unknown_fields: + if not self._unknown_fields: + self._unknown_fields = [] + self._unknown_fields.extend(msg._unknown_fields) + + cls.MergeFrom = MergeFrom + + +def _AddWhichOneofMethod(message_descriptor, cls): + + def WhichOneof(self, oneof_name): + """Returns the name of the currently set field inside a oneof, or None.""" + try: + field = message_descriptor.oneofs_by_name[oneof_name] + except KeyError: + raise ValueError('Protocol message has no oneof "%s" field.' % oneof_name) + + nested_field = self._oneofs.get(field, None) + if nested_field is not None and self.HasField(nested_field.name): + return nested_field.name + else: + return None + + cls.WhichOneof = WhichOneof + + +def _Clear(self): + self._AssureWritable() + # Clear fields. + self._fields = {} + self._unknown_fields = () + + self._oneofs = {} + self._Modified() + + +def _SetFrozen(self): + self._frozen = True + for value in self._fields.values(): + if hasattr(value, '_SetFrozen'): + value._SetFrozen() + + +def _AssureWritable(self): + if self._frozen: + warnings.warn( + 'Mutating messages or containers returned by GetOptions() is' + ' deprecated and will raise an exception in a future release.', + category=FutureWarning, + stacklevel=3, + ) + return self + + +def _UnknownFields(self): + raise NotImplementedError( + 'Please use the add-on feaure ' + 'unknown_fields.UnknownFieldSet(message) in ' + 'unknown_fields.py instead.' + ) + + +def _DiscardUnknownFields(self): + self._AssureWritable() + self._unknown_fields = [] + for field, value in self.ListFields(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if _IsMapField(field): + if _IsMessageMapField(field): + for key in value: + value[key].DiscardUnknownFields() + elif field.is_repeated: + for sub_message in value: + sub_message.DiscardUnknownFields() + else: + value.DiscardUnknownFields() + + +def _SetListener(self, listener): + if listener is None: + self._listener = message_listener_mod.NullMessageListener() + else: + self._listener = listener + + +def _AddMessageMethods(message_descriptor, cls): + """Adds implementations of all Message methods to cls.""" + _AddListFieldsMethod(message_descriptor, cls) + _AddHasFieldMethod(message_descriptor, cls) + _AddClearFieldMethod(message_descriptor, cls) + if message_descriptor.is_extendable: + _AddClearExtensionMethod(cls) + _AddHasExtensionMethod(cls) + _AddEqualsMethod(message_descriptor, cls) + _AddStrMethod(message_descriptor, cls) + _AddReprMethod(message_descriptor, cls) + _AddUnicodeMethod(message_descriptor, cls) + _AddContainsMethod(message_descriptor, cls) + _AddByteSizeMethod(message_descriptor, cls) + _AddSerializeToStringMethod(message_descriptor, cls) + _AddSerializePartialToStringMethod(message_descriptor, cls) + _AddMergeFromStringMethod(message_descriptor, cls) + _AddIsInitializedMethod(message_descriptor, cls) + _AddMergeFromMethod(cls) + _AddWhichOneofMethod(message_descriptor, cls) + # Adds methods which do not depend on cls. + cls.Clear = _Clear + cls.DiscardUnknownFields = _DiscardUnknownFields + cls._SetListener = _SetListener + cls._SetFrozen = _SetFrozen + cls._AssureWritable = _AssureWritable + + +def _AddPrivateHelperMethods(message_descriptor, cls): + """Adds implementation of private helper methods to cls.""" + + def Modified(self): + """Sets the _cached_byte_size_dirty bit to true, + + and propagates this to our listener iff this was a state change. + """ + + # Note: Some callers check _cached_byte_size_dirty before calling + # _Modified() as an extra optimization. So, if this method is ever + # changed such that it does stuff even when _cached_byte_size_dirty is + # already true, the callers need to be updated. + if not self._cached_byte_size_dirty: + self._cached_byte_size_dirty = True + self._listener_for_children.dirty = True + self._is_present_in_parent = True + self._listener.Modified() + + def _UpdateOneofState(self, field): + """Sets field as the active field in its containing oneof. + + Will also delete currently active field in the oneof, if it is different + from the argument. Does not mark the message as modified. + """ + other_field = self._oneofs.setdefault(field.containing_oneof, field) + if other_field is not field: + del self._fields[other_field] + self._oneofs[field.containing_oneof] = field + + cls._Modified = Modified + cls.SetInParent = Modified + cls._UpdateOneofState = _UpdateOneofState + + +class _Listener(object): + """MessageListener implementation that a parent message registers with its + + child message. + + In order to support semantics like: + + foo.bar.baz.moo = 23 + assert foo.HasField('bar') + + ...child objects must have back references to their parents. + This helper class is at the heart of this support. + """ + + def __init__(self, parent_message): + """Args: + + parent_message: The message whose _Modified() method we should call when + we receive Modified() messages. + """ + # This listener establishes a back reference from a child (contained) object + # to its parent (containing) object. We make this a weak reference to avoid + # creating cyclic garbage when the client finishes with the 'parent' object + # in the tree. + if isinstance(parent_message, weakref.ProxyType): + self._parent_message_weakref = parent_message + else: + self._parent_message_weakref = weakref.proxy(parent_message) + + # As an optimization, we also indicate directly on the listener whether + # or not the parent message is dirty. This way we can avoid traversing + # up the tree in the common case. + self.dirty = False + + def Modified(self): + if self.dirty: + return + try: + # Propagate the signal to our parents iff this is the first field set. + self._parent_message_weakref._Modified() + except ReferenceError: + # We can get here if a client has kept a reference to a child object, + # and is now setting a field on it, but the child's parent has been + # garbage-collected. This is not an error. + pass + + +class _OneofListener(_Listener): + """Special listener implementation for setting composite oneof fields.""" + + def __init__(self, parent_message, field): + """Args: + + parent_message: The message whose _Modified() method we should call when + we receive Modified() messages. + field: The descriptor of the field being set in the parent message. + """ + super(_OneofListener, self).__init__(parent_message) + self._field = field + + def Modified(self): + """Also updates the state of the containing oneof in the parent message.""" + try: + self._parent_message_weakref._UpdateOneofState(self._field) + super(_OneofListener, self).Modified() + except ReferenceError: + pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py new file mode 100644 index 00000000000..375e7024984 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py @@ -0,0 +1,465 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Provides type checking routines. + +This module defines type checking utilities in the forms of dictionaries: + +VALUE_CHECKERS: A dictionary of field types and a value validation object. +TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing + function. +TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization + function. +FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their + corresponding wire types. +TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization + function. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import numbers +import struct +import warnings + +from opentelemetry.agent._vendor.google.protobuf import descriptor +from opentelemetry.agent._vendor.google.protobuf.internal import decoder +from opentelemetry.agent._vendor.google.protobuf.internal import encoder +from opentelemetry.agent._vendor.google.protobuf.internal import wire_format + +_FieldDescriptor = descriptor.FieldDescriptor + + +def TruncateToFourByteFloat(original): + return struct.unpack(' _FLOAT_MAX: + if converted_value <= _MAX_FLOAT_AS_DOUBLE_ROUNDED: + return _FLOAT_MAX + return _INF + if converted_value < _FLOAT_MIN: + if converted_value >= -_MAX_FLOAT_AS_DOUBLE_ROUNDED: + return _FLOAT_MIN + return _NEG_INF + + return TruncateToFourByteFloat(converted_value) + + +# Type-checkers for all scalar CPPTYPEs. +_VALUE_CHECKERS = { + _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), + _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), + _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), + _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), + _FieldDescriptor.CPPTYPE_DOUBLE: DoubleValueChecker(), + _FieldDescriptor.CPPTYPE_FLOAT: FloatValueChecker(), + _FieldDescriptor.CPPTYPE_BOOL: BoolValueChecker(), + _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes), +} + +# Map from field type to a function F, such that F(field_num, value) +# gives the total byte size for a value of the given type. This +# byte size includes tag information and any other additional space +# associated with serializing "value". +TYPE_TO_BYTE_SIZE_FN = { + _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, + _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, + _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, + _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, + _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, + _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, + _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, + _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, + _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, + _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, + _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, + _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, + _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, + _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, + _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, + _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, + _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, + _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize, +} + +# Maps from field types to encoder constructors. +TYPE_TO_ENCODER = { + _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder, + _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder, + _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder, + _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder, + _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder, + _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder, + _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder, + _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder, + _FieldDescriptor.TYPE_STRING: encoder.StringEncoder, + _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder, + _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder, + _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder, + _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder, + _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder, + _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder, + _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder, + _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder, + _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder, +} + +# Maps from field types to sizer constructors. +TYPE_TO_SIZER = { + _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer, + _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer, + _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer, + _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer, + _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer, + _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer, + _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer, + _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer, + _FieldDescriptor.TYPE_STRING: encoder.StringSizer, + _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer, + _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer, + _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer, + _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer, + _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer, + _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer, + _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer, + _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer, + _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer, +} + +# Maps from field type to a decoder constructor. +TYPE_TO_DECODER = { + _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder, + _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder, + _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder, + _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder, + _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder, + _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder, + _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder, + _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder, + _FieldDescriptor.TYPE_STRING: decoder.StringDecoder, + _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder, + _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder, + _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder, + _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder, + _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder, + _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder, + _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder, + _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder, + _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder, +} + +# Maps from field type to expected wiretype. +FIELD_TYPE_TO_WIRE_TYPE = { + _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, + _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, + _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, + _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, + _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_STRING: wire_format.WIRETYPE_LENGTH_DELIMITED, + _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, + _FieldDescriptor.TYPE_MESSAGE: wire_format.WIRETYPE_LENGTH_DELIMITED, + _FieldDescriptor.TYPE_BYTES: wire_format.WIRETYPE_LENGTH_DELIMITED, + _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, + _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, + _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, + _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py new file mode 100644 index 00000000000..2b5957c27b4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py @@ -0,0 +1,707 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains well known classes. + +This files defines well known classes which need extra maintenance including: + - Any + - Duration + - FieldMask + - Struct + - Timestamp +""" + +__author__ = 'jieluo@google.com (Jie Luo)' + +import calendar +import collections.abc +import datetime +from typing import Union +import warnings +from opentelemetry.agent._vendor.google.protobuf.internal import field_mask + +FieldMask = field_mask.FieldMask + +_TIMESTAMPFORMAT = '%Y-%m-%dT%H:%M:%S' +_NANOS_PER_SECOND = 1000000000 +_NANOS_PER_MILLISECOND = 1000000 +_NANOS_PER_MICROSECOND = 1000 +_MILLIS_PER_SECOND = 1000 +_MICROS_PER_SECOND = 1000000 +_SECONDS_PER_DAY = 24 * 3600 +_DURATION_SECONDS_MAX = 315576000000 +_TIMESTAMP_SECONDS_MIN = -62135596800 +_TIMESTAMP_SECONDS_MAX = 253402300799 + +_EPOCH_DATETIME_NAIVE = datetime.datetime(1970, 1, 1, tzinfo=None) +_EPOCH_DATETIME_AWARE = _EPOCH_DATETIME_NAIVE.replace( + tzinfo=datetime.timezone.utc +) + + +class Any(object): + """Class for Any Message type.""" + + __slots__ = () + + def Pack( + self, msg, type_url_prefix='type.googleapis.com/', deterministic=None + ): + """Packs the specified message into current Any message.""" + if len(type_url_prefix) < 1 or type_url_prefix[-1] != '/': + self.type_url = '%s/%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) + else: + self.type_url = '%s%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) + self.value = msg.SerializeToString(deterministic=deterministic) + + def Unpack(self, msg): + """Unpacks the current Any message into specified message.""" + descriptor = msg.DESCRIPTOR + if not self.Is(descriptor): + return False + msg.ParseFromString(self.value) + return True + + def TypeName(self): + """Returns the protobuf type name of the inner message.""" + # Only last part is to be used: b/25630112 + return self.type_url.rpartition('/')[2] + + def Is(self, descriptor): + """Checks if this Any represents the given protobuf type.""" + return '/' in self.type_url and self.TypeName() == descriptor.full_name + + +class Timestamp(object): + """Class for Timestamp message type.""" + + __slots__ = () + + def ToJsonString(self): + """Converts Timestamp to RFC 3339 date string format. + + Returns: + A string converted from timestamp. The string is always Z-normalized + and uses 3, 6 or 9 fractional digits as required to represent the + exact time. Example of the return format: '1972-01-01T10:00:20.021Z' + """ + _CheckTimestampValid(self.seconds, self.nanos) + nanos = self.nanos + seconds = self.seconds % _SECONDS_PER_DAY + days = (self.seconds - seconds) // _SECONDS_PER_DAY + dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(days, seconds) + + result = dt.isoformat() + if (nanos % 1e9) == 0: + # If there are 0 fractional digits, the fractional + # point '.' should be omitted when serializing. + return result + 'Z' + if (nanos % 1e6) == 0: + # Serialize 3 fractional digits. + return result + '.%03dZ' % (nanos / 1e6) + if (nanos % 1e3) == 0: + # Serialize 6 fractional digits. + return result + '.%06dZ' % (nanos / 1e3) + # Serialize 9 fractional digits. + return result + '.%09dZ' % nanos + + def FromJsonString(self, value): + """Parse a RFC 3339 date string format to Timestamp. + + Args: + value: A date string. Any fractional digits (or none) and any offset are + accepted as long as they fit into nano-seconds precision. Example of + accepted format: '1972-01-01T10:00:20.021-05:00' + + Raises: + ValueError: On parsing problems. + """ + if not isinstance(value, str): + raise ValueError('Timestamp JSON value not a string: {!r}'.format(value)) + timezone_offset = value.find('Z') + if timezone_offset == -1: + timezone_offset = value.find('+') + if timezone_offset == -1: + timezone_offset = value.rfind('-') + if timezone_offset == -1: + raise ValueError( + 'Failed to parse timestamp: missing valid timezone offset.' + ) + time_value = value[0:timezone_offset] + # Parse datetime and nanos. + point_position = time_value.find('.') + if point_position == -1: + second_value = time_value + nano_value = '' + else: + second_value = time_value[:point_position] + nano_value = time_value[point_position + 1 :] + if 't' in second_value: + raise ValueError( + "time data '{0}' does not match format '%Y-%m-%dT%H:%M:%S', " + "lowercase 't' is not accepted".format(second_value) + ) + date_object = datetime.datetime.strptime(second_value, _TIMESTAMPFORMAT) + td = date_object - datetime.datetime(1970, 1, 1) + seconds = td.seconds + td.days * _SECONDS_PER_DAY + if len(nano_value) > 9: + raise ValueError( + 'Failed to parse Timestamp: nanos {0} more than ' + '9 fractional digits.'.format(nano_value) + ) + if nano_value: + nanos = round(float('0.' + nano_value) * 1e9) + else: + nanos = 0 + # Parse timezone offsets. + if value[timezone_offset] == 'Z': + if len(value) != timezone_offset + 1: + raise ValueError( + 'Failed to parse timestamp: invalid trailing data {0}.'.format( + value + ) + ) + else: + timezone = value[timezone_offset:] + pos = timezone.find(':') + if pos == -1: + raise ValueError('Invalid timezone offset value: {0}.'.format(timezone)) + if timezone[0] == '+': + seconds -= (int(timezone[1:pos]) * 60 + int(timezone[pos + 1 :])) * 60 + else: + seconds += (int(timezone[1:pos]) * 60 + int(timezone[pos + 1 :])) * 60 + # Set seconds and nanos + _CheckTimestampValid(seconds, nanos) + self.seconds = int(seconds) + self.nanos = int(nanos) + + def GetCurrentTime(self): + """Get the current UTC into Timestamp.""" + self.FromDatetime(datetime.datetime.now(tz=datetime.timezone.utc)) + + def ToNanoseconds(self): + """Converts Timestamp to nanoseconds since epoch.""" + _CheckTimestampValid(self.seconds, self.nanos) + return self.seconds * _NANOS_PER_SECOND + self.nanos + + def ToMicroseconds(self): + """Converts Timestamp to microseconds since epoch.""" + _CheckTimestampValid(self.seconds, self.nanos) + return ( + self.seconds * _MICROS_PER_SECOND + self.nanos // _NANOS_PER_MICROSECOND + ) + + def ToMilliseconds(self): + """Converts Timestamp to milliseconds since epoch.""" + _CheckTimestampValid(self.seconds, self.nanos) + return ( + self.seconds * _MILLIS_PER_SECOND + self.nanos // _NANOS_PER_MILLISECOND + ) + + def ToSeconds(self): + """Converts Timestamp to seconds since epoch.""" + _CheckTimestampValid(self.seconds, self.nanos) + return self.seconds + + def FromNanoseconds(self, nanos): + """Converts nanoseconds since epoch to Timestamp.""" + seconds = nanos // _NANOS_PER_SECOND + nanos = nanos % _NANOS_PER_SECOND + _CheckTimestampValid(seconds, nanos) + self.seconds = seconds + self.nanos = nanos + + def FromMicroseconds(self, micros): + """Converts microseconds since epoch to Timestamp.""" + seconds = micros // _MICROS_PER_SECOND + nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND + _CheckTimestampValid(seconds, nanos) + self.seconds = seconds + self.nanos = nanos + + def FromMilliseconds(self, millis): + """Converts milliseconds since epoch to Timestamp.""" + seconds = millis // _MILLIS_PER_SECOND + nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND + _CheckTimestampValid(seconds, nanos) + self.seconds = seconds + self.nanos = nanos + + def FromSeconds(self, seconds): + """Converts seconds since epoch to Timestamp.""" + _CheckTimestampValid(seconds, 0) + self.seconds = seconds + self.nanos = 0 + + def ToDatetime(self, tzinfo=None): + """Converts Timestamp to a datetime. + + Args: + tzinfo: A datetime.tzinfo subclass; defaults to None. + + Returns: + If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone + information, i.e. not aware that it's UTC). + + Otherwise, returns a timezone-aware datetime in the input timezone. + """ + # Using datetime.fromtimestamp for this would avoid constructing an extra + # timedelta object and possibly an extra datetime. Unfortunately, that has + # the disadvantage of not handling the full precision (on all platforms, see + # https://github.com/python/cpython/issues/109849) or full range (on some + # platforms, see https://github.com/python/cpython/issues/110042) of + # datetime. + _CheckTimestampValid(self.seconds, self.nanos) + delta = datetime.timedelta( + seconds=self.seconds, + microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND), + ) + if tzinfo is None: + return _EPOCH_DATETIME_NAIVE + delta + else: + # Note the tz conversion has to come after the timedelta arithmetic. + return (_EPOCH_DATETIME_AWARE + delta).astimezone(tzinfo) + + def FromDatetime(self, dt): + """Converts datetime to Timestamp. + + Args: + dt: A datetime. If it's timezone-naive, it's assumed to be in UTC. + """ + # Using this guide: http://wiki.python.org/moin/WorkingWithTime + # And this conversion guide: http://docs.python.org/library/time.html + + # Turn the date parameter into a tuple (struct_time) that can then be + # manipulated into a long value of seconds. During the conversion from + # struct_time to long, the source date in UTC, and so it follows that the + # correct transformation is calendar.timegm() + if type(dt).__name__ != 'datetime' and not isinstance( + dt, datetime.datetime + ): + raise TypeError( + 'Fail to convert to Timestamp. Expected a datetime object ' + 'got {0}'.format(type(dt).__name__) + ) + try: + seconds = calendar.timegm(dt.utctimetuple()) + nanos = dt.microsecond * _NANOS_PER_MICROSECOND + except AttributeError as e: + raise AttributeError( + 'Fail to convert to Timestamp. Expected a datetime like ' + 'object got {0} : {1}'.format(type(dt).__name__, e) + ) from e + _CheckTimestampValid(seconds, nanos) + self.seconds = seconds + self.nanos = nanos + + def _internal_assign(self, dt): + self.FromDatetime(dt) + + def __add__(self, value) -> datetime.datetime: + if isinstance(value, Duration): + return self.ToDatetime() + value.ToTimedelta() + return self.ToDatetime() + value + + __radd__ = __add__ + + def __sub__(self, value) -> Union[datetime.datetime, datetime.timedelta]: + if isinstance(value, Timestamp): + return self.ToDatetime() - value.ToDatetime() + elif isinstance(value, Duration): + return self.ToDatetime() - value.ToTimedelta() + return self.ToDatetime() - value + + def __rsub__(self, dt) -> datetime.timedelta: + return dt - self.ToDatetime() + + +def _CheckTimestampValid(seconds, nanos): + if seconds < _TIMESTAMP_SECONDS_MIN or seconds > _TIMESTAMP_SECONDS_MAX: + raise ValueError( + 'Timestamp is not valid: Seconds {0} must be in range ' + '[-62135596800, 253402300799].'.format(seconds)) + if nanos < 0 or nanos >= _NANOS_PER_SECOND: + raise ValueError( + 'Timestamp is not valid: Nanos {} must be in a range ' + '[0, 999999].'.format(nanos) + ) + + +class Duration(object): + """Class for Duration message type.""" + + __slots__ = () + + def ToJsonString(self): + """Converts Duration to string format. + + Returns: + A string converted from self. The string format will contains + 3, 6, or 9 fractional digits depending on the precision required to + represent the exact Duration value. For example: "1s", "1.010s", + "1.000000100s", "-3.100s" + """ + _CheckDurationValid(self.seconds, self.nanos) + if self.seconds < 0 or self.nanos < 0: + result = '-' + seconds = -self.seconds + int((0 - self.nanos) // 1e9) + nanos = (0 - self.nanos) % 1e9 + else: + result = '' + seconds = self.seconds + int(self.nanos // 1e9) + nanos = self.nanos % 1e9 + result += '%d' % seconds + if (nanos % 1e9) == 0: + # If there are 0 fractional digits, the fractional + # point '.' should be omitted when serializing. + return result + 's' + if (nanos % 1e6) == 0: + # Serialize 3 fractional digits. + return result + '.%03ds' % (nanos / 1e6) + if (nanos % 1e3) == 0: + # Serialize 6 fractional digits. + return result + '.%06ds' % (nanos / 1e3) + # Serialize 9 fractional digits. + return result + '.%09ds' % nanos + + def FromJsonString(self, value): + """Converts a string to Duration. + + Args: + value: A string to be converted. The string must end with 's'. Any + fractional digits (or none) are accepted as long as they fit into + precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s + + Raises: + ValueError: On parsing problems. + """ + if not isinstance(value, str): + raise ValueError('Duration JSON value not a string: {!r}'.format(value)) + if len(value) < 1 or value[-1] != 's': + raise ValueError('Duration must end with letter "s": {0}.'.format(value)) + try: + pos = value.find('.') + if pos == -1: + seconds = int(value[:-1]) + nanos = 0 + else: + seconds = int(value[:pos]) + if value[0] == '-': + nanos = int(round(float('-0{0}'.format(value[pos:-1])) * 1e9)) + else: + nanos = int(round(float('0{0}'.format(value[pos:-1])) * 1e9)) + _CheckDurationValid(seconds, nanos) + self.seconds = seconds + self.nanos = nanos + except ValueError as e: + raise ValueError("Couldn't parse duration: {0} : {1}.".format(value, e)) + + def ToNanoseconds(self): + """Converts a Duration to nanoseconds.""" + return self.seconds * _NANOS_PER_SECOND + self.nanos + + def ToMicroseconds(self): + """Converts a Duration to microseconds.""" + micros = _RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND) + return self.seconds * _MICROS_PER_SECOND + micros + + def ToMilliseconds(self): + """Converts a Duration to milliseconds.""" + millis = _RoundTowardZero(self.nanos, _NANOS_PER_MILLISECOND) + return self.seconds * _MILLIS_PER_SECOND + millis + + def ToSeconds(self): + """Converts a Duration to seconds.""" + return self.seconds + + def FromNanoseconds(self, nanos): + """Converts nanoseconds to Duration.""" + self._NormalizeDuration( + nanos // _NANOS_PER_SECOND, nanos % _NANOS_PER_SECOND + ) + + def FromMicroseconds(self, micros): + """Converts microseconds to Duration.""" + self._NormalizeDuration( + micros // _MICROS_PER_SECOND, + (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND, + ) + + def FromMilliseconds(self, millis): + """Converts milliseconds to Duration.""" + self._NormalizeDuration( + millis // _MILLIS_PER_SECOND, + (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND, + ) + + def FromSeconds(self, seconds): + """Converts seconds to Duration.""" + self.seconds = seconds + self.nanos = 0 + + def ToTimedelta(self) -> datetime.timedelta: + """Converts Duration to timedelta.""" + return datetime.timedelta( + seconds=self.seconds, + microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND), + ) + + def FromTimedelta(self, td): + """Converts timedelta to Duration.""" + if type(td).__name__ != 'timedelta' and not isinstance( + td, datetime.timedelta + ): + raise TypeError( + 'Fail to convert to Duration. Expected a timedelta object ' + 'got {0}'.format(type(td).__name__) + ) + try: + self._NormalizeDuration( + td.seconds + td.days * _SECONDS_PER_DAY, + td.microseconds * _NANOS_PER_MICROSECOND, + ) + except AttributeError as e: + raise AttributeError( + 'Fail to convert to Duration. Expected a timedelta like ' + 'object got {0}: {1}'.format(type(td).__name__, e) + ) from e + + def _internal_assign(self, td): + self.FromTimedelta(td) + + def _NormalizeDuration(self, seconds, nanos): + """Set Duration by seconds and nanos.""" + # Force nanos to be negative if the duration is negative. + if seconds < 0 and nanos > 0: + seconds += 1 + nanos -= _NANOS_PER_SECOND + self.seconds = seconds + self.nanos = nanos + + def __add__(self, value) -> Union[datetime.datetime, datetime.timedelta]: + if isinstance(value, Timestamp): + return self.ToTimedelta() + value.ToDatetime() + return self.ToTimedelta() + value + + __radd__ = __add__ + + def __sub__(self, value) -> datetime.timedelta: + return self.ToTimedelta() - value + + def __rsub__(self, value) -> Union[datetime.datetime, datetime.timedelta]: + return value - self.ToTimedelta() + + +def _CheckDurationValid(seconds, nanos): + if seconds < -_DURATION_SECONDS_MAX or seconds > _DURATION_SECONDS_MAX: + raise ValueError( + 'Duration is not valid: Seconds {0} must be in range ' + '[-315576000000, 315576000000].'.format(seconds) + ) + if nanos <= -_NANOS_PER_SECOND or nanos >= _NANOS_PER_SECOND: + raise ValueError( + 'Duration is not valid: Nanos {0} must be in range ' + '[-999999999, 999999999].'.format(nanos) + ) + if (nanos < 0 and seconds > 0) or (nanos > 0 and seconds < 0): + raise ValueError('Duration is not valid: Sign mismatch.') + + +def _RoundTowardZero(value, divider): + """Truncates the remainder part after division.""" + # For some languages, the sign of the remainder is implementation + # dependent if any of the operands is negative. Here we enforce + # "rounded toward zero" semantics. For example, for (-5) / 2 an + # implementation may give -3 as the result with the remainder being + # 1. This function ensures we always return -2 (closer to zero). + result = value // divider + remainder = value % divider + if result < 0 and remainder > 0: + return result + 1 + else: + return result + + +def _SetStructValue(struct_value, value): + if value is None: + struct_value.null_value = 0 + elif isinstance(value, bool): + # Note: this check must come before the number check because in Python + # True and False are also considered numbers. + struct_value.bool_value = value + elif isinstance(value, str): + struct_value.string_value = value + elif isinstance(value, (int, float)): + struct_value.number_value = value + elif isinstance(value, (dict, Struct)): + struct_value.struct_value.Clear() + struct_value.struct_value.update(value) + elif isinstance(value, (list, tuple, ListValue)): + struct_value.list_value.Clear() + struct_value.list_value.extend(value) + else: + raise ValueError('Unexpected type') + + +def _GetStructValue(struct_value): + which = struct_value.WhichOneof('kind') + if which == 'struct_value': + return struct_value.struct_value + elif which == 'null_value': + return None + elif which == 'number_value': + return struct_value.number_value + elif which == 'string_value': + return struct_value.string_value + elif which == 'bool_value': + return struct_value.bool_value + elif which == 'list_value': + return struct_value.list_value + elif which is None: + raise ValueError('Value not set') + + +class Struct(object): + """Class for Struct message type.""" + + __slots__ = () + + def __getitem__(self, key): + return _GetStructValue(self.fields[key]) + + def __setitem__(self, key, value): + _SetStructValue(self.fields[key], value) + + def __delitem__(self, key): + del self.fields[key] + + def __len__(self): + return len(self.fields) + + def __iter__(self): + return iter(self.fields) + + def _internal_assign(self, dictionary): + self.Clear() + self.update(dictionary) + + def _internal_compare(self, other): + size = len(self) + if size != len(other): + return False + for key, value in self.items(): + if key not in other: + return False + if isinstance(other[key], (dict, list)): + if not value._internal_compare(other[key]): + return False + elif value != other[key]: + return False + return True + + def keys(self): # pylint: disable=invalid-name + return self.fields.keys() + + def values(self): # pylint: disable=invalid-name + return [self[key] for key in self] + + def items(self): # pylint: disable=invalid-name + return [(key, self[key]) for key in self] + + def get_or_create_list(self, key): + """Returns a list for this key, creating if it didn't exist already.""" + if not self.fields[key].HasField('list_value'): + # Clear will mark list_value modified which will indeed create a list. + self.fields[key].list_value.Clear() + return self.fields[key].list_value + + def get_or_create_struct(self, key): + """Returns a struct for this key, creating if it didn't exist already.""" + if not self.fields[key].HasField('struct_value'): + # Clear will mark struct_value modified which will indeed create a struct. + self.fields[key].struct_value.Clear() + return self.fields[key].struct_value + + def update(self, dictionary): # pylint: disable=invalid-name + for key, value in dictionary.items(): + _SetStructValue(self.fields[key], value) + + +collections.abc.MutableMapping.register(Struct) + + +class ListValue(object): + """Class for ListValue message type.""" + + __slots__ = () + + def __len__(self): + return len(self.values) + + def append(self, value): + _SetStructValue(self.values.add(), value) + + def extend(self, elem_seq): + for value in elem_seq: + self.append(value) + + def __getitem__(self, index): + """Retrieves item by the specified index.""" + return _GetStructValue(self.values.__getitem__(index)) + + def __setitem__(self, index, value): + _SetStructValue(self.values.__getitem__(index), value) + + def __delitem__(self, key): + del self.values[key] + + def _internal_assign(self, elem_seq): + self.Clear() + self.extend(elem_seq) + + def _internal_compare(self, other): + size = len(self) + if size != len(other): + return False + for i in range(size): + if isinstance(other[i], (dict, list)): + if not self[i]._internal_compare(other[i]): + return False + elif self[i] != other[i]: + return False + return True + + def items(self): + for i in range(len(self)): + yield self[i] + + def add_struct(self): + """Appends and returns a struct value as the next value in the list.""" + struct_value = self.values.add().struct_value + # Clear will mark struct_value modified which will indeed create a struct. + struct_value.Clear() + return struct_value + + def add_list(self): + """Appends and returns a list value as the next value in the list.""" + list_value = self.values.add().list_value + # Clear will mark list_value modified which will indeed create a list. + list_value.Clear() + return list_value + + +collections.abc.MutableSequence.register(ListValue) + +# LINT.IfChange(wktbases) +WKTBASES = { + 'google.protobuf.Any': Any, + 'google.protobuf.Duration': Duration, + 'google.protobuf.FieldMask': FieldMask, + 'google.protobuf.ListValue': ListValue, + 'google.protobuf.Struct': Struct, + 'google.protobuf.Timestamp': Timestamp, +} +# LINT.ThenChange(//depot/google.protobuf/compiler/python/pyi_generator.cc:wktbases) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py new file mode 100644 index 00000000000..4f177f45cb5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py @@ -0,0 +1,255 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Constants and static functions to support protocol buffer wire format.""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import struct +from opentelemetry.agent._vendor.google.protobuf import descriptor +from opentelemetry.agent._vendor.google.protobuf import message + +TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. +TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 + +# These numbers identify the wire type of a protocol buffer value. +# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded +# tag-and-type to store one of these WIRETYPE_* constants. +# These values must match WireType enum in //google/protobuf/wire_format.h. +WIRETYPE_VARINT = 0 +WIRETYPE_FIXED64 = 1 +WIRETYPE_LENGTH_DELIMITED = 2 +WIRETYPE_START_GROUP = 3 +WIRETYPE_END_GROUP = 4 +WIRETYPE_FIXED32 = 5 +_WIRETYPE_MAX = 5 + +# Bounds for various integer types. +INT32_MAX = int((1 << 31) - 1) +INT32_MIN = int(-(1 << 31)) +UINT32_MAX = (1 << 32) - 1 + +INT64_MAX = (1 << 63) - 1 +INT64_MIN = -(1 << 63) +UINT64_MAX = (1 << 64) - 1 + +# "struct" format strings that will encode/decode the specified formats. +FORMAT_UINT32_LITTLE_ENDIAN = '> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK) + + +def ZigZagEncode(value): + """ZigZag Transform: Encodes signed integers so that they can be + + effectively used with varint encoding. See wire_format.h for + more details. + """ + if value >= 0: + return value << 1 + return (value << 1) ^ (~0) + + +def ZigZagDecode(value): + """Inverse of ZigZagEncode().""" + if not value & 0x1: + return value >> 1 + return (value >> 1) ^ (~0) + + +# The *ByteSize() functions below return the number of bytes required to +# serialize "field number + type" information and then serialize the value. + + +def Int32ByteSize(field_number, int32): + return Int64ByteSize(field_number, int32) + + +def Int32ByteSizeNoTag(int32): + return _VarUInt64ByteSizeNoTag(0xFFFFFFFFFFFFFFFF & int32) + + +def Int64ByteSize(field_number, int64): + # Have to convert to uint before calling UInt64ByteSize(). + return UInt64ByteSize(field_number, 0xFFFFFFFFFFFFFFFF & int64) + + +def UInt32ByteSize(field_number, uint32): + return UInt64ByteSize(field_number, uint32) + + +def UInt64ByteSize(field_number, uint64): + return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) + + +def SInt32ByteSize(field_number, int32): + return UInt32ByteSize(field_number, ZigZagEncode(int32)) + + +def SInt64ByteSize(field_number, int64): + return UInt64ByteSize(field_number, ZigZagEncode(int64)) + + +def Fixed32ByteSize(field_number, fixed32): + return TagByteSize(field_number) + 4 + + +def Fixed64ByteSize(field_number, fixed64): + return TagByteSize(field_number) + 8 + + +def SFixed32ByteSize(field_number, sfixed32): + return TagByteSize(field_number) + 4 + + +def SFixed64ByteSize(field_number, sfixed64): + return TagByteSize(field_number) + 8 + + +def FloatByteSize(field_number, flt): + return TagByteSize(field_number) + 4 + + +def DoubleByteSize(field_number, double): + return TagByteSize(field_number) + 8 + + +def BoolByteSize(field_number, b): + return TagByteSize(field_number) + 1 + + +def EnumByteSize(field_number, enum): + return UInt32ByteSize(field_number, enum) + + +def StringByteSize(field_number, string): + return BytesByteSize(field_number, string.encode('utf-8')) + + +def BytesByteSize(field_number, b): + return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(len(b)) + len(b) + + +def GroupByteSize(field_number, message): + return ( + 2 * TagByteSize(field_number) + message.ByteSize() # START and END group. + ) + + +def MessageByteSize(field_number, message): + return ( + TagByteSize(field_number) + + _VarUInt64ByteSizeNoTag(message.ByteSize()) + + message.ByteSize() + ) + + +def MessageSetItemByteSize(field_number, msg): + # First compute the sizes of the tags. + # There are 2 tags for the beginning and ending of the repeated group, that + # is field number 1, one with field number 2 (type_id) and one with field + # number 3 (message). + total_size = 2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3) + + # Add the number of bytes for type_id. + total_size += _VarUInt64ByteSizeNoTag(field_number) + + message_size = msg.ByteSize() + + # The number of bytes for encoding the length of the message. + total_size += _VarUInt64ByteSizeNoTag(message_size) + + # The size of the message. + total_size += message_size + return total_size + + +def TagByteSize(field_number): + """Returns the bytes required to serialize a tag with this field number.""" + # Just pass in type 0, since the type won't affect the tag+type size. + return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) + + +# Private helper function for the *ByteSize() functions above. + + +def _VarUInt64ByteSizeNoTag(uint64): + """Returns the number of bytes required to serialize a single varint + + using boundary value comparisons. (unrolled loop optimization -WPierce) + uint64 must be unsigned. + """ + if uint64 <= 0x7F: + return 1 + if uint64 <= 0x3FFF: + return 2 + if uint64 <= 0x1FFFFF: + return 3 + if uint64 <= 0xFFFFFFF: + return 4 + if uint64 <= 0x7FFFFFFFF: + return 5 + if uint64 <= 0x3FFFFFFFFFF: + return 6 + if uint64 <= 0x1FFFFFFFFFFFF: + return 7 + if uint64 <= 0xFFFFFFFFFFFFFF: + return 8 + if uint64 <= 0x7FFFFFFFFFFFFFFF: + return 9 + if uint64 > UINT64_MAX: + raise message.EncodeError('Value out of range: %d' % uint64) + return 10 + + +NON_PACKABLE_TYPES = ( + descriptor.FieldDescriptor.TYPE_STRING, + descriptor.FieldDescriptor.TYPE_GROUP, + descriptor.FieldDescriptor.TYPE_MESSAGE, + descriptor.FieldDescriptor.TYPE_BYTES, +) + + +def IsTypePackable(field_type): + """Return true iff packable = true is valid for fields of this type. + + Args: + field_type: a FieldDescriptor::Type value. + + Returns: + True iff fields of this type are packable. + """ + return field_type not in NON_PACKABLE_TYPES diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py new file mode 100644 index 00000000000..83e5f6c94d4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/json_enumvalue_options.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/json_enumvalue_options.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,google/protobuf/json_enumvalue_options.proto\x12\x0cpb.enumvalue\x1a google/protobuf/descriptor.proto\"0\n\x14JsonEnumValueOptions\x12\x16\n\x06string\x18\x01 \x01(\tR\x06stringX\x01:b\n\x04json\x12!.google.protobuf.EnumValueOptions\x18\xe6\x07 \x01(\x0b\x32\".pb.enumvalue.JsonEnumValueOptionsB\x06\xb2\x01\x03\x08\xea\x07R\x04jsonB\x1a\n\x18\x63om.google.protobuf.utilb\x08\x65\x64itionsp\xe9\x07') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.json_enumvalue_options_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\030com.google.protobuf.util' + _globals['json']._loaded_options = None + _globals['json']._serialized_options = b'\262\001\003\010\352\007' + _globals['_JSONENUMVALUEOPTIONS']._serialized_start=96 + _globals['_JSONENUMVALUEOPTIONS']._serialized_end=144 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py new file mode 100644 index 00000000000..72b112a9dde --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py @@ -0,0 +1,1247 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains routines for printing protocol messages in JSON format. + +Simple usage example: + + # Create a proto object and serialize it to a json format string. + message = my_proto_pb2.MyMessage(foo='bar') + json_string = json_format.MessageToJson(message) + + # Parse a json format string to proto object. + message = json_format.Parse(json_string, my_proto_pb2.MyMessage()) +""" + +__author__ = 'jieluo@google.com (Jie Luo)' + +import base64 +from collections import OrderedDict +import json +import math +from operator import methodcaller +import re + +from opentelemetry.agent._vendor.google.protobuf import descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import message_factory +from opentelemetry.agent._vendor.google.protobuf import symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers + +_INT_TYPES = frozenset([ + descriptor.FieldDescriptor.CPPTYPE_INT32, + descriptor.FieldDescriptor.CPPTYPE_UINT32, + descriptor.FieldDescriptor.CPPTYPE_INT64, + descriptor.FieldDescriptor.CPPTYPE_UINT64, +]) +_INT64_TYPES = frozenset([ + descriptor.FieldDescriptor.CPPTYPE_INT64, + descriptor.FieldDescriptor.CPPTYPE_UINT64, +]) +_FLOAT_TYPES = frozenset([ + descriptor.FieldDescriptor.CPPTYPE_FLOAT, + descriptor.FieldDescriptor.CPPTYPE_DOUBLE, +]) +_INFINITY = 'Infinity' +_NEG_INFINITY = '-Infinity' +_NAN = 'NaN' + +_UNPAIRED_SURROGATE_PATTERN = re.compile( + '[\ud800-\udbff](?![\udc00-\udfff])|(? self.max_recursion_depth: + raise ParseError( + 'Message too deep. Max recursion depth is {0}'.format( + self.max_recursion_depth + ) + ) + message_descriptor = message.DESCRIPTOR + full_name = message_descriptor.full_name + if not path: + path = message_descriptor.name + if _IsWrapperMessage(message_descriptor): + self._ConvertWrapperMessage(value, message, path) + elif full_name in _WKTJSONMETHODS: + methodcaller(_WKTJSONMETHODS[full_name][1], value, message, path)(self) + else: + self._ConvertFieldValuePair(value, message, path) + self.recursion_depth -= 1 + + def _ConvertFieldValuePair(self, js, message, path): + """Convert field value pairs into regular message. + + Args: + js: A JSON object to convert the field value pairs. + message: A regular protocol message to record the data. + path: parent path to log parse error info. + + Raises: + ParseError: In case of problems converting. + """ + names = [] + message_descriptor = message.DESCRIPTOR + fields_by_json_name = dict( + (f.json_name, f) for f in message_descriptor.fields + ) + + def _ClearFieldOrExtension(message, field): + if field.is_extension: + message.ClearExtension(field) + else: + message.ClearField(field.name) + + def _GetFieldOrExtension(message, field): + if field.is_extension: + return message.Extensions[field] + else: + return getattr(message, field.name) + + def _SetFieldOrExtension(message, field, value): + if field.is_extension: + message.Extensions[field] = value + else: + setattr(message, field.name, value) + + for name in js: + try: + field = fields_by_json_name.get(name, None) + if not field: + field = message_descriptor.fields_by_name.get(name, None) + if not field and _VALID_EXTENSION_NAME.match(name): + if not message_descriptor.is_extendable: + raise ParseError( + 'Message type {0} does not have extensions at {1}'.format( + message_descriptor.full_name, path + ) + ) + identifier = name[1:-1] # strip [] brackets + # pylint: disable=protected-access + field = message.Extensions._FindExtensionByName(identifier) + # pylint: enable=protected-access + if not field: + # Try looking for extension by the message type name, dropping the + # field name following the final . separator in full_name. + identifier = '.'.join(identifier.split('.')[:-1]) + # pylint: disable=protected-access + field = message.Extensions._FindExtensionByName(identifier) + # pylint: enable=protected-access + if not field: + if self.ignore_unknown_fields: + continue + raise ParseError( + ( + 'Message type "{0}" has no field named "{1}" at "{2}".\n' + ' Available Fields(except extensions): "{3}"' + ).format( + message_descriptor.full_name, + name, + path, + [f.json_name for f in message_descriptor.fields], + ) + ) + if name in names: + raise ParseError( + 'Message type "{0}" should not have multiple ' + '"{1}" fields at "{2}".'.format( + message.DESCRIPTOR.full_name, name, path + ) + ) + names.append(name) + value = js[name] + # Check no other oneof field is parsed. + if field.containing_oneof is not None and value is not None: + oneof_name = field.containing_oneof.name + if oneof_name in names: + raise ParseError( + 'Message type "{0}" should not have multiple ' + '"{1}" oneof fields at "{2}".'.format( + message.DESCRIPTOR.full_name, oneof_name, path + ) + ) + names.append(oneof_name) + + if value is None: + if ( + field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE + and field.message_type.full_name == 'google.protobuf.Value' + ): + sub_message = _GetFieldOrExtension(message, field) + sub_message.null_value = 0 + elif ( + field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM + and field.enum_type.full_name == 'google.protobuf.NullValue' + ): + _SetFieldOrExtension(message, field, 0) + else: + _ClearFieldOrExtension(message, field) + continue + + # Parse field value. + if _IsMapEntry(field): + _ClearFieldOrExtension(message, field) + self._ConvertMapFieldValue( + value, message, field, '{0}.{1}'.format(path, name) + ) + elif field.is_repeated: + _ClearFieldOrExtension(message, field) + if not isinstance(value, _LIST_LIKE): + raise ParseError( + 'repeated field {0} must be in [] which is {1} at {2}'.format( + name, value, path + ) + ) + if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + # Repeated message field. + for index, item in enumerate(value): + sub_message = _GetFieldOrExtension(message, field).add() + # None is a null_value in Value. + if ( + item is None + and sub_message.DESCRIPTOR.full_name + != 'google.protobuf.Value' + ): + raise ParseError( + 'null is not allowed to be used as an element' + ' in a repeated field at {0}.{1}[{2}]'.format( + path, name, index + ) + ) + self.ConvertMessage( + item, sub_message, '{0}.{1}[{2}]'.format(path, name, index) + ) + else: + # Repeated scalar field. + for index, item in enumerate(value): + if item is None: + raise ParseError( + 'null is not allowed to be used as an element' + ' in a repeated field at {0}.{1}[{2}]'.format( + path, name, index + ) + ) + self._ConvertAndAppendScalar( + message, field, item, '{0}.{1}[{2}]'.format(path, name, index) + ) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + sub_message = _GetFieldOrExtension(message, field) + sub_message.SetInParent() + self.ConvertMessage(value, sub_message, '{0}.{1}'.format(path, name)) + else: + self._ConvertAndSetScalar( + message, field, value, '{0}.{1}'.format(path, name) + ) + except ParseError as e: + if field and field.containing_oneof is None: + raise ParseError( + 'Failed to parse {0} field: {1}.'.format(name, e) + ) from e + else: + raise ParseError(str(e)) from e + except ValueError as e: + raise ParseError( + 'Failed to parse {0} field: {1}.'.format(name, e) + ) from e + except TypeError as e: + raise ParseError( + 'Failed to parse {0} field: {1}.'.format(name, e) + ) from e + + def _ConvertAnyMessage(self, value, message, path): + """Convert a JSON representation into Any message.""" + if isinstance(value, dict) and not value: + return + try: + type_url = value['@type'] + except KeyError as e: + raise ParseError( + '@type is missing when parsing any message at {0}'.format(path) + ) from e + + try: + sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) + except TypeError as e: + raise ParseError('{0} at {1}'.format(e, path)) from e + message_descriptor = sub_message.DESCRIPTOR + full_name = message_descriptor.full_name + if _IsWrapperMessage(message_descriptor): + self._ConvertWrapperMessage( + value['value'], sub_message, '{0}.value'.format(path) + ) + elif full_name in _WKTJSONMETHODS: + # For well-known types (including nested Any), use ConvertMessage + # to ensure recursion depth is properly tracked + self.ConvertMessage(value['value'], sub_message, '{0}.value'.format(path)) + else: + del value['@type'] + try: + self._ConvertFieldValuePair(value, sub_message, path) + finally: + value['@type'] = type_url + # Sets Any message + message.value = sub_message.SerializeToString() + message.type_url = type_url + + def _ConvertGenericMessage(self, value, message, path): + """Convert a JSON representation into message with FromJsonString.""" + # Duration, Timestamp, FieldMask have a FromJsonString method to do the + # conversion. Users can also call the method directly. + try: + message.FromJsonString(value) + except ValueError as e: + raise ParseError('{0} at {1}'.format(e, path)) from e + + def _ConvertValueMessage(self, value, message, path): + """Convert a JSON representation into Value message.""" + if isinstance(value, dict): + self.ConvertMessage(value, message.struct_value, path) + elif isinstance(value, _LIST_LIKE): + self.ConvertMessage(value, message.list_value, path) + elif value is None: + message.null_value = 0 + elif isinstance(value, bool): + message.bool_value = value + elif isinstance(value, str): + message.string_value = value + elif isinstance(value, _INT_OR_FLOAT): + message.number_value = value + else: + raise ParseError( + 'Value {0} has unexpected type {1} at {2}'.format( + value, type(value), path + ) + ) + + def _ConvertListOrTupleValueMessage(self, value, message, path): + """Convert a JSON representation into ListValue message.""" + if not isinstance(value, _LIST_LIKE): + raise ParseError( + 'ListValue must be in [] which is {0} at {1}'.format(value, path) + ) + message.ClearField('values') + for index, item in enumerate(value): + self.ConvertMessage( + item, message.values.add(), '{0}[{1}]'.format(path, index) + ) + + def _ConvertStructMessage(self, value, message, path): + """Convert a JSON representation into Struct message.""" + if not isinstance(value, dict): + raise ParseError( + 'Struct must be in a dict which is {0} at {1}'.format(value, path) + ) + # Clear will mark the struct as modified so it will be created even if + # there are no values. + message.Clear() + for key in value: + self.ConvertMessage( + value[key], message.fields[key], '{0}.{1}'.format(path, key) + ) + return + + def _ConvertWrapperMessage(self, value, message, path): + """Convert a JSON representation into Wrapper message.""" + field = message.DESCRIPTOR.fields_by_name['value'] + self._ConvertAndSetScalar( + message, field, value, path='{0}.value'.format(path) + ) + + def _ConvertMapFieldValue(self, value, message, field, path): + """Convert map field value for a message map field. + + Args: + value: A JSON object to convert the map field value. + message: A protocol message to record the converted data. + field: The descriptor of the map field to be converted. + path: parent path to log parse error info. + + Raises: + ParseError: In case of convert problems. + """ + if not isinstance(value, dict): + raise ParseError( + 'Map field {0} must be in a dict which is {1} at {2}'.format( + field.name, value, path + ) + ) + key_field = field.message_type.fields_by_name['key'] + value_field = field.message_type.fields_by_name['value'] + for key in value: + key_value = _ConvertScalarFieldValue( + key, + key_field, + '{0}.key'.format(path), + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), + require_str=True, + ) + if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + self.ConvertMessage( + value[key], + getattr(message, field.name)[key_value], + '{0}[{1}]'.format(path, key_value), + ) + else: + self._ConvertAndSetScalarToMapKey( + message, + field, + key_value, + value[key], + path='{0}[{1}]'.format(path, key_value), + ) + + def _ConvertAndSetScalar(self, message, field, js_value, path): + """Convert scalar from js_value and assign it to message.field.""" + try: + value = _ConvertScalarFieldValue( + js_value, + field, + path, + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), + ) + if field.is_extension: + message.Extensions[field] = value + else: + setattr(message, field.name, value) + except EnumStringValueParseError: + if not self.ignore_unknown_fields: + raise + + def _ConvertAndAppendScalar(self, message, repeated_field, js_value, path): + """Convert scalar from js_value and append it to message.repeated_field.""" + try: + if repeated_field.is_extension: + repeated = message.Extensions[repeated_field] + else: + repeated = getattr(message, repeated_field.name) + value = _ConvertScalarFieldValue( + js_value, + repeated_field, + path, + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), + ) + repeated.append(value) + except EnumStringValueParseError: + if not self.ignore_unknown_fields: + raise + + def _ConvertAndSetScalarToMapKey( + self, message, map_field, converted_key, js_value, path + ): + """Convert scalar from 'js_value' and add it to message.map_field[converted_key].""" + try: + getattr(message, map_field.name)[converted_key] = ( + _ConvertScalarFieldValue( + js_value, + map_field.message_type.fields_by_name['value'], + path, + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), + ) + ) + except EnumStringValueParseError: + if not self.ignore_unknown_fields: + raise + + +def _GetJsonEnumValueOption(ev, extension_descriptor): + """Helper to get the JsonEnumValueOptions for an enum value. + + Args: + ev: The EnumValueDescriptor. + extension_descriptor: The extension descriptor for 'pb.enumvalue.json'. + + Returns: + The JsonEnumValueOptions message if the extension is present, + otherwise None. + """ + if ev.GetOptions().HasExtension(extension_descriptor): + return ev.GetOptions().Extensions[extension_descriptor] + return None + + +def _GetCustomJsonEnumNames( + enum_type, custom_enum_names_cache, enumvalue_json_extension=None +): + """Helper to get a mapping from custom JSON name to EnumValueDescriptor. + + Args: + enum_type: The EnumDescriptor. + custom_enum_names_cache: A dict to store/lookup the cached map. + enumvalue_json_extension: The extension descriptor for 'pb.enumvalue.json', + or None to look it up in the default descriptor pool. + + Returns: + A dict mapping custom JSON name strings to EnumValueDescriptors. + """ + if enum_type in custom_enum_names_cache: + return custom_enum_names_cache[enum_type] + + custom_names = {} + if enumvalue_json_extension is None: + # Options are always put on the default pool, so we only search the default pool. + try: + enumvalue_json_extension = descriptor_pool.Default().FindExtensionByName( + 'pb.enumvalue.json' + ) + except KeyError: + enumvalue_json_extension = None + + if enumvalue_json_extension is not None: + for ev in enum_type.values: + options = ev.GetOptions() + if options.HasExtension(enumvalue_json_extension): + option = options.Extensions[enumvalue_json_extension] + if option.HasField('string'): + custom_names[option.string] = ev + + custom_enum_names_cache[enum_type] = custom_names + return custom_names + + +def _ConvertScalarFieldValue( + value, + field, + path, + custom_enum_names_cache, + enumvalue_json_extension=None, + require_str=False, +): + """Convert a single scalar field value. + + Args: + value: A scalar value to convert the scalar field value. + field: The descriptor of the field to convert. + path: parent path to log parse error info. + custom_enum_names_cache: A dict to store/lookup custom enum names. + enumvalue_json_extension: The extension descriptor for 'pb.enumvalue.json', + or None if not loaded. + require_str: If True, the field value must be a str. + + Returns: + The converted scalar field value + + Raises: + ParseError: In case of convert problems. + EnumStringValueParseError: In case of unknown enum string value. + """ + try: + if field.cpp_type in _INT_TYPES: + return _ConvertInteger(value) + elif field.cpp_type in _FLOAT_TYPES: + return _ConvertFloat(value, field) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: + return _ConvertBool(value, require_str) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: + if field.type == descriptor.FieldDescriptor.TYPE_BYTES: + if isinstance(value, str): + encoded = value.encode('utf-8') + else: + encoded = value + # Add extra padding '=' + padded_value = encoded + b'=' * (4 - len(encoded) % 4) + return base64.urlsafe_b64decode(padded_value) + else: + # Checking for unpaired surrogates appears to be unreliable, + # depending on the specific Python version, so we check manually. + if _UNPAIRED_SURROGATE_PATTERN.search(value): + raise ParseError('Unpaired surrogate') + return value + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: + # Convert an enum value. + enum_value = field.enum_type.values_by_name.get(value, None) + # First check to see if we have a custom enum string. + if ( + enum_value is None + and isinstance(value, str) + and enumvalue_json_extension is not None + ): + custom_names = _GetCustomJsonEnumNames( + field.enum_type, + custom_enum_names_cache, + enumvalue_json_extension, + ) + enum_value = custom_names.get(value, None) + # If not, try parsing it as an integer. + if enum_value is None: + try: + number = int(value) + enum_value = field.enum_type.values_by_number.get(number, None) + except ValueError as e: + # Since parsing to integer failed and lookup in values_by_name didn't + # find this name, we have an enum string value which is unknown. + raise EnumStringValueParseError( + 'Invalid enum value {0} for enum type {1}'.format( + value, field.enum_type.full_name + ) + ) from e + if enum_value is None: + if field.enum_type.is_closed: + raise ParseError( + 'Invalid enum value {0} for enum type {1}'.format( + value, field.enum_type.full_name + ) + ) + else: + return number + return enum_value.number + except EnumStringValueParseError as e: + raise EnumStringValueParseError('{0} at {1}'.format(e, path)) from e + except ParseError as e: + raise ParseError('{0} at {1}'.format(e, path)) from e + + +def _ConvertInteger(value): + """Convert an integer. + + Args: + value: A scalar value to convert. + + Returns: + The integer value. + + Raises: + ParseError: If an integer couldn't be consumed. + """ + if isinstance(value, float) and not value.is_integer(): + raise ParseError("Couldn't parse integer: {0}".format(value)) + + if isinstance(value, str) and value.find(' ') != -1: + raise ParseError('Couldn\'t parse integer: "{0}"'.format(value)) + + if isinstance(value, bool): + raise ParseError( + 'Bool value {0} is not acceptable for integer field'.format(value) + ) + + try: + return int(value) + except ValueError as e: + # Attempt to parse as an integer-valued float. + try: + f = float(value) + except ValueError: + # Raise the original exception for the int parse. + raise e # pylint: disable=raise-missing-from + if not f.is_integer(): + raise ParseError( + 'Couldn\'t parse non-integer string: "{0}"'.format(value) + ) from e + return int(f) + + +def _ConvertFloat(value, field): + """Convert an floating point number.""" + if isinstance(value, float): + if math.isnan(value): + raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead') + if math.isinf(value): + if value > 0: + raise ParseError( + "Couldn't parse Infinity or value too large, " + 'use quoted "Infinity" instead' + ) + else: + raise ParseError( + "Couldn't parse -Infinity or value too small, " + 'use quoted "-Infinity" instead' + ) + if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: + # pylint: disable=protected-access + if value > type_checkers._FLOAT_MAX: + raise ParseError('Float value too large') + # pylint: disable=protected-access + if value < type_checkers._FLOAT_MIN: + raise ParseError('Float value too small') + if value == 'nan': + raise ParseError('Couldn\'t parse float "nan", use "NaN" instead') + try: + # Assume Python compatible syntax. + return float(value) + except ValueError as e: + # Check alternative spellings. + if value == _NEG_INFINITY: + return float('-inf') + elif value == _INFINITY: + return float('inf') + elif value == _NAN: + return float('nan') + else: + raise ParseError("Couldn't parse float: {0}".format(value)) from e + + +def _ConvertBool(value, require_str): + """Convert a boolean value. + + Args: + value: A scalar value to convert. + require_str: If True, value must be a str. + + Returns: + The bool parsed. + + Raises: + ParseError: If a boolean value couldn't be consumed. + """ + if require_str: + if value == 'true': + return True + elif value == 'false': + return False + else: + raise ParseError('Expected "true" or "false", not {0}'.format(value)) + + if not isinstance(value, bool): + raise ParseError('Expected true or false without quotes') + return value + + +_WKTJSONMETHODS = { + 'google.protobuf.Any': ['_AnyMessageToJsonObject', '_ConvertAnyMessage'], + 'google.protobuf.Duration': [ + '_GenericMessageToJsonObject', + '_ConvertGenericMessage', + ], + 'google.protobuf.FieldMask': [ + '_GenericMessageToJsonObject', + '_ConvertGenericMessage', + ], + 'google.protobuf.ListValue': [ + '_ListValueMessageToJsonObject', + '_ConvertListOrTupleValueMessage', + ], + 'google.protobuf.Struct': [ + '_StructMessageToJsonObject', + '_ConvertStructMessage', + ], + 'google.protobuf.Timestamp': [ + '_GenericMessageToJsonObject', + '_ConvertGenericMessage', + ], + 'google.protobuf.Value': [ + '_ValueMessageToJsonObject', + '_ConvertValueMessage', + ], +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py new file mode 100644 index 00000000000..7e029843db7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/json_options.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/json_options.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import json_enumvalue_options_pb2 as google_dot_protobuf_dot_json__enumvalue__options__pb2 + +from opentelemetry.agent._vendor.google.protobuf.json_enumvalue_options_pb2 import * + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"google/protobuf/json_options.proto\x12\x02pb\x1a,google/protobuf/json_enumvalue_options.protoB\x1a\n\x18\x63om.google.protobuf.utilP\x00\x62\x08\x65\x64itionsp\xe9\x07') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.json_options_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\030com.google.protobuf.util' +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py new file mode 100644 index 00000000000..c0e8001069a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py @@ -0,0 +1,467 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +# TODO: We should just make these methods all "pure-virtual" and move +# all implementation out, into reflection.py for now. +"""Contains an abstract base class for protocol messages.""" + +__author__ = 'robinson@google.com (Will Robinson)' + +_INCONSISTENT_MESSAGE_ATTRIBUTES = ('Extensions',) + + +class Error(Exception): + """Base error type for this module.""" + + pass + + +class DecodeError(Error): + """Exception raised when deserializing messages.""" + + pass + + +class EncodeError(Error): + """Exception raised when serializing messages.""" + + pass + + +class FrozenInstanceError(AttributeError): + """Exception raised when mutating a frozen message.""" + + pass + + +class Message(object): + """Abstract base class for protocol messages. + + Protocol message classes are almost always generated by the protocol + compiler. These generated types subclass Message and implement the methods + shown below. + """ + + # TODO: Link to an HTML document here. + + # TODO: Document that instances of this class will also + # have an Extensions attribute with __getitem__ and __setitem__. + # Again, not sure how to best convey this. + + # TODO: Document these fields and methods. + + __slots__ = [] + + #: The :class:`google.protobuf.Descriptor` + # for this message type. + DESCRIPTOR = None + + def __deepcopy__(self, memo=None): + clone = type(self)() + clone.MergeFrom(self) + return clone + + def __dir__(self): + """Provides the list of all accessible Message attributes.""" + message_attributes = set(super().__dir__()) + + # TODO: Remove this once the UPB implementation is improved. + # The UPB proto implementation currently doesn't provide proto fields as + # attributes and they have to added. + if self.DESCRIPTOR is not None: + for field in self.DESCRIPTOR.fields: + message_attributes.add(field.name) + + # The Fast C++ proto implementation provides inaccessible attributes that + # have to be removed. + for attribute in _INCONSISTENT_MESSAGE_ATTRIBUTES: + if attribute not in message_attributes: + continue + try: + getattr(self, attribute) + except AttributeError: + message_attributes.remove(attribute) + + return sorted(message_attributes) + + def __eq__(self, other_msg): + """Recursively compares two messages by value and structure.""" + raise NotImplementedError + + def __ne__(self, other_msg): + # Can't just say self != other_msg, since that would infinitely recurse. :) + return not self == other_msg + + def __hash__(self): + raise TypeError('unhashable object') + + def __str__(self): + """Outputs a human-readable representation of the message.""" + raise NotImplementedError + + def __unicode__(self): + """Outputs a human-readable representation of the message.""" + raise NotImplementedError + + def __contains__(self, field_name_or_key): + """Checks if a certain field is set for the message. + + Has presence fields return true if the field is set, false if the field is + not set. Fields without presence do raise `ValueError` (this includes + repeated fields, map fields, and implicit presence fields). + + If field_name is not defined in the message descriptor, `ValueError` will + be raised. + Note: WKT Struct checks if the key is contained in fields. ListValue checks + if the item is contained in the list. + + Args: + field_name_or_key: For Struct, the key (str) of the fields map. For + ListValue, any type that may be contained in the list. For other + messages, name of the field (str) to check for presence. + + Returns: + bool: For Struct, whether the item is contained in fields. For ListValue, + whether the item is contained in the list. For other message, + whether a value has been set for the named field. + + Raises: + ValueError: For normal messages, if the `field_name_or_key` is not a + member of this message or `field_name_or_key` is not a string. + """ + raise NotImplementedError + + def MergeFrom(self, other_msg): + """Merges the contents of the specified message into current message. + + This method merges the contents of the specified message into the current + message. Singular fields that are set in the specified message overwrite + the corresponding fields in the current message. Repeated fields are + appended. Singular sub-messages and groups are recursively merged. + + Args: + other_msg (Message): A message to merge into the current message. + """ + raise NotImplementedError + + def CopyFrom(self, other_msg): + """Copies the content of the specified message into the current message. + + The method clears the current message and then merges the specified + message using MergeFrom. + + Args: + other_msg (Message): A message to copy into the current one. + """ + if self is other_msg: + return + self.Clear() + self.MergeFrom(other_msg) + + def Clear(self): + """Clears all data that was set in the message.""" + raise NotImplementedError + + def SetInParent(self): + """Mark this as present in the parent. + + This normally happens automatically when you assign a field of a + sub-message, but sometimes you want to make the sub-message + present while keeping it empty. If you find yourself using this, + you may want to reconsider your design. + """ + raise NotImplementedError + + def IsInitialized(self): + """Checks if the message is initialized. + + Returns: + bool: The method returns True if the message is initialized (i.e. all of + its required fields are set). + """ + raise NotImplementedError + + # TODO: MergeFromString() should probably return None and be + # implemented in terms of a helper that returns the # of bytes read. Our + # deserialization routines would use the helper when recursively + # deserializing, but the end user would almost always just want the no-return + # MergeFromString(). + + def MergeFromString(self, serialized): + """Merges serialized protocol buffer data into this message. + + When we find a field in `serialized` that is already present + in this message: + + - If it's a "repeated" field, we append to the end of our list. + - Else, if it's a scalar, we overwrite our field. + - Else, (it's a nonrepeated composite), we recursively merge + into the existing composite. + + Args: + serialized (bytes): Any object that allows us to call + ``memoryview(serialized)`` to access a string of bytes using the buffer + interface. + + Returns: + int: The number of bytes read from `serialized`. + For non-group messages, this will always be `len(serialized)`, + but for messages which are actually groups, this will + generally be less than `len(serialized)`, since we must + stop when we reach an ``END_GROUP`` tag. Note that if + we *do* stop because of an ``END_GROUP`` tag, the number + of bytes returned does not include the bytes + for the ``END_GROUP`` tag information. + + Raises: + DecodeError: if the input cannot be parsed. + """ + # TODO: Document handling of unknown fields. + # TODO: When we switch to a helper, this will return None. + raise NotImplementedError + + def ParseFromString(self, serialized): + """Parse serialized protocol buffer data in binary form into this message. + + Like :func:`MergeFromString()`, except we clear the object first. + + Raises: + message.DecodeError if the input cannot be parsed. + """ + self.Clear() + return self.MergeFromString(serialized) + + def SerializeToString(self, **kwargs): + """Serializes the protocol message to a binary string. + + Keyword Args: + deterministic (bool): If true, requests deterministic serialization + of the protobuf. Note that there is no canonical representation of + protobuf messages: deterministic serialization only means 'consistent + for current build, but not stable between rebuilds, and may not match + decisions made by other languages'. + See + https://protobuf.dev/programming-guides/serialization-not-canonical/. + + Returns: + A binary string representation of the message if all of the required + fields in the message are set (i.e. the message is initialized). + + Raises: + EncodeError: if the message isn't initialized (see :func:`IsInitialized`). + """ + raise NotImplementedError + + def SerializePartialToString(self, **kwargs): + """Serializes the protocol message to a binary string. + + This method is similar to SerializeToString but doesn't check if the + message is initialized. + + Keyword Args: + deterministic (bool): If true, requests deterministic serialization + of the protobuf. Note that 'deterministic' serialization only means + 'Consistent for current build, but still arbitary and not stable over + time'. There is no canonical representation of protobuf messages, + See + https://protobuf.dev/programming-guides/serialization-not-canonical/. + + Returns: + bytes: A serialized representation of the partial message. + """ + raise NotImplementedError + + # TODO: Decide whether we like these better + # than auto-generated has_foo() and clear_foo() methods + # on the instances themselves. This way is less consistent + # with C++, but it makes reflection-type access easier and + # reduces the number of magically autogenerated things. + # + # TODO: Be sure to document (and test) exactly + # which field names are accepted here. Are we case-sensitive? + # What do we do with fields that share names with Python keywords + # like 'lambda' and 'yield'? + # + # nnorwitz says: + # """ + # Typically (in python), an underscore is appended to names that are + # keywords. So they would become lambda_ or yield_. + # """ + def ListFields(self): + """Returns a list of (FieldDescriptor, value) tuples for present fields. + + A message field is non-empty if HasField() would return true. A singular + primitive field is non-empty if HasField() would return true in proto2 or it + is non zero in proto3. A repeated field is non-empty if it contains at least + one element. The fields are ordered by field number. + + Returns: + list[tuple(FieldDescriptor, value)]: field descriptors and values + for all fields in the message which are not empty. The values vary by + field type. + """ + raise NotImplementedError + + def HasField(self, field_name): + """Checks if a certain field is set for the message. + + For a oneof group, checks if any field inside is set. Note that if the + field_name is not defined in the message descriptor, :exc:`ValueError` will + be raised. + + Args: + field_name (str): The name of the field to check for presence. + + Returns: + bool: Whether a value has been set for the named field. + + Raises: + ValueError: if the `field_name` is not a member of this message. + """ + raise NotImplementedError + + def ClearField(self, field_name): + """Clears the contents of a given field. + + Inside a oneof group, clears the field set. If the name neither refers to a + defined field or oneof group, :exc:`ValueError` is raised. + + Args: + field_name (str): The name of the field to check for presence. + + Raises: + ValueError: if the `field_name` is not a member of this message. + """ + raise NotImplementedError + + def WhichOneof(self, oneof_group): + """Returns the name of the field that is set inside a oneof group. + + If no field is set, returns None. + + Args: + oneof_group (str): the name of the oneof group to check. + + Returns: + str or None: The name of the group that is set, or None. + + Raises: + ValueError: no group with the given name exists + """ + raise NotImplementedError + + def HasExtension(self, field_descriptor): + """Checks if a certain extension is present for this message. + + Extensions are retrieved using the :attr:`Extensions` mapping (if present). + + Args: + field_descriptor: The field descriptor for the extension to check. + + Returns: + bool: Whether the extension is present for this message. + + Raises: + KeyError: if the extension is repeated. Similar to repeated fields, + there is no separate notion of presence: a "not present" repeated + extension is an empty list. + """ + raise NotImplementedError + + def ClearExtension(self, field_descriptor): + """Clears the contents of a given extension. + + Args: + field_descriptor: The field descriptor for the extension to clear. + """ + raise NotImplementedError + + def UnknownFields(self): + """Returns the UnknownFieldSet. + + Returns: + UnknownFieldSet: The unknown fields stored in this message. + """ + raise NotImplementedError + + def DiscardUnknownFields(self): + """Clears all fields in the :class:`UnknownFieldSet`. + + This operation is recursive for nested message. + """ + raise NotImplementedError + + def ByteSize(self): + """Returns the serialized size of this message. + + Recursively calls ByteSize() on all contained messages. + + Returns: + int: The number of bytes required to serialize this message. + """ + raise NotImplementedError + + @classmethod + def FromString(cls, s): + raise NotImplementedError + + def _SetListener(self, message_listener): + """Internal method used by the protocol message implementation. + + Clients should not call this directly. + + Sets a listener that this message will call on certain state transitions. + + The purpose of this method is to register back-edges from children to + parents at runtime, for the purpose of setting "has" bits and + byte-size-dirty bits in the parent and ancestor objects whenever a child or + descendant object is modified. + + If the client wants to disconnect this Message from the object tree, she + explicitly sets callback to None. + + If message_listener is None, unregisters any existing listener. Otherwise, + message_listener must implement the MessageListener interface in + internal/message_listener.py, and we discard any listener registered + via a previous _SetListener() call. + """ + raise NotImplementedError + + def __getstate__(self): + """Support the pickle protocol.""" + return dict(serialized=self.SerializePartialToString()) + + def __setstate__(self, state): + """Support the pickle protocol.""" + self.__init__() + serialized = state['serialized'] + # On Python 3, using encoding='latin1' is required for unpickling + # protos pickled by Python 2. + if not isinstance(serialized, bytes): + serialized = serialized.encode('latin1') + self.ParseFromString(serialized) + + def __reduce__(self): + message_descriptor = self.DESCRIPTOR + if message_descriptor.containing_type is None: + return type(self), (), self.__getstate__() + # the message type must be nested. + # Python does not pickle nested classes; use the symbol_database on the + # receiving end. + container = message_descriptor + return ( + _InternalConstructMessage, + (container.full_name,), + self.__getstate__(), + ) + + +def _InternalConstructMessage(full_name): + """Constructs a nested message.""" + from opentelemetry.agent._vendor.google.protobuf import symbol_database # pylint:disable=g-import-not-at-top + + return symbol_database.Default().GetSymbol(full_name)() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py new file mode 100644 index 00000000000..3858440b219 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py @@ -0,0 +1,188 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Provides a factory class for generating dynamic messages. + +The easiest way to use this class is if you have access to the FileDescriptor +protos containing the messages you want to create you can just do the following: + +message_classes = message_factory.GetMessages(iterable_of_file_descriptors) +my_proto_instance = message_classes['some.proto.package.MessageName']() +""" + +__author__ = 'matthewtoia@google.com (Matt Toia)' + +import warnings + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import message +from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation + +if api_implementation.Type() == 'python': + from opentelemetry.agent._vendor.google.protobuf.internal import python_message as message_impl +else: + from opentelemetry.agent._vendor.google.protobuf.pyext import cpp_message as message_impl # pylint: disable=g-import-not-at-top + +# The type of all Message classes. +_GENERATED_PROTOCOL_MESSAGE_TYPE = message_impl.GeneratedProtocolMessageType + + +def GetMessageClass(descriptor): + """Obtains a proto2 message class based on the passed in descriptor. + + Passing a descriptor with a fully qualified name matching a previous + invocation will cause the same class to be returned. + + Args: + descriptor: The descriptor to build from. + + Returns: + A class describing the passed in descriptor. + """ + concrete_class = getattr(descriptor, '_concrete_class', None) + if concrete_class: + return concrete_class + return _InternalCreateMessageClass(descriptor) + + +def GetMessageClassesForFiles(files, pool): + """Gets all the messages from specified files. + + This will find and resolve dependencies, failing if the descriptor + pool cannot satisfy them. + + This will not return the classes for nested types within those classes, for + those, use GetMessageClass() on the nested types within their containing + messages. + + For example, for the message: + + message NestedTypeMessage { + message NestedType { + string data = 1; + } + NestedType nested = 1; + } + + NestedTypeMessage will be in the result, but not + NestedTypeMessage.NestedType. + + Args: + files: The file names to extract messages from. + pool: The descriptor pool to find the files including the dependent files. + + Returns: + A dictionary mapping proto names to the message classes. + """ + result = {} + for file_name in files: + file_desc = pool.FindFileByName(file_name) + for desc in file_desc.message_types_by_name.values(): + result[desc.full_name] = GetMessageClass(desc) + + # While the extension FieldDescriptors are created by the descriptor pool, + # the python classes created in the factory need them to be registered + # explicitly, which is done below. + # + # The call to RegisterExtension will specifically check if the + # extension was already registered on the object and either + # ignore the registration if the original was the same, or raise + # an error if they were different. + + for extension in file_desc.extensions_by_name.values(): + _ = GetMessageClass(extension.containing_type) + if api_implementation.Type() != 'python': + # TODO: Remove this check here. Duplicate extension + # register check should be in descriptor_pool. + if extension is not pool.FindExtensionByNumber( + extension.containing_type, extension.number + ): + raise ValueError('Double registration of Extensions') + # Recursively load protos for extension field, in order to be able to + # fully represent the extension. This matches the behavior for regular + # fields too. + if extension.message_type: + GetMessageClass(extension.message_type) + return result + + +def _InternalCreateMessageClass(descriptor): + """Builds a proto2 message class based on the passed in descriptor. + + Args: + descriptor: The descriptor to build from. + + Returns: + A class describing the passed in descriptor. + """ + descriptor_name = descriptor.name + result_class = _GENERATED_PROTOCOL_MESSAGE_TYPE( + descriptor_name, + (message.Message,), + { + 'DESCRIPTOR': descriptor, + # If module not set, it wrongly points to message_factory module. + '__module__': None, + }, + ) + for field in descriptor.fields: + if field.message_type: + GetMessageClass(field.message_type) + + for extension in result_class.DESCRIPTOR.extensions: + extended_class = GetMessageClass(extension.containing_type) + if api_implementation.Type() != 'python': + # TODO: Remove this check here. Duplicate extension + # register check should be in descriptor_pool. + pool = extension.containing_type.file.pool + if extension is not pool.FindExtensionByNumber( + extension.containing_type, extension.number + ): + raise ValueError('Double registration of Extensions') + if extension.message_type: + GetMessageClass(extension.message_type) + return result_class + + +# Deprecated. Please use GetMessageClass() or GetMessageClassesForFiles() +# method above instead. +class MessageFactory(object): + """Factory for creating Proto2 messages from descriptors in a pool.""" + + def __init__(self, pool=None): + """Initializes a new factory.""" + self.pool = pool or descriptor_pool.DescriptorPool() + + +def GetMessages(file_protos, pool=None): + """Builds a dictionary of all the messages available in a set of files. + + Args: + file_protos: Iterable of FileDescriptorProto to build messages out of. + pool: The descriptor pool to add the file protos. + + Returns: + A dictionary mapping proto names to the message classes. This will include + any dependent messages as well as any messages defined in the same file as + a specified message. + """ + # The cpp implementation of the protocol buffer library requires to add the + # message in topological order of the dependency graph. + des_pool = pool or descriptor_pool.DescriptorPool() + file_by_name = {file_proto.name: file_proto for file_proto in file_protos} + + def _AddFile(file_proto): + for dependency in file_proto.dependency: + if dependency in file_by_name: + # Remove from elements to be visited, in order to cut cycles. + _AddFile(file_by_name.pop(dependency)) + des_pool.Add(file_proto) + + while file_by_name: + _AddFile(file_by_name.popitem()[1]) + return GetMessageClassesForFiles( + [file_proto.name for file_proto in file_protos], des_pool + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py new file mode 100644 index 00000000000..ee373e92cbf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py @@ -0,0 +1,153 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains the Nextgen Pythonic protobuf APIs.""" + +import io +from typing import Text, Type, TypeVar + +from opentelemetry.agent._vendor.google.protobuf.internal import decoder +from opentelemetry.agent._vendor.google.protobuf.internal import encoder +from opentelemetry.agent._vendor.google.protobuf.message import Message + +_MESSAGE = TypeVar('_MESSAGE', bound='Message') + + +def serialize(message: _MESSAGE, deterministic: bool = None) -> bytes: + """Return the serialized proto. + + Args: + message: The proto message to be serialized. + deterministic: If true, requests deterministic serialization of the + protobuf, with predictable ordering of map keys. + + Returns: + A binary bytes representation of the message. + """ + return message.SerializeToString(deterministic=deterministic) + + +def parse(message_class: Type[_MESSAGE], payload: bytes) -> _MESSAGE: + """Given a serialized data in binary form, deserialize it into a Message. + + Args: + message_class: The message meta class. + payload: A serialized bytes in binary form. + + Returns: + A new message deserialized from payload. + """ + new_message = message_class() + new_message.ParseFromString(payload) + return new_message + + +def serialize_length_prefixed(message: _MESSAGE, output: io.BytesIO) -> None: + """Writes the size of the message as a varint and the serialized message. + + Writes the size of the message as a varint and then the serialized message. + This allows more data to be written to the output after the message. Use + parse_length_prefixed to parse messages written by this method. + + The output stream must be buffered, e.g. using + https://docs.python.org/3/library/io.html#buffered-streams. + + Example usage: + out = io.BytesIO() + for msg in message_list: + proto.serialize_length_prefixed(msg, out) + + Args: + message: The protocol buffer message that should be serialized. + output: BytesIO or custom buffered IO that data should be written to. + """ + payload = serialize(message) + size = len(payload) + encoder._VarintEncoder()(output.write, size) + out_size = output.write(payload) + + if out_size != size: + raise TypeError( + 'Failed to write complete message (wrote: %d, expected: %d)' + '. Ensure output is using buffered IO.' % (out_size, size) + ) + + +def parse_length_prefixed( + message_class: Type[_MESSAGE], input_bytes: io.BytesIO +) -> _MESSAGE: + """Parse a message from input_bytes. + + Args: + message_class: The protocol buffer message class that parser should parse. + input_bytes: A buffered input. + + Example usage: + while True: + msg = proto.parse_length_prefixed(message_class, input_bytes) + if msg is None: + break + ... + + Returns: + A parsed message if successful. None if input_bytes is at EOF. + """ + size = decoder._DecodeVarint(input_bytes) + if size is None: + # It is the end of buffered input. See example usage in the + # API description. + return None + + message = message_class() + + if size == 0: + return message + + parsed_size = message.ParseFromString(input_bytes.read(size)) + if parsed_size != size: + raise ValueError( + 'Truncated message or non-buffered input_bytes: ' + 'Expected {0} bytes but only {1} bytes parsed for ' + '{2}.'.format(size, parsed_size, message.DESCRIPTOR.name) + ) + return message + + +def byte_size(message: Message) -> int: + """Returns the serialized size of this message. + + Args: + message: A proto message. + + Returns: + int: The number of bytes required to serialize this message. + """ + return message.ByteSize() + + +def clear_message(message: Message) -> None: + """Clears all data that was set in the message. + + Args: + message: The proto message to be cleared. + """ + message.Clear() + + +def clear_field(message: Message, field_name: Text) -> None: + """Clears the contents of a given field. + + Inside a oneof group, clears the field set. If the name neither refers to a + defined field or oneof group, :exc:`ValueError` is raised. + + Args: + message: The proto message. + field_name (str): The name of the field to be cleared. + + Raises: + ValueError: if the `field_name` is not a member of this message. + """ + message.ClearField(field_name) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py new file mode 100644 index 00000000000..d98b4025cbf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py @@ -0,0 +1,117 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Dynamic Protobuf class creator.""" + +from collections import OrderedDict +import hashlib +import os + +from opentelemetry.agent._vendor.google.protobuf import descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import message_factory + + +def _GetMessageFromFactory(pool, full_name): + """Get a proto class from the MessageFactory by name. + + Args: + pool: a descriptor pool. + full_name: str, the fully qualified name of the proto type. + + Returns: + A class, for the type identified by full_name. + Raises: + KeyError, if the proto is not found in the factory's descriptor pool. + """ + proto_descriptor = pool.FindMessageTypeByName(full_name) + proto_cls = message_factory.GetMessageClass(proto_descriptor) + return proto_cls + + +def MakeSimpleProtoClass(fields, full_name=None, pool=None): + """Create a Protobuf class whose fields are basic types. + + Note: this doesn't validate field names! + + Args: + fields: dict of {name: field_type} mappings for each field in the proto. If + this is an OrderedDict the order will be maintained, otherwise the fields + will be sorted by name. + full_name: optional str, the fully-qualified name of the proto type. + pool: optional DescriptorPool instance. + + Returns: + a class, the new protobuf class with a FileDescriptor. + """ + pool_instance = pool or descriptor_pool.DescriptorPool() + if full_name is not None: + try: + proto_cls = _GetMessageFromFactory(pool_instance, full_name) + return proto_cls + except KeyError: + # The factory's DescriptorPool doesn't know about this class yet. + pass + + # Get a list of (name, field_type) tuples from the fields dict. If fields was + # an OrderedDict we keep the order, but otherwise we sort the field to ensure + # consistent ordering. + field_items = fields.items() + if not isinstance(fields, OrderedDict): + field_items = sorted(field_items) + + # Use a consistent file name that is unlikely to conflict with any imported + # proto files. + fields_hash = hashlib.sha1(usedforsecurity=False) + for f_name, f_type in field_items: + fields_hash.update(f_name.encode('utf-8')) + fields_hash.update(str(f_type).encode('utf-8')) + proto_file_name = fields_hash.hexdigest() + '.proto' + + # If the proto is anonymous, use the same hash to name it. + if full_name is None: + full_name = ( + 'net.proto2.python.public.proto_builder.AnonymousProto_' + + fields_hash.hexdigest() + ) + try: + proto_cls = _GetMessageFromFactory(pool_instance, full_name) + return proto_cls + except KeyError: + # The factory's DescriptorPool doesn't know about this class yet. + pass + + # This is the first time we see this proto: add a new descriptor to the pool. + pool_instance.Add( + _MakeFileDescriptorProto(proto_file_name, full_name, field_items) + ) + return _GetMessageFromFactory(pool_instance, full_name) + + +def _MakeFileDescriptorProto(proto_file_name, full_name, field_items): + """Populate FileDescriptorProto for MessageFactory's DescriptorPool.""" + package, name = full_name.rsplit('.', 1) + file_proto = descriptor_pb2.FileDescriptorProto() + file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name) + file_proto.package = package + desc_proto = file_proto.message_type.add() + desc_proto.name = name + for f_number, (f_name, f_type) in enumerate(field_items, 1): + field_proto = desc_proto.field.add() + field_proto.name = f_name + # # If the number falls in the reserved range, reassign it to the correct + # # number after the range. + if f_number >= descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER: + f_number += ( + descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER + - descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER + + 1 + ) + field_proto.number = f_number + field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL + field_proto.type = f_type + return file_proto diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py new file mode 100644 index 00000000000..af95a43b4e2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py @@ -0,0 +1,81 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains the Nextgen Pythonic Protobuf JSON APIs.""" + +from typing import Optional, Type + +from opentelemetry.agent._vendor.google.protobuf import json_format +from opentelemetry.agent._vendor.google.protobuf.descriptor_pool import DescriptorPool +from opentelemetry.agent._vendor.google.protobuf.message import Message + + +def serialize( + message: Message, + always_print_fields_with_no_presence: bool = False, + preserving_proto_field_name: bool = False, + use_integers_for_enums: bool = False, + descriptor_pool: Optional[DescriptorPool] = None, +) -> dict: + """Converts protobuf message to a dictionary. + + When the dictionary is encoded to JSON, it conforms to ProtoJSON spec. + + Args: + message: The protocol buffers message instance to serialize. + always_print_fields_with_no_presence: If True, fields without presence + (implicit presence scalars, repeated fields, and map fields) will always + be serialized. Any field that supports presence is not affected by this + option (including singular message fields and oneof fields). + preserving_proto_field_name: If True, use the original proto field names as + defined in the .proto file. If False, convert the field names to + lowerCamelCase. + use_integers_for_enums: If true, print integers instead of enum names. + descriptor_pool: A Descriptor Pool for resolving types. If None use the + default. + + Returns: + A dict representation of the protocol buffer message. + """ + return json_format.MessageToDict( + message, + always_print_fields_with_no_presence=always_print_fields_with_no_presence, + preserving_proto_field_name=preserving_proto_field_name, + use_integers_for_enums=use_integers_for_enums, + ) + + +def parse( + message_class: Type[Message], + js_dict: dict, + ignore_unknown_fields: bool = False, + descriptor_pool: Optional[DescriptorPool] = None, + max_recursion_depth: int = 100, +) -> Message: + """Parses a JSON dictionary representation into a message. + + Args: + message_class: The message meta class. + js_dict: Dict representation of a JSON message. + ignore_unknown_fields: If True, do not raise errors for unknown fields. + descriptor_pool: A Descriptor Pool for resolving types. If None use the + default. + max_recursion_depth: max recursion depth of JSON message to be deserialized. + JSON messages over this depth will fail to be deserialized. Default value + is 100. + + Returns: + A new message passed from json_dict. + """ + new_message = message_class() + json_format.ParseDict( + js_dict=js_dict, + message=new_message, + ignore_unknown_fields=ignore_unknown_fields, + descriptor_pool=descriptor_pool, + max_recursion_depth=max_recursion_depth, + ) + return new_message diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py new file mode 100644 index 00000000000..96a61f7bcd8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py @@ -0,0 +1,118 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2025 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains the Nextgen Pythonic Protobuf Text Format APIs.""" + +from typing import AnyStr, Callable, Optional, Text, Type, Union + +from opentelemetry.agent._vendor.google.protobuf import text_format +from opentelemetry.agent._vendor.google.protobuf.descriptor_pool import DescriptorPool +from opentelemetry.agent._vendor.google.protobuf.message import Message + +_MsgFormatter = Callable[[Message, Union[int, bool], bool], Optional[Text]] + + +def serialize( + message: Message, + as_utf8: bool = True, + as_one_line: bool = False, + use_short_repeated_primitives: bool = False, + pointy_brackets: bool = False, + use_index_order: bool = False, + use_field_number: bool = False, + descriptor_pool: Optional[DescriptorPool] = None, + indent: int = 0, + message_formatter: Optional[_MsgFormatter] = None, + print_unknown_fields: bool = False, + force_colon: bool = False, +) -> str: + """Convert protobuf message to text format. + + Double values can be formatted compactly with 15 digits of + precision (which is the most that IEEE 754 "double" can guarantee) + using double_format='.15g'. To ensure that converting to text and back to a + proto will result in an identical value, double_format='.17g' should be used. + + Args: + message: The protocol buffers message. + as_utf8: Return unescaped Unicode for non-ASCII characters. + as_one_line: Don't introduce newlines between fields. + use_short_repeated_primitives: Use short repeated format for primitives. + pointy_brackets: If True, use angle brackets instead of curly braces for + nesting. + use_index_order: If True, fields of a proto message will be printed using + the order defined in source code instead of the field number, extensions + will be printed at the end of the message and their relative order is + determined by the extension number. By default, use the field number + order. + use_field_number: If True, print field numbers instead of names. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. + indent (int): The initial indent level, in terms of spaces, for pretty + print. + message_formatter (function(message, indent, as_one_line) -> unicode|None): + Custom formatter for selected sub-messages (usually based on message + type). Use to pretty print parts of the protobuf for easier diffing. + print_unknown_fields: If True, unknown fields will be printed. + force_colon: If set, a colon will be added after the field name even if the + field is a proto message. + + Returns: + str: A string of the text formatted protocol buffer message. + """ + return text_format.MessageToString( + message=message, + as_utf8=as_utf8, + as_one_line=as_one_line, + use_short_repeated_primitives=use_short_repeated_primitives, + pointy_brackets=pointy_brackets, + use_index_order=use_index_order, + use_field_number=use_field_number, + descriptor_pool=descriptor_pool, + indent=indent, + message_formatter=message_formatter, + print_unknown_fields=print_unknown_fields, + force_colon=force_colon, + ) + + +def parse( + message_class: Type[Message], + text: AnyStr, + allow_unknown_extension: bool = False, + allow_field_number: bool = False, + descriptor_pool: Optional[DescriptorPool] = None, + allow_unknown_field: bool = False, +) -> Message: + """Parses a text representation of a protocol message into a message. + + Args: + message_class: The message meta class. + text (str): Message text representation. + message (Message): A protocol buffer message to merge into. + allow_unknown_extension: if True, skip over missing extensions and keep + parsing + allow_field_number: if True, both field number and field name are allowed. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. + allow_unknown_field: if True, skip over unknown field and keep parsing. + Avoid to use this option if possible. It may hide some errors (e.g. + spelling error on field name) + + Returns: + Message: A new message passed from text. + + Raises: + ParseError: On text parsing problems. + """ + new_message = message_class() + text_format.Parse( + text=text, + message=new_message, + allow_unknown_extension=allow_unknown_extension, + allow_field_number=allow_field_number, + descriptor_pool=descriptor_pool, + allow_unknown_field=allow_unknown_field, + ) + return new_message diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py new file mode 100644 index 00000000000..03bf7da68a0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py @@ -0,0 +1,46 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Protocol message implementation hooks for C++ implementation. + +Contains helper functions used to create protocol message classes from +Descriptor objects at runtime backed by the protocol buffer C++ API. +""" + +__author__ = 'tibell@google.com (Johan Tibell)' + +from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation + +# pylint: disable=protected-access +_message = api_implementation._c_module +# TODO: Remove this import after fix api_implementation +if _message is None: + from opentelemetry.agent._vendor.google.protobuf.pyext import _message + + +class GeneratedProtocolMessageType(_message.MessageMeta): + """Metaclass for protocol message classes created at runtime from Descriptors. + + The protocol compiler currently uses this metaclass to create protocol + message classes at runtime. Clients can also manually create their own + classes at runtime, as in this example: + + mydescriptor = Descriptor(.....) + factory = symbol_database.Default() + factory.pool.AddDescriptor(mydescriptor) + MyProtoClass = message_factory.GetMessageClass(mydescriptor) + myproto_instance = MyProtoClass() + myproto.foo_field = 23 + ... + + The above example will not work for nested types. If you wish to include them, + use reflection.MakeClass() instead of manually instantiating the class in + order to create the appropriate class structure. + """ + + # Must be consistent with the protocol-compiler code in + # proto2/compiler/internal/generator.*. + _DESCRIPTOR_KEY = 'DESCRIPTOR' diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py new file mode 100644 index 00000000000..cf8014a141a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py @@ -0,0 +1,36 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +# This code is meant to work on Python 2.4 and above only. +"""Contains a metaclass and helper functions used to create + +protocol message classes from Descriptor objects at runtime. + +Recall that a metaclass is the "type" of a class. +(A class is to a metaclass what an instance is to a class.) + +In this case, we use the GeneratedProtocolMessageType metaclass +to inject all the useful functionality into the classes +output by the protocol compiler at compile-time. + +The upshot of all this is that the real implementation +details for ALL pure-Python protocol buffers are *here in +this file*. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +import warnings + +from opentelemetry.agent._vendor.google.protobuf import message_factory +from opentelemetry.agent._vendor.google.protobuf import symbol_database + +# The type of all Message classes. +# Part of the public interface, but normally only used by message factories. +GeneratedProtocolMessageType = message_factory._GENERATED_PROTOCOL_MESSAGE_TYPE + +MESSAGE_CLASS_CACHE = {} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py new file mode 100644 index 00000000000..857f373c38e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py @@ -0,0 +1,105 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Protobuf Runtime versions and validators. + +It should only be accessed by Protobuf gencodes and tests. DO NOT USE it +elsewhere. +""" + +__author__ = 'shaod@google.com (Dennis Shao)' + +from enum import Enum + +import os +import warnings + + +class Domain(Enum): + GOOGLE_INTERNAL = 1 + PUBLIC = 2 + + +# The versions of this Python Protobuf runtime to be changed automatically by +# the Protobuf release process. Do not edit them manually. +# These OSS versions are not stripped to avoid merging conflicts. +OSS_DOMAIN = Domain.PUBLIC +OSS_MAJOR = 7 +OSS_MINOR = 36 +OSS_PATCH = 2 +OSS_SUFFIX = '' + +DOMAIN = OSS_DOMAIN +MAJOR = OSS_MAJOR +MINOR = OSS_MINOR +PATCH = OSS_PATCH +SUFFIX = OSS_SUFFIX + +# Avoid flooding of warnings. +_MAX_WARNING_COUNT = 20 +_warning_count = 0 + + +class VersionError(Exception): + """Exception class for version violation.""" + + +def _ReportVersionError(msg): + raise VersionError(msg) + + +def ValidateProtobufRuntimeVersion( + gen_domain, gen_major, gen_minor, gen_patch, gen_suffix, location +): + """Function to validate versions. + + Args: + gen_domain: The domain where the code was generated from. + gen_major: The major version number of the gencode. + gen_minor: The minor version number of the gencode. + gen_patch: The patch version number of the gencode. + gen_suffix: The version suffix e.g. '-dev', '-rc1' of the gencode. + location: The proto location that causes the version violation. + + Raises: + VersionError: if gencode version is invalid or incompatible with the + runtime. + """ + + disable_flag = os.getenv('TEMPORARILY_DISABLE_PROTOBUF_VERSION_CHECK') + if disable_flag is not None and disable_flag.lower() == 'true': + return + + global _warning_count + + version = f'{MAJOR}.{MINOR}.{PATCH}{SUFFIX}' + gen_version = f'{gen_major}.{gen_minor}.{gen_patch}{gen_suffix}' + + if gen_major < 0 or gen_minor < 0 or gen_patch < 0: + raise VersionError(f'Invalid gencode version: {gen_version}') + + error_prompt = ( + 'See Protobuf version guarantees at' + ' https://protobuf.dev/support/cross-version-runtime-guarantee.' + ) + + if gen_domain != DOMAIN: + _ReportVersionError( + 'Detected mismatched Protobuf Gencode/Runtime domains when loading' + f' {location}: gencode {gen_domain.name} runtime {DOMAIN.name}.' + ' Cross-domain usage of Protobuf is not supported.' + ) + + if ( + MAJOR < gen_major + or (MAJOR == gen_major and MINOR < gen_minor) + or (MAJOR == gen_major and MINOR == gen_minor and PATCH < gen_patch) + ): + _ReportVersionError( + 'Detected incompatible Protobuf Gencode/Runtime versions when loading' + f' {location}: gencode {gen_version} runtime {version}. Runtime version' + f' cannot be older than the linked gencode version. {error_prompt}' + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py new file mode 100644 index 00000000000..8760be50ce9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py @@ -0,0 +1,284 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +"""Contains metaclasses used to create protocol service and service stub + +classes from ServiceDescriptor objects at runtime. + +The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to +inject all useful functionality into the classes output by the protocol +compiler at compile-time. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + + +class GeneratedServiceType(type): + """Metaclass for service classes created at runtime from ServiceDescriptors. + + Implementations for all methods described in the Service class are added here + by this class. We also create properties to allow getting/setting all fields + in the protocol message. + + The protocol compiler currently uses this metaclass to create protocol service + classes at runtime. Clients can also manually create their own classes at + runtime, as in this example:: + + mydescriptor = ServiceDescriptor(.....) + class MyProtoService(service.Service): + __metaclass__ = GeneratedServiceType + DESCRIPTOR = mydescriptor + myservice_instance = MyProtoService() + # ... + """ + + _DESCRIPTOR_KEY = 'DESCRIPTOR' + + def __init__(cls, name, bases, dictionary): + """Creates a message service class. + + Args: + name: Name of the class (ignored, but required by the metaclass protocol). + bases: Base classes of the class being constructed. + dictionary: The class dictionary of the class being constructed. + dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object + describing this protocol service type. + """ + # Don't do anything if this class doesn't have a descriptor. This happens + # when a service class is subclassed. + if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary: + return + + descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY] + service_builder = _ServiceBuilder(descriptor) + service_builder.BuildService(cls) + cls.DESCRIPTOR = descriptor + + +class GeneratedServiceStubType(GeneratedServiceType): + """Metaclass for service stubs created at runtime from ServiceDescriptors. + + This class has similar responsibilities as GeneratedServiceType, except that + it creates the service stub classes. + """ + + _DESCRIPTOR_KEY = 'DESCRIPTOR' + + def __init__(cls, name, bases, dictionary): + """Creates a message service stub class. + + Args: + name: Name of the class (ignored, here). + bases: Base classes of the class being constructed. + dictionary: The class dictionary of the class being constructed. + dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object + describing this protocol service type. + """ + super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary) + # Don't do anything if this class doesn't have a descriptor. This happens + # when a service stub is subclassed. + if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary: + return + + descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] + service_stub_builder = _ServiceStubBuilder(descriptor) + service_stub_builder.BuildServiceStub(cls) + + +class _ServiceBuilder(object): + """This class constructs a protocol service class using a service descriptor. + + Given a service descriptor, this class constructs a class that represents + the specified service descriptor. One service builder instance constructs + exactly one service class. That means all instances of that class share the + same builder. + """ + + def __init__(self, service_descriptor): + """Initializes an instance of the service class builder. + + Args: + service_descriptor: ServiceDescriptor to use when constructing the service + class. + """ + self.descriptor = service_descriptor + + def BuildService(builder, cls): + """Constructs the service class. + + Args: + cls: The class that will be constructed. + """ + + # CallMethod needs to operate with an instance of the Service class. This + # internal wrapper function exists only to be able to pass the service + # instance to the method that does the real CallMethod work. + # Making sure to use exact argument names from the abstract interface in + # service.py to match the type signature + def _WrapCallMethod(self, method_descriptor, rpc_controller, request, done): + return builder._CallMethod( + self, method_descriptor, rpc_controller, request, done + ) + + def _WrapGetRequestClass(self, method_descriptor): + return builder._GetRequestClass(method_descriptor) + + def _WrapGetResponseClass(self, method_descriptor): + return builder._GetResponseClass(method_descriptor) + + builder.cls = cls + cls.CallMethod = _WrapCallMethod + cls.GetDescriptor = staticmethod(lambda: builder.descriptor) + cls.GetDescriptor.__doc__ = 'Returns the service descriptor.' + cls.GetRequestClass = _WrapGetRequestClass + cls.GetResponseClass = _WrapGetResponseClass + for method in builder.descriptor.methods: + setattr(cls, method.name, builder._GenerateNonImplementedMethod(method)) + + def _CallMethod( + self, srvc, method_descriptor, rpc_controller, request, callback + ): + """Calls the method described by a given method descriptor. + + Args: + srvc: Instance of the service for which this method is called. + method_descriptor: Descriptor that represent the method to call. + rpc_controller: RPC controller to use for this method's execution. + request: Request protocol message. + callback: A callback to invoke after the method has completed. + """ + if method_descriptor.containing_service != self.descriptor: + raise RuntimeError( + 'CallMethod() given method descriptor for wrong service type.' + ) + method = getattr(srvc, method_descriptor.name) + return method(rpc_controller, request, callback) + + def _GetRequestClass(self, method_descriptor): + """Returns the class of the request protocol message. + + Args: + method_descriptor: Descriptor of the method for which to return the + request protocol message class. + + Returns: + A class that represents the input protocol message of the specified + method. + """ + if method_descriptor.containing_service != self.descriptor: + raise RuntimeError( + 'GetRequestClass() given method descriptor for wrong service type.' + ) + return method_descriptor.input_type._concrete_class + + def _GetResponseClass(self, method_descriptor): + """Returns the class of the response protocol message. + + Args: + method_descriptor: Descriptor of the method for which to return the + response protocol message class. + + Returns: + A class that represents the output protocol message of the specified + method. + """ + if method_descriptor.containing_service != self.descriptor: + raise RuntimeError( + 'GetResponseClass() given method descriptor for wrong service type.' + ) + return method_descriptor.output_type._concrete_class + + def _GenerateNonImplementedMethod(self, method): + """Generates and returns a method that can be set for a service methods. + + Args: + method: Descriptor of the service method for which a method is to be + generated. + + Returns: + A method that can be added to the service class. + """ + return lambda inst, rpc_controller, request, callback: ( + self._NonImplementedMethod(method.name, rpc_controller, callback) + ) + + def _NonImplementedMethod(self, method_name, rpc_controller, callback): + """The body of all methods in the generated service class. + + Args: + method_name: Name of the method being executed. + rpc_controller: RPC controller used to execute this method. + callback: A callback which will be invoked when the method finishes. + """ + rpc_controller.SetFailed('Method %s not implemented.' % method_name) + callback(None) + + +class _ServiceStubBuilder(object): + """Constructs a protocol service stub class using a service descriptor. + + Given a service descriptor, this class constructs a suitable stub class. + A stub is just a type-safe wrapper around an RpcChannel which emulates a + local implementation of the service. + + One service stub builder instance constructs exactly one class. It means all + instances of that class share the same service stub builder. + """ + + def __init__(self, service_descriptor): + """Initializes an instance of the service stub class builder. + + Args: + service_descriptor: ServiceDescriptor to use when constructing the stub + class. + """ + self.descriptor = service_descriptor + + def BuildServiceStub(self, cls): + """Constructs the stub class. + + Args: + cls: The class that will be constructed. + """ + + def _ServiceStubInit(stub, rpc_channel): + stub.rpc_channel = rpc_channel + + self.cls = cls + cls.__init__ = _ServiceStubInit + for method in self.descriptor.methods: + setattr(cls, method.name, self._GenerateStubMethod(method)) + + def _GenerateStubMethod(self, method): + return ( + lambda inst, rpc_controller, request, callback=None: self._StubMethod( + inst, method, rpc_controller, request, callback + ) + ) + + def _StubMethod( + self, stub, method_descriptor, rpc_controller, request, callback + ): + """The body of all service methods in the generated stub class. + + Args: + stub: Stub instance. + method_descriptor: Descriptor of the invoked method. + rpc_controller: Rpc controller to execute the method. + request: Request protocol message. + callback: A callback to execute when the method finishes. + + Returns: + Response message (in case of blocking call). + """ + return stub.rpc_channel.CallMethod( + method_descriptor, + rpc_controller, + request, + method_descriptor.output_type._concrete_class, + callback, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py new file mode 100644 index 00000000000..53baf277947 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/source_context.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/source_context.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$google/protobuf/source_context.proto\x12\x0fgoogle.protobuf\",\n\rSourceContext\x12\x1b\n\tfile_name\x18\x01 \x01(\tR\x08\x66ileNameB\x8a\x01\n\x13\x63om.google.protobufB\x12SourceContextProtoP\x01Z6google.golang.org/protobuf/types/known/sourcecontextpb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.source_context_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\022SourceContextProtoP\001Z6google.golang.org/protobuf/types/known/sourcecontextpb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_SOURCECONTEXT']._serialized_start=57 + _globals['_SOURCECONTEXT']._serialized_end=101 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py new file mode 100644 index 00000000000..33ce4e37a47 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/struct.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/struct.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cgoogle/protobuf/struct.proto\x12\x0fgoogle.protobuf\"\x98\x01\n\x06Struct\x12;\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.protobuf.Struct.FieldsEntryR\x06\x66ields\x1aQ\n\x0b\x46ieldsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.ValueR\x05value:\x02\x38\x01\"\xb2\x02\n\x05Value\x12;\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12#\n\x0cnumber_value\x18\x02 \x01(\x01H\x00R\x0bnumberValue\x12#\n\x0cstring_value\x18\x03 \x01(\tH\x00R\x0bstringValue\x12\x1f\n\nbool_value\x18\x04 \x01(\x08H\x00R\tboolValue\x12<\n\x0cstruct_value\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x00R\x0bstructValue\x12;\n\nlist_value\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.ListValueH\x00R\tlistValueB\x06\n\x04kind\";\n\tListValue\x12.\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.ValueR\x06values*\x1b\n\tNullValue\x12\x0e\n\nNULL_VALUE\x10\x00\x42\x7f\n\x13\x63om.google.protobufB\x0bStructProtoP\x01Z/google.golang.org/protobuf/types/known/structpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.struct_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\013StructProtoP\001Z/google.golang.org/protobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_STRUCT_FIELDSENTRY']._loaded_options = None + _globals['_STRUCT_FIELDSENTRY']._serialized_options = b'8\001' + _globals['_NULLVALUE']._serialized_start=574 + _globals['_NULLVALUE']._serialized_end=601 + _globals['_STRUCT']._serialized_start=50 + _globals['_STRUCT']._serialized_end=202 + _globals['_STRUCT_FIELDSENTRY']._serialized_start=121 + _globals['_STRUCT_FIELDSENTRY']._serialized_end=202 + _globals['_VALUE']._serialized_start=205 + _globals['_VALUE']._serialized_end=511 + _globals['_LISTVALUE']._serialized_start=513 + _globals['_LISTVALUE']._serialized_end=572 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py new file mode 100644 index 00000000000..3055ddc27d4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py @@ -0,0 +1,178 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""A database of Python protocol buffer generated symbols. + +SymbolDatabase is the MessageFactory for messages generated at compile time, +and makes it easy to create new instances of a registered type, given only the +type's protocol buffer symbol name. + +Example usage:: + + db = symbol_database.SymbolDatabase() + + # Register symbols of interest, from one or multiple files. + db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR) + db.RegisterMessage(my_proto_pb2.MyMessage) + db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR) + + # The database can be used as a MessageFactory, to generate types based on + # their name: + types = db.GetMessages(['my_proto.proto']) + my_message_instance = types['MyMessage']() + + # The database's underlying descriptor pool can be queried, so it's not + # necessary to know a type's filename to be able to generate it: + filename = db.pool.FindFileContainingSymbol('MyMessage') + my_message_instance = db.GetMessages([filename])['MyMessage']() + + # This functionality is also provided directly via a convenience method: + my_message_instance = db.GetSymbol('MyMessage')() +""" + +import warnings + +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import message_factory +from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation + + +class SymbolDatabase: + """A database of Python generated symbols.""" + + # local cache of registered classes. + _classes = {} + + def __init__(self, pool=None): + """Initializes a new SymbolDatabase.""" + self.pool = pool or descriptor_pool.DescriptorPool() + + def RegisterMessage(self, message): + """Registers the given message type in the local database. + + Calls to GetSymbol() and GetMessages() will return messages registered here. + + Args: + message: A :class:`google.protobuf.message.Message` subclass (or + instance); its descriptor will be registered. + + Returns: + The provided message. + """ + + desc = message.DESCRIPTOR + self._classes[desc] = message + self.RegisterMessageDescriptor(desc) + return message + + def RegisterMessageDescriptor(self, message_descriptor): + """Registers the given message descriptor in the local database. + + Args: + message_descriptor (Descriptor): the message descriptor to add. + """ + if api_implementation.Type() == 'python': + # pylint: disable=protected-access + self.pool._AddDescriptor(message_descriptor) + + def RegisterEnumDescriptor(self, enum_descriptor): + """Registers the given enum descriptor in the local database. + + Args: + enum_descriptor (EnumDescriptor): The enum descriptor to register. + + Returns: + EnumDescriptor: The provided descriptor. + """ + if api_implementation.Type() == 'python': + # pylint: disable=protected-access + self.pool._AddEnumDescriptor(enum_descriptor) + return enum_descriptor + + def RegisterServiceDescriptor(self, service_descriptor): + """Registers the given service descriptor in the local database. + + Args: + service_descriptor (ServiceDescriptor): the service descriptor to + register. + """ + if api_implementation.Type() == 'python': + # pylint: disable=protected-access + self.pool._AddServiceDescriptor(service_descriptor) + + def RegisterFileDescriptor(self, file_descriptor): + """Registers the given file descriptor in the local database. + + Args: + file_descriptor (FileDescriptor): The file descriptor to register. + """ + if api_implementation.Type() == 'python': + # pylint: disable=protected-access + self.pool._InternalAddFileDescriptor(file_descriptor) + + def GetSymbol(self, symbol): + """Tries to find a symbol in the local database. + + Currently, this method only returns message.Message instances, however, if + may be extended in future to support other symbol types. + + Args: + symbol (str): a protocol buffer symbol. + + Returns: + A Python class corresponding to the symbol. + + Raises: + KeyError: if the symbol could not be found. + """ + + return self._classes[self.pool.FindMessageTypeByName(symbol)] + + def GetMessages(self, files): + # TODO: Fix the differences with MessageFactory. + """Gets all registered messages from a specified file. + + Only messages already created and registered will be returned; (this is the + case for imported _pb2 modules) + But unlike MessageFactory, this version also returns already defined nested + messages, but does not register any message extensions. + + Args: + files (list[str]): The file names to extract messages from. + + Returns: + A dictionary mapping proto names to the message classes. + + Raises: + KeyError: if a file could not be found. + """ + + def _GetAllMessages(desc): + """Walk a message Descriptor and recursively yields all message names.""" + yield desc + for msg_desc in desc.nested_types: + for nested_desc in _GetAllMessages(msg_desc): + yield nested_desc + + result = {} + for file_name in files: + file_desc = self.pool.FindFileByName(file_name) + for msg_desc in file_desc.message_types_by_name.values(): + for desc in _GetAllMessages(msg_desc): + try: + result[desc.full_name] = self._classes[desc] + except KeyError: + # This descriptor has no registered class, skip it. + pass + return result + + +_DEFAULT = SymbolDatabase(pool=descriptor_pool.Default()) + + +def Default(): + """Returns the default SymbolDatabase.""" + return _DEFAULT diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py new file mode 100644 index 00000000000..294a4624200 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py @@ -0,0 +1,111 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Encoding related utilities.""" + +import re + + +def _AsciiIsPrint(i): + return i >= 32 and i < 127 + + +def _MakeStrEscapes(): + ret = {} + for i in range(0, 128): + if not _AsciiIsPrint(i): + ret[i] = r'\%03o' % i + ret[ord('\t')] = r'\t' # optional escape + ret[ord('\n')] = r'\n' # optional escape + ret[ord('\r')] = r'\r' # optional escape + ret[ord('"')] = r'\"' # necessary escape + ret[ord("'")] = r'\'' # optional escape + ret[ord('\\')] = r'\\' # necessary escape + return ret + + +# Maps int -> char, performing string escapes. +_str_escapes = _MakeStrEscapes() + +# Maps int -> char, performing byte escaping and string escapes +_byte_escapes = {i: chr(i) for i in range(0, 256)} +_byte_escapes.update(_str_escapes) +_byte_escapes.update({i: r'\%03o' % i for i in range(128, 256)}) + + +def _DecodeUtf8EscapeErrors(text_bytes): + ret = '' + while text_bytes: + try: + ret += text_bytes.decode('utf-8').translate(_str_escapes) + text_bytes = '' + except UnicodeDecodeError as e: + ret += text_bytes[: e.start].decode('utf-8').translate(_str_escapes) + ret += _byte_escapes[text_bytes[e.start]] + text_bytes = text_bytes[e.start + 1 :] + return ret + + +def CEscape(text, as_utf8) -> str: + """Escape a bytes string for use in an text protocol buffer. + + Args: + text: A byte string to be escaped. + as_utf8: Specifies if result may contain non-ASCII characters. In Python 3 + this allows unescaped non-ASCII Unicode characters. In Python 2 the return + value will be valid UTF-8 rather than only ASCII. + + Returns: + Escaped string (str). + """ + # Python's text.encode() 'string_escape' or 'unicode_escape' codecs do not + # satisfy our needs; they encodes unprintable characters using two-digit hex + # escapes whereas our C++ unescaping function allows hex escapes to be any + # length. So, "\0011".encode('string_escape') ends up being "\\x011", which + # will be decoded in C++ as a single-character string with char code 0x11. + text_is_unicode = isinstance(text, str) + if as_utf8: + if text_is_unicode: + return text.translate(_str_escapes) + else: + return _DecodeUtf8EscapeErrors(text) + else: + if text_is_unicode: + text = text.encode('utf-8') + return ''.join([_byte_escapes[c] for c in text]) + + +_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])') + + +def CUnescape(text: str) -> bytes: + """Unescape a text string with C-style escape sequences to UTF-8 bytes. + + Args: + text: The data to parse in a str. + + Returns: + A byte string. + """ + + def ReplaceHex(m): + # Only replace the match if the number of leading back slashes is odd. i.e. + # the slash itself is not escaped. + if len(m.group(1)) & 1: + return m.group(1) + 'x0' + m.group(2) + return m.group(0) + + # This is required because the 'string_escape' encoding doesn't + # allow single-digit hex escapes (like '\xf'). + result = _CUNESCAPE_HEX.sub(ReplaceHex, text) + + # Replaces Unicode escape sequences with their character equivalents. + result = result.encode('raw_unicode_escape').decode('raw_unicode_escape') + # Encode Unicode characters as UTF-8, then decode to Latin-1 escaping + # unprintable characters. + result = result.encode('utf-8').decode('unicode_escape') + # Convert Latin-1 text back to a byte string (latin-1 codec also works here). + return result.encode('latin-1') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py new file mode 100644 index 00000000000..947d72e6ff0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py @@ -0,0 +1,2089 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains routines for printing messages in Protobuf Text Format. + +Printing and parsing messages in Text Format is useful for debugging +and human editing of messages. + +Unlike the Binary and ProtoJSON formats, Text Format is not designed to be +used as a wire format; instead it is intended for human-in-the-loop +configuration use-cases. + +Systems processing untrusted inputs should strongly prefer to use Binary format +instead. If a textual format of untrusted inputs is required, consider using +ProtoJSON format instead. + +Simple usage example:: + + # Create a proto object and serialize it to a text proto string. + message = my_proto_pb2.MyMessage(foo='bar') + text_proto = text_format.MessageToString(message) + + # Parse a text proto string. + message = text_format.Parse(text_proto, my_proto_pb2.MyMessage()) +""" + +__author__ = 'kenton@google.com (Kenton Varda)' + +# TODO Import thread contention leads to test failures. +import encodings.raw_unicode_escape # pylint: disable=unused-import +import encodings.unicode_escape # pylint: disable=unused-import +import io +import math +import re +import warnings + +from opentelemetry.agent._vendor.google.protobuf.internal import decoder +from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers +from opentelemetry.agent._vendor.google.protobuf import descriptor + +from opentelemetry.agent._vendor.google.protobuf import text_encoding +from opentelemetry.agent._vendor.google.protobuf import unknown_fields + +# pylint: disable=g-import-not-at-top +__all__ = [ + 'MessageToString', + 'Parse', + 'PrintMessage', + 'PrintField', + 'PrintFieldValue', + 'Merge', + 'MessageToBytes', +] + +_INTEGER_CHECKERS = ( + type_checkers.Uint32ValueChecker(), + type_checkers.Int32ValueChecker(), + type_checkers.Uint64ValueChecker(), + type_checkers.Int64ValueChecker(), +) +_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?$', re.IGNORECASE) +_FLOAT_NAN = re.compile('nanf?$', re.IGNORECASE) +_FLOAT_OCTAL_PREFIX = re.compile('-?0[0-9]+') +_PERCENT_ENCODING = re.compile(r'^%[\da-fA-F][\da-fA-F]$') +_TYPE_NAME = re.compile(r'^[^\d\W]\w*(\.[^\d\W]\w*)*$') +_QUOTES = frozenset(("'", '"')) +_ANY_FULL_TYPE_NAME = 'google.protobuf.Any' +_DEBUG_STRING_SILENT_MARKER = '\t ' + +_as_utf8_default = True + + +class Error(Exception): + """Top-level module error for text_format.""" + + +class ParseError(Error): + """Thrown in case of text parsing or tokenizing error.""" + + def __init__(self, message=None, line=None, column=None): + if message is not None and line is not None: + loc = str(line) + if column is not None: + loc += ':{0}'.format(column) + message = '{0} : {1}'.format(loc, message) + if message is not None: + super(ParseError, self).__init__(message) + else: + super(ParseError, self).__init__() + self._line = line + self._column = column + + def GetLine(self): + return self._line + + def GetColumn(self): + return self._column + + +class TextWriter(object): + + def __init__(self, as_utf8): + self._writer = io.StringIO() + + def write(self, val): + return self._writer.write(val) + + def close(self): + return self._writer.close() + + def getvalue(self): + return self._writer.getvalue() + + +def MessageToString( + message, + as_utf8=_as_utf8_default, + as_one_line=False, + use_short_repeated_primitives=False, + pointy_brackets=False, + use_index_order=False, + use_field_number=False, + descriptor_pool=None, + indent=0, + message_formatter=None, + print_unknown_fields=False, + force_colon=False, +) -> str: + """Convert protobuf message to text format. + + Args: + message: The protocol buffers message. + as_utf8: Return unescaped Unicode for non-ASCII characters. + as_one_line: Don't introduce newlines between fields. + use_short_repeated_primitives: Use short repeated format for primitives. + pointy_brackets: If True, use angle brackets instead of curly braces for + nesting. + use_index_order: If True, fields of a proto message will be printed using + the order defined in source code instead of the field number, extensions + will be printed at the end of the message and their relative order is + determined by the extension number. By default, use the field number + order. + use_field_number: If True, print field numbers instead of names. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. + indent (int): The initial indent level, in terms of spaces, for pretty + print. + message_formatter (function(message, indent, as_one_line) -> unicode|None): + Custom formatter for selected sub-messages (usually based on message + type). Use to pretty print parts of the protobuf for easier diffing. + print_unknown_fields: If True, unknown fields will be printed. + force_colon: If set, a colon will be added after the field name even if the + field is a proto message. + + Returns: + str: A string of the text formatted protocol buffer message. + """ + out = TextWriter(as_utf8) + printer = _Printer( + out=out, + indent=indent, + as_utf8=as_utf8, + as_one_line=as_one_line, + use_short_repeated_primitives=use_short_repeated_primitives, + pointy_brackets=pointy_brackets, + use_index_order=use_index_order, + use_field_number=use_field_number, + descriptor_pool=descriptor_pool, + message_formatter=message_formatter, + print_unknown_fields=print_unknown_fields, + force_colon=force_colon, + ) + printer.PrintMessage(message) + result = out.getvalue() + out.close() + if as_one_line: + return result.rstrip() + return result + + +def MessageToBytes(message, **kwargs) -> bytes: + """Convert protobuf message to encoded text format. See MessageToString.""" + text = MessageToString(message, **kwargs) + if isinstance(text, bytes): + return text + codec = 'utf-8' if kwargs.get('as_utf8') else 'ascii' + return text.encode(codec) + + +def _IsMapEntry(field): + return ( + field.type == descriptor.FieldDescriptor.TYPE_MESSAGE + and field.message_type.has_options + and field.message_type.GetOptions().map_entry + ) + + +def _IsGroupLike(field): + """Determines if a field is consistent with a proto2 group. + + Args: + field: The field descriptor. + + Returns: + True if this field is group-like, false otherwise. + """ + # Groups are always tag-delimited. + if field.type != descriptor.FieldDescriptor.TYPE_GROUP: + return False + + # Group fields always are always the lowercase type name. + if field.name != field.message_type.name.lower(): + return False + + if field.message_type.file != field.file: + return False + + # Group messages are always defined in the same scope as the field. File + # level extensions will compare NULL == NULL here, which is why the file + # comparison above is necessary to ensure both come from the same file. + return ( + field.message_type.containing_type == field.extension_scope + if field.is_extension + else field.message_type.containing_type == field.containing_type + ) + + +def PrintMessage( + message, + out, + indent=0, + as_utf8=_as_utf8_default, + as_one_line=False, + use_short_repeated_primitives=False, + pointy_brackets=False, + use_index_order=False, + use_field_number=False, + descriptor_pool=None, + message_formatter=None, + print_unknown_fields=False, + force_colon=False, +): + """Convert the message to text format and write it to the out stream. + + Args: + message: The Message object to convert to text format. + out: A file handle to write the message to. + indent: The initial indent level for pretty print. + as_utf8: Return unescaped Unicode for non-ASCII characters. + as_one_line: Don't introduce newlines between fields. + use_short_repeated_primitives: Use short repeated format for primitives. + pointy_brackets: If True, use angle brackets instead of curly braces for + nesting. + use_index_order: If True, print fields of a proto message using the order + defined in source code instead of the field number. By default, use the + field number order. + use_field_number: If True, print field numbers instead of names. + descriptor_pool: A DescriptorPool used to resolve Any types. + message_formatter: A function(message, indent, as_one_line): unicode|None to + custom format selected sub-messages (usually based on message type). Use + to pretty print parts of the protobuf for easier diffing. + print_unknown_fields: If True, unknown fields will be printed. + force_colon: If set, a colon will be added after the field name even if the + field is a proto message. + """ + printer = _Printer( + out=out, + indent=indent, + as_utf8=as_utf8, + as_one_line=as_one_line, + use_short_repeated_primitives=use_short_repeated_primitives, + pointy_brackets=pointy_brackets, + use_index_order=use_index_order, + use_field_number=use_field_number, + descriptor_pool=descriptor_pool, + message_formatter=message_formatter, + print_unknown_fields=print_unknown_fields, + force_colon=force_colon, + ) + printer.PrintMessage(message) + + +def PrintField( + field, + value, + out, + indent=0, + as_utf8=_as_utf8_default, + as_one_line=False, + use_short_repeated_primitives=False, + pointy_brackets=False, + use_index_order=False, + message_formatter=None, + print_unknown_fields=False, + force_colon=False, +): + """Print a single field name/value pair.""" + printer = _Printer( + out, + indent, + as_utf8, + as_one_line, + use_short_repeated_primitives, + pointy_brackets, + use_index_order, + message_formatter=message_formatter, + print_unknown_fields=print_unknown_fields, + force_colon=force_colon, + ) + printer.PrintField(field, value) + + +def PrintFieldValue( + field, + value, + out, + indent=0, + as_utf8=_as_utf8_default, + as_one_line=False, + use_short_repeated_primitives=False, + pointy_brackets=False, + use_index_order=False, + message_formatter=None, + print_unknown_fields=False, + force_colon=False, +): + """Print a single field value (not including name).""" + printer = _Printer( + out, + indent, + as_utf8, + as_one_line, + use_short_repeated_primitives, + pointy_brackets, + use_index_order, + message_formatter=message_formatter, + print_unknown_fields=print_unknown_fields, + force_colon=force_colon, + ) + printer.PrintFieldValue(field, value) + + +def _BuildMessageFromTypeName(type_name, descriptor_pool): + """Returns a protobuf message instance. + + Args: + type_name: Fully-qualified protobuf message type name string. + descriptor_pool: DescriptorPool instance. + + Returns: + A Message instance of type matching type_name, or None if the a Descriptor + wasn't found matching type_name. + """ + # pylint: disable=g-import-not-at-top + if descriptor_pool is None: + from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as pool_mod + + descriptor_pool = pool_mod.Default() + from opentelemetry.agent._vendor.google.protobuf import message_factory + + try: + message_descriptor = descriptor_pool.FindMessageTypeByName(type_name) + except KeyError: + return None + message_type = message_factory.GetMessageClass(message_descriptor) + return message_type() + + +# These values must match WireType enum in //google/protobuf/wire_format.h. +WIRETYPE_LENGTH_DELIMITED = 2 +WIRETYPE_START_GROUP = 3 + + +class _Printer(object): + """Text format printer for protocol message.""" + + def __init__( + self, + out, + indent=0, + as_utf8=_as_utf8_default, + as_one_line=False, + use_short_repeated_primitives=False, + pointy_brackets=False, + use_index_order=False, + use_field_number=False, + descriptor_pool=None, + message_formatter=None, + print_unknown_fields=False, + force_colon=False, + ): + """Initialize the Printer. + + Args: + out: To record the text format result. + indent: The initial indent level for pretty print. + as_utf8: Return unescaped Unicode for non-ASCII characters. + as_one_line: Don't introduce newlines between fields. + use_short_repeated_primitives: Use short repeated format for primitives. + pointy_brackets: If True, use angle brackets instead of curly braces for + nesting. + use_index_order: If True, print fields of a proto message using the order + defined in source code instead of the field number. By default, use the + field number order. + use_field_number: If True, print field numbers instead of names. + descriptor_pool: A DescriptorPool used to resolve Any types. + message_formatter: A function(message, indent, as_one_line): unicode|None + to custom format selected sub-messages (usually based on message type). + Use to pretty print parts of the protobuf for easier diffing. + print_unknown_fields: If True, unknown fields will be printed. + force_colon: If set, a colon will be added after the field name even if + the field is a proto message. + """ + self.out = out + self.indent = indent + self.as_utf8 = as_utf8 + self.as_one_line = as_one_line + self.use_short_repeated_primitives = use_short_repeated_primitives + self.pointy_brackets = pointy_brackets + self.use_index_order = use_index_order + self.use_field_number = use_field_number + self.descriptor_pool = descriptor_pool + self.message_formatter = message_formatter + self.print_unknown_fields = print_unknown_fields + self.force_colon = force_colon + + def _TryPrintAsAnyMessage(self, message): + """Serializes if message is a google.protobuf.Any field.""" + if '/' not in message.type_url: + return False + packed_message = _BuildMessageFromTypeName( + message.TypeName(), self.descriptor_pool + ) + if packed_message is not None: + packed_message.MergeFromString(message.value) + colon = ':' if self.force_colon else '' + self.out.write('%s[%s]%s ' % (self.indent * ' ', message.type_url, colon)) + self._PrintMessageFieldValue(packed_message) + self.out.write(' ' if self.as_one_line else '\n') + return True + else: + return False + + def _TryCustomFormatMessage(self, message): + formatted = self.message_formatter(message, self.indent, self.as_one_line) + if formatted is None: + return False + + out = self.out + out.write(' ' * self.indent) + out.write(formatted) + out.write(' ' if self.as_one_line else '\n') + return True + + def PrintMessage(self, message): + """Convert protobuf message to text format. + + Args: + message: The protocol buffers message. + """ + if self.message_formatter and self._TryCustomFormatMessage(message): + return + if ( + message.DESCRIPTOR.full_name == _ANY_FULL_TYPE_NAME + and self._TryPrintAsAnyMessage(message) + ): + return + fields = message.ListFields() + if self.use_index_order: + fields.sort( + key=lambda x: x[0].number if x[0].is_extension else x[0].index + ) + for field, value in fields: + if _IsMapEntry(field): + for key in sorted(value): + # This is slow for maps with submessage entries because it copies the + # entire tree. Unfortunately this would take significant refactoring + # of this file to work around. + # + # TODO: refactor and optimize if this becomes an issue. + entry_submsg = value.GetEntryClass()(key=key, value=value[key]) + self.PrintField(field, entry_submsg) + elif field.is_repeated: + if ( + self.use_short_repeated_primitives + and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE + and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_STRING + ): + self._PrintShortRepeatedPrimitivesValue(field, value) + else: + for element in value: + self.PrintField(field, element) + else: + self.PrintField(field, value) + + if self.print_unknown_fields: + self._PrintUnknownFields(unknown_fields.UnknownFieldSet(message)) + + def _PrintUnknownFields(self, unknown_field_set): + """Print unknown fields.""" + out = self.out + for field in unknown_field_set: + out.write(' ' * self.indent) + out.write(str(field.field_number)) + if field.wire_type == WIRETYPE_START_GROUP: + if self.as_one_line: + out.write(' { ') + else: + out.write(' {\n') + self.indent += 2 + + self._PrintUnknownFields(field.data) + + if self.as_one_line: + out.write('} ') + else: + self.indent -= 2 + out.write(' ' * self.indent + '}\n') + elif field.wire_type == WIRETYPE_LENGTH_DELIMITED: + try: + # If this field is parseable as a Message, it is probably + # an embedded message. + # pylint: disable=protected-access + embedded_unknown_message, pos = decoder._DecodeUnknownFieldSet( + memoryview(field.data), 0, len(field.data) + ) + except Exception: # pylint: disable=broad-except + pos = 0 + + if pos == len(field.data): + if self.as_one_line: + out.write(' { ') + else: + out.write(' {\n') + self.indent += 2 + + self._PrintUnknownFields(embedded_unknown_message) + + if self.as_one_line: + out.write('} ') + else: + self.indent -= 2 + out.write(' ' * self.indent + '}\n') + else: + # A string or bytes field. self.as_utf8 may not work. + out.write(': "') + out.write(text_encoding.CEscape(field.data, False)) + out.write('" ' if self.as_one_line else '"\n') + else: + # varint, fixed32, fixed64 + out.write(': ') + out.write(str(field.data)) + out.write(' ' if self.as_one_line else '\n') + + def _PrintFieldName(self, field): + """Print field name.""" + out = self.out + out.write(' ' * self.indent) + if self.use_field_number: + out.write(str(field.number)) + else: + if field.is_extension: + out.write('[') + if ( + field.containing_type.GetOptions().message_set_wire_format + and field.type == descriptor.FieldDescriptor.TYPE_MESSAGE + and not field.is_required + and not field.is_repeated + ): + out.write(field.message_type.full_name) + else: + out.write(field.full_name) + out.write(']') + elif _IsGroupLike(field): + # For groups, use the capitalized name. + out.write(field.message_type.name) + else: + out.write(field.name) + + if ( + self.force_colon + or field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE + ): + # The colon is optional in this case, but our cross-language golden files + # don't include it. Here, the colon is only included if force_colon is + # set to True + out.write(':') + + def PrintField(self, field, value): + """Print a single field name/value pair.""" + self._PrintFieldName(field) + self.out.write(' ') + self.PrintFieldValue(field, value) + self.out.write(' ' if self.as_one_line else '\n') + + def _PrintShortRepeatedPrimitivesValue(self, field, value): + """ "Prints short repeated primitives value.""" + # Note: this is called only when value has at least one element. + self._PrintFieldName(field) + self.out.write(' [') + for i in range(len(value) - 1): + self.PrintFieldValue(field, value[i]) + self.out.write(', ') + self.PrintFieldValue(field, value[-1]) + self.out.write(']') + self.out.write(' ' if self.as_one_line else '\n') + + def _PrintMessageFieldValue(self, value): + if self.pointy_brackets: + openb = '<' + closeb = '>' + else: + openb = '{' + closeb = '}' + + if self.as_one_line: + self.out.write('%s ' % openb) + self.PrintMessage(value) + self.out.write(closeb) + else: + self.out.write('%s\n' % openb) + self.indent += 2 + self.PrintMessage(value) + self.indent -= 2 + self.out.write(' ' * self.indent + closeb) + + def PrintFieldValue(self, field, value): + """Print a single field value (not including name). + + For repeated fields, the value should be a single element. + + Args: + field: The descriptor of the field to be printed. + value: The value of the field. + """ + out = self.out + if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + self._PrintMessageFieldValue(value) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: + enum_value = field.enum_type.values_by_number.get(value, None) + if enum_value is not None: + out.write(enum_value.name) + else: + out.write(str(value)) + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: + out.write('"') + if isinstance(value, str) and not self.as_utf8: + out_value = value.encode('utf-8') + else: + out_value = value + if field.type == descriptor.FieldDescriptor.TYPE_BYTES: + # We always need to escape all binary data in TYPE_BYTES fields. + out_as_utf8 = False + else: + out_as_utf8 = self.as_utf8 + out.write(text_encoding.CEscape(out_value, out_as_utf8)) + out.write('"') + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: + if value: + out.write('true') + else: + out.write('false') + elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: + if math.isnan(value): + out.write(str(value)) + else: + out.write(str(type_checkers.ToShortestFloat(value))) + else: + out.write(str(value)) + + +def Parse( + text, + message, + allow_unknown_extension=False, + allow_field_number=False, + descriptor_pool=None, + allow_unknown_field=False, + max_recursion_depth=None, +): + """Parses a text representation of a protocol message into a message. + + NOTE: for historical reasons this function does not clear the input + message. This is different from what the binary msg.ParseFrom(...) does. + If text contains a field already set in message, the value is appended if the + field is repeated. Otherwise, an error is raised. + + Example:: + + a = MyProto() + a.repeated_field.append('test') + b = MyProto() + + # Repeated fields are combined + text_format.Parse(repr(a), b) + text_format.Parse(repr(a), b) # repeated_field contains ["test", "test"] + + # Non-repeated fields cannot be overwritten + a.singular_field = 1 + b.singular_field = 2 + text_format.Parse(repr(a), b) # ParseError + + # Binary version: + b.ParseFromString(a.SerializeToString()) # repeated_field is now "test" + + Caller is responsible for clearing the message as needed. + + Args: + text (str): Message text representation. + message (Message): A protocol buffer message to merge into. + allow_unknown_extension: if True, skip over missing extensions and keep + parsing + allow_field_number: if True, both field number and field name are allowed. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. + allow_unknown_field: if True, skip over unknown field and keep parsing. + Avoid to use this option if possible. It may hide some errors (e.g. + spelling error on field name) + max_recursion_depth: Optional maximum recursion depth of the message to be + parsed: Text Format inputs over this depth will fail to parse. ``None`` + means no additional limit (the Python runtime will enforce some limit + due to call stack limits). As Text Format is primarily intended to be + used on trusted configuration inputs, and to maintain backwards + compatibility, the default of ``None`` (unbounded) is intentional. For + better consistency with what messages will successfully round trip + through binary wire format, or for the discouraged case of processing + untrusted Text Format inputs, setting a limit of 100 is recommended. + + Returns: + Message: The same message passed as argument. + + Raises: + ParseError: On text parsing problems. + """ + return ParseLines( + text.split(b'\n' if isinstance(text, bytes) else '\n'), + message, + allow_unknown_extension, + allow_field_number, + descriptor_pool=descriptor_pool, + allow_unknown_field=allow_unknown_field, + max_recursion_depth=max_recursion_depth, + ) + + +def Merge( + text, + message, + allow_unknown_extension=False, + allow_field_number=False, + descriptor_pool=None, + allow_unknown_field=False, + max_recursion_depth=None, +): + """Parses a text representation of a protocol message into a message. + + Like Parse(), but allows repeated values for a non-repeated field, and uses + the last one. This means any non-repeated, top-level fields specified in text + replace those in the message. + + Args: + text (str): Message text representation. + message (Message): A protocol buffer message to merge into. + allow_unknown_extension: if True, skip over missing extensions and keep + parsing + allow_field_number: if True, both field number and field name are allowed. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. + allow_unknown_field: if True, skip over unknown field and keep parsing. + Avoid to use this option if possible. It may hide some errors (e.g. + spelling error on field name) + max_recursion_depth: Optional maximum recursion depth of the message to be + parsed: Text Format inputs over this depth will fail to parse. ``None`` + means no additional limit (the Python runtime will enforce some limit + due to call stack limits). As Text Format is primarily intended to be + used on trusted configuration inputs, and to maintain backwards + compatibility, the default of ``None`` (unbounded) is intentional. For + better consistency with what messages will successfully round trip + through binary wire format, or for the discouraged case of processing + untrusted Text Format inputs, setting a limit of 100 is recommended. + + Returns: + Message: The same message passed as argument. + + Raises: + ParseError: On text parsing problems. + """ + return MergeLines( + text.split(b'\n' if isinstance(text, bytes) else '\n'), + message, + allow_unknown_extension, + allow_field_number, + descriptor_pool=descriptor_pool, + allow_unknown_field=allow_unknown_field, + max_recursion_depth=max_recursion_depth, + ) + + +def ParseLines( + lines, + message, + allow_unknown_extension=False, + allow_field_number=False, + descriptor_pool=None, + allow_unknown_field=False, + max_recursion_depth=None, +): + """Parses a text representation of a protocol message into a message. + + See Parse() for caveats. + + Args: + lines: An iterable of lines of a message's text representation. + message: A protocol buffer message to merge into. + allow_unknown_extension: if True, skip over missing extensions and keep + parsing + allow_field_number: if True, both field number and field name are allowed. + descriptor_pool: A DescriptorPool used to resolve Any types. + allow_unknown_field: if True, skip over unknown field and keep parsing. + Avoid to use this option if possible. It may hide some errors (e.g. + spelling error on field name) + max_recursion_depth: Optional maximum recursion depth of the message to be + parsed: Text Format inputs over this depth will fail to parse. ``None`` + means no additional limit (the Python runtime will enforce some limit + due to call stack limits). As Text Format is primarily intended to be + used on trusted configuration inputs, and to maintain backwards + compatibility, the default of ``None`` (unbounded) is intentional. For + better consistency with what messages will successfully round trip + through binary wire format, or for the discouraged case of processing + untrusted Text Format inputs, setting a limit of 100 is recommended. + + Returns: + The same message passed as argument. + + Raises: + ParseError: On text parsing problems. + """ + parser = _Parser( + allow_unknown_extension, + allow_field_number, + descriptor_pool=descriptor_pool, + allow_unknown_field=allow_unknown_field, + max_recursion_depth=max_recursion_depth, + ) + return parser.ParseLines(lines, message) + + +def MergeLines( + lines, + message, + allow_unknown_extension=False, + allow_field_number=False, + descriptor_pool=None, + allow_unknown_field=False, + max_recursion_depth=None, +): + """Parses a text representation of a protocol message into a message. + + See Merge() for more details. + + Args: + lines: An iterable of lines of a message's text representation. + message: A protocol buffer message to merge into. + allow_unknown_extension: if True, skip over missing extensions and keep + parsing + allow_field_number: if True, both field number and field name are allowed. + descriptor_pool: A DescriptorPool used to resolve Any types. + allow_unknown_field: if True, skip over unknown field and keep parsing. + Avoid to use this option if possible. It may hide some errors (e.g. + spelling error on field name) + max_recursion_depth: Optional maximum recursion depth of the message to be + parsed: Text Format inputs over this depth will fail to parse. ``None`` + means no additional limit (the Python runtime will enforce some limit + due to call stack limits). As Text Format is primarily intended to be + used on trusted configuration inputs, and to maintain backwards + compatibility, the default of ``None`` (unbounded) is intentional. For + better consistency with what messages will successfully round trip + through binary wire format, or for the discouraged case of processing + untrusted Text Format inputs, setting a limit of 100 is recommended. + + Returns: + The same message passed as argument. + + Raises: + ParseError: On text parsing problems. + """ + parser = _Parser( + allow_unknown_extension, + allow_field_number, + descriptor_pool=descriptor_pool, + allow_unknown_field=allow_unknown_field, + max_recursion_depth=max_recursion_depth, + ) + return parser.MergeLines(lines, message) + + +class _Parser(object): + """Text format parser for protocol message.""" + + def __init__( + self, + allow_unknown_extension=False, + allow_field_number=False, + descriptor_pool=None, + allow_unknown_field=False, + max_recursion_depth=None, + ): + self.allow_unknown_extension = allow_unknown_extension + self.allow_field_number = allow_field_number + self.descriptor_pool = descriptor_pool + self.allow_unknown_field = allow_unknown_field + self.max_recursion_depth = max_recursion_depth + self.recursion_depth = 0 + + def ParseLines(self, lines, message): + """Parses a text representation of a protocol message into a message.""" + self._allow_multiple_scalars = False + self._ParseOrMerge(lines, message) + return message + + def MergeLines(self, lines, message): + """Merges a text representation of a protocol message into a message.""" + self._allow_multiple_scalars = True + self._ParseOrMerge(lines, message) + return message + + def _ParseOrMerge(self, lines, message): + """Converts a text representation of a protocol message into a message. + + Args: + lines: Lines of a message's text representation. + message: A protocol buffer message to merge into. + + Raises: + ParseError: On text parsing problems. + """ + # Tokenize expects native str lines. + try: + str_lines = ( + line if isinstance(line, str) else line.decode('utf-8') + for line in lines + ) + tokenizer = Tokenizer(str_lines) + except UnicodeDecodeError as e: + raise ParseError from e + if message: + self.root_type = message.DESCRIPTOR.full_name + self.recursion_depth += 1 + if ( + self.max_recursion_depth is not None + and self.recursion_depth > self.max_recursion_depth + ): + raise ParseError( + 'Message too deep. Max recursion depth is {0}'.format( + self.max_recursion_depth + ) + ) + while not tokenizer.AtEnd(): + self._MergeField(tokenizer, message) + self.recursion_depth -= 1 + + def _MergeMessage(self, tokenizer, message, end_token): + self.recursion_depth += 1 + if ( + self.max_recursion_depth is not None + and self.recursion_depth > self.max_recursion_depth + ): + raise ParseError( + 'Message too deep. Max recursion depth is {0}'.format( + self.max_recursion_depth + ) + ) + while not tokenizer.TryConsume(end_token): + if tokenizer.AtEnd(): + raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token,)) + self._MergeField(tokenizer, message) + self.recursion_depth -= 1 + + def _MergeField(self, tokenizer, message): + """Merges a single protocol message field into a message. + + Args: + tokenizer: A tokenizer to parse the field name and values. + message: A protocol message to record the data. + + Raises: + ParseError: In case of text parsing problems. + """ + message_descriptor = message.DESCRIPTOR + if ( + message_descriptor.full_name == _ANY_FULL_TYPE_NAME + and tokenizer.TryConsume('[') + ): + type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer) + tokenizer.TryConsume(':') + self._DetectSilentMarker( + tokenizer, + message_descriptor.full_name, + type_url_prefix + '/' + packed_type_name, + ) + if tokenizer.TryConsume('<'): + expanded_any_end_token = '>' + else: + tokenizer.Consume('{') + expanded_any_end_token = '}' + expanded_any_sub_message = _BuildMessageFromTypeName( + packed_type_name, self.descriptor_pool + ) + # Direct comparison with None is used instead of implicit bool conversion + # to avoid false positives with falsy initial values, e.g. for + # google.protobuf.ListValue. + if expanded_any_sub_message is None: + raise ParseError( + 'Type %s not found in descriptor pool' % packed_type_name + ) + self._MergeMessage( + tokenizer, expanded_any_sub_message, expanded_any_end_token + ) + deterministic = False + + message.Pack( + expanded_any_sub_message, + type_url_prefix=type_url_prefix + '/', + deterministic=deterministic, + ) + return + + if tokenizer.TryConsume('['): + name = [tokenizer.ConsumeIdentifier()] + while tokenizer.TryConsume('.'): + name.append(tokenizer.ConsumeIdentifier()) + name = '.'.join(name) + + if not message_descriptor.is_extendable: + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" does not have extensions.' + % message_descriptor.full_name + ) + # pylint: disable=protected-access + field = message.Extensions._FindExtensionByName(name) + # pylint: enable=protected-access + if not field: + if self.allow_unknown_extension: + field = None + else: + raise tokenizer.ParseErrorPreviousToken( + 'Extension "%s" not registered. ' + 'Did you import the _pb2 module which defines it? ' + 'If you are trying to place the extension in the MessageSet ' + 'field of another message that is in an Any or MessageSet field, ' + "that message's _pb2 module must be imported as well" % name + ) + elif message_descriptor != field.containing_type: + raise tokenizer.ParseErrorPreviousToken( + 'Extension "%s" does not extend message type "%s".' + % (name, message_descriptor.full_name) + ) + + tokenizer.Consume(']') + + else: + name = tokenizer.ConsumeIdentifierOrNumber() + if self.allow_field_number and name.isdigit(): + number = ParseInteger(name, True, True) + field = message_descriptor.fields_by_number.get(number, None) + if not field and message_descriptor.is_extendable: + field = message.Extensions._FindExtensionByNumber(number) + else: + field = message_descriptor.fields_by_name.get(name, None) + + # Group names are expected to be capitalized as they appear in the + # .proto file, which actually matches their type names, not their field + # names. + if not field: + field = message_descriptor.fields_by_name.get(name.lower(), None) + if field and not _IsGroupLike(field): + field = None + if field and field.message_type.name != name: + field = None + + if not field and not self.allow_unknown_field: + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" has no field named "%s".' + % (message_descriptor.full_name, name) + ) + + if field: + if not self._allow_multiple_scalars and field.containing_oneof: + # Check if there's a different field set in this oneof. + # Note that we ignore the case if the same field was set before, and we + # apply _allow_multiple_scalars to non-scalar fields as well. + which_oneof = message.WhichOneof(field.containing_oneof.name) + if which_oneof is not None and which_oneof != field.name: + raise tokenizer.ParseErrorPreviousToken( + 'Field "%s" is specified along with field "%s", another member ' + 'of oneof "%s" for message type "%s".' + % ( + field.name, + which_oneof, + field.containing_oneof.name, + message_descriptor.full_name, + ) + ) + + if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + tokenizer.TryConsume(':') + self._DetectSilentMarker( + tokenizer, message_descriptor.full_name, field.full_name + ) + merger = self._MergeMessageField + else: + tokenizer.Consume(':') + self._DetectSilentMarker( + tokenizer, message_descriptor.full_name, field.full_name + ) + merger = self._MergeScalarField + + if field.is_repeated and tokenizer.TryConsume('['): + # Short repeated format, e.g. "foo: [1, 2, 3]" + if not tokenizer.TryConsume(']'): + while True: + merger(tokenizer, message, field) + if tokenizer.TryConsume(']'): + break + tokenizer.Consume(',') + + else: + merger(tokenizer, message, field) + + else: # Proto field is unknown. + assert self.allow_unknown_extension or self.allow_unknown_field + self._SkipFieldContents(tokenizer, name, message_descriptor.full_name) + + # For historical reasons, fields may optionally be separated by commas or + # semicolons. + if not tokenizer.TryConsume(','): + tokenizer.TryConsume(';') + + def _LogSilentMarker(self, immediate_message_type, field_name): + pass + + def _DetectSilentMarker(self, tokenizer, immediate_message_type, field_name): + if tokenizer.contains_silent_marker_before_current_token: + self._LogSilentMarker(immediate_message_type, field_name) + + def _ConsumeAnyTypeUrl(self, tokenizer): + """Consumes a google.protobuf.Any type URL. + + Assumes the caller has already consumed the opening [ and consumes up to the + closing ]. + + Args: + tokenizer: A tokenizer to parse the type URL. + + Returns: + A tuple of type URL prefix (without trailing slash) and type name. + """ + # Consume all tokens with valid URL characters until ]. Whitespace and + # comments are ignored/skipped by the Tokenizer. + tokens = [] + last_slash = -1 + while True: + try: + tokens.append(tokenizer.ConsumeUrlChars()) + continue + except ParseError: + pass + if tokenizer.TryConsume('/'): + last_slash = len(tokens) + tokens.append('/') + else: + tokenizer.Consume(']') + break + + if last_slash == -1: + raise tokenizer.ParseError('Type URL does not contain "/".') + + prefix = ''.join(tokens[:last_slash]) + name = ''.join(tokens[last_slash + 1 :]) + + if not prefix: + raise tokenizer.ParseError('Type URL prefix is empty.') + if prefix.startswith('/'): + raise tokenizer.ParseError('Type URL prefix starts with "/".') + + # Check for invalid percent encodings. '%' needs to be followed by exactly + # two valid hexadecimal digits. + for i, char in enumerate(prefix): + if char == '%' and not _PERCENT_ENCODING.match(prefix[i : i + 3]): + raise tokenizer.ParseError( + f'Invalid percent escape, got "{prefix[i : i + 3]}".' + ) + + # After the last slash we expect a valid type name, not just any sequence of + # URL characters. + if not _TYPE_NAME.match(name): + raise tokenizer.ParseError('Expected type name, got "%s".' % name) + + return prefix, name + + def _MergeMessageField(self, tokenizer, message, field): + """Merges a single scalar field into a message. + + Args: + tokenizer: A tokenizer to parse the field value. + message: The message of which field is a member. + field: The descriptor of the field to be merged. + + Raises: + ParseError: In case of text parsing problems. + """ + is_map_entry = _IsMapEntry(field) + + if tokenizer.TryConsume('<'): + end_token = '>' + else: + tokenizer.Consume('{') + end_token = '}' + + if field.is_repeated: + if field.is_extension: + sub_message = message.Extensions[field].add() + elif is_map_entry: + sub_message = getattr(message, field.name).GetEntryClass()() + else: + sub_message = getattr(message, field.name).add() + else: + if field.is_extension: + if not self._allow_multiple_scalars and message.HasExtension(field): + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" should not have multiple "%s" extensions.' + % (message.DESCRIPTOR.full_name, field.full_name) + ) + sub_message = message.Extensions[field] + else: + # Also apply _allow_multiple_scalars to message field. + # TODO: Change to _allow_singular_overwrites. + if not self._allow_multiple_scalars and message.HasField(field.name): + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" should not have multiple "%s" fields.' + % (message.DESCRIPTOR.full_name, field.name) + ) + sub_message = getattr(message, field.name) + sub_message.SetInParent() + + self._MergeMessage(tokenizer, sub_message, end_token) + + if is_map_entry: + value_cpptype = field.message_type.fields_by_name['value'].cpp_type + if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + value = getattr(message, field.name)[sub_message.key] + value.CopyFrom(sub_message.value) + else: + getattr(message, field.name)[sub_message.key] = sub_message.value + + def _MergeScalarField(self, tokenizer, message, field): + """Merges a single scalar field into a message. + + Args: + tokenizer: A tokenizer to parse the field value. + message: A protocol message to record the data. + field: The descriptor of the field to be merged. + + Raises: + ParseError: In case of text parsing problems. + RuntimeError: On runtime errors. + """ + _ = self.allow_unknown_extension + value = None + + if field.type in ( + descriptor.FieldDescriptor.TYPE_INT32, + descriptor.FieldDescriptor.TYPE_SINT32, + descriptor.FieldDescriptor.TYPE_SFIXED32, + ): + value = _ConsumeInt32(tokenizer) + elif field.type in ( + descriptor.FieldDescriptor.TYPE_INT64, + descriptor.FieldDescriptor.TYPE_SINT64, + descriptor.FieldDescriptor.TYPE_SFIXED64, + ): + value = _ConsumeInt64(tokenizer) + elif field.type in ( + descriptor.FieldDescriptor.TYPE_UINT32, + descriptor.FieldDescriptor.TYPE_FIXED32, + ): + value = _ConsumeUint32(tokenizer) + elif field.type in ( + descriptor.FieldDescriptor.TYPE_UINT64, + descriptor.FieldDescriptor.TYPE_FIXED64, + ): + value = _ConsumeUint64(tokenizer) + elif field.type in ( + descriptor.FieldDescriptor.TYPE_FLOAT, + descriptor.FieldDescriptor.TYPE_DOUBLE, + ): + value = tokenizer.ConsumeFloat() + elif field.type == descriptor.FieldDescriptor.TYPE_BOOL: + value = tokenizer.ConsumeBool() + elif field.type == descriptor.FieldDescriptor.TYPE_STRING: + value = tokenizer.ConsumeString() + elif field.type == descriptor.FieldDescriptor.TYPE_BYTES: + value = tokenizer.ConsumeByteString() + elif field.type == descriptor.FieldDescriptor.TYPE_ENUM: + value = tokenizer.ConsumeEnum(field) + else: + raise RuntimeError('Unknown field type %d' % field.type) + + if field.is_repeated: + if field.is_extension: + message.Extensions[field].append(value) + else: + getattr(message, field.name).append(value) + else: + if field.is_extension: + if ( + not self._allow_multiple_scalars + and field.has_presence + and message.HasExtension(field) + ): + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" should not have multiple "%s" extensions.' + % (message.DESCRIPTOR.full_name, field.full_name) + ) + else: + message.Extensions[field] = value + else: + duplicate_error = False + if not self._allow_multiple_scalars: + if field.has_presence: + duplicate_error = message.HasField(field.name) + else: + # For field that doesn't represent presence, try best effort to + # check multiple scalars by compare to default values. + duplicate_error = not decoder.IsDefaultScalarValue( + getattr(message, field.name) + ) + + if duplicate_error: + raise tokenizer.ParseErrorPreviousToken( + 'Message type "%s" should not have multiple "%s" fields.' + % (message.DESCRIPTOR.full_name, field.name) + ) + else: + setattr(message, field.name, value) + + def _SkipFieldContents(self, tokenizer, field_name, immediate_message_type): + """Skips over contents (value or message) of a field. + + Args: + tokenizer: A tokenizer to parse the field name and values. + field_name: The field name currently being parsed. + immediate_message_type: The type of the message immediately containing the + silent marker. + """ + # Try to guess the type of this field. + # If this field is not a message, there should be a ":" between the + # field name and the field value and also the field value should not + # start with "{" or "<" which indicates the beginning of a message body. + # If there is no ":" or there is a "{" or "<" after ":", this field has + # to be a message or the input is ill-formed. + if ( + tokenizer.TryConsume(':') + and not tokenizer.LookingAt('{') + and not tokenizer.LookingAt('<') + ): + self._DetectSilentMarker(tokenizer, immediate_message_type, field_name) + if tokenizer.LookingAt('['): + self._SkipRepeatedFieldValue(tokenizer, immediate_message_type) + else: + self._SkipFieldValue(tokenizer) + else: + self._DetectSilentMarker(tokenizer, immediate_message_type, field_name) + self._SkipFieldMessage(tokenizer, immediate_message_type) + + def _SkipField(self, tokenizer, immediate_message_type): + """Skips over a complete field (name and value/message). + + Args: + tokenizer: A tokenizer to parse the field name and values. + immediate_message_type: The type of the message immediately containing the + silent marker. + """ + field_name = '' + if tokenizer.TryConsume('['): + # Consume extension or google.protobuf.Any type URL + field_name += '[' + tokenizer.ConsumeIdentifier() + num_identifiers = 1 + while tokenizer.TryConsume('.'): + field_name += '.' + tokenizer.ConsumeIdentifier() + num_identifiers += 1 + # This is possibly a type URL for an Any message. + if num_identifiers == 3 and tokenizer.TryConsume('/'): + field_name += '/' + tokenizer.ConsumeIdentifier() + while tokenizer.TryConsume('.'): + field_name += '.' + tokenizer.ConsumeIdentifier() + tokenizer.Consume(']') + field_name += ']' + else: + field_name += tokenizer.ConsumeIdentifierOrNumber() + + self._SkipFieldContents(tokenizer, field_name, immediate_message_type) + + # For historical reasons, fields may optionally be separated by commas or + # semicolons. + if not tokenizer.TryConsume(','): + tokenizer.TryConsume(';') + + def _SkipFieldMessage(self, tokenizer, immediate_message_type): + """Skips over a field message. + + Args: + tokenizer: A tokenizer to parse the field name and values. + immediate_message_type: The type of the message immediately containing the + silent marker + """ + if tokenizer.TryConsume('<'): + delimiter = '>' + else: + tokenizer.Consume('{') + delimiter = '}' + + while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'): + self._SkipField(tokenizer, immediate_message_type) + + tokenizer.Consume(delimiter) + + def _SkipFieldValue(self, tokenizer): + """Skips over a field value. + + Args: + tokenizer: A tokenizer to parse the field name and values. + + Raises: + ParseError: In case an invalid field value is found. + """ + if ( + not tokenizer.TryConsumeByteString() + and not tokenizer.TryConsumeIdentifier() + and not _TryConsumeInt64(tokenizer) + and not _TryConsumeUint64(tokenizer) + and not tokenizer.TryConsumeFloat() + ): + raise ParseError('Invalid field value: ' + tokenizer.token) + + def _SkipRepeatedFieldValue(self, tokenizer, immediate_message_type): + """Skips over a repeated field value. + + Args: + tokenizer: A tokenizer to parse the field value. + """ + tokenizer.Consume('[') + if not tokenizer.TryConsume(']'): + while True: + if tokenizer.LookingAt('<') or tokenizer.LookingAt('{'): + self._SkipFieldMessage(tokenizer, immediate_message_type) + else: + self._SkipFieldValue(tokenizer) + if tokenizer.TryConsume(']'): + break + tokenizer.Consume(',') + + +class Tokenizer(object): + """Protocol buffer text representation tokenizer. + + This class handles the lower level string parsing by splitting it into + meaningful tokens. + + It was directly ported from the Java protocol buffer API. + """ + + _WHITESPACE = re.compile(r'\s+') + _COMMENT = re.compile(r'(\s*#.*$)', re.MULTILINE) + _WHITESPACE_OR_COMMENT = re.compile(r'(\s|(#.*$))+', re.MULTILINE) + _TOKEN = re.compile( + '|'.join( + [ + r'[a-zA-Z_][0-9a-zA-Z_+-]*', # an identifier + r'([0-9+-]|(\.[0-9]))[0-9a-zA-Z_.+-]*', # a number + ] + + [ # quoted str for each quote mark + # Avoid backtracking! https://stackoverflow.com/a/844267 + r'{qt}[^{qt}\n\\]*((\\.)+[^{qt}\n\\]*)*({qt}|\\?$)'.format( + qt=mark + ) + for mark in _QUOTES + ] + ) + ) + + _IDENTIFIER = re.compile(r'[^\d\W]\w*') + _IDENTIFIER_OR_NUMBER = re.compile(r'\w+') + # Accepted URL characters (excluding "/") + _URL_CHARS = re.compile(r'^[0-9a-zA-Z-.~_ !$&()*+,;=%]+$') + + def __init__(self, lines, skip_comments=True): + self._position = 0 + self._line = -1 + self._column = 0 + self._token_start = None + self.token = '' + self._lines = iter(lines) + self._current_line = '' + self._previous_line = 0 + self._previous_column = 0 + self._more_lines = True + self._skip_comments = skip_comments + self._whitespace_pattern = ( + skip_comments and self._WHITESPACE_OR_COMMENT or self._WHITESPACE + ) + self.contains_silent_marker_before_current_token = False + + self._SkipWhitespace() + self.NextToken() + + def LookingAt(self, token): + return self.token == token + + def AtEnd(self): + """Checks the end of the text was reached. + + Returns: + True iff the end was reached. + """ + return not self.token + + def _PopLine(self): + while len(self._current_line) <= self._column: + try: + self._current_line = next(self._lines) + except StopIteration: + self._current_line = '' + self._more_lines = False + return + else: + self._line += 1 + self._column = 0 + + def _SkipWhitespace(self): + while True: + self._PopLine() + match = self._whitespace_pattern.match(self._current_line, self._column) + if not match: + break + self.contains_silent_marker_before_current_token = match.group(0) == ( + ' ' + _DEBUG_STRING_SILENT_MARKER + ) + length = len(match.group(0)) + self._column += length + + def TryConsume(self, token): + """Tries to consume a given piece of text. + + Args: + token: Text to consume. + + Returns: + True iff the text was consumed. + """ + if self.token == token: + self.NextToken() + return True + return False + + def Consume(self, token): + """Consumes a piece of text. + + Args: + token: Text to consume. + + Raises: + ParseError: If the text couldn't be consumed. + """ + if not self.TryConsume(token): + raise self.ParseError('Expected "%s".' % token) + + def ConsumeComment(self): + result = self.token + if not self._COMMENT.match(result): + raise self.ParseError('Expected comment.') + self.NextToken() + return result + + def ConsumeCommentOrTrailingComment(self): + """Consumes a comment, returns a 2-tuple (trailing bool, comment str).""" + + # Tokenizer initializes _previous_line and _previous_column to 0. As the + # tokenizer starts, it looks like there is a previous token on the line. + just_started = self._line == 0 and self._column == 0 + + before_parsing = self._previous_line + comment = self.ConsumeComment() + + # A trailing comment is a comment on the same line than the previous token. + trailing = self._previous_line == before_parsing and not just_started + + return trailing, comment + + def TryConsumeIdentifier(self): + try: + self.ConsumeIdentifier() + return True + except ParseError: + return False + + def ConsumeIdentifier(self): + """Consumes protocol message field identifier. + + Returns: + Identifier string. + + Raises: + ParseError: If an identifier couldn't be consumed. + """ + result = self.token + if not self._IDENTIFIER.match(result): + raise self.ParseError('Expected identifier.') + self.NextToken() + return result + + def TryConsumeIdentifierOrNumber(self): + try: + self.ConsumeIdentifierOrNumber() + return True + except ParseError: + return False + + def ConsumeIdentifierOrNumber(self): + """Consumes protocol message field identifier. + + Returns: + Identifier string. + + Raises: + ParseError: If an identifier couldn't be consumed. + """ + result = self.token + if not self._IDENTIFIER_OR_NUMBER.match(result): + raise self.ParseError('Expected identifier or number, got %s.' % result) + self.NextToken() + return result + + def TryConsumeInteger(self): + try: + self.ConsumeInteger() + return True + except ParseError: + return False + + def ConsumeInteger(self): + """Consumes an integer number. + + Returns: + The integer parsed. + + Raises: + ParseError: If an integer couldn't be consumed. + """ + try: + result = _ParseAbstractInteger(self.token) + except ValueError as e: + raise self.ParseError(str(e)) + self.NextToken() + return result + + def TryConsumeFloat(self): + try: + self.ConsumeFloat() + return True + except ParseError: + return False + + def ConsumeFloat(self): + """Consumes an floating point number. + + Returns: + The number parsed. + + Raises: + ParseError: If a floating point number couldn't be consumed. + """ + try: + result = ParseFloat(self.token) + except ValueError as e: + raise self.ParseError(str(e)) + self.NextToken() + return result + + def ConsumeBool(self): + """Consumes a boolean value. + + Returns: + The bool parsed. + + Raises: + ParseError: If a boolean value couldn't be consumed. + """ + try: + result = ParseBool(self.token) + except ValueError as e: + raise self.ParseError(str(e)) + self.NextToken() + return result + + def TryConsumeByteString(self): + try: + self.ConsumeByteString() + return True + except ParseError: + return False + + def ConsumeString(self): + """Consumes a string value. + + Returns: + The string parsed. + + Raises: + ParseError: If a string value couldn't be consumed. + """ + the_bytes = self.ConsumeByteString() + try: + return str(the_bytes, 'utf-8') + except UnicodeDecodeError as e: + raise self._StringParseError(e) + + def ConsumeByteString(self): + """Consumes a byte array value. + + Returns: + The array parsed (as a string). + + Raises: + ParseError: If a byte array value couldn't be consumed. + """ + the_list = [self._ConsumeSingleByteString()] + while self.token and self.token[0] in _QUOTES: + the_list.append(self._ConsumeSingleByteString()) + return b''.join(the_list) + + def _ConsumeSingleByteString(self): + """Consume one token of a string literal. + + String literals (whether bytes or text) can come in multiple adjacent + tokens which are automatically concatenated, like in C or Python. This + method only consumes one token. + + Returns: + The token parsed. + Raises: + ParseError: When the wrong format data is found. + """ + text = self.token + if len(text) < 1 or text[0] not in _QUOTES: + raise self.ParseError('Expected string but found: %r' % (text,)) + + if len(text) < 2 or text[-1] != text[0]: + raise self.ParseError('String missing ending quote: %r' % (text,)) + + try: + result = text_encoding.CUnescape(text[1:-1]) + except ValueError as e: + raise self.ParseError(str(e)) + self.NextToken() + return result + + def ConsumeEnum(self, field): + try: + result = ParseEnum(field, self.token) + except ValueError as e: + raise self.ParseError(str(e)) + self.NextToken() + return result + + def ConsumeUrlChars(self): + """Consumes a token containing valid URL characters. + + Excludes '/' so that it can be treated specially as a delimiter. + + Returns: + The next token containing one or more URL characters. + + Raises: + ParseError: If the next token contains unaccepted URL characters. + """ + if not self._URL_CHARS.match(self.token): + raise self.ParseError('Expected URL character(s), got "%s"' % self.token) + + result = self.token + self.NextToken() + return result + + def TryConsumeUrlChars(self): + try: + self.ConsumeUrlChars() + return True + except ParseError: + return False + + def ParseErrorPreviousToken(self, message): + """Creates and *returns* a ParseError for the previously read token. + + Args: + message: A message to set for the exception. + + Returns: + A ParseError instance. + """ + return ParseError( + message, self._previous_line + 1, self._previous_column + 1 + ) + + def ParseError(self, message): + """Creates and *returns* a ParseError for the current token.""" + return ParseError( + "'" + self._current_line + "': " + message, + self._line + 1, + self._column + 1, + ) + + def _StringParseError(self, e): + return self.ParseError("Couldn't parse string: " + str(e)) + + def NextToken(self): + """Reads the next meaningful token.""" + self._previous_line = self._line + self._previous_column = self._column + self.contains_silent_marker_before_current_token = False + + self._column += len(self.token) + self._SkipWhitespace() + + if not self._more_lines: + self.token = '' + return + + match = self._TOKEN.match(self._current_line, self._column) + if not match and not self._skip_comments: + match = self._COMMENT.match(self._current_line, self._column) + if match: + token = match.group(0) + self.token = token + else: + self.token = self._current_line[self._column] + + +# Aliased so it can still be accessed by current visibility violators. +# TODO: Migrate violators to textformat_tokenizer. +_Tokenizer = Tokenizer # pylint: disable=invalid-name + + +def _ConsumeInt32(tokenizer): + """Consumes a signed 32bit integer number from tokenizer. + + Args: + tokenizer: A tokenizer used to parse the number. + + Returns: + The integer parsed. + + Raises: + ParseError: If a signed 32bit integer couldn't be consumed. + """ + return _ConsumeInteger(tokenizer, is_signed=True, is_long=False) + + +def _ConsumeUint32(tokenizer): + """Consumes an unsigned 32bit integer number from tokenizer. + + Args: + tokenizer: A tokenizer used to parse the number. + + Returns: + The integer parsed. + + Raises: + ParseError: If an unsigned 32bit integer couldn't be consumed. + """ + return _ConsumeInteger(tokenizer, is_signed=False, is_long=False) + + +def _TryConsumeInt64(tokenizer): + try: + _ConsumeInt64(tokenizer) + return True + except ParseError: + return False + + +def _ConsumeInt64(tokenizer): + """Consumes a signed 32bit integer number from tokenizer. + + Args: + tokenizer: A tokenizer used to parse the number. + + Returns: + The integer parsed. + + Raises: + ParseError: If a signed 32bit integer couldn't be consumed. + """ + return _ConsumeInteger(tokenizer, is_signed=True, is_long=True) + + +def _TryConsumeUint64(tokenizer): + try: + _ConsumeUint64(tokenizer) + return True + except ParseError: + return False + + +def _ConsumeUint64(tokenizer): + """Consumes an unsigned 64bit integer number from tokenizer. + + Args: + tokenizer: A tokenizer used to parse the number. + + Returns: + The integer parsed. + + Raises: + ParseError: If an unsigned 64bit integer couldn't be consumed. + """ + return _ConsumeInteger(tokenizer, is_signed=False, is_long=True) + + +def _ConsumeInteger(tokenizer, is_signed=False, is_long=False): + """Consumes an integer number from tokenizer. + + Args: + tokenizer: A tokenizer used to parse the number. + is_signed: True if a signed integer must be parsed. + is_long: True if a long integer must be parsed. + + Returns: + The integer parsed. + + Raises: + ParseError: If an integer with given characteristics couldn't be consumed. + """ + try: + result = ParseInteger(tokenizer.token, is_signed=is_signed, is_long=is_long) + except ValueError as e: + raise tokenizer.ParseError(str(e)) + tokenizer.NextToken() + return result + + +def ParseInteger(text, is_signed=False, is_long=False): + """Parses an integer. + + Args: + text: The text to parse. + is_signed: True if a signed integer must be parsed. + is_long: True if a long integer must be parsed. + + Returns: + The integer value. + + Raises: + ValueError: Thrown Iff the text is not a valid integer. + """ + # Do the actual parsing. Exception handling is propagated to caller. + result = _ParseAbstractInteger(text) + + # Check if the integer is sane. Exceptions handled by callers. + checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)] + checker.CheckValue(result) + return result + + +def _ParseAbstractInteger(text): + """Parses an integer without checking size/signedness. + + Args: + text: The text to parse. + + Returns: + The integer value. + + Raises: + ValueError: Thrown Iff the text is not a valid integer. + """ + # Do the actual parsing. Exception handling is propagated to caller. + orig_text = text + c_octal_match = re.match(r'(-?)0(\d+)$', text) + if c_octal_match: + # Python 3 no longer supports 0755 octal syntax without the 'o', so + # we always use the '0o' prefix for multi-digit numbers starting with 0. + text = c_octal_match.group(1) + '0o' + c_octal_match.group(2) + try: + return int(text, 0) + except ValueError: + raise ValueError("Couldn't parse integer: %s" % orig_text) + + +def ParseFloat(text): + """Parse a floating point number. + + Args: + text: Text to parse. + + Returns: + The number parsed. + + Raises: + ValueError: If a floating point number couldn't be parsed. + """ + if _FLOAT_OCTAL_PREFIX.match(text): + raise ValueError('Invalid octal float: %s' % text) + try: + # Assume Python compatible syntax. + return float(text) + except ValueError: + # Check alternative spellings. + if _FLOAT_INFINITY.match(text): + if text[0] == '-': + return float('-inf') + else: + return float('inf') + elif _FLOAT_NAN.match(text): + return float('nan') + else: + # assume '1.0f' format + try: + return float(text.rstrip('fF')) + except ValueError: + raise ValueError("Couldn't parse float: %s" % text) + + +def ParseBool(text): + """Parse a boolean value. + + Args: + text: Text to parse. + + Returns: + Boolean values parsed + + Raises: + ValueError: If text is not a valid boolean. + """ + if text in ('true', 't', '1', 'True'): + return True + elif text in ('false', 'f', '0', 'False'): + return False + else: + raise ValueError('Expected "true" or "false".') + + +def ParseEnum(field, value): + """Parse an enum value. + + The value can be specified by a number (the enum value), or by + a string literal (the enum name). + + Args: + field: Enum field descriptor. + value: String value. + + Returns: + Enum value number. + + Raises: + ValueError: If the enum value could not be parsed. + """ + enum_descriptor = field.enum_type + try: + number = int(value, 0) + except ValueError: + # Identifier. + enum_value = enum_descriptor.values_by_name.get(value, None) + if enum_value is None: + raise ValueError( + 'Enum type "%s" has no value named %s.' + % (enum_descriptor.full_name, value) + ) + else: + if not field.enum_type.is_closed: + return number + enum_value = enum_descriptor.values_by_number.get(number, None) + if enum_value is None: + raise ValueError( + 'Enum type "%s" has no value with number %d.' + % (enum_descriptor.full_name, number) + ) + return enum_value.number diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py new file mode 100644 index 00000000000..fb9c89143bb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py @@ -0,0 +1,112 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd + +"""Contains the Timestamp helper APIs.""" + +import datetime +from typing import Optional + +from opentelemetry.agent._vendor.google.protobuf.timestamp_pb2 import Timestamp + + +def from_json_string(value: str) -> Timestamp: + """Parse a RFC 3339 date string format to Timestamp. + + Args: + value: A date string. Any fractional digits (or none) and any offset are + accepted as long as they fit into nano-seconds precision. Example of + accepted format: '1972-01-01T10:00:20.021-05:00' + + Raises: + ValueError: On parsing problems. + """ + timestamp = Timestamp() + timestamp.FromJsonString(value) + return timestamp + + +def from_microseconds(micros: float) -> Timestamp: + """Converts microseconds since epoch to Timestamp.""" + timestamp = Timestamp() + timestamp.FromMicroseconds(micros) + return timestamp + + +def from_milliseconds(millis: float) -> Timestamp: + """Converts milliseconds since epoch to Timestamp.""" + timestamp = Timestamp() + timestamp.FromMilliseconds(millis) + return timestamp + + +def from_nanoseconds(nanos: float) -> Timestamp: + """Converts nanoseconds since epoch to Timestamp.""" + timestamp = Timestamp() + timestamp.FromNanoseconds(nanos) + return timestamp + + +def from_seconds(seconds: float) -> Timestamp: + """Converts seconds since epoch to Timestamp.""" + timestamp = Timestamp() + timestamp.FromSeconds(seconds) + return timestamp + + +def from_current_time() -> Timestamp: + """Converts the current UTC to Timestamp.""" + timestamp = Timestamp() + timestamp.FromDatetime(datetime.datetime.now(tz=datetime.timezone.utc)) + return timestamp + + +def to_json_string(ts: Timestamp) -> str: + """Converts Timestamp to RFC 3339 date string format. + + Returns: + A string converted from timestamp. The string is always Z-normalized + and uses 3, 6 or 9 fractional digits as required to represent the + exact time. Example of the return format: '1972-01-01T10:00:20.021Z' + """ + return ts.ToJsonString() + + +def to_microseconds(ts: Timestamp) -> int: + """Converts Timestamp to microseconds since epoch.""" + return ts.ToMicroseconds() + + +def to_milliseconds(ts: Timestamp) -> int: + """Converts Timestamp to milliseconds since epoch.""" + return ts.ToMilliseconds() + + +def to_nanoseconds(ts: Timestamp) -> int: + """Converts Timestamp to nanoseconds since epoch.""" + return ts.ToNanoseconds() + + +def to_seconds(ts: Timestamp) -> int: + """Converts Timestamp to seconds since epoch.""" + return ts.ToSeconds() + + +def to_datetime( + ts: Timestamp, tz: Optional[datetime.tzinfo] = None +) -> datetime.datetime: + """Converts Timestamp to a datetime. + + Args: + tz: A datetime.tzinfo subclass; defaults to None. + + Returns: + If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone + information, i.e. not aware that it's UTC). + + Otherwise, returns a timezone-aware datetime in the input timezone. + """ + return ts.ToDatetime(tzinfo=tz) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py new file mode 100644 index 00000000000..41c048c29ff --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/timestamp.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/timestamp.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fgoogle/protobuf/timestamp.proto\x12\x0fgoogle.protobuf\";\n\tTimestamp\x12\x18\n\x07seconds\x18\x01 \x01(\x03R\x07seconds\x12\x14\n\x05nanos\x18\x02 \x01(\x05R\x05nanosB\x85\x01\n\x13\x63om.google.protobufB\x0eTimestampProtoP\x01Z2google.golang.org/protobuf/types/known/timestamppb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.timestamp_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\016TimestampProtoP\001Z2google.golang.org/protobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_TIMESTAMP']._serialized_start=52 + _globals['_TIMESTAMP']._serialized_end=111 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py new file mode 100644 index 00000000000..67d136d7765 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/type.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/type.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from opentelemetry.agent._vendor.google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1agoogle/protobuf/type.proto\x12\x0fgoogle.protobuf\x1a\x19google/protobuf/any.proto\x1a$google/protobuf/source_context.proto\"\xa7\x02\n\x04Type\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12.\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x16.google.protobuf.FieldR\x06\x66ields\x12\x16\n\x06oneofs\x18\x03 \x03(\tR\x06oneofs\x12\x31\n\x07options\x18\x04 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x45\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContextR\rsourceContext\x12/\n\x06syntax\x18\x06 \x01(\x0e\x32\x17.google.protobuf.SyntaxR\x06syntax\x12\x18\n\x07\x65\x64ition\x18\x07 \x01(\tR\x07\x65\x64ition\"\xb4\x06\n\x05\x46ield\x12/\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.google.protobuf.Field.KindR\x04kind\x12\x44\n\x0b\x63\x61rdinality\x18\x02 \x01(\x0e\x32\".google.protobuf.Field.CardinalityR\x0b\x63\x61rdinality\x12\x16\n\x06number\x18\x03 \x01(\x05R\x06number\x12\x12\n\x04name\x18\x04 \x01(\tR\x04name\x12\x19\n\x08type_url\x18\x06 \x01(\tR\x07typeUrl\x12\x1f\n\x0boneof_index\x18\x07 \x01(\x05R\noneofIndex\x12\x16\n\x06packed\x18\x08 \x01(\x08R\x06packed\x12\x31\n\x07options\x18\t \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x1b\n\tjson_name\x18\n \x01(\tR\x08jsonName\x12#\n\rdefault_value\x18\x0b \x01(\tR\x0c\x64\x65\x66\x61ultValue\"\xc8\x02\n\x04Kind\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"t\n\x0b\x43\x61rdinality\x12\x17\n\x13\x43\x41RDINALITY_UNKNOWN\x10\x00\x12\x18\n\x14\x43\x41RDINALITY_OPTIONAL\x10\x01\x12\x18\n\x14\x43\x41RDINALITY_REQUIRED\x10\x02\x12\x18\n\x14\x43\x41RDINALITY_REPEATED\x10\x03\"\x99\x02\n\x04\x45num\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x38\n\tenumvalue\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.EnumValueR\tenumvalue\x12\x31\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x45\n\x0esource_context\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.SourceContextR\rsourceContext\x12/\n\x06syntax\x18\x05 \x01(\x0e\x32\x17.google.protobuf.SyntaxR\x06syntax\x12\x18\n\x07\x65\x64ition\x18\x06 \x01(\tR\x07\x65\x64ition\"j\n\tEnumValue\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x02 \x01(\x05R\x06number\x12\x31\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\"H\n\x06Option\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x14.google.protobuf.AnyR\x05value*C\n\x06Syntax\x12\x11\n\rSYNTAX_PROTO2\x10\x00\x12\x11\n\rSYNTAX_PROTO3\x10\x01\x12\x13\n\x0fSYNTAX_EDITIONS\x10\x02\x42{\n\x13\x63om.google.protobufB\tTypeProtoP\x01Z-google.golang.org/protobuf/types/known/typepb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.type_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\tTypeProtoP\001Z-google.golang.org/protobuf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_SYNTAX']._serialized_start=1699 + _globals['_SYNTAX']._serialized_end=1766 + _globals['_TYPE']._serialized_start=113 + _globals['_TYPE']._serialized_end=408 + _globals['_FIELD']._serialized_start=411 + _globals['_FIELD']._serialized_end=1231 + _globals['_FIELD_KIND']._serialized_start=785 + _globals['_FIELD_KIND']._serialized_end=1113 + _globals['_FIELD_CARDINALITY']._serialized_start=1115 + _globals['_FIELD_CARDINALITY']._serialized_end=1231 + _globals['_ENUM']._serialized_start=1234 + _globals['_ENUM']._serialized_end=1515 + _globals['_ENUMVALUE']._serialized_start=1517 + _globals['_ENUMVALUE']._serialized_end=1623 + _globals['_OPTION']._serialized_start=1625 + _globals['_OPTION']._serialized_end=1697 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py new file mode 100644 index 00000000000..0845f428388 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py @@ -0,0 +1,93 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file or at +# https://developers.google.com/open-source/licenses/bsd +"""Contains Unknown Fields APIs. + +Simple usage example: + unknown_field_set = UnknownFieldSet(message) + for unknown_field in unknown_field_set: + wire_type = unknown_field.wire_type + field_number = unknown_field.field_number + data = unknown_field.data +""" + +from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation + +if api_implementation._c_module is not None: # pylint: disable=protected-access + UnknownFieldSet = api_implementation._c_module.UnknownFieldSet # pylint: disable=protected-access +else: + from opentelemetry.agent._vendor.google.protobuf.internal import decoder # pylint: disable=g-import-not-at-top + from opentelemetry.agent._vendor.google.protobuf.internal import wire_format # pylint: disable=g-import-not-at-top + + class UnknownField: + """A parsed unknown field.""" + + # Disallows assignment to other attributes. + __slots__ = ['_field_number', '_wire_type', '_data'] + + def __init__(self, field_number, wire_type, data): + self._field_number = field_number + self._wire_type = wire_type + self._data = data + return + + @property + def field_number(self): + return self._field_number + + @property + def wire_type(self): + return self._wire_type + + @property + def data(self): + return self._data + + class UnknownFieldSet: + """UnknownField container.""" + + # Disallows assignment to other attributes. + __slots__ = ['_values'] + + def __init__(self, msg): + + def InternalAdd(field_number, wire_type, data): + unknown_field = UnknownField(field_number, wire_type, data) + self._values.append(unknown_field) + + self._values = [] + msg_des = msg.DESCRIPTOR + # pylint: disable=protected-access + unknown_fields = msg._unknown_fields + if msg_des.has_options and msg_des.GetOptions().message_set_wire_format: + local_decoder = decoder.UnknownMessageSetItemDecoder() + for _, buffer in unknown_fields: + field_number, data = local_decoder(memoryview(buffer)) + InternalAdd(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED, data) + else: + for tag_bytes, buffer in unknown_fields: + field_number, wire_type = decoder.DecodeTag(tag_bytes) + if field_number == 0: + raise RuntimeError('Field number 0 is illegal.') + data, _ = decoder._DecodeUnknownField( + memoryview(buffer), 0, len(buffer), field_number, wire_type + ) + InternalAdd(field_number, wire_type, data) + + def __getitem__(self, index): + size = len(self._values) + if index < 0: + index += size + if index < 0 or index >= size: + raise IndexError('index %d out of range'.index) + + return self._values[index] + + def __len__(self): + return len(self._values) + + def __iter__(self): + return iter(self._values) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/util/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/util/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py new file mode 100644 index 00000000000..d6470414b00 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/protobuf/wrappers.proto +# Protobuf Python Version: 7.36.2 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 7, + 36, + 2, + '', + 'google/protobuf/wrappers.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/wrappers.proto\x12\x0fgoogle.protobuf\"#\n\x0b\x44oubleValue\x12\x14\n\x05value\x18\x01 \x01(\x01R\x05value\"\"\n\nFloatValue\x12\x14\n\x05value\x18\x01 \x01(\x02R\x05value\"\"\n\nInt64Value\x12\x14\n\x05value\x18\x01 \x01(\x03R\x05value\"#\n\x0bUInt64Value\x12\x14\n\x05value\x18\x01 \x01(\x04R\x05value\"\"\n\nInt32Value\x12\x14\n\x05value\x18\x01 \x01(\x05R\x05value\"#\n\x0bUInt32Value\x12\x14\n\x05value\x18\x01 \x01(\rR\x05value\"!\n\tBoolValue\x12\x14\n\x05value\x18\x01 \x01(\x08R\x05value\"#\n\x0bStringValue\x12\x14\n\x05value\x18\x01 \x01(\tR\x05value\"\"\n\nBytesValue\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05valueB\x83\x01\n\x13\x63om.google.protobufB\rWrappersProtoP\x01Z1google.golang.org/protobuf/types/known/wrapperspb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.wrappers_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\rWrappersProtoP\001Z1google.golang.org/protobuf/types/known/wrapperspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' + _globals['_DOUBLEVALUE']._serialized_start=51 + _globals['_DOUBLEVALUE']._serialized_end=86 + _globals['_FLOATVALUE']._serialized_start=88 + _globals['_FLOATVALUE']._serialized_end=122 + _globals['_INT64VALUE']._serialized_start=124 + _globals['_INT64VALUE']._serialized_end=158 + _globals['_UINT64VALUE']._serialized_start=160 + _globals['_UINT64VALUE']._serialized_end=195 + _globals['_INT32VALUE']._serialized_start=197 + _globals['_INT32VALUE']._serialized_end=231 + _globals['_UINT32VALUE']._serialized_start=233 + _globals['_UINT32VALUE']._serialized_end=268 + _globals['_BOOLVALUE']._serialized_start=270 + _globals['_BOOLVALUE']._serialized_end=303 + _globals['_STRINGVALUE']._serialized_start=305 + _globals['_STRINGVALUE']._serialized_end=340 + _globals['_BYTESVALUE']._serialized_start=342 + _globals['_BYTESVALUE']._serialized_end=376 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto new file mode 100644 index 00000000000..46b5d75a78a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto @@ -0,0 +1,186 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +option go_package = "google.golang.org/genproto/googleapis/rpc/code;code"; +option java_multiple_files = true; +option java_outer_classname = "CodeProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + +// The canonical error codes for gRPC APIs. +// +// +// Sometimes multiple error codes may apply. Services should return +// the most specific error code that applies. For example, prefer +// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply. +// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`. +enum Code { + // Not an error; returned on success. + // + // HTTP Mapping: 200 OK + OK = 0; + + // The operation was cancelled, typically by the caller. + // + // HTTP Mapping: 499 Client Closed Request + CANCELLED = 1; + + // Unknown error. For example, this error may be returned when + // a `Status` value received from another address space belongs to + // an error space that is not known in this address space. Also + // errors raised by APIs that do not return enough error information + // may be converted to this error. + // + // HTTP Mapping: 500 Internal Server Error + UNKNOWN = 2; + + // The client specified an invalid argument. Note that this differs + // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments + // that are problematic regardless of the state of the system + // (e.g., a malformed file name). + // + // HTTP Mapping: 400 Bad Request + INVALID_ARGUMENT = 3; + + // The deadline expired before the operation could complete. For operations + // that change the state of the system, this error may be returned + // even if the operation has completed successfully. For example, a + // successful response from a server could have been delayed long + // enough for the deadline to expire. + // + // HTTP Mapping: 504 Gateway Timeout + DEADLINE_EXCEEDED = 4; + + // Some requested entity (e.g., file or directory) was not found. + // + // Note to server developers: if a request is denied for an entire class + // of users, such as gradual feature rollout or undocumented allowlist, + // `NOT_FOUND` may be used. If a request is denied for some users within + // a class of users, such as user-based access control, `PERMISSION_DENIED` + // must be used. + // + // HTTP Mapping: 404 Not Found + NOT_FOUND = 5; + + // The entity that a client attempted to create (e.g., file or directory) + // already exists. + // + // HTTP Mapping: 409 Conflict + ALREADY_EXISTS = 6; + + // The caller does not have permission to execute the specified + // operation. `PERMISSION_DENIED` must not be used for rejections + // caused by exhausting some resource (use `RESOURCE_EXHAUSTED` + // instead for those errors). `PERMISSION_DENIED` must not be + // used if the caller can not be identified (use `UNAUTHENTICATED` + // instead for those errors). This error code does not imply the + // request is valid or the requested entity exists or satisfies + // other pre-conditions. + // + // HTTP Mapping: 403 Forbidden + PERMISSION_DENIED = 7; + + // The request does not have valid authentication credentials for the + // operation. + // + // HTTP Mapping: 401 Unauthorized + UNAUTHENTICATED = 16; + + // Some resource has been exhausted, perhaps a per-user quota, or + // perhaps the entire file system is out of space. + // + // HTTP Mapping: 429 Too Many Requests + RESOURCE_EXHAUSTED = 8; + + // The operation was rejected because the system is not in a state + // required for the operation's execution. For example, the directory + // to be deleted is non-empty, an rmdir operation is applied to + // a non-directory, etc. + // + // Service implementors can use the following guidelines to decide + // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: + // (a) Use `UNAVAILABLE` if the client can retry just the failing call. + // (b) Use `ABORTED` if the client should retry at a higher level. For + // example, when a client-specified test-and-set fails, indicating the + // client should restart a read-modify-write sequence. + // (c) Use `FAILED_PRECONDITION` if the client should not retry until + // the system state has been explicitly fixed. For example, if an "rmdir" + // fails because the directory is non-empty, `FAILED_PRECONDITION` + // should be returned since the client should not retry unless + // the files are deleted from the directory. + // + // HTTP Mapping: 400 Bad Request + FAILED_PRECONDITION = 9; + + // The operation was aborted, typically due to a concurrency issue such as + // a sequencer check failure or transaction abort. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 409 Conflict + ABORTED = 10; + + // The operation was attempted past the valid range. E.g., seeking or + // reading past end-of-file. + // + // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may + // be fixed if the system state changes. For example, a 32-bit file + // system will generate `INVALID_ARGUMENT` if asked to read at an + // offset that is not in the range [0,2^32-1], but it will generate + // `OUT_OF_RANGE` if asked to read from an offset past the current + // file size. + // + // There is a fair bit of overlap between `FAILED_PRECONDITION` and + // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific + // error) when it applies so that callers who are iterating through + // a space can easily look for an `OUT_OF_RANGE` error to detect when + // they are done. + // + // HTTP Mapping: 400 Bad Request + OUT_OF_RANGE = 11; + + // The operation is not implemented or is not supported/enabled in this + // service. + // + // HTTP Mapping: 501 Not Implemented + UNIMPLEMENTED = 12; + + // Internal errors. This means that some invariants expected by the + // underlying system have been broken. This error code is reserved + // for serious errors. + // + // HTTP Mapping: 500 Internal Server Error + INTERNAL = 13; + + // The service is currently unavailable. This is most likely a + // transient condition, which can be corrected by retrying with + // a backoff. Note that it is not always safe to retry + // non-idempotent operations. + // + // See the guidelines above for deciding between `FAILED_PRECONDITION`, + // `ABORTED`, and `UNAVAILABLE`. + // + // HTTP Mapping: 503 Service Unavailable + UNAVAILABLE = 14; + + // Unrecoverable data loss or corruption. + // + // HTTP Mapping: 500 Internal Server Error + DATA_LOSS = 15; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py new file mode 100644 index 00000000000..c79900e7978 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/rpc/code.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/code.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n\x15google/rpc/code.proto\x12\ngoogle.rpc*\xb7\x02\n\x04\x43ode\x12\x06\n\x02OK\x10\x00\x12\r\n\tCANCELLED\x10\x01\x12\x0b\n\x07UNKNOWN\x10\x02\x12\x14\n\x10INVALID_ARGUMENT\x10\x03\x12\x15\n\x11\x44\x45\x41\x44LINE_EXCEEDED\x10\x04\x12\r\n\tNOT_FOUND\x10\x05\x12\x12\n\x0e\x41LREADY_EXISTS\x10\x06\x12\x15\n\x11PERMISSION_DENIED\x10\x07\x12\x13\n\x0fUNAUTHENTICATED\x10\x10\x12\x16\n\x12RESOURCE_EXHAUSTED\x10\x08\x12\x17\n\x13\x46\x41ILED_PRECONDITION\x10\t\x12\x0b\n\x07\x41\x42ORTED\x10\n\x12\x10\n\x0cOUT_OF_RANGE\x10\x0b\x12\x11\n\rUNIMPLEMENTED\x10\x0c\x12\x0c\n\x08INTERNAL\x10\r\x12\x0f\n\x0bUNAVAILABLE\x10\x0e\x12\r\n\tDATA_LOSS\x10\x0f\x42X\n\x0e\x63om.google.rpcB\tCodeProtoP\x01Z3google.golang.org/genproto/googleapis/rpc/code;code\xa2\x02\x03RPCb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.code_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.rpcB\tCodeProtoP\001Z3google.golang.org/genproto/googleapis/rpc/code;code\242\002\003RPC" + _globals["_CODE"]._serialized_start = 38 + _globals["_CODE"]._serialized_end = 349 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi new file mode 100644 index 00000000000..17acb5af980 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi @@ -0,0 +1,58 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class Code(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + OK: _ClassVar[Code] + CANCELLED: _ClassVar[Code] + UNKNOWN: _ClassVar[Code] + INVALID_ARGUMENT: _ClassVar[Code] + DEADLINE_EXCEEDED: _ClassVar[Code] + NOT_FOUND: _ClassVar[Code] + ALREADY_EXISTS: _ClassVar[Code] + PERMISSION_DENIED: _ClassVar[Code] + UNAUTHENTICATED: _ClassVar[Code] + RESOURCE_EXHAUSTED: _ClassVar[Code] + FAILED_PRECONDITION: _ClassVar[Code] + ABORTED: _ClassVar[Code] + OUT_OF_RANGE: _ClassVar[Code] + UNIMPLEMENTED: _ClassVar[Code] + INTERNAL: _ClassVar[Code] + UNAVAILABLE: _ClassVar[Code] + DATA_LOSS: _ClassVar[Code] + +OK: Code +CANCELLED: Code +UNKNOWN: Code +INVALID_ARGUMENT: Code +DEADLINE_EXCEEDED: Code +NOT_FOUND: Code +ALREADY_EXISTS: Code +PERMISSION_DENIED: Code +UNAUTHENTICATED: Code +RESOURCE_EXHAUSTED: Code +FAILED_PRECONDITION: Code +ABORTED: Code +OUT_OF_RANGE: Code +UNIMPLEMENTED: Code +INTERNAL: Code +UNAVAILABLE: Code +DATA_LOSS: Code diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto new file mode 100644 index 00000000000..55f95f844e7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto @@ -0,0 +1,350 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc.context; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "google.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_context"; +option java_multiple_files = true; +option java_outer_classname = "AttributeContextProto"; +option java_package = "com.google.rpc.context"; + +// This message defines the standard attribute vocabulary for Google APIs. +// +// An attribute is a piece of metadata that describes an activity on a network +// service. For example, the size of an HTTP request, or the status code of +// an HTTP response. +// +// Each attribute has a type and a name, which is logically defined as +// a proto message field in `AttributeContext`. The field type becomes the +// attribute type, and the field path becomes the attribute name. For example, +// the attribute `source.ip` maps to field `AttributeContext.source.ip`. +// +// This message definition is guaranteed not to have any wire breaking change. +// So you can use it directly for passing attributes across different systems. +// +// NOTE: Different system may generate different subset of attributes. Please +// verify the system specification before relying on an attribute generated +// a system. +message AttributeContext { + // This message defines attributes for a node that handles a network request. + // The node can be either a service or an application that sends, forwards, + // or receives the request. Service peers should fill in + // `principal` and `labels` as appropriate. + message Peer { + // The IP address of the peer. + string ip = 1; + + // The network port of the peer. + int64 port = 2; + + // The labels associated with the peer. + map labels = 6; + + // The identity of this peer. Similar to `Request.auth.principal`, but + // relative to the peer instead of the request. For example, the + // identity associated with a load balancer that forwarded the request. + string principal = 7; + + // The CLDR country/region code associated with the above IP address. + // If the IP address is private, the `region_code` should reflect the + // physical location where this peer is running. + string region_code = 8; + } + + // This message defines attributes associated with API operations, such as + // a network API request. The terminology is based on the conventions used + // by Google APIs, Istio, and OpenAPI. + message Api { + // The API service name. It is a logical identifier for a networked API, + // such as "pubsub.googleapis.com". The naming syntax depends on the + // API management system being used for handling the request. + string service = 1; + + // The API operation name. For gRPC requests, it is the fully qualified API + // method name, such as "google.pubsub.v1.Publisher.Publish". For OpenAPI + // requests, it is the `operationId`, such as "getPet". + string operation = 2; + + // The API protocol used for sending the request, such as "http", "https", + // "grpc", or "internal". + string protocol = 3; + + // The API version associated with the API operation above, such as "v1" or + // "v1alpha1". + string version = 4; + } + + // This message defines request authentication attributes. Terminology is + // based on the JSON Web Token (JWT) standard, but the terms also + // correlate to concepts in other standards. + message Auth { + // The authenticated principal. Reflects the issuer (`iss`) and subject + // (`sub`) claims within a JWT. The issuer and subject should be `/` + // delimited, with `/` percent-encoded within the subject fragment. For + // Google accounts, the principal format is: + // "https://accounts.google.com/{id}" + string principal = 1; + + // The intended audience(s) for this authentication information. Reflects + // the audience (`aud`) claim within a JWT. The audience + // value(s) depends on the `issuer`, but typically include one or more of + // the following pieces of information: + // + // * The services intended to receive the credential. For example, + // ["https://pubsub.googleapis.com/", "https://storage.googleapis.com/"]. + // * A set of service-based scopes. For example, + // ["https://www.googleapis.com/auth/cloud-platform"]. + // * The client id of an app, such as the Firebase project id for JWTs + // from Firebase Auth. + // + // Consult the documentation for the credential issuer to determine the + // information provided. + repeated string audiences = 2; + + // The authorized presenter of the credential. Reflects the optional + // Authorized Presenter (`azp`) claim within a JWT or the + // OAuth client id. For example, a Google Cloud Platform client id looks + // as follows: "123456789012.apps.googleusercontent.com". + string presenter = 3; + + // Structured claims presented with the credential. JWTs include + // `{key: value}` pairs for standard and private claims. The following + // is a subset of the standard required and optional claims that would + // typically be presented for a Google-based JWT: + // + // {'iss': 'accounts.google.com', + // 'sub': '113289723416554971153', + // 'aud': ['123456789012', 'pubsub.googleapis.com'], + // 'azp': '123456789012.apps.googleusercontent.com', + // 'email': 'jsmith@example.com', + // 'iat': 1353601026, + // 'exp': 1353604926} + // + // SAML assertions are similarly specified, but with an identity provider + // dependent structure. + google.protobuf.Struct claims = 4; + + // A list of access level resource names that allow resources to be + // accessed by authenticated requester. It is part of Secure GCP processing + // for the incoming request. An access level string has the format: + // "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/{short_name}" + // + // Example: + // "//accesscontextmanager.googleapis.com/accessPolicies/MY_POLICY_ID/accessLevels/MY_LEVEL" + repeated string access_levels = 5; + } + + // This message defines attributes for an HTTP request. If the actual + // request is not an HTTP request, the runtime system should try to map + // the actual request to an equivalent HTTP request. + message Request { + // The unique ID for a request, which can be propagated to downstream + // systems. The ID should have low probability of collision + // within a single day for a specific service. + string id = 1; + + // The HTTP request method, such as `GET`, `POST`. + string method = 2; + + // The HTTP request headers. If multiple headers share the same key, they + // must be merged according to the HTTP spec. All header keys must be + // lowercased, because HTTP header keys are case-insensitive. + map headers = 3; + + // The HTTP URL path, excluding the query parameters. + string path = 4; + + // The HTTP request `Host` header value. + string host = 5; + + // The HTTP URL scheme, such as `http` and `https`. + string scheme = 6; + + // The HTTP URL query in the format of `name1=value1&name2=value2`, as it + // appears in the first line of the HTTP request. No decoding is performed. + string query = 7; + + // The timestamp when the `destination` service receives the last byte of + // the request. + google.protobuf.Timestamp time = 9; + + // The HTTP request size in bytes. If unknown, it must be -1. + int64 size = 10; + + // The network protocol used with the request, such as "http/1.1", + // "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See + // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids + // for details. + string protocol = 11; + + // A special parameter for request reason. It is used by security systems + // to associate auditing information with a request. + string reason = 12; + + // The request authentication. May be absent for unauthenticated requests. + // Derived from the HTTP request `Authorization` header or equivalent. + Auth auth = 13; + + // The values from Origin header from the HTTP request, such as + // "https://console.cloud.google.com". Modern browsers can only have one + // origin. Special browsers and/or HTTP clients may require multiple + // origins. + string origin = 14; + } + + // This message defines attributes for a typical network response. It + // generally models semantics of an HTTP response. + message Response { + // The HTTP response status code, such as `200` and `404`. + int64 code = 1; + + // The HTTP response size in bytes. If unknown, it must be -1. + int64 size = 2; + + // The HTTP response headers. If multiple headers share the same key, they + // must be merged according to HTTP spec. All header keys must be + // lowercased, because HTTP header keys are case-insensitive. + map headers = 3; + + // The timestamp when the `destination` service sends the last byte of + // the response. + google.protobuf.Timestamp time = 4; + + // The amount of time it takes the backend service to fully respond to a + // request. Measured from when the destination service starts to send the + // request to the backend until when the destination service receives the + // complete response from the backend. + google.protobuf.Duration backend_latency = 5; + } + + // This message defines core attributes for a resource. A resource is an + // addressable (named) entity provided by the destination service. For + // example, a file stored on a network storage service. + message Resource { + // The name of the service that this resource belongs to, such as + // `pubsub.googleapis.com`. The service may be different from the DNS + // hostname that actually serves the request. + string service = 1; + + // The stable identifier (name) of a resource on the `service`. A resource + // can be logically identified as "//{resource.service}/{resource.name}". + // The differences between a resource name and a URI are: + // + // * Resource name is a logical identifier, independent of network + // protocol and API version. For example, + // `//pubsub.googleapis.com/projects/123/topics/news-feed`. + // * URI often includes protocol and version information, so it can + // be used directly by applications. For example, + // `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`. + // + // See https://cloud.google.com/apis/design/resource_names for details. + string name = 2; + + // The type of the resource. The syntax is platform-specific because + // different platforms define their resources differently. + // + // For Google APIs, the type format must be "{service}/{kind}", such as + // "pubsub.googleapis.com/Topic". + string type = 3; + + // The labels or tags on the resource, such as AWS resource tags and + // Kubernetes resource labels. + map labels = 4; + + // The unique identifier of the resource. UID is unique in the time + // and space for this resource within the scope of the service. It is + // typically generated by the server on successful creation of a resource + // and must not be changed. UID is used to uniquely identify resources + // with resource name reuses. This should be a UUID4. + string uid = 5; + + // Annotations is an unstructured key-value map stored with a resource that + // may be set by external tools to store and retrieve arbitrary metadata. + // They are not queryable and should be preserved when modifying objects. + // + // More info: + // https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + map annotations = 6; + + // Mutable. The display name set by clients. Must be <= 63 characters. + string display_name = 7; + + // Output only. The timestamp when the resource was created. This may + // be either the time creation was initiated or when it was completed. + google.protobuf.Timestamp create_time = 8; + + // Output only. The timestamp when the resource was last updated. Any + // change to the resource made by users must refresh this value. + // Changes to a resource made by the service should refresh this value. + google.protobuf.Timestamp update_time = 9; + + // Output only. The timestamp when the resource was deleted. + // If the resource is not deleted, this must be empty. + google.protobuf.Timestamp delete_time = 10; + + // Output only. An opaque value that uniquely identifies a version or + // generation of a resource. It can be used to confirm that the client + // and server agree on the ordering of a resource being written. + string etag = 11; + + // Immutable. The location of the resource. The location encoding is + // specific to the service provider, and new encoding may be introduced + // as the service evolves. + // + // For Google Cloud products, the encoding is what is used by Google Cloud + // APIs, such as `us-east1`, `aws-us-east-1`, and `azure-eastus2`. The + // semantics of `location` is identical to the + // `cloud.googleapis.com/location` label used by some Google Cloud APIs. + string location = 12; + } + + // The origin of a network activity. In a multi hop network activity, + // the origin represents the sender of the first hop. For the first hop, + // the `source` and the `origin` must have the same content. + Peer origin = 7; + + // The source of a network activity, such as starting a TCP connection. + // In a multi hop network activity, the source represents the sender of the + // last hop. + Peer source = 1; + + // The destination of a network activity, such as accepting a TCP connection. + // In a multi hop network activity, the destination represents the receiver of + // the last hop. + Peer destination = 2; + + // Represents a network request, such as an HTTP request. + Request request = 3; + + // Represents a network response, such as an HTTP response. + Response response = 4; + + // Represents a target resource that is involved with a network activity. + // If multiple resources are involved with an activity, this must be the + // primary one. + Resource resource = 5; + + // Represents an API operation that is involved to a network activity. + Api api = 6; + + // Supports extensions for advanced use cases, such as logs and metrics. + repeated google.protobuf.Any extensions = 8; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py new file mode 100644 index 00000000000..8fe0b8631d7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/rpc/context/attribute_context.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + "", + "google/rpc/context/attribute_context.proto", +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 +from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 +from opentelemetry.agent._vendor.google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 +from opentelemetry.agent._vendor.google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n*google/rpc/context/attribute_context.proto\x12\x12google.rpc.context\x1a\x19google/protobuf/any.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x93\x10\n\x10\x41ttributeContext\x12\x39\n\x06origin\x18\x07 \x01(\x0b\x32).google.rpc.context.AttributeContext.Peer\x12\x39\n\x06source\x18\x01 \x01(\x0b\x32).google.rpc.context.AttributeContext.Peer\x12>\n\x0b\x64\x65stination\x18\x02 \x01(\x0b\x32).google.rpc.context.AttributeContext.Peer\x12=\n\x07request\x18\x03 \x01(\x0b\x32,.google.rpc.context.AttributeContext.Request\x12?\n\x08response\x18\x04 \x01(\x0b\x32-.google.rpc.context.AttributeContext.Response\x12?\n\x08resource\x18\x05 \x01(\x0b\x32-.google.rpc.context.AttributeContext.Resource\x12\x35\n\x03\x61pi\x18\x06 \x01(\x0b\x32(.google.rpc.context.AttributeContext.Api\x12(\n\nextensions\x18\x08 \x03(\x0b\x32\x14.google.protobuf.Any\x1a\xbe\x01\n\x04Peer\x12\n\n\x02ip\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x03\x12\x45\n\x06labels\x18\x06 \x03(\x0b\x32\x35.google.rpc.context.AttributeContext.Peer.LabelsEntry\x12\x11\n\tprincipal\x18\x07 \x01(\t\x12\x13\n\x0bregion_code\x18\x08 \x01(\t\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aL\n\x03\x41pi\x12\x0f\n\x07service\x18\x01 \x01(\t\x12\x11\n\toperation\x18\x02 \x01(\t\x12\x10\n\x08protocol\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x1a\x7f\n\x04\x41uth\x12\x11\n\tprincipal\x18\x01 \x01(\t\x12\x11\n\taudiences\x18\x02 \x03(\t\x12\x11\n\tpresenter\x18\x03 \x01(\t\x12'\n\x06\x63laims\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x15\n\raccess_levels\x18\x05 \x03(\t\x1a\xff\x02\n\x07Request\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\x12J\n\x07headers\x18\x03 \x03(\x0b\x32\x39.google.rpc.context.AttributeContext.Request.HeadersEntry\x12\x0c\n\x04path\x18\x04 \x01(\t\x12\x0c\n\x04host\x18\x05 \x01(\t\x12\x0e\n\x06scheme\x18\x06 \x01(\t\x12\r\n\x05query\x18\x07 \x01(\t\x12(\n\x04time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04size\x18\n \x01(\x03\x12\x10\n\x08protocol\x18\x0b \x01(\t\x12\x0e\n\x06reason\x18\x0c \x01(\t\x12\x37\n\x04\x61uth\x18\r \x01(\x0b\x32).google.rpc.context.AttributeContext.Auth\x12\x0e\n\x06origin\x18\x0e \x01(\t\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x81\x02\n\x08Response\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x03\x12\x0c\n\x04size\x18\x02 \x01(\x03\x12K\n\x07headers\x18\x03 \x03(\x0b\x32:.google.rpc.context.AttributeContext.Response.HeadersEntry\x12(\n\x04time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0f\x62\x61\x63kend_latency\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x90\x04\n\x08Resource\x12\x0f\n\x07service\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04type\x18\x03 \x01(\t\x12I\n\x06labels\x18\x04 \x03(\x0b\x32\x39.google.rpc.context.AttributeContext.Resource.LabelsEntry\x12\x0b\n\x03uid\x18\x05 \x01(\t\x12S\n\x0b\x61nnotations\x18\x06 \x03(\x0b\x32>.google.rpc.context.AttributeContext.Resource.AnnotationsEntry\x12\x14\n\x0c\x64isplay_name\x18\x07 \x01(\t\x12/\n\x0b\x63reate_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bupdate_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0b\x64\x65lete_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04\x65tag\x18\x0b \x01(\t\x12\x10\n\x08location\x18\x0c \x01(\t\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x32\n\x10\x41nnotationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x88\x01\n\x16\x63om.google.rpc.contextB\x15\x41ttributeContextProtoP\x01ZUgoogle.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_contextb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.context.attribute_context_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\026com.google.rpc.contextB\025AttributeContextProtoP\001ZUgoogle.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_context" + _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._loaded_options = None + _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._serialized_options = b"8\001" + _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._loaded_options = None + _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._serialized_options = b"8\001" + _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._loaded_options = None + _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._serialized_options = b"8\001" + _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._loaded_options = None + _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._serialized_options = b"8\001" + _globals["_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY"]._loaded_options = None + _globals[ + "_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY" + ]._serialized_options = b"8\001" + _globals["_ATTRIBUTECONTEXT"]._serialized_start = 189 + _globals["_ATTRIBUTECONTEXT"]._serialized_end = 2256 + _globals["_ATTRIBUTECONTEXT_PEER"]._serialized_start = 682 + _globals["_ATTRIBUTECONTEXT_PEER"]._serialized_end = 872 + _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._serialized_start = 827 + _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._serialized_end = 872 + _globals["_ATTRIBUTECONTEXT_API"]._serialized_start = 874 + _globals["_ATTRIBUTECONTEXT_API"]._serialized_end = 950 + _globals["_ATTRIBUTECONTEXT_AUTH"]._serialized_start = 952 + _globals["_ATTRIBUTECONTEXT_AUTH"]._serialized_end = 1079 + _globals["_ATTRIBUTECONTEXT_REQUEST"]._serialized_start = 1082 + _globals["_ATTRIBUTECONTEXT_REQUEST"]._serialized_end = 1465 + _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._serialized_start = 1419 + _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._serialized_end = 1465 + _globals["_ATTRIBUTECONTEXT_RESPONSE"]._serialized_start = 1468 + _globals["_ATTRIBUTECONTEXT_RESPONSE"]._serialized_end = 1725 + _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._serialized_start = 1419 + _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._serialized_end = 1465 + _globals["_ATTRIBUTECONTEXT_RESOURCE"]._serialized_start = 1728 + _globals["_ATTRIBUTECONTEXT_RESOURCE"]._serialized_end = 2256 + _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._serialized_start = 827 + _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._serialized_end = 872 + _globals["_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY"]._serialized_start = 2206 + _globals["_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY"]._serialized_end = 2256 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi new file mode 100644 index 00000000000..feab1f6f623 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi @@ -0,0 +1,326 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import duration_pb2 as _duration_pb2 +from google.protobuf import message as _message +from google.protobuf import struct_pb2 as _struct_pb2 +from google.protobuf import timestamp_pb2 as _timestamp_pb2 +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class AttributeContext(_message.Message): + __slots__ = ( + "origin", + "source", + "destination", + "request", + "response", + "resource", + "api", + "extensions", + ) + class Peer(_message.Message): + __slots__ = ("ip", "port", "labels", "principal", "region_code") + class LabelsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + IP_FIELD_NUMBER: _ClassVar[int] + PORT_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + PRINCIPAL_FIELD_NUMBER: _ClassVar[int] + REGION_CODE_FIELD_NUMBER: _ClassVar[int] + ip: str + port: int + labels: _containers.ScalarMap[str, str] + principal: str + region_code: str + def __init__( + self, + ip: _Optional[str] = ..., + port: _Optional[int] = ..., + labels: _Optional[_Mapping[str, str]] = ..., + principal: _Optional[str] = ..., + region_code: _Optional[str] = ..., + ) -> None: ... + + class Api(_message.Message): + __slots__ = ("service", "operation", "protocol", "version") + SERVICE_FIELD_NUMBER: _ClassVar[int] + OPERATION_FIELD_NUMBER: _ClassVar[int] + PROTOCOL_FIELD_NUMBER: _ClassVar[int] + VERSION_FIELD_NUMBER: _ClassVar[int] + service: str + operation: str + protocol: str + version: str + def __init__( + self, + service: _Optional[str] = ..., + operation: _Optional[str] = ..., + protocol: _Optional[str] = ..., + version: _Optional[str] = ..., + ) -> None: ... + + class Auth(_message.Message): + __slots__ = ("principal", "audiences", "presenter", "claims", "access_levels") + PRINCIPAL_FIELD_NUMBER: _ClassVar[int] + AUDIENCES_FIELD_NUMBER: _ClassVar[int] + PRESENTER_FIELD_NUMBER: _ClassVar[int] + CLAIMS_FIELD_NUMBER: _ClassVar[int] + ACCESS_LEVELS_FIELD_NUMBER: _ClassVar[int] + principal: str + audiences: _containers.RepeatedScalarFieldContainer[str] + presenter: str + claims: _struct_pb2.Struct + access_levels: _containers.RepeatedScalarFieldContainer[str] + def __init__( + self, + principal: _Optional[str] = ..., + audiences: _Optional[_Iterable[str]] = ..., + presenter: _Optional[str] = ..., + claims: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., + access_levels: _Optional[_Iterable[str]] = ..., + ) -> None: ... + + class Request(_message.Message): + __slots__ = ( + "id", + "method", + "headers", + "path", + "host", + "scheme", + "query", + "time", + "size", + "protocol", + "reason", + "auth", + "origin", + ) + class HeadersEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + ID_FIELD_NUMBER: _ClassVar[int] + METHOD_FIELD_NUMBER: _ClassVar[int] + HEADERS_FIELD_NUMBER: _ClassVar[int] + PATH_FIELD_NUMBER: _ClassVar[int] + HOST_FIELD_NUMBER: _ClassVar[int] + SCHEME_FIELD_NUMBER: _ClassVar[int] + QUERY_FIELD_NUMBER: _ClassVar[int] + TIME_FIELD_NUMBER: _ClassVar[int] + SIZE_FIELD_NUMBER: _ClassVar[int] + PROTOCOL_FIELD_NUMBER: _ClassVar[int] + REASON_FIELD_NUMBER: _ClassVar[int] + AUTH_FIELD_NUMBER: _ClassVar[int] + ORIGIN_FIELD_NUMBER: _ClassVar[int] + id: str + method: str + headers: _containers.ScalarMap[str, str] + path: str + host: str + scheme: str + query: str + time: _timestamp_pb2.Timestamp + size: int + protocol: str + reason: str + auth: AttributeContext.Auth + origin: str + def __init__( + self, + id: _Optional[str] = ..., + method: _Optional[str] = ..., + headers: _Optional[_Mapping[str, str]] = ..., + path: _Optional[str] = ..., + host: _Optional[str] = ..., + scheme: _Optional[str] = ..., + query: _Optional[str] = ..., + time: _Optional[ + _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] + ] = ..., + size: _Optional[int] = ..., + protocol: _Optional[str] = ..., + reason: _Optional[str] = ..., + auth: _Optional[_Union[AttributeContext.Auth, _Mapping]] = ..., + origin: _Optional[str] = ..., + ) -> None: ... + + class Response(_message.Message): + __slots__ = ("code", "size", "headers", "time", "backend_latency") + class HeadersEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + CODE_FIELD_NUMBER: _ClassVar[int] + SIZE_FIELD_NUMBER: _ClassVar[int] + HEADERS_FIELD_NUMBER: _ClassVar[int] + TIME_FIELD_NUMBER: _ClassVar[int] + BACKEND_LATENCY_FIELD_NUMBER: _ClassVar[int] + code: int + size: int + headers: _containers.ScalarMap[str, str] + time: _timestamp_pb2.Timestamp + backend_latency: _duration_pb2.Duration + def __init__( + self, + code: _Optional[int] = ..., + size: _Optional[int] = ..., + headers: _Optional[_Mapping[str, str]] = ..., + time: _Optional[ + _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] + ] = ..., + backend_latency: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + ) -> None: ... + + class Resource(_message.Message): + __slots__ = ( + "service", + "name", + "type", + "labels", + "uid", + "annotations", + "display_name", + "create_time", + "update_time", + "delete_time", + "etag", + "location", + ) + class LabelsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + class AnnotationsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + SERVICE_FIELD_NUMBER: _ClassVar[int] + NAME_FIELD_NUMBER: _ClassVar[int] + TYPE_FIELD_NUMBER: _ClassVar[int] + LABELS_FIELD_NUMBER: _ClassVar[int] + UID_FIELD_NUMBER: _ClassVar[int] + ANNOTATIONS_FIELD_NUMBER: _ClassVar[int] + DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] + CREATE_TIME_FIELD_NUMBER: _ClassVar[int] + UPDATE_TIME_FIELD_NUMBER: _ClassVar[int] + DELETE_TIME_FIELD_NUMBER: _ClassVar[int] + ETAG_FIELD_NUMBER: _ClassVar[int] + LOCATION_FIELD_NUMBER: _ClassVar[int] + service: str + name: str + type: str + labels: _containers.ScalarMap[str, str] + uid: str + annotations: _containers.ScalarMap[str, str] + display_name: str + create_time: _timestamp_pb2.Timestamp + update_time: _timestamp_pb2.Timestamp + delete_time: _timestamp_pb2.Timestamp + etag: str + location: str + def __init__( + self, + service: _Optional[str] = ..., + name: _Optional[str] = ..., + type: _Optional[str] = ..., + labels: _Optional[_Mapping[str, str]] = ..., + uid: _Optional[str] = ..., + annotations: _Optional[_Mapping[str, str]] = ..., + display_name: _Optional[str] = ..., + create_time: _Optional[ + _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] + ] = ..., + update_time: _Optional[ + _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] + ] = ..., + delete_time: _Optional[ + _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] + ] = ..., + etag: _Optional[str] = ..., + location: _Optional[str] = ..., + ) -> None: ... + + ORIGIN_FIELD_NUMBER: _ClassVar[int] + SOURCE_FIELD_NUMBER: _ClassVar[int] + DESTINATION_FIELD_NUMBER: _ClassVar[int] + REQUEST_FIELD_NUMBER: _ClassVar[int] + RESPONSE_FIELD_NUMBER: _ClassVar[int] + RESOURCE_FIELD_NUMBER: _ClassVar[int] + API_FIELD_NUMBER: _ClassVar[int] + EXTENSIONS_FIELD_NUMBER: _ClassVar[int] + origin: AttributeContext.Peer + source: AttributeContext.Peer + destination: AttributeContext.Peer + request: AttributeContext.Request + response: AttributeContext.Response + resource: AttributeContext.Resource + api: AttributeContext.Api + extensions: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] + def __init__( + self, + origin: _Optional[_Union[AttributeContext.Peer, _Mapping]] = ..., + source: _Optional[_Union[AttributeContext.Peer, _Mapping]] = ..., + destination: _Optional[_Union[AttributeContext.Peer, _Mapping]] = ..., + request: _Optional[_Union[AttributeContext.Request, _Mapping]] = ..., + response: _Optional[_Union[AttributeContext.Response, _Mapping]] = ..., + resource: _Optional[_Union[AttributeContext.Resource, _Mapping]] = ..., + api: _Optional[_Union[AttributeContext.Api, _Mapping]] = ..., + extensions: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto new file mode 100644 index 00000000000..03c5ab9a508 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto @@ -0,0 +1,48 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc.context; + +import "google/protobuf/struct.proto"; + +option go_package = "google.golang.org/genproto/googleapis/rpc/context;context"; +option java_multiple_files = true; +option java_outer_classname = "AuditContextProto"; +option java_package = "com.google.rpc.context"; + +// `AuditContext` provides information that is needed for audit logging. +message AuditContext { + // Serialized audit log. + bytes audit_log = 1; + + // An API request message that is scrubbed based on the method annotation. + // This field should only be filled if audit_log field is present. + // Service Control will use this to assemble a complete log for Cloud Audit + // Logs and Google internal audit logs. + google.protobuf.Struct scrubbed_request = 2; + + // An API response message that is scrubbed based on the method annotation. + // This field should only be filled if audit_log field is present. + // Service Control will use this to assemble a complete log for Cloud Audit + // Logs and Google internal audit logs. + google.protobuf.Struct scrubbed_response = 3; + + // Number of scrubbed response items. + int32 scrubbed_response_item_count = 4; + + // Audit resource name which is scrubbed. + string target_resource = 5; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py new file mode 100644 index 00000000000..41cacce0ac6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/rpc/context/audit_context.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 5, + "", + "google/rpc/context/audit_context.proto", +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n&google/rpc/context/audit_context.proto\x12\x12google.rpc.context\x1a\x1cgoogle/protobuf/struct.proto"\xc7\x01\n\x0c\x41uditContext\x12\x11\n\taudit_log\x18\x01 \x01(\x0c\x12\x31\n\x10scrubbed_request\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x32\n\x11scrubbed_response\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12$\n\x1cscrubbed_response_item_count\x18\x04 \x01(\x05\x12\x17\n\x0ftarget_resource\x18\x05 \x01(\tBh\n\x16\x63om.google.rpc.contextB\x11\x41uditContextProtoP\x01Z9google.golang.org/genproto/googleapis/rpc/context;contextb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.context.audit_context_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\026com.google.rpc.contextB\021AuditContextProtoP\001Z9google.golang.org/genproto/googleapis/rpc/context;context" + _globals["_AUDITCONTEXT"]._serialized_start = 93 + _globals["_AUDITCONTEXT"]._serialized_end = 292 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi new file mode 100644 index 00000000000..720be02d377 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi @@ -0,0 +1,51 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import struct_pb2 as _struct_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class AuditContext(_message.Message): + __slots__ = ( + "audit_log", + "scrubbed_request", + "scrubbed_response", + "scrubbed_response_item_count", + "target_resource", + ) + AUDIT_LOG_FIELD_NUMBER: _ClassVar[int] + SCRUBBED_REQUEST_FIELD_NUMBER: _ClassVar[int] + SCRUBBED_RESPONSE_FIELD_NUMBER: _ClassVar[int] + SCRUBBED_RESPONSE_ITEM_COUNT_FIELD_NUMBER: _ClassVar[int] + TARGET_RESOURCE_FIELD_NUMBER: _ClassVar[int] + audit_log: bytes + scrubbed_request: _struct_pb2.Struct + scrubbed_response: _struct_pb2.Struct + scrubbed_response_item_count: int + target_resource: str + def __init__( + self, + audit_log: _Optional[bytes] = ..., + scrubbed_request: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., + scrubbed_response: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., + scrubbed_response_item_count: _Optional[int] = ..., + target_resource: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto new file mode 100644 index 00000000000..43b7d04d2ba --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto @@ -0,0 +1,363 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +import "google/protobuf/duration.proto"; + +option go_package = "google.golang.org/genproto/googleapis/rpc/errdetails;errdetails"; +option java_multiple_files = true; +option java_outer_classname = "ErrorDetailsProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + +// Describes the cause of the error with structured details. +// +// Example of an error when contacting the "pubsub.googleapis.com" API when it +// is not enabled: +// +// { "reason": "API_DISABLED" +// "domain": "googleapis.com" +// "metadata": { +// "resource": "projects/123", +// "service": "pubsub.googleapis.com" +// } +// } +// +// This response indicates that the pubsub.googleapis.com API is not enabled. +// +// Example of an error that is returned when attempting to create a Spanner +// instance in a region that is out of stock: +// +// { "reason": "STOCKOUT" +// "domain": "spanner.googleapis.com", +// "metadata": { +// "availableRegions": "us-central1,us-east2" +// } +// } +message ErrorInfo { + // The reason of the error. This is a constant value that identifies the + // proximate cause of the error. Error reasons are unique within a particular + // domain of errors. This should be at most 63 characters and match a + // regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, which represents + // UPPER_SNAKE_CASE. + string reason = 1; + + // The logical grouping to which the "reason" belongs. The error domain + // is typically the registered service name of the tool or product that + // generates the error. Example: "pubsub.googleapis.com". If the error is + // generated by some common infrastructure, the error domain must be a + // globally unique value that identifies the infrastructure. For Google API + // infrastructure, the error domain is "googleapis.com". + string domain = 2; + + // Additional structured details about this error. + // + // Keys must match a regular expression of `[a-z][a-zA-Z0-9-_]+` but should + // ideally be lowerCamelCase. Also, they must be limited to 64 characters in + // length. When identifying the current value of an exceeded limit, the units + // should be contained in the key, not the value. For example, rather than + // `{"instanceLimit": "100/request"}`, should be returned as, + // `{"instanceLimitPerRequest": "100"}`, if the client exceeds the number of + // instances that can be created in a single (batch) request. + map metadata = 3; +} + +// Describes when the clients can retry a failed request. Clients could ignore +// the recommendation here or retry when this information is missing from error +// responses. +// +// It's always recommended that clients should use exponential backoff when +// retrying. +// +// Clients should wait until `retry_delay` amount of time has passed since +// receiving the error response before retrying. If retrying requests also +// fail, clients should use an exponential backoff scheme to gradually increase +// the delay between retries based on `retry_delay`, until either a maximum +// number of retries have been reached or a maximum retry delay cap has been +// reached. +message RetryInfo { + // Clients should wait at least this long between retrying the same request. + google.protobuf.Duration retry_delay = 1; +} + +// Describes additional debugging info. +message DebugInfo { + // The stack trace entries indicating where the error occurred. + repeated string stack_entries = 1; + + // Additional debugging information provided by the server. + string detail = 2; +} + +// Describes how a quota check failed. +// +// For example if a daily limit was exceeded for the calling project, +// a service could respond with a QuotaFailure detail containing the project +// id and the description of the quota limit that was exceeded. If the +// calling project hasn't enabled the service in the developer console, then +// a service could respond with the project id and set `service_disabled` +// to true. +// +// Also see RetryInfo and Help types for other details about handling a +// quota failure. +message QuotaFailure { + // A message type used to describe a single quota violation. For example, a + // daily quota or a custom quota that was exceeded. + message Violation { + // The subject on which the quota check failed. + // For example, "clientip:" or "project:". + string subject = 1; + + // A description of how the quota check failed. Clients can use this + // description to find more about the quota configuration in the service's + // public documentation, or find the relevant quota limit to adjust through + // developer console. + // + // For example: "Service disabled" or "Daily Limit for read operations + // exceeded". + string description = 2; + + // The API Service from which the `QuotaFailure.Violation` orginates. In + // some cases, Quota issues originate from an API Service other than the one + // that was called. In other words, a dependency of the called API Service + // could be the cause of the `QuotaFailure`, and this field would have the + // dependency API service name. + // + // For example, if the called API is Kubernetes Engine API + // (container.googleapis.com), and a quota violation occurs in the + // Kubernetes Engine API itself, this field would be + // "container.googleapis.com". On the other hand, if the quota violation + // occurs when the Kubernetes Engine API creates VMs in the Compute Engine + // API (compute.googleapis.com), this field would be + // "compute.googleapis.com". + string api_service = 3; + + // The metric of the violated quota. A quota metric is a named counter to + // measure usage, such as API requests or CPUs. When an activity occurs in a + // service, such as Virtual Machine allocation, one or more quota metrics + // may be affected. + // + // For example, "compute.googleapis.com/cpus_per_vm_family", + // "storage.googleapis.com/internet_egress_bandwidth". + string quota_metric = 4; + + // The id of the violated quota. Also know as "limit name", this is the + // unique identifier of a quota in the context of an API service. + // + // For example, "CPUS-PER-VM-FAMILY-per-project-region". + string quota_id = 5; + + // The dimensions of the violated quota. Every non-global quota is enforced + // on a set of dimensions. While quota metric defines what to count, the + // dimensions specify for what aspects the counter should be increased. + // + // For example, the quota "CPUs per region per VM family" enforces a limit + // on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions + // "region" and "vm_family". And if the violation occurred in region + // "us-central1" and for VM family "n1", the quota_dimensions would be, + // + // { + // "region": "us-central1", + // "vm_family": "n1", + // } + // + // When a quota is enforced globally, the quota_dimensions would always be + // empty. + map quota_dimensions = 6; + + // The enforced quota value at the time of the `QuotaFailure`. + // + // For example, if the enforced quota value at the time of the + // `QuotaFailure` on the number of CPUs is "10", then the value of this + // field would reflect this quantity. + int64 quota_value = 7; + + // The new quota value being rolled out at the time of the violation. At the + // completion of the rollout, this value will be enforced in place of + // quota_value. If no rollout is in progress at the time of the violation, + // this field is not set. + // + // For example, if at the time of the violation a rollout is in progress + // changing the number of CPUs quota from 10 to 20, 20 would be the value of + // this field. + optional int64 future_quota_value = 8; + } + + // Describes all quota violations. + repeated Violation violations = 1; +} + +// Describes what preconditions have failed. +// +// For example, if an RPC failed because it required the Terms of Service to be +// acknowledged, it could list the terms of service violation in the +// PreconditionFailure message. +message PreconditionFailure { + // A message type used to describe a single precondition failure. + message Violation { + // The type of PreconditionFailure. We recommend using a service-specific + // enum type to define the supported precondition violation subjects. For + // example, "TOS" for "Terms of Service violation". + string type = 1; + + // The subject, relative to the type, that failed. + // For example, "google.com/cloud" relative to the "TOS" type would indicate + // which terms of service is being referenced. + string subject = 2; + + // A description of how the precondition failed. Developers can use this + // description to understand how to fix the failure. + // + // For example: "Terms of service not accepted". + string description = 3; + } + + // Describes all precondition violations. + repeated Violation violations = 1; +} + +// Describes violations in a client request. This error type focuses on the +// syntactic aspects of the request. +message BadRequest { + // A message type used to describe a single bad request field. + message FieldViolation { + // A path that leads to a field in the request body. The value will be a + // sequence of dot-separated identifiers that identify a protocol buffer + // field. + // + // Consider the following: + // + // message CreateContactRequest { + // message EmailAddress { + // enum Type { + // TYPE_UNSPECIFIED = 0; + // HOME = 1; + // WORK = 2; + // } + // + // optional string email = 1; + // repeated EmailType type = 2; + // } + // + // string full_name = 1; + // repeated EmailAddress email_addresses = 2; + // } + // + // In this example, in proto `field` could take one of the following values: + // + // * `full_name` for a violation in the `full_name` value + // * `email_addresses[0].email` for a violation in the `email` field of the + // first `email_addresses` message + // * `email_addresses[2].type[1]` for a violation in the second `type` + // value in the third `email_addresses` message. + // + // In JSON, the same values are represented as: + // + // * `fullName` for a violation in the `fullName` value + // * `emailAddresses[0].email` for a violation in the `email` field of the + // first `emailAddresses` message + // * `emailAddresses[2].type[1]` for a violation in the second `type` + // value in the third `emailAddresses` message. + string field = 1; + + // A description of why the request element is bad. + string description = 2; + + // The reason of the field-level error. This is a constant value that + // identifies the proximate cause of the field-level error. It should + // uniquely identify the type of the FieldViolation within the scope of the + // google.rpc.ErrorInfo.domain. This should be at most 63 + // characters and match a regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, + // which represents UPPER_SNAKE_CASE. + string reason = 3; + + // Provides a localized error message for field-level errors that is safe to + // return to the API consumer. + LocalizedMessage localized_message = 4; + } + + // Describes all violations in a client request. + repeated FieldViolation field_violations = 1; +} + +// Contains metadata about the request that clients can attach when filing a bug +// or providing other forms of feedback. +message RequestInfo { + // An opaque string that should only be interpreted by the service generating + // it. For example, it can be used to identify requests in the service's logs. + string request_id = 1; + + // Any data that was used to serve this request. For example, an encrypted + // stack trace that can be sent back to the service provider for debugging. + string serving_data = 2; +} + +// Describes the resource that is being accessed. +message ResourceInfo { + // A name for the type of resource being accessed, e.g. "sql table", + // "cloud storage bucket", "file", "Google calendar"; or the type URL + // of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". + string resource_type = 1; + + // The name of the resource being accessed. For example, a shared calendar + // name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current + // error is + // [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. + string resource_name = 2; + + // The owner of the resource (optional). + // For example, "user:" or "project:". + string owner = 3; + + // Describes what error is encountered when accessing this resource. + // For example, updating a cloud project may require the `writer` permission + // on the developer console project. + string description = 4; +} + +// Provides links to documentation or for performing an out of band action. +// +// For example, if a quota check failed with an error indicating the calling +// project hasn't enabled the accessed service, this can contain a URL pointing +// directly to the right place in the developer console to flip the bit. +message Help { + // Describes a URL link. + message Link { + // Describes what the link offers. + string description = 1; + + // The URL of the link. + string url = 2; + } + + // URL(s) pointing to additional information on handling the current error. + repeated Link links = 1; +} + +// Provides a localized error message that is safe to return to the user +// which can be attached to an RPC error. +message LocalizedMessage { + // The locale used following the specification defined at + // https://www.rfc-editor.org/rfc/bcp/bcp47.txt. + // Examples are: "en-US", "fr-CH", "es-MX" + string locale = 1; + + // The localized error message in the above locale. + string message = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py new file mode 100644 index 00000000000..b53f087da55 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/rpc/error_details.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/error_details.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1egoogle/rpc/error_details.proto\x12\ngoogle.rpc\x1a\x1egoogle/protobuf/duration.proto"\x93\x01\n\tErrorInfo\x12\x0e\n\x06reason\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\x12\x35\n\x08metadata\x18\x03 \x03(\x0b\x32#.google.rpc.ErrorInfo.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01";\n\tRetryInfo\x12.\n\x0bretry_delay\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration"2\n\tDebugInfo\x12\x15\n\rstack_entries\x18\x01 \x03(\t\x12\x0e\n\x06\x64\x65tail\x18\x02 \x01(\t"\x8f\x03\n\x0cQuotaFailure\x12\x36\n\nviolations\x18\x01 \x03(\x0b\x32".google.rpc.QuotaFailure.Violation\x1a\xc6\x02\n\tViolation\x12\x0f\n\x07subject\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x13\n\x0b\x61pi_service\x18\x03 \x01(\t\x12\x14\n\x0cquota_metric\x18\x04 \x01(\t\x12\x10\n\x08quota_id\x18\x05 \x01(\t\x12Q\n\x10quota_dimensions\x18\x06 \x03(\x0b\x32\x37.google.rpc.QuotaFailure.Violation.QuotaDimensionsEntry\x12\x13\n\x0bquota_value\x18\x07 \x01(\x03\x12\x1f\n\x12\x66uture_quota_value\x18\x08 \x01(\x03H\x00\x88\x01\x01\x1a\x36\n\x14QuotaDimensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x15\n\x13_future_quota_value"\x95\x01\n\x13PreconditionFailure\x12=\n\nviolations\x18\x01 \x03(\x0b\x32).google.rpc.PreconditionFailure.Violation\x1a?\n\tViolation\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07subject\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"\xcc\x01\n\nBadRequest\x12?\n\x10\x66ield_violations\x18\x01 \x03(\x0b\x32%.google.rpc.BadRequest.FieldViolation\x1a}\n\x0e\x46ieldViolation\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x37\n\x11localized_message\x18\x04 \x01(\x0b\x32\x1c.google.rpc.LocalizedMessage"7\n\x0bRequestInfo\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x14\n\x0cserving_data\x18\x02 \x01(\t"`\n\x0cResourceInfo\x12\x15\n\rresource_type\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\r\n\x05owner\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t"V\n\x04Help\x12$\n\x05links\x18\x01 \x03(\x0b\x32\x15.google.rpc.Help.Link\x1a(\n\x04Link\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t"3\n\x10LocalizedMessage\x12\x0e\n\x06locale\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\tBl\n\x0e\x63om.google.rpcB\x11\x45rrorDetailsProtoP\x01Z?google.golang.org/genproto/googleapis/rpc/errdetails;errdetails\xa2\x02\x03RPCb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.error_details_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.rpcB\021ErrorDetailsProtoP\001Z?google.golang.org/genproto/googleapis/rpc/errdetails;errdetails\242\002\003RPC" + _globals["_ERRORINFO_METADATAENTRY"]._loaded_options = None + _globals["_ERRORINFO_METADATAENTRY"]._serialized_options = b"8\001" + _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._loaded_options = None + _globals[ + "_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY" + ]._serialized_options = b"8\001" + _globals["_ERRORINFO"]._serialized_start = 79 + _globals["_ERRORINFO"]._serialized_end = 226 + _globals["_ERRORINFO_METADATAENTRY"]._serialized_start = 179 + _globals["_ERRORINFO_METADATAENTRY"]._serialized_end = 226 + _globals["_RETRYINFO"]._serialized_start = 228 + _globals["_RETRYINFO"]._serialized_end = 287 + _globals["_DEBUGINFO"]._serialized_start = 289 + _globals["_DEBUGINFO"]._serialized_end = 339 + _globals["_QUOTAFAILURE"]._serialized_start = 342 + _globals["_QUOTAFAILURE"]._serialized_end = 741 + _globals["_QUOTAFAILURE_VIOLATION"]._serialized_start = 415 + _globals["_QUOTAFAILURE_VIOLATION"]._serialized_end = 741 + _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._serialized_start = 664 + _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._serialized_end = 718 + _globals["_PRECONDITIONFAILURE"]._serialized_start = 744 + _globals["_PRECONDITIONFAILURE"]._serialized_end = 893 + _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_start = 830 + _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_end = 893 + _globals["_BADREQUEST"]._serialized_start = 896 + _globals["_BADREQUEST"]._serialized_end = 1100 + _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_start = 975 + _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_end = 1100 + _globals["_REQUESTINFO"]._serialized_start = 1102 + _globals["_REQUESTINFO"]._serialized_end = 1157 + _globals["_RESOURCEINFO"]._serialized_start = 1159 + _globals["_RESOURCEINFO"]._serialized_end = 1255 + _globals["_HELP"]._serialized_start = 1257 + _globals["_HELP"]._serialized_end = 1343 + _globals["_HELP_LINK"]._serialized_start = 1303 + _globals["_HELP_LINK"]._serialized_end = 1343 + _globals["_LOCALIZEDMESSAGE"]._serialized_start = 1345 + _globals["_LOCALIZEDMESSAGE"]._serialized_end = 1396 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi new file mode 100644 index 00000000000..d581ac79152 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi @@ -0,0 +1,250 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import datetime +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import duration_pb2 as _duration_pb2 +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class ErrorInfo(_message.Message): + __slots__ = ("reason", "domain", "metadata") + class MetadataEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + REASON_FIELD_NUMBER: _ClassVar[int] + DOMAIN_FIELD_NUMBER: _ClassVar[int] + METADATA_FIELD_NUMBER: _ClassVar[int] + reason: str + domain: str + metadata: _containers.ScalarMap[str, str] + def __init__( + self, + reason: _Optional[str] = ..., + domain: _Optional[str] = ..., + metadata: _Optional[_Mapping[str, str]] = ..., + ) -> None: ... + +class RetryInfo(_message.Message): + __slots__ = ("retry_delay",) + RETRY_DELAY_FIELD_NUMBER: _ClassVar[int] + retry_delay: _duration_pb2.Duration + def __init__( + self, + retry_delay: _Optional[ + _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] + ] = ..., + ) -> None: ... + +class DebugInfo(_message.Message): + __slots__ = ("stack_entries", "detail") + STACK_ENTRIES_FIELD_NUMBER: _ClassVar[int] + DETAIL_FIELD_NUMBER: _ClassVar[int] + stack_entries: _containers.RepeatedScalarFieldContainer[str] + detail: str + def __init__( + self, + stack_entries: _Optional[_Iterable[str]] = ..., + detail: _Optional[str] = ..., + ) -> None: ... + +class QuotaFailure(_message.Message): + __slots__ = ("violations",) + class Violation(_message.Message): + __slots__ = ( + "subject", + "description", + "api_service", + "quota_metric", + "quota_id", + "quota_dimensions", + "quota_value", + "future_quota_value", + ) + class QuotaDimensionsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... + + SUBJECT_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + API_SERVICE_FIELD_NUMBER: _ClassVar[int] + QUOTA_METRIC_FIELD_NUMBER: _ClassVar[int] + QUOTA_ID_FIELD_NUMBER: _ClassVar[int] + QUOTA_DIMENSIONS_FIELD_NUMBER: _ClassVar[int] + QUOTA_VALUE_FIELD_NUMBER: _ClassVar[int] + FUTURE_QUOTA_VALUE_FIELD_NUMBER: _ClassVar[int] + subject: str + description: str + api_service: str + quota_metric: str + quota_id: str + quota_dimensions: _containers.ScalarMap[str, str] + quota_value: int + future_quota_value: int + def __init__( + self, + subject: _Optional[str] = ..., + description: _Optional[str] = ..., + api_service: _Optional[str] = ..., + quota_metric: _Optional[str] = ..., + quota_id: _Optional[str] = ..., + quota_dimensions: _Optional[_Mapping[str, str]] = ..., + quota_value: _Optional[int] = ..., + future_quota_value: _Optional[int] = ..., + ) -> None: ... + + VIOLATIONS_FIELD_NUMBER: _ClassVar[int] + violations: _containers.RepeatedCompositeFieldContainer[QuotaFailure.Violation] + def __init__( + self, + violations: _Optional[ + _Iterable[_Union[QuotaFailure.Violation, _Mapping]] + ] = ..., + ) -> None: ... + +class PreconditionFailure(_message.Message): + __slots__ = ("violations",) + class Violation(_message.Message): + __slots__ = ("type", "subject", "description") + TYPE_FIELD_NUMBER: _ClassVar[int] + SUBJECT_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + type: str + subject: str + description: str + def __init__( + self, + type: _Optional[str] = ..., + subject: _Optional[str] = ..., + description: _Optional[str] = ..., + ) -> None: ... + + VIOLATIONS_FIELD_NUMBER: _ClassVar[int] + violations: _containers.RepeatedCompositeFieldContainer[ + PreconditionFailure.Violation + ] + def __init__( + self, + violations: _Optional[ + _Iterable[_Union[PreconditionFailure.Violation, _Mapping]] + ] = ..., + ) -> None: ... + +class BadRequest(_message.Message): + __slots__ = ("field_violations",) + class FieldViolation(_message.Message): + __slots__ = ("field", "description", "reason", "localized_message") + FIELD_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + REASON_FIELD_NUMBER: _ClassVar[int] + LOCALIZED_MESSAGE_FIELD_NUMBER: _ClassVar[int] + field: str + description: str + reason: str + localized_message: LocalizedMessage + def __init__( + self, + field: _Optional[str] = ..., + description: _Optional[str] = ..., + reason: _Optional[str] = ..., + localized_message: _Optional[_Union[LocalizedMessage, _Mapping]] = ..., + ) -> None: ... + + FIELD_VIOLATIONS_FIELD_NUMBER: _ClassVar[int] + field_violations: _containers.RepeatedCompositeFieldContainer[ + BadRequest.FieldViolation + ] + def __init__( + self, + field_violations: _Optional[ + _Iterable[_Union[BadRequest.FieldViolation, _Mapping]] + ] = ..., + ) -> None: ... + +class RequestInfo(_message.Message): + __slots__ = ("request_id", "serving_data") + REQUEST_ID_FIELD_NUMBER: _ClassVar[int] + SERVING_DATA_FIELD_NUMBER: _ClassVar[int] + request_id: str + serving_data: str + def __init__( + self, request_id: _Optional[str] = ..., serving_data: _Optional[str] = ... + ) -> None: ... + +class ResourceInfo(_message.Message): + __slots__ = ("resource_type", "resource_name", "owner", "description") + RESOURCE_TYPE_FIELD_NUMBER: _ClassVar[int] + RESOURCE_NAME_FIELD_NUMBER: _ClassVar[int] + OWNER_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + resource_type: str + resource_name: str + owner: str + description: str + def __init__( + self, + resource_type: _Optional[str] = ..., + resource_name: _Optional[str] = ..., + owner: _Optional[str] = ..., + description: _Optional[str] = ..., + ) -> None: ... + +class Help(_message.Message): + __slots__ = ("links",) + class Link(_message.Message): + __slots__ = ("description", "url") + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + URL_FIELD_NUMBER: _ClassVar[int] + description: str + url: str + def __init__( + self, description: _Optional[str] = ..., url: _Optional[str] = ... + ) -> None: ... + + LINKS_FIELD_NUMBER: _ClassVar[int] + links: _containers.RepeatedCompositeFieldContainer[Help.Link] + def __init__( + self, links: _Optional[_Iterable[_Union[Help.Link, _Mapping]]] = ... + ) -> None: ... + +class LocalizedMessage(_message.Message): + __slots__ = ("locale", "message") + LOCALE_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + locale: str + message: str + def __init__( + self, locale: _Optional[str] = ..., message: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto new file mode 100644 index 00000000000..9d97b601d9f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto @@ -0,0 +1,64 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +option go_package = "google.golang.org/genproto/googleapis/rpc/http;http"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + +// Represents an HTTP request. +message HttpRequest { + // The HTTP request method. + string method = 1; + + // The HTTP request URI. + string uri = 2; + + // The HTTP request headers. The ordering of the headers is significant. + // Multiple headers with the same key may present for the request. + repeated HttpHeader headers = 3; + + // The HTTP request body. If the body is not expected, it should be empty. + bytes body = 4; +} + +// Represents an HTTP response. +message HttpResponse { + // The HTTP status code, such as 200 or 404. + int32 status = 1; + + // The HTTP reason phrase, such as "OK" or "Not Found". + string reason = 2; + + // The HTTP response headers. The ordering of the headers is significant. + // Multiple headers with the same key may present for the response. + repeated HttpHeader headers = 3; + + // The HTTP response body. If the body is not expected, it should be empty. + bytes body = 4; +} + +// Represents an HTTP header. +message HttpHeader { + // The HTTP header key. It is case insensitive. + string key = 1; + + // The HTTP header value. + string value = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py new file mode 100644 index 00000000000..57fd1ef8681 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/rpc/http.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/http.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x15google/rpc/http.proto\x12\ngoogle.rpc"a\n\x0bHttpRequest\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\'\n\x07headers\x18\x03 \x03(\x0b\x32\x16.google.rpc.HttpHeader\x12\x0c\n\x04\x62ody\x18\x04 \x01(\x0c"e\n\x0cHttpResponse\x12\x0e\n\x06status\x18\x01 \x01(\x05\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\'\n\x07headers\x18\x03 \x03(\x0b\x32\x16.google.rpc.HttpHeader\x12\x0c\n\x04\x62ody\x18\x04 \x01(\x0c"(\n\nHttpHeader\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\tBX\n\x0e\x63om.google.rpcB\tHttpProtoP\x01Z3google.golang.org/genproto/googleapis/rpc/http;http\xa2\x02\x03RPCb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.http_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.rpcB\tHttpProtoP\001Z3google.golang.org/genproto/googleapis/rpc/http;http\242\002\003RPC" + _globals["_HTTPREQUEST"]._serialized_start = 37 + _globals["_HTTPREQUEST"]._serialized_end = 134 + _globals["_HTTPRESPONSE"]._serialized_start = 136 + _globals["_HTTPRESPONSE"]._serialized_end = 237 + _globals["_HTTPHEADER"]._serialized_start = 239 + _globals["_HTTPHEADER"]._serialized_end = 279 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi new file mode 100644 index 00000000000..69f680b03a4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi @@ -0,0 +1,71 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class HttpRequest(_message.Message): + __slots__ = ("method", "uri", "headers", "body") + METHOD_FIELD_NUMBER: _ClassVar[int] + URI_FIELD_NUMBER: _ClassVar[int] + HEADERS_FIELD_NUMBER: _ClassVar[int] + BODY_FIELD_NUMBER: _ClassVar[int] + method: str + uri: str + headers: _containers.RepeatedCompositeFieldContainer[HttpHeader] + body: bytes + def __init__( + self, + method: _Optional[str] = ..., + uri: _Optional[str] = ..., + headers: _Optional[_Iterable[_Union[HttpHeader, _Mapping]]] = ..., + body: _Optional[bytes] = ..., + ) -> None: ... + +class HttpResponse(_message.Message): + __slots__ = ("status", "reason", "headers", "body") + STATUS_FIELD_NUMBER: _ClassVar[int] + REASON_FIELD_NUMBER: _ClassVar[int] + HEADERS_FIELD_NUMBER: _ClassVar[int] + BODY_FIELD_NUMBER: _ClassVar[int] + status: int + reason: str + headers: _containers.RepeatedCompositeFieldContainer[HttpHeader] + body: bytes + def __init__( + self, + status: _Optional[int] = ..., + reason: _Optional[str] = ..., + headers: _Optional[_Iterable[_Union[HttpHeader, _Mapping]]] = ..., + body: _Optional[bytes] = ..., + ) -> None: ... + +class HttpHeader(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto new file mode 100644 index 00000000000..97f50b9d890 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto @@ -0,0 +1,48 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.rpc; + +import "google/protobuf/any.proto"; + +option go_package = "google.golang.org/genproto/googleapis/rpc/status;status"; +option java_multiple_files = true; +option java_outer_classname = "StatusProto"; +option java_package = "com.google.rpc"; +option objc_class_prefix = "RPC"; + +// The `Status` type defines a logical error model that is suitable for +// different programming environments, including REST APIs and RPC APIs. It is +// used by [gRPC](https://github.com/grpc). Each `Status` message contains +// three pieces of data: error code, error message, and error details. +// +// You can find out more about this error model and how to work with it in the +// [API Design Guide](https://cloud.google.com/apis/design/errors). +message Status { + // The status code, which should be an enum value of + // [google.rpc.Code][google.rpc.Code]. + int32 code = 1; + + // A developer-facing error message, which should be in English. Any + // user-facing error message should be localized and sent in the + // [google.rpc.Status.details][google.rpc.Status.details] field, or localized + // by the client. + string message = 2; + + // A list of messages that carry the error details. There is a common set of + // message types for APIs to use. + repeated google.protobuf.Any details = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py new file mode 100644 index 00000000000..2d713790e3c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/rpc/status.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/status.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x17google/rpc/status.proto\x12\ngoogle.rpc\x1a\x19google/protobuf/any.proto"N\n\x06Status\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\x12%\n\x07\x64\x65tails\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyB^\n\x0e\x63om.google.rpcB\x0bStatusProtoP\x01Z7google.golang.org/genproto/googleapis/rpc/status;status\xa2\x02\x03RPCb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.status_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\016com.google.rpcB\013StatusProtoP\001Z7google.golang.org/genproto/googleapis/rpc/status;status\242\002\003RPC" + _globals["_STATUS"]._serialized_start = 66 + _globals["_STATUS"]._serialized_end = 144 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi new file mode 100644 index 00000000000..c24374a0eca --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi @@ -0,0 +1,41 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import any_pb2 as _any_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class Status(_message.Message): + __slots__ = ("code", "message", "details") + CODE_FIELD_NUMBER: _ClassVar[int] + MESSAGE_FIELD_NUMBER: _ClassVar[int] + DETAILS_FIELD_NUMBER: _ClassVar[int] + code: int + message: str + details: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] + def __init__( + self, + code: _Optional[int] = ..., + message: _Optional[str] = ..., + details: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto new file mode 100644 index 00000000000..ae08aebd677 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto @@ -0,0 +1,56 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/calendarperiod;calendarperiod"; +option java_multiple_files = true; +option java_outer_classname = "CalendarPeriodProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// A `CalendarPeriod` represents the abstract concept of a time period that has +// a canonical start. Grammatically, "the start of the current +// `CalendarPeriod`." All calendar times begin at midnight UTC. +enum CalendarPeriod { + // Undefined period, raises an error. + CALENDAR_PERIOD_UNSPECIFIED = 0; + + // A day. + DAY = 1; + + // A week. Weeks begin on Monday, following + // [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). + WEEK = 2; + + // A fortnight. The first calendar fortnight of the year begins at the start + // of week 1 according to + // [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). + FORTNIGHT = 3; + + // A month. + MONTH = 4; + + // A quarter. Quarters start on dates 1-Jan, 1-Apr, 1-Jul, and 1-Oct of each + // year. + QUARTER = 5; + + // A half-year. Half-years start on dates 1-Jan and 1-Jul. + HALF = 6; + + // A year. + YEAR = 7; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py new file mode 100644 index 00000000000..813bccfed09 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/calendar_period.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/calendar_period.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n!google/type/calendar_period.proto\x12\x0bgoogle.type*\x7f\n\x0e\x43\x61lendarPeriod\x12\x1f\n\x1b\x43\x41LENDAR_PERIOD_UNSPECIFIED\x10\x00\x12\x07\n\x03\x44\x41Y\x10\x01\x12\x08\n\x04WEEK\x10\x02\x12\r\n\tFORTNIGHT\x10\x03\x12\t\n\x05MONTH\x10\x04\x12\x0b\n\x07QUARTER\x10\x05\x12\x08\n\x04HALF\x10\x06\x12\x08\n\x04YEAR\x10\x07\x42x\n\x0f\x63om.google.typeB\x13\x43\x61lendarPeriodProtoP\x01ZHgoogle.golang.org/genproto/googleapis/type/calendarperiod;calendarperiod\xa2\x02\x03GTPb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.type.calendar_period_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\023CalendarPeriodProtoP\001ZHgoogle.golang.org/genproto/googleapis/type/calendarperiod;calendarperiod\242\002\003GTP" + _globals["_CALENDARPERIOD"]._serialized_start = 50 + _globals["_CALENDARPERIOD"]._serialized_end = 177 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi new file mode 100644 index 00000000000..2e230b4ed08 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class CalendarPeriod(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + CALENDAR_PERIOD_UNSPECIFIED: _ClassVar[CalendarPeriod] + DAY: _ClassVar[CalendarPeriod] + WEEK: _ClassVar[CalendarPeriod] + FORTNIGHT: _ClassVar[CalendarPeriod] + MONTH: _ClassVar[CalendarPeriod] + QUARTER: _ClassVar[CalendarPeriod] + HALF: _ClassVar[CalendarPeriod] + YEAR: _ClassVar[CalendarPeriod] + +CALENDAR_PERIOD_UNSPECIFIED: CalendarPeriod +DAY: CalendarPeriod +WEEK: CalendarPeriod +FORTNIGHT: CalendarPeriod +MONTH: CalendarPeriod +QUARTER: CalendarPeriod +HALF: CalendarPeriod +YEAR: CalendarPeriod diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto new file mode 100644 index 00000000000..c48d0644a70 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto @@ -0,0 +1,173 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +import "google/protobuf/wrappers.proto"; + +option go_package = "google.golang.org/genproto/googleapis/type/color;color"; +option java_multiple_files = true; +option java_outer_classname = "ColorProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a color in the RGBA color space. This representation is designed +// for simplicity of conversion to and from color representations in various +// languages over compactness. For example, the fields of this representation +// can be trivially provided to the constructor of `java.awt.Color` in Java; it +// can also be trivially provided to UIColor's `+colorWithRed:green:blue:alpha` +// method in iOS; and, with just a little work, it can be easily formatted into +// a CSS `rgba()` string in JavaScript. +// +// This reference page doesn't have information about the absolute color +// space that should be used to interpret the RGB value—for example, sRGB, +// Adobe RGB, +// DCI-P3, and BT.2020. By default, applications should assume the sRGB color +// space. +// +// When color equality needs to be decided, implementations, unless documented +// otherwise, treat two colors as equal if all their red, green, blue, and alpha +// values each differ by at most `1e-5`. +// +// Example (Java): +// +// import com.google.type.Color; +// +// // ... +// public static java.awt.Color fromProto(Color protocolor) { +// float alpha = protocolor.hasAlpha() +// ? protocolor.getAlpha().getValue() +// : 1.0; +// +// return new java.awt.Color( +// protocolor.getRed(), +// protocolor.getGreen(), +// protocolor.getBlue(), +// alpha); +// } +// +// public static Color toProto(java.awt.Color color) { +// float red = (float) color.getRed(); +// float green = (float) color.getGreen(); +// float blue = (float) color.getBlue(); +// float denominator = 255.0; +// Color.Builder resultBuilder = +// Color +// .newBuilder() +// .setRed(red / denominator) +// .setGreen(green / denominator) +// .setBlue(blue / denominator); +// int alpha = color.getAlpha(); +// if (alpha != 255) { +// result.setAlpha( +// FloatValue +// .newBuilder() +// .setValue(((float) alpha) / denominator) +// .build()); +// } +// return resultBuilder.build(); +// } +// // ... +// +// Example (iOS / Obj-C): +// +// // ... +// static UIColor* fromProto(Color* protocolor) { +// float red = [protocolor red]; +// float green = [protocolor green]; +// float blue = [protocolor blue]; +// FloatValue* alpha_wrapper = [protocolor alpha]; +// float alpha = 1.0; +// if (alpha_wrapper != nil) { +// alpha = [alpha_wrapper value]; +// } +// return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; +// } +// +// static Color* toProto(UIColor* color) { +// CGFloat red, green, blue, alpha; +// if (![color getRed:&red green:&green blue:&blue alpha:&alpha]) { +// return nil; +// } +// Color* result = [[Color alloc] init]; +// [result setRed:red]; +// [result setGreen:green]; +// [result setBlue:blue]; +// if (alpha <= 0.9999) { +// [result setAlpha:floatWrapperWithValue(alpha)]; +// } +// [result autorelease]; +// return result; +// } +// // ... +// +// Example (JavaScript): +// +// // ... +// +// var protoToCssColor = function(rgb_color) { +// var redFrac = rgb_color.red || 0.0; +// var greenFrac = rgb_color.green || 0.0; +// var blueFrac = rgb_color.blue || 0.0; +// var red = Math.floor(redFrac * 255); +// var green = Math.floor(greenFrac * 255); +// var blue = Math.floor(blueFrac * 255); +// +// if (!('alpha' in rgb_color)) { +// return rgbToCssColor(red, green, blue); +// } +// +// var alphaFrac = rgb_color.alpha.value || 0.0; +// var rgbParams = [red, green, blue].join(','); +// return ['rgba(', rgbParams, ',', alphaFrac, ')'].join(''); +// }; +// +// var rgbToCssColor = function(red, green, blue) { +// var rgbNumber = new Number((red << 16) | (green << 8) | blue); +// var hexString = rgbNumber.toString(16); +// var missingZeros = 6 - hexString.length; +// var resultBuilder = ['#']; +// for (var i = 0; i < missingZeros; i++) { +// resultBuilder.push('0'); +// } +// resultBuilder.push(hexString); +// return resultBuilder.join(''); +// }; +// +// // ... +message Color { + // The amount of red in the color as a value in the interval [0, 1]. + float red = 1; + + // The amount of green in the color as a value in the interval [0, 1]. + float green = 2; + + // The amount of blue in the color as a value in the interval [0, 1]. + float blue = 3; + + // The fraction of this color that should be applied to the pixel. That is, + // the final pixel color is defined by the equation: + // + // `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` + // + // This means that a value of 1.0 corresponds to a solid color, whereas + // a value of 0.0 corresponds to a completely transparent color. This + // uses a wrapper message rather than a simple float scalar so that it is + // possible to distinguish between a default value and the value being unset. + // If omitted, this color object is rendered as a solid color + // (as if the alpha value had been explicitly given a value of 1.0). + google.protobuf.FloatValue alpha = 4; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py new file mode 100644 index 00000000000..5e4e0a27f69 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/color.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/color.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x17google/type/color.proto\x12\x0bgoogle.type\x1a\x1egoogle/protobuf/wrappers.proto"]\n\x05\x43olor\x12\x0b\n\x03red\x18\x01 \x01(\x02\x12\r\n\x05green\x18\x02 \x01(\x02\x12\x0c\n\x04\x62lue\x18\x03 \x01(\x02\x12*\n\x05\x61lpha\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.FloatValueB]\n\x0f\x63om.google.typeB\nColorProtoP\x01Z6google.golang.org/genproto/googleapis/type/color;color\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.color_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\nColorProtoP\001Z6google.golang.org/genproto/googleapis/type/color;color\242\002\003GTP" + _globals["_COLOR"]._serialized_start = 72 + _globals["_COLOR"]._serialized_end = 165 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi new file mode 100644 index 00000000000..c80242e79bb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi @@ -0,0 +1,42 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import wrappers_pb2 as _wrappers_pb2 + +DESCRIPTOR: _descriptor.FileDescriptor + +class Color(_message.Message): + __slots__ = ("red", "green", "blue", "alpha") + RED_FIELD_NUMBER: _ClassVar[int] + GREEN_FIELD_NUMBER: _ClassVar[int] + BLUE_FIELD_NUMBER: _ClassVar[int] + ALPHA_FIELD_NUMBER: _ClassVar[int] + red: float + green: float + blue: float + alpha: _wrappers_pb2.FloatValue + def __init__( + self, + red: _Optional[float] = ..., + green: _Optional[float] = ..., + blue: _Optional[float] = ..., + alpha: _Optional[_Union[_wrappers_pb2.FloatValue, _Mapping]] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto new file mode 100644 index 00000000000..12be7e16a48 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto @@ -0,0 +1,54 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/date;date"; +option java_multiple_files = true; +option java_outer_classname = "DateProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a whole or partial calendar date, such as a birthday. The time of +// day and time zone are either specified elsewhere or are insignificant. The +// date is relative to the Gregorian Calendar. This can represent one of the +// following: +// +// * A full date, with non-zero year, month, and day values. +// * A month and day, with a zero year (for example, an anniversary). +// * A year on its own, with a zero month and a zero day. +// * A year and month, with a zero day (for example, a credit card expiration +// date). +// +// Related types: +// +// * [google.type.TimeOfDay][google.type.TimeOfDay] +// * [google.type.DateTime][google.type.DateTime] +// * [google.protobuf.Timestamp][google.protobuf.Timestamp] +message Date { + // Year of the date. Must be from 1 to 9999, or 0 to specify a date without + // a year. + int32 year = 1; + + // Month of a year. Must be from 1 to 12, or 0 to specify a year without a + // month and day. + int32 month = 2; + + // Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 + // to specify a year by itself or a year and month where the day isn't + // significant. + int32 day = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py new file mode 100644 index 00000000000..11130adab1c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/date.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/date.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x16google/type/date.proto\x12\x0bgoogle.type"0\n\x04\x44\x61te\x12\x0c\n\x04year\x18\x01 \x01(\x05\x12\r\n\x05month\x18\x02 \x01(\x05\x12\x0b\n\x03\x64\x61y\x18\x03 \x01(\x05\x42Z\n\x0f\x63om.google.typeB\tDateProtoP\x01Z4google.golang.org/genproto/googleapis/type/date;date\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.date_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\tDateProtoP\001Z4google.golang.org/genproto/googleapis/type/date;date\242\002\003GTP" + _globals["_DATE"]._serialized_start = 39 + _globals["_DATE"]._serialized_end = 87 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi new file mode 100644 index 00000000000..fcaf2f9984a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi @@ -0,0 +1,36 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class Date(_message.Message): + __slots__ = ("year", "month", "day") + YEAR_FIELD_NUMBER: _ClassVar[int] + MONTH_FIELD_NUMBER: _ClassVar[int] + DAY_FIELD_NUMBER: _ClassVar[int] + year: int + month: int + day: int + def __init__( + self, + year: _Optional[int] = ..., + month: _Optional[int] = ..., + day: _Optional[int] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto new file mode 100644 index 00000000000..b81e4f472f9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto @@ -0,0 +1,104 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +import "google/protobuf/duration.proto"; + +option go_package = "google.golang.org/genproto/googleapis/type/datetime;datetime"; +option java_multiple_files = true; +option java_outer_classname = "DateTimeProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents civil time (or occasionally physical time). +// +// This type can represent a civil time in one of a few possible ways: +// +// * When utc_offset is set and time_zone is unset: a civil time on a calendar +// day with a particular offset from UTC. +// * When time_zone is set and utc_offset is unset: a civil time on a calendar +// day in a particular time zone. +// * When neither time_zone nor utc_offset is set: a civil time on a calendar +// day in local time. +// +// The date is relative to the Proleptic Gregorian Calendar. +// +// If year, month, or day are 0, the DateTime is considered not to have a +// specific year, month, or day respectively. +// +// This type may also be used to represent a physical time if all the date and +// time fields are set and either case of the `time_offset` oneof is set. +// Consider using `Timestamp` message for physical time instead. If your use +// case also would like to store the user's timezone, that can be done in +// another field. +// +// This type is more flexible than some applications may want. Make sure to +// document and validate your application's limitations. +message DateTime { + // Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a + // datetime without a year. + int32 year = 1; + + // Optional. Month of year. Must be from 1 to 12, or 0 if specifying a + // datetime without a month. + int32 month = 2; + + // Optional. Day of month. Must be from 1 to 31 and valid for the year and + // month, or 0 if specifying a datetime without a day. + int32 day = 3; + + // Optional. Hours of day in 24 hour format. Should be from 0 to 23, defaults + // to 0 (midnight). An API may choose to allow the value "24:00:00" for + // scenarios like business closing time. + int32 hours = 4; + + // Optional. Minutes of hour of day. Must be from 0 to 59, defaults to 0. + int32 minutes = 5; + + // Optional. Seconds of minutes of the time. Must normally be from 0 to 59, + // defaults to 0. An API may allow the value 60 if it allows leap-seconds. + int32 seconds = 6; + + // Optional. Fractions of seconds in nanoseconds. Must be from 0 to + // 999,999,999, defaults to 0. + int32 nanos = 7; + + // Optional. Specifies either the UTC offset or the time zone of the DateTime. + // Choose carefully between them, considering that time zone data may change + // in the future (for example, a country modifies their DST start/end dates, + // and future DateTimes in the affected range had already been stored). + // If omitted, the DateTime is considered to be in local time. + oneof time_offset { + // UTC offset. Must be whole seconds, between -18 hours and +18 hours. + // For example, a UTC offset of -4:00 would be represented as + // { seconds: -14400 }. + google.protobuf.Duration utc_offset = 8; + + // Time zone. + TimeZone time_zone = 9; + } +} + +// Represents a time zone from the +// [IANA Time Zone Database](https://www.iana.org/time-zones). +message TimeZone { + // IANA Time Zone Database time zone. For example "America/New_York". + string id = 1; + + // Optional. IANA Time Zone Database version number. For example "2019a". + string version = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py new file mode 100644 index 00000000000..84bf4dabfd4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/datetime.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/datetime.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1agoogle/type/datetime.proto\x12\x0bgoogle.type\x1a\x1egoogle/protobuf/duration.proto"\xe0\x01\n\x08\x44\x61teTime\x12\x0c\n\x04year\x18\x01 \x01(\x05\x12\r\n\x05month\x18\x02 \x01(\x05\x12\x0b\n\x03\x64\x61y\x18\x03 \x01(\x05\x12\r\n\x05hours\x18\x04 \x01(\x05\x12\x0f\n\x07minutes\x18\x05 \x01(\x05\x12\x0f\n\x07seconds\x18\x06 \x01(\x05\x12\r\n\x05nanos\x18\x07 \x01(\x05\x12/\n\nutc_offset\x18\x08 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x12*\n\ttime_zone\x18\t \x01(\x0b\x32\x15.google.type.TimeZoneH\x00\x42\r\n\x0btime_offset"\'\n\x08TimeZone\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\tBf\n\x0f\x63om.google.typeB\rDateTimeProtoP\x01Z None: ... + +class TimeZone(_message.Message): + __slots__ = ("id", "version") + ID_FIELD_NUMBER: _ClassVar[int] + VERSION_FIELD_NUMBER: _ClassVar[int] + id: str + version: str + def __init__( + self, id: _Optional[str] = ..., version: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto new file mode 100644 index 00000000000..669d89401c1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto @@ -0,0 +1,50 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/dayofweek;dayofweek"; +option java_multiple_files = true; +option java_outer_classname = "DayOfWeekProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a day of the week. +enum DayOfWeek { + // The day of the week is unspecified. + DAY_OF_WEEK_UNSPECIFIED = 0; + + // Monday + MONDAY = 1; + + // Tuesday + TUESDAY = 2; + + // Wednesday + WEDNESDAY = 3; + + // Thursday + THURSDAY = 4; + + // Friday + FRIDAY = 5; + + // Saturday + SATURDAY = 6; + + // Sunday + SUNDAY = 7; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py new file mode 100644 index 00000000000..18ceb9601c3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/dayofweek.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/dayofweek.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n\x1bgoogle/type/dayofweek.proto\x12\x0bgoogle.type*\x84\x01\n\tDayOfWeek\x12\x1b\n\x17\x44\x41Y_OF_WEEK_UNSPECIFIED\x10\x00\x12\n\n\x06MONDAY\x10\x01\x12\x0b\n\x07TUESDAY\x10\x02\x12\r\n\tWEDNESDAY\x10\x03\x12\x0c\n\x08THURSDAY\x10\x04\x12\n\n\x06\x46RIDAY\x10\x05\x12\x0c\n\x08SATURDAY\x10\x06\x12\n\n\x06SUNDAY\x10\x07\x42i\n\x0f\x63om.google.typeB\x0e\x44\x61yOfWeekProtoP\x01Z>google.golang.org/genproto/googleapis/type/dayofweek;dayofweek\xa2\x02\x03GTPb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.type.dayofweek_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\016DayOfWeekProtoP\001Z>google.golang.org/genproto/googleapis/type/dayofweek;dayofweek\242\002\003GTP" + _globals["_DAYOFWEEK"]._serialized_start = 45 + _globals["_DAYOFWEEK"]._serialized_end = 177 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi new file mode 100644 index 00000000000..34c6770654e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class DayOfWeek(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + DAY_OF_WEEK_UNSPECIFIED: _ClassVar[DayOfWeek] + MONDAY: _ClassVar[DayOfWeek] + TUESDAY: _ClassVar[DayOfWeek] + WEDNESDAY: _ClassVar[DayOfWeek] + THURSDAY: _ClassVar[DayOfWeek] + FRIDAY: _ClassVar[DayOfWeek] + SATURDAY: _ClassVar[DayOfWeek] + SUNDAY: _ClassVar[DayOfWeek] + +DAY_OF_WEEK_UNSPECIFIED: DayOfWeek +MONDAY: DayOfWeek +TUESDAY: DayOfWeek +WEDNESDAY: DayOfWeek +THURSDAY: DayOfWeek +FRIDAY: DayOfWeek +SATURDAY: DayOfWeek +SUNDAY: DayOfWeek diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto new file mode 100644 index 00000000000..353e14b477a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto @@ -0,0 +1,93 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/decimal;decimal"; +option java_multiple_files = true; +option java_outer_classname = "DecimalProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// A representation of a decimal value, such as 2.5. Clients may convert values +// into language-native decimal formats, such as Java's +// [BigDecimal](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html) +// or Python's +// [decimal.Decimal](https://docs.python.org/3/library/decimal.html). +message Decimal { + // The decimal value, as a string. + // + // The string representation consists of an optional sign, `+` (`U+002B`) + // or `-` (`U+002D`), followed by a sequence of zero or more decimal digits + // ("the integer"), optionally followed by a fraction, optionally followed + // by an exponent. An empty string **should** be interpreted as `0`. + // + // The fraction consists of a decimal point followed by zero or more decimal + // digits. The string must contain at least one digit in either the integer + // or the fraction. The number formed by the sign, the integer and the + // fraction is referred to as the significand. + // + // The exponent consists of the character `e` (`U+0065`) or `E` (`U+0045`) + // followed by one or more decimal digits. + // + // Services **should** normalize decimal values before storing them by: + // + // - Removing an explicitly-provided `+` sign (`+2.5` -> `2.5`). + // - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). + // - Coercing the exponent character to upper-case, with explicit sign + // (`2.5e8` -> `2.5E+8`). + // - Removing an explicitly-provided zero exponent (`2.5E0` -> `2.5`). + // + // Services **may** perform additional normalization based on its own needs + // and the internal decimal implementation selected, such as shifting the + // decimal point and exponent value together (example: `2.5E-1` <-> `0.25`). + // Additionally, services **may** preserve trailing zeroes in the fraction + // to indicate increased precision, but are not required to do so. + // + // Note that only the `.` character is supported to divide the integer + // and the fraction; `,` **should not** be supported regardless of locale. + // Additionally, thousand separators **should not** be supported. If a + // service does support them, values **must** be normalized. + // + // The ENBF grammar is: + // + // DecimalString = + // '' | [Sign] Significand [Exponent]; + // + // Sign = '+' | '-'; + // + // Significand = + // Digits ['.'] [Digits] | [Digits] '.' Digits; + // + // Exponent = ('e' | 'E') [Sign] Digits; + // + // Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; + // + // Services **should** clearly document the range of supported values, the + // maximum supported precision (total number of digits), and, if applicable, + // the scale (number of digits after the decimal point), as well as how it + // behaves when receiving out-of-bounds values. + // + // Services **may** choose to accept values passed as input even when the + // value has a higher precision or scale than the service supports, and + // **should** round the value to fit the supported scale. Alternatively, the + // service **may** error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) + // if precision would be lost. + // + // Services **should** error with `400 Bad Request` (`INVALID_ARGUMENT` in + // gRPC) if the service receives a value outside of the supported range. + string value = 1; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py new file mode 100644 index 00000000000..79a62771fa9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/decimal.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/decimal.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x19google/type/decimal.proto\x12\x0bgoogle.type"\x18\n\x07\x44\x65\x63imal\x12\r\n\x05value\x18\x01 \x01(\tBc\n\x0f\x63om.google.typeB\x0c\x44\x65\x63imalProtoP\x01Z:google.golang.org/genproto/googleapis/type/decimal;decimal\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.decimal_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\014DecimalProtoP\001Z:google.golang.org/genproto/googleapis/type/decimal;decimal\242\002\003GTP" + _globals["_DECIMAL"]._serialized_start = 42 + _globals["_DECIMAL"]._serialized_end = 66 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi new file mode 100644 index 00000000000..95f43e305a7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi @@ -0,0 +1,27 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class Decimal(_message.Message): + __slots__ = ("value",) + VALUE_FIELD_NUMBER: _ClassVar[int] + value: str + def __init__(self, value: _Optional[str] = ...) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto new file mode 100644 index 00000000000..2fca5cda315 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto @@ -0,0 +1,73 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/expr;expr"; +option java_multiple_files = true; +option java_outer_classname = "ExprProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a textual expression in the Common Expression Language (CEL) +// syntax. CEL is a C-like expression language. The syntax and semantics of CEL +// are documented at https://github.com/google/cel-spec. +// +// Example (Comparison): +// +// title: "Summary size limit" +// description: "Determines if a summary is less than 100 chars" +// expression: "document.summary.size() < 100" +// +// Example (Equality): +// +// title: "Requestor is owner" +// description: "Determines if requestor is the document owner" +// expression: "document.owner == request.auth.claims.email" +// +// Example (Logic): +// +// title: "Public documents" +// description: "Determine whether the document should be publicly visible" +// expression: "document.type != 'private' && document.type != 'internal'" +// +// Example (Data Manipulation): +// +// title: "Notification string" +// description: "Create a notification string with a timestamp." +// expression: "'New message received at ' + string(document.create_time)" +// +// The exact variables and functions that may be referenced within an expression +// are determined by the service that evaluates it. See the service +// documentation for additional information. +message Expr { + // Textual representation of an expression in Common Expression Language + // syntax. + string expression = 1; + + // Optional. Title for the expression, i.e. a short string describing + // its purpose. This can be used e.g. in UIs which allow to enter the + // expression. + string title = 2; + + // Optional. Description of the expression. This is a longer text which + // describes the expression, e.g. when hovered over it in a UI. + string description = 3; + + // Optional. String indicating the location of the expression for error + // reporting, e.g. a file name and a position in the file. + string location = 4; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py new file mode 100644 index 00000000000..01af5242d6e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/expr.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/expr.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x16google/type/expr.proto\x12\x0bgoogle.type"P\n\x04\x45xpr\x12\x12\n\nexpression\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08location\x18\x04 \x01(\tBZ\n\x0f\x63om.google.typeB\tExprProtoP\x01Z4google.golang.org/genproto/googleapis/type/expr;expr\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.expr_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\tExprProtoP\001Z4google.golang.org/genproto/googleapis/type/expr;expr\242\002\003GTP" + _globals["_EXPR"]._serialized_start = 39 + _globals["_EXPR"]._serialized_end = 119 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi new file mode 100644 index 00000000000..a1a55662b92 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi @@ -0,0 +1,39 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class Expr(_message.Message): + __slots__ = ("expression", "title", "description", "location") + EXPRESSION_FIELD_NUMBER: _ClassVar[int] + TITLE_FIELD_NUMBER: _ClassVar[int] + DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + LOCATION_FIELD_NUMBER: _ClassVar[int] + expression: str + title: str + description: str + location: str + def __init__( + self, + expression: _Optional[str] = ..., + title: _Optional[str] = ..., + description: _Optional[str] = ..., + location: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto new file mode 100644 index 00000000000..72f90b3113e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto @@ -0,0 +1,33 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/fraction;fraction"; +option java_multiple_files = true; +option java_outer_classname = "FractionProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a fraction in terms of a numerator divided by a denominator. +message Fraction { + // The numerator in the fraction, e.g. 2 in 2/3. + int64 numerator = 1; + + // The value by which the numerator is divided, e.g. 3 in 2/3. Must be + // positive. + int64 denominator = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py new file mode 100644 index 00000000000..a89d2c1d588 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/fraction.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/fraction.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1agoogle/type/fraction.proto\x12\x0bgoogle.type"2\n\x08\x46raction\x12\x11\n\tnumerator\x18\x01 \x01(\x03\x12\x13\n\x0b\x64\x65nominator\x18\x02 \x01(\x03\x42\x66\n\x0f\x63om.google.typeB\rFractionProtoP\x01Z None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto new file mode 100644 index 00000000000..8e001282caa --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto @@ -0,0 +1,45 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +import "google/protobuf/timestamp.proto"; + +option go_package = "google.golang.org/genproto/googleapis/type/interval;interval"; +option java_multiple_files = true; +option java_outer_classname = "IntervalProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a time interval, encoded as a Timestamp start (inclusive) and a +// Timestamp end (exclusive). +// +// The start must be less than or equal to the end. +// When the start equals the end, the interval is empty (matches no time). +// When both start and end are unspecified, the interval matches any time. +message Interval { + // Optional. Inclusive start of the interval. + // + // If specified, a Timestamp matching this interval will have to be the same + // or after the start. + google.protobuf.Timestamp start_time = 1; + + // Optional. Exclusive end of the interval. + // + // If specified, a Timestamp matching this interval will have to be before the + // end. + google.protobuf.Timestamp end_time = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py new file mode 100644 index 00000000000..a5da33d592a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/interval.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/interval.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1agoogle/type/interval.proto\x12\x0bgoogle.type\x1a\x1fgoogle/protobuf/timestamp.proto"h\n\x08Interval\x12.\n\nstart_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampBf\n\x0f\x63om.google.typeB\rIntervalProtoP\x01Z None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto new file mode 100644 index 00000000000..2866058ccf1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto @@ -0,0 +1,36 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/latlng;latlng"; +option java_multiple_files = true; +option java_outer_classname = "LatLngProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// An object that represents a latitude/longitude pair. This is expressed as a +// pair of doubles to represent degrees latitude and degrees longitude. Unless +// specified otherwise, this object must conform to the +// +// WGS84 standard. Values must be within normalized ranges. +message LatLng { + // The latitude in degrees. It must be in the range [-90.0, +90.0]. + double latitude = 1; + + // The longitude in degrees. It must be in the range [-180.0, +180.0]. + double longitude = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py new file mode 100644 index 00000000000..0f3911bde54 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/latlng.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/latlng.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x18google/type/latlng.proto\x12\x0bgoogle.type"-\n\x06LatLng\x12\x10\n\x08latitude\x18\x01 \x01(\x01\x12\x11\n\tlongitude\x18\x02 \x01(\x01\x42`\n\x0f\x63om.google.typeB\x0bLatLngProtoP\x01Z8google.golang.org/genproto/googleapis/type/latlng;latlng\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.latlng_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\013LatLngProtoP\001Z8google.golang.org/genproto/googleapis/type/latlng;latlng\242\002\003GTP" + _globals["_LATLNG"]._serialized_start = 41 + _globals["_LATLNG"]._serialized_end = 86 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi new file mode 100644 index 00000000000..033dd881924 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi @@ -0,0 +1,31 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class LatLng(_message.Message): + __slots__ = ("latitude", "longitude") + LATITUDE_FIELD_NUMBER: _ClassVar[int] + LONGITUDE_FIELD_NUMBER: _ClassVar[int] + latitude: float + longitude: float + def __init__( + self, latitude: _Optional[float] = ..., longitude: _Optional[float] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto new file mode 100644 index 00000000000..d3f2c2c1833 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto @@ -0,0 +1,36 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/localized_text;localized_text"; +option java_multiple_files = true; +option java_outer_classname = "LocalizedTextProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Localized variant of a text in a particular language. +message LocalizedText { + // Localized string in the language corresponding to + // [language_code][google.type.LocalizedText.language_code] below. + string text = 1; + + // The text's BCP-47 language code, such as "en-US" or "sr-Latn". + // + // For more information, see + // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + string language_code = 2; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py new file mode 100644 index 00000000000..c6a9ac88f42 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/localized_text.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/localized_text.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n google/type/localized_text.proto\x12\x0bgoogle.type"4\n\rLocalizedText\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x15\n\rlanguage_code\x18\x02 \x01(\tBw\n\x0f\x63om.google.typeB\x12LocalizedTextProtoP\x01ZHgoogle.golang.org/genproto/googleapis/type/localized_text;localized_text\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.type.localized_text_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\022LocalizedTextProtoP\001ZHgoogle.golang.org/genproto/googleapis/type/localized_text;localized_text\242\002\003GTP" + _globals["_LOCALIZEDTEXT"]._serialized_start = 49 + _globals["_LOCALIZEDTEXT"]._serialized_end = 101 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi new file mode 100644 index 00000000000..f67aa6deb76 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi @@ -0,0 +1,31 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class LocalizedText(_message.Message): + __slots__ = ("text", "language_code") + TEXT_FIELD_NUMBER: _ClassVar[int] + LANGUAGE_CODE_FIELD_NUMBER: _ClassVar[int] + text: str + language_code: str + def __init__( + self, text: _Optional[str] = ..., language_code: _Optional[str] = ... + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto new file mode 100644 index 00000000000..ed0d790a334 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto @@ -0,0 +1,41 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/money;money"; +option java_multiple_files = true; +option java_outer_classname = "MoneyProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents an amount of money with its currency type. +message Money { + // The three-letter currency code defined in ISO 4217. + string currency_code = 1; + + // The whole units of the amount. + // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. + int64 units = 2; + + // Number of nano (10^-9) units of the amount. + // The value must be between -999,999,999 and +999,999,999 inclusive. + // If `units` is positive, `nanos` must be positive or zero. + // If `units` is zero, `nanos` can be positive, zero, or negative. + // If `units` is negative, `nanos` must be negative or zero. + // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. + int32 nanos = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py new file mode 100644 index 00000000000..332526e578e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/money.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/money.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x17google/type/money.proto\x12\x0bgoogle.type"<\n\x05Money\x12\x15\n\rcurrency_code\x18\x01 \x01(\t\x12\r\n\x05units\x18\x02 \x01(\x03\x12\r\n\x05nanos\x18\x03 \x01(\x05\x42]\n\x0f\x63om.google.typeB\nMoneyProtoP\x01Z6google.golang.org/genproto/googleapis/type/money;money\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.money_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\nMoneyProtoP\001Z6google.golang.org/genproto/googleapis/type/money;money\242\002\003GTP" + _globals["_MONEY"]._serialized_start = 40 + _globals["_MONEY"]._serialized_end = 100 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi new file mode 100644 index 00000000000..dd1c02b3212 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi @@ -0,0 +1,36 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class Money(_message.Message): + __slots__ = ("currency_code", "units", "nanos") + CURRENCY_CODE_FIELD_NUMBER: _ClassVar[int] + UNITS_FIELD_NUMBER: _ClassVar[int] + NANOS_FIELD_NUMBER: _ClassVar[int] + currency_code: str + units: int + nanos: int + def __init__( + self, + currency_code: _Optional[str] = ..., + units: _Optional[int] = ..., + nanos: _Optional[int] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto new file mode 100644 index 00000000000..f8a66305f9b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto @@ -0,0 +1,65 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/month;month"; +option java_multiple_files = true; +option java_outer_classname = "MonthProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a month in the Gregorian calendar. +enum Month { + // The unspecified month. + MONTH_UNSPECIFIED = 0; + + // The month of January. + JANUARY = 1; + + // The month of February. + FEBRUARY = 2; + + // The month of March. + MARCH = 3; + + // The month of April. + APRIL = 4; + + // The month of May. + MAY = 5; + + // The month of June. + JUNE = 6; + + // The month of July. + JULY = 7; + + // The month of August. + AUGUST = 8; + + // The month of September. + SEPTEMBER = 9; + + // The month of October. + OCTOBER = 10; + + // The month of November. + NOVEMBER = 11; + + // The month of December. + DECEMBER = 12; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py new file mode 100644 index 00000000000..05d2498eedd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/month.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/month.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b"\n\x17google/type/month.proto\x12\x0bgoogle.type*\xb0\x01\n\x05Month\x12\x15\n\x11MONTH_UNSPECIFIED\x10\x00\x12\x0b\n\x07JANUARY\x10\x01\x12\x0c\n\x08\x46\x45\x42RUARY\x10\x02\x12\t\n\x05MARCH\x10\x03\x12\t\n\x05\x41PRIL\x10\x04\x12\x07\n\x03MAY\x10\x05\x12\x08\n\x04JUNE\x10\x06\x12\x08\n\x04JULY\x10\x07\x12\n\n\x06\x41UGUST\x10\x08\x12\r\n\tSEPTEMBER\x10\t\x12\x0b\n\x07OCTOBER\x10\n\x12\x0c\n\x08NOVEMBER\x10\x0b\x12\x0c\n\x08\x44\x45\x43\x45MBER\x10\x0c\x42]\n\x0f\x63om.google.typeB\nMonthProtoP\x01Z6google.golang.org/genproto/googleapis/type/month;month\xa2\x02\x03GTPb\x06proto3" +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.month_pb2", _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\nMonthProtoP\001Z6google.golang.org/genproto/googleapis/type/month;month\242\002\003GTP" + _globals["_MONTH"]._serialized_start = 41 + _globals["_MONTH"]._serialized_end = 217 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi new file mode 100644 index 00000000000..a5634ce2250 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi @@ -0,0 +1,50 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar + +from google.protobuf import descriptor as _descriptor +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper + +DESCRIPTOR: _descriptor.FileDescriptor + +class Month(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + MONTH_UNSPECIFIED: _ClassVar[Month] + JANUARY: _ClassVar[Month] + FEBRUARY: _ClassVar[Month] + MARCH: _ClassVar[Month] + APRIL: _ClassVar[Month] + MAY: _ClassVar[Month] + JUNE: _ClassVar[Month] + JULY: _ClassVar[Month] + AUGUST: _ClassVar[Month] + SEPTEMBER: _ClassVar[Month] + OCTOBER: _ClassVar[Month] + NOVEMBER: _ClassVar[Month] + DECEMBER: _ClassVar[Month] + +MONTH_UNSPECIFIED: Month +JANUARY: Month +FEBRUARY: Month +MARCH: Month +APRIL: Month +MAY: Month +JUNE: Month +JULY: Month +AUGUST: Month +SEPTEMBER: Month +OCTOBER: Month +NOVEMBER: Month +DECEMBER: Month diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto new file mode 100644 index 00000000000..7c55be07688 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto @@ -0,0 +1,118 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/phone_number;phone_number"; +option java_multiple_files = true; +option java_outer_classname = "PhoneNumberProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// An object representing a phone number, suitable as an API wire format. +// +// This representation: +// +// - should not be used for locale-specific formatting of a phone number, such +// as "+1 (650) 253-0000 ext. 123" +// +// - is not designed for efficient storage +// - may not be suitable for dialing - specialized libraries (see references) +// should be used to parse the number for that purpose +// +// To do something meaningful with this number, such as format it for various +// use-cases, convert it to an `i18n.phonenumbers.PhoneNumber` object first. +// +// For instance, in Java this would be: +// +// com.google.type.PhoneNumber wireProto = +// com.google.type.PhoneNumber.newBuilder().build(); +// com.google.i18n.phonenumbers.Phonenumber.PhoneNumber phoneNumber = +// PhoneNumberUtil.getInstance().parse(wireProto.getE164Number(), "ZZ"); +// if (!wireProto.getExtension().isEmpty()) { +// phoneNumber.setExtension(wireProto.getExtension()); +// } +// +// Reference(s): +// - https://github.com/google/libphonenumber +message PhoneNumber { + // An object representing a short code, which is a phone number that is + // typically much shorter than regular phone numbers and can be used to + // address messages in MMS and SMS systems, as well as for abbreviated dialing + // (For example "Text 611 to see how many minutes you have remaining on your + // plan."). + // + // Short codes are restricted to a region and are not internationally + // dialable, which means the same short code can exist in different regions, + // with different usage and pricing, even if those regions share the same + // country calling code (For example: US and CA). + message ShortCode { + // Required. The BCP-47 region code of the location where calls to this + // short code can be made, such as "US" and "BB". + // + // Reference(s): + // - http://www.unicode.org/reports/tr35/#unicode_region_subtag + string region_code = 1; + + // Required. The short code digits, without a leading plus ('+') or country + // calling code. For example "611". + string number = 2; + } + + // Required. Either a regular number, or a short code. New fields may be + // added to the oneof below in the future, so clients should ignore phone + // numbers for which none of the fields they coded against are set. + oneof kind { + // The phone number, represented as a leading plus sign ('+'), followed by a + // phone number that uses a relaxed ITU E.164 format consisting of the + // country calling code (1 to 3 digits) and the subscriber number, with no + // additional spaces or formatting. For example: + // + // - correct: "+15552220123" + // + // - incorrect: "+1 (555) 222-01234 x123" + // + // The ITU E.164 format limits the latter to 12 digits, but in practice not + // all countries respect that, so we relax that restriction here. + // National-only numbers are not allowed. + // + // References: + // + // - https://www.itu.int/rec/T-REC-E.164-201011-I + // + // - https://en.wikipedia.org/wiki/E.164. + // + // - https://en.wikipedia.org/wiki/List_of_country_calling_codes + string e164_number = 1; + + // A short code. + // + // Reference(s): + // - https://wikipedia.org/wiki/Short_code + ShortCode short_code = 2; + } + + // The phone number's extension. The extension is not standardized in ITU + // recommendations, except for being defined as a series of numbers with a + // maximum length of 40 digits. Other than digits, some other dialing + // characters such as ',' (indicating a wait) or '#' may be stored here. + // + // Note that no regions currently use extensions with short codes, so this + // field is normally only set in conjunction with an E.164 number. It is held + // separately from the E.164 number to allow for short code extensions in the + // future. + string extension = 3; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py new file mode 100644 index 00000000000..e87b2a13980 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/phone_number.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/phone_number.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1egoogle/type/phone_number.proto\x12\x0bgoogle.type"\xab\x01\n\x0bPhoneNumber\x12\x15\n\x0b\x65\x31\x36\x34_number\x18\x01 \x01(\tH\x00\x12\x38\n\nshort_code\x18\x02 \x01(\x0b\x32".google.type.PhoneNumber.ShortCodeH\x00\x12\x11\n\textension\x18\x03 \x01(\t\x1a\x30\n\tShortCode\x12\x13\n\x0bregion_code\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\tB\x06\n\x04kindBq\n\x0f\x63om.google.typeB\x10PhoneNumberProtoP\x01ZDgoogle.golang.org/genproto/googleapis/type/phone_number;phone_number\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.type.phone_number_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\020PhoneNumberProtoP\001ZDgoogle.golang.org/genproto/googleapis/type/phone_number;phone_number\242\002\003GTP" + _globals["_PHONENUMBER"]._serialized_start = 48 + _globals["_PHONENUMBER"]._serialized_end = 219 + _globals["_PHONENUMBER_SHORTCODE"]._serialized_start = 163 + _globals["_PHONENUMBER_SHORTCODE"]._serialized_end = 211 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi new file mode 100644 index 00000000000..aae75ceea08 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi @@ -0,0 +1,48 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Mapping as _Mapping +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional +from typing import Union as _Union + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class PhoneNumber(_message.Message): + __slots__ = ("e164_number", "short_code", "extension") + class ShortCode(_message.Message): + __slots__ = ("region_code", "number") + REGION_CODE_FIELD_NUMBER: _ClassVar[int] + NUMBER_FIELD_NUMBER: _ClassVar[int] + region_code: str + number: str + def __init__( + self, region_code: _Optional[str] = ..., number: _Optional[str] = ... + ) -> None: ... + + E164_NUMBER_FIELD_NUMBER: _ClassVar[int] + SHORT_CODE_FIELD_NUMBER: _ClassVar[int] + EXTENSION_FIELD_NUMBER: _ClassVar[int] + e164_number: str + short_code: PhoneNumber.ShortCode + extension: str + def __init__( + self, + e164_number: _Optional[str] = ..., + short_code: _Optional[_Union[PhoneNumber.ShortCode, _Mapping]] = ..., + extension: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto new file mode 100644 index 00000000000..57059625235 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto @@ -0,0 +1,134 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/postaladdress;postaladdress"; +option java_multiple_files = true; +option java_outer_classname = "PostalAddressProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a postal address, such as for postal delivery or payments +// addresses. With a postal address, a postal service can deliver items to a +// premise, P.O. box, or similar. A postal address is not intended to model +// geographical locations like roads, towns, or mountains. +// +// In typical usage, an address would be created by user input or from importing +// existing data, depending on the type of process. +// +// Advice on address input or editing: +// +// - Use an internationalization-ready address widget such as +// https://github.com/google/libaddressinput. +// - Users should not be presented with UI elements for input or editing of +// fields outside countries where that field is used. +// +// For more guidance on how to use this schema, see: +// https://support.google.com/business/answer/6397478. +message PostalAddress { + // The schema revision of the `PostalAddress`. This must be set to 0, which is + // the latest revision. + // + // All new revisions **must** be backward compatible with old revisions. + int32 revision = 1; + + // Required. CLDR region code of the country/region of the address. This + // is never inferred and it is up to the user to ensure the value is + // correct. See https://cldr.unicode.org/ and + // https://www.unicode.org/cldr/charts/30/supplemental/territory_information.html + // for details. Example: "CH" for Switzerland. + string region_code = 2; + + // Optional. BCP-47 language code of the contents of this address (if + // known). This is often the UI language of the input form or is expected + // to match one of the languages used in the address' country/region, or their + // transliterated equivalents. + // This can affect formatting in certain countries, but is not critical + // to the correctness of the data and will never affect any validation or + // other non-formatting related operations. + // + // If this value is not known, it should be omitted (rather than specifying a + // possibly incorrect default). + // + // Examples: "zh-Hant", "ja", "ja-Latn", "en". + string language_code = 3; + + // Optional. Postal code of the address. Not all countries use or require + // postal codes to be present, but where they are used, they may trigger + // additional validation with other parts of the address (for example, + // state or zip code validation in the United States). + string postal_code = 4; + + // Optional. Additional, country-specific, sorting code. This is not used + // in most regions. Where it is used, the value is either a string like + // "CEDEX", optionally followed by a number (for example, "CEDEX 7"), or just + // a number alone, representing the "sector code" (Jamaica), "delivery area + // indicator" (Malawi) or "post office indicator" (Côte d'Ivoire). + string sorting_code = 5; + + // Optional. Highest administrative subdivision which is used for postal + // addresses of a country or region. + // For example, this can be a state, a province, an oblast, or a prefecture. + // For Spain, this is the province and not the autonomous + // community (for example, "Barcelona" and not "Catalonia"). + // Many countries don't use an administrative area in postal addresses. For + // example, in Switzerland, this should be left unpopulated. + string administrative_area = 6; + + // Optional. Generally refers to the city or town portion of the address. + // Examples: US city, IT comune, UK post town. + // In regions of the world where localities are not well defined or do not fit + // into this structure well, leave `locality` empty and use `address_lines`. + string locality = 7; + + // Optional. Sublocality of the address. + // For example, this can be a neighborhood, borough, or district. + string sublocality = 8; + + // Unstructured address lines describing the lower levels of an address. + // + // Because values in `address_lines` do not have type information and may + // sometimes contain multiple values in a single field (for example, + // "Austin, TX"), it is important that the line order is clear. The order of + // address lines should be "envelope order" for the country or region of the + // address. In places where this can vary (for example, Japan), + // `address_language` is used to make it explicit (for example, "ja" for + // large-to-small ordering and "ja-Latn" or "en" for small-to-large). In this + // way, the most specific line of an address can be selected based on the + // language. + // + // The minimum permitted structural representation of an address consists + // of a `region_code` with all remaining information placed in the + // `address_lines`. It would be possible to format such an address very + // approximately without geocoding, but no semantic reasoning could be + // made about any of the address components until it was at least + // partially resolved. + // + // Creating an address only containing a `region_code` and `address_lines` and + // then geocoding is the recommended way to handle completely unstructured + // addresses (as opposed to guessing which parts of the address should be + // localities or administrative areas). + repeated string address_lines = 9; + + // Optional. The recipient at the address. + // This field may, under certain circumstances, contain multiline information. + // For example, it might contain "care of" information. + repeated string recipients = 10; + + // Optional. The name of the organization at the address. + string organization = 11; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py new file mode 100644 index 00000000000..ffd6b8c96bc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/postal_address.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/postal_address.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n google/type/postal_address.proto\x12\x0bgoogle.type"\xfd\x01\n\rPostalAddress\x12\x10\n\x08revision\x18\x01 \x01(\x05\x12\x13\n\x0bregion_code\x18\x02 \x01(\t\x12\x15\n\rlanguage_code\x18\x03 \x01(\t\x12\x13\n\x0bpostal_code\x18\x04 \x01(\t\x12\x14\n\x0csorting_code\x18\x05 \x01(\t\x12\x1b\n\x13\x61\x64ministrative_area\x18\x06 \x01(\t\x12\x10\n\x08locality\x18\x07 \x01(\t\x12\x13\n\x0bsublocality\x18\x08 \x01(\t\x12\x15\n\raddress_lines\x18\t \x03(\t\x12\x12\n\nrecipients\x18\n \x03(\t\x12\x14\n\x0corganization\x18\x0b \x01(\tBu\n\x0f\x63om.google.typeB\x12PostalAddressProtoP\x01ZFgoogle.golang.org/genproto/googleapis/type/postaladdress;postaladdress\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.type.postal_address_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\022PostalAddressProtoP\001ZFgoogle.golang.org/genproto/googleapis/type/postaladdress;postaladdress\242\002\003GTP" + _globals["_POSTALADDRESS"]._serialized_start = 50 + _globals["_POSTALADDRESS"]._serialized_end = 303 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi new file mode 100644 index 00000000000..946cbf7c13c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi @@ -0,0 +1,74 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import Iterable as _Iterable +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf.internal import containers as _containers + +DESCRIPTOR: _descriptor.FileDescriptor + +class PostalAddress(_message.Message): + __slots__ = ( + "revision", + "region_code", + "language_code", + "postal_code", + "sorting_code", + "administrative_area", + "locality", + "sublocality", + "address_lines", + "recipients", + "organization", + ) + REVISION_FIELD_NUMBER: _ClassVar[int] + REGION_CODE_FIELD_NUMBER: _ClassVar[int] + LANGUAGE_CODE_FIELD_NUMBER: _ClassVar[int] + POSTAL_CODE_FIELD_NUMBER: _ClassVar[int] + SORTING_CODE_FIELD_NUMBER: _ClassVar[int] + ADMINISTRATIVE_AREA_FIELD_NUMBER: _ClassVar[int] + LOCALITY_FIELD_NUMBER: _ClassVar[int] + SUBLOCALITY_FIELD_NUMBER: _ClassVar[int] + ADDRESS_LINES_FIELD_NUMBER: _ClassVar[int] + RECIPIENTS_FIELD_NUMBER: _ClassVar[int] + ORGANIZATION_FIELD_NUMBER: _ClassVar[int] + revision: int + region_code: str + language_code: str + postal_code: str + sorting_code: str + administrative_area: str + locality: str + sublocality: str + address_lines: _containers.RepeatedScalarFieldContainer[str] + recipients: _containers.RepeatedScalarFieldContainer[str] + organization: str + def __init__( + self, + revision: _Optional[int] = ..., + region_code: _Optional[str] = ..., + language_code: _Optional[str] = ..., + postal_code: _Optional[str] = ..., + sorting_code: _Optional[str] = ..., + administrative_area: _Optional[str] = ..., + locality: _Optional[str] = ..., + sublocality: _Optional[str] = ..., + address_lines: _Optional[_Iterable[str]] = ..., + recipients: _Optional[_Iterable[str]] = ..., + organization: _Optional[str] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto new file mode 100644 index 00000000000..d24629821ff --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto @@ -0,0 +1,94 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/quaternion;quaternion"; +option java_multiple_files = true; +option java_outer_classname = "QuaternionProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// A quaternion, represented by four 64-bit floating point values. +// +// A quaternion is defined as the quotient of two directed lines in a +// three-dimensional space or equivalently as the quotient of two Euclidean +// vectors (https://en.wikipedia.org/wiki/Quaternion). +// +// Quaternions are often used in calculations involving three-dimensional +// rotations (https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation), +// as they provide greater mathematical robustness by avoiding the gimbal lock +// problems that can be encountered when using Euler angles +// (https://en.wikipedia.org/wiki/Gimbal_lock). +// +// Quaternions are generally represented in this form: +// +// w + xi + yj + zk +// +// where x, y, z, and w are real numbers, and i, j, and k are three imaginary +// numbers. +// +// The naming choice `(x, y, z, w)` comes from the desire to avoid confusion for +// those interested in the geometric properties of the quaternion in the 3D +// Cartesian space. Other texts often use alternative names or subscripts, such +// as `(a, b, c, d)`, `(1, i, j, k)`, or `(0, 1, 2, 3)`, which are perhaps +// better suited for mathematical interpretations. +// +// To avoid any confusion, as well as to maintain compatibility with a large +// number of software libraries, the quaternions represented using the protocol +// buffer below *must* follow the Hamilton convention, which defines `ij = k` +// (i.e. a right-handed algebra), and therefore: +// +// i^2 = j^2 = k^2 = ijk = −1 +// ij = −ji = k +// jk = −kj = i +// ki = −ik = j +// +// Please DO NOT use this to represent quaternions that follow the JPL +// convention, or any of the other quaternion flavors out there. +// +// Definitions: +// +// - Quaternion norm (or magnitude): `sqrt(x^2 + y^2 + z^2 + w^2)`. +// - Unit (or normalized) quaternion: a quaternion whose norm is 1. +// - Pure quaternion: a quaternion whose scalar component (`w`) is 0. +// - Rotation quaternion: a unit quaternion used to represent rotation. +// - Orientation quaternion: a unit quaternion used to represent orientation. +// +// A quaternion can be normalized by dividing it by its norm. The resulting +// quaternion maintains the same direction, but has a norm of 1, i.e. it moves +// on the unit sphere. This is generally necessary for rotation and orientation +// quaternions, to avoid rounding errors: +// https://en.wikipedia.org/wiki/Rotation_formalisms_in_three_dimensions +// +// Note that `(x, y, z, w)` and `(-x, -y, -z, -w)` represent the same rotation, +// but normalization would be even more useful, e.g. for comparison purposes, if +// it would produce a unique representation. It is thus recommended that `w` be +// kept positive, which can be achieved by changing all the signs when `w` is +// negative. +message Quaternion { + // The x component. + double x = 1; + + // The y component. + double y = 2; + + // The z component. + double z = 3; + + // The scalar component. + double w = 4; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py new file mode 100644 index 00000000000..92b0b7f79d3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/quaternion.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/quaternion.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1cgoogle/type/quaternion.proto\x12\x0bgoogle.type"8\n\nQuaternion\x12\t\n\x01x\x18\x01 \x01(\x01\x12\t\n\x01y\x18\x02 \x01(\x01\x12\t\n\x01z\x18\x03 \x01(\x01\x12\t\n\x01w\x18\x04 \x01(\x01\x42l\n\x0f\x63om.google.typeB\x0fQuaternionProtoP\x01Z@google.golang.org/genproto/googleapis/type/quaternion;quaternion\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.type.quaternion_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\017QuaternionProtoP\001Z@google.golang.org/genproto/googleapis/type/quaternion;quaternion\242\002\003GTP" + _globals["_QUATERNION"]._serialized_start = 45 + _globals["_QUATERNION"]._serialized_end = 101 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi new file mode 100644 index 00000000000..8a7bfbe24c2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi @@ -0,0 +1,39 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class Quaternion(_message.Message): + __slots__ = ("x", "y", "z", "w") + X_FIELD_NUMBER: _ClassVar[int] + Y_FIELD_NUMBER: _ClassVar[int] + Z_FIELD_NUMBER: _ClassVar[int] + W_FIELD_NUMBER: _ClassVar[int] + x: float + y: float + z: float + w: float + def __init__( + self, + x: _Optional[float] = ..., + y: _Optional[float] = ..., + z: _Optional[float] = ..., + w: _Optional[float] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto new file mode 100644 index 00000000000..94090bd085e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto @@ -0,0 +1,47 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.type; + +option go_package = "google.golang.org/genproto/googleapis/type/timeofday;timeofday"; +option java_multiple_files = true; +option java_outer_classname = "TimeOfDayProto"; +option java_package = "com.google.type"; +option objc_class_prefix = "GTP"; + +// Represents a time of day. The date and time zone are either not significant +// or are specified elsewhere. An API may choose to allow leap seconds. Related +// types are [google.type.Date][google.type.Date] and +// `google.protobuf.Timestamp`. +message TimeOfDay { + // Hours of a day in 24 hour format. Must be greater than or equal to 0 and + // typically must be less than or equal to 23. An API may choose to allow the + // value "24:00:00" for scenarios like business closing time. + int32 hours = 1; + + // Minutes of an hour. Must be greater than or equal to 0 and less than or + // equal to 59. + int32 minutes = 2; + + // Seconds of a minute. Must be greater than or equal to 0 and typically must + // be less than or equal to 59. An API may allow the value 60 if it allows + // leap-seconds. + int32 seconds = 3; + + // Fractions of seconds, in nanoseconds. Must be greater than or equal to 0 + // and less than or equal to 999,999,999. + int32 nanos = 4; +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py new file mode 100644 index 00000000000..e76f2d45152 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: google/type/timeofday.proto +# Protobuf Python Version: 6.33.5 +"""Generated protocol buffer code.""" + +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder + +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/timeofday.proto" +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1bgoogle/type/timeofday.proto\x12\x0bgoogle.type"K\n\tTimeOfDay\x12\r\n\x05hours\x18\x01 \x01(\x05\x12\x0f\n\x07minutes\x18\x02 \x01(\x05\x12\x0f\n\x07seconds\x18\x03 \x01(\x05\x12\r\n\x05nanos\x18\x04 \x01(\x05\x42i\n\x0f\x63om.google.typeB\x0eTimeOfDayProtoP\x01Z>google.golang.org/genproto/googleapis/type/timeofday;timeofday\xa2\x02\x03GTPb\x06proto3' +) + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "opentelemetry.agent._vendor.google.type.timeofday_pb2", _globals +) +if not _descriptor._USE_C_DESCRIPTORS: + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = b"\n\017com.google.typeB\016TimeOfDayProtoP\001Z>google.golang.org/genproto/googleapis/type/timeofday;timeofday\242\002\003GTP" + _globals["_TIMEOFDAY"]._serialized_start = 44 + _globals["_TIMEOFDAY"]._serialized_end = 119 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi new file mode 100644 index 00000000000..1a5e2618956 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi @@ -0,0 +1,39 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import ClassVar as _ClassVar +from typing import Optional as _Optional + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message + +DESCRIPTOR: _descriptor.FileDescriptor + +class TimeOfDay(_message.Message): + __slots__ = ("hours", "minutes", "seconds", "nanos") + HOURS_FIELD_NUMBER: _ClassVar[int] + MINUTES_FIELD_NUMBER: _ClassVar[int] + SECONDS_FIELD_NUMBER: _ClassVar[int] + NANOS_FIELD_NUMBER: _ClassVar[int] + hours: int + minutes: int + seconds: int + nanos: int + def __init__( + self, + hours: _Optional[int] = ..., + minutes: _Optional[int] = ..., + seconds: _Optional[int] = ..., + nanos: _Optional[int] = ..., + ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md new file mode 100644 index 00000000000..f706835ab3a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md @@ -0,0 +1,31 @@ +BSD 3-Clause License + +Copyright (c) 2013-2026, Kim Davies and contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py new file mode 100644 index 00000000000..d6c890a9a93 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py @@ -0,0 +1,47 @@ +from .core import ( + IDNABidiError, + IDNAError, + InvalidCodepoint, + InvalidCodepointContext, + alabel, + check_bidi, + check_hyphen_ok, + check_initial_combiner, + check_label, + check_nfc, + decode, + encode, + ulabel, + uts46_remap, + valid_contextj, + valid_contexto, + valid_label_length, + valid_string_length, +) +from .idnadata import __version__ as unicode_version +from .intranges import intranges_contain +from .package_data import __version__ + +__all__ = [ + "__version__", + "unicode_version", + "IDNABidiError", + "IDNAError", + "InvalidCodepoint", + "InvalidCodepointContext", + "alabel", + "check_bidi", + "check_hyphen_ok", + "check_initial_combiner", + "check_label", + "check_nfc", + "decode", + "encode", + "intranges_contain", + "ulabel", + "uts46_remap", + "valid_contextj", + "valid_contexto", + "valid_label_length", + "valid_string_length", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py new file mode 100644 index 00000000000..8efc1eed736 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py @@ -0,0 +1,225 @@ +from __future__ import annotations + +import codecs +from typing import Any + +from .core import IDNAError, _max_domain_length, _unicode_dots_re, alabel, decode, encode, ulabel + + +class Codec(codecs.Codec): + """Stateless IDNA 2008 codec. + + Implements the :class:`codecs.Codec` protocol so that the whole-domain + encoder (:func:`idna.encode`) and decoder (:func:`idna.decode`) are + accessible through the standard codec machinery as ``"idna2008"``. + + Only the ``"strict"`` error handler is supported; any other handler + raises :exc:`~idna.IDNAError`. + """ + + def encode(self, data: str, errors: str = "strict") -> tuple[bytes, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") + + if not data: + return b"", 0 + + return encode(data), len(data) + + def decode(self, data: bytes, errors: str = "strict") -> tuple[str, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") + + if not data: + return "", 0 + + return decode(data), len(data) + + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + """Incremental IDNA 2008 encoder. + + Buffers a partial trailing label across calls until either the next + label separator is seen or ``final=True``, so that streamed input is + encoded one whole label at a time. Any of the four Unicode label + separators (``U+002E``, ``U+3002``, ``U+FF0E``, ``U+FF61``) ends a + label; the result always uses ``U+002E`` as the separator. + + The 253-octet domain length limit (254 with a trailing dot) that + :func:`idna.encode` enforces is applied to the accumulated output, so + that streaming a name and encoding it in one shot either both succeed + with the same result or both raise :exc:`~idna.IDNAError`. + + Only the ``"strict"`` error handler is supported. + """ + + def __init__(self, errors: str = "strict") -> None: + super().__init__(errors) + self._emitted = 0 # octets returned so far + self._trailing_dot = False # whether the output so far ends with "." + + def reset(self) -> None: + super().reset() + self._emitted = 0 + self._trailing_dot = False + + def getstate(self) -> Any: + if not self.buffer and not self._emitted: + return 0 + return (self.buffer, self._emitted, self._trailing_dot) + + def setstate(self, state: Any) -> None: + if state: + self.buffer, self._emitted, self._trailing_dot = state + else: + self.reset() + + def _buffer_encode(self, data: str, errors: str, final: bool) -> tuple[bytes, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") + + result_bytes = b"" + size = 0 + if data: + labels = _unicode_dots_re.split(data) + trailing_dot = b"" + if labels: + if not labels[-1]: + trailing_dot = b"." + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = b"." + + result = [] + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + result_bytes = b".".join(result) + trailing_dot + size += len(trailing_dot) + + # Mirror encode(): the whole name may not exceed 253 octets, or 254 + # when it ends with a dot. Until the input is final a trailing dot + # may still arrive, so only the 254-octet ceiling applies before then. + self._emitted += len(result_bytes) + if result_bytes: + self._trailing_dot = result_bytes.endswith(b".") + may_end_with_dot = self._trailing_dot or not final + if self._emitted > _max_domain_length + may_end_with_dot: + raise IDNAError("Domain too long", code="domain_too_long") + return result_bytes, size + + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + """Incremental IDNA 2008 decoder. + + Buffers a partial trailing label across calls until either the next + label separator is seen or ``final=True``, so that streamed input is + decoded one whole label at a time. + + The 254-octet input length limit that :func:`idna.decode` enforces is + applied to the accumulated input, so that streaming a name and decoding + it in one shot either both succeed with the same result or both raise + :exc:`~idna.IDNAError`. + + Only the ``"strict"`` error handler is supported. + """ + + def __init__(self, errors: str = "strict") -> None: + super().__init__(errors) + self._consumed = 0 # input octets consumed so far + + def reset(self) -> None: + super().reset() + self._consumed = 0 + + def getstate(self) -> tuple[bytes, int]: + return (self.buffer, self._consumed) + + def setstate(self, state: tuple[bytes, int]) -> None: + self.buffer, self._consumed = state + + def _buffer_decode(self, data: Any, errors: str, final: bool) -> tuple[str, int]: # ty: ignore[invalid-method-override] + if errors != "strict": + raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") + + if not data: + return ("", 0) + + if not isinstance(data, str): + try: + data = str(data, "ascii") + except UnicodeDecodeError as err: + raise IDNAError("Invalid ASCII in A-label", code="invalid_ascii") from err + + # Mirror decode(), which rejects input longer than 254 characters + # (253 plus a possible trailing dot) before looking at any label. + # ``data`` is the unconsumed buffer plus the new input, so this is + # the total seen so far. + if self._consumed + len(data) > _max_domain_length + 1: + raise IDNAError("Domain too long", code="domain_too_long") + + labels = _unicode_dots_re.split(data) + trailing_dot = "" + if labels: + if not labels[-1]: + trailing_dot = "." + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = "." + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result_str = ".".join(result) + trailing_dot + size += len(trailing_dot) + self._consumed += size + return (result_str, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +def search_function(name: str) -> codecs.CodecInfo | None: + """Codec search function registered with :mod:`codecs`. + + Returns a :class:`codecs.CodecInfo` for the ``"idna2008"`` codec name + so that ``str.encode("idna2008")`` and ``bytes.decode("idna2008")`` + invoke the IDNA 2008 codec defined in this module. + + :param name: The codec name being looked up. + :returns: A :class:`codecs.CodecInfo` instance if ``name`` is + ``"idna2008"``, otherwise ``None``. + """ + if name != "idna2008": + return None + return codecs.CodecInfo( + name=name, + encode=Codec().encode, + decode=Codec().decode, # type: ignore + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +codecs.register(search_function) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py new file mode 100644 index 00000000000..5bedee9bad9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +from typing import Any + +from .core import decode, encode + + +def ToASCII(label: str) -> bytes: + """Compatibility shim for :rfc:`3490` ``ToASCII``. + + Delegates to :func:`idna.encode` (IDNA 2008). Provided to ease porting + of code written against the legacy :mod:`encodings.idna` API; new code + should call :func:`idna.encode` directly. + + :param label: The label or domain to encode. + :returns: The encoded form as ASCII :class:`bytes`. + """ + return encode(label) + + +def ToUnicode(label: bytes | bytearray) -> str: + """Compatibility shim for :rfc:`3490` ``ToUnicode``. + + Delegates to :func:`idna.decode` (IDNA 2008). Provided to ease porting + of code written against the legacy :mod:`encodings.idna` API; new code + should call :func:`idna.decode` directly. + + :param label: The label or domain to decode. + :returns: The decoded Unicode form. + """ + return decode(label) + + +def nameprep(s: Any) -> None: + """Stub for :rfc:`3491` Nameprep, which is not used by IDNA 2008. + + IDNA 2008 (:rfc:`5891`) replaces Nameprep with the per-codepoint + validity classes from :rfc:`5892`; this function exists only to + return a clear error if legacy code attempts to call it. + + :raises NotImplementedError: Always. + """ + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py new file mode 100644 index 00000000000..d4a6f0e3a7d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py @@ -0,0 +1,863 @@ +from __future__ import annotations + +import bisect +import re +import unicodedata +import warnings +from typing import Literal + +from . import idnadata +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b"xn--" +_max_input_length = 1024 +_max_domain_length = 253 # RFC 1035 octets, excluding any trailing dot +_STATUS_VALID, _STATUS_MAPPED, _STATUS_DEVIATION, _STATUS_IGNORED = b"VMDI" +_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") +_std3_disallowed_re = re.compile("[\x00-\x2c\x2f\x3a-\x40A-Z\x5b-\x60\x7b-\x7f]") +_bidi_rtl_first = frozenset({"R", "AL"}) +_bidi_rtl_categories = frozenset({"R", "AL", "AN"}) +_bidi_rtl_allowed = frozenset({"R", "AL", "AN", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) +_bidi_rtl_valid_ending = frozenset({"R", "AL", "EN", "AN"}) +_bidi_rtl_numeric = frozenset({"AN", "EN"}) +_bidi_ltr_allowed = frozenset({"L", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) +_bidi_ltr_valid_ending = frozenset({"L", "EN"}) +_bidi_joiner_l_or_d = frozenset({"L", "D"}) +_bidi_joiner_r_or_d = frozenset({"R", "D"}) + + +def _joining_type(cp: int) -> str | None: + for jt, ranges in idnadata.joining_types.items(): + if intranges_contain(cp, ranges): + return jt + return None + + +# Machine-readable identifiers for the rule an :class:`IDNAError` reports. +# These strings are stable and documented; exception message wording is not. +_ErrorCode = Literal[ + "input_too_long", + "label_too_long", + "domain_too_long", + "empty_label", + "empty_domain", + "not_nfc", + "hyphen_3_4", + "hyphen_start_end", + "leading_combiner", + "disallowed_codepoint", + "contextj", + "contexto", + "unknown_codepoint", + "bidi_rule_1", + "bidi_rule_2", + "bidi_rule_3", + "bidi_rule_4", + "bidi_rule_5", + "bidi_rule_6", + "bidi_unknown_direction", + "invalid_alabel", + "non_canonical_alabel", + "invalid_ascii", + "invalid_utf8", + "uts46_disallowed", + "uts46_std3", + "unsupported_errors", +] + + +class IDNAError(UnicodeError): + """Base exception for all IDNA-encoding related problems. + + ``str(err)`` is a human-readable description of the failure. The + exception also carries machine-readable attributes so callers do not + need to parse the message: + + * ``code`` -- a short, stable identifier for the rule that failed, such + as ``"disallowed_codepoint"`` or ``"bidi_rule_2"``; the full list is + documented in the README. Message wording, by contrast, may change + between releases. + * ``text`` -- the label (or, for UTS #46 processing, the domain) that + was being validated; + * ``codepoint`` -- the offending codepoint, as an ``int``; + * ``position`` -- the 1-based index of the offending character within + ``text``, matching the position quoted in the message. + + Each is ``None`` when it does not apply. + """ + + code: str | None + text: str | None + codepoint: int | None + position: int | None + + def __init__( + self, + *args: object, + code: _ErrorCode | None = None, + text: str | None = None, + codepoint: int | None = None, + position: int | None = None, + ) -> None: + super().__init__(*args) + self.code = code + self.text = text + self.codepoint = codepoint + self.position = position + + +class IDNABidiError(IDNAError): + """Exception when bidirectional requirements are not satisfied""" + + +class InvalidCodepoint(IDNAError): + """Exception when a disallowed or unallocated codepoint is used""" + + +class InvalidCodepointContext(IDNAError): + """Exception when the codepoint is not valid in the context it is used""" + + +def _combining_class(cp: int) -> int: + v = unicodedata.combining(chr(cp)) + if v == 0 and not unicodedata.name(chr(cp)): + raise ValueError("Unknown character in unicodedata") + return v + + +def _is_script(cp: str, script: str) -> bool: + return intranges_contain(ord(cp), idnadata.scripts[script]) + + +def _punycode(s: str) -> bytes: + return s.encode("punycode") + + +def _unot(s: int) -> str: + return f"U+{s:04X}" + + +def valid_label_length(label: bytes | str) -> bool: + """Check that a label does not exceed the maximum permitted length. + + Per :rfc:`1035` (and :rfc:`5891` §4.2.4) a DNS label must not exceed + 63 octets. The argument may be either a :class:`str` (a U-label, where + length is measured in characters) or :class:`bytes` (an A-label, where + length is measured in octets). + + :param label: The label to check. + :returns: ``True`` if the label is within the length limit, otherwise + ``False``. + """ + return len(label) <= 63 + + +def valid_string_length(domain: bytes | str, trailing_dot: bool) -> bool: + """Check that a full domain name does not exceed the maximum length. + + Per :rfc:`1035`, a domain name is limited to 253 octets when no trailing + dot is present, or 254 octets when one is included. + + :param domain: The full (possibly multi-label) domain name. + :param trailing_dot: ``True`` if ``domain`` includes a trailing ``.``. + :returns: ``True`` if the domain is within the length limit, otherwise + ``False``. + """ + return len(domain) <= _max_domain_length + trailing_dot + + +def check_bidi(label: str, check_ltr: bool = False) -> bool: + """Validate the Bidi Rule from :rfc:`5893` for a single label. + + The Bidi Rule constrains how bidirectional characters (Hebrew, Arabic, + etc.) may appear within a label. By default the check is only applied + when the label contains at least one right-to-left character (Unicode + bidirectional categories ``R``, ``AL``, or ``AN``); set ``check_ltr`` + to ``True`` to apply it to LTR-only labels as well. + + :param label: The label to validate, as a Unicode string. + :param check_ltr: If ``True``, apply the rules even when the label + contains no RTL characters. + :returns: ``True`` if the label satisfies the Bidi Rule. + :raises IDNABidiError: If any of Bidi Rule conditions 1-6 are violated, + or if the directional category of a codepoint cannot be determined. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long", code="input_too_long") + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for idx, cp in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == "": + # String likely comes from a newer version of Unicode + raise IDNABidiError( + f"Unknown directionality in label {label!r} at position {idx}", + code="bidi_unknown_direction", + text=label, + codepoint=ord(cp), + position=idx, + ) + if direction in _bidi_rtl_categories: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in _bidi_rtl_first: + rtl = True + elif direction == "L": + rtl = False + else: + raise IDNABidiError( + f"First codepoint in label {label!r} must be directionality L, R or AL", + code="bidi_rule_1", + text=label, + codepoint=ord(label[0]), + position=1, + ) + + valid_ending = False + ending_idx = 1 + number_type: str | None = None + for idx, cp in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if direction not in _bidi_rtl_allowed: + raise IDNABidiError( + f"Invalid direction for codepoint at position {idx} in a right-to-left label", + code="bidi_rule_2", + text=label, + codepoint=ord(cp), + position=idx, + ) + # Bidi rule 3 + if direction in _bidi_rtl_valid_ending: + valid_ending = True + ending_idx = idx + elif direction != "NSM": + valid_ending = False + ending_idx = idx + # Bidi rule 4 + if direction in _bidi_rtl_numeric: + if not number_type: + number_type = direction + elif number_type != direction: + raise IDNABidiError( + "Can not mix numeral types in a right-to-left label", + code="bidi_rule_4", + text=label, + codepoint=ord(cp), + position=idx, + ) + else: + # Bidi rule 5 + if direction not in _bidi_ltr_allowed: + raise IDNABidiError( + f"Invalid direction for codepoint at position {idx} in a left-to-right label", + code="bidi_rule_5", + text=label, + codepoint=ord(cp), + position=idx, + ) + # Bidi rule 6 + if direction in _bidi_ltr_valid_ending: + valid_ending = True + ending_idx = idx + elif direction != "NSM": + valid_ending = False + ending_idx = idx + + if not valid_ending: + # Rules 3 and 6 concern the last character that is not a + # non-spacing mark, which is what ``ending_idx`` tracks. + raise IDNABidiError( + "Label ends with illegal codepoint directionality", + code="bidi_rule_3" if rtl else "bidi_rule_6", + text=label, + codepoint=ord(label[ending_idx - 1]), + position=ending_idx, + ) + + return True + + +def check_initial_combiner(label: str) -> bool: + """Reject labels that begin with a combining mark. + + Per :rfc:`5891` §4.2.3.2 a label must not start with a character of + Unicode general category ``M`` (Mark). + + :param label: The label to check. + :returns: ``True`` if the first character is not a combining mark. + :raises IDNAError: If the label begins with a combining character. + """ + if label and unicodedata.category(label[0])[0] == "M": + raise IDNAError( + "Label begins with an illegal combining character", + code="leading_combiner", + text=label, + codepoint=ord(label[0]), + position=1, + ) + return True + + +def check_hyphen_ok(label: str) -> bool: + """Validate the hyphen restrictions for a label. + + Per :rfc:`5891` §4.2.3.1 a label must not start or end with a hyphen + (``U+002D``), and must not have hyphens in both the third and fourth + positions (the prefix reserved for A-labels). + + :param label: The label to check. + :returns: ``True`` if the hyphen restrictions are satisfied. + :raises IDNAError: If any of the hyphen restrictions are violated. + """ + if label[2:4] == "--": + raise IDNAError("Label has disallowed hyphens in 3rd and 4th position", code="hyphen_3_4") + if label.startswith("-") or label.endswith("-"): + raise IDNAError("Label must not start or end with a hyphen", code="hyphen_start_end") + return True + + +def check_nfc(label: str) -> None: + """Require that a label is in Unicode Normalization Form C. + + :param label: The label to check. + :raises IDNAError: If ``label`` differs from its NFC normalisation. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long", code="input_too_long") + if unicodedata.normalize("NFC", label) != label: + raise IDNAError("Label must be in Normalization Form C", code="not_nfc") + + +def valid_contextj(label: str, pos: int) -> bool: + """Validate the CONTEXTJ rules from :rfc:`5892` Appendix A. + + These rules govern the contextual use of the joiner codepoints + ``U+200C`` (ZERO WIDTH NON-JOINER, Appendix A.1) and ``U+200D`` + (ZERO WIDTH JOINER, Appendix A.2) within a label. + + :param label: The label containing the codepoint. + :param pos: Index of the joiner codepoint within ``label``. + :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTJ + rule, ``False`` otherwise (including when the codepoint at + ``pos`` is not a recognised joiner). + :raises ValueError: If an adjacent codepoint has no Unicode name when + determining its combining class. + :raises IDNAError: If ``label`` exceeds the defensive input length limit. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long", code="input_too_long") + cp_value = ord(label[pos]) + + if cp_value == 0x200C: + if pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos - 1, -1, -1): + joining_type = _joining_type(ord(label[i])) + if joining_type == "T": + continue + if joining_type in _bidi_joiner_l_or_d: + ok = True + break + break + + if not ok: + return False + + ok = False + for i in range(pos + 1, len(label)): + joining_type = _joining_type(ord(label[i])) + if joining_type == "T": + continue + if joining_type in _bidi_joiner_r_or_d: + ok = True + break + break + return ok + + if cp_value == 0x200D: + return pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class + + return False + + +def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: + """Validate the CONTEXTO rules from :rfc:`5892` Appendix A. + + Covers the contextual rules for codepoints such as MIDDLE DOT + (``U+00B7``), Greek lower numeral sign, Hebrew punctuation, Katakana + middle dot, and the Arabic-Indic / Extended Arabic-Indic digit ranges. + + :param label: The label containing the codepoint. + :param pos: Index of the codepoint within ``label``. + :param exception: Reserved for forward compatibility; currently unused. + :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTO + rule, ``False`` otherwise (including when the codepoint is not a + recognised CONTEXTO codepoint). + :raises IDNAError: If ``label`` exceeds the defensive input length limit. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long", code="input_too_long") + cp_value = ord(label[pos]) + + if cp_value == 0x00B7: + return 0 < pos < len(label) - 1 and ord(label[pos - 1]) == 0x006C and ord(label[pos + 1]) == 0x006C + + if cp_value == 0x0375: + if pos < len(label) - 1 and len(label) > 1: + return _is_script(label[pos + 1], "Greek") + return False + + if cp_value in {0x05F3, 0x05F4}: + if pos > 0: + return _is_script(label[pos - 1], "Hebrew") + return False + + if cp_value == 0x30FB: + for cp in label: + if cp == "\u30fb": + continue + if _is_script(cp, "Hiragana") or _is_script(cp, "Katakana") or _is_script(cp, "Han"): + return True + return False + + if 0x660 <= cp_value <= 0x669: + return not any(0x6F0 <= ord(cp) <= 0x06F9 for cp in label) + + if 0x6F0 <= cp_value <= 0x6F9: + return not any(0x660 <= ord(cp) <= 0x0669 for cp in label) + + return False + + +def check_label(label: str | bytes | bytearray) -> None: + """Run the full set of IDNA 2008 validity checks on a single label. + + Applies, in order: NFC normalisation (:func:`check_nfc`), hyphen + restrictions (:func:`check_hyphen_ok`), the no-leading-combiner rule + (:func:`check_initial_combiner`), per-codepoint validity (PVALID, + CONTEXTJ, CONTEXTO classes from :rfc:`5892`), and the Bidi Rule + (:func:`check_bidi`). + + :param label: The label to validate. ``bytes`` or ``bytearray`` input + is decoded as UTF-8 first. + :raises IDNAError: If the label is empty or fails a structural rule. + :raises InvalidCodepoint: If the label contains a DISALLOWED or + UNASSIGNED codepoint. + :raises InvalidCodepointContext: If a CONTEXTJ or CONTEXTO codepoint + is not valid in its context. + :raises IDNABidiError: If the Bidi Rule is violated. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long", code="input_too_long") + if isinstance(label, (bytes, bytearray)): + try: + label = label.decode("utf-8") + except UnicodeDecodeError as err: + raise IDNAError("Invalid UTF-8 in label", code="invalid_utf8") from err + if len(label) == 0: + raise IDNAError("Empty Label", code="empty_label") + + # Check against the domain length rather than the label length to + # support some UTS #46 use cases, while still bounding the work done + # by the label contextual rules below. + if not valid_string_length(label, trailing_dot=True): + raise IDNAError("Label too long", code="label_too_long") + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for pos, cp in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes["PVALID"]): + continue + if intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]): + try: + contextj_ok = valid_contextj(label, pos) + except ValueError as err: + raise IDNAError( + f"Unknown codepoint adjacent to joiner {_unot(cp_value)} at position {pos + 1} in {label!r}", + code="unknown_codepoint", + text=label, + codepoint=cp_value, + position=pos + 1, + ) from err + if not contextj_ok: + raise InvalidCodepointContext( + f"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}", + code="contextj", + text=label, + codepoint=cp_value, + position=pos + 1, + ) + elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTO"]): + if not valid_contexto(label, pos): + raise InvalidCodepointContext( + f"Codepoint {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}", + code="contexto", + text=label, + codepoint=cp_value, + position=pos + 1, + ) + else: + raise InvalidCodepoint( + f"Codepoint {_unot(cp_value)} at position {pos + 1} of {label!r} not allowed", + code="disallowed_codepoint", + text=label, + codepoint=cp_value, + position=pos + 1, + ) + + check_bidi(label) + + +def alabel(label: str) -> bytes: + """Convert a single U-label into its A-label form. + + The result is the ASCII-Compatible Encoding (ACE) form per :rfc:`5891` + §4: the label is validated, Punycode-encoded, and prefixed with + ``xn--``. Pure ASCII labels that are already valid IDNA labels are + returned unchanged (as :class:`bytes`). + + :param label: The label to convert, as a Unicode string. + :returns: The A-label as ASCII-encoded :class:`bytes`. + :raises IDNAError: If the label is invalid or the resulting A-label + exceeds 63 octets. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long", code="input_too_long") + try: + label_bytes = label.encode("ascii") + except UnicodeEncodeError: + pass + else: + ulabel(label_bytes) + if not valid_label_length(label_bytes): + raise IDNAError("Label too long", code="label_too_long") + return label_bytes + + check_label(label) + label_bytes = _alabel_prefix + _punycode(label) + + if not valid_label_length(label_bytes): + raise IDNAError("Label too long", code="label_too_long") + + return label_bytes + + +def ulabel(label: str | bytes | bytearray) -> str: + """Convert a single A-label into its U-label form. + + Performs the inverse of :func:`alabel`: an ``xn--``-prefixed label is + Punycode-decoded and validated, and is rejected unless it is the + canonical A-label for the decoded U-label (:rfc:`5891` §5.3). Labels + that are already Unicode (or plain ASCII without the ACE prefix) are + validated and returned as a Unicode string. + + :param label: The label to convert. ``bytes`` or ``bytearray`` input + is treated as ASCII. + :returns: The U-label as a Unicode string. + :raises IDNAError: If the label is malformed or fails validation. + """ + if len(label) > _max_input_length: + raise IDNAError("Label too long", code="input_too_long") + if not isinstance(label, (bytes, bytearray)): + try: + label_bytes = label.encode("ascii") + except UnicodeEncodeError: + check_label(label) + return label + else: + label_bytes = bytes(label) + if not label_bytes.isascii(): + raise IDNAError("Invalid ASCII in A-label", code="invalid_ascii") + + label_bytes = label_bytes.lower() + if label_bytes.startswith(_alabel_prefix): + label_bytes = label_bytes[len(_alabel_prefix) :] + if not label_bytes: + raise IDNAError("Malformed A-label, no Punycode eligible content found", code="invalid_alabel") + if label_bytes.endswith(b"-"): + raise IDNAError("A-label must not end with a hyphen", code="invalid_alabel") + else: + check_label(label_bytes) + return label_bytes.decode("ascii") + + try: + label = label_bytes.decode("punycode") + except UnicodeError as err: + raise IDNAError("Invalid A-label", code="invalid_alabel") from err + # RFC 5891 §5.3: the label is rejected unless re-encoding the decoded + # form reproduces the (lowercased) input. This catches "fake A-labels" + # (RFC 5890 §2.3.2.1) such as ``xn---bbk``, a non-canonical Punycode + # spelling of ``xn--bbk`` that would otherwise decode to the same + # U-label and so display identically to a different wire-format name. + if _punycode(label) != label_bytes: + raise IDNAError("A-label is not the canonical Punycode encoding of its U-label", code="non_canonical_alabel") + check_label(label) + return label + + +def _check_std3(text: str, domain: str, offset: int) -> None: + """Raise if ``text``, a slice of ``domain`` starting at ``offset`` that + UTS #46 mapping left unchanged, contains an ASCII character disallowed + under ``UseSTD3ASCIIRules``.""" + match = _std3_disallowed_re.search(text) + if match: + codepoint = ord(match.group()) + position = offset + match.start() + 1 + raise InvalidCodepoint( + f"Codepoint {_unot(codepoint)} not allowed at position {position} in {domain!r}", + code="uts46_std3", + text=domain, + codepoint=codepoint, + position=position, + ) + + +def _warn_transitional() -> None: + warnings.warn( + "Transitional processing is deprecated in UTS #46 and has no effect. " + "The transitional argument will be removed in a future version.", + DeprecationWarning, + stacklevel=3, + ) + + +def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: + """Apply the UTS #46 character mapping to a domain string. + + Implements the mapping table from `UTS #46 §4 + `_: each character is kept, + replaced, or rejected based on its status (``V``, ``M``, ``D``, + ``I``, ``X``). The result is returned in Normalisation Form C. + + :param domain: The full domain name to remap. + :param std3_rules: If ``True``, apply UTS #46's ``UseSTD3ASCIIRules``: + after mapping, any ASCII character other than a lowercase letter, + digit, hyphen or the label separator ``.`` is rejected, whether it + appeared in the input or was produced by a mapping (e.g. U+FF01 + FULLWIDTH EXCLAMATION MARK maps to ``!``). If ``False``, such + characters are passed through. + :param transitional: Deprecated and ignored. UTS #46 deprecated + transitional processing in Unicode 15.1 and deviation (status + ``D``) codepoints are now always kept, so this has no effect + beyond emitting a :class:`DeprecationWarning`. It will be removed + in a future version. + :returns: The remapped domain, in Normalisation Form C. + :raises InvalidCodepoint: If the domain contains a disallowed + codepoint under the chosen rules. + :raises IDNAError: If ``domain`` exceeds the defensive input length limit. + """ + if transitional: + _warn_transitional() + if len(domain) > _max_input_length: + raise IDNAError("Domain too long", code="input_too_long") + if domain.isascii(): + # The only ASCII mapping in UTS #46 is upper- to lowercase, and + # ASCII is invariant under NFC, so lowercasing is the whole job. + result = domain.lower() + if std3_rules: + _check_std3(result, domain, 0) + return result + + from .uts46data import uts46_replacements, uts46_starts, uts46_statuses + + # ``start`` marks the run of unchanged input not yet copied; a run is + # only sliced out when a character must be replaced or dropped, so the + # common no-change case makes no copy. STD3 is checked per output piece + # to report a violation at its input position. + output: list[str] = [] + start = 0 + for pos, char in enumerate(domain): + code_point = ord(char) + i = code_point if code_point < 256 else bisect.bisect_right(uts46_starts, code_point) - 1 + status = uts46_statuses[i] + # UTS #46 §4: V valid, D deviation (kept), M mapped, I ignored, + # anything else disallowed. + if status == _STATUS_VALID: + continue + if status == _STATUS_MAPPED: + replacement = uts46_replacements[i] + elif status == _STATUS_DEVIATION: + continue + elif status == _STATUS_IGNORED: + replacement = None + else: + raise InvalidCodepoint( + f"Codepoint {_unot(code_point)} not allowed at position {pos + 1} in {domain!r}", + code="uts46_disallowed", + text=domain, + codepoint=code_point, + position=pos + 1, + ) + if start < pos: + run = domain[start:pos] + if std3_rules: + _check_std3(run, domain, start) + output.append(run) + if replacement: + if std3_rules and _std3_disallowed_re.search(replacement): + raise InvalidCodepoint( + f"Codepoint {_unot(code_point)} not allowed at position {pos + 1} in {domain!r}", + code="uts46_std3", + text=domain, + codepoint=code_point, + position=pos + 1, + ) + output.append(replacement) + start = pos + 1 + + if start == 0: + if std3_rules: + _check_std3(domain, domain, 0) + return unicodedata.normalize("NFC", domain) + tail = domain[start:] + if std3_rules: + _check_std3(tail, domain, start) + output.append(tail) + return unicodedata.normalize("NFC", "".join(output)) + + +def encode( + s: str | bytes | bytearray, + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, + transitional: bool = False, +) -> bytes: + """Encode a Unicode domain name into its ASCII (A-label) form. + + Splits the input on label separators (only ``U+002E`` if ``strict`` is + set; otherwise also IDEOGRAPHIC FULL STOP ``U+3002``, FULLWIDTH FULL + STOP ``U+FF0E``, and HALFWIDTH IDEOGRAPHIC FULL STOP ``U+FF61``), + encodes each label with :func:`alabel`, and rejoins them with ``.``. + Optionally pre-processes the input through :func:`uts46_remap`. + + :param s: The domain name to encode. + :param strict: If ``True``, only ``U+002E`` is recognised as a label + separator. + :param uts46: If ``True``, apply UTS #46 mapping before encoding. + :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is + ``True``. + :param transitional: Deprecated and ignored (see :func:`uts46_remap`): + emits a :class:`DeprecationWarning` and will be removed in a + future version. + :returns: The encoded domain as ASCII :class:`bytes`. + :raises IDNAError: If the domain is empty, contains an invalid label, + or exceeds the maximum domain length. + """ + if transitional: + _warn_transitional() + if not isinstance(s, str): + try: + s = str(s, "ascii") + except (UnicodeDecodeError, TypeError) as err: + raise IDNAError( + "should pass a unicode string to the function rather than a byte string.", code="invalid_ascii" + ) from err + if len(s) > _max_input_length: + raise IDNAError("Domain too long", code="input_too_long") + if uts46: + s = uts46_remap(s, std3_rules) + + if not valid_string_length(s, trailing_dot=True): + raise IDNAError("Domain too long", code="domain_too_long") + + trailing_dot = False + result = [] + labels = s.split(".") if strict else _unicode_dots_re.split(s) + if not labels or labels == [""]: + raise IDNAError("Empty domain", code="empty_domain") + if labels[-1] == "": + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError("Empty label", code="empty_label") + if trailing_dot: + result.append(b"") + s = b".".join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError("Domain too long", code="domain_too_long") + return s + + +def decode( + s: str | bytes | bytearray, + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, + display: bool = False, +) -> str: + """Decode an A-label-encoded domain name back to Unicode. + + Splits the input on label separators (see :func:`encode` for the + rules), decodes each label with :func:`ulabel`, and rejoins them + with ``.``. Optionally pre-processes the input through + :func:`uts46_remap`. + + :param s: The domain name to decode. + :param strict: If ``True``, only ``U+002E`` is recognised as a label + separator. + :param uts46: If ``True``, apply UTS #46 mapping before decoding. + :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is + ``True``. + :param display: If ``True``, any ``xn--`` label that fails IDNA + validation is passed through unchanged (lowercased) rather than + aborting the whole call. Intended for "decode for display" + consumers (e.g. URL libraries, HTTP clients) that want to show + the user the label as it appears on the wire when it cannot be + rendered as Unicode. Matches the per-label recovery prescribed + by UTS #46 §4 and the WHATWG URL "domain to Unicode" algorithm. + :returns: The decoded domain as a Unicode string. + :raises IDNAError: If the input is not valid ASCII, contains an + invalid label, or is empty. + """ + if not isinstance(s, str): + try: + s = str(s, "ascii") + except (UnicodeDecodeError, TypeError) as err: + raise IDNAError("Invalid ASCII in A-label", code="invalid_ascii") from err + if len(s) > _max_input_length: + raise IDNAError("Domain too long", code="input_too_long") + if uts46: + s = uts46_remap(s, std3_rules, False) + if not valid_string_length(s, trailing_dot=True): + raise IDNAError("Domain too long", code="domain_too_long") + trailing_dot = False + result = [] + labels = s.split(".") if strict else _unicode_dots_re.split(s) + if not labels or labels == [""]: + raise IDNAError("Empty domain", code="empty_domain") + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + try: + u = ulabel(label) + except IDNAError: + if display and label[:4].lower() == "xn--": + u = label.lower() + else: + raise + if u: + result.append(u) + else: + raise IDNAError("Empty label", code="empty_label") + if trailing_dot: + result.append("") + return ".".join(result) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py new file mode 100644 index 00000000000..471c047d1f2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py @@ -0,0 +1,1933 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "18.0.0" + +scripts = { + "Greek": ( + 0x37000000374, + 0x37500000378, + 0x37A0000037E, + 0x37F00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038B, + 0x38C0000038D, + 0x38E000003A2, + 0x3A3000003E2, + 0x3F000000400, + 0x1D2600001D2B, + 0x1D5D00001D62, + 0x1D6600001D6B, + 0x1DBF00001DC0, + 0x1F0000001F16, + 0x1F1800001F1E, + 0x1F2000001F46, + 0x1F4800001F4E, + 0x1F5000001F58, + 0x1F5900001F5A, + 0x1F5B00001F5C, + 0x1F5D00001F5E, + 0x1F5F00001F7E, + 0x1F8000001FB5, + 0x1FB600001FC5, + 0x1FC600001FD4, + 0x1FD600001FDC, + 0x1FDD00001FF0, + 0x1FF200001FF5, + 0x1FF600001FFF, + 0x212600002127, + 0xAB650000AB66, + 0x101400001018F, + 0x101A0000101A1, + 0x1D2000001D246, + 0x1DFF30001DFF5, + ), + "Han": ( + 0x2E8000002E9A, + 0x2E9B00002EF4, + 0x2F0000002FD6, + 0x300500003006, + 0x300700003008, + 0x30210000302A, + 0x30380000303C, + 0x340000004DC0, + 0x4E000000A000, + 0xF9000000FA6E, + 0xFA700000FADA, + 0x16FE200016FE4, + 0x16FF000016FF7, + 0x200000002A6E0, + 0x2A7000002B81F, + 0x2B8200002CEAE, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x2F8000002FA1E, + 0x300000003134B, + 0x313500003347A, + ), + "Hebrew": ( + 0x591000005CA, + 0x5D0000005EB, + 0x5EF000005F5, + 0xFB1D0000FB37, + 0xFB380000FB3D, + 0xFB3E0000FB3F, + 0xFB400000FB42, + 0xFB430000FB45, + 0xFB460000FB50, + ), + "Hiragana": ( + 0x304100003097, + 0x309D000030A0, + 0x1B0010001B120, + 0x1B1230001B124, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1F2000001F201, + ), + "Katakana": ( + 0x30A1000030FB, + 0x30FD00003100, + 0x31F000003200, + 0x32D0000032FF, + 0x330000003358, + 0xFF660000FF70, + 0xFF710000FF9E, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B001, + 0x1B1200001B123, + 0x1B1240001B129, + 0x1B1550001B156, + 0x1B1640001B169, + ), +} + + +joining_types = { + "C": ( + 0x64000000641, + 0x7FA000007FB, + 0x88300000886, + 0x180A0000180B, + 0x200D0000200E, + ), + "D": ( + 0x62000000621, + 0x62600000627, + 0x62800000629, + 0x62A0000062F, + 0x63300000640, + 0x64100000648, + 0x6490000064B, + 0x66E00000670, + 0x67800000688, + 0x69A000006C0, + 0x6C1000006C3, + 0x6CC000006CD, + 0x6CE000006CF, + 0x6D0000006D2, + 0x6FA000006FD, + 0x6FF00000700, + 0x71200000715, + 0x71A0000071E, + 0x71F00000728, + 0x7290000072A, + 0x72B0000072C, + 0x72D0000072F, + 0x74E00000759, + 0x75C0000076B, + 0x76D00000771, + 0x77200000773, + 0x77500000778, + 0x77A00000780, + 0x7CA000007EB, + 0x84100000846, + 0x84800000849, + 0x84A00000854, + 0x85500000856, + 0x86000000861, + 0x86200000866, + 0x86800000869, + 0x88600000887, + 0x8890000088E, + 0x88F00000890, + 0x8A0000008AA, + 0x8AF000008B1, + 0x8B3000008B9, + 0x8BA000008C9, + 0x180700001808, + 0x182000001879, + 0x1887000018A9, + 0x18AA000018AB, + 0xA8400000A872, + 0x10AC000010AC5, + 0x10AD300010AD7, + 0x10AD800010ADD, + 0x10ADE00010AE1, + 0x10AEB00010AEF, + 0x10B8000010B81, + 0x10B8200010B83, + 0x10B8600010B89, + 0x10B8A00010B8C, + 0x10B8D00010B8E, + 0x10B9000010B91, + 0x10BAD00010BAF, + 0x10D0100010D22, + 0x10D2300010D24, + 0x10EC300010EC5, + 0x10EC600010EC8, + 0x10F3000010F33, + 0x10F3400010F45, + 0x10F5100010F54, + 0x10F7000010F74, + 0x10F7600010F82, + 0x10FB000010FB1, + 0x10FB200010FB4, + 0x10FB800010FB9, + 0x10FBB00010FBD, + 0x10FBE00010FC0, + 0x10FC100010FC2, + 0x10FC400010FC5, + 0x10FCA00010FCB, + 0x1E9000001E944, + ), + "L": ( + 0xA8720000A873, + 0x10ACD00010ACE, + 0x10AD700010AD8, + 0x10D0000010D01, + 0x10ED900010EEF, + 0x10FCB00010FCC, + ), + "R": ( + 0x62200000626, + 0x62700000628, + 0x6290000062A, + 0x62F00000633, + 0x64800000649, + 0x67100000674, + 0x67500000678, + 0x6880000069A, + 0x6C0000006C1, + 0x6C3000006CC, + 0x6CD000006CE, + 0x6CF000006D0, + 0x6D2000006D4, + 0x6D5000006D6, + 0x6EE000006F0, + 0x71000000711, + 0x7150000071A, + 0x71E0000071F, + 0x72800000729, + 0x72A0000072B, + 0x72C0000072D, + 0x72F00000730, + 0x74D0000074E, + 0x7590000075C, + 0x76B0000076D, + 0x77100000772, + 0x77300000775, + 0x7780000077A, + 0x84000000841, + 0x84600000848, + 0x8490000084A, + 0x85400000855, + 0x85600000859, + 0x86700000868, + 0x8690000086B, + 0x87000000883, + 0x88E0000088F, + 0x8AA000008AD, + 0x8AE000008AF, + 0x8B1000008B3, + 0x8B9000008BA, + 0x10AC500010AC6, + 0x10AC700010AC8, + 0x10AC900010ACB, + 0x10ACE00010AD3, + 0x10ADD00010ADE, + 0x10AE100010AE2, + 0x10AE400010AE5, + 0x10AEF00010AF0, + 0x10B8100010B82, + 0x10B8300010B86, + 0x10B8900010B8A, + 0x10B8C00010B8D, + 0x10B8E00010B90, + 0x10B9100010B92, + 0x10BA900010BAD, + 0x10D2200010D23, + 0x10EC200010EC3, + 0x10F3300010F34, + 0x10F5400010F55, + 0x10F7400010F76, + 0x10FB400010FB7, + 0x10FB900010FBB, + 0x10FBD00010FBE, + 0x10FC200010FC4, + 0x10FC900010FCA, + ), + "T": ( + 0xAD000000AE, + 0x30000000370, + 0x4830000048A, + 0x591000005BE, + 0x5BF000005C0, + 0x5C1000005C3, + 0x5C4000005C6, + 0x5C7000005CA, + 0x6100000061B, + 0x61C0000061D, + 0x64B00000660, + 0x67000000671, + 0x6D6000006DD, + 0x6DF000006E5, + 0x6E7000006E9, + 0x6EA000006EE, + 0x70F00000710, + 0x71100000712, + 0x7300000074B, + 0x7A6000007B1, + 0x7EB000007F4, + 0x7FD000007FE, + 0x8160000081A, + 0x81B00000824, + 0x82500000828, + 0x8290000082E, + 0x8590000085C, + 0x897000008A0, + 0x8CA000008E2, + 0x8E300000903, + 0x93A0000093B, + 0x93C0000093D, + 0x94100000949, + 0x94D0000094E, + 0x95100000958, + 0x96200000964, + 0x98100000982, + 0x9BC000009BD, + 0x9C1000009C5, + 0x9CD000009CE, + 0x9E2000009E4, + 0x9FE000009FF, + 0xA0100000A03, + 0xA3C00000A3D, + 0xA4100000A43, + 0xA4700000A49, + 0xA4B00000A4E, + 0xA5100000A52, + 0xA7000000A72, + 0xA7500000A76, + 0xA8100000A83, + 0xABC00000ABD, + 0xAC100000AC6, + 0xAC700000AC9, + 0xACD00000ACE, + 0xAE200000AE4, + 0xAFA00000B00, + 0xB0100000B02, + 0xB3C00000B3D, + 0xB3F00000B40, + 0xB4100000B45, + 0xB4D00000B4E, + 0xB5300000B57, + 0xB6200000B64, + 0xB8200000B83, + 0xBC000000BC1, + 0xBCD00000BCE, + 0xC0000000C01, + 0xC0400000C05, + 0xC3C00000C3D, + 0xC3E00000C41, + 0xC4600000C49, + 0xC4A00000C4E, + 0xC5500000C57, + 0xC6200000C64, + 0xC8100000C82, + 0xCBC00000CBD, + 0xCBF00000CC0, + 0xCC600000CC7, + 0xCCC00000CCE, + 0xCE200000CE4, + 0xD0000000D02, + 0xD3B00000D3D, + 0xD4100000D45, + 0xD4D00000D4E, + 0xD6200000D64, + 0xD8100000D82, + 0xDCA00000DCB, + 0xDD200000DD5, + 0xDD600000DD7, + 0xE3100000E32, + 0xE3400000E3B, + 0xE4700000E4F, + 0xEB100000EB2, + 0xEB400000EBD, + 0xEC800000ECF, + 0xF1800000F1A, + 0xF3500000F36, + 0xF3700000F38, + 0xF3900000F3A, + 0xF7100000F7F, + 0xF8000000F85, + 0xF8600000F88, + 0xF8D00000F98, + 0xF9900000FBD, + 0xFC600000FC7, + 0x102D00001031, + 0x103200001038, + 0x10390000103B, + 0x103D0000103F, + 0x10580000105A, + 0x105E00001061, + 0x107100001075, + 0x108200001083, + 0x108500001087, + 0x108D0000108E, + 0x109D0000109E, + 0x135D00001360, + 0x171200001715, + 0x173200001734, + 0x175200001754, + 0x177200001774, + 0x17B4000017B6, + 0x17B7000017BE, + 0x17C6000017C7, + 0x17C9000017D4, + 0x17DD000017DE, + 0x180B0000180E, + 0x180F00001810, + 0x188500001887, + 0x18A9000018AA, + 0x192000001923, + 0x192700001929, + 0x193200001933, + 0x19390000193C, + 0x1A1700001A19, + 0x1A1B00001A1C, + 0x1A5600001A57, + 0x1A5800001A5F, + 0x1A6000001A61, + 0x1A6200001A63, + 0x1A6500001A6D, + 0x1A7300001A7D, + 0x1A7F00001A80, + 0x1AB000001AF1, + 0x1B0000001B04, + 0x1B3400001B35, + 0x1B3600001B3B, + 0x1B3C00001B3D, + 0x1B4200001B43, + 0x1B6B00001B74, + 0x1B8000001B82, + 0x1BA200001BA6, + 0x1BA800001BAA, + 0x1BAB00001BAE, + 0x1BE600001BE7, + 0x1BE800001BEA, + 0x1BED00001BEE, + 0x1BEF00001BF2, + 0x1C2C00001C34, + 0x1C3600001C38, + 0x1CD000001CD3, + 0x1CD400001CE1, + 0x1CE200001CE9, + 0x1CED00001CEE, + 0x1CF400001CF5, + 0x1CF800001CFA, + 0x1DC000001E00, + 0x200B0000200C, + 0x200E00002010, + 0x202A0000202F, + 0x206000002065, + 0x206A00002070, + 0x20D0000020F1, + 0x2CEF00002CF2, + 0x2D7F00002D80, + 0x2DE000002E00, + 0x302A0000302E, + 0x30990000309B, + 0xA66F0000A673, + 0xA6740000A67E, + 0xA69E0000A6A0, + 0xA6F00000A6F2, + 0xA8020000A803, + 0xA8060000A807, + 0xA80B0000A80C, + 0xA8250000A827, + 0xA82C0000A82D, + 0xA8C40000A8C6, + 0xA8E00000A8F2, + 0xA8FF0000A900, + 0xA9260000A92E, + 0xA9470000A952, + 0xA9800000A983, + 0xA9B30000A9B4, + 0xA9B60000A9BA, + 0xA9BC0000A9BE, + 0xA9E50000A9E6, + 0xAA290000AA2F, + 0xAA310000AA33, + 0xAA350000AA37, + 0xAA430000AA44, + 0xAA4C0000AA4D, + 0xAA7C0000AA7D, + 0xAAB00000AAB1, + 0xAAB20000AAB5, + 0xAAB70000AAB9, + 0xAABE0000AAC0, + 0xAAC10000AAC2, + 0xAAEC0000AAEE, + 0xAAF60000AAF7, + 0xABE50000ABE6, + 0xABE80000ABE9, + 0xABED0000ABEE, + 0xFB1E0000FB1F, + 0xFE000000FE10, + 0xFE200000FE30, + 0xFEFF0000FF00, + 0xFFF90000FFFC, + 0x101FD000101FE, + 0x102E0000102E1, + 0x103760001037B, + 0x10A0100010A04, + 0x10A0500010A07, + 0x10A0C00010A10, + 0x10A3800010A3B, + 0x10A3F00010A40, + 0x10AE500010AE7, + 0x10D2400010D28, + 0x10D6900010D6E, + 0x10EAB00010EAD, + 0x10ECB00010ED0, + 0x10EF000010F00, + 0x10F4600010F51, + 0x10F8200010F86, + 0x1100100011002, + 0x1103800011047, + 0x1107000011071, + 0x1107300011075, + 0x1107F00011082, + 0x110B3000110B7, + 0x110B9000110BB, + 0x110C2000110C3, + 0x1110000011103, + 0x111270001112C, + 0x1112D00011135, + 0x1117300011174, + 0x1118000011182, + 0x111B6000111BF, + 0x111C9000111CD, + 0x111CF000111D0, + 0x1122F00011232, + 0x1123400011235, + 0x1123600011238, + 0x1123E0001123F, + 0x1124100011242, + 0x112DF000112E0, + 0x112E3000112EB, + 0x1130000011302, + 0x1133B0001133D, + 0x1134000011341, + 0x113660001136D, + 0x1137000011375, + 0x113BB000113C1, + 0x113CE000113CF, + 0x113D0000113D1, + 0x113D2000113D3, + 0x113E1000113E3, + 0x1143800011440, + 0x1144200011445, + 0x1144600011447, + 0x1145E0001145F, + 0x114B3000114B9, + 0x114BA000114BB, + 0x114BF000114C1, + 0x114C2000114C4, + 0x115B2000115B6, + 0x115BC000115BE, + 0x115BF000115C1, + 0x115DC000115DE, + 0x116330001163B, + 0x1163D0001163E, + 0x1163F00011641, + 0x116AB000116AC, + 0x116AD000116AE, + 0x116B0000116B6, + 0x116B7000116B8, + 0x1171D0001171E, + 0x1171F00011720, + 0x1172200011726, + 0x117270001172C, + 0x1182F00011838, + 0x118390001183B, + 0x1193B0001193D, + 0x1193E0001193F, + 0x1194300011944, + 0x119D4000119D8, + 0x119DA000119DC, + 0x119E0000119E1, + 0x11A0100011A0B, + 0x11A3300011A39, + 0x11A3B00011A3F, + 0x11A4700011A48, + 0x11A5100011A57, + 0x11A5900011A5C, + 0x11A8A00011A97, + 0x11A9800011A9A, + 0x11B6000011B61, + 0x11B6200011B65, + 0x11B6600011B67, + 0x11C3000011C37, + 0x11C3800011C3E, + 0x11C3F00011C40, + 0x11C9200011CA8, + 0x11CAA00011CB1, + 0x11CB200011CB4, + 0x11CB500011CB7, + 0x11D3100011D37, + 0x11D3A00011D3B, + 0x11D3C00011D3E, + 0x11D3F00011D46, + 0x11D4700011D48, + 0x11D9000011D92, + 0x11D9500011D96, + 0x11D9700011D98, + 0x11DF000011DF1, + 0x11EF300011EF5, + 0x11F0000011F02, + 0x11F3600011F3B, + 0x11F4000011F41, + 0x11F4200011F43, + 0x11F5A00011F5B, + 0x1343000013441, + 0x1344700013456, + 0x1611E0001612A, + 0x1612D00016130, + 0x16AF000016AF5, + 0x16B3000016B37, + 0x16F4F00016F50, + 0x16F8F00016F93, + 0x16FE400016FE5, + 0x1BC9D0001BC9F, + 0x1BCA00001BCA4, + 0x1CF000001CF2E, + 0x1CF300001CF47, + 0x1D1270001D129, + 0x1D1670001D16A, + 0x1D1730001D183, + 0x1D1850001D18C, + 0x1D1AA0001D1AE, + 0x1D2420001D245, + 0x1D25B0001D25D, + 0x1DA000001DA37, + 0x1DA3B0001DA6D, + 0x1DA750001DA76, + 0x1DA840001DA85, + 0x1DA9B0001DAA0, + 0x1DAA10001DAB0, + 0x1E0000001E007, + 0x1E0080001E019, + 0x1E01B0001E022, + 0x1E0230001E025, + 0x1E0260001E02B, + 0x1E08F0001E090, + 0x1E1300001E137, + 0x1E2AE0001E2AF, + 0x1E2EC0001E2F0, + 0x1E4EC0001E4F0, + 0x1E5EE0001E5F0, + 0x1E6E30001E6E4, + 0x1E6E60001E6E7, + 0x1E6EE0001E6F0, + 0x1E6F50001E6F6, + 0x1E8D00001E8D7, + 0x1E9440001E94C, + 0xE0001000E0002, + 0xE0020000E0080, + 0xE0100000E01F0, + ), +} + + +codepoint_classes = { + "PVALID": ( + 0x2D0000002E, + 0x300000003A, + 0x610000007B, + 0xDF000000F7, + 0xF800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010A, + 0x10B0000010C, + 0x10D0000010E, + 0x10F00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011A, + 0x11B0000011C, + 0x11D0000011E, + 0x11F00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012A, + 0x12B0000012C, + 0x12D0000012E, + 0x12F00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13A0000013B, + 0x13C0000013D, + 0x13E0000013F, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14B0000014C, + 0x14D0000014E, + 0x14F00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015A, + 0x15B0000015C, + 0x15D0000015E, + 0x15F00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016A, + 0x16B0000016C, + 0x16D0000016E, + 0x16F00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17A0000017B, + 0x17C0000017D, + 0x17E0000017F, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18C0000018E, + 0x19200000193, + 0x19500000196, + 0x1990000019C, + 0x19E0000019F, + 0x1A1000001A2, + 0x1A3000001A4, + 0x1A5000001A6, + 0x1A8000001A9, + 0x1AA000001AC, + 0x1AD000001AE, + 0x1B0000001B1, + 0x1B4000001B5, + 0x1B6000001B7, + 0x1B9000001BC, + 0x1BD000001C4, + 0x1CE000001CF, + 0x1D0000001D1, + 0x1D2000001D3, + 0x1D4000001D5, + 0x1D6000001D7, + 0x1D8000001D9, + 0x1DA000001DB, + 0x1DC000001DE, + 0x1DF000001E0, + 0x1E1000001E2, + 0x1E3000001E4, + 0x1E5000001E6, + 0x1E7000001E8, + 0x1E9000001EA, + 0x1EB000001EC, + 0x1ED000001EE, + 0x1EF000001F1, + 0x1F5000001F6, + 0x1F9000001FA, + 0x1FB000001FC, + 0x1FD000001FE, + 0x1FF00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020A, + 0x20B0000020C, + 0x20D0000020E, + 0x20F00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021A, + 0x21B0000021C, + 0x21D0000021E, + 0x21F00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022A, + 0x22B0000022C, + 0x22D0000022E, + 0x22F00000230, + 0x23100000232, + 0x2330000023A, + 0x23C0000023D, + 0x23F00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024A, + 0x24B0000024C, + 0x24D0000024E, + 0x24F000002B0, + 0x2B9000002C2, + 0x2C6000002D2, + 0x2EC000002ED, + 0x2EE000002EF, + 0x30000000340, + 0x34200000343, + 0x3460000034F, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37B0000037E, + 0x39000000391, + 0x3AC000003CF, + 0x3D7000003D8, + 0x3D9000003DA, + 0x3DB000003DC, + 0x3DD000003DE, + 0x3DF000003E0, + 0x3E1000003E2, + 0x3E3000003E4, + 0x3E5000003E6, + 0x3E7000003E8, + 0x3E9000003EA, + 0x3EB000003EC, + 0x3ED000003EE, + 0x3EF000003F0, + 0x3F3000003F4, + 0x3F8000003F9, + 0x3FB000003FD, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046A, + 0x46B0000046C, + 0x46D0000046E, + 0x46F00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047A, + 0x47B0000047C, + 0x47D0000047E, + 0x47F00000480, + 0x48100000482, + 0x48300000488, + 0x48B0000048C, + 0x48D0000048E, + 0x48F00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049A, + 0x49B0000049C, + 0x49D0000049E, + 0x49F000004A0, + 0x4A1000004A2, + 0x4A3000004A4, + 0x4A5000004A6, + 0x4A7000004A8, + 0x4A9000004AA, + 0x4AB000004AC, + 0x4AD000004AE, + 0x4AF000004B0, + 0x4B1000004B2, + 0x4B3000004B4, + 0x4B5000004B6, + 0x4B7000004B8, + 0x4B9000004BA, + 0x4BB000004BC, + 0x4BD000004BE, + 0x4BF000004C0, + 0x4C2000004C3, + 0x4C4000004C5, + 0x4C6000004C7, + 0x4C8000004C9, + 0x4CA000004CB, + 0x4CC000004CD, + 0x4CE000004D0, + 0x4D1000004D2, + 0x4D3000004D4, + 0x4D5000004D6, + 0x4D7000004D8, + 0x4D9000004DA, + 0x4DB000004DC, + 0x4DD000004DE, + 0x4DF000004E0, + 0x4E1000004E2, + 0x4E3000004E4, + 0x4E5000004E6, + 0x4E7000004E8, + 0x4E9000004EA, + 0x4EB000004EC, + 0x4ED000004EE, + 0x4EF000004F0, + 0x4F1000004F2, + 0x4F3000004F4, + 0x4F5000004F6, + 0x4F7000004F8, + 0x4F9000004FA, + 0x4FB000004FC, + 0x4FD000004FE, + 0x4FF00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050A, + 0x50B0000050C, + 0x50D0000050E, + 0x50F00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051A, + 0x51B0000051C, + 0x51D0000051E, + 0x51F00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052A, + 0x52B0000052C, + 0x52D0000052E, + 0x52F00000530, + 0x5590000055A, + 0x56000000587, + 0x58800000589, + 0x591000005BE, + 0x5BF000005C0, + 0x5C1000005C3, + 0x5C4000005C6, + 0x5C7000005CA, + 0x5D0000005EB, + 0x5EF000005F3, + 0x6100000061B, + 0x62000000640, + 0x64100000660, + 0x66E00000675, + 0x679000006D4, + 0x6D5000006DD, + 0x6DF000006E9, + 0x6EA000006F0, + 0x6FA00000700, + 0x7100000074B, + 0x74D000007B2, + 0x7C0000007F6, + 0x7FD000007FE, + 0x8000000082E, + 0x8400000085C, + 0x8600000086B, + 0x87000000888, + 0x88900000890, + 0x897000008E2, + 0x8E300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098D, + 0x98F00000991, + 0x993000009A9, + 0x9AA000009B1, + 0x9B2000009B3, + 0x9B6000009BA, + 0x9BC000009C5, + 0x9C7000009C9, + 0x9CB000009CF, + 0x9D7000009D8, + 0x9E0000009E4, + 0x9E6000009F2, + 0x9FC000009FD, + 0x9FE000009FF, + 0xA0100000A04, + 0xA0500000A0B, + 0xA0F00000A11, + 0xA1300000A29, + 0xA2A00000A31, + 0xA3200000A33, + 0xA3500000A36, + 0xA3800000A3A, + 0xA3C00000A3D, + 0xA3E00000A43, + 0xA4700000A49, + 0xA4B00000A4E, + 0xA5100000A52, + 0xA5C00000A5D, + 0xA6600000A76, + 0xA8100000A84, + 0xA8500000A8E, + 0xA8F00000A92, + 0xA9300000AA9, + 0xAAA00000AB1, + 0xAB200000AB4, + 0xAB500000ABA, + 0xABC00000AC6, + 0xAC700000ACA, + 0xACB00000ACE, + 0xAD000000AD1, + 0xAE000000AE4, + 0xAE600000AF0, + 0xAF900000B00, + 0xB0100000B04, + 0xB0500000B0D, + 0xB0F00000B11, + 0xB1300000B29, + 0xB2A00000B31, + 0xB3200000B34, + 0xB3500000B3A, + 0xB3C00000B45, + 0xB4700000B49, + 0xB4B00000B4E, + 0xB5300000B58, + 0xB5F00000B64, + 0xB6600000B70, + 0xB7100000B72, + 0xB8200000B84, + 0xB8500000B8B, + 0xB8E00000B91, + 0xB9200000B96, + 0xB9900000B9B, + 0xB9C00000B9D, + 0xB9E00000BA0, + 0xBA300000BA5, + 0xBA800000BAB, + 0xBAE00000BBA, + 0xBBE00000BC3, + 0xBC600000BC9, + 0xBCA00000BCE, + 0xBD000000BD1, + 0xBD700000BD8, + 0xBE600000BF0, + 0xC0000000C0D, + 0xC0E00000C11, + 0xC1200000C29, + 0xC2A00000C3A, + 0xC3C00000C45, + 0xC4600000C49, + 0xC4A00000C4E, + 0xC5500000C57, + 0xC5800000C5B, + 0xC5C00000C5E, + 0xC6000000C64, + 0xC6600000C70, + 0xC8000000C84, + 0xC8500000C8D, + 0xC8E00000C91, + 0xC9200000CA9, + 0xCAA00000CB4, + 0xCB500000CBA, + 0xCBC00000CC5, + 0xCC600000CC9, + 0xCCA00000CCE, + 0xCD500000CD7, + 0xCDC00000CDF, + 0xCE000000CE4, + 0xCE600000CF0, + 0xCF100000CF4, + 0xD0000000D0D, + 0xD0E00000D11, + 0xD1200000D45, + 0xD4600000D49, + 0xD4A00000D4F, + 0xD5400000D58, + 0xD5F00000D64, + 0xD6600000D70, + 0xD7A00000D80, + 0xD8100000D84, + 0xD8500000D97, + 0xD9A00000DB2, + 0xDB300000DBC, + 0xDBD00000DBE, + 0xDC000000DC7, + 0xDCA00000DCB, + 0xDCF00000DD5, + 0xDD600000DD7, + 0xDD800000DE0, + 0xDE600000DF0, + 0xDF200000DF4, + 0xE0100000E33, + 0xE3400000E3B, + 0xE4000000E4F, + 0xE5000000E5A, + 0xE8100000E83, + 0xE8400000E85, + 0xE8600000E8B, + 0xE8C00000EA4, + 0xEA500000EA6, + 0xEA700000EB3, + 0xEB400000EBE, + 0xEC000000EC5, + 0xEC600000EC7, + 0xEC800000ECF, + 0xED000000EDA, + 0xEDE00000EE0, + 0xF0000000F01, + 0xF0B00000F0C, + 0xF1800000F1A, + 0xF2000000F2A, + 0xF3500000F36, + 0xF3700000F38, + 0xF3900000F3A, + 0xF3E00000F43, + 0xF4400000F48, + 0xF4900000F4D, + 0xF4E00000F52, + 0xF5300000F57, + 0xF5800000F5C, + 0xF5D00000F69, + 0xF6A00000F6D, + 0xF7100000F73, + 0xF7400000F75, + 0xF7A00000F81, + 0xF8200000F85, + 0xF8600000F93, + 0xF9400000F98, + 0xF9900000F9D, + 0xF9E00000FA2, + 0xFA300000FA7, + 0xFA800000FAC, + 0xFAD00000FB9, + 0xFBA00000FBD, + 0xFC600000FC7, + 0x10000000104A, + 0x10500000109E, + 0x10D0000010FB, + 0x10FD00001100, + 0x120000001249, + 0x124A0000124E, + 0x125000001257, + 0x125800001259, + 0x125A0000125E, + 0x126000001289, + 0x128A0000128E, + 0x1290000012B1, + 0x12B2000012B6, + 0x12B8000012BF, + 0x12C0000012C1, + 0x12C2000012C6, + 0x12C8000012D7, + 0x12D800001311, + 0x131200001316, + 0x13180000135B, + 0x135D00001360, + 0x138000001390, + 0x13A0000013F6, + 0x14010000166D, + 0x166F00001680, + 0x16810000169B, + 0x16A0000016EB, + 0x16F1000016F9, + 0x170000001716, + 0x171F00001735, + 0x174000001754, + 0x17600000176D, + 0x176E00001771, + 0x177200001774, + 0x1780000017B4, + 0x17B6000017D4, + 0x17D7000017D8, + 0x17DC000017DE, + 0x17E0000017EA, + 0x18100000181A, + 0x182000001879, + 0x1880000018AB, + 0x18B0000018F6, + 0x19000000191F, + 0x19200000192C, + 0x19300000193C, + 0x19460000196E, + 0x197000001975, + 0x1980000019AC, + 0x19B0000019CA, + 0x19D0000019DA, + 0x1A0000001A1C, + 0x1A2000001A5F, + 0x1A6000001A7D, + 0x1A7F00001A8A, + 0x1A9000001A9A, + 0x1AA700001AA8, + 0x1AB000001ABE, + 0x1ABF00001AF1, + 0x1B0000001B4D, + 0x1B5000001B5A, + 0x1B6B00001B74, + 0x1B8000001BF4, + 0x1C0000001C38, + 0x1C4000001C4A, + 0x1C4D00001C7E, + 0x1C8A00001C8B, + 0x1CD000001CD3, + 0x1CD400001CFB, + 0x1D0000001D2C, + 0x1D2F00001D30, + 0x1D3B00001D3C, + 0x1D4E00001D4F, + 0x1D6B00001D78, + 0x1D7900001D9B, + 0x1DC000001E00, + 0x1E0100001E02, + 0x1E0300001E04, + 0x1E0500001E06, + 0x1E0700001E08, + 0x1E0900001E0A, + 0x1E0B00001E0C, + 0x1E0D00001E0E, + 0x1E0F00001E10, + 0x1E1100001E12, + 0x1E1300001E14, + 0x1E1500001E16, + 0x1E1700001E18, + 0x1E1900001E1A, + 0x1E1B00001E1C, + 0x1E1D00001E1E, + 0x1E1F00001E20, + 0x1E2100001E22, + 0x1E2300001E24, + 0x1E2500001E26, + 0x1E2700001E28, + 0x1E2900001E2A, + 0x1E2B00001E2C, + 0x1E2D00001E2E, + 0x1E2F00001E30, + 0x1E3100001E32, + 0x1E3300001E34, + 0x1E3500001E36, + 0x1E3700001E38, + 0x1E3900001E3A, + 0x1E3B00001E3C, + 0x1E3D00001E3E, + 0x1E3F00001E40, + 0x1E4100001E42, + 0x1E4300001E44, + 0x1E4500001E46, + 0x1E4700001E48, + 0x1E4900001E4A, + 0x1E4B00001E4C, + 0x1E4D00001E4E, + 0x1E4F00001E50, + 0x1E5100001E52, + 0x1E5300001E54, + 0x1E5500001E56, + 0x1E5700001E58, + 0x1E5900001E5A, + 0x1E5B00001E5C, + 0x1E5D00001E5E, + 0x1E5F00001E60, + 0x1E6100001E62, + 0x1E6300001E64, + 0x1E6500001E66, + 0x1E6700001E68, + 0x1E6900001E6A, + 0x1E6B00001E6C, + 0x1E6D00001E6E, + 0x1E6F00001E70, + 0x1E7100001E72, + 0x1E7300001E74, + 0x1E7500001E76, + 0x1E7700001E78, + 0x1E7900001E7A, + 0x1E7B00001E7C, + 0x1E7D00001E7E, + 0x1E7F00001E80, + 0x1E8100001E82, + 0x1E8300001E84, + 0x1E8500001E86, + 0x1E8700001E88, + 0x1E8900001E8A, + 0x1E8B00001E8C, + 0x1E8D00001E8E, + 0x1E8F00001E90, + 0x1E9100001E92, + 0x1E9300001E94, + 0x1E9500001E9A, + 0x1E9C00001E9E, + 0x1E9F00001EA0, + 0x1EA100001EA2, + 0x1EA300001EA4, + 0x1EA500001EA6, + 0x1EA700001EA8, + 0x1EA900001EAA, + 0x1EAB00001EAC, + 0x1EAD00001EAE, + 0x1EAF00001EB0, + 0x1EB100001EB2, + 0x1EB300001EB4, + 0x1EB500001EB6, + 0x1EB700001EB8, + 0x1EB900001EBA, + 0x1EBB00001EBC, + 0x1EBD00001EBE, + 0x1EBF00001EC0, + 0x1EC100001EC2, + 0x1EC300001EC4, + 0x1EC500001EC6, + 0x1EC700001EC8, + 0x1EC900001ECA, + 0x1ECB00001ECC, + 0x1ECD00001ECE, + 0x1ECF00001ED0, + 0x1ED100001ED2, + 0x1ED300001ED4, + 0x1ED500001ED6, + 0x1ED700001ED8, + 0x1ED900001EDA, + 0x1EDB00001EDC, + 0x1EDD00001EDE, + 0x1EDF00001EE0, + 0x1EE100001EE2, + 0x1EE300001EE4, + 0x1EE500001EE6, + 0x1EE700001EE8, + 0x1EE900001EEA, + 0x1EEB00001EEC, + 0x1EED00001EEE, + 0x1EEF00001EF0, + 0x1EF100001EF2, + 0x1EF300001EF4, + 0x1EF500001EF6, + 0x1EF700001EF8, + 0x1EF900001EFA, + 0x1EFB00001EFC, + 0x1EFD00001EFE, + 0x1EFF00001F08, + 0x1F1000001F16, + 0x1F2000001F28, + 0x1F3000001F38, + 0x1F4000001F46, + 0x1F5000001F58, + 0x1F6000001F68, + 0x1F7000001F71, + 0x1F7200001F73, + 0x1F7400001F75, + 0x1F7600001F77, + 0x1F7800001F79, + 0x1F7A00001F7B, + 0x1F7C00001F7D, + 0x1FB000001FB2, + 0x1FB600001FB7, + 0x1FC600001FC7, + 0x1FD000001FD3, + 0x1FD600001FD8, + 0x1FE000001FE3, + 0x1FE400001FE8, + 0x1FF600001FF7, + 0x208F00002090, + 0x214E0000214F, + 0x218400002185, + 0x2C3000002C60, + 0x2C6100002C62, + 0x2C6500002C67, + 0x2C6800002C69, + 0x2C6A00002C6B, + 0x2C6C00002C6D, + 0x2C7100002C72, + 0x2C7300002C75, + 0x2C7600002C7C, + 0x2C8100002C82, + 0x2C8300002C84, + 0x2C8500002C86, + 0x2C8700002C88, + 0x2C8900002C8A, + 0x2C8B00002C8C, + 0x2C8D00002C8E, + 0x2C8F00002C90, + 0x2C9100002C92, + 0x2C9300002C94, + 0x2C9500002C96, + 0x2C9700002C98, + 0x2C9900002C9A, + 0x2C9B00002C9C, + 0x2C9D00002C9E, + 0x2C9F00002CA0, + 0x2CA100002CA2, + 0x2CA300002CA4, + 0x2CA500002CA6, + 0x2CA700002CA8, + 0x2CA900002CAA, + 0x2CAB00002CAC, + 0x2CAD00002CAE, + 0x2CAF00002CB0, + 0x2CB100002CB2, + 0x2CB300002CB4, + 0x2CB500002CB6, + 0x2CB700002CB8, + 0x2CB900002CBA, + 0x2CBB00002CBC, + 0x2CBD00002CBE, + 0x2CBF00002CC0, + 0x2CC100002CC2, + 0x2CC300002CC4, + 0x2CC500002CC6, + 0x2CC700002CC8, + 0x2CC900002CCA, + 0x2CCB00002CCC, + 0x2CCD00002CCE, + 0x2CCF00002CD0, + 0x2CD100002CD2, + 0x2CD300002CD4, + 0x2CD500002CD6, + 0x2CD700002CD8, + 0x2CD900002CDA, + 0x2CDB00002CDC, + 0x2CDD00002CDE, + 0x2CDF00002CE0, + 0x2CE100002CE2, + 0x2CE300002CE5, + 0x2CEC00002CED, + 0x2CEE00002CF2, + 0x2CF300002CF4, + 0x2D0000002D26, + 0x2D2700002D28, + 0x2D2D00002D2E, + 0x2D3000002D68, + 0x2D7F00002D97, + 0x2DA000002DA7, + 0x2DA800002DAF, + 0x2DB000002DB7, + 0x2DB800002DBF, + 0x2DC000002DC7, + 0x2DC800002DCF, + 0x2DD000002DD7, + 0x2DD800002DDF, + 0x2DE000002E00, + 0x2E2F00002E30, + 0x300500003008, + 0x302A0000302E, + 0x303C0000303D, + 0x304100003097, + 0x30990000309B, + 0x309D0000309F, + 0x30A1000030FB, + 0x30FC000030FF, + 0x310500003130, + 0x31A0000031C0, + 0x31F000003200, + 0x340000004DC0, + 0x4E000000A48D, + 0xA4D00000A4FE, + 0xA5000000A60D, + 0xA6100000A62C, + 0xA6410000A642, + 0xA6430000A644, + 0xA6450000A646, + 0xA6470000A648, + 0xA6490000A64A, + 0xA64B0000A64C, + 0xA64D0000A64E, + 0xA64F0000A650, + 0xA6510000A652, + 0xA6530000A654, + 0xA6550000A656, + 0xA6570000A658, + 0xA6590000A65A, + 0xA65B0000A65C, + 0xA65D0000A65E, + 0xA65F0000A660, + 0xA6610000A662, + 0xA6630000A664, + 0xA6650000A666, + 0xA6670000A668, + 0xA6690000A66A, + 0xA66B0000A66C, + 0xA66D0000A670, + 0xA6740000A67E, + 0xA67F0000A680, + 0xA6810000A682, + 0xA6830000A684, + 0xA6850000A686, + 0xA6870000A688, + 0xA6890000A68A, + 0xA68B0000A68C, + 0xA68D0000A68E, + 0xA68F0000A690, + 0xA6910000A692, + 0xA6930000A694, + 0xA6950000A696, + 0xA6970000A698, + 0xA6990000A69A, + 0xA69B0000A69C, + 0xA69E0000A6E6, + 0xA6F00000A6F2, + 0xA7170000A720, + 0xA7230000A724, + 0xA7250000A726, + 0xA7270000A728, + 0xA7290000A72A, + 0xA72B0000A72C, + 0xA72D0000A72E, + 0xA72F0000A732, + 0xA7330000A734, + 0xA7350000A736, + 0xA7370000A738, + 0xA7390000A73A, + 0xA73B0000A73C, + 0xA73D0000A73E, + 0xA73F0000A740, + 0xA7410000A742, + 0xA7430000A744, + 0xA7450000A746, + 0xA7470000A748, + 0xA7490000A74A, + 0xA74B0000A74C, + 0xA74D0000A74E, + 0xA74F0000A750, + 0xA7510000A752, + 0xA7530000A754, + 0xA7550000A756, + 0xA7570000A758, + 0xA7590000A75A, + 0xA75B0000A75C, + 0xA75D0000A75E, + 0xA75F0000A760, + 0xA7610000A762, + 0xA7630000A764, + 0xA7650000A766, + 0xA7670000A768, + 0xA7690000A76A, + 0xA76B0000A76C, + 0xA76D0000A76E, + 0xA76F0000A770, + 0xA7710000A779, + 0xA77A0000A77B, + 0xA77C0000A77D, + 0xA77F0000A780, + 0xA7810000A782, + 0xA7830000A784, + 0xA7850000A786, + 0xA7870000A789, + 0xA78C0000A78D, + 0xA78E0000A790, + 0xA7910000A792, + 0xA7930000A796, + 0xA7970000A798, + 0xA7990000A79A, + 0xA79B0000A79C, + 0xA79D0000A79E, + 0xA79F0000A7A0, + 0xA7A10000A7A2, + 0xA7A30000A7A4, + 0xA7A50000A7A6, + 0xA7A70000A7A8, + 0xA7A90000A7AA, + 0xA7AF0000A7B0, + 0xA7B50000A7B6, + 0xA7B70000A7B8, + 0xA7B90000A7BA, + 0xA7BB0000A7BC, + 0xA7BD0000A7BE, + 0xA7BF0000A7C0, + 0xA7C10000A7C2, + 0xA7C30000A7C4, + 0xA7C80000A7C9, + 0xA7CA0000A7CB, + 0xA7CD0000A7CE, + 0xA7CF0000A7D0, + 0xA7D10000A7D2, + 0xA7D30000A7D4, + 0xA7D50000A7D6, + 0xA7D70000A7D8, + 0xA7D90000A7DA, + 0xA7DB0000A7DC, + 0xA7F60000A7F8, + 0xA7FA0000A828, + 0xA82C0000A82D, + 0xA8400000A874, + 0xA8800000A8C6, + 0xA8D00000A8DA, + 0xA8E00000A8F8, + 0xA8FB0000A8FC, + 0xA8FD0000A92E, + 0xA9300000A954, + 0xA9800000A9C1, + 0xA9CF0000A9DA, + 0xA9E00000A9FF, + 0xAA000000AA37, + 0xAA400000AA4E, + 0xAA500000AA5A, + 0xAA600000AA77, + 0xAA7A0000AAC3, + 0xAADB0000AADE, + 0xAAE00000AAF0, + 0xAAF20000AAF7, + 0xAB010000AB07, + 0xAB090000AB0F, + 0xAB110000AB17, + 0xAB200000AB27, + 0xAB280000AB2F, + 0xAB300000AB5B, + 0xAB600000AB69, + 0xABC00000ABEB, + 0xABEC0000ABEE, + 0xABF00000ABFA, + 0xAC000000D7A4, + 0xFA0E0000FA10, + 0xFA110000FA12, + 0xFA130000FA15, + 0xFA1F0000FA20, + 0xFA210000FA22, + 0xFA230000FA25, + 0xFA270000FA2A, + 0xFB1E0000FB1F, + 0xFE200000FE30, + 0xFE730000FE74, + 0x100000001000C, + 0x1000D00010027, + 0x100280001003B, + 0x1003C0001003E, + 0x1003F0001004E, + 0x100500001005E, + 0x10080000100FB, + 0x101FD000101FE, + 0x102800001029D, + 0x102A0000102D1, + 0x102E0000102E1, + 0x1030000010320, + 0x1032D00010341, + 0x103420001034A, + 0x103500001037B, + 0x103800001039E, + 0x103A0000103C4, + 0x103C8000103D0, + 0x104280001049E, + 0x104A0000104AA, + 0x104D8000104FC, + 0x1050000010528, + 0x1053000010564, + 0x10597000105A2, + 0x105A3000105B2, + 0x105B3000105BA, + 0x105BB000105BD, + 0x105C0000105F4, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1078000010781, + 0x1080000010806, + 0x1080800010809, + 0x1080A00010836, + 0x1083700010839, + 0x1083C0001083D, + 0x1083F00010856, + 0x1086000010877, + 0x108800001089F, + 0x108E0000108F3, + 0x108F4000108F6, + 0x1090000010916, + 0x109200001093A, + 0x109400001095A, + 0x10980000109B8, + 0x109BE000109C0, + 0x10A0000010A04, + 0x10A0500010A07, + 0x10A0C00010A14, + 0x10A1500010A18, + 0x10A1900010A36, + 0x10A3800010A3B, + 0x10A3F00010A40, + 0x10A6000010A7D, + 0x10A8000010A9D, + 0x10AC000010AC8, + 0x10AC900010AE7, + 0x10B0000010B36, + 0x10B4000010B56, + 0x10B6000010B73, + 0x10B8000010B92, + 0x10C0000010C49, + 0x10CC000010CF3, + 0x10D0000010D28, + 0x10D3000010D3A, + 0x10D4000010D50, + 0x10D6900010D6E, + 0x10D6F00010D86, + 0x10E8000010EAA, + 0x10EAB00010EAD, + 0x10EB000010EB2, + 0x10EC200010EC8, + 0x10ECB00010ED0, + 0x10ED900010EEF, + 0x10EF000010F1D, + 0x10F2700010F28, + 0x10F3000010F51, + 0x10F7000010F86, + 0x10FB000010FC5, + 0x10FE000010FF7, + 0x1100000011047, + 0x1106600011076, + 0x1107F000110BB, + 0x110C2000110C3, + 0x110D0000110E9, + 0x110F0000110FA, + 0x1110000011135, + 0x1113600011140, + 0x1114400011148, + 0x1115000011174, + 0x1117600011177, + 0x11180000111C5, + 0x111C9000111CD, + 0x111CE000111DB, + 0x111DC000111DD, + 0x1120000011212, + 0x1121300011238, + 0x1123E00011242, + 0x1128000011287, + 0x1128800011289, + 0x1128A0001128E, + 0x1128F0001129E, + 0x1129F000112A9, + 0x112B0000112EB, + 0x112F0000112FA, + 0x1130000011304, + 0x113050001130D, + 0x1130F00011311, + 0x1131300011329, + 0x1132A00011331, + 0x1133200011334, + 0x113350001133A, + 0x1133B00011345, + 0x1134700011349, + 0x1134B0001134E, + 0x1135000011351, + 0x1135700011358, + 0x1135D00011364, + 0x113660001136D, + 0x1137000011375, + 0x113800001138A, + 0x1138B0001138C, + 0x1138E0001138F, + 0x11390000113B6, + 0x113B7000113C1, + 0x113C2000113C3, + 0x113C5000113C6, + 0x113C7000113CB, + 0x113CC000113D4, + 0x113E1000113E3, + 0x114000001144B, + 0x114500001145A, + 0x1145E00011462, + 0x11480000114C6, + 0x114C7000114C8, + 0x114D0000114DA, + 0x11580000115B6, + 0x115B8000115C1, + 0x115D8000115DE, + 0x1160000011641, + 0x1164400011645, + 0x116500001165A, + 0x11680000116B9, + 0x116C0000116CA, + 0x116D0000116E4, + 0x117000001171B, + 0x1171D0001172C, + 0x117300001173A, + 0x1174000011747, + 0x118000001183B, + 0x118C0000118EA, + 0x118FF00011907, + 0x119090001190A, + 0x1190C00011914, + 0x1191500011917, + 0x1191800011936, + 0x1193700011939, + 0x1193B00011944, + 0x119500001195A, + 0x119A0000119A8, + 0x119AA000119D8, + 0x119DA000119E2, + 0x119E3000119E5, + 0x11A0000011A3F, + 0x11A4700011A48, + 0x11A5000011A9A, + 0x11A9D00011A9E, + 0x11AB000011AF9, + 0x11B0A00011B0B, + 0x11B6000011B68, + 0x11BC000011BE1, + 0x11BF000011BFA, + 0x11C0000011C09, + 0x11C0A00011C37, + 0x11C3800011C41, + 0x11C5000011C5A, + 0x11C7200011C90, + 0x11C9200011CA8, + 0x11CA900011CB7, + 0x11D0000011D07, + 0x11D0800011D0A, + 0x11D0B00011D37, + 0x11D3A00011D3B, + 0x11D3C00011D3E, + 0x11D3F00011D48, + 0x11D5000011D5A, + 0x11D6000011D66, + 0x11D6700011D69, + 0x11D6A00011D8F, + 0x11D9000011D92, + 0x11D9300011D99, + 0x11DA000011DAA, + 0x11DB000011DDC, + 0x11DE000011DEA, + 0x11DF000011DF2, + 0x11EE000011EF7, + 0x11F0000011F11, + 0x11F1200011F3B, + 0x11F3E00011F43, + 0x11F5000011F5B, + 0x11FB000011FB1, + 0x120000001239A, + 0x1248000012544, + 0x12F9000012FF1, + 0x1300000013430, + 0x1344000013456, + 0x13460000143FB, + 0x1440000014647, + 0x161000001613A, + 0x1680000016A39, + 0x16A4000016A5F, + 0x16A6000016A6A, + 0x16A7000016ABF, + 0x16AC000016ACA, + 0x16AD000016AEE, + 0x16AF000016AF5, + 0x16B0000016B37, + 0x16B4000016B44, + 0x16B5000016B5A, + 0x16B6300016B78, + 0x16B7D00016B90, + 0x16D4000016D6D, + 0x16D7000016D7A, + 0x16E6000016E80, + 0x16EBB00016ED4, + 0x16F0000016F4B, + 0x16F4F00016F88, + 0x16F8F00016FA0, + 0x16FE000016FE2, + 0x16FE300016FE5, + 0x16FF000016FF4, + 0x1700000018CDB, + 0x18CFF00018D21, + 0x18D8000018DF3, + 0x18E0000019192, + 0x191A0000191D3, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B123, + 0x1B1270001B129, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1B1550001B156, + 0x1B1640001B169, + 0x1B1700001B2FC, + 0x1BC000001BC6B, + 0x1BC700001BC7D, + 0x1BC800001BC89, + 0x1BC900001BC9A, + 0x1BC9D0001BC9F, + 0x1CF000001CF2E, + 0x1CF300001CF47, + 0x1D2500001D253, + 0x1D25B0001D25D, + 0x1D25F0001D260, + 0x1D2800001D282, + 0x1DA000001DA37, + 0x1DA3B0001DA6D, + 0x1DA750001DA76, + 0x1DA840001DA85, + 0x1DA9B0001DAA0, + 0x1DAA10001DAB0, + 0x1DF000001DF40, + 0x1DF410001DF48, + 0x1DF490001DF4A, + 0x1DF4B0001DF4D, + 0x1DF4E0001DF51, + 0x1DF520001DF68, + 0x1DF690001DF6A, + 0x1DF6B0001DF6C, + 0x1DF6D0001DF6E, + 0x1DF6F0001DF72, + 0x1DF730001DF74, + 0x1DF750001DF76, + 0x1DF770001DF78, + 0x1DF790001DF7A, + 0x1DF7B0001DF7C, + 0x1DF7D0001DF7E, + 0x1DF7F0001DF82, + 0x1DF900001DF95, + 0x1DF960001DF97, + 0x1E0000001E007, + 0x1E0080001E019, + 0x1E01B0001E022, + 0x1E0230001E025, + 0x1E0260001E02B, + 0x1E08F0001E090, + 0x1E1000001E12D, + 0x1E1300001E13E, + 0x1E1400001E14A, + 0x1E14E0001E14F, + 0x1E2900001E2AF, + 0x1E2C00001E2FA, + 0x1E4D00001E4FA, + 0x1E5D00001E5FB, + 0x1E6C00001E6DF, + 0x1E6E00001E6F6, + 0x1E6FE0001E700, + 0x1E7E00001E7E7, + 0x1E7E80001E7EC, + 0x1E7ED0001E7EF, + 0x1E7F00001E7FF, + 0x1E8000001E8C5, + 0x1E8D00001E8D7, + 0x1E9220001E94C, + 0x1E9500001E95A, + 0x200000002A6E0, + 0x2A7000002B81F, + 0x2B8200002CEAE, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x300000003134B, + 0x313500003347A, + 0x3D0000003FC40, + ), + "CONTEXTJ": (0x200C0000200E,), + "CONTEXTO": ( + 0xB7000000B8, + 0x37500000376, + 0x5F3000005F5, + 0x6600000066A, + 0x6F0000006FA, + 0x30FB000030FC, + ), +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py new file mode 100644 index 00000000000..19d77810caf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py @@ -0,0 +1,55 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect + + +def intranges_from_list(list_: list[int]) -> tuple[int, ...]: + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i + 1 < len(sorted_list) and sorted_list[i] == sorted_list[i + 1] - 1: + continue + current_range = sorted_list[last_write + 1 : i + 1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + + +def _encode_range(start: int, end: int) -> int: + return (start << 32) | end + + +def _decode_range(r: int) -> tuple[int, int]: + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_: int, ranges: tuple[int, ...]) -> bool: + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos - 1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py new file mode 100644 index 00000000000..2f9ff7e825c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py @@ -0,0 +1 @@ +__version__ = "3.20" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py new file mode 100644 index 00000000000..dbfb60ff4b3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py @@ -0,0 +1,17117 @@ +# This file is automatically generated by tools/idna-data + +from __future__ import annotations + +from array import array + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "18.0.0" + +uts46_starts: array[int] = array( + "I", + ( + 0x0, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0x9, + 0xA, + 0xB, + 0xC, + 0xD, + 0xE, + 0xF, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0x1A, + 0x1B, + 0x1C, + 0x1D, + 0x1E, + 0x1F, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2A, + 0x2B, + 0x2C, + 0x2D, + 0x2E, + 0x2F, + 0x30, + 0x31, + 0x32, + 0x33, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3A, + 0x3B, + 0x3C, + 0x3D, + 0x3E, + 0x3F, + 0x40, + 0x41, + 0x42, + 0x43, + 0x44, + 0x45, + 0x46, + 0x47, + 0x48, + 0x49, + 0x4A, + 0x4B, + 0x4C, + 0x4D, + 0x4E, + 0x4F, + 0x50, + 0x51, + 0x52, + 0x53, + 0x54, + 0x55, + 0x56, + 0x57, + 0x58, + 0x59, + 0x5A, + 0x5B, + 0x5C, + 0x5D, + 0x5E, + 0x5F, + 0x60, + 0x61, + 0x62, + 0x63, + 0x64, + 0x65, + 0x66, + 0x67, + 0x68, + 0x69, + 0x6A, + 0x6B, + 0x6C, + 0x6D, + 0x6E, + 0x6F, + 0x70, + 0x71, + 0x72, + 0x73, + 0x74, + 0x75, + 0x76, + 0x77, + 0x78, + 0x79, + 0x7A, + 0x7B, + 0x7C, + 0x7D, + 0x7E, + 0x7F, + 0x80, + 0x81, + 0x82, + 0x83, + 0x84, + 0x85, + 0x86, + 0x87, + 0x88, + 0x89, + 0x8A, + 0x8B, + 0x8C, + 0x8D, + 0x8E, + 0x8F, + 0x90, + 0x91, + 0x92, + 0x93, + 0x94, + 0x95, + 0x96, + 0x97, + 0x98, + 0x99, + 0x9A, + 0x9B, + 0x9C, + 0x9D, + 0x9E, + 0x9F, + 0xA0, + 0xA1, + 0xA2, + 0xA3, + 0xA4, + 0xA5, + 0xA6, + 0xA7, + 0xA8, + 0xA9, + 0xAA, + 0xAB, + 0xAC, + 0xAD, + 0xAE, + 0xAF, + 0xB0, + 0xB1, + 0xB2, + 0xB3, + 0xB4, + 0xB5, + 0xB6, + 0xB7, + 0xB8, + 0xB9, + 0xBA, + 0xBB, + 0xBC, + 0xBD, + 0xBE, + 0xBF, + 0xC0, + 0xC1, + 0xC2, + 0xC3, + 0xC4, + 0xC5, + 0xC6, + 0xC7, + 0xC8, + 0xC9, + 0xCA, + 0xCB, + 0xCC, + 0xCD, + 0xCE, + 0xCF, + 0xD0, + 0xD1, + 0xD2, + 0xD3, + 0xD4, + 0xD5, + 0xD6, + 0xD7, + 0xD8, + 0xD9, + 0xDA, + 0xDB, + 0xDC, + 0xDD, + 0xDE, + 0xDF, + 0xE0, + 0xE1, + 0xE2, + 0xE3, + 0xE4, + 0xE5, + 0xE6, + 0xE7, + 0xE8, + 0xE9, + 0xEA, + 0xEB, + 0xEC, + 0xED, + 0xEE, + 0xEF, + 0xF0, + 0xF1, + 0xF2, + 0xF3, + 0xF4, + 0xF5, + 0xF6, + 0xF7, + 0xF8, + 0xF9, + 0xFA, + 0xFB, + 0xFC, + 0xFD, + 0xFE, + 0xFF, + 0x100, + 0x101, + 0x102, + 0x103, + 0x104, + 0x105, + 0x106, + 0x107, + 0x108, + 0x109, + 0x10A, + 0x10B, + 0x10C, + 0x10D, + 0x10E, + 0x10F, + 0x110, + 0x111, + 0x112, + 0x113, + 0x114, + 0x115, + 0x116, + 0x117, + 0x118, + 0x119, + 0x11A, + 0x11B, + 0x11C, + 0x11D, + 0x11E, + 0x11F, + 0x120, + 0x121, + 0x122, + 0x123, + 0x124, + 0x125, + 0x126, + 0x127, + 0x128, + 0x129, + 0x12A, + 0x12B, + 0x12C, + 0x12D, + 0x12E, + 0x12F, + 0x130, + 0x131, + 0x132, + 0x134, + 0x135, + 0x136, + 0x137, + 0x139, + 0x13A, + 0x13B, + 0x13C, + 0x13D, + 0x13E, + 0x13F, + 0x141, + 0x142, + 0x143, + 0x144, + 0x145, + 0x146, + 0x147, + 0x148, + 0x149, + 0x14A, + 0x14B, + 0x14C, + 0x14D, + 0x14E, + 0x14F, + 0x150, + 0x151, + 0x152, + 0x153, + 0x154, + 0x155, + 0x156, + 0x157, + 0x158, + 0x159, + 0x15A, + 0x15B, + 0x15C, + 0x15D, + 0x15E, + 0x15F, + 0x160, + 0x161, + 0x162, + 0x163, + 0x164, + 0x165, + 0x166, + 0x167, + 0x168, + 0x169, + 0x16A, + 0x16B, + 0x16C, + 0x16D, + 0x16E, + 0x16F, + 0x170, + 0x171, + 0x172, + 0x173, + 0x174, + 0x175, + 0x176, + 0x177, + 0x178, + 0x179, + 0x17A, + 0x17B, + 0x17C, + 0x17D, + 0x17E, + 0x17F, + 0x180, + 0x181, + 0x182, + 0x183, + 0x184, + 0x185, + 0x186, + 0x187, + 0x188, + 0x189, + 0x18A, + 0x18B, + 0x18C, + 0x18E, + 0x18F, + 0x190, + 0x191, + 0x192, + 0x193, + 0x194, + 0x195, + 0x196, + 0x197, + 0x198, + 0x199, + 0x19C, + 0x19D, + 0x19E, + 0x19F, + 0x1A0, + 0x1A1, + 0x1A2, + 0x1A3, + 0x1A4, + 0x1A5, + 0x1A6, + 0x1A7, + 0x1A8, + 0x1A9, + 0x1AA, + 0x1AC, + 0x1AD, + 0x1AE, + 0x1AF, + 0x1B0, + 0x1B1, + 0x1B2, + 0x1B3, + 0x1B4, + 0x1B5, + 0x1B6, + 0x1B7, + 0x1B8, + 0x1B9, + 0x1BC, + 0x1BD, + 0x1C4, + 0x1C7, + 0x1CA, + 0x1CD, + 0x1CE, + 0x1CF, + 0x1D0, + 0x1D1, + 0x1D2, + 0x1D3, + 0x1D4, + 0x1D5, + 0x1D6, + 0x1D7, + 0x1D8, + 0x1D9, + 0x1DA, + 0x1DB, + 0x1DC, + 0x1DE, + 0x1DF, + 0x1E0, + 0x1E1, + 0x1E2, + 0x1E3, + 0x1E4, + 0x1E5, + 0x1E6, + 0x1E7, + 0x1E8, + 0x1E9, + 0x1EA, + 0x1EB, + 0x1EC, + 0x1ED, + 0x1EE, + 0x1EF, + 0x1F1, + 0x1F4, + 0x1F5, + 0x1F6, + 0x1F7, + 0x1F8, + 0x1F9, + 0x1FA, + 0x1FB, + 0x1FC, + 0x1FD, + 0x1FE, + 0x1FF, + 0x200, + 0x201, + 0x202, + 0x203, + 0x204, + 0x205, + 0x206, + 0x207, + 0x208, + 0x209, + 0x20A, + 0x20B, + 0x20C, + 0x20D, + 0x20E, + 0x20F, + 0x210, + 0x211, + 0x212, + 0x213, + 0x214, + 0x215, + 0x216, + 0x217, + 0x218, + 0x219, + 0x21A, + 0x21B, + 0x21C, + 0x21D, + 0x21E, + 0x21F, + 0x220, + 0x221, + 0x222, + 0x223, + 0x224, + 0x225, + 0x226, + 0x227, + 0x228, + 0x229, + 0x22A, + 0x22B, + 0x22C, + 0x22D, + 0x22E, + 0x22F, + 0x230, + 0x231, + 0x232, + 0x233, + 0x23A, + 0x23B, + 0x23C, + 0x23D, + 0x23E, + 0x23F, + 0x241, + 0x242, + 0x243, + 0x244, + 0x245, + 0x246, + 0x247, + 0x248, + 0x249, + 0x24A, + 0x24B, + 0x24C, + 0x24D, + 0x24E, + 0x24F, + 0x2B0, + 0x2B1, + 0x2B2, + 0x2B3, + 0x2B4, + 0x2B5, + 0x2B6, + 0x2B7, + 0x2B8, + 0x2B9, + 0x2D8, + 0x2D9, + 0x2DA, + 0x2DB, + 0x2DC, + 0x2DD, + 0x2DE, + 0x2E0, + 0x2E1, + 0x2E2, + 0x2E3, + 0x2E4, + 0x2E5, + 0x340, + 0x341, + 0x342, + 0x343, + 0x344, + 0x345, + 0x346, + 0x34F, + 0x350, + 0x370, + 0x371, + 0x372, + 0x373, + 0x374, + 0x375, + 0x376, + 0x377, + 0x378, + 0x37A, + 0x37B, + 0x37E, + 0x37F, + 0x380, + 0x384, + 0x385, + 0x386, + 0x387, + 0x388, + 0x389, + 0x38A, + 0x38B, + 0x38C, + 0x38D, + 0x38E, + 0x38F, + 0x390, + 0x391, + 0x392, + 0x393, + 0x394, + 0x395, + 0x396, + 0x397, + 0x398, + 0x399, + 0x39A, + 0x39B, + 0x39C, + 0x39D, + 0x39E, + 0x39F, + 0x3A0, + 0x3A1, + 0x3A2, + 0x3A3, + 0x3A4, + 0x3A5, + 0x3A6, + 0x3A7, + 0x3A8, + 0x3A9, + 0x3AA, + 0x3AB, + 0x3AC, + 0x3C2, + 0x3C3, + 0x3CF, + 0x3D0, + 0x3D1, + 0x3D2, + 0x3D3, + 0x3D4, + 0x3D5, + 0x3D6, + 0x3D7, + 0x3D8, + 0x3D9, + 0x3DA, + 0x3DB, + 0x3DC, + 0x3DD, + 0x3DE, + 0x3DF, + 0x3E0, + 0x3E1, + 0x3E2, + 0x3E3, + 0x3E4, + 0x3E5, + 0x3E6, + 0x3E7, + 0x3E8, + 0x3E9, + 0x3EA, + 0x3EB, + 0x3EC, + 0x3ED, + 0x3EE, + 0x3EF, + 0x3F0, + 0x3F1, + 0x3F2, + 0x3F3, + 0x3F4, + 0x3F5, + 0x3F6, + 0x3F7, + 0x3F8, + 0x3F9, + 0x3FA, + 0x3FB, + 0x3FD, + 0x3FE, + 0x3FF, + 0x400, + 0x401, + 0x402, + 0x403, + 0x404, + 0x405, + 0x406, + 0x407, + 0x408, + 0x409, + 0x40A, + 0x40B, + 0x40C, + 0x40D, + 0x40E, + 0x40F, + 0x410, + 0x411, + 0x412, + 0x413, + 0x414, + 0x415, + 0x416, + 0x417, + 0x418, + 0x419, + 0x41A, + 0x41B, + 0x41C, + 0x41D, + 0x41E, + 0x41F, + 0x420, + 0x421, + 0x422, + 0x423, + 0x424, + 0x425, + 0x426, + 0x427, + 0x428, + 0x429, + 0x42A, + 0x42B, + 0x42C, + 0x42D, + 0x42E, + 0x42F, + 0x430, + 0x460, + 0x461, + 0x462, + 0x463, + 0x464, + 0x465, + 0x466, + 0x467, + 0x468, + 0x469, + 0x46A, + 0x46B, + 0x46C, + 0x46D, + 0x46E, + 0x46F, + 0x470, + 0x471, + 0x472, + 0x473, + 0x474, + 0x475, + 0x476, + 0x477, + 0x478, + 0x479, + 0x47A, + 0x47B, + 0x47C, + 0x47D, + 0x47E, + 0x47F, + 0x480, + 0x481, + 0x48A, + 0x48B, + 0x48C, + 0x48D, + 0x48E, + 0x48F, + 0x490, + 0x491, + 0x492, + 0x493, + 0x494, + 0x495, + 0x496, + 0x497, + 0x498, + 0x499, + 0x49A, + 0x49B, + 0x49C, + 0x49D, + 0x49E, + 0x49F, + 0x4A0, + 0x4A1, + 0x4A2, + 0x4A3, + 0x4A4, + 0x4A5, + 0x4A6, + 0x4A7, + 0x4A8, + 0x4A9, + 0x4AA, + 0x4AB, + 0x4AC, + 0x4AD, + 0x4AE, + 0x4AF, + 0x4B0, + 0x4B1, + 0x4B2, + 0x4B3, + 0x4B4, + 0x4B5, + 0x4B6, + 0x4B7, + 0x4B8, + 0x4B9, + 0x4BA, + 0x4BB, + 0x4BC, + 0x4BD, + 0x4BE, + 0x4BF, + 0x4C0, + 0x4C1, + 0x4C2, + 0x4C3, + 0x4C4, + 0x4C5, + 0x4C6, + 0x4C7, + 0x4C8, + 0x4C9, + 0x4CA, + 0x4CB, + 0x4CC, + 0x4CD, + 0x4CE, + 0x4D0, + 0x4D1, + 0x4D2, + 0x4D3, + 0x4D4, + 0x4D5, + 0x4D6, + 0x4D7, + 0x4D8, + 0x4D9, + 0x4DA, + 0x4DB, + 0x4DC, + 0x4DD, + 0x4DE, + 0x4DF, + 0x4E0, + 0x4E1, + 0x4E2, + 0x4E3, + 0x4E4, + 0x4E5, + 0x4E6, + 0x4E7, + 0x4E8, + 0x4E9, + 0x4EA, + 0x4EB, + 0x4EC, + 0x4ED, + 0x4EE, + 0x4EF, + 0x4F0, + 0x4F1, + 0x4F2, + 0x4F3, + 0x4F4, + 0x4F5, + 0x4F6, + 0x4F7, + 0x4F8, + 0x4F9, + 0x4FA, + 0x4FB, + 0x4FC, + 0x4FD, + 0x4FE, + 0x4FF, + 0x500, + 0x501, + 0x502, + 0x503, + 0x504, + 0x505, + 0x506, + 0x507, + 0x508, + 0x509, + 0x50A, + 0x50B, + 0x50C, + 0x50D, + 0x50E, + 0x50F, + 0x510, + 0x511, + 0x512, + 0x513, + 0x514, + 0x515, + 0x516, + 0x517, + 0x518, + 0x519, + 0x51A, + 0x51B, + 0x51C, + 0x51D, + 0x51E, + 0x51F, + 0x520, + 0x521, + 0x522, + 0x523, + 0x524, + 0x525, + 0x526, + 0x527, + 0x528, + 0x529, + 0x52A, + 0x52B, + 0x52C, + 0x52D, + 0x52E, + 0x52F, + 0x530, + 0x531, + 0x532, + 0x533, + 0x534, + 0x535, + 0x536, + 0x537, + 0x538, + 0x539, + 0x53A, + 0x53B, + 0x53C, + 0x53D, + 0x53E, + 0x53F, + 0x540, + 0x541, + 0x542, + 0x543, + 0x544, + 0x545, + 0x546, + 0x547, + 0x548, + 0x549, + 0x54A, + 0x54B, + 0x54C, + 0x54D, + 0x54E, + 0x54F, + 0x550, + 0x551, + 0x552, + 0x553, + 0x554, + 0x555, + 0x556, + 0x557, + 0x558, + 0x559, + 0x587, + 0x588, + 0x58B, + 0x58C, + 0x58D, + 0x590, + 0x591, + 0x5CA, + 0x5D0, + 0x5EB, + 0x5EF, + 0x5F5, + 0x606, + 0x61C, + 0x61D, + 0x675, + 0x676, + 0x677, + 0x678, + 0x679, + 0x6DD, + 0x6DE, + 0x70E, + 0x710, + 0x74B, + 0x74D, + 0x7B2, + 0x7C0, + 0x7FB, + 0x7FD, + 0x82E, + 0x830, + 0x83F, + 0x840, + 0x85C, + 0x85E, + 0x85F, + 0x860, + 0x86B, + 0x870, + 0x890, + 0x897, + 0x8E2, + 0x8E3, + 0x958, + 0x959, + 0x95A, + 0x95B, + 0x95C, + 0x95D, + 0x95E, + 0x95F, + 0x960, + 0x984, + 0x985, + 0x98D, + 0x98F, + 0x991, + 0x993, + 0x9A9, + 0x9AA, + 0x9B1, + 0x9B2, + 0x9B3, + 0x9B6, + 0x9BA, + 0x9BC, + 0x9C5, + 0x9C7, + 0x9C9, + 0x9CB, + 0x9CF, + 0x9D7, + 0x9D8, + 0x9DC, + 0x9DD, + 0x9DE, + 0x9DF, + 0x9E0, + 0x9E4, + 0x9E6, + 0x9FF, + 0xA01, + 0xA04, + 0xA05, + 0xA0B, + 0xA0F, + 0xA11, + 0xA13, + 0xA29, + 0xA2A, + 0xA31, + 0xA32, + 0xA33, + 0xA34, + 0xA35, + 0xA36, + 0xA37, + 0xA38, + 0xA3A, + 0xA3C, + 0xA3D, + 0xA3E, + 0xA43, + 0xA47, + 0xA49, + 0xA4B, + 0xA4E, + 0xA51, + 0xA52, + 0xA59, + 0xA5A, + 0xA5B, + 0xA5C, + 0xA5D, + 0xA5E, + 0xA5F, + 0xA66, + 0xA77, + 0xA81, + 0xA84, + 0xA85, + 0xA8E, + 0xA8F, + 0xA92, + 0xA93, + 0xAA9, + 0xAAA, + 0xAB1, + 0xAB2, + 0xAB4, + 0xAB5, + 0xABA, + 0xABC, + 0xAC6, + 0xAC7, + 0xACA, + 0xACB, + 0xACE, + 0xAD0, + 0xAD1, + 0xAE0, + 0xAE4, + 0xAE6, + 0xAF2, + 0xAF9, + 0xB00, + 0xB01, + 0xB04, + 0xB05, + 0xB0D, + 0xB0F, + 0xB11, + 0xB13, + 0xB29, + 0xB2A, + 0xB31, + 0xB32, + 0xB34, + 0xB35, + 0xB3A, + 0xB3C, + 0xB45, + 0xB47, + 0xB49, + 0xB4B, + 0xB4E, + 0xB53, + 0xB58, + 0xB5C, + 0xB5D, + 0xB5E, + 0xB5F, + 0xB64, + 0xB66, + 0xB78, + 0xB82, + 0xB84, + 0xB85, + 0xB8B, + 0xB8E, + 0xB91, + 0xB92, + 0xB96, + 0xB99, + 0xB9B, + 0xB9C, + 0xB9D, + 0xB9E, + 0xBA0, + 0xBA3, + 0xBA5, + 0xBA8, + 0xBAB, + 0xBAE, + 0xBBA, + 0xBBE, + 0xBC3, + 0xBC6, + 0xBC9, + 0xBCA, + 0xBCE, + 0xBD0, + 0xBD1, + 0xBD7, + 0xBD8, + 0xBE6, + 0xBFB, + 0xC00, + 0xC0D, + 0xC0E, + 0xC11, + 0xC12, + 0xC29, + 0xC2A, + 0xC3A, + 0xC3C, + 0xC45, + 0xC46, + 0xC49, + 0xC4A, + 0xC4E, + 0xC55, + 0xC57, + 0xC58, + 0xC5B, + 0xC5C, + 0xC5E, + 0xC60, + 0xC64, + 0xC66, + 0xC70, + 0xC77, + 0xC8D, + 0xC8E, + 0xC91, + 0xC92, + 0xCA9, + 0xCAA, + 0xCB4, + 0xCB5, + 0xCBA, + 0xCBC, + 0xCC5, + 0xCC6, + 0xCC9, + 0xCCA, + 0xCCE, + 0xCD5, + 0xCD7, + 0xCDC, + 0xCDF, + 0xCE0, + 0xCE4, + 0xCE6, + 0xCF0, + 0xCF1, + 0xCF4, + 0xD00, + 0xD0D, + 0xD0E, + 0xD11, + 0xD12, + 0xD45, + 0xD46, + 0xD49, + 0xD4A, + 0xD50, + 0xD54, + 0xD64, + 0xD66, + 0xD80, + 0xD81, + 0xD84, + 0xD85, + 0xD97, + 0xD9A, + 0xDB2, + 0xDB3, + 0xDBC, + 0xDBD, + 0xDBE, + 0xDC0, + 0xDC7, + 0xDCA, + 0xDCB, + 0xDCF, + 0xDD5, + 0xDD6, + 0xDD7, + 0xDD8, + 0xDE0, + 0xDE6, + 0xDF0, + 0xDF2, + 0xDF5, + 0xE01, + 0xE33, + 0xE34, + 0xE3B, + 0xE3F, + 0xE5C, + 0xE81, + 0xE83, + 0xE84, + 0xE85, + 0xE86, + 0xE8B, + 0xE8C, + 0xEA4, + 0xEA5, + 0xEA6, + 0xEA7, + 0xEB3, + 0xEB4, + 0xEBE, + 0xEC0, + 0xEC5, + 0xEC6, + 0xEC7, + 0xEC8, + 0xECF, + 0xED0, + 0xEDA, + 0xEDC, + 0xEDD, + 0xEDE, + 0xEE0, + 0xF00, + 0xF0C, + 0xF0D, + 0xF43, + 0xF44, + 0xF48, + 0xF49, + 0xF4D, + 0xF4E, + 0xF52, + 0xF53, + 0xF57, + 0xF58, + 0xF5C, + 0xF5D, + 0xF69, + 0xF6A, + 0xF6D, + 0xF71, + 0xF73, + 0xF74, + 0xF75, + 0xF76, + 0xF77, + 0xF78, + 0xF79, + 0xF7A, + 0xF81, + 0xF82, + 0xF93, + 0xF94, + 0xF98, + 0xF99, + 0xF9D, + 0xF9E, + 0xFA2, + 0xFA3, + 0xFA7, + 0xFA8, + 0xFAC, + 0xFAD, + 0xFB9, + 0xFBA, + 0xFBD, + 0xFBE, + 0xFCD, + 0xFCE, + 0xFDB, + 0x1000, + 0x10A0, + 0x10A1, + 0x10A2, + 0x10A3, + 0x10A4, + 0x10A5, + 0x10A6, + 0x10A7, + 0x10A8, + 0x10A9, + 0x10AA, + 0x10AB, + 0x10AC, + 0x10AD, + 0x10AE, + 0x10AF, + 0x10B0, + 0x10B1, + 0x10B2, + 0x10B3, + 0x10B4, + 0x10B5, + 0x10B6, + 0x10B7, + 0x10B8, + 0x10B9, + 0x10BA, + 0x10BB, + 0x10BC, + 0x10BD, + 0x10BE, + 0x10BF, + 0x10C0, + 0x10C1, + 0x10C2, + 0x10C3, + 0x10C4, + 0x10C5, + 0x10C6, + 0x10C7, + 0x10C8, + 0x10CD, + 0x10CE, + 0x10D0, + 0x10FC, + 0x10FD, + 0x115F, + 0x1161, + 0x1249, + 0x124A, + 0x124E, + 0x1250, + 0x1257, + 0x1258, + 0x1259, + 0x125A, + 0x125E, + 0x1260, + 0x1289, + 0x128A, + 0x128E, + 0x1290, + 0x12B1, + 0x12B2, + 0x12B6, + 0x12B8, + 0x12BF, + 0x12C0, + 0x12C1, + 0x12C2, + 0x12C6, + 0x12C8, + 0x12D7, + 0x12D8, + 0x1311, + 0x1312, + 0x1316, + 0x1318, + 0x135B, + 0x135D, + 0x137D, + 0x1380, + 0x139A, + 0x13A0, + 0x13F6, + 0x13F8, + 0x13F9, + 0x13FA, + 0x13FB, + 0x13FC, + 0x13FD, + 0x13FE, + 0x1400, + 0x1680, + 0x1681, + 0x169D, + 0x16A0, + 0x16F9, + 0x1700, + 0x1716, + 0x171F, + 0x1737, + 0x1740, + 0x1754, + 0x1760, + 0x176D, + 0x176E, + 0x1771, + 0x1772, + 0x1774, + 0x1780, + 0x17B4, + 0x17B6, + 0x17DE, + 0x17E0, + 0x17EA, + 0x17F0, + 0x17FA, + 0x1800, + 0x180B, + 0x1810, + 0x181A, + 0x1820, + 0x1879, + 0x1880, + 0x18AB, + 0x18B0, + 0x18F6, + 0x1900, + 0x191F, + 0x1920, + 0x192C, + 0x1930, + 0x193C, + 0x1940, + 0x1941, + 0x1944, + 0x196E, + 0x1970, + 0x1975, + 0x1980, + 0x19AC, + 0x19B0, + 0x19CA, + 0x19D0, + 0x19DB, + 0x19DE, + 0x1A1C, + 0x1A1E, + 0x1A5F, + 0x1A60, + 0x1A7D, + 0x1A7F, + 0x1A8A, + 0x1A90, + 0x1A9A, + 0x1AA0, + 0x1AAE, + 0x1AB0, + 0x1AF1, + 0x1B00, + 0x1B4D, + 0x1B4E, + 0x1BF4, + 0x1BFC, + 0x1C38, + 0x1C3B, + 0x1C4A, + 0x1C4D, + 0x1C80, + 0x1C81, + 0x1C82, + 0x1C83, + 0x1C84, + 0x1C86, + 0x1C87, + 0x1C88, + 0x1C89, + 0x1C8A, + 0x1C8B, + 0x1C90, + 0x1C91, + 0x1C92, + 0x1C93, + 0x1C94, + 0x1C95, + 0x1C96, + 0x1C97, + 0x1C98, + 0x1C99, + 0x1C9A, + 0x1C9B, + 0x1C9C, + 0x1C9D, + 0x1C9E, + 0x1C9F, + 0x1CA0, + 0x1CA1, + 0x1CA2, + 0x1CA3, + 0x1CA4, + 0x1CA5, + 0x1CA6, + 0x1CA7, + 0x1CA8, + 0x1CA9, + 0x1CAA, + 0x1CAB, + 0x1CAC, + 0x1CAD, + 0x1CAE, + 0x1CAF, + 0x1CB0, + 0x1CB1, + 0x1CB2, + 0x1CB3, + 0x1CB4, + 0x1CB5, + 0x1CB6, + 0x1CB7, + 0x1CB8, + 0x1CB9, + 0x1CBA, + 0x1CBB, + 0x1CBD, + 0x1CBE, + 0x1CBF, + 0x1CC0, + 0x1CC8, + 0x1CD0, + 0x1CFB, + 0x1D00, + 0x1D2C, + 0x1D2D, + 0x1D2E, + 0x1D2F, + 0x1D30, + 0x1D31, + 0x1D32, + 0x1D33, + 0x1D34, + 0x1D35, + 0x1D36, + 0x1D37, + 0x1D38, + 0x1D39, + 0x1D3A, + 0x1D3B, + 0x1D3C, + 0x1D3D, + 0x1D3E, + 0x1D3F, + 0x1D40, + 0x1D41, + 0x1D42, + 0x1D43, + 0x1D44, + 0x1D45, + 0x1D46, + 0x1D47, + 0x1D48, + 0x1D49, + 0x1D4A, + 0x1D4B, + 0x1D4C, + 0x1D4D, + 0x1D4E, + 0x1D4F, + 0x1D50, + 0x1D51, + 0x1D52, + 0x1D53, + 0x1D54, + 0x1D55, + 0x1D56, + 0x1D57, + 0x1D58, + 0x1D59, + 0x1D5A, + 0x1D5B, + 0x1D5C, + 0x1D5D, + 0x1D5E, + 0x1D5F, + 0x1D60, + 0x1D61, + 0x1D62, + 0x1D63, + 0x1D64, + 0x1D65, + 0x1D66, + 0x1D67, + 0x1D68, + 0x1D69, + 0x1D6A, + 0x1D6B, + 0x1D78, + 0x1D79, + 0x1D9B, + 0x1D9C, + 0x1D9D, + 0x1D9E, + 0x1D9F, + 0x1DA0, + 0x1DA1, + 0x1DA2, + 0x1DA3, + 0x1DA4, + 0x1DA5, + 0x1DA6, + 0x1DA7, + 0x1DA8, + 0x1DA9, + 0x1DAA, + 0x1DAB, + 0x1DAC, + 0x1DAD, + 0x1DAE, + 0x1DAF, + 0x1DB0, + 0x1DB1, + 0x1DB2, + 0x1DB3, + 0x1DB4, + 0x1DB5, + 0x1DB6, + 0x1DB7, + 0x1DB8, + 0x1DB9, + 0x1DBA, + 0x1DBB, + 0x1DBC, + 0x1DBD, + 0x1DBE, + 0x1DBF, + 0x1DC0, + 0x1E00, + 0x1E01, + 0x1E02, + 0x1E03, + 0x1E04, + 0x1E05, + 0x1E06, + 0x1E07, + 0x1E08, + 0x1E09, + 0x1E0A, + 0x1E0B, + 0x1E0C, + 0x1E0D, + 0x1E0E, + 0x1E0F, + 0x1E10, + 0x1E11, + 0x1E12, + 0x1E13, + 0x1E14, + 0x1E15, + 0x1E16, + 0x1E17, + 0x1E18, + 0x1E19, + 0x1E1A, + 0x1E1B, + 0x1E1C, + 0x1E1D, + 0x1E1E, + 0x1E1F, + 0x1E20, + 0x1E21, + 0x1E22, + 0x1E23, + 0x1E24, + 0x1E25, + 0x1E26, + 0x1E27, + 0x1E28, + 0x1E29, + 0x1E2A, + 0x1E2B, + 0x1E2C, + 0x1E2D, + 0x1E2E, + 0x1E2F, + 0x1E30, + 0x1E31, + 0x1E32, + 0x1E33, + 0x1E34, + 0x1E35, + 0x1E36, + 0x1E37, + 0x1E38, + 0x1E39, + 0x1E3A, + 0x1E3B, + 0x1E3C, + 0x1E3D, + 0x1E3E, + 0x1E3F, + 0x1E40, + 0x1E41, + 0x1E42, + 0x1E43, + 0x1E44, + 0x1E45, + 0x1E46, + 0x1E47, + 0x1E48, + 0x1E49, + 0x1E4A, + 0x1E4B, + 0x1E4C, + 0x1E4D, + 0x1E4E, + 0x1E4F, + 0x1E50, + 0x1E51, + 0x1E52, + 0x1E53, + 0x1E54, + 0x1E55, + 0x1E56, + 0x1E57, + 0x1E58, + 0x1E59, + 0x1E5A, + 0x1E5B, + 0x1E5C, + 0x1E5D, + 0x1E5E, + 0x1E5F, + 0x1E60, + 0x1E61, + 0x1E62, + 0x1E63, + 0x1E64, + 0x1E65, + 0x1E66, + 0x1E67, + 0x1E68, + 0x1E69, + 0x1E6A, + 0x1E6B, + 0x1E6C, + 0x1E6D, + 0x1E6E, + 0x1E6F, + 0x1E70, + 0x1E71, + 0x1E72, + 0x1E73, + 0x1E74, + 0x1E75, + 0x1E76, + 0x1E77, + 0x1E78, + 0x1E79, + 0x1E7A, + 0x1E7B, + 0x1E7C, + 0x1E7D, + 0x1E7E, + 0x1E7F, + 0x1E80, + 0x1E81, + 0x1E82, + 0x1E83, + 0x1E84, + 0x1E85, + 0x1E86, + 0x1E87, + 0x1E88, + 0x1E89, + 0x1E8A, + 0x1E8B, + 0x1E8C, + 0x1E8D, + 0x1E8E, + 0x1E8F, + 0x1E90, + 0x1E91, + 0x1E92, + 0x1E93, + 0x1E94, + 0x1E95, + 0x1E9A, + 0x1E9B, + 0x1E9C, + 0x1E9E, + 0x1E9F, + 0x1EA0, + 0x1EA1, + 0x1EA2, + 0x1EA3, + 0x1EA4, + 0x1EA5, + 0x1EA6, + 0x1EA7, + 0x1EA8, + 0x1EA9, + 0x1EAA, + 0x1EAB, + 0x1EAC, + 0x1EAD, + 0x1EAE, + 0x1EAF, + 0x1EB0, + 0x1EB1, + 0x1EB2, + 0x1EB3, + 0x1EB4, + 0x1EB5, + 0x1EB6, + 0x1EB7, + 0x1EB8, + 0x1EB9, + 0x1EBA, + 0x1EBB, + 0x1EBC, + 0x1EBD, + 0x1EBE, + 0x1EBF, + 0x1EC0, + 0x1EC1, + 0x1EC2, + 0x1EC3, + 0x1EC4, + 0x1EC5, + 0x1EC6, + 0x1EC7, + 0x1EC8, + 0x1EC9, + 0x1ECA, + 0x1ECB, + 0x1ECC, + 0x1ECD, + 0x1ECE, + 0x1ECF, + 0x1ED0, + 0x1ED1, + 0x1ED2, + 0x1ED3, + 0x1ED4, + 0x1ED5, + 0x1ED6, + 0x1ED7, + 0x1ED8, + 0x1ED9, + 0x1EDA, + 0x1EDB, + 0x1EDC, + 0x1EDD, + 0x1EDE, + 0x1EDF, + 0x1EE0, + 0x1EE1, + 0x1EE2, + 0x1EE3, + 0x1EE4, + 0x1EE5, + 0x1EE6, + 0x1EE7, + 0x1EE8, + 0x1EE9, + 0x1EEA, + 0x1EEB, + 0x1EEC, + 0x1EED, + 0x1EEE, + 0x1EEF, + 0x1EF0, + 0x1EF1, + 0x1EF2, + 0x1EF3, + 0x1EF4, + 0x1EF5, + 0x1EF6, + 0x1EF7, + 0x1EF8, + 0x1EF9, + 0x1EFA, + 0x1EFB, + 0x1EFC, + 0x1EFD, + 0x1EFE, + 0x1EFF, + 0x1F08, + 0x1F09, + 0x1F0A, + 0x1F0B, + 0x1F0C, + 0x1F0D, + 0x1F0E, + 0x1F0F, + 0x1F10, + 0x1F16, + 0x1F18, + 0x1F19, + 0x1F1A, + 0x1F1B, + 0x1F1C, + 0x1F1D, + 0x1F1E, + 0x1F20, + 0x1F28, + 0x1F29, + 0x1F2A, + 0x1F2B, + 0x1F2C, + 0x1F2D, + 0x1F2E, + 0x1F2F, + 0x1F30, + 0x1F38, + 0x1F39, + 0x1F3A, + 0x1F3B, + 0x1F3C, + 0x1F3D, + 0x1F3E, + 0x1F3F, + 0x1F40, + 0x1F46, + 0x1F48, + 0x1F49, + 0x1F4A, + 0x1F4B, + 0x1F4C, + 0x1F4D, + 0x1F4E, + 0x1F50, + 0x1F58, + 0x1F59, + 0x1F5A, + 0x1F5B, + 0x1F5C, + 0x1F5D, + 0x1F5E, + 0x1F5F, + 0x1F60, + 0x1F68, + 0x1F69, + 0x1F6A, + 0x1F6B, + 0x1F6C, + 0x1F6D, + 0x1F6E, + 0x1F6F, + 0x1F70, + 0x1F71, + 0x1F72, + 0x1F73, + 0x1F74, + 0x1F75, + 0x1F76, + 0x1F77, + 0x1F78, + 0x1F79, + 0x1F7A, + 0x1F7B, + 0x1F7C, + 0x1F7D, + 0x1F7E, + 0x1F80, + 0x1F81, + 0x1F82, + 0x1F83, + 0x1F84, + 0x1F85, + 0x1F86, + 0x1F87, + 0x1F88, + 0x1F89, + 0x1F8A, + 0x1F8B, + 0x1F8C, + 0x1F8D, + 0x1F8E, + 0x1F8F, + 0x1F90, + 0x1F91, + 0x1F92, + 0x1F93, + 0x1F94, + 0x1F95, + 0x1F96, + 0x1F97, + 0x1F98, + 0x1F99, + 0x1F9A, + 0x1F9B, + 0x1F9C, + 0x1F9D, + 0x1F9E, + 0x1F9F, + 0x1FA0, + 0x1FA1, + 0x1FA2, + 0x1FA3, + 0x1FA4, + 0x1FA5, + 0x1FA6, + 0x1FA7, + 0x1FA8, + 0x1FA9, + 0x1FAA, + 0x1FAB, + 0x1FAC, + 0x1FAD, + 0x1FAE, + 0x1FAF, + 0x1FB0, + 0x1FB2, + 0x1FB3, + 0x1FB4, + 0x1FB5, + 0x1FB6, + 0x1FB7, + 0x1FB8, + 0x1FB9, + 0x1FBA, + 0x1FBB, + 0x1FBC, + 0x1FBD, + 0x1FBE, + 0x1FBF, + 0x1FC0, + 0x1FC1, + 0x1FC2, + 0x1FC3, + 0x1FC4, + 0x1FC5, + 0x1FC6, + 0x1FC7, + 0x1FC8, + 0x1FC9, + 0x1FCA, + 0x1FCB, + 0x1FCC, + 0x1FCD, + 0x1FCE, + 0x1FCF, + 0x1FD0, + 0x1FD3, + 0x1FD4, + 0x1FD6, + 0x1FD8, + 0x1FD9, + 0x1FDA, + 0x1FDB, + 0x1FDC, + 0x1FDD, + 0x1FDE, + 0x1FDF, + 0x1FE0, + 0x1FE3, + 0x1FE4, + 0x1FE8, + 0x1FE9, + 0x1FEA, + 0x1FEB, + 0x1FEC, + 0x1FED, + 0x1FEE, + 0x1FEF, + 0x1FF0, + 0x1FF2, + 0x1FF3, + 0x1FF4, + 0x1FF5, + 0x1FF6, + 0x1FF7, + 0x1FF8, + 0x1FF9, + 0x1FFA, + 0x1FFB, + 0x1FFC, + 0x1FFD, + 0x1FFE, + 0x1FFF, + 0x2000, + 0x200B, + 0x200C, + 0x200E, + 0x2010, + 0x2011, + 0x2012, + 0x2017, + 0x2018, + 0x2024, + 0x2027, + 0x2028, + 0x202F, + 0x2030, + 0x2033, + 0x2034, + 0x2035, + 0x2036, + 0x2037, + 0x2038, + 0x203C, + 0x203D, + 0x203E, + 0x203F, + 0x2047, + 0x2048, + 0x2049, + 0x204A, + 0x2057, + 0x2058, + 0x205F, + 0x2060, + 0x2065, + 0x206A, + 0x2070, + 0x2071, + 0x2072, + 0x2074, + 0x2075, + 0x2076, + 0x2077, + 0x2078, + 0x2079, + 0x207A, + 0x207B, + 0x207C, + 0x207D, + 0x207E, + 0x207F, + 0x2080, + 0x2081, + 0x2082, + 0x2083, + 0x2084, + 0x2085, + 0x2086, + 0x2087, + 0x2088, + 0x2089, + 0x208A, + 0x208B, + 0x208C, + 0x208D, + 0x208E, + 0x208F, + 0x2090, + 0x2091, + 0x2092, + 0x2093, + 0x2094, + 0x2095, + 0x2096, + 0x2097, + 0x2098, + 0x2099, + 0x209A, + 0x209B, + 0x209C, + 0x209D, + 0x209E, + 0x209F, + 0x20A0, + 0x20A8, + 0x20A9, + 0x20C5, + 0x20D0, + 0x20F1, + 0x2100, + 0x2101, + 0x2102, + 0x2103, + 0x2104, + 0x2105, + 0x2106, + 0x2107, + 0x2108, + 0x2109, + 0x210A, + 0x210B, + 0x210F, + 0x2110, + 0x2112, + 0x2114, + 0x2115, + 0x2116, + 0x2117, + 0x2119, + 0x211A, + 0x211B, + 0x211E, + 0x2120, + 0x2121, + 0x2122, + 0x2123, + 0x2124, + 0x2125, + 0x2126, + 0x2127, + 0x2128, + 0x2129, + 0x212A, + 0x212B, + 0x212C, + 0x212D, + 0x212E, + 0x212F, + 0x2131, + 0x2132, + 0x2133, + 0x2134, + 0x2135, + 0x2136, + 0x2137, + 0x2138, + 0x2139, + 0x213A, + 0x213B, + 0x213C, + 0x213D, + 0x213F, + 0x2140, + 0x2141, + 0x2145, + 0x2147, + 0x2148, + 0x2149, + 0x214A, + 0x2150, + 0x2151, + 0x2152, + 0x2153, + 0x2154, + 0x2155, + 0x2156, + 0x2157, + 0x2158, + 0x2159, + 0x215A, + 0x215B, + 0x215C, + 0x215D, + 0x215E, + 0x215F, + 0x2160, + 0x2161, + 0x2162, + 0x2163, + 0x2164, + 0x2165, + 0x2166, + 0x2167, + 0x2168, + 0x2169, + 0x216A, + 0x216B, + 0x216C, + 0x216D, + 0x216E, + 0x216F, + 0x2170, + 0x2171, + 0x2172, + 0x2173, + 0x2174, + 0x2175, + 0x2176, + 0x2177, + 0x2178, + 0x2179, + 0x217A, + 0x217B, + 0x217C, + 0x217D, + 0x217E, + 0x217F, + 0x2180, + 0x2183, + 0x2184, + 0x2189, + 0x218A, + 0x218C, + 0x2190, + 0x222C, + 0x222D, + 0x222E, + 0x222F, + 0x2230, + 0x2231, + 0x2329, + 0x232A, + 0x232B, + 0x242A, + 0x2440, + 0x244B, + 0x2460, + 0x2461, + 0x2462, + 0x2463, + 0x2464, + 0x2465, + 0x2466, + 0x2467, + 0x2468, + 0x2469, + 0x246A, + 0x246B, + 0x246C, + 0x246D, + 0x246E, + 0x246F, + 0x2470, + 0x2471, + 0x2472, + 0x2473, + 0x2474, + 0x2475, + 0x2476, + 0x2477, + 0x2478, + 0x2479, + 0x247A, + 0x247B, + 0x247C, + 0x247D, + 0x247E, + 0x247F, + 0x2480, + 0x2481, + 0x2482, + 0x2483, + 0x2484, + 0x2485, + 0x2486, + 0x2487, + 0x2488, + 0x249C, + 0x249D, + 0x249E, + 0x249F, + 0x24A0, + 0x24A1, + 0x24A2, + 0x24A3, + 0x24A4, + 0x24A5, + 0x24A6, + 0x24A7, + 0x24A8, + 0x24A9, + 0x24AA, + 0x24AB, + 0x24AC, + 0x24AD, + 0x24AE, + 0x24AF, + 0x24B0, + 0x24B1, + 0x24B2, + 0x24B3, + 0x24B4, + 0x24B5, + 0x24B6, + 0x24B7, + 0x24B8, + 0x24B9, + 0x24BA, + 0x24BB, + 0x24BC, + 0x24BD, + 0x24BE, + 0x24BF, + 0x24C0, + 0x24C1, + 0x24C2, + 0x24C3, + 0x24C4, + 0x24C5, + 0x24C6, + 0x24C7, + 0x24C8, + 0x24C9, + 0x24CA, + 0x24CB, + 0x24CC, + 0x24CD, + 0x24CE, + 0x24CF, + 0x24D0, + 0x24D1, + 0x24D2, + 0x24D3, + 0x24D4, + 0x24D5, + 0x24D6, + 0x24D7, + 0x24D8, + 0x24D9, + 0x24DA, + 0x24DB, + 0x24DC, + 0x24DD, + 0x24DE, + 0x24DF, + 0x24E0, + 0x24E1, + 0x24E2, + 0x24E3, + 0x24E4, + 0x24E5, + 0x24E6, + 0x24E7, + 0x24E8, + 0x24E9, + 0x24EA, + 0x24EB, + 0x2A0C, + 0x2A0D, + 0x2A74, + 0x2A75, + 0x2A76, + 0x2A77, + 0x2ADC, + 0x2ADD, + 0x2B74, + 0x2B76, + 0x2C00, + 0x2C01, + 0x2C02, + 0x2C03, + 0x2C04, + 0x2C05, + 0x2C06, + 0x2C07, + 0x2C08, + 0x2C09, + 0x2C0A, + 0x2C0B, + 0x2C0C, + 0x2C0D, + 0x2C0E, + 0x2C0F, + 0x2C10, + 0x2C11, + 0x2C12, + 0x2C13, + 0x2C14, + 0x2C15, + 0x2C16, + 0x2C17, + 0x2C18, + 0x2C19, + 0x2C1A, + 0x2C1B, + 0x2C1C, + 0x2C1D, + 0x2C1E, + 0x2C1F, + 0x2C20, + 0x2C21, + 0x2C22, + 0x2C23, + 0x2C24, + 0x2C25, + 0x2C26, + 0x2C27, + 0x2C28, + 0x2C29, + 0x2C2A, + 0x2C2B, + 0x2C2C, + 0x2C2D, + 0x2C2E, + 0x2C2F, + 0x2C30, + 0x2C60, + 0x2C61, + 0x2C62, + 0x2C63, + 0x2C64, + 0x2C65, + 0x2C67, + 0x2C68, + 0x2C69, + 0x2C6A, + 0x2C6B, + 0x2C6C, + 0x2C6D, + 0x2C6E, + 0x2C6F, + 0x2C70, + 0x2C71, + 0x2C72, + 0x2C73, + 0x2C75, + 0x2C76, + 0x2C7C, + 0x2C7D, + 0x2C7E, + 0x2C7F, + 0x2C80, + 0x2C81, + 0x2C82, + 0x2C83, + 0x2C84, + 0x2C85, + 0x2C86, + 0x2C87, + 0x2C88, + 0x2C89, + 0x2C8A, + 0x2C8B, + 0x2C8C, + 0x2C8D, + 0x2C8E, + 0x2C8F, + 0x2C90, + 0x2C91, + 0x2C92, + 0x2C93, + 0x2C94, + 0x2C95, + 0x2C96, + 0x2C97, + 0x2C98, + 0x2C99, + 0x2C9A, + 0x2C9B, + 0x2C9C, + 0x2C9D, + 0x2C9E, + 0x2C9F, + 0x2CA0, + 0x2CA1, + 0x2CA2, + 0x2CA3, + 0x2CA4, + 0x2CA5, + 0x2CA6, + 0x2CA7, + 0x2CA8, + 0x2CA9, + 0x2CAA, + 0x2CAB, + 0x2CAC, + 0x2CAD, + 0x2CAE, + 0x2CAF, + 0x2CB0, + 0x2CB1, + 0x2CB2, + 0x2CB3, + 0x2CB4, + 0x2CB5, + 0x2CB6, + 0x2CB7, + 0x2CB8, + 0x2CB9, + 0x2CBA, + 0x2CBB, + 0x2CBC, + 0x2CBD, + 0x2CBE, + 0x2CBF, + 0x2CC0, + 0x2CC1, + 0x2CC2, + 0x2CC3, + 0x2CC4, + 0x2CC5, + 0x2CC6, + 0x2CC7, + 0x2CC8, + 0x2CC9, + 0x2CCA, + 0x2CCB, + 0x2CCC, + 0x2CCD, + 0x2CCE, + 0x2CCF, + 0x2CD0, + 0x2CD1, + 0x2CD2, + 0x2CD3, + 0x2CD4, + 0x2CD5, + 0x2CD6, + 0x2CD7, + 0x2CD8, + 0x2CD9, + 0x2CDA, + 0x2CDB, + 0x2CDC, + 0x2CDD, + 0x2CDE, + 0x2CDF, + 0x2CE0, + 0x2CE1, + 0x2CE2, + 0x2CE3, + 0x2CEB, + 0x2CEC, + 0x2CED, + 0x2CEE, + 0x2CF2, + 0x2CF3, + 0x2CF4, + 0x2CF9, + 0x2D26, + 0x2D27, + 0x2D28, + 0x2D2D, + 0x2D2E, + 0x2D30, + 0x2D68, + 0x2D6F, + 0x2D70, + 0x2D71, + 0x2D7F, + 0x2D97, + 0x2DA0, + 0x2DA7, + 0x2DA8, + 0x2DAF, + 0x2DB0, + 0x2DB7, + 0x2DB8, + 0x2DBF, + 0x2DC0, + 0x2DC7, + 0x2DC8, + 0x2DCF, + 0x2DD0, + 0x2DD7, + 0x2DD8, + 0x2DDF, + 0x2DE0, + 0x2E5E, + 0x2E60, + 0x2E64, + 0x2E80, + 0x2E9A, + 0x2E9B, + 0x2E9F, + 0x2EA0, + 0x2EF3, + 0x2EF4, + 0x2F00, + 0x2F01, + 0x2F02, + 0x2F03, + 0x2F04, + 0x2F05, + 0x2F06, + 0x2F07, + 0x2F08, + 0x2F09, + 0x2F0A, + 0x2F0B, + 0x2F0C, + 0x2F0D, + 0x2F0E, + 0x2F0F, + 0x2F10, + 0x2F11, + 0x2F12, + 0x2F13, + 0x2F14, + 0x2F15, + 0x2F16, + 0x2F17, + 0x2F18, + 0x2F19, + 0x2F1A, + 0x2F1B, + 0x2F1C, + 0x2F1D, + 0x2F1E, + 0x2F1F, + 0x2F20, + 0x2F21, + 0x2F22, + 0x2F23, + 0x2F24, + 0x2F25, + 0x2F26, + 0x2F27, + 0x2F28, + 0x2F29, + 0x2F2A, + 0x2F2B, + 0x2F2C, + 0x2F2D, + 0x2F2E, + 0x2F2F, + 0x2F30, + 0x2F31, + 0x2F32, + 0x2F33, + 0x2F34, + 0x2F35, + 0x2F36, + 0x2F37, + 0x2F38, + 0x2F39, + 0x2F3A, + 0x2F3B, + 0x2F3C, + 0x2F3D, + 0x2F3E, + 0x2F3F, + 0x2F40, + 0x2F41, + 0x2F42, + 0x2F43, + 0x2F44, + 0x2F45, + 0x2F46, + 0x2F47, + 0x2F48, + 0x2F49, + 0x2F4A, + 0x2F4B, + 0x2F4C, + 0x2F4D, + 0x2F4E, + 0x2F4F, + 0x2F50, + 0x2F51, + 0x2F52, + 0x2F53, + 0x2F54, + 0x2F55, + 0x2F56, + 0x2F57, + 0x2F58, + 0x2F59, + 0x2F5A, + 0x2F5B, + 0x2F5C, + 0x2F5D, + 0x2F5E, + 0x2F5F, + 0x2F60, + 0x2F61, + 0x2F62, + 0x2F63, + 0x2F64, + 0x2F65, + 0x2F66, + 0x2F67, + 0x2F68, + 0x2F69, + 0x2F6A, + 0x2F6B, + 0x2F6C, + 0x2F6D, + 0x2F6E, + 0x2F6F, + 0x2F70, + 0x2F71, + 0x2F72, + 0x2F73, + 0x2F74, + 0x2F75, + 0x2F76, + 0x2F77, + 0x2F78, + 0x2F79, + 0x2F7A, + 0x2F7B, + 0x2F7C, + 0x2F7D, + 0x2F7E, + 0x2F7F, + 0x2F80, + 0x2F81, + 0x2F82, + 0x2F83, + 0x2F84, + 0x2F85, + 0x2F86, + 0x2F87, + 0x2F88, + 0x2F89, + 0x2F8A, + 0x2F8B, + 0x2F8C, + 0x2F8D, + 0x2F8E, + 0x2F8F, + 0x2F90, + 0x2F91, + 0x2F92, + 0x2F93, + 0x2F94, + 0x2F95, + 0x2F96, + 0x2F97, + 0x2F98, + 0x2F99, + 0x2F9A, + 0x2F9B, + 0x2F9C, + 0x2F9D, + 0x2F9E, + 0x2F9F, + 0x2FA0, + 0x2FA1, + 0x2FA2, + 0x2FA3, + 0x2FA4, + 0x2FA5, + 0x2FA6, + 0x2FA7, + 0x2FA8, + 0x2FA9, + 0x2FAA, + 0x2FAB, + 0x2FAC, + 0x2FAD, + 0x2FAE, + 0x2FAF, + 0x2FB0, + 0x2FB1, + 0x2FB2, + 0x2FB3, + 0x2FB4, + 0x2FB5, + 0x2FB6, + 0x2FB7, + 0x2FB8, + 0x2FB9, + 0x2FBA, + 0x2FBB, + 0x2FBC, + 0x2FBD, + 0x2FBE, + 0x2FBF, + 0x2FC0, + 0x2FC1, + 0x2FC2, + 0x2FC3, + 0x2FC4, + 0x2FC5, + 0x2FC6, + 0x2FC7, + 0x2FC8, + 0x2FC9, + 0x2FCA, + 0x2FCB, + 0x2FCC, + 0x2FCD, + 0x2FCE, + 0x2FCF, + 0x2FD0, + 0x2FD1, + 0x2FD2, + 0x2FD3, + 0x2FD4, + 0x2FD5, + 0x2FD6, + 0x3000, + 0x3001, + 0x3002, + 0x3003, + 0x3036, + 0x3037, + 0x3038, + 0x3039, + 0x303A, + 0x303B, + 0x3040, + 0x3041, + 0x3097, + 0x3099, + 0x309B, + 0x309C, + 0x309D, + 0x309F, + 0x30A0, + 0x30FF, + 0x3100, + 0x3105, + 0x3130, + 0x3131, + 0x3132, + 0x3133, + 0x3134, + 0x3135, + 0x3136, + 0x3137, + 0x3138, + 0x3139, + 0x313A, + 0x313B, + 0x313C, + 0x313D, + 0x313E, + 0x313F, + 0x3140, + 0x3141, + 0x3142, + 0x3143, + 0x3144, + 0x3145, + 0x3146, + 0x3147, + 0x3148, + 0x3149, + 0x314A, + 0x314B, + 0x314C, + 0x314D, + 0x314E, + 0x314F, + 0x3150, + 0x3151, + 0x3152, + 0x3153, + 0x3154, + 0x3155, + 0x3156, + 0x3157, + 0x3158, + 0x3159, + 0x315A, + 0x315B, + 0x315C, + 0x315D, + 0x315E, + 0x315F, + 0x3160, + 0x3161, + 0x3162, + 0x3163, + 0x3164, + 0x3165, + 0x3166, + 0x3167, + 0x3168, + 0x3169, + 0x316A, + 0x316B, + 0x316C, + 0x316D, + 0x316E, + 0x316F, + 0x3170, + 0x3171, + 0x3172, + 0x3173, + 0x3174, + 0x3175, + 0x3176, + 0x3177, + 0x3178, + 0x3179, + 0x317A, + 0x317B, + 0x317C, + 0x317D, + 0x317E, + 0x317F, + 0x3180, + 0x3181, + 0x3182, + 0x3183, + 0x3184, + 0x3185, + 0x3186, + 0x3187, + 0x3188, + 0x3189, + 0x318A, + 0x318B, + 0x318C, + 0x318D, + 0x318E, + 0x318F, + 0x3190, + 0x3192, + 0x3193, + 0x3194, + 0x3195, + 0x3196, + 0x3197, + 0x3198, + 0x3199, + 0x319A, + 0x319B, + 0x319C, + 0x319D, + 0x319E, + 0x319F, + 0x31A0, + 0x31E6, + 0x31F0, + 0x3200, + 0x3201, + 0x3202, + 0x3203, + 0x3204, + 0x3205, + 0x3206, + 0x3207, + 0x3208, + 0x3209, + 0x320A, + 0x320B, + 0x320C, + 0x320D, + 0x320E, + 0x320F, + 0x3210, + 0x3211, + 0x3212, + 0x3213, + 0x3214, + 0x3215, + 0x3216, + 0x3217, + 0x3218, + 0x3219, + 0x321A, + 0x321B, + 0x321C, + 0x321D, + 0x321E, + 0x321F, + 0x3220, + 0x3221, + 0x3222, + 0x3223, + 0x3224, + 0x3225, + 0x3226, + 0x3227, + 0x3228, + 0x3229, + 0x322A, + 0x322B, + 0x322C, + 0x322D, + 0x322E, + 0x322F, + 0x3230, + 0x3231, + 0x3232, + 0x3233, + 0x3234, + 0x3235, + 0x3236, + 0x3237, + 0x3238, + 0x3239, + 0x323A, + 0x323B, + 0x323C, + 0x323D, + 0x323E, + 0x323F, + 0x3240, + 0x3241, + 0x3242, + 0x3243, + 0x3244, + 0x3245, + 0x3246, + 0x3247, + 0x3248, + 0x3250, + 0x3251, + 0x3252, + 0x3253, + 0x3254, + 0x3255, + 0x3256, + 0x3257, + 0x3258, + 0x3259, + 0x325A, + 0x325B, + 0x325C, + 0x325D, + 0x325E, + 0x325F, + 0x3260, + 0x3261, + 0x3262, + 0x3263, + 0x3264, + 0x3265, + 0x3266, + 0x3267, + 0x3268, + 0x3269, + 0x326A, + 0x326B, + 0x326C, + 0x326D, + 0x326E, + 0x326F, + 0x3270, + 0x3271, + 0x3272, + 0x3273, + 0x3274, + 0x3275, + 0x3276, + 0x3277, + 0x3278, + 0x3279, + 0x327A, + 0x327B, + 0x327C, + 0x327D, + 0x327E, + 0x327F, + 0x3280, + 0x3281, + 0x3282, + 0x3283, + 0x3284, + 0x3285, + 0x3286, + 0x3287, + 0x3288, + 0x3289, + 0x328A, + 0x328B, + 0x328C, + 0x328D, + 0x328E, + 0x328F, + 0x3290, + 0x3291, + 0x3292, + 0x3293, + 0x3294, + 0x3295, + 0x3296, + 0x3297, + 0x3298, + 0x3299, + 0x329A, + 0x329B, + 0x329C, + 0x329D, + 0x329E, + 0x329F, + 0x32A0, + 0x32A1, + 0x32A2, + 0x32A3, + 0x32A4, + 0x32A5, + 0x32A6, + 0x32A7, + 0x32A8, + 0x32A9, + 0x32AA, + 0x32AB, + 0x32AC, + 0x32AD, + 0x32AE, + 0x32AF, + 0x32B0, + 0x32B1, + 0x32B2, + 0x32B3, + 0x32B4, + 0x32B5, + 0x32B6, + 0x32B7, + 0x32B8, + 0x32B9, + 0x32BA, + 0x32BB, + 0x32BC, + 0x32BD, + 0x32BE, + 0x32BF, + 0x32C0, + 0x32C1, + 0x32C2, + 0x32C3, + 0x32C4, + 0x32C5, + 0x32C6, + 0x32C7, + 0x32C8, + 0x32C9, + 0x32CA, + 0x32CB, + 0x32CC, + 0x32CD, + 0x32CE, + 0x32CF, + 0x32D0, + 0x32D1, + 0x32D2, + 0x32D3, + 0x32D4, + 0x32D5, + 0x32D6, + 0x32D7, + 0x32D8, + 0x32D9, + 0x32DA, + 0x32DB, + 0x32DC, + 0x32DD, + 0x32DE, + 0x32DF, + 0x32E0, + 0x32E1, + 0x32E2, + 0x32E3, + 0x32E4, + 0x32E5, + 0x32E6, + 0x32E7, + 0x32E8, + 0x32E9, + 0x32EA, + 0x32EB, + 0x32EC, + 0x32ED, + 0x32EE, + 0x32EF, + 0x32F0, + 0x32F1, + 0x32F2, + 0x32F3, + 0x32F4, + 0x32F5, + 0x32F6, + 0x32F7, + 0x32F8, + 0x32F9, + 0x32FA, + 0x32FB, + 0x32FC, + 0x32FD, + 0x32FE, + 0x32FF, + 0x3300, + 0x3301, + 0x3302, + 0x3303, + 0x3304, + 0x3305, + 0x3306, + 0x3307, + 0x3308, + 0x3309, + 0x330A, + 0x330B, + 0x330C, + 0x330D, + 0x330E, + 0x330F, + 0x3310, + 0x3311, + 0x3312, + 0x3313, + 0x3314, + 0x3315, + 0x3316, + 0x3317, + 0x3318, + 0x3319, + 0x331A, + 0x331B, + 0x331C, + 0x331D, + 0x331E, + 0x331F, + 0x3320, + 0x3321, + 0x3322, + 0x3323, + 0x3324, + 0x3325, + 0x3326, + 0x3327, + 0x3328, + 0x3329, + 0x332A, + 0x332B, + 0x332C, + 0x332D, + 0x332E, + 0x332F, + 0x3330, + 0x3331, + 0x3332, + 0x3333, + 0x3334, + 0x3335, + 0x3336, + 0x3337, + 0x3338, + 0x3339, + 0x333A, + 0x333B, + 0x333C, + 0x333D, + 0x333E, + 0x333F, + 0x3340, + 0x3341, + 0x3342, + 0x3343, + 0x3344, + 0x3345, + 0x3346, + 0x3347, + 0x3348, + 0x3349, + 0x334A, + 0x334B, + 0x334C, + 0x334D, + 0x334E, + 0x334F, + 0x3350, + 0x3351, + 0x3352, + 0x3353, + 0x3354, + 0x3355, + 0x3356, + 0x3357, + 0x3358, + 0x3359, + 0x335A, + 0x335B, + 0x335C, + 0x335D, + 0x335E, + 0x335F, + 0x3360, + 0x3361, + 0x3362, + 0x3363, + 0x3364, + 0x3365, + 0x3366, + 0x3367, + 0x3368, + 0x3369, + 0x336A, + 0x336B, + 0x336C, + 0x336D, + 0x336E, + 0x336F, + 0x3370, + 0x3371, + 0x3372, + 0x3373, + 0x3374, + 0x3375, + 0x3376, + 0x3377, + 0x3378, + 0x3379, + 0x337A, + 0x337B, + 0x337C, + 0x337D, + 0x337E, + 0x337F, + 0x3380, + 0x3381, + 0x3382, + 0x3383, + 0x3384, + 0x3385, + 0x3386, + 0x3387, + 0x3388, + 0x3389, + 0x338A, + 0x338B, + 0x338C, + 0x338D, + 0x338E, + 0x338F, + 0x3390, + 0x3391, + 0x3392, + 0x3393, + 0x3394, + 0x3395, + 0x3396, + 0x3397, + 0x3398, + 0x3399, + 0x339A, + 0x339B, + 0x339C, + 0x339D, + 0x339E, + 0x339F, + 0x33A0, + 0x33A1, + 0x33A2, + 0x33A3, + 0x33A4, + 0x33A5, + 0x33A6, + 0x33A7, + 0x33A8, + 0x33A9, + 0x33AA, + 0x33AB, + 0x33AC, + 0x33AD, + 0x33AE, + 0x33AF, + 0x33B0, + 0x33B1, + 0x33B2, + 0x33B3, + 0x33B4, + 0x33B5, + 0x33B6, + 0x33B7, + 0x33B8, + 0x33B9, + 0x33BA, + 0x33BB, + 0x33BC, + 0x33BD, + 0x33BE, + 0x33BF, + 0x33C0, + 0x33C1, + 0x33C2, + 0x33C3, + 0x33C4, + 0x33C5, + 0x33C6, + 0x33C7, + 0x33C8, + 0x33C9, + 0x33CA, + 0x33CB, + 0x33CC, + 0x33CD, + 0x33CE, + 0x33CF, + 0x33D0, + 0x33D1, + 0x33D2, + 0x33D3, + 0x33D4, + 0x33D5, + 0x33D6, + 0x33D7, + 0x33D8, + 0x33D9, + 0x33DA, + 0x33DB, + 0x33DC, + 0x33DD, + 0x33DE, + 0x33DF, + 0x33E0, + 0x33E1, + 0x33E2, + 0x33E3, + 0x33E4, + 0x33E5, + 0x33E6, + 0x33E7, + 0x33E8, + 0x33E9, + 0x33EA, + 0x33EB, + 0x33EC, + 0x33ED, + 0x33EE, + 0x33EF, + 0x33F0, + 0x33F1, + 0x33F2, + 0x33F3, + 0x33F4, + 0x33F5, + 0x33F6, + 0x33F7, + 0x33F8, + 0x33F9, + 0x33FA, + 0x33FB, + 0x33FC, + 0x33FD, + 0x33FE, + 0x33FF, + 0x3400, + 0xA48D, + 0xA490, + 0xA4C7, + 0xA4D0, + 0xA62C, + 0xA640, + 0xA641, + 0xA642, + 0xA643, + 0xA644, + 0xA645, + 0xA646, + 0xA647, + 0xA648, + 0xA649, + 0xA64A, + 0xA64B, + 0xA64C, + 0xA64D, + 0xA64E, + 0xA64F, + 0xA650, + 0xA651, + 0xA652, + 0xA653, + 0xA654, + 0xA655, + 0xA656, + 0xA657, + 0xA658, + 0xA659, + 0xA65A, + 0xA65B, + 0xA65C, + 0xA65D, + 0xA65E, + 0xA65F, + 0xA660, + 0xA661, + 0xA662, + 0xA663, + 0xA664, + 0xA665, + 0xA666, + 0xA667, + 0xA668, + 0xA669, + 0xA66A, + 0xA66B, + 0xA66C, + 0xA66D, + 0xA680, + 0xA681, + 0xA682, + 0xA683, + 0xA684, + 0xA685, + 0xA686, + 0xA687, + 0xA688, + 0xA689, + 0xA68A, + 0xA68B, + 0xA68C, + 0xA68D, + 0xA68E, + 0xA68F, + 0xA690, + 0xA691, + 0xA692, + 0xA693, + 0xA694, + 0xA695, + 0xA696, + 0xA697, + 0xA698, + 0xA699, + 0xA69A, + 0xA69B, + 0xA69C, + 0xA69D, + 0xA69E, + 0xA6F8, + 0xA700, + 0xA722, + 0xA723, + 0xA724, + 0xA725, + 0xA726, + 0xA727, + 0xA728, + 0xA729, + 0xA72A, + 0xA72B, + 0xA72C, + 0xA72D, + 0xA72E, + 0xA72F, + 0xA732, + 0xA733, + 0xA734, + 0xA735, + 0xA736, + 0xA737, + 0xA738, + 0xA739, + 0xA73A, + 0xA73B, + 0xA73C, + 0xA73D, + 0xA73E, + 0xA73F, + 0xA740, + 0xA741, + 0xA742, + 0xA743, + 0xA744, + 0xA745, + 0xA746, + 0xA747, + 0xA748, + 0xA749, + 0xA74A, + 0xA74B, + 0xA74C, + 0xA74D, + 0xA74E, + 0xA74F, + 0xA750, + 0xA751, + 0xA752, + 0xA753, + 0xA754, + 0xA755, + 0xA756, + 0xA757, + 0xA758, + 0xA759, + 0xA75A, + 0xA75B, + 0xA75C, + 0xA75D, + 0xA75E, + 0xA75F, + 0xA760, + 0xA761, + 0xA762, + 0xA763, + 0xA764, + 0xA765, + 0xA766, + 0xA767, + 0xA768, + 0xA769, + 0xA76A, + 0xA76B, + 0xA76C, + 0xA76D, + 0xA76E, + 0xA76F, + 0xA770, + 0xA771, + 0xA779, + 0xA77A, + 0xA77B, + 0xA77C, + 0xA77D, + 0xA77E, + 0xA77F, + 0xA780, + 0xA781, + 0xA782, + 0xA783, + 0xA784, + 0xA785, + 0xA786, + 0xA787, + 0xA78B, + 0xA78C, + 0xA78D, + 0xA78E, + 0xA790, + 0xA791, + 0xA792, + 0xA793, + 0xA796, + 0xA797, + 0xA798, + 0xA799, + 0xA79A, + 0xA79B, + 0xA79C, + 0xA79D, + 0xA79E, + 0xA79F, + 0xA7A0, + 0xA7A1, + 0xA7A2, + 0xA7A3, + 0xA7A4, + 0xA7A5, + 0xA7A6, + 0xA7A7, + 0xA7A8, + 0xA7A9, + 0xA7AA, + 0xA7AB, + 0xA7AC, + 0xA7AD, + 0xA7AE, + 0xA7AF, + 0xA7B0, + 0xA7B1, + 0xA7B2, + 0xA7B3, + 0xA7B4, + 0xA7B5, + 0xA7B6, + 0xA7B7, + 0xA7B8, + 0xA7B9, + 0xA7BA, + 0xA7BB, + 0xA7BC, + 0xA7BD, + 0xA7BE, + 0xA7BF, + 0xA7C0, + 0xA7C1, + 0xA7C2, + 0xA7C3, + 0xA7C4, + 0xA7C5, + 0xA7C6, + 0xA7C7, + 0xA7C8, + 0xA7C9, + 0xA7CA, + 0xA7CB, + 0xA7CC, + 0xA7CD, + 0xA7CE, + 0xA7CF, + 0xA7D0, + 0xA7D1, + 0xA7D2, + 0xA7D3, + 0xA7D4, + 0xA7D5, + 0xA7D6, + 0xA7D7, + 0xA7D8, + 0xA7D9, + 0xA7DA, + 0xA7DB, + 0xA7DC, + 0xA7DD, + 0xA7DE, + 0xA7E2, + 0xA7E3, + 0xA7F1, + 0xA7F2, + 0xA7F3, + 0xA7F4, + 0xA7F5, + 0xA7F6, + 0xA7F8, + 0xA7F9, + 0xA7FA, + 0xA82D, + 0xA830, + 0xA83A, + 0xA840, + 0xA878, + 0xA880, + 0xA8C6, + 0xA8CE, + 0xA8DA, + 0xA8E0, + 0xA954, + 0xA95F, + 0xA97D, + 0xA980, + 0xA9CE, + 0xA9CF, + 0xA9DA, + 0xA9DE, + 0xA9FF, + 0xAA00, + 0xAA37, + 0xAA40, + 0xAA4E, + 0xAA50, + 0xAA5A, + 0xAA5C, + 0xAAC3, + 0xAADB, + 0xAAF7, + 0xAB01, + 0xAB07, + 0xAB09, + 0xAB0F, + 0xAB11, + 0xAB17, + 0xAB20, + 0xAB27, + 0xAB28, + 0xAB2F, + 0xAB30, + 0xAB5C, + 0xAB5D, + 0xAB5E, + 0xAB5F, + 0xAB60, + 0xAB69, + 0xAB6A, + 0xAB6C, + 0xAB6D, + 0xAB6E, + 0xAB70, + 0xAB71, + 0xAB72, + 0xAB73, + 0xAB74, + 0xAB75, + 0xAB76, + 0xAB77, + 0xAB78, + 0xAB79, + 0xAB7A, + 0xAB7B, + 0xAB7C, + 0xAB7D, + 0xAB7E, + 0xAB7F, + 0xAB80, + 0xAB81, + 0xAB82, + 0xAB83, + 0xAB84, + 0xAB85, + 0xAB86, + 0xAB87, + 0xAB88, + 0xAB89, + 0xAB8A, + 0xAB8B, + 0xAB8C, + 0xAB8D, + 0xAB8E, + 0xAB8F, + 0xAB90, + 0xAB91, + 0xAB92, + 0xAB93, + 0xAB94, + 0xAB95, + 0xAB96, + 0xAB97, + 0xAB98, + 0xAB99, + 0xAB9A, + 0xAB9B, + 0xAB9C, + 0xAB9D, + 0xAB9E, + 0xAB9F, + 0xABA0, + 0xABA1, + 0xABA2, + 0xABA3, + 0xABA4, + 0xABA5, + 0xABA6, + 0xABA7, + 0xABA8, + 0xABA9, + 0xABAA, + 0xABAB, + 0xABAC, + 0xABAD, + 0xABAE, + 0xABAF, + 0xABB0, + 0xABB1, + 0xABB2, + 0xABB3, + 0xABB4, + 0xABB5, + 0xABB6, + 0xABB7, + 0xABB8, + 0xABB9, + 0xABBA, + 0xABBB, + 0xABBC, + 0xABBD, + 0xABBE, + 0xABBF, + 0xABC0, + 0xABEE, + 0xABF0, + 0xABFA, + 0xAC00, + 0xD7A4, + 0xD7B0, + 0xD7C7, + 0xD7CB, + 0xD7FC, + 0xF900, + 0xF901, + 0xF902, + 0xF903, + 0xF904, + 0xF905, + 0xF906, + 0xF907, + 0xF909, + 0xF90A, + 0xF90B, + 0xF90C, + 0xF90D, + 0xF90E, + 0xF90F, + 0xF910, + 0xF911, + 0xF912, + 0xF913, + 0xF914, + 0xF915, + 0xF916, + 0xF917, + 0xF918, + 0xF919, + 0xF91A, + 0xF91B, + 0xF91C, + 0xF91D, + 0xF91E, + 0xF91F, + 0xF920, + 0xF921, + 0xF922, + 0xF923, + 0xF924, + 0xF925, + 0xF926, + 0xF927, + 0xF928, + 0xF929, + 0xF92A, + 0xF92B, + 0xF92C, + 0xF92D, + 0xF92E, + 0xF92F, + 0xF930, + 0xF931, + 0xF932, + 0xF933, + 0xF934, + 0xF935, + 0xF936, + 0xF937, + 0xF938, + 0xF939, + 0xF93A, + 0xF93B, + 0xF93C, + 0xF93D, + 0xF93E, + 0xF93F, + 0xF940, + 0xF941, + 0xF942, + 0xF943, + 0xF944, + 0xF945, + 0xF946, + 0xF947, + 0xF948, + 0xF949, + 0xF94A, + 0xF94B, + 0xF94C, + 0xF94D, + 0xF94E, + 0xF94F, + 0xF950, + 0xF951, + 0xF952, + 0xF953, + 0xF954, + 0xF955, + 0xF956, + 0xF957, + 0xF958, + 0xF959, + 0xF95A, + 0xF95B, + 0xF95C, + 0xF95D, + 0xF95E, + 0xF95F, + 0xF960, + 0xF961, + 0xF962, + 0xF963, + 0xF964, + 0xF965, + 0xF966, + 0xF967, + 0xF968, + 0xF969, + 0xF96A, + 0xF96B, + 0xF96C, + 0xF96D, + 0xF96E, + 0xF96F, + 0xF970, + 0xF971, + 0xF972, + 0xF973, + 0xF974, + 0xF975, + 0xF976, + 0xF977, + 0xF978, + 0xF979, + 0xF97A, + 0xF97B, + 0xF97C, + 0xF97D, + 0xF97E, + 0xF97F, + 0xF980, + 0xF981, + 0xF982, + 0xF983, + 0xF984, + 0xF985, + 0xF986, + 0xF987, + 0xF988, + 0xF989, + 0xF98A, + 0xF98B, + 0xF98C, + 0xF98D, + 0xF98E, + 0xF98F, + 0xF990, + 0xF991, + 0xF992, + 0xF993, + 0xF994, + 0xF995, + 0xF996, + 0xF997, + 0xF998, + 0xF999, + 0xF99A, + 0xF99B, + 0xF99C, + 0xF99D, + 0xF99E, + 0xF99F, + 0xF9A0, + 0xF9A1, + 0xF9A2, + 0xF9A3, + 0xF9A4, + 0xF9A5, + 0xF9A6, + 0xF9A7, + 0xF9A8, + 0xF9A9, + 0xF9AA, + 0xF9AB, + 0xF9AC, + 0xF9AD, + 0xF9AE, + 0xF9AF, + 0xF9B0, + 0xF9B1, + 0xF9B2, + 0xF9B3, + 0xF9B4, + 0xF9B5, + 0xF9B6, + 0xF9B7, + 0xF9B8, + 0xF9B9, + 0xF9BA, + 0xF9BB, + 0xF9BC, + 0xF9BD, + 0xF9BE, + 0xF9BF, + 0xF9C0, + 0xF9C1, + 0xF9C2, + 0xF9C3, + 0xF9C4, + 0xF9C5, + 0xF9C6, + 0xF9C7, + 0xF9C8, + 0xF9C9, + 0xF9CA, + 0xF9CB, + 0xF9CC, + 0xF9CD, + 0xF9CE, + 0xF9CF, + 0xF9D0, + 0xF9D1, + 0xF9D2, + 0xF9D3, + 0xF9D4, + 0xF9D5, + 0xF9D6, + 0xF9D7, + 0xF9D8, + 0xF9D9, + 0xF9DA, + 0xF9DB, + 0xF9DC, + 0xF9DD, + 0xF9DE, + 0xF9DF, + 0xF9E0, + 0xF9E1, + 0xF9E2, + 0xF9E3, + 0xF9E4, + 0xF9E5, + 0xF9E6, + 0xF9E7, + 0xF9E8, + 0xF9E9, + 0xF9EA, + 0xF9EB, + 0xF9EC, + 0xF9ED, + 0xF9EE, + 0xF9EF, + 0xF9F0, + 0xF9F1, + 0xF9F2, + 0xF9F3, + 0xF9F4, + 0xF9F5, + 0xF9F6, + 0xF9F7, + 0xF9F8, + 0xF9F9, + 0xF9FA, + 0xF9FB, + 0xF9FC, + 0xF9FD, + 0xF9FE, + 0xF9FF, + 0xFA00, + 0xFA01, + 0xFA02, + 0xFA03, + 0xFA04, + 0xFA05, + 0xFA06, + 0xFA07, + 0xFA08, + 0xFA09, + 0xFA0A, + 0xFA0B, + 0xFA0C, + 0xFA0D, + 0xFA0E, + 0xFA10, + 0xFA11, + 0xFA12, + 0xFA13, + 0xFA15, + 0xFA16, + 0xFA17, + 0xFA18, + 0xFA19, + 0xFA1A, + 0xFA1B, + 0xFA1C, + 0xFA1D, + 0xFA1E, + 0xFA1F, + 0xFA20, + 0xFA21, + 0xFA22, + 0xFA23, + 0xFA25, + 0xFA26, + 0xFA27, + 0xFA2A, + 0xFA2B, + 0xFA2C, + 0xFA2D, + 0xFA2E, + 0xFA2F, + 0xFA30, + 0xFA31, + 0xFA32, + 0xFA33, + 0xFA34, + 0xFA35, + 0xFA36, + 0xFA37, + 0xFA38, + 0xFA39, + 0xFA3A, + 0xFA3B, + 0xFA3C, + 0xFA3D, + 0xFA3E, + 0xFA3F, + 0xFA40, + 0xFA41, + 0xFA42, + 0xFA43, + 0xFA44, + 0xFA45, + 0xFA46, + 0xFA47, + 0xFA48, + 0xFA49, + 0xFA4A, + 0xFA4B, + 0xFA4C, + 0xFA4D, + 0xFA4E, + 0xFA4F, + 0xFA50, + 0xFA51, + 0xFA52, + 0xFA53, + 0xFA54, + 0xFA55, + 0xFA56, + 0xFA57, + 0xFA58, + 0xFA59, + 0xFA5A, + 0xFA5B, + 0xFA5C, + 0xFA5D, + 0xFA5F, + 0xFA60, + 0xFA61, + 0xFA62, + 0xFA63, + 0xFA64, + 0xFA65, + 0xFA66, + 0xFA67, + 0xFA68, + 0xFA69, + 0xFA6A, + 0xFA6B, + 0xFA6C, + 0xFA6D, + 0xFA6E, + 0xFA70, + 0xFA71, + 0xFA72, + 0xFA73, + 0xFA74, + 0xFA75, + 0xFA76, + 0xFA77, + 0xFA78, + 0xFA79, + 0xFA7A, + 0xFA7B, + 0xFA7C, + 0xFA7D, + 0xFA7E, + 0xFA7F, + 0xFA80, + 0xFA81, + 0xFA82, + 0xFA83, + 0xFA84, + 0xFA85, + 0xFA86, + 0xFA87, + 0xFA88, + 0xFA89, + 0xFA8A, + 0xFA8B, + 0xFA8C, + 0xFA8D, + 0xFA8E, + 0xFA8F, + 0xFA90, + 0xFA91, + 0xFA92, + 0xFA93, + 0xFA94, + 0xFA95, + 0xFA96, + 0xFA97, + 0xFA98, + 0xFA99, + 0xFA9A, + 0xFA9B, + 0xFA9C, + 0xFA9D, + 0xFA9E, + 0xFA9F, + 0xFAA0, + 0xFAA1, + 0xFAA2, + 0xFAA3, + 0xFAA4, + 0xFAA5, + 0xFAA6, + 0xFAA7, + 0xFAA8, + 0xFAA9, + 0xFAAA, + 0xFAAB, + 0xFAAC, + 0xFAAD, + 0xFAAE, + 0xFAAF, + 0xFAB0, + 0xFAB1, + 0xFAB2, + 0xFAB3, + 0xFAB4, + 0xFAB5, + 0xFAB6, + 0xFAB7, + 0xFAB8, + 0xFAB9, + 0xFABA, + 0xFABB, + 0xFABC, + 0xFABD, + 0xFABE, + 0xFABF, + 0xFAC0, + 0xFAC1, + 0xFAC2, + 0xFAC3, + 0xFAC4, + 0xFAC5, + 0xFAC6, + 0xFAC7, + 0xFAC8, + 0xFAC9, + 0xFACA, + 0xFACB, + 0xFACC, + 0xFACD, + 0xFACE, + 0xFACF, + 0xFAD0, + 0xFAD1, + 0xFAD2, + 0xFAD3, + 0xFAD4, + 0xFAD5, + 0xFAD6, + 0xFAD7, + 0xFAD8, + 0xFAD9, + 0xFADA, + 0xFB00, + 0xFB01, + 0xFB02, + 0xFB03, + 0xFB04, + 0xFB05, + 0xFB07, + 0xFB13, + 0xFB14, + 0xFB15, + 0xFB16, + 0xFB17, + 0xFB18, + 0xFB1D, + 0xFB1E, + 0xFB1F, + 0xFB20, + 0xFB21, + 0xFB22, + 0xFB23, + 0xFB24, + 0xFB25, + 0xFB26, + 0xFB27, + 0xFB28, + 0xFB29, + 0xFB2A, + 0xFB2B, + 0xFB2C, + 0xFB2D, + 0xFB2E, + 0xFB2F, + 0xFB30, + 0xFB31, + 0xFB32, + 0xFB33, + 0xFB34, + 0xFB35, + 0xFB36, + 0xFB37, + 0xFB38, + 0xFB39, + 0xFB3A, + 0xFB3B, + 0xFB3C, + 0xFB3D, + 0xFB3E, + 0xFB3F, + 0xFB40, + 0xFB41, + 0xFB42, + 0xFB43, + 0xFB44, + 0xFB45, + 0xFB46, + 0xFB47, + 0xFB48, + 0xFB49, + 0xFB4A, + 0xFB4B, + 0xFB4C, + 0xFB4D, + 0xFB4E, + 0xFB4F, + 0xFB50, + 0xFB52, + 0xFB56, + 0xFB5A, + 0xFB5E, + 0xFB62, + 0xFB66, + 0xFB6A, + 0xFB6E, + 0xFB72, + 0xFB76, + 0xFB7A, + 0xFB7E, + 0xFB82, + 0xFB84, + 0xFB86, + 0xFB88, + 0xFB8A, + 0xFB8C, + 0xFB8E, + 0xFB92, + 0xFB96, + 0xFB9A, + 0xFB9E, + 0xFBA0, + 0xFBA4, + 0xFBA6, + 0xFBAA, + 0xFBAE, + 0xFBB0, + 0xFBB2, + 0xFBD3, + 0xFBD7, + 0xFBD9, + 0xFBDB, + 0xFBDD, + 0xFBDE, + 0xFBE0, + 0xFBE2, + 0xFBE4, + 0xFBE8, + 0xFBEA, + 0xFBEC, + 0xFBEE, + 0xFBF0, + 0xFBF2, + 0xFBF4, + 0xFBF6, + 0xFBF9, + 0xFBFC, + 0xFC00, + 0xFC01, + 0xFC02, + 0xFC03, + 0xFC04, + 0xFC05, + 0xFC06, + 0xFC07, + 0xFC08, + 0xFC09, + 0xFC0A, + 0xFC0B, + 0xFC0C, + 0xFC0D, + 0xFC0E, + 0xFC0F, + 0xFC10, + 0xFC11, + 0xFC12, + 0xFC13, + 0xFC14, + 0xFC15, + 0xFC16, + 0xFC17, + 0xFC18, + 0xFC19, + 0xFC1A, + 0xFC1B, + 0xFC1C, + 0xFC1D, + 0xFC1E, + 0xFC1F, + 0xFC20, + 0xFC21, + 0xFC22, + 0xFC23, + 0xFC24, + 0xFC25, + 0xFC26, + 0xFC27, + 0xFC28, + 0xFC29, + 0xFC2A, + 0xFC2B, + 0xFC2C, + 0xFC2D, + 0xFC2E, + 0xFC2F, + 0xFC30, + 0xFC31, + 0xFC32, + 0xFC33, + 0xFC34, + 0xFC35, + 0xFC36, + 0xFC37, + 0xFC38, + 0xFC39, + 0xFC3A, + 0xFC3B, + 0xFC3C, + 0xFC3D, + 0xFC3E, + 0xFC3F, + 0xFC40, + 0xFC41, + 0xFC42, + 0xFC43, + 0xFC44, + 0xFC45, + 0xFC46, + 0xFC47, + 0xFC48, + 0xFC49, + 0xFC4A, + 0xFC4B, + 0xFC4C, + 0xFC4D, + 0xFC4E, + 0xFC4F, + 0xFC50, + 0xFC51, + 0xFC52, + 0xFC53, + 0xFC54, + 0xFC55, + 0xFC56, + 0xFC57, + 0xFC58, + 0xFC59, + 0xFC5A, + 0xFC5B, + 0xFC5C, + 0xFC5D, + 0xFC5E, + 0xFC5F, + 0xFC60, + 0xFC61, + 0xFC62, + 0xFC63, + 0xFC64, + 0xFC65, + 0xFC66, + 0xFC67, + 0xFC68, + 0xFC69, + 0xFC6A, + 0xFC6B, + 0xFC6C, + 0xFC6D, + 0xFC6E, + 0xFC6F, + 0xFC70, + 0xFC71, + 0xFC72, + 0xFC73, + 0xFC74, + 0xFC75, + 0xFC76, + 0xFC77, + 0xFC78, + 0xFC79, + 0xFC7A, + 0xFC7B, + 0xFC7C, + 0xFC7D, + 0xFC7E, + 0xFC7F, + 0xFC80, + 0xFC81, + 0xFC82, + 0xFC83, + 0xFC84, + 0xFC85, + 0xFC86, + 0xFC87, + 0xFC88, + 0xFC89, + 0xFC8A, + 0xFC8B, + 0xFC8C, + 0xFC8D, + 0xFC8E, + 0xFC8F, + 0xFC90, + 0xFC91, + 0xFC92, + 0xFC93, + 0xFC94, + 0xFC95, + 0xFC96, + 0xFC97, + 0xFC98, + 0xFC99, + 0xFC9A, + 0xFC9B, + 0xFC9C, + 0xFC9D, + 0xFC9E, + 0xFC9F, + 0xFCA0, + 0xFCA1, + 0xFCA2, + 0xFCA3, + 0xFCA4, + 0xFCA5, + 0xFCA6, + 0xFCA7, + 0xFCA8, + 0xFCA9, + 0xFCAA, + 0xFCAB, + 0xFCAC, + 0xFCAD, + 0xFCAE, + 0xFCAF, + 0xFCB0, + 0xFCB1, + 0xFCB2, + 0xFCB3, + 0xFCB4, + 0xFCB5, + 0xFCB6, + 0xFCB7, + 0xFCB8, + 0xFCB9, + 0xFCBA, + 0xFCBB, + 0xFCBC, + 0xFCBD, + 0xFCBE, + 0xFCBF, + 0xFCC0, + 0xFCC1, + 0xFCC2, + 0xFCC3, + 0xFCC4, + 0xFCC5, + 0xFCC6, + 0xFCC7, + 0xFCC8, + 0xFCC9, + 0xFCCA, + 0xFCCB, + 0xFCCC, + 0xFCCD, + 0xFCCE, + 0xFCCF, + 0xFCD0, + 0xFCD1, + 0xFCD2, + 0xFCD3, + 0xFCD4, + 0xFCD5, + 0xFCD6, + 0xFCD7, + 0xFCD8, + 0xFCD9, + 0xFCDA, + 0xFCDB, + 0xFCDC, + 0xFCDD, + 0xFCDE, + 0xFCDF, + 0xFCE0, + 0xFCE1, + 0xFCE2, + 0xFCE3, + 0xFCE4, + 0xFCE5, + 0xFCE6, + 0xFCE7, + 0xFCE8, + 0xFCE9, + 0xFCEA, + 0xFCEB, + 0xFCEC, + 0xFCED, + 0xFCEE, + 0xFCEF, + 0xFCF0, + 0xFCF1, + 0xFCF2, + 0xFCF3, + 0xFCF4, + 0xFCF5, + 0xFCF6, + 0xFCF7, + 0xFCF8, + 0xFCF9, + 0xFCFA, + 0xFCFB, + 0xFCFC, + 0xFCFD, + 0xFCFE, + 0xFCFF, + 0xFD00, + 0xFD01, + 0xFD02, + 0xFD03, + 0xFD04, + 0xFD05, + 0xFD06, + 0xFD07, + 0xFD08, + 0xFD09, + 0xFD0A, + 0xFD0B, + 0xFD0C, + 0xFD0D, + 0xFD0E, + 0xFD0F, + 0xFD10, + 0xFD11, + 0xFD12, + 0xFD13, + 0xFD14, + 0xFD15, + 0xFD16, + 0xFD17, + 0xFD18, + 0xFD19, + 0xFD1A, + 0xFD1B, + 0xFD1C, + 0xFD1D, + 0xFD1E, + 0xFD1F, + 0xFD20, + 0xFD21, + 0xFD22, + 0xFD23, + 0xFD24, + 0xFD25, + 0xFD26, + 0xFD27, + 0xFD28, + 0xFD29, + 0xFD2A, + 0xFD2B, + 0xFD2C, + 0xFD2D, + 0xFD2E, + 0xFD2F, + 0xFD30, + 0xFD31, + 0xFD32, + 0xFD33, + 0xFD34, + 0xFD35, + 0xFD36, + 0xFD37, + 0xFD38, + 0xFD39, + 0xFD3A, + 0xFD3B, + 0xFD3C, + 0xFD3E, + 0xFD50, + 0xFD51, + 0xFD53, + 0xFD54, + 0xFD55, + 0xFD56, + 0xFD57, + 0xFD58, + 0xFD5A, + 0xFD5B, + 0xFD5C, + 0xFD5D, + 0xFD5E, + 0xFD5F, + 0xFD61, + 0xFD62, + 0xFD64, + 0xFD66, + 0xFD67, + 0xFD69, + 0xFD6A, + 0xFD6C, + 0xFD6E, + 0xFD6F, + 0xFD71, + 0xFD73, + 0xFD74, + 0xFD75, + 0xFD76, + 0xFD78, + 0xFD79, + 0xFD7A, + 0xFD7B, + 0xFD7C, + 0xFD7E, + 0xFD7F, + 0xFD80, + 0xFD81, + 0xFD82, + 0xFD83, + 0xFD85, + 0xFD87, + 0xFD89, + 0xFD8A, + 0xFD8B, + 0xFD8C, + 0xFD8D, + 0xFD8E, + 0xFD8F, + 0xFD90, + 0xFD92, + 0xFD93, + 0xFD94, + 0xFD95, + 0xFD96, + 0xFD97, + 0xFD99, + 0xFD9A, + 0xFD9B, + 0xFD9C, + 0xFD9E, + 0xFD9F, + 0xFDA0, + 0xFDA1, + 0xFDA2, + 0xFDA3, + 0xFDA4, + 0xFDA5, + 0xFDA6, + 0xFDA7, + 0xFDA8, + 0xFDA9, + 0xFDAA, + 0xFDAB, + 0xFDAC, + 0xFDAD, + 0xFDAE, + 0xFDAF, + 0xFDB0, + 0xFDB1, + 0xFDB2, + 0xFDB3, + 0xFDB4, + 0xFDB5, + 0xFDB6, + 0xFDB7, + 0xFDB8, + 0xFDB9, + 0xFDBA, + 0xFDBB, + 0xFDBC, + 0xFDBD, + 0xFDBE, + 0xFDBF, + 0xFDC0, + 0xFDC1, + 0xFDC2, + 0xFDC3, + 0xFDC4, + 0xFDC5, + 0xFDC6, + 0xFDC7, + 0xFDC8, + 0xFDD0, + 0xFDF0, + 0xFDF1, + 0xFDF2, + 0xFDF3, + 0xFDF4, + 0xFDF5, + 0xFDF6, + 0xFDF7, + 0xFDF8, + 0xFDF9, + 0xFDFA, + 0xFDFB, + 0xFDFC, + 0xFDFD, + 0xFE00, + 0xFE10, + 0xFE11, + 0xFE12, + 0xFE13, + 0xFE14, + 0xFE15, + 0xFE16, + 0xFE17, + 0xFE18, + 0xFE19, + 0xFE20, + 0xFE30, + 0xFE31, + 0xFE32, + 0xFE33, + 0xFE35, + 0xFE36, + 0xFE37, + 0xFE38, + 0xFE39, + 0xFE3A, + 0xFE3B, + 0xFE3C, + 0xFE3D, + 0xFE3E, + 0xFE3F, + 0xFE40, + 0xFE41, + 0xFE42, + 0xFE43, + 0xFE44, + 0xFE45, + 0xFE47, + 0xFE48, + 0xFE49, + 0xFE4D, + 0xFE50, + 0xFE51, + 0xFE52, + 0xFE54, + 0xFE55, + 0xFE56, + 0xFE57, + 0xFE58, + 0xFE59, + 0xFE5A, + 0xFE5B, + 0xFE5C, + 0xFE5D, + 0xFE5E, + 0xFE5F, + 0xFE60, + 0xFE61, + 0xFE62, + 0xFE63, + 0xFE64, + 0xFE65, + 0xFE66, + 0xFE67, + 0xFE68, + 0xFE69, + 0xFE6A, + 0xFE6B, + 0xFE6C, + 0xFE70, + 0xFE71, + 0xFE72, + 0xFE73, + 0xFE74, + 0xFE75, + 0xFE76, + 0xFE77, + 0xFE78, + 0xFE79, + 0xFE7A, + 0xFE7B, + 0xFE7C, + 0xFE7D, + 0xFE7E, + 0xFE7F, + 0xFE80, + 0xFE81, + 0xFE83, + 0xFE85, + 0xFE87, + 0xFE89, + 0xFE8D, + 0xFE8F, + 0xFE93, + 0xFE95, + 0xFE99, + 0xFE9D, + 0xFEA1, + 0xFEA5, + 0xFEA9, + 0xFEAB, + 0xFEAD, + 0xFEAF, + 0xFEB1, + 0xFEB5, + 0xFEB9, + 0xFEBD, + 0xFEC1, + 0xFEC5, + 0xFEC9, + 0xFECD, + 0xFED1, + 0xFED5, + 0xFED9, + 0xFEDD, + 0xFEE1, + 0xFEE5, + 0xFEE9, + 0xFEED, + 0xFEEF, + 0xFEF1, + 0xFEF5, + 0xFEF7, + 0xFEF9, + 0xFEFB, + 0xFEFD, + 0xFEFF, + 0xFF00, + 0xFF01, + 0xFF02, + 0xFF03, + 0xFF04, + 0xFF05, + 0xFF06, + 0xFF07, + 0xFF08, + 0xFF09, + 0xFF0A, + 0xFF0B, + 0xFF0C, + 0xFF0D, + 0xFF0E, + 0xFF0F, + 0xFF10, + 0xFF11, + 0xFF12, + 0xFF13, + 0xFF14, + 0xFF15, + 0xFF16, + 0xFF17, + 0xFF18, + 0xFF19, + 0xFF1A, + 0xFF1B, + 0xFF1C, + 0xFF1D, + 0xFF1E, + 0xFF1F, + 0xFF20, + 0xFF21, + 0xFF22, + 0xFF23, + 0xFF24, + 0xFF25, + 0xFF26, + 0xFF27, + 0xFF28, + 0xFF29, + 0xFF2A, + 0xFF2B, + 0xFF2C, + 0xFF2D, + 0xFF2E, + 0xFF2F, + 0xFF30, + 0xFF31, + 0xFF32, + 0xFF33, + 0xFF34, + 0xFF35, + 0xFF36, + 0xFF37, + 0xFF38, + 0xFF39, + 0xFF3A, + 0xFF3B, + 0xFF3C, + 0xFF3D, + 0xFF3E, + 0xFF3F, + 0xFF40, + 0xFF41, + 0xFF42, + 0xFF43, + 0xFF44, + 0xFF45, + 0xFF46, + 0xFF47, + 0xFF48, + 0xFF49, + 0xFF4A, + 0xFF4B, + 0xFF4C, + 0xFF4D, + 0xFF4E, + 0xFF4F, + 0xFF50, + 0xFF51, + 0xFF52, + 0xFF53, + 0xFF54, + 0xFF55, + 0xFF56, + 0xFF57, + 0xFF58, + 0xFF59, + 0xFF5A, + 0xFF5B, + 0xFF5C, + 0xFF5D, + 0xFF5E, + 0xFF5F, + 0xFF60, + 0xFF61, + 0xFF62, + 0xFF63, + 0xFF64, + 0xFF65, + 0xFF66, + 0xFF67, + 0xFF68, + 0xFF69, + 0xFF6A, + 0xFF6B, + 0xFF6C, + 0xFF6D, + 0xFF6E, + 0xFF6F, + 0xFF70, + 0xFF71, + 0xFF72, + 0xFF73, + 0xFF74, + 0xFF75, + 0xFF76, + 0xFF77, + 0xFF78, + 0xFF79, + 0xFF7A, + 0xFF7B, + 0xFF7C, + 0xFF7D, + 0xFF7E, + 0xFF7F, + 0xFF80, + 0xFF81, + 0xFF82, + 0xFF83, + 0xFF84, + 0xFF85, + 0xFF86, + 0xFF87, + 0xFF88, + 0xFF89, + 0xFF8A, + 0xFF8B, + 0xFF8C, + 0xFF8D, + 0xFF8E, + 0xFF8F, + 0xFF90, + 0xFF91, + 0xFF92, + 0xFF93, + 0xFF94, + 0xFF95, + 0xFF96, + 0xFF97, + 0xFF98, + 0xFF99, + 0xFF9A, + 0xFF9B, + 0xFF9C, + 0xFF9D, + 0xFF9E, + 0xFF9F, + 0xFFA0, + 0xFFA1, + 0xFFA2, + 0xFFA3, + 0xFFA4, + 0xFFA5, + 0xFFA6, + 0xFFA7, + 0xFFA8, + 0xFFA9, + 0xFFAA, + 0xFFAB, + 0xFFAC, + 0xFFAD, + 0xFFAE, + 0xFFAF, + 0xFFB0, + 0xFFB1, + 0xFFB2, + 0xFFB3, + 0xFFB4, + 0xFFB5, + 0xFFB6, + 0xFFB7, + 0xFFB8, + 0xFFB9, + 0xFFBA, + 0xFFBB, + 0xFFBC, + 0xFFBD, + 0xFFBE, + 0xFFBF, + 0xFFC2, + 0xFFC3, + 0xFFC4, + 0xFFC5, + 0xFFC6, + 0xFFC7, + 0xFFC8, + 0xFFCA, + 0xFFCB, + 0xFFCC, + 0xFFCD, + 0xFFCE, + 0xFFCF, + 0xFFD0, + 0xFFD2, + 0xFFD3, + 0xFFD4, + 0xFFD5, + 0xFFD6, + 0xFFD7, + 0xFFD8, + 0xFFDA, + 0xFFDB, + 0xFFDC, + 0xFFDD, + 0xFFE0, + 0xFFE1, + 0xFFE2, + 0xFFE3, + 0xFFE4, + 0xFFE5, + 0xFFE6, + 0xFFE7, + 0xFFE8, + 0xFFE9, + 0xFFEA, + 0xFFEB, + 0xFFEC, + 0xFFED, + 0xFFEE, + 0xFFEF, + 0x10000, + 0x1000C, + 0x1000D, + 0x10027, + 0x10028, + 0x1003B, + 0x1003C, + 0x1003E, + 0x1003F, + 0x1004E, + 0x10050, + 0x1005E, + 0x10080, + 0x100FB, + 0x10100, + 0x10103, + 0x10107, + 0x10134, + 0x10137, + 0x1018F, + 0x10190, + 0x1019D, + 0x101A0, + 0x101A1, + 0x101D0, + 0x101FE, + 0x10280, + 0x1029D, + 0x102A0, + 0x102D1, + 0x102E0, + 0x102FC, + 0x10300, + 0x10324, + 0x1032D, + 0x1034B, + 0x10350, + 0x1037B, + 0x10380, + 0x1039E, + 0x1039F, + 0x103C4, + 0x103C8, + 0x103D6, + 0x10400, + 0x10401, + 0x10402, + 0x10403, + 0x10404, + 0x10405, + 0x10406, + 0x10407, + 0x10408, + 0x10409, + 0x1040A, + 0x1040B, + 0x1040C, + 0x1040D, + 0x1040E, + 0x1040F, + 0x10410, + 0x10411, + 0x10412, + 0x10413, + 0x10414, + 0x10415, + 0x10416, + 0x10417, + 0x10418, + 0x10419, + 0x1041A, + 0x1041B, + 0x1041C, + 0x1041D, + 0x1041E, + 0x1041F, + 0x10420, + 0x10421, + 0x10422, + 0x10423, + 0x10424, + 0x10425, + 0x10426, + 0x10427, + 0x10428, + 0x1049E, + 0x104A0, + 0x104AA, + 0x104B0, + 0x104B1, + 0x104B2, + 0x104B3, + 0x104B4, + 0x104B5, + 0x104B6, + 0x104B7, + 0x104B8, + 0x104B9, + 0x104BA, + 0x104BB, + 0x104BC, + 0x104BD, + 0x104BE, + 0x104BF, + 0x104C0, + 0x104C1, + 0x104C2, + 0x104C3, + 0x104C4, + 0x104C5, + 0x104C6, + 0x104C7, + 0x104C8, + 0x104C9, + 0x104CA, + 0x104CB, + 0x104CC, + 0x104CD, + 0x104CE, + 0x104CF, + 0x104D0, + 0x104D1, + 0x104D2, + 0x104D3, + 0x104D4, + 0x104D8, + 0x104FC, + 0x10500, + 0x10528, + 0x10530, + 0x10564, + 0x1056F, + 0x10570, + 0x10571, + 0x10572, + 0x10573, + 0x10574, + 0x10575, + 0x10576, + 0x10577, + 0x10578, + 0x10579, + 0x1057A, + 0x1057B, + 0x1057C, + 0x1057D, + 0x1057E, + 0x1057F, + 0x10580, + 0x10581, + 0x10582, + 0x10583, + 0x10584, + 0x10585, + 0x10586, + 0x10587, + 0x10588, + 0x10589, + 0x1058A, + 0x1058B, + 0x1058C, + 0x1058D, + 0x1058E, + 0x1058F, + 0x10590, + 0x10591, + 0x10592, + 0x10593, + 0x10594, + 0x10595, + 0x10596, + 0x10597, + 0x105A2, + 0x105A3, + 0x105B2, + 0x105B3, + 0x105BA, + 0x105BB, + 0x105BD, + 0x105C0, + 0x105F4, + 0x10600, + 0x10737, + 0x10740, + 0x10756, + 0x10760, + 0x10768, + 0x10780, + 0x10781, + 0x10782, + 0x10783, + 0x10784, + 0x10785, + 0x10786, + 0x10787, + 0x10788, + 0x10789, + 0x1078A, + 0x1078B, + 0x1078C, + 0x1078D, + 0x1078E, + 0x1078F, + 0x10790, + 0x10791, + 0x10792, + 0x10793, + 0x10794, + 0x10795, + 0x10796, + 0x10797, + 0x10798, + 0x10799, + 0x1079A, + 0x1079B, + 0x1079C, + 0x1079D, + 0x1079E, + 0x1079F, + 0x107A0, + 0x107A1, + 0x107A2, + 0x107A3, + 0x107A4, + 0x107A5, + 0x107A6, + 0x107A7, + 0x107A8, + 0x107A9, + 0x107AA, + 0x107AB, + 0x107AC, + 0x107AD, + 0x107AE, + 0x107AF, + 0x107B0, + 0x107B1, + 0x107B2, + 0x107B3, + 0x107B4, + 0x107B5, + 0x107B6, + 0x107B7, + 0x107B8, + 0x107B9, + 0x107BA, + 0x107BB, + 0x107BC, + 0x107BD, + 0x107BE, + 0x107BF, + 0x107C0, + 0x10800, + 0x10806, + 0x10808, + 0x10809, + 0x1080A, + 0x10836, + 0x10837, + 0x10839, + 0x1083C, + 0x1083D, + 0x1083F, + 0x10856, + 0x10857, + 0x1089F, + 0x108A7, + 0x108B0, + 0x108E0, + 0x108F3, + 0x108F4, + 0x108F6, + 0x108FB, + 0x1091C, + 0x1091F, + 0x1093A, + 0x1093F, + 0x1095A, + 0x10980, + 0x109B8, + 0x109BC, + 0x109D0, + 0x109D2, + 0x10A04, + 0x10A05, + 0x10A07, + 0x10A0C, + 0x10A14, + 0x10A15, + 0x10A18, + 0x10A19, + 0x10A36, + 0x10A38, + 0x10A3B, + 0x10A3F, + 0x10A49, + 0x10A50, + 0x10A59, + 0x10A60, + 0x10AA0, + 0x10AC0, + 0x10AE7, + 0x10AEB, + 0x10AF7, + 0x10B00, + 0x10B36, + 0x10B39, + 0x10B56, + 0x10B58, + 0x10B73, + 0x10B78, + 0x10B92, + 0x10B99, + 0x10B9D, + 0x10BA9, + 0x10BB0, + 0x10C00, + 0x10C49, + 0x10C80, + 0x10C81, + 0x10C82, + 0x10C83, + 0x10C84, + 0x10C85, + 0x10C86, + 0x10C87, + 0x10C88, + 0x10C89, + 0x10C8A, + 0x10C8B, + 0x10C8C, + 0x10C8D, + 0x10C8E, + 0x10C8F, + 0x10C90, + 0x10C91, + 0x10C92, + 0x10C93, + 0x10C94, + 0x10C95, + 0x10C96, + 0x10C97, + 0x10C98, + 0x10C99, + 0x10C9A, + 0x10C9B, + 0x10C9C, + 0x10C9D, + 0x10C9E, + 0x10C9F, + 0x10CA0, + 0x10CA1, + 0x10CA2, + 0x10CA3, + 0x10CA4, + 0x10CA5, + 0x10CA6, + 0x10CA7, + 0x10CA8, + 0x10CA9, + 0x10CAA, + 0x10CAB, + 0x10CAC, + 0x10CAD, + 0x10CAE, + 0x10CAF, + 0x10CB0, + 0x10CB1, + 0x10CB2, + 0x10CB3, + 0x10CC0, + 0x10CF3, + 0x10CFA, + 0x10D28, + 0x10D30, + 0x10D3A, + 0x10D40, + 0x10D50, + 0x10D51, + 0x10D52, + 0x10D53, + 0x10D54, + 0x10D55, + 0x10D56, + 0x10D57, + 0x10D58, + 0x10D59, + 0x10D5A, + 0x10D5B, + 0x10D5C, + 0x10D5D, + 0x10D5E, + 0x10D5F, + 0x10D60, + 0x10D61, + 0x10D62, + 0x10D63, + 0x10D64, + 0x10D65, + 0x10D66, + 0x10D69, + 0x10D86, + 0x10D8E, + 0x10D90, + 0x10E60, + 0x10E7F, + 0x10E80, + 0x10EAA, + 0x10EAB, + 0x10EAE, + 0x10EB0, + 0x10EB2, + 0x10EC2, + 0x10EC8, + 0x10EC9, + 0x10EEF, + 0x10EF0, + 0x10F28, + 0x10F30, + 0x10F5A, + 0x10F70, + 0x10F8A, + 0x10FB0, + 0x10FCC, + 0x10FE0, + 0x10FF7, + 0x11000, + 0x1104E, + 0x11052, + 0x11076, + 0x1107F, + 0x110BD, + 0x110BE, + 0x110C3, + 0x110D0, + 0x110E9, + 0x110F0, + 0x110FA, + 0x11100, + 0x11135, + 0x11136, + 0x11148, + 0x11150, + 0x11177, + 0x11180, + 0x111E0, + 0x111E1, + 0x111F5, + 0x11200, + 0x11212, + 0x11213, + 0x11242, + 0x11280, + 0x11287, + 0x11288, + 0x11289, + 0x1128A, + 0x1128E, + 0x1128F, + 0x1129E, + 0x1129F, + 0x112AA, + 0x112B0, + 0x112EB, + 0x112F0, + 0x112FA, + 0x11300, + 0x11304, + 0x11305, + 0x1130D, + 0x1130F, + 0x11311, + 0x11313, + 0x11329, + 0x1132A, + 0x11331, + 0x11332, + 0x11334, + 0x11335, + 0x1133A, + 0x1133B, + 0x11345, + 0x11347, + 0x11349, + 0x1134B, + 0x1134E, + 0x11350, + 0x11351, + 0x11357, + 0x11358, + 0x1135D, + 0x11364, + 0x11366, + 0x1136D, + 0x11370, + 0x11375, + 0x11380, + 0x1138A, + 0x1138B, + 0x1138C, + 0x1138E, + 0x1138F, + 0x11390, + 0x113B6, + 0x113B7, + 0x113C1, + 0x113C2, + 0x113C3, + 0x113C5, + 0x113C6, + 0x113C7, + 0x113CB, + 0x113CC, + 0x113D6, + 0x113D7, + 0x113D9, + 0x113E1, + 0x113E3, + 0x11400, + 0x1145C, + 0x1145D, + 0x11462, + 0x11480, + 0x114C8, + 0x114D0, + 0x114DA, + 0x11580, + 0x115B6, + 0x115B8, + 0x115DE, + 0x11600, + 0x11645, + 0x11650, + 0x1165A, + 0x11660, + 0x1166D, + 0x11680, + 0x116BA, + 0x116C0, + 0x116CA, + 0x116D0, + 0x116E4, + 0x11700, + 0x1171B, + 0x1171D, + 0x1172C, + 0x11730, + 0x11747, + 0x11800, + 0x1183C, + 0x118A0, + 0x118A1, + 0x118A2, + 0x118A3, + 0x118A4, + 0x118A5, + 0x118A6, + 0x118A7, + 0x118A8, + 0x118A9, + 0x118AA, + 0x118AB, + 0x118AC, + 0x118AD, + 0x118AE, + 0x118AF, + 0x118B0, + 0x118B1, + 0x118B2, + 0x118B3, + 0x118B4, + 0x118B5, + 0x118B6, + 0x118B7, + 0x118B8, + 0x118B9, + 0x118BA, + 0x118BB, + 0x118BC, + 0x118BD, + 0x118BE, + 0x118BF, + 0x118C0, + 0x118F3, + 0x118FF, + 0x11907, + 0x11909, + 0x1190A, + 0x1190C, + 0x11914, + 0x11915, + 0x11917, + 0x11918, + 0x11936, + 0x11937, + 0x11939, + 0x1193B, + 0x11947, + 0x11950, + 0x1195A, + 0x119A0, + 0x119A8, + 0x119AA, + 0x119D8, + 0x119DA, + 0x119E5, + 0x11A00, + 0x11A48, + 0x11A50, + 0x11AA3, + 0x11AB0, + 0x11AF9, + 0x11B00, + 0x11B0B, + 0x11B60, + 0x11B68, + 0x11BC0, + 0x11BE2, + 0x11BF0, + 0x11BFA, + 0x11C00, + 0x11C09, + 0x11C0A, + 0x11C37, + 0x11C38, + 0x11C46, + 0x11C50, + 0x11C6D, + 0x11C70, + 0x11C90, + 0x11C92, + 0x11CA8, + 0x11CA9, + 0x11CB7, + 0x11D00, + 0x11D07, + 0x11D08, + 0x11D0A, + 0x11D0B, + 0x11D37, + 0x11D3A, + 0x11D3B, + 0x11D3C, + 0x11D3E, + 0x11D3F, + 0x11D48, + 0x11D50, + 0x11D5A, + 0x11D60, + 0x11D66, + 0x11D67, + 0x11D69, + 0x11D6A, + 0x11D8F, + 0x11D90, + 0x11D92, + 0x11D93, + 0x11D99, + 0x11DA0, + 0x11DAA, + 0x11DB0, + 0x11DDC, + 0x11DE0, + 0x11DEA, + 0x11DF0, + 0x11DF2, + 0x11EE0, + 0x11EF9, + 0x11F00, + 0x11F11, + 0x11F12, + 0x11F3B, + 0x11F3E, + 0x11F5B, + 0x11FB0, + 0x11FB1, + 0x11FC0, + 0x11FF2, + 0x11FFF, + 0x1239A, + 0x12400, + 0x12544, + 0x12550, + 0x12687, + 0x12F90, + 0x12FF3, + 0x13000, + 0x13430, + 0x13440, + 0x13456, + 0x13460, + 0x143FB, + 0x14400, + 0x14647, + 0x16100, + 0x1613A, + 0x16800, + 0x16A39, + 0x16A40, + 0x16A5F, + 0x16A60, + 0x16A6A, + 0x16A6E, + 0x16ABF, + 0x16AC0, + 0x16ACA, + 0x16AD0, + 0x16AEE, + 0x16AF0, + 0x16AF6, + 0x16B00, + 0x16B46, + 0x16B50, + 0x16B5A, + 0x16B5B, + 0x16B62, + 0x16B63, + 0x16B78, + 0x16B7D, + 0x16B90, + 0x16D40, + 0x16D7A, + 0x16E40, + 0x16E41, + 0x16E42, + 0x16E43, + 0x16E44, + 0x16E45, + 0x16E46, + 0x16E47, + 0x16E48, + 0x16E49, + 0x16E4A, + 0x16E4B, + 0x16E4C, + 0x16E4D, + 0x16E4E, + 0x16E4F, + 0x16E50, + 0x16E51, + 0x16E52, + 0x16E53, + 0x16E54, + 0x16E55, + 0x16E56, + 0x16E57, + 0x16E58, + 0x16E59, + 0x16E5A, + 0x16E5B, + 0x16E5C, + 0x16E5D, + 0x16E5E, + 0x16E5F, + 0x16E60, + 0x16E9B, + 0x16EA0, + 0x16EA1, + 0x16EA2, + 0x16EA3, + 0x16EA4, + 0x16EA5, + 0x16EA6, + 0x16EA7, + 0x16EA8, + 0x16EA9, + 0x16EAA, + 0x16EAB, + 0x16EAC, + 0x16EAD, + 0x16EAE, + 0x16EAF, + 0x16EB0, + 0x16EB1, + 0x16EB2, + 0x16EB3, + 0x16EB4, + 0x16EB5, + 0x16EB6, + 0x16EB7, + 0x16EB8, + 0x16EB9, + 0x16EBB, + 0x16ED4, + 0x16F00, + 0x16F4B, + 0x16F4F, + 0x16F88, + 0x16F8F, + 0x16FA0, + 0x16FE0, + 0x16FE5, + 0x16FF0, + 0x16FF7, + 0x17000, + 0x18CDB, + 0x18CFF, + 0x18D21, + 0x18D80, + 0x18DF3, + 0x18E00, + 0x19192, + 0x191A0, + 0x191D3, + 0x1AFF0, + 0x1AFF4, + 0x1AFF5, + 0x1AFFC, + 0x1AFFD, + 0x1AFFF, + 0x1B000, + 0x1B123, + 0x1B124, + 0x1B125, + 0x1B126, + 0x1B127, + 0x1B129, + 0x1B132, + 0x1B133, + 0x1B150, + 0x1B153, + 0x1B155, + 0x1B156, + 0x1B164, + 0x1B169, + 0x1B170, + 0x1B2FC, + 0x1BC00, + 0x1BC6B, + 0x1BC70, + 0x1BC7D, + 0x1BC80, + 0x1BC89, + 0x1BC90, + 0x1BC9A, + 0x1BC9C, + 0x1BCA0, + 0x1BCA4, + 0x1CC00, + 0x1CCD6, + 0x1CCD7, + 0x1CCD8, + 0x1CCD9, + 0x1CCDA, + 0x1CCDB, + 0x1CCDC, + 0x1CCDD, + 0x1CCDE, + 0x1CCDF, + 0x1CCE0, + 0x1CCE1, + 0x1CCE2, + 0x1CCE3, + 0x1CCE4, + 0x1CCE5, + 0x1CCE6, + 0x1CCE7, + 0x1CCE8, + 0x1CCE9, + 0x1CCEA, + 0x1CCEB, + 0x1CCEC, + 0x1CCED, + 0x1CCEE, + 0x1CCEF, + 0x1CCF0, + 0x1CCF1, + 0x1CCF2, + 0x1CCF3, + 0x1CCF4, + 0x1CCF5, + 0x1CCF6, + 0x1CCF7, + 0x1CCF8, + 0x1CCF9, + 0x1CCFA, + 0x1CCFD, + 0x1CD00, + 0x1CEB4, + 0x1CEBA, + 0x1CED1, + 0x1CED2, + 0x1CED5, + 0x1CEDD, + 0x1CEFE, + 0x1CF00, + 0x1CF2E, + 0x1CF30, + 0x1CF47, + 0x1CF50, + 0x1CFC4, + 0x1D000, + 0x1D0F6, + 0x1D100, + 0x1D15E, + 0x1D15F, + 0x1D160, + 0x1D161, + 0x1D162, + 0x1D163, + 0x1D164, + 0x1D165, + 0x1D173, + 0x1D17B, + 0x1D1BB, + 0x1D1BC, + 0x1D1BD, + 0x1D1BE, + 0x1D1BF, + 0x1D1C0, + 0x1D1C1, + 0x1D246, + 0x1D250, + 0x1D282, + 0x1D2C0, + 0x1D2D4, + 0x1D2E0, + 0x1D2F4, + 0x1D300, + 0x1D357, + 0x1D360, + 0x1D379, + 0x1D400, + 0x1D401, + 0x1D402, + 0x1D403, + 0x1D404, + 0x1D405, + 0x1D406, + 0x1D407, + 0x1D408, + 0x1D409, + 0x1D40A, + 0x1D40B, + 0x1D40C, + 0x1D40D, + 0x1D40E, + 0x1D40F, + 0x1D410, + 0x1D411, + 0x1D412, + 0x1D413, + 0x1D414, + 0x1D415, + 0x1D416, + 0x1D417, + 0x1D418, + 0x1D419, + 0x1D41A, + 0x1D41B, + 0x1D41C, + 0x1D41D, + 0x1D41E, + 0x1D41F, + 0x1D420, + 0x1D421, + 0x1D422, + 0x1D423, + 0x1D424, + 0x1D425, + 0x1D426, + 0x1D427, + 0x1D428, + 0x1D429, + 0x1D42A, + 0x1D42B, + 0x1D42C, + 0x1D42D, + 0x1D42E, + 0x1D42F, + 0x1D430, + 0x1D431, + 0x1D432, + 0x1D433, + 0x1D434, + 0x1D435, + 0x1D436, + 0x1D437, + 0x1D438, + 0x1D439, + 0x1D43A, + 0x1D43B, + 0x1D43C, + 0x1D43D, + 0x1D43E, + 0x1D43F, + 0x1D440, + 0x1D441, + 0x1D442, + 0x1D443, + 0x1D444, + 0x1D445, + 0x1D446, + 0x1D447, + 0x1D448, + 0x1D449, + 0x1D44A, + 0x1D44B, + 0x1D44C, + 0x1D44D, + 0x1D44E, + 0x1D44F, + 0x1D450, + 0x1D451, + 0x1D452, + 0x1D453, + 0x1D454, + 0x1D455, + 0x1D456, + 0x1D457, + 0x1D458, + 0x1D459, + 0x1D45A, + 0x1D45B, + 0x1D45C, + 0x1D45D, + 0x1D45E, + 0x1D45F, + 0x1D460, + 0x1D461, + 0x1D462, + 0x1D463, + 0x1D464, + 0x1D465, + 0x1D466, + 0x1D467, + 0x1D468, + 0x1D469, + 0x1D46A, + 0x1D46B, + 0x1D46C, + 0x1D46D, + 0x1D46E, + 0x1D46F, + 0x1D470, + 0x1D471, + 0x1D472, + 0x1D473, + 0x1D474, + 0x1D475, + 0x1D476, + 0x1D477, + 0x1D478, + 0x1D479, + 0x1D47A, + 0x1D47B, + 0x1D47C, + 0x1D47D, + 0x1D47E, + 0x1D47F, + 0x1D480, + 0x1D481, + 0x1D482, + 0x1D483, + 0x1D484, + 0x1D485, + 0x1D486, + 0x1D487, + 0x1D488, + 0x1D489, + 0x1D48A, + 0x1D48B, + 0x1D48C, + 0x1D48D, + 0x1D48E, + 0x1D48F, + 0x1D490, + 0x1D491, + 0x1D492, + 0x1D493, + 0x1D494, + 0x1D495, + 0x1D496, + 0x1D497, + 0x1D498, + 0x1D499, + 0x1D49A, + 0x1D49B, + 0x1D49C, + 0x1D49D, + 0x1D49E, + 0x1D49F, + 0x1D4A0, + 0x1D4A2, + 0x1D4A3, + 0x1D4A5, + 0x1D4A6, + 0x1D4A7, + 0x1D4A9, + 0x1D4AA, + 0x1D4AB, + 0x1D4AC, + 0x1D4AD, + 0x1D4AE, + 0x1D4AF, + 0x1D4B0, + 0x1D4B1, + 0x1D4B2, + 0x1D4B3, + 0x1D4B4, + 0x1D4B5, + 0x1D4B6, + 0x1D4B7, + 0x1D4B8, + 0x1D4B9, + 0x1D4BA, + 0x1D4BB, + 0x1D4BC, + 0x1D4BD, + 0x1D4BE, + 0x1D4BF, + 0x1D4C0, + 0x1D4C1, + 0x1D4C2, + 0x1D4C3, + 0x1D4C4, + 0x1D4C5, + 0x1D4C6, + 0x1D4C7, + 0x1D4C8, + 0x1D4C9, + 0x1D4CA, + 0x1D4CB, + 0x1D4CC, + 0x1D4CD, + 0x1D4CE, + 0x1D4CF, + 0x1D4D0, + 0x1D4D1, + 0x1D4D2, + 0x1D4D3, + 0x1D4D4, + 0x1D4D5, + 0x1D4D6, + 0x1D4D7, + 0x1D4D8, + 0x1D4D9, + 0x1D4DA, + 0x1D4DB, + 0x1D4DC, + 0x1D4DD, + 0x1D4DE, + 0x1D4DF, + 0x1D4E0, + 0x1D4E1, + 0x1D4E2, + 0x1D4E3, + 0x1D4E4, + 0x1D4E5, + 0x1D4E6, + 0x1D4E7, + 0x1D4E8, + 0x1D4E9, + 0x1D4EA, + 0x1D4EB, + 0x1D4EC, + 0x1D4ED, + 0x1D4EE, + 0x1D4EF, + 0x1D4F0, + 0x1D4F1, + 0x1D4F2, + 0x1D4F3, + 0x1D4F4, + 0x1D4F5, + 0x1D4F6, + 0x1D4F7, + 0x1D4F8, + 0x1D4F9, + 0x1D4FA, + 0x1D4FB, + 0x1D4FC, + 0x1D4FD, + 0x1D4FE, + 0x1D4FF, + 0x1D500, + 0x1D501, + 0x1D502, + 0x1D503, + 0x1D504, + 0x1D505, + 0x1D506, + 0x1D507, + 0x1D508, + 0x1D509, + 0x1D50A, + 0x1D50B, + 0x1D50D, + 0x1D50E, + 0x1D50F, + 0x1D510, + 0x1D511, + 0x1D512, + 0x1D513, + 0x1D514, + 0x1D515, + 0x1D516, + 0x1D517, + 0x1D518, + 0x1D519, + 0x1D51A, + 0x1D51B, + 0x1D51C, + 0x1D51D, + 0x1D51E, + 0x1D51F, + 0x1D520, + 0x1D521, + 0x1D522, + 0x1D523, + 0x1D524, + 0x1D525, + 0x1D526, + 0x1D527, + 0x1D528, + 0x1D529, + 0x1D52A, + 0x1D52B, + 0x1D52C, + 0x1D52D, + 0x1D52E, + 0x1D52F, + 0x1D530, + 0x1D531, + 0x1D532, + 0x1D533, + 0x1D534, + 0x1D535, + 0x1D536, + 0x1D537, + 0x1D538, + 0x1D539, + 0x1D53A, + 0x1D53B, + 0x1D53C, + 0x1D53D, + 0x1D53E, + 0x1D53F, + 0x1D540, + 0x1D541, + 0x1D542, + 0x1D543, + 0x1D544, + 0x1D545, + 0x1D546, + 0x1D547, + 0x1D54A, + 0x1D54B, + 0x1D54C, + 0x1D54D, + 0x1D54E, + 0x1D54F, + 0x1D550, + 0x1D551, + 0x1D552, + 0x1D553, + 0x1D554, + 0x1D555, + 0x1D556, + 0x1D557, + 0x1D558, + 0x1D559, + 0x1D55A, + 0x1D55B, + 0x1D55C, + 0x1D55D, + 0x1D55E, + 0x1D55F, + 0x1D560, + 0x1D561, + 0x1D562, + 0x1D563, + 0x1D564, + 0x1D565, + 0x1D566, + 0x1D567, + 0x1D568, + 0x1D569, + 0x1D56A, + 0x1D56B, + 0x1D56C, + 0x1D56D, + 0x1D56E, + 0x1D56F, + 0x1D570, + 0x1D571, + 0x1D572, + 0x1D573, + 0x1D574, + 0x1D575, + 0x1D576, + 0x1D577, + 0x1D578, + 0x1D579, + 0x1D57A, + 0x1D57B, + 0x1D57C, + 0x1D57D, + 0x1D57E, + 0x1D57F, + 0x1D580, + 0x1D581, + 0x1D582, + 0x1D583, + 0x1D584, + 0x1D585, + 0x1D586, + 0x1D587, + 0x1D588, + 0x1D589, + 0x1D58A, + 0x1D58B, + 0x1D58C, + 0x1D58D, + 0x1D58E, + 0x1D58F, + 0x1D590, + 0x1D591, + 0x1D592, + 0x1D593, + 0x1D594, + 0x1D595, + 0x1D596, + 0x1D597, + 0x1D598, + 0x1D599, + 0x1D59A, + 0x1D59B, + 0x1D59C, + 0x1D59D, + 0x1D59E, + 0x1D59F, + 0x1D5A0, + 0x1D5A1, + 0x1D5A2, + 0x1D5A3, + 0x1D5A4, + 0x1D5A5, + 0x1D5A6, + 0x1D5A7, + 0x1D5A8, + 0x1D5A9, + 0x1D5AA, + 0x1D5AB, + 0x1D5AC, + 0x1D5AD, + 0x1D5AE, + 0x1D5AF, + 0x1D5B0, + 0x1D5B1, + 0x1D5B2, + 0x1D5B3, + 0x1D5B4, + 0x1D5B5, + 0x1D5B6, + 0x1D5B7, + 0x1D5B8, + 0x1D5B9, + 0x1D5BA, + 0x1D5BB, + 0x1D5BC, + 0x1D5BD, + 0x1D5BE, + 0x1D5BF, + 0x1D5C0, + 0x1D5C1, + 0x1D5C2, + 0x1D5C3, + 0x1D5C4, + 0x1D5C5, + 0x1D5C6, + 0x1D5C7, + 0x1D5C8, + 0x1D5C9, + 0x1D5CA, + 0x1D5CB, + 0x1D5CC, + 0x1D5CD, + 0x1D5CE, + 0x1D5CF, + 0x1D5D0, + 0x1D5D1, + 0x1D5D2, + 0x1D5D3, + 0x1D5D4, + 0x1D5D5, + 0x1D5D6, + 0x1D5D7, + 0x1D5D8, + 0x1D5D9, + 0x1D5DA, + 0x1D5DB, + 0x1D5DC, + 0x1D5DD, + 0x1D5DE, + 0x1D5DF, + 0x1D5E0, + 0x1D5E1, + 0x1D5E2, + 0x1D5E3, + 0x1D5E4, + 0x1D5E5, + 0x1D5E6, + 0x1D5E7, + 0x1D5E8, + 0x1D5E9, + 0x1D5EA, + 0x1D5EB, + 0x1D5EC, + 0x1D5ED, + 0x1D5EE, + 0x1D5EF, + 0x1D5F0, + 0x1D5F1, + 0x1D5F2, + 0x1D5F3, + 0x1D5F4, + 0x1D5F5, + 0x1D5F6, + 0x1D5F7, + 0x1D5F8, + 0x1D5F9, + 0x1D5FA, + 0x1D5FB, + 0x1D5FC, + 0x1D5FD, + 0x1D5FE, + 0x1D5FF, + 0x1D600, + 0x1D601, + 0x1D602, + 0x1D603, + 0x1D604, + 0x1D605, + 0x1D606, + 0x1D607, + 0x1D608, + 0x1D609, + 0x1D60A, + 0x1D60B, + 0x1D60C, + 0x1D60D, + 0x1D60E, + 0x1D60F, + 0x1D610, + 0x1D611, + 0x1D612, + 0x1D613, + 0x1D614, + 0x1D615, + 0x1D616, + 0x1D617, + 0x1D618, + 0x1D619, + 0x1D61A, + 0x1D61B, + 0x1D61C, + 0x1D61D, + 0x1D61E, + 0x1D61F, + 0x1D620, + 0x1D621, + 0x1D622, + 0x1D623, + 0x1D624, + 0x1D625, + 0x1D626, + 0x1D627, + 0x1D628, + 0x1D629, + 0x1D62A, + 0x1D62B, + 0x1D62C, + 0x1D62D, + 0x1D62E, + 0x1D62F, + 0x1D630, + 0x1D631, + 0x1D632, + 0x1D633, + 0x1D634, + 0x1D635, + 0x1D636, + 0x1D637, + 0x1D638, + 0x1D639, + 0x1D63A, + 0x1D63B, + 0x1D63C, + 0x1D63D, + 0x1D63E, + 0x1D63F, + 0x1D640, + 0x1D641, + 0x1D642, + 0x1D643, + 0x1D644, + 0x1D645, + 0x1D646, + 0x1D647, + 0x1D648, + 0x1D649, + 0x1D64A, + 0x1D64B, + 0x1D64C, + 0x1D64D, + 0x1D64E, + 0x1D64F, + 0x1D650, + 0x1D651, + 0x1D652, + 0x1D653, + 0x1D654, + 0x1D655, + 0x1D656, + 0x1D657, + 0x1D658, + 0x1D659, + 0x1D65A, + 0x1D65B, + 0x1D65C, + 0x1D65D, + 0x1D65E, + 0x1D65F, + 0x1D660, + 0x1D661, + 0x1D662, + 0x1D663, + 0x1D664, + 0x1D665, + 0x1D666, + 0x1D667, + 0x1D668, + 0x1D669, + 0x1D66A, + 0x1D66B, + 0x1D66C, + 0x1D66D, + 0x1D66E, + 0x1D66F, + 0x1D670, + 0x1D671, + 0x1D672, + 0x1D673, + 0x1D674, + 0x1D675, + 0x1D676, + 0x1D677, + 0x1D678, + 0x1D679, + 0x1D67A, + 0x1D67B, + 0x1D67C, + 0x1D67D, + 0x1D67E, + 0x1D67F, + 0x1D680, + 0x1D681, + 0x1D682, + 0x1D683, + 0x1D684, + 0x1D685, + 0x1D686, + 0x1D687, + 0x1D688, + 0x1D689, + 0x1D68A, + 0x1D68B, + 0x1D68C, + 0x1D68D, + 0x1D68E, + 0x1D68F, + 0x1D690, + 0x1D691, + 0x1D692, + 0x1D693, + 0x1D694, + 0x1D695, + 0x1D696, + 0x1D697, + 0x1D698, + 0x1D699, + 0x1D69A, + 0x1D69B, + 0x1D69C, + 0x1D69D, + 0x1D69E, + 0x1D69F, + 0x1D6A0, + 0x1D6A1, + 0x1D6A2, + 0x1D6A3, + 0x1D6A4, + 0x1D6A5, + 0x1D6A6, + 0x1D6A7, + 0x1D6A8, + 0x1D6A9, + 0x1D6AA, + 0x1D6AB, + 0x1D6AC, + 0x1D6AD, + 0x1D6AE, + 0x1D6AF, + 0x1D6B0, + 0x1D6B1, + 0x1D6B2, + 0x1D6B3, + 0x1D6B4, + 0x1D6B5, + 0x1D6B6, + 0x1D6B7, + 0x1D6B8, + 0x1D6B9, + 0x1D6BA, + 0x1D6BB, + 0x1D6BC, + 0x1D6BD, + 0x1D6BE, + 0x1D6BF, + 0x1D6C0, + 0x1D6C1, + 0x1D6C2, + 0x1D6C3, + 0x1D6C4, + 0x1D6C5, + 0x1D6C6, + 0x1D6C7, + 0x1D6C8, + 0x1D6C9, + 0x1D6CA, + 0x1D6CB, + 0x1D6CC, + 0x1D6CD, + 0x1D6CE, + 0x1D6CF, + 0x1D6D0, + 0x1D6D1, + 0x1D6D2, + 0x1D6D3, + 0x1D6D5, + 0x1D6D6, + 0x1D6D7, + 0x1D6D8, + 0x1D6D9, + 0x1D6DA, + 0x1D6DB, + 0x1D6DC, + 0x1D6DD, + 0x1D6DE, + 0x1D6DF, + 0x1D6E0, + 0x1D6E1, + 0x1D6E2, + 0x1D6E3, + 0x1D6E4, + 0x1D6E5, + 0x1D6E6, + 0x1D6E7, + 0x1D6E8, + 0x1D6E9, + 0x1D6EA, + 0x1D6EB, + 0x1D6EC, + 0x1D6ED, + 0x1D6EE, + 0x1D6EF, + 0x1D6F0, + 0x1D6F1, + 0x1D6F2, + 0x1D6F3, + 0x1D6F4, + 0x1D6F5, + 0x1D6F6, + 0x1D6F7, + 0x1D6F8, + 0x1D6F9, + 0x1D6FA, + 0x1D6FB, + 0x1D6FC, + 0x1D6FD, + 0x1D6FE, + 0x1D6FF, + 0x1D700, + 0x1D701, + 0x1D702, + 0x1D703, + 0x1D704, + 0x1D705, + 0x1D706, + 0x1D707, + 0x1D708, + 0x1D709, + 0x1D70A, + 0x1D70B, + 0x1D70C, + 0x1D70D, + 0x1D70F, + 0x1D710, + 0x1D711, + 0x1D712, + 0x1D713, + 0x1D714, + 0x1D715, + 0x1D716, + 0x1D717, + 0x1D718, + 0x1D719, + 0x1D71A, + 0x1D71B, + 0x1D71C, + 0x1D71D, + 0x1D71E, + 0x1D71F, + 0x1D720, + 0x1D721, + 0x1D722, + 0x1D723, + 0x1D724, + 0x1D725, + 0x1D726, + 0x1D727, + 0x1D728, + 0x1D729, + 0x1D72A, + 0x1D72B, + 0x1D72C, + 0x1D72D, + 0x1D72E, + 0x1D72F, + 0x1D730, + 0x1D731, + 0x1D732, + 0x1D733, + 0x1D734, + 0x1D735, + 0x1D736, + 0x1D737, + 0x1D738, + 0x1D739, + 0x1D73A, + 0x1D73B, + 0x1D73C, + 0x1D73D, + 0x1D73E, + 0x1D73F, + 0x1D740, + 0x1D741, + 0x1D742, + 0x1D743, + 0x1D744, + 0x1D745, + 0x1D746, + 0x1D747, + 0x1D749, + 0x1D74A, + 0x1D74B, + 0x1D74C, + 0x1D74D, + 0x1D74E, + 0x1D74F, + 0x1D750, + 0x1D751, + 0x1D752, + 0x1D753, + 0x1D754, + 0x1D755, + 0x1D756, + 0x1D757, + 0x1D758, + 0x1D759, + 0x1D75A, + 0x1D75B, + 0x1D75C, + 0x1D75D, + 0x1D75E, + 0x1D75F, + 0x1D760, + 0x1D761, + 0x1D762, + 0x1D763, + 0x1D764, + 0x1D765, + 0x1D766, + 0x1D767, + 0x1D768, + 0x1D769, + 0x1D76A, + 0x1D76B, + 0x1D76C, + 0x1D76D, + 0x1D76E, + 0x1D76F, + 0x1D770, + 0x1D771, + 0x1D772, + 0x1D773, + 0x1D774, + 0x1D775, + 0x1D776, + 0x1D777, + 0x1D778, + 0x1D779, + 0x1D77A, + 0x1D77B, + 0x1D77C, + 0x1D77D, + 0x1D77E, + 0x1D77F, + 0x1D780, + 0x1D781, + 0x1D783, + 0x1D784, + 0x1D785, + 0x1D786, + 0x1D787, + 0x1D788, + 0x1D789, + 0x1D78A, + 0x1D78B, + 0x1D78C, + 0x1D78D, + 0x1D78E, + 0x1D78F, + 0x1D790, + 0x1D791, + 0x1D792, + 0x1D793, + 0x1D794, + 0x1D795, + 0x1D796, + 0x1D797, + 0x1D798, + 0x1D799, + 0x1D79A, + 0x1D79B, + 0x1D79C, + 0x1D79D, + 0x1D79E, + 0x1D79F, + 0x1D7A0, + 0x1D7A1, + 0x1D7A2, + 0x1D7A3, + 0x1D7A4, + 0x1D7A5, + 0x1D7A6, + 0x1D7A7, + 0x1D7A8, + 0x1D7A9, + 0x1D7AA, + 0x1D7AB, + 0x1D7AC, + 0x1D7AD, + 0x1D7AE, + 0x1D7AF, + 0x1D7B0, + 0x1D7B1, + 0x1D7B2, + 0x1D7B3, + 0x1D7B4, + 0x1D7B5, + 0x1D7B6, + 0x1D7B7, + 0x1D7B8, + 0x1D7B9, + 0x1D7BA, + 0x1D7BB, + 0x1D7BD, + 0x1D7BE, + 0x1D7BF, + 0x1D7C0, + 0x1D7C1, + 0x1D7C2, + 0x1D7C3, + 0x1D7C4, + 0x1D7C5, + 0x1D7C6, + 0x1D7C7, + 0x1D7C8, + 0x1D7C9, + 0x1D7CA, + 0x1D7CC, + 0x1D7CE, + 0x1D7CF, + 0x1D7D0, + 0x1D7D1, + 0x1D7D2, + 0x1D7D3, + 0x1D7D4, + 0x1D7D5, + 0x1D7D6, + 0x1D7D7, + 0x1D7D8, + 0x1D7D9, + 0x1D7DA, + 0x1D7DB, + 0x1D7DC, + 0x1D7DD, + 0x1D7DE, + 0x1D7DF, + 0x1D7E0, + 0x1D7E1, + 0x1D7E2, + 0x1D7E3, + 0x1D7E4, + 0x1D7E5, + 0x1D7E6, + 0x1D7E7, + 0x1D7E8, + 0x1D7E9, + 0x1D7EA, + 0x1D7EB, + 0x1D7EC, + 0x1D7ED, + 0x1D7EE, + 0x1D7EF, + 0x1D7F0, + 0x1D7F1, + 0x1D7F2, + 0x1D7F3, + 0x1D7F4, + 0x1D7F5, + 0x1D7F6, + 0x1D7F7, + 0x1D7F8, + 0x1D7F9, + 0x1D7FA, + 0x1D7FB, + 0x1D7FC, + 0x1D7FD, + 0x1D7FE, + 0x1D7FF, + 0x1D800, + 0x1DA8C, + 0x1DA9B, + 0x1DAA0, + 0x1DAA1, + 0x1DAB0, + 0x1DB00, + 0x1DB1D, + 0x1DF00, + 0x1DF40, + 0x1DF41, + 0x1DF48, + 0x1DF49, + 0x1DF4A, + 0x1DF4B, + 0x1DF4D, + 0x1DF4E, + 0x1DF51, + 0x1DF52, + 0x1DF68, + 0x1DF69, + 0x1DF6A, + 0x1DF6B, + 0x1DF6C, + 0x1DF6D, + 0x1DF6E, + 0x1DF6F, + 0x1DF72, + 0x1DF73, + 0x1DF74, + 0x1DF75, + 0x1DF76, + 0x1DF77, + 0x1DF78, + 0x1DF79, + 0x1DF7A, + 0x1DF7B, + 0x1DF7C, + 0x1DF7D, + 0x1DF7E, + 0x1DF7F, + 0x1DF82, + 0x1DF90, + 0x1DF95, + 0x1DF96, + 0x1DF97, + 0x1DFCD, + 0x1DFCE, + 0x1DFCF, + 0x1DFD0, + 0x1DFD1, + 0x1DFD2, + 0x1DFD3, + 0x1DFD4, + 0x1DFD5, + 0x1DFD6, + 0x1DFD7, + 0x1DFD8, + 0x1DFD9, + 0x1DFDA, + 0x1DFDB, + 0x1DFDC, + 0x1DFDD, + 0x1DFDE, + 0x1DFDF, + 0x1DFE0, + 0x1DFE1, + 0x1DFE2, + 0x1DFE3, + 0x1DFE4, + 0x1DFE5, + 0x1DFE6, + 0x1DFE7, + 0x1DFE8, + 0x1DFE9, + 0x1DFEA, + 0x1DFEB, + 0x1DFEC, + 0x1DFED, + 0x1DFEE, + 0x1DFEF, + 0x1DFF0, + 0x1DFF1, + 0x1DFF2, + 0x1DFF3, + 0x1DFF4, + 0x1DFF5, + 0x1DFF6, + 0x1DFF7, + 0x1DFF8, + 0x1DFF9, + 0x1DFFA, + 0x1DFFB, + 0x1DFFC, + 0x1DFFD, + 0x1DFFE, + 0x1DFFF, + 0x1E000, + 0x1E007, + 0x1E008, + 0x1E019, + 0x1E01B, + 0x1E022, + 0x1E023, + 0x1E025, + 0x1E026, + 0x1E02B, + 0x1E030, + 0x1E031, + 0x1E032, + 0x1E033, + 0x1E034, + 0x1E035, + 0x1E036, + 0x1E037, + 0x1E038, + 0x1E039, + 0x1E03A, + 0x1E03B, + 0x1E03C, + 0x1E03D, + 0x1E03E, + 0x1E03F, + 0x1E040, + 0x1E041, + 0x1E042, + 0x1E043, + 0x1E044, + 0x1E045, + 0x1E046, + 0x1E047, + 0x1E048, + 0x1E049, + 0x1E04A, + 0x1E04B, + 0x1E04C, + 0x1E04D, + 0x1E04E, + 0x1E04F, + 0x1E050, + 0x1E051, + 0x1E052, + 0x1E053, + 0x1E054, + 0x1E055, + 0x1E056, + 0x1E057, + 0x1E058, + 0x1E059, + 0x1E05A, + 0x1E05B, + 0x1E05C, + 0x1E05D, + 0x1E05E, + 0x1E05F, + 0x1E060, + 0x1E061, + 0x1E062, + 0x1E063, + 0x1E064, + 0x1E065, + 0x1E066, + 0x1E067, + 0x1E068, + 0x1E069, + 0x1E06A, + 0x1E06B, + 0x1E06C, + 0x1E06D, + 0x1E06E, + 0x1E08F, + 0x1E090, + 0x1E100, + 0x1E12D, + 0x1E130, + 0x1E13E, + 0x1E140, + 0x1E14A, + 0x1E14E, + 0x1E150, + 0x1E290, + 0x1E2AF, + 0x1E2C0, + 0x1E2FA, + 0x1E2FF, + 0x1E300, + 0x1E4D0, + 0x1E4FA, + 0x1E5D0, + 0x1E5FB, + 0x1E5FF, + 0x1E600, + 0x1E6C0, + 0x1E6DF, + 0x1E6E0, + 0x1E6F6, + 0x1E6FE, + 0x1E700, + 0x1E7E0, + 0x1E7E7, + 0x1E7E8, + 0x1E7EC, + 0x1E7ED, + 0x1E7EF, + 0x1E7F0, + 0x1E7FF, + 0x1E800, + 0x1E8C5, + 0x1E8C7, + 0x1E8D7, + 0x1E900, + 0x1E901, + 0x1E902, + 0x1E903, + 0x1E904, + 0x1E905, + 0x1E906, + 0x1E907, + 0x1E908, + 0x1E909, + 0x1E90A, + 0x1E90B, + 0x1E90C, + 0x1E90D, + 0x1E90E, + 0x1E90F, + 0x1E910, + 0x1E911, + 0x1E912, + 0x1E913, + 0x1E914, + 0x1E915, + 0x1E916, + 0x1E917, + 0x1E918, + 0x1E919, + 0x1E91A, + 0x1E91B, + 0x1E91C, + 0x1E91D, + 0x1E91E, + 0x1E91F, + 0x1E920, + 0x1E921, + 0x1E922, + 0x1E94C, + 0x1E950, + 0x1E95A, + 0x1E95E, + 0x1E960, + 0x1EC71, + 0x1ECB5, + 0x1ED01, + 0x1ED3E, + 0x1EE00, + 0x1EE01, + 0x1EE02, + 0x1EE03, + 0x1EE04, + 0x1EE05, + 0x1EE06, + 0x1EE07, + 0x1EE08, + 0x1EE09, + 0x1EE0A, + 0x1EE0B, + 0x1EE0C, + 0x1EE0D, + 0x1EE0E, + 0x1EE0F, + 0x1EE10, + 0x1EE11, + 0x1EE12, + 0x1EE13, + 0x1EE14, + 0x1EE15, + 0x1EE16, + 0x1EE17, + 0x1EE18, + 0x1EE19, + 0x1EE1A, + 0x1EE1B, + 0x1EE1C, + 0x1EE1D, + 0x1EE1E, + 0x1EE1F, + 0x1EE20, + 0x1EE21, + 0x1EE22, + 0x1EE23, + 0x1EE24, + 0x1EE25, + 0x1EE27, + 0x1EE28, + 0x1EE29, + 0x1EE2A, + 0x1EE2B, + 0x1EE2C, + 0x1EE2D, + 0x1EE2E, + 0x1EE2F, + 0x1EE30, + 0x1EE31, + 0x1EE32, + 0x1EE33, + 0x1EE34, + 0x1EE35, + 0x1EE36, + 0x1EE37, + 0x1EE38, + 0x1EE39, + 0x1EE3A, + 0x1EE3B, + 0x1EE3C, + 0x1EE42, + 0x1EE43, + 0x1EE47, + 0x1EE48, + 0x1EE49, + 0x1EE4A, + 0x1EE4B, + 0x1EE4C, + 0x1EE4D, + 0x1EE4E, + 0x1EE4F, + 0x1EE50, + 0x1EE51, + 0x1EE52, + 0x1EE53, + 0x1EE54, + 0x1EE55, + 0x1EE57, + 0x1EE58, + 0x1EE59, + 0x1EE5A, + 0x1EE5B, + 0x1EE5C, + 0x1EE5D, + 0x1EE5E, + 0x1EE5F, + 0x1EE60, + 0x1EE61, + 0x1EE62, + 0x1EE63, + 0x1EE64, + 0x1EE65, + 0x1EE67, + 0x1EE68, + 0x1EE69, + 0x1EE6A, + 0x1EE6B, + 0x1EE6C, + 0x1EE6D, + 0x1EE6E, + 0x1EE6F, + 0x1EE70, + 0x1EE71, + 0x1EE72, + 0x1EE73, + 0x1EE74, + 0x1EE75, + 0x1EE76, + 0x1EE77, + 0x1EE78, + 0x1EE79, + 0x1EE7A, + 0x1EE7B, + 0x1EE7C, + 0x1EE7D, + 0x1EE7E, + 0x1EE7F, + 0x1EE80, + 0x1EE81, + 0x1EE82, + 0x1EE83, + 0x1EE84, + 0x1EE85, + 0x1EE86, + 0x1EE87, + 0x1EE88, + 0x1EE89, + 0x1EE8A, + 0x1EE8B, + 0x1EE8C, + 0x1EE8D, + 0x1EE8E, + 0x1EE8F, + 0x1EE90, + 0x1EE91, + 0x1EE92, + 0x1EE93, + 0x1EE94, + 0x1EE95, + 0x1EE96, + 0x1EE97, + 0x1EE98, + 0x1EE99, + 0x1EE9A, + 0x1EE9B, + 0x1EE9C, + 0x1EEA1, + 0x1EEA2, + 0x1EEA3, + 0x1EEA4, + 0x1EEA5, + 0x1EEA6, + 0x1EEA7, + 0x1EEA8, + 0x1EEA9, + 0x1EEAA, + 0x1EEAB, + 0x1EEAC, + 0x1EEAD, + 0x1EEAE, + 0x1EEAF, + 0x1EEB0, + 0x1EEB1, + 0x1EEB2, + 0x1EEB3, + 0x1EEB4, + 0x1EEB5, + 0x1EEB6, + 0x1EEB7, + 0x1EEB8, + 0x1EEB9, + 0x1EEBA, + 0x1EEBB, + 0x1EEBC, + 0x1EEF0, + 0x1EEF2, + 0x1F000, + 0x1F02C, + 0x1F030, + 0x1F094, + 0x1F0A0, + 0x1F0AF, + 0x1F0B1, + 0x1F0C0, + 0x1F0C1, + 0x1F0D0, + 0x1F0D1, + 0x1F0F6, + 0x1F101, + 0x1F102, + 0x1F103, + 0x1F104, + 0x1F105, + 0x1F106, + 0x1F107, + 0x1F108, + 0x1F109, + 0x1F10A, + 0x1F10B, + 0x1F110, + 0x1F111, + 0x1F112, + 0x1F113, + 0x1F114, + 0x1F115, + 0x1F116, + 0x1F117, + 0x1F118, + 0x1F119, + 0x1F11A, + 0x1F11B, + 0x1F11C, + 0x1F11D, + 0x1F11E, + 0x1F11F, + 0x1F120, + 0x1F121, + 0x1F122, + 0x1F123, + 0x1F124, + 0x1F125, + 0x1F126, + 0x1F127, + 0x1F128, + 0x1F129, + 0x1F12A, + 0x1F12B, + 0x1F12C, + 0x1F12D, + 0x1F12E, + 0x1F12F, + 0x1F130, + 0x1F131, + 0x1F132, + 0x1F133, + 0x1F134, + 0x1F135, + 0x1F136, + 0x1F137, + 0x1F138, + 0x1F139, + 0x1F13A, + 0x1F13B, + 0x1F13C, + 0x1F13D, + 0x1F13E, + 0x1F13F, + 0x1F140, + 0x1F141, + 0x1F142, + 0x1F143, + 0x1F144, + 0x1F145, + 0x1F146, + 0x1F147, + 0x1F148, + 0x1F149, + 0x1F14A, + 0x1F14B, + 0x1F14C, + 0x1F14D, + 0x1F14E, + 0x1F14F, + 0x1F150, + 0x1F16A, + 0x1F16B, + 0x1F16C, + 0x1F16D, + 0x1F190, + 0x1F191, + 0x1F1AF, + 0x1F1E6, + 0x1F200, + 0x1F201, + 0x1F202, + 0x1F203, + 0x1F210, + 0x1F211, + 0x1F212, + 0x1F213, + 0x1F214, + 0x1F215, + 0x1F216, + 0x1F217, + 0x1F218, + 0x1F219, + 0x1F21A, + 0x1F21B, + 0x1F21C, + 0x1F21D, + 0x1F21E, + 0x1F21F, + 0x1F220, + 0x1F221, + 0x1F222, + 0x1F223, + 0x1F224, + 0x1F225, + 0x1F226, + 0x1F227, + 0x1F228, + 0x1F229, + 0x1F22A, + 0x1F22B, + 0x1F22C, + 0x1F22D, + 0x1F22E, + 0x1F22F, + 0x1F230, + 0x1F231, + 0x1F232, + 0x1F233, + 0x1F234, + 0x1F235, + 0x1F236, + 0x1F237, + 0x1F238, + 0x1F239, + 0x1F23A, + 0x1F23B, + 0x1F23C, + 0x1F240, + 0x1F241, + 0x1F242, + 0x1F243, + 0x1F244, + 0x1F245, + 0x1F246, + 0x1F247, + 0x1F248, + 0x1F249, + 0x1F250, + 0x1F251, + 0x1F252, + 0x1F260, + 0x1F266, + 0x1F300, + 0x1F6DA, + 0x1F6DC, + 0x1F6ED, + 0x1F6F0, + 0x1F6FD, + 0x1F700, + 0x1F7DC, + 0x1F7E0, + 0x1F7EC, + 0x1F7F0, + 0x1F80C, + 0x1F810, + 0x1F848, + 0x1F850, + 0x1F85A, + 0x1F860, + 0x1F888, + 0x1F890, + 0x1F8AE, + 0x1F8B0, + 0x1F8BC, + 0x1F8C0, + 0x1F8C2, + 0x1F8D0, + 0x1F8D9, + 0x1F900, + 0x1FA58, + 0x1FA60, + 0x1FA6E, + 0x1FA70, + 0x1FA7D, + 0x1FA80, + 0x1FAC7, + 0x1FAC8, + 0x1FAC9, + 0x1FACC, + 0x1FADE, + 0x1FADF, + 0x1FAEC, + 0x1FAEF, + 0x1FAFB, + 0x1FB00, + 0x1FB93, + 0x1FB94, + 0x1FBF0, + 0x1FBF1, + 0x1FBF2, + 0x1FBF3, + 0x1FBF4, + 0x1FBF5, + 0x1FBF6, + 0x1FBF7, + 0x1FBF8, + 0x1FBF9, + 0x1FBFA, + 0x1FBFB, + 0x20000, + 0x2A6E0, + 0x2A700, + 0x2B81F, + 0x2B820, + 0x2CEAE, + 0x2CEB0, + 0x2EBE1, + 0x2EBF0, + 0x2EE5E, + 0x2F800, + 0x2F801, + 0x2F802, + 0x2F803, + 0x2F804, + 0x2F805, + 0x2F806, + 0x2F807, + 0x2F808, + 0x2F809, + 0x2F80A, + 0x2F80B, + 0x2F80C, + 0x2F80D, + 0x2F80E, + 0x2F80F, + 0x2F810, + 0x2F811, + 0x2F812, + 0x2F813, + 0x2F814, + 0x2F815, + 0x2F816, + 0x2F817, + 0x2F818, + 0x2F819, + 0x2F81A, + 0x2F81B, + 0x2F81C, + 0x2F81D, + 0x2F81E, + 0x2F81F, + 0x2F820, + 0x2F821, + 0x2F822, + 0x2F823, + 0x2F824, + 0x2F825, + 0x2F826, + 0x2F827, + 0x2F828, + 0x2F829, + 0x2F82A, + 0x2F82B, + 0x2F82C, + 0x2F82D, + 0x2F82E, + 0x2F82F, + 0x2F830, + 0x2F831, + 0x2F834, + 0x2F835, + 0x2F836, + 0x2F837, + 0x2F838, + 0x2F839, + 0x2F83A, + 0x2F83B, + 0x2F83C, + 0x2F83D, + 0x2F83E, + 0x2F83F, + 0x2F840, + 0x2F841, + 0x2F842, + 0x2F843, + 0x2F844, + 0x2F845, + 0x2F847, + 0x2F848, + 0x2F849, + 0x2F84A, + 0x2F84B, + 0x2F84C, + 0x2F84D, + 0x2F84E, + 0x2F84F, + 0x2F850, + 0x2F851, + 0x2F852, + 0x2F853, + 0x2F854, + 0x2F855, + 0x2F856, + 0x2F857, + 0x2F858, + 0x2F859, + 0x2F85A, + 0x2F85B, + 0x2F85C, + 0x2F85D, + 0x2F85E, + 0x2F85F, + 0x2F860, + 0x2F861, + 0x2F862, + 0x2F863, + 0x2F864, + 0x2F865, + 0x2F866, + 0x2F867, + 0x2F868, + 0x2F869, + 0x2F86A, + 0x2F86C, + 0x2F86D, + 0x2F86E, + 0x2F86F, + 0x2F870, + 0x2F871, + 0x2F872, + 0x2F873, + 0x2F874, + 0x2F875, + 0x2F876, + 0x2F877, + 0x2F878, + 0x2F879, + 0x2F87A, + 0x2F87B, + 0x2F87C, + 0x2F87D, + 0x2F87E, + 0x2F87F, + 0x2F880, + 0x2F881, + 0x2F882, + 0x2F883, + 0x2F884, + 0x2F885, + 0x2F886, + 0x2F887, + 0x2F888, + 0x2F889, + 0x2F88A, + 0x2F88B, + 0x2F88C, + 0x2F88D, + 0x2F88E, + 0x2F88F, + 0x2F890, + 0x2F891, + 0x2F893, + 0x2F894, + 0x2F896, + 0x2F897, + 0x2F898, + 0x2F899, + 0x2F89A, + 0x2F89B, + 0x2F89C, + 0x2F89D, + 0x2F89E, + 0x2F89F, + 0x2F8A0, + 0x2F8A1, + 0x2F8A2, + 0x2F8A3, + 0x2F8A4, + 0x2F8A5, + 0x2F8A6, + 0x2F8A7, + 0x2F8A8, + 0x2F8A9, + 0x2F8AA, + 0x2F8AB, + 0x2F8AC, + 0x2F8AD, + 0x2F8AE, + 0x2F8AF, + 0x2F8B0, + 0x2F8B1, + 0x2F8B2, + 0x2F8B3, + 0x2F8B4, + 0x2F8B5, + 0x2F8B6, + 0x2F8B7, + 0x2F8B8, + 0x2F8B9, + 0x2F8BA, + 0x2F8BB, + 0x2F8BC, + 0x2F8BD, + 0x2F8BE, + 0x2F8BF, + 0x2F8C0, + 0x2F8C1, + 0x2F8C2, + 0x2F8C3, + 0x2F8C4, + 0x2F8C5, + 0x2F8C6, + 0x2F8C7, + 0x2F8C8, + 0x2F8C9, + 0x2F8CA, + 0x2F8CB, + 0x2F8CC, + 0x2F8CD, + 0x2F8CE, + 0x2F8CF, + 0x2F8D0, + 0x2F8D1, + 0x2F8D2, + 0x2F8D3, + 0x2F8D4, + 0x2F8D5, + 0x2F8D6, + 0x2F8D7, + 0x2F8D8, + 0x2F8D9, + 0x2F8DA, + 0x2F8DB, + 0x2F8DC, + 0x2F8DD, + 0x2F8DE, + 0x2F8DF, + 0x2F8E0, + 0x2F8E1, + 0x2F8E2, + 0x2F8E3, + 0x2F8E4, + 0x2F8E5, + 0x2F8E6, + 0x2F8E7, + 0x2F8E8, + 0x2F8E9, + 0x2F8EA, + 0x2F8EB, + 0x2F8EC, + 0x2F8ED, + 0x2F8EE, + 0x2F8EF, + 0x2F8F0, + 0x2F8F1, + 0x2F8F2, + 0x2F8F3, + 0x2F8F4, + 0x2F8F5, + 0x2F8F6, + 0x2F8F7, + 0x2F8F8, + 0x2F8F9, + 0x2F8FA, + 0x2F8FB, + 0x2F8FC, + 0x2F8FD, + 0x2F8FE, + 0x2F8FF, + 0x2F900, + 0x2F901, + 0x2F902, + 0x2F903, + 0x2F904, + 0x2F905, + 0x2F906, + 0x2F907, + 0x2F908, + 0x2F909, + 0x2F90A, + 0x2F90B, + 0x2F90C, + 0x2F90D, + 0x2F90E, + 0x2F90F, + 0x2F910, + 0x2F911, + 0x2F912, + 0x2F913, + 0x2F914, + 0x2F915, + 0x2F916, + 0x2F917, + 0x2F918, + 0x2F919, + 0x2F91A, + 0x2F91B, + 0x2F91C, + 0x2F91D, + 0x2F91E, + 0x2F91F, + 0x2F920, + 0x2F921, + 0x2F922, + 0x2F923, + 0x2F924, + 0x2F925, + 0x2F926, + 0x2F927, + 0x2F928, + 0x2F929, + 0x2F92A, + 0x2F92B, + 0x2F92C, + 0x2F92E, + 0x2F92F, + 0x2F930, + 0x2F931, + 0x2F932, + 0x2F933, + 0x2F934, + 0x2F935, + 0x2F936, + 0x2F937, + 0x2F938, + 0x2F939, + 0x2F93A, + 0x2F93B, + 0x2F93C, + 0x2F93D, + 0x2F93E, + 0x2F93F, + 0x2F940, + 0x2F941, + 0x2F942, + 0x2F943, + 0x2F944, + 0x2F945, + 0x2F946, + 0x2F948, + 0x2F949, + 0x2F94A, + 0x2F94B, + 0x2F94C, + 0x2F94D, + 0x2F94E, + 0x2F94F, + 0x2F950, + 0x2F951, + 0x2F952, + 0x2F953, + 0x2F954, + 0x2F955, + 0x2F956, + 0x2F957, + 0x2F958, + 0x2F959, + 0x2F95A, + 0x2F95B, + 0x2F95C, + 0x2F95D, + 0x2F95F, + 0x2F960, + 0x2F961, + 0x2F962, + 0x2F963, + 0x2F964, + 0x2F965, + 0x2F966, + 0x2F967, + 0x2F968, + 0x2F969, + 0x2F96A, + 0x2F96B, + 0x2F96C, + 0x2F96D, + 0x2F96E, + 0x2F96F, + 0x2F970, + 0x2F971, + 0x2F972, + 0x2F973, + 0x2F974, + 0x2F975, + 0x2F976, + 0x2F977, + 0x2F978, + 0x2F979, + 0x2F97A, + 0x2F97B, + 0x2F97C, + 0x2F97D, + 0x2F97E, + 0x2F97F, + 0x2F980, + 0x2F981, + 0x2F982, + 0x2F983, + 0x2F984, + 0x2F985, + 0x2F986, + 0x2F987, + 0x2F988, + 0x2F989, + 0x2F98A, + 0x2F98B, + 0x2F98C, + 0x2F98D, + 0x2F98E, + 0x2F98F, + 0x2F990, + 0x2F991, + 0x2F992, + 0x2F993, + 0x2F994, + 0x2F995, + 0x2F996, + 0x2F997, + 0x2F998, + 0x2F999, + 0x2F99A, + 0x2F99B, + 0x2F99C, + 0x2F99D, + 0x2F99E, + 0x2F99F, + 0x2F9A0, + 0x2F9A1, + 0x2F9A2, + 0x2F9A3, + 0x2F9A4, + 0x2F9A5, + 0x2F9A6, + 0x2F9A7, + 0x2F9A8, + 0x2F9A9, + 0x2F9AA, + 0x2F9AB, + 0x2F9AC, + 0x2F9AD, + 0x2F9AE, + 0x2F9AF, + 0x2F9B0, + 0x2F9B1, + 0x2F9B2, + 0x2F9B3, + 0x2F9B4, + 0x2F9B5, + 0x2F9B6, + 0x2F9B7, + 0x2F9B8, + 0x2F9B9, + 0x2F9BA, + 0x2F9BB, + 0x2F9BC, + 0x2F9BD, + 0x2F9BE, + 0x2F9BF, + 0x2F9C0, + 0x2F9C1, + 0x2F9C2, + 0x2F9C3, + 0x2F9C4, + 0x2F9C5, + 0x2F9C6, + 0x2F9C7, + 0x2F9C8, + 0x2F9C9, + 0x2F9CA, + 0x2F9CB, + 0x2F9CC, + 0x2F9CD, + 0x2F9CE, + 0x2F9CF, + 0x2F9D0, + 0x2F9D1, + 0x2F9D2, + 0x2F9D3, + 0x2F9D4, + 0x2F9D5, + 0x2F9D6, + 0x2F9D7, + 0x2F9D8, + 0x2F9D9, + 0x2F9DA, + 0x2F9DB, + 0x2F9DC, + 0x2F9DD, + 0x2F9DE, + 0x2F9DF, + 0x2F9E0, + 0x2F9E1, + 0x2F9E2, + 0x2F9E3, + 0x2F9E4, + 0x2F9E5, + 0x2F9E6, + 0x2F9E7, + 0x2F9E8, + 0x2F9E9, + 0x2F9EA, + 0x2F9EB, + 0x2F9EC, + 0x2F9ED, + 0x2F9EE, + 0x2F9EF, + 0x2F9F0, + 0x2F9F1, + 0x2F9F2, + 0x2F9F3, + 0x2F9F4, + 0x2F9F5, + 0x2F9F6, + 0x2F9F7, + 0x2F9F8, + 0x2F9F9, + 0x2F9FA, + 0x2F9FB, + 0x2F9FC, + 0x2F9FD, + 0x2F9FE, + 0x2FA00, + 0x2FA01, + 0x2FA02, + 0x2FA03, + 0x2FA04, + 0x2FA05, + 0x2FA06, + 0x2FA07, + 0x2FA08, + 0x2FA09, + 0x2FA0A, + 0x2FA0B, + 0x2FA0C, + 0x2FA0D, + 0x2FA0E, + 0x2FA0F, + 0x2FA10, + 0x2FA11, + 0x2FA12, + 0x2FA13, + 0x2FA14, + 0x2FA15, + 0x2FA16, + 0x2FA17, + 0x2FA18, + 0x2FA19, + 0x2FA1A, + 0x2FA1B, + 0x2FA1C, + 0x2FA1D, + 0x2FA1E, + 0x30000, + 0x3134B, + 0x31350, + 0x3347A, + 0x3D000, + 0x3FC40, + 0xE0100, + 0xE01F0, + ), +) + +uts46_statuses: bytes = ( + b"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" + b"VMMMMMMMMMMMMMMMMMMMMMMMMMMVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" + b"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMVVVVVVVMVMVVIVMVVMMMMVVMMMVMMMV" + b"MMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMDVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMVMMV" + b"MVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMM" + b"VMVMMVMMMVMMMMVMMVMMMVMMVMMVMVMVMMVMVMVMMVMMMVMVMMVMVMMMMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMVMVMMMMVMVMVMVMVMMMMMMMMMVMMMMMM" + b"VMMMMMVMMVMMMVIVMVMVMVMVXMVMMXMMMMMMMXMXMMVMMMMMMMMMMMMMMMMMXMMM" + b"MMMMMMVDVMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMMMVMMVMVMMVMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMXMVMVMMVXVXVXVXVXVMMMMVXVXVXVXVXVXVXVXVX" + b"VXVXVXVMMMMMMMMVXVXVXVXVXVXVXVXVXVXVXMMXMVXVXVXVXVXVXVXVMXVMXVXV" + b"XVXVXVXVXMMMVXMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" + b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" + b"XVXVMVXVXVXVXVXVXVXVMVXVXVXVXVXMMVXVMVMVXVMVMVMVMVMVXVMVMMMMMVMV" + b"MVXVMVMVMVMVMVXVXVXVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMXMXV" + b"MVIVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMXVXVXVXVXVXVXVXVX" + b"VXVIVXVXVXVIVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMM" + b"MMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMVXVXVMMMV" + b"MMMMMMMMMMMVMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMMMMMMMVXMMMMMMXVMMMMMMMMVMMMMMM" + b"MMVXMMMMMMXVXMXMXMXMVMMMMMMMMVMVMVMVMVMVMVMXMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMXVMMMMMMMMMMMMMMXVMMMMMMMMMVMXVM" + b"MMMXMMMVMVMMMMMMMMXMMMXVMMMMMMMMXMIDXVMVMVXVXMVMMVMMVMVMVMMMVMVM" + b"IXIMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMVMVXVXMMMMVMMM" + b"VMMMMMMVMMVMMMVMMMVMVMVMVMMMMVMMMMMMMMMMVMMMMMVMMMMVMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVXVMMVMMVMMVXVXMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVXVMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVMVMVMMMMVMVMV" + b"MMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXVXVXVXVXMVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVMVMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMVMVMVMMMVXVXVMMVM" + b"VMXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVMMMMMMMMMMMMMMVXVMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMMMMM" + b"MMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXMVMVMVMVMVM" + b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" + b"MVXVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMM" + b"MMVMMMMMVMVMVMVMVMVMVMVMMMMVMVMMVMVMVMVMVMVMVMVMMXMXMMMMMVMMVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMMMVMVMMXMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMV" + b"XVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMVMVMVMMMMMMMMMMVMVMVMMVMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMXMMMMMXMVMMMMMMMMMMMMMMMMMMMMM" + b"MMMXMMMMMXMXMMXMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXMMMMMMMMMMMM" + b"MVIMMXMMMMMMXVXMMMMMMMMMMMMMMMMMMMVMMMMMMXMMMMMMMMMMMMMMMMMMMXMM" + b"MMXMMMVMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXIXMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMM" + b"MMMXMMMMMMXMMMMMMXMMMXMMMMMMMXMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVMMMMMMMMMMMXMMMMMMMMMM" + b"MMMMMXMMMMMMMXMMXVXVXVXVXVXVXVXVXVMMMMMXMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVX" + b"VXVXVXVXVXVXVXVXVMMMMVXVXVXVXVXVXVXVXVXVXVIXVMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVMMMMMMMVIVMMMMMMVXVXVXVXVXVX" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMXMXMMXMMMMXMMMMMMMMMMMMXMXMMMMMM" + b"MXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMXMMMMXMMMMMMMMXMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMM" + b"MXMXMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVMVMV" + b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVXVMVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" + b"XVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXMMMMXMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMXMMXMXMXMMMMMMMMMMXMMMMXMXMXMXMXMXMXMMMXMMXMXMX" + b"MXMXMXMXMMXMXMMMMXMMMMMMMXMMMMXMMMMXMXMMMMMMMMMMXMMMMMMMMMMMMMMM" + b"MMXMMMXMMMMMXMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXMMMMMMMMMMVMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMVMVX" + b"VMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMXMMXV" + b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMMMMMMMMMVXVXVXVX" + b"VXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + b"MMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXIX" +) + +uts46_replacements: tuple[str | None, ...] = ( + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + " ", + None, + None, + None, + None, + None, + None, + None, + " ̈", + None, + "a", + None, + None, + None, + None, + " ̄", + None, + None, + "2", + "3", + " ́", + "μ", + None, + None, + " ̧", + "1", + "o", + None, + "1⁄4", + "1⁄2", + "3⁄4", + None, + "à", + "á", + "â", + "ã", + "ä", + "å", + "æ", + "ç", + "è", + "é", + "ê", + "ë", + "ì", + "í", + "î", + "ï", + "ð", + "ñ", + "ò", + "ó", + "ô", + "õ", + "ö", + None, + "ø", + "ù", + "ú", + "û", + "ü", + "ý", + "þ", + "ss", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ā", + None, + "ă", + None, + "ą", + None, + "ć", + None, + "ĉ", + None, + "ċ", + None, + "č", + None, + "ď", + None, + "đ", + None, + "ē", + None, + "ĕ", + None, + "ė", + None, + "ę", + None, + "ě", + None, + "ĝ", + None, + "ğ", + None, + "ġ", + None, + "ģ", + None, + "ĥ", + None, + "ħ", + None, + "ĩ", + None, + "ī", + None, + "ĭ", + None, + "į", + None, + "i̇", + None, + "ij", + "ĵ", + None, + "ķ", + None, + "ĺ", + None, + "ļ", + None, + "ľ", + None, + "l·", + "ł", + None, + "ń", + None, + "ņ", + None, + "ň", + None, + "ʼn", + "ŋ", + None, + "ō", + None, + "ŏ", + None, + "ő", + None, + "œ", + None, + "ŕ", + None, + "ŗ", + None, + "ř", + None, + "ś", + None, + "ŝ", + None, + "ş", + None, + "š", + None, + "ţ", + None, + "ť", + None, + "ŧ", + None, + "ũ", + None, + "ū", + None, + "ŭ", + None, + "ů", + None, + "ű", + None, + "ų", + None, + "ŵ", + None, + "ŷ", + None, + "ÿ", + "ź", + None, + "ż", + None, + "ž", + None, + "s", + None, + "ɓ", + "ƃ", + None, + "ƅ", + None, + "ɔ", + "ƈ", + None, + "ɖ", + "ɗ", + "ƌ", + None, + "ǝ", + "ə", + "ɛ", + "ƒ", + None, + "ɠ", + "ɣ", + None, + "ɩ", + "ɨ", + "ƙ", + None, + "ɯ", + "ɲ", + None, + "ɵ", + "ơ", + None, + "ƣ", + None, + "ƥ", + None, + "ʀ", + "ƨ", + None, + "ʃ", + None, + "ƭ", + None, + "ʈ", + "ư", + None, + "ʊ", + "ʋ", + "ƴ", + None, + "ƶ", + None, + "ʒ", + "ƹ", + None, + "ƽ", + None, + "dž", + "lj", + "nj", + "ǎ", + None, + "ǐ", + None, + "ǒ", + None, + "ǔ", + None, + "ǖ", + None, + "ǘ", + None, + "ǚ", + None, + "ǜ", + None, + "ǟ", + None, + "ǡ", + None, + "ǣ", + None, + "ǥ", + None, + "ǧ", + None, + "ǩ", + None, + "ǫ", + None, + "ǭ", + None, + "ǯ", + None, + "dz", + "ǵ", + None, + "ƕ", + "ƿ", + "ǹ", + None, + "ǻ", + None, + "ǽ", + None, + "ǿ", + None, + "ȁ", + None, + "ȃ", + None, + "ȅ", + None, + "ȇ", + None, + "ȉ", + None, + "ȋ", + None, + "ȍ", + None, + "ȏ", + None, + "ȑ", + None, + "ȓ", + None, + "ȕ", + None, + "ȗ", + None, + "ș", + None, + "ț", + None, + "ȝ", + None, + "ȟ", + None, + "ƞ", + None, + "ȣ", + None, + "ȥ", + None, + "ȧ", + None, + "ȩ", + None, + "ȫ", + None, + "ȭ", + None, + "ȯ", + None, + "ȱ", + None, + "ȳ", + None, + "ⱥ", + "ȼ", + None, + "ƚ", + "ⱦ", + None, + "ɂ", + None, + "ƀ", + "ʉ", + "ʌ", + "ɇ", + None, + "ɉ", + None, + "ɋ", + None, + "ɍ", + None, + "ɏ", + None, + "h", + "ɦ", + "j", + "r", + "ɹ", + "ɻ", + "ʁ", + "w", + "y", + None, + " ̆", + " ̇", + " ̊", + " ̨", + " ̃", + " ̋", + None, + "ɣ", + "l", + "s", + "x", + "ʕ", + None, + "̀", + "́", + None, + "̓", + "̈́", + "ι", + None, + None, + None, + "ͱ", + None, + "ͳ", + None, + "ʹ", + None, + "ͷ", + None, + None, + " ι", + None, + ";", + "ϳ", + None, + " ́", + " ̈́", + "ά", + "·", + "έ", + "ή", + "ί", + None, + "ό", + None, + "ύ", + "ώ", + None, + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + None, + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "ϊ", + "ϋ", + None, + "σ", + None, + "ϗ", + "β", + "θ", + "υ", + "ύ", + "ϋ", + "φ", + "π", + None, + "ϙ", + None, + "ϛ", + None, + "ϝ", + None, + "ϟ", + None, + "ϡ", + None, + "ϣ", + None, + "ϥ", + None, + "ϧ", + None, + "ϩ", + None, + "ϫ", + None, + "ϭ", + None, + "ϯ", + None, + "κ", + "ρ", + "σ", + None, + "θ", + "ε", + None, + "ϸ", + None, + "σ", + "ϻ", + None, + "ͻ", + "ͼ", + "ͽ", + "ѐ", + "ё", + "ђ", + "ѓ", + "є", + "ѕ", + "і", + "ї", + "ј", + "љ", + "њ", + "ћ", + "ќ", + "ѝ", + "ў", + "џ", + "а", + "б", + "в", + "г", + "д", + "е", + "ж", + "з", + "и", + "й", + "к", + "л", + "м", + "н", + "о", + "п", + "р", + "с", + "т", + "у", + "ф", + "х", + "ц", + "ч", + "ш", + "щ", + "ъ", + "ы", + "ь", + "э", + "ю", + "я", + None, + "ѡ", + None, + "ѣ", + None, + "ѥ", + None, + "ѧ", + None, + "ѩ", + None, + "ѫ", + None, + "ѭ", + None, + "ѯ", + None, + "ѱ", + None, + "ѳ", + None, + "ѵ", + None, + "ѷ", + None, + "ѹ", + None, + "ѻ", + None, + "ѽ", + None, + "ѿ", + None, + "ҁ", + None, + "ҋ", + None, + "ҍ", + None, + "ҏ", + None, + "ґ", + None, + "ғ", + None, + "ҕ", + None, + "җ", + None, + "ҙ", + None, + "қ", + None, + "ҝ", + None, + "ҟ", + None, + "ҡ", + None, + "ң", + None, + "ҥ", + None, + "ҧ", + None, + "ҩ", + None, + "ҫ", + None, + "ҭ", + None, + "ү", + None, + "ұ", + None, + "ҳ", + None, + "ҵ", + None, + "ҷ", + None, + "ҹ", + None, + "һ", + None, + "ҽ", + None, + "ҿ", + None, + "ӏ", + "ӂ", + None, + "ӄ", + None, + "ӆ", + None, + "ӈ", + None, + "ӊ", + None, + "ӌ", + None, + "ӎ", + None, + "ӑ", + None, + "ӓ", + None, + "ӕ", + None, + "ӗ", + None, + "ә", + None, + "ӛ", + None, + "ӝ", + None, + "ӟ", + None, + "ӡ", + None, + "ӣ", + None, + "ӥ", + None, + "ӧ", + None, + "ө", + None, + "ӫ", + None, + "ӭ", + None, + "ӯ", + None, + "ӱ", + None, + "ӳ", + None, + "ӵ", + None, + "ӷ", + None, + "ӹ", + None, + "ӻ", + None, + "ӽ", + None, + "ӿ", + None, + "ԁ", + None, + "ԃ", + None, + "ԅ", + None, + "ԇ", + None, + "ԉ", + None, + "ԋ", + None, + "ԍ", + None, + "ԏ", + None, + "ԑ", + None, + "ԓ", + None, + "ԕ", + None, + "ԗ", + None, + "ԙ", + None, + "ԛ", + None, + "ԝ", + None, + "ԟ", + None, + "ԡ", + None, + "ԣ", + None, + "ԥ", + None, + "ԧ", + None, + "ԩ", + None, + "ԫ", + None, + "ԭ", + None, + "ԯ", + None, + None, + "ա", + "բ", + "գ", + "դ", + "ե", + "զ", + "է", + "ը", + "թ", + "ժ", + "ի", + "լ", + "խ", + "ծ", + "կ", + "հ", + "ձ", + "ղ", + "ճ", + "մ", + "յ", + "ն", + "շ", + "ո", + "չ", + "պ", + "ջ", + "ռ", + "ս", + "վ", + "տ", + "ր", + "ց", + "ւ", + "փ", + "ք", + "օ", + "ֆ", + None, + "է", + None, + "եւ", + None, + "ի", + "յ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "اٴ", + "وٴ", + "ۇٴ", + "يٴ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "क़", + "ख़", + "ग़", + "ज़", + "ड़", + "ढ़", + "फ़", + "य़", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ড়", + "ঢ়", + None, + "য়", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ਲ਼", + None, + None, + "ਸ਼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ਖ਼", + "ਗ਼", + "ਜ਼", + None, + None, + "ਫ਼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ଡ଼", + "ଢ଼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ํา", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ໍາ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ຫນ", + "ຫມ", + None, + None, + None, + "་", + None, + "གྷ", + None, + None, + None, + "ཌྷ", + None, + "དྷ", + None, + "བྷ", + None, + "ཛྷ", + None, + "ཀྵ", + None, + None, + None, + "ཱི", + None, + "ཱུ", + "ྲྀ", + "ྲཱྀ", + "ླྀ", + "ླཱྀ", + None, + "ཱྀ", + None, + "ྒྷ", + None, + None, + None, + "ྜྷ", + None, + "ྡྷ", + None, + "ྦྷ", + None, + "ྫྷ", + None, + "ྐྵ", + None, + None, + None, + None, + None, + None, + None, + "ⴀ", + "ⴁ", + "ⴂ", + "ⴃ", + "ⴄ", + "ⴅ", + "ⴆ", + "ⴇ", + "ⴈ", + "ⴉ", + "ⴊ", + "ⴋ", + "ⴌ", + "ⴍ", + "ⴎ", + "ⴏ", + "ⴐ", + "ⴑ", + "ⴒ", + "ⴓ", + "ⴔ", + "ⴕ", + "ⴖ", + "ⴗ", + "ⴘ", + "ⴙ", + "ⴚ", + "ⴛ", + "ⴜ", + "ⴝ", + "ⴞ", + "ⴟ", + "ⴠ", + "ⴡ", + "ⴢ", + "ⴣ", + "ⴤ", + "ⴥ", + None, + "ⴧ", + None, + "ⴭ", + None, + None, + "ნ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "Ᏸ", + "Ᏹ", + "Ᏺ", + "Ᏻ", + "Ᏼ", + "Ᏽ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "в", + "д", + "о", + "с", + "т", + "ъ", + "ѣ", + "ꙋ", + "ᲊ", + None, + None, + "ა", + "ბ", + "გ", + "დ", + "ე", + "ვ", + "ზ", + "თ", + "ი", + "კ", + "ლ", + "მ", + "ნ", + "ო", + "პ", + "ჟ", + "რ", + "ს", + "ტ", + "უ", + "ფ", + "ქ", + "ღ", + "ყ", + "შ", + "ჩ", + "ც", + "ძ", + "წ", + "ჭ", + "ხ", + "ჯ", + "ჰ", + "ჱ", + "ჲ", + "ჳ", + "ჴ", + "ჵ", + "ჶ", + "ჷ", + "ჸ", + "ჹ", + "ჺ", + None, + "ჽ", + "ჾ", + "ჿ", + None, + None, + None, + None, + None, + "a", + "æ", + "b", + None, + "d", + "e", + "ǝ", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + None, + "o", + "ȣ", + "p", + "r", + "t", + "u", + "w", + "a", + "ɐ", + "ɑ", + "ᴂ", + "b", + "d", + "e", + "ə", + "ɛ", + "ɜ", + "g", + None, + "k", + "m", + "ŋ", + "o", + "ɔ", + "ᴖ", + "ᴗ", + "p", + "t", + "u", + "ᴝ", + "ɯ", + "v", + "ᴥ", + "β", + "γ", + "δ", + "φ", + "χ", + "i", + "r", + "u", + "v", + "β", + "γ", + "ρ", + "φ", + "χ", + None, + "н", + None, + "ɒ", + "c", + "ɕ", + "ð", + "ɜ", + "f", + "ɟ", + "ɡ", + "ɥ", + "ɨ", + "ɩ", + "ɪ", + "ᵻ", + "ʝ", + "ɭ", + "ᶅ", + "ʟ", + "ɱ", + "ɰ", + "ɲ", + "ɳ", + "ɴ", + "ɵ", + "ɸ", + "ʂ", + "ʃ", + "ƫ", + "ʉ", + "ʊ", + "ᴜ", + "ʋ", + "ʌ", + "z", + "ʐ", + "ʑ", + "ʒ", + "θ", + None, + "ḁ", + None, + "ḃ", + None, + "ḅ", + None, + "ḇ", + None, + "ḉ", + None, + "ḋ", + None, + "ḍ", + None, + "ḏ", + None, + "ḑ", + None, + "ḓ", + None, + "ḕ", + None, + "ḗ", + None, + "ḙ", + None, + "ḛ", + None, + "ḝ", + None, + "ḟ", + None, + "ḡ", + None, + "ḣ", + None, + "ḥ", + None, + "ḧ", + None, + "ḩ", + None, + "ḫ", + None, + "ḭ", + None, + "ḯ", + None, + "ḱ", + None, + "ḳ", + None, + "ḵ", + None, + "ḷ", + None, + "ḹ", + None, + "ḻ", + None, + "ḽ", + None, + "ḿ", + None, + "ṁ", + None, + "ṃ", + None, + "ṅ", + None, + "ṇ", + None, + "ṉ", + None, + "ṋ", + None, + "ṍ", + None, + "ṏ", + None, + "ṑ", + None, + "ṓ", + None, + "ṕ", + None, + "ṗ", + None, + "ṙ", + None, + "ṛ", + None, + "ṝ", + None, + "ṟ", + None, + "ṡ", + None, + "ṣ", + None, + "ṥ", + None, + "ṧ", + None, + "ṩ", + None, + "ṫ", + None, + "ṭ", + None, + "ṯ", + None, + "ṱ", + None, + "ṳ", + None, + "ṵ", + None, + "ṷ", + None, + "ṹ", + None, + "ṻ", + None, + "ṽ", + None, + "ṿ", + None, + "ẁ", + None, + "ẃ", + None, + "ẅ", + None, + "ẇ", + None, + "ẉ", + None, + "ẋ", + None, + "ẍ", + None, + "ẏ", + None, + "ẑ", + None, + "ẓ", + None, + "ẕ", + None, + "aʾ", + "ṡ", + None, + "ß", + None, + "ạ", + None, + "ả", + None, + "ấ", + None, + "ầ", + None, + "ẩ", + None, + "ẫ", + None, + "ậ", + None, + "ắ", + None, + "ằ", + None, + "ẳ", + None, + "ẵ", + None, + "ặ", + None, + "ẹ", + None, + "ẻ", + None, + "ẽ", + None, + "ế", + None, + "ề", + None, + "ể", + None, + "ễ", + None, + "ệ", + None, + "ỉ", + None, + "ị", + None, + "ọ", + None, + "ỏ", + None, + "ố", + None, + "ồ", + None, + "ổ", + None, + "ỗ", + None, + "ộ", + None, + "ớ", + None, + "ờ", + None, + "ở", + None, + "ỡ", + None, + "ợ", + None, + "ụ", + None, + "ủ", + None, + "ứ", + None, + "ừ", + None, + "ử", + None, + "ữ", + None, + "ự", + None, + "ỳ", + None, + "ỵ", + None, + "ỷ", + None, + "ỹ", + None, + "ỻ", + None, + "ỽ", + None, + "ỿ", + None, + "ἀ", + "ἁ", + "ἂ", + "ἃ", + "ἄ", + "ἅ", + "ἆ", + "ἇ", + None, + None, + "ἐ", + "ἑ", + "ἒ", + "ἓ", + "ἔ", + "ἕ", + None, + None, + "ἠ", + "ἡ", + "ἢ", + "ἣ", + "ἤ", + "ἥ", + "ἦ", + "ἧ", + None, + "ἰ", + "ἱ", + "ἲ", + "ἳ", + "ἴ", + "ἵ", + "ἶ", + "ἷ", + None, + None, + "ὀ", + "ὁ", + "ὂ", + "ὃ", + "ὄ", + "ὅ", + None, + None, + None, + "ὑ", + None, + "ὓ", + None, + "ὕ", + None, + "ὗ", + None, + "ὠ", + "ὡ", + "ὢ", + "ὣ", + "ὤ", + "ὥ", + "ὦ", + "ὧ", + None, + "ά", + None, + "έ", + None, + "ή", + None, + "ί", + None, + "ό", + None, + "ύ", + None, + "ώ", + None, + "ἀι", + "ἁι", + "ἂι", + "ἃι", + "ἄι", + "ἅι", + "ἆι", + "ἇι", + "ἀι", + "ἁι", + "ἂι", + "ἃι", + "ἄι", + "ἅι", + "ἆι", + "ἇι", + "ἠι", + "ἡι", + "ἢι", + "ἣι", + "ἤι", + "ἥι", + "ἦι", + "ἧι", + "ἠι", + "ἡι", + "ἢι", + "ἣι", + "ἤι", + "ἥι", + "ἦι", + "ἧι", + "ὠι", + "ὡι", + "ὢι", + "ὣι", + "ὤι", + "ὥι", + "ὦι", + "ὧι", + "ὠι", + "ὡι", + "ὢι", + "ὣι", + "ὤι", + "ὥι", + "ὦι", + "ὧι", + None, + "ὰι", + "αι", + "άι", + None, + None, + "ᾶι", + "ᾰ", + "ᾱ", + "ὰ", + "ά", + "αι", + " ̓", + "ι", + " ̓", + " ͂", + " ̈͂", + "ὴι", + "ηι", + "ήι", + None, + None, + "ῆι", + "ὲ", + "έ", + "ὴ", + "ή", + "ηι", + " ̓̀", + " ̓́", + " ̓͂", + None, + "ΐ", + None, + None, + "ῐ", + "ῑ", + "ὶ", + "ί", + None, + " ̔̀", + " ̔́", + " ̔͂", + None, + "ΰ", + None, + "ῠ", + "ῡ", + "ὺ", + "ύ", + "ῥ", + " ̈̀", + " ̈́", + "`", + None, + "ὼι", + "ωι", + "ώι", + None, + None, + "ῶι", + "ὸ", + "ό", + "ὼ", + "ώ", + "ωι", + " ́", + " ̔", + None, + " ", + None, + "", + None, + None, + "‐", + None, + " ̳", + None, + None, + None, + None, + " ", + None, + "′′", + "′′′", + None, + "‵‵", + "‵‵‵", + None, + "!!", + None, + " ̅", + None, + "??", + "?!", + "!?", + None, + "′′′′", + None, + " ", + None, + None, + None, + "0", + "i", + None, + "4", + "5", + "6", + "7", + "8", + "9", + "+", + "−", + "=", + "(", + ")", + "n", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "+", + "−", + "=", + "(", + ")", + None, + "a", + "e", + "o", + "x", + "ə", + "h", + "k", + "l", + "m", + "n", + "p", + "s", + "t", + "w", + "y", + "z", + None, + "rs", + None, + None, + None, + None, + "a/c", + "a/s", + "c", + "°c", + None, + "c/o", + "c/u", + "ɛ", + None, + "°f", + "g", + "h", + "ħ", + "i", + "l", + None, + "n", + "no", + None, + "p", + "q", + "r", + None, + "sm", + "tel", + "tm", + None, + "z", + None, + "ω", + None, + "z", + None, + "k", + "å", + "b", + "c", + None, + "e", + "f", + "ⅎ", + "m", + "o", + "א", + "ב", + "ג", + "ד", + "i", + None, + "fax", + "π", + "γ", + "π", + "∑", + None, + "d", + "e", + "i", + "j", + None, + "1⁄7", + "1⁄9", + "1⁄10", + "1⁄3", + "2⁄3", + "1⁄5", + "2⁄5", + "3⁄5", + "4⁄5", + "1⁄6", + "5⁄6", + "1⁄8", + "3⁄8", + "5⁄8", + "7⁄8", + "1⁄", + "i", + "ii", + "iii", + "iv", + "v", + "vi", + "vii", + "viii", + "ix", + "x", + "xi", + "xii", + "l", + "c", + "d", + "m", + "i", + "ii", + "iii", + "iv", + "v", + "vi", + "vii", + "viii", + "ix", + "x", + "xi", + "xii", + "l", + "c", + "d", + "m", + None, + "ↄ", + None, + "0⁄3", + None, + None, + None, + "∫∫", + "∫∫∫", + None, + "∮∮", + "∮∮∮", + None, + "〈", + "〉", + None, + None, + None, + None, + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "20", + "(1)", + "(2)", + "(3)", + "(4)", + "(5)", + "(6)", + "(7)", + "(8)", + "(9)", + "(10)", + "(11)", + "(12)", + "(13)", + "(14)", + "(15)", + "(16)", + "(17)", + "(18)", + "(19)", + "(20)", + None, + "(a)", + "(b)", + "(c)", + "(d)", + "(e)", + "(f)", + "(g)", + "(h)", + "(i)", + "(j)", + "(k)", + "(l)", + "(m)", + "(n)", + "(o)", + "(p)", + "(q)", + "(r)", + "(s)", + "(t)", + "(u)", + "(v)", + "(w)", + "(x)", + "(y)", + "(z)", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "0", + None, + "∫∫∫∫", + None, + "::=", + "==", + "===", + None, + "⫝̸", + None, + None, + None, + "ⰰ", + "ⰱ", + "ⰲ", + "ⰳ", + "ⰴ", + "ⰵ", + "ⰶ", + "ⰷ", + "ⰸ", + "ⰹ", + "ⰺ", + "ⰻ", + "ⰼ", + "ⰽ", + "ⰾ", + "ⰿ", + "ⱀ", + "ⱁ", + "ⱂ", + "ⱃ", + "ⱄ", + "ⱅ", + "ⱆ", + "ⱇ", + "ⱈ", + "ⱉ", + "ⱊ", + "ⱋ", + "ⱌ", + "ⱍ", + "ⱎ", + "ⱏ", + "ⱐ", + "ⱑ", + "ⱒ", + "ⱓ", + "ⱔ", + "ⱕ", + "ⱖ", + "ⱗ", + "ⱘ", + "ⱙ", + "ⱚ", + "ⱛ", + "ⱜ", + "ⱝ", + "ⱞ", + "ⱟ", + None, + "ⱡ", + None, + "ɫ", + "ᵽ", + "ɽ", + None, + "ⱨ", + None, + "ⱪ", + None, + "ⱬ", + None, + "ɑ", + "ɱ", + "ɐ", + "ɒ", + None, + "ⱳ", + None, + "ⱶ", + None, + "j", + "v", + "ȿ", + "ɀ", + "ⲁ", + None, + "ⲃ", + None, + "ⲅ", + None, + "ⲇ", + None, + "ⲉ", + None, + "ⲋ", + None, + "ⲍ", + None, + "ⲏ", + None, + "ⲑ", + None, + "ⲓ", + None, + "ⲕ", + None, + "ⲗ", + None, + "ⲙ", + None, + "ⲛ", + None, + "ⲝ", + None, + "ⲟ", + None, + "ⲡ", + None, + "ⲣ", + None, + "ⲥ", + None, + "ⲧ", + None, + "ⲩ", + None, + "ⲫ", + None, + "ⲭ", + None, + "ⲯ", + None, + "ⲱ", + None, + "ⲳ", + None, + "ⲵ", + None, + "ⲷ", + None, + "ⲹ", + None, + "ⲻ", + None, + "ⲽ", + None, + "ⲿ", + None, + "ⳁ", + None, + "ⳃ", + None, + "ⳅ", + None, + "ⳇ", + None, + "ⳉ", + None, + "ⳋ", + None, + "ⳍ", + None, + "ⳏ", + None, + "ⳑ", + None, + "ⳓ", + None, + "ⳕ", + None, + "ⳗ", + None, + "ⳙ", + None, + "ⳛ", + None, + "ⳝ", + None, + "ⳟ", + None, + "ⳡ", + None, + "ⳣ", + None, + "ⳬ", + None, + "ⳮ", + None, + "ⳳ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ⵡ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "母", + None, + "龟", + None, + "一", + "丨", + "丶", + "丿", + "乙", + "亅", + "二", + "亠", + "人", + "儿", + "入", + "八", + "冂", + "冖", + "冫", + "几", + "凵", + "刀", + "力", + "勹", + "匕", + "匚", + "匸", + "十", + "卜", + "卩", + "厂", + "厶", + "又", + "口", + "囗", + "土", + "士", + "夂", + "夊", + "夕", + "大", + "女", + "子", + "宀", + "寸", + "小", + "尢", + "尸", + "屮", + "山", + "巛", + "工", + "己", + "巾", + "干", + "幺", + "广", + "廴", + "廾", + "弋", + "弓", + "彐", + "彡", + "彳", + "心", + "戈", + "戶", + "手", + "支", + "攴", + "文", + "斗", + "斤", + "方", + "无", + "日", + "曰", + "月", + "木", + "欠", + "止", + "歹", + "殳", + "毋", + "比", + "毛", + "氏", + "气", + "水", + "火", + "爪", + "父", + "爻", + "爿", + "片", + "牙", + "牛", + "犬", + "玄", + "玉", + "瓜", + "瓦", + "甘", + "生", + "用", + "田", + "疋", + "疒", + "癶", + "白", + "皮", + "皿", + "目", + "矛", + "矢", + "石", + "示", + "禸", + "禾", + "穴", + "立", + "竹", + "米", + "糸", + "缶", + "网", + "羊", + "羽", + "老", + "而", + "耒", + "耳", + "聿", + "肉", + "臣", + "自", + "至", + "臼", + "舌", + "舛", + "舟", + "艮", + "色", + "艸", + "虍", + "虫", + "血", + "行", + "衣", + "襾", + "見", + "角", + "言", + "谷", + "豆", + "豕", + "豸", + "貝", + "赤", + "走", + "足", + "身", + "車", + "辛", + "辰", + "辵", + "邑", + "酉", + "釆", + "里", + "金", + "長", + "門", + "阜", + "隶", + "隹", + "雨", + "靑", + "非", + "面", + "革", + "韋", + "韭", + "音", + "頁", + "風", + "飛", + "食", + "首", + "香", + "馬", + "骨", + "高", + "髟", + "鬥", + "鬯", + "鬲", + "鬼", + "魚", + "鳥", + "鹵", + "鹿", + "麥", + "麻", + "黃", + "黍", + "黑", + "黹", + "黽", + "鼎", + "鼓", + "鼠", + "鼻", + "齊", + "齒", + "龍", + "龜", + "龠", + None, + " ", + None, + ".", + None, + "〒", + None, + "十", + "卄", + "卅", + None, + None, + None, + None, + None, + " ゙", + " ゚", + None, + "より", + None, + "コト", + None, + None, + None, + "ᄀ", + "ᄁ", + "ᆪ", + "ᄂ", + "ᆬ", + "ᆭ", + "ᄃ", + "ᄄ", + "ᄅ", + "ᆰ", + "ᆱ", + "ᆲ", + "ᆳ", + "ᆴ", + "ᆵ", + "ᄚ", + "ᄆ", + "ᄇ", + "ᄈ", + "ᄡ", + "ᄉ", + "ᄊ", + "ᄋ", + "ᄌ", + "ᄍ", + "ᄎ", + "ᄏ", + "ᄐ", + "ᄑ", + "ᄒ", + "ᅡ", + "ᅢ", + "ᅣ", + "ᅤ", + "ᅥ", + "ᅦ", + "ᅧ", + "ᅨ", + "ᅩ", + "ᅪ", + "ᅫ", + "ᅬ", + "ᅭ", + "ᅮ", + "ᅯ", + "ᅰ", + "ᅱ", + "ᅲ", + "ᅳ", + "ᅴ", + "ᅵ", + None, + "ᄔ", + "ᄕ", + "ᇇ", + "ᇈ", + "ᇌ", + "ᇎ", + "ᇓ", + "ᇗ", + "ᇙ", + "ᄜ", + "ᇝ", + "ᇟ", + "ᄝ", + "ᄞ", + "ᄠ", + "ᄢ", + "ᄣ", + "ᄧ", + "ᄩ", + "ᄫ", + "ᄬ", + "ᄭ", + "ᄮ", + "ᄯ", + "ᄲ", + "ᄶ", + "ᅀ", + "ᅇ", + "ᅌ", + "ᇱ", + "ᇲ", + "ᅗ", + "ᅘ", + "ᅙ", + "ᆄ", + "ᆅ", + "ᆈ", + "ᆑ", + "ᆒ", + "ᆔ", + "ᆞ", + "ᆡ", + None, + None, + "一", + "二", + "三", + "四", + "上", + "中", + "下", + "甲", + "乙", + "丙", + "丁", + "天", + "地", + "人", + None, + None, + None, + "(ᄀ)", + "(ᄂ)", + "(ᄃ)", + "(ᄅ)", + "(ᄆ)", + "(ᄇ)", + "(ᄉ)", + "(ᄋ)", + "(ᄌ)", + "(ᄎ)", + "(ᄏ)", + "(ᄐ)", + "(ᄑ)", + "(ᄒ)", + "(가)", + "(나)", + "(다)", + "(라)", + "(마)", + "(바)", + "(사)", + "(아)", + "(자)", + "(차)", + "(카)", + "(타)", + "(파)", + "(하)", + "(주)", + "(오전)", + "(오후)", + None, + "(一)", + "(二)", + "(三)", + "(四)", + "(五)", + "(六)", + "(七)", + "(八)", + "(九)", + "(十)", + "(月)", + "(火)", + "(水)", + "(木)", + "(金)", + "(土)", + "(日)", + "(株)", + "(有)", + "(社)", + "(名)", + "(特)", + "(財)", + "(祝)", + "(労)", + "(代)", + "(呼)", + "(学)", + "(監)", + "(企)", + "(資)", + "(協)", + "(祭)", + "(休)", + "(自)", + "(至)", + "問", + "幼", + "文", + "箏", + None, + "pte", + "21", + "22", + "23", + "24", + "25", + "26", + "27", + "28", + "29", + "30", + "31", + "32", + "33", + "34", + "35", + "ᄀ", + "ᄂ", + "ᄃ", + "ᄅ", + "ᄆ", + "ᄇ", + "ᄉ", + "ᄋ", + "ᄌ", + "ᄎ", + "ᄏ", + "ᄐ", + "ᄑ", + "ᄒ", + "가", + "나", + "다", + "라", + "마", + "바", + "사", + "아", + "자", + "차", + "카", + "타", + "파", + "하", + "참고", + "주의", + "우", + None, + "一", + "二", + "三", + "四", + "五", + "六", + "七", + "八", + "九", + "十", + "月", + "火", + "水", + "木", + "金", + "土", + "日", + "株", + "有", + "社", + "名", + "特", + "財", + "祝", + "労", + "秘", + "男", + "女", + "適", + "優", + "印", + "注", + "項", + "休", + "写", + "正", + "上", + "中", + "下", + "左", + "右", + "医", + "宗", + "学", + "監", + "企", + "資", + "協", + "夜", + "36", + "37", + "38", + "39", + "40", + "41", + "42", + "43", + "44", + "45", + "46", + "47", + "48", + "49", + "50", + "1月", + "2月", + "3月", + "4月", + "5月", + "6月", + "7月", + "8月", + "9月", + "10月", + "11月", + "12月", + "hg", + "erg", + "ev", + "ltd", + "ア", + "イ", + "ウ", + "エ", + "オ", + "カ", + "キ", + "ク", + "ケ", + "コ", + "サ", + "シ", + "ス", + "セ", + "ソ", + "タ", + "チ", + "ツ", + "テ", + "ト", + "ナ", + "ニ", + "ヌ", + "ネ", + "ノ", + "ハ", + "ヒ", + "フ", + "ヘ", + "ホ", + "マ", + "ミ", + "ム", + "メ", + "モ", + "ヤ", + "ユ", + "ヨ", + "ラ", + "リ", + "ル", + "レ", + "ロ", + "ワ", + "ヰ", + "ヱ", + "ヲ", + "令和", + "アパート", + "アルファ", + "アンペア", + "アール", + "イニング", + "インチ", + "ウォン", + "エスクード", + "エーカー", + "オンス", + "オーム", + "カイリ", + "カラット", + "カロリー", + "ガロン", + "ガンマ", + "ギガ", + "ギニー", + "キュリー", + "ギルダー", + "キロ", + "キログラム", + "キロメートル", + "キロワット", + "グラム", + "グラムトン", + "クルゼイロ", + "クローネ", + "ケース", + "コルナ", + "コーポ", + "サイクル", + "サンチーム", + "シリング", + "センチ", + "セント", + "ダース", + "デシ", + "ドル", + "トン", + "ナノ", + "ノット", + "ハイツ", + "パーセント", + "パーツ", + "バーレル", + "ピアストル", + "ピクル", + "ピコ", + "ビル", + "ファラッド", + "フィート", + "ブッシェル", + "フラン", + "ヘクタール", + "ペソ", + "ペニヒ", + "ヘルツ", + "ペンス", + "ページ", + "ベータ", + "ポイント", + "ボルト", + "ホン", + "ポンド", + "ホール", + "ホーン", + "マイクロ", + "マイル", + "マッハ", + "マルク", + "マンション", + "ミクロン", + "ミリ", + "ミリバール", + "メガ", + "メガトン", + "メートル", + "ヤード", + "ヤール", + "ユアン", + "リットル", + "リラ", + "ルピー", + "ルーブル", + "レム", + "レントゲン", + "ワット", + "0点", + "1点", + "2点", + "3点", + "4点", + "5点", + "6点", + "7点", + "8点", + "9点", + "10点", + "11点", + "12点", + "13点", + "14点", + "15点", + "16点", + "17点", + "18点", + "19点", + "20点", + "21点", + "22点", + "23点", + "24点", + "hpa", + "da", + "au", + "bar", + "ov", + "pc", + "dm", + "dm2", + "dm3", + "iu", + "平成", + "昭和", + "大正", + "明治", + "株式会社", + "pa", + "na", + "μa", + "ma", + "ka", + "kb", + "mb", + "gb", + "cal", + "kcal", + "pf", + "nf", + "μf", + "μg", + "mg", + "kg", + "hz", + "khz", + "mhz", + "ghz", + "thz", + "μl", + "ml", + "dl", + "kl", + "fm", + "nm", + "μm", + "mm", + "cm", + "km", + "mm2", + "cm2", + "m2", + "km2", + "mm3", + "cm3", + "m3", + "km3", + "m∕s", + "m∕s2", + "pa", + "kpa", + "mpa", + "gpa", + "rad", + "rad∕s", + "rad∕s2", + "ps", + "ns", + "μs", + "ms", + "pv", + "nv", + "μv", + "mv", + "kv", + "mv", + "pw", + "nw", + "μw", + "mw", + "kw", + "mw", + "kω", + "mω", + None, + "bq", + "cc", + "cd", + "c∕kg", + None, + "db", + "gy", + "ha", + "hp", + "in", + "kk", + "km", + "kt", + "lm", + "ln", + "log", + "lx", + "mb", + "mil", + "mol", + "ph", + None, + "ppm", + "pr", + "sr", + "sv", + "wb", + "v∕m", + "a∕m", + "1日", + "2日", + "3日", + "4日", + "5日", + "6日", + "7日", + "8日", + "9日", + "10日", + "11日", + "12日", + "13日", + "14日", + "15日", + "16日", + "17日", + "18日", + "19日", + "20日", + "21日", + "22日", + "23日", + "24日", + "25日", + "26日", + "27日", + "28日", + "29日", + "30日", + "31日", + "gal", + None, + None, + None, + None, + None, + None, + "ꙁ", + None, + "ꙃ", + None, + "ꙅ", + None, + "ꙇ", + None, + "ꙉ", + None, + "ꙋ", + None, + "ꙍ", + None, + "ꙏ", + None, + "ꙑ", + None, + "ꙓ", + None, + "ꙕ", + None, + "ꙗ", + None, + "ꙙ", + None, + "ꙛ", + None, + "ꙝ", + None, + "ꙟ", + None, + "ꙡ", + None, + "ꙣ", + None, + "ꙥ", + None, + "ꙧ", + None, + "ꙩ", + None, + "ꙫ", + None, + "ꙭ", + None, + "ꚁ", + None, + "ꚃ", + None, + "ꚅ", + None, + "ꚇ", + None, + "ꚉ", + None, + "ꚋ", + None, + "ꚍ", + None, + "ꚏ", + None, + "ꚑ", + None, + "ꚓ", + None, + "ꚕ", + None, + "ꚗ", + None, + "ꚙ", + None, + "ꚛ", + None, + "ъ", + "ь", + None, + None, + None, + "ꜣ", + None, + "ꜥ", + None, + "ꜧ", + None, + "ꜩ", + None, + "ꜫ", + None, + "ꜭ", + None, + "ꜯ", + None, + "ꜳ", + None, + "ꜵ", + None, + "ꜷ", + None, + "ꜹ", + None, + "ꜻ", + None, + "ꜽ", + None, + "ꜿ", + None, + "ꝁ", + None, + "ꝃ", + None, + "ꝅ", + None, + "ꝇ", + None, + "ꝉ", + None, + "ꝋ", + None, + "ꝍ", + None, + "ꝏ", + None, + "ꝑ", + None, + "ꝓ", + None, + "ꝕ", + None, + "ꝗ", + None, + "ꝙ", + None, + "ꝛ", + None, + "ꝝ", + None, + "ꝟ", + None, + "ꝡ", + None, + "ꝣ", + None, + "ꝥ", + None, + "ꝧ", + None, + "ꝩ", + None, + "ꝫ", + None, + "ꝭ", + None, + "ꝯ", + None, + "ꝯ", + None, + "ꝺ", + None, + "ꝼ", + None, + "ᵹ", + "ꝿ", + None, + "ꞁ", + None, + "ꞃ", + None, + "ꞅ", + None, + "ꞇ", + None, + "ꞌ", + None, + "ɥ", + None, + "ꞑ", + None, + "ꞓ", + None, + "ꞗ", + None, + "ꞙ", + None, + "ꞛ", + None, + "ꞝ", + None, + "ꞟ", + None, + "ꞡ", + None, + "ꞣ", + None, + "ꞥ", + None, + "ꞧ", + None, + "ꞩ", + None, + "ɦ", + "ɜ", + "ɡ", + "ɬ", + "ɪ", + None, + "ʞ", + "ʇ", + "ʝ", + "ꭓ", + "ꞵ", + None, + "ꞷ", + None, + "ꞹ", + None, + "ꞻ", + None, + "ꞽ", + None, + "ꞿ", + None, + "ꟁ", + None, + "ꟃ", + None, + "ꞔ", + "ʂ", + "ᶎ", + "ꟈ", + None, + "ꟊ", + None, + "ɤ", + "ꟍ", + None, + "꟏", + None, + "ꟑ", + None, + "ꟓ", + None, + "ꟕ", + None, + "ꟗ", + None, + "ꟙ", + None, + "ꟛ", + None, + "ƛ", + "ɷ", + None, + "ɼ", + None, + "s", + "c", + "f", + "q", + "ꟶ", + None, + "ħ", + "œ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ꜧ", + "ꬷ", + "ɫ", + "ꭒ", + None, + "ʍ", + None, + "ꭋ", + "ꭌ", + None, + "Ꭰ", + "Ꭱ", + "Ꭲ", + "Ꭳ", + "Ꭴ", + "Ꭵ", + "Ꭶ", + "Ꭷ", + "Ꭸ", + "Ꭹ", + "Ꭺ", + "Ꭻ", + "Ꭼ", + "Ꭽ", + "Ꭾ", + "Ꭿ", + "Ꮀ", + "Ꮁ", + "Ꮂ", + "Ꮃ", + "Ꮄ", + "Ꮅ", + "Ꮆ", + "Ꮇ", + "Ꮈ", + "Ꮉ", + "Ꮊ", + "Ꮋ", + "Ꮌ", + "Ꮍ", + "Ꮎ", + "Ꮏ", + "Ꮐ", + "Ꮑ", + "Ꮒ", + "Ꮓ", + "Ꮔ", + "Ꮕ", + "Ꮖ", + "Ꮗ", + "Ꮘ", + "Ꮙ", + "Ꮚ", + "Ꮛ", + "Ꮜ", + "Ꮝ", + "Ꮞ", + "Ꮟ", + "Ꮠ", + "Ꮡ", + "Ꮢ", + "Ꮣ", + "Ꮤ", + "Ꮥ", + "Ꮦ", + "Ꮧ", + "Ꮨ", + "Ꮩ", + "Ꮪ", + "Ꮫ", + "Ꮬ", + "Ꮭ", + "Ꮮ", + "Ꮯ", + "Ꮰ", + "Ꮱ", + "Ꮲ", + "Ꮳ", + "Ꮴ", + "Ꮵ", + "Ꮶ", + "Ꮷ", + "Ꮸ", + "Ꮹ", + "Ꮺ", + "Ꮻ", + "Ꮼ", + "Ꮽ", + "Ꮾ", + "Ꮿ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "豈", + "更", + "車", + "賈", + "滑", + "串", + "句", + "龜", + "契", + "金", + "喇", + "奈", + "懶", + "癩", + "羅", + "蘿", + "螺", + "裸", + "邏", + "樂", + "洛", + "烙", + "珞", + "落", + "酪", + "駱", + "亂", + "卵", + "欄", + "爛", + "蘭", + "鸞", + "嵐", + "濫", + "藍", + "襤", + "拉", + "臘", + "蠟", + "廊", + "朗", + "浪", + "狼", + "郎", + "來", + "冷", + "勞", + "擄", + "櫓", + "爐", + "盧", + "老", + "蘆", + "虜", + "路", + "露", + "魯", + "鷺", + "碌", + "祿", + "綠", + "菉", + "錄", + "鹿", + "論", + "壟", + "弄", + "籠", + "聾", + "牢", + "磊", + "賂", + "雷", + "壘", + "屢", + "樓", + "淚", + "漏", + "累", + "縷", + "陋", + "勒", + "肋", + "凜", + "凌", + "稜", + "綾", + "菱", + "陵", + "讀", + "拏", + "樂", + "諾", + "丹", + "寧", + "怒", + "率", + "異", + "北", + "磻", + "便", + "復", + "不", + "泌", + "數", + "索", + "參", + "塞", + "省", + "葉", + "說", + "殺", + "辰", + "沈", + "拾", + "若", + "掠", + "略", + "亮", + "兩", + "凉", + "梁", + "糧", + "良", + "諒", + "量", + "勵", + "呂", + "女", + "廬", + "旅", + "濾", + "礪", + "閭", + "驪", + "麗", + "黎", + "力", + "曆", + "歷", + "轢", + "年", + "憐", + "戀", + "撚", + "漣", + "煉", + "璉", + "秊", + "練", + "聯", + "輦", + "蓮", + "連", + "鍊", + "列", + "劣", + "咽", + "烈", + "裂", + "說", + "廉", + "念", + "捻", + "殮", + "簾", + "獵", + "令", + "囹", + "寧", + "嶺", + "怜", + "玲", + "瑩", + "羚", + "聆", + "鈴", + "零", + "靈", + "領", + "例", + "禮", + "醴", + "隸", + "惡", + "了", + "僚", + "寮", + "尿", + "料", + "樂", + "燎", + "療", + "蓼", + "遼", + "龍", + "暈", + "阮", + "劉", + "杻", + "柳", + "流", + "溜", + "琉", + "留", + "硫", + "紐", + "類", + "六", + "戮", + "陸", + "倫", + "崙", + "淪", + "輪", + "律", + "慄", + "栗", + "率", + "隆", + "利", + "吏", + "履", + "易", + "李", + "梨", + "泥", + "理", + "痢", + "罹", + "裏", + "裡", + "里", + "離", + "匿", + "溺", + "吝", + "燐", + "璘", + "藺", + "隣", + "鱗", + "麟", + "林", + "淋", + "臨", + "立", + "笠", + "粒", + "狀", + "炙", + "識", + "什", + "茶", + "刺", + "切", + "度", + "拓", + "糖", + "宅", + "洞", + "暴", + "輻", + "行", + "降", + "見", + "廓", + "兀", + "嗀", + None, + "塚", + None, + "晴", + None, + "凞", + "猪", + "益", + "礼", + "神", + "祥", + "福", + "靖", + "精", + "羽", + None, + "蘒", + None, + "諸", + None, + "逸", + "都", + None, + "飯", + "飼", + "館", + "鶴", + "郞", + "隷", + "侮", + "僧", + "免", + "勉", + "勤", + "卑", + "喝", + "嘆", + "器", + "塀", + "墨", + "層", + "屮", + "悔", + "慨", + "憎", + "懲", + "敏", + "既", + "暑", + "梅", + "海", + "渚", + "漢", + "煮", + "爫", + "琢", + "碑", + "社", + "祉", + "祈", + "祐", + "祖", + "祝", + "禍", + "禎", + "穀", + "突", + "節", + "練", + "縉", + "繁", + "署", + "者", + "臭", + "艹", + "著", + "褐", + "視", + "謁", + "謹", + "賓", + "贈", + "辶", + "逸", + "難", + "響", + "頻", + "恵", + "𤋮", + "舘", + None, + "並", + "况", + "全", + "侀", + "充", + "冀", + "勇", + "勺", + "喝", + "啕", + "喙", + "嗢", + "塚", + "墳", + "奄", + "奔", + "婢", + "嬨", + "廒", + "廙", + "彩", + "徭", + "惘", + "慎", + "愈", + "憎", + "慠", + "懲", + "戴", + "揄", + "搜", + "摒", + "敖", + "晴", + "朗", + "望", + "杖", + "歹", + "殺", + "流", + "滛", + "滋", + "漢", + "瀞", + "煮", + "瞧", + "爵", + "犯", + "猪", + "瑱", + "甆", + "画", + "瘝", + "瘟", + "益", + "盛", + "直", + "睊", + "着", + "磌", + "窱", + "節", + "类", + "絛", + "練", + "缾", + "者", + "荒", + "華", + "蝹", + "襁", + "覆", + "視", + "調", + "諸", + "請", + "謁", + "諾", + "諭", + "謹", + "變", + "贈", + "輸", + "遲", + "醙", + "鉶", + "陼", + "難", + "靖", + "韛", + "響", + "頋", + "頻", + "鬒", + "龜", + "𢡊", + "𢡄", + "𣏕", + "㮝", + "䀘", + "䀹", + "𥉉", + "𥳐", + "𧻓", + "齃", + "龎", + None, + "ff", + "fi", + "fl", + "ffi", + "ffl", + "st", + None, + "մն", + "մե", + "մի", + "վն", + "մխ", + None, + "יִ", + None, + "ײַ", + "ע", + "א", + "ד", + "ה", + "כ", + "ל", + "ם", + "ר", + "ת", + "+", + "שׁ", + "שׂ", + "שּׁ", + "שּׂ", + "אַ", + "אָ", + "אּ", + "בּ", + "גּ", + "דּ", + "הּ", + "וּ", + "זּ", + None, + "טּ", + "יּ", + "ךּ", + "כּ", + "לּ", + None, + "מּ", + None, + "נּ", + "סּ", + None, + "ףּ", + "פּ", + None, + "צּ", + "קּ", + "רּ", + "שּ", + "תּ", + "וֹ", + "בֿ", + "כֿ", + "פֿ", + "אל", + "ٱ", + "ٻ", + "پ", + "ڀ", + "ٺ", + "ٿ", + "ٹ", + "ڤ", + "ڦ", + "ڄ", + "ڃ", + "چ", + "ڇ", + "ڍ", + "ڌ", + "ڎ", + "ڈ", + "ژ", + "ڑ", + "ک", + "گ", + "ڳ", + "ڱ", + "ں", + "ڻ", + "ۀ", + "ہ", + "ھ", + "ے", + "ۓ", + None, + "ڭ", + "ۇ", + "ۆ", + "ۈ", + "ۇٴ", + "ۋ", + "ۅ", + "ۉ", + "ې", + "ى", + "ئا", + "ئە", + "ئو", + "ئۇ", + "ئۆ", + "ئۈ", + "ئې", + "ئى", + "ی", + "ئج", + "ئح", + "ئم", + "ئى", + "ئي", + "بج", + "بح", + "بخ", + "بم", + "بى", + "بي", + "تج", + "تح", + "تخ", + "تم", + "تى", + "تي", + "ثج", + "ثم", + "ثى", + "ثي", + "جح", + "جم", + "حج", + "حم", + "خج", + "خح", + "خم", + "سج", + "سح", + "سخ", + "سم", + "صح", + "صم", + "ضج", + "ضح", + "ضخ", + "ضم", + "طح", + "طم", + "ظم", + "عج", + "عم", + "غج", + "غم", + "فج", + "فح", + "فخ", + "فم", + "فى", + "في", + "قح", + "قم", + "قى", + "قي", + "كا", + "كج", + "كح", + "كخ", + "كل", + "كم", + "كى", + "كي", + "لج", + "لح", + "لخ", + "لم", + "لى", + "لي", + "مج", + "مح", + "مخ", + "مم", + "مى", + "مي", + "نج", + "نح", + "نخ", + "نم", + "نى", + "ني", + "هج", + "هم", + "هى", + "هي", + "يج", + "يح", + "يخ", + "يم", + "يى", + "يي", + "ذٰ", + "رٰ", + "ىٰ", + " ٌّ", + " ٍّ", + " َّ", + " ُّ", + " ِّ", + " ّٰ", + "ئر", + "ئز", + "ئم", + "ئن", + "ئى", + "ئي", + "بر", + "بز", + "بم", + "بن", + "بى", + "بي", + "تر", + "تز", + "تم", + "تن", + "تى", + "تي", + "ثر", + "ثز", + "ثم", + "ثن", + "ثى", + "ثي", + "فى", + "في", + "قى", + "قي", + "كا", + "كل", + "كم", + "كى", + "كي", + "لم", + "لى", + "لي", + "ما", + "مم", + "نر", + "نز", + "نم", + "نن", + "نى", + "ني", + "ىٰ", + "ير", + "يز", + "يم", + "ين", + "يى", + "يي", + "ئج", + "ئح", + "ئخ", + "ئم", + "ئه", + "بج", + "بح", + "بخ", + "بم", + "به", + "تج", + "تح", + "تخ", + "تم", + "ته", + "ثم", + "جح", + "جم", + "حج", + "حم", + "خج", + "خم", + "سج", + "سح", + "سخ", + "سم", + "صح", + "صخ", + "صم", + "ضج", + "ضح", + "ضخ", + "ضم", + "طح", + "ظم", + "عج", + "عم", + "غج", + "غم", + "فج", + "فح", + "فخ", + "فم", + "قح", + "قم", + "كج", + "كح", + "كخ", + "كل", + "كم", + "لج", + "لح", + "لخ", + "لم", + "له", + "مج", + "مح", + "مخ", + "مم", + "نج", + "نح", + "نخ", + "نم", + "نه", + "هج", + "هم", + "هٰ", + "يج", + "يح", + "يخ", + "يم", + "يه", + "ئم", + "ئه", + "بم", + "به", + "تم", + "ته", + "ثم", + "ثه", + "سم", + "سه", + "شم", + "شه", + "كل", + "كم", + "لم", + "نم", + "نه", + "يم", + "يه", + "ـَّ", + "ـُّ", + "ـِّ", + "طى", + "طي", + "عى", + "عي", + "غى", + "غي", + "سى", + "سي", + "شى", + "شي", + "حى", + "حي", + "جى", + "جي", + "خى", + "خي", + "صى", + "صي", + "ضى", + "ضي", + "شج", + "شح", + "شخ", + "شم", + "شر", + "سر", + "صر", + "ضر", + "طى", + "طي", + "عى", + "عي", + "غى", + "غي", + "سى", + "سي", + "شى", + "شي", + "حى", + "حي", + "جى", + "جي", + "خى", + "خي", + "صى", + "صي", + "ضى", + "ضي", + "شج", + "شح", + "شخ", + "شم", + "شر", + "سر", + "صر", + "ضر", + "شج", + "شح", + "شخ", + "شم", + "سه", + "شه", + "طم", + "سج", + "سح", + "سخ", + "شج", + "شح", + "شخ", + "طم", + "ظم", + "اً", + None, + "تجم", + "تحج", + "تحم", + "تخم", + "تمج", + "تمح", + "تمخ", + "جمح", + "حمي", + "حمى", + "سحج", + "سجح", + "سجى", + "سمح", + "سمج", + "سمم", + "صحح", + "صمم", + "شحم", + "شجي", + "شمخ", + "شمم", + "ضحى", + "ضخم", + "طمح", + "طمم", + "طمي", + "عجم", + "عمم", + "عمى", + "غمم", + "غمي", + "غمى", + "فخم", + "قمح", + "قمم", + "لحم", + "لحي", + "لحى", + "لجج", + "لخم", + "لمح", + "محج", + "محم", + "محي", + "مجح", + "مجم", + "مخج", + "مخم", + None, + "مجخ", + "همج", + "همم", + "نحم", + "نحى", + "نجم", + "نجى", + "نمي", + "نمى", + "يمم", + "بخي", + "تجي", + "تجى", + "تخي", + "تخى", + "تمي", + "تمى", + "جمي", + "جحى", + "جمى", + "سخى", + "صحي", + "شحي", + "ضحي", + "لجي", + "لمي", + "يحي", + "يجي", + "يمي", + "ممي", + "قمي", + "نحي", + "قمح", + "لحم", + "عمي", + "كمي", + "نجح", + "مخي", + "لجم", + "كمم", + "لجم", + "نجح", + "جحي", + "حجي", + "مجي", + "فمي", + "بحي", + "كمم", + "عجم", + "صمم", + "سخي", + "نجي", + None, + None, + "صلے", + "قلے", + "الله", + "اكبر", + "محمد", + "صلعم", + "رسول", + "عليه", + "وسلم", + "صلى", + "صلى الله عليه وسلم", + "جل جلاله", + "ریال", + None, + None, + ",", + "、", + None, + ":", + ";", + "!", + "?", + "〖", + "〗", + None, + None, + None, + "—", + "–", + "_", + "(", + ")", + "{", + "}", + "〔", + "〕", + "【", + "】", + "《", + "》", + "〈", + "〉", + "「", + "」", + "『", + "』", + None, + "[", + "]", + " ̅", + "_", + ",", + "、", + None, + ";", + ":", + "?", + "!", + "—", + "(", + ")", + "{", + "}", + "〔", + "〕", + "#", + "&", + "*", + "+", + "-", + "<", + ">", + "=", + None, + "\\", + "$", + "%", + "@", + None, + " ً", + "ـً", + " ٌ", + None, + " ٍ", + None, + " َ", + "ـَ", + " ُ", + "ـُ", + " ِ", + "ـِ", + " ّ", + "ـّ", + " ْ", + "ـْ", + "ء", + "آ", + "أ", + "ؤ", + "إ", + "ئ", + "ا", + "ب", + "ة", + "ت", + "ث", + "ج", + "ح", + "خ", + "د", + "ذ", + "ر", + "ز", + "س", + "ش", + "ص", + "ض", + "ط", + "ظ", + "ع", + "غ", + "ف", + "ق", + "ك", + "ل", + "م", + "ن", + "ه", + "و", + "ى", + "ي", + "لآ", + "لأ", + "لإ", + "لا", + None, + None, + None, + "!", + '"', + "#", + "$", + "%", + "&", + "'", + "(", + ")", + "*", + "+", + ",", + "-", + ".", + "/", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + ":", + ";", + "<", + "=", + ">", + "?", + "@", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "[", + "\\", + "]", + "^", + "_", + "`", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "{", + "|", + "}", + "~", + "⦅", + "⦆", + ".", + "「", + "」", + "、", + "・", + "ヲ", + "ァ", + "ィ", + "ゥ", + "ェ", + "ォ", + "ャ", + "ュ", + "ョ", + "ッ", + "ー", + "ア", + "イ", + "ウ", + "エ", + "オ", + "カ", + "キ", + "ク", + "ケ", + "コ", + "サ", + "シ", + "ス", + "セ", + "ソ", + "タ", + "チ", + "ツ", + "テ", + "ト", + "ナ", + "ニ", + "ヌ", + "ネ", + "ノ", + "ハ", + "ヒ", + "フ", + "ヘ", + "ホ", + "マ", + "ミ", + "ム", + "メ", + "モ", + "ヤ", + "ユ", + "ヨ", + "ラ", + "リ", + "ル", + "レ", + "ロ", + "ワ", + "ン", + "゙", + "゚", + None, + "ᄀ", + "ᄁ", + "ᆪ", + "ᄂ", + "ᆬ", + "ᆭ", + "ᄃ", + "ᄄ", + "ᄅ", + "ᆰ", + "ᆱ", + "ᆲ", + "ᆳ", + "ᆴ", + "ᆵ", + "ᄚ", + "ᄆ", + "ᄇ", + "ᄈ", + "ᄡ", + "ᄉ", + "ᄊ", + "ᄋ", + "ᄌ", + "ᄍ", + "ᄎ", + "ᄏ", + "ᄐ", + "ᄑ", + "ᄒ", + None, + "ᅡ", + "ᅢ", + "ᅣ", + "ᅤ", + "ᅥ", + "ᅦ", + None, + "ᅧ", + "ᅨ", + "ᅩ", + "ᅪ", + "ᅫ", + "ᅬ", + None, + "ᅭ", + "ᅮ", + "ᅯ", + "ᅰ", + "ᅱ", + "ᅲ", + None, + "ᅳ", + "ᅴ", + "ᅵ", + None, + "¢", + "£", + "¬", + " ̄", + "¦", + "¥", + "₩", + None, + "│", + "←", + "↑", + "→", + "↓", + "■", + "○", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𐐨", + "𐐩", + "𐐪", + "𐐫", + "𐐬", + "𐐭", + "𐐮", + "𐐯", + "𐐰", + "𐐱", + "𐐲", + "𐐳", + "𐐴", + "𐐵", + "𐐶", + "𐐷", + "𐐸", + "𐐹", + "𐐺", + "𐐻", + "𐐼", + "𐐽", + "𐐾", + "𐐿", + "𐑀", + "𐑁", + "𐑂", + "𐑃", + "𐑄", + "𐑅", + "𐑆", + "𐑇", + "𐑈", + "𐑉", + "𐑊", + "𐑋", + "𐑌", + "𐑍", + "𐑎", + "𐑏", + None, + None, + None, + None, + "𐓘", + "𐓙", + "𐓚", + "𐓛", + "𐓜", + "𐓝", + "𐓞", + "𐓟", + "𐓠", + "𐓡", + "𐓢", + "𐓣", + "𐓤", + "𐓥", + "𐓦", + "𐓧", + "𐓨", + "𐓩", + "𐓪", + "𐓫", + "𐓬", + "𐓭", + "𐓮", + "𐓯", + "𐓰", + "𐓱", + "𐓲", + "𐓳", + "𐓴", + "𐓵", + "𐓶", + "𐓷", + "𐓸", + "𐓹", + "𐓺", + "𐓻", + None, + None, + None, + None, + None, + None, + None, + None, + "𐖗", + "𐖘", + "𐖙", + "𐖚", + "𐖛", + "𐖜", + "𐖝", + "𐖞", + "𐖟", + "𐖠", + "𐖡", + None, + "𐖣", + "𐖤", + "𐖥", + "𐖦", + "𐖧", + "𐖨", + "𐖩", + "𐖪", + "𐖫", + "𐖬", + "𐖭", + "𐖮", + "𐖯", + "𐖰", + "𐖱", + None, + "𐖳", + "𐖴", + "𐖵", + "𐖶", + "𐖷", + "𐖸", + "𐖹", + None, + "𐖻", + "𐖼", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ː", + "ˑ", + "æ", + "ʙ", + "ɓ", + None, + "ʣ", + "ꭦ", + "ʥ", + "ʤ", + "ɖ", + "ɗ", + "ᶑ", + "ɘ", + "ɞ", + "ʩ", + "ɤ", + "ɢ", + "ɠ", + "ʛ", + "ħ", + "ʜ", + "ɧ", + "ʄ", + "ʪ", + "ʫ", + "ɬ", + "𝼄", + "ꞎ", + "ɮ", + "𝼅", + "ʎ", + "𝼆", + "ø", + "ɶ", + "ɷ", + "q", + "ɺ", + "𝼈", + "ɽ", + "ɾ", + "ʀ", + "ʨ", + "ʦ", + "ꭧ", + "ʧ", + "ʈ", + "ⱱ", + None, + "ʏ", + "ʡ", + "ʢ", + "ʘ", + "ǀ", + "ǁ", + "ǂ", + "𝼊", + "𝼞", + "ʇ", + "ʖ", + "ʗ", + "ʞ", + "𝼋", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𐳀", + "𐳁", + "𐳂", + "𐳃", + "𐳄", + "𐳅", + "𐳆", + "𐳇", + "𐳈", + "𐳉", + "𐳊", + "𐳋", + "𐳌", + "𐳍", + "𐳎", + "𐳏", + "𐳐", + "𐳑", + "𐳒", + "𐳓", + "𐳔", + "𐳕", + "𐳖", + "𐳗", + "𐳘", + "𐳙", + "𐳚", + "𐳛", + "𐳜", + "𐳝", + "𐳞", + "𐳟", + "𐳠", + "𐳡", + "𐳢", + "𐳣", + "𐳤", + "𐳥", + "𐳦", + "𐳧", + "𐳨", + "𐳩", + "𐳪", + "𐳫", + "𐳬", + "𐳭", + "𐳮", + "𐳯", + "𐳰", + "𐳱", + "𐳲", + None, + None, + None, + None, + None, + None, + None, + None, + "𐵰", + "𐵱", + "𐵲", + "𐵳", + "𐵴", + "𐵵", + "𐵶", + "𐵷", + "𐵸", + "𐵹", + "𐵺", + "𐵻", + "𐵼", + "𐵽", + "𐵾", + "𐵿", + "𐶀", + "𐶁", + "𐶂", + "𐶃", + "𐶄", + "𐶅", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𑣀", + "𑣁", + "𑣂", + "𑣃", + "𑣄", + "𑣅", + "𑣆", + "𑣇", + "𑣈", + "𑣉", + "𑣊", + "𑣋", + "𑣌", + "𑣍", + "𑣎", + "𑣏", + "𑣐", + "𑣑", + "𑣒", + "𑣓", + "𑣔", + "𑣕", + "𑣖", + "𑣗", + "𑣘", + "𑣙", + "𑣚", + "𑣛", + "𑣜", + "𑣝", + "𑣞", + "𑣟", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𖹠", + "𖹡", + "𖹢", + "𖹣", + "𖹤", + "𖹥", + "𖹦", + "𖹧", + "𖹨", + "𖹩", + "𖹪", + "𖹫", + "𖹬", + "𖹭", + "𖹮", + "𖹯", + "𖹰", + "𖹱", + "𖹲", + "𖹳", + "𖹴", + "𖹵", + "𖹶", + "𖹷", + "𖹸", + "𖹹", + "𖹺", + "𖹻", + "𖹼", + "𖹽", + "𖹾", + "𖹿", + None, + None, + "𖺻", + "𖺼", + "𖺽", + "𖺾", + "𖺿", + "𖻀", + "𖻁", + "𖻂", + "𖻃", + "𖻄", + "𖻅", + "𖻆", + "𖻇", + "𖻈", + "𖻉", + "𖻊", + "𖻋", + "𖻌", + "𖻍", + "𖻎", + "𖻏", + "𖻐", + "𖻑", + "𖻒", + "𖻓", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "こと", + "トキ", + "トテ", + "ヨリ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𝅗𝅥", + "𝅘𝅥", + "𝅘𝅥𝅮", + "𝅘𝅥𝅯", + "𝅘𝅥𝅰", + "𝅘𝅥𝅱", + "𝅘𝅥𝅲", + None, + None, + None, + "𝆹𝅥", + "𝆺𝅥", + "𝆹𝅥𝅮", + "𝆺𝅥𝅮", + "𝆹𝅥𝅯", + "𝆺𝅥𝅯", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + None, + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + None, + "c", + "d", + None, + "g", + None, + "j", + "k", + None, + "n", + "o", + "p", + "q", + None, + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + None, + "f", + None, + "h", + "i", + "j", + "k", + "l", + "m", + "n", + None, + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + None, + "d", + "e", + "f", + "g", + None, + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + None, + "s", + "t", + "u", + "v", + "w", + "x", + "y", + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + None, + "d", + "e", + "f", + "g", + None, + "i", + "j", + "k", + "l", + "m", + None, + "o", + None, + "s", + "t", + "u", + "v", + "w", + "x", + "y", + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "ı", + "ȷ", + "ss", + None, + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "θ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∇", + "α", + "β", + "γ", + "δ", + "ε", + "ζ", + "η", + "θ", + "ι", + "κ", + "λ", + "μ", + "ν", + "ξ", + "ο", + "π", + "ρ", + "σ", + "τ", + "υ", + "φ", + "χ", + "ψ", + "ω", + "∂", + "ε", + "θ", + "κ", + "φ", + "ρ", + "π", + "ϝ", + None, + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𝽁", + None, + "𝽉", + None, + "𝽋", + None, + "𝽎", + None, + "𝽒", + None, + "𝽩", + None, + "𝽫", + None, + "𝽭", + None, + "𝽯", + None, + "𝽳", + None, + "𝽵", + None, + "𝽷", + None, + "𝽹", + None, + "𝽻", + None, + "𝽽", + None, + "𝽿", + None, + None, + None, + "ss", + None, + None, + "𝽗", + "𝽘", + "𝽙", + "ɣ", + "ᴘ", + "ƀ", + "đ", + "ǥ", + "ł", + "ƚ", + "𝽐", + "𝼾", + "ɉ", + "ᵿ", + "𝼿", + "ƞ", + "ɼ", + "ȸ", + "ȹ", + "𝼫", + "𝼙", + "ʆ", + "ᶘ", + "𝼬", + "𝼜", + "ʓ", + "ᶚ", + "ᴅ", + "ᴀ", + "ᴇ", + "ɿ", + "ʅ", + "ʮ", + "ʯ", + "ȡ", + "ȴ", + "ȵ", + "ȶ", + "ψ", + "ω", + "ᶁ", + "ꞕ", + "ᶇ", + "ᶊ", + "ᶎ", + "ƈ", + "ƙ", + "ƥ", + "ʠ", + "ƭ", + "𝼉", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "а", + "б", + "в", + "г", + "д", + "е", + "ж", + "з", + "и", + "к", + "л", + "м", + "о", + "п", + "р", + "с", + "т", + "у", + "ф", + "х", + "ц", + "ч", + "ш", + "ы", + "э", + "ю", + "ꚉ", + "ә", + "і", + "ј", + "ө", + "ү", + "ӏ", + "а", + "б", + "в", + "г", + "д", + "е", + "ж", + "з", + "и", + "к", + "л", + "о", + "п", + "с", + "у", + "ф", + "х", + "ц", + "ч", + "ш", + "ъ", + "ы", + "ґ", + "і", + "ѕ", + "џ", + "ҫ", + "ꙑ", + "ұ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "𞤢", + "𞤣", + "𞤤", + "𞤥", + "𞤦", + "𞤧", + "𞤨", + "𞤩", + "𞤪", + "𞤫", + "𞤬", + "𞤭", + "𞤮", + "𞤯", + "𞤰", + "𞤱", + "𞤲", + "𞤳", + "𞤴", + "𞤵", + "𞤶", + "𞤷", + "𞤸", + "𞤹", + "𞤺", + "𞤻", + "𞤼", + "𞤽", + "𞤾", + "𞤿", + "𞥀", + "𞥁", + "𞥂", + "𞥃", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "ا", + "ب", + "ج", + "د", + None, + "و", + "ز", + "ح", + "ط", + "ي", + "ك", + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + "ر", + "ش", + "ت", + "ث", + "خ", + "ذ", + "ض", + "ظ", + "غ", + "ٮ", + "ں", + "ڡ", + "ٯ", + None, + "ب", + "ج", + None, + "ه", + None, + "ح", + None, + "ي", + "ك", + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + None, + "ش", + "ت", + "ث", + "خ", + None, + "ض", + None, + "غ", + None, + "ج", + None, + "ح", + None, + "ي", + None, + "ل", + None, + "ن", + "س", + "ع", + None, + "ص", + "ق", + None, + "ش", + None, + "خ", + None, + "ض", + None, + "غ", + None, + "ں", + None, + "ٯ", + None, + "ب", + "ج", + None, + "ه", + None, + "ح", + "ط", + "ي", + "ك", + None, + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + None, + "ش", + "ت", + "ث", + "خ", + None, + "ض", + "ظ", + "غ", + "ٮ", + None, + "ڡ", + None, + "ا", + "ب", + "ج", + "د", + "ه", + "و", + "ز", + "ح", + "ط", + "ي", + None, + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + "ر", + "ش", + "ت", + "ث", + "خ", + "ذ", + "ض", + "ظ", + "غ", + None, + "ب", + "ج", + "د", + None, + "و", + "ز", + "ح", + "ط", + "ي", + None, + "ل", + "م", + "ن", + "س", + "ع", + "ف", + "ص", + "ق", + "ر", + "ش", + "ت", + "ث", + "خ", + "ذ", + "ض", + "ظ", + "غ", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "0,", + "1,", + "2,", + "3,", + "4,", + "5,", + "6,", + "7,", + "8,", + "9,", + None, + "(a)", + "(b)", + "(c)", + "(d)", + "(e)", + "(f)", + "(g)", + "(h)", + "(i)", + "(j)", + "(k)", + "(l)", + "(m)", + "(n)", + "(o)", + "(p)", + "(q)", + "(r)", + "(s)", + "(t)", + "(u)", + "(v)", + "(w)", + "(x)", + "(y)", + "(z)", + "〔s〕", + "c", + "r", + "cd", + "wz", + None, + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "hv", + "mv", + "sd", + "ss", + "ppv", + "wc", + None, + "mc", + "md", + "mr", + None, + "dj", + None, + None, + None, + "ほか", + "ココ", + "サ", + None, + "手", + "字", + "双", + "デ", + "二", + "多", + "解", + "天", + "交", + "映", + "無", + "料", + "前", + "後", + "再", + "新", + "初", + "終", + "生", + "販", + "声", + "吹", + "演", + "投", + "捕", + "一", + "三", + "遊", + "左", + "中", + "右", + "指", + "走", + "打", + "禁", + "空", + "合", + "満", + "有", + "月", + "申", + "割", + "営", + "配", + None, + "〔本〕", + "〔三〕", + "〔二〕", + "〔安〕", + "〔点〕", + "〔打〕", + "〔盗〕", + "〔勝〕", + "〔敗〕", + None, + "得", + "可", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + "丽", + "丸", + "乁", + "𠄢", + "你", + "侮", + "侻", + "倂", + "偺", + "備", + "僧", + "像", + "㒞", + "𠘺", + "免", + "兔", + "兤", + "具", + "𠔜", + "㒹", + "內", + "再", + "𠕋", + "冗", + "冤", + "仌", + "冬", + "况", + "𩇟", + "凵", + "刃", + "㓟", + "刻", + "剆", + "割", + "剷", + "㔕", + "勇", + "勉", + "勤", + "勺", + "包", + "匆", + "北", + "卉", + "卑", + "博", + "即", + "卽", + "卿", + "𠨬", + "灰", + "及", + "叟", + "𠭣", + "叫", + "叱", + "吆", + "咞", + "吸", + "呈", + "周", + "咢", + "哶", + "唐", + "啓", + "啣", + "善", + "喙", + "喫", + "喳", + "嗂", + "圖", + "嘆", + "圗", + "噑", + "噴", + "切", + "壮", + "城", + "埴", + "堍", + "型", + "堲", + "報", + "墬", + "𡓤", + "売", + "壷", + "夆", + "多", + "夢", + "奢", + "𡚨", + "𡛪", + "姬", + "娛", + "娧", + "姘", + "婦", + "㛮", + "㛼", + "嬈", + "嬾", + "𡧈", + "寃", + "寘", + "寧", + "寳", + "𡬘", + "寿", + "将", + "当", + "尢", + "㞁", + "屠", + "屮", + "峀", + "岍", + "𡷤", + "嵃", + "𡷦", + "嵮", + "嵫", + "嵼", + "巡", + "巢", + "㠯", + "巽", + "帨", + "帽", + "幩", + "㡢", + "𢆃", + "㡼", + "庰", + "庳", + "庶", + "廊", + "𪎒", + "廾", + "𢌱", + "舁", + "弢", + "㣇", + "𣊸", + "𦇚", + "形", + "彫", + "㣣", + "徚", + "忍", + "志", + "忹", + "悁", + "㤺", + "㤜", + "悔", + "𢛔", + "惇", + "慈", + "慌", + "慎", + "慌", + "慺", + "憎", + "憲", + "憤", + "憯", + "懞", + "懲", + "懶", + "成", + "戛", + "扝", + "抱", + "拔", + "捐", + "𢬌", + "挽", + "拼", + "捨", + "掃", + "揤", + "𢯱", + "搢", + "揅", + "掩", + "㨮", + "摩", + "摾", + "撝", + "摷", + "㩬", + "敏", + "敬", + "𣀊", + "旣", + "書", + "晉", + "㬙", + "暑", + "㬈", + "㫤", + "冒", + "冕", + "最", + "暜", + "肭", + "䏙", + "朗", + "望", + "朡", + "杞", + "杓", + "𣏃", + "㭉", + "柺", + "枅", + "桒", + "梅", + "𣑭", + "梎", + "栟", + "椔", + "㮝", + "楂", + "榣", + "槪", + "檨", + "𣚣", + "櫛", + "㰘", + "次", + "𣢧", + "歔", + "㱎", + "歲", + "殟", + "殺", + "殻", + "𣪍", + "𡴋", + "𣫺", + "汎", + "𣲼", + "沿", + "泍", + "汧", + "洖", + "派", + "海", + "流", + "浩", + "浸", + "涅", + "𣴞", + "洴", + "港", + "湮", + "㴳", + "滋", + "滇", + "𣻑", + "淹", + "潮", + "𣽞", + "𣾎", + "濆", + "瀹", + "瀞", + "瀛", + "㶖", + "灊", + "災", + "灷", + "炭", + "𠔥", + "煅", + "𤉣", + "熜", + "𤎫", + "爨", + "爵", + "牐", + "𤘈", + "犀", + "犕", + "𤜵", + "𤠔", + "獺", + "王", + "㺬", + "玥", + "㺸", + "瑇", + "瑜", + "瑱", + "璅", + "瓊", + "㼛", + "甤", + "𤰶", + "甾", + "𤲒", + "異", + "𢆟", + "瘐", + "𤾡", + "𤾸", + "𥁄", + "㿼", + "䀈", + "直", + "𥃳", + "𥃲", + "𥄙", + "𥄳", + "眞", + "真", + "睊", + "䀹", + "瞋", + "䁆", + "䂖", + "𥐝", + "硎", + "碌", + "磌", + "䃣", + "𥘦", + "祖", + "𥚚", + "𥛅", + "福", + "秫", + "䄯", + "穀", + "穊", + "穏", + "𥥼", + "𥪧", + "竮", + "䈂", + "𥮫", + "篆", + "築", + "䈧", + "𥲀", + "糒", + "䊠", + "糨", + "糣", + "紀", + "𥾆", + "絣", + "䌁", + "緇", + "縂", + "繅", + "䌴", + "𦈨", + "𦉇", + "䍙", + "𦋙", + "罺", + "𦌾", + "羕", + "翺", + "者", + "𦓚", + "𦔣", + "聠", + "𦖨", + "聰", + "𣍟", + "䏕", + "育", + "脃", + "䐋", + "脾", + "媵", + "𦞧", + "𦞵", + "𣎓", + "𣎜", + "舁", + "舄", + "辞", + "䑫", + "芑", + "芋", + "芝", + "劳", + "花", + "芳", + "芽", + "苦", + "𦬼", + "若", + "茝", + "荣", + "莭", + "茣", + "莽", + "菧", + "著", + "荓", + "菊", + "菌", + "菜", + "𦰶", + "𦵫", + "𦳕", + "䔫", + "蓱", + "蓳", + "蔖", + "𧏊", + "蕤", + "𦼬", + "䕝", + "䕡", + "𦾱", + "𧃒", + "䕫", + "虐", + "虜", + "虧", + "虩", + "蚩", + "蚈", + "蜎", + "蛢", + "蝹", + "蜨", + "蝫", + "螆", + "䗗", + "蟡", + "蠁", + "䗹", + "衠", + "衣", + "𧙧", + "裗", + "裞", + "䘵", + "裺", + "㒻", + "𧢮", + "𧥦", + "䚾", + "䛇", + "誠", + "諭", + "變", + "豕", + "𧲨", + "貫", + "賁", + "贛", + "起", + "𧼯", + "𠠄", + "跋", + "趼", + "跰", + "𠣞", + "軔", + "輸", + "𨗒", + "𨗭", + "邔", + "郱", + "鄑", + "𨜮", + "鄛", + "鈸", + "鋗", + "鋘", + "鉼", + "鏹", + "鐕", + "𨯺", + "開", + "䦕", + "閷", + "𨵷", + "䧦", + "雃", + "嶲", + "霣", + "𩅅", + "𩈚", + "䩮", + "䩶", + "韠", + "𩐊", + "䪲", + "𩒖", + "頋", + "頩", + "𩖶", + "飢", + "䬳", + "餩", + "馧", + "駂", + "駾", + "䯎", + "𩬰", + "鬒", + "鱀", + "鳽", + "䳎", + "䳭", + "鵧", + "𪃎", + "䳸", + "𪄅", + "𪈎", + "𪊑", + "麻", + "䵖", + "黹", + "黾", + "鼅", + "鼏", + "鼖", + "鼻", + "𪘀", + None, + None, + None, + None, + None, + None, + None, + None, + None, +) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py new file mode 100644 index 00000000000..9bfc71644e8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py @@ -0,0 +1,47 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +""" +The OpenTelemetry logging API describes the classes used to generate logs and events. + +The :class:`.LoggerProvider` provides users access to the :class:`.Logger`. + +This module provides abstract (i.e. unimplemented) classes required for +logging, and a concrete no-op implementation :class:`.NoOpLogger` that allows applications +to use the API package alone without a supporting implementation. + +To get a logger, you need to provide the package name from which you are +calling the logging APIs to OpenTelemetry by calling `LoggerProvider.get_logger` +with the calling module name and the version of your package. + +The following code shows how to obtain a logger using the global :class:`.LoggerProvider`:: + + from opentelemetry._logs import get_logger + + logger = get_logger("example-logger") + +.. versionadded:: 1.15.0 +""" + +from opentelemetry.agent._vendor.opentelemetry._logs._internal import ( + Logger, + LoggerProvider, + LogRecord, + NoOpLogger, + NoOpLoggerProvider, + get_logger, + get_logger_provider, + set_logger_provider, +) +from opentelemetry.agent._vendor.opentelemetry._logs.severity import SeverityNumber + +__all__ = [ + "LogRecord", + "Logger", + "LoggerProvider", + "NoOpLogger", + "NoOpLoggerProvider", + "SeverityNumber", + "get_logger", + "get_logger_provider", + "set_logger_provider", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py new file mode 100644 index 00000000000..da2c77dbfc6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py @@ -0,0 +1,484 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +""" +The OpenTelemetry logging API describes the classes used to generate logs and events. + +The :class:`.LoggerProvider` provides users access to the :class:`.Logger`. + +This module provides abstract (i.e. unimplemented) classes required for +logging, and a concrete no-op implementation :class:`.NoOpLogger` that allows applications +to use the API package alone without a supporting implementation. + +To get a logger, you need to provide the package name from which you are +calling the logging APIs to OpenTelemetry by calling `LoggerProvider.get_logger` +with the calling module name and the version of your package. + +The following code shows how to obtain a logger using the global :class:`.LoggerProvider`:: + + from opentelemetry._logs import get_logger + + logger = get_logger("example-logger") + +.. versionadded:: 1.15.0 +""" + +from __future__ import annotations + +from abc import ABC, abstractmethod +from logging import getLogger +from os import environ +from time import time_ns +from typing import cast, overload + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry._logs.severity import SeverityNumber +from opentelemetry.agent._vendor.opentelemetry.context import get_current +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.environment_variables import _OTEL_PYTHON_LOGGER_PROVIDER +from opentelemetry.agent._vendor.opentelemetry.trace import get_current_span +from opentelemetry.agent._vendor.opentelemetry.trace.span import TraceFlags +from opentelemetry.agent._vendor.opentelemetry.util._once import Once +from opentelemetry.agent._vendor.opentelemetry.util._providers import _load_provider +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes + +_logger = getLogger(__name__) + + +class LogRecord(ABC): + """A LogRecord instance represents an event being logged. + + LogRecord instances are created and emitted via `Logger` + every time something is logged. They contain all the information + pertinent to the event being logged. + """ + + @overload + def __init__( + self, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_text: str | None = None, + severity_number: SeverityNumber | None = None, + body: AnyValue = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: ... + + @overload + @deprecated( + "LogRecord init with `trace_id`, `span_id`, and/or `trace_flags` is deprecated since 1.35.0. Use `context` instead." + ) + def __init__( + self, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + trace_id: int | None = None, + span_id: int | None = None, + trace_flags: TraceFlags | None = None, + severity_text: str | None = None, + severity_number: SeverityNumber | None = None, + body: AnyValue = None, + attributes: Attributes = None, + ) -> None: ... + + def __init__( + self, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + trace_id: int | None = None, + span_id: int | None = None, + trace_flags: TraceFlags | None = None, + severity_text: str | None = None, + severity_number: SeverityNumber | None = None, + body: AnyValue = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: + if not context: + context = get_current() + span_context = get_current_span(context).get_span_context() + self.timestamp = timestamp + if observed_timestamp is None: + observed_timestamp = time_ns() + self.observed_timestamp = observed_timestamp + self.context = context + self.trace_id = trace_id or span_context.trace_id + self.span_id = span_id or span_context.span_id + self.trace_flags = trace_flags or span_context.trace_flags + self.severity_text = severity_text + self.severity_number = severity_number + self.body = body + self.attributes = attributes + self.event_name = event_name + self.exception = exception + + +class Logger(ABC): + """Handles emitting events and logs via `LogRecord`.""" + + def __init__( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> None: + super().__init__() + self._name = name + self._version = version + self._schema_url = schema_url + self._attributes = attributes + + @overload + def emit( + self, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: ... + + @overload + def emit( + self, + record: LogRecord, + ) -> None: ... + + @abstractmethod + def emit( + self, + record: LogRecord | None = None, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: + """Emits a :class:`LogRecord` representing a log to the processing pipeline.""" + + @abstractmethod + def enabled( + self, + *, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + event_name: str | None = None, + ) -> bool: + """Returns whether the logger is enabled for the given arguments. + + Instrumentation should call this before performing expensive work to + construct a log record, and skip that work if ``False`` is returned. + + The returned value may change over time and should be checked each time + before emitting a log record. + """ + + +class NoOpLogger(Logger): + """The default Logger used when no Logger implementation is available. + + All operations are no-op. + """ + + @overload + def emit( + self, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: ... + + @overload + def emit( # pylint:disable=arguments-differ + self, + record: LogRecord, + ) -> None: ... + + def emit( + self, + record: LogRecord | None = None, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: + pass + + def enabled( + self, + *, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + event_name: str | None = None, + ) -> bool: + return False + + +class ProxyLogger(Logger): + def __init__( # pylint: disable=super-init-not-called + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ): + self._name = name + self._version = version + self._schema_url = schema_url + self._attributes = attributes + self._real_logger: Logger | None = None + self._noop_logger = NoOpLogger(name) + + @property + def _logger(self) -> Logger: + if self._real_logger: + return self._real_logger + + if _LOGGER_PROVIDER: + self._real_logger = _LOGGER_PROVIDER.get_logger( + self._name, + self._version, + self._schema_url, + self._attributes, + ) + return self._real_logger + return self._noop_logger + + @overload + def emit( + self, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: ... + + @overload + def emit( # pylint:disable=arguments-differ + self, + record: LogRecord, + ) -> None: ... + + def emit( + self, + record: LogRecord | None = None, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: + if record: + self._logger.emit(record) + else: + self._logger.emit( + timestamp=timestamp, + observed_timestamp=observed_timestamp, + context=context, + severity_number=severity_number, + severity_text=severity_text, + body=body, + attributes=attributes, + event_name=event_name, + exception=exception, + ) + + def enabled( + self, + *, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + event_name: str | None = None, + ) -> bool: + return self._logger.enabled( + context=context, + severity_number=severity_number, + event_name=event_name, + ) + + +class LoggerProvider(ABC): + """ + LoggerProvider is the entry point of the API. It provides access to Logger instances. + """ + + @abstractmethod + def get_logger( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> Logger: + """Returns a `Logger` for use by the given instrumentation library. + + For any two calls with identical parameters, it is undefined whether the same + or different `Logger` instances are returned. + + This function may return different `Logger` types (e.g. a no-op logger + vs. a functional logger). + + Args: + name: The name of the instrumenting module, package or class. + This should *not* be the name of the module, package or class that is + instrumented but the name of the code doing the instrumentation. + E.g., instead of ``"requests"``, use + ``"opentelemetry.instrumentation.requests"``. + + For log sources which define a logger name (e.g. logging.Logger.name) + the Logger Name should be recorded as the instrumentation scope name. + + version: Optional. The version string of the + instrumenting library. Usually this should be the same as + ``importlib.metadata.version(instrumenting_library_name)``. + + schema_url: Optional. Specifies the Schema URL of the emitted telemetry. + + attributes: Optional. Specifies the instrumentation scope attributes to + associate with emitted telemetry. + """ + + +class NoOpLoggerProvider(LoggerProvider): + """The default LoggerProvider used when no LoggerProvider implementation is available.""" + + def get_logger( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> Logger: + """Returns a NoOpLogger.""" + return NoOpLogger(name, version=version, schema_url=schema_url, attributes=attributes) + + +class ProxyLoggerProvider(LoggerProvider): + def get_logger( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> Logger: + if _LOGGER_PROVIDER: + return _LOGGER_PROVIDER.get_logger( + name, + version=version, + schema_url=schema_url, + attributes=attributes, + ) + return ProxyLogger( + name, + version=version, + schema_url=schema_url, + attributes=attributes, + ) + + +_LOGGER_PROVIDER_SET_ONCE = Once() +_LOGGER_PROVIDER: LoggerProvider | None = None +_PROXY_LOGGER_PROVIDER = ProxyLoggerProvider() + + +def get_logger_provider() -> LoggerProvider: + """Gets the current global :class:`~.LoggerProvider` object.""" + global _LOGGER_PROVIDER # pylint: disable=global-variable-not-assigned + if _LOGGER_PROVIDER is None: + if _OTEL_PYTHON_LOGGER_PROVIDER not in environ: + return _PROXY_LOGGER_PROVIDER + + logger_provider: LoggerProvider = _load_provider( # type: ignore + _OTEL_PYTHON_LOGGER_PROVIDER, "logger_provider" + ) + _set_logger_provider(logger_provider, log=False) + + # _LOGGER_PROVIDER will have been set by one thread + return cast("LoggerProvider", _LOGGER_PROVIDER) + + +def _set_logger_provider(logger_provider: LoggerProvider, log: bool) -> None: + def set_lp() -> None: + global _LOGGER_PROVIDER # pylint: disable=global-statement + _LOGGER_PROVIDER = logger_provider + + did_set = _LOGGER_PROVIDER_SET_ONCE.do_once(set_lp) + + if log and not did_set: + _logger.warning("Overriding of current LoggerProvider is not allowed") + + +def set_logger_provider(logger_provider: LoggerProvider) -> None: + """Sets the current global :class:`~.LoggerProvider` object. + + This can only be done once, a warning will be logged if any further attempt + is made. + """ + _set_logger_provider(logger_provider, log=True) + + +def get_logger( + instrumenting_module_name: str, + instrumenting_library_version: str = "", + logger_provider: LoggerProvider | None = None, + schema_url: str | None = None, + attributes: Attributes = None, +) -> Logger: + """Returns a `Logger` for use within a python process. + + This function is a convenience wrapper for + opentelemetry.sdk._logs.LoggerProvider.get_logger. + + If logger_provider param is omitted the current configured one is used. + """ + if logger_provider is None: + logger_provider = get_logger_provider() + return logger_provider.get_logger( + instrumenting_module_name, + instrumenting_library_version, + schema_url, + attributes, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py new file mode 100644 index 00000000000..96ffcc6229e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py @@ -0,0 +1,44 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import enum + + +class SeverityNumber(enum.Enum): + """Numerical value of severity. + + Smaller numerical values correspond to less severe events + (such as debug events), larger numerical values correspond + to more severe events (such as errors and critical events). + + See the `Log Data Model`_ spec for more info and how to map the + severity from source format to OTLP Model. + + .. _Log Data Model: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber + """ + + UNSPECIFIED = 0 + TRACE = 1 + TRACE2 = 2 + TRACE3 = 3 + TRACE4 = 4 + DEBUG = 5 + DEBUG2 = 6 + DEBUG3 = 7 + DEBUG4 = 8 + INFO = 9 + INFO2 = 10 + INFO3 = 11 + INFO4 = 12 + WARN = 13 + WARN2 = 14 + WARN3 = 15 + WARN4 = 16 + ERROR = 17 + ERROR2 = 18 + ERROR3 = 19 + ERROR4 = 20 + FATAL = 21 + FATAL2 = 22 + FATAL3 = 23 + FATAL4 = 24 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py new file mode 100644 index 00000000000..2e5947c315f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py @@ -0,0 +1,243 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pyright: reportUnnecessaryIsInstance=false + +import copy +import logging +import threading +from collections.abc import Mapping, MutableMapping, Sequence +from types import NoneType +from typing import TYPE_CHECKING, Any, overload + +from opentelemetry.agent._vendor.typing_extensions import assert_never, deprecated + +from opentelemetry.agent._vendor.opentelemetry.util import types + +_logger = logging.getLogger(__name__) + + +# Calling str(x) will use an object's `__str__` method if it exists, otherwise it will use it's `__repr__` method. +# If neither is defined it uses the base class's `object.__repr__` method, which returns a string that is hard to understand. +# So in that case we drop the key/value pair. +def _is_non_custom_str(key: Any) -> bool: + return type(key).__str__ is not object.__str__ or type(key).__repr__ is not object.__repr__ + + +@overload +def _clean_attribute_value( + value: Mapping[str, types.AnyValue], + max_string_value_length: int | None, +) -> Mapping[str, types.AnyValue]: ... + + +@overload +def _clean_attribute_value( + value: types.AnyValue, + max_string_value_length: int | None, +) -> types.AnyValue: ... + + +def _clean_attribute_value( + value: types.AnyValue, + max_string_value_length: int | None, +) -> types.AnyValue: + """Recursively checks if an attribute value is valid and cleans it if required. + + String values are truncated to max_string_value_length if provided. + Anything that isn't of `types.AnyValue`, we attempt to cast to `str`. + If this fails, the value is replaced with None. Sequence's are converted to tuples and mappings + are copied into new dicts. + + Returns: + The recursively cleaned AnyValue. + """ + if isinstance(value, (NoneType, bool, int, float, bytes)): + return value + if isinstance(value, str): + if max_string_value_length is not None and len(value) > max_string_value_length: + _logger.warning( + "String attribute value exceeds max length of %d, truncating.", + max_string_value_length, + ) + value = value[:max_string_value_length] + return value + if isinstance(value, Sequence): + return tuple(_clean_attribute_value(v, max_string_value_length) for v in value) + if isinstance(value, Mapping): + cleaned_mapping: dict[str, types.AnyValue] = {} + for key, val in value.items(): + if not key: + _logger.warning( + "invalid attribute key `%s`. must be non-empty string. Dropping key from attributes.", + key, + ) + continue + # Spec says to convert unknown types to strings if possible (here and below too). + if not isinstance(key, str): + _logger.warning( + "Invalid type `%s` for attribute key `%s`, must be a str. Key's `__str__/__repr__` method will be called if it exists, otherwise the key/value pair will be dropped.", + type(key), + key, + ) + if _is_non_custom_str(key): + key = str(key) + else: + continue + cleaned_mapping[key] = _clean_attribute_value(val, max_string_value_length) + return cleaned_mapping + if TYPE_CHECKING: + assert_never(value) + _logger.warning( + "Invalid type `%s` for attribute value. Expected one of bool, str, None, bytes, int, float or a " + "Mapping or Sequence of those types. Value's __str__ method will be called if it exists, otherwise the value will be replaced with None.", + type(value), + ) + if _is_non_custom_str(value): + return str(value) + return None + + +class BoundedAttributes(MutableMapping[str, types.AnyValue]): + """A dict with a fixed max capacity which cleans and potentially drops values to ensure they are valid attribute values. + + Args: + maxlen: The maximum number of attributes to store, use None for no limit. + attributes: The initial attributes to store. + immutable: Defaults to true. Whether to allow adding/removing of attributes after the initialisation of the instance. + max_value_len: The maximum length of string values, use None for no limit. + extended_attributes: Deprecated. Kept for backwards compatibility. Extended attributes are now always used for attributes everywhere. + + When the dict is full and a new element is added, the oldest element is dropped. Attributes are made to be immutable when set in this container. + So passing a mutable list as an attribute value, and then mutating it after will not change it's value in this container. + """ + + @overload + def __init__( + self, + maxlen: int | None = None, + attributes: types.Attributes = None, + immutable: bool = True, + max_value_len: int | None = None, + ) -> None: ... + + @overload + @deprecated( + "Creating BoundedAttributes with `extended_attributes` set is deprecated. " + "The `extended_attributes` param is no longer used and will be removed " + "in a future release. Extended attributes are now always used for attributes everywhere." + ) + def __init__( + self, + maxlen: int | None = None, + attributes: types.Attributes = None, + immutable: bool = True, + max_value_len: int | None = None, + extended_attributes: bool = False, + ) -> None: ... + + def __init__( + self, + maxlen: int | None = None, + attributes: types.Attributes = None, + immutable: bool = True, + max_value_len: int | None = None, + extended_attributes: bool = False, + ) -> None: + if maxlen is not None and maxlen < 0: + raise ValueError("maxlen must be valid int greater or equal to 0") + if max_value_len is not None and max_value_len < 0: + raise ValueError("max_value_len must be valid int greater or equal to 0") + self._dict: dict[str, types.AnyValue] = {} + self.maxlen = maxlen + self.dropped = 0 + self.max_value_len = max_value_len + self._lock = threading.Lock() + # setting False before adding items + self._immutable = False + if attributes: + self._set_items(attributes) + self._immutable = immutable + + def __repr__(self) -> str: + return f"{dict(self._dict)}" + + def __getitem__(self, key: str) -> types.AnyValue: + return self._dict[key] + + def _raise_if_immutable(self) -> None: + if self._immutable: + raise TypeError("Cannot mutate immutable BoundedAttributes") + + def __setitem__(self, key: str, value: types.AnyValue) -> None: + self._raise_if_immutable() + if self.maxlen is not None and self.maxlen == 0: + with self._lock: + self.dropped += 1 + return + if not key or not isinstance(key, str): + _logger.warning( + "invalid key `%s`. must be non-empty string. Dropping key from attributes.", + key, + ) + with self._lock: + self.dropped += 1 + return + cleaned = _clean_attribute_value(value, self.max_value_len) + with self._lock: + self._setitem_locked(key, cleaned) + + def _set_items(self, attributes: Mapping[str, types.AnyValue]) -> None: + self._raise_if_immutable() + if self.maxlen is not None and self.maxlen == 0: + with self._lock: + self.dropped += len(attributes) + return + cleaned_attributes: Mapping[str, types.AnyValue] = _clean_attribute_value(attributes, self.max_value_len) + with self._lock: + self.dropped += len(attributes) - len(cleaned_attributes) + for key, value in cleaned_attributes.items(): + self._setitem_locked(key, value) + + def _setitem_locked(self, key: str, value: types.AnyValue) -> None: + if key in self._dict: + del self._dict[key] + if self.maxlen is not None and len(self._dict) >= self.maxlen: + _logger.warning( + "Attributes dict is full. Dropping the oldest key-value pair from attributes to make space for the new key-value pair.", + ) + # Dictionaries are insertion ordered in Python, this is the recommended way to get the oldest value. + del self._dict[next(iter(self._dict.keys()))] + self.dropped += 1 + + self._dict[key] = value + + def __delitem__(self, key: str) -> None: + self._raise_if_immutable() + del self._dict[key] + + def __iter__(self): + if self._immutable: + return iter(self._dict) + with self._lock: + return iter(list(self._dict)) + + def __len__(self) -> int: + return len(self._dict) + + def __deepcopy__(self, memo: dict[int, Any]) -> "BoundedAttributes": + copy_ = BoundedAttributes( + maxlen=self.maxlen, + immutable=self._immutable, + max_value_len=self.max_value_len, + ) + memo[id(self)] = copy_ + with self._lock: + # Assign _dict directly to avoid re-cleaning already clean values + # and to bypass the immutability guard in __setitem__ + copy_._dict = copy.deepcopy(self._dict, memo) + copy_.dropped = self.dropped + return copy_ + + def copy(self) -> MutableMapping[str, types.AnyValue]: + return self._dict.copy() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py new file mode 100644 index 00000000000..7e72d68e514 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py @@ -0,0 +1,122 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from collections.abc import Mapping +from logging import getLogger +from re import compile +from types import MappingProxyType + +from opentelemetry.agent._vendor.opentelemetry.context import create_key, get_value, set_value +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.util.re import ( + _BAGGAGE_PROPERTY_FORMAT, + _KEY_FORMAT, + _VALUE_FORMAT, +) + +_BAGGAGE_KEY = create_key("baggage") +_logger = getLogger(__name__) + +_KEY_PATTERN = compile(_KEY_FORMAT) +_VALUE_PATTERN = compile(_VALUE_FORMAT) +_PROPERT_PATTERN = compile(_BAGGAGE_PROPERTY_FORMAT) + + +def get_all( + context: Context | None = None, +) -> Mapping[str, object]: + """Returns the name/value pairs in the Baggage + + Args: + context: The Context to use. If not set, uses current Context + + Returns: + The name/value pairs in the Baggage + """ + return MappingProxyType(_get_baggage_value(context=context)) + + +def get_baggage(name: str, context: Context | None = None) -> object | None: + """Provides access to the value for a name/value pair in the + Baggage + + Args: + name: The name of the value to retrieve + context: The Context to use. If not set, uses current Context + + Returns: + The value associated with the given name, or null if the given name is + not present. + """ + return _get_baggage_value(context=context).get(name) + + +def set_baggage(name: str, value: object, context: Context | None = None) -> Context: + """Sets a value in the Baggage + + Args: + name: The name of the value to set + value: The value to set + context: The Context to use. If not set, uses current Context + + Returns: + A Context with the value updated + """ + baggage = _get_baggage_value(context=context).copy() + baggage[name] = value + return set_value(_BAGGAGE_KEY, baggage, context=context) + + +def remove_baggage(name: str, context: Context | None = None) -> Context: + """Removes a value from the Baggage + + Args: + name: The name of the value to remove + context: The Context to use. If not set, uses current Context + + Returns: + A Context with the name/value removed + """ + baggage = _get_baggage_value(context=context).copy() + baggage.pop(name, None) + + return set_value(_BAGGAGE_KEY, baggage, context=context) + + +def clear(context: Context | None = None) -> Context: + """Removes all values from the Baggage + + Args: + context: The Context to use. If not set, uses current Context + + Returns: + A Context with all baggage entries removed + """ + return set_value(_BAGGAGE_KEY, {}, context=context) + + +def _get_baggage_value(context: Context | None = None) -> dict[str, object]: + baggage = get_value(_BAGGAGE_KEY, context=context) + if isinstance(baggage, dict): + return baggage + return {} + + +def _is_valid_key(name: str) -> bool: + return _KEY_PATTERN.fullmatch(str(name)) is not None + + +def _is_valid_value(value: object) -> bool: + parts = str(value).split(";") + # W3C Baggage allows optional whitespace between the value and ";" + is_valid_value = _VALUE_PATTERN.fullmatch(parts[0].rstrip(" \t")) is not None + if len(parts) > 1: # one or more properties metadata + for property in parts[1:]: + if _PROPERT_PATTERN.fullmatch(property) is None: + is_valid_value = False + break + return is_valid_value + + +def _is_valid_pair(key: str, value: str) -> bool: + return _is_valid_key(key) and _is_valid_value(value) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py new file mode 100644 index 00000000000..a314415242c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py @@ -0,0 +1,179 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# +from collections.abc import Iterable, Iterator, Mapping +from logging import getLogger +from re import split +from urllib.parse import quote_plus, unquote_plus + +from opentelemetry.agent._vendor.opentelemetry.baggage import _is_valid_pair, get_all, set_baggage +from opentelemetry.agent._vendor.opentelemetry.context import get_current +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.propagators import textmap +from opentelemetry.agent._vendor.opentelemetry.util.re import _DELIMITER_PATTERN + +_logger = getLogger(__name__) + + +def _filter_valid_entries( + entries: Iterable[str], + max_pair_length: int, +) -> Iterator[str]: + for entry in entries: + if not entry: + continue + if not entry.isascii(): + _logger.warning( + "Baggage entry with key `%s` contains non-ASCII characters", + entry.split("=", 1)[0], + ) + continue + if len(entry) > max_pair_length: + _logger.warning( + "Baggage entry with key `%s` exceeded the maximum number of bytes per list-member with length %d", + entry.split("=", 1)[0], + len(entry), + ) + continue + yield entry + + +def _apply_baggage_limits( + entries: Iterable[str], + max_pairs: int, + max_pair_length: int, + max_header_length: int, +) -> Iterator[str]: + """Apply W3C Baggage size limits to a sequence of baggage entries. + + Yields entries that fit within the W3C specification limits. + Logs warnings when entries are dropped. + """ + length = 0 + for index, entry in enumerate(_filter_valid_entries(entries, max_pair_length)): + if index >= max_pairs: + _logger.warning("Baggage exceeded the maximum number of list-members") + return + + length += (1 if index > 0 else 0) + len(entry) + if length > max_header_length: + _logger.warning("Baggage exceeded the maximum number of bytes per baggage-string") + return + yield entry + + +class W3CBaggagePropagator(textmap.TextMapPropagator): + """Extracts and injects Baggage which is used to annotate telemetry.""" + + _MAX_HEADER_LENGTH = 8192 + _MAX_PAIR_LENGTH = 4096 + _MAX_PAIRS = 180 + _BAGGAGE_HEADER_NAME = "baggage" + + def extract( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, + ) -> Context: + """Extract Baggage from the carrier. + + See + `opentelemetry.propagators.textmap.TextMapPropagator.extract` + """ + + if context is None: + context = get_current() + + header = _extract_first_element(getter.get(carrier, self._BAGGAGE_HEADER_NAME)) + + if not header: + return context + + if len(header.encode()) > self._MAX_HEADER_LENGTH: + _logger.warning( + "Baggage header `%s` exceeded the maximum number of bytes per baggage-string", + header, + ) + return context + + baggage_entries = split(_DELIMITER_PATTERN, header) + + for entry in _apply_baggage_limits( + baggage_entries, + max_pairs=self._MAX_PAIRS, + max_pair_length=self._MAX_PAIR_LENGTH, + max_header_length=self._MAX_HEADER_LENGTH, + ): + try: + name, value = entry.split("=", 1) + except Exception: # pylint: disable=broad-exception-caught + _logger.warning("Baggage list-member `%s` doesn't match the format", entry) + continue + + # W3C Baggage allows optional whitespace around "=" + name = name.strip(" \t") + value = value.strip(" \t") + + if not _is_valid_pair(name, value): + _logger.warning("Invalid baggage entry: `%s`", entry) + continue + + name = unquote_plus(name).strip() + value = unquote_plus(value).strip() + + context = set_baggage( + name, + value, + context=context, + ) + + return context + + def inject( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, + ) -> None: + """Injects Baggage into the carrier. + + See + `opentelemetry.propagators.textmap.TextMapPropagator.inject` + """ + baggage_entries = get_all(context=context) + if not baggage_entries: + return + + baggage_string = ",".join( + _apply_baggage_limits( + _encode_baggage_pairs(baggage_entries), + max_pairs=self._MAX_PAIRS, + max_pair_length=self._MAX_PAIR_LENGTH, + max_header_length=self._MAX_HEADER_LENGTH, + ) + ) + + if baggage_string: + setter.set(carrier, self._BAGGAGE_HEADER_NAME, baggage_string) + + @property + def fields(self) -> set[str]: + """Returns a set with the fields set in `inject`.""" + return {self._BAGGAGE_HEADER_NAME} + + +def _encode_baggage_pairs( + baggage_entries: Mapping[str, object], +) -> Iterator[str]: + """Yield URL-encoded 'key=value' pairs from baggage entries.""" + for key, value in baggage_entries.items(): + yield quote_plus(str(key)) + "=" + quote_plus(str(value)) + + +def _extract_first_element( + items: Iterable[textmap.CarrierT] | None, +) -> textmap.CarrierT | None: + if items is None: + return None + return next(iter(items), None) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md new file mode 100644 index 00000000000..b6c4ffb922f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md @@ -0,0 +1,30 @@ +# SDK Declarative Configuration + +This package implements [OpenTelemetry file-based configuration](https://opentelemetry.io/docs/specs/otel/configuration). + +## Files + +- `schema.json`: vendored copy of the [OpenTelemetry configuration JSON schema](https://github.com/open-telemetry/opentelemetry-configuration) +- `models.py`: Python dataclasses generated from `schema.json` by [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator), using a custom template from `opentelemetry-configuration/codegen/` (see that directory's README for details) + +## Spec conformance + +Which fields of the configuration schema the Python SDK actually applies at runtime is tracked in the shared [language support status matrix](https://github.com/open-telemetry/opentelemetry-configuration/blob/main/language-support-status.md#python) in the `opentelemetry-configuration` repository. The Python column is the source of truth; update [`schema/meta_schema_language_python.yaml`](https://github.com/open-telemetry/opentelemetry-configuration/blob/main/schema/meta_schema_language_python.yaml) there when wiring lands or changes, and the matrix regenerates. + +## Updating the schema + +1. Pick the desired release tag from the [opentelemetry-configuration releases](https://github.com/open-telemetry/opentelemetry-configuration/releases) and overwrite `opentelemetry-configuration/src/opentelemetry/configuration/schema.json` with the `opentelemetry_configuration.json` published on that release. + +2. Regenerate `models.py`: + + ```sh + tox -e generate-config-from-jsonschema + ``` + +3. Bump `_SUPPORTED_SCHEMA_MAJOR` / `_SUPPORTED_SCHEMA_MINOR` in `file/_loader.py` to the version of the vendored schema. + +4. Update any version string references in tests and source: + + ```sh + grep -r "OLD_VERSION" opentelemetry-configuration/ + ``` diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py new file mode 100644 index 00000000000..320b8ad5d89 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py @@ -0,0 +1,44 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""OpenTelemetry SDK Declarative Configuration. + +This package implements the OpenTelemetry declarative configuration +specification for the Python SDK. Load a YAML or JSON configuration file +(or build a configuration model programmatically) and apply it to the +process-global SDK providers. + +The standard activation path is the ``OTEL_CONFIG_FILE`` environment +variable, which the SDK's configurator picks up automatically. For +programmatic use: + +>>> from opentelemetry.configuration import ( +... load_config_file, +... configure_sdk, +... ) +>>> config = load_config_file("otel-config.yaml") +>>> configure_sdk(config) + +Construct a configuration programmatically and apply it: + +>>> from opentelemetry.configuration import ( +... OpenTelemetryConfiguration, +... configure_sdk, +... ) +>>> configure_sdk(OpenTelemetryConfiguration(file_format="1.0-rc.1")) + +This package is **experimental**. The API surface, type names, and +behaviour may change between minor versions. +""" + +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ConfigurationError +from opentelemetry.agent._vendor.opentelemetry.configuration._sdk import configure_sdk +from opentelemetry.agent._vendor.opentelemetry.configuration.file._loader import load_config_file +from opentelemetry.agent._vendor.opentelemetry.configuration.models import OpenTelemetryConfiguration + +__all__ = [ + "ConfigurationError", + "OpenTelemetryConfiguration", + "configure_sdk", + "load_config_file", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py new file mode 100644 index 00000000000..b5706dcc148 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py @@ -0,0 +1,228 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import dataclasses +import inspect +import logging +from collections.abc import Callable +from typing import Any, Protocol +from urllib.parse import urlparse + +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ConfigurationError +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points + +_logger = logging.getLogger(__name__) + + +def _additional_properties(cls): + """Decorator for dataclasses whose JSON Schema sets additionalProperties. + + Wraps the dataclass-generated ``__init__`` so that extra keyword + arguments are captured into an ``additional_properties`` instance + attribute instead of raising ``TypeError``. This lets user-defined + component names flow through the config pipeline without modifying + the codegen output for built-in fields. + + Applied automatically by the custom template in ``opentelemetry-sdk/codegen/`` + when ``additionalPropertiesType`` is present in the template context + (set by ``datamodel-codegen`` for schema types with ``additionalProperties``). + """ + original_init = cls.__init__ + original_sig = inspect.signature(original_init) + known_fields = frozenset(f.name for f in dataclasses.fields(cls)) + + def _init(self, **kwargs): + known = {k: v for k, v in kwargs.items() if k in known_fields} + extra = {k: v for k, v in kwargs.items() if k not in known_fields} + original_init(self, **known) + self.additional_properties = extra + + # Preserve the original parameter list for IDE autocompletion and + # inspect.signature(), adding **kwargs to signal extras are accepted. + # setattr used because pyright rejects direct __signature__ assignment. + params = list(original_sig.parameters.values()) + params.append(inspect.Parameter("kwargs", inspect.Parameter.VAR_KEYWORD)) + setattr(_init, "__signature__", original_sig.replace(parameters=params)) # noqa: B010 + + cls.__init__ = _init + return cls + + +def load_entry_point(group: str, name: str) -> type: + """Load a plugin class from an entry point group by name. + + Returns the loaded class — callers are responsible for instantiation + with whatever arguments their config requires. + + Raises: + ConfigurationError: If the entry point is not found or fails to load. + """ + try: + ep = next(iter(entry_points(group=group, name=name)), None) + if ep is None: + raise ConfigurationError( + f"Plugin '{name}' not found in group '{group}'. " + "Make sure the package providing this plugin is installed." + ) + return ep.load() + except ConfigurationError: + raise + except Exception as exc: + raise ConfigurationError(f"Failed to load plugin '{name}' from group '{group}': {exc}") from exc + + +class _ComponentConfig(Protocol): + """Protocol for config dataclasses decorated with @_additional_properties. + + Values in ``additional_properties`` are nested config dicts (suitable + for ``**kwargs`` splatting to the user-defined component class) or + ``None`` (when the YAML uses ``my_plugin:`` or ``my_plugin: null``). + + Note: the generated models declare ``additional_properties`` as a + ``ClassVar`` even though the decorator assigns it as an instance + attribute at runtime. This is tolerated by pyright in ``standard`` + mode but flagged in ``strict`` mode. See #5268. + """ + + additional_properties: dict[str, dict[str, Any] | None] + + +def _resolve_component( + config: _ComponentConfig, + registry: dict[str, Callable[[Any], Any]], + entry_point_group: str, + component_type: str, +) -> Any: + """Resolve a config dataclass to a component instance. + + Checks built-in factories in ``registry`` first (by matching typed + field names on ``config``), then falls back to entry point loading + for plugin components found in ``config.additional_properties``. + + The JSON schema enforces exactly one component per config block + (``minProperties: 1, maxProperties: 1``). If multiple typed fields or + ``additional_properties`` entries are set (e.g. when schema validation + is bypassed), the first registry match wins. + + Args: + config: A dataclass with ``additional_properties`` (from the + ``@_additional_properties`` decorator). + registry: Mapping of built-in component names to factory + callables. Each factory receives the field value from config. + entry_point_group: The entry point group name for plugin loading. + component_type: Human-readable name for error messages + (e.g. "span exporter"). + + Returns: + The resolved component instance. + + Raises: + ConfigurationError: If no component type is specified in config. + """ + for name, factory in registry.items(): + value = getattr(config, name, None) + if value is not None: + return factory(value) + if config.additional_properties: + name, plugin_config = next(iter(config.additional_properties.items())) + return load_entry_point(entry_point_group, name)(**(plugin_config or {})) + raise ConfigurationError(f"No {component_type} type specified in config.") + + +def _parse_headers( + headers: list | None, + headers_list: str | None, +) -> dict[str, str] | None: + """Merge headers struct and headers_list into a dict. + + Returns None if neither is set, letting the exporter read env vars. + headers struct takes priority over headers_list for the same key. + """ + if headers is None and headers_list is None: + return None + result: dict[str, str] = {} + if headers_list: + for item in headers_list.split(","): + item = item.strip() + if "=" in item: + key, value = item.split("=", 1) + result[key.strip()] = value.strip() + elif item: + _logger.warning( + "Invalid header pair in headers_list (missing '='): %s", + item, + ) + if headers: + for pair in headers: + if isinstance(pair, dict): + result[pair["name"]] = pair.get("value") or "" + else: + result[pair.name] = pair.value or "" + return result + + +def _map_compression( + value: str | None, + compression_enum: type, + *, + allow_deflate: bool = False, +) -> object | None: + """Map a compression string to the given Compression enum value.""" + if value is None: + return None + + value_lower = value.lower() + supports_deflate = hasattr(compression_enum, "Deflate") + + if value_lower == "none": + return None + if value_lower == "gzip": + return compression_enum.Gzip # type: ignore[attr-defined] + if value_lower == "deflate" and allow_deflate and supports_deflate: + return compression_enum.Deflate # type: ignore[attr-defined] + + supported_values = ["'gzip'", "'none'"] + if allow_deflate and supports_deflate: + supported_values.insert(1, "'deflate'") + + raise ConfigurationError( + f"Unsupported compression value '{value}'. Supported values: {', '.join(supported_values)}." + ) + + +def _parse_otlp_file_output_stream(output_stream: str | None) -> str | None: + """Resolve an output_stream value to a file path, or None for stdout. + + Per the OTel file exporter spec, output_stream is "stdout" (or + None, which means the same), or a "file://" URI giving a path. + """ + if output_stream is None or output_stream == "stdout": + return None + try: + parsed = urlparse(output_stream) + except ValueError as exc: + raise ConfigurationError( + f"Failed to parse output_stream '{output_stream}' for otlp_file_development exporter: {exc}" + ) from exc + is_local_file_uri = parsed.scheme == "file" and parsed.netloc in ("", "localhost") and bool(parsed.path) + has_extra_components = parsed.params or parsed.query or parsed.fragment + if is_local_file_uri and not has_extra_components: + path = parsed.path + if not path.startswith("/"): + raise ConfigurationError( + f"Unsupported output_stream '{output_stream}' for " + "otlp_file_development exporter. Path must be absolute." + ) + if path.endswith("/"): + raise ConfigurationError( + f"Unsupported output_stream '{output_stream}' for " + "otlp_file_development exporter. Path must be a file, " + "not a directory." + ) + return path + raise ConfigurationError( + f"Unsupported output_stream '{output_stream}' for otlp_file_development " + "exporter. Supported values: stdout, file://." + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py new file mode 100644 index 00000000000..dfb1a0f0209 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py @@ -0,0 +1,137 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Recursive dict-to-dataclass conversion for parsed config data. + +The YAML/JSON loader produces nested dicts. Factory functions expect typed +dataclass instances (e.g. ``TracerProvider``, ``SpanProcessor``). This module +walks each field's type annotation and converts nested dicts into their +corresponding dataclass types. +""" + +from __future__ import annotations + +from collections.abc import Mapping +from dataclasses import MISSING, fields, is_dataclass +from enum import Enum +from types import UnionType +from typing import Any, TypeVar, Union, get_args, get_origin, get_type_hints + +_T = TypeVar("_T") + + +def _unwrap_optional(type_hint: Any) -> Any: + """Strip ``None`` from a ``X | None`` / ``Optional[X]`` annotation. + + Returns the unwrapped type, or the original hint if not a union with None. + """ + origin = get_origin(type_hint) + if origin is UnionType or origin is Union: + non_none = [t for t in get_args(type_hint) if t is not type(None)] + if len(non_none) == 1: + return non_none[0] + return type_hint + + +def _is_empty_constructible_dataclass(unwrapped: Any) -> bool: + """True if ``unwrapped`` is a dataclass type instantiable with no args. + + A dataclass with only optional fields (all have a default or + default_factory) can be built as ``cls()``; one with a required field + cannot, and coercing a present null into it would raise ``TypeError``. + """ + return ( + isinstance(unwrapped, type) + and is_dataclass(unwrapped) + and all(field.default is not MISSING or field.default_factory is not MISSING for field in fields(unwrapped)) + ) + + +def _convert_value(value: Any, type_hint: Any) -> Any: + """Convert a value according to its type hint. + + Recursively converts dicts to dataclasses and lists of dicts to lists of + dataclasses. Other values (primitives, enums, ``dict[str, Any]`` aliases) + pass through unchanged. + """ + unwrapped = _unwrap_optional(type_hint) + origin = get_origin(unwrapped) + + if value is None: + # A mapping key present with an empty (null) YAML value parses to + # ``None``, which is otherwise indistinguishable from an absent key. + # For object-typed nodes the declarative-config spec treats a present + # null as "select this with an empty config" — e.g. ``always_on:`` is + # equivalent to ``always_on: {}`` and a metric ``console:`` exporter to + # ``console: {}``. Substitute an empty mapping and let the dict/ + # dataclass handling below build it, so downstream ``is not None`` type + # dispatch selects it. Scalar fields — and dataclasses with required + # fields, which cannot be defaulted — keep ``None``, so an absent + # optional section stays unset. + if origin is dict or _is_empty_constructible_dataclass(unwrapped): + value = {} + else: + return None + + # list[X] — recurse on each element + if origin is list and isinstance(value, list): + args = get_args(unwrapped) + if args: + item_type = args[0] + return [_convert_value(item, item_type) for item in value] + return value + + # Direct dataclass type — recurse + if isinstance(unwrapped, type) and is_dataclass(unwrapped) and isinstance(value, dict): + return _dict_to_dataclass(value, unwrapped) + + # Enum type — coerce string/value to the Enum member + if isinstance(unwrapped, type) and issubclass(unwrapped, Enum) and not isinstance(value, unwrapped): + return unwrapped(value) + + return value + + +def _dict_to_dataclass(data: Mapping[str, Any], cls: type[_T]) -> _T: + """Recursively convert a mapping to a dataclass instance. + + For each key in ``data``: + - If it matches a known dataclass field, the value is converted according + to that field's type annotation (recursing for nested dataclasses). + - Unknown keys are passed through as kwargs; classes decorated with + ``@_additional_properties`` will capture them on the instance's + ``additional_properties`` attribute. + + ``ClassVar`` fields (e.g. the ``additional_properties`` annotation on + decorated dataclasses) are ignored as expected. + + Raises: + TypeError: If ``cls`` is not a dataclass type. + """ + if not is_dataclass(cls): + raise TypeError(f"{cls.__name__} is not a dataclass") + + # Annotated as ``dict[str, Any]`` so astroid stops tracing into + # ``get_type_hints`` — under pylint 3.x that path leads into + # Python 3.14's ``annotationlib`` (which uses t-strings) and crashes. + hints: dict[str, Any] = dict(get_type_hints(cls, include_extras=False)) + known_fields = {f.name for f in fields(cls)} + kwargs: dict[str, Any] = {} + + for key, value in data.items(): + # The OTel configuration schema uses "/" as a namespace separator for + # development/experimental features (e.g. "otlp_file/development", + # "instrumentation/development"). Python identifiers cannot contain + # "/", so the corresponding dataclass fields use "_" instead (e.g. + # "otlp_file_development"). Without this normalisation the key would + # not match any known field and would fall through to + # additional_properties, causing the factory lookup to fail silently. + field_key = key.replace("/", "_") + if field_key in known_fields: + type_hint = hints.get(field_key) + kwargs[field_key] = _convert_value(value, type_hint) + else: + # Unknown key — @_additional_properties decorator will capture it. + kwargs[key] = value + + return cls(**kwargs) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py new file mode 100644 index 00000000000..85b73574c8e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py @@ -0,0 +1,53 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +class ConfigurationError(Exception): + """Raised when configuration loading, parsing, validation, or instantiation fails. + + This includes errors from: + - File not found or inaccessible + - Invalid YAML/JSON syntax + - Schema validation failures + - Environment variable substitution errors + - Missing required SDK extensions (e.g., propagator packages not installed) + """ + + +class MissingDependencyError(ConfigurationError, ImportError): + """Raised when an optional dependency is not installed. + + Inherits from both :class:`ConfigurationError` and :class:`ImportError` to + maintain backwards compatibility with callers that catch ``ImportError``. + + Args: + package: The name of the missing package. + feature: Optional description of the feature that requires the package. + install_name: Optional package name used in the pip install command + (defaults to ``package``). + extras: Optional extras string for the pip install command. + """ + + def __init__( + self, + package: str, + feature: str | None = None, + install_name: str | None = None, + extras: str | None = None, + ) -> None: + self.package = package + self.feature = feature + self.install_name = install_name or package + self.extras = extras + + if extras: + install_cmd = f'pip install "{self.install_name}[{extras}]"' + else: + install_cmd = f"pip install {self.install_name}" + + if feature: + message = f"{feature} requires '{package}'. Install it with: {install_cmd}" + else: + message = f"'{package}' is required but not installed. Install it with: {install_cmd}" + + super().__init__(message) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py new file mode 100644 index 00000000000..8863f395f83 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py @@ -0,0 +1,386 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging + +from opentelemetry.agent._vendor.opentelemetry._logs import set_logger_provider +from opentelemetry.agent._vendor.opentelemetry.configuration._common import ( + _map_compression, + _parse_headers, + _parse_otlp_file_output_stream, + load_entry_point, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( + ConfigurationError, + MissingDependencyError, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + AttributeLimits, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + BatchLogRecordProcessor as BatchLogRecordProcessorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalLoggerConfig as LoggerConfigConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalLoggerConfigurator as LoggerConfiguratorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalOtlpFileExporter as ExperimentalOtlpFileExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + LoggerProvider as LoggerProviderConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + LogRecordExporter as LogRecordExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + LogRecordLimits as LogRecordLimitsConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + LogRecordProcessor as LogRecordProcessorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + OtlpGrpcExporter as OtlpGrpcExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + OtlpHttpExporter as OtlpHttpExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + SimpleLogRecordProcessor as SimpleLogRecordProcessorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal import ( + LogRecordLimits, + _LoggerConfig, + _RuleBasedLoggerConfigurator, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal.export import ( + BatchLogRecordProcessor, + ConsoleLogRecordExporter, + LogRecordExporter, + SimpleLogRecordProcessor, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob + +_logger = logging.getLogger(__name__) + +_DEFAULT_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT = 128 + +# BatchLogRecordProcessor defaults per OTel spec (milliseconds). +_DEFAULT_SCHEDULE_DELAY_MILLIS = 1000 +_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 +_DEFAULT_MAX_QUEUE_SIZE = 2048 +_DEFAULT_MAX_EXPORT_BATCH_SIZE = 512 + + +def _create_console_log_exporter() -> ConsoleLogRecordExporter: + """Create a ConsoleLogRecordExporter.""" + return ConsoleLogRecordExporter() + + +def _create_otlp_http_log_exporter( + config: OtlpHttpExporterConfig, +) -> LogRecordExporter: + """Create an OTLP HTTP log exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( # noqa: PLC0415 # type: ignore[import-untyped] + Compression, + ) + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._log_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + OTLPLogExporter, + ) + except ImportError as exc: + raise MissingDependencyError( + package="opentelemetry-exporter-otlp-proto-http", + feature="otlp_http log exporter", + ) from exc + + compression = _map_compression(config.compression, Compression, allow_deflate=True) + headers = _parse_headers(config.headers, config.headers_list) + timeout = (config.timeout / 1000.0) if config.timeout is not None else None + + return OTLPLogExporter( # type: ignore[return-value] + endpoint=config.endpoint, + headers=headers, + timeout=timeout, + compression=compression, # type: ignore[arg-type] + ) + + +def _create_otlp_grpc_log_exporter( + config: OtlpGrpcExporterConfig, +) -> LogRecordExporter: + """Create an OTLP gRPC log exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + import grpc # noqa: PLC0415 # type: ignore[import-untyped] + + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + OTLPLogExporter, + ) + except ImportError as exc: + raise MissingDependencyError( + package="opentelemetry-exporter-otlp-proto-grpc", + feature="otlp_grpc log exporter", + ) from exc + + compression = _map_compression(config.compression, grpc.Compression) + headers = _parse_headers(config.headers, config.headers_list) + timeout = (config.timeout / 1000.0) if config.timeout is not None else None + + return OTLPLogExporter( # type: ignore[return-value] + endpoint=config.endpoint, + headers=headers, + timeout=timeout, + compression=compression, # type: ignore[arg-type] + ) + + +def _create_otlp_file_development_log_exporter( + config: ExperimentalOtlpFileExporterConfig, +) -> LogRecordExporter: + """Create an OTLP file (JSON Lines) log exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._log_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + FileLogExporter, + ) + except ImportError as exc: + raise ConfigurationError( + "otlp_file_development log exporter requires 'opentelemetry-exporter-otlp-json-file'. " + "Install it with: pip install opentelemetry-exporter-otlp-json-file" + ) from exc + + path = _parse_otlp_file_output_stream(config.output_stream) + return FileLogExporter(path) if path is not None else FileLogExporter() + + +_LOG_EXPORTER_REGISTRY: dict = { + "otlp_http": _create_otlp_http_log_exporter, + "otlp_grpc": _create_otlp_grpc_log_exporter, + "console": lambda _: ConsoleLogRecordExporter(), + "otlp_file_development": _create_otlp_file_development_log_exporter, +} + + +def _create_log_record_exporter( + config: LogRecordExporterConfig, +) -> LogRecordExporter: + """Create a log record exporter from config. + + Known exporter types are checked via typed fields on the LogRecordExporter + dataclass. Unknown exporter names captured in additional_properties + by the @_additional_properties decorator are loaded via the + ``opentelemetry_logs_exporter`` entry point group. + """ + for name, factory in _LOG_EXPORTER_REGISTRY.items(): + value = getattr(config, name, None) + if value is not None: + return factory(value) + if config.additional_properties: + name, plugin_config = next(iter(config.additional_properties.items())) + return load_entry_point("opentelemetry_logs_exporter", name)(**(plugin_config or {})) + raise ConfigurationError( + "No exporter type specified in log record exporter config. " + "Supported types: console, otlp_http, otlp_grpc, otlp_file_development." + ) + + +def _create_batch_log_record_processor( + config: BatchLogRecordProcessorConfig, +) -> BatchLogRecordProcessor: + """Create a BatchLogRecordProcessor from config. + + Passes explicit defaults to suppress OTEL_BLRP_* env var reading. + """ + exporter = _create_log_record_exporter(config.exporter) + schedule_delay = config.schedule_delay if config.schedule_delay is not None else _DEFAULT_SCHEDULE_DELAY_MILLIS + export_timeout = config.export_timeout if config.export_timeout is not None else _DEFAULT_EXPORT_TIMEOUT_MILLIS + max_queue_size = config.max_queue_size if config.max_queue_size is not None else _DEFAULT_MAX_QUEUE_SIZE + max_export_batch_size = ( + config.max_export_batch_size if config.max_export_batch_size is not None else _DEFAULT_MAX_EXPORT_BATCH_SIZE + ) + return BatchLogRecordProcessor( + exporter=exporter, + schedule_delay_millis=float(schedule_delay), + export_timeout_millis=float(export_timeout), + max_queue_size=max_queue_size, + max_export_batch_size=max_export_batch_size, + ) + + +def _create_simple_log_record_processor( + config: SimpleLogRecordProcessorConfig, +) -> SimpleLogRecordProcessor: + """Create a SimpleLogRecordProcessor from config.""" + exporter = _create_log_record_exporter(config.exporter) + return SimpleLogRecordProcessor(exporter) + + +def _create_log_record_processor( + config: LogRecordProcessorConfig, +) -> BatchLogRecordProcessor | SimpleLogRecordProcessor: + """Create a log record processor from config.""" + if config.batch is not None: + return _create_batch_log_record_processor(config.batch) + if config.simple is not None: + return _create_simple_log_record_processor(config.simple) + raise ConfigurationError( + "No processor type specified in log record processor config. Supported types: batch, simple." + ) + + +def _to_logger_config(config: LoggerConfigConfig | None) -> _LoggerConfig: + """Map an experimental per-logger config to an SDK ``_LoggerConfig``. + + Only ``enabled`` is honored. ``minimum_severity`` and ``trace_based`` are + accepted by the config schema but not supported by the Python SDK + ``_LoggerConfig``; the ones that are set are ignored with a warning naming + them. An absent ``enabled`` leaves the logger enabled. + """ + if config is None: + return _LoggerConfig.default() + unsupported_fields = [ + field_name for field_name in ("minimum_severity", "trace_based") if getattr(config, field_name) is not None + ] + if unsupported_fields: + _logger.warning( + "Ignoring logger_configurator fields that are not supported by the Python SDK LoggerProvider: %s", + ", ".join(unsupported_fields), + ) + if config.enabled is None: + return _LoggerConfig.default() + return _LoggerConfig(is_enabled=config.enabled) + + +def _create_logger_configurator( + config: LoggerConfiguratorConfig, +) -> _RuleBasedLoggerConfigurator: + """Build a rule-based logger configurator from experimental config. + + Each entry in ``loggers`` maps an instrumentation-scope name glob to a + per-logger config; ``default_config`` applies to scopes matching no glob. + Rules are evaluated in order, so earlier entries take precedence. + """ + rules = [ + ( + _scope_name_matches_glob(matcher.name), + _to_logger_config(matcher.config), + ) + for matcher in (config.loggers or []) + ] + return _RuleBasedLoggerConfigurator( + rules=rules, + default_config=_to_logger_config(config.default_config), + ) + + +def _create_log_record_limits( + config: LogRecordLimitsConfig, + global_limits: AttributeLimits | None = None, +) -> LogRecordLimits: + """Create LogRecordLimits from config. + + Absent fields fall back to global_limits (if provided), then to OTel spec + defaults (128 for counts, unlimited for lengths). + Explicit values suppress env-var reading — matching Java SDK behavior. + """ + attribute_count_limit = config.attribute_count_limit + if attribute_count_limit is None and global_limits is not None: + attribute_count_limit = global_limits.attribute_count_limit + + attribute_value_length_limit = config.attribute_value_length_limit + if attribute_value_length_limit is None and global_limits is not None: + attribute_value_length_limit = global_limits.attribute_value_length_limit + + max_attributes = ( + attribute_count_limit if attribute_count_limit is not None else _DEFAULT_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT + ) + max_attribute_length = ( + attribute_value_length_limit if attribute_value_length_limit is not None else LogRecordLimits.UNSET + ) + + # The log-record-specific fields are the ones the SDK enforces, so they are + # set explicitly too. Leaving them absent would let OTEL_LOGRECORD_ATTRIBUTE_* + # override the configured values. + return LogRecordLimits( + max_attributes=max_attributes, + max_attribute_length=max_attribute_length, + max_log_record_attributes=max_attributes, + max_log_record_attribute_length=max_attribute_length, + ) + + +def create_logger_provider( + config: LoggerProviderConfig | None, + resource: Resource | None = None, + global_attribute_limits: AttributeLimits | None = None, +) -> LoggerProvider: + """Create an SDK LoggerProvider from declarative config. + + Does NOT read OTEL_BLRP_* or other env vars for values explicitly + controlled by the config. Absent config values use OTel spec defaults. + + Args: + config: LoggerProvider config from the parsed config file, or None. + resource: Resource to attach to the provider. + global_attribute_limits: Top-level attribute_limits from the root config, + used as a fallback when per-signal limits are not specified. + + Returns: + A configured LoggerProvider. + """ + logger_configurator = ( + _create_logger_configurator(config.logger_configurator_development) + if config is not None and config.logger_configurator_development is not None + else None + ) + + if config is not None and config.limits is not None: + limits = config.limits + + else: + limits = LogRecordLimitsConfig() + + log_record_limits = _create_log_record_limits(limits, global_attribute_limits) + + provider = LoggerProvider( + resource=resource, + log_record_limits=log_record_limits, + _logger_configurator=logger_configurator, + ) + + if config is None: + return provider + + for processor_config in config.processors: + provider.add_log_record_processor(_create_log_record_processor(processor_config)) + + return provider + + +def configure_logger_provider( + config: LoggerProviderConfig | None, + resource: Resource | None = None, + global_attribute_limits: AttributeLimits | None = None, +) -> None: + """Configure the global LoggerProvider from declarative config. + + When config is None (logger_provider section absent from config file), + the global is not set — matching Java/JS SDK behavior. + + Args: + config: LoggerProvider config from the parsed config file, or None. + resource: Resource to attach to the provider. + global_attribute_limits: Top-level attribute_limits from the root config, + used as a fallback when per-signal limits are not specified. + """ + if config is None: + return + set_logger_provider(create_logger_provider(config, resource, global_attribute_limits)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py new file mode 100644 index 00000000000..30ae72cc01d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py @@ -0,0 +1,656 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging + +from opentelemetry.agent._vendor.opentelemetry import metrics +from opentelemetry.agent._vendor.opentelemetry.configuration._common import ( + _map_compression, + _parse_headers, + _parse_otlp_file_output_stream, + load_entry_point, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( + ConfigurationError, + MissingDependencyError, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + Aggregation as AggregationConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + CardinalityLimits as CardinalityLimitsConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ConsoleMetricExporter as ConsoleMetricExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExemplarFilter as ExemplarFilterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalMeterConfig as MeterConfigConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalMeterConfigurator as MeterConfiguratorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalOtlpFileMetricExporter as ExperimentalOtlpFileMetricExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalPrometheusMetricExporter as PrometheusMetricExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExporterDefaultHistogramAggregation, + ExporterTemporalityPreference, + InstrumentType, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + MeterProvider as MeterProviderConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + MetricReader as MetricReaderConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + OtlpGrpcMetricExporter as OtlpGrpcMetricExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + OtlpHttpMetricExporter as OtlpHttpMetricExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + PeriodicMetricReader as PeriodicMetricReaderConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + PullMetricExporter as PullMetricExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + PullMetricReader as PullMetricReaderConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + PushMetricExporter as PushMetricExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + View as ViewConfig, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( + AlwaysOffExemplarFilter, + AlwaysOnExemplarFilter, + Counter, + Histogram, + MeterProvider, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + TraceBasedExemplarFilter, + UpDownCounter, + _Gauge, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import ( + _MeterConfig, + _RuleBasedMeterConfigurator, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + AggregationTemporality, + CardinalityLimits, + ConsoleMetricExporter, + MetricExporter, + MetricReader, + PeriodicExportingMetricReader, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import ( + Aggregation, + DefaultAggregation, + DropAggregation, + ExplicitBucketHistogramAggregation, + ExponentialBucketHistogramAggregation, + LastValueAggregation, + SumAggregation, + View, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob + +_logger = logging.getLogger(__name__) + + +# Default interval/timeout per OTel spec (milliseconds). +_DEFAULT_EXPORT_INTERVAL_MILLIS = 60000 +_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 + +# Instrument type → SDK instrument class mapping (for View selectors). +_INSTRUMENT_TYPE_MAP: dict[InstrumentType, type] = { + InstrumentType.counter: Counter, + InstrumentType.up_down_counter: UpDownCounter, + InstrumentType.histogram: Histogram, + InstrumentType.gauge: _Gauge, + InstrumentType.observable_counter: ObservableCounter, + InstrumentType.observable_gauge: ObservableGauge, + InstrumentType.observable_up_down_counter: ObservableUpDownCounter, +} + + +def _map_temporality( + pref: ExporterTemporalityPreference | None, +) -> dict[type, AggregationTemporality]: + """Map a temporality preference to an explicit preferred_temporality dict. + + Always returns an explicit dict to suppress OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE. + Default (None or cumulative) → all instruments CUMULATIVE. + """ + if pref is None or pref == ExporterTemporalityPreference.cumulative: + return { + Counter: AggregationTemporality.CUMULATIVE, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.CUMULATIVE, + ObservableCounter: AggregationTemporality.CUMULATIVE, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + if pref == ExporterTemporalityPreference.delta: + return { + Counter: AggregationTemporality.DELTA, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.DELTA, + ObservableCounter: AggregationTemporality.DELTA, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + if pref == ExporterTemporalityPreference.low_memory: + return { + Counter: AggregationTemporality.DELTA, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.DELTA, + ObservableCounter: AggregationTemporality.CUMULATIVE, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + raise ConfigurationError( + f"Unsupported temporality preference '{pref}'. Supported values: cumulative, delta, low_memory." + ) + + +def _map_histogram_aggregation( + pref: ExporterDefaultHistogramAggregation | None, +) -> dict[type, Aggregation]: + """Map a histogram aggregation preference to an explicit preferred_aggregation dict. + + Always returns an explicit dict to suppress + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION. + Default (None or explicit_bucket_histogram) → ExplicitBucketHistogramAggregation. + """ + if pref is None or pref == ExporterDefaultHistogramAggregation.explicit_bucket_histogram: + return {Histogram: ExplicitBucketHistogramAggregation()} + if pref == ExporterDefaultHistogramAggregation.base2_exponential_bucket_histogram: + return {Histogram: ExponentialBucketHistogramAggregation()} + raise ConfigurationError( + f"Unsupported default histogram aggregation '{pref}'. " + "Supported values: explicit_bucket_histogram, base2_exponential_bucket_histogram." + ) + + +def _create_aggregation(config: AggregationConfig) -> Aggregation: + """Create an SDK Aggregation from config, passing through detail parameters.""" + if config.default is not None: + return DefaultAggregation() + if config.drop is not None: + return DropAggregation() + if config.explicit_bucket_histogram is not None: + return ExplicitBucketHistogramAggregation( + boundaries=config.explicit_bucket_histogram.boundaries, + record_min_max=( + config.explicit_bucket_histogram.record_min_max + if config.explicit_bucket_histogram.record_min_max is not None + else True + ), + ) + if config.base2_exponential_bucket_histogram is not None: + kwargs = {} + if config.base2_exponential_bucket_histogram.max_size is not None: + kwargs["max_size"] = config.base2_exponential_bucket_histogram.max_size + if config.base2_exponential_bucket_histogram.max_scale is not None: + kwargs["max_scale"] = config.base2_exponential_bucket_histogram.max_scale + if config.base2_exponential_bucket_histogram.record_min_max is not None: + kwargs["record_min_max"] = config.base2_exponential_bucket_histogram.record_min_max + return ExponentialBucketHistogramAggregation(**kwargs) + if config.last_value is not None: + return LastValueAggregation() + if config.sum is not None: + return SumAggregation() + raise ConfigurationError( + f"Unknown or unsupported aggregation type in config: {config!r}. " + "Supported types: default, drop, explicit_bucket_histogram, " + "base2_exponential_bucket_histogram, last_value, sum." + ) + + +def _create_view(config: ViewConfig) -> View: + """Create an SDK View from config.""" + selector = config.selector + stream = config.stream + + instrument_type = None + if selector.instrument_type is not None: + instrument_type = _INSTRUMENT_TYPE_MAP.get(selector.instrument_type) + if instrument_type is None: + raise ConfigurationError(f"Unknown instrument type: {selector.instrument_type!r}") + + attribute_keys: set[str] | None = None + if stream.attribute_keys is not None: + if stream.attribute_keys.excluded: + _logger.warning( + "attribute_keys.excluded is not supported by the Python SDK View; the exclusion list will be ignored." + ) + if stream.attribute_keys.included is not None: + attribute_keys = set(stream.attribute_keys.included) + + aggregation = None + if stream.aggregation is not None: + aggregation = _create_aggregation(stream.aggregation) + + return View( + instrument_type=instrument_type, + instrument_name=selector.instrument_name, + meter_name=selector.meter_name, + meter_version=selector.meter_version, + meter_schema_url=selector.meter_schema_url, + instrument_unit=selector.unit, + name=stream.name, + description=stream.description, + attribute_keys=attribute_keys, + aggregation=aggregation, + aggregation_cardinality_limit=stream.aggregation_cardinality_limit, + ) + + +def _create_console_metric_exporter( + config: ConsoleMetricExporterConfig, +) -> MetricExporter: + """Create a ConsoleMetricExporter from config.""" + preferred_temporality = _map_temporality(config.temporality_preference) + preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) + return ConsoleMetricExporter( + preferred_temporality=preferred_temporality, + preferred_aggregation=preferred_aggregation, + ) + + +def _create_otlp_http_metric_exporter( + config: OtlpHttpMetricExporterConfig, +) -> MetricExporter: + """Create an OTLP HTTP metric exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( # noqa: PLC0415 # type: ignore[import-untyped] + Compression, + ) + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.metric_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + OTLPMetricExporter, + ) + except ImportError as exc: + raise MissingDependencyError( + package="opentelemetry-exporter-otlp-proto-http", + feature="otlp_http metric exporter", + ) from exc + + compression = _map_compression(config.compression, Compression, allow_deflate=True) + headers = _parse_headers(config.headers, config.headers_list) + timeout = (config.timeout / 1000.0) if config.timeout is not None else None + preferred_temporality = _map_temporality(config.temporality_preference) + preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) + + return OTLPMetricExporter( # type: ignore[return-value] + endpoint=config.endpoint, + headers=headers, + timeout=timeout, + compression=compression, # type: ignore[arg-type] + preferred_temporality=preferred_temporality, + preferred_aggregation=preferred_aggregation, + ) + + +def _create_otlp_grpc_metric_exporter( + config: OtlpGrpcMetricExporterConfig, +) -> MetricExporter: + """Create an OTLP gRPC metric exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + import grpc # noqa: PLC0415 # type: ignore[import-untyped] + + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.grpc.metric_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + OTLPMetricExporter, + ) + except ImportError as exc: + raise MissingDependencyError( + package="opentelemetry-exporter-otlp-proto-grpc", + feature="otlp_grpc metric exporter", + ) from exc + + compression = _map_compression(config.compression, grpc.Compression) + headers = _parse_headers(config.headers, config.headers_list) + timeout = (config.timeout / 1000.0) if config.timeout is not None else None + preferred_temporality = _map_temporality(config.temporality_preference) + preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) + + return OTLPMetricExporter( # type: ignore[return-value] + endpoint=config.endpoint, + headers=headers, + timeout=timeout, + compression=compression, # type: ignore[arg-type] + preferred_temporality=preferred_temporality, + preferred_aggregation=preferred_aggregation, + ) + + +def _create_otlp_file_development_metric_exporter( + config: ExperimentalOtlpFileMetricExporterConfig, +) -> MetricExporter: + """Create an OTLP file (JSON Lines) metric exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.metric_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + FileMetricExporter, + ) + except ImportError as exc: + raise ConfigurationError( + "otlp_file_development metric exporter requires 'opentelemetry-exporter-otlp-json-file'. " + "Install it with: pip install opentelemetry-exporter-otlp-json-file" + ) from exc + + path = _parse_otlp_file_output_stream(config.output_stream) + preferred_temporality = _map_temporality(config.temporality_preference) + preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) + return ( + FileMetricExporter( + path, + preferred_temporality=preferred_temporality, + preferred_aggregation=preferred_aggregation, + ) + if path is not None + else FileMetricExporter( + preferred_temporality=preferred_temporality, + preferred_aggregation=preferred_aggregation, + ) + ) + + +_METRIC_EXPORTER_REGISTRY: dict = { + "otlp_http": _create_otlp_http_metric_exporter, + "otlp_grpc": _create_otlp_grpc_metric_exporter, + "console": _create_console_metric_exporter, + "otlp_file_development": _create_otlp_file_development_metric_exporter, +} + + +def _create_push_metric_exporter( + config: PushMetricExporterConfig, +) -> MetricExporter: + """Create a push metric exporter from config. + + Known exporter types are checked via typed fields on the PushMetricExporter + dataclass. Unknown exporter names captured in additional_properties + by the @_additional_properties decorator are loaded via the + ``opentelemetry_metrics_exporter`` entry point group. + """ + for name, factory in _METRIC_EXPORTER_REGISTRY.items(): + value = getattr(config, name, None) + if value is not None: + return factory(value) + if config.additional_properties: + name, plugin_config = next(iter(config.additional_properties.items())) + return load_entry_point("opentelemetry_metrics_exporter", name)(**(plugin_config or {})) + raise ConfigurationError( + "No exporter type specified in push metric exporter config. " + "Supported types: console, otlp_http, otlp_grpc, otlp_file_development." + ) + + +def _create_cardinality_limits(config: CardinalityLimitsConfig | None) -> CardinalityLimits | None: + """Create the SDK per-instrument cardinality limits from config. + + Each instrument type uses its own limit and falls back to ``default``. + Instrument types left out of the result use the SDK default limit. + """ + if config is None: + return None + limits: CardinalityLimits = {} + for instrument_class, limit in ( + (Counter, config.counter), + (UpDownCounter, config.up_down_counter), + (Histogram, config.histogram), + (_Gauge, config.gauge), + (ObservableCounter, config.observable_counter), + (ObservableUpDownCounter, config.observable_up_down_counter), + (ObservableGauge, config.observable_gauge), + ): + limit = limit if limit is not None else config.default + if limit is not None: + limits[instrument_class] = limit + return limits + + +def _create_periodic_metric_reader( + config: PeriodicMetricReaderConfig, +) -> PeriodicExportingMetricReader: + """Create a PeriodicExportingMetricReader from config. + + Passes explicit interval/timeout defaults to suppress env var reading. + """ + exporter = _create_push_metric_exporter(config.exporter) + interval = config.interval if config.interval is not None else _DEFAULT_EXPORT_INTERVAL_MILLIS + timeout = config.timeout if config.timeout is not None else _DEFAULT_EXPORT_TIMEOUT_MILLIS + return PeriodicExportingMetricReader( + exporter=exporter, + export_interval_millis=float(interval), + export_timeout_millis=float(timeout), + cardinality_limits=_create_cardinality_limits(config.cardinality_limits), + ) + + +def _create_prometheus_metric_reader( + config: PrometheusMetricExporterConfig, + cardinality_limits: CardinalityLimits | None = None, +) -> MetricReader: + """Create a PrometheusMetricReader from config. + + Dynamically imports the prometheus exporter package to avoid a hard + dependency. Maps config fields to constructor parameters and starts + the HTTP server. + """ + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.exporter.prometheus import ( # noqa: PLC0415 # type: ignore[import-untyped] + PrometheusMetricReader, + start_http_server, + ) + except ImportError as exc: + raise MissingDependencyError( + package="opentelemetry-exporter-prometheus", + feature="prometheus pull metric exporter", + ) from exc + + disable_target_info = ( + config.target_info_enabled_development is not None and not config.target_info_enabled_development + ) + + if config.scope_info_enabled is not None: + _logger.warning("scope_info_enabled is not yet supported for Prometheus metric exporter and will be ignored.") + if config.resource_constant_labels is not None: + _logger.warning( + "resource_constant_labels is not yet supported for Prometheus metric exporter and will be ignored." + ) + + reader = PrometheusMetricReader( + disable_target_info=disable_target_info, + cardinality_limits=cardinality_limits, + ) + + port = config.port if config.port is not None else 9464 + host = config.host if config.host is not None else "localhost" + start_http_server(port=port, addr=host) + + return reader + + +def _create_pull_metric_exporter( + config: PullMetricExporterConfig, + cardinality_limits: CardinalityLimits | None = None, +) -> MetricReader: + """Create a pull metric exporter (which is itself a MetricReader) from config. + + Pull metric exporters like Prometheus are combined reader+exporter objects: + the "exporter" IS the reader. The config schema models them as separate + exporter configs, but the factory returns a MetricReader. + + Plugin pull exporters are loaded via the ``opentelemetry_pull_metric_exporter`` + entry point group. + """ + if config.prometheus_development is not None: + return _create_prometheus_metric_reader(config.prometheus_development, cardinality_limits) + if config.additional_properties: + name, plugin_config = next(iter(config.additional_properties.items())) + if cardinality_limits is not None: + _logger.warning( + "cardinality_limits is not yet supported for pull metric exporter plugins and will be ignored." + ) + return load_entry_point("opentelemetry_pull_metric_exporter", name)(**(plugin_config or {})) + raise ConfigurationError( + "No exporter type specified in pull metric exporter config. Supported types: prometheus_development." + ) + + +def _create_pull_metric_reader( + config: PullMetricReaderConfig, +) -> MetricReader: + """Create a pull MetricReader from config. + + The pull reader's exporter is itself a MetricReader (combined reader+exporter). + producers are not yet supported. + """ + if config.producers: + _logger.warning( + "MetricProducer configuration is not yet supported for pull metric readers and will be ignored." + ) + return _create_pull_metric_exporter(config.exporter, _create_cardinality_limits(config.cardinality_limits)) + + +def _create_metric_reader(config: MetricReaderConfig) -> MetricReader: + """Create a MetricReader from config.""" + if config.periodic is not None: + return _create_periodic_metric_reader(config.periodic) + if config.pull is not None: + return _create_pull_metric_reader(config.pull) + raise ConfigurationError("No reader type specified in metric reader config. Supported types: periodic, pull.") + + +def _create_exemplar_filter( + value: ExemplarFilterConfig, +) -> object: + """Create an SDK exemplar filter from config enum value.""" + if value == ExemplarFilterConfig.always_on: + return AlwaysOnExemplarFilter() + if value == ExemplarFilterConfig.always_off: + return AlwaysOffExemplarFilter() + if value == ExemplarFilterConfig.trace_based: + return TraceBasedExemplarFilter() + raise ConfigurationError( + f"Unknown exemplar filter value: {value!r}. Supported values: always_on, always_off, trace_based." + ) + + +def _to_meter_config(config: MeterConfigConfig | None) -> _MeterConfig: + """Map an experimental per-meter config to an SDK ``_MeterConfig``. + + Only ``enabled`` is honored — it is the sole field the SDK + ``_MeterConfig`` exposes. An absent ``enabled`` leaves the meter enabled. + """ + if config is None or config.enabled is None: + return _MeterConfig.default() + return _MeterConfig(is_enabled=config.enabled) + + +def _create_meter_configurator( + config: MeterConfiguratorConfig, +) -> _RuleBasedMeterConfigurator: + """Build a rule-based meter configurator from experimental config. + + Each entry in ``meters`` maps an instrumentation-scope name glob to a + per-meter config; ``default_config`` applies to scopes matching no glob. + Rules are evaluated in order, so earlier entries take precedence. + """ + rules = [ + ( + _scope_name_matches_glob(matcher.name), + _to_meter_config(matcher.config), + ) + for matcher in (config.meters or []) + ] + return _RuleBasedMeterConfigurator( + rules=rules, + default_config=_to_meter_config(config.default_config), + ) + + +def create_meter_provider( + config: MeterProviderConfig | None, + resource: Resource | None = None, +) -> MeterProvider: + """Create an SDK MeterProvider from declarative config. + + Does NOT read OTEL_METRIC_EXPORT_INTERVAL, OTEL_METRICS_EXEMPLAR_FILTER, + or any other env vars for values explicitly controlled by the config. + Absent config values use OTel spec defaults, matching Java SDK behavior. + + Args: + config: MeterProvider config from the parsed config file, or None. + resource: Resource to attach to the provider. + + Returns: + A configured MeterProvider. + """ + # Always pass an explicit exemplar filter to suppress env var reading. + # Spec default is trace_based. + exemplar_filter: object = TraceBasedExemplarFilter() + if config is not None and config.exemplar_filter is not None: + exemplar_filter = _create_exemplar_filter(config.exemplar_filter) + + readers: list[MetricReader] = [] + views: list[View] = [] + + if config is not None: + for reader_config in config.readers: + readers.append(_create_metric_reader(reader_config)) + if config.views: + for view_config in config.views: + views.append(_create_view(view_config)) + + meter_configurator = ( + _create_meter_configurator(config.meter_configurator_development) + if config is not None and config.meter_configurator_development is not None + else None + ) + + return MeterProvider( + resource=resource, + metric_readers=readers, + exemplar_filter=exemplar_filter, # type: ignore[arg-type] + views=views, + _meter_configurator=meter_configurator, + ) + + +def configure_meter_provider( + config: MeterProviderConfig | None, + resource: Resource | None = None, +) -> None: + """Configure the global MeterProvider from declarative config. + + When config is None (meter_provider section absent from config file), + the global is not set — matching Java/JS SDK behavior. + + Args: + config: MeterProvider config from the parsed config file, or None. + resource: Resource to attach to the provider. + """ + if config is None: + return + metrics.set_meter_provider(create_meter_provider(config, resource)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py new file mode 100644 index 00000000000..e78eec1a87a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py @@ -0,0 +1,102 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from opentelemetry.agent._vendor.opentelemetry.baggage.propagation import W3CBaggagePropagator +from opentelemetry.agent._vendor.opentelemetry.configuration._common import load_entry_point +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + Propagator as PropagatorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + TextMapPropagator as TextMapPropagatorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.propagate import set_global_textmap +from opentelemetry.agent._vendor.opentelemetry.propagators.composite import CompositePropagator +from opentelemetry.agent._vendor.opentelemetry.propagators.textmap import TextMapPropagator +from opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext import ( + TraceContextTextMapPropagator, +) + +# Propagators bundled with the SDK — no entry point lookup needed. +_PROPAGATOR_REGISTRY: dict[str, type[TextMapPropagator]] = { + "tracecontext": TraceContextTextMapPropagator, + "baggage": W3CBaggagePropagator, +} + + +def _propagators_from_textmap_config( + config: TextMapPropagatorConfig, +) -> list[TextMapPropagator]: + """Resolve a TextMapPropagator config to a list of propagators. + + Known names (tracecontext, baggage) are bootstrapped directly via + _PROPAGATOR_REGISTRY. Known schema fields not in the registry (b3, b3multi) + and unknown plugin names from additional_properties are loaded via the + ``opentelemetry_propagator`` entry point group. + """ + result: list[TextMapPropagator] = [] + for name, cls in _PROPAGATOR_REGISTRY.items(): + if getattr(config, name, None) is not None: + result.append(cls()) + + # Known schema fields not in registry (b3, b3multi) — loaded via entry point + for name in ("b3", "b3multi"): + if getattr(config, name, None) is not None: + result.append(load_entry_point("opentelemetry_propagator", name)()) + + # Plugin propagators from additional_properties + for name, plugin_config in config.additional_properties.items(): + result.append(load_entry_point("opentelemetry_propagator", name)(**(plugin_config or {}))) + + return result + + +def create_propagator( + config: PropagatorConfig | None, +) -> CompositePropagator: + """Create a CompositePropagator from declarative config. + + If config is None or has no propagators defined, returns an empty + CompositePropagator (no-op), ensuring "what you see is what you get" + semantics — the env-var-based default propagators are not used. + + Args: + config: Propagator config from the parsed config file, or None. + + Returns: + A CompositePropagator wrapping all configured propagators. + """ + if config is None: + return CompositePropagator([]) + + propagators: dict[type[TextMapPropagator], TextMapPropagator] = {} + + # Process structured composite list + if config.composite: + for entry in config.composite: + for propagator in _propagators_from_textmap_config(entry): + propagators.setdefault(type(propagator), propagator) + + # Process composite_list (comma-separated propagator names via entry_points) + if config.composite_list: + for name in config.composite_list.split(","): + name = name.strip() + if not name or name.lower() == "none": + continue + propagator = load_entry_point("opentelemetry_propagator", name)() + propagators.setdefault(type(propagator), propagator) + + return CompositePropagator(list(propagators.values())) + + +def configure_propagator(config: PropagatorConfig | None) -> None: + """Configure the global text map propagator from declarative config. + + Always calls set_global_textmap to override any defaults (including the + env-var-based tracecontext+baggage default set by the SDK). + + Args: + config: Propagator config from the parsed config file, or None. + """ + set_global_textmap(create_propagator(config)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py new file mode 100644 index 00000000000..7e9188d1511 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py @@ -0,0 +1,219 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import dataclasses +import fnmatch +import logging +import os +import sys +from collections.abc import Callable +from typing import Any +from urllib import parse + +from opentelemetry.agent._vendor.opentelemetry.configuration._common import load_entry_point +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + AttributeNameValue, + AttributeType, + ExperimentalResourceDetector, + IncludeExclude, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import Resource as ResourceConfig +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import OTEL_SERVICE_NAME +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( + _DEFAULT_RESOURCE, + SERVICE_NAME, + ProcessResourceDetector, + Resource, + ServiceInstanceIdResourceDetector, + _HostResourceDetector, +) +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue + +_logger = logging.getLogger(__name__) + + +def _coerce_bool(value: object) -> bool: + if isinstance(value, str): + return value.lower() not in ("false", "0", "") + return bool(value) + + +def _array(coerce: Callable) -> Callable: + return lambda value: [coerce(item) for item in value] + + +# Dispatch table mapping AttributeType to its coercion callable +_COERCIONS = { + AttributeType.string: str, + AttributeType.int: int, + AttributeType.double: float, + AttributeType.bool: _coerce_bool, + AttributeType.string_array: _array(str), + AttributeType.int_array: _array(int), + AttributeType.double_array: _array(float), + AttributeType.bool_array: _array(_coerce_bool), +} + + +def _coerce_attribute_value(attr: AttributeNameValue) -> object: + """Coerce an attribute value to the correct Python type based on AttributeType.""" + coerce = _COERCIONS.get(attr.type) # type: ignore[arg-type] + return coerce(attr.value) if coerce is not None else attr.value # type: ignore[operator] + + +def _parse_attributes_list(attributes_list: str) -> dict[str, str]: + """Parse a comma-separated key=value string into a dict. + + Format is the same as OTEL_RESOURCE_ATTRIBUTES: key=value,key=value + Values are always strings (no type coercion). + """ + result: dict[str, str] = {} + for item in attributes_list.split(","): + item = item.strip() + if not item: + continue + if "=" not in item: + _logger.warning( + "Invalid resource attribute pair in attributes_list: %s", + item, + ) + continue + key, value = item.split("=", maxsplit=1) + result[key.strip()] = parse.unquote(value.strip()) + return result + + +def create_resource(config: ResourceConfig | None) -> Resource: + """Create an SDK Resource from declarative config. + + Does NOT read OTEL_RESOURCE_ATTRIBUTES. Resource detectors are only run + when explicitly listed under detection_development.detectors in the config. + Starts from SDK telemetry defaults (telemetry.sdk.*), merges any detected + attributes, then merges explicit config attributes on top (highest priority). + + Args: + config: Resource config from the parsed config file, or None. + + Returns: + A Resource with SDK defaults, optional detector attributes, and any + config-specified attributes merged in priority order. + """ + # Spec requires service.name to always be present; detectors and explicit + # config attributes can override this default. + executable_name = os.path.basename(sys.executable) if sys.executable else None + default_service_name = f"unknown_service:{executable_name}" if executable_name else "unknown_service" + base = _DEFAULT_RESOURCE.merge(Resource({SERVICE_NAME: default_service_name})) + + if config is None: + return base + + # attributes_list is lower priority; explicit attributes overwrite conflicts. + config_attrs: dict[str, object] = {} + if config.attributes_list: + config_attrs.update(_parse_attributes_list(config.attributes_list)) + + if config.attributes: + for attr in config.attributes: + # An unset ${VAR} with no default substitutes an empty value that + # the YAML parser reads as null. Skip such attributes rather than + # inserting a None (or coercing it into garbage like "None"/0). + if attr.value is None: + _logger.warning( + "Ignoring resource attribute '%s' with empty value", + attr.name, + ) + continue + config_attrs[attr.name] = _coerce_attribute_value(attr) + + schema_url = config.schema_url + + # Run detectors only if detection_development is configured. Collect all + # detected attributes, apply the include/exclude filter, then merge before + # config attributes so explicit values always win. + result = base + if config.detection_development: + detected_attrs: dict[str, object] = {} + if config.detection_development.detectors: + for detector_config in config.detection_development.detectors: + _run_detectors(detector_config, detected_attrs) + + filtered = _filter_attributes(detected_attrs, config.detection_development.attributes) + if filtered: + result = result.merge(Resource(filtered)) # type: ignore[arg-type] + + config_resource = Resource(config_attrs, schema_url) # type: ignore[arg-type] + return result.merge(config_resource) + + +def _detect_service(_config: Any) -> dict[str, AnyValue]: + """Service detector: generates instance ID and reads OTEL_SERVICE_NAME.""" + attrs: dict[str, AnyValue] = dict(ServiceInstanceIdResourceDetector().detect().attributes) + if service_name := os.environ.get(OTEL_SERVICE_NAME): + attrs[SERVICE_NAME] = service_name + return attrs + + +_RESOURCE_DETECTOR_REGISTRY: dict[str, Callable[[Any], dict[str, AnyValue]]] = { + "service": _detect_service, + "host": lambda _: dict(_HostResourceDetector().detect().attributes), + "process": lambda _: dict(ProcessResourceDetector().detect().attributes), +} + + +def _run_detectors( + detector_config: ExperimentalResourceDetector, + detected_attrs: dict[str, object], +) -> None: + """Run detectors present in a single detector config entry. + + Known detectors (service, host, process) are handled directly via + _RESOURCE_DETECTOR_REGISTRY. All other detectors — including known + schema fields like container that require contrib packages, and + unknown plugin detectors captured in additional_properties — are + loaded via the ``opentelemetry_resource_detector`` entry point group. + + The detected_attrs dict is updated in-place; later detectors overwrite + earlier ones for the same key. + """ + for name in dataclasses.fields(detector_config): + value = getattr(detector_config, name.name, None) + if value is None: + continue + if name.name in _RESOURCE_DETECTOR_REGISTRY: + detected_attrs.update(_RESOURCE_DETECTOR_REGISTRY[name.name](value)) + else: + cls = load_entry_point("opentelemetry_resource_detector", name.name) + detected_attrs.update(cls(**(value or {})).detect().attributes) + + for name, plugin_config in detector_config.additional_properties.items(): + cls = load_entry_point("opentelemetry_resource_detector", name) + detected_attrs.update(cls(**(plugin_config or {})).detect().attributes) + + +def _filter_attributes(attrs: dict[str, object], filter_config: IncludeExclude | None) -> dict[str, object]: + """Filter detected attribute keys using include/exclude glob patterns. + + Mirrors other SDK IncludeExcludePredicate.createPatternMatching behaviour: + - No filter config (attributes absent) → include all detected attributes. + - included patterns are checked first; excluded patterns are applied after. + - An empty included list is treated as "include everything". + """ + if filter_config is None: + return attrs + + included = filter_config.included + excluded = filter_config.excluded + + if not included and not excluded: + return attrs + + result: dict[str, object] = {} + for key, value in attrs.items(): + if included and not any(fnmatch.fnmatch(key, pat) for pat in included): + continue + if excluded and any(fnmatch.fnmatch(key, pat) for pat in excluded): + continue + result[key] = value + return result diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py new file mode 100644 index 00000000000..99785b0426f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py @@ -0,0 +1,108 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Top-level orchestrator for declarative SDK configuration. + +Takes a parsed ``OpenTelemetryConfiguration`` and applies it by calling +each per-signal ``configure_*`` factory in order. This is the single +entry point for "apply this config" on the declarative path. +""" + +from __future__ import annotations + +from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING, getLogger + +from opentelemetry.agent._vendor.opentelemetry.configuration._logger_provider import ( + configure_logger_provider, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._meter_provider import ( + configure_meter_provider, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._propagator import configure_propagator +from opentelemetry.agent._vendor.opentelemetry.configuration._resource import create_resource +from opentelemetry.agent._vendor.opentelemetry.configuration._tracer_provider import ( + configure_tracer_provider, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.instrumentation import ( + configure_instrumentation, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + OpenTelemetryConfiguration, + SeverityNumber, +) + +_logger = getLogger(__name__) + +# Maps OTel SeverityNumber groups to Python logging levels. +# The numbered variants (debug2, info3, …) are sub-levels within the same +# Python tier, so they collapse to the same level constant. +_SEVERITY_TO_LOGGING_LEVEL: dict[SeverityNumber, int] = { + SeverityNumber.trace: DEBUG, + SeverityNumber.trace2: DEBUG, + SeverityNumber.trace3: DEBUG, + SeverityNumber.trace4: DEBUG, + SeverityNumber.debug: DEBUG, + SeverityNumber.debug2: DEBUG, + SeverityNumber.debug3: DEBUG, + SeverityNumber.debug4: DEBUG, + SeverityNumber.info: INFO, + SeverityNumber.info2: INFO, + SeverityNumber.info3: INFO, + SeverityNumber.info4: INFO, + SeverityNumber.warn: WARNING, + SeverityNumber.warn2: WARNING, + SeverityNumber.warn3: WARNING, + SeverityNumber.warn4: WARNING, + SeverityNumber.error: ERROR, + SeverityNumber.error2: ERROR, + SeverityNumber.error3: ERROR, + SeverityNumber.error4: ERROR, + SeverityNumber.fatal: CRITICAL, + SeverityNumber.fatal2: CRITICAL, + SeverityNumber.fatal3: CRITICAL, + SeverityNumber.fatal4: CRITICAL, +} + + +def configure_sdk(config: OpenTelemetryConfiguration) -> None: + """Configure the global SDK from a parsed declarative configuration. + + Builds a :class:`Resource` from ``config.resource`` and applies it to + each signal provider. Sets the global tracer provider, meter provider, + logger provider, and text map propagator from their respective config + sections. Sections absent from the config (``None``) leave the + corresponding global untouched — matching the spec's "noop default" + behavior. + + Honors the top-level ``disabled`` flag: when true, the function returns + early without setting any globals. The ``log_level`` field, when present + and not disabled, is applied to the internal ``opentelemetry`` logger to + control the verbosity of SDK self-diagnostics. + + Args: + config: Parsed ``OpenTelemetryConfiguration`` (typically from + ``load_config_file``). + + Example: + >>> from opentelemetry.configuration.file import ( + ... load_config_file, + ... configure_sdk, + ... ) + >>> config = load_config_file("otel-config.yaml") + >>> configure_sdk(config) + """ + if config.disabled: + _logger.warning("Declarative configuration has disabled=true; skipping SDK setup.") + return + + if config.log_level is not None: + level = _SEVERITY_TO_LOGGING_LEVEL.get(config.log_level, INFO) + getLogger("opentelemetry.agent._vendor.opentelemetry").setLevel(level) + + global_attribute_limits = config.attribute_limits + resource = create_resource(config.resource) + configure_tracer_provider(config.tracer_provider, resource, global_attribute_limits) + configure_meter_provider(config.meter_provider, resource) + configure_logger_provider(config.logger_provider, resource, global_attribute_limits) + configure_propagator(config.propagator) + configure_instrumentation(config.instrumentation_development) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py new file mode 100644 index 00000000000..d0b09349c51 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py @@ -0,0 +1,524 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging + +from opentelemetry.agent._vendor.opentelemetry import trace +from opentelemetry.agent._vendor.opentelemetry.configuration._common import ( + _map_compression, + _parse_headers, + _parse_otlp_file_output_stream, + load_entry_point, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( + ConfigurationError, + MissingDependencyError, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + AttributeLimits, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalComposableRuleBasedSampler as RuleBasedSamplerConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalComposableRuleBasedSamplerRule as RuleBasedSamplerRuleConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalComposableSampler as ComposableSamplerConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalOtlpFileExporter as ExperimentalOtlpFileExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalTracerConfig as TracerConfigConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ExperimentalTracerConfigurator as TracerConfiguratorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + IdGenerator as IdGeneratorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + OtlpGrpcExporter as OtlpGrpcExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + OtlpHttpExporter as OtlpHttpExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + ParentBasedSampler as ParentBasedSamplerConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + Sampler as SamplerConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + SpanExporter as SpanExporterConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + SpanLimits as SpanLimitsConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + SpanProcessor as SpanProcessorConfig, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( + TracerProvider as TracerProviderConfig, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ( + _DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, + _DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, + _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, + _DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT, + _DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT, + SpanLimits, + TracerProvider, + _RuleBasedTracerConfigurator, + _TracerConfig, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace._sampling_experimental import ( + ComposableSampler, + composable_always_off, + composable_always_on, + composable_parent_threshold, + composable_rule_based, + composable_traceid_ratio_based, + composite_sampler, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace._sampling_experimental._rule_based import ( + AllPredicate, + AlwaysMatchPredicate, + AttributePatternsPredicate, + AttributeValuesPredicate, + ParentPredicate, + PredicateT, + RulesT, + SpanKindPredicate, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import ( + BatchSpanProcessor, + ConsoleSpanExporter, + SimpleSpanProcessor, + SpanExporter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import ( + ALWAYS_OFF, + ALWAYS_ON, + ParentBased, + Sampler, + TraceIdRatioBased, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob +from opentelemetry.agent._vendor.opentelemetry.trace import SpanKind as TraceSpanKind + +_logger = logging.getLogger(__name__) + +# Default sampler per the OTel spec: parent_based with always_on root. +_DEFAULT_SAMPLER = ParentBased(root=ALWAYS_ON) + + +def _create_otlp_http_span_exporter( + config: OtlpHttpExporterConfig, +) -> SpanExporter: + """Create an OTLP HTTP span exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( # noqa: PLC0415 # type: ignore[import-untyped] + Compression, + ) + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.trace_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + OTLPSpanExporter, + ) + except ImportError as exc: + raise MissingDependencyError( + package="opentelemetry-exporter-otlp-proto-http", + feature="otlp_http span exporter", + ) from exc + + compression = _map_compression(config.compression, Compression, allow_deflate=True) + headers = _parse_headers(config.headers, config.headers_list) + timeout = (config.timeout / 1000.0) if config.timeout is not None else None + + return OTLPSpanExporter( # type: ignore[return-value] + endpoint=config.endpoint, + headers=headers, + timeout=timeout, + compression=compression, # type: ignore[arg-type] + ) + + +def _create_otlp_grpc_span_exporter( + config: OtlpGrpcExporterConfig, +) -> SpanExporter: + """Create an OTLP gRPC span exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + import grpc # noqa: PLC0415 # type: ignore[import-untyped] + + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + OTLPSpanExporter, + ) + except ImportError as exc: + raise MissingDependencyError( + package="opentelemetry-exporter-otlp-proto-grpc", + feature="otlp_grpc span exporter", + ) from exc + + compression = _map_compression(config.compression, grpc.Compression) + headers = _parse_headers(config.headers, config.headers_list) + timeout = (config.timeout / 1000.0) if config.timeout is not None else None + + return OTLPSpanExporter( # type: ignore[return-value] + endpoint=config.endpoint, + headers=headers, + timeout=timeout, + compression=compression, # type: ignore[arg-type] + ) + + +def _create_otlp_file_development_span_exporter( + config: ExperimentalOtlpFileExporterConfig, +) -> SpanExporter: + """Create an OTLP file (JSON Lines) span exporter from config.""" + try: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.trace_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] + FileSpanExporter, + ) + except ImportError as exc: + raise ConfigurationError( + "otlp_file_development span exporter requires 'opentelemetry-exporter-otlp-json-file'. " + "Install it with: pip install opentelemetry-exporter-otlp-json-file" + ) from exc + + path = _parse_otlp_file_output_stream(config.output_stream) + return FileSpanExporter(path) if path is not None else FileSpanExporter() + + +_SPAN_EXPORTER_REGISTRY: dict = { + "otlp_http": _create_otlp_http_span_exporter, + "otlp_grpc": _create_otlp_grpc_span_exporter, + "console": lambda _: ConsoleSpanExporter(), + "otlp_file_development": _create_otlp_file_development_span_exporter, +} + + +def _create_span_exporter(config: SpanExporterConfig) -> SpanExporter: + """Create a span exporter from config. + + Known exporter types are checked via typed fields on the SpanExporter + dataclass. Unknown exporter names captured in additional_properties + by the @_additional_properties decorator are loaded via the + ``opentelemetry_traces_exporter`` entry point group. + """ + for name, factory in _SPAN_EXPORTER_REGISTRY.items(): + value = getattr(config, name, None) + if value is not None: + return factory(value) + if config.additional_properties: + name, plugin_config = next(iter(config.additional_properties.items())) + return load_entry_point("opentelemetry_traces_exporter", name)(**(plugin_config or {})) + raise ConfigurationError( + "No exporter type specified in span exporter config. " + "Supported types: otlp_http, otlp_grpc, console, otlp_file_development." + ) + + +def _create_span_processor( + config: SpanProcessorConfig, +) -> BatchSpanProcessor | SimpleSpanProcessor: + """Create a span processor from config.""" + if config.batch is not None: + exporter = _create_span_exporter(config.batch.exporter) + return BatchSpanProcessor( + exporter, + max_queue_size=config.batch.max_queue_size, + schedule_delay_millis=config.batch.schedule_delay, + max_export_batch_size=config.batch.max_export_batch_size, + export_timeout_millis=config.batch.export_timeout, + ) + if config.simple is not None: + return SimpleSpanProcessor(_create_span_exporter(config.simple.exporter)) + raise ConfigurationError("No processor type specified in span processor config. Supported types: batch, simple.") + + +def _create_experimental_composable_sampler( + config: ComposableSamplerConfig, +) -> ComposableSampler: + """Create an experimental composable sampler from config""" + if config.always_on is not None: + return composable_always_on() + if config.always_off is not None: + return composable_always_off() + if config.parent_threshold is not None: + return composable_parent_threshold(_create_experimental_composable_sampler(config.parent_threshold.root)) + if config.probability is not None: + ratio = config.probability.ratio + return composable_traceid_ratio_based(ratio if ratio is not None else 1.0) + if config.rule_based is not None: + return composable_rule_based(_create_rule_based_sampler_rules(config.rule_based)) + raise ConfigurationError( + f"Unknown or unsupported experimental composable sampler type in config: {config!r}. " + "Supported types: always_on, always_off, parent_threshold, probability, rule_based." + ) + + +def _create_rule_based_sampler_rules( + config: RuleBasedSamplerConfig, +) -> RulesT: + if config.rules is None: + return [] + return [ + ( + _create_rule_based_sampler_rule_predicate(rule), + _create_experimental_composable_sampler(rule.sampler), + ) + for rule in config.rules + ] + + +def _create_rule_based_sampler_rule_predicate( + config: RuleBasedSamplerRuleConfig, +) -> PredicateT: + predicates: list[PredicateT] = [] + if config.attribute_values is not None: + predicates.append( + AttributeValuesPredicate( + config.attribute_values.key, + config.attribute_values.values, + ) + ) + if config.attribute_patterns is not None: + predicates.append( + AttributePatternsPredicate( + config.attribute_patterns.key, + config.attribute_patterns.included, + config.attribute_patterns.excluded, + ) + ) + if config.span_kinds is not None: + predicates.append( + SpanKindPredicate([TraceSpanKind[span_kind.value.upper()] for span_kind in config.span_kinds]) + ) + if config.parent is not None: + predicates.append(ParentPredicate([parent.value for parent in config.parent])) + if not predicates: + return AlwaysMatchPredicate() + if len(predicates) == 1: + return predicates[0] + return AllPredicate(predicates) + + +def _create_sampler(config: SamplerConfig) -> Sampler: + """Create a sampler from config. + + Built-in sampler types are checked via typed fields on the Sampler + dataclass. User-defined sampler names captured in additional_properties + by the @_additional_properties decorator are loaded via the + ``opentelemetry_sampler`` entry point group. + """ + if config.always_on is not None: + return ALWAYS_ON + if config.always_off is not None: + return ALWAYS_OFF + if config.trace_id_ratio_based is not None: + ratio = config.trace_id_ratio_based.ratio + return TraceIdRatioBased(ratio if ratio is not None else 1.0) + if config.composite_development is not None: + return composite_sampler(_create_experimental_composable_sampler(config.composite_development)) + if config.parent_based is not None: + return _create_parent_based_sampler(config.parent_based) + if config.additional_properties: + name = next(iter(config.additional_properties)) + return load_entry_point("opentelemetry_sampler", name)() + raise ConfigurationError( + f"Unsupported sampler type in config: {config!r}. " + "Supported types: always_on, always_off, composite_development, " + "trace_id_ratio_based, parent_based." + ) + + +def _create_id_generator(config: IdGeneratorConfig) -> IdGenerator: + """Create an IdGenerator from config. + + Built-in ``random`` resolves to ``RandomIdGenerator``; unknown names + load from the ``opentelemetry_id_generator`` entry point group (the + same group ``OTEL_PYTHON_ID_GENERATOR`` uses today). + """ + if config.random is not None: + return RandomIdGenerator() + if config.additional_properties: + name, plugin_config = next(iter(config.additional_properties.items())) + return load_entry_point("opentelemetry_id_generator", name)(**(plugin_config or {})) + raise ConfigurationError("No id_generator type specified in config. Supported built-in types: random.") + + +def _create_parent_based_sampler(config: ParentBasedSamplerConfig) -> Sampler: + """Create a ParentBased sampler from config, applying SDK defaults for absent delegates.""" + root = _create_sampler(config.root) if config.root is not None else ALWAYS_ON + kwargs: dict = {"root": root} + if config.remote_parent_sampled is not None: + kwargs["remote_parent_sampled"] = _create_sampler(config.remote_parent_sampled) + if config.remote_parent_not_sampled is not None: + kwargs["remote_parent_not_sampled"] = _create_sampler(config.remote_parent_not_sampled) + if config.local_parent_sampled is not None: + kwargs["local_parent_sampled"] = _create_sampler(config.local_parent_sampled) + if config.local_parent_not_sampled is not None: + kwargs["local_parent_not_sampled"] = _create_sampler(config.local_parent_not_sampled) + return ParentBased(**kwargs) + + +def _create_span_limits( + config: SpanLimitsConfig, + global_limits: AttributeLimits | None = None, +) -> SpanLimits: + """Create SpanLimits from config. + + Absent fields fall back to global_limits (if provided), then to OTel spec + defaults (128 for counts, unlimited for lengths). + Explicit values suppress env-var reading — matching Java SDK behavior. + """ + attribute_count_limit = config.attribute_count_limit + if attribute_count_limit is None and global_limits is not None: + attribute_count_limit = global_limits.attribute_count_limit + + attribute_value_length_limit = config.attribute_value_length_limit + if attribute_value_length_limit is None and global_limits is not None: + attribute_value_length_limit = global_limits.attribute_value_length_limit + + return SpanLimits( + max_span_attributes=( + attribute_count_limit if attribute_count_limit is not None else _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT + ), + max_events=( + config.event_count_limit if config.event_count_limit is not None else _DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT + ), + max_links=( + config.link_count_limit if config.link_count_limit is not None else _DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT + ), + max_event_attributes=( + config.event_attribute_count_limit + if config.event_attribute_count_limit is not None + else _DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT + ), + max_link_attributes=( + config.link_attribute_count_limit + if config.link_attribute_count_limit is not None + else _DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT + ), + max_attribute_length=( + attribute_value_length_limit if attribute_value_length_limit is not None else SpanLimits.UNSET + ), + max_span_attribute_length=( + attribute_value_length_limit if attribute_value_length_limit is not None else SpanLimits.UNSET + ), + ) + + +def _to_tracer_config(config: TracerConfigConfig | None) -> _TracerConfig: + """Map an experimental per-tracer config to an SDK ``_TracerConfig``. + + Only ``enabled`` is honored — it is the sole field the SDK + ``_TracerConfig`` exposes. An absent ``enabled`` leaves the tracer enabled. + """ + if config is None or config.enabled is None: + return _TracerConfig.default() + return _TracerConfig(is_enabled=config.enabled) + + +def _create_tracer_configurator( + config: TracerConfiguratorConfig, +) -> _RuleBasedTracerConfigurator: + """Build a rule-based tracer configurator from experimental config. + + Each entry in ``tracers`` maps an instrumentation-scope name glob to a + per-tracer config; ``default_config`` applies to scopes matching no glob. + Rules are evaluated in order, so earlier entries take precedence. + """ + rules = [ + ( + _scope_name_matches_glob(matcher.name), + _to_tracer_config(matcher.config), + ) + for matcher in (config.tracers or []) + ] + return _RuleBasedTracerConfigurator( + rules=rules, + default_config=_to_tracer_config(config.default_config), + ) + + +def create_tracer_provider( + config: TracerProviderConfig | None, + resource: Resource | None = None, + global_attribute_limits: AttributeLimits | None = None, +) -> TracerProvider: + """Create an SDK TracerProvider from declarative config. + + Does NOT read OTEL_TRACES_SAMPLER, OTEL_SPAN_*_LIMIT, or any other env vars + for values that are explicitly controlled by the config. Absent config values + use OTel spec defaults (not env vars), matching Java SDK behavior. + + Args: + config: TracerProvider config from the parsed config file, or None. + resource: Resource to attach to the provider. + global_attribute_limits: Top-level attribute_limits from the root config, + used as a fallback when per-signal limits are not specified. + + Returns: + A configured TracerProvider. + """ + sampler = _create_sampler(config.sampler) if config is not None and config.sampler is not None else _DEFAULT_SAMPLER + id_generator = ( + _create_id_generator(config.id_generator) if config is not None and config.id_generator is not None else None + ) + if config is not None and config.limits is not None: + limits = config.limits + + else: + limits = SpanLimitsConfig() + + span_limits = _create_span_limits(limits, global_attribute_limits) + + tracer_configurator = ( + _create_tracer_configurator(config.tracer_configurator_development) + if config is not None and config.tracer_configurator_development is not None + else None + ) + + provider = TracerProvider( + resource=resource, + sampler=sampler, + span_limits=span_limits, + id_generator=id_generator, + _tracer_configurator=tracer_configurator, + ) + + if config is not None: + for proc_config in config.processors: + provider.add_span_processor(_create_span_processor(proc_config)) + + return provider + + +def configure_tracer_provider( + config: TracerProviderConfig | None, + resource: Resource | None = None, + global_attribute_limits: AttributeLimits | None = None, +) -> None: + """Configure the global TracerProvider from declarative config. + + When config is None (tracer_provider section absent from config file), + the global is not set — matching Java/JS SDK behavior and the spec's + "a noop tracer provider is used" default. + + Args: + config: TracerProvider config from the parsed config file, or None. + resource: Resource to attach to the provider. + global_attribute_limits: Top-level attribute_limits from the root config, + used as a fallback when per-signal limits are not specified. + """ + if config is None: + return + trace.set_tracer_provider(create_tracer_provider(config, resource, global_attribute_limits)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py new file mode 100644 index 00000000000..17af64baee5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py @@ -0,0 +1,58 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""OpenTelemetry SDK File Configuration. + +This module provides support for configuring the OpenTelemetry SDK +using declarative configuration files (YAML or JSON). + +Example: + >>> from opentelemetry.configuration.file import load_config_file + >>> config = load_config_file("otel-config.yaml") + >>> print(config.file_format) + '1.0' +""" + +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( + ConfigurationError, + MissingDependencyError, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._logger_provider import ( + configure_logger_provider, + create_logger_provider, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._meter_provider import ( + configure_meter_provider, + create_meter_provider, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._propagator import ( + configure_propagator, + create_propagator, +) +from opentelemetry.agent._vendor.opentelemetry.configuration._resource import create_resource +from opentelemetry.agent._vendor.opentelemetry.configuration._sdk import configure_sdk +from opentelemetry.agent._vendor.opentelemetry.configuration._tracer_provider import ( + configure_tracer_provider, + create_tracer_provider, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.file._env_substitution import ( + substitute_env_vars, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.file._loader import load_config_file + +__all__ = [ + "ConfigurationError", + "MissingDependencyError", + "configure_logger_provider", + "configure_meter_provider", + "configure_propagator", + "configure_sdk", + "configure_tracer_provider", + "create_logger_provider", + "create_meter_provider", + "create_propagator", + "create_resource", + "create_tracer_provider", + "load_config_file", + "substitute_env_vars", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py new file mode 100644 index 00000000000..82327ce2db7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py @@ -0,0 +1,82 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Environment variable substitution for configuration files.""" + +import os +import re + + +def substitute_env_vars(text: str) -> str: + """Substitute environment variables within a configuration value. + + A configuration value is a single value from the parsed configuration file + (the value of one key or one list item), never a key, a comment, or a whole + mapping/list. Substitution is applied per configuration value after the + file has been parsed, so comments and mapping keys are never touched. + + For example, given the YAML:: + + service_name: ${SERVICE_NAME} + endpoint: http://${HOST}:${PORT} + + the configuration values are ``${SERVICE_NAME}`` and + ``http://${HOST}:${PORT}``; this function is called once with each, and + never with the keys ``service_name`` or ``endpoint``. + + Supports the following syntax: + + - ${VAR}: Substitute with environment variable VAR, or an empty value if + VAR is not set. + - ${VAR:-default}: Substitute with VAR if set, otherwise use default value. + - $$: Escape sequence for literal $. + + Per the declarative configuration specification, a referenced environment + variable that is not set and has no default is replaced with an empty + value (which the YAML parser then interprets as null). This matches the + behavior of the Java and Node.js implementations and lets configuration + files be shared across languages. + + Args: + text: A configuration value with potential ${VAR} placeholders. + + Returns: + The configuration value with environment variables substituted. + + Examples: + >>> os.environ["SERVICE_NAME"] = "my-service" + >>> substitute_env_vars("${SERVICE_NAME}") + 'my-service' + >>> substitute_env_vars("${MISSING:-default}") + 'default' + >>> substitute_env_vars("$$100") + '$100' + """ + # Pattern matches $$ (escape sequence) or ${VAR_NAME} / ${VAR_NAME:-default_value} + # Handling both in a single pass ensures $$ followed by ${VAR} works correctly + pattern = r"\$\$|\$\{([A-Za-z_][A-Za-z0-9_]*)(:-([^}]*))?\}" + + def replace_var(match) -> str: + if match.group(1) is None: + # Matched $$, return literal $ + return "$" + + var_name = match.group(1) + has_default = match.group(2) is not None + default_value = match.group(3) if has_default else None + + value = os.environ.get(var_name) + + if value is None: + # An unset variable is replaced with its default if one is + # provided, otherwise with an empty value, per the spec. + return default_value or "" + + # Substitution runs on an already-parsed configuration value, so the + # result cannot inject new YAML structure regardless of its contents + # (a newline in the value stays a literal character within this one + # value). Type interpretation for standalone references is handled by + # the loader, which re-resolves the node tag after substitution. + return value + + return re.sub(pattern, replace_var, text) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py new file mode 100644 index 00000000000..44029a96def --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py @@ -0,0 +1,376 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Configuration file loading and parsing.""" + +import json +import logging +import os +import re +from pathlib import Path +from typing import Any + +from opentelemetry.agent._vendor.opentelemetry.configuration._conversion import _dict_to_dataclass +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( + ConfigurationError, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.file._env_substitution import ( + substitute_env_vars, +) +from opentelemetry.agent._vendor.opentelemetry.configuration.models import OpenTelemetryConfiguration + +# opentelemetry-agent: pyyaml and jsonschema have no pure-Python wheels (jsonschema needs rpds-py), +# so the vendored ruamel.yaml (its pure-Python, PyYAML-style loader API) and fastjsonschema stand in. +from opentelemetry.agent._vendor import fastjsonschema +from opentelemetry.agent._vendor.ruamel.yaml import nodes as _yaml_nodes +from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError +from opentelemetry.agent._vendor.ruamel.yaml.loader import SafeLoader as _RuamelSafeLoader + + +class SafeLoader(_RuamelSafeLoader): + # Only ruamel.yaml's YAML class sets the composer's nesting limit; 0 means none, like PyYAML. + max_depth = 0 + +# Schema version vendored in schema.json. ``file_format`` values are accepted +# per the configuration spec's versioning rules: the major version must match, +# and a minor version newer than the one this SDK targets is accepted with a +# warning. See +# https://github.com/open-telemetry/opentelemetry-configuration/blob/main/VERSIONING.md +_SUPPORTED_SCHEMA_MAJOR = 1 +_SUPPORTED_SCHEMA_MINOR = 1 + +_schema_cache: list[dict] = [] +_validator_cache: list[Any] = [] + + +def _get_schema() -> dict: + if not _schema_cache: + # opentelemetry-agent: resolve the schema relative to this (vendored) package, not by name. + schema_path = Path(__file__).resolve().parent.parent / "schema.json" + _schema_cache.append(json.loads(schema_path.read_text(encoding="utf-8"))) + return _schema_cache[0] + + +def _get_validator() -> Any: + # Compiling the schema generates and executes Python code; do it once. + if not _validator_cache: + _validator_cache.append(fastjsonschema.compile(_get_schema())) + return _validator_cache[0] + + +_logger = logging.getLogger(__name__) + +_YAML_STR_TAG = "tag:yaml.org,2002:str" + +# A configuration value whose entire content is a single ``${VAR}`` / +# ``${VAR:-default}`` reference. Only such standalone references (when +# unquoted) have their type re-interpreted after substitution; embedded or +# multiple references resolve to a string per the configuration spec. A +# leading ``$$`` escape does not match, so ``$${VAR}`` is treated as an +# embedded (string) value. +_STANDALONE_ENV_REF = re.compile(r"\A\$\{[A-Za-z_][A-Za-z0-9_]*(?::-[^}]*)?\}\Z") + + +def _substitute_env_in_yaml_node( + node: _yaml_nodes.Node, + loader: SafeLoader, + visited: set[int] | None = None, +): + """Apply env-var substitution to string configuration values in a node tree. + + Substitution runs after parsing on configuration values only, so comments + and mapping keys are never candidates (per the configuration spec). For an + unquoted standalone ``${VAR}`` reference the node's type tag is re-resolved + from the substituted value so YAML type coercion still applies (e.g. + ``${LIMIT}`` -> int); quoted or embedded references stay strings. + + Args: + node: Root of the node tree to walk. Substitution happens in place. + loader: The loader that composed ``node``; used to re-resolve tags. + visited: Ids of nodes already processed in this traversal. Callers pass + nothing; the walker creates and threads one set through the whole + tree. + """ + # Every anchor/alias pair shares one composed node, so the same node is + # reached once per reference to it. Each node must be substituted exactly + # once for two reasons: + # + # 1. Substituting twice re-reads the output of the first pass. An + # anchored ``$${TOKEN}`` becomes the escaped literal ``${TOKEN}`` on + # the first visit, which the second visit then resolves as a real + # variable -- silently defeating the ``$$`` escape. + # 2. A cyclic alias (``a: &anchor {self: *anchor}``) makes the node tree + # a graph with a loop, so an unguarded walk recurses until it raises + # ``RecursionError``. + # + # Tracking ``id(node)`` is safe here because ``root_node`` keeps every node + # in the tree alive for the whole traversal, so no id can be reused. + if visited is None: + visited = set() + if id(node) in visited: + return + visited.add(id(node)) + # Worked example: a node value that makes all three checks below true. + # + # YAML (with environment LIMIT=100): + # attribute_limits: + # attribute_count_limit: ${LIMIT} + # + # The parser hands this function the value node of attribute_count_limit, + # which has value="${LIMIT}", tag=str, style=None (plain/unquoted). Then: + # + # 1. isinstance(node, ScalarNode) -> True: it is a leaf value. + # 2. node.tag == _YAML_STR_TAG -> True: "${LIMIT}" is not a number or + # bool, so the parser tagged it str. We substitute in place, giving + # node.value = "100". + # 3. node.style is None and _STANDALONE_ENV_REF.match(raw) -> True: + # it was unquoted and the whole value is a single reference. We + # re-resolve the tag: resolve("100") -> int, and construct_document() + # later builds the integer 100 (not the string "100"). + # + # Counter-cases that reach check 3 but stop there: "${LIMIT}" quoted fails + # the style test; x${LIMIT} fails the regex. Both keep the str tag. + if isinstance(node, _yaml_nodes.ScalarNode): + # A ``ScalarNode`` is a leaf -- one configuration value. Only a + # ``str``-tagged one can hold a ``${VAR}`` reference (nodes the parser + # already typed as int, float, bool or null cannot), so those are the + # only substitution candidates. + if node.tag == _YAML_STR_TAG: + # ``node.value`` is the raw text of this one value (never a key or + # comment). Replace any ${VAR} / ${VAR:-default} / $$ in it. + raw = node.value + node.value = substitute_env_vars(raw) + # The spec says node types are interpreted *after* substitution, + # but only for a value that is exactly one reference and written + # unquoted (``style is None``). Example: ``count: ${N}`` with + # ``N=42`` must yield the int 42, not the string "42". In that case + # re-run YAML's implicit type resolution on the substituted text + # and retag the node. A quoted (``"${N}"``) or embedded + # (``foo-${N}``) value keeps its ``str`` tag and stays a string. + if node.style is None and _STANDALONE_ENV_REF.match(raw): + # ``resolve`` returns the implicit tag (int/float/bool/null/ + # str) YAML would assign to ``node.value``; the ``(True, False)`` + # implicit-flag pair marks it as a plain scalar so that + # type-guessing applies, exactly as during normal parsing. + node.tag = loader.resolve(_yaml_nodes.ScalarNode, node.value, (True, False)) + elif isinstance(node, _yaml_nodes.SequenceNode): + # A sequence (list): each item is itself a value node -- recurse. + for item in node.value: + _substitute_env_in_yaml_node(item, loader, visited) + elif isinstance(node, _yaml_nodes.MappingNode): + # A mapping (dict): recurse into values only; keys are not + # substitution candidates per the spec. A merge key (``<<: *base``) + # appears here as an ordinary pair whose value node is the anchored + # mapping itself, so ``visited`` also covers the merged-in values. + for _key_node, value_node in node.value: + _substitute_env_in_yaml_node(value_node, loader, visited) + + +def _substitute_env_in_json_value(value: Any) -> Any: + """Recursively apply env-var substitution to string values in JSON data. + + JSON has explicit types and no comments, so substitution applies only to + string values (the result stays a string) and mapping keys are left as-is. + """ + if isinstance(value, str): + return substitute_env_vars(value) + if isinstance(value, list): + return [_substitute_env_in_json_value(item) for item in value] + if isinstance(value, dict): + return {key: _substitute_env_in_json_value(val) for key, val in value.items()} + return value + + +def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLike[str]) -> Any: + """Parse configuration text and substitute environment variables. + + Parsing happens first, so ``${VAR}`` references in comments and mapping + keys are never substitution candidates; substitution then runs on + configuration values, with YAML node types re-resolved for standalone + references. + + Raises: + ConfigurationError: If the content cannot be parsed or substitution of + a required environment variable fails. + """ + try: + if suffix == ".json": + return _substitute_env_in_json_value(json.loads(content)) + # YAML 1.2 core schema, as the configuration spec requires (PyYAML implements YAML 1.1). + yaml_loader = SafeLoader(content) + try: + root_node = yaml_loader.get_single_node() + if root_node is None: + return None + _substitute_env_in_yaml_node(root_node, yaml_loader) + return yaml_loader.construct_document(root_node) + finally: + yaml_loader.dispose() + except YAMLError as exc: + _logger.exception("Failed to parse YAML from %s", file_path) + raise ConfigurationError(f"Failed to parse YAML: {exc}") from exc + except json.JSONDecodeError as exc: + _logger.exception("Failed to parse JSON from %s", file_path) + raise ConfigurationError(f"Failed to parse JSON: {exc}") from exc + + +def load_config_file( + file_path: str | os.PathLike[str], +) -> OpenTelemetryConfiguration: + """Load and parse an OpenTelemetry configuration file. + + Supports YAML and JSON formats. Environment variable substitution is + performed after parsing, on configuration values only, so ``${VAR}`` + references in comments or mapping keys are left untouched. + + Args: + file_path: Path to the configuration file (.yaml, .yml, or .json). + + Returns: + Parsed OpenTelemetryConfiguration object. + + Raises: + ConfigurationError: If file cannot be read, parsed, or validated. + + Examples: + >>> config = load_config_file("otel-config.yaml") + >>> print(config.tracer_provider) + """ + path = Path(file_path) + + if not path.exists(): + _logger.error("Configuration file not found: %s", file_path) + raise ConfigurationError(f"Configuration file not found: {file_path}") + + if not path.is_file(): + _logger.error("Configuration path is not a file: %s", file_path) + raise ConfigurationError(f"Configuration path is not a file: {file_path}") + + try: + with open(path, encoding="utf-8") as config_file: + content = config_file.read() + except OSError as exc: + _logger.exception("Failed to read configuration file: %s", file_path) + raise ConfigurationError(f"Failed to read configuration file: {file_path}") from exc + + # Parse the file, then substitute env vars in configuration values only. + # Parsing first means comments and mapping keys are never substitution + # candidates, and node types are still resolved after substitution. + suffix = path.suffix.lower() + if suffix not in (".yaml", ".yml", ".json"): + _logger.error("Unsupported file format: %s", suffix) + raise ConfigurationError(f"Unsupported file format: {suffix}. Use .yaml, .yml, or .json") + + data = _parse_config_content(content, suffix, file_path) + + if data is None: + _logger.error("Configuration file is empty: %s", file_path) + raise ConfigurationError("Configuration file is empty") + + if not isinstance(data, dict): + _logger.error( + "Configuration must be a mapping/object, got %s", + type(data).__name__, + ) + raise ConfigurationError(f"Configuration must be a mapping/object, got {type(data).__name__}") + + _validate_schema(data) + _validate_file_format(data) + + # Convert to OpenTelemetryConfiguration model + try: + config = _dict_to_model(data) + except Exception as exc: + _logger.exception("Failed to validate configuration from %s", file_path) + raise ConfigurationError(f"Failed to validate configuration: {exc}") from exc + + return config + + +def _validate_schema(data: dict) -> None: + """Validate configuration dict against the OTel configuration JSON schema. + + Raises: + ConfigurationError: If the data does not conform to the schema. + """ + try: + _get_validator()(data) + except fastjsonschema.JsonSchemaValueException as exc: + # The path starts with the root's name ("data"). + path = exc.path[1:] + raise ConfigurationError( + f"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in path)})" + if path + else f"Configuration does not match schema: {exc.message}" + ) from exc + except fastjsonschema.JsonSchemaDefinitionException as exc: + raise ConfigurationError(f"Invalid configuration schema: {exc}") from exc + + +def _validate_file_format(data: dict) -> None: + """Validate the ``file_format`` version per the configuration spec. + + The spec requires implementations to fail on an unsupported major version + (a breaking-change boundary) and to accept, with a warning, a minor version + newer than the one this SDK targets. See + https://github.com/open-telemetry/opentelemetry-configuration/blob/main/VERSIONING.md + + Raises: + ConfigurationError: If ``file_format`` is malformed or its major + version is not supported. + """ + file_format = data.get("file_format") + # file_format is required and typed as a string by the schema, which is + # validated before this runs; guard defensively regardless. + if not isinstance(file_format, str): + raise ConfigurationError(f"Invalid file_format: expected a version string, got {file_format!r}") + + # Drop any pre-release / meta tag, e.g. "1.0-rc.2" -> "1.0". + version = file_format.split("-", 1)[0] + parts = version.split(".") + try: + major = int(parts[0]) + minor = int(parts[1]) if len(parts) > 1 else 0 + except ValueError as exc: + raise ConfigurationError(f"Invalid file_format '{file_format}': expected MAJOR.MINOR version numbers") from exc + + if major != _SUPPORTED_SCHEMA_MAJOR: + raise ConfigurationError( + f"Unsupported file_format '{file_format}': this SDK supports schema version {_SUPPORTED_SCHEMA_MAJOR}.x" + ) + + if minor > _SUPPORTED_SCHEMA_MINOR: + _logger.warning( + "Configuration file_format '%s' has a newer minor version than " + "this SDK supports (%d.%d); some settings may be ignored.", + file_format, + _SUPPORTED_SCHEMA_MAJOR, + _SUPPORTED_SCHEMA_MINOR, + ) + + +def _dict_to_model(data: dict[str, Any]) -> OpenTelemetryConfiguration: + """Convert a parsed config dictionary to the full typed model tree. + + Walks each field's type annotation, recursively converting nested + dicts to their corresponding dataclass types. The resulting + ``OpenTelemetryConfiguration`` is fully typed end-to-end, so factory + functions can rely on typed attribute access (e.g. ``config.sampler``, + ``config.processors[0].batch.exporter``). + + Args: + data: Parsed configuration dictionary. + + Returns: + OpenTelemetryConfiguration instance. + + Raises: + TypeError: If data doesn't match expected structure. + ValueError: If values are invalid. + """ + try: + return _dict_to_dataclass(data, OpenTelemetryConfiguration) + except TypeError as exc: + raise TypeError( + f"Configuration structure is invalid. Check that all required fields are present and correctly typed: {exc}" + ) from exc diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py new file mode 100644 index 00000000000..884ba470ea8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py @@ -0,0 +1,73 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from dataclasses import fields, is_dataclass +from inspect import isclass +from logging import getLogger + +from opentelemetry.agent._vendor.opentelemetry.configuration._common import load_entry_point +from opentelemetry.agent._vendor.opentelemetry.configuration._conversion import _dict_to_dataclass +from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ConfigurationError +from opentelemetry.agent._vendor.opentelemetry.configuration.models import ExperimentalInstrumentation + +_logger = getLogger(__name__) + + +def configure_instrumentation( + configuration: ExperimentalInstrumentation | None, +) -> None: + """Activate instrumentors listed under ``instrumentation/development.python``. + + For each entry in ``configuration.python`` the matching + ``opentelemetry_instrumentor`` entry point is loaded. If the instrumentor + class exposes a ``configuration`` attribute that is a dataclass type, the + raw options are validated through ``_dict_to_dataclass`` before being + forwarded to ``instrument()``. An ``enabled: false`` value suppresses + instrumentation without raising. + + If an instrumentor is already active (e.g. ``opentelemetry-instrument`` + ran before the SDK was configured from the file) its ``instrument()`` call + is skipped to avoid a double-instrumentation warning. + + Absent or unknown entry points are logged as warnings; runtime errors from + an instrumentor are logged as exceptions. Neither stops the remaining + instrumentors from being applied. + """ + if configuration is None or configuration.python is None: + return + + for name, options in configuration.python.items(): + options = dict(options) + if not options.pop("enabled", True): + _logger.debug( + "Instrumentation '%s' is disabled in declarative config; skipping", + name, + ) + continue + + try: + cls = load_entry_point("opentelemetry_instrumentor", name) + configuration_cls = getattr(cls, "configuration", None) + if isclass(configuration_cls) and is_dataclass(configuration_cls): + configuration_obj = _dict_to_dataclass(options, configuration_cls) + options = { + f.name: value + for f in fields(configuration_obj) + if (value := getattr(configuration_obj, f.name)) is not None + } + instance = cls() + if getattr(instance, "is_instrumented_by_opentelemetry", False): + _logger.debug("Skipping '%s': already instrumented", name) + else: + instance.instrument(**options) + _logger.debug("Instrumented '%s' via declarative config", name) + except ConfigurationError as exc: + _logger.warning( + "Skipping instrumentation '%s' in declarative config: %s", + name, + exc, + ) + except Exception: # pylint: disable=broad-except + _logger.exception("Failed to instrument '%s' via declarative config", name) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py new file mode 100644 index 00000000000..fc7cc2ae5a1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py @@ -0,0 +1,803 @@ +# generated by datamodel-codegen: +# filename: schema.json +# timestamp: 2026-06-23T15:17:37+00:00 + +from __future__ import annotations + +from dataclasses import dataclass +from enum import Enum +from typing import Any, ClassVar, TypeAlias + +from opentelemetry.agent._vendor.opentelemetry.configuration._common import _additional_properties + +AlwaysOffSampler: TypeAlias = dict[str, Any] | None + + +AlwaysOnSampler: TypeAlias = dict[str, Any] | None + + +@dataclass +class AttributeLimits: + attribute_value_length_limit: int | None = None + attribute_count_limit: int | None = None + + +Value: TypeAlias = list[str] + + +Value1: TypeAlias = list[bool] + + +Value2: TypeAlias = list[float] + + +class AttributeType(Enum): + string = "string" + bool = "bool" + int = "int" + double = "double" + string_array = "string_array" + bool_array = "bool_array" + int_array = "int_array" + double_array = "double_array" + + +B3MultiPropagator: TypeAlias = dict[str, Any] | None + + +B3Propagator: TypeAlias = dict[str, Any] | None + + +BaggagePropagator: TypeAlias = dict[str, Any] | None + + +@dataclass +class Base2ExponentialBucketHistogramAggregation: + max_scale: int | None = None + max_size: int | None = None + record_min_max: bool | None = None + + +@dataclass +class CardinalityLimits: + default: int | None = None + counter: int | None = None + gauge: int | None = None + histogram: int | None = None + observable_counter: int | None = None + observable_gauge: int | None = None + observable_up_down_counter: int | None = None + up_down_counter: int | None = None + + +ConsoleExporter: TypeAlias = dict[str, Any] | None + + +DefaultAggregation: TypeAlias = dict[str, Any] | None + + +Distribution: TypeAlias = dict[str, dict[str, Any]] + + +DropAggregation: TypeAlias = dict[str, Any] | None + + +class ExemplarFilter(Enum): + always_on = "always_on" + always_off = "always_off" + trace_based = "trace_based" + + +ExperimentalComposableAlwaysOffSampler: TypeAlias = dict[str, Any] | None + + +ExperimentalComposableAlwaysOnSampler: TypeAlias = dict[str, Any] | None + + +@dataclass +class ExperimentalComposableProbabilitySampler: + ratio: float | None = None + + +@dataclass +class ExperimentalComposableRuleBasedSamplerRuleAttributePatterns: + key: str + included: list[str] | None = None + excluded: list[str] | None = None + + +@dataclass +class ExperimentalComposableRuleBasedSamplerRuleAttributeValues: + key: str + values: list[str] + + +ExperimentalContainerResourceDetector: TypeAlias = dict[str, Any] | None + + +ExperimentalEventToSpanEventBridgeLogRecordProcessor: TypeAlias = dict[str, Any] | None + + +ExperimentalHostResourceDetector: TypeAlias = dict[str, Any] | None + + +@dataclass +class ExperimentalHttpClientInstrumentation: + request_captured_headers: list[str] | None = None + response_captured_headers: list[str] | None = None + known_methods: list[str] | None = None + + +@dataclass +class ExperimentalHttpServerInstrumentation: + request_captured_headers: list[str] | None = None + response_captured_headers: list[str] | None = None + known_methods: list[str] | None = None + + +ExperimentalLanguageSpecificInstrumentation: TypeAlias = dict[str, dict[str, Any]] + + +@dataclass +class ExperimentalMeterConfig: + enabled: bool | None = None + + +@dataclass +class ExperimentalMeterMatcherAndConfig: + name: str + config: ExperimentalMeterConfig + + +@dataclass +class ExperimentalOtlpFileExporter: + output_stream: str | None = None + + +@dataclass +class ExperimentalProbabilitySampler: + ratio: float | None = None + + +ExperimentalProcessResourceDetector: TypeAlias = dict[str, Any] | None + + +class ExperimentalPrometheusTranslationStrategy(Enum): + underscore_escaping_with_suffixes = "underscore_escaping_with_suffixes" + underscore_escaping_without_suffixes_development = "underscore_escaping_without_suffixes/development" + no_utf8_escaping_with_suffixes_development = "no_utf8_escaping_with_suffixes/development" + no_translation_development = "no_translation/development" + + +@dataclass +class ExperimentalSemconvConfig: + version: int | None = None + experimental: bool | None = None + dual_emit: bool | None = None + + +ExperimentalServiceResourceDetector: TypeAlias = dict[str, Any] | None + + +class ExperimentalSpanParent(Enum): + none = "none" + remote = "remote" + local = "local" + + +@dataclass +class ExperimentalTracerConfig: + enabled: bool | None = None + + +@dataclass +class ExperimentalTracerMatcherAndConfig: + name: str + config: ExperimentalTracerConfig + + +@dataclass +class ExperimentalUrlSanitization: + sensitive_query_parameters: list[str] | None = None + + +@dataclass +class ExplicitBucketHistogramAggregation: + boundaries: list[float] | None = None + record_min_max: bool | None = None + + +class ExporterDefaultHistogramAggregation(Enum): + explicit_bucket_histogram = "explicit_bucket_histogram" + base2_exponential_bucket_histogram = "base2_exponential_bucket_histogram" + + +class ExporterTemporalityPreference(Enum): + cumulative = "cumulative" + delta = "delta" + low_memory = "low_memory" + + +@dataclass +class GrpcTls: + ca_file: str | None = None + key_file: str | None = None + cert_file: str | None = None + insecure: bool | None = None + + +@dataclass +class HttpTls: + ca_file: str | None = None + key_file: str | None = None + cert_file: str | None = None + + +@dataclass +class IncludeExclude: + included: list[str] | None = None + excluded: list[str] | None = None + + +class InstrumentType(Enum): + counter = "counter" + gauge = "gauge" + histogram = "histogram" + observable_counter = "observable_counter" + observable_gauge = "observable_gauge" + observable_up_down_counter = "observable_up_down_counter" + up_down_counter = "up_down_counter" + + +LastValueAggregation: TypeAlias = dict[str, Any] | None + + +@dataclass +class LogRecordLimits: + attribute_value_length_limit: int | None = None + attribute_count_limit: int | None = None + + +@dataclass +class NameStringValuePair: + name: str + value: str | None + + +OpenCensusMetricProducer: TypeAlias = dict[str, Any] | None + + +@dataclass +class OtlpGrpcExporter: + endpoint: str | None = None + tls: GrpcTls | None = None + headers: list[NameStringValuePair] | None = None + headers_list: str | None = None + compression: str | None = None + timeout: int | None = None + + +@dataclass +class OtlpGrpcMetricExporter: + endpoint: str | None = None + tls: GrpcTls | None = None + headers: list[NameStringValuePair] | None = None + headers_list: str | None = None + compression: str | None = None + timeout: int | None = None + temporality_preference: ExporterTemporalityPreference | None = None + default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None + + +class OtlpHttpEncoding(Enum): + protobuf = "protobuf" + json = "json" + + +@dataclass +class OtlpHttpExporter: + endpoint: str | None = None + tls: HttpTls | None = None + headers: list[NameStringValuePair] | None = None + headers_list: str | None = None + compression: str | None = None + timeout: int | None = None + encoding: OtlpHttpEncoding | None = None + + +@dataclass +class OtlpHttpMetricExporter: + endpoint: str | None = None + tls: HttpTls | None = None + headers: list[NameStringValuePair] | None = None + headers_list: str | None = None + compression: str | None = None + timeout: int | None = None + encoding: OtlpHttpEncoding | None = None + temporality_preference: ExporterTemporalityPreference | None = None + default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None + + +RandomIdGenerator: TypeAlias = dict[str, Any] | None + + +class SeverityNumber(Enum): + trace = "trace" + trace2 = "trace2" + trace3 = "trace3" + trace4 = "trace4" + debug = "debug" + debug2 = "debug2" + debug3 = "debug3" + debug4 = "debug4" + info = "info" + info2 = "info2" + info3 = "info3" + info4 = "info4" + warn = "warn" + warn2 = "warn2" + warn3 = "warn3" + warn4 = "warn4" + error = "error" + error2 = "error2" + error3 = "error3" + error4 = "error4" + fatal = "fatal" + fatal2 = "fatal2" + fatal3 = "fatal3" + fatal4 = "fatal4" + + +@_additional_properties +@dataclass +class SpanExporter: + otlp_http: OtlpHttpExporter | None = None + otlp_grpc: OtlpGrpcExporter | None = None + otlp_file_development: ExperimentalOtlpFileExporter | None = None + console: ConsoleExporter | None = None + additional_properties: ClassVar[dict[str, Any]] + + +class SpanKind(Enum): + internal = "internal" + server = "server" + client = "client" + producer = "producer" + consumer = "consumer" + + +@dataclass +class SpanLimits: + attribute_value_length_limit: int | None = None + attribute_count_limit: int | None = None + event_count_limit: int | None = None + link_count_limit: int | None = None + event_attribute_count_limit: int | None = None + link_attribute_count_limit: int | None = None + + +SumAggregation: TypeAlias = dict[str, Any] | None + + +TraceContextPropagator: TypeAlias = dict[str, Any] | None + + +@dataclass +class TraceIdRatioBasedSampler: + ratio: float | None = None + + +@dataclass +class ViewSelector: + instrument_name: str | None = None + instrument_type: InstrumentType | None = None + unit: str | None = None + meter_name: str | None = None + meter_version: str | None = None + meter_schema_url: str | None = None + + +@dataclass +class Aggregation: + default: DefaultAggregation | None = None + drop: DropAggregation | None = None + explicit_bucket_histogram: ExplicitBucketHistogramAggregation | None = None + base2_exponential_bucket_histogram: Base2ExponentialBucketHistogramAggregation | None = None + last_value: LastValueAggregation | None = None + sum: SumAggregation | None = None + + +@dataclass +class AttributeNameValue: + name: str + value: str | float | bool | Value | Value1 | Value2 | None + type: AttributeType | None = None + + +@dataclass +class BatchSpanProcessor: + exporter: SpanExporter + schedule_delay: int | None = None + export_timeout: int | None = None + max_queue_size: int | None = None + max_export_batch_size: int | None = None + + +@dataclass +class ConsoleMetricExporter: + temporality_preference: ExporterTemporalityPreference | None = None + default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None + + +@dataclass +class ExperimentalCodeInstrumentation: + semconv: ExperimentalSemconvConfig | None = None + + +@dataclass +class ExperimentalDbInstrumentation: + semconv: ExperimentalSemconvConfig | None = None + + +@dataclass +class ExperimentalGenAiInstrumentation: + semconv: ExperimentalSemconvConfig | None = None + + +@dataclass +class ExperimentalHttpInstrumentation: + semconv: ExperimentalSemconvConfig | None = None + client: ExperimentalHttpClientInstrumentation | None = None + server: ExperimentalHttpServerInstrumentation | None = None + + +@dataclass +class ExperimentalLoggerConfig: + enabled: bool | None = None + minimum_severity: SeverityNumber | None = None + trace_based: bool | None = None + + +@dataclass +class ExperimentalLoggerMatcherAndConfig: + name: str + config: ExperimentalLoggerConfig + + +@dataclass +class ExperimentalMessagingInstrumentation: + semconv: ExperimentalSemconvConfig | None = None + + +@dataclass +class ExperimentalMeterConfigurator: + default_config: ExperimentalMeterConfig | None = None + meters: list[ExperimentalMeterMatcherAndConfig] | None = None + + +@dataclass +class ExperimentalOtlpFileMetricExporter: + output_stream: str | None = None + temporality_preference: ExporterTemporalityPreference | None = None + default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None + + +@dataclass +class ExperimentalPrometheusMetricExporter: + host: str | None = None + port: int | None = None + scope_info_enabled: bool | None = None + target_info_enabled_development: bool | None = None + resource_constant_labels: IncludeExclude | None = None + translation_strategy: ExperimentalPrometheusTranslationStrategy | None = None + + +@_additional_properties +@dataclass +class ExperimentalResourceDetector: + container: ExperimentalContainerResourceDetector | None = None + host: ExperimentalHostResourceDetector | None = None + process: ExperimentalProcessResourceDetector | None = None + service: ExperimentalServiceResourceDetector | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class ExperimentalRpcInstrumentation: + semconv: ExperimentalSemconvConfig | None = None + + +@dataclass +class ExperimentalSanitization: + url: ExperimentalUrlSanitization | None = None + + +@dataclass +class ExperimentalTracerConfigurator: + default_config: ExperimentalTracerConfig | None = None + tracers: list[ExperimentalTracerMatcherAndConfig] | None = None + + +@_additional_properties +@dataclass +class IdGenerator: + random: RandomIdGenerator | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@_additional_properties +@dataclass +class LogRecordExporter: + otlp_http: OtlpHttpExporter | None = None + otlp_grpc: OtlpGrpcExporter | None = None + otlp_file_development: ExperimentalOtlpFileExporter | None = None + console: ConsoleExporter | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@_additional_properties +@dataclass +class MetricProducer: + opencensus: OpenCensusMetricProducer | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@_additional_properties +@dataclass +class PullMetricExporter: + prometheus_development: ExperimentalPrometheusMetricExporter | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class PullMetricReader: + exporter: PullMetricExporter + producers: list[MetricProducer] | None = None + cardinality_limits: CardinalityLimits | None = None + + +@_additional_properties +@dataclass +class PushMetricExporter: + otlp_http: OtlpHttpMetricExporter | None = None + otlp_grpc: OtlpGrpcMetricExporter | None = None + otlp_file_development: ExperimentalOtlpFileMetricExporter | None = None + console: ConsoleMetricExporter | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class SimpleLogRecordProcessor: + exporter: LogRecordExporter + + +@dataclass +class SimpleSpanProcessor: + exporter: SpanExporter + + +@_additional_properties +@dataclass +class SpanProcessor: + batch: BatchSpanProcessor | None = None + simple: SimpleSpanProcessor | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@_additional_properties +@dataclass +class TextMapPropagator: + tracecontext: TraceContextPropagator | None = None + baggage: BaggagePropagator | None = None + b3: B3Propagator | None = None + b3multi: B3MultiPropagator | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class ViewStream: + name: str | None = None + description: str | None = None + aggregation: Aggregation | None = None + aggregation_cardinality_limit: int | None = None + attribute_keys: IncludeExclude | None = None + + +@dataclass +class BatchLogRecordProcessor: + exporter: LogRecordExporter + schedule_delay: int | None = None + export_timeout: int | None = None + max_queue_size: int | None = None + max_export_batch_size: int | None = None + + +@dataclass +class ExperimentalGeneralInstrumentation: + http: ExperimentalHttpInstrumentation | None = None + code: ExperimentalCodeInstrumentation | None = None + db: ExperimentalDbInstrumentation | None = None + gen_ai: ExperimentalGenAiInstrumentation | None = None + messaging: ExperimentalMessagingInstrumentation | None = None + rpc: ExperimentalRpcInstrumentation | None = None + sanitization: ExperimentalSanitization | None = None + stability_opt_in_list: str | None = None + + +@dataclass +class ExperimentalInstrumentation: + general: ExperimentalGeneralInstrumentation | None = None + cpp: ExperimentalLanguageSpecificInstrumentation | None = None + dotnet: ExperimentalLanguageSpecificInstrumentation | None = None + erlang: ExperimentalLanguageSpecificInstrumentation | None = None + go: ExperimentalLanguageSpecificInstrumentation | None = None + java: ExperimentalLanguageSpecificInstrumentation | None = None + js: ExperimentalLanguageSpecificInstrumentation | None = None + php: ExperimentalLanguageSpecificInstrumentation | None = None + python: ExperimentalLanguageSpecificInstrumentation | None = None + ruby: ExperimentalLanguageSpecificInstrumentation | None = None + rust: ExperimentalLanguageSpecificInstrumentation | None = None + swift: ExperimentalLanguageSpecificInstrumentation | None = None + + +@dataclass +class ExperimentalLoggerConfigurator: + default_config: ExperimentalLoggerConfig | None = None + loggers: list[ExperimentalLoggerMatcherAndConfig] | None = None + + +@dataclass +class ExperimentalResourceDetection: + attributes: IncludeExclude | None = None + detectors: list[ExperimentalResourceDetector] | None = None + + +@_additional_properties +@dataclass +class LogRecordProcessor: + batch: BatchLogRecordProcessor | None = None + simple: SimpleLogRecordProcessor | None = None + event_to_span_event_bridge_development: ExperimentalEventToSpanEventBridgeLogRecordProcessor | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class PeriodicMetricReader: + exporter: PushMetricExporter + interval: int | None = None + timeout: int | None = None + max_export_batch_size_development: int | None = None + producers: list[MetricProducer] | None = None + cardinality_limits: CardinalityLimits | None = None + + +@dataclass +class Propagator: + composite: list[TextMapPropagator] | None = None + composite_list: str | None = None + + +@dataclass +class Resource: + attributes: list[AttributeNameValue] | None = None + detection_development: ExperimentalResourceDetection | None = None + schema_url: str | None = None + attributes_list: str | None = None + + +@dataclass +class View: + selector: ViewSelector + stream: ViewStream + + +@dataclass +class LoggerProvider: + processors: list[LogRecordProcessor] + limits: LogRecordLimits | None = None + logger_configurator_development: ExperimentalLoggerConfigurator | None = None + + +@dataclass +class MetricReader: + periodic: PeriodicMetricReader | None = None + pull: PullMetricReader | None = None + + +@dataclass +class MeterProvider: + readers: list[MetricReader] + views: list[View] | None = None + exemplar_filter: ExemplarFilter | None = None + meter_configurator_development: ExperimentalMeterConfigurator | None = None + + +@_additional_properties +@dataclass +class OpenTelemetryConfiguration: + file_format: str + disabled: bool | None = None + log_level: SeverityNumber | None = None + attribute_limits: AttributeLimits | None = None + logger_provider: LoggerProvider | None = None + meter_provider: MeterProvider | None = None + propagator: Propagator | None = None + tracer_provider: TracerProvider | None = None + resource: Resource | None = None + instrumentation_development: ExperimentalInstrumentation | None = None + distribution: Distribution | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class ExperimentalComposableParentThresholdSampler: + root: ExperimentalComposableSampler + + +@dataclass +class ExperimentalComposableRuleBasedSampler: + rules: list[ExperimentalComposableRuleBasedSamplerRule] | None = None + + +@dataclass +class ExperimentalComposableRuleBasedSamplerRule: + """ + A rule for ExperimentalComposableRuleBasedSampler. A rule can have multiple match conditions - the sampler will be applied if all match. + If no conditions are specified, the rule matches all spans that reach it. + + """ + + sampler: ExperimentalComposableSampler + attribute_values: ExperimentalComposableRuleBasedSamplerRuleAttributeValues | None = None + attribute_patterns: ExperimentalComposableRuleBasedSamplerRuleAttributePatterns | None = None + span_kinds: list[SpanKind] | None = None + parent: list[ExperimentalSpanParent] | None = None + + +@_additional_properties +@dataclass +class ExperimentalComposableSampler: + always_off: ExperimentalComposableAlwaysOffSampler | None = None + always_on: ExperimentalComposableAlwaysOnSampler | None = None + parent_threshold: ExperimentalComposableParentThresholdSampler | None = None + probability: ExperimentalComposableProbabilitySampler | None = None + rule_based: ExperimentalComposableRuleBasedSampler | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class ExperimentalJaegerRemoteSampler: + endpoint: str + initial_sampler: Sampler + interval: int | None = None + + +@dataclass +class ParentBasedSampler: + root: Sampler | None = None + remote_parent_sampled: Sampler | None = None + remote_parent_not_sampled: Sampler | None = None + local_parent_sampled: Sampler | None = None + local_parent_not_sampled: Sampler | None = None + + +@_additional_properties +@dataclass +class Sampler: + always_off: AlwaysOffSampler | None = None + always_on: AlwaysOnSampler | None = None + composite_development: ExperimentalComposableSampler | None = None + jaeger_remote_development: ExperimentalJaegerRemoteSampler | None = None + parent_based: ParentBasedSampler | None = None + probability_development: ExperimentalProbabilitySampler | None = None + trace_id_ratio_based: TraceIdRatioBasedSampler | None = None + additional_properties: ClassVar[dict[str, Any]] + + +@dataclass +class TracerProvider: + processors: list[SpanProcessor] + limits: SpanLimits | None = None + sampler: Sampler | None = None + id_generator: IdGenerator | None = None + tracer_configurator_development: ExperimentalTracerConfigurator | None = None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json new file mode 100644 index 00000000000..1a30982ecb6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json @@ -0,0 +1,2576 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "OpenTelemetryConfiguration", + "type": "object", + "additionalProperties": true, + "properties": { + "file_format": { + "type": "string", + "description": "The file format version.\nRepresented as a string including the semver major, minor version numbers (and optionally the meta tag). For example: \"0.4\", \"1.0-rc.2\", \"1.0\" (after stable release).\nSee https://github.com/open-telemetry/opentelemetry-configuration/blob/main/VERSIONING.md for more details.\nThe yaml format is documented at https://github.com/open-telemetry/opentelemetry-configuration/tree/main/schema\nProperty is required and must be non-null.\n" + }, + "disabled": { + "type": [ + "boolean", + "null" + ], + "description": "Configure if the SDK is disabled or not.\nIf omitted or null, false is used.\n" + }, + "log_level": { + "$ref": "#/$defs/SeverityNumber", + "description": "Configure the log level of the internal logger used by the SDK.\nValues include:\n* debug: debug, severity number 5.\n* debug2: debug2, severity number 6.\n* debug3: debug3, severity number 7.\n* debug4: debug4, severity number 8.\n* error: error, severity number 17.\n* error2: error2, severity number 18.\n* error3: error3, severity number 19.\n* error4: error4, severity number 20.\n* fatal: fatal, severity number 21.\n* fatal2: fatal2, severity number 22.\n* fatal3: fatal3, severity number 23.\n* fatal4: fatal4, severity number 24.\n* info: info, severity number 9.\n* info2: info2, severity number 10.\n* info3: info3, severity number 11.\n* info4: info4, severity number 12.\n* trace: trace, severity number 1.\n* trace2: trace2, severity number 2.\n* trace3: trace3, severity number 3.\n* trace4: trace4, severity number 4.\n* warn: warn, severity number 13.\n* warn2: warn2, severity number 14.\n* warn3: warn3, severity number 15.\n* warn4: warn4, severity number 16.\nIf omitted, INFO is used.\n" + }, + "attribute_limits": { + "$ref": "#/$defs/AttributeLimits", + "description": "Configure general attribute limits. See also tracer_provider.limits, logger_provider.limits.\nIf omitted, default values as described in AttributeLimits are used.\n" + }, + "logger_provider": { + "$ref": "#/$defs/LoggerProvider", + "description": "Configure logger provider.\nIf omitted, a noop logger provider is used.\n" + }, + "meter_provider": { + "$ref": "#/$defs/MeterProvider", + "description": "Configure meter provider.\nIf omitted, a noop meter provider is used.\n" + }, + "propagator": { + "$ref": "#/$defs/Propagator", + "description": "Configure text map context propagators.\nIf omitted, a noop propagator is used.\n" + }, + "tracer_provider": { + "$ref": "#/$defs/TracerProvider", + "description": "Configure tracer provider.\nIf omitted, a noop tracer provider is used.\n" + }, + "resource": { + "$ref": "#/$defs/Resource", + "description": "Configure resource for all signals.\nIf omitted, the default resource is used.\n" + }, + "instrumentation/development": { + "$ref": "#/$defs/ExperimentalInstrumentation", + "description": "Configure instrumentation.\nIf omitted, instrumentation defaults are used.\n" + }, + "distribution": { + "$ref": "#/$defs/Distribution", + "description": "Defines configuration parameters specific to a particular OpenTelemetry distribution or vendor.\nThis section provides a standardized location for distribution-specific settings\nthat are not part of the OpenTelemetry configuration model.\nIt allows vendors to expose their own extensions and general configuration options.\nIf omitted, distribution defaults are used.\n" + } + }, + "required": [ + "file_format" + ], + "$defs": { + "Aggregation": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "default": { + "$ref": "#/$defs/DefaultAggregation", + "description": "Configures the stream to use the instrument kind to select an aggregation and advisory parameters to influence aggregation configuration parameters. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#default-aggregation for details.\nIf omitted, ignore.\n" + }, + "drop": { + "$ref": "#/$defs/DropAggregation", + "description": "Configures the stream to ignore/drop all instrument measurements. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#drop-aggregation for details.\nIf omitted, ignore.\n" + }, + "explicit_bucket_histogram": { + "$ref": "#/$defs/ExplicitBucketHistogramAggregation", + "description": "Configures the stream to collect data for the histogram metric point using a set of explicit boundary values for histogram bucketing. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation for details\nIf omitted, ignore.\n" + }, + "base2_exponential_bucket_histogram": { + "$ref": "#/$defs/Base2ExponentialBucketHistogramAggregation", + "description": "Configures the stream to collect data for the exponential histogram metric point, which uses a base-2 exponential formula to determine bucket boundaries and an integer scale parameter to control resolution. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation for details.\nIf omitted, ignore.\n" + }, + "last_value": { + "$ref": "#/$defs/LastValueAggregation", + "description": "Configures the stream to collect data using the last measurement. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#last-value-aggregation for details.\nIf omitted, ignore.\n" + }, + "sum": { + "$ref": "#/$defs/SumAggregation", + "description": "Configures the stream to collect the arithmetic sum of measurement values. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#sum-aggregation for details.\nIf omitted, ignore.\n" + } + } + }, + "AlwaysOffSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "AlwaysOnSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "AttributeLimits": { + "type": "object", + "additionalProperties": false, + "properties": { + "attribute_value_length_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attribute value size. \nValue must be non-negative.\nIf omitted or null, there is no limit.\n" + }, + "attribute_count_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attribute count. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" + } + } + }, + "AttributeNameValue": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The attribute name.\nProperty is required and must be non-null.\n" + }, + "value": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + { + "type": "array", + "items": { + "type": "boolean" + }, + "minItems": 1 + }, + { + "type": "array", + "items": { + "type": "number" + }, + "minItems": 1 + } + ], + "description": "The attribute value.\nThe type of value must match .type.\nProperty must be present, but if null the entry is ignored.\n" + }, + "type": { + "$ref": "#/$defs/AttributeType", + "description": "The attribute type.\nValues include:\n* bool: Boolean attribute value.\n* bool_array: Boolean array attribute value.\n* double: Double attribute value.\n* double_array: Double array attribute value.\n* int: Integer attribute value.\n* int_array: Integer array attribute value.\n* string: String attribute value.\n* string_array: String array attribute value.\nIf omitted, string is used.\n" + } + }, + "required": [ + "name", + "value" + ] + }, + "AttributeType": { + "type": [ + "string", + "null" + ], + "enum": [ + "string", + "bool", + "int", + "double", + "string_array", + "bool_array", + "int_array", + "double_array" + ] + }, + "B3MultiPropagator": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "B3Propagator": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "BaggagePropagator": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "Base2ExponentialBucketHistogramAggregation": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "max_scale": { + "type": [ + "integer", + "null" + ], + "minimum": -10, + "maximum": 20, + "description": "Configure the max scale factor.\nIf omitted or null, 20 is used.\n" + }, + "max_size": { + "type": [ + "integer", + "null" + ], + "minimum": 2, + "description": "Configure the maximum number of buckets in each of the positive and negative ranges, not counting the special zero bucket.\nIf omitted or null, 160 is used.\n" + }, + "record_min_max": { + "type": [ + "boolean", + "null" + ], + "description": "Configure whether or not to record min and max.\nIf omitted or null, true is used.\n" + } + } + }, + "BatchLogRecordProcessor": { + "type": "object", + "additionalProperties": false, + "properties": { + "schedule_delay": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure delay interval (in milliseconds) between two consecutive exports. \nValue must be non-negative.\nIf omitted or null, 1000 is used.\n" + }, + "export_timeout": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure maximum allowed time (in milliseconds) to export data. \nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 30000 is used.\n" + }, + "max_queue_size": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure maximum queue size. Value must be positive.\nIf omitted or null, 2048 is used.\n" + }, + "max_export_batch_size": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure maximum batch size. Value must be positive.\nIf omitted or null, 512 is used.\n" + }, + "exporter": { + "$ref": "#/$defs/LogRecordExporter", + "description": "Configure exporter.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "exporter" + ] + }, + "BatchSpanProcessor": { + "type": "object", + "additionalProperties": false, + "properties": { + "schedule_delay": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure delay interval (in milliseconds) between two consecutive exports. \nValue must be non-negative.\nIf omitted or null, 5000 is used.\n" + }, + "export_timeout": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure maximum allowed time (in milliseconds) to export data. \nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 30000 is used.\n" + }, + "max_queue_size": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure maximum queue size. Value must be positive.\nIf omitted or null, 2048 is used.\n" + }, + "max_export_batch_size": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure maximum batch size. Value must be positive.\nIf omitted or null, 512 is used.\n" + }, + "exporter": { + "$ref": "#/$defs/SpanExporter", + "description": "Configure exporter.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "exporter" + ] + }, + "CardinalityLimits": { + "type": "object", + "additionalProperties": false, + "properties": { + "default": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for all instrument types.\nInstrument-specific cardinality limits take priority.\nIf omitted or null, 2000 is used.\n" + }, + "counter": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for counter instruments.\nIf omitted or null, the value from .default is used.\n" + }, + "gauge": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for gauge instruments.\nIf omitted or null, the value from .default is used.\n" + }, + "histogram": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for histogram instruments.\nIf omitted or null, the value from .default is used.\n" + }, + "observable_counter": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for observable_counter instruments.\nIf omitted or null, the value from .default is used.\n" + }, + "observable_gauge": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for observable_gauge instruments.\nIf omitted or null, the value from .default is used.\n" + }, + "observable_up_down_counter": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for observable_up_down_counter instruments.\nIf omitted or null, the value from .default is used.\n" + }, + "up_down_counter": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure default cardinality limit for up_down_counter instruments.\nIf omitted or null, the value from .default is used.\n" + } + } + }, + "ConsoleExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ConsoleMetricExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "temporality_preference": { + "$ref": "#/$defs/ExporterTemporalityPreference", + "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" + }, + "default_histogram_aggregation": { + "$ref": "#/$defs/ExporterDefaultHistogramAggregation", + "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" + } + } + }, + "DefaultAggregation": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "Distribution": { + "type": "object", + "additionalProperties": { + "type": "object" + }, + "minProperties": 1 + }, + "DropAggregation": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExemplarFilter": { + "type": [ + "string", + "null" + ], + "enum": [ + "always_on", + "always_off", + "trace_based" + ] + }, + "ExperimentalCodeInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "semconv": { + "$ref": "#/$defs/ExperimentalSemconvConfig", + "description": "Configure code semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee code semantic conventions: https://opentelemetry.io/docs/specs/semconv/registry/attributes/code/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" + } + } + }, + "ExperimentalComposableAlwaysOffSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExperimentalComposableAlwaysOnSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExperimentalComposableParentThresholdSampler": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "root": { + "$ref": "#/$defs/ExperimentalComposableSampler", + "description": "Sampler to use when there is no parent.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "root" + ] + }, + "ExperimentalComposableProbabilitySampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "ratio": { + "type": [ + "number", + "null" + ], + "minimum": 0, + "maximum": 1, + "description": "Configure ratio.\nIf omitted or null, 1.0 is used.\n" + } + } + }, + "ExperimentalComposableRuleBasedSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "rules": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/ExperimentalComposableRuleBasedSamplerRule" + }, + "description": "The rules for the sampler, matched in order.\nEach rule can have multiple match conditions. All conditions must match for the rule to match.\nIf no conditions are specified, the rule matches all spans that reach it.\nIf no rules match, the span is not sampled.\nIf omitted, no span is sampled.\n" + } + } + }, + "ExperimentalComposableRuleBasedSamplerRule": { + "type": "object", + "description": "A rule for ExperimentalComposableRuleBasedSampler. A rule can have multiple match conditions - the sampler will be applied if all match. \nIf no conditions are specified, the rule matches all spans that reach it.\n", + "additionalProperties": false, + "properties": { + "attribute_values": { + "$ref": "#/$defs/ExperimentalComposableRuleBasedSamplerRuleAttributeValues", + "description": "Values to match against a single attribute. Non-string attributes are matched using their string representation:\nfor example, a value of \"404\" would match the http.response.status_code 404. For array attributes, if any\nitem matches, it is considered a match.\nIf omitted, ignore.\n" + }, + "attribute_patterns": { + "$ref": "#/$defs/ExperimentalComposableRuleBasedSamplerRuleAttributePatterns", + "description": "Patterns to match against a single attribute. Non-string attributes are matched using their string representation:\nfor example, a pattern of \"4*\" would match any http.response.status_code in 400-499. For array attributes, if any\nitem matches, it is considered a match.\nIf omitted, ignore.\n" + }, + "span_kinds": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/SpanKind" + }, + "description": "The span kinds to match. If the span's kind matches any of these, it matches.\nValues include:\n* client: client, a client span.\n* consumer: consumer, a consumer span.\n* internal: internal, an internal span.\n* producer: producer, a producer span.\n* server: server, a server span.\nIf omitted, ignore.\n" + }, + "parent": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/ExperimentalSpanParent" + }, + "description": "The parent span types to match.\nValues include:\n* local: local, a local parent.\n* none: none, no parent, i.e., the trace root.\n* remote: remote, a remote parent.\nIf omitted, ignore.\n" + }, + "sampler": { + "$ref": "#/$defs/ExperimentalComposableSampler", + "description": "The sampler to use for matching spans.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "sampler" + ] + }, + "ExperimentalComposableRuleBasedSamplerRuleAttributePatterns": { + "type": "object", + "additionalProperties": false, + "properties": { + "key": { + "type": "string", + "description": "The attribute key to match against.\nProperty is required and must be non-null.\n" + }, + "included": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure list of value patterns to include.\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, all values are included.\n" + }, + "excluded": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure list of value patterns to exclude. Applies after .included (i.e. excluded has higher priority than included).\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, .included attributes are included.\n" + } + }, + "required": [ + "key" + ] + }, + "ExperimentalComposableRuleBasedSamplerRuleAttributeValues": { + "type": "object", + "additionalProperties": false, + "properties": { + "key": { + "type": "string", + "description": "The attribute key to match against.\nProperty is required and must be non-null.\n" + }, + "values": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "The attribute values to match against. If the attribute's value matches any of these, it matches.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "key", + "values" + ] + }, + "ExperimentalComposableSampler": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "always_off": { + "$ref": "#/$defs/ExperimentalComposableAlwaysOffSampler", + "description": "Configure sampler to be always_off.\nIf omitted, ignore.\n" + }, + "always_on": { + "$ref": "#/$defs/ExperimentalComposableAlwaysOnSampler", + "description": "Configure sampler to be always_on.\nIf omitted, ignore.\n" + }, + "parent_threshold": { + "$ref": "#/$defs/ExperimentalComposableParentThresholdSampler", + "description": "Configure sampler to be parent_threshold.\nIf omitted, ignore.\n" + }, + "probability": { + "$ref": "#/$defs/ExperimentalComposableProbabilitySampler", + "description": "Configure sampler to be probability.\nIf omitted, ignore.\n" + }, + "rule_based": { + "$ref": "#/$defs/ExperimentalComposableRuleBasedSampler", + "description": "Configure sampler to be rule_based.\nIf omitted, ignore.\n" + } + } + }, + "ExperimentalContainerResourceDetector": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExperimentalDbInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "semconv": { + "$ref": "#/$defs/ExperimentalSemconvConfig", + "description": "Configure database semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee database migration: https://opentelemetry.io/docs/specs/semconv/database/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" + } + } + }, + "ExperimentalEventToSpanEventBridgeLogRecordProcessor": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExperimentalGenAiInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "semconv": { + "$ref": "#/$defs/ExperimentalSemconvConfig", + "description": "Configure GenAI semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee GenAI semantic conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" + } + } + }, + "ExperimentalGeneralInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "http": { + "$ref": "#/$defs/ExperimentalHttpInstrumentation", + "description": "Configure instrumentations following the http semantic conventions.\nSee http semantic conventions: https://opentelemetry.io/docs/specs/semconv/http/\nIf omitted, defaults as described in ExperimentalHttpInstrumentation are used.\n" + }, + "code": { + "$ref": "#/$defs/ExperimentalCodeInstrumentation", + "description": "Configure instrumentations following the code semantic conventions.\nSee code semantic conventions: https://opentelemetry.io/docs/specs/semconv/registry/attributes/code/\nIf omitted, defaults as described in ExperimentalCodeInstrumentation are used.\n" + }, + "db": { + "$ref": "#/$defs/ExperimentalDbInstrumentation", + "description": "Configure instrumentations following the database semantic conventions.\nSee database semantic conventions: https://opentelemetry.io/docs/specs/semconv/database/\nIf omitted, defaults as described in ExperimentalDbInstrumentation are used.\n" + }, + "gen_ai": { + "$ref": "#/$defs/ExperimentalGenAiInstrumentation", + "description": "Configure instrumentations following the GenAI semantic conventions.\nSee GenAI semantic conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/\nIf omitted, defaults as described in ExperimentalGenAiInstrumentation are used.\n" + }, + "messaging": { + "$ref": "#/$defs/ExperimentalMessagingInstrumentation", + "description": "Configure instrumentations following the messaging semantic conventions.\nSee messaging semantic conventions: https://opentelemetry.io/docs/specs/semconv/messaging/\nIf omitted, defaults as described in ExperimentalMessagingInstrumentation are used.\n" + }, + "rpc": { + "$ref": "#/$defs/ExperimentalRpcInstrumentation", + "description": "Configure instrumentations following the RPC semantic conventions.\nSee RPC semantic conventions: https://opentelemetry.io/docs/specs/semconv/rpc/\nIf omitted, defaults as described in ExperimentalRpcInstrumentation are used.\n" + }, + "sanitization": { + "$ref": "#/$defs/ExperimentalSanitization", + "description": "Configure general sanitization options.\nIf omitted, defaults as described in ExperimentalSanitization are used.\n" + }, + "stability_opt_in_list": { + "type": [ + "string", + "null" + ], + "description": "Configure semantic convention stability opt-in as a comma-separated list.\nThis property follows the format and semantics of the OTEL_SEMCONV_STABILITY_OPT_IN environment variable.\nControls the emission of stable vs. experimental semantic conventions for instrumentation.\nThis setting is only intended for migrating from experimental to stable semantic conventions.\n\nKnown values include:\n- http: Emit stable HTTP and networking conventions only\n- http/dup: Emit both old and stable HTTP and networking conventions (for phased migration)\n- database: Emit stable database conventions only\n- database/dup: Emit both old and stable database conventions (for phased migration)\n- rpc: Emit stable RPC conventions only\n- rpc/dup: Emit both experimental and stable RPC conventions (for phased migration)\n- messaging: Emit stable messaging conventions only\n- messaging/dup: Emit both old and stable messaging conventions (for phased migration)\n- code: Emit stable code conventions only\n- code/dup: Emit both old and stable code conventions (for phased migration)\n\nMultiple values can be specified as a comma-separated list (e.g., \"http,database/dup\").\nAdditional signal types may be supported in future versions.\n\nDomain-specific semconv properties (e.g., .instrumentation/development.general.db.semconv) take precedence over this general setting.\n\nSee:\n- HTTP migration: https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/\n- Database migration: https://opentelemetry.io/docs/specs/semconv/database/\n- RPC: https://opentelemetry.io/docs/specs/semconv/rpc/\n- Messaging: https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/\nIf omitted or null, no opt-in is configured and instrumentations continue emitting their default semantic convention version.\n" + } + } + }, + "ExperimentalHostResourceDetector": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExperimentalHttpClientInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "request_captured_headers": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure headers to capture for outbound http requests.\nIf omitted, no outbound request headers are captured.\n" + }, + "response_captured_headers": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure headers to capture for inbound http responses.\nIf omitted, no inbound response headers are captured.\n" + }, + "known_methods": { + "type": "array", + "minItems": 0, + "items": { + "type": "string" + }, + "description": "Override the default list of known HTTP methods.\nKnown methods are case-sensitive.\nThis is a full override of the default known methods, not a list of known methods in addition to the defaults.\nIf omitted, HTTP methods GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH are known.\n" + } + } + }, + "ExperimentalHttpInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "semconv": { + "$ref": "#/$defs/ExperimentalSemconvConfig", + "description": "Configure HTTP semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee HTTP migration: https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" + }, + "client": { + "$ref": "#/$defs/ExperimentalHttpClientInstrumentation", + "description": "Configure instrumentations following the http client semantic conventions.\nIf omitted, defaults as described in ExperimentalHttpClientInstrumentation are used.\n" + }, + "server": { + "$ref": "#/$defs/ExperimentalHttpServerInstrumentation", + "description": "Configure instrumentations following the http server semantic conventions.\nIf omitted, defaults as described in ExperimentalHttpServerInstrumentation are used.\n" + } + } + }, + "ExperimentalHttpServerInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "request_captured_headers": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure headers to capture for inbound http requests.\nIf omitted, no request headers are captured.\n" + }, + "response_captured_headers": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure headers to capture for outbound http responses.\nIf omitted, no response headers are captures.\n" + }, + "known_methods": { + "type": "array", + "minItems": 0, + "items": { + "type": "string" + }, + "description": "Override the default list of known HTTP methods.\nKnown methods are case-sensitive.\nThis is a full override of the default known methods, not a list of known methods in addition to the defaults.\nIf omitted, HTTP methods GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH are known.\n" + } + } + }, + "ExperimentalInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "general": { + "$ref": "#/$defs/ExperimentalGeneralInstrumentation", + "description": "Configure general SemConv options that may apply to multiple languages and instrumentations.\nInstrumenation may merge general config options with the language specific configuration at .instrumentation..\nIf omitted, default values as described in ExperimentalGeneralInstrumentation are used.\n" + }, + "cpp": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure C++ language-specific instrumentation libraries.\nIf omitted, instrumentation defaults are used.\n" + }, + "dotnet": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure .NET language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "erlang": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure Erlang language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "go": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure Go language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "java": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure Java language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "js": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure JavaScript language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "php": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure PHP language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "python": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure Python language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "ruby": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure Ruby language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "rust": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure Rust language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + }, + "swift": { + "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", + "description": "Configure Swift language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" + } + } + }, + "ExperimentalJaegerRemoteSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "endpoint": { + "type": [ + "string" + ], + "description": "Configure the endpoint of the jaeger remote sampling service.\nProperty is required and must be non-null.\n" + }, + "interval": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure the polling interval (in milliseconds) to fetch from the remote sampling service.\nIf omitted or null, 60000 is used.\n" + }, + "initial_sampler": { + "$ref": "#/$defs/Sampler", + "description": "Configure the initial sampler used before first configuration is fetched.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "endpoint", + "initial_sampler" + ] + }, + "ExperimentalLanguageSpecificInstrumentation": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "ExperimentalLoggerConfig": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": [ + "boolean", + "null" + ], + "description": "Configure if the logger is enabled or not.\nIf omitted or null, true is used.\n" + }, + "minimum_severity": { + "$ref": "#/$defs/SeverityNumber", + "description": "Configure severity filtering.\nLog records with an non-zero (i.e. unspecified) severity number which is less than minimum_severity are not processed.\nValues include:\n* debug: debug, severity number 5.\n* debug2: debug2, severity number 6.\n* debug3: debug3, severity number 7.\n* debug4: debug4, severity number 8.\n* error: error, severity number 17.\n* error2: error2, severity number 18.\n* error3: error3, severity number 19.\n* error4: error4, severity number 20.\n* fatal: fatal, severity number 21.\n* fatal2: fatal2, severity number 22.\n* fatal3: fatal3, severity number 23.\n* fatal4: fatal4, severity number 24.\n* info: info, severity number 9.\n* info2: info2, severity number 10.\n* info3: info3, severity number 11.\n* info4: info4, severity number 12.\n* trace: trace, severity number 1.\n* trace2: trace2, severity number 2.\n* trace3: trace3, severity number 3.\n* trace4: trace4, severity number 4.\n* warn: warn, severity number 13.\n* warn2: warn2, severity number 14.\n* warn3: warn3, severity number 15.\n* warn4: warn4, severity number 16.\nIf omitted, severity filtering is not applied.\n" + }, + "trace_based": { + "type": [ + "boolean", + "null" + ], + "description": "Configure trace based filtering.\nIf true, log records associated with unsampled trace contexts traces are not processed. If false, or if a log record is not associated with a trace context, trace based filtering is not applied.\nIf omitted or null, trace based filtering is not applied.\n" + } + } + }, + "ExperimentalLoggerConfigurator": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "default_config": { + "$ref": "#/$defs/ExperimentalLoggerConfig", + "description": "Configure the default logger config used there is no matching entry in .logger_configurator/development.loggers.\nIf omitted, unmatched .loggers use default values as described in ExperimentalLoggerConfig.\n" + }, + "loggers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/ExperimentalLoggerMatcherAndConfig" + }, + "description": "Configure loggers.\nIf omitted, all loggers use .default_config.\n" + } + } + }, + "ExperimentalLoggerMatcherAndConfig": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": [ + "string" + ], + "description": "Configure logger names to match. Matching is case-sensitive, evaluated as follows:\n\n * If the logger name exactly matches.\n * If the logger name matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nProperty is required and must be non-null.\n" + }, + "config": { + "$ref": "#/$defs/ExperimentalLoggerConfig", + "description": "The logger config.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "name", + "config" + ] + }, + "ExperimentalMessagingInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "semconv": { + "$ref": "#/$defs/ExperimentalSemconvConfig", + "description": "Configure messaging semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee messaging semantic conventions: https://opentelemetry.io/docs/specs/semconv/messaging/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" + } + } + }, + "ExperimentalMeterConfig": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": [ + "boolean" + ], + "description": "Configure if the meter is enabled or not.\nIf omitted, true is used.\n" + } + } + }, + "ExperimentalMeterConfigurator": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "default_config": { + "$ref": "#/$defs/ExperimentalMeterConfig", + "description": "Configure the default meter config used there is no matching entry in .meter_configurator/development.meters.\nIf omitted, unmatched .meters use default values as described in ExperimentalMeterConfig.\n" + }, + "meters": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/ExperimentalMeterMatcherAndConfig" + }, + "description": "Configure meters.\nIf omitted, all meters used .default_config.\n" + } + } + }, + "ExperimentalMeterMatcherAndConfig": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": [ + "string" + ], + "description": "Configure meter names to match. Matching is case-sensitive, evaluated as follows:\n\n * If the meter name exactly matches.\n * If the meter name matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nProperty is required and must be non-null.\n" + }, + "config": { + "$ref": "#/$defs/ExperimentalMeterConfig", + "description": "The meter config.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "name", + "config" + ] + }, + "ExperimentalOtlpFileExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "output_stream": { + "type": [ + "string", + "null" + ], + "description": "Configure output stream. \nValues include stdout, or scheme+destination. For example: file:///path/to/file.jsonl.\nIf omitted or null, stdout is used.\n" + } + } + }, + "ExperimentalOtlpFileMetricExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "output_stream": { + "type": [ + "string", + "null" + ], + "description": "Configure output stream. \nValues include stdout, or scheme+destination. For example: file:///path/to/file.jsonl.\nIf omitted or null, stdout is used.\n" + }, + "temporality_preference": { + "$ref": "#/$defs/ExporterTemporalityPreference", + "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" + }, + "default_histogram_aggregation": { + "$ref": "#/$defs/ExporterDefaultHistogramAggregation", + "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" + } + } + }, + "ExperimentalProbabilitySampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "ratio": { + "type": [ + "number", + "null" + ], + "minimum": 0, + "maximum": 1, + "description": "Configure ratio.\nIf omitted or null, 1.0 is used.\n" + } + } + }, + "ExperimentalProcessResourceDetector": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExperimentalPrometheusMetricExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "host": { + "type": [ + "string", + "null" + ], + "description": "Configure host.\nIf omitted or null, localhost is used.\n" + }, + "port": { + "type": [ + "integer", + "null" + ], + "description": "Configure port.\nIf omitted or null, 9464 is used.\n" + }, + "scope_info_enabled": { + "type": [ + "boolean", + "null" + ], + "description": "Configure Prometheus Exporter to produce metrics with scope labels.\nIf omitted or null, true is used.\n" + }, + "target_info_enabled/development": { + "type": [ + "boolean", + "null" + ], + "description": "Configure Prometheus Exporter to produce metrics with a target info metric for the resource.\nIf omitted or null, true is used.\n" + }, + "resource_constant_labels": { + "$ref": "#/$defs/IncludeExclude", + "description": "Configure Prometheus Exporter to add resource attributes as metrics attributes, where the resource attribute keys match the patterns.\nIf omitted, no resource attributes are added.\n" + }, + "translation_strategy": { + "$ref": "#/$defs/ExperimentalPrometheusTranslationStrategy", + "description": "Configure how metric names are translated to Prometheus metric names.\nValues include:\n* no_translation/development: Special character escaping is disabled. Type and unit suffixes are disabled. Metric names are unaltered.\n* no_utf8_escaping_with_suffixes/development: Special character escaping is disabled. Type and unit suffixes are enabled.\n* underscore_escaping_with_suffixes: Special character escaping is enabled. Type and unit suffixes are enabled.\n* underscore_escaping_without_suffixes/development: Special character escaping is enabled. Type and unit suffixes are disabled. This represents classic Prometheus metric name compatibility.\nIf omitted, underscore_escaping_with_suffixes is used.\n" + } + } + }, + "ExperimentalPrometheusTranslationStrategy": { + "type": [ + "string", + "null" + ], + "enum": [ + "underscore_escaping_with_suffixes", + "underscore_escaping_without_suffixes/development", + "no_utf8_escaping_with_suffixes/development", + "no_translation/development" + ] + }, + "ExperimentalResourceDetection": { + "type": "object", + "additionalProperties": false, + "properties": { + "attributes": { + "$ref": "#/$defs/IncludeExclude", + "description": "Configure attributes provided by resource detectors.\nIf omitted, all attributes from resource detectors are added.\n" + }, + "detectors": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/ExperimentalResourceDetector" + }, + "description": "Configure resource detectors.\nResource detector names are dependent on the SDK language ecosystem. Please consult documentation for each respective language. \nIf omitted, no resource detectors are enabled.\n" + } + } + }, + "ExperimentalResourceDetector": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "container": { + "$ref": "#/$defs/ExperimentalContainerResourceDetector", + "description": "Enable the container resource detector, which populates container.* attributes.\nIf omitted, ignore.\n" + }, + "host": { + "$ref": "#/$defs/ExperimentalHostResourceDetector", + "description": "Enable the host resource detector, which populates host.* and os.* attributes.\nIf omitted, ignore.\n" + }, + "process": { + "$ref": "#/$defs/ExperimentalProcessResourceDetector", + "description": "Enable the process resource detector, which populates process.* attributes.\nIf omitted, ignore.\n" + }, + "service": { + "$ref": "#/$defs/ExperimentalServiceResourceDetector", + "description": "Enable the service detector, which populates service.name based on the OTEL_SERVICE_NAME environment variable and service.instance.id.\nIf omitted, ignore.\n" + } + } + }, + "ExperimentalRpcInstrumentation": { + "type": "object", + "additionalProperties": false, + "properties": { + "semconv": { + "$ref": "#/$defs/ExperimentalSemconvConfig", + "description": "Configure RPC semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee RPC semantic conventions: https://opentelemetry.io/docs/specs/semconv/rpc/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" + } + } + }, + "ExperimentalSanitization": { + "type": "object", + "additionalProperties": false, + "properties": { + "url": { + "$ref": "#/$defs/ExperimentalUrlSanitization", + "description": "Configure URL sanitization options.\nIf omitted, defaults as described in ExperimentalUrlSanitization are used.\n" + } + } + }, + "ExperimentalSemconvConfig": { + "type": "object", + "additionalProperties": false, + "properties": { + "version": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "The target semantic convention version for this domain (e.g., 1).\nIf omitted or null, the latest stable version is used, or if no stable version is available and .experimental is true then the latest experimental version is used.\n" + }, + "experimental": { + "type": [ + "boolean", + "null" + ], + "description": "Use latest experimental semantic conventions (before stable is available or to enable experimental features on top of stable conventions).\nIf omitted or null, false is used.\n" + }, + "dual_emit": { + "type": [ + "boolean", + "null" + ], + "description": "When true, also emit the previous major version alongside the target version.\nFor version=1, the previous version refers to the pre-stable conventions that the instrumentation emitted before the first stable semantic convention version was defined.\nFor version=2 and above, the previous version is the prior stable major version (e.g., version=2, dual_emit=true emits both v2 and v1).\nEnables dual-emit for phased migration between versions.\nIf omitted or null, false is used.\n" + } + } + }, + "ExperimentalServiceResourceDetector": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "ExperimentalSpanParent": { + "type": [ + "string", + "null" + ], + "enum": [ + "none", + "remote", + "local" + ] + }, + "ExperimentalTracerConfig": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "enabled": { + "type": [ + "boolean" + ], + "description": "Configure if the tracer is enabled or not.\nIf omitted, true is used.\n" + } + } + }, + "ExperimentalTracerConfigurator": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "default_config": { + "$ref": "#/$defs/ExperimentalTracerConfig", + "description": "Configure the default tracer config used there is no matching entry in .tracer_configurator/development.tracers.\nIf omitted, unmatched .tracers use default values as described in ExperimentalTracerConfig.\n" + }, + "tracers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/ExperimentalTracerMatcherAndConfig" + }, + "description": "Configure tracers.\nIf omitted, all tracers use .default_config.\n" + } + } + }, + "ExperimentalTracerMatcherAndConfig": { + "type": [ + "object" + ], + "additionalProperties": false, + "properties": { + "name": { + "type": [ + "string" + ], + "description": "Configure tracer names to match. Matching is case-sensitive, evaluated as follows:\n\n * If the tracer name exactly matches.\n * If the tracer name matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nProperty is required and must be non-null.\n" + }, + "config": { + "$ref": "#/$defs/ExperimentalTracerConfig", + "description": "The tracer config.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "name", + "config" + ] + }, + "ExperimentalUrlSanitization": { + "type": "object", + "additionalProperties": false, + "properties": { + "sensitive_query_parameters": { + "type": "array", + "minItems": 0, + "items": { + "type": "string" + }, + "description": "List of query parameter names whose values should be redacted from URLs.\nQuery parameter names are case-sensitive.\nThis is a full override of the default sensitive query parameter keys, it is not a list of keys in addition to the defaults.\nSet to an empty array to disable query parameter redaction.\nIf omitted, the default sensitive query parameter list as defined by the url semantic conventions (https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/url.md) is used.\n" + } + } + }, + "ExplicitBucketHistogramAggregation": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "boundaries": { + "type": "array", + "minItems": 0, + "items": { + "type": "number" + }, + "description": "Configure bucket boundaries.\nIf omitted, [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000] is used.\n" + }, + "record_min_max": { + "type": [ + "boolean", + "null" + ], + "description": "Configure record min and max.\nIf omitted or null, true is used.\n" + } + } + }, + "ExporterDefaultHistogramAggregation": { + "type": [ + "string", + "null" + ], + "enum": [ + "explicit_bucket_histogram", + "base2_exponential_bucket_histogram" + ] + }, + "ExporterTemporalityPreference": { + "type": [ + "string", + "null" + ], + "enum": [ + "cumulative", + "delta", + "low_memory" + ] + }, + "GrpcTls": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "ca_file": { + "type": [ + "string", + "null" + ], + "description": "Configure certificate used to verify a server's TLS credentials. \nAbsolute path to certificate file in PEM format.\nIf omitted or null, system default certificate verification is used for secure connections.\n" + }, + "key_file": { + "type": [ + "string", + "null" + ], + "description": "Configure mTLS private client key. \nAbsolute path to client key file in PEM format. If set, .client_certificate must also be set.\nIf omitted or null, mTLS is not used.\n" + }, + "cert_file": { + "type": [ + "string", + "null" + ], + "description": "Configure mTLS client certificate. \nAbsolute path to client certificate file in PEM format. If set, .client_key must also be set.\nIf omitted or null, mTLS is not used.\n" + }, + "insecure": { + "type": [ + "boolean", + "null" + ], + "description": "Configure client transport security for the exporter's connection. \nOnly applicable when .endpoint is provided without http or https scheme. Implementations may choose to ignore .insecure.\nIf omitted or null, false is used.\n" + } + } + }, + "HttpTls": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "ca_file": { + "type": [ + "string", + "null" + ], + "description": "Configure certificate used to verify a server's TLS credentials. \nAbsolute path to certificate file in PEM format.\nIf omitted or null, system default certificate verification is used for secure connections.\n" + }, + "key_file": { + "type": [ + "string", + "null" + ], + "description": "Configure mTLS private client key. \nAbsolute path to client key file in PEM format. If set, .client_certificate must also be set.\nIf omitted or null, mTLS is not used.\n" + }, + "cert_file": { + "type": [ + "string", + "null" + ], + "description": "Configure mTLS client certificate. \nAbsolute path to client certificate file in PEM format. If set, .client_key must also be set.\nIf omitted or null, mTLS is not used.\n" + } + } + }, + "IdGenerator": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "random": { + "$ref": "#/$defs/RandomIdGenerator", + "description": "Configure the ID generator to randomly generate TraceIds and SpanIds (spec default).\nIf omitted, ignore.\n" + } + } + }, + "IncludeExclude": { + "type": "object", + "additionalProperties": false, + "properties": { + "included": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure list of value patterns to include.\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, all values are included.\n" + }, + "excluded": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + }, + "description": "Configure list of value patterns to exclude. Applies after .included (i.e. excluded has higher priority than included).\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, .included attributes are included.\n" + } + } + }, + "InstrumentType": { + "type": [ + "string", + "null" + ], + "enum": [ + "counter", + "gauge", + "histogram", + "observable_counter", + "observable_gauge", + "observable_up_down_counter", + "up_down_counter" + ] + }, + "LastValueAggregation": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "LoggerProvider": { + "type": "object", + "additionalProperties": false, + "properties": { + "processors": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/LogRecordProcessor" + }, + "description": "Configure log record processors.\nProperty is required and must be non-null.\n" + }, + "limits": { + "$ref": "#/$defs/LogRecordLimits", + "description": "Configure log record limits. See also attribute_limits.\nIf omitted, default values as described in LogRecordLimits are used.\n" + }, + "logger_configurator/development": { + "$ref": "#/$defs/ExperimentalLoggerConfigurator", + "description": "Configure loggers.\nIf omitted, all loggers use default values as described in ExperimentalLoggerConfig.\n" + } + }, + "required": [ + "processors" + ] + }, + "LogRecordExporter": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "otlp_http": { + "$ref": "#/$defs/OtlpHttpExporter", + "description": "Configure exporter to be OTLP with HTTP transport.\nIf omitted, ignore.\n" + }, + "otlp_grpc": { + "$ref": "#/$defs/OtlpGrpcExporter", + "description": "Configure exporter to be OTLP with gRPC transport.\nIf omitted, ignore.\n" + }, + "otlp_file/development": { + "$ref": "#/$defs/ExperimentalOtlpFileExporter", + "description": "Configure exporter to be OTLP with file transport.\nIf omitted, ignore.\n" + }, + "console": { + "$ref": "#/$defs/ConsoleExporter", + "description": "Configure exporter to be console.\nIf omitted, ignore.\n" + } + } + }, + "LogRecordLimits": { + "type": "object", + "additionalProperties": false, + "properties": { + "attribute_value_length_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attribute value size. Overrides .attribute_limits.attribute_value_length_limit. \nValue must be non-negative.\nIf omitted or null, there is no limit.\n" + }, + "attribute_count_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attribute count. Overrides .attribute_limits.attribute_count_limit. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" + } + } + }, + "LogRecordProcessor": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "batch": { + "$ref": "#/$defs/BatchLogRecordProcessor", + "description": "Configure a batch log record processor.\nIf omitted, ignore.\n" + }, + "simple": { + "$ref": "#/$defs/SimpleLogRecordProcessor", + "description": "Configure a simple log record processor.\nIf omitted, ignore.\n" + }, + "event_to_span_event_bridge/development": { + "$ref": "#/$defs/ExperimentalEventToSpanEventBridgeLogRecordProcessor", + "description": "Configure an event to span event bridge log record processor.\nIf omitted, ignore.\n" + } + } + }, + "MeterProvider": { + "type": "object", + "additionalProperties": false, + "properties": { + "readers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/MetricReader" + }, + "description": "Configure metric readers.\nProperty is required and must be non-null.\n" + }, + "views": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/View" + }, + "description": "Configure views. \nEach view has a selector which determines the instrument(s) it applies to, and a configuration for the resulting stream(s).\nIf omitted, no views are registered.\n" + }, + "exemplar_filter": { + "$ref": "#/$defs/ExemplarFilter", + "description": "Configure the exemplar filter.\nValues include:\n* always_off: ExemplarFilter which makes no measurements eligible for being an Exemplar.\n* always_on: ExemplarFilter which makes all measurements eligible for being an Exemplar.\n* trace_based: ExemplarFilter which makes measurements recorded in the context of a sampled parent span eligible for being an Exemplar.\nIf omitted, trace_based is used.\n" + }, + "meter_configurator/development": { + "$ref": "#/$defs/ExperimentalMeterConfigurator", + "description": "Configure meters.\nIf omitted, all meters use default values as described in ExperimentalMeterConfig.\n" + } + }, + "required": [ + "readers" + ] + }, + "MetricProducer": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "opencensus": { + "$ref": "#/$defs/OpenCensusMetricProducer", + "description": "Configure metric producer to be opencensus.\nIf omitted, ignore.\n" + } + } + }, + "MetricReader": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "periodic": { + "$ref": "#/$defs/PeriodicMetricReader", + "description": "Configure a periodic metric reader.\nIf omitted, ignore.\n" + }, + "pull": { + "$ref": "#/$defs/PullMetricReader", + "description": "Configure a pull based metric reader.\nIf omitted, ignore.\n" + } + } + }, + "NameStringValuePair": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the pair.\nProperty is required and must be non-null.\n" + }, + "value": { + "type": [ + "string", + "null" + ], + "description": "The value of the pair.\nProperty must be present, but if null the behavior is dependent on usage context.\n" + } + }, + "required": [ + "name", + "value" + ] + }, + "OpenCensusMetricProducer": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "OtlpGrpcExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "endpoint": { + "type": [ + "string", + "null" + ], + "description": "Configure endpoint.\nIf omitted or null, http://localhost:4317 is used.\n" + }, + "tls": { + "$ref": "#/$defs/GrpcTls", + "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" + }, + "headers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/NameStringValuePair" + }, + "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" + }, + "headers_list": { + "type": [ + "string", + "null" + ], + "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" + }, + "compression": { + "type": [ + "string", + "null" + ], + "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" + }, + "timeout": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" + } + } + }, + "OtlpGrpcMetricExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "endpoint": { + "type": [ + "string", + "null" + ], + "description": "Configure endpoint.\nIf omitted or null, http://localhost:4317 is used.\n" + }, + "tls": { + "$ref": "#/$defs/GrpcTls", + "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" + }, + "headers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/NameStringValuePair" + }, + "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" + }, + "headers_list": { + "type": [ + "string", + "null" + ], + "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" + }, + "compression": { + "type": [ + "string", + "null" + ], + "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" + }, + "timeout": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" + }, + "temporality_preference": { + "$ref": "#/$defs/ExporterTemporalityPreference", + "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" + }, + "default_histogram_aggregation": { + "$ref": "#/$defs/ExporterDefaultHistogramAggregation", + "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" + } + } + }, + "OtlpHttpEncoding": { + "type": [ + "string", + "null" + ], + "enum": [ + "protobuf", + "json" + ] + }, + "OtlpHttpExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "endpoint": { + "type": [ + "string", + "null" + ], + "description": "Configure endpoint, including the signal specific path.\nIf omitted or null, the http://localhost:4318/v1/{signal} (where signal is 'traces', 'logs', or 'metrics') is used.\n" + }, + "tls": { + "$ref": "#/$defs/HttpTls", + "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" + }, + "headers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/NameStringValuePair" + }, + "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" + }, + "headers_list": { + "type": [ + "string", + "null" + ], + "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" + }, + "compression": { + "type": [ + "string", + "null" + ], + "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" + }, + "timeout": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" + }, + "encoding": { + "$ref": "#/$defs/OtlpHttpEncoding", + "description": "Configure the encoding used for messages. \nImplementations may not support json.\nValues include:\n* json: Protobuf JSON encoding.\n* protobuf: Protobuf binary encoding.\nIf omitted, protobuf is used.\n" + } + } + }, + "OtlpHttpMetricExporter": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "endpoint": { + "type": [ + "string", + "null" + ], + "description": "Configure endpoint.\nIf omitted or null, http://localhost:4318/v1/metrics is used.\n" + }, + "tls": { + "$ref": "#/$defs/HttpTls", + "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" + }, + "headers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/NameStringValuePair" + }, + "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" + }, + "headers_list": { + "type": [ + "string", + "null" + ], + "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" + }, + "compression": { + "type": [ + "string", + "null" + ], + "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" + }, + "timeout": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" + }, + "encoding": { + "$ref": "#/$defs/OtlpHttpEncoding", + "description": "Configure the encoding used for messages. \nImplementations may not support json.\nValues include:\n* json: Protobuf JSON encoding.\n* protobuf: Protobuf binary encoding.\nIf omitted, protobuf is used.\n" + }, + "temporality_preference": { + "$ref": "#/$defs/ExporterTemporalityPreference", + "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" + }, + "default_histogram_aggregation": { + "$ref": "#/$defs/ExporterDefaultHistogramAggregation", + "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" + } + } + }, + "ParentBasedSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "root": { + "$ref": "#/$defs/Sampler", + "description": "Configure root sampler.\nIf omitted, always_on is used.\n" + }, + "remote_parent_sampled": { + "$ref": "#/$defs/Sampler", + "description": "Configure remote_parent_sampled sampler.\nIf omitted, always_on is used.\n" + }, + "remote_parent_not_sampled": { + "$ref": "#/$defs/Sampler", + "description": "Configure remote_parent_not_sampled sampler.\nIf omitted, always_off is used.\n" + }, + "local_parent_sampled": { + "$ref": "#/$defs/Sampler", + "description": "Configure local_parent_sampled sampler.\nIf omitted, always_on is used.\n" + }, + "local_parent_not_sampled": { + "$ref": "#/$defs/Sampler", + "description": "Configure local_parent_not_sampled sampler.\nIf omitted, always_off is used.\n" + } + } + }, + "PeriodicMetricReader": { + "type": "object", + "additionalProperties": false, + "properties": { + "interval": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure delay interval (in milliseconds) between start of two consecutive exports. \nValue must be non-negative.\nIf omitted or null, 60000 is used.\n" + }, + "timeout": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure maximum allowed time (in milliseconds) to export data. \nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 30000 is used.\n" + }, + "max_export_batch_size/development": { + "type": [ + "integer", + "null" + ], + "minimum": 1, + "description": "Configure maximum export batch size.\nIf omitted or null, no limit is used.\n" + }, + "exporter": { + "$ref": "#/$defs/PushMetricExporter", + "description": "Configure exporter.\nProperty is required and must be non-null.\n" + }, + "producers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/MetricProducer" + }, + "description": "Configure metric producers.\nIf omitted, no metric producers are added.\n" + }, + "cardinality_limits": { + "$ref": "#/$defs/CardinalityLimits", + "description": "Configure cardinality limits.\nIf omitted, default values as described in CardinalityLimits are used.\n" + } + }, + "required": [ + "exporter" + ] + }, + "Propagator": { + "type": "object", + "additionalProperties": false, + "properties": { + "composite": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/TextMapPropagator" + }, + "description": "Configure the propagators in the composite text map propagator. Entries from .composite_list are appended to the list here with duplicates filtered out.\nBuilt-in propagator keys include: tracecontext, baggage, b3, b3multi. Known third party keys include: xray.\nIf omitted, and .composite_list is omitted or null, a noop propagator is used.\n" + }, + "composite_list": { + "type": [ + "string", + "null" + ], + "description": "Configure the propagators in the composite text map propagator. Entries are appended to .composite with duplicates filtered out.\nThe value is a comma separated list of propagator identifiers matching the format of OTEL_PROPAGATORS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details.\nBuilt-in propagator identifiers include: tracecontext, baggage, b3, b3multi. Known third party identifiers include: xray.\nIf omitted or null, and .composite is omitted or null, a noop propagator is used.\n" + } + } + }, + "PullMetricExporter": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "prometheus/development": { + "$ref": "#/$defs/ExperimentalPrometheusMetricExporter", + "description": "Configure exporter to be prometheus.\nIf omitted, ignore.\n" + } + } + }, + "PullMetricReader": { + "type": "object", + "additionalProperties": false, + "properties": { + "exporter": { + "$ref": "#/$defs/PullMetricExporter", + "description": "Configure exporter.\nProperty is required and must be non-null.\n" + }, + "producers": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/MetricProducer" + }, + "description": "Configure metric producers.\nIf omitted, no metric producers are added.\n" + }, + "cardinality_limits": { + "$ref": "#/$defs/CardinalityLimits", + "description": "Configure cardinality limits.\nIf omitted, default values as described in CardinalityLimits are used.\n" + } + }, + "required": [ + "exporter" + ] + }, + "PushMetricExporter": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "otlp_http": { + "$ref": "#/$defs/OtlpHttpMetricExporter", + "description": "Configure exporter to be OTLP with HTTP transport.\nIf omitted, ignore.\n" + }, + "otlp_grpc": { + "$ref": "#/$defs/OtlpGrpcMetricExporter", + "description": "Configure exporter to be OTLP with gRPC transport.\nIf omitted, ignore.\n" + }, + "otlp_file/development": { + "$ref": "#/$defs/ExperimentalOtlpFileMetricExporter", + "description": "Configure exporter to be OTLP with file transport.\nIf omitted, ignore.\n" + }, + "console": { + "$ref": "#/$defs/ConsoleMetricExporter", + "description": "Configure exporter to be console.\nIf omitted, ignore.\n" + } + } + }, + "RandomIdGenerator": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "Resource": { + "type": "object", + "additionalProperties": false, + "properties": { + "attributes": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/AttributeNameValue" + }, + "description": "Configure resource attributes. Entries have higher priority than entries from .resource.attributes_list.\nIf omitted, no resource attributes are added.\n" + }, + "detection/development": { + "$ref": "#/$defs/ExperimentalResourceDetection", + "description": "Configure resource detection.\nIf omitted, resource detection is disabled.\n" + }, + "schema_url": { + "type": [ + "string", + "null" + ], + "description": "Configure resource schema URL.\nIf omitted or null, no schema URL is used.\n" + }, + "attributes_list": { + "type": [ + "string", + "null" + ], + "description": "Configure resource attributes. Entries have lower priority than entries from .resource.attributes.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_RESOURCE_ATTRIBUTES. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details.\nIf omitted or null, no resource attributes are added.\n" + } + } + }, + "Sampler": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "always_off": { + "$ref": "#/$defs/AlwaysOffSampler", + "description": "Configure sampler to be always_off.\nIf omitted, ignore.\n" + }, + "always_on": { + "$ref": "#/$defs/AlwaysOnSampler", + "description": "Configure sampler to be always_on.\nIf omitted, ignore.\n" + }, + "composite/development": { + "$ref": "#/$defs/ExperimentalComposableSampler", + "description": "Configure sampler to be composite.\nIf omitted, ignore.\n" + }, + "jaeger_remote/development": { + "$ref": "#/$defs/ExperimentalJaegerRemoteSampler", + "description": "Configure sampler to be jaeger_remote.\nIf omitted, ignore.\n" + }, + "parent_based": { + "$ref": "#/$defs/ParentBasedSampler", + "description": "Configure sampler to be parent_based.\nIf omitted, ignore.\n" + }, + "probability/development": { + "$ref": "#/$defs/ExperimentalProbabilitySampler", + "description": "Configure sampler to be probability.\nIf omitted, ignore.\n" + }, + "trace_id_ratio_based": { + "$ref": "#/$defs/TraceIdRatioBasedSampler", + "description": "Configure sampler to be trace_id_ratio_based.\nIf omitted, ignore.\n" + } + } + }, + "SeverityNumber": { + "type": [ + "string", + "null" + ], + "enum": [ + "trace", + "trace2", + "trace3", + "trace4", + "debug", + "debug2", + "debug3", + "debug4", + "info", + "info2", + "info3", + "info4", + "warn", + "warn2", + "warn3", + "warn4", + "error", + "error2", + "error3", + "error4", + "fatal", + "fatal2", + "fatal3", + "fatal4" + ] + }, + "SimpleLogRecordProcessor": { + "type": "object", + "additionalProperties": false, + "properties": { + "exporter": { + "$ref": "#/$defs/LogRecordExporter", + "description": "Configure exporter.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "exporter" + ] + }, + "SimpleSpanProcessor": { + "type": "object", + "additionalProperties": false, + "properties": { + "exporter": { + "$ref": "#/$defs/SpanExporter", + "description": "Configure exporter.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "exporter" + ] + }, + "SpanExporter": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "otlp_http": { + "$ref": "#/$defs/OtlpHttpExporter", + "description": "Configure exporter to be OTLP with HTTP transport.\nIf omitted, ignore.\n" + }, + "otlp_grpc": { + "$ref": "#/$defs/OtlpGrpcExporter", + "description": "Configure exporter to be OTLP with gRPC transport.\nIf omitted, ignore.\n" + }, + "otlp_file/development": { + "$ref": "#/$defs/ExperimentalOtlpFileExporter", + "description": "Configure exporter to be OTLP with file transport.\nIf omitted, ignore.\n" + }, + "console": { + "$ref": "#/$defs/ConsoleExporter", + "description": "Configure exporter to be console.\nIf omitted, ignore.\n" + } + } + }, + "SpanKind": { + "type": [ + "string", + "null" + ], + "enum": [ + "internal", + "server", + "client", + "producer", + "consumer" + ] + }, + "SpanLimits": { + "type": "object", + "additionalProperties": false, + "properties": { + "attribute_value_length_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attribute value size. Overrides .attribute_limits.attribute_value_length_limit. \nValue must be non-negative.\nIf omitted or null, there is no limit.\n" + }, + "attribute_count_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attribute count. Overrides .attribute_limits.attribute_count_limit. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" + }, + "event_count_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max span event count. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" + }, + "link_count_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max span link count. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" + }, + "event_attribute_count_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attributes per span event. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" + }, + "link_attribute_count_limit": { + "type": [ + "integer", + "null" + ], + "minimum": 0, + "description": "Configure max attributes per span link. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" + } + } + }, + "SpanProcessor": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "batch": { + "$ref": "#/$defs/BatchSpanProcessor", + "description": "Configure a batch span processor.\nIf omitted, ignore.\n" + }, + "simple": { + "$ref": "#/$defs/SimpleSpanProcessor", + "description": "Configure a simple span processor.\nIf omitted, ignore.\n" + } + } + }, + "SumAggregation": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "TextMapPropagator": { + "type": "object", + "additionalProperties": { + "type": [ + "object", + "null" + ] + }, + "minProperties": 1, + "maxProperties": 1, + "properties": { + "tracecontext": { + "$ref": "#/$defs/TraceContextPropagator", + "description": "Include the w3c trace context propagator.\nIf omitted, ignore.\n" + }, + "baggage": { + "$ref": "#/$defs/BaggagePropagator", + "description": "Include the w3c baggage propagator.\nIf omitted, ignore.\n" + }, + "b3": { + "$ref": "#/$defs/B3Propagator", + "description": "Include the zipkin b3 propagator.\nIf omitted, ignore.\n" + }, + "b3multi": { + "$ref": "#/$defs/B3MultiPropagator", + "description": "Include the zipkin b3 multi propagator.\nIf omitted, ignore.\n" + } + } + }, + "TraceContextPropagator": { + "type": [ + "object", + "null" + ], + "additionalProperties": false + }, + "TraceIdRatioBasedSampler": { + "type": [ + "object", + "null" + ], + "additionalProperties": false, + "properties": { + "ratio": { + "type": [ + "number", + "null" + ], + "minimum": 0, + "maximum": 1, + "description": "Configure trace_id_ratio.\nIf omitted or null, 1.0 is used.\n" + } + } + }, + "TracerProvider": { + "type": "object", + "additionalProperties": false, + "properties": { + "processors": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/SpanProcessor" + }, + "description": "Configure span processors.\nProperty is required and must be non-null.\n" + }, + "limits": { + "$ref": "#/$defs/SpanLimits", + "description": "Configure span limits. See also attribute_limits.\nIf omitted, default values as described in SpanLimits are used.\n" + }, + "sampler": { + "$ref": "#/$defs/Sampler", + "description": "Configure the sampler.\nIf omitted, parent based sampler with a root of always_on is used.\n" + }, + "id_generator": { + "$ref": "#/$defs/IdGenerator", + "description": "Configure the trace and span ID generator.\nIf omitted, RandomIdGenerator is used.\n" + }, + "tracer_configurator/development": { + "$ref": "#/$defs/ExperimentalTracerConfigurator", + "description": "Configure tracers.\nIf omitted, all tracers use default values as described in ExperimentalTracerConfig.\n" + } + }, + "required": [ + "processors" + ] + }, + "View": { + "type": "object", + "additionalProperties": false, + "properties": { + "selector": { + "$ref": "#/$defs/ViewSelector", + "description": "Configure view selector. \nSelection criteria is additive as described in https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#instrument-selection-criteria.\nProperty is required and must be non-null.\n" + }, + "stream": { + "$ref": "#/$defs/ViewStream", + "description": "Configure view stream.\nProperty is required and must be non-null.\n" + } + }, + "required": [ + "selector", + "stream" + ] + }, + "ViewSelector": { + "type": "object", + "additionalProperties": false, + "properties": { + "instrument_name": { + "type": [ + "string", + "null" + ], + "description": "Configure instrument name selection criteria.\nIf omitted or null, all instrument names match.\n" + }, + "instrument_type": { + "$ref": "#/$defs/InstrumentType", + "description": "Configure instrument type selection criteria.\nValues include:\n* counter: Synchronous counter instruments.\n* gauge: Synchronous gauge instruments.\n* histogram: Synchronous histogram instruments.\n* observable_counter: Asynchronous counter instruments.\n* observable_gauge: Asynchronous gauge instruments.\n* observable_up_down_counter: Asynchronous up down counter instruments.\n* up_down_counter: Synchronous up down counter instruments.\nIf omitted, all instrument types match.\n" + }, + "unit": { + "type": [ + "string", + "null" + ], + "description": "Configure the instrument unit selection criteria.\nIf omitted or null, all instrument units match.\n" + }, + "meter_name": { + "type": [ + "string", + "null" + ], + "description": "Configure meter name selection criteria.\nIf omitted or null, all meter names match.\n" + }, + "meter_version": { + "type": [ + "string", + "null" + ], + "description": "Configure meter version selection criteria.\nIf omitted or null, all meter versions match.\n" + }, + "meter_schema_url": { + "type": [ + "string", + "null" + ], + "description": "Configure meter schema url selection criteria.\nIf omitted or null, all meter schema URLs match.\n" + } + } + }, + "ViewStream": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": [ + "string", + "null" + ], + "description": "Configure metric name of the resulting stream(s).\nIf omitted or null, the instrument's original name is used.\n" + }, + "description": { + "type": [ + "string", + "null" + ], + "description": "Configure metric description of the resulting stream(s).\nIf omitted or null, the instrument's origin description is used.\n" + }, + "aggregation": { + "$ref": "#/$defs/Aggregation", + "description": "Configure aggregation of the resulting stream(s).\nIf omitted, default is used.\n" + }, + "aggregation_cardinality_limit": { + "type": [ + "integer", + "null" + ], + "exclusiveMinimum": 0, + "description": "Configure the aggregation cardinality limit.\nIf omitted or null, the metric reader's default cardinality limit is used.\n" + }, + "attribute_keys": { + "$ref": "#/$defs/IncludeExclude", + "description": "Configure attribute keys retained in the resulting stream(s).\nIf omitted, all attribute keys are retained.\n" + } + } + } + } +} \ No newline at end of file diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py new file mode 100644 index 00000000000..7e96f7105d1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py @@ -0,0 +1,147 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +import os +from contextvars import Token +from uuid import uuid4 + +# pylint: disable=wrong-import-position +from opentelemetry.agent._vendor.opentelemetry.context.context import Context, _RuntimeContext +from opentelemetry.agent._vendor.opentelemetry.context.contextvars_context import ContextVarsRuntimeContext +from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_CONTEXT + +logger = logging.getLogger(__name__) + + +def _load_runtime_context() -> _RuntimeContext: + """Initialize the RuntimeContext + + Returns: + An instance of RuntimeContext. + """ + configured_context = os.environ.get(OTEL_PYTHON_CONTEXT) + if not configured_context: + return ContextVarsRuntimeContext() + + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 + entry_points, + ) + + try: + return next(iter(entry_points(group="opentelemetry_context", name=configured_context))).load()() + except Exception: # pylint: disable=broad-exception-caught + logger.exception( + "Failed to load context: %s, falling back to contextvars_context", + configured_context, + ) + return ContextVarsRuntimeContext() + + +_RUNTIME_CONTEXT = _load_runtime_context() + + +def create_key(keyname: str) -> str: + """To allow cross-cutting concern to control access to their local state, + the RuntimeContext API provides a function which takes a keyname as input, + and returns a unique key. + Args: + keyname: The key name is for debugging purposes and is not required to be unique. + Returns: + A unique string representing the newly created key. + """ + return keyname + "-" + str(uuid4()) + + +def get_value(key: str, context: Context | None = None) -> object: + """To access the local state of a concern, the RuntimeContext API + provides a function which takes a context and a key as input, + and returns a value. + + Args: + key: The key of the value to retrieve. + context: The context from which to retrieve the value, if None, the current context is used. + + Returns: + The value associated with the key. + """ + return context.get(key) if context is not None else get_current().get(key) + + +def set_value(key: str, value: object, context: Context | None = None) -> Context: + """To record the local state of a cross-cutting concern, the + RuntimeContext API provides a function which takes a context, a + key, and a value as input, and returns an updated context + which contains the new value. + + Args: + key: The key of the entry to set. + value: The value of the entry to set. + context: The context to copy, if None, the current context is used. + + Returns: + A new `Context` containing the value set. + """ + if context is None: + context = get_current() + new_values = context.copy() + new_values[key] = value + return Context(new_values) + + +def get_current() -> Context: + """To access the context associated with program execution, + the Context API provides a function which takes no arguments + and returns a Context. + + Returns: + The current `Context` object. + """ + return _RUNTIME_CONTEXT.get_current() + + +def attach(context: Context) -> Token[Context]: + """Associates a Context with the caller's current execution unit. Returns + a token that can be used to restore the previous Context. + + Args: + context: The Context to set as current. + + Returns: + A token that can be used with `detach` to reset the context. + """ + return _RUNTIME_CONTEXT.attach(context) + + +def detach(token: Token[Context]) -> None: + """Resets the Context associated with the caller's current execution unit + to the value it had before attaching a specified Context. + + Args: + token: The Token that was returned by a previous call to attach a Context. + """ + try: + _RUNTIME_CONTEXT.detach(token) + except Exception: # pylint: disable=broad-exception-caught + logger.exception("Failed to detach context") + + +# FIXME This is a temporary location for the suppress instrumentation key. +# Once the decision around how to suppress instrumentation is made in the +# spec, this key should be moved accordingly. +_ON_EMIT_RECURSION_COUNT_KEY = create_key("on_emit_recursion_count") +_SUPPRESS_INSTRUMENTATION_KEY = create_key("suppress_instrumentation") +_SUPPRESS_HTTP_INSTRUMENTATION_KEY = create_key("suppress_http_instrumentation") + +__all__ = [ + "Context", + "attach", + "create_key", + "detach", + "get_current", + "get_value", + "set_value", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py new file mode 100644 index 00000000000..984bf424d84 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py @@ -0,0 +1,65 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from abc import ABC, abstractmethod +from contextvars import Token + + +class Context(dict[str, object]): + def __setitem__(self, key: str, value: object) -> None: + raise ValueError + + def __delitem__(self, key: str) -> None: + raise ValueError + + def setdefault(self, key: str, default: object = None) -> object: + raise ValueError + + def pop(self, key: str, *args: object) -> object: + raise ValueError + + def popitem(self) -> tuple[str, object]: + raise ValueError + + def clear(self) -> None: + raise ValueError + + def update(self, *args: object, **kwargs: object) -> None: + raise ValueError + + def __ior__(self, other: object) -> Context: + raise ValueError + + +class _RuntimeContext(ABC): + """The RuntimeContext interface provides a wrapper for the different + mechanisms that are used to propagate context in Python. + Implementations can be made available via entry_points and + selected through environment variables. + """ + + @abstractmethod + def attach(self, context: Context) -> Token[Context]: + """Sets the current `Context` object. Returns a + token that can be used to reset to the previous `Context`. + + Args: + context: The Context to set. + """ + + @abstractmethod + def get_current(self) -> Context: + """Returns the current `Context` object.""" + + @abstractmethod + def detach(self, token: Token[Context]) -> None: + """Resets Context to a previous value + + Args: + token: A reference to a previous Context. + """ + + +__all__ = ["Context"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py new file mode 100644 index 00000000000..923cc2dfc9e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py @@ -0,0 +1,43 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from contextvars import ContextVar, Token + +from opentelemetry.agent._vendor.opentelemetry.context.context import Context, _RuntimeContext + + +class ContextVarsRuntimeContext(_RuntimeContext): + """An implementation of the RuntimeContext interface which wraps ContextVar under + the hood. This is the preferred implementation for usage with Python 3.5+ + """ + + _CONTEXT_KEY = "current_context" + + def __init__(self) -> None: + self._current_context = ContextVar(self._CONTEXT_KEY, default=Context()) + + def attach(self, context: Context) -> Token[Context]: + """Sets the current `Context` object. Returns a + token that can be used to reset to the previous `Context`. + + Args: + context: The Context to set. + """ + return self._current_context.set(context) + + def get_current(self) -> Context: + """Returns the current `Context` object.""" + return self._current_context.get() + + def detach(self, token: Token[Context]) -> None: + """Resets Context to a previous value + + Args: + token: A reference to a previous Context. + """ + self._current_context.reset(token) + + +__all__ = ["ContextVarsRuntimeContext"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py new file mode 100644 index 00000000000..6165e7a93da --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py @@ -0,0 +1,32 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import os + +from opentelemetry.agent._vendor.opentelemetry.environment_variables import ( + OTEL_LOGS_EXPORTER, + OTEL_METRICS_EXPORTER, + OTEL_TRACES_EXPORTER, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.distro import BaseDistro +from opentelemetry.agent._vendor.opentelemetry.sdk._configuration import _OTelSDKConfigurator +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_PROTOCOL + + +class OpenTelemetryConfigurator(_OTelSDKConfigurator): + pass + + +class OpenTelemetryDistro(BaseDistro): + """ + The OpenTelemetry provided Distro configures a default set of + configuration out of the box. + """ + + # pylint: disable=no-self-use + def _configure(self, **kwargs): + os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp") + os.environ.setdefault(OTEL_METRICS_EXPORTER, "otlp") + os.environ.setdefault(OTEL_LOGS_EXPORTER, "otlp") + # opentelemetry-agent: the gRPC exporters aren't vendored (grpcio has no pure-Python wheel). + os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, "http/protobuf") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py new file mode 100644 index 00000000000..b335c826380 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py @@ -0,0 +1,72 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +OTEL_LOGS_EXPORTER = "OTEL_LOGS_EXPORTER" +""" +.. envvar:: OTEL_LOGS_EXPORTER + +""" + +OTEL_METRICS_EXPORTER = "OTEL_METRICS_EXPORTER" +""" +.. envvar:: OTEL_METRICS_EXPORTER + +Specifies which exporter is used for metrics. See `General SDK Configuration +`_. + +**Default value:** ``"otlp"`` + +**Example:** + +``export OTEL_METRICS_EXPORTER="prometheus"`` + +Accepted values for ``OTEL_METRICS_EXPORTER`` are: + +- ``"otlp"`` +- ``"prometheus"`` +- ``"none"``: No automatically configured exporter for metrics. + +.. note:: + + Exporter packages may add entry points for group ``opentelemetry_metrics_exporter`` which + can then be used with this environment variable by name. The entry point should point to + either a `opentelemetry.sdk.metrics.export.MetricExporter` (push exporter) or + `opentelemetry.sdk.metrics.export.MetricReader` (pull exporter) subclass; it must be + constructable without any required arguments. This mechanism is considered experimental and + may change in subsequent releases. +""" + +OTEL_PROPAGATORS = "OTEL_PROPAGATORS" +""" +.. envvar:: OTEL_PROPAGATORS +""" + +OTEL_PYTHON_CONTEXT = "OTEL_PYTHON_CONTEXT" +""" +.. envvar:: OTEL_PYTHON_CONTEXT +""" + +OTEL_PYTHON_ID_GENERATOR = "OTEL_PYTHON_ID_GENERATOR" +""" +.. envvar:: OTEL_PYTHON_ID_GENERATOR +""" + +OTEL_TRACES_EXPORTER = "OTEL_TRACES_EXPORTER" +""" +.. envvar:: OTEL_TRACES_EXPORTER +""" + +OTEL_PYTHON_TRACER_PROVIDER = "OTEL_PYTHON_TRACER_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_TRACER_PROVIDER +""" + +OTEL_PYTHON_METER_PROVIDER = "OTEL_PYTHON_METER_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_METER_PROVIDER +""" + +_OTEL_PYTHON_LOGGER_PROVIDER = "OTEL_PYTHON_LOGGER_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_LOGGER_PROVIDER +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py new file mode 100644 index 00000000000..72af79e9752 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py @@ -0,0 +1,73 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +# pylint: disable-next=import-error +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._requests import ( + RequestsHTTPTransport as _RequestsHTTPTransport, +) + +# pylint: disable-next=import-error +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._urllib3 import ( + Urllib3HTTPTransport as _Urllib3HTTPTransport, +) + +if TYPE_CHECKING: + from typing import Any, Protocol + + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport + + class BaseHTTPTransportFactory(Protocol): + def __call__( + self, + *, + verify: bool | str, + cert: str | tuple[str, str] | None, + **kwargs: Any, + ) -> BaseHTTPTransport: ... + + +_KNOWN_TRANSPORTS: dict[str, BaseHTTPTransportFactory] = { + "requests": _RequestsHTTPTransport, + "urllib3": _Urllib3HTTPTransport, +} + + +def _load_http_transport_factory(name: str) -> BaseHTTPTransportFactory: + """Return the transport factory registered under *name*. + + Checks the built-in transport registry first to avoid the overhead of an + entry-point scan for built-in transports. Falls back to standard entry-point + discovery for user supplied transports registered under the + ``opentelemetry_http_transport`` group. + + :param name: Entry point name, e.g. ``"requests"`` or ``"urllib3"``. + :returns: A callable with signature + ``(*, verify, cert, **kwargs) -> BaseHTTPTransport``. + :raises ValueError: If no transport is registered under *name*. + :raises TypeError: If the loaded entry point is not callable. + """ + if name in _KNOWN_TRANSPORTS: + return _KNOWN_TRANSPORTS[name] + # pylint: disable-next=import-outside-toplevel,import-error + from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 + entry_points, + ) + + ep = next( + iter(entry_points(group="opentelemetry_http_transport", name=name)), + None, + ) + if not ep: + raise ValueError( + f"No HTTP transport registered under name {name!r}. " + "Install the corresponding extra or register an entry point " + "under the 'opentelemetry_http_transport' group." + ) + factory = ep.load() + if not callable(factory): + raise TypeError(f"Transport {name!r} loaded from entry point is not callable (got {factory!r}).") + return cast("BaseHTTPTransportFactory", factory) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py new file mode 100644 index 00000000000..74b7976a5d0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py @@ -0,0 +1,91 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import json +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from collections.abc import Mapping + from typing import Any + + +@dataclass(frozen=True, slots=True) +class BaseHTTPResult(ABC): + """Outcome of a single HTTP request made by a :class:`BaseHTTPTransport`. + + Either ``status_code`` and ``reason`` are populated (server responded), + or ``error`` is set (request failed before a response was received). + """ + + status_code: int | None = None + reason: str | None = None + error: Exception | None = None + + @abstractmethod + def content(self) -> bytes: + """Return the raw response body. + + Implementations may raise an exception if the returned content is malformed. + """ + + @abstractmethod + def headers(self) -> Mapping[str, str]: + """Return the response headers. + + The returned mapping MUST be case-insensitive with respect to header + keys. Headers with multiple values are represented as a single string + of comma separated values. + + Implementations may raise an exception if the returned headers are malformed. + """ + + def text(self) -> str: + """Return the response body decoded as UTF-8. + + Implementations may raise an exception if the returned string is malformed. + """ + return self.content().decode("utf-8") + + def json(self) -> Any: + """Return the response body parsed as JSON. + + Implementations may raise an exception if no response content + is available or the returned JSON is malformed. + """ + return json.loads(self.text()) + + +class BaseHTTPTransport(ABC): + """Abstract HTTP transport interface used by HTTP exporters.""" + + @abstractmethod + def request( + self, + method: str, + url: str, + *, + headers: dict[str, str] | None = None, + timeout: float | None = None, + data: bytes | None = None, + ) -> BaseHTTPResult: + """Send an HTTP request and return the result. + + :param method: HTTP method (e.g. ``"POST"``). + :param url: Target URL. + :param headers: Optional HTTP headers to include in the request. + :param timeout: Optional request timeout in seconds. + :param data: Optional request body. + :returns: A :class:`BaseHTTPResult` describing the outcome. + """ + + @abstractmethod + def close(self) -> None: + """Release any resources held by the transport.""" + + @abstractmethod + def is_connection_error(self, exception: Exception | None) -> bool: + """Return ``True`` if the exception is a transport-level connection error.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py new file mode 100644 index 00000000000..90e6cb314df --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py @@ -0,0 +1,118 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import functools +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +# pylint: disable-next=import-error +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import ( + BaseHTTPResult, + BaseHTTPTransport, +) + +if TYPE_CHECKING: + from collections.abc import Mapping + from typing import Any + + from opentelemetry.agent._vendor import requests + from opentelemetry.agent._vendor.requests import Response + + +@functools.cache +def _get_connection_error_types() -> tuple[type[Exception], ...]: + # pylint: disable-next=import-outside-toplevel + import opentelemetry.agent._vendor.requests.exceptions + from opentelemetry.agent._vendor import requests + from opentelemetry.agent._vendor import opentelemetry # noqa: PLC0415 + + return ( + requests.exceptions.ConnectionError, + requests.exceptions.ConnectTimeout, + requests.exceptions.ReadTimeout, + requests.exceptions.Timeout, + requests.exceptions.SSLError, + requests.exceptions.ProxyError, + ) + + +@dataclass(frozen=True, slots=True) +class RequestsHTTPResult(BaseHTTPResult): + response: Response | None = field(default=None, hash=False, compare=False) + + def content(self) -> bytes: + if self.response is None: + return b"" + return self.response.content or b"" + + def text(self) -> str: + if self.response is None: + return "" + return self.response.text or "" + + def json(self) -> Any: + if self.response is None: + raise ValueError("No response available.") + return self.response.json() + + def headers(self) -> Mapping[str, str]: + if self.response is None: + return {} + return self.response.headers + + +class RequestsHTTPTransport(BaseHTTPTransport): + def __init__( + self, + *, + verify: bool | str = True, + cert: str | tuple[str, str] | None = None, + session: requests.Session | None = None, + **kwargs: Any, + ) -> None: + # pylint: disable-next=import-outside-toplevel + from opentelemetry.agent._vendor import requests # noqa: PLC0415 + + self._session = session if session is not None else requests.Session() + self._session.verify = verify + if cert is not None: + self._session.cert = cert + + def request( + self, + method: str, + url: str, + *, + headers: dict[str, str] | None = None, + timeout: float | None = None, + data: bytes | None = None, + ) -> BaseHTTPResult: + try: + response = self._session.request( + method=method, + url=url, + headers=headers, + data=data, + timeout=timeout, + allow_redirects=False, + ) + # pylint: disable-next=broad-exception-caught + except Exception as error: + # pylint: disable-next=unexpected-keyword-arg + return RequestsHTTPResult(error=error) + + # pylint: disable-next=unexpected-keyword-arg + return RequestsHTTPResult( + status_code=response.status_code, + reason=response.reason, + response=response, + ) + + # pylint: disable-next=no-self-use + def is_connection_error(self, exception: Exception | None) -> bool: + return isinstance(exception, _get_connection_error_types()) + + def close(self) -> None: + self._session.close() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py new file mode 100644 index 00000000000..6213b653791 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py @@ -0,0 +1,133 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import functools +import json +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +# pylint: disable-next=import-error +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import ( + BaseHTTPResult, + BaseHTTPTransport, +) + +if TYPE_CHECKING: + from collections.abc import Mapping + from typing import Any + + from opentelemetry.agent._vendor.urllib3 import BaseHTTPResponse + + +@functools.cache +def _get_connection_error_types() -> tuple[type[Exception], ...]: + # pylint: disable-next=import-outside-toplevel + import opentelemetry.agent._vendor.urllib3.exceptions + from opentelemetry.agent._vendor import urllib3 + from opentelemetry.agent._vendor import opentelemetry # noqa: PLC0415 + + types: list[type[Exception]] = [ + urllib3.exceptions.ConnectionError, + urllib3.exceptions.NewConnectionError, + urllib3.exceptions.ConnectTimeoutError, + urllib3.exceptions.MaxRetryError, + urllib3.exceptions.ProtocolError, + ] + + # NameResolutionError was added in urllib3 2.0 + name_resolution_error = getattr(urllib3.exceptions, "NameResolutionError", None) + if name_resolution_error is not None: + types.append(name_resolution_error) + + return tuple(types) + + +@dataclass(frozen=True, slots=True) +class Urllib3HTTPResult(BaseHTTPResult): + response: BaseHTTPResponse | None = field(default=None, hash=False, compare=False) + + def content(self) -> bytes: + if self.response is None: + return b"" + return self.response.data or b"" + + def headers(self) -> Mapping[str, str]: + if self.response is None: + return {} + return self.response.headers + + def json(self) -> Any: + if self.response is None: + raise ValueError("No response available.") + return json.loads(self.content()) + + +class Urllib3HTTPTransport(BaseHTTPTransport): + def __init__( + self, + *, + verify: bool | str = True, + cert: str | tuple[str, str] | None = None, + **kwargs: Any, + ) -> None: + # pylint: disable-next=import-outside-toplevel + from opentelemetry.agent._vendor import urllib3 # noqa: PLC0415 + + pool_kwargs: dict[str, object] = { + "retries": urllib3.Retry(0, redirect=False), + } + if verify is False: + pool_kwargs["cert_reqs"] = "CERT_NONE" + else: + pool_kwargs["cert_reqs"] = "CERT_REQUIRED" + if isinstance(verify, str): + pool_kwargs["ca_certs"] = verify + if isinstance(cert, tuple): + pool_kwargs["cert_file"] = cert[0] + pool_kwargs["key_file"] = cert[1] + elif isinstance(cert, str): + pool_kwargs["cert_file"] = cert + + self._pool = urllib3.PoolManager(**pool_kwargs) # type: ignore + + def request( + self, + method: str, + url: str, + *, + headers: dict[str, str] | None = None, + timeout: float | None = None, + data: bytes | None = None, + ) -> BaseHTTPResult: + # pylint: disable-next=import-outside-toplevel + from opentelemetry.agent._vendor import urllib3 # noqa: PLC0415 + + try: + response = self._pool.request( + method=method, + url=url, + headers=headers, + body=data, + timeout=urllib3.Timeout(total=timeout) if timeout is not None else None, + preload_content=True, + ) + # pylint: disable-next=broad-exception-caught + except Exception as error: + # pylint: disable-next=unexpected-keyword-arg + return Urllib3HTTPResult(error=error) + + # pylint: disable-next=unexpected-keyword-arg + return Urllib3HTTPResult( + status_code=response.status, + reason=response.reason, + response=response, + ) + + # pylint: disable-next=no-self-use + def is_connection_error(self, exception: Exception | None) -> bool: + return isinstance(exception, _get_connection_error_types()) + + def close(self) -> None: + self._pool.clear() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py new file mode 100644 index 00000000000..e57cf4aba95 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py @@ -0,0 +1,2 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py new file mode 100644 index 00000000000..74e52f456b8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py @@ -0,0 +1,112 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +import os + +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( + Counter, + Histogram, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import AggregationTemporality +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import ( + Aggregation, + ExplicitBucketHistogramAggregation, + ExponentialBucketHistogramAggregation, +) + +_logger = logging.getLogger(__name__) + + +def _get_temporality( + preferred_temporality: dict[type, AggregationTemporality] | None, +) -> dict[type, AggregationTemporality]: + temporality_preference = ( + os.environ.get( + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, + "CUMULATIVE", + ) + .upper() + .strip() + ) + + instrument_class_temporality: dict[type, AggregationTemporality] + match temporality_preference: + case "DELTA": + instrument_class_temporality = { + Counter: AggregationTemporality.DELTA, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.DELTA, + ObservableCounter: AggregationTemporality.DELTA, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + case "LOWMEMORY": + instrument_class_temporality = { + Counter: AggregationTemporality.DELTA, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.DELTA, + ObservableCounter: AggregationTemporality.CUMULATIVE, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + case _: + if temporality_preference != "CUMULATIVE": + _logger.warning( + ("Invalid value for %s: %s, using cumulative temporality aggregation"), + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, + temporality_preference, + ) + instrument_class_temporality = { + Counter: AggregationTemporality.CUMULATIVE, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.CUMULATIVE, + ObservableCounter: AggregationTemporality.CUMULATIVE, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + + return instrument_class_temporality | (preferred_temporality or {}) + + +def _get_aggregation( + preferred_aggregation: dict[type, Aggregation] | None, +) -> dict[type, Aggregation]: + default_histogram_aggregation = ( + os.environ.get( + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, + "explicit_bucket_histogram", + ) + .upper() + .strip() + ) + + instrument_class_aggregation: dict[type, Aggregation] + match default_histogram_aggregation: + case "BASE2_EXPONENTIAL_BUCKET_HISTOGRAM": + instrument_class_aggregation = { + Histogram: ExponentialBucketHistogramAggregation(), + } + case _: + if default_histogram_aggregation != "EXPLICIT_BUCKET_HISTOGRAM": + _logger.warning( + ("Invalid value for %s: %s, using explicit bucket histogram aggregation"), + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, + default_histogram_aggregation, + ) + + instrument_class_aggregation = { + Histogram: ExplicitBucketHistogramAggregation(), + } + + return instrument_class_aggregation | (preferred_aggregation or {}) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py new file mode 100644 index 00000000000..8d4029b539d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py @@ -0,0 +1,152 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections import Counter +from collections.abc import Iterator +from contextlib import AbstractContextManager, contextmanager +from dataclasses import dataclass +from time import perf_counter +from typing import TYPE_CHECKING, Protocol +from urllib.parse import urlparse + +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OTEL_COMPONENT_NAME, + OTEL_COMPONENT_TYPE, + OtelComponentTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( + create_otel_sdk_exporter_log_exported, + create_otel_sdk_exporter_log_inflight, + create_otel_sdk_exporter_metric_data_point_exported, + create_otel_sdk_exporter_metric_data_point_inflight, + create_otel_sdk_exporter_operation_duration, + create_otel_sdk_exporter_span_exported, + create_otel_sdk_exporter_span_inflight, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) + +if TYPE_CHECKING: + from typing import Literal + + from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes + +_component_counter = Counter() + +_GRPC_COMPONENT_TYPES = frozenset( + { + OtelComponentTypeValues.OTLP_GRPC_SPAN_EXPORTER, + OtelComponentTypeValues.OTLP_GRPC_LOG_EXPORTER, + OtelComponentTypeValues.OTLP_GRPC_METRIC_EXPORTER, + } +) + + +@dataclass +class ExportResult: + error: Exception | None = None + error_attrs: Attributes = None + + +class ExporterMetricsT(Protocol): + def export_operation(self, num_items: int) -> AbstractContextManager[ExportResult]: ... + + +class NoOpExporterMetrics: + @contextmanager + # pylint: disable-next=no-self-use + def export_operation(self, num_items: int) -> Iterator[ExportResult]: + yield ExportResult() + + +class ExporterMetrics: + def __init__( + self, + component_type: OtelComponentTypeValues | None, + signal: Literal["traces", "metrics", "logs"], + endpoint: str, + meter_provider: MeterProvider | None, + ) -> None: + if signal == "traces": + create_exported = create_otel_sdk_exporter_span_exported + create_inflight = create_otel_sdk_exporter_span_inflight + elif signal == "logs": + create_exported = create_otel_sdk_exporter_log_exported + create_inflight = create_otel_sdk_exporter_log_inflight + else: + create_exported = create_otel_sdk_exporter_metric_data_point_exported + create_inflight = create_otel_sdk_exporter_metric_data_point_inflight + + if not endpoint.startswith("//") and "://" not in endpoint: + endpoint = f"//{endpoint}" + parsed_endpoint = urlparse(endpoint) + + port = parsed_endpoint.port + if port is None: + if component_type in _GRPC_COMPONENT_TYPES or parsed_endpoint.scheme == "https": + port = 443 + elif parsed_endpoint.scheme == "http": + port = 80 + + component_type_value = component_type.value if component_type else "unknown_otlp_exporter" + count = _component_counter[component_type_value] + _component_counter[component_type_value] = count + 1 + self._standard_attrs: dict[str, AnyValue] = { + OTEL_COMPONENT_TYPE: component_type_value, + OTEL_COMPONENT_NAME: f"{component_type_value}/{count}", + } + if parsed_endpoint.hostname: + self._standard_attrs[SERVER_ADDRESS] = parsed_endpoint.hostname + if port is not None: + self._standard_attrs[SERVER_PORT] = port + + meter_provider = meter_provider or get_meter_provider() + meter = meter_provider.get_meter("opentelemetry-sdk") + self._inflight = create_inflight(meter) + self._exported = create_exported(meter) + self._duration = create_otel_sdk_exporter_operation_duration(meter) + + @contextmanager + def export_operation(self, num_items: int) -> Iterator[ExportResult]: + start_time = perf_counter() + self._inflight.add(num_items, self._standard_attrs) + + result = ExportResult() + try: + yield result + finally: + error = result.error + error_attrs = result.error_attrs + + end_time = perf_counter() + self._inflight.add(-num_items, self._standard_attrs) + exported_attrs = ( + {**self._standard_attrs, ERROR_TYPE: type(error).__qualname__} if error else self._standard_attrs + ) + self._exported.add(num_items, exported_attrs) + duration_attrs = {**exported_attrs, **error_attrs} if error_attrs else exported_attrs + self._duration.record(end_time - start_time, duration_attrs) + + +def create_exporter_metrics( + component_type: OtelComponentTypeValues | None, + signal: Literal["traces", "metrics", "logs"], + endpoint: str, + meter_provider: MeterProvider | None, + enabled: bool, +) -> ExporterMetricsT: + if not enabled: + return NoOpExporterMetrics() + + return ExporterMetrics( + component_type, + signal, + endpoint, + meter_provider, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py new file mode 100644 index 00000000000..1904c22ba3c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py @@ -0,0 +1,248 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import enum +import gzip +import logging +import math +import random +import threading +import time +import zlib +from collections.abc import Mapping +from dataclasses import dataclass +from datetime import timezone +from email.utils import parsedate_to_datetime +from http import HTTPStatus +from io import BytesIO +from typing import TYPE_CHECKING, Final, Literal + +if TYPE_CHECKING: + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import ( + BaseHTTPResult, + BaseHTTPTransport, + ) + +_logger = logging.getLogger(__name__) + +_MAX_RETRIES: Final[int] = 6 +_DEFAULT_TIMEOUT: Final[float] = 10.0 +_DEFAULT_JITTER: Final[float] = 0.2 + + +_RETRYABLE_STATUS_CODES: Final[frozenset[int]] = frozenset( + { + HTTPStatus.TOO_MANY_REQUESTS.value, + HTTPStatus.BAD_GATEWAY.value, + HTTPStatus.SERVICE_UNAVAILABLE.value, + HTTPStatus.GATEWAY_TIMEOUT.value, + } +) + + +def _is_retryable(status_code: int | None) -> bool: + return status_code in _RETRYABLE_STATUS_CODES + + +def _extract_retry_after(result: BaseHTTPResult) -> float | None: + """Parse the ``Retry-After`` header (RFC 7231).""" + try: + value = result.headers().get("retry-after") + # pylint: disable-next=broad-exception-caught + except Exception: + return None + if value is None: + return None + value = value.strip() + + # delay-seconds: a non-negative decimal integer. + try: + seconds = float(value) + except ValueError: + pass + else: + return max(seconds, 0.0) if math.isfinite(seconds) else None + + # HTTP-date: wait until the indicated absolute time. + try: + retry_at = parsedate_to_datetime(value) + except (TypeError, ValueError): + return None + if retry_at.tzinfo is None: + retry_at = retry_at.replace(tzinfo=timezone.utc) + return max(retry_at.timestamp() - time.time(), 0.0) + + +class Compression(enum.Enum): + NONE = "none" + DEFLATE = "deflate" + GZIP = "gzip" + + @staticmethod + def from_str(value: str) -> Compression: + match value.strip().lower(): + case "none": + return Compression.NONE + case "deflate": + return Compression.DEFLATE + case "gzip": + return Compression.GZIP + case _: + raise ValueError(f"Invalid compression type: {value!r}. Expected one of: 'none', 'deflate', 'gzip'.") + + +@dataclass(slots=True, frozen=True) +class _ExportResult: + """Outcome of an OTLP export attempt, including retry exhaustion.""" + + success: bool + status_code: int | None + reason: str | None + error: Exception | None + + +class _OTLPHTTPClient: + """Sends serialized OTLP payloads over HTTP with retry logic. + + Compression, backoff, and connection-error recovery are handled internally. + Callers interact through the :meth:`export` and :meth:`close` methods. + """ + + def __init__( + self, + transport: BaseHTTPTransport, + endpoint: str, + kind: Literal["spans", "logs", "metrics"], + timeout: float = _DEFAULT_TIMEOUT, + compression: Compression = Compression.NONE, + headers: Mapping[str, str] | None = None, + jitter: float = _DEFAULT_JITTER, + logger: logging.Logger | None = None, + ) -> None: + self._transport = transport + self._endpoint = endpoint + self._timeout = timeout + self._compression = compression + self._headers = dict(headers) if headers is not None else {} + if self._compression is not Compression.NONE and not any( + key.lower() == "content-encoding" for key in self._headers + ): + self._headers["Content-Encoding"] = self._compression.value + self._kind = kind + self._jitter = min(max(jitter, 0.0), 1.0) + self._logger = logger if logger is not None else _logger + self._shutdown = False + self._shutdown_event = threading.Event() + + def _compute_backoff(self, retry: int) -> float: + return 2**retry * random.uniform(1 - self._jitter, 1 + self._jitter) + + def _compress(self, serialized_data: bytes) -> bytes: + if self._compression is Compression.GZIP: + buf = BytesIO() + with gzip.GzipFile(fileobj=buf, mode="w") as gz: + gz.write(serialized_data) + return buf.getvalue() + if self._compression is Compression.DEFLATE: + return zlib.compress(serialized_data) + return serialized_data + + def _submit(self, data: bytes, timeout: float) -> BaseHTTPResult: + deadline = time.time() + timeout + result = self._transport.request( + "POST", + self._endpoint, + headers=self._headers, + data=data, + timeout=timeout, + ) + if ( + result.error is not None + and self._transport.is_connection_error(result.error) + and (remaining := deadline - time.time()) > 0 + ): + # Immediately retry connection errors once without backoff. These + # usually indicate a stale pooled connection that the transport will + # reestablish on the next attempt. + result = self._transport.request( + "POST", + self._endpoint, + headers=self._headers, + data=data, + timeout=remaining, + ) + return result + + def export(self, data: bytes) -> _ExportResult: + """Export a serialized payload, retrying on transient failures. + + :param data: Serialized bytes to send. + :returns: An :class:`ExportResult` indicating success or the reason for failure. + """ + data = self._compress(data) + deadline = time.time() + self._timeout + + for retry in range(_MAX_RETRIES): + backoff = self._compute_backoff(retry) + status_code: int | None = None + reason: str | None = None + export_error: Exception | None + retryable: bool + + try: + result = self._submit(data, max(deadline - time.time(), 0.0)) + # pylint: disable-next=broad-exception-caught + except Exception as error: + export_error = error + retryable = False + else: + status_code = result.status_code + reason = result.reason + if status_code is not None and 200 <= status_code < 400: + return _ExportResult(True, status_code, reason, None) + export_error = result.error + retryable = ( + _is_retryable(status_code) if status_code else self._transport.is_connection_error(result.error) + ) + if retryable and status_code is not None and (retry_after := _extract_retry_after(result)) is not None: + backoff = retry_after + + if not retryable: + self._logger.error( + "Failed to export %s batch code: %s, reason: %s", + self._kind, + status_code, + reason or export_error or "unknown", + ) + return _ExportResult(False, status_code, reason, export_error) + + if retry + 1 == _MAX_RETRIES or backoff > (deadline - time.time()) or self._shutdown_event.is_set(): + self._logger.error( + "Failed to export %s batch due to timeout, max retries or shutdown.", + self._kind, + ) + return _ExportResult(False, status_code, reason, export_error) + + self._logger.warning( + "Transient error %s encountered while exporting %s batch, retrying in %.2fs.", + reason or export_error, + self._kind, + backoff, + ) + shutdown = self._shutdown_event.wait(backoff) + if shutdown: + self._logger.warning("Shutdown in progress, aborting retry.") + break + + return _ExportResult(False, None, None, None) + + def shutdown(self) -> None: + """Shutdown the client.""" + if self._shutdown: + self._logger.warning("OTLP client already shutdown, ignoring call") + return + self._shutdown = True + self._shutdown_event.set() + self._transport.close() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py new file mode 100644 index 00000000000..e57cf4aba95 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py @@ -0,0 +1,2 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py new file mode 100644 index 00000000000..cf1ca13c262 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py @@ -0,0 +1,98 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pyright: reportCallIssue=false + +from __future__ import annotations + +import logging +from collections.abc import Mapping, Sequence +from typing import Any + +from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import AnyValue as JSONAnyValue +from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import ( + ArrayValue as JSONArrayValue, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import ( + InstrumentationScope as JSONInstrumentationScope, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import KeyValue as JSONKeyValue +from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import ( + KeyValueList as JSONKeyValueList, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource import ( + Resource as JSONResource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +_logger = logging.getLogger(__name__) + + +def _encode_instrumentation_scope( + instrumentation_scope: InstrumentationScope | None, +) -> JSONInstrumentationScope: + return ( + JSONInstrumentationScope( + name=instrumentation_scope.name, + version=instrumentation_scope.version, + attributes=_encode_attributes(instrumentation_scope.attributes), + ) + if instrumentation_scope is not None + else JSONInstrumentationScope() + ) + + +def _encode_resource(resource: Resource) -> JSONResource: + return JSONResource(attributes=_encode_attributes(resource.attributes)) + + +# pylint: disable-next=too-many-return-statements +def _encode_value(value: Any) -> JSONAnyValue: + if value is None: + return JSONAnyValue() + if isinstance(value, bool): + return JSONAnyValue(bool_value=value) + if isinstance(value, str): + return JSONAnyValue(string_value=value) + if isinstance(value, int): + return JSONAnyValue(int_value=value) + if isinstance(value, float): + return JSONAnyValue(double_value=value) + if isinstance(value, bytes): + return JSONAnyValue(bytes_value=value) + if isinstance(value, Sequence): + return JSONAnyValue(array_value=JSONArrayValue(values=[_encode_value(v) for v in value])) + if isinstance(value, Mapping): + return JSONAnyValue( + kvlist_value=JSONKeyValueList(values=[_encode_key_value(str(k), v) for k, v in value.items()]) + ) + raise TypeError(f"Invalid type {type(value)} of value {value}") + + +def _encode_key_value(key: str, value: Any) -> JSONKeyValue: + return JSONKeyValue(key=key, value=_encode_value(value)) + + +def _encode_span_id(span_id: int) -> bytes: + return span_id.to_bytes(length=8, byteorder="big", signed=False) + + +def _encode_trace_id(trace_id: int) -> bytes: + return trace_id.to_bytes(length=16, byteorder="big", signed=False) + + +def _encode_attributes( + attributes: Attributes, +) -> list[JSONKeyValue]: + if not attributes: + return [] + json_attributes = [] + for key, value in attributes.items(): + # pylint: disable=broad-exception-caught + try: + json_attributes.append(_encode_key_value(key, value)) + except Exception as error: + _logger.exception("Failed to encode key %s: %s", key, error) + return json_attributes diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py new file mode 100644 index 00000000000..5aa5f9a7d16 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py @@ -0,0 +1,89 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pyright: reportCallIssue=false + +from __future__ import annotations + +from collections import defaultdict +from collections.abc import Collection +from typing import cast + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal import ( + _encode_attributes, + _encode_instrumentation_scope, + _encode_resource, + _encode_span_id, + _encode_trace_id, + _encode_value, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.collector.logs.v1.logs_service import ( + ExportLogsServiceRequest as JSONExportLogsServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs import LogRecord as JSONLogRecord +from opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs import ( + ResourceLogs as JSONResourceLogs, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs import ( + ScopeLogs as JSONScopeLogs, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + + +def encode_logs( + batch: Collection[ReadableLogRecord], +) -> JSONExportLogsServiceRequest: + return JSONExportLogsServiceRequest(resource_logs=_encode_resource_logs(batch)) + + +def _encode_log(readable_log_record: ReadableLogRecord) -> JSONLogRecord: + return JSONLogRecord( + time_unix_nano=readable_log_record.log_record.timestamp, + observed_time_unix_nano=readable_log_record.log_record.observed_timestamp, + span_id=_encode_span_id(readable_log_record.log_record.span_id) + if readable_log_record.log_record.span_id + else None, + trace_id=_encode_trace_id(readable_log_record.log_record.trace_id) + if readable_log_record.log_record.trace_id + else None, + flags=int(readable_log_record.log_record.trace_flags), + body=_encode_value(readable_log_record.log_record.body), + severity_text=readable_log_record.log_record.severity_text, + attributes=_encode_attributes(cast(Attributes, readable_log_record.log_record.attributes)), + dropped_attributes_count=readable_log_record.dropped_attributes, + severity_number=getattr(readable_log_record.log_record.severity_number, "value", None), + event_name=readable_log_record.log_record.event_name, + ) + + +def _encode_resource_logs( + batch: Collection[ReadableLogRecord], +) -> list[JSONResourceLogs]: + sdk_resource_logs = defaultdict(lambda: defaultdict(list)) + + for readable_log in batch: + sdk_resource = readable_log.resource + sdk_instrumentation = readable_log.instrumentation_scope or None + sdk_resource_logs[sdk_resource][sdk_instrumentation].append(_encode_log(readable_log)) + + json_resource_logs = [] + for sdk_resource, sdk_instrumentations in sdk_resource_logs.items(): + scope_logs = [] + for sdk_instrumentation, json_logs in sdk_instrumentations.items(): + scope_logs.append( + JSONScopeLogs( + scope=(_encode_instrumentation_scope(sdk_instrumentation)), + log_records=json_logs, + schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, + ) + ) + json_resource_logs.append( + JSONResourceLogs( + resource=_encode_resource(sdk_resource), + scope_logs=scope_logs, + schema_url=sdk_resource.schema_url, + ) + ) + + return json_resource_logs diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py new file mode 100644 index 00000000000..2e718a53f6d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py @@ -0,0 +1,372 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# type: ignore[reportArgumentType] +# pyright: reportCallIssue=false + +from __future__ import annotations + +import logging +from collections.abc import Collection, Iterable +from dataclasses import replace +from typing import TYPE_CHECKING + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal import ( + _encode_attributes, + _encode_instrumentation_scope, + _encode_span_id, + _encode_trace_id, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.collector.metrics.v1.metrics_service import ( + ExportMetricsServiceRequest as JSONExportMetricsServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + Exemplar as JSONExemplar, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + ExponentialHistogram as JSONExponentialHistogram, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + ExponentialHistogramDataPoint as JSONExponentialHistogramDataPoint, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import Gauge as JSONGauge +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + Histogram as JSONHistogram, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + HistogramDataPoint as JSONHistogramDataPoint, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import Metric as JSONMetric +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + NumberDataPoint as JSONNumberDataPoint, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + ResourceMetrics as JSONResourceMetrics, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( + ScopeMetrics as JSONScopeMetrics, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import Sum as JSONSum +from opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource import ( + Resource as JSONResource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( + Exemplar, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( + ExponentialHistogramDataPoint, + HistogramDataPoint, + Metric, + NumberDataPoint, + ResourceMetrics, + ScopeMetrics, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + ExponentialHistogram, + Gauge, + Histogram, + MetricsData, + Sum, +) + +if TYPE_CHECKING: + from opentelemetry.agent._vendor.typing_extensions import assert_never + +_logger = logging.getLogger(__name__) + +_METRIC_DATA_FIELDS = ( + "gauge", + "sum", + "histogram", + "exponential_histogram", + "summary", +) + + +def encode_metrics(data: MetricsData) -> JSONExportMetricsServiceRequest: + return JSONExportMetricsServiceRequest( + resource_metrics=[_encode_resource_metrics(rm) for rm in data.resource_metrics] + ) + + +# pylint: disable-next=too-many-locals +def split_metrics_data( + metrics_data: JSONExportMetricsServiceRequest, + max_export_batch_size: int | None, +) -> Iterable[JSONExportMetricsServiceRequest]: + """Split an ExportMetricsServiceRequest into batches of at most + max_export_batch_size data points, preserving resource/scope hierarchy. + """ + if max_export_batch_size is None: + yield metrics_data + return + + batch_size: int = 0 + resource_metrics_batch: list[JSONResourceMetrics] = [] + scope_metrics_batch: list[JSONScopeMetrics] = [] + metrics_batch: list[JSONMetric] = [] + + for ( + resource_metrics, + scope_metrics, + metric, + field_name, + data_points, + ) in _iter_metric_data_points(metrics_data): + if not resource_metrics_batch or resource_metrics_batch[-1].resource is not resource_metrics.resource: + scope_metrics_batch = [] + resource_metrics_batch.append(replace(resource_metrics, scope_metrics=scope_metrics_batch)) + + if not scope_metrics_batch or scope_metrics_batch[-1].scope is not scope_metrics.scope: + metrics_batch = [] + scope_metrics_batch.append(replace(scope_metrics, metrics=metrics_batch)) + + data_points_batch: list = [] + metrics_batch.append(_build_metric_with_data_points(metric, field_name, data_points_batch)) + + for data_point in data_points: + data_points_batch.append(data_point) + batch_size += 1 + + if batch_size >= max_export_batch_size: + yield JSONExportMetricsServiceRequest(resource_metrics=resource_metrics_batch) + ( + resource_metrics_batch, + scope_metrics_batch, + metrics_batch, + data_points_batch, + ) = _build_empty_metric_batches(resource_metrics, scope_metrics, metric, field_name) + batch_size = 0 + + if not batch_size: + resource_metrics_batch = [] + scope_metrics_batch = [] + metrics_batch = [] + + if batch_size: + yield JSONExportMetricsServiceRequest(resource_metrics=resource_metrics_batch) + + +def _get_metric_data_field_name(metric: JSONMetric) -> str | None: + return next( + (f for f in _METRIC_DATA_FIELDS if getattr(metric, f) is not None), + None, + ) + + +def _iter_metric_data_points( + metrics_data: JSONExportMetricsServiceRequest, +) -> Iterable[tuple[JSONResourceMetrics, JSONScopeMetrics, JSONMetric, str, list]]: + for resource_metrics in metrics_data.resource_metrics: + for scope_metrics in resource_metrics.scope_metrics: + for metric in scope_metrics.metrics: + field_name = _get_metric_data_field_name(metric) + if field_name is None: + _logger.warning("Tried to split and export an unsupported metric type. Skipping.") + continue + dps = getattr(metric, field_name).data_points + if not dps: + _logger.warning("Unexpected empty metric datapoints. Skipping.") + continue + yield ( + resource_metrics, + scope_metrics, + metric, + field_name, + dps, + ) + + +def _build_metric_with_data_points( + metric: JSONMetric, + field_name: str, + data_points: list, +) -> JSONMetric: + new_data = replace(getattr(metric, field_name), data_points=data_points) + return replace(metric, **{field_name: new_data}) + + +def _build_empty_metric_batches( + resource_metrics: JSONResourceMetrics, + scope_metrics: JSONScopeMetrics, + metric: JSONMetric, + field_name: str, +) -> tuple[list[JSONResourceMetrics], list[JSONScopeMetrics], list[JSONMetric], list]: + data_points_batch = [] + metrics_batch = [_build_metric_with_data_points(metric, field_name, data_points_batch)] + scope_metrics_batch = [replace(scope_metrics, metrics=metrics_batch)] + resource_metrics_batch = [replace(resource_metrics, scope_metrics=scope_metrics_batch)] + return ( + resource_metrics_batch, + scope_metrics_batch, + metrics_batch, + data_points_batch, + ) + + +def _encode_resource_metrics( + rm: ResourceMetrics, +) -> JSONResourceMetrics: + return JSONResourceMetrics( + resource=JSONResource(attributes=_encode_attributes(rm.resource.attributes)), + scope_metrics=[_encode_scope_metrics(sm) for sm in rm.scope_metrics], + schema_url=rm.resource.schema_url, + ) + + +def _encode_scope_metrics( + sm: ScopeMetrics, +) -> JSONScopeMetrics: + return JSONScopeMetrics( + scope=_encode_instrumentation_scope(sm.scope), + schema_url=sm.scope.schema_url, + metrics=[_encode_metric(m) for m in sm.metrics], + ) + + +def _encode_metric(metric: Metric) -> JSONMetric: + json_metric = JSONMetric( + name=metric.name, + description=metric.description, + unit=metric.unit, + ) + if isinstance(metric.data, Gauge): + json_metric.gauge = JSONGauge(data_points=[_encode_gauge_data_point(pt) for pt in metric.data.data_points]) + elif isinstance(metric.data, Histogram): + json_metric.histogram = JSONHistogram( + data_points=[_encode_histogram_data_point(pt) for pt in metric.data.data_points], + aggregation_temporality=metric.data.aggregation_temporality, + ) + elif isinstance(metric.data, Sum): + json_metric.sum = JSONSum( + data_points=[_encode_sum_data_point(pt) for pt in metric.data.data_points], + aggregation_temporality=metric.data.aggregation_temporality, + is_monotonic=metric.data.is_monotonic, + ) + elif isinstance(metric.data, ExponentialHistogram): + json_metric.exponential_histogram = JSONExponentialHistogram( + data_points=[_encode_exponential_histogram_data_point(pt) for pt in metric.data.data_points], + aggregation_temporality=metric.data.aggregation_temporality, + ) + else: + if TYPE_CHECKING: + assert_never(metric.data) + _logger.warning( + "unsupported data type %s", + metric.data.__class__.__name__, + ) + return json_metric + + +def _encode_gauge_data_point( + data_point: NumberDataPoint, +) -> JSONNumberDataPoint: + pt = JSONNumberDataPoint( + attributes=_encode_attributes(data_point.attributes), + time_unix_nano=data_point.time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + ) + if isinstance(data_point.value, int): + pt.as_int = data_point.value + else: + pt.as_double = data_point.value + return pt + + +def _encode_sum_data_point( + data_point: NumberDataPoint, +) -> JSONNumberDataPoint: + pt = JSONNumberDataPoint( + attributes=_encode_attributes(data_point.attributes), + start_time_unix_nano=data_point.start_time_unix_nano, + time_unix_nano=data_point.time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + ) + if isinstance(data_point.value, int): + pt.as_int = data_point.value + else: + pt.as_double = data_point.value + return pt + + +def _encode_histogram_data_point( + data_point: HistogramDataPoint, +) -> JSONHistogramDataPoint: + return JSONHistogramDataPoint( + attributes=_encode_attributes(data_point.attributes), + time_unix_nano=data_point.time_unix_nano, + start_time_unix_nano=data_point.start_time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + count=data_point.count, + sum=data_point.sum, + bucket_counts=list(data_point.bucket_counts), + explicit_bounds=list(data_point.explicit_bounds), + max=data_point.max, + min=data_point.min, + ) + + +def _encode_exponential_histogram_data_point( + data_point: ExponentialHistogramDataPoint, +) -> JSONExponentialHistogramDataPoint: + return JSONExponentialHistogramDataPoint( + attributes=_encode_attributes(data_point.attributes), + time_unix_nano=data_point.time_unix_nano, + start_time_unix_nano=data_point.start_time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + count=data_point.count, + sum=data_point.sum, + scale=data_point.scale, + zero_count=data_point.zero_count, + positive=( + JSONExponentialHistogramDataPoint.Buckets( + offset=data_point.positive.offset, + bucket_counts=list(data_point.positive.bucket_counts), + ) + if data_point.positive.bucket_counts + else None + ), + negative=( + JSONExponentialHistogramDataPoint.Buckets( + offset=data_point.negative.offset, + bucket_counts=list(data_point.negative.bucket_counts), + ) + if data_point.negative.bucket_counts + else None + ), + flags=data_point.flags, + max=data_point.max, + min=data_point.min, + ) + + +def _encode_exemplars( + sdk_exemplars: Collection[Exemplar], +) -> list[JSONExemplar]: + json_exemplars = [] + for sdk_exemplar in sdk_exemplars: + if sdk_exemplar.span_id is not None and sdk_exemplar.trace_id is not None: + json_exemplar = JSONExemplar( + time_unix_nano=sdk_exemplar.time_unix_nano, + span_id=_encode_span_id(sdk_exemplar.span_id), + trace_id=_encode_trace_id(sdk_exemplar.trace_id), + filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), + ) + else: + json_exemplar = JSONExemplar( + time_unix_nano=sdk_exemplar.time_unix_nano, + filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), + ) + + # Assign the value based on its type in the SDK exemplar + if isinstance(sdk_exemplar.value, float): + json_exemplar.as_double = sdk_exemplar.value + elif isinstance(sdk_exemplar.value, int): + json_exemplar.as_int = sdk_exemplar.value + else: + if TYPE_CHECKING: + assert_never(sdk_exemplar.value) + raise ValueError("Exemplar value must be an int or float") + json_exemplars.append(json_exemplar) + + return json_exemplars diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py new file mode 100644 index 00000000000..7e4b4d9550a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py @@ -0,0 +1,159 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pyright: reportCallIssue=false + +from __future__ import annotations + +import logging +from collections import defaultdict +from collections.abc import Collection + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal import ( + _encode_attributes, + _encode_instrumentation_scope, + _encode_resource, + _encode_span_id, + _encode_trace_id, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.collector.trace.v1.trace_service import ( + ExportTraceServiceRequest as JSONExportTraceServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import ( + ResourceSpans as JSONResourceSpans, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import ( + ScopeSpans as JSONScopeSpans, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import Span as JSONSpan +from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import ( + SpanFlags as JSONSpanFlags, +) +from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import Status as JSONStatus +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Event, ReadableSpan +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind +from opentelemetry.agent._vendor.opentelemetry.trace.span import SpanContext, Status, TraceState + +# pylint: disable=E1101 +_SPAN_KIND_MAP = { + SpanKind.INTERNAL: JSONSpan.SpanKind.SPAN_KIND_INTERNAL, + SpanKind.SERVER: JSONSpan.SpanKind.SPAN_KIND_SERVER, + SpanKind.CLIENT: JSONSpan.SpanKind.SPAN_KIND_CLIENT, + SpanKind.PRODUCER: JSONSpan.SpanKind.SPAN_KIND_PRODUCER, + SpanKind.CONSUMER: JSONSpan.SpanKind.SPAN_KIND_CONSUMER, +} + +_logger = logging.getLogger(__name__) + + +def encode_spans( + sdk_spans: Collection[ReadableSpan], +) -> JSONExportTraceServiceRequest: + return JSONExportTraceServiceRequest(resource_spans=_encode_resource_spans(sdk_spans)) + + +def _encode_resource_spans( + sdk_spans: Collection[ReadableSpan], +) -> list[JSONResourceSpans]: + sdk_resource_spans = defaultdict(lambda: defaultdict(list)) + + for sdk_span in sdk_spans: + sdk_resource = sdk_span.resource + sdk_instrumentation = sdk_span.instrumentation_scope or None + sdk_resource_spans[sdk_resource][sdk_instrumentation].append(_encode_span(sdk_span)) + + json_resource_spans = [] + for sdk_resource, sdk_instrumentations in sdk_resource_spans.items(): + scope_spans = [] + for sdk_instrumentation, json_spans in sdk_instrumentations.items(): + scope_spans.append( + JSONScopeSpans( + scope=(_encode_instrumentation_scope(sdk_instrumentation)), + spans=json_spans, + schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, + ) + ) + json_resource_spans.append( + JSONResourceSpans( + resource=_encode_resource(sdk_resource), + scope_spans=scope_spans, + schema_url=sdk_resource.schema_url, + ) + ) + + return json_resource_spans + + +def _span_flags(parent_span_context: SpanContext | None) -> int: + flags = JSONSpanFlags.SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK + if parent_span_context and parent_span_context.is_remote: + flags |= JSONSpanFlags.SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK + return int(flags) + + +def _encode_span(sdk_span: ReadableSpan) -> JSONSpan: + span_context = sdk_span.get_span_context() + return JSONSpan( + trace_id=_encode_trace_id(span_context.trace_id if span_context else 0), + span_id=_encode_span_id(span_context.span_id if span_context else 0), + trace_state=_encode_trace_state(span_context.trace_state if span_context else None), + parent_span_id=_encode_context_span_id(sdk_span.parent), + name=sdk_span.name, + kind=_SPAN_KIND_MAP[sdk_span.kind], + start_time_unix_nano=sdk_span.start_time, + end_time_unix_nano=sdk_span.end_time, + attributes=_encode_attributes(sdk_span.attributes), + events=_encode_events(sdk_span.events), + links=_encode_links(sdk_span.links), + status=_encode_status(sdk_span.status), + dropped_attributes_count=sdk_span.dropped_attributes, + dropped_events_count=sdk_span.dropped_events, + dropped_links_count=sdk_span.dropped_links, + flags=_span_flags(sdk_span.parent), + ) + + +def _encode_events( + events: Collection[Event], +) -> list[JSONSpan.Event]: + return [ + JSONSpan.Event( + name=event.name, + time_unix_nano=event.timestamp, + attributes=_encode_attributes(event.attributes), + dropped_attributes_count=event.dropped_attributes, + ) + for event in events + ] + + +def _encode_links(links: Collection[Link]) -> list[JSONSpan.Link]: + return [ + JSONSpan.Link( + trace_id=_encode_trace_id(link.context.trace_id), + span_id=_encode_span_id(link.context.span_id), + attributes=_encode_attributes(link.attributes), + dropped_attributes_count=link.dropped_attributes, + flags=_span_flags(link.context), + ) + for link in links + ] + + +def _encode_status(status: Status | None) -> JSONStatus | None: + return ( + JSONStatus( + code=JSONStatus.StatusCode(status.status_code.value), + message=status.description, + ) + if status is not None + else None + ) + + +def _encode_trace_state(trace_state: TraceState | None) -> str | None: + return ",".join([f"{key}={value}" for key, value in (trace_state.items())]) if trace_state is not None else None + + +def _encode_context_span_id(context: SpanContext | None) -> bytes | None: + return _encode_span_id(context.span_id) if context else None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py new file mode 100644 index 00000000000..f6fff4cf524 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py @@ -0,0 +1,8 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal._log_encoder import ( + encode_logs, +) + +__all__ = ["encode_logs"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py new file mode 100644 index 00000000000..b16f5d63353 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py @@ -0,0 +1,8 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.metrics_encoder import ( + encode_metrics, +) + +__all__ = ["encode_metrics"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py new file mode 100644 index 00000000000..4968e789f14 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py @@ -0,0 +1,8 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.trace_encoder import ( + encode_spans, +) + +__all__ = ["encode_spans"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py new file mode 100644 index 00000000000..228853fab25 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py @@ -0,0 +1,73 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +This library allows exporting OpenTelemetry telemetry to a file or stream +in OTLP JSON (JSON Lines) format. + +Usage +----- + +The **OTLP JSON File Exporter** writes `OpenTelemetry`_ traces, metrics, and +logs as compact JSON Lines to a file, an arbitrary ``IO[str]`` stream or +``sys.stdout``. + +Three exporters are provided: + +- :class:`~opentelemetry.exporter.otlp.json.file.trace_exporter.FileSpanExporter` - traces +- :class:`~opentelemetry.exporter.otlp.json.file.metric_exporter.FileMetricExporter` - metrics +- :class:`~opentelemetry.exporter.otlp.json.file._log_exporter.FileLogExporter` - logs + +Each exporter accepts a destination in one of three ways: + +- ``path`` - a file path opened in append mode (UTF-8) +- ``stream`` - any ``IO[str]`` text stream +- neither - defaults to ``sys.stdout`` + +.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ + +.. code:: python + + from opentelemetry import trace + from opentelemetry.exporter.otlp.json.file import FileSpanExporter + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchSpanProcessor + + # Write traces to a file (append mode, UTF-8) + exporter = FileSpanExporter("/var/log/otel/traces.jsonl") + + # Alternatively, write to an explicit stream: + # exporter = FileSpanExporter(stream=open("traces.jsonl", "a")) + + # Or write to sys.stdout (default when no path or stream is given): + # exporter = FileSpanExporter() + + trace.set_tracer_provider(TracerProvider()) + trace.get_tracer_provider().add_span_processor( + BatchSpanProcessor(exporter) + ) + + tracer = trace.get_tracer(__name__) + with tracer.start_as_current_span("foo"): + print("Hello world!") + +The metric exporter supports the following environment variables: + +- :envvar:`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` +- :envvar:`OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` + +API +--- +""" + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.metric_exporter import ( + FileMetricExporter, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.trace_exporter import ( + FileSpanExporter, +) + +__all__ = [ + "FileMetricExporter", + "FileSpanExporter", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py new file mode 100644 index 00000000000..34222944cf1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py @@ -0,0 +1,80 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import json +import logging +import sys +import threading +from collections.abc import Callable +from os import PathLike +from typing import IO, Generic, Literal, TypeVar + +_logger = logging.getLogger(__name__) + +T = TypeVar("T") + + +class _FileExporter(Generic[T]): + def __init__( + self, + encode: Callable[[T], dict | None], + kind: Literal["spans", "logs", "metrics"], + logger: logging.Logger | None = None, + path: str | PathLike[str] | None = None, + stream: IO[str] | None = None, + ) -> None: + if path is not None and stream is not None: + raise ValueError("Cannot specify both 'path' and 'stream'") + if path is not None: + self._stream: IO[str] = open( # pylint: disable=consider-using-with + path, "a", encoding="utf-8" + ) + self._owns_stream = True + elif stream is not None: + self._stream = stream + self._owns_stream = False + else: + self._stream = sys.stdout + self._owns_stream = False + self._shutdown = False + self._encode = encode + self._kind = kind + self._logger = logger if logger is not None else _logger + self._lock = threading.Lock() + + def export(self, data: T) -> bool: + if self._shutdown: + self._logger.warning("Exporter already shutdown, ignoring call") + return False + try: + encoded = self._encode(data) + with self._lock: + if self._stream.closed: + self._logger.warning("Stream is closed, ignoring %s export call", self._kind) + return False + if encoded is not None: + self._stream.write(_format_line(encoded)) + self._stream.flush() + # pylint: disable-next=broad-exception-caught + except Exception as error: + self._logger.exception( + "Failed to write %s batch to stream: %s: %s", + self._kind, + type(error).__name__, + error, + ) + return False + return True + + def shutdown(self) -> None: + if self._shutdown: + self._logger.warning("Exporter already shutdown, ignoring call") + return + self._shutdown = True + if self._owns_stream: + with self._lock: + self._stream.close() + + +def _format_line(entry: dict) -> str: + return json.dumps(entry, separators=(",", ":")) + "\n" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py new file mode 100644 index 00000000000..028a923ca77 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py @@ -0,0 +1,70 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os +from collections.abc import Sequence +from typing import IO, Any, overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._log_encoder import encode_logs +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._internal import _FileExporter +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord +from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( + LogRecordExporter, + LogRecordExportResult, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import DuplicateFilter + +_logger = logging.getLogger(__name__) +_logger.addFilter(DuplicateFilter()) + + +def _encode_logs_to_dict( + batch: Sequence[ReadableLogRecord], +) -> dict[str, Any] | None: + data = encode_logs(batch) + return data.to_dict() if data.resource_logs else None + + +class FileLogExporter(LogRecordExporter): + @overload + def __init__( + self, + path: str | os.PathLike[str], + ) -> None: ... + + @overload + def __init__( + self, + *, + stream: IO[str], + ) -> None: ... + + @overload + def __init__( + self, + ) -> None: ... + + def __init__( + self, + path: str | os.PathLike[str] | None = None, + *, + stream: IO[str] | None = None, + ) -> None: + self._exporter: _FileExporter[Sequence[ReadableLogRecord]] = _FileExporter( + encode=_encode_logs_to_dict, + kind="logs", + logger=_logger, + path=path, + stream=stream, + ) + + def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: + return LogRecordExportResult.SUCCESS if self._exporter.export(batch) else LogRecordExportResult.FAILURE + + def shutdown(self) -> None: + self._exporter.shutdown() + + # pylint: disable-next=no-self-use + def force_flush(self, timeout_millis: int = 10_000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py new file mode 100644 index 00000000000..1ce97ace535 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py @@ -0,0 +1,94 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os +from typing import IO, Any, overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._aggregation import ( + _get_aggregation, + _get_temporality, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common.metrics_encoder import ( + encode_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._internal import _FileExporter +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + AggregationTemporality, + MetricExporter, + MetricExportResult, + MetricsData, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import Aggregation + +_logger = logging.getLogger(__name__) + + +def _encode_metrics_to_dict( + metrics_data: MetricsData, +) -> dict[str, Any] | None: + data = encode_metrics(metrics_data) + return data.to_dict() if data.resource_metrics else None + + +class FileMetricExporter(MetricExporter): + @overload + def __init__( + self, + path: str | os.PathLike[str], + *, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + ) -> None: ... + + @overload + def __init__( + self, + *, + stream: IO[str], + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + ) -> None: ... + + @overload + def __init__( + self, + *, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + ) -> None: ... + + def __init__( + self, + path: str | os.PathLike[str] | None = None, + *, + stream: IO[str] | None = None, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + ) -> None: + MetricExporter.__init__( + self, + preferred_temporality=_get_temporality(preferred_temporality), + preferred_aggregation=_get_aggregation(preferred_aggregation), + ) + self._exporter: _FileExporter[MetricsData] = _FileExporter( + encode=_encode_metrics_to_dict, + kind="metrics", + logger=_logger, + path=path, + stream=stream, + ) + + def export( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> MetricExportResult: + return MetricExportResult.SUCCESS if self._exporter.export(metrics_data) else MetricExportResult.FAILURE + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + self._exporter.shutdown() + + def force_flush(self, timeout_millis: float = 10_000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py new file mode 100644 index 00000000000..f3bcb567097 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py @@ -0,0 +1,64 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os +from collections.abc import Sequence +from typing import IO, Any, overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common.trace_encoder import encode_spans +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._internal import _FileExporter +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult + +_logger = logging.getLogger(__name__) + + +def _encode_spans_to_dict( + spans: Sequence[ReadableSpan], +) -> dict[str, Any] | None: + data = encode_spans(spans) + return data.to_dict() if data.resource_spans else None + + +class FileSpanExporter(SpanExporter): + @overload + def __init__( + self, + path: str | os.PathLike[str], + ) -> None: ... + + @overload + def __init__( + self, + *, + stream: IO[str], + ) -> None: ... + + @overload + def __init__( + self, + ) -> None: ... + + def __init__( + self, + path: str | os.PathLike[str] | None = None, + *, + stream: IO[str] | None = None, + ) -> None: + self._exporter: _FileExporter[Sequence[ReadableSpan]] = _FileExporter( + encode=_encode_spans_to_dict, + kind="spans", + logger=_logger, + path=path, + stream=stream, + ) + + def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: + return SpanExportResult.SUCCESS if self._exporter.export(spans) else SpanExportResult.FAILURE + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + self._exporter.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py new file mode 100644 index 00000000000..3c2993f3b19 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py @@ -0,0 +1,79 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +This library allows exporting OpenTelemetry telemetry using the OTLP JSON +over HTTP wire format to any backend that accepts OTLP JSON. + +Usage +----- + +The **OTLP JSON HTTP Exporter** exports `OpenTelemetry`_ traces, metrics, +and logs via HTTP to any `OTLP`_-compatible backend using OTLP JSON +encoding instead of protobuf. + +Three exporters are provided: + +- :class:`~opentelemetry.exporter.otlp.json.http.trace_exporter.OTLPSpanExporter` - traces +- :class:`~opentelemetry.exporter.otlp.json.http.metric_exporter.OTLPMetricExporter` - metrics +- :class:`~opentelemetry.exporter.otlp.json.http._log_exporter.OTLPLogExporter` - logs + +You can configure each exporter with the following environment variables, +using the appropriate per-signal prefix (``TRACES``, ``METRICS``, or +``LOGS``) or the generic variant that applies to all three: + +- :envvar:`OTEL_EXPORTER_OTLP_ENDPOINT` +- :envvar:`OTEL_EXPORTER_OTLP_HEADERS` +- :envvar:`OTEL_EXPORTER_OTLP_TIMEOUT` +- :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` +- :envvar:`OTEL_EXPORTER_OTLP_CERTIFICATE` +- :envvar:`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` +- :envvar:`OTEL_EXPORTER_OTLP_CLIENT_KEY` + +The metric exporter also supports the following environment variables: + +- :envvar:`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` +- :envvar:`OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` + +.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/ +.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ + +.. code:: python + + from opentelemetry import trace + from opentelemetry.exporter.otlp.json.http import OTLPSpanExporter + from opentelemetry.sdk.resources import Resource + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchSpanProcessor + + resource = Resource.create({ + "service.name": "service" + }) + + trace.set_tracer_provider(TracerProvider(resource=resource)) + tracer = trace.get_tracer(__name__) + + otlp_exporter = OTLPSpanExporter() + + span_processor = BatchSpanProcessor(otlp_exporter) + + trace.get_tracer_provider().add_span_processor(span_processor) + + with tracer.start_as_current_span("foo"): + print("Hello world!") + +API +--- +""" + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.metric_exporter import ( + OTLPMetricExporter, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.trace_exporter import ( + OTLPSpanExporter, +) + +__all__ = [ + "OTLPMetricExporter", + "OTLPSpanExporter", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py new file mode 100644 index 00000000000..942df502545 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py @@ -0,0 +1,137 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +import os +from collections.abc import Mapping +from typing import TYPE_CHECKING, Literal + +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._urllib3 import Urllib3HTTPTransport +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import Compression +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.version import __version__ +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, + OTEL_EXPORTER_OTLP_COMPRESSION, + OTEL_EXPORTER_OTLP_ENDPOINT, + OTEL_EXPORTER_OTLP_HEADERS, + OTEL_EXPORTER_OTLP_TIMEOUT, +) +from opentelemetry.agent._vendor.opentelemetry.util.re import parse_env_headers + +if TYPE_CHECKING: + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport import BaseHTTPTransportFactory + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport + +_DEFAULT_ENDPOINT = "http://localhost:4318" +_DEFAULT_TIMEOUT = 10 + +_logger = logging.getLogger(__name__) + + +def _resolve_endpoint( + endpoint_env_var: str, + default_path: Literal["v1/traces", "v1/metrics", "v1/logs"], +) -> str: + if endpoint := os.environ.get(endpoint_env_var): + return endpoint + + base_endpoint = os.environ.get(OTEL_EXPORTER_OTLP_ENDPOINT) or _DEFAULT_ENDPOINT + + return f"{base_endpoint.removesuffix('/')}/{default_path}" + + +def _resolve_headers( + headers: Mapping[str, str] | None, + headers_env_var: str, +) -> dict[str, str]: + headers_ = { + "content-type": "application/json", + "user-agent": "OTel-OTLP-JSON-Exporter-Python/" + __version__, + } + env_headers = parse_env_headers( + os.environ.get(headers_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), + liberal=True, + ) + headers_.update(env_headers) + if headers: + headers_.update({key.lower(): value for key, value in headers.items()}) + return headers_ + + +def _resolve_timeout( + timeout_env_var: str, +) -> float: + raw = os.environ.get(timeout_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_TIMEOUT) or _DEFAULT_TIMEOUT + + try: + return float(raw) + except ValueError: + _logger.warning( + "Invalid timeout value %r, using default of %s seconds", + raw, + _DEFAULT_TIMEOUT, + ) + return float(_DEFAULT_TIMEOUT) + + +def _resolve_compression(compression_env_var: str) -> Compression: + val = ( + ( + os.environ.get( + compression_env_var, + ) + or os.environ.get(OTEL_EXPORTER_OTLP_COMPRESSION) + or "none" + ) + .lower() + .strip() + ) + + try: + return Compression.from_str(val) + except ValueError: + _logger.warning("Unsupported compression type: %s", val) + return Compression.NONE + + +def _build_transport( + certificate_file: str | None, + client_key_file: str | None, + client_certificate_file: str | None, + certificate_env_var: str, + client_key_env_var: str, + client_certificate_env_var: str, + transport_factory: BaseHTTPTransportFactory = Urllib3HTTPTransport, +) -> BaseHTTPTransport: + verify: bool | str = ( + certificate_file + or os.environ.get( + certificate_env_var, + ) + or os.environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE) + or True + ) + client_key_file = ( + client_key_file + or os.environ.get( + client_key_env_var, + ) + or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_KEY) + ) + client_certificate_file = ( + client_certificate_file + or os.environ.get( + client_certificate_env_var, + ) + or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE) + ) + return transport_factory( + verify=verify, + cert=(client_certificate_file, client_key_file) + if client_certificate_file and client_key_file + else client_certificate_file, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py new file mode 100644 index 00000000000..9c30db2074c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py @@ -0,0 +1,134 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +from collections.abc import Mapping, Sequence +from typing import overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import ( + Compression, + _OTLPHTTPClient, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal._log_encoder import ( + encode_logs, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._internal import ( + _build_transport, + _resolve_compression, + _resolve_endpoint, + _resolve_headers, + _resolve_timeout, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord +from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( + LogRecordExporter, + LogRecordExportResult, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import DuplicateFilter +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, + OTEL_EXPORTER_OTLP_LOGS_HEADERS, + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, +) + +_DEFAULT_LOGS_EXPORT_PATH = "v1/logs" + +_logger = logging.getLogger(__name__) +_logger.addFilter(DuplicateFilter()) + + +class OTLPLogExporter(LogRecordExporter): + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + ) -> None: ... + + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: None = None, + client_key_file: None = None, + client_certificate_file: None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + *, + _transport: BaseHTTPTransport, + ) -> None: ... + + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + *, + _transport: BaseHTTPTransport | None = None, + ) -> None: + """OTLP HTTP JSON log exporter. + + Args: + endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal + path. Example: ``http://collector:4318/v1/logs``. For a base URL without a + signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. + """ + transport = _transport or _build_transport( + certificate_file, + client_key_file, + client_certificate_file, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + ) + self._client = _OTLPHTTPClient( + transport=transport, + endpoint=endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, _DEFAULT_LOGS_EXPORT_PATH), + kind="logs", + timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT), + compression=compression + if compression is not None + else _resolve_compression(OTEL_EXPORTER_OTLP_LOGS_COMPRESSION), + headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_LOGS_HEADERS), + logger=_logger, + ) + self._shutdown = False + + def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring batch") + return LogRecordExportResult.FAILURE + try: + body = encode_logs(batch).to_json().encode() + # pylint: disable-next=broad-exception-caught + except Exception as error: + _logger.error("Failed to encode logs: %s", error) + return LogRecordExportResult.FAILURE + export_result = self._client.export(body) + return LogRecordExportResult.SUCCESS if export_result.success else LogRecordExportResult.FAILURE + + def shutdown(self) -> None: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring call") + return + self._shutdown = True + self._client.shutdown() + + # pylint: disable-next=no-self-use + def force_flush(self, timeout_millis: int = 10_000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py new file mode 100644 index 00000000000..f8de6408261 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py @@ -0,0 +1,165 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +from collections.abc import Mapping +from typing import overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._aggregation import ( + _get_aggregation, + _get_temporality, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import ( + Compression, + _OTLPHTTPClient, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.metrics_encoder import ( + encode_metrics, + split_metrics_data, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._internal import ( + _build_transport, + _resolve_compression, + _resolve_endpoint, + _resolve_headers, + _resolve_timeout, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, + OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, + OTEL_EXPORTER_OTLP_METRICS_HEADERS, + OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + AggregationTemporality, + MetricExporter, + MetricExportResult, + MetricsData, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import Aggregation + +_DEFAULT_METRICS_EXPORT_PATH = "v1/metrics" + +_logger = logging.getLogger(__name__) + + +class OTLPMetricExporter(MetricExporter): + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + max_export_batch_size: int | None = None, + ) -> None: ... + + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: None = None, + client_key_file: None = None, + client_certificate_file: None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + max_export_batch_size: int | None = None, + *, + _transport: BaseHTTPTransport, + ) -> None: ... + + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + max_export_batch_size: int | None = None, + *, + _transport: BaseHTTPTransport | None = None, + ) -> None: + """OTLP HTTP JSON metric exporter. + + Args: + endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal + path. Example: ``http://collector:4318/v1/metrics``. For a base URL without a + signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. + """ + MetricExporter.__init__( + self, + preferred_temporality=_get_temporality(preferred_temporality), + preferred_aggregation=_get_aggregation(preferred_aggregation), + ) + transport = _transport or _build_transport( + certificate_file, + client_key_file, + client_certificate_file, + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + ) + self._client = _OTLPHTTPClient( + transport=transport, + endpoint=endpoint + or _resolve_endpoint( + OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, + _DEFAULT_METRICS_EXPORT_PATH, + ), + kind="metrics", + timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_METRICS_TIMEOUT), + compression=compression + if compression is not None + else _resolve_compression(OTEL_EXPORTER_OTLP_METRICS_COMPRESSION), + headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_METRICS_HEADERS), + logger=_logger, + ) + self._max_export_batch_size = max_export_batch_size + self._shutdown = False + + def export( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> MetricExportResult: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring batch") + return MetricExportResult.FAILURE + try: + export_request = encode_metrics(metrics_data) + # pylint: disable-next=broad-exception-caught + except Exception as error: + _logger.error("Failed to encode metrics: %s", error) + return MetricExportResult.FAILURE + for request in split_metrics_data(export_request, self._max_export_batch_size): + export_result = self._client.export(request.to_json().encode()) + if not export_result.success: + return MetricExportResult.FAILURE + return MetricExportResult.SUCCESS + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring call") + return + self._shutdown = True + self._client.shutdown() + + def force_flush(self, timeout_millis: float = 10_000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py new file mode 100644 index 00000000000..3477ba4b27c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py @@ -0,0 +1,128 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +from collections.abc import Mapping, Sequence +from typing import overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import ( + Compression, + _OTLPHTTPClient, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.trace_encoder import ( + encode_spans, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._internal import ( + _build_transport, + _resolve_compression, + _resolve_endpoint, + _resolve_headers, + _resolve_timeout, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, + OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, + OTEL_EXPORTER_OTLP_TRACES_HEADERS, + OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult + +_DEFAULT_TRACES_EXPORT_PATH = "v1/traces" + +_logger = logging.getLogger(__name__) + + +class OTLPSpanExporter(SpanExporter): + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + ) -> None: ... + + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: None = None, + client_key_file: None = None, + client_certificate_file: None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + *, + _transport: BaseHTTPTransport, + ) -> None: ... + + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | None = None, + *, + _transport: BaseHTTPTransport | None = None, + ) -> None: + """OTLP HTTP JSON span exporter. + + Args: + endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal + path. Example: ``http://collector:4318/v1/traces``. For a base URL without a + signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. + """ + transport = _transport or _build_transport( + certificate_file, + client_key_file, + client_certificate_file, + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + ) + self._client = _OTLPHTTPClient( + transport=transport, + endpoint=endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, _DEFAULT_TRACES_EXPORT_PATH), + kind="spans", + timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT), + compression=compression + if compression is not None + else _resolve_compression(OTEL_EXPORTER_OTLP_TRACES_COMPRESSION), + headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_TRACES_HEADERS), + logger=_logger, + ) + self._shutdown = False + + def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring batch") + return SpanExportResult.FAILURE + try: + body = encode_spans(spans).to_json().encode() + # pylint: disable-next=broad-exception-caught + except Exception as error: + _logger.error("Failed to encode spans: %s", error) + return SpanExportResult.FAILURE + export_result = self._client.export(body) + return SpanExportResult.SUCCESS if export_result.success else SpanExportResult.FAILURE + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring call") + return + self._shutdown = True + self._client.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py new file mode 100644 index 00000000000..ca87bc042d2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py @@ -0,0 +1,7 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common.version import __version__ + +__all__ = ["__version__"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py new file mode 100644 index 00000000000..fdeeabddd2a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py @@ -0,0 +1,121 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from __future__ import annotations + +import logging +from collections.abc import Callable, Mapping, Sequence +from typing import ( + Any, + TypeVar, +) + +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import AnyValue as PB2AnyValue +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( + ArrayValue as PB2ArrayValue, +) +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( + InstrumentationScope as PB2InstrumentationScope, +) +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import KeyValue as PB2KeyValue +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( + KeyValueList as PB2KeyValueList, +) +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( + Resource as PB2Resource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +_logger = logging.getLogger(__name__) + +_TypingResourceT = TypeVar("_TypingResourceT") +_ResourceDataT = TypeVar("_ResourceDataT") + + +def _encode_instrumentation_scope( + instrumentation_scope: InstrumentationScope, +) -> PB2InstrumentationScope: + if instrumentation_scope is None: + return PB2InstrumentationScope() + return PB2InstrumentationScope( + name=instrumentation_scope.name, + version=instrumentation_scope.version, + attributes=_encode_attributes(instrumentation_scope.attributes), + ) + + +def _encode_resource(resource: Resource) -> PB2Resource: + return PB2Resource(attributes=_encode_attributes(resource.attributes)) + + +def _encode_value(value: Any) -> PB2AnyValue: + if value is None: + return PB2AnyValue() + if isinstance(value, bool): + return PB2AnyValue(bool_value=value) + if isinstance(value, str): + return PB2AnyValue(string_value=value) + if isinstance(value, int): + return PB2AnyValue(int_value=value) + if isinstance(value, float): + return PB2AnyValue(double_value=value) + if isinstance(value, bytes): + return PB2AnyValue(bytes_value=value) + if isinstance(value, Sequence): + return PB2AnyValue(array_value=PB2ArrayValue(values=[_encode_value(v) for v in value])) + if isinstance(value, Mapping): + return PB2AnyValue( + kvlist_value=PB2KeyValueList(values=[_encode_key_value(str(k), v) for k, v in value.items()]) + ) + raise Exception(f"Invalid type {type(value)} of value {value}") + + +def _encode_key_value(key: str, value: Any) -> PB2KeyValue: + return PB2KeyValue(key=key, value=_encode_value(value)) + + +def _encode_span_id(span_id: int) -> bytes: + return span_id.to_bytes(length=8, byteorder="big", signed=False) + + +def _encode_trace_id(trace_id: int) -> bytes: + return trace_id.to_bytes(length=16, byteorder="big", signed=False) + + +def _encode_attributes(attributes: Attributes) -> list[PB2KeyValue]: + if not attributes: + return [] + pb2_attributes = [] + for key, value in attributes.items(): + # pylint: disable=broad-exception-caught + try: + pb2_attributes.append(_encode_key_value(key, value)) + except Exception as error: + _logger.exception("Failed to encode key %s: %s", key, error) + return pb2_attributes + + +def _get_resource_data( + sdk_resource_scope_data: dict[Resource, _ResourceDataT], + resource_class: Callable[..., _TypingResourceT], + name: str, +) -> list[_TypingResourceT]: + resource_data = [] + + for ( + sdk_resource, + scope_data, + ) in sdk_resource_scope_data.items(): + collector_resource = PB2Resource(attributes=_encode_attributes(sdk_resource.attributes)) + resource_data.append( + resource_class( + **{ + "resource": collector_resource, + f"scope_{name}": scope_data.values(), + } + ) + ) + return resource_data diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py new file mode 100644 index 00000000000..3a8e30c78f6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py @@ -0,0 +1,87 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from collections import defaultdict +from collections.abc import Sequence + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( + _encode_attributes, + _encode_instrumentation_scope, + _encode_resource, + _encode_span_id, + _encode_trace_id, + _encode_value, +) +from opentelemetry.agent._vendor.opentelemetry.proto.collector.logs.v1.logs_service_pb2 import ( + ExportLogsServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto.logs.v1.logs_pb2 import LogRecord as PB2LogRecord +from opentelemetry.agent._vendor.opentelemetry.proto.logs.v1.logs_pb2 import ( + ResourceLogs, + ScopeLogs, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord + + +def encode_logs( + batch: Sequence[ReadableLogRecord], +) -> ExportLogsServiceRequest: + return ExportLogsServiceRequest(resource_logs=_encode_resource_logs(batch)) + + +def _encode_log(readable_log_record: ReadableLogRecord) -> PB2LogRecord: + span_id = ( + None if readable_log_record.log_record.span_id == 0 else _encode_span_id(readable_log_record.log_record.span_id) + ) + trace_id = ( + None + if readable_log_record.log_record.trace_id == 0 + else _encode_trace_id(readable_log_record.log_record.trace_id) + ) + return PB2LogRecord( + time_unix_nano=readable_log_record.log_record.timestamp, + observed_time_unix_nano=readable_log_record.log_record.observed_timestamp, + span_id=span_id, + trace_id=trace_id, + flags=int(readable_log_record.log_record.trace_flags), + body=_encode_value(readable_log_record.log_record.body), + severity_text=readable_log_record.log_record.severity_text, + attributes=_encode_attributes(readable_log_record.log_record.attributes), + dropped_attributes_count=readable_log_record.dropped_attributes, + severity_number=getattr(readable_log_record.log_record.severity_number, "value", None), + event_name=readable_log_record.log_record.event_name, + ) + + +def _encode_resource_logs( + batch: Sequence[ReadableLogRecord], +) -> list[ResourceLogs]: + sdk_resource_logs = defaultdict(lambda: defaultdict(list)) + + for readable_log in batch: + sdk_resource = readable_log.resource + sdk_instrumentation = readable_log.instrumentation_scope or None + pb2_log = _encode_log(readable_log) + + sdk_resource_logs[sdk_resource][sdk_instrumentation].append(pb2_log) + + pb2_resource_logs = [] + + for sdk_resource, sdk_instrumentations in sdk_resource_logs.items(): + scope_logs = [] + for sdk_instrumentation, pb2_logs in sdk_instrumentations.items(): + scope_logs.append( + ScopeLogs( + scope=(_encode_instrumentation_scope(sdk_instrumentation)), + log_records=pb2_logs, + schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, + ) + ) + pb2_resource_logs.append( + ResourceLogs( + resource=_encode_resource(sdk_resource), + scope_logs=scope_logs, + schema_url=sdk_resource.schema_url, + ) + ) + + return pb2_resource_logs diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py new file mode 100644 index 00000000000..378efb6d8b8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py @@ -0,0 +1,348 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import logging +from os import environ + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( + _encode_attributes, + _encode_instrumentation_scope, + _encode_span_id, + _encode_trace_id, +) +from opentelemetry.agent._vendor.opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( + ExportMetricsServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2 +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( + Resource as PB2Resource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( + Counter, + Exemplar, + Histogram, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + AggregationTemporality, + Gauge, + MetricExporter, + MetricsData, + Sum, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + ExponentialHistogram as ExponentialHistogramType, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + Histogram as HistogramType, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import ( + Aggregation, + ExplicitBucketHistogramAggregation, + ExponentialBucketHistogramAggregation, +) + +_logger = logging.getLogger(__name__) + + +class OTLPMetricExporterMixin: + def _common_configuration( + self, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + ) -> None: + MetricExporter.__init__( + self, + preferred_temporality=self._get_temporality(preferred_temporality), + preferred_aggregation=self._get_aggregation(preferred_aggregation), + ) + + def _get_temporality( + self, preferred_temporality: dict[type, AggregationTemporality] + ) -> dict[type, AggregationTemporality]: + otel_exporter_otlp_metrics_temporality_preference = ( + environ.get( + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, + "CUMULATIVE", + ) + .upper() + .strip() + ) + + if otel_exporter_otlp_metrics_temporality_preference == "DELTA": + instrument_class_temporality = { + Counter: AggregationTemporality.DELTA, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.DELTA, + ObservableCounter: AggregationTemporality.DELTA, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + + elif otel_exporter_otlp_metrics_temporality_preference == "LOWMEMORY": + instrument_class_temporality = { + Counter: AggregationTemporality.DELTA, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.DELTA, + ObservableCounter: AggregationTemporality.CUMULATIVE, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + + else: + if otel_exporter_otlp_metrics_temporality_preference != ("CUMULATIVE"): + _logger.warning( + "Unrecognized OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE value found: %s, using CUMULATIVE", + otel_exporter_otlp_metrics_temporality_preference, + ) + instrument_class_temporality = { + Counter: AggregationTemporality.CUMULATIVE, + UpDownCounter: AggregationTemporality.CUMULATIVE, + Histogram: AggregationTemporality.CUMULATIVE, + ObservableCounter: AggregationTemporality.CUMULATIVE, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + } + + instrument_class_temporality.update(preferred_temporality or {}) + + return instrument_class_temporality + + def _get_aggregation( + self, + preferred_aggregation: dict[type, Aggregation], + ) -> dict[type, Aggregation]: + otel_exporter_otlp_metrics_default_histogram_aggregation = environ.get( + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, + "explicit_bucket_histogram", + ) + + if otel_exporter_otlp_metrics_default_histogram_aggregation == ("base2_exponential_bucket_histogram"): + instrument_class_aggregation = { + Histogram: ExponentialBucketHistogramAggregation(), + } + + else: + if otel_exporter_otlp_metrics_default_histogram_aggregation != ("explicit_bucket_histogram"): + _logger.warning( + ("Invalid value for %s: %s, using explicit bucket histogram aggregation"), + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, + otel_exporter_otlp_metrics_default_histogram_aggregation, + ) + + instrument_class_aggregation = { + Histogram: ExplicitBucketHistogramAggregation(), + } + + instrument_class_aggregation.update(preferred_aggregation or {}) + + return instrument_class_aggregation + + +class EncodingException(Exception): + """ + Raised by encode_metrics() when an exception is caught during encoding. Contains the problematic metric so + the misbehaving metric name and details can be logged during exception handling. + """ + + def __init__(self, original_exception, metric): + super().__init__() + self.original_exception = original_exception + self.metric = metric + + def __str__(self): + return f"{self.metric}\n{self.original_exception}" + + +def encode_metrics(data: MetricsData) -> ExportMetricsServiceRequest: + resource_metrics_dict = {} + + for resource_metrics in data.resource_metrics: + _encode_resource_metrics(resource_metrics, resource_metrics_dict) + + resource_data = [] + for ( + sdk_resource, + scope_data, + ) in resource_metrics_dict.items(): + resource_data.append( + pb2.ResourceMetrics( + resource=PB2Resource(attributes=_encode_attributes(sdk_resource.attributes)), + scope_metrics=scope_data.values(), + schema_url=sdk_resource.schema_url, + ) + ) + return ExportMetricsServiceRequest(resource_metrics=resource_data) + + +def _encode_resource_metrics(resource_metrics, resource_metrics_dict): + resource = resource_metrics.resource + # It is safe to assume that each entry in data.resource_metrics is + # associated with an unique resource. + scope_metrics_dict = {} + resource_metrics_dict[resource] = scope_metrics_dict + for scope_metrics in resource_metrics.scope_metrics: + instrumentation_scope = scope_metrics.scope + + # The SDK groups metrics in instrumentation scopes already so + # there is no need to check for existing instrumentation scopes + # here. + pb2_scope_metrics = pb2.ScopeMetrics( + scope=_encode_instrumentation_scope(instrumentation_scope), + schema_url=instrumentation_scope.schema_url, + ) + + scope_metrics_dict[instrumentation_scope] = pb2_scope_metrics + + for metric in scope_metrics.metrics: + pb2_metric = pb2.Metric( + name=metric.name, + description=metric.description, + unit=metric.unit, + ) + + try: + _encode_metric(metric, pb2_metric) + except Exception as ex: + # `from None` so we don't get "During handling of the above exception, another exception occurred:" + raise EncodingException(ex, metric) from None + + pb2_scope_metrics.metrics.append(pb2_metric) + + +def _encode_metric(metric, pb2_metric): + if isinstance(metric.data, Gauge): + for data_point in metric.data.data_points: + pt = pb2.NumberDataPoint( + attributes=_encode_attributes(data_point.attributes), + time_unix_nano=data_point.time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + ) + if isinstance(data_point.value, int): + pt.as_int = data_point.value + else: + pt.as_double = data_point.value + pb2_metric.gauge.data_points.append(pt) + + elif isinstance(metric.data, HistogramType): + for data_point in metric.data.data_points: + pt = pb2.HistogramDataPoint( + attributes=_encode_attributes(data_point.attributes), + time_unix_nano=data_point.time_unix_nano, + start_time_unix_nano=data_point.start_time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + count=data_point.count, + sum=data_point.sum, + bucket_counts=data_point.bucket_counts, + explicit_bounds=data_point.explicit_bounds, + max=data_point.max, + min=data_point.min, + ) + pb2_metric.histogram.aggregation_temporality = metric.data.aggregation_temporality + pb2_metric.histogram.data_points.append(pt) + + elif isinstance(metric.data, Sum): + for data_point in metric.data.data_points: + pt = pb2.NumberDataPoint( + attributes=_encode_attributes(data_point.attributes), + start_time_unix_nano=data_point.start_time_unix_nano, + time_unix_nano=data_point.time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + ) + if isinstance(data_point.value, int): + pt.as_int = data_point.value + else: + pt.as_double = data_point.value + # note that because sum is a message type, the + # fields must be set individually rather than + # instantiating a pb2.Sum and setting it once + pb2_metric.sum.aggregation_temporality = metric.data.aggregation_temporality + pb2_metric.sum.is_monotonic = metric.data.is_monotonic + pb2_metric.sum.data_points.append(pt) + + elif isinstance(metric.data, ExponentialHistogramType): + for data_point in metric.data.data_points: + if data_point.positive.bucket_counts: + positive = pb2.ExponentialHistogramDataPoint.Buckets( + offset=data_point.positive.offset, + bucket_counts=data_point.positive.bucket_counts, + ) + else: + positive = None + + if data_point.negative.bucket_counts: + negative = pb2.ExponentialHistogramDataPoint.Buckets( + offset=data_point.negative.offset, + bucket_counts=data_point.negative.bucket_counts, + ) + else: + negative = None + + pt = pb2.ExponentialHistogramDataPoint( + attributes=_encode_attributes(data_point.attributes), + time_unix_nano=data_point.time_unix_nano, + start_time_unix_nano=data_point.start_time_unix_nano, + exemplars=_encode_exemplars(data_point.exemplars), + count=data_point.count, + sum=data_point.sum, + scale=data_point.scale, + zero_count=data_point.zero_count, + positive=positive, + negative=negative, + flags=data_point.flags, + max=data_point.max, + min=data_point.min, + ) + pb2_metric.exponential_histogram.aggregation_temporality = metric.data.aggregation_temporality + pb2_metric.exponential_histogram.data_points.append(pt) + + else: + _logger.warning( + "unsupported data type %s", + metric.data.__class__.__name__, + ) + + +def _encode_exemplars(sdk_exemplars: list[Exemplar]) -> list[pb2.Exemplar]: + """ + Converts a list of SDK Exemplars into a list of protobuf Exemplars. + + Args: + sdk_exemplars (list): The list of exemplars from the OpenTelemetry SDK. + + Returns: + list: A list of protobuf exemplars. + """ + pb_exemplars = [] + for sdk_exemplar in sdk_exemplars: + if sdk_exemplar.span_id is not None and sdk_exemplar.trace_id is not None: + pb_exemplar = pb2.Exemplar( + time_unix_nano=sdk_exemplar.time_unix_nano, + span_id=_encode_span_id(sdk_exemplar.span_id), + trace_id=_encode_trace_id(sdk_exemplar.trace_id), + filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), + ) + else: + pb_exemplar = pb2.Exemplar( + time_unix_nano=sdk_exemplar.time_unix_nano, + filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), + ) + + # Assign the value based on its type in the SDK exemplar + if isinstance(sdk_exemplar.value, float): + pb_exemplar.as_double = sdk_exemplar.value + elif isinstance(sdk_exemplar.value, int): + pb_exemplar.as_int = sdk_exemplar.value + else: + raise ValueError("Exemplar value must be an int or float") + pb_exemplars.append(pb_exemplar) + + return pb_exemplars diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py new file mode 100644 index 00000000000..48bdb23bf34 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py @@ -0,0 +1,175 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +from collections import defaultdict +from collections.abc import Sequence + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( + _encode_attributes, + _encode_instrumentation_scope, + _encode_resource, + _encode_span_id, + _encode_trace_id, +) +from opentelemetry.agent._vendor.opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ( + ExportTraceServiceRequest as PB2ExportTraceServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( + ResourceSpans as PB2ResourceSpans, +) +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ScopeSpans as PB2ScopeSpans +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import Span as PB2SPan +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import SpanFlags as PB2SpanFlags +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import Status as PB2Status +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Event, ReadableSpan +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind +from opentelemetry.agent._vendor.opentelemetry.trace.span import SpanContext, Status, TraceState + +# pylint: disable=E1101 +_SPAN_KIND_MAP = { + SpanKind.INTERNAL: PB2SPan.SpanKind.SPAN_KIND_INTERNAL, + SpanKind.SERVER: PB2SPan.SpanKind.SPAN_KIND_SERVER, + SpanKind.CLIENT: PB2SPan.SpanKind.SPAN_KIND_CLIENT, + SpanKind.PRODUCER: PB2SPan.SpanKind.SPAN_KIND_PRODUCER, + SpanKind.CONSUMER: PB2SPan.SpanKind.SPAN_KIND_CONSUMER, +} + +_logger = logging.getLogger(__name__) + + +def encode_spans( + sdk_spans: Sequence[ReadableSpan], +) -> PB2ExportTraceServiceRequest: + return PB2ExportTraceServiceRequest(resource_spans=_encode_resource_spans(sdk_spans)) + + +def _encode_resource_spans( + sdk_spans: Sequence[ReadableSpan], +) -> list[PB2ResourceSpans]: + # We need to inspect the spans and group + structure them as: + # + # Resource + # Instrumentation Library + # Spans + # + # First loop organizes the SDK spans in this structure. Protobuf messages + # are not hashable so we stick with SDK data in this phase. + # + # Second loop encodes the data into Protobuf format. + # + sdk_resource_spans = defaultdict(lambda: defaultdict(list)) + + for sdk_span in sdk_spans: + sdk_resource = sdk_span.resource + sdk_instrumentation = sdk_span.instrumentation_scope or None + pb2_span = _encode_span(sdk_span) + + sdk_resource_spans[sdk_resource][sdk_instrumentation].append(pb2_span) + + pb2_resource_spans = [] + + for sdk_resource, sdk_instrumentations in sdk_resource_spans.items(): + scope_spans = [] + for sdk_instrumentation, pb2_spans in sdk_instrumentations.items(): + scope_spans.append( + PB2ScopeSpans( + scope=(_encode_instrumentation_scope(sdk_instrumentation)), + spans=pb2_spans, + schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, + ) + ) + pb2_resource_spans.append( + PB2ResourceSpans( + resource=_encode_resource(sdk_resource), + scope_spans=scope_spans, + schema_url=sdk_resource.schema_url, + ) + ) + + return pb2_resource_spans + + +def _span_flags(parent_span_context: SpanContext | None) -> int: + flags = PB2SpanFlags.SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK + if parent_span_context and parent_span_context.is_remote: + flags |= PB2SpanFlags.SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK + return flags + + +def _encode_span(sdk_span: ReadableSpan) -> PB2SPan: + span_context = sdk_span.get_span_context() + return PB2SPan( + trace_id=_encode_trace_id(span_context.trace_id), + span_id=_encode_span_id(span_context.span_id), + trace_state=_encode_trace_state(span_context.trace_state), + parent_span_id=_encode_parent_id(sdk_span.parent), + name=sdk_span.name, + kind=_SPAN_KIND_MAP[sdk_span.kind], + start_time_unix_nano=sdk_span.start_time, + end_time_unix_nano=sdk_span.end_time, + attributes=_encode_attributes(sdk_span.attributes), + events=_encode_events(sdk_span.events), + links=_encode_links(sdk_span.links), + status=_encode_status(sdk_span.status), + dropped_attributes_count=sdk_span.dropped_attributes, + dropped_events_count=sdk_span.dropped_events, + dropped_links_count=sdk_span.dropped_links, + flags=_span_flags(sdk_span.parent), + ) + + +def _encode_events( + events: Sequence[Event], +) -> list[PB2SPan.Event] | None: + pb2_events = None + if events: + pb2_events = [] + for event in events: + encoded_event = PB2SPan.Event( + name=event.name, + time_unix_nano=event.timestamp, + attributes=_encode_attributes(event.attributes), + dropped_attributes_count=event.dropped_attributes, + ) + pb2_events.append(encoded_event) + return pb2_events + + +def _encode_links(links: Sequence[Link]) -> Sequence[PB2SPan.Link]: + pb2_links = None + if links: + pb2_links = [] + for link in links: + encoded_link = PB2SPan.Link( + trace_id=_encode_trace_id(link.context.trace_id), + span_id=_encode_span_id(link.context.span_id), + attributes=_encode_attributes(link.attributes), + dropped_attributes_count=link.dropped_attributes, + flags=_span_flags(link.context), + ) + pb2_links.append(encoded_link) + return pb2_links + + +def _encode_status(status: Status) -> PB2Status | None: + pb2_status = None + if status is not None: + pb2_status = PB2Status( + code=status.status_code.value, + message=status.description, + ) + return pb2_status + + +def _encode_trace_state(trace_state: TraceState) -> str | None: + pb2_trace_state = None + if trace_state is not None: + pb2_trace_state = ",".join([f"{key}={value}" for key, value in (trace_state.items())]) + return pb2_trace_state + + +def _encode_parent_id(context: SpanContext | None) -> bytes | None: + if context: + return _encode_span_id(context.span_id) + return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py new file mode 100644 index 00000000000..51463b90b19 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal._log_encoder import ( + encode_logs, +) + +__all__ = ["encode_logs"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py new file mode 100644 index 00000000000..79bd0d4d27a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal.metrics_encoder import ( + encode_metrics, +) + +__all__ = ["encode_metrics"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py new file mode 100644 index 00000000000..b8b5b90024d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal.trace_encoder import ( + encode_spans, +) + +__all__ = ["encode_spans"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py new file mode 100644 index 00000000000..0101c361616 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py new file mode 100644 index 00000000000..69f51ec0557 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py @@ -0,0 +1,75 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +""" +This library allows to export tracing data to an OTLP collector. + +Usage +----- + +The **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the +`OTLP`_ collector. + +You can configure the exporter with the following environment variables: + +- :envvar:`OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` +- :envvar:`OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` +- :envvar:`OTEL_EXPORTER_OTLP_TRACES_HEADERS` +- :envvar:`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` +- :envvar:`OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` +- :envvar:`OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` +- :envvar:`OTEL_EXPORTER_OTLP_TIMEOUT` +- :envvar:`OTEL_EXPORTER_OTLP_PROTOCOL` +- :envvar:`OTEL_EXPORTER_OTLP_HEADERS` +- :envvar:`OTEL_EXPORTER_OTLP_ENDPOINT` +- :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` +- :envvar:`OTEL_EXPORTER_OTLP_CERTIFICATE` + +.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/ +.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ + +.. code:: python + + from opentelemetry import trace + from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter + from opentelemetry.sdk.resources import Resource + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchSpanProcessor + + # Resource can be required for some backends, e.g. Jaeger + # If resource wouldn't be set - traces wouldn't appears in Jaeger + resource = Resource.create({ + "service.name": "service" + }) + + trace.set_tracer_provider(TracerProvider(resource=resource)) + tracer = trace.get_tracer(__name__) + + otlp_exporter = OTLPSpanExporter() + + span_processor = BatchSpanProcessor(otlp_exporter) + + trace.get_tracer_provider().add_span_processor(span_processor) + + with tracer.start_as_current_span("foo"): + print("Hello world!") + +API +--- +""" + +import enum + +from .version import __version__ + +_OTLP_HTTP_HEADERS = { + "Content-Type": "application/x-protobuf", + "User-Agent": "OTel-OTLP-Exporter-Python/" + __version__, +} + + +class Compression(enum.Enum): + NoCompression = "none" + Deflate = "deflate" + Gzip = "gzip" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py new file mode 100644 index 00000000000..a2e87b1a353 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py @@ -0,0 +1,211 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +import os +from collections.abc import Mapping +from os import environ +from typing import TYPE_CHECKING, Literal + +from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._requests import ( + RequestsHTTPTransport, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( + _OTLP_HTTP_HEADERS, + Compression, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + _OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER, + OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, + OTEL_EXPORTER_OTLP_COMPRESSION, + OTEL_EXPORTER_OTLP_ENDPOINT, + OTEL_EXPORTER_OTLP_HEADERS, + OTEL_EXPORTER_OTLP_TIMEOUT, +) +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points +from opentelemetry.agent._vendor.opentelemetry.util.re import parse_env_headers + +if TYPE_CHECKING: + from opentelemetry.agent._vendor import requests + + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport + + _CredentialEnvVar = Literal[ + "OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER", + "OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER", + "OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER", + ] + +_logger = logging.getLogger(__name__) + +_DEFAULT_ENDPOINT = "http://localhost:4318" +_DEFAULT_TIMEOUT = 10 + +# 64 MiB, in bytes. +_DEFAULT_MAX_REQUEST_SIZE = 64 * 1024 * 1024 + + +class RequestPayloadTooLargeError(Exception): + """A serialized OTLP request exceeded the configured ``max_request_size``. + + The class name is emitted as the ``error.type`` attribute on the exporter's + failed-export metric, so renaming it changes observable telemetry. + """ + + +def _is_request_too_large(serialized_data: bytes, max_request_size: int) -> bool: + """Return True if the serialized request exceeds a positive size limit. + + The size is measured on the uncompressed serialized request, matching the + OTLP specification's "before compression" request-size limit. A + ``max_request_size`` of ``0`` (or any non-positive value) disables the + check. + """ + return 0 < max_request_size < len(serialized_data) + + +def _load_session_from_envvar( + cred_envvar: _CredentialEnvVar, +) -> requests.Session | None: + _credential_env = environ.get(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER) or environ.get(cred_envvar) + if _credential_env: + try: + # pylint: disable-next=import-outside-toplevel + from opentelemetry.agent._vendor import requests # noqa: PLC0415 + except ImportError as exc: + raise ImportError( + "The 'requests' package is required to load a credential " + "provider session but is not installed. Install it with " + "`pip install requests`." + ) from exc + + try: + maybe_session = next( + iter( + entry_points( + group="opentelemetry_otlp_credential_provider", + name=_credential_env, + ) + ) + ).load()() + except StopIteration: + raise RuntimeError( + f"Requested component '{_credential_env}' not found in " + f"entry point 'opentelemetry_otlp_credential_provider'" + ) + if isinstance(maybe_session, requests.Session): + return maybe_session + else: + raise RuntimeError( + f"Requested component '{_credential_env}' is of type {type(maybe_session)}" + f" must be of type `requests.Session`." + ) + return None + + +def _normalize_compression( + compression: Compression | _http.Compression | None, +) -> _http.Compression | None: + match compression: + case Compression.NoCompression: + return _http.Compression.NONE + case Compression.Deflate: + return _http.Compression.DEFLATE + case Compression.Gzip: + return _http.Compression.GZIP + case _: + return compression + + +def _resolve_endpoint( + endpoint_env_var: str, + default_path: Literal["v1/traces", "v1/metrics", "v1/logs"], +) -> str: + if endpoint := os.environ.get(endpoint_env_var): + return endpoint + + base_endpoint = os.environ.get(OTEL_EXPORTER_OTLP_ENDPOINT) or _DEFAULT_ENDPOINT + + return f"{base_endpoint.removesuffix('/')}/{default_path}" + + +def _resolve_headers( + headers: Mapping[str, str] | None, + headers_env_var: str, +) -> dict[str, str]: + headers_ = {k.lower(): v for k, v in _OTLP_HTTP_HEADERS.items()} + env_headers = parse_env_headers( + os.environ.get(headers_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), + liberal=True, + ) + headers_.update(env_headers) + if headers: + headers_.update({key.lower(): value for key, value in headers.items()}) + return headers_ + + +def _resolve_timeout( + timeout_env_var: str, +) -> float: + raw = os.environ.get(timeout_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_TIMEOUT) or _DEFAULT_TIMEOUT + + try: + return float(raw) + except ValueError: + _logger.warning( + "Invalid timeout value %r, using default of %s seconds", + raw, + _DEFAULT_TIMEOUT, + ) + return float(_DEFAULT_TIMEOUT) + + +def _resolve_compression(compression_env_var: str) -> _http.Compression: + value = ( + (os.environ.get(compression_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_COMPRESSION) or "none") + .lower() + .strip() + ) + + try: + return _http.Compression.from_str(value) + except ValueError: + _logger.warning("Unsupported compression type: %s", value) + return _http.Compression.NONE + + +def _build_transport( + certificate_file: str | None, + client_key_file: str | None, + client_certificate_file: str | None, + certificate_env_var: str, + client_key_env_var: str, + client_certificate_env_var: str, + session: requests.Session | None, +) -> BaseHTTPTransport: + verify: bool | str = ( + certificate_file + or os.environ.get(certificate_env_var) + or os.environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE) + or True + ) + client_key_file = ( + client_key_file or os.environ.get(client_key_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_KEY) + ) + client_certificate_file = ( + client_certificate_file + or os.environ.get(client_certificate_env_var) + or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE) + ) + cert = ( + (client_certificate_file, client_key_file) + if client_certificate_file and client_key_file + else client_certificate_file + ) + + return RequestsHTTPTransport(verify=verify, cert=cert, session=session) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py new file mode 100644 index 00000000000..bbc80a740a4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -0,0 +1,223 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +import os +from collections.abc import Mapping, Sequence +from typing import TYPE_CHECKING, overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._exporter_metrics import ( + create_exporter_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._log_encoder import encode_logs +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import Compression +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._common import ( + _DEFAULT_MAX_REQUEST_SIZE, + RequestPayloadTooLargeError, + _build_transport, + _is_request_too_large, + _load_session_from_envvar, + _normalize_compression, + _resolve_compression, + _resolve_endpoint, + _resolve_headers, + _resolve_timeout, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord +from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( + LogRecordExporter, + LogRecordExportResult, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import DuplicateFilter +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + _OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, + OTEL_EXPORTER_OTLP_LOGS_HEADERS, + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OtelComponentTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( + HTTP_RESPONSE_STATUS_CODE, +) + +if TYPE_CHECKING: + from opentelemetry.agent._vendor import requests + + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport + +_logger = logging.getLogger(__name__) +# This prevents logs generated when a log fails to be written to generate another log which fails to be written etc. etc. +_logger.addFilter(DuplicateFilter()) + + +DEFAULT_COMPRESSION = Compression.NoCompression +DEFAULT_ENDPOINT = "http://localhost:4318/" +DEFAULT_LOGS_EXPORT_PATH = "v1/logs" +DEFAULT_TIMEOUT = 10 # in seconds + + +class OTLPLogExporter(LogRecordExporter): + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + ) -> None: ... + + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: None = None, + client_key_file: None = None, + client_certificate_file: None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + _transport: BaseHTTPTransport, + ) -> None: ... + + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + _transport: BaseHTTPTransport | None = None, + ) -> None: + """OTLP HTTP log exporter. + + Args: + endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal + path. Example: ``http://collector:4318/v1/logs``. For a base URL without a + signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. + certificate_file: Path to the CA certificate file for TLS. + client_key_file: Path to the client key file for mTLS. + client_certificate_file: Path to the client certificate file for mTLS. + headers: Headers to send with each export request. + timeout: Timeout in seconds for each export request. + compression: Compression to use; one of none, gzip, deflate. + session: Requests session to use at export. + max_request_size: Maximum size in bytes of a serialized request, + measured before compression. A request exceeding this size is + dropped before being sent. Defaults to 64 MiB; a value of 0 (or + any non-positive value) disables the limit. Batch processors + group log records by count rather than serialized size, so a + batch whose serialized request exceeds this limit is dropped as + a whole and recorded as a failed export; reduce the processor's + ``max_export_batch_size`` (or raise/disable this limit) if + batches may approach it. + meter_provider: MeterProvider used for the exporter's own metrics. + """ + self._endpoint = endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, DEFAULT_LOGS_EXPORT_PATH) + self._compression = _normalize_compression(compression) or _resolve_compression( + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION + ) + transport = _transport or _build_transport( + certificate_file, + client_key_file, + client_certificate_file, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + session=session or _load_session_from_envvar(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER), + ) + self._max_request_size = _DEFAULT_MAX_REQUEST_SIZE if max_request_size is None else max_request_size + self._client = _http._OTLPHTTPClient( + transport=transport, + endpoint=self._endpoint, + kind="logs", + timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT), + compression=self._compression, + headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_LOGS_HEADERS), + logger=_logger, + ) + self._shutdown = False + + self._metrics = create_exporter_metrics( + OtelComponentTypeValues.OTLP_HTTP_LOG_EXPORTER, + "logs", + self._endpoint, + meter_provider, + os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", + ) + + def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring batch") + return LogRecordExportResult.FAILURE + + with self._metrics.export_operation(len(batch)) as result: + try: + serialized_data = encode_logs(batch).SerializeToString() + # pylint: disable-next=broad-exception-caught + except Exception as error: + _logger.error("Failed to encode logs batch: %s", error) + result.error = error + return LogRecordExportResult.FAILURE + + if _is_request_too_large(serialized_data, self._max_request_size): + _logger.warning( + "Dropping logs batch: serialized size %d bytes exceeds max_request_size %d bytes.", + len(serialized_data), + self._max_request_size, + ) + result.error = RequestPayloadTooLargeError( + f"Serialized logs request size {len(serialized_data)} " + f"bytes exceeds max_request_size " + f"{self._max_request_size} bytes." + ) + return LogRecordExportResult.FAILURE + + export_result = self._client.export(serialized_data) + if not export_result.success: + result.error = export_result.error + result.error_attrs = ( + {HTTP_RESPONSE_STATUS_CODE: export_result.status_code} + if export_result.status_code is not None + else None + ) + return LogRecordExportResult.FAILURE + return LogRecordExportResult.SUCCESS + + def force_flush(self, timeout_millis: int = 10_000) -> bool: + """Nothing is buffered in this exporter, so this method does nothing.""" + return True + + def shutdown(self): + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring call") + return + self._shutdown = True + self._client.shutdown() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py new file mode 100644 index 00000000000..2e8fa2c1ef0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py @@ -0,0 +1,611 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import logging +import os +from collections.abc import Callable, Iterable, Mapping +from typing import ( # noqa: F401 + TYPE_CHECKING, + Any, + Optional, + overload, +) + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._aggregation import ( + _get_aggregation, + _get_temporality, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._exporter_metrics import ( + create_exporter_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( + _get_resource_data, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common.metrics_encoder import ( + encode_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import Compression +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._common import ( + _DEFAULT_MAX_REQUEST_SIZE, + RequestPayloadTooLargeError, + _build_transport, + _is_request_too_large, + _load_session_from_envvar, + _normalize_compression, + _resolve_compression, + _resolve_endpoint, + _resolve_headers, + _resolve_timeout, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider +from opentelemetry.agent._vendor.opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( + ExportMetricsServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 + AnyValue, + ArrayValue, + InstrumentationScope, + KeyValue, + KeyValueList, +) +from opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2 +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import Resource # noqa: F401 +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( + Resource as PB2Resource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + _OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER, + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, + OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, + OTEL_EXPORTER_OTLP_METRICS_HEADERS, + OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import Aggregation +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( # noqa: F401 + AggregationTemporality, + Gauge, + MetricExporter, + MetricExportResult, + MetricsData, + Sum, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( # noqa: F401 + Histogram as HistogramType, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource as SDKResource +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OtelComponentTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( + HTTP_RESPONSE_STATUS_CODE, +) + +if TYPE_CHECKING: + from opentelemetry.agent._vendor import requests + + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport + +_logger = logging.getLogger(__name__) + + +DEFAULT_COMPRESSION = Compression.NoCompression +DEFAULT_ENDPOINT = "http://localhost:4318/" +DEFAULT_METRICS_EXPORT_PATH = "v1/metrics" +DEFAULT_TIMEOUT = 10 # in seconds + + +class OTLPMetricExporter(MetricExporter): + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + max_export_batch_size: int | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + ) -> None: ... + + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: None = None, + client_key_file: None = None, + client_certificate_file: None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + max_export_batch_size: int | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + _transport: BaseHTTPTransport, + ) -> None: ... + + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, Aggregation] | None = None, + max_export_batch_size: int | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + _transport: BaseHTTPTransport | None = None, + ) -> None: + """OTLP HTTP metrics exporter + + Args: + endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal + path. Example: ``http://collector:4318/v1/metrics``. For a base URL without a + signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. + certificate_file: Path to the certificate file to use for any TLS + client_key_file: Path to the client key file to use for any TLS + client_certificate_file: Path to the client certificate file to use for any TLS + headers: Headers to be sent with HTTP requests at export + timeout: Timeout in seconds for export + compression: Compression to use; one of none, gzip, deflate + session: Requests session to use at export + preferred_temporality: Map of preferred temporality for each metric type. + See `opentelemetry.sdk.metrics.export.MetricReader` for more details on what + preferred temporality is. + preferred_aggregation: Map of preferred aggregation for each metric type. + See `opentelemetry.sdk.metrics.export.MetricReader` for more details on what + preferred aggregation is. + max_export_batch_size: Maximum number of data points to export in a single request. + If not set there is no limit to the number of data points in a request. + If it is set and the number of data points exceeds the max, the request will be split. + max_request_size: Maximum size in bytes of a serialized request, measured before + compression. A request exceeding this size is dropped before being sent. Defaults + to 64 MiB; a value of 0 (or any non-positive value) disables the limit. Requests + are sized after any ``max_export_batch_size`` splitting; a batch whose serialized + request still exceeds this limit is dropped as a whole and recorded as a failed + export. Reduce ``max_export_batch_size`` (or raise/disable this limit) if batches + may approach it. + meter_provider: MeterProvider used for the exporter's own metrics. + """ + MetricExporter.__init__( + self, + preferred_temporality=_get_temporality(preferred_temporality), + preferred_aggregation=_get_aggregation(preferred_aggregation), + ) + self._endpoint = endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, DEFAULT_METRICS_EXPORT_PATH) + self._compression = _normalize_compression(compression) or _resolve_compression( + OTEL_EXPORTER_OTLP_METRICS_COMPRESSION + ) + transport = _transport or _build_transport( + certificate_file, + client_key_file, + client_certificate_file, + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + session=session or _load_session_from_envvar(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER), + ) + self._client = _http._OTLPHTTPClient( + transport=transport, + endpoint=self._endpoint, + kind="metrics", + timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_METRICS_TIMEOUT), + compression=self._compression, + headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_METRICS_HEADERS), + logger=_logger, + ) + self._max_export_batch_size: int | None = max_export_batch_size + self._max_request_size = _DEFAULT_MAX_REQUEST_SIZE if max_request_size is None else max_request_size + self._shutdown = False + + self._metrics = create_exporter_metrics( + OtelComponentTypeValues.OTLP_HTTP_METRIC_EXPORTER, + "metrics", + self._endpoint, + meter_provider, + os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", + ) + + def _export_batch( + self, + export_request: ExportMetricsServiceRequest, + ) -> MetricExportResult: + with self._metrics.export_operation(_count_data_points(export_request)) as result: + serialized_data = export_request.SerializeToString() + if _is_request_too_large(serialized_data, self._max_request_size): + _logger.warning( + "Dropping metrics batch: serialized size %d bytes exceeds max_request_size %d bytes.", + len(serialized_data), + self._max_request_size, + ) + result.error = RequestPayloadTooLargeError( + f"Serialized metrics request size {len(serialized_data)} " + f"bytes exceeds max_request_size " + f"{self._max_request_size} bytes." + ) + return MetricExportResult.FAILURE + export_result = self._client.export(serialized_data) + if not export_result.success: + result.error = export_result.error + result.error_attrs = ( + {HTTP_RESPONSE_STATUS_CODE: export_result.status_code} + if export_result.status_code is not None + else None + ) + return MetricExportResult.FAILURE + return MetricExportResult.SUCCESS + + def export( + self, + metrics_data: MetricsData, + timeout_millis: float | None = 10000, + **kwargs, + ) -> MetricExportResult: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring batch") + return MetricExportResult.FAILURE + + try: + export_request = encode_metrics(metrics_data) + # pylint: disable-next=broad-exception-caught + except Exception as error: + _logger.error("Failed to encode metrics batch: %s", error) + return MetricExportResult.FAILURE + + # If no batch size configured, export as single batch with retries as configured + if self._max_export_batch_size is None: + return self._export_batch(export_request) + + for batch in _split_metrics_data(export_request, self._max_export_batch_size): + export_result = self._export_batch(batch) + if export_result != MetricExportResult.SUCCESS: + return MetricExportResult.FAILURE + + # Only returns SUCCESS if all batches succeeded + return MetricExportResult.SUCCESS + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring call") + return + self._shutdown = True + self._client.shutdown() + + def force_flush(self, timeout_millis: float = 10_000) -> bool: + """Nothing is buffered in this exporter, so this method does nothing.""" + return True + + def set_meter_provider(self, meter_provider: MeterProvider) -> None: + self._metrics = create_exporter_metrics( + OtelComponentTypeValues.OTLP_HTTP_METRIC_EXPORTER, + "metrics", + self._endpoint, + meter_provider, + os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", + ) + + +def _count_data_points(export_request: ExportMetricsServiceRequest) -> int: + """Count the number of data points in an encoded metrics export request.""" + count = 0 + for resource_metrics in export_request.resource_metrics: + for scope_metrics in resource_metrics.scope_metrics: + for metric in scope_metrics.metrics: + field_name = metric.WhichOneof("data") + if field_name: + count += len(getattr(metric, field_name).data_points) + return count + + +def _split_metrics_data( + metrics_data: ExportMetricsServiceRequest, + max_export_batch_size: int | None = None, +) -> Iterable[ExportMetricsServiceRequest]: + """Splits metrics data into several ExportMetricsServiceRequest (copies protobuf originals), + based on configured data point max export batch size. + + Args: + metrics_data: metrics object based on HTTP protocol buffer definition + + Returns: + Iterable[ExportMetricsServiceRequest]: An iterable of ExportMetricsServiceRequest objects containing + ExportMetricsServiceRequest.ResourceMetrics, ExportMetricsServiceRequest.ScopeMetrics, ExportMetricsServiceRequest.Metrics, and data points + """ + if not max_export_batch_size: + return metrics_data + + batch_size: int = 0 + # Stores split metrics data as editable references + # used to write batched pb2 objects for export when finalized + split_resource_metrics = [] + + for resource_metrics in metrics_data.resource_metrics: + split_scope_metrics = [] + split_resource_metrics.append( + { + "resource": resource_metrics.resource, + "schema_url": resource_metrics.schema_url, + "scope_metrics": split_scope_metrics, + } + ) + + for scope_metrics in resource_metrics.scope_metrics: + split_metrics = [] + split_scope_metrics.append( + { + "scope": scope_metrics.scope, + "schema_url": scope_metrics.schema_url, + "metrics": split_metrics, + } + ) + + for metric in scope_metrics.metrics: + split_data_points = [] + field_name = metric.WhichOneof("data") + if not field_name: + _logger.warning("Tried to split and export an unsupported metric type. Skipping.") + continue + + # Get data container using field name + # and build metric dictionary dynamically for conciseness + data_container = getattr(metric, field_name) + metric_dict = { + "name": metric.name, + "description": metric.description, + "unit": metric.unit, + field_name: { + "data_points": split_data_points, + }, + } + if hasattr(data_container, "aggregation_temporality"): + metric_dict[field_name]["aggregation_temporality"] = data_container.aggregation_temporality + if hasattr(data_container, "is_monotonic"): + metric_dict[field_name]["is_monotonic"] = data_container.is_monotonic + split_metrics.append(metric_dict) + + current_data_points = data_container.data_points + for data_point in current_data_points: + split_data_points.append(data_point) + batch_size += 1 + + if batch_size >= max_export_batch_size: + yield ExportMetricsServiceRequest( + resource_metrics=_get_split_resource_metrics_pb2(split_resource_metrics) + ) + + # Reset all the reference variables with current metrics_data position + # minus yielded data_points. Need to clear data_points and keep metric + # to avoid duplicate data_point export + batch_size = 0 + split_data_points = [] + + # Rebuild metric dict generically using same approach as initial creation + field_name = metric.WhichOneof("data") + if field_name is None: + _logger.warning("Tried to split and export an unsupported metric type. Skipping.") + continue + data_container = getattr(metric, field_name) + metric_dict = { + "name": metric.name, + "description": metric.description, + "unit": metric.unit, + field_name: { + "data_points": split_data_points, + }, + } + if hasattr(data_container, "aggregation_temporality"): + metric_dict[field_name]["aggregation_temporality"] = data_container.aggregation_temporality + if hasattr(data_container, "is_monotonic"): + metric_dict[field_name]["is_monotonic"] = data_container.is_monotonic + + split_metrics = [metric_dict] + split_scope_metrics = [ + { + "scope": scope_metrics.scope, + "schema_url": scope_metrics.schema_url, + "metrics": split_metrics, + } + ] + split_resource_metrics = [ + { + "resource": resource_metrics.resource, + "schema_url": resource_metrics.schema_url, + "scope_metrics": split_scope_metrics, + } + ] + + if not split_data_points: + # If data_points is empty remove the whole metric + split_metrics.pop() + + if not split_metrics: + # If metrics is empty remove the whole scope_metrics + split_scope_metrics.pop() + + if not split_scope_metrics: + # If scope_metrics is empty remove the whole resource_metrics + split_resource_metrics.pop() + + if batch_size > 0: + yield ExportMetricsServiceRequest(resource_metrics=_get_split_resource_metrics_pb2(split_resource_metrics)) + + +def _get_split_resource_metrics_pb2( + split_resource_metrics: list[dict], +) -> list[pb2.ResourceMetrics]: + """Helper that returns a list of pb2.ResourceMetrics objects based on split_resource_metrics. + Example input: + + ```python + [ + { + "resource": , + "schema_url": "http://foo-bar", + "scope_metrics": [ + "scope": , + "schema_url": "http://foo-baz", + "metrics": [ + { + "name": "apples", + "description": "number of apples purchased", + "sum": { + "aggregation_temporality": 1, + "is_monotonic": "false", + "data_points": [ + { + start_time_unix_nano: 1000 + time_unix_nano: 1001 + exemplars { + time_unix_nano: 1002 + span_id: "foo-span" + trace_id: "foo-trace" + as_int: 5 + } + as_int: 5 + } + ] + } + }, + ], + ], + }, + ] + ``` + + Args: + split_resource_metrics: A list of dict representations of ResourceMetrics, + ScopeMetrics, Metrics, and data points. + + Returns: + List[pb2.ResourceMetrics]: A list of pb2.ResourceMetrics objects containing + pb2.ScopeMetrics, pb2.Metrics, and data points + """ + split_resource_metrics_pb = [] + for resource_metrics in split_resource_metrics: + new_resource_metrics = pb2.ResourceMetrics( + resource=resource_metrics.get("resource"), + scope_metrics=[], + schema_url=resource_metrics.get("schema_url") or "", + ) + for scope_metrics in resource_metrics.get("scope_metrics", []): + new_scope_metrics = pb2.ScopeMetrics( + scope=scope_metrics.get("scope"), + metrics=[], + schema_url=scope_metrics.get("schema_url") or "", + ) + + for metric in scope_metrics.get("metrics", []): + new_metric = None + data_points = [] + + if "sum" in metric: + new_metric = pb2.Metric( + name=metric.get("name"), + description=metric.get("description"), + unit=metric.get("unit"), + sum=pb2.Sum( + data_points=[], + aggregation_temporality=metric.get("sum").get("aggregation_temporality"), + is_monotonic=metric.get("sum").get("is_monotonic"), + ), + ) + data_points = metric.get("sum").get("data_points") + elif "histogram" in metric: + new_metric = pb2.Metric( + name=metric.get("name"), + description=metric.get("description"), + unit=metric.get("unit"), + histogram=pb2.Histogram( + data_points=[], + aggregation_temporality=metric.get("histogram").get("aggregation_temporality"), + ), + ) + data_points = metric.get("histogram").get("data_points") + elif "exponential_histogram" in metric: + new_metric = pb2.Metric( + name=metric.get("name"), + description=metric.get("description"), + unit=metric.get("unit"), + exponential_histogram=pb2.ExponentialHistogram( + data_points=[], + aggregation_temporality=metric.get("exponential_histogram").get("aggregation_temporality"), + ), + ) + data_points = metric.get("exponential_histogram").get("data_points") + elif "gauge" in metric: + new_metric = pb2.Metric( + name=metric.get("name"), + description=metric.get("description"), + unit=metric.get("unit"), + gauge=pb2.Gauge( + data_points=[], + ), + ) + data_points = metric.get("gauge").get("data_points") + elif "summary" in metric: + new_metric = pb2.Metric( + name=metric.get("name"), + description=metric.get("description"), + unit=metric.get("unit"), + summary=pb2.Summary( + data_points=[], + ), + ) + data_points = metric.get("summary").get("data_points") + else: + _logger.warning("Tried to split and export an unsupported metric type. Skipping.") + continue + + # Append data points generically using the field name from the metric dict + for field_name in [ + "sum", + "histogram", + "exponential_histogram", + "gauge", + "summary", + ]: + if field_name in metric: + metric_data_container = getattr(new_metric, field_name) + for data_point in data_points: + metric_data_container.data_points.append(data_point) + break + + new_scope_metrics.metrics.append(new_metric) + new_resource_metrics.scope_metrics.append(new_scope_metrics) + split_resource_metrics_pb.append(new_resource_metrics) + return split_resource_metrics_pb + + +@deprecated( + "Use one of the encoders from opentelemetry-exporter-otlp-proto-common instead. Deprecated since version 1.18.0.", +) +def get_resource_data( + sdk_resource_scope_data: dict[SDKResource, Any], # ResourceDataT? + resource_class: Callable[..., PB2Resource], + name: str, +) -> list[PB2Resource]: + return _get_resource_data(sdk_resource_scope_data, resource_class, name) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py new file mode 100644 index 00000000000..0512e653120 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py @@ -0,0 +1,219 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +import os +from collections.abc import Mapping, Sequence +from typing import TYPE_CHECKING, overload + +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._exporter_metrics import ( + create_exporter_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common.trace_encoder import ( + encode_spans, +) +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import Compression +from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._common import ( + _DEFAULT_MAX_REQUEST_SIZE, + RequestPayloadTooLargeError, + _build_transport, + _is_request_too_large, + _load_session_from_envvar, + _normalize_compression, + _resolve_compression, + _resolve_endpoint, + _resolve_headers, + _resolve_timeout, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + _OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER, + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, + OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, + OTEL_EXPORTER_OTLP_TRACES_HEADERS, + OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OtelComponentTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( + HTTP_RESPONSE_STATUS_CODE, +) + +if TYPE_CHECKING: + from opentelemetry.agent._vendor import requests + + from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport + +_logger = logging.getLogger(__name__) + + +DEFAULT_COMPRESSION = Compression.NoCompression +DEFAULT_ENDPOINT = "http://localhost:4318/" +DEFAULT_TRACES_EXPORT_PATH = "v1/traces" +DEFAULT_TIMEOUT = 10 # in seconds + + +class OTLPSpanExporter(SpanExporter): + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + ) -> None: ... + + @overload + def __init__( + self, + endpoint: str | None = None, + certificate_file: None = None, + client_key_file: None = None, + client_certificate_file: None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + _transport: BaseHTTPTransport, + ) -> None: ... + + def __init__( + self, + endpoint: str | None = None, + certificate_file: str | None = None, + client_key_file: str | None = None, + client_certificate_file: str | None = None, + headers: Mapping[str, str] | None = None, + timeout: float | None = None, + compression: Compression | _http.Compression | None = None, + session: requests.Session | None = None, + *, + max_request_size: int | None = None, + meter_provider: MeterProvider | None = None, + _transport: BaseHTTPTransport | None = None, + ) -> None: + """OTLP HTTP span exporter. + + Args: + endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal + path. Example: ``http://collector:4318/v1/traces``. For a base URL without a + signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. + certificate_file: Path to the CA certificate file for TLS. + client_key_file: Path to the client key file for mTLS. + client_certificate_file: Path to the client certificate file for mTLS. + headers: Headers to send with each export request. + timeout: Timeout in seconds for each export request. + compression: Compression to use; one of none, gzip, deflate. + session: Requests session to use at export. + max_request_size: Maximum size in bytes of a serialized request, + measured before compression. A request exceeding this size is + dropped before being sent. Defaults to 64 MiB; a value of 0 (or + any non-positive value) disables the limit. Batch processors + group spans by count rather than serialized size, so a batch + whose serialized request exceeds this limit is dropped as a + whole and recorded as a failed export; reduce the processor's + ``max_export_batch_size`` (or raise/disable this limit) if + batches may approach it. + meter_provider: MeterProvider used for the exporter's own metrics. + """ + self._endpoint = endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, DEFAULT_TRACES_EXPORT_PATH) + self._compression = _normalize_compression(compression) or _resolve_compression( + OTEL_EXPORTER_OTLP_TRACES_COMPRESSION + ) + transport = _transport or _build_transport( + certificate_file, + client_key_file, + client_certificate_file, + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + session=session or _load_session_from_envvar(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER), + ) + self._max_request_size = _DEFAULT_MAX_REQUEST_SIZE if max_request_size is None else max_request_size + self._client = _http._OTLPHTTPClient( + transport=transport, + endpoint=self._endpoint, + kind="spans", + timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT), + compression=self._compression, + headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_TRACES_HEADERS), + logger=_logger, + ) + self._shutdown = False + + self._metrics = create_exporter_metrics( + OtelComponentTypeValues.OTLP_HTTP_SPAN_EXPORTER, + "traces", + self._endpoint, + meter_provider, + os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", + ) + + def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring batch") + return SpanExportResult.FAILURE + + with self._metrics.export_operation(len(spans)) as result: + try: + serialized_data = encode_spans(spans).SerializePartialToString() + # pylint: disable-next=broad-exception-caught + except Exception as error: + _logger.error("Failed to encode span batch: %s", error) + result.error = error + return SpanExportResult.FAILURE + + if _is_request_too_large(serialized_data, self._max_request_size): + _logger.warning( + "Dropping span batch: serialized size %d bytes exceeds max_request_size %d bytes.", + len(serialized_data), + self._max_request_size, + ) + result.error = RequestPayloadTooLargeError( + f"Serialized span request size {len(serialized_data)} " + f"bytes exceeds max_request_size " + f"{self._max_request_size} bytes." + ) + return SpanExportResult.FAILURE + + export_result = self._client.export(serialized_data) + if not export_result.success: + result.error = export_result.error + result.error_attrs = ( + {HTTP_RESPONSE_STATUS_CODE: export_result.status_code} + if export_result.status_code is not None + else None + ) + return SpanExportResult.FAILURE + return SpanExportResult.SUCCESS + + def shutdown(self): + if self._shutdown: + _logger.warning("Exporter already shutdown, ignoring call") + return + self._shutdown = True + self._client.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Nothing is buffered in this exporter, so this method does nothing.""" + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py new file mode 100644 index 00000000000..6b9b95be1fc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py @@ -0,0 +1,55 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging # noqa: F401 +from collections import abc # noqa: F401 +from collections.abc import Sequence # noqa: F401 + +from opentelemetry.agent._vendor.opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ( # noqa: F401 + ExportTraceServiceRequest as PB2ExportTraceServiceRequest, +) +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 + AnyValue as PB2AnyValue, +) +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 + ArrayValue as PB2ArrayValue, +) +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 + InstrumentationScope as PB2InstrumentationScope, +) +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 + KeyValue as PB2KeyValue, +) +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( # noqa: F401 + Resource as PB2Resource, +) +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 + ResourceSpans as PB2ResourceSpans, +) +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 + ScopeSpans as PB2ScopeSpans, +) +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 + Span as PB2SPan, +) +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 + Status as PB2Status, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ( + Event, # noqa: F401 + Resource, # noqa: F401 +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Span as SDKSpan # noqa: F401 +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( # noqa: F401 + InstrumentationScope, +) +from opentelemetry.agent._vendor.opentelemetry.trace import ( + Link, # noqa: F401 + SpanKind, # noqa: F401 +) +from opentelemetry.agent._vendor.opentelemetry.trace.span import ( # noqa: F401 + SpanContext, + Status, + TraceState, +) +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes # noqa: F401 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py new file mode 100644 index 00000000000..0101c361616 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py new file mode 100644 index 00000000000..2c5a682a03b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py @@ -0,0 +1,523 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +This library allows export of metrics data to `Prometheus `_. + +Usage +----- + +The **OpenTelemetry Prometheus Exporter** allows export of `OpenTelemetry`_ +metrics to `Prometheus`_. + + +.. _Prometheus: https://prometheus.io/ +.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ + +.. code:: python + + from prometheus_client import start_http_server + + from opentelemetry.exporter.prometheus import PrometheusMetricReader + from opentelemetry.metrics import get_meter_provider, set_meter_provider + from opentelemetry.sdk.metrics import MeterProvider + + # Start Prometheus client + start_http_server(port=8000, addr="localhost") + + # Exporter to export metrics to Prometheus + prefix = "MyAppPrefix" + reader = PrometheusMetricReader(prefix=prefix) + + # Meter is responsible for creating and recording metrics + set_meter_provider(MeterProvider(metric_readers=[reader])) + meter = get_meter_provider().get_meter("myapp", "0.1.2") + + counter = meter.create_counter( + "requests", + "requests", + "number of requests", + ) + + # Labels are used to identify key-values that are associated with a specific + # metric that you want to record. These are useful for pre-aggregation and can + # be used to store custom dimensions pertaining to a metric + labels = {"environment": "staging"} + + counter.add(25, labels) + input("Press any key to exit...") + +API +--- +""" + +from collections import deque +from collections.abc import Callable, Iterable, Sequence +from itertools import chain +from json import dumps +from logging import getLogger +from os import environ +from typing import ( + Any, + TypeVar, +) + +from opentelemetry.agent._vendor.prometheus_client import CollectorRegistry, start_http_server +from opentelemetry.agent._vendor.prometheus_client.core import ( + REGISTRY, + CounterMetricFamily, + GaugeMetricFamily, + HistogramMetricFamily, + InfoMetricFamily, +) +from opentelemetry.agent._vendor.prometheus_client.core import Metric as PrometheusMetric + +from opentelemetry.agent._vendor.opentelemetry.exporter.prometheus._mapping import ( + map_unit, + sanitize_attribute, + sanitize_full_name, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_PROMETHEUS_HOST, + OTEL_EXPORTER_PROMETHEUS_PORT, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( + Counter, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import Histogram as HistogramInstrument +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + AggregationTemporality, + CardinalityLimits, + DataT, + Gauge, + Histogram, + HistogramDataPoint, + Metric, + MetricReader, + MetricsData, + Sum, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OtelComponentTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes + +_logger = getLogger(__name__) + +_TARGET_INFO_NAME = "target" +_TARGET_INFO_DESCRIPTION = "Target metadata" + +_OTEL_SCOPE_NAME_LABEL = "otel_scope_name" +_OTEL_SCOPE_VERSION_LABEL = "otel_scope_version" +_OTEL_SCOPE_SCHEMA_URL_LABEL = "otel_scope_schema_url" +_OTEL_SCOPE_ATTR_PREFIX = "otel_scope_" + + +def _convert_buckets(bucket_counts: Sequence[int], explicit_bounds: Sequence[float]) -> Sequence[tuple[str, int]]: + buckets = [] + total_count = 0 + for upper_bound, count in zip( + chain(explicit_bounds, ["+Inf"]), + bucket_counts, + ): + total_count += count + buckets.append((f"{upper_bound}", total_count)) + + return buckets + + +def _should_convert_sum_to_gauge(metric: Metric) -> bool: + # The Prometheus compatibility spec requires cumulative non-monotonic Sums + # to be exported as Gauges. + if not isinstance(metric.data, Sum): + return False + return not metric.data.is_monotonic and metric.data.aggregation_temporality == AggregationTemporality.CUMULATIVE + + +_FamilyT = TypeVar("_FamilyT", bound=PrometheusMetric) + + +def _get_or_create_family( + registry: dict[str, PrometheusMetric], + family_id: str, + factory: Callable[..., _FamilyT], + *, + name: str, + documentation: str, + labels: Sequence[str], + unit: str, +) -> _FamilyT: + if family_id not in registry: + registry[family_id] = factory( + name=name, + documentation=documentation, + labels=labels, + unit=unit, + ) + return registry[family_id] + + +def _populate_counter_family( + registry: dict[str, PrometheusMetric], + per_metric_family_id: str, + metric_name: str, + description: str, + unit: str, + label_keys: Sequence[str], + label_rows: Sequence[Sequence[str]], + values: Sequence[float], +) -> None: + family_id = "|".join([per_metric_family_id, CounterMetricFamily.__name__]) + family = _get_or_create_family( + registry, + family_id, + CounterMetricFamily, + name=metric_name, + documentation=description, + labels=label_keys, + unit=unit, + ) + for label_values, value in zip(label_rows, values): + family.add_metric(labels=label_values, value=value) + + +def _populate_gauge_family( + registry: dict[str, PrometheusMetric], + per_metric_family_id: str, + metric_name: str, + description: str, + unit: str, + label_keys: Sequence[str], + label_rows: Sequence[Sequence[str]], + values: Sequence[float], +) -> None: + family_id = "|".join([per_metric_family_id, GaugeMetricFamily.__name__]) + family = _get_or_create_family( + registry, + family_id, + GaugeMetricFamily, + name=metric_name, + documentation=description, + labels=label_keys, + unit=unit, + ) + for label_values, value in zip(label_rows, values): + family.add_metric(labels=label_values, value=value) + + +def _populate_histogram_family( + registry: dict[str, PrometheusMetric], + per_metric_family_id: str, + metric_name: str, + description: str, + unit: str, + label_keys: Sequence[str], + label_rows: Sequence[Sequence[str]], + values: Sequence[dict[str, Any]], +) -> None: + family_id = "|".join([per_metric_family_id, HistogramMetricFamily.__name__]) + family = _get_or_create_family( + registry, + family_id, + HistogramMetricFamily, + name=metric_name, + documentation=description, + labels=label_keys, + unit=unit, + ) + for label_values, value in zip(label_rows, values): + family.add_metric( + labels=label_values, + buckets=_convert_buckets(value["bucket_counts"], value["explicit_bounds"]), + sum_value=value["sum"], + ) + + +class PrometheusMetricReader(MetricReader): + """Prometheus metric exporter for OpenTelemetry. + + Args: + disable_target_info: Whether to disable the ``target_info`` metric. + prefix: Prefix added to exported Prometheus metric names. + scope_info_enabled: Whether to include instrumentation scope labels on + exported metrics. Scope labels are exported by default. + resource_attribute_filter: Optional callback to select resource attributes + that are copied as labels on exported metrics. The callback receives + the original resource attribute key. Selected keys are sanitized to + valid Prometheus label names. + cardinality_limits: A mapping between instrument classes and the + maximum number of metric points a metric stream of that class may + export per collection cycle. Classes not included in the mapping + use a limit of 2000. See + :class:`~opentelemetry.sdk.metrics.export.MetricReader` for details. + """ + + def __init__( + self, + disable_target_info: bool = False, + prefix: str = "", + scope_info_enabled: bool = True, + *, + resource_attribute_filter: Callable[[str], bool] | None = None, + registry: CollectorRegistry = REGISTRY, + cardinality_limits: CardinalityLimits | None = None, + ) -> None: + super().__init__( + preferred_temporality={ + Counter: AggregationTemporality.CUMULATIVE, + UpDownCounter: AggregationTemporality.CUMULATIVE, + HistogramInstrument: AggregationTemporality.CUMULATIVE, + ObservableCounter: AggregationTemporality.CUMULATIVE, + ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + ObservableGauge: AggregationTemporality.CUMULATIVE, + }, + cardinality_limits=cardinality_limits, + otel_component_type=OtelComponentTypeValues.PROMETHEUS_HTTP_TEXT_METRIC_EXPORTER, + ) + self._collector = _CustomCollector( + disable_target_info=disable_target_info, + prefix=prefix, + scope_info_enabled=scope_info_enabled, + resource_attribute_filter=resource_attribute_filter, + ) + self._registry = registry + self._registry.register(self._collector) + self._collector._callback = self.collect + self._prefix = prefix + + def _receive_metrics( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> None: + if metrics_data is None: + return + self._collector.add_metrics_data(metrics_data) + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + self._registry.unregister(self._collector) + + +class _CustomCollector: + """_CustomCollector represents the Prometheus Collector object + + See more: + https://github.com/prometheus/client_python#custom-collectors + """ + + def __init__( + self, + disable_target_info: bool = False, + prefix: str = "", + scope_info_enabled: bool = True, + resource_attribute_filter: Callable[[str], bool] | None = None, + ): + self._callback = None + self._metrics_datas: deque[MetricsData] = deque() + self._disable_target_info = disable_target_info + self._target_info = None + self._prefix = prefix + self._scope_info_enabled = scope_info_enabled + self._resource_attribute_filter = resource_attribute_filter + + def add_metrics_data(self, metrics_data: MetricsData) -> None: + """Add metrics to Prometheus data""" + self._metrics_datas.append(metrics_data) + + def collect(self) -> Iterable[PrometheusMetric]: + """Collect fetches the metrics from OpenTelemetry + and delivers them as Prometheus Metrics. + Collect is invoked every time a ``prometheus.Gatherer`` is run + for example when the HTTP endpoint is invoked by Prometheus. + """ + if self._callback is not None: + self._callback() + + metric_family_id_metric_family = {} + + if len(self._metrics_datas): + if not self._disable_target_info: + if self._target_info is None: + attributes: Attributes = {} + for res in self._metrics_datas[0].resource_metrics: + attributes = {**attributes, **res.resource.attributes} + + self._target_info = self._create_info_metric( + _TARGET_INFO_NAME, _TARGET_INFO_DESCRIPTION, attributes + ) + metric_family_id_metric_family[_TARGET_INFO_NAME] = self._target_info + + while self._metrics_datas: + self._translate_to_prometheus(self._metrics_datas.popleft(), metric_family_id_metric_family) + + if metric_family_id_metric_family: + yield from metric_family_id_metric_family.values() + + def _translate_to_prometheus( + self, + metrics_data: MetricsData, + metric_family_id_metric_family: dict[str, PrometheusMetric], + ): + for rm in metrics_data.resource_metrics: + resource_attrs = self._build_resource_attrs(rm.resource) + for sm in rm.scope_metrics: + scope_attrs = self._build_scope_attrs(sm.scope) + for metric in sm.metrics: + self._translate_metric( + metric=metric, + scope_attrs=scope_attrs, + resource_attrs=resource_attrs, + metric_family_id_metric_family=metric_family_id_metric_family, + ) + + def _translate_metric( + self, + metric: Metric, + scope_attrs: dict[str, AnyValue], + resource_attrs: dict[str, AnyValue], + metric_family_id_metric_family: dict[str, PrometheusMetric], + ) -> None: + metric_name = self._resolve_metric_name(metric.name) + description = metric.description or "" + unit = map_unit(metric.unit or "") + label_keys, label_rows, values = self._collect_data_points(metric.data, scope_attrs, resource_attrs) + per_metric_family_id = "|".join((metric_name, description, unit)) + + convert_sum_to_gauge = _should_convert_sum_to_gauge(metric) + + if isinstance(metric.data, Sum) and not convert_sum_to_gauge: + _populate_counter_family( + registry=metric_family_id_metric_family, + per_metric_family_id=per_metric_family_id, + metric_name=metric_name, + description=description, + unit=unit, + label_keys=label_keys, + label_rows=label_rows, + values=values, + ) + elif isinstance(metric.data, Gauge) or convert_sum_to_gauge: + _populate_gauge_family( + registry=metric_family_id_metric_family, + per_metric_family_id=per_metric_family_id, + metric_name=metric_name, + description=description, + unit=unit, + label_keys=label_keys, + label_rows=label_rows, + values=values, + ) + elif isinstance(metric.data, Histogram): + _populate_histogram_family( + registry=metric_family_id_metric_family, + per_metric_family_id=per_metric_family_id, + metric_name=metric_name, + description=description, + unit=unit, + label_keys=label_keys, + label_rows=label_rows, + values=values, + ) + else: + _logger.warning("Unsupported metric data. %s", type(metric.data)) + + def _build_scope_attrs(self, scope: InstrumentationScope) -> dict[str, AnyValue]: + if not self._scope_info_enabled: + return {} + attrs: dict[str, AnyValue] = {} + if scope.attributes: + for key, value in scope.attributes.items(): + attrs[_OTEL_SCOPE_ATTR_PREFIX + key] = value + attrs[_OTEL_SCOPE_NAME_LABEL] = scope.name or "" + attrs[_OTEL_SCOPE_VERSION_LABEL] = scope.version or "" + attrs[_OTEL_SCOPE_SCHEMA_URL_LABEL] = scope.schema_url or "" + return attrs + + def _build_resource_attrs(self, resource: Resource) -> dict[str, AnyValue]: + if not self._resource_attribute_filter: + return {} + return {key: value for key, value in resource.attributes.items() if self._resource_attribute_filter(key)} + + def _resolve_metric_name(self, name: str) -> str: + if self._prefix: + name = self._prefix + "_" + name + return sanitize_full_name(name) + + def _collect_data_points( + self, + metric_data: DataT, + scope_attrs: dict[str, AnyValue], + resource_attrs: dict[str, AnyValue], + ) -> tuple[list[str], list[list[str]], list[float | dict[str, Any]]]: + keys: set[str] = set() + rows: list[dict[str, str]] = [] + values: list[float | dict[str, Any]] = [] + + for point in metric_data.data_points: + labels: dict[str, str] = {} + for key, value in chain( + resource_attrs.items(), + scope_attrs.items(), + point.attributes.items(), + ): + label = sanitize_attribute(key) + keys.add(label) + labels[label] = self._check_value(value) + rows.append(labels) + + if isinstance(point, HistogramDataPoint): + values.append( + { + "bucket_counts": point.bucket_counts, + "explicit_bounds": point.explicit_bounds, + "sum": point.sum, + } + ) + else: + values.append(point.value) + + label_keys = sorted(keys) + # Backfill missing labels with "" so every data point exposes the + # full label set expected by the Prometheus family. + label_rows = [[labels.get(k, "") for k in label_keys] for labels in rows] + return label_keys, label_rows, values + + # pylint: disable=no-self-use + def _check_value(self, value: float | str | Sequence) -> str: + """Check the label value and return is appropriate representation""" + if not isinstance(value, str): + return dumps(value, default=str) + return str(value) + + def _create_info_metric(self, name: str, description: str, attributes: dict[str, str]) -> InfoMetricFamily: + """Create an Info Metric Family with list of attributes""" + # sanitize the attribute names according to Prometheus rule + attributes = {sanitize_attribute(key): self._check_value(value) for key, value in attributes.items()} + info = InfoMetricFamily(name, description, labels=attributes) + info.add_metric(labels=list(attributes.keys()), value=attributes) + return info + + +class _AutoPrometheusMetricReader(PrometheusMetricReader): + """Thin wrapper around PrometheusMetricReader used for the opentelemetry_metrics_exporter entry point. + + This allows users to use the prometheus exporter with opentelemetry-instrument. It handles + starting the Prometheus http server on the the correct port and host. + """ + + def __init__(self) -> None: + super().__init__() + + # Default values are specified in + # https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#prometheus-exporter + start_http_server( + port=int(environ.get(OTEL_EXPORTER_PROMETHEUS_PORT, "9464")), + addr=environ.get(OTEL_EXPORTER_PROMETHEUS_HOST, "localhost"), + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py new file mode 100644 index 00000000000..7822c69cc57 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py @@ -0,0 +1,126 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from re import UNICODE, compile + +_SANITIZE_NAME_RE = compile(r"[^a-zA-Z0-9:]+", UNICODE) +# Same as name, but doesn't allow ":" +_SANITIZE_ATTRIBUTE_KEY_RE = compile(r"[^a-zA-Z0-9]+", UNICODE) + +# UCUM style annotations which are text enclosed in curly braces https://ucum.org/ucum#para-6. +# This regex is more permissive than UCUM allows and matches any character within curly braces. +_UNIT_ANNOTATION = compile(r"{.*}") + +# Remaps common UCUM and SI units to prometheus conventions. Copied from +# https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/v0.101.0/pkg/translator/prometheus/normalize_name.go#L19 +# See specification: +# https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 +_UNIT_MAPPINGS = { + # Time + "d": "days", + "h": "hours", + "min": "minutes", + "s": "seconds", + "ms": "milliseconds", + "us": "microseconds", + "ns": "nanoseconds", + # Bytes + "By": "bytes", + "KiBy": "kibibytes", + "MiBy": "mebibytes", + "GiBy": "gibibytes", + "TiBy": "tibibytes", + "KBy": "kilobytes", + "MBy": "megabytes", + "GBy": "gigabytes", + "TBy": "terabytes", + # SI + "m": "meters", + "V": "volts", + "A": "amperes", + "J": "joules", + "W": "watts", + "g": "grams", + # Misc + "Cel": "celsius", + "Hz": "hertz", + # TODO(https://github.com/open-telemetry/opentelemetry-specification/issues/4058): the + # specification says to normalize "1" to ratio but that may change. Update this mapping or + # remove TODO once a decision is made. + "1": "", + "%": "percent", +} +# Similar to _UNIT_MAPPINGS, but for "per" unit denominator. +# Example: s => per second (singular) +# Copied from https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/80317ce83ed87a2dff0c316bb939afbfaa823d5e/pkg/translator/prometheus/normalize_name.go#L58 +_PER_UNIT_MAPPINGS = { + "s": "second", + "m": "minute", + "h": "hour", + "d": "day", + "w": "week", + "mo": "month", + "y": "year", +} + + +def sanitize_full_name(name: str) -> str: + """sanitize the given metric name according to Prometheus rule, including sanitizing + leading digits + + https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 + """ + # Leading number special case + if name and name[0].isdigit(): + name = "_" + name[1:] + return _sanitize_name(name) + + +def _sanitize_name(name: str) -> str: + """sanitize the given metric name according to Prometheus rule, but does not handle + sanitizing a leading digit.""" + return _SANITIZE_NAME_RE.sub("_", name) + + +def sanitize_attribute(key: str) -> str: + """sanitize the given metric attribute key according to Prometheus rule. + + https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-attributes + """ + # Leading number special case + if key and key[0].isdigit(): + key = "_" + key[1:] + return _SANITIZE_ATTRIBUTE_KEY_RE.sub("_", key) + + +def map_unit(unit: str) -> str: + """Maps unit to common prometheus metric names if available and sanitizes any invalid + characters + + See: + - https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 + - https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/v0.101.0/pkg/translator/prometheus/normalize_name.go#L108 + """ + # remove curly brace unit annotations + unit = _UNIT_ANNOTATION.sub("", unit) + + if unit in _UNIT_MAPPINGS: + return _UNIT_MAPPINGS[unit] + + # replace "/" with "per" units like m/s -> meters_per_second + ratio_unit_subparts = unit.split("/", maxsplit=1) + if len(ratio_unit_subparts) == 2: + bottom = _sanitize_name(ratio_unit_subparts[1]) + if bottom: + top = _sanitize_name(ratio_unit_subparts[0]) + top = _UNIT_MAPPINGS.get(top, top) + bottom = _PER_UNIT_MAPPINGS.get(bottom, bottom) + return f"{top}_per_{bottom}" if top else f"per_{bottom}" + + return ( + # since units end up as a metric name suffix, they must be sanitized + _sanitize_name(unit) + # strip surrounding "_" chars since it will lead to consecutive underscores in the + # metric name + .strip("_") + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py new file mode 100644 index 00000000000..7c9f8f20e01 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py @@ -0,0 +1,88 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +OpenTelemetry Labeler +===================== + +The labeler utility provides a way to add custom attributes to metrics. + +This was inspired by OpenTelemetry Go's net/http instrumentation Labeler +https://github.com/open-telemetry/opentelemetry-go-contrib/pull/306 + +Usage +----- + +The labeler is typically used within the context of an instrumented request +or operation. Use ``get_labeler`` to obtain a labeler instance for the +current context, then add attributes using the ``add`` or +``add_attributes`` methods. + +Example +------- + +Here's a framework-agnostic example showing manual use of the labeler: + +.. code-block:: python + + from opentelemetry.instrumentation._labeler import ( + enrich_metric_attributes, + get_labeler, + ) + from opentelemetry.metrics import get_meter + + meter = get_meter("example.manual") + duration_histogram = meter.create_histogram( + name="http.server.request.duration", + unit="s", + description="Duration of HTTP server requests.", + ) + + + def record_request(user_id: str, duration_s: float) -> None: + labeler = get_labeler() + labeler.add("user_id", user_id) + labeler.add_attributes( + { + "has_premium": user_id in ["123", "456"], + "experiment_group": "control", + "feature_enabled": True, + "user_segment": "active", + } + ) + + base_attributes = { + "http.request.method": "GET", + "http.response.status_code": 200, + } + duration_histogram.record( + max(duration_s, 0), + enrich_metric_attributes(base_attributes), + ) + +This package introduces the shared Labeler API and helper utilities. +Framework-specific integration points that call +``enrich_metric_attributes`` (for example before ``Histogram.record``) +can be added by individual instrumentors. + +When instrumentors use ``enrich_metric_attributes``, it does not +overwrite base attributes that exist at the same keys. +""" + +from opentelemetry.agent._vendor.opentelemetry.instrumentation._labeler._internal import ( + Labeler, + clear_labeler, + enrich_metric_attributes, + get_labeler, + get_labeler_attributes, + set_labeler, +) + +__all__ = [ + "Labeler", + "clear_labeler", + "enrich_metric_attributes", + "get_labeler", + "get_labeler_attributes", + "set_labeler", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py new file mode 100644 index 00000000000..63531f845e2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py @@ -0,0 +1,250 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import logging +import threading +from collections.abc import Mapping +from types import MappingProxyType +from typing import Any + +from opentelemetry.agent._vendor.opentelemetry.context import attach, create_key, get_value, set_value +from opentelemetry.agent._vendor.opentelemetry.util.types import AttributeValue + +LABELER_CONTEXT_KEY = create_key("otel_labeler") + +_logger = logging.getLogger(__name__) + + +class Labeler: + """ + Stores custom attributes for the current OTel context. + + This feature is experimental and unstable. + """ + + def __init__(self, max_custom_attrs: int = 20, max_attr_value_length: int = 100): + """ + Initialize a new Labeler instance. + + Args: + max_custom_attrs: Maximum number of custom attributes to store. + When this limit is reached, new attributes will be ignored; + existing attributes can still be updated. + max_attr_value_length: Maximum length for string attribute values. + String values exceeding this length will be truncated. + """ + self._lock = threading.Lock() + self._attributes: dict[str, str | int | float | bool] = {} + self._max_custom_attrs = max_custom_attrs + self._max_attr_value_length = max_attr_value_length + + def add(self, key: str, value: Any) -> None: + """ + Add a single attribute to the labeler, subject to the labeler's limits: + - If max_custom_attrs limit is reached and this is a new key, the attribute is ignored + - String values exceeding max_attr_value_length are truncated + + Args: + key: attribute key + value: attribute value, must be a primitive type: str, int, float, or bool + """ + if not isinstance(value, (str, int, float, bool)): + _logger.warning( + "Skipping attribute '%s': value must be str, int, float, or bool, got %s", + key, + type(value).__name__, + ) + return + + with self._lock: + if len(self._attributes) >= self._max_custom_attrs and key not in self._attributes: + return + + if isinstance(value, str) and len(value) > self._max_attr_value_length: + value = value[: self._max_attr_value_length] + + self._attributes[key] = value + + def add_attributes(self, attributes: dict[str, Any]) -> None: + """ + Add multiple attributes to the labeler, subject to the labeler's limits: + - If max_custom_attrs limit is reached and this is a new key, the attribute is ignored + - Existing attributes can still be updated + - String values exceeding max_attr_value_length are truncated + + Args: + attributes: Dictionary of attributes to add. Values must be primitive types + (str, int, float, or bool) + """ + with self._lock: + for key, value in attributes.items(): + if not isinstance(value, (str, int, float, bool)): + _logger.warning( + "Skipping attribute '%s': value must be str, int, float, or bool, got %s", + key, + type(value).__name__, + ) + continue + + if len(self._attributes) >= self._max_custom_attrs and key not in self._attributes: + continue + + if isinstance(value, str) and len(value) > self._max_attr_value_length: + value = value[: self._max_attr_value_length] + + self._attributes[key] = value + + def get_attributes(self) -> Mapping[str, str | int | float | bool]: + """ + Return a read-only mapping view of attributes in this labeler. + """ + with self._lock: + return MappingProxyType(self._attributes) + + def clear(self) -> None: + with self._lock: + self._attributes.clear() + + def __len__(self) -> int: + with self._lock: + return len(self._attributes) + + +def _attach_context_value(value: Labeler | None) -> None: + """ + Attach a new OpenTelemetry context containing the given labeler value. + + This helper is fail-safe: context attach errors are suppressed and + logged at debug level. + + Args: + value: Labeler instance to store in context, or ``None`` to clear it. + """ + try: + updated_context = set_value(LABELER_CONTEXT_KEY, value) + attach(updated_context) + except Exception: # pylint: disable=broad-exception-caught + _logger.debug("Failed to attach labeler context", exc_info=True) + + +def get_labeler() -> Labeler: + """ + Get the Labeler instance for the current OTel context. + + If no Labeler exists in the current context, a new one is created + and stored in the context. + + Returns: + Labeler instance for the current OTel context, or a new empty Labeler + if no Labeler is currently stored in context. + """ + try: + current_value = get_value(LABELER_CONTEXT_KEY) + except Exception: # pylint: disable=broad-exception-caught + _logger.debug("Failed to read labeler from context", exc_info=True) + current_value = None + + if isinstance(current_value, Labeler): + return current_value + + labeler = Labeler() + _attach_context_value(labeler) + return labeler + + +def set_labeler(labeler: Any) -> None: + """ + Set the Labeler instance for the current OTel context. + + Args: + labeler: The Labeler instance to set + """ + if not isinstance(labeler, Labeler): + _logger.warning( + "Skipping set_labeler: value must be Labeler, got %s", + type(labeler).__name__, + ) + return + _attach_context_value(labeler) + + +def clear_labeler() -> None: + """ + Clear the Labeler instance from the current OTel context. + + This is primarily intended for test isolation or manual context-lifecycle + management. In typical framework-instrumented request handling, + applications generally should not need to call this directly. + """ + _attach_context_value(None) + + +def get_labeler_attributes() -> Mapping[str, str | int | float | bool]: + """ + Get attributes from the current labeler, if any. + + Returns: + Read-only mapping of custom attributes, or an empty read-only mapping + if no labeler exists. + """ + empty_attributes: dict[str, str | int | float | bool] = {} + try: + current_value = get_value(LABELER_CONTEXT_KEY) + except Exception: # pylint: disable=broad-exception-caught + _logger.debug("Failed to read labeler attributes from context", exc_info=True) + return MappingProxyType(empty_attributes) + + if not isinstance(current_value, Labeler): + return MappingProxyType(empty_attributes) + return current_value.get_attributes() + + +def enrich_metric_attributes( + base_attributes: dict[str, Any], + enrich_enabled: bool = True, +) -> dict[str, AttributeValue]: + """ + Combines base_attributes with custom attributes from the current labeler, + returning a new dictionary of attributes according to the labeler configuration: + - Attributes that would override base_attributes are skipped + - If max_custom_attrs limit is reached and this is a new key, the attribute is ignored + - String values exceeding max_attr_value_length are truncated + + Args: + base_attributes: The base attributes for the metric + enrich_enabled: Whether to include custom labeler attributes + + Returns: + Dictionary combining base and custom attributes. If no custom attributes, + returns a copy of the original base attributes. + """ + if not enrich_enabled: + return base_attributes.copy() + + labeler_attributes = get_labeler_attributes() + if not labeler_attributes: + return base_attributes.copy() + + try: + labeler = get_value(LABELER_CONTEXT_KEY) + except Exception: # pylint: disable=broad-exception-caught + labeler = None + + if not isinstance(labeler, Labeler): + return base_attributes.copy() + + enriched_attributes = base_attributes.copy() + added_count = 0 + for key, value in labeler_attributes.items(): + if added_count >= labeler._max_custom_attrs: + break + if key in base_attributes: + continue + + if isinstance(value, str) and len(value) > labeler._max_attr_value_length: + value = value[: labeler._max_attr_value_length] + + enriched_attributes[key] = value + added_count += 1 + + return enriched_attributes diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py new file mode 100644 index 00000000000..37a7b36afe5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py @@ -0,0 +1,725 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import os +import threading +from collections.abc import Container, Mapping, MutableMapping +from enum import Enum +from urllib.parse import urlparse + +from opentelemetry.agent._vendor.packaging import version as package_version + +from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import http_status_to_status_code +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.db_attributes import ( + DB_NAME, + DB_OPERATION, + DB_REDIS_DATABASE_INDEX, + DB_STATEMENT, + DB_SYSTEM, + DB_USER, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.http_attributes import ( + HTTP_FLAVOR, + HTTP_HOST, + HTTP_METHOD, + HTTP_SCHEME, + HTTP_SERVER_NAME, + HTTP_STATUS_CODE, + HTTP_TARGET, + HTTP_URL, + HTTP_USER_AGENT, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_HOST_NAME, + NET_HOST_PORT, + NET_PEER_IP, + NET_PEER_NAME, + NET_PEER_PORT, + NET_TRANSPORT, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.client_attributes import ( + CLIENT_ADDRESS, + CLIENT_PORT, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.db_attributes import ( + DB_NAMESPACE, + DB_OPERATION_NAME, + DB_QUERY_TEXT, + DB_SYSTEM_NAME, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( + HTTP_REQUEST_METHOD, + HTTP_REQUEST_METHOD_ORIGINAL, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.network_attributes import ( + NETWORK_PROTOCOL_VERSION, + NETWORK_TRANSPORT, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.server_attributes import ( + SERVER_ADDRESS, + SERVER_PORT, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.url_attributes import ( + URL_FULL, + URL_PATH, + URL_QUERY, + URL_SCHEME, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.user_agent_attributes import ( + USER_AGENT_ORIGINAL, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.schemas import Schemas +from opentelemetry.agent._vendor.opentelemetry.trace import Span +from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode +from opentelemetry.agent._vendor.opentelemetry.util.types import AttributeValue + +# Values defined in milliseconds +HTTP_DURATION_HISTOGRAM_BUCKETS_OLD = ( + 0.0, + 5.0, + 10.0, + 25.0, + 50.0, + 75.0, + 100.0, + 250.0, + 500.0, + 750.0, + 1000.0, + 2500.0, + 5000.0, + 7500.0, + 10000.0, +) + +# Values defined in seconds +HTTP_DURATION_HISTOGRAM_BUCKETS_NEW = ( + 0.005, + 0.01, + 0.025, + 0.05, + 0.075, + 0.1, + 0.25, + 0.5, + 0.75, + 1, + 2.5, + 5, + 7.5, + 10, +) + +# These lists represent attributes for metrics that are currently supported + +_client_duration_attrs_old = [ + HTTP_STATUS_CODE, + HTTP_HOST, + HTTP_METHOD, + HTTP_FLAVOR, + HTTP_SCHEME, + NET_PEER_PORT, + NET_PEER_NAME, +] + +_client_duration_attrs_new = [ + ERROR_TYPE, + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, + NETWORK_PROTOCOL_VERSION, + SERVER_ADDRESS, + SERVER_PORT, + # TODO: Support opt-in for scheme in new semconv + # URL_SCHEME, +] + +_server_duration_attrs_old = [ + HTTP_METHOD, + HTTP_HOST, + HTTP_SCHEME, + HTTP_STATUS_CODE, + HTTP_FLAVOR, + HTTP_SERVER_NAME, + NET_HOST_NAME, + NET_HOST_PORT, +] + +_server_duration_attrs_new = [ + ERROR_TYPE, + HTTP_REQUEST_METHOD, + HTTP_RESPONSE_STATUS_CODE, + HTTP_ROUTE, + NETWORK_PROTOCOL_VERSION, + URL_SCHEME, +] + +_server_active_requests_count_attrs_old = [ + HTTP_METHOD, + HTTP_HOST, + HTTP_SCHEME, + HTTP_FLAVOR, + HTTP_SERVER_NAME, +] + +_server_active_requests_count_attrs_new = [ + HTTP_REQUEST_METHOD, + URL_SCHEME, + # TODO: Support SERVER_ADDRESS AND SERVER_PORT +] + +OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" + +# Legacy/default schema version when schema_url was first introduced +_LEGACY_SCHEMA_VERSION = "1.11.0" + + +class _OpenTelemetryStabilitySignalType(Enum): + HTTP = "http" + DATABASE = "database" + GEN_AI = "gen_ai" + + +class _StabilityMode(Enum): + DEFAULT = "default" + HTTP = "http" + HTTP_DUP = "http/dup" + DATABASE = "database" + DATABASE_DUP = "database/dup" + GEN_AI_LATEST_EXPERIMENTAL = "gen_ai_latest_experimental" + + +def _report_new(mode: _StabilityMode): + return mode != _StabilityMode.DEFAULT + + +def _report_old(mode: _StabilityMode): + return mode not in (_StabilityMode.HTTP, _StabilityMode.DATABASE) + + +class _OpenTelemetrySemanticConventionStability: + _initialized = False + _lock = threading.Lock() + _OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = {} + + @classmethod + def _initialize(cls): + with cls._lock: + if cls._initialized: + return + + # Users can pass in comma delimited string for opt-in options + # Only values for http, gen ai, and database stability are supported for now + opt_in = os.environ.get(OTEL_SEMCONV_STABILITY_OPT_IN) + + if not opt_in: + # early return in case of default + cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = { + _OpenTelemetryStabilitySignalType.HTTP: _StabilityMode.DEFAULT, + _OpenTelemetryStabilitySignalType.DATABASE: _StabilityMode.DEFAULT, + _OpenTelemetryStabilitySignalType.GEN_AI: _StabilityMode.DEFAULT, + } + cls._initialized = True + return + + opt_in_list = [s.strip() for s in opt_in.split(",")] + + cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[_OpenTelemetryStabilitySignalType.HTTP] = cls._filter_mode( + opt_in_list, _StabilityMode.HTTP, _StabilityMode.HTTP_DUP + ) + + cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[_OpenTelemetryStabilitySignalType.GEN_AI] = cls._filter_mode( + opt_in_list, + _StabilityMode.DEFAULT, + _StabilityMode.GEN_AI_LATEST_EXPERIMENTAL, + ) + + cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[_OpenTelemetryStabilitySignalType.DATABASE] = cls._filter_mode( + opt_in_list, + _StabilityMode.DATABASE, + _StabilityMode.DATABASE_DUP, + ) + cls._initialized = True + + @staticmethod + def _filter_mode(opt_in_list, stable_mode, dup_mode): + # Process semconv stability opt-in + # http/dup,database/dup has higher precedence over http,database + if dup_mode.value in opt_in_list: + return dup_mode + + return stable_mode if stable_mode.value in opt_in_list else _StabilityMode.DEFAULT + + @classmethod + def _get_opentelemetry_stability_opt_in_mode(cls, signal_type: _OpenTelemetryStabilitySignalType) -> _StabilityMode: + # Get OpenTelemetry opt-in mode based off of signal type (http, messaging, etc.) + return cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING.get(signal_type, _StabilityMode.DEFAULT) + + +def _get_semconv_opt_in_modes( + signal_types: tuple[_OpenTelemetryStabilitySignalType, ...], +) -> dict[_OpenTelemetryStabilitySignalType, _StabilityMode]: + """Returns a mapping of signal type to mode for the provided + signal_types (one/more of DATABASE, HTTP, GEN_AI). + """ + _OpenTelemetrySemanticConventionStability._initialize() + return { + signal_type: _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(signal_type) + for signal_type in signal_types + } + + +def _filter_semconv_duration_attrs( + attrs: Mapping[str, AttributeValue], + old_attrs: Container[AttributeValue], + new_attrs: Container[AttributeValue], + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, +) -> dict[str, AttributeValue]: + filtered_attrs = {} + # duration is two different metrics depending on sem_conv_opt_in_mode, so no DUP attributes + allowed_attributes = new_attrs if sem_conv_opt_in_mode == _StabilityMode.HTTP else old_attrs + for key, val in attrs.items(): + if key in allowed_attributes: + filtered_attrs[key] = val + return filtered_attrs + + +def _filter_semconv_active_request_count_attr( + attrs: Mapping[str, AttributeValue], + old_attrs: Container[AttributeValue], + new_attrs: Container[AttributeValue], + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, +) -> dict[str, AttributeValue]: + filtered_attrs = {} + if _report_old(sem_conv_opt_in_mode): + for key, val in attrs.items(): + if key in old_attrs: + filtered_attrs[key] = val + if _report_new(sem_conv_opt_in_mode): + for key, val in attrs.items(): + if key in new_attrs: + filtered_attrs[key] = val + return filtered_attrs + + +def set_string_attribute( + result: MutableMapping[str, AttributeValue], + key: str, + value: AttributeValue, +) -> None: + if value: + result[key] = value + + +def set_int_attribute( + result: MutableMapping[str, AttributeValue], + key: str, + value: AttributeValue, +) -> None: + if value: + try: + result[key] = int(value) + except (ValueError, TypeError): + pass + + +def _set_http_method( + result: MutableMapping[str, AttributeValue], + original: str, + normalized: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + original = original.strip() + normalized = normalized.strip() + # See https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes + # Method is case sensitive. "http.request.method_original" should not be sanitized or automatically capitalized. + if original != normalized and _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_REQUEST_METHOD_ORIGINAL, original) + + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_METHOD, normalized) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_REQUEST_METHOD, normalized) + + +def _set_http_status_code( + result: MutableMapping[str, AttributeValue], + code: str | int, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_int_attribute(result, HTTP_STATUS_CODE, code) + if _report_new(sem_conv_opt_in_mode): + set_int_attribute(result, HTTP_RESPONSE_STATUS_CODE, code) + + +def _set_http_url( + result: MutableMapping[str, AttributeValue], + url: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_URL, url) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, URL_FULL, url) + + +def _set_http_scheme( + result: MutableMapping[str, AttributeValue], + scheme: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_SCHEME, scheme) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, URL_SCHEME, scheme) + + +def _set_http_flavor_version( + result: MutableMapping[str, AttributeValue], + version: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_FLAVOR, version) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) + + +def _set_http_user_agent( + result: MutableMapping[str, AttributeValue], + user_agent: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_USER_AGENT, user_agent) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent) + + +# Client + + +def _set_http_host_client( + result: MutableMapping[str, AttributeValue], + host: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_HOST, host) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, SERVER_ADDRESS, host) + + +def _set_http_net_peer_name_client( + result: MutableMapping[str, AttributeValue], + peer_name: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, NET_PEER_NAME, peer_name) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, SERVER_ADDRESS, peer_name) + + +def _set_http_peer_port_client( + result: MutableMapping[str, AttributeValue], + port: str | int, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_int_attribute(result, NET_PEER_PORT, port) + if _report_new(sem_conv_opt_in_mode): + set_int_attribute(result, SERVER_PORT, port) + + +def _set_http_network_protocol_version( + result: MutableMapping[str, AttributeValue], + version: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_FLAVOR, version) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) + + +# Server + + +def _set_http_net_host( + result: MutableMapping[str, AttributeValue], + host: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, NET_HOST_NAME, host) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, SERVER_ADDRESS, host) + + +def _set_http_net_host_port( + result: MutableMapping[str, AttributeValue], + port: str | int, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_int_attribute(result, NET_HOST_PORT, port) + if _report_new(sem_conv_opt_in_mode): + set_int_attribute(result, SERVER_PORT, port) + + +def _set_http_target( + result: MutableMapping[str, AttributeValue], + target: str, + path: str | None, + query: str | None, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_TARGET, target) + if _report_new(sem_conv_opt_in_mode): + if path: + set_string_attribute(result, URL_PATH, path) + if query: + set_string_attribute(result, URL_QUERY, query) + + +def _set_http_host_server( + result: MutableMapping[str, AttributeValue], + host: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, HTTP_HOST, host) + if _report_new(sem_conv_opt_in_mode): + if not result.get(SERVER_ADDRESS): + set_string_attribute(result, SERVER_ADDRESS, host) + + +# net.peer.ip -> net.sock.peer.addr +# https://github.com/open-telemetry/semantic-conventions/blob/40db676ca0e735aa84f242b5a0fb14e49438b69b/schemas/1.15.0#L18 +# net.sock.peer.addr -> client.socket.address for server spans (TODO) AND client.address if missing +# https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/CHANGELOG.md#v1210-2023-07-13 +# https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md#common-attributes-across-http-client-and-server-spans +def _set_http_peer_ip_server( + result: MutableMapping[str, AttributeValue], + ip: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, NET_PEER_IP, ip) + if _report_new(sem_conv_opt_in_mode): + # Only populate if not already populated + if not result.get(CLIENT_ADDRESS): + set_string_attribute(result, CLIENT_ADDRESS, ip) + + +def _set_http_peer_port_server( + result: MutableMapping[str, AttributeValue], + port: str | int, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_int_attribute(result, NET_PEER_PORT, port) + if _report_new(sem_conv_opt_in_mode): + set_int_attribute(result, CLIENT_PORT, port) + + +def _set_http_net_peer_name_server( + result: MutableMapping[str, AttributeValue], + name: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, NET_PEER_NAME, name) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, CLIENT_ADDRESS, name) + + +# Database + + +def _set_db_system( + result: MutableMapping[str, AttributeValue], + system: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, DB_SYSTEM, system) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, DB_SYSTEM_NAME, system) + + +def _set_db_name( + result: MutableMapping[str, AttributeValue], + name: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, DB_NAME, name) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, DB_NAMESPACE, name) + + +def _set_db_statement( + result: MutableMapping[str, AttributeValue], + statement: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + # skip the statement if it's None but set it if it's an empty string + if statement is None: + return + + if _report_old(sem_conv_opt_in_mode): + result[DB_STATEMENT] = statement + if _report_new(sem_conv_opt_in_mode): + result[DB_QUERY_TEXT] = statement + + +def _set_db_user( + result: MutableMapping[str, AttributeValue], + user: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, DB_USER, user) + # No new attribute - db.user was removed with no replacement + + +def _set_db_operation( + result: MutableMapping[str, AttributeValue], + operation: str, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, DB_OPERATION, operation) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, DB_OPERATION_NAME, operation) + + +def _set_db_redis_database_index( + result: MutableMapping[str, AttributeValue], + database_index: int, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + if database_index is not None: + result[DB_REDIS_DATABASE_INDEX] = int(database_index) + # No new attribute - db.redis.database_index was removed with no replacement in semconv 1.38.0 + + +def _set_net_transport( + result: MutableMapping[str, AttributeValue], + old_transport: AttributeValue, + new_transport: AttributeValue, + sem_conv_opt_in_mode: _StabilityMode, +) -> None: + if _report_old(sem_conv_opt_in_mode): + set_string_attribute(result, NET_TRANSPORT, old_transport) + if _report_new(sem_conv_opt_in_mode): + set_string_attribute(result, NETWORK_TRANSPORT, new_transport) + + +# General + + +def _set_status( + span: Span, + metrics_attributes: MutableMapping[str, AttributeValue], + status_code: int, + status_code_str: str, + server_span: bool = True, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, +) -> None: + if status_code < 0: + if _report_new(sem_conv_opt_in_mode): + metrics_attributes[ERROR_TYPE] = status_code_str + if span.is_recording(): + if _report_new(sem_conv_opt_in_mode): + span.set_attribute(ERROR_TYPE, status_code_str) + span.set_status( + Status( + StatusCode.ERROR, + "Non-integer HTTP status: " + status_code_str, + ) + ) + else: + status = http_status_to_status_code(status_code, server_span=server_span) + + if _report_old(sem_conv_opt_in_mode): + if span.is_recording(): + span.set_attribute(HTTP_STATUS_CODE, status_code) + metrics_attributes[HTTP_STATUS_CODE] = status_code + if _report_new(sem_conv_opt_in_mode): + if span.is_recording(): + span.set_attribute(HTTP_RESPONSE_STATUS_CODE, status_code) + metrics_attributes[HTTP_RESPONSE_STATUS_CODE] = status_code + if status == StatusCode.ERROR: + if span.is_recording(): + span.set_attribute(ERROR_TYPE, status_code_str) + metrics_attributes[ERROR_TYPE] = status_code_str + if span.is_recording(): + span.set_status(Status(status)) + + +def _get_schema_url(mode: _StabilityMode) -> str: + """Get schema version URL for a single signal type's opt-in mode (backwards compatible). + + For new instrumentations using multiple signal types, use + _get_schema_url_for_signal_types() + """ + if mode is _StabilityMode.DEFAULT: + return f"https://opentelemetry.io/schemas/{_LEGACY_SCHEMA_VERSION}" + return Schemas.V1_21_0.value + + +def _get_schema_version_for_opt_in_mode( + signal_type: _OpenTelemetryStabilitySignalType, + mode: _StabilityMode, +) -> str: + """Get the schema version for a specific signal type and opt-in mode.""" + if mode == _StabilityMode.DEFAULT: + return _LEGACY_SCHEMA_VERSION + + signal_versions = { + _OpenTelemetryStabilitySignalType.HTTP: Schemas.V1_21_0.value, + _OpenTelemetryStabilitySignalType.DATABASE: Schemas.V1_25_0.value, + _OpenTelemetryStabilitySignalType.GEN_AI: Schemas.V1_26_0.value, + } + schema_url = signal_versions.get(signal_type) + if not schema_url: + return _LEGACY_SCHEMA_VERSION + + path = urlparse(schema_url).path + schema_version = path.rstrip("/").split("/")[-1] + return schema_version or _LEGACY_SCHEMA_VERSION + + +def _get_schema_url_for_signal_types( + signal_types: list[_OpenTelemetryStabilitySignalType], +) -> str: + """Get the highest applicable schema URL for multiple signal types. + + Note: + Instrumentors should call _OpenTelemetrySemanticConventionStability._initialize() + before using this function to ensure proper initialization of stability modes. + + Args: + signal_types: List of signal types used by the instrumentation + + Returns: + Schema URL string representing the highest applicable semconv version + """ + highest_schema_version = _LEGACY_SCHEMA_VERSION + for signal_type in signal_types: + mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(signal_type) + schema_version = _get_schema_version_for_opt_in_mode(signal_type, mode) + # Keep the highest for all signals + if package_version.Version(schema_version) > package_version.Version(highest_schema_version): + highest_schema_version = schema_version + return f"https://opentelemetry.io/schemas/{highest_schema_version}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py new file mode 100644 index 00000000000..ac89a699b92 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py @@ -0,0 +1,721 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +The opentelemetry-instrumentation-aiohttp-client package allows tracing HTTP +requests made by the aiohttp client library. + +Usage +----- +Explicitly instrumenting a single client session: + +.. code:: python + + import asyncio + import aiohttp + from opentelemetry.instrumentation.aiohttp_client import create_trace_config + import yarl + + def strip_query_params(url: yarl.URL) -> str: + return str(url.with_query(None)) + + async def get(url): + async with aiohttp.ClientSession(trace_configs=[create_trace_config( + # Remove all query params from the URL attribute on the span. + url_filter=strip_query_params, + )]) as session: + async with session.get(url) as response: + await response.text() + + asyncio.run(get("https://example.com")) + +Instrumenting all client sessions: + +.. code:: python + + import asyncio + import aiohttp + from opentelemetry.instrumentation.aiohttp_client import ( + AioHttpClientInstrumentor + ) + + # Enable instrumentation + AioHttpClientInstrumentor().instrument() + + # Create a session and make an HTTP get request + async def get(url): + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + await response.text() + + asyncio.run(get("https://example.com")) + +Configuration +------------- + +Request/Response hooks +********************** + +Utilize request/response hooks to execute custom logic to be performed before/after performing a request. + +.. code-block:: python + + def request_hook(span: Span, params: aiohttp.TraceRequestStartParams): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_request_hook", "some-value") + + + def response_hook( + span: Span, + params: typing.Union[ + aiohttp.TraceRequestEndParams, + aiohttp.TraceRequestExceptionParams, + ], + ): + if span and span.is_recording(): + span.set_attribute("custom_user_attribute_from_response_hook", "some-value") + + + AioHttpClientInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook) + +Exclude lists +************* +To exclude certain URLs from tracking, set the environment variable ``OTEL_PYTHON_AIOHTTP_CLIENT_EXCLUDED_URLS`` +(or ``OTEL_PYTHON_EXCLUDED_URLS`` to cover all instrumentations) to a string of comma delimited regexes that match the +URLs. + +For example, + +:: + + export OTEL_PYTHON_AIOHTTP_CLIENT_EXCLUDED_URLS="client/.*/info,healthcheck" + +will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. + +Capture HTTP request and response headers +***************************************** +You can configure the agent to capture specified HTTP headers as span attributes, according to the +`semantic conventions `_. + +Request headers +*************** +To capture HTTP request headers as span attributes, set the environment variable +``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST`` to a comma delimited list of HTTP header names. + +For example using the environment variable, +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST="content-type,custom_request_header" + +will extract ``content-type`` and ``custom_request_header`` from the request headers and add them as span attributes. + +Request header names in aiohttp are case-insensitive. So, giving the header name as ``CUStom-Header`` in the environment +variable will capture the header named ``custom-header``. + +Regular expressions may also be used to match multiple headers that correspond to the given pattern. For example: +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST="Accept.*,X-.*" + +Would match all request headers that start with ``Accept`` and ``X-``. + +To capture all request headers, set ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST`` to ``".*"``. +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST=".*" + +The name of the added span attribute will follow the format ``http.request.header.`` where ```` +is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a +single item list containing all the header values. + +For example: +``http.request.header.custom_request_header = ["", ""]`` + +Response headers +**************** +To capture HTTP response headers as span attributes, set the environment variable +``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE`` to a comma delimited list of HTTP header names. + +For example using the environment variable, +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE="content-type,custom_response_header" + +will extract ``content-type`` and ``custom_response_header`` from the response headers and add them as span attributes. + +Response header names in aiohttp are case-insensitive. So, giving the header name as ``CUStom-Header`` in the environment +variable will capture the header named ``custom-header``. + +Regular expressions may also be used to match multiple headers that correspond to the given pattern. For example: +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE="Content.*,X-.*" + +Would match all response headers that start with ``Content`` and ``X-``. + +To capture all response headers, set ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE`` to ``".*"``. +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE=".*" + +The name of the added span attribute will follow the format ``http.response.header.`` where ```` +is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a +list containing the header values. + +For example: +``http.response.header.custom_response_header = ["", ""]`` + +Sanitizing headers +****************** +In order to prevent storing sensitive data such as personally identifiable information (PII), session keys, passwords, +etc, set the environment variable ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS`` +to a comma delimited list of HTTP header names to be sanitized. + +Regexes may be used, and all header names will be matched in a case-insensitive manner. + +For example using the environment variable, +:: + + export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS=".*session.*,set-cookie" + +will replace the value of headers such as ``session-id`` and ``set-cookie`` with ``[REDACTED]`` in the span. + +Note: + The environment variable names used to capture HTTP headers are still experimental, and thus are subject to change. + +API +--- +""" + +from __future__ import annotations + +import types +import typing +from collections.abc import Callable, Collection +from timeit import default_timer +from typing import ( + TYPE_CHECKING, + Any, + TypedDict, + cast, +) +from urllib.parse import urlparse + +import aiohttp +from opentelemetry.agent._vendor import wrapt +import yarl + +from opentelemetry.agent._vendor.opentelemetry import context as context_api +from opentelemetry.agent._vendor.opentelemetry import trace +from opentelemetry.agent._vendor.opentelemetry.instrumentation._semconv import ( + HTTP_DURATION_HISTOGRAM_BUCKETS_NEW, + HTTP_DURATION_HISTOGRAM_BUCKETS_OLD, + _client_duration_attrs_new, + _client_duration_attrs_old, + _filter_semconv_duration_attrs, + _get_schema_url, + _OpenTelemetrySemanticConventionStability, + _OpenTelemetryStabilitySignalType, + _report_new, + _report_old, + _set_http_host_client, + _set_http_method, + _set_http_net_peer_name_client, + _set_http_peer_port_client, + _set_http_url, + _set_status, + _StabilityMode, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.aiohttp_client.package import _instruments +from opentelemetry.agent._vendor.opentelemetry.instrumentation.aiohttp_client.version import __version__ +from opentelemetry.agent._vendor.opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import ( + is_http_instrumentation_enabled, + unwrap, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter +from opentelemetry.agent._vendor.opentelemetry.propagate import inject +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE +from opentelemetry.agent._vendor.opentelemetry.semconv.metrics import ( + MetricInstruments, # type: ignore[reportDeprecated] +) +from opentelemetry.agent._vendor.opentelemetry.semconv.metrics.http_metrics import ( + HTTP_CLIENT_REQUEST_DURATION, +) +from opentelemetry.agent._vendor.opentelemetry.trace import Span, SpanKind, TracerProvider, get_tracer +from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode +from opentelemetry.agent._vendor.opentelemetry.util.http import ( + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE, + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, + get_custom_header_attributes, + get_custom_headers, + get_excluded_urls, + normalise_request_header_name, + normalise_response_header_name, + redact_url, + sanitize_method, +) + +if TYPE_CHECKING: + from opentelemetry.agent._vendor.typing_extensions import Unpack + + UrlFilterT = Callable[[yarl.URL], str] | None + RequestHookT = Callable[[Span, aiohttp.TraceRequestStartParams], None] | None + ResponseHookT = ( + Callable[ + [ + Span, + aiohttp.TraceRequestEndParams | aiohttp.TraceRequestExceptionParams, + ], + None, + ] + | None + ) + + class ClientSessionInitKwargs(TypedDict, total=False): + trace_configs: typing.Sequence[aiohttp.TraceConfig] + + class InstrumentKwargs(TypedDict, total=False): + tracer_provider: trace.TracerProvider + meter_provider: MeterProvider + url_filter: UrlFilterT + request_hook: RequestHookT + response_hook: ResponseHookT + trace_configs: typing.Sequence[aiohttp.TraceConfig] + + class UninstrumentKwargs(TypedDict, total=False): + pass + + +def _get_span_name(method: str) -> str: + method = sanitize_method(method.strip()) + if method == "_OTHER": + method = "HTTP" + return method + + +def _set_http_status_code_attribute( + span: Span, + status_code: int, + metric_attributes: dict[str, Any] | None = None, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, +): + status_code_str = str(status_code) + try: + status_code = int(status_code) + except ValueError: + status_code = -1 + if metric_attributes is None: + metric_attributes = {} + # When we have durations we should set metrics only once + # Also the decision to include status code on a histogram should + # not be dependent on tracing decisions. + _set_status( + span, + metric_attributes, + status_code, + status_code_str, + server_span=False, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + ) + + +# pylint: disable=too-many-locals +# pylint: disable=too-many-statements +def create_trace_config( + url_filter: UrlFilterT = None, + request_hook: RequestHookT = None, + response_hook: ResponseHookT = None, + tracer_provider: TracerProvider | None = None, + meter_provider: MeterProvider | None = None, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, + captured_request_headers: list[str] | None = None, + captured_response_headers: list[str] | None = None, + sensitive_headers: list[str] | None = None, +) -> aiohttp.TraceConfig: + """Create an aiohttp-compatible trace configuration. + + One span is created for the entire HTTP request, including initial + TCP/TLS setup if the connection doesn't exist. + + By default the span name is set to the HTTP request method. + + Example usage: + + .. code:: python + + import aiohttp + from opentelemetry.instrumentation.aiohttp_client import create_trace_config + + async with aiohttp.ClientSession(trace_configs=[create_trace_config()]) as session: + async with session.get(url) as response: + await response.text() + + + :param url_filter: A callback to process the requested URL prior to adding + it as a span attribute. This can be useful to remove sensitive data + such as API keys or user personal information. + + :param Callable request_hook: Optional callback that can modify span name and request params. + :param Callable response_hook: Optional callback that can modify span name and response params. + :param tracer_provider: optional TracerProvider from which to get a Tracer + :param meter_provider: optional Meter provider to use + :param captured_request_headers: List of HTTP request header regexes to capture as + span attributes. Header names matching these patterns will be added as span + attributes with the format ``http.request.header.``. + :param captured_response_headers: List of HTTP response header regexes to capture as + span attributes. Header names matching these patterns will be added as span + attributes with the format ``http.response.header.``. + :param sensitive_headers: List of HTTP header regexes whose values should be + sanitized (redacted) when captured. Header values matching these patterns + will be replaced with ``[REDACTED]``. + + :return: An object suitable for use with :py:class:`aiohttp.ClientSession`. + :rtype: :py:class:`aiohttp.TraceConfig` + """ + # `aiohttp.TraceRequestStartParams` resolves to `aiohttp.tracing.TraceRequestStartParams` + # which doesn't exist in the aiohttp intersphinx inventory. + # Explicitly specify the type for the `request_hook` and `response_hook` param and rtype to work + # around this issue. + + schema_url = _get_schema_url(sem_conv_opt_in_mode) + + tracer = get_tracer( + __name__, + __version__, + tracer_provider, + schema_url=schema_url, + ) + + meter = get_meter( + __name__, + __version__, + meter_provider, + schema_url, + ) + + duration_histogram_old = None + if _report_old(sem_conv_opt_in_mode): + duration_histogram_old = meter.create_histogram( + name=MetricInstruments.HTTP_CLIENT_DURATION, # type: ignore[reportDeprecated] + unit="ms", + description="measures the duration of the outbound HTTP request", + explicit_bucket_boundaries_advisory=HTTP_DURATION_HISTOGRAM_BUCKETS_OLD, + ) + duration_histogram_new = None + if _report_new(sem_conv_opt_in_mode): + duration_histogram_new = meter.create_histogram( + name=HTTP_CLIENT_REQUEST_DURATION, + unit="s", + description="Duration of HTTP client requests.", + explicit_bucket_boundaries_advisory=HTTP_DURATION_HISTOGRAM_BUCKETS_NEW, + ) + + excluded_urls = get_excluded_urls("AIOHTTP_CLIENT") + + def _end_trace(trace_config_ctx: types.SimpleNamespace): + elapsed_time = max(default_timer() - trace_config_ctx.start_time, 0) + if trace_config_ctx.token: + context_api.detach(trace_config_ctx.token) + if trace_config_ctx.span: + trace_config_ctx.span.end() + + if trace_config_ctx.duration_histogram_old is not None: + duration_attrs_old = cast( + dict[str, Any], + _filter_semconv_duration_attrs( + trace_config_ctx.metric_attributes, + _client_duration_attrs_old, + _client_duration_attrs_new, + _StabilityMode.DEFAULT, + ), + ) + trace_config_ctx.duration_histogram_old.record( + max(round(elapsed_time * 1000), 0), + attributes=duration_attrs_old, + ) + if trace_config_ctx.duration_histogram_new is not None: + duration_attrs_new = cast( + dict[str, Any], + _filter_semconv_duration_attrs( + trace_config_ctx.metric_attributes, + _client_duration_attrs_old, + _client_duration_attrs_new, + _StabilityMode.HTTP, + ), + ) + trace_config_ctx.duration_histogram_new.record(elapsed_time, attributes=duration_attrs_new) + + async def on_request_start( + _session: aiohttp.ClientSession, + trace_config_ctx: types.SimpleNamespace, + params: aiohttp.TraceRequestStartParams, + ): + if not is_http_instrumentation_enabled() or trace_config_ctx.excluded_urls.url_disabled(str(params.url)): + return + + trace_config_ctx.start_time = default_timer() + method = params.method + request_span_name = _get_span_name(method) + request_url = ( + redact_url(cast(Callable[[yarl.URL], str], trace_config_ctx.url_filter)(params.url)) + if callable(trace_config_ctx.url_filter) + else redact_url(str(params.url)) + ) + + span_attributes: dict[str, Any] = {} + _set_http_method( + span_attributes, + method, + sanitize_method(method), + sem_conv_opt_in_mode, + ) + _set_http_method( + trace_config_ctx.metric_attributes, + method, + sanitize_method(method), + sem_conv_opt_in_mode, + ) + _set_http_url(span_attributes, request_url, sem_conv_opt_in_mode) + + try: + parsed_url = urlparse(request_url) + if parsed_url.hostname: + _set_http_host_client( + trace_config_ctx.metric_attributes, + parsed_url.hostname, + sem_conv_opt_in_mode, + ) + _set_http_net_peer_name_client( + trace_config_ctx.metric_attributes, + parsed_url.hostname, + sem_conv_opt_in_mode, + ) + if _report_new(sem_conv_opt_in_mode): + _set_http_host_client( + span_attributes, + parsed_url.hostname, + sem_conv_opt_in_mode, + ) + if parsed_url.port: + _set_http_peer_port_client( + trace_config_ctx.metric_attributes, + parsed_url.port, + sem_conv_opt_in_mode, + ) + if _report_new(sem_conv_opt_in_mode): + _set_http_peer_port_client(span_attributes, parsed_url.port, sem_conv_opt_in_mode) + except ValueError: + pass + + span_attributes.update( + get_custom_header_attributes( + {key: params.headers.getall(key) for key in params.headers.keys()}, + captured_request_headers, + sensitive_headers, + normalise_request_header_name, + ) + ) + + trace_config_ctx.span = trace_config_ctx.tracer.start_span( + request_span_name, kind=SpanKind.CLIENT, attributes=span_attributes + ) + + if callable(request_hook): + request_hook(trace_config_ctx.span, params) + + trace_config_ctx.token = context_api.attach(trace.set_span_in_context(trace_config_ctx.span)) + + inject(params.headers) + + async def on_request_end( + _session: aiohttp.ClientSession, + trace_config_ctx: types.SimpleNamespace, + params: aiohttp.TraceRequestEndParams, + ): + if trace_config_ctx.span is None: + return + + if callable(response_hook): + response_hook(trace_config_ctx.span, params) + _set_http_status_code_attribute( + trace_config_ctx.span, + params.response.status, + trace_config_ctx.metric_attributes, + sem_conv_opt_in_mode, + ) + + trace_config_ctx.span.set_attributes( + get_custom_header_attributes( + {key: params.response.headers.getall(key) for key in params.response.headers.keys()}, + captured_response_headers, + sensitive_headers, + normalise_response_header_name, + ) + ) + + _end_trace(trace_config_ctx) + + async def on_request_exception( + _session: aiohttp.ClientSession, + trace_config_ctx: types.SimpleNamespace, + params: aiohttp.TraceRequestExceptionParams, + ): + if trace_config_ctx.span is None: + return + + if trace_config_ctx.span.is_recording() and params.exception: + exc_type = type(params.exception).__qualname__ + if _report_new(sem_conv_opt_in_mode): + trace_config_ctx.span.set_attribute(ERROR_TYPE, exc_type) + trace_config_ctx.metric_attributes[ERROR_TYPE] = exc_type + + trace_config_ctx.span.set_status(Status(StatusCode.ERROR, exc_type)) + trace_config_ctx.span.record_exception(params.exception) + + if callable(response_hook): + response_hook(trace_config_ctx.span, params) + + _end_trace(trace_config_ctx) + + def _trace_config_ctx_factory(**kwargs: Any) -> types.SimpleNamespace: + kwargs.setdefault("trace_request_ctx", {}) + return types.SimpleNamespace( + tracer=tracer, + span=None, + token=None, + duration_histogram_old=duration_histogram_old, + duration_histogram_new=duration_histogram_new, + metric_attributes={}, + url_filter=url_filter, + excluded_urls=excluded_urls, + start_time=0, + **kwargs, + ) + + trace_config = aiohttp.TraceConfig( + trace_config_ctx_factory=cast(type[types.SimpleNamespace], _trace_config_ctx_factory) + ) + + trace_config.on_request_start.append(on_request_start) + trace_config.on_request_end.append(on_request_end) + trace_config.on_request_exception.append(on_request_exception) + + return trace_config + + +def _instrument( + tracer_provider: TracerProvider | None = None, + meter_provider: MeterProvider | None = None, + url_filter: UrlFilterT = None, + request_hook: RequestHookT = None, + response_hook: ResponseHookT = None, + trace_configs: typing.Sequence[aiohttp.TraceConfig] | None = None, + sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, + captured_request_headers: list[str] | None = None, + captured_response_headers: list[str] | None = None, + sensitive_headers: list[str] | None = None, +): + """Enables tracing of all ClientSessions + + When a ClientSession gets created a TraceConfig is automatically added to + the session's trace_configs. + """ + + trace_configs = trace_configs or () + + # pylint:disable=unused-argument + def instrumented_init( + wrapped: Callable[..., None], + _instance: aiohttp.ClientSession, + args: tuple[Any, ...], + kwargs: ClientSessionInitKwargs, + ): + client_trace_configs = list(kwargs.get("trace_configs") or []) + client_trace_configs.extend(trace_configs) + + trace_config = create_trace_config( + url_filter=url_filter, + request_hook=request_hook, + response_hook=response_hook, + tracer_provider=tracer_provider, + meter_provider=meter_provider, + sem_conv_opt_in_mode=sem_conv_opt_in_mode, + captured_request_headers=captured_request_headers, + captured_response_headers=captured_response_headers, + sensitive_headers=sensitive_headers, + ) + setattr(trace_config, "_is_instrumented_by_opentelemetry", True) + client_trace_configs.append(trace_config) + + kwargs["trace_configs"] = client_trace_configs + return wrapped(*args, **kwargs) + + wrapt.wrap_function_wrapper( # type: ignore[reportUnknownVariableType] + aiohttp.ClientSession, "__init__", instrumented_init + ) + + +def _uninstrument(): + """Disables instrumenting for all newly created ClientSessions""" + unwrap(aiohttp.ClientSession, "__init__") + + +def _uninstrument_session(client_session: aiohttp.ClientSession): + """Disables instrumentation for the given ClientSession""" + # pylint: disable=protected-access + trace_configs = client_session._trace_configs + client_session._trace_configs = [ + trace_config for trace_config in trace_configs if not hasattr(trace_config, "_is_instrumented_by_opentelemetry") + ] + + +class AioHttpClientInstrumentor(BaseInstrumentor): + """An instrumentor for aiohttp client sessions + + See `BaseInstrumentor` + """ + + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments + + def _instrument(self, **kwargs: Unpack[InstrumentKwargs]): + """Instruments aiohttp ClientSession + + Args: + **kwargs: Optional arguments + ``tracer_provider``: a TracerProvider, defaults to global + ``meter_provider``: a MeterProvider, defaults to global + ``url_filter``: A callback to process the requested URL prior to adding + it as a span attribute. This can be useful to remove sensitive data + such as API keys or user personal information. + ``request_hook``: An optional callback that is invoked right after a span is created. + ``response_hook``: An optional callback which is invoked right before the span is finished processing a response. + ``trace_configs``: An optional list of aiohttp.TraceConfig items, allowing customize enrichment of spans + based on aiohttp events (see specification: https://docs.aiohttp.org/en/stable/tracing_reference.html) + """ + _OpenTelemetrySemanticConventionStability._initialize() + _sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( + _OpenTelemetryStabilitySignalType.HTTP, + ) + _instrument( + tracer_provider=kwargs.get("tracer_provider"), + meter_provider=kwargs.get("meter_provider"), + url_filter=kwargs.get("url_filter"), + request_hook=kwargs.get("request_hook"), + response_hook=kwargs.get("response_hook"), + trace_configs=kwargs.get("trace_configs"), + sem_conv_opt_in_mode=_sem_conv_opt_in_mode, + captured_request_headers=get_custom_headers(OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST), + captured_response_headers=get_custom_headers(OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE), + sensitive_headers=get_custom_headers(OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS), + ) + + def _uninstrument(self, **kwargs: Unpack[UninstrumentKwargs]): + _uninstrument() + + @staticmethod + def uninstrument_session(client_session: aiohttp.ClientSession): + """Disables instrumentation for the given session""" + _uninstrument_session(client_session) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py new file mode 100644 index 00000000000..0e356f89fb4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +_instruments = ("aiohttp ~= 3.0",) + +_supports_metrics = True + +_semconv_status = "migration" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py new file mode 100644 index 00000000000..d5728026249 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py @@ -0,0 +1,168 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from argparse import REMAINDER, ArgumentParser +from logging import getLogger +from os import environ, execl, getcwd +from os.path import abspath, dirname, pathsep +from re import sub +from shutil import which + +from opentelemetry.agent._vendor.opentelemetry.instrumentation.auto_instrumentation._load import ( + _load_configurators, + _load_distro, + _load_instrumentors, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.environment_variables import ( + OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import _python_path_without_directory +from opentelemetry.agent._vendor.opentelemetry.instrumentation.version import __version__ +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points + +_logger = getLogger(__name__) + + +def run() -> None: + parser = ArgumentParser( + description=""" + opentelemetry-instrument automatically instruments a Python + program and its dependencies and then runs the program. + """, + epilog=""" + Optional arguments (except for --help and --version) for opentelemetry-instrument + directly correspond with OpenTelemetry environment variables. The + corresponding optional argument is formed by removing the OTEL_ or + OTEL_PYTHON_ prefix from the environment variable and lower casing the + rest. For example, the optional argument --attribute_value_length_limit + corresponds with the environment variable + OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT. + + These optional arguments will override the current value of the + corresponding environment variable during the execution of the command. + """, + ) + + argument_otel_environment_variable = {} + + for entry_point in entry_points(group="opentelemetry_environment_variables"): + environment_variable_module = entry_point.load() + + for attribute in dir(environment_variable_module): + if attribute.startswith("OTEL_"): + argument = sub(r"OTEL_(PYTHON_)?", "", attribute).lower() + + parser.add_argument( + f"--{argument}", + required=False, + ) + argument_otel_environment_variable[argument] = attribute + + parser.add_argument( + "--version", + help="print version information", + action="version", + version="%(prog)s " + __version__, + ) + parser.add_argument("command", help="Your Python application.") + parser.add_argument( + "command_args", + help="Arguments for your application.", + nargs=REMAINDER, + ) + + args = parser.parse_args() + + for argument, otel_environment_variable in (argument_otel_environment_variable).items(): + value = getattr(args, argument) + if value is not None: + environ[otel_environment_variable] = value + + python_path = environ.get("PYTHONPATH") + + if not python_path: + python_path = [] + + else: + python_path = python_path.split(pathsep) + + cwd_path = getcwd() + + # This is being added to support applications that are being run from their + # own executable, like Django. + # FIXME investigate if there is another way to achieve this + if cwd_path not in python_path: + python_path.insert(0, cwd_path) + + filedir_path = dirname(abspath(__file__)) + + python_path = [path for path in python_path if path != filedir_path] + + python_path.insert(0, filedir_path) + + environ["PYTHONPATH"] = pathsep.join(python_path) + + executable = which(args.command) + execl(executable, executable, *args.command_args) + + +def _initialize(*, swallow_exceptions: bool = True) -> None: + # handle optional gevent monkey patching. This is done via environment variables so it may be used from the + # opentelemetry operator + gevent_patch: str | None = environ.get(OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH) + if gevent_patch is not None: + if gevent_patch != "patch_all": + _logger.error( + "%s value must be `patch_all`", + OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH, + ) + else: + try: + # pylint: disable=import-outside-toplevel + from gevent import monkey # noqa: PLC0415 + + getattr(monkey, gevent_patch)() + except ImportError: + _logger.exception("Failed to monkey patch with gevent because gevent is not available") + if not swallow_exceptions: + raise + + try: + distro = _load_distro() + distro.configure() + _load_configurators() + _load_instrumentors(distro) + except Exception as exc: # pylint: disable=broad-except + _logger.exception("Failed to auto initialize OpenTelemetry") + if not swallow_exceptions: + raise exc + + +def initialize(*, swallow_exceptions: bool = True) -> None: + """ + Setup auto-instrumentation, called by the sitecustomize module + + :param swallow_exceptions: Whether or not to propagate instrumentation exceptions to the caller. Exceptions are logged and swallowed by default. + """ + filedir = dirname(abspath(__file__)) + + python_path = environ.get("PYTHONPATH") + auto_instrumentation_path_was_present = python_path is not None and filedir in python_path.split(pathsep) + + # Remove the auto-instrumentation path during initialization to prevent + # auto-instrumentation from executing in subprocesses spawned during this phase. + # This suppression is performed to avoid creating a recursive loop scenario + # where subprocesses spawned in the initialization phase execute the + # initialization phase again, spawning more subprocesses. + if python_path is not None: + environ["PYTHONPATH"] = _python_path_without_directory(python_path, filedir, pathsep) + + try: + _initialize(swallow_exceptions=swallow_exceptions) + finally: + if auto_instrumentation_path_was_present: + current = environ.get("PYTHONPATH", "") + if filedir not in current.split(pathsep): + environ["PYTHONPATH"] = filedir + pathsep + current if current else filedir diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py new file mode 100644 index 00000000000..436f2ba88be --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py @@ -0,0 +1,153 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from functools import cached_property +from logging import getLogger +from os import environ + +from opentelemetry.agent._vendor.opentelemetry.instrumentation.dependencies import ( + DependencyConflictError, + get_dist_dependency_conflicts, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.distro import BaseDistro, DefaultDistro +from opentelemetry.agent._vendor.opentelemetry.instrumentation.environment_variables import ( + OTEL_PYTHON_CONFIGURATOR, + OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, + OTEL_PYTHON_DISTRO, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.version import __version__ +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( + EntryPoint, + distributions, + entry_points, +) + +_logger = getLogger(__name__) + +SKIPPED_INSTRUMENTATIONS_WILDCARD = "*" + + +class _EntryPointDistFinder: + @cached_property + def _mapping(self): + return {self._key_for(ep): dist for dist in distributions() for ep in dist.entry_points} + + def dist_for(self, entry_point: EntryPoint): + dist = getattr(entry_point, "dist", None) + if dist: + return dist + + return self._mapping.get(self._key_for(entry_point)) + + @staticmethod + def _key_for(entry_point: EntryPoint): + return f"{entry_point.group}:{entry_point.name}:{entry_point.value}" + + +def _load_distro() -> BaseDistro: + distro_name = environ.get(OTEL_PYTHON_DISTRO, None) + for entry_point in entry_points(group="opentelemetry_distro"): + try: + # If no distro is specified, use first to come up. + if distro_name is None or distro_name == entry_point.name: + distro = entry_point.load()() + if not isinstance(distro, BaseDistro): + _logger.debug( + "%s is not an OpenTelemetry Distro. Skipping", + entry_point.name, + ) + continue + _logger.debug("Distribution %s will be configured", entry_point.name) + return distro + except Exception as exc: # pylint: disable=broad-except + _logger.exception("Distribution %s configuration failed", entry_point.name) + raise exc + return DefaultDistro() + + +def _load_instrumentors(distro): + package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, []) + entry_point_finder = _EntryPointDistFinder() + if isinstance(package_to_exclude, str): + package_to_exclude = package_to_exclude.split(",") + # to handle users entering "requests , flask" or "requests, flask" with spaces + package_to_exclude = [x.strip() for x in package_to_exclude] + + for entry_point in entry_points(group="opentelemetry_pre_instrument"): + entry_point.load()() + + for entry_point in entry_points(group="opentelemetry_instrumentor"): + if SKIPPED_INSTRUMENTATIONS_WILDCARD in package_to_exclude: + break + + if entry_point.name in package_to_exclude: + _logger.debug("Instrumentation skipped for library %s", entry_point.name) + continue + + try: + entry_point_dist = entry_point_finder.dist_for(entry_point) + conflict = get_dist_dependency_conflicts(entry_point_dist) + if conflict: + conflict._log(_logger, entry_point.name) + continue + + # tell instrumentation to not run dep checks again as we already did it above + distro.load_instrumentor(entry_point, skip_dep_check=True) + _logger.debug("Instrumented %s", entry_point.name) + except DependencyConflictError as exc: + # Dependency conflicts are generally caught from get_dist_dependency_conflicts + # returning a DependencyConflict. Keeping this error handling in case custom + # distro and instrumentor behavior raises a DependencyConflictError later. + # See https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610 + exc.conflict._log(_logger, entry_point.name) + continue + except ModuleNotFoundError as exc: + # ModuleNotFoundError is raised when the library is not installed + # and the instrumentation is not required to be loaded. + # See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/3421 + _logger.debug("Skipping instrumentation %s: %s", entry_point.name, exc.msg) + continue + except ImportError: + # in scenarios using the kubernetes operator to do autoinstrumentation some + # instrumentors (usually requiring binary extensions) may fail to load + # because the injected autoinstrumentation code does not match the application + # environment regarding python version, libc, etc... In this case it's better + # to skip the single instrumentation rather than failing to load everything + # so treat differently ImportError than the rest of exceptions + _logger.exception("Importing of %s failed, skipping it", entry_point.name) + continue + except Exception as exc: # pylint: disable=broad-except + _logger.exception("Instrumenting of %s failed", entry_point.name) + raise exc + + for entry_point in entry_points(group="opentelemetry_post_instrument"): + entry_point.load()() + + +def _load_configurators(): + configurator_name = environ.get(OTEL_PYTHON_CONFIGURATOR, None) + configured = None + for entry_point in entry_points(group="opentelemetry_configurator"): + if configured is not None: + _logger.warning( + "Configuration of %s not loaded, %s already loaded", + entry_point.name, + configured, + ) + continue + try: + if configurator_name is None or configurator_name == entry_point.name: + entry_point.load()().configure(auto_instrumentation_version=__version__) # type: ignore + configured = entry_point.name + else: + _logger.warning( + "Configuration of %s not loaded because %s is set by %s", + entry_point.name, + configurator_name, + OTEL_PYTHON_CONFIGURATOR, + ) + except Exception as exc: # pylint: disable=broad-except + _logger.exception("Configuration of %s failed", entry_point.name) + raise exc diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py new file mode 100644 index 00000000000..46407e2987f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py @@ -0,0 +1,6 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.instrumentation.auto_instrumentation import initialize + +initialize() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py new file mode 100644 index 00000000000..29c3c40e522 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py @@ -0,0 +1,166 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import logging +import sys +from subprocess import ( + PIPE, + CalledProcessError, + Popen, + SubprocessError, + check_call, +) + +from opentelemetry.agent._vendor.packaging.requirements import Requirement + +from opentelemetry.agent._vendor.opentelemetry.instrumentation.bootstrap_gen import ( + default_instrumentations as gen_default_instrumentations, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.bootstrap_gen import ( + libraries as gen_libraries, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.version import __version__ +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( + PackageNotFoundError, + version, +) + +logger = logging.getLogger(__name__) + + +def _syscall(func): + def wrapper(package=None): + try: + if package: + return func(package) + return func() + except SubprocessError as exp: + cmd = getattr(exp, "cmd", None) + if cmd: + msg = f'Error calling system command "{" ".join(cmd)}"' + if package: + msg = f'{msg} for package "{package}"' + raise RuntimeError(msg) + + return wrapper + + +@_syscall +def _sys_pip_install(package): + # explicit upgrade strategy to override potential pip config + try: + check_call( + [ + sys.executable, + "-m", + "pip", + "install", + "-U", + "--upgrade-strategy", + "only-if-needed", + package, + ] + ) + except CalledProcessError as error: + print(error) + + +def _pip_check(libraries): + """Ensures none of the instrumentations have dependency conflicts. + Clean check reported as: + 'No broken requirements found.' + Dependency conflicts are reported as: + 'opentelemetry-instrumentation-flask 1.0.1 has requirement opentelemetry-sdk<2.0,>=1.0, but you have opentelemetry-sdk 0.5.' + To not be too restrictive, we'll only check for relevant packages. + """ + with Popen([sys.executable, "-m", "pip", "check"], stdout=PIPE) as check_pipe: + pip_check = check_pipe.communicate()[0].decode() + pip_check_lower = pip_check.lower() + for package_tup in libraries: + for package in package_tup: + if package.lower() in pip_check_lower: + raise RuntimeError(f"Dependency conflict found: {pip_check}") + + +def _is_installed(req): + req = Requirement(req) + + try: + dist_version = version(req.name) + except PackageNotFoundError: + return False + + if not req.specifier.filter(dist_version): + logger.warning( + "instrumentation for package %s is available but version %s is installed. Skipping.", + req, + dist_version, + ) + return False + return True + + +def _find_installed_libraries(default_instrumentations, libraries): + yield from default_instrumentations + + for lib in libraries: + if _is_installed(lib["library"]): + yield lib["instrumentation"] + + +def _run_requirements(default_instrumentations, libraries): + logger.setLevel(logging.ERROR) + print("\n".join(_find_installed_libraries(default_instrumentations, libraries))) + + +def _run_install(default_instrumentations, libraries): + for lib in _find_installed_libraries(default_instrumentations, libraries): + _sys_pip_install(lib) + _pip_check(libraries) + + +def run( + default_instrumentations: list | None = None, + libraries: list | None = None, +) -> None: + action_install = "install" + action_requirements = "requirements" + + parser = argparse.ArgumentParser( + description=""" + opentelemetry-bootstrap detects installed libraries and automatically + installs the relevant instrumentation packages for them. + """ + ) + parser.add_argument( + "--version", + help="print version information", + action="version", + version="%(prog)s " + __version__, + ) + parser.add_argument( + "-a", + "--action", + choices=[action_install, action_requirements], + default=action_requirements, + help=""" + install - uses pip to install the new requirements using to the + currently active site-package. + requirements - prints out the new requirements to stdout. Action can + be piped and appended to a requirements.txt file. + """, + ) + args = parser.parse_args() + + if libraries is None: + libraries = gen_libraries + + if default_instrumentations is None: + default_instrumentations = gen_default_instrumentations + + cmd = { + action_install: _run_install, + action_requirements: _run_requirements, + }[args.action] + cmd(default_instrumentations, libraries) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py new file mode 100644 index 00000000000..15959848204 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py @@ -0,0 +1,70 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# DO NOT EDIT. THIS FILE WAS AUTOGENERATED FROM INSTRUMENTATION PACKAGES. +# RUN `python scripts/generate_instrumentation_bootstrap.py` TO REGENERATE. + +libraries = [ + {"library": "openai >= 1.26.0", "instrumentation": "opentelemetry-instrumentation-openai-v2"}, + {"library": "google-cloud-aiplatform >= 1.64", "instrumentation": "opentelemetry-instrumentation-vertexai>=2.0b0"}, + {"library": "aio_pika >= 7.2.0, < 11.0.0", "instrumentation": "opentelemetry-instrumentation-aio-pika==0.66b2"}, + {"library": "aiohttp ~= 3.0", "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.66b2"}, + {"library": "aiohttp ~= 3.0", "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.66b2"}, + {"library": "aiokafka >= 0.8, < 1.0", "instrumentation": "opentelemetry-instrumentation-aiokafka==0.66b2"}, + {"library": "aiopg >= 0.13.0, < 2.0.0", "instrumentation": "opentelemetry-instrumentation-aiopg==0.66b2"}, + {"library": "asgiref ~= 3.0", "instrumentation": "opentelemetry-instrumentation-asgi==0.66b2"}, + {"library": "asyncclick ~= 8.0", "instrumentation": "opentelemetry-instrumentation-asyncclick==0.66b2"}, + {"library": "asyncpg >= 0.12.0", "instrumentation": "opentelemetry-instrumentation-asyncpg==0.66b2"}, + {"library": "boto3 ~= 1.0", "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.66b2"}, + {"library": "botocore ~= 1.0", "instrumentation": "opentelemetry-instrumentation-botocore==0.66b2"}, + {"library": "aiobotocore >= 2.0, < 4.0", "instrumentation": "opentelemetry-instrumentation-botocore==0.66b2"}, + {"library": "cassandra-driver ~= 3.25", "instrumentation": "opentelemetry-instrumentation-cassandra==0.66b2"}, + {"library": "scylla-driver ~= 3.25", "instrumentation": "opentelemetry-instrumentation-cassandra==0.66b2"}, + {"library": "celery >= 4.0, < 6.0", "instrumentation": "opentelemetry-instrumentation-celery==0.66b2"}, + {"library": "click >= 8.1.3, < 9.0.0", "instrumentation": "opentelemetry-instrumentation-click==0.66b2"}, + { + "library": "confluent-kafka >= 1.8.2, < 3.0.0", + "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.66b2", + }, + {"library": "django >= 2.0", "instrumentation": "opentelemetry-instrumentation-django==0.66b2"}, + {"library": "falcon >= 1.4.1, < 5.0.0", "instrumentation": "opentelemetry-instrumentation-falcon==0.66b2"}, + {"library": "fastapi ~= 0.92", "instrumentation": "opentelemetry-instrumentation-fastapi==0.66b2"}, + {"library": "flask >= 1.0", "instrumentation": "opentelemetry-instrumentation-flask==0.66b2"}, + {"library": "grpcio >= 1.42.0", "instrumentation": "opentelemetry-instrumentation-grpc==0.66b2"}, + {"library": "httpx >= 0.18.0", "instrumentation": "opentelemetry-instrumentation-httpx==0.66b2"}, + {"library": "httpx2 >= 2.0.0", "instrumentation": "opentelemetry-instrumentation-httpx==0.66b2"}, + {"library": "jinja2 >= 2.7, < 4.0", "instrumentation": "opentelemetry-instrumentation-jinja2==0.66b2"}, + {"library": "kafka-python >= 2.0, < 4.0", "instrumentation": "opentelemetry-instrumentation-kafka-python==0.66b2"}, + {"library": "mysql-connector-python >= 8.0", "instrumentation": "opentelemetry-instrumentation-mysql==0.66b2"}, + {"library": "mysqlclient < 3", "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.66b2"}, + {"library": "pika >= 0.12.0", "instrumentation": "opentelemetry-instrumentation-pika==0.66b2"}, + {"library": "psycopg >= 3.1.0", "instrumentation": "opentelemetry-instrumentation-psycopg==0.66b2"}, + {"library": "psycopg2 >= 2.7.3.1", "instrumentation": "opentelemetry-instrumentation-psycopg2==0.66b2"}, + {"library": "psycopg2-binary >= 2.7.3.1", "instrumentation": "opentelemetry-instrumentation-psycopg2==0.66b2"}, + {"library": "pymemcache >= 1.3.5, < 5", "instrumentation": "opentelemetry-instrumentation-pymemcache==0.66b2"}, + {"library": "pymongo >= 3.1, < 5.0", "instrumentation": "opentelemetry-instrumentation-pymongo==0.66b2"}, + {"library": "pymssql >= 2.1.5, < 3", "instrumentation": "opentelemetry-instrumentation-pymssql==0.66b2"}, + {"library": "PyMySQL < 2", "instrumentation": "opentelemetry-instrumentation-pymysql==0.66b2"}, + {"library": "pyramid >= 1.7", "instrumentation": "opentelemetry-instrumentation-pyramid==0.66b2"}, + {"library": "redis >= 2.6", "instrumentation": "opentelemetry-instrumentation-redis==0.66b2"}, + {"library": "remoulade >= 0.50", "instrumentation": "opentelemetry-instrumentation-remoulade==0.66b2"}, + {"library": "requests ~= 2.0", "instrumentation": "opentelemetry-instrumentation-requests==0.66b2"}, + {"library": "sqlalchemy >= 1.0.0, < 2.1.0", "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.66b2"}, + {"library": "starlette >= 0.13", "instrumentation": "opentelemetry-instrumentation-starlette==0.66b2"}, + {"library": "structlog >= 21.1", "instrumentation": "opentelemetry-instrumentation-structlog==0.66b2"}, + {"library": "psutil >= 5", "instrumentation": "opentelemetry-instrumentation-system-metrics==0.66b2"}, + {"library": "tornado >= 5.1.1", "instrumentation": "opentelemetry-instrumentation-tornado==0.66b2"}, + {"library": "tortoise-orm >= 0.17.0", "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.66b2"}, + {"library": "pydantic >= 1.10.2", "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.66b2"}, + {"library": "urllib3 >= 1.0.0, < 3.0.0", "instrumentation": "opentelemetry-instrumentation-urllib3==0.66b2"}, +] +default_instrumentations = [ + "opentelemetry-instrumentation-asyncio==0.66b2", + "opentelemetry-instrumentation-dbapi==0.66b2", + "opentelemetry-instrumentation-exceptions==0.66b2", + "opentelemetry-instrumentation-logging==0.66b2", + "opentelemetry-instrumentation-sqlite3==0.66b2", + "opentelemetry-instrumentation-threading==0.66b2", + "opentelemetry-instrumentation-urllib==0.66b2", + "opentelemetry-instrumentation-wsgi==0.66b2", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py new file mode 100644 index 00000000000..86814840a72 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py @@ -0,0 +1,71 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Iterable, Iterator, Mapping, MutableMapping +from typing import ( + Any, + TypeVar, +) + +KT = TypeVar("KT") +VT = TypeVar("VT") + + +class CIDict(MutableMapping[KT, VT]): + def __init__( + self, + data: Mapping[KT, VT] | Iterable[tuple[KT, VT]] | None = None, + ) -> None: + self._data: dict[KT, tuple[KT, VT]] = {} + if data is None: + data = {} + self.update(data) + + @staticmethod + def _normalize_key(key: KT) -> KT: + if isinstance(key, str): + return key.lower() # type: ignore + return key + + def _get_entry(self, key: KT) -> tuple[KT, VT]: + normalized_key = self._normalize_key(key) + if normalized_key in self._data: + return self._data[normalized_key] + raise KeyError(repr(key)) + + def original_key(self, key: KT) -> KT: + return self._get_entry(key)[0] + + def normalized_items(self) -> Iterable[tuple[KT, VT]]: + return ((key, value[1]) for key, value in self._data.items()) + + def __setitem__(self, key: KT, value: VT, /) -> None: + self._data[self._normalize_key(key)] = (key, value) + + def __delitem__(self, key: KT, /) -> None: + try: + del self._data[self._normalize_key(key)] + except KeyError: + raise KeyError(repr(key)) from None + + def __getitem__(self, key: KT, /) -> VT: + return self._get_entry(key)[1] + + def __len__(self) -> int: + return len(self._data) + + def __iter__(self) -> Iterator[KT]: + return (key for key, _ in self._data.values()) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({dict(self.items())!r})" + + def __eq__(self, other: object) -> bool: + if isinstance(other, CIDict): + return dict(self.normalized_items()) == dict(other.normalized_items()) + if not isinstance(other, Mapping): + return False + ciother: CIDict[Any, Any] = CIDict(other) + return dict(self.normalized_items()) == dict(ciother.normalized_items()) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py new file mode 100644 index 00000000000..9620154134c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py @@ -0,0 +1,209 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Collection +from logging import Logger, getLogger + +from opentelemetry.agent._vendor.packaging.requirements import InvalidRequirement, Requirement + +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( + Distribution, + PackageNotFoundError, + version, +) + +_logger = getLogger(__name__) + + +def _format_deps(deps: Collection[str]) -> str: + return ", ".join(str(dep) for dep in deps) + + +class DependencyConflict: + """Represents a dependency conflict in OpenTelemetry instrumentation. + + This class is used to track conflicts between required dependencies and the + actual installed packages. It supports two scenarios: + + 1. Standard conflicts where all dependencies are required + 2. Either/or conflicts where only one of a set of dependencies is required + + Attributes: + required: The required dependency specification that conflicts with what's installed. + found: The actual dependency that was found installed (if any). + required_any: Collection of dependency specifications where any one would satisfy + the requirement (for either/or scenarios). + found_any: Collection of actual dependencies found for either/or scenarios. + """ + + required: str | None = None + found: str | None = None + # The following fields are used when an instrumentation requires any of a set of dependencies rather than all. + required_any: Collection[str] = None + found_any: Collection[str] = None + + def __init__( + self, + required: str | None = None, + found: str | None = None, + required_any: Collection[str] = None, + found_any: Collection[str] = None, + ): + self.required = required + self.found = found + # The following fields are used when an instrumentation requires any of a set of dependencies rather than all. + self.required_any = required_any + self.found_any = found_any + + @property + def _is_version_conflict(self) -> bool: + """False when the dependency is not installed at all, rather than installed at an incompatible version.""" + return bool(self.found or self.found_any) + + def _log(self, logger: Logger, instrumentor_name: str) -> None: + """Log as an error for a version conflict, at debug level when the dependency is not installed.""" + log = logger.error if self._is_version_conflict else logger.debug + log(self._format_message(instrumentor_name)) + + def _format_message(self, instrumentor_name: str | None = None) -> str: + subject = instrumentor_name or "This instrumentation" + if self.required: + if self.found: + return ( + f'{subject} only instruments "{self.required}", ' + f'but currently installed version ("{self.found}") falls outside of that range, ' + f"so nothing can be instrumented." + ) + return ( + f'{subject} only instruments "{self.required}", ' + f"but no installed version was found, so nothing can be instrumented." + ) + if self.required_any: + if self.found_any: + return ( + f'{subject} instruments any of "{_format_deps(self.required_any)}", ' + f'but currently installed version(s) ("{_format_deps(self.found_any)}") fall outside of that range, ' + f"so nothing can be instrumented." + ) + return ( + f'{subject} requires any of "{_format_deps(self.required_any)}", ' + f"but none are installed, so nothing can be instrumented." + ) + return f"{subject} has an unknown dependency conflict, so nothing can be instrumented." + + def __str__(self): + return self._format_message() + + +class DependencyConflictError(Exception): + conflict: DependencyConflict + + def __init__(self, conflict: DependencyConflict): + self.conflict = conflict + + def __str__(self): + return str(self.conflict) + + +def get_dist_dependency_conflicts( + dist: Distribution, +) -> DependencyConflict | None: + instrumentation_deps = [] + instrumentation_any_deps = [] + extra = "extra" + instruments = "instruments" + instruments_marker = {extra: instruments} + instruments_any = "instruments-any" + instruments_any_marker = {extra: instruments_any} + if dist.requires: + for dep in dist.requires: + if extra not in dep: + continue + if instruments not in dep and instruments_any not in dep: + continue + + req = Requirement(dep) + if req.marker.evaluate(instruments_marker): # type: ignore + instrumentation_deps.append(req) # type: ignore + if req.marker.evaluate(instruments_any_marker): # type: ignore + instrumentation_any_deps.append(req) # type: ignore + return get_dependency_conflicts(instrumentation_deps, instrumentation_any_deps) # type: ignore + + +def get_dependency_conflicts( + deps: Collection[str | Requirement], # Dependencies all of which are required + deps_any: Collection[str | Requirement] | None = None, # Dependencies any of which are required +) -> DependencyConflict | None: + for dep in deps: + if isinstance(dep, Requirement): + req = dep + else: + try: + req = Requirement(dep) + except InvalidRequirement as exc: + _logger.warning( + 'error parsing dependency, reporting as a conflict: "%s" - %s', + dep, + exc, + ) + return DependencyConflict(dep) + + try: + dist_version = version(req.name) + except PackageNotFoundError: + return DependencyConflict(dep) + + if not req.specifier.contains(dist_version): + return DependencyConflict(dep, f"{req.name} {dist_version}") + + # If all the dependencies in "instruments" are present, check "instruments-any" for conflicts. + if deps_any: + return _get_dependency_conflicts_any(deps_any) + return None + + +# This is a helper functions designed to ease reading and meet linting requirements. +def _get_dependency_conflicts_any( + deps_any: Collection[str | Requirement], +) -> DependencyConflict | None: + if not deps_any: + return None + is_dependency_conflict = True + required_any: Collection[str] = [] + found_any: Collection[str] = [] + for dep in deps_any: + if isinstance(dep, Requirement): + req = dep + else: + try: + req = Requirement(dep) + except InvalidRequirement as exc: + _logger.warning( + 'error parsing dependency, reporting as a conflict: "%s" - %s', + dep, + exc, + ) + return DependencyConflict(dep) + + try: + dist_version = version(req.name) + except PackageNotFoundError: + required_any.append(str(dep)) + continue + + if req.specifier.contains(dist_version): + # Since only one of the instrumentation_any dependencies is required, there is no dependency conflict. + is_dependency_conflict = False + break + # If the version does not match, add it to the list of unfulfilled requirement options. + required_any.append(str(dep)) + found_any.append(f"{req.name} {dist_version}") + + if is_dependency_conflict: + return DependencyConflict( + required_any=required_any, + found_any=found_any, + ) + return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py new file mode 100644 index 00000000000..d9b259e9ca6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py @@ -0,0 +1,59 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# type: ignore + +""" +OpenTelemetry Base Distribution (Distro) +""" + +from abc import ABC, abstractmethod +from logging import getLogger + +from opentelemetry.agent._vendor.opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import EntryPoint + +_LOG = getLogger(__name__) + + +class BaseDistro(ABC): + """An ABC for distro""" + + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = object.__new__(cls, *args, **kwargs) + + return cls._instance + + @abstractmethod + def _configure(self, **kwargs): + """Configure the distribution""" + + def configure(self, **kwargs): + """Configure the distribution""" + self._configure(**kwargs) + + def load_instrumentor( # pylint: disable=no-self-use + self, entry_point: EntryPoint, **kwargs + ): + """Takes an instrumentation entry point and activates it by instantiating + and calling instrument() on it. + This is called for each opentelemetry_instrumentor entry point by auto + instrumentation. + + Distros can override this method to customize the behavior by + inspecting each entry point and configuring them in special ways, + passing additional arguments, load a replacement/fork instead, + skip loading entirely, etc. + """ + instrumentor: BaseInstrumentor = entry_point.load() + instrumentor().instrument(**kwargs) + + +class DefaultDistro(BaseDistro): + def _configure(self, **kwargs): + pass + + +__all__ = ["BaseDistro", "DefaultDistro"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py new file mode 100644 index 00000000000..27773aadb7c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py @@ -0,0 +1,32 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +OTEL_PYTHON_DISABLED_INSTRUMENTATIONS = "OTEL_PYTHON_DISABLED_INSTRUMENTATIONS" +""" +.. envvar:: OTEL_PYTHON_DISABLED_INSTRUMENTATIONS +""" + +OTEL_PYTHON_DISTRO = "OTEL_PYTHON_DISTRO" +""" +.. envvar:: OTEL_PYTHON_DISTRO +""" + +OTEL_PYTHON_CONFIGURATOR = "OTEL_PYTHON_CONFIGURATOR" +""" +.. envvar:: OTEL_PYTHON_CONFIGURATOR +""" + +OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH = ( + "OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH" +) +""" +.. envvar:: OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH +""" + +OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" +""" +.. envvar:: OTEL_SEMCONV_STABILITY_OPT_IN + +Opt-in to stable semantic convention signals. +Comma-separated list of signals, e.g. ``http``, ``http/dup``. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py new file mode 100644 index 00000000000..e99d86f2e9b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py @@ -0,0 +1,136 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# type: ignore + +""" +OpenTelemetry Base Instrumentor +""" + +from __future__ import annotations + +from abc import ABC, abstractmethod +from collections.abc import Collection +from logging import getLogger +from typing import Any + +from opentelemetry.agent._vendor.opentelemetry.instrumentation._semconv import ( + _OpenTelemetrySemanticConventionStability, +) +from opentelemetry.agent._vendor.opentelemetry.instrumentation.dependencies import ( + DependencyConflict, + DependencyConflictError, + get_dependency_conflicts, +) + +_LOG = getLogger(__name__) + + +class BaseInstrumentor(ABC): + """An ABC for instrumentors. + + Child classes of this ABC should instrument specific third + party libraries or frameworks either by using the + ``opentelemetry-instrument`` command or by calling their methods + directly. + + Since every third party library or framework is different and has different + instrumentation needs, more methods can be added to the child classes as + needed to provide practical instrumentation to the end user. + """ + + _instance = None + _is_instrumented_by_opentelemetry = False + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = object.__new__(cls) + + return cls._instance + + @property + def is_instrumented_by_opentelemetry(self): + return self._is_instrumented_by_opentelemetry + + @abstractmethod + def instrumentation_dependencies(self) -> Collection[str]: + """Return a list of python packages with versions that the will be instrumented. + + The format should be the same as used in requirements.txt or pyproject.toml. + + For example, if an instrumentation instruments requests 1.x, this method should look + like: + + def instrumentation_dependencies(self) -> Collection[str]: + return ['requests ~= 1.0'] + + This will ensure that the instrumentation will only be used when the specified library + is present in the environment. + """ + + def _instrument(self, **kwargs: Any): + """Instrument the library""" + + @abstractmethod + def _uninstrument(self, **kwargs: Any): + """Uninstrument the library""" + + def _check_dependency_conflicts(self) -> DependencyConflict | None: + dependencies = self.instrumentation_dependencies() + return get_dependency_conflicts(dependencies) + + def instrument(self, **kwargs: Any): + """Instrument the library + + This method will be called without any optional arguments by the + ``opentelemetry-instrument`` command. + + This means that calling this method directly without passing any + optional values should do the very same thing that the + ``opentelemetry-instrument`` command does. + """ + + if self._is_instrumented_by_opentelemetry: + _LOG.warning("Attempting to instrument while already instrumented") + return None + + # check if instrumentor has any missing or conflicting dependencies + skip_dep_check = kwargs.pop("skip_dep_check", False) + raise_exception_on_conflict = kwargs.pop("raise_exception_on_conflict", False) + if not skip_dep_check: + conflict = self._check_dependency_conflicts() + if conflict: + # auto-instrumentation path: don't log conflict as error, instead + # let _load_instrumentors handle the exception + if raise_exception_on_conflict: + raise DependencyConflictError(conflict) + # manual instrumentation path: log the conflict as error + _LOG.error(conflict._format_message(self.__class__.__name__)) + return None + + # initialize semantic conventions opt-in if needed + _OpenTelemetrySemanticConventionStability._initialize() + + result = self._instrument( # pylint: disable=assignment-from-no-return + **kwargs + ) + self._is_instrumented_by_opentelemetry = True + return result + + def uninstrument(self, **kwargs: Any): + """Uninstrument the library + + See ``BaseInstrumentor.instrument`` for more information regarding the + usage of ``kwargs``. + """ + + if self._is_instrumented_by_opentelemetry: + result = self._uninstrument(**kwargs) + self._is_instrumented_by_opentelemetry = False + return result + + _LOG.warning("Attempting to uninstrument while already uninstrumented") + + return None + + +__all__ = ["BaseInstrumentor"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py new file mode 100644 index 00000000000..df0bc280f69 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py @@ -0,0 +1,65 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry._logs import SeverityNumber + +_STD_TO_OTEL = { + 10: SeverityNumber.DEBUG, + 11: SeverityNumber.DEBUG2, + 12: SeverityNumber.DEBUG3, + 13: SeverityNumber.DEBUG4, + 14: SeverityNumber.DEBUG4, + 15: SeverityNumber.DEBUG4, + 16: SeverityNumber.DEBUG4, + 17: SeverityNumber.DEBUG4, + 18: SeverityNumber.DEBUG4, + 19: SeverityNumber.DEBUG4, + 20: SeverityNumber.INFO, + 21: SeverityNumber.INFO2, + 22: SeverityNumber.INFO3, + 23: SeverityNumber.INFO4, + 24: SeverityNumber.INFO4, + 25: SeverityNumber.INFO4, + 26: SeverityNumber.INFO4, + 27: SeverityNumber.INFO4, + 28: SeverityNumber.INFO4, + 29: SeverityNumber.INFO4, + 30: SeverityNumber.WARN, + 31: SeverityNumber.WARN2, + 32: SeverityNumber.WARN3, + 33: SeverityNumber.WARN4, + 34: SeverityNumber.WARN4, + 35: SeverityNumber.WARN4, + 36: SeverityNumber.WARN4, + 37: SeverityNumber.WARN4, + 38: SeverityNumber.WARN4, + 39: SeverityNumber.WARN4, + 40: SeverityNumber.ERROR, + 41: SeverityNumber.ERROR2, + 42: SeverityNumber.ERROR3, + 43: SeverityNumber.ERROR4, + 44: SeverityNumber.ERROR4, + 45: SeverityNumber.ERROR4, + 46: SeverityNumber.ERROR4, + 47: SeverityNumber.ERROR4, + 48: SeverityNumber.ERROR4, + 49: SeverityNumber.ERROR4, + 50: SeverityNumber.FATAL, + 51: SeverityNumber.FATAL2, + 52: SeverityNumber.FATAL3, + 53: SeverityNumber.FATAL4, +} + + +def std_to_otel(levelno: int) -> SeverityNumber: + """ + Map a Python log level number as defined in + https://docs.python.org/3/library/logging.html#logging-levels + to an OTel log severity number as defined in + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber + """ + if levelno < 10: + return SeverityNumber.UNSPECIFIED + if levelno > 53: + return SeverityNumber.FATAL4 + return _STD_TO_OTEL[levelno] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py new file mode 100644 index 00000000000..b405ae801e7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py @@ -0,0 +1,113 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +This module implements experimental propagators to inject trace context +into response carriers. This is useful for server side frameworks that start traces +when server requests and want to share the trace context with the client so the +client can add its spans to the same trace. + +This is part of an upcoming W3C spec and will eventually make it to the Otel spec. + +https://w3c.github.io/trace-context/#trace-context-http-response-headers-format +""" + +from abc import ABC, abstractmethod + +from opentelemetry.agent._vendor.opentelemetry import trace +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.propagators import textmap +from opentelemetry.agent._vendor.opentelemetry.trace import format_span_id, format_trace_id + +_HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers" +_RESPONSE_PROPAGATOR = None + + +def get_global_response_propagator(): + return _RESPONSE_PROPAGATOR + + +def set_global_response_propagator(propagator): + global _RESPONSE_PROPAGATOR # pylint:disable=global-statement + _RESPONSE_PROPAGATOR = propagator + + +class Setter(ABC): + @abstractmethod + def set(self, carrier, key, value): + """Inject the provided key value pair in carrier.""" + + +class DictHeaderSetter(Setter): + def set(self, carrier, key, value): # pylint: disable=no-self-use + old_value = carrier.get(key, "") + if old_value: + value = f"{old_value}, {value}" + carrier[key] = value + + +class FuncSetter(Setter): + """FuncSetter converts a function into a valid Setter. Any function that + can set values in a carrier can be converted into a Setter by using + FuncSetter. This is useful when injecting trace context into non-dict + objects such HTTP Response objects for different framework. + + For example, it can be used to create a setter for Falcon response object + as: + + setter = FuncSetter(falcon.api.Response.append_header) + + and then used with the propagator as: + + propagator.inject(falcon_response, setter=setter) + + This would essentially make the propagator call `falcon_response.append_header(key, value)` + """ + + def __init__(self, func): + self._func = func + + def set(self, carrier, key, value): + self._func(carrier, key, value) + + +default_setter = DictHeaderSetter() + + +class ResponsePropagator(ABC): + @abstractmethod + def inject( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + setter: textmap.Setter = default_setter, + ) -> None: + """Injects SpanContext into the HTTP response carrier.""" + + +class TraceResponsePropagator(ResponsePropagator): + """Experimental propagator that injects tracecontext into HTTP responses.""" + + def inject( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + setter: textmap.Setter = default_setter, + ) -> None: + """Injects SpanContext into the HTTP response carrier.""" + span = trace.get_current_span(context) + span_context = span.get_span_context() + if span_context == trace.INVALID_SPAN_CONTEXT: + return + + header_name = "traceresponse" + setter.set( + carrier, + header_name, + f"00-{format_trace_id(span_context.trace_id)}-{format_span_id(span_context.span_id)}-{span_context.trace_flags:02x}", + ) + setter.set( + carrier, + _HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, + header_name, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py new file mode 100644 index 00000000000..ad46f2c5925 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py @@ -0,0 +1,92 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import itertools +import sys +from typing import TYPE_CHECKING, Any + +from opentelemetry.agent._vendor.opentelemetry import context +from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import _url_quote + +if sys.version_info >= (3, 14): + from string.templatelib import Template as _Template +else: + _Template = () + +if TYPE_CHECKING: + if sys.version_info >= (3, 14): + from string.templatelib import Template + else: + from typing import Never + + Template = Never + from typing import overload + + @overload + def _add_sql_comment(sql: str, **meta: Any) -> str: ... + + @overload + def _add_sql_comment(sql: Template, **meta: Any) -> Template: ... + + +def _add_sql_comment(sql: str | Template, **meta: Any) -> str | Template: + """ + Appends comments to the sql statement and returns it + """ + meta.update(**_add_framework_tags()) + comment = _generate_sql_comment(**meta) + + if isinstance(sql, _Template): + last = sql.strings[-1].rstrip() + if last.endswith(";"): + last = last[:-1] + comment + ";" + else: + last += comment + args = [ + *itertools.chain.from_iterable(zip(sql.strings[:-1], sql.interpolations)), + last, + ] + return _Template(*args) + + sql = sql.rstrip() + if sql.endswith(";"): + sql = sql[:-1] + comment + ";" + else: + sql = sql + comment + return sql + + +def _generate_sql_comment(**meta) -> str: + """ + Return a SQL comment with comma delimited key=value pairs created from + **meta kwargs. + """ + key_value_delimiter = "," + + if not meta: # No entries added. + return "" + + # Sort the keywords to ensure that caching works and that testing is + # deterministic. It eases visual inspection as well. + return ( + " /*" + + key_value_delimiter.join( + f"{_url_quote(key)}={_url_quote(value)!r}" for key, value in sorted(meta.items()) if value is not None + ) + + "*/" + ) + + +def _add_framework_tags() -> dict: + """ + Returns orm related tags if any set by the context + """ + + sqlcommenter_framework_values = ( + context.get_value("SQLCOMMENTER_ORM_TAGS_AND_VALUES") + if context.get_value("SQLCOMMENTER_ORM_TAGS_AND_VALUES") + else {} + ) + return sqlcommenter_framework_values diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py new file mode 100644 index 00000000000..73fa7dfb83a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py @@ -0,0 +1,214 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import sys +import urllib.parse +from collections.abc import Generator, Sequence +from contextlib import contextmanager +from importlib import import_module +from re import escape, sub +from typing import Any + +try: + # wrapt 2.0.0+ + from opentelemetry.agent._vendor.wrapt import BaseObjectProxy # pylint: disable=no-name-in-module +except ImportError: + from opentelemetry.agent._vendor.wrapt import ObjectProxy as BaseObjectProxy + +from opentelemetry.agent._vendor.opentelemetry import context, trace + +# pylint: disable=E0611 +# FIXME: fix the importing of these private attributes when the location of the _SUPPRESS_HTTP_INSTRUMENTATION_KEY is defined.= +from opentelemetry.agent._vendor.opentelemetry.context import ( + _SUPPRESS_HTTP_INSTRUMENTATION_KEY, + _SUPPRESS_INSTRUMENTATION_KEY, +) + +# pylint: disable=E0611 +from opentelemetry.agent._vendor.opentelemetry.propagate import extract +from opentelemetry.agent._vendor.opentelemetry.trace import StatusCode +from opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext import ( + TraceContextTextMapPropagator, +) + +propagator = TraceContextTextMapPropagator() + +_SUPPRESS_INSTRUMENTATION_KEY_PLAIN = "suppress_instrumentation" # Set for backward compatibility + + +def extract_attributes_from_object( + obj: Any, attributes: Sequence[str], existing: dict[str, str] | None = None +) -> dict[str, str]: + extracted: dict[str, str] = {} + if existing: + extracted.update(existing) + for attr in attributes: + value = getattr(obj, attr, None) + if value is not None: + extracted[attr] = str(value) + return extracted + + +def http_status_to_status_code( + status: int, + allow_redirect: bool = True, + server_span: bool = False, +) -> StatusCode: + """Converts an HTTP status code to an OpenTelemetry canonical status code + + Args: + status (int): HTTP status code + """ + # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status + if not isinstance(status, int): + return StatusCode.UNSET + + if status < 100: + return StatusCode.ERROR + if status <= 299: + return StatusCode.UNSET + if status <= 399 and allow_redirect: + return StatusCode.UNSET + if status <= 499 and server_span: + return StatusCode.UNSET + return StatusCode.ERROR + + +def unwrap(obj: object, attr: str): + """Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it + + The object containing the function to unwrap may be passed as dotted module path string. + + Args: + obj: Object that holds a reference to the wrapped function or dotted import path as string + attr (str): Name of the wrapped function + """ + if isinstance(obj, str): + try: + module_path, class_name = obj.rsplit(".", 1) + except ValueError as exc: + raise ImportError(f"Cannot parse '{obj}' as dotted import path") from exc + if module_path not in sys.modules: + # Was never imported, meaning it could never have been wrapped + return + module = import_module(module_path) + try: + obj = getattr(module, class_name) + except AttributeError as exc: + raise ImportError(f"Cannot import '{class_name}' from '{module}'") from exc + + func = getattr(obj, attr, None) + if func and isinstance(func, BaseObjectProxy) and hasattr(func, "__wrapped__"): + setattr(obj, attr, func.__wrapped__) + + +def _start_internal_or_server_span( + tracer, + span_name, + start_time, + context_carrier, + context_getter, + attributes=None, +): + """Returns internal or server span along with the token which can be used by caller to reset context + + + Args: + tracer : tracer in use by given instrumentation library + span_name (string): name of the span + start_time : start time of the span + context_carrier : 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_getter : an object which contains a get function that can retrieve zero + or more values from the carrier and a keys function that can get all the keys + from carrier. + """ + + token = ctx = span_kind = None + if trace.get_current_span() is trace.INVALID_SPAN: + ctx = extract(context_carrier, getter=context_getter) + token = context.attach(ctx) + span_kind = trace.SpanKind.SERVER + else: + ctx = context.get_current() + span_kind = trace.SpanKind.INTERNAL + span = tracer.start_span( + name=span_name, + context=ctx, + kind=span_kind, + start_time=start_time, + attributes=attributes, + ) + return span, token + + +def _url_quote(s: Any) -> str: # pylint: disable=invalid-name + if not isinstance(s, (str, bytes)): + return s + quoted = urllib.parse.quote(s) + # Since SQL uses '%' as a keyword, '%' is a by-product of url quoting + # e.g. foo,bar --> foo%2Cbar + # thus in our quoting, we need to escape it too to finally give + # foo,bar --> foo%%2Cbar + return quoted.replace("%", "%%") + + +def _get_opentelemetry_values() -> dict[str, Any]: + """ + Return the OpenTelemetry Trace and Span IDs if Span ID is set in the + OpenTelemetry execution context. + """ + # Insert the W3C TraceContext generated + _headers: dict[str, Any] = {} + propagator.inject(_headers) + return _headers + + +def _python_path_without_directory(python_path, directory, path_separator): + return sub( + rf"{escape(directory)}{path_separator}(?!$)", + "", + python_path, + ) + + +def is_instrumentation_enabled() -> bool: + return not ( + context.get_value(_SUPPRESS_INSTRUMENTATION_KEY) or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY_PLAIN) + ) + + +def is_http_instrumentation_enabled() -> bool: + return is_instrumentation_enabled() and not context.get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY) + + +@contextmanager +def _suppress_instrumentation(*keys: str) -> Generator[None]: + """Suppress instrumentation within the context.""" + ctx = context.get_current() + for key in keys: + ctx = context.set_value(key, True, ctx) + token = context.attach(ctx) + try: + yield + finally: + if token: + context.detach(token) + + +@contextmanager +def suppress_instrumentation() -> Generator[None]: + """Suppress instrumentation within the context.""" + with _suppress_instrumentation(_SUPPRESS_INSTRUMENTATION_KEY, _SUPPRESS_INSTRUMENTATION_KEY_PLAIN): + yield + + +@contextmanager +def suppress_http_instrumentation() -> Generator[None]: + """Suppress instrumentation within the context.""" + with _suppress_instrumentation(_SUPPRESS_HTTP_INSTRUMENTATION_KEY): + yield diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py new file mode 100644 index 00000000000..c6660418e74 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py @@ -0,0 +1,121 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +The OpenTelemetry metrics API describes the classes used to generate +metrics. + +The :class:`.MeterProvider` provides users access to the :class:`.Meter` which in +turn is used to create :class:`.Instrument` objects. The :class:`.Instrument` objects are +used to record measurements. + +This module provides abstract (i.e. unimplemented) classes required for +metrics, and a concrete no-op implementation :class:`.NoOpMeter` that allows applications +to use the API package alone without a supporting implementation. + +To get a meter, you need to provide the package name from which you are +calling the meter APIs to OpenTelemetry by calling `MeterProvider.get_meter` +with the calling instrumentation name and the version of your package. + +The following code shows how to obtain a meter using the global :class:`.MeterProvider`:: + + from opentelemetry.metrics import get_meter + + meter = get_meter("example-meter") + counter = meter.create_counter("example-counter") + +.. versionadded:: 1.10.0 +.. versionchanged:: 1.12.0rc +""" + +from opentelemetry.agent._vendor.opentelemetry.metrics._internal import ( + Meter, + MeterProvider, + NoOpMeter, + NoOpMeterProvider, + get_meter, + get_meter_provider, + set_meter_provider, +) +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import ( + Asynchronous, + CallbackOptions, + CallbackT, + Counter, + Histogram, + Instrument, + NoOpCounter, + NoOpHistogram, + NoOpObservableCounter, + NoOpObservableGauge, + NoOpObservableUpDownCounter, + NoOpUpDownCounter, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + Synchronous, + UpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import Gauge as _Gauge +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import NoOpGauge as _NoOpGauge +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.observation import Observation + +for obj in [ + Counter, + Synchronous, + Asynchronous, + CallbackOptions, + _Gauge, + _NoOpGauge, + get_meter_provider, + get_meter, + Histogram, + Meter, + MeterProvider, + Instrument, + NoOpCounter, + NoOpHistogram, + NoOpMeter, + NoOpMeterProvider, + NoOpObservableCounter, + NoOpObservableGauge, + NoOpObservableUpDownCounter, + NoOpUpDownCounter, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + Observation, + set_meter_provider, + UpDownCounter, +]: + obj.__module__ = __name__ + +__all__ = [ + "Asynchronous", + "CallbackOptions", + "CallbackT", + "Counter", + "Histogram", + "Instrument", + "Meter", + "MeterProvider", + "NoOpCounter", + "NoOpHistogram", + "NoOpMeter", + "NoOpMeterProvider", + "NoOpObservableCounter", + "NoOpObservableGauge", + "NoOpObservableUpDownCounter", + "NoOpUpDownCounter", + "ObservableCounter", + "ObservableGauge", + "ObservableUpDownCounter", + "Observation", + "Synchronous", + "UpDownCounter", + "_Gauge", + "_NoOpGauge", + "get_meter", + "get_meter_provider", + "set_meter_provider", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py new file mode 100644 index 00000000000..4635d3bd412 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py @@ -0,0 +1,892 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=too-many-ancestors + +""" +The OpenTelemetry metrics API describes the classes used to generate +metrics. + +The :class:`.MeterProvider` provides users access to the :class:`.Meter` which in +turn is used to create :class:`.Instrument` objects. The :class:`.Instrument` objects are +used to record measurements. + +This module provides abstract (i.e. unimplemented) classes required for +metrics, and a concrete no-op implementation :class:`.NoOpMeter` that allows applications +to use the API package alone without a supporting implementation. + +To get a meter, you need to provide the package name from which you are +calling the meter APIs to OpenTelemetry by calling `MeterProvider.get_meter` +with the calling instrumentation name and the version of your package. + +The following code shows how to obtain a meter using the global :class:`.MeterProvider`:: + + from opentelemetry.metrics import get_meter + + meter = get_meter("example-meter") + counter = meter.create_counter("example-counter") + +.. versionadded:: 1.10.0 +""" + +import warnings +from abc import ABC, abstractmethod +from collections.abc import Sequence +from dataclasses import dataclass +from logging import getLogger +from os import environ +from threading import Lock +from typing import cast + +from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_METER_PROVIDER +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import ( + CallbackT, + Counter, + Gauge, + Histogram, + NoOpCounter, + NoOpGauge, + NoOpHistogram, + NoOpObservableCounter, + NoOpObservableGauge, + NoOpObservableUpDownCounter, + NoOpUpDownCounter, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, + _MetricsHistogramAdvisory, + _ProxyCounter, + _ProxyGauge, + _ProxyHistogram, + _ProxyObservableCounter, + _ProxyObservableGauge, + _ProxyObservableUpDownCounter, + _ProxyUpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.util._once import Once +from opentelemetry.agent._vendor.opentelemetry.util._providers import _load_provider +from opentelemetry.agent._vendor.opentelemetry.util.types import ( + Attributes, +) + +_logger = getLogger(__name__) + + +# pylint: disable=invalid-name +_ProxyInstrumentT = ( + _ProxyCounter + | _ProxyHistogram + | _ProxyGauge + | _ProxyObservableCounter + | _ProxyObservableGauge + | _ProxyObservableUpDownCounter + | _ProxyUpDownCounter +) + + +class MeterProvider(ABC): + """ + MeterProvider is the entry point of the API. It provides access to `Meter` instances. + """ + + @abstractmethod + def get_meter( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> "Meter": + """Returns a `Meter` for use by the given instrumentation library. + + For any two calls it is undefined whether the same or different + `Meter` instances are returned, even for different library names. + + This function may return different `Meter` types (e.g. a no-op meter + vs. a functional meter). + + Args: + name: The name of the instrumenting module. + ``__name__`` should be avoided as this can result in + different meter names if the meters are in different files. + It is better to use a fixed string that can be imported where + needed and used consistently as the name of the meter. + + This should *not* be the name of the module that is + instrumented but the name of the module doing the instrumentation. + E.g., instead of ``"requests"``, use + ``"opentelemetry.instrumentation.requests"``. + + version: Optional. The version string of the + instrumenting library. Usually this should be the same as + ``importlib.metadata.version(instrumenting_library_name)``. + + schema_url: Optional. Specifies the Schema URL of the emitted telemetry. + attributes: Optional. Attributes that are associated with the emitted telemetry. + """ + + +class NoOpMeterProvider(MeterProvider): + """The default MeterProvider used when no MeterProvider implementation is available.""" + + def get_meter( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> "Meter": + """Returns a NoOpMeter.""" + return NoOpMeter(name, version=version, schema_url=schema_url) + + +class _ProxyMeterProvider(MeterProvider): + def __init__(self) -> None: + self._lock = Lock() + self._meters: list[_ProxyMeter] = [] + self._real_meter_provider: MeterProvider | None = None + + def get_meter( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> "Meter": + with self._lock: + if self._real_meter_provider is not None: + return self._real_meter_provider.get_meter(name, version, schema_url) + + meter = _ProxyMeter(name, version=version, schema_url=schema_url) + self._meters.append(meter) + return meter + + def on_set_meter_provider(self, meter_provider: MeterProvider) -> None: + with self._lock: + self._real_meter_provider = meter_provider + for meter in self._meters: + meter.on_set_meter_provider(meter_provider) + + +@dataclass +class _InstrumentRegistrationStatus: + instrument_id: str + already_registered: bool + conflict: bool + current_advisory: _MetricsHistogramAdvisory | None + + +class Meter(ABC): + """Handles instrument creation. + + This class provides methods for creating instruments which are then + used to produce measurements. + """ + + def __init__( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + ) -> None: + super().__init__() + self._name = name + self._version = version + self._schema_url = schema_url + self._instrument_ids: dict[str, _MetricsHistogramAdvisory | None] = {} + self._instrument_ids_lock = Lock() + + @property + def name(self) -> str: + """ + The name of the instrumenting module. + """ + return self._name + + @property + def version(self) -> str | None: + """ + The version string of the instrumenting library. + """ + return self._version + + @property + def schema_url(self) -> str | None: + """ + Specifies the Schema URL of the emitted telemetry + """ + return self._schema_url + + def _register_instrument( + self, + name: str, + type_: type, + unit: str, + description: str, + advisory: _MetricsHistogramAdvisory | None = None, + ) -> _InstrumentRegistrationStatus: + """ + Register an instrument with the name, type, unit and description as + identifying keys and the advisory as value. + + Returns a tuple. The first value is the instrument id. + The second value is an `_InstrumentRegistrationStatus` where + `already_registered` is `True` if the instrument has been registered + already. + If `conflict` is set to True the `current_advisory` attribute contains + the registered instrument advisory. + """ + + instrument_id = ",".join([name.strip().lower(), type_.__name__, unit, description]) + + already_registered = False + conflict = False + current_advisory = None + + with self._instrument_ids_lock: + # we are not using get because None is a valid value + already_registered = instrument_id in self._instrument_ids + if already_registered: + current_advisory = self._instrument_ids[instrument_id] + conflict = current_advisory != advisory + else: + self._instrument_ids[instrument_id] = advisory + + return _InstrumentRegistrationStatus( + instrument_id=instrument_id, + already_registered=already_registered, + conflict=conflict, + current_advisory=current_advisory, + ) + + @staticmethod + def _log_instrument_registration_conflict( + name: str, + instrumentation_type: str, + unit: str, + description: str, + status: _InstrumentRegistrationStatus, + ) -> None: + _logger.warning( + "An instrument with name %s, type %s, unit %s and " + "description %s has been created already with a " + "different advisory value %s and will be used instead.", + name, + instrumentation_type, + unit, + description, + status.current_advisory, + ) + + @abstractmethod + def create_counter( + self, + name: str, + unit: str = "", + description: str = "", + ) -> Counter: + """Creates a `Counter` instrument + + Args: + name: The name of the instrument to be created + unit: The unit for observations this instrument reports. For + example, ``By`` for bytes. UCUM units are recommended. + description: A description for this instrument and what it measures. + """ + + @abstractmethod + def create_up_down_counter( + self, + name: str, + unit: str = "", + description: str = "", + ) -> UpDownCounter: + """Creates an `UpDownCounter` instrument + + Args: + name: The name of the instrument to be created + unit: The unit for observations this instrument reports. For + example, ``By`` for bytes. UCUM units are recommended. + description: A description for this instrument and what it measures. + """ + + @abstractmethod + def create_observable_counter( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableCounter: + """Creates an `ObservableCounter` instrument + + An observable counter observes a monotonically increasing count by calling provided + callbacks which accept a :class:`~opentelemetry.metrics.CallbackOptions` and return + multiple :class:`~opentelemetry.metrics.Observation`. + + For example, an observable counter could be used to report system CPU + time periodically. Here is a basic implementation:: + + def cpu_time_callback( + options: CallbackOptions, + ) -> Iterable[Observation]: + observations = [] + with open("/proc/stat") as procstat: + procstat.readline() # skip the first line + for line in procstat: + if not line.startswith("cpu"): + break + cpu, *states = line.split() + observations.append( + Observation( + int(states[0]) // 100, + {"cpu": cpu, "state": "user"}, + ) + ) + observations.append( + Observation( + int(states[1]) // 100, + {"cpu": cpu, "state": "nice"}, + ) + ) + observations.append( + Observation( + int(states[2]) // 100, + {"cpu": cpu, "state": "system"}, + ) + ) + # ... other states + return observations + + + meter.create_observable_counter( + "system.cpu.time", + callbacks=[cpu_time_callback], + unit="s", + description="CPU time", + ) + + To reduce memory usage, you can use generator callbacks instead of + building the full list:: + + def cpu_time_callback( + options: CallbackOptions, + ) -> Iterable[Observation]: + with open("/proc/stat") as procstat: + procstat.readline() # skip the first line + for line in procstat: + if not line.startswith("cpu"): + break + cpu, *states = line.split() + yield Observation( + int(states[0]) // 100, + {"cpu": cpu, "state": "user"}, + ) + yield Observation( + int(states[1]) // 100, + {"cpu": cpu, "state": "nice"}, + ) + # ... other states + + Alternatively, you can pass a sequence of generators directly instead of a sequence of + callbacks, which each should return iterables of :class:`~opentelemetry.metrics.Observation`:: + + def cpu_time_callback( + states_to_include: set[str], + ) -> Iterable[Iterable[Observation]]: + # accept options sent in from OpenTelemetry + options = yield + while True: + observations = [] + with open("/proc/stat") as procstat: + procstat.readline() # skip the first line + for line in procstat: + if not line.startswith("cpu"): + break + cpu, *states = line.split() + if "user" in states_to_include: + observations.append( + Observation( + int(states[0]) // 100, + {"cpu": cpu, "state": "user"}, + ) + ) + if "nice" in states_to_include: + observations.append( + Observation( + int(states[1]) // 100, + {"cpu": cpu, "state": "nice"}, + ) + ) + # ... other states + # yield the observations and receive the options for next iteration + options = yield observations + + + meter.create_observable_counter( + "system.cpu.time", + callbacks=[cpu_time_callback({"user", "system"})], + unit="s", + description="CPU time", + ) + + The :class:`~opentelemetry.metrics.CallbackOptions` contain a timeout which the + callback should respect. For example if the callback does asynchronous work, like + making HTTP requests, it should respect the timeout:: + + def scrape_http_callback( + options: CallbackOptions, + ) -> Iterable[Observation]: + r = requests.get( + "http://scrapethis.com", + timeout=options.timeout_millis / 10**3, + ) + for value in r.json(): + yield Observation(value) + + Args: + name: The name of the instrument to be created + callbacks: A sequence of callbacks that return an iterable of + :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a sequence of generators that each + yields iterables of :class:`~opentelemetry.metrics.Observation`. + unit: The unit for observations this instrument reports. For + example, ``By`` for bytes. UCUM units are recommended. + description: A description for this instrument and what it measures. + """ + + @abstractmethod + def create_histogram( + self, + name: str, + unit: str = "", + description: str = "", + *, + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + ) -> Histogram: + """Creates a :class:`~opentelemetry.metrics.Histogram` instrument + + Args: + name: The name of the instrument to be created + unit: The unit for observations this instrument reports. For + example, ``By`` for bytes. UCUM units are recommended. + description: A description for this instrument and what it measures. + """ + + def create_gauge( # type: ignore # pylint: disable=no-self-use + self, + name: str, + unit: str = "", + description: str = "", + ) -> Gauge: # pyright: ignore[reportReturnType] + """Creates a ``Gauge`` instrument + + Args: + name: The name of the instrument to be created + unit: The unit for observations this instrument reports. For + example, ``By`` for bytes. UCUM units are recommended. + description: A description for this instrument and what it measures. + """ + warnings.warn("create_gauge() is not implemented and will be a no-op") + + @abstractmethod + def create_observable_gauge( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableGauge: + """Creates an `ObservableGauge` instrument + + Args: + name: The name of the instrument to be created + callbacks: A sequence of callbacks that return an iterable of + :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a generator that yields iterables + of :class:`~opentelemetry.metrics.Observation`. + unit: The unit for observations this instrument reports. For + example, ``By`` for bytes. UCUM units are recommended. + description: A description for this instrument and what it measures. + """ + + @abstractmethod + def create_observable_up_down_counter( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableUpDownCounter: + """Creates an `ObservableUpDownCounter` instrument + + Args: + name: The name of the instrument to be created + callbacks: A sequence of callbacks that return an iterable of + :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a generator that yields iterables + of :class:`~opentelemetry.metrics.Observation`. + unit: The unit for observations this instrument reports. For + example, ``By`` for bytes. UCUM units are recommended. + description: A description for this instrument and what it measures. + """ + + +class _ProxyMeter(Meter): + def __init__( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + ) -> None: + super().__init__(name, version=version, schema_url=schema_url) + self._lock = Lock() + self._instruments: list[_ProxyInstrumentT] = [] + self._real_meter: Meter | None = None + + def on_set_meter_provider(self, meter_provider: MeterProvider) -> None: + """Called when a real meter provider is set on the creating _ProxyMeterProvider + + Creates a real backing meter for this instance and notifies all created + instruments so they can create real backing instruments. + """ + real_meter = meter_provider.get_meter(self._name, self._version, self._schema_url) + + with self._lock: + self._real_meter = real_meter + # notify all proxy instruments of the new meter so they can create + # real instruments to back themselves + for instrument in self._instruments: + instrument.on_meter_set(real_meter) + + def create_counter( + self, + name: str, + unit: str = "", + description: str = "", + ) -> Counter: + with self._lock: + if self._real_meter: + return self._real_meter.create_counter(name, unit, description) + proxy = _ProxyCounter(name, unit, description) + self._instruments.append(proxy) + return proxy + + def create_up_down_counter( + self, + name: str, + unit: str = "", + description: str = "", + ) -> UpDownCounter: + with self._lock: + if self._real_meter: + return self._real_meter.create_up_down_counter(name, unit, description) + proxy = _ProxyUpDownCounter(name, unit, description) + self._instruments.append(proxy) + return proxy + + def create_observable_counter( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableCounter: + with self._lock: + if self._real_meter: + return self._real_meter.create_observable_counter(name, callbacks, unit, description) + proxy = _ProxyObservableCounter(name, callbacks, unit=unit, description=description) + self._instruments.append(proxy) + return proxy + + def create_histogram( + self, + name: str, + unit: str = "", + description: str = "", + *, + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + ) -> Histogram: + with self._lock: + if self._real_meter: + return self._real_meter.create_histogram( + name, + unit, + description, + explicit_bucket_boundaries_advisory=explicit_bucket_boundaries_advisory, + ) + proxy = _ProxyHistogram(name, unit, description, explicit_bucket_boundaries_advisory) + self._instruments.append(proxy) + return proxy + + def create_gauge( + self, + name: str, + unit: str = "", + description: str = "", + ) -> Gauge: + with self._lock: + if self._real_meter: + return self._real_meter.create_gauge(name, unit, description) + proxy = _ProxyGauge(name, unit, description) + self._instruments.append(proxy) + return proxy + + def create_observable_gauge( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableGauge: + with self._lock: + if self._real_meter: + return self._real_meter.create_observable_gauge(name, callbacks, unit, description) + proxy = _ProxyObservableGauge(name, callbacks, unit=unit, description=description) + self._instruments.append(proxy) + return proxy + + def create_observable_up_down_counter( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableUpDownCounter: + with self._lock: + if self._real_meter: + return self._real_meter.create_observable_up_down_counter( + name, + callbacks, + unit, + description, + ) + proxy = _ProxyObservableUpDownCounter(name, callbacks, unit=unit, description=description) + self._instruments.append(proxy) + return proxy + + +class NoOpMeter(Meter): + """The default Meter used when no Meter implementation is available. + + All operations are no-op. + """ + + def create_counter( + self, + name: str, + unit: str = "", + description: str = "", + ) -> Counter: + """Returns a no-op Counter.""" + status = self._register_instrument(name, NoOpCounter, unit, description) + if status.conflict: + self._log_instrument_registration_conflict( + name, + Counter.__name__, + unit, + description, + status, + ) + + return NoOpCounter(name, unit=unit, description=description) + + def create_gauge( + self, + name: str, + unit: str = "", + description: str = "", + ) -> Gauge: + """Returns a no-op Gauge.""" + status = self._register_instrument(name, NoOpGauge, unit, description) + if status.conflict: + self._log_instrument_registration_conflict( + name, + Gauge.__name__, + unit, + description, + status, + ) + return NoOpGauge(name, unit=unit, description=description) + + def create_up_down_counter( + self, + name: str, + unit: str = "", + description: str = "", + ) -> UpDownCounter: + """Returns a no-op UpDownCounter.""" + status = self._register_instrument(name, NoOpUpDownCounter, unit, description) + if status.conflict: + self._log_instrument_registration_conflict( + name, + UpDownCounter.__name__, + unit, + description, + status, + ) + return NoOpUpDownCounter(name, unit=unit, description=description) + + def create_observable_counter( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableCounter: + """Returns a no-op ObservableCounter.""" + status = self._register_instrument(name, NoOpObservableCounter, unit, description) + if status.conflict: + self._log_instrument_registration_conflict( + name, + ObservableCounter.__name__, + unit, + description, + status, + ) + return NoOpObservableCounter( + name, + callbacks, + unit=unit, + description=description, + ) + + def create_histogram( + self, + name: str, + unit: str = "", + description: str = "", + *, + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + ) -> Histogram: + """Returns a no-op Histogram.""" + status = self._register_instrument( + name, + NoOpHistogram, + unit, + description, + _MetricsHistogramAdvisory(explicit_bucket_boundaries=explicit_bucket_boundaries_advisory), + ) + if status.conflict: + self._log_instrument_registration_conflict( + name, + Histogram.__name__, + unit, + description, + status, + ) + return NoOpHistogram( + name, + unit=unit, + description=description, + explicit_bucket_boundaries_advisory=explicit_bucket_boundaries_advisory, + ) + + def create_observable_gauge( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableGauge: + """Returns a no-op ObservableGauge.""" + status = self._register_instrument(name, NoOpObservableGauge, unit, description) + if status.conflict: + self._log_instrument_registration_conflict( + name, + ObservableGauge.__name__, + unit, + description, + status, + ) + return NoOpObservableGauge( + name, + callbacks, + unit=unit, + description=description, + ) + + def create_observable_up_down_counter( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> ObservableUpDownCounter: + """Returns a no-op ObservableUpDownCounter.""" + status = self._register_instrument(name, NoOpObservableUpDownCounter, unit, description) + if status.conflict: + self._log_instrument_registration_conflict( + name, + ObservableUpDownCounter.__name__, + unit, + description, + status, + ) + return NoOpObservableUpDownCounter( + name, + callbacks, + unit=unit, + description=description, + ) + + +_METER_PROVIDER_SET_ONCE = Once() +_METER_PROVIDER: MeterProvider | None = None +_PROXY_METER_PROVIDER = _ProxyMeterProvider() + + +def get_meter( + name: str, + version: str = "", + meter_provider: MeterProvider | None = None, + schema_url: str | None = None, + attributes: Attributes = None, +) -> "Meter": + """Returns a `Meter` for use by the given instrumentation library. + + This function is a convenience wrapper for + `opentelemetry.metrics.MeterProvider.get_meter`. + + If meter_provider is omitted the current configured one is used. + """ + if meter_provider is None: + meter_provider = get_meter_provider() + return meter_provider.get_meter(name, version, schema_url, attributes) + + +def _set_meter_provider(meter_provider: MeterProvider, log: bool) -> None: + def set_mp() -> None: + global _METER_PROVIDER # pylint: disable=global-statement + _METER_PROVIDER = meter_provider + + # gives all proxies real instruments off the newly set meter provider + _PROXY_METER_PROVIDER.on_set_meter_provider(meter_provider) + + did_set = _METER_PROVIDER_SET_ONCE.do_once(set_mp) + + if log and not did_set: + _logger.warning("Overriding of current MeterProvider is not allowed") + + +def set_meter_provider(meter_provider: MeterProvider) -> None: + """Sets the current global :class:`~.MeterProvider` object. + + This can only be done once, a warning will be logged if any further attempt + is made. + """ + _set_meter_provider(meter_provider, log=True) + + +def get_meter_provider() -> MeterProvider: + """Gets the current global :class:`~.MeterProvider` object.""" + + if _METER_PROVIDER is None: + if OTEL_PYTHON_METER_PROVIDER not in environ: + return _PROXY_METER_PROVIDER + + meter_provider: MeterProvider = _load_provider( # type: ignore + OTEL_PYTHON_METER_PROVIDER, "meter_provider" + ) + _set_meter_provider(meter_provider, log=False) + + # _METER_PROVIDER will have been set by one thread + return cast("MeterProvider", _METER_PROVIDER) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py new file mode 100644 index 00000000000..9dfa1057f4f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py @@ -0,0 +1,540 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=too-many-ancestors + + +from abc import ABC, abstractmethod +from collections.abc import Callable, Generator, Iterable, Sequence +from dataclasses import dataclass +from logging import getLogger +from re import compile as re_compile +from typing import ( + Generic, + TypeVar, +) + +# pylint: disable=unused-import; needed for typing and sphinx +from opentelemetry.agent._vendor.opentelemetry import metrics +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.observation import Observation +from opentelemetry.agent._vendor.opentelemetry.util.types import ( + Attributes, +) + +_logger = getLogger(__name__) + +_name_regex = re_compile(r"[a-zA-Z][-_./a-zA-Z0-9]{0,254}") +_unit_regex = re_compile(r"[\x00-\x7F]{0,63}") + + +@dataclass(frozen=True) +class _MetricsHistogramAdvisory: + explicit_bucket_boundaries: Sequence[float] | None = None + + +@dataclass(frozen=True) +class CallbackOptions: + """Options for the callback + + Args: + timeout_millis: Timeout for the callback's execution. If the callback does asynchronous + work (e.g. HTTP requests), it should respect this timeout. + """ + + timeout_millis: float = 10_000 + + +InstrumentT = TypeVar("InstrumentT", bound="Instrument") +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +class Instrument(ABC): + """Abstract class that serves as base for all instruments.""" + + @abstractmethod + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + ) -> None: + pass + + @staticmethod + def _check_name_unit_description(name: str, unit: str, description: str) -> dict[str, str | None]: + """ + Checks the following instrument name, unit and description for + compliance with the spec. + + Returns a dict with keys "name", "unit" and "description", the + corresponding values will be the checked strings or `None` if the value + is invalid. If valid, the checked strings should be used instead of the + original values. + """ + + result: dict[str, str | None] = {} + + if _name_regex.fullmatch(name) is not None: + result["name"] = name + else: + result["name"] = None + + if unit is None: + unit = "" + if _unit_regex.fullmatch(unit) is not None: + result["unit"] = unit + else: + result["unit"] = None + + if description is None: + result["description"] = "" + else: + result["description"] = description + + return result + + +class _ProxyInstrument(ABC, Generic[InstrumentT]): + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + ) -> None: + self._name = name + self._unit = unit + self._description = description + self._real_instrument: InstrumentT | None = None + + def on_meter_set(self, meter: "metrics.Meter") -> None: + """Called when a real meter is set on the creating _ProxyMeter""" + + # We don't need any locking on proxy instruments because it's OK if some + # measurements get dropped while a real backing instrument is being + # created. + self._real_instrument = self._create_real_instrument(meter) + + @abstractmethod + def _create_real_instrument(self, meter: "metrics.Meter") -> InstrumentT: + """Create an instance of the real instrument. Implement this.""" + + +class _ProxyAsynchronousInstrument(_ProxyInstrument[InstrumentT]): + def __init__( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> None: + super().__init__(name, unit, description) + self._callbacks = callbacks + + +class Synchronous(Instrument): + """Base class for all synchronous instruments""" + + +class Asynchronous(Instrument): + """Base class for all asynchronous instruments""" + + @abstractmethod + def __init__( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> None: + super().__init__(name, unit=unit, description=description) + + +class Counter(Synchronous): + """A Counter is a synchronous `Instrument` which supports non-negative increments.""" + + @abstractmethod + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + """Records an increment to the counter. + + Args: + amount: The amount to increment the counter by. Must be non-negative. + attributes: Optional set of attributes to associate with the measurement. + context: Optional context to associate with the measurement. If not + provided, the current context is used. + """ + + +class NoOpCounter(Counter): + """No-op implementation of `Counter`.""" + + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + ) -> None: + super().__init__(name, unit=unit, description=description) + + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + return super().add(amount, attributes=attributes, context=context) + + +class _ProxyCounter(_ProxyInstrument[Counter], Counter): + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + if self._real_instrument: + self._real_instrument.add(amount, attributes, context) + + def _create_real_instrument(self, meter: "metrics.Meter") -> Counter: + return meter.create_counter( + self._name, + self._unit, + self._description, + ) + + +class UpDownCounter(Synchronous): + """An UpDownCounter is a synchronous `Instrument` which supports increments and decrements.""" + + @abstractmethod + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + """Records an increment or decrement to the counter. + + Unlike `Counter`, the ``amount`` may be negative, allowing the + instrument to track values that go up and down (e.g. number of + active requests, queue depth). + + Args: + amount: The amount to add to the counter. May be positive or negative. + attributes: Optional set of attributes to associate with the measurement. + context: Optional context to associate with the measurement. If not + provided, the current context is used. + """ + + +class NoOpUpDownCounter(UpDownCounter): + """No-op implementation of `UpDownCounter`.""" + + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + ) -> None: + super().__init__(name, unit=unit, description=description) + + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + return super().add(amount, attributes=attributes, context=context) + + +class _ProxyUpDownCounter(_ProxyInstrument[UpDownCounter], UpDownCounter): + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + if self._real_instrument: + self._real_instrument.add(amount, attributes, context) + + def _create_real_instrument(self, meter: "metrics.Meter") -> UpDownCounter: + return meter.create_up_down_counter( + self._name, + self._unit, + self._description, + ) + + +class ObservableCounter(Asynchronous): + """An ObservableCounter is an asynchronous `Instrument` which reports monotonically + increasing value(s) when the instrument is being observed. + """ + + +class NoOpObservableCounter(ObservableCounter): + """No-op implementation of `ObservableCounter`.""" + + def __init__( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> None: + super().__init__( + name, + callbacks, + unit=unit, + description=description, + ) + + +class _ProxyObservableCounter(_ProxyAsynchronousInstrument[ObservableCounter], ObservableCounter): + def _create_real_instrument(self, meter: "metrics.Meter") -> ObservableCounter: + return meter.create_observable_counter( + self._name, + self._callbacks, + self._unit, + self._description, + ) + + +class ObservableUpDownCounter(Asynchronous): + """An ObservableUpDownCounter is an asynchronous `Instrument` which reports additive value(s) (e.g. + the process heap size - it makes sense to report the heap size from multiple processes and sum them + up, so we get the total heap usage) when the instrument is being observed. + """ + + +class NoOpObservableUpDownCounter(ObservableUpDownCounter): + """No-op implementation of `ObservableUpDownCounter`.""" + + def __init__( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> None: + super().__init__( + name, + callbacks, + unit=unit, + description=description, + ) + + +class _ProxyObservableUpDownCounter( + _ProxyAsynchronousInstrument[ObservableUpDownCounter], + ObservableUpDownCounter, +): + def _create_real_instrument(self, meter: "metrics.Meter") -> ObservableUpDownCounter: + return meter.create_observable_up_down_counter( + self._name, + self._callbacks, + self._unit, + self._description, + ) + + +class Histogram(Synchronous): + """Histogram is a synchronous `Instrument` which can be used to report arbitrary values + that are likely to be statistically meaningful. It is intended for statistics such as + histograms, summaries, and percentile. + """ + + @abstractmethod + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + ) -> None: + pass + + @abstractmethod + def record( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + """Records a measurement. + + Used to report measurements that are likely to be statistically + meaningful, such as request durations, payload sizes, or any value + for which a distribution (e.g. percentiles) is useful. + + Args: + amount: The measurement to record. Should be non-negative in most + cases; negative values are only meaningful when the histogram + is used to track signed deltas. + attributes: Optional set of attributes to associate with the measurement. + context: Optional context to associate with the measurement. If not + provided, the current context is used. + """ + + +class NoOpHistogram(Histogram): + """No-op implementation of `Histogram`.""" + + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + ) -> None: + super().__init__( + name, + unit=unit, + description=description, + explicit_bucket_boundaries_advisory=explicit_bucket_boundaries_advisory, + ) + + def record( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + return super().record(amount, attributes=attributes, context=context) + + +class _ProxyHistogram(_ProxyInstrument[Histogram], Histogram): + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + ) -> None: + super().__init__(name, unit=unit, description=description) + self._explicit_bucket_boundaries_advisory = explicit_bucket_boundaries_advisory + + def record( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + if self._real_instrument: + self._real_instrument.record(amount, attributes, context) + + def _create_real_instrument(self, meter: "metrics.Meter") -> Histogram: + return meter.create_histogram( + self._name, + self._unit, + self._description, + explicit_bucket_boundaries_advisory=self._explicit_bucket_boundaries_advisory, + ) + + +class ObservableGauge(Asynchronous): + """Asynchronous Gauge is an asynchronous `Instrument` which reports non-additive value(s) (e.g. + the room temperature - it makes no sense to report the temperature value from multiple rooms + and sum them up) when the instrument is being observed. + """ + + +class NoOpObservableGauge(ObservableGauge): + """No-op implementation of `ObservableGauge`.""" + + def __init__( + self, + name: str, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + ) -> None: + super().__init__( + name, + callbacks, + unit=unit, + description=description, + ) + + +class _ProxyObservableGauge( + _ProxyAsynchronousInstrument[ObservableGauge], + ObservableGauge, +): + def _create_real_instrument(self, meter: "metrics.Meter") -> ObservableGauge: + return meter.create_observable_gauge( + self._name, + self._callbacks, + self._unit, + self._description, + ) + + +class Gauge(Synchronous): + """A Gauge is a synchronous `Instrument` which can be used to record non-additive values as they occur.""" + + @abstractmethod + def set( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + """Records the current value of the gauge. + + The gauge reports the last recorded value when observed. It is + intended for non-additive measurements where only the current + value matters (e.g. CPU utilisation percentage, room temperature). + + Args: + amount: The current value to record. + attributes: Optional set of attributes to associate with the measurement. + context: Optional context to associate with the measurement. If not + provided, the current context is used. + """ + + +class NoOpGauge(Gauge): + """No-op implementation of ``Gauge``.""" + + def __init__( + self, + name: str, + unit: str = "", + description: str = "", + ) -> None: + super().__init__(name, unit=unit, description=description) + + def set( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + return super().set(amount, attributes=attributes, context=context) + + +class _ProxyGauge( + _ProxyInstrument[Gauge], + Gauge, +): + def set( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + if self._real_instrument: + self._real_instrument.set(amount, attributes, context) + + def _create_real_instrument(self, meter: "metrics.Meter") -> Gauge: + return meter.create_gauge( + self._name, + self._unit, + self._description, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py new file mode 100644 index 00000000000..3248045e1ce --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py @@ -0,0 +1,51 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + + +class Observation: + """A measurement observed in an asynchronous instrument + + Return/yield instances of this class from asynchronous instrument callbacks. + + Args: + value: The float or int measured value + attributes: The measurement's attributes + context: The measurement's context + """ + + def __init__( + self, + value: float, + attributes: Attributes = None, + context: Context | None = None, + ) -> None: + self._value = value + self._attributes = attributes + self._context = context + + @property + def value(self) -> float | int: + return self._value + + @property + def attributes(self) -> Attributes: + return self._attributes + + @property + def context(self) -> Context | None: + return self._context + + def __eq__(self, other: object) -> bool: + return ( + isinstance(other, Observation) + and self.value == other.value + and self.attributes == other.attributes + and self.context == other.context + ) + + def __repr__(self) -> str: + return f"Observation(value={self.value}, attributes={self.attributes}, context={self.context})" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py new file mode 100644 index 00000000000..6561217c51e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py @@ -0,0 +1,171 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +API for propagation of context. + +The propagators for the +``opentelemetry.propagators.composite.CompositePropagator`` can be defined +via configuration in the ``OTEL_PROPAGATORS`` environment variable. This +variable should be set to a comma-separated string of names of values for the +``opentelemetry_propagator`` entry point. For example, setting +``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value) +would instantiate +``opentelemetry.propagators.composite.CompositePropagator`` with 2 +propagators, one of type +``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator`` +and other of type ``opentelemetry.baggage.propagation.W3CBaggagePropagator``. +Notice that these propagator classes are defined as +``opentelemetry_propagator`` entry points in the ``pyproject.toml`` file of +``opentelemetry``. + +Example:: + + import flask + import requests + from opentelemetry import propagate + + + PROPAGATOR = propagate.get_global_textmap() + + + def get_header_from_flask_request(request, key): + return request.headers.get_all(key) + + + def set_header_into_requests_request(request: requests.Request, key: str, value: str): + request.headers[key] = value + + + def example_route(): + context = PROPAGATOR.extract(get_header_from_flask_request, flask.request) + request_to_downstream = requests.Request("GET", "http://httpbin.org/get") + PROPAGATOR.inject( + set_header_into_requests_request, + request_to_downstream, + context=context, + ) + session = requests.Session() + session.send(request_to_downstream.prepare()) + + +.. _Propagation API Specification: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md +""" + +from logging import getLogger +from os import environ + +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PROPAGATORS +from opentelemetry.agent._vendor.opentelemetry.propagators import composite, textmap + +logger = getLogger(__name__) + + +def extract( + carrier: textmap.CarrierT, + context: Context | None = None, + getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, +) -> Context: + """Uses the configured propagator to extract a Context from the carrier. + + Args: + getter: an object which contains a get function that can retrieve zero + or more values from the carrier and a keys function that can get all the keys + from carrier. + 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. + """ + return get_global_textmap().extract(carrier, context, getter=getter) + + +def inject( + carrier: textmap.CarrierT, + context: Context | None = None, + setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, +) -> None: + """Uses the configured propagator to inject a Context into the carrier. + + Args: + carrier: the medium used by Propagators to read + values from and write values to. + 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. + """ + get_global_textmap().inject(carrier, context=context, setter=setter) + + +def _load_propagators() -> textmap.TextMapPropagator: + configured = environ.get(OTEL_PROPAGATORS) + if not configured: + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.baggage.propagation import ( # noqa: PLC0415 + W3CBaggagePropagator, + ) + + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext import ( # noqa: PLC0415 + TraceContextTextMapPropagator, + ) + + return composite.CompositePropagator([TraceContextTextMapPropagator(), W3CBaggagePropagator()]) + + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.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([]) + 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 + 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") + +for propagator in environ_propagators.split(","): # type: ignore[assignment] + propagator = propagator.strip() + + +def get_global_textmap() -> textmap.TextMapPropagator: + return _HTTP_TEXT_FORMAT + + +def set_global_textmap( + http_text_format: textmap.TextMapPropagator, +) -> None: + global _HTTP_TEXT_FORMAT # pylint:disable=global-statement + _HTTP_TEXT_FORMAT = http_text_format diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py new file mode 100644 index 00000000000..3d934f4a3f0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py @@ -0,0 +1,94 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Environment variable carriers for text map propagators. + +Use :class:`EnvironmentGetter` with the environment mapping to extract from, +usually ``os.environ`` during application or child-process initialization. +Use :class:`EnvironmentSetter` with a mutable environment copy when preparing +the environment for a child process. +""" + +import re +from collections.abc import Mapping, MutableMapping + +from opentelemetry.agent._vendor.opentelemetry.propagators.textmap import Getter, Setter + + +def _normalize_key(key: str) -> str: + if not key: + return "_" + result = re.sub(r"[^A-Za-z0-9_]", "_", key).upper() + if result and result[0].isdigit(): + result = "_" + result + return result + + +def _is_normalized_key(key: str) -> bool: + if not key: + return False + if "0" <= key[0] <= "9": + return False + return all("A" <= char <= "Z" or "0" <= char <= "9" or char == "_" for char in key) + + +class EnvironmentGetter(Getter[Mapping[str, str]]): + """Getter implementation for extracting context and baggage from environment variables. + + EnvironmentGetter reads from the mapping provided as the carrier, normalizes + requested keys, and provides simple data access without validation. + + Example usage: + getter = EnvironmentGetter() + traceparent = getter.get(os.environ, "traceparent") + """ + + def get(self, carrier: Mapping[str, str], key: str) -> list[str] | None: + """Get a value from the environment carrier for the given key. + + Args: + carrier: Mapping to read environment variables from + key: The key to look up (will be normalized) + + Returns: + A list with a single string value if the key exists, None otherwise. + """ + val = carrier.get(_normalize_key(key)) + if val is None: + return None + return [val] + + def keys(self, carrier: Mapping[str, str]) -> list[str]: + """Get all keys from the environment carrier. + + Args: + carrier: Mapping to read environment variable keys from + + Returns: + List of all already-normalized environment variable keys. + """ + return [key for key in carrier.keys() if _is_normalized_key(key)] + + +class EnvironmentSetter(Setter[MutableMapping[str, str]]): + """Setter implementation for building environment variable dictionaries. + + EnvironmentSetter builds a dictionary of environment variables that + can be passed to utilities like subprocess.run() + + Example usage: + setter = EnvironmentSetter() + env_vars = {} + setter.set(env_vars, "traceparent", "00-trace-id-span-id-01") + subprocess.run(myCommand, env=env_vars) + """ + + def set(self, carrier: MutableMapping[str, str], key: str, value: str) -> None: + """Set a value in the carrier dictionary for the given key. + + Args: + carrier: Dictionary to store environment variables + key: The key to set (normalized) + value: The value to set + """ + carrier[_normalize_key(key)] = value diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py new file mode 100644 index 00000000000..ba9b04067dd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py @@ -0,0 +1,182 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import collections.abc +from re import compile as re_compile + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry import trace +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.propagators.textmap import ( + CarrierT, + Getter, + Setter, + TextMapPropagator, + default_getter, + default_setter, +) +from opentelemetry.agent._vendor.opentelemetry.trace import format_span_id, format_trace_id + + +class B3MultiFormat(TextMapPropagator): + """Propagator for the B3 HTTP multi-header format. + + See: https://github.com/openzipkin/b3-propagation + https://github.com/openzipkin/b3-propagation#multiple-headers + """ + + SINGLE_HEADER_KEY = "b3" + TRACE_ID_KEY = "x-b3-traceid" + SPAN_ID_KEY = "x-b3-spanid" + SAMPLED_KEY = "x-b3-sampled" + FLAGS_KEY = "x-b3-flags" + _SAMPLE_PROPAGATE_VALUES = {"1", "True", "true", "d"} + _trace_id_regex = re_compile(r"[\da-fA-F]{16}|[\da-fA-F]{32}") + _span_id_regex = re_compile(r"[\da-fA-F]{16}") + + def extract( + self, + carrier: CarrierT, + context: Context | None = None, + getter: Getter = default_getter, + ) -> Context: + if context is None: + context = Context() + trace_id = trace.INVALID_TRACE_ID + span_id = trace.INVALID_SPAN_ID + sampled = "0" + flags = None + + single_header = _extract_first_element(getter.get(carrier, self.SINGLE_HEADER_KEY)) + if single_header: + # The b3 spec calls for the sampling state to be + # "deferred", which is unspecified. This concept does not + # translate to SpanContext, so we set it as recorded. + sampled = "1" + fields = single_header.split("-", 4) + + if len(fields) == 1: + sampled = fields[0] + elif len(fields) == 2: + trace_id, span_id = fields + elif len(fields) == 3: + trace_id, span_id, sampled = fields + elif len(fields) == 4: + trace_id, span_id, sampled, _ = fields + else: + trace_id = _extract_first_element(getter.get(carrier, self.TRACE_ID_KEY)) or trace_id + span_id = _extract_first_element(getter.get(carrier, self.SPAN_ID_KEY)) or span_id + sampled = _extract_first_element(getter.get(carrier, self.SAMPLED_KEY)) or sampled + flags = _extract_first_element(getter.get(carrier, self.FLAGS_KEY)) or flags + + if ( + trace_id == trace.INVALID_TRACE_ID + or span_id == trace.INVALID_SPAN_ID + or self._trace_id_regex.fullmatch(trace_id) is None + or self._span_id_regex.fullmatch(span_id) is None + ): + return context + + trace_id = int(trace_id, 16) + span_id = int(span_id, 16) + options = 0 + # The b3 spec provides no defined behavior for both sample and + # flag values set. Since the setting of at least one implies + # the desire for some form of sampling, propagate if either + # header is set to allow. + if sampled in self._SAMPLE_PROPAGATE_VALUES or flags == "1": + options |= trace.TraceFlags.SAMPLED + + return trace.set_span_in_context( + trace.NonRecordingSpan( + trace.SpanContext( + # trace an span ids are encoded in hex, so must be converted + trace_id=trace_id, + span_id=span_id, + is_remote=True, + trace_flags=trace.TraceFlags(options), + trace_state=trace.TraceState(), + ) + ), + context, + ) + + def inject( + self, + carrier: CarrierT, + context: Context | None = None, + setter: Setter = default_setter, + ) -> None: + span = trace.get_current_span(context=context) + + span_context = span.get_span_context() + if span_context == trace.INVALID_SPAN_CONTEXT: + return + + sampled = (trace.TraceFlags.SAMPLED & span_context.trace_flags) != 0 + setter.set( + carrier, + self.TRACE_ID_KEY, + format_trace_id(span_context.trace_id), + ) + setter.set(carrier, self.SPAN_ID_KEY, format_span_id(span_context.span_id)) + setter.set(carrier, self.SAMPLED_KEY, "1" if sampled else "0") + + @property + def fields(self) -> set[str]: + return { + self.TRACE_ID_KEY, + self.SPAN_ID_KEY, + self.SAMPLED_KEY, + } + + +class B3SingleFormat(B3MultiFormat): + """Propagator for the B3 HTTP single-header format. + + See: https://github.com/openzipkin/b3-propagation + https://github.com/openzipkin/b3-propagation#single-header + """ + + def inject( + self, + carrier: CarrierT, + context: Context | None = None, + setter: Setter = default_setter, + ) -> None: + span = trace.get_current_span(context=context) + + span_context = span.get_span_context() + if span_context == trace.INVALID_SPAN_CONTEXT: + return + + sampled = (trace.TraceFlags.SAMPLED & span_context.trace_flags) != 0 + + fields = [ + format_trace_id(span_context.trace_id), + format_span_id(span_context.span_id), + "1" if sampled else "0", + ] + + setter.set(carrier, self.SINGLE_HEADER_KEY, "-".join(fields)) + + @property + def fields(self) -> set[str]: + return {self.SINGLE_HEADER_KEY} + + +class B3Format(B3MultiFormat): + @deprecated( + "B3Format is deprecated in favor of B3MultiFormat. Deprecated since version 1.2.0.", + ) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + +def _extract_first_element( + items: collections.abc.Iterable[CarrierT], +) -> CarrierT | None: + if items is None: + return None + return next(iter(items), None) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py new file mode 100644 index 00000000000..0101c361616 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py new file mode 100644 index 00000000000..801faa3d42a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py @@ -0,0 +1,78 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +import collections.abc +import logging + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.propagators import textmap + +logger = logging.getLogger(__name__) + + +class CompositePropagator(textmap.TextMapPropagator): + """CompositePropagator provides a mechanism for combining multiple + propagators into a single one. + + Args: + propagators: the list of propagators to use + """ + + def __init__(self, propagators: collections.abc.Sequence[textmap.TextMapPropagator]) -> None: + self._propagators = propagators + + def extract( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, + ) -> Context: + """Run each of the configured propagators with the given context and carrier. + Propagators are run in the order they are configured, if multiple + propagators write the same context key, the propagator later in the list + will override previous propagators. + + See `opentelemetry.propagators.textmap.TextMapPropagator.extract` + """ + for propagator in self._propagators: + context = propagator.extract(carrier, context, getter=getter) + return context # type: ignore + + def inject( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, + ) -> None: + """Run each of the configured propagators with the given context and carrier. + Propagators are run in the order they are configured, if multiple + propagators write the same carrier key, the propagator later in the list + will override previous propagators. + + See `opentelemetry.propagators.textmap.TextMapPropagator.inject` + """ + for propagator in self._propagators: + propagator.inject(carrier, context, setter=setter) + + @property + def fields(self) -> set[str]: + """Returns a set with the fields set in `inject`. + + See + `opentelemetry.propagators.textmap.TextMapPropagator.fields` + """ + composite_fields = set() + + for propagator in self._propagators: + for field in propagator.fields: + composite_fields.add(field) + + return composite_fields + + +@deprecated("You should use CompositePropagator. Deprecated since version 1.2.0.") +class CompositeHTTPPropagator(CompositePropagator): + """CompositeHTTPPropagator provides a mechanism for combining multiple + propagators into a single one. + """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py new file mode 100644 index 00000000000..504124d54cf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py @@ -0,0 +1,181 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import abc +import typing +from collections.abc import Iterable, Mapping, MutableMapping + +from opentelemetry.agent._vendor.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`. + """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py new file mode 100644 index 00000000000..d3e9a32f978 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/collector/logs/v1/logs_service.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.logs.v1 import logs_pb2 as opentelemetry_dot_proto_dot_logs_dot_v1_dot_logs__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n8opentelemetry/proto/collector/logs/v1/logs_service.proto\x12%opentelemetry.proto.collector.logs.v1\x1a&opentelemetry/proto/logs/v1/logs.proto\"\\\n\x18\x45xportLogsServiceRequest\x12@\n\rresource_logs\x18\x01 \x03(\x0b\x32).opentelemetry.proto.logs.v1.ResourceLogs\"u\n\x19\x45xportLogsServiceResponse\x12X\n\x0fpartial_success\x18\x01 \x01(\x0b\x32?.opentelemetry.proto.collector.logs.v1.ExportLogsPartialSuccess\"O\n\x18\x45xportLogsPartialSuccess\x12\x1c\n\x14rejected_log_records\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\x9d\x01\n\x0bLogsService\x12\x8d\x01\n\x06\x45xport\x12?.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest\x1a@.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse\"\x00\x42\x98\x01\n(io.opentelemetry.proto.collector.logs.v1B\x10LogsServiceProtoP\x01Z0go.opentelemetry.io/proto/otlp/collector/logs/v1\xaa\x02%OpenTelemetry.Proto.Collector.Logs.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.logs.v1.logs_service_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n(io.opentelemetry.proto.collector.logs.v1B\020LogsServiceProtoP\001Z0go.opentelemetry.io/proto/otlp/collector/logs/v1\252\002%OpenTelemetry.Proto.Collector.Logs.V1' + _globals['_EXPORTLOGSSERVICEREQUEST']._serialized_start=139 + _globals['_EXPORTLOGSSERVICEREQUEST']._serialized_end=231 + _globals['_EXPORTLOGSSERVICERESPONSE']._serialized_start=233 + _globals['_EXPORTLOGSSERVICERESPONSE']._serialized_end=350 + _globals['_EXPORTLOGSPARTIALSUCCESS']._serialized_start=352 + _globals['_EXPORTLOGSPARTIALSUCCESS']._serialized_end=431 + _globals['_LOGSSERVICE']._serialized_start=434 + _globals['_LOGSSERVICE']._serialized_end=591 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi new file mode 100644 index 00000000000..99e2a0ac101 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi @@ -0,0 +1,117 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2020, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import opentelemetry.proto.logs.v1.logs_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class ExportLogsServiceRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_LOGS_FIELD_NUMBER: builtins.int + @property + def resource_logs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.logs.v1.logs_pb2.ResourceLogs]: + """An array of ResourceLogs. + For data coming from a single resource this array will typically contain one + element. Intermediary nodes (such as OpenTelemetry Collector) that receive + data from multiple origins typically batch the data before forwarding further and + in that case this array will contain multiple elements. + """ + def __init__( + self, + *, + resource_logs: collections.abc.Iterable[opentelemetry.proto.logs.v1.logs_pb2.ResourceLogs] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["resource_logs", b"resource_logs"]) -> None: ... + +global___ExportLogsServiceRequest = ExportLogsServiceRequest + +@typing_extensions.final +class ExportLogsServiceResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int + @property + def partial_success(self) -> global___ExportLogsPartialSuccess: + """The details of a partially successful export request. + + If the request is only partially accepted + (i.e. when the server accepts only parts of the data and rejects the rest) + the server MUST initialize the `partial_success` field and MUST + set the `rejected_` with the number of items it rejected. + + Servers MAY also make use of the `partial_success` field to convey + warnings/suggestions to senders even when the request was fully accepted. + In such cases, the `rejected_` MUST have a value of `0` and + the `error_message` MUST be non-empty. + + A `partial_success` message with an empty value (rejected_ = 0 and + `error_message` = "") is equivalent to it not being set/present. Senders + SHOULD interpret it the same way as in the full success case. + """ + def __init__( + self, + *, + partial_success: global___ExportLogsPartialSuccess | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... + +global___ExportLogsServiceResponse = ExportLogsServiceResponse + +@typing_extensions.final +class ExportLogsPartialSuccess(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + REJECTED_LOG_RECORDS_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + rejected_log_records: builtins.int + """The number of rejected log records. + + A `rejected_` field holding a `0` value indicates that the + request was fully accepted. + """ + error_message: builtins.str + """A developer-facing human-readable message in English. It should be used + either to explain why the server rejected parts of the data during a partial + success or to convey warnings/suggestions during a full success. The message + should offer guidance on how users can address such issues. + + error_message is an optional field. An error_message with an empty value + is equivalent to it not being set. + """ + def __init__( + self, + *, + rejected_log_records: builtins.int = ..., + error_message: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_log_records", b"rejected_log_records"]) -> None: ... + +global___ExportLogsPartialSuccess = ExportLogsPartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py new file mode 100644 index 00000000000..603b072d9dc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/collector/metrics/v1/metrics_service.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1 import metrics_pb2 as opentelemetry_dot_proto_dot_metrics_dot_v1_dot_metrics__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n>opentelemetry/proto/collector/metrics/v1/metrics_service.proto\x12(opentelemetry.proto.collector.metrics.v1\x1a,opentelemetry/proto/metrics/v1/metrics.proto\"h\n\x1b\x45xportMetricsServiceRequest\x12I\n\x10resource_metrics\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.ResourceMetrics\"~\n\x1c\x45xportMetricsServiceResponse\x12^\n\x0fpartial_success\x18\x01 \x01(\x0b\x32\x45.opentelemetry.proto.collector.metrics.v1.ExportMetricsPartialSuccess\"R\n\x1b\x45xportMetricsPartialSuccess\x12\x1c\n\x14rejected_data_points\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\xac\x01\n\x0eMetricsService\x12\x99\x01\n\x06\x45xport\x12\x45.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest\x1a\x46.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse\"\x00\x42\xa4\x01\n+io.opentelemetry.proto.collector.metrics.v1B\x13MetricsServiceProtoP\x01Z3go.opentelemetry.io/proto/otlp/collector/metrics/v1\xaa\x02(OpenTelemetry.Proto.Collector.Metrics.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.metrics.v1.metrics_service_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n+io.opentelemetry.proto.collector.metrics.v1B\023MetricsServiceProtoP\001Z3go.opentelemetry.io/proto/otlp/collector/metrics/v1\252\002(OpenTelemetry.Proto.Collector.Metrics.V1' + _globals['_EXPORTMETRICSSERVICEREQUEST']._serialized_start=154 + _globals['_EXPORTMETRICSSERVICEREQUEST']._serialized_end=258 + _globals['_EXPORTMETRICSSERVICERESPONSE']._serialized_start=260 + _globals['_EXPORTMETRICSSERVICERESPONSE']._serialized_end=386 + _globals['_EXPORTMETRICSPARTIALSUCCESS']._serialized_start=388 + _globals['_EXPORTMETRICSPARTIALSUCCESS']._serialized_end=470 + _globals['_METRICSSERVICE']._serialized_start=473 + _globals['_METRICSSERVICE']._serialized_end=645 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi new file mode 100644 index 00000000000..fe3c44f3c37 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi @@ -0,0 +1,117 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2019, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import opentelemetry.proto.metrics.v1.metrics_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class ExportMetricsServiceRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_METRICS_FIELD_NUMBER: builtins.int + @property + def resource_metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.metrics.v1.metrics_pb2.ResourceMetrics]: + """An array of ResourceMetrics. + For data coming from a single resource this array will typically contain one + element. Intermediary nodes (such as OpenTelemetry Collector) that receive + data from multiple origins typically batch the data before forwarding further and + in that case this array will contain multiple elements. + """ + def __init__( + self, + *, + resource_metrics: collections.abc.Iterable[opentelemetry.proto.metrics.v1.metrics_pb2.ResourceMetrics] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["resource_metrics", b"resource_metrics"]) -> None: ... + +global___ExportMetricsServiceRequest = ExportMetricsServiceRequest + +@typing_extensions.final +class ExportMetricsServiceResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int + @property + def partial_success(self) -> global___ExportMetricsPartialSuccess: + """The details of a partially successful export request. + + If the request is only partially accepted + (i.e. when the server accepts only parts of the data and rejects the rest) + the server MUST initialize the `partial_success` field and MUST + set the `rejected_` with the number of items it rejected. + + Servers MAY also make use of the `partial_success` field to convey + warnings/suggestions to senders even when the request was fully accepted. + In such cases, the `rejected_` MUST have a value of `0` and + the `error_message` MUST be non-empty. + + A `partial_success` message with an empty value (rejected_ = 0 and + `error_message` = "") is equivalent to it not being set/present. Senders + SHOULD interpret it the same way as in the full success case. + """ + def __init__( + self, + *, + partial_success: global___ExportMetricsPartialSuccess | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... + +global___ExportMetricsServiceResponse = ExportMetricsServiceResponse + +@typing_extensions.final +class ExportMetricsPartialSuccess(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + REJECTED_DATA_POINTS_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + rejected_data_points: builtins.int + """The number of rejected data points. + + A `rejected_` field holding a `0` value indicates that the + request was fully accepted. + """ + error_message: builtins.str + """A developer-facing human-readable message in English. It should be used + either to explain why the server rejected parts of the data during a partial + success or to convey warnings/suggestions during a full success. The message + should offer guidance on how users can address such issues. + + error_message is an optional field. An error_message with an empty value + is equivalent to it not being set. + """ + def __init__( + self, + *, + rejected_data_points: builtins.int = ..., + error_message: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_data_points", b"rejected_data_points"]) -> None: ... + +global___ExportMetricsPartialSuccess = ExportMetricsPartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py new file mode 100644 index 00000000000..0fcb9d8b503 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/collector/profiles/v1development/profiles_service.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.profiles.v1development import profiles_pb2 as opentelemetry_dot_proto_dot_profiles_dot_v1development_dot_profiles__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\nKopentelemetry/proto/collector/profiles/v1development/profiles_service.proto\x12\x34opentelemetry.proto.collector.profiles.v1development\x1a\x39opentelemetry/proto/profiles/v1development/profiles.proto\"\xcb\x01\n\x1c\x45xportProfilesServiceRequest\x12W\n\x11resource_profiles\x18\x01 \x03(\x0b\x32<.opentelemetry.proto.profiles.v1development.ResourceProfiles\x12R\n\ndictionary\x18\x02 \x01(\x0b\x32>.opentelemetry.proto.profiles.v1development.ProfilesDictionary\"\x8c\x01\n\x1d\x45xportProfilesServiceResponse\x12k\n\x0fpartial_success\x18\x01 \x01(\x0b\x32R.opentelemetry.proto.collector.profiles.v1development.ExportProfilesPartialSuccess\"P\n\x1c\x45xportProfilesPartialSuccess\x12\x19\n\x11rejected_profiles\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\xc7\x01\n\x0fProfilesService\x12\xb3\x01\n\x06\x45xport\x12R.opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceRequest\x1aS.opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceResponse\"\x00\x42\xc9\x01\n7io.opentelemetry.proto.collector.profiles.v1developmentB\x14ProfilesServiceProtoP\x01Z?go.opentelemetry.io/proto/otlp/collector/profiles/v1development\xaa\x02\x34OpenTelemetry.Proto.Collector.Profiles.V1Developmentb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.profiles.v1development.profiles_service_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n7io.opentelemetry.proto.collector.profiles.v1developmentB\024ProfilesServiceProtoP\001Z?go.opentelemetry.io/proto/otlp/collector/profiles/v1development\252\0024OpenTelemetry.Proto.Collector.Profiles.V1Development' + _globals['_EXPORTPROFILESSERVICEREQUEST']._serialized_start=193 + _globals['_EXPORTPROFILESSERVICEREQUEST']._serialized_end=396 + _globals['_EXPORTPROFILESSERVICERESPONSE']._serialized_start=399 + _globals['_EXPORTPROFILESSERVICERESPONSE']._serialized_end=539 + _globals['_EXPORTPROFILESPARTIALSUCCESS']._serialized_start=541 + _globals['_EXPORTPROFILESPARTIALSUCCESS']._serialized_end=621 + _globals['_PROFILESSERVICE']._serialized_start=624 + _globals['_PROFILESSERVICE']._serialized_end=823 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi new file mode 100644 index 00000000000..e8b7a82095c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi @@ -0,0 +1,123 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2023, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import opentelemetry.proto.profiles.v1development.profiles_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class ExportProfilesServiceRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_PROFILES_FIELD_NUMBER: builtins.int + DICTIONARY_FIELD_NUMBER: builtins.int + @property + def resource_profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.profiles.v1development.profiles_pb2.ResourceProfiles]: + """An array of ResourceProfiles. + For data coming from a single resource this array will typically contain one + element. Intermediary nodes (such as OpenTelemetry Collector) that receive + data from multiple origins typically batch the data before forwarding further and + in that case this array will contain multiple elements. + """ + @property + def dictionary(self) -> opentelemetry.proto.profiles.v1development.profiles_pb2.ProfilesDictionary: + """The reference table containing all data shared by profiles across the message being sent.""" + def __init__( + self, + *, + resource_profiles: collections.abc.Iterable[opentelemetry.proto.profiles.v1development.profiles_pb2.ResourceProfiles] | None = ..., + dictionary: opentelemetry.proto.profiles.v1development.profiles_pb2.ProfilesDictionary | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary", "resource_profiles", b"resource_profiles"]) -> None: ... + +global___ExportProfilesServiceRequest = ExportProfilesServiceRequest + +@typing_extensions.final +class ExportProfilesServiceResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int + @property + def partial_success(self) -> global___ExportProfilesPartialSuccess: + """The details of a partially successful export request. + + If the request is only partially accepted + (i.e. when the server accepts only parts of the data and rejects the rest) + the server MUST initialize the `partial_success` field and MUST + set the `rejected_` with the number of items it rejected. + + Servers MAY also make use of the `partial_success` field to convey + warnings/suggestions to senders even when the request was fully accepted. + In such cases, the `rejected_` MUST have a value of `0` and + the `error_message` MUST be non-empty. + + A `partial_success` message with an empty value (rejected_ = 0 and + `error_message` = "") is equivalent to it not being set/present. Senders + SHOULD interpret it the same way as in the full success case. + """ + def __init__( + self, + *, + partial_success: global___ExportProfilesPartialSuccess | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... + +global___ExportProfilesServiceResponse = ExportProfilesServiceResponse + +@typing_extensions.final +class ExportProfilesPartialSuccess(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + REJECTED_PROFILES_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + rejected_profiles: builtins.int + """The number of rejected profiles. + + A `rejected_` field holding a `0` value indicates that the + request was fully accepted. + """ + error_message: builtins.str + """A developer-facing human-readable message in English. It should be used + either to explain why the server rejected parts of the data during a partial + success or to convey warnings/suggestions during a full success. The message + should offer guidance on how users can address such issues. + + error_message is an optional field. An error_message with an empty value + is equivalent to it not being set. + """ + def __init__( + self, + *, + rejected_profiles: builtins.int = ..., + error_message: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_profiles", b"rejected_profiles"]) -> None: ... + +global___ExportProfilesPartialSuccess = ExportProfilesPartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py new file mode 100644 index 00000000000..db09e3babf1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/collector/trace/v1/trace_service.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1 import trace_pb2 as opentelemetry_dot_proto_dot_trace_dot_v1_dot_trace__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n:opentelemetry/proto/collector/trace/v1/trace_service.proto\x12&opentelemetry.proto.collector.trace.v1\x1a(opentelemetry/proto/trace/v1/trace.proto\"`\n\x19\x45xportTraceServiceRequest\x12\x43\n\x0eresource_spans\x18\x01 \x03(\x0b\x32+.opentelemetry.proto.trace.v1.ResourceSpans\"x\n\x1a\x45xportTraceServiceResponse\x12Z\n\x0fpartial_success\x18\x01 \x01(\x0b\x32\x41.opentelemetry.proto.collector.trace.v1.ExportTracePartialSuccess\"J\n\x19\x45xportTracePartialSuccess\x12\x16\n\x0erejected_spans\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\xa2\x01\n\x0cTraceService\x12\x91\x01\n\x06\x45xport\x12\x41.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest\x1a\x42.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse\"\x00\x42\x9c\x01\n)io.opentelemetry.proto.collector.trace.v1B\x11TraceServiceProtoP\x01Z1go.opentelemetry.io/proto/otlp/collector/trace/v1\xaa\x02&OpenTelemetry.Proto.Collector.Trace.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.trace.v1.trace_service_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n)io.opentelemetry.proto.collector.trace.v1B\021TraceServiceProtoP\001Z1go.opentelemetry.io/proto/otlp/collector/trace/v1\252\002&OpenTelemetry.Proto.Collector.Trace.V1' + _globals['_EXPORTTRACESERVICEREQUEST']._serialized_start=144 + _globals['_EXPORTTRACESERVICEREQUEST']._serialized_end=240 + _globals['_EXPORTTRACESERVICERESPONSE']._serialized_start=242 + _globals['_EXPORTTRACESERVICERESPONSE']._serialized_end=362 + _globals['_EXPORTTRACEPARTIALSUCCESS']._serialized_start=364 + _globals['_EXPORTTRACEPARTIALSUCCESS']._serialized_end=438 + _globals['_TRACESERVICE']._serialized_start=441 + _globals['_TRACESERVICE']._serialized_end=603 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi new file mode 100644 index 00000000000..ceb4db5213f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi @@ -0,0 +1,117 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2019, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import opentelemetry.proto.trace.v1.trace_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class ExportTraceServiceRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_SPANS_FIELD_NUMBER: builtins.int + @property + def resource_spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.trace.v1.trace_pb2.ResourceSpans]: + """An array of ResourceSpans. + For data coming from a single resource this array will typically contain one + element. Intermediary nodes (such as OpenTelemetry Collector) that receive + data from multiple origins typically batch the data before forwarding further and + in that case this array will contain multiple elements. + """ + def __init__( + self, + *, + resource_spans: collections.abc.Iterable[opentelemetry.proto.trace.v1.trace_pb2.ResourceSpans] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["resource_spans", b"resource_spans"]) -> None: ... + +global___ExportTraceServiceRequest = ExportTraceServiceRequest + +@typing_extensions.final +class ExportTraceServiceResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int + @property + def partial_success(self) -> global___ExportTracePartialSuccess: + """The details of a partially successful export request. + + If the request is only partially accepted + (i.e. when the server accepts only parts of the data and rejects the rest) + the server MUST initialize the `partial_success` field and MUST + set the `rejected_` with the number of items it rejected. + + Servers MAY also make use of the `partial_success` field to convey + warnings/suggestions to senders even when the request was fully accepted. + In such cases, the `rejected_` MUST have a value of `0` and + the `error_message` MUST be non-empty. + + A `partial_success` message with an empty value (rejected_ = 0 and + `error_message` = "") is equivalent to it not being set/present. Senders + SHOULD interpret it the same way as in the full success case. + """ + def __init__( + self, + *, + partial_success: global___ExportTracePartialSuccess | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... + +global___ExportTraceServiceResponse = ExportTraceServiceResponse + +@typing_extensions.final +class ExportTracePartialSuccess(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + REJECTED_SPANS_FIELD_NUMBER: builtins.int + ERROR_MESSAGE_FIELD_NUMBER: builtins.int + rejected_spans: builtins.int + """The number of rejected spans. + + A `rejected_` field holding a `0` value indicates that the + request was fully accepted. + """ + error_message: builtins.str + """A developer-facing human-readable message in English. It should be used + either to explain why the server rejected parts of the data during a partial + success or to convey warnings/suggestions during a full success. The message + should offer guidance on how users can address such issues. + + error_message is an optional field. An error_message with an empty value + is equivalent to it not being set. + """ + def __init__( + self, + *, + rejected_spans: builtins.int = ..., + error_message: builtins.str = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_spans", b"rejected_spans"]) -> None: ... + +global___ExportTracePartialSuccess = ExportTracePartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py new file mode 100644 index 00000000000..07d0de164fc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/common/v1/common.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*opentelemetry/proto/common/v1/common.proto\x12\x1dopentelemetry.proto.common.v1\"\xad\x02\n\x08\x41nyValue\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12@\n\x0b\x61rray_value\x18\x05 \x01(\x0b\x32).opentelemetry.proto.common.v1.ArrayValueH\x00\x12\x43\n\x0ckvlist_value\x18\x06 \x01(\x0b\x32+.opentelemetry.proto.common.v1.KeyValueListH\x00\x12\x15\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00\x12\x1f\n\x15string_value_strindex\x18\x08 \x01(\x05H\x00\x42\x07\n\x05value\"E\n\nArrayValue\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\"G\n\x0cKeyValueList\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\"e\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\x12\x14\n\x0ckey_strindex\x18\x03 \x01(\x05\"\x94\x01\n\x14InstrumentationScope\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12;\n\nattributes\x18\x03 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x04 \x01(\r\"X\n\tEntityRef\x12\x12\n\nschema_url\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0f\n\x07id_keys\x18\x03 \x03(\t\x12\x18\n\x10\x64\x65scription_keys\x18\x04 \x03(\tB{\n io.opentelemetry.proto.common.v1B\x0b\x43ommonProtoP\x01Z(go.opentelemetry.io/proto/otlp/common/v1\xaa\x02\x1dOpenTelemetry.Proto.Common.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n io.opentelemetry.proto.common.v1B\013CommonProtoP\001Z(go.opentelemetry.io/proto/otlp/common/v1\252\002\035OpenTelemetry.Proto.Common.V1' + _globals['_ANYVALUE']._serialized_start=78 + _globals['_ANYVALUE']._serialized_end=379 + _globals['_ARRAYVALUE']._serialized_start=381 + _globals['_ARRAYVALUE']._serialized_end=450 + _globals['_KEYVALUELIST']._serialized_start=452 + _globals['_KEYVALUELIST']._serialized_end=523 + _globals['_KEYVALUE']._serialized_start=525 + _globals['_KEYVALUE']._serialized_end=626 + _globals['_INSTRUMENTATIONSCOPE']._serialized_start=629 + _globals['_INSTRUMENTATIONSCOPE']._serialized_end=777 + _globals['_ENTITYREF']._serialized_start=779 + _globals['_ENTITYREF']._serialized_end=867 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi new file mode 100644 index 00000000000..205bba7510f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi @@ -0,0 +1,280 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2019, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class AnyValue(google.protobuf.message.Message): + """Represents any type of attribute value. AnyValue may contain a + primitive value such as a string or integer or it may contain an arbitrary nested + object containing arrays, key-value lists and primitives. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STRING_VALUE_FIELD_NUMBER: builtins.int + BOOL_VALUE_FIELD_NUMBER: builtins.int + INT_VALUE_FIELD_NUMBER: builtins.int + DOUBLE_VALUE_FIELD_NUMBER: builtins.int + ARRAY_VALUE_FIELD_NUMBER: builtins.int + KVLIST_VALUE_FIELD_NUMBER: builtins.int + BYTES_VALUE_FIELD_NUMBER: builtins.int + STRING_VALUE_STRINDEX_FIELD_NUMBER: builtins.int + string_value: builtins.str + bool_value: builtins.bool + int_value: builtins.int + double_value: builtins.float + @property + def array_value(self) -> global___ArrayValue: ... + @property + def kvlist_value(self) -> global___KeyValueList: ... + bytes_value: builtins.bytes + string_value_strindex: builtins.int + """Reference to the string value in ProfilesDictionary.string_table. + + Note: This is currently used exclusively in the Profiling signal. + Implementers of OTLP receivers for signals other than Profiling should + treat the presence of this value as a non-fatal issue. + Log an error or warning indicating an unexpected field intended for the + Profiling signal and process the data as if this value were absent or + empty, ignoring its semantic content for the non-Profiling signal. + + Status: [Development] + """ + def __init__( + self, + *, + string_value: builtins.str = ..., + bool_value: builtins.bool = ..., + int_value: builtins.int = ..., + double_value: builtins.float = ..., + array_value: global___ArrayValue | None = ..., + kvlist_value: global___KeyValueList | None = ..., + bytes_value: builtins.bytes = ..., + string_value_strindex: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["array_value", b"array_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "double_value", b"double_value", "int_value", b"int_value", "kvlist_value", b"kvlist_value", "string_value", b"string_value", "string_value_strindex", b"string_value_strindex", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["array_value", b"array_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "double_value", b"double_value", "int_value", b"int_value", "kvlist_value", b"kvlist_value", "string_value", b"string_value", "string_value_strindex", b"string_value_strindex", "value", b"value"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["string_value", "bool_value", "int_value", "double_value", "array_value", "kvlist_value", "bytes_value", "string_value_strindex"] | None: ... + +global___AnyValue = AnyValue + +@typing_extensions.final +class ArrayValue(google.protobuf.message.Message): + """ArrayValue is a list of AnyValue messages. We need ArrayValue as a message + since oneof in AnyValue does not allow repeated fields. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUES_FIELD_NUMBER: builtins.int + @property + def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AnyValue]: + """Array of values. The array may be empty (contain 0 elements).""" + def __init__( + self, + *, + values: collections.abc.Iterable[global___AnyValue] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["values", b"values"]) -> None: ... + +global___ArrayValue = ArrayValue + +@typing_extensions.final +class KeyValueList(google.protobuf.message.Message): + """KeyValueList is a list of KeyValue messages. We need KeyValueList as a message + since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need + a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to + avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches + are semantically equivalent. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VALUES_FIELD_NUMBER: builtins.int + @property + def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___KeyValue]: + """A collection of key/value pairs of key-value pairs. The list may be empty (may + contain 0 elements). + + The keys MUST be unique (it is not allowed to have more than one + value with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + def __init__( + self, + *, + values: collections.abc.Iterable[global___KeyValue] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["values", b"values"]) -> None: ... + +global___KeyValueList = KeyValueList + +@typing_extensions.final +class KeyValue(google.protobuf.message.Message): + """Represents a key-value pair that is used to store Span attributes, Link + attributes, etc. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + KEY_STRINDEX_FIELD_NUMBER: builtins.int + key: builtins.str + """The key name of the pair. + key_ref MUST NOT be set if key is used. + """ + @property + def value(self) -> global___AnyValue: + """The value of the pair.""" + key_strindex: builtins.int + """Reference to the string key in ProfilesDictionary.string_table. + key MUST NOT be set if key_strindex is used. + + Note: This is currently used exclusively in the Profiling signal. + Implementers of OTLP receivers for signals other than Profiling should + treat the presence of this key as a non-fatal issue. + Log an error or warning indicating an unexpected field intended for the + Profiling signal and process the data as if this value were absent or + empty, ignoring its semantic content for the non-Profiling signal. + + Status: [Development] + """ + def __init__( + self, + *, + key: builtins.str = ..., + value: global___AnyValue | None = ..., + key_strindex: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "key_strindex", b"key_strindex", "value", b"value"]) -> None: ... + +global___KeyValue = KeyValue + +@typing_extensions.final +class InstrumentationScope(google.protobuf.message.Message): + """InstrumentationScope is a message representing the instrumentation scope information + such as the fully qualified name and version. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + VERSION_FIELD_NUMBER: builtins.int + ATTRIBUTES_FIELD_NUMBER: builtins.int + DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int + name: builtins.str + """A name denoting the Instrumentation scope. + An empty instrumentation scope name means the name is unknown. + """ + version: builtins.str + """Defines the version of the instrumentation scope. + An empty instrumentation scope version means the version is unknown. + """ + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___KeyValue]: + """Additional attributes that describe the scope. [Optional]. + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + dropped_attributes_count: builtins.int + """The number of attributes that were discarded. Attributes + can be discarded because their keys are too long or because there are too many + attributes. If this value is 0, then no attributes were dropped. + """ + def __init__( + self, + *, + name: builtins.str = ..., + version: builtins.str = ..., + attributes: collections.abc.Iterable[global___KeyValue] | None = ..., + dropped_attributes_count: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "name", b"name", "version", b"version"]) -> None: ... + +global___InstrumentationScope = InstrumentationScope + +@typing_extensions.final +class EntityRef(google.protobuf.message.Message): + """A reference to an Entity. + Entity represents an object of interest associated with produced telemetry: e.g spans, metrics, profiles, or logs. + + Status: [Development] + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCHEMA_URL_FIELD_NUMBER: builtins.int + TYPE_FIELD_NUMBER: builtins.int + ID_KEYS_FIELD_NUMBER: builtins.int + DESCRIPTION_KEYS_FIELD_NUMBER: builtins.int + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the entity data + is recorded in. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + + This schema_url applies to the data in this message and to the Resource attributes + referenced by id_keys and description_keys. + TODO: discuss if we are happy with this somewhat complicated definition of what + the schema_url applies to. + + This field obsoletes the schema_url field in ResourceMetrics/ResourceSpans/ResourceLogs. + """ + type: builtins.str + """Defines the type of the entity. MUST not change during the lifetime of the entity. + For example: "service" or "host". This field is required and MUST not be empty + for valid entities. + """ + @property + def id_keys(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Attribute Keys that identify the entity. + MUST not change during the lifetime of the entity. The Id must contain at least one attribute. + These keys MUST exist in the containing {message}.attributes. + """ + @property + def description_keys(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """Descriptive (non-identifying) attribute keys of the entity. + MAY change over the lifetime of the entity. MAY be empty. + These attribute keys are not part of entity's identity. + These keys MUST exist in the containing {message}.attributes. + """ + def __init__( + self, + *, + schema_url: builtins.str = ..., + type: builtins.str = ..., + id_keys: collections.abc.Iterable[builtins.str] | None = ..., + description_keys: collections.abc.Iterable[builtins.str] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["description_keys", b"description_keys", "id_keys", b"id_keys", "schema_url", b"schema_url", "type", b"type"]) -> None: ... + +global___EntityRef = EntityRef diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py new file mode 100644 index 00000000000..e88e99462f0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/logs/v1/logs.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&opentelemetry/proto/logs/v1/logs.proto\x12\x1bopentelemetry.proto.logs.v1\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"L\n\x08LogsData\x12@\n\rresource_logs\x18\x01 \x03(\x0b\x32).opentelemetry.proto.logs.v1.ResourceLogs\"\xa3\x01\n\x0cResourceLogs\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12:\n\nscope_logs\x18\x02 \x03(\x0b\x32&.opentelemetry.proto.logs.v1.ScopeLogs\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\xa0\x01\n\tScopeLogs\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12;\n\x0blog_records\x18\x02 \x03(\x0b\x32&.opentelemetry.proto.logs.v1.LogRecord\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\x83\x03\n\tLogRecord\x12\x16\n\x0etime_unix_nano\x18\x01 \x01(\x06\x12\x1f\n\x17observed_time_unix_nano\x18\x0b \x01(\x06\x12\x44\n\x0fseverity_number\x18\x02 \x01(\x0e\x32+.opentelemetry.proto.logs.v1.SeverityNumber\x12\x15\n\rseverity_text\x18\x03 \x01(\t\x12\x35\n\x04\x62ody\x18\x05 \x01(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\x12;\n\nattributes\x18\x06 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x07 \x01(\r\x12\r\n\x05\x66lags\x18\x08 \x01(\x07\x12\x10\n\x08trace_id\x18\t \x01(\x0c\x12\x0f\n\x07span_id\x18\n \x01(\x0c\x12\x12\n\nevent_name\x18\x0c \x01(\tJ\x04\x08\x04\x10\x05*\xc3\x05\n\x0eSeverityNumber\x12\x1f\n\x1bSEVERITY_NUMBER_UNSPECIFIED\x10\x00\x12\x19\n\x15SEVERITY_NUMBER_TRACE\x10\x01\x12\x1a\n\x16SEVERITY_NUMBER_TRACE2\x10\x02\x12\x1a\n\x16SEVERITY_NUMBER_TRACE3\x10\x03\x12\x1a\n\x16SEVERITY_NUMBER_TRACE4\x10\x04\x12\x19\n\x15SEVERITY_NUMBER_DEBUG\x10\x05\x12\x1a\n\x16SEVERITY_NUMBER_DEBUG2\x10\x06\x12\x1a\n\x16SEVERITY_NUMBER_DEBUG3\x10\x07\x12\x1a\n\x16SEVERITY_NUMBER_DEBUG4\x10\x08\x12\x18\n\x14SEVERITY_NUMBER_INFO\x10\t\x12\x19\n\x15SEVERITY_NUMBER_INFO2\x10\n\x12\x19\n\x15SEVERITY_NUMBER_INFO3\x10\x0b\x12\x19\n\x15SEVERITY_NUMBER_INFO4\x10\x0c\x12\x18\n\x14SEVERITY_NUMBER_WARN\x10\r\x12\x19\n\x15SEVERITY_NUMBER_WARN2\x10\x0e\x12\x19\n\x15SEVERITY_NUMBER_WARN3\x10\x0f\x12\x19\n\x15SEVERITY_NUMBER_WARN4\x10\x10\x12\x19\n\x15SEVERITY_NUMBER_ERROR\x10\x11\x12\x1a\n\x16SEVERITY_NUMBER_ERROR2\x10\x12\x12\x1a\n\x16SEVERITY_NUMBER_ERROR3\x10\x13\x12\x1a\n\x16SEVERITY_NUMBER_ERROR4\x10\x14\x12\x19\n\x15SEVERITY_NUMBER_FATAL\x10\x15\x12\x1a\n\x16SEVERITY_NUMBER_FATAL2\x10\x16\x12\x1a\n\x16SEVERITY_NUMBER_FATAL3\x10\x17\x12\x1a\n\x16SEVERITY_NUMBER_FATAL4\x10\x18*Y\n\x0eLogRecordFlags\x12\x1f\n\x1bLOG_RECORD_FLAGS_DO_NOT_USE\x10\x00\x12&\n!LOG_RECORD_FLAGS_TRACE_FLAGS_MASK\x10\xff\x01\x42s\n\x1eio.opentelemetry.proto.logs.v1B\tLogsProtoP\x01Z&go.opentelemetry.io/proto/otlp/logs/v1\xaa\x02\x1bOpenTelemetry.Proto.Logs.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.logs.v1.logs_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\036io.opentelemetry.proto.logs.v1B\tLogsProtoP\001Z&go.opentelemetry.io/proto/otlp/logs/v1\252\002\033OpenTelemetry.Proto.Logs.V1' + _globals['_SEVERITYNUMBER']._serialized_start=961 + _globals['_SEVERITYNUMBER']._serialized_end=1668 + _globals['_LOGRECORDFLAGS']._serialized_start=1670 + _globals['_LOGRECORDFLAGS']._serialized_end=1759 + _globals['_LOGSDATA']._serialized_start=163 + _globals['_LOGSDATA']._serialized_end=239 + _globals['_RESOURCELOGS']._serialized_start=242 + _globals['_RESOURCELOGS']._serialized_end=405 + _globals['_SCOPELOGS']._serialized_start=408 + _globals['_SCOPELOGS']._serialized_end=568 + _globals['_LOGRECORD']._serialized_start=571 + _globals['_LOGRECORD']._serialized_end=958 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi new file mode 100644 index 00000000000..03edd535b7c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi @@ -0,0 +1,365 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2020, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import opentelemetry.proto.common.v1.common_pb2 +import opentelemetry.proto.resource.v1.resource_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _SeverityNumber: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SeverityNumberEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SeverityNumber.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SEVERITY_NUMBER_UNSPECIFIED: _SeverityNumber.ValueType # 0 + SEVERITY_NUMBER_TRACE: _SeverityNumber.ValueType # 1 + SEVERITY_NUMBER_TRACE2: _SeverityNumber.ValueType # 2 + SEVERITY_NUMBER_TRACE3: _SeverityNumber.ValueType # 3 + SEVERITY_NUMBER_TRACE4: _SeverityNumber.ValueType # 4 + SEVERITY_NUMBER_DEBUG: _SeverityNumber.ValueType # 5 + SEVERITY_NUMBER_DEBUG2: _SeverityNumber.ValueType # 6 + SEVERITY_NUMBER_DEBUG3: _SeverityNumber.ValueType # 7 + SEVERITY_NUMBER_DEBUG4: _SeverityNumber.ValueType # 8 + SEVERITY_NUMBER_INFO: _SeverityNumber.ValueType # 9 + SEVERITY_NUMBER_INFO2: _SeverityNumber.ValueType # 10 + SEVERITY_NUMBER_INFO3: _SeverityNumber.ValueType # 11 + SEVERITY_NUMBER_INFO4: _SeverityNumber.ValueType # 12 + SEVERITY_NUMBER_WARN: _SeverityNumber.ValueType # 13 + SEVERITY_NUMBER_WARN2: _SeverityNumber.ValueType # 14 + SEVERITY_NUMBER_WARN3: _SeverityNumber.ValueType # 15 + SEVERITY_NUMBER_WARN4: _SeverityNumber.ValueType # 16 + SEVERITY_NUMBER_ERROR: _SeverityNumber.ValueType # 17 + SEVERITY_NUMBER_ERROR2: _SeverityNumber.ValueType # 18 + SEVERITY_NUMBER_ERROR3: _SeverityNumber.ValueType # 19 + SEVERITY_NUMBER_ERROR4: _SeverityNumber.ValueType # 20 + SEVERITY_NUMBER_FATAL: _SeverityNumber.ValueType # 21 + SEVERITY_NUMBER_FATAL2: _SeverityNumber.ValueType # 22 + SEVERITY_NUMBER_FATAL3: _SeverityNumber.ValueType # 23 + SEVERITY_NUMBER_FATAL4: _SeverityNumber.ValueType # 24 + +class SeverityNumber(_SeverityNumber, metaclass=_SeverityNumberEnumTypeWrapper): + """Possible values for LogRecord.SeverityNumber.""" + +SEVERITY_NUMBER_UNSPECIFIED: SeverityNumber.ValueType # 0 +SEVERITY_NUMBER_TRACE: SeverityNumber.ValueType # 1 +SEVERITY_NUMBER_TRACE2: SeverityNumber.ValueType # 2 +SEVERITY_NUMBER_TRACE3: SeverityNumber.ValueType # 3 +SEVERITY_NUMBER_TRACE4: SeverityNumber.ValueType # 4 +SEVERITY_NUMBER_DEBUG: SeverityNumber.ValueType # 5 +SEVERITY_NUMBER_DEBUG2: SeverityNumber.ValueType # 6 +SEVERITY_NUMBER_DEBUG3: SeverityNumber.ValueType # 7 +SEVERITY_NUMBER_DEBUG4: SeverityNumber.ValueType # 8 +SEVERITY_NUMBER_INFO: SeverityNumber.ValueType # 9 +SEVERITY_NUMBER_INFO2: SeverityNumber.ValueType # 10 +SEVERITY_NUMBER_INFO3: SeverityNumber.ValueType # 11 +SEVERITY_NUMBER_INFO4: SeverityNumber.ValueType # 12 +SEVERITY_NUMBER_WARN: SeverityNumber.ValueType # 13 +SEVERITY_NUMBER_WARN2: SeverityNumber.ValueType # 14 +SEVERITY_NUMBER_WARN3: SeverityNumber.ValueType # 15 +SEVERITY_NUMBER_WARN4: SeverityNumber.ValueType # 16 +SEVERITY_NUMBER_ERROR: SeverityNumber.ValueType # 17 +SEVERITY_NUMBER_ERROR2: SeverityNumber.ValueType # 18 +SEVERITY_NUMBER_ERROR3: SeverityNumber.ValueType # 19 +SEVERITY_NUMBER_ERROR4: SeverityNumber.ValueType # 20 +SEVERITY_NUMBER_FATAL: SeverityNumber.ValueType # 21 +SEVERITY_NUMBER_FATAL2: SeverityNumber.ValueType # 22 +SEVERITY_NUMBER_FATAL3: SeverityNumber.ValueType # 23 +SEVERITY_NUMBER_FATAL4: SeverityNumber.ValueType # 24 +global___SeverityNumber = SeverityNumber + +class _LogRecordFlags: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _LogRecordFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_LogRecordFlags.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + LOG_RECORD_FLAGS_DO_NOT_USE: _LogRecordFlags.ValueType # 0 + """The zero value for the enum. Should not be used for comparisons. + Instead use bitwise "and" with the appropriate mask as shown above. + """ + LOG_RECORD_FLAGS_TRACE_FLAGS_MASK: _LogRecordFlags.ValueType # 255 + """Bits 0-7 are used for trace flags.""" + +class LogRecordFlags(_LogRecordFlags, metaclass=_LogRecordFlagsEnumTypeWrapper): + """LogRecordFlags represents constants used to interpret the + LogRecord.flags field, which is protobuf 'fixed32' type and is to + be used as bit-fields. Each non-zero value defined in this enum is + a bit-mask. To extract the bit-field, for example, use an + expression like: + + (logRecord.flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK) + """ + +LOG_RECORD_FLAGS_DO_NOT_USE: LogRecordFlags.ValueType # 0 +"""The zero value for the enum. Should not be used for comparisons. +Instead use bitwise "and" with the appropriate mask as shown above. +""" +LOG_RECORD_FLAGS_TRACE_FLAGS_MASK: LogRecordFlags.ValueType # 255 +"""Bits 0-7 are used for trace flags.""" +global___LogRecordFlags = LogRecordFlags + +@typing_extensions.final +class LogsData(google.protobuf.message.Message): + """LogsData represents the logs data that can be stored in a persistent storage, + OR can be embedded by other protocols that transfer OTLP logs data but do not + implement the OTLP protocol. + + The main difference between this message and collector protocol is that + in this message there will not be any "control" or "metadata" specific to + OTLP protocol. + + When new fields are added into this message, the OTLP request MUST be updated + as well. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_LOGS_FIELD_NUMBER: builtins.int + @property + def resource_logs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceLogs]: + """An array of ResourceLogs. + For data coming from a single resource this array will typically contain + one element. Intermediary nodes that receive data from multiple origins + typically batch the data before forwarding further and in that case this + array will contain multiple elements. + """ + def __init__( + self, + *, + resource_logs: collections.abc.Iterable[global___ResourceLogs] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["resource_logs", b"resource_logs"]) -> None: ... + +global___LogsData = LogsData + +@typing_extensions.final +class ResourceLogs(google.protobuf.message.Message): + """A collection of ScopeLogs from a Resource.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_FIELD_NUMBER: builtins.int + SCOPE_LOGS_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: + """The resource for the logs in this message. + If this field is not set then resource info is unknown. + """ + @property + def scope_logs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeLogs]: + """A list of ScopeLogs that originate from a resource.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the resource data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "resource" field. It does not apply + to the data in the "scope_logs" field which have their own schema_url field. + """ + def __init__( + self, + *, + resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., + scope_logs: collections.abc.Iterable[global___ScopeLogs] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_logs", b"scope_logs"]) -> None: ... + +global___ResourceLogs = ResourceLogs + +@typing_extensions.final +class ScopeLogs(google.protobuf.message.Message): + """A collection of Logs produced by a Scope.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCOPE_FIELD_NUMBER: builtins.int + LOG_RECORDS_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: + """The instrumentation scope information for the logs in this message. + Semantically when InstrumentationScope isn't set, it is equivalent with + an empty instrumentation scope name (unknown). + """ + @property + def log_records(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LogRecord]: + """A list of log records.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the log data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "scope" field and all logs in the + "log_records" field. + """ + def __init__( + self, + *, + scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., + log_records: collections.abc.Iterable[global___LogRecord] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["log_records", b"log_records", "schema_url", b"schema_url", "scope", b"scope"]) -> None: ... + +global___ScopeLogs = ScopeLogs + +@typing_extensions.final +class LogRecord(google.protobuf.message.Message): + """A log record according to OpenTelemetry Log Data Model: + https://github.com/open-telemetry/oteps/blob/main/text/logs/0097-log-data-model.md + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + OBSERVED_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + SEVERITY_NUMBER_FIELD_NUMBER: builtins.int + SEVERITY_TEXT_FIELD_NUMBER: builtins.int + BODY_FIELD_NUMBER: builtins.int + ATTRIBUTES_FIELD_NUMBER: builtins.int + DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + TRACE_ID_FIELD_NUMBER: builtins.int + SPAN_ID_FIELD_NUMBER: builtins.int + EVENT_NAME_FIELD_NUMBER: builtins.int + time_unix_nano: builtins.int + """time_unix_nano is the time when the event occurred. + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + Value of 0 indicates unknown or missing timestamp. + """ + observed_time_unix_nano: builtins.int + """Time when the event was observed by the collection system. + For events that originate in OpenTelemetry (e.g. using OpenTelemetry Logging SDK) + this timestamp is typically set at the generation time and is equal to Timestamp. + For events originating externally and collected by OpenTelemetry (e.g. using + Collector) this is the time when OpenTelemetry's code observed the event measured + by the clock of the OpenTelemetry code. This field MUST be set once the event is + observed by OpenTelemetry. + + For converting OpenTelemetry log data to formats that support only one timestamp or + when receiving OpenTelemetry log data by recipients that support only one timestamp + internally the following logic is recommended: + - Use time_unix_nano if it is present, otherwise use observed_time_unix_nano. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + Value of 0 indicates unknown or missing timestamp. + """ + severity_number: global___SeverityNumber.ValueType + """Numerical value of the severity, normalized to values described in Log Data Model. + [Optional]. + """ + severity_text: builtins.str + """The severity text (also known as log level). The original string representation as + it is known at the source. [Optional]. + """ + @property + def body(self) -> opentelemetry.proto.common.v1.common_pb2.AnyValue: + """A value containing the body of the log record. Can be for example a human-readable + string message (including multi-line) describing the event in a free form or it can + be a structured data composed of arrays and maps of other values. [Optional]. + """ + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """Additional attributes that describe the specific event occurrence. [Optional]. + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + dropped_attributes_count: builtins.int + flags: builtins.int + """Flags, a bit field. 8 least significant bits are the trace flags as + defined in W3C Trace Context specification. 24 most significant bits are reserved + and must be set to 0. Readers must not assume that 24 most significant bits + will be zero and must correctly mask the bits when reading 8-bit trace flag (use + flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK). [Optional]. + """ + trace_id: builtins.bytes + """A unique identifier for a trace. All logs from the same trace share + the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR + of length other than 16 bytes is considered invalid (empty string in OTLP/JSON + is zero-length and thus is also invalid). + + This field is optional. + + The receivers SHOULD assume that the log record is not associated with a + trace if any of the following is true: + - the field is not present, + - the field contains an invalid value. + """ + span_id: builtins.bytes + """A unique identifier for a span within a trace, assigned when the span + is created. The ID is an 8-byte array. An ID with all zeroes OR of length + other than 8 bytes is considered invalid (empty string in OTLP/JSON + is zero-length and thus is also invalid). + + This field is optional. If the sender specifies a valid span_id then it SHOULD also + specify a valid trace_id. + + The receivers SHOULD assume that the log record is not associated with a + span if any of the following is true: + - the field is not present, + - the field contains an invalid value. + """ + event_name: builtins.str + """A unique identifier of event category/type. + All events with the same event_name are expected to conform to the same + schema for both their attributes and their body. + + Recommended to be fully qualified and short (no longer than 256 characters). + + Presence of event_name on the log record identifies this record + as an event. + + [Optional]. + """ + def __init__( + self, + *, + time_unix_nano: builtins.int = ..., + observed_time_unix_nano: builtins.int = ..., + severity_number: global___SeverityNumber.ValueType = ..., + severity_text: builtins.str = ..., + body: opentelemetry.proto.common.v1.common_pb2.AnyValue | None = ..., + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + dropped_attributes_count: builtins.int = ..., + flags: builtins.int = ..., + trace_id: builtins.bytes = ..., + span_id: builtins.bytes = ..., + event_name: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["body", b"body"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "body", b"body", "dropped_attributes_count", b"dropped_attributes_count", "event_name", b"event_name", "flags", b"flags", "observed_time_unix_nano", b"observed_time_unix_nano", "severity_number", b"severity_number", "severity_text", b"severity_text", "span_id", b"span_id", "time_unix_nano", b"time_unix_nano", "trace_id", b"trace_id"]) -> None: ... + +global___LogRecord = LogRecord diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py new file mode 100644 index 00000000000..2a279a61ed7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/metrics/v1/metrics.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,opentelemetry/proto/metrics/v1/metrics.proto\x12\x1eopentelemetry.proto.metrics.v1\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"X\n\x0bMetricsData\x12I\n\x10resource_metrics\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.ResourceMetrics\"\xaf\x01\n\x0fResourceMetrics\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12\x43\n\rscope_metrics\x18\x02 \x03(\x0b\x32,.opentelemetry.proto.metrics.v1.ScopeMetrics\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\x9f\x01\n\x0cScopeMetrics\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12\x37\n\x07metrics\x18\x02 \x03(\x0b\x32&.opentelemetry.proto.metrics.v1.Metric\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\xcd\x03\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0c\n\x04unit\x18\x03 \x01(\t\x12\x36\n\x05gauge\x18\x05 \x01(\x0b\x32%.opentelemetry.proto.metrics.v1.GaugeH\x00\x12\x32\n\x03sum\x18\x07 \x01(\x0b\x32#.opentelemetry.proto.metrics.v1.SumH\x00\x12>\n\thistogram\x18\t \x01(\x0b\x32).opentelemetry.proto.metrics.v1.HistogramH\x00\x12U\n\x15\x65xponential_histogram\x18\n \x01(\x0b\x32\x34.opentelemetry.proto.metrics.v1.ExponentialHistogramH\x00\x12:\n\x07summary\x18\x0b \x01(\x0b\x32\'.opentelemetry.proto.metrics.v1.SummaryH\x00\x12\x39\n\x08metadata\x18\x0c \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValueB\x06\n\x04\x64\x61taJ\x04\x08\x04\x10\x05J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\t\"M\n\x05Gauge\x12\x44\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.NumberDataPoint\"\xba\x01\n\x03Sum\x12\x44\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.NumberDataPoint\x12W\n\x17\x61ggregation_temporality\x18\x02 \x01(\x0e\x32\x36.opentelemetry.proto.metrics.v1.AggregationTemporality\x12\x14\n\x0cis_monotonic\x18\x03 \x01(\x08\"\xad\x01\n\tHistogram\x12G\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32\x32.opentelemetry.proto.metrics.v1.HistogramDataPoint\x12W\n\x17\x61ggregation_temporality\x18\x02 \x01(\x0e\x32\x36.opentelemetry.proto.metrics.v1.AggregationTemporality\"\xc3\x01\n\x14\x45xponentialHistogram\x12R\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32=.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint\x12W\n\x17\x61ggregation_temporality\x18\x02 \x01(\x0e\x32\x36.opentelemetry.proto.metrics.v1.AggregationTemporality\"P\n\x07Summary\x12\x45\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32\x30.opentelemetry.proto.metrics.v1.SummaryDataPoint\"\x86\x02\n\x0fNumberDataPoint\x12;\n\nattributes\x18\x07 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\x13\n\tas_double\x18\x04 \x01(\x01H\x00\x12\x10\n\x06\x61s_int\x18\x06 \x01(\x10H\x00\x12;\n\texemplars\x18\x05 \x03(\x0b\x32(.opentelemetry.proto.metrics.v1.Exemplar\x12\r\n\x05\x66lags\x18\x08 \x01(\rB\x07\n\x05valueJ\x04\x08\x01\x10\x02\"\xe6\x02\n\x12HistogramDataPoint\x12;\n\nattributes\x18\t \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\r\n\x05\x63ount\x18\x04 \x01(\x06\x12\x10\n\x03sum\x18\x05 \x01(\x01H\x00\x88\x01\x01\x12\x15\n\rbucket_counts\x18\x06 \x03(\x06\x12\x17\n\x0f\x65xplicit_bounds\x18\x07 \x03(\x01\x12;\n\texemplars\x18\x08 \x03(\x0b\x32(.opentelemetry.proto.metrics.v1.Exemplar\x12\r\n\x05\x66lags\x18\n \x01(\r\x12\x10\n\x03min\x18\x0b \x01(\x01H\x01\x88\x01\x01\x12\x10\n\x03max\x18\x0c \x01(\x01H\x02\x88\x01\x01\x42\x06\n\x04_sumB\x06\n\x04_minB\x06\n\x04_maxJ\x04\x08\x01\x10\x02\"\xda\x04\n\x1d\x45xponentialHistogramDataPoint\x12;\n\nattributes\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\r\n\x05\x63ount\x18\x04 \x01(\x06\x12\x10\n\x03sum\x18\x05 \x01(\x01H\x00\x88\x01\x01\x12\r\n\x05scale\x18\x06 \x01(\x11\x12\x12\n\nzero_count\x18\x07 \x01(\x06\x12W\n\x08positive\x18\x08 \x01(\x0b\x32\x45.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint.Buckets\x12W\n\x08negative\x18\t \x01(\x0b\x32\x45.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint.Buckets\x12\r\n\x05\x66lags\x18\n \x01(\r\x12;\n\texemplars\x18\x0b \x03(\x0b\x32(.opentelemetry.proto.metrics.v1.Exemplar\x12\x10\n\x03min\x18\x0c \x01(\x01H\x01\x88\x01\x01\x12\x10\n\x03max\x18\r \x01(\x01H\x02\x88\x01\x01\x12\x16\n\x0ezero_threshold\x18\x0e \x01(\x01\x1a\x30\n\x07\x42uckets\x12\x0e\n\x06offset\x18\x01 \x01(\x11\x12\x15\n\rbucket_counts\x18\x02 \x03(\x04\x42\x06\n\x04_sumB\x06\n\x04_minB\x06\n\x04_max\"\xc5\x02\n\x10SummaryDataPoint\x12;\n\nattributes\x18\x07 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\r\n\x05\x63ount\x18\x04 \x01(\x06\x12\x0b\n\x03sum\x18\x05 \x01(\x01\x12Y\n\x0fquantile_values\x18\x06 \x03(\x0b\x32@.opentelemetry.proto.metrics.v1.SummaryDataPoint.ValueAtQuantile\x12\r\n\x05\x66lags\x18\x08 \x01(\r\x1a\x32\n\x0fValueAtQuantile\x12\x10\n\x08quantile\x18\x01 \x01(\x01\x12\r\n\x05value\x18\x02 \x01(\x01J\x04\x08\x01\x10\x02\"\xc1\x01\n\x08\x45xemplar\x12\x44\n\x13\x66iltered_attributes\x18\x07 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x16\n\x0etime_unix_nano\x18\x02 \x01(\x06\x12\x13\n\tas_double\x18\x03 \x01(\x01H\x00\x12\x10\n\x06\x61s_int\x18\x06 \x01(\x10H\x00\x12\x0f\n\x07span_id\x18\x04 \x01(\x0c\x12\x10\n\x08trace_id\x18\x05 \x01(\x0c\x42\x07\n\x05valueJ\x04\x08\x01\x10\x02*\x8c\x01\n\x16\x41ggregationTemporality\x12\'\n#AGGREGATION_TEMPORALITY_UNSPECIFIED\x10\x00\x12!\n\x1d\x41GGREGATION_TEMPORALITY_DELTA\x10\x01\x12&\n\"AGGREGATION_TEMPORALITY_CUMULATIVE\x10\x02*^\n\x0e\x44\x61taPointFlags\x12\x1f\n\x1b\x44\x41TA_POINT_FLAGS_DO_NOT_USE\x10\x00\x12+\n\'DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK\x10\x01\x42\x7f\n!io.opentelemetry.proto.metrics.v1B\x0cMetricsProtoP\x01Z)go.opentelemetry.io/proto/otlp/metrics/v1\xaa\x02\x1eOpenTelemetry.Proto.Metrics.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1.metrics_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n!io.opentelemetry.proto.metrics.v1B\014MetricsProtoP\001Z)go.opentelemetry.io/proto/otlp/metrics/v1\252\002\036OpenTelemetry.Proto.Metrics.V1' + _globals['_AGGREGATIONTEMPORALITY']._serialized_start=3546 + _globals['_AGGREGATIONTEMPORALITY']._serialized_end=3686 + _globals['_DATAPOINTFLAGS']._serialized_start=3688 + _globals['_DATAPOINTFLAGS']._serialized_end=3782 + _globals['_METRICSDATA']._serialized_start=172 + _globals['_METRICSDATA']._serialized_end=260 + _globals['_RESOURCEMETRICS']._serialized_start=263 + _globals['_RESOURCEMETRICS']._serialized_end=438 + _globals['_SCOPEMETRICS']._serialized_start=441 + _globals['_SCOPEMETRICS']._serialized_end=600 + _globals['_METRIC']._serialized_start=603 + _globals['_METRIC']._serialized_end=1064 + _globals['_GAUGE']._serialized_start=1066 + _globals['_GAUGE']._serialized_end=1143 + _globals['_SUM']._serialized_start=1146 + _globals['_SUM']._serialized_end=1332 + _globals['_HISTOGRAM']._serialized_start=1335 + _globals['_HISTOGRAM']._serialized_end=1508 + _globals['_EXPONENTIALHISTOGRAM']._serialized_start=1511 + _globals['_EXPONENTIALHISTOGRAM']._serialized_end=1706 + _globals['_SUMMARY']._serialized_start=1708 + _globals['_SUMMARY']._serialized_end=1788 + _globals['_NUMBERDATAPOINT']._serialized_start=1791 + _globals['_NUMBERDATAPOINT']._serialized_end=2053 + _globals['_HISTOGRAMDATAPOINT']._serialized_start=2056 + _globals['_HISTOGRAMDATAPOINT']._serialized_end=2414 + _globals['_EXPONENTIALHISTOGRAMDATAPOINT']._serialized_start=2417 + _globals['_EXPONENTIALHISTOGRAMDATAPOINT']._serialized_end=3019 + _globals['_EXPONENTIALHISTOGRAMDATAPOINT_BUCKETS']._serialized_start=2947 + _globals['_EXPONENTIALHISTOGRAMDATAPOINT_BUCKETS']._serialized_end=2995 + _globals['_SUMMARYDATAPOINT']._serialized_start=3022 + _globals['_SUMMARYDATAPOINT']._serialized_end=3347 + _globals['_SUMMARYDATAPOINT_VALUEATQUANTILE']._serialized_start=3291 + _globals['_SUMMARYDATAPOINT_VALUEATQUANTILE']._serialized_end=3341 + _globals['_EXEMPLAR']._serialized_start=3350 + _globals['_EXEMPLAR']._serialized_end=3543 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi new file mode 100644 index 00000000000..0f374be93ee --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi @@ -0,0 +1,1177 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2019, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import opentelemetry.proto.common.v1.common_pb2 +import opentelemetry.proto.resource.v1.resource_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _AggregationTemporality: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _AggregationTemporalityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AggregationTemporality.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + AGGREGATION_TEMPORALITY_UNSPECIFIED: _AggregationTemporality.ValueType # 0 + """UNSPECIFIED is the default AggregationTemporality, it MUST not be used.""" + AGGREGATION_TEMPORALITY_DELTA: _AggregationTemporality.ValueType # 1 + """DELTA is an AggregationTemporality for a metric aggregator which reports + changes since last report time. Successive metrics contain aggregation of + values from continuous and non-overlapping intervals. + + The values for a DELTA metric are based only on the time interval + associated with one measurement cycle. There is no dependency on + previous measurements like is the case for CUMULATIVE metrics. + + For example, consider a system measuring the number of requests that + it receives and reports the sum of these requests every second as a + DELTA metric: + + 1. The system starts receiving at time=t_0. + 2. A request is received, the system measures 1 request. + 3. A request is received, the system measures 1 request. + 4. A request is received, the system measures 1 request. + 5. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+1 with a value of 3. + 6. A request is received, the system measures 1 request. + 7. A request is received, the system measures 1 request. + 8. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0+1 to + t_0+2 with a value of 2. + """ + AGGREGATION_TEMPORALITY_CUMULATIVE: _AggregationTemporality.ValueType # 2 + """CUMULATIVE is an AggregationTemporality for a metric aggregator which + reports changes since a fixed start time. This means that current values + of a CUMULATIVE metric depend on all previous measurements since the + start time. Because of this, the sender is required to retain this state + in some form. If this state is lost or invalidated, the CUMULATIVE metric + values MUST be reset and a new fixed start time following the last + reported measurement time sent MUST be used. + + For example, consider a system measuring the number of requests that + it receives and reports the sum of these requests every second as a + CUMULATIVE metric: + + 1. The system starts receiving at time=t_0. + 2. A request is received, the system measures 1 request. + 3. A request is received, the system measures 1 request. + 4. A request is received, the system measures 1 request. + 5. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+1 with a value of 3. + 6. A request is received, the system measures 1 request. + 7. A request is received, the system measures 1 request. + 8. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+2 with a value of 5. + 9. The system experiences a fault and loses state. + 10. The system recovers and resumes receiving at time=t_1. + 11. A request is received, the system measures 1 request. + 12. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_1 to + t_0+1 with a value of 1. + + Note: Even though, when reporting changes since last report time, using + CUMULATIVE is valid, it is not recommended. This may cause problems for + systems that do not use start_time to determine when the aggregation + value was reset (e.g. Prometheus). + """ + +class AggregationTemporality(_AggregationTemporality, metaclass=_AggregationTemporalityEnumTypeWrapper): + """AggregationTemporality defines how a metric aggregator reports aggregated + values. It describes how those values relate to the time interval over + which they are aggregated. + """ + +AGGREGATION_TEMPORALITY_UNSPECIFIED: AggregationTemporality.ValueType # 0 +"""UNSPECIFIED is the default AggregationTemporality, it MUST not be used.""" +AGGREGATION_TEMPORALITY_DELTA: AggregationTemporality.ValueType # 1 +"""DELTA is an AggregationTemporality for a metric aggregator which reports +changes since last report time. Successive metrics contain aggregation of +values from continuous and non-overlapping intervals. + +The values for a DELTA metric are based only on the time interval +associated with one measurement cycle. There is no dependency on +previous measurements like is the case for CUMULATIVE metrics. + +For example, consider a system measuring the number of requests that +it receives and reports the sum of these requests every second as a +DELTA metric: + + 1. The system starts receiving at time=t_0. + 2. A request is received, the system measures 1 request. + 3. A request is received, the system measures 1 request. + 4. A request is received, the system measures 1 request. + 5. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+1 with a value of 3. + 6. A request is received, the system measures 1 request. + 7. A request is received, the system measures 1 request. + 8. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0+1 to + t_0+2 with a value of 2. +""" +AGGREGATION_TEMPORALITY_CUMULATIVE: AggregationTemporality.ValueType # 2 +"""CUMULATIVE is an AggregationTemporality for a metric aggregator which +reports changes since a fixed start time. This means that current values +of a CUMULATIVE metric depend on all previous measurements since the +start time. Because of this, the sender is required to retain this state +in some form. If this state is lost or invalidated, the CUMULATIVE metric +values MUST be reset and a new fixed start time following the last +reported measurement time sent MUST be used. + +For example, consider a system measuring the number of requests that +it receives and reports the sum of these requests every second as a +CUMULATIVE metric: + + 1. The system starts receiving at time=t_0. + 2. A request is received, the system measures 1 request. + 3. A request is received, the system measures 1 request. + 4. A request is received, the system measures 1 request. + 5. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+1 with a value of 3. + 6. A request is received, the system measures 1 request. + 7. A request is received, the system measures 1 request. + 8. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_0 to + t_0+2 with a value of 5. + 9. The system experiences a fault and loses state. + 10. The system recovers and resumes receiving at time=t_1. + 11. A request is received, the system measures 1 request. + 12. The 1 second collection cycle ends. A metric is exported for the + number of requests received over the interval of time t_1 to + t_0+1 with a value of 1. + +Note: Even though, when reporting changes since last report time, using +CUMULATIVE is valid, it is not recommended. This may cause problems for +systems that do not use start_time to determine when the aggregation +value was reset (e.g. Prometheus). +""" +global___AggregationTemporality = AggregationTemporality + +class _DataPointFlags: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _DataPointFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_DataPointFlags.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + DATA_POINT_FLAGS_DO_NOT_USE: _DataPointFlags.ValueType # 0 + """The zero value for the enum. Should not be used for comparisons. + Instead use bitwise "and" with the appropriate mask as shown above. + """ + DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK: _DataPointFlags.ValueType # 1 + """This DataPoint is valid but has no recorded value. This value + SHOULD be used to reflect explicitly missing data in a series, as + for an equivalent to the Prometheus "staleness marker". + """ + +class DataPointFlags(_DataPointFlags, metaclass=_DataPointFlagsEnumTypeWrapper): + """DataPointFlags is defined as a protobuf 'uint32' type and is to be used as a + bit-field representing 32 distinct boolean flags. Each flag defined in this + enum is a bit-mask. To test the presence of a single flag in the flags of + a data point, for example, use an expression like: + + (point.flags & DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK) == DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK + """ + +DATA_POINT_FLAGS_DO_NOT_USE: DataPointFlags.ValueType # 0 +"""The zero value for the enum. Should not be used for comparisons. +Instead use bitwise "and" with the appropriate mask as shown above. +""" +DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK: DataPointFlags.ValueType # 1 +"""This DataPoint is valid but has no recorded value. This value +SHOULD be used to reflect explicitly missing data in a series, as +for an equivalent to the Prometheus "staleness marker". +""" +global___DataPointFlags = DataPointFlags + +@typing_extensions.final +class MetricsData(google.protobuf.message.Message): + """MetricsData represents the metrics data that can be stored in a persistent + storage, OR can be embedded by other protocols that transfer OTLP metrics + data but do not implement the OTLP protocol. + + MetricsData + └─── ResourceMetrics + ├── Resource + ├── SchemaURL + └── ScopeMetrics + ├── Scope + ├── SchemaURL + └── Metric + ├── Name + ├── Description + ├── Unit + └── data + ├── Gauge + ├── Sum + ├── Histogram + ├── ExponentialHistogram + └── Summary + + The main difference between this message and collector protocol is that + in this message there will not be any "control" or "metadata" specific to + OTLP protocol. + + When new fields are added into this message, the OTLP request MUST be updated + as well. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_METRICS_FIELD_NUMBER: builtins.int + @property + def resource_metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceMetrics]: + """An array of ResourceMetrics. + For data coming from a single resource this array will typically contain + one element. Intermediary nodes that receive data from multiple origins + typically batch the data before forwarding further and in that case this + array will contain multiple elements. + """ + def __init__( + self, + *, + resource_metrics: collections.abc.Iterable[global___ResourceMetrics] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["resource_metrics", b"resource_metrics"]) -> None: ... + +global___MetricsData = MetricsData + +@typing_extensions.final +class ResourceMetrics(google.protobuf.message.Message): + """A collection of ScopeMetrics from a Resource.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_FIELD_NUMBER: builtins.int + SCOPE_METRICS_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: + """The resource for the metrics in this message. + If this field is not set then no resource info is known. + """ + @property + def scope_metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeMetrics]: + """A list of metrics that originate from a resource.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the resource data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "resource" field. It does not apply + to the data in the "scope_metrics" field which have their own schema_url field. + """ + def __init__( + self, + *, + resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., + scope_metrics: collections.abc.Iterable[global___ScopeMetrics] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_metrics", b"scope_metrics"]) -> None: ... + +global___ResourceMetrics = ResourceMetrics + +@typing_extensions.final +class ScopeMetrics(google.protobuf.message.Message): + """A collection of Metrics produced by an Scope.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCOPE_FIELD_NUMBER: builtins.int + METRICS_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: + """The instrumentation scope information for the metrics in this message. + Semantically when InstrumentationScope isn't set, it is equivalent with + an empty instrumentation scope name (unknown). + """ + @property + def metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Metric]: + """A list of metrics that originate from an instrumentation library.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the metric data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "scope" field and all metrics in the + "metrics" field. + """ + def __init__( + self, + *, + scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., + metrics: collections.abc.Iterable[global___Metric] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["metrics", b"metrics", "schema_url", b"schema_url", "scope", b"scope"]) -> None: ... + +global___ScopeMetrics = ScopeMetrics + +@typing_extensions.final +class Metric(google.protobuf.message.Message): + """Defines a Metric which has one or more timeseries. The following is a + brief summary of the Metric data model. For more details, see: + + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md + + The data model and relation between entities is shown in the + diagram below. Here, "DataPoint" is the term used to refer to any + one of the specific data point value types, and "points" is the term used + to refer to any one of the lists of points contained in the Metric. + + - Metric is composed of a metadata and data. + - Metadata part contains a name, description, unit. + - Data is one of the possible types (Sum, Gauge, Histogram, Summary). + - DataPoint contains timestamps, attributes, and one of the possible value type + fields. + + Metric + +------------+ + |name | + |description | + |unit | +------------------------------------+ + |data |---> |Gauge, Sum, Histogram, Summary, ... | + +------------+ +------------------------------------+ + + Data [One of Gauge, Sum, Histogram, Summary, ...] + +-----------+ + |... | // Metadata about the Data. + |points |--+ + +-----------+ | + | +---------------------------+ + | |DataPoint 1 | + v |+------+------+ +------+ | + +-----+ ||label |label |...|label | | + | 1 |-->||value1|value2|...|valueN| | + +-----+ |+------+------+ +------+ | + | . | |+-----+ | + | . | ||value| | + | . | |+-----+ | + | . | +---------------------------+ + | . | . + | . | . + | . | . + | . | +---------------------------+ + | . | |DataPoint M | + +-----+ |+------+------+ +------+ | + | M |-->||label |label |...|label | | + +-----+ ||value1|value2|...|valueN| | + |+------+------+ +------+ | + |+-----+ | + ||value| | + |+-----+ | + +---------------------------+ + + Each distinct type of DataPoint represents the output of a specific + aggregation function, the result of applying the DataPoint's + associated function of to one or more measurements. + + All DataPoint types have three common fields: + - Attributes includes key-value pairs associated with the data point + - TimeUnixNano is required, set to the end time of the aggregation + - StartTimeUnixNano is optional, but strongly encouraged for DataPoints + having an AggregationTemporality field, as discussed below. + + Both TimeUnixNano and StartTimeUnixNano values are expressed as + UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + + # TimeUnixNano + + This field is required, having consistent interpretation across + DataPoint types. TimeUnixNano is the moment corresponding to when + the data point's aggregate value was captured. + + Data points with the 0 value for TimeUnixNano SHOULD be rejected + by consumers. + + # StartTimeUnixNano + + StartTimeUnixNano in general allows detecting when a sequence of + observations is unbroken. This field indicates to consumers the + start time for points with cumulative and delta + AggregationTemporality, and it should be included whenever possible + to support correct rate calculation. Although it may be omitted + when the start time is truly unknown, setting StartTimeUnixNano is + strongly encouraged. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_FIELD_NUMBER: builtins.int + DESCRIPTION_FIELD_NUMBER: builtins.int + UNIT_FIELD_NUMBER: builtins.int + GAUGE_FIELD_NUMBER: builtins.int + SUM_FIELD_NUMBER: builtins.int + HISTOGRAM_FIELD_NUMBER: builtins.int + EXPONENTIAL_HISTOGRAM_FIELD_NUMBER: builtins.int + SUMMARY_FIELD_NUMBER: builtins.int + METADATA_FIELD_NUMBER: builtins.int + name: builtins.str + """The name of the metric.""" + description: builtins.str + """A description of the metric, which can be used in documentation.""" + unit: builtins.str + """The unit in which the metric value is reported. Follows the format + described by https://unitsofmeasure.org/ucum.html. + """ + @property + def gauge(self) -> global___Gauge: ... + @property + def sum(self) -> global___Sum: ... + @property + def histogram(self) -> global___Histogram: ... + @property + def exponential_histogram(self) -> global___ExponentialHistogram: ... + @property + def summary(self) -> global___Summary: ... + @property + def metadata(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """Additional metadata attributes that describe the metric. [Optional]. + Attributes are non-identifying. + Consumers SHOULD NOT need to be aware of these attributes. + These attributes MAY be used to encode information allowing + for lossless roundtrip translation to / from another data model. + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + def __init__( + self, + *, + name: builtins.str = ..., + description: builtins.str = ..., + unit: builtins.str = ..., + gauge: global___Gauge | None = ..., + sum: global___Sum | None = ..., + histogram: global___Histogram | None = ..., + exponential_histogram: global___ExponentialHistogram | None = ..., + summary: global___Summary | None = ..., + metadata: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["data", b"data", "exponential_histogram", b"exponential_histogram", "gauge", b"gauge", "histogram", b"histogram", "sum", b"sum", "summary", b"summary"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["data", b"data", "description", b"description", "exponential_histogram", b"exponential_histogram", "gauge", b"gauge", "histogram", b"histogram", "metadata", b"metadata", "name", b"name", "sum", b"sum", "summary", b"summary", "unit", b"unit"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["data", b"data"]) -> typing_extensions.Literal["gauge", "sum", "histogram", "exponential_histogram", "summary"] | None: ... + +global___Metric = Metric + +@typing_extensions.final +class Gauge(google.protobuf.message.Message): + """Gauge represents the type of a scalar metric that always exports the + "current value" for every data point. It should be used for an "unknown" + aggregation. + + A Gauge does not support different aggregation temporalities. Given the + aggregation is unknown, points cannot be combined using the same + aggregation, regardless of aggregation temporalities. Therefore, + AggregationTemporality is not included. Consequently, this also means + "StartTimeUnixNano" is ignored for all data points. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATA_POINTS_FIELD_NUMBER: builtins.int + @property + def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NumberDataPoint]: + """The time series data points. + Note: Multiple time series may be included (same timestamp, different attributes). + """ + def __init__( + self, + *, + data_points: collections.abc.Iterable[global___NumberDataPoint] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["data_points", b"data_points"]) -> None: ... + +global___Gauge = Gauge + +@typing_extensions.final +class Sum(google.protobuf.message.Message): + """Sum represents the type of a scalar metric that is calculated as a sum of all + reported measurements over a time interval. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATA_POINTS_FIELD_NUMBER: builtins.int + AGGREGATION_TEMPORALITY_FIELD_NUMBER: builtins.int + IS_MONOTONIC_FIELD_NUMBER: builtins.int + @property + def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NumberDataPoint]: + """The time series data points. + Note: Multiple time series may be included (same timestamp, different attributes). + """ + aggregation_temporality: global___AggregationTemporality.ValueType + """aggregation_temporality describes if the aggregator reports delta changes + since last report time, or cumulative changes since a fixed start time. + """ + is_monotonic: builtins.bool + """Represents whether the sum is monotonic.""" + def __init__( + self, + *, + data_points: collections.abc.Iterable[global___NumberDataPoint] | None = ..., + aggregation_temporality: global___AggregationTemporality.ValueType = ..., + is_monotonic: builtins.bool = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["aggregation_temporality", b"aggregation_temporality", "data_points", b"data_points", "is_monotonic", b"is_monotonic"]) -> None: ... + +global___Sum = Sum + +@typing_extensions.final +class Histogram(google.protobuf.message.Message): + """Histogram represents the type of a metric that is calculated by aggregating + as a Histogram of all reported measurements over a time interval. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATA_POINTS_FIELD_NUMBER: builtins.int + AGGREGATION_TEMPORALITY_FIELD_NUMBER: builtins.int + @property + def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___HistogramDataPoint]: + """The time series data points. + Note: Multiple time series may be included (same timestamp, different attributes). + """ + aggregation_temporality: global___AggregationTemporality.ValueType + """aggregation_temporality describes if the aggregator reports delta changes + since last report time, or cumulative changes since a fixed start time. + """ + def __init__( + self, + *, + data_points: collections.abc.Iterable[global___HistogramDataPoint] | None = ..., + aggregation_temporality: global___AggregationTemporality.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["aggregation_temporality", b"aggregation_temporality", "data_points", b"data_points"]) -> None: ... + +global___Histogram = Histogram + +@typing_extensions.final +class ExponentialHistogram(google.protobuf.message.Message): + """ExponentialHistogram represents the type of a metric that is calculated by aggregating + as a ExponentialHistogram of all reported double measurements over a time interval. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATA_POINTS_FIELD_NUMBER: builtins.int + AGGREGATION_TEMPORALITY_FIELD_NUMBER: builtins.int + @property + def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ExponentialHistogramDataPoint]: + """The time series data points. + Note: Multiple time series may be included (same timestamp, different attributes). + """ + aggregation_temporality: global___AggregationTemporality.ValueType + """aggregation_temporality describes if the aggregator reports delta changes + since last report time, or cumulative changes since a fixed start time. + """ + def __init__( + self, + *, + data_points: collections.abc.Iterable[global___ExponentialHistogramDataPoint] | None = ..., + aggregation_temporality: global___AggregationTemporality.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["aggregation_temporality", b"aggregation_temporality", "data_points", b"data_points"]) -> None: ... + +global___ExponentialHistogram = ExponentialHistogram + +@typing_extensions.final +class Summary(google.protobuf.message.Message): + """Summary metric data are used to convey quantile summaries, + a Prometheus (see: https://prometheus.io/docs/concepts/metric_types/#summary) + and OpenMetrics (see: https://github.com/prometheus/OpenMetrics/blob/4dbf6075567ab43296eed941037c12951faafb92/protos/prometheus.proto#L45) + data type. These data points cannot always be merged in a meaningful way. + While they can be useful in some applications, histogram data points are + recommended for new applications. + Summary metrics do not have an aggregation temporality field. This is + because the count and sum fields of a SummaryDataPoint are assumed to be + cumulative values. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + DATA_POINTS_FIELD_NUMBER: builtins.int + @property + def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SummaryDataPoint]: + """The time series data points. + Note: Multiple time series may be included (same timestamp, different attributes). + """ + def __init__( + self, + *, + data_points: collections.abc.Iterable[global___SummaryDataPoint] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["data_points", b"data_points"]) -> None: ... + +global___Summary = Summary + +@typing_extensions.final +class NumberDataPoint(google.protobuf.message.Message): + """NumberDataPoint is a single data point in a timeseries that describes the + time-varying scalar value of a metric. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ATTRIBUTES_FIELD_NUMBER: builtins.int + START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + AS_DOUBLE_FIELD_NUMBER: builtins.int + AS_INT_FIELD_NUMBER: builtins.int + EXEMPLARS_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """The set of key/value pairs that uniquely identify the timeseries from + where this point belongs. The list may be empty (may contain 0 elements). + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + start_time_unix_nano: builtins.int + """StartTimeUnixNano is optional but strongly encouraged, see the + the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + time_unix_nano: builtins.int + """TimeUnixNano is required, see the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + as_double: builtins.float + as_int: builtins.int + @property + def exemplars(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Exemplar]: + """(Optional) List of exemplars collected from + measurements that were used to form the data point + """ + flags: builtins.int + """Flags that apply to this specific data point. See DataPointFlags + for the available flags and their meaning. + """ + def __init__( + self, + *, + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + start_time_unix_nano: builtins.int = ..., + time_unix_nano: builtins.int = ..., + as_double: builtins.float = ..., + as_int: builtins.int = ..., + exemplars: collections.abc.Iterable[global___Exemplar] | None = ..., + flags: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "attributes", b"attributes", "exemplars", b"exemplars", "flags", b"flags", "start_time_unix_nano", b"start_time_unix_nano", "time_unix_nano", b"time_unix_nano", "value", b"value"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["as_double", "as_int"] | None: ... + +global___NumberDataPoint = NumberDataPoint + +@typing_extensions.final +class HistogramDataPoint(google.protobuf.message.Message): + """HistogramDataPoint is a single data point in a timeseries that describes the + time-varying values of a Histogram. A Histogram contains summary statistics + for a population of values, it may optionally contain the distribution of + those values across a set of buckets. + + If the histogram contains the distribution of values, then both + "explicit_bounds" and "bucket counts" fields must be defined. + If the histogram does not contain the distribution of values, then both + "explicit_bounds" and "bucket_counts" must be omitted and only "count" and + "sum" are known. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ATTRIBUTES_FIELD_NUMBER: builtins.int + START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + COUNT_FIELD_NUMBER: builtins.int + SUM_FIELD_NUMBER: builtins.int + BUCKET_COUNTS_FIELD_NUMBER: builtins.int + EXPLICIT_BOUNDS_FIELD_NUMBER: builtins.int + EXEMPLARS_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + MIN_FIELD_NUMBER: builtins.int + MAX_FIELD_NUMBER: builtins.int + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """The set of key/value pairs that uniquely identify the timeseries from + where this point belongs. The list may be empty (may contain 0 elements). + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + start_time_unix_nano: builtins.int + """StartTimeUnixNano is optional but strongly encouraged, see the + the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + time_unix_nano: builtins.int + """TimeUnixNano is required, see the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + count: builtins.int + """count is the number of values in the population. Must be non-negative. This + value must be equal to the sum of the "count" fields in buckets if a + histogram is provided. + """ + sum: builtins.float + """sum of the values in the population. If count is zero then this field + must be zero. + + Note: Sum should only be filled out when measuring non-negative discrete + events, and is assumed to be monotonic over the values of these events. + Negative events *can* be recorded, but sum should not be filled out when + doing so. This is specifically to enforce compatibility w/ OpenMetrics, + see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram + """ + @property + def bucket_counts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """bucket_counts is an optional field contains the count values of histogram + for each bucket. + + The sum of the bucket_counts must equal the value in the count field. + + The number of elements in bucket_counts array must be by one greater than + the number of elements in explicit_bounds array. The exception to this rule + is when the length of bucket_counts is 0, then the length of explicit_bounds + must also be 0. + """ + @property + def explicit_bounds(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: + """explicit_bounds specifies buckets with explicitly defined bounds for values. + + The boundaries for bucket at index i are: + + (-infinity, explicit_bounds[i]] for i == 0 + (explicit_bounds[i-1], explicit_bounds[i]] for 0 < i < size(explicit_bounds) + (explicit_bounds[i-1], +infinity) for i == size(explicit_bounds) + + The values in the explicit_bounds array must be strictly increasing. + + Histogram buckets are inclusive of their upper boundary, except the last + bucket where the boundary is at infinity. This format is intentionally + compatible with the OpenMetrics histogram definition. + + If bucket_counts length is 0 then explicit_bounds length must also be 0, + otherwise the data point is invalid. + """ + @property + def exemplars(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Exemplar]: + """(Optional) List of exemplars collected from + measurements that were used to form the data point + """ + flags: builtins.int + """Flags that apply to this specific data point. See DataPointFlags + for the available flags and their meaning. + """ + min: builtins.float + """min is the minimum value over (start_time, end_time].""" + max: builtins.float + """max is the maximum value over (start_time, end_time].""" + def __init__( + self, + *, + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + start_time_unix_nano: builtins.int = ..., + time_unix_nano: builtins.int = ..., + count: builtins.int = ..., + sum: builtins.float | None = ..., + bucket_counts: collections.abc.Iterable[builtins.int] | None = ..., + explicit_bounds: collections.abc.Iterable[builtins.float] | None = ..., + exemplars: collections.abc.Iterable[global___Exemplar] | None = ..., + flags: builtins.int = ..., + min: builtins.float | None = ..., + max: builtins.float | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "max", b"max", "min", b"min", "sum", b"sum"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "attributes", b"attributes", "bucket_counts", b"bucket_counts", "count", b"count", "exemplars", b"exemplars", "explicit_bounds", b"explicit_bounds", "flags", b"flags", "max", b"max", "min", b"min", "start_time_unix_nano", b"start_time_unix_nano", "sum", b"sum", "time_unix_nano", b"time_unix_nano"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_max", b"_max"]) -> typing_extensions.Literal["max"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_min", b"_min"]) -> typing_extensions.Literal["min"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_sum", b"_sum"]) -> typing_extensions.Literal["sum"] | None: ... + +global___HistogramDataPoint = HistogramDataPoint + +@typing_extensions.final +class ExponentialHistogramDataPoint(google.protobuf.message.Message): + """ExponentialHistogramDataPoint is a single data point in a timeseries that describes the + time-varying values of a ExponentialHistogram of double values. A ExponentialHistogram contains + summary statistics for a population of values, it may optionally contain the + distribution of those values across a set of buckets. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class Buckets(google.protobuf.message.Message): + """Buckets are a set of bucket counts, encoded in a contiguous array + of counts. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + OFFSET_FIELD_NUMBER: builtins.int + BUCKET_COUNTS_FIELD_NUMBER: builtins.int + offset: builtins.int + """The bucket index of the first entry in the bucket_counts array. + + Note: This uses a varint encoding as a simple form of compression. + """ + @property + def bucket_counts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """An array of count values, where bucket_counts[i] carries + the count of the bucket at index (offset+i). bucket_counts[i] is the count + of values greater than base^(offset+i) and less than or equal to + base^(offset+i+1). + + Note: By contrast, the explicit HistogramDataPoint uses + fixed64. This field is expected to have many buckets, + especially zeros, so uint64 has been selected to ensure + varint encoding. + """ + def __init__( + self, + *, + offset: builtins.int = ..., + bucket_counts: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["bucket_counts", b"bucket_counts", "offset", b"offset"]) -> None: ... + + ATTRIBUTES_FIELD_NUMBER: builtins.int + START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + COUNT_FIELD_NUMBER: builtins.int + SUM_FIELD_NUMBER: builtins.int + SCALE_FIELD_NUMBER: builtins.int + ZERO_COUNT_FIELD_NUMBER: builtins.int + POSITIVE_FIELD_NUMBER: builtins.int + NEGATIVE_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + EXEMPLARS_FIELD_NUMBER: builtins.int + MIN_FIELD_NUMBER: builtins.int + MAX_FIELD_NUMBER: builtins.int + ZERO_THRESHOLD_FIELD_NUMBER: builtins.int + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """The set of key/value pairs that uniquely identify the timeseries from + where this point belongs. The list may be empty (may contain 0 elements). + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + start_time_unix_nano: builtins.int + """StartTimeUnixNano is optional but strongly encouraged, see the + the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + time_unix_nano: builtins.int + """TimeUnixNano is required, see the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + count: builtins.int + """The number of values in the population. Must be + non-negative. This value must be equal to the sum of the "bucket_counts" + values in the positive and negative Buckets plus the "zero_count" field. + """ + sum: builtins.float + """The sum of the values in the population. If count is zero then this field + must be zero. + + Note: Sum should only be filled out when measuring non-negative discrete + events, and is assumed to be monotonic over the values of these events. + Negative events *can* be recorded, but sum should not be filled out when + doing so. This is specifically to enforce compatibility w/ OpenMetrics, + see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram + """ + scale: builtins.int + """scale describes the resolution of the histogram. Boundaries are + located at powers of the base, where: + + base = (2^(2^-scale)) + + The histogram bucket identified by `index`, a signed integer, + contains values that are greater than (base^index) and + less than or equal to (base^(index+1)). + + The positive and negative ranges of the histogram are expressed + separately. Negative values are mapped by their absolute value + into the negative range using the same scale as the positive range. + + scale is not restricted by the protocol, as the permissible + values depend on the range of the data. + """ + zero_count: builtins.int + """The count of values that are either exactly zero or + within the region considered zero by the instrumentation at the + tolerated degree of precision. This bucket stores values that + cannot be expressed using the standard exponential formula as + well as values that have been rounded to zero. + + Implementations MAY consider the zero bucket to have probability + mass equal to (zero_count / count). + """ + @property + def positive(self) -> global___ExponentialHistogramDataPoint.Buckets: + """positive carries the positive range of exponential bucket counts.""" + @property + def negative(self) -> global___ExponentialHistogramDataPoint.Buckets: + """negative carries the negative range of exponential bucket counts.""" + flags: builtins.int + """Flags that apply to this specific data point. See DataPointFlags + for the available flags and their meaning. + """ + @property + def exemplars(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Exemplar]: + """(Optional) List of exemplars collected from + measurements that were used to form the data point + """ + min: builtins.float + """The minimum value over (start_time, end_time].""" + max: builtins.float + """The maximum value over (start_time, end_time].""" + zero_threshold: builtins.float + """ZeroThreshold may be optionally set to convey the width of the zero + region. Where the zero region is defined as the closed interval + [-ZeroThreshold, ZeroThreshold]. + When ZeroThreshold is 0, zero count bucket stores values that cannot be + expressed using the standard exponential formula as well as values that + have been rounded to zero. + """ + def __init__( + self, + *, + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + start_time_unix_nano: builtins.int = ..., + time_unix_nano: builtins.int = ..., + count: builtins.int = ..., + sum: builtins.float | None = ..., + scale: builtins.int = ..., + zero_count: builtins.int = ..., + positive: global___ExponentialHistogramDataPoint.Buckets | None = ..., + negative: global___ExponentialHistogramDataPoint.Buckets | None = ..., + flags: builtins.int = ..., + exemplars: collections.abc.Iterable[global___Exemplar] | None = ..., + min: builtins.float | None = ..., + max: builtins.float | None = ..., + zero_threshold: builtins.float = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "max", b"max", "min", b"min", "negative", b"negative", "positive", b"positive", "sum", b"sum"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "attributes", b"attributes", "count", b"count", "exemplars", b"exemplars", "flags", b"flags", "max", b"max", "min", b"min", "negative", b"negative", "positive", b"positive", "scale", b"scale", "start_time_unix_nano", b"start_time_unix_nano", "sum", b"sum", "time_unix_nano", b"time_unix_nano", "zero_count", b"zero_count", "zero_threshold", b"zero_threshold"]) -> None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_max", b"_max"]) -> typing_extensions.Literal["max"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_min", b"_min"]) -> typing_extensions.Literal["min"] | None: ... + @typing.overload + def WhichOneof(self, oneof_group: typing_extensions.Literal["_sum", b"_sum"]) -> typing_extensions.Literal["sum"] | None: ... + +global___ExponentialHistogramDataPoint = ExponentialHistogramDataPoint + +@typing_extensions.final +class SummaryDataPoint(google.protobuf.message.Message): + """SummaryDataPoint is a single data point in a timeseries that describes the + time-varying values of a Summary metric. The count and sum fields represent + cumulative values. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + @typing_extensions.final + class ValueAtQuantile(google.protobuf.message.Message): + """Represents the value at a given quantile of a distribution. + + To record Min and Max values following conventions are used: + - The 1.0 quantile is equivalent to the maximum value observed. + - The 0.0 quantile is equivalent to the minimum value observed. + + See the following issue for more context: + https://github.com/open-telemetry/opentelemetry-proto/issues/125 + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + QUANTILE_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + quantile: builtins.float + """The quantile of a distribution. Must be in the interval + [0.0, 1.0]. + """ + value: builtins.float + """The value at the given quantile of a distribution. + + Quantile values must NOT be negative. + """ + def __init__( + self, + *, + quantile: builtins.float = ..., + value: builtins.float = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["quantile", b"quantile", "value", b"value"]) -> None: ... + + ATTRIBUTES_FIELD_NUMBER: builtins.int + START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + COUNT_FIELD_NUMBER: builtins.int + SUM_FIELD_NUMBER: builtins.int + QUANTILE_VALUES_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """The set of key/value pairs that uniquely identify the timeseries from + where this point belongs. The list may be empty (may contain 0 elements). + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + start_time_unix_nano: builtins.int + """StartTimeUnixNano is optional but strongly encouraged, see the + the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + time_unix_nano: builtins.int + """TimeUnixNano is required, see the detailed comments above Metric. + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + count: builtins.int + """count is the number of values in the population. Must be non-negative.""" + sum: builtins.float + """sum of the values in the population. If count is zero then this field + must be zero. + + Note: Sum should only be filled out when measuring non-negative discrete + events, and is assumed to be monotonic over the values of these events. + Negative events *can* be recorded, but sum should not be filled out when + doing so. This is specifically to enforce compatibility w/ OpenMetrics, + see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#summary + """ + @property + def quantile_values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SummaryDataPoint.ValueAtQuantile]: + """(Optional) list of values at different quantiles of the distribution calculated + from the current snapshot. The quantiles must be strictly increasing. + """ + flags: builtins.int + """Flags that apply to this specific data point. See DataPointFlags + for the available flags and their meaning. + """ + def __init__( + self, + *, + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + start_time_unix_nano: builtins.int = ..., + time_unix_nano: builtins.int = ..., + count: builtins.int = ..., + sum: builtins.float = ..., + quantile_values: collections.abc.Iterable[global___SummaryDataPoint.ValueAtQuantile] | None = ..., + flags: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "count", b"count", "flags", b"flags", "quantile_values", b"quantile_values", "start_time_unix_nano", b"start_time_unix_nano", "sum", b"sum", "time_unix_nano", b"time_unix_nano"]) -> None: ... + +global___SummaryDataPoint = SummaryDataPoint + +@typing_extensions.final +class Exemplar(google.protobuf.message.Message): + """A representation of an exemplar, which is a sample input measurement. + Exemplars also hold information about the environment when the measurement + was recorded, for example the span and trace ID of the active span when the + exemplar was recorded. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FILTERED_ATTRIBUTES_FIELD_NUMBER: builtins.int + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + AS_DOUBLE_FIELD_NUMBER: builtins.int + AS_INT_FIELD_NUMBER: builtins.int + SPAN_ID_FIELD_NUMBER: builtins.int + TRACE_ID_FIELD_NUMBER: builtins.int + @property + def filtered_attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """The set of key/value pairs that were filtered out by the aggregator, but + recorded alongside the original measurement. Only key/value pairs that were + filtered out by the aggregator should be included + """ + time_unix_nano: builtins.int + """time_unix_nano is the exact time when this exemplar was recorded + + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + 1970. + """ + as_double: builtins.float + as_int: builtins.int + span_id: builtins.bytes + """(Optional) Span ID of the exemplar trace. + span_id may be missing if the measurement is not recorded inside a trace + or if the trace is not sampled. + """ + trace_id: builtins.bytes + """(Optional) Trace ID of the exemplar trace. + trace_id may be missing if the measurement is not recorded inside a trace + or if the trace is not sampled. + """ + def __init__( + self, + *, + filtered_attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + time_unix_nano: builtins.int = ..., + as_double: builtins.float = ..., + as_int: builtins.int = ..., + span_id: builtins.bytes = ..., + trace_id: builtins.bytes = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "filtered_attributes", b"filtered_attributes", "span_id", b"span_id", "time_unix_nano", b"time_unix_nano", "trace_id", b"trace_id", "value", b"value"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["as_double", "as_int"] | None: ... + +global___Exemplar = Exemplar diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py new file mode 100644 index 00000000000..5d8c241a36b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/profiles/v1development/profiles.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n9opentelemetry/proto/profiles/v1development/profiles.proto\x12*opentelemetry.proto.profiles.v1development\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"\xf6\x03\n\x12ProfilesDictionary\x12J\n\rmapping_table\x18\x01 \x03(\x0b\x32\x33.opentelemetry.proto.profiles.v1development.Mapping\x12L\n\x0elocation_table\x18\x02 \x03(\x0b\x32\x34.opentelemetry.proto.profiles.v1development.Location\x12L\n\x0e\x66unction_table\x18\x03 \x03(\x0b\x32\x34.opentelemetry.proto.profiles.v1development.Function\x12\x44\n\nlink_table\x18\x04 \x03(\x0b\x32\x30.opentelemetry.proto.profiles.v1development.Link\x12\x14\n\x0cstring_table\x18\x05 \x03(\t\x12T\n\x0f\x61ttribute_table\x18\x06 \x03(\x0b\x32;.opentelemetry.proto.profiles.v1development.KeyValueAndUnit\x12\x46\n\x0bstack_table\x18\x07 \x03(\x0b\x32\x31.opentelemetry.proto.profiles.v1development.Stack\"\xbb\x01\n\x0cProfilesData\x12W\n\x11resource_profiles\x18\x01 \x03(\x0b\x32<.opentelemetry.proto.profiles.v1development.ResourceProfiles\x12R\n\ndictionary\x18\x02 \x01(\x0b\x32>.opentelemetry.proto.profiles.v1development.ProfilesDictionary\"\xbe\x01\n\x10ResourceProfiles\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12Q\n\x0escope_profiles\x18\x02 \x03(\x0b\x32\x39.opentelemetry.proto.profiles.v1development.ScopeProfiles\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\xae\x01\n\rScopeProfiles\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12\x45\n\x08profiles\x18\x02 \x03(\x0b\x32\x33.opentelemetry.proto.profiles.v1development.Profile\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\xb1\x03\n\x07Profile\x12J\n\x0bsample_type\x18\x01 \x01(\x0b\x32\x35.opentelemetry.proto.profiles.v1development.ValueType\x12\x43\n\x07samples\x18\x02 \x03(\x0b\x32\x32.opentelemetry.proto.profiles.v1development.Sample\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\x15\n\rduration_nano\x18\x04 \x01(\x04\x12J\n\x0bperiod_type\x18\x05 \x01(\x0b\x32\x35.opentelemetry.proto.profiles.v1development.ValueType\x12\x0e\n\x06period\x18\x06 \x01(\x03\x12\x12\n\nprofile_id\x18\x07 \x01(\x0c\x12 \n\x18\x64ropped_attributes_count\x18\x08 \x01(\r\x12\x1f\n\x17original_payload_format\x18\t \x01(\t\x12\x18\n\x10original_payload\x18\n \x01(\x0c\x12\x19\n\x11\x61ttribute_indices\x18\x0b \x03(\x05\")\n\x04Link\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\"9\n\tValueType\x12\x15\n\rtype_strindex\x18\x01 \x01(\x05\x12\x15\n\runit_strindex\x18\x02 \x01(\x05\"z\n\x06Sample\x12\x13\n\x0bstack_index\x18\x01 \x01(\x05\x12\x19\n\x11\x61ttribute_indices\x18\x02 \x03(\x05\x12\x12\n\nlink_index\x18\x03 \x01(\x05\x12\x0e\n\x06values\x18\x04 \x03(\x03\x12\x1c\n\x14timestamps_unix_nano\x18\x05 \x03(\x06\"\x80\x01\n\x07Mapping\x12\x14\n\x0cmemory_start\x18\x01 \x01(\x04\x12\x14\n\x0cmemory_limit\x18\x02 \x01(\x04\x12\x13\n\x0b\x66ile_offset\x18\x03 \x01(\x04\x12\x19\n\x11\x66ilename_strindex\x18\x04 \x01(\x05\x12\x19\n\x11\x61ttribute_indices\x18\x05 \x03(\x05\"!\n\x05Stack\x12\x18\n\x10location_indices\x18\x01 \x03(\x05\"\x8e\x01\n\x08Location\x12\x15\n\rmapping_index\x18\x01 \x01(\x05\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\x04\x12?\n\x05lines\x18\x03 \x03(\x0b\x32\x30.opentelemetry.proto.profiles.v1development.Line\x12\x19\n\x11\x61ttribute_indices\x18\x04 \x03(\x05\"<\n\x04Line\x12\x16\n\x0e\x66unction_index\x18\x01 \x01(\x05\x12\x0c\n\x04line\x18\x02 \x01(\x03\x12\x0e\n\x06\x63olumn\x18\x03 \x01(\x03\"n\n\x08\x46unction\x12\x15\n\rname_strindex\x18\x01 \x01(\x05\x12\x1c\n\x14system_name_strindex\x18\x02 \x01(\x05\x12\x19\n\x11\x66ilename_strindex\x18\x03 \x01(\x05\x12\x12\n\nstart_line\x18\x04 \x01(\x03\"v\n\x0fKeyValueAndUnit\x12\x14\n\x0ckey_strindex\x18\x01 \x01(\x05\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\x12\x15\n\runit_strindex\x18\x03 \x01(\x05\x42\xa4\x01\n-io.opentelemetry.proto.profiles.v1developmentB\rProfilesProtoP\x01Z5go.opentelemetry.io/proto/otlp/profiles/v1development\xaa\x02*OpenTelemetry.Proto.Profiles.V1Developmentb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.profiles.v1development.profiles_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n-io.opentelemetry.proto.profiles.v1developmentB\rProfilesProtoP\001Z5go.opentelemetry.io/proto/otlp/profiles/v1development\252\002*OpenTelemetry.Proto.Profiles.V1Development' + _globals['_PROFILESDICTIONARY']._serialized_start=198 + _globals['_PROFILESDICTIONARY']._serialized_end=700 + _globals['_PROFILESDATA']._serialized_start=703 + _globals['_PROFILESDATA']._serialized_end=890 + _globals['_RESOURCEPROFILES']._serialized_start=893 + _globals['_RESOURCEPROFILES']._serialized_end=1083 + _globals['_SCOPEPROFILES']._serialized_start=1086 + _globals['_SCOPEPROFILES']._serialized_end=1260 + _globals['_PROFILE']._serialized_start=1263 + _globals['_PROFILE']._serialized_end=1696 + _globals['_LINK']._serialized_start=1698 + _globals['_LINK']._serialized_end=1739 + _globals['_VALUETYPE']._serialized_start=1741 + _globals['_VALUETYPE']._serialized_end=1798 + _globals['_SAMPLE']._serialized_start=1800 + _globals['_SAMPLE']._serialized_end=1922 + _globals['_MAPPING']._serialized_start=1925 + _globals['_MAPPING']._serialized_end=2053 + _globals['_STACK']._serialized_start=2055 + _globals['_STACK']._serialized_end=2088 + _globals['_LOCATION']._serialized_start=2091 + _globals['_LOCATION']._serialized_end=2233 + _globals['_LINE']._serialized_start=2235 + _globals['_LINE']._serialized_end=2295 + _globals['_FUNCTION']._serialized_start=2297 + _globals['_FUNCTION']._serialized_end=2407 + _globals['_KEYVALUEANDUNIT']._serialized_start=2409 + _globals['_KEYVALUEANDUNIT']._serialized_end=2527 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi new file mode 100644 index 00000000000..01938eded00 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi @@ -0,0 +1,800 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2023, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +This file includes work covered by the following copyright and permission notices: + +Copyright 2016 Google Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import opentelemetry.proto.common.v1.common_pb2 +import opentelemetry.proto.resource.v1.resource_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class ProfilesDictionary(google.protobuf.message.Message): + """ Relationships Diagram + + ┌──────────────────┐ LEGEND + │ ProfilesData │ ─────┐ + └──────────────────┘ │ ─────▶ embedded + │ │ + │ 1-n │ ─────▷ referenced by index + ▼ ▼ + ┌──────────────────┐ ┌────────────────────┐ + │ ResourceProfiles │ │ ProfilesDictionary │ + └──────────────────┘ └────────────────────┘ + │ + │ 1-n + ▼ + ┌──────────────────┐ + │ ScopeProfiles │ + └──────────────────┘ + │ + │ 1-n + ▼ + ┌──────────────────┐ + │ Profile │ + └──────────────────┘ + │ n-1 + │ 1-n ┌───────────────────────────────────────┐ + ▼ │ ▽ + ┌──────────────────┐ 1-n ┌─────────────────┐ ┌──────────┐ + │ Sample │ ──────▷ │ KeyValueAndUnit │ │ Link │ + └──────────────────┘ └─────────────────┘ └──────────┘ + │ △ △ + │ n-1 │ │ 1-n + ▽ │ │ + ┌──────────────────┐ │ │ + │ Stack │ │ │ + └──────────────────┘ │ │ + │ 1-n │ │ + │ 1-n ┌────────────────┘ │ + ▽ │ │ + ┌──────────────────┐ n-1 ┌─────────────┐ + │ Location │ ──────▷ │ Mapping │ + └──────────────────┘ └─────────────┘ + │ + │ 1-n + ▼ + ┌──────────────────┐ + │ Line │ + └──────────────────┘ + │ + │ 1-1 + ▽ + ┌──────────────────┐ + │ Function │ + └──────────────────┘ + + ProfilesDictionary represents the profiles data shared across the + entire message being sent. The following applies to all fields in this + message: + + - A dictionary is an array of dictionary items. Users of the dictionary + compactly reference the items using the index within the array. + + - A dictionary MUST have a zero value encoded as the first element. This + allows for _index fields pointing into the dictionary to use a 0 pointer + value to indicate 'null' / 'not set'. Unless otherwise defined, a 'zero + value' message value is one with all default field values, so as to + minimize wire encoded size. + + - There SHOULD NOT be dupes in a dictionary. The identity of dictionary + items is based on their value, recursively as needed. If a particular + implementation does emit duplicated items, it MUST NOT attempt to give them + meaning based on the index or order. A profile processor may remove + duplicate items and this MUST NOT have any observable effects for + consumers. + + - There SHOULD NOT be orphaned (unreferenced) items in a dictionary. A + profile processor may remove ("garbage-collect") orphaned items and this + MUST NOT have any observable effects for consumers. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MAPPING_TABLE_FIELD_NUMBER: builtins.int + LOCATION_TABLE_FIELD_NUMBER: builtins.int + FUNCTION_TABLE_FIELD_NUMBER: builtins.int + LINK_TABLE_FIELD_NUMBER: builtins.int + STRING_TABLE_FIELD_NUMBER: builtins.int + ATTRIBUTE_TABLE_FIELD_NUMBER: builtins.int + STACK_TABLE_FIELD_NUMBER: builtins.int + @property + def mapping_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Mapping]: + """Mappings from address ranges to the image/binary/library mapped + into that address range referenced by locations via Location.mapping_index. + + mapping_table[0] must always be zero value (Mapping{}) and present. + """ + @property + def location_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Location]: + """Locations referenced by samples via Stack.location_indices. + + location_table[0] must always be zero value (Location{}) and present. + """ + @property + def function_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Function]: + """Functions referenced by locations via Line.function_index. + + function_table[0] must always be zero value (Function{}) and present. + """ + @property + def link_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Link]: + """Links referenced by samples via Sample.link_index. + + link_table[0] must always be zero value (Link{}) and present. + """ + @property + def string_table(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: + """A common table for strings referenced by various messages. + + string_table[0] must always be "" and present. + """ + @property + def attribute_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___KeyValueAndUnit]: + """A common table for attributes referenced by the Profile, Sample, Mapping + and Location messages below through attribute_indices field. Each entry is + a key/value pair with an optional unit. Since this is a dictionary table, + multiple entries with the same key may be present, unlike direct attribute + tables like Resource.attributes. The referencing attribute_indices fields, + though, do maintain the key uniqueness requirement. + + It's recommended to use attributes for variables with bounded cardinality, + such as categorical variables + (https://en.wikipedia.org/wiki/Categorical_variable). Using an attribute of + a floating point type (e.g., CPU time) in a sample can quickly make every + attribute value unique, defeating the purpose of the dictionary and + impractically increasing the profile size. + + Examples of attributes: + "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" + "abc.com/myattribute": true + "allocation_size": 128 bytes + + attribute_table[0] must always be zero value (KeyValueAndUnit{}) and present. + """ + @property + def stack_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Stack]: + """Stacks referenced by samples via Sample.stack_index. + + stack_table[0] must always be zero value (Stack{}) and present. + """ + def __init__( + self, + *, + mapping_table: collections.abc.Iterable[global___Mapping] | None = ..., + location_table: collections.abc.Iterable[global___Location] | None = ..., + function_table: collections.abc.Iterable[global___Function] | None = ..., + link_table: collections.abc.Iterable[global___Link] | None = ..., + string_table: collections.abc.Iterable[builtins.str] | None = ..., + attribute_table: collections.abc.Iterable[global___KeyValueAndUnit] | None = ..., + stack_table: collections.abc.Iterable[global___Stack] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attribute_table", b"attribute_table", "function_table", b"function_table", "link_table", b"link_table", "location_table", b"location_table", "mapping_table", b"mapping_table", "stack_table", b"stack_table", "string_table", b"string_table"]) -> None: ... + +global___ProfilesDictionary = ProfilesDictionary + +@typing_extensions.final +class ProfilesData(google.protobuf.message.Message): + """ProfilesData represents the profiles data that can be stored in persistent storage, + OR can be embedded by other protocols that transfer OTLP profiles data but do not + implement the OTLP protocol. + + The main difference between this message and collector protocol is that + in this message there will not be any "control" or "metadata" specific to + OTLP protocol. + + When new fields are added into this message, the OTLP request MUST be updated + as well. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_PROFILES_FIELD_NUMBER: builtins.int + DICTIONARY_FIELD_NUMBER: builtins.int + @property + def resource_profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceProfiles]: + """An array of ResourceProfiles. + For data coming from an SDK profiler, this array will typically contain one + element. Host-level profilers will usually create one ResourceProfile per + container, as well as one additional ResourceProfile grouping all samples + from non-containerized processes. + Other resource groupings are possible as well and clarified via + Resource.attributes and semantic conventions. + Tools that visualize profiles should prefer displaying + resources_profiles[0].scope_profiles[0].profiles[0] by default. + """ + @property + def dictionary(self) -> global___ProfilesDictionary: + """One instance of ProfilesDictionary""" + def __init__( + self, + *, + resource_profiles: collections.abc.Iterable[global___ResourceProfiles] | None = ..., + dictionary: global___ProfilesDictionary | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary", "resource_profiles", b"resource_profiles"]) -> None: ... + +global___ProfilesData = ProfilesData + +@typing_extensions.final +class ResourceProfiles(google.protobuf.message.Message): + """A collection of ScopeProfiles from a Resource.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_FIELD_NUMBER: builtins.int + SCOPE_PROFILES_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: + """The resource for the profiles in this message. + If this field is not set then no resource info is known. + """ + @property + def scope_profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeProfiles]: + """A list of ScopeProfiles that originate from a resource.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the resource data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "resource" field. It does not apply + to the data in the "scope_profiles" field which have their own schema_url field. + """ + def __init__( + self, + *, + resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., + scope_profiles: collections.abc.Iterable[global___ScopeProfiles] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_profiles", b"scope_profiles"]) -> None: ... + +global___ResourceProfiles = ResourceProfiles + +@typing_extensions.final +class ScopeProfiles(google.protobuf.message.Message): + """A collection of Profiles produced by an InstrumentationScope.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCOPE_FIELD_NUMBER: builtins.int + PROFILES_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: + """The instrumentation scope information for the profiles in this message. + Semantically when InstrumentationScope isn't set, it is equivalent with + an empty instrumentation scope name (unknown). + """ + @property + def profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Profile]: + """A list of Profiles that originate from an instrumentation scope.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the profile data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "scope" field and all profiles in the + "profiles" field. + """ + def __init__( + self, + *, + scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., + profiles: collections.abc.Iterable[global___Profile] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["profiles", b"profiles", "schema_url", b"schema_url", "scope", b"scope"]) -> None: ... + +global___ScopeProfiles = ScopeProfiles + +@typing_extensions.final +class Profile(google.protobuf.message.Message): + """Profile is a common stacktrace profile format. + + Measurements represented with this format should follow the + following conventions: + + - Consumers should treat unset optional fields as if they had been + set with their default value. + + - When possible, measurements should be stored in "unsampled" form + that is most useful to humans. There should be enough + information present to determine the original sampled values. + + - The profile is represented as a set of samples, where each sample + references a stack trace which is a list of locations, each belonging + to a mapping. + - There is a N->1 relationship from Stack.location_indices entries to + locations. For every Stack.location_indices entry there must be a + unique Location with that index. + - There is an optional N->1 relationship from locations to + mappings. For every nonzero Location.mapping_id there must be a + unique Mapping with that index. + + Represents a complete profile, including sample types, samples, mappings to + binaries, stacks, locations, functions, string table, and additional + metadata. It modifies and annotates pprof Profile with OpenTelemetry + specific fields. + + Note that whilst fields in this message retain the name and field id from pprof in most cases + for ease of understanding data migration, it is not intended that pprof:Profile and + OpenTelemetry:Profile encoding be wire compatible. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SAMPLE_TYPE_FIELD_NUMBER: builtins.int + SAMPLES_FIELD_NUMBER: builtins.int + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + DURATION_NANO_FIELD_NUMBER: builtins.int + PERIOD_TYPE_FIELD_NUMBER: builtins.int + PERIOD_FIELD_NUMBER: builtins.int + PROFILE_ID_FIELD_NUMBER: builtins.int + DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int + ORIGINAL_PAYLOAD_FORMAT_FIELD_NUMBER: builtins.int + ORIGINAL_PAYLOAD_FIELD_NUMBER: builtins.int + ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int + @property + def sample_type(self) -> global___ValueType: + """The type and unit of all Sample.values in this profile. + For a cpu or off-cpu profile this might be: + ["cpu","nanoseconds"] or ["off_cpu","nanoseconds"] + For a heap profile, this might be: + ["allocated_objects","count"] or ["allocated_space","bytes"], + """ + @property + def samples(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Sample]: + """The set of samples recorded in this profile.""" + time_unix_nano: builtins.int + """The following fields 3-12 are informational, do not affect + interpretation of results. + + Time of collection. Value is UNIX Epoch time in nanoseconds since 00:00:00 + UTC on 1 January 1970. + """ + duration_nano: builtins.int + """Duration of the profile. For instant profiles like live heap snapshot, the + duration can be zero but it may be preferable to set time_unix_nano to the + process start time and duration_nano to the relative time when the profile + was gathered. This ensures Sample.timestamps_unix_nano values such as + allocation timestamp fall into the profile time range. + """ + @property + def period_type(self) -> global___ValueType: + """The kind of events between sampled occurrences. + e.g [ "cpu","cycles" ] or [ "heap","bytes" ] + """ + period: builtins.int + """The number of events between sampled occurrences.""" + profile_id: builtins.bytes + """A globally unique identifier for a profile. The ID is a 16-byte array. An ID with + all zeroes is considered invalid. It may be used for deduplication and signal + correlation purposes. It is acceptable to treat two profiles with different values + in this field as not equal, even if they represented the same object at an earlier + time. + This field is optional; an ID may be assigned to an ID-less profile in a later step. + """ + dropped_attributes_count: builtins.int + """The number of attributes that were discarded. Attributes + can be discarded because their keys are too long or because there are too many + attributes. If this value is 0, then no attributes were dropped. + """ + original_payload_format: builtins.str + """The original payload format. See also original_payload. Optional, but the + format and the bytes must be set or unset together. + + The allowed values for the format string are defined by the OpenTelemetry + specification. Some examples are "jfr", "pprof", "linux_perf". + + The original payload may be optionally provided when the conversion to the + OLTP format was done from a different format with some loss of the fidelity + and the receiver may want to store the original payload to allow future + lossless export or reinterpretation. Some examples of the original format + are JFR (Java Flight Recorder), pprof, Linux perf. + + Even when the original payload is in a format that is semantically close to + OTLP, such as pprof, a conversion may still be lossy in some cases (e.g. if + the pprof file contains custom extensions or conventions). + + The original payload can be large in size, so including the original + payload should be configurable by the profiler or collector options. The + default behavior should be to not include the original payload. + """ + original_payload: builtins.bytes + """The original payload bytes. See also original_payload_format. Optional, but + format and the bytes must be set or unset together. + """ + @property + def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """References to attributes in attribute_table. [optional]""" + def __init__( + self, + *, + sample_type: global___ValueType | None = ..., + samples: collections.abc.Iterable[global___Sample] | None = ..., + time_unix_nano: builtins.int = ..., + duration_nano: builtins.int = ..., + period_type: global___ValueType | None = ..., + period: builtins.int = ..., + profile_id: builtins.bytes = ..., + dropped_attributes_count: builtins.int = ..., + original_payload_format: builtins.str = ..., + original_payload: builtins.bytes = ..., + attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["period_type", b"period_type", "sample_type", b"sample_type"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["attribute_indices", b"attribute_indices", "dropped_attributes_count", b"dropped_attributes_count", "duration_nano", b"duration_nano", "original_payload", b"original_payload", "original_payload_format", b"original_payload_format", "period", b"period", "period_type", b"period_type", "profile_id", b"profile_id", "sample_type", b"sample_type", "samples", b"samples", "time_unix_nano", b"time_unix_nano"]) -> None: ... + +global___Profile = Profile + +@typing_extensions.final +class Link(google.protobuf.message.Message): + """A pointer from a profile Sample to a trace Span. + Connects a profile sample to a trace span, identified by unique trace and span IDs. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACE_ID_FIELD_NUMBER: builtins.int + SPAN_ID_FIELD_NUMBER: builtins.int + trace_id: builtins.bytes + """A unique identifier of a trace that this linked span is part of. The ID is a + 16-byte array. + """ + span_id: builtins.bytes + """A unique identifier for the linked span. The ID is an 8-byte array.""" + def __init__( + self, + *, + trace_id: builtins.bytes = ..., + span_id: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["span_id", b"span_id", "trace_id", b"trace_id"]) -> None: ... + +global___Link = Link + +@typing_extensions.final +class ValueType(google.protobuf.message.Message): + """ValueType describes the type and units of a value.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TYPE_STRINDEX_FIELD_NUMBER: builtins.int + UNIT_STRINDEX_FIELD_NUMBER: builtins.int + type_strindex: builtins.int + """Index into ProfilesDictionary.string_table.""" + unit_strindex: builtins.int + """Index into ProfilesDictionary.string_table.""" + def __init__( + self, + *, + type_strindex: builtins.int = ..., + unit_strindex: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["type_strindex", b"type_strindex", "unit_strindex", b"unit_strindex"]) -> None: ... + +global___ValueType = ValueType + +@typing_extensions.final +class Sample(google.protobuf.message.Message): + """Each Sample records values encountered in some program context. The program + context is typically a stack trace, perhaps augmented with auxiliary + information like the thread-id, some indicator of a higher level request + being handled etc. + + A Sample MUST have have at least one values or timestamps_unix_nano entry. If + both fields are populated, they MUST contain the same number of elements, and + the elements at the same index MUST refer to the same event. + + For the purposes of efficiently representing aggregated data observations, a Sample is regarded + as having a shared identity and an associated collection of per-observation data points. + Samples having the same identity SHOULD be combined by inserting timestamps and values to the data arrays. + + Examples of different ways ('shapes') of representing a sample with the total value of 10: + + Report of a stacktrace at 10 timestamps (consumers must assume the value is 1 for each point): + values: [] + timestamps_unix_nano: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + Report of a stacktrace with an aggregated value without timestamps: + values: [10] + timestamps_unix_nano: [] + + Report of a stacktrace at 4 timestamps where each point records a specific value: + values: [2, 2, 3, 3] + timestamps_unix_nano: [1, 2, 3, 4] + + All Samples for a Profile SHOULD have the same shape, i.e. all data observation series should consistently + adopt the same data recording style. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + STACK_INDEX_FIELD_NUMBER: builtins.int + ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int + LINK_INDEX_FIELD_NUMBER: builtins.int + VALUES_FIELD_NUMBER: builtins.int + TIMESTAMPS_UNIX_NANO_FIELD_NUMBER: builtins.int + stack_index: builtins.int + """A Sample's identity (i.e. 'primary key') is the tuple of {stack_index, set_of(attribute_indices), link_index} + + Reference to stack in ProfilesDictionary.stack_table. + """ + @property + def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """References to attributes in ProfilesDictionary.attribute_table. [optional]""" + link_index: builtins.int + """Reference to link in ProfilesDictionary.link_table. [optional] + It can be unset / set to 0 if no link exists, as link_table[0] is always a 'null' default value. + """ + @property + def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """The following fields may contain per-observation data and do not form part of the Sample's identity. + + The type and unit of each value is defined by Profile.sample_type. + """ + @property + def timestamps_unix_nano(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """Timestamps associated with Sample. Value is UNIX Epoch time in nanoseconds + since 00:00:00 UTC on 1 January 1970. The timestamps should fall within the + [Profile.time_unix_nano, Profile.time_unix_nano + Profile.duration_nano) + time range. + """ + def __init__( + self, + *, + stack_index: builtins.int = ..., + attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., + link_index: builtins.int = ..., + values: collections.abc.Iterable[builtins.int] | None = ..., + timestamps_unix_nano: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attribute_indices", b"attribute_indices", "link_index", b"link_index", "stack_index", b"stack_index", "timestamps_unix_nano", b"timestamps_unix_nano", "values", b"values"]) -> None: ... + +global___Sample = Sample + +@typing_extensions.final +class Mapping(google.protobuf.message.Message): + """Describes the mapping of a binary in memory, including its address range, + file offset, and metadata like build ID + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MEMORY_START_FIELD_NUMBER: builtins.int + MEMORY_LIMIT_FIELD_NUMBER: builtins.int + FILE_OFFSET_FIELD_NUMBER: builtins.int + FILENAME_STRINDEX_FIELD_NUMBER: builtins.int + ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int + memory_start: builtins.int + """Address at which the binary (or DLL) is loaded into memory.""" + memory_limit: builtins.int + """The limit of the address range occupied by this mapping.""" + file_offset: builtins.int + """Offset in the binary that corresponds to the first mapped address.""" + filename_strindex: builtins.int + """The object this entry is loaded from. This can be a filename on + disk for the main binary and shared libraries, or virtual + abstractions like "[vdso]". + Index into ProfilesDictionary.string_table. + """ + @property + def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """References to attributes in ProfilesDictionary.attribute_table. [optional]""" + def __init__( + self, + *, + memory_start: builtins.int = ..., + memory_limit: builtins.int = ..., + file_offset: builtins.int = ..., + filename_strindex: builtins.int = ..., + attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attribute_indices", b"attribute_indices", "file_offset", b"file_offset", "filename_strindex", b"filename_strindex", "memory_limit", b"memory_limit", "memory_start", b"memory_start"]) -> None: ... + +global___Mapping = Mapping + +@typing_extensions.final +class Stack(google.protobuf.message.Message): + """A Stack represents a stack trace as a list of locations.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + LOCATION_INDICES_FIELD_NUMBER: builtins.int + @property + def location_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """References to locations in ProfilesDictionary.location_table. + The first location is the leaf frame. + """ + def __init__( + self, + *, + location_indices: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["location_indices", b"location_indices"]) -> None: ... + +global___Stack = Stack + +@typing_extensions.final +class Location(google.protobuf.message.Message): + """Describes function and line table debug information.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + MAPPING_INDEX_FIELD_NUMBER: builtins.int + ADDRESS_FIELD_NUMBER: builtins.int + LINES_FIELD_NUMBER: builtins.int + ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int + mapping_index: builtins.int + """Reference to mapping in ProfilesDictionary.mapping_table. + It can be unset / set to 0 if the mapping is unknown or not applicable for + this profile type, as mapping_table[0] is always a 'null' default mapping. + """ + address: builtins.int + """The instruction address for this location, if available. It + should be within [Mapping.memory_start...Mapping.memory_limit] + for the corresponding mapping. A non-leaf address may be in the + middle of a call instruction. It is up to display tools to find + the beginning of the instruction if necessary. + """ + @property + def lines(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Line]: + """Multiple line indicates this location has inlined functions, + where the last entry represents the caller into which the + preceding entries were inlined. + + E.g., if memcpy() is inlined into printf: + lines[0].function_name == "memcpy" + lines[1].function_name == "printf" + """ + @property + def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: + """References to attributes in ProfilesDictionary.attribute_table. [optional]""" + def __init__( + self, + *, + mapping_index: builtins.int = ..., + address: builtins.int = ..., + lines: collections.abc.Iterable[global___Line] | None = ..., + attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "attribute_indices", b"attribute_indices", "lines", b"lines", "mapping_index", b"mapping_index"]) -> None: ... + +global___Location = Location + +@typing_extensions.final +class Line(google.protobuf.message.Message): + """Details a specific line in a source code, linked to a function.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + FUNCTION_INDEX_FIELD_NUMBER: builtins.int + LINE_FIELD_NUMBER: builtins.int + COLUMN_FIELD_NUMBER: builtins.int + function_index: builtins.int + """Reference to function in ProfilesDictionary.function_table.""" + line: builtins.int + """Line number in source code. 0 means unset.""" + column: builtins.int + """Column number in source code. 0 means unset.""" + def __init__( + self, + *, + function_index: builtins.int = ..., + line: builtins.int = ..., + column: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["column", b"column", "function_index", b"function_index", "line", b"line"]) -> None: ... + +global___Line = Line + +@typing_extensions.final +class Function(google.protobuf.message.Message): + """Describes a function, including its human-readable name, system name, + source file, and starting line number in the source. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NAME_STRINDEX_FIELD_NUMBER: builtins.int + SYSTEM_NAME_STRINDEX_FIELD_NUMBER: builtins.int + FILENAME_STRINDEX_FIELD_NUMBER: builtins.int + START_LINE_FIELD_NUMBER: builtins.int + name_strindex: builtins.int + """The function name. Empty string if not available.""" + system_name_strindex: builtins.int + """Function name, as identified by the system. For instance, + it can be a C++ mangled name. Empty string if not available. + """ + filename_strindex: builtins.int + """Source file containing the function. Empty string if not available.""" + start_line: builtins.int + """Line number in source file. 0 means unset.""" + def __init__( + self, + *, + name_strindex: builtins.int = ..., + system_name_strindex: builtins.int = ..., + filename_strindex: builtins.int = ..., + start_line: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["filename_strindex", b"filename_strindex", "name_strindex", b"name_strindex", "start_line", b"start_line", "system_name_strindex", b"system_name_strindex"]) -> None: ... + +global___Function = Function + +@typing_extensions.final +class KeyValueAndUnit(google.protobuf.message.Message): + """A custom 'dictionary native' style of encoding attributes which is more convenient + for profiles than opentelemetry.proto.common.v1.KeyValue + Specifically, uses the string table for keys and allows optional unit information. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + KEY_STRINDEX_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + UNIT_STRINDEX_FIELD_NUMBER: builtins.int + key_strindex: builtins.int + """The index into the string table for the attribute's key.""" + @property + def value(self) -> opentelemetry.proto.common.v1.common_pb2.AnyValue: + """The value of the attribute.""" + unit_strindex: builtins.int + """The index into the string table for the attribute's unit. + zero indicates implicit (by semconv) or non-defined unit. + """ + def __init__( + self, + *, + key_strindex: builtins.int = ..., + value: opentelemetry.proto.common.v1.common_pb2.AnyValue | None = ..., + unit_strindex: builtins.int = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["key_strindex", b"key_strindex", "unit_strindex", b"unit_strindex", "value", b"value"]) -> None: ... + +global___KeyValueAndUnit = KeyValueAndUnit diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py new file mode 100644 index 00000000000..f226d76ea50 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/resource/v1/resource.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.opentelemetry/proto/resource/v1/resource.proto\x12\x1fopentelemetry.proto.resource.v1\x1a*opentelemetry/proto/common/v1/common.proto\"\xa8\x01\n\x08Resource\x12;\n\nattributes\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x02 \x01(\r\x12=\n\x0b\x65ntity_refs\x18\x03 \x03(\x0b\x32(.opentelemetry.proto.common.v1.EntityRefB\x83\x01\n\"io.opentelemetry.proto.resource.v1B\rResourceProtoP\x01Z*go.opentelemetry.io/proto/otlp/resource/v1\xaa\x02\x1fOpenTelemetry.Proto.Resource.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\"io.opentelemetry.proto.resource.v1B\rResourceProtoP\001Z*go.opentelemetry.io/proto/otlp/resource/v1\252\002\037OpenTelemetry.Proto.Resource.V1' + _globals['_RESOURCE']._serialized_start=128 + _globals['_RESOURCE']._serialized_end=296 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi new file mode 100644 index 00000000000..61472c538e1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi @@ -0,0 +1,70 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2019, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import opentelemetry.proto.common.v1.common_pb2 +import sys + +if sys.version_info >= (3, 8): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing_extensions.final +class Resource(google.protobuf.message.Message): + """Resource information.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + ATTRIBUTES_FIELD_NUMBER: builtins.int + DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int + ENTITY_REFS_FIELD_NUMBER: builtins.int + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """Set of attributes that describe the resource. + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + dropped_attributes_count: builtins.int + """The number of dropped attributes. If the value is 0, then + no attributes were dropped. + """ + @property + def entity_refs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.EntityRef]: + """Set of entities that participate in this Resource. + + Note: keys in the references MUST exist in attributes of this message. + + Status: [Development] + """ + def __init__( + self, + *, + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + dropped_attributes_count: builtins.int = ..., + entity_refs: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.EntityRef] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "entity_refs", b"entity_refs"]) -> None: ... + +global___Resource = Resource diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py new file mode 100644 index 00000000000..534b3a6a522 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: opentelemetry/proto/trace/v1/trace.proto +# Protobuf Python Version: 5.26.1 +"""Generated protocol buffer code.""" +from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor +from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool +from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database +from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 +from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(opentelemetry/proto/trace/v1/trace.proto\x12\x1copentelemetry.proto.trace.v1\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"Q\n\nTracesData\x12\x43\n\x0eresource_spans\x18\x01 \x03(\x0b\x32+.opentelemetry.proto.trace.v1.ResourceSpans\"\xa7\x01\n\rResourceSpans\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12=\n\x0bscope_spans\x18\x02 \x03(\x0b\x32(.opentelemetry.proto.trace.v1.ScopeSpans\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\x97\x01\n\nScopeSpans\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12\x31\n\x05spans\x18\x02 \x03(\x0b\x32\".opentelemetry.proto.trace.v1.Span\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\x84\x08\n\x04Span\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\x12\x13\n\x0btrace_state\x18\x03 \x01(\t\x12\x16\n\x0eparent_span_id\x18\x04 \x01(\x0c\x12\r\n\x05\x66lags\x18\x10 \x01(\x07\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x39\n\x04kind\x18\x06 \x01(\x0e\x32+.opentelemetry.proto.trace.v1.Span.SpanKind\x12\x1c\n\x14start_time_unix_nano\x18\x07 \x01(\x06\x12\x1a\n\x12\x65nd_time_unix_nano\x18\x08 \x01(\x06\x12;\n\nattributes\x18\t \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\n \x01(\r\x12\x38\n\x06\x65vents\x18\x0b \x03(\x0b\x32(.opentelemetry.proto.trace.v1.Span.Event\x12\x1c\n\x14\x64ropped_events_count\x18\x0c \x01(\r\x12\x36\n\x05links\x18\r \x03(\x0b\x32\'.opentelemetry.proto.trace.v1.Span.Link\x12\x1b\n\x13\x64ropped_links_count\x18\x0e \x01(\r\x12\x34\n\x06status\x18\x0f \x01(\x0b\x32$.opentelemetry.proto.trace.v1.Status\x1a\x8c\x01\n\x05\x45vent\x12\x16\n\x0etime_unix_nano\x18\x01 \x01(\x06\x12\x0c\n\x04name\x18\x02 \x01(\t\x12;\n\nattributes\x18\x03 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x04 \x01(\r\x1a\xac\x01\n\x04Link\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\x12\x13\n\x0btrace_state\x18\x03 \x01(\t\x12;\n\nattributes\x18\x04 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\x07\"\x99\x01\n\x08SpanKind\x12\x19\n\x15SPAN_KIND_UNSPECIFIED\x10\x00\x12\x16\n\x12SPAN_KIND_INTERNAL\x10\x01\x12\x14\n\x10SPAN_KIND_SERVER\x10\x02\x12\x14\n\x10SPAN_KIND_CLIENT\x10\x03\x12\x16\n\x12SPAN_KIND_PRODUCER\x10\x04\x12\x16\n\x12SPAN_KIND_CONSUMER\x10\x05\"\xae\x01\n\x06Status\x12\x0f\n\x07message\x18\x02 \x01(\t\x12=\n\x04\x63ode\x18\x03 \x01(\x0e\x32/.opentelemetry.proto.trace.v1.Status.StatusCode\"N\n\nStatusCode\x12\x15\n\x11STATUS_CODE_UNSET\x10\x00\x12\x12\n\x0eSTATUS_CODE_OK\x10\x01\x12\x15\n\x11STATUS_CODE_ERROR\x10\x02J\x04\x08\x01\x10\x02*\x9c\x01\n\tSpanFlags\x12\x19\n\x15SPAN_FLAGS_DO_NOT_USE\x10\x00\x12 \n\x1bSPAN_FLAGS_TRACE_FLAGS_MASK\x10\xff\x01\x12*\n%SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK\x10\x80\x02\x12&\n!SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK\x10\x80\x04\x42w\n\x1fio.opentelemetry.proto.trace.v1B\nTraceProtoP\x01Z\'go.opentelemetry.io/proto/otlp/trace/v1\xaa\x02\x1cOpenTelemetry.Proto.Trace.V1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\037io.opentelemetry.proto.trace.v1B\nTraceProtoP\001Z\'go.opentelemetry.io/proto/otlp/trace/v1\252\002\034OpenTelemetry.Proto.Trace.V1' + _globals['_SPANFLAGS']._serialized_start=1782 + _globals['_SPANFLAGS']._serialized_end=1938 + _globals['_TRACESDATA']._serialized_start=166 + _globals['_TRACESDATA']._serialized_end=247 + _globals['_RESOURCESPANS']._serialized_start=250 + _globals['_RESOURCESPANS']._serialized_end=417 + _globals['_SCOPESPANS']._serialized_start=420 + _globals['_SCOPESPANS']._serialized_end=571 + _globals['_SPAN']._serialized_start=574 + _globals['_SPAN']._serialized_end=1602 + _globals['_SPAN_EVENT']._serialized_start=1131 + _globals['_SPAN_EVENT']._serialized_end=1271 + _globals['_SPAN_LINK']._serialized_start=1274 + _globals['_SPAN_LINK']._serialized_end=1446 + _globals['_SPAN_SPANKIND']._serialized_start=1449 + _globals['_SPAN_SPANKIND']._serialized_end=1602 + _globals['_STATUS']._serialized_start=1605 + _globals['_STATUS']._serialized_end=1779 + _globals['_STATUS_STATUSCODE']._serialized_start=1695 + _globals['_STATUS_STATUSCODE']._serialized_end=1773 +# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi new file mode 100644 index 00000000000..e21336f03c6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi @@ -0,0 +1,586 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +Copyright 2019, OpenTelemetry Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message +import opentelemetry.proto.common.v1.common_pb2 +import opentelemetry.proto.resource.v1.resource_pb2 +import sys +import typing + +if sys.version_info >= (3, 10): + import typing as typing_extensions +else: + import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class _SpanFlags: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + +class _SpanFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SpanFlags.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SPAN_FLAGS_DO_NOT_USE: _SpanFlags.ValueType # 0 + """The zero value for the enum. Should not be used for comparisons. + Instead use bitwise "and" with the appropriate mask as shown above. + """ + SPAN_FLAGS_TRACE_FLAGS_MASK: _SpanFlags.ValueType # 255 + """Bits 0-7 are used for trace flags.""" + SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK: _SpanFlags.ValueType # 256 + """Bits 8 and 9 are used to indicate that the parent span or link span is remote. + Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known. + Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote. + """ + SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK: _SpanFlags.ValueType # 512 + +class SpanFlags(_SpanFlags, metaclass=_SpanFlagsEnumTypeWrapper): + """SpanFlags represents constants used to interpret the + Span.flags field, which is protobuf 'fixed32' type and is to + be used as bit-fields. Each non-zero value defined in this enum is + a bit-mask. To extract the bit-field, for example, use an + expression like: + + (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK) + + See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + + Note that Span flags were introduced in version 1.1 of the + OpenTelemetry protocol. Older Span producers do not set this + field, consequently consumers should not rely on the absence of a + particular flag bit to indicate the presence of a particular feature. + """ + +SPAN_FLAGS_DO_NOT_USE: SpanFlags.ValueType # 0 +"""The zero value for the enum. Should not be used for comparisons. +Instead use bitwise "and" with the appropriate mask as shown above. +""" +SPAN_FLAGS_TRACE_FLAGS_MASK: SpanFlags.ValueType # 255 +"""Bits 0-7 are used for trace flags.""" +SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK: SpanFlags.ValueType # 256 +"""Bits 8 and 9 are used to indicate that the parent span or link span is remote. +Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known. +Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote. +""" +SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK: SpanFlags.ValueType # 512 +global___SpanFlags = SpanFlags + +@typing_extensions.final +class TracesData(google.protobuf.message.Message): + """TracesData represents the traces data that can be stored in a persistent storage, + OR can be embedded by other protocols that transfer OTLP traces data but do + not implement the OTLP protocol. + + The main difference between this message and collector protocol is that + in this message there will not be any "control" or "metadata" specific to + OTLP protocol. + + When new fields are added into this message, the OTLP request MUST be updated + as well. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_SPANS_FIELD_NUMBER: builtins.int + @property + def resource_spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceSpans]: + """An array of ResourceSpans. + For data coming from a single resource this array will typically contain + one element. Intermediary nodes that receive data from multiple origins + typically batch the data before forwarding further and in that case this + array will contain multiple elements. + """ + def __init__( + self, + *, + resource_spans: collections.abc.Iterable[global___ResourceSpans] | None = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["resource_spans", b"resource_spans"]) -> None: ... + +global___TracesData = TracesData + +@typing_extensions.final +class ResourceSpans(google.protobuf.message.Message): + """A collection of ScopeSpans from a Resource.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + RESOURCE_FIELD_NUMBER: builtins.int + SCOPE_SPANS_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: + """The resource for the spans in this message. + If this field is not set then no resource info is known. + """ + @property + def scope_spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeSpans]: + """A list of ScopeSpans that originate from a resource.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the resource data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "resource" field. It does not apply + to the data in the "scope_spans" field which have their own schema_url field. + """ + def __init__( + self, + *, + resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., + scope_spans: collections.abc.Iterable[global___ScopeSpans] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_spans", b"scope_spans"]) -> None: ... + +global___ResourceSpans = ResourceSpans + +@typing_extensions.final +class ScopeSpans(google.protobuf.message.Message): + """A collection of Spans produced by an InstrumentationScope.""" + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + SCOPE_FIELD_NUMBER: builtins.int + SPANS_FIELD_NUMBER: builtins.int + SCHEMA_URL_FIELD_NUMBER: builtins.int + @property + def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: + """The instrumentation scope information for the spans in this message. + Semantically when InstrumentationScope isn't set, it is equivalent with + an empty instrumentation scope name (unknown). + """ + @property + def spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Span]: + """A list of Spans that originate from an instrumentation scope.""" + schema_url: builtins.str + """The Schema URL, if known. This is the identifier of the Schema that the span data + is recorded in. Notably, the last part of the URL path is the version number of the + schema: http[s]://server[:port]/path/. To learn more about Schema URL see + https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + This schema_url applies to the data in the "scope" field and all spans and span + events in the "spans" field. + """ + def __init__( + self, + *, + scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., + spans: collections.abc.Iterable[global___Span] | None = ..., + schema_url: builtins.str = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["schema_url", b"schema_url", "scope", b"scope", "spans", b"spans"]) -> None: ... + +global___ScopeSpans = ScopeSpans + +@typing_extensions.final +class Span(google.protobuf.message.Message): + """A Span represents a single operation performed by a single component of the system. + + The next available field id is 17. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _SpanKind: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _SpanKindEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Span._SpanKind.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + SPAN_KIND_UNSPECIFIED: Span._SpanKind.ValueType # 0 + """Unspecified. Do NOT use as default. + Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. + """ + SPAN_KIND_INTERNAL: Span._SpanKind.ValueType # 1 + """Indicates that the span represents an internal operation within an application, + as opposed to an operation happening at the boundaries. Default value. + """ + SPAN_KIND_SERVER: Span._SpanKind.ValueType # 2 + """Indicates that the span covers server-side handling of an RPC or other + remote network request. + """ + SPAN_KIND_CLIENT: Span._SpanKind.ValueType # 3 + """Indicates that the span describes a request to some remote service.""" + SPAN_KIND_PRODUCER: Span._SpanKind.ValueType # 4 + """Indicates that the span describes a producer sending a message to a broker. + Unlike CLIENT and SERVER, there is often no direct critical path latency relationship + between producer and consumer spans. A PRODUCER span ends when the message was accepted + by the broker while the logical processing of the message might span a much longer time. + """ + SPAN_KIND_CONSUMER: Span._SpanKind.ValueType # 5 + """Indicates that the span describes consumer receiving a message from a broker. + Like the PRODUCER kind, there is often no direct critical path latency relationship + between producer and consumer spans. + """ + + class SpanKind(_SpanKind, metaclass=_SpanKindEnumTypeWrapper): + """SpanKind is the type of span. Can be used to specify additional relationships between spans + in addition to a parent/child relationship. + """ + + SPAN_KIND_UNSPECIFIED: Span.SpanKind.ValueType # 0 + """Unspecified. Do NOT use as default. + Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. + """ + SPAN_KIND_INTERNAL: Span.SpanKind.ValueType # 1 + """Indicates that the span represents an internal operation within an application, + as opposed to an operation happening at the boundaries. Default value. + """ + SPAN_KIND_SERVER: Span.SpanKind.ValueType # 2 + """Indicates that the span covers server-side handling of an RPC or other + remote network request. + """ + SPAN_KIND_CLIENT: Span.SpanKind.ValueType # 3 + """Indicates that the span describes a request to some remote service.""" + SPAN_KIND_PRODUCER: Span.SpanKind.ValueType # 4 + """Indicates that the span describes a producer sending a message to a broker. + Unlike CLIENT and SERVER, there is often no direct critical path latency relationship + between producer and consumer spans. A PRODUCER span ends when the message was accepted + by the broker while the logical processing of the message might span a much longer time. + """ + SPAN_KIND_CONSUMER: Span.SpanKind.ValueType # 5 + """Indicates that the span describes consumer receiving a message from a broker. + Like the PRODUCER kind, there is often no direct critical path latency relationship + between producer and consumer spans. + """ + + @typing_extensions.final + class Event(google.protobuf.message.Message): + """Event is a time-stamped annotation of the span, consisting of user-supplied + text description and key-value pairs. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + ATTRIBUTES_FIELD_NUMBER: builtins.int + DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int + time_unix_nano: builtins.int + """The time the event occurred.""" + name: builtins.str + """The name of the event. + This field is semantically required to be set to non-empty string. + """ + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """A collection of attribute key/value pairs on the event. + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + dropped_attributes_count: builtins.int + """The number of dropped attributes. If the value is 0, + then no attributes were dropped. + """ + def __init__( + self, + *, + time_unix_nano: builtins.int = ..., + name: builtins.str = ..., + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + dropped_attributes_count: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "name", b"name", "time_unix_nano", b"time_unix_nano"]) -> None: ... + + @typing_extensions.final + class Link(google.protobuf.message.Message): + """A pointer from the current span to another span in the same trace or in a + different trace. For example, this can be used in batching operations, + where a single batch handler processes multiple requests from different + traces or when the handler receives a request from a different project. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + TRACE_ID_FIELD_NUMBER: builtins.int + SPAN_ID_FIELD_NUMBER: builtins.int + TRACE_STATE_FIELD_NUMBER: builtins.int + ATTRIBUTES_FIELD_NUMBER: builtins.int + DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + trace_id: builtins.bytes + """A unique identifier of a trace that this linked span is part of. The ID is a + 16-byte array. + """ + span_id: builtins.bytes + """A unique identifier for the linked span. The ID is an 8-byte array.""" + trace_state: builtins.str + """The trace_state associated with the link.""" + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """A collection of attribute key/value pairs on the link. + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + dropped_attributes_count: builtins.int + """The number of dropped attributes. If the value is 0, + then no attributes were dropped. + """ + flags: builtins.int + """Flags, a bit field. + + Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace + Context specification. To read the 8-bit W3C trace flag, use + `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. + + See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + + Bits 8 and 9 represent the 3 states of whether the link is remote. + The states are (unknown, is not remote, is remote). + To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. + To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. + + Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. + When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero. + + [Optional]. + """ + def __init__( + self, + *, + trace_id: builtins.bytes = ..., + span_id: builtins.bytes = ..., + trace_state: builtins.str = ..., + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + dropped_attributes_count: builtins.int = ..., + flags: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "flags", b"flags", "span_id", b"span_id", "trace_id", b"trace_id", "trace_state", b"trace_state"]) -> None: ... + + TRACE_ID_FIELD_NUMBER: builtins.int + SPAN_ID_FIELD_NUMBER: builtins.int + TRACE_STATE_FIELD_NUMBER: builtins.int + PARENT_SPAN_ID_FIELD_NUMBER: builtins.int + FLAGS_FIELD_NUMBER: builtins.int + NAME_FIELD_NUMBER: builtins.int + KIND_FIELD_NUMBER: builtins.int + START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + END_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int + ATTRIBUTES_FIELD_NUMBER: builtins.int + DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int + EVENTS_FIELD_NUMBER: builtins.int + DROPPED_EVENTS_COUNT_FIELD_NUMBER: builtins.int + LINKS_FIELD_NUMBER: builtins.int + DROPPED_LINKS_COUNT_FIELD_NUMBER: builtins.int + STATUS_FIELD_NUMBER: builtins.int + trace_id: builtins.bytes + """A unique identifier for a trace. All spans from the same trace share + the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR + of length other than 16 bytes is considered invalid (empty string in OTLP/JSON + is zero-length and thus is also invalid). + + This field is required. + """ + span_id: builtins.bytes + """A unique identifier for a span within a trace, assigned when the span + is created. The ID is an 8-byte array. An ID with all zeroes OR of length + other than 8 bytes is considered invalid (empty string in OTLP/JSON + is zero-length and thus is also invalid). + + This field is required. + """ + trace_state: builtins.str + """trace_state conveys information about request position in multiple distributed tracing graphs. + It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header + See also https://github.com/w3c/distributed-tracing for more details about this field. + """ + parent_span_id: builtins.bytes + """The `span_id` of this span's parent span. If this is a root span, then this + field must be empty. The ID is an 8-byte array. + """ + flags: builtins.int + """Flags, a bit field. + + Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace + Context specification. To read the 8-bit W3C trace flag, use + `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. + + See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. + + Bits 8 and 9 represent the 3 states of whether a span's parent + is remote. The states are (unknown, is not remote, is remote). + To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. + To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. + + When creating span messages, if the message is logically forwarded from another source + with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD + be copied as-is. If creating from a source that does not have an equivalent flags field + (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST + be set to zero. + Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. + + [Optional]. + """ + name: builtins.str + """A description of the span's operation. + + For example, the name can be a qualified method name or a file name + and a line number where the operation is called. A best practice is to use + the same display name at the same call point in an application. + This makes it easier to correlate spans in different traces. + + This field is semantically required to be set to non-empty string. + Empty value is equivalent to an unknown span name. + + This field is required. + """ + kind: global___Span.SpanKind.ValueType + """Distinguishes between spans generated in a particular context. For example, + two spans with the same name may be distinguished using `CLIENT` (caller) + and `SERVER` (callee) to identify queueing latency associated with the span. + """ + start_time_unix_nano: builtins.int + """The start time of the span. On the client side, this is the time + kept by the local machine where the span execution starts. On the server side, this + is the time when the server's application handler starts running. + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + + This field is semantically required and it is expected that end_time >= start_time. + """ + end_time_unix_nano: builtins.int + """The end time of the span. On the client side, this is the time + kept by the local machine where the span execution ends. On the server side, this + is the time when the server application handler stops running. + Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. + + This field is semantically required and it is expected that end_time >= start_time. + """ + @property + def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: + """A collection of key/value pairs. Note, global attributes + like server name can be set using the resource API. Examples of attributes: + + "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" + "/http/server_latency": 300 + "example.com/myattribute": true + "example.com/score": 10.239 + + Attribute keys MUST be unique (it is not allowed to have more than one + attribute with the same key). + The behavior of software that receives duplicated keys can be unpredictable. + """ + dropped_attributes_count: builtins.int + """The number of attributes that were discarded. Attributes + can be discarded because their keys are too long or because there are too many + attributes. If this value is 0, then no attributes were dropped. + """ + @property + def events(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Span.Event]: + """A collection of Event items.""" + dropped_events_count: builtins.int + """The number of dropped events. If the value is 0, then no + events were dropped. + """ + @property + def links(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Span.Link]: + """A collection of Links, which are references from this span to a span + in the same or different trace. + """ + dropped_links_count: builtins.int + """The number of dropped links after the maximum size was + enforced. If this value is 0, then no links were dropped. + """ + @property + def status(self) -> global___Status: + """An optional final status for this span. Semantically when Status isn't set, it means + span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0). + """ + def __init__( + self, + *, + trace_id: builtins.bytes = ..., + span_id: builtins.bytes = ..., + trace_state: builtins.str = ..., + parent_span_id: builtins.bytes = ..., + flags: builtins.int = ..., + name: builtins.str = ..., + kind: global___Span.SpanKind.ValueType = ..., + start_time_unix_nano: builtins.int = ..., + end_time_unix_nano: builtins.int = ..., + attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., + dropped_attributes_count: builtins.int = ..., + events: collections.abc.Iterable[global___Span.Event] | None = ..., + dropped_events_count: builtins.int = ..., + links: collections.abc.Iterable[global___Span.Link] | None = ..., + dropped_links_count: builtins.int = ..., + status: global___Status | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["status", b"status"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "dropped_events_count", b"dropped_events_count", "dropped_links_count", b"dropped_links_count", "end_time_unix_nano", b"end_time_unix_nano", "events", b"events", "flags", b"flags", "kind", b"kind", "links", b"links", "name", b"name", "parent_span_id", b"parent_span_id", "span_id", b"span_id", "start_time_unix_nano", b"start_time_unix_nano", "status", b"status", "trace_id", b"trace_id", "trace_state", b"trace_state"]) -> None: ... + +global___Span = Span + +@typing_extensions.final +class Status(google.protobuf.message.Message): + """The Status type defines a logical error model that is suitable for different + programming environments, including REST APIs and RPC APIs. + """ + + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + class _StatusCode: + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType + + class _StatusCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Status._StatusCode.ValueType], builtins.type): + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor + STATUS_CODE_UNSET: Status._StatusCode.ValueType # 0 + """The default status.""" + STATUS_CODE_OK: Status._StatusCode.ValueType # 1 + """The Span has been validated by an Application developer or Operator to + have completed successfully. + """ + STATUS_CODE_ERROR: Status._StatusCode.ValueType # 2 + """The Span contains an error.""" + + class StatusCode(_StatusCode, metaclass=_StatusCodeEnumTypeWrapper): + """For the semantics of status codes see + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status + """ + + STATUS_CODE_UNSET: Status.StatusCode.ValueType # 0 + """The default status.""" + STATUS_CODE_OK: Status.StatusCode.ValueType # 1 + """The Span has been validated by an Application developer or Operator to + have completed successfully. + """ + STATUS_CODE_ERROR: Status.StatusCode.ValueType # 2 + """The Span contains an error.""" + + MESSAGE_FIELD_NUMBER: builtins.int + CODE_FIELD_NUMBER: builtins.int + message: builtins.str + """A developer-facing human readable error message.""" + code: global___Status.StatusCode.ValueType + """The status code.""" + def __init__( + self, + *, + message: builtins.str = ..., + code: global___Status.StatusCode.ValueType = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["code", b"code", "message", b"message"]) -> None: ... + +global___Status = Status diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py new file mode 100644 index 00000000000..0101c361616 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py new file mode 100644 index 00000000000..af4ed5ad0cb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py @@ -0,0 +1,250 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import abc +import base64 +import collections.abc +import json +import math +import typing + +from opentelemetry.agent._vendor.typing_extensions import Self + +T = typing.TypeVar("T") +M = typing.TypeVar("M", bound="JsonMessage") + + +class JsonMessage(abc.ABC): + """ + Abstract base class for protobuf messages with JSON serialization. + """ + + @abc.abstractmethod + def to_dict(self) -> dict[str, typing.Any]: + """ + Convert this message to a dictionary. + """ + + @classmethod + @abc.abstractmethod + def from_dict(cls: type[M], data: dict[str, typing.Any]) -> M: + """ + Create an instance from a dictionary. + """ + + def to_json(self) -> str: + """ + Serialize this message to a JSON string. + """ + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, data: str | bytes) -> Self: + """ + Deserialize from a JSON string or bytes. + """ + return cls.from_dict(json.loads(data)) + + +def encode_hex(value: bytes | None) -> str: + """ + Encode bytes as hex string. + + Args: + value: The bytes to encode. + Returns: + Hex string representation of the input bytes. + """ + return value.hex() if value else "" + + +def encode_base64(value: bytes | None) -> str: + """ + Encode bytes as base64 string. + Standard Proto3 JSON mapping for bytes. + + Args: + value: The bytes to encode. + Returns: + Base64 string representation of the input bytes. + """ + return base64.b64encode(value).decode("utf-8") if value else "" + + +def encode_int64(value: int) -> str: + """ + Encode 64 bit integers as strings. + Required for int64, uint64, fixed64, sfixed64 and sint64 per Proto3 JSON spec. + + Args: + value: The integer to encode. + Returns: + String representation of the input integer. + """ + return str(value) + + +def encode_float(value: float) -> float | str: + """ + Encode float/double values. + + Args: + value: The float to encode. + Returns: + The input value, or a string for special float values (NaN, Infinity). + """ + if math.isnan(value): + return "NaN" + if math.isinf(value): + return "Infinity" if value > 0 else "-Infinity" + return value + + +def encode_repeated( + values: list[T] | None, + map_fn: collections.abc.Callable[[T], typing.Any], +) -> list[typing.Any]: + """ + Helper to serialize repeated fields with a mapping function. + + Args: + values: The list of values to encode. + map_fn: A function that takes a single value and returns its encoded form. + Returns: + A list of encoded values, or an empty list if input is None or empty. + """ + return [map_fn(v) for v in values] if values else [] + + +def decode_hex(value: str | None, field_name: str) -> bytes: + """ + Decode hex string to bytes. + + Args: + value: The hex string to decode. + field_name: The name of the field being decoded (for error messages). + Returns: + The decoded bytes, or empty bytes if input is None or empty. + """ + if not value: + return b"" + validate_type(value, str, field_name) + try: + return bytes.fromhex(value) + except ValueError as error: + raise ValueError( + f"Invalid hex string for field '{field_name}': {error}" + ) from None + + +def decode_base64(value: str | None, field_name: str) -> bytes: + """ + Decode base64 string to bytes. + + Args: + value: The base64 string to decode. + field_name: The name of the field being decoded (for error messages). + Returns: + The decoded bytes, or empty bytes if input is None or empty. + """ + if not value: + return b"" + validate_type(value, str, field_name) + try: + return base64.b64decode(value) + except Exception as error: + raise ValueError( + f"Invalid base64 string for field '{field_name}': {error}" + ) from None + + +def decode_int64(value: int | str | None, field_name: str) -> int: + """ + Parse int64 from number or string. + + Args: + value: The value to decode, which can be an int, a string, or None + field_name: The name of the field being decoded (for error messages). + Returns: + The decoded integer, or 0 if input is None. + """ + if value is None: + return 0 + validate_type(value, (int, str), field_name) + try: + return int(value) + except (ValueError, TypeError): + raise ValueError( + f"Invalid int64 value for field '{field_name}': {value}" + ) from None + + +def decode_float(value: float | str | None, field_name: str) -> float: + """ + Parse float/double from number or string, handling special values. + + Args: + value: The value to decode, which can be a float, int, string, or None + field_name: The name of the field being decoded (for error messages). + Returns: + The decoded float, or 0.0 if input is None. + """ + if value is None: + return 0.0 + validate_type(value, (float, int, str), field_name) + if value == "NaN": + return math.nan + if value == "Infinity": + return math.inf + if value == "-Infinity": + return -math.inf + try: + return float(value) + except (ValueError, TypeError): + raise ValueError( + f"Invalid float value for field '{field_name}': {value}" + ) from None + + +def decode_repeated( + values: list[typing.Any] | None, + item_parser: collections.abc.Callable[[typing.Any], T], + field_name: str, +) -> list[T]: + """ + Parse a list of values using the provided item parser function. + + Args: + values: The list of values to decode, or None. + item_parser: A function that takes a single value and returns the parsed form. + field_name: The name of the field being decoded (for error messages). + Returns: + A list of parsed values, or an empty list if input is None. + """ + if values is None: + return [] + validate_type(values, list, field_name) + return [item_parser(v) for v in values] + + +def validate_type( + value: typing.Any, + expected_types: type | tuple[type, ...], + field_name: str, +) -> None: + """ + Validate that a value is of the expected type(s). + Raises TypeError if validation fails. + + Args: + value: The value to validate. + expected_types: A type or tuple of types that the value is expected to be. + field_name: The name of the field being validated (for error messages). + """ + if not isinstance(value, expected_types): + raise TypeError( + f"Field '{field_name}' expected {expected_types}, " + f"got {type(value).__name__}" + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py new file mode 100644 index 00000000000..0c751b94871 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py @@ -0,0 +1,148 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/collector/logs/v1/logs_service.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +@_dataclass +class ExportLogsServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportLogsServiceRequest + """ + + resource_logs: builtins.list[opentelemetry.proto_json.logs.v1.logs.ResourceLogs] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_logs: + _result["resourceLogs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_logs, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportLogsServiceRequest: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportLogsServiceRequest instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceLogs")) is not None: + _args["resource_logs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.logs.v1.logs.ResourceLogs.from_dict(_v), "resource_logs") + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportLogsServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportLogsServiceResponse + """ + + partial_success: ExportLogsPartialSuccess | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.partial_success: + _result["partialSuccess"] = self.partial_success.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportLogsServiceResponse: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportLogsServiceResponse instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("partialSuccess")) is not None: + _args["partial_success"] = ExportLogsPartialSuccess.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportLogsPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportLogsPartialSuccess + """ + + rejected_log_records: builtins.int | None = 0 + error_message: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.rejected_log_records: + _result["rejectedLogRecords"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_log_records) + if self.error_message: + _result["errorMessage"] = self.error_message + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportLogsPartialSuccess: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportLogsPartialSuccess instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("rejectedLogRecords")) is not None: + _args["rejected_log_records"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_log_records") + if (_value := data.get("errorMessage")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") + _args["error_message"] = _value + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py new file mode 100644 index 00000000000..b77e752bc46 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py @@ -0,0 +1,148 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/collector/metrics/v1/metrics_service.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +@_dataclass +class ExportMetricsServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportMetricsServiceRequest + """ + + resource_metrics: builtins.list[opentelemetry.proto_json.metrics.v1.metrics.ResourceMetrics] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_metrics: + _result["resourceMetrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_metrics, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportMetricsServiceRequest: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportMetricsServiceRequest instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceMetrics")) is not None: + _args["resource_metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.metrics.v1.metrics.ResourceMetrics.from_dict(_v), "resource_metrics") + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportMetricsServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportMetricsServiceResponse + """ + + partial_success: ExportMetricsPartialSuccess | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.partial_success: + _result["partialSuccess"] = self.partial_success.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportMetricsServiceResponse: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportMetricsServiceResponse instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("partialSuccess")) is not None: + _args["partial_success"] = ExportMetricsPartialSuccess.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportMetricsPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportMetricsPartialSuccess + """ + + rejected_data_points: builtins.int | None = 0 + error_message: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.rejected_data_points: + _result["rejectedDataPoints"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_data_points) + if self.error_message: + _result["errorMessage"] = self.error_message + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportMetricsPartialSuccess: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportMetricsPartialSuccess instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("rejectedDataPoints")) is not None: + _args["rejected_data_points"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_data_points") + if (_value := data.get("errorMessage")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") + _args["error_message"] = _value + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py new file mode 100644 index 00000000000..80e88874693 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py @@ -0,0 +1,153 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/collector/profiles/v1development/profiles_service.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.profiles.v1development.profiles +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +@_dataclass +class ExportProfilesServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportProfilesServiceRequest + """ + + resource_profiles: builtins.list[opentelemetry.proto_json.profiles.v1development.profiles.ResourceProfiles] = dataclasses.field(default_factory=builtins.list) + dictionary: opentelemetry.proto_json.profiles.v1development.profiles.ProfilesDictionary | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_profiles: + _result["resourceProfiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_profiles, lambda _v: _v.to_dict()) + if self.dictionary: + _result["dictionary"] = self.dictionary.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportProfilesServiceRequest: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportProfilesServiceRequest instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceProfiles")) is not None: + _args["resource_profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.profiles.v1development.profiles.ResourceProfiles.from_dict(_v), "resource_profiles") + if (_value := data.get("dictionary")) is not None: + _args["dictionary"] = opentelemetry.proto_json.profiles.v1development.profiles.ProfilesDictionary.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportProfilesServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportProfilesServiceResponse + """ + + partial_success: ExportProfilesPartialSuccess | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.partial_success: + _result["partialSuccess"] = self.partial_success.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportProfilesServiceResponse: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportProfilesServiceResponse instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("partialSuccess")) is not None: + _args["partial_success"] = ExportProfilesPartialSuccess.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportProfilesPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportProfilesPartialSuccess + """ + + rejected_profiles: builtins.int | None = 0 + error_message: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.rejected_profiles: + _result["rejectedProfiles"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_profiles) + if self.error_message: + _result["errorMessage"] = self.error_message + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportProfilesPartialSuccess: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportProfilesPartialSuccess instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("rejectedProfiles")) is not None: + _args["rejected_profiles"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_profiles") + if (_value := data.get("errorMessage")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") + _args["error_message"] = _value + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py new file mode 100644 index 00000000000..7043becb62a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py @@ -0,0 +1,148 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/collector/trace/v1/trace_service.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +@_dataclass +class ExportTraceServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportTraceServiceRequest + """ + + resource_spans: builtins.list[opentelemetry.proto_json.trace.v1.trace.ResourceSpans] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_spans: + _result["resourceSpans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_spans, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportTraceServiceRequest: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportTraceServiceRequest instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceSpans")) is not None: + _args["resource_spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.trace.v1.trace.ResourceSpans.from_dict(_v), "resource_spans") + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportTraceServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportTraceServiceResponse + """ + + partial_success: ExportTracePartialSuccess | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.partial_success: + _result["partialSuccess"] = self.partial_success.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportTraceServiceResponse: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportTraceServiceResponse instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("partialSuccess")) is not None: + _args["partial_success"] = ExportTracePartialSuccess.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class ExportTracePartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExportTracePartialSuccess + """ + + rejected_spans: builtins.int | None = 0 + error_message: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.rejected_spans: + _result["rejectedSpans"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_spans) + if self.error_message: + _result["errorMessage"] = self.error_message + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportTracePartialSuccess: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExportTracePartialSuccess instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("rejectedSpans")) is not None: + _args["rejected_spans"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_spans") + if (_value := data.get("errorMessage")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") + _args["error_message"] = _value + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py new file mode 100644 index 00000000000..0dce42472c4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py @@ -0,0 +1,348 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/common/v1/common.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +@_dataclass +class AnyValue(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message AnyValue + """ + + string_value: builtins.str | None = None + bool_value: builtins.bool | None = None + int_value: builtins.int | None = None + double_value: builtins.float | None = None + array_value: ArrayValue | None = None + kvlist_value: KeyValueList | None = None + bytes_value: builtins.bytes | None = None + string_value_strindex: builtins.int | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.string_value_strindex is not None: + _result["stringValueStrindex"] = self.string_value_strindex + elif self.bytes_value is not None: + _result["bytesValue"] = opentelemetry.proto_json._json_codec.encode_base64(self.bytes_value) + elif self.kvlist_value is not None: + _result["kvlistValue"] = self.kvlist_value.to_dict() + elif self.array_value is not None: + _result["arrayValue"] = self.array_value.to_dict() + elif self.double_value is not None: + _result["doubleValue"] = opentelemetry.proto_json._json_codec.encode_float(self.double_value) + elif self.int_value is not None: + _result["intValue"] = opentelemetry.proto_json._json_codec.encode_int64(self.int_value) + elif self.bool_value is not None: + _result["boolValue"] = self.bool_value + elif self.string_value is not None: + _result["stringValue"] = self.string_value + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> AnyValue: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + AnyValue instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("stringValueStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "string_value_strindex") + _args["string_value_strindex"] = _value + elif (_value := data.get("bytesValue")) is not None: + _args["bytes_value"] = opentelemetry.proto_json._json_codec.decode_base64(_value, "bytes_value") + elif (_value := data.get("kvlistValue")) is not None: + _args["kvlist_value"] = KeyValueList.from_dict(_value) + elif (_value := data.get("arrayValue")) is not None: + _args["array_value"] = ArrayValue.from_dict(_value) + elif (_value := data.get("doubleValue")) is not None: + _args["double_value"] = opentelemetry.proto_json._json_codec.decode_float(_value, "double_value") + elif (_value := data.get("intValue")) is not None: + _args["int_value"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "int_value") + elif (_value := data.get("boolValue")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.bool, "bool_value") + _args["bool_value"] = _value + elif (_value := data.get("stringValue")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "string_value") + _args["string_value"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class ArrayValue(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ArrayValue + """ + + values: builtins.list[AnyValue] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.values: + _result["values"] = opentelemetry.proto_json._json_codec.encode_repeated(self.values, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ArrayValue: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ArrayValue instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("values")) is not None: + _args["values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: AnyValue.from_dict(_v), "values") + + return cls(**_args) + + +@typing.final +@_dataclass +class KeyValueList(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message KeyValueList + """ + + values: builtins.list[KeyValue] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.values: + _result["values"] = opentelemetry.proto_json._json_codec.encode_repeated(self.values, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> KeyValueList: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + KeyValueList instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("values")) is not None: + _args["values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: KeyValue.from_dict(_v), "values") + + return cls(**_args) + + +@typing.final +@_dataclass +class KeyValue(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message KeyValue + """ + + key: builtins.str | None = "" + value: AnyValue | None = None + key_strindex: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.key: + _result["key"] = self.key + if self.value: + _result["value"] = self.value.to_dict() + if self.key_strindex: + _result["keyStrindex"] = self.key_strindex + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> KeyValue: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + KeyValue instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("key")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "key") + _args["key"] = _value + if (_value := data.get("value")) is not None: + _args["value"] = AnyValue.from_dict(_value) + if (_value := data.get("keyStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "key_strindex") + _args["key_strindex"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class InstrumentationScope(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message InstrumentationScope + """ + + name: builtins.str | None = "" + version: builtins.str | None = "" + attributes: builtins.list[KeyValue] = dataclasses.field(default_factory=builtins.list) + dropped_attributes_count: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.name: + _result["name"] = self.name + if self.version: + _result["version"] = self.version + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.dropped_attributes_count: + _result["droppedAttributesCount"] = self.dropped_attributes_count + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> InstrumentationScope: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + InstrumentationScope instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("name")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") + _args["name"] = _value + if (_value := data.get("version")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "version") + _args["version"] = _value + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: KeyValue.from_dict(_v), "attributes") + if (_value := data.get("droppedAttributesCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") + _args["dropped_attributes_count"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class EntityRef(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message EntityRef + """ + + schema_url: builtins.str | None = "" + type: builtins.str | None = "" + id_keys: builtins.list[builtins.str] = dataclasses.field(default_factory=builtins.list) + description_keys: builtins.list[builtins.str] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.schema_url: + _result["schemaUrl"] = self.schema_url + if self.type: + _result["type"] = self.type + if self.id_keys: + _result["idKeys"] = self.id_keys + if self.description_keys: + _result["descriptionKeys"] = self.description_keys + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> EntityRef: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + EntityRef instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + if (_value := data.get("type")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "type") + _args["type"] = _value + if (_value := data.get("idKeys")) is not None: + _args["id_keys"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "id_keys") + if (_value := data.get("descriptionKeys")) is not None: + _args["description_keys"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "description_keys") + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py new file mode 100644 index 00000000000..cd874620a2b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py @@ -0,0 +1,304 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/logs/v1/logs.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import enum +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +class SeverityNumber(enum.IntEnum): + """ + Generated from protobuf enum SeverityNumber + """ + + SEVERITY_NUMBER_UNSPECIFIED = 0 + SEVERITY_NUMBER_TRACE = 1 + SEVERITY_NUMBER_TRACE2 = 2 + SEVERITY_NUMBER_TRACE3 = 3 + SEVERITY_NUMBER_TRACE4 = 4 + SEVERITY_NUMBER_DEBUG = 5 + SEVERITY_NUMBER_DEBUG2 = 6 + SEVERITY_NUMBER_DEBUG3 = 7 + SEVERITY_NUMBER_DEBUG4 = 8 + SEVERITY_NUMBER_INFO = 9 + SEVERITY_NUMBER_INFO2 = 10 + SEVERITY_NUMBER_INFO3 = 11 + SEVERITY_NUMBER_INFO4 = 12 + SEVERITY_NUMBER_WARN = 13 + SEVERITY_NUMBER_WARN2 = 14 + SEVERITY_NUMBER_WARN3 = 15 + SEVERITY_NUMBER_WARN4 = 16 + SEVERITY_NUMBER_ERROR = 17 + SEVERITY_NUMBER_ERROR2 = 18 + SEVERITY_NUMBER_ERROR3 = 19 + SEVERITY_NUMBER_ERROR4 = 20 + SEVERITY_NUMBER_FATAL = 21 + SEVERITY_NUMBER_FATAL2 = 22 + SEVERITY_NUMBER_FATAL3 = 23 + SEVERITY_NUMBER_FATAL4 = 24 + +@typing.final +class LogRecordFlags(enum.IntEnum): + """ + Generated from protobuf enum LogRecordFlags + """ + + LOG_RECORD_FLAGS_DO_NOT_USE = 0 + LOG_RECORD_FLAGS_TRACE_FLAGS_MASK = 255 + +@typing.final +@_dataclass +class LogsData(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message LogsData + """ + + resource_logs: builtins.list[ResourceLogs] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_logs: + _result["resourceLogs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_logs, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> LogsData: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + LogsData instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceLogs")) is not None: + _args["resource_logs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceLogs.from_dict(_v), "resource_logs") + + return cls(**_args) + + +@typing.final +@_dataclass +class ResourceLogs(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ResourceLogs + """ + + resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None + scope_logs: builtins.list[ScopeLogs] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource: + _result["resource"] = self.resource.to_dict() + if self.scope_logs: + _result["scopeLogs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_logs, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceLogs: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ResourceLogs instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resource")) is not None: + _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) + if (_value := data.get("scopeLogs")) is not None: + _args["scope_logs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeLogs.from_dict(_v), "scope_logs") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class ScopeLogs(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ScopeLogs + """ + + scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None + log_records: builtins.list[LogRecord] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.scope: + _result["scope"] = self.scope.to_dict() + if self.log_records: + _result["logRecords"] = opentelemetry.proto_json._json_codec.encode_repeated(self.log_records, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeLogs: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ScopeLogs instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("scope")) is not None: + _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) + if (_value := data.get("logRecords")) is not None: + _args["log_records"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: LogRecord.from_dict(_v), "log_records") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class LogRecord(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message LogRecord + """ + + time_unix_nano: builtins.int | None = 0 + observed_time_unix_nano: builtins.int | None = 0 + severity_number: SeverityNumber | builtins.int | None = 0 + severity_text: builtins.str | None = "" + body: opentelemetry.proto_json.common.v1.common.AnyValue | None = None + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + dropped_attributes_count: builtins.int | None = 0 + flags: builtins.int | None = 0 + trace_id: builtins.bytes | None = b"" + span_id: builtins.bytes | None = b"" + event_name: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.observed_time_unix_nano: + _result["observedTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.observed_time_unix_nano) + if self.severity_number: + _result["severityNumber"] = builtins.int(self.severity_number) + if self.severity_text: + _result["severityText"] = self.severity_text + if self.body: + _result["body"] = self.body.to_dict() + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.dropped_attributes_count: + _result["droppedAttributesCount"] = self.dropped_attributes_count + if self.flags: + _result["flags"] = self.flags + if self.trace_id: + _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) + if self.span_id: + _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) + if self.event_name: + _result["eventName"] = self.event_name + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> LogRecord: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + LogRecord instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("observedTimeUnixNano")) is not None: + _args["observed_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "observed_time_unix_nano") + if (_value := data.get("severityNumber")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "severity_number") + _args["severity_number"] = SeverityNumber(_value) + if (_value := data.get("severityText")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "severity_text") + _args["severity_text"] = _value + if (_value := data.get("body")) is not None: + _args["body"] = opentelemetry.proto_json.common.v1.common.AnyValue.from_dict(_value) + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("droppedAttributesCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") + _args["dropped_attributes_count"] = _value + if (_value := data.get("flags")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") + _args["flags"] = _value + if (_value := data.get("traceId")) is not None: + _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") + if (_value := data.get("spanId")) is not None: + _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") + if (_value := data.get("eventName")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "event_name") + _args["event_name"] = _value + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py new file mode 100644 index 00000000000..741794ceccb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py @@ -0,0 +1,1000 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/metrics/v1/metrics.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import enum +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +class AggregationTemporality(enum.IntEnum): + """ + Generated from protobuf enum AggregationTemporality + """ + + AGGREGATION_TEMPORALITY_UNSPECIFIED = 0 + AGGREGATION_TEMPORALITY_DELTA = 1 + AGGREGATION_TEMPORALITY_CUMULATIVE = 2 + +@typing.final +class DataPointFlags(enum.IntEnum): + """ + Generated from protobuf enum DataPointFlags + """ + + DATA_POINT_FLAGS_DO_NOT_USE = 0 + DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK = 1 + +@typing.final +@_dataclass +class MetricsData(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message MetricsData + """ + + resource_metrics: builtins.list[ResourceMetrics] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_metrics: + _result["resourceMetrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_metrics, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> MetricsData: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + MetricsData instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceMetrics")) is not None: + _args["resource_metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceMetrics.from_dict(_v), "resource_metrics") + + return cls(**_args) + + +@typing.final +@_dataclass +class ResourceMetrics(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ResourceMetrics + """ + + resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None + scope_metrics: builtins.list[ScopeMetrics] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource: + _result["resource"] = self.resource.to_dict() + if self.scope_metrics: + _result["scopeMetrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_metrics, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceMetrics: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ResourceMetrics instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resource")) is not None: + _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) + if (_value := data.get("scopeMetrics")) is not None: + _args["scope_metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeMetrics.from_dict(_v), "scope_metrics") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class ScopeMetrics(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ScopeMetrics + """ + + scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None + metrics: builtins.list[Metric] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.scope: + _result["scope"] = self.scope.to_dict() + if self.metrics: + _result["metrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.metrics, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeMetrics: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ScopeMetrics instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("scope")) is not None: + _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) + if (_value := data.get("metrics")) is not None: + _args["metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Metric.from_dict(_v), "metrics") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class Metric(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Metric + """ + + name: builtins.str | None = "" + description: builtins.str | None = "" + unit: builtins.str | None = "" + gauge: Gauge | None = None + sum: Sum | None = None + histogram: Histogram | None = None + exponential_histogram: ExponentialHistogram | None = None + summary: Summary | None = None + metadata: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.name: + _result["name"] = self.name + if self.description: + _result["description"] = self.description + if self.unit: + _result["unit"] = self.unit + if self.metadata: + _result["metadata"] = opentelemetry.proto_json._json_codec.encode_repeated(self.metadata, lambda _v: _v.to_dict()) + if self.summary is not None: + _result["summary"] = self.summary.to_dict() + elif self.exponential_histogram is not None: + _result["exponentialHistogram"] = self.exponential_histogram.to_dict() + elif self.histogram is not None: + _result["histogram"] = self.histogram.to_dict() + elif self.sum is not None: + _result["sum"] = self.sum.to_dict() + elif self.gauge is not None: + _result["gauge"] = self.gauge.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Metric: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Metric instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("name")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") + _args["name"] = _value + if (_value := data.get("description")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "description") + _args["description"] = _value + if (_value := data.get("unit")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "unit") + _args["unit"] = _value + if (_value := data.get("metadata")) is not None: + _args["metadata"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "metadata") + if (_value := data.get("summary")) is not None: + _args["summary"] = Summary.from_dict(_value) + elif (_value := data.get("exponentialHistogram")) is not None: + _args["exponential_histogram"] = ExponentialHistogram.from_dict(_value) + elif (_value := data.get("histogram")) is not None: + _args["histogram"] = Histogram.from_dict(_value) + elif (_value := data.get("sum")) is not None: + _args["sum"] = Sum.from_dict(_value) + elif (_value := data.get("gauge")) is not None: + _args["gauge"] = Gauge.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class Gauge(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Gauge + """ + + data_points: builtins.list[NumberDataPoint] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.data_points: + _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Gauge: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Gauge instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("dataPoints")) is not None: + _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: NumberDataPoint.from_dict(_v), "data_points") + + return cls(**_args) + + +@typing.final +@_dataclass +class Sum(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Sum + """ + + data_points: builtins.list[NumberDataPoint] = dataclasses.field(default_factory=builtins.list) + aggregation_temporality: AggregationTemporality | builtins.int | None = 0 + is_monotonic: builtins.bool | None = False + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.data_points: + _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) + if self.aggregation_temporality: + _result["aggregationTemporality"] = builtins.int(self.aggregation_temporality) + if self.is_monotonic: + _result["isMonotonic"] = self.is_monotonic + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Sum: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Sum instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("dataPoints")) is not None: + _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: NumberDataPoint.from_dict(_v), "data_points") + if (_value := data.get("aggregationTemporality")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") + _args["aggregation_temporality"] = AggregationTemporality(_value) + if (_value := data.get("isMonotonic")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.bool, "is_monotonic") + _args["is_monotonic"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class Histogram(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Histogram + """ + + data_points: builtins.list[HistogramDataPoint] = dataclasses.field(default_factory=builtins.list) + aggregation_temporality: AggregationTemporality | builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.data_points: + _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) + if self.aggregation_temporality: + _result["aggregationTemporality"] = builtins.int(self.aggregation_temporality) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Histogram: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Histogram instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("dataPoints")) is not None: + _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: HistogramDataPoint.from_dict(_v), "data_points") + if (_value := data.get("aggregationTemporality")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") + _args["aggregation_temporality"] = AggregationTemporality(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class ExponentialHistogram(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExponentialHistogram + """ + + data_points: builtins.list[ExponentialHistogramDataPoint] = dataclasses.field(default_factory=builtins.list) + aggregation_temporality: AggregationTemporality | builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.data_points: + _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) + if self.aggregation_temporality: + _result["aggregationTemporality"] = builtins.int(self.aggregation_temporality) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExponentialHistogram: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExponentialHistogram instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("dataPoints")) is not None: + _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ExponentialHistogramDataPoint.from_dict(_v), "data_points") + if (_value := data.get("aggregationTemporality")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") + _args["aggregation_temporality"] = AggregationTemporality(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class Summary(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Summary + """ + + data_points: builtins.list[SummaryDataPoint] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.data_points: + _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Summary: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Summary instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("dataPoints")) is not None: + _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: SummaryDataPoint.from_dict(_v), "data_points") + + return cls(**_args) + + +@typing.final +@_dataclass +class NumberDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message NumberDataPoint + """ + + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + start_time_unix_nano: builtins.int | None = 0 + time_unix_nano: builtins.int | None = 0 + as_double: builtins.float | None = None + as_int: builtins.int | None = None + exemplars: builtins.list[Exemplar] = dataclasses.field(default_factory=builtins.list) + flags: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.start_time_unix_nano: + _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.exemplars: + _result["exemplars"] = opentelemetry.proto_json._json_codec.encode_repeated(self.exemplars, lambda _v: _v.to_dict()) + if self.flags: + _result["flags"] = self.flags + if self.as_int is not None: + _result["asInt"] = opentelemetry.proto_json._json_codec.encode_int64(self.as_int) + elif self.as_double is not None: + _result["asDouble"] = opentelemetry.proto_json._json_codec.encode_float(self.as_double) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> NumberDataPoint: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + NumberDataPoint instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("startTimeUnixNano")) is not None: + _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("exemplars")) is not None: + _args["exemplars"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Exemplar.from_dict(_v), "exemplars") + if (_value := data.get("flags")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") + _args["flags"] = _value + if (_value := data.get("asInt")) is not None: + _args["as_int"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "as_int") + elif (_value := data.get("asDouble")) is not None: + _args["as_double"] = opentelemetry.proto_json._json_codec.decode_float(_value, "as_double") + + return cls(**_args) + + +@typing.final +@_dataclass +class HistogramDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message HistogramDataPoint + """ + + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + start_time_unix_nano: builtins.int | None = 0 + time_unix_nano: builtins.int | None = 0 + count: builtins.int | None = 0 + sum: builtins.float | None = None + bucket_counts: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + explicit_bounds: builtins.list[builtins.float] = dataclasses.field(default_factory=builtins.list) + exemplars: builtins.list[Exemplar] = dataclasses.field(default_factory=builtins.list) + flags: builtins.int | None = 0 + min: builtins.float | None = None + max: builtins.float | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.start_time_unix_nano: + _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.count: + _result["count"] = opentelemetry.proto_json._json_codec.encode_int64(self.count) + if self.sum is not None: + _result["sum"] = opentelemetry.proto_json._json_codec.encode_float(self.sum) + if self.bucket_counts: + _result["bucketCounts"] = opentelemetry.proto_json._json_codec.encode_repeated(self.bucket_counts, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) + if self.explicit_bounds: + _result["explicitBounds"] = opentelemetry.proto_json._json_codec.encode_repeated(self.explicit_bounds, lambda _v: opentelemetry.proto_json._json_codec.encode_float(_v)) + if self.exemplars: + _result["exemplars"] = opentelemetry.proto_json._json_codec.encode_repeated(self.exemplars, lambda _v: _v.to_dict()) + if self.flags: + _result["flags"] = self.flags + if self.min is not None: + _result["min"] = opentelemetry.proto_json._json_codec.encode_float(self.min) + if self.max is not None: + _result["max"] = opentelemetry.proto_json._json_codec.encode_float(self.max) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> HistogramDataPoint: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + HistogramDataPoint instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("startTimeUnixNano")) is not None: + _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("count")) is not None: + _args["count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "count") + if (_value := data.get("sum")) is not None: + _args["sum"] = opentelemetry.proto_json._json_codec.decode_float(_value, "sum") + if (_value := data.get("bucketCounts")) is not None: + _args["bucket_counts"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "bucket_counts"), "bucket_counts") + if (_value := data.get("explicitBounds")) is not None: + _args["explicit_bounds"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_float(_v, "explicit_bounds"), "explicit_bounds") + if (_value := data.get("exemplars")) is not None: + _args["exemplars"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Exemplar.from_dict(_v), "exemplars") + if (_value := data.get("flags")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") + _args["flags"] = _value + if (_value := data.get("min")) is not None: + _args["min"] = opentelemetry.proto_json._json_codec.decode_float(_value, "min") + if (_value := data.get("max")) is not None: + _args["max"] = opentelemetry.proto_json._json_codec.decode_float(_value, "max") + + return cls(**_args) + + +@typing.final +@_dataclass +class ExponentialHistogramDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ExponentialHistogramDataPoint + """ + + @typing.final + @_dataclass + class Buckets(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Buckets + """ + + offset: builtins.int | None = 0 + bucket_counts: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.offset: + _result["offset"] = self.offset + if self.bucket_counts: + _result["bucketCounts"] = opentelemetry.proto_json._json_codec.encode_repeated(self.bucket_counts, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExponentialHistogramDataPoint.Buckets: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Buckets instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("offset")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "offset") + _args["offset"] = _value + if (_value := data.get("bucketCounts")) is not None: + _args["bucket_counts"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "bucket_counts"), "bucket_counts") + + return cls(**_args) + + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + start_time_unix_nano: builtins.int | None = 0 + time_unix_nano: builtins.int | None = 0 + count: builtins.int | None = 0 + sum: builtins.float | None = None + scale: builtins.int | None = 0 + zero_count: builtins.int | None = 0 + positive: ExponentialHistogramDataPoint.Buckets | None = None + negative: ExponentialHistogramDataPoint.Buckets | None = None + flags: builtins.int | None = 0 + exemplars: builtins.list[Exemplar] = dataclasses.field(default_factory=builtins.list) + min: builtins.float | None = None + max: builtins.float | None = None + zero_threshold: builtins.float | None = 0.0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.start_time_unix_nano: + _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.count: + _result["count"] = opentelemetry.proto_json._json_codec.encode_int64(self.count) + if self.sum is not None: + _result["sum"] = opentelemetry.proto_json._json_codec.encode_float(self.sum) + if self.scale: + _result["scale"] = self.scale + if self.zero_count: + _result["zeroCount"] = opentelemetry.proto_json._json_codec.encode_int64(self.zero_count) + if self.positive: + _result["positive"] = self.positive.to_dict() + if self.negative: + _result["negative"] = self.negative.to_dict() + if self.flags: + _result["flags"] = self.flags + if self.exemplars: + _result["exemplars"] = opentelemetry.proto_json._json_codec.encode_repeated(self.exemplars, lambda _v: _v.to_dict()) + if self.min is not None: + _result["min"] = opentelemetry.proto_json._json_codec.encode_float(self.min) + if self.max is not None: + _result["max"] = opentelemetry.proto_json._json_codec.encode_float(self.max) + if self.zero_threshold: + _result["zeroThreshold"] = opentelemetry.proto_json._json_codec.encode_float(self.zero_threshold) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExponentialHistogramDataPoint: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ExponentialHistogramDataPoint instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("startTimeUnixNano")) is not None: + _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("count")) is not None: + _args["count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "count") + if (_value := data.get("sum")) is not None: + _args["sum"] = opentelemetry.proto_json._json_codec.decode_float(_value, "sum") + if (_value := data.get("scale")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "scale") + _args["scale"] = _value + if (_value := data.get("zeroCount")) is not None: + _args["zero_count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "zero_count") + if (_value := data.get("positive")) is not None: + _args["positive"] = ExponentialHistogramDataPoint.Buckets.from_dict(_value) + if (_value := data.get("negative")) is not None: + _args["negative"] = ExponentialHistogramDataPoint.Buckets.from_dict(_value) + if (_value := data.get("flags")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") + _args["flags"] = _value + if (_value := data.get("exemplars")) is not None: + _args["exemplars"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Exemplar.from_dict(_v), "exemplars") + if (_value := data.get("min")) is not None: + _args["min"] = opentelemetry.proto_json._json_codec.decode_float(_value, "min") + if (_value := data.get("max")) is not None: + _args["max"] = opentelemetry.proto_json._json_codec.decode_float(_value, "max") + if (_value := data.get("zeroThreshold")) is not None: + _args["zero_threshold"] = opentelemetry.proto_json._json_codec.decode_float(_value, "zero_threshold") + + return cls(**_args) + + +@typing.final +@_dataclass +class SummaryDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message SummaryDataPoint + """ + + @typing.final + @_dataclass + class ValueAtQuantile(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ValueAtQuantile + """ + + quantile: builtins.float | None = 0.0 + value: builtins.float | None = 0.0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.quantile: + _result["quantile"] = opentelemetry.proto_json._json_codec.encode_float(self.quantile) + if self.value: + _result["value"] = opentelemetry.proto_json._json_codec.encode_float(self.value) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> SummaryDataPoint.ValueAtQuantile: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ValueAtQuantile instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("quantile")) is not None: + _args["quantile"] = opentelemetry.proto_json._json_codec.decode_float(_value, "quantile") + if (_value := data.get("value")) is not None: + _args["value"] = opentelemetry.proto_json._json_codec.decode_float(_value, "value") + + return cls(**_args) + + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + start_time_unix_nano: builtins.int | None = 0 + time_unix_nano: builtins.int | None = 0 + count: builtins.int | None = 0 + sum: builtins.float | None = 0.0 + quantile_values: builtins.list[SummaryDataPoint.ValueAtQuantile] = dataclasses.field(default_factory=builtins.list) + flags: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.start_time_unix_nano: + _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.count: + _result["count"] = opentelemetry.proto_json._json_codec.encode_int64(self.count) + if self.sum: + _result["sum"] = opentelemetry.proto_json._json_codec.encode_float(self.sum) + if self.quantile_values: + _result["quantileValues"] = opentelemetry.proto_json._json_codec.encode_repeated(self.quantile_values, lambda _v: _v.to_dict()) + if self.flags: + _result["flags"] = self.flags + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> SummaryDataPoint: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + SummaryDataPoint instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("startTimeUnixNano")) is not None: + _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("count")) is not None: + _args["count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "count") + if (_value := data.get("sum")) is not None: + _args["sum"] = opentelemetry.proto_json._json_codec.decode_float(_value, "sum") + if (_value := data.get("quantileValues")) is not None: + _args["quantile_values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: SummaryDataPoint.ValueAtQuantile.from_dict(_v), "quantile_values") + if (_value := data.get("flags")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") + _args["flags"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class Exemplar(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Exemplar + """ + + filtered_attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + time_unix_nano: builtins.int | None = 0 + as_double: builtins.float | None = None + as_int: builtins.int | None = None + span_id: builtins.bytes | None = b"" + trace_id: builtins.bytes | None = b"" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.filtered_attributes: + _result["filteredAttributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.filtered_attributes, lambda _v: _v.to_dict()) + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.span_id: + _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) + if self.trace_id: + _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) + if self.as_int is not None: + _result["asInt"] = opentelemetry.proto_json._json_codec.encode_int64(self.as_int) + elif self.as_double is not None: + _result["asDouble"] = opentelemetry.proto_json._json_codec.encode_float(self.as_double) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Exemplar: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Exemplar instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("filteredAttributes")) is not None: + _args["filtered_attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "filtered_attributes") + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("spanId")) is not None: + _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") + if (_value := data.get("traceId")) is not None: + _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") + if (_value := data.get("asInt")) is not None: + _args["as_int"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "as_int") + elif (_value := data.get("asDouble")) is not None: + _args["as_double"] = opentelemetry.proto_json._json_codec.decode_float(_value, "as_double") + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py new file mode 100644 index 00000000000..cf5e4f1a7bb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py @@ -0,0 +1,816 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/profiles/v1development/profiles.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +@_dataclass +class ProfilesDictionary(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ProfilesDictionary + """ + + mapping_table: builtins.list[Mapping] = dataclasses.field(default_factory=builtins.list) + location_table: builtins.list[Location] = dataclasses.field(default_factory=builtins.list) + function_table: builtins.list[Function] = dataclasses.field(default_factory=builtins.list) + link_table: builtins.list[Link] = dataclasses.field(default_factory=builtins.list) + string_table: builtins.list[builtins.str] = dataclasses.field(default_factory=builtins.list) + attribute_table: builtins.list[KeyValueAndUnit] = dataclasses.field(default_factory=builtins.list) + stack_table: builtins.list[Stack] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.mapping_table: + _result["mappingTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.mapping_table, lambda _v: _v.to_dict()) + if self.location_table: + _result["locationTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.location_table, lambda _v: _v.to_dict()) + if self.function_table: + _result["functionTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.function_table, lambda _v: _v.to_dict()) + if self.link_table: + _result["linkTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.link_table, lambda _v: _v.to_dict()) + if self.string_table: + _result["stringTable"] = self.string_table + if self.attribute_table: + _result["attributeTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attribute_table, lambda _v: _v.to_dict()) + if self.stack_table: + _result["stackTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.stack_table, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ProfilesDictionary: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ProfilesDictionary instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("mappingTable")) is not None: + _args["mapping_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Mapping.from_dict(_v), "mapping_table") + if (_value := data.get("locationTable")) is not None: + _args["location_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Location.from_dict(_v), "location_table") + if (_value := data.get("functionTable")) is not None: + _args["function_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Function.from_dict(_v), "function_table") + if (_value := data.get("linkTable")) is not None: + _args["link_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Link.from_dict(_v), "link_table") + if (_value := data.get("stringTable")) is not None: + _args["string_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "string_table") + if (_value := data.get("attributeTable")) is not None: + _args["attribute_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: KeyValueAndUnit.from_dict(_v), "attribute_table") + if (_value := data.get("stackTable")) is not None: + _args["stack_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Stack.from_dict(_v), "stack_table") + + return cls(**_args) + + +@typing.final +@_dataclass +class ProfilesData(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ProfilesData + """ + + resource_profiles: builtins.list[ResourceProfiles] = dataclasses.field(default_factory=builtins.list) + dictionary: ProfilesDictionary | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_profiles: + _result["resourceProfiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_profiles, lambda _v: _v.to_dict()) + if self.dictionary: + _result["dictionary"] = self.dictionary.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ProfilesData: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ProfilesData instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceProfiles")) is not None: + _args["resource_profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceProfiles.from_dict(_v), "resource_profiles") + if (_value := data.get("dictionary")) is not None: + _args["dictionary"] = ProfilesDictionary.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class ResourceProfiles(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ResourceProfiles + """ + + resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None + scope_profiles: builtins.list[ScopeProfiles] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource: + _result["resource"] = self.resource.to_dict() + if self.scope_profiles: + _result["scopeProfiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_profiles, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceProfiles: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ResourceProfiles instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resource")) is not None: + _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) + if (_value := data.get("scopeProfiles")) is not None: + _args["scope_profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeProfiles.from_dict(_v), "scope_profiles") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class ScopeProfiles(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ScopeProfiles + """ + + scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None + profiles: builtins.list[Profile] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.scope: + _result["scope"] = self.scope.to_dict() + if self.profiles: + _result["profiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.profiles, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeProfiles: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ScopeProfiles instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("scope")) is not None: + _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) + if (_value := data.get("profiles")) is not None: + _args["profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Profile.from_dict(_v), "profiles") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class Profile(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Profile + """ + + sample_type: ValueType | None = None + samples: builtins.list[Sample] = dataclasses.field(default_factory=builtins.list) + time_unix_nano: builtins.int | None = 0 + duration_nano: builtins.int | None = 0 + period_type: ValueType | None = None + period: builtins.int | None = 0 + profile_id: builtins.bytes | None = b"" + dropped_attributes_count: builtins.int | None = 0 + original_payload_format: builtins.str | None = "" + original_payload: builtins.bytes | None = b"" + attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.sample_type: + _result["sampleType"] = self.sample_type.to_dict() + if self.samples: + _result["samples"] = opentelemetry.proto_json._json_codec.encode_repeated(self.samples, lambda _v: _v.to_dict()) + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.duration_nano: + _result["durationNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.duration_nano) + if self.period_type: + _result["periodType"] = self.period_type.to_dict() + if self.period: + _result["period"] = opentelemetry.proto_json._json_codec.encode_int64(self.period) + if self.profile_id: + _result["profileId"] = opentelemetry.proto_json._json_codec.encode_base64(self.profile_id) + if self.dropped_attributes_count: + _result["droppedAttributesCount"] = self.dropped_attributes_count + if self.original_payload_format: + _result["originalPayloadFormat"] = self.original_payload_format + if self.original_payload: + _result["originalPayload"] = opentelemetry.proto_json._json_codec.encode_base64(self.original_payload) + if self.attribute_indices: + _result["attributeIndices"] = self.attribute_indices + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Profile: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Profile instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("sampleType")) is not None: + _args["sample_type"] = ValueType.from_dict(_value) + if (_value := data.get("samples")) is not None: + _args["samples"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Sample.from_dict(_v), "samples") + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("durationNano")) is not None: + _args["duration_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "duration_nano") + if (_value := data.get("periodType")) is not None: + _args["period_type"] = ValueType.from_dict(_value) + if (_value := data.get("period")) is not None: + _args["period"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "period") + if (_value := data.get("profileId")) is not None: + _args["profile_id"] = opentelemetry.proto_json._json_codec.decode_base64(_value, "profile_id") + if (_value := data.get("droppedAttributesCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") + _args["dropped_attributes_count"] = _value + if (_value := data.get("originalPayloadFormat")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "original_payload_format") + _args["original_payload_format"] = _value + if (_value := data.get("originalPayload")) is not None: + _args["original_payload"] = opentelemetry.proto_json._json_codec.decode_base64(_value, "original_payload") + if (_value := data.get("attributeIndices")) is not None: + _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") + + return cls(**_args) + + +@typing.final +@_dataclass +class Link(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Link + """ + + trace_id: builtins.bytes | None = b"" + span_id: builtins.bytes | None = b"" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.trace_id: + _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) + if self.span_id: + _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Link: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Link instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("traceId")) is not None: + _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") + if (_value := data.get("spanId")) is not None: + _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") + + return cls(**_args) + + +@typing.final +@_dataclass +class ValueType(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ValueType + """ + + type_strindex: builtins.int | None = 0 + unit_strindex: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.type_strindex: + _result["typeStrindex"] = self.type_strindex + if self.unit_strindex: + _result["unitStrindex"] = self.unit_strindex + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ValueType: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ValueType instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("typeStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "type_strindex") + _args["type_strindex"] = _value + if (_value := data.get("unitStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "unit_strindex") + _args["unit_strindex"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class Sample(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Sample + """ + + stack_index: builtins.int | None = 0 + attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + link_index: builtins.int | None = 0 + values: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + timestamps_unix_nano: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.stack_index: + _result["stackIndex"] = self.stack_index + if self.attribute_indices: + _result["attributeIndices"] = self.attribute_indices + if self.link_index: + _result["linkIndex"] = self.link_index + if self.values: + _result["values"] = opentelemetry.proto_json._json_codec.encode_repeated(self.values, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) + if self.timestamps_unix_nano: + _result["timestampsUnixNano"] = opentelemetry.proto_json._json_codec.encode_repeated(self.timestamps_unix_nano, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Sample: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Sample instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("stackIndex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "stack_index") + _args["stack_index"] = _value + if (_value := data.get("attributeIndices")) is not None: + _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") + if (_value := data.get("linkIndex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "link_index") + _args["link_index"] = _value + if (_value := data.get("values")) is not None: + _args["values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "values"), "values") + if (_value := data.get("timestampsUnixNano")) is not None: + _args["timestamps_unix_nano"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "timestamps_unix_nano"), "timestamps_unix_nano") + + return cls(**_args) + + +@typing.final +@_dataclass +class Mapping(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Mapping + """ + + memory_start: builtins.int | None = 0 + memory_limit: builtins.int | None = 0 + file_offset: builtins.int | None = 0 + filename_strindex: builtins.int | None = 0 + attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.memory_start: + _result["memoryStart"] = opentelemetry.proto_json._json_codec.encode_int64(self.memory_start) + if self.memory_limit: + _result["memoryLimit"] = opentelemetry.proto_json._json_codec.encode_int64(self.memory_limit) + if self.file_offset: + _result["fileOffset"] = opentelemetry.proto_json._json_codec.encode_int64(self.file_offset) + if self.filename_strindex: + _result["filenameStrindex"] = self.filename_strindex + if self.attribute_indices: + _result["attributeIndices"] = self.attribute_indices + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Mapping: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Mapping instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("memoryStart")) is not None: + _args["memory_start"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "memory_start") + if (_value := data.get("memoryLimit")) is not None: + _args["memory_limit"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "memory_limit") + if (_value := data.get("fileOffset")) is not None: + _args["file_offset"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "file_offset") + if (_value := data.get("filenameStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "filename_strindex") + _args["filename_strindex"] = _value + if (_value := data.get("attributeIndices")) is not None: + _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") + + return cls(**_args) + + +@typing.final +@_dataclass +class Stack(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Stack + """ + + location_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.location_indices: + _result["locationIndices"] = self.location_indices + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Stack: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Stack instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("locationIndices")) is not None: + _args["location_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "location_indices") + + return cls(**_args) + + +@typing.final +@_dataclass +class Location(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Location + """ + + mapping_index: builtins.int | None = 0 + address: builtins.int | None = 0 + lines: builtins.list[Line] = dataclasses.field(default_factory=builtins.list) + attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.mapping_index: + _result["mappingIndex"] = self.mapping_index + if self.address: + _result["address"] = opentelemetry.proto_json._json_codec.encode_int64(self.address) + if self.lines: + _result["lines"] = opentelemetry.proto_json._json_codec.encode_repeated(self.lines, lambda _v: _v.to_dict()) + if self.attribute_indices: + _result["attributeIndices"] = self.attribute_indices + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Location: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Location instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("mappingIndex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "mapping_index") + _args["mapping_index"] = _value + if (_value := data.get("address")) is not None: + _args["address"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "address") + if (_value := data.get("lines")) is not None: + _args["lines"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Line.from_dict(_v), "lines") + if (_value := data.get("attributeIndices")) is not None: + _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") + + return cls(**_args) + + +@typing.final +@_dataclass +class Line(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Line + """ + + function_index: builtins.int | None = 0 + line: builtins.int | None = 0 + column: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.function_index: + _result["functionIndex"] = self.function_index + if self.line: + _result["line"] = opentelemetry.proto_json._json_codec.encode_int64(self.line) + if self.column: + _result["column"] = opentelemetry.proto_json._json_codec.encode_int64(self.column) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Line: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Line instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("functionIndex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "function_index") + _args["function_index"] = _value + if (_value := data.get("line")) is not None: + _args["line"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "line") + if (_value := data.get("column")) is not None: + _args["column"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "column") + + return cls(**_args) + + +@typing.final +@_dataclass +class Function(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Function + """ + + name_strindex: builtins.int | None = 0 + system_name_strindex: builtins.int | None = 0 + filename_strindex: builtins.int | None = 0 + start_line: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.name_strindex: + _result["nameStrindex"] = self.name_strindex + if self.system_name_strindex: + _result["systemNameStrindex"] = self.system_name_strindex + if self.filename_strindex: + _result["filenameStrindex"] = self.filename_strindex + if self.start_line: + _result["startLine"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_line) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Function: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Function instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("nameStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "name_strindex") + _args["name_strindex"] = _value + if (_value := data.get("systemNameStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "system_name_strindex") + _args["system_name_strindex"] = _value + if (_value := data.get("filenameStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "filename_strindex") + _args["filename_strindex"] = _value + if (_value := data.get("startLine")) is not None: + _args["start_line"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_line") + + return cls(**_args) + + +@typing.final +@_dataclass +class KeyValueAndUnit(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message KeyValueAndUnit + """ + + key_strindex: builtins.int | None = 0 + value: opentelemetry.proto_json.common.v1.common.AnyValue | None = None + unit_strindex: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.key_strindex: + _result["keyStrindex"] = self.key_strindex + if self.value: + _result["value"] = self.value.to_dict() + if self.unit_strindex: + _result["unitStrindex"] = self.unit_strindex + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> KeyValueAndUnit: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + KeyValueAndUnit instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("keyStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "key_strindex") + _args["key_strindex"] = _value + if (_value := data.get("value")) is not None: + _args["value"] = opentelemetry.proto_json.common.v1.common.AnyValue.from_dict(_value) + if (_value := data.get("unitStrindex")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "unit_strindex") + _args["unit_strindex"] = _value + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py new file mode 100644 index 00000000000..247d5169a22 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py @@ -0,0 +1,71 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/resource/v1/resource.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +@_dataclass +class Resource(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Resource + """ + + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + dropped_attributes_count: builtins.int | None = 0 + entity_refs: builtins.list[opentelemetry.proto_json.common.v1.common.EntityRef] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.dropped_attributes_count: + _result["droppedAttributesCount"] = self.dropped_attributes_count + if self.entity_refs: + _result["entityRefs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.entity_refs, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Resource: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Resource instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("droppedAttributesCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") + _args["dropped_attributes_count"] = _value + if (_value := data.get("entityRefs")) is not None: + _args["entity_refs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.EntityRef.from_dict(_v), "entity_refs") + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py new file mode 100644 index 00000000000..18ca440aef2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py @@ -0,0 +1,497 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# AUTO-GENERATED from "opentelemetry/proto/trace/v1/trace.proto" +# DO NOT EDIT MANUALLY + +from __future__ import annotations + +import builtins +import dataclasses +import enum +import functools +import typing + +_dataclass = functools.partial(dataclasses.dataclass, slots=True) + +import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource +from opentelemetry.agent._vendor import opentelemetry + + +@typing.final +class SpanFlags(enum.IntEnum): + """ + Generated from protobuf enum SpanFlags + """ + + SPAN_FLAGS_DO_NOT_USE = 0 + SPAN_FLAGS_TRACE_FLAGS_MASK = 255 + SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK = 256 + SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 512 + +@typing.final +@_dataclass +class TracesData(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message TracesData + """ + + resource_spans: builtins.list[ResourceSpans] = dataclasses.field(default_factory=builtins.list) + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource_spans: + _result["resourceSpans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_spans, lambda _v: _v.to_dict()) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> TracesData: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + TracesData instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resourceSpans")) is not None: + _args["resource_spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceSpans.from_dict(_v), "resource_spans") + + return cls(**_args) + + +@typing.final +@_dataclass +class ResourceSpans(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ResourceSpans + """ + + resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None + scope_spans: builtins.list[ScopeSpans] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.resource: + _result["resource"] = self.resource.to_dict() + if self.scope_spans: + _result["scopeSpans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_spans, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceSpans: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ResourceSpans instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("resource")) is not None: + _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) + if (_value := data.get("scopeSpans")) is not None: + _args["scope_spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeSpans.from_dict(_v), "scope_spans") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class ScopeSpans(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message ScopeSpans + """ + + scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None + spans: builtins.list[Span] = dataclasses.field(default_factory=builtins.list) + schema_url: builtins.str | None = "" + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.scope: + _result["scope"] = self.scope.to_dict() + if self.spans: + _result["spans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.spans, lambda _v: _v.to_dict()) + if self.schema_url: + _result["schemaUrl"] = self.schema_url + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeSpans: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + ScopeSpans instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("scope")) is not None: + _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) + if (_value := data.get("spans")) is not None: + _args["spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Span.from_dict(_v), "spans") + if (_value := data.get("schemaUrl")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") + _args["schema_url"] = _value + + return cls(**_args) + + +@typing.final +@_dataclass +class Span(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Span + """ + + @typing.final + class SpanKind(enum.IntEnum): + """ + Generated from protobuf enum SpanKind + """ + + SPAN_KIND_UNSPECIFIED = 0 + SPAN_KIND_INTERNAL = 1 + SPAN_KIND_SERVER = 2 + SPAN_KIND_CLIENT = 3 + SPAN_KIND_PRODUCER = 4 + SPAN_KIND_CONSUMER = 5 + + @typing.final + @_dataclass + class Event(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Event + """ + + time_unix_nano: builtins.int | None = 0 + name: builtins.str | None = "" + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + dropped_attributes_count: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.time_unix_nano: + _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) + if self.name: + _result["name"] = self.name + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.dropped_attributes_count: + _result["droppedAttributesCount"] = self.dropped_attributes_count + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Span.Event: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Event instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("timeUnixNano")) is not None: + _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") + if (_value := data.get("name")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") + _args["name"] = _value + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("droppedAttributesCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") + _args["dropped_attributes_count"] = _value + + return cls(**_args) + + @typing.final + @_dataclass + class Link(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Link + """ + + trace_id: builtins.bytes | None = b"" + span_id: builtins.bytes | None = b"" + trace_state: builtins.str | None = "" + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + dropped_attributes_count: builtins.int | None = 0 + flags: builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.trace_id: + _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) + if self.span_id: + _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) + if self.trace_state: + _result["traceState"] = self.trace_state + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.dropped_attributes_count: + _result["droppedAttributesCount"] = self.dropped_attributes_count + if self.flags: + _result["flags"] = self.flags + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Span.Link: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Link instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("traceId")) is not None: + _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") + if (_value := data.get("spanId")) is not None: + _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") + if (_value := data.get("traceState")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "trace_state") + _args["trace_state"] = _value + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("droppedAttributesCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") + _args["dropped_attributes_count"] = _value + if (_value := data.get("flags")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") + _args["flags"] = _value + + return cls(**_args) + + trace_id: builtins.bytes | None = b"" + span_id: builtins.bytes | None = b"" + trace_state: builtins.str | None = "" + parent_span_id: builtins.bytes | None = b"" + flags: builtins.int | None = 0 + name: builtins.str | None = "" + kind: Span.SpanKind | builtins.int | None = 0 + start_time_unix_nano: builtins.int | None = 0 + end_time_unix_nano: builtins.int | None = 0 + attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) + dropped_attributes_count: builtins.int | None = 0 + events: builtins.list[Span.Event] = dataclasses.field(default_factory=builtins.list) + dropped_events_count: builtins.int | None = 0 + links: builtins.list[Span.Link] = dataclasses.field(default_factory=builtins.list) + dropped_links_count: builtins.int | None = 0 + status: Status | None = None + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.trace_id: + _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) + if self.span_id: + _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) + if self.trace_state: + _result["traceState"] = self.trace_state + if self.parent_span_id: + _result["parentSpanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.parent_span_id) + if self.flags: + _result["flags"] = self.flags + if self.name: + _result["name"] = self.name + if self.kind: + _result["kind"] = builtins.int(self.kind) + if self.start_time_unix_nano: + _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) + if self.end_time_unix_nano: + _result["endTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.end_time_unix_nano) + if self.attributes: + _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) + if self.dropped_attributes_count: + _result["droppedAttributesCount"] = self.dropped_attributes_count + if self.events: + _result["events"] = opentelemetry.proto_json._json_codec.encode_repeated(self.events, lambda _v: _v.to_dict()) + if self.dropped_events_count: + _result["droppedEventsCount"] = self.dropped_events_count + if self.links: + _result["links"] = opentelemetry.proto_json._json_codec.encode_repeated(self.links, lambda _v: _v.to_dict()) + if self.dropped_links_count: + _result["droppedLinksCount"] = self.dropped_links_count + if self.status: + _result["status"] = self.status.to_dict() + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Span: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Span instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("traceId")) is not None: + _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") + if (_value := data.get("spanId")) is not None: + _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") + if (_value := data.get("traceState")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "trace_state") + _args["trace_state"] = _value + if (_value := data.get("parentSpanId")) is not None: + _args["parent_span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "parent_span_id") + if (_value := data.get("flags")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") + _args["flags"] = _value + if (_value := data.get("name")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") + _args["name"] = _value + if (_value := data.get("kind")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "kind") + _args["kind"] = Span.SpanKind(_value) + if (_value := data.get("startTimeUnixNano")) is not None: + _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") + if (_value := data.get("endTimeUnixNano")) is not None: + _args["end_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "end_time_unix_nano") + if (_value := data.get("attributes")) is not None: + _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") + if (_value := data.get("droppedAttributesCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") + _args["dropped_attributes_count"] = _value + if (_value := data.get("events")) is not None: + _args["events"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Span.Event.from_dict(_v), "events") + if (_value := data.get("droppedEventsCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_events_count") + _args["dropped_events_count"] = _value + if (_value := data.get("links")) is not None: + _args["links"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Span.Link.from_dict(_v), "links") + if (_value := data.get("droppedLinksCount")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_links_count") + _args["dropped_links_count"] = _value + if (_value := data.get("status")) is not None: + _args["status"] = Status.from_dict(_value) + + return cls(**_args) + + +@typing.final +@_dataclass +class Status(opentelemetry.proto_json._json_codec.JsonMessage): + """ + Generated from protobuf message Status + """ + + @typing.final + class StatusCode(enum.IntEnum): + """ + Generated from protobuf enum StatusCode + """ + + STATUS_CODE_UNSET = 0 + STATUS_CODE_OK = 1 + STATUS_CODE_ERROR = 2 + + message: builtins.str | None = "" + code: Status.StatusCode | builtins.int | None = 0 + + def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: + """ + Convert this message to a dictionary with lowerCamelCase keys. + + Returns: + Dictionary representation following OTLP JSON encoding + """ + _result = {} + if self.message: + _result["message"] = self.message + if self.code: + _result["code"] = builtins.int(self.code) + return _result + + @builtins.classmethod + def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Status: + """ + Create from a dictionary with lowerCamelCase keys. + + Args: + data: Dictionary representation following OTLP JSON encoding + + Returns: + Status instance + """ + opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") + _args = {} + + if (_value := data.get("message")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "message") + _args["message"] = _value + if (_value := data.get("code")) is not None: + opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "code") + _args["code"] = Status.StatusCode(_value) + + return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi new file mode 100644 index 00000000000..e57edc0f58b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi @@ -0,0 +1,18 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +The OpenTelemetry SDK package is an implementation of the OpenTelemetry +API +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py new file mode 100644 index 00000000000..160f4c1666c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py @@ -0,0 +1,676 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# + +""" +OpenTelemetry SDK Configurator for Easy Instrumentation with Distros +""" + +from __future__ import annotations + +import logging +import logging.config +import os +import warnings +from abc import ABC, abstractmethod +from collections.abc import Callable, Mapping, Sequence +from os import environ +from typing import Any, Literal, Protocol + +from opentelemetry.agent._vendor.opentelemetry._logs import set_logger_provider +from opentelemetry.agent._vendor.opentelemetry.environment_variables import ( + OTEL_LOGS_EXPORTER, + OTEL_METRICS_EXPORTER, + OTEL_PYTHON_ID_GENERATOR, + OTEL_TRACES_EXPORTER, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import set_meter_provider +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ( + LoggerProvider, + LoggingHandler, + LogRecordProcessor, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal import _LoggerConfiguratorT +from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( + BatchLogRecordProcessor, + LogRecordExporter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + _OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, + OTEL_CONFIG_FILE, + OTEL_EXPORTER_OTLP_LOGS_PROTOCOL, + OTEL_EXPORTER_OTLP_METRICS_PROTOCOL, + OTEL_EXPORTER_OTLP_PROTOCOL, + OTEL_EXPORTER_OTLP_TRACES_PROTOCOL, + OTEL_PYTHON_LOGGER_CONFIGURATOR, + OTEL_PYTHON_METER_CONFIGURATOR, + OTEL_PYTHON_TRACER_CONFIGURATOR, + OTEL_TRACES_SAMPLER, + OTEL_TRACES_SAMPLER_ARG, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import MeterProvider +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import _MeterConfiguratorT +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( + MetricExporter, + MetricReader, + PeriodicExportingMetricReader, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Attributes, Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ( + SpanProcessor, + TracerProvider, + _TracerConfiguratorT, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator import IdGenerator +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import Sampler +from opentelemetry.agent._vendor.opentelemetry.semconv.resource import ResourceAttributes +from opentelemetry.agent._vendor.opentelemetry.trace import set_tracer_provider +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points + +_EXPORTER_OTLP = "otlp" +_EXPORTER_OTLP_PROTO_GRPC = "otlp_proto_grpc" +_EXPORTER_OTLP_PROTO_HTTP = "otlp_proto_http" + +_EXPORTER_BY_OTLP_PROTOCOL = { + "grpc": _EXPORTER_OTLP_PROTO_GRPC, + "http/protobuf": _EXPORTER_OTLP_PROTO_HTTP, +} + +_EXPORTER_ENV_BY_SIGNAL_TYPE = { + "traces": OTEL_TRACES_EXPORTER, + "metrics": OTEL_METRICS_EXPORTER, + "logs": OTEL_LOGS_EXPORTER, +} + +_PROTOCOL_ENV_BY_SIGNAL_TYPE = { + "traces": OTEL_EXPORTER_OTLP_TRACES_PROTOCOL, + "metrics": OTEL_EXPORTER_OTLP_METRICS_PROTOCOL, + "logs": OTEL_EXPORTER_OTLP_LOGS_PROTOCOL, +} + +_RANDOM_ID_GENERATOR = "random" +_DEFAULT_ID_GENERATOR = _RANDOM_ID_GENERATOR + +_OTEL_SAMPLER_ENTRY_POINT_GROUP = "opentelemetry_traces_sampler" + +_logger = logging.getLogger(__name__) + +ExporterArgsMap = Mapping[ + type[SpanExporter] | type[MetricExporter] | type[MetricReader] | type[LogRecordExporter], + Mapping[str, Any], +] + + +class _ConfigurationExporterSpanProcessorT(Protocol): + def __call__(self, span_exporter: SpanExporter, *args, **kwargs) -> SpanProcessor: ... + + +class _ConfigurationExporterLogRecordProcessorT(Protocol): + def __call__(self, exporter: LogRecordExporter, *args, **kwargs) -> LogRecordProcessor: ... + + +def _import_config_components(selected_components: Sequence[str], entry_point_name: str) -> list[tuple[str, type]]: + component_implementations = [] + + for selected_component in selected_components: + try: + component_implementations.append( + ( + selected_component, + next(iter(entry_points(group=entry_point_name, name=selected_component))).load(), + ) + ) + except KeyError: + raise RuntimeError(f"Requested entry point '{entry_point_name}' not found") + + except StopIteration: + raise RuntimeError( + f"Requested component '{selected_component}' not found in entry point '{entry_point_name}'" + ) + + return component_implementations + + +def _get_sampler() -> str | None: + return environ.get(OTEL_TRACES_SAMPLER, None) + + +def _get_id_generator() -> str: + return environ.get(OTEL_PYTHON_ID_GENERATOR, _DEFAULT_ID_GENERATOR) + + +def _get_tracer_configurator() -> str | None: + return environ.get(OTEL_PYTHON_TRACER_CONFIGURATOR, None) + + +def _get_meter_configurator() -> str | None: + return environ.get(OTEL_PYTHON_METER_CONFIGURATOR, None) + + +def _get_logger_configurator() -> str | None: + return environ.get(OTEL_PYTHON_LOGGER_CONFIGURATOR, None) + + +def _get_exporter_entry_point(exporter_name: str, signal_type: Literal["traces", "metrics", "logs"]): + if exporter_name not in ( + _EXPORTER_OTLP, + _EXPORTER_OTLP_PROTO_GRPC, + _EXPORTER_OTLP_PROTO_HTTP, + ): + return exporter_name + + # Checking env vars for OTLP protocol (grpc/http). + otlp_protocol = environ.get(_PROTOCOL_ENV_BY_SIGNAL_TYPE[signal_type]) or environ.get(OTEL_EXPORTER_OTLP_PROTOCOL) + + if not otlp_protocol: + if exporter_name == _EXPORTER_OTLP: + return _EXPORTER_OTLP_PROTO_GRPC + return exporter_name + + otlp_protocol = otlp_protocol.strip() + + if exporter_name == _EXPORTER_OTLP: + if otlp_protocol not in _EXPORTER_BY_OTLP_PROTOCOL: + # Invalid value was set by the env var + raise RuntimeError(f"Unsupported OTLP protocol '{otlp_protocol}' is configured") + + return _EXPORTER_BY_OTLP_PROTOCOL[otlp_protocol] + + # grpc/http already specified by exporter_name, only add a warning in case + # of a conflict. + exporter_name_by_env = _EXPORTER_BY_OTLP_PROTOCOL.get(otlp_protocol) + if exporter_name_by_env and exporter_name != exporter_name_by_env: + _logger.warning( + "Conflicting values for %s OTLP exporter protocol, using '%s'", + signal_type, + exporter_name, + ) + + return exporter_name + + +def _get_exporter_names( + signal_type: Literal["traces", "metrics", "logs"], +) -> list[str]: + names = environ.get(_EXPORTER_ENV_BY_SIGNAL_TYPE.get(signal_type, "")) + + if not names or names.lower().strip() == "none": + return [] + + return [_get_exporter_entry_point(_exporter.strip(), signal_type) for _exporter in names.split(",")] + + +def _init_tracing( + exporters: dict[str, type[SpanExporter]], + id_generator: IdGenerator | None = None, + sampler: Sampler | None = None, + resource: Resource | None = None, + exporter_args_map: ExporterArgsMap | None = None, + span_processors: Sequence[SpanProcessor] | None = None, + export_span_processor: _ConfigurationExporterSpanProcessorT | None = None, + tracer_configurator: _TracerConfiguratorT | None = None, +): + provider = TracerProvider( + id_generator=id_generator, + sampler=sampler, + resource=resource, + _tracer_configurator=tracer_configurator, + ) + set_tracer_provider(provider) + + exporter_args_map = exporter_args_map or {} + export_processor = export_span_processor or BatchSpanProcessor + + span_processors = span_processors or [] + for span_processor in span_processors: + provider.add_span_processor(span_processor) + + for _, exporter_class in exporters.items(): + exporter_args = exporter_args_map.get(exporter_class, {}) + provider.add_span_processor(export_processor(exporter_class(**exporter_args))) + + +def _init_metrics( + exporters_or_readers: dict[str, type[MetricExporter | MetricReader]], + resource: Resource | None = None, + exporter_args_map: ExporterArgsMap | None = None, + meter_configurator: _MeterConfiguratorT | None = None, +): + metric_readers = [] + + exporter_args_map = exporter_args_map or {} + for _, exporter_or_reader_class in exporters_or_readers.items(): + exporter_args = exporter_args_map.get(exporter_or_reader_class, {}) + if issubclass(exporter_or_reader_class, MetricReader): + metric_readers.append(exporter_or_reader_class(**exporter_args)) + else: + metric_readers.append(PeriodicExportingMetricReader(exporter_or_reader_class(**exporter_args))) + + provider = MeterProvider( + resource=resource, + metric_readers=metric_readers, + _meter_configurator=meter_configurator, + ) + set_meter_provider(provider) + + +# pylint: disable-next=too-many-locals +def _init_logging( + exporters: dict[str, type[LogRecordExporter]], + resource: Resource | None = None, + setup_logging_handler: bool = True, + exporter_args_map: ExporterArgsMap | None = None, + log_record_processors: Sequence[LogRecordProcessor] | None = None, + export_log_record_processor: _ConfigurationExporterLogRecordProcessorT | None = None, + logger_configurator: _LoggerConfiguratorT | None = None, +): + provider = LoggerProvider(resource=resource, _logger_configurator=logger_configurator) + set_logger_provider(provider) + + exporter_args_map = exporter_args_map or {} + export_processor = export_log_record_processor or BatchLogRecordProcessor + + log_record_processors = log_record_processors or [] + for log_record_processor in log_record_processors: + provider.add_log_record_processor(log_record_processor) + + for _, exporter_class in exporters.items(): + exporter_args = exporter_args_map.get(exporter_class, {}) + provider.add_log_record_processor(export_processor(exporter_class(**exporter_args))) + + if setup_logging_handler: + warnings.warn( + "The `OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED` environment variable " + "and the `LoggingHandler` in `opentelemetry-sdk` that it controls are deprecated." + "Install `opentelemetry-instrumentation-logging` package instead.", + DeprecationWarning, + ) + + # Add OTel handler + handler = LoggingHandler(level=logging.NOTSET, logger_provider=provider) + logging.getLogger().addHandler(handler) + _overwrite_logging_config_fns(handler) + + +def _overwrite_logging_config_fns(handler: LoggingHandler) -> None: + root = logging.getLogger() + + def wrapper(config_fn: Callable) -> Callable: + def overwritten_config_fn(*args, **kwargs): + removed_handler = False + # We don't want the OTLP handler to be modified or deleted by the logging config functions. + # So we remove it and then add it back after the function call. + if handler in root.handlers: + removed_handler = True + root.handlers.remove(handler) + try: + config_fn(*args, **kwargs) + finally: + # Ensure handler is added back if logging function throws exception. + if removed_handler: + root.addHandler(handler) + + return overwritten_config_fn + + logging.config.fileConfig = wrapper(logging.config.fileConfig) + logging.config.dictConfig = wrapper(logging.config.dictConfig) + logging.basicConfig = wrapper(logging.basicConfig) + + +def _import_logger_configurator( + logger_configurator_name: str | None, +) -> _LoggerConfiguratorT | None: + if not logger_configurator_name: + return None + + try: + _, logger_configurator_impl = _import_config_components( + [logger_configurator_name.strip()], + "_opentelemetry_logger_configurator", + )[0] + except Exception as exc: # pylint: disable=broad-exception-caught + _logger.warning( + "Using default logger configurator. Failed to load logger configurator, %s: %s", + logger_configurator_name, + exc, + ) + return None + return logger_configurator_impl + + +def _import_tracer_configurator( + tracer_configurator_name: str | None, +) -> _TracerConfiguratorT | None: + if not tracer_configurator_name: + return None + + try: + _, tracer_configurator_impl = _import_config_components( + [tracer_configurator_name.strip()], + "_opentelemetry_tracer_configurator", + )[0] + except Exception as exc: # pylint: disable=broad-exception-caught + _logger.warning( + "Using default tracer configurator. Failed to load tracer configurator, %s: %s", + tracer_configurator_name, + exc, + ) + return None + return tracer_configurator_impl + + +def _import_meter_configurator( + meter_configurator_name: str | None, +) -> _MeterConfiguratorT | None: + if not meter_configurator_name: + return None + + try: + _, meter_configurator_impl = _import_config_components( + [meter_configurator_name.strip()], + "_opentelemetry_meter_configurator", + )[0] + except Exception as exc: # pylint: disable=broad-exception-caught + _logger.warning( + "Using default meter configurator. Failed to load meter configurator, %s: %s", + meter_configurator_name, + exc, + ) + return None + return meter_configurator_impl + + +def _import_exporters( + trace_exporter_names: Sequence[str], + metric_exporter_names: Sequence[str], + log_exporter_names: Sequence[str], +) -> tuple[ + dict[str, type[SpanExporter]], + dict[str, type[MetricExporter | MetricReader]], + dict[str, type[LogRecordExporter]], +]: + trace_exporters = {} + metric_exporters = {} + log_exporters = {} + + for ( + exporter_name, + exporter_impl, + ) in _import_config_components(trace_exporter_names, "opentelemetry_traces_exporter"): + if issubclass(exporter_impl, SpanExporter): + trace_exporters[exporter_name] = exporter_impl + else: + raise RuntimeError(f"{exporter_name} is not a trace exporter") + + for ( + exporter_name, + exporter_impl, + ) in _import_config_components(metric_exporter_names, "opentelemetry_metrics_exporter"): + # The metric exporter components may be push MetricExporter or pull exporters which + # subclass MetricReader directly + if issubclass(exporter_impl, (MetricExporter, MetricReader)): + metric_exporters[exporter_name] = exporter_impl + else: + raise RuntimeError(f"{exporter_name} is not a metric exporter") + + for ( + exporter_name, + exporter_impl, + ) in _import_config_components(log_exporter_names, "opentelemetry_logs_exporter"): + if issubclass(exporter_impl, LogRecordExporter): + log_exporters[exporter_name] = exporter_impl + else: + raise RuntimeError(f"{exporter_name} is not a log exporter") + + return trace_exporters, metric_exporters, log_exporters + + +def _import_sampler_factory( + sampler_name: str, +) -> Callable[[float | str | None], Sampler]: + _, sampler_impl = _import_config_components([sampler_name.strip()], _OTEL_SAMPLER_ENTRY_POINT_GROUP)[0] + return sampler_impl + + +def _import_sampler(sampler_name: str | None) -> Sampler | None: + if not sampler_name: + return None + try: + sampler_factory = _import_sampler_factory(sampler_name) + arg = None + if sampler_name in ("traceidratio", "parentbased_traceidratio"): + try: + rate = float(os.getenv(OTEL_TRACES_SAMPLER_ARG, "")) + except (ValueError, TypeError): + _logger.warning("Could not convert TRACES_SAMPLER_ARG to float. Using default value 1.0.") + rate = 1.0 + arg = rate + else: + arg = os.getenv(OTEL_TRACES_SAMPLER_ARG) + + sampler = sampler_factory(arg) + if not isinstance(sampler, Sampler): + message = f"Sampler factory, {sampler_factory}, produced output, {sampler}, which is not a Sampler." + _logger.warning(message) + raise ValueError(message) + return sampler + except Exception as exc: # pylint: disable=broad-exception-caught + _logger.warning( + "Using default sampler. Failed to initialize sampler, %s: %s", + sampler_name, + exc, + ) + return None + + +def _import_id_generator(id_generator_name: str) -> IdGenerator: + id_generator_name, id_generator_impl = _import_config_components( + [id_generator_name.strip()], "opentelemetry_id_generator" + )[0] + + if issubclass(id_generator_impl, IdGenerator): + return id_generator_impl() + + raise RuntimeError(f"{id_generator_name} is not an IdGenerator") + + +def _import_opamp( + name: Literal["pre_sdk_init_function", "post_sdk_init_function"], +) -> Callable[[Resource], None] | None: + """Helper for OpAMP entry points loading + + This in development, at the moment we are looking for a callable that takes + the resource and instantiate an OpAMP agent. + Since configuration is not specified every implementer may have its own. + Refer to the opentelemetry-opamp-client package on how to setup the OpAMP agent. + """ + entry_point = None + try: + entry_point = next(iter(entry_points(group="_opentelemetry_opamp", name=name))) + return entry_point.load() + except StopIteration: + _logger.debug("No OpAMP init function found") + except AttributeError as exc: + _logger.warning( + "Failed to load OpAMP init function from entry point, %s: %s", + entry_point, + exc, + ) + + return None + + +def _initialize_components( + auto_instrumentation_version: str | None = None, + trace_exporter_names: list[str] | None = None, + metric_exporter_names: list[str] | None = None, + log_exporter_names: list[str] | None = None, + sampler: Sampler | None = None, + resource_attributes: Attributes | None = None, + id_generator: IdGenerator | None = None, + setup_logging_handler: bool | None = None, + exporter_args_map: ExporterArgsMap | None = None, + span_processors: Sequence[SpanProcessor] | None = None, + export_span_processor: _ConfigurationExporterSpanProcessorT | None = None, + log_record_processors: Sequence[LogRecordProcessor] | None = None, + export_log_record_processor: _ConfigurationExporterLogRecordProcessorT | None = None, + tracer_configurator: _TracerConfiguratorT | None = None, + meter_configurator: _MeterConfiguratorT | None = None, + logger_configurator: _LoggerConfiguratorT | None = None, +): + # pylint: disable=too-many-locals,too-many-branches + if resource_attributes is None: + resource_attributes = {} + # populate version if using auto-instrumentation + if auto_instrumentation_version: + resource_attributes[ResourceAttributes.TELEMETRY_AUTO_VERSION] = ( # type: ignore[reportIndexIssue] + auto_instrumentation_version + ) + # if env var OTEL_RESOURCE_ATTRIBUTES is given, it will read the service_name + # from the env variable else defaults to "unknown_service" + resource = Resource.create(resource_attributes) + + # OpAMP is a system created to configure OpenTelemetry SDKs with a remote config. + # This is different than other init helpers because setting up OpAMP requires distro + # provided code as it's not strictly specified. We have two entry points for OpAMP: + # one called early for people that want it blocking to get an updated config before + # setting up the rest of the SDK and the other after for people that want the + # SDK already setup. + _init_opamp = _import_opamp("pre_sdk_init_function") + if _init_opamp is not None: + _init_opamp(resource) + + if trace_exporter_names is None: + trace_exporter_names = [] + if metric_exporter_names is None: + metric_exporter_names = [] + if log_exporter_names is None: + log_exporter_names = [] + span_exporters, metric_exporters, log_exporters = _import_exporters( + trace_exporter_names + _get_exporter_names("traces"), + metric_exporter_names + _get_exporter_names("metrics"), + log_exporter_names + _get_exporter_names("logs"), + ) + if sampler is None: + sampler_name = _get_sampler() + sampler = _import_sampler(sampler_name) + if id_generator is None: + id_generator_name = _get_id_generator() + id_generator = _import_id_generator(id_generator_name) + + if tracer_configurator is None: + tracer_configurator_name = _get_tracer_configurator() + tracer_configurator = _import_tracer_configurator(tracer_configurator_name) + if meter_configurator is None: + meter_configurator_name = _get_meter_configurator() + meter_configurator = _import_meter_configurator(meter_configurator_name) + if logger_configurator is None: + logger_configurator_name = _get_logger_configurator() + logger_configurator = _import_logger_configurator(logger_configurator_name) + + _init_tracing( + exporters=span_exporters, + id_generator=id_generator, + sampler=sampler, + resource=resource, + exporter_args_map=exporter_args_map, + span_processors=span_processors, + export_span_processor=export_span_processor, + tracer_configurator=tracer_configurator, + ) + _init_metrics( + exporters_or_readers=metric_exporters, + resource=resource, + exporter_args_map=exporter_args_map, + meter_configurator=meter_configurator, + ) + if setup_logging_handler is None: + setup_logging_handler = ( + os.getenv(_OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, "false").strip().lower() == "true" + ) + _init_logging( + log_exporters, + resource, + setup_logging_handler, + exporter_args_map=exporter_args_map, + log_record_processors=log_record_processors, + export_log_record_processor=export_log_record_processor, + logger_configurator=logger_configurator, + ) + + _init_opamp = _import_opamp("post_sdk_init_function") + if _init_opamp is not None: + _init_opamp(resource) + + +class _BaseConfigurator(ABC): + """An ABC for configurators + + Configurators are used to configure + SDKs (i.e. TracerProvider, MeterProvider, Processors...) + to reduce the amount of manual configuration required. + """ + + _instance = None + _is_instrumented = False + + def __new__(cls, *args, **kwargs): + if cls._instance is None: + cls._instance = super().__new__(cls) + + return cls._instance + + @abstractmethod + def _configure(self, **kwargs): + """Configure the SDK""" + + def configure(self, **kwargs): + """Configure the SDK""" + self._configure(**kwargs) + + +class _OTelSDKConfigurator(_BaseConfigurator): + """A basic Configurator by OTel Python for initializing OTel SDK components + + Initializes several crucial OTel SDK components (i.e. TracerProvider, + MeterProvider, Processors...) according to a default implementation. Other + Configurators can subclass and slightly alter this initialization. + + NOTE: This class should not be instantiated nor should it become an entry + point on the `opentelemetry-sdk` package. Instead, distros should subclass + this Configurator and enhance it as needed. + """ + + def _configure(self, **kwargs): + if config_file := environ.get(OTEL_CONFIG_FILE): + # Declarative configuration lives in the separate + # ``opentelemetry-configuration`` package. Import lazily so the + # SDK has no runtime dependency on it; users who don't set + # ``OTEL_CONFIG_FILE`` never pay the import cost. + try: + # opentelemetry-configuration is an optional runtime dep + # and is not installed in this package's lint env, so + # silence the static-analysis no-name-in-module on the + # conditional import. + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.configuration import ( # noqa: PLC0415 + configure_sdk, + load_config_file, + ) + except ImportError as exc: + raise RuntimeError( + f"{OTEL_CONFIG_FILE} is set but " + "opentelemetry-configuration is not installed. " + "Install it with: pip install opentelemetry-configuration" + ) from exc + + if kwargs: + _logger.warning( + "%s is set; ignoring configurator kwargs: %s", + OTEL_CONFIG_FILE, + sorted(kwargs), + ) + configure_sdk(load_config_file(config_file)) + return + _initialize_components(**kwargs) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py new file mode 100644 index 00000000000..da62c461a91 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py @@ -0,0 +1,32 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal import ( + ConcurrentMultiLogRecordProcessor, + LogDroppedAttributesWarning, + Logger, + LoggerProvider, + LoggingHandler, + LogLimits, + LogRecordDroppedAttributesWarning, + LogRecordLimits, + LogRecordProcessor, + ReadableLogRecord, + ReadWriteLogRecord, + SynchronousMultiLogRecordProcessor, +) + +__all__ = [ + "ConcurrentMultiLogRecordProcessor", + "LogDroppedAttributesWarning", + "LogLimits", + "LogRecordDroppedAttributesWarning", + "LogRecordLimits", + "LogRecordProcessor", + "Logger", + "LoggerProvider", + "LoggingHandler", + "ReadWriteLogRecord", + "ReadableLogRecord", + "SynchronousMultiLogRecordProcessor", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py new file mode 100644 index 00000000000..56c439b6f9c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py @@ -0,0 +1,1092 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import abc +import atexit +import base64 +import concurrent.futures +import json +import logging +import os +import threading +import traceback +import warnings +from collections.abc import Callable, Mapping, Sequence +from dataclasses import dataclass, field +from os import environ +from threading import Lock +from time import time_ns +from types import NoneType +from typing import ( # noqa + Any, + Tuple, + Union, + cast, + overload, +) +from weakref import WeakMethod, WeakSet + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry._logs import Logger as APILogger +from opentelemetry.agent._vendor.opentelemetry._logs import LoggerProvider as APILoggerProvider +from opentelemetry.agent._vendor.opentelemetry._logs import ( + LogRecord, + NoOpLogger, + SeverityNumber, + get_logger, + get_logger_provider, +) +from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes +from opentelemetry.agent._vendor.opentelemetry.context import get_current +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal._exceptions import ( + _copy_log_record_with_exception, + _create_log_record_with_exception, + _set_log_record_exception_attributes, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal._logger_metrics import ( + LoggerMetricsT, + create_logger_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_ATTRIBUTE_COUNT_LIMIT, + OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, + OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT, + OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, + OTEL_SDK_DISABLED, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( + parse_boolean_environment_variable, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( + Resource, + _get_process_dependent_resource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.util import ns_to_iso_str +from opentelemetry.agent._vendor.opentelemetry.sdk.util._configurator import RuleBasedConfigurator +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( + InstrumentationScope, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes import ( + code_attributes, + exception_attributes, +) +from opentelemetry.agent._vendor.opentelemetry.trace import ( + format_span_id, + format_trace_id, +) +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes + +# pylint: disable=too-many-lines + +_DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT = 128 +_ENV_VALUE_UNSET = "" + +_logger = logging.getLogger(__name__) + + +class BytesEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, bytes): + return base64.b64encode(o).decode() + return super().default(o) + + +class LogRecordDroppedAttributesWarning(UserWarning): + """Custom warning to indicate dropped log attributes due to limits. + + This class is used to filter and handle these specific warnings separately + from other warnings, ensuring that they are only shown once without + interfering with default user warnings. + """ + + +warnings.simplefilter("once", LogRecordDroppedAttributesWarning) + + +@deprecated( + "Use LogRecordDroppedAttributesWarning. Since logs are not stable yet this WILL be removed in future releases." +) +class LogDroppedAttributesWarning(LogRecordDroppedAttributesWarning): + pass + + +class LogRecordLimits: + """This class is based on a SpanLimits class in the Tracing module. + + This class represents the limits that should be enforced on recorded data such as events, links, attributes etc. + + This class does not enforce any limits itself. It only provides a way to read limits from env, + default values and from user provided arguments. + + All limit arguments must be either a non-negative integer, ``None`` or ``LogRecordLimits.UNSET``. + + - All limit arguments are optional. + - If a limit argument is not set, the class will try to read its value from the corresponding + environment variable. + - If the environment variable is not set, the default value, if any, will be used. + + Limit precedence: + + - If a model specific limit is set, it will be used. + - Else if the corresponding global limit is set, it will be used. + - Else if the model specific limit has a default value, the default value will be used. + - Else if the global limit has a default value, the default value will be used. + + Args: + max_attributes: Maximum number of attributes that can be added to a log record (global fallback). + Environment variable: ``OTEL_ATTRIBUTE_COUNT_LIMIT`` + Default: {_DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT} + max_attribute_length: Maximum length an attribute value can have (global fallback). Values + longer than the specified length will be truncated. + max_log_record_attributes: Maximum number of attributes that can be added to a log record. + Environment variable: ``OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT`` + Falls back to ``max_attributes`` when unset. + max_log_record_attribute_length: Maximum length a log record attribute value can have. + Environment variable: ``OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT`` + Falls back to ``max_attribute_length`` when unset. + """ + + UNSET = -1 + + def __init__( + self, + max_attributes: int | None = None, + max_attribute_length: int | None = None, + max_log_record_attributes: int | None = None, + max_log_record_attribute_length: int | None = None, + ): + # global attribute count + global_max_attributes = self._from_env_if_absent(max_attributes, OTEL_ATTRIBUTE_COUNT_LIMIT) + self.max_attributes = ( + global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT + ) + + # global attribute length + self.max_attribute_length = self._from_env_if_absent( + max_attribute_length, + OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, + ) + + self.max_log_record_attributes = self._from_env_if_absent( + max_log_record_attributes, + OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT, + default=self.max_attributes, + ) + + self.max_log_record_attribute_length = self._from_env_if_absent( + max_log_record_attribute_length, + OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT, + default=self.max_attribute_length, + ) + + def __repr__(self): + return ( + f"{type(self).__name__}(" + f"max_attributes={self.max_attributes}, " + f"max_attribute_length={self.max_attribute_length}, " + f"max_log_record_attributes={self.max_log_record_attributes}, " + f"max_log_record_attribute_length={self.max_log_record_attribute_length})" + ) + + @classmethod + def _from_env_if_absent(cls, value: int | None, env_var: str, default: int | None = None) -> int | None: + if value == cls.UNSET: + return None + + err_msg = "{} must be a non-negative integer but got {}" + + # if no value is provided for the limit, try to load it from env + if value is None: + # return default value if env var is not set + if env_var not in environ: + return default + + str_value = environ.get(env_var, "").strip().lower() + if str_value == _ENV_VALUE_UNSET: + return None + + try: + value = int(str_value) + except ValueError: + raise ValueError(err_msg.format(env_var, str_value)) + + if value < 0: + raise ValueError(err_msg.format(env_var, value)) + return value + + +@deprecated("Use LogRecordLimits. Since logs are not stable yet this WILL be removed in future releases.") +class LogLimits(LogRecordLimits): + pass + + +@dataclass(frozen=True) +class ReadableLogRecord: + """Readable LogRecord should be kept exactly in-sync with ReadWriteLogRecord, only difference is the frozen=True param.""" + + log_record: LogRecord + resource: Resource + instrumentation_scope: InstrumentationScope | None = None + limits: LogRecordLimits | None = None + + @property + def dropped_attributes(self) -> int: + if isinstance(self.log_record.attributes, BoundedAttributes): + return self.log_record.attributes.dropped + return 0 + + def to_json(self, indent: int | None = 4) -> str: + return json.dumps( + { + "body": self.log_record.body, + "severity_number": self.log_record.severity_number.value + if self.log_record.severity_number is not None + else None, + "severity_text": self.log_record.severity_text, + "attributes": (dict(self.log_record.attributes) if bool(self.log_record.attributes) else None), + "dropped_attributes": self.dropped_attributes, + "timestamp": ns_to_iso_str(self.log_record.timestamp) + if self.log_record.timestamp is not None + else None, + "observed_timestamp": ns_to_iso_str(self.log_record.observed_timestamp), + "trace_id": ( + f"0x{format_trace_id(self.log_record.trace_id)}" if self.log_record.trace_id is not None else "" + ), + "span_id": ( + f"0x{format_span_id(self.log_record.span_id)}" if self.log_record.span_id is not None else "" + ), + "trace_flags": self.log_record.trace_flags, + "resource": json.loads(self.resource.to_json()), + "event_name": self.log_record.event_name if self.log_record.event_name else "", + }, + indent=indent, + cls=BytesEncoder, + ) + + +@dataclass +class ReadWriteLogRecord: + """A ReadWriteLogRecord instance represents an event being logged. + ReadWriteLogRecord instances are created and emitted via `Logger` + every time something is logged. They contain all the information + pertinent to the event being logged. + """ + + log_record: LogRecord + resource: Resource | None = Resource.create({}) + instrumentation_scope: InstrumentationScope | None = None + limits: LogRecordLimits = field(default_factory=LogRecordLimits) + + def __post_init__(self): + self.log_record.attributes = BoundedAttributes( + maxlen=self.limits.max_log_record_attributes, + attributes=self.log_record.attributes if self.log_record.attributes else None, + immutable=False, + max_value_len=self.limits.max_log_record_attribute_length, + extended_attributes=True, + ) + if self.dropped_attributes > 0: + warnings.warn( + "Log record attributes were dropped due to limits", + LogRecordDroppedAttributesWarning, + stacklevel=2, + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, ReadWriteLogRecord): + return NotImplemented + return self.__dict__ == other.__dict__ + + @property + def dropped_attributes(self) -> int: + if isinstance(self.log_record.attributes, BoundedAttributes): + return self.log_record.attributes.dropped + return 0 + + @classmethod + def _from_api_log_record( + cls, + *, + record: LogRecord, + resource: Resource, + instrumentation_scope: InstrumentationScope | None = None, + limits: LogRecordLimits | None = None, + ) -> ReadWriteLogRecord: + return cls( + log_record=record, + resource=resource, + instrumentation_scope=instrumentation_scope, + **({} if limits is None else {"limits": limits}), + ) + + +class LogRecordProcessor(abc.ABC): + """Interface to hook the log record emitting action. + + Log processors can be registered directly using + :func:`LoggerProvider.add_log_record_processor` and they are invoked + in the same order as they were registered. + + Implementers of custom log processors should be aware of the following: + + Error Handling + -------------- + According to the OpenTelemetry error handling principles, the SDK should + not throw unhandled exceptions at runtime. When implementing a custom + ``LogRecordProcessor``, it is the **processor's responsibility** to handle + any exceptions that may be raised by the exporter's ``export()`` method. + + The ``LogRecordExporter.export()`` method may raise exceptions (e.g., + network errors, timeouts). If these exceptions are not caught, they will + propagate up and potentially crash the application. + + Custom processor implementations should wrap exporter calls in a + try/except block. See ``SimpleLogRecordProcessor`` for a reference + implementation:: + + def on_emit(self, log_record: ReadWriteLogRecord): + try: + self._exporter.export((log_record,)) + except Exception: # pylint: disable=broad-exception-caught + logger.exception("Exception while exporting logs.") + + The ``BatchLogRecordProcessor`` handles this implicitly since export + operations occur in a background thread where exceptions cannot bubble + up to the caller. + """ + + @abc.abstractmethod + def on_emit(self, log_record: ReadWriteLogRecord) -> None: + """Emits the ``ReadWriteLogRecord``. + + Implementers should handle any exceptions raised during log processing + to prevent application crashes. See the class docstring for details + on error handling expectations. + """ + + def enabled( # pylint: disable=no-self-use,unused-argument + self, + *, + context: Context | None = None, + instrumentation_scope: InstrumentationScope | None = None, + severity_number: SeverityNumber | None = None, + event_name: str | None = None, + ) -> bool: + """Returns whether this processor would emit a record for the given arguments. + + Processors that support filtering MAY override this method. The default + implementation returns ``True``. + """ + return True + + @abc.abstractmethod + def shutdown(self) -> None: + """Called when a :class:`opentelemetry.sdk._logs.Logger` is shutdown""" + + @abc.abstractmethod + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Export all the received logs to the configured Exporter that have not yet + been exported. + + Args: + timeout_millis: The maximum amount of time to wait for logs to be + exported. + + Returns: + False if the timeout is exceeded, True otherwise. + """ + + +# Temporary fix until https://github.com/PyCQA/pylint/issues/4098 is resolved +# pylint:disable=no-member +class SynchronousMultiLogRecordProcessor(LogRecordProcessor): + """Implementation of class:`LogRecordProcessor` that forwards all received + events to a list of log processors sequentially. + + The underlying log processors are called in sequential order as they were + added. + """ + + def __init__(self): + # use a tuple to avoid race conditions when adding a new log and + # iterating through it on "emit". + self._log_record_processors = () # type: tuple[LogRecordProcessor, ...] + self._lock = threading.Lock() + + def add_log_record_processor(self, log_record_processor: LogRecordProcessor) -> None: + """Adds a Logprocessor to the list of log processors handled by this instance""" + with self._lock: + self._log_record_processors += (log_record_processor,) + + def on_emit(self, log_record: ReadWriteLogRecord) -> None: + for lp in self._log_record_processors: + lp.on_emit(log_record) + + def enabled( + self, + *, + context: Context | None = None, + instrumentation_scope: InstrumentationScope | None = None, + severity_number: SeverityNumber | None = None, + event_name: str | None = None, + ) -> bool: + processors = self._log_record_processors + return any( + lp.enabled( + context=context, + instrumentation_scope=instrumentation_scope, + severity_number=severity_number, + event_name=event_name, + ) + for lp in processors + ) + + def shutdown(self) -> None: + """Shutdown the log processors one by one""" + for lp in self._log_record_processors: + lp.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Force flush the log processors one by one + + Args: + timeout_millis: The maximum amount of time to wait for logs to be + exported. If the first n log processors exceeded the timeout + then remaining log processors will not be flushed. + + Returns: + True if all the log processors flushes the logs within timeout, + False otherwise. + """ + deadline_ns = time_ns() + timeout_millis * 1000000 + all_flushed = True + for lp in self._log_record_processors: + current_ts = time_ns() + if current_ts >= deadline_ns: + return False + + if lp.force_flush((deadline_ns - current_ts) // 1000000) is False: + all_flushed = False + + return all_flushed + + +class ConcurrentMultiLogRecordProcessor(LogRecordProcessor): + """Implementation of :class:`LogRecordProcessor` that forwards all received + events to a list of log processors in parallel. + + Calls to the underlying log processors are forwarded in parallel by + submitting them to a thread pool executor and waiting until each log + processor finished its work. + + Args: + max_workers: The number of threads managed by the thread pool executor + and thus defining how many log processors can work in parallel. + """ + + def __init__(self, max_workers: int = 2): + # use a tuple to avoid race conditions when adding a new log and + # iterating through it on "emit". + self._log_record_processors = () # type: tuple[LogRecordProcessor, ...] + self._lock = threading.Lock() + self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) + + def add_log_record_processor(self, log_record_processor: LogRecordProcessor): + with self._lock: + self._log_record_processors += (log_record_processor,) + + def _submit_and_wait( + self, + func: Callable[[LogRecordProcessor], Callable[..., None]], + *args: Any, + **kwargs: Any, + ): + futures = [] + for lp in self._log_record_processors: + future = self._executor.submit(func(lp), *args, **kwargs) + futures.append(future) + for future in futures: + future.result() + + def on_emit(self, log_record: ReadWriteLogRecord) -> None: + self._submit_and_wait(lambda lp: lp.on_emit, log_record) + + def enabled( + self, + *, + context: Context | None = None, + instrumentation_scope: InstrumentationScope | None = None, + severity_number: SeverityNumber | None = None, + event_name: str | None = None, + ) -> bool: + processors = self._log_record_processors + return any( + lp.enabled( + context=context, + instrumentation_scope=instrumentation_scope, + severity_number=severity_number, + event_name=event_name, + ) + for lp in processors + ) + + def shutdown(self) -> None: + self._submit_and_wait(lambda lp: lp.shutdown) + + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Force flush the log processors in parallel. + + Args: + timeout_millis: The maximum amount of time to wait for logs to be + exported. + + Returns: + True if all the log processors flushes the logs within timeout, + False otherwise. + """ + futures = [] + for lp in self._log_record_processors: + future = self._executor.submit(lp.force_flush, timeout_millis) + futures.append(future) + + done_futures, not_done_futures = concurrent.futures.wait(futures, timeout_millis / 1e3) + + if not_done_futures: + return False + + for future in done_futures: + if future.result() is False: + return False + + return True + + +# skip natural LogRecord attributes +# http://docs.python.org/library/logging.html#logrecord-attributes +_RESERVED_ATTRS = frozenset( + ( + "asctime", + "args", + "created", + "exc_info", + "exc_text", + "filename", + "funcName", + "getMessage", + "message", + "levelname", + "levelno", + "lineno", + "module", + "msecs", + "msg", + "name", + "pathname", + "process", + "processName", + "relativeCreated", + "stack_info", + "thread", + "threadName", + "taskName", + ) +) + + +class LoggingHandler(logging.Handler): + """A handler class which writes logging records, in OTLP format, to + a network destination or file. Supports signals from the `logging` module. + https://docs.python.org/3/library/logging.html + """ + + def __init__( + self, + level: int = logging.NOTSET, + logger_provider: APILoggerProvider | None = None, + ) -> None: + super().__init__(level=level) + self._logger_provider = logger_provider or get_logger_provider() + + warnings.warn( + "`LoggingHandler` in `opentelemetry-sdk` is deprecated. Use the " + "handler from `opentelemetry-instrumentation-logging` instead.", + DeprecationWarning, + ) + + @staticmethod + def _get_attributes(record: logging.LogRecord) -> Attributes: + attributes = {k: v for k, v in vars(record).items() if k not in _RESERVED_ATTRS} + + # Add standard code attributes for logs. + attributes[code_attributes.CODE_FILE_PATH] = record.pathname + attributes[code_attributes.CODE_FUNCTION_NAME] = record.funcName + attributes[code_attributes.CODE_LINE_NUMBER] = record.lineno + + if record.exc_info: + exctype, value, tb = record.exc_info + if exctype is not None: + attributes[exception_attributes.EXCEPTION_TYPE] = exctype.__name__ + if value is not None and value.args: + attributes[exception_attributes.EXCEPTION_MESSAGE] = str(value.args[0]) + if tb is not None: + # https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#stacktrace-representation + attributes[exception_attributes.EXCEPTION_STACKTRACE] = "".join( + traceback.format_exception(*record.exc_info) + ) + return attributes + + def _translate(self, record: logging.LogRecord) -> LogRecord: + timestamp = int(record.created * 1e9) + observered_timestamp = time_ns() + attributes = self._get_attributes(record) + severity_number = std_to_otel(record.levelno) + if self.formatter: + body = self.format(record) + else: + # `record.getMessage()` uses `record.msg` as a template to format + # `record.args` into. There is a special case in `record.getMessage()` + # where it will only attempt formatting if args are provided, + # otherwise, it just stringifies `record.msg`. + # + # Since the OTLP body field has a type of 'any' and the logging module + # is sometimes used in such a way that objects incorrectly end up + # set as record.msg, in those cases we would like to bypass + # `record.getMessage()` completely and set the body to the object + # itself instead of its string representation. + # For more background, see: https://github.com/open-telemetry/opentelemetry-python/pull/4216 + if not record.args and not isinstance(record.msg, str): + # if record.msg is not a value we can export, cast it to string + # TODO: https://github.com/open-telemetry/opentelemetry-python/issues/5304 - do something better + # than just casting to a string. + if not isinstance( + record.msg, + ( + NoneType, + bool, + bytes, + int, + float, + str, + Sequence, + Mapping, + ), + ): + body = str(record.msg) + else: + body = record.msg + else: + body = record.getMessage() + + # Map Python log level names to OTel severity text as defined in + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#displaying-severity + # Python "WARNING" -> OTel "WARN" (see #3548) + # Python "CRITICAL" -> OTel "FATAL" (see #4984) + _python_to_otel_severity_text = { + "WARNING": "WARN", + "CRITICAL": "FATAL", + } + level_name = _python_to_otel_severity_text.get(record.levelname, record.levelname) + + return LogRecord( + timestamp=timestamp, + observed_timestamp=observered_timestamp, + context=get_current() or None, + severity_text=level_name, + severity_number=severity_number, + body=body, + attributes=attributes, + ) + + def emit(self, record: logging.LogRecord) -> None: + """ + Emit a record. Skip emitting if logger is NoOp. + + The record is translated to OTel format, and then sent across the pipeline. + """ + logger = get_logger(record.name, logger_provider=self._logger_provider) + if not isinstance(logger, NoOpLogger): + logger.emit(self._translate(record)) + + def flush(self) -> None: + """ + Flushes the logging output. Skip flushing if logging_provider has no force_flush method. + """ + if hasattr(self._logger_provider, "force_flush") and callable( + self._logger_provider.force_flush # type: ignore[reportAttributeAccessIssue] + ): + # This is done in a separate thread to avoid a potential deadlock, for + # details see https://github.com/open-telemetry/opentelemetry-python/pull/4636. + thread = threading.Thread(target=self._logger_provider.force_flush) # type: ignore[reportAttributeAccessIssue] + thread.start() + + +@dataclass +class _LoggerConfig: + is_enabled: bool = True + + @classmethod + def default(cls) -> _LoggerConfig: + return _LoggerConfig() + + +class Logger(APILogger): + def __init__( + self, + resource: Resource, + multi_log_record_processor: SynchronousMultiLogRecordProcessor | ConcurrentMultiLogRecordProcessor, + instrumentation_scope: InstrumentationScope, + *, + logger_metrics: LoggerMetricsT, + log_record_limits: LogRecordLimits | None = None, + _logger_config: _LoggerConfig, + ): + super().__init__( + instrumentation_scope.name, + instrumentation_scope.version, + instrumentation_scope.schema_url, + instrumentation_scope.attributes, + ) + self._resource = resource + self._multi_log_record_processor = multi_log_record_processor + self._instrumentation_scope = instrumentation_scope + self._logger_metrics = logger_metrics + self._logger_config = _logger_config + self._log_record_limits = log_record_limits or LogRecordLimits() + + def _is_enabled(self) -> bool: + return self._logger_config.is_enabled + + def enabled( + self, + *, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + event_name: str | None = None, + ) -> bool: + if not self._is_enabled(): + return False + return self._multi_log_record_processor.enabled( + context=context, + instrumentation_scope=self._instrumentation_scope, + severity_number=severity_number, + event_name=event_name, + ) + + def _set_logger_config(self, logger_config: _LoggerConfig) -> None: + self._logger_config = logger_config + + def _set_resource(self, resource: Resource) -> None: + self._resource = resource + + @property + def instrumentation_scope(self): + return self._instrumentation_scope + + @property + def resource(self): + return self._resource + + # pylint: disable=arguments-differ + def emit( + self, + record: LogRecord | None = None, + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context: Context | None = None, + severity_number: SeverityNumber | None = None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, + ) -> None: + """Emits the :class:`ReadWriteLogRecord` by setting instrumentation scope + and forwarding to the processor. + """ + if not self._is_enabled(): + return + # If a record is provided, use it directly + if record is not None: + if not isinstance(record, ReadWriteLogRecord): + if record.exception is not None: + record = _copy_log_record_with_exception(record) + # pylint:disable=protected-access + writable_record = ReadWriteLogRecord._from_api_log_record( + record=record, + resource=self._resource, + instrumentation_scope=self._instrumentation_scope, + limits=self._log_record_limits, + ) + else: + _set_log_record_exception_attributes(record.log_record) + writable_record = record + else: + # Create a record from individual parameters + log_record = _create_log_record_with_exception( + timestamp=timestamp, + observed_timestamp=observed_timestamp, + context=context, + severity_number=severity_number, + severity_text=severity_text, + body=body, + attributes=attributes, + event_name=event_name, + exception=exception, + ) + # pylint:disable=protected-access + writable_record = ReadWriteLogRecord._from_api_log_record( + record=log_record, + resource=self._resource, + instrumentation_scope=self._instrumentation_scope, + limits=self._log_record_limits, + ) + + self._logger_metrics.emit_log() + self._multi_log_record_processor.on_emit(writable_record) + + +_LoggerConfiguratorT = Callable[[InstrumentationScope], _LoggerConfig] +_RuleBasedLoggerConfigurator = RuleBasedConfigurator[_LoggerConfig] + + +def _default_logger_configurator( + _logger_scope: InstrumentationScope, +) -> _LoggerConfig: + return _LoggerConfig.default() + + +def _disable_logger_configurator( + _logger_scope: InstrumentationScope, +) -> _LoggerConfig: + return _LoggerConfig(is_enabled=False) + + +class LoggerProvider(APILoggerProvider): + def __init__( + self, + resource: Resource | None = None, + shutdown_on_exit: bool = True, + multi_log_record_processor: SynchronousMultiLogRecordProcessor + | ConcurrentMultiLogRecordProcessor + | None = None, + *, + meter_provider: MeterProvider | None = None, + log_record_limits: LogRecordLimits | None = None, + _logger_configurator: _LoggerConfiguratorT | None = None, + ): + if resource is None: + self._resource = Resource.create({}) + else: + self._resource = resource + self._multi_log_record_processor = multi_log_record_processor or SynchronousMultiLogRecordProcessor() + self._logger_metrics = create_logger_metrics( + meter_provider or get_meter_provider(), + parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ) + disabled = environ.get(OTEL_SDK_DISABLED, "") + self._disabled = disabled.lower().strip() == "true" + self._logger_configurator = _logger_configurator or _default_logger_configurator + self._log_record_limits = log_record_limits or LogRecordLimits() + self._at_exit_handler = None + if shutdown_on_exit: + self._at_exit_handler = atexit.register(self.shutdown) + self._logger_cache = {} + self._logger_cache_lock = Lock() + self._active_loggers: WeakSet[Logger] = WeakSet() + self._active_loggers_lock = Lock() + if hasattr(os, "register_at_fork"): + weak_at_fork = WeakMethod(self._handle_fork) + + def _after_in_child() -> None: + if at_fork := weak_at_fork(): + at_fork() + + os.register_at_fork(after_in_child=_after_in_child) + + def _handle_fork(self) -> None: + self._logger_cache_lock = Lock() + self._active_loggers_lock = Lock() + self._update_resource(_get_process_dependent_resource()) + + @property + def resource(self): + return self._resource + + def _update_resource(self, resource: Resource) -> None: + with self._active_loggers_lock: + self._resource = self._resource.merge(resource) + for logger in list(self._active_loggers): + # pylint: disable-next=protected-access + logger._set_resource(self._resource) + + def _get_logger_no_cache( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> Logger: + scope = InstrumentationScope(name, version, schema_url, attributes) + + return Logger( + self._resource, + self._multi_log_record_processor, + scope, + logger_metrics=self._logger_metrics, + _logger_config=self._apply_logger_configurator(scope), + log_record_limits=self._log_record_limits, + ) + + def _get_logger_cached( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + ) -> Logger: + with self._logger_cache_lock: + key = (name, version, schema_url) + if key in self._logger_cache: + return self._logger_cache[key] + + self._logger_cache[key] = self._get_logger_no_cache(name, version, schema_url) + return self._logger_cache[key] + + def get_logger( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> APILogger: + if self._disabled: + return NoOpLogger( + name, + version=version, + schema_url=schema_url, + attributes=attributes, + ) + logger = ( + self._get_logger_cached(name, version, schema_url) + if attributes is None + else self._get_logger_no_cache(name, version, schema_url, attributes) + ) + with self._active_loggers_lock: + self._active_loggers.add(logger) + return logger + + def add_log_record_processor(self, log_record_processor: LogRecordProcessor): + """Registers a new :class:`LogRecordProcessor` for this `LoggerProvider` instance. + + The log processors are invoked in the same order they are registered. + """ + self._multi_log_record_processor.add_log_record_processor(log_record_processor) + + def _set_logger_configurator(self, *, logger_configurator: _LoggerConfiguratorT): + """Set a new LoggerConfigurator for this LoggerProvider. + + Setting a new LoggerConfigurator will result in the configurator being called + for each outstanding Logger and for any newly created loggers thereafter. + Therefore, it is important that the provided function returns quickly. + """ + self._logger_configurator = logger_configurator + with self._active_loggers_lock: + for logger in list(self._active_loggers): + # pylint: disable-next=protected-access + logger._set_logger_config(self._apply_logger_configurator(logger.instrumentation_scope)) + + def _apply_logger_configurator(self, instrumentation_scope: InstrumentationScope) -> _LoggerConfig: + try: + return self._logger_configurator(instrumentation_scope) + # pylint: disable-next=broad-exception-caught + except Exception: + _logger.exception( + "logger configurator failed for scope '%s', using default config", + instrumentation_scope.name, + ) + return _LoggerConfig.default() + + def shutdown(self) -> None: + """Shuts down the log processors.""" + self._multi_log_record_processor.shutdown() + if self._at_exit_handler is not None: + atexit.unregister(self._at_exit_handler) + self._at_exit_handler = None + + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Force flush the log processors. + + Args: + timeout_millis: The maximum amount of time to wait for logs to be + exported. + + Returns: + True if all the log processors flushes the logs within timeout, + False otherwise. + """ + return self._multi_log_record_processor.force_flush(timeout_millis) + + +_STD_TO_OTEL = { + 10: SeverityNumber.DEBUG, + 11: SeverityNumber.DEBUG2, + 12: SeverityNumber.DEBUG3, + 13: SeverityNumber.DEBUG4, + 14: SeverityNumber.DEBUG4, + 15: SeverityNumber.DEBUG4, + 16: SeverityNumber.DEBUG4, + 17: SeverityNumber.DEBUG4, + 18: SeverityNumber.DEBUG4, + 19: SeverityNumber.DEBUG4, + 20: SeverityNumber.INFO, + 21: SeverityNumber.INFO2, + 22: SeverityNumber.INFO3, + 23: SeverityNumber.INFO4, + 24: SeverityNumber.INFO4, + 25: SeverityNumber.INFO4, + 26: SeverityNumber.INFO4, + 27: SeverityNumber.INFO4, + 28: SeverityNumber.INFO4, + 29: SeverityNumber.INFO4, + 30: SeverityNumber.WARN, + 31: SeverityNumber.WARN2, + 32: SeverityNumber.WARN3, + 33: SeverityNumber.WARN4, + 34: SeverityNumber.WARN4, + 35: SeverityNumber.WARN4, + 36: SeverityNumber.WARN4, + 37: SeverityNumber.WARN4, + 38: SeverityNumber.WARN4, + 39: SeverityNumber.WARN4, + 40: SeverityNumber.ERROR, + 41: SeverityNumber.ERROR2, + 42: SeverityNumber.ERROR3, + 43: SeverityNumber.ERROR4, + 44: SeverityNumber.ERROR4, + 45: SeverityNumber.ERROR4, + 46: SeverityNumber.ERROR4, + 47: SeverityNumber.ERROR4, + 48: SeverityNumber.ERROR4, + 49: SeverityNumber.ERROR4, + 50: SeverityNumber.FATAL, + 51: SeverityNumber.FATAL2, + 52: SeverityNumber.FATAL3, + 53: SeverityNumber.FATAL4, +} + + +def std_to_otel(levelno: int) -> SeverityNumber: + """ + Map python log levelno as defined in https://docs.python.org/3/library/logging.html#logging-levels + to OTel log severity number as defined here: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber + """ + if levelno < 10: + return SeverityNumber.UNSPECIFIED + if levelno > 53: + return SeverityNumber.FATAL4 + return _STD_TO_OTEL[levelno] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py new file mode 100644 index 00000000000..de5132e91af --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py @@ -0,0 +1,114 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import traceback + +from opentelemetry.agent._vendor.opentelemetry._logs import LogRecord +from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes import exception_attributes +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes + + +def _get_exception_attributes( + exception: BaseException, +) -> dict[str, AnyValue]: + stacktrace = "".join(traceback.format_exception(type(exception), value=exception, tb=exception.__traceback__)) + module = type(exception).__module__ + qualname = type(exception).__qualname__ + exception_type = f"{module}.{qualname}" if module and module != "builtins" else qualname + return { + exception_attributes.EXCEPTION_TYPE: exception_type, + exception_attributes.EXCEPTION_MESSAGE: str(exception), + exception_attributes.EXCEPTION_STACKTRACE: stacktrace, + } + + +def _get_attributes_with_exception( + attributes: Attributes, + exception: BaseException | None, +) -> Attributes: + if exception is None: + return attributes + + exception_attributes_map = _get_exception_attributes(exception) + if attributes is None: + attributes_map: Attributes = {} + else: + attributes_map = attributes + + if isinstance(attributes_map, BoundedAttributes): + bounded_attributes = attributes_map + merged = BoundedAttributes( + maxlen=bounded_attributes.maxlen, + attributes=bounded_attributes, + immutable=False, + max_value_len=bounded_attributes.max_value_len, + ) + merged.dropped = bounded_attributes.dropped + for key, value in exception_attributes_map.items(): + if key not in merged: + merged[key] = value + return merged + + return exception_attributes_map | dict(attributes_map.items()) + + +def _copy_log_record( + record: LogRecord, + attributes: Attributes, +) -> LogRecord: + copied_record = LogRecord( + timestamp=record.timestamp, + observed_timestamp=record.observed_timestamp, + context=record.context, + severity_text=record.severity_text, + severity_number=record.severity_number, + body=record.body, + attributes=attributes, + event_name=record.event_name, + exception=getattr(record, "exception", None), + ) + copied_record.trace_id = record.trace_id + copied_record.span_id = record.span_id + copied_record.trace_flags = record.trace_flags + return copied_record + + +def _copy_log_record_with_exception(record: LogRecord) -> LogRecord: + return _copy_log_record( + record, + _get_attributes_with_exception(record.attributes, record.exception), + ) + + +def _set_log_record_exception_attributes(record: LogRecord) -> None: + record.attributes = _get_attributes_with_exception( + record.attributes, + record.exception, + ) + + +def _create_log_record_with_exception( + *, + timestamp: int | None = None, + observed_timestamp: int | None = None, + context=None, + severity_number=None, + severity_text: str | None = None, + body: AnyValue | None = None, + attributes: Attributes = None, + event_name: str | None = None, + exception: BaseException | None = None, +) -> LogRecord: + return LogRecord( + timestamp=timestamp, + observed_timestamp=observed_timestamp, + context=context, + severity_number=severity_number, + severity_text=severity_text, + body=body, + attributes=_get_attributes_with_exception(attributes, exception), + event_name=event_name, + exception=exception, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py new file mode 100644 index 00000000000..3eb224c8565 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py @@ -0,0 +1,37 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Protocol + +from opentelemetry.agent._vendor.opentelemetry import metrics as metrics_api +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( + create_otel_sdk_log_created, +) + + +class LoggerMetricsT(Protocol): + def emit_log(self) -> None: ... + + +class NoOpLoggerMetrics: + def emit_log(self) -> None: + pass + + +class LoggerMetrics: + def __init__(self, meter_provider: metrics_api.MeterProvider) -> None: + meter = meter_provider.get_meter("opentelemetry-sdk") + self._created_logs = create_otel_sdk_log_created(meter) + + def emit_log(self) -> None: + self._created_logs.add(1) + + +def create_logger_metrics( + meter_provider: metrics_api.MeterProvider, + enabled: bool, +) -> LoggerMetricsT: + if not enabled: + return NoOpLoggerMetrics() + + return LoggerMetrics(meter_provider) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py new file mode 100644 index 00000000000..dc790f59b0d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py @@ -0,0 +1,392 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import abc +import copy +import enum +import logging +import sys +from collections.abc import Callable, Sequence +from os import environ, linesep +from typing import IO + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry.context import ( + _ON_EMIT_RECURSION_COUNT_KEY, + _SUPPRESS_INSTRUMENTATION_KEY, + Context, + attach, + detach, + get_value, + set_value, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ( + LogRecordProcessor, + ReadableLogRecord, + ReadWriteLogRecord, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import ( + BatchProcessor, + DuplicateFilter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal._processor_metrics import ( + create_processor_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_BLRP_EXPORT_TIMEOUT, + OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, + OTEL_BLRP_MAX_QUEUE_SIZE, + OTEL_BLRP_SCHEDULE_DELAY, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( + parse_boolean_environment_variable, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OtelComponentTypeValues, +) + +_DEFAULT_SCHEDULE_DELAY_MILLIS = 1000 +_DEFAULT_MAX_EXPORT_BATCH_SIZE = 512 +_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 +_DEFAULT_MAX_QUEUE_SIZE = 2048 +_ENV_VAR_INT_VALUE_ERROR_MESSAGE = "Unable to parse value for %s as integer. Defaulting to %s." +_logger = logging.getLogger(__name__) +_logger.addFilter(DuplicateFilter()) + +_propagate_false_logger = logging.getLogger(__name__ + ".propagate.false") +_propagate_false_logger.propagate = False + + +class LogRecordExportResult(enum.Enum): + SUCCESS = 0 + FAILURE = 1 + + +@deprecated("Use LogRecordExportResult. Since logs are not stable yet this WILL be removed in future releases.") +class LogExportResult(enum.Enum): + SUCCESS = 0 + FAILURE = 1 + + +class LogRecordExporter(abc.ABC): + """Interface for exporting logs. + + Interface to be implemented by services that want to export logs received + in their own format. + + To export data this MUST be registered to the :class:`opentelemetry.sdk._logs.Logger` + using a log processor. + + Important + --------- + The ``export()`` method may raise exceptions (e.g., network errors, + timeouts, serialization errors). It is the responsibility of the + ``LogRecordProcessor`` calling this exporter to handle these exceptions + appropriately to prevent application crashes. See ``LogRecordProcessor`` + for guidance on implementing proper error handling. + """ + + @abc.abstractmethod + def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: + """Exports a batch of logs. + + Args: + batch: The list of ``ReadableLogRecord`` objects to be exported. + + Returns: + The result of the export. + + Raises: + Exception: This method may raise exceptions on network errors, + timeouts, or other failures. Callers (i.e., log processors) + should handle these exceptions to comply with OpenTelemetry + error handling principles. + """ + + @abc.abstractmethod + def shutdown(self): + """Shuts down the exporter. + + Called when the SDK is shut down. + """ + + @abc.abstractmethod + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Hint to ensure that the export of any ``ReadableLogRecord`` objects + the exporter has received prior to the call to ``force_flush`` SHOULD be + completed as soon as possible, preferably before returning from this method. + + Args: + timeout_millis: The maximum amount of time to wait for the flush to + complete, in milliseconds. + + Returns: + ``True`` if the flush completed successfully within the timeout, + ``False`` otherwise. + """ + + +@deprecated("Use LogRecordExporter. Since logs are not stable yet this WILL be removed in future releases.") +class LogExporter(LogRecordExporter): + pass + + +class ConsoleLogRecordExporter(LogRecordExporter): + """Implementation of :class:`LogRecordExporter` that prints log records to the + console. + + This class can be used for diagnostic purposes. It prints the exported + log records to the console STDOUT. + """ + + def __init__( + self, + out: IO = sys.stdout, + formatter: Callable[[ReadableLogRecord], str] = lambda record: record.to_json() + linesep, + ): + self.out = out + self.formatter = formatter + + def export(self, batch: Sequence[ReadableLogRecord]): + for log_record in batch: + self.out.write(self.formatter(log_record)) + self.out.flush() + return LogRecordExportResult.SUCCESS + + def shutdown(self): + pass + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return True + + +@deprecated("Use ConsoleLogRecordExporter. Since logs are not stable yet this WILL be removed in future releases.") +class ConsoleLogExporter(ConsoleLogRecordExporter): + pass + + +class SimpleLogRecordProcessor(LogRecordProcessor): + """Implementation of LogRecordProcessor that exports logs synchronously. + + This processor passes received logs directly to the configured + ``LogRecordExporter`` as soon as they are emitted. + + This class serves as a reference implementation for custom log processors, + demonstrating proper error handling. Note how the ``on_emit`` method wraps + the exporter call in a try/except block to prevent exceptions from + propagating to the application. + """ + + def __init__( + self, + exporter: LogRecordExporter, + *, + meter_provider: MeterProvider | None = None, + ): + self._exporter = exporter + self._shutdown = False + self._metrics = create_processor_metrics( + "logs", + OtelComponentTypeValues.SIMPLE_LOG_PROCESSOR, + meter_provider or get_meter_provider(), + enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ) + + def on_emit(self, log_record: ReadWriteLogRecord): + # Prevent entering a recursive loop. + cnt = get_value(_ON_EMIT_RECURSION_COUNT_KEY) or 0 + # Recursive depth of 3 is sort of arbitrary. It's possible that an Exporter.export call + # emits a log which returns us to this function, but when we call Exporter.export again the log + # is no longer emitted and we exit this recursive loop naturally, a depth of >3 allows 3 + # recursive log calls but exits after because it's likely endless. + if cnt > 3: # pyright: ignore[reportOperatorIssue] + _propagate_false_logger.warning( + "SimpleLogRecordProcessor.on_emit has entered a recursive loop. Dropping log and exiting the loop." + ) + return + token = attach( + set_value( + _SUPPRESS_INSTRUMENTATION_KEY, + True, + set_value(_ON_EMIT_RECURSION_COUNT_KEY, cnt + 1), # pyright: ignore[reportOperatorIssue] + ) + ) + try: + if self._shutdown: + _logger.warning("Processor is already shutdown, ignoring call") + self._metrics.drop_items(1, "already_shutdown") + return + # Convert ReadWriteLogRecord to ReadableLogRecord before exporting + # Note: resource should not be None at this point as it's set during Logger.emit() + resource = log_record.resource if log_record.resource is not None else Resource.create({}) + readable_log_record = ReadableLogRecord( + log_record=log_record.log_record, + resource=resource, + instrumentation_scope=log_record.instrumentation_scope, + limits=log_record.limits, + ) + # Record on submission to the exporter. + self._metrics.finish_items(1) + self._exporter.export((readable_log_record,)) + except Exception: # pylint: disable=broad-exception-caught + _logger.exception("Exception while exporting logs.") + finally: + detach(token) + + def shutdown(self): + self._shutdown = True + self._exporter.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: # pylint: disable=no-self-use + return True + + +class BatchLogRecordProcessor(LogRecordProcessor): + """This is an implementation of LogRecordProcessor which creates batches of + received logs and sends them to the configured LogRecordExporter. + + `BatchLogRecordProcessor` is configurable with the following environment + variables which correspond to constructor parameters: + + - :envvar:`OTEL_BLRP_SCHEDULE_DELAY` + - :envvar:`OTEL_BLRP_MAX_QUEUE_SIZE` + - :envvar:`OTEL_BLRP_MAX_EXPORT_BATCH_SIZE` + - :envvar:`OTEL_BLRP_EXPORT_TIMEOUT` + + All the logic for emitting logs, shutting down etc. resides in the BatchProcessor class. + """ + + def __init__( + self, + exporter: LogRecordExporter, + schedule_delay_millis: float | None = None, + max_export_batch_size: int | None = None, + export_timeout_millis: float | None = None, + max_queue_size: int | None = None, + *, + meter_provider: MeterProvider | None = None, + ): + if max_queue_size is None: + max_queue_size = BatchLogRecordProcessor._default_max_queue_size() + + if schedule_delay_millis is None: + schedule_delay_millis = BatchLogRecordProcessor._default_schedule_delay_millis() + + if max_export_batch_size is None: + max_export_batch_size = BatchLogRecordProcessor._default_max_export_batch_size() + # Not used. No way currently to pass timeout to export. + if export_timeout_millis is None: + export_timeout_millis = BatchLogRecordProcessor._default_export_timeout_millis() + + BatchLogRecordProcessor._validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size) + # Initializes BatchProcessor + self._batch_processor = BatchProcessor( + exporter, + schedule_delay_millis, + max_export_batch_size, + export_timeout_millis, + max_queue_size, + "Log", + create_processor_metrics( + "logs", + OtelComponentTypeValues.BATCHING_LOG_PROCESSOR, + meter_provider or get_meter_provider(), + capacity=max_queue_size, + enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ), + ) + + def on_emit(self, log_record: ReadWriteLogRecord) -> None: + # Convert ReadWriteLogRecord to ReadableLogRecord before passing to BatchProcessor + # Note: resource should not be None at this point as it's set during Logger.emit() + resource = log_record.resource if log_record.resource is not None else Resource.create({}) + # Shallow copy the API log record to break the reference to the potentially large context + # while keeping the original context intact for other processors. + api_log_record = copy.copy(log_record.log_record) + api_log_record.context = Context() + + readable_log_record = ReadableLogRecord( + log_record=api_log_record, + resource=resource, + instrumentation_scope=log_record.instrumentation_scope, + limits=log_record.limits, + ) + return self._batch_processor.emit(readable_log_record) + + def shutdown(self): + return self._batch_processor.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return self._batch_processor.force_flush(timeout_millis) + + @staticmethod + def _default_max_queue_size(): + try: + return int(environ.get(OTEL_BLRP_MAX_QUEUE_SIZE, _DEFAULT_MAX_QUEUE_SIZE)) + except ValueError: + _logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BLRP_MAX_QUEUE_SIZE, + _DEFAULT_MAX_QUEUE_SIZE, + ) + return _DEFAULT_MAX_QUEUE_SIZE + + @staticmethod + def _default_schedule_delay_millis(): + try: + return int(environ.get(OTEL_BLRP_SCHEDULE_DELAY, _DEFAULT_SCHEDULE_DELAY_MILLIS)) + except ValueError: + _logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BLRP_SCHEDULE_DELAY, + _DEFAULT_SCHEDULE_DELAY_MILLIS, + ) + return _DEFAULT_SCHEDULE_DELAY_MILLIS + + @staticmethod + def _default_max_export_batch_size(): + try: + return int( + environ.get( + OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, + _DEFAULT_MAX_EXPORT_BATCH_SIZE, + ) + ) + except ValueError: + _logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, + _DEFAULT_MAX_EXPORT_BATCH_SIZE, + ) + return _DEFAULT_MAX_EXPORT_BATCH_SIZE + + @staticmethod + def _default_export_timeout_millis(): + try: + return int(environ.get(OTEL_BLRP_EXPORT_TIMEOUT, _DEFAULT_EXPORT_TIMEOUT_MILLIS)) + except ValueError: + _logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BLRP_EXPORT_TIMEOUT, + _DEFAULT_EXPORT_TIMEOUT_MILLIS, + ) + return _DEFAULT_EXPORT_TIMEOUT_MILLIS + + @staticmethod + def _validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size): + if max_queue_size <= 0: + raise ValueError("max_queue_size must be a positive integer.") + + if schedule_delay_millis <= 0: + raise ValueError("schedule_delay_millis must be positive.") + + if max_export_batch_size <= 0: + raise ValueError("max_export_batch_size must be a positive integer.") + + if max_export_batch_size > max_queue_size: + raise ValueError("max_export_batch_size must be less than or equal to max_queue_size.") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py new file mode 100644 index 00000000000..2ece1662393 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py @@ -0,0 +1,53 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import collections.abc +import threading + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord +from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( + LogRecordExporter, + LogRecordExportResult, +) + + +class InMemoryLogRecordExporter(LogRecordExporter): + """Implementation of :class:`.LogRecordExporter` that stores logs in memory. + + This class can be used for testing purposes. It stores the exported logs + in a list in memory that can be retrieved using the + :meth:`.get_finished_logs` method. + """ + + def __init__(self): + self._logs = [] + self._lock = threading.Lock() + self._stopped = False + + def clear(self) -> None: + with self._lock: + self._logs.clear() + + def get_finished_logs(self) -> tuple[ReadableLogRecord, ...]: + with self._lock: + return tuple(self._logs) + + def export(self, batch: collections.abc.Sequence[ReadableLogRecord]) -> LogRecordExportResult: + if self._stopped: + return LogRecordExportResult.FAILURE + with self._lock: + self._logs.extend(batch) + return LogRecordExportResult.SUCCESS + + def shutdown(self) -> None: + self._stopped = True + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return True + + +@deprecated("Use InMemoryLogRecordExporter. Since logs are not stable yet this WILL be removed in future releases.") +class InMemoryLogExporter(InMemoryLogRecordExporter): + pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py new file mode 100644 index 00000000000..323ccbd3ac4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py @@ -0,0 +1,32 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal.export import ( + BatchLogRecordProcessor, + ConsoleLogExporter, + ConsoleLogRecordExporter, + LogExporter, + LogExportResult, + LogRecordExporter, + LogRecordExportResult, + SimpleLogRecordProcessor, +) + +# The point module is not in the export directory to avoid a circular import. +from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal.export.in_memory_log_exporter import ( + InMemoryLogExporter, + InMemoryLogRecordExporter, +) + +__all__ = [ + "BatchLogRecordProcessor", + "ConsoleLogExporter", + "ConsoleLogRecordExporter", + "InMemoryLogExporter", + "InMemoryLogRecordExporter", + "LogExportResult", + "LogExporter", + "LogRecordExportResult", + "LogRecordExporter", + "SimpleLogRecordProcessor", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py new file mode 100644 index 00000000000..daddc95be68 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py @@ -0,0 +1,237 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import collections +import enum +import inspect +import logging +import os +import threading +import time +import weakref +from abc import abstractmethod +from typing import ( + Generic, + Protocol, + TypeVar, +) + +from opentelemetry.agent._vendor.opentelemetry.context import ( + _SUPPRESS_INSTRUMENTATION_KEY, + attach, + detach, + set_value, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal._processor_metrics import ( + ProcessorMetricsT, +) +from opentelemetry.agent._vendor.opentelemetry.util._once import Once + + +class DuplicateFilter(logging.Filter): + """Filter that can be applied to internal `logger`'s. + + Currently applied to `logger`s on the export logs path to prevent endlessly logging the same log + in cases where logging itself is failing.""" + + def filter(self, record): + current_log = ( + record.module, + record.levelno, + record.msg, + # We need to pick a time longer than the OTLP LogExporter timeout + # which defaults to 10 seconds, but not pick something so long that + # it filters out useful logs. + time.time() // 20, + ) + if current_log != getattr(self, "last_log", None): + self.last_log = current_log # pylint: disable=attribute-defined-outside-init + return True + # False means python's `logging` module will no longer process this log. + return False + + +class BatchExportStrategy(enum.Enum): + EXPORT_ALL = 0 + EXPORT_WHILE_BATCH_EXCEEDS_THRESHOLD = 1 + EXPORT_AT_LEAST_ONE_BATCH = 2 + + +Telemetry = TypeVar("Telemetry") + + +class Exporter(Protocol[Telemetry]): + @abstractmethod + def export(self, batch: list[Telemetry], /): + raise NotImplementedError + + @abstractmethod + def shutdown(self): + raise NotImplementedError + + +_logger = logging.getLogger(__name__) +_logger.addFilter(DuplicateFilter()) + + +class BatchProcessor(Generic[Telemetry]): + """This class can be used with exporter's that implement the above + Exporter interface to buffer and send telemetry in batch through + the exporter.""" + + def __init__( + self, + exporter: Exporter[Telemetry], + schedule_delay_millis: float, + max_export_batch_size: int, + export_timeout_millis: float, + max_queue_size: int, + exporting: str, + metrics: ProcessorMetricsT, + ): + self._bsp_reset_once = Once() + self._exporter = exporter + self._max_queue_size = max_queue_size + self._schedule_delay_millis = schedule_delay_millis + self._schedule_delay = schedule_delay_millis / 1e3 + self._max_export_batch_size = max_export_batch_size + # Not used. No way currently to pass timeout to export. + # TODO(https://github.com/open-telemetry/opentelemetry-python/issues/4555): figure out what this should do. + self._export_timeout_millis = export_timeout_millis + # Deque is thread safe. + self._queue = collections.deque([], max_queue_size) + self._worker_thread = threading.Thread( + name=f"OtelBatch{exporting}RecordProcessor", + target=self.worker, + daemon=True, + ) + self._exporting = exporting + + self._shutdown = False + self._shutdown_timeout_exceeded = False + self._export_lock = threading.Lock() + self._worker_awaken = threading.Event() + self._worker_thread.start() + if hasattr(os, "register_at_fork"): + weak_reinit = weakref.WeakMethod(self._at_fork_reinit) + + def _after_in_child() -> None: + if reinit := weak_reinit(): + reinit() + + os.register_at_fork(after_in_child=_after_in_child) + self._pid = os.getpid() + + metrics.register_queue_size(lambda: len(self._queue)) + self._metrics = metrics + + def _should_export_batch(self, batch_strategy: BatchExportStrategy, num_iterations: int) -> bool: + if not self._queue or self._shutdown_timeout_exceeded: + return False + # Always continue to export while queue length exceeds max batch size. + if len(self._queue) >= self._max_export_batch_size: + return True + if batch_strategy is BatchExportStrategy.EXPORT_ALL: + return True + if batch_strategy is BatchExportStrategy.EXPORT_AT_LEAST_ONE_BATCH: + return num_iterations == 0 + return False + + def _at_fork_reinit(self): + self._export_lock = threading.Lock() + self._worker_awaken = threading.Event() + self._queue.clear() + self._worker_thread = threading.Thread( + name=f"OtelBatch{self._exporting}RecordProcessor", + target=self.worker, + daemon=True, + ) + self._worker_thread.start() + self._pid = os.getpid() + + def worker(self): + while not self._shutdown: + # Lots of strategies in the spec for setting next timeout. + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#batching-processor. + # Shutdown will interrupt this sleep. Emit will interrupt this sleep only if the queue is bigger then threshold. + sleep_interrupted = self._worker_awaken.wait(self._schedule_delay) + if self._shutdown: + break + self._export( + BatchExportStrategy.EXPORT_WHILE_BATCH_EXCEEDS_THRESHOLD + if sleep_interrupted + else BatchExportStrategy.EXPORT_AT_LEAST_ONE_BATCH + ) + self._worker_awaken.clear() + self._export(BatchExportStrategy.EXPORT_ALL) + + def _export(self, batch_strategy: BatchExportStrategy) -> None: + with self._export_lock: + iteration = 0 + # We could see concurrent export calls from worker and force_flush. We call _should_export_batch + # once the lock is obtained to see if we still need to make the requested export. + while self._should_export_batch(batch_strategy, iteration): + iteration += 1 + token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) + count = min( + self._max_export_batch_size, + len(self._queue), + ) + # Oldest records are at the back, so pop from there. + batch = [self._queue.pop() for _ in range(count)] + # Record on submission to the exporter. + self._metrics.finish_items(count) + try: + self._exporter.export(batch) + except Exception: # pylint: disable=broad-exception-caught + _logger.exception("Exception while exporting %s.", self._exporting) + detach(token) + + def emit(self, data: Telemetry) -> None: + if self._shutdown: + _logger.info("Shutdown called, ignoring %s.", self._exporting) + self._metrics.drop_items(1, "already_shutdown") + return + if self._pid != os.getpid(): + self._bsp_reset_once.do_once(self._at_fork_reinit) + if len(self._queue) == self._max_queue_size: + _logger.warning("Queue full, dropping %s.", self._exporting) + self._metrics.drop_items(1) + # This will drop a log from the right side if the queue is at _max_queue_size. + self._queue.appendleft(data) + if len(self._queue) >= self._max_export_batch_size and not self._worker_awaken.is_set(): + self._worker_awaken.set() + + def shutdown(self, timeout_millis: int = 30000): + if self._shutdown: + return + shutdown_should_end = time.time() + (timeout_millis / 1000) + # Causes emit to reject telemetry and makes force_flush a no-op. + self._shutdown = True + # Interrupts sleep in the worker if it's sleeping. + self._worker_awaken.set() + self._worker_thread.join(timeout_millis / 1000) + # Stops worker thread from calling export again if queue is still not empty. + self._shutdown_timeout_exceeded = True + # We want to shutdown immediately only if we already waited `timeout_secs`. + # Otherwise we pass the remaining timeout to the exporter. + # Some exporter's shutdown support a timeout param. + if "timeout_millis" in inspect.getfullargspec(self._exporter.shutdown).args: + remaining_millis = (shutdown_should_end - time.time()) * 1000 + self._exporter.shutdown(timeout_millis=max(0, remaining_millis)) # type: ignore + else: + self._exporter.shutdown() + # Worker thread **should** be finished at this point, because we called shutdown on the exporter, + # and set shutdown_is_occuring to prevent further export calls. It's possible that a single export + # call is ongoing and the thread isn't finished. In this case we will return instead of waiting on + # the thread to finish. + + # TODO: Fix force flush so the timeout is used https://github.com/open-telemetry/opentelemetry-python/issues/4568. + def force_flush(self, timeout_millis: int | None = None) -> bool: + if self._shutdown: + return False + # Blocking call to export. + self._export(BatchExportStrategy.EXPORT_ALL) + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py new file mode 100644 index 00000000000..441ccdcafd2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py @@ -0,0 +1,140 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections import Counter +from collections.abc import Callable +from typing import Literal, Protocol + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, MeterProvider, Observation +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OTEL_COMPONENT_NAME, + OTEL_COMPONENT_TYPE, + OtelComponentTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( + OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE, + OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE, + create_otel_sdk_processor_log_processed, + create_otel_sdk_processor_log_queue_capacity, + create_otel_sdk_processor_span_processed, + create_otel_sdk_processor_span_queue_capacity, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE + +_component_counter = Counter() + + +class ProcessorMetricsT(Protocol): + def register_queue_size(self, get_queue_size: Callable[[], int]) -> None: ... + + def drop_items(self, count: int, error_type: str = "queue_full") -> None: ... + + def finish_items(self, count: int) -> None: ... + + +class NoOpProcessorMetrics: + def register_queue_size(self, get_queue_size: Callable[[], int]) -> None: + pass + + def drop_items(self, count: int, error_type: str = "queue_full") -> None: + pass + + def finish_items(self, count: int) -> None: + pass + + +class ProcessorMetrics: + def __init__( + self, + signal: Literal["traces", "logs"], + component_type: OtelComponentTypeValues, + meter_provider: MeterProvider, + *, + capacity: int | None = None, + ) -> None: + self._signal = signal + meter = meter_provider.get_meter("opentelemetry-sdk") + self._meter = meter + + count = _component_counter[component_type.value] + _component_counter[component_type.value] = count + 1 + + self._standard_attrs = { + OTEL_COMPONENT_TYPE: component_type.value, + OTEL_COMPONENT_NAME: f"{component_type.value}/{count}", + } + + self._dropped_attrs = { + **self._standard_attrs, + ERROR_TYPE: "queue_full", + } + + self._already_shutdown_attrs = { + **self._standard_attrs, + ERROR_TYPE: "already_shutdown", + } + + if signal == "traces": + create_processed = create_otel_sdk_processor_span_processed + create_queue_capacity = create_otel_sdk_processor_span_queue_capacity + else: + create_processed = create_otel_sdk_processor_log_processed + create_queue_capacity = create_otel_sdk_processor_log_queue_capacity + + self._processed = create_processed(meter) + + if capacity is not None: + self._queue_capacity = create_queue_capacity(meter) + self._queue_capacity.add(capacity, self._standard_attrs) + + def register_queue_size(self, get_queue_size: Callable[[], int]) -> None: + def record_queue_size( + _options: CallbackOptions, + ) -> tuple[Observation]: + return (Observation(get_queue_size(), self._standard_attrs),) + + if self._signal == "traces": + queue_size_name = OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE + queue_size_description = "The number of spans in the queue of a given instance of an SDK span processor." + queue_size_unit = "{span}" + else: + queue_size_name = OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE + queue_size_description = "The number of logs in the queue of a given instance of an SDK log processor." + queue_size_unit = "{log}" + + self._meter.create_observable_up_down_counter( + queue_size_name, + callbacks=(record_queue_size,), + description=queue_size_description, + unit=queue_size_unit, + ) + + def drop_items(self, count: int, error_type: str = "queue_full") -> None: + if error_type == "already_shutdown": + self._processed.add(count, self._already_shutdown_attrs) + else: + self._processed.add(count, self._dropped_attrs) + + def finish_items(self, count: int) -> None: + self._processed.add(count, self._standard_attrs) + + +def create_processor_metrics( + signal: Literal["traces", "logs"], + component_type: OtelComponentTypeValues, + meter_provider: MeterProvider, + *, + capacity: int | None = None, + enabled: bool, +) -> ProcessorMetricsT: + if not enabled: + return NoOpProcessorMetrics() + + return ProcessorMetrics( + signal, + component_type, + meter_provider, + capacity=capacity, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py new file mode 100644 index 00000000000..303f62924bc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py @@ -0,0 +1,863 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +OTEL_SDK_DISABLED = "OTEL_SDK_DISABLED" +""" +.. envvar:: OTEL_SDK_DISABLED + +The :envvar:`OTEL_SDK_DISABLED` environment variable disables the SDK for all signals +Default: "false" +""" + +OTEL_CONFIG_FILE = "OTEL_CONFIG_FILE" +""" +.. envvar:: OTEL_CONFIG_FILE + +The :envvar:`OTEL_CONFIG_FILE` environment variable points the SDK at a +declarative configuration file (YAML or JSON). When set, the file is the +sole source for SDK construction. Spec-defined ``OTEL_*`` variables with +schema equivalents are ignored. Env vars may still be read indirectly by +components the file enables (e.g. resource detectors) and via +``${env:VAR}`` substitution inside the file. + +Python-implementation extensions outside the spec (``OTEL_PYTHON_*`` +variables such as ``OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED`` or +:envvar:`OTEL_PYTHON_TRACER_CONFIGURATOR`) are also bypassed when +:envvar:`OTEL_CONFIG_FILE` is set, because the env-var initialisation path +is skipped entirely in favour of the declarative file. Honouring these +alongside a config file is tracked separately. + +See the OpenTelemetry declarative configuration specification for details. +""" + +OTEL_RESOURCE_ATTRIBUTES = "OTEL_RESOURCE_ATTRIBUTES" +""" +.. envvar:: OTEL_RESOURCE_ATTRIBUTES + +The :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable allows resource +attributes to be passed to the SDK at process invocation. The attributes from +:envvar:`OTEL_RESOURCE_ATTRIBUTES` are merged with those passed to +`Resource.create`, meaning :envvar:`OTEL_RESOURCE_ATTRIBUTES` takes *lower* +priority. Attributes should be in the format ``key1=value1,key2=value2``. +Additional details are available `in the specification +`__. + +.. code-block:: console + + $ OTEL_RESOURCE_ATTRIBUTES="service.name=shoppingcard,will_be_overridden=foo" python - <`__. +""" + +OTEL_EXPORTER_OTLP_TIMEOUT = "OTEL_EXPORTER_OTLP_TIMEOUT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TIMEOUT + +The :envvar:`OTEL_EXPORTER_OTLP_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will wait for each batch export. +Default: 10 +""" + +OTEL_EXPORTER_OTLP_ENDPOINT = "OTEL_EXPORTER_OTLP_ENDPOINT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_ENDPOINT + +The :envvar:`OTEL_EXPORTER_OTLP_ENDPOINT` target to which the exporter is going to send spans or metrics. +The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. +A scheme of https indicates a secure connection and takes precedence over the insecure configuration setting. +Default: "http://localhost:4317" +""" + +OTEL_EXPORTER_OTLP_INSECURE = "OTEL_EXPORTER_OTLP_INSECURE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_INSECURE + +The :envvar:`OTEL_EXPORTER_OTLP_INSECURE` represents whether to enable client transport security for gRPC requests. +A scheme of https takes precedence over this configuration setting. +Default: False +""" + +OTEL_EXPORTER_OTLP_TRACES_INSECURE = "OTEL_EXPORTER_OTLP_TRACES_INSECURE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_INSECURE + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_INSECURE` represents whether to enable client transport security +for gRPC requests for spans. A scheme of https takes precedence over the this configuration setting. +Default: False +""" + + +OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` target to which the span exporter is going to send spans. +The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. +A scheme of https indicates a secure connection and takes precedence over this configuration setting. +""" + +OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` target to which the metrics exporter is going to send metrics. +The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. +A scheme of https indicates a secure connection and takes precedence over this configuration setting. +""" + +OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` target to which the log exporter is going to send logs. +The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. +A scheme of https indicates a secure connection and takes precedence over this configuration setting. +""" + +_OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` to the grpc OTLP Log exporter, +Entry point providers should implement the following: + +.. code-block:: python + + import grpc + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def channel_credential_provider() -> grpc.ChannelCredentials: + +Note: This environment variable is experimental and subject to change. +""" + +_OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER` provides `requests.Session` for the HTTP OTLP Log exporter. +Entry point providers should implement the following: + +.. code-block:: python + + import requests + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def request_session_provder() -> requests.Session: + +Note: This environment variable is experimental and subject to change. +""" +_OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER` provides `requests.Session` for all HTTP OTLP exporters. +Entry point providers should implement the following: + +.. code-block:: python + + import requests + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def request_session_provder() -> requests.Session: + +Note: This environment variable is experimental and subject to change. +""" +_OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` for all GRPC OTLP exporters. +Entry point providers should implement the following: + +.. code-block:: python + + import grpc + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def channel_credential_provider() -> grpc.ChannelCredentials: + +Note: This environment variable is experimental and subject to change. +""" +_OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER` provides `requests.Session` to the HTTP OTLP Span exporter. +Entry point providers should implement the following: + +.. code-block:: python + + import requests + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def request_session_provder() -> requests.Session: + +Note: This environment variable is experimental and subject to change. +""" +_OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER" +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` to the GRPC OTLP Span exporter. +Entry point providers should implement the following: + +.. code-block:: python + + import grpc + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def channel_credential_provider() -> grpc.ChannelCredentials: + +Note: This environment variable is experimental and subject to change. +""" +_OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER = ( + "OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER" +) +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER` provides `requests.Session` to the HTTP OTLP Metric exporter. +Entry point providers should implement the following: + +.. code-block:: python + + import requests + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def request_session_provder() -> requests.Session: + +Note: This environment variable is experimental and subject to change. +""" +_OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER = ( + "OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER" +) +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` to the GRPC OTLP Metric exporter. +Entry point providers should implement the following: + +.. code-block:: python + + import grpc + + # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. + def channel_credential_provider() -> grpc.ChannelCredentials: + +Note: This environment variable is experimental and subject to change. +""" + +_OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES" +""" +.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES + +The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES` stores a comma-separated list of human-readable +gRPC error codes that are considered retryable for the OTLP gRPC exporters (e.g. `UNAVAILABLE, DEADLINE_EXCEEDED`). +Supported error codes are defined in `grpc.StatusCode` and are parsed in a case-insensitive manner. + +Note: This environment variable is experimental and subject to change. +""" + +OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` stores the path to the certificate file for +TLS credentials of gRPC client for traces. Should only be used for a secure connection for tracing. +""" + +OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE = "OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE` stores the path to the certificate file for +TLS credentials of gRPC client for metrics. Should only be used for a secure connection for exporting metrics. +""" + +OTEL_EXPORTER_OTLP_CLIENT_KEY = "OTEL_EXPORTER_OTLP_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format. +""" + +OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY = "OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format for traces. +""" + +OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY = "OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format for metrics. +""" + +OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY = "OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format for logs. +""" + +OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format. +""" + +OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format for traces. +""" + +OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format for metrics. +""" + +OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format for logs. +""" + +OTEL_EXPORTER_OTLP_TRACES_HEADERS = "OTEL_EXPORTER_OTLP_TRACES_HEADERS" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_HEADERS + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_HEADERS` contains the key-value pairs to be used as headers for spans +associated with gRPC or HTTP requests. +""" + +OTEL_EXPORTER_OTLP_METRICS_HEADERS = "OTEL_EXPORTER_OTLP_METRICS_HEADERS" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_HEADERS + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_HEADERS` contains the key-value pairs to be used as headers for metrics +associated with gRPC or HTTP requests. +""" + +OTEL_EXPORTER_OTLP_LOGS_HEADERS = "OTEL_EXPORTER_OTLP_LOGS_HEADERS" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_HEADERS + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_HEADERS` contains the key-value pairs to be used as headers for logs +associated with gRPC or HTTP requests. +""" + +OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_COMPRESSION + +Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the span +exporter. If both are present, this takes higher precedence. +""" + +OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = "OTEL_EXPORTER_OTLP_METRICS_COMPRESSION" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_COMPRESSION + +Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the metric +exporter. If both are present, this takes higher precedence. +""" + +OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = "OTEL_EXPORTER_OTLP_LOGS_COMPRESSION" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION + +Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the log +exporter. If both are present, this takes higher precedence. +""" + +OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_TIMEOUT + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will +wait for each batch export for spans. +Default: 10 +""" + +OTEL_EXPORTER_OTLP_METRICS_TIMEOUT = "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_TIMEOUT + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will +wait for each batch export for metrics. +Default: 10 +""" + +OTEL_EXPORTER_OTLP_METRICS_INSECURE = "OTEL_EXPORTER_OTLP_METRICS_INSECURE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_INSECURE + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_INSECURE` represents whether to enable client transport security +for gRPC requests for metrics. A scheme of https takes precedence over the this configuration setting. +Default: False +""" + +OTEL_EXPORTER_OTLP_LOGS_INSECURE = "OTEL_EXPORTER_OTLP_LOGS_INSECURE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_INSECURE + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_INSECURE` represents whether to enable client transport security +for gRPC requests for logs. A scheme of https takes precedence over the this configuration setting. +Default: False +""" + +OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = "OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE` stores the path to the certificate file for +TLS credentials of gRPC client for logs. Should only be used for a secure connection for logs. +""" + +OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will +wait for each batch export for logs. +Default: 10 +""" + +OTEL_SERVICE_NAME = "OTEL_SERVICE_NAME" +""" +.. envvar:: OTEL_SERVICE_NAME + +Convenience environment variable for setting the service name resource attribute. +The following two environment variables have the same effect + +.. code-block:: console + + OTEL_SERVICE_NAME=my-python-service + + OTEL_RESOURCE_ATTRIBUTES=service.name=my-python-service + + +If both are set, :envvar:`OTEL_SERVICE_NAME` takes precedence. +""" + + +_OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED = "OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED" +""" +.. envvar:: OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED + +The :envvar:`OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED` environment variable allows users to +enable/disable the auto instrumentation for the python logging module. +Default: False + +Note: Logs SDK and its related settings are experimental. + +.. warning:: + + This option is deprecated, instead you should install `opentelemetry-instrumentation-logging`. +""" + + +OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment +variable allows users to set the default aggregation temporality policy to use +on the basis of instrument kind. The valid (case-insensitive) values are: + +``CUMULATIVE``: Use ``CUMULATIVE`` aggregation temporality for all instrument kinds. +``DELTA``: Use ``DELTA`` aggregation temporality for ``Counter``, ``Asynchronous Counter`` and ``Histogram``. +Use ``CUMULATIVE`` aggregation temporality for ``UpDownCounter`` and ``Asynchronous UpDownCounter``. +``LOWMEMORY``: Use ``DELTA`` aggregation temporality for ``Counter`` and ``Histogram``. +Use ``CUMULATIVE`` aggregation temporality for ``UpDownCounter``, ``AsynchronousCounter`` and ``Asynchronous UpDownCounter``. +""" + +OTEL_METRIC_EXPORT_INTERVAL = "OTEL_METRIC_EXPORT_INTERVAL" +""" +.. envvar:: OTEL_METRIC_EXPORT_INTERVAL + +The :envvar:`OTEL_METRIC_EXPORT_INTERVAL` is the time interval (in milliseconds) between the start of two export attempts. +""" + +OTEL_METRIC_EXPORT_TIMEOUT = "OTEL_METRIC_EXPORT_TIMEOUT" +""" +.. envvar:: OTEL_METRIC_EXPORT_TIMEOUT + +The :envvar:`OTEL_METRIC_EXPORT_TIMEOUT` is the maximum allowed time (in milliseconds) to export data. +""" + +OTEL_METRICS_EXEMPLAR_FILTER = "OTEL_METRICS_EXEMPLAR_FILTER" +""" +.. envvar:: OTEL_METRICS_EXEMPLAR_FILTER + +The :envvar:`OTEL_METRICS_EXEMPLAR_FILTER` is the filter for which measurements can become Exemplars. +""" + +OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = "OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` is the default aggregation to use for histogram instruments. +""" + +OTEL_EXPERIMENTAL_RESOURCE_DETECTORS = "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS" +""" +.. envvar:: OTEL_EXPERIMENTAL_RESOURCE_DETECTORS + +The :envvar:`OTEL_EXPERIMENTAL_RESOURCE_DETECTORS` is a comma-separated string +of names of resource detectors. These names must be the same as the names of +entry points for the ```opentelemetry_resource_detector``` entry point. This is an +experimental feature and the name of this variable and its behavior can change +in a non-backwards compatible way. + +Detectors are run in the order they are listed and their attributes are merged +in that order, with later detectors taking precedence over earlier ones on +conflicting keys. The ``otel`` detector (which reads +:envvar:`OTEL_RESOURCE_ATTRIBUTES` and :envvar:`OTEL_SERVICE_NAME`) is always +appended last unless explicitly placed elsewhere in the list, ensuring +environment variable attributes take highest priority among detectors. +""" + +OTEL_EXPORTER_PROMETHEUS_HOST = "OTEL_EXPORTER_PROMETHEUS_HOST" +""" +.. envvar:: OTEL_EXPORTER_PROMETHEUS_HOST + +The :envvar:`OTEL_EXPORTER_PROMETHEUS_HOST` environment variable configures the host used by +the Prometheus exporter. +Default: "localhost" + +This is an experimental environment variable and the name of this variable and its behavior can +change in a non-backwards compatible way. +""" + +OTEL_EXPORTER_PROMETHEUS_PORT = "OTEL_EXPORTER_PROMETHEUS_PORT" +""" +.. envvar:: OTEL_EXPORTER_PROMETHEUS_PORT + +The :envvar:`OTEL_EXPORTER_PROMETHEUS_PORT` environment variable configures the port used by +the Prometheus exporter. +Default: 9464 + +This is an experimental environment variable and the name of this variable and its behavior can +change in a non-backwards compatible way. +""" + +OTEL_PYTHON_TRACER_CONFIGURATOR = "OTEL_PYTHON_TRACER_CONFIGURATOR" +""" +.. envvar:: OTEL_PYTHON_TRACER_CONFIGURATOR + +The :envvar:`OTEL_PYTHON_TRACER_CONFIGURATOR` environment variable allows users to set a +custom Tracer Configurator function. +Default: opentelemetry.sdk.trace._default_tracer_configurator + +This is an experimental environment variable and the name of this variable and its behavior can +change in a non-backwards compatible way. +""" + +OTEL_PYTHON_METER_CONFIGURATOR = "OTEL_PYTHON_METER_CONFIGURATOR" +""" +.. envvar:: OTEL_PYTHON_METER_CONFIGURATOR + +The :envvar:`OTEL_PYTHON_METER_CONFIGURATOR` environment variable allows users to set a +custom Meter Configurator function. +Default: opentelemetry.sdk.metrics._internal._default_meter_configurator + +This is an experimental environment variable and the name of this variable and its behavior can +change in a non-backwards compatible way. +""" + +OTEL_PYTHON_LOGGER_CONFIGURATOR = "OTEL_PYTHON_LOGGER_CONFIGURATOR" +""" +.. envvar:: OTEL_PYTHON_LOGGER_CONFIGURATOR + +The :envvar:`OTEL_PYTHON_LOGGER_CONFIGURATOR` environment variable allows users to set a +custom Logger Configurator function. +Default: opentelemetry.sdk._logs._internal._default_logger_configurator + +This is an experimental environment variable and the name of this variable and its behavior can +change in a non-backwards compatible way. +""" + +OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED = "OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED" +""" +.. envvar:: OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED + +The :envvar:`OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED` environment variable enables +metrics emitted by the SDK about its own internal state. +Default: "false" +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py new file mode 100644 index 00000000000..0f0fa930a62 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py @@ -0,0 +1,26 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from logging import getLogger +from os import environ + +_logger = getLogger(__name__) + + +def parse_boolean_environment_variable(environment_variable: str, default: bool = False) -> bool: + value = environ.get(environment_variable) + if value is None: + return default + + match value.strip().lower(): + case "true": + return True + case "false": + return False + case _: + _logger.warning( + "Invalid value for %s: %r. Expected 'true' or 'false'.", + environment_variable, + value, + ) + return default diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py new file mode 100644 index 00000000000..1a4c037548d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py @@ -0,0 +1,128 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +Global Error Handler + +This module provides a global error handler and an interface that allows +error handlers to be registered with the global error handler via entry points. +A default error handler is also provided. + +To use this feature, users can create an error handler that is registered +using the ``opentelemetry_error_handler`` entry point. A class is to be +registered in this entry point, this class must inherit from the +``opentelemetry.sdk.error_handler.ErrorHandler`` class and implement the +corresponding ``handle`` method. This method will receive the exception object +that is to be handled. The error handler class should also inherit from the +exception classes it wants to handle. For example, this would be an error +handler that handles ``ZeroDivisionError``: + +.. code:: python + + from opentelemetry.sdk.error_handler import ErrorHandler + from logging import getLogger + + logger = getLogger(__name__) + + + class ErrorHandler0(ErrorHandler, ZeroDivisionError): + + def _handle(self, error: Exception, *args, **kwargs): + + logger.exception("ErrorHandler0 handling a ZeroDivisionError") + +To use the global error handler, just instantiate it as a context manager where +you want exceptions to be handled: + + +.. code:: python + + from opentelemetry.sdk.error_handler import GlobalErrorHandler + + with GlobalErrorHandler(): + 1 / 0 + +If the class of the exception raised in the scope of the ``GlobalErrorHandler`` +object is not parent of any registered error handler, then the default error +handler will handle the exception. This default error handler will only log the +exception to standard logging, the exception won't be raised any further. +""" + +from abc import ABC, abstractmethod +from logging import getLogger + +from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points + +logger = getLogger(__name__) + + +class ErrorHandler(ABC): + @abstractmethod + def _handle(self, error: Exception, *args, **kwargs): + """ + Handle an exception + """ + + +class _DefaultErrorHandler(ErrorHandler): + """ + Default error handler + + This error handler just logs the exception using standard logging. + """ + + # pylint: disable=useless-return + def _handle(self, error: Exception, *args, **kwargs): + logger.exception("Error handled by default error handler: ") + + +class GlobalErrorHandler: + """ + Global error handler + + This is a singleton class that can be instantiated anywhere to get the + global error handler. This object provides a handle method that receives + an exception object that will be handled by the registered error handlers. + """ + + _instance = None + + def __new__(cls) -> "GlobalErrorHandler": + if cls._instance is None: + cls._instance = super().__new__(cls) + + return cls._instance + + def __enter__(self): + pass + + # pylint: disable=no-self-use + def __exit__(self, exc_type, exc_value, traceback): + if exc_value is None: + return None + + plugin_handled = False + + error_handler_entry_points = entry_points(group="opentelemetry_error_handler") + + for error_handler_entry_point in error_handler_entry_points: + error_handler_class = error_handler_entry_point.load() + + if issubclass(error_handler_class, exc_value.__class__): + try: + error_handler_class()._handle(exc_value) + plugin_handled = True + + # pylint: disable=broad-exception-caught + except Exception as error_handling_error: + logger.exception( + "%s error while handling error %s by error handler %s", + error_handling_error.__class__.__name__, + exc_value.__class__.__name__, + error_handler_class.__name__, + ) + + if not plugin_handled: + _DefaultErrorHandler()._handle(exc_value) + + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py new file mode 100644 index 00000000000..f59d0718680 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py @@ -0,0 +1,49 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import export, view +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import Meter, MeterProvider +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( + AlignedHistogramBucketExemplarReservoir, + AlwaysOffExemplarFilter, + AlwaysOnExemplarFilter, + Exemplar, + ExemplarFilter, + ExemplarReservoir, + SimpleFixedSizeExemplarReservoir, + TraceBasedExemplarFilter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( + Counter, + Histogram, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import Gauge as _Gauge + +__all__ = [ + "AlignedHistogramBucketExemplarReservoir", + "AlwaysOffExemplarFilter", + "AlwaysOnExemplarFilter", + "Counter", + "Exemplar", + "ExemplarFilter", + "ExemplarReservoir", + "Histogram", + "Meter", + "MeterProvider", + "MetricsTimeoutError", + "ObservableCounter", + "ObservableGauge", + "ObservableUpDownCounter", + "SimpleFixedSizeExemplarReservoir", + "TraceBasedExemplarFilter", + "UpDownCounter", + "_Gauge", + "export", + "view", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py new file mode 100644 index 00000000000..9ca9fbb985a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py @@ -0,0 +1,660 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import os +import weakref +from atexit import register, unregister +from collections.abc import Callable, Sequence +from dataclasses import dataclass +from logging import getLogger +from os import environ +from threading import Lock +from time import time_ns + +# This kind of import is needed to avoid Sphinx errors. +import opentelemetry.agent._vendor.opentelemetry.sdk.metrics +from opentelemetry.agent._vendor import opentelemetry +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter as APICounter +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram as APIHistogram +from opentelemetry.agent._vendor.opentelemetry.metrics import Meter as APIMeter +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider as APIMeterProvider +from opentelemetry.agent._vendor.opentelemetry.metrics import NoOpMeter +from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableCounter as APIObservableCounter +from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableGauge as APIObservableGauge +from opentelemetry.agent._vendor.opentelemetry.metrics import ( + ObservableUpDownCounter as APIObservableUpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import UpDownCounter as APIUpDownCounter +from opentelemetry.agent._vendor.opentelemetry.metrics import _Gauge as APIGauge +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_METRICS_EXEMPLAR_FILTER, + OTEL_SDK_DISABLED, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( + AlwaysOffExemplarFilter, + AlwaysOnExemplarFilter, + ExemplarFilter, + TraceBasedExemplarFilter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( + _Counter, + _Gauge, + _Histogram, + _ObservableCounter, + _ObservableGauge, + _ObservableUpDownCounter, + _UpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement_consumer import ( + MeasurementConsumer, + SynchronousMeasurementConsumer, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.sdk_configuration import ( + SdkConfiguration, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( + Resource, + _get_process_dependent_resource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.util._configurator import RuleBasedConfigurator +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( + InstrumentationScope, +) +from opentelemetry.agent._vendor.opentelemetry.util._once import Once +from opentelemetry.agent._vendor.opentelemetry.util.types import ( + Attributes, +) + +_logger = getLogger(__name__) + + +@dataclass +class _MeterConfig: + is_enabled: bool = True + + @classmethod + def default(cls) -> "_MeterConfig": + return _MeterConfig() + + +class _ProxyMeterConfig: + def __init__(self, config: _MeterConfig): + self._config = config + + @property + def is_enabled(self) -> bool: + return self._config.is_enabled + + def update(self, config: _MeterConfig) -> None: + self._config = config + + +class Meter(APIMeter): + """See `opentelemetry.metrics.Meter`.""" + + def __init__( + self, + instrumentation_scope: InstrumentationScope, + measurement_consumer: MeasurementConsumer, + *, + _meter_config: _MeterConfig | None = None, + ): + super().__init__( + name=instrumentation_scope.name, + version=instrumentation_scope.version, + schema_url=instrumentation_scope.schema_url, + ) + self._instrumentation_scope = instrumentation_scope + self._measurement_consumer = measurement_consumer + self._instrument_id_instrument = {} + self._instrument_registration_lock = Lock() + self._meter_config = _ProxyMeterConfig(_meter_config or _MeterConfig.default()) + + def _is_enabled(self) -> bool: + return self._meter_config.is_enabled + + def _set_meter_config(self, meter_config: _MeterConfig) -> None: + self._meter_config.update(meter_config) + + def create_counter(self, name, unit="", description="") -> APICounter: + with self._instrument_registration_lock: + status = self._register_instrument(name, _Counter, unit, description) + if not status.already_registered: + self._instrument_id_instrument[status.instrument_id] = _Counter( + name, + self._instrumentation_scope, + self._measurement_consumer, + unit, + description, + _meter_config=self._meter_config, + ) + instrument = self._instrument_id_instrument[status.instrument_id] + + if status.conflict: + # FIXME #2558 go through all views here and check if this + # instrument registration conflict can be fixed. If it can be, do + # not log the following warning. + self._log_instrument_registration_conflict( + name, + APICounter.__name__, + unit, + description, + status, + ) + return instrument + + def create_up_down_counter(self, name, unit="", description="") -> APIUpDownCounter: + with self._instrument_registration_lock: + status = self._register_instrument(name, _UpDownCounter, unit, description) + if not status.already_registered: + self._instrument_id_instrument[status.instrument_id] = _UpDownCounter( + name, + self._instrumentation_scope, + self._measurement_consumer, + unit, + description, + _meter_config=self._meter_config, + ) + instrument = self._instrument_id_instrument[status.instrument_id] + + if status.conflict: + # FIXME #2558 go through all views here and check if this + # instrument registration conflict can be fixed. If it can be, do + # not log the following warning. + self._log_instrument_registration_conflict( + name, + APIUpDownCounter.__name__, + unit, + description, + status, + ) + return instrument + + def create_observable_counter( + self, + name, + callbacks=None, + unit="", + description="", + ) -> APIObservableCounter: + with self._instrument_registration_lock: + status = self._register_instrument(name, _ObservableCounter, unit, description) + if not status.already_registered: + self._instrument_id_instrument[status.instrument_id] = _ObservableCounter( + name, + self._instrumentation_scope, + self._measurement_consumer, + callbacks, + unit, + description, + _meter_config=self._meter_config, + ) + instrument = self._instrument_id_instrument[status.instrument_id] + + if not status.already_registered: + self._measurement_consumer.register_asynchronous_instrument(instrument) + + if status.conflict: + # FIXME #2558 go through all views here and check if this + # instrument registration conflict can be fixed. If it can be, do + # not log the following warning. + self._log_instrument_registration_conflict( + name, + APIObservableCounter.__name__, + unit, + description, + status, + ) + return instrument + + def create_histogram( + self, + name: str, + unit: str = "", + description: str = "", + *, + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + ) -> APIHistogram: + if explicit_bucket_boundaries_advisory is not None: + invalid_advisory = False + if isinstance(explicit_bucket_boundaries_advisory, Sequence): + try: + invalid_advisory = not ( + all(isinstance(e, (float, int)) for e in explicit_bucket_boundaries_advisory) + ) + except (KeyError, TypeError): + invalid_advisory = True + else: + invalid_advisory = True + + if invalid_advisory: + explicit_bucket_boundaries_advisory = None + _logger.warning("explicit_bucket_boundaries_advisory must be a sequence of numbers") + + with self._instrument_registration_lock: + status = self._register_instrument( + name, + _Histogram, + unit, + description, + explicit_bucket_boundaries_advisory, + ) + if not status.already_registered: + self._instrument_id_instrument[status.instrument_id] = _Histogram( + name, + self._instrumentation_scope, + self._measurement_consumer, + unit, + description, + explicit_bucket_boundaries_advisory, + _meter_config=self._meter_config, + ) + instrument = self._instrument_id_instrument[status.instrument_id] + + if status.conflict: + # FIXME #2558 go through all views here and check if this + # instrument registration conflict can be fixed. If it can be, do + # not log the following warning. + self._log_instrument_registration_conflict( + name, + APIHistogram.__name__, + unit, + description, + status, + ) + return instrument + + def create_gauge(self, name, unit="", description="") -> APIGauge: + with self._instrument_registration_lock: + status = self._register_instrument(name, _Gauge, unit, description) + if not status.already_registered: + self._instrument_id_instrument[status.instrument_id] = _Gauge( + name, + self._instrumentation_scope, + self._measurement_consumer, + unit, + description, + _meter_config=self._meter_config, + ) + instrument = self._instrument_id_instrument[status.instrument_id] + + if status.conflict: + # FIXME #2558 go through all views here and check if this + # instrument registration conflict can be fixed. If it can be, do + # not log the following warning. + self._log_instrument_registration_conflict( + name, + APIGauge.__name__, + unit, + description, + status, + ) + return instrument + + def create_observable_gauge(self, name, callbacks=None, unit="", description="") -> APIObservableGauge: + with self._instrument_registration_lock: + status = self._register_instrument(name, _ObservableGauge, unit, description) + if not status.already_registered: + self._instrument_id_instrument[status.instrument_id] = _ObservableGauge( + name, + self._instrumentation_scope, + self._measurement_consumer, + callbacks, + unit, + description, + _meter_config=self._meter_config, + ) + instrument = self._instrument_id_instrument[status.instrument_id] + + if not status.already_registered: + self._measurement_consumer.register_asynchronous_instrument(instrument) + + if status.conflict: + # FIXME #2558 go through all views here and check if this + # instrument registration conflict can be fixed. If it can be, do + # not log the following warning. + self._log_instrument_registration_conflict( + name, + APIObservableGauge.__name__, + unit, + description, + status, + ) + return instrument + + def create_observable_up_down_counter( + self, name, callbacks=None, unit="", description="" + ) -> APIObservableUpDownCounter: + with self._instrument_registration_lock: + status = self._register_instrument(name, _ObservableUpDownCounter, unit, description) + if not status.already_registered: + self._instrument_id_instrument[status.instrument_id] = _ObservableUpDownCounter( + name, + self._instrumentation_scope, + self._measurement_consumer, + callbacks, + unit, + description, + _meter_config=self._meter_config, + ) + instrument = self._instrument_id_instrument[status.instrument_id] + + if not status.already_registered: + self._measurement_consumer.register_asynchronous_instrument(instrument) + + if status.conflict: + # FIXME #2558 go through all views here and check if this + # instrument registration conflict can be fixed. If it can be, do + # not log the following warning. + self._log_instrument_registration_conflict( + name, + APIObservableUpDownCounter.__name__, + unit, + description, + status, + ) + return instrument + + +def _get_exemplar_filter(exemplar_filter: str) -> ExemplarFilter: + if exemplar_filter == "trace_based": + return TraceBasedExemplarFilter() + if exemplar_filter == "always_on": + return AlwaysOnExemplarFilter() + if exemplar_filter == "always_off": + return AlwaysOffExemplarFilter() + msg = f"Unknown exemplar filter '{exemplar_filter}'." + raise ValueError(msg) + + +_MeterConfiguratorT = Callable[[InstrumentationScope], _MeterConfig] +_RuleBasedMeterConfigurator = RuleBasedConfigurator[_MeterConfig] + + +def _default_meter_configurator( + _meter_scope: InstrumentationScope, +) -> _MeterConfig: + return _MeterConfig.default() + + +def _disable_meter_configurator( + _meter_scope: InstrumentationScope, +) -> _MeterConfig: + return _MeterConfig(is_enabled=False) + + +class MeterProvider(APIMeterProvider): + r"""See `opentelemetry.metrics.MeterProvider`. + + Args: + metric_readers: Register metric readers to collect metrics from the SDK + on demand. Each :class:`opentelemetry.sdk.metrics.export.MetricReader` is + completely independent and will collect separate streams of + metrics. For push-based export, use + :class:`opentelemetry.sdk.metrics.export.PeriodicExportingMetricReader`. + resource: The resource representing what the metrics emitted from the SDK pertain to. + shutdown_on_exit: If true, registers an `atexit` handler to call + `MeterProvider.shutdown` + views: The views to configure the metric output the SDK + + .. code-block:: python + :caption: Push-based export with PeriodicExportingMetricReader + + from opentelemetry.sdk.metrics import MeterProvider + from opentelemetry.sdk.metrics.export import ( + ConsoleMetricExporter, + PeriodicExportingMetricReader, + ) + + reader = PeriodicExportingMetricReader(ConsoleMetricExporter()) + provider = MeterProvider(metric_readers=[reader]) + + By default, instruments which do not match any :class:`opentelemetry.sdk.metrics.view.View` (or if no :class:`opentelemetry.sdk.metrics.view.View`\ s + are provided) will report metrics with the default aggregation for the + instrument's kind. To disable instruments by default, configure a match-all + :class:`opentelemetry.sdk.metrics.view.View` with `DropAggregation` and then create :class:`opentelemetry.sdk.metrics.view.View`\ s to re-enable + individual instruments: + + .. code-block:: python + :caption: Disable default views + + MeterProvider( + views=[ + View(instrument_name="*", aggregation=DropAggregation()), + View(instrument_name="mycounter"), + ], + # ... + ) + """ + + _all_metric_readers_lock = Lock() + _all_metric_readers = weakref.WeakSet() + + def __init__( + self, + metric_readers: Sequence["opentelemetry.sdk.metrics.export.MetricReader"] = (), + resource: Resource | None = None, + exemplar_filter: ExemplarFilter | None = None, + shutdown_on_exit: bool = True, + views: Sequence["opentelemetry.sdk.metrics.view.View"] = (), + *, + _meter_configurator: _MeterConfiguratorT | None = None, + ): + self._lock = Lock() + self._meter_lock = Lock() + self._atexit_handler = None + if resource is None: + resource = Resource.create({}) + self._sdk_config = SdkConfiguration( + exemplar_filter=( + exemplar_filter or _get_exemplar_filter(environ.get(OTEL_METRICS_EXEMPLAR_FILTER, "trace_based")) + ), + resource=resource, + views=views, + ) + self._metric_readers = metric_readers + self._measurement_consumer = SynchronousMeasurementConsumer( + sdk_config=self._sdk_config, + metric_readers=metric_readers, + ) + disabled = environ.get(OTEL_SDK_DISABLED, "") + self._disabled = disabled.lower().strip() == "true" + + if shutdown_on_exit: + self._atexit_handler = register(self.shutdown) + + self._meters: dict[InstrumentationScope, Meter] = {} + self._shutdown_once = Once() + self._shutdown = False + self._meter_configurator = _meter_configurator or _default_meter_configurator + + for metric_reader in self._metric_readers: + with self._all_metric_readers_lock: + if metric_reader in self._all_metric_readers: + # pylint: disable=broad-exception-raised + raise Exception( + f"MetricReader {metric_reader} has been registered already in other MeterProvider instance" + ) + + self._all_metric_readers.add(metric_reader) + + metric_reader._set_collect_callback(self._measurement_consumer.collect) + metric_reader._set_meter_provider(self) + + if hasattr(os, "register_at_fork"): + weak_at_fork = weakref.WeakMethod(self._handle_fork) + + def _after_in_child() -> None: + if at_fork := weak_at_fork(): + at_fork() + + os.register_at_fork(after_in_child=_after_in_child) + + def _handle_fork(self) -> None: + self._lock = Lock() + self._meter_lock = Lock() + type(self)._all_metric_readers_lock = Lock() + self._update_resource(_get_process_dependent_resource()) + + def _set_meter_configurator(self, *, meter_configurator: _MeterConfiguratorT): + """Set a new MeterConfigurator for this MeterProvider. + + Setting a new MeterConfigurator will result in the configurator being called + for each outstanding Meter and for any newly created meters thereafter. + Therefore, it is important that the provided function returns quickly. + """ + with self._meter_lock: + self._meter_configurator = meter_configurator + for instrumentation_scope, meter in self._meters.items(): + # pylint: disable-next=protected-access + meter._set_meter_config(self._apply_meter_configurator(instrumentation_scope)) + + def _update_resource(self, resource: Resource) -> None: + with self._meter_lock: + self._sdk_config.resource = self._sdk_config.resource.merge(resource) + + def _apply_meter_configurator(self, instrumentation_scope: InstrumentationScope) -> _MeterConfig: + try: + return self._meter_configurator(instrumentation_scope) + # pylint: disable-next=broad-exception-caught + except Exception: + _logger.exception( + "meter configurator failed for scope '%s', using default config", + instrumentation_scope.name, + ) + return _MeterConfig.default() + + def force_flush(self, timeout_millis: float = 10_000) -> bool: + deadline_ns = time_ns() + timeout_millis * 10**6 + + metric_reader_error = {} + + for metric_reader in self._metric_readers: + current_ts = time_ns() + try: + if current_ts >= deadline_ns: + raise MetricsTimeoutError("Timed out while flushing metric readers") + metric_reader.force_flush(timeout_millis=(deadline_ns - current_ts) / 10**6) + + # pylint: disable=broad-exception-caught + except Exception as error: + metric_reader_error[metric_reader] = error + + if metric_reader_error: + metric_reader_error_string = "\n".join( + [ + f"{metric_reader.__class__.__name__}: {error!r}" + for metric_reader, error in metric_reader_error.items() + ] + ) + + # pylint: disable=broad-exception-raised + raise Exception( + "MeterProvider.force_flush failed because the following " + "metric readers failed during collect:\n" + f"{metric_reader_error_string}" + ) + return True + + def shutdown(self, timeout_millis: float = 30_000): + deadline_ns = time_ns() + timeout_millis * 10**6 + + def _shutdown(): + self._shutdown = True + + did_shutdown = self._shutdown_once.do_once(_shutdown) + + if not did_shutdown: + _logger.warning("shutdown can only be called once") + return + + metric_reader_error = {} + + for metric_reader in self._metric_readers: + current_ts = time_ns() + try: + if current_ts >= deadline_ns: + # pylint: disable=broad-exception-raised + raise Exception("Didn't get to execute, deadline already exceeded") + metric_reader.shutdown(timeout_millis=(deadline_ns - current_ts) / 10**6) + + # pylint: disable=broad-exception-caught + except Exception as error: + metric_reader_error[metric_reader] = error + + if self._atexit_handler is not None: + unregister(self._atexit_handler) + self._atexit_handler = None + + if metric_reader_error: + metric_reader_error_string = "\n".join( + [ + f"{metric_reader.__class__.__name__}: {error!r}" + for metric_reader, error in metric_reader_error.items() + ] + ) + + # pylint: disable=broad-exception-raised + raise Exception( + "MeterProvider.shutdown failed because the following " + "metric readers failed during shutdown:\n" + f"{metric_reader_error_string}" + ) + + def get_meter( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> APIMeter: + if self._disabled: + return NoOpMeter(name, version=version, schema_url=schema_url) + + if self._shutdown: + _logger.warning("A shutdown `MeterProvider` can not provide a `Meter`") + return NoOpMeter(name, version=version, schema_url=schema_url) + + if not name: + _logger.warning("Meter name cannot be None or empty.") + return NoOpMeter(name, version=version, schema_url=schema_url) + + instrumentation_scope = InstrumentationScope(name, version, schema_url, attributes) + with self._meter_lock: + if not self._meters.get(instrumentation_scope): + # FIXME #2558 pass SDKConfig object to meter so that the meter + # has access to views. + self._meters[instrumentation_scope] = Meter( + instrumentation_scope, + self._measurement_consumer, + _meter_config=self._apply_meter_configurator(instrumentation_scope), + ) + return self._meters[instrumentation_scope] + + def add_metric_reader(self, metric_reader: "opentelemetry.sdk.metrics.export.MetricReader") -> None: + with self._all_metric_readers_lock: + if metric_reader in self._all_metric_readers: + _logger.warning( + "MetricReader '%s' has been registered already!", + metric_reader, + ) + return + self._measurement_consumer.add_metric_reader(metric_reader) + # pylint: disable-next=protected-access + metric_reader._set_collect_callback(self._measurement_consumer.collect) + self._all_metric_readers.add(metric_reader) + + def remove_metric_reader( + self, + metric_reader: "opentelemetry.sdk.metrics.export.MetricReader", + ) -> None: + with self._all_metric_readers_lock: + if metric_reader not in self._all_metric_readers: + _logger.warning("MetricReader '%s' has not been registered!", metric_reader) + return + self._measurement_consumer.remove_metric_reader(metric_reader) + # pylint: disable-next=protected-access + metric_reader._set_collect_callback(None) + metric_reader.shutdown() + self._all_metric_readers.remove(metric_reader) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py new file mode 100644 index 00000000000..7dd0971e4ef --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py @@ -0,0 +1,217 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from collections.abc import Mapping, Sequence +from logging import getLogger +from threading import Lock +from time import time_ns +from types import NoneType +from typing import TYPE_CHECKING, cast + +from opentelemetry.agent._vendor.typing_extensions import assert_never + +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( + Aggregation, + AggregationTemporality, + DefaultAggregation, + _Aggregation, + _SumAggregation, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import DataPointT +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.view import View +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes + +_logger = getLogger(__name__) + +# Every branch is tagged so that values Python considers equal but the OTel +# data model does not -- True/1/1.0, or a sequence of pairs and the mapping +# it resembles -- produce different aggregation keys. +_HashedAttributes = tuple[ + str, + str + | bool + | int + | float + | bytes + | None + | tuple["_HashedAttributes", ...] + | tuple[tuple[str, "_HashedAttributes"], ...], +] + + +# pylint: disable=inconsistent-return-statements +def _hash_attributes(value: Attributes | AnyValue) -> _HashedAttributes: + # Attributes have been cleaned and validated when Measurement was instantiated, + # so value is guaranteed to match one of the branches below at runtime. + if isinstance(value, (NoneType, str, int, float, bool, bytes)): + # bool is a subclass of int and 1 == 1.0, so the value alone is not + # enough to tell these apart. + return (type(value).__name__, value) + if isinstance(value, Sequence): + return ("sequence", tuple(_hash_attributes(v) for v in value)) + if isinstance(value, Mapping): + return ( + "mapping", + tuple( + (k, _hash_attributes(value[k])) + for k in sorted( + value, + key=lambda item: item if isinstance(item, str) else str(item), + ) + ), + ) + if TYPE_CHECKING: + assert_never(value) + + +_DEFAULT_CARDINALITY_LIMIT = 2000 + +_OVERFLOW_ATTRIBUTES: dict[str, AnyValue] = {"otel.metric.overflow": True} +_OVERFLOW_KEY = _hash_attributes(_OVERFLOW_ATTRIBUTES) + + +class _ViewInstrumentMatch: + def __init__( + self, + view: View, + instrument: _Instrument, + instrument_class_aggregation: dict[type, Aggregation], + cardinality_limit: int = _DEFAULT_CARDINALITY_LIMIT, + reset_on_collect: bool = False, + ): + self._view = view + self._cardinality_limit = cardinality_limit + self._reset_on_collect = reset_on_collect + # Delta aggregations created after a collection continue from it. + self._previous_collection_start_nanos: int | None = None + self._instrument = instrument + self._attributes_aggregation: dict[_HashedAttributes, _Aggregation] = {} + self._lock = Lock() + self._instrument_class_aggregation = instrument_class_aggregation + self._name = self._view._name or self._instrument.name + self._description = self._view._description or self._instrument.description + if not isinstance(self._view._aggregation, DefaultAggregation): + self._aggregation = self._view._aggregation._create_aggregation( + self._instrument, + None, + self._view._exemplar_reservoir_factory, + 0, + ) + else: + self._aggregation = self._instrument_class_aggregation[self._instrument.__class__]._create_aggregation( + self._instrument, + None, + self._view._exemplar_reservoir_factory, + 0, + ) + + def conflicts(self, other: "_ViewInstrumentMatch") -> bool: + # pylint: disable=protected-access + + result = ( + self._name == other._name + and self._instrument.unit == other._instrument.unit + # The aggregation class is being used here instead of data point + # type since they are functionally equivalent. + and self._aggregation.__class__ == other._aggregation.__class__ + ) + if not result: + return result + + if isinstance(self._aggregation, _SumAggregation): + # if result is True the two aggregation are of the same type + self._aggregation = cast(_SumAggregation, self._aggregation) + other._aggregation = cast(_SumAggregation, other._aggregation) + + result = ( + self._aggregation._instrument_is_monotonic == other._aggregation._instrument_is_monotonic + and self._aggregation._instrument_aggregation_temporality + == other._aggregation._instrument_aggregation_temporality + ) + + return result + + # pylint: disable=protected-access + def consume_measurement(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: + attributes = {} + if measurement.attributes: + # Make a shallow copy since the user can mutate the dict after the fact. + # The user can still modify mutable attribute values (lists/dicts) + # leading to unexpected behavior, but deep copying is expensive. + attributes = dict(measurement.attributes) + if self._view._attribute_keys is not None: + attributes = {k: v for k, v in attributes.items() if k in self._view._attribute_keys} + + aggr_key = _hash_attributes(attributes) + + if self._reset_on_collect: + # collect() discards the aggregations, so hold the lock until the + # measurement is aggregated to not lose it. + with self._lock: + self._get_or_create_aggregation(aggr_key, attributes).aggregate(measurement, should_sample_exemplar) + return + + aggregation = self._attributes_aggregation.get(aggr_key) + if aggregation is None: + with self._lock: + aggregation = self._get_or_create_aggregation(aggr_key, attributes) + + aggregation.aggregate(measurement, should_sample_exemplar) + + def _get_or_create_aggregation(self, aggr_key: _HashedAttributes, attributes: Attributes) -> _Aggregation: + """Must be called with ``self._lock`` held.""" + aggregation = self._attributes_aggregation.get(aggr_key) + if aggregation is not None: + return aggregation + + # Overflow is only used once the limit of distinct attribute sets is + # reached, so the overflow point is exported in addition to them. + if len(self._attributes_aggregation) >= self._cardinality_limit: + aggr_key = _OVERFLOW_KEY + attributes = dict(_OVERFLOW_ATTRIBUTES) + aggregation = self._attributes_aggregation.get(aggr_key) + if aggregation is not None: + return aggregation + + start_time_unix_nano = self._previous_collection_start_nanos or time_ns() + # pylint: disable=protected-access + if not isinstance(self._view._aggregation, DefaultAggregation): + aggregation = self._view._aggregation._create_aggregation( + self._instrument, + attributes, + self._view._exemplar_reservoir_factory, + start_time_unix_nano, + ) + else: + aggregation = self._instrument_class_aggregation[self._instrument.__class__]._create_aggregation( + self._instrument, + attributes, + self._view._exemplar_reservoir_factory, + start_time_unix_nano, + ) + self._attributes_aggregation[aggr_key] = aggregation + return aggregation + + def collect( + self, + collection_aggregation_temporality: AggregationTemporality, + collection_start_nanos: int, + ) -> Sequence[DataPointT] | None: + data_points: list[DataPointT] = [] + with self._lock: + aggregations = self._attributes_aggregation + if self._reset_on_collect and collection_aggregation_temporality is AggregationTemporality.DELTA: + self._attributes_aggregation = {} + self._previous_collection_start_nanos = collection_start_nanos + + for aggregation in aggregations.values(): + data_point = aggregation.collect(collection_aggregation_temporality, collection_start_nanos) + if data_point is not None: + data_points.append(data_point) + + # Returning here None instead of an empty list because the caller + # does not consume a sequence and to be consistent with the rest of + # collect methods that also return None. + return data_points or None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py new file mode 100644 index 00000000000..5e307adc444 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py @@ -0,0 +1,1354 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=too-many-lines + +import math +from abc import ABC, abstractmethod +from bisect import bisect_left +from collections.abc import Callable, Sequence +from enum import IntEnum +from functools import partial +from logging import getLogger +from threading import Lock +from typing import ( + Generic, + TypeVar, + cast, +) + +from opentelemetry.agent._vendor.opentelemetry.metrics import ( + Asynchronous, + Counter, + Histogram, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + Synchronous, + UpDownCounter, + _Gauge, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( + Exemplar, + ExemplarReservoirBuilder, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.buckets import ( + Buckets, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping import ( + Mapping, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.exponent_mapping import ( + ExponentMapping, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.logarithm_mapping import ( + LogarithmMapping, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import Buckets as BucketsPoint +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( + ExponentialHistogramDataPoint, + HistogramDataPoint, + NumberDataPoint, + Sum, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import Gauge as GaugePoint +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( + Histogram as HistogramPoint, +) +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +_DataPointVarT = TypeVar("_DataPointVarT", NumberDataPoint, HistogramDataPoint) + +_logger = getLogger(__name__) + + +class AggregationTemporality(IntEnum): + """ + The temporality to use when aggregating data. + + Can be one of the following values: + """ + + UNSPECIFIED = 0 + DELTA = 1 + CUMULATIVE = 2 + + +class _Aggregation(ABC, Generic[_DataPointVarT]): + def __init__( + self, + attributes: Attributes, + reservoir_builder: ExemplarReservoirBuilder, + ): + self._lock = Lock() + self._attributes = attributes + self._reservoir = reservoir_builder() + self._previous_point = None + + @abstractmethod + def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: + """Aggregate a measurement. + + Args: + measurement: Measurement to aggregate + should_sample_exemplar: Whether the measurement should be sampled by the exemplars reservoir or not. + """ + + @abstractmethod + def collect( + self, + collection_aggregation_temporality: AggregationTemporality, + collection_start_nano: int, + ) -> _DataPointVarT | None: + pass + + def _collect_exemplars(self) -> Sequence[Exemplar]: + """Returns the collected exemplars. + + Returns: + The exemplars collected by the reservoir + """ + return self._reservoir.collect(self._attributes) + + def _sample_exemplar(self, measurement: Measurement, should_sample_exemplar: bool) -> None: + """Offer the measurement to the exemplar reservoir for sampling. + + It should be called within the each :ref:`aggregate` call. + + Args: + measurement: The new measurement + should_sample_exemplar: Whether the measurement should be sampled by the exemplars reservoir or not. + """ + if should_sample_exemplar: + self._reservoir.offer( + measurement.value, + measurement.time_unix_nano, + measurement.attributes, + measurement.context, + ) + + +class _DropAggregation(_Aggregation): + def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: + pass + + def collect( + self, + collection_aggregation_temporality: AggregationTemporality, + collection_start_nano: int, + ) -> _DataPointVarT | None: + pass + + +class _SumAggregation(_Aggregation[Sum]): + def __init__( + self, + attributes: Attributes, + instrument_is_monotonic: bool, + instrument_aggregation_temporality: AggregationTemporality, + start_time_unix_nano: int, + reservoir_builder: ExemplarReservoirBuilder, + ): + super().__init__(attributes, reservoir_builder) + + self._start_time_unix_nano = start_time_unix_nano + self._instrument_aggregation_temporality = instrument_aggregation_temporality + self._instrument_is_monotonic = instrument_is_monotonic + + self._value = None + + self._previous_collection_start_nano = self._start_time_unix_nano + self._previous_value = 0 + + def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: + with self._lock: + if self._value is None: + self._value = 0 + + self._value = self._value + measurement.value + + self._sample_exemplar(measurement, should_sample_exemplar) + + def collect( + self, + collection_aggregation_temporality: AggregationTemporality, + collection_start_nano: int, + ) -> NumberDataPoint | None: + """ + Atomically return a point for the current value of the metric and + reset the aggregation value. + + Synchronous instruments have a method which is called directly with + increments for a given quantity: + + For example, an instrument that counts the amount of passengers in + every vehicle that crosses a certain point in a highway: + + synchronous_instrument.add(2) + collect(...) # 2 passengers are counted + synchronous_instrument.add(3) + collect(...) # 3 passengers are counted + synchronous_instrument.add(1) + collect(...) # 1 passenger is counted + + In this case the instrument aggregation temporality is DELTA because + every value represents an increment to the count, + + Asynchronous instruments have a callback which returns the total value + of a given quantity: + + For example, an instrument that measures the amount of bytes written to + a certain hard drive: + + callback() -> 1352 + collect(...) # 1352 bytes have been written so far + callback() -> 2324 + collect(...) # 2324 bytes have been written so far + callback() -> 4542 + collect(...) # 4542 bytes have been written so far + + In this case the instrument aggregation temporality is CUMULATIVE + because every value represents the total of the measurement. + + There is also the collection aggregation temporality, which is passed + to this method. The collection aggregation temporality defines the + nature of the returned value by this aggregation. + + When the collection aggregation temporality matches the + instrument aggregation temporality, then this method returns the + current value directly: + + synchronous_instrument.add(2) + collect(DELTA) -> 2 + synchronous_instrument.add(3) + collect(DELTA) -> 3 + synchronous_instrument.add(1) + collect(DELTA) -> 1 + + callback() -> 1352 + collect(CUMULATIVE) -> 1352 + callback() -> 2324 + collect(CUMULATIVE) -> 2324 + callback() -> 4542 + collect(CUMULATIVE) -> 4542 + + When the collection aggregation temporality does not match the + instrument aggregation temporality, then a conversion is made. For this + purpose, this aggregation keeps a private attribute, + self._previous_value. + + When the instrument is synchronous: + + self._previous_value is the sum of every previously + collected (delta) value. In this case, the returned (cumulative) value + will be: + + self._previous_value + value + + synchronous_instrument.add(2) + collect(CUMULATIVE) -> 2 + synchronous_instrument.add(3) + collect(CUMULATIVE) -> 5 + synchronous_instrument.add(1) + collect(CUMULATIVE) -> 6 + + Also, as a diagram: + + time -> + + self._previous_value + |-------------| + + value (delta) + |----| + + returned value (cumulative) + |------------------| + + When the instrument is asynchronous: + + self._previous_value is the value of the previously + collected (cumulative) value. In this case, the returned (delta) value + will be: + + value - self._previous_value + + callback() -> 1352 + collect(DELTA) -> 1352 + callback() -> 2324 + collect(DELTA) -> 972 + callback() -> 4542 + collect(DELTA) -> 2218 + + Also, as a diagram: + + time -> + + self._previous_value + |-------------| + + value (cumulative) + |------------------| + + returned value (delta) + |----| + """ + + with self._lock: + value = self._value + self._value = None + + if self._instrument_aggregation_temporality is AggregationTemporality.DELTA: + # This happens when the corresponding instrument for this + # aggregation is synchronous. + if collection_aggregation_temporality is AggregationTemporality.DELTA: + previous_collection_start_nano = self._previous_collection_start_nano + self._previous_collection_start_nano = collection_start_nano + + if value is None: + return None + + return NumberDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=previous_collection_start_nano, + time_unix_nano=collection_start_nano, + value=value, + ) + + if value is None: + value = 0 + + self._previous_value = value + self._previous_value + + return NumberDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=self._start_time_unix_nano, + time_unix_nano=collection_start_nano, + value=self._previous_value, + ) + + # This happens when the corresponding instrument for this + # aggregation is asynchronous. + + if value is None: + # This happens when the corresponding instrument callback + # does not produce measurements. + return None + + if collection_aggregation_temporality is AggregationTemporality.DELTA: + result_value = value - self._previous_value + + self._previous_value = value + + previous_collection_start_nano = self._previous_collection_start_nano + self._previous_collection_start_nano = collection_start_nano + + return NumberDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=previous_collection_start_nano, + time_unix_nano=collection_start_nano, + value=result_value, + ) + + return NumberDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=self._start_time_unix_nano, + time_unix_nano=collection_start_nano, + value=value, + ) + + +class _LastValueAggregation(_Aggregation[GaugePoint]): + def __init__( + self, + attributes: Attributes, + reservoir_builder: ExemplarReservoirBuilder, + instrument_is_synchronous: bool, + ): + super().__init__(attributes, reservoir_builder) + self._instrument_is_synchronous = instrument_is_synchronous + self._value = None + + def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True): + with self._lock: + self._value = measurement.value + + self._sample_exemplar(measurement, should_sample_exemplar) + + def collect( + self, + collection_aggregation_temporality: AggregationTemporality, + collection_start_nano: int, + ) -> _DataPointVarT | None: + """ + Atomically return a point for the current value of the metric. + """ + with self._lock: + if self._value is None: + return None + value = self._value + if not ( + self._instrument_is_synchronous + and collection_aggregation_temporality is AggregationTemporality.CUMULATIVE + ): + self._value = None + + exemplars = self._collect_exemplars() + + return NumberDataPoint( + attributes=self._attributes, + exemplars=exemplars, + start_time_unix_nano=None, + time_unix_nano=collection_start_nano, + value=value, + ) + + +_DEFAULT_EXPLICIT_BUCKET_HISTOGRAM_AGGREGATION_BOUNDARIES: Sequence[float] = ( + 0.0, + 5.0, + 10.0, + 25.0, + 50.0, + 75.0, + 100.0, + 250.0, + 500.0, + 750.0, + 1000.0, + 2500.0, + 5000.0, + 7500.0, + 10000.0, +) + + +class _ExplicitBucketHistogramAggregation(_Aggregation[HistogramPoint]): + def __init__( + self, + attributes: Attributes, + instrument_aggregation_temporality: AggregationTemporality, + start_time_unix_nano: int, + reservoir_builder: ExemplarReservoirBuilder, + boundaries: Sequence[float] | None = None, + record_min_max: bool = True, + ): + if boundaries is None: + boundaries = _DEFAULT_EXPLICIT_BUCKET_HISTOGRAM_AGGREGATION_BOUNDARIES + if boundaries: + for idx, bound in enumerate(boundaries): + if not math.isfinite(bound): + raise ValueError(f"invalid boundary: {bound!r}") + if idx and boundaries[idx - 1] >= bound: + raise ValueError("boundaries must be strictly increasing") + super().__init__( + attributes, + reservoir_builder=partial(reservoir_builder, boundaries=boundaries), + ) + + self._instrument_aggregation_temporality = instrument_aggregation_temporality + self._start_time_unix_nano = start_time_unix_nano + self._boundaries = tuple(boundaries) + self._record_min_max = record_min_max + + self._value = None + self._min = math.inf + self._max = -math.inf + self._sum = 0 + + self._previous_value = None + self._previous_min = math.inf + self._previous_max = -math.inf + self._previous_sum = 0 + + self._previous_collection_start_nano = self._start_time_unix_nano + + def _get_empty_bucket_counts(self) -> list[int]: + return [0] * (len(self._boundaries) + 1) + + def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: + with self._lock: + if self._value is None: + self._value = self._get_empty_bucket_counts() + + measurement_value = measurement.value + + self._sum += measurement_value + + if self._record_min_max: + self._min = min(self._min, measurement_value) + self._max = max(self._max, measurement_value) + + self._value[bisect_left(self._boundaries, measurement_value)] += 1 + + self._sample_exemplar(measurement, should_sample_exemplar) + + def collect( + self, + collection_aggregation_temporality: AggregationTemporality, + collection_start_nano: int, + ) -> _DataPointVarT | None: + """ + Atomically return a point for the current value of the metric. + """ + + with self._lock: + value = self._value + sum_ = self._sum + min_ = self._min + max_ = self._max + + self._value = None + self._sum = 0 + self._min = math.inf + self._max = -math.inf + + if self._instrument_aggregation_temporality is AggregationTemporality.DELTA: + # This happens when the corresponding instrument for this + # aggregation is synchronous. + if collection_aggregation_temporality is AggregationTemporality.DELTA: + previous_collection_start_nano = self._previous_collection_start_nano + self._previous_collection_start_nano = collection_start_nano + + if value is None: + return None + + return HistogramDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=previous_collection_start_nano, + time_unix_nano=collection_start_nano, + count=sum(value), + sum=sum_, + bucket_counts=tuple(value), + explicit_bounds=self._boundaries, + min=min_, + max=max_, + ) + + if value is None: + value = self._get_empty_bucket_counts() + + if self._previous_value is None: + self._previous_value = self._get_empty_bucket_counts() + + self._previous_value = [ + value_element + previous_value_element + for ( + value_element, + previous_value_element, + ) in zip(value, self._previous_value) + ] + self._previous_min = min(min_, self._previous_min) + self._previous_max = max(max_, self._previous_max) + self._previous_sum = sum_ + self._previous_sum + + return HistogramDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=self._start_time_unix_nano, + time_unix_nano=collection_start_nano, + count=sum(self._previous_value), + sum=self._previous_sum, + bucket_counts=tuple(self._previous_value), + explicit_bounds=self._boundaries, + min=self._previous_min, + max=self._previous_max, + ) + + return None + + +# pylint: disable=protected-access +class _ExponentialBucketHistogramAggregation(_Aggregation[HistogramPoint]): + # _min_max_size and _max_max_size are the smallest and largest values + # the max_size parameter may have, respectively. + + # _min_max_size is is the smallest reasonable value which is small enough + # to contain the entire normal floating point range at the minimum scale. + _min_max_size = 2 + + # _max_max_size is an arbitrary limit meant to limit accidental creation of + # giant exponential bucket histograms. + _max_max_size = 16384 + + def __init__( + self, + attributes: Attributes, + reservoir_builder: ExemplarReservoirBuilder, + instrument_aggregation_temporality: AggregationTemporality, + start_time_unix_nano: int, + # This is the default maximum number of buckets per positive or + # negative number range. The value 160 is specified by OpenTelemetry. + # See the derivation here: + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exponential-bucket-histogram-aggregation) + max_size: int = 160, + max_scale: int = 20, + record_min_max: bool = True, + ): + # max_size is the maximum capacity of the positive and negative + # buckets. + # _sum is the sum of all the values aggregated by this aggregator. + # _count is the count of all calls to aggregate. + # _zero_count is the count of all the calls to aggregate when the value + # to be aggregated is exactly 0. + # _min is the smallest value aggregated by this aggregator. + # _max is the smallest value aggregated by this aggregator. + # _positive holds the positive values. + # _negative holds the negative values by their absolute value. + if max_size < self._min_max_size: + raise ValueError(f"Buckets max size {max_size} is smaller than minimum max size {self._min_max_size}") + + if max_size > self._max_max_size: + raise ValueError(f"Buckets max size {max_size} is larger than maximum max size {self._max_max_size}") + if max_scale > 20: + _logger.warning( + "max_scale is set to %s which is larger than the recommended value of 20", + max_scale, + ) + + # This aggregation is analogous to _ExplicitBucketHistogramAggregation, + # the only difference is that with every call to aggregate, the size + # and amount of buckets can change (in + # _ExplicitBucketHistogramAggregation both size and amount of buckets + # remain constant once it is instantiated). + + super().__init__( + attributes, + reservoir_builder=partial(reservoir_builder, size=min(20, max_size)), + ) + + self._instrument_aggregation_temporality = instrument_aggregation_temporality + self._start_time_unix_nano = start_time_unix_nano + self._max_size = max_size + self._max_scale = max_scale + self._record_min_max = record_min_max + + self._value_positive = None + self._value_negative = None + self._min = math.inf + self._max = -math.inf + self._sum = 0 + self._count = 0 + self._zero_count = 0 + self._scale = None + + self._previous_value_positive = None + self._previous_value_negative = None + self._previous_min = math.inf + self._previous_max = -math.inf + self._previous_sum = 0 + self._previous_count = 0 + self._previous_zero_count = 0 + self._previous_scale = None + + self._previous_collection_start_nano = self._start_time_unix_nano + + self._mapping = self._new_mapping(self._max_scale) + + def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: + # pylint: disable=too-many-branches,too-many-statements, too-many-locals + + with self._lock: + if self._value_positive is None: + self._value_positive = Buckets() + if self._value_negative is None: + self._value_negative = Buckets() + + measurement_value = measurement.value + + self._sum += measurement_value + + if self._record_min_max: + self._min = min(self._min, measurement_value) + self._max = max(self._max, measurement_value) + + self._count += 1 + + if measurement_value == 0: + self._zero_count += 1 + + if self._count == self._zero_count: + self._scale = 0 + + return + + if measurement_value > 0: + value = self._value_positive + + else: + measurement_value = -measurement_value + value = self._value_negative + + # The following code finds out if it is necessary to change the + # buckets to hold the incoming measurement_value, changes them if + # necessary. This process does not exist in + # _ExplicitBucketHistogram aggregation because the buckets there + # are constant in size and amount. + index = self._mapping.map_to_index(measurement_value) + + is_rescaling_needed = False + low, high = 0, 0 + + if len(value) == 0: + value.index_start = index + value.index_end = index + value.index_base = index + + elif index < value.index_start and (value.index_end - index) >= self._max_size: + is_rescaling_needed = True + low = index + high = value.index_end + + elif index > value.index_end and (index - value.index_start) >= self._max_size: + is_rescaling_needed = True + low = value.index_start + high = index + + if is_rescaling_needed: + scale_change = self._get_scale_change(low, high) + self._downscale( + scale_change, + self._value_positive, + self._value_negative, + ) + self._mapping = self._new_mapping(self._mapping.scale - scale_change) + + index = self._mapping.map_to_index(measurement_value) + + self._scale = self._mapping.scale + + if index < value.index_start: + span = value.index_end - index + + if span >= len(value.counts): + value.grow(span + 1, self._max_size) + + value.index_start = index + + elif index > value.index_end: + span = index - value.index_start + + if span >= len(value.counts): + value.grow(span + 1, self._max_size) + + value.index_end = index + + bucket_index = index - value.index_base + + if bucket_index < 0: + bucket_index += len(value.counts) + + # Now the buckets have been changed if needed and bucket_index will + # be used to increment the counter of the bucket that needs to be + # incremented. + + # This is analogous to + # self._value[bisect_left(self._boundaries, measurement_value)] += 1 + # in _ExplicitBucketHistogramAggregation.aggregate + value.increment_bucket(bucket_index) + + self._sample_exemplar(measurement, should_sample_exemplar) + + def collect( + self, + collection_aggregation_temporality: AggregationTemporality, + collection_start_nano: int, + ) -> _DataPointVarT | None: + """ + Atomically return a point for the current value of the metric. + """ + + # pylint: disable=too-many-statements, too-many-locals + with self._lock: + value_positive = self._value_positive + value_negative = self._value_negative + sum_ = self._sum + min_ = self._min + max_ = self._max + count = self._count + zero_count = self._zero_count + scale = self._scale + + self._value_positive = None + self._value_negative = None + self._sum = 0 + self._min = math.inf + self._max = -math.inf + self._count = 0 + self._zero_count = 0 + self._scale = None + + if self._instrument_aggregation_temporality is AggregationTemporality.DELTA: + # This happens when the corresponding instrument for this + # aggregation is synchronous. + if collection_aggregation_temporality is AggregationTemporality.DELTA: + previous_collection_start_nano = self._previous_collection_start_nano + self._previous_collection_start_nano = collection_start_nano + + if value_positive is None and value_negative is None: + return None + + return ExponentialHistogramDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=previous_collection_start_nano, + time_unix_nano=collection_start_nano, + count=count, + sum=sum_, + scale=scale, + zero_count=zero_count, + positive=BucketsPoint( + offset=value_positive.offset, + bucket_counts=(value_positive.get_offset_counts()), + ), + negative=BucketsPoint( + offset=value_negative.offset, + bucket_counts=(value_negative.get_offset_counts()), + ), + # FIXME: Find the right value for flags + flags=0, + min=min_, + max=max_, + ) + + # Here collection_temporality is CUMULATIVE. + # instrument_temporality is always DELTA for the time being. + # Here we need to handle the case where: + # collect is called after at least one other call to collect + # (there is data in previous buckets, a call to merge is needed + # to handle possible differences in bucket sizes). + # collect is called without another call previous call to + # collect was made (there is no previous buckets, previous, + # empty buckets that are the same scale of the current buckets + # need to be made so that they can be cumulatively aggregated + # to the current buckets). + + if value_positive is None and self._previous_value_positive is None: + # This happens if collect is called for the first time + # and aggregate has not yet been called. + value_positive = Buckets() + self._previous_value_positive = value_positive.copy_empty() + if value_negative is None and self._previous_value_negative is None: + value_negative = Buckets() + self._previous_value_negative = value_negative.copy_empty() + if scale is None and self._previous_scale is None: + scale = self._mapping.scale + self._previous_scale = scale + + if value_positive is not None and self._previous_value_positive is None: + # This happens when collect is called the very first time + # and aggregate has been called before. + + # We need previous buckets to add them to the current ones. + # When collect is called for the first time, there are no + # previous buckets, so we need to create empty buckets to + # add them to the current ones. The addition of empty + # buckets to the current ones will result in the current + # ones unchanged. + + # The way the previous buckets are generated here is + # different from the explicit bucket histogram where + # the size and amount of the buckets does not change once + # they are instantiated. Here, the size and amount of the + # buckets can change with every call to aggregate. In order + # to get empty buckets that can be added to the current + # ones resulting in the current ones unchanged we need to + # generate empty buckets that have the same size and amount + # as the current ones, this is what copy_empty does. + self._previous_value_positive = value_positive.copy_empty() + if value_negative is not None and self._previous_value_negative is None: + self._previous_value_negative = value_negative.copy_empty() + if scale is not None and self._previous_scale is None: + self._previous_scale = scale + + if value_positive is None and self._previous_value_positive is not None: + value_positive = self._previous_value_positive.copy_empty() + if value_negative is None and self._previous_value_negative is not None: + value_negative = self._previous_value_negative.copy_empty() + if scale is None and self._previous_scale is not None: + scale = self._previous_scale + + # here self._previous_value_negative and self._previous_value_positive are not Optional anymore + self._previous_value_negative = cast(Buckets, self._previous_value_negative) + self._previous_value_positive = cast(Buckets, self._previous_value_positive) + + min_scale = min(self._previous_scale, scale) + + low_positive, high_positive = self._get_low_high_previous_current( + self._previous_value_positive, + value_positive, + scale, + min_scale, + ) + low_negative, high_negative = self._get_low_high_previous_current( + self._previous_value_negative, + value_negative, + scale, + min_scale, + ) + + min_scale = min( + min_scale - self._get_scale_change(low_positive, high_positive), + min_scale - self._get_scale_change(low_negative, high_negative), + ) + + self._downscale( + self._previous_scale - min_scale, + self._previous_value_positive, + self._previous_value_negative, + ) + + # self._merge adds the values from value to + # self._previous_value, this is analogous to + # self._previous_value = [ + # value_element + previous_value_element + # for ( + # value_element, + # previous_value_element, + # ) in zip(value, self._previous_value) + # ] + # in _ExplicitBucketHistogramAggregation.collect. + self._merge( + self._previous_value_positive, + value_positive, + scale, + min_scale, + collection_aggregation_temporality, + ) + self._merge( + self._previous_value_negative, + value_negative, + scale, + min_scale, + collection_aggregation_temporality, + ) + + self._previous_min = min(min_, self._previous_min) + self._previous_max = max(max_, self._previous_max) + self._previous_sum = sum_ + self._previous_sum + self._previous_count = count + self._previous_count + self._previous_zero_count = zero_count + self._previous_zero_count + self._previous_scale = min_scale + + return ExponentialHistogramDataPoint( + attributes=self._attributes, + exemplars=self._collect_exemplars(), + start_time_unix_nano=self._start_time_unix_nano, + time_unix_nano=collection_start_nano, + count=self._previous_count, + sum=self._previous_sum, + scale=self._previous_scale, + zero_count=self._previous_zero_count, + positive=BucketsPoint( + offset=self._previous_value_positive.offset, + bucket_counts=(self._previous_value_positive.get_offset_counts()), + ), + negative=BucketsPoint( + offset=self._previous_value_negative.offset, + bucket_counts=(self._previous_value_negative.get_offset_counts()), + ), + # FIXME: Find the right value for flags + flags=0, + min=self._previous_min, + max=self._previous_max, + ) + + return None + + def _get_low_high_previous_current( + self, + previous_point_buckets, + current_point_buckets, + current_scale, + min_scale, + ): + (previous_point_low, previous_point_high) = self._get_low_high( + previous_point_buckets, self._previous_scale, min_scale + ) + (current_point_low, current_point_high) = self._get_low_high(current_point_buckets, current_scale, min_scale) + + if current_point_low > current_point_high: + low = previous_point_low + high = previous_point_high + + elif previous_point_low > previous_point_high: + low = current_point_low + high = current_point_high + + else: + low = min(previous_point_low, current_point_low) + high = max(previous_point_high, current_point_high) + + return low, high + + @staticmethod + def _get_low_high(buckets, scale, min_scale): + if buckets.counts == [0]: + return 0, -1 + + shift = scale - min_scale + + return buckets.index_start >> shift, buckets.index_end >> shift + + @staticmethod + def _new_mapping(scale: int) -> Mapping: + if scale <= 0: + return ExponentMapping(scale) + return LogarithmMapping(scale) + + def _get_scale_change(self, low, high): + change = 0 + + while high - low >= self._max_size: + high = high >> 1 + low = low >> 1 + + change += 1 + + return change + + @staticmethod + def _downscale(change: int, positive, negative): + if change == 0: + return + + if change < 0: + # pylint: disable=broad-exception-raised + raise Exception("Invalid change of scale") + + positive.downscale(change) + negative.downscale(change) + + def _merge( + self, + previous_buckets: Buckets, + current_buckets: Buckets, + current_scale, + min_scale, + aggregation_temporality, + ): + current_change = current_scale - min_scale + + for current_bucket_index, current_bucket in enumerate(current_buckets.counts): + if current_bucket == 0: + continue + + # Not considering the case where len(previous_buckets) == 0. This + # would not happen because self._previous_point is only assigned to + # an ExponentialHistogramDataPoint object if self._count != 0. + + current_index = current_buckets.index_base + current_bucket_index + if current_index > current_buckets.index_end: + current_index -= len(current_buckets.counts) + + index = current_index >> current_change + + if index < previous_buckets.index_start: + span = previous_buckets.index_end - index + + if span >= self._max_size: + # pylint: disable=broad-exception-raised + raise Exception("Incorrect merge scale") + + if span >= len(previous_buckets.counts): + previous_buckets.grow(span + 1, self._max_size) + + previous_buckets.index_start = index + + if index > previous_buckets.index_end: + span = index - previous_buckets.index_start + + if span >= self._max_size: + # pylint: disable=broad-exception-raised + raise Exception("Incorrect merge scale") + + if span >= len(previous_buckets.counts): + previous_buckets.grow(span + 1, self._max_size) + + previous_buckets.index_end = index + + bucket_index = index - previous_buckets.index_base + + if bucket_index < 0: + bucket_index += len(previous_buckets.counts) + + if aggregation_temporality is AggregationTemporality.DELTA: + current_bucket = -current_bucket + + previous_buckets.increment_bucket(bucket_index, increment=current_bucket) + + +class Aggregation(ABC): + """ + Base class for all aggregation types. + """ + + @abstractmethod + def _create_aggregation( + self, + instrument: _Instrument, + attributes: Attributes, + reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], + start_time_unix_nano: int, + ) -> _Aggregation: + """Creates an aggregation""" + + +class DefaultAggregation(Aggregation): + """ + The default aggregation to be used in a `View`. + + This aggregation will create an actual aggregation depending on the + instrument type, as specified next: + + ==================================================== ==================================== + Instrument Aggregation + ==================================================== ==================================== + `opentelemetry.sdk.metrics.Counter` `SumAggregation` + `opentelemetry.sdk.metrics.UpDownCounter` `SumAggregation` + `opentelemetry.sdk.metrics.ObservableCounter` `SumAggregation` + `opentelemetry.sdk.metrics.ObservableUpDownCounter` `SumAggregation` + `opentelemetry.sdk.metrics.Histogram` `ExplicitBucketHistogramAggregation` + `opentelemetry.sdk.metrics.ObservableGauge` `LastValueAggregation` + ==================================================== ==================================== + """ + + def _create_aggregation( + self, + instrument: _Instrument, + attributes: Attributes, + reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], + start_time_unix_nano: int, + ) -> _Aggregation: + # pylint: disable=too-many-return-statements + if isinstance(instrument, Counter): + return _SumAggregation( + attributes, + reservoir_builder=reservoir_factory(_SumAggregation), + instrument_is_monotonic=True, + instrument_aggregation_temporality=(AggregationTemporality.DELTA), + start_time_unix_nano=start_time_unix_nano, + ) + if isinstance(instrument, UpDownCounter): + return _SumAggregation( + attributes, + reservoir_builder=reservoir_factory(_SumAggregation), + instrument_is_monotonic=False, + instrument_aggregation_temporality=(AggregationTemporality.DELTA), + start_time_unix_nano=start_time_unix_nano, + ) + + if isinstance(instrument, ObservableCounter): + return _SumAggregation( + attributes, + reservoir_builder=reservoir_factory(_SumAggregation), + instrument_is_monotonic=True, + instrument_aggregation_temporality=(AggregationTemporality.CUMULATIVE), + start_time_unix_nano=start_time_unix_nano, + ) + + if isinstance(instrument, ObservableUpDownCounter): + return _SumAggregation( + attributes, + reservoir_builder=reservoir_factory(_SumAggregation), + instrument_is_monotonic=False, + instrument_aggregation_temporality=(AggregationTemporality.CUMULATIVE), + start_time_unix_nano=start_time_unix_nano, + ) + + if isinstance(instrument, Histogram): + boundaries = instrument._advisory.explicit_bucket_boundaries + return _ExplicitBucketHistogramAggregation( + attributes, + reservoir_builder=reservoir_factory(_ExplicitBucketHistogramAggregation), + instrument_aggregation_temporality=(AggregationTemporality.DELTA), + boundaries=boundaries, + start_time_unix_nano=start_time_unix_nano, + ) + + if isinstance(instrument, ObservableGauge): + return _LastValueAggregation( + attributes, + reservoir_builder=reservoir_factory(_LastValueAggregation), + instrument_is_synchronous=False, + ) + + if isinstance(instrument, _Gauge): + return _LastValueAggregation( + attributes, + reservoir_builder=reservoir_factory(_LastValueAggregation), + instrument_is_synchronous=True, + ) + + # pylint: disable=broad-exception-raised + raise Exception(f"Invalid instrument type {type(instrument)} found") + + +class ExponentialBucketHistogramAggregation(Aggregation): + """This aggregation informs the SDK to collect: + + - Count of Measurement values falling using a base-2 exponential formula. + - Arithmetic sum of Measurement values in population. This SHOULD NOT be collected when used with instruments that record negative measurements, e.g. UpDownCounter or ObservableGauge. + - Min (optional) Measurement value in population. + - Max (optional) Measurement value in population. + + Args: + max_size: Maximum number of buckets in each of the positive and negative ranges, not counting the special zero bucket. + max_scale: Maximum scale factor. + record_min_max: Whether to record min and max. + """ + + def __init__( + self, + max_size: int = 160, + max_scale: int = 20, + record_min_max: bool = True, + ): + self._max_size = max_size + self._max_scale = max_scale + self._record_min_max = record_min_max + + def _create_aggregation( + self, + instrument: _Instrument, + attributes: Attributes, + reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], + start_time_unix_nano: int, + ) -> _Aggregation: + instrument_aggregation_temporality = AggregationTemporality.UNSPECIFIED + if isinstance(instrument, Synchronous): + instrument_aggregation_temporality = AggregationTemporality.DELTA + elif isinstance(instrument, Asynchronous): + instrument_aggregation_temporality = AggregationTemporality.CUMULATIVE + + return _ExponentialBucketHistogramAggregation( + attributes, + reservoir_factory(_ExponentialBucketHistogramAggregation), + instrument_aggregation_temporality, + start_time_unix_nano, + max_size=self._max_size, + max_scale=self._max_scale, + record_min_max=self._record_min_max, + ) + + +class ExplicitBucketHistogramAggregation(Aggregation): + """This aggregation informs the SDK to collect: + + - Count of Measurement values falling within explicit bucket boundaries. + - Arithmetic sum of Measurement values in population. This SHOULD NOT be collected when used with instruments that record negative measurements, e.g. UpDownCounter or ObservableGauge. + - Min (optional) Measurement value in population. + - Max (optional) Measurement value in population. + + + Args: + boundaries: Array of increasing values representing explicit bucket boundary values. + record_min_max: Whether to record min and max. + """ + + def __init__( + self, + boundaries: Sequence[float] | None = None, + record_min_max: bool = True, + ) -> None: + self._boundaries = boundaries + self._record_min_max = record_min_max + + def _create_aggregation( + self, + instrument: _Instrument, + attributes: Attributes, + reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], + start_time_unix_nano: int, + ) -> _Aggregation: + instrument_aggregation_temporality = AggregationTemporality.UNSPECIFIED + if isinstance(instrument, Synchronous): + instrument_aggregation_temporality = AggregationTemporality.DELTA + elif isinstance(instrument, Asynchronous): + instrument_aggregation_temporality = AggregationTemporality.CUMULATIVE + + if self._boundaries is not None: + boundaries = self._boundaries + else: + # guard for usage with instruments without advisory + advisory = getattr(instrument, "_advisory", None) + boundaries = advisory.explicit_bucket_boundaries if advisory is not None else None + + return _ExplicitBucketHistogramAggregation( + attributes, + instrument_aggregation_temporality, + start_time_unix_nano, + reservoir_factory(_ExplicitBucketHistogramAggregation), + boundaries, + self._record_min_max, + ) + + +class SumAggregation(Aggregation): + """This aggregation informs the SDK to collect: + + - The arithmetic sum of Measurement values. + """ + + def _create_aggregation( + self, + instrument: _Instrument, + attributes: Attributes, + reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], + start_time_unix_nano: int, + ) -> _Aggregation: + instrument_aggregation_temporality = AggregationTemporality.UNSPECIFIED + if isinstance(instrument, Synchronous): + instrument_aggregation_temporality = AggregationTemporality.DELTA + elif isinstance(instrument, Asynchronous): + instrument_aggregation_temporality = AggregationTemporality.CUMULATIVE + + return _SumAggregation( + attributes, + isinstance(instrument, (Counter, ObservableCounter)), + instrument_aggregation_temporality, + start_time_unix_nano, + reservoir_factory(_SumAggregation), + ) + + +class LastValueAggregation(Aggregation): + """ + This aggregation informs the SDK to collect: + + - The last Measurement. + - The timestamp of the last Measurement. + """ + + def _create_aggregation( + self, + instrument: _Instrument, + attributes: Attributes, + reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], + start_time_unix_nano: int, + ) -> _Aggregation: + return _LastValueAggregation( + attributes, + reservoir_builder=reservoir_factory(_LastValueAggregation), + instrument_is_synchronous=isinstance(instrument, Synchronous), + ) + + +class DropAggregation(Aggregation): + """Using this aggregation will make all measurements be ignored.""" + + def _create_aggregation( + self, + instrument: _Instrument, + attributes: Attributes, + reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], + start_time_unix_nano: int, + ) -> _Aggregation: + return _DropAggregation(attributes, reservoir_factory(_DropAggregation)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py new file mode 100644 index 00000000000..5ae8519eb9a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py @@ -0,0 +1,6 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +class MetricsTimeoutError(Exception): + """Raised when a metrics function times out""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py new file mode 100644 index 00000000000..8068406a280 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py @@ -0,0 +1,28 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from .exemplar import Exemplar +from .exemplar_filter import ( + AlwaysOffExemplarFilter, + AlwaysOnExemplarFilter, + ExemplarFilter, + TraceBasedExemplarFilter, +) +from .exemplar_reservoir import ( + AlignedHistogramBucketExemplarReservoir, + ExemplarReservoir, + ExemplarReservoirBuilder, + SimpleFixedSizeExemplarReservoir, +) + +__all__ = [ + "AlignedHistogramBucketExemplarReservoir", + "AlwaysOffExemplarFilter", + "AlwaysOnExemplarFilter", + "Exemplar", + "ExemplarFilter", + "ExemplarReservoir", + "ExemplarReservoirBuilder", + "SimpleFixedSizeExemplarReservoir", + "TraceBasedExemplarFilter", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py new file mode 100644 index 00000000000..cb51c4b8a61 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py @@ -0,0 +1,33 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import dataclasses + +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + + +@dataclasses.dataclass(frozen=True) +class Exemplar: + """A representation of an exemplar, which is a sample input measurement. + + Exemplars also hold information about the environment when the measurement + was recorded, for example the span and trace ID of the active span when the + exemplar was recorded. + + Attributes: + trace_id: (optional) The trace associated with a recording + span_id: (optional) The span associated with a recording + time_unix_nano: The time of the observation + value: The recorded value + filtered_attributes: A set of filtered attributes which provide additional insight into the Context when the observation was made. + + References: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#exemplars + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar + """ + + filtered_attributes: Attributes + value: int | float + time_unix_nano: int + span_id: int | None = None + trace_id: int | None = None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py new file mode 100644 index 00000000000..815702c7397 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py @@ -0,0 +1,120 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from abc import ABC, abstractmethod + +from opentelemetry.agent._vendor.opentelemetry import trace +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace.span import INVALID_SPAN +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + + +class ExemplarFilter(ABC): + """``ExemplarFilter`` determines which measurements are eligible for becoming an + ``Exemplar``. + + Exemplar filters are used to filter measurements before attempting to store them + in a reservoir. + + Reference: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplarfilter + """ + + @abstractmethod + def should_sample( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> bool: + """Returns whether or not a reservoir should attempt to filter a measurement. + + Args: + value: The value of the measurement + timestamp: A timestamp that best represents when the measurement was taken + attributes: The complete set of measurement attributes + context: The Context of the measurement + """ + raise NotImplementedError("ExemplarFilter.should_sample is not implemented") + + +class AlwaysOnExemplarFilter(ExemplarFilter): + """An ExemplarFilter which makes all measurements eligible for being an Exemplar. + + Reference: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#alwayson + """ + + def should_sample( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> bool: + """Returns whether or not a reservoir should attempt to filter a measurement. + + Args: + value: The value of the measurement + timestamp: A timestamp that best represents when the measurement was taken + attributes: The complete set of measurement attributes + context: The Context of the measurement + """ + return True + + +class AlwaysOffExemplarFilter(ExemplarFilter): + """An ExemplarFilter which makes no measurements eligible for being an Exemplar. + + Using this ExemplarFilter is as good as disabling Exemplar feature. + + Reference: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#alwaysoff + """ + + def should_sample( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> bool: + """Returns whether or not a reservoir should attempt to filter a measurement. + + Args: + value: The value of the measurement + timestamp: A timestamp that best represents when the measurement was taken + attributes: The complete set of measurement attributes + context: The Context of the measurement + """ + return False + + +class TraceBasedExemplarFilter(ExemplarFilter): + """An ExemplarFilter which makes those measurements eligible for being an Exemplar, + which are recorded in the context of a sampled parent span. + + Reference: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#tracebased + """ + + def should_sample( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> bool: + """Returns whether or not a reservoir should attempt to filter a measurement. + + Args: + value: The value of the measurement + timestamp: A timestamp that best represents when the measurement was taken + attributes: The complete set of measurement attributes + context: The Context of the measurement + """ + span = trace.get_current_span(context) + if span == INVALID_SPAN: + return False + return span.get_span_context().trace_flags.sampled diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py new file mode 100644 index 00000000000..0904d2e7c07 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py @@ -0,0 +1,291 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from abc import ABC, abstractmethod +from collections import defaultdict +from collections.abc import Callable, Mapping, Sequence +from random import randrange +from threading import Lock +from typing import ( + Any, +) + +from opentelemetry.agent._vendor.opentelemetry import trace +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace.span import INVALID_SPAN +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +from .exemplar import Exemplar + + +class ExemplarReservoir(ABC): + """ExemplarReservoir provide a method to offer measurements to the reservoir + and another to collect accumulated Exemplars. + + Note: + The constructor MUST accept ``**kwargs`` that may be set from aggregation + parameters. + + Note: + All methods MUST be safe to call concurrently. Measurements are offered + from application threads while a metric reader collects from its own + thread. + + Reference: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplarreservoir + """ + + @abstractmethod + def offer( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> None: + """Offers a measurement to be sampled. + + Args: + value: Measured value + time_unix_nano: Measurement instant + attributes: Measurement attributes + context: Measurement context + """ + raise NotImplementedError("ExemplarReservoir.offer is not implemented") + + @abstractmethod + def collect(self, point_attributes: Attributes) -> list[Exemplar]: + """Returns accumulated Exemplars and also resets the reservoir for the next + sampling period + + Args: + point_attributes: The attributes associated with metric point. + + Returns: + a list of ``opentelemetry.sdk.metrics._internal.exemplar.exemplar.Exemplar`` s. Returned + exemplars contain the attributes that were filtered out by the aggregator, + but recorded alongside the original measurement. + """ + raise NotImplementedError("ExemplarReservoir.collect is not implemented") + + +class ExemplarBucket: + def __init__(self) -> None: + self.__value: int | float = 0 + self.__attributes: Attributes = None + self.__time_unix_nano: int = 0 + self.__span_id: int | None = None + self.__trace_id: int | None = None + self.__offered: bool = False + + def offer( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> None: + """Offers a measurement to be sampled. + + Args: + value: Measured value + time_unix_nano: Measurement instant + attributes: Measurement attributes + context: Measurement context + """ + self.__value = value + self.__time_unix_nano = time_unix_nano + self.__attributes = attributes + span = trace.get_current_span(context) + if span != INVALID_SPAN: + span_context = span.get_span_context() + self.__span_id = span_context.span_id + self.__trace_id = span_context.trace_id + + self.__offered = True + + def collect(self, point_attributes: Attributes) -> Exemplar | None: + """May return an Exemplar and resets the bucket for the next sampling period.""" + if not self.__offered: + return None + + # filters out attributes from the measurement that are already included in the metric data point + # See the specification for more details: + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar + filtered_attributes = ( + {k: v for k, v in self.__attributes.items() if k not in point_attributes} if self.__attributes else None + ) + + exemplar = Exemplar( + filtered_attributes, + self.__value, + self.__time_unix_nano, + self.__span_id, + self.__trace_id, + ) + self.__reset() + return exemplar + + def __reset(self) -> None: + """Reset the bucket state after a collection cycle.""" + self.__value = 0 + self.__attributes = {} + self.__time_unix_nano = 0 + self.__span_id = None + self.__trace_id = None + self.__offered = False + + +class BucketIndexError(ValueError): + """An exception raised when the bucket index cannot be found.""" + + +class FixedSizeExemplarReservoirABC(ExemplarReservoir): + """Abstract class for a reservoir with fixed size.""" + + def __init__(self, size: int, **kwargs) -> None: + super().__init__(**kwargs) + self._size: int = size + self._reservoir_storage: Mapping[int, ExemplarBucket] = defaultdict(ExemplarBucket) + self._lock = Lock() + + def collect(self, point_attributes: Attributes) -> list[Exemplar]: + """Returns accumulated Exemplars and also resets the reservoir for the next + sampling period + + Args: + point_attributes: The attributes associated with metric point. + + Returns: + a list of ``opentelemetry.sdk.metrics._internal.exemplar.exemplar.Exemplar`` s. Returned + exemplars contain the attributes that were filtered out by the aggregator, + but recorded alongside the original measurement. + """ + with self._lock: + exemplars = [ + e + for e in (bucket.collect(point_attributes) for _, bucket in sorted(self._reservoir_storage.items())) + if e is not None + ] + self._reset() + return exemplars + + def offer( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> None: + """Offers a measurement to be sampled. + + Args: + value: Measured value + time_unix_nano: Measurement instant + attributes: Measurement attributes + context: Measurement context + """ + with self._lock: + try: + index = self._find_bucket_index(value, time_unix_nano, attributes, context) + + self._reservoir_storage[index].offer(value, time_unix_nano, attributes, context) + except BucketIndexError: + # Ignore invalid bucket index + pass + + @abstractmethod + def _find_bucket_index( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> int: + """Determines the bucket index for the given measurement. + + It should be implemented by subclasses based on specific strategies. + + Args: + value: Measured value + time_unix_nano: Measurement instant + attributes: Measurement attributes + context: Measurement context + + Returns: + The bucket index + + Raises: + BucketIndexError: If no bucket index can be found. + """ + + def _reset(self) -> None: + """Reset the reservoir by resetting any stateful logic after a collection cycle.""" + + +class SimpleFixedSizeExemplarReservoir(FixedSizeExemplarReservoirABC): + """This reservoir uses an uniformly-weighted sampling algorithm based on the number + of samples the reservoir has seen so far to determine if the offered measurements + should be sampled. + + Reference: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#simplefixedsizeexemplarreservoir + """ + + def __init__(self, size: int = 1, **kwargs) -> None: + super().__init__(size, **kwargs) + self._measurements_seen: int = 0 + + def _reset(self) -> None: + super()._reset() + self._measurements_seen = 0 + + def _find_bucket_index( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> int: + if self._measurements_seen < self._size: + self._measurements_seen += 1 + return self._measurements_seen - 1 + + self._measurements_seen += 1 + index = randrange(0, self._measurements_seen) + if index < self._size: + return index + + raise BucketIndexError("Unable to find the bucket index.") + + +class AlignedHistogramBucketExemplarReservoir(FixedSizeExemplarReservoirABC): + """This Exemplar reservoir takes a configuration parameter that is the + configuration of a Histogram. This implementation keeps the last seen measurement + that falls within a histogram bucket. + + Reference: + https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#alignedhistogrambucketexemplarreservoir + """ + + def __init__(self, boundaries: Sequence[float], **kwargs) -> None: + super().__init__(len(boundaries) + 1, **kwargs) + self._boundaries: Sequence[float] = boundaries + + def _find_bucket_index( + self, + value: float, + time_unix_nano: int, + attributes: Attributes, + context: Context, + ) -> int: + for index, boundary in enumerate(self._boundaries): + if value <= boundary: + return index + return len(self._boundaries) + + +# ExemplarReservoirBuilder: A callable that takes Aggregation parameters +# (e.g. boundaries for _ExplicitBucketHistogramAggregation) and returns +# an ExemplarReservoir instance. +ExemplarReservoirBuilder = Callable[[dict[str, Any]], ExemplarReservoir] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py new file mode 100644 index 00000000000..a8749700b00 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py @@ -0,0 +1,177 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from math import ceil, log2 + + +class Buckets: + # No method of this class is protected by locks because instances of this + # class are only used in methods that are protected by locks themselves. + + def __init__(self): + self._counts = [0] + + # The term index refers to the number of the exponential histogram bucket + # used to determine its boundaries. The lower boundary of a bucket is + # determined by base ** index and the upper boundary of a bucket is + # determined by base ** (index + 1). index values are signedto account + # for values less than or equal to 1. + + # self._index_* will all have values equal to a certain index that is + # determined by the corresponding mapping _map_to_index function and + # the value of the index depends on the value passed to _map_to_index. + + # Index of the 0th position in self._counts: self._counts[0] is the + # count in the bucket with index self.__index_base. + self.__index_base = 0 + + # self.__index_start is the smallest index value represented in + # self._counts. + self.__index_start = 0 + + # self.__index_start is the largest index value represented in + # self._counts. + self.__index_end = 0 + + @property + def index_start(self) -> int: + return self.__index_start + + @index_start.setter + def index_start(self, value: int) -> None: + self.__index_start = value + + @property + def index_end(self) -> int: + return self.__index_end + + @index_end.setter + def index_end(self, value: int) -> None: + self.__index_end = value + + @property + def index_base(self) -> int: + return self.__index_base + + @index_base.setter + def index_base(self, value: int) -> None: + self.__index_base = value + + @property + def counts(self): + return self._counts + + def get_offset_counts(self): + bias = self.__index_base - self.__index_start + return self._counts[-bias:] + self._counts[:-bias] + + def grow(self, needed: int, max_size: int) -> None: + size = len(self._counts) + bias = self.__index_base - self.__index_start + old_positive_limit = size - bias + + # 2 ** ceil(log2(needed)) finds the smallest power of two that is larger + # or equal than needed: + # 2 ** ceil(log2(1)) == 1 + # 2 ** ceil(log2(2)) == 2 + # 2 ** ceil(log2(3)) == 4 + # 2 ** ceil(log2(4)) == 4 + # 2 ** ceil(log2(5)) == 8 + # 2 ** ceil(log2(6)) == 8 + # 2 ** ceil(log2(7)) == 8 + # 2 ** ceil(log2(8)) == 8 + new_size = min(2 ** ceil(log2(needed)), max_size) + + new_positive_limit = new_size - bias + + tmp = [0] * new_size + tmp[new_positive_limit:] = self._counts[old_positive_limit:] + tmp[0:old_positive_limit] = self._counts[0:old_positive_limit] + self._counts = tmp + + @property + def offset(self) -> int: + return self.__index_start + + def __len__(self) -> int: + if len(self._counts) == 0: + return 0 + + if self.__index_end == self.__index_start and self[0] == 0: + return 0 + + return self.__index_end - self.__index_start + 1 + + def __getitem__(self, key: int) -> int: + bias = self.__index_base - self.__index_start + + if key < bias: + key += len(self._counts) + + key -= bias + + return self._counts[key] + + def downscale(self, amount: int) -> None: + """ + Rotates, then collapses 2 ** amount to 1 buckets. + """ + + bias = self.__index_base - self.__index_start + + if bias != 0: + self.__index_base = self.__index_start + + # [0, 1, 2, 3, 4] Original backing array + + self._counts = self._counts[::-1] + # [4, 3, 2, 1, 0] + + self._counts = self._counts[:bias][::-1] + self._counts[bias:][::-1] + # [3, 4, 0, 1, 2] This is a rotation of the backing array. + + size = 1 + self.__index_end - self.__index_start + each = 1 << amount + inpos = 0 + outpos = 0 + + pos = self.__index_start + + while pos <= self.__index_end: + mod = pos % each + if mod < 0: + mod += each + + index = mod + + while index < each and inpos < size: + if outpos != inpos: + self._counts[outpos] += self._counts[inpos] + self._counts[inpos] = 0 + + inpos += 1 + pos += 1 + index += 1 + + outpos += 1 + + self.__index_start >>= amount + self.__index_end >>= amount + self.__index_base = self.__index_start + + def increment_bucket(self, bucket_index: int, increment: int = 1) -> None: + self._counts[bucket_index] += increment + + def copy_empty(self) -> "Buckets": + copy = Buckets() + + # pylint: disable=no-member + # pylint: disable=protected-access + # pylint: disable=attribute-defined-outside-init + # pylint: disable=invalid-name + copy._Buckets__index_base = self._Buckets__index_base # type: ignore[reportArgumentType] + copy._Buckets__index_start = self._Buckets__index_start # type: ignore[reportArgumentType] + copy._Buckets__index_end = self._Buckets__index_end # type: ignore[reportArgumentType] + copy._counts = [0 for _ in self._counts] + + return copy diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py new file mode 100644 index 00000000000..a62a2e6b0df --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py @@ -0,0 +1,94 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from abc import ABC, abstractmethod +from threading import Lock + + +class Mapping(ABC): + """ + Parent class for `LogarithmMapping` and `ExponentialMapping`. + """ + + _mappings: dict[int, "Mapping"] + _mappings_lock: Lock + + _min_scale: int + _max_scale: int + + # pylint: disable=no-member + def __new__(cls, scale: int): + with cls._mappings_lock: + # cls._mappings and cls._mappings_lock are implemented in each of + # the child classes as a dictionary and a lock, respectively. They + # are not instantiated here because that would lead to both child + # classes having the same instance of cls._mappings and + # cls._mappings_lock. + if scale not in cls._mappings: + cls._mappings[scale] = super().__new__(cls) + cls._mappings[scale]._init(scale) + + return cls._mappings[scale] + + @abstractmethod + def _init(self, scale: int) -> None: + # pylint: disable=attribute-defined-outside-init + + if scale > self._get_max_scale(): + # pylint: disable=broad-exception-raised + raise Exception(f"scale is larger than {self._max_scale}") + + if scale < self._get_min_scale(): + # pylint: disable=broad-exception-raised + raise Exception(f"scale is smaller than {self._min_scale}") + + # The size of the exponential histogram buckets is determined by a + # parameter known as scale, larger values of scale will produce smaller + # buckets. Bucket boundaries of the exponential histogram are located + # at integer powers of the base, where: + # + # base = 2 ** (2 ** (-scale)) + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#all-scales-use-the-logarithm-function + self._scale = scale + + @abstractmethod + def _get_min_scale(self) -> int: + """ + Return the smallest possible value for the mapping scale + """ + + @abstractmethod + def _get_max_scale(self) -> int: + """ + Return the largest possible value for the mapping scale + """ + + @abstractmethod + def map_to_index(self, value: float) -> int: + """ + Maps positive floating point values to indexes corresponding to + `Mapping.scale`. Implementations are not expected to handle zeros, + +inf, NaN, or negative values. + """ + + @abstractmethod + def get_lower_boundary(self, index: int) -> float: + """ + Returns the lower boundary of a given bucket index. The index is + expected to map onto a range that is at least partially inside the + range of normal floating point values. If the corresponding + bucket's upper boundary is less than or equal to 2 ** -1022, + :class:`~opentelemetry.sdk.metrics.MappingUnderflowError` + will be raised. If the corresponding bucket's lower boundary is greater + than ``sys.float_info.max``, + :class:`~opentelemetry.sdk.metrics.MappingOverflowError` + will be raised. + """ + + @property + def scale(self) -> int: + """ + Returns the parameter that controls the resolution of this mapping. + See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/datamodel.md#exponential-scale + """ + return self._scale diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py new file mode 100644 index 00000000000..8bf64b28464 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +class MappingUnderflowError(Exception): + """ + Raised when computing the lower boundary of an index that maps into a + denormal floating point value. + """ + + +class MappingOverflowError(Exception): + """ + Raised when computing the lower boundary of an index that maps into +inf. + """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py new file mode 100644 index 00000000000..014d28c470b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py @@ -0,0 +1,145 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from math import ldexp +from threading import Lock + +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping import ( + Mapping, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.errors import ( + MappingOverflowError, + MappingUnderflowError, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.ieee_754 import ( + MANTISSA_WIDTH, + MAX_NORMAL_EXPONENT, + MIN_NORMAL_EXPONENT, + MIN_NORMAL_VALUE, + get_ieee_754_exponent, + get_ieee_754_mantissa, +) + + +class ExponentMapping(Mapping): + # Reference implementation here: + # https://github.com/open-telemetry/opentelemetry-go/blob/0e6f9c29c10d6078e8131418e1d1d166c7195d61/sdk/metric/aggregator/exponential/mapping/exponent/exponent.go + + _mappings = {} + _mappings_lock = Lock() + + _min_scale = -10 + _max_scale = 0 + + def _get_min_scale(self): + # _min_scale defines the point at which the exponential mapping + # function becomes useless for 64-bit floats. With scale -10, ignoring + # subnormal values, bucket indices range from -1 to 1. + return -10 + + def _get_max_scale(self): + # _max_scale is the largest scale supported by exponential mapping. Use + # a logarithm mapping for larger scales. + return 0 + + def _init(self, scale: int): + # pylint: disable=attribute-defined-outside-init + + super()._init(scale) + + # self._min_normal_lower_boundary_index is the largest index such that + # base ** index < MIN_NORMAL_VALUE and + # base ** (index + 1) >= MIN_NORMAL_VALUE. An exponential histogram + # bucket with this index covers the range + # (base ** index, base (index + 1)], including MIN_NORMAL_VALUE. This + # is the smallest valid index that contains at least one normal value. + index = MIN_NORMAL_EXPONENT >> -self._scale + + if -self._scale < 2: + # For scales -1 and 0, the maximum value 2 ** -1022 is a + # power-of-two multiple, meaning base ** index == MIN_NORMAL_VALUE. + # Subtracting 1 so that base ** (index + 1) == MIN_NORMAL_VALUE. + index -= 1 + + self._min_normal_lower_boundary_index = index + + # self._max_normal_lower_boundary_index is the index such that + # base**index equals the greatest representable lower boundary. An + # exponential histogram bucket with this index covers the range + # ((2 ** 1024) / base, 2 ** 1024], which includes opentelemetry.sdk. + # metrics._internal.exponential_histogram.ieee_754.MAX_NORMAL_VALUE. + # This bucket is incomplete, since the upper boundary cannot be + # represented. One greater than this index corresponds with the bucket + # containing values > 2 ** 1024. + self._max_normal_lower_boundary_index = MAX_NORMAL_EXPONENT >> -self._scale + + def map_to_index(self, value: float) -> int: + if value < MIN_NORMAL_VALUE: + return self._min_normal_lower_boundary_index + + exponent = get_ieee_754_exponent(value) + + # Positive integers are represented in binary as having an infinite + # amount of leading zeroes, for example 2 is represented as ...00010. + + # A negative integer -x is represented in binary as the complement of + # (x - 1). For example, -4 is represented as the complement of 4 - 1 + # == 3. 3 is represented as ...00011. Its compliment is ...11100, the + # binary representation of -4. + + # get_ieee_754_mantissa(value) gets the positive integer made up + # from the rightmost MANTISSA_WIDTH bits (the mantissa) of the IEEE + # 754 representation of value. If value is an exact power of 2, all + # these MANTISSA_WIDTH bits would be all zeroes, and when 1 is + # subtracted the resulting value is -1. The binary representation of + # -1 is ...111, so when these bits are right shifted MANTISSA_WIDTH + # places, the resulting value for correction is -1. If value is not an + # exact power of 2, at least one of the rightmost MANTISSA_WIDTH + # bits would be 1 (even for values whose decimal part is 0, like 5.0 + # since the IEEE 754 of such number is too the product of a power of 2 + # (defined in the exponent part of the IEEE 754 representation) and the + # value defined in the mantissa). Having at least one of the rightmost + # MANTISSA_WIDTH bit being 1 means that get_ieee_754(value) will + # always be greater or equal to 1, and when 1 is subtracted, the + # result will be greater or equal to 0, whose representation in binary + # will be of at most MANTISSA_WIDTH ones that have an infinite + # amount of leading zeroes. When those MANTISSA_WIDTH bits are + # shifted to the right MANTISSA_WIDTH places, the resulting value + # will be 0. + + # In summary, correction will be -1 if value is a power of 2, 0 if not. + + # map_to_index requires value to be a finite, positive real number. + # 0, inf, and NaN violate this precondition. + + # Zero is represented in IEEE 754 with all exponent bits set to 0, + # giving get_ieee_754_exponent a result of -1023. Since -1023 is less + # than MIN_NORMAL_EXPONENT (-1022), zero is caught by the guard above + # and returned early. + + # Inf is represented in IEEE 754 with all 11 exponent bits set to 1 + # and a mantissa of 0, giving get_ieee_754_exponent a result of 1024 + # and correction a value of -1. + + # NaN is represented in IEEE 754 with all 11 exponent bits set to 1 + # and a non-zero mantissa of unspecified bit pattern, producing an + # unspecified correction value. + + # Inf and NaN are not caught by the guard above. Callers must ensure + # that only finite, positive values are passed to map_to_index. + correction = (get_ieee_754_mantissa(value) - 1) >> MANTISSA_WIDTH + + return (exponent + correction) >> -self._scale + + def get_lower_boundary(self, index: int) -> float: + if index < self._min_normal_lower_boundary_index: + raise MappingUnderflowError() + + if index > self._max_normal_lower_boundary_index: + raise MappingOverflowError() + + return ldexp(1, index << -self._scale) + + @property + def scale(self) -> int: + return self._scale diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md new file mode 100644 index 00000000000..0cf5c8c59b3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md @@ -0,0 +1,175 @@ +# IEEE 754 Explained + +IEEE 754 is a standard that defines a way to represent certain mathematical +objects using binary numbers. + +## Binary Number Fields + +The binary numbers used in IEEE 754 can have different lengths, the length that +is interesting for the purposes of this project is 64 bits. These binary +numbers are made up of 3 contiguous fields of bits, from left to right: + +1. 1 sign bit +2. 11 exponent bits +3. 52 mantissa bits + +Depending on the values these fields have, the represented mathematical object +can be one of: + +* Floating point number +* Zero +* NaN +* Infinite + +## Floating Point Numbers + +IEEE 754 represents a floating point number $f$ using an exponential +notation with 4 components: $sign$, $mantissa$, $base$ and $exponent$: + +$$f = sign \times mantissa \times base ^ {exponent}$$ + +There are two possible representations of floating point numbers: +_normal_ and _denormal_, which have different valid values for +their $mantissa$ and $exponent$ fields. + +### Binary Representation + +$sign$, $mantissa$, and $exponent$ are represented in binary, the +representation of each component has certain details explained next. + +$base$ is always $2$ and it is not represented in binary. + +#### Sign + +$sign$ can have 2 values: + +1. $1$ if the `sign` bit is `0` +2. $-1$ if the `sign` bit is `1`. + +#### Mantissa + +##### Normal Floating Point Numbers + +$mantissa$ is a positive fractional number whose integer part is $1$, for example +$1.2345 \dots$. The `mantissa` bits represent only the fractional part and the +$mantissa$ value can be calculated as: + +$$mantissa = 1 + \sum_{i=1}^{52} b_{i} \times 2^{-i} = 1 + \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{51}}{2^{51}} + \frac{b_{52}}{2^{52}}$$ + +Where $b_{i}$ is: + +1. $0$ if the bit at the position `i - 1` is `0`. +2. $1$ if the bit at the position `i - 1` is `1`. + +##### Denormal Floating Point Numbers + +$mantissa$ is a positive fractional number whose integer part is $0$, for example +$0.12345 \dots$. The `mantissa` bits represent only the fractional part and the +$mantissa$ value can be calculated as: + +$$mantissa = \sum_{i=1}^{52} b_{i} \times 2^{-i} = \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{51}}{2^{51}} + \frac{b_{52}}{2^{52}}$$ + +Where $b_{i}$ is: + +1. $0$ if the bit at the position `i - 1` is `0`. +2. $1$ if the bit at the position `i - 1` is `1`. + +#### Exponent + +##### Normal Floating Point Numbers + +Only the following bit sequences are allowed: `00000000001` to `11111111110`. +That is, there must be at least one `0` and one `1` in the exponent bits. + +The actual value of the $exponent$ can be calculated as: + +$$exponent = v - bias$$ + +where $v$ is the value of the binary number in the exponent bits and $bias$ is $1023$. +Considering the restrictions above, the respective minimum and maximum values for the +exponent are: + +1. `00000000001` = $1$, $1 - 1023 = -1022$ +2. `11111111110` = $2046$, $2046 - 1023 = 1023$ + +So, $exponent$ is an integer in the range $\left[-1022, 1023\right]$. + + +##### Denormal Floating Point Numbers + +$exponent$ is always $-1022$. Nevertheless, it is always represented as `00000000000`. + +### Normal and Denormal Floating Point Numbers + +The smallest absolute value a normal floating point number can have is calculated +like this: + +$$1 \times 1.0\dots0 \times 2^{-1022} = 2.2250738585072014 \times 10^{-308}$$ + +Since normal floating point numbers always have a $1$ as the integer part of the +$mantissa$, then smaller values can be achieved by using the smallest possible exponent +( $-1022$ ) and a $0$ in the integer part of the $mantissa$, but significant digits are lost. + +The smallest absolute value a denormal floating point number can have is calculated +like this: + +$$1 \times 2^{-52} \times 2^{-1022} = 5 \times 10^{-324}$$ + +## Zero + +Zero is represented like this: + +* Sign bit: `X` +* Exponent bits: `00000000000` +* Mantissa bits: `0000000000000000000000000000000000000000000000000000` + +where `X` means `0` or `1`. + +## NaN + +There are 2 kinds of NaNs that are represented: + +1. QNaNs (Quiet NaNs): represent the result of indeterminate operations. +2. SNaNs (Signalling NaNs): represent the result of invalid operations. + +### QNaNs + +QNaNs are represented like this: + +* Sign bit: `X` +* Exponent bits: `11111111111` +* Mantissa bits: `1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` + +where `X` means `0` or `1`. + +### SNaNs + +SNaNs are represented like this: + +* Sign bit: `X` +* Exponent bits: `11111111111` +* Mantissa bits: `0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1` + +where `X` means `0` or `1`. + +## Infinite + +### Positive Infinite + +Positive infinite is represented like this: + +* Sign bit: `0` +* Exponent bits: `11111111111` +* Mantissa bits: `0000000000000000000000000000000000000000000000000000` + +where `X` means `0` or `1`. + +### Negative Infinite + +Negative infinite is represented like this: + +* Sign bit: `1` +* Exponent bits: `11111111111` +* Mantissa bits: `0000000000000000000000000000000000000000000000000000` + +where `X` means `0` or `1`. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py new file mode 100644 index 00000000000..b1815c42561 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py @@ -0,0 +1,106 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from ctypes import c_double, c_uint64 +from sys import float_info + +# IEEE 754 64-bit floating point numbers use 11 bits for the exponent and 52 +# bits for the mantissa. +MANTISSA_WIDTH = 52 +EXPONENT_WIDTH = 11 + +# This mask is equivalent to 52 "1" bits (there are 13 hexadecimal 4-bit "f"s +# in the mantissa mask, 13 * 4 == 52) or 0xfffffffffffff in hexadecimal. +MANTISSA_MASK = (1 << MANTISSA_WIDTH) - 1 + +# There are 11 bits for the exponent, but the exponent values 0 (11 "0" +# bits) and 2047 (11 "1" bits) have special meanings so the exponent range is +# from 1 to 2046. To calculate the exponent value, 1023 (the bias) is +# subtracted from the exponent, so the exponent value range is from -1022 to +# +1023. +EXPONENT_BIAS = (2 ** (EXPONENT_WIDTH - 1)) - 1 + +# All the exponent mask bits are set to 1 for the 11 exponent bits. +EXPONENT_MASK = ((1 << EXPONENT_WIDTH) - 1) << MANTISSA_WIDTH + +# The sign mask has the first bit set to 1 and the rest to 0. +SIGN_MASK = 1 << (EXPONENT_WIDTH + MANTISSA_WIDTH) + +# For normal floating point numbers, the exponent can have a value in the +# range [-1022, 1023]. +MIN_NORMAL_EXPONENT = -EXPONENT_BIAS + 1 +MAX_NORMAL_EXPONENT = EXPONENT_BIAS + +# The smallest possible normal value is 2.2250738585072014e-308. +# This value is the result of using the smallest possible number in the +# mantissa, 1.0000000000000000000000000000000000000000000000000000 (52 "0"s in +# the fractional part) and a single "1" in the exponent. +# Finally 1 * (2 ** -1022) = 2.2250738585072014e-308. +MIN_NORMAL_VALUE = float_info.min + +# Greatest possible normal value (1.7976931348623157e+308) +# The binary representation of a float in scientific notation uses (for the +# mantissa) one bit for the integer part (which is implicit) and 52 bits for +# the fractional part. Consider a float binary 1.111. It is equal to 1 + 1/2 + +# 1/4 + 1/8. The greatest possible value in the 52-bit binary mantissa would be +# then 1.1111111111111111111111111111111111111111111111111111 (52 "1"s in the +# fractional part) whose decimal value is 1.9999999999999998. Finally, +# 1.9999999999999998 * (2 ** 1023) = 1.7976931348623157e+308. +MAX_NORMAL_VALUE = float_info.max + + +def get_ieee_754_exponent(value: float) -> int: + """ + Gets the exponent of the IEEE 754 representation of a float. + """ + + return ( + ( + # This step gives the integer that corresponds to the IEEE 754 + # representation of a float. For example, consider + # -MAX_NORMAL_VALUE for an example. We choose this value because + # of its binary representation which makes easy to understand the + # subsequent operations. + # + # c_uint64.from_buffer(c_double(-MAX_NORMAL_VALUE)).value == 18442240474082181119 + # bin(18442240474082181119) == '0b1111111111101111111111111111111111111111111111111111111111111111' + # + # The first bit of the previous binary number is the sign bit: 1 (1 means negative, 0 means positive) + # The next 11 bits are the exponent bits: 11111111110 + # The next 52 bits are the mantissa bits: 1111111111111111111111111111111111111111111111111111 + # + # This step isolates the exponent bits, turning every bit outside + # of the exponent field (sign and mantissa bits) to 0. + c_uint64.from_buffer(c_double(value)).value & EXPONENT_MASK + # For the example this means: + # 18442240474082181119 & EXPONENT_MASK == 9214364837600034816 + # bin(9214364837600034816) == '0b111111111100000000000000000000000000000000000000000000000000000' + # Notice that the previous binary representation does not include + # leading zeroes, so the sign bit is not included since it is a + # zero. + ) + # This step moves the exponent bits to the right, removing the + # mantissa bits that were set to 0 by the previous step. This + # leaves the IEEE 754 exponent value, ready for the next step. + >> MANTISSA_WIDTH + # For the example this means: + # 9214364837600034816 >> MANTISSA_WIDTH == 2046 + # bin(2046) == '0b11111111110' + # As shown above, these are the original 11 bits that correspond to the + # exponent. + # This step subtracts the exponent bias from the IEEE 754 value, + # leaving the actual exponent value. + ) - EXPONENT_BIAS + # For the example this means: + # 2046 - EXPONENT_BIAS == 1023 + # As mentioned in a comment above, the largest value for the exponent is + + +def get_ieee_754_mantissa(value: float) -> int: + return ( + c_uint64.from_buffer(c_double(value)).value + # This step isolates the mantissa bits. There is no need to do any + # bit shifting as the mantissa bits are already the rightmost field + # in an IEEE 754 representation. + & MANTISSA_MASK + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py new file mode 100644 index 00000000000..6f88f206bf9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py @@ -0,0 +1,123 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from math import exp, floor, ldexp, log +from threading import Lock + +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping import ( + Mapping, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.errors import ( + MappingOverflowError, + MappingUnderflowError, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.ieee_754 import ( + MAX_NORMAL_EXPONENT, + MIN_NORMAL_EXPONENT, + MIN_NORMAL_VALUE, + get_ieee_754_exponent, + get_ieee_754_mantissa, +) + + +class LogarithmMapping(Mapping): + # Reference implementation here: + # https://github.com/open-telemetry/opentelemetry-go/blob/0e6f9c29c10d6078e8131418e1d1d166c7195d61/sdk/metric/aggregator/exponential/mapping/logarithm/logarithm.go + + _mappings = {} + _mappings_lock = Lock() + + _min_scale = 1 + _max_scale = 20 + + def _get_min_scale(self): + # _min_scale ensures that ExponentMapping is used for zero and negative + # scale values. + return self._min_scale + + def _get_max_scale(self): + # _max_scale is 20. The OpenTelemetry specification requires that + # bucket indices fit within a signed 32-bit integer. At scale 20, + # the maximum bucket index is ((MAX_NORMAL_EXPONENT + 1) << 20) - 1, + # which fits within this range. At scale 21, the maximum bucket + # index reaches the upper limit of a signed 32-bit integer, making + # it difficult to test correctness. See: + # https://github.com/lightstep/otel-launcher-go/blob/c9ca8483be067a39ab306b09060446e7fda65f35/lightstep/sdk/metric/aggregator/histogram/structure/README.md#mapping-function + # https://github.com/open-telemetry/opentelemetry-go/blob/0e6f9c29c10d6078e8131418e1d1d166c7195d61/sdk/metric/aggregator/exponential/mapping/logarithm/logarithm.go#L32-L45 + return self._max_scale + + def _init(self, scale: int): + # pylint: disable=attribute-defined-outside-init + + super()._init(scale) + + # self._scale_factor is defined as a multiplier because multiplication + # is faster than division. self._scale_factor is defined as: + # index = log(value) * self._scale_factor + # Where: + # index = log(value) / log(base) + # index = log(value) / log(2 ** (2 ** -scale)) + # index = log(value) / ((2 ** -scale) * log(2)) + # index = log(value) * ((1 / log(2)) * (2 ** scale)) + # self._scale_factor = ((1 / log(2)) * (2 ** scale)) + # self._scale_factor = (1 /log(2)) * (2 ** scale) + # self._scale_factor = ldexp(1 / log(2), scale) + # This implementation was copied from a Java prototype. See: + # https://github.com/newrelic-experimental/newrelic-sketch-java/blob/1ce245713603d61ba3a4510f6df930a5479cd3f6/src/main/java/com/newrelic/nrsketch/indexer/LogIndexer.java + # for the equations used here. + self._scale_factor = ldexp(1 / log(2), scale) + + # self._min_normal_lower_boundary_index is the index such that + # base ** index == MIN_NORMAL_VALUE. An exponential histogram bucket + # with this index covers the range + # (MIN_NORMAL_VALUE, MIN_NORMAL_VALUE * base]. One less than this index + # corresponds with the bucket containing values <= MIN_NORMAL_VALUE. + self._min_normal_lower_boundary_index = MIN_NORMAL_EXPONENT << self._scale + + # self._max_normal_lower_boundary_index is the index such that + # base ** index equals the greatest representable lower boundary. An + # exponential histogram bucket with this index covers the range + # ((2 ** 1024) / base, 2 ** 1024], which includes opentelemetry.sdk. + # metrics._internal.exponential_histogram.ieee_754.MAX_NORMAL_VALUE. + # This bucket is incomplete, since the upper boundary cannot be + # represented. One greater than this index corresponds with the bucket + # containing values > 2 ** 1024. + self._max_normal_lower_boundary_index = ((MAX_NORMAL_EXPONENT + 1) << self._scale) - 1 + + def map_to_index(self, value: float) -> int: + """ + Maps positive floating point values to indexes corresponding to scale. + """ + + # value is subnormal + if value <= MIN_NORMAL_VALUE: + return self._min_normal_lower_boundary_index - 1 + + # value is an exact power of two. + if get_ieee_754_mantissa(value) == 0: + exponent = get_ieee_754_exponent(value) + return (exponent << self._scale) - 1 + + return min( + floor(log(value) * self._scale_factor), + self._max_normal_lower_boundary_index, + ) + + def get_lower_boundary(self, index: int) -> float: + if index >= self._max_normal_lower_boundary_index: + if index == self._max_normal_lower_boundary_index: + return 2 * exp((index - (1 << self._scale)) / self._scale_factor) + raise MappingOverflowError() + + if index <= self._min_normal_lower_boundary_index: + if index == self._min_normal_lower_boundary_index: + return MIN_NORMAL_VALUE + if index == self._min_normal_lower_boundary_index - 1: + return exp((index + (1 << self._scale)) / self._scale_factor) / 2 + raise MappingUnderflowError() + + return exp(index / self._scale_factor) + + @property + def scale(self) -> int: + return self._scale diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py new file mode 100644 index 00000000000..25ba8c1b323 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py @@ -0,0 +1,608 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import math +import os +import weakref +from abc import ABC, abstractmethod +from collections.abc import Callable, Iterable +from enum import Enum +from logging import getLogger +from os import environ, linesep +from sys import stdout +from threading import Event, Lock, RLock, Thread +from time import perf_counter, time_ns +from typing import IO + +from opentelemetry.agent._vendor.typing_extensions import final + +# This kind of import is needed to avoid Sphinx errors. +import opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal +from opentelemetry.agent._vendor import opentelemetry +from opentelemetry.agent._vendor.opentelemetry.context import ( + _SUPPRESS_INSTRUMENTATION_KEY, + attach, + detach, + set_value, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, NoOpMeterProvider +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_METRIC_EXPORT_INTERVAL, + OTEL_METRIC_EXPORT_TIMEOUT, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( + parse_boolean_environment_variable, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal._view_instrument_match import ( + _DEFAULT_CARDINALITY_LIMIT, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( + AggregationTemporality, + DefaultAggregation, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( + Counter, + Gauge, + Histogram, + ObservableCounter, + ObservableGauge, + ObservableUpDownCounter, + UpDownCounter, + _Counter, + _Gauge, + _Histogram, + _ObservableCounter, + _ObservableGauge, + _ObservableUpDownCounter, + _UpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import MetricsData +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OtelComponentTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.util._once import Once + +from ._metric_reader_metrics import create_metric_reader_metrics + +_logger = getLogger(__name__) + + +class MetricExportResult(Enum): + """Result of exporting a metric + + Can be any of the following values:""" + + SUCCESS = 0 + FAILURE = 1 + + +class MetricExporter(ABC): + """Interface for exporting metrics. + + Interface to be implemented by services that want to export metrics received + in their own format. + + Args: + preferred_temporality: Used by `opentelemetry.sdk.metrics.export.PeriodicExportingMetricReader` to + configure exporter level preferred temporality. See `opentelemetry.sdk.metrics.export.MetricReader` for + more details on what preferred temporality is. + preferred_aggregation: Used by `opentelemetry.sdk.metrics.export.PeriodicExportingMetricReader` to + configure exporter level preferred aggregation. See `opentelemetry.sdk.metrics.export.MetricReader` for + more details on what preferred aggregation is. + """ + + def __init__( + self, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, + ) -> None: + self._preferred_temporality = preferred_temporality + self._preferred_aggregation = preferred_aggregation + + @abstractmethod + def export( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> MetricExportResult: + """Exports a batch of telemetry data. + + Args: + metrics: The list of `opentelemetry.sdk.metrics.export.Metric` objects to be exported + + Returns: + The result of the export + """ + + @abstractmethod + def force_flush(self, timeout_millis: float = 10_000) -> bool: + """ + Ensure that export of any metrics currently received by the exporter + are completed as soon as possible. + """ + + @abstractmethod + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + """Shuts down the exporter. + + Called when the SDK is shut down. + """ + + +class ConsoleMetricExporter(MetricExporter): + """Implementation of :class:`MetricExporter` that prints metrics to the + console. + + This class can be used for diagnostic purposes. It prints the exported + metrics to the console STDOUT. + """ + + def __init__( + self, + out: IO = stdout, + formatter: Callable[[MetricsData], str] = lambda metrics_data: metrics_data.to_json() + linesep, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, + ): + super().__init__( + preferred_temporality=preferred_temporality, + preferred_aggregation=preferred_aggregation, + ) + self.out = out + self.formatter = formatter + + def export( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> MetricExportResult: + self.out.write(self.formatter(metrics_data)) + self.out.flush() + return MetricExportResult.SUCCESS + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + pass + + def force_flush(self, timeout_millis: float = 10_000) -> bool: + return True + + +InstrumentCardinalityKey = ( + type[Counter] + | type[UpDownCounter] + | type[Histogram] + | type[Gauge] + | type[ObservableCounter] + | type[ObservableUpDownCounter] + | type[ObservableGauge] +) + +CardinalityLimits = dict[InstrumentCardinalityKey, int] + +_CARDINALITY_INSTRUMENT_CLASSES: dict[type, type] = { + Counter: _Counter, + UpDownCounter: _UpDownCounter, + Histogram: _Histogram, + Gauge: _Gauge, + ObservableCounter: _ObservableCounter, + ObservableUpDownCounter: _ObservableUpDownCounter, + ObservableGauge: _ObservableGauge, +} + + +def _validate_cardinality_limit(typ: type, limit: int) -> type: + """Return the SDK instrument class for ``typ`` after validating ``limit``.""" + if typ not in _CARDINALITY_INSTRUMENT_CLASSES: + raise ValueError(f"Invalid instrument class found {typ}") + if isinstance(limit, bool) or not isinstance(limit, int) or limit < 1: + raise ValueError(f"Cardinality limit for {typ} must be a positive integer, got {limit!r}") + return _CARDINALITY_INSTRUMENT_CLASSES[typ] + + +class MetricReader(ABC): + # pylint: disable=too-many-branches,broad-exception-raised + """ + Base class for all metric readers + + Args: + preferred_temporality: A mapping between instrument classes and + aggregation temporality. By default uses CUMULATIVE for all instrument + classes. This mapping will be used to define the default aggregation + temporality of every instrument class. If the user wants to make a + change in the default aggregation temporality of an instrument class, + it is enough to pass here a dictionary whose keys are the instrument + classes and the values are the corresponding desired aggregation + temporalities of the classes that the user wants to change, not all of + them. The classes not included in the passed dictionary will retain + their association to their default aggregation temporalities. + preferred_aggregation: A mapping between instrument classes and + aggregation instances. By default maps all instrument classes to an + instance of `DefaultAggregation`. This mapping will be used to + define the default aggregation of every instrument class. If the + user wants to make a change in the default aggregation of an + instrument class, it is enough to pass here a dictionary whose keys + are the instrument classes and the values are the corresponding + desired aggregation for the instrument classes that the user wants + to change, not necessarily all of them. The classes not included in + the passed dictionary will retain their association to their + default aggregations. The aggregation defined here will be + overridden by an aggregation defined by a view that is not + `DefaultAggregation`. + cardinality_limits: A dictionary mapping instrument classes to the + maximum number of distinct attribute sets a metric stream of that + instrument class aggregates per collection cycle. Instrument + classes not included use a limit of 2000. A limit defined by a view + takes precedence. Measurements with further attribute sets are + aggregated into one additional point identified by the attribute + ``otel.metric.overflow=true``. + + .. document protected _receive_metrics which is a intended to be overridden by subclass + .. automethod:: _receive_metrics + """ + + def __init__( + self, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, + cardinality_limits: CardinalityLimits | None = None, + *, + otel_component_type: OtelComponentTypeValues | None = None, + ) -> None: + self._collect: ( + Callable[ + [ + opentelemetry.sdk.metrics.export.MetricReader, + AggregationTemporality, + ], + Iterable[opentelemetry.sdk.metrics.export.Metric], + ] + | None + ) = None + + self._instrument_class_temporality = { + _Counter: AggregationTemporality.CUMULATIVE, + _UpDownCounter: AggregationTemporality.CUMULATIVE, + _Histogram: AggregationTemporality.CUMULATIVE, + _Gauge: AggregationTemporality.CUMULATIVE, + _ObservableCounter: AggregationTemporality.CUMULATIVE, + _ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, + _ObservableGauge: AggregationTemporality.CUMULATIVE, + } + + if preferred_temporality is not None: + for temporality in preferred_temporality.values(): + if temporality not in ( + AggregationTemporality.CUMULATIVE, + AggregationTemporality.DELTA, + ): + raise Exception(f"Invalid temporality value found {temporality}") + + if preferred_temporality is not None: + for typ, temporality in preferred_temporality.items(): + if typ is Counter: + self._instrument_class_temporality[_Counter] = temporality + elif typ is UpDownCounter: + self._instrument_class_temporality[_UpDownCounter] = temporality + elif typ is Histogram: + self._instrument_class_temporality[_Histogram] = temporality + elif typ is Gauge: + self._instrument_class_temporality[_Gauge] = temporality + elif typ is ObservableCounter: + self._instrument_class_temporality[_ObservableCounter] = temporality + elif typ is ObservableUpDownCounter: + self._instrument_class_temporality[_ObservableUpDownCounter] = temporality + elif typ is ObservableGauge: + self._instrument_class_temporality[_ObservableGauge] = temporality + else: + raise Exception(f"Invalid instrument class found {typ}") + + self._preferred_temporality = preferred_temporality + self._instrument_class_aggregation = { + _Counter: DefaultAggregation(), + _UpDownCounter: DefaultAggregation(), + _Histogram: DefaultAggregation(), + _Gauge: DefaultAggregation(), + _ObservableCounter: DefaultAggregation(), + _ObservableUpDownCounter: DefaultAggregation(), + _ObservableGauge: DefaultAggregation(), + } + + if preferred_aggregation is not None: + for typ, aggregation in preferred_aggregation.items(): + if typ is Counter: + self._instrument_class_aggregation[_Counter] = aggregation + elif typ is UpDownCounter: + self._instrument_class_aggregation[_UpDownCounter] = aggregation + elif typ is Histogram: + self._instrument_class_aggregation[_Histogram] = aggregation + elif typ is Gauge: + self._instrument_class_aggregation[_Gauge] = aggregation + elif typ is ObservableCounter: + self._instrument_class_aggregation[_ObservableCounter] = aggregation + elif typ is ObservableUpDownCounter: + self._instrument_class_aggregation[_ObservableUpDownCounter] = aggregation + elif typ is ObservableGauge: + self._instrument_class_aggregation[_ObservableGauge] = aggregation + else: + raise Exception(f"Invalid instrument class found {typ}") + + self._instrument_class_cardinality_limit = { + _Counter: _DEFAULT_CARDINALITY_LIMIT, + _UpDownCounter: _DEFAULT_CARDINALITY_LIMIT, + _Histogram: _DEFAULT_CARDINALITY_LIMIT, + _Gauge: _DEFAULT_CARDINALITY_LIMIT, + _ObservableCounter: _DEFAULT_CARDINALITY_LIMIT, + _ObservableUpDownCounter: _DEFAULT_CARDINALITY_LIMIT, + _ObservableGauge: _DEFAULT_CARDINALITY_LIMIT, + } + + if cardinality_limits is not None: + for typ, limit in cardinality_limits.items(): + self._instrument_class_cardinality_limit[_validate_cardinality_limit(typ, limit)] = limit + + self._otel_component_type = otel_component_type.value if otel_component_type else type(self).__qualname__ + self._metrics = create_metric_reader_metrics( + self._otel_component_type, + NoOpMeterProvider(), + parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ) + + @final + def collect(self, timeout_millis: float = 10_000) -> None: + """Collects the metrics from the internal SDK state and + invokes the `_receive_metrics` with the collection. + + Args: + timeout_millis: Amount of time in milliseconds before this function + raises a timeout error. + + If any of the underlying ``collect`` methods called by this method + fails by any reason (including timeout) an exception will be raised + detailing the individual errors that caused this function to fail. + """ + if self._collect is None: + _logger.warning("Cannot call collect on a MetricReader until it is registered on a MeterProvider") + return + + start_time = perf_counter() + try: + metrics = self._collect(self, timeout_millis=timeout_millis) + finally: + self._metrics.record_collection(perf_counter() - start_time) + + if metrics is not None: + self._receive_metrics( + metrics, + timeout_millis=timeout_millis, + ) + + @final + def _set_collect_callback( + self, + func: Callable[ + [ + opentelemetry.sdk.metrics.export.MetricReader, + AggregationTemporality, + ], + MetricsData, + ] + | None, + ) -> None: + """This function is internal to the SDK. It should not be called or overridden by users""" + self._collect = func + + @abstractmethod + def _receive_metrics( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> None: + """Called by `MetricReader.collect` when it receives a batch of metrics""" + + def _set_meter_provider(self, meter_provider: MeterProvider) -> None: + self._metrics = create_metric_reader_metrics( + self._otel_component_type, + meter_provider, + parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ) + + def force_flush(self, timeout_millis: float = 10_000) -> bool: + self.collect(timeout_millis=timeout_millis) + return True + + @abstractmethod + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + """Shuts down the MetricReader. This method provides a way + for the MetricReader to do any cleanup required. A metric reader can + only be shutdown once, any subsequent calls are ignored and return + failure status. + + When a `MetricReader` is registered on a + :class:`~opentelemetry.sdk.metrics.MeterProvider`, + :meth:`~opentelemetry.sdk.metrics.MeterProvider.shutdown` will invoke this + automatically. + """ + + +class InMemoryMetricReader(MetricReader): + """Implementation of `MetricReader` that returns its metrics from :func:`get_metrics_data`. + + This is useful for e.g. unit tests. + """ + + def __init__( + self, + preferred_temporality: dict[type, AggregationTemporality] | None = None, + preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, + cardinality_limits: CardinalityLimits | None = None, + ) -> None: + super().__init__( + preferred_temporality=preferred_temporality, + preferred_aggregation=preferred_aggregation, + cardinality_limits=cardinality_limits, + ) + self._lock = RLock() + self._metrics_data: MetricsData | None = None + + def get_metrics_data( + self, + ) -> MetricsData | None: + """Reads and returns current metrics from the SDK""" + with self._lock: + self.collect() + metrics_data = self._metrics_data + self._metrics_data = None + return metrics_data + + def _receive_metrics( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> None: + with self._lock: + self._metrics_data = metrics_data + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + pass + + +class PeriodicExportingMetricReader(MetricReader): + """`PeriodicExportingMetricReader` is an implementation of `MetricReader` + that collects metrics based on a user-configurable time interval, and passes the + metrics to the configured exporter. If the time interval is set to `math.inf`, the + reader will not invoke periodic collection. + + The configured exporter's :py:meth:`~MetricExporter.export` method will not be called + concurrently. + """ + + def __init__( + self, + exporter: MetricExporter, + export_interval_millis: float | None = None, + export_timeout_millis: float | None = None, + cardinality_limits: CardinalityLimits | None = None, + ) -> None: + # PeriodicExportingMetricReader defers to exporter for configuration + super().__init__( + preferred_temporality=exporter._preferred_temporality, + preferred_aggregation=exporter._preferred_aggregation, + cardinality_limits=cardinality_limits, + otel_component_type=OtelComponentTypeValues.PERIODIC_METRIC_READER, + ) + + # This lock is held whenever calling self._exporter.export() to prevent concurrent + # execution of MetricExporter.export() + # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exportbatch + self._export_lock = Lock() + + self._exporter = exporter + if export_interval_millis is None: + try: + export_interval_millis = float(environ.get(OTEL_METRIC_EXPORT_INTERVAL, 60000)) + except ValueError: + _logger.warning("Found invalid value for export interval, using default") + export_interval_millis = 60000 + if export_timeout_millis is None: + try: + export_timeout_millis = float(environ.get(OTEL_METRIC_EXPORT_TIMEOUT, 30000)) + except ValueError: + _logger.warning("Found invalid value for export timeout, using default") + export_timeout_millis = 30000 + self._export_interval_millis = export_interval_millis + self._export_timeout_millis = export_timeout_millis + self._shutdown = False + self._shutdown_event = Event() + self._shutdown_once = Once() + self._daemon_thread = None + if self._export_interval_millis > 0 and self._export_interval_millis < math.inf: + self._daemon_thread = Thread( + name="OtelPeriodicExportingMetricReader", + target=self._ticker, + daemon=True, + ) + self._daemon_thread.start() + if hasattr(os, "register_at_fork"): + weak_at_fork = weakref.WeakMethod(self._at_fork_reinit) + + def _after_in_child() -> None: + if at_fork := weak_at_fork(): + at_fork() + + os.register_at_fork(after_in_child=_after_in_child) + elif self._export_interval_millis <= 0: + raise ValueError( + f"interval value {self._export_interval_millis} is invalid \ + and needs to be larger than zero." + ) + + def _at_fork_reinit(self): + self._daemon_thread = Thread( + name="OtelPeriodicExportingMetricReader", + target=self._ticker, + daemon=True, + ) + self._daemon_thread.start() + + def _ticker(self) -> None: + interval_secs = self._export_interval_millis / 1e3 + while not self._shutdown_event.wait(interval_secs): + try: + self.collect(timeout_millis=self._export_timeout_millis) + except MetricsTimeoutError: + _logger.warning( + "Metric collection timed out. Will try again after %s seconds", + interval_secs, + exc_info=True, + ) + # one last collection below before shutting down completely + try: + self.collect(timeout_millis=self._export_interval_millis) + except MetricsTimeoutError: + _logger.warning( + "Metric collection timed out.", + exc_info=True, + ) + + def _receive_metrics( + self, + metrics_data: MetricsData, + timeout_millis: float = 10_000, + **kwargs, + ) -> None: + token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) + # pylint: disable=broad-exception-caught,invalid-name + try: + with self._export_lock: + self._exporter.export(metrics_data, timeout_millis=timeout_millis) + except Exception: + _logger.exception("Exception while exporting metrics") + detach(token) + + def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: + deadline_ns = time_ns() + timeout_millis * 10**6 + + def _shutdown(): + self._shutdown = True + + did_set = self._shutdown_once.do_once(_shutdown) + if not did_set: + _logger.warning("Can't shutdown multiple times") + return + + self._shutdown_event.set() + if self._daemon_thread: + self._daemon_thread.join(timeout=(deadline_ns - time_ns()) / 10**9) + self._exporter.shutdown(timeout=(deadline_ns - time_ns()) / 10**6) + + def force_flush(self, timeout_millis: float = 10_000) -> bool: + super().force_flush(timeout_millis=timeout_millis) + self._exporter.force_flush(timeout_millis=timeout_millis) + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py new file mode 100644 index 00000000000..2d5fdb606f1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py @@ -0,0 +1,54 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from collections import Counter +from typing import Protocol + +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OTEL_COMPONENT_NAME, + OTEL_COMPONENT_TYPE, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( + create_otel_sdk_metric_reader_collection_duration, +) + +_component_counter = Counter() + + +class MetricReaderMetricsT(Protocol): + def record_collection(self, duration: float) -> None: ... + + +class NoOpMetricReaderMetrics: + def record_collection(self, duration: float) -> None: + pass + + +class MetricReaderMetrics: + def __init__(self, component_type: str, meter_provider: MeterProvider) -> None: + meter = meter_provider.get_meter("opentelemetry-sdk") + + count = _component_counter[component_type] + _component_counter[component_type] = count + 1 + + self._standard_attrs = { + OTEL_COMPONENT_TYPE: component_type, + OTEL_COMPONENT_NAME: f"{component_type}/{count}", + } + + self._collection_duration = create_otel_sdk_metric_reader_collection_duration(meter) + + def record_collection(self, duration: float) -> None: + self._collection_duration.record(duration, self._standard_attrs) + + +def create_metric_reader_metrics( + component_type: str, + meter_provider: MeterProvider, + enabled: bool, +) -> MetricReaderMetricsT: + if not enabled: + return NoOpMetricReaderMetrics() + + return MetricReaderMetrics(component_type, meter_provider) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py new file mode 100644 index 00000000000..de372a8fc8d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py @@ -0,0 +1,400 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=too-many-ancestors, unused-import +from __future__ import annotations + +import math +from collections.abc import Generator, Iterable, Sequence +from logging import getLogger +from time import time_ns +from typing import ( + TYPE_CHECKING, + Protocol, + cast, + runtime_checkable, +) + +# This kind of import is needed to avoid Sphinx errors. +from opentelemetry.agent._vendor.opentelemetry.context import Context, get_current +from opentelemetry.agent._vendor.opentelemetry.metrics import Asynchronous, CallbackT, Synchronous +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter as APICounter +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram as APIHistogram +from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableCounter as APIObservableCounter +from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableGauge as APIObservableGauge +from opentelemetry.agent._vendor.opentelemetry.metrics import ( + ObservableUpDownCounter as APIObservableUpDownCounter, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import UpDownCounter as APIUpDownCounter +from opentelemetry.agent._vendor.opentelemetry.metrics import _Gauge as APIGauge +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import ( + CallbackOptions, + _MetricsHistogramAdvisory, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +if TYPE_CHECKING: + from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import ( + _ProxyMeterConfig, + ) + from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement_consumer import ( + MeasurementConsumer, + ) + from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope + + +_logger = getLogger(__name__) + + +_NAME_ERROR_MESSAGE = "Expected ASCII string of maximum length 255 characters but got {}" +_UNIT_ERROR_MESSAGE = "Expected ASCII string of maximum length 63 characters but got {}" + + +@runtime_checkable +class _Instrument(Protocol): + name: str + unit: str + description: str + instrumentation_scope: InstrumentationScope + + +class _Synchronous(_Instrument, Synchronous): + def __init__( + self, + name: str, + instrumentation_scope: InstrumentationScope, + measurement_consumer: MeasurementConsumer, + unit: str = "", + description: str = "", + *, + _meter_config: _ProxyMeterConfig | None = None, + ): + # pylint: disable=no-member + result = self._check_name_unit_description(name, unit, description) + + if result["name"] is None: + # pylint: disable=broad-exception-raised + raise Exception(_NAME_ERROR_MESSAGE.format(name)) + + if result["unit"] is None: + # pylint: disable=broad-exception-raised + raise Exception(_UNIT_ERROR_MESSAGE.format(unit)) + + name = result["name"] + unit = result["unit"] + description = cast(str, result["description"]) + + self.name = name.lower() + self.unit = unit + self.description = description + self.instrumentation_scope = instrumentation_scope + self._measurement_consumer = measurement_consumer + self._meter_config = _meter_config + super().__init__(name, unit=unit, description=description) + + def _is_enabled(self) -> bool: + return self._meter_config is None or self._meter_config.is_enabled + + +class _Asynchronous(_Instrument, Asynchronous): + def __init__( + self, + name: str, + instrumentation_scope: InstrumentationScope, + measurement_consumer: MeasurementConsumer, + callbacks: Sequence[CallbackT] | None = None, + unit: str = "", + description: str = "", + *, + _meter_config: _ProxyMeterConfig | None = None, + ): + # pylint: disable=no-member + result = self._check_name_unit_description(name, unit, description) + + if result["name"] is None: + # pylint: disable=broad-exception-raised + raise Exception(_NAME_ERROR_MESSAGE.format(name)) + + if result["unit"] is None: + # pylint: disable=broad-exception-raised + raise Exception(_UNIT_ERROR_MESSAGE.format(unit)) + + name = result["name"] + unit = result["unit"] + description = cast(str, result["description"]) + + self.name = name.lower() + self.unit = unit + self.description = description + self.instrumentation_scope = instrumentation_scope + self._measurement_consumer = measurement_consumer + self._meter_config = _meter_config + super().__init__(name, callbacks, unit=unit, description=description) + + self._callbacks: list[CallbackT] = [] + + if callbacks is not None: + for callback in callbacks: + if isinstance(callback, Generator): + # advance generator to it's first yield + next(callback) + + def inner( + options: CallbackOptions, + callback=callback, + ) -> Iterable[Measurement]: + try: + return callback.send(options) + except StopIteration: + return [] + + self._callbacks.append(inner) + else: + self._callbacks.append(callback) + + def _is_enabled(self) -> bool: + return self._meter_config is None or self._meter_config.is_enabled + + def callback(self, callback_options: CallbackOptions) -> Iterable[Measurement]: + if not self._is_enabled(): + return + for callback in self._callbacks: + try: + for api_measurement in callback(callback_options): + if not math.isfinite(api_measurement.value): + _logger.warning( + "Callback returned a non-finite value %s for instrument %s, ignoring measurement.", + api_measurement.value, + self.name, + ) + continue + yield Measurement( + api_measurement.value, + time_unix_nano=time_ns(), + instrument=self, + context=api_measurement.context or get_current(), + attributes=api_measurement.attributes, + ) + except Exception: # pylint: disable=broad-exception-caught + _logger.exception("Callback failed for instrument %s.", self.name) + + +class Counter(_Synchronous, APICounter): + def __new__(cls, *args, **kwargs): + if cls is Counter: + raise TypeError("Counter must be instantiated via a meter.") + return super().__new__(cls) + + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ): + if not self._is_enabled(): + super().add(amount, attributes=attributes, context=context) + return + + if not math.isfinite(amount): + _logger.warning( + "Add amount %s is not finite on Counter %s, ignoring measurement.", + amount, + self.name, + ) + return + if amount < 0: + _logger.warning("Add amount must be non-negative on Counter %s.", self.name) + return + time_unix_nano = time_ns() + self._measurement_consumer.consume_measurement( + Measurement( + amount, + time_unix_nano, + self, + context or get_current(), + attributes, + ) + ) + + +class UpDownCounter(_Synchronous, APIUpDownCounter): + def __new__(cls, *args, **kwargs): + if cls is UpDownCounter: + raise TypeError("UpDownCounter must be instantiated via a meter.") + return super().__new__(cls) + + def add( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ): + if not self._is_enabled(): + super().add(amount, attributes=attributes, context=context) + return + + if not math.isfinite(amount): + _logger.warning( + "Add amount %s is not finite on UpDownCounter %s, ignoring measurement.", + amount, + self.name, + ) + return + time_unix_nano = time_ns() + self._measurement_consumer.consume_measurement( + Measurement( + amount, + time_unix_nano, + self, + context or get_current(), + attributes, + ) + ) + + +class ObservableCounter(_Asynchronous, APIObservableCounter): + def __new__(cls, *args, **kwargs): + if cls is ObservableCounter: + raise TypeError("ObservableCounter must be instantiated via a meter.") + return super().__new__(cls) + + +class ObservableUpDownCounter(_Asynchronous, APIObservableUpDownCounter): + def __new__(cls, *args, **kwargs): + if cls is ObservableUpDownCounter: + raise TypeError("ObservableUpDownCounter must be instantiated via a meter.") + return super().__new__(cls) + + +class Histogram(_Synchronous, APIHistogram): + def __init__( + self, + name: str, + instrumentation_scope: InstrumentationScope, + measurement_consumer: MeasurementConsumer, + unit: str = "", + description: str = "", + explicit_bucket_boundaries_advisory: Sequence[float] | None = None, + *, + _meter_config: _ProxyMeterConfig | None = None, + ): + super().__init__( + name, + unit=unit, + description=description, + instrumentation_scope=instrumentation_scope, + measurement_consumer=measurement_consumer, + _meter_config=_meter_config, + ) + self._advisory = _MetricsHistogramAdvisory(explicit_bucket_boundaries=explicit_bucket_boundaries_advisory) + + def __new__(cls, *args, **kwargs): + if cls is Histogram: + raise TypeError("Histogram must be instantiated via a meter.") + return super().__new__(cls) + + def record( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ): + if not self._is_enabled(): + super().record(amount, attributes=attributes, context=context) + return + + if not math.isfinite(amount): + _logger.warning( + "Record amount %s is not finite on Histogram %s, ignoring measurement.", + amount, + self.name, + ) + return + if amount < 0: + _logger.warning( + "Record amount must be non-negative on Histogram %s.", + self.name, + ) + return + time_unix_nano = time_ns() + self._measurement_consumer.consume_measurement( + Measurement( + amount, + time_unix_nano, + self, + context or get_current(), + attributes, + ) + ) + + +class Gauge(_Synchronous, APIGauge): + def __new__(cls, *args, **kwargs): + if cls is Gauge: + raise TypeError("Gauge must be instantiated via a meter.") + return super().__new__(cls) + + def set( + self, + amount: float, + attributes: Attributes = None, + context: Context | None = None, + ): + if not self._is_enabled(): + super().set(amount, attributes=attributes, context=context) + return + + if not math.isfinite(amount): + _logger.warning( + "Set amount %s is not finite on Gauge %s, ignoring measurement.", + amount, + self.name, + ) + return + time_unix_nano = time_ns() + self._measurement_consumer.consume_measurement( + Measurement( + amount, + time_unix_nano, + self, + context or get_current(), + attributes, + ) + ) + + +class ObservableGauge(_Asynchronous, APIObservableGauge): + def __new__(cls, *args, **kwargs): + if cls is ObservableGauge: + raise TypeError("ObservableGauge must be instantiated via a meter.") + return super().__new__(cls) + + +# Below classes exist to prevent the direct instantiation +class _Counter(Counter): + pass + + +class _UpDownCounter(UpDownCounter): + pass + + +class _ObservableCounter(ObservableCounter): + pass + + +class _ObservableUpDownCounter(ObservableUpDownCounter): + pass + + +class _Histogram(Histogram): + pass + + +class _Gauge(Gauge): + pass + + +class _ObservableGauge(ObservableGauge): + pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py new file mode 100644 index 00000000000..a95a14aabf0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py @@ -0,0 +1,54 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Mapping +from dataclasses import dataclass +from logging import getLogger +from typing import TYPE_CHECKING + +from opentelemetry.agent._vendor.opentelemetry.attributes import _clean_attribute_value +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +_logger = getLogger(__name__) + +if TYPE_CHECKING: + from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument + + +@dataclass(frozen=True) +class Measurement: + """ + Represents a data point reported via the metrics API to the SDK. + + Attributes: + value: Measured value + time_unix_nano: The time the API call was made to record the Measurement + instrument: The instrument that produced this `Measurement`. + context: The active Context of the Measurement at API call time. + attributes: Measurement attributes. Mutating mutable attribute values (lists or dicts) + outside of the Measurement object can lead to undefined and bad behavior. + """ + + value: int | float + time_unix_nano: int + instrument: _Instrument + context: Context + attributes: Attributes = None + + def __post_init__(self) -> None: + if self.attributes is not None: + if isinstance(self.attributes, Mapping): + object.__setattr__( + self, + "attributes", + _clean_attribute_value(self.attributes, None), + ) + else: + _logger.warning( + "Invalid type '%s' for attributes. Expected a Mapping or None.", + type(self.attributes), + ) + object.__setattr__(self, "attributes", None) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py new file mode 100644 index 00000000000..9bbf1d527c8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py @@ -0,0 +1,145 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=unused-import + +from abc import ABC, abstractmethod +from collections.abc import Iterable, Mapping +from threading import Lock +from time import time_ns + +# This kind of import is needed to avoid Sphinx errors. +import opentelemetry.agent._vendor.opentelemetry.sdk.metrics +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument +from opentelemetry.agent._vendor import opentelemetry +from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import CallbackOptions +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.metric_reader_storage import ( + MetricReaderStorage, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import MetricsData + + +class MeasurementConsumer(ABC): + @abstractmethod + def consume_measurement(self, measurement: Measurement) -> None: + pass + + @abstractmethod + def register_asynchronous_instrument( + self, + instrument: ("opentelemetry.sdk.metrics._internal.instrument._Asynchronous"), + ): + pass + + @abstractmethod + def collect( + self, + metric_reader: "opentelemetry.sdk.metrics.export.MetricReader", + timeout_millis: float = 10_000, + ) -> MetricsData | None: + pass + + +class SynchronousMeasurementConsumer(MeasurementConsumer): + def __init__( + self, + sdk_config: "opentelemetry.sdk.metrics._internal.sdk_configuration.SdkConfiguration", + metric_readers: Iterable["opentelemetry.sdk.metrics.MetricReader"], + ) -> None: + self._lock = Lock() + self._sdk_config = sdk_config + self._reader_storages: Mapping[opentelemetry.sdk.metrics.export.MetricReader, MetricReaderStorage] = { + reader: MetricReaderStorage( + sdk_config, + reader._instrument_class_temporality, + reader._instrument_class_aggregation, + reader._instrument_class_cardinality_limit, + ) + for reader in metric_readers + } + self._async_instruments: list[opentelemetry.sdk.metrics._internal.instrument._Asynchronous] = [] + + def consume_measurement(self, measurement: Measurement) -> None: + should_sample_exemplar = self._sdk_config.exemplar_filter.should_sample( + measurement.value, + measurement.time_unix_nano, + measurement.attributes, + measurement.context, + ) + # `_reader_storages` is replaced (never mutated in place) by + # `add_metric_reader` and `remove_metric_reader`, so it is safe + # to iterate over without a lock. + for reader_storage in self._reader_storages.values(): + reader_storage.consume_measurement(measurement, should_sample_exemplar) + + def register_asynchronous_instrument( + self, + instrument: ("opentelemetry.sdk.metrics._internal.instrument._Asynchronous"), + ) -> None: + with self._lock: + self._async_instruments.append(instrument) + + def collect( + self, + metric_reader: "opentelemetry.sdk.metrics.export.MetricReader", + timeout_millis: float = 10_000, + ) -> MetricsData | None: + with self._lock: + metric_reader_storage = self._reader_storages[metric_reader] + # for now, just use the defaults + callback_options = CallbackOptions() + deadline_ns = time_ns() + (timeout_millis * 1e6) + + default_timeout_ns = 10000 * 1e6 + + for async_instrument in self._async_instruments: + remaining_time = deadline_ns - time_ns() + + if remaining_time < default_timeout_ns: + callback_options = CallbackOptions(timeout_millis=remaining_time / 1e6) + + measurements = async_instrument.callback(callback_options) + if time_ns() >= deadline_ns: + raise MetricsTimeoutError("Timed out while executing callback") + + for measurement in measurements: + should_sample_exemplar = self._sdk_config.exemplar_filter.should_sample( + measurement.value, + measurement.time_unix_nano, + measurement.attributes, + measurement.context, + ) + metric_reader_storage.consume_measurement(measurement, should_sample_exemplar) + + result = self._reader_storages[metric_reader].collect() + + return result + + def add_metric_reader(self, metric_reader: "opentelemetry.sdk.metrics.MetricReader") -> None: + """Registers a new metric reader.""" + # Build a new mapping and swap it in atomically so that + # a concurrent consume_measurement never iterates a mapping + # that is being mutated in place. + with self._lock: + new_reader_storages = dict(self._reader_storages) + new_reader_storages[metric_reader] = MetricReaderStorage( + self._sdk_config, + # pylint: disable-next=protected-access + metric_reader._instrument_class_temporality, + # pylint: disable-next=protected-access + metric_reader._instrument_class_aggregation, + # pylint: disable-next=protected-access + metric_reader._instrument_class_cardinality_limit, + ) + self._reader_storages = new_reader_storages + + def remove_metric_reader(self, metric_reader: "opentelemetry.sdk.metrics.MetricReader") -> None: + """Unregisters the given metric reader.""" + # Mutate using copy-on-write: see add_metric_reader. + with self._lock: + new_reader_storages = dict(self._reader_storages) + new_reader_storages.pop(metric_reader) + self._reader_storages = new_reader_storages diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py new file mode 100644 index 00000000000..76eb7efd07e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py @@ -0,0 +1,285 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from logging import getLogger +from threading import RLock +from time import time_ns + +from opentelemetry.agent._vendor.opentelemetry.metrics import ( + Asynchronous, + Counter, + ObservableCounter, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal._view_instrument_match import ( + _DEFAULT_CARDINALITY_LIMIT, + _ViewInstrumentMatch, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( + Aggregation, + AggregationTemporality, + ExplicitBucketHistogramAggregation, + ExponentialBucketHistogramAggregation, + _DropAggregation, + _ExplicitBucketHistogramAggregation, + _ExponentialBucketHistogramAggregation, + _LastValueAggregation, + _SumAggregation, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( + _Asynchronous, + _Instrument, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( + ExponentialHistogram, + Gauge, + Histogram, + Metric, + MetricsData, + ResourceMetrics, + ScopeMetrics, + Sum, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.sdk_configuration import ( + SdkConfiguration, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.view import View +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope + +_logger = getLogger(__name__) + +_DEFAULT_VIEW = View(instrument_name="") + + +class MetricReaderStorage: + """The SDK's storage for a given reader""" + + def __init__( + self, + sdk_config: SdkConfiguration, + instrument_class_temporality: dict[type, AggregationTemporality], + instrument_class_aggregation: dict[type, Aggregation], + instrument_class_cardinality_limit: dict[type, int] | None = None, + ) -> None: + self._lock = RLock() + self._sdk_config = sdk_config + self._instrument_view_instrument_matches: dict[_Instrument, list[_ViewInstrumentMatch]] = {} + self._instrument_class_temporality = instrument_class_temporality + self._instrument_class_aggregation = instrument_class_aggregation + self._instrument_class_cardinality_limit = instrument_class_cardinality_limit or {} + + def _new_view_instrument_match(self, view: View, instrument: _Instrument) -> _ViewInstrumentMatch: + # pylint: disable=protected-access + cardinality_limit = view._aggregation_cardinality_limit + if cardinality_limit is None: + cardinality_limit = self._instrument_class_cardinality_limit.get( + instrument.__class__, _DEFAULT_CARDINALITY_LIMIT + ) + + # Idle attribute sets of synchronous instruments are only released on + # delta collection, so that the limit applies per collection cycle. + # Asynchronous instruments keep their state, which delta conversion + # relies on. + reset_on_collect = self._instrument_class_temporality[ + instrument.__class__ + ] is AggregationTemporality.DELTA and not isinstance(instrument, _Asynchronous) + + return _ViewInstrumentMatch( + view=view, + instrument=instrument, + instrument_class_aggregation=self._instrument_class_aggregation, + cardinality_limit=cardinality_limit, + reset_on_collect=reset_on_collect, + ) + + def _get_or_init_view_instrument_match(self, instrument: _Instrument) -> list[_ViewInstrumentMatch]: + # Optimistically get the relevant views for the given instrument. Once set for a given + # instrument, the mapping will never change + + if instrument in self._instrument_view_instrument_matches: + return self._instrument_view_instrument_matches[instrument] + + with self._lock: + # double check if it was set before we held the lock + if instrument in self._instrument_view_instrument_matches: + return self._instrument_view_instrument_matches[instrument] + + # not present, hold the lock and add a new mapping + view_instrument_matches = [] + + self._handle_view_instrument_match(instrument, view_instrument_matches) + + # if no view targeted the instrument, use the default + if not view_instrument_matches: + view_instrument_matches.append(self._new_view_instrument_match(_DEFAULT_VIEW, instrument)) + self._instrument_view_instrument_matches[instrument] = view_instrument_matches + + return view_instrument_matches + + def consume_measurement(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: + for view_instrument_match in self._get_or_init_view_instrument_match(measurement.instrument): + view_instrument_match.consume_measurement(measurement, should_sample_exemplar) + + def collect(self) -> MetricsData | None: + # Use a list instead of yielding to prevent a slow reader from holding + # SDK locks + + # While holding the lock, new _ViewInstrumentMatch can't be added from + # another thread (so we are sure we collect all existing view). + # However, instruments can still send measurements that will make it + # into the individual aggregations; collection will acquire those locks + # iteratively to keep locking as fine-grained as possible. One side + # effect is that end times can be slightly skewed among the metric + # streams produced by the SDK, but we still align the output timestamps + # for a single instrument. + + collection_start_nanos = time_ns() + + with self._lock: + instrumentation_scope_scope_metrics: dict[InstrumentationScope, ScopeMetrics] = {} + + instrument_matches_snapshot = list(self._instrument_view_instrument_matches.items()) + + for ( + instrument, + view_instrument_matches, + ) in instrument_matches_snapshot: + aggregation_temporality = self._instrument_class_temporality[instrument.__class__] + + metrics: list[Metric] = [] + + for view_instrument_match in view_instrument_matches: + data_points = view_instrument_match.collect(aggregation_temporality, collection_start_nanos) + + if data_points is None: + continue + + if isinstance( + # pylint: disable=protected-access + view_instrument_match._aggregation, + _SumAggregation, + ): + data = Sum( + aggregation_temporality=aggregation_temporality, + data_points=data_points, + is_monotonic=isinstance(instrument, (Counter, ObservableCounter)), + ) + elif isinstance( + # pylint: disable=protected-access + view_instrument_match._aggregation, + _LastValueAggregation, + ): + data = Gauge(data_points=data_points) + elif isinstance( + # pylint: disable=protected-access + view_instrument_match._aggregation, + _ExplicitBucketHistogramAggregation, + ): + data = Histogram( + data_points=data_points, + aggregation_temporality=aggregation_temporality, + ) + elif isinstance( + # pylint: disable=protected-access + view_instrument_match._aggregation, + _DropAggregation, + ): + continue + + elif isinstance( + # pylint: disable=protected-access + view_instrument_match._aggregation, + _ExponentialBucketHistogramAggregation, + ): + data = ExponentialHistogram( + data_points=data_points, + aggregation_temporality=aggregation_temporality, + ) + + metrics.append( + Metric( + # pylint: disable=protected-access + # pylint: disable=possibly-used-before-assignment + name=view_instrument_match._name, + description=view_instrument_match._description, + unit=view_instrument_match._instrument.unit, + data=data, + ) + ) + + if metrics: + if instrument.instrumentation_scope not in (instrumentation_scope_scope_metrics): + instrumentation_scope_scope_metrics[instrument.instrumentation_scope] = ScopeMetrics( + scope=instrument.instrumentation_scope, + metrics=metrics, + schema_url=instrument.instrumentation_scope.schema_url, + ) + else: + instrumentation_scope_scope_metrics[instrument.instrumentation_scope].metrics.extend(metrics) + + if instrumentation_scope_scope_metrics: + return MetricsData( + resource_metrics=[ + ResourceMetrics( + resource=self._sdk_config.resource, + scope_metrics=list(instrumentation_scope_scope_metrics.values()), + schema_url=self._sdk_config.resource.schema_url, + ) + ] + ) + + return None + + def _handle_view_instrument_match( + self, + instrument: _Instrument, + view_instrument_matches: list["_ViewInstrumentMatch"], + ) -> None: + for view in self._sdk_config.views: + # pylint: disable=protected-access + if not view._match(instrument): + continue + + if not self._check_view_instrument_compatibility(view, instrument): + continue + + new_view_instrument_match = self._new_view_instrument_match(view, instrument) + + for existing_view_instrument_matches in self._instrument_view_instrument_matches.values(): + for existing_view_instrument_match in existing_view_instrument_matches: + if existing_view_instrument_match.conflicts(new_view_instrument_match): + _logger.warning( + "Views %s and %s will cause conflicting metrics identities", + existing_view_instrument_match._view, + new_view_instrument_match._view, + ) + + view_instrument_matches.append(new_view_instrument_match) + + @staticmethod + def _check_view_instrument_compatibility(view: View, instrument: _Instrument) -> bool: + """ + Checks if a view and an instrument are compatible. + + Returns `true` if they are compatible and a `_ViewInstrumentMatch` + object should be created, `false` otherwise. + """ + + result = True + + # pylint: disable=protected-access + if isinstance(instrument, Asynchronous) and isinstance( + view._aggregation, + ( + ExplicitBucketHistogramAggregation, + ExponentialBucketHistogramAggregation, + ), + ): + _logger.warning( + "View %s and instrument %s will produce semantic errors when matched, the view has not been applied.", + view, + instrument, + ) + result = False + + return result diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py new file mode 100644 index 00000000000..641b55cd4c7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py @@ -0,0 +1,240 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=unused-import + +from collections.abc import Sequence +from dataclasses import asdict, dataclass, field +from json import dumps, loads + +# This kind of import is needed to avoid Sphinx errors. +import opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal +from opentelemetry.agent._vendor import opentelemetry +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import Exemplar +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + + +@dataclass(frozen=True) +class NumberDataPoint: + """Single data point in a timeseries that describes the time-varying scalar + value of a metric. + """ + + attributes: Attributes + start_time_unix_nano: int + time_unix_nano: int + value: int | float + exemplars: Sequence[Exemplar] = field(default_factory=list) + + def to_json(self, indent: int | None = 4) -> str: + return dumps(asdict(self), indent=indent) + + +@dataclass(frozen=True) +class HistogramDataPoint: + """Single data point in a timeseries that describes the time-varying scalar + value of a metric. + """ + + attributes: Attributes + start_time_unix_nano: int + time_unix_nano: int + count: int + sum: int | float + bucket_counts: Sequence[int] + explicit_bounds: Sequence[float] + min: float + max: float + exemplars: Sequence[Exemplar] = field(default_factory=list) + + def to_json(self, indent: int | None = 4) -> str: + return dumps(asdict(self), indent=indent) + + +@dataclass(frozen=True) +class Buckets: + offset: int + bucket_counts: Sequence[int] + + +@dataclass(frozen=True) +class ExponentialHistogramDataPoint: + """Single data point in a timeseries whose boundaries are defined by an + exponential function. This timeseries describes the time-varying scalar + value of a metric. + """ + + attributes: Attributes + start_time_unix_nano: int + time_unix_nano: int + count: int + sum: int | float + scale: int + zero_count: int + positive: Buckets + negative: Buckets + flags: int + min: float + max: float + exemplars: Sequence[Exemplar] = field(default_factory=list) + + def to_json(self, indent: int | None = 4) -> str: + return dumps(asdict(self), indent=indent) + + +@dataclass(frozen=True) +class ExponentialHistogram: + """Represents the type of a metric that is calculated by aggregating as an + ExponentialHistogram of all reported measurements over a time interval. + """ + + data_points: Sequence[ExponentialHistogramDataPoint] + aggregation_temporality: "opentelemetry.sdk.metrics.export.AggregationTemporality" + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], + "aggregation_temporality": self.aggregation_temporality, + }, + indent=indent, + ) + + +@dataclass(frozen=True) +class Sum: + """Represents the type of a scalar metric that is calculated as a sum of + all reported measurements over a time interval.""" + + data_points: Sequence[NumberDataPoint] + aggregation_temporality: "opentelemetry.sdk.metrics.export.AggregationTemporality" + is_monotonic: bool + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], + "aggregation_temporality": self.aggregation_temporality, + "is_monotonic": self.is_monotonic, + }, + indent=indent, + ) + + +@dataclass(frozen=True) +class Gauge: + """Represents the type of a scalar metric that always exports the current + value for every data point. It should be used for an unknown + aggregation.""" + + data_points: Sequence[NumberDataPoint] + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], + }, + indent=indent, + ) + + +@dataclass(frozen=True) +class Histogram: + """Represents the type of a metric that is calculated by aggregating as a + histogram of all reported measurements over a time interval.""" + + data_points: Sequence[HistogramDataPoint] + aggregation_temporality: "opentelemetry.sdk.metrics.export.AggregationTemporality" + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], + "aggregation_temporality": self.aggregation_temporality, + }, + indent=indent, + ) + + +# pylint: disable=invalid-name +DataT = Sum | Gauge | Histogram | ExponentialHistogram +DataPointT = NumberDataPoint | HistogramDataPoint | ExponentialHistogramDataPoint + + +@dataclass(frozen=True) +class Metric: + """Represents a metric point in the OpenTelemetry data model to be + exported.""" + + name: str + description: str | None + unit: str | None + data: DataT + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "name": self.name, + "description": self.description or "", + "unit": self.unit or "", + "data": loads(self.data.to_json(indent=indent)), + }, + indent=indent, + ) + + +@dataclass(frozen=True) +class ScopeMetrics: + """A collection of Metrics produced by a scope""" + + scope: InstrumentationScope + metrics: Sequence[Metric] + schema_url: str + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "scope": loads(self.scope.to_json(indent=indent)), + "metrics": [loads(metric.to_json(indent=indent)) for metric in self.metrics], + "schema_url": self.schema_url, + }, + indent=indent, + ) + + +@dataclass(frozen=True) +class ResourceMetrics: + """A collection of ScopeMetrics from a Resource""" + + resource: Resource + scope_metrics: Sequence[ScopeMetrics] + schema_url: str + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "resource": loads(self.resource.to_json(indent=indent)), + "scope_metrics": [loads(scope_metrics.to_json(indent=indent)) for scope_metrics in self.scope_metrics], + "schema_url": self.schema_url, + }, + indent=indent, + ) + + +@dataclass(frozen=True) +class MetricsData: + """An array of ResourceMetrics""" + + resource_metrics: Sequence[ResourceMetrics] + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "resource_metrics": [ + loads(resource_metrics.to_json(indent=indent)) for resource_metrics in self.resource_metrics + ] + }, + indent=indent, + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py new file mode 100644 index 00000000000..3f372371560 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py @@ -0,0 +1,20 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=unused-import + +from collections.abc import Sequence +from dataclasses import dataclass + +# This kind of import is needed to avoid Sphinx errors. +import opentelemetry.agent._vendor.opentelemetry.sdk.metrics +from opentelemetry.agent._vendor import opentelemetry +import opentelemetry.agent._vendor.opentelemetry.sdk.resources +from opentelemetry.agent._vendor import opentelemetry + + +@dataclass +class SdkConfiguration: + exemplar_filter: "opentelemetry.sdk.metrics.ExemplarFilter" + resource: "opentelemetry.sdk.resources.Resource" + views: Sequence["opentelemetry.sdk.metrics.view.View"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py new file mode 100644 index 00000000000..b4689bad76d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py @@ -0,0 +1,194 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable +from fnmatch import fnmatchcase +from logging import getLogger + +from opentelemetry.agent._vendor.opentelemetry.metrics import Instrument +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( + Aggregation, + DefaultAggregation, + _Aggregation, + _ExplicitBucketHistogramAggregation, + _ExponentialBucketHistogramAggregation, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( + AlignedHistogramBucketExemplarReservoir, + ExemplarReservoirBuilder, + SimpleFixedSizeExemplarReservoir, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument + +_logger = getLogger(__name__) + + +def _default_reservoir_factory( + aggregation_type: type[_Aggregation], +) -> ExemplarReservoirBuilder: + """Default reservoir factory per aggregation.""" + if issubclass(aggregation_type, _ExplicitBucketHistogramAggregation): + return AlignedHistogramBucketExemplarReservoir + if issubclass(aggregation_type, _ExponentialBucketHistogramAggregation): + return SimpleFixedSizeExemplarReservoir + return SimpleFixedSizeExemplarReservoir + + +class View: + """ + A `View` configuration parameters can be used for the following + purposes: + + 1. Match instruments: When an instrument matches a view, measurements + received by that instrument will be processed. + 2. Customize metric streams: A metric stream is identified by a match + between a view and an instrument and a set of attributes. The metric + stream can be customized by certain attributes of the corresponding view. + + The attributes documented next serve one of the previous two purposes. + + Args: + instrument_type: This is an instrument matching attribute: the class the + instrument must be to match the view. + + instrument_name: This is an instrument matching attribute: the name the + instrument must have to match the view. Wild card characters are supported. Wild + card characters should not be used with this attribute if the view has also a + ``name`` defined. + + meter_name: This is an instrument matching attribute: the name the + instrument meter must have to match the view. + + meter_version: This is an instrument matching attribute: the version + the instrument meter must have to match the view. + + meter_schema_url: This is an instrument matching attribute: the schema + URL the instrument meter must have to match the view. + + name: This is a metric stream customizing attribute: the name of the + metric stream. If `None`, the name of the instrument will be used. + + description: This is a metric stream customizing attribute: the + description of the metric stream. If `None`, the description of the instrument will + be used. + + attribute_keys: This is a metric stream customizing attribute: this is + a set of attribute keys. If not `None` then only the measurement attributes that + are in ``attribute_keys`` will be used to identify the metric stream. + + aggregation: This is a metric stream customizing attribute: the + aggregation instance to use when data is aggregated for the + corresponding metrics stream. If `None` an instance of + `DefaultAggregation` will be used. + + exemplar_reservoir_factory: This is a metric stream customizing attribute: + the exemplar reservoir factory + + instrument_unit: This is an instrument matching attribute: the unit the + instrument must have to match the view. + + aggregation_cardinality_limit: This is a metric stream customizing + attribute: the maximum number of distinct attribute sets the + stream aggregates per collection cycle. Measurements with further + attribute sets are aggregated into one additional point identified + by the attribute ``otel.metric.overflow=true``. If `None` the + cardinality limit of the metric reader is used, which defaults to + 2000. Must be a positive integer. + + This class is not intended to be subclassed by the user. + """ + + _default_aggregation = DefaultAggregation() + + def __init__( + self, + instrument_type: type[Instrument] | None = None, + instrument_name: str | None = None, + meter_name: str | None = None, + meter_version: str | None = None, + meter_schema_url: str | None = None, + name: str | None = None, + description: str | None = None, + attribute_keys: set[str] | None = None, + aggregation: Aggregation | None = None, + exemplar_reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder] | None = None, + instrument_unit: str | None = None, + aggregation_cardinality_limit: int | None = None, + ): + if aggregation_cardinality_limit is not None and ( + isinstance(aggregation_cardinality_limit, bool) + or not isinstance(aggregation_cardinality_limit, int) + or aggregation_cardinality_limit < 1 + ): + raise ValueError( + f"aggregation_cardinality_limit must be a positive integer, got {aggregation_cardinality_limit!r}" + ) + + if ( + instrument_type + is instrument_name + is instrument_unit + is meter_name + is meter_version + is meter_schema_url + is None + ): + # pylint: disable=broad-exception-raised + raise Exception(f"Some instrument selection criteria must be provided for View {name}") + + if name is not None and instrument_name is not None and ("*" in instrument_name or "?" in instrument_name): + # pylint: disable=broad-exception-raised + raise Exception(f"View {name} declared with wildcard characters in instrument_name") + + # _name, _description, _aggregation, _exemplar_reservoir_factory, + # _attribute_keys and _aggregation_cardinality_limit will be accessed + # when instantiating a _ViewInstrumentMatch. + self._name = name + self._instrument_type = instrument_type + self._instrument_name = instrument_name + self._instrument_unit = instrument_unit + self._meter_name = meter_name + self._meter_version = meter_version + self._meter_schema_url = meter_schema_url + + self._description = description + self._attribute_keys = attribute_keys + self._aggregation = aggregation or self._default_aggregation + self._exemplar_reservoir_factory = exemplar_reservoir_factory or _default_reservoir_factory + self._aggregation_cardinality_limit = aggregation_cardinality_limit + + # pylint: disable=too-many-return-statements + # pylint: disable=too-many-branches + def _match(self, instrument: _Instrument) -> bool: + if self._instrument_type is not None: + if not isinstance(instrument, self._instrument_type): + return False + + if self._instrument_name is not None: + # Instrument names are treated case-insensitively and are stored + # lower-cased by the SDK, so the pattern is lower-cased to match. + # fnmatchcase is used instead of fnmatch so it does not rely + # on the host platform's filename case sensitivity (normcase). + if not fnmatchcase(instrument.name, self._instrument_name.lower()): + return False + + if self._instrument_unit is not None: + # Units are case-sensitive; fnmatchcase keeps matching consistent + # across platforms. + if not fnmatchcase(instrument.unit, self._instrument_unit): + return False + + if self._meter_name is not None: + if instrument.instrumentation_scope.name != self._meter_name: + return False + + if self._meter_version is not None: + if instrument.instrumentation_scope.version != self._meter_version: + return False + + if self._meter_schema_url is not None: + if instrument.instrumentation_scope.schema_url != self._meter_schema_url: + return False + + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py new file mode 100644 index 00000000000..e8f17f684e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py @@ -0,0 +1,61 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( + AggregationTemporality, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.export import ( + CardinalityLimits, + ConsoleMetricExporter, + InMemoryMetricReader, + InstrumentCardinalityKey, + MetricExporter, + MetricExportResult, + MetricReader, + PeriodicExportingMetricReader, +) + +# The point module is not in the export directory to avoid a circular import. +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( + Buckets, + DataPointT, + DataT, + ExponentialHistogram, + ExponentialHistogramDataPoint, + Gauge, + Histogram, + HistogramDataPoint, + Metric, + MetricsData, + NumberDataPoint, + ResourceMetrics, + ScopeMetrics, + Sum, +) + +__all__ = [ + "AggregationTemporality", + "Buckets", + "CardinalityLimits", + "ConsoleMetricExporter", + "DataPointT", + "DataT", + "ExponentialHistogram", + "ExponentialHistogramDataPoint", + "Gauge", + "Histogram", + "HistogramDataPoint", + "InMemoryMetricReader", + "InstrumentCardinalityKey", + "Metric", + "MetricExportResult", + "MetricExporter", + "MetricReader", + "MetricsData", + "NumberDataPoint", + "PeriodicExportingMetricReader", + "ResourceMetrics", + "ScopeMetrics", + "Sum", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py new file mode 100644 index 00000000000..4f661ffd2c4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py @@ -0,0 +1,24 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( + Aggregation, + DefaultAggregation, + DropAggregation, + ExplicitBucketHistogramAggregation, + ExponentialBucketHistogramAggregation, + LastValueAggregation, + SumAggregation, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.view import View + +__all__ = [ + "Aggregation", + "DefaultAggregation", + "DropAggregation", + "ExplicitBucketHistogramAggregation", + "ExponentialBucketHistogramAggregation", + "LastValueAggregation", + "SumAggregation", + "View", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py new file mode 100644 index 00000000000..3008bcb616f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py @@ -0,0 +1,776 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +This package implements `OpenTelemetry Resources +`_: + + *A Resource is an immutable representation of the entity producing + telemetry. For example, a process producing telemetry that is running in + a container on Kubernetes has a Pod name, it is in a namespace and + possibly is part of a Deployment which also has a name. All three of + these attributes can be included in the Resource.* + +Resource objects are created with `Resource.create`, which accepts attributes +(key-values). Resources should NOT be created via constructor except by `ResourceDetector` +instances which can't use `Resource.create` to avoid infinite loops. Working with +`Resource` objects should only be done via the Resource API methods. Resource +attributes can also be passed at process invocation in the +:envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable. You should register +your resource with the `opentelemetry.sdk.trace.TracerProvider` by passing +them into their constructors. The `Resource` passed to a provider is available +to the exporter, which can send on this information as it sees fit. + +.. code-block:: python + + trace.set_tracer_provider( + TracerProvider( + resource=Resource.create( + { + "service.name": "shoppingcart", + "service.instance.id": "instance-12", + } + ), + ), + ) + print(trace.get_tracer_provider().resource.attributes) + + { + "telemetry.sdk.language": "python", + "telemetry.sdk.name": "opentelemetry", + "telemetry.sdk.version": "0.13.dev0", + "service.name": "shoppingcart", + "service.instance.id": "instance-12", + } + +Note that the OpenTelemetry project documents certain `"standard attributes" +`_ +that have prescribed semantic meanings, for example ``service.name`` in the +above example. +""" + +# ResourceAttributes is deprecated +# pyright: reportDeprecated=false + +import abc +import concurrent.futures +import logging +import os +import platform +import socket +import subprocess +import sys +import threading +import uuid +from collections.abc import Mapping, Sequence +from json import dumps +from os import environ +from types import ModuleType +from urllib import parse + +from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, + OTEL_RESOURCE_ATTRIBUTES, + OTEL_SERVICE_NAME, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.version import ( + __version__ as _OPENTELEMETRY_SDK_VERSION, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.resource import ResourceAttributes +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue + +psutil: ModuleType | None = None + +try: + import psutil as psutil_module + + psutil = psutil_module +except ImportError: + pass + +# Only available on Windows, where it is used to read the MachineGuid for host.id. +winreg: ModuleType | None = None + +try: + import winreg as winreg_module + + winreg = winreg_module +except ImportError: + pass + +LabelValue = AnyValue +Attributes = Mapping[str, LabelValue] +logger = logging.getLogger(__name__) +CLOUD_PROVIDER = ResourceAttributes.CLOUD_PROVIDER +CLOUD_ACCOUNT_ID = ResourceAttributes.CLOUD_ACCOUNT_ID +CLOUD_REGION = ResourceAttributes.CLOUD_REGION +CLOUD_AVAILABILITY_ZONE = ResourceAttributes.CLOUD_AVAILABILITY_ZONE +CONTAINER_NAME = ResourceAttributes.CONTAINER_NAME +CONTAINER_ID = ResourceAttributes.CONTAINER_ID +CONTAINER_IMAGE_NAME = ResourceAttributes.CONTAINER_IMAGE_NAME +CONTAINER_IMAGE_TAG = ResourceAttributes.CONTAINER_IMAGE_TAG +DEPLOYMENT_ENVIRONMENT = ResourceAttributes.DEPLOYMENT_ENVIRONMENT +FAAS_NAME = ResourceAttributes.FAAS_NAME +FAAS_ID = ResourceAttributes.FAAS_ID +FAAS_VERSION = ResourceAttributes.FAAS_VERSION +FAAS_INSTANCE = ResourceAttributes.FAAS_INSTANCE +HOST_NAME = ResourceAttributes.HOST_NAME +HOST_ARCH = ResourceAttributes.HOST_ARCH +HOST_ID = ResourceAttributes.HOST_ID +HOST_TYPE = ResourceAttributes.HOST_TYPE +HOST_IMAGE_NAME = ResourceAttributes.HOST_IMAGE_NAME +HOST_IMAGE_ID = ResourceAttributes.HOST_IMAGE_ID +HOST_IMAGE_VERSION = ResourceAttributes.HOST_IMAGE_VERSION +KUBERNETES_CLUSTER_NAME = ResourceAttributes.K8S_CLUSTER_NAME +KUBERNETES_NAMESPACE_NAME = ResourceAttributes.K8S_NAMESPACE_NAME +KUBERNETES_POD_UID = ResourceAttributes.K8S_POD_UID +KUBERNETES_POD_NAME = ResourceAttributes.K8S_POD_NAME +KUBERNETES_CONTAINER_NAME = ResourceAttributes.K8S_CONTAINER_NAME +KUBERNETES_REPLICA_SET_UID = ResourceAttributes.K8S_REPLICASET_UID +KUBERNETES_REPLICA_SET_NAME = ResourceAttributes.K8S_REPLICASET_NAME +KUBERNETES_DEPLOYMENT_UID = ResourceAttributes.K8S_DEPLOYMENT_UID +KUBERNETES_DEPLOYMENT_NAME = ResourceAttributes.K8S_DEPLOYMENT_NAME +KUBERNETES_STATEFUL_SET_UID = ResourceAttributes.K8S_STATEFULSET_UID +KUBERNETES_STATEFUL_SET_NAME = ResourceAttributes.K8S_STATEFULSET_NAME +KUBERNETES_DAEMON_SET_UID = ResourceAttributes.K8S_DAEMONSET_UID +KUBERNETES_DAEMON_SET_NAME = ResourceAttributes.K8S_DAEMONSET_NAME +KUBERNETES_JOB_UID = ResourceAttributes.K8S_JOB_UID +KUBERNETES_JOB_NAME = ResourceAttributes.K8S_JOB_NAME +KUBERNETES_CRON_JOB_UID = ResourceAttributes.K8S_CRONJOB_UID +KUBERNETES_CRON_JOB_NAME = ResourceAttributes.K8S_CRONJOB_NAME +OS_DESCRIPTION = ResourceAttributes.OS_DESCRIPTION +OS_TYPE = ResourceAttributes.OS_TYPE +OS_VERSION = ResourceAttributes.OS_VERSION +PROCESS_PID = ResourceAttributes.PROCESS_PID +PROCESS_PARENT_PID = ResourceAttributes.PROCESS_PARENT_PID +PROCESS_EXECUTABLE_NAME = ResourceAttributes.PROCESS_EXECUTABLE_NAME +PROCESS_EXECUTABLE_PATH = ResourceAttributes.PROCESS_EXECUTABLE_PATH +PROCESS_COMMAND = ResourceAttributes.PROCESS_COMMAND +PROCESS_COMMAND_LINE = ResourceAttributes.PROCESS_COMMAND_LINE +PROCESS_COMMAND_ARGS = ResourceAttributes.PROCESS_COMMAND_ARGS +PROCESS_OWNER = ResourceAttributes.PROCESS_OWNER +PROCESS_RUNTIME_NAME = ResourceAttributes.PROCESS_RUNTIME_NAME +PROCESS_RUNTIME_VERSION = ResourceAttributes.PROCESS_RUNTIME_VERSION +PROCESS_RUNTIME_DESCRIPTION = ResourceAttributes.PROCESS_RUNTIME_DESCRIPTION +SERVICE_NAME = ResourceAttributes.SERVICE_NAME +SERVICE_NAMESPACE = ResourceAttributes.SERVICE_NAMESPACE +SERVICE_INSTANCE_ID = ResourceAttributes.SERVICE_INSTANCE_ID +SERVICE_VERSION = ResourceAttributes.SERVICE_VERSION +TELEMETRY_SDK_NAME = ResourceAttributes.TELEMETRY_SDK_NAME +TELEMETRY_SDK_VERSION = ResourceAttributes.TELEMETRY_SDK_VERSION +TELEMETRY_AUTO_VERSION = ResourceAttributes.TELEMETRY_AUTO_VERSION +TELEMETRY_SDK_LANGUAGE = ResourceAttributes.TELEMETRY_SDK_LANGUAGE + + +class Resource: + """A Resource is an immutable representation of the entity producing telemetry as Attributes.""" + + _attributes: BoundedAttributes + _schema_url: str + + def __init__(self, attributes: Attributes, schema_url: str | None = None): + # Immutable set to true so attributes cannot be added or removed after creation. + self._attributes = BoundedAttributes(attributes=attributes, immutable=True) + if schema_url is None: + schema_url = "" + self._schema_url = schema_url + + @staticmethod + def create( + attributes: Attributes | None = None, + schema_url: str | None = None, + ) -> "Resource": + """Creates a new `Resource` from attributes. + + `ResourceDetector` instances should not call this method. + + Args: + attributes: Optional zero or more key-value pairs. + schema_url: Optional URL pointing to the schema + + Returns: + The newly-created Resource. + """ + + if not attributes: + attributes = {} + + resource = get_aggregated_resources(_build_resource_detectors(), _DEFAULT_RESOURCE).merge( + Resource(attributes, schema_url) + ) + + if not resource.attributes.get(SERVICE_NAME, None): + default_service_name = "unknown_service" + if sys.executable: + default_service_name += f":{os.path.basename(sys.executable)}" + resource = resource.merge(Resource({SERVICE_NAME: default_service_name}, schema_url)) + return resource + + @staticmethod + def get_empty() -> "Resource": + return _EMPTY_RESOURCE + + @property + def attributes(self) -> Attributes: + return self._attributes + + @property + def schema_url(self) -> str: + return self._schema_url + + def merge(self, other: "Resource") -> "Resource": + """Merges this resource and an updating resource into a new `Resource`. + + If a key exists on both the old and updating resource, the value of the + updating resource will override the old resource value. + + The updating resource's `schema_url` will be used only if the old + `schema_url` is empty. Attempting to merge two resources with + different, non-empty values for `schema_url` will result in an error + and return the old resource. + + Args: + other: The other resource to be merged. + + Returns: + The newly-created Resource. + """ + merged_attributes = dict(self.attributes) + merged_attributes.update(other.attributes) + + if self.schema_url == "": + schema_url = other.schema_url + elif other.schema_url == "": + schema_url = self.schema_url + elif self.schema_url == other.schema_url: + schema_url = other.schema_url + else: + logger.error( + "Failed to merge resources: The two schemas %s and %s are incompatible", + self.schema_url, + other.schema_url, + ) + return self + return Resource(merged_attributes, schema_url) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Resource): + return False + return self._attributes == other._attributes and self._schema_url == other._schema_url + + def __hash__(self) -> int: + return hash(f"{dumps(self._attributes.copy(), sort_keys=True, default=_json_default)}|{self._schema_url}") + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "attributes": dict(self.attributes), + "schema_url": self._schema_url, + }, + indent=indent, + default=_json_default, + ) + + +def _json_default(value: object) -> str: + """Represent attribute values that `json` cannot encode natively. + + `types.AnyValue` admits `bytes`, which `json.dumps` rejects. Rendering it + as hex keeps `to_json` readable and keeps `__hash__` working; `__eq__` + still distinguishes `b"\x01"` from the string `"01"`, so the resulting + hash collision is harmless. + """ + if isinstance(value, (bytes, bytearray)): + return value.hex() + return str(value) + + +_EMPTY_RESOURCE = Resource({}) + +_DEFAULT_RESOURCE = Resource( + { + TELEMETRY_SDK_LANGUAGE: "python", + TELEMETRY_SDK_NAME: "opentelemetry", + TELEMETRY_SDK_VERSION: _OPENTELEMETRY_SDK_VERSION, + } +) + + +_service_instance_id: str | None = None +_service_instance_id_pid: int | None = None +_service_instance_id_lock = threading.Lock() + + +class ResourceDetector(abc.ABC): + def __init__(self, raise_on_error: bool = False) -> None: + self.raise_on_error = raise_on_error + + @abc.abstractmethod + def detect(self) -> "Resource": + """Don't call `Resource.create` here to avoid an infinite loop, instead instantiate `Resource` directly""" + raise NotImplementedError() + + # pylint: disable-next=no-self-use + def is_process_dependent(self) -> bool: + """Return whether this detector depends on the current process identity. + + Process dependent detectors may return resource attributes that become + stale after a process identity change, such as :func:`os.fork`. + Detectors returning ``True`` should be re-run after such changes so the + resulting :class:`Resource` describes the current process. + + Returns: + ``True`` if this detector should be re-run after process identity + changes otherwise ``False``. + """ + return False + + +class OTELResourceDetector(ResourceDetector): + # pylint: disable=no-self-use + def detect(self) -> "Resource": + env_resources_items = environ.get(OTEL_RESOURCE_ATTRIBUTES) + env_resource_map: dict[str, AnyValue] = {} + + if env_resources_items: + for item in env_resources_items.split(","): + try: + key, value = item.split("=", maxsplit=1) + except ValueError as exc: + logger.warning( + "Invalid key value resource attribute pair %s: %s", + item, + exc, + ) + continue + value_url_decoded = parse.unquote(value.strip()) + env_resource_map[key.strip()] = value_url_decoded + + service_name = environ.get(OTEL_SERVICE_NAME) + if service_name: + env_resource_map[SERVICE_NAME] = service_name + return Resource(env_resource_map) + + +class ProcessResourceDetector(ResourceDetector): + """Detect process resource attributes. + + Args: + raise_on_error: Raise errors from detection instead of logging them. + include_command_args: Include ``process.command_args`` and + ``process.command_line``. These attributes can contain sensitive + command-line values, so they are excluded by default. + """ + + def __init__( + self, + raise_on_error: bool = False, + *, + include_command_args: bool = False, + ) -> None: + super().__init__(raise_on_error=raise_on_error) + self._include_command_args = include_command_args + + # pylint: disable=no-self-use + def is_process_dependent(self) -> bool: + return True + + def detect(self) -> "Resource": + _runtime_version = ".".join( + map( + str, + ( + sys.version_info[:3] + if sys.version_info.releaselevel == "final" and not sys.version_info.serial + else sys.version_info + ), + ) + ) + _process_pid = os.getpid() + # Use sys.orig_argv, which preserves the original arguments received + # by the interpreter. This correctly captures ``python -m `` + # invocations where sys.argv is rewritten to the resolved module path + # and the ``-m `` information is lost. Only read argv[0] by + # default because full command arguments are opt-in. + _process_command = sys.orig_argv[0] if sys.orig_argv else "" + executable = sys.executable or "" + resource_info: dict[str, AnyValue] = { + PROCESS_RUNTIME_DESCRIPTION: sys.version, + PROCESS_RUNTIME_NAME: sys.implementation.name, + PROCESS_RUNTIME_VERSION: _runtime_version, + PROCESS_PID: _process_pid, + PROCESS_EXECUTABLE_NAME: os.path.basename(executable), + PROCESS_EXECUTABLE_PATH: executable, + PROCESS_COMMAND: _process_command, + } + if self._include_command_args: + _process_argv = list(sys.orig_argv) + resource_info[PROCESS_COMMAND_LINE] = " ".join(_process_argv) + resource_info[PROCESS_COMMAND_ARGS] = _process_argv + + if hasattr(os, "getppid"): + # pypy3 does not have getppid() + resource_info[PROCESS_PARENT_PID] = os.getppid() + + if psutil is not None: + process = psutil.Process() + username = process.username() + resource_info[PROCESS_OWNER] = username + + return Resource(resource_info) # type: ignore + + +class OsResourceDetector(ResourceDetector): + """Detect os resources based on `Operating System conventions `_.""" + + def detect(self) -> "Resource": + """Returns a resource with with ``os.type`` and ``os.version``. + + Python's platform library + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + To grab this information, Python's ``platform`` does not return what a + user might expect it to. Below is a breakdown of its return values in + different operating systems. + + .. code-block:: python + :caption: Linux + + >>> platform.system() + 'Linux' + >>> platform.release() + '6.5.0-35-generic' + >>> platform.version() + '#35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2' + + .. code-block:: python + :caption: MacOS + + >>> platform.system() + 'Darwin' + >>> platform.release() + '23.0.0' + >>> platform.version() + 'Darwin Kernel Version 23.0.0: Fri Sep 15 14:42:57 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T8112' + + .. code-block:: python + :caption: Windows + + >>> platform.system() + 'Windows' + >>> platform.release() + '2022Server' + >>> platform.version() + '10.0.20348' + + .. code-block:: python + :caption: FreeBSD + + >>> platform.system() + 'FreeBSD' + >>> platform.release() + '14.1-RELEASE' + >>> platform.version() + 'FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC' + + .. code-block:: python + :caption: Solaris + + >>> platform.system() + 'SunOS' + >>> platform.release() + '5.11' + >>> platform.version() + '11.4.0.15.0' + + """ + + os_type = platform.system().lower() + os_version = platform.release() + + # See docstring + if os_type == "windows": + os_version = platform.version() + # Align SunOS with conventions + elif os_type == "sunos": + os_type = "solaris" + os_version = platform.version() + + return Resource( + { + OS_TYPE: os_type, + OS_VERSION: os_version, + } + ) + + +# Non-privileged machine id sources per the semantic conventions: +# https://opentelemetry.io/docs/specs/semconv/resource/host/#non-privileged-machine-id-lookup +_LINUX_MACHINE_ID_PATHS = ("/etc/machine-id", "/var/lib/dbus/machine-id") +_BSD_HOSTID_PATH = "/etc/hostid" +_BSD_KENV_COMMAND = ("/bin/kenv", "-q", "smbios.system.uuid") +_MACOS_IOREG_COMMAND = ("/usr/sbin/ioreg", "-rd1", "-c", "IOPlatformExpertDevice") +_WINDOWS_CRYPTOGRAPHY_KEY = r"SOFTWARE\Microsoft\Cryptography" +_WINDOWS_MACHINE_GUID_VALUE = "MachineGuid" +# Deliberately below get_aggregated_resources' per detector timeout so that a +# hung command still leaves time for host.name and host.arch to be returned. +_COMMAND_TIMEOUT_SECONDS = 2 + + +def _read_machine_id_file(path: str) -> str | None: + try: + with open(path, encoding="utf8") as machine_id_file: + return machine_id_file.read().strip() or None + except OSError as exception: + logger.debug("Failed to read %s: %s", path, exception) + return None + + +def _run_command(command: tuple[str, ...]) -> str: + """Returns the command's stdout, or "" when the source is unavailable here. + + A non-zero exit or a missing binary means this host has no machine id to + offer. + """ + try: + completed = subprocess.run( + command, + capture_output=True, + text=True, + timeout=_COMMAND_TIMEOUT_SECONDS, + check=True, + ) + except (subprocess.CalledProcessError, FileNotFoundError) as exception: + logger.debug("Failed to run %s: %s", command[0], exception) + return "" + return completed.stdout + + +def _get_linux_machine_id() -> str | None: + for path in _LINUX_MACHINE_ID_PATHS: + machine_id = _read_machine_id_file(path) + if machine_id: + return machine_id + return None + + +def _get_bsd_machine_id() -> str | None: + return _read_machine_id_file(_BSD_HOSTID_PATH) or _run_command(_BSD_KENV_COMMAND).strip() or None + + +def _get_macos_machine_id() -> str | None: + for line in _run_command(_MACOS_IOREG_COMMAND).splitlines(): + # The line looks like: ` "IOPlatformUUID" = "AAAAAAAA-BBBB-..."` + key, separator, value = line.partition("=") + if not separator or key.strip().strip('"') != "IOPlatformUUID": + continue + + machine_id = value.strip().strip('"') + if machine_id: + return machine_id + return None + + +def _get_windows_machine_id() -> str | None: + if winreg is None: + logger.debug("winreg is unavailable, cannot detect %s", HOST_ID) + return None + with winreg.OpenKey( + winreg.HKEY_LOCAL_MACHINE, + _WINDOWS_CRYPTOGRAPHY_KEY, + access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY, + ) as key: + machine_guid, _ = winreg.QueryValueEx(key, _WINDOWS_MACHINE_GUID_VALUE) + return str(machine_guid) if machine_guid else None + + +def _get_host_id() -> str | None: + system = platform.system() + if system == "Linux": + return _get_linux_machine_id() + if system == "Darwin": + return _get_macos_machine_id() + if system == "Windows": + return _get_windows_machine_id() + if system == "DragonFly" or system.endswith("BSD"): + return _get_bsd_machine_id() + logger.debug("Unsupported OS type for %s detection: %s", HOST_ID, system) + return None + + +class _HostResourceDetector(ResourceDetector): # type: ignore[reportUnusedClass] + """ + The HostResourceDetector detects the hostname, architecture and host id + attributes. + + ``host.id`` is the non-privileged machine id described by the `Host resource + conventions `_, + and is omitted when it cannot be determined. A failed lookup does not + prevent ``host.name`` and ``host.arch`` from being detected unless + ``raise_on_error=True``. + """ + + def detect(self) -> "Resource": + resource_info: dict[str, AnyValue] = { + HOST_NAME: socket.gethostname(), + HOST_ARCH: platform.machine(), + } + + # A failed host id lookup must not cost the caller the attributes above, + # so it is guarded here rather than relying on the handling in + # get_aggregated_resources: detect() is also called directly. + try: + if host_id := _get_host_id(): + resource_info[HOST_ID] = host_id + # pylint: disable=broad-exception-caught + except Exception as exception: + logger.warning("Failed to detect %s: %s", HOST_ID, exception) + if self.raise_on_error: + raise + + return Resource(resource_info) + + +class ServiceInstanceIdResourceDetector(ResourceDetector): + """Detects service.instance.id as a random UUID v4. + + Per the OpenTelemetry specification, SDKs SHOULD generate a random v1/v4 + UUID for service.instance.id to uniquely identify each service instance. + The ID is shared across all detector instances within the same process and + regenerated automatically when the process PID changes (e.g. after a fork). + + Note: because this detector is process dependent, providers refresh it + automatically after a fork and merge the newly detected value on top of + the existing resource. This means that if a user explicitly sets + `service.instance.id` (e.g. via OTEL_RESOURCE_ATTRIBUTES or + Resource.create(attributes=...)), that value will be overwritten with a + newly generated UUID the next time the process forks. This differs from + Resource.create(), which does preserve user supplied overrides. + """ + + def is_process_dependent(self) -> bool: + return True + + def detect(self) -> "Resource": + # pylint: disable-next=global-statement + global _service_instance_id, _service_instance_id_pid + with _service_instance_id_lock: + current_pid = os.getpid() + if _service_instance_id is None or _service_instance_id_pid != current_pid: + _service_instance_id = str(uuid.uuid4()) + _service_instance_id_pid = current_pid + instance_id = _service_instance_id + return Resource({SERVICE_INSTANCE_ID: instance_id}) + + +def _build_resource_detectors() -> list["ResourceDetector"]: + """Returns the ordered list of resource detectors to use for Resource.create. + + Fast path: if no extra detectors are configured, returns only the two + built-in detectors without scanning entry_points. + + "service_instance" (ServiceInstanceIdResourceDetector) is prepended unless + it is explicitly configured. "otel" (OTELResourceDetector) is last so + that OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME take highest merge + priority, but an explicit position in + OTEL_EXPERIMENTAL_RESOURCE_DETECTORS is respected for either name. + """ + configured_detector_names = [ + name.strip() for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") if name.strip() + ] + default_detector_names = [] if "service_instance" in configured_detector_names else ["service_instance"] + detector_names: list[str] = list(dict.fromkeys(default_detector_names + configured_detector_names + ["otel"])) + + # Fast path: only the two built-in detectors — no entry_points scan needed. + if detector_names == ["service_instance", "otel"]: + return [ServiceInstanceIdResourceDetector(), OTELResourceDetector()] + + # pylint: disable=import-outside-toplevel + from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 + entry_points, # type: ignore[reportUnknownVariableType] + ) + + if "*" in detector_names: + registered = set( + name + for name in entry_points(group="opentelemetry_resource_detector").names # type: ignore[reportUnknownArgumentType] + if name != "otel" + ) + expansion = sorted(registered - set(detector_names)) + idx = detector_names.index("*") + detector_names = detector_names[:idx] + expansion + detector_names[idx + 1 :] + + detectors: list[ResourceDetector] = [] + for name in detector_names: + try: + detectors.append( + next( + iter( + entry_points( + group="opentelemetry_resource_detector", + name=name, + ) # type: ignore[reportUnknownArgumentType] + ) + ).load()() + ) + except Exception: # pylint: disable=broad-exception-caught + logger.exception( + "Failed to load resource detector '%s', skipping", + name, + ) + return detectors + + +def _get_process_dependent_resource() -> Resource: # pyright: ignore[reportUnusedFunction] + return get_aggregated_resources( + [detector for detector in _build_resource_detectors() if detector.is_process_dependent()], + Resource.get_empty(), + ) + + +def get_aggregated_resources( + detectors: Sequence["ResourceDetector"], + initial_resource: Resource | None = None, + timeout: int = 5, +) -> "Resource": + """Retrieves resources from detectors in the order that they were passed + + :param detectors: List of resources in order of priority + :param initial_resource: Static resource. This has highest priority + :param timeout: Number of seconds to wait for each detector to return + :return: + """ + detectors_merged_resource = initial_resource or Resource.create() + + # A detector that exceeds `timeout` is skipped, but shutdown still joins + # its worker so no threads outlive this call. A detector that blocks + # indefinitely therefore blocks this call. `cancel_futures=True` drops + # detectors that have not started yet if a `raise_on_error` detector raises. + executor = concurrent.futures.ThreadPoolExecutor(max_workers=4) + try: + futures = [executor.submit(detector.detect) for detector in detectors] + for detector_ind, future in enumerate(futures): + detector = detectors[detector_ind] + detected_resource: Resource = _EMPTY_RESOURCE + try: + detected_resource = future.result(timeout=timeout) + except concurrent.futures.TimeoutError as ex: + if detector.raise_on_error: + raise ex + logger.warning( + "Detector %s took longer than %s seconds, skipping", + detector, + timeout, + ) + # pylint: disable=broad-exception-caught + except Exception as ex: + if detector.raise_on_error: + raise ex + logger.warning("Exception %s in detector %s, ignoring", ex, detector) + finally: + detectors_merged_resource = detectors_merged_resource.merge(detected_resource) + finally: + executor.shutdown(wait=True, cancel_futures=True) + + return detectors_merged_resource diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py new file mode 100644 index 00000000000..1f7ab187dec --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py @@ -0,0 +1,1426 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=too-many-lines +import abc +import atexit +import concurrent.futures +import json +import logging +import os +import threading +import traceback +import typing +import weakref +from collections.abc import ( + Callable, + Iterator, + Mapping, + MutableMapping, + Sequence, +) +from dataclasses import dataclass +from os import environ +from time import time_ns +from types import MappingProxyType, TracebackType +from typing import ( + Any, +) +from warnings import filterwarnings + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry import context as context_api +from opentelemetry.agent._vendor.opentelemetry import metrics as metrics_api +from opentelemetry.agent._vendor.opentelemetry import trace as trace_api +from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes +from opentelemetry.agent._vendor.opentelemetry.sdk import util +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_ATTRIBUTE_COUNT_LIMIT, + OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, + OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, + OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, + OTEL_SDK_DISABLED, + OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, + OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, + OTEL_SPAN_EVENT_COUNT_LIMIT, + OTEL_SPAN_LINK_COUNT_LIMIT, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( + parse_boolean_environment_variable, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( + Resource, + _get_process_dependent_resource, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import sampling +from opentelemetry.agent._vendor.opentelemetry.sdk.trace._tracer_metrics import create_tracer_metrics +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator +from opentelemetry.agent._vendor.opentelemetry.sdk.util import BoundedList +from opentelemetry.agent._vendor.opentelemetry.sdk.util._configurator import RuleBasedConfigurator +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( + InstrumentationInfo, + InstrumentationScope, +) +from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.exception_attributes import ( + EXCEPTION_ESCAPED, + EXCEPTION_MESSAGE, + EXCEPTION_STACKTRACE, + EXCEPTION_TYPE, +) +from opentelemetry.agent._vendor.opentelemetry.trace import NoOpTracer, SpanContext +from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode +from opentelemetry.agent._vendor.opentelemetry.util import types +from opentelemetry.agent._vendor.opentelemetry.util._decorator import _agnosticcontextmanager + +logger = logging.getLogger(__name__) + +_DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT = 128 +_DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = 128 +_DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT = 128 +_DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = 128 +_DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT = 128 +_DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT = 128 + + +_ENV_VALUE_UNSET = "" + + +class SpanProcessor: + """Interface which allows hooks for SDK's `Span` start and end method + invocations. + + Span processors can be registered directly using + :func:`TracerProvider.add_span_processor` and they are invoked + in the same order as they were registered. + """ + + def on_start( + self, + span: "Span", + parent_context: context_api.Context | None = None, + ) -> None: + """Called when a :class:`opentelemetry.trace.Span` is started. + + This method is called synchronously on the thread that starts the + span, therefore it should not block or throw an exception. + + Args: + span: The :class:`opentelemetry.trace.Span` that just started. + parent_context: The parent context of the span that just started. + """ + + def _on_ending(self, span: "Span") -> None: + """Called when a :class:`opentelemetry.trace.Span` is ending. + + This method is called synchronously on the thread that ends the + span, therefore it should not block or throw an exception. + + Args: + span: The :class:`opentelemetry.trace.Span` that is ending. + """ + + def on_end(self, span: "ReadableSpan") -> None: + """Called when a :class:`opentelemetry.trace.Span` is ended. + + This method is called synchronously on the thread that ends the + span, therefore it should not block or throw an exception. + + Args: + span: The :class:`opentelemetry.trace.Span` that just ended. + """ + + def shutdown(self) -> None: + """Called when a :class:`opentelemetry.sdk.trace.TracerProvider` is shutdown.""" + + def force_flush(self, timeout_millis: int = 30000) -> bool: # pylint: disable=no-self-use + """Export all ended spans to the configured Exporter that have not yet + been exported. + + Args: + timeout_millis: The maximum amount of time to wait for spans to be + exported. + + Returns: + False if the timeout is exceeded, True otherwise. + """ + return True + + +# Temporary fix until https://github.com/PyCQA/pylint/issues/4098 is resolved +# pylint:disable=no-member +class SynchronousMultiSpanProcessor(SpanProcessor): + """Implementation of class:`SpanProcessor` that forwards all received + events to a list of span processors sequentially. + + The underlying span processors are called in sequential order as they were + added. + """ + + _span_processors: tuple[SpanProcessor, ...] + + def __init__(self): + # use a tuple to avoid race conditions when adding a new span and + # iterating through it on "on_start" and "on_end". + self._span_processors = () + self._lock = threading.Lock() + + def add_span_processor(self, span_processor: SpanProcessor) -> None: + """Adds a SpanProcessor to the list handled by this instance.""" + with self._lock: + self._span_processors += (span_processor,) + + def on_start( + self, + span: "Span", + parent_context: context_api.Context | None = None, + ) -> None: + for sp in self._span_processors: + sp.on_start(span, parent_context=parent_context) + + def _on_ending(self, span: "Span") -> None: + for sp in self._span_processors: + # pylint: disable=protected-access + sp._on_ending(span) + + def on_end(self, span: "ReadableSpan") -> None: + for sp in self._span_processors: + sp.on_end(span) + + def shutdown(self) -> None: + """Sequentially shuts down all underlying span processors.""" + for sp in self._span_processors: + sp.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Sequentially calls force_flush on all underlying + :class:`SpanProcessor` + + Args: + timeout_millis: The maximum amount of time over all span processors + to wait for spans to be exported. In case the first n span + processors exceeded the timeout followup span processors will be + skipped. + + Returns: + True if all span processors flushed their spans within the + given timeout, False otherwise. + """ + deadline_ns = time_ns() + timeout_millis * 1000000 + all_flushed = True + for sp in self._span_processors: + current_time_ns = time_ns() + if current_time_ns >= deadline_ns: + return False + + if sp.force_flush((deadline_ns - current_time_ns) // 1000000) is False: + all_flushed = False + + return all_flushed + + +class ConcurrentMultiSpanProcessor(SpanProcessor): + """Implementation of :class:`SpanProcessor` that forwards all received + events to a list of span processors in parallel. + + Calls to the underlying span processors are forwarded in parallel by + submitting them to a thread pool executor and waiting until each span + processor finished its work. + + Args: + num_threads: The number of threads managed by the thread pool executor + and thus defining how many span processors can work in parallel. + """ + + _span_processors: tuple[SpanProcessor, ...] + + def __init__(self, num_threads: int = 2): + # use a tuple to avoid race conditions when adding a new span and + # iterating through it on "on_start" and "on_end". + self._span_processors = () + self._lock = threading.Lock() + self._init_executor(num_threads) + if hasattr(os, "register_at_fork"): + # Only the main thread is kept in forked processed, the executor + # needs to be re-instantiated to get a fresh pool of threads: + weak_reinit = weakref.WeakMethod(self._init_executor) + + def _after_in_child() -> None: + reinit = weak_reinit() + if reinit is not None: + reinit(num_threads) + + os.register_at_fork(after_in_child=_after_in_child) + + def _init_executor(self, num_threads: int) -> None: + self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) + + def add_span_processor(self, span_processor: SpanProcessor) -> None: + """Adds a SpanProcessor to the list handled by this instance.""" + with self._lock: + self._span_processors += (span_processor,) + + def _submit_and_await( + self, + func: Callable[[SpanProcessor], Callable[..., None]], + *args: Any, + **kwargs: Any, + ): + futures = [] + for sp in self._span_processors: + future = self._executor.submit(func(sp), *args, **kwargs) + futures.append(future) + for future in futures: + future.result() + + def on_start( + self, + span: "Span", + parent_context: context_api.Context | None = None, + ) -> None: + self._submit_and_await(lambda sp: sp.on_start, span, parent_context=parent_context) + + def _on_ending(self, span: "Span") -> None: + # pylint: disable=protected-access + self._submit_and_await(lambda sp: sp._on_ending, span) + + def on_end(self, span: "ReadableSpan") -> None: + self._submit_and_await(lambda sp: sp.on_end, span) + + def shutdown(self) -> None: + """Shuts down all underlying span processors in parallel.""" + self._submit_and_await(lambda sp: sp.shutdown) + + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Calls force_flush on all underlying span processors in parallel. + + Args: + timeout_millis: The maximum amount of time to wait for spans to be + exported. + + Returns: + True if all span processors flushed their spans within the given + timeout, False otherwise. + """ + futures = [] + for sp in self._span_processors: + future = self._executor.submit(sp.force_flush, timeout_millis) + futures.append(future) + + timeout_sec = timeout_millis / 1e3 + done_futures, not_done_futures = concurrent.futures.wait(futures, timeout_sec) + if not_done_futures: + return False + + for future in done_futures: + if future.result() is False: + return False + + return True + + +class EventBase(abc.ABC): + def __init__(self, name: str, timestamp: int | None = None) -> None: + self._name = name + if timestamp is None: + self._timestamp = time_ns() + else: + self._timestamp = timestamp + + @property + def name(self) -> str: + return self._name + + @property + def timestamp(self) -> int: + return self._timestamp + + @property + @abc.abstractmethod + def attributes(self) -> types.Attributes: + pass + + +class Event(EventBase): + """A text annotation with a set of attributes. The attributes of an event + are immutable. + + Args: + name: Name of the event. + attributes: Attributes of the event. + timestamp: Timestamp of the event. If `None` it will filled + automatically. + """ + + def __init__( + self, + name: str, + attributes: types.Attributes = None, + timestamp: int | None = None, + limit: int | None = _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, + ) -> None: + super().__init__(name, timestamp) + self._attributes = attributes + + @property + def attributes(self) -> types.Attributes: + return self._attributes + + @property + def dropped_attributes(self) -> int: + if isinstance(self._attributes, BoundedAttributes): + return self._attributes.dropped + return 0 + + +def _check_span_ended(func): + def wrapper(self, *args, **kwargs): + already_ended = False + with self._lock: # pylint: disable=protected-access + if self._end_time is None: # pylint: disable=protected-access + func(self, *args, **kwargs) + else: + already_ended = True + + if already_ended: + logger.warning("Tried calling %s on an ended span.", func.__name__) + + return wrapper + + +def _is_valid_link(context: SpanContext, attributes: types.Attributes) -> bool: + return bool(context and (context.is_valid or (attributes or context.trace_state))) + + +class ReadableSpan: + """Provides read-only access to span attributes. + + Users should NOT be creating these objects directly. `ReadableSpan`s are created as + a direct result from using the tracing pipeline via the `Tracer`. + + """ + + def __init__( + self, + name: str, + context: trace_api.SpanContext | None = None, + parent: trace_api.SpanContext | None = None, + resource: Resource | None = None, + attributes: types.Attributes = None, + events: Sequence[Event] = (), + links: Sequence[trace_api.Link] = (), + kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, + instrumentation_info: InstrumentationInfo | None = None, + status: Status = Status(StatusCode.UNSET), + start_time: int | None = None, + end_time: int | None = None, + instrumentation_scope: InstrumentationScope | None = None, + ) -> None: + self._name = name + self._context = context + self._kind = kind + self._instrumentation_info = instrumentation_info + self._instrumentation_scope = instrumentation_scope + self._parent = parent + self._start_time = start_time + self._end_time = end_time + self._attributes = attributes + self._events = events + self._links = links + if resource is None: + self._resource = Resource.create({}) + else: + self._resource = resource + self._status = status + + @property + def dropped_attributes(self) -> int: + if isinstance(self._attributes, BoundedAttributes): + return self._attributes.dropped + return 0 + + @property + def dropped_events(self) -> int: + if isinstance(self._events, BoundedList): + return self._events.dropped + return 0 + + @property + def dropped_links(self) -> int: + if isinstance(self._links, BoundedList): + return self._links.dropped + return 0 + + @property + def name(self) -> str: + return self._name + + def get_span_context(self) -> trace_api.SpanContext | None: + return self._context + + @property + def context(self): + return self._context + + @property + def kind(self) -> trace_api.SpanKind: + return self._kind + + @property + def parent(self) -> trace_api.SpanContext | None: + return self._parent + + @property + def start_time(self) -> int | None: + return self._start_time + + @property + def end_time(self) -> int | None: + return self._end_time + + @property + def status(self) -> trace_api.Status: + return self._status + + @property + def attributes(self) -> types.Attributes: + return MappingProxyType(self._attributes or {}) + + @property + def events(self) -> Sequence[Event]: + return tuple(self._events) + + @property + def links(self) -> Sequence[trace_api.Link]: + return tuple(self._links) + + @property + def resource(self) -> Resource: + return self._resource + + @property + @deprecated("You should use instrumentation_scope. Deprecated since version 1.11.1.") + def instrumentation_info(self) -> InstrumentationInfo | None: + return self._instrumentation_info + + @property + def instrumentation_scope(self) -> InstrumentationScope | None: + return self._instrumentation_scope + + def to_json(self, indent: int | None = 4): + parent_id = None + if self.parent is not None: + parent_id = f"0x{trace_api.format_span_id(self.parent.span_id)}" + + start_time = None + if self._start_time: + start_time = util.ns_to_iso_str(self._start_time) + + end_time = None + if self._end_time: + end_time = util.ns_to_iso_str(self._end_time) + + status = { + "status_code": str(self._status.status_code.name), + } + if self._status.description: + status["description"] = self._status.description + + f_span = { + "name": self._name, + "context": (self._format_context(self._context) if self._context else None), + "kind": str(self.kind), + "parent_id": parent_id, + "start_time": start_time, + "end_time": end_time, + "status": status, + "attributes": self._format_attributes(self._attributes), + "events": self._format_events(self._events), + "links": self._format_links(self._links), + "resource": json.loads(self.resource.to_json()), + } + + return json.dumps(f_span, indent=indent) + + @staticmethod + def _format_context(context: SpanContext) -> dict[str, str]: + return { + "trace_id": f"0x{trace_api.format_trace_id(context.trace_id)}", + "span_id": f"0x{trace_api.format_span_id(context.span_id)}", + "trace_state": repr(context.trace_state), + } + + @staticmethod + def _format_attributes( + attributes: types.Attributes, + ) -> dict[str, Any] | None: + if attributes is not None and not isinstance(attributes, dict): + return dict(attributes) + return attributes + + @staticmethod + def _format_events(events: Sequence[Event]) -> list[dict[str, Any]]: + return [ + { + "name": event.name, + "timestamp": util.ns_to_iso_str(event.timestamp), + "attributes": Span._format_attributes( # pylint: disable=protected-access + event.attributes + ), + } + for event in events + ] + + @staticmethod + def _format_links(links: Sequence[trace_api.Link]) -> list[dict[str, Any]]: + return [ + { + "context": Span._format_context( # pylint: disable=protected-access + link.context + ), + "attributes": Span._format_attributes( # pylint: disable=protected-access + link.attributes + ), + } + for link in links + ] + + +class SpanLimits: + """The limits that should be enforced on recorded data such as events, links, attributes etc. + + This class does not enforce any limits itself. It only provides a way to read limits from env, + default values and from user provided arguments. + + All limit arguments must be either a non-negative integer, ``None`` or ``SpanLimits.UNSET``. + + - All limit arguments are optional. + - If a limit argument is not set, the class will try to read its value from the corresponding + environment variable. + - If the environment variable is not set, the default value, if any, will be used. + + Limit precedence: + + - If a model specific limit is set, it will be used. + - Else if the corresponding global limit is set, it will be used. + - Else if the model specific limit has a default value, the default value will be used. + - Else if the global limit has a default value, the default value will be used. + + Args: + max_attributes: Maximum number of attributes that can be added to a span, event, and link. + Environment variable: OTEL_ATTRIBUTE_COUNT_LIMIT + Default: {_DEFAULT_ATTRIBUTE_COUNT_LIMIT} + max_events: Maximum number of events that can be added to a Span. + Environment variable: OTEL_SPAN_EVENT_COUNT_LIMIT + Default: {_DEFAULT_SPAN_EVENT_COUNT_LIMIT} + max_links: Maximum number of links that can be added to a Span. + Environment variable: OTEL_SPAN_LINK_COUNT_LIMIT + Default: {_DEFAULT_SPAN_LINK_COUNT_LIMIT} + max_span_attributes: Maximum number of attributes that can be added to a Span. + Environment variable: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT + Default: {_DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT} + max_event_attributes: Maximum number of attributes that can be added to an Event. + Default: {_DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT} + max_link_attributes: Maximum number of attributes that can be added to a Link. + Default: {_DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT} + max_attribute_length: Maximum length an attribute value can have. Values longer than + the specified length will be truncated. + max_span_attribute_length: Maximum length a span attribute value can have. Values longer than + the specified length will be truncated. + """ + + UNSET = -1 + + def __init__( + self, + max_attributes: int | None = None, + max_events: int | None = None, + max_links: int | None = None, + max_span_attributes: int | None = None, + max_event_attributes: int | None = None, + max_link_attributes: int | None = None, + max_attribute_length: int | None = None, + max_span_attribute_length: int | None = None, + ): + # span events and links count + self.max_events = self._from_env_if_absent( + max_events, + OTEL_SPAN_EVENT_COUNT_LIMIT, + _DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT, + ) + self.max_links = self._from_env_if_absent( + max_links, + OTEL_SPAN_LINK_COUNT_LIMIT, + _DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT, + ) + + # attribute count + global_max_attributes = self._from_env_if_absent(max_attributes, OTEL_ATTRIBUTE_COUNT_LIMIT) + self.max_attributes = ( + global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT + ) + + self.max_span_attributes = self._from_env_if_absent( + max_span_attributes, + OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, + (global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT), + ) + self.max_event_attributes = self._from_env_if_absent( + max_event_attributes, + OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, + (global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT), + ) + self.max_link_attributes = self._from_env_if_absent( + max_link_attributes, + OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, + (global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT), + ) + + # attribute length + self.max_attribute_length = self._from_env_if_absent( + max_attribute_length, + OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, + ) + self.max_span_attribute_length = self._from_env_if_absent( + max_span_attribute_length, + OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, + # use global attribute length limit as default + self.max_attribute_length, + ) + + def __repr__(self): + return f"{type(self).__name__}(max_span_attributes={self.max_span_attributes}, max_events_attributes={self.max_event_attributes}, max_link_attributes={self.max_link_attributes}, max_attributes={self.max_attributes}, max_events={self.max_events}, max_links={self.max_links}, max_attribute_length={self.max_attribute_length})" + + @classmethod + def _from_env_if_absent(cls, value: int | None, env_var: str, default: int | None = None) -> int | None: + if value == cls.UNSET: + return None + + err_msg = "{} must be a non-negative integer but got {}" + + # if no value is provided for the limit, try to load it from env + if value is None: + # return default value if env var is not set + if env_var not in environ: + return default + + str_value = environ.get(env_var, "").strip().lower() + if str_value == _ENV_VALUE_UNSET: + return None + + try: + value = int(str_value) + except ValueError: + raise ValueError(err_msg.format(env_var, str_value)) + + if value < 0: + raise ValueError(err_msg.format(env_var, value)) + return value + + +_UnsetLimits = SpanLimits( + max_attributes=SpanLimits.UNSET, + max_events=SpanLimits.UNSET, + max_links=SpanLimits.UNSET, + max_span_attributes=SpanLimits.UNSET, + max_event_attributes=SpanLimits.UNSET, + max_link_attributes=SpanLimits.UNSET, + max_attribute_length=SpanLimits.UNSET, + max_span_attribute_length=SpanLimits.UNSET, +) + +# not removed for backward compat. please use SpanLimits instead. +SPAN_ATTRIBUTE_COUNT_LIMIT = SpanLimits._from_env_if_absent( # pylint: disable=protected-access + None, + OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, + _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, +) + + +class Span(trace_api.Span, ReadableSpan): + """See `opentelemetry.trace.Span`. + + Users should create `Span` objects via the `Tracer` instead of this + constructor. + + Args: + name: The name of the operation this span represents + context: The immutable span context + parent: This span's parent's `opentelemetry.trace.SpanContext`, or + None if this is a root span + sampler: The sampler used to create this span + trace_config: Unused. Originally intended for trace-level configuration + from the OpenTelemetry protocol, but the upstream ``TraceConfig`` + proto was removed. Retained for backwards compatibility. + resource: Entity producing telemetry + attributes: The span's attributes to be exported + events: Timestamped events to be exported + links: Links to other spans to be exported + span_processor: `SpanProcessor` to invoke when starting and ending + this `Span`. + limits: `SpanLimits` instance that was passed to the `TracerProvider` + """ + + def __new__(cls, *args, **kwargs): + if cls is Span: + raise TypeError("Span must be instantiated via a tracer.") + return super().__new__(cls) + + # pylint: disable=too-many-locals + def __init__( + self, + name: str, + context: trace_api.SpanContext, + parent: trace_api.SpanContext | None = None, + sampler: sampling.Sampler | None = None, + trace_config: None = None, + resource: Resource | None = None, + attributes: types.Attributes = None, + events: Sequence[Event] | None = None, + links: Sequence[trace_api.Link] = (), + kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, + span_processor: SpanProcessor = SpanProcessor(), + instrumentation_info: InstrumentationInfo | None = None, + record_exception: bool = True, + set_status_on_exception: bool = True, + limits=_UnsetLimits, + instrumentation_scope: InstrumentationScope | None = None, + *, + record_end_metrics: Callable[[], None] | None = None, + ) -> None: + if resource is None: + resource = Resource.create({}) + super().__init__( + name=name, + context=context, + parent=parent, + kind=kind, + resource=resource, + instrumentation_info=instrumentation_info, + instrumentation_scope=instrumentation_scope, + ) + self._sampler = sampler + self._trace_config = trace_config + self._record_exception = record_exception + self._set_status_on_exception = set_status_on_exception + self._span_processor = span_processor + self._limits = limits + self._lock = threading.Lock() + self._attributes = BoundedAttributes( + self._limits.max_span_attributes, + attributes, + immutable=False, + max_value_len=self._limits.max_span_attribute_length, + ) + self._events = self._new_events() + if events: + for event in events: + # Immutable set to true so attributes cannot be added or removed after creation. + event._attributes = BoundedAttributes( + self._limits.max_event_attributes, + event.attributes, + max_value_len=self._limits.max_attribute_length, + immutable=True, + ) + self._events.append(event) + + self._links = self._new_links(links) + + self._record_end_metrics = record_end_metrics + + def __repr__(self): + return f'{type(self).__name__}(name="{self._name}", context={self._context})' + + def _new_events(self): + return BoundedList(self._limits.max_events) + + def _new_links(self, links: Sequence[trace_api.Link]): + if not links: + return BoundedList(self._limits.max_links) + + valid_links = [] + for link in links: + if link and _is_valid_link(link.context, link.attributes): + # Immutable set to true so attributes cannot be added or removed after creation. + # pylint: disable=protected-access + link._attributes = BoundedAttributes( + self._limits.max_link_attributes, + link.attributes, + max_value_len=self._limits.max_attribute_length, + immutable=True, + ) + valid_links.append(link) + + return BoundedList.from_seq(self._limits.max_links, valid_links) + + def get_span_context(self) -> trace_api.SpanContext: + return typing.cast(trace_api.SpanContext, self._context) + + def set_attributes(self, attributes: Mapping[str, types.AnyValue]) -> None: + with self._lock: + if self._end_time is not None: + logger.warning("Setting attribute on ended span.") + return + + self._attributes._set_items(attributes) # pylint: disable=protected-access + + def set_attribute(self, key: str, value: types.AnyValue) -> None: + with self._lock: + if self._end_time is not None: + logger.warning("Setting attribute on ended span.") + return + + self._attributes[key] = value + + @_check_span_ended + def _add_event(self, event: EventBase) -> None: + self._events.append(event) + + def add_event( + self, + name: str, + attributes: types.Attributes = None, + timestamp: int | None = None, + ) -> None: + # Immutable set to true so attributes cannot be added or removed after creation. + attributes = BoundedAttributes( + self._limits.max_event_attributes, + attributes, + max_value_len=self._limits.max_attribute_length, + immutable=True, + ) + self._add_event( + Event( + name=name, + attributes=attributes, + timestamp=timestamp, + ) + ) + + @_check_span_ended + def _add_link(self, link: trace_api.Link) -> None: + self._links.append(link) + + def add_link( + self, + context: SpanContext, + attributes: types.Attributes = None, + ) -> None: + if not _is_valid_link(context, attributes): + return + # Immutable set to true so attributes cannot be added or removed after creation. + attributes = BoundedAttributes( + self._limits.max_link_attributes, + attributes, + max_value_len=self._limits.max_attribute_length, + immutable=True, + ) + self._add_link( + trace_api.Link( + context=context, + attributes=attributes, + ) + ) + + def _readable_span(self) -> ReadableSpan: + return ReadableSpan( + name=self._name, + context=self._context, + parent=self._parent, + resource=self._resource, + attributes=self._attributes, + events=self._events, + links=self._links, + kind=self.kind, + status=self._status, + start_time=self._start_time, + end_time=self._end_time, + instrumentation_info=self._instrumentation_info, + instrumentation_scope=self._instrumentation_scope, + ) + + def start( + self, + start_time: int | None = None, + parent_context: context_api.Context | None = None, + ) -> None: + with self._lock: + if self._start_time is not None: + logger.warning("Calling start() on a started span.") + return + self._start_time = start_time if start_time is not None else time_ns() + + self._span_processor.on_start(self, parent_context=parent_context) + + def end(self, end_time: int | None = None) -> None: + with self._lock: + if self._start_time is None: + raise RuntimeError("Calling end() on a not started span.") + if self._end_time is not None: + logger.warning("Calling end() on an ended span.") + return + + self._end_time = end_time if end_time is not None else time_ns() + self._attributes._immutable = True # pylint: disable=protected-access + + if self._record_end_metrics: + self._record_end_metrics() + # pylint: disable=protected-access + self._span_processor._on_ending(self) + self._span_processor.on_end(self._readable_span()) + + @_check_span_ended + def update_name(self, name: str) -> None: + self._name = name + + def is_recording(self) -> bool: + return self._end_time is None + + @_check_span_ended + def set_status( + self, + status: Status | StatusCode, + description: str | None = None, + ) -> None: + # Ignore future calls if status is already set to OK + # Ignore calls to set to StatusCode.UNSET + if isinstance(status, Status): + if self._status and self._status.status_code is StatusCode.OK or status.status_code is StatusCode.UNSET: + return + if description is not None: + logger.warning( + "Description %s ignored. Use either `Status` or `(StatusCode, Description)`", + description, + ) + self._status = status + elif isinstance(status, StatusCode): + if self._status and self._status.status_code is StatusCode.OK or status is StatusCode.UNSET: + return + self._status = Status(status, description) + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + """Ends context manager and calls `end` on the `Span`.""" + if exc_val is not None and self.is_recording(): + # Record the exception as an event + # pylint:disable=protected-access + if self._record_exception: + self.record_exception(exception=exc_val, escaped=True) + # Records status if span is used as context manager + # i.e. with tracer.start_span() as span: + if self._set_status_on_exception: + self.set_status( + Status( + status_code=StatusCode.ERROR, + description=(f"{type(exc_val).__name__}: {exc_val}"), + ) + ) + + super().__exit__(exc_type, exc_val, exc_tb) + + def record_exception( + self, + exception: BaseException, + attributes: types.Attributes = None, + timestamp: int | None = None, + escaped: bool = False, + ) -> None: + """Records an exception as a span event.""" + stacktrace = "".join(traceback.format_exception(exception)) + module = type(exception).__module__ + qualname = type(exception).__qualname__ + exception_type = f"{module}.{qualname}" if module and module != "builtins" else qualname + _attributes: MutableMapping[str, types.AnyValue] = { + EXCEPTION_TYPE: exception_type, + EXCEPTION_MESSAGE: str(exception), + EXCEPTION_STACKTRACE: stacktrace, + EXCEPTION_ESCAPED: str(escaped), + } + if attributes: + _attributes.update(attributes) + self.add_event(name="exception", attributes=_attributes, timestamp=timestamp) + + +class _Span(Span): + """Protected implementation of `opentelemetry.trace.Span`. + + This constructor exists to prevent the instantiation of the `Span` class + by other mechanisms than through the `Tracer`. + """ + + +@dataclass +class _TracerConfig: + is_enabled: bool + + @classmethod + def default(cls): + return cls(is_enabled=True) + + +class Tracer(trace_api.Tracer): + """See `opentelemetry.trace.Tracer`.""" + + def __init__( + self, + sampler: sampling.Sampler, + resource: Resource, + span_processor: SynchronousMultiSpanProcessor | ConcurrentMultiSpanProcessor, + id_generator: IdGenerator, + instrumentation_info: InstrumentationInfo, + span_limits: SpanLimits, + instrumentation_scope: InstrumentationScope, + *, + meter_provider: metrics_api.MeterProvider | None = None, + _tracer_config: _TracerConfig | None = None, + ) -> None: + self.sampler = sampler + self.resource = resource + self.span_processor = span_processor + self.id_generator = id_generator + self.instrumentation_info = instrumentation_info + self._span_limits = span_limits + self._instrumentation_scope = instrumentation_scope + self._tracer_config = _tracer_config or _TracerConfig.default() + + meter_provider = meter_provider or metrics_api.get_meter_provider() + self._tracer_metrics = create_tracer_metrics( + meter_provider, + parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ) + + def _set_tracer_config(self, tracer_config: _TracerConfig): + self._tracer_config = tracer_config + + def _set_resource(self, resource: Resource) -> None: + self.resource = resource + + def _is_enabled(self) -> bool: + """If the tracer is not enabled, start_span will create a NonRecordingSpan""" + return self._tracer_config.is_enabled + + @_agnosticcontextmanager # pylint: disable=protected-access + def start_as_current_span( + self, + name: str, + context: context_api.Context | None = None, + kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, + attributes: types.Attributes = None, + links: Sequence[trace_api.Link] | None = (), + start_time: int | None = None, + record_exception: bool = True, + set_status_on_exception: bool = True, + end_on_exit: bool = True, + ) -> Iterator[trace_api.Span]: + span = self.start_span( + name=name, + context=context, + kind=kind, + attributes=attributes, + links=links, + start_time=start_time, + record_exception=record_exception, + set_status_on_exception=set_status_on_exception, + ) + with trace_api.use_span( + span, + end_on_exit=end_on_exit, + record_exception=record_exception, + set_status_on_exception=set_status_on_exception, + ) as span: + yield span + + def start_span( # pylint: disable=too-many-locals + self, + name: str, + context: context_api.Context | None = None, + kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, + attributes: types.Attributes = None, + links: Sequence[trace_api.Link] | None = (), + start_time: int | None = None, + record_exception: bool = True, + set_status_on_exception: bool = True, + ) -> trace_api.Span: + links = links or () + parent_span_context = trace_api.get_current_span(context).get_span_context() + + if parent_span_context is not None and not isinstance(parent_span_context, trace_api.SpanContext): + raise TypeError("parent_span_context must be a SpanContext or None.") + + if not self._is_enabled(): + return trace_api.NonRecordingSpan(context=parent_span_context) + + # is_valid determines root span + if parent_span_context is None or not parent_span_context.is_valid: + parent_span_context = None + trace_id = self.id_generator.generate_trace_id() + else: + trace_id = parent_span_context.trace_id + + # The sampler decides whether to create a real or no-op span at the + # time of span creation. No-op spans do not record events, and are not + # exported. + # The sampler may also add attributes to the newly-created span, e.g. + # to include information about the sampling result. + # The sampler may also modify the parent span context's tracestate + sampling_result = self.sampler.should_sample(context, trace_id, name, kind, attributes, links) + + trace_flags = ( + trace_api.TraceFlags(trace_api.TraceFlags.SAMPLED) + if sampling_result.decision.is_sampled() + else trace_api.TraceFlags(trace_api.TraceFlags.DEFAULT) + ) + + if parent_span_context is None: + random_trace_id = self.id_generator.is_trace_id_random() + else: + random_trace_id = parent_span_context.trace_flags.random_trace_id + + if random_trace_id: + trace_flags = trace_api.TraceFlags(trace_flags | trace_api.TraceFlags.RANDOM_TRACE_ID) + + span_context = trace_api.SpanContext( + trace_id, + self.id_generator.generate_span_id(), + is_remote=False, + trace_flags=trace_flags, + trace_state=sampling_result.trace_state, + ) + + record_end_metrics = self._tracer_metrics.start_span(parent_span_context, sampling_result.decision) + + # Only record if is_recording() is true + if sampling_result.decision.is_recording(): + # pylint:disable=protected-access + span = _Span( + name=name, + context=span_context, + parent=parent_span_context, + sampler=self.sampler, + resource=self.resource, + attributes=sampling_result.attributes, + span_processor=self.span_processor, + kind=kind, + links=links, + instrumentation_info=self.instrumentation_info, + record_exception=record_exception, + set_status_on_exception=set_status_on_exception, + limits=self._span_limits, + instrumentation_scope=self._instrumentation_scope, + record_end_metrics=record_end_metrics, + ) + span.start(start_time=start_time, parent_context=context) + else: + span = trace_api.NonRecordingSpan(context=span_context) + return span + + +_TracerConfiguratorT = Callable[[InstrumentationScope], _TracerConfig] +_RuleBasedTracerConfigurator = RuleBasedConfigurator[_TracerConfig] + + +def _default_tracer_configurator( + tracer_scope: InstrumentationScope, +) -> _TracerConfig: + """Default Tracer Configurator implementation + + In order to update Tracers configs you need to call + TracerProvider._set_tracer_configurator with a function + implementing this interface returning a Tracer Config.""" + return _RuleBasedTracerConfigurator( + rules=[], + default_config=_TracerConfig.default(), + )(tracer_scope) + + +def _disable_tracer_configurator( + tracer_scope: InstrumentationScope, +) -> _TracerConfig: + return _RuleBasedTracerConfigurator( + rules=[], + default_config=_TracerConfig(is_enabled=False), + )(tracer_scope) + + +class TracerProvider(trace_api.TracerProvider): + """See `opentelemetry.trace.TracerProvider`.""" + + def __init__( + self, + sampler: sampling.Sampler | None = None, + resource: Resource | None = None, + shutdown_on_exit: bool = True, + active_span_processor: SynchronousMultiSpanProcessor | ConcurrentMultiSpanProcessor | None = None, + id_generator: IdGenerator | None = None, + span_limits: SpanLimits | None = None, + *, + meter_provider: metrics_api.MeterProvider | None = None, + _tracer_configurator: _TracerConfiguratorT | None = None, + ) -> None: + self._active_span_processor = active_span_processor or SynchronousMultiSpanProcessor() + if id_generator is None: + self.id_generator = RandomIdGenerator() + else: + self.id_generator = id_generator + if resource is None: + self._resource = Resource.create({}) + else: + self._resource = resource + if not sampler: + sampler = sampling._get_from_env_or_default() + self.sampler = sampler + self._span_limits = span_limits or SpanLimits() + disabled = environ.get(OTEL_SDK_DISABLED, "") + self._disabled = disabled.lower().strip() == "true" + self._atexit_handler = None + self._meter_provider = meter_provider + + if shutdown_on_exit: + self._atexit_handler = atexit.register(self.shutdown) + + self._tracer_configurator = _tracer_configurator or _default_tracer_configurator + self._tracers_lock = threading.Lock() + self._tracers: dict[InstrumentationScope, Tracer] = {} + if hasattr(os, "register_at_fork"): + weak_at_fork = weakref.WeakMethod(self._handle_fork) + + def _after_in_child() -> None: + if at_fork := weak_at_fork(): + at_fork() + + os.register_at_fork(after_in_child=_after_in_child) + + def _handle_fork(self) -> None: + self._tracers_lock = threading.Lock() + self._update_resource(_get_process_dependent_resource()) + + def _set_tracer_configurator(self, *, tracer_configurator: _TracerConfiguratorT): + """This is the function used to update the TracerProvider TracerConfigurator + + Setting a new TracerConfigurator for a TracerProvider will update the + TracerConfig of all Tracers create by this TracerProvider. + """ + self._tracer_configurator = tracer_configurator + with self._tracers_lock: + for instrumentation_scope, tracer in self._tracers.items(): + tracer_config = self._apply_tracer_configurator(instrumentation_scope) + # pylint: disable-next=protected-access + tracer._set_tracer_config(tracer_config) + + @property + def resource(self) -> Resource: + return self._resource + + def _update_resource(self, resource: Resource) -> None: + with self._tracers_lock: + self._resource = self._resource.merge(resource) + for tracer in self._tracers.values(): + tracer._set_resource(self._resource) # pylint: disable=protected-access + + def _apply_tracer_configurator(self, instrumentation_scope: InstrumentationScope): + try: + return self._tracer_configurator(instrumentation_scope) + except Exception: # pylint: disable=broad-exception-caught + logger.exception( + "Failed to create a Tracer Config for %s, using default Tracer config", + instrumentation_scope, + ) + return _TracerConfig.default() + + def get_tracer( + self, + instrumenting_module_name: str, + instrumenting_library_version: str | None = None, + schema_url: str | None = None, + attributes: types.Attributes = None, + ) -> "trace_api.Tracer": + if self._disabled: + return NoOpTracer() + if not instrumenting_module_name: # Reject empty strings too. + instrumenting_module_name = "" + logger.error("get_tracer called with missing module name.") + if instrumenting_library_version is None: + instrumenting_library_version = "" + + filterwarnings( + "ignore", + message=(r"You should use InstrumentationScope. Deprecated since version 1.11.1."), + category=DeprecationWarning, + # opentelemetry-agent: match this (vendored) module, not the application's SDK. + module=__name__, + ) + + instrumentation_info = InstrumentationInfo( + instrumenting_module_name, + instrumenting_library_version, + schema_url, + ) + + instrumentation_scope = InstrumentationScope( + instrumenting_module_name, + instrumenting_library_version, + schema_url, + attributes, + ) + + with self._tracers_lock: + if instrumentation_scope in self._tracers: + return self._tracers[instrumentation_scope] + + tracer_config = self._apply_tracer_configurator(instrumentation_scope) + tracer = Tracer( + self.sampler, + self.resource, + self._active_span_processor, + self.id_generator, + instrumentation_info, + self._span_limits, + instrumentation_scope, + meter_provider=self._meter_provider, + _tracer_config=tracer_config, + ) + self._tracers[instrumentation_scope] = tracer + + return tracer + + def add_span_processor(self, span_processor: SpanProcessor) -> None: + """Registers a new :class:`SpanProcessor` for this `TracerProvider`. + + The span processors are invoked in the same order they are registered. + """ + + # no lock here because add_span_processor is thread safe for both + # SynchronousMultiSpanProcessor and ConcurrentMultiSpanProcessor. + self._active_span_processor.add_span_processor(span_processor) + + def shutdown(self) -> None: + """Shut down the span processors added to the tracer provider.""" + self._active_span_processor.shutdown() + if self._atexit_handler is not None: + atexit.unregister(self._atexit_handler) + self._atexit_handler = None + + def force_flush(self, timeout_millis: int = 30000) -> bool: + """Requests the active span processor to process all spans that have not + yet been processed. + + By default force flush is called sequentially on all added span + processors. This means that span processors further back in the list + have less time to flush their spans. + To have span processors flush their spans in parallel it is possible to + initialize the tracer provider with an instance of + `ConcurrentMultiSpanProcessor` at the cost of using multiple threads. + + Args: + timeout_millis: The maximum amount of time to wait for spans to be + processed. + + Returns: + False if the timeout is exceeded, True otherwise. + """ + return self._active_span_processor.force_flush(timeout_millis) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py new file mode 100644 index 00000000000..e838448490a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py @@ -0,0 +1,22 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__all__ = [ + "ComposableSampler", + "SamplingIntent", + "composable_always_off", + "composable_always_on", + "composable_parent_threshold", + "composable_rule_based", + "composable_traceid_ratio_based", + "composite_sampler", +] + + +from ._always_off import composable_always_off +from ._always_on import composable_always_on +from ._composable import ComposableSampler, SamplingIntent +from ._parent_threshold import composable_parent_threshold +from ._rule_based import composable_rule_based +from ._sampler import composite_sampler +from ._traceid_ratio import composable_traceid_ratio_based diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py new file mode 100644 index 00000000000..ab144f65f21 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py @@ -0,0 +1,44 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Sequence + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +from ._composable import ComposableSampler, SamplingIntent +from ._util import INVALID_THRESHOLD + +_intent = SamplingIntent(threshold=INVALID_THRESHOLD, threshold_reliable=False) + + +class _ComposableAlwaysOffSampler(ComposableSampler): + def sampling_intent( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None = None, + ) -> SamplingIntent: + return _intent + + def get_description(self) -> str: + return "ComposableAlwaysOff" + + +_always_off = _ComposableAlwaysOffSampler() + + +def composable_always_off() -> ComposableSampler: + """Returns a composable sampler that does not sample any span. + + - Always returns a SamplingIntent with no threshold, indicating all spans should be dropped + - Sets threshold_reliable to false + - Does not add any attributes + """ + return _always_off diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py new file mode 100644 index 00000000000..bd191817df4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py @@ -0,0 +1,44 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Sequence + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +from ._composable import ComposableSampler, SamplingIntent +from ._util import MIN_THRESHOLD + +_intent = SamplingIntent(threshold=MIN_THRESHOLD) + + +class _ComposableAlwaysOnSampler(ComposableSampler): + def sampling_intent( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None = None, + ) -> SamplingIntent: + return _intent + + def get_description(self) -> str: + return "ComposableAlwaysOn" + + +_always_on = _ComposableAlwaysOnSampler() + + +def composable_always_on() -> ComposableSampler: + """Returns a composable sampler that samples all spans. + + - Always returns a SamplingIntent with threshold set to sample all spans (threshold = 0) + - Sets threshold_reliable to true + - Does not add any attributes + """ + return _always_on diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py new file mode 100644 index 00000000000..d6712fe3744 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py @@ -0,0 +1,49 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Callable, Sequence +from dataclasses import dataclass, field +from typing import Protocol + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + + +@dataclass(frozen=True) +class SamplingIntent: + """Information to make a consistent sampling decision.""" + + threshold: int + """The sampling threshold value. A lower threshold increases the likelihood of sampling.""" + + threshold_reliable: bool = field(default=True) + """Indicates whether the threshold is reliable for Span-to-Metrics estimation.""" + + attributes: Attributes = field(default=None) + """Any attributes to be added to a sampled span.""" + + update_trace_state: Callable[[TraceState], TraceState] = field(default=lambda ts: ts) + """Any updates to be made to trace state.""" + + +class ComposableSampler(Protocol): + """A sampler that can be composed to make a final sampling decision.""" + + def sampling_intent( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> SamplingIntent: + """Returns information to make a sampling decision.""" + ... # pylint: disable=unnecessary-ellipsis + + def get_description(self) -> str: + """Returns a description of the sampler.""" + ... # pylint: disable=unnecessary-ellipsis diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py new file mode 100644 index 00000000000..456605af8a7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py @@ -0,0 +1,72 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Sequence + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState, get_current_span +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +from ._composable import ComposableSampler, SamplingIntent +from ._trace_state import OtelTraceState +from ._util import ( + INVALID_THRESHOLD, + MIN_THRESHOLD, + is_valid_threshold, +) + + +class _ComposableParentThreshold(ComposableSampler): + def __init__(self, root_sampler: ComposableSampler): + self._root_sampler = root_sampler + self._description = f"ComposableParentThreshold{{root={root_sampler.get_description()}}}" + + def sampling_intent( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None = None, + ) -> SamplingIntent: + parent_span = get_current_span(parent_ctx) + parent_span_ctx = parent_span.get_span_context() + is_root = not parent_span_ctx.is_valid + if is_root: + return self._root_sampler.sampling_intent(parent_ctx, name, span_kind, attributes, links, trace_state) + + ot_trace_state = OtelTraceState.parse(trace_state) + + if is_valid_threshold(ot_trace_state.threshold): + return SamplingIntent( + threshold=ot_trace_state.threshold, + threshold_reliable=True, + ) + + threshold = MIN_THRESHOLD if parent_span_ctx.trace_flags.sampled else INVALID_THRESHOLD + return SamplingIntent(threshold=threshold, threshold_reliable=False) + + def get_description(self) -> str: + return self._description + + +def composable_parent_threshold( + root_sampler: ComposableSampler, +) -> ComposableSampler: + """Returns a consistent sampler that respects the sampling decision of + the parent span or falls-back to the given sampler if it is a root span. + + - For spans without a parent context, delegate to the root sampler + - For spans with a parent context, returns a SamplingIntent that propagates the parent's sampling decision + - Returns the parent's threshold if available; otherwise, if the parent's sampled flag is set, + returns threshold=0; otherwise, if the parent's sampled flag is not set, no threshold is returned. + - Sets threshold_reliable to match the parent’s reliability, which is true if the parent had a threshold. + - Does not add any attributes + + Args: + root_sampler: The root sampler to use for spans without a parent context. + """ + return _ComposableParentThreshold(root_sampler) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py new file mode 100644 index 00000000000..6c45082bf08 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py @@ -0,0 +1,271 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import logging +from collections.abc import Sequence +from fnmatch import fnmatchcase +from typing import Protocol + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace import ( + Link, + SpanKind, + TraceState, + get_current_span, +) +from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes + +from ._composable import ComposableSampler, SamplingIntent +from ._util import INVALID_THRESHOLD + + +class PredicateT(Protocol): + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: ... + + def __str__(self) -> str: ... + + +class AttributePredicate: + """An exact match of an attribute value""" + + def __init__(self, key: str, value: AnyValue): + logging.warning("This is deprecated, use AttributeValuesPredicate instead") + self.key = key + self.value = value + + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: + if not attributes: + return False + return attributes.get(self.key) == self.value + + def __str__(self): + return f"{self.key}={self.value}" + + +class AlwaysMatchPredicate: + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: + return True + + def __str__(self) -> str: + return "AlwaysMatch" + + +class AllPredicate: + def __init__(self, predicates: Sequence[PredicateT]): + self._predicates = tuple(predicates) + + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: + return all( + predicate( + parent_ctx, + name, + span_kind, + attributes, + links, + trace_state, + ) + for predicate in self._predicates + ) + + def __str__(self) -> str: + return " && ".join(str(predicate) for predicate in self._predicates) + + +class AttributeValuesPredicate: + def __init__(self, key: str, values: Sequence[str]): + self._key = key + self._values = frozenset(values) + + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: + if not attributes or self._key not in attributes: + return False + return any(str(value) in self._values for value in _attribute_values(attributes[self._key])) + + def __str__(self) -> str: + values = ",".join(sorted(self._values)) + return f"{self._key} in [{values}]" + + +class AttributePatternsPredicate: + def __init__( + self, + key: str, + included: Sequence[str] | None = None, + excluded: Sequence[str] | None = None, + ): + self._key = key + self._included = tuple(included or ()) + self._excluded = tuple(excluded or ()) + + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: + if not attributes or self._key not in attributes: + return False + return any(self._matches_value(str(value)) for value in _attribute_values(attributes[self._key])) + + def _matches_value(self, value: str) -> bool: + included = not self._included or any(fnmatchcase(value, pattern) for pattern in self._included) + excluded = any(fnmatchcase(value, pattern) for pattern in self._excluded) + return included and not excluded + + def __str__(self) -> str: + return f"{self._key} matches" + + +class SpanKindPredicate: + def __init__(self, span_kinds: Sequence[SpanKind]): + self._span_kinds = frozenset(span_kinds) + + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: + return span_kind in self._span_kinds + + def __str__(self) -> str: + kinds = ",".join(kind.name.lower() for kind in self._span_kinds) + return f"span_kind in [{kinds}]" + + +class ParentPredicate: + def __init__(self, parents: Sequence[str]): + self._parents = frozenset(parents) + + def __call__( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> bool: + parent_span_context = get_current_span(parent_ctx).get_span_context() + if not parent_span_context.is_valid: + parent = "none" + elif parent_span_context.is_remote: + parent = "remote" + else: + parent = "local" + return parent in self._parents + + def __str__(self) -> str: + parents = ",".join(self._parents) + return f"parent in [{parents}]" + + +def _attribute_values(value): + if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)): + return value + return (value,) + + +RulesT = Sequence[tuple[PredicateT, ComposableSampler]] + +_non_sampling_intent = SamplingIntent(threshold=INVALID_THRESHOLD, threshold_reliable=False) + + +class _ComposableRuleBased(ComposableSampler): + def __init__(self, rules: RulesT): + # work on an internal copy of the rules + self._rules = list(rules) + + def sampling_intent( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None = None, + ) -> SamplingIntent: + for predicate, sampler in self._rules: + if predicate( + parent_ctx=parent_ctx, + name=name, + span_kind=span_kind, + attributes=attributes, + links=links, + trace_state=trace_state, + ): + return sampler.sampling_intent( + parent_ctx=parent_ctx, + name=name, + span_kind=span_kind, + attributes=attributes, + links=links, + trace_state=trace_state, + ) + return _non_sampling_intent + + def get_description(self) -> str: + rules_str = ",".join(f"({predicate}:{sampler.get_description()})" for predicate, sampler in self._rules) + return f"ComposableRuleBased{{[{rules_str}]}}" + + +def composable_rule_based( + rules: RulesT, +) -> ComposableSampler: + """Returns a consistent sampler that: + + - Evaluates a series of rules based on predicates and returns the SamplingIntent from the first matching sampler + - If no rules match, returns a non-sampling intent + + Args: + rules: A list of (Predicate, ComposableSampler) pairs, where Predicate is a function that evaluates whether a rule applies + """ + return _ComposableRuleBased(rules) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py new file mode 100644 index 00000000000..17bd9f96b3e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py @@ -0,0 +1,88 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Sequence + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import Decision, Sampler, SamplingResult +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +from ._composable import ComposableSampler, SamplingIntent +from ._trace_state import OTEL_TRACE_STATE_KEY, OtelTraceState +from ._util import INVALID_THRESHOLD, is_valid_random_value, is_valid_threshold + + +class _CompositeSampler(Sampler): + def __init__(self, delegate: ComposableSampler): + self._delegate = delegate + + def should_sample( + self, + parent_context: Context | None, + trace_id: int, + name: str, + kind: SpanKind | None = None, + attributes: Attributes = None, + links: Sequence[Link] | None = None, + trace_state: TraceState | None = None, + ) -> SamplingResult: + ot_trace_state = OtelTraceState.parse(trace_state) + + intent = self._delegate.sampling_intent(parent_context, name, kind, attributes, links, trace_state) + threshold = intent.threshold + + if is_valid_threshold(threshold): + adjusted_count_correct = intent.threshold_reliable + if is_valid_random_value(ot_trace_state.random_value): + randomness = ot_trace_state.random_value + else: + # Use last 56 bits of trace_id as randomness + randomness = trace_id & 0x00FFFFFFFFFFFFFF + sampled = threshold <= randomness + else: + sampled = False + adjusted_count_correct = False + + decision = Decision.RECORD_AND_SAMPLE if sampled else Decision.DROP + if sampled and adjusted_count_correct: + ot_trace_state.threshold = threshold + else: + ot_trace_state.threshold = INVALID_THRESHOLD + + return SamplingResult( + decision, + intent.attributes, + _update_trace_state(trace_state, ot_trace_state, intent), + ) + + def get_description(self) -> str: + return self._delegate.get_description() + + +def _update_trace_state( + trace_state: TraceState | None, + ot_trace_state: OtelTraceState, + intent: SamplingIntent, +) -> TraceState | None: + otts = ot_trace_state.serialize() + if not trace_state: + if otts: + return TraceState(((OTEL_TRACE_STATE_KEY, otts),)) + return None + new_trace_state = intent.update_trace_state(trace_state) + if otts: + return new_trace_state.update(OTEL_TRACE_STATE_KEY, otts) + return new_trace_state + + +def composite_sampler(delegate: ComposableSampler) -> Sampler: + """A sampler that uses a a composable sampler to make its decision while + handling tracestate. + + Args: + delegate: The composable sampler to use for making sampling decisions. + """ + return _CompositeSampler(delegate) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py new file mode 100644 index 00000000000..d58bc7c4bb1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py @@ -0,0 +1,121 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Sequence +from dataclasses import dataclass + +from opentelemetry.agent._vendor.opentelemetry.trace import TraceState + +from ._util import ( + INVALID_RANDOM_VALUE, + INVALID_THRESHOLD, + MAX_THRESHOLD, + is_valid_random_value, + is_valid_threshold, +) + +OTEL_TRACE_STATE_KEY = "ot" + +_TRACE_STATE_SIZE_LIMIT = 256 +_MAX_VALUE_LENGTH = 14 # 56 bits, 4 bits per hex digit + + +@dataclass +class OtelTraceState: + """Marshals OpenTelemetry tracestate for sampling parameters. + + https://opentelemetry.io/docs/specs/otel/trace/tracestate-probability-sampling/ + """ + + random_value: int + threshold: int + rest: Sequence[str] + + @staticmethod + def invalid() -> OtelTraceState: + return OtelTraceState(INVALID_RANDOM_VALUE, INVALID_THRESHOLD, ()) + + @staticmethod + def parse(trace_state: TraceState | None) -> OtelTraceState: + if not trace_state: + return OtelTraceState.invalid() + + ot = trace_state.get(OTEL_TRACE_STATE_KEY, "") + + if not ot or len(ot) > _TRACE_STATE_SIZE_LIMIT: + return OtelTraceState.invalid() + + threshold = INVALID_THRESHOLD + random_value = INVALID_RANDOM_VALUE + + members = ot.split(";") + rest: list[str] | None = None + for member in members: + if member.startswith("th:"): + threshold = _parse_th(member[len("th:") :], INVALID_THRESHOLD) + continue + if member.startswith("rv:"): + random_value = _parse_rv(member[len("rv:") :], INVALID_RANDOM_VALUE) + continue + if rest is None: + rest = [member] + else: + rest.append(member) + + return OtelTraceState(random_value=random_value, threshold=threshold, rest=rest or ()) + + def serialize(self) -> str: + if not is_valid_threshold(self.threshold) and not is_valid_random_value(self.random_value) and not self.rest: + return "" + + parts: list[str] = [] + if is_valid_threshold(self.threshold) and self.threshold != MAX_THRESHOLD: + parts.append(f"th:{serialize_th(self.threshold)}") + if is_valid_random_value(self.random_value): + parts.append(f"rv:{_serialize_rv(self.random_value)}") + if self.rest: + parts.extend(self.rest) + res = ";".join(parts) + while len(res) > _TRACE_STATE_SIZE_LIMIT: + delim_idx = res.rfind(";") + if delim_idx == -1: + break + res = res[:delim_idx] + return res + + +def _parse_th(value: str, default: int) -> int: + if not value or len(value) > _MAX_VALUE_LENGTH: + return default + + try: + parsed = int(value, 16) + except ValueError: + return default + + # th value is compressed by removing all trailing zeros, + # so we restore them to get the real value. + trailing_zeros = _MAX_VALUE_LENGTH - len(value) + return parsed << (trailing_zeros * 4) + + +def _parse_rv(value: str, default: int) -> int: + if not value or len(value) != _MAX_VALUE_LENGTH: + return default + + try: + return int(value, 16) + except ValueError: + return default + + +def serialize_th(threshold: int) -> str: + if not threshold: + return "0" + return f"{threshold:014x}".rstrip("0") + + +def _serialize_rv(random_value: int) -> str: + return f"{random_value:014x}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py new file mode 100644 index 00000000000..fb1cc40b71f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py @@ -0,0 +1,67 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Sequence + +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +from ._composable import ComposableSampler, SamplingIntent +from ._trace_state import serialize_th +from ._util import INVALID_THRESHOLD, MAX_THRESHOLD, calculate_threshold + + +class ComposableTraceIDRatioBased(ComposableSampler): + _threshold: int + _description: str + + def __init__(self, ratio: float): + threshold = calculate_threshold(ratio) + if threshold == MAX_THRESHOLD: + threshold_str = "max" + else: + threshold_str = serialize_th(threshold) + if threshold != MAX_THRESHOLD: + intent = SamplingIntent(threshold=threshold) + else: + intent = SamplingIntent(threshold=INVALID_THRESHOLD, threshold_reliable=False) + self._intent = intent + self._description = f"ComposableTraceIDRatioBased{{threshold={threshold_str}, ratio={ratio}}}" + + def sampling_intent( + self, + parent_ctx: Context | None, + name: str, + span_kind: SpanKind | None, + attributes: Attributes, + links: Sequence[Link] | None, + trace_state: TraceState | None, + ) -> SamplingIntent: + return self._intent + + def get_description(self) -> str: + return self._description + + +def composable_traceid_ratio_based( + ratio: float, +) -> ComposableSampler: + """Returns a composable sampler that samples each span with a fixed ratio. + + - Returns a SamplingIntent with threshold determined by the configured sampling ratio + - Sets threshold_reliable to true + - Does not add any attributes + + Note: + If the ratio is 0, it will behave as an ComposableAlwaysOff sampler instead. + + Args: + ratio: The sampling ratio to use (between 0.0 and 1.0). + """ + if not 0.0 <= ratio <= 1.0: + raise ValueError("Sampling ratio must be between 0.0 and 1.0") + + return ComposableTraceIDRatioBased(ratio) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py new file mode 100644 index 00000000000..dc8c10ae40b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py @@ -0,0 +1,23 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +RANDOM_VALUE_BITS = 56 +MAX_THRESHOLD = 1 << RANDOM_VALUE_BITS # 0% sampling +MIN_THRESHOLD = 0 # 100% sampling +MAX_RANDOM_VALUE = MAX_THRESHOLD - 1 +INVALID_THRESHOLD = -1 +INVALID_RANDOM_VALUE = -1 + +_probability_threshold_scale = float.fromhex("0x1p56") + + +def calculate_threshold(sampling_probability: float) -> int: + return MAX_THRESHOLD - round(sampling_probability * _probability_threshold_scale) + + +def is_valid_threshold(threshold: int) -> bool: + return MIN_THRESHOLD <= threshold <= MAX_THRESHOLD + + +def is_valid_random_value(random_value: int) -> bool: + return 0 <= random_value <= MAX_RANDOM_VALUE diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py new file mode 100644 index 00000000000..852a97f84e5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py @@ -0,0 +1,103 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Callable +from typing import Protocol + +from opentelemetry.agent._vendor.opentelemetry import metrics as metrics_api +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import Decision +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OTEL_SPAN_PARENT_ORIGIN, + OTEL_SPAN_SAMPLING_RESULT, + OtelSpanSamplingResultValues, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( + create_otel_sdk_span_live, + create_otel_sdk_span_started, +) +from opentelemetry.agent._vendor.opentelemetry.trace.span import SpanContext + + +class TracerMetricsT(Protocol): + def start_span( + self, + parent_span_context: SpanContext | None, + sampling_decision: Decision, + ) -> Callable[[], None]: ... + + +# pylint: disable=no-self-use +class NoOpTracerMetrics: + def start_span( + self, + parent_span_context: SpanContext | None, + sampling_decision: Decision, + ) -> Callable[[], None]: + return noop + + +class TracerMetrics: + def __init__(self, meter_provider: metrics_api.MeterProvider) -> None: + meter = meter_provider.get_meter("opentelemetry-sdk") + + self._started_spans = create_otel_sdk_span_started(meter) + self._live_spans = create_otel_sdk_span_live(meter) + + def start_span( + self, + parent_span_context: SpanContext | None, + sampling_decision: Decision, + ) -> Callable[[], None]: + sampling_result_value = sampling_result(sampling_decision) + self._started_spans.add( + 1, + { + OTEL_SPAN_PARENT_ORIGIN: parent_origin(parent_span_context), + OTEL_SPAN_SAMPLING_RESULT: sampling_result_value, + }, + ) + + if not sampling_decision.is_recording(): + return noop + + live_span_attrs = { + OTEL_SPAN_SAMPLING_RESULT: sampling_result_value, + } + self._live_spans.add(1, live_span_attrs) + + def end_span() -> None: + self._live_spans.add(-1, live_span_attrs) + + return end_span + + +def create_tracer_metrics( + meter_provider: metrics_api.MeterProvider, + enabled: bool, +) -> TracerMetricsT: + if not enabled: + return NoOpTracerMetrics() + + return TracerMetrics(meter_provider) + + +def noop() -> None: + pass + + +def parent_origin(span_ctx: SpanContext | None) -> str: + if span_ctx is None: + return "none" + if span_ctx.is_remote: + return "remote" + return "local" + + +def sampling_result(decision: Decision) -> str: + if decision == Decision.RECORD_AND_SAMPLE: + return OtelSpanSamplingResultValues.RECORD_AND_SAMPLE.value + if decision == Decision.RECORD_ONLY: + return OtelSpanSamplingResultValues.RECORD_ONLY.value + return OtelSpanSamplingResultValues.DROP.value diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py new file mode 100644 index 00000000000..d0eed223e5f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py @@ -0,0 +1,316 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from __future__ import annotations + +import collections.abc +import logging +import sys +import typing +from enum import Enum +from os import environ, linesep + +from opentelemetry.agent._vendor.opentelemetry.context import ( + _SUPPRESS_INSTRUMENTATION_KEY, + Context, + attach, + detach, + set_value, +) +from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import ( + BatchProcessor, +) +from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal._processor_metrics import ( + create_processor_metrics, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_BSP_EXPORT_TIMEOUT, + OTEL_BSP_MAX_EXPORT_BATCH_SIZE, + OTEL_BSP_MAX_QUEUE_SIZE, + OTEL_BSP_SCHEDULE_DELAY, + OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( + parse_boolean_environment_variable, +) +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( + OtelComponentTypeValues, +) + +_DEFAULT_SCHEDULE_DELAY_MILLIS = 5000 +_DEFAULT_MAX_EXPORT_BATCH_SIZE = 512 +_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 +_DEFAULT_MAX_QUEUE_SIZE = 2048 +_ENV_VAR_INT_VALUE_ERROR_MESSAGE = "Unable to parse value for %s as integer. Defaulting to %s." + +logger = logging.getLogger(__name__) + + +class SpanExportResult(Enum): + SUCCESS = 0 + FAILURE = 1 + + +class SpanExporter: + """Interface for exporting spans. + + Interface to be implemented by services that want to export spans recorded + in their own format. + + To export data this MUST be registered to the :class`opentelemetry.sdk.trace.Tracer` using a + `SimpleSpanProcessor` or a `BatchSpanProcessor`. + """ + + def export(self, spans: collections.abc.Sequence[ReadableSpan]) -> SpanExportResult: # pyright: ignore[reportReturnType] + """Exports a batch of telemetry data. + + Args: + spans: The list of `opentelemetry.trace.Span` objects to be exported + + Returns: + The result of the export + """ + + def shutdown(self) -> None: + """Shuts down the exporter. + + Called when the SDK is shut down. + """ + + def force_flush(self, timeout_millis: int = 30000) -> bool: # pyright: ignore[reportReturnType] + """Hint to ensure that the export of any spans the exporter has received + prior to the call to ForceFlush SHOULD be completed as soon as possible, preferably + before returning from this method. + """ + + +class SimpleSpanProcessor(SpanProcessor): + """Simple SpanProcessor implementation. + + SimpleSpanProcessor is an implementation of `SpanProcessor` that + passes ended spans directly to the configured `SpanExporter`. + """ + + def __init__( + self, + span_exporter: SpanExporter, + *, + meter_provider: MeterProvider | None = None, + ): + self.span_exporter = span_exporter + self._shutdown = False + self._metrics = create_processor_metrics( + "traces", + OtelComponentTypeValues.SIMPLE_SPAN_PROCESSOR, + meter_provider or get_meter_provider(), + enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ) + + def on_start(self, span: Span, parent_context: Context | None = None) -> None: + pass + + def _on_ending(self, span: Span) -> None: + pass + + def on_end(self, span: ReadableSpan) -> None: + if not (span.context and span.context.trace_flags.sampled): + return + if self._shutdown: + logger.warning("Processor is already shutdown, ignoring call") + self._metrics.drop_items(1, "already_shutdown") + return + token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) + # Record on submission to the exporter. + self._metrics.finish_items(1) + try: + self.span_exporter.export((span,)) + # pylint: disable=broad-exception-caught + except Exception: + logger.exception("Exception while exporting Span.") + finally: + detach(token) + + def shutdown(self) -> None: + self._shutdown = True + self.span_exporter.shutdown() + + def force_flush(self, timeout_millis: int = 30000) -> bool: + # pylint: disable=unused-argument + return True + + +class BatchSpanProcessor(SpanProcessor): + """Batch span processor implementation. + + `BatchSpanProcessor` is an implementation of `SpanProcessor` that + batches ended spans and pushes them to the configured `SpanExporter`. + + `BatchSpanProcessor` is configurable with the following environment + variables which correspond to constructor parameters: + + - :envvar:`OTEL_BSP_SCHEDULE_DELAY` + - :envvar:`OTEL_BSP_MAX_QUEUE_SIZE` + - :envvar:`OTEL_BSP_MAX_EXPORT_BATCH_SIZE` + - :envvar:`OTEL_BSP_EXPORT_TIMEOUT` + + All the logic for emitting spans, shutting down etc. resides in the `BatchProcessor` class. + """ + + def __init__( + self, + span_exporter: SpanExporter, + max_queue_size: int | None = None, + schedule_delay_millis: float | None = None, + max_export_batch_size: int | None = None, + export_timeout_millis: float | None = None, + *, + meter_provider: MeterProvider | None = None, + ): + if max_queue_size is None: + max_queue_size = BatchSpanProcessor._default_max_queue_size() + + if schedule_delay_millis is None: + schedule_delay_millis = BatchSpanProcessor._default_schedule_delay_millis() + + if max_export_batch_size is None: + max_export_batch_size = BatchSpanProcessor._default_max_export_batch_size() + + # Not used. No way currently to pass timeout to export. + if export_timeout_millis is None: + export_timeout_millis = BatchSpanProcessor._default_export_timeout_millis() + + BatchSpanProcessor._validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size) + + self._batch_processor = BatchProcessor( + span_exporter, + schedule_delay_millis, + max_export_batch_size, + export_timeout_millis, + max_queue_size, + "Span", + create_processor_metrics( + "traces", + OtelComponentTypeValues.BATCHING_SPAN_PROCESSOR, + meter_provider or get_meter_provider(), + capacity=max_queue_size, + enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), + ), + ) + + # Added for backward compatibility. Not recommended to directly access/use underlying exporter. + @property + def span_exporter(self): + return self._batch_processor._exporter # pylint: disable=protected-access + + def on_start(self, span: Span, parent_context: Context | None = None) -> None: + pass + + def _on_ending(self, span: Span) -> None: + pass + + def on_end(self, span: ReadableSpan) -> None: + if not (span.context and span.context.trace_flags.sampled): + return + self._batch_processor.emit(span) + + def shutdown(self): + return self._batch_processor.shutdown() + + def force_flush(self, timeout_millis: int | None = None) -> bool: + return self._batch_processor.force_flush(timeout_millis) + + @staticmethod + def _default_max_queue_size(): + try: + return int(environ.get(OTEL_BSP_MAX_QUEUE_SIZE, _DEFAULT_MAX_QUEUE_SIZE)) + except ValueError: + logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BSP_MAX_QUEUE_SIZE, + _DEFAULT_MAX_QUEUE_SIZE, + ) + return _DEFAULT_MAX_QUEUE_SIZE + + @staticmethod + def _default_schedule_delay_millis(): + try: + return int(environ.get(OTEL_BSP_SCHEDULE_DELAY, _DEFAULT_SCHEDULE_DELAY_MILLIS)) + except ValueError: + logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BSP_SCHEDULE_DELAY, + _DEFAULT_SCHEDULE_DELAY_MILLIS, + ) + return _DEFAULT_SCHEDULE_DELAY_MILLIS + + @staticmethod + def _default_max_export_batch_size(): + try: + return int( + environ.get( + OTEL_BSP_MAX_EXPORT_BATCH_SIZE, + _DEFAULT_MAX_EXPORT_BATCH_SIZE, + ) + ) + except ValueError: + logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BSP_MAX_EXPORT_BATCH_SIZE, + _DEFAULT_MAX_EXPORT_BATCH_SIZE, + ) + return _DEFAULT_MAX_EXPORT_BATCH_SIZE + + @staticmethod + def _default_export_timeout_millis(): + try: + return int(environ.get(OTEL_BSP_EXPORT_TIMEOUT, _DEFAULT_EXPORT_TIMEOUT_MILLIS)) + except ValueError: + logger.exception( + _ENV_VAR_INT_VALUE_ERROR_MESSAGE, + OTEL_BSP_EXPORT_TIMEOUT, + _DEFAULT_EXPORT_TIMEOUT_MILLIS, + ) + return _DEFAULT_EXPORT_TIMEOUT_MILLIS + + @staticmethod + def _validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size): + if max_queue_size <= 0: + raise ValueError("max_queue_size must be a positive integer.") + + if schedule_delay_millis <= 0: + raise ValueError("schedule_delay_millis must be positive.") + + if max_export_batch_size <= 0: + raise ValueError("max_export_batch_size must be a positive integer.") + + if max_export_batch_size > max_queue_size: + raise ValueError("max_export_batch_size must be less than or equal to max_queue_size.") + + +class ConsoleSpanExporter(SpanExporter): + """Implementation of :class:`SpanExporter` that prints spans to the + console. + + This class can be used for diagnostic purposes. It prints the exported + spans to the console STDOUT. + """ + + def __init__( + self, + service_name: str | None = None, + out: typing.IO = sys.stdout, + formatter: collections.abc.Callable[[ReadableSpan], str] = lambda span: span.to_json() + linesep, + ): + self.out = out + self.formatter = formatter + self.service_name = service_name + + def export(self, spans: collections.abc.Sequence[ReadableSpan]) -> SpanExportResult: + for span in spans: + self.out.write(self.formatter(span)) + self.out.flush() + return SpanExportResult.SUCCESS + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py new file mode 100644 index 00000000000..436143c14f2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py @@ -0,0 +1,56 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import collections.abc +import threading +from collections import deque + +from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult + + +class InMemorySpanExporter(SpanExporter): + """Implementation of :class:`.SpanExporter` that stores spans in memory. + + This class can be used for testing purposes. It stores the exported spans + in a deque in memory that can be retrieved using the + :func:`.get_finished_spans` method. + + Args: + max_spans: Maximum number of spans to store in memory. When the limit + is reached, the oldest spans are dropped automatically. If ``None`` + (default), there is no limit. + """ + + def __init__(self, max_spans: int | None = None) -> None: + self._finished_spans: deque[ReadableSpan] = deque(maxlen=max_spans) + self._stopped = False + self._lock = threading.Lock() + + def clear(self) -> None: + """Clear list of collected spans.""" + with self._lock: + self._finished_spans.clear() + + def get_finished_spans(self) -> tuple[ReadableSpan, ...]: + """Get list of collected spans.""" + with self._lock: + return tuple(self._finished_spans) + + def export(self, spans: collections.abc.Sequence[ReadableSpan]) -> SpanExportResult: + """Stores a list of spans in memory.""" + if self._stopped: + return SpanExportResult.FAILURE + with self._lock: + self._finished_spans.extend(spans) + return SpanExportResult.SUCCESS + + def shutdown(self) -> None: + """Shut downs the exporter. + + Calls to export after the exporter has been shut down will fail. + """ + self._stopped = True + + def force_flush(self, timeout_millis: int = 30000) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py new file mode 100644 index 00000000000..2484ce7f93c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py @@ -0,0 +1,72 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import abc +import random + +from opentelemetry.agent._vendor.opentelemetry import trace + + +class IdGenerator(abc.ABC): + @abc.abstractmethod + def generate_span_id(self) -> int: + """Get a new span ID. + + Returns: + A 64-bit int for use as a span ID + """ + + @abc.abstractmethod + def generate_trace_id(self) -> int: + """Get a new trace ID. + + Implementations should at least make the 56 least significant bits + uniformly random. Samplers like the `TraceIdRatioBased` sampler rely on + this randomness to make sampling decisions. + + If the implementation does randomly generate the 56 least significant bits, + it should also implement `is_trace_id_random` to return True. + + See `the specification on TraceIdRatioBased `_. + + Returns: + A 128-bit int for use as a trace ID + """ + + # pylint: disable=no-self-use + def is_trace_id_random(self) -> bool: + """Indicates whether generated trace IDs are random. + + When True, the `trace-id` field will have the `random-trace-id` flag set + in the W3C traceparent header. Per the W3C Trace Context specification, + this indicates that at least the 7 rightmost bytes (56 bits) of the + trace ID were generated randomly with uniform distribution. + + See `the W3C Trace Context specification `_. + + Returns: + True if this generator produces random IDs, False otherwise. + """ + # By default, return False for backwards compatibility. + return False + + +class RandomIdGenerator(IdGenerator): + """The default ID generator for TracerProvider which randomly generates all + bits when generating IDs. + """ + + def generate_span_id(self) -> int: + span_id = random.getrandbits(64) + while span_id == trace.INVALID_SPAN_ID: + span_id = random.getrandbits(64) + return span_id + + def generate_trace_id(self) -> int: + trace_id = random.getrandbits(128) + while trace_id == trace.INVALID_TRACE_ID: + trace_id = random.getrandbits(128) + return trace_id + + def is_trace_id_random(self) -> bool: + return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py new file mode 100644 index 00000000000..64d96ae552f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py @@ -0,0 +1,488 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +""" +For general information about sampling, see `the specification `_. + +OpenTelemetry provides two types of samplers: + +- `StaticSampler` +- `TraceIdRatioBased` + +A `StaticSampler` always returns the same sampling result regardless of the conditions. Both possible StaticSamplers are already created: + +- Always sample spans: ALWAYS_ON +- Never sample spans: ALWAYS_OFF + +A `TraceIdRatioBased` sampler makes a random sampling result based on the sampling probability given. + +If the span being sampled has a parent, `ParentBased` will respect the parent delegate sampler. Otherwise, it returns the sampling result from the given root sampler. + +Currently, sampling results are always made during the creation of the span. However, this might not always be the case in the future (see `OTEP #115 `_). + +Custom samplers can be created by subclassing `Sampler` and implementing `Sampler.should_sample` as well as `Sampler.get_description`. + +Samplers are able to modify the `opentelemetry.trace.span.TraceState` of the parent of the span being created. For custom samplers, it is suggested to implement `Sampler.should_sample` to utilize the +parent span context's `opentelemetry.trace.span.TraceState` and pass into the `SamplingResult` instead of the explicit trace_state field passed into the parameter of `Sampler.should_sample`. + +To use a sampler, pass it into the tracer provider constructor. For example: + +.. code:: python + + from opentelemetry import trace + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import ( + ConsoleSpanExporter, + SimpleSpanProcessor, + ) + from opentelemetry.sdk.trace.sampling import TraceIdRatioBased + + # sample 1 in every 1000 traces + sampler = TraceIdRatioBased(1/1000) + + # set the sampler onto the global tracer provider + trace.set_tracer_provider(TracerProvider(sampler=sampler)) + + # set up an exporter for sampled spans + trace.get_tracer_provider().add_span_processor( + SimpleSpanProcessor(ConsoleSpanExporter()) + ) + + # created spans will now be sampled by the TraceIdRatioBased sampler + with trace.get_tracer(__name__).start_as_current_span("Test Span"): + ... + +The tracer sampler can also be configured via environment variables ``OTEL_TRACES_SAMPLER`` and ``OTEL_TRACES_SAMPLER_ARG`` (only if applicable). +The list of built-in values for ``OTEL_TRACES_SAMPLER`` are: + + * always_on - Sampler that always samples spans, regardless of the parent span's sampling decision. + * always_off - Sampler that never samples spans, regardless of the parent span's sampling decision. + * traceidratio - Sampler that samples probabilistically based on rate. + * parentbased_always_on - (default) Sampler that respects its parent span's sampling decision, but otherwise always samples. + * parentbased_always_off - Sampler that respects its parent span's sampling decision, but otherwise never samples. + * parentbased_traceidratio - Sampler that respects its parent span's sampling decision, but otherwise samples probabilistically based on rate. + +Sampling probability can be set with ``OTEL_TRACES_SAMPLER_ARG`` if the sampler is traceidratio or parentbased_traceidratio. Rate must be in the range [0.0,1.0]. When not provided rate will be set to +1.0 (maximum rate possible). + +Prev example but with environment variables. Please make sure to set the env ``OTEL_TRACES_SAMPLER=traceidratio`` and ``OTEL_TRACES_SAMPLER_ARG=0.001``. + +.. code:: python + + from opentelemetry import trace + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import ( + ConsoleSpanExporter, + SimpleSpanProcessor, + ) + + trace.set_tracer_provider(TracerProvider()) + + # set up an exporter for sampled spans + trace.get_tracer_provider().add_span_processor( + SimpleSpanProcessor(ConsoleSpanExporter()) + ) + + # created spans will now be sampled by the TraceIdRatioBased sampler with rate 1/1000. + with trace.get_tracer(__name__).start_as_current_span("Test Span"): + ... + +When utilizing a configurator, you can configure a custom sampler. In order to create a configurable custom sampler, create an entry point for the custom sampler +factory method or function under the entry point group, ``opentelemetry_traces_sampler``. The custom sampler factory method must be of type ``Callable[[str], Sampler]``, taking a single string argument and +returning a Sampler object. The single input will come from the string value of the ``OTEL_TRACES_SAMPLER_ARG`` environment variable. If ``OTEL_TRACES_SAMPLER_ARG`` is not configured, the input will +be an empty string. For example: + +.. code:: python + + setup( + ... + entry_points={ + ... + "opentelemetry_traces_sampler": [ + "custom_sampler_name = path.to.sampler.factory.method:CustomSamplerFactory.get_sampler" + ] + } + ) + # ... + class CustomRatioSampler(Sampler): + def __init__(rate): + # ... + # ... + class CustomSamplerFactory: + @staticmethod + def get_sampler(sampler_argument): + try: + rate = float(sampler_argument) + return CustomSampler(rate) + except ValueError: # In case argument is empty string. + return CustomSampler(0.5) + +In order to configure you application with a custom sampler's entry point, set the ``OTEL_TRACES_SAMPLER`` environment variable to the key name of the entry point. For example, to configured the +above sampler, set ``OTEL_TRACES_SAMPLER=custom_sampler_name`` and ``OTEL_TRACES_SAMPLER_ARG=0.5``. +""" + +from __future__ import annotations + +import abc +import enum +import os +from collections.abc import Sequence +from logging import getLogger +from types import MappingProxyType + +# pylint: disable=unused-import +from opentelemetry.agent._vendor.opentelemetry.context import Context +from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( + OTEL_TRACES_SAMPLER, + OTEL_TRACES_SAMPLER_ARG, +) +from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, get_current_span +from opentelemetry.agent._vendor.opentelemetry.trace.span import TraceState +from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes + +_logger = getLogger(__name__) + + +class Decision(enum.Enum): + # IsRecording() == false, span will not be recorded and all events and attributes will be dropped. + DROP = 0 + # IsRecording() == true, but Sampled flag MUST NOT be set. + RECORD_ONLY = 1 + # IsRecording() == true AND Sampled flag` MUST be set. + RECORD_AND_SAMPLE = 2 + + def is_recording(self): + return self in (Decision.RECORD_ONLY, Decision.RECORD_AND_SAMPLE) + + def is_sampled(self): + return self is Decision.RECORD_AND_SAMPLE + + +class SamplingResult: + """A sampling result as applied to a newly-created Span. + + Args: + decision: A sampling decision based off of whether the span is recorded + and the sampled flag in trace flags in the span context. + attributes: Attributes to add to the `opentelemetry.trace.Span`. + trace_state: The tracestate used for the `opentelemetry.trace.Span`. + Could possibly have been modified by the sampler. + """ + + def __repr__(self) -> str: + return f"{type(self).__name__}({self.decision!s}, attributes={self.attributes!s})" + + def __init__( + self, + decision: Decision, + attributes: Attributes = None, + trace_state: TraceState | None = None, + ) -> None: + self.decision = decision + if attributes is None: + self.attributes = MappingProxyType({}) + else: + self.attributes = MappingProxyType(attributes) + self.trace_state = trace_state + + +class Sampler(abc.ABC): + @abc.abstractmethod + def should_sample( + self, + parent_context: Context | None, + trace_id: int, + name: str, + kind: SpanKind | None = None, + attributes: Attributes = None, + links: Sequence[Link] | None = None, + trace_state: TraceState | None = None, + ) -> SamplingResult: + pass + + @abc.abstractmethod + def get_description(self) -> str: + pass + + +class StaticSampler(Sampler): + """Sampler that always returns the same decision.""" + + def __init__(self, decision: Decision) -> None: + self._decision = decision + + def should_sample( + self, + parent_context: Context | None, + trace_id: int, + name: str, + kind: SpanKind | None = None, + attributes: Attributes = None, + links: Sequence[Link] | None = None, + trace_state: TraceState | None = None, + ) -> SamplingResult: + if self._decision is Decision.DROP: + attributes = None + return SamplingResult( + self._decision, + attributes, + _get_parent_trace_state(parent_context), + ) + + def get_description(self) -> str: + if self._decision is Decision.DROP: + return "AlwaysOffSampler" + return "AlwaysOnSampler" + + +ALWAYS_OFF = StaticSampler(Decision.DROP) +"""Sampler that never samples spans, regardless of the parent span's sampling decision.""" + +ALWAYS_ON = StaticSampler(Decision.RECORD_AND_SAMPLE) +"""Sampler that always samples spans, regardless of the parent span's sampling decision.""" + + +class TraceIdRatioBased(Sampler): + """ + Sampler that makes sampling decisions probabilistically based on `rate`. + + Args: + rate: Probability (between 0 and 1) that a span will be sampled + """ + + def __init__(self, rate: float): + if rate < 0.0 or rate > 1.0: + raise ValueError("Probability must be in range [0.0, 1.0].") + self._rate = rate + self._bound = self.get_bound_for_rate(self._rate) + + # For compatibility with 64 bit trace IDs, the sampler checks the 64 + # low-order bits of the trace ID to decide whether to sample a given trace. + TRACE_ID_LIMIT = (1 << 64) - 1 + + @classmethod + def get_bound_for_rate(cls, rate: float) -> int: + return round(rate * (cls.TRACE_ID_LIMIT + 1)) + + @property + def rate(self) -> float: + return self._rate + + @property + def bound(self) -> int: + return self._bound + + def should_sample( + self, + parent_context: Context | None, + trace_id: int, + name: str, + kind: SpanKind | None = None, + attributes: Attributes = None, + links: Sequence[Link] | None = None, + trace_state: TraceState | None = None, + ) -> SamplingResult: + decision = Decision.DROP + if trace_id & self.TRACE_ID_LIMIT < self.bound: + decision = Decision.RECORD_AND_SAMPLE + if decision is Decision.DROP: + attributes = None + return SamplingResult( + decision, + attributes, + _get_parent_trace_state(parent_context), + ) + + def get_description(self) -> str: + return f"TraceIdRatioBased{{{self._rate}}}" + + +class ParentBased(Sampler): + """ + If a parent is set, applies the respective delegate sampler. + Otherwise, uses the root provided at initialization to make a + decision. + + Args: + root: Sampler called for spans with no parent (root spans). + remote_parent_sampled: Sampler called for a remote sampled parent. + remote_parent_not_sampled: Sampler called for a remote parent that is + not sampled. + local_parent_sampled: Sampler called for a local sampled parent. + local_parent_not_sampled: Sampler called for a local parent that is + not sampled. + """ + + def __init__( + self, + root: Sampler, + remote_parent_sampled: Sampler = ALWAYS_ON, + remote_parent_not_sampled: Sampler = ALWAYS_OFF, + local_parent_sampled: Sampler = ALWAYS_ON, + local_parent_not_sampled: Sampler = ALWAYS_OFF, + ): + self._root = root + self._remote_parent_sampled = remote_parent_sampled + self._remote_parent_not_sampled = remote_parent_not_sampled + self._local_parent_sampled = local_parent_sampled + self._local_parent_not_sampled = local_parent_not_sampled + + def should_sample( + self, + parent_context: Context | None, + trace_id: int, + name: str, + kind: SpanKind | None = None, + attributes: Attributes = None, + links: Sequence[Link] | None = None, + trace_state: TraceState | None = None, + ) -> SamplingResult: + parent_span_context = get_current_span(parent_context).get_span_context() + # default to the root sampler + sampler = self._root + # respect the sampling and remote flag of the parent if present + if parent_span_context is not None and parent_span_context.is_valid: + if parent_span_context.is_remote: + if parent_span_context.trace_flags.sampled: + sampler = self._remote_parent_sampled + else: + sampler = self._remote_parent_not_sampled + else: + if parent_span_context.trace_flags.sampled: + sampler = self._local_parent_sampled + else: + sampler = self._local_parent_not_sampled + + return sampler.should_sample( + parent_context=parent_context, + trace_id=trace_id, + name=name, + kind=kind, + attributes=attributes, + links=links, + ) + + def get_description(self): + return f"ParentBased{{root:{self._root.get_description()},remoteParentSampled:{self._remote_parent_sampled.get_description()},remoteParentNotSampled:{self._remote_parent_not_sampled.get_description()},localParentSampled:{self._local_parent_sampled.get_description()},localParentNotSampled:{self._local_parent_not_sampled.get_description()}}}" + + +class AlwaysRecordSampler(Sampler): + """ + This sampler will return the sampling result of the provided `root`, unless the + sampling result contains the sampling decision `Decision.DROP`, in which case, a + new sampling result will be returned that is functionally equivalent to the original, except that + it contains the sampling decision `Decision.RECORD_ONLY`. This ensures that all + spans are recorded, with no change to sampling. + + The intended use case of this sampler is to provide a means of sending all spans to a + processor without having an impact on the sampling rate. This may be desirable if a user wishes + to count or otherwise measure all spans produced in a service, without incurring the cost of 100% + sampling. + """ + + def __init__(self, root: Sampler): + if root is None: + raise ValueError("root must not be None") + self._root = root + + def should_sample( + self, + parent_context: Context | None, + trace_id: int, + name: str, + kind: SpanKind | None = None, + attributes: Attributes = None, + links: Sequence[Link] | None = None, + trace_state: TraceState | None = None, + ) -> SamplingResult: + result: SamplingResult = self._root.should_sample( + parent_context, + trace_id, + name, + kind, + attributes, + links, + trace_state, + ) + if result.decision is Decision.DROP: + result = SamplingResult(Decision.RECORD_ONLY, result.attributes, result.trace_state) + + return result + + def get_description(self): + return f"AlwaysRecordSampler{{{self._root.get_description()}}}" + + +DEFAULT_OFF = ParentBased(ALWAYS_OFF) +"""Sampler that respects its parent span's sampling decision, but otherwise never samples.""" + +DEFAULT_ON = ParentBased(ALWAYS_ON) +"""Sampler that respects its parent span's sampling decision, but otherwise always samples.""" + + +class ParentBasedTraceIdRatio(ParentBased): + """ + Sampler that respects its parent span's sampling decision, but otherwise + samples probabilistically based on `rate`. + """ + + def __init__(self, rate: float): + root = TraceIdRatioBased(rate=rate) + super().__init__(root=root) + + +class _AlwaysOff(StaticSampler): + def __init__(self, _): + super().__init__(Decision.DROP) + + +class _AlwaysOn(StaticSampler): + def __init__(self, _): + super().__init__(Decision.RECORD_AND_SAMPLE) + + +class _ParentBasedAlwaysOff(ParentBased): + def __init__(self, _): + super().__init__(ALWAYS_OFF) + + +class _ParentBasedAlwaysOn(ParentBased): + def __init__(self, _): + super().__init__(ALWAYS_ON) + + +_KNOWN_SAMPLERS = { + "always_on": ALWAYS_ON, + "always_off": ALWAYS_OFF, + "parentbased_always_on": DEFAULT_ON, + "parentbased_always_off": DEFAULT_OFF, + "traceidratio": TraceIdRatioBased, + "parentbased_traceidratio": ParentBasedTraceIdRatio, +} + + +def _get_from_env_or_default() -> Sampler: + trace_sampler = os.getenv(OTEL_TRACES_SAMPLER, "parentbased_always_on").lower() + if trace_sampler not in _KNOWN_SAMPLERS: + _logger.warning("Couldn't recognize sampler %s.", trace_sampler) + trace_sampler = "parentbased_always_on" + + if trace_sampler in ("traceidratio", "parentbased_traceidratio"): + try: + rate = float(os.getenv(OTEL_TRACES_SAMPLER_ARG, "")) + return _KNOWN_SAMPLERS[trace_sampler](rate) + except (ValueError, TypeError): + _logger.warning("Could not convert TRACES_SAMPLER_ARG to float. Using default rate 1.0.") + return _KNOWN_SAMPLERS[trace_sampler](1.0) + + return _KNOWN_SAMPLERS[trace_sampler] + + +def _get_parent_trace_state( + parent_context: Context | None, +) -> TraceState | None: + parent_span_context = get_current_span(parent_context).get_span_context() + if parent_span_context is None or not parent_span_context.is_valid: + return None + return parent_span_context.trace_state diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py new file mode 100644 index 00000000000..c762410e3c4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py @@ -0,0 +1,140 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import copy +import datetime +import threading +from collections import deque +from collections.abc import MutableMapping, Sequence + +from opentelemetry.agent._vendor.typing_extensions import deprecated + + +def ns_to_iso_str(nanoseconds): + """Get an ISO 8601 string from time_ns value.""" + ts = datetime.datetime.fromtimestamp(nanoseconds / 1e9, tz=datetime.timezone.utc) + return ts.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + + +def get_dict_as_key(labels): + """Converts a dict to be used as a unique key""" + return tuple( + sorted( + map( + lambda kv: (kv[0], tuple(kv[1])) if isinstance(kv[1], list) else kv, + labels.items(), + ) + ) + ) + + +class BoundedList(Sequence): + """An append only list with a fixed max size. + + Calls to `append` and `extend` will drop the oldest elements if there is + not enough room. + """ + + def __init__(self, maxlen: int | None): + self.dropped = 0 + self._dq = deque(maxlen=maxlen) # type: deque + self._lock = threading.Lock() + + def __deepcopy__(self, memo): + copy_ = BoundedList(0) + memo[id(self)] = copy_ + with self._lock: + copy_.dropped = self.dropped + copy_._dq = copy.deepcopy(self._dq, memo) + return copy_ + + def __repr__(self): + return f"{type(self).__name__}({list(self._dq)}, maxlen={self._dq.maxlen})" + + def __getitem__(self, index): + return self._dq[index] + + def __len__(self): + return len(self._dq) + + def __iter__(self): + with self._lock: + return iter(list(self._dq)) + + def append(self, item): + with self._lock: + if self._dq.maxlen is not None and len(self._dq) == self._dq.maxlen: + self.dropped += 1 + self._dq.append(item) + + def extend(self, seq): + with self._lock: + if self._dq.maxlen is not None: + to_drop = len(seq) + len(self._dq) - self._dq.maxlen + if to_drop > 0: + self.dropped += to_drop + self._dq.extend(seq) + + @classmethod + def from_seq(cls, maxlen, seq): + seq = tuple(seq) + bounded_list = cls(maxlen) + bounded_list.extend(seq) + return bounded_list + + +@deprecated("Deprecated since version 1.4.0.") +class BoundedDict(MutableMapping): + """An ordered dict with a fixed max capacity. + + Oldest elements are dropped when the dict is full and a new element is + added. + """ + + def __init__(self, maxlen: int | None): + if maxlen is not None: + if not isinstance(maxlen, int): + raise ValueError + if maxlen < 0: + raise ValueError + self.maxlen = maxlen + self.dropped = 0 + self._dict = {} # type: dict + self._lock = threading.Lock() # type: threading.Lock + + def __repr__(self): + return f"{type(self).__name__}({dict(self._dict)}, maxlen={self.maxlen})" + + def __getitem__(self, key): + return self._dict[key] + + def __setitem__(self, key, value): + with self._lock: + if self.maxlen is not None and self.maxlen == 0: + self.dropped += 1 + return + + if key in self._dict: + del self._dict[key] + elif self.maxlen is not None and len(self._dict) == self.maxlen: + del self._dict[next(iter(self._dict.keys()))] + self.dropped += 1 + self._dict[key] = value + + def __delitem__(self, key): + del self._dict[key] + + def __iter__(self): + with self._lock: + return iter(self._dict.copy()) + + def __len__(self): + return len(self._dict) + + @classmethod + def from_map(cls, maxlen, mapping): + mapping = dict(mapping) + bounded_dict = cls(maxlen) + for key, value in mapping.items(): + bounded_dict[key] = value + return bounded_dict diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi new file mode 100644 index 00000000000..1b769659492 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi @@ -0,0 +1,76 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from collections.abc import ( + Iterable, + Iterator, + Mapping, + MutableMapping, + Sequence, +) +from typing import ( + Any, + TypeVar, + overload, +) + +from opentelemetry.util.types import AnyValue, AttributesAsKey + +_T = TypeVar("_T") +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") + +def ns_to_iso_str(nanoseconds: int) -> str: ... +def get_dict_as_key( + labels: Mapping[str, AnyValue], +) -> AttributesAsKey: ... + +# pylint: disable=no-self-use +class BoundedList(Sequence[_T]): + """An append only list with a fixed max size. + + Calls to `append` and `extend` will drop the oldest elements if there is + not enough room. + """ + + dropped: int + def __init__(self, maxlen: int | None): ... + def __deepcopy__(self, memo: dict[int, Any]) -> BoundedList[_T]: ... + def insert(self, index: int, value: _T) -> None: ... + @overload + def __getitem__(self, i: int) -> _T: ... + @overload + def __getitem__(self, s: slice) -> Sequence[_T]: ... + def __len__(self) -> int: ... + def append(self, item: _T) -> None: ... + def extend(self, seq: Sequence[_T]) -> None: ... + @classmethod + def from_seq(cls, maxlen: int | None, seq: Iterable[_T]) -> BoundedList[_T]: ... # pylint: disable=undefined-variable + +class BoundedDict(MutableMapping[_KT, _VT]): + """An ordered dict with a fixed max capacity. + + Oldest elements are dropped when the dict is full and a new element is + added. + """ + + dropped: int + def __init__(self, maxlen: int): ... + def __getitem__(self, k: _KT) -> _VT: ... + def __setitem__(self, k: _KT, v: _VT) -> None: ... + def __delitem__(self, v: _KT) -> None: ... + def __iter__(self) -> Iterator[_KT]: ... + def __len__(self) -> int: ... + @classmethod + def from_map(cls, maxlen: int, mapping: Mapping[_KT, _VT]) -> BoundedDict[_KT, _VT]: ... # pylint: disable=undefined-variable diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py new file mode 100644 index 00000000000..4974fd762c6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py @@ -0,0 +1,28 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from collections.abc import Sequence +from typing import Generic, TypeVar + +from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( + InstrumentationScope, + _InstrumentationScopePredicateT, +) + +ConfigT = TypeVar("ConfigT") +ConfiguratorRulesT = Sequence[tuple[_InstrumentationScopePredicateT, ConfigT]] + + +class RuleBasedConfigurator(Generic[ConfigT]): + def __init__(self, *, rules: ConfiguratorRulesT, default_config: ConfigT): + self._rules = rules + self._default_config = default_config + + def __call__(self, scope: InstrumentationScope) -> ConfigT: + for predicate, config in self._rules: + if predicate(scope): + return config + # by default return default config + return self._default_config + + def update_rules(self, rules: ConfiguratorRulesT) -> None: + self._rules = rules diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py new file mode 100644 index 00000000000..9cf849129b5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py @@ -0,0 +1,191 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +from collections.abc import Callable +from fnmatch import fnmatchcase +from json import dumps + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes +from opentelemetry.agent._vendor.opentelemetry.util.types import ( # TODO: see if we can remove F401 when using new sphinx version # noqa: F401 # pylint: disable=unused-import + AnyValue, + Attributes, +) + + +# opentelemetry-agent: instrumentations vendored under the agent's namespace name their scope after +# their module (get_tracer(__name__)); report the upstream module name instead, e.g. +# "opentelemetry.instrumentation.aiohttp_client" rather than "opentelemetry.agent._vendor.opentelemetry...". +_VENDOR_PREFIX = __name__.removesuffix("opentelemetry.sdk.util.instrumentation") + + +def _unvendored_name(name: str) -> str: + if isinstance(name, str) and name.startswith(_VENDOR_PREFIX): + return name[len(_VENDOR_PREFIX) :] + return name + + +class InstrumentationInfo: + """Immutable information about an instrumentation library module. + + See `opentelemetry.trace.TracerProvider.get_tracer` for the meaning of these + properties. + """ + + __slots__ = ("_name", "_version", "_schema_url") + + @deprecated("You should use InstrumentationScope. Deprecated since version 1.11.1.") + def __init__( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + ): + self._name = _unvendored_name(name) + self._version = version + if schema_url is None: + schema_url = "" + self._schema_url = schema_url + + def __repr__(self): + return f"{type(self).__name__}({self._name}, {self._version}, {self._schema_url})" + + def __hash__(self): + return hash((self._name, self._version, self._schema_url)) + + def __eq__(self, value): + return type(value) is type(self) and ( + self._name, + self._version, + self._schema_url, + ) == (value._name, value._version, value._schema_url) + + def __lt__(self, value): + if type(value) is not type(self): + return NotImplemented + return (self._name, self._version, self._schema_url) < ( + value._name, + value._version, + value._schema_url, + ) + + @property + def schema_url(self) -> str | None: + return self._schema_url + + @property + def version(self) -> str | None: + return self._version + + @property + def name(self) -> str: + return self._name + + +class InstrumentationScope: + """A logical unit of the application code with which the emitted telemetry can be + associated. + + See `opentelemetry.trace.TracerProvider.get_tracer` for the meaning of these + properties. + """ + + __slots__ = ( + "_name", + "_version", + "_schema_url", + "_attributes", + ) + + def __init__( + self, + name: str, + version: str | None = None, + schema_url: str | None = None, + attributes: Attributes = None, + ) -> None: + self._name = _unvendored_name(name) + self._version = version + if schema_url is None: + schema_url = "" + self._schema_url = schema_url + # Attributes cannot be added/removed after creation. + self._attributes = BoundedAttributes(attributes=attributes, immutable=True) + + def __repr__(self) -> str: + return f"{type(self).__name__}({self._name}, {self._version}, {self._schema_url}, {self._attributes})" + + def __hash__(self) -> int: + return hash((self._name, self._version, self._schema_url)) + + def __eq__(self, value: object) -> bool: + if not isinstance(value, InstrumentationScope): + return NotImplemented + return ( + self._name, + self._version, + self._schema_url, + self._attributes, + ) == ( + value._name, + value._version, + value._schema_url, + value._attributes, + ) + + def __lt__(self, value: object) -> bool: + if not isinstance(value, InstrumentationScope): + return NotImplemented + return ( + self._name, + self._version, + self._schema_url, + self._attributes, + ) < ( + value._name, + value._version, + value._schema_url, + value._attributes, + ) + + @property + def schema_url(self) -> str | None: + return self._schema_url + + @property + def version(self) -> str | None: + return self._version + + @property + def name(self) -> str: + return self._name + + @property + def attributes(self) -> Attributes: + return self._attributes + + def to_json(self, indent: int | None = 4) -> str: + return dumps( + { + "name": self._name, + "version": self._version, + "schema_url": self._schema_url, + "attributes": (dict(self._attributes) if bool(self._attributes) else None), + }, + indent=indent, + ) + + +_InstrumentationScopePredicateT = Callable[[InstrumentationScope], bool] + + +def _scope_name_matches_glob( + glob_pattern: str, +) -> _InstrumentationScopePredicateT: + def inner(scope: InstrumentationScope) -> bool: + # Scope name matching is case-sensitive. fnmatchcase is used instead of + # fnmatch so it does not rely on the host platform's filename case + # sensitivity (normcase), which lower-cases both operands on Windows. + return fnmatchcase(scope.name, glob_pattern) + + return inner diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py new file mode 100644 index 00000000000..0101c361616 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py new file mode 100644 index 00000000000..77289c2536c --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py @@ -0,0 +1,90 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +APP_BUILD_ID: Final = "app.build_id" +""" +Unique identifier for a particular build or compilation of the application. +""" + +APP_CRASH_ID: Final = "app.crash.id" +""" +A unique identifier representing an instance of an end user facing app crash. +Note: Its value MAY be meaningful and be used as a reference for telemetry and metadata recorded by +the same instrumentation (e.g. it is an ID generated by an external source that captured the crash). +It MAY come from a source external to the instrumentation such that it can be used to look up additional +data from other sources as well as facilitate deduplication. +""" + +APP_INSTALLATION_ID: Final = "app.installation.id" +""" +A unique identifier representing the installation of an application on a specific device. +Note: Its value SHOULD persist across launches of the same application installation, including through application upgrades. +It SHOULD change if the application is uninstalled or if all applications of the vendor are uninstalled. +Additionally, users might be able to reset this value (e.g. by clearing application data). +If an app is installed multiple times on the same device (e.g. in different accounts on Android), each `app.installation.id` SHOULD have a different value. +If multiple OpenTelemetry SDKs are used within the same application, they SHOULD use the same value for `app.installation.id`. +Hardware IDs (e.g. serial number, IMEI, MAC address) MUST NOT be used as the `app.installation.id`. + +For iOS, this value SHOULD be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor). + +For Android, examples of `app.installation.id` implementations include: + +- [Firebase Installation ID](https://firebase.google.com/docs/projects/manage-installations). +- A globally unique UUID which is persisted across sessions in your application. +- [App set ID](https://developer.android.com/identity/app-set-id). +- [`Settings.getString(Settings.Secure.ANDROID_ID)`](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID). + +More information about Android identifier best practices can be found in the [Android user data IDs guide](https://developer.android.com/training/articles/user-data-ids). +""" + +APP_JANK_FRAME_COUNT: Final = "app.jank.frame_count" +""" +A number of frame renders that experienced jank. +Note: Depending on platform limitations, the value provided MAY be approximation. +""" + +APP_JANK_PERIOD: Final = "app.jank.period" +""" +The time period, in seconds, for which this jank is being reported. +""" + +APP_JANK_THRESHOLD: Final = "app.jank.threshold" +""" +The minimum rendering threshold for this jank, in seconds. +""" + +APP_SCREEN_COORDINATE_X: Final = "app.screen.coordinate.x" +""" +The x (horizontal) coordinate of a screen coordinate, in screen pixels. +""" + +APP_SCREEN_COORDINATE_Y: Final = "app.screen.coordinate.y" +""" +The y (vertical) component of a screen coordinate, in screen pixels. +""" + +APP_SCREEN_ID: Final = "app.screen.id" +""" +An identifier that uniquely differentiates this screen from other screens in the same application. +Note: A screen represents only the part of the device display drawn by the app. It typically contains multiple widgets or UI components and is larger in scope than individual widgets. Multiple screens can coexist on the same display simultaneously (e.g., split view on tablets). +""" + +APP_SCREEN_NAME: Final = "app.screen.name" +""" +The name of an application screen. +Note: A screen represents only the part of the device display drawn by the app. It typically contains multiple widgets or UI components and is larger in scope than individual widgets. Multiple screens can coexist on the same display simultaneously (e.g., split view on tablets). +""" + +APP_WIDGET_ID: Final = "app.widget.id" +""" +An identifier that uniquely differentiates this widget from other widgets in the same application. +Note: A widget is an application component, typically an on-screen visual GUI element. +""" + +APP_WIDGET_NAME: Final = "app.widget.name" +""" +The name of an application widget. +Note: A widget is an application component, typically an on-screen visual GUI element. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py new file mode 100644 index 00000000000..ab3dcef5c92 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py @@ -0,0 +1,51 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +ARTIFACT_ATTESTATION_FILENAME: Final = "artifact.attestation.filename" +""" +The provenance filename of the built attestation which directly relates to the build artifact filename. This filename SHOULD accompany the artifact at publish time. See the [SLSA Relationship](https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations) specification for more information. +""" + +ARTIFACT_ATTESTATION_HASH: Final = "artifact.attestation.hash" +""" +The full [hash value (see glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), of the built attestation. Some envelopes in the [software attestation space](https://github.com/in-toto/attestation/tree/main/spec) also refer to this as the **digest**. +""" + +ARTIFACT_ATTESTATION_ID: Final = "artifact.attestation.id" +""" +The ID of the build [software attestation](https://slsa.dev/attestation-model). +""" + +ARTIFACT_FILENAME: Final = "artifact.filename" +""" +The human readable filename of the artifact, typically generated during build and release processes. Often includes the package name and version in the filename. +Note: This filename can also act as the [Package Name](https://slsa.dev/spec/v1.0/terminology#package-model) +in cases where the package ecosystem maps accordingly. +Additionally, the artifact [can be published](https://slsa.dev/spec/v1.0/terminology#software-supply-chain) +for others, but that is not a guarantee. +""" + +ARTIFACT_HASH: Final = "artifact.hash" +""" +The full [hash value (see glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), often found in checksum.txt on a release of the artifact and used to verify package integrity. +Note: The specific algorithm used to create the cryptographic hash value is +not defined. In situations where an artifact has multiple +cryptographic hashes, it is up to the implementer to choose which +hash value to set here; this should be the most secure hash algorithm +that is suitable for the situation and consistent with the +corresponding attestation. The implementer can then provide the other +hash values through an additional set of attribute extensions as they +deem necessary. +""" + +ARTIFACT_PURL: Final = "artifact.purl" +""" +The [Package URL](https://github.com/package-url/purl-spec) of the [package artifact](https://slsa.dev/spec/v1.0/terminology#package-model) provides a standard way to identify and locate the packaged artifact. +""" + +ARTIFACT_VERSION: Final = "artifact.version" +""" +The version of the artifact. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py new file mode 100644 index 00000000000..e9113aa9c01 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py @@ -0,0 +1,316 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +AWS_BEDROCK_GUARDRAIL_ID: Final = "aws.bedrock.guardrail.id" +""" +The unique identifier of the AWS Bedrock Guardrail. A [guardrail](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) helps safeguard and prevent unwanted behavior from model responses or user messages. +""" + +AWS_BEDROCK_KNOWLEDGE_BASE_ID: Final = "aws.bedrock.knowledge_base.id" +""" +The unique identifier of the AWS Bedrock Knowledge base. A [knowledge base](https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html) is a bank of information that can be queried by models to generate more relevant responses and augment prompts. +""" + +AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS: Final = "aws.dynamodb.attribute_definitions" +""" +The JSON-serialized value of each item in the `AttributeDefinitions` request field. +""" + +AWS_DYNAMODB_ATTRIBUTES_TO_GET: Final = "aws.dynamodb.attributes_to_get" +""" +The value of the `AttributesToGet` request parameter. +""" + +AWS_DYNAMODB_CONSISTENT_READ: Final = "aws.dynamodb.consistent_read" +""" +The value of the `ConsistentRead` request parameter. +""" + +AWS_DYNAMODB_CONSUMED_CAPACITY: Final = "aws.dynamodb.consumed_capacity" +""" +The JSON-serialized value of each item in the `ConsumedCapacity` response field. +""" + +AWS_DYNAMODB_COUNT: Final = "aws.dynamodb.count" +""" +The value of the `Count` response parameter. +""" + +AWS_DYNAMODB_EXCLUSIVE_START_TABLE: Final = "aws.dynamodb.exclusive_start_table" +""" +The value of the `ExclusiveStartTableName` request parameter. +""" + +AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES: Final = "aws.dynamodb.global_secondary_index_updates" +""" +The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. +""" + +AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES: Final = "aws.dynamodb.global_secondary_indexes" +""" +The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field. +""" + +AWS_DYNAMODB_INDEX_NAME: Final = "aws.dynamodb.index_name" +""" +The value of the `IndexName` request parameter. +""" + +AWS_DYNAMODB_ITEM_COLLECTION_METRICS: Final = "aws.dynamodb.item_collection_metrics" +""" +The JSON-serialized value of the `ItemCollectionMetrics` response field. +""" + +AWS_DYNAMODB_LIMIT: Final = "aws.dynamodb.limit" +""" +The value of the `Limit` request parameter. +""" + +AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES: Final = "aws.dynamodb.local_secondary_indexes" +""" +The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. +""" + +AWS_DYNAMODB_PROJECTION: Final = "aws.dynamodb.projection" +""" +The value of the `ProjectionExpression` request parameter. +""" + +AWS_DYNAMODB_PROVISIONED_READ_CAPACITY: Final = "aws.dynamodb.provisioned_read_capacity" +""" +The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. +""" + +AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY: Final = "aws.dynamodb.provisioned_write_capacity" +""" +The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. +""" + +AWS_DYNAMODB_SCAN_FORWARD: Final = "aws.dynamodb.scan_forward" +""" +The value of the `ScanIndexForward` request parameter. +""" + +AWS_DYNAMODB_SCANNED_COUNT: Final = "aws.dynamodb.scanned_count" +""" +The value of the `ScannedCount` response parameter. +""" + +AWS_DYNAMODB_SEGMENT: Final = "aws.dynamodb.segment" +""" +The value of the `Segment` request parameter. +""" + +AWS_DYNAMODB_SELECT: Final = "aws.dynamodb.select" +""" +The value of the `Select` request parameter. +""" + +AWS_DYNAMODB_TABLE_COUNT: Final = "aws.dynamodb.table_count" +""" +The number of items in the `TableNames` response parameter. +""" + +AWS_DYNAMODB_TABLE_NAMES: Final = "aws.dynamodb.table_names" +""" +The keys in the `RequestItems` object field. +""" + +AWS_DYNAMODB_TOTAL_SEGMENTS: Final = "aws.dynamodb.total_segments" +""" +The value of the `TotalSegments` request parameter. +""" + +AWS_ECS_CLUSTER_ARN: Final = "aws.ecs.cluster.arn" +""" +The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). +""" + +AWS_ECS_CONTAINER_ARN: Final = "aws.ecs.container.arn" +""" +The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). +""" + +AWS_ECS_LAUNCHTYPE: Final = "aws.ecs.launchtype" +""" +The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. +""" + +AWS_ECS_TASK_ARN: Final = "aws.ecs.task.arn" +""" +The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). +""" + +AWS_ECS_TASK_FAMILY: Final = "aws.ecs.task.family" +""" +The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. +""" + +AWS_ECS_TASK_ID: Final = "aws.ecs.task.id" +""" +The ID of a running ECS task. The ID MUST be extracted from `task.arn`. +""" + +AWS_ECS_TASK_REVISION: Final = "aws.ecs.task.revision" +""" +The revision for the task definition used to create the ECS task. +""" + +AWS_EKS_CLUSTER_ARN: Final = "aws.eks.cluster.arn" +""" +The ARN of an EKS cluster. +""" + +AWS_EXTENDED_REQUEST_ID: Final = "aws.extended_request_id" +""" +The AWS extended request ID as returned in the response header `x-amz-id-2`. +""" + +AWS_KINESIS_STREAM_NAME: Final = "aws.kinesis.stream_name" +""" +The name of the AWS Kinesis [stream](https://docs.aws.amazon.com/streams/latest/dev/introduction.html) the request refers to. Corresponds to the `--stream-name` parameter of the Kinesis [describe-stream](https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html) operation. +""" + +AWS_LAMBDA_INVOKED_ARN: Final = "aws.lambda.invoked_arn" +""" +The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). +Note: This may be different from `cloud.resource_id` if an alias is involved. +""" + +AWS_LAMBDA_RESOURCE_MAPPING_ID: Final = "aws.lambda.resource_mapping.id" +""" +The UUID of the [AWS Lambda EvenSource Mapping](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html). An event source is mapped to a lambda function. It's contents are read by Lambda and used to trigger a function. This isn't available in the lambda execution context or the lambda runtime environment. This is going to be populated by the AWS SDK for each language when that UUID is present. Some of these operations are Create/Delete/Get/List/Update EventSourceMapping. +""" + +AWS_LOG_GROUP_ARNS: Final = "aws.log.group.arns" +""" +The Amazon Resource Name(s) (ARN) of the AWS log group(s). +Note: See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). +""" + +AWS_LOG_GROUP_NAMES: Final = "aws.log.group.names" +""" +The name(s) of the AWS log group(s) an application is writing to. +Note: Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. +""" + +AWS_LOG_STREAM_ARNS: Final = "aws.log.stream.arns" +""" +The ARN(s) of the AWS log stream(s). +Note: See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. +""" + +AWS_LOG_STREAM_NAMES: Final = "aws.log.stream.names" +""" +The name(s) of the AWS log stream(s) an application is writing to. +""" + +AWS_REQUEST_ID: Final = "aws.request_id" +""" +The AWS request ID as returned in the response headers `x-amzn-requestid`, `x-amzn-request-id` or `x-amz-request-id`. +""" + +AWS_S3_BUCKET: Final = "aws.s3.bucket" +""" +The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. +Note: The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. +This applies to almost all S3 operations except `list-buckets`. +""" + +AWS_S3_COPY_SOURCE: Final = "aws.s3.copy_source" +""" +The source object (in the form `bucket`/`key`) for the copy operation. +Note: The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter +of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). +This applies in particular to the following operations: + +- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) +- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). +""" + +AWS_S3_DELETE: Final = "aws.s3.delete" +""" +The delete request container that specifies the objects to be deleted. +Note: The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. +The `delete` attribute corresponds to the `--delete` parameter of the +[delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). +""" + +AWS_S3_KEY: Final = "aws.s3.key" +""" +The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. +Note: The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. +This applies in particular to the following operations: + +- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) +- [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) +- [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) +- [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) +- [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) +- [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) +- [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) +- [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) +- [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) +- [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) +- [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) +- [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). +""" + +AWS_S3_PART_NUMBER: Final = "aws.s3.part_number" +""" +The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. +Note: The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. +The `part_number` attribute corresponds to the `--part-number` parameter of the +[upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). +""" + +AWS_S3_UPLOAD_ID: Final = "aws.s3.upload_id" +""" +Upload ID that identifies the multipart upload. +Note: The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter +of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. +This applies in particular to the following operations: + +- [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) +- [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) +- [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) +- [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) +- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). +""" + +AWS_SECRETSMANAGER_SECRET_ARN: Final = "aws.secretsmanager.secret.arn" +""" +The ARN of the Secret stored in the Secrets Manager. +""" + +AWS_SNS_TOPIC_ARN: Final = "aws.sns.topic.arn" +""" +The ARN of the AWS SNS Topic. An Amazon SNS [topic](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html) is a logical access point that acts as a communication channel. +""" + +AWS_SQS_QUEUE_URL: Final = "aws.sqs.queue.url" +""" +The URL of the AWS SQS Queue. It's a unique identifier for a queue in Amazon Simple Queue Service (SQS) and is used to access the queue and perform actions on it. +""" + +AWS_STEP_FUNCTIONS_ACTIVITY_ARN: Final = "aws.step_functions.activity.arn" +""" +The ARN of the AWS Step Functions Activity. +""" + +AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN: Final = "aws.step_functions.state_machine.arn" +""" +The ARN of the AWS Step Functions State Machine. +""" + + +class AwsEcsLaunchtypeValues(Enum): + EC2 = "ec2" + """Amazon EC2.""" + FARGATE = "fargate" + """Amazon Fargate.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py new file mode 100644 index 00000000000..7595d9aa750 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py @@ -0,0 +1,14 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +AZ_NAMESPACE: Final = "az.namespace" +""" +Deprecated: Replaced by `azure.resource_provider.namespace`. +""" + +AZ_SERVICE_REQUEST_ID: Final = "az.service_request_id" +""" +Deprecated: Replaced by `azure.service.request.id`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py new file mode 100644 index 00000000000..fb1a7f1ed50 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py @@ -0,0 +1,76 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +AZURE_CLIENT_ID: Final = "azure.client.id" +""" +The unique identifier of the client instance. +""" + +AZURE_COSMOSDB_CONNECTION_MODE: Final = "azure.cosmosdb.connection.mode" +""" +Cosmos client connection mode. +""" + +AZURE_COSMOSDB_CONSISTENCY_LEVEL: Final = "azure.cosmosdb.consistency.level" +""" +Account or request [consistency level](https://learn.microsoft.com/azure/cosmos-db/consistency-levels). +""" + +AZURE_COSMOSDB_OPERATION_CONTACTED_REGIONS: Final = "azure.cosmosdb.operation.contacted_regions" +""" +List of regions contacted during operation in the order that they were contacted. If there is more than one region listed, it indicates that the operation was performed on multiple regions i.e. cross-regional call. +Note: Region name matches the format of `displayName` in [Azure Location API](https://learn.microsoft.com/rest/api/resources/subscriptions/list-locations). +""" + +AZURE_COSMOSDB_OPERATION_REQUEST_CHARGE: Final = "azure.cosmosdb.operation.request_charge" +""" +The number of request units consumed by the operation. +""" + +AZURE_COSMOSDB_REQUEST_BODY_SIZE: Final = "azure.cosmosdb.request.body.size" +""" +Request payload size in bytes. +""" + +AZURE_COSMOSDB_RESPONSE_SUB_STATUS_CODE: Final = "azure.cosmosdb.response.sub_status_code" +""" +Cosmos DB sub status code. +""" + +AZURE_RESOURCE_GROUP_NAME: Final = "azure.resource_group.name" +""" +The name of the Azure [resource group](https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal) the resource belongs to. +""" + +AZURE_RESOURCE_PROVIDER_NAMESPACE: Final = "azure.resource_provider.namespace" +""" +[Azure Resource Provider Namespace](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers) as recognized by the client. +""" + +AZURE_SERVICE_REQUEST_ID: Final = "azure.service.request.id" +""" +The unique identifier of the service request. It's generated by the Azure service and returned with the response. +""" + + +class AzureCosmosdbConnectionModeValues(Enum): + GATEWAY = "gateway" + """Gateway (HTTP) connection.""" + DIRECT = "direct" + """Direct connection.""" + + +class AzureCosmosdbConsistencyLevelValues(Enum): + STRONG = "Strong" + """Strong.""" + BOUNDED_STALENESS = "BoundedStaleness" + """Bounded Staleness.""" + SESSION = "Session" + """Session.""" + EVENTUAL = "Eventual" + """Eventual.""" + CONSISTENT_PREFIX = "ConsistentPrefix" + """Consistent Prefix.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py new file mode 100644 index 00000000000..ff96d0ccfdd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py @@ -0,0 +1,104 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +BROWSER_BRANDS: Final = "browser.brands" +""" +Array of brand name and version separated by a space. +Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). +""" + +BROWSER_DOCUMENT_URL_FULL: Final = "browser.document.url.full" +""" +Absolute URL of the current browser document according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). +""" + +BROWSER_LANGUAGE: Final = "browser.language" +""" +Preferred language of the user using the browser. +Note: This value is intended to be taken from the Navigator API `navigator.language`. +""" + +BROWSER_MOBILE: Final = "browser.mobile" +""" +A boolean that is true if the browser is running on a mobile device. +Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset. +""" + +BROWSER_PLATFORM: Final = "browser.platform" +""" +The platform on which the browser is running. +Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. +The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. +""" + +BROWSER_WEB_VITAL_DELTA: Final = "browser.web_vital.delta" +""" +The delta between the current value and the last-reported value. See [delta](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#report-only-the-delta-of-changes). +""" + +BROWSER_WEB_VITAL_ID: Final = "browser.web_vital.id" +""" +A unique ID representing this particular metric instance. +""" + +BROWSER_WEB_VITAL_NAME: Final = "browser.web_vital.name" +""" +Name of the web vital. +""" + +BROWSER_WEB_VITAL_NAVIGATION_TYPE: Final = "browser.web_vital.navigation_type" +""" +The type of navigation, as reported by the [Navigation Timing API](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/type), with additional values reported by the web-vitals library. +""" + +BROWSER_WEB_VITAL_RATING: Final = "browser.web_vital.rating" +""" +The rating of the web vital value against the "good", "needs improvement", and "poor" thresholds defined for the metric. +""" + +BROWSER_WEB_VITAL_VALUE: Final = "browser.web_vital.value" +""" +Value of the web vital. +""" + + +class BrowserWebVitalNameValues(Enum): + CLS = "cls" + """Cumulative Layout Shift. See [cls](https://web.dev/articles/cls).""" + LCP = "lcp" + """Largest Contentful Paint. See [lcp](https://web.dev/articles/lcp).""" + FCP = "fcp" + """First Contentful Paint. See [fcp](https://web.dev/articles/fcp).""" + INP = "inp" + """Interaction to Next Paint. See [inp](https://web.dev/articles/inp).""" + TTFB = "ttfb" + """Time to First Byte. See [ttfb](https://web.dev/articles/ttfb).""" + FID = "fid" + """Deprecated: Replaced by Interaction to Next Paint (`inp`), which became a Core Web Vital in March 2024. See [inp](https://web.dev/articles/inp).""" + + +class BrowserWebVitalNavigationTypeValues(Enum): + NAVIGATE = "navigate" + """Navigation started by clicking a link, entering a URL, form submission, or a script operation.""" + RELOAD = "reload" + """Navigation through a reload operation or a `Location.reload()` call.""" + BACK_FORWARD = "back-forward" + """Navigation through the browser's history traversal (e.g. back/forward buttons).""" + BACK_FORWARD_CACHE = "back-forward-cache" + """Navigation restoring a page from the back/forward cache (bfcache).""" + PRERENDER = "prerender" + """Navigation to a page that was prerendered.""" + RESTORE = "restore" + """Navigation restoring a page that was previously discarded by the browser.""" + + +class BrowserWebVitalRatingValues(Enum): + GOOD = "good" + """The metric value is within the "good" threshold.""" + NEEDS_IMPROVEMENT = "needs-improvement" + """The metric value is within the "needs improvement" threshold.""" + POOR = "poor" + """The metric value is within the "poor" threshold.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py new file mode 100644 index 00000000000..976a5f74fb8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py @@ -0,0 +1,60 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +CASSANDRA_CONSISTENCY_LEVEL: Final = "cassandra.consistency.level" +""" +The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). +""" + +CASSANDRA_COORDINATOR_DC: Final = "cassandra.coordinator.dc" +""" +The data center of the coordinating node for a query. +""" + +CASSANDRA_COORDINATOR_ID: Final = "cassandra.coordinator.id" +""" +The ID of the coordinating node for a query. +""" + +CASSANDRA_PAGE_SIZE: Final = "cassandra.page.size" +""" +The fetch size used for paging, i.e. how many rows will be returned at once. +""" + +CASSANDRA_QUERY_IDEMPOTENT: Final = "cassandra.query.idempotent" +""" +Whether or not the query is idempotent. +""" + +CASSANDRA_SPECULATIVE_EXECUTION_COUNT: Final = "cassandra.speculative_execution.count" +""" +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. +""" + + +class CassandraConsistencyLevelValues(Enum): + ALL = "all" + """All.""" + EACH_QUORUM = "each_quorum" + """Each Quorum.""" + QUORUM = "quorum" + """Quorum.""" + LOCAL_QUORUM = "local_quorum" + """Local Quorum.""" + ONE = "one" + """One.""" + TWO = "two" + """Two.""" + THREE = "three" + """Three.""" + LOCAL_ONE = "local_one" + """Local One.""" + ANY = "any" + """Any.""" + SERIAL = "serial" + """Serial.""" + LOCAL_SERIAL = "local_serial" + """Local Serial.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py new file mode 100644 index 00000000000..a68690814ef --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py @@ -0,0 +1,152 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +CICD_PIPELINE_ACTION_NAME: Final = "cicd.pipeline.action.name" +""" +The kind of action a pipeline run is performing. +""" + +CICD_PIPELINE_NAME: Final = "cicd.pipeline.name" +""" +The human readable name of the pipeline within a CI/CD system. +""" + +CICD_PIPELINE_RESULT: Final = "cicd.pipeline.result" +""" +The result of a pipeline run. +""" + +CICD_PIPELINE_RUN_ID: Final = "cicd.pipeline.run.id" +""" +The unique identifier of a pipeline run within a CI/CD system. +""" + +CICD_PIPELINE_RUN_STATE: Final = "cicd.pipeline.run.state" +""" +The pipeline run goes through these states during its lifecycle. +""" + +CICD_PIPELINE_RUN_URL_FULL: Final = "cicd.pipeline.run.url.full" +""" +The [URL](https://wikipedia.org/wiki/URL) of the pipeline run, providing the complete address in order to locate and identify the pipeline run. +""" + +CICD_PIPELINE_TASK_NAME: Final = "cicd.pipeline.task.name" +""" +The human readable name of a task within a pipeline. Task here most closely aligns with a [computing process](https://wikipedia.org/wiki/Pipeline_(computing)) in a pipeline. Other terms for tasks include commands, steps, and procedures. +""" + +CICD_PIPELINE_TASK_RUN_ID: Final = "cicd.pipeline.task.run.id" +""" +The unique identifier of a task run within a pipeline. +Note: For a given pipeline run and task, the `cicd.pipeline.task.run.id` MUST be unique within that run. For the same task across different runs of the same pipeline, the `cicd.pipeline.task.run.id` MAY remain the same, enabling correlation of `cicd.pipeline.task.run.result` values across multiple pipeline runs. +""" + +CICD_PIPELINE_TASK_RUN_RESULT: Final = "cicd.pipeline.task.run.result" +""" +The result of a task run. +""" + +CICD_PIPELINE_TASK_RUN_URL_FULL: Final = "cicd.pipeline.task.run.url.full" +""" +The [URL](https://wikipedia.org/wiki/URL) of the pipeline task run, providing the complete address in order to locate and identify the pipeline task run. +""" + +CICD_PIPELINE_TASK_TYPE: Final = "cicd.pipeline.task.type" +""" +The type of the task within a pipeline. +""" + +CICD_SYSTEM_COMPONENT: Final = "cicd.system.component" +""" +The name of a component of the CI/CD system. +""" + +CICD_WORKER_ID: Final = "cicd.worker.id" +""" +The unique identifier of a worker within a CI/CD system. +""" + +CICD_WORKER_NAME: Final = "cicd.worker.name" +""" +The name of a worker within a CI/CD system. +""" + +CICD_WORKER_STATE: Final = "cicd.worker.state" +""" +The state of a CI/CD worker / agent. +""" + +CICD_WORKER_URL_FULL: Final = "cicd.worker.url.full" +""" +The [URL](https://wikipedia.org/wiki/URL) of the worker, providing the complete address in order to locate and identify the worker. +""" + + +class CicdPipelineActionNameValues(Enum): + BUILD = "BUILD" + """The pipeline run is executing a build.""" + RUN = "RUN" + """The pipeline run is executing.""" + SYNC = "SYNC" + """The pipeline run is executing a sync.""" + + +class CicdPipelineResultValues(Enum): + SUCCESS = "success" + """The pipeline run finished successfully.""" + FAILURE = "failure" + """The pipeline run did not finish successfully, eg. due to a compile error or a failing test. Such failures are usually detected by non-zero exit codes of the tools executed in the pipeline run.""" + ERROR = "error" + """The pipeline run failed due to an error in the CI/CD system, eg. due to the worker being killed.""" + TIMEOUT = "timeout" + """A timeout caused the pipeline run to be interrupted.""" + CANCELLATION = "cancellation" + """The pipeline run was cancelled, eg. by a user manually cancelling the pipeline run.""" + SKIP = "skip" + """The pipeline run was skipped, eg. due to a precondition not being met.""" + + +class CicdPipelineRunStateValues(Enum): + PENDING = "pending" + """The run pending state spans from the event triggering the pipeline run until the execution of the run starts (eg. time spent in a queue, provisioning agents, creating run resources).""" + EXECUTING = "executing" + """The executing state spans the execution of any run tasks (eg. build, test).""" + FINALIZING = "finalizing" + """The finalizing state spans from when the run has finished executing (eg. cleanup of run resources).""" + + +class CicdPipelineTaskRunResultValues(Enum): + SUCCESS = "success" + """The task run finished successfully.""" + FAILURE = "failure" + """The task run did not finish successfully, eg. due to a compile error or a failing test. Such failures are usually detected by non-zero exit codes of the tools executed in the task run.""" + ERROR = "error" + """The task run failed due to an error in the CI/CD system, eg. due to the worker being killed.""" + TIMEOUT = "timeout" + """A timeout caused the task run to be interrupted.""" + CANCELLATION = "cancellation" + """The task run was cancelled, eg. by a user manually cancelling the task run.""" + SKIP = "skip" + """The task run was skipped, eg. due to a precondition not being met.""" + + +class CicdPipelineTaskTypeValues(Enum): + BUILD = "build" + """build.""" + TEST = "test" + """test.""" + DEPLOY = "deploy" + """deploy.""" + + +class CicdWorkerStateValues(Enum): + AVAILABLE = "available" + """The worker is not performing work for the CI/CD system. It is available to the CI/CD system to perform work on (online / idle).""" + BUSY = "busy" + """The worker is performing work for the CI/CD system.""" + OFFLINE = "offline" + """The worker is not available to the CI/CD system (disconnected / down).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py new file mode 100644 index 00000000000..b68dea7203f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py @@ -0,0 +1,14 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +CLIENT_ADDRESS: Final = "client.address" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.client_attributes.CLIENT_ADDRESS`. +""" + +CLIENT_PORT: Final = "client.port" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.client_attributes.CLIENT_PORT`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py new file mode 100644 index 00000000000..87570ea4d2b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py @@ -0,0 +1,156 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +CLOUD_ACCOUNT_ID: Final = "cloud.account.id" +""" +The cloud account ID the resource is assigned to. +Note: For Azure, this is the subscription ID. +""" + +CLOUD_AVAILABILITY_ZONE: Final = "cloud.availability_zone" +""" +Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. +Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud. +""" + +CLOUD_PLATFORM: Final = "cloud.platform" +""" +The cloud platform in use. +Note: The prefix of the service SHOULD match the one specified in `cloud.provider`. +""" + +CLOUD_PROVIDER: Final = "cloud.provider" +""" +Name of the cloud provider. +""" + +CLOUD_REGION: Final = "cloud.region" +""" +The geographical region within a cloud provider. When associated with a resource, this attribute specifies the region where the resource operates. When calling services or APIs deployed on a cloud, this attribute identifies the region where the called destination is deployed. +Note: Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). +""" + +CLOUD_RESOURCE_ID: Final = "cloud.resource_id" +""" +Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://google.aip.dev/122#full-resource-names) on GCP). +Note: On some cloud providers, it may not be possible to determine the full ID at startup, +so it may be necessary to set `cloud.resource_id` as a span attribute instead. + +The exact value to use for `cloud.resource_id` depends on the cloud provider. +The following well-known definitions MUST be used if you set this attribute and they apply: + +- **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + Take care not to use the "invoked ARN" directly but replace any + [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + with the resolved function version, as the same runtime instance may be invocable with + multiple different aliases. +- **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) +- **Azure:** The [Fully Qualified Resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, + *not* the function app, having the form + `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + a TracerProvider. +""" + + +class CloudPlatformValues(Enum): + AKAMAI_CLOUD_COMPUTE = "akamai_cloud.compute" + """Akamai Cloud Compute.""" + ALIBABA_CLOUD_ECS = "alibaba_cloud_ecs" + """Alibaba Cloud Elastic Compute Service.""" + ALIBABA_CLOUD_FC = "alibaba_cloud_fc" + """Alibaba Cloud Function Compute.""" + ALIBABA_CLOUD_OPENSHIFT = "alibaba_cloud_openshift" + """Red Hat OpenShift on Alibaba Cloud.""" + AWS_EC2 = "aws_ec2" + """AWS Elastic Compute Cloud.""" + AWS_ECS = "aws_ecs" + """AWS Elastic Container Service.""" + AWS_EKS = "aws_eks" + """AWS Elastic Kubernetes Service.""" + AWS_LAMBDA = "aws_lambda" + """AWS Lambda.""" + AWS_ELASTIC_BEANSTALK = "aws_elastic_beanstalk" + """AWS Elastic Beanstalk.""" + AWS_APP_RUNNER = "aws_app_runner" + """AWS App Runner.""" + AWS_OPENSHIFT = "aws_openshift" + """Red Hat OpenShift on AWS (ROSA).""" + AZURE_VM = "azure.vm" + """Azure Virtual Machines.""" + AZURE_CONTAINER_APPS = "azure.container_apps" + """Azure Container Apps.""" + AZURE_CONTAINER_INSTANCES = "azure.container_instances" + """Azure Container Instances.""" + AZURE_AKS = "azure.aks" + """Azure Kubernetes Service.""" + AZURE_FUNCTIONS = "azure.functions" + """Azure Functions.""" + AZURE_APP_SERVICE = "azure.app_service" + """Azure App Service.""" + AZURE_OPENSHIFT = "azure.openshift" + """Azure Red Hat OpenShift.""" + GCP_AGENT_ENGINE = "gcp.agent_engine" + """Google Vertex AI Agent Engine.""" + GCP_BARE_METAL_SOLUTION = "gcp_bare_metal_solution" + """Google Bare Metal Solution (BMS).""" + GCP_COMPUTE_ENGINE = "gcp_compute_engine" + """Google Cloud Compute Engine (GCE).""" + GCP_CLOUD_RUN = "gcp_cloud_run" + """Google Cloud Run.""" + GCP_KUBERNETES_ENGINE = "gcp_kubernetes_engine" + """Google Cloud Kubernetes Engine (GKE).""" + GCP_CLOUD_FUNCTIONS = "gcp_cloud_functions" + """Google Cloud Functions (GCF).""" + GCP_APP_ENGINE = "gcp_app_engine" + """Google Cloud App Engine (GAE).""" + GCP_OPENSHIFT = "gcp_openshift" + """Red Hat OpenShift on Google Cloud.""" + HETZNER_CLOUD_SERVER = "hetzner.cloud_server" + """Server on Hetzner Cloud.""" + IBM_CLOUD_OPENSHIFT = "ibm_cloud_openshift" + """Red Hat OpenShift on IBM Cloud.""" + ORACLE_CLOUD_COMPUTE = "oracle_cloud_compute" + """Compute on Oracle Cloud Infrastructure (OCI).""" + ORACLE_CLOUD_OKE = "oracle_cloud_oke" + """Kubernetes Engine (OKE) on Oracle Cloud Infrastructure (OCI).""" + SCALEWAY_CLOUD_COMPUTE = "scaleway_cloud_compute" + """Compute on Scaleway Cloud.""" + TENCENT_CLOUD_CVM = "tencent_cloud_cvm" + """Tencent Cloud Cloud Virtual Machine (CVM).""" + TENCENT_CLOUD_EKS = "tencent_cloud_eks" + """Tencent Cloud Elastic Kubernetes Service (EKS).""" + TENCENT_CLOUD_SCF = "tencent_cloud_scf" + """Tencent Cloud Serverless Cloud Function (SCF).""" + VULTR_CLOUD_COMPUTE = "vultr.cloud_compute" + """Vultr Cloud Compute.""" + + +class CloudProviderValues(Enum): + AKAMAI_CLOUD = "akamai_cloud" + """Akamai Cloud.""" + ALIBABA_CLOUD = "alibaba_cloud" + """Alibaba Cloud.""" + AWS = "aws" + """Amazon Web Services.""" + AZURE = "azure" + """Microsoft Azure.""" + GCP = "gcp" + """Google Cloud Platform.""" + HEROKU = "heroku" + """Heroku Platform as a Service.""" + HETZNER = "hetzner" + """Hetzner.""" + IBM_CLOUD = "ibm_cloud" + """IBM Cloud.""" + ORACLE_CLOUD = "oracle_cloud" + """Oracle Cloud Infrastructure (OCI).""" + SCALEWAY_CLOUD = "scaleway_cloud" + """Scaleway Cloud.""" + TENCENT_CLOUD = "tencent_cloud" + """Tencent Cloud.""" + VULTR = "vultr" + """Vultr.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py new file mode 100644 index 00000000000..fe3226a594d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py @@ -0,0 +1,29 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +CLOUDEVENTS_EVENT_ID: Final = "cloudevents.event_id" +""" +The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. +""" + +CLOUDEVENTS_EVENT_SOURCE: Final = "cloudevents.event_source" +""" +The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. +""" + +CLOUDEVENTS_EVENT_SPEC_VERSION: Final = "cloudevents.event_spec_version" +""" +The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. +""" + +CLOUDEVENTS_EVENT_SUBJECT: Final = "cloudevents.event_subject" +""" +The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). +""" + +CLOUDEVENTS_EVENT_TYPE: Final = "cloudevents.event_type" +""" +The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py new file mode 100644 index 00000000000..9ed23c0406d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py @@ -0,0 +1,107 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +CLOUDFOUNDRY_APP_ID: Final = "cloudfoundry.app.id" +""" +The guid of the application. +Note: Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.application_id`. This is the same value as +reported by `cf app --guid`. +""" + +CLOUDFOUNDRY_APP_INSTANCE_ID: Final = "cloudfoundry.app.instance.id" +""" +The index of the application instance. 0 when just one instance is active. +Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the application instance index for applications +deployed on the runtime. + +Application instrumentation should use the value from environment +variable `CF_INSTANCE_INDEX`. +""" + +CLOUDFOUNDRY_APP_NAME: Final = "cloudfoundry.app.name" +""" +The name of the application. +Note: Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.application_name`. This is the same value +as reported by `cf apps`. +""" + +CLOUDFOUNDRY_ORG_ID: Final = "cloudfoundry.org.id" +""" +The guid of the CloudFoundry org the application is running in. +Note: Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.org_id`. This is the same value as +reported by `cf org --guid`. +""" + +CLOUDFOUNDRY_ORG_NAME: Final = "cloudfoundry.org.name" +""" +The name of the CloudFoundry organization the app is running in. +Note: Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.org_name`. This is the same value as +reported by `cf orgs`. +""" + +CLOUDFOUNDRY_PROCESS_ID: Final = "cloudfoundry.process.id" +""" +The UID identifying the process. +Note: Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to +`VCAP_APPLICATION.app_id` for applications deployed to the runtime. +For system components, this could be the actual PID. +""" + +CLOUDFOUNDRY_PROCESS_TYPE: Final = "cloudfoundry.process.type" +""" +The type of process. +Note: CloudFoundry applications can consist of multiple jobs. Usually the +main process will be of type `web`. There can be additional background +tasks or side-cars with different process types. +""" + +CLOUDFOUNDRY_SPACE_ID: Final = "cloudfoundry.space.id" +""" +The guid of the CloudFoundry space the application is running in. +Note: Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.space_id`. This is the same value as +reported by `cf space --guid`. +""" + +CLOUDFOUNDRY_SPACE_NAME: Final = "cloudfoundry.space.name" +""" +The name of the CloudFoundry space the application is running in. +Note: Application instrumentation should use the value from environment +variable `VCAP_APPLICATION.space_name`. This is the same value as +reported by `cf spaces`. +""" + +CLOUDFOUNDRY_SYSTEM_ID: Final = "cloudfoundry.system.id" +""" +A guid or another name describing the event source. +Note: CloudFoundry defines the `source_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the component name, e.g. "gorouter", for +CloudFoundry components. + +When system components are instrumented, values from the +[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) +should be used. The `system.id` should be set to +`spec.deployment/spec.name`. +""" + +CLOUDFOUNDRY_SYSTEM_INSTANCE_ID: Final = "cloudfoundry.system.instance.id" +""" +A guid describing the concrete instance of the event source. +Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). +It is used for logs and metrics emitted by CloudFoundry. It is +supposed to contain the vm ID for CloudFoundry components. + +When system components are instrumented, values from the +[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) +should be used. The `system.instance.id` should be set to `spec.id`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py new file mode 100644 index 00000000000..130aebc2c4d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py @@ -0,0 +1,54 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +CODE_COLUMN: Final = "code.column" +""" +Deprecated: Replaced by `code.column.number`. +""" + +CODE_COLUMN_NUMBER: Final = "code.column.number" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_COLUMN_NUMBER`. +""" + +CODE_FILE_PATH: Final = "code.file.path" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_FILE_PATH`. +""" + +CODE_FILEPATH: Final = "code.filepath" +""" +Deprecated: Replaced by `code.file.path`. +""" + +CODE_FUNCTION: Final = "code.function" +""" +Deprecated: Value should be included in `code.function.name` which is expected to be a fully-qualified name. +""" + +CODE_FUNCTION_NAME: Final = "code.function.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_FUNCTION_NAME`. +""" + +CODE_LINE_NUMBER: Final = "code.line.number" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_LINE_NUMBER`. +""" + +CODE_LINENO: Final = "code.lineno" +""" +Deprecated: Replaced by `code.line.number`. +""" + +CODE_NAMESPACE: Final = "code.namespace" +""" +Deprecated: Value should be included in `code.function.name` which is expected to be a fully-qualified name. +""" + +CODE_STACKTRACE: Final = "code.stacktrace" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_STACKTRACE`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py new file mode 100644 index 00000000000..ca6c1f06e8a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py @@ -0,0 +1,114 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +CONTAINER_COMMAND: Final = "container.command" +""" +The command used to run the container (i.e. the command name). +Note: If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. +""" + +CONTAINER_COMMAND_ARGS: Final = "container.command_args" +""" +All the command arguments (including the command/executable itself) run by the container. +""" + +CONTAINER_COMMAND_LINE: Final = "container.command_line" +""" +The full command run by the container as a single string representing the full command. +""" + +CONTAINER_CPU_STATE: Final = "container.cpu.state" +""" +Deprecated: Replaced by `cpu.mode`. +""" + +CONTAINER_CSI_PLUGIN_NAME: Final = "container.csi.plugin.name" +""" +The name of the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin used by the volume. +Note: This can sometimes be referred to as a "driver" in CSI implementations. This should represent the `name` field of the GetPluginInfo RPC. +""" + +CONTAINER_CSI_VOLUME_ID: Final = "container.csi.volume.id" +""" +The unique volume ID returned by the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin. +Note: This can sometimes be referred to as a "volume handle" in CSI implementations. This should represent the `Volume.volume_id` field in CSI spec. +""" + +CONTAINER_ID: Final = "container.id" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_ID`. +""" + +CONTAINER_IMAGE_ID: Final = "container.image.id" +""" +Runtime specific image identifier. Usually a hash algorithm followed by a UUID. +Note: Docker defines a sha256 of the image ID; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Container/operation/ContainerInspect) endpoint. +K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. +The ID is assigned by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. +""" + +CONTAINER_IMAGE_NAME: Final = "container.image.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_IMAGE_NAME`. +""" + +CONTAINER_IMAGE_REPO_DIGESTS: Final = "container.image.repo_digests" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_IMAGE_REPO_DIGESTS`. +""" + +CONTAINER_IMAGE_TAGS: Final = "container.image.tags" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_IMAGE_TAGS`. +""" + +CONTAINER_LABEL_TEMPLATE: Final = "container.label" +""" +Container labels, `` being the label name, the value being the label value. +Note: For example, a Docker container label `app` with value `nginx` SHOULD be recorded as the `container.label.app` attribute with value `"nginx"`. +""" + +CONTAINER_LABELS_TEMPLATE: Final = "container.labels" +""" +Deprecated: Replaced by `container.label`. +""" + +CONTAINER_NAME: Final = "container.name" +""" +Container name used by container runtime. +""" + +CONTAINER_RUNTIME: Final = "container.runtime" +""" +Deprecated: Replaced by `container.runtime.name`. +""" + +CONTAINER_RUNTIME_DESCRIPTION: Final = "container.runtime.description" +""" +A description about the runtime which could include, for example details about the CRI/API version being used or other customizations. +""" + +CONTAINER_RUNTIME_NAME: Final = "container.runtime.name" +""" +The container runtime managing this container. +""" + +CONTAINER_RUNTIME_VERSION: Final = "container.runtime.version" +""" +The version of the runtime of this process, as returned by the runtime without modification. +""" + + +@deprecated("The attribute container.cpu.state is deprecated - Replaced by `cpu.mode`") +class ContainerCpuStateValues(Enum): + USER = "user" + """When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows).""" + SYSTEM = "system" + """When CPU is used by the system (host OS).""" + KERNEL = "kernel" + """When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py new file mode 100644 index 00000000000..a2982d549c8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py @@ -0,0 +1,34 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +CPU_LOGICAL_NUMBER: Final = "cpu.logical_number" +""" +The logical CPU number [0..n-1]. +""" + +CPU_MODE: Final = "cpu.mode" +""" +The mode of the CPU. +""" + + +class CpuModeValues(Enum): + USER = "user" + """User.""" + SYSTEM = "system" + """System.""" + NICE = "nice" + """Nice.""" + IDLE = "idle" + """Idle.""" + IOWAIT = "iowait" + """IO Wait.""" + INTERRUPT = "interrupt" + """Interrupt.""" + STEAL = "steal" + """Steal.""" + KERNEL = "kernel" + """Deprecated: Replaced by `system`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py new file mode 100644 index 00000000000..90ef20560af --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py @@ -0,0 +1,19 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +CPYTHON_GC_GENERATION: Final = "cpython.gc.generation" +""" +Value of the garbage collector collection generation. +""" + + +class CPythonGCGenerationValues(Enum): + GENERATION_0 = 0 + """Generation 0.""" + GENERATION_1 = 1 + """Generation 1.""" + GENERATION_2 = 2 + """Generation 2.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py new file mode 100644 index 00000000000..a8ced43e028 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py @@ -0,0 +1,574 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +DB_CASSANDRA_CONSISTENCY_LEVEL: Final = "db.cassandra.consistency_level" +""" +Deprecated: Replaced by `cassandra.consistency.level`. +""" + +DB_CASSANDRA_COORDINATOR_DC: Final = "db.cassandra.coordinator.dc" +""" +Deprecated: Replaced by `cassandra.coordinator.dc`. +""" + +DB_CASSANDRA_COORDINATOR_ID: Final = "db.cassandra.coordinator.id" +""" +Deprecated: Replaced by `cassandra.coordinator.id`. +""" + +DB_CASSANDRA_IDEMPOTENCE: Final = "db.cassandra.idempotence" +""" +Deprecated: Replaced by `cassandra.query.idempotent`. +""" + +DB_CASSANDRA_PAGE_SIZE: Final = "db.cassandra.page_size" +""" +Deprecated: Replaced by `cassandra.page.size`. +""" + +DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT: Final = "db.cassandra.speculative_execution_count" +""" +Deprecated: Replaced by `cassandra.speculative_execution.count`. +""" + +DB_CASSANDRA_TABLE: Final = "db.cassandra.table" +""" +Deprecated: Replaced by `db.collection.name`. +""" + +DB_CLIENT_CONNECTION_POOL_NAME: Final = "db.client.connection.pool.name" +""" +The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation SHOULD use a combination of parameters that would make the name unique, for example, combining attributes `server.address`, `server.port`, and `db.namespace`, formatted as `server.address:server.port/db.namespace`. Instrumentations that generate connection pool name following different patterns SHOULD document it. +""" + +DB_CLIENT_CONNECTION_STATE: Final = "db.client.connection.state" +""" +The state of a connection in the pool. +""" + +DB_CLIENT_CONNECTIONS_POOL_NAME: Final = "db.client.connections.pool.name" +""" +Deprecated: Replaced by `db.client.connection.pool.name`. +""" + +DB_CLIENT_CONNECTIONS_STATE: Final = "db.client.connections.state" +""" +Deprecated: Replaced by `db.client.connection.state`. +""" + +DB_COLLECTION_NAME: Final = "db.collection.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_COLLECTION_NAME`. +""" + +DB_CONNECTION_STRING: Final = "db.connection_string" +""" +Deprecated: Replaced by `server.address` and `server.port`. +""" + +DB_COSMOSDB_CLIENT_ID: Final = "db.cosmosdb.client_id" +""" +Deprecated: Replaced by `azure.client.id`. +""" + +DB_COSMOSDB_CONNECTION_MODE: Final = "db.cosmosdb.connection_mode" +""" +Deprecated: Replaced by `azure.cosmosdb.connection.mode`. +""" + +DB_COSMOSDB_CONSISTENCY_LEVEL: Final = "db.cosmosdb.consistency_level" +""" +Deprecated: Replaced by `azure.cosmosdb.consistency.level`. +""" + +DB_COSMOSDB_CONTAINER: Final = "db.cosmosdb.container" +""" +Deprecated: Replaced by `db.collection.name`. +""" + +DB_COSMOSDB_OPERATION_TYPE: Final = "db.cosmosdb.operation_type" +""" +Deprecated: Removed, no replacement at this time. +""" + +DB_COSMOSDB_REGIONS_CONTACTED: Final = "db.cosmosdb.regions_contacted" +""" +Deprecated: Replaced by `azure.cosmosdb.operation.contacted_regions`. +""" + +DB_COSMOSDB_REQUEST_CHARGE: Final = "db.cosmosdb.request_charge" +""" +Deprecated: Replaced by `azure.cosmosdb.operation.request_charge`. +""" + +DB_COSMOSDB_REQUEST_CONTENT_LENGTH: Final = "db.cosmosdb.request_content_length" +""" +Deprecated: Replaced by `azure.cosmosdb.request.body.size`. +""" + +DB_COSMOSDB_STATUS_CODE: Final = "db.cosmosdb.status_code" +""" +Deprecated: Use `db.response.status_code` instead. +""" + +DB_COSMOSDB_SUB_STATUS_CODE: Final = "db.cosmosdb.sub_status_code" +""" +Deprecated: Replaced by `azure.cosmosdb.response.sub_status_code`. +""" + +DB_ELASTICSEARCH_CLUSTER_NAME: Final = "db.elasticsearch.cluster.name" +""" +Deprecated: Replaced by `db.namespace`. +""" + +DB_ELASTICSEARCH_NODE_NAME: Final = "db.elasticsearch.node.name" +""" +Deprecated: Replaced by `elasticsearch.node.name`. +""" + +DB_ELASTICSEARCH_PATH_PARTS_TEMPLATE: Final = "db.elasticsearch.path_parts" +""" +Deprecated: Replaced by `db.operation.parameter`. +""" + +DB_INSTANCE_ID: Final = "db.instance.id" +""" +Deprecated: Removed, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. +""" + +DB_JDBC_DRIVER_CLASSNAME: Final = "db.jdbc.driver_classname" +""" +Deprecated: Removed, no replacement at this time. +""" + +DB_MONGODB_COLLECTION: Final = "db.mongodb.collection" +""" +Deprecated: Replaced by `db.collection.name`. +""" + +DB_MSSQL_INSTANCE_NAME: Final = "db.mssql.instance_name" +""" +Deprecated: Removed, no replacement at this time. +""" + +DB_NAME: Final = "db.name" +""" +Deprecated: Replaced by `db.namespace`. +""" + +DB_NAMESPACE: Final = "db.namespace" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_NAMESPACE`. +""" + +DB_OPERATION: Final = "db.operation" +""" +Deprecated: Replaced by `db.operation.name`. +""" + +DB_OPERATION_BATCH_SIZE: Final = "db.operation.batch.size" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_OPERATION_BATCH_SIZE`. +""" + +DB_OPERATION_NAME: Final = "db.operation.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_OPERATION_NAME`. +""" + +DB_OPERATION_PARAMETER_TEMPLATE: Final = "db.operation.parameter" +""" +A database operation parameter, with `` being the parameter name, and the attribute value being a string representation of the parameter value. +Note: For example, a client-side maximum number of rows to read from the database +MAY be recorded as the `db.operation.parameter.max_rows` attribute. + +`db.query.text` parameters SHOULD be captured using `db.query.parameter.` +instead of `db.operation.parameter.`. +""" + +DB_QUERY_PARAMETER_TEMPLATE: Final = "db.query.parameter" +""" +A database query parameter, with `` being the parameter name, and the attribute value being a string representation of the parameter value. +Note: If a query parameter has no name and instead is referenced only by index, +then `` SHOULD be the 0-based index. + +`db.query.parameter.` SHOULD match +up with the parameterized placeholders present in `db.query.text`. + +It is RECOMMENDED to capture the value as provided by the application +without attempting to do any case normalization or sanitization. + +Instrumentations SHOULD NOT capture `db.query.parameter.` by default +since values may contain PII or sensitive details. +Application operators are expected to enable specific keys depending +on their privacy and security considerations. + +`db.query.parameter.` SHOULD NOT be captured on batch operations. + +Examples: + +- For a query `SELECT * FROM users where username = %s` with the parameter `"jdoe"`, + the attribute `db.query.parameter.0` SHOULD be set to `"jdoe"`. + +- For a query `"SELECT * FROM users WHERE username = %(userName)s;` with parameter + `userName = "jdoe"`, the attribute `db.query.parameter.userName` SHOULD be set to `"jdoe"`. +""" + +DB_QUERY_SUMMARY: Final = "db.query.summary" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_QUERY_SUMMARY`. +""" + +DB_QUERY_TEXT: Final = "db.query.text" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_QUERY_TEXT`. +""" + +DB_REDIS_DATABASE_INDEX: Final = "db.redis.database_index" +""" +Deprecated: Replaced by `db.namespace` (string). +""" + +DB_RESPONSE_RETURNED_ROWS: Final = "db.response.returned_rows" +""" +Number of rows returned by the operation. +""" + +DB_RESPONSE_STATUS_CODE: Final = "db.response.status_code" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_RESPONSE_STATUS_CODE`. +""" + +DB_SQL_TABLE: Final = "db.sql.table" +""" +Deprecated: Replaced by `db.collection.name`, but only if not extracting the value from `db.query.text`. +""" + +DB_STATEMENT: Final = "db.statement" +""" +Deprecated: Replaced by `db.query.text`. +""" + +DB_STORED_PROCEDURE_NAME: Final = "db.stored_procedure.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_STORED_PROCEDURE_NAME`. +""" + +DB_SYSTEM: Final = "db.system" +""" +Deprecated: Replaced by `db.system.name`. +""" + +DB_SYSTEM_NAME: Final = "db.system.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_SYSTEM_NAME`. +""" + +DB_USER: Final = "db.user" +""" +Deprecated: Removed, no replacement at this time. +""" + + +@deprecated("The attribute db.cassandra.consistency_level is deprecated - Replaced by `cassandra.consistency.level`") +class DbCassandraConsistencyLevelValues(Enum): + ALL = "all" + """all.""" + EACH_QUORUM = "each_quorum" + """each_quorum.""" + QUORUM = "quorum" + """quorum.""" + LOCAL_QUORUM = "local_quorum" + """local_quorum.""" + ONE = "one" + """one.""" + TWO = "two" + """two.""" + THREE = "three" + """three.""" + LOCAL_ONE = "local_one" + """local_one.""" + ANY = "any" + """any.""" + SERIAL = "serial" + """serial.""" + LOCAL_SERIAL = "local_serial" + """local_serial.""" + + +class DbClientConnectionStateValues(Enum): + IDLE = "idle" + """idle.""" + USED = "used" + """used.""" + + +@deprecated("The attribute db.client.connections.state is deprecated - Replaced by `db.client.connection.state`") +class DbClientConnectionsStateValues(Enum): + IDLE = "idle" + """idle.""" + USED = "used" + """used.""" + + +@deprecated("The attribute db.cosmosdb.connection_mode is deprecated - Replaced by `azure.cosmosdb.connection.mode`") +class DbCosmosdbConnectionModeValues(Enum): + GATEWAY = "gateway" + """Gateway (HTTP) connection.""" + DIRECT = "direct" + """Direct connection.""" + + +@deprecated( + "The attribute db.cosmosdb.consistency_level is deprecated - Replaced by `azure.cosmosdb.consistency.level`" +) +class DbCosmosdbConsistencyLevelValues(Enum): + STRONG = "Strong" + """strong.""" + BOUNDED_STALENESS = "BoundedStaleness" + """bounded_staleness.""" + SESSION = "Session" + """session.""" + EVENTUAL = "Eventual" + """eventual.""" + CONSISTENT_PREFIX = "ConsistentPrefix" + """consistent_prefix.""" + + +@deprecated("The attribute db.cosmosdb.operation_type is deprecated - Removed, no replacement at this time") +class DbCosmosdbOperationTypeValues(Enum): + BATCH = "batch" + """batch.""" + CREATE = "create" + """create.""" + DELETE = "delete" + """delete.""" + EXECUTE = "execute" + """execute.""" + EXECUTE_JAVASCRIPT = "execute_javascript" + """execute_javascript.""" + INVALID = "invalid" + """invalid.""" + HEAD = "head" + """head.""" + HEAD_FEED = "head_feed" + """head_feed.""" + PATCH = "patch" + """patch.""" + QUERY = "query" + """query.""" + QUERY_PLAN = "query_plan" + """query_plan.""" + READ = "read" + """read.""" + READ_FEED = "read_feed" + """read_feed.""" + REPLACE = "replace" + """replace.""" + UPSERT = "upsert" + """upsert.""" + + +@deprecated("The attribute db.system is deprecated - Replaced by `db.system.name`") +class DbSystemValues(Enum): + OTHER_SQL = "other_sql" + """Some other SQL database. Fallback only. See notes.""" + ADABAS = "adabas" + """Adabas (Adaptable Database System).""" + CACHE = "cache" + """Deprecated: Replaced by `intersystems_cache`.""" + INTERSYSTEMS_CACHE = "intersystems_cache" + """InterSystems Caché.""" + CASSANDRA = "cassandra" + """Apache Cassandra.""" + CLICKHOUSE = "clickhouse" + """ClickHouse.""" + CLOUDSCAPE = "cloudscape" + """Deprecated: Replaced by `other_sql`.""" + COCKROACHDB = "cockroachdb" + """CockroachDB.""" + COLDFUSION = "coldfusion" + """Deprecated: Obsoleted.""" + COSMOSDB = "cosmosdb" + """Microsoft Azure Cosmos DB.""" + COUCHBASE = "couchbase" + """Couchbase.""" + COUCHDB = "couchdb" + """CouchDB.""" + DB2 = "db2" + """IBM Db2.""" + DERBY = "derby" + """Apache Derby.""" + DYNAMODB = "dynamodb" + """Amazon DynamoDB.""" + EDB = "edb" + """EnterpriseDB.""" + ELASTICSEARCH = "elasticsearch" + """Elasticsearch.""" + FILEMAKER = "filemaker" + """FileMaker.""" + FIREBIRD = "firebird" + """Firebird.""" + FIRSTSQL = "firstsql" + """Deprecated: Replaced by `other_sql`.""" + GEODE = "geode" + """Apache Geode.""" + H2 = "h2" + """H2.""" + HANADB = "hanadb" + """SAP HANA.""" + HBASE = "hbase" + """Apache HBase.""" + HIVE = "hive" + """Apache Hive.""" + HSQLDB = "hsqldb" + """HyperSQL DataBase.""" + INFLUXDB = "influxdb" + """InfluxDB.""" + INFORMIX = "informix" + """Informix.""" + INGRES = "ingres" + """Ingres.""" + INSTANTDB = "instantdb" + """InstantDB.""" + INTERBASE = "interbase" + """InterBase.""" + MARIADB = "mariadb" + """MariaDB.""" + MAXDB = "maxdb" + """SAP MaxDB.""" + MEMCACHED = "memcached" + """Memcached.""" + MONGODB = "mongodb" + """MongoDB.""" + MSSQL = "mssql" + """Microsoft SQL Server.""" + MSSQLCOMPACT = "mssqlcompact" + """Deprecated: Replaced by `other_sql`.""" + MYSQL = "mysql" + """MySQL.""" + NEO4J = "neo4j" + """Neo4j.""" + NETEZZA = "netezza" + """Netezza.""" + OPENSEARCH = "opensearch" + """OpenSearch.""" + ORACLE = "oracle" + """Oracle Database.""" + PERVASIVE = "pervasive" + """Pervasive PSQL.""" + POINTBASE = "pointbase" + """PointBase.""" + POSTGRESQL = "postgresql" + """PostgreSQL.""" + PROGRESS = "progress" + """Progress Database.""" + REDIS = "redis" + """Redis.""" + REDSHIFT = "redshift" + """Amazon Redshift.""" + SPANNER = "spanner" + """Cloud Spanner.""" + SQLITE = "sqlite" + """SQLite.""" + SYBASE = "sybase" + """Sybase.""" + TERADATA = "teradata" + """Teradata.""" + TRINO = "trino" + """Trino.""" + VERTICA = "vertica" + """Vertica.""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues`." +) +class DbSystemNameValues(Enum): + OTHER_SQL = "other_sql" + """Some other SQL database. Fallback only.""" + SOFTWAREAG_ADABAS = "softwareag.adabas" + """[Adabas (Adaptable Database System)](https://documentation.softwareag.com/?pf=adabas).""" + ACTIAN_INGRES = "actian.ingres" + """[Actian Ingres](https://www.actian.com/databases/ingres/).""" + AWS_DYNAMODB = "aws.dynamodb" + """[Amazon DynamoDB](https://aws.amazon.com/pm/dynamodb/).""" + AWS_REDSHIFT = "aws.redshift" + """[Amazon Redshift](https://aws.amazon.com/redshift/).""" + AZURE_COSMOSDB = "azure.cosmosdb" + """[Azure Cosmos DB](https://learn.microsoft.com/azure/cosmos-db).""" + INTERSYSTEMS_CACHE = "intersystems.cache" + """[InterSystems Caché](https://www.intersystems.com/products/cache/).""" + CASSANDRA = "cassandra" + """[Apache Cassandra](https://cassandra.apache.org/).""" + CLICKHOUSE = "clickhouse" + """[ClickHouse](https://clickhouse.com/).""" + COCKROACHDB = "cockroachdb" + """[CockroachDB](https://www.cockroachlabs.com/).""" + COUCHBASE = "couchbase" + """[Couchbase](https://www.couchbase.com/).""" + COUCHDB = "couchdb" + """[Apache CouchDB](https://couchdb.apache.org/).""" + DERBY = "derby" + """[Apache Derby](https://db.apache.org/derby/).""" + ELASTICSEARCH = "elasticsearch" + """[Elasticsearch](https://www.elastic.co/elasticsearch).""" + FIREBIRDSQL = "firebirdsql" + """[Firebird](https://www.firebirdsql.org/).""" + GCP_SPANNER = "gcp.spanner" + """[Google Cloud Spanner](https://cloud.google.com/spanner).""" + GEODE = "geode" + """[Apache Geode](https://geode.apache.org/).""" + H2DATABASE = "h2database" + """[H2 Database](https://h2database.com/).""" + HBASE = "hbase" + """[Apache HBase](https://hbase.apache.org/).""" + HIVE = "hive" + """[Apache Hive](https://hive.apache.org/).""" + HSQLDB = "hsqldb" + """[HyperSQL Database](https://hsqldb.org/).""" + IBM_DB2 = "ibm.db2" + """[IBM Db2](https://www.ibm.com/db2).""" + IBM_INFORMIX = "ibm.informix" + """[IBM Informix](https://www.ibm.com/products/informix).""" + IBM_NETEZZA = "ibm.netezza" + """[IBM Netezza](https://www.ibm.com/products/netezza).""" + INFLUXDB = "influxdb" + """[InfluxDB](https://www.influxdata.com/).""" + INSTANTDB = "instantdb" + """[Instant](https://www.instantdb.com/).""" + MARIADB = "mariadb" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.MARIADB`.""" + MEMCACHED = "memcached" + """[Memcached](https://memcached.org/).""" + MONGODB = "mongodb" + """[MongoDB](https://www.mongodb.com/).""" + MICROSOFT_SQL_SERVER = "microsoft.sql_server" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.MICROSOFT_SQL_SERVER`.""" + MYSQL = "mysql" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.MYSQL`.""" + NEO4J = "neo4j" + """[Neo4j](https://neo4j.com/).""" + OPENSEARCH = "opensearch" + """[OpenSearch](https://opensearch.org/).""" + ORACLE_DB = "oracle.db" + """[Oracle Database](https://www.oracle.com/database/).""" + POSTGRESQL = "postgresql" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.POSTGRESQL`.""" + REDIS = "redis" + """[Redis](https://redis.io/).""" + SAP_HANA = "sap.hana" + """[SAP HANA](https://www.sap.com/products/technology-platform/hana/what-is-sap-hana.html).""" + SAP_MAXDB = "sap.maxdb" + """[SAP MaxDB](https://maxdb.sap.com/).""" + SQLITE = "sqlite" + """[SQLite](https://www.sqlite.org/).""" + TERADATA = "teradata" + """[Teradata](https://www.teradata.com/).""" + TRINO = "trino" + """[Trino](https://trino.io/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py new file mode 100644 index 00000000000..976ff3f2e09 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py @@ -0,0 +1,53 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +DEPLOYMENT_ENVIRONMENT: Final = "deployment.environment" +""" +Deprecated: Replaced by `deployment.environment.name`. +""" + +DEPLOYMENT_ENVIRONMENT_NAME: Final = "deployment.environment.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DEPLOYMENT_ENVIRONMENT_NAME`. +""" + +DEPLOYMENT_ID: Final = "deployment.id" +""" +The ID of the deployment. +""" + +DEPLOYMENT_NAME: Final = "deployment.name" +""" +The name of the deployment. +""" + +DEPLOYMENT_STATUS: Final = "deployment.status" +""" +The status of the deployment. +""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues`." +) +class DeploymentEnvironmentNameValues(Enum): + PRODUCTION = "production" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.PRODUCTION`.""" + STAGING = "staging" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.STAGING`.""" + TEST = "test" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.TEST`.""" + DEVELOPMENT = "development" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.DEVELOPMENT`.""" + + +class DeploymentStatusValues(Enum): + FAILED = "failed" + """failed.""" + SUCCEEDED = "succeeded" + """succeeded.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py new file mode 100644 index 00000000000..40f7de949f0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +DESTINATION_ADDRESS: Final = "destination.address" +""" +Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. +Note: When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. +""" + +DESTINATION_PORT: Final = "destination.port" +""" +Destination port number. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py new file mode 100644 index 00000000000..87dcaaa0b2d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py @@ -0,0 +1,43 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +DEVICE_ID: Final = "device.id" +""" +A unique identifier representing the device. +Note: Its value SHOULD be identical for all apps on a device and it SHOULD NOT change if an app is uninstalled and re-installed. +However, it might be resettable by the user for all apps on a device. +Hardware IDs (e.g. vendor-specific serial number, IMEI or MAC address) MAY be used as values. + +More information about Android identifier best practices can be found in the [Android user data IDs guide](https://developer.android.com/training/articles/user-data-ids). + +> [!WARNING] +> +> This attribute may contain sensitive (PII) information. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, +> ensure you do your own due diligence. +> +> Due to these reasons, this identifier is not recommended for consumer applications and will likely result in rejection from both Google Play and App Store. +> However, it may be appropriate for specific enterprise scenarios, such as kiosk devices or enterprise-managed devices, with appropriate compliance clearance. +> Any instrumentation providing this identifier MUST implement it as an opt-in feature. +> +> See [`app.installation.id`](/docs/registry/attributes/app.md#app-installation-id) for a more privacy-preserving alternative. +""" + +DEVICE_MANUFACTURER: Final = "device.manufacturer" +""" +The name of the device manufacturer. +Note: The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. +""" + +DEVICE_MODEL_IDENTIFIER: Final = "device.model.identifier" +""" +The model identifier for the device. +Note: It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. +""" + +DEVICE_MODEL_NAME: Final = "device.model.name" +""" +The marketing name for the device model. +Note: It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py new file mode 100644 index 00000000000..1e08f412073 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py @@ -0,0 +1,17 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +DISK_IO_DIRECTION: Final = "disk.io.direction" +""" +The disk IO operation direction. +""" + + +class DiskIoDirectionValues(Enum): + READ = "read" + """read.""" + WRITE = "write" + """write.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py new file mode 100644 index 00000000000..83def12b52f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +DNS_ANSWERS: Final = "dns.answers" +""" +The list of IPv4 or IPv6 addresses resolved during DNS lookup. +""" + +DNS_QUESTION_NAME: Final = "dns.question.name" +""" +The name being queried. +Note: The name represents the queried domain name as it appears in the DNS query without any additional normalization. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py new file mode 100644 index 00000000000..86748754ada --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +ELASTICSEARCH_NODE_NAME: Final = "elasticsearch.node.name" +""" +Represents the human-readable identifier of the node/instance to which a request was routed. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py new file mode 100644 index 00000000000..121a2c0ce26 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py @@ -0,0 +1,32 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +ENDUSER_ID: Final = "enduser.id" +""" +Unique identifier of an end user in the system. It maybe a username, email address, or other identifier. +Note: Unique identifier of an end user in the system. + +> [!Warning] +> This field contains sensitive (PII) information. +""" + +ENDUSER_PSEUDO_ID: Final = "enduser.pseudo.id" +""" +Pseudonymous identifier of an end user. This identifier should be a random value that is not directly linked or associated with the end user's actual identity. +Note: Pseudonymous identifier of an end user. + +> [!Warning] +> This field contains sensitive (linkable PII) information. +""" + +ENDUSER_ROLE: Final = "enduser.role" +""" +Deprecated: Use `user.roles` instead. +""" + +ENDUSER_SCOPE: Final = "enduser.scope" +""" +Deprecated: Removed, no replacement at this time. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py new file mode 100644 index 00000000000..6b655daf951 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py @@ -0,0 +1,25 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +ERROR_MESSAGE: Final = "error.message" +""" +Deprecated: Use domain-specific error message attribute. For example, use `feature_flag.error.message` for feature flag errors. +""" + +ERROR_TYPE: Final = "error.type" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ERROR_TYPE`. +""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ErrorTypeValues`." +) +class ErrorTypeValues(Enum): + OTHER = "_OTHER" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ErrorTypeValues.OTHER`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py new file mode 100644 index 00000000000..05f481bbb3e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +EVENT_NAME: Final = "event.name" +""" +Deprecated: The value of this attribute MUST now be set as the value of the EventName field on the LogRecord to indicate that the LogRecord represents an Event. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py new file mode 100644 index 00000000000..efec9363f22 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py @@ -0,0 +1,24 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +EXCEPTION_ESCAPED: Final = "exception.escaped" +""" +Deprecated: It's no longer recommended to record exceptions that are handled and do not escape the scope of a span. +""" + +EXCEPTION_MESSAGE: Final = "exception.message" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_MESSAGE`. +""" + +EXCEPTION_STACKTRACE: Final = "exception.stacktrace" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_STACKTRACE`. +""" + +EXCEPTION_TYPE: Final = "exception.type" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_TYPE`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py new file mode 100644 index 00000000000..21a0b6f91ea --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py @@ -0,0 +1,150 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +FAAS_COLDSTART: Final = "faas.coldstart" +""" +A boolean that is true if the serverless function is executed for the first time (aka cold-start). +""" + +FAAS_CRON: Final = "faas.cron" +""" +A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). +""" + +FAAS_DOCUMENT_COLLECTION: Final = "faas.document.collection" +""" +The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. +""" + +FAAS_DOCUMENT_NAME: Final = "faas.document.name" +""" +The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. +""" + +FAAS_DOCUMENT_OPERATION: Final = "faas.document.operation" +""" +Describes the type of the operation that was performed on the data. +""" + +FAAS_DOCUMENT_TIME: Final = "faas.document.time" +""" +A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). +""" + +FAAS_INSTANCE: Final = "faas.instance" +""" +The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. +Note: - **AWS Lambda:** Use the (full) log stream name. +""" + +FAAS_INVOCATION_ID: Final = "faas.invocation_id" +""" +The invocation ID of the current function invocation. +""" + +FAAS_INVOKED_NAME: Final = "faas.invoked_name" +""" +The name of the invoked function. +Note: SHOULD be equal to the `faas.name` resource attribute of the invoked function. +""" + +FAAS_INVOKED_PROVIDER: Final = "faas.invoked_provider" +""" +The cloud provider of the invoked function. +Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked function. +""" + +FAAS_INVOKED_REGION: Final = "faas.invoked_region" +""" +The cloud region of the invoked function. +Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked function. +""" + +FAAS_MAX_MEMORY: Final = "faas.max_memory" +""" +The amount of memory available to the serverless function converted to Bytes. +Note: It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). +""" + +FAAS_NAME: Final = "faas.name" +""" +The name of the single function that this runtime instance executes. +Note: This is the name of the function as configured/deployed on the FaaS +platform and is usually different from the name of the callback +function (which may be stored in the +[`code.namespace`/`code.function.name`](/docs/general/attributes.md#source-code-attributes) +span attributes). + +For some cloud providers, the above definition is ambiguous. The following +definition of function name MUST be used for this attribute +(and consequently the span name) for the listed cloud providers/products: + +- **Azure:** The full name `/`, i.e., function app name + followed by a forward slash followed by the function name (this form + can also be seen in the resource JSON for the function). + This means that a span attribute MUST be used, as an Azure function + app can host multiple functions that would usually share + a TracerProvider (see also the `cloud.resource_id` attribute). +""" + +FAAS_TIME: Final = "faas.time" +""" +A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). +""" + +FAAS_TRIGGER: Final = "faas.trigger" +""" +Type of the trigger which caused this function invocation. +""" + +FAAS_VERSION: Final = "faas.version" +""" +The immutable version of the function being executed. +Note: Depending on the cloud provider and platform, use: + +- **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) + (an integer represented as a decimal string). +- **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) + (i.e., the function name plus the revision suffix). +- **Google Cloud Functions:** The value of the + [`K_REVISION` environment variable](https://cloud.google.com/run/docs/container-contract#services-env-vars). +- **Azure Functions:** Not applicable. Do not set this attribute. +""" + + +class FaasDocumentOperationValues(Enum): + INSERT = "insert" + """When a new object is created.""" + EDIT = "edit" + """When an object is modified.""" + DELETE = "delete" + """When an object is deleted.""" + + +class FaasInvokedProviderValues(Enum): + ALIBABA_CLOUD = "alibaba_cloud" + """Alibaba Cloud.""" + AWS = "aws" + """Amazon Web Services.""" + AZURE = "azure" + """Microsoft Azure.""" + GCP = "gcp" + """Google Cloud Platform.""" + TENCENT_CLOUD = "tencent_cloud" + """Tencent Cloud.""" + + +class FaasTriggerValues(Enum): + DATASOURCE = "datasource" + """A response to some data source operation such as a database or filesystem read/write.""" + HTTP = "http" + """To provide an answer to an inbound HTTP request.""" + PUBSUB = "pubsub" + """A function is set to be executed when messages are sent to a messaging system.""" + TIMER = "timer" + """A function is scheduled to be executed regularly.""" + OTHER = "other" + """If none of the others apply.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py new file mode 100644 index 00000000000..97673108395 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py @@ -0,0 +1,119 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +FEATURE_FLAG_CONTEXT_ID: Final = "feature_flag.context.id" +""" +The unique identifier for the flag evaluation context. For example, the targeting key. +""" + +FEATURE_FLAG_ERROR_MESSAGE: Final = "feature_flag.error.message" +""" +A message providing more detail about an error that occurred during feature flag evaluation in human-readable form. +""" + +FEATURE_FLAG_EVALUATION_ERROR_MESSAGE: Final = "feature_flag.evaluation.error.message" +""" +Deprecated: Replaced by `feature_flag.error.message`. +""" + +FEATURE_FLAG_EVALUATION_REASON: Final = "feature_flag.evaluation.reason" +""" +Deprecated: Replaced by `feature_flag.result.reason`. +""" + +FEATURE_FLAG_KEY: Final = "feature_flag.key" +""" +The lookup key of the feature flag. +""" + +FEATURE_FLAG_PROVIDER_NAME: Final = "feature_flag.provider.name" +""" +Identifies the feature flag provider. +""" + +FEATURE_FLAG_RESULT_REASON: Final = "feature_flag.result.reason" +""" +The reason code which shows how a feature flag value was determined. +""" + +FEATURE_FLAG_RESULT_VALUE: Final = "feature_flag.result.value" +""" +The evaluated value of the feature flag. +Note: With some feature flag providers, feature flag results can be quite large or contain private or sensitive details. +Because of this, `feature_flag.result.variant` is often the preferred attribute if it is available. + +It may be desirable to redact or otherwise limit the size and scope of `feature_flag.result.value` if possible. +Because the evaluated flag value is unstructured and may be any type, it is left to the instrumentation author to determine how best to achieve this. +""" + +FEATURE_FLAG_RESULT_VARIANT: Final = "feature_flag.result.variant" +""" +A semantic identifier for an evaluated flag value. +Note: A semantic identifier, commonly referred to as a variant, provides a means +for referring to a value without including the value itself. This can +provide additional context for understanding the meaning behind a value. +For example, the variant `red` maybe be used for the value `#c05543`. +""" + +FEATURE_FLAG_SET_ID: Final = "feature_flag.set.id" +""" +The identifier of the [flag set](https://openfeature.dev/specification/glossary/#flag-set) to which the feature flag belongs. +""" + +FEATURE_FLAG_VARIANT: Final = "feature_flag.variant" +""" +Deprecated: Replaced by `feature_flag.result.variant`. +""" + +FEATURE_FLAG_VERSION: Final = "feature_flag.version" +""" +The version of the ruleset used during the evaluation. This may be any stable value which uniquely identifies the ruleset. +""" + + +@deprecated("The attribute feature_flag.evaluation.reason is deprecated - Replaced by `feature_flag.result.reason`") +class FeatureFlagEvaluationReasonValues(Enum): + STATIC = "static" + """The resolved value is static (no dynamic evaluation).""" + DEFAULT = "default" + """The resolved value fell back to a pre-configured value (no dynamic evaluation occurred or dynamic evaluation yielded no result).""" + TARGETING_MATCH = "targeting_match" + """The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.""" + SPLIT = "split" + """The resolved value was the result of pseudorandom assignment.""" + CACHED = "cached" + """The resolved value was retrieved from cache.""" + DISABLED = "disabled" + """The resolved value was the result of the flag being disabled in the management system.""" + UNKNOWN = "unknown" + """The reason for the resolved value could not be determined.""" + STALE = "stale" + """The resolved value is non-authoritative or possibly out of date.""" + ERROR = "error" + """The resolved value was the result of an error.""" + + +class FeatureFlagResultReasonValues(Enum): + STATIC = "static" + """The resolved value is static (no dynamic evaluation).""" + DEFAULT = "default" + """The resolved value fell back to a pre-configured value (no dynamic evaluation occurred or dynamic evaluation yielded no result).""" + TARGETING_MATCH = "targeting_match" + """The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.""" + SPLIT = "split" + """The resolved value was the result of pseudorandom assignment.""" + CACHED = "cached" + """The resolved value was retrieved from cache.""" + DISABLED = "disabled" + """The resolved value was the result of the flag being disabled in the management system.""" + UNKNOWN = "unknown" + """The reason for the resolved value could not be determined.""" + STALE = "stale" + """The resolved value is non-authoritative or possibly out of date.""" + ERROR = "error" + """The resolved value was the result of an error.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py new file mode 100644 index 00000000000..f84f0ea3616 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py @@ -0,0 +1,125 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +FILE_ACCESSED: Final = "file.accessed" +""" +Time when the file was last accessed, in ISO 8601 format. +Note: This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. +""" + +FILE_ATTRIBUTES: Final = "file.attributes" +""" +Array of file attributes. +Note: Attributes names depend on the OS or file system. Here’s a non-exhaustive list of values expected for this attribute: `archive`, `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`, `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`, `write`. +""" + +FILE_CHANGED: Final = "file.changed" +""" +Time when the file attributes or metadata was last changed, in ISO 8601 format. +Note: `file.changed` captures the time when any of the file's properties or attributes (including the content) are changed, while `file.modified` captures the timestamp when the file content is modified. +""" + +FILE_CREATED: Final = "file.created" +""" +Time when the file was created, in ISO 8601 format. +Note: This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. +""" + +FILE_DIRECTORY: Final = "file.directory" +""" +Directory where the file is located. It should include the drive letter, when appropriate. +""" + +FILE_EXTENSION: Final = "file.extension" +""" +File extension, excluding the leading dot. +Note: When the filename has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). +""" + +FILE_FORK_NAME: Final = "file.fork_name" +""" +Name of the fork. A fork is additional data associated with a filesystem object. +Note: On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at least one fork for the data portion, and additional forks may exist. +On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the internet. An ADS is typically of the form: C:\\path\\to\\filename.extension:some_fork_name, and some_fork_name is the value that should populate `fork_name`. `filename.extension` should populate `file.name`, and `extension` should populate `file.extension`. The full path, `file.path`, will include the fork name. +""" + +FILE_GROUP_ID: Final = "file.group.id" +""" +Primary Group ID (GID) of the file. +""" + +FILE_GROUP_NAME: Final = "file.group.name" +""" +Primary group name of the file. +""" + +FILE_INODE: Final = "file.inode" +""" +Inode representing the file in the filesystem. +""" + +FILE_LOCK_MECHANISM: Final = "file.lock.mechanism" +""" +The lock mechanism such as noted by [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html). +""" + +FILE_LOCK_MODE: Final = "file.lock.mode" +""" +Mode of lock or operation such as documented by [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html). +""" + +FILE_LOCK_TYPE: Final = "file.lock.type" +""" +The lock type as represented by i.e. [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html)'s l_type. +""" + +FILE_MODE: Final = "file.mode" +""" +Mode of the file in octal representation. +""" + +FILE_MODIFIED: Final = "file.modified" +""" +Time when the file content was last modified, in ISO 8601 format. +""" + +FILE_NAME: Final = "file.name" +""" +Name of the file including the extension, without the directory. +""" + +FILE_OWNER_ID: Final = "file.owner.id" +""" +The user ID (UID) or security identifier (SID) of the file owner. +""" + +FILE_OWNER_NAME: Final = "file.owner.name" +""" +Username of the file owner. +""" + +FILE_PATH: Final = "file.path" +""" +Full path to the file, including the filename. It should include the drive letter, when appropriate. +""" + +FILE_SIZE: Final = "file.size" +""" +File size in bytes. +""" + +FILE_SYMBOLIC_LINK_TARGET_PATH: Final = "file.symbolic_link.target_path" +""" +Path to the target of a symbolic link. +Note: This attribute is only applicable to symbolic links. +""" + + +class FileLockTypeValues(Enum): + READ = "read" + """read.""" + WRITE = "write" + """write.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py new file mode 100644 index 00000000000..b472e4cea5b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py @@ -0,0 +1,234 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +GCP_APPHUB_APPLICATION_CONTAINER: Final = "gcp.apphub.application.container" +""" +The container within GCP where the AppHub application is defined. +""" + +GCP_APPHUB_APPLICATION_ID: Final = "gcp.apphub.application.id" +""" +The name of the application as configured in AppHub. +""" + +GCP_APPHUB_APPLICATION_LOCATION: Final = "gcp.apphub.application.location" +""" +The GCP zone or region where the application is defined. +""" + +GCP_APPHUB_SERVICE_CRITICALITY_TYPE: Final = "gcp.apphub.service.criticality_type" +""" +Criticality of a service indicates its importance to the business. +Note: [See AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). +""" + +GCP_APPHUB_SERVICE_ENVIRONMENT_TYPE: Final = "gcp.apphub.service.environment_type" +""" +Environment of a service is the stage of a software lifecycle. +Note: [See AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). +""" + +GCP_APPHUB_SERVICE_ID: Final = "gcp.apphub.service.id" +""" +The name of the service as configured in AppHub. +""" + +GCP_APPHUB_WORKLOAD_CRITICALITY_TYPE: Final = "gcp.apphub.workload.criticality_type" +""" +Criticality of a workload indicates its importance to the business. +Note: [See AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). +""" + +GCP_APPHUB_WORKLOAD_ENVIRONMENT_TYPE: Final = "gcp.apphub.workload.environment_type" +""" +Environment of a workload is the stage of a software lifecycle. +Note: [See AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). +""" + +GCP_APPHUB_WORKLOAD_ID: Final = "gcp.apphub.workload.id" +""" +The name of the workload as configured in AppHub. +""" + +GCP_APPHUB_DESTINATION_APPLICATION_CONTAINER: Final = "gcp.apphub_destination.application.container" +""" +The container within GCP where the AppHub destination application is defined. +""" + +GCP_APPHUB_DESTINATION_APPLICATION_ID: Final = "gcp.apphub_destination.application.id" +""" +The name of the destination application as configured in AppHub. +""" + +GCP_APPHUB_DESTINATION_APPLICATION_LOCATION: Final = "gcp.apphub_destination.application.location" +""" +The GCP zone or region where the destination application is defined. +""" + +GCP_APPHUB_DESTINATION_SERVICE_CRITICALITY_TYPE: Final = "gcp.apphub_destination.service.criticality_type" +""" +Criticality of a destination workload indicates its importance to the business as specified in [AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). +""" + +GCP_APPHUB_DESTINATION_SERVICE_ENVIRONMENT_TYPE: Final = "gcp.apphub_destination.service.environment_type" +""" +Software lifecycle stage of a destination service as defined [AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). +""" + +GCP_APPHUB_DESTINATION_SERVICE_ID: Final = "gcp.apphub_destination.service.id" +""" +The name of the destination service as configured in AppHub. +""" + +GCP_APPHUB_DESTINATION_WORKLOAD_CRITICALITY_TYPE: Final = "gcp.apphub_destination.workload.criticality_type" +""" +Criticality of a destination workload indicates its importance to the business as specified in [AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). +""" + +GCP_APPHUB_DESTINATION_WORKLOAD_ENVIRONMENT_TYPE: Final = "gcp.apphub_destination.workload.environment_type" +""" +Environment of a destination workload is the stage of a software lifecycle as provided in the [AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). +""" + +GCP_APPHUB_DESTINATION_WORKLOAD_ID: Final = "gcp.apphub_destination.workload.id" +""" +The name of the destination workload as configured in AppHub. +""" + +GCP_CLIENT_SERVICE: Final = "gcp.client.service" +""" +Identifies the Google Cloud service for which the official client library is intended. +Note: Intended to be a stable identifier for Google Cloud client libraries that is uniform across implementation languages. The value should be derived from the canonical service domain for the service; for example, 'foo.googleapis.com' should result in a value of 'foo'. +""" + +GCP_CLOUD_RUN_JOB_EXECUTION: Final = "gcp.cloud_run.job.execution" +""" +The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. +""" + +GCP_CLOUD_RUN_JOB_TASK_INDEX: Final = "gcp.cloud_run.job.task_index" +""" +The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. +""" + +GCP_GCE_INSTANCE_HOSTNAME: Final = "gcp.gce.instance.hostname" +""" +The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). +""" + +GCP_GCE_INSTANCE_LABELS_TEMPLATE: Final = "gcp.gce.instance.labels" +""" +GCE instance labels, `` being the label name and the value being the label value. +Note: For example, a GCE instance label `team` with value `observability` SHOULD be recorded as the `gcp.gce.instance.labels.team` attribute with value `"observability"`. The `` MUST be the exact GCE instance label key. +""" + +GCP_GCE_INSTANCE_NAME: Final = "gcp.gce.instance.name" +""" +The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). +""" + +GCP_GCE_INSTANCE_GROUP_MANAGER_NAME: Final = "gcp.gce.instance_group_manager.name" +""" +The name of the Instance Group Manager (IGM) that manages this VM, if any. +""" + +GCP_GCE_INSTANCE_GROUP_MANAGER_REGION: Final = "gcp.gce.instance_group_manager.region" +""" +The region of a **regional** Instance Group Manager (e.g., `us-central1`). Set this **only** when the IGM is regional. +""" + +GCP_GCE_INSTANCE_GROUP_MANAGER_ZONE: Final = "gcp.gce.instance_group_manager.zone" +""" +The zone of a **zonal** Instance Group Manager (e.g., `us-central1-a`). Set this **only** when the IGM is zonal. +""" + + +class GcpApphubServiceCriticalityTypeValues(Enum): + MISSION_CRITICAL = "MISSION_CRITICAL" + """Mission critical service.""" + HIGH = "HIGH" + """High impact.""" + MEDIUM = "MEDIUM" + """Medium impact.""" + LOW = "LOW" + """Low impact.""" + + +class GcpApphubServiceEnvironmentTypeValues(Enum): + PRODUCTION = "PRODUCTION" + """Production environment.""" + STAGING = "STAGING" + """Staging environment.""" + TEST = "TEST" + """Test environment.""" + DEVELOPMENT = "DEVELOPMENT" + """Development environment.""" + + +class GcpApphubWorkloadCriticalityTypeValues(Enum): + MISSION_CRITICAL = "MISSION_CRITICAL" + """Mission critical service.""" + HIGH = "HIGH" + """High impact.""" + MEDIUM = "MEDIUM" + """Medium impact.""" + LOW = "LOW" + """Low impact.""" + + +class GcpApphubWorkloadEnvironmentTypeValues(Enum): + PRODUCTION = "PRODUCTION" + """Production environment.""" + STAGING = "STAGING" + """Staging environment.""" + TEST = "TEST" + """Test environment.""" + DEVELOPMENT = "DEVELOPMENT" + """Development environment.""" + + +class GcpApphubDestinationServiceCriticalityTypeValues(Enum): + MISSION_CRITICAL = "MISSION_CRITICAL" + """Mission critical service.""" + HIGH = "HIGH" + """High impact.""" + MEDIUM = "MEDIUM" + """Medium impact.""" + LOW = "LOW" + """Low impact.""" + + +class GcpApphubDestinationServiceEnvironmentTypeValues(Enum): + PRODUCTION = "PRODUCTION" + """Production environment.""" + STAGING = "STAGING" + """Staging environment.""" + TEST = "TEST" + """Test environment.""" + DEVELOPMENT = "DEVELOPMENT" + """Development environment.""" + + +class GcpApphubDestinationWorkloadCriticalityTypeValues(Enum): + MISSION_CRITICAL = "MISSION_CRITICAL" + """Mission critical service.""" + HIGH = "HIGH" + """High impact.""" + MEDIUM = "MEDIUM" + """Medium impact.""" + LOW = "LOW" + """Low impact.""" + + +class GcpApphubDestinationWorkloadEnvironmentTypeValues(Enum): + PRODUCTION = "PRODUCTION" + """Production environment.""" + STAGING = "STAGING" + """Staging environment.""" + TEST = "TEST" + """Test environment.""" + DEVELOPMENT = "DEVELOPMENT" + """Development environment.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py new file mode 100644 index 00000000000..6bab43dd254 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py @@ -0,0 +1,459 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +GEN_AI_AGENT_DESCRIPTION: Final = "gen_ai.agent.description" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_AGENT_ID: Final = "gen_ai.agent.id" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_AGENT_NAME: Final = "gen_ai.agent.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_AGENT_VERSION: Final = "gen_ai.agent.version" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_COMPLETION: Final = "gen_ai.completion" +""" +Deprecated: Removed, no replacement at this time. +""" + +GEN_AI_CONVERSATION_ID: Final = "gen_ai.conversation.id" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_DATA_SOURCE_ID: Final = "gen_ai.data_source.id" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_EMBEDDINGS_DIMENSION_COUNT: Final = "gen_ai.embeddings.dimension.count" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_EVALUATION_EXPLANATION: Final = "gen_ai.evaluation.explanation" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_EVALUATION_NAME: Final = "gen_ai.evaluation.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_EVALUATION_SCORE_LABEL: Final = "gen_ai.evaluation.score.label" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_EVALUATION_SCORE_VALUE: Final = "gen_ai.evaluation.score.value" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_INPUT_MESSAGES: Final = "gen_ai.input.messages" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: Final = "gen_ai.openai.request.response_format" +""" +Deprecated: Replaced by `gen_ai.output.type`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OPENAI_REQUEST_SEED: Final = "gen_ai.openai.request.seed" +""" +Deprecated: Replaced by `gen_ai.request.seed`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OPENAI_REQUEST_SERVICE_TIER: Final = "gen_ai.openai.request.service_tier" +""" +Deprecated: Replaced by `openai.request.service_tier`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OPENAI_RESPONSE_SERVICE_TIER: Final = "gen_ai.openai.response.service_tier" +""" +Deprecated: Replaced by `openai.response.service_tier`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OPENAI_RESPONSE_SYSTEM_FINGERPRINT: Final = "gen_ai.openai.response.system_fingerprint" +""" +Deprecated: Replaced by `openai.response.system_fingerprint`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OPERATION_NAME: Final = "gen_ai.operation.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OUTPUT_MESSAGES: Final = "gen_ai.output.messages" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_OUTPUT_TYPE: Final = "gen_ai.output.type" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_PROMPT: Final = "gen_ai.prompt" +""" +Deprecated: Removed, no replacement at this time. +""" + +GEN_AI_PROMPT_NAME: Final = "gen_ai.prompt.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_PROVIDER_NAME: Final = "gen_ai.provider.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_CHOICE_COUNT: Final = "gen_ai.request.choice.count" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_ENCODING_FORMATS: Final = "gen_ai.request.encoding_formats" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_FREQUENCY_PENALTY: Final = "gen_ai.request.frequency_penalty" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_MAX_TOKENS: Final = "gen_ai.request.max_tokens" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_MODEL: Final = "gen_ai.request.model" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_PRESENCE_PENALTY: Final = "gen_ai.request.presence_penalty" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_SEED: Final = "gen_ai.request.seed" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_STOP_SEQUENCES: Final = "gen_ai.request.stop_sequences" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_STREAM: Final = "gen_ai.request.stream" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_TEMPERATURE: Final = "gen_ai.request.temperature" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_TOP_K: Final = "gen_ai.request.top_k" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_REQUEST_TOP_P: Final = "gen_ai.request.top_p" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_RESPONSE_FINISH_REASONS: Final = "gen_ai.response.finish_reasons" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_RESPONSE_ID: Final = "gen_ai.response.id" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_RESPONSE_MODEL: Final = "gen_ai.response.model" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_RESPONSE_TIME_TO_FIRST_CHUNK: Final = "gen_ai.response.time_to_first_chunk" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_RETRIEVAL_DOCUMENTS: Final = "gen_ai.retrieval.documents" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_RETRIEVAL_QUERY_TEXT: Final = "gen_ai.retrieval.query.text" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_SYSTEM: Final = "gen_ai.system" +""" +Deprecated: Replaced by `gen_ai.provider.name`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_SYSTEM_INSTRUCTIONS: Final = "gen_ai.system_instructions" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOKEN_TYPE: Final = "gen_ai.token.type" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOOL_CALL_ARGUMENTS: Final = "gen_ai.tool.call.arguments" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOOL_CALL_ID: Final = "gen_ai.tool.call.id" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOOL_CALL_RESULT: Final = "gen_ai.tool.call.result" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOOL_DEFINITIONS: Final = "gen_ai.tool.definitions" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOOL_DESCRIPTION: Final = "gen_ai.tool.description" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOOL_NAME: Final = "gen_ai.tool.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_TOOL_TYPE: Final = "gen_ai.tool.type" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS: Final = "gen_ai.usage.cache_creation.input_tokens" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS: Final = "gen_ai.usage.cache_read.input_tokens" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_USAGE_COMPLETION_TOKENS: Final = "gen_ai.usage.completion_tokens" +""" +Deprecated: Replaced by `gen_ai.usage.output_tokens`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_USAGE_INPUT_TOKENS: Final = "gen_ai.usage.input_tokens" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_USAGE_OUTPUT_TOKENS: Final = "gen_ai.usage.output_tokens" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_USAGE_PROMPT_TOKENS: Final = "gen_ai.usage.prompt_tokens" +""" +Deprecated: Replaced by `gen_ai.usage.input_tokens`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_USAGE_REASONING_OUTPUT_TOKENS: Final = "gen_ai.usage.reasoning.output_tokens" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +GEN_AI_WORKFLOW_NAME: Final = "gen_ai.workflow.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +@deprecated( + "The attribute gen_ai.openai.request.response_format is deprecated - Replaced by `gen_ai.output.type`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class GenAiOpenaiRequestResponseFormatValues(Enum): + TEXT = "text" + """Text response format.""" + JSON_OBJECT = "json_object" + """JSON object response format.""" + JSON_SCHEMA = "json_schema" + """JSON schema response format.""" + + +@deprecated( + "The attribute gen_ai.openai.request.service_tier is deprecated - Replaced by `openai.request.service_tier`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class GenAiOpenaiRequestServiceTierValues(Enum): + AUTO = "auto" + """The system will utilize scale tier credits until they are exhausted.""" + DEFAULT = "default" + """The system will utilize the default scale tier.""" + + +@deprecated( + "The attribute gen_ai.operation.name is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class GenAiOperationNameValues(Enum): + CHAT = "chat" + """Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat).""" + GENERATE_CONTENT = "generate_content" + """Multimodal content generation operation such as [Gemini Generate Content](https://ai.google.dev/api/generate-content).""" + TEXT_COMPLETION = "text_completion" + """Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions).""" + EMBEDDINGS = "embeddings" + """Embeddings operation such as [OpenAI Create embeddings API](https://platform.openai.com/docs/api-reference/embeddings/create).""" + RETRIEVAL = "retrieval" + """Retrieval operation such as [OpenAI Search Vector Store API](https://platform.openai.com/docs/api-reference/vector-stores/search).""" + CREATE_AGENT = "create_agent" + """Create GenAI agent.""" + INVOKE_AGENT = "invoke_agent" + """Invoke GenAI agent.""" + EXECUTE_TOOL = "execute_tool" + """Execute a tool.""" + INVOKE_WORKFLOW = "invoke_workflow" + """Invoke GenAI workflow.""" + + +@deprecated( + "The attribute gen_ai.output.type is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class GenAiOutputTypeValues(Enum): + TEXT = "text" + """Plain text.""" + JSON = "json" + """JSON object with known or unknown schema.""" + IMAGE = "image" + """Image.""" + SPEECH = "speech" + """Speech.""" + + +@deprecated( + "The attribute gen_ai.provider.name is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class GenAiProviderNameValues(Enum): + OPENAI = "openai" + """[OpenAI](https://openai.com/).""" + GCP_GEN_AI = "gcp.gen_ai" + """Any Google generative AI endpoint.""" + GCP_VERTEX_AI = "gcp.vertex_ai" + """[Vertex AI](https://cloud.google.com/vertex-ai).""" + GCP_GEMINI = "gcp.gemini" + """[Gemini](https://cloud.google.com/products/gemini).""" + ANTHROPIC = "anthropic" + """[Anthropic](https://www.anthropic.com/).""" + COHERE = "cohere" + """[Cohere](https://cohere.com/).""" + AZURE_AI_INFERENCE = "azure.ai.inference" + """Azure AI Inference.""" + AZURE_AI_OPENAI = "azure.ai.openai" + """[Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/overview).""" + IBM_WATSONX_AI = "ibm.watsonx.ai" + """[IBM Watsonx AI](https://www.ibm.com/products/watsonx-ai).""" + AWS_BEDROCK = "aws.bedrock" + """[AWS Bedrock](https://aws.amazon.com/bedrock).""" + PERPLEXITY = "perplexity" + """[Perplexity](https://www.perplexity.ai/).""" + X_AI = "x_ai" + """[xAI](https://x.ai/).""" + DEEPSEEK = "deepseek" + """[DeepSeek](https://www.deepseek.com/).""" + GROQ = "groq" + """[Groq](https://groq.com/).""" + MISTRAL_AI = "mistral_ai" + """[Mistral AI](https://mistral.ai/).""" + + +@deprecated( + "The attribute gen_ai.system is deprecated - Replaced by `gen_ai.provider.name`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class GenAiSystemValues(Enum): + OPENAI = "openai" + """OpenAI.""" + GCP_GEN_AI = "gcp.gen_ai" + """Any Google generative AI endpoint.""" + GCP_VERTEX_AI = "gcp.vertex_ai" + """Vertex AI.""" + GCP_GEMINI = "gcp.gemini" + """Gemini.""" + VERTEX_AI = "vertex_ai" + """Deprecated: Replaced by `gcp.vertex_ai`.""" + GEMINI = "gemini" + """Deprecated: Replaced by `gcp.gemini`.""" + ANTHROPIC = "anthropic" + """Anthropic.""" + COHERE = "cohere" + """Cohere.""" + AZ_AI_INFERENCE = "az.ai.inference" + """Deprecated: Replaced by `azure.ai.inference`.""" + AZ_AI_OPENAI = "az.ai.openai" + """Deprecated: Replaced by `azure.ai.openai`.""" + AZURE_AI_INFERENCE = "azure.ai.inference" + """Azure AI Inference.""" + AZURE_AI_OPENAI = "azure.ai.openai" + """Azure OpenAI.""" + IBM_WATSONX_AI = "ibm.watsonx.ai" + """IBM Watsonx AI.""" + AWS_BEDROCK = "aws.bedrock" + """AWS Bedrock.""" + PERPLEXITY = "perplexity" + """Perplexity.""" + XAI = "xai" + """xAI.""" + DEEPSEEK = "deepseek" + """DeepSeek.""" + GROQ = "groq" + """Groq.""" + MISTRAL_AI = "mistral_ai" + """Mistral AI.""" + + +@deprecated( + "The attribute gen_ai.token.type is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class GenAiTokenTypeValues(Enum): + INPUT = "input" + """Input tokens (prompt, input, etc.).""" + COMPLETION = "output" + """Deprecated: Replaced by `output`.""" + OUTPUT = "output" + """Output tokens (completion, response, etc.).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py new file mode 100644 index 00000000000..a32cfdda069 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py @@ -0,0 +1,57 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +GEO_CONTINENT_CODE: Final = "geo.continent.code" +""" +Two-letter code representing continent’s name. +""" + +GEO_COUNTRY_ISO_CODE: Final = "geo.country.iso_code" +""" +Two-letter ISO Country Code ([ISO 3166-1 alpha2](https://wikipedia.org/wiki/ISO_3166-1#Codes)). +""" + +GEO_LOCALITY_NAME: Final = "geo.locality.name" +""" +Locality name. Represents the name of a city, town, village, or similar populated place. +""" + +GEO_LOCATION_LAT: Final = "geo.location.lat" +""" +Latitude of the geo location in [WGS84](https://wikipedia.org/wiki/World_Geodetic_System#WGS84). +""" + +GEO_LOCATION_LON: Final = "geo.location.lon" +""" +Longitude of the geo location in [WGS84](https://wikipedia.org/wiki/World_Geodetic_System#WGS84). +""" + +GEO_POSTAL_CODE: Final = "geo.postal_code" +""" +Postal code associated with the location. Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. +""" + +GEO_REGION_ISO_CODE: Final = "geo.region.iso_code" +""" +Region ISO code ([ISO 3166-2](https://wikipedia.org/wiki/ISO_3166-2)). +""" + + +class GeoContinentCodeValues(Enum): + AF = "AF" + """Africa.""" + AN = "AN" + """Antarctica.""" + AS = "AS" + """Asia.""" + EU = "EU" + """Europe.""" + NA = "NA" + """North America.""" + OC = "OC" + """Oceania.""" + SA = "SA" + """South America.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py new file mode 100644 index 00000000000..83c0d672740 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py @@ -0,0 +1,30 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +GRAPHQL_DOCUMENT: Final = "graphql.document" +""" +The GraphQL document being executed. +Note: If instrumentation can reliably identify and redact sensitive information it SHOULD do it. +""" + +GRAPHQL_OPERATION_NAME: Final = "graphql.operation.name" +""" +The name of the operation being executed. +""" + +GRAPHQL_OPERATION_TYPE: Final = "graphql.operation.type" +""" +The type of the operation being executed. +""" + + +class GraphqlOperationTypeValues(Enum): + QUERY = "query" + """GraphQL query.""" + MUTATION = "mutation" + """GraphQL mutation.""" + SUBSCRIPTION = "subscription" + """GraphQL subscription.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py new file mode 100644 index 00000000000..2de0654dc65 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py @@ -0,0 +1,19 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +HEROKU_APP_ID: Final = "heroku.app.id" +""" +Unique identifier for the application. +""" + +HEROKU_RELEASE_COMMIT: Final = "heroku.release.commit" +""" +Commit hash for the current release. +""" + +HEROKU_RELEASE_CREATION_TIMESTAMP: Final = "heroku.release.creation_timestamp" +""" +Time and date the release was created. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py new file mode 100644 index 00000000000..0bf5391eac0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py @@ -0,0 +1,102 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +HOST_ARCH: Final = "host.arch" +""" +The CPU architecture the host system is running on. +""" + +HOST_CPU_CACHE_L2_SIZE: Final = "host.cpu.cache.l2.size" +""" +The amount of level 2 memory cache available to the processor (in Bytes). +""" + +HOST_CPU_FAMILY: Final = "host.cpu.family" +""" +Family or generation of the CPU. +""" + +HOST_CPU_MODEL_ID: Final = "host.cpu.model.id" +""" +Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. +""" + +HOST_CPU_MODEL_NAME: Final = "host.cpu.model.name" +""" +Model designation of the processor. +""" + +HOST_CPU_STEPPING: Final = "host.cpu.stepping" +""" +Stepping or core revisions. +""" + +HOST_CPU_VENDOR_ID: Final = "host.cpu.vendor.id" +""" +Processor manufacturer identifier. A maximum 12-character string. +Note: [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. +""" + +HOST_ID: Final = "host.id" +""" +Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. +""" + +HOST_IMAGE_ID: Final = "host.image.id" +""" +VM image ID or host OS image ID. For Cloud, this value is from the provider. +""" + +HOST_IMAGE_NAME: Final = "host.image.name" +""" +Name of the VM image or OS install the host was instantiated from. +""" + +HOST_IMAGE_VERSION: Final = "host.image.version" +""" +The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). +""" + +HOST_IP: Final = "host.ip" +""" +Available IP addresses of the host, excluding loopback interfaces. +Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. +""" + +HOST_MAC: Final = "host.mac" +""" +Available MAC addresses of the host, excluding loopback interfaces. +Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): as hyphen-separated octets in uppercase hexadecimal form from most to least significant. +""" + +HOST_NAME: Final = "host.name" +""" +Name of the host. On UNIX systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. +""" + +HOST_TYPE: Final = "host.type" +""" +Type of host. For Cloud, this must be the machine type. +""" + + +class HostArchValues(Enum): + AMD64 = "amd64" + """AMD64.""" + ARM32 = "arm32" + """ARM32.""" + ARM64 = "arm64" + """ARM64.""" + IA64 = "ia64" + """Itanium.""" + PPC32 = "ppc32" + """32-bit PowerPC.""" + PPC64 = "ppc64" + """64-bit PowerPC.""" + S390X = "s390x" + """IBM z/Architecture.""" + X86 = "x86" + """32-bit x86.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py new file mode 100644 index 00000000000..58cfb708bab --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py @@ -0,0 +1,190 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +HTTP_CLIENT_IP: Final = "http.client_ip" +""" +Deprecated: Replaced by `client.address`. +""" + +HTTP_CONNECTION_STATE: Final = "http.connection.state" +""" +State of the HTTP connection in the HTTP connection pool. +""" + +HTTP_FLAVOR: Final = "http.flavor" +""" +Deprecated: Split into `network.protocol.name` and `network.protocol.version`. +""" + +HTTP_HOST: Final = "http.host" +""" +Deprecated: Replaced by one of `server.address`, `client.address` or `http.request.header.host`, depending on the usage. +""" + +HTTP_METHOD: Final = "http.method" +""" +Deprecated: Replaced by `http.request.method`. +""" + +HTTP_REQUEST_BODY_SIZE: Final = "http.request.body.size" +""" +The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. +""" + +HTTP_REQUEST_HEADER_TEMPLATE: Final = "http.request.header" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_HEADER_TEMPLATE`. +""" + +HTTP_REQUEST_METHOD: Final = "http.request.method" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_METHOD`. +""" + +HTTP_REQUEST_METHOD_ORIGINAL: Final = "http.request.method_original" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_METHOD_ORIGINAL`. +""" + +HTTP_REQUEST_RESEND_COUNT: Final = "http.request.resend_count" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_RESEND_COUNT`. +""" + +HTTP_REQUEST_SIZE: Final = "http.request.size" +""" +The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. +""" + +HTTP_REQUEST_CONTENT_LENGTH: Final = "http.request_content_length" +""" +Deprecated: Replaced by `http.request.header.content-length`. +""" + +HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED: Final = "http.request_content_length_uncompressed" +""" +Deprecated: Replaced by `http.request.body.size`. +""" + +HTTP_RESPONSE_BODY_SIZE: Final = "http.response.body.size" +""" +The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. +""" + +HTTP_RESPONSE_HEADER_TEMPLATE: Final = "http.response.header" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_RESPONSE_HEADER_TEMPLATE`. +""" + +HTTP_RESPONSE_SIZE: Final = "http.response.size" +""" +The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. +""" + +HTTP_RESPONSE_STATUS_CODE: Final = "http.response.status_code" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_RESPONSE_STATUS_CODE`. +""" + +HTTP_RESPONSE_CONTENT_LENGTH: Final = "http.response_content_length" +""" +Deprecated: Replaced by `http.response.header.content-length`. +""" + +HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED: Final = "http.response_content_length_uncompressed" +""" +Deprecated: Replaced by `http.response.body.size`. +""" + +HTTP_ROUTE: Final = "http.route" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_ROUTE`. +""" + +HTTP_SCHEME: Final = "http.scheme" +""" +Deprecated: Replaced by `url.scheme`. +""" + +HTTP_SERVER_NAME: Final = "http.server_name" +""" +Deprecated: Replaced by `server.address`. +""" + +HTTP_STATUS_CODE: Final = "http.status_code" +""" +Deprecated: Replaced by `http.response.status_code`. +""" + +HTTP_TARGET: Final = "http.target" +""" +Deprecated: Split to `url.path` and `url.query`. +""" + +HTTP_URL: Final = "http.url" +""" +Deprecated: Replaced by `url.full`. +""" + +HTTP_USER_AGENT: Final = "http.user_agent" +""" +Deprecated: Replaced by `user_agent.original`. +""" + + +class HttpConnectionStateValues(Enum): + ACTIVE = "active" + """active state.""" + IDLE = "idle" + """idle state.""" + + +@deprecated( + "The attribute http.flavor is deprecated - Split into `network.protocol.name` and `network.protocol.version`" +) +class HttpFlavorValues(Enum): + HTTP_1_0 = "1.0" + """HTTP/1.0.""" + HTTP_1_1 = "1.1" + """HTTP/1.1.""" + HTTP_2_0 = "2.0" + """HTTP/2.""" + HTTP_3_0 = "3.0" + """HTTP/3.""" + SPDY = "SPDY" + """SPDY protocol.""" + QUIC = "QUIC" + """QUIC protocol.""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues`." +) +class HttpRequestMethodValues(Enum): + CONNECT = "CONNECT" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.CONNECT`.""" + DELETE = "DELETE" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.DELETE`.""" + GET = "GET" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.GET`.""" + HEAD = "HEAD" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.HEAD`.""" + OPTIONS = "OPTIONS" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.OPTIONS`.""" + PATCH = "PATCH" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.PATCH`.""" + POST = "POST" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.POST`.""" + PUT = "PUT" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.PUT`.""" + TRACE = "TRACE" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.TRACE`.""" + QUERY = "QUERY" + """QUERY method.""" + OTHER = "_OTHER" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.OTHER`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py new file mode 100644 index 00000000000..548e6fdc518 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py @@ -0,0 +1,243 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +HW_BATTERY_CAPACITY: Final = "hw.battery.capacity" +""" +Design capacity in Watts-hours or Ampere-hours. +""" + +HW_BATTERY_CHEMISTRY: Final = "hw.battery.chemistry" +""" +Battery [chemistry](https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html), e.g. Lithium-Ion, Nickel-Cadmium, etc. +""" + +HW_BATTERY_STATE: Final = "hw.battery.state" +""" +The current state of the battery. +""" + +HW_BIOS_VERSION: Final = "hw.bios_version" +""" +BIOS version of the hardware component. +""" + +HW_DRIVER_VERSION: Final = "hw.driver_version" +""" +Driver version for the hardware component. +""" + +HW_ENCLOSURE_TYPE: Final = "hw.enclosure.type" +""" +Type of the enclosure (useful for modular systems). +""" + +HW_FIRMWARE_VERSION: Final = "hw.firmware_version" +""" +Firmware version of the hardware component. +""" + +HW_GPU_TASK: Final = "hw.gpu.task" +""" +Type of task the GPU is performing. +""" + +HW_ID: Final = "hw.id" +""" +An identifier for the hardware component, unique within the monitored host. +""" + +HW_LIMIT_TYPE: Final = "hw.limit_type" +""" +Type of limit for hardware components. +""" + +HW_LOGICAL_DISK_RAID_LEVEL: Final = "hw.logical_disk.raid_level" +""" +RAID Level of the logical disk. +""" + +HW_LOGICAL_DISK_STATE: Final = "hw.logical_disk.state" +""" +State of the logical disk space usage. +""" + +HW_MEMORY_TYPE: Final = "hw.memory.type" +""" +Type of the memory module. +""" + +HW_MODEL: Final = "hw.model" +""" +Descriptive model name of the hardware component. +""" + +HW_NAME: Final = "hw.name" +""" +An easily-recognizable name for the hardware component. +""" + +HW_NETWORK_LOGICAL_ADDRESSES: Final = "hw.network.logical_addresses" +""" +Logical addresses of the adapter (e.g. IP address, or WWPN). +""" + +HW_NETWORK_PHYSICAL_ADDRESS: Final = "hw.network.physical_address" +""" +Physical address of the adapter (e.g. MAC address, or WWNN). +""" + +HW_PARENT: Final = "hw.parent" +""" +Unique identifier of the parent component (typically the `hw.id` attribute of the enclosure, or disk controller). +""" + +HW_PHYSICAL_DISK_SMART_ATTRIBUTE: Final = "hw.physical_disk.smart_attribute" +""" +[S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute of the physical disk. +""" + +HW_PHYSICAL_DISK_STATE: Final = "hw.physical_disk.state" +""" +State of the physical disk endurance utilization. +""" + +HW_PHYSICAL_DISK_TYPE: Final = "hw.physical_disk.type" +""" +Type of the physical disk. +""" + +HW_SENSOR_LOCATION: Final = "hw.sensor_location" +""" +Location of the sensor. +""" + +HW_SERIAL_NUMBER: Final = "hw.serial_number" +""" +Serial number of the hardware component. +""" + +HW_STATE: Final = "hw.state" +""" +The current state of the component. +""" + +HW_TAPE_DRIVE_OPERATION_TYPE: Final = "hw.tape_drive.operation_type" +""" +Type of tape drive operation. +""" + +HW_TYPE: Final = "hw.type" +""" +Type of the component. +Note: Describes the category of the hardware component for which `hw.state` is being reported. For example, `hw.type=temperature` along with `hw.state=degraded` would indicate that the temperature of the hardware component has been reported as `degraded`. +""" + +HW_VENDOR: Final = "hw.vendor" +""" +Vendor name of the hardware component. +""" + + +class HwBatteryStateValues(Enum): + CHARGING = "charging" + """Charging.""" + DISCHARGING = "discharging" + """Discharging.""" + + +class HwGpuTaskValues(Enum): + DECODER = "decoder" + """Decoder.""" + ENCODER = "encoder" + """Encoder.""" + GENERAL = "general" + """General.""" + + +class HwLimitTypeValues(Enum): + CRITICAL = "critical" + """Critical.""" + DEGRADED = "degraded" + """Degraded.""" + HIGH_CRITICAL = "high.critical" + """High Critical.""" + HIGH_DEGRADED = "high.degraded" + """High Degraded.""" + LOW_CRITICAL = "low.critical" + """Low Critical.""" + LOW_DEGRADED = "low.degraded" + """Low Degraded.""" + MAX = "max" + """Maximum.""" + THROTTLED = "throttled" + """Throttled.""" + TURBO = "turbo" + """Turbo.""" + + +class HwLogicalDiskStateValues(Enum): + USED = "used" + """Used.""" + FREE = "free" + """Free.""" + + +class HwPhysicalDiskStateValues(Enum): + REMAINING = "remaining" + """Remaining.""" + + +class HwStateValues(Enum): + DEGRADED = "degraded" + """Degraded.""" + FAILED = "failed" + """Failed.""" + NEEDS_CLEANING = "needs_cleaning" + """Needs Cleaning.""" + OK = "ok" + """OK.""" + PREDICTED_FAILURE = "predicted_failure" + """Predicted Failure.""" + + +class HwTapeDriveOperationTypeValues(Enum): + MOUNT = "mount" + """Mount.""" + UNMOUNT = "unmount" + """Unmount.""" + CLEAN = "clean" + """Clean.""" + + +class HwTypeValues(Enum): + BATTERY = "battery" + """Battery.""" + CPU = "cpu" + """CPU.""" + DISK_CONTROLLER = "disk_controller" + """Disk controller.""" + ENCLOSURE = "enclosure" + """Enclosure.""" + FAN = "fan" + """Fan.""" + GPU = "gpu" + """GPU.""" + LOGICAL_DISK = "logical_disk" + """Logical disk.""" + MEMORY = "memory" + """Memory.""" + NETWORK = "network" + """Network.""" + PHYSICAL_DISK = "physical_disk" + """Physical disk.""" + POWER_SUPPLY = "power_supply" + """Power supply.""" + TAPE_DRIVE = "tape_drive" + """Tape drive.""" + TEMPERATURE = "temperature" + """Temperature.""" + VOLTAGE = "voltage" + """Voltage.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py new file mode 100644 index 00000000000..fcea8239f93 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py @@ -0,0 +1,16 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +JSONRPC_PROTOCOL_VERSION: Final = "jsonrpc.protocol.version" +""" +Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. +""" + +JSONRPC_REQUEST_ID: Final = "jsonrpc.request.id" +""" +A string representation of the `id` property of the request and its corresponding response. +Note: Under the [JSON-RPC specification](https://www.jsonrpc.org/specification), the `id` property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using `null` is not equivalent to omitting the `id`, but it is discouraged. +Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or omitted. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py new file mode 100644 index 00000000000..0b2eed32e52 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py @@ -0,0 +1,721 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +K8S_CLUSTER_NAME: Final = "k8s.cluster.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CLUSTER_NAME`. +""" + +K8S_CLUSTER_UID: Final = "k8s.cluster.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CLUSTER_UID`. +""" + +K8S_CONTAINER_EPHEMERAL_STORAGE_FS_TYPE: Final = "k8s.container.ephemeral_storage.fs_type" +""" +The type of file system component for ephemeral storage. +Note: Eviction decisions based on ephemeral-storage resource limits are made based on the total container usage. +""" + +K8S_CONTAINER_NAME: Final = "k8s.container.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CONTAINER_NAME`. +""" + +K8S_CONTAINER_RESTART_COUNT: Final = "k8s.container.restart_count" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CONTAINER_RESTART_COUNT`. +""" + +K8S_CONTAINER_STATUS_LAST_TERMINATED_REASON: Final = "k8s.container.status.last_terminated_reason" +""" +Last terminated reason of the Container. +""" + +K8S_CONTAINER_STATUS_REASON: Final = "k8s.container.status.reason" +""" +The reason for the container state. Corresponds to the `reason` field of the: [K8s ContainerStateWaiting](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatewaiting-v1-core) or [K8s ContainerStateTerminated](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstateterminated-v1-core). +""" + +K8S_CONTAINER_STATUS_STATE: Final = "k8s.container.status.state" +""" +The state of the container. [K8s ContainerState](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstate-v1-core). +""" + +K8S_CRONJOB_ANNOTATION_TEMPLATE: Final = "k8s.cronjob.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_ANNOTATION_TEMPLATE`. +""" + +K8S_CRONJOB_LABEL_TEMPLATE: Final = "k8s.cronjob.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_LABEL_TEMPLATE`. +""" + +K8S_CRONJOB_NAME: Final = "k8s.cronjob.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_NAME`. +""" + +K8S_CRONJOB_UID: Final = "k8s.cronjob.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_UID`. +""" + +K8S_DAEMONSET_ANNOTATION_TEMPLATE: Final = "k8s.daemonset.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_ANNOTATION_TEMPLATE`. +""" + +K8S_DAEMONSET_LABEL_TEMPLATE: Final = "k8s.daemonset.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_LABEL_TEMPLATE`. +""" + +K8S_DAEMONSET_NAME: Final = "k8s.daemonset.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_NAME`. +""" + +K8S_DAEMONSET_UID: Final = "k8s.daemonset.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_UID`. +""" + +K8S_DEPLOYMENT_ANNOTATION_TEMPLATE: Final = "k8s.deployment.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_ANNOTATION_TEMPLATE`. +""" + +K8S_DEPLOYMENT_LABEL_TEMPLATE: Final = "k8s.deployment.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_LABEL_TEMPLATE`. +""" + +K8S_DEPLOYMENT_NAME: Final = "k8s.deployment.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_NAME`. +""" + +K8S_DEPLOYMENT_UID: Final = "k8s.deployment.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_UID`. +""" + +K8S_HPA_METRIC_TYPE: Final = "k8s.hpa.metric.type" +""" +The type of metric source for the horizontal pod autoscaler. +Note: This attribute reflects the `type` field of spec.metrics[] in the HPA. +""" + +K8S_HPA_NAME: Final = "k8s.hpa.name" +""" +The name of the horizontal pod autoscaler. +""" + +K8S_HPA_SCALETARGETREF_API_VERSION: Final = "k8s.hpa.scaletargetref.api_version" +""" +The API version of the target resource to scale for the HorizontalPodAutoscaler. +Note: This maps to the `apiVersion` field in the `scaleTargetRef` of the HPA spec. +""" + +K8S_HPA_SCALETARGETREF_KIND: Final = "k8s.hpa.scaletargetref.kind" +""" +The kind of the target resource to scale for the HorizontalPodAutoscaler. +Note: This maps to the `kind` field in the `scaleTargetRef` of the HPA spec. +""" + +K8S_HPA_SCALETARGETREF_NAME: Final = "k8s.hpa.scaletargetref.name" +""" +The name of the target resource to scale for the HorizontalPodAutoscaler. +Note: This maps to the `name` field in the `scaleTargetRef` of the HPA spec. +""" + +K8S_HPA_UID: Final = "k8s.hpa.uid" +""" +The UID of the horizontal pod autoscaler. +""" + +K8S_HUGEPAGE_SIZE: Final = "k8s.hugepage.size" +""" +The size (identifier) of the K8s huge page. +""" + +K8S_JOB_ANNOTATION_TEMPLATE: Final = "k8s.job.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_ANNOTATION_TEMPLATE`. +""" + +K8S_JOB_LABEL_TEMPLATE: Final = "k8s.job.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_LABEL_TEMPLATE`. +""" + +K8S_JOB_NAME: Final = "k8s.job.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_NAME`. +""" + +K8S_JOB_UID: Final = "k8s.job.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_UID`. +""" + +K8S_NAMESPACE_ANNOTATION_TEMPLATE: Final = "k8s.namespace.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NAMESPACE_ANNOTATION_TEMPLATE`. +""" + +K8S_NAMESPACE_LABEL_TEMPLATE: Final = "k8s.namespace.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NAMESPACE_LABEL_TEMPLATE`. +""" + +K8S_NAMESPACE_NAME: Final = "k8s.namespace.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NAMESPACE_NAME`. +""" + +K8S_NAMESPACE_PHASE: Final = "k8s.namespace.phase" +""" +The phase of the K8s namespace. +Note: This attribute aligns with the `phase` field of the +[K8s NamespaceStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#namespacestatus-v1-core). +""" + +K8S_NODE_ANNOTATION_TEMPLATE: Final = "k8s.node.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_ANNOTATION_TEMPLATE`. +""" + +K8S_NODE_CONDITION_STATUS: Final = "k8s.node.condition.status" +""" +The status of the condition, one of True, False, Unknown. +Note: This attribute aligns with the `status` field of the +[NodeCondition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#nodecondition-v1-core). +""" + +K8S_NODE_CONDITION_TYPE: Final = "k8s.node.condition.type" +""" +The condition type of a K8s Node. +Note: K8s Node conditions as described +by [K8s documentation](https://kubernetes.io/docs/reference/node/node-status/#condition). + +This attribute aligns with the `type` field of the +[NodeCondition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#nodecondition-v1-core) + +The set of possible values is not limited to those listed here. Managed Kubernetes environments, +or custom controllers MAY introduce additional node condition types. +When this occurs, the exact value as reported by the Kubernetes API SHOULD be used. +""" + +K8S_NODE_LABEL_TEMPLATE: Final = "k8s.node.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_LABEL_TEMPLATE`. +""" + +K8S_NODE_NAME: Final = "k8s.node.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_NAME`. +""" + +K8S_NODE_SYSTEM_CONTAINER_NAME: Final = "k8s.node.system_container.name" +""" +The name of the system container running on the K8s Node. +""" + +K8S_NODE_UID: Final = "k8s.node.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_UID`. +""" + +K8S_PERSISTENTVOLUME_ANNOTATION_TEMPLATE: Final = "k8s.persistentvolume.annotation" +""" +The annotation placed on the PersistentVolume, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `pv.kubernetes.io/provisioned-by` with value `kubernetes.io/aws-ebs` SHOULD be recorded as + the `k8s.persistentvolume.annotation.pv.kubernetes.io/provisioned-by` attribute with value `"kubernetes.io/aws-ebs"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.persistentvolume.annotation.data` attribute with value `""`. +""" + +K8S_PERSISTENTVOLUME_LABEL_TEMPLATE: Final = "k8s.persistentvolume.label" +""" +The label placed on the PersistentVolume, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `type` with value `ssd` SHOULD be recorded as + the `k8s.persistentvolume.label.type` attribute with value `"ssd"`. +- A label `data` with empty string value SHOULD be recorded as + the `k8s.persistentvolume.label.data` attribute with value `""`. +""" + +K8S_PERSISTENTVOLUME_NAME: Final = "k8s.persistentvolume.name" +""" +The name of the PersistentVolume. +""" + +K8S_PERSISTENTVOLUME_RECLAIM_POLICY: Final = "k8s.persistentvolume.reclaim_policy" +""" +The reclaim policy of the PersistentVolume. +Note: This attribute aligns with the `persistentVolumeReclaimPolicy` field of the +[K8s PersistentVolumeSpec](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec). +""" + +K8S_PERSISTENTVOLUME_STATUS_PHASE: Final = "k8s.persistentvolume.status.phase" +""" +The phase of the PersistentVolume. +Note: This attribute aligns with the `phase` field of the +[K8s PersistentVolumeStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeStatus). +""" + +K8S_PERSISTENTVOLUME_UID: Final = "k8s.persistentvolume.uid" +""" +The UID of the PersistentVolume. +""" + +K8S_PERSISTENTVOLUMECLAIM_ANNOTATION_TEMPLATE: Final = "k8s.persistentvolumeclaim.annotation" +""" +The annotation placed on the PersistentVolumeClaim, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `volume.beta.kubernetes.io/storage-provisioner` with value `kubernetes.io/aws-ebs` SHOULD be recorded as + the `k8s.persistentvolumeclaim.annotation.volume.beta.kubernetes.io/storage-provisioner` attribute with value `"kubernetes.io/aws-ebs"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.persistentvolumeclaim.annotation.data` attribute with value `""`. +""" + +K8S_PERSISTENTVOLUMECLAIM_LABEL_TEMPLATE: Final = "k8s.persistentvolumeclaim.label" +""" +The label placed on the PersistentVolumeClaim, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `app` with value `my-app` SHOULD be recorded as + the `k8s.persistentvolumeclaim.label.app` attribute with value `"my-app"`. +- A label `data` with empty string value SHOULD be recorded as + the `k8s.persistentvolumeclaim.label.data` attribute with value `""`. +""" + +K8S_PERSISTENTVOLUMECLAIM_NAME: Final = "k8s.persistentvolumeclaim.name" +""" +The name of the PersistentVolumeClaim. +""" + +K8S_PERSISTENTVOLUMECLAIM_STATUS_PHASE: Final = "k8s.persistentvolumeclaim.status.phase" +""" +The phase of the PersistentVolumeClaim. +Note: This attribute aligns with the `phase` field of the +[K8s PersistentVolumeClaimStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus). +""" + +K8S_PERSISTENTVOLUMECLAIM_UID: Final = "k8s.persistentvolumeclaim.uid" +""" +The UID of the PersistentVolumeClaim. +""" + +K8S_POD_ANNOTATION_TEMPLATE: Final = "k8s.pod.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_ANNOTATION_TEMPLATE`. +""" + +K8S_POD_HOSTNAME: Final = "k8s.pod.hostname" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_HOSTNAME`. +""" + +K8S_POD_IP: Final = "k8s.pod.ip" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_IP`. +""" + +K8S_POD_LABEL_TEMPLATE: Final = "k8s.pod.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_LABEL_TEMPLATE`. +""" + +K8S_POD_LABELS_TEMPLATE: Final = "k8s.pod.labels" +""" +Deprecated: Replaced by `k8s.pod.label`. +""" + +K8S_POD_NAME: Final = "k8s.pod.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_NAME`. +""" + +K8S_POD_START_TIME: Final = "k8s.pod.start_time" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_START_TIME`. +""" + +K8S_POD_STATUS_PHASE: Final = "k8s.pod.status.phase" +""" +The phase for the pod. Corresponds to the `phase` field of the: [K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core). +""" + +K8S_POD_STATUS_REASON: Final = "k8s.pod.status.reason" +""" +The reason for the pod state. Corresponds to the `reason` field of the: [K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core). +""" + +K8S_POD_UID: Final = "k8s.pod.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_UID`. +""" + +K8S_REPLICASET_ANNOTATION_TEMPLATE: Final = "k8s.replicaset.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_ANNOTATION_TEMPLATE`. +""" + +K8S_REPLICASET_LABEL_TEMPLATE: Final = "k8s.replicaset.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_LABEL_TEMPLATE`. +""" + +K8S_REPLICASET_NAME: Final = "k8s.replicaset.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_NAME`. +""" + +K8S_REPLICASET_UID: Final = "k8s.replicaset.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_UID`. +""" + +K8S_REPLICATIONCONTROLLER_NAME: Final = "k8s.replicationcontroller.name" +""" +The name of the replication controller. +""" + +K8S_REPLICATIONCONTROLLER_UID: Final = "k8s.replicationcontroller.uid" +""" +The UID of the replication controller. +""" + +K8S_RESOURCEQUOTA_NAME: Final = "k8s.resourcequota.name" +""" +The name of the resource quota. +""" + +K8S_RESOURCEQUOTA_RESOURCE_NAME: Final = "k8s.resourcequota.resource_name" +""" +The name of the K8s resource a resource quota defines. +Note: The value for this attribute can be either the full `count/[.]` string (e.g., count/deployments.apps, count/pods), or, for certain core Kubernetes resources, just the resource name (e.g., pods, services, configmaps). Both forms are supported by Kubernetes for object count quotas. See [Kubernetes Resource Quotas documentation](https://kubernetes.io/docs/concepts/policy/resource-quotas/#quota-on-object-count) for more details. +""" + +K8S_RESOURCEQUOTA_UID: Final = "k8s.resourcequota.uid" +""" +The UID of the resource quota. +""" + +K8S_SERVICE_ANNOTATION_TEMPLATE: Final = "k8s.service.annotation" +""" +The annotation placed on the Service, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `prometheus.io/scrape` with value `true` SHOULD be recorded as + the `k8s.service.annotation.prometheus.io/scrape` attribute with value `"true"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.service.annotation.data` attribute with value `""`. +""" + +K8S_SERVICE_ENDPOINT_ADDRESS_TYPE: Final = "k8s.service.endpoint.address_type" +""" +The address type of the service endpoint. +Note: The network address family or type of the endpoint. +This attribute aligns with the `addressType` field of the +[K8s EndpointSlice](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). +It is used to differentiate metrics when a Service is backed by multiple address types +(e.g., in dual-stack clusters). +""" + +K8S_SERVICE_ENDPOINT_CONDITION: Final = "k8s.service.endpoint.condition" +""" +The condition of the service endpoint. +Note: The current operational condition of the service endpoint. +An endpoint can have multiple conditions set at once (e.g., both `serving` and `terminating` during rollout). +This attribute aligns with the condition fields in the [K8s EndpointSlice](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). +""" + +K8S_SERVICE_ENDPOINT_ZONE: Final = "k8s.service.endpoint.zone" +""" +The zone of the service endpoint. +Note: The zone where the endpoint is located, typically corresponding to a failure domain. +This attribute aligns with the `zone` field of endpoints in the +[K8s EndpointSlice](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). +It enables zone-aware monitoring of service endpoint distribution and supports +features like [Topology Aware Routing](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/). + +If the zone is not populated (e.g., nodes without the `topology.kubernetes.io/zone` label), +the attribute value will be an empty string. +""" + +K8S_SERVICE_LABEL_TEMPLATE: Final = "k8s.service.label" +""" +The label placed on the Service, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `app` with value `my-service` SHOULD be recorded as + the `k8s.service.label.app` attribute with value `"my-service"`. +- A label `data` with empty string value SHOULD be recorded as + the `k8s.service.label.data` attribute with value `""`. +""" + +K8S_SERVICE_NAME: Final = "k8s.service.name" +""" +The name of the Service. +""" + +K8S_SERVICE_PUBLISH_NOT_READY_ADDRESSES: Final = "k8s.service.publish_not_ready_addresses" +""" +Whether the Service publishes not-ready endpoints. +Note: Whether the Service is configured to publish endpoints before the pods are ready. +This attribute is typically used to indicate that a Service (such as a headless +Service for a StatefulSet) allows peer discovery before pods pass their readiness probes. +It aligns with the `publishNotReadyAddresses` field of the +[K8s ServiceSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec). +""" + +K8S_SERVICE_SELECTOR_TEMPLATE: Final = "k8s.service.selector" +""" +The selector key-value pair placed on the Service, the `` being the selector key, the value being the selector value. +Note: These selectors are used to correlate with pod labels. Each selector key-value pair becomes a separate attribute. + +Examples: + +- A selector `app=my-app` SHOULD be recorded as + the `k8s.service.selector.app` attribute with value `"my-app"`. +- A selector `version=v1` SHOULD be recorded as + the `k8s.service.selector.version` attribute with value `"v1"`. +""" + +K8S_SERVICE_TRAFFIC_DISTRIBUTION: Final = "k8s.service.traffic_distribution" +""" +The traffic distribution policy for the Service. +Note: Specifies how traffic is distributed to endpoints for this Service. +This attribute aligns with the `trafficDistribution` field of the +[K8s ServiceSpec](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution). +Known values include `PreferSameZone` (prefer endpoints in the same zone as the client) and +`PreferSameNode` (prefer endpoints on the same node, fallback to same zone, then cluster-wide). +If this field is not set on the Service, the attribute SHOULD NOT be emitted. +When not set, Kubernetes distributes traffic evenly across all endpoints cluster-wide. +""" + +K8S_SERVICE_TYPE: Final = "k8s.service.type" +""" +The type of the Kubernetes Service. +Note: This attribute aligns with the `type` field of the +[K8s ServiceSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec). +""" + +K8S_SERVICE_UID: Final = "k8s.service.uid" +""" +The UID of the Service. +""" + +K8S_STATEFULSET_ANNOTATION_TEMPLATE: Final = "k8s.statefulset.annotation" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_ANNOTATION_TEMPLATE`. +""" + +K8S_STATEFULSET_LABEL_TEMPLATE: Final = "k8s.statefulset.label" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_LABEL_TEMPLATE`. +""" + +K8S_STATEFULSET_NAME: Final = "k8s.statefulset.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_NAME`. +""" + +K8S_STATEFULSET_UID: Final = "k8s.statefulset.uid" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_UID`. +""" + +K8S_STORAGECLASS_NAME: Final = "k8s.storageclass.name" +""" +The name of K8s [StorageClass](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#storageclass-v1-storage-k8s-io) object. +""" + +K8S_VOLUME_NAME: Final = "k8s.volume.name" +""" +The name of the K8s volume. +""" + +K8S_VOLUME_TYPE: Final = "k8s.volume.type" +""" +The type of the K8s volume. +""" + + +class K8sContainerEphemeralStorageFsTypeValues(Enum): + ROOTFS = "rootfs" + """For the container's writable layer usage.""" + LOGS = "logs" + """For the container's log files usage (stdout/stderr).""" + + +class K8sContainerStatusReasonValues(Enum): + CONTAINER_CREATING = "ContainerCreating" + """The container is being created.""" + CRASH_LOOP_BACK_OFF = "CrashLoopBackOff" + """The container is in a crash loop back off state.""" + CREATE_CONTAINER_CONFIG_ERROR = "CreateContainerConfigError" + """There was an error creating the container configuration.""" + ERR_IMAGE_PULL = "ErrImagePull" + """There was an error pulling the container image.""" + IMAGE_PULL_BACK_OFF = "ImagePullBackOff" + """The container image pull is in back off state.""" + OOM_KILLED = "OOMKilled" + """The container was killed due to out of memory.""" + COMPLETED = "Completed" + """The container has completed execution.""" + ERROR = "Error" + """There was an error with the container.""" + CONTAINER_CANNOT_RUN = "ContainerCannotRun" + """The container cannot run.""" + + +class K8sContainerStatusStateValues(Enum): + TERMINATED = "terminated" + """The container has terminated.""" + RUNNING = "running" + """The container is running.""" + WAITING = "waiting" + """The container is waiting.""" + + +class K8sNamespacePhaseValues(Enum): + ACTIVE = "active" + """Active namespace phase as described by [K8s API](https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase).""" + TERMINATING = "terminating" + """Terminating namespace phase as described by [K8s API](https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase).""" + + +class K8sNodeConditionStatusValues(Enum): + CONDITION_TRUE = "true" + """condition_true.""" + CONDITION_FALSE = "false" + """condition_false.""" + CONDITION_UNKNOWN = "unknown" + """condition_unknown.""" + + +class K8sNodeConditionTypeValues(Enum): + READY = "Ready" + """The node is healthy and ready to accept pods.""" + DISK_PRESSURE = "DiskPressure" + """Pressure exists on the disk size—that is, if the disk capacity is low.""" + MEMORY_PRESSURE = "MemoryPressure" + """Pressure exists on the node memory—that is, if the node memory is low.""" + PID_PRESSURE = "PIDPressure" + """Pressure exists on the processes—that is, if there are too many processes on the node.""" + NETWORK_UNAVAILABLE = "NetworkUnavailable" + """The network for the node is not correctly configured.""" + + +class K8sPersistentvolumeReclaimPolicyValues(Enum): + DELETE = "Delete" + """The volume will be deleted when released from its claim.""" + RECYCLE = "Recycle" + """The volume will be recycled (basic scrub) when released from its claim.""" + RETAIN = "Retain" + """The volume will be retained when released from its claim.""" + + +class K8sPersistentvolumeStatusPhaseValues(Enum): + AVAILABLE = "Available" + """The volume is available and not yet bound to a claim.""" + BOUND = "Bound" + """The volume is bound to a claim.""" + FAILED = "Failed" + """The volume has failed its automatic reclamation.""" + PENDING = "Pending" + """The volume is being provisioned.""" + RELEASED = "Released" + """The claim has been deleted but the volume is not yet available.""" + + +class K8sPersistentvolumeclaimStatusPhaseValues(Enum): + BOUND = "Bound" + """The claim is bound to a volume.""" + LOST = "Lost" + """The claim has lost its underlying volume (the volume does not exist anymore).""" + PENDING = "Pending" + """The claim has not yet been bound to a volume.""" + + +class K8sPodStatusPhaseValues(Enum): + PENDING = "Pending" + """The pod has been accepted by the system, but one or more of the containers has not been started. This includes time before being bound to a node, as well as time spent pulling images onto the host.""" + RUNNING = "Running" + """The pod has been bound to a node and all of the containers have been started. At least one container is still running or is in the process of being restarted.""" + SUCCEEDED = "Succeeded" + """All containers in the pod have voluntarily terminated with a container exit code of 0, and the system is not going to restart any of these containers.""" + FAILED = "Failed" + """All containers in the pod have terminated, and at least one container has terminated in a failure (exited with a non-zero exit code or was stopped by the system).""" + UNKNOWN = "Unknown" + """For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod.""" + + +class K8sPodStatusReasonValues(Enum): + EVICTED = "Evicted" + """The pod is evicted.""" + NODE_AFFINITY = "NodeAffinity" + """The pod is in a status because of its node affinity.""" + NODE_LOST = "NodeLost" + """The reason on a pod when its state cannot be confirmed as kubelet is unresponsive on the node it is (was) running.""" + SHUTDOWN = "Shutdown" + """The node is shutdown.""" + UNEXPECTED_ADMISSION_ERROR = "UnexpectedAdmissionError" + """The pod was rejected admission to the node because of an error during admission that could not be categorized.""" + + +class K8sServiceEndpointAddressTypeValues(Enum): + IPV4 = "IPv4" + """IPv4 address type.""" + IPV6 = "IPv6" + """IPv6 address type.""" + FQDN = "FQDN" + """FQDN address type.""" + + +class K8sServiceEndpointConditionValues(Enum): + READY = "ready" + """The endpoint is ready to receive new connections.""" + SERVING = "serving" + """The endpoint is currently handling traffic.""" + TERMINATING = "terminating" + """The endpoint is in the process of shutting down.""" + + +class K8sServiceTypeValues(Enum): + CLUSTER_IP = "ClusterIP" + """ClusterIP service type.""" + NODE_PORT = "NodePort" + """NodePort service type.""" + LOAD_BALANCER = "LoadBalancer" + """LoadBalancer service type.""" + EXTERNAL_NAME = "ExternalName" + """ExternalName service type.""" + + +class K8sVolumeTypeValues(Enum): + PERSISTENT_VOLUME_CLAIM = "persistentVolumeClaim" + """A [persistentVolumeClaim](https://kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim) volume.""" + CONFIG_MAP = "configMap" + """A [configMap](https://kubernetes.io/docs/concepts/storage/volumes/#configmap) volume.""" + DOWNWARD_API = "downwardAPI" + """A [downwardAPI](https://kubernetes.io/docs/concepts/storage/volumes/#downwardapi) volume.""" + EMPTY_DIR = "emptyDir" + """An [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) volume.""" + SECRET = "secret" + """A [secret](https://kubernetes.io/docs/concepts/storage/volumes/#secret) volume.""" + LOCAL = "local" + """A [local](https://kubernetes.io/docs/concepts/storage/volumes/#local) volume.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py new file mode 100644 index 00000000000..df275c9144f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py @@ -0,0 +1,20 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +LINUX_MEMORY_SLAB_STATE: Final = "linux.memory.slab.state" +""" +Deprecated: Replaced by `system.memory.linux.slab.state`. +""" + + +@deprecated("The attribute linux.memory.slab.state is deprecated - Replaced by `system.memory.linux.slab.state`") +class LinuxMemorySlabStateValues(Enum): + RECLAIMABLE = "reclaimable" + """reclaimable.""" + UNRECLAIMABLE = "unreclaimable" + """unreclaimable.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py new file mode 100644 index 00000000000..30264071c20 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py @@ -0,0 +1,50 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +LOG_FILE_NAME: Final = "log.file.name" +""" +The basename of the file. +""" + +LOG_FILE_NAME_RESOLVED: Final = "log.file.name_resolved" +""" +The basename of the file, with symlinks resolved. +""" + +LOG_FILE_PATH: Final = "log.file.path" +""" +The full path to the file. +""" + +LOG_FILE_PATH_RESOLVED: Final = "log.file.path_resolved" +""" +The full path to the file, with symlinks resolved. +""" + +LOG_IOSTREAM: Final = "log.iostream" +""" +The stream associated with the log. See below for a list of well-known values. +""" + +LOG_RECORD_ORIGINAL: Final = "log.record.original" +""" +The complete original Log Record. +Note: This value MAY be added when processing a Log Record which was originally transmitted as a string or equivalent data type AND the Body field of the Log Record does not contain the same value. (e.g. a syslog or a log record read from a file.). +""" + +LOG_RECORD_UID: Final = "log.record.uid" +""" +A unique identifier for the Log Record. +Note: If an ID is provided, other log records with the same ID will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. +The ID MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. +""" + + +class LogIostreamValues(Enum): + STDOUT = "stdout" + """Logs from stdout stream.""" + STDERR = "stderr" + """Events from stderr stream.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py new file mode 100644 index 00000000000..bfa8d1969f3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +MAINFRAME_LPAR_NAME: Final = "mainframe.lpar.name" +""" +Name of the logical partition that hosts a systems with a mainframe operating system. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py new file mode 100644 index 00000000000..28480b6027b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py @@ -0,0 +1,83 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +MCP_METHOD_NAME: Final = "mcp.method.name" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +MCP_PROTOCOL_VERSION: Final = "mcp.protocol.version" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +MCP_RESOURCE_URI: Final = "mcp.resource.uri" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +MCP_SESSION_ID: Final = "mcp.session.id" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +@deprecated( + "The attribute mcp.method.name is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class McpMethodNameValues(Enum): + NOTIFICATIONS_CANCELLED = "notifications/cancelled" + """Notification cancelling a previously-issued request.""" + INITIALIZE = "initialize" + """Request to initialize the MCP client.""" + NOTIFICATIONS_INITIALIZED = "notifications/initialized" + """Notification indicating that the MCP client has been initialized.""" + NOTIFICATIONS_PROGRESS = "notifications/progress" + """Notification indicating the progress for a long-running operation.""" + PING = "ping" + """Request to check that the other party is still alive.""" + RESOURCES_LIST = "resources/list" + """Request to list resources available on server.""" + RESOURCES_TEMPLATES_LIST = "resources/templates/list" + """Request to list resource templates available on server.""" + RESOURCES_READ = "resources/read" + """Request to read a resource.""" + NOTIFICATIONS_RESOURCES_LIST_CHANGED = "notifications/resources/list_changed" + """Notification indicating that the list of resources has changed.""" + RESOURCES_SUBSCRIBE = "resources/subscribe" + """Request to subscribe to a resource.""" + RESOURCES_UNSUBSCRIBE = "resources/unsubscribe" + """Request to unsubscribe from resource updates.""" + NOTIFICATIONS_RESOURCES_UPDATED = "notifications/resources/updated" + """Notification indicating that a resource has been updated.""" + PROMPTS_LIST = "prompts/list" + """Request to list prompts available on server.""" + PROMPTS_GET = "prompts/get" + """Request to get a prompt.""" + NOTIFICATIONS_PROMPTS_LIST_CHANGED = "notifications/prompts/list_changed" + """Notification indicating that the list of prompts has changed.""" + TOOLS_LIST = "tools/list" + """Request to list tools available on server.""" + TOOLS_CALL = "tools/call" + """Request to call a tool.""" + NOTIFICATIONS_TOOLS_LIST_CHANGED = "notifications/tools/list_changed" + """Notification indicating that the list of tools has changed.""" + LOGGING_SET_LEVEL = "logging/setLevel" + """Request to set the logging level.""" + NOTIFICATIONS_MESSAGE = "notifications/message" + """Notification indicating that a message has been received.""" + SAMPLING_CREATE_MESSAGE = "sampling/createMessage" + """Request to create a sampling message.""" + COMPLETION_COMPLETE = "completion/complete" + """Request to complete a prompt.""" + ROOTS_LIST = "roots/list" + """Request to list roots available on server.""" + NOTIFICATIONS_ROOTS_LIST_CHANGED = "notifications/roots/list_changed" + """Notification indicating that the list of roots has changed.""" + ELICITATION_CREATE = "elicitation/create" + """Request from the server to elicit additional information from the user via the client.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py new file mode 100644 index 00000000000..70db48e98cd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py @@ -0,0 +1,35 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +MESSAGE_COMPRESSED_SIZE: Final = "message.compressed_size" +""" +Deprecated: Deprecated, no replacement at this time. +""" + +MESSAGE_ID: Final = "message.id" +""" +Deprecated: Deprecated, no replacement at this time. +""" + +MESSAGE_TYPE: Final = "message.type" +""" +Deprecated: Deprecated, no replacement at this time. +""" + +MESSAGE_UNCOMPRESSED_SIZE: Final = "message.uncompressed_size" +""" +Deprecated: Deprecated, no replacement at this time. +""" + + +@deprecated("The attribute message.type is deprecated - Deprecated, no replacement at this time") +class MessageTypeValues(Enum): + SENT = "SENT" + """sent.""" + RECEIVED = "RECEIVED" + """received.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py new file mode 100644 index 00000000000..9f462f39a44 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py @@ -0,0 +1,327 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +MESSAGING_BATCH_MESSAGE_COUNT: Final = "messaging.batch.message_count" +""" +The number of messages sent, received, or processed in the scope of the batching operation. +Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. +""" + +MESSAGING_CLIENT_ID: Final = "messaging.client.id" +""" +A unique identifier for the client that consumes or produces a message. +""" + +MESSAGING_CONSUMER_GROUP_NAME: Final = "messaging.consumer.group.name" +""" +The name of the consumer group with which a consumer is associated. +Note: Semantic conventions for individual messaging systems SHOULD document whether `messaging.consumer.group.name` is applicable and what it means in the context of that system. +""" + +MESSAGING_DESTINATION_ANONYMOUS: Final = "messaging.destination.anonymous" +""" +A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). +""" + +MESSAGING_DESTINATION_NAME: Final = "messaging.destination.name" +""" +The message destination name. +Note: SHOULD uniquely identify a specific queue, topic or other entity within the broker. If +the broker doesn't have such notion, it SHOULD uniquely identify the broker. +""" + +MESSAGING_DESTINATION_PARTITION_ID: Final = "messaging.destination.partition.id" +""" +The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. +""" + +MESSAGING_DESTINATION_SUBSCRIPTION_NAME: Final = "messaging.destination.subscription.name" +""" +The name of the destination subscription from which a message is consumed. +Note: Semantic conventions for individual messaging systems SHOULD document whether `messaging.destination.subscription.name` is applicable and what it means in the context of that system. +""" + +MESSAGING_DESTINATION_TEMPLATE: Final = "messaging.destination.template" +""" +Low cardinality representation of the messaging destination name. +Note: Destination names could be constructed from templates. An example would be a destination name involving a username or product ID. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. +""" + +MESSAGING_DESTINATION_TEMPORARY: Final = "messaging.destination.temporary" +""" +A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. +""" + +MESSAGING_DESTINATION_PUBLISH_ANONYMOUS: Final = "messaging.destination_publish.anonymous" +""" +Deprecated: Removed. No replacement at this time. +""" + +MESSAGING_DESTINATION_PUBLISH_NAME: Final = "messaging.destination_publish.name" +""" +Deprecated: Removed. No replacement at this time. +""" + +MESSAGING_EVENTHUBS_CONSUMER_GROUP: Final = "messaging.eventhubs.consumer.group" +""" +Deprecated: Replaced by `messaging.consumer.group.name`. +""" + +MESSAGING_EVENTHUBS_MESSAGE_ENQUEUED_TIME: Final = "messaging.eventhubs.message.enqueued_time" +""" +The UTC epoch seconds at which the message has been accepted and stored in the entity. +""" + +MESSAGING_GCP_PUBSUB_MESSAGE_ACK_DEADLINE: Final = "messaging.gcp_pubsub.message.ack_deadline" +""" +The ack deadline in seconds set for the modify ack deadline request. +""" + +MESSAGING_GCP_PUBSUB_MESSAGE_ACK_ID: Final = "messaging.gcp_pubsub.message.ack_id" +""" +The ack ID for a given message. +""" + +MESSAGING_GCP_PUBSUB_MESSAGE_DELIVERY_ATTEMPT: Final = "messaging.gcp_pubsub.message.delivery_attempt" +""" +The delivery attempt for a given message. +""" + +MESSAGING_GCP_PUBSUB_MESSAGE_ORDERING_KEY: Final = "messaging.gcp_pubsub.message.ordering_key" +""" +The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. +""" + +MESSAGING_KAFKA_CLUSTER_ID: Final = "messaging.kafka.cluster.id" +""" +The Kafka cluster ID, obtained from the broker metadata exposed through the Kafka client (or AdminClient) API. +Note: The cluster ID is a unique identifier reported by the Kafka broker. It identifies the cluster independently of the individual brokers the client is configured to connect to, and remains stable even if broker hostnames, IP addresses, or ports change. +""" + +MESSAGING_KAFKA_CONSUMER_GROUP: Final = "messaging.kafka.consumer.group" +""" +Deprecated: Replaced by `messaging.consumer.group.name`. +""" + +MESSAGING_KAFKA_DESTINATION_PARTITION: Final = "messaging.kafka.destination.partition" +""" +Deprecated: Record string representation of the partition ID in `messaging.destination.partition.id` attribute. +""" + +MESSAGING_KAFKA_MESSAGE_KEY: Final = "messaging.kafka.message.key" +""" +Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. +Note: If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. +""" + +MESSAGING_KAFKA_MESSAGE_OFFSET: Final = "messaging.kafka.message.offset" +""" +Deprecated: Replaced by `messaging.kafka.offset`. +""" + +MESSAGING_KAFKA_MESSAGE_TOMBSTONE: Final = "messaging.kafka.message.tombstone" +""" +A boolean that is true if the message is a tombstone. +""" + +MESSAGING_KAFKA_OFFSET: Final = "messaging.kafka.offset" +""" +The offset of a record in the corresponding Kafka partition. +""" + +MESSAGING_MESSAGE_BODY_SIZE: Final = "messaging.message.body.size" +""" +The size of the message body in bytes. +Note: This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed +body size should be used. +""" + +MESSAGING_MESSAGE_CONVERSATION_ID: Final = "messaging.message.conversation_id" +""" +The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". +""" + +MESSAGING_MESSAGE_ENVELOPE_SIZE: Final = "messaging.message.envelope.size" +""" +The size of the message body and metadata in bytes. +Note: This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed +size should be used. +""" + +MESSAGING_MESSAGE_ID: Final = "messaging.message.id" +""" +A value used by the messaging system as an identifier for the message, represented as a string. +""" + +MESSAGING_OPERATION: Final = "messaging.operation" +""" +Deprecated: Replaced by `messaging.operation.type`. +""" + +MESSAGING_OPERATION_NAME: Final = "messaging.operation.name" +""" +The system-specific name of the messaging operation. +""" + +MESSAGING_OPERATION_TYPE: Final = "messaging.operation.type" +""" +A string identifying the type of the messaging operation. +Note: If a custom value is used, it MUST be of low cardinality. +""" + +MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY: Final = "messaging.rabbitmq.destination.routing_key" +""" +RabbitMQ message routing key. +""" + +MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG: Final = "messaging.rabbitmq.message.delivery_tag" +""" +RabbitMQ message delivery tag. +""" + +MESSAGING_ROCKETMQ_CLIENT_GROUP: Final = "messaging.rocketmq.client_group" +""" +Deprecated: Replaced by `messaging.consumer.group.name` on the consumer spans. No replacement for producer spans. +""" + +MESSAGING_ROCKETMQ_CONSUMPTION_MODEL: Final = "messaging.rocketmq.consumption_model" +""" +Model of message consumption. This only applies to consumer spans. +""" + +MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL: Final = "messaging.rocketmq.message.delay_time_level" +""" +The delay time level for delay message, which determines the message delay time. +""" + +MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP: Final = "messaging.rocketmq.message.delivery_timestamp" +""" +The timestamp in milliseconds that the delay message is expected to be delivered to consumer. +""" + +MESSAGING_ROCKETMQ_MESSAGE_GROUP: Final = "messaging.rocketmq.message.group" +""" +It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. +""" + +MESSAGING_ROCKETMQ_MESSAGE_KEYS: Final = "messaging.rocketmq.message.keys" +""" +Key(s) of message, another way to mark message besides message ID. +""" + +MESSAGING_ROCKETMQ_MESSAGE_TAG: Final = "messaging.rocketmq.message.tag" +""" +The secondary classifier of message besides topic. +""" + +MESSAGING_ROCKETMQ_MESSAGE_TYPE: Final = "messaging.rocketmq.message.type" +""" +Type of message. +""" + +MESSAGING_ROCKETMQ_NAMESPACE: Final = "messaging.rocketmq.namespace" +""" +Namespace of RocketMQ resources, resources in different namespaces are individual. +""" + +MESSAGING_SERVICEBUS_DESTINATION_SUBSCRIPTION_NAME: Final = "messaging.servicebus.destination.subscription_name" +""" +Deprecated: Replaced by `messaging.destination.subscription.name`. +""" + +MESSAGING_SERVICEBUS_DISPOSITION_STATUS: Final = "messaging.servicebus.disposition_status" +""" +Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). +""" + +MESSAGING_SERVICEBUS_MESSAGE_DELIVERY_COUNT: Final = "messaging.servicebus.message.delivery_count" +""" +Number of deliveries that have been attempted for this message. +""" + +MESSAGING_SERVICEBUS_MESSAGE_ENQUEUED_TIME: Final = "messaging.servicebus.message.enqueued_time" +""" +The UTC epoch seconds at which the message has been accepted and stored in the entity. +""" + +MESSAGING_SYSTEM: Final = "messaging.system" +""" +The messaging system as identified by the client instrumentation. +Note: The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. +""" + + +class MessagingOperationTypeValues(Enum): + CREATE = "create" + """A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch sending scenarios.""" + SEND = "send" + """One or more messages are provided for sending to an intermediary. If a single message is sent, the context of the "Send" span can be used as the creation context and no "Create" span needs to be created.""" + RECEIVE = "receive" + """One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages.""" + PROCESS = "process" + """One or more messages are processed by a consumer.""" + SETTLE = "settle" + """One or more messages are settled.""" + DELIVER = "deliver" + """Deprecated: Replaced by `process`.""" + PUBLISH = "publish" + """Deprecated: Replaced by `send`.""" + + +class MessagingRocketmqConsumptionModelValues(Enum): + CLUSTERING = "clustering" + """Clustering consumption model.""" + BROADCASTING = "broadcasting" + """Broadcasting consumption model.""" + + +class MessagingRocketmqMessageTypeValues(Enum): + NORMAL = "normal" + """Normal message.""" + FIFO = "fifo" + """FIFO message.""" + DELAY = "delay" + """Delay message.""" + TRANSACTION = "transaction" + """Transaction message.""" + + +class MessagingServicebusDispositionStatusValues(Enum): + COMPLETE = "complete" + """Message is completed.""" + ABANDON = "abandon" + """Message is abandoned.""" + DEAD_LETTER = "dead_letter" + """Message is sent to dead letter queue.""" + DEFER = "defer" + """Message is deferred.""" + + +class MessagingSystemValues(Enum): + ACTIVEMQ = "activemq" + """Apache ActiveMQ.""" + AWS_SNS = "aws.sns" + """Amazon Simple Notification Service (SNS).""" + AWS_SQS = "aws_sqs" + """Amazon Simple Queue Service (SQS).""" + EVENTGRID = "eventgrid" + """Azure Event Grid.""" + EVENTHUBS = "eventhubs" + """Azure Event Hubs.""" + SERVICEBUS = "servicebus" + """Azure Service Bus.""" + GCP_PUBSUB = "gcp_pubsub" + """Google Cloud Pub/Sub.""" + JMS = "jms" + """Java Message Service.""" + KAFKA = "kafka" + """Apache Kafka.""" + RABBITMQ = "rabbitmq" + """RabbitMQ.""" + ROCKETMQ = "rocketmq" + """Apache RocketMQ.""" + PULSAR = "pulsar" + """Apache Pulsar.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py new file mode 100644 index 00000000000..fab03d197c0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py @@ -0,0 +1,106 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +NET_HOST_IP: Final = "net.host.ip" +""" +Deprecated: Replaced by `network.local.address`. +""" + +NET_HOST_NAME: Final = "net.host.name" +""" +Deprecated: Replaced by `server.address`. +""" + +NET_HOST_PORT: Final = "net.host.port" +""" +Deprecated: Replaced by `server.port`. +""" + +NET_PEER_IP: Final = "net.peer.ip" +""" +Deprecated: Replaced by `network.peer.address`. +""" + +NET_PEER_NAME: Final = "net.peer.name" +""" +Deprecated: Replaced by `server.address` on client spans and `client.address` on server spans. +""" + +NET_PEER_PORT: Final = "net.peer.port" +""" +Deprecated: Replaced by `server.port` on client spans and `client.port` on server spans. +""" + +NET_PROTOCOL_NAME: Final = "net.protocol.name" +""" +Deprecated: Replaced by `network.protocol.name`. +""" + +NET_PROTOCOL_VERSION: Final = "net.protocol.version" +""" +Deprecated: Replaced by `network.protocol.version`. +""" + +NET_SOCK_FAMILY: Final = "net.sock.family" +""" +Deprecated: Split to `network.transport` and `network.type`. +""" + +NET_SOCK_HOST_ADDR: Final = "net.sock.host.addr" +""" +Deprecated: Replaced by `network.local.address`. +""" + +NET_SOCK_HOST_PORT: Final = "net.sock.host.port" +""" +Deprecated: Replaced by `network.local.port`. +""" + +NET_SOCK_PEER_ADDR: Final = "net.sock.peer.addr" +""" +Deprecated: Replaced by `network.peer.address`. +""" + +NET_SOCK_PEER_NAME: Final = "net.sock.peer.name" +""" +Deprecated: Removed. No replacement at this time. +""" + +NET_SOCK_PEER_PORT: Final = "net.sock.peer.port" +""" +Deprecated: Replaced by `network.peer.port`. +""" + +NET_TRANSPORT: Final = "net.transport" +""" +Deprecated: Replaced by `network.transport`. +""" + + +@deprecated("The attribute net.sock.family is deprecated - Split to `network.transport` and `network.type`") +class NetSockFamilyValues(Enum): + INET = "inet" + """IPv4 address.""" + INET6 = "inet6" + """IPv6 address.""" + UNIX = "unix" + """UNIX domain socket path.""" + + +@deprecated("The attribute net.transport is deprecated - Replaced by `network.transport`") +class NetTransportValues(Enum): + IP_TCP = "ip_tcp" + """ip_tcp.""" + IP_UDP = "ip_udp" + """ip_udp.""" + PIPE = "pipe" + """Named or anonymous pipe.""" + INPROC = "inproc" + """In-process communication.""" + OTHER = "other" + """Something else (non IP-based).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py new file mode 100644 index 00000000000..823b46159e3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py @@ -0,0 +1,209 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +NETWORK_CARRIER_ICC: Final = "network.carrier.icc" +""" +The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. +""" + +NETWORK_CARRIER_MCC: Final = "network.carrier.mcc" +""" +The mobile carrier country code. +""" + +NETWORK_CARRIER_MNC: Final = "network.carrier.mnc" +""" +The mobile carrier network code. +""" + +NETWORK_CARRIER_NAME: Final = "network.carrier.name" +""" +The name of the mobile carrier. +""" + +NETWORK_CONNECTION_STATE: Final = "network.connection.state" +""" +The state of network connection. +Note: Connection states are defined as part of the [rfc9293](https://datatracker.ietf.org/doc/html/rfc9293#section-3.3.2). +""" + +NETWORK_CONNECTION_SUBTYPE: Final = "network.connection.subtype" +""" +This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a Wi-Fi connection. +""" + +NETWORK_CONNECTION_TYPE: Final = "network.connection.type" +""" +The internet connection type. +""" + +NETWORK_INTERFACE_NAME: Final = "network.interface.name" +""" +The network interface name. +""" + +NETWORK_IO_DIRECTION: Final = "network.io.direction" +""" +The direction of traffic from the perspective of the observing host's physical or virtual network interface. It should not be used to represent the logical direction of a stateful connection or network flow. +""" + +NETWORK_LOCAL_ADDRESS: Final = "network.local.address" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_LOCAL_ADDRESS`. +""" + +NETWORK_LOCAL_PORT: Final = "network.local.port" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_LOCAL_PORT`. +""" + +NETWORK_PEER_ADDRESS: Final = "network.peer.address" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PEER_ADDRESS`. +""" + +NETWORK_PEER_PORT: Final = "network.peer.port" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PEER_PORT`. +""" + +NETWORK_PROTOCOL_NAME: Final = "network.protocol.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PROTOCOL_NAME`. +""" + +NETWORK_PROTOCOL_VERSION: Final = "network.protocol.version" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PROTOCOL_VERSION`. +""" + +NETWORK_TRANSPORT: Final = "network.transport" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_TRANSPORT`. +""" + +NETWORK_TYPE: Final = "network.type" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_TYPE`. +""" + + +class NetworkConnectionStateValues(Enum): + CLOSED = "closed" + """closed.""" + CLOSE_WAIT = "close_wait" + """close_wait.""" + CLOSING = "closing" + """closing.""" + ESTABLISHED = "established" + """established.""" + FIN_WAIT_1 = "fin_wait_1" + """fin_wait_1.""" + FIN_WAIT_2 = "fin_wait_2" + """fin_wait_2.""" + LAST_ACK = "last_ack" + """last_ack.""" + LISTEN = "listen" + """listen.""" + SYN_RECEIVED = "syn_received" + """syn_received.""" + SYN_SENT = "syn_sent" + """syn_sent.""" + TIME_WAIT = "time_wait" + """time_wait.""" + + +class NetworkConnectionSubtypeValues(Enum): + GPRS = "gprs" + """GPRS.""" + EDGE = "edge" + """EDGE.""" + UMTS = "umts" + """UMTS.""" + CDMA = "cdma" + """CDMA.""" + EVDO_0 = "evdo_0" + """EVDO Rel. 0.""" + EVDO_A = "evdo_a" + """EVDO Rev. A.""" + CDMA2000_1XRTT = "cdma2000_1xrtt" + """CDMA2000 1XRTT.""" + HSDPA = "hsdpa" + """HSDPA.""" + HSUPA = "hsupa" + """HSUPA.""" + HSPA = "hspa" + """HSPA.""" + IDEN = "iden" + """IDEN.""" + EVDO_B = "evdo_b" + """EVDO Rev. B.""" + LTE = "lte" + """LTE.""" + EHRPD = "ehrpd" + """EHRPD.""" + HSPAP = "hspap" + """HSPAP.""" + GSM = "gsm" + """GSM.""" + TD_SCDMA = "td_scdma" + """TD-SCDMA.""" + IWLAN = "iwlan" + """IWLAN.""" + NR = "nr" + """5G NR (New Radio).""" + NRNSA = "nrnsa" + """5G NRNSA (New Radio Non-Standalone).""" + LTE_CA = "lte_ca" + """LTE CA.""" + + +class NetworkConnectionTypeValues(Enum): + WIFI = "wifi" + """Wi-Fi.""" + WIRED = "wired" + """wired.""" + CELL = "cell" + """cell.""" + UNAVAILABLE = "unavailable" + """unavailable.""" + UNKNOWN = "unknown" + """unknown.""" + + +class NetworkIoDirectionValues(Enum): + TRANSMIT = "transmit" + """transmit.""" + RECEIVE = "receive" + """receive.""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues`." +) +class NetworkTransportValues(Enum): + TCP = "tcp" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.TCP`.""" + UDP = "udp" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.UDP`.""" + PIPE = "pipe" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.PIPE`.""" + UNIX = "unix" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.UNIX`.""" + QUIC = "quic" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.QUIC`.""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues`." +) +class NetworkTypeValues(Enum): + IPV4 = "ipv4" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues.IPV4`.""" + IPV6 = "ipv6" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues.IPV6`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py new file mode 100644 index 00000000000..3ef1dd50117 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py @@ -0,0 +1,14 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +NFS_OPERATION_NAME: Final = "nfs.operation.name" +""" +NFSv4+ operation name. +""" + +NFS_SERVER_REPCACHE_STATUS: Final = "nfs.server.repcache.status" +""" +Linux: one of "hit" (NFSD_STATS_RC_HITS), "miss" (NFSD_STATS_RC_MISSES), or "nocache" (NFSD_STATS_RC_NOCACHE -- uncacheable). +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py new file mode 100644 index 00000000000..c3342c0fec1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py @@ -0,0 +1,11 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +OCI_MANIFEST_DIGEST: Final = "oci.manifest.digest" +""" +The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. +Note: Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). +An example can be found in [Example Image Manifest](https://github.com/opencontainers/image-spec/blob/main/manifest.md#example-image-manifest). +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py new file mode 100644 index 00000000000..eecf84ceae5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py @@ -0,0 +1,24 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +ONC_RPC_PROCEDURE_NAME: Final = "onc_rpc.procedure.name" +""" +ONC/Sun RPC procedure name. +""" + +ONC_RPC_PROCEDURE_NUMBER: Final = "onc_rpc.procedure.number" +""" +ONC/Sun RPC procedure number. +""" + +ONC_RPC_PROGRAM_NAME: Final = "onc_rpc.program.name" +""" +ONC/Sun RPC program name. +""" + +ONC_RPC_VERSION: Final = "onc_rpc.version" +""" +ONC/Sun RPC program version. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py new file mode 100644 index 00000000000..df471c66079 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py @@ -0,0 +1,47 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +OPENAI_API_TYPE: Final = "openai.api.type" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +OPENAI_REQUEST_SERVICE_TIER: Final = "openai.request.service_tier" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +OPENAI_RESPONSE_SERVICE_TIER: Final = "openai.response.service_tier" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + +OPENAI_RESPONSE_SYSTEM_FINGERPRINT: Final = "openai.response.system_fingerprint" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +@deprecated( + "The attribute openai.api.type is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class OpenaiApiTypeValues(Enum): + CHAT_COMPLETIONS = "chat_completions" + """The OpenAI [Chat Completions API](https://developers.openai.com/api/reference/chat-completions/overview).""" + RESPONSES = "responses" + """The OpenAI [Responses API](https://developers.openai.com/api/reference/responses/overview).""" + + +@deprecated( + "The attribute openai.request.service_tier is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" +) +class OpenaiRequestServiceTierValues(Enum): + AUTO = "auto" + """The system will utilize scale tier credits until they are exhausted.""" + DEFAULT = "default" + """The system will utilize the default scale tier.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py new file mode 100644 index 00000000000..db1abf01285 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py @@ -0,0 +1,14 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +OPENSHIFT_CLUSTERQUOTA_NAME: Final = "openshift.clusterquota.name" +""" +The name of the cluster quota. +""" + +OPENSHIFT_CLUSTERQUOTA_UID: Final = "openshift.clusterquota.uid" +""" +The UID of the cluster quota. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py new file mode 100644 index 00000000000..5237de935fe --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py @@ -0,0 +1,18 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +OPENTRACING_REF_TYPE: Final = "opentracing.ref_type" +""" +Parent-child Reference type. +Note: The causal relationship between a child Span and a parent Span. +""" + + +class OpentracingRefTypeValues(Enum): + CHILD_OF = "child_of" + """The parent Span depends on the child Span in some capacity.""" + FOLLOWS_FROM = "follows_from" + """The parent Span doesn't depend in any way on the result of the child Span.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py new file mode 100644 index 00000000000..191be10f98a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py @@ -0,0 +1,47 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +ORACLE_DB_DOMAIN: Final = "oracle.db.domain" +""" +The database domain associated with the connection. +Note: This attribute SHOULD be set to the value of the `DB_DOMAIN` initialization parameter, +as exposed in `v$parameter`. `DB_DOMAIN` defines the domain portion of the global +database name and SHOULD be configured when a database is, or may become, part of a +distributed environment. Its value consists of one or more valid identifiers +(alphanumeric ASCII characters) separated by periods. +""" + +ORACLE_DB_INSTANCE_NAME: Final = "oracle.db.instance.name" +""" +The instance name associated with the connection in an Oracle Real Application Clusters environment. +Note: There can be multiple instances associated with a single database service. It indicates the +unique instance name to which the connection is currently bound. For non-RAC databases, this value +defaults to the `oracle.db.name`. +""" + +ORACLE_DB_NAME: Final = "oracle.db.name" +""" +The database name associated with the connection. +Note: This attribute SHOULD be set to the value of the parameter `DB_NAME` exposed in `v$parameter`. +""" + +ORACLE_DB_PDB: Final = "oracle.db.pdb" +""" +The pluggable database (PDB) name associated with the connection. +Note: This attribute SHOULD reflect the PDB that the session is currently connected to. +If instrumentation cannot reliably obtain the active PDB name for each operation +without issuing an additional query (such as `SELECT SYS_CONTEXT`), it is +RECOMMENDED to fall back to the PDB name specified at connection establishment. +""" + +ORACLE_DB_SERVICE: Final = "oracle.db.service" +""" +The service name currently associated with the database connection. +Note: The effective service name for a connection can change during its lifetime, +for example after executing SQL, `ALTER SESSION`. If an instrumentation cannot reliably +obtain the current service name for each operation without issuing an additional +query (such as `SELECT SYS_CONTEXT`), it is RECOMMENDED to fall back to the +service name originally provided at connection establishment. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py new file mode 100644 index 00000000000..a829590b83f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py @@ -0,0 +1,10 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +ORACLE_CLOUD_REALM: Final = "oracle_cloud.realm" +""" +The OCI realm identifier that indicates the isolated partition in which the tenancy and its resources reside. +Note: See [OCI documentation on realms](https://docs.oracle.com/iaas/Content/General/Concepts/regions.htm). +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py new file mode 100644 index 00000000000..b10d4bdd8d9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py @@ -0,0 +1,57 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +OS_BUILD_ID: Final = "os.build_id" +""" +Unique identifier for a particular build or compilation of the operating system. +""" + +OS_DESCRIPTION: Final = "os.description" +""" +Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. +""" + +OS_NAME: Final = "os.name" +""" +Human readable operating system name. +""" + +OS_TYPE: Final = "os.type" +""" +The operating system type. +""" + +OS_VERSION: Final = "os.version" +""" +The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). +""" + + +class OsTypeValues(Enum): + WINDOWS = "windows" + """Microsoft Windows.""" + LINUX = "linux" + """Linux.""" + DARWIN = "darwin" + """Apple Darwin.""" + FREEBSD = "freebsd" + """FreeBSD.""" + NETBSD = "netbsd" + """NetBSD.""" + OPENBSD = "openbsd" + """OpenBSD.""" + DRAGONFLYBSD = "dragonflybsd" + """DragonFly BSD.""" + HPUX = "hpux" + """HP-UX (Hewlett Packard UNIX).""" + AIX = "aix" + """AIX (Advanced Interactive eXecutive).""" + SOLARIS = "solaris" + """SunOS, Oracle Solaris.""" + Z_OS = "z_os" + """Deprecated: Replaced by `zos`.""" + ZOS = "zos" + """IBM z/OS.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py new file mode 100644 index 00000000000..46f98750b24 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py @@ -0,0 +1,145 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +OTEL_COMPONENT_NAME: Final = "otel.component.name" +""" +A name uniquely identifying the instance of the OpenTelemetry component within its containing SDK instance. +Note: Implementations SHOULD ensure a low cardinality for this attribute, even across application or SDK restarts. +E.g. implementations MUST NOT use UUIDs as values for this attribute. + +Implementations MAY achieve these goals by following a `/` pattern, e.g. `batching_span_processor/0`. +Hereby `otel.component.type` refers to the corresponding attribute value of the component. + +The value of `instance-counter` MAY be automatically assigned by the component and uniqueness within the enclosing SDK instance MUST be guaranteed. +For example, `` MAY be implemented by using a monotonically increasing counter (starting with `0`), which is incremented every time an +instance of the given component type is started. + +With this implementation, for example the first Batching Span Processor would have `batching_span_processor/0` +as `otel.component.name`, the second one `batching_span_processor/1` and so on. +These values will therefore be reused in the case of an application restart. +""" + +OTEL_COMPONENT_TYPE: Final = "otel.component.type" +""" +A name identifying the type of the OpenTelemetry component. +Note: If none of the standardized values apply, implementations SHOULD use the language-defined name of the type. +E.g. for Java the fully qualified classname SHOULD be used in this case. +""" + +OTEL_EVENT_NAME: Final = "otel.event.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_EVENT_NAME`. +""" + +OTEL_LIBRARY_NAME: Final = "otel.library.name" +""" +Deprecated: Replaced by `otel.scope.name`. +""" + +OTEL_LIBRARY_VERSION: Final = "otel.library.version" +""" +Deprecated: Replaced by `otel.scope.version`. +""" + +OTEL_SCOPE_NAME: Final = "otel.scope.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_SCOPE_NAME`. +""" + +OTEL_SCOPE_SCHEMA_URL: Final = "otel.scope.schema_url" +""" +The schema URL of the instrumentation scope. +""" + +OTEL_SCOPE_VERSION: Final = "otel.scope.version" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_SCOPE_VERSION`. +""" + +OTEL_SPAN_PARENT_ORIGIN: Final = "otel.span.parent.origin" +""" +Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote). +""" + +OTEL_SPAN_SAMPLING_RESULT: Final = "otel.span.sampling_result" +""" +The result value of the sampler for this span. +""" + +OTEL_STATUS_CODE: Final = "otel.status_code" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_STATUS_CODE`. +""" + +OTEL_STATUS_DESCRIPTION: Final = "otel.status_description" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_STATUS_DESCRIPTION`. +""" + + +class OtelComponentTypeValues(Enum): + BATCHING_SPAN_PROCESSOR = "batching_span_processor" + """The built-in SDK batching span processor.""" + SIMPLE_SPAN_PROCESSOR = "simple_span_processor" + """The built-in SDK simple span processor.""" + BATCHING_LOG_PROCESSOR = "batching_log_processor" + """The built-in SDK batching log record processor.""" + SIMPLE_LOG_PROCESSOR = "simple_log_processor" + """The built-in SDK simple log record processor.""" + OTLP_GRPC_SPAN_EXPORTER = "otlp_grpc_span_exporter" + """OTLP span exporter over gRPC with protobuf serialization.""" + OTLP_HTTP_SPAN_EXPORTER = "otlp_http_span_exporter" + """OTLP span exporter over HTTP with protobuf serialization.""" + OTLP_HTTP_JSON_SPAN_EXPORTER = "otlp_http_json_span_exporter" + """OTLP span exporter over HTTP with JSON serialization.""" + ZIPKIN_HTTP_SPAN_EXPORTER = "zipkin_http_span_exporter" + """Zipkin span exporter over HTTP.""" + OTLP_GRPC_LOG_EXPORTER = "otlp_grpc_log_exporter" + """OTLP log record exporter over gRPC with protobuf serialization.""" + OTLP_HTTP_LOG_EXPORTER = "otlp_http_log_exporter" + """OTLP log record exporter over HTTP with protobuf serialization.""" + OTLP_HTTP_JSON_LOG_EXPORTER = "otlp_http_json_log_exporter" + """OTLP log record exporter over HTTP with JSON serialization.""" + PERIODIC_METRIC_READER = "periodic_metric_reader" + """The built-in SDK periodically exporting metric reader.""" + OTLP_GRPC_METRIC_EXPORTER = "otlp_grpc_metric_exporter" + """OTLP metric exporter over gRPC with protobuf serialization.""" + OTLP_HTTP_METRIC_EXPORTER = "otlp_http_metric_exporter" + """OTLP metric exporter over HTTP with protobuf serialization.""" + OTLP_HTTP_JSON_METRIC_EXPORTER = "otlp_http_json_metric_exporter" + """OTLP metric exporter over HTTP with JSON serialization.""" + PROMETHEUS_HTTP_TEXT_METRIC_EXPORTER = "prometheus_http_text_metric_exporter" + """Prometheus metric exporter over HTTP with the default text-based format.""" + + +class OtelSpanParentOriginValues(Enum): + NONE = "none" + """The span does not have a parent, it is a root span.""" + LOCAL = "local" + """The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is false.""" + REMOTE = "remote" + """The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is true.""" + + +class OtelSpanSamplingResultValues(Enum): + DROP = "DROP" + """The span is not sampled and not recording.""" + RECORD_ONLY = "RECORD_ONLY" + """The span is not sampled, but recording.""" + RECORD_AND_SAMPLE = "RECORD_AND_SAMPLE" + """The span is sampled and recording.""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues`." +) +class OtelStatusCodeValues(Enum): + OK = "OK" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues.OK`.""" + ERROR = "ERROR" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues.ERROR`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py new file mode 100644 index 00000000000..a447aaa6bb4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py @@ -0,0 +1,20 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +STATE: Final = "state" +""" +Deprecated: Replaced by `db.client.connection.state`. +""" + + +@deprecated("The attribute state is deprecated - Replaced by `db.client.connection.state`") +class StateValues(Enum): + IDLE = "idle" + """idle.""" + USED = "used" + """used.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py new file mode 100644 index 00000000000..27ff455a696 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +PEER_SERVICE: Final = "peer.service" +""" +Deprecated: Replaced by `service.peer.name`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py new file mode 100644 index 00000000000..cd3fa908184 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +POOL_NAME: Final = "pool.name" +""" +Deprecated: Replaced by `db.client.connection.pool.name`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py new file mode 100644 index 00000000000..f99c8a3b9eb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py @@ -0,0 +1,62 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +PPROF_LOCATION_IS_FOLDED: Final = "pprof.location.is_folded" +""" +Provides an indication that multiple symbols map to this location's address, for example due to identical code folding by the linker. In that case the line information represents one of the multiple symbols. This field must be recomputed when the symbolization state of the profile changes. +""" + +PPROF_MAPPING_HAS_FILENAMES: Final = "pprof.mapping.has_filenames" +""" +Indicates that there are filenames related to this mapping. +""" + +PPROF_MAPPING_HAS_FUNCTIONS: Final = "pprof.mapping.has_functions" +""" +Indicates that there are functions related to this mapping. +""" + +PPROF_MAPPING_HAS_INLINE_FRAMES: Final = "pprof.mapping.has_inline_frames" +""" +Indicates that there are inline frames related to this mapping. +""" + +PPROF_MAPPING_HAS_LINE_NUMBERS: Final = "pprof.mapping.has_line_numbers" +""" +Indicates that there are line numbers related to this mapping. +""" + +PPROF_PROFILE_COMMENT: Final = "pprof.profile.comment" +""" +Free-form text associated with the profile. This field should not be used to store any machine-readable information, it is only for human-friendly content. +""" + +PPROF_PROFILE_DOC_URL: Final = "pprof.profile.doc_url" +""" +Documentation link for this profile type. +Note: The URL must be absolute and may be missing if the profile was generated by code that did not supply a link. +""" + +PPROF_PROFILE_DROP_FRAMES: Final = "pprof.profile.drop_frames" +""" +Frames with Function.function_name fully matching the regular expression will be dropped from the samples, along with their successors. +""" + +PPROF_PROFILE_KEEP_FRAMES: Final = "pprof.profile.keep_frames" +""" +Frames with Function.function_name fully matching the regular expression will be kept, even if it matches drop_frames. +""" + +PPROF_SCOPE_DEFAULT_SAMPLE_TYPE: Final = "pprof.scope.default_sample_type" +""" +Records the pprof's default_sample_type in the original profile. Not set if the default sample type was missing. +Note: This attribute, if present, MUST be set at the scope level (resource_profiles[].scope_profiles[].scope.attributes[]). +""" + +PPROF_SCOPE_SAMPLE_TYPE_ORDER: Final = "pprof.scope.sample_type_order" +""" +Records the indexes of the sample types in the original profile. +Note: This attribute, if present, MUST be set at the scope level (resource_profiles[].scope_profiles[].scope.attributes[]). +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py new file mode 100644 index 00000000000..a548988633a --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py @@ -0,0 +1,253 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +PROCESS_ARGS_COUNT: Final = "process.args_count" +""" +Length of the process.command_args array. +Note: This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity. +""" + +PROCESS_COMMAND: Final = "process.command" +""" +The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. +""" + +PROCESS_COMMAND_ARGS: Final = "process.command_args" +""" +All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. SHOULD NOT be collected by default unless there is sanitization that excludes sensitive data. +""" + +PROCESS_COMMAND_LINE: Final = "process.command_line" +""" +The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. SHOULD NOT be collected by default unless there is sanitization that excludes sensitive data. +""" + +PROCESS_CONTEXT_SWITCH_TYPE: Final = "process.context_switch.type" +""" +Specifies whether the context switches for this data point were voluntary or involuntary. +""" + +PROCESS_CPU_STATE: Final = "process.cpu.state" +""" +Deprecated: Replaced by `cpu.mode`. +""" + +PROCESS_CREATION_TIME: Final = "process.creation.time" +""" +The date and time the process was created, in ISO 8601 format. +""" + +PROCESS_ENVIRONMENT_VARIABLE_TEMPLATE: Final = "process.environment_variable" +""" +Process environment variables, `` being the environment variable name, the value being the environment variable value. +Note: Examples: + +- an environment variable `USER` with value `"ubuntu"` SHOULD be recorded +as the `process.environment_variable.USER` attribute with value `"ubuntu"`. + +- an environment variable `PATH` with value `"/usr/local/bin:/usr/bin"` +SHOULD be recorded as the `process.environment_variable.PATH` attribute +with value `"/usr/local/bin:/usr/bin"`. +""" + +PROCESS_EXECUTABLE_BUILD_ID_GNU: Final = "process.executable.build_id.gnu" +""" +The GNU build ID as found in the `.note.gnu.build-id` ELF section (hex string). +""" + +PROCESS_EXECUTABLE_BUILD_ID_GO: Final = "process.executable.build_id.go" +""" +The Go build ID as retrieved by `go tool buildid `. +""" + +PROCESS_EXECUTABLE_BUILD_ID_HTLHASH: Final = "process.executable.build_id.htlhash" +""" +Deterministic build ID for executables. +Note: GNU and Go build IDs may be stripped or unavailable in some environments +(e.g., Alpine Linux, Docker images). This attribute provides a deterministic +build ID computed by hashing the first and last 4096 bytes of the file +along with its length: + +``` +Input ← Concat(File[:4096], File[-4096:], BigEndianUInt64(Len(File))) +Digest ← SHA256(Input) +BuildID ← Digest[:16] +``` + +The result is the first 16 bytes (128 bits) of the SHA256 digest, +represented as a hex string. +""" + +PROCESS_EXECUTABLE_BUILD_ID_PROFILING: Final = "process.executable.build_id.profiling" +""" +Deprecated: Replaced by `process.executable.build_id.htlhash`. +""" + +PROCESS_EXECUTABLE_NAME: Final = "process.executable.name" +""" +The name of the process executable. On Linux based systems, this SHOULD be set to the base name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to the base name of `GetProcessImageFileNameW`. +""" + +PROCESS_EXECUTABLE_PATH: Final = "process.executable.path" +""" +The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. +""" + +PROCESS_EXIT_CODE: Final = "process.exit.code" +""" +The exit code of the process. +""" + +PROCESS_EXIT_TIME: Final = "process.exit.time" +""" +The date and time the process exited, in ISO 8601 format. +""" + +PROCESS_GROUP_LEADER_PID: Final = "process.group_leader.pid" +""" +The PID of the process's group leader. This is also the process group ID (PGID) of the process. +""" + +PROCESS_INTERACTIVE: Final = "process.interactive" +""" +Whether the process is connected to an interactive shell. +""" + +PROCESS_LINUX_CGROUP: Final = "process.linux.cgroup" +""" +The control group associated with the process. +Note: Control groups (cgroups) are a kernel feature used to organize and manage process resources. This attribute provides the path(s) to the cgroup(s) associated with the process, which should match the contents of the [/proc/\\[PID\\]/cgroup](https://man7.org/linux/man-pages/man7/cgroups.7.html) file. +""" + +PROCESS_OWNER: Final = "process.owner" +""" +The username of the user that owns the process. +""" + +PROCESS_PAGING_FAULT_TYPE: Final = "process.paging.fault_type" +""" +Deprecated: Replaced by `system.paging.fault.type`. +""" + +PROCESS_PARENT_PID: Final = "process.parent_pid" +""" +Parent Process identifier (PPID). +""" + +PROCESS_PID: Final = "process.pid" +""" +Process identifier (PID). +""" + +PROCESS_REAL_USER_ID: Final = "process.real_user.id" +""" +The real user ID (RUID) of the process. +""" + +PROCESS_REAL_USER_NAME: Final = "process.real_user.name" +""" +The username of the real user of the process. +""" + +PROCESS_RUNTIME_DESCRIPTION: Final = "process.runtime.description" +""" +An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. +""" + +PROCESS_RUNTIME_NAME: Final = "process.runtime.name" +""" +The name of the runtime of this process. +""" + +PROCESS_RUNTIME_VERSION: Final = "process.runtime.version" +""" +The version of the runtime of this process, as returned by the runtime without modification. +""" + +PROCESS_SAVED_USER_ID: Final = "process.saved_user.id" +""" +The saved user ID (SUID) of the process. +""" + +PROCESS_SAVED_USER_NAME: Final = "process.saved_user.name" +""" +The username of the saved user. +""" + +PROCESS_SESSION_LEADER_PID: Final = "process.session_leader.pid" +""" +The PID of the process's session leader. This is also the session ID (SID) of the process. +""" + +PROCESS_STATE: Final = "process.state" +""" +The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES). +""" + +PROCESS_TITLE: Final = "process.title" +""" +Process title (proctitle). +Note: In many Unix-like systems, process title (proctitle), is the string that represents the name or command line of a running process, displayed by system monitoring tools like ps, top, and htop. +""" + +PROCESS_USER_ID: Final = "process.user.id" +""" +The effective user ID (EUID) of the process. +""" + +PROCESS_USER_NAME: Final = "process.user.name" +""" +The username of the effective user of the process. +""" + +PROCESS_VPID: Final = "process.vpid" +""" +Virtual process identifier. +Note: The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. +""" + +PROCESS_WORKING_DIRECTORY: Final = "process.working_directory" +""" +The working directory of the process. +""" + + +class ProcessContextSwitchTypeValues(Enum): + VOLUNTARY = "voluntary" + """voluntary.""" + INVOLUNTARY = "involuntary" + """involuntary.""" + + +@deprecated("The attribute process.cpu.state is deprecated - Replaced by `cpu.mode`") +class ProcessCpuStateValues(Enum): + SYSTEM = "system" + """system.""" + USER = "user" + """user.""" + WAIT = "wait" + """wait.""" + + +@deprecated("The attribute process.paging.fault_type is deprecated - Replaced by `system.paging.fault.type`") +class ProcessPagingFaultTypeValues(Enum): + MAJOR = "major" + """major.""" + MINOR = "minor" + """minor.""" + + +class ProcessStateValues(Enum): + RUNNING = "running" + """running.""" + SLEEPING = "sleeping" + """sleeping.""" + STOPPED = "stopped" + """stopped.""" + DEFUNCT = "defunct" + """defunct.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py new file mode 100644 index 00000000000..7fd6de26520 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py @@ -0,0 +1,39 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +PROFILE_FRAME_TYPE: Final = "profile.frame.type" +""" +Describes the interpreter or compiler of a single frame. +""" + + +class ProfileFrameTypeValues(Enum): + DOTNET = "dotnet" + """[.NET](https://wikipedia.org/wiki/.NET).""" + JVM = "jvm" + """[JVM](https://wikipedia.org/wiki/Java_virtual_machine).""" + KERNEL = "kernel" + """[Kernel](https://wikipedia.org/wiki/Kernel_(operating_system)).""" + NATIVE = "native" + """Can be one of but not limited to [C](https://wikipedia.org/wiki/C_(programming_language)), [C++](https://wikipedia.org/wiki/C%2B%2B), [Go](https://wikipedia.org/wiki/Go_(programming_language)) or [Rust](https://wikipedia.org/wiki/Rust_(programming_language)). If possible, a more precise value MUST be used.""" + PERL = "perl" + """[Perl](https://wikipedia.org/wiki/Perl).""" + PHP = "php" + """[PHP](https://wikipedia.org/wiki/PHP).""" + CPYTHON = "cpython" + """[Python](https://wikipedia.org/wiki/Python_(programming_language)).""" + RUBY = "ruby" + """[Ruby](https://wikipedia.org/wiki/Ruby_(programming_language)).""" + V8JS = "v8js" + """[V8JS](https://wikipedia.org/wiki/V8_(JavaScript_engine)).""" + BEAM = "beam" + """[Erlang](https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine)).""" + GO = "go" + """[Go](https://wikipedia.org/wiki/Go_(programming_language)),.""" + RUST = "rust" + """[Rust](https://wikipedia.org/wiki/Rust_(programming_language)).""" + LUAJIT = "luajit" + """[LuaJIT](https://en.wikipedia.org/wiki/LuaJIT).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py new file mode 100644 index 00000000000..9802b7bdc73 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py @@ -0,0 +1,264 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +RPC_CONNECT_RPC_ERROR_CODE: Final = "rpc.connect_rpc.error_code" +""" +Deprecated: Replaced by `rpc.response.status_code`. +""" + +RPC_CONNECT_RPC_REQUEST_METADATA_TEMPLATE: Final = "rpc.connect_rpc.request.metadata" +""" +Deprecated: Replaced by `rpc.request.metadata`. +""" + +RPC_CONNECT_RPC_RESPONSE_METADATA_TEMPLATE: Final = "rpc.connect_rpc.response.metadata" +""" +Deprecated: Replaced by `rpc.response.metadata`. +""" + +RPC_GRPC_REQUEST_METADATA_TEMPLATE: Final = "rpc.grpc.request.metadata" +""" +Deprecated: Replaced by `rpc.request.metadata`. +""" + +RPC_GRPC_RESPONSE_METADATA_TEMPLATE: Final = "rpc.grpc.response.metadata" +""" +Deprecated: Replaced by `rpc.response.metadata`. +""" + +RPC_GRPC_STATUS_CODE: Final = "rpc.grpc.status_code" +""" +Deprecated: Use string representation of the gRPC status code on the `rpc.response.status_code` attribute. +""" + +RPC_JSONRPC_ERROR_CODE: Final = "rpc.jsonrpc.error_code" +""" +Deprecated: Use string representation of the error code on the `rpc.response.status_code` attribute. +""" + +RPC_JSONRPC_ERROR_MESSAGE: Final = "rpc.jsonrpc.error_message" +""" +Deprecated: Use the span status description when reporting JSON-RPC spans. +""" + +RPC_JSONRPC_REQUEST_ID: Final = "rpc.jsonrpc.request_id" +""" +Deprecated: Replaced by `jsonrpc.request.id`. +""" + +RPC_JSONRPC_VERSION: Final = "rpc.jsonrpc.version" +""" +Deprecated: Replaced by `jsonrpc.protocol.version`. +""" + +RPC_MESSAGE_COMPRESSED_SIZE: Final = "rpc.message.compressed_size" +""" +Deprecated: Deprecated, no replacement at this time. +""" + +RPC_MESSAGE_ID: Final = "rpc.message.id" +""" +Deprecated: Deprecated, no replacement at this time. +""" + +RPC_MESSAGE_TYPE: Final = "rpc.message.type" +""" +Deprecated: Deprecated, no replacement at this time. +""" + +RPC_MESSAGE_UNCOMPRESSED_SIZE: Final = "rpc.message.uncompressed_size" +""" +Deprecated: Deprecated, no replacement at this time. +""" + +RPC_METHOD: Final = "rpc.method" +""" +The fully-qualified logical name of the method from the RPC interface perspective. +Note: The method name MAY have unbounded cardinality in edge or error cases. + +Some RPC frameworks or libraries provide a fixed set of recognized methods +for client stubs and server implementations. Instrumentations for such +frameworks MUST set this attribute to the original method name only +when the method is recognized by the framework or library. + +When the method is not recognized, for example, when the server receives +a request for a method that is not predefined on the server, or when +instrumentation is not able to reliably detect if the method is predefined, +the attribute MUST be set to `_OTHER`. + +If the RPC instrumentation could end up converting valid RPC methods to +`_OTHER`, then it SHOULD provide a way to configure the list of recognized +RPC methods. + +The `rpc.method` can be different from the name of any implementing +method/function. +The `code.function.name` attribute may be used to record the fully-qualified +method actually executing the call on the server side, or the +RPC client stub method on the client side. +""" + +RPC_METHOD_ORIGINAL: Final = "rpc.method_original" +""" +The original name of the method used by the client. +""" + +RPC_REQUEST_METADATA_TEMPLATE: Final = "rpc.request.metadata" +""" +RPC request metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. +Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +For example, a property `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as +`rpc.request.metadata.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]`. +""" + +RPC_RESPONSE_METADATA_TEMPLATE: Final = "rpc.response.metadata" +""" +RPC response metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. +Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. +Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + +For example, a property `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as +the `rpc.response.metadata.my-custom-key` attribute with value `["attribute_value"]`. +""" + +RPC_RESPONSE_STATUS_CODE: Final = "rpc.response.status_code" +""" +Status code of the RPC returned by the RPC server or generated by the client. +Note: Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. +""" + +RPC_SERVICE: Final = "rpc.service" +""" +Deprecated: Value should be included in `rpc.method` which is expected to be a fully-qualified name. +""" + +RPC_SYSTEM: Final = "rpc.system" +""" +Deprecated: Replaced by `rpc.system.name`. +""" + +RPC_SYSTEM_NAME: Final = "rpc.system.name" +""" +The Remote Procedure Call (RPC) system. +Note: The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC. +""" + + +@deprecated("The attribute rpc.connect_rpc.error_code is deprecated - Replaced by `rpc.response.status_code`") +class RpcConnectRpcErrorCodeValues(Enum): + CANCELLED = "cancelled" + """cancelled.""" + UNKNOWN = "unknown" + """unknown.""" + INVALID_ARGUMENT = "invalid_argument" + """invalid_argument.""" + DEADLINE_EXCEEDED = "deadline_exceeded" + """deadline_exceeded.""" + NOT_FOUND = "not_found" + """not_found.""" + ALREADY_EXISTS = "already_exists" + """already_exists.""" + PERMISSION_DENIED = "permission_denied" + """permission_denied.""" + RESOURCE_EXHAUSTED = "resource_exhausted" + """resource_exhausted.""" + FAILED_PRECONDITION = "failed_precondition" + """failed_precondition.""" + ABORTED = "aborted" + """aborted.""" + OUT_OF_RANGE = "out_of_range" + """out_of_range.""" + UNIMPLEMENTED = "unimplemented" + """unimplemented.""" + INTERNAL = "internal" + """internal.""" + UNAVAILABLE = "unavailable" + """unavailable.""" + DATA_LOSS = "data_loss" + """data_loss.""" + UNAUTHENTICATED = "unauthenticated" + """unauthenticated.""" + + +@deprecated( + "The attribute rpc.grpc.status_code is deprecated - Use string representation of the gRPC status code on the `rpc.response.status_code` attribute" +) +class RpcGrpcStatusCodeValues(Enum): + OK = 0 + """OK.""" + CANCELLED = 1 + """CANCELLED.""" + UNKNOWN = 2 + """UNKNOWN.""" + INVALID_ARGUMENT = 3 + """INVALID_ARGUMENT.""" + DEADLINE_EXCEEDED = 4 + """DEADLINE_EXCEEDED.""" + NOT_FOUND = 5 + """NOT_FOUND.""" + ALREADY_EXISTS = 6 + """ALREADY_EXISTS.""" + PERMISSION_DENIED = 7 + """PERMISSION_DENIED.""" + RESOURCE_EXHAUSTED = 8 + """RESOURCE_EXHAUSTED.""" + FAILED_PRECONDITION = 9 + """FAILED_PRECONDITION.""" + ABORTED = 10 + """ABORTED.""" + OUT_OF_RANGE = 11 + """OUT_OF_RANGE.""" + UNIMPLEMENTED = 12 + """UNIMPLEMENTED.""" + INTERNAL = 13 + """INTERNAL.""" + UNAVAILABLE = 14 + """UNAVAILABLE.""" + DATA_LOSS = 15 + """DATA_LOSS.""" + UNAUTHENTICATED = 16 + """UNAUTHENTICATED.""" + + +@deprecated("The attribute rpc.message.type is deprecated - Deprecated, no replacement at this time") +class RpcMessageTypeValues(Enum): + SENT = "SENT" + """sent.""" + RECEIVED = "RECEIVED" + """received.""" + + +@deprecated("The attribute rpc.system is deprecated - Replaced by `rpc.system.name`") +class RpcSystemValues(Enum): + GRPC = "grpc" + """gRPC.""" + JAVA_RMI = "java_rmi" + """Java RMI.""" + DOTNET_WCF = "dotnet_wcf" + """.NET WCF.""" + APACHE_DUBBO = "apache_dubbo" + """Apache Dubbo.""" + CONNECT_RPC = "connect_rpc" + """Connect RPC.""" + ONC_RPC = "onc_rpc" + """[ONC RPC (Sun RPC)](https://datatracker.ietf.org/doc/html/rfc5531).""" + JSONRPC = "jsonrpc" + """JSON-RPC.""" + + +class RpcSystemNameValues(Enum): + GRPC = "grpc" + """[gRPC](https://grpc.io/).""" + DUBBO = "dubbo" + """[Apache Dubbo](https://dubbo.apache.org/).""" + CONNECTRPC = "connectrpc" + """[Connect RPC](https://connectrpc.com/).""" + JSONRPC = "jsonrpc" + """[JSON-RPC](https://www.jsonrpc.org/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py new file mode 100644 index 00000000000..fa4ec427244 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py @@ -0,0 +1,45 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +SECURITY_RULE_CATEGORY: Final = "security_rule.category" +""" +A categorization value keyword used by the entity using the rule for detection of this event. +""" + +SECURITY_RULE_DESCRIPTION: Final = "security_rule.description" +""" +The description of the rule generating the event. +""" + +SECURITY_RULE_LICENSE: Final = "security_rule.license" +""" +Name of the license under which the rule used to generate this event is made available. +""" + +SECURITY_RULE_NAME: Final = "security_rule.name" +""" +The name of the rule or signature generating the event. +""" + +SECURITY_RULE_REFERENCE: Final = "security_rule.reference" +""" +Reference URL to additional information about the rule used to generate this event. +Note: The URL can point to the vendor’s documentation about the rule. If that’s not available, it can also be a link to a more general page describing this type of alert. +""" + +SECURITY_RULE_RULESET_NAME: Final = "security_rule.ruleset.name" +""" +Name of the ruleset, policy, group, or parent category in which the rule used to generate this event is a member. +""" + +SECURITY_RULE_UUID: Final = "security_rule.uuid" +""" +A rule ID that is unique within the scope of a set or group of agents, observers, or other entities using the rule for detection of this event. +""" + +SECURITY_RULE_VERSION: Final = "security_rule.version" +""" +The version / revision of the rule being used for analysis. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py new file mode 100644 index 00000000000..865dcde6b08 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py @@ -0,0 +1,14 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +SERVER_ADDRESS: Final = "server.address" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.server_attributes.SERVER_ADDRESS`. +""" + +SERVER_PORT: Final = "server.port" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.server_attributes.SERVER_PORT`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py new file mode 100644 index 00000000000..eb2dcd6e8a2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py @@ -0,0 +1,52 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +SERVICE_CRITICALITY: Final = "service.criticality" +""" +The operational criticality of the service. +Note: Application developers are encouraged to set `service.criticality` to express the operational importance of their services. Telemetry consumers MAY use this attribute to optimize telemetry collection or improve user experience. +""" + +SERVICE_INSTANCE_ID: Final = "service.instance.id" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_INSTANCE_ID`. +""" + +SERVICE_NAME: Final = "service.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_NAME`. +""" + +SERVICE_NAMESPACE: Final = "service.namespace" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_NAMESPACE`. +""" + +SERVICE_PEER_NAME: Final = "service.peer.name" +""" +Logical name of the service on the other side of the connection. SHOULD be equal to the actual [`service.name`](/docs/resource/README.md#service) resource attribute of the remote service if any. +""" + +SERVICE_PEER_NAMESPACE: Final = "service.peer.namespace" +""" +Logical namespace of the service on the other side of the connection. SHOULD be equal to the actual [`service.namespace`](/docs/resource/README.md#service) resource attribute of the remote service if any. +""" + +SERVICE_VERSION: Final = "service.version" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_VERSION`. +""" + + +class ServiceCriticalityValues(Enum): + CRITICAL = "critical" + """Service is business-critical; downtime directly impacts revenue, user experience, or core functionality.""" + HIGH = "high" + """Service is important but has degradation tolerance or fallback mechanisms.""" + MEDIUM = "medium" + """Service provides supplementary functionality; degradation has limited user impact.""" + LOW = "low" + """Service is non-essential to core operations; used for background tasks or internal tools.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py new file mode 100644 index 00000000000..db9a5edc417 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py @@ -0,0 +1,14 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +SESSION_ID: Final = "session.id" +""" +A unique ID to identify a session. +""" + +SESSION_PREVIOUS_ID: Final = "session.previous_id" +""" +The previous `session.id` for this user, when known. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py new file mode 100644 index 00000000000..1960b24ef64 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py @@ -0,0 +1,15 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +SOURCE_ADDRESS: Final = "source.address" +""" +Source address - domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. +Note: When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. +""" + +SOURCE_PORT: Final = "source.port" +""" +Source port number. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py new file mode 100644 index 00000000000..93784858e47 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py @@ -0,0 +1,242 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +SYSTEM_CPU_LOGICAL_NUMBER: Final = "system.cpu.logical_number" +""" +Deprecated: Replaced by `cpu.logical_number`. +""" + +SYSTEM_CPU_STATE: Final = "system.cpu.state" +""" +Deprecated: Replaced by `cpu.mode`. +""" + +SYSTEM_DEVICE: Final = "system.device" +""" +The device identifier. +""" + +SYSTEM_FILESYSTEM_MODE: Final = "system.filesystem.mode" +""" +The filesystem mode. +""" + +SYSTEM_FILESYSTEM_MOUNTPOINT: Final = "system.filesystem.mountpoint" +""" +The filesystem mount path. +""" + +SYSTEM_FILESYSTEM_STATE: Final = "system.filesystem.state" +""" +The filesystem state. +""" + +SYSTEM_FILESYSTEM_TYPE: Final = "system.filesystem.type" +""" +The filesystem type. +""" + +SYSTEM_MEMORY_LINUX_HUGEPAGES_STATE: Final = "system.memory.linux.hugepages.state" +""" +The Linux HugePages memory state. +""" + +SYSTEM_MEMORY_LINUX_SLAB_STATE: Final = "system.memory.linux.slab.state" +""" +The Linux Slab memory state. +""" + +SYSTEM_MEMORY_STATE: Final = "system.memory.state" +""" +The memory state. +""" + +SYSTEM_NETWORK_STATE: Final = "system.network.state" +""" +Deprecated: Replaced by `network.connection.state`. +""" + +SYSTEM_PAGING_DIRECTION: Final = "system.paging.direction" +""" +The paging access direction. +""" + +SYSTEM_PAGING_FAULT_TYPE: Final = "system.paging.fault.type" +""" +The paging fault type. +""" + +SYSTEM_PAGING_STATE: Final = "system.paging.state" +""" +The memory paging state. +""" + +SYSTEM_PAGING_TYPE: Final = "system.paging.type" +""" +Deprecated: Replaced by `system.paging.fault.type`. +""" + +SYSTEM_PROCESS_STATUS: Final = "system.process.status" +""" +Deprecated: Replaced by `process.state`. +""" + +SYSTEM_PROCESSES_STATUS: Final = "system.processes.status" +""" +Deprecated: Replaced by `process.state`. +""" + + +@deprecated("The attribute system.cpu.state is deprecated - Replaced by `cpu.mode`") +class SystemCpuStateValues(Enum): + USER = "user" + """user.""" + SYSTEM = "system" + """system.""" + NICE = "nice" + """nice.""" + IDLE = "idle" + """idle.""" + IOWAIT = "iowait" + """iowait.""" + INTERRUPT = "interrupt" + """interrupt.""" + STEAL = "steal" + """steal.""" + + +class SystemFilesystemStateValues(Enum): + USED = "used" + """used.""" + FREE = "free" + """free.""" + RESERVED = "reserved" + """reserved.""" + + +class SystemFilesystemTypeValues(Enum): + FAT32 = "fat32" + """fat32.""" + EXFAT = "exfat" + """exfat.""" + NTFS = "ntfs" + """ntfs.""" + REFS = "refs" + """refs.""" + HFSPLUS = "hfsplus" + """hfsplus.""" + EXT4 = "ext4" + """ext4.""" + + +class SystemMemoryLinuxHugepagesStateValues(Enum): + FREE = "free" + """free.""" + USED = "used" + """used.""" + + +class SystemMemoryLinuxSlabStateValues(Enum): + RECLAIMABLE = "reclaimable" + """reclaimable.""" + UNRECLAIMABLE = "unreclaimable" + """unreclaimable.""" + + +class SystemMemoryStateValues(Enum): + USED = "used" + """Actual used virtual memory in bytes.""" + FREE = "free" + """free.""" + SHARED = "shared" + """Deprecated: Removed, report shared memory usage with `metric.system.memory.linux.shared` metric.""" + BUFFERS = "buffers" + """buffers.""" + CACHED = "cached" + """cached.""" + + +@deprecated("The attribute system.network.state is deprecated - Replaced by `network.connection.state`") +class SystemNetworkStateValues(Enum): + CLOSE = "close" + """close.""" + CLOSE_WAIT = "close_wait" + """close_wait.""" + CLOSING = "closing" + """closing.""" + DELETE = "delete" + """delete.""" + ESTABLISHED = "established" + """established.""" + FIN_WAIT_1 = "fin_wait_1" + """fin_wait_1.""" + FIN_WAIT_2 = "fin_wait_2" + """fin_wait_2.""" + LAST_ACK = "last_ack" + """last_ack.""" + LISTEN = "listen" + """listen.""" + SYN_RECV = "syn_recv" + """syn_recv.""" + SYN_SENT = "syn_sent" + """syn_sent.""" + TIME_WAIT = "time_wait" + """time_wait.""" + + +class SystemPagingDirectionValues(Enum): + IN = "in" + """in.""" + OUT = "out" + """out.""" + + +class SystemPagingFaultTypeValues(Enum): + MAJOR = "major" + """major.""" + MINOR = "minor" + """minor.""" + + +class SystemPagingStateValues(Enum): + USED = "used" + """used.""" + FREE = "free" + """free.""" + + +@deprecated("The attribute system.paging.type is deprecated - Replaced by `system.paging.fault.type`") +class SystemPagingTypeValues(Enum): + MAJOR = "major" + """major.""" + MINOR = "minor" + """minor.""" + + +@deprecated("The attribute system.process.status is deprecated - Replaced by `process.state`") +class SystemProcessStatusValues(Enum): + RUNNING = "running" + """running.""" + SLEEPING = "sleeping" + """sleeping.""" + STOPPED = "stopped" + """stopped.""" + DEFUNCT = "defunct" + """defunct.""" + + +@deprecated("The attribute system.processes.status is deprecated - Replaced by `process.state`") +class SystemProcessesStatusValues(Enum): + RUNNING = "running" + """running.""" + SLEEPING = "sleeping" + """sleeping.""" + STOPPED = "stopped" + """stopped.""" + DEFUNCT = "defunct" + """defunct.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py new file mode 100644 index 00000000000..4067f433703 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py @@ -0,0 +1,64 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +TELEMETRY_DISTRO_NAME: Final = "telemetry.distro.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_DISTRO_NAME`. +""" + +TELEMETRY_DISTRO_VERSION: Final = "telemetry.distro.version" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_DISTRO_VERSION`. +""" + +TELEMETRY_SDK_LANGUAGE: Final = "telemetry.sdk.language" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_LANGUAGE`. +""" + +TELEMETRY_SDK_NAME: Final = "telemetry.sdk.name" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_NAME`. +""" + +TELEMETRY_SDK_VERSION: Final = "telemetry.sdk.version" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_VERSION`. +""" + + +@deprecated( + "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues`." +) +class TelemetrySdkLanguageValues(Enum): + CPP = "cpp" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.CPP`.""" + DOTNET = "dotnet" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.DOTNET`.""" + ERLANG = "erlang" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.ERLANG`.""" + GO = "go" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.GO`.""" + JAVA = "java" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.JAVA`.""" + KOTLIN = "kotlin" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.KOTLIN`.""" + NODEJS = "nodejs" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.NODEJS`.""" + PHP = "php" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.PHP`.""" + PYTHON = "python" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.PYTHON`.""" + RUBY = "ruby" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.RUBY`.""" + RUST = "rust" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.RUST`.""" + SWIFT = "swift" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.SWIFT`.""" + WEBJS = "webjs" + """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.WEBJS`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py new file mode 100644 index 00000000000..4a3ef390d88 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py @@ -0,0 +1,47 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +TEST_CASE_NAME: Final = "test.case.name" +""" +The fully qualified human readable name of the [test case](https://wikipedia.org/wiki/Test_case). +""" + +TEST_CASE_RESULT_STATUS: Final = "test.case.result.status" +""" +The status of the actual test case result from test execution. +""" + +TEST_SUITE_NAME: Final = "test.suite.name" +""" +The human readable name of a [test suite](https://wikipedia.org/wiki/Test_suite). +""" + +TEST_SUITE_RUN_STATUS: Final = "test.suite.run.status" +""" +The status of the test suite run. +""" + + +class TestCaseResultStatusValues(Enum): + PASS = "pass" + """pass.""" + FAIL = "fail" + """fail.""" + + +class TestSuiteRunStatusValues(Enum): + SUCCESS = "success" + """success.""" + FAILURE = "failure" + """failure.""" + SKIPPED = "skipped" + """skipped.""" + ABORTED = "aborted" + """aborted.""" + TIMED_OUT = "timed_out" + """timed_out.""" + IN_PROGRESS = "in_progress" + """in_progress.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py new file mode 100644 index 00000000000..29c41435fd5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py @@ -0,0 +1,33 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +THREAD_ID: Final = "thread.id" +""" +Current "managed" thread ID (as opposed to OS thread ID). +Note: Examples of where the value can be extracted from: + +| Language or platform | Source | +| --- | --- | +| JVM | `Thread.currentThread().threadId()` | +| .NET | `Thread.CurrentThread.ManagedThreadId` | +| Python | `threading.current_thread().ident` | +| Ruby | `Thread.current.object_id` | +| C++ | `std::this_thread::get_id()` | +| Erlang | `erlang:self()` |. +""" + +THREAD_NAME: Final = "thread.name" +""" +Current thread name. +Note: Examples of where the value can be extracted from: + +| Language or platform | Source | +| --- | --- | +| JVM | `Thread.currentThread().getName()` | +| .NET | `Thread.CurrentThread.Name` | +| Python | `threading.current_thread().name` | +| Ruby | `Thread.current.name` | +| Erlang | `erlang:process_info(self(), registered_name)` |. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py new file mode 100644 index 00000000000..60e722c757e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py @@ -0,0 +1,158 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +TLS_CIPHER: Final = "tls.cipher" +""" +String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. +Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). +""" + +TLS_CLIENT_CERTIFICATE: Final = "tls.client.certificate" +""" +PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. +""" + +TLS_CLIENT_CERTIFICATE_CHAIN: Final = "tls.client.certificate_chain" +""" +Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. +""" + +TLS_CLIENT_HASH_MD5: Final = "tls.client.hash.md5" +""" +Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. +""" + +TLS_CLIENT_HASH_SHA1: Final = "tls.client.hash.sha1" +""" +Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. +""" + +TLS_CLIENT_HASH_SHA256: Final = "tls.client.hash.sha256" +""" +Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. +""" + +TLS_CLIENT_ISSUER: Final = "tls.client.issuer" +""" +Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. +""" + +TLS_CLIENT_JA3: Final = "tls.client.ja3" +""" +A hash that identifies clients based on how they perform an SSL/TLS handshake. +""" + +TLS_CLIENT_NOT_AFTER: Final = "tls.client.not_after" +""" +Date/Time indicating when client certificate is no longer considered valid. +""" + +TLS_CLIENT_NOT_BEFORE: Final = "tls.client.not_before" +""" +Date/Time indicating when client certificate is first considered valid. +""" + +TLS_CLIENT_SERVER_NAME: Final = "tls.client.server_name" +""" +Deprecated: Replaced by `server.address`. +""" + +TLS_CLIENT_SUBJECT: Final = "tls.client.subject" +""" +Distinguished name of subject of the x.509 certificate presented by the client. +""" + +TLS_CLIENT_SUPPORTED_CIPHERS: Final = "tls.client.supported_ciphers" +""" +Array of ciphers offered by the client during the client hello. +""" + +TLS_CURVE: Final = "tls.curve" +""" +String indicating the curve used for the given cipher, when applicable. +""" + +TLS_ESTABLISHED: Final = "tls.established" +""" +Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. +""" + +TLS_NEXT_PROTOCOL: Final = "tls.next_protocol" +""" +String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. +""" + +TLS_PROTOCOL_NAME: Final = "tls.protocol.name" +""" +Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values). +""" + +TLS_PROTOCOL_VERSION: Final = "tls.protocol.version" +""" +Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values). +""" + +TLS_RESUMED: Final = "tls.resumed" +""" +Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. +""" + +TLS_SERVER_CERTIFICATE: Final = "tls.server.certificate" +""" +PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. +""" + +TLS_SERVER_CERTIFICATE_CHAIN: Final = "tls.server.certificate_chain" +""" +Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. +""" + +TLS_SERVER_HASH_MD5: Final = "tls.server.hash.md5" +""" +Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. +""" + +TLS_SERVER_HASH_SHA1: Final = "tls.server.hash.sha1" +""" +Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. +""" + +TLS_SERVER_HASH_SHA256: Final = "tls.server.hash.sha256" +""" +Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. +""" + +TLS_SERVER_ISSUER: Final = "tls.server.issuer" +""" +Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. +""" + +TLS_SERVER_JA3S: Final = "tls.server.ja3s" +""" +A hash that identifies servers based on how they perform an SSL/TLS handshake. +""" + +TLS_SERVER_NOT_AFTER: Final = "tls.server.not_after" +""" +Date/Time indicating when server certificate is no longer considered valid. +""" + +TLS_SERVER_NOT_BEFORE: Final = "tls.server.not_before" +""" +Date/Time indicating when server certificate is first considered valid. +""" + +TLS_SERVER_SUBJECT: Final = "tls.server.subject" +""" +Distinguished name of subject of the x.509 certificate presented by the server. +""" + + +class TlsProtocolNameValues(Enum): + SSL = "ssl" + """SSL.""" + TLS = "tls" + """TLS.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py new file mode 100644 index 00000000000..345349a45aa --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py @@ -0,0 +1,76 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +URL_DOMAIN: Final = "url.domain" +""" +Domain extracted from the `url.full`, such as "opentelemetry.io". +Note: In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. +""" + +URL_EXTENSION: Final = "url.extension" +""" +The file extension extracted from the `url.full`, excluding the leading dot. +Note: The file extension is only set if it exists, as not every URL has a file extension. When the filename has multiple extensions `example.tar.gz`, only the last one should be captured `gz`, not `tar.gz`. +""" + +URL_FRAGMENT: Final = "url.fragment" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_FRAGMENT`. +""" + +URL_FULL: Final = "url.full" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_FULL`. +""" + +URL_ORIGINAL: Final = "url.original" +""" +Unmodified original URL as seen in the event source. +Note: In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. +`url.original` might contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same. +""" + +URL_PATH: Final = "url.path" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_PATH`. +""" + +URL_PORT: Final = "url.port" +""" +Port extracted from the `url.full`. +""" + +URL_QUERY: Final = "url.query" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_QUERY`. +""" + +URL_REGISTERED_DOMAIN: Final = "url.registered_domain" +""" +The highest registered URL domain, stripped of the subdomain. +Note: This value can be determined precisely with the [public suffix list](https://publicsuffix.org/). For example, the registered domain for `foo.example.com` is `example.com`. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as `co.uk`. +""" + +URL_SCHEME: Final = "url.scheme" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_SCHEME`. +""" + +URL_SUBDOMAIN: Final = "url.subdomain" +""" +The subdomain portion of a fully qualified domain name includes all of the names except the hostname under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. +Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. +""" + +URL_TEMPLATE: Final = "url.template" +""" +The low-cardinality template of an [absolute path reference](https://www.rfc-editor.org/rfc/rfc3986#section-4.2). +""" + +URL_TOP_LEVEL_DOMAIN: Final = "url.top_level_domain" +""" +The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. +Note: This value can be determined precisely with the [public suffix list](https://publicsuffix.org/). +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py new file mode 100644 index 00000000000..bccceba3cba --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py @@ -0,0 +1,47 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +USER_AGENT_NAME: Final = "user_agent.name" +""" +Name of the user-agent extracted from original. Usually refers to the browser's name. +Note: [Example](https://uaparser.dev/#demo) of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant name SHOULD be selected. In such a scenario it should align with `user_agent.version`. +""" + +USER_AGENT_ORIGINAL: Final = "user_agent.original" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.user_agent_attributes.USER_AGENT_ORIGINAL`. +""" + +USER_AGENT_OS_NAME: Final = "user_agent.os.name" +""" +Human readable operating system name. +Note: For mapping user agent strings to OS names, libraries such as [ua-parser](https://github.com/ua-parser) can be utilized. +""" + +USER_AGENT_OS_VERSION: Final = "user_agent.os.version" +""" +The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). +Note: For mapping user agent strings to OS versions, libraries such as [ua-parser](https://github.com/ua-parser) can be utilized. +""" + +USER_AGENT_SYNTHETIC_TYPE: Final = "user_agent.synthetic.type" +""" +Specifies the category of synthetic traffic, such as tests or bots. +Note: This attribute MAY be derived from the contents of the `user_agent.original` attribute. Components that populate the attribute are responsible for determining what they consider to be synthetic bot or test traffic. This attribute can either be set for self-identification purposes, or on telemetry detected to be generated as a result of a synthetic request. This attribute is useful for distinguishing between genuine client traffic and synthetic traffic generated by bots or tests. +""" + +USER_AGENT_VERSION: Final = "user_agent.version" +""" +Version of the user-agent extracted from original. Usually refers to the browser's version. +Note: [Example](https://uaparser.dev/#demo) of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant version SHOULD be selected. In such a scenario it should align with `user_agent.name`. +""" + + +class UserAgentSyntheticTypeValues(Enum): + BOT = "bot" + """Bot source.""" + TEST = "test" + """Synthetic test source.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py new file mode 100644 index 00000000000..91d0dbccada --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py @@ -0,0 +1,35 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +USER_EMAIL: Final = "user.email" +""" +User email address. +""" + +USER_FULL_NAME: Final = "user.full_name" +""" +User's full name. +""" + +USER_HASH: Final = "user.hash" +""" +Unique user hash to correlate information for a user in anonymized form. +Note: Useful if `user.id` or `user.name` contain confidential information and cannot be used. +""" + +USER_ID: Final = "user.id" +""" +Unique identifier of the user. +""" + +USER_NAME: Final = "user.name" +""" +Short name or login/username of the user. +""" + +USER_ROLES: Final = "user.roles" +""" +Array of user roles at the time of the event. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py new file mode 100644 index 00000000000..d0b43bfe6e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py @@ -0,0 +1,218 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +VCS_CHANGE_ID: Final = "vcs.change.id" +""" +The ID of the change (pull request/merge request/changelist) if applicable. This is usually a unique (within repository) identifier generated by the VCS system. +""" + +VCS_CHANGE_STATE: Final = "vcs.change.state" +""" +The state of the change (pull request/merge request/changelist). +""" + +VCS_CHANGE_TITLE: Final = "vcs.change.title" +""" +The human readable title of the change (pull request/merge request/changelist). This title is often a brief summary of the change and may get merged in to a ref as the commit summary. +""" + +VCS_LINE_CHANGE_TYPE: Final = "vcs.line_change.type" +""" +The type of line change being measured on a branch or change. +""" + +VCS_OWNER_NAME: Final = "vcs.owner.name" +""" +The group owner within the version control system. +""" + +VCS_PROVIDER_NAME: Final = "vcs.provider.name" +""" +The name of the version control system provider. +""" + +VCS_REF_BASE_NAME: Final = "vcs.ref.base.name" +""" +The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. +Note: `base` refers to the starting point of a change. For example, `main` +would be the base reference of type branch if you've created a new +reference of type branch from it and created new commits. +""" + +VCS_REF_BASE_REVISION: Final = "vcs.ref.base.revision" +""" +The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. +Note: `base` refers to the starting point of a change. For example, `main` +would be the base reference of type branch if you've created a new +reference of type branch from it and created new commits. The +revision can be a full [hash value (see +glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), +of the recorded change to a ref within a repository pointing to a +commit [commit](https://git-scm.com/docs/git-commit) object. It does +not necessarily have to be a hash; it can simply define a [revision +number](https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html) +which is an integer that is monotonically increasing. In cases where +it is identical to the `ref.base.name`, it SHOULD still be included. +It is up to the implementer to decide which value to set as the +revision based on the VCS system and situational context. +""" + +VCS_REF_BASE_TYPE: Final = "vcs.ref.base.type" +""" +The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. +Note: `base` refers to the starting point of a change. For example, `main` +would be the base reference of type branch if you've created a new +reference of type branch from it and created new commits. +""" + +VCS_REF_HEAD_NAME: Final = "vcs.ref.head.name" +""" +The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. +Note: `head` refers to where you are right now; the current reference at a +given time. +""" + +VCS_REF_HEAD_REVISION: Final = "vcs.ref.head.revision" +""" +The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. +Note: `head` refers to where you are right now; the current reference at a +given time.The revision can be a full [hash value (see +glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), +of the recorded change to a ref within a repository pointing to a +commit [commit](https://git-scm.com/docs/git-commit) object. It does +not necessarily have to be a hash; it can simply define a [revision +number](https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html) +which is an integer that is monotonically increasing. In cases where +it is identical to the `ref.head.name`, it SHOULD still be included. +It is up to the implementer to decide which value to set as the +revision based on the VCS system and situational context. +""" + +VCS_REF_HEAD_TYPE: Final = "vcs.ref.head.type" +""" +The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. +Note: `head` refers to where you are right now; the current reference at a +given time. +""" + +VCS_REF_TYPE: Final = "vcs.ref.type" +""" +The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. +""" + +VCS_REPOSITORY_CHANGE_ID: Final = "vcs.repository.change.id" +""" +Deprecated: Replaced by `vcs.change.id`. +""" + +VCS_REPOSITORY_CHANGE_TITLE: Final = "vcs.repository.change.title" +""" +Deprecated: Replaced by `vcs.change.title`. +""" + +VCS_REPOSITORY_NAME: Final = "vcs.repository.name" +""" +The human readable name of the repository. It SHOULD NOT include any additional identifier like Group/SubGroup in GitLab or organization in GitHub. +Note: Due to it only being the name, it can clash with forks of the same +repository if collecting telemetry across multiple orgs or groups in +the same backends. +""" + +VCS_REPOSITORY_REF_NAME: Final = "vcs.repository.ref.name" +""" +Deprecated: Replaced by `vcs.ref.head.name`. +""" + +VCS_REPOSITORY_REF_REVISION: Final = "vcs.repository.ref.revision" +""" +Deprecated: Replaced by `vcs.ref.head.revision`. +""" + +VCS_REPOSITORY_REF_TYPE: Final = "vcs.repository.ref.type" +""" +Deprecated: Replaced by `vcs.ref.head.type`. +""" + +VCS_REPOSITORY_URL_FULL: Final = "vcs.repository.url.full" +""" +The [canonical URL](https://support.google.com/webmasters/answer/10347851) of the repository providing the complete HTTP(S) address in order to locate and identify the repository through a browser. +Note: In Git Version Control Systems, the canonical URL SHOULD NOT include +the `.git` extension. +""" + +VCS_REVISION_DELTA_DIRECTION: Final = "vcs.revision_delta.direction" +""" +The type of revision comparison. +""" + + +class VcsChangeStateValues(Enum): + OPEN = "open" + """Open means the change is currently active and under review. It hasn't been merged into the target branch yet, and it's still possible to make changes or add comments.""" + WIP = "wip" + """WIP (work-in-progress, draft) means the change is still in progress and not yet ready for a full review. It might still undergo significant changes.""" + CLOSED = "closed" + """Closed means the merge request has been closed without merging. This can happen for various reasons, such as the changes being deemed unnecessary, the issue being resolved in another way, or the author deciding to withdraw the request.""" + MERGED = "merged" + """Merged indicates that the change has been successfully integrated into the target codebase.""" + + +class VcsLineChangeTypeValues(Enum): + ADDED = "added" + """How many lines were added.""" + REMOVED = "removed" + """How many lines were removed.""" + + +class VcsProviderNameValues(Enum): + GITHUB = "github" + """[GitHub](https://github.com).""" + GITLAB = "gitlab" + """[GitLab](https://gitlab.com).""" + GITTEA = "gittea" + """Deprecated: Replaced by `gitea`.""" + GITEA = "gitea" + """[Gitea](https://gitea.io).""" + BITBUCKET = "bitbucket" + """[Bitbucket](https://bitbucket.org).""" + + +class VcsRefBaseTypeValues(Enum): + BRANCH = "branch" + """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" + TAG = "tag" + """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" + + +class VcsRefHeadTypeValues(Enum): + BRANCH = "branch" + """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" + TAG = "tag" + """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" + + +class VcsRefTypeValues(Enum): + BRANCH = "branch" + """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" + TAG = "tag" + """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" + + +@deprecated("The attribute vcs.repository.ref.type is deprecated - Replaced by `vcs.ref.head.type`") +class VcsRepositoryRefTypeValues(Enum): + BRANCH = "branch" + """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" + TAG = "tag" + """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" + + +class VcsRevisionDeltaDirectionValues(Enum): + BEHIND = "behind" + """How many revisions the change is behind the target ref.""" + AHEAD = "ahead" + """How many revisions the change is ahead of the target ref.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py new file mode 100644 index 00000000000..0d0bf87feae --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py @@ -0,0 +1,19 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +WEBENGINE_DESCRIPTION: Final = "webengine.description" +""" +Additional description of the web engine (e.g. detailed version and edition information). +""" + +WEBENGINE_NAME: Final = "webengine.name" +""" +The name of the web engine. +""" + +WEBENGINE_VERSION: Final = "webengine.version" +""" +The version of the web engine. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py new file mode 100644 index 00000000000..3c6571076ff --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py @@ -0,0 +1,14 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +ZOS_SMF_ID: Final = "zos.smf.id" +""" +The System Management Facility (SMF) Identifier uniquely identified a z/OS system within a SYSPLEX or mainframe environment and is used for system and performance analysis. +""" + +ZOS_SYSPLEX_NAME: Final = "zos.sysplex.name" +""" +The name of the SYSPLEX to which the z/OS system belongs too. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py new file mode 100644 index 00000000000..22123af0174 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py @@ -0,0 +1,40 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter, UpDownCounter + +AZURE_COSMOSDB_CLIENT_ACTIVE_INSTANCE_COUNT: Final = "azure.cosmosdb.client.active_instance.count" +""" +Number of active client instances +Instrument: updowncounter +Unit: {instance} +""" + + +def create_azure_cosmosdb_client_active_instance_count(meter: Meter) -> UpDownCounter: + """Number of active client instances""" + return meter.create_up_down_counter( + name=AZURE_COSMOSDB_CLIENT_ACTIVE_INSTANCE_COUNT, + description="Number of active client instances.", + unit="{instance}", + ) + + +AZURE_COSMOSDB_CLIENT_OPERATION_REQUEST_CHARGE: Final = "azure.cosmosdb.client.operation.request_charge" +""" +[Request units](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation +Instrument: histogram +Unit: {request_unit} +""" + + +def create_azure_cosmosdb_client_operation_request_charge(meter: Meter) -> Histogram: + """[Request units](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation""" + return meter.create_histogram( + name=AZURE_COSMOSDB_CLIENT_OPERATION_REQUEST_CHARGE, + description="[Request units](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation.", + unit="{request_unit}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py new file mode 100644 index 00000000000..1ff810e34a3 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py @@ -0,0 +1,94 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter, UpDownCounter + +CICD_PIPELINE_RUN_ACTIVE: Final = "cicd.pipeline.run.active" +""" +The number of pipeline runs currently active in the system by state +Instrument: updowncounter +Unit: {run} +""" + + +def create_cicd_pipeline_run_active(meter: Meter) -> UpDownCounter: + """The number of pipeline runs currently active in the system by state""" + return meter.create_up_down_counter( + name=CICD_PIPELINE_RUN_ACTIVE, + description="The number of pipeline runs currently active in the system by state.", + unit="{run}", + ) + + +CICD_PIPELINE_RUN_DURATION: Final = "cicd.pipeline.run.duration" +""" +Duration of a pipeline run grouped by pipeline, state and result +Instrument: histogram +Unit: s +""" + + +def create_cicd_pipeline_run_duration(meter: Meter) -> Histogram: + """Duration of a pipeline run grouped by pipeline, state and result""" + return meter.create_histogram( + name=CICD_PIPELINE_RUN_DURATION, + description="Duration of a pipeline run grouped by pipeline, state and result.", + unit="s", + ) + + +CICD_PIPELINE_RUN_ERRORS: Final = "cicd.pipeline.run.errors" +""" +The number of errors encountered in pipeline runs (eg. compile, test failures) +Instrument: counter +Unit: {error} +Note: There might be errors in a pipeline run that are non fatal (eg. they are suppressed) or in a parallel stage multiple stages could have a fatal error. +This means that this error count might not be the same as the count of metric `cicd.pipeline.run.duration` with run result `failure`. +""" + + +def create_cicd_pipeline_run_errors(meter: Meter) -> Counter: + """The number of errors encountered in pipeline runs (eg. compile, test failures)""" + return meter.create_counter( + name=CICD_PIPELINE_RUN_ERRORS, + description="The number of errors encountered in pipeline runs (eg. compile, test failures).", + unit="{error}", + ) + + +CICD_SYSTEM_ERRORS: Final = "cicd.system.errors" +""" +The number of errors in a component of the CI/CD system (eg. controller, scheduler, agent) +Instrument: counter +Unit: {error} +Note: Errors in pipeline run execution are explicitly excluded. Ie a test failure is not counted in this metric. +""" + + +def create_cicd_system_errors(meter: Meter) -> Counter: + """The number of errors in a component of the CI/CD system (eg. controller, scheduler, agent)""" + return meter.create_counter( + name=CICD_SYSTEM_ERRORS, + description="The number of errors in a component of the CI/CD system (eg. controller, scheduler, agent).", + unit="{error}", + ) + + +CICD_WORKER_COUNT: Final = "cicd.worker.count" +""" +The number of workers on the CI/CD system by state +Instrument: updowncounter +Unit: {worker} +""" + + +def create_cicd_worker_count(meter: Meter) -> UpDownCounter: + """The number of workers on the CI/CD system by state""" + return meter.create_up_down_counter( + name=CICD_WORKER_COUNT, + description="The number of workers on the CI/CD system by state.", + unit="{worker}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py new file mode 100644 index 00000000000..0a13944ef78 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py @@ -0,0 +1,281 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter + +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +CONTAINER_CPU_TIME: Final = "container.cpu.time" +""" +Total CPU time consumed +Instrument: counter +Unit: s +Note: CPU time consumed by the specific container on all available CPU cores. +""" + + +def create_container_cpu_time(meter: Meter) -> Counter: + """Total CPU time consumed""" + return meter.create_counter( + name=CONTAINER_CPU_TIME, + description="Total CPU time consumed.", + unit="s", + ) + + +CONTAINER_CPU_USAGE: Final = "container.cpu.usage" +""" +Container's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs +Instrument: gauge +Unit: {cpu} +Note: CPU usage of the specific container on all available CPU cores. It is calculated as the change in cumulative CPU time (container.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. +""" + + +def create_container_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Container's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs""" + return meter.create_observable_gauge( + name=CONTAINER_CPU_USAGE, + callbacks=callbacks, + description="Container's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs.", + unit="{cpu}", + ) + + +CONTAINER_DISK_IO: Final = "container.disk.io" +""" +Disk bytes for the container +Instrument: counter +Unit: By +Note: The total number of bytes read/written successfully (aggregated from all disks). +""" + + +def create_container_disk_io(meter: Meter) -> Counter: + """Disk bytes for the container""" + return meter.create_counter( + name=CONTAINER_DISK_IO, + description="Disk bytes for the container.", + unit="By", + ) + + +CONTAINER_FILESYSTEM_AVAILABLE: Final = "container.filesystem.available" +""" +Container filesystem available bytes +Instrument: updowncounter +Unit: By +Note: In K8s, this metric is derived from the +[FsStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [ContainerStats.Rootfs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#ContainerStats) +of the Kubelet's stats API. +""" + + +def create_container_filesystem_available(meter: Meter) -> UpDownCounter: + """Container filesystem available bytes""" + return meter.create_up_down_counter( + name=CONTAINER_FILESYSTEM_AVAILABLE, + description="Container filesystem available bytes.", + unit="By", + ) + + +CONTAINER_FILESYSTEM_CAPACITY: Final = "container.filesystem.capacity" +""" +Container filesystem capacity +Instrument: updowncounter +Unit: By +Note: In K8s, this metric is derived from the +[FsStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [ContainerStats.Rootfs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#ContainerStats) +of the Kubelet's stats API. +""" + + +def create_container_filesystem_capacity(meter: Meter) -> UpDownCounter: + """Container filesystem capacity""" + return meter.create_up_down_counter( + name=CONTAINER_FILESYSTEM_CAPACITY, + description="Container filesystem capacity.", + unit="By", + ) + + +CONTAINER_FILESYSTEM_USAGE: Final = "container.filesystem.usage" +""" +Container filesystem usage +Instrument: updowncounter +Unit: By +Note: This may not equal capacity - available. + +In K8s, this metric is derived from the +[FsStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [ContainerStats.Rootfs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#ContainerStats) +of the Kubelet's stats API. +""" + + +def create_container_filesystem_usage(meter: Meter) -> UpDownCounter: + """Container filesystem usage""" + return meter.create_up_down_counter( + name=CONTAINER_FILESYSTEM_USAGE, + description="Container filesystem usage.", + unit="By", + ) + + +CONTAINER_MEMORY_AVAILABLE: Final = "container.memory.available" +""" +Container memory available +Instrument: updowncounter +Unit: By +Note: Available memory for use. This is defined as the memory limit - workingSetBytes. If memory limit is undefined, the available bytes is omitted. +In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and by subtracting the `container_memory_working_set_bytes` metric from the `container_spec_memory_limit_bytes` metric. +In K8s, this metric is derived from the [MemoryStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. +""" + + +def create_container_memory_available(meter: Meter) -> UpDownCounter: + """Container memory available""" + return meter.create_up_down_counter( + name=CONTAINER_MEMORY_AVAILABLE, + description="Container memory available.", + unit="By", + ) + + +CONTAINER_MEMORY_PAGING_FAULTS: Final = "container.memory.paging.faults" +""" +Deprecated: Replaced by `container.paging.faults`. +""" + + +def create_container_memory_paging_faults(meter: Meter) -> Counter: + """Deprecated, use `container.paging.faults` instead""" + return meter.create_counter( + name=CONTAINER_MEMORY_PAGING_FAULTS, + description="Deprecated, use `container.paging.faults` instead.", + unit="{fault}", + ) + + +CONTAINER_MEMORY_RSS: Final = "container.memory.rss" +""" +Container memory RSS +Instrument: updowncounter +Unit: By +Note: In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_rss` metric. +In K8s, this metric is derived from the [MemoryStats.RSSBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. +""" + + +def create_container_memory_rss(meter: Meter) -> UpDownCounter: + """Container memory RSS""" + return meter.create_up_down_counter( + name=CONTAINER_MEMORY_RSS, + description="Container memory RSS.", + unit="By", + ) + + +CONTAINER_MEMORY_USAGE: Final = "container.memory.usage" +""" +Memory usage of the container +Instrument: updowncounter +Unit: By +Note: Current memory usage, including all memory regardless of when it was accessed. +In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_usage_bytes` metric. +In K8s, this metric is derived from the [MemoryStats.UsageBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. +""" + + +def create_container_memory_usage(meter: Meter) -> UpDownCounter: + """Memory usage of the container""" + return meter.create_up_down_counter( + name=CONTAINER_MEMORY_USAGE, + description="Memory usage of the container.", + unit="By", + ) + + +CONTAINER_MEMORY_WORKING_SET: Final = "container.memory.working_set" +""" +Container memory working set +Instrument: updowncounter +Unit: By +Note: In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_working_set_bytes` metric. +In K8s, this metric is derived from the [MemoryStats.WorkingSetBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. +""" + + +def create_container_memory_working_set(meter: Meter) -> UpDownCounter: + """Container memory working set""" + return meter.create_up_down_counter( + name=CONTAINER_MEMORY_WORKING_SET, + description="Container memory working set.", + unit="By", + ) + + +CONTAINER_NETWORK_IO: Final = "container.network.io" +""" +Network bytes for the container +Instrument: counter +Unit: By +Note: The number of bytes sent/received on all network interfaces by the container. +""" + + +def create_container_network_io(meter: Meter) -> Counter: + """Network bytes for the container""" + return meter.create_counter( + name=CONTAINER_NETWORK_IO, + description="Network bytes for the container.", + unit="By", + ) + + +CONTAINER_PAGING_FAULTS: Final = "container.paging.faults" +""" +Container memory paging faults +Instrument: counter +Unit: {fault} +Note: In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_failures_total{failure_type=pgfault, scope=container}` and `container_memory_failures_total{failure_type=pgmajfault, scope=container}`metric. +In K8s, this metric is derived from the [MemoryStats.PageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) and [MemoryStats.MajorPageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. +""" + + +def create_container_paging_faults(meter: Meter) -> Counter: + """Container memory paging faults""" + return meter.create_counter( + name=CONTAINER_PAGING_FAULTS, + description="Container memory paging faults.", + unit="{fault}", + ) + + +CONTAINER_UPTIME: Final = "container.uptime" +""" +The time the container has been running +Instrument: gauge +Unit: s +Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. +The actual accuracy would depend on the instrumentation and operating system. +""" + + +def create_container_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The time the container has been running""" + return meter.create_observable_gauge( + name=CONTAINER_UPTIME, + callbacks=callbacks, + description="The time the container has been running.", + unit="s", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py new file mode 100644 index 00000000000..286d6dc0ac1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py @@ -0,0 +1,58 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation + +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +CPU_FREQUENCY: Final = "cpu.frequency" +""" +Deprecated: Replaced by `system.cpu.frequency`. +""" + + +def create_cpu_frequency(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Deprecated. Use `system.cpu.frequency` instead""" + return meter.create_observable_gauge( + name=CPU_FREQUENCY, + callbacks=callbacks, + description="Deprecated. Use `system.cpu.frequency` instead.", + unit="{Hz}", + ) + + +CPU_TIME: Final = "cpu.time" +""" +Deprecated: Replaced by `system.cpu.time`. +""" + + +def create_cpu_time(meter: Meter) -> Counter: + """Deprecated. Use `system.cpu.time` instead""" + return meter.create_counter( + name=CPU_TIME, + description="Deprecated. Use `system.cpu.time` instead.", + unit="s", + ) + + +CPU_UTILIZATION: Final = "cpu.utilization" +""" +Deprecated: Replaced by `system.cpu.utilization`. +""" + + +def create_cpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Deprecated. Use `system.cpu.utilization` instead""" + return meter.create_observable_gauge( + name=CPU_UTILIZATION, + callbacks=callbacks, + description="Deprecated. Use `system.cpu.utilization` instead.", + unit="1", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py new file mode 100644 index 00000000000..be242849e2d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py @@ -0,0 +1,60 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Meter + +CPYTHON_GC_COLLECTED_OBJECTS: Final = "cpython.gc.collected_objects" +""" +The total number of objects collected inside a generation since interpreter start +Instrument: counter +Unit: {object} +Note: This metric reports data from [`gc.stats()`](https://docs.python.org/3/library/gc.html#gc.get_stats). +""" + + +def create_cpython_gc_collected_objects(meter: Meter) -> Counter: + """The total number of objects collected inside a generation since interpreter start""" + return meter.create_counter( + name=CPYTHON_GC_COLLECTED_OBJECTS, + description="The total number of objects collected inside a generation since interpreter start.", + unit="{object}", + ) + + +CPYTHON_GC_COLLECTIONS: Final = "cpython.gc.collections" +""" +The number of times a generation was collected since interpreter start +Instrument: counter +Unit: {collection} +Note: This metric reports data from [`gc.stats()`](https://docs.python.org/3/library/gc.html#gc.get_stats). +""" + + +def create_cpython_gc_collections(meter: Meter) -> Counter: + """The number of times a generation was collected since interpreter start""" + return meter.create_counter( + name=CPYTHON_GC_COLLECTIONS, + description="The number of times a generation was collected since interpreter start.", + unit="{collection}", + ) + + +CPYTHON_GC_UNCOLLECTABLE_OBJECTS: Final = "cpython.gc.uncollectable_objects" +""" +The total number of objects which were found to be uncollectable inside a generation since interpreter start +Instrument: counter +Unit: {object} +Note: This metric reports data from [`gc.stats()`](https://docs.python.org/3/library/gc.html#gc.get_stats). +""" + + +def create_cpython_gc_uncollectable_objects(meter: Meter) -> Counter: + """The total number of objects which were found to be uncollectable inside a generation since interpreter start""" + return meter.create_counter( + name=CPYTHON_GC_UNCOLLECTABLE_OBJECTS, + description="The total number of objects which were found to be uncollectable inside a generation since interpreter start.", + unit="{object}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py new file mode 100644 index 00000000000..bbce85bd7d0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py @@ -0,0 +1,356 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter, UpDownCounter + +DB_CLIENT_CONNECTION_COUNT: Final = "db.client.connection.count" +""" +The number of connections that are currently in state described by the `state` attribute +Instrument: updowncounter +Unit: {connection} +""" + + +def create_db_client_connection_count(meter: Meter) -> UpDownCounter: + """The number of connections that are currently in state described by the `state` attribute""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTION_COUNT, + description="The number of connections that are currently in state described by the `state` attribute.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTION_CREATE_TIME: Final = "db.client.connection.create_time" +""" +The time it took to create a new connection +Instrument: histogram +Unit: s +""" + + +def create_db_client_connection_create_time(meter: Meter) -> Histogram: + """The time it took to create a new connection""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTION_CREATE_TIME, + description="The time it took to create a new connection.", + unit="s", + ) + + +DB_CLIENT_CONNECTION_IDLE_MAX: Final = "db.client.connection.idle.max" +""" +The maximum number of idle open connections allowed +Instrument: updowncounter +Unit: {connection} +""" + + +def create_db_client_connection_idle_max(meter: Meter) -> UpDownCounter: + """The maximum number of idle open connections allowed""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTION_IDLE_MAX, + description="The maximum number of idle open connections allowed.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTION_IDLE_MIN: Final = "db.client.connection.idle.min" +""" +The minimum number of idle open connections allowed +Instrument: updowncounter +Unit: {connection} +""" + + +def create_db_client_connection_idle_min(meter: Meter) -> UpDownCounter: + """The minimum number of idle open connections allowed""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTION_IDLE_MIN, + description="The minimum number of idle open connections allowed.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTION_MAX: Final = "db.client.connection.max" +""" +The maximum number of open connections allowed +Instrument: updowncounter +Unit: {connection} +""" + + +def create_db_client_connection_max(meter: Meter) -> UpDownCounter: + """The maximum number of open connections allowed""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTION_MAX, + description="The maximum number of open connections allowed.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTION_PENDING_REQUESTS: Final = "db.client.connection.pending_requests" +""" +The number of current pending requests for an open connection +Instrument: updowncounter +Unit: {request} +""" + + +def create_db_client_connection_pending_requests(meter: Meter) -> UpDownCounter: + """The number of current pending requests for an open connection""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTION_PENDING_REQUESTS, + description="The number of current pending requests for an open connection.", + unit="{request}", + ) + + +DB_CLIENT_CONNECTION_TIMEOUTS: Final = "db.client.connection.timeouts" +""" +The number of connection timeouts that have occurred trying to obtain a connection from the pool +Instrument: counter +Unit: {timeout} +""" + + +def create_db_client_connection_timeouts(meter: Meter) -> Counter: + """The number of connection timeouts that have occurred trying to obtain a connection from the pool""" + return meter.create_counter( + name=DB_CLIENT_CONNECTION_TIMEOUTS, + description="The number of connection timeouts that have occurred trying to obtain a connection from the pool.", + unit="{timeout}", + ) + + +DB_CLIENT_CONNECTION_USE_TIME: Final = "db.client.connection.use_time" +""" +The time between borrowing a connection and returning it to the pool +Instrument: histogram +Unit: s +""" + + +def create_db_client_connection_use_time(meter: Meter) -> Histogram: + """The time between borrowing a connection and returning it to the pool""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTION_USE_TIME, + description="The time between borrowing a connection and returning it to the pool.", + unit="s", + ) + + +DB_CLIENT_CONNECTION_WAIT_TIME: Final = "db.client.connection.wait_time" +""" +The time it took to obtain an open connection from the pool +Instrument: histogram +Unit: s +""" + + +def create_db_client_connection_wait_time(meter: Meter) -> Histogram: + """The time it took to obtain an open connection from the pool""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTION_WAIT_TIME, + description="The time it took to obtain an open connection from the pool.", + unit="s", + ) + + +DB_CLIENT_CONNECTIONS_CREATE_TIME: Final = "db.client.connections.create_time" +""" +Deprecated: Replaced by `db.client.connection.create_time` with unit `s`. +""" + + +def create_db_client_connections_create_time(meter: Meter) -> Histogram: + """Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTIONS_CREATE_TIME, + description="Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`.", + unit="ms", + ) + + +DB_CLIENT_CONNECTIONS_IDLE_MAX: Final = "db.client.connections.idle.max" +""" +Deprecated: Replaced by `db.client.connection.idle.max`. +""" + + +def create_db_client_connections_idle_max(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.idle.max` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_IDLE_MAX, + description="Deprecated, use `db.client.connection.idle.max` instead.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTIONS_IDLE_MIN: Final = "db.client.connections.idle.min" +""" +Deprecated: Replaced by `db.client.connection.idle.min`. +""" + + +def create_db_client_connections_idle_min(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.idle.min` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_IDLE_MIN, + description="Deprecated, use `db.client.connection.idle.min` instead.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTIONS_MAX: Final = "db.client.connections.max" +""" +Deprecated: Replaced by `db.client.connection.max`. +""" + + +def create_db_client_connections_max(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.max` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_MAX, + description="Deprecated, use `db.client.connection.max` instead.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTIONS_PENDING_REQUESTS: Final = "db.client.connections.pending_requests" +""" +Deprecated: Replaced by `db.client.connection.pending_requests`. +""" + + +def create_db_client_connections_pending_requests(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.pending_requests` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_PENDING_REQUESTS, + description="Deprecated, use `db.client.connection.pending_requests` instead.", + unit="{request}", + ) + + +DB_CLIENT_CONNECTIONS_TIMEOUTS: Final = "db.client.connections.timeouts" +""" +Deprecated: Replaced by `db.client.connection.timeouts`. +""" + + +def create_db_client_connections_timeouts(meter: Meter) -> Counter: + """Deprecated, use `db.client.connection.timeouts` instead""" + return meter.create_counter( + name=DB_CLIENT_CONNECTIONS_TIMEOUTS, + description="Deprecated, use `db.client.connection.timeouts` instead.", + unit="{timeout}", + ) + + +DB_CLIENT_CONNECTIONS_USAGE: Final = "db.client.connections.usage" +""" +Deprecated: Replaced by `db.client.connection.count`. +""" + + +def create_db_client_connections_usage(meter: Meter) -> UpDownCounter: + """Deprecated, use `db.client.connection.count` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_CONNECTIONS_USAGE, + description="Deprecated, use `db.client.connection.count` instead.", + unit="{connection}", + ) + + +DB_CLIENT_CONNECTIONS_USE_TIME: Final = "db.client.connections.use_time" +""" +Deprecated: Replaced by `db.client.connection.use_time` with unit `s`. +""" + + +def create_db_client_connections_use_time(meter: Meter) -> Histogram: + """Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTIONS_USE_TIME, + description="Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`.", + unit="ms", + ) + + +DB_CLIENT_CONNECTIONS_WAIT_TIME: Final = "db.client.connections.wait_time" +""" +Deprecated: Replaced by `db.client.connection.wait_time` with unit `s`. +""" + + +def create_db_client_connections_wait_time(meter: Meter) -> Histogram: + """Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`""" + return meter.create_histogram( + name=DB_CLIENT_CONNECTIONS_WAIT_TIME, + description="Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`.", + unit="ms", + ) + + +DB_CLIENT_COSMOSDB_ACTIVE_INSTANCE_COUNT: Final = "db.client.cosmosdb.active_instance.count" +""" +Deprecated: Replaced by `azure.cosmosdb.client.active_instance.count`. +""" + + +def create_db_client_cosmosdb_active_instance_count(meter: Meter) -> UpDownCounter: + """Deprecated, use `azure.cosmosdb.client.active_instance.count` instead""" + return meter.create_up_down_counter( + name=DB_CLIENT_COSMOSDB_ACTIVE_INSTANCE_COUNT, + description="Deprecated, use `azure.cosmosdb.client.active_instance.count` instead.", + unit="{instance}", + ) + + +DB_CLIENT_COSMOSDB_OPERATION_REQUEST_CHARGE: Final = "db.client.cosmosdb.operation.request_charge" +""" +Deprecated: Replaced by `azure.cosmosdb.client.operation.request_charge`. +""" + + +def create_db_client_cosmosdb_operation_request_charge(meter: Meter) -> Histogram: + """Deprecated, use `azure.cosmosdb.client.operation.request_charge` instead""" + return meter.create_histogram( + name=DB_CLIENT_COSMOSDB_OPERATION_REQUEST_CHARGE, + description="Deprecated, use `azure.cosmosdb.client.operation.request_charge` instead.", + unit="{request_unit}", + ) + + +DB_CLIENT_OPERATION_DURATION: Final = "db.client.operation.duration" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.db_metrics.DB_CLIENT_OPERATION_DURATION`. +""" + + +def create_db_client_operation_duration(meter: Meter) -> Histogram: + """Duration of database client operations""" + return meter.create_histogram( + name=DB_CLIENT_OPERATION_DURATION, + description="Duration of database client operations.", + unit="s", + ) + + +DB_CLIENT_RESPONSE_RETURNED_ROWS: Final = "db.client.response.returned_rows" +""" +The actual number of records returned by the database operation +Instrument: histogram +Unit: {row} +""" + + +def create_db_client_response_returned_rows(meter: Meter) -> Histogram: + """The actual number of records returned by the database operation""" + return meter.create_histogram( + name=DB_CLIENT_RESPONSE_RETURNED_ROWS, + description="The actual number of records returned by the database operation.", + unit="{row}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py new file mode 100644 index 00000000000..1a2ed99125f --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py @@ -0,0 +1,23 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter + +DNS_LOOKUP_DURATION: Final = "dns.lookup.duration" +""" +Measures the time taken to perform a DNS lookup +Instrument: histogram +Unit: s +""" + + +def create_dns_lookup_duration(meter: Meter) -> Histogram: + """Measures the time taken to perform a DNS lookup""" + return meter.create_histogram( + name=DNS_LOOKUP_DURATION, + description="Measures the time taken to perform a DNS lookup.", + unit="s", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py new file mode 100644 index 00000000000..48bc12c3960 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py @@ -0,0 +1,159 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter + +FAAS_COLDSTARTS: Final = "faas.coldstarts" +""" +Number of invocation cold starts +Instrument: counter +Unit: {coldstart} +""" + + +def create_faas_coldstarts(meter: Meter) -> Counter: + """Number of invocation cold starts""" + return meter.create_counter( + name=FAAS_COLDSTARTS, + description="Number of invocation cold starts.", + unit="{coldstart}", + ) + + +FAAS_CPU_USAGE: Final = "faas.cpu_usage" +""" +Distribution of CPU usage per invocation +Instrument: histogram +Unit: s +""" + + +def create_faas_cpu_usage(meter: Meter) -> Histogram: + """Distribution of CPU usage per invocation""" + return meter.create_histogram( + name=FAAS_CPU_USAGE, + description="Distribution of CPU usage per invocation.", + unit="s", + ) + + +FAAS_ERRORS: Final = "faas.errors" +""" +Number of invocation errors +Instrument: counter +Unit: {error} +""" + + +def create_faas_errors(meter: Meter) -> Counter: + """Number of invocation errors""" + return meter.create_counter( + name=FAAS_ERRORS, + description="Number of invocation errors.", + unit="{error}", + ) + + +FAAS_INIT_DURATION: Final = "faas.init_duration" +""" +Measures the duration of the function's initialization, such as a cold start +Instrument: histogram +Unit: s +""" + + +def create_faas_init_duration(meter: Meter) -> Histogram: + """Measures the duration of the function's initialization, such as a cold start""" + return meter.create_histogram( + name=FAAS_INIT_DURATION, + description="Measures the duration of the function's initialization, such as a cold start.", + unit="s", + ) + + +FAAS_INVOCATIONS: Final = "faas.invocations" +""" +Number of successful invocations +Instrument: counter +Unit: {invocation} +""" + + +def create_faas_invocations(meter: Meter) -> Counter: + """Number of successful invocations""" + return meter.create_counter( + name=FAAS_INVOCATIONS, + description="Number of successful invocations.", + unit="{invocation}", + ) + + +FAAS_INVOKE_DURATION: Final = "faas.invoke_duration" +""" +Measures the duration of the function's logic execution +Instrument: histogram +Unit: s +""" + + +def create_faas_invoke_duration(meter: Meter) -> Histogram: + """Measures the duration of the function's logic execution""" + return meter.create_histogram( + name=FAAS_INVOKE_DURATION, + description="Measures the duration of the function's logic execution.", + unit="s", + ) + + +FAAS_MEM_USAGE: Final = "faas.mem_usage" +""" +Distribution of max memory usage per invocation +Instrument: histogram +Unit: By +""" + + +def create_faas_mem_usage(meter: Meter) -> Histogram: + """Distribution of max memory usage per invocation""" + return meter.create_histogram( + name=FAAS_MEM_USAGE, + description="Distribution of max memory usage per invocation.", + unit="By", + ) + + +FAAS_NET_IO: Final = "faas.net_io" +""" +Distribution of net I/O usage per invocation +Instrument: histogram +Unit: By +""" + + +def create_faas_net_io(meter: Meter) -> Histogram: + """Distribution of net I/O usage per invocation""" + return meter.create_histogram( + name=FAAS_NET_IO, + description="Distribution of net I/O usage per invocation.", + unit="By", + ) + + +FAAS_TIMEOUTS: Final = "faas.timeouts" +""" +Number of invocation timeouts +Instrument: counter +Unit: {timeout} +""" + + +def create_faas_timeouts(meter: Meter) -> Counter: + """Number of invocation timeouts""" + return meter.create_counter( + name=FAAS_TIMEOUTS, + description="Number of invocation timeouts.", + unit="{timeout}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py new file mode 100644 index 00000000000..22e6ce6e39d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py @@ -0,0 +1,111 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter + +GEN_AI_CLIENT_OPERATION_DURATION: Final = "gen_ai.client.operation.duration" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_gen_ai_client_operation_duration(meter: Meter) -> Histogram: + """GenAI operation duration""" + return meter.create_histogram( + name=GEN_AI_CLIENT_OPERATION_DURATION, + description="GenAI operation duration.", + unit="s", + ) + + +GEN_AI_CLIENT_OPERATION_TIME_PER_OUTPUT_CHUNK: Final = "gen_ai.client.operation.time_per_output_chunk" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_gen_ai_client_operation_time_per_output_chunk(meter: Meter) -> Histogram: + """Time per output chunk, recorded for each chunk received after the first one, measured as the time elapsed from the end of the previous chunk to the end of the current chunk""" + return meter.create_histogram( + name=GEN_AI_CLIENT_OPERATION_TIME_PER_OUTPUT_CHUNK, + description="Time per output chunk, recorded for each chunk received after the first one, measured as the time elapsed from the end of the previous chunk to the end of the current chunk.", + unit="s", + ) + + +GEN_AI_CLIENT_OPERATION_TIME_TO_FIRST_CHUNK: Final = "gen_ai.client.operation.time_to_first_chunk" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_gen_ai_client_operation_time_to_first_chunk(meter: Meter) -> Histogram: + """Time to receive the first chunk, measured from when the client issues the generation request to when the first chunk is received in the response stream""" + return meter.create_histogram( + name=GEN_AI_CLIENT_OPERATION_TIME_TO_FIRST_CHUNK, + description="Time to receive the first chunk, measured from when the client issues the generation request to when the first chunk is received in the response stream.", + unit="s", + ) + + +GEN_AI_CLIENT_TOKEN_USAGE: Final = "gen_ai.client.token.usage" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_gen_ai_client_token_usage(meter: Meter) -> Histogram: + """Number of input and output tokens used""" + return meter.create_histogram( + name=GEN_AI_CLIENT_TOKEN_USAGE, + description="Number of input and output tokens used.", + unit="{token}", + ) + + +GEN_AI_SERVER_REQUEST_DURATION: Final = "gen_ai.server.request.duration" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_gen_ai_server_request_duration(meter: Meter) -> Histogram: + """Generative AI server request duration such as time-to-last byte or last output token""" + return meter.create_histogram( + name=GEN_AI_SERVER_REQUEST_DURATION, + description="Generative AI server request duration such as time-to-last byte or last output token.", + unit="s", + ) + + +GEN_AI_SERVER_TIME_PER_OUTPUT_TOKEN: Final = "gen_ai.server.time_per_output_token" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_gen_ai_server_time_per_output_token(meter: Meter) -> Histogram: + """Time per output token generated after the first token for successful responses""" + return meter.create_histogram( + name=GEN_AI_SERVER_TIME_PER_OUTPUT_TOKEN, + description="Time per output token generated after the first token for successful responses.", + unit="s", + ) + + +GEN_AI_SERVER_TIME_TO_FIRST_TOKEN: Final = "gen_ai.server.time_to_first_token" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_gen_ai_server_time_to_first_token(meter: Meter) -> Histogram: + """Time to generate first token for successful responses""" + return meter.create_histogram( + name=GEN_AI_SERVER_TIME_TO_FIRST_TOKEN, + description="Time to generate first token for successful responses.", + unit="s", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py new file mode 100644 index 00000000000..fd7aa61fc94 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py @@ -0,0 +1,176 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter, UpDownCounter + +HTTP_CLIENT_ACTIVE_REQUESTS: Final = "http.client.active_requests" +""" +Number of active HTTP requests +Instrument: updowncounter +Unit: {request} +""" + + +def create_http_client_active_requests(meter: Meter) -> UpDownCounter: + """Number of active HTTP requests""" + return meter.create_up_down_counter( + name=HTTP_CLIENT_ACTIVE_REQUESTS, + description="Number of active HTTP requests.", + unit="{request}", + ) + + +HTTP_CLIENT_CONNECTION_DURATION: Final = "http.client.connection.duration" +""" +The duration of the successfully established outbound HTTP connections +Instrument: histogram +Unit: s +""" + + +def create_http_client_connection_duration(meter: Meter) -> Histogram: + """The duration of the successfully established outbound HTTP connections""" + return meter.create_histogram( + name=HTTP_CLIENT_CONNECTION_DURATION, + description="The duration of the successfully established outbound HTTP connections.", + unit="s", + ) + + +HTTP_CLIENT_OPEN_CONNECTIONS: Final = "http.client.open_connections" +""" +Number of outbound HTTP connections that are currently active or idle on the client +Instrument: updowncounter +Unit: {connection} +""" + + +def create_http_client_open_connections(meter: Meter) -> UpDownCounter: + """Number of outbound HTTP connections that are currently active or idle on the client""" + return meter.create_up_down_counter( + name=HTTP_CLIENT_OPEN_CONNECTIONS, + description="Number of outbound HTTP connections that are currently active or idle on the client.", + unit="{connection}", + ) + + +HTTP_CLIENT_REQUEST_BODY_SIZE: Final = "http.client.request.body.size" +""" +Size of HTTP client request bodies +Instrument: histogram +Unit: By +Note: The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. +""" + + +def create_http_client_request_body_size(meter: Meter) -> Histogram: + """Size of HTTP client request bodies""" + return meter.create_histogram( + name=HTTP_CLIENT_REQUEST_BODY_SIZE, + description="Size of HTTP client request bodies.", + unit="By", + ) + + +HTTP_CLIENT_REQUEST_DURATION: Final = "http.client.request.duration" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.http_metrics.HTTP_CLIENT_REQUEST_DURATION`. +""" + + +def create_http_client_request_duration(meter: Meter) -> Histogram: + """Duration of HTTP client requests""" + return meter.create_histogram( + name=HTTP_CLIENT_REQUEST_DURATION, + description="Duration of HTTP client requests.", + unit="s", + ) + + +HTTP_CLIENT_RESPONSE_BODY_SIZE: Final = "http.client.response.body.size" +""" +Size of HTTP client response bodies +Instrument: histogram +Unit: By +Note: The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. +""" + + +def create_http_client_response_body_size(meter: Meter) -> Histogram: + """Size of HTTP client response bodies""" + return meter.create_histogram( + name=HTTP_CLIENT_RESPONSE_BODY_SIZE, + description="Size of HTTP client response bodies.", + unit="By", + ) + + +HTTP_SERVER_ACTIVE_REQUESTS: Final = "http.server.active_requests" +""" +Number of active HTTP server requests +Instrument: updowncounter +Unit: {request} +""" + + +def create_http_server_active_requests(meter: Meter) -> UpDownCounter: + """Number of active HTTP server requests""" + return meter.create_up_down_counter( + name=HTTP_SERVER_ACTIVE_REQUESTS, + description="Number of active HTTP server requests.", + unit="{request}", + ) + + +HTTP_SERVER_REQUEST_BODY_SIZE: Final = "http.server.request.body.size" +""" +Size of HTTP server request bodies +Instrument: histogram +Unit: By +Note: The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. +""" + + +def create_http_server_request_body_size(meter: Meter) -> Histogram: + """Size of HTTP server request bodies""" + return meter.create_histogram( + name=HTTP_SERVER_REQUEST_BODY_SIZE, + description="Size of HTTP server request bodies.", + unit="By", + ) + + +HTTP_SERVER_REQUEST_DURATION: Final = "http.server.request.duration" +""" +Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.http_metrics.HTTP_SERVER_REQUEST_DURATION`. +""" + + +def create_http_server_request_duration(meter: Meter) -> Histogram: + """Duration of HTTP server requests""" + return meter.create_histogram( + name=HTTP_SERVER_REQUEST_DURATION, + description="Duration of HTTP server requests.", + unit="s", + ) + + +HTTP_SERVER_RESPONSE_BODY_SIZE: Final = "http.server.response.body.size" +""" +Size of HTTP server response bodies +Instrument: histogram +Unit: By +Note: The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. +""" + + +def create_http_server_response_body_size(meter: Meter) -> Histogram: + """Size of HTTP server response bodies""" + return meter.create_histogram( + name=HTTP_SERVER_RESPONSE_BODY_SIZE, + description="Size of HTTP server response bodies.", + unit="By", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py new file mode 100644 index 00000000000..f42b0593dee --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py @@ -0,0 +1,755 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter + +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +HW_BATTERY_CHARGE: Final = "hw.battery.charge" +""" +Remaining fraction of battery charge +Instrument: gauge +Unit: 1 +""" + + +def create_hw_battery_charge(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Remaining fraction of battery charge""" + return meter.create_observable_gauge( + name=HW_BATTERY_CHARGE, + callbacks=callbacks, + description="Remaining fraction of battery charge.", + unit="1", + ) + + +HW_BATTERY_CHARGE_LIMIT: Final = "hw.battery.charge.limit" +""" +Lower limit of battery charge fraction to ensure proper operation +Instrument: gauge +Unit: 1 +""" + + +def create_hw_battery_charge_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Lower limit of battery charge fraction to ensure proper operation""" + return meter.create_observable_gauge( + name=HW_BATTERY_CHARGE_LIMIT, + callbacks=callbacks, + description="Lower limit of battery charge fraction to ensure proper operation.", + unit="1", + ) + + +HW_BATTERY_TIME_LEFT: Final = "hw.battery.time_left" +""" +Time left before battery is completely charged or discharged +Instrument: gauge +Unit: s +""" + + +def create_hw_battery_time_left(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Time left before battery is completely charged or discharged""" + return meter.create_observable_gauge( + name=HW_BATTERY_TIME_LEFT, + callbacks=callbacks, + description="Time left before battery is completely charged or discharged.", + unit="s", + ) + + +HW_CPU_SPEED: Final = "hw.cpu.speed" +""" +CPU current frequency +Instrument: gauge +Unit: Hz +""" + + +def create_hw_cpu_speed(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """CPU current frequency""" + return meter.create_observable_gauge( + name=HW_CPU_SPEED, + callbacks=callbacks, + description="CPU current frequency.", + unit="Hz", + ) + + +HW_CPU_SPEED_LIMIT: Final = "hw.cpu.speed.limit" +""" +CPU maximum frequency +Instrument: gauge +Unit: Hz +""" + + +def create_hw_cpu_speed_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """CPU maximum frequency""" + return meter.create_observable_gauge( + name=HW_CPU_SPEED_LIMIT, + callbacks=callbacks, + description="CPU maximum frequency.", + unit="Hz", + ) + + +HW_ENERGY: Final = "hw.energy" +""" +Energy consumed by the component +Instrument: counter +Unit: J +""" + + +def create_hw_energy(meter: Meter) -> Counter: + """Energy consumed by the component""" + return meter.create_counter( + name=HW_ENERGY, + description="Energy consumed by the component.", + unit="J", + ) + + +HW_ERRORS: Final = "hw.errors" +""" +Number of errors encountered by the component +Instrument: counter +Unit: {error} +""" + + +def create_hw_errors(meter: Meter) -> Counter: + """Number of errors encountered by the component""" + return meter.create_counter( + name=HW_ERRORS, + description="Number of errors encountered by the component.", + unit="{error}", + ) + + +HW_FAN_SPEED: Final = "hw.fan.speed" +""" +Fan speed in revolutions per minute +Instrument: gauge +Unit: rpm +""" + + +def create_hw_fan_speed(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Fan speed in revolutions per minute""" + return meter.create_observable_gauge( + name=HW_FAN_SPEED, + callbacks=callbacks, + description="Fan speed in revolutions per minute.", + unit="rpm", + ) + + +HW_FAN_SPEED_LIMIT: Final = "hw.fan.speed.limit" +""" +Speed limit in rpm +Instrument: gauge +Unit: rpm +""" + + +def create_hw_fan_speed_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Speed limit in rpm""" + return meter.create_observable_gauge( + name=HW_FAN_SPEED_LIMIT, + callbacks=callbacks, + description="Speed limit in rpm.", + unit="rpm", + ) + + +HW_FAN_SPEED_RATIO: Final = "hw.fan.speed_ratio" +""" +Fan speed expressed as a fraction of its maximum speed +Instrument: gauge +Unit: 1 +""" + + +def create_hw_fan_speed_ratio(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Fan speed expressed as a fraction of its maximum speed""" + return meter.create_observable_gauge( + name=HW_FAN_SPEED_RATIO, + callbacks=callbacks, + description="Fan speed expressed as a fraction of its maximum speed.", + unit="1", + ) + + +HW_GPU_IO: Final = "hw.gpu.io" +""" +Received and transmitted bytes by the GPU +Instrument: counter +Unit: By +""" + + +def create_hw_gpu_io(meter: Meter) -> Counter: + """Received and transmitted bytes by the GPU""" + return meter.create_counter( + name=HW_GPU_IO, + description="Received and transmitted bytes by the GPU.", + unit="By", + ) + + +HW_GPU_MEMORY_LIMIT: Final = "hw.gpu.memory.limit" +""" +Size of the GPU memory +Instrument: updowncounter +Unit: By +""" + + +def create_hw_gpu_memory_limit(meter: Meter) -> UpDownCounter: + """Size of the GPU memory""" + return meter.create_up_down_counter( + name=HW_GPU_MEMORY_LIMIT, + description="Size of the GPU memory.", + unit="By", + ) + + +HW_GPU_MEMORY_USAGE: Final = "hw.gpu.memory.usage" +""" +GPU memory used +Instrument: updowncounter +Unit: By +""" + + +def create_hw_gpu_memory_usage(meter: Meter) -> UpDownCounter: + """GPU memory used""" + return meter.create_up_down_counter( + name=HW_GPU_MEMORY_USAGE, + description="GPU memory used.", + unit="By", + ) + + +HW_GPU_MEMORY_UTILIZATION: Final = "hw.gpu.memory.utilization" +""" +Fraction of GPU memory used +Instrument: gauge +Unit: 1 +""" + + +def create_hw_gpu_memory_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Fraction of GPU memory used""" + return meter.create_observable_gauge( + name=HW_GPU_MEMORY_UTILIZATION, + callbacks=callbacks, + description="Fraction of GPU memory used.", + unit="1", + ) + + +HW_GPU_UTILIZATION: Final = "hw.gpu.utilization" +""" +Fraction of time spent in a specific task +Instrument: gauge +Unit: 1 +""" + + +def create_hw_gpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Fraction of time spent in a specific task""" + return meter.create_observable_gauge( + name=HW_GPU_UTILIZATION, + callbacks=callbacks, + description="Fraction of time spent in a specific task.", + unit="1", + ) + + +HW_HOST_AMBIENT_TEMPERATURE: Final = "hw.host.ambient_temperature" +""" +Ambient (external) temperature of the physical host +Instrument: gauge +Unit: Cel +""" + + +def create_hw_host_ambient_temperature(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Ambient (external) temperature of the physical host""" + return meter.create_observable_gauge( + name=HW_HOST_AMBIENT_TEMPERATURE, + callbacks=callbacks, + description="Ambient (external) temperature of the physical host.", + unit="Cel", + ) + + +HW_HOST_ENERGY: Final = "hw.host.energy" +""" +Total energy consumed by the entire physical host, in joules +Instrument: counter +Unit: J +Note: The overall energy usage of a host MUST be reported using the specific `hw.host.energy` and `hw.host.power` metrics **only**, instead of the generic `hw.energy` and `hw.power` described in the previous section, to prevent summing up overlapping values. +""" + + +def create_hw_host_energy(meter: Meter) -> Counter: + """Total energy consumed by the entire physical host, in joules""" + return meter.create_counter( + name=HW_HOST_ENERGY, + description="Total energy consumed by the entire physical host, in joules.", + unit="J", + ) + + +HW_HOST_HEATING_MARGIN: Final = "hw.host.heating_margin" +""" +By how many degrees Celsius the temperature of the physical host can be increased, before reaching a warning threshold on one of the internal sensors +Instrument: gauge +Unit: Cel +""" + + +def create_hw_host_heating_margin(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """By how many degrees Celsius the temperature of the physical host can be increased, before reaching a warning threshold on one of the internal sensors""" + return meter.create_observable_gauge( + name=HW_HOST_HEATING_MARGIN, + callbacks=callbacks, + description="By how many degrees Celsius the temperature of the physical host can be increased, before reaching a warning threshold on one of the internal sensors.", + unit="Cel", + ) + + +HW_HOST_POWER: Final = "hw.host.power" +""" +Instantaneous power consumed by the entire physical host in Watts (`hw.host.energy` is preferred) +Instrument: gauge +Unit: W +Note: The overall energy usage of a host MUST be reported using the specific `hw.host.energy` and `hw.host.power` metrics **only**, instead of the generic `hw.energy` and `hw.power` described in the previous section, to prevent summing up overlapping values. +""" + + +def create_hw_host_power(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Instantaneous power consumed by the entire physical host in Watts (`hw.host.energy` is preferred)""" + return meter.create_observable_gauge( + name=HW_HOST_POWER, + callbacks=callbacks, + description="Instantaneous power consumed by the entire physical host in Watts (`hw.host.energy` is preferred).", + unit="W", + ) + + +HW_LOGICAL_DISK_LIMIT: Final = "hw.logical_disk.limit" +""" +Size of the logical disk +Instrument: updowncounter +Unit: By +""" + + +def create_hw_logical_disk_limit(meter: Meter) -> UpDownCounter: + """Size of the logical disk""" + return meter.create_up_down_counter( + name=HW_LOGICAL_DISK_LIMIT, + description="Size of the logical disk.", + unit="By", + ) + + +HW_LOGICAL_DISK_USAGE: Final = "hw.logical_disk.usage" +""" +Logical disk space usage +Instrument: updowncounter +Unit: By +""" + + +def create_hw_logical_disk_usage(meter: Meter) -> UpDownCounter: + """Logical disk space usage""" + return meter.create_up_down_counter( + name=HW_LOGICAL_DISK_USAGE, + description="Logical disk space usage.", + unit="By", + ) + + +HW_LOGICAL_DISK_UTILIZATION: Final = "hw.logical_disk.utilization" +""" +Logical disk space utilization as a fraction +Instrument: gauge +Unit: 1 +""" + + +def create_hw_logical_disk_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Logical disk space utilization as a fraction""" + return meter.create_observable_gauge( + name=HW_LOGICAL_DISK_UTILIZATION, + callbacks=callbacks, + description="Logical disk space utilization as a fraction.", + unit="1", + ) + + +HW_MEMORY_SIZE: Final = "hw.memory.size" +""" +Size of the memory module +Instrument: updowncounter +Unit: By +""" + + +def create_hw_memory_size(meter: Meter) -> UpDownCounter: + """Size of the memory module""" + return meter.create_up_down_counter( + name=HW_MEMORY_SIZE, + description="Size of the memory module.", + unit="By", + ) + + +HW_NETWORK_BANDWIDTH_LIMIT: Final = "hw.network.bandwidth.limit" +""" +Link speed +Instrument: updowncounter +Unit: By/s +""" + + +def create_hw_network_bandwidth_limit(meter: Meter) -> UpDownCounter: + """Link speed""" + return meter.create_up_down_counter( + name=HW_NETWORK_BANDWIDTH_LIMIT, + description="Link speed.", + unit="By/s", + ) + + +HW_NETWORK_BANDWIDTH_UTILIZATION: Final = "hw.network.bandwidth.utilization" +""" +Utilization of the network bandwidth as a fraction +Instrument: gauge +Unit: 1 +""" + + +def create_hw_network_bandwidth_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Utilization of the network bandwidth as a fraction""" + return meter.create_observable_gauge( + name=HW_NETWORK_BANDWIDTH_UTILIZATION, + callbacks=callbacks, + description="Utilization of the network bandwidth as a fraction.", + unit="1", + ) + + +HW_NETWORK_IO: Final = "hw.network.io" +""" +Received and transmitted network traffic in bytes +Instrument: counter +Unit: By +""" + + +def create_hw_network_io(meter: Meter) -> Counter: + """Received and transmitted network traffic in bytes""" + return meter.create_counter( + name=HW_NETWORK_IO, + description="Received and transmitted network traffic in bytes.", + unit="By", + ) + + +HW_NETWORK_PACKETS: Final = "hw.network.packets" +""" +Received and transmitted network traffic in packets (or frames) +Instrument: counter +Unit: {packet} +""" + + +def create_hw_network_packets(meter: Meter) -> Counter: + """Received and transmitted network traffic in packets (or frames)""" + return meter.create_counter( + name=HW_NETWORK_PACKETS, + description="Received and transmitted network traffic in packets (or frames).", + unit="{packet}", + ) + + +HW_NETWORK_UP: Final = "hw.network.up" +""" +Link status: `1` (up) or `0` (down) +Instrument: updowncounter +Unit: 1 +""" + + +def create_hw_network_up(meter: Meter) -> UpDownCounter: + """Link status: `1` (up) or `0` (down)""" + return meter.create_up_down_counter( + name=HW_NETWORK_UP, + description="Link status: `1` (up) or `0` (down).", + unit="1", + ) + + +HW_PHYSICAL_DISK_ENDURANCE_UTILIZATION: Final = "hw.physical_disk.endurance_utilization" +""" +Endurance remaining for this SSD disk +Instrument: gauge +Unit: 1 +""" + + +def create_hw_physical_disk_endurance_utilization( + meter: Meter, callbacks: Sequence[CallbackT] | None +) -> ObservableGauge: + """Endurance remaining for this SSD disk""" + return meter.create_observable_gauge( + name=HW_PHYSICAL_DISK_ENDURANCE_UTILIZATION, + callbacks=callbacks, + description="Endurance remaining for this SSD disk.", + unit="1", + ) + + +HW_PHYSICAL_DISK_SIZE: Final = "hw.physical_disk.size" +""" +Size of the disk +Instrument: updowncounter +Unit: By +""" + + +def create_hw_physical_disk_size(meter: Meter) -> UpDownCounter: + """Size of the disk""" + return meter.create_up_down_counter( + name=HW_PHYSICAL_DISK_SIZE, + description="Size of the disk.", + unit="By", + ) + + +HW_PHYSICAL_DISK_SMART: Final = "hw.physical_disk.smart" +""" +Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute +Instrument: gauge +Unit: 1 +""" + + +def create_hw_physical_disk_smart(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute""" + return meter.create_observable_gauge( + name=HW_PHYSICAL_DISK_SMART, + callbacks=callbacks, + description="Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute.", + unit="1", + ) + + +HW_POWER: Final = "hw.power" +""" +Instantaneous power consumed by the component +Instrument: gauge +Unit: W +Note: It is recommended to report `hw.energy` instead of `hw.power` when possible. +""" + + +def create_hw_power(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Instantaneous power consumed by the component""" + return meter.create_observable_gauge( + name=HW_POWER, + callbacks=callbacks, + description="Instantaneous power consumed by the component.", + unit="W", + ) + + +HW_POWER_SUPPLY_LIMIT: Final = "hw.power_supply.limit" +""" +Maximum power output of the power supply +Instrument: updowncounter +Unit: W +""" + + +def create_hw_power_supply_limit(meter: Meter) -> UpDownCounter: + """Maximum power output of the power supply""" + return meter.create_up_down_counter( + name=HW_POWER_SUPPLY_LIMIT, + description="Maximum power output of the power supply.", + unit="W", + ) + + +HW_POWER_SUPPLY_USAGE: Final = "hw.power_supply.usage" +""" +Current power output of the power supply +Instrument: updowncounter +Unit: W +""" + + +def create_hw_power_supply_usage(meter: Meter) -> UpDownCounter: + """Current power output of the power supply""" + return meter.create_up_down_counter( + name=HW_POWER_SUPPLY_USAGE, + description="Current power output of the power supply.", + unit="W", + ) + + +HW_POWER_SUPPLY_UTILIZATION: Final = "hw.power_supply.utilization" +""" +Utilization of the power supply as a fraction of its maximum output +Instrument: gauge +Unit: 1 +""" + + +def create_hw_power_supply_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Utilization of the power supply as a fraction of its maximum output""" + return meter.create_observable_gauge( + name=HW_POWER_SUPPLY_UTILIZATION, + callbacks=callbacks, + description="Utilization of the power supply as a fraction of its maximum output.", + unit="1", + ) + + +HW_STATUS: Final = "hw.status" +""" +Operational status: `1` (true) or `0` (false) for each of the possible states +Instrument: updowncounter +Unit: 1 +Note: `hw.status` is currently specified as an *UpDownCounter* but would ideally be represented using a [*StateSet* as defined in OpenMetrics](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#stateset). This semantic convention will be updated once *StateSet* is specified in OpenTelemetry. This planned change is not expected to have any consequence on the way users query their timeseries backend to retrieve the values of `hw.status` over time. +""" + + +def create_hw_status(meter: Meter) -> UpDownCounter: + """Operational status: `1` (true) or `0` (false) for each of the possible states""" + return meter.create_up_down_counter( + name=HW_STATUS, + description="Operational status: `1` (true) or `0` (false) for each of the possible states.", + unit="1", + ) + + +HW_TAPE_DRIVE_OPERATIONS: Final = "hw.tape_drive.operations" +""" +Operations performed by the tape drive +Instrument: counter +Unit: {operation} +""" + + +def create_hw_tape_drive_operations(meter: Meter) -> Counter: + """Operations performed by the tape drive""" + return meter.create_counter( + name=HW_TAPE_DRIVE_OPERATIONS, + description="Operations performed by the tape drive.", + unit="{operation}", + ) + + +HW_TEMPERATURE: Final = "hw.temperature" +""" +Temperature in degrees Celsius +Instrument: gauge +Unit: Cel +""" + + +def create_hw_temperature(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Temperature in degrees Celsius""" + return meter.create_observable_gauge( + name=HW_TEMPERATURE, + callbacks=callbacks, + description="Temperature in degrees Celsius.", + unit="Cel", + ) + + +HW_TEMPERATURE_LIMIT: Final = "hw.temperature.limit" +""" +Temperature limit in degrees Celsius +Instrument: gauge +Unit: Cel +""" + + +def create_hw_temperature_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Temperature limit in degrees Celsius""" + return meter.create_observable_gauge( + name=HW_TEMPERATURE_LIMIT, + callbacks=callbacks, + description="Temperature limit in degrees Celsius.", + unit="Cel", + ) + + +HW_VOLTAGE: Final = "hw.voltage" +""" +Voltage measured by the sensor +Instrument: gauge +Unit: V +""" + + +def create_hw_voltage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Voltage measured by the sensor""" + return meter.create_observable_gauge( + name=HW_VOLTAGE, + callbacks=callbacks, + description="Voltage measured by the sensor.", + unit="V", + ) + + +HW_VOLTAGE_LIMIT: Final = "hw.voltage.limit" +""" +Voltage limit in Volts +Instrument: gauge +Unit: V +""" + + +def create_hw_voltage_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Voltage limit in Volts""" + return meter.create_observable_gauge( + name=HW_VOLTAGE_LIMIT, + callbacks=callbacks, + description="Voltage limit in Volts.", + unit="V", + ) + + +HW_VOLTAGE_NOMINAL: Final = "hw.voltage.nominal" +""" +Nominal (expected) voltage +Instrument: gauge +Unit: V +""" + + +def create_hw_voltage_nominal(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Nominal (expected) voltage""" + return meter.create_observable_gauge( + name=HW_VOLTAGE_NOMINAL, + callbacks=callbacks, + description="Nominal (expected) voltage.", + unit="V", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py new file mode 100644 index 00000000000..8fdde341f92 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py @@ -0,0 +1,2952 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter + +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +K8S_CONTAINER_CPU_LIMIT: Final = "k8s.container.cpu.limit" +""" +Deprecated: Replaced by `k8s.container.cpu.limit.desired`. +""" + + +def create_k8s_container_cpu_limit(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.container.cpu.limit.desired` and `k8s.container.cpu.limit.current` instead""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_CPU_LIMIT, + description="Deprecated, use `k8s.container.cpu.limit.desired` and `k8s.container.cpu.limit.current` instead.", + unit="{cpu}", + ) + + +K8S_CONTAINER_CPU_LIMIT_CURRENT: Final = "k8s.container.cpu.limit.current" +""" +Maximum CPU resource limit currently configured for a running container +Instrument: updowncounter +Unit: {cpu} +Note: This metric aligns with the limit in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) +(status.containerStatuses[*].resources). Also see `Actual Resources` in + for more details. +""" + + +def create_k8s_container_cpu_limit_current(meter: Meter) -> UpDownCounter: + """Maximum CPU resource limit currently configured for a running container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_CPU_LIMIT_CURRENT, + description="Maximum CPU resource limit currently configured for a running container.", + unit="{cpu}", + ) + + +K8S_CONTAINER_CPU_LIMIT_DESIRED: Final = "k8s.container.cpu.limit.desired" +""" +Maximum CPU resource limit as defined by the container spec +Instrument: updowncounter +Unit: {cpu} +Note: This metric aligns with the limit in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) +(spec.containers[*].resources). Also see `Desired Resources` in + for more details. +""" + + +def create_k8s_container_cpu_limit_desired(meter: Meter) -> UpDownCounter: + """Maximum CPU resource limit as defined by the container spec""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_CPU_LIMIT_DESIRED, + description="Maximum CPU resource limit as defined by the container spec.", + unit="{cpu}", + ) + + +K8S_CONTAINER_CPU_LIMIT_UTILIZATION: Final = "k8s.container.cpu.limit.utilization" +""" +The ratio of container CPU usage to its current CPU limit +Instrument: gauge +Unit: 1 +Note: The current CPU limit reflects the actual resources applied to the container, as reported by +[ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core). +The value range is [0.0,1.0]. A value of 1.0 means the container is using 100% of its actual CPU limit. +If the CPU limit is not set, this metric SHOULD NOT be emitted for that container. +""" + + +def create_k8s_container_cpu_limit_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The ratio of container CPU usage to its current CPU limit""" + return meter.create_observable_gauge( + name=K8S_CONTAINER_CPU_LIMIT_UTILIZATION, + callbacks=callbacks, + description="The ratio of container CPU usage to its current CPU limit.", + unit="1", + ) + + +K8S_CONTAINER_CPU_REQUEST: Final = "k8s.container.cpu.request" +""" +Deprecated: Replaced by `k8s.container.cpu.request.desired`. +""" + + +def create_k8s_container_cpu_request(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.container.cpu.request.desired` and `k8s.container.cpu.request.current` instead""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_CPU_REQUEST, + description="Deprecated, use `k8s.container.cpu.request.desired` and `k8s.container.cpu.request.current` instead.", + unit="{cpu}", + ) + + +K8S_CONTAINER_CPU_REQUEST_CURRENT: Final = "k8s.container.cpu.request.current" +""" +CPU resource requested currently configured for a running container +Instrument: updowncounter +Unit: {cpu} +Note: This metric aligns with the request in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) +(status.containerStatuses[*].resources). Also see `Actual Resources` in + for more details. +""" + + +def create_k8s_container_cpu_request_current(meter: Meter) -> UpDownCounter: + """CPU resource requested currently configured for a running container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_CPU_REQUEST_CURRENT, + description="CPU resource requested currently configured for a running container.", + unit="{cpu}", + ) + + +K8S_CONTAINER_CPU_REQUEST_DESIRED: Final = "k8s.container.cpu.request.desired" +""" +CPU resource requested as defined by the container spec +Instrument: updowncounter +Unit: {cpu} +Note: This metric aligns with the request in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) +(spec.containers[*].resources). Also see `Desired Resources` in + for more details. +""" + + +def create_k8s_container_cpu_request_desired(meter: Meter) -> UpDownCounter: + """CPU resource requested as defined by the container spec""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_CPU_REQUEST_DESIRED, + description="CPU resource requested as defined by the container spec.", + unit="{cpu}", + ) + + +K8S_CONTAINER_CPU_REQUEST_UTILIZATION: Final = "k8s.container.cpu.request.utilization" +""" +The ratio of container CPU usage to its current CPU request +Instrument: gauge +Unit: 1 +Note: The current CPU request reflects the request applied to the running container, as reported by +[ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core). +The value range is [0.0,1.0]. A value of 1.0 means the container is using 100% of its actual CPU request. +If the CPU request is not set, this metric SHOULD NOT be emitted for that container. +""" + + +def create_k8s_container_cpu_request_utilization( + meter: Meter, callbacks: Sequence[CallbackT] | None +) -> ObservableGauge: + """The ratio of container CPU usage to its current CPU request""" + return meter.create_observable_gauge( + name=K8S_CONTAINER_CPU_REQUEST_UTILIZATION, + callbacks=callbacks, + description="The ratio of container CPU usage to its current CPU request.", + unit="1", + ) + + +K8S_CONTAINER_EPHEMERAL_STORAGE_LIMIT: Final = "k8s.container.ephemeral_storage.limit" +""" +Maximum ephemeral storage resource limit set for the container +Instrument: updowncounter +Unit: By +Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. +""" + + +def create_k8s_container_ephemeral_storage_limit(meter: Meter) -> UpDownCounter: + """Maximum ephemeral storage resource limit set for the container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_EPHEMERAL_STORAGE_LIMIT, + description="Maximum ephemeral storage resource limit set for the container.", + unit="By", + ) + + +K8S_CONTAINER_EPHEMERAL_STORAGE_REQUEST: Final = "k8s.container.ephemeral_storage.request" +""" +Ephemeral storage resource requested for the container +Instrument: updowncounter +Unit: By +Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. +""" + + +def create_k8s_container_ephemeral_storage_request(meter: Meter) -> UpDownCounter: + """Ephemeral storage resource requested for the container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_EPHEMERAL_STORAGE_REQUEST, + description="Ephemeral storage resource requested for the container.", + unit="By", + ) + + +K8S_CONTAINER_EPHEMERAL_STORAGE_USAGE: Final = "k8s.container.ephemeral_storage.usage" +""" +The ephemeral storage used by a container +Instrument: updowncounter +Unit: By +Note: The value for this metric can be compared against `metric.k8s.container.ephemeral_storage.request` and `metric.k8s.container.ephemeral_storage.limit`. +""" + + +def create_k8s_container_ephemeral_storage_usage(meter: Meter) -> UpDownCounter: + """The ephemeral storage used by a container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_EPHEMERAL_STORAGE_USAGE, + description="The ephemeral storage used by a container.", + unit="By", + ) + + +K8S_CONTAINER_MEMORY_LIMIT: Final = "k8s.container.memory.limit" +""" +Deprecated: Replaced by `k8s.container.memory.limit.desired`. +""" + + +def create_k8s_container_memory_limit(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.container.memory.limit.desired` and `k8s.container.memory.limit.current` instead""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_MEMORY_LIMIT, + description="Deprecated, use `k8s.container.memory.limit.desired` and `k8s.container.memory.limit.current` instead.", + unit="By", + ) + + +K8S_CONTAINER_MEMORY_LIMIT_CURRENT: Final = "k8s.container.memory.limit.current" +""" +Maximum memory resource limit currently configured for a running container +Instrument: updowncounter +Unit: By +Note: This metric aligns with the limit in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) +(status.containerStatuses[*].resources). Also see `Actual Resources` in + for more details. +""" + + +def create_k8s_container_memory_limit_current(meter: Meter) -> UpDownCounter: + """Maximum memory resource limit currently configured for a running container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_MEMORY_LIMIT_CURRENT, + description="Maximum memory resource limit currently configured for a running container.", + unit="By", + ) + + +K8S_CONTAINER_MEMORY_LIMIT_DESIRED: Final = "k8s.container.memory.limit.desired" +""" +Maximum memory resource limit as defined by the container spec +Instrument: updowncounter +Unit: By +Note: This metric aligns with the limit in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) +(spec.containers[*].resources). Also see `Desired Resources` in + for more details. +""" + + +def create_k8s_container_memory_limit_desired(meter: Meter) -> UpDownCounter: + """Maximum memory resource limit as defined by the container spec""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_MEMORY_LIMIT_DESIRED, + description="Maximum memory resource limit as defined by the container spec.", + unit="By", + ) + + +K8S_CONTAINER_MEMORY_REQUEST: Final = "k8s.container.memory.request" +""" +Deprecated: Replaced by `k8s.container.memory.request.desired`. +""" + + +def create_k8s_container_memory_request(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.container.memory.request.desired` and `k8s.container.memory.request.current` instead""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_MEMORY_REQUEST, + description="Deprecated, use `k8s.container.memory.request.desired` and `k8s.container.memory.request.current` instead.", + unit="By", + ) + + +K8S_CONTAINER_MEMORY_REQUEST_CURRENT: Final = "k8s.container.memory.request.current" +""" +Memory resource request currently configured for a running container +Instrument: updowncounter +Unit: By +Note: This metric aligns with the request in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) +(status.containerStatuses[*].resources). Also see `Actual Resources` in + for more details. +""" + + +def create_k8s_container_memory_request_current(meter: Meter) -> UpDownCounter: + """Memory resource request currently configured for a running container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_MEMORY_REQUEST_CURRENT, + description="Memory resource request currently configured for a running container.", + unit="By", + ) + + +K8S_CONTAINER_MEMORY_REQUEST_DESIRED: Final = "k8s.container.memory.request.desired" +""" +Memory resource requested as defined by the container spec +Instrument: updowncounter +Unit: By +Note: This metric aligns with the request in the +[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of +[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) +(spec.containers[*].resources). Also see `Desired Resources` in + for more details. +""" + + +def create_k8s_container_memory_request_desired(meter: Meter) -> UpDownCounter: + """Memory resource requested as defined by the container spec""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_MEMORY_REQUEST_DESIRED, + description="Memory resource requested as defined by the container spec.", + unit="By", + ) + + +K8S_CONTAINER_READY: Final = "k8s.container.ready" +""" +Indicates whether the container is currently marked as ready to accept traffic, based on its readiness probe (1 = ready, 0 = not ready) +Instrument: updowncounter +Unit: {container} +Note: This metric SHOULD reflect the value of the `ready` field in the +[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core). +""" + + +def create_k8s_container_ready(meter: Meter) -> UpDownCounter: + """Indicates whether the container is currently marked as ready to accept traffic, based on its readiness probe (1 = ready, 0 = not ready)""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_READY, + description="Indicates whether the container is currently marked as ready to accept traffic, based on its readiness probe (1 = ready, 0 = not ready).", + unit="{container}", + ) + + +K8S_CONTAINER_RESTART_COUNT: Final = "k8s.container.restart.count" +""" +Describes how many times the container has restarted (since the last counter reset) +Instrument: updowncounter +Unit: {restart} +Note: This value is pulled directly from the K8s API and the value can go indefinitely high and be reset to 0 +at any time depending on how your kubelet is configured to prune dead containers. +It is best to not depend too much on the exact value but rather look at it as +either == 0, in which case you can conclude there were no restarts in the recent past, or > 0, in which case +you can conclude there were restarts in the recent past, and not try and analyze the value beyond that. +""" + + +def create_k8s_container_restart_count(meter: Meter) -> UpDownCounter: + """Describes how many times the container has restarted (since the last counter reset)""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_RESTART_COUNT, + description="Describes how many times the container has restarted (since the last counter reset).", + unit="{restart}", + ) + + +K8S_CONTAINER_STATUS_REASON: Final = "k8s.container.status.reason" +""" +Describes the number of K8s containers that are currently in a state for a given reason +Instrument: updowncounter +Unit: {container} +Note: All possible container state reasons will be reported at each time interval to avoid missing metrics. +Only the value corresponding to the current state reason will be non-zero. +""" + + +def create_k8s_container_status_reason(meter: Meter) -> UpDownCounter: + """Describes the number of K8s containers that are currently in a state for a given reason""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_STATUS_REASON, + description="Describes the number of K8s containers that are currently in a state for a given reason.", + unit="{container}", + ) + + +K8S_CONTAINER_STATUS_STATE: Final = "k8s.container.status.state" +""" +Describes the number of K8s containers that are currently in a given state +Instrument: updowncounter +Unit: {container} +Note: All possible container states will be reported at each time interval to avoid missing metrics. +Only the value corresponding to the current state will be non-zero. +""" + + +def create_k8s_container_status_state(meter: Meter) -> UpDownCounter: + """Describes the number of K8s containers that are currently in a given state""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_STATUS_STATE, + description="Describes the number of K8s containers that are currently in a given state.", + unit="{container}", + ) + + +K8S_CONTAINER_STORAGE_LIMIT: Final = "k8s.container.storage.limit" +""" +Maximum storage resource limit set for the container +Instrument: updowncounter +Unit: By +Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. +""" + + +def create_k8s_container_storage_limit(meter: Meter) -> UpDownCounter: + """Maximum storage resource limit set for the container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_STORAGE_LIMIT, + description="Maximum storage resource limit set for the container.", + unit="By", + ) + + +K8S_CONTAINER_STORAGE_REQUEST: Final = "k8s.container.storage.request" +""" +Storage resource requested for the container +Instrument: updowncounter +Unit: By +Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. +""" + + +def create_k8s_container_storage_request(meter: Meter) -> UpDownCounter: + """Storage resource requested for the container""" + return meter.create_up_down_counter( + name=K8S_CONTAINER_STORAGE_REQUEST, + description="Storage resource requested for the container.", + unit="By", + ) + + +K8S_CRONJOB_ACTIVE_JOBS: Final = "k8s.cronjob.active_jobs" +""" +Deprecated: Replaced by `k8s.cronjob.job.active`. +""" + + +def create_k8s_cronjob_active_jobs(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.cronjob.job.active` instead""" + return meter.create_up_down_counter( + name=K8S_CRONJOB_ACTIVE_JOBS, + description="Deprecated, use `k8s.cronjob.job.active` instead.", + unit="{job}", + ) + + +K8S_CRONJOB_JOB_ACTIVE: Final = "k8s.cronjob.job.active" +""" +The number of actively running jobs for a cronjob +Instrument: updowncounter +Unit: {job} +Note: This metric aligns with the `active` field of the +[K8s CronJobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#cronjobstatus-v1-batch). +""" + + +def create_k8s_cronjob_job_active(meter: Meter) -> UpDownCounter: + """The number of actively running jobs for a cronjob""" + return meter.create_up_down_counter( + name=K8S_CRONJOB_JOB_ACTIVE, + description="The number of actively running jobs for a cronjob.", + unit="{job}", + ) + + +K8S_DAEMONSET_CURRENT_SCHEDULED_NODES: Final = "k8s.daemonset.current_scheduled_nodes" +""" +Deprecated: Replaced by `k8s.daemonset.node.current_scheduled`. +""" + + +def create_k8s_daemonset_current_scheduled_nodes(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.daemonset.node.current_scheduled` instead""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_CURRENT_SCHEDULED_NODES, + description="Deprecated, use `k8s.daemonset.node.current_scheduled` instead.", + unit="{node}", + ) + + +K8S_DAEMONSET_DESIRED_SCHEDULED_NODES: Final = "k8s.daemonset.desired_scheduled_nodes" +""" +Deprecated: Replaced by `k8s.daemonset.node.desired_scheduled`. +""" + + +def create_k8s_daemonset_desired_scheduled_nodes(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.daemonset.node.desired_scheduled` instead""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_DESIRED_SCHEDULED_NODES, + description="Deprecated, use `k8s.daemonset.node.desired_scheduled` instead.", + unit="{node}", + ) + + +K8S_DAEMONSET_MISSCHEDULED_NODES: Final = "k8s.daemonset.misscheduled_nodes" +""" +Deprecated: Replaced by `k8s.daemonset.node.misscheduled`. +""" + + +def create_k8s_daemonset_misscheduled_nodes(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.daemonset.node.misscheduled` instead""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_MISSCHEDULED_NODES, + description="Deprecated, use `k8s.daemonset.node.misscheduled` instead.", + unit="{node}", + ) + + +K8S_DAEMONSET_NODE_CURRENT_SCHEDULED: Final = "k8s.daemonset.node.current_scheduled" +""" +Number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod +Instrument: updowncounter +Unit: {node} +Note: This metric aligns with the `currentNumberScheduled` field of the +[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). +""" + + +def create_k8s_daemonset_node_current_scheduled(meter: Meter) -> UpDownCounter: + """Number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_NODE_CURRENT_SCHEDULED, + description="Number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod.", + unit="{node}", + ) + + +K8S_DAEMONSET_NODE_DESIRED_SCHEDULED: Final = "k8s.daemonset.node.desired_scheduled" +""" +Number of nodes that should be running the daemon pod (including nodes currently running the daemon pod) +Instrument: updowncounter +Unit: {node} +Note: This metric aligns with the `desiredNumberScheduled` field of the +[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). +""" + + +def create_k8s_daemonset_node_desired_scheduled(meter: Meter) -> UpDownCounter: + """Number of nodes that should be running the daemon pod (including nodes currently running the daemon pod)""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_NODE_DESIRED_SCHEDULED, + description="Number of nodes that should be running the daemon pod (including nodes currently running the daemon pod).", + unit="{node}", + ) + + +K8S_DAEMONSET_NODE_MISSCHEDULED: Final = "k8s.daemonset.node.misscheduled" +""" +Number of nodes that are running the daemon pod, but are not supposed to run the daemon pod +Instrument: updowncounter +Unit: {node} +Note: This metric aligns with the `numberMisscheduled` field of the +[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). +""" + + +def create_k8s_daemonset_node_misscheduled(meter: Meter) -> UpDownCounter: + """Number of nodes that are running the daemon pod, but are not supposed to run the daemon pod""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_NODE_MISSCHEDULED, + description="Number of nodes that are running the daemon pod, but are not supposed to run the daemon pod.", + unit="{node}", + ) + + +K8S_DAEMONSET_NODE_READY: Final = "k8s.daemonset.node.ready" +""" +Number of nodes that should be running the daemon pod and have one or more of the daemon pod running and ready +Instrument: updowncounter +Unit: {node} +Note: This metric aligns with the `numberReady` field of the +[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). +""" + + +def create_k8s_daemonset_node_ready(meter: Meter) -> UpDownCounter: + """Number of nodes that should be running the daemon pod and have one or more of the daemon pod running and ready""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_NODE_READY, + description="Number of nodes that should be running the daemon pod and have one or more of the daemon pod running and ready.", + unit="{node}", + ) + + +K8S_DAEMONSET_READY_NODES: Final = "k8s.daemonset.ready_nodes" +""" +Deprecated: Replaced by `k8s.daemonset.node.ready`. +""" + + +def create_k8s_daemonset_ready_nodes(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.daemonset.node.ready` instead""" + return meter.create_up_down_counter( + name=K8S_DAEMONSET_READY_NODES, + description="Deprecated, use `k8s.daemonset.node.ready` instead.", + unit="{node}", + ) + + +K8S_DEPLOYMENT_AVAILABLE_PODS: Final = "k8s.deployment.available_pods" +""" +Deprecated: Replaced by `k8s.deployment.pod.available`. +""" + + +def create_k8s_deployment_available_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.deployment.pod.available` instead""" + return meter.create_up_down_counter( + name=K8S_DEPLOYMENT_AVAILABLE_PODS, + description="Deprecated, use `k8s.deployment.pod.available` instead.", + unit="{pod}", + ) + + +K8S_DEPLOYMENT_DESIRED_PODS: Final = "k8s.deployment.desired_pods" +""" +Deprecated: Replaced by `k8s.deployment.pod.desired`. +""" + + +def create_k8s_deployment_desired_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.deployment.pod.desired` instead""" + return meter.create_up_down_counter( + name=K8S_DEPLOYMENT_DESIRED_PODS, + description="Deprecated, use `k8s.deployment.pod.desired` instead.", + unit="{pod}", + ) + + +K8S_DEPLOYMENT_POD_AVAILABLE: Final = "k8s.deployment.pod.available" +""" +Total number of available replica pods (ready for at least minReadySeconds) targeted by this deployment +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `availableReplicas` field of the +[K8s DeploymentStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#deploymentstatus-v1-apps). +""" + + +def create_k8s_deployment_pod_available(meter: Meter) -> UpDownCounter: + """Total number of available replica pods (ready for at least minReadySeconds) targeted by this deployment""" + return meter.create_up_down_counter( + name=K8S_DEPLOYMENT_POD_AVAILABLE, + description="Total number of available replica pods (ready for at least minReadySeconds) targeted by this deployment.", + unit="{pod}", + ) + + +K8S_DEPLOYMENT_POD_DESIRED: Final = "k8s.deployment.pod.desired" +""" +Number of desired replica pods in this deployment +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `replicas` field of the +[K8s DeploymentSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#deploymentspec-v1-apps). +""" + + +def create_k8s_deployment_pod_desired(meter: Meter) -> UpDownCounter: + """Number of desired replica pods in this deployment""" + return meter.create_up_down_counter( + name=K8S_DEPLOYMENT_POD_DESIRED, + description="Number of desired replica pods in this deployment.", + unit="{pod}", + ) + + +K8S_HPA_CURRENT_PODS: Final = "k8s.hpa.current_pods" +""" +Deprecated: Replaced by `k8s.hpa.pod.current`. +""" + + +def create_k8s_hpa_current_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.hpa.pod.current` instead""" + return meter.create_up_down_counter( + name=K8S_HPA_CURRENT_PODS, + description="Deprecated, use `k8s.hpa.pod.current` instead.", + unit="{pod}", + ) + + +K8S_HPA_DESIRED_PODS: Final = "k8s.hpa.desired_pods" +""" +Deprecated: Replaced by `k8s.hpa.pod.desired`. +""" + + +def create_k8s_hpa_desired_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.hpa.pod.desired` instead""" + return meter.create_up_down_counter( + name=K8S_HPA_DESIRED_PODS, + description="Deprecated, use `k8s.hpa.pod.desired` instead.", + unit="{pod}", + ) + + +K8S_HPA_MAX_PODS: Final = "k8s.hpa.max_pods" +""" +Deprecated: Replaced by `k8s.hpa.pod.max`. +""" + + +def create_k8s_hpa_max_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.hpa.pod.max` instead""" + return meter.create_up_down_counter( + name=K8S_HPA_MAX_PODS, + description="Deprecated, use `k8s.hpa.pod.max` instead.", + unit="{pod}", + ) + + +K8S_HPA_METRIC_TARGET_CPU_AVERAGE_UTILIZATION: Final = "k8s.hpa.metric.target.cpu.average_utilization" +""" +Target average utilization, in percentage, for CPU resource in HPA config +Instrument: gauge +Unit: 1 +Note: This metric aligns with the `averageUtilization` field of the +[K8s HPA MetricTarget](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#metrictarget-v2-autoscaling). +If the type of the metric is [`ContainerResource`](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis), +the `k8s.container.name` attribute MUST be set to identify the specific container within the pod to which the metric applies. +""" + + +def create_k8s_hpa_metric_target_cpu_average_utilization( + meter: Meter, callbacks: Sequence[CallbackT] | None +) -> ObservableGauge: + """Target average utilization, in percentage, for CPU resource in HPA config""" + return meter.create_observable_gauge( + name=K8S_HPA_METRIC_TARGET_CPU_AVERAGE_UTILIZATION, + callbacks=callbacks, + description="Target average utilization, in percentage, for CPU resource in HPA config.", + unit="1", + ) + + +K8S_HPA_METRIC_TARGET_CPU_AVERAGE_VALUE: Final = "k8s.hpa.metric.target.cpu.average_value" +""" +Target average value for CPU resource in HPA config +Instrument: gauge +Unit: {cpu} +Note: This metric aligns with the `averageValue` field of the +[K8s HPA MetricTarget](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#metrictarget-v2-autoscaling). +If the type of the metric is [`ContainerResource`](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis), +the `k8s.container.name` attribute MUST be set to identify the specific container within the pod to which the metric applies. +""" + + +def create_k8s_hpa_metric_target_cpu_average_value( + meter: Meter, callbacks: Sequence[CallbackT] | None +) -> ObservableGauge: + """Target average value for CPU resource in HPA config""" + return meter.create_observable_gauge( + name=K8S_HPA_METRIC_TARGET_CPU_AVERAGE_VALUE, + callbacks=callbacks, + description="Target average value for CPU resource in HPA config.", + unit="{cpu}", + ) + + +K8S_HPA_METRIC_TARGET_CPU_VALUE: Final = "k8s.hpa.metric.target.cpu.value" +""" +Target value for CPU resource in HPA config +Instrument: gauge +Unit: {cpu} +Note: This metric aligns with the `value` field of the +[K8s HPA MetricTarget](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#metrictarget-v2-autoscaling). +If the type of the metric is [`ContainerResource`](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis), +the `k8s.container.name` attribute MUST be set to identify the specific container within the pod to which the metric applies. +""" + + +def create_k8s_hpa_metric_target_cpu_value(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Target value for CPU resource in HPA config""" + return meter.create_observable_gauge( + name=K8S_HPA_METRIC_TARGET_CPU_VALUE, + callbacks=callbacks, + description="Target value for CPU resource in HPA config.", + unit="{cpu}", + ) + + +K8S_HPA_MIN_PODS: Final = "k8s.hpa.min_pods" +""" +Deprecated: Replaced by `k8s.hpa.pod.min`. +""" + + +def create_k8s_hpa_min_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.hpa.pod.min` instead""" + return meter.create_up_down_counter( + name=K8S_HPA_MIN_PODS, + description="Deprecated, use `k8s.hpa.pod.min` instead.", + unit="{pod}", + ) + + +K8S_HPA_POD_CURRENT: Final = "k8s.hpa.pod.current" +""" +Current number of replica pods managed by this horizontal pod autoscaler, as last seen by the autoscaler +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `currentReplicas` field of the +[K8s HorizontalPodAutoscalerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerstatus-v2-autoscaling). +""" + + +def create_k8s_hpa_pod_current(meter: Meter) -> UpDownCounter: + """Current number of replica pods managed by this horizontal pod autoscaler, as last seen by the autoscaler""" + return meter.create_up_down_counter( + name=K8S_HPA_POD_CURRENT, + description="Current number of replica pods managed by this horizontal pod autoscaler, as last seen by the autoscaler.", + unit="{pod}", + ) + + +K8S_HPA_POD_DESIRED: Final = "k8s.hpa.pod.desired" +""" +Desired number of replica pods managed by this horizontal pod autoscaler, as last calculated by the autoscaler +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `desiredReplicas` field of the +[K8s HorizontalPodAutoscalerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerstatus-v2-autoscaling). +""" + + +def create_k8s_hpa_pod_desired(meter: Meter) -> UpDownCounter: + """Desired number of replica pods managed by this horizontal pod autoscaler, as last calculated by the autoscaler""" + return meter.create_up_down_counter( + name=K8S_HPA_POD_DESIRED, + description="Desired number of replica pods managed by this horizontal pod autoscaler, as last calculated by the autoscaler.", + unit="{pod}", + ) + + +K8S_HPA_POD_MAX: Final = "k8s.hpa.pod.max" +""" +The upper limit for the number of replica pods to which the autoscaler can scale up +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `maxReplicas` field of the +[K8s HorizontalPodAutoscalerSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerspec-v2-autoscaling). +""" + + +def create_k8s_hpa_pod_max(meter: Meter) -> UpDownCounter: + """The upper limit for the number of replica pods to which the autoscaler can scale up""" + return meter.create_up_down_counter( + name=K8S_HPA_POD_MAX, + description="The upper limit for the number of replica pods to which the autoscaler can scale up.", + unit="{pod}", + ) + + +K8S_HPA_POD_MIN: Final = "k8s.hpa.pod.min" +""" +The lower limit for the number of replica pods to which the autoscaler can scale down +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `minReplicas` field of the +[K8s HorizontalPodAutoscalerSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerspec-v2-autoscaling). +""" + + +def create_k8s_hpa_pod_min(meter: Meter) -> UpDownCounter: + """The lower limit for the number of replica pods to which the autoscaler can scale down""" + return meter.create_up_down_counter( + name=K8S_HPA_POD_MIN, + description="The lower limit for the number of replica pods to which the autoscaler can scale down.", + unit="{pod}", + ) + + +K8S_JOB_ACTIVE_PODS: Final = "k8s.job.active_pods" +""" +Deprecated: Replaced by `k8s.job.pod.active`. +""" + + +def create_k8s_job_active_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.job.pod.active` instead""" + return meter.create_up_down_counter( + name=K8S_JOB_ACTIVE_PODS, + description="Deprecated, use `k8s.job.pod.active` instead.", + unit="{pod}", + ) + + +K8S_JOB_DESIRED_SUCCESSFUL_PODS: Final = "k8s.job.desired_successful_pods" +""" +Deprecated: Replaced by `k8s.job.pod.desired_successful`. +""" + + +def create_k8s_job_desired_successful_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.job.pod.desired_successful` instead""" + return meter.create_up_down_counter( + name=K8S_JOB_DESIRED_SUCCESSFUL_PODS, + description="Deprecated, use `k8s.job.pod.desired_successful` instead.", + unit="{pod}", + ) + + +K8S_JOB_FAILED_PODS: Final = "k8s.job.failed_pods" +""" +Deprecated: Replaced by `k8s.job.pod.failed`. +""" + + +def create_k8s_job_failed_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.job.pod.failed` instead""" + return meter.create_up_down_counter( + name=K8S_JOB_FAILED_PODS, + description="Deprecated, use `k8s.job.pod.failed` instead.", + unit="{pod}", + ) + + +K8S_JOB_MAX_PARALLEL_PODS: Final = "k8s.job.max_parallel_pods" +""" +Deprecated: Replaced by `k8s.job.pod.max_parallel`. +""" + + +def create_k8s_job_max_parallel_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.job.pod.max_parallel` instead""" + return meter.create_up_down_counter( + name=K8S_JOB_MAX_PARALLEL_PODS, + description="Deprecated, use `k8s.job.pod.max_parallel` instead.", + unit="{pod}", + ) + + +K8S_JOB_POD_ACTIVE: Final = "k8s.job.pod.active" +""" +The number of pending and actively running pods for a job +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `active` field of the +[K8s JobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobstatus-v1-batch). +""" + + +def create_k8s_job_pod_active(meter: Meter) -> UpDownCounter: + """The number of pending and actively running pods for a job""" + return meter.create_up_down_counter( + name=K8S_JOB_POD_ACTIVE, + description="The number of pending and actively running pods for a job.", + unit="{pod}", + ) + + +K8S_JOB_POD_DESIRED_SUCCESSFUL: Final = "k8s.job.pod.desired_successful" +""" +The desired number of successfully finished pods the job should be run with +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `completions` field of the +[K8s JobSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobspec-v1-batch). +""" + + +def create_k8s_job_pod_desired_successful(meter: Meter) -> UpDownCounter: + """The desired number of successfully finished pods the job should be run with""" + return meter.create_up_down_counter( + name=K8S_JOB_POD_DESIRED_SUCCESSFUL, + description="The desired number of successfully finished pods the job should be run with.", + unit="{pod}", + ) + + +K8S_JOB_POD_FAILED: Final = "k8s.job.pod.failed" +""" +The number of pods which reached phase Failed for a job +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `failed` field of the +[K8s JobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobstatus-v1-batch). +""" + + +def create_k8s_job_pod_failed(meter: Meter) -> UpDownCounter: + """The number of pods which reached phase Failed for a job""" + return meter.create_up_down_counter( + name=K8S_JOB_POD_FAILED, + description="The number of pods which reached phase Failed for a job.", + unit="{pod}", + ) + + +K8S_JOB_POD_MAX_PARALLEL: Final = "k8s.job.pod.max_parallel" +""" +The max desired number of pods the job should run at any given time +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `parallelism` field of the +[K8s JobSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobspec-v1-batch). +""" + + +def create_k8s_job_pod_max_parallel(meter: Meter) -> UpDownCounter: + """The max desired number of pods the job should run at any given time""" + return meter.create_up_down_counter( + name=K8S_JOB_POD_MAX_PARALLEL, + description="The max desired number of pods the job should run at any given time.", + unit="{pod}", + ) + + +K8S_JOB_POD_SUCCESSFUL: Final = "k8s.job.pod.successful" +""" +The number of pods which reached phase Succeeded for a job +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `succeeded` field of the +[K8s JobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobstatus-v1-batch). +""" + + +def create_k8s_job_pod_successful(meter: Meter) -> UpDownCounter: + """The number of pods which reached phase Succeeded for a job""" + return meter.create_up_down_counter( + name=K8S_JOB_POD_SUCCESSFUL, + description="The number of pods which reached phase Succeeded for a job.", + unit="{pod}", + ) + + +K8S_JOB_SUCCESSFUL_PODS: Final = "k8s.job.successful_pods" +""" +Deprecated: Replaced by `k8s.job.pod.successful`. +""" + + +def create_k8s_job_successful_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.job.pod.successful` instead""" + return meter.create_up_down_counter( + name=K8S_JOB_SUCCESSFUL_PODS, + description="Deprecated, use `k8s.job.pod.successful` instead.", + unit="{pod}", + ) + + +K8S_NAMESPACE_PHASE: Final = "k8s.namespace.phase" +""" +Describes number of K8s namespaces that are currently in a given phase +Instrument: updowncounter +Unit: {namespace} +""" + + +def create_k8s_namespace_phase(meter: Meter) -> UpDownCounter: + """Describes number of K8s namespaces that are currently in a given phase""" + return meter.create_up_down_counter( + name=K8S_NAMESPACE_PHASE, + description="Describes number of K8s namespaces that are currently in a given phase.", + unit="{namespace}", + ) + + +K8S_NODE_ALLOCATABLE_CPU: Final = "k8s.node.allocatable.cpu" +""" +Deprecated: Replaced by `k8s.node.cpu.allocatable`. +""" + + +def create_k8s_node_allocatable_cpu(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.node.cpu.allocatable` instead""" + return meter.create_up_down_counter( + name=K8S_NODE_ALLOCATABLE_CPU, + description="Deprecated, use `k8s.node.cpu.allocatable` instead.", + unit="{cpu}", + ) + + +K8S_NODE_ALLOCATABLE_EPHEMERAL_STORAGE: Final = "k8s.node.allocatable.ephemeral_storage" +""" +Deprecated: Replaced by `k8s.node.ephemeral_storage.allocatable`. +""" + + +def create_k8s_node_allocatable_ephemeral_storage(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.node.ephemeral_storage.allocatable` instead""" + return meter.create_up_down_counter( + name=K8S_NODE_ALLOCATABLE_EPHEMERAL_STORAGE, + description="Deprecated, use `k8s.node.ephemeral_storage.allocatable` instead.", + unit="By", + ) + + +K8S_NODE_ALLOCATABLE_MEMORY: Final = "k8s.node.allocatable.memory" +""" +Deprecated: Replaced by `k8s.node.memory.allocatable`. +""" + + +def create_k8s_node_allocatable_memory(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.node.memory.allocatable` instead""" + return meter.create_up_down_counter( + name=K8S_NODE_ALLOCATABLE_MEMORY, + description="Deprecated, use `k8s.node.memory.allocatable` instead.", + unit="By", + ) + + +K8S_NODE_ALLOCATABLE_PODS: Final = "k8s.node.allocatable.pods" +""" +Deprecated: Replaced by `k8s.node.pod.allocatable`. +""" + + +def create_k8s_node_allocatable_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.node.pod.allocatable` instead""" + return meter.create_up_down_counter( + name=K8S_NODE_ALLOCATABLE_PODS, + description="Deprecated, use `k8s.node.pod.allocatable` instead.", + unit="{pod}", + ) + + +K8S_NODE_CONDITION_STATUS: Final = "k8s.node.condition.status" +""" +Describes the condition of a particular Node +Instrument: updowncounter +Unit: {node} +Note: All possible node condition pairs (type and status) will be reported at each time interval to avoid missing metrics. Condition pairs corresponding to the current conditions' statuses will be non-zero. +""" + + +def create_k8s_node_condition_status(meter: Meter) -> UpDownCounter: + """Describes the condition of a particular Node""" + return meter.create_up_down_counter( + name=K8S_NODE_CONDITION_STATUS, + description="Describes the condition of a particular Node.", + unit="{node}", + ) + + +K8S_NODE_CPU_ALLOCATABLE: Final = "k8s.node.cpu.allocatable" +""" +Amount of CPU allocatable on the node +Instrument: updowncounter +Unit: {cpu} +""" + + +def create_k8s_node_cpu_allocatable(meter: Meter) -> UpDownCounter: + """Amount of CPU allocatable on the node""" + return meter.create_up_down_counter( + name=K8S_NODE_CPU_ALLOCATABLE, + description="Amount of CPU allocatable on the node.", + unit="{cpu}", + ) + + +K8S_NODE_CPU_TIME: Final = "k8s.node.cpu.time" +""" +Total CPU time consumed +Instrument: counter +Unit: s +Note: Total CPU time consumed by the specific Node on all available CPU cores. +""" + + +def create_k8s_node_cpu_time(meter: Meter) -> Counter: + """Total CPU time consumed""" + return meter.create_counter( + name=K8S_NODE_CPU_TIME, + description="Total CPU time consumed.", + unit="s", + ) + + +K8S_NODE_CPU_USAGE: Final = "k8s.node.cpu.usage" +""" +Node's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs +Instrument: gauge +Unit: {cpu} +Note: CPU usage of the specific Node on all available CPU cores. It is calculated as the change in cumulative CPU time (k8s.node.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. +""" + + +def create_k8s_node_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Node's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs""" + return meter.create_observable_gauge( + name=K8S_NODE_CPU_USAGE, + callbacks=callbacks, + description="Node's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs.", + unit="{cpu}", + ) + + +K8S_NODE_EPHEMERAL_STORAGE_ALLOCATABLE: Final = "k8s.node.ephemeral_storage.allocatable" +""" +Amount of ephemeral-storage allocatable on the node +Instrument: updowncounter +Unit: By +""" + + +def create_k8s_node_ephemeral_storage_allocatable(meter: Meter) -> UpDownCounter: + """Amount of ephemeral-storage allocatable on the node""" + return meter.create_up_down_counter( + name=K8S_NODE_EPHEMERAL_STORAGE_ALLOCATABLE, + description="Amount of ephemeral-storage allocatable on the node.", + unit="By", + ) + + +K8S_NODE_FILESYSTEM_AVAILABLE: Final = "k8s.node.filesystem.available" +""" +Node filesystem available bytes +Instrument: updowncounter +Unit: By +Note: This metric is derived from the +[FsStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) +of the Kubelet's stats API. +""" + + +def create_k8s_node_filesystem_available(meter: Meter) -> UpDownCounter: + """Node filesystem available bytes""" + return meter.create_up_down_counter( + name=K8S_NODE_FILESYSTEM_AVAILABLE, + description="Node filesystem available bytes.", + unit="By", + ) + + +K8S_NODE_FILESYSTEM_CAPACITY: Final = "k8s.node.filesystem.capacity" +""" +Node filesystem capacity +Instrument: updowncounter +Unit: By +Note: This metric is derived from the +[FsStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) +of the Kubelet's stats API. +""" + + +def create_k8s_node_filesystem_capacity(meter: Meter) -> UpDownCounter: + """Node filesystem capacity""" + return meter.create_up_down_counter( + name=K8S_NODE_FILESYSTEM_CAPACITY, + description="Node filesystem capacity.", + unit="By", + ) + + +K8S_NODE_FILESYSTEM_INODE_COUNT: Final = "k8s.node.filesystem.inode.count" +""" +The total inodes in the node's root filesystem +Instrument: updowncounter +Unit: {inode} +Note: This metric is derived from the +[FsStats.Inodes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) +of the Kubelet's stats API. +""" + + +def create_k8s_node_filesystem_inode_count(meter: Meter) -> UpDownCounter: + """The total inodes in the node's root filesystem""" + return meter.create_up_down_counter( + name=K8S_NODE_FILESYSTEM_INODE_COUNT, + description="The total inodes in the node's root filesystem.", + unit="{inode}", + ) + + +K8S_NODE_FILESYSTEM_INODE_FREE: Final = "k8s.node.filesystem.inode.free" +""" +The free inodes in the node's root filesystem +Instrument: updowncounter +Unit: {inode} +Note: This metric is derived from the +[FsStats.InodesFree](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) +of the Kubelet's stats API. +""" + + +def create_k8s_node_filesystem_inode_free(meter: Meter) -> UpDownCounter: + """The free inodes in the node's root filesystem""" + return meter.create_up_down_counter( + name=K8S_NODE_FILESYSTEM_INODE_FREE, + description="The free inodes in the node's root filesystem.", + unit="{inode}", + ) + + +K8S_NODE_FILESYSTEM_USAGE: Final = "k8s.node.filesystem.usage" +""" +Node filesystem usage +Instrument: updowncounter +Unit: By +Note: This may not equal capacity - available. + +This metric is derived from the +[FsStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) +of the Kubelet's stats API. +""" + + +def create_k8s_node_filesystem_usage(meter: Meter) -> UpDownCounter: + """Node filesystem usage""" + return meter.create_up_down_counter( + name=K8S_NODE_FILESYSTEM_USAGE, + description="Node filesystem usage.", + unit="By", + ) + + +K8S_NODE_MEMORY_ALLOCATABLE: Final = "k8s.node.memory.allocatable" +""" +Amount of memory allocatable on the node +Instrument: updowncounter +Unit: By +""" + + +def create_k8s_node_memory_allocatable(meter: Meter) -> UpDownCounter: + """Amount of memory allocatable on the node""" + return meter.create_up_down_counter( + name=K8S_NODE_MEMORY_ALLOCATABLE, + description="Amount of memory allocatable on the node.", + unit="By", + ) + + +K8S_NODE_MEMORY_AVAILABLE: Final = "k8s.node.memory.available" +""" +Node memory available +Instrument: updowncounter +Unit: By +Note: Available memory for use. This is defined as the memory limit - workingSetBytes. If memory limit is undefined, the available bytes is omitted. +This metric is derived from the [MemoryStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. +""" + + +def create_k8s_node_memory_available(meter: Meter) -> UpDownCounter: + """Node memory available""" + return meter.create_up_down_counter( + name=K8S_NODE_MEMORY_AVAILABLE, + description="Node memory available.", + unit="By", + ) + + +K8S_NODE_MEMORY_PAGING_FAULTS: Final = "k8s.node.memory.paging.faults" +""" +Deprecated: Replaced by `k8s.node.paging.faults`. +""" + + +def create_k8s_node_memory_paging_faults(meter: Meter) -> Counter: + """Deprecated, use `k8s.node.paging.faults` instead""" + return meter.create_counter( + name=K8S_NODE_MEMORY_PAGING_FAULTS, + description="Deprecated, use `k8s.node.paging.faults` instead.", + unit="{fault}", + ) + + +K8S_NODE_MEMORY_RSS: Final = "k8s.node.memory.rss" +""" +Node memory RSS +Instrument: updowncounter +Unit: By +Note: The amount of anonymous and swap cache memory (includes transparent hugepages). +This metric is derived from the [MemoryStats.RSSBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. +""" + + +def create_k8s_node_memory_rss(meter: Meter) -> UpDownCounter: + """Node memory RSS""" + return meter.create_up_down_counter( + name=K8S_NODE_MEMORY_RSS, + description="Node memory RSS.", + unit="By", + ) + + +K8S_NODE_MEMORY_USAGE: Final = "k8s.node.memory.usage" +""" +Memory usage of the Node +Instrument: updowncounter +Unit: By +Note: Total memory in use. This includes all memory regardless of when it was accessed. +This metric is derived from the [MemoryStats.UsageBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. +""" + + +def create_k8s_node_memory_usage(meter: Meter) -> UpDownCounter: + """Memory usage of the Node""" + return meter.create_up_down_counter( + name=K8S_NODE_MEMORY_USAGE, + description="Memory usage of the Node.", + unit="By", + ) + + +K8S_NODE_MEMORY_WORKING_SET: Final = "k8s.node.memory.working_set" +""" +Node memory working set +Instrument: updowncounter +Unit: By +Note: The amount of working set memory. This includes recently accessed memory, dirty memory, and kernel memory. WorkingSetBytes is <= UsageBytes. +This metric is derived from the [MemoryStats.WorkingSetBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. +""" + + +def create_k8s_node_memory_working_set(meter: Meter) -> UpDownCounter: + """Node memory working set""" + return meter.create_up_down_counter( + name=K8S_NODE_MEMORY_WORKING_SET, + description="Node memory working set.", + unit="By", + ) + + +K8S_NODE_NETWORK_ERRORS: Final = "k8s.node.network.errors" +""" +Node network errors +Instrument: counter +Unit: {error} +""" + + +def create_k8s_node_network_errors(meter: Meter) -> Counter: + """Node network errors""" + return meter.create_counter( + name=K8S_NODE_NETWORK_ERRORS, + description="Node network errors.", + unit="{error}", + ) + + +K8S_NODE_NETWORK_IO: Final = "k8s.node.network.io" +""" +Network bytes for the Node +Instrument: counter +Unit: By +""" + + +def create_k8s_node_network_io(meter: Meter) -> Counter: + """Network bytes for the Node""" + return meter.create_counter( + name=K8S_NODE_NETWORK_IO, + description="Network bytes for the Node.", + unit="By", + ) + + +K8S_NODE_PAGING_FAULTS: Final = "k8s.node.paging.faults" +""" +Node memory paging faults +Instrument: counter +Unit: {fault} +Note: Cumulative number of major/minor page faults. +This metric is derived from the [MemoryStats.PageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) and [MemoryStats.MajorPageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) fields of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. +""" + + +def create_k8s_node_paging_faults(meter: Meter) -> Counter: + """Node memory paging faults""" + return meter.create_counter( + name=K8S_NODE_PAGING_FAULTS, + description="Node memory paging faults.", + unit="{fault}", + ) + + +K8S_NODE_POD_ALLOCATABLE: Final = "k8s.node.pod.allocatable" +""" +Amount of pods allocatable on the node +Instrument: updowncounter +Unit: {pod} +""" + + +def create_k8s_node_pod_allocatable(meter: Meter) -> UpDownCounter: + """Amount of pods allocatable on the node""" + return meter.create_up_down_counter( + name=K8S_NODE_POD_ALLOCATABLE, + description="Amount of pods allocatable on the node.", + unit="{pod}", + ) + + +K8S_NODE_SYSTEM_CONTAINER_CPU_TIME: Final = "k8s.node.system_container.cpu.time" +""" +Node's system container CPU time +Instrument: counter +Unit: s +Note: This metric is derived from the [CPUStats.UsageCoreNanoSeconds](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L236) field of the [ContainerStats](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L157C6-L157C20) of [Node.SystemContainers](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L40) of the Kubelet's stats API. +""" + + +def create_k8s_node_system_container_cpu_time(meter: Meter) -> Counter: + """Node's system container CPU time""" + return meter.create_counter( + name=K8S_NODE_SYSTEM_CONTAINER_CPU_TIME, + description="Node's system container CPU time.", + unit="s", + ) + + +K8S_NODE_SYSTEM_CONTAINER_CPU_USAGE: Final = "k8s.node.system_container.cpu.usage" +""" +Node's system container CPU usage, measured in CPUs +Instrument: gauge +Unit: {cpu} +Note: CPU usage of the specific System Container on all available CPU cores. It is calculated as the change in cumulative CPU time (k8s.node.system_container.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. +""" + + +def create_k8s_node_system_container_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Node's system container CPU usage, measured in CPUs""" + return meter.create_observable_gauge( + name=K8S_NODE_SYSTEM_CONTAINER_CPU_USAGE, + callbacks=callbacks, + description="Node's system container CPU usage, measured in CPUs.", + unit="{cpu}", + ) + + +K8S_NODE_SYSTEM_CONTAINER_MEMORY_USAGE: Final = "k8s.node.system_container.memory.usage" +""" +Node's system container memory usage +Instrument: updowncounter +Unit: By +Note: This metric is derived from the [MemoryStats.UsageBytes](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L252) field of the [ContainerStats](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L157C6-L157C20) of [Node.SystemContainers](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L40) of the Kubelet's stats API. +""" + + +def create_k8s_node_system_container_memory_usage(meter: Meter) -> UpDownCounter: + """Node's system container memory usage""" + return meter.create_up_down_counter( + name=K8S_NODE_SYSTEM_CONTAINER_MEMORY_USAGE, + description="Node's system container memory usage.", + unit="By", + ) + + +K8S_NODE_SYSTEM_CONTAINER_MEMORY_WORKING_SET: Final = "k8s.node.system_container.memory.working_set" +""" +The amount of working set memory +Instrument: updowncounter +Unit: By +Note: This metric is derived from the [MemoryStats.WorkingSetBytes](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L256) field of the [ContainerStats](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L157C6-L157C20) of [Node.SystemContainers](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L40) of the Kubelet's stats API. +""" + + +def create_k8s_node_system_container_memory_working_set(meter: Meter) -> UpDownCounter: + """The amount of working set memory""" + return meter.create_up_down_counter( + name=K8S_NODE_SYSTEM_CONTAINER_MEMORY_WORKING_SET, + description="The amount of working set memory.", + unit="By", + ) + + +K8S_NODE_UPTIME: Final = "k8s.node.uptime" +""" +The time the Node has been running +Instrument: gauge +Unit: s +Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. +The actual accuracy would depend on the instrumentation and operating system. +""" + + +def create_k8s_node_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The time the Node has been running""" + return meter.create_observable_gauge( + name=K8S_NODE_UPTIME, + callbacks=callbacks, + description="The time the Node has been running.", + unit="s", + ) + + +K8S_PERSISTENTVOLUME_STATUS_PHASE: Final = "k8s.persistentvolume.status.phase" +""" +Number of PersistentVolumes in a given phase +Instrument: updowncounter +Unit: {persistentvolume} +Note: All possible phases should be reported at each interval to avoid gaps in the time series. +This metric is derived from the `.status.phase` field of the +[K8s PersistentVolumeStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeStatus). +""" + + +def create_k8s_persistentvolume_status_phase(meter: Meter) -> UpDownCounter: + """Number of PersistentVolumes in a given phase""" + return meter.create_up_down_counter( + name=K8S_PERSISTENTVOLUME_STATUS_PHASE, + description="Number of PersistentVolumes in a given phase.", + unit="{persistentvolume}", + ) + + +K8S_PERSISTENTVOLUME_STORAGE_CAPACITY: Final = "k8s.persistentvolume.storage.capacity" +""" +The storage capacity of the PersistentVolume +Instrument: updowncounter +Unit: By +Note: This metric is derived from the `.spec.capacity.storage` field of the [K8s PersistentVolumeSpec](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec). +""" + + +def create_k8s_persistentvolume_storage_capacity(meter: Meter) -> UpDownCounter: + """The storage capacity of the PersistentVolume""" + return meter.create_up_down_counter( + name=K8S_PERSISTENTVOLUME_STORAGE_CAPACITY, + description="The storage capacity of the PersistentVolume.", + unit="By", + ) + + +K8S_PERSISTENTVOLUMECLAIM_STATUS_PHASE: Final = "k8s.persistentvolumeclaim.status.phase" +""" +Number of PersistentVolumeClaims in a given phase +Instrument: updowncounter +Unit: {persistentvolumeclaim} +Note: All possible phases should be reported at each interval to avoid gaps in the time series. +This metric is derived from the `.status.phase` field of the +[K8s PersistentVolumeClaimStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus). +""" + + +def create_k8s_persistentvolumeclaim_status_phase(meter: Meter) -> UpDownCounter: + """Number of PersistentVolumeClaims in a given phase""" + return meter.create_up_down_counter( + name=K8S_PERSISTENTVOLUMECLAIM_STATUS_PHASE, + description="Number of PersistentVolumeClaims in a given phase.", + unit="{persistentvolumeclaim}", + ) + + +K8S_PERSISTENTVOLUMECLAIM_STORAGE_CAPACITY: Final = "k8s.persistentvolumeclaim.storage.capacity" +""" +The actual storage capacity provisioned for the PersistentVolumeClaim +Instrument: updowncounter +Unit: By +Note: Only available when the PVC is bound. May differ from the requested capacity due to provisioner rounding. +This metric is derived from the `.status.capacity.storage` field of the +[K8s PersistentVolumeClaimStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus). +""" + + +def create_k8s_persistentvolumeclaim_storage_capacity(meter: Meter) -> UpDownCounter: + """The actual storage capacity provisioned for the PersistentVolumeClaim""" + return meter.create_up_down_counter( + name=K8S_PERSISTENTVOLUMECLAIM_STORAGE_CAPACITY, + description="The actual storage capacity provisioned for the PersistentVolumeClaim.", + unit="By", + ) + + +K8S_PERSISTENTVOLUMECLAIM_STORAGE_REQUEST: Final = "k8s.persistentvolumeclaim.storage.request" +""" +The storage requested by the PersistentVolumeClaim +Instrument: updowncounter +Unit: By +Note: This metric is derived from the `.spec.resources.requests.storage` field of the [K8s PersistentVolumeClaimSpec](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimSpec). +""" + + +def create_k8s_persistentvolumeclaim_storage_request(meter: Meter) -> UpDownCounter: + """The storage requested by the PersistentVolumeClaim""" + return meter.create_up_down_counter( + name=K8S_PERSISTENTVOLUMECLAIM_STORAGE_REQUEST, + description="The storage requested by the PersistentVolumeClaim.", + unit="By", + ) + + +K8S_POD_CPU_TIME: Final = "k8s.pod.cpu.time" +""" +Total CPU time consumed +Instrument: counter +Unit: s +Note: Total CPU time consumed by the specific Pod on all available CPU cores. +""" + + +def create_k8s_pod_cpu_time(meter: Meter) -> Counter: + """Total CPU time consumed""" + return meter.create_counter( + name=K8S_POD_CPU_TIME, + description="Total CPU time consumed.", + unit="s", + ) + + +K8S_POD_CPU_USAGE: Final = "k8s.pod.cpu.usage" +""" +Pod's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs +Instrument: gauge +Unit: {cpu} +Note: CPU usage of the specific Pod on all available CPU cores. It is calculated as the change in cumulative CPU time (k8s.pod.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. +""" + + +def create_k8s_pod_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Pod's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs""" + return meter.create_observable_gauge( + name=K8S_POD_CPU_USAGE, + callbacks=callbacks, + description="Pod's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs.", + unit="{cpu}", + ) + + +K8S_POD_FILESYSTEM_AVAILABLE: Final = "k8s.pod.filesystem.available" +""" +Pod filesystem available bytes +Instrument: updowncounter +Unit: By +Note: This metric is derived from the +[FsStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [PodStats.EphemeralStorage](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) +of the Kubelet's stats API. +""" + + +def create_k8s_pod_filesystem_available(meter: Meter) -> UpDownCounter: + """Pod filesystem available bytes""" + return meter.create_up_down_counter( + name=K8S_POD_FILESYSTEM_AVAILABLE, + description="Pod filesystem available bytes.", + unit="By", + ) + + +K8S_POD_FILESYSTEM_CAPACITY: Final = "k8s.pod.filesystem.capacity" +""" +Pod filesystem capacity +Instrument: updowncounter +Unit: By +Note: This metric is derived from the +[FsStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [PodStats.EphemeralStorage](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) +of the Kubelet's stats API. +""" + + +def create_k8s_pod_filesystem_capacity(meter: Meter) -> UpDownCounter: + """Pod filesystem capacity""" + return meter.create_up_down_counter( + name=K8S_POD_FILESYSTEM_CAPACITY, + description="Pod filesystem capacity.", + unit="By", + ) + + +K8S_POD_FILESYSTEM_USAGE: Final = "k8s.pod.filesystem.usage" +""" +Pod filesystem usage +Instrument: updowncounter +Unit: By +Note: This may not equal capacity - available. + +This metric is derived from the +[FsStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field +of the [PodStats.EphemeralStorage](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) +of the Kubelet's stats API. +""" + + +def create_k8s_pod_filesystem_usage(meter: Meter) -> UpDownCounter: + """Pod filesystem usage""" + return meter.create_up_down_counter( + name=K8S_POD_FILESYSTEM_USAGE, + description="Pod filesystem usage.", + unit="By", + ) + + +K8S_POD_MEMORY_AVAILABLE: Final = "k8s.pod.memory.available" +""" +Pod memory available +Instrument: updowncounter +Unit: By +Note: Available memory for use. This is defined as the memory limit - workingSetBytes. If memory limit is undefined, the available bytes is omitted. +This metric is derived from the [MemoryStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. +""" + + +def create_k8s_pod_memory_available(meter: Meter) -> UpDownCounter: + """Pod memory available""" + return meter.create_up_down_counter( + name=K8S_POD_MEMORY_AVAILABLE, + description="Pod memory available.", + unit="By", + ) + + +K8S_POD_MEMORY_PAGING_FAULTS: Final = "k8s.pod.memory.paging.faults" +""" +Deprecated: Replaced by `k8s.pod.paging.faults`. +""" + + +def create_k8s_pod_memory_paging_faults(meter: Meter) -> Counter: + """Deprecated, use `k8s.pod.paging.faults` instead""" + return meter.create_counter( + name=K8S_POD_MEMORY_PAGING_FAULTS, + description="Deprecated, use `k8s.pod.paging.faults` instead.", + unit="{fault}", + ) + + +K8S_POD_MEMORY_RSS: Final = "k8s.pod.memory.rss" +""" +Pod memory RSS +Instrument: updowncounter +Unit: By +Note: The amount of anonymous and swap cache memory (includes transparent hugepages). +This metric is derived from the [MemoryStats.RSSBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. +""" + + +def create_k8s_pod_memory_rss(meter: Meter) -> UpDownCounter: + """Pod memory RSS""" + return meter.create_up_down_counter( + name=K8S_POD_MEMORY_RSS, + description="Pod memory RSS.", + unit="By", + ) + + +K8S_POD_MEMORY_USAGE: Final = "k8s.pod.memory.usage" +""" +Memory usage of the Pod +Instrument: updowncounter +Unit: By +Note: Total memory in use. This includes all memory regardless of when it was accessed. +This metric is derived from the [MemoryStats.UsageBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. +""" + + +def create_k8s_pod_memory_usage(meter: Meter) -> UpDownCounter: + """Memory usage of the Pod""" + return meter.create_up_down_counter( + name=K8S_POD_MEMORY_USAGE, + description="Memory usage of the Pod.", + unit="By", + ) + + +K8S_POD_MEMORY_WORKING_SET: Final = "k8s.pod.memory.working_set" +""" +Pod memory working set +Instrument: updowncounter +Unit: By +Note: The amount of working set memory. This includes recently accessed memory, dirty memory, and kernel memory. WorkingSetBytes is <= UsageBytes. +This metric is derived from the [MemoryStats.WorkingSetBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. +""" + + +def create_k8s_pod_memory_working_set(meter: Meter) -> UpDownCounter: + """Pod memory working set""" + return meter.create_up_down_counter( + name=K8S_POD_MEMORY_WORKING_SET, + description="Pod memory working set.", + unit="By", + ) + + +K8S_POD_NETWORK_ERRORS: Final = "k8s.pod.network.errors" +""" +Pod network errors +Instrument: counter +Unit: {error} +""" + + +def create_k8s_pod_network_errors(meter: Meter) -> Counter: + """Pod network errors""" + return meter.create_counter( + name=K8S_POD_NETWORK_ERRORS, + description="Pod network errors.", + unit="{error}", + ) + + +K8S_POD_NETWORK_IO: Final = "k8s.pod.network.io" +""" +Network bytes for the Pod +Instrument: counter +Unit: By +""" + + +def create_k8s_pod_network_io(meter: Meter) -> Counter: + """Network bytes for the Pod""" + return meter.create_counter( + name=K8S_POD_NETWORK_IO, + description="Network bytes for the Pod.", + unit="By", + ) + + +K8S_POD_PAGING_FAULTS: Final = "k8s.pod.paging.faults" +""" +Pod memory paging faults +Instrument: counter +Unit: {fault} +Note: Cumulative number of major/minor page faults. +This metric is derived from the [MemoryStats.PageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) and [MemoryStats.MajorPageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. +""" + + +def create_k8s_pod_paging_faults(meter: Meter) -> Counter: + """Pod memory paging faults""" + return meter.create_counter( + name=K8S_POD_PAGING_FAULTS, + description="Pod memory paging faults.", + unit="{fault}", + ) + + +K8S_POD_STATUS_PHASE: Final = "k8s.pod.status.phase" +""" +Describes number of K8s Pods that are currently in a given phase +Instrument: updowncounter +Unit: {pod} +Note: All possible pod phases will be reported at each time interval to avoid missing metrics. +Only the value corresponding to the current phase will be non-zero. +""" + + +def create_k8s_pod_status_phase(meter: Meter) -> UpDownCounter: + """Describes number of K8s Pods that are currently in a given phase""" + return meter.create_up_down_counter( + name=K8S_POD_STATUS_PHASE, + description="Describes number of K8s Pods that are currently in a given phase.", + unit="{pod}", + ) + + +K8S_POD_STATUS_REASON: Final = "k8s.pod.status.reason" +""" +Describes the number of K8s Pods that are currently in a state for a given reason +Instrument: updowncounter +Unit: {pod} +Note: All possible pod status reasons will be reported at each time interval to avoid missing metrics. +Only the value corresponding to the current reason will be non-zero. +""" + + +def create_k8s_pod_status_reason(meter: Meter) -> UpDownCounter: + """Describes the number of K8s Pods that are currently in a state for a given reason""" + return meter.create_up_down_counter( + name=K8S_POD_STATUS_REASON, + description="Describes the number of K8s Pods that are currently in a state for a given reason.", + unit="{pod}", + ) + + +K8S_POD_UPTIME: Final = "k8s.pod.uptime" +""" +The time the Pod has been running +Instrument: gauge +Unit: s +Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. +The actual accuracy would depend on the instrumentation and operating system. +""" + + +def create_k8s_pod_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The time the Pod has been running""" + return meter.create_observable_gauge( + name=K8S_POD_UPTIME, + callbacks=callbacks, + description="The time the Pod has been running.", + unit="s", + ) + + +K8S_POD_VOLUME_AVAILABLE: Final = "k8s.pod.volume.available" +""" +Pod volume storage space available +Instrument: updowncounter +Unit: By +Note: This metric is derived from the +[VolumeStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field +of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the +Kubelet's stats API. +""" + + +def create_k8s_pod_volume_available(meter: Meter) -> UpDownCounter: + """Pod volume storage space available""" + return meter.create_up_down_counter( + name=K8S_POD_VOLUME_AVAILABLE, + description="Pod volume storage space available.", + unit="By", + ) + + +K8S_POD_VOLUME_CAPACITY: Final = "k8s.pod.volume.capacity" +""" +Pod volume total capacity +Instrument: updowncounter +Unit: By +Note: This metric is derived from the +[VolumeStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field +of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the +Kubelet's stats API. +""" + + +def create_k8s_pod_volume_capacity(meter: Meter) -> UpDownCounter: + """Pod volume total capacity""" + return meter.create_up_down_counter( + name=K8S_POD_VOLUME_CAPACITY, + description="Pod volume total capacity.", + unit="By", + ) + + +K8S_POD_VOLUME_INODE_COUNT: Final = "k8s.pod.volume.inode.count" +""" +The total inodes in the filesystem of the Pod's volume +Instrument: updowncounter +Unit: {inode} +Note: This metric is derived from the +[VolumeStats.Inodes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field +of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the +Kubelet's stats API. +""" + + +def create_k8s_pod_volume_inode_count(meter: Meter) -> UpDownCounter: + """The total inodes in the filesystem of the Pod's volume""" + return meter.create_up_down_counter( + name=K8S_POD_VOLUME_INODE_COUNT, + description="The total inodes in the filesystem of the Pod's volume.", + unit="{inode}", + ) + + +K8S_POD_VOLUME_INODE_FREE: Final = "k8s.pod.volume.inode.free" +""" +The free inodes in the filesystem of the Pod's volume +Instrument: updowncounter +Unit: {inode} +Note: This metric is derived from the +[VolumeStats.InodesFree](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field +of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the +Kubelet's stats API. +""" + + +def create_k8s_pod_volume_inode_free(meter: Meter) -> UpDownCounter: + """The free inodes in the filesystem of the Pod's volume""" + return meter.create_up_down_counter( + name=K8S_POD_VOLUME_INODE_FREE, + description="The free inodes in the filesystem of the Pod's volume.", + unit="{inode}", + ) + + +K8S_POD_VOLUME_INODE_USED: Final = "k8s.pod.volume.inode.used" +""" +The inodes used by the filesystem of the Pod's volume +Instrument: updowncounter +Unit: {inode} +Note: This metric is derived from the +[VolumeStats.InodesUsed](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field +of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the +Kubelet's stats API. + +This may not be equal to `inodes - free` because filesystem may share inodes with other filesystems. +""" + + +def create_k8s_pod_volume_inode_used(meter: Meter) -> UpDownCounter: + """The inodes used by the filesystem of the Pod's volume""" + return meter.create_up_down_counter( + name=K8S_POD_VOLUME_INODE_USED, + description="The inodes used by the filesystem of the Pod's volume.", + unit="{inode}", + ) + + +K8S_POD_VOLUME_USAGE: Final = "k8s.pod.volume.usage" +""" +Pod volume usage +Instrument: updowncounter +Unit: By +Note: This may not equal capacity - available. + +This metric is derived from the +[VolumeStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field +of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the +Kubelet's stats API. +""" + + +def create_k8s_pod_volume_usage(meter: Meter) -> UpDownCounter: + """Pod volume usage""" + return meter.create_up_down_counter( + name=K8S_POD_VOLUME_USAGE, + description="Pod volume usage.", + unit="By", + ) + + +K8S_REPLICASET_AVAILABLE_PODS: Final = "k8s.replicaset.available_pods" +""" +Deprecated: Replaced by `k8s.replicaset.pod.available`. +""" + + +def create_k8s_replicaset_available_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.replicaset.pod.available` instead""" + return meter.create_up_down_counter( + name=K8S_REPLICASET_AVAILABLE_PODS, + description="Deprecated, use `k8s.replicaset.pod.available` instead.", + unit="{pod}", + ) + + +K8S_REPLICASET_DESIRED_PODS: Final = "k8s.replicaset.desired_pods" +""" +Deprecated: Replaced by `k8s.replicaset.pod.desired`. +""" + + +def create_k8s_replicaset_desired_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.replicaset.pod.desired` instead""" + return meter.create_up_down_counter( + name=K8S_REPLICASET_DESIRED_PODS, + description="Deprecated, use `k8s.replicaset.pod.desired` instead.", + unit="{pod}", + ) + + +K8S_REPLICASET_POD_AVAILABLE: Final = "k8s.replicaset.pod.available" +""" +Total number of available replica pods (ready for at least minReadySeconds) targeted by this replicaset +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `availableReplicas` field of the +[K8s ReplicaSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicasetstatus-v1-apps). +""" + + +def create_k8s_replicaset_pod_available(meter: Meter) -> UpDownCounter: + """Total number of available replica pods (ready for at least minReadySeconds) targeted by this replicaset""" + return meter.create_up_down_counter( + name=K8S_REPLICASET_POD_AVAILABLE, + description="Total number of available replica pods (ready for at least minReadySeconds) targeted by this replicaset.", + unit="{pod}", + ) + + +K8S_REPLICASET_POD_DESIRED: Final = "k8s.replicaset.pod.desired" +""" +Number of desired replica pods in this replicaset +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `replicas` field of the +[K8s ReplicaSetSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicasetspec-v1-apps). +""" + + +def create_k8s_replicaset_pod_desired(meter: Meter) -> UpDownCounter: + """Number of desired replica pods in this replicaset""" + return meter.create_up_down_counter( + name=K8S_REPLICASET_POD_DESIRED, + description="Number of desired replica pods in this replicaset.", + unit="{pod}", + ) + + +K8S_REPLICATION_CONTROLLER_AVAILABLE_PODS: Final = "k8s.replication_controller.available_pods" +""" +Deprecated: Replaced by `k8s.replicationcontroller.pod.available`. +""" + + +def create_k8s_replication_controller_available_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.replicationcontroller.pod.available` instead""" + return meter.create_up_down_counter( + name=K8S_REPLICATION_CONTROLLER_AVAILABLE_PODS, + description="Deprecated, use `k8s.replicationcontroller.pod.available` instead.", + unit="{pod}", + ) + + +K8S_REPLICATION_CONTROLLER_DESIRED_PODS: Final = "k8s.replication_controller.desired_pods" +""" +Deprecated: Replaced by `k8s.replicationcontroller.pod.desired`. +""" + + +def create_k8s_replication_controller_desired_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.replicationcontroller.pod.desired` instead""" + return meter.create_up_down_counter( + name=K8S_REPLICATION_CONTROLLER_DESIRED_PODS, + description="Deprecated, use `k8s.replicationcontroller.pod.desired` instead.", + unit="{pod}", + ) + + +K8S_REPLICATIONCONTROLLER_AVAILABLE_PODS: Final = "k8s.replicationcontroller.available_pods" +""" +Deprecated: Replaced by `k8s.replicationcontroller.pod.available`. +""" + + +def create_k8s_replicationcontroller_available_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.replicationcontroller.pod.available` instead""" + return meter.create_up_down_counter( + name=K8S_REPLICATIONCONTROLLER_AVAILABLE_PODS, + description="Deprecated, use `k8s.replicationcontroller.pod.available` instead.", + unit="{pod}", + ) + + +K8S_REPLICATIONCONTROLLER_DESIRED_PODS: Final = "k8s.replicationcontroller.desired_pods" +""" +Deprecated: Replaced by `k8s.replicationcontroller.pod.desired`. +""" + + +def create_k8s_replicationcontroller_desired_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.replicationcontroller.pod.desired` instead""" + return meter.create_up_down_counter( + name=K8S_REPLICATIONCONTROLLER_DESIRED_PODS, + description="Deprecated, use `k8s.replicationcontroller.pod.desired` instead.", + unit="{pod}", + ) + + +K8S_REPLICATIONCONTROLLER_POD_AVAILABLE: Final = "k8s.replicationcontroller.pod.available" +""" +Total number of available replica pods (ready for at least minReadySeconds) targeted by this replication controller +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `availableReplicas` field of the +[K8s ReplicationControllerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicationcontrollerstatus-v1-core). +""" + + +def create_k8s_replicationcontroller_pod_available(meter: Meter) -> UpDownCounter: + """Total number of available replica pods (ready for at least minReadySeconds) targeted by this replication controller""" + return meter.create_up_down_counter( + name=K8S_REPLICATIONCONTROLLER_POD_AVAILABLE, + description="Total number of available replica pods (ready for at least minReadySeconds) targeted by this replication controller.", + unit="{pod}", + ) + + +K8S_REPLICATIONCONTROLLER_POD_DESIRED: Final = "k8s.replicationcontroller.pod.desired" +""" +Number of desired replica pods in this replication controller +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `replicas` field of the +[K8s ReplicationControllerSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicationcontrollerspec-v1-core). +""" + + +def create_k8s_replicationcontroller_pod_desired(meter: Meter) -> UpDownCounter: + """Number of desired replica pods in this replication controller""" + return meter.create_up_down_counter( + name=K8S_REPLICATIONCONTROLLER_POD_DESIRED, + description="Number of desired replica pods in this replication controller.", + unit="{pod}", + ) + + +K8S_RESOURCEQUOTA_CPU_LIMIT_HARD: Final = "k8s.resourcequota.cpu.limit.hard" +""" +The CPU limits in a specific namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_cpu_limit_hard(meter: Meter) -> UpDownCounter: + """The CPU limits in a specific namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_CPU_LIMIT_HARD, + description="The CPU limits in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="{cpu}", + ) + + +K8S_RESOURCEQUOTA_CPU_LIMIT_USED: Final = "k8s.resourcequota.cpu.limit.used" +""" +The CPU limits in a specific namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_cpu_limit_used(meter: Meter) -> UpDownCounter: + """The CPU limits in a specific namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_CPU_LIMIT_USED, + description="The CPU limits in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="{cpu}", + ) + + +K8S_RESOURCEQUOTA_CPU_REQUEST_HARD: Final = "k8s.resourcequota.cpu.request.hard" +""" +The CPU requests in a specific namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_cpu_request_hard(meter: Meter) -> UpDownCounter: + """The CPU requests in a specific namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_CPU_REQUEST_HARD, + description="The CPU requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="{cpu}", + ) + + +K8S_RESOURCEQUOTA_CPU_REQUEST_USED: Final = "k8s.resourcequota.cpu.request.used" +""" +The CPU requests in a specific namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_cpu_request_used(meter: Meter) -> UpDownCounter: + """The CPU requests in a specific namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_CPU_REQUEST_USED, + description="The CPU requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="{cpu}", + ) + + +K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD: Final = "k8s.resourcequota.ephemeral_storage.limit.hard" +""" +The sum of local ephemeral storage limits in the namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_ephemeral_storage_limit_hard(meter: Meter) -> UpDownCounter: + """The sum of local ephemeral storage limits in the namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD, + description="The sum of local ephemeral storage limits in the namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_USED: Final = "k8s.resourcequota.ephemeral_storage.limit.used" +""" +The sum of local ephemeral storage limits in the namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_ephemeral_storage_limit_used(meter: Meter) -> UpDownCounter: + """The sum of local ephemeral storage limits in the namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_USED, + description="The sum of local ephemeral storage limits in the namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD: Final = "k8s.resourcequota.ephemeral_storage.request.hard" +""" +The sum of local ephemeral storage requests in the namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_ephemeral_storage_request_hard(meter: Meter) -> UpDownCounter: + """The sum of local ephemeral storage requests in the namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD, + description="The sum of local ephemeral storage requests in the namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_USED: Final = "k8s.resourcequota.ephemeral_storage.request.used" +""" +The sum of local ephemeral storage requests in the namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_ephemeral_storage_request_used(meter: Meter) -> UpDownCounter: + """The sum of local ephemeral storage requests in the namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_USED, + description="The sum of local ephemeral storage requests in the namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_HARD: Final = "k8s.resourcequota.hugepage_count.request.hard" +""" +The huge page requests in a specific namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: {hugepage} +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_hugepage_count_request_hard(meter: Meter) -> UpDownCounter: + """The huge page requests in a specific namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_HARD, + description="The huge page requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="{hugepage}", + ) + + +K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_USED: Final = "k8s.resourcequota.hugepage_count.request.used" +""" +The huge page requests in a specific namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: {hugepage} +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_hugepage_count_request_used(meter: Meter) -> UpDownCounter: + """The huge page requests in a specific namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_USED, + description="The huge page requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="{hugepage}", + ) + + +K8S_RESOURCEQUOTA_MEMORY_LIMIT_HARD: Final = "k8s.resourcequota.memory.limit.hard" +""" +The memory limits in a specific namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_memory_limit_hard(meter: Meter) -> UpDownCounter: + """The memory limits in a specific namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_MEMORY_LIMIT_HARD, + description="The memory limits in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_MEMORY_LIMIT_USED: Final = "k8s.resourcequota.memory.limit.used" +""" +The memory limits in a specific namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_memory_limit_used(meter: Meter) -> UpDownCounter: + """The memory limits in a specific namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_MEMORY_LIMIT_USED, + description="The memory limits in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_MEMORY_REQUEST_HARD: Final = "k8s.resourcequota.memory.request.hard" +""" +The memory requests in a specific namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_memory_request_hard(meter: Meter) -> UpDownCounter: + """The memory requests in a specific namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_MEMORY_REQUEST_HARD, + description="The memory requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_MEMORY_REQUEST_USED: Final = "k8s.resourcequota.memory.request.used" +""" +The memory requests in a specific namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_memory_request_used(meter: Meter) -> UpDownCounter: + """The memory requests in a specific namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_MEMORY_REQUEST_USED, + description="The memory requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_OBJECT_COUNT_HARD: Final = "k8s.resourcequota.object_count.hard" +""" +The object count limits in a specific namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: {object} +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_object_count_hard(meter: Meter) -> UpDownCounter: + """The object count limits in a specific namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_OBJECT_COUNT_HARD, + description="The object count limits in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="{object}", + ) + + +K8S_RESOURCEQUOTA_OBJECT_COUNT_USED: Final = "k8s.resourcequota.object_count.used" +""" +The object count limits in a specific namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: {object} +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). +""" + + +def create_k8s_resourcequota_object_count_used(meter: Meter) -> UpDownCounter: + """The object count limits in a specific namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_OBJECT_COUNT_USED, + description="The object count limits in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="{object}", + ) + + +K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD: Final = "k8s.resourcequota.persistentvolumeclaim_count.hard" +""" +The total number of PersistentVolumeClaims that can exist in the namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: {persistentvolumeclaim} +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_k8s_resourcequota_persistentvolumeclaim_count_hard(meter: Meter) -> UpDownCounter: + """The total number of PersistentVolumeClaims that can exist in the namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD, + description="The total number of PersistentVolumeClaims that can exist in the namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="{persistentvolumeclaim}", + ) + + +K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED: Final = "k8s.resourcequota.persistentvolumeclaim_count.used" +""" +The total number of PersistentVolumeClaims that can exist in the namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: {persistentvolumeclaim} +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_k8s_resourcequota_persistentvolumeclaim_count_used(meter: Meter) -> UpDownCounter: + """The total number of PersistentVolumeClaims that can exist in the namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED, + description="The total number of PersistentVolumeClaims that can exist in the namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="{persistentvolumeclaim}", + ) + + +K8S_RESOURCEQUOTA_STORAGE_REQUEST_HARD: Final = "k8s.resourcequota.storage.request.hard" +""" +The storage requests in a specific namespace. +The value represents the configured quota limit of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_k8s_resourcequota_storage_request_hard(meter: Meter) -> UpDownCounter: + """The storage requests in a specific namespace. + The value represents the configured quota limit of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_STORAGE_REQUEST_HARD, + description="The storage requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", + unit="By", + ) + + +K8S_RESOURCEQUOTA_STORAGE_REQUEST_USED: Final = "k8s.resourcequota.storage.request.used" +""" +The storage requests in a specific namespace. +The value represents the current observed total usage of the resource in the namespace +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_k8s_resourcequota_storage_request_used(meter: Meter) -> UpDownCounter: + """The storage requests in a specific namespace. + The value represents the current observed total usage of the resource in the namespace""" + return meter.create_up_down_counter( + name=K8S_RESOURCEQUOTA_STORAGE_REQUEST_USED, + description="The storage requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", + unit="By", + ) + + +K8S_SERVICE_ENDPOINT_COUNT: Final = "k8s.service.endpoint.count" +""" +Number of endpoints for a service by condition and address type +Instrument: gauge +Unit: {endpoint} +Note: This metric is derived from the Kubernetes [EndpointSlice API](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). +It reports the number of network endpoints backing a Service, broken down by their condition and address type. + +In dual-stack or multi-protocol clusters, separate counts are reported for each address family (`IPv4`, `IPv6`, `FQDN`). + +When the optional `zone` attribute is enabled, counts are further broken down by availability zone for zone-aware monitoring. + +An endpoint may be reported under multiple conditions simultaneously (e.g., both `serving` and `terminating` during a graceful shutdown). +See [K8s EndpointConditions](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/) for more details. + +The conditions represent: +- `ready`: Endpoints capable of receiving new connections. +- `serving`: Endpoints currently handling traffic. +- `terminating`: Endpoints that are being phased out but may still be handling existing connections. + +For Services with `publishNotReadyAddresses` enabled (common for headless StatefulSets), +this metric will include endpoints that are published despite not being ready. +The `k8s.service.publish_not_ready_addresses` resource attribute indicates this setting. +""" + + +def create_k8s_service_endpoint_count(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Number of endpoints for a service by condition and address type""" + return meter.create_observable_gauge( + name=K8S_SERVICE_ENDPOINT_COUNT, + callbacks=callbacks, + description="Number of endpoints for a service by condition and address type.", + unit="{endpoint}", + ) + + +K8S_SERVICE_LOAD_BALANCER_INGRESS_COUNT: Final = "k8s.service.load_balancer.ingress.count" +""" +Number of load balancer ingress points (external IPs/hostnames) assigned to the service +Instrument: gauge +Unit: {ingress} +Note: This metric reports the number of external ingress points (IP addresses or hostnames) +assigned to a LoadBalancer Service. + +It is only emitted for Services of type `LoadBalancer` and reflects the assignments +made by the underlying infrastructure's load balancer controller in the +[.status.loadBalancer.ingress](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceStatus) field. + +A value of `0` indicates that no ingress points have been assigned yet (e.g., during provisioning). +A value greater than `1` may occur when multiple IPs or hostnames are assigned (e.g., dual-stack configurations). + +This metric signals that external endpoints have been assigned by the load balancer controller, but it does not +guarantee that the load balancer is healthy. +""" + + +def create_k8s_service_load_balancer_ingress_count( + meter: Meter, callbacks: Sequence[CallbackT] | None +) -> ObservableGauge: + """Number of load balancer ingress points (external IPs/hostnames) assigned to the service""" + return meter.create_observable_gauge( + name=K8S_SERVICE_LOAD_BALANCER_INGRESS_COUNT, + callbacks=callbacks, + description="Number of load balancer ingress points (external IPs/hostnames) assigned to the service.", + unit="{ingress}", + ) + + +K8S_STATEFULSET_CURRENT_PODS: Final = "k8s.statefulset.current_pods" +""" +Deprecated: Replaced by `k8s.statefulset.pod.current`. +""" + + +def create_k8s_statefulset_current_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.statefulset.pod.current` instead""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_CURRENT_PODS, + description="Deprecated, use `k8s.statefulset.pod.current` instead.", + unit="{pod}", + ) + + +K8S_STATEFULSET_DESIRED_PODS: Final = "k8s.statefulset.desired_pods" +""" +Deprecated: Replaced by `k8s.statefulset.pod.desired`. +""" + + +def create_k8s_statefulset_desired_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.statefulset.pod.desired` instead""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_DESIRED_PODS, + description="Deprecated, use `k8s.statefulset.pod.desired` instead.", + unit="{pod}", + ) + + +K8S_STATEFULSET_POD_CURRENT: Final = "k8s.statefulset.pod.current" +""" +The number of replica pods created by the statefulset controller from the statefulset version indicated by currentRevision +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `currentReplicas` field of the +[K8s StatefulSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetstatus-v1-apps). +""" + + +def create_k8s_statefulset_pod_current(meter: Meter) -> UpDownCounter: + """The number of replica pods created by the statefulset controller from the statefulset version indicated by currentRevision""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_POD_CURRENT, + description="The number of replica pods created by the statefulset controller from the statefulset version indicated by currentRevision.", + unit="{pod}", + ) + + +K8S_STATEFULSET_POD_DESIRED: Final = "k8s.statefulset.pod.desired" +""" +Number of desired replica pods in this statefulset +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `replicas` field of the +[K8s StatefulSetSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetspec-v1-apps). +""" + + +def create_k8s_statefulset_pod_desired(meter: Meter) -> UpDownCounter: + """Number of desired replica pods in this statefulset""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_POD_DESIRED, + description="Number of desired replica pods in this statefulset.", + unit="{pod}", + ) + + +K8S_STATEFULSET_POD_READY: Final = "k8s.statefulset.pod.ready" +""" +The number of replica pods created for this statefulset with a Ready Condition +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `readyReplicas` field of the +[K8s StatefulSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetstatus-v1-apps). +""" + + +def create_k8s_statefulset_pod_ready(meter: Meter) -> UpDownCounter: + """The number of replica pods created for this statefulset with a Ready Condition""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_POD_READY, + description="The number of replica pods created for this statefulset with a Ready Condition.", + unit="{pod}", + ) + + +K8S_STATEFULSET_POD_UPDATED: Final = "k8s.statefulset.pod.updated" +""" +Number of replica pods created by the statefulset controller from the statefulset version indicated by updateRevision +Instrument: updowncounter +Unit: {pod} +Note: This metric aligns with the `updatedReplicas` field of the +[K8s StatefulSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetstatus-v1-apps). +""" + + +def create_k8s_statefulset_pod_updated(meter: Meter) -> UpDownCounter: + """Number of replica pods created by the statefulset controller from the statefulset version indicated by updateRevision""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_POD_UPDATED, + description="Number of replica pods created by the statefulset controller from the statefulset version indicated by updateRevision.", + unit="{pod}", + ) + + +K8S_STATEFULSET_READY_PODS: Final = "k8s.statefulset.ready_pods" +""" +Deprecated: Replaced by `k8s.statefulset.pod.ready`. +""" + + +def create_k8s_statefulset_ready_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.statefulset.pod.ready` instead""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_READY_PODS, + description="Deprecated, use `k8s.statefulset.pod.ready` instead.", + unit="{pod}", + ) + + +K8S_STATEFULSET_UPDATED_PODS: Final = "k8s.statefulset.updated_pods" +""" +Deprecated: Replaced by `k8s.statefulset.pod.updated`. +""" + + +def create_k8s_statefulset_updated_pods(meter: Meter) -> UpDownCounter: + """Deprecated, use `k8s.statefulset.pod.updated` instead""" + return meter.create_up_down_counter( + name=K8S_STATEFULSET_UPDATED_PODS, + description="Deprecated, use `k8s.statefulset.pod.updated` instead.", + unit="{pod}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py new file mode 100644 index 00000000000..93bb2e833e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py @@ -0,0 +1,66 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter + +MCP_CLIENT_OPERATION_DURATION: Final = "mcp.client.operation.duration" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_mcp_client_operation_duration(meter: Meter) -> Histogram: + """The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received""" + return meter.create_histogram( + name=MCP_CLIENT_OPERATION_DURATION, + description="The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received.", + unit="s", + ) + + +MCP_CLIENT_SESSION_DURATION: Final = "mcp.client.session.duration" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_mcp_client_session_duration(meter: Meter) -> Histogram: + """The duration of the MCP session as observed on the MCP client""" + return meter.create_histogram( + name=MCP_CLIENT_SESSION_DURATION, + description="The duration of the MCP session as observed on the MCP client.", + unit="s", + ) + + +MCP_SERVER_OPERATION_DURATION: Final = "mcp.server.operation.duration" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_mcp_server_operation_duration(meter: Meter) -> Histogram: + """MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent""" + return meter.create_histogram( + name=MCP_SERVER_OPERATION_DURATION, + description="MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent.", + unit="s", + ) + + +MCP_SERVER_SESSION_DURATION: Final = "mcp.server.session.duration" +""" +Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). +""" + + +def create_mcp_server_session_duration(meter: Meter) -> Histogram: + """The duration of the MCP session as observed on the MCP server""" + return meter.create_histogram( + name=MCP_SERVER_SESSION_DURATION, + description="The duration of the MCP session as observed on the MCP server.", + unit="s", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py new file mode 100644 index 00000000000..8e7f878f099 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py @@ -0,0 +1,169 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter + +MESSAGING_CLIENT_CONSUMED_MESSAGES: Final = "messaging.client.consumed.messages" +""" +Number of messages that were delivered to the application +Instrument: counter +Unit: {message} +Note: Records the number of messages pulled from the broker or number of messages dispatched to the application in push-based scenarios. +The metric SHOULD be reported once per message delivery. For example, if receiving and processing operations are both instrumented for a single message delivery, this counter is incremented when the message is received and not reported when it is processed. +""" + + +def create_messaging_client_consumed_messages(meter: Meter) -> Counter: + """Number of messages that were delivered to the application""" + return meter.create_counter( + name=MESSAGING_CLIENT_CONSUMED_MESSAGES, + description="Number of messages that were delivered to the application.", + unit="{message}", + ) + + +MESSAGING_CLIENT_OPERATION_DURATION: Final = "messaging.client.operation.duration" +""" +Duration of messaging operation initiated by a producer or consumer client +Instrument: histogram +Unit: s +Note: This metric SHOULD NOT be used to report processing duration - processing duration is reported in `messaging.process.duration` metric. +""" + + +def create_messaging_client_operation_duration(meter: Meter) -> Histogram: + """Duration of messaging operation initiated by a producer or consumer client""" + return meter.create_histogram( + name=MESSAGING_CLIENT_OPERATION_DURATION, + description="Duration of messaging operation initiated by a producer or consumer client.", + unit="s", + ) + + +MESSAGING_CLIENT_PUBLISHED_MESSAGES: Final = "messaging.client.published.messages" +""" +Deprecated: Replaced by `messaging.client.sent.messages`. +""" + + +def create_messaging_client_published_messages(meter: Meter) -> Counter: + """Deprecated. Use `messaging.client.sent.messages` instead""" + return meter.create_counter( + name=MESSAGING_CLIENT_PUBLISHED_MESSAGES, + description="Deprecated. Use `messaging.client.sent.messages` instead.", + unit="{message}", + ) + + +MESSAGING_CLIENT_SENT_MESSAGES: Final = "messaging.client.sent.messages" +""" +Number of messages producer attempted to send to the broker +Instrument: counter +Unit: {message} +Note: This metric MUST NOT count messages that were created but haven't yet been sent. +""" + + +def create_messaging_client_sent_messages(meter: Meter) -> Counter: + """Number of messages producer attempted to send to the broker""" + return meter.create_counter( + name=MESSAGING_CLIENT_SENT_MESSAGES, + description="Number of messages producer attempted to send to the broker.", + unit="{message}", + ) + + +MESSAGING_PROCESS_DURATION: Final = "messaging.process.duration" +""" +Duration of processing operation +Instrument: histogram +Unit: s +Note: This metric MUST be reported for operations with `messaging.operation.type` that matches `process`. +""" + + +def create_messaging_process_duration(meter: Meter) -> Histogram: + """Duration of processing operation""" + return meter.create_histogram( + name=MESSAGING_PROCESS_DURATION, + description="Duration of processing operation.", + unit="s", + ) + + +MESSAGING_PROCESS_MESSAGES: Final = "messaging.process.messages" +""" +Deprecated: Replaced by `messaging.client.consumed.messages`. +""" + + +def create_messaging_process_messages(meter: Meter) -> Counter: + """Deprecated. Use `messaging.client.consumed.messages` instead""" + return meter.create_counter( + name=MESSAGING_PROCESS_MESSAGES, + description="Deprecated. Use `messaging.client.consumed.messages` instead.", + unit="{message}", + ) + + +MESSAGING_PUBLISH_DURATION: Final = "messaging.publish.duration" +""" +Deprecated: Replaced by `messaging.client.operation.duration`. +""" + + +def create_messaging_publish_duration(meter: Meter) -> Histogram: + """Deprecated. Use `messaging.client.operation.duration` instead""" + return meter.create_histogram( + name=MESSAGING_PUBLISH_DURATION, + description="Deprecated. Use `messaging.client.operation.duration` instead.", + unit="s", + ) + + +MESSAGING_PUBLISH_MESSAGES: Final = "messaging.publish.messages" +""" +Deprecated: Replaced by `messaging.client.sent.messages`. +""" + + +def create_messaging_publish_messages(meter: Meter) -> Counter: + """Deprecated. Use `messaging.client.sent.messages` instead""" + return meter.create_counter( + name=MESSAGING_PUBLISH_MESSAGES, + description="Deprecated. Use `messaging.client.sent.messages` instead.", + unit="{message}", + ) + + +MESSAGING_RECEIVE_DURATION: Final = "messaging.receive.duration" +""" +Deprecated: Replaced by `messaging.client.operation.duration`. +""" + + +def create_messaging_receive_duration(meter: Meter) -> Histogram: + """Deprecated. Use `messaging.client.operation.duration` instead""" + return meter.create_histogram( + name=MESSAGING_RECEIVE_DURATION, + description="Deprecated. Use `messaging.client.operation.duration` instead.", + unit="s", + ) + + +MESSAGING_RECEIVE_MESSAGES: Final = "messaging.receive.messages" +""" +Deprecated: Replaced by `messaging.client.consumed.messages`. +""" + + +def create_messaging_receive_messages(meter: Meter) -> Counter: + """Deprecated. Use `messaging.client.consumed.messages` instead""" + return meter.create_counter( + name=MESSAGING_RECEIVE_MESSAGES, + description="Deprecated. Use `messaging.client.consumed.messages` instead.", + unit="{message}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py new file mode 100644 index 00000000000..adfadc02083 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py @@ -0,0 +1,290 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Meter, UpDownCounter + +NFS_CLIENT_NET_COUNT: Final = "nfs.client.net.count" +""" +Reports the count of kernel NFS client TCP segments and UDP datagrams handled +Instrument: counter +Unit: {record} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.netudpcnt and svc_stat.nettcpcnt. +""" + + +def create_nfs_client_net_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS client TCP segments and UDP datagrams handled""" + return meter.create_counter( + name=NFS_CLIENT_NET_COUNT, + description="Reports the count of kernel NFS client TCP segments and UDP datagrams handled.", + unit="{record}", + ) + + +NFS_CLIENT_NET_TCP_CONNECTION_ACCEPTED: Final = "nfs.client.net.tcp.connection.accepted" +""" +Reports the count of kernel NFS client TCP connections accepted +Instrument: counter +Unit: {connection} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.nettcpconn. +""" + + +def create_nfs_client_net_tcp_connection_accepted(meter: Meter) -> Counter: + """Reports the count of kernel NFS client TCP connections accepted""" + return meter.create_counter( + name=NFS_CLIENT_NET_TCP_CONNECTION_ACCEPTED, + description="Reports the count of kernel NFS client TCP connections accepted.", + unit="{connection}", + ) + + +NFS_CLIENT_OPERATION_COUNT: Final = "nfs.client.operation.count" +""" +Reports the count of kernel NFSv4+ client operations +Instrument: counter +Unit: {operation} +""" + + +def create_nfs_client_operation_count(meter: Meter) -> Counter: + """Reports the count of kernel NFSv4+ client operations""" + return meter.create_counter( + name=NFS_CLIENT_OPERATION_COUNT, + description="Reports the count of kernel NFSv4+ client operations.", + unit="{operation}", + ) + + +NFS_CLIENT_PROCEDURE_COUNT: Final = "nfs.client.procedure.count" +""" +Reports the count of kernel NFS client procedures +Instrument: counter +Unit: {procedure} +""" + + +def create_nfs_client_procedure_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS client procedures""" + return meter.create_counter( + name=NFS_CLIENT_PROCEDURE_COUNT, + description="Reports the count of kernel NFS client procedures.", + unit="{procedure}", + ) + + +NFS_CLIENT_RPC_AUTHREFRESH_COUNT: Final = "nfs.client.rpc.authrefresh.count" +""" +Reports the count of kernel NFS client RPC authentication refreshes +Instrument: counter +Unit: {authrefresh} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpcauthrefresh. +""" + + +def create_nfs_client_rpc_authrefresh_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS client RPC authentication refreshes""" + return meter.create_counter( + name=NFS_CLIENT_RPC_AUTHREFRESH_COUNT, + description="Reports the count of kernel NFS client RPC authentication refreshes.", + unit="{authrefresh}", + ) + + +NFS_CLIENT_RPC_COUNT: Final = "nfs.client.rpc.count" +""" +Reports the count of kernel NFS client RPCs sent, regardless of whether they're accepted/rejected by the server +Instrument: counter +Unit: {request} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpccnt. +""" + + +def create_nfs_client_rpc_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS client RPCs sent, regardless of whether they're accepted/rejected by the server""" + return meter.create_counter( + name=NFS_CLIENT_RPC_COUNT, + description="Reports the count of kernel NFS client RPCs sent, regardless of whether they're accepted/rejected by the server.", + unit="{request}", + ) + + +NFS_CLIENT_RPC_RETRANSMIT_COUNT: Final = "nfs.client.rpc.retransmit.count" +""" +Reports the count of kernel NFS client RPC retransmits +Instrument: counter +Unit: {retransmit} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpcretrans. +""" + + +def create_nfs_client_rpc_retransmit_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS client RPC retransmits""" + return meter.create_counter( + name=NFS_CLIENT_RPC_RETRANSMIT_COUNT, + description="Reports the count of kernel NFS client RPC retransmits.", + unit="{retransmit}", + ) + + +NFS_SERVER_FH_STALE_COUNT: Final = "nfs.server.fh.stale.count" +""" +Reports the count of kernel NFS server stale file handles +Instrument: counter +Unit: {fh} +Note: Linux: this metric is taken from the Linux kernel NFSD_STATS_FH_STALE counter in the nfsd_net struct. +""" + + +def create_nfs_server_fh_stale_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS server stale file handles""" + return meter.create_counter( + name=NFS_SERVER_FH_STALE_COUNT, + description="Reports the count of kernel NFS server stale file handles.", + unit="{fh}", + ) + + +NFS_SERVER_IO: Final = "nfs.server.io" +""" +Reports the count of kernel NFS server bytes returned to receive and transmit (read and write) requests +Instrument: counter +Unit: By +Note: Linux: this metric is taken from the Linux kernel NFSD_STATS_IO_READ and NFSD_STATS_IO_WRITE counters in the nfsd_net struct. +""" + + +def create_nfs_server_io(meter: Meter) -> Counter: + """Reports the count of kernel NFS server bytes returned to receive and transmit (read and write) requests""" + return meter.create_counter( + name=NFS_SERVER_IO, + description="Reports the count of kernel NFS server bytes returned to receive and transmit (read and write) requests.", + unit="By", + ) + + +NFS_SERVER_NET_COUNT: Final = "nfs.server.net.count" +""" +Reports the count of kernel NFS server TCP segments and UDP datagrams handled +Instrument: counter +Unit: {record} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.nettcpcnt and svc_stat.netudpcnt. +""" + + +def create_nfs_server_net_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS server TCP segments and UDP datagrams handled""" + return meter.create_counter( + name=NFS_SERVER_NET_COUNT, + description="Reports the count of kernel NFS server TCP segments and UDP datagrams handled.", + unit="{record}", + ) + + +NFS_SERVER_NET_TCP_CONNECTION_ACCEPTED: Final = "nfs.server.net.tcp.connection.accepted" +""" +Reports the count of kernel NFS server TCP connections accepted +Instrument: counter +Unit: {connection} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.nettcpconn. +""" + + +def create_nfs_server_net_tcp_connection_accepted(meter: Meter) -> Counter: + """Reports the count of kernel NFS server TCP connections accepted""" + return meter.create_counter( + name=NFS_SERVER_NET_TCP_CONNECTION_ACCEPTED, + description="Reports the count of kernel NFS server TCP connections accepted.", + unit="{connection}", + ) + + +NFS_SERVER_OPERATION_COUNT: Final = "nfs.server.operation.count" +""" +Reports the count of kernel NFSv4+ server operations +Instrument: counter +Unit: {operation} +""" + + +def create_nfs_server_operation_count(meter: Meter) -> Counter: + """Reports the count of kernel NFSv4+ server operations""" + return meter.create_counter( + name=NFS_SERVER_OPERATION_COUNT, + description="Reports the count of kernel NFSv4+ server operations.", + unit="{operation}", + ) + + +NFS_SERVER_PROCEDURE_COUNT: Final = "nfs.server.procedure.count" +""" +Reports the count of kernel NFS server procedures +Instrument: counter +Unit: {procedure} +""" + + +def create_nfs_server_procedure_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS server procedures""" + return meter.create_counter( + name=NFS_SERVER_PROCEDURE_COUNT, + description="Reports the count of kernel NFS server procedures.", + unit="{procedure}", + ) + + +NFS_SERVER_REPCACHE_REQUESTS: Final = "nfs.server.repcache.requests" +""" +Reports the kernel NFS server reply cache request count by cache hit status +Instrument: counter +Unit: {request} +""" + + +def create_nfs_server_repcache_requests(meter: Meter) -> Counter: + """Reports the kernel NFS server reply cache request count by cache hit status""" + return meter.create_counter( + name=NFS_SERVER_REPCACHE_REQUESTS, + description="Reports the kernel NFS server reply cache request count by cache hit status.", + unit="{request}", + ) + + +NFS_SERVER_RPC_COUNT: Final = "nfs.server.rpc.count" +""" +Reports the count of kernel NFS server RPCs handled +Instrument: counter +Unit: {request} +Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpccnt, the count of good RPCs. This metric can have +an error.type of "format", "auth", or "client" for svc_stat.badfmt, svc_stat.badauth, and svc_stat.badclnt. +""" + + +def create_nfs_server_rpc_count(meter: Meter) -> Counter: + """Reports the count of kernel NFS server RPCs handled""" + return meter.create_counter( + name=NFS_SERVER_RPC_COUNT, + description="Reports the count of kernel NFS server RPCs handled.", + unit="{request}", + ) + + +NFS_SERVER_THREAD_COUNT: Final = "nfs.server.thread.count" +""" +Reports the count of kernel NFS server available threads +Instrument: updowncounter +Unit: {thread} +Note: Linux: this metric is taken from the Linux kernel nfsd_th_cnt variable. +""" + + +def create_nfs_server_thread_count(meter: Meter) -> UpDownCounter: + """Reports the count of kernel NFS server available threads""" + return meter.create_up_down_counter( + name=NFS_SERVER_THREAD_COUNT, + description="Reports the count of kernel NFS server available threads.", + unit="{thread}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py new file mode 100644 index 00000000000..6f36f4a48ba --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py @@ -0,0 +1,442 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Meter, UpDownCounter + +OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_HARD: Final = "openshift.clusterquota.cpu.limit.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_cpu_limit_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="{cpu}", + ) + + +OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_USED: Final = "openshift.clusterquota.cpu.limit.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_cpu_limit_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_USED, + description="The current observed total usage of the resource across all projects.", + unit="{cpu}", + ) + + +OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_HARD: Final = "openshift.clusterquota.cpu.request.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_cpu_request_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="{cpu}", + ) + + +OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_USED: Final = "openshift.clusterquota.cpu.request.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: {cpu} +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_cpu_request_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_USED, + description="The current observed total usage of the resource across all projects.", + unit="{cpu}", + ) + + +OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD: Final = "openshift.clusterquota.ephemeral_storage.limit.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_ephemeral_storage_limit_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_USED: Final = "openshift.clusterquota.ephemeral_storage.limit.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_ephemeral_storage_limit_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_USED, + description="The current observed total usage of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD: Final = "openshift.clusterquota.ephemeral_storage.request.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_ephemeral_storage_request_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_USED: Final = "openshift.clusterquota.ephemeral_storage.request.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_ephemeral_storage_request_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_USED, + description="The current observed total usage of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_HARD: Final = "openshift.clusterquota.hugepage_count.request.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: {hugepage} +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_hugepage_count_request_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="{hugepage}", + ) + + +OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_USED: Final = "openshift.clusterquota.hugepage_count.request.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: {hugepage} +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_hugepage_count_request_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_USED, + description="The current observed total usage of the resource across all projects.", + unit="{hugepage}", + ) + + +OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_HARD: Final = "openshift.clusterquota.memory.limit.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_memory_limit_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_USED: Final = "openshift.clusterquota.memory.limit.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_memory_limit_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_USED, + description="The current observed total usage of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_HARD: Final = "openshift.clusterquota.memory.request.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_memory_request_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_USED: Final = "openshift.clusterquota.memory.request.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_memory_request_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_USED, + description="The current observed total usage of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_HARD: Final = "openshift.clusterquota.object_count.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: {object} +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_object_count_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="{object}", + ) + + +OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_USED: Final = "openshift.clusterquota.object_count.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: {object} +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). +""" + + +def create_openshift_clusterquota_object_count_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_USED, + description="The current observed total usage of the resource across all projects.", + unit="{object}", + ) + + +OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD: Final = ( + "openshift.clusterquota.persistentvolumeclaim_count.hard" +) +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: {persistentvolumeclaim} +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_openshift_clusterquota_persistentvolumeclaim_count_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="{persistentvolumeclaim}", + ) + + +OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED: Final = ( + "openshift.clusterquota.persistentvolumeclaim_count.used" +) +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: {persistentvolumeclaim} +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_openshift_clusterquota_persistentvolumeclaim_count_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED, + description="The current observed total usage of the resource across all projects.", + unit="{persistentvolumeclaim}", + ) + + +OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_HARD: Final = "openshift.clusterquota.storage.request.hard" +""" +The enforced hard limit of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Hard` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_openshift_clusterquota_storage_request_hard(meter: Meter) -> UpDownCounter: + """The enforced hard limit of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_HARD, + description="The enforced hard limit of the resource across all projects.", + unit="By", + ) + + +OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_USED: Final = "openshift.clusterquota.storage.request.used" +""" +The current observed total usage of the resource across all projects +Instrument: updowncounter +Unit: By +Note: This metric is retrieved from the `Status.Total.Used` field of the +[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) +of the +[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). + +The `k8s.storageclass.name` should be required when a resource quota is defined for a specific +storage class. +""" + + +def create_openshift_clusterquota_storage_request_used(meter: Meter) -> UpDownCounter: + """The current observed total usage of the resource across all projects""" + return meter.create_up_down_counter( + name=OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_USED, + description="The current observed total usage of the resource across all projects.", + unit="By", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py new file mode 100644 index 00000000000..3acc2edc063 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py @@ -0,0 +1,443 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter, UpDownCounter + +OTEL_SDK_EXPORTER_LOG_EXPORTED: Final = "otel.sdk.exporter.log.exported" +""" +The number of log records for which the export has finished, either successful or failed +Instrument: counter +Unit: {log_record} +Note: For successful exports, `error.type` MUST NOT be set. For failed exports, `error.type` MUST contain the failure cause. +For exporters with partial success semantics (e.g. OTLP with `rejected_log_records`), rejected log records MUST count as failed and only non-rejected log records count as success. +If no rejection reason is available, `rejected` SHOULD be used as value for `error.type`. +If the exporter retries failed export attempts, the export operation is considered finished only after the final attempt has concluded. +Each log record MUST be counted exactly once per export operation: intermediate failed attempts that are followed by a retry MUST NOT increment the counter, +and `error.type` reflects the cause of the final attempt. +""" + + +def create_otel_sdk_exporter_log_exported(meter: Meter) -> Counter: + """The number of log records for which the export has finished, either successful or failed""" + return meter.create_counter( + name=OTEL_SDK_EXPORTER_LOG_EXPORTED, + description="The number of log records for which the export has finished, either successful or failed.", + unit="{log_record}", + ) + + +OTEL_SDK_EXPORTER_LOG_INFLIGHT: Final = "otel.sdk.exporter.log.inflight" +""" +The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed) +Instrument: updowncounter +Unit: {log_record} +Note: Log records are counted as inflight from when they are passed to the exporter until the export operation has concluded. +If the exporter retries failed export attempts, log records remain inflight across all retry attempts and any backoff between them. +""" + + +def create_otel_sdk_exporter_log_inflight(meter: Meter) -> UpDownCounter: + """The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)""" + return meter.create_up_down_counter( + name=OTEL_SDK_EXPORTER_LOG_INFLIGHT, + description="The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).", + unit="{log_record}", + ) + + +OTEL_SDK_EXPORTER_METRIC_DATA_POINT_EXPORTED: Final = "otel.sdk.exporter.metric_data_point.exported" +""" +The number of metric data points for which the export has finished, either successful or failed +Instrument: counter +Unit: {data_point} +Note: For successful exports, `error.type` MUST NOT be set. For failed exports, `error.type` MUST contain the failure cause. +For exporters with partial success semantics (e.g. OTLP with `rejected_data_points`), rejected data points MUST count as failed and only non-rejected data points count as success. +If no rejection reason is available, `rejected` SHOULD be used as value for `error.type`. +If the exporter retries failed export attempts, the export operation is considered finished only after the final attempt has concluded. +Each metric data point MUST be counted exactly once per export operation: intermediate failed attempts that are followed by a retry MUST NOT increment the counter, +and `error.type` reflects the cause of the final attempt. +""" + + +def create_otel_sdk_exporter_metric_data_point_exported(meter: Meter) -> Counter: + """The number of metric data points for which the export has finished, either successful or failed""" + return meter.create_counter( + name=OTEL_SDK_EXPORTER_METRIC_DATA_POINT_EXPORTED, + description="The number of metric data points for which the export has finished, either successful or failed.", + unit="{data_point}", + ) + + +OTEL_SDK_EXPORTER_METRIC_DATA_POINT_INFLIGHT: Final = "otel.sdk.exporter.metric_data_point.inflight" +""" +The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed) +Instrument: updowncounter +Unit: {data_point} +Note: Metric data points are counted as inflight from when they are passed to the exporter until the export operation has concluded. +If the exporter retries failed export attempts, metric data points remain inflight across all retry attempts and any backoff between them. +""" + + +def create_otel_sdk_exporter_metric_data_point_inflight(meter: Meter) -> UpDownCounter: + """The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)""" + return meter.create_up_down_counter( + name=OTEL_SDK_EXPORTER_METRIC_DATA_POINT_INFLIGHT, + description="The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).", + unit="{data_point}", + ) + + +OTEL_SDK_EXPORTER_OPERATION_DURATION: Final = "otel.sdk.exporter.operation.duration" +""" +The duration of exporting a batch of telemetry records +Instrument: histogram +Unit: s +Note: This metric defines successful operations using the full success definitions for [HTTP](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1) +and [gRPC](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success). Anything else is defined as an unsuccessful operation. For successful +operations, `error.type` MUST NOT be set. For unsuccessful export operations, `error.type` MUST contain a relevant failure cause. +If the exporter retries failed export attempts, exactly one observation MUST be recorded per export operation, +covering the wall-clock duration from the start of the first attempt through the conclusion of the final attempt (including any backoff between attempts). +`error.type` reflects the cause of the final attempt. +""" + + +def create_otel_sdk_exporter_operation_duration(meter: Meter) -> Histogram: + """The duration of exporting a batch of telemetry records""" + return meter.create_histogram( + name=OTEL_SDK_EXPORTER_OPERATION_DURATION, + description="The duration of exporting a batch of telemetry records.", + unit="s", + ) + + +OTEL_SDK_EXPORTER_SPAN_EXPORTED: Final = "otel.sdk.exporter.span.exported" +""" +The number of spans for which the export has finished, either successful or failed +Instrument: counter +Unit: {span} +Note: For successful exports, `error.type` MUST NOT be set. For failed exports, `error.type` MUST contain the failure cause. +For exporters with partial success semantics (e.g. OTLP with `rejected_spans`), rejected spans MUST count as failed and only non-rejected spans count as success. +If no rejection reason is available, `rejected` SHOULD be used as value for `error.type`. +If the exporter retries failed export attempts, the export operation is considered finished only after the final attempt has concluded. +Each span MUST be counted exactly once per export operation: intermediate failed attempts that are followed by a retry MUST NOT increment the counter, +and `error.type` reflects the cause of the final attempt. +""" + + +def create_otel_sdk_exporter_span_exported(meter: Meter) -> Counter: + """The number of spans for which the export has finished, either successful or failed""" + return meter.create_counter( + name=OTEL_SDK_EXPORTER_SPAN_EXPORTED, + description="The number of spans for which the export has finished, either successful or failed.", + unit="{span}", + ) + + +OTEL_SDK_EXPORTER_SPAN_EXPORTED_COUNT: Final = "otel.sdk.exporter.span.exported.count" +""" +Deprecated: Replaced by `otel.sdk.exporter.span.exported`. +""" + + +def create_otel_sdk_exporter_span_exported_count(meter: Meter) -> UpDownCounter: + """Deprecated, use `otel.sdk.exporter.span.exported` instead""" + return meter.create_up_down_counter( + name=OTEL_SDK_EXPORTER_SPAN_EXPORTED_COUNT, + description="Deprecated, use `otel.sdk.exporter.span.exported` instead.", + unit="{span}", + ) + + +OTEL_SDK_EXPORTER_SPAN_INFLIGHT: Final = "otel.sdk.exporter.span.inflight" +""" +The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed) +Instrument: updowncounter +Unit: {span} +Note: Spans are counted as inflight from when they are passed to the exporter until the export operation has concluded. +If the exporter retries failed export attempts, spans remain inflight across all retry attempts and any backoff between them. +""" + + +def create_otel_sdk_exporter_span_inflight(meter: Meter) -> UpDownCounter: + """The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)""" + return meter.create_up_down_counter( + name=OTEL_SDK_EXPORTER_SPAN_INFLIGHT, + description="The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).", + unit="{span}", + ) + + +OTEL_SDK_EXPORTER_SPAN_INFLIGHT_COUNT: Final = "otel.sdk.exporter.span.inflight.count" +""" +Deprecated: Replaced by `otel.sdk.exporter.span.inflight`. +""" + + +def create_otel_sdk_exporter_span_inflight_count(meter: Meter) -> UpDownCounter: + """Deprecated, use `otel.sdk.exporter.span.inflight` instead""" + return meter.create_up_down_counter( + name=OTEL_SDK_EXPORTER_SPAN_INFLIGHT_COUNT, + description="Deprecated, use `otel.sdk.exporter.span.inflight` instead.", + unit="{span}", + ) + + +OTEL_SDK_LOG_CREATED: Final = "otel.sdk.log.created" +""" +The number of logs submitted to enabled SDK Loggers +Instrument: counter +Unit: {log_record} +""" + + +def create_otel_sdk_log_created(meter: Meter) -> Counter: + """The number of logs submitted to enabled SDK Loggers""" + return meter.create_counter( + name=OTEL_SDK_LOG_CREATED, + description="The number of logs submitted to enabled SDK Loggers.", + unit="{log_record}", + ) + + +OTEL_SDK_METRIC_READER_COLLECTION_DURATION: Final = "otel.sdk.metric_reader.collection.duration" +""" +The duration of the collect operation of the metric reader +Instrument: histogram +Unit: s +Note: For successful collections, `error.type` MUST NOT be set. For failed collections, `error.type` SHOULD contain the failure cause. +It can happen that metrics collection is successful for some MetricProducers, while others fail. In that case `error.type` SHOULD be set to any of the failure causes. +""" + + +def create_otel_sdk_metric_reader_collection_duration(meter: Meter) -> Histogram: + """The duration of the collect operation of the metric reader""" + return meter.create_histogram( + name=OTEL_SDK_METRIC_READER_COLLECTION_DURATION, + description="The duration of the collect operation of the metric reader.", + unit="s", + ) + + +OTEL_SDK_PROCESSOR_LOG_PROCESSED: Final = "otel.sdk.processor.log.processed" +""" +The number of log records for which the processing has finished, either successful or failed +Instrument: counter +Unit: {log_record} +Note: For successful processing, `error.type` MUST NOT be set. For failed processing, `error.type` MUST contain the failure cause. +SDK Batching Log Record Processors MUST use `queue_full` as the value of `error.type` for log records dropped due to a full queue. +If a processor reports a log record dropped because it has already been shut down, `error.type` MUST be `already_shutdown`. +Whether and when a processor drops such log records is governed by the SDK specification, not by this metric. +For the SDK Simple and Batching Log Record Processors, a log record MUST be counted as successfully processed at the point the +processor invokes the export operation. For batching processors, all log records in the batch passed to the exporter are counted +at that point; log records accepted into the processor's queue but not yet passed to the exporter have not been processed. +Implementations MUST NOT delay this count until the export operation concludes, and the outcome of the export operation, +including an immediate failure of the invocation itself, MUST NOT affect this metric. +Export outcomes are reported by `otel.sdk.exporter.log.exported`. +""" + + +def create_otel_sdk_processor_log_processed(meter: Meter) -> Counter: + """The number of log records for which the processing has finished, either successful or failed""" + return meter.create_counter( + name=OTEL_SDK_PROCESSOR_LOG_PROCESSED, + description="The number of log records for which the processing has finished, either successful or failed.", + unit="{log_record}", + ) + + +OTEL_SDK_PROCESSOR_LOG_QUEUE_CAPACITY: Final = "otel.sdk.processor.log.queue.capacity" +""" +The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold +Instrument: updowncounter +Unit: {log_record} +Note: Only applies to Log Record processors which use a queue, e.g. the SDK Batching Log Record Processor. +""" + + +def create_otel_sdk_processor_log_queue_capacity(meter: Meter) -> UpDownCounter: + """The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold""" + return meter.create_up_down_counter( + name=OTEL_SDK_PROCESSOR_LOG_QUEUE_CAPACITY, + description="The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold.", + unit="{log_record}", + ) + + +OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE: Final = "otel.sdk.processor.log.queue.size" +""" +The number of log records in the queue of a given instance of an SDK log processor +Instrument: updowncounter +Unit: {log_record} +Note: Only applies to log record processors which use a queue, e.g. the SDK Batching Log Record Processor. +""" + + +def create_otel_sdk_processor_log_queue_size(meter: Meter) -> UpDownCounter: + """The number of log records in the queue of a given instance of an SDK log processor""" + return meter.create_up_down_counter( + name=OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE, + description="The number of log records in the queue of a given instance of an SDK log processor.", + unit="{log_record}", + ) + + +OTEL_SDK_PROCESSOR_SPAN_PROCESSED: Final = "otel.sdk.processor.span.processed" +""" +The number of spans for which the processing has finished, either successful or failed +Instrument: counter +Unit: {span} +Note: For successful processing, `error.type` MUST NOT be set. For failed processing, `error.type` MUST contain the failure cause. +SDK Batching Span Processors MUST use `queue_full` as the value of `error.type` for spans dropped due to a full queue. +If a processor reports a span dropped because it has already been shut down, `error.type` MUST be `already_shutdown`. +Whether and when a processor drops such spans is governed by the SDK specification, not by this metric. +For the SDK Simple and Batching Span Processors, a span MUST be counted as successfully processed at the point the processor +invokes the export operation. For batching processors, all spans in the batch passed to the exporter are counted at that point; +spans accepted into the processor's queue but not yet passed to the exporter have not been processed. +Implementations MUST NOT delay this count until the export operation concludes, and the outcome of the export operation, +including an immediate failure of the invocation itself, MUST NOT affect this metric. +Export outcomes are reported by `otel.sdk.exporter.span.exported`. +""" + + +def create_otel_sdk_processor_span_processed(meter: Meter) -> Counter: + """The number of spans for which the processing has finished, either successful or failed""" + return meter.create_counter( + name=OTEL_SDK_PROCESSOR_SPAN_PROCESSED, + description="The number of spans for which the processing has finished, either successful or failed.", + unit="{span}", + ) + + +OTEL_SDK_PROCESSOR_SPAN_PROCESSED_COUNT: Final = "otel.sdk.processor.span.processed.count" +""" +Deprecated: Replaced by `otel.sdk.processor.span.processed`. +""" + + +def create_otel_sdk_processor_span_processed_count(meter: Meter) -> UpDownCounter: + """Deprecated, use `otel.sdk.processor.span.processed` instead""" + return meter.create_up_down_counter( + name=OTEL_SDK_PROCESSOR_SPAN_PROCESSED_COUNT, + description="Deprecated, use `otel.sdk.processor.span.processed` instead.", + unit="{span}", + ) + + +OTEL_SDK_PROCESSOR_SPAN_QUEUE_CAPACITY: Final = "otel.sdk.processor.span.queue.capacity" +""" +The maximum number of spans the queue of a given instance of an SDK span processor can hold +Instrument: updowncounter +Unit: {span} +Note: Only applies to span processors which use a queue, e.g. the SDK Batching Span Processor. +""" + + +def create_otel_sdk_processor_span_queue_capacity(meter: Meter) -> UpDownCounter: + """The maximum number of spans the queue of a given instance of an SDK span processor can hold""" + return meter.create_up_down_counter( + name=OTEL_SDK_PROCESSOR_SPAN_QUEUE_CAPACITY, + description="The maximum number of spans the queue of a given instance of an SDK span processor can hold.", + unit="{span}", + ) + + +OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE: Final = "otel.sdk.processor.span.queue.size" +""" +The number of spans in the queue of a given instance of an SDK span processor +Instrument: updowncounter +Unit: {span} +Note: Only applies to span processors which use a queue, e.g. the SDK Batching Span Processor. +""" + + +def create_otel_sdk_processor_span_queue_size(meter: Meter) -> UpDownCounter: + """The number of spans in the queue of a given instance of an SDK span processor""" + return meter.create_up_down_counter( + name=OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE, + description="The number of spans in the queue of a given instance of an SDK span processor.", + unit="{span}", + ) + + +OTEL_SDK_SPAN_ENDED: Final = "otel.sdk.span.ended" +""" +Deprecated: Obsoleted. +""" + + +def create_otel_sdk_span_ended(meter: Meter) -> Counter: + """Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value""" + return meter.create_counter( + name=OTEL_SDK_SPAN_ENDED, + description="Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value.", + unit="{span}", + ) + + +OTEL_SDK_SPAN_ENDED_COUNT: Final = "otel.sdk.span.ended.count" +""" +Deprecated: Obsoleted. +""" + + +def create_otel_sdk_span_ended_count(meter: Meter) -> Counter: + """Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value""" + return meter.create_counter( + name=OTEL_SDK_SPAN_ENDED_COUNT, + description="Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value.", + unit="{span}", + ) + + +OTEL_SDK_SPAN_LIVE: Final = "otel.sdk.span.live" +""" +The number of created spans with `recording=true` for which the end operation has not been called yet +Instrument: updowncounter +Unit: {span} +Note: Non-recording spans are not counted, hence `otel.span.sampling_result` can only take values `RECORD_ONLY` and `RECORD_AND_SAMPLE`, not `DROP`. +""" + + +def create_otel_sdk_span_live(meter: Meter) -> UpDownCounter: + """The number of created spans with `recording=true` for which the end operation has not been called yet""" + return meter.create_up_down_counter( + name=OTEL_SDK_SPAN_LIVE, + description="The number of created spans with `recording=true` for which the end operation has not been called yet.", + unit="{span}", + ) + + +OTEL_SDK_SPAN_LIVE_COUNT: Final = "otel.sdk.span.live.count" +""" +Deprecated: Replaced by `otel.sdk.span.live`. +""" + + +def create_otel_sdk_span_live_count(meter: Meter) -> UpDownCounter: + """Deprecated, use `otel.sdk.span.live` instead""" + return meter.create_up_down_counter( + name=OTEL_SDK_SPAN_LIVE_COUNT, + description="Deprecated, use `otel.sdk.span.live` instead.", + unit="{span}", + ) + + +OTEL_SDK_SPAN_STARTED: Final = "otel.sdk.span.started" +""" +The number of created spans +Instrument: counter +Unit: {span} +Note: Implementations MUST record this metric for all spans, even for non-recording ones. +""" + + +def create_otel_sdk_span_started(meter: Meter) -> Counter: + """The number of created spans""" + return meter.create_counter( + name=OTEL_SDK_SPAN_STARTED, + description="The number of created spans.", + unit="{span}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py new file mode 100644 index 00000000000..bf82d7bf6ee --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py @@ -0,0 +1,286 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter + +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +PROCESS_CONTEXT_SWITCHES: Final = "process.context_switches" +""" +Number of times the process has been context switched +Instrument: counter +Unit: {context_switch} +""" + + +def create_process_context_switches(meter: Meter) -> Counter: + """Number of times the process has been context switched""" + return meter.create_counter( + name=PROCESS_CONTEXT_SWITCHES, + description="Number of times the process has been context switched.", + unit="{context_switch}", + ) + + +PROCESS_CPU_TIME: Final = "process.cpu.time" +""" +Total CPU seconds broken down by different CPU modes +Instrument: counter +Unit: s +""" + + +def create_process_cpu_time(meter: Meter) -> Counter: + """Total CPU seconds broken down by different CPU modes""" + return meter.create_counter( + name=PROCESS_CPU_TIME, + description="Total CPU seconds broken down by different CPU modes.", + unit="s", + ) + + +PROCESS_CPU_UTILIZATION: Final = "process.cpu.utilization" +""" +Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process +Instrument: gauge +Unit: 1 +""" + + +def create_process_cpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process""" + return meter.create_observable_gauge( + name=PROCESS_CPU_UTILIZATION, + callbacks=callbacks, + description="Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process.", + unit="1", + ) + + +PROCESS_DISK_IO: Final = "process.disk.io" +""" +Disk bytes transferred +Instrument: counter +Unit: By +""" + + +def create_process_disk_io(meter: Meter) -> Counter: + """Disk bytes transferred""" + return meter.create_counter( + name=PROCESS_DISK_IO, + description="Disk bytes transferred.", + unit="By", + ) + + +PROCESS_DISK_OPERATIONS: Final = "process.disk.operations" +""" +Number of disk operations performed by the process +Instrument: counter +Unit: {operation} +""" + + +def create_process_disk_operations(meter: Meter) -> Counter: + """Number of disk operations performed by the process""" + return meter.create_counter( + name=PROCESS_DISK_OPERATIONS, + description="Number of disk operations performed by the process.", + unit="{operation}", + ) + + +PROCESS_MEMORY_USAGE: Final = "process.memory.usage" +""" +The amount of physical memory in use +Instrument: updowncounter +Unit: By +""" + + +def create_process_memory_usage(meter: Meter) -> UpDownCounter: + """The amount of physical memory in use""" + return meter.create_up_down_counter( + name=PROCESS_MEMORY_USAGE, + description="The amount of physical memory in use.", + unit="By", + ) + + +PROCESS_MEMORY_UTILIZATION: Final = "process.memory.utilization" +""" +Percentage of total physical memory that is used by the process +Instrument: gauge +Unit: 1 +""" + + +def create_process_memory_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Percentage of total physical memory that is used by the process""" + return meter.create_observable_gauge( + name=PROCESS_MEMORY_UTILIZATION, + callbacks=callbacks, + description="Percentage of total physical memory that is used by the process.", + unit="1", + ) + + +PROCESS_MEMORY_VIRTUAL: Final = "process.memory.virtual" +""" +The amount of committed virtual memory +Instrument: updowncounter +Unit: By +""" + + +def create_process_memory_virtual(meter: Meter) -> UpDownCounter: + """The amount of committed virtual memory""" + return meter.create_up_down_counter( + name=PROCESS_MEMORY_VIRTUAL, + description="The amount of committed virtual memory.", + unit="By", + ) + + +PROCESS_NETWORK_IO: Final = "process.network.io" +""" +Network bytes transferred +Instrument: counter +Unit: By +""" + + +def create_process_network_io(meter: Meter) -> Counter: + """Network bytes transferred""" + return meter.create_counter( + name=PROCESS_NETWORK_IO, + description="Network bytes transferred.", + unit="By", + ) + + +PROCESS_OPEN_FILE_DESCRIPTOR_COUNT: Final = "process.open_file_descriptor.count" +""" +Deprecated: Replaced by `process.unix.file_descriptor.count`. +""" + + +def create_process_open_file_descriptor_count(meter: Meter) -> UpDownCounter: + """Deprecated, use `process.unix.file_descriptor.count` instead""" + return meter.create_up_down_counter( + name=PROCESS_OPEN_FILE_DESCRIPTOR_COUNT, + description="Deprecated, use `process.unix.file_descriptor.count` instead.", + unit="{file_descriptor}", + ) + + +PROCESS_PAGING_FAULTS: Final = "process.paging.faults" +""" +Number of page faults the process has made +Instrument: counter +Unit: {fault} +""" + + +def create_process_paging_faults(meter: Meter) -> Counter: + """Number of page faults the process has made""" + return meter.create_counter( + name=PROCESS_PAGING_FAULTS, + description="Number of page faults the process has made.", + unit="{fault}", + ) + + +PROCESS_SIGNALS_PENDING: Final = "process.signals_pending" +""" +Number of pending signals for the process +Instrument: updowncounter +Unit: {signal} +""" + + +def create_process_signals_pending(meter: Meter) -> UpDownCounter: + """Number of pending signals for the process""" + return meter.create_up_down_counter( + name=PROCESS_SIGNALS_PENDING, + description="Number of pending signals for the process.", + unit="{signal}", + ) + + +PROCESS_THREAD_COUNT: Final = "process.thread.count" +""" +Process threads count +Instrument: updowncounter +Unit: {thread} +""" + + +def create_process_thread_count(meter: Meter) -> UpDownCounter: + """Process threads count""" + return meter.create_up_down_counter( + name=PROCESS_THREAD_COUNT, + description="Process threads count.", + unit="{thread}", + ) + + +PROCESS_UNIX_FILE_DESCRIPTOR_COUNT: Final = "process.unix.file_descriptor.count" +""" +Number of UNIX file descriptors in use by the process +Instrument: updowncounter +Unit: {file_descriptor} +""" + + +def create_process_unix_file_descriptor_count(meter: Meter) -> UpDownCounter: + """Number of UNIX file descriptors in use by the process""" + return meter.create_up_down_counter( + name=PROCESS_UNIX_FILE_DESCRIPTOR_COUNT, + description="Number of UNIX file descriptors in use by the process.", + unit="{file_descriptor}", + ) + + +PROCESS_UPTIME: Final = "process.uptime" +""" +The time the process has been running +Instrument: gauge +Unit: s +Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. +The actual accuracy would depend on the instrumentation and operating system. +""" + + +def create_process_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The time the process has been running""" + return meter.create_observable_gauge( + name=PROCESS_UPTIME, + callbacks=callbacks, + description="The time the process has been running.", + unit="s", + ) + + +PROCESS_WINDOWS_HANDLE_COUNT: Final = "process.windows.handle.count" +""" +Number of handles held by the process +Instrument: updowncounter +Unit: {handle} +""" + + +def create_process_windows_handle_count(meter: Meter) -> UpDownCounter: + """Number of handles held by the process""" + return meter.create_up_down_counter( + name=PROCESS_WINDOWS_HANDLE_COUNT, + description="Number of handles held by the process.", + unit="{handle}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py new file mode 100644 index 00000000000..b2c5dfe8c46 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py @@ -0,0 +1,194 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter + +RPC_CLIENT_CALL_DURATION: Final = "rpc.client.call.duration" +""" +Measures the duration of an outgoing Remote Procedure Call (RPC) +Instrument: histogram +Unit: s +Note: When this metric is reported alongside an RPC client span, the metric value +SHOULD be the same as the RPC client span duration. +""" + + +def create_rpc_client_call_duration(meter: Meter) -> Histogram: + """Measures the duration of an outgoing Remote Procedure Call (RPC)""" + return meter.create_histogram( + name=RPC_CLIENT_CALL_DURATION, + description="Measures the duration of an outgoing Remote Procedure Call (RPC).", + unit="s", + ) + + +RPC_CLIENT_DURATION: Final = "rpc.client.duration" +""" +Deprecated: Replaced by `rpc.client.call.duration` with unit `s`. +""" + + +def create_rpc_client_duration(meter: Meter) -> Histogram: + """Deprecated, use `rpc.client.call.duration` instead. Note: the unit also changed from `ms` to `s`""" + return meter.create_histogram( + name=RPC_CLIENT_DURATION, + description="Deprecated, use `rpc.client.call.duration` instead. Note: the unit also changed from `ms` to `s`.", + unit="ms", + ) + + +RPC_CLIENT_REQUEST_SIZE: Final = "rpc.client.request.size" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_client_request_size(meter: Meter) -> Histogram: + """Measures the size of RPC request messages (uncompressed)""" + return meter.create_histogram( + name=RPC_CLIENT_REQUEST_SIZE, + description="Measures the size of RPC request messages (uncompressed).", + unit="By", + ) + + +RPC_CLIENT_REQUESTS_PER_RPC: Final = "rpc.client.requests_per_rpc" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_client_requests_per_rpc(meter: Meter) -> Histogram: + """Measures the number of messages received per RPC""" + return meter.create_histogram( + name=RPC_CLIENT_REQUESTS_PER_RPC, + description="Measures the number of messages received per RPC.", + unit="{count}", + ) + + +RPC_CLIENT_RESPONSE_SIZE: Final = "rpc.client.response.size" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_client_response_size(meter: Meter) -> Histogram: + """Measures the size of RPC response messages (uncompressed)""" + return meter.create_histogram( + name=RPC_CLIENT_RESPONSE_SIZE, + description="Measures the size of RPC response messages (uncompressed).", + unit="By", + ) + + +RPC_CLIENT_RESPONSES_PER_RPC: Final = "rpc.client.responses_per_rpc" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_client_responses_per_rpc(meter: Meter) -> Histogram: + """Measures the number of messages sent per RPC""" + return meter.create_histogram( + name=RPC_CLIENT_RESPONSES_PER_RPC, + description="Measures the number of messages sent per RPC.", + unit="{count}", + ) + + +RPC_SERVER_CALL_DURATION: Final = "rpc.server.call.duration" +""" +Measures the duration of an incoming Remote Procedure Call (RPC) +Instrument: histogram +Unit: s +Note: When this metric is reported alongside an RPC server span, the metric value +SHOULD be the same as the RPC server span duration. +""" + + +def create_rpc_server_call_duration(meter: Meter) -> Histogram: + """Measures the duration of an incoming Remote Procedure Call (RPC)""" + return meter.create_histogram( + name=RPC_SERVER_CALL_DURATION, + description="Measures the duration of an incoming Remote Procedure Call (RPC).", + unit="s", + ) + + +RPC_SERVER_DURATION: Final = "rpc.server.duration" +""" +Deprecated: Replaced by `rpc.server.call.duration` with unit `s`. +""" + + +def create_rpc_server_duration(meter: Meter) -> Histogram: + """Deprecated, use `rpc.server.call.duration` instead. Note: the unit also changed from `ms` to `s`""" + return meter.create_histogram( + name=RPC_SERVER_DURATION, + description="Deprecated, use `rpc.server.call.duration` instead. Note: the unit also changed from `ms` to `s`.", + unit="ms", + ) + + +RPC_SERVER_REQUEST_SIZE: Final = "rpc.server.request.size" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_server_request_size(meter: Meter) -> Histogram: + """Measures the size of RPC request messages (uncompressed)""" + return meter.create_histogram( + name=RPC_SERVER_REQUEST_SIZE, + description="Measures the size of RPC request messages (uncompressed).", + unit="By", + ) + + +RPC_SERVER_REQUESTS_PER_RPC: Final = "rpc.server.requests_per_rpc" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_server_requests_per_rpc(meter: Meter) -> Histogram: + """Measures the number of messages received per RPC""" + return meter.create_histogram( + name=RPC_SERVER_REQUESTS_PER_RPC, + description="Measures the number of messages received per RPC.", + unit="{count}", + ) + + +RPC_SERVER_RESPONSE_SIZE: Final = "rpc.server.response.size" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_server_response_size(meter: Meter) -> Histogram: + """Measures the size of RPC response messages (uncompressed)""" + return meter.create_histogram( + name=RPC_SERVER_RESPONSE_SIZE, + description="Measures the size of RPC response messages (uncompressed).", + unit="By", + ) + + +RPC_SERVER_RESPONSES_PER_RPC: Final = "rpc.server.responses_per_rpc" +""" +Deprecated: Removed, no replacement at this time. +""" + + +def create_rpc_server_responses_per_rpc(meter: Meter) -> Histogram: + """Measures the number of messages sent per RPC""" + return meter.create_histogram( + name=RPC_SERVER_RESPONSES_PER_RPC, + description="Measures the number of messages sent per RPC.", + unit="{count}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py new file mode 100644 index 00000000000..f899111910e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py @@ -0,0 +1,835 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter + +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +SYSTEM_CPU_FREQUENCY: Final = "system.cpu.frequency" +""" +Operating frequency of the logical CPU in Hertz +Instrument: gauge +Unit: Hz +""" + + +def create_system_cpu_frequency(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Operating frequency of the logical CPU in Hertz""" + return meter.create_observable_gauge( + name=SYSTEM_CPU_FREQUENCY, + callbacks=callbacks, + description="Operating frequency of the logical CPU in Hertz.", + unit="Hz", + ) + + +SYSTEM_CPU_LOGICAL_COUNT: Final = "system.cpu.logical.count" +""" +Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking +Instrument: updowncounter +Unit: {cpu} +Note: Calculated by multiplying the number of sockets by the number of cores per socket, and then by the number of threads per core. +""" + + +def create_system_cpu_logical_count(meter: Meter) -> UpDownCounter: + """Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking""" + return meter.create_up_down_counter( + name=SYSTEM_CPU_LOGICAL_COUNT, + description="Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking.", + unit="{cpu}", + ) + + +SYSTEM_CPU_PHYSICAL_COUNT: Final = "system.cpu.physical.count" +""" +Reports the number of actual physical processor cores on the hardware +Instrument: updowncounter +Unit: {cpu} +Note: Calculated by multiplying the number of sockets by the number of cores per socket. +""" + + +def create_system_cpu_physical_count(meter: Meter) -> UpDownCounter: + """Reports the number of actual physical processor cores on the hardware""" + return meter.create_up_down_counter( + name=SYSTEM_CPU_PHYSICAL_COUNT, + description="Reports the number of actual physical processor cores on the hardware.", + unit="{cpu}", + ) + + +SYSTEM_CPU_TIME: Final = "system.cpu.time" +""" +Seconds each logical CPU spent on each mode +Instrument: counter +Unit: s +""" + + +def create_system_cpu_time(meter: Meter) -> Counter: + """Seconds each logical CPU spent on each mode""" + return meter.create_counter( + name=SYSTEM_CPU_TIME, + description="Seconds each logical CPU spent on each mode.", + unit="s", + ) + + +SYSTEM_CPU_UTILIZATION: Final = "system.cpu.utilization" +""" +For each logical CPU, the utilization is calculated as the change in cumulative CPU time (cpu.time) over a measurement interval, divided by the elapsed time +Instrument: gauge +Unit: 1 +""" + + +def create_system_cpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """For each logical CPU, the utilization is calculated as the change in cumulative CPU time (cpu.time) over a measurement interval, divided by the elapsed time""" + return meter.create_observable_gauge( + name=SYSTEM_CPU_UTILIZATION, + callbacks=callbacks, + description="For each logical CPU, the utilization is calculated as the change in cumulative CPU time (cpu.time) over a measurement interval, divided by the elapsed time.", + unit="1", + ) + + +SYSTEM_DISK_IO: Final = "system.disk.io" +""" +Disk bytes transferred +Instrument: counter +Unit: By +""" + + +def create_system_disk_io(meter: Meter) -> Counter: + """Disk bytes transferred""" + return meter.create_counter( + name=SYSTEM_DISK_IO, + description="Disk bytes transferred.", + unit="By", + ) + + +SYSTEM_DISK_IO_TIME: Final = "system.disk.io_time" +""" +Time disk spent activated +Instrument: counter +Unit: s +Note: The real elapsed time ("wall clock") used in the I/O path (time from operations running in parallel are not counted). Measured as: + +- Linux: Field 13 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) +- Windows: The complement of + ["Disk\\% Idle Time"](https://learn.microsoft.com/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) + performance counter: `uptime * (100 - "Disk\\% Idle Time") / 100`. +""" + + +def create_system_disk_io_time(meter: Meter) -> Counter: + """Time disk spent activated""" + return meter.create_counter( + name=SYSTEM_DISK_IO_TIME, + description="Time disk spent activated.", + unit="s", + ) + + +SYSTEM_DISK_LIMIT: Final = "system.disk.limit" +""" +The total storage capacity of the disk +Instrument: updowncounter +Unit: By +""" + + +def create_system_disk_limit(meter: Meter) -> UpDownCounter: + """The total storage capacity of the disk""" + return meter.create_up_down_counter( + name=SYSTEM_DISK_LIMIT, + description="The total storage capacity of the disk.", + unit="By", + ) + + +SYSTEM_DISK_MERGED: Final = "system.disk.merged" +""" +The number of disk reads/writes merged into single physical disk access operations +Instrument: counter +Unit: {operation} +""" + + +def create_system_disk_merged(meter: Meter) -> Counter: + """The number of disk reads/writes merged into single physical disk access operations""" + return meter.create_counter( + name=SYSTEM_DISK_MERGED, + description="The number of disk reads/writes merged into single physical disk access operations.", + unit="{operation}", + ) + + +SYSTEM_DISK_OPERATION_TIME: Final = "system.disk.operation_time" +""" +Sum of the time each operation took to complete +Instrument: counter +Unit: s +Note: Because it is the sum of time each request took, parallel-issued requests each contribute to make the count grow. Measured as: + +- Linux: Fields 7 & 11 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) +- Windows: "Avg. Disk sec/Read" perf counter multiplied by "Disk Reads/sec" perf counter (similar for Writes). +""" + + +def create_system_disk_operation_time(meter: Meter) -> Counter: + """Sum of the time each operation took to complete""" + return meter.create_counter( + name=SYSTEM_DISK_OPERATION_TIME, + description="Sum of the time each operation took to complete.", + unit="s", + ) + + +SYSTEM_DISK_OPERATIONS: Final = "system.disk.operations" +""" +Disk operations count +Instrument: counter +Unit: {operation} +""" + + +def create_system_disk_operations(meter: Meter) -> Counter: + """Disk operations count""" + return meter.create_counter( + name=SYSTEM_DISK_OPERATIONS, + description="Disk operations count.", + unit="{operation}", + ) + + +SYSTEM_FILESYSTEM_LIMIT: Final = "system.filesystem.limit" +""" +The total storage capacity of the filesystem +Instrument: updowncounter +Unit: By +""" + + +def create_system_filesystem_limit(meter: Meter) -> UpDownCounter: + """The total storage capacity of the filesystem""" + return meter.create_up_down_counter( + name=SYSTEM_FILESYSTEM_LIMIT, + description="The total storage capacity of the filesystem.", + unit="By", + ) + + +SYSTEM_FILESYSTEM_LOCK_COUNT: Final = "system.filesystem.lock.count" +""" +Filesystem lock counts +Instrument: updowncounter +Unit: {lock} +""" + + +def create_system_filesystem_lock_count(meter: Meter) -> UpDownCounter: + """Filesystem lock counts""" + return meter.create_up_down_counter( + name=SYSTEM_FILESYSTEM_LOCK_COUNT, + description="Filesystem lock counts.", + unit="{lock}", + ) + + +SYSTEM_FILESYSTEM_USAGE: Final = "system.filesystem.usage" +""" +Reports a filesystem's space usage across different states +Instrument: updowncounter +Unit: By +Note: The sum of all `system.filesystem.usage` values over the different `system.filesystem.state` attributes +SHOULD equal the total storage capacity of the filesystem, that is `system.filesystem.limit`. +""" + + +def create_system_filesystem_usage(meter: Meter) -> UpDownCounter: + """Reports a filesystem's space usage across different states""" + return meter.create_up_down_counter( + name=SYSTEM_FILESYSTEM_USAGE, + description="Reports a filesystem's space usage across different states.", + unit="By", + ) + + +SYSTEM_FILESYSTEM_UTILIZATION: Final = "system.filesystem.utilization" +""" +Fraction of filesystem bytes used +Instrument: gauge +Unit: 1 +""" + + +def create_system_filesystem_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Fraction of filesystem bytes used""" + return meter.create_observable_gauge( + name=SYSTEM_FILESYSTEM_UTILIZATION, + callbacks=callbacks, + description="Fraction of filesystem bytes used.", + unit="1", + ) + + +SYSTEM_LINUX_MEMORY_AVAILABLE: Final = "system.linux.memory.available" +""" +Deprecated: Replaced by `system.memory.linux.available`. +""" + + +def create_system_linux_memory_available(meter: Meter) -> Counter: + """The number of packets transferred""" + return meter.create_counter( + name=SYSTEM_LINUX_MEMORY_AVAILABLE, + description="The number of packets transferred.", + unit="{packet}", + ) + + +SYSTEM_LINUX_MEMORY_SLAB_USAGE: Final = "system.linux.memory.slab.usage" +""" +Deprecated: Replaced by `system.memory.linux.slab.usage`. +""" + + +def create_system_linux_memory_slab_usage(meter: Meter) -> Counter: + """The number of packets transferred""" + return meter.create_counter( + name=SYSTEM_LINUX_MEMORY_SLAB_USAGE, + description="The number of packets transferred.", + unit="{packet}", + ) + + +SYSTEM_MEMORY_LIMIT: Final = "system.memory.limit" +""" +Total virtual memory available in the system +Instrument: updowncounter +Unit: By +""" + + +def create_system_memory_limit(meter: Meter) -> UpDownCounter: + """Total virtual memory available in the system""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LIMIT, + description="Total virtual memory available in the system.", + unit="By", + ) + + +SYSTEM_MEMORY_LINUX_AVAILABLE: Final = "system.memory.linux.available" +""" +An estimate of how much memory is available for starting new applications, without causing swapping +Instrument: updowncounter +Unit: By +Note: This is an alternative to `system.memory.usage` metric with `state=free`. +Linux starting from 3.14 exports "available" memory. It takes "free" memory as a baseline, and then factors in kernel-specific values. +This is supposed to be more accurate than just "free" memory. +For reference, see the calculations [here](https://superuser.com/a/980821). +See also `MemAvailable` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html). +""" + + +def create_system_memory_linux_available(meter: Meter) -> UpDownCounter: + """An estimate of how much memory is available for starting new applications, without causing swapping""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_AVAILABLE, + description="An estimate of how much memory is available for starting new applications, without causing swapping.", + unit="By", + ) + + +SYSTEM_MEMORY_LINUX_HUGEPAGES_LIMIT: Final = "system.memory.linux.hugepages.limit" +""" +Total number of hugepages available +Instrument: updowncounter +Unit: {page} +""" + + +def create_system_memory_linux_hugepages_limit(meter: Meter) -> UpDownCounter: + """Total number of hugepages available""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_HUGEPAGES_LIMIT, + description="Total number of hugepages available.", + unit="{page}", + ) + + +SYSTEM_MEMORY_LINUX_HUGEPAGES_PAGE_SIZE: Final = "system.memory.linux.hugepages.page_size" +""" +System hugepage size in bytes +Instrument: updowncounter +Unit: By +""" + + +def create_system_memory_linux_hugepages_page_size(meter: Meter) -> UpDownCounter: + """System hugepage size in bytes""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_HUGEPAGES_PAGE_SIZE, + description="System hugepage size in bytes.", + unit="By", + ) + + +SYSTEM_MEMORY_LINUX_HUGEPAGES_RESERVED: Final = "system.memory.linux.hugepages.reserved" +""" +Number of reserved hugepages +Instrument: updowncounter +Unit: {page} +Note: Hugepages for which a commitment to allocate has been made, but no allocation has yet been made. +This is reported as a separate metric rather than a `usage` state because reserved pages are already counted in `free` pages. +They represent a subset of free pages that cannot be used for non-reserved allocations. +""" + + +def create_system_memory_linux_hugepages_reserved(meter: Meter) -> UpDownCounter: + """Number of reserved hugepages""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_HUGEPAGES_RESERVED, + description="Number of reserved hugepages.", + unit="{page}", + ) + + +SYSTEM_MEMORY_LINUX_HUGEPAGES_SURPLUS: Final = "system.memory.linux.hugepages.surplus" +""" +Number of surplus hugepages +Instrument: updowncounter +Unit: {page} +Note: Overcommitted hugepages beyond the persistent pool. +This is reported as a separate metric rather than a `usage` state because surplus pages can be in either `used` or `free` state. +Including them in `usage` would break the convention that `usage` states sum to the `limit`. +""" + + +def create_system_memory_linux_hugepages_surplus(meter: Meter) -> UpDownCounter: + """Number of surplus hugepages""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_HUGEPAGES_SURPLUS, + description="Number of surplus hugepages.", + unit="{page}", + ) + + +SYSTEM_MEMORY_LINUX_HUGEPAGES_USAGE: Final = "system.memory.linux.hugepages.usage" +""" +Number of hugepages in use by state +Instrument: updowncounter +Unit: {page} +""" + + +def create_system_memory_linux_hugepages_usage(meter: Meter) -> UpDownCounter: + """Number of hugepages in use by state""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_HUGEPAGES_USAGE, + description="Number of hugepages in use by state.", + unit="{page}", + ) + + +SYSTEM_MEMORY_LINUX_HUGEPAGES_UTILIZATION: Final = "system.memory.linux.hugepages.utilization" +""" +Percentage of hugepages in use by state +Instrument: gauge +Unit: 1 +""" + + +def create_system_memory_linux_hugepages_utilization( + meter: Meter, callbacks: Sequence[CallbackT] | None +) -> ObservableGauge: + """Percentage of hugepages in use by state""" + return meter.create_observable_gauge( + name=SYSTEM_MEMORY_LINUX_HUGEPAGES_UTILIZATION, + callbacks=callbacks, + description="Percentage of hugepages in use by state.", + unit="1", + ) + + +SYSTEM_MEMORY_LINUX_SHARED: Final = "system.memory.linux.shared" +""" +Shared memory used (mostly by tmpfs) +Instrument: updowncounter +Unit: By +Note: Equivalent of `shared` from [`free` command](https://man7.org/linux/man-pages/man1/free.1.html) or +`Shmem` from [`/proc/meminfo`](https://man7.org/linux/man-pages/man5/proc.5.html)". +""" + + +def create_system_memory_linux_shared(meter: Meter) -> UpDownCounter: + """Shared memory used (mostly by tmpfs)""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_SHARED, + description="Shared memory used (mostly by tmpfs).", + unit="By", + ) + + +SYSTEM_MEMORY_LINUX_SLAB_USAGE: Final = "system.memory.linux.slab.usage" +""" +Reports the memory used by the Linux kernel for managing caches of frequently used objects +Instrument: updowncounter +Unit: By +Note: The sum over the `reclaimable` and `unreclaimable` state values in `memory.linux.slab.usage` SHOULD be equal to the total slab memory available on the system. +Note that the total slab memory is not constant and may vary over time. +See also the [Slab allocator](https://blogs.oracle.com/linux/post/understanding-linux-kernel-memory-statistics) and `Slab` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html). +""" + + +def create_system_memory_linux_slab_usage(meter: Meter) -> UpDownCounter: + """Reports the memory used by the Linux kernel for managing caches of frequently used objects""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_LINUX_SLAB_USAGE, + description="Reports the memory used by the Linux kernel for managing caches of frequently used objects.", + unit="By", + ) + + +SYSTEM_MEMORY_SHARED: Final = "system.memory.shared" +""" +Deprecated: Replaced by `system.memory.linux.shared`. +""" + + +def create_system_memory_shared(meter: Meter) -> UpDownCounter: + """Deprecated, use `system.memory.linux.shared` instead""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_SHARED, + description="Deprecated, use `system.memory.linux.shared` instead.", + unit="By", + ) + + +SYSTEM_MEMORY_USAGE: Final = "system.memory.usage" +""" +Reports memory in use by state +Instrument: updowncounter +Unit: By +""" + + +def create_system_memory_usage(meter: Meter) -> UpDownCounter: + """Reports memory in use by state""" + return meter.create_up_down_counter( + name=SYSTEM_MEMORY_USAGE, + description="Reports memory in use by state.", + unit="By", + ) + + +SYSTEM_MEMORY_UTILIZATION: Final = "system.memory.utilization" +""" +Percentage of memory bytes in use +Instrument: gauge +Unit: 1 +""" + + +def create_system_memory_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Percentage of memory bytes in use""" + return meter.create_observable_gauge( + name=SYSTEM_MEMORY_UTILIZATION, + callbacks=callbacks, + description="Percentage of memory bytes in use.", + unit="1", + ) + + +SYSTEM_NETWORK_CONNECTION_COUNT: Final = "system.network.connection.count" +""" +The number of connections +Instrument: updowncounter +Unit: {connection} +""" + + +def create_system_network_connection_count(meter: Meter) -> UpDownCounter: + """The number of connections""" + return meter.create_up_down_counter( + name=SYSTEM_NETWORK_CONNECTION_COUNT, + description="The number of connections.", + unit="{connection}", + ) + + +SYSTEM_NETWORK_CONNECTIONS: Final = "system.network.connections" +""" +Deprecated: Replaced by `system.network.connection.count`. +""" + + +def create_system_network_connections(meter: Meter) -> UpDownCounter: + """Deprecated, use `system.network.connection.count` instead""" + return meter.create_up_down_counter( + name=SYSTEM_NETWORK_CONNECTIONS, + description="Deprecated, use `system.network.connection.count` instead.", + unit="{connection}", + ) + + +SYSTEM_NETWORK_DROPPED: Final = "system.network.dropped" +""" +Deprecated: Replaced by `system.network.packet.dropped`. +""" + + +def create_system_network_dropped(meter: Meter) -> Counter: + """Count of packets that are dropped or discarded even though there was no error""" + return meter.create_counter( + name=SYSTEM_NETWORK_DROPPED, + description="Count of packets that are dropped or discarded even though there was no error.", + unit="{packet}", + ) + + +SYSTEM_NETWORK_ERRORS: Final = "system.network.errors" +""" +Count of network errors detected +Instrument: counter +Unit: {error} +Note: Measured as: + +- Linux: the `errs` column in `/proc/net/dev` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). +- Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2). +""" + + +def create_system_network_errors(meter: Meter) -> Counter: + """Count of network errors detected""" + return meter.create_counter( + name=SYSTEM_NETWORK_ERRORS, + description="Count of network errors detected.", + unit="{error}", + ) + + +SYSTEM_NETWORK_IO: Final = "system.network.io" +""" +The number of bytes transmitted and received +Instrument: counter +Unit: By +""" + + +def create_system_network_io(meter: Meter) -> Counter: + """The number of bytes transmitted and received""" + return meter.create_counter( + name=SYSTEM_NETWORK_IO, + description="The number of bytes transmitted and received.", + unit="By", + ) + + +SYSTEM_NETWORK_PACKET_COUNT: Final = "system.network.packet.count" +""" +The number of packets transferred +Instrument: counter +Unit: {packet} +""" + + +def create_system_network_packet_count(meter: Meter) -> Counter: + """The number of packets transferred""" + return meter.create_counter( + name=SYSTEM_NETWORK_PACKET_COUNT, + description="The number of packets transferred.", + unit="{packet}", + ) + + +SYSTEM_NETWORK_PACKET_DROPPED: Final = "system.network.packet.dropped" +""" +Count of packets that are dropped or discarded even though there was no error +Instrument: counter +Unit: {packet} +Note: Measured as: + +- Linux: the `drop` column in `/proc/net/dev` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)) +- Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) + from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2). +""" + + +def create_system_network_packet_dropped(meter: Meter) -> Counter: + """Count of packets that are dropped or discarded even though there was no error""" + return meter.create_counter( + name=SYSTEM_NETWORK_PACKET_DROPPED, + description="Count of packets that are dropped or discarded even though there was no error.", + unit="{packet}", + ) + + +SYSTEM_NETWORK_PACKETS: Final = "system.network.packets" +""" +Deprecated: Replaced by `system.network.packet.count`. +""" + + +def create_system_network_packets(meter: Meter) -> Counter: + """The number of packets transferred""" + return meter.create_counter( + name=SYSTEM_NETWORK_PACKETS, + description="The number of packets transferred.", + unit="{packet}", + ) + + +SYSTEM_PAGING_FAULTS: Final = "system.paging.faults" +""" +The number of page faults +Instrument: counter +Unit: {fault} +""" + + +def create_system_paging_faults(meter: Meter) -> Counter: + """The number of page faults""" + return meter.create_counter( + name=SYSTEM_PAGING_FAULTS, + description="The number of page faults.", + unit="{fault}", + ) + + +SYSTEM_PAGING_OPERATIONS: Final = "system.paging.operations" +""" +The number of paging operations +Instrument: counter +Unit: {operation} +""" + + +def create_system_paging_operations(meter: Meter) -> Counter: + """The number of paging operations""" + return meter.create_counter( + name=SYSTEM_PAGING_OPERATIONS, + description="The number of paging operations.", + unit="{operation}", + ) + + +SYSTEM_PAGING_USAGE: Final = "system.paging.usage" +""" +UNIX swap or windows pagefile usage +Instrument: updowncounter +Unit: By +""" + + +def create_system_paging_usage(meter: Meter) -> UpDownCounter: + """UNIX swap or windows pagefile usage""" + return meter.create_up_down_counter( + name=SYSTEM_PAGING_USAGE, + description="UNIX swap or windows pagefile usage.", + unit="By", + ) + + +SYSTEM_PAGING_UTILIZATION: Final = "system.paging.utilization" +""" +Swap (UNIX) or pagefile (windows) utilization +Instrument: gauge +Unit: 1 +""" + + +def create_system_paging_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Swap (UNIX) or pagefile (windows) utilization""" + return meter.create_observable_gauge( + name=SYSTEM_PAGING_UTILIZATION, + callbacks=callbacks, + description="Swap (UNIX) or pagefile (windows) utilization.", + unit="1", + ) + + +SYSTEM_PROCESS_COUNT: Final = "system.process.count" +""" +Total number of processes in each state +Instrument: updowncounter +Unit: {process} +""" + + +def create_system_process_count(meter: Meter) -> UpDownCounter: + """Total number of processes in each state""" + return meter.create_up_down_counter( + name=SYSTEM_PROCESS_COUNT, + description="Total number of processes in each state.", + unit="{process}", + ) + + +SYSTEM_PROCESS_CREATED: Final = "system.process.created" +""" +Total number of processes created over uptime of the host +Instrument: counter +Unit: {process} +""" + + +def create_system_process_created(meter: Meter) -> Counter: + """Total number of processes created over uptime of the host""" + return meter.create_counter( + name=SYSTEM_PROCESS_CREATED, + description="Total number of processes created over uptime of the host.", + unit="{process}", + ) + + +SYSTEM_PROCESS_LIMIT: Final = "system.process.limit" +""" +The maximum number of concurrent processes/tasks allowed by the operating system +Instrument: updowncounter +Unit: {thread} +Note: On Linux, this corresponds to `/proc/sys/kernel/pid_max` or `/proc/sys/kernel/threads-max`. +A per-user process limit may also be retrieved via `getrlimit(RLIMIT_NPROC)`. +On BSD-like systems, this corresponds to `sysctl kern.maxproc`. This metric is unsupported on Windows systems. +""" + + +def create_system_process_limit(meter: Meter) -> UpDownCounter: + """The maximum number of concurrent processes/tasks allowed by the operating system""" + return meter.create_up_down_counter( + name=SYSTEM_PROCESS_LIMIT, + description="The maximum number of concurrent processes/tasks allowed by the operating system.", + unit="{thread}", + ) + + +SYSTEM_UPTIME: Final = "system.uptime" +""" +The time the system has been running +Instrument: gauge +Unit: s +Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. +The actual accuracy would depend on the instrumentation and operating system. +""" + + +def create_system_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The time the system has been running""" + return meter.create_observable_gauge( + name=SYSTEM_UPTIME, + callbacks=callbacks, + description="The time the system has been running.", + unit="s", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py new file mode 100644 index 00000000000..53f80512db0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py @@ -0,0 +1,193 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from collections.abc import Callable, Generator, Iterable, Sequence +from typing import Final + +from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Meter, ObservableGauge, Observation, UpDownCounter + +# pylint: disable=invalid-name +CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] + + +VCS_CHANGE_COUNT: Final = "vcs.change.count" +""" +The number of changes (pull requests/merge requests/changelists) in a repository, categorized by their state (e.g. open or merged) +Instrument: updowncounter +Unit: {change} +""" + + +def create_vcs_change_count(meter: Meter) -> UpDownCounter: + """The number of changes (pull requests/merge requests/changelists) in a repository, categorized by their state (e.g. open or merged)""" + return meter.create_up_down_counter( + name=VCS_CHANGE_COUNT, + description="The number of changes (pull requests/merge requests/changelists) in a repository, categorized by their state (e.g. open or merged).", + unit="{change}", + ) + + +VCS_CHANGE_DURATION: Final = "vcs.change.duration" +""" +The time duration a change (pull request/merge request/changelist) has been in a given state +Instrument: gauge +Unit: s +""" + + +def create_vcs_change_duration(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The time duration a change (pull request/merge request/changelist) has been in a given state""" + return meter.create_observable_gauge( + name=VCS_CHANGE_DURATION, + callbacks=callbacks, + description="The time duration a change (pull request/merge request/changelist) has been in a given state.", + unit="s", + ) + + +VCS_CHANGE_TIME_TO_APPROVAL: Final = "vcs.change.time_to_approval" +""" +The amount of time since its creation it took a change (pull request/merge request/changelist) to get the first approval +Instrument: gauge +Unit: s +""" + + +def create_vcs_change_time_to_approval(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The amount of time since its creation it took a change (pull request/merge request/changelist) to get the first approval""" + return meter.create_observable_gauge( + name=VCS_CHANGE_TIME_TO_APPROVAL, + callbacks=callbacks, + description="The amount of time since its creation it took a change (pull request/merge request/changelist) to get the first approval.", + unit="s", + ) + + +VCS_CHANGE_TIME_TO_MERGE: Final = "vcs.change.time_to_merge" +""" +The amount of time since its creation it took a change (pull request/merge request/changelist) to get merged into the target(base) ref +Instrument: gauge +Unit: s +""" + + +def create_vcs_change_time_to_merge(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The amount of time since its creation it took a change (pull request/merge request/changelist) to get merged into the target(base) ref""" + return meter.create_observable_gauge( + name=VCS_CHANGE_TIME_TO_MERGE, + callbacks=callbacks, + description="The amount of time since its creation it took a change (pull request/merge request/changelist) to get merged into the target(base) ref.", + unit="s", + ) + + +VCS_CONTRIBUTOR_COUNT: Final = "vcs.contributor.count" +""" +The number of unique contributors to a repository +Instrument: gauge +Unit: {contributor} +""" + + +def create_vcs_contributor_count(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The number of unique contributors to a repository""" + return meter.create_observable_gauge( + name=VCS_CONTRIBUTOR_COUNT, + callbacks=callbacks, + description="The number of unique contributors to a repository.", + unit="{contributor}", + ) + + +VCS_REF_COUNT: Final = "vcs.ref.count" +""" +The number of refs of type branch or tag in a repository +Instrument: updowncounter +Unit: {ref} +""" + + +def create_vcs_ref_count(meter: Meter) -> UpDownCounter: + """The number of refs of type branch or tag in a repository""" + return meter.create_up_down_counter( + name=VCS_REF_COUNT, + description="The number of refs of type branch or tag in a repository.", + unit="{ref}", + ) + + +VCS_REF_LINES_DELTA: Final = "vcs.ref.lines_delta" +""" +The number of lines added/removed in a ref (branch) relative to the ref from the `vcs.ref.base.name` attribute +Instrument: gauge +Unit: {line} +Note: This metric should be reported for each `vcs.line_change.type` value. For example if a ref added 3 lines and removed 2 lines, +instrumentation SHOULD report two measurements: 3 and 2 (both positive numbers). +If number of lines added/removed should be calculated from the start of time, then `vcs.ref.base.name` SHOULD be set to an empty string. +""" + + +def create_vcs_ref_lines_delta(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The number of lines added/removed in a ref (branch) relative to the ref from the `vcs.ref.base.name` attribute""" + return meter.create_observable_gauge( + name=VCS_REF_LINES_DELTA, + callbacks=callbacks, + description="The number of lines added/removed in a ref (branch) relative to the ref from the `vcs.ref.base.name` attribute.", + unit="{line}", + ) + + +VCS_REF_REVISIONS_DELTA: Final = "vcs.ref.revisions_delta" +""" +The number of revisions (commits) a ref (branch) is ahead/behind the branch from the `vcs.ref.base.name` attribute +Instrument: gauge +Unit: {revision} +Note: This metric should be reported for each `vcs.revision_delta.direction` value. For example if branch `a` is 3 commits behind and 2 commits ahead of `trunk`, +instrumentation SHOULD report two measurements: 3 and 2 (both positive numbers) and `vcs.ref.base.name` is set to `trunk`. +""" + + +def create_vcs_ref_revisions_delta(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """The number of revisions (commits) a ref (branch) is ahead/behind the branch from the `vcs.ref.base.name` attribute""" + return meter.create_observable_gauge( + name=VCS_REF_REVISIONS_DELTA, + callbacks=callbacks, + description="The number of revisions (commits) a ref (branch) is ahead/behind the branch from the `vcs.ref.base.name` attribute.", + unit="{revision}", + ) + + +VCS_REF_TIME: Final = "vcs.ref.time" +""" +Time a ref (branch) created from the default branch (trunk) has existed. The `ref.type` attribute will always be `branch` +Instrument: gauge +Unit: s +""" + + +def create_vcs_ref_time(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: + """Time a ref (branch) created from the default branch (trunk) has existed. The `ref.type` attribute will always be `branch`""" + return meter.create_observable_gauge( + name=VCS_REF_TIME, + callbacks=callbacks, + description="Time a ref (branch) created from the default branch (trunk) has existed. The `ref.type` attribute will always be `branch`.", + unit="s", + ) + + +VCS_REPOSITORY_COUNT: Final = "vcs.repository.count" +""" +The number of repositories in an organization +Instrument: updowncounter +Unit: {repository} +""" + + +def create_vcs_repository_count(meter: Meter) -> UpDownCounter: + """The number of repositories in an organization""" + return meter.create_up_down_counter( + name=VCS_REPOSITORY_COUNT, + description="The number of repositories in an organization.", + unit="{repository}", + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py new file mode 100644 index 00000000000..cf7bb336294 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py @@ -0,0 +1,16 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +CLIENT_ADDRESS: Final = "client.address" +""" +Client address - domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. +Note: When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. +""" + +CLIENT_PORT: Final = "client.port" +""" +Client port number. +Note: When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py new file mode 100644 index 00000000000..142fb957948 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py @@ -0,0 +1,44 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +CODE_COLUMN_NUMBER: Final = "code.column.number" +""" +The column number in `code.file.path` best representing the operation. It SHOULD point within the code unit named in `code.function.name`. This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Line'. This constraint is imposed to prevent redundancy and maintain data integrity. +""" + +CODE_FILE_PATH: Final = "code.file.path" +""" +The source code filename that identifies the code unit as uniquely as possible (preferably an absolute file path). This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Function'. This constraint is imposed to prevent redundancy and maintain data integrity. +""" + +CODE_FUNCTION_NAME: Final = "code.function.name" +""" +The method or function fully-qualified name without arguments. The value should fit the natural representation of the language runtime, which is also likely the same used within `code.stacktrace` attribute value. This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Function'. This constraint is imposed to prevent redundancy and maintain data integrity. +Note: Values and format depends on each language runtime, thus it is impossible to provide an exhaustive list of examples. +The values are usually the same (or prefixes of) the ones found in native stack trace representation stored in +`code.stacktrace` without information on arguments. + +Examples: + +* Java method: `com.example.MyHttpService.serveRequest` +* Java anonymous class method: `com.mycompany.Main$1.myMethod` +* Java lambda method: `com.mycompany.Main$$Lambda/0x0000748ae4149c00.myMethod` +* PHP function: `GuzzleHttp\\Client::transfer` +* Go function: `github.com/my/repo/pkg.foo.func5` +* Elixir: `OpenTelemetry.Ctx.new` +* Erlang: `opentelemetry_ctx:new` +* Rust: `playground::my_module::my_cool_func` +* C function: `fopen`. +""" + +CODE_LINE_NUMBER: Final = "code.line.number" +""" +The line number in `code.file.path` best representing the operation. It SHOULD point within the code unit named in `code.function.name`. This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Line'. This constraint is imposed to prevent redundancy and maintain data integrity. +""" + +CODE_STACKTRACE: Final = "code.stacktrace" +""" +A stacktrace as a string in the natural representation for the language runtime. The representation is identical to [`exception.stacktrace`](/docs/exceptions/exceptions-spans.md#stacktrace-representation). This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Location'. This constraint is imposed to prevent redundancy and maintain data integrity. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py new file mode 100644 index 00000000000..cc3739771fb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py @@ -0,0 +1,25 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +CONTAINER_ID: Final = "container.id" +""" +Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/containers/run/#container-identification). The UUID might be abbreviated. +""" + +CONTAINER_IMAGE_NAME: Final = "container.image.name" +""" +Name of the image the container was built on. +""" + +CONTAINER_IMAGE_REPO_DIGESTS: Final = "container.image.repo_digests" +""" +Repository digests of the container image as provided by the container runtime. +Note: [Docker](https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. +""" + +CONTAINER_IMAGE_TAGS: Final = "container.image.tags" +""" +Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py new file mode 100644 index 00000000000..26e7b483a17 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py @@ -0,0 +1,134 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +DB_COLLECTION_NAME: Final = "db.collection.name" +""" +The name of a collection (table, container) within the database. +Note: It is RECOMMENDED to capture the value as provided by the application +without attempting to do any case normalization. + +The collection name SHOULD NOT be extracted from `db.query.text`, +when the database system supports query text with multiple collections +in non-batch operations. + +For batch operations, if the individual operations are known to have the same +collection name then that collection name SHOULD be used. +""" + +DB_NAMESPACE: Final = "db.namespace" +""" +The name of the database, fully qualified within the server address and port. +Note: If a database system has multiple namespace components, they SHOULD be concatenated from the most general to the most specific namespace component, using `|` as a separator between the components. Any missing components (and their associated separators) SHOULD be omitted. +Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. +It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. +""" + +DB_OPERATION_BATCH_SIZE: Final = "db.operation.batch.size" +""" +The number of database operations included in a batch operation. +Note: Except for empty batch requests described below, a batch operation contains two +or more database operations explicitly submitted as separate operations in a single +client call, protocol message, or database command. + +Requests to batch APIs that contain only one operation SHOULD be modeled as single +operations, not as batch operations. + +A database call is not a batch operation solely because one operation accepts +multiple operands, such as keys, rows, documents, points, or other data elements, +including Redis [`MGET`](https://redis.io/docs/latest/commands/mget/) with +multiple keys. + +In batch APIs that execute the same parameterized operation with parameter sets, +each parameter set represents one database operation for determining whether the +request is a batch operation. Requests with only one parameter set SHOULD be modeled +as single operations, not as batch operations. + +`db.operation.batch.size` SHOULD be set to the number of operations in the batch. +It SHOULD NOT be set for non-batch operations. + +A request to execute a batch operation with no operations SHOULD also be treated +as a batch operation, and `db.operation.batch.size` SHOULD be set to `0`. +""" + +DB_OPERATION_NAME: Final = "db.operation.name" +""" +The name of the operation or command being executed. +Note: It is RECOMMENDED to capture the value as provided by the application +without attempting to do any case normalization. + +The operation name SHOULD NOT be extracted from `db.query.text`, +when the database system supports query text with multiple operations +in non-batch operations. + +If spaces can occur in the operation name, multiple consecutive spaces +SHOULD be normalized to a single space. + +For batch operations, if the individual operations are known to have the same operation name +then that operation name SHOULD be used prepended by `BATCH `, +otherwise `db.operation.name` SHOULD be `BATCH` or some other database +system specific term if more applicable. +""" + +DB_QUERY_SUMMARY: Final = "db.query.summary" +""" +Low cardinality summary of a database query. +Note: The query summary describes a class of database queries and is useful +as a grouping key, especially when analyzing telemetry for database +calls involving complex queries. + +Summary may be available to the instrumentation through +instrumentation hooks or other means. If it is not available, instrumentations +that support query parsing SHOULD generate a summary following +[Generating query summary](/docs/db/database-spans.md#generating-a-summary-of-the-query) +section. + +For batch operations, if the individual operations are known to have the same query summary +then that query summary SHOULD be used prepended by `BATCH `, +otherwise `db.query.summary` SHOULD be `BATCH` or some other database +system specific term if more applicable. +""" + +DB_QUERY_TEXT: Final = "db.query.text" +""" +The database query being executed. +Note: For sanitization see [Sanitization of `db.query.text`](/docs/db/database-spans.md#sanitization-of-dbquerytext). +For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. +Parameterized query text SHOULD NOT be sanitized. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. +""" + +DB_RESPONSE_STATUS_CODE: Final = "db.response.status_code" +""" +Database response status code. +Note: The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. +Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. +""" + +DB_STORED_PROCEDURE_NAME: Final = "db.stored_procedure.name" +""" +The name of a stored procedure within the database. +Note: It is RECOMMENDED to capture the value as provided by the application +without attempting to do any case normalization. + +For batch operations, if the individual operations are known to have the same +stored procedure name then that stored procedure name SHOULD be used. +""" + +DB_SYSTEM_NAME: Final = "db.system.name" +""" +The database management system (DBMS) product as identified by the client instrumentation. +Note: The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system.name` is set to `postgresql` based on the instrumentation's best knowledge. +""" + + +class DbSystemNameValues(Enum): + MARIADB = "mariadb" + """[MariaDB](https://mariadb.org/).""" + MICROSOFT_SQL_SERVER = "microsoft.sql_server" + """[Microsoft SQL Server](https://www.microsoft.com/sql-server).""" + MYSQL = "mysql" + """[MySQL](https://www.mysql.com/).""" + POSTGRESQL = "postgresql" + """[PostgreSQL](https://www.postgresql.org/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py new file mode 100644 index 00000000000..338f935e74b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py @@ -0,0 +1,28 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +DEPLOYMENT_ENVIRONMENT_NAME: Final = "deployment.environment.name" +""" +Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). +Note: `deployment.environment.name` does not affect the uniqueness constraints defined through +the `service.namespace`, `service.name` and `service.instance.id` resource attributes. +This implies that resources carrying the following attribute combinations MUST be +considered to be identifying the same service: + +- `service.name=frontend`, `deployment.environment.name=production` +- `service.name=frontend`, `deployment.environment.name=staging`. +""" + + +class DeploymentEnvironmentNameValues(Enum): + PRODUCTION = "production" + """Production environment.""" + STAGING = "staging" + """Staging environment.""" + TEST = "test" + """Testing environment.""" + DEVELOPMENT = "development" + """Development environment.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py new file mode 100644 index 00000000000..9c4efd7d8b4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py @@ -0,0 +1,40 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +ERROR_TYPE: Final = "error.type" +""" +Describes a class of error the operation ended with. +Note: The `error.type` SHOULD be predictable, and SHOULD have low cardinality. + +When `error.type` is set to a type (e.g., an exception type), its +canonical class name identifying the type within the artifact SHOULD be used. + +If the recorded error type is a wrapper that is not meaningful for +failure classification, instrumentation MAY use the type of the inner +error instead. For example, in Go, errors created with `fmt.Errorf` +using `%w` MAY be unwrapped when the wrapper type does not help +classify the failure. + +Instrumentations SHOULD document the list of errors they report. + +The cardinality of `error.type` within one instrumentation library SHOULD be low. +Telemetry consumers that aggregate data from multiple instrumentation libraries and applications +should be prepared for `error.type` to have high cardinality at query time when no +additional filters are applied. + +If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. + +If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), +it's RECOMMENDED to: + +- Use a domain-specific attribute +- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. +""" + + +class ErrorTypeValues(Enum): + OTHER = "_OTHER" + """A fallback error value to be used when the instrumentation doesn't define a custom value.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py new file mode 100644 index 00000000000..2d7e748e370 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py @@ -0,0 +1,32 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +EXCEPTION_ESCAPED: Final = "exception.escaped" +""" +Deprecated: It's no longer recommended to record exceptions that are handled and do not escape the scope of a span. +""" + +EXCEPTION_MESSAGE: Final = "exception.message" +""" +The exception message. +Note: > [!WARNING] +> +> This attribute may contain sensitive information. +""" + +EXCEPTION_STACKTRACE: Final = "exception.stacktrace" +""" +A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. +""" + +EXCEPTION_TYPE: Final = "exception.type" +""" +The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. +Note: If the recorded exception type is a wrapper that is not meaningful for +failure classification, instrumentation MAY use the type of the inner +exception instead. For example, in Go, errors created with `fmt.Errorf` +using `%w` MAY be unwrapped when the wrapper type does not help +classify the failure. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py new file mode 100644 index 00000000000..5dbad619dd5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py @@ -0,0 +1,127 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +HTTP_REQUEST_HEADER_TEMPLATE: Final = "http.request.header" +""" +HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. +Note: Instrumentations SHOULD require an explicit configuration of which headers are to be captured. +Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + +The `User-Agent` header is already captured in the `user_agent.original` attribute. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + +The attribute value MUST consist of either multiple header values as an array of strings +or a single-item array containing a possibly comma-concatenated string, depending on the way +the HTTP library provides access to headers. + +Examples: + +- A header `Content-Type: application/json` SHOULD be recorded as the `http.request.header.content-type` + attribute with value `["application/json"]`. +- A header `X-Forwarded-For: 1.2.3.4, 1.2.3.5` SHOULD be recorded as the `http.request.header.x-forwarded-for` + attribute with value `["1.2.3.4", "1.2.3.5"]` or `["1.2.3.4, 1.2.3.5"]` depending on the HTTP library. +""" + +HTTP_REQUEST_METHOD: Final = "http.request.method" +""" +HTTP request method. +Note: HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods), +the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html) +and the QUERY method defined in [httpbis-safe-method-w-body](https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/?include_text=1). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods. + +![Development](https://img.shields.io/badge/-development-blue) +If this override is done via declarative configuration, then the list MUST be configurable via the `known_methods` property +(an array of case-sensitive strings with minimum items 0) under `.instrumentation/development.general.http.client` and/or +`.instrumentation/development.general.http.server`. + +In either case, this list MUST be a full override of the default known methods, +it is not a list of known methods in addition to the defaults. + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. +""" + +HTTP_REQUEST_METHOD_ORIGINAL: Final = "http.request.method_original" +""" +Original HTTP method sent by the client in the request line. +""" + +HTTP_REQUEST_RESEND_COUNT: Final = "http.request.resend_count" +""" +The ordinal number of request resending attempt (for any reason, including redirects). +Note: The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). +""" + +HTTP_RESPONSE_HEADER_TEMPLATE: Final = "http.response.header" +""" +HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. +Note: Instrumentations SHOULD require an explicit configuration of which headers are to be captured. +Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + +The attribute value MUST consist of either multiple header values as an array of strings +or a single-item array containing a possibly comma-concatenated string, depending on the way +the HTTP library provides access to headers. + +Examples: + +- A header `Content-Type: application/json` header SHOULD be recorded as the `http.request.response.content-type` + attribute with value `["application/json"]`. +- A header `My-custom-header: abc, def` header SHOULD be recorded as the `http.response.header.my-custom-header` + attribute with value `["abc", "def"]` or `["abc, def"]` depending on the HTTP library. +""" + +HTTP_RESPONSE_STATUS_CODE: Final = "http.response.status_code" +""" +[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). +""" + +HTTP_ROUTE: Final = "http.route" +""" +The matched route template for the request. This MUST be low-cardinality and include all static path segments, with dynamic path segments represented with placeholders. +Note: MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. + +A static path segment is a part of the route template with a fixed, low-cardinality value. This includes literal strings like `/users/` and placeholders that +are constrained to a finite, predefined set of values, e.g. `{controller}` or `{action}`. + +A dynamic path segment is a placeholder for a value that can have high cardinality and is not constrained to a predefined list like static path segments. + +Instrumentations SHOULD use routing information provided by the corresponding web framework. They SHOULD pick the most precise source of routing information and MAY +support custom route formatting. Instrumentations SHOULD document the format and the API used to obtain the route string. +""" + + +class HttpRequestMethodValues(Enum): + CONNECT = "CONNECT" + """CONNECT method.""" + DELETE = "DELETE" + """DELETE method.""" + GET = "GET" + """GET method.""" + HEAD = "HEAD" + """HEAD method.""" + OPTIONS = "OPTIONS" + """OPTIONS method.""" + PATCH = "PATCH" + """PATCH method.""" + POST = "POST" + """POST method.""" + PUT = "PUT" + """PUT method.""" + TRACE = "TRACE" + """TRACE method.""" + OTHER = "_OTHER" + """Any HTTP method that the instrumentation has no prior knowledge of.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py new file mode 100644 index 00000000000..ca07fadf8a2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py @@ -0,0 +1,362 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +K8S_CLUSTER_NAME: Final = "k8s.cluster.name" +""" +The name of the cluster. +""" + +K8S_CLUSTER_UID: Final = "k8s.cluster.uid" +""" +A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. +Note: K8s doesn't have support for obtaining a cluster ID. If this is ever +added, we will recommend collecting the `k8s.cluster.uid` through the +official APIs. In the meantime, we are able to use the `uid` of the +`kube-system` namespace as a proxy for cluster ID. Read on for the +rationale. + +Every object created in a K8s cluster is assigned a distinct UID. The +`kube-system` namespace is used by Kubernetes itself and will exist +for the lifetime of the cluster. Using the `uid` of the `kube-system` +namespace is a reasonable proxy for the K8s ClusterID as it will only +change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are +UUIDs as standardized by +[ISO/IEC 9834-8 and ITU-T X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). +Which states: + +> If generated according to one of the mechanisms defined in Rec. +> ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be +> different from all other UUIDs generated before 3603 A.D., or is +> extremely likely to be different (depending on the mechanism chosen). + +Therefore, UIDs between clusters should be extremely unlikely to +conflict. +""" + +K8S_CONTAINER_NAME: Final = "k8s.container.name" +""" +The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). +""" + +K8S_CONTAINER_RESTART_COUNT: Final = "k8s.container.restart_count" +""" +Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. +""" + +K8S_CRONJOB_ANNOTATION_TEMPLATE: Final = "k8s.cronjob.annotation" +""" +The cronjob annotation placed on the CronJob, the `` being the annotation name, the value being the annotation value. +Note: Examples: + +- An annotation `retries` with value `4` SHOULD be recorded as the + `k8s.cronjob.annotation.retries` attribute with value `"4"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.cronjob.annotation.data` attribute with value `""`. +""" + +K8S_CRONJOB_LABEL_TEMPLATE: Final = "k8s.cronjob.label" +""" +The label placed on the CronJob, the `` being the label name, the value being the label value. +Note: Examples: + +- A label `type` with value `weekly` SHOULD be recorded as the + `k8s.cronjob.label.type` attribute with value `"weekly"`. +- A label `automated` with empty string value SHOULD be recorded as + the `k8s.cronjob.label.automated` attribute with value `""`. +""" + +K8S_CRONJOB_NAME: Final = "k8s.cronjob.name" +""" +The name of the CronJob. +""" + +K8S_CRONJOB_UID: Final = "k8s.cronjob.uid" +""" +The UID of the CronJob. +""" + +K8S_DAEMONSET_ANNOTATION_TEMPLATE: Final = "k8s.daemonset.annotation" +""" +The annotation placed on the DaemonSet, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `replicas` with value `1` SHOULD be recorded + as the `k8s.daemonset.annotation.replicas` attribute with value `"1"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.daemonset.annotation.data` attribute with value `""`. +""" + +K8S_DAEMONSET_LABEL_TEMPLATE: Final = "k8s.daemonset.label" +""" +The label placed on the DaemonSet, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `app` with value `guestbook` SHOULD be recorded + as the `k8s.daemonset.label.app` attribute with value `"guestbook"`. +- A label `injected` with empty string value SHOULD be recorded as + the `k8s.daemonset.label.injected` attribute with value `""`. +""" + +K8S_DAEMONSET_NAME: Final = "k8s.daemonset.name" +""" +The name of the DaemonSet. +""" + +K8S_DAEMONSET_UID: Final = "k8s.daemonset.uid" +""" +The UID of the DaemonSet. +""" + +K8S_DEPLOYMENT_ANNOTATION_TEMPLATE: Final = "k8s.deployment.annotation" +""" +The annotation placed on the Deployment, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `replicas` with value `1` SHOULD be recorded + as the `k8s.deployment.annotation.replicas` attribute with value `"1"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.deployment.annotation.data` attribute with value `""`. +""" + +K8S_DEPLOYMENT_LABEL_TEMPLATE: Final = "k8s.deployment.label" +""" +The label placed on the Deployment, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `app` with value `guestbook` SHOULD be recorded + as the `k8s.deployment.label.app` attribute with value `"guestbook"`. +- A label `injected` with empty string value SHOULD be recorded as + the `k8s.deployment.label.injected` attribute with value `""`. +""" + +K8S_DEPLOYMENT_NAME: Final = "k8s.deployment.name" +""" +The name of the Deployment. +""" + +K8S_DEPLOYMENT_UID: Final = "k8s.deployment.uid" +""" +The UID of the Deployment. +""" + +K8S_JOB_ANNOTATION_TEMPLATE: Final = "k8s.job.annotation" +""" +The annotation placed on the Job, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `number` with value `1` SHOULD be recorded + as the `k8s.job.annotation.number` attribute with value `"1"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.job.annotation.data` attribute with value `""`. +""" + +K8S_JOB_LABEL_TEMPLATE: Final = "k8s.job.label" +""" +The label placed on the Job, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `jobtype` with value `ci` SHOULD be recorded + as the `k8s.job.label.jobtype` attribute with value `"ci"`. +- A label `automated` with empty string value SHOULD be recorded as + the `k8s.job.label.automated` attribute with value `""`. +""" + +K8S_JOB_NAME: Final = "k8s.job.name" +""" +The name of the Job. +""" + +K8S_JOB_UID: Final = "k8s.job.uid" +""" +The UID of the Job. +""" + +K8S_NAMESPACE_ANNOTATION_TEMPLATE: Final = "k8s.namespace.annotation" +""" +The annotation placed on the Namespace, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `ttl` with value `0` SHOULD be recorded + as the `k8s.namespace.annotation.ttl` attribute with value `"0"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.namespace.annotation.data` attribute with value `""`. +""" + +K8S_NAMESPACE_LABEL_TEMPLATE: Final = "k8s.namespace.label" +""" +The label placed on the Namespace, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `kubernetes.io/metadata.name` with value `default` SHOULD be recorded + as the `k8s.namespace.label.kubernetes.io/metadata.name` attribute with value `"default"`. +- A label `data` with empty string value SHOULD be recorded as + the `k8s.namespace.label.data` attribute with value `""`. +""" + +K8S_NAMESPACE_NAME: Final = "k8s.namespace.name" +""" +The name of the namespace that the pod is running in. +""" + +K8S_NODE_ANNOTATION_TEMPLATE: Final = "k8s.node.annotation" +""" +The annotation placed on the Node, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `node.alpha.kubernetes.io/ttl` with value `0` SHOULD be recorded as + the `k8s.node.annotation.node.alpha.kubernetes.io/ttl` attribute with value `"0"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.node.annotation.data` attribute with value `""`. +""" + +K8S_NODE_LABEL_TEMPLATE: Final = "k8s.node.label" +""" +The label placed on the Node, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `kubernetes.io/arch` with value `arm64` SHOULD be recorded + as the `k8s.node.label.kubernetes.io/arch` attribute with value `"arm64"`. +- A label `data` with empty string value SHOULD be recorded as + the `k8s.node.label.data` attribute with value `""`. +""" + +K8S_NODE_NAME: Final = "k8s.node.name" +""" +The name of the Node. +""" + +K8S_NODE_UID: Final = "k8s.node.uid" +""" +The UID of the Node. +""" + +K8S_POD_ANNOTATION_TEMPLATE: Final = "k8s.pod.annotation" +""" +The annotation placed on the Pod, the `` being the annotation name, the value being the annotation value. +Note: Examples: + +- An annotation `kubernetes.io/enforce-mountable-secrets` with value `true` SHOULD be recorded as + the `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets` attribute with value `"true"`. +- An annotation `mycompany.io/arch` with value `x64` SHOULD be recorded as + the `k8s.pod.annotation.mycompany.io/arch` attribute with value `"x64"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.pod.annotation.data` attribute with value `""`. +""" + +K8S_POD_HOSTNAME: Final = "k8s.pod.hostname" +""" +Specifies the hostname of the Pod. +Note: The K8s Pod spec has an optional hostname field, which can be used to specify a hostname. +Refer to [K8s docs](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-hostname-and-subdomain-field) +for more information about this field. + +This attribute aligns with the `hostname` field of the +[K8s PodSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podspec-v1-core). +""" + +K8S_POD_IP: Final = "k8s.pod.ip" +""" +IP address allocated to the Pod. +Note: This attribute aligns with the `podIP` field of the +[K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core). +""" + +K8S_POD_LABEL_TEMPLATE: Final = "k8s.pod.label" +""" +The label placed on the Pod, the `` being the label name, the value being the label value. +Note: Examples: + +- A label `app` with value `my-app` SHOULD be recorded as + the `k8s.pod.label.app` attribute with value `"my-app"`. +- A label `mycompany.io/arch` with value `x64` SHOULD be recorded as + the `k8s.pod.label.mycompany.io/arch` attribute with value `"x64"`. +- A label `data` with empty string value SHOULD be recorded as + the `k8s.pod.label.data` attribute with value `""`. +""" + +K8S_POD_NAME: Final = "k8s.pod.name" +""" +The name of the Pod. +""" + +K8S_POD_START_TIME: Final = "k8s.pod.start_time" +""" +The start timestamp of the Pod. +Note: Date and time at which the object was acknowledged by the Kubelet. +This is before the Kubelet pulled the container image(s) for the pod. + +This attribute aligns with the `startTime` field of the +[K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core), +in ISO 8601 (RFC 3339 compatible) format. +""" + +K8S_POD_UID: Final = "k8s.pod.uid" +""" +The UID of the Pod. +""" + +K8S_REPLICASET_ANNOTATION_TEMPLATE: Final = "k8s.replicaset.annotation" +""" +The annotation placed on the ReplicaSet, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `replicas` with value `0` SHOULD be recorded + as the `k8s.replicaset.annotation.replicas` attribute with value `"0"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.replicaset.annotation.data` attribute with value `""`. +""" + +K8S_REPLICASET_LABEL_TEMPLATE: Final = "k8s.replicaset.label" +""" +The label placed on the ReplicaSet, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `app` with value `guestbook` SHOULD be recorded + as the `k8s.replicaset.label.app` attribute with value `"guestbook"`. +- A label `injected` with empty string value SHOULD be recorded as + the `k8s.replicaset.label.injected` attribute with value `""`. +""" + +K8S_REPLICASET_NAME: Final = "k8s.replicaset.name" +""" +The name of the ReplicaSet. +""" + +K8S_REPLICASET_UID: Final = "k8s.replicaset.uid" +""" +The UID of the ReplicaSet. +""" + +K8S_STATEFULSET_ANNOTATION_TEMPLATE: Final = "k8s.statefulset.annotation" +""" +The annotation placed on the StatefulSet, the `` being the annotation name, the value being the annotation value, even if the value is empty. +Note: Examples: + +- An annotation `replicas` with value `1` SHOULD be recorded + as the `k8s.statefulset.annotation.replicas` attribute with value `"1"`. +- An annotation `data` with empty string value SHOULD be recorded as + the `k8s.statefulset.annotation.data` attribute with value `""`. +""" + +K8S_STATEFULSET_LABEL_TEMPLATE: Final = "k8s.statefulset.label" +""" +The label placed on the StatefulSet, the `` being the label name, the value being the label value, even if the value is empty. +Note: Examples: + +- A label `app` with value `guestbook` SHOULD be recorded + as the `k8s.statefulset.label.app` attribute with value `"guestbook"`. +- A label `injected` with empty string value SHOULD be recorded as + the `k8s.statefulset.label.injected` attribute with value `""`. +""" + +K8S_STATEFULSET_NAME: Final = "k8s.statefulset.name" +""" +The name of the StatefulSet. +""" + +K8S_STATEFULSET_UID: Final = "k8s.statefulset.uid" +""" +The UID of the StatefulSet. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py new file mode 100644 index 00000000000..7f4cd4aa50d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py @@ -0,0 +1,73 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +NETWORK_LOCAL_ADDRESS: Final = "network.local.address" +""" +Local address of the network connection - IP address or UNIX domain socket name. +""" + +NETWORK_LOCAL_PORT: Final = "network.local.port" +""" +Local port number of the network connection. +""" + +NETWORK_PEER_ADDRESS: Final = "network.peer.address" +""" +Peer address of the network connection - IP address or UNIX domain socket name. +""" + +NETWORK_PEER_PORT: Final = "network.peer.port" +""" +Peer port number of the network connection. +""" + +NETWORK_PROTOCOL_NAME: Final = "network.protocol.name" +""" +[OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. +Note: The value SHOULD be normalized to lowercase. +""" + +NETWORK_PROTOCOL_VERSION: Final = "network.protocol.version" +""" +The actual version of the protocol used for network communication. +Note: If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. +""" + +NETWORK_TRANSPORT: Final = "network.transport" +""" +[OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). +Note: The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. +""" + +NETWORK_TYPE: Final = "network.type" +""" +[OSI network layer](https://wikipedia.org/wiki/Network_layer) or non-OSI equivalent. +Note: The value SHOULD be normalized to lowercase. +""" + + +class NetworkTransportValues(Enum): + TCP = "tcp" + """TCP.""" + UDP = "udp" + """UDP.""" + PIPE = "pipe" + """Named or anonymous pipe.""" + UNIX = "unix" + """UNIX domain socket.""" + QUIC = "quic" + """QUIC.""" + + +class NetworkTypeValues(Enum): + IPV4 = "ipv4" + """IPv4.""" + IPV6 = "ipv6" + """IPv6.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py new file mode 100644 index 00000000000..3bb5747f7dc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py @@ -0,0 +1,38 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +OTEL_EVENT_NAME: Final = "otel.event.name" +""" +Identifies the class / type of event. +Note: This attribute SHOULD be used by non-OTLP exporters when destination does not support `EventName` or equivalent field. This attribute MAY be used by applications using existing logging libraries so that it can be used to set the `EventName` field by Collector or SDK components. +""" + +OTEL_SCOPE_NAME: Final = "otel.scope.name" +""" +The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). +""" + +OTEL_SCOPE_VERSION: Final = "otel.scope.version" +""" +The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). +""" + +OTEL_STATUS_CODE: Final = "otel.status_code" +""" +Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. +""" + +OTEL_STATUS_DESCRIPTION: Final = "otel.status_description" +""" +Description of the Status if it has a value, otherwise not set. +""" + + +class OtelStatusCodeValues(Enum): + OK = "OK" + """The operation has been validated by an Application developer or Operator to have completed successfully.""" + ERROR = "ERROR" + """The operation contains an error.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py new file mode 100644 index 00000000000..1da29204763 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py @@ -0,0 +1,16 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +SERVER_ADDRESS: Final = "server.address" +""" +Server domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. +Note: When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. +""" + +SERVER_PORT: Final = "server.port" +""" +Server port number. +Note: When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py new file mode 100644 index 00000000000..1ee79b9a917 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py @@ -0,0 +1,53 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +SERVICE_INSTANCE_ID: Final = "service.instance.id" +""" +The string ID of the service instance. +Note: MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words +`service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to +distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled +service). + +Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC +4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of +this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and +SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. + +UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is +needed. Similar to what can be seen in the man page for the +[`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/latest/machine-id.html) file, the underlying +data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it +or not via another resource attribute. + +For applications running behind an application server (like unicorn), we do not recommend using one identifier +for all processes participating in the application. Instead, it's recommended each division (e.g. a worker +thread in unicorn) to have its own instance.id. + +It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the +service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will +likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. +However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance +for that telemetry. This is typically the case for scraping receivers, as they know the target address and +port. +""" + +SERVICE_NAME: Final = "service.name" +""" +Logical name of the service. +Note: MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with the process executable name, e.g. `unknown_service:bash`. If the process executable name is not available, the value MUST be set to `unknown_service`. +The process executable name is the name of the process executable, the same value as described by the [`process.executable.name`](process.md) resource attribute. +""" + +SERVICE_NAMESPACE: Final = "service.namespace" +""" +A namespace for `service.name`. +Note: A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. +""" + +SERVICE_VERSION: Final = "service.version" +""" +The version string of the service component. The format is not defined by these conventions. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py new file mode 100644 index 00000000000..4d390c4c416 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py @@ -0,0 +1,67 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum +from typing import Final + +TELEMETRY_DISTRO_NAME: Final = "telemetry.distro.name" +""" +The name of the auto instrumentation agent or distribution, if used. +Note: Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to +a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. +""" + +TELEMETRY_DISTRO_VERSION: Final = "telemetry.distro.version" +""" +The version string of the auto instrumentation agent or distribution, if used. +""" + +TELEMETRY_SDK_LANGUAGE: Final = "telemetry.sdk.language" +""" +The language of the telemetry SDK. +""" + +TELEMETRY_SDK_NAME: Final = "telemetry.sdk.name" +""" +The name of the telemetry SDK as defined above. +Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. +If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the +`telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point +or another suitable identifier depending on the language. +The identifier `opentelemetry` is reserved and MUST NOT be used in this case. +All custom identifiers SHOULD be stable across different versions of an implementation. +""" + +TELEMETRY_SDK_VERSION: Final = "telemetry.sdk.version" +""" +The version string of the telemetry SDK. +""" + + +class TelemetrySdkLanguageValues(Enum): + CPP = "cpp" + """[C++](https://opentelemetry.io/docs/languages/cpp/).""" + DOTNET = "dotnet" + """[.NET](https://opentelemetry.io/docs/languages/dotnet/).""" + ERLANG = "erlang" + """[Erlang/Elixir](https://opentelemetry.io/docs/languages/erlang/).""" + GO = "go" + """[Go](https://opentelemetry.io/docs/languages/go/).""" + JAVA = "java" + """[Java](https://opentelemetry.io/docs/languages/java/).""" + KOTLIN = "kotlin" + """[Kotlin](https://opentelemetry.io/docs/languages/kotlin/).""" + NODEJS = "nodejs" + """[Node.js](https://opentelemetry.io/docs/languages/js/).""" + PHP = "php" + """[PHP](https://opentelemetry.io/docs/languages/php/).""" + PYTHON = "python" + """[Python](https://opentelemetry.io/docs/languages/python/).""" + RUBY = "ruby" + """[Ruby](https://opentelemetry.io/docs/languages/ruby/).""" + RUST = "rust" + """[Rust](https://opentelemetry.io/docs/languages/rust/).""" + SWIFT = "swift" + """[Swift](https://opentelemetry.io/docs/languages/swift/).""" + WEBJS = "webjs" + """[Browser](https://opentelemetry.io/docs/languages/js/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py new file mode 100644 index 00000000000..920de47aafd --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py @@ -0,0 +1,88 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +URL_FRAGMENT: Final = "url.fragment" +""" +The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component. +""" + +URL_FULL: Final = "url.full" +""" +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). +Note: For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment +is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. + +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. +In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. + +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). + +Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. + +![Development](https://img.shields.io/badge/-development-blue) +Query string values for the following keys SHOULD be redacted by default and replaced by the +value `REDACTED`: + +* [`X-Amz-Signature`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) +* [`X-Amz-Credential`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) +* [`X-Amz-Security-Token`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) +* [`sig`](https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token) +* [`X-Goog-Signature`](https://cloud.google.com/storage/docs/access-control/signed-urls) + +This list is subject to change over time. + +Matching of query parameter keys against the sensitive list SHOULD be case-sensitive. + +![Development](https://img.shields.io/badge/-development-blue) +Instrumentation MAY provide a way to override this list via declarative configuration. +If so, it SHOULD use the `sensitive_query_parameters` property +(an array of case-sensitive strings with minimum items 0) under +`.instrumentation/development.general.sanitization.url`. +This list is a full override of the default sensitive query parameter keys, +it is not a list of keys in addition to the defaults. + +When a query string value is redacted, the query string key SHOULD still be preserved, e.g. +`https://www.example.com/path?color=blue&sig=REDACTED`. +""" + +URL_PATH: Final = "url.path" +""" +The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component. +Note: Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. +""" + +URL_QUERY: Final = "url.query" +""" +The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component. +Note: Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. + +![Development](https://img.shields.io/badge/-development-blue) +Query string values for the following keys SHOULD be redacted by default and replaced by the value `REDACTED`: + +* [`X-Amz-Signature`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) +* [`X-Amz-Credential`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) +* [`X-Amz-Security-Token`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) +* [`sig`](https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token) +* [`X-Goog-Signature`](https://cloud.google.com/storage/docs/access-control/signed-urls) + +This list is subject to change over time. + +Matching of query parameter keys against the sensitive list SHOULD be case-sensitive. + +Instrumentation MAY provide a way to override this list via declarative configuration. +If so, it SHOULD use the `sensitive_query_parameters` property +(an array of case-sensitive strings with minimum items 0) under +`.instrumentation/development.general.sanitization.url`. +This list is a full override of the default sensitive query parameter keys, +it is not a list of keys in addition to the defaults. + +When a query string value is redacted, the query string key SHOULD still be preserved, e.g. +`q=OpenTelemetry&sig=REDACTED`. +""" + +URL_SCHEME: Final = "url.scheme" +""" +The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py new file mode 100644 index 00000000000..6d7e44f2a8d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py @@ -0,0 +1,9 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from typing import Final + +USER_AGENT_ORIGINAL: Final = "user_agent.original" +""" +Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py new file mode 100644 index 00000000000..35939f3d263 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py @@ -0,0 +1,191 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.typing_extensions import deprecated + + +@deprecated( + "Use metrics defined in the :py:const:`opentelemetry.semconv.metrics` and :py:const:`opentelemetry.semconv._incubating.metrics` modules instead. Deprecated since version 1.25.0.", +) +class MetricInstruments: + SCHEMA_URL = "https://opentelemetry.io/schemas/1.21.0" + """ + The URL of the OpenTelemetry schema for these keys and values. + """ + + HTTP_SERVER_DURATION = "http.server.duration" + """ + Measures the duration of inbound HTTP requests + Instrument: histogram + Unit: s + """ + + HTTP_SERVER_ACTIVE_REQUESTS = "http.server.active_requests" + """ + Measures the number of concurrent HTTP requests that are currently in-flight + Instrument: updowncounter + Unit: {request} + """ + + HTTP_SERVER_REQUEST_SIZE = "http.server.request.size" + """ + Measures the size of HTTP request messages (compressed) + Instrument: histogram + Unit: By + """ + + HTTP_SERVER_RESPONSE_SIZE = "http.server.response.size" + """ + Measures the size of HTTP response messages (compressed) + Instrument: histogram + Unit: By + """ + + HTTP_CLIENT_DURATION = "http.client.duration" + """ + Measures the duration of outbound HTTP requests + Instrument: histogram + Unit: s + """ + + HTTP_CLIENT_REQUEST_SIZE = "http.client.request.size" + """ + Measures the size of HTTP request messages (compressed) + Instrument: histogram + Unit: By + """ + + HTTP_CLIENT_RESPONSE_SIZE = "http.client.response.size" + """ + Measures the size of HTTP response messages (compressed) + Instrument: histogram + Unit: By + """ + + PROCESS_RUNTIME_JVM_MEMORY_INIT = "process.runtime.jvm.memory.init" + """ + Measure of initial memory requested + Instrument: updowncounter + Unit: By + """ + + PROCESS_RUNTIME_JVM_SYSTEM_CPU_UTILIZATION = "process.runtime.jvm.system.cpu.utilization" + """ + Recent CPU utilization for the whole system as reported by the JVM + Instrument: gauge + Unit: 1 + """ + + PROCESS_RUNTIME_JVM_SYSTEM_CPU_LOAD_1M = "process.runtime.jvm.system.cpu.load_1m" + """ + Average CPU load of the whole system for the last minute as reported by the JVM + Instrument: gauge + Unit: 1 + """ + + PROCESS_RUNTIME_JVM_BUFFER_USAGE = "process.runtime.jvm.buffer.usage" + """ + Measure of memory used by buffers + Instrument: updowncounter + Unit: By + """ + + PROCESS_RUNTIME_JVM_BUFFER_LIMIT = "process.runtime.jvm.buffer.limit" + """ + Measure of total memory capacity of buffers + Instrument: updowncounter + Unit: By + """ + + PROCESS_RUNTIME_JVM_BUFFER_COUNT = "process.runtime.jvm.buffer.count" + """ + Number of buffers in the pool + Instrument: updowncounter + Unit: {buffer} + """ + + PROCESS_RUNTIME_JVM_MEMORY_USAGE = "process.runtime.jvm.memory.usage" + """ + Measure of memory used + Instrument: updowncounter + Unit: By + """ + + PROCESS_RUNTIME_JVM_MEMORY_COMMITTED = "process.runtime.jvm.memory.committed" + """ + Measure of memory committed + Instrument: updowncounter + Unit: By + """ + + PROCESS_RUNTIME_JVM_MEMORY_LIMIT = "process.runtime.jvm.memory.limit" + """ + Measure of max obtainable memory + Instrument: updowncounter + Unit: By + """ + + PROCESS_RUNTIME_JVM_MEMORY_USAGE_AFTER_LAST_GC = "process.runtime.jvm.memory.usage_after_last_gc" + """ + Measure of memory used, as measured after the most recent garbage collection event on this pool + Instrument: updowncounter + Unit: By + """ + + PROCESS_RUNTIME_JVM_GC_DURATION = "process.runtime.jvm.gc.duration" + """ + Duration of JVM garbage collection actions + Instrument: histogram + Unit: s + """ + + PROCESS_RUNTIME_JVM_THREADS_COUNT = "process.runtime.jvm.threads.count" + """ + Number of executing platform threads + Instrument: updowncounter + Unit: {thread} + """ + + PROCESS_RUNTIME_JVM_CLASSES_LOADED = "process.runtime.jvm.classes.loaded" + """ + Number of classes loaded since JVM start + Instrument: counter + Unit: {class} + """ + + PROCESS_RUNTIME_JVM_CLASSES_UNLOADED = "process.runtime.jvm.classes.unloaded" + """ + Number of classes unloaded since JVM start + Instrument: counter + Unit: {class} + """ + + PROCESS_RUNTIME_JVM_CLASSES_CURRENT_LOADED = "process.runtime.jvm.classes.current_loaded" + """ + Number of classes currently loaded + Instrument: updowncounter + Unit: {class} + """ + + PROCESS_RUNTIME_JVM_CPU_TIME = "process.runtime.jvm.cpu.time" + """ + CPU time used by the process as reported by the JVM + Instrument: counter + Unit: s + """ + + PROCESS_RUNTIME_JVM_CPU_RECENT_UTILIZATION = "process.runtime.jvm.cpu.recent_utilization" + """ + Recent CPU utilization for the process as reported by the JVM + Instrument: gauge + Unit: 1 + """ + + # Manually defined metrics + + DB_CLIENT_CONNECTIONS_USAGE = "db.client.connections.usage" + """ + The number of connections that are currently in state described by the `state` attribute + Instrument: UpDownCounter + Unit: {connection} + """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py new file mode 100644 index 00000000000..60317281ddc --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py @@ -0,0 +1,13 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +DB_CLIENT_OPERATION_DURATION: Final = "db.client.operation.duration" +""" +Duration of database client operations +Instrument: histogram +Unit: s +Note: Batch operations SHOULD be recorded as a single operation. +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py new file mode 100644 index 00000000000..924d41d9860 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py @@ -0,0 +1,20 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + + +from typing import Final + +HTTP_CLIENT_REQUEST_DURATION: Final = "http.client.request.duration" +""" +Duration of HTTP client requests +Instrument: histogram +Unit: s +""" + + +HTTP_SERVER_REQUEST_DURATION: Final = "http.server.request.duration" +""" +Duration of HTTP server requests +Instrument: histogram +Unit: s +""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py new file mode 100644 index 00000000000..eb12c3e330e --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py @@ -0,0 +1,875 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=too-many-lines + +from enum import Enum + +from opentelemetry.agent._vendor.typing_extensions import deprecated + + +@deprecated( + "Use attributes defined in the :py:const:`opentelemetry.semconv.attributes` and :py:const:`opentelemetry.semconv._incubating.attributes` modules instead. Deprecated since version 1.25.0.", +) +class ResourceAttributes: + SCHEMA_URL = "https://opentelemetry.io/schemas/1.21.0" + """ + The URL of the OpenTelemetry schema for these keys and values. + """ + BROWSER_BRANDS = "browser.brands" + """ + Array of brand name and version separated by a space. + Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). + """ + + BROWSER_PLATFORM = "browser.platform" + """ + The platform on which the browser is running. + Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. + The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. + """ + + BROWSER_MOBILE = "browser.mobile" + """ + A boolean that is true if the browser is running on a mobile device. + Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset. + """ + + BROWSER_LANGUAGE = "browser.language" + """ + Preferred language of the user using the browser. + Note: This value is intended to be taken from the Navigator API `navigator.language`. + """ + + USER_AGENT_ORIGINAL = "user_agent.original" + """ + Full user-agent string provided by the browser. + Note: The user-agent value SHOULD be provided only from browsers that do not have a mechanism to retrieve brands and platform individually from the User-Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` API can be used. + """ + + CLOUD_PROVIDER = "cloud.provider" + """ + Name of the cloud provider. + """ + + CLOUD_ACCOUNT_ID = "cloud.account.id" + """ + The cloud account ID the resource is assigned to. + """ + + CLOUD_REGION = "cloud.region" + """ + The geographical region the resource is running. + Note: Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). + """ + + CLOUD_RESOURCE_ID = "cloud.resource_id" + """ + Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP). + Note: On some cloud providers, it may not be possible to determine the full ID at startup, + so it may be necessary to set `cloud.resource_id` as a span attribute instead. + + The exact value to use for `cloud.resource_id` depends on the cloud provider. + The following well-known definitions MUST be used if you set this attribute and they apply: + + * **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + Take care not to use the "invoked ARN" directly but replace any + [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + with the resolved function version, as the same runtime instance may be invokable with + multiple different aliases. + * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) + * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, + *not* the function app, having the form + `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + a TracerProvider. + """ + + CLOUD_AVAILABILITY_ZONE = "cloud.availability_zone" + """ + Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. + Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud. + """ + + CLOUD_PLATFORM = "cloud.platform" + """ + The cloud platform in use. + Note: The prefix of the service SHOULD match the one specified in `cloud.provider`. + """ + + AWS_ECS_CONTAINER_ARN = "aws.ecs.container.arn" + """ + The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). + """ + + AWS_ECS_CLUSTER_ARN = "aws.ecs.cluster.arn" + """ + The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). + """ + + AWS_ECS_LAUNCHTYPE = "aws.ecs.launchtype" + """ + The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. + """ + + AWS_ECS_TASK_ARN = "aws.ecs.task.arn" + """ + The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). + """ + + AWS_ECS_TASK_FAMILY = "aws.ecs.task.family" + """ + The task definition family this task definition is a member of. + """ + + AWS_ECS_TASK_REVISION = "aws.ecs.task.revision" + """ + The revision for this task definition. + """ + + AWS_EKS_CLUSTER_ARN = "aws.eks.cluster.arn" + """ + The ARN of an EKS cluster. + """ + + AWS_LOG_GROUP_NAMES = "aws.log.group.names" + """ + The name(s) of the AWS log group(s) an application is writing to. + Note: Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. + """ + + AWS_LOG_GROUP_ARNS = "aws.log.group.arns" + """ + The Amazon Resource Name(s) (ARN) of the AWS log group(s). + Note: See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). + """ + + AWS_LOG_STREAM_NAMES = "aws.log.stream.names" + """ + The name(s) of the AWS log stream(s) an application is writing to. + """ + + AWS_LOG_STREAM_ARNS = "aws.log.stream.arns" + """ + The ARN(s) of the AWS log stream(s). + Note: See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. + """ + + GCP_CLOUD_RUN_JOB_EXECUTION = "gcp.cloud_run.job.execution" + """ + The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. + """ + + GCP_CLOUD_RUN_JOB_TASK_INDEX = "gcp.cloud_run.job.task_index" + """ + The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. + """ + + GCP_GCE_INSTANCE_NAME = "gcp.gce.instance.name" + """ + The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). + """ + + GCP_GCE_INSTANCE_HOSTNAME = "gcp.gce.instance.hostname" + """ + The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). + """ + + HEROKU_RELEASE_CREATION_TIMESTAMP = "heroku.release.creation_timestamp" + """ + Time and date the release was created. + """ + + HEROKU_RELEASE_COMMIT = "heroku.release.commit" + """ + Commit hash for the current release. + """ + + HEROKU_APP_ID = "heroku.app.id" + """ + Unique identifier for the application. + """ + + CONTAINER_NAME = "container.name" + """ + Container name used by container runtime. + """ + + CONTAINER_ID = "container.id" + """ + Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. + """ + + CONTAINER_RUNTIME = "container.runtime" + """ + The container runtime managing this container. + """ + + CONTAINER_IMAGE_NAME = "container.image.name" + """ + Name of the image the container was built on. + """ + + CONTAINER_IMAGE_TAG = "container.image.tag" + """ + Container image tag. + """ + + CONTAINER_IMAGE_ID = "container.image.id" + """ + Runtime specific image identifier. Usually a hash algorithm followed by a UUID. + Note: Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. + K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. + OCI defines a digest of manifest. + """ + + CONTAINER_COMMAND = "container.command" + """ + The command used to run the container (i.e. the command name). + Note: If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. + """ + + CONTAINER_COMMAND_LINE = "container.command_line" + """ + The full command run by the container as a single string representing the full command. [2]. + """ + + CONTAINER_COMMAND_ARGS = "container.command_args" + """ + All the command arguments (including the command/executable itself) run by the container. [2]. + """ + + DEPLOYMENT_ENVIRONMENT = "deployment.environment" + """ + Name of the [deployment environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka deployment tier). + """ + + DEVICE_ID = "device.id" + """ + A unique identifier representing the device. + Note: The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. + """ + + DEVICE_MODEL_IDENTIFIER = "device.model.identifier" + """ + The model identifier for the device. + Note: It's recommended this value represents a machine readable version of the model identifier rather than the market or consumer-friendly name of the device. + """ + + DEVICE_MODEL_NAME = "device.model.name" + """ + The marketing name for the device model. + Note: It's recommended this value represents a human readable version of the device model rather than a machine readable alternative. + """ + + DEVICE_MANUFACTURER = "device.manufacturer" + """ + The name of the device manufacturer. + Note: The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. + """ + + FAAS_NAME = "faas.name" + """ + The name of the single function that this runtime instance executes. + Note: This is the name of the function as configured/deployed on the FaaS + platform and is usually different from the name of the callback + function (which may be stored in the + [`code.namespace`/`code.function`](/docs/general/general-attributes.md#source-code-attributes) + span attributes). + + For some cloud providers, the above definition is ambiguous. The following + definition of function name MUST be used for this attribute + (and consequently the span name) for the listed cloud providers/products: + + * **Azure:** The full name `/`, i.e., function app name + followed by a forward slash followed by the function name (this form + can also be seen in the resource JSON for the function). + This means that a span attribute MUST be used, as an Azure function + app can host multiple functions that would usually share + a TracerProvider (see also the `cloud.resource_id` attribute). + """ + + FAAS_VERSION = "faas.version" + """ + The immutable version of the function being executed. + Note: Depending on the cloud provider and platform, use: + + * **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) + (an integer represented as a decimal string). + * **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) + (i.e., the function name plus the revision suffix). + * **Google Cloud Functions:** The value of the + [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). + * **Azure Functions:** Not applicable. Do not set this attribute. + """ + + FAAS_INSTANCE = "faas.instance" + """ + The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. + Note: * **AWS Lambda:** Use the (full) log stream name. + """ + + FAAS_MAX_MEMORY = "faas.max_memory" + """ + The amount of memory available to the serverless function converted to Bytes. + Note: It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). + """ + + HOST_ID = "host.id" + """ + Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. + """ + + HOST_NAME = "host.name" + """ + Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. + """ + + HOST_TYPE = "host.type" + """ + Type of host. For Cloud, this must be the machine type. + """ + + HOST_ARCH = "host.arch" + """ + The CPU architecture the host system is running on. + """ + + HOST_IMAGE_NAME = "host.image.name" + """ + Name of the VM image or OS install the host was instantiated from. + """ + + HOST_IMAGE_ID = "host.image.id" + """ + VM image ID or host OS image ID. For Cloud, this value is from the provider. + """ + + HOST_IMAGE_VERSION = "host.image.version" + """ + The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). + """ + + K8S_CLUSTER_NAME = "k8s.cluster.name" + """ + The name of the cluster. + """ + + K8S_CLUSTER_UID = "k8s.cluster.uid" + """ + A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. + Note: K8s does not have support for obtaining a cluster ID. If this is ever + added, we will recommend collecting the `k8s.cluster.uid` through the + official APIs. In the meantime, we are able to use the `uid` of the + `kube-system` namespace as a proxy for cluster ID. Read on for the + rationale. + + Every object created in a K8s cluster is assigned a distinct UID. The + `kube-system` namespace is used by Kubernetes itself and will exist + for the lifetime of the cluster. Using the `uid` of the `kube-system` + namespace is a reasonable proxy for the K8s ClusterID as it will only + change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are + UUIDs as standardized by + [ISO/IEC 9834-8 and ITU-T X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). + Which states: + + > If generated according to one of the mechanisms defined in Rec. + ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be + different from all other UUIDs generated before 3603 A.D., or is + extremely likely to be different (depending on the mechanism chosen). + + Therefore, UIDs between clusters should be extremely unlikely to + conflict. + """ + + K8S_NODE_NAME = "k8s.node.name" + """ + The name of the Node. + """ + + K8S_NODE_UID = "k8s.node.uid" + """ + The UID of the Node. + """ + + K8S_NAMESPACE_NAME = "k8s.namespace.name" + """ + The name of the namespace that the pod is running in. + """ + + K8S_POD_UID = "k8s.pod.uid" + """ + The UID of the Pod. + """ + + K8S_POD_NAME = "k8s.pod.name" + """ + The name of the Pod. + """ + + K8S_CONTAINER_NAME = "k8s.container.name" + """ + The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). + """ + + K8S_CONTAINER_RESTART_COUNT = "k8s.container.restart_count" + """ + Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. + """ + + K8S_REPLICASET_UID = "k8s.replicaset.uid" + """ + The UID of the ReplicaSet. + """ + + K8S_REPLICASET_NAME = "k8s.replicaset.name" + """ + The name of the ReplicaSet. + """ + + K8S_DEPLOYMENT_UID = "k8s.deployment.uid" + """ + The UID of the Deployment. + """ + + K8S_DEPLOYMENT_NAME = "k8s.deployment.name" + """ + The name of the Deployment. + """ + + K8S_STATEFULSET_UID = "k8s.statefulset.uid" + """ + The UID of the StatefulSet. + """ + + K8S_STATEFULSET_NAME = "k8s.statefulset.name" + """ + The name of the StatefulSet. + """ + + K8S_DAEMONSET_UID = "k8s.daemonset.uid" + """ + The UID of the DaemonSet. + """ + + K8S_DAEMONSET_NAME = "k8s.daemonset.name" + """ + The name of the DaemonSet. + """ + + K8S_JOB_UID = "k8s.job.uid" + """ + The UID of the Job. + """ + + K8S_JOB_NAME = "k8s.job.name" + """ + The name of the Job. + """ + + K8S_CRONJOB_UID = "k8s.cronjob.uid" + """ + The UID of the CronJob. + """ + + K8S_CRONJOB_NAME = "k8s.cronjob.name" + """ + The name of the CronJob. + """ + + OS_TYPE = "os.type" + """ + The operating system type. + """ + + OS_DESCRIPTION = "os.description" + """ + Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. + """ + + OS_NAME = "os.name" + """ + Human readable operating system name. + """ + + OS_VERSION = "os.version" + """ + The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). + """ + + PROCESS_PID = "process.pid" + """ + Process identifier (PID). + """ + + PROCESS_PARENT_PID = "process.parent_pid" + """ + Parent Process identifier (PID). + """ + + PROCESS_EXECUTABLE_NAME = "process.executable.name" + """ + The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. + """ + + PROCESS_EXECUTABLE_PATH = "process.executable.path" + """ + The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. + """ + + PROCESS_COMMAND = "process.command" + """ + The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. + """ + + PROCESS_COMMAND_LINE = "process.command_line" + """ + The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. + """ + + PROCESS_COMMAND_ARGS = "process.command_args" + """ + All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. + """ + + PROCESS_OWNER = "process.owner" + """ + The username of the user that owns the process. + """ + + PROCESS_RUNTIME_NAME = "process.runtime.name" + """ + The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. + """ + + PROCESS_RUNTIME_VERSION = "process.runtime.version" + """ + The version of the runtime of this process, as returned by the runtime without modification. + """ + + PROCESS_RUNTIME_DESCRIPTION = "process.runtime.description" + """ + An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. + """ + + SERVICE_NAME = "service.name" + """ + Logical name of the service. + Note: MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. + """ + + SERVICE_VERSION = "service.version" + """ + The version string of the service API or implementation. The format is not defined by these conventions. + """ + + SERVICE_NAMESPACE = "service.namespace" + """ + A namespace for `service.name`. + Note: A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. + """ + + SERVICE_INSTANCE_ID = "service.instance.id" + """ + The string ID of the service instance. + Note: MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled service). It is preferable for the ID to be persistent and stay the same for the lifetime of the service instance, however it is acceptable that the ID is ephemeral and changes during important lifetime events for the service (e.g. service restarts). If the service has no inherent unique ID that can be used as the value of this attribute it is recommended to generate a random Version 1 or Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use Version 5, see RFC 4122 for more recommendations). + """ + + TELEMETRY_SDK_NAME = "telemetry.sdk.name" + """ + The name of the telemetry SDK as defined above. + Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. + If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the + `telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point + or another suitable identifier depending on the language. + The identifier `opentelemetry` is reserved and MUST NOT be used in this case. + All custom identifiers SHOULD be stable across different versions of an implementation. + """ + + TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language" + """ + The language of the telemetry SDK. + """ + + TELEMETRY_SDK_VERSION = "telemetry.sdk.version" + """ + The version string of the telemetry SDK. + """ + + TELEMETRY_AUTO_VERSION = "telemetry.auto.version" + """ + The version string of the auto instrumentation agent, if used. + """ + + WEBENGINE_NAME = "webengine.name" + """ + The name of the web engine. + """ + + WEBENGINE_VERSION = "webengine.version" + """ + The version of the web engine. + """ + + WEBENGINE_DESCRIPTION = "webengine.description" + """ + Additional description of the web engine (e.g. detailed version and edition information). + """ + + OTEL_SCOPE_NAME = "otel.scope.name" + """ + The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + """ + + OTEL_SCOPE_VERSION = "otel.scope.version" + """ + The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + """ + + OTEL_LIBRARY_NAME = "otel.library.name" + """ + Deprecated, use the `otel.scope.name` attribute. + """ + + OTEL_LIBRARY_VERSION = "otel.library.version" + """ + Deprecated, use the `otel.scope.version` attribute. + """ + + # Manually defined deprecated attributes + + FAAS_ID = "faas.id" + """ + Deprecated, use the `cloud.resource.id` attribute. + """ + + +@deprecated( + "Use :py:const:`opentelemetry.semconv._incubating.attributes.CloudProviderValues` instead. Deprecated since version 1.25.0.", +) +class CloudProviderValues(Enum): + ALIBABA_CLOUD = "alibaba_cloud" + """Alibaba Cloud.""" + + AWS = "aws" + """Amazon Web Services.""" + + AZURE = "azure" + """Microsoft Azure.""" + + GCP = "gcp" + """Google Cloud Platform.""" + + HEROKU = "heroku" + """Heroku Platform as a Service.""" + + IBM_CLOUD = "ibm_cloud" + """IBM Cloud.""" + + TENCENT_CLOUD = "tencent_cloud" + """Tencent Cloud.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv._incubating.attributes.CloudPlatformValues` instead. Deprecated since version 1.25.0.", +) +class CloudPlatformValues(Enum): + ALIBABA_CLOUD_ECS = "alibaba_cloud_ecs" + """Alibaba Cloud Elastic Compute Service.""" + + ALIBABA_CLOUD_FC = "alibaba_cloud_fc" + """Alibaba Cloud Function Compute.""" + + ALIBABA_CLOUD_OPENSHIFT = "alibaba_cloud_openshift" + """Red Hat OpenShift on Alibaba Cloud.""" + + AWS_EC2 = "aws_ec2" + """AWS Elastic Compute Cloud.""" + + AWS_ECS = "aws_ecs" + """AWS Elastic Container Service.""" + + AWS_EKS = "aws_eks" + """AWS Elastic Kubernetes Service.""" + + AWS_LAMBDA = "aws_lambda" + """AWS Lambda.""" + + AWS_ELASTIC_BEANSTALK = "aws_elastic_beanstalk" + """AWS Elastic Beanstalk.""" + + AWS_APP_RUNNER = "aws_app_runner" + """AWS App Runner.""" + + AWS_OPENSHIFT = "aws_openshift" + """Red Hat OpenShift on AWS (ROSA).""" + + AZURE_VM = "azure_vm" + """Azure Virtual Machines.""" + + AZURE_CONTAINER_INSTANCES = "azure_container_instances" + """Azure Container Instances.""" + + AZURE_AKS = "azure_aks" + """Azure Kubernetes Service.""" + + AZURE_FUNCTIONS = "azure_functions" + """Azure Functions.""" + + AZURE_APP_SERVICE = "azure_app_service" + """Azure App Service.""" + + AZURE_OPENSHIFT = "azure_openshift" + """Azure Red Hat OpenShift.""" + + GCP_BARE_METAL_SOLUTION = "gcp_bare_metal_solution" + """Google Bare Metal Solution (BMS).""" + + GCP_COMPUTE_ENGINE = "gcp_compute_engine" + """Google Cloud Compute Engine (GCE).""" + + GCP_CLOUD_RUN = "gcp_cloud_run" + """Google Cloud Run.""" + + GCP_KUBERNETES_ENGINE = "gcp_kubernetes_engine" + """Google Cloud Kubernetes Engine (GKE).""" + + GCP_CLOUD_FUNCTIONS = "gcp_cloud_functions" + """Google Cloud Functions (GCF).""" + + GCP_APP_ENGINE = "gcp_app_engine" + """Google Cloud App Engine (GAE).""" + + GCP_OPENSHIFT = "gcp_openshift" + """Red Hat OpenShift on Google Cloud.""" + + IBM_CLOUD_OPENSHIFT = "ibm_cloud_openshift" + """Red Hat OpenShift on IBM Cloud.""" + + TENCENT_CLOUD_CVM = "tencent_cloud_cvm" + """Tencent Cloud Cloud Virtual Machine (CVM).""" + + TENCENT_CLOUD_EKS = "tencent_cloud_eks" + """Tencent Cloud Elastic Kubernetes Service (EKS).""" + + TENCENT_CLOUD_SCF = "tencent_cloud_scf" + """Tencent Cloud Serverless Cloud Function (SCF).""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv._incubating.attributes.AwsEcsLaunchtypeValues` instead. Deprecated since version 1.25.0.", +) +class AwsEcsLaunchtypeValues(Enum): + EC2 = "ec2" + """ec2.""" + + FARGATE = "fargate" + """fargate.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv._incubating.attributes.HostArchValues` instead. Deprecated since version 1.25.0.", +) +class HostArchValues(Enum): + AMD64 = "amd64" + """AMD64.""" + + ARM32 = "arm32" + """ARM32.""" + + ARM64 = "arm64" + """ARM64.""" + + IA64 = "ia64" + """Itanium.""" + + PPC32 = "ppc32" + """32-bit PowerPC.""" + + PPC64 = "ppc64" + """64-bit PowerPC.""" + + S390X = "s390x" + """IBM z/Architecture.""" + + X86 = "x86" + """32-bit x86.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv._incubating.attributes.OsTypeValues` instead. Deprecated since version 1.25.0.", +) +class OsTypeValues(Enum): + WINDOWS = "windows" + """Microsoft Windows.""" + + LINUX = "linux" + """Linux.""" + + DARWIN = "darwin" + """Apple Darwin.""" + + FREEBSD = "freebsd" + """FreeBSD.""" + + NETBSD = "netbsd" + """NetBSD.""" + + OPENBSD = "openbsd" + """OpenBSD.""" + + DRAGONFLYBSD = "dragonflybsd" + """DragonFly BSD.""" + + HPUX = "hpux" + """HP-UX (Hewlett Packard Unix).""" + + AIX = "aix" + """AIX (Advanced Interactive eXecutive).""" + + SOLARIS = "solaris" + """SunOS, Oracle Solaris.""" + + Z_OS = "z_os" + """IBM z/OS.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv.attributes.TelemetrySdkLanguageValues` instead. Deprecated since version 1.25.0.", +) +class TelemetrySdkLanguageValues(Enum): + CPP = "cpp" + """cpp.""" + + DOTNET = "dotnet" + """dotnet.""" + + ERLANG = "erlang" + """erlang.""" + + GO = "go" + """go.""" + + JAVA = "java" + """java.""" + + NODEJS = "nodejs" + """nodejs.""" + + PHP = "php" + """php.""" + + PYTHON = "python" + """python.""" + + RUBY = "ruby" + """ruby.""" + + RUST = "rust" + """rust.""" + + SWIFT = "swift" + """swift.""" + + WEBJS = "webjs" + """webjs.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py new file mode 100644 index 00000000000..01c01f7bd2d --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py @@ -0,0 +1,118 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from enum import Enum + + +class Schemas(Enum): + V1_21_0 = "https://opentelemetry.io/schemas/1.21.0" + """ + The URL of the OpenTelemetry schema version 1.21.0. + """ + + V1_23_1 = "https://opentelemetry.io/schemas/1.23.1" + """ + The URL of the OpenTelemetry schema version 1.23.1. + """ + + V1_25_0 = "https://opentelemetry.io/schemas/1.25.0" + """ + The URL of the OpenTelemetry schema version 1.25.0. + """ + + V1_26_0 = "https://opentelemetry.io/schemas/1.26.0" + """ + The URL of the OpenTelemetry schema version 1.26.0. + """ + + V1_27_0 = "https://opentelemetry.io/schemas/1.27.0" + """ + The URL of the OpenTelemetry schema version 1.27.0. + """ + + V1_28_0 = "https://opentelemetry.io/schemas/1.28.0" + """ + The URL of the OpenTelemetry schema version 1.28.0. + """ + + V1_29_0 = "https://opentelemetry.io/schemas/1.29.0" + """ + The URL of the OpenTelemetry schema version 1.29.0. + """ + + V1_30_0 = "https://opentelemetry.io/schemas/1.30.0" + """ + The URL of the OpenTelemetry schema version 1.30.0. + """ + + V1_31_0 = "https://opentelemetry.io/schemas/1.31.0" + """ + The URL of the OpenTelemetry schema version 1.31.0. + """ + + V1_32_0 = "https://opentelemetry.io/schemas/1.32.0" + """ + The URL of the OpenTelemetry schema version 1.32.0. + """ + + V1_33_0 = "https://opentelemetry.io/schemas/1.33.0" + """ + The URL of the OpenTelemetry schema version 1.33.0. + """ + + V1_34_0 = "https://opentelemetry.io/schemas/1.34.0" + """ + The URL of the OpenTelemetry schema version 1.34.0. + """ + V1_36_0 = "https://opentelemetry.io/schemas/1.36.0" + """ + The URL of the OpenTelemetry schema version 1.36.0. + """ + + V1_37_0 = "https://opentelemetry.io/schemas/1.37.0" + """ + The URL of the OpenTelemetry schema version 1.37.0. + """ + + V1_38_0 = "https://opentelemetry.io/schemas/1.38.0" + """ + The URL of the OpenTelemetry schema version 1.38.0. + """ + + V1_39_0 = "https://opentelemetry.io/schemas/1.39.0" + """ + The URL of the OpenTelemetry schema version 1.39.0. + """ + + V1_40_0 = "https://opentelemetry.io/schemas/1.40.0" + """ + The URL of the OpenTelemetry schema version 1.40.0. + """ + + V1_41_0 = "https://opentelemetry.io/schemas/1.41.0" + """ + The URL of the OpenTelemetry schema version 1.41.0. + """ + + V1_41_1 = "https://opentelemetry.io/schemas/1.41.1" + """ + The URL of the OpenTelemetry schema version 1.41.1. + """ + + V1_42_0 = "https://opentelemetry.io/schemas/1.42.0" + """ + The URL of the OpenTelemetry schema version 1.42.0. + """ + + V1_43_0 = "https://opentelemetry.io/schemas/1.43.0" + """ + The URL of the OpenTelemetry schema version 1.43.0. + """ + + V1_44_0 = "https://opentelemetry.io/schemas/1.44.0" + """ + The URL of the OpenTelemetry schema version 1.44.0. + """ + + # when generating new semantic conventions, + # make sure to add new versions version here. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py new file mode 100644 index 00000000000..48e4ba1be84 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py @@ -0,0 +1,2164 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: disable=too-many-lines + +from enum import Enum + +from opentelemetry.agent._vendor.typing_extensions import deprecated + + +@deprecated( + "Use attributes defined in the :py:const:`opentelemetry.semconv.attributes` and :py:const:`opentelemetry.semconv._incubating.attributes` modules instead. Deprecated since version 1.25.0.", +) +class SpanAttributes: + SCHEMA_URL = "https://opentelemetry.io/schemas/1.21.0" + """ + The URL of the OpenTelemetry schema for these keys and values. + """ + CLIENT_ADDRESS = "client.address" + """ + Client address - unix domain socket name, IPv4 or IPv6 address. + Note: When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent client address behind any intermediaries (e.g. proxies) if it's available. + """ + + CLIENT_PORT = "client.port" + """ + Client port number. + Note: When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent client port behind any intermediaries (e.g. proxies) if it's available. + """ + + CLIENT_SOCKET_ADDRESS = "client.socket.address" + """ + Immediate client peer address - unix domain socket name, IPv4 or IPv6 address. + """ + + CLIENT_SOCKET_PORT = "client.socket.port" + """ + Immediate client peer port number. + """ + + HTTP_METHOD = "http.method" + """ + Deprecated, use `http.request.method` instead. + """ + + HTTP_STATUS_CODE = "http.status_code" + """ + Deprecated, use `http.response.status_code` instead. + """ + + HTTP_SCHEME = "http.scheme" + """ + Deprecated, use `url.scheme` instead. + """ + + HTTP_URL = "http.url" + """ + Deprecated, use `url.full` instead. + """ + + HTTP_TARGET = "http.target" + """ + Deprecated, use `url.path` and `url.query` instead. + """ + + HTTP_REQUEST_CONTENT_LENGTH = "http.request_content_length" + """ + Deprecated, use `http.request.body.size` instead. + """ + + HTTP_RESPONSE_CONTENT_LENGTH = "http.response_content_length" + """ + Deprecated, use `http.response.body.size` instead. + """ + + NET_SOCK_PEER_NAME = "net.sock.peer.name" + """ + Deprecated, use `server.socket.domain` on client spans. + """ + + NET_SOCK_PEER_ADDR = "net.sock.peer.addr" + """ + Deprecated, use `server.socket.address` on client spans and `client.socket.address` on server spans. + """ + + NET_SOCK_PEER_PORT = "net.sock.peer.port" + """ + Deprecated, use `server.socket.port` on client spans and `client.socket.port` on server spans. + """ + + NET_PEER_NAME = "net.peer.name" + """ + Deprecated, use `server.address` on client spans and `client.address` on server spans. + """ + + NET_PEER_PORT = "net.peer.port" + """ + Deprecated, use `server.port` on client spans and `client.port` on server spans. + """ + + NET_HOST_NAME = "net.host.name" + """ + Deprecated, use `server.address`. + """ + + NET_HOST_PORT = "net.host.port" + """ + Deprecated, use `server.port`. + """ + + NET_SOCK_HOST_ADDR = "net.sock.host.addr" + """ + Deprecated, use `server.socket.address`. + """ + + NET_SOCK_HOST_PORT = "net.sock.host.port" + """ + Deprecated, use `server.socket.port`. + """ + + NET_TRANSPORT = "net.transport" + """ + Deprecated, use `network.transport`. + """ + + NET_PROTOCOL_NAME = "net.protocol.name" + """ + Deprecated, use `network.protocol.name`. + """ + + NET_PROTOCOL_VERSION = "net.protocol.version" + """ + Deprecated, use `network.protocol.version`. + """ + + NET_SOCK_FAMILY = "net.sock.family" + """ + Deprecated, use `network.transport` and `network.type`. + """ + + DESTINATION_DOMAIN = "destination.domain" + """ + The domain name of the destination system. + Note: This value may be a host name, a fully qualified domain name, or another host naming format. + """ + + DESTINATION_ADDRESS = "destination.address" + """ + Peer address, for example IP address or UNIX socket name. + """ + + DESTINATION_PORT = "destination.port" + """ + Peer port number. + """ + + EXCEPTION_TYPE = "exception.type" + """ + The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. + """ + + EXCEPTION_MESSAGE = "exception.message" + """ + The exception message. + """ + + EXCEPTION_STACKTRACE = "exception.stacktrace" + """ + A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. + """ + + HTTP_REQUEST_METHOD = "http.request.method" + """ + HTTP request method. + Note: HTTP request method value SHOULD be "known" to the instrumentation. + By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) + and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + + If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST + set the exact method received in the request line as value of the `http.request.method_original` attribute. + + If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override + the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named + OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods + (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + + HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. + Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. + Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + """ + + HTTP_RESPONSE_STATUS_CODE = "http.response.status_code" + """ + [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). + """ + + NETWORK_PROTOCOL_NAME = "network.protocol.name" + """ + [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. + """ + + NETWORK_PROTOCOL_VERSION = "network.protocol.version" + """ + Version of the application layer protocol used. See note below. + Note: `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. + """ + + SERVER_ADDRESS = "server.address" + """ + Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + Note: Determined by using the first of the following that applies + + - Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) + if it's sent in absolute-form + - Host identifier of the `Host` header + + SHOULD NOT be set if capturing it would require an extra DNS lookup. + """ + + SERVER_PORT = "server.port" + """ + Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. + Note: When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. + """ + + HTTP_ROUTE = "http.route" + """ + The matched route (path template in the format used by the respective server framework). See note below. + Note: MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. + SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. + """ + + URL_SCHEME = "url.scheme" + """ + The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. + """ + + EVENT_NAME = "event.name" + """ + The name identifies the event. + """ + + EVENT_DOMAIN = "event.domain" + """ + The domain identifies the business context for the events. + Note: Events across different domains may have same `event.name`, yet be + unrelated events. + """ + + LOG_RECORD_UID = "log.record.uid" + """ + A unique identifier for the Log Record. + Note: If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. + The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. + """ + + FEATURE_FLAG_KEY = "feature_flag.key" + """ + The unique identifier of the feature flag. + """ + + FEATURE_FLAG_PROVIDER_NAME = "feature_flag.provider_name" + """ + The name of the service provider that performs the flag evaluation. + """ + + FEATURE_FLAG_VARIANT = "feature_flag.variant" + """ + SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. + Note: A semantic identifier, commonly referred to as a variant, provides a means + for referring to a value without including the value itself. This can + provide additional context for understanding the meaning behind a value. + For example, the variant `red` maybe be used for the value `#c05543`. + + A stringified version of the value can be used in situations where a + semantic identifier is unavailable. String representation of the value + should be determined by the implementer. + """ + + LOG_IOSTREAM = "log.iostream" + """ + The stream associated with the log. See below for a list of well-known values. + """ + + LOG_FILE_NAME = "log.file.name" + """ + The basename of the file. + """ + + LOG_FILE_PATH = "log.file.path" + """ + The full path to the file. + """ + + LOG_FILE_NAME_RESOLVED = "log.file.name_resolved" + """ + The basename of the file, with symlinks resolved. + """ + + LOG_FILE_PATH_RESOLVED = "log.file.path_resolved" + """ + The full path to the file, with symlinks resolved. + """ + + SERVER_SOCKET_ADDRESS = "server.socket.address" + """ + Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). + """ + + POOL = "pool" + """ + Name of the buffer pool. + Note: Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). + """ + + TYPE = "type" + """ + The type of memory. + """ + + SERVER_SOCKET_DOMAIN = "server.socket.domain" + """ + The domain name of an immediate peer. + Note: Typically observed from the client side, and represents a proxy or other intermediary domain name. + """ + + SERVER_SOCKET_PORT = "server.socket.port" + """ + Physical server port. + """ + + SOURCE_DOMAIN = "source.domain" + """ + The domain name of the source system. + Note: This value may be a host name, a fully qualified domain name, or another host naming format. + """ + + SOURCE_ADDRESS = "source.address" + """ + Source address, for example IP address or Unix socket name. + """ + + SOURCE_PORT = "source.port" + """ + Source port number. + """ + + AWS_LAMBDA_INVOKED_ARN = "aws.lambda.invoked_arn" + """ + The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). + Note: This may be different from `cloud.resource_id` if an alias is involved. + """ + + CLOUDEVENTS_EVENT_ID = "cloudevents.event_id" + """ + The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. + """ + + CLOUDEVENTS_EVENT_SOURCE = "cloudevents.event_source" + """ + The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. + """ + + CLOUDEVENTS_EVENT_SPEC_VERSION = "cloudevents.event_spec_version" + """ + The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. + """ + + CLOUDEVENTS_EVENT_TYPE = "cloudevents.event_type" + """ + The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. + """ + + CLOUDEVENTS_EVENT_SUBJECT = "cloudevents.event_subject" + """ + The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). + """ + + OPENTRACING_REF_TYPE = "opentracing.ref_type" + """ + Parent-child Reference type. + Note: The causal relationship between a child Span and a parent Span. + """ + + DB_SYSTEM = "db.system" + """ + An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + """ + + DB_CONNECTION_STRING = "db.connection_string" + """ + The connection string used to connect to the database. It is recommended to remove embedded credentials. + """ + + DB_USER = "db.user" + """ + Username for accessing the database. + """ + + DB_JDBC_DRIVER_CLASSNAME = "db.jdbc.driver_classname" + """ + The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. + """ + + DB_NAME = "db.name" + """ + This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). + Note: In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). + """ + + DB_STATEMENT = "db.statement" + """ + The database statement being executed. + """ + + DB_OPERATION = "db.operation" + """ + The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. + Note: When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. + """ + + NETWORK_TRANSPORT = "network.transport" + """ + [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. + """ + + NETWORK_TYPE = "network.type" + """ + [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. + """ + + DB_MSSQL_INSTANCE_NAME = "db.mssql.instance_name" + """ + The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. + Note: If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + """ + + DB_CASSANDRA_PAGE_SIZE = "db.cassandra.page_size" + """ + The fetch size used for paging, i.e. how many rows will be returned at once. + """ + + DB_CASSANDRA_CONSISTENCY_LEVEL = "db.cassandra.consistency_level" + """ + The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). + """ + + DB_CASSANDRA_TABLE = "db.cassandra.table" + """ + The name of the primary table that the operation is acting upon, including the keyspace name (if applicable). + Note: This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + """ + + DB_CASSANDRA_IDEMPOTENCE = "db.cassandra.idempotence" + """ + Whether or not the query is idempotent. + """ + + DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT = "db.cassandra.speculative_execution_count" + """ + The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + """ + + DB_CASSANDRA_COORDINATOR_ID = "db.cassandra.coordinator.id" + """ + The ID of the coordinating node for a query. + """ + + DB_CASSANDRA_COORDINATOR_DC = "db.cassandra.coordinator.dc" + """ + The data center of the coordinating node for a query. + """ + + DB_REDIS_DATABASE_INDEX = "db.redis.database_index" + """ + The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. + """ + + DB_MONGODB_COLLECTION = "db.mongodb.collection" + """ + The collection being accessed within the database stated in `db.name`. + """ + + URL_FULL = "url.full" + """ + Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). + Note: For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. + `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. + `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + """ + + DB_SQL_TABLE = "db.sql.table" + """ + The name of the primary table that the operation is acting upon, including the database name (if applicable). + Note: It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + """ + + DB_COSMOSDB_CLIENT_ID = "db.cosmosdb.client_id" + """ + Unique Cosmos client instance id. + """ + + DB_COSMOSDB_OPERATION_TYPE = "db.cosmosdb.operation_type" + """ + CosmosDB Operation Type. + """ + + USER_AGENT_ORIGINAL = "user_agent.original" + """ + Full user-agent string is generated by Cosmos DB SDK. + Note: The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + """ + + DB_COSMOSDB_CONNECTION_MODE = "db.cosmosdb.connection_mode" + """ + Cosmos client connection mode. + """ + + DB_COSMOSDB_CONTAINER = "db.cosmosdb.container" + """ + Cosmos DB container name. + """ + + DB_COSMOSDB_REQUEST_CONTENT_LENGTH = "db.cosmosdb.request_content_length" + """ + Request payload size in bytes. + """ + + DB_COSMOSDB_STATUS_CODE = "db.cosmosdb.status_code" + """ + Cosmos DB status code. + """ + + DB_COSMOSDB_SUB_STATUS_CODE = "db.cosmosdb.sub_status_code" + """ + Cosmos DB sub status code. + """ + + DB_COSMOSDB_REQUEST_CHARGE = "db.cosmosdb.request_charge" + """ + RU consumed for that operation. + """ + + OTEL_STATUS_CODE = "otel.status_code" + """ + Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. + """ + + OTEL_STATUS_DESCRIPTION = "otel.status_description" + """ + Description of the Status if it has a value, otherwise not set. + """ + + FAAS_TRIGGER = "faas.trigger" + """ + Type of the trigger which caused this function invocation. + Note: For the server/consumer span on the incoming side, + `faas.trigger` MUST be set. + + Clients invoking FaaS instances usually cannot set `faas.trigger`, + since they would typically need to look in the payload to determine + the event type. If clients set it, it should be the same as the + trigger that corresponding incoming would have (i.e., this has + nothing to do with the underlying transport used to make the API + call to invoke the lambda, which is often HTTP). + """ + + FAAS_INVOCATION_ID = "faas.invocation_id" + """ + The invocation ID of the current function invocation. + """ + + CLOUD_RESOURCE_ID = "cloud.resource_id" + """ + Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP). + Note: On some cloud providers, it may not be possible to determine the full ID at startup, + so it may be necessary to set `cloud.resource_id` as a span attribute instead. + + The exact value to use for `cloud.resource_id` depends on the cloud provider. + The following well-known definitions MUST be used if you set this attribute and they apply: + + * **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). + Take care not to use the "invoked ARN" directly but replace any + [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) + with the resolved function version, as the same runtime instance may be invokable with + multiple different aliases. + * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) + * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, + *not* the function app, having the form + `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. + This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + a TracerProvider. + """ + + FAAS_DOCUMENT_COLLECTION = "faas.document.collection" + """ + The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. + """ + + FAAS_DOCUMENT_OPERATION = "faas.document.operation" + """ + Describes the type of the operation that was performed on the data. + """ + + FAAS_DOCUMENT_TIME = "faas.document.time" + """ + A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + """ + + FAAS_DOCUMENT_NAME = "faas.document.name" + """ + The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. + """ + + URL_PATH = "url.path" + """ + The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component. + Note: When missing, the value is assumed to be `/`. + """ + + URL_QUERY = "url.query" + """ + The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component. + Note: Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + """ + + MESSAGING_SYSTEM = "messaging.system" + """ + A string identifying the messaging system. + """ + + MESSAGING_OPERATION = "messaging.operation" + """ + A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. + Note: If a custom value is used, it MUST be of low cardinality. + """ + + MESSAGING_BATCH_MESSAGE_COUNT = "messaging.batch.message_count" + """ + The number of messages sent, received, or processed in the scope of the batching operation. + Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. + """ + + MESSAGING_CLIENT_ID = "messaging.client_id" + """ + A unique identifier for the client that consumes or produces a message. + """ + + MESSAGING_DESTINATION_NAME = "messaging.destination.name" + """ + The message destination name. + Note: Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If + the broker does not have such notion, the destination name SHOULD uniquely identify the broker. + """ + + MESSAGING_DESTINATION_TEMPLATE = "messaging.destination.template" + """ + Low cardinality representation of the messaging destination name. + Note: Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + """ + + MESSAGING_DESTINATION_TEMPORARY = "messaging.destination.temporary" + """ + A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. + """ + + MESSAGING_DESTINATION_ANONYMOUS = "messaging.destination.anonymous" + """ + A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). + """ + + MESSAGING_MESSAGE_ID = "messaging.message.id" + """ + A value used by the messaging system as an identifier for the message, represented as a string. + """ + + MESSAGING_MESSAGE_CONVERSATION_ID = "messaging.message.conversation_id" + """ + The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". + """ + + MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES = "messaging.message.payload_size_bytes" + """ + The (uncompressed) size of the message payload in bytes. Also use this attribute if it is unknown whether the compressed or uncompressed payload size is reported. + """ + + MESSAGING_MESSAGE_PAYLOAD_COMPRESSED_SIZE_BYTES = "messaging.message.payload_compressed_size_bytes" + """ + The compressed size of the message payload in bytes. + """ + + FAAS_TIME = "faas.time" + """ + A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). + """ + + FAAS_CRON = "faas.cron" + """ + A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). + """ + + FAAS_COLDSTART = "faas.coldstart" + """ + A boolean that is true if the serverless function is executed for the first time (aka cold-start). + """ + + FAAS_INVOKED_NAME = "faas.invoked_name" + """ + The name of the invoked function. + Note: SHOULD be equal to the `faas.name` resource attribute of the invoked function. + """ + + FAAS_INVOKED_PROVIDER = "faas.invoked_provider" + """ + The cloud provider of the invoked function. + Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked function. + """ + + FAAS_INVOKED_REGION = "faas.invoked_region" + """ + The cloud region of the invoked function. + Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked function. + """ + + NETWORK_CONNECTION_TYPE = "network.connection.type" + """ + The internet connection type. + """ + + NETWORK_CONNECTION_SUBTYPE = "network.connection.subtype" + """ + This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. + """ + + NETWORK_CARRIER_NAME = "network.carrier.name" + """ + The name of the mobile carrier. + """ + + NETWORK_CARRIER_MCC = "network.carrier.mcc" + """ + The mobile carrier country code. + """ + + NETWORK_CARRIER_MNC = "network.carrier.mnc" + """ + The mobile carrier network code. + """ + + NETWORK_CARRIER_ICC = "network.carrier.icc" + """ + The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. + """ + + PEER_SERVICE = "peer.service" + """ + The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. + """ + + ENDUSER_ID = "enduser.id" + """ + Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. + """ + + ENDUSER_ROLE = "enduser.role" + """ + Actual/assumed role the client is making the request under extracted from token or application security context. + """ + + ENDUSER_SCOPE = "enduser.scope" + """ + Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). + """ + + THREAD_ID = "thread.id" + """ + Current "managed" thread ID (as opposed to OS thread ID). + """ + + THREAD_NAME = "thread.name" + """ + Current thread name. + """ + + CODE_FUNCTION = "code.function" + """ + The method or function name, or equivalent (usually rightmost part of the code unit's name). + """ + + CODE_NAMESPACE = "code.namespace" + """ + The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. + """ + + CODE_FILEPATH = "code.filepath" + """ + The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). + """ + + CODE_LINENO = "code.lineno" + """ + The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. + """ + + CODE_COLUMN = "code.column" + """ + The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. + """ + + HTTP_REQUEST_METHOD_ORIGINAL = "http.request.method_original" + """ + Original HTTP method sent by the client in the request line. + """ + + HTTP_REQUEST_BODY_SIZE = "http.request.body.size" + """ + The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. + """ + + HTTP_RESPONSE_BODY_SIZE = "http.response.body.size" + """ + The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. + """ + + HTTP_RESEND_COUNT = "http.resend_count" + """ + The ordinal number of request resending attempt (for any reason, including redirects). + Note: The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). + """ + + RPC_SYSTEM = "rpc.system" + """ + The value `aws-api`. + """ + + RPC_SERVICE = "rpc.service" + """ + The name of the service to which a request is made, as returned by the AWS SDK. + Note: This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + """ + + RPC_METHOD = "rpc.method" + """ + The name of the operation corresponding to the request, as returned by the AWS SDK. + Note: This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + """ + + AWS_REQUEST_ID = "aws.request_id" + """ + The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. + """ + + AWS_DYNAMODB_TABLE_NAMES = "aws.dynamodb.table_names" + """ + The keys in the `RequestItems` object field. + """ + + AWS_DYNAMODB_CONSUMED_CAPACITY = "aws.dynamodb.consumed_capacity" + """ + The JSON-serialized value of each item in the `ConsumedCapacity` response field. + """ + + AWS_DYNAMODB_ITEM_COLLECTION_METRICS = "aws.dynamodb.item_collection_metrics" + """ + The JSON-serialized value of the `ItemCollectionMetrics` response field. + """ + + AWS_DYNAMODB_PROVISIONED_READ_CAPACITY = "aws.dynamodb.provisioned_read_capacity" + """ + The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. + """ + + AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY = "aws.dynamodb.provisioned_write_capacity" + """ + The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. + """ + + AWS_DYNAMODB_CONSISTENT_READ = "aws.dynamodb.consistent_read" + """ + The value of the `ConsistentRead` request parameter. + """ + + AWS_DYNAMODB_PROJECTION = "aws.dynamodb.projection" + """ + The value of the `ProjectionExpression` request parameter. + """ + + AWS_DYNAMODB_LIMIT = "aws.dynamodb.limit" + """ + The value of the `Limit` request parameter. + """ + + AWS_DYNAMODB_ATTRIBUTES_TO_GET = "aws.dynamodb.attributes_to_get" + """ + The value of the `AttributesToGet` request parameter. + """ + + AWS_DYNAMODB_INDEX_NAME = "aws.dynamodb.index_name" + """ + The value of the `IndexName` request parameter. + """ + + AWS_DYNAMODB_SELECT = "aws.dynamodb.select" + """ + The value of the `Select` request parameter. + """ + + AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES = "aws.dynamodb.global_secondary_indexes" + """ + The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field. + """ + + AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES = "aws.dynamodb.local_secondary_indexes" + """ + The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. + """ + + AWS_DYNAMODB_EXCLUSIVE_START_TABLE = "aws.dynamodb.exclusive_start_table" + """ + The value of the `ExclusiveStartTableName` request parameter. + """ + + AWS_DYNAMODB_TABLE_COUNT = "aws.dynamodb.table_count" + """ + The the number of items in the `TableNames` response parameter. + """ + + AWS_DYNAMODB_SCAN_FORWARD = "aws.dynamodb.scan_forward" + """ + The value of the `ScanIndexForward` request parameter. + """ + + AWS_DYNAMODB_SEGMENT = "aws.dynamodb.segment" + """ + The value of the `Segment` request parameter. + """ + + AWS_DYNAMODB_TOTAL_SEGMENTS = "aws.dynamodb.total_segments" + """ + The value of the `TotalSegments` request parameter. + """ + + AWS_DYNAMODB_COUNT = "aws.dynamodb.count" + """ + The value of the `Count` response parameter. + """ + + AWS_DYNAMODB_SCANNED_COUNT = "aws.dynamodb.scanned_count" + """ + The value of the `ScannedCount` response parameter. + """ + + AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS = "aws.dynamodb.attribute_definitions" + """ + The JSON-serialized value of each item in the `AttributeDefinitions` request field. + """ + + AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES = "aws.dynamodb.global_secondary_index_updates" + """ + The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` request field. + """ + + AWS_S3_BUCKET = "aws.s3.bucket" + """ + The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. + Note: The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. + This applies to almost all S3 operations except `list-buckets`. + """ + + AWS_S3_KEY = "aws.s3.key" + """ + The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. + Note: The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. + This applies in particular to the following operations: + + - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) + - [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) + - [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) + - [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) + - [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) + - [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) + - [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) + - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) + - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) + - [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) + - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) + - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). + """ + + AWS_S3_COPY_SOURCE = "aws.s3.copy_source" + """ + The source object (in the form `bucket`/`key`) for the copy operation. + Note: The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter + of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). + This applies in particular to the following operations: + + - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) + - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). + """ + + AWS_S3_UPLOAD_ID = "aws.s3.upload_id" + """ + Upload ID that identifies the multipart upload. + Note: The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter + of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. + This applies in particular to the following operations: + + - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) + - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) + - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) + - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). + """ + + AWS_S3_DELETE = "aws.s3.delete" + """ + The delete request container that specifies the objects to be deleted. + Note: The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. + The `delete` attribute corresponds to the `--delete` parameter of the + [delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). + """ + + AWS_S3_PART_NUMBER = "aws.s3.part_number" + """ + The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. + Note: The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) + and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. + The `part_number` attribute corresponds to the `--part-number` parameter of the + [upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). + """ + + GRAPHQL_OPERATION_NAME = "graphql.operation.name" + """ + The name of the operation being executed. + """ + + GRAPHQL_OPERATION_TYPE = "graphql.operation.type" + """ + The type of the operation being executed. + """ + + GRAPHQL_DOCUMENT = "graphql.document" + """ + The GraphQL document being executed. + Note: The value may be sanitized to exclude sensitive information. + """ + + MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY = "messaging.rabbitmq.destination.routing_key" + """ + RabbitMQ message routing key. + """ + + MESSAGING_KAFKA_MESSAGE_KEY = "messaging.kafka.message.key" + """ + Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. + Note: If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. + """ + + MESSAGING_KAFKA_CONSUMER_GROUP = "messaging.kafka.consumer.group" + """ + Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. + """ + + MESSAGING_KAFKA_DESTINATION_PARTITION = "messaging.kafka.destination.partition" + """ + Partition the message is sent to. + """ + + MESSAGING_KAFKA_MESSAGE_OFFSET = "messaging.kafka.message.offset" + """ + The offset of a record in the corresponding Kafka partition. + """ + + MESSAGING_KAFKA_MESSAGE_TOMBSTONE = "messaging.kafka.message.tombstone" + """ + A boolean that is true if the message is a tombstone. + """ + + MESSAGING_ROCKETMQ_NAMESPACE = "messaging.rocketmq.namespace" + """ + Namespace of RocketMQ resources, resources in different namespaces are individual. + """ + + MESSAGING_ROCKETMQ_CLIENT_GROUP = "messaging.rocketmq.client_group" + """ + Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. + """ + + MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP = "messaging.rocketmq.message.delivery_timestamp" + """ + The timestamp in milliseconds that the delay message is expected to be delivered to consumer. + """ + + MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL = "messaging.rocketmq.message.delay_time_level" + """ + The delay time level for delay message, which determines the message delay time. + """ + + MESSAGING_ROCKETMQ_MESSAGE_GROUP = "messaging.rocketmq.message.group" + """ + It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. + """ + + MESSAGING_ROCKETMQ_MESSAGE_TYPE = "messaging.rocketmq.message.type" + """ + Type of message. + """ + + MESSAGING_ROCKETMQ_MESSAGE_TAG = "messaging.rocketmq.message.tag" + """ + The secondary classifier of message besides topic. + """ + + MESSAGING_ROCKETMQ_MESSAGE_KEYS = "messaging.rocketmq.message.keys" + """ + Key(s) of message, another way to mark message besides message id. + """ + + MESSAGING_ROCKETMQ_CONSUMPTION_MODEL = "messaging.rocketmq.consumption_model" + """ + Model of message consumption. This only applies to consumer spans. + """ + + RPC_GRPC_STATUS_CODE = "rpc.grpc.status_code" + """ + The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. + """ + + RPC_JSONRPC_VERSION = "rpc.jsonrpc.version" + """ + Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 does not specify this, the value can be omitted. + """ + + RPC_JSONRPC_REQUEST_ID = "rpc.jsonrpc.request_id" + """ + `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. + """ + + RPC_JSONRPC_ERROR_CODE = "rpc.jsonrpc.error_code" + """ + `error.code` property of response if it is an error response. + """ + + RPC_JSONRPC_ERROR_MESSAGE = "rpc.jsonrpc.error_message" + """ + `error.message` property of response if it is an error response. + """ + + MESSAGE_TYPE = "message.type" + """ + Whether this is a received or sent message. + """ + + MESSAGE_ID = "message.id" + """ + MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. + Note: This way we guarantee that the values will be consistent between different implementations. + """ + + MESSAGE_COMPRESSED_SIZE = "message.compressed_size" + """ + Compressed size of the message in bytes. + """ + + MESSAGE_UNCOMPRESSED_SIZE = "message.uncompressed_size" + """ + Uncompressed size of the message in bytes. + """ + + RPC_CONNECT_RPC_ERROR_CODE = "rpc.connect_rpc.error_code" + """ + The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. + """ + + EXCEPTION_ESCAPED = "exception.escaped" + """ + SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. + Note: An exception is considered to have escaped (or left) the scope of a span, + if that span is ended while the exception is still logically "in flight". + This may be actually "in flight" in some languages (e.g. if the exception + is passed to a Context manager's `__exit__` method in Python) but will + usually be caught at the point of recording the exception in most languages. + + It is usually not possible to determine at the point where an exception is thrown + whether it will escape the scope of a span. + However, it is trivial to know that an exception + will escape, if one checks for an active exception just before ending the span, + as done in the [example above](#recording-an-exception). + + It follows that an exception may still escape the scope of the span + even if the `exception.escaped` attribute was not set or set to false, + since the event might have been recorded at a time where it was not + clear whether the exception will escape. + """ + + URL_FRAGMENT = "url.fragment" + """ + The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component. + """ + + # Manually defined deprecated attributes + + NET_PEER_IP = "net.peer.ip" + """ + Deprecated, use the `client.socket.address` attribute. + """ + + NET_HOST_IP = "net.host.ip" + """ + Deprecated, use the `server.socket.address` attribute. + """ + + HTTP_SERVER_NAME = "http.server_name" + """ + Deprecated, use the `server.address` attribute. + """ + + HTTP_HOST = "http.host" + """ + Deprecated, use the `server.address` and `server.port` attributes. + """ + + HTTP_RETRY_COUNT = "http.retry_count" + """ + Deprecated, use the `http.resend_count` attribute. + """ + + HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED = "http.request_content_length_uncompressed" + """ + Deprecated, use the `http.request.body.size` attribute. + """ + + HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED = "http.response_content_length_uncompressed" + """ + Deprecated, use the `http.response.body.size` attribute. + """ + + MESSAGING_DESTINATION = "messaging.destination" + """ + Deprecated, use the `messaging.destination.name` attribute. + """ + + MESSAGING_DESTINATION_KIND = "messaging.destination_kind" + """ + Deprecated. + """ + + MESSAGING_TEMP_DESTINATION = "messaging.temp_destination" + """ + Deprecated. Use `messaging.destination.temporary` attribute. + """ + + MESSAGING_PROTOCOL = "messaging.protocol" + """ + Deprecated. Use `network.protocol.name` attribute. + """ + + MESSAGING_PROTOCOL_VERSION = "messaging.protocol_version" + """ + Deprecated. Use `network.protocol.version` attribute. + """ + + MESSAGING_URL = "messaging.url" + """ + Deprecated. Use `server.address` and `server.port` attributes. + """ + + MESSAGING_CONVERSATION_ID = "messaging.conversation_id" + """ + Deprecated. Use `messaging.message.conversation.id` attribute. + """ + + MESSAGING_KAFKA_PARTITION = "messaging.kafka.partition" + """ + Deprecated. Use `messaging.kafka.destination.partition` attribute. + """ + + FAAS_EXECUTION = "faas.execution" + """ + Deprecated. Use `faas.invocation_id` attribute. + """ + + HTTP_USER_AGENT = "http.user_agent" + """ + Deprecated. Use `user_agent.original` attribute. + """ + + MESSAGING_RABBITMQ_ROUTING_KEY = "messaging.rabbitmq.routing_key" + """ + Deprecated. Use `messaging.rabbitmq.destination.routing_key` attribute. + """ + + MESSAGING_KAFKA_TOMBSTONE = "messaging.kafka.tombstone" + """ + Deprecated. Use `messaging.kafka.destination.tombstone` attribute. + """ + + NET_APP_PROTOCOL_NAME = "net.app.protocol.name" + """ + Deprecated. Use `network.protocol.name` attribute. + """ + + NET_APP_PROTOCOL_VERSION = "net.app.protocol.version" + """ + Deprecated. Use `network.protocol.version` attribute. + """ + + HTTP_CLIENT_IP = "http.client_ip" + """ + Deprecated. Use `client.address` attribute. + """ + + HTTP_FLAVOR = "http.flavor" + """ + Deprecated. Use `network.protocol.name` and `network.protocol.version` attributes. + """ + + NET_HOST_CONNECTION_TYPE = "net.host.connection.type" + """ + Deprecated. Use `network.connection.type` attribute. + """ + + NET_HOST_CONNECTION_SUBTYPE = "net.host.connection.subtype" + """ + Deprecated. Use `network.connection.subtype` attribute. + """ + + NET_HOST_CARRIER_NAME = "net.host.carrier.name" + """ + Deprecated. Use `network.carrier.name` attribute. + """ + + NET_HOST_CARRIER_MCC = "net.host.carrier.mcc" + """ + Deprecated. Use `network.carrier.mcc` attribute. + """ + + NET_HOST_CARRIER_MNC = "net.host.carrier.mnc" + """ + Deprecated. Use `network.carrier.mnc` attribute. + """ + + MESSAGING_CONSUMER_ID = "messaging.consumer_id" + """ + Deprecated. Use `messaging.client_id` attribute. + """ + + MESSAGING_KAFKA_CLIENT_ID = "messaging.kafka.client_id" + """ + Deprecated. Use `messaging.client_id` attribute. + """ + + MESSAGING_ROCKETMQ_CLIENT_ID = "messaging.rocketmq.client_id" + """ + Deprecated. Use `messaging.client_id` attribute. + """ + + +@deprecated( + "Removed from the specification in favor of `network.protocol.name` and `network.protocol.version` attributes. Deprecated since version 1.18.0.", +) +class HttpFlavorValues(Enum): + HTTP_1_0 = "1.0" + + HTTP_1_1 = "1.1" + + HTTP_2_0 = "2.0" + + HTTP_3_0 = "3.0" + + SPDY = "SPDY" + + QUIC = "QUIC" + + +@deprecated( + "Removed from the specification. Deprecated since version 1.18.0.", +) +class MessagingDestinationKindValues(Enum): + QUEUE = "queue" + """A message sent to a queue.""" + + TOPIC = "topic" + """A message sent to a topic.""" + + +@deprecated( + "Renamed to NetworkConnectionTypeValues. Deprecated since version 1.21.0.", +) +class NetHostConnectionTypeValues(Enum): + WIFI = "wifi" + """wifi.""" + + WIRED = "wired" + """wired.""" + + CELL = "cell" + """cell.""" + + UNAVAILABLE = "unavailable" + """unavailable.""" + + UNKNOWN = "unknown" + """unknown.""" + + +@deprecated( + "Renamed to NetworkConnectionSubtypeValues. Deprecated since version 1.21.0.", +) +class NetHostConnectionSubtypeValues(Enum): + GPRS = "gprs" + """GPRS.""" + + EDGE = "edge" + """EDGE.""" + + UMTS = "umts" + """UMTS.""" + + CDMA = "cdma" + """CDMA.""" + + EVDO_0 = "evdo_0" + """EVDO Rel. 0.""" + + EVDO_A = "evdo_a" + """EVDO Rev. A.""" + + CDMA2000_1XRTT = "cdma2000_1xrtt" + """CDMA2000 1XRTT.""" + + HSDPA = "hsdpa" + """HSDPA.""" + + HSUPA = "hsupa" + """HSUPA.""" + + HSPA = "hspa" + """HSPA.""" + + IDEN = "iden" + """IDEN.""" + + EVDO_B = "evdo_b" + """EVDO Rev. B.""" + + LTE = "lte" + """LTE.""" + + EHRPD = "ehrpd" + """EHRPD.""" + + HSPAP = "hspap" + """HSPAP.""" + + GSM = "gsm" + """GSM.""" + + TD_SCDMA = "td_scdma" + """TD-SCDMA.""" + + IWLAN = "iwlan" + """IWLAN.""" + + NR = "nr" + """5G NR (New Radio).""" + + NRNSA = "nrnsa" + """5G NRNSA (New Radio Non-Standalone).""" + + LTE_CA = "lte_ca" + """LTE CA.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv.attributes.NetworkTransportValues` instead. Deprecated since version 1.25.0.", +) +class NetTransportValues(Enum): + IP_TCP = "ip_tcp" + """ip_tcp.""" + + IP_UDP = "ip_udp" + """ip_udp.""" + + PIPE = "pipe" + """Named or anonymous pipe.""" + + INPROC = "inproc" + """In-process communication.""" + + OTHER = "other" + """Something else (non IP-based).""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv.attributes.NetworkType` instead. Deprecated since version 1.25.0.", +) +class NetSockFamilyValues(Enum): + INET = "inet" + """IPv4 address.""" + + INET6 = "inet6" + """IPv6 address.""" + + UNIX = "unix" + """Unix domain socket path.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv.attributes.HttpRequestMethodValues` instead. Deprecated since version 1.25.0.", +) +class HttpRequestMethodValues(Enum): + CONNECT = "CONNECT" + """CONNECT method.""" + + DELETE = "DELETE" + """DELETE method.""" + + GET = "GET" + """GET method.""" + + HEAD = "HEAD" + """HEAD method.""" + + OPTIONS = "OPTIONS" + """OPTIONS method.""" + + PATCH = "PATCH" + """PATCH method.""" + + POST = "POST" + """POST method.""" + + PUT = "PUT" + """PUT method.""" + + TRACE = "TRACE" + """TRACE method.""" + + OTHER = "_OTHER" + """Any HTTP method that the instrumentation has no prior knowledge of.""" + + +@deprecated("Removed from the specification. Deprecated since version 1.25.0.") +class EventDomainValues(Enum): + BROWSER = "browser" + """Events from browser apps.""" + + DEVICE = "device" + """Events from mobile apps.""" + + K8S = "k8s" + """Events from Kubernetes.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv._incubating.attributes.LogIostreamValues` instead. Deprecated since version 1.25.0.", +) +class LogIostreamValues(Enum): + STDOUT = "stdout" + """Logs from stdout stream.""" + + STDERR = "stderr" + """Events from stderr stream.""" + + +@deprecated("Removed from the specification. Deprecated since version 1.25.0.") +class TypeValues(Enum): + HEAP = "heap" + """Heap memory.""" + + NON_HEAP = "non_heap" + """Non-heap memory.""" + + +@deprecated( + "Use :py:const:`opentelemetry.semconv._incubating.attributes.OpentracingRefTypeValues` instead. Deprecated since version 1.25.0.", +) +class OpentracingRefTypeValues(Enum): + CHILD_OF = "child_of" + """The parent Span depends on the child Span in some capacity.""" + + FOLLOWS_FROM = "follows_from" + """The parent Span does not depend in any way on the result of the child Span.""" + + +class DbSystemValues(Enum): + OTHER_SQL = "other_sql" + """Some other SQL database. Fallback only. See notes.""" + + MSSQL = "mssql" + """Microsoft SQL Server.""" + + MSSQLCOMPACT = "mssqlcompact" + """Microsoft SQL Server Compact.""" + + MYSQL = "mysql" + """MySQL.""" + + ORACLE = "oracle" + """Oracle Database.""" + + DB2 = "db2" + """IBM Db2.""" + + POSTGRESQL = "postgresql" + """PostgreSQL.""" + + REDSHIFT = "redshift" + """Amazon Redshift.""" + + HIVE = "hive" + """Apache Hive.""" + + CLOUDSCAPE = "cloudscape" + """Cloudscape.""" + + HSQLDB = "hsqldb" + """HyperSQL DataBase.""" + + PROGRESS = "progress" + """Progress Database.""" + + MAXDB = "maxdb" + """SAP MaxDB.""" + + HANADB = "hanadb" + """SAP HANA.""" + + INGRES = "ingres" + """Ingres.""" + + FIRSTSQL = "firstsql" + """FirstSQL.""" + + EDB = "edb" + """EnterpriseDB.""" + + CACHE = "cache" + """InterSystems Caché.""" + + ADABAS = "adabas" + """Adabas (Adaptable Database System).""" + + FIREBIRD = "firebird" + """Firebird.""" + + DERBY = "derby" + """Apache Derby.""" + + FILEMAKER = "filemaker" + """FileMaker.""" + + INFORMIX = "informix" + """Informix.""" + + INSTANTDB = "instantdb" + """InstantDB.""" + + INTERBASE = "interbase" + """InterBase.""" + + MARIADB = "mariadb" + """MariaDB.""" + + NETEZZA = "netezza" + """Netezza.""" + + PERVASIVE = "pervasive" + """Pervasive PSQL.""" + + POINTBASE = "pointbase" + """PointBase.""" + + SQLITE = "sqlite" + """SQLite.""" + + SYBASE = "sybase" + """Sybase.""" + + TERADATA = "teradata" + """Teradata.""" + + VERTICA = "vertica" + """Vertica.""" + + H2 = "h2" + """H2.""" + + COLDFUSION = "coldfusion" + """ColdFusion IMQ.""" + + CASSANDRA = "cassandra" + """Apache Cassandra.""" + + HBASE = "hbase" + """Apache HBase.""" + + MONGODB = "mongodb" + """MongoDB.""" + + REDIS = "redis" + """Redis.""" + + COUCHBASE = "couchbase" + """Couchbase.""" + + COUCHDB = "couchdb" + """CouchDB.""" + + COSMOSDB = "cosmosdb" + """Microsoft Azure Cosmos DB.""" + + DYNAMODB = "dynamodb" + """Amazon DynamoDB.""" + + NEO4J = "neo4j" + """Neo4j.""" + + GEODE = "geode" + """Apache Geode.""" + + ELASTICSEARCH = "elasticsearch" + """Elasticsearch.""" + + MEMCACHED = "memcached" + """Memcached.""" + + COCKROACHDB = "cockroachdb" + """CockroachDB.""" + + OPENSEARCH = "opensearch" + """OpenSearch.""" + + CLICKHOUSE = "clickhouse" + """ClickHouse.""" + + SPANNER = "spanner" + """Cloud Spanner.""" + + TRINO = "trino" + """Trino.""" + + +class NetworkTransportValues(Enum): + TCP = "tcp" + """TCP.""" + + UDP = "udp" + """UDP.""" + + PIPE = "pipe" + """Named or anonymous pipe. See note below.""" + + UNIX = "unix" + """Unix domain socket.""" + + +class NetworkTypeValues(Enum): + IPV4 = "ipv4" + """IPv4.""" + + IPV6 = "ipv6" + """IPv6.""" + + +class DbCassandraConsistencyLevelValues(Enum): + ALL = "all" + """all.""" + + EACH_QUORUM = "each_quorum" + """each_quorum.""" + + QUORUM = "quorum" + """quorum.""" + + LOCAL_QUORUM = "local_quorum" + """local_quorum.""" + + ONE = "one" + """one.""" + + TWO = "two" + """two.""" + + THREE = "three" + """three.""" + + LOCAL_ONE = "local_one" + """local_one.""" + + ANY = "any" + """any.""" + + SERIAL = "serial" + """serial.""" + + LOCAL_SERIAL = "local_serial" + """local_serial.""" + + +class DbCosmosdbOperationTypeValues(Enum): + INVALID = "Invalid" + """invalid.""" + + CREATE = "Create" + """create.""" + + PATCH = "Patch" + """patch.""" + + READ = "Read" + """read.""" + + READ_FEED = "ReadFeed" + """read_feed.""" + + DELETE = "Delete" + """delete.""" + + REPLACE = "Replace" + """replace.""" + + EXECUTE = "Execute" + """execute.""" + + QUERY = "Query" + """query.""" + + HEAD = "Head" + """head.""" + + HEAD_FEED = "HeadFeed" + """head_feed.""" + + UPSERT = "Upsert" + """upsert.""" + + BATCH = "Batch" + """batch.""" + + QUERY_PLAN = "QueryPlan" + """query_plan.""" + + EXECUTE_JAVASCRIPT = "ExecuteJavaScript" + """execute_javascript.""" + + +class DbCosmosdbConnectionModeValues(Enum): + GATEWAY = "gateway" + """Gateway (HTTP) connections mode.""" + + DIRECT = "direct" + """Direct connection.""" + + +class OtelStatusCodeValues(Enum): + OK = "OK" + """The operation has been validated by an Application developer or Operator to have completed successfully.""" + + ERROR = "ERROR" + """The operation contains an error.""" + + +class FaasTriggerValues(Enum): + DATASOURCE = "datasource" + """A response to some data source operation such as a database or filesystem read/write.""" + + HTTP = "http" + """To provide an answer to an inbound HTTP request.""" + + PUBSUB = "pubsub" + """A function is set to be executed when messages are sent to a messaging system.""" + + TIMER = "timer" + """A function is scheduled to be executed regularly.""" + + OTHER = "other" + """If none of the others apply.""" + + +class FaasDocumentOperationValues(Enum): + INSERT = "insert" + """When a new object is created.""" + + EDIT = "edit" + """When an object is modified.""" + + DELETE = "delete" + """When an object is deleted.""" + + +class MessagingOperationValues(Enum): + PUBLISH = "publish" + """publish.""" + + RECEIVE = "receive" + """receive.""" + + PROCESS = "process" + """process.""" + + +class FaasInvokedProviderValues(Enum): + ALIBABA_CLOUD = "alibaba_cloud" + """Alibaba Cloud.""" + + AWS = "aws" + """Amazon Web Services.""" + + AZURE = "azure" + """Microsoft Azure.""" + + GCP = "gcp" + """Google Cloud Platform.""" + + TENCENT_CLOUD = "tencent_cloud" + """Tencent Cloud.""" + + +class NetworkConnectionTypeValues(Enum): + WIFI = "wifi" + """wifi.""" + + WIRED = "wired" + """wired.""" + + CELL = "cell" + """cell.""" + + UNAVAILABLE = "unavailable" + """unavailable.""" + + UNKNOWN = "unknown" + """unknown.""" + + +class NetworkConnectionSubtypeValues(Enum): + GPRS = "gprs" + """GPRS.""" + + EDGE = "edge" + """EDGE.""" + + UMTS = "umts" + """UMTS.""" + + CDMA = "cdma" + """CDMA.""" + + EVDO_0 = "evdo_0" + """EVDO Rel. 0.""" + + EVDO_A = "evdo_a" + """EVDO Rev. A.""" + + CDMA2000_1XRTT = "cdma2000_1xrtt" + """CDMA2000 1XRTT.""" + + HSDPA = "hsdpa" + """HSDPA.""" + + HSUPA = "hsupa" + """HSUPA.""" + + HSPA = "hspa" + """HSPA.""" + + IDEN = "iden" + """IDEN.""" + + EVDO_B = "evdo_b" + """EVDO Rev. B.""" + + LTE = "lte" + """LTE.""" + + EHRPD = "ehrpd" + """EHRPD.""" + + HSPAP = "hspap" + """HSPAP.""" + + GSM = "gsm" + """GSM.""" + + TD_SCDMA = "td_scdma" + """TD-SCDMA.""" + + IWLAN = "iwlan" + """IWLAN.""" + + NR = "nr" + """5G NR (New Radio).""" + + NRNSA = "nrnsa" + """5G NRNSA (New Radio Non-Standalone).""" + + LTE_CA = "lte_ca" + """LTE CA.""" + + +class RpcSystemValues(Enum): + GRPC = "grpc" + """gRPC.""" + + JAVA_RMI = "java_rmi" + """Java RMI.""" + + DOTNET_WCF = "dotnet_wcf" + """.NET WCF.""" + + APACHE_DUBBO = "apache_dubbo" + """Apache Dubbo.""" + + CONNECT_RPC = "connect_rpc" + """Connect RPC.""" + + +class GraphqlOperationTypeValues(Enum): + QUERY = "query" + """GraphQL query.""" + + MUTATION = "mutation" + """GraphQL mutation.""" + + SUBSCRIPTION = "subscription" + """GraphQL subscription.""" + + +class MessagingRocketmqMessageTypeValues(Enum): + NORMAL = "normal" + """Normal message.""" + + FIFO = "fifo" + """FIFO message.""" + + DELAY = "delay" + """Delay message.""" + + TRANSACTION = "transaction" + """Transaction message.""" + + +class MessagingRocketmqConsumptionModelValues(Enum): + CLUSTERING = "clustering" + """Clustering consumption model.""" + + BROADCASTING = "broadcasting" + """Broadcasting consumption model.""" + + +class RpcGrpcStatusCodeValues(Enum): + OK = 0 + """OK.""" + + CANCELLED = 1 + """CANCELLED.""" + + UNKNOWN = 2 + """UNKNOWN.""" + + INVALID_ARGUMENT = 3 + """INVALID_ARGUMENT.""" + + DEADLINE_EXCEEDED = 4 + """DEADLINE_EXCEEDED.""" + + NOT_FOUND = 5 + """NOT_FOUND.""" + + ALREADY_EXISTS = 6 + """ALREADY_EXISTS.""" + + PERMISSION_DENIED = 7 + """PERMISSION_DENIED.""" + + RESOURCE_EXHAUSTED = 8 + """RESOURCE_EXHAUSTED.""" + + FAILED_PRECONDITION = 9 + """FAILED_PRECONDITION.""" + + ABORTED = 10 + """ABORTED.""" + + OUT_OF_RANGE = 11 + """OUT_OF_RANGE.""" + + UNIMPLEMENTED = 12 + """UNIMPLEMENTED.""" + + INTERNAL = 13 + """INTERNAL.""" + + UNAVAILABLE = 14 + """UNAVAILABLE.""" + + DATA_LOSS = 15 + """DATA_LOSS.""" + + UNAUTHENTICATED = 16 + """UNAUTHENTICATED.""" + + +class MessageTypeValues(Enum): + SENT = "SENT" + """sent.""" + + RECEIVED = "RECEIVED" + """received.""" + + +class RpcConnectRpcErrorCodeValues(Enum): + CANCELLED = "cancelled" + """cancelled.""" + + UNKNOWN = "unknown" + """unknown.""" + + INVALID_ARGUMENT = "invalid_argument" + """invalid_argument.""" + + DEADLINE_EXCEEDED = "deadline_exceeded" + """deadline_exceeded.""" + + NOT_FOUND = "not_found" + """not_found.""" + + ALREADY_EXISTS = "already_exists" + """already_exists.""" + + PERMISSION_DENIED = "permission_denied" + """permission_denied.""" + + RESOURCE_EXHAUSTED = "resource_exhausted" + """resource_exhausted.""" + + FAILED_PRECONDITION = "failed_precondition" + """failed_precondition.""" + + ABORTED = "aborted" + """aborted.""" + + OUT_OF_RANGE = "out_of_range" + """out_of_range.""" + + UNIMPLEMENTED = "unimplemented" + """unimplemented.""" + + INTERNAL = "internal" + """internal.""" + + UNAVAILABLE = "unavailable" + """unavailable.""" + + DATA_LOSS = "data_loss" + """data_loss.""" + + UNAUTHENTICATED = "unauthenticated" + """unauthenticated.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py new file mode 100644 index 00000000000..9e0fac92eaf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py @@ -0,0 +1,661 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +The OpenTelemetry tracing API describes the classes used to generate +distributed traces. + +The :class:`.Tracer` class controls access to the execution context, and +manages span creation. Each operation in a trace is represented by a +:class:`.Span`, which records the start, end time, and metadata associated with +the operation. + +This module provides abstract (i.e. unimplemented) classes required for +tracing, and a concrete no-op :class:`.NonRecordingSpan` that allows applications +to use the API package alone without a supporting implementation. + +To get a tracer, you need to provide the package name from which you are +calling the tracer APIs to OpenTelemetry by calling `TracerProvider.get_tracer` +with the calling module name and the version of your package. + +The tracer supports creating spans that are "attached" or "detached" from the +context. New spans are "attached" to the context in that they are +created as children of the currently active span, and the newly-created span +can optionally become the new active span:: + + from opentelemetry import trace + + tracer = trace.get_tracer(__name__) + + # Create a new root span, set it as the current span in context + with tracer.start_as_current_span("parent"): + # Attach a new child and update the current span + with tracer.start_as_current_span("child"): + do_work(): + # Close child span, set parent as current + # Close parent span, set default span as current + +When creating a span that's "detached" from the context the active span doesn't +change, and the caller is responsible for managing the span's lifetime:: + + # Explicit parent span assignment is done via the Context + from opentelemetry.trace import set_span_in_context + + context = set_span_in_context(parent) + child = tracer.start_span("child", context=context) + + try: + do_work(span=child) + finally: + child.end() + +Applications should generally use a single global TracerProvider, and use +either implicit or explicit context propagation consistently throughout. + +.. versionadded:: 0.1.0 +.. versionchanged:: 0.3.0 + `TracerProvider` was introduced and the global ``tracer`` getter was + replaced by ``tracer_provider``. +.. versionchanged:: 0.5.0 + ``tracer_provider`` was replaced by `get_tracer_provider`, + ``set_preferred_tracer_provider_implementation`` was replaced by + `set_tracer_provider`. +""" + +import os +from abc import ABC, abstractmethod +from collections.abc import Iterator, Sequence +from enum import Enum +from logging import getLogger +from typing import cast + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +from opentelemetry.agent._vendor.opentelemetry import context as context_api +from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER +from opentelemetry.agent._vendor.opentelemetry.trace.propagation import ( + _SPAN_KEY, + get_current_span, + set_span_in_context, +) +from opentelemetry.agent._vendor.opentelemetry.trace.span import ( + DEFAULT_TRACE_OPTIONS, + DEFAULT_TRACE_STATE, + INVALID_SPAN, + INVALID_SPAN_CONTEXT, + INVALID_SPAN_ID, + INVALID_TRACE_ID, + NonRecordingSpan, + Span, + SpanContext, + TraceFlags, + TraceState, + format_span_id, + format_trace_id, +) +from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode +from opentelemetry.agent._vendor.opentelemetry.util import types +from opentelemetry.agent._vendor.opentelemetry.util._decorator import _agnosticcontextmanager +from opentelemetry.agent._vendor.opentelemetry.util._once import Once +from opentelemetry.agent._vendor.opentelemetry.util._providers import _load_provider + +logger = getLogger(__name__) + + +class _LinkBase(ABC): + def __init__(self, context: "SpanContext") -> None: + self._context = context + + @property + def context(self) -> "SpanContext": + return self._context + + @property + @abstractmethod + def attributes(self) -> types.Attributes: + pass + + +class Link(_LinkBase): + """A link to a `Span`. The attributes of a Link are immutable. + + Args: + context: `SpanContext` of the `Span` to link to. + attributes: Link's attributes. + """ + + def __init__( + self, + context: "SpanContext", + attributes: types.Attributes = None, + ) -> None: + super().__init__(context) + self._attributes = attributes + + @property + def attributes(self) -> types.Attributes: + return self._attributes + + @property + def dropped_attributes(self) -> int: + if isinstance(self._attributes, BoundedAttributes): + return self._attributes.dropped + return 0 + + +_Links = Sequence[Link] | None + + +class SpanKind(Enum): + """Specifies additional details on how this span relates to its parent span. + + Note that this enumeration is experimental and likely to change. See + https://github.com/open-telemetry/opentelemetry-specification/pull/226. + """ + + #: Default value. Indicates that the span is used internally in the + # application. + INTERNAL = 0 + + #: Indicates that the span describes an operation that handles a remote + # request. + SERVER = 1 + + #: Indicates that the span describes a request to some remote service. + CLIENT = 2 + + #: Indicates that the span describes a producer sending a message to a + #: broker. Unlike client and server, there is usually no direct critical + #: path latency relationship between producer and consumer spans. + PRODUCER = 3 + + #: Indicates that the span describes a consumer receiving a message from a + #: broker. Unlike client and server, there is usually no direct critical + #: path latency relationship between producer and consumer spans. + CONSUMER = 4 + + +class TracerProvider(ABC): + @abstractmethod + def get_tracer( + self, + instrumenting_module_name: str, + instrumenting_library_version: str | None = None, + schema_url: str | None = None, + attributes: types.Attributes = None, + ) -> "Tracer": + """Returns a `Tracer` for use by the given instrumentation library. + + For any two calls it is undefined whether the same or different + `Tracer` instances are returned, even for different library names. + + This function may return different `Tracer` types (e.g. a no-op tracer + vs. a functional tracer). + + Args: + instrumenting_module_name: The uniquely identifiable name for instrumentation + scope, such as instrumentation library, package, module or class name. + ``__name__`` should be avoided as this can result in + different tracer names if the tracers are in different files. + It is better to use a fixed string that can be imported where + needed and used consistently as the name of the tracer. + + This should *not* be the name of the module that is + instrumented but the name of the module doing the instrumentation. + E.g., instead of ``"requests"``, use + ``"opentelemetry.instrumentation.requests"``. + + instrumenting_library_version: Optional. The version string of the + instrumenting library. Usually this should be the same as + ``importlib.metadata.version(instrumenting_library_name)``. + + schema_url: Optional. Specifies the Schema URL of the emitted telemetry. + attributes: Optional. Specifies the attributes of the emitted telemetry. + """ + + +class NoOpTracerProvider(TracerProvider): + """The default TracerProvider, used when no implementation is available. + + All operations are no-op. + """ + + def get_tracer( + self, + instrumenting_module_name: str, + instrumenting_library_version: str | None = None, + schema_url: str | None = None, + attributes: types.Attributes = None, + ) -> "Tracer": + # pylint:disable=no-self-use,unused-argument + return NoOpTracer() + + +@deprecated("You should use NoOpTracerProvider. Deprecated since version 1.9.0.") +class _DefaultTracerProvider(NoOpTracerProvider): + """The default TracerProvider, used when no implementation is available. + + All operations are no-op. + """ + + +class ProxyTracerProvider(TracerProvider): + def get_tracer( + self, + instrumenting_module_name: str, + instrumenting_library_version: str | None = None, + schema_url: str | None = None, + attributes: types.Attributes = None, + ) -> "Tracer": + if _TRACER_PROVIDER: + return _TRACER_PROVIDER.get_tracer( + instrumenting_module_name, + instrumenting_library_version, + schema_url, + attributes, + ) + return ProxyTracer( + instrumenting_module_name, + instrumenting_library_version, + schema_url, + attributes, + ) + + +class Tracer(ABC): + """Handles span creation and in-process context propagation. + + This class provides methods for manipulating the context, creating spans, + and controlling spans' lifecycles. + """ + + @abstractmethod + def start_span( + self, + name: str, + context: Context | None = None, + kind: SpanKind = SpanKind.INTERNAL, + attributes: types.Attributes = None, + links: _Links = None, + start_time: int | None = None, + record_exception: bool = True, + set_status_on_exception: bool = True, + ) -> "Span": + """Starts a span. + + Create a new span. Start the span without setting it as the current + span in the context. To start the span and use the context in a single + method, see :meth:`start_as_current_span`. + + By default the current span in the context will be used as parent, but an + explicit context can also be specified, by passing in a `Context` containing + a current `Span`. If there is no current span in the global `Context` or in + the specified context, the created span will be a root span. + + The span can be used as a context manager. On exiting the context manager, + the span's end() method will be called. + + Example:: + + # trace.get_current_span() will be used as the implicit parent. + # If none is found, the created span will be a root instance. + with tracer.start_span("one") as child: + child.add_event("child's event") + + Args: + name: The name of the span to be created. + context: An optional Context containing the span's parent. Defaults to the + global context. + kind: The span's kind (relationship to parent). Note that is + meaningful even if there is no parent. + attributes: The span's attributes. + links: Links span to other spans + start_time: Sets the start time of a span + record_exception: Whether to record any exceptions raised within the + context as error event on the span. + set_status_on_exception: Only relevant if the returned span is used + in a with/context manager. Defines whether the span status will + be automatically set to ERROR when an uncaught exception is + raised in the span with block. The span status won't be set by + this mechanism if it was previously set manually. + + Returns: + The newly-created span. + """ + + @_agnosticcontextmanager + @abstractmethod + def start_as_current_span( + self, + name: str, + context: Context | None = None, + kind: SpanKind = SpanKind.INTERNAL, + attributes: types.Attributes = None, + links: _Links = None, + start_time: int | None = None, + record_exception: bool = True, + set_status_on_exception: bool = True, + end_on_exit: bool = True, + ) -> Iterator["Span"]: + """Context manager for creating a new span and set it + as the current span in this tracer's context. + + Exiting the context manager will call the span's end method, + as well as return the current span to its previous value by + returning to the previous context. + + Example:: + + with tracer.start_as_current_span("one") as parent: + parent.add_event("parent's event") + with tracer.start_as_current_span("two") as child: + child.add_event("child's event") + trace.get_current_span() # returns child + trace.get_current_span() # returns parent + trace.get_current_span() # returns previously active span + + This is a convenience method for creating spans attached to the + tracer's context. Applications that need more control over the span + lifetime should use :meth:`start_span` instead. For example:: + + with tracer.start_as_current_span(name) as span: + do_work() + + is equivalent to:: + + span = tracer.start_span(name) + with opentelemetry.trace.use_span(span, end_on_exit=True): + do_work() + + This can also be used as a decorator:: + + @tracer.start_as_current_span("name") + def function(): ... + + + function() + + Args: + name: The name of the span to be created. + context: An optional Context containing the span's parent. Defaults to the + global context. + kind: The span's kind (relationship to parent). Note that is + meaningful even if there is no parent. + attributes: The span's attributes. + links: Links span to other spans + start_time: Sets the start time of a span + record_exception: Whether to record any exceptions raised within the + context as error event on the span. + set_status_on_exception: Only relevant if the returned span is used + in a with/context manager. Defines whether the span status will + be automatically set to ERROR when an uncaught exception is + raised in the span with block. The span status won't be set by + this mechanism if it was previously set manually. + end_on_exit: Whether to end the span automatically when leaving the + context manager. + + Yields: + The newly-created span. + """ + + +class ProxyTracer(Tracer): + # pylint: disable=W0222,signature-differs + def __init__( + self, + instrumenting_module_name: str, + instrumenting_library_version: str | None = None, + schema_url: str | None = None, + attributes: types.Attributes = None, + ): + self._instrumenting_module_name = instrumenting_module_name + self._instrumenting_library_version = instrumenting_library_version + self._schema_url = schema_url + self._attributes = attributes + self._real_tracer: Tracer | None = None + self._noop_tracer = NoOpTracer() + + @property + def _tracer(self) -> Tracer: + if self._real_tracer: + return self._real_tracer + + if _TRACER_PROVIDER: + self._real_tracer = _TRACER_PROVIDER.get_tracer( + self._instrumenting_module_name, + self._instrumenting_library_version, + self._schema_url, + self._attributes, + ) + return self._real_tracer + return self._noop_tracer + + def start_span(self, *args, **kwargs) -> Span: # type: ignore + return self._tracer.start_span(*args, **kwargs) # type: ignore + + @_agnosticcontextmanager # type: ignore + def start_as_current_span(self, *args, **kwargs) -> Iterator[Span]: + with self._tracer.start_as_current_span(*args, **kwargs) as span: # type: ignore + yield span + + +class NoOpTracer(Tracer): + """The default Tracer, used when no Tracer implementation is available. + + All operations are no-op. + """ + + def start_span( + self, + name: str, + context: Context | None = None, + kind: SpanKind = SpanKind.INTERNAL, + attributes: types.Attributes = None, + links: _Links = None, + start_time: int | None = None, + record_exception: bool = True, + set_status_on_exception: bool = True, + ) -> "Span": + current_span = get_current_span(context) + if isinstance(current_span, NonRecordingSpan): + return current_span + parent_span_context = current_span.get_span_context() + if parent_span_context is not None and not isinstance(parent_span_context, SpanContext): + logger.warning( + "Invalid span context for %s: %s", + current_span, + parent_span_context, + ) + return INVALID_SPAN + + return NonRecordingSpan(context=parent_span_context) + + @_agnosticcontextmanager + def start_as_current_span( + self, + name: str, + context: Context | None = None, + kind: SpanKind = SpanKind.INTERNAL, + attributes: types.Attributes = None, + links: _Links = None, + start_time: int | None = None, + record_exception: bool = True, + set_status_on_exception: bool = True, + end_on_exit: bool = True, + ) -> Iterator["Span"]: + span = self.start_span( + name=name, + context=context, + kind=kind, + attributes=attributes, + links=links, + start_time=start_time, + record_exception=record_exception, + set_status_on_exception=set_status_on_exception, + ) + with use_span( + span, + end_on_exit=end_on_exit, + record_exception=record_exception, + set_status_on_exception=set_status_on_exception, + ) as span: + yield span + + +@deprecated("You should use NoOpTracer. Deprecated since version 1.9.0.") +class _DefaultTracer(NoOpTracer): + """The default Tracer, used when no Tracer implementation is available. + + All operations are no-op. + """ + + +_TRACER_PROVIDER_SET_ONCE = Once() +_TRACER_PROVIDER: TracerProvider | None = None +_PROXY_TRACER_PROVIDER = ProxyTracerProvider() + + +def get_tracer( + instrumenting_module_name: str, + instrumenting_library_version: str | None = None, + tracer_provider: TracerProvider | None = None, + schema_url: str | None = None, + attributes: types.Attributes = None, +) -> "Tracer": + """Returns a `Tracer` for use by the given instrumentation library. + + This function is a convenience wrapper for + opentelemetry.trace.TracerProvider.get_tracer. + + If tracer_provider is omitted the current configured one is used. + """ + if tracer_provider is None: + tracer_provider = get_tracer_provider() + return tracer_provider.get_tracer( + instrumenting_module_name, + instrumenting_library_version, + schema_url, + attributes, + ) + + +def _set_tracer_provider(tracer_provider: TracerProvider, log: bool) -> None: + def set_tp() -> None: + global _TRACER_PROVIDER # pylint: disable=global-statement + _TRACER_PROVIDER = tracer_provider + + did_set = _TRACER_PROVIDER_SET_ONCE.do_once(set_tp) + + if log and not did_set: + logger.warning("Overriding of current TracerProvider is not allowed") + + +def set_tracer_provider(tracer_provider: TracerProvider) -> None: + """Sets the current global :class:`~.TracerProvider` object. + + This can only be done once, a warning will be logged if any further attempt + is made. + """ + _set_tracer_provider(tracer_provider, log=True) + + +def get_tracer_provider() -> TracerProvider: + """Gets the current global :class:`~.TracerProvider` object.""" + if _TRACER_PROVIDER is None: + # if a global tracer provider has not been set either via code or env + # vars, return a proxy tracer provider + if OTEL_PYTHON_TRACER_PROVIDER not in os.environ: + return _PROXY_TRACER_PROVIDER + + tracer_provider: TracerProvider = _load_provider(OTEL_PYTHON_TRACER_PROVIDER, "tracer_provider") + _set_tracer_provider(tracer_provider, log=False) + # _TRACER_PROVIDER will have been set by one thread + return cast("TracerProvider", _TRACER_PROVIDER) + + +@_agnosticcontextmanager +def use_span( + span: Span, + end_on_exit: bool = False, + record_exception: bool = True, + set_status_on_exception: bool = True, +) -> Iterator[Span]: + """Takes a non-active span and activates it in the current context. + + Args: + span: The span that should be activated in the current context. + end_on_exit: Whether to end the span automatically when leaving the + context manager scope. + record_exception: Whether to record any exceptions raised within the + context as error event on the span. + set_status_on_exception: Only relevant if the returned span is used + in a with/context manager. Defines whether the span status will + be automatically set to ERROR when an uncaught exception is + raised in the span with block. The span status won't be set by + this mechanism if it was previously set manually. + """ + try: + token = context_api.attach(context_api.set_value(_SPAN_KEY, span)) + try: + yield span + finally: + context_api.detach(token) + + # Record only exceptions that inherit Exception class but not BaseException, because + # classes that directly inherit BaseException are not technically errors, e.g. GeneratorExit. + # See https://github.com/open-telemetry/opentelemetry-python/issues/4484 + except Exception as exc: # pylint: disable=broad-exception-caught + if isinstance(span, Span) and span.is_recording(): + # Record the exception as an event + if record_exception: + span.record_exception(exc) + + # Set status in case exception was raised + if set_status_on_exception: + span.set_status( + Status( + status_code=StatusCode.ERROR, + description=f"{type(exc).__name__}: {exc}", + ) + ) + + # This causes parent spans to set their status to ERROR and to record + # an exception as an event if a child span raises an exception even if + # such child span was started with both record_exception and + # set_status_on_exception attributes set to False. + raise + + finally: + if end_on_exit: + span.end() + + +__all__ = [ + "DEFAULT_TRACE_OPTIONS", + "DEFAULT_TRACE_STATE", + "INVALID_SPAN", + "INVALID_SPAN_CONTEXT", + "INVALID_SPAN_ID", + "INVALID_TRACE_ID", + "Link", + "NonRecordingSpan", + "Span", + "SpanContext", + "SpanKind", + "Status", + "StatusCode", + "TraceFlags", + "TraceState", + "Tracer", + "TracerProvider", + "format_span_id", + "format_trace_id", + "get_current_span", + "get_tracer", + "get_tracer_provider", + "set_span_in_context", + "set_tracer_provider", + "use_span", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py new file mode 100644 index 00000000000..2f04296b7d4 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py @@ -0,0 +1,37 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from opentelemetry.agent._vendor.opentelemetry.context import create_key, get_value, set_value +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.trace.span import INVALID_SPAN, Span + +SPAN_KEY = "current-span" +_SPAN_KEY = create_key("current-span") + + +def set_span_in_context(span: Span, context: Context | None = None) -> Context: + """Set the span in the given context. + + Args: + span: The Span to set. + context: a Context object. if one is not passed, the + default current context is used instead. + """ + ctx = set_value(_SPAN_KEY, span, context=context) + return ctx + + +def get_current_span(context: Context | None = None) -> Span: + """Retrieve the current span. + + Args: + context: A Context object. If one is not passed, the + default current context is used instead. + + Returns: + The Span set in the context if it exists. INVALID_SPAN otherwise. + """ + span = get_value(_SPAN_KEY, context=context) + if span is None or not isinstance(span, Span): + return INVALID_SPAN + return span diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py new file mode 100644 index 00000000000..2dea2af09cf --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py @@ -0,0 +1,126 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# +import logging +import re + +from opentelemetry.agent._vendor.opentelemetry import trace +from opentelemetry.agent._vendor.opentelemetry.context.context import Context +from opentelemetry.agent._vendor.opentelemetry.propagators import textmap +from opentelemetry.agent._vendor.opentelemetry.trace import format_span_id, format_trace_id +from opentelemetry.agent._vendor.opentelemetry.trace.span import ( + _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH, + TraceState, +) + +_logger = logging.getLogger(__name__) + + +class TraceContextTextMapPropagator(textmap.TextMapPropagator): + """Extracts and injects using w3c TraceContext's headers.""" + + _TRACEPARENT_HEADER_NAME = "traceparent" + _TRACESTATE_HEADER_NAME = "tracestate" + _TRACEPARENT_HEADER_FORMAT = ( + "^[ \t]*([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})" + "(?:(-.*)|[ \t]*)$" + ) + _TRACEPARENT_HEADER_FORMAT_RE = re.compile(_TRACEPARENT_HEADER_FORMAT) + _TRACEPARENT_MAXIMUM_LENGTH = 512 + + # pylint: disable-next=too-many-return-statements + def extract( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, + ) -> Context: + """Extracts SpanContext from the carrier. + + See `opentelemetry.propagators.textmap.TextMapPropagator.extract` + """ + if context is None: + context = Context() + + header = getter.get(carrier, self._TRACEPARENT_HEADER_NAME) + + if not header: + return context + + if len(header[0]) > self._TRACEPARENT_MAXIMUM_LENGTH: + _logger.warning( + "traceparent header exceeded the maximum length of %d characters", + self._TRACEPARENT_MAXIMUM_LENGTH, + ) + return context + + match = re.search(self._TRACEPARENT_HEADER_FORMAT_RE, header[0]) + if not match: + return context + + version: str = match.group(1) + trace_id: str = match.group(2) + span_id: str = match.group(3) + trace_flags: str = match.group(4) + + if trace_id == "0" * 32 or span_id == "0" * 16: + return context + + if version == "00": + if match.group(5): # type: ignore + return context + if version == "ff": + return context + + tracestate_headers = getter.get(carrier, self._TRACESTATE_HEADER_NAME) + if tracestate_headers is None: + tracestate = None + elif ( + # multiple header fields are combined with "," (RFC 9110, section 5.3) + sum(len(header) for header in tracestate_headers) + len(tracestate_headers) - 1 + > _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH + ): + _logger.warning( + "tracestate header exceeded the maximum length of %d characters", + _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH, + ) + tracestate = None + else: + tracestate = TraceState.from_header(tracestate_headers) + + span_context = trace.SpanContext( + trace_id=int(trace_id, 16), + span_id=int(span_id, 16), + is_remote=True, + trace_flags=trace.TraceFlags(int(trace_flags, 16)), + trace_state=tracestate, + ) + return trace.set_span_in_context(trace.NonRecordingSpan(span_context), context) + + def inject( + self, + carrier: textmap.CarrierT, + context: Context | None = None, + setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, + ) -> None: + """Injects SpanContext into the carrier. + + See `opentelemetry.propagators.textmap.TextMapPropagator.inject` + """ + span = trace.get_current_span(context) + span_context = span.get_span_context() + if span_context == trace.INVALID_SPAN_CONTEXT: + return + traceparent_string = f"00-{format_trace_id(span_context.trace_id)}-{format_span_id(span_context.span_id)}-{span_context.trace_flags:02x}" + setter.set(carrier, self._TRACEPARENT_HEADER_NAME, traceparent_string) + if span_context.trace_state: + tracestate_string = span_context.trace_state.to_header() + setter.set(carrier, self._TRACESTATE_HEADER_NAME, tracestate_string) + + @property + def fields(self) -> set[str]: + """Returns a set with the fields set in `inject`. + + See + `opentelemetry.propagators.textmap.TextMapPropagator.fields` + """ + return {self._TRACEPARENT_HEADER_NAME, self._TRACESTATE_HEADER_NAME} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py new file mode 100644 index 00000000000..09c712d58a0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py @@ -0,0 +1,616 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +import abc +import logging +import re +import types as python_types +import typing +import warnings +from collections.abc import Iterator, Mapping, Sequence + +from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode +from opentelemetry.agent._vendor.opentelemetry.util import types + +# The key MUST begin with a lowercase letter or a digit, +# and can only contain lowercase letters (a-z), digits (0-9), +# underscores (_), dashes (-), asterisks (*), and forward slashes (/). +# For multi-tenant vendor scenarios, an at sign (@) can be used to +# prefix the vendor name. Vendors SHOULD set the tenant ID +# at the beginning of the key. + +# key = ( lcalpha ) 0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) +# key = ( lcalpha / DIGIT ) 0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) "@" lcalpha 0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) +# lcalpha = %x61-7A ; a-z + +_KEY_FORMAT = ( + r"[a-z][_0-9a-z\-\*\/]{0,255}|" + r"[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}" +) +_KEY_PATTERN = re.compile(_KEY_FORMAT) + +# The value is an opaque string containing up to 256 printable +# ASCII [RFC0020] characters (i.e., the range 0x20 to 0x7E) +# except comma (,) and (=). +# value = 0*255(chr) nblk-chr +# nblk-chr = %x21-2B / %x2D-3C / %x3E-7E +# chr = %x20 / nblk-chr + +_VALUE_FORMAT = r"[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]" +_VALUE_PATTERN = re.compile(_VALUE_FORMAT) + + +_TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS = 32 +_TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH = 8192 +_member_pattern = re.compile(f"({_KEY_FORMAT})=({_VALUE_FORMAT})") +_logger = logging.getLogger(__name__) + + +def _is_valid_pair(key: str, value: str) -> bool: + return ( + isinstance(key, str) + and _KEY_PATTERN.fullmatch(key) is not None + and isinstance(value, str) + and _VALUE_PATTERN.fullmatch(value) is not None + ) + + +class Span(abc.ABC): + """A span represents a single operation within a trace.""" + + @abc.abstractmethod + def end(self, end_time: int | None = None) -> None: + """Sets the current time as the span's end time. + + The span's end time is the wall time at which the operation finished. + + Only the first call to `end` should modify the span, and + implementations are free to ignore or raise on further calls. + """ + + @abc.abstractmethod + def get_span_context(self) -> SpanContext: + """Gets the span's SpanContext. + + Get an immutable, serializable identifier for this span that can be + used to create new child spans. + + Returns: + A :class:`opentelemetry.trace.SpanContext` with a copy of this span's immutable state. + """ + + @abc.abstractmethod + def set_attributes(self, attributes: Mapping[str, types.AnyValue]) -> None: + """Sets Attributes. + + Sets Attributes with the key and value passed as arguments dict. + + Note: The behavior of `None` value attributes is undefined, and hence + strongly discouraged. It is also preferred to set attributes at span + creation, instead of calling this method later since samplers can only + consider information already present during span creation. + """ + + @abc.abstractmethod + def set_attribute(self, key: str, value: types.AnyValue) -> None: + """Sets an Attribute. + + Sets a single Attribute with the key and value passed as arguments. + + Note: The behavior of `None` value attributes is undefined, and hence + strongly discouraged. It is also preferred to set attributes at span + creation, instead of calling this method later since samplers can only + consider information already present during span creation. + """ + + @abc.abstractmethod + def add_event( + self, + name: str, + attributes: types.Attributes = None, + timestamp: int | None = None, + ) -> None: + """Adds an `Event`. + + Adds a single `Event` with the name and, optionally, a timestamp and + attributes passed as arguments. Implementations should generate a + timestamp if the `timestamp` argument is omitted. + """ + + def add_link( # pylint: disable=no-self-use + self, + context: SpanContext, + attributes: types.Attributes = None, + ) -> None: + """Adds a `Link`. + + Adds a single `Link` with the `SpanContext` of the span to link to and, + optionally, attributes passed as arguments. Implementations may ignore + calls with an invalid span context if both attributes and TraceState + are empty. + + Note: It is preferred to add links at span creation, instead of calling + this method later since samplers can only consider information already + present during span creation. + """ + warnings.warn( + "Span.add_link() not implemented and will be a no-op. " + "Use opentelemetry-sdk >= 1.23 to add links after span creation" + ) + + @abc.abstractmethod + def update_name(self, name: str) -> None: + """Updates the `Span` name. + + This will override the name provided via :func:`opentelemetry.trace.Tracer.start_span`. + + Upon this update, any sampling behavior based on Span name will depend + on the implementation. + """ + + @abc.abstractmethod + def is_recording(self) -> bool: + """Returns whether this span will be recorded. + + Returns true if this Span is active and recording information like + events with the add_event operation and attributes using set_attribute. + """ + + @abc.abstractmethod + def set_status( + self, + status: Status | StatusCode, + description: str | None = None, + ) -> None: + """Sets the Status of the Span. If used, this will override the default + Span status. + """ + + @abc.abstractmethod + def record_exception( + self, + exception: BaseException, + attributes: types.Attributes = None, + timestamp: int | None = None, + escaped: bool = False, + ) -> None: + """Records an exception as a span event.""" + + def __enter__(self) -> Span: + """Invoked when `Span` is used as a context manager. + + Returns the `Span` itself. + """ + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: python_types.TracebackType | None, + ) -> None: + """Ends context manager and calls `end` on the `Span`.""" + + self.end() + + +class TraceFlags(int): + """A bitmask that represents options specific to the trace. + + Supported flags: + - "sampled" (``0x01``): Indicates the trace may have been sampled upstream. + - "random-trace-id" (``0x02``): Indicates the trace ID was generated + randomly, with at least the 7 rightmost bytes (56 bits) selected with + uniform distribution. + + See the `W3C Trace Context - Traceparent`_ spec for details. + + .. _W3C Trace Context - Traceparent: + https://www.w3.org/TR/trace-context-2/#trace-flags + """ + + DEFAULT = 0x00 + SAMPLED = 0x01 + RANDOM_TRACE_ID = 0x02 + + @classmethod + def get_default(cls) -> TraceFlags: + return cls(cls.DEFAULT) + + @property + def sampled(self) -> bool: + return bool(self & TraceFlags.SAMPLED) + + @property + def random_trace_id(self) -> bool: + return bool(self & TraceFlags.RANDOM_TRACE_ID) + + +DEFAULT_TRACE_OPTIONS = TraceFlags.get_default() + + +class TraceState(Mapping[str, str]): + """A list of key-value pairs representing vendor-specific trace info. + + Keys and values are strings of up to 256 printable US-ASCII characters. + Implementations should conform to the `W3C Trace Context - Tracestate`_ + spec, which describes additional restrictions on valid field values. + + .. _W3C Trace Context - Tracestate: + https://www.w3.org/TR/trace-context/#tracestate-field + """ + + def __init__( + self, + entries: Sequence[tuple[str, str]] | None = None, + ) -> None: + self._dict = {} # type: dict[str, str] + if entries is None: + return + if len(entries) > _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS: + _logger.warning( + "There can't be more than %s key/value pairs.", + _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS, + ) + return + + for key, value in entries: + if _is_valid_pair(key, value): + if key in self._dict: + _logger.warning("Duplicate key: %s found.", key) + continue + self._dict[key] = value + else: + _logger.warning("Invalid key/value pair (%s, %s) found.", key, value) + + def __contains__(self, item: object) -> bool: + return item in self._dict + + def __getitem__(self, key: str) -> str: + return self._dict[key] + + def __iter__(self) -> Iterator[str]: + return iter(self._dict) + + def __len__(self) -> int: + return len(self._dict) + + def __repr__(self) -> str: + pairs = [f"{{key={key}, value={value}}}" for key, value in self._dict.items()] + return str(pairs) + + def add(self, key: str, value: str) -> TraceState: + """Adds a key-value pair to tracestate. The provided pair should + adhere to w3c tracestate identifiers format. + + Args: + key: A valid tracestate key to add + value: A valid tracestate value to add + + Returns: + A new TraceState with the modifications applied. + + If the provided key-value pair is invalid or results in tracestate + that violates tracecontext specification, they are discarded and + same tracestate will be returned. + """ + if not _is_valid_pair(key, value): + _logger.warning("Invalid key/value pair (%s, %s) found.", key, value) + return self + # There can be a maximum of 32 pairs + if len(self) >= _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS: + _logger.warning("There can't be more 32 key/value pairs.") + return self + # Duplicate entries are not allowed + if key in self._dict: + _logger.warning("The provided key %s already exists.", key) + return self + new_state = [(key, value)] + list(self._dict.items()) + return TraceState(new_state) + + def update(self, key: str, value: str) -> TraceState: + """Updates a key-value pair in tracestate. The provided pair should + adhere to w3c tracestate identifiers format. + + Note: + This method performs an "upsert": if ``key`` is not already present + it is added (when the tracestate is below the 32-entry limit), + otherwise its value is updated. This upsert behaviour is intentional + but goes beyond what the OpenTelemetry specification defines for + ``update`` (https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#tracestate), + and is kept for backwards compatibility with callers that rely on it. + + Args: + key: A valid tracestate key to update + value: A valid tracestate value to update for key + + Returns: + A new TraceState with the modifications applied. + + If the provided pair is invalid, or adding a new key would exceed + the maximum of 32 key/value pairs, they are discarded and the same + tracestate is returned unchanged. Updating an existing key is always + allowed, even at the maximum. + """ + if not _is_valid_pair(key, value): + _logger.warning("Invalid key/value pair (%s, %s) found.", key, value) + return self + # Adding a new key at the maximum would push the tracestate over the + # limit and cause the constructor to drop every entry. Return unchanged + # instead of silently discarding existing state. + if key not in self._dict and len(self._dict) >= _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS: + _logger.warning("There can't be more 32 key/value pairs.") + return self + prev_state = self._dict.copy() + prev_state.pop(key, None) + new_state = [(key, value), *prev_state.items()] + return TraceState(new_state) + + def delete(self, key: str) -> TraceState: + """Deletes a key-value from tracestate. + + Args: + key: A valid tracestate key to remove key-value pair from tracestate + + Returns: + A new TraceState with the modifications applied. + + If the provided key-value pair is invalid or results in tracestate + that violates tracecontext specification, they are discarded and + same tracestate will be returned. + """ + if key not in self._dict: + _logger.warning("The provided key %s doesn't exist.", key) + return self + prev_state = self._dict.copy() + prev_state.pop(key) + new_state = list(prev_state.items()) + return TraceState(new_state) + + def to_header(self) -> str: + """Creates a w3c tracestate header from a TraceState. + + Returns: + A string that adheres to the w3c tracestate + header format. + """ + return ",".join(key + "=" + value for key, value in self._dict.items()) + + @classmethod + def from_header(cls, header_list: list[str]) -> TraceState: + """Parses one or more w3c tracestate header into a TraceState. + + Args: + header_list: one or more w3c tracestate headers. + + Returns: + A valid TraceState that contains values extracted from + the tracestate header. + + If the format of one headers is illegal, all values will + be discarded and an empty tracestate will be returned. + + If the number of keys is beyond the maximum, all values + will be discarded and an empty tracestate will be returned. + """ + pairs = {} # type: dict[str, str] + for header in header_list: + for member in header.split(","): + # remove optional whitespace (RFC 9110, section 5.6.3) + member = member.strip(" \t") + # empty members are valid, but no need to process further. + if not member: + continue + match = _member_pattern.fullmatch(member) + if not match: + _logger.warning( + "Member doesn't match the w3c identifiers format %s", + member, + ) + return cls() + key, value = match.groups() + # duplicate keys are not legal in header + if key in pairs: + return cls() + pairs[key] = value + return cls(list(pairs.items())) + + @classmethod + def get_default(cls) -> TraceState: + return cls() + + def keys(self) -> typing.KeysView[str]: + return self._dict.keys() + + def items(self) -> typing.ItemsView[str, str]: + return self._dict.items() + + def values(self) -> typing.ValuesView[str]: + return self._dict.values() + + +DEFAULT_TRACE_STATE = TraceState.get_default() +_TRACE_ID_MAX_VALUE = 2**128 - 1 +_SPAN_ID_MAX_VALUE = 2**64 - 1 + + +class SpanContext(tuple[int, int, bool, "TraceFlags", "TraceState", bool]): + """The state of a Span to propagate between processes. + + This class includes the immutable attributes of a :class:`.Span` that must + be propagated to a span's children and across process boundaries. + + Args: + trace_id: The ID of the trace that this span belongs to. + span_id: This span's ID. + is_remote: True if propagated from a remote parent. + trace_flags: Trace options to propagate. + trace_state: Tracing-system-specific info to propagate. + """ + + def __new__( + cls, + trace_id: int, + span_id: int, + is_remote: bool, + trace_flags: TraceFlags | None = DEFAULT_TRACE_OPTIONS, + trace_state: TraceState | None = DEFAULT_TRACE_STATE, + ) -> SpanContext: + if trace_flags is None: + trace_flags = DEFAULT_TRACE_OPTIONS + if trace_state is None: + trace_state = DEFAULT_TRACE_STATE + + is_valid = ( + INVALID_TRACE_ID < trace_id <= _TRACE_ID_MAX_VALUE and INVALID_SPAN_ID < span_id <= _SPAN_ID_MAX_VALUE + ) + + return tuple.__new__( + cls, + (trace_id, span_id, is_remote, trace_flags, trace_state, is_valid), + ) + + def __getnewargs__( + self, + ) -> tuple[int, int, bool, TraceFlags, TraceState]: + return ( + self.trace_id, + self.span_id, + self.is_remote, + self.trace_flags, + self.trace_state, + ) + + @property + def trace_id(self) -> int: + return self[0] # pylint: disable=unsubscriptable-object + + @property + def span_id(self) -> int: + return self[1] # pylint: disable=unsubscriptable-object + + @property + def is_remote(self) -> bool: + return self[2] # pylint: disable=unsubscriptable-object + + @property + def trace_flags(self) -> TraceFlags: + return self[3] # pylint: disable=unsubscriptable-object + + @property + def trace_state(self) -> TraceState: + return self[4] # pylint: disable=unsubscriptable-object + + @property + def is_valid(self) -> bool: + return self[5] # pylint: disable=unsubscriptable-object + + def __setattr__(self, *args: str) -> None: + _logger.debug("Immutable type, ignoring call to set attribute", stack_info=True) + + def __delattr__(self, *args: str) -> None: + _logger.debug( + "Immutable type, ignoring call to delete attribute", + stack_info=True, + ) + + def __repr__(self) -> str: + return f"{type(self).__name__}(trace_id=0x{format_trace_id(self.trace_id)}, span_id=0x{format_span_id(self.span_id)}, trace_flags=0x{self.trace_flags:02x}, trace_state={self.trace_state!r}, is_remote={self.is_remote})" + + +class NonRecordingSpan(Span): + """The Span that is used when no Span implementation is available. + + All operations are no-op except context propagation. + """ + + def __init__(self, context: SpanContext) -> None: + self._context = context + + def get_span_context(self) -> SpanContext: + return self._context + + def is_recording(self) -> bool: + return False + + def end(self, end_time: int | None = None) -> None: + pass + + def set_attributes(self, attributes: Mapping[str, types.AnyValue]) -> None: + pass + + def set_attribute(self, key: str, value: types.AnyValue) -> None: + pass + + def add_event( + self, + name: str, + attributes: types.Attributes = None, + timestamp: int | None = None, + ) -> None: + pass + + def add_link( + self, + context: SpanContext, + attributes: types.Attributes = None, + ) -> None: + pass + + def update_name(self, name: str) -> None: + pass + + def set_status( + self, + status: Status | StatusCode, + description: str | None = None, + ) -> None: + pass + + def record_exception( + self, + exception: BaseException, + attributes: types.Attributes = None, + timestamp: int | None = None, + escaped: bool = False, + ) -> None: + pass + + def __repr__(self) -> str: + return f"NonRecordingSpan({self._context!r})" + + +INVALID_SPAN_ID = 0x0000000000000000 +INVALID_TRACE_ID = 0x00000000000000000000000000000000 +INVALID_SPAN_CONTEXT = SpanContext( + trace_id=INVALID_TRACE_ID, + span_id=INVALID_SPAN_ID, + is_remote=False, + trace_flags=DEFAULT_TRACE_OPTIONS, + trace_state=DEFAULT_TRACE_STATE, +) +INVALID_SPAN = NonRecordingSpan(INVALID_SPAN_CONTEXT) + + +def format_trace_id(trace_id: int) -> str: + """Convenience trace ID formatting method + Args: + trace_id: Trace ID int + + Returns: + The trace ID (16 bytes) cast to a 32-character hexadecimal string + """ + return format(trace_id, "032x") + + +def format_span_id(span_id: int) -> str: + """Convenience span ID formatting method + Args: + span_id: Span ID int + + Returns: + The span ID (8 bytes) cast to a 16-character hexadecimal string + """ + return format(span_id, "016x") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py new file mode 100644 index 00000000000..88c07a69107 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py @@ -0,0 +1,68 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import enum +import logging + +logger = logging.getLogger(__name__) + + +class StatusCode(enum.Enum): + """Represents the canonical set of status codes of a finished Span.""" + + UNSET = 0 + """The default status.""" + + OK = 1 + """The operation has been validated by an Application developer or Operator to have completed successfully.""" + + ERROR = 2 + """The operation contains an error.""" + + +class Status: + """Represents the status of a finished Span. + + Args: + status_code: The canonical status code that describes the result + status of the operation. + description: An optional description of the status. + """ + + def __init__( + self, + status_code: StatusCode = StatusCode.UNSET, + description: str | None = None, + ): + self._status_code = status_code + self._description = None + + if description: + if not isinstance(description, str): + logger.warning("Invalid status description type, expected str") + return + if status_code is not StatusCode.ERROR: + logger.warning("description should only be set when status_code is set to StatusCode.ERROR") + return + + self._description = description + + @property + def status_code(self) -> StatusCode: + """Represents the canonical status code of a finished Span.""" + return self._status_code + + @property + def description(self) -> str | None: + """Status description""" + return self._description + + @property + def is_ok(self) -> bool: + """Returns false if this represents an error, true otherwise.""" + return self.is_unset or self._status_code is StatusCode.OK + + @property + def is_unset(self) -> bool: + """Returns true if unset, false otherwise.""" + return self._status_code is StatusCode.UNSET diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py new file mode 100644 index 00000000000..98bb55ee011 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py @@ -0,0 +1,75 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +import contextlib +import functools +import inspect +from collections.abc import Callable, Iterator +from typing import TYPE_CHECKING, Generic, TypeVar + +V = TypeVar("V") +R = TypeVar("R") # Return type +Pargs = TypeVar("Pargs") # Generic type for arguments +Pkwargs = TypeVar("Pkwargs") # Generic type for arguments + +# We don't actually depend on typing_extensions but we can use it in CI with this conditional +# import. ParamSpec can be imported directly from typing after python 3.9 is dropped +# https://peps.python.org/pep-0612/. +if TYPE_CHECKING: + from opentelemetry.agent._vendor.typing_extensions import ParamSpec + + P = ParamSpec("P") # Generic type for all arguments + + +class _AgnosticContextManager( + contextlib._GeneratorContextManager[R], + Generic[R], +): # pylint: disable=protected-access + """Context manager that can decorate both async and sync functions. + + This is an overridden version of the contextlib._GeneratorContextManager + class that will decorate async functions with an async context manager + to end the span AFTER the entire async function coroutine finishes. + + Else it will report near zero spans durations for async functions. + + We are overriding the contextlib._GeneratorContextManager class as + reimplementing it is a lot of code to maintain and this class (even if it's + marked as protected) doesn't seems like to be evolving a lot. + + For more information, see: + https://github.com/open-telemetry/opentelemetry-python/pull/3633 + """ + + def __enter__(self) -> R: + """Reimplementing __enter__ to avoid the type error. + + The original __enter__ method returns Any type, but we want to return R. + """ + del self.args, self.kwds, self.func # type: ignore + try: + return next(self.gen) # type: ignore + except StopIteration: + raise RuntimeError("generator didn't yield") from None + + def __call__(self, func: V) -> V: # pyright: ignore [reportIncompatibleMethodOverride] + if inspect.iscoroutinefunction(func): + + @functools.wraps(func) # type: ignore + async def async_wrapper(*args: Pargs, **kwargs: Pkwargs) -> R: # pyright: ignore [reportInvalidTypeVarUse] + with self._recreate_cm(): # type: ignore + return await func(*args, **kwargs) # type: ignore + + return async_wrapper # type: ignore + return super().__call__(func) # type: ignore + + +def _agnosticcontextmanager( + func: "Callable[P, Iterator[R]]", +) -> "Callable[P, _AgnosticContextManager[R]]": + @functools.wraps(func) + def helper(*args: Pargs, **kwargs: Pkwargs) -> _AgnosticContextManager[R]: # pyright: ignore [reportInvalidTypeVarUse] + return _AgnosticContextManager(func, args, kwargs) # pyright: ignore [reportArgumentType] + + # Ignoring the type to keep the original signature of the function + return helper # type: ignore[return-value] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py new file mode 100644 index 00000000000..c7c5399c816 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py @@ -0,0 +1,58 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +Caching and compatibility wrapper for standard library ``importlib.metadata``. + +This module caches ``entry_points()`` to avoid reloading entry points from disk on every call. +It also normalizes minor differences across python versions 3.10+. References to issues: + +- https://github.com/open-telemetry/opentelemetry-python/pull/4735 +- https://github.com/open-telemetry/opentelemetry-python/pull/5203 +""" + +import os +from functools import cache +from importlib.metadata import ( + Distribution, + EntryPoint, + EntryPoints, + PackageNotFoundError, + requires, + version, +) +from importlib.metadata import distributions as _all_distributions +from typing import Any, Iterable + +# opentelemetry-agent: entry points are only looked up in the vendored distributions' metadata +# (written to _vendor/_metadata by opentelemetry-vendor sync), never in the application's, whose +# OpenTelemetry plugins point at un-vendored modules. version() and requires() still see the +# application's distributions: instrumentors check the installed versions of the libraries they patch. +_VENDORED_METADATA_PATH = [ + os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "_metadata") +] + + +def distributions(**kwargs: Any) -> Iterable[Distribution]: + return _all_distributions(path=_VENDORED_METADATA_PATH, **kwargs) + + +@cache +def _original_entry_points_cached() -> EntryPoints: + return EntryPoints(entry_point for dist in distributions() for entry_point in dist.entry_points) + + +def entry_points(**params) -> EntryPoints: + return _original_entry_points_cached().select(**params) + + +__all__ = [ + "Distribution", + "EntryPoint", + "EntryPoints", + "PackageNotFoundError", + "distributions", + "entry_points", + "requires", + "version", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py new file mode 100644 index 00000000000..59f562385e6 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py @@ -0,0 +1,36 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from collections.abc import Callable +from threading import Lock + + +class Once: + """Execute a function exactly once and block all callers until the function returns + + Same as golang's `sync.Once `_ + """ + + def __init__(self) -> None: + self._lock = Lock() + self._done = False + + def do_once(self, func: Callable[[], None]) -> bool: + """Execute ``func`` if it hasn't been executed or return. + + Will block until ``func`` has been called by one thread. + + Returns: + Whether or not ``func`` was executed in this call + """ + + # fast path, try to avoid locking + if self._done: + return False + + with self._lock: + if not self._done: + func() + self._done = True + return True + return False diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py new file mode 100644 index 00000000000..6475da98ce8 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py @@ -0,0 +1,42 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from logging import getLogger +from os import environ +from typing import TYPE_CHECKING, TypeVar, cast + +if TYPE_CHECKING: + from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider + from opentelemetry.agent._vendor.opentelemetry.trace import TracerProvider + +Provider = TypeVar("Provider", "TracerProvider", "MeterProvider") + +logger = getLogger(__name__) + + +def _load_provider(provider_environment_variable: str, provider: str) -> Provider: # type: ignore[type-var] + # pylint: disable=import-outside-toplevel,no-name-in-module + from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 + entry_points, + ) + + try: + provider_name = cast( + str, + environ.get(provider_environment_variable, f"default_{provider}"), + ) + + return cast( + Provider, + next( # type: ignore + iter( # type: ignore + entry_points( # type: ignore + group=f"opentelemetry_{provider}", + name=provider_name, + ) + ) + ).load()(), + ) + except Exception: # pylint: disable=broad-exception-caught + logger.exception("Failed to load configured provider %s", provider) + raise diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py new file mode 100644 index 00000000000..c438e965bdb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py @@ -0,0 +1,351 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from __future__ import annotations + +from collections.abc import Callable, Iterable, Mapping +from os import environ +from re import IGNORECASE as RE_IGNORECASE +from re import compile as re_compile +from re import search +from typing import overload +from urllib.parse import parse_qs, urlencode, urlparse, urlunparse + +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.http_attributes import ( + HTTP_FLAVOR, + HTTP_HOST, + HTTP_METHOD, + HTTP_SCHEME, + HTTP_SERVER_NAME, + HTTP_STATUS_CODE, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_HOST_NAME, + NET_HOST_PORT, +) +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.user_agent_attributes import ( + UserAgentSyntheticTypeValues, +) +from opentelemetry.agent._vendor.opentelemetry.util.http.constants import BOT_PATTERNS, TEST_PATTERNS + +OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS" +OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST" +OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE" +OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST" +OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE" + +OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS = "OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS" + +# List of recommended metrics attributes +_duration_attrs = { + HTTP_METHOD, + HTTP_HOST, + HTTP_SCHEME, + HTTP_STATUS_CODE, + HTTP_FLAVOR, + HTTP_SERVER_NAME, + NET_HOST_NAME, + NET_HOST_PORT, +} + +_active_requests_count_attrs = { + HTTP_METHOD, + HTTP_HOST, + HTTP_SCHEME, + HTTP_FLAVOR, + HTTP_SERVER_NAME, +} + +PARAMS_TO_REDACT = ["AWSAccessKeyId", "Signature", "sig", "X-Goog-Signature"] + + +class ExcludeList: + """Class to exclude certain paths (given as a list of regexes) from tracing requests""" + + def __init__(self, excluded_urls: Iterable[str]): + self._excluded_urls = excluded_urls + if self._excluded_urls: + self._regex = re_compile("|".join(excluded_urls)) + + def url_disabled(self, url: str) -> bool: + return bool(self._excluded_urls and search(self._regex, url)) + + +class SanitizeValue: + """Class to sanitize (remove sensitive data from) certain headers (given as a list of regexes)""" + + def __init__(self, sanitized_fields: Iterable[str]): + self._sanitized_fields = sanitized_fields + if self._sanitized_fields: + self._regex = re_compile("|".join(sanitized_fields), RE_IGNORECASE) + + def sanitize_header_value(self, header: str, value: str) -> str: + return "[REDACTED]" if (self._sanitized_fields and search(self._regex, header)) else value + + def sanitize_header_values( + self, + headers: Mapping[str, str | list[str]], + header_regexes: list[str], + normalize_function: Callable[[str], str], + ) -> dict[str, list[str]]: + values: dict[str, list[str]] = {} + + if header_regexes: + header_regexes_compiled = re_compile( + "|".join(header_regexes), + RE_IGNORECASE, + ) + + for header_name, header_value in headers.items(): + if header_regexes_compiled.fullmatch(header_name): + key = normalize_function(header_name.lower()) + if isinstance(header_value, str): + values[key] = [self.sanitize_header_value(header_name, header_value)] + else: + values[key] = [self.sanitize_header_value(header_name, value) for value in header_value] + + return values + + +_root = r"OTEL_PYTHON_{}" + + +def get_traced_request_attrs(instrumentation: str) -> list[str]: + traced_request_attrs = environ.get(_root.format(f"{instrumentation}_TRACED_REQUEST_ATTRS")) + if traced_request_attrs: + return [traced_request_attr.strip() for traced_request_attr in traced_request_attrs.split(",")] + return [] + + +def get_excluded_urls(instrumentation: str) -> ExcludeList: + # Get instrumentation-specific excluded URLs. If not set, retrieve them + # from generic variable. + excluded_urls = environ.get( + _root.format(f"{instrumentation}_EXCLUDED_URLS"), + environ.get(_root.format("EXCLUDED_URLS"), ""), + ) + + return parse_excluded_urls(excluded_urls) + + +def parse_excluded_urls(excluded_urls: str) -> ExcludeList: + """ + Small helper to put an arbitrary url list inside an ExcludeList + """ + if excluded_urls: + excluded_url_list = [excluded_url.strip() for excluded_url in excluded_urls.split(",")] + else: + excluded_url_list = [] + + return ExcludeList(excluded_url_list) + + +def remove_url_credentials(url: str) -> str: + """Given a string url, replace the username and password with the keyword `REDACTED` only if it is a valid url""" + try: + parsed = urlparse(url) + if all([parsed.scheme, parsed.netloc]): # checks for valid url + if "@" in parsed.netloc: + _, _, host = parsed.netloc.rpartition("@") + new_netloc = "REDACTED:REDACTED@" + host + return urlunparse( + ( + parsed.scheme, + new_netloc, + parsed.path, + parsed.params, + parsed.query, + parsed.fragment, + ) + ) + except ValueError: # an unparsable url was passed + pass + return url + + +def normalise_request_header_name(header: str) -> str: + key = header.lower().replace("-", "_") + return f"http.request.header.{key}" + + +def normalise_response_header_name(header: str) -> str: + key = header.lower().replace("-", "_") + return f"http.response.header.{key}" + + +@overload +def sanitize_method(method: str) -> str: ... + + +@overload +def sanitize_method(method: None) -> None: ... + + +def sanitize_method(method: str | None) -> str | None: + if method is None: + return None + method = method.upper() + if ( + environ.get(OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS) + or + # Based on https://www.rfc-editor.org/rfc/rfc9110.html#name-methods, https://www.rfc-editor.org/rfc/rfc5789#section-2 + # and https://datatracker.ietf.org/doc/rfc10008/. + method + in [ + "GET", + "HEAD", + "POST", + "PUT", + "DELETE", + "CONNECT", + "OPTIONS", + "TRACE", + "PATCH", + "QUERY", + ] + ): + return method + return "_OTHER" + + +def get_custom_headers(env_var: str) -> list[str]: + custom_headers = environ.get(env_var, None) + if custom_headers: + return [custom_headers.strip() for custom_headers in custom_headers.split(",")] + return [] + + +def get_custom_header_attributes( + headers: Mapping[str, str | list[str]] | None, + captured_headers: list[str] | None, + sensitive_headers: list[str] | None, + normalize_function: Callable[[str], str], +) -> dict[str, list[str]]: + """Extract and sanitize HTTP headers for span attributes. + + Args: + headers: The HTTP headers to process, either from a request or response. + Can be None if no headers are available. + captured_headers: List of header regexes to capture as span attributes. + If None or empty, no headers will be captured. + sensitive_headers: List of header regexes whose values should be sanitized + (redacted). If None, no sanitization is applied. + normalize_function: Function to normalize header names. + + Returns: + Dictionary of normalized header attribute names to their values + as lists of strings. + """ + if not headers or not captured_headers: + return {} + sanitize: SanitizeValue = SanitizeValue(sensitive_headers or ()) + return sanitize.sanitize_header_values(headers, captured_headers, normalize_function) + + +def _parse_active_request_count_attrs(req_attrs): + active_requests_count_attrs = { + key: req_attrs[key] for key in _active_requests_count_attrs.intersection(req_attrs.keys()) + } + return active_requests_count_attrs + + +def _parse_duration_attrs(req_attrs): + duration_attrs = {key: req_attrs[key] for key in _duration_attrs.intersection(req_attrs.keys())} + return duration_attrs + + +def _parse_url_query(url: str) -> tuple[str, str]: + """Split a url into its path and query components. + + Callers may pass request targets that come straight off the request line, + so the url need not be parsable. An unparsable one yields empty components + rather than raising, since instrumentation must never break the request it + is measuring. + + Returns: + The path and the query string, either of which may be empty. + """ + try: + parsed_url = urlparse(url) + except ValueError: # an unparsable url was passed + return "", "" + path = parsed_url.path + query_params = parsed_url.query + return path, query_params + + +def redact_query_parameters(url: str) -> str: + """Given a string url, redact sensitive query parameter values""" + try: + parsed = urlparse(url) + if not parsed.query: # No query parameters to redact + return url + query_params = parse_qs(parsed.query) + if not any(param in query_params for param in PARAMS_TO_REDACT): + return url + for param in PARAMS_TO_REDACT: + if param in query_params: + query_params[param] = ["REDACTED"] + return urlunparse( + ( + parsed.scheme, + parsed.netloc, + parsed.path, + parsed.params, + urlencode(query_params, doseq=True), + parsed.fragment, + ) + ) + except ValueError: # an unparsable url was passed + return url + + +def redact_url(url: str) -> str: + """Redact sensitive data from the URL, including credentials and query parameters.""" + url = remove_url_credentials(url) + url = redact_query_parameters(url) + return url + + +def normalize_user_agent( + user_agent: str | bytes | bytearray | memoryview | None, +) -> str | None: + """Convert user-agent header values into a usable string.""" + # Different servers/frameworks surface headers as str, bytes, bytearray or memoryview; + # keep decoding logic centralized so instrumentation modules just call this helper. + if user_agent is None: + return None + if isinstance(user_agent, str): + return user_agent + if isinstance(user_agent, (bytes, bytearray)): + return user_agent.decode("latin-1") + if isinstance(user_agent, memoryview): + return user_agent.tobytes().decode("latin-1") + return str(user_agent) + + +def detect_synthetic_user_agent(user_agent: str | None) -> str | None: + """ + Detect synthetic user agent type based on user agent string contents. + + Args: + user_agent: The user agent string to analyze + + Returns: + UserAgentSyntheticTypeValues.TEST if user agent contains any pattern from TEST_PATTERNS + UserAgentSyntheticTypeValues.BOT if user agent contains any pattern from BOT_PATTERNS + None otherwise + + Note: Test patterns take priority over bot patterns. + """ + if not user_agent: + return None + + user_agent_lower = user_agent.lower() + + if any(test_pattern in user_agent_lower for test_pattern in TEST_PATTERNS): + return UserAgentSyntheticTypeValues.TEST.value + if any(bot_pattern in user_agent_lower for bot_pattern in BOT_PATTERNS): + return UserAgentSyntheticTypeValues.BOT.value + + return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py new file mode 100644 index 00000000000..7ee751826ef --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py @@ -0,0 +1,23 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +Constants for OpenTelemetry HTTP utilities. + +This module contains configuration constants and pattern definitions used +by HTTP instrumentation utilities for various features like synthetic user +agent detection. +""" + +# Test patterns to detect in user agent strings (case-insensitive) +# These patterns indicate synthetic test traffic +TEST_PATTERNS = [ + "alwayson", +] + +# Bot patterns to detect in user agent strings (case-insensitive) +# These patterns indicate automated bot traffic +BOT_PATTERNS = [ + "googlebot", + "bingbot", +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py new file mode 100644 index 00000000000..d0360175ea0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py @@ -0,0 +1,186 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +This library provides functionality to enrich HTTP client spans with IPs. It does +not create spans on its own. +""" + +from __future__ import annotations + +import contextlib +import http.client +import logging +import socket # pylint:disable=unused-import # Used for typing +import typing +from collections.abc import Callable, Collection +from typing import Any, TypedDict, cast + +from opentelemetry.agent._vendor import wrapt + +from opentelemetry.agent._vendor.opentelemetry import context +from opentelemetry.agent._vendor.opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import unwrap +from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.net_attributes import ( + NET_PEER_IP, +) +from opentelemetry.agent._vendor.opentelemetry.trace.span import Span + +_STATE_KEY = "httpbase_instrumentation_state" + +logger = logging.getLogger(__name__) + +R = typing.TypeVar("R") + + +class HttpClientInstrumentor(BaseInstrumentor): + def instrumentation_dependencies(self) -> Collection[str]: + return () # This instruments http.client from stdlib; no extra deps. + + def _instrument(self, **kwargs: Any): + """Instruments the http.client module (not creating spans on its own)""" + _instrument() + + def _uninstrument(self, **kwargs: Any): + _uninstrument() + + +def _remove_nonrecording(spanlist: list[Span]) -> bool: + idx = len(spanlist) - 1 + while idx >= 0: + if not spanlist[idx].is_recording(): + logger.debug("Span is not recording: %s", spanlist[idx]) + islast = idx + 1 == len(spanlist) + if not islast: + spanlist[idx] = spanlist[len(spanlist) - 1] + spanlist.pop() + if islast: + if idx == 0: + return False # We removed everything + idx -= 1 + else: + idx -= 1 + return True + + +def trysetip(conn: http.client.HTTPConnection, loglevel: int = logging.DEBUG) -> bool: + """Tries to set the net.peer.ip semantic attribute on the current span from the given + HttpConnection. + + Returns False if the connection is not yet established, False if the IP was captured + or there is no need to capture it. + """ + + state = _getstate() + if not state: + return True + spanlist: list[Span] = state.get("need_ip") + if not spanlist: + return True + + # Remove all non-recording spans from the list. + if not _remove_nonrecording(spanlist): + return True + + sock = "" + ip = None + try: + sock: socket.socket | None = conn.sock + logger.debug("Got socket: %s", sock) + if sock is None: + return False + addr = sock.getpeername() + if addr and addr[0]: + ip = addr[0] + except Exception: # pylint:disable=broad-except + logger.log( + loglevel, + "Failed to get peer address from %s", + sock, + exc_info=True, + stack_info=True, + ) + else: + if ip is not None: + for span in spanlist: + span.set_attribute(NET_PEER_IP, ip) + return True + + +def _instrumented_connect( + wrapped: Callable[..., R], + instance: http.client.HTTPConnection, + args: tuple[Any, ...], + kwargs: dict[str, Any], +) -> R: + result = wrapped(*args, **kwargs) + trysetip(instance, loglevel=logging.WARNING) + return result + + +def instrument_connect(module: type[Any], name: str = "connect"): + """Instrument additional connect() methods, e.g. for derived classes.""" + + wrapt.wrap_function_wrapper( + module, + name, + _instrumented_connect, + ) + + +def _instrument(): + def instrumented_send( + wrapped: Callable[..., R], + instance: http.client.HTTPConnection, + args: tuple[Any, ...], + kwargs: dict[str, Any], + ) -> R: + done = trysetip(instance) + result = wrapped(*args, **kwargs) + if not done: + trysetip(instance, loglevel=logging.WARNING) + return result + + wrapt.wrap_function_wrapper( + http.client.HTTPConnection, + "send", + instrumented_send, + ) + + instrument_connect(http.client.HTTPConnection) + # No need to instrument HTTPSConnection, as it calls super().connect() + + +class _ConnectionState(TypedDict): + need_ip: list[Span] + + +def _getstate() -> _ConnectionState | None: + return cast(_ConnectionState, context.get_value(_STATE_KEY)) + + +@contextlib.contextmanager +def set_ip_on_next_http_connection(span: Span): + state = _getstate() + if not state: + token = context.attach(context.set_value(_STATE_KEY, {"need_ip": [span]})) + try: + yield + finally: + if token: + context.detach(token) + else: + spans = state["need_ip"] + spans.append(span) + try: + yield + finally: + try: + spans.remove(span) + except ValueError: # Span might have become non-recording + pass + + +def _uninstrument(): + unwrap(http.client.HTTPConnection, "send") + unwrap(http.client.HTTPConnection, "connect") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py new file mode 100644 index 00000000000..31dc36b24e9 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py new file mode 100644 index 00000000000..e6aec9697fa --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py @@ -0,0 +1,93 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from collections.abc import Mapping +from logging import getLogger +from re import compile, split +from urllib.parse import unquote + +from opentelemetry.agent._vendor.typing_extensions import deprecated + +_logger = getLogger(__name__) + +# The following regexes reference this spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables + +# Optional whitespace +_OWS = r"[ \t]*" +# A key contains printable US-ASCII characters except: SP and "(),/:;<=>?@[\]{} +_KEY_FORMAT = r"[\x21\x23-\x27\x2a\x2b\x2d\x2e\x30-\x39\x41-\x5a\x5e-\x7a\x7c\x7e]+" +# A value contains a URL-encoded UTF-8 string. The encoded form can contain any +# printable US-ASCII characters (0x20-0x7f) other than SP, DEL, and ",;/ +_VALUE_FORMAT = r"[\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*" +# Like above with SP included +_LIBERAL_VALUE_FORMAT = r"[\x20\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*" +# A key-value is key=value, with optional whitespace surrounding key and value +_KEY_VALUE_FORMAT = rf"{_OWS}{_KEY_FORMAT}{_OWS}={_OWS}{_VALUE_FORMAT}{_OWS}" + +_HEADER_PATTERN = compile(_KEY_VALUE_FORMAT) +_LIBERAL_HEADER_PATTERN = compile(rf"{_OWS}{_KEY_FORMAT}{_OWS}={_OWS}{_LIBERAL_VALUE_FORMAT}{_OWS}") +_DELIMITER_PATTERN = compile(r"[ \t]*,[ \t]*") + +_BAGGAGE_PROPERTY_FORMAT = rf"{_KEY_VALUE_FORMAT}|{_OWS}{_KEY_FORMAT}{_OWS}" + +_INVALID_HEADER_ERROR_MESSAGE_STRICT_TEMPLATE = ( + "Header format invalid! Header values in environment variables must be " + "URL encoded per the OpenTelemetry Protocol Exporter specification: %s" +) + +_INVALID_HEADER_ERROR_MESSAGE_LIBERAL_TEMPLATE = ( + "Header format invalid! Header values in environment variables must be " + "URL encoded per the OpenTelemetry Protocol Exporter specification or " + "a comma separated list of name=value occurrences: %s" +) + +# pylint: disable=invalid-name + + +@deprecated("You should use parse_env_headers. Deprecated since version 1.15.0.") +def parse_headers(s: str) -> Mapping[str, str]: + return parse_env_headers(s) + + +def parse_env_headers(s: str, liberal: bool = False) -> Mapping[str, str]: + """ + Parse ``s``, which is a ``str`` instance containing HTTP headers encoded + for use in ENV variables per the W3C Baggage HTTP header format at + https://www.w3.org/TR/baggage/#baggage-http-header-format, except that + additional semi-colon delimited metadata is not supported. + If ``liberal`` is True we try to parse ``s`` anyway to be more compatible + with other languages SDKs that accept non URL-encoded headers by default. + """ + headers: dict[str, str] = {} + headers_list: list[str] = split(_DELIMITER_PATTERN, s) + for header in headers_list: + if not header: # empty string + continue + header_match = _HEADER_PATTERN.fullmatch(header.strip()) + if not header_match and not liberal: + _logger.warning(_INVALID_HEADER_ERROR_MESSAGE_STRICT_TEMPLATE, header) + continue + + if header_match: + match_string: str = header_match.string + # value may contain any number of `=` + name, value = match_string.split("=", 1) + name = unquote(name).strip().lower() + value = unquote(value).strip() + headers[name] = value + else: + # this is not url-encoded and does not match the spec but we decided to be + # liberal in what we accept to match other languages SDKs behaviour + liberal_header_match = _LIBERAL_HEADER_PATTERN.fullmatch(header.strip()) + if not liberal_header_match: + _logger.warning(_INVALID_HEADER_ERROR_MESSAGE_LIBERAL_TEMPLATE, header) + continue + + liberal_match_string: str = liberal_header_match.string + # value may contain any number of `=` + name, value = liberal_match_string.split("=", 1) + name = name.strip().lower() + value = value.strip() + headers[name] = value + + return headers diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py new file mode 100644 index 00000000000..f37d7c99cc1 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py @@ -0,0 +1,28 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +from collections.abc import Mapping, Sequence +from typing import TypeAlias + +# This is the implementation of the "Any" type as specified by the specifications of OpenTelemetry data model for logs. +# For more details, refer to the OTel specification: +# https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#type-any +AnyValue: TypeAlias = str | bool | int | float | bytes | Sequence["AnyValue"] | Mapping[str, "AnyValue"] | None +AttributeValue: TypeAlias = AnyValue +Attributes = Mapping[str, AnyValue] | None + +# Deprecated type, do not use. +AttributesAsKey = tuple[ + tuple[ + str, + str + | bool + | int + | float + | tuple[str | None, ...] + | tuple[bool | None, ...] + | tuple[int | None, ...] + | tuple[float | None, ...], + ], + ..., +] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py new file mode 100644 index 00000000000..0101c361616 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE new file mode 100644 index 00000000000..6f62d44e4ef --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE @@ -0,0 +1,3 @@ +This software is made available under the terms of *either* of the licenses +found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made +under the terms of *both* these licenses. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE new file mode 100644 index 00000000000..f433b1a53f5 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD new file mode 100644 index 00000000000..42ce7b75c92 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD @@ -0,0 +1,23 @@ +Copyright (c) Donald Stufft and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py new file mode 100644 index 00000000000..5a969154fef --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py @@ -0,0 +1,15 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "26.3" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD-2-Clause or Apache-2.0" +__copyright__ = f"2014 {__author__}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py new file mode 100644 index 00000000000..1ce081d0d2b --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py @@ -0,0 +1,108 @@ +""" +ELF file parser. + +This provides a class ``ELFFile`` that parses an ELF executable in a similar +interface to ``ZipFile``. Only the read interface is implemented. + +ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html +""" + +from __future__ import annotations + +import enum +import os +import struct +from typing import IO + + +class ELFInvalid(ValueError): + pass + + +class EIClass(enum.IntEnum): + C32 = 1 + C64 = 2 + + +class EIData(enum.IntEnum): + Lsb = 1 + Msb = 2 + + +class EMachine(enum.IntEnum): + I386 = 3 + S390 = 22 + Arm = 40 + X8664 = 62 + AArch64 = 183 + + +class ELFFile: + """ + Representation of an ELF executable. + """ + + def __init__(self, f: IO[bytes]) -> None: + self._f = f + + try: + ident = self._read("16B") + except struct.error as e: + raise ELFInvalid("unable to parse identification") from e + magic = bytes(ident[:4]) + if magic != b"\x7fELF": + raise ELFInvalid(f"invalid magic: {magic!r}") + + self.capacity = ident[4] # Format for program header (bitness). + self.encoding = ident[5] # Data structure encoding (endianness). + + try: + # e_fmt: Format for the ELF header. + # p_fmt: Format for a program header. + # p_idx: Indexes to find p_type, p_offset, and p_filesz. + e_fmt, self._p_fmt, self._p_idx = { + (1, 1): ("HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB. + (2, 1): ("HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB. + }[(self.capacity, self.encoding)] + except KeyError as e: + raise ELFInvalid( + f"unrecognized capacity ({self.capacity}) or encoding ({self.encoding})" + ) from e + + try: + ( + _, + self.machine, # Architecture type. + _, + _, + self._e_phoff, # Offset of program header. + _, + self.flags, # Processor-specific flags. + _, + self._e_phentsize, # Size of a program header entry. + self._e_phnum, # Number of program headers. + ) = self._read(e_fmt) + except struct.error as e: + raise ELFInvalid("unable to parse machine and section information") from e + + def _read(self, fmt: str) -> tuple[int, ...]: + return struct.unpack(fmt, self._f.read(struct.calcsize(fmt))) + + @property + def interpreter(self) -> str | None: + """ + The path recorded in the ``PT_INTERP`` section header. + """ + for index in range(self._e_phnum): + self._f.seek(self._e_phoff + self._e_phentsize * index) + try: + data = self._read(self._p_fmt) + except struct.error: + continue + if data[self._p_idx[0]] != 3: # Not PT_INTERP. + continue + self._f.seek(data[self._p_idx[1]]) + return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0") + return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py new file mode 100644 index 00000000000..86de1e6d599 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py @@ -0,0 +1,278 @@ +from __future__ import annotations + +import collections +import contextlib +import functools +import os +import re +import sys +import warnings +from typing import TYPE_CHECKING, NamedTuple + +from ._elffile import EIClass, EIData, ELFFile, EMachine + +if TYPE_CHECKING: + import types + from collections.abc import Generator, Iterator, Sequence + +EF_ARM_ABIMASK = 0xFF000000 +EF_ARM_ABI_VER5 = 0x05000000 +EF_ARM_ABI_FLOAT_HARD = 0x00000400 + +_ALLOWED_ARCHS = { + "x86_64", + "aarch64", + "ppc64", + "ppc64le", + "s390x", + "loongarch64", + "riscv64", +} + + +@contextlib.contextmanager +def _parse_elf(path: str) -> Generator[ELFFile | None, None, None]: + try: + with open(path, "rb") as f: + yield ELFFile(f) + except (OSError, TypeError, ValueError): + yield None + + +def _is_linux_armhf(executable: str) -> bool: + # hard-float ABI can be detected from the ELF header of the running + # process + # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf + with _parse_elf(executable) as f: + return ( + f is not None + and f.capacity == EIClass.C32 + and f.encoding == EIData.Lsb + and f.machine == EMachine.Arm + and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5 + and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD + ) + + +def _is_linux_i686(executable: str) -> bool: + with _parse_elf(executable) as f: + return ( + f is not None + and f.capacity == EIClass.C32 + and f.encoding == EIData.Lsb + and f.machine == EMachine.I386 + ) + + +def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool: + if "armv7l" in archs: + return _is_linux_armhf(executable) + if "i686" in archs: + return _is_linux_i686(executable) + return any(arch in _ALLOWED_ARCHS for arch in archs) + + +# If glibc ever changes its major version, we need to know what the last +# minor version was, so we can build the complete list of all versions. +# For now, guess what the highest minor version might be, assume it will +# be 50 for testing. Once this actually happens, update the dictionary +# with the actual value. +_LAST_GLIBC_MINOR: dict[int, int] = collections.defaultdict(lambda: 50) + + +class _GLibCVersion(NamedTuple): + major: int + minor: int + + +def _glibc_version_string_confstr() -> str | None: + """ + Primary implementation of glibc_version_string using os.confstr. + """ + # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely + # to be broken or missing. This strategy is used in the standard library + # platform module. + # https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183 + try: + # Should be a string like "glibc 2.17". + version_string: str | None = os.confstr("CS_GNU_LIBC_VERSION") + assert version_string is not None + _, version = version_string.rsplit() + except (AssertionError, AttributeError, OSError, ValueError): + # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... + return None + return version + + +def _glibc_version_string_ctypes() -> str | None: + """ + Fallback implementation of glibc_version_string using ctypes. + """ + try: + import ctypes # noqa: PLC0415 + except ImportError: + return None + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + # + # We must also handle the special case where the executable is not a + # dynamically linked executable. This can occur when using musl libc, + # for example. In this situation, dlopen() will error, leading to an + # OSError. Interestingly, at least in the case of musl, there is no + # errno set on the OSError. The single string argument used to construct + # OSError comes from libc itself and is therefore not portable to + # hard code here. In any case, failure to call dlopen() means we + # can proceed, so we bail on our attempt. + try: + process_namespace = ctypes.CDLL(None) + except OSError: + return None + + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5". + gnu_get_libc_version.restype = ctypes.c_char_p + # A c_char_p restype comes back as bytes, so decode to text. + version_str: str | bytes = gnu_get_libc_version() + if isinstance(version_str, bytes): + version_str = version_str.decode("ascii") + + return version_str + + +def _glibc_version_string() -> str | None: + """Returns glibc version string, or None if not using glibc.""" + return _glibc_version_string_confstr() or _glibc_version_string_ctypes() + + +def _parse_glibc_version(version_str: str) -> _GLibCVersion: + """Parse glibc version. + + We use a regexp instead of str.split because we want to discard any + random junk that might come after the minor version -- this might happen + in patched/forked versions of glibc (e.g. Linaro's version of glibc + uses version strings like "2.20-2014.11"). See gh-3588. + """ + m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) + if not m: + warnings.warn( + f"Expected glibc version with 2 components major.minor, got: {version_str}", + RuntimeWarning, + stacklevel=2, + ) + return _GLibCVersion(-1, -1) + return _GLibCVersion(int(m.group("major")), int(m.group("minor"))) + + +@functools.lru_cache +def _get_glibc_version() -> _GLibCVersion: + version_str = _glibc_version_string() + if version_str is None: + return _GLibCVersion(-1, -1) + return _parse_glibc_version(version_str) + + +# From PEP 513, PEP 600 +@functools.lru_cache(maxsize=1) +def _get_manylinux_module() -> types.ModuleType | None: + """Return the ``_manylinux`` C extension module, or None if unavailable. + + The result is cached for the lifetime of the process, since the presence + of the module does not change while running. + """ + try: + return __import__("_manylinux") + except ImportError: + return None + + +def _is_compatible(arch: str, version: _GLibCVersion) -> bool: + sys_glibc = _get_glibc_version() + if sys_glibc < version: + return False + # Check for presence of _manylinux module. + manylinux_mod = _get_manylinux_module() + if manylinux_mod is None: + return True + if hasattr(manylinux_mod, "manylinux_compatible"): + result = manylinux_mod.manylinux_compatible(version[0], version[1], arch) + if result is not None: + return bool(result) + return True + if version == _GLibCVersion(2, 5) and hasattr( + manylinux_mod, "manylinux1_compatible" + ): + return bool(manylinux_mod.manylinux1_compatible) + if version == _GLibCVersion(2, 12) and hasattr( + manylinux_mod, "manylinux2010_compatible" + ): + return bool(manylinux_mod.manylinux2010_compatible) + if version == _GLibCVersion(2, 17) and hasattr( + manylinux_mod, "manylinux2014_compatible" + ): + return bool(manylinux_mod.manylinux2014_compatible) + return True + + +_LEGACY_MANYLINUX_MAP: dict[_GLibCVersion, str] = { + # CentOS 7 w/ glibc 2.17 (PEP 599) + _GLibCVersion(2, 17): "manylinux2014", + # CentOS 6 w/ glibc 2.12 (PEP 571) + _GLibCVersion(2, 12): "manylinux2010", + # CentOS 5 w/ glibc 2.5 (PEP 513) + _GLibCVersion(2, 5): "manylinux1", +} + + +def platform_tags(archs: Sequence[str]) -> Iterator[str]: + """Generate manylinux tags compatible to the current platform. + + :param archs: Sequence of compatible architectures. + The first one shall be the closest to the actual architecture and be the part of + platform tag after the ``linux_`` prefix, e.g. ``x86_64``. + The ``linux_`` prefix is assumed as a prerequisite for the current platform to + be manylinux-compatible. + + :returns: An iterator of compatible manylinux tags. + """ + if not _have_compatible_abi(sys.executable, archs): + return + # Oldest glibc to be supported regardless of architecture is (2, 17). + too_old_glibc2 = _GLibCVersion(2, 16) + if set(archs) & {"x86_64", "i686"}: + # On x86/i686 also oldest glibc to be supported is (2, 5). + too_old_glibc2 = _GLibCVersion(2, 4) + current_glibc = _GLibCVersion(*_get_glibc_version()) + glibc_max_list = [current_glibc] + # We can assume compatibility across glibc major versions. + # https://sourceware.org/bugzilla/show_bug.cgi?id=24636 + # + # Build a list of maximum glibc versions so that we can + # output the canonical list of all glibc from current_glibc + # down to too_old_glibc2, including all intermediary versions. + for glibc_major in range(current_glibc.major - 1, 1, -1): + glibc_minor = _LAST_GLIBC_MINOR[glibc_major] + glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor)) + for arch in archs: + for glibc_max in glibc_max_list: + if glibc_max.major == too_old_glibc2.major: + min_minor = too_old_glibc2.minor + else: + # For other glibc major versions oldest supported is (x, 0). + min_minor = -1 + for glibc_minor in range(glibc_max.minor, min_minor, -1): + glibc_version = _GLibCVersion(glibc_max.major, glibc_minor) + if _is_compatible(arch, glibc_version): + yield "manylinux_{}_{}_{}".format(*glibc_version, arch) + + # Handle the legacy manylinux1, manylinux2010, manylinux2014 tags. + if legacy_tag := _LEGACY_MANYLINUX_MAP.get(glibc_version): + yield f"{legacy_tag}_{arch}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py new file mode 100644 index 00000000000..74c4136f535 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py @@ -0,0 +1,88 @@ +"""PEP 656 support. + +This module implements logic to detect if the currently running Python is +linked against musl, and what musl version is used. +""" + +from __future__ import annotations + +import functools +import re +import subprocess +import sys +from typing import TYPE_CHECKING, NamedTuple + +from ._elffile import ELFFile + +if TYPE_CHECKING: + from collections.abc import Iterator, Sequence + + +class _MuslVersion(NamedTuple): + major: int + minor: int + + +def _parse_musl_version(output: str) -> _MuslVersion | None: + lines = [n for n in (n.strip() for n in output.splitlines()) if n] + if len(lines) < 2 or lines[0][:4] != "musl": + return None + m = re.match(r"Version (\d+)\.(\d+)", lines[1]) + if not m: + return None + return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2))) + + +@functools.lru_cache +def _get_musl_version(executable: str) -> _MuslVersion | None: + """Detect currently-running musl runtime version. + + This is done by checking the specified executable's dynamic linking + information, and invoking the loader to parse its output for a version + string. If the loader is musl, the output would be something like:: + + musl libc (x86_64) + Version 1.2.2 + Dynamic Program Loader + """ + try: + with open(executable, "rb") as f: + ld = ELFFile(f).interpreter + except (OSError, TypeError, ValueError): + return None + if ld is None or "musl" not in ld: + return None + proc = subprocess.run([ld], check=False, stderr=subprocess.PIPE, text=True) + return _parse_musl_version(proc.stderr) + + +def platform_tags(archs: Sequence[str]) -> Iterator[str]: + """Generate musllinux tags compatible to the current platform. + + :param archs: Sequence of compatible architectures. + The first one shall be the closest to the actual architecture and be the part of + platform tag after the ``linux_`` prefix, e.g. ``x86_64``. + The ``linux_`` prefix is assumed as a prerequisite for the current platform to + be musllinux-compatible. + + :returns: An iterator of compatible musllinux tags. + """ + sys_musl = _get_musl_version(sys.executable) + if sys_musl is None: # Python not dynamically linked against musl. + return + for arch in archs: + for minor in range(sys_musl.minor, -1, -1): + yield f"musllinux_{sys_musl.major}_{minor}_{arch}" + + +if __name__ == "__main__": # pragma: no cover + import sysconfig + + plat = sysconfig.get_platform() + assert plat.startswith("linux-"), "not linux" + + print("plat:", plat) + print("musl:", _get_musl_version(sys.executable)) + print("tags:", end=" ") + for t in platform_tags([re.sub(r"[.-]", "_", plat.split("-", 1)[-1])]): + print(t, end="\n ") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py new file mode 100644 index 00000000000..9331b4b4c01 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py @@ -0,0 +1,418 @@ +"""Handwritten parser of dependency specifiers. + +The docstring for each __parse_* function contains EBNF-inspired grammar representing +the implementation. +""" + +from __future__ import annotations + +import ast +from collections.abc import Sequence +from typing import Literal, NamedTuple, Union + +from ._tokenizer import DEFAULT_RULES, ParserSyntaxError, Tokenizer + + +class Node: + __slots__ = ("value",) + + def __init__(self, value: str) -> None: + self.value = value + + def __str__(self) -> str: + return self.value + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}({self.value!r})>" + + def serialize(self) -> str: + raise NotImplementedError + + def __getstate__(self) -> str: + # Return just the value string for compactness and stability. + return self.value + + def _restore_value(self, value: object) -> None: + if not isinstance(value, str): + raise TypeError( + f"Cannot restore {self.__class__.__name__} value from {value!r}" + ) + self.value = value + + def __setstate__(self, state: object) -> None: + if isinstance(state, str): + # New format (26.2+): just the value string. + self._restore_value(state) + return + if isinstance(state, tuple) and len(state) == 2: + # Old format (packaging <= 26.0, __slots__): (None, {slot: value}). + _, slot_dict = state + if isinstance(slot_dict, dict) and "value" in slot_dict: + self._restore_value(slot_dict["value"]) + return + if isinstance(state, dict) and "value" in state: + # Old format (packaging <= 25.0, no __slots__): plain __dict__. + self._restore_value(state["value"]) + return + raise TypeError(f"Cannot restore {self.__class__.__name__} from {state!r}") + + +class Variable(Node): + __slots__ = () + + def serialize(self) -> str: + return str(self) + + +class Value(Node): + __slots__ = () + + def serialize(self) -> str: + value = str(self) + if '"' not in value: + return f'"{value}"' + if "'" not in value: + return f"'{value}'" + raise ValueError( + "Cannot serialize marker value containing both quote characters" + ) + + +class Op(Node): + __slots__ = () + + def serialize(self) -> str: + return str(self) + + +MarkerLogical = Literal["and", "or"] +MarkerVar = Union[Variable, Value] +MarkerItem = tuple[MarkerVar, Op, MarkerVar] +MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]] +MarkerList = list[Union["MarkerList", MarkerAtom, MarkerLogical]] + + +class ParsedRequirement(NamedTuple): + name: str + url: str + extras: list[str] + specifier: str + marker: MarkerList | None + + +# -------------------------------------------------------------------------------------- +# Recursive descent parser for dependency specifier +# -------------------------------------------------------------------------------------- +def parse_requirement(source: str) -> ParsedRequirement: + return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES)) + + +def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement: + """ + requirement = WS? IDENTIFIER WS? extras WS? requirement_details + """ + tokenizer.consume("WS") + + name_token = tokenizer.expect( + "IDENTIFIER", expected="package name at the start of dependency specifier" + ) + name = name_token.text + tokenizer.consume("WS") + + extras = _parse_extras(tokenizer) + tokenizer.consume("WS") + + url, specifier, marker = _parse_requirement_details(tokenizer) + tokenizer.expect("END", expected="end of dependency specifier") + + return ParsedRequirement(name, url, extras, specifier, marker) + + +def _parse_requirement_details( + tokenizer: Tokenizer, +) -> tuple[str, str, MarkerList | None]: + """ + requirement_details = AT URL (WS requirement_marker?)? + | specifier WS? (requirement_marker)? + """ + + specifier = "" + url = "" + marker = None + + if tokenizer.check("AT"): + tokenizer.read() + tokenizer.consume("WS") + + url_start = tokenizer.position + url = tokenizer.expect("URL", expected="URL after @").text + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + tokenizer.expect("WS", expected="whitespace after URL") + + # The input might end after whitespace. + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + marker = _parse_requirement_marker( + tokenizer, + span_start=url_start, + expected="semicolon (after URL and whitespace)", + ) + else: + specifier_start = tokenizer.position + specifier = _parse_specifier(tokenizer) + tokenizer.consume("WS") + + if tokenizer.check("END", peek=True): + return (url, specifier, marker) + + marker = _parse_requirement_marker( + tokenizer, + span_start=specifier_start, + expected=( + "comma (within version specifier), semicolon (after version specifier)" + if specifier + else "semicolon (after name with no version specifier)" + ), + ) + + return (url, specifier, marker) + + +def _parse_requirement_marker( + tokenizer: Tokenizer, *, span_start: int, expected: str +) -> MarkerList: + """ + requirement_marker = SEMICOLON marker WS? + """ + + if not tokenizer.check("SEMICOLON"): + tokenizer.raise_syntax_error( + f"Expected {expected} or end", + span_start=span_start, + span_end=None, + ) + tokenizer.read() + + marker = _parse_marker(tokenizer) + tokenizer.consume("WS") + + return marker + + +def _parse_extras(tokenizer: Tokenizer) -> list[str]: + """ + extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)? + """ + if not tokenizer.check("LEFT_BRACKET", peek=True): + return [] + + with tokenizer.enclosing_tokens( + "LEFT_BRACKET", + "RIGHT_BRACKET", + around="extras", + ): + tokenizer.consume("WS") + extras = _parse_extras_list(tokenizer) + tokenizer.consume("WS") + + return extras + + +def _parse_extras_list(tokenizer: Tokenizer) -> list[str]: + """ + extras_list = identifier (wsp* ',' wsp* identifier)* + """ + extras: list[str] = [] + + if not tokenizer.check("IDENTIFIER"): + return extras + + extras.append(tokenizer.read().text) + + while True: + tokenizer.consume("WS") + if tokenizer.check("IDENTIFIER", peek=True): + tokenizer.raise_syntax_error("Expected comma between extra names") + elif not tokenizer.check("COMMA"): + break + + tokenizer.read() + tokenizer.consume("WS") + + extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma") + extras.append(extra_token.text) + + return extras + + +def _parse_specifier(tokenizer: Tokenizer) -> str: + """ + specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS + | WS? version_many WS? + """ + with tokenizer.enclosing_tokens( + "LEFT_PARENTHESIS", + "RIGHT_PARENTHESIS", + around="version specifier", + ): + tokenizer.consume("WS") + parsed_specifiers = _parse_version_many(tokenizer) + tokenizer.consume("WS") + + return parsed_specifiers + + +def _parse_version_many(tokenizer: Tokenizer) -> str: + """ + version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)? + """ + parsed_specifiers = "" + while tokenizer.check("SPECIFIER"): + span_start = tokenizer.position + specifier = tokenizer.read().text + parsed_specifiers += specifier + if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True): + message = ".* suffix can only be used with `==` or `!=` operators" + if specifier.startswith("!=") or ( + specifier.startswith("==") and not specifier.startswith("===") + ): + message = ( + ".* suffix cannot be used with pre-release, post-release, " + "dev or local versions" + ) + tokenizer.raise_syntax_error( + message, + span_start=span_start, + span_end=tokenizer.position + 1, + ) + if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True): + tokenizer.raise_syntax_error( + "Local version label can only be used with `==` or `!=` operators", + span_start=span_start, + span_end=tokenizer.position, + ) + tokenizer.consume("WS") + if not tokenizer.check("COMMA"): + break + parsed_specifiers += tokenizer.read().text + tokenizer.consume("WS") + + return parsed_specifiers + + +# -------------------------------------------------------------------------------------- +# Recursive descent parser for marker expression +# -------------------------------------------------------------------------------------- +def parse_marker(source: str) -> MarkerList: + return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES)) + + +def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList: + retval = _parse_marker(tokenizer) + tokenizer.expect("END", expected="end of marker expression") + return retval + + +def _parse_marker(tokenizer: Tokenizer) -> MarkerList: + """ + marker = marker_atom (BOOLOP marker_atom)+ + """ + expression = [_parse_marker_atom(tokenizer)] + while tokenizer.check("BOOLOP"): + token = tokenizer.read() + expr_right = _parse_marker_atom(tokenizer) + expression.extend((token.text, expr_right)) + return expression + + +def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom: + """ + marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS? + | WS? marker_item WS? + """ + + tokenizer.consume("WS") + if tokenizer.check("LEFT_PARENTHESIS", peek=True): + with tokenizer.enclosing_tokens( + "LEFT_PARENTHESIS", + "RIGHT_PARENTHESIS", + around="marker expression", + ): + tokenizer.consume("WS") + marker: MarkerAtom = _parse_marker(tokenizer) + tokenizer.consume("WS") + else: + marker = _parse_marker_item(tokenizer) + tokenizer.consume("WS") + return marker + + +def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem: + """ + marker_item = WS? marker_var WS? marker_op WS? marker_var WS? + """ + tokenizer.consume("WS") + marker_var_left = _parse_marker_var(tokenizer) + tokenizer.consume("WS") + marker_op = _parse_marker_op(tokenizer) + tokenizer.consume("WS") + marker_var_right = _parse_marker_var(tokenizer) + tokenizer.consume("WS") + return (marker_var_left, marker_op, marker_var_right) + + +def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar: # noqa: RET503 + """ + marker_var = VARIABLE | QUOTED_STRING + """ + if tokenizer.check("VARIABLE"): + return process_env_var(tokenizer.read().text.replace(".", "_")) + elif tokenizer.check("QUOTED_STRING"): + token = tokenizer.read() + try: + return process_python_str(token.text) + except (SyntaxError, ValueError) as exc: + raise ParserSyntaxError( + "Invalid quoted string", + source=tokenizer.source, + span=(token.position, token.position + len(token.text)), + ) from exc + else: + tokenizer.raise_syntax_error( + message="Expected a marker variable or quoted string" + ) + + +def process_env_var(env_var: str) -> Variable: + if env_var in ("platform_python_implementation", "python_implementation"): + return Variable("platform_python_implementation") + else: + return Variable(env_var) + + +def process_python_str(python_str: str) -> Value: + value = ast.literal_eval(python_str) + return Value(str(value)) + + +def _parse_marker_op(tokenizer: Tokenizer) -> Op: + """ + marker_op = IN | NOT IN | OP + """ + if tokenizer.check("IN"): + tokenizer.read() + return Op("in") + elif tokenizer.check("NOT"): + tokenizer.read() + tokenizer.expect("WS", expected="whitespace after 'not'") + tokenizer.expect("IN", expected="'in' after 'not'") + return Op("not in") + elif tokenizer.check("OP"): + return Op(tokenizer.read().text) + else: + return tokenizer.raise_syntax_error( + "Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in" + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py new file mode 100644 index 00000000000..5370ec87e61 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py @@ -0,0 +1,836 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +"""Private version-range helpers used by :mod:`packaging.specifiers`.""" + +from __future__ import annotations + +import enum +import functools +from typing import ( + TYPE_CHECKING, + Any, + Final, +) + +from .version import InvalidVersion, Version + +if TYPE_CHECKING: + from collections.abc import Callable, Iterable, Iterator, Sequence + from typing import Union + + # Total-order key for comparing two boundaries (boundary-vs-boundary only). + # The post slot may be ``_BOUNDARY_INF`` for an AFTER_POSTS boundary. + _BoundaryOrderSuffix = tuple[int, int, int, Union[int, float], int, int] + _BoundaryOrderKey = tuple[int, tuple[int, ...], _BoundaryOrderSuffix, float] + +__all__ = [ + "FULL_RANGE", + "bounds_for_spec", + "coerce_version", + "filter_by_ranges", + "intersect_ranges", + "intersect_specifier_bounds", + "least_version_above", + "matches_bounds_only", + "range_is_empty", + "ranges_are_prerelease_only", + "resolve_prereleases", + "standard_ranges", + "wildcard_ranges", +] + +#: The smallest possible PEP 440 version. No valid version is less than this. +MIN_VERSION: Final[Version] = Version("0.dev0") + +#: The smallest non-pre-release version, i.e. the nearest non-pre-release at or +#: above the ``-inf`` floor. +MIN_RELEASE: Final[Version] = Version("0") + +#: Sorts above any real post number and any local label, so a boundary can be +#: ordered above the version family it covers when two boundaries are compared. +_BOUNDARY_INF: Final[float] = float("inf") + + +class BoundaryKind(enum.Enum): + """Where a boundary marker sits in the version ordering.""" + + AFTER_LOCALS = enum.auto() # after V+local, before V.post0 + AFTER_POSTS = enum.auto() # after V.postN, before next release + + +@functools.total_ordering +class BoundaryVersion: + """A point on the version line between two real PEP 440 versions. + + Relative to a base version V:: + + V < V+local < AFTER_LOCALS(V) < V.post0 < AFTER_POSTS(V) + + AFTER_LOCALS is the upper bound of ``<=V``, ``==V``, ``!=V`` (no + local), and the lower bound of the upper-side range of ``!=V``. + AFTER_POSTS is the lower bound of ``>V`` (V final or pre-release), + excluding V's post-releases per PEP 440. + """ + + __slots__ = ( + "_cached_dev", + "_cached_epoch", + "_cached_post", + "_cached_pre", + "_cached_trimmed_release", + "kind", + "version", + ) + + def __init__(self, version: Version, kind: BoundaryKind) -> None: + self.version = version + self.kind = kind + self._cached_trimmed_release = trim_release(version.release) + self._cached_epoch = version.epoch + self._cached_pre = version.pre + self._cached_post = version.post + self._cached_dev = version.dev + + def _is_family(self, other: Version) -> bool: + """Is ``other`` a version that this boundary sorts above?""" + if other.epoch != self._cached_epoch: + return False + # Inline release-trim comparison: other.release matches the + # trimmed release iff its leading slice is equal and any extra + # components are zero. Avoids trim_release's tuple allocation. + other_release = other.release + trimmed_release = self._cached_trimmed_release + trimmed_length = len(trimmed_release) + if len(other_release) < trimmed_length: + return False + if other_release[:trimmed_length] != trimmed_release: + return False + for i in range(trimmed_length, len(other_release)): + if other_release[i] != 0: + return False + if other.pre != self._cached_pre: + return False + if self.kind == BoundaryKind.AFTER_LOCALS: + # Local family: same public version, any local label. + return other.post == self._cached_post and other.dev == self._cached_dev + # Post family: V itself + any post-release of V. + return other.dev == self._cached_dev or other.post is not None + + def _order_key(self) -> _BoundaryOrderKey: + """Sort key placing this boundary just above the versions it covers. + + It extends ``V``'s comparison key ``(epoch, release, suffix)`` with + a trailing ``_BOUNDARY_INF`` local component, so the key sorts after + ``V`` and every ``V+local`` (whose keys carry a real, finite local + segment). ``suffix`` is the 6-int comparison suffix + ``(pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)``. + + For an AFTER_POSTS boundary the suffix is replaced with one whose + post number is ``_BOUNDARY_INF``, so the key also sorts after every + ``V.postN``. An AFTER_LOCALS boundary uses ``V``'s suffix unchanged. + """ + version_key = self.version._key + suffix: _BoundaryOrderSuffix = version_key[2] + + if self.kind == BoundaryKind.AFTER_POSTS: + suffix = (suffix[0], suffix[1], 1, _BOUNDARY_INF, 1, 0) + + return version_key[0], version_key[1], suffix, _BOUNDARY_INF + + def __eq__(self, other: object) -> bool: + # Key off the order key so equality matches the ``<`` / ``>`` order: + # ``AFTER_POSTS(1.0)`` and ``AFTER_POSTS(1.0.post1)`` are the same point. + if isinstance(other, BoundaryVersion): + return self._order_key() == other._order_key() + return NotImplemented + + def __lt__(self, other: BoundaryVersion | Version) -> bool: + if isinstance(other, BoundaryVersion): + return self._order_key() < other._order_key() + # boundary < other_version iff V < other AND other not in family. + # The cheap V >= other path short-circuits before the family check. + if not (self.version < other): + return False + return not self._is_family(other) + + def __gt__(self, other: BoundaryVersion | Version) -> bool: + # Defined directly to bypass functools.total_ordering's + # NotImplemented round-trip on reflected ``Version < boundary``. + if isinstance(other, BoundaryVersion): + return self._order_key() > other._order_key() + if self.version >= other: + return True + return self._is_family(other) + + def __hash__(self) -> int: + # Keyed to ``__eq__`` (the order key), so equal boundaries hash equal. + return hash(self._order_key()) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.version!r}, {self.kind.name})" + + +if TYPE_CHECKING: + _VersionOrBoundary = Union[Version, BoundaryVersion, None] + + +@functools.total_ordering +class LowerBound: + """Lower bound of a version range. + + A version *v* of ``None`` means unbounded below (-inf). + At equal versions, ``[v`` sorts before ``(v`` because an inclusive + bound starts earlier. + """ + + __slots__ = ("_above", "inclusive", "version") + + def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None: + self.version = version + self.inclusive = inclusive + # Pre-bind a predicate "is parsed at or above this lower + # bound?" for the hot filter / contains loops. One direct + # call per check, no operator-dispatch chain. + if version is None: + self._above: Callable[[Version], bool] | None = None + elif isinstance(version, BoundaryVersion): + # >V produces an AFTER_POSTS lower bound; the upper-side + # range of !=V produces an AFTER_LOCALS lower bound. + if version.kind == BoundaryKind.AFTER_POSTS: + self._above = _make_above_after_posts(version.version) + else: + self._above = _make_above_after_locals(version.version) + elif inclusive: + self._above = version.__le__ + else: + self._above = version.__lt__ + + def __eq__(self, other: object) -> bool: + if not isinstance(other, LowerBound): + return NotImplemented + return self.version == other.version and self.inclusive == other.inclusive + + def __lt__(self, other: LowerBound) -> bool: + if not isinstance(other, LowerBound): + return NotImplemented + # -inf < anything (except -inf itself). + if self.version is None: + return other.version is not None + if other.version is None: + return False + if self.version != other.version: + return self.version < other.version + # [v < (v: inclusive starts earlier. + return self.inclusive and not other.inclusive + + def __hash__(self) -> int: + return hash((self.version, self.inclusive)) + + def __repr__(self) -> str: + bracket = "[" if self.inclusive else "(" + return f"<{self.__class__.__name__} {bracket}{self.version!r}>" + + +@functools.total_ordering +class UpperBound: + """Upper bound of a version range. + + A version *v* of ``None`` means unbounded above (+inf). + At equal versions, ``v)`` sorts before ``v]`` because an exclusive + bound ends earlier. + """ + + __slots__ = ("_below", "inclusive", "version") + + def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None: + self.version = version + self.inclusive = inclusive + # Pre-bind a predicate "is parsed at or below this upper + # bound?". See LowerBound for the rationale. + if version is None: + self._below: Callable[[Version], bool] | None = None + elif isinstance(version, BoundaryVersion): + # Standard specifiers only ever produce AFTER_LOCALS upper + # bounds (from <=V / ==V / !=V with no local). + if version.kind == BoundaryKind.AFTER_LOCALS: + self._below = _make_below_after_locals(version.version) + else: + # An AFTER_POSTS upper is not produced by any specifier, but + # range algebra reaches it: complementing ``>V`` flips the + # ``AFTER_POSTS(V)`` lower into this upper bound. + self._below = version.__ge__ + elif inclusive: + self._below = version.__ge__ + else: + self._below = version.__gt__ + + def __eq__(self, other: object) -> bool: + if not isinstance(other, UpperBound): + return NotImplemented + return self.version == other.version and self.inclusive == other.inclusive + + def __lt__(self, other: UpperBound) -> bool: + if not isinstance(other, UpperBound): + return NotImplemented + # Nothing < +inf (except +inf itself). + if self.version is None: + return False + if other.version is None: + return True + if self.version != other.version: + return self.version < other.version + # v) < v]: exclusive ends earlier. + return not self.inclusive and other.inclusive + + def __hash__(self) -> int: + return hash((self.version, self.inclusive)) + + def __repr__(self) -> str: + bracket = "]" if self.inclusive else ")" + return f"<{self.__class__.__name__} {self.version!r}{bracket}>" + + +if TYPE_CHECKING: + #: A single contiguous interval as a (lower, upper) bound pair. + Interval = tuple[LowerBound, UpperBound] + + +NEG_INF: Final[LowerBound] = LowerBound(None, False) +POS_INF: Final[UpperBound] = UpperBound(None, False) +FULL_RANGE: Final[tuple[Interval]] = ((NEG_INF, POS_INF),) + + +def trim_release(release: tuple[int, ...]) -> tuple[int, ...]: + """Strip trailing zeros from a release tuple for normalized comparison.""" + end = len(release) + while end > 1 and release[end - 1] == 0: + end -= 1 + return release if end == len(release) else release[:end] + + +def _next_prefix_dev0(version: Version) -> Version: + """Smallest version in the next prefix: 1.2 -> 1.3.dev0.""" + release = (*version.release[:-1], version.release[-1] + 1) + return Version.from_parts(epoch=version.epoch, release=release, dev=0) + + +def _base_dev0(version: Version) -> Version: + """The .dev0 of a version's base release: 1.2 -> 1.2.dev0.""" + return Version.from_parts(epoch=version.epoch, release=version.release, dev=0) + + +def coerce_version(version: Version | str) -> Version | None: + if not isinstance(version, Version): + try: + version = Version(version) + except InvalidVersion: + return None + return version + + +def _make_above_after_posts(version: Version) -> Callable[[Version], bool]: + """Predicate ``parsed > AFTER_POSTS(V)`` for a lower bound. + + Per PEP 440, ``>V`` excludes V's post-releases unless V is itself + a post-release. AFTER_POSTS sits above V and every V.postN (with + or without local), and just below the next release. + """ + version_ge = version.__ge__ + version_epoch = version.epoch + version_pre = version.pre + version_release_trimmed = trim_release(version.release) + trimmed_length = len(version_release_trimmed) + + def above(parsed: Version) -> bool: + if version_ge(parsed): + return False + # parsed > V cmpkey-wise: above the boundary iff NOT in V's + # post family. + if parsed.epoch != version_epoch: + return True + parsed_release = parsed.release + if len(parsed_release) < trimmed_length: + return True + if parsed_release[:trimmed_length] != version_release_trimmed: + return True + for i in range(trimmed_length, len(parsed_release)): + if parsed_release[i] != 0: + return True + if parsed.pre != version_pre: + return True + + # Same release and pre as V: parsed is in V's post family (V itself, + # V+local, or V.postN), which the boundary sits above. A V.devN + # (different dev, no post) sorts before V and was already caught by + # ``version_ge`` above, so the answer here is always "not above". + return False + + return above + + +def _make_above_after_locals(version: Version) -> Callable[[Version], bool]: + """Predicate ``parsed > AFTER_LOCALS(V)`` for a lower bound. + + Used by the upper-side range of ``!=V`` (when V has no local + segment). AFTER_LOCALS sits above V and every ``V+local`` but + just below ``V.post0``. + """ + version_ge = version.__ge__ + version_epoch = version.epoch + version_pre = version.pre + version_post = version.post + version_dev = version.dev + version_release_trimmed = trim_release(version.release) + trimmed_length = len(version_release_trimmed) + + def above(parsed: Version) -> bool: + if version_ge(parsed): + return False + # parsed > V cmpkey-wise: above the boundary iff NOT in V's + # local family (same public version, any local segment). + if parsed.epoch != version_epoch: + return True + parsed_release = parsed.release + if len(parsed_release) < trimmed_length: + return True + if parsed_release[:trimmed_length] != version_release_trimmed: + return True + for i in range(trimmed_length, len(parsed_release)): + if parsed_release[i] != 0: + return True + if parsed.pre != version_pre: + return True + if parsed.post != version_post: + return True + return parsed.dev != version_dev + + return above + + +def _make_below_after_locals(version: Version) -> Callable[[Version], bool]: + """Predicate ``parsed <= AFTER_LOCALS(V)`` for an upper bound. + + Used by ``<=V``, ``==V``, ``!=V`` (no local). ``parsed`` is at or + below the boundary when it is at or below V cmpkey-wise, or when + it is in V's local family. + """ + version_ge = version.__ge__ + version_epoch = version.epoch + version_pre = version.pre + version_post = version.post + version_dev = version.dev + version_release_trimmed = trim_release(version.release) + trimmed_length = len(version_release_trimmed) + + def below(parsed: Version) -> bool: + if version_ge(parsed): + return True + # parsed > V cmpkey-wise: below the boundary iff in V's local + # family. + if parsed.epoch != version_epoch: + return False + parsed_release = parsed.release + if len(parsed_release) < trimmed_length: + return False + if parsed_release[:trimmed_length] != version_release_trimmed: + return False + for i in range(trimmed_length, len(parsed_release)): + if parsed_release[i] != 0: + return False + if parsed.pre != version_pre: + return False + if parsed.post != version_post: + return False + return parsed.dev == version_dev + + return below + + +def least_version_above(boundary: BoundaryVersion) -> Version | None: + """Smallest real version strictly above *boundary*, or ``None`` if none exists.""" + base = boundary.version + + if boundary.kind == BoundaryKind.AFTER_LOCALS: + # AFTER_LOCALS(V) sits just below V.post0, so its least successor is + # V.post0.dev0 (V.dev(N+1) if V has a dev, V.post(N+1).dev0 if a post). + if base.dev is not None: + return base.__replace__(dev=base.dev + 1, local=None) + next_post = (base.post + 1) if base.post is not None else 0 + return base.__replace__(post=next_post, dev=0, local=None) + + # AFTER_POSTS(V): a pre-release V steps to the next pre-release's .dev0; + # a final-release AFTER_POSTS has no least successor. + if base.pre is not None: + kind, number = base.pre + return base.__replace__(pre=(kind, number + 1), post=None, dev=0, local=None) + + return None + + +def range_is_empty(lower: LowerBound, upper: UpperBound) -> bool: + """True when the range defined by *lower* and *upper* contains no versions. + + A boundary lower sits just below the next real version, so an ordered pair + is still empty when the upper excludes that least successor: + ``(AFTER_POSTS(1.0a1), 1.0a2.dev0)`` holds no version. + """ + if upper.version is None: + return False + + if lower.version is None: + # Nothing sorts below MIN_VERSION, so an exclusive upper at or below it + # leaves an empty floor interval such as ``(-inf, 0.dev0)``. + return ( + not upper.inclusive + and isinstance(upper.version, Version) + and upper.version <= MIN_VERSION + ) + + if isinstance(lower.version, BoundaryVersion): + successor = least_version_above(lower.version) + if successor is not None: + if upper.version == successor: + return not upper.inclusive + return upper.version < successor + + if lower.version == upper.version: + return not (lower.inclusive and upper.inclusive) + + return lower.version > upper.version + + +def intersect_ranges( + left: Sequence[Interval], + right: Sequence[Interval], +) -> list[Interval]: + """Intersect two sorted, non-overlapping range lists (two-pointer merge).""" + result: list[Interval] = [] + left_index = right_index = 0 + while left_index < len(left) and right_index < len(right): + left_lower, left_upper = left[left_index] + right_lower, right_upper = right[right_index] + + lower = max(left_lower, right_lower) + upper = min(left_upper, right_upper) + + if not range_is_empty(lower, upper): + result.append((lower, upper)) + + # Advance whichever side has the smaller upper bound. + if left_upper < right_upper: + left_index += 1 + else: + right_index += 1 + + return result + + +def filter_by_ranges( + ranges: Sequence[Interval], + iterable: Iterable[Any], + key: Callable[[Any], Version | str] | None, + prereleases: bool | None, + region: Sequence[Interval] = (), +) -> Iterator[Any]: + """Filter *iterable* against precomputed version *ranges*. + + With ``prereleases=None``, the PEP 440 default applies: pre-releases are + excluded unless no final matches, in which case buffered pre-releases come + out at the end. A pre-release inside the opt-in ``region`` is the exception: + it is force-admitted in place, as ``prereleases=True`` would yield it. A + force-admitted pre-release is not a final, so it never suppresses the buffer. + """ + if prereleases is None: + prerelease_buffer: list[Any] = [] + found_final = False + + if len(ranges) == 1: + # Hot path: most specifiers and small SpecifierSets reduce to + # a single contiguous range. + lower, upper = ranges[0] + above = lower._above + below = upper._below + for item in iterable: + parsed = coerce_version(item if key is None else key(item)) + if parsed is None: + continue + if above is not None and not above(parsed): + continue + if below is not None and not below(parsed): + continue + if not parsed.is_prerelease: + found_final = True + yield item + elif region and matches_bounds_only(region, parsed): + yield item + elif not found_final: + prerelease_buffer.append(item) + if not found_final: + yield from prerelease_buffer + return + + for item in iterable: + parsed = coerce_version(item if key is None else key(item)) + if parsed is None: + continue + for lower, upper in ranges: + above = lower._above + if above is not None and not above(parsed): + break + below = upper._below + if below is None or below(parsed): + if not parsed.is_prerelease: + found_final = True + yield item + elif region and matches_bounds_only(region, parsed): + yield item + elif not found_final: + prerelease_buffer.append(item) + break + if not found_final: + yield from prerelease_buffer + return + + exclude_prereleases = prereleases is False + + if len(ranges) == 1: + # Hot path: most specifiers and small SpecifierSets reduce to + # a single contiguous range. + lower, upper = ranges[0] + above = lower._above + below = upper._below + for item in iterable: + parsed = coerce_version(item if key is None else key(item)) + if parsed is None: + continue + if exclude_prereleases and parsed.is_prerelease: + continue + if above is not None and not above(parsed): + continue + if below is None or below(parsed): + yield item + return + + for item in iterable: + parsed = coerce_version(item if key is None else key(item)) + if parsed is None: + continue + if exclude_prereleases and parsed.is_prerelease: + continue + for lower, upper in ranges: + above = lower._above + if above is not None and not above(parsed): + break + below = upper._below + if below is None or below(parsed): + yield item + break + + +def _nearest_release_above_prerelease(version: Version) -> Version: + """Smallest non-pre-release at or above a pre-release *version*.""" + if version.pre is not None: + # An a/b/rc pre-release drops to its final release, which outranks + # every post-release of that pre-release (1.0a1.post0 -> 1.0). + return version.__replace__(pre=None, post=None, dev=None, local=None) + + # A dev-only release keeps its post-release (1.0.post0.dev0 -> 1.0.post0, + # whose final 1.0 sorts below it). + return version.__replace__(dev=None, local=None) + + +def _lowest_release_at_or_above(value: Version | BoundaryVersion | None) -> Version: + """Smallest non-pre-release version at or above *value*. + + ``None`` is the ``-inf`` floor, whose nearest non-pre-release is + :data:`MIN_RELEASE`. + """ + if value is None: + return MIN_RELEASE + if isinstance(value, BoundaryVersion): + inner_version = value.version + if inner_version.is_prerelease: + return _nearest_release_above_prerelease(inner_version) + # AFTER_LOCALS(1.0) -> nearest non-pre is 1.0.post0 + # AFTER_LOCALS(1.0.post0) -> nearest non-pre is 1.0.post1 + next_post = (inner_version.post + 1) if inner_version.post is not None else 0 + return inner_version.__replace__(post=next_post, local=None) + + if not value.is_prerelease: + return value + + return _nearest_release_above_prerelease(value) + + +def ranges_are_prerelease_only(ranges: Sequence[Interval]) -> bool: + """True when every range in *ranges* contains only pre-releases. + + Used to detect unsatisfiable specifier sets when ``prereleases=False``: + if every range is pre-release-only, every contained version is excluded. + """ + for lower, upper in ranges: + nearest = _lowest_release_at_or_above(lower.version) + if upper.version is None or nearest < upper.version: + return False + if nearest == upper.version and upper.inclusive: + return False + return True + + +def wildcard_ranges(op: str, base: Version) -> list[Interval]: + """Ranges for ==V.* and !=V.*. + + ==1.2.* -> [1.2.dev0, 1.3.dev0); !=1.2.* -> complement. + """ + lower = _base_dev0(base) + upper = _next_prefix_dev0(base) + if op == "==": + return [(LowerBound(lower, True), UpperBound(upper, False))] + # != + return [ + (NEG_INF, UpperBound(lower, False)), + (LowerBound(upper, True), POS_INF), + ] + + +def standard_ranges(op: str, version: Version, has_local: bool) -> list[Interval]: + """Ranges for the standard PEP 440 operators (no wildcard, no ===). + + *has_local* indicates whether the spec string included a ``+local`` + segment; relevant only for ``==`` / ``!=`` to decide whether the + upper bound includes V's local family. + """ + if op == ">=": + return [(LowerBound(version, True), POS_INF)] + + if op == "<=": + return [ + ( + NEG_INF, + UpperBound(BoundaryVersion(version, BoundaryKind.AFTER_LOCALS), True), + ) + ] + + if op == ">": + if version.dev is not None: + # >V.devN: dev versions have no post-releases, so the + # next real version is V.dev(N+1). + lower_bound = version.__replace__(dev=version.dev + 1, local=None) + return [(LowerBound(lower_bound, True), POS_INF)] + if version.post is not None: + # >V.postN: next real version is V.post(N+1).dev0. + lower_bound = version.__replace__(post=version.post + 1, dev=0, local=None) + return [(LowerBound(lower_bound, True), POS_INF)] + # >V (final or pre-release V): exclude V itself, V+local, and + # every V.postN per PEP 440. + return [ + ( + LowerBound(BoundaryVersion(version, BoundaryKind.AFTER_POSTS), False), + POS_INF, + ) + ] + + if op == "<": + # list[Interval]: + """Ranges for one specifier's ``(op, version_str)``. + + Dispatches between the wildcard and standard builders. ``version`` is the + parsed ``version_str`` (its base, without the trailing ``.*``, for + wildcards). ``===`` is not handled here; its match is a literal string + compared in :mod:`packaging.specifiers`. + """ + if version_str.endswith(".*"): + return wildcard_ranges(op, version) + + return standard_ranges(op, version, "+" in version_str) + + +def intersect_specifier_bounds( + per_specifier_ranges: Iterable[Sequence[Interval]], +) -> Sequence[Interval]: + """Intersect each specifier's ranges into a single sequence. + + Short-circuits once the running intersection is empty, since no later + specifier can revive it. Callers must pass at least one specifier. + """ + result: Sequence[Interval] | None = None + for sub in per_specifier_ranges: + if result is None: + result = sub + else: + result = intersect_ranges(result, sub) + if not result: + break + + if result is None: # pragma: no cover - callers guard non-empty input + raise RuntimeError("intersect_specifier_bounds called with no specifiers") + + return result + + +def matches_bounds_only(ranges: Sequence[Interval], version: Version) -> bool: + """Whether ``version`` falls within any of ``ranges``. + + The pure bounds membership test, for a single already-parsed version with + no pre-release policy applied. ``ranges`` are sorted and non-overlapping, + so a version below one range's lower bound is below every later range too. + """ + for lower, upper in ranges: + above = lower._above + if above is not None and not above(version): + return False + + below = upper._below + if below is None or below(version): + return True + + return False + + +def resolve_prereleases( + configured: bool | None, autodetected: bool | None +) -> bool | None: + """Resolve a specifier's effective default pre-release policy. + + An explicit ``configured`` value wins; otherwise an autodetected ``True`` + propagates and anything else falls back to the PEP 440 default (``None``). + """ + if configured is not None: + return configured + + if autodetected: + return True + + return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py new file mode 100644 index 00000000000..4306784d9a2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py @@ -0,0 +1,33 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +"""Backward-compatibility shim for unpickling Version objects serialized before +packaging 26.1. + +Old pickles reference ``packaging._structures.InfinityType`` and +``packaging._structures.NegativeInfinityType``. This module provides minimal +stand-in classes so that ``pickle.loads()`` can resolve those references. +The deserialized objects are not used for comparisons — ``Version.__setstate__`` +discards the stale ``_key`` cache and recomputes it from the core version fields. +""" + +from __future__ import annotations + + +class InfinityType: + """Stand-in for the removed ``InfinityType`` used in old comparison keys.""" + + def __repr__(self) -> str: + return "Infinity" + + +class NegativeInfinityType: + """Stand-in for the removed ``NegativeInfinityType`` used in old comparison keys.""" + + def __repr__(self) -> str: + return "-Infinity" + + +Infinity = InfinityType() +NegativeInfinity = NegativeInfinityType() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py new file mode 100644 index 00000000000..db7cd17fbad --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py @@ -0,0 +1,200 @@ +from __future__ import annotations + +import contextlib +import re +from dataclasses import dataclass +from typing import TYPE_CHECKING, NoReturn + +from .specifiers import Specifier + +if TYPE_CHECKING: + from collections.abc import Generator, Mapping + + +@dataclass +class Token: + __slots__ = ("name", "position", "text") + + name: str + text: str + position: int + + +class ParserSyntaxError(Exception): + """The provided source text could not be parsed correctly.""" + + def __init__( + self, + message: str, + *, + source: str, + span: tuple[int, int], + ) -> None: + self.span = span + self.message = message + self.source = source + + super().__init__() + + def __str__(self) -> str: + marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^" + return f"{self.message}\n {self.source}\n {marker}" + + +DEFAULT_RULES: dict[str, re.Pattern[str]] = { + "LEFT_PARENTHESIS": re.compile(r"\("), + "RIGHT_PARENTHESIS": re.compile(r"\)"), + "LEFT_BRACKET": re.compile(r"\["), + "RIGHT_BRACKET": re.compile(r"\]"), + "SEMICOLON": re.compile(r";"), + "COMMA": re.compile(r","), + "QUOTED_STRING": re.compile( + r""" + ( + ('[^']*') + | + ("[^"]*") + ) + """, + re.VERBOSE, + ), + "OP": re.compile(r"(===|==|~=|!=|<=|>=|<|>)"), + "BOOLOP": re.compile(r"\b(or|and)\b"), + "IN": re.compile(r"\bin\b"), + "NOT": re.compile(r"\bnot\b"), + "VARIABLE": re.compile( + r""" + \b( + python_version + |python_full_version + |os[._]name + |sys[._]platform + |platform_(release|system) + |platform[._](version|machine|python_implementation) + |python_implementation + |implementation_(name|version) + |extras? + |dependency_groups + )\b + """, + re.VERBOSE, + ), + "SPECIFIER": re.compile( + Specifier._specifier_regex_str, + re.VERBOSE | re.IGNORECASE, + ), + "AT": re.compile(r"\@"), + "URL": re.compile(r"[^ \t]+"), + "IDENTIFIER": re.compile(r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b"), + "VERSION_PREFIX_TRAIL": re.compile(r"\.\*"), + "VERSION_LOCAL_LABEL_TRAIL": re.compile(r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*"), + "WS": re.compile(r"[ \t]+"), + "END": re.compile(r"\Z"), +} + + +class Tokenizer: + """Context-sensitive token parsing. + + Provides methods to examine the input stream to check whether the next token + matches. + """ + + __slots__ = ("next_token", "position", "rules", "source") + + def __init__( + self, + source: str, + *, + rules: Mapping[str, re.Pattern[str]], + ) -> None: + self.source = source + self.rules = rules + self.next_token: Token | None = None + self.position = 0 + + def consume(self, name: str) -> None: + """Move beyond provided token name, if at current position.""" + if self.check(name): + self.read() + + def check(self, name: str, *, peek: bool = False) -> bool: + """Check whether the next token has the provided name. + + By default, if the check succeeds, the token *must* be read before + another check. If `peek` is set to `True`, the token is not loaded and + would need to be checked again. + """ + assert self.next_token is None, ( + f"Cannot check for {name!r}, already have {self.next_token!r}" + ) + assert name in self.rules, f"Unknown token name: {name!r}" + + expression = self.rules[name] + + match = expression.match(self.source, self.position) + if match is None: + return False + if not peek: + self.next_token = Token(name, match[0], self.position) + return True + + def expect(self, name: str, *, expected: str) -> Token: + """Expect a certain token name next, failing with a syntax error otherwise. + + The token is read and returned. + """ + if not self.check(name): + raise self.raise_syntax_error(f"Expected {expected}") + return self.read() + + def read(self) -> Token: + """Consume the next token and return it.""" + token = self.next_token + assert token is not None + + self.position += len(token.text) + self.next_token = None + + return token + + def raise_syntax_error( + self, + message: str, + *, + span_start: int | None = None, + span_end: int | None = None, + ) -> NoReturn: + """Raise ParserSyntaxError at the given position.""" + span = ( + self.position if span_start is None else span_start, + self.position if span_end is None else span_end, + ) + raise ParserSyntaxError( + message, + source=self.source, + span=span, + ) + + @contextlib.contextmanager + def enclosing_tokens( + self, open_token: str, close_token: str, *, around: str + ) -> Generator[None, None, None]: + if self.check(open_token): + open_position = self.position + self.read() + else: + open_position = None + + yield + + if open_position is None: + return + + if not self.check(close_token): + self.raise_syntax_error( + f"Expected matching {close_token} for {open_token}, after {around}", + span_start=open_position, + ) + + self.read() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py new file mode 100644 index 00000000000..0ad2d013cc2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py @@ -0,0 +1,335 @@ +from __future__ import annotations + +import re +from collections.abc import Mapping, Sequence + +from .errors import _ErrorCollector +from .requirements import InvalidRequirement, Requirement + +__all__ = [ + "CyclicDependencyGroup", + "DependencyGroupInclude", + "DependencyGroupResolver", + "DuplicateGroupNames", + "InvalidDependencyGroupObject", + "resolve_dependency_groups", +] + + +def __dir__() -> list[str]: + return __all__ + + +# ----------- +# Error Types +# ----------- + + +class DuplicateGroupNames(ValueError): + """ + The same dependency groups were defined twice, with different non-normalized names. + + .. versionadded:: 26.1 + """ + + +class CyclicDependencyGroup(ValueError): + """ + The dependency group includes form a cycle. + + .. versionadded:: 26.1 + """ + + def __init__(self, requested_group: str, group: str, include_group: str) -> None: + self.requested_group = requested_group + self.group = group + self.include_group = include_group + + if include_group == group: + reason = f"{group} includes itself" + else: + reason = f"{include_group} -> {group}, {group} -> {include_group}" + super().__init__( + "Cyclic dependency group include while resolving " + f"{requested_group}: {reason}" + ) + + # Support pickling; ``args`` does not match ``__init__``'s signature. + def __reduce__(self) -> tuple[type[CyclicDependencyGroup], tuple[str, str, str]]: + return (self.__class__, (self.requested_group, self.group, self.include_group)) + + +# in the PEP 735 spec, the tables in dependency group lists were described as +# "Dependency Object Specifiers", but the only defined type of object was a +# "Dependency Group Include" -- hence the naming of this error as "Object" +class InvalidDependencyGroupObject(ValueError): + """ + A member of a dependency group was identified as a dict, but was not in a valid + format. + + .. versionadded:: 26.1 + """ + + +# ------------------------ +# Object Model & Interface +# ------------------------ + + +class DependencyGroupInclude: + """ + A reference to another dependency group by name. + + .. versionadded:: 26.1 + """ + + __slots__ = ("include_group",) + + def __init__(self, include_group: str) -> None: + """ + Initialize a DependencyGroupInclude. + + :param include_group: The name of the group referred to by this include. + """ + self.include_group = include_group + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.include_group!r})" + + +class DependencyGroupResolver: + """ + A resolver for Dependency Group data. + + This class handles caching, name normalization, cycle detection, and other + parsing requirements. There are only two public methods for exploring the data: + ``lookup()`` and ``resolve()``. + + :param dependency_groups: A mapping, as provided via pyproject + ``[dependency-groups]``. + + .. versionadded:: 26.1 + """ + + def __init__( + self, + dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], + ) -> None: + errors = _ErrorCollector() + + self.dependency_groups = _normalize_group_names(dependency_groups, errors) + + # a map of group names to parsed data + self._parsed_groups: dict[ + str, tuple[Requirement | DependencyGroupInclude, ...] + ] = {} + # a map of group names to their ancestors, used for cycle detection + self._include_graph_ancestors: dict[str, tuple[str, ...]] = {} + # a cache of completed resolutions to Requirement lists + self._resolve_cache: dict[str, tuple[Requirement, ...]] = {} + + errors.finalize("[dependency-groups] data was invalid") + + def lookup(self, group: str) -> tuple[Requirement | DependencyGroupInclude, ...]: + """ + Lookup a group name, returning the parsed dependency data for that group. + This will not resolve includes. + + :param group: the name of the group to lookup + """ + group = _normalize_name(group) + + with _ErrorCollector().on_exit( + f"[dependency-groups] data for {group!r} was malformed" + ) as errors: + return self._parse_group(group, errors) + + def resolve(self, group: str) -> tuple[Requirement, ...]: + """ + Resolve a dependency group to a list of requirements. + + :param group: the name of the group to resolve + """ + group = _normalize_name(group) + + with _ErrorCollector().on_exit( + f"[dependency-groups] data for {group!r} was malformed" + ) as errors: + return self._resolve(group, group, errors) + + def _resolve( + self, group: str, requested_group: str, errors: _ErrorCollector + ) -> tuple[Requirement, ...]: + """ + This is a helper for cached resolution to strings. It preserves the name of the + group which the user initially requested in order to present a clearer error in + the event that a cycle is detected. + + :param group: The normalized name of the group to resolve. + :param requested_group: The group which was used in the original, user-facing + request. + """ + if group in self._resolve_cache: + return self._resolve_cache[group] + + parsed = self._parse_group(group, errors) + + resolved_group = [] + + for item in parsed: + if isinstance(item, Requirement): + resolved_group.append(item) + elif isinstance(item, DependencyGroupInclude): + include_group = _normalize_name(item.include_group) + + # if a group is cyclic, record the error + # otherwise, follow the include_group reference + # + # this allows us to examine all includes in a group, even in the + # presence of errors + if include_group in self._include_graph_ancestors.get(group, ()): + errors.error( + CyclicDependencyGroup( + requested_group, group, item.include_group + ) + ) + else: + self._include_graph_ancestors[include_group] = ( + *self._include_graph_ancestors.get(group, ()), + group, + ) + resolved_group.extend( + self._resolve(include_group, requested_group, errors) + ) + else: # pragma: no cover + raise NotImplementedError( + f"Invalid dependency group item after parse: {item}" + ) + + # in the event that errors were detected, present the group as empty and do not + # cache the result + # this ensures that repeated access to a cyclic group will raise multiple errors + if errors.errors: + return () + + self._resolve_cache[group] = tuple(resolved_group) + return self._resolve_cache[group] + + def _parse_group( + self, group: str, errors: _ErrorCollector + ) -> tuple[Requirement | DependencyGroupInclude, ...]: + # short circuit -- never do the work twice + if group in self._parsed_groups: + return self._parsed_groups[group] + + if group not in self.dependency_groups: + errors.error(LookupError(f"Dependency group '{group}' not found")) + return () + + raw_group = self.dependency_groups[group] + if isinstance(raw_group, str): + errors.error( + TypeError( + f"Dependency group {group!r} contained a string rather than a list." + ) + ) + return () + + if not isinstance(raw_group, Sequence): + errors.error( + TypeError(f"Dependency group {group!r} is not a sequence type.") + ) + return () + + elements: list[Requirement | DependencyGroupInclude] = [] + for item in raw_group: + if isinstance(item, str): + # packaging.requirements.Requirement parsing ensures that this is a + # valid PEP 508 Dependency Specifier. Collect InvalidRequirement + # if it throws that. + with errors.collect(InvalidRequirement): + elements.append(Requirement(item)) + elif isinstance(item, Mapping): + if tuple(item.keys()) != ("include-group",): + errors.error( + InvalidDependencyGroupObject( + f"Invalid dependency group item: {item!r}" + ) + ) + else: + include_group = item["include-group"] + if not isinstance(include_group, str): + msg = ( + "Dependency group include-group value is not a string: " + f"{item!r}" + ) + errors.error(TypeError(msg)) + else: + elements.append( + DependencyGroupInclude(include_group=include_group) + ) + else: + errors.error(TypeError(f"Invalid dependency group item: {item!r}")) + + if errors.errors: + return () + + self._parsed_groups[group] = tuple(elements) + return self._parsed_groups[group] + + +# -------------------- +# Functional Interface +# -------------------- + + +def resolve_dependency_groups( + dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], /, *groups: str +) -> tuple[str, ...]: + """ + Resolve a dependency group to a tuple of requirements, as strings. + + :param dependency_groups: the parsed contents of the ``[dependency-groups]`` table + from ``pyproject.toml`` + :param groups: the name of the group(s) to resolve + + .. versionadded:: 26.1 + """ + resolver = DependencyGroupResolver(dependency_groups) + return tuple(str(r) for group in groups for r in resolver.resolve(group)) + + +# ---------------- +# internal helpers +# ---------------- + + +_NORMALIZE_PATTERN = re.compile(r"[-_.]+") + + +def _normalize_name(name: str) -> str: + return _NORMALIZE_PATTERN.sub("-", name).lower() + + +def _normalize_group_names( + dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], + errors: _ErrorCollector, +) -> dict[str, Sequence[str | Mapping[str, str]]]: + original_names: dict[str, list[str]] = {} + normalized_groups: dict[str, Sequence[str | Mapping[str, str]]] = {} + + for group_name, value in dependency_groups.items(): + normed_group_name = _normalize_name(group_name) + original_names.setdefault(normed_group_name, []).append(group_name) + normalized_groups[normed_group_name] = value + + for normed_name, names in original_names.items(): + if len(names) > 1: + errors.error( + DuplicateGroupNames( + "Duplicate dependency group names: " + f"{normed_name} ({', '.join(names)})" + ) + ) + + return normalized_groups diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py new file mode 100644 index 00000000000..4090e3d8fd0 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py @@ -0,0 +1,349 @@ +from __future__ import annotations + +import dataclasses +import re +import urllib.parse +from collections.abc import Mapping +from typing import TYPE_CHECKING, Any, Protocol, TypeVar + +if TYPE_CHECKING: # pragma: no cover + import sys + from collections.abc import Collection + from urllib.parse import SplitResult + + if sys.version_info >= (3, 11): + from typing import Self + else: + from opentelemetry.agent._vendor.typing_extensions import Self + +__all__ = [ + "ArchiveInfo", + "DirInfo", + "DirectUrl", + "DirectUrlValidationError", + "VcsInfo", +] + + +def __dir__() -> list[str]: + return __all__ + + +_T = TypeVar("_T") + + +class _FromMappingProtocol(Protocol): # pragma: no cover + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: ... + + +_FromMappingProtocolT = TypeVar("_FromMappingProtocolT", bound=_FromMappingProtocol) + + +def _json_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]: + return {key: value for key, value in data if value is not None} + + +def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None: + """Get a value from the dictionary and verify it's the expected type.""" + if (value := d.get(key)) is None: + return None + if not isinstance(value, expected_type): + raise DirectUrlValidationError( + f"Unexpected type {type(value).__name__} " + f"(expected {expected_type.__name__})", + context=key, + ) + return value + + +def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T: + """Get a required value from the dictionary and verify it's the expected type.""" + if (value := _get(d, expected_type, key)) is None: + raise _DirectUrlRequiredKeyError(key) + return value + + +def _get_object( + d: Mapping[str, Any], target_type: type[_FromMappingProtocolT], key: str +) -> _FromMappingProtocolT | None: + """Get a dictionary value from the dictionary and convert it to a dataclass.""" + if (value := _get(d, Mapping, key)) is None: # type: ignore[type-abstract] + return None + try: + return target_type._from_dict(value) + except Exception as e: + raise DirectUrlValidationError(e, context=key) from e + + +_PEP610_USER_PASS_ENV_VARS_REGEX = re.compile( + r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$" +) + + +def _strip_auth_from_netloc(netloc: str, safe_user_passwords: Collection[str]) -> str: + if "@" not in netloc: + return netloc + user_pass, netloc_no_user_pass = netloc.rsplit("@", 1) + if user_pass in safe_user_passwords: + return netloc + if _PEP610_USER_PASS_ENV_VARS_REGEX.match(user_pass): + return netloc + return netloc_no_user_pass + + +def _strip_url(url: str, safe_user_passwords: Collection[str]) -> str: + """url with user:password part removed unless it is formed with + environment variables as specified in PEP 610, or it is a safe user:password + such as `git`. + """ + parsed_url = urllib.parse.urlsplit(url) + netloc = _strip_auth_from_netloc(parsed_url.netloc, safe_user_passwords) + return urllib.parse.urlunsplit( + ( + parsed_url.scheme, + netloc, + parsed_url.path, + parsed_url.query, + parsed_url.fragment, + ) + ) + + +def _file_url_has_absolute_path(parsed_url: SplitResult) -> bool: + return parsed_url.path.startswith("/") + + +class DirectUrlValidationError(Exception): + """Raised when when input data is not spec-compliant. + + .. versionadded:: 26.1 + """ + + context: str | None = None + message: str + + def __init__( + self, + cause: str | Exception, + *, + context: str | None = None, + ) -> None: + if isinstance(cause, DirectUrlValidationError): + if cause.context: + self.context = ( + f"{context}.{cause.context}" if context else cause.context + ) + else: + self.context = context # pragma: no cover + self.message = cause.message + else: + self.context = context + self.message = str(cause) + + def __str__(self) -> str: + if self.context: + return f"{self.message} in {self.context!r}" + return self.message + + +class _DirectUrlRequiredKeyError(DirectUrlValidationError): + def __init__(self, key: str) -> None: + super().__init__("Missing required value", context=key) + + +@dataclasses.dataclass(frozen=True, init=False) +class VcsInfo: + """The version control information of a :class:`DirectUrl`.""" + + vcs: str + commit_id: str + requested_revision: str | None = None + + def __init__( + self, + *, + vcs: str, + commit_id: str, + requested_revision: str | None = None, + ) -> None: + object.__setattr__(self, "vcs", vcs) + object.__setattr__(self, "commit_id", commit_id) + object.__setattr__(self, "requested_revision", requested_revision) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + # We can't validate vcs value because is not closed. + return cls( + vcs=_get_required(d, str, "vcs"), + requested_revision=_get(d, str, "requested_revision"), + commit_id=_get_required(d, str, "commit_id"), + ) + + +@dataclasses.dataclass(frozen=True, init=False) +class ArchiveInfo: + """The archive information of a :class:`DirectUrl`.""" + + hashes: Mapping[str, str] | None = None + + def __init__( + self, + *, + hashes: Mapping[str, str] | None = None, + ) -> None: + object.__setattr__(self, "hashes", hashes) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + hashes = _get(d, Mapping, "hashes") # type: ignore[type-abstract] + if hashes is not None and not all(isinstance(h, str) for h in hashes.values()): + raise DirectUrlValidationError( + "Hash values must be strings", context="hashes" + ) + legacy_hash = _get(d, str, "hash") + if legacy_hash is not None: + if "=" not in legacy_hash: + raise DirectUrlValidationError( + "Invalid hash format (expected '=')", + context="hash", + ) + hash_algorithm, hash_value = legacy_hash.split("=", 1) + if hashes is None: + # if `hashes` are not present, we can derive it from the legacy `hash` + hashes = {hash_algorithm: hash_value} + else: + # if `hashes` are present, the legacy `hash` must match one of them + if hash_algorithm not in hashes: + raise DirectUrlValidationError( + f"Algorithm {hash_algorithm!r} used in hash field " + f"is not present in hashes field", + context="hashes", + ) + if hashes[hash_algorithm] != hash_value: + raise DirectUrlValidationError( + f"Algorithm {hash_algorithm!r} used in hash field " + f"has different value in hashes field", + context="hash", + ) + return cls(hashes=hashes) + + +@dataclasses.dataclass(frozen=True, init=False) +class DirInfo: + """The local directory information of a :class:`DirectUrl`.""" + + editable: bool | None = None + + def __init__( + self, + *, + editable: bool | None = None, + ) -> None: + object.__setattr__(self, "editable", editable) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + return cls( + editable=_get(d, bool, "editable"), + ) + + +@dataclasses.dataclass(frozen=True, init=False) +class DirectUrl: + """A class representing a direct URL. + + .. versionadded:: 26.1 + """ + + url: str + archive_info: ArchiveInfo | None = None + vcs_info: VcsInfo | None = None + dir_info: DirInfo | None = None + subdirectory: str | None = None # XXX Path or str? + + def __init__( + self, + *, + url: str, + archive_info: ArchiveInfo | None = None, + vcs_info: VcsInfo | None = None, + dir_info: DirInfo | None = None, + subdirectory: str | None = None, + ) -> None: + object.__setattr__(self, "url", url) + object.__setattr__(self, "archive_info", archive_info) + object.__setattr__(self, "vcs_info", vcs_info) + object.__setattr__(self, "dir_info", dir_info) + object.__setattr__(self, "subdirectory", subdirectory) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + direct_url = cls( + url=_get_required(d, str, "url"), + archive_info=_get_object(d, ArchiveInfo, "archive_info"), + vcs_info=_get_object(d, VcsInfo, "vcs_info"), + dir_info=_get_object(d, DirInfo, "dir_info"), + subdirectory=_get(d, str, "subdirectory"), + ) + if ( + bool(direct_url.vcs_info) + + bool(direct_url.archive_info) + + bool(direct_url.dir_info) + ) != 1: + raise DirectUrlValidationError( + "Exactly one of vcs_info, archive_info, dir_info must be present" + ) + if direct_url.dir_info is not None: + parsed_url = urllib.parse.urlsplit(direct_url.url) + if parsed_url.scheme != "file": + raise DirectUrlValidationError( + "URL scheme must be file:// when dir_info is present", + context="url", + ) + if not _file_url_has_absolute_path(parsed_url): + raise DirectUrlValidationError( + "File URL must be absolute when dir_info is present", + context="url", + ) + # XXX subdirectory must be relative, can we, should we validate that here? + return direct_url + + @classmethod + def from_dict(cls, d: Mapping[str, Any], /) -> Self: + """Create and validate a DirectUrl instance from a JSON dictionary.""" + return cls._from_dict(d) + + def to_dict( + self, + *, + generate_legacy_hash: bool = False, + strip_user_password: bool = True, + safe_user_passwords: Collection[str] = ("git",), + ) -> Mapping[str, Any]: + """Convert the DirectUrl instance to a JSON dictionary. + + :param generate_legacy_hash: If True, include a legacy `hash` field in + `archive_info` for backward compatibility with tools that don't + support the `hashes` field. + :param strip_user_password: If True, strip user:password from the URL + unless it is formed with environment variables as specified in PEP + 610, or it is a safe user:password such as `git`. + :param safe_user_passwords: A collection of user:password strings that + should not be stripped from the URL even if `strip_user_password` is + True. + """ + res = dataclasses.asdict(self, dict_factory=_json_dict_factory) + if generate_legacy_hash and self.archive_info and self.archive_info.hashes: + hash_algorithm, hash_value = next(iter(self.archive_info.hashes.items())) + res["archive_info"]["hash"] = f"{hash_algorithm}={hash_value}" + if strip_user_password: + res["url"] = _strip_url(self.url, safe_user_passwords) + return res + + def validate(self) -> None: + """Validate the DirectUrl instance against the specification. + + Raises :class:`DirectUrlValidationError` if invalid. + """ + self.from_dict(self.to_dict()) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py new file mode 100644 index 00000000000..d1d47cf6c34 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py @@ -0,0 +1,94 @@ +from __future__ import annotations + +import contextlib +import dataclasses +import sys +import typing + +__all__ = ["ExceptionGroup"] + + +def __dir__() -> list[str]: + return __all__ + + +if sys.version_info >= (3, 11): # pragma: no cover + from builtins import ExceptionGroup +else: # pragma: no cover + + class ExceptionGroup(Exception): + """A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11. + + If :external:exc:`ExceptionGroup` is already defined by Python itself, + that version is used instead. + """ + + message: str + exceptions: list[Exception] + + def __init__(self, message: str, exceptions: list[Exception]) -> None: + self.message = message + self.exceptions = exceptions + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})" + + +@dataclasses.dataclass +class _ErrorCollector: + """ + Collect errors into ExceptionGroups. + + Used like this: + + collector = _ErrorCollector() + # Add a single exception + collector.error(ValueError("one")) + + # Supports nesting, including combining ExceptionGroups + with collector.collect(): + raise ValueError("two") + collector.finalize("Found some errors") + + Since making a collector and then calling finalize later is a common pattern, + a convenience method ``on_exit`` is provided. + """ + + errors: list[Exception] = dataclasses.field(default_factory=list, init=False) + + def finalize(self, msg: str) -> None: + """Raise a group exception if there are any errors.""" + if self.errors: + raise ExceptionGroup(msg, self.errors) + + @contextlib.contextmanager + def on_exit(self, msg: str) -> typing.Generator[_ErrorCollector, None, None]: + """ + Calls finalize if no uncollected errors were present. + + Uncollected errors are raised normally. + """ + yield self + self.finalize(msg) + + @contextlib.contextmanager + def collect(self, *err_cls: type[Exception]) -> typing.Generator[None, None, None]: + """ + Context manager to collect errors into the error list. + + Must be inside loops, as only one error can be collected at a time. + """ + error_classes = err_cls or (Exception,) + try: + yield + except ExceptionGroup as error: + self.errors.extend(error.exceptions) + except error_classes as error: + self.errors.append(error) + + def error( + self, + error: Exception, + ) -> None: + """Add an error to the list.""" + self.errors.append(error) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py new file mode 100644 index 00000000000..f95ac02e230 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py @@ -0,0 +1,198 @@ +####################################################################################### +# +# Adapted from: +# https://github.com/pypa/hatch/blob/5352e44/backend/src/hatchling/licenses/parse.py +# +# MIT License +# +# Copyright (c) 2017-present Ofek Lev +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of this +# software and associated documentation files (the "Software"), to deal in the Software +# without restriction, including without limitation the rights to use, copy, modify, +# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be included in all copies +# or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# +# With additional allowance of arbitrary `LicenseRef-` identifiers, not just +# `LicenseRef-Public-Domain` and `LicenseRef-Proprietary`. +# +####################################################################################### +from __future__ import annotations + +import re +from typing import NewType, cast + +from ._spdx import EXCEPTIONS, LICENSES + +__all__ = [ + "InvalidLicenseExpression", + "NormalizedLicenseExpression", + "canonicalize_license_expression", +] + + +# Simple __dir__ implementation since there are no public submodules +def __dir__() -> list[str]: + return __all__ + + +license_ref_allowed = re.compile("^[A-Za-z0-9.-]+$") + +NormalizedLicenseExpression = NewType("NormalizedLicenseExpression", str) +""" +A :class:`typing.NewType` of :class:`str`, representing a normalized +License-Expression. +""" + + +class InvalidLicenseExpression(ValueError): + """Raised when a license-expression string is invalid + + >>> from packaging.licenses import canonicalize_license_expression + >>> canonicalize_license_expression("invalid") + Traceback (most recent call last): + ... + packaging.licenses.InvalidLicenseExpression: Unknown license: 'invalid' + """ + + +def canonicalize_license_expression( + raw_license_expression: str, +) -> NormalizedLicenseExpression: + """ + This function takes a valid License-Expression, and returns the normalized + form of it. + + The return type is typed as :class:`NormalizedLicenseExpression`. This + allows type checkers to help require that a string has passed through this + function before use. + + :param str raw_license_expression: The License-Expression to canonicalize. + :raises InvalidLicenseExpression: If the License-Expression is invalid due to an + invalid/unknown license identifier or invalid syntax. + + .. doctest:: + + >>> from packaging.licenses import canonicalize_license_expression + >>> canonicalize_license_expression("mit") + 'MIT' + >>> canonicalize_license_expression("mit and (apache-2.0 or bsd-2-clause)") + 'MIT AND (Apache-2.0 OR BSD-2-Clause)' + >>> canonicalize_license_expression("(mit") + Traceback (most recent call last): + ... + InvalidLicenseExpression: Invalid license expression: '(mit' + >>> canonicalize_license_expression("Use-it-after-midnight") + Traceback (most recent call last): + ... + InvalidLicenseExpression: Unknown license: 'Use-it-after-midnight' + """ + if not raw_license_expression: + message = f"Invalid license expression: {raw_license_expression!r}" + raise InvalidLicenseExpression(message) + + # Pad any parentheses so tokenization can be achieved by merely splitting on + # whitespace. + license_expression = raw_license_expression.replace("(", " ( ").replace(")", " ) ") + licenseref_prefix = "LicenseRef-" + license_refs = { + ref.lower(): "LicenseRef-" + ref[len(licenseref_prefix) :] + for ref in license_expression.split() + if ref.lower().startswith(licenseref_prefix.lower()) + } + + # Normalize to lower case so we can look up licenses/exceptions + # and so boolean operators are Python-compatible. + license_expression = license_expression.lower() + + tokens = license_expression.split() + + # Rather than implementing a parenthesis/boolean logic parser, create an + # expression that Python can parse. Everything that is not involved with the + # grammar itself is replaced with the placeholder `False` and the resultant + # expression should become a valid Python expression. + python_tokens = [] + for token in tokens: + if token not in {"or", "and", "with", "(", ")"}: + python_tokens.append("False") + elif token == "with": + python_tokens.append("or") + elif ( + token == "(" + and python_tokens + and python_tokens[-1] not in {"or", "and", "("} + ) or (token == ")" and python_tokens and python_tokens[-1] == "("): + message = f"Invalid license expression: {raw_license_expression!r}" + raise InvalidLicenseExpression(message) + else: + python_tokens.append(token) + + python_expression = " ".join(python_tokens) + try: + compile(python_expression, "", "eval") + except SyntaxError: + message = f"Invalid license expression: {raw_license_expression!r}" + raise InvalidLicenseExpression(message) from None + + # Take a final pass to check for unknown licenses/exceptions. + normalized_tokens = [] + last_license_start = False + for index, token in enumerate(tokens): + if token in {"or", "and", "with", "(", ")"}: + if token == "with" and ( + not last_license_start + or index + 1 == len(tokens) + or tokens[index + 1] in {"or", "and", "with", "(", ")"} + ): + message = f"Invalid license expression: {raw_license_expression!r}" + raise InvalidLicenseExpression(message) + normalized_tokens.append(token.upper()) + last_license_start = False + continue + + if normalized_tokens and normalized_tokens[-1] == "WITH": + if token not in EXCEPTIONS: + message = f"Unknown license exception: {token!r}" + raise InvalidLicenseExpression(message) + + normalized_tokens.append(EXCEPTIONS[token]["id"]) + last_license_start = False + else: + if token.endswith("+"): + final_token = token[:-1] + suffix = "+" + else: + final_token = token + suffix = "" + + if final_token.startswith("licenseref-"): + license_ref_id = final_token[len("licenseref-") :] + if suffix or not license_ref_allowed.match(license_ref_id): + message = f"Invalid licenseref: {token!r}" + raise InvalidLicenseExpression(message) + normalized_tokens.append(license_refs[final_token]) + else: + if final_token not in LICENSES: + message = f"Unknown license: {final_token!r}" + raise InvalidLicenseExpression(message) + normalized_tokens.append(LICENSES[final_token]["id"] + suffix) + last_license_start = True + + normalized_expression = " ".join(normalized_tokens) + + return cast( + "NormalizedLicenseExpression", + normalized_expression.replace("( ", "(").replace(" )", ")"), + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py new file mode 100644 index 00000000000..a277af28220 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py @@ -0,0 +1,799 @@ + +from __future__ import annotations + +from typing import TypedDict + +class SPDXLicense(TypedDict): + id: str + deprecated: bool + +class SPDXException(TypedDict): + id: str + deprecated: bool + + +VERSION = '3.27.0' + +LICENSES: dict[str, SPDXLicense] = { + '0bsd': {'id': '0BSD', 'deprecated': False}, + '3d-slicer-1.0': {'id': '3D-Slicer-1.0', 'deprecated': False}, + 'aal': {'id': 'AAL', 'deprecated': False}, + 'abstyles': {'id': 'Abstyles', 'deprecated': False}, + 'adacore-doc': {'id': 'AdaCore-doc', 'deprecated': False}, + 'adobe-2006': {'id': 'Adobe-2006', 'deprecated': False}, + 'adobe-display-postscript': {'id': 'Adobe-Display-PostScript', 'deprecated': False}, + 'adobe-glyph': {'id': 'Adobe-Glyph', 'deprecated': False}, + 'adobe-utopia': {'id': 'Adobe-Utopia', 'deprecated': False}, + 'adsl': {'id': 'ADSL', 'deprecated': False}, + 'afl-1.1': {'id': 'AFL-1.1', 'deprecated': False}, + 'afl-1.2': {'id': 'AFL-1.2', 'deprecated': False}, + 'afl-2.0': {'id': 'AFL-2.0', 'deprecated': False}, + 'afl-2.1': {'id': 'AFL-2.1', 'deprecated': False}, + 'afl-3.0': {'id': 'AFL-3.0', 'deprecated': False}, + 'afmparse': {'id': 'Afmparse', 'deprecated': False}, + 'agpl-1.0': {'id': 'AGPL-1.0', 'deprecated': True}, + 'agpl-1.0-only': {'id': 'AGPL-1.0-only', 'deprecated': False}, + 'agpl-1.0-or-later': {'id': 'AGPL-1.0-or-later', 'deprecated': False}, + 'agpl-3.0': {'id': 'AGPL-3.0', 'deprecated': True}, + 'agpl-3.0-only': {'id': 'AGPL-3.0-only', 'deprecated': False}, + 'agpl-3.0-or-later': {'id': 'AGPL-3.0-or-later', 'deprecated': False}, + 'aladdin': {'id': 'Aladdin', 'deprecated': False}, + 'amd-newlib': {'id': 'AMD-newlib', 'deprecated': False}, + 'amdplpa': {'id': 'AMDPLPA', 'deprecated': False}, + 'aml': {'id': 'AML', 'deprecated': False}, + 'aml-glslang': {'id': 'AML-glslang', 'deprecated': False}, + 'ampas': {'id': 'AMPAS', 'deprecated': False}, + 'antlr-pd': {'id': 'ANTLR-PD', 'deprecated': False}, + 'antlr-pd-fallback': {'id': 'ANTLR-PD-fallback', 'deprecated': False}, + 'any-osi': {'id': 'any-OSI', 'deprecated': False}, + 'any-osi-perl-modules': {'id': 'any-OSI-perl-modules', 'deprecated': False}, + 'apache-1.0': {'id': 'Apache-1.0', 'deprecated': False}, + 'apache-1.1': {'id': 'Apache-1.1', 'deprecated': False}, + 'apache-2.0': {'id': 'Apache-2.0', 'deprecated': False}, + 'apafml': {'id': 'APAFML', 'deprecated': False}, + 'apl-1.0': {'id': 'APL-1.0', 'deprecated': False}, + 'app-s2p': {'id': 'App-s2p', 'deprecated': False}, + 'apsl-1.0': {'id': 'APSL-1.0', 'deprecated': False}, + 'apsl-1.1': {'id': 'APSL-1.1', 'deprecated': False}, + 'apsl-1.2': {'id': 'APSL-1.2', 'deprecated': False}, + 'apsl-2.0': {'id': 'APSL-2.0', 'deprecated': False}, + 'arphic-1999': {'id': 'Arphic-1999', 'deprecated': False}, + 'artistic-1.0': {'id': 'Artistic-1.0', 'deprecated': False}, + 'artistic-1.0-cl8': {'id': 'Artistic-1.0-cl8', 'deprecated': False}, + 'artistic-1.0-perl': {'id': 'Artistic-1.0-Perl', 'deprecated': False}, + 'artistic-2.0': {'id': 'Artistic-2.0', 'deprecated': False}, + 'artistic-dist': {'id': 'Artistic-dist', 'deprecated': False}, + 'aspell-ru': {'id': 'Aspell-RU', 'deprecated': False}, + 'aswf-digital-assets-1.0': {'id': 'ASWF-Digital-Assets-1.0', 'deprecated': False}, + 'aswf-digital-assets-1.1': {'id': 'ASWF-Digital-Assets-1.1', 'deprecated': False}, + 'baekmuk': {'id': 'Baekmuk', 'deprecated': False}, + 'bahyph': {'id': 'Bahyph', 'deprecated': False}, + 'barr': {'id': 'Barr', 'deprecated': False}, + 'bcrypt-solar-designer': {'id': 'bcrypt-Solar-Designer', 'deprecated': False}, + 'beerware': {'id': 'Beerware', 'deprecated': False}, + 'bitstream-charter': {'id': 'Bitstream-Charter', 'deprecated': False}, + 'bitstream-vera': {'id': 'Bitstream-Vera', 'deprecated': False}, + 'bittorrent-1.0': {'id': 'BitTorrent-1.0', 'deprecated': False}, + 'bittorrent-1.1': {'id': 'BitTorrent-1.1', 'deprecated': False}, + 'blessing': {'id': 'blessing', 'deprecated': False}, + 'blueoak-1.0.0': {'id': 'BlueOak-1.0.0', 'deprecated': False}, + 'boehm-gc': {'id': 'Boehm-GC', 'deprecated': False}, + 'boehm-gc-without-fee': {'id': 'Boehm-GC-without-fee', 'deprecated': False}, + 'borceux': {'id': 'Borceux', 'deprecated': False}, + 'brian-gladman-2-clause': {'id': 'Brian-Gladman-2-Clause', 'deprecated': False}, + 'brian-gladman-3-clause': {'id': 'Brian-Gladman-3-Clause', 'deprecated': False}, + 'bsd-1-clause': {'id': 'BSD-1-Clause', 'deprecated': False}, + 'bsd-2-clause': {'id': 'BSD-2-Clause', 'deprecated': False}, + 'bsd-2-clause-darwin': {'id': 'BSD-2-Clause-Darwin', 'deprecated': False}, + 'bsd-2-clause-first-lines': {'id': 'BSD-2-Clause-first-lines', 'deprecated': False}, + 'bsd-2-clause-freebsd': {'id': 'BSD-2-Clause-FreeBSD', 'deprecated': True}, + 'bsd-2-clause-netbsd': {'id': 'BSD-2-Clause-NetBSD', 'deprecated': True}, + 'bsd-2-clause-patent': {'id': 'BSD-2-Clause-Patent', 'deprecated': False}, + 'bsd-2-clause-pkgconf-disclaimer': {'id': 'BSD-2-Clause-pkgconf-disclaimer', 'deprecated': False}, + 'bsd-2-clause-views': {'id': 'BSD-2-Clause-Views', 'deprecated': False}, + 'bsd-3-clause': {'id': 'BSD-3-Clause', 'deprecated': False}, + 'bsd-3-clause-acpica': {'id': 'BSD-3-Clause-acpica', 'deprecated': False}, + 'bsd-3-clause-attribution': {'id': 'BSD-3-Clause-Attribution', 'deprecated': False}, + 'bsd-3-clause-clear': {'id': 'BSD-3-Clause-Clear', 'deprecated': False}, + 'bsd-3-clause-flex': {'id': 'BSD-3-Clause-flex', 'deprecated': False}, + 'bsd-3-clause-hp': {'id': 'BSD-3-Clause-HP', 'deprecated': False}, + 'bsd-3-clause-lbnl': {'id': 'BSD-3-Clause-LBNL', 'deprecated': False}, + 'bsd-3-clause-modification': {'id': 'BSD-3-Clause-Modification', 'deprecated': False}, + 'bsd-3-clause-no-military-license': {'id': 'BSD-3-Clause-No-Military-License', 'deprecated': False}, + 'bsd-3-clause-no-nuclear-license': {'id': 'BSD-3-Clause-No-Nuclear-License', 'deprecated': False}, + 'bsd-3-clause-no-nuclear-license-2014': {'id': 'BSD-3-Clause-No-Nuclear-License-2014', 'deprecated': False}, + 'bsd-3-clause-no-nuclear-warranty': {'id': 'BSD-3-Clause-No-Nuclear-Warranty', 'deprecated': False}, + 'bsd-3-clause-open-mpi': {'id': 'BSD-3-Clause-Open-MPI', 'deprecated': False}, + 'bsd-3-clause-sun': {'id': 'BSD-3-Clause-Sun', 'deprecated': False}, + 'bsd-4-clause': {'id': 'BSD-4-Clause', 'deprecated': False}, + 'bsd-4-clause-shortened': {'id': 'BSD-4-Clause-Shortened', 'deprecated': False}, + 'bsd-4-clause-uc': {'id': 'BSD-4-Clause-UC', 'deprecated': False}, + 'bsd-4.3reno': {'id': 'BSD-4.3RENO', 'deprecated': False}, + 'bsd-4.3tahoe': {'id': 'BSD-4.3TAHOE', 'deprecated': False}, + 'bsd-advertising-acknowledgement': {'id': 'BSD-Advertising-Acknowledgement', 'deprecated': False}, + 'bsd-attribution-hpnd-disclaimer': {'id': 'BSD-Attribution-HPND-disclaimer', 'deprecated': False}, + 'bsd-inferno-nettverk': {'id': 'BSD-Inferno-Nettverk', 'deprecated': False}, + 'bsd-protection': {'id': 'BSD-Protection', 'deprecated': False}, + 'bsd-source-beginning-file': {'id': 'BSD-Source-beginning-file', 'deprecated': False}, + 'bsd-source-code': {'id': 'BSD-Source-Code', 'deprecated': False}, + 'bsd-systemics': {'id': 'BSD-Systemics', 'deprecated': False}, + 'bsd-systemics-w3works': {'id': 'BSD-Systemics-W3Works', 'deprecated': False}, + 'bsl-1.0': {'id': 'BSL-1.0', 'deprecated': False}, + 'busl-1.1': {'id': 'BUSL-1.1', 'deprecated': False}, + 'bzip2-1.0.5': {'id': 'bzip2-1.0.5', 'deprecated': True}, + 'bzip2-1.0.6': {'id': 'bzip2-1.0.6', 'deprecated': False}, + 'c-uda-1.0': {'id': 'C-UDA-1.0', 'deprecated': False}, + 'cal-1.0': {'id': 'CAL-1.0', 'deprecated': False}, + 'cal-1.0-combined-work-exception': {'id': 'CAL-1.0-Combined-Work-Exception', 'deprecated': False}, + 'caldera': {'id': 'Caldera', 'deprecated': False}, + 'caldera-no-preamble': {'id': 'Caldera-no-preamble', 'deprecated': False}, + 'catharon': {'id': 'Catharon', 'deprecated': False}, + 'catosl-1.1': {'id': 'CATOSL-1.1', 'deprecated': False}, + 'cc-by-1.0': {'id': 'CC-BY-1.0', 'deprecated': False}, + 'cc-by-2.0': {'id': 'CC-BY-2.0', 'deprecated': False}, + 'cc-by-2.5': {'id': 'CC-BY-2.5', 'deprecated': False}, + 'cc-by-2.5-au': {'id': 'CC-BY-2.5-AU', 'deprecated': False}, + 'cc-by-3.0': {'id': 'CC-BY-3.0', 'deprecated': False}, + 'cc-by-3.0-at': {'id': 'CC-BY-3.0-AT', 'deprecated': False}, + 'cc-by-3.0-au': {'id': 'CC-BY-3.0-AU', 'deprecated': False}, + 'cc-by-3.0-de': {'id': 'CC-BY-3.0-DE', 'deprecated': False}, + 'cc-by-3.0-igo': {'id': 'CC-BY-3.0-IGO', 'deprecated': False}, + 'cc-by-3.0-nl': {'id': 'CC-BY-3.0-NL', 'deprecated': False}, + 'cc-by-3.0-us': {'id': 'CC-BY-3.0-US', 'deprecated': False}, + 'cc-by-4.0': {'id': 'CC-BY-4.0', 'deprecated': False}, + 'cc-by-nc-1.0': {'id': 'CC-BY-NC-1.0', 'deprecated': False}, + 'cc-by-nc-2.0': {'id': 'CC-BY-NC-2.0', 'deprecated': False}, + 'cc-by-nc-2.5': {'id': 'CC-BY-NC-2.5', 'deprecated': False}, + 'cc-by-nc-3.0': {'id': 'CC-BY-NC-3.0', 'deprecated': False}, + 'cc-by-nc-3.0-de': {'id': 'CC-BY-NC-3.0-DE', 'deprecated': False}, + 'cc-by-nc-4.0': {'id': 'CC-BY-NC-4.0', 'deprecated': False}, + 'cc-by-nc-nd-1.0': {'id': 'CC-BY-NC-ND-1.0', 'deprecated': False}, + 'cc-by-nc-nd-2.0': {'id': 'CC-BY-NC-ND-2.0', 'deprecated': False}, + 'cc-by-nc-nd-2.5': {'id': 'CC-BY-NC-ND-2.5', 'deprecated': False}, + 'cc-by-nc-nd-3.0': {'id': 'CC-BY-NC-ND-3.0', 'deprecated': False}, + 'cc-by-nc-nd-3.0-de': {'id': 'CC-BY-NC-ND-3.0-DE', 'deprecated': False}, + 'cc-by-nc-nd-3.0-igo': {'id': 'CC-BY-NC-ND-3.0-IGO', 'deprecated': False}, + 'cc-by-nc-nd-4.0': {'id': 'CC-BY-NC-ND-4.0', 'deprecated': False}, + 'cc-by-nc-sa-1.0': {'id': 'CC-BY-NC-SA-1.0', 'deprecated': False}, + 'cc-by-nc-sa-2.0': {'id': 'CC-BY-NC-SA-2.0', 'deprecated': False}, + 'cc-by-nc-sa-2.0-de': {'id': 'CC-BY-NC-SA-2.0-DE', 'deprecated': False}, + 'cc-by-nc-sa-2.0-fr': {'id': 'CC-BY-NC-SA-2.0-FR', 'deprecated': False}, + 'cc-by-nc-sa-2.0-uk': {'id': 'CC-BY-NC-SA-2.0-UK', 'deprecated': False}, + 'cc-by-nc-sa-2.5': {'id': 'CC-BY-NC-SA-2.5', 'deprecated': False}, + 'cc-by-nc-sa-3.0': {'id': 'CC-BY-NC-SA-3.0', 'deprecated': False}, + 'cc-by-nc-sa-3.0-de': {'id': 'CC-BY-NC-SA-3.0-DE', 'deprecated': False}, + 'cc-by-nc-sa-3.0-igo': {'id': 'CC-BY-NC-SA-3.0-IGO', 'deprecated': False}, + 'cc-by-nc-sa-4.0': {'id': 'CC-BY-NC-SA-4.0', 'deprecated': False}, + 'cc-by-nd-1.0': {'id': 'CC-BY-ND-1.0', 'deprecated': False}, + 'cc-by-nd-2.0': {'id': 'CC-BY-ND-2.0', 'deprecated': False}, + 'cc-by-nd-2.5': {'id': 'CC-BY-ND-2.5', 'deprecated': False}, + 'cc-by-nd-3.0': {'id': 'CC-BY-ND-3.0', 'deprecated': False}, + 'cc-by-nd-3.0-de': {'id': 'CC-BY-ND-3.0-DE', 'deprecated': False}, + 'cc-by-nd-4.0': {'id': 'CC-BY-ND-4.0', 'deprecated': False}, + 'cc-by-sa-1.0': {'id': 'CC-BY-SA-1.0', 'deprecated': False}, + 'cc-by-sa-2.0': {'id': 'CC-BY-SA-2.0', 'deprecated': False}, + 'cc-by-sa-2.0-uk': {'id': 'CC-BY-SA-2.0-UK', 'deprecated': False}, + 'cc-by-sa-2.1-jp': {'id': 'CC-BY-SA-2.1-JP', 'deprecated': False}, + 'cc-by-sa-2.5': {'id': 'CC-BY-SA-2.5', 'deprecated': False}, + 'cc-by-sa-3.0': {'id': 'CC-BY-SA-3.0', 'deprecated': False}, + 'cc-by-sa-3.0-at': {'id': 'CC-BY-SA-3.0-AT', 'deprecated': False}, + 'cc-by-sa-3.0-de': {'id': 'CC-BY-SA-3.0-DE', 'deprecated': False}, + 'cc-by-sa-3.0-igo': {'id': 'CC-BY-SA-3.0-IGO', 'deprecated': False}, + 'cc-by-sa-4.0': {'id': 'CC-BY-SA-4.0', 'deprecated': False}, + 'cc-pddc': {'id': 'CC-PDDC', 'deprecated': False}, + 'cc-pdm-1.0': {'id': 'CC-PDM-1.0', 'deprecated': False}, + 'cc-sa-1.0': {'id': 'CC-SA-1.0', 'deprecated': False}, + 'cc0-1.0': {'id': 'CC0-1.0', 'deprecated': False}, + 'cddl-1.0': {'id': 'CDDL-1.0', 'deprecated': False}, + 'cddl-1.1': {'id': 'CDDL-1.1', 'deprecated': False}, + 'cdl-1.0': {'id': 'CDL-1.0', 'deprecated': False}, + 'cdla-permissive-1.0': {'id': 'CDLA-Permissive-1.0', 'deprecated': False}, + 'cdla-permissive-2.0': {'id': 'CDLA-Permissive-2.0', 'deprecated': False}, + 'cdla-sharing-1.0': {'id': 'CDLA-Sharing-1.0', 'deprecated': False}, + 'cecill-1.0': {'id': 'CECILL-1.0', 'deprecated': False}, + 'cecill-1.1': {'id': 'CECILL-1.1', 'deprecated': False}, + 'cecill-2.0': {'id': 'CECILL-2.0', 'deprecated': False}, + 'cecill-2.1': {'id': 'CECILL-2.1', 'deprecated': False}, + 'cecill-b': {'id': 'CECILL-B', 'deprecated': False}, + 'cecill-c': {'id': 'CECILL-C', 'deprecated': False}, + 'cern-ohl-1.1': {'id': 'CERN-OHL-1.1', 'deprecated': False}, + 'cern-ohl-1.2': {'id': 'CERN-OHL-1.2', 'deprecated': False}, + 'cern-ohl-p-2.0': {'id': 'CERN-OHL-P-2.0', 'deprecated': False}, + 'cern-ohl-s-2.0': {'id': 'CERN-OHL-S-2.0', 'deprecated': False}, + 'cern-ohl-w-2.0': {'id': 'CERN-OHL-W-2.0', 'deprecated': False}, + 'cfitsio': {'id': 'CFITSIO', 'deprecated': False}, + 'check-cvs': {'id': 'check-cvs', 'deprecated': False}, + 'checkmk': {'id': 'checkmk', 'deprecated': False}, + 'clartistic': {'id': 'ClArtistic', 'deprecated': False}, + 'clips': {'id': 'Clips', 'deprecated': False}, + 'cmu-mach': {'id': 'CMU-Mach', 'deprecated': False}, + 'cmu-mach-nodoc': {'id': 'CMU-Mach-nodoc', 'deprecated': False}, + 'cnri-jython': {'id': 'CNRI-Jython', 'deprecated': False}, + 'cnri-python': {'id': 'CNRI-Python', 'deprecated': False}, + 'cnri-python-gpl-compatible': {'id': 'CNRI-Python-GPL-Compatible', 'deprecated': False}, + 'coil-1.0': {'id': 'COIL-1.0', 'deprecated': False}, + 'community-spec-1.0': {'id': 'Community-Spec-1.0', 'deprecated': False}, + 'condor-1.1': {'id': 'Condor-1.1', 'deprecated': False}, + 'copyleft-next-0.3.0': {'id': 'copyleft-next-0.3.0', 'deprecated': False}, + 'copyleft-next-0.3.1': {'id': 'copyleft-next-0.3.1', 'deprecated': False}, + 'cornell-lossless-jpeg': {'id': 'Cornell-Lossless-JPEG', 'deprecated': False}, + 'cpal-1.0': {'id': 'CPAL-1.0', 'deprecated': False}, + 'cpl-1.0': {'id': 'CPL-1.0', 'deprecated': False}, + 'cpol-1.02': {'id': 'CPOL-1.02', 'deprecated': False}, + 'cronyx': {'id': 'Cronyx', 'deprecated': False}, + 'crossword': {'id': 'Crossword', 'deprecated': False}, + 'cryptoswift': {'id': 'CryptoSwift', 'deprecated': False}, + 'crystalstacker': {'id': 'CrystalStacker', 'deprecated': False}, + 'cua-opl-1.0': {'id': 'CUA-OPL-1.0', 'deprecated': False}, + 'cube': {'id': 'Cube', 'deprecated': False}, + 'curl': {'id': 'curl', 'deprecated': False}, + 'cve-tou': {'id': 'cve-tou', 'deprecated': False}, + 'd-fsl-1.0': {'id': 'D-FSL-1.0', 'deprecated': False}, + 'dec-3-clause': {'id': 'DEC-3-Clause', 'deprecated': False}, + 'diffmark': {'id': 'diffmark', 'deprecated': False}, + 'dl-de-by-2.0': {'id': 'DL-DE-BY-2.0', 'deprecated': False}, + 'dl-de-zero-2.0': {'id': 'DL-DE-ZERO-2.0', 'deprecated': False}, + 'doc': {'id': 'DOC', 'deprecated': False}, + 'docbook-dtd': {'id': 'DocBook-DTD', 'deprecated': False}, + 'docbook-schema': {'id': 'DocBook-Schema', 'deprecated': False}, + 'docbook-stylesheet': {'id': 'DocBook-Stylesheet', 'deprecated': False}, + 'docbook-xml': {'id': 'DocBook-XML', 'deprecated': False}, + 'dotseqn': {'id': 'Dotseqn', 'deprecated': False}, + 'drl-1.0': {'id': 'DRL-1.0', 'deprecated': False}, + 'drl-1.1': {'id': 'DRL-1.1', 'deprecated': False}, + 'dsdp': {'id': 'DSDP', 'deprecated': False}, + 'dtoa': {'id': 'dtoa', 'deprecated': False}, + 'dvipdfm': {'id': 'dvipdfm', 'deprecated': False}, + 'ecl-1.0': {'id': 'ECL-1.0', 'deprecated': False}, + 'ecl-2.0': {'id': 'ECL-2.0', 'deprecated': False}, + 'ecos-2.0': {'id': 'eCos-2.0', 'deprecated': True}, + 'efl-1.0': {'id': 'EFL-1.0', 'deprecated': False}, + 'efl-2.0': {'id': 'EFL-2.0', 'deprecated': False}, + 'egenix': {'id': 'eGenix', 'deprecated': False}, + 'elastic-2.0': {'id': 'Elastic-2.0', 'deprecated': False}, + 'entessa': {'id': 'Entessa', 'deprecated': False}, + 'epics': {'id': 'EPICS', 'deprecated': False}, + 'epl-1.0': {'id': 'EPL-1.0', 'deprecated': False}, + 'epl-2.0': {'id': 'EPL-2.0', 'deprecated': False}, + 'erlpl-1.1': {'id': 'ErlPL-1.1', 'deprecated': False}, + 'etalab-2.0': {'id': 'etalab-2.0', 'deprecated': False}, + 'eudatagrid': {'id': 'EUDatagrid', 'deprecated': False}, + 'eupl-1.0': {'id': 'EUPL-1.0', 'deprecated': False}, + 'eupl-1.1': {'id': 'EUPL-1.1', 'deprecated': False}, + 'eupl-1.2': {'id': 'EUPL-1.2', 'deprecated': False}, + 'eurosym': {'id': 'Eurosym', 'deprecated': False}, + 'fair': {'id': 'Fair', 'deprecated': False}, + 'fbm': {'id': 'FBM', 'deprecated': False}, + 'fdk-aac': {'id': 'FDK-AAC', 'deprecated': False}, + 'ferguson-twofish': {'id': 'Ferguson-Twofish', 'deprecated': False}, + 'frameworx-1.0': {'id': 'Frameworx-1.0', 'deprecated': False}, + 'freebsd-doc': {'id': 'FreeBSD-DOC', 'deprecated': False}, + 'freeimage': {'id': 'FreeImage', 'deprecated': False}, + 'fsfap': {'id': 'FSFAP', 'deprecated': False}, + 'fsfap-no-warranty-disclaimer': {'id': 'FSFAP-no-warranty-disclaimer', 'deprecated': False}, + 'fsful': {'id': 'FSFUL', 'deprecated': False}, + 'fsfullr': {'id': 'FSFULLR', 'deprecated': False}, + 'fsfullrsd': {'id': 'FSFULLRSD', 'deprecated': False}, + 'fsfullrwd': {'id': 'FSFULLRWD', 'deprecated': False}, + 'fsl-1.1-alv2': {'id': 'FSL-1.1-ALv2', 'deprecated': False}, + 'fsl-1.1-mit': {'id': 'FSL-1.1-MIT', 'deprecated': False}, + 'ftl': {'id': 'FTL', 'deprecated': False}, + 'furuseth': {'id': 'Furuseth', 'deprecated': False}, + 'fwlw': {'id': 'fwlw', 'deprecated': False}, + 'game-programming-gems': {'id': 'Game-Programming-Gems', 'deprecated': False}, + 'gcr-docs': {'id': 'GCR-docs', 'deprecated': False}, + 'gd': {'id': 'GD', 'deprecated': False}, + 'generic-xts': {'id': 'generic-xts', 'deprecated': False}, + 'gfdl-1.1': {'id': 'GFDL-1.1', 'deprecated': True}, + 'gfdl-1.1-invariants-only': {'id': 'GFDL-1.1-invariants-only', 'deprecated': False}, + 'gfdl-1.1-invariants-or-later': {'id': 'GFDL-1.1-invariants-or-later', 'deprecated': False}, + 'gfdl-1.1-no-invariants-only': {'id': 'GFDL-1.1-no-invariants-only', 'deprecated': False}, + 'gfdl-1.1-no-invariants-or-later': {'id': 'GFDL-1.1-no-invariants-or-later', 'deprecated': False}, + 'gfdl-1.1-only': {'id': 'GFDL-1.1-only', 'deprecated': False}, + 'gfdl-1.1-or-later': {'id': 'GFDL-1.1-or-later', 'deprecated': False}, + 'gfdl-1.2': {'id': 'GFDL-1.2', 'deprecated': True}, + 'gfdl-1.2-invariants-only': {'id': 'GFDL-1.2-invariants-only', 'deprecated': False}, + 'gfdl-1.2-invariants-or-later': {'id': 'GFDL-1.2-invariants-or-later', 'deprecated': False}, + 'gfdl-1.2-no-invariants-only': {'id': 'GFDL-1.2-no-invariants-only', 'deprecated': False}, + 'gfdl-1.2-no-invariants-or-later': {'id': 'GFDL-1.2-no-invariants-or-later', 'deprecated': False}, + 'gfdl-1.2-only': {'id': 'GFDL-1.2-only', 'deprecated': False}, + 'gfdl-1.2-or-later': {'id': 'GFDL-1.2-or-later', 'deprecated': False}, + 'gfdl-1.3': {'id': 'GFDL-1.3', 'deprecated': True}, + 'gfdl-1.3-invariants-only': {'id': 'GFDL-1.3-invariants-only', 'deprecated': False}, + 'gfdl-1.3-invariants-or-later': {'id': 'GFDL-1.3-invariants-or-later', 'deprecated': False}, + 'gfdl-1.3-no-invariants-only': {'id': 'GFDL-1.3-no-invariants-only', 'deprecated': False}, + 'gfdl-1.3-no-invariants-or-later': {'id': 'GFDL-1.3-no-invariants-or-later', 'deprecated': False}, + 'gfdl-1.3-only': {'id': 'GFDL-1.3-only', 'deprecated': False}, + 'gfdl-1.3-or-later': {'id': 'GFDL-1.3-or-later', 'deprecated': False}, + 'giftware': {'id': 'Giftware', 'deprecated': False}, + 'gl2ps': {'id': 'GL2PS', 'deprecated': False}, + 'glide': {'id': 'Glide', 'deprecated': False}, + 'glulxe': {'id': 'Glulxe', 'deprecated': False}, + 'glwtpl': {'id': 'GLWTPL', 'deprecated': False}, + 'gnuplot': {'id': 'gnuplot', 'deprecated': False}, + 'gpl-1.0': {'id': 'GPL-1.0', 'deprecated': True}, + 'gpl-1.0+': {'id': 'GPL-1.0+', 'deprecated': True}, + 'gpl-1.0-only': {'id': 'GPL-1.0-only', 'deprecated': False}, + 'gpl-1.0-or-later': {'id': 'GPL-1.0-or-later', 'deprecated': False}, + 'gpl-2.0': {'id': 'GPL-2.0', 'deprecated': True}, + 'gpl-2.0+': {'id': 'GPL-2.0+', 'deprecated': True}, + 'gpl-2.0-only': {'id': 'GPL-2.0-only', 'deprecated': False}, + 'gpl-2.0-or-later': {'id': 'GPL-2.0-or-later', 'deprecated': False}, + 'gpl-2.0-with-autoconf-exception': {'id': 'GPL-2.0-with-autoconf-exception', 'deprecated': True}, + 'gpl-2.0-with-bison-exception': {'id': 'GPL-2.0-with-bison-exception', 'deprecated': True}, + 'gpl-2.0-with-classpath-exception': {'id': 'GPL-2.0-with-classpath-exception', 'deprecated': True}, + 'gpl-2.0-with-font-exception': {'id': 'GPL-2.0-with-font-exception', 'deprecated': True}, + 'gpl-2.0-with-gcc-exception': {'id': 'GPL-2.0-with-GCC-exception', 'deprecated': True}, + 'gpl-3.0': {'id': 'GPL-3.0', 'deprecated': True}, + 'gpl-3.0+': {'id': 'GPL-3.0+', 'deprecated': True}, + 'gpl-3.0-only': {'id': 'GPL-3.0-only', 'deprecated': False}, + 'gpl-3.0-or-later': {'id': 'GPL-3.0-or-later', 'deprecated': False}, + 'gpl-3.0-with-autoconf-exception': {'id': 'GPL-3.0-with-autoconf-exception', 'deprecated': True}, + 'gpl-3.0-with-gcc-exception': {'id': 'GPL-3.0-with-GCC-exception', 'deprecated': True}, + 'graphics-gems': {'id': 'Graphics-Gems', 'deprecated': False}, + 'gsoap-1.3b': {'id': 'gSOAP-1.3b', 'deprecated': False}, + 'gtkbook': {'id': 'gtkbook', 'deprecated': False}, + 'gutmann': {'id': 'Gutmann', 'deprecated': False}, + 'haskellreport': {'id': 'HaskellReport', 'deprecated': False}, + 'hdf5': {'id': 'HDF5', 'deprecated': False}, + 'hdparm': {'id': 'hdparm', 'deprecated': False}, + 'hidapi': {'id': 'HIDAPI', 'deprecated': False}, + 'hippocratic-2.1': {'id': 'Hippocratic-2.1', 'deprecated': False}, + 'hp-1986': {'id': 'HP-1986', 'deprecated': False}, + 'hp-1989': {'id': 'HP-1989', 'deprecated': False}, + 'hpnd': {'id': 'HPND', 'deprecated': False}, + 'hpnd-dec': {'id': 'HPND-DEC', 'deprecated': False}, + 'hpnd-doc': {'id': 'HPND-doc', 'deprecated': False}, + 'hpnd-doc-sell': {'id': 'HPND-doc-sell', 'deprecated': False}, + 'hpnd-export-us': {'id': 'HPND-export-US', 'deprecated': False}, + 'hpnd-export-us-acknowledgement': {'id': 'HPND-export-US-acknowledgement', 'deprecated': False}, + 'hpnd-export-us-modify': {'id': 'HPND-export-US-modify', 'deprecated': False}, + 'hpnd-export2-us': {'id': 'HPND-export2-US', 'deprecated': False}, + 'hpnd-fenneberg-livingston': {'id': 'HPND-Fenneberg-Livingston', 'deprecated': False}, + 'hpnd-inria-imag': {'id': 'HPND-INRIA-IMAG', 'deprecated': False}, + 'hpnd-intel': {'id': 'HPND-Intel', 'deprecated': False}, + 'hpnd-kevlin-henney': {'id': 'HPND-Kevlin-Henney', 'deprecated': False}, + 'hpnd-markus-kuhn': {'id': 'HPND-Markus-Kuhn', 'deprecated': False}, + 'hpnd-merchantability-variant': {'id': 'HPND-merchantability-variant', 'deprecated': False}, + 'hpnd-mit-disclaimer': {'id': 'HPND-MIT-disclaimer', 'deprecated': False}, + 'hpnd-netrek': {'id': 'HPND-Netrek', 'deprecated': False}, + 'hpnd-pbmplus': {'id': 'HPND-Pbmplus', 'deprecated': False}, + 'hpnd-sell-mit-disclaimer-xserver': {'id': 'HPND-sell-MIT-disclaimer-xserver', 'deprecated': False}, + 'hpnd-sell-regexpr': {'id': 'HPND-sell-regexpr', 'deprecated': False}, + 'hpnd-sell-variant': {'id': 'HPND-sell-variant', 'deprecated': False}, + 'hpnd-sell-variant-mit-disclaimer': {'id': 'HPND-sell-variant-MIT-disclaimer', 'deprecated': False}, + 'hpnd-sell-variant-mit-disclaimer-rev': {'id': 'HPND-sell-variant-MIT-disclaimer-rev', 'deprecated': False}, + 'hpnd-uc': {'id': 'HPND-UC', 'deprecated': False}, + 'hpnd-uc-export-us': {'id': 'HPND-UC-export-US', 'deprecated': False}, + 'htmltidy': {'id': 'HTMLTIDY', 'deprecated': False}, + 'ibm-pibs': {'id': 'IBM-pibs', 'deprecated': False}, + 'icu': {'id': 'ICU', 'deprecated': False}, + 'iec-code-components-eula': {'id': 'IEC-Code-Components-EULA', 'deprecated': False}, + 'ijg': {'id': 'IJG', 'deprecated': False}, + 'ijg-short': {'id': 'IJG-short', 'deprecated': False}, + 'imagemagick': {'id': 'ImageMagick', 'deprecated': False}, + 'imatix': {'id': 'iMatix', 'deprecated': False}, + 'imlib2': {'id': 'Imlib2', 'deprecated': False}, + 'info-zip': {'id': 'Info-ZIP', 'deprecated': False}, + 'inner-net-2.0': {'id': 'Inner-Net-2.0', 'deprecated': False}, + 'innosetup': {'id': 'InnoSetup', 'deprecated': False}, + 'intel': {'id': 'Intel', 'deprecated': False}, + 'intel-acpi': {'id': 'Intel-ACPI', 'deprecated': False}, + 'interbase-1.0': {'id': 'Interbase-1.0', 'deprecated': False}, + 'ipa': {'id': 'IPA', 'deprecated': False}, + 'ipl-1.0': {'id': 'IPL-1.0', 'deprecated': False}, + 'isc': {'id': 'ISC', 'deprecated': False}, + 'isc-veillard': {'id': 'ISC-Veillard', 'deprecated': False}, + 'jam': {'id': 'Jam', 'deprecated': False}, + 'jasper-2.0': {'id': 'JasPer-2.0', 'deprecated': False}, + 'jove': {'id': 'jove', 'deprecated': False}, + 'jpl-image': {'id': 'JPL-image', 'deprecated': False}, + 'jpnic': {'id': 'JPNIC', 'deprecated': False}, + 'json': {'id': 'JSON', 'deprecated': False}, + 'kastrup': {'id': 'Kastrup', 'deprecated': False}, + 'kazlib': {'id': 'Kazlib', 'deprecated': False}, + 'knuth-ctan': {'id': 'Knuth-CTAN', 'deprecated': False}, + 'lal-1.2': {'id': 'LAL-1.2', 'deprecated': False}, + 'lal-1.3': {'id': 'LAL-1.3', 'deprecated': False}, + 'latex2e': {'id': 'Latex2e', 'deprecated': False}, + 'latex2e-translated-notice': {'id': 'Latex2e-translated-notice', 'deprecated': False}, + 'leptonica': {'id': 'Leptonica', 'deprecated': False}, + 'lgpl-2.0': {'id': 'LGPL-2.0', 'deprecated': True}, + 'lgpl-2.0+': {'id': 'LGPL-2.0+', 'deprecated': True}, + 'lgpl-2.0-only': {'id': 'LGPL-2.0-only', 'deprecated': False}, + 'lgpl-2.0-or-later': {'id': 'LGPL-2.0-or-later', 'deprecated': False}, + 'lgpl-2.1': {'id': 'LGPL-2.1', 'deprecated': True}, + 'lgpl-2.1+': {'id': 'LGPL-2.1+', 'deprecated': True}, + 'lgpl-2.1-only': {'id': 'LGPL-2.1-only', 'deprecated': False}, + 'lgpl-2.1-or-later': {'id': 'LGPL-2.1-or-later', 'deprecated': False}, + 'lgpl-3.0': {'id': 'LGPL-3.0', 'deprecated': True}, + 'lgpl-3.0+': {'id': 'LGPL-3.0+', 'deprecated': True}, + 'lgpl-3.0-only': {'id': 'LGPL-3.0-only', 'deprecated': False}, + 'lgpl-3.0-or-later': {'id': 'LGPL-3.0-or-later', 'deprecated': False}, + 'lgpllr': {'id': 'LGPLLR', 'deprecated': False}, + 'libpng': {'id': 'Libpng', 'deprecated': False}, + 'libpng-1.6.35': {'id': 'libpng-1.6.35', 'deprecated': False}, + 'libpng-2.0': {'id': 'libpng-2.0', 'deprecated': False}, + 'libselinux-1.0': {'id': 'libselinux-1.0', 'deprecated': False}, + 'libtiff': {'id': 'libtiff', 'deprecated': False}, + 'libutil-david-nugent': {'id': 'libutil-David-Nugent', 'deprecated': False}, + 'liliq-p-1.1': {'id': 'LiLiQ-P-1.1', 'deprecated': False}, + 'liliq-r-1.1': {'id': 'LiLiQ-R-1.1', 'deprecated': False}, + 'liliq-rplus-1.1': {'id': 'LiLiQ-Rplus-1.1', 'deprecated': False}, + 'linux-man-pages-1-para': {'id': 'Linux-man-pages-1-para', 'deprecated': False}, + 'linux-man-pages-copyleft': {'id': 'Linux-man-pages-copyleft', 'deprecated': False}, + 'linux-man-pages-copyleft-2-para': {'id': 'Linux-man-pages-copyleft-2-para', 'deprecated': False}, + 'linux-man-pages-copyleft-var': {'id': 'Linux-man-pages-copyleft-var', 'deprecated': False}, + 'linux-openib': {'id': 'Linux-OpenIB', 'deprecated': False}, + 'loop': {'id': 'LOOP', 'deprecated': False}, + 'lpd-document': {'id': 'LPD-document', 'deprecated': False}, + 'lpl-1.0': {'id': 'LPL-1.0', 'deprecated': False}, + 'lpl-1.02': {'id': 'LPL-1.02', 'deprecated': False}, + 'lppl-1.0': {'id': 'LPPL-1.0', 'deprecated': False}, + 'lppl-1.1': {'id': 'LPPL-1.1', 'deprecated': False}, + 'lppl-1.2': {'id': 'LPPL-1.2', 'deprecated': False}, + 'lppl-1.3a': {'id': 'LPPL-1.3a', 'deprecated': False}, + 'lppl-1.3c': {'id': 'LPPL-1.3c', 'deprecated': False}, + 'lsof': {'id': 'lsof', 'deprecated': False}, + 'lucida-bitmap-fonts': {'id': 'Lucida-Bitmap-Fonts', 'deprecated': False}, + 'lzma-sdk-9.11-to-9.20': {'id': 'LZMA-SDK-9.11-to-9.20', 'deprecated': False}, + 'lzma-sdk-9.22': {'id': 'LZMA-SDK-9.22', 'deprecated': False}, + 'mackerras-3-clause': {'id': 'Mackerras-3-Clause', 'deprecated': False}, + 'mackerras-3-clause-acknowledgment': {'id': 'Mackerras-3-Clause-acknowledgment', 'deprecated': False}, + 'magaz': {'id': 'magaz', 'deprecated': False}, + 'mailprio': {'id': 'mailprio', 'deprecated': False}, + 'makeindex': {'id': 'MakeIndex', 'deprecated': False}, + 'man2html': {'id': 'man2html', 'deprecated': False}, + 'martin-birgmeier': {'id': 'Martin-Birgmeier', 'deprecated': False}, + 'mcphee-slideshow': {'id': 'McPhee-slideshow', 'deprecated': False}, + 'metamail': {'id': 'metamail', 'deprecated': False}, + 'minpack': {'id': 'Minpack', 'deprecated': False}, + 'mips': {'id': 'MIPS', 'deprecated': False}, + 'miros': {'id': 'MirOS', 'deprecated': False}, + 'mit': {'id': 'MIT', 'deprecated': False}, + 'mit-0': {'id': 'MIT-0', 'deprecated': False}, + 'mit-advertising': {'id': 'MIT-advertising', 'deprecated': False}, + 'mit-click': {'id': 'MIT-Click', 'deprecated': False}, + 'mit-cmu': {'id': 'MIT-CMU', 'deprecated': False}, + 'mit-enna': {'id': 'MIT-enna', 'deprecated': False}, + 'mit-feh': {'id': 'MIT-feh', 'deprecated': False}, + 'mit-festival': {'id': 'MIT-Festival', 'deprecated': False}, + 'mit-khronos-old': {'id': 'MIT-Khronos-old', 'deprecated': False}, + 'mit-modern-variant': {'id': 'MIT-Modern-Variant', 'deprecated': False}, + 'mit-open-group': {'id': 'MIT-open-group', 'deprecated': False}, + 'mit-testregex': {'id': 'MIT-testregex', 'deprecated': False}, + 'mit-wu': {'id': 'MIT-Wu', 'deprecated': False}, + 'mitnfa': {'id': 'MITNFA', 'deprecated': False}, + 'mmixware': {'id': 'MMIXware', 'deprecated': False}, + 'motosoto': {'id': 'Motosoto', 'deprecated': False}, + 'mpeg-ssg': {'id': 'MPEG-SSG', 'deprecated': False}, + 'mpi-permissive': {'id': 'mpi-permissive', 'deprecated': False}, + 'mpich2': {'id': 'mpich2', 'deprecated': False}, + 'mpl-1.0': {'id': 'MPL-1.0', 'deprecated': False}, + 'mpl-1.1': {'id': 'MPL-1.1', 'deprecated': False}, + 'mpl-2.0': {'id': 'MPL-2.0', 'deprecated': False}, + 'mpl-2.0-no-copyleft-exception': {'id': 'MPL-2.0-no-copyleft-exception', 'deprecated': False}, + 'mplus': {'id': 'mplus', 'deprecated': False}, + 'ms-lpl': {'id': 'MS-LPL', 'deprecated': False}, + 'ms-pl': {'id': 'MS-PL', 'deprecated': False}, + 'ms-rl': {'id': 'MS-RL', 'deprecated': False}, + 'mtll': {'id': 'MTLL', 'deprecated': False}, + 'mulanpsl-1.0': {'id': 'MulanPSL-1.0', 'deprecated': False}, + 'mulanpsl-2.0': {'id': 'MulanPSL-2.0', 'deprecated': False}, + 'multics': {'id': 'Multics', 'deprecated': False}, + 'mup': {'id': 'Mup', 'deprecated': False}, + 'naist-2003': {'id': 'NAIST-2003', 'deprecated': False}, + 'nasa-1.3': {'id': 'NASA-1.3', 'deprecated': False}, + 'naumen': {'id': 'Naumen', 'deprecated': False}, + 'nbpl-1.0': {'id': 'NBPL-1.0', 'deprecated': False}, + 'ncbi-pd': {'id': 'NCBI-PD', 'deprecated': False}, + 'ncgl-uk-2.0': {'id': 'NCGL-UK-2.0', 'deprecated': False}, + 'ncl': {'id': 'NCL', 'deprecated': False}, + 'ncsa': {'id': 'NCSA', 'deprecated': False}, + 'net-snmp': {'id': 'Net-SNMP', 'deprecated': True}, + 'netcdf': {'id': 'NetCDF', 'deprecated': False}, + 'newsletr': {'id': 'Newsletr', 'deprecated': False}, + 'ngpl': {'id': 'NGPL', 'deprecated': False}, + 'ngrep': {'id': 'ngrep', 'deprecated': False}, + 'nicta-1.0': {'id': 'NICTA-1.0', 'deprecated': False}, + 'nist-pd': {'id': 'NIST-PD', 'deprecated': False}, + 'nist-pd-fallback': {'id': 'NIST-PD-fallback', 'deprecated': False}, + 'nist-software': {'id': 'NIST-Software', 'deprecated': False}, + 'nlod-1.0': {'id': 'NLOD-1.0', 'deprecated': False}, + 'nlod-2.0': {'id': 'NLOD-2.0', 'deprecated': False}, + 'nlpl': {'id': 'NLPL', 'deprecated': False}, + 'nokia': {'id': 'Nokia', 'deprecated': False}, + 'nosl': {'id': 'NOSL', 'deprecated': False}, + 'noweb': {'id': 'Noweb', 'deprecated': False}, + 'npl-1.0': {'id': 'NPL-1.0', 'deprecated': False}, + 'npl-1.1': {'id': 'NPL-1.1', 'deprecated': False}, + 'nposl-3.0': {'id': 'NPOSL-3.0', 'deprecated': False}, + 'nrl': {'id': 'NRL', 'deprecated': False}, + 'ntia-pd': {'id': 'NTIA-PD', 'deprecated': False}, + 'ntp': {'id': 'NTP', 'deprecated': False}, + 'ntp-0': {'id': 'NTP-0', 'deprecated': False}, + 'nunit': {'id': 'Nunit', 'deprecated': True}, + 'o-uda-1.0': {'id': 'O-UDA-1.0', 'deprecated': False}, + 'oar': {'id': 'OAR', 'deprecated': False}, + 'occt-pl': {'id': 'OCCT-PL', 'deprecated': False}, + 'oclc-2.0': {'id': 'OCLC-2.0', 'deprecated': False}, + 'odbl-1.0': {'id': 'ODbL-1.0', 'deprecated': False}, + 'odc-by-1.0': {'id': 'ODC-By-1.0', 'deprecated': False}, + 'offis': {'id': 'OFFIS', 'deprecated': False}, + 'ofl-1.0': {'id': 'OFL-1.0', 'deprecated': False}, + 'ofl-1.0-no-rfn': {'id': 'OFL-1.0-no-RFN', 'deprecated': False}, + 'ofl-1.0-rfn': {'id': 'OFL-1.0-RFN', 'deprecated': False}, + 'ofl-1.1': {'id': 'OFL-1.1', 'deprecated': False}, + 'ofl-1.1-no-rfn': {'id': 'OFL-1.1-no-RFN', 'deprecated': False}, + 'ofl-1.1-rfn': {'id': 'OFL-1.1-RFN', 'deprecated': False}, + 'ogc-1.0': {'id': 'OGC-1.0', 'deprecated': False}, + 'ogdl-taiwan-1.0': {'id': 'OGDL-Taiwan-1.0', 'deprecated': False}, + 'ogl-canada-2.0': {'id': 'OGL-Canada-2.0', 'deprecated': False}, + 'ogl-uk-1.0': {'id': 'OGL-UK-1.0', 'deprecated': False}, + 'ogl-uk-2.0': {'id': 'OGL-UK-2.0', 'deprecated': False}, + 'ogl-uk-3.0': {'id': 'OGL-UK-3.0', 'deprecated': False}, + 'ogtsl': {'id': 'OGTSL', 'deprecated': False}, + 'oldap-1.1': {'id': 'OLDAP-1.1', 'deprecated': False}, + 'oldap-1.2': {'id': 'OLDAP-1.2', 'deprecated': False}, + 'oldap-1.3': {'id': 'OLDAP-1.3', 'deprecated': False}, + 'oldap-1.4': {'id': 'OLDAP-1.4', 'deprecated': False}, + 'oldap-2.0': {'id': 'OLDAP-2.0', 'deprecated': False}, + 'oldap-2.0.1': {'id': 'OLDAP-2.0.1', 'deprecated': False}, + 'oldap-2.1': {'id': 'OLDAP-2.1', 'deprecated': False}, + 'oldap-2.2': {'id': 'OLDAP-2.2', 'deprecated': False}, + 'oldap-2.2.1': {'id': 'OLDAP-2.2.1', 'deprecated': False}, + 'oldap-2.2.2': {'id': 'OLDAP-2.2.2', 'deprecated': False}, + 'oldap-2.3': {'id': 'OLDAP-2.3', 'deprecated': False}, + 'oldap-2.4': {'id': 'OLDAP-2.4', 'deprecated': False}, + 'oldap-2.5': {'id': 'OLDAP-2.5', 'deprecated': False}, + 'oldap-2.6': {'id': 'OLDAP-2.6', 'deprecated': False}, + 'oldap-2.7': {'id': 'OLDAP-2.7', 'deprecated': False}, + 'oldap-2.8': {'id': 'OLDAP-2.8', 'deprecated': False}, + 'olfl-1.3': {'id': 'OLFL-1.3', 'deprecated': False}, + 'oml': {'id': 'OML', 'deprecated': False}, + 'openpbs-2.3': {'id': 'OpenPBS-2.3', 'deprecated': False}, + 'openssl': {'id': 'OpenSSL', 'deprecated': False}, + 'openssl-standalone': {'id': 'OpenSSL-standalone', 'deprecated': False}, + 'openvision': {'id': 'OpenVision', 'deprecated': False}, + 'opl-1.0': {'id': 'OPL-1.0', 'deprecated': False}, + 'opl-uk-3.0': {'id': 'OPL-UK-3.0', 'deprecated': False}, + 'opubl-1.0': {'id': 'OPUBL-1.0', 'deprecated': False}, + 'oset-pl-2.1': {'id': 'OSET-PL-2.1', 'deprecated': False}, + 'osl-1.0': {'id': 'OSL-1.0', 'deprecated': False}, + 'osl-1.1': {'id': 'OSL-1.1', 'deprecated': False}, + 'osl-2.0': {'id': 'OSL-2.0', 'deprecated': False}, + 'osl-2.1': {'id': 'OSL-2.1', 'deprecated': False}, + 'osl-3.0': {'id': 'OSL-3.0', 'deprecated': False}, + 'padl': {'id': 'PADL', 'deprecated': False}, + 'parity-6.0.0': {'id': 'Parity-6.0.0', 'deprecated': False}, + 'parity-7.0.0': {'id': 'Parity-7.0.0', 'deprecated': False}, + 'pddl-1.0': {'id': 'PDDL-1.0', 'deprecated': False}, + 'php-3.0': {'id': 'PHP-3.0', 'deprecated': False}, + 'php-3.01': {'id': 'PHP-3.01', 'deprecated': False}, + 'pixar': {'id': 'Pixar', 'deprecated': False}, + 'pkgconf': {'id': 'pkgconf', 'deprecated': False}, + 'plexus': {'id': 'Plexus', 'deprecated': False}, + 'pnmstitch': {'id': 'pnmstitch', 'deprecated': False}, + 'polyform-noncommercial-1.0.0': {'id': 'PolyForm-Noncommercial-1.0.0', 'deprecated': False}, + 'polyform-small-business-1.0.0': {'id': 'PolyForm-Small-Business-1.0.0', 'deprecated': False}, + 'postgresql': {'id': 'PostgreSQL', 'deprecated': False}, + 'ppl': {'id': 'PPL', 'deprecated': False}, + 'psf-2.0': {'id': 'PSF-2.0', 'deprecated': False}, + 'psfrag': {'id': 'psfrag', 'deprecated': False}, + 'psutils': {'id': 'psutils', 'deprecated': False}, + 'python-2.0': {'id': 'Python-2.0', 'deprecated': False}, + 'python-2.0.1': {'id': 'Python-2.0.1', 'deprecated': False}, + 'python-ldap': {'id': 'python-ldap', 'deprecated': False}, + 'qhull': {'id': 'Qhull', 'deprecated': False}, + 'qpl-1.0': {'id': 'QPL-1.0', 'deprecated': False}, + 'qpl-1.0-inria-2004': {'id': 'QPL-1.0-INRIA-2004', 'deprecated': False}, + 'radvd': {'id': 'radvd', 'deprecated': False}, + 'rdisc': {'id': 'Rdisc', 'deprecated': False}, + 'rhecos-1.1': {'id': 'RHeCos-1.1', 'deprecated': False}, + 'rpl-1.1': {'id': 'RPL-1.1', 'deprecated': False}, + 'rpl-1.5': {'id': 'RPL-1.5', 'deprecated': False}, + 'rpsl-1.0': {'id': 'RPSL-1.0', 'deprecated': False}, + 'rsa-md': {'id': 'RSA-MD', 'deprecated': False}, + 'rscpl': {'id': 'RSCPL', 'deprecated': False}, + 'ruby': {'id': 'Ruby', 'deprecated': False}, + 'ruby-pty': {'id': 'Ruby-pty', 'deprecated': False}, + 'sax-pd': {'id': 'SAX-PD', 'deprecated': False}, + 'sax-pd-2.0': {'id': 'SAX-PD-2.0', 'deprecated': False}, + 'saxpath': {'id': 'Saxpath', 'deprecated': False}, + 'scea': {'id': 'SCEA', 'deprecated': False}, + 'schemereport': {'id': 'SchemeReport', 'deprecated': False}, + 'sendmail': {'id': 'Sendmail', 'deprecated': False}, + 'sendmail-8.23': {'id': 'Sendmail-8.23', 'deprecated': False}, + 'sendmail-open-source-1.1': {'id': 'Sendmail-Open-Source-1.1', 'deprecated': False}, + 'sgi-b-1.0': {'id': 'SGI-B-1.0', 'deprecated': False}, + 'sgi-b-1.1': {'id': 'SGI-B-1.1', 'deprecated': False}, + 'sgi-b-2.0': {'id': 'SGI-B-2.0', 'deprecated': False}, + 'sgi-opengl': {'id': 'SGI-OpenGL', 'deprecated': False}, + 'sgp4': {'id': 'SGP4', 'deprecated': False}, + 'shl-0.5': {'id': 'SHL-0.5', 'deprecated': False}, + 'shl-0.51': {'id': 'SHL-0.51', 'deprecated': False}, + 'simpl-2.0': {'id': 'SimPL-2.0', 'deprecated': False}, + 'sissl': {'id': 'SISSL', 'deprecated': False}, + 'sissl-1.2': {'id': 'SISSL-1.2', 'deprecated': False}, + 'sl': {'id': 'SL', 'deprecated': False}, + 'sleepycat': {'id': 'Sleepycat', 'deprecated': False}, + 'smail-gpl': {'id': 'SMAIL-GPL', 'deprecated': False}, + 'smlnj': {'id': 'SMLNJ', 'deprecated': False}, + 'smppl': {'id': 'SMPPL', 'deprecated': False}, + 'snia': {'id': 'SNIA', 'deprecated': False}, + 'snprintf': {'id': 'snprintf', 'deprecated': False}, + 'sofa': {'id': 'SOFA', 'deprecated': False}, + 'softsurfer': {'id': 'softSurfer', 'deprecated': False}, + 'soundex': {'id': 'Soundex', 'deprecated': False}, + 'spencer-86': {'id': 'Spencer-86', 'deprecated': False}, + 'spencer-94': {'id': 'Spencer-94', 'deprecated': False}, + 'spencer-99': {'id': 'Spencer-99', 'deprecated': False}, + 'spl-1.0': {'id': 'SPL-1.0', 'deprecated': False}, + 'ssh-keyscan': {'id': 'ssh-keyscan', 'deprecated': False}, + 'ssh-openssh': {'id': 'SSH-OpenSSH', 'deprecated': False}, + 'ssh-short': {'id': 'SSH-short', 'deprecated': False}, + 'ssleay-standalone': {'id': 'SSLeay-standalone', 'deprecated': False}, + 'sspl-1.0': {'id': 'SSPL-1.0', 'deprecated': False}, + 'standardml-nj': {'id': 'StandardML-NJ', 'deprecated': True}, + 'sugarcrm-1.1.3': {'id': 'SugarCRM-1.1.3', 'deprecated': False}, + 'sul-1.0': {'id': 'SUL-1.0', 'deprecated': False}, + 'sun-ppp': {'id': 'Sun-PPP', 'deprecated': False}, + 'sun-ppp-2000': {'id': 'Sun-PPP-2000', 'deprecated': False}, + 'sunpro': {'id': 'SunPro', 'deprecated': False}, + 'swl': {'id': 'SWL', 'deprecated': False}, + 'swrule': {'id': 'swrule', 'deprecated': False}, + 'symlinks': {'id': 'Symlinks', 'deprecated': False}, + 'tapr-ohl-1.0': {'id': 'TAPR-OHL-1.0', 'deprecated': False}, + 'tcl': {'id': 'TCL', 'deprecated': False}, + 'tcp-wrappers': {'id': 'TCP-wrappers', 'deprecated': False}, + 'termreadkey': {'id': 'TermReadKey', 'deprecated': False}, + 'tgppl-1.0': {'id': 'TGPPL-1.0', 'deprecated': False}, + 'thirdeye': {'id': 'ThirdEye', 'deprecated': False}, + 'threeparttable': {'id': 'threeparttable', 'deprecated': False}, + 'tmate': {'id': 'TMate', 'deprecated': False}, + 'torque-1.1': {'id': 'TORQUE-1.1', 'deprecated': False}, + 'tosl': {'id': 'TOSL', 'deprecated': False}, + 'tpdl': {'id': 'TPDL', 'deprecated': False}, + 'tpl-1.0': {'id': 'TPL-1.0', 'deprecated': False}, + 'trustedqsl': {'id': 'TrustedQSL', 'deprecated': False}, + 'ttwl': {'id': 'TTWL', 'deprecated': False}, + 'ttyp0': {'id': 'TTYP0', 'deprecated': False}, + 'tu-berlin-1.0': {'id': 'TU-Berlin-1.0', 'deprecated': False}, + 'tu-berlin-2.0': {'id': 'TU-Berlin-2.0', 'deprecated': False}, + 'ubuntu-font-1.0': {'id': 'Ubuntu-font-1.0', 'deprecated': False}, + 'ucar': {'id': 'UCAR', 'deprecated': False}, + 'ucl-1.0': {'id': 'UCL-1.0', 'deprecated': False}, + 'ulem': {'id': 'ulem', 'deprecated': False}, + 'umich-merit': {'id': 'UMich-Merit', 'deprecated': False}, + 'unicode-3.0': {'id': 'Unicode-3.0', 'deprecated': False}, + 'unicode-dfs-2015': {'id': 'Unicode-DFS-2015', 'deprecated': False}, + 'unicode-dfs-2016': {'id': 'Unicode-DFS-2016', 'deprecated': False}, + 'unicode-tou': {'id': 'Unicode-TOU', 'deprecated': False}, + 'unixcrypt': {'id': 'UnixCrypt', 'deprecated': False}, + 'unlicense': {'id': 'Unlicense', 'deprecated': False}, + 'unlicense-libtelnet': {'id': 'Unlicense-libtelnet', 'deprecated': False}, + 'unlicense-libwhirlpool': {'id': 'Unlicense-libwhirlpool', 'deprecated': False}, + 'upl-1.0': {'id': 'UPL-1.0', 'deprecated': False}, + 'urt-rle': {'id': 'URT-RLE', 'deprecated': False}, + 'vim': {'id': 'Vim', 'deprecated': False}, + 'vostrom': {'id': 'VOSTROM', 'deprecated': False}, + 'vsl-1.0': {'id': 'VSL-1.0', 'deprecated': False}, + 'w3c': {'id': 'W3C', 'deprecated': False}, + 'w3c-19980720': {'id': 'W3C-19980720', 'deprecated': False}, + 'w3c-20150513': {'id': 'W3C-20150513', 'deprecated': False}, + 'w3m': {'id': 'w3m', 'deprecated': False}, + 'watcom-1.0': {'id': 'Watcom-1.0', 'deprecated': False}, + 'widget-workshop': {'id': 'Widget-Workshop', 'deprecated': False}, + 'wsuipa': {'id': 'Wsuipa', 'deprecated': False}, + 'wtfpl': {'id': 'WTFPL', 'deprecated': False}, + 'wwl': {'id': 'wwl', 'deprecated': False}, + 'wxwindows': {'id': 'wxWindows', 'deprecated': True}, + 'x11': {'id': 'X11', 'deprecated': False}, + 'x11-distribute-modifications-variant': {'id': 'X11-distribute-modifications-variant', 'deprecated': False}, + 'x11-swapped': {'id': 'X11-swapped', 'deprecated': False}, + 'xdebug-1.03': {'id': 'Xdebug-1.03', 'deprecated': False}, + 'xerox': {'id': 'Xerox', 'deprecated': False}, + 'xfig': {'id': 'Xfig', 'deprecated': False}, + 'xfree86-1.1': {'id': 'XFree86-1.1', 'deprecated': False}, + 'xinetd': {'id': 'xinetd', 'deprecated': False}, + 'xkeyboard-config-zinoviev': {'id': 'xkeyboard-config-Zinoviev', 'deprecated': False}, + 'xlock': {'id': 'xlock', 'deprecated': False}, + 'xnet': {'id': 'Xnet', 'deprecated': False}, + 'xpp': {'id': 'xpp', 'deprecated': False}, + 'xskat': {'id': 'XSkat', 'deprecated': False}, + 'xzoom': {'id': 'xzoom', 'deprecated': False}, + 'ypl-1.0': {'id': 'YPL-1.0', 'deprecated': False}, + 'ypl-1.1': {'id': 'YPL-1.1', 'deprecated': False}, + 'zed': {'id': 'Zed', 'deprecated': False}, + 'zeeff': {'id': 'Zeeff', 'deprecated': False}, + 'zend-2.0': {'id': 'Zend-2.0', 'deprecated': False}, + 'zimbra-1.3': {'id': 'Zimbra-1.3', 'deprecated': False}, + 'zimbra-1.4': {'id': 'Zimbra-1.4', 'deprecated': False}, + 'zlib': {'id': 'Zlib', 'deprecated': False}, + 'zlib-acknowledgement': {'id': 'zlib-acknowledgement', 'deprecated': False}, + 'zpl-1.1': {'id': 'ZPL-1.1', 'deprecated': False}, + 'zpl-2.0': {'id': 'ZPL-2.0', 'deprecated': False}, + 'zpl-2.1': {'id': 'ZPL-2.1', 'deprecated': False}, +} + +EXCEPTIONS: dict[str, SPDXException] = { + '389-exception': {'id': '389-exception', 'deprecated': False}, + 'asterisk-exception': {'id': 'Asterisk-exception', 'deprecated': False}, + 'asterisk-linking-protocols-exception': {'id': 'Asterisk-linking-protocols-exception', 'deprecated': False}, + 'autoconf-exception-2.0': {'id': 'Autoconf-exception-2.0', 'deprecated': False}, + 'autoconf-exception-3.0': {'id': 'Autoconf-exception-3.0', 'deprecated': False}, + 'autoconf-exception-generic': {'id': 'Autoconf-exception-generic', 'deprecated': False}, + 'autoconf-exception-generic-3.0': {'id': 'Autoconf-exception-generic-3.0', 'deprecated': False}, + 'autoconf-exception-macro': {'id': 'Autoconf-exception-macro', 'deprecated': False}, + 'bison-exception-1.24': {'id': 'Bison-exception-1.24', 'deprecated': False}, + 'bison-exception-2.2': {'id': 'Bison-exception-2.2', 'deprecated': False}, + 'bootloader-exception': {'id': 'Bootloader-exception', 'deprecated': False}, + 'cgal-linking-exception': {'id': 'CGAL-linking-exception', 'deprecated': False}, + 'classpath-exception-2.0': {'id': 'Classpath-exception-2.0', 'deprecated': False}, + 'clisp-exception-2.0': {'id': 'CLISP-exception-2.0', 'deprecated': False}, + 'cryptsetup-openssl-exception': {'id': 'cryptsetup-OpenSSL-exception', 'deprecated': False}, + 'digia-qt-lgpl-exception-1.1': {'id': 'Digia-Qt-LGPL-exception-1.1', 'deprecated': False}, + 'digirule-foss-exception': {'id': 'DigiRule-FOSS-exception', 'deprecated': False}, + 'ecos-exception-2.0': {'id': 'eCos-exception-2.0', 'deprecated': False}, + 'erlang-otp-linking-exception': {'id': 'erlang-otp-linking-exception', 'deprecated': False}, + 'fawkes-runtime-exception': {'id': 'Fawkes-Runtime-exception', 'deprecated': False}, + 'fltk-exception': {'id': 'FLTK-exception', 'deprecated': False}, + 'fmt-exception': {'id': 'fmt-exception', 'deprecated': False}, + 'font-exception-2.0': {'id': 'Font-exception-2.0', 'deprecated': False}, + 'freertos-exception-2.0': {'id': 'freertos-exception-2.0', 'deprecated': False}, + 'gcc-exception-2.0': {'id': 'GCC-exception-2.0', 'deprecated': False}, + 'gcc-exception-2.0-note': {'id': 'GCC-exception-2.0-note', 'deprecated': False}, + 'gcc-exception-3.1': {'id': 'GCC-exception-3.1', 'deprecated': False}, + 'gmsh-exception': {'id': 'Gmsh-exception', 'deprecated': False}, + 'gnat-exception': {'id': 'GNAT-exception', 'deprecated': False}, + 'gnome-examples-exception': {'id': 'GNOME-examples-exception', 'deprecated': False}, + 'gnu-compiler-exception': {'id': 'GNU-compiler-exception', 'deprecated': False}, + 'gnu-javamail-exception': {'id': 'gnu-javamail-exception', 'deprecated': False}, + 'gpl-3.0-389-ds-base-exception': {'id': 'GPL-3.0-389-ds-base-exception', 'deprecated': False}, + 'gpl-3.0-interface-exception': {'id': 'GPL-3.0-interface-exception', 'deprecated': False}, + 'gpl-3.0-linking-exception': {'id': 'GPL-3.0-linking-exception', 'deprecated': False}, + 'gpl-3.0-linking-source-exception': {'id': 'GPL-3.0-linking-source-exception', 'deprecated': False}, + 'gpl-cc-1.0': {'id': 'GPL-CC-1.0', 'deprecated': False}, + 'gstreamer-exception-2005': {'id': 'GStreamer-exception-2005', 'deprecated': False}, + 'gstreamer-exception-2008': {'id': 'GStreamer-exception-2008', 'deprecated': False}, + 'harbour-exception': {'id': 'harbour-exception', 'deprecated': False}, + 'i2p-gpl-java-exception': {'id': 'i2p-gpl-java-exception', 'deprecated': False}, + 'independent-modules-exception': {'id': 'Independent-modules-exception', 'deprecated': False}, + 'kicad-libraries-exception': {'id': 'KiCad-libraries-exception', 'deprecated': False}, + 'lgpl-3.0-linking-exception': {'id': 'LGPL-3.0-linking-exception', 'deprecated': False}, + 'libpri-openh323-exception': {'id': 'libpri-OpenH323-exception', 'deprecated': False}, + 'libtool-exception': {'id': 'Libtool-exception', 'deprecated': False}, + 'linux-syscall-note': {'id': 'Linux-syscall-note', 'deprecated': False}, + 'llgpl': {'id': 'LLGPL', 'deprecated': False}, + 'llvm-exception': {'id': 'LLVM-exception', 'deprecated': False}, + 'lzma-exception': {'id': 'LZMA-exception', 'deprecated': False}, + 'mif-exception': {'id': 'mif-exception', 'deprecated': False}, + 'mxml-exception': {'id': 'mxml-exception', 'deprecated': False}, + 'nokia-qt-exception-1.1': {'id': 'Nokia-Qt-exception-1.1', 'deprecated': True}, + 'ocaml-lgpl-linking-exception': {'id': 'OCaml-LGPL-linking-exception', 'deprecated': False}, + 'occt-exception-1.0': {'id': 'OCCT-exception-1.0', 'deprecated': False}, + 'openjdk-assembly-exception-1.0': {'id': 'OpenJDK-assembly-exception-1.0', 'deprecated': False}, + 'openvpn-openssl-exception': {'id': 'openvpn-openssl-exception', 'deprecated': False}, + 'pcre2-exception': {'id': 'PCRE2-exception', 'deprecated': False}, + 'polyparse-exception': {'id': 'polyparse-exception', 'deprecated': False}, + 'ps-or-pdf-font-exception-20170817': {'id': 'PS-or-PDF-font-exception-20170817', 'deprecated': False}, + 'qpl-1.0-inria-2004-exception': {'id': 'QPL-1.0-INRIA-2004-exception', 'deprecated': False}, + 'qt-gpl-exception-1.0': {'id': 'Qt-GPL-exception-1.0', 'deprecated': False}, + 'qt-lgpl-exception-1.1': {'id': 'Qt-LGPL-exception-1.1', 'deprecated': False}, + 'qwt-exception-1.0': {'id': 'Qwt-exception-1.0', 'deprecated': False}, + 'romic-exception': {'id': 'romic-exception', 'deprecated': False}, + 'rrdtool-floss-exception-2.0': {'id': 'RRDtool-FLOSS-exception-2.0', 'deprecated': False}, + 'sane-exception': {'id': 'SANE-exception', 'deprecated': False}, + 'shl-2.0': {'id': 'SHL-2.0', 'deprecated': False}, + 'shl-2.1': {'id': 'SHL-2.1', 'deprecated': False}, + 'stunnel-exception': {'id': 'stunnel-exception', 'deprecated': False}, + 'swi-exception': {'id': 'SWI-exception', 'deprecated': False}, + 'swift-exception': {'id': 'Swift-exception', 'deprecated': False}, + 'texinfo-exception': {'id': 'Texinfo-exception', 'deprecated': False}, + 'u-boot-exception-2.0': {'id': 'u-boot-exception-2.0', 'deprecated': False}, + 'ubdl-exception': {'id': 'UBDL-exception', 'deprecated': False}, + 'universal-foss-exception-1.0': {'id': 'Universal-FOSS-exception-1.0', 'deprecated': False}, + 'vsftpd-openssl-exception': {'id': 'vsftpd-openssl-exception', 'deprecated': False}, + 'wxwindows-exception-3.1': {'id': 'WxWindows-exception-3.1', 'deprecated': False}, + 'x11vnc-openssl-exception': {'id': 'x11vnc-openssl-exception', 'deprecated': False}, +} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py new file mode 100644 index 00000000000..51b60364603 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py @@ -0,0 +1,576 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import functools +import operator +import os +import platform +import sys +from collections.abc import Set as AbstractSet +from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union, cast + +from ._parser import MarkerAtom, MarkerList, Op, Value, Variable +from ._parser import parse_marker as _parse_marker +from ._tokenizer import ParserSyntaxError +from .specifiers import InvalidSpecifier, Specifier +from .utils import canonicalize_name + +if TYPE_CHECKING: + from collections.abc import Mapping + +__all__ = [ + "Environment", + "EvaluateContext", + "InvalidMarker", + "Marker", + "UndefinedComparison", + "UndefinedEnvironmentName", + "default_environment", +] + + +def __dir__() -> list[str]: + return __all__ + + +Operator = Callable[[str, Union[str, AbstractSet[str]]], bool] +EvaluateContext = Literal["metadata", "lock_file", "requirement"] +"""A ``typing.Literal`` enumerating valid marker evaluation contexts. + +Valid values for the ``context`` passed to :meth:`Marker.evaluate` are: + +* ``"metadata"`` (for core metadata; default) +* ``"lock_file"`` (for lock files) +* ``"requirement"`` (i.e. all other situations) + +.. versionadded:: 25.0 +""" + +MARKERS_ALLOWING_SET = {"extras", "dependency_groups"} +MARKERS_REQUIRING_VERSION = { + "implementation_version", + "platform_release", + "python_full_version", + "python_version", +} + + +class InvalidMarker(ValueError): + """Raised when attempting to create a :class:`Marker` from invalid input. + + This error indicates that the given marker string does not conform to the + :ref:`specification of dependency specifiers `. + """ + + +class UndefinedComparison(ValueError): + """Raised when evaluating an unsupported marker comparison. + + This can happen when marker values are compared as versions but do not + conform to the :ref:`specification of version specifiers + `. + """ + + +class UndefinedEnvironmentName(KeyError): + """Raised when evaluating a marker that references a missing environment key. + + Subclasses :class:`KeyError` so that code catching the bare ``KeyError`` that + a missing environment lookup historically produced keeps working. + + .. versionchanged:: 26.3 + Now subclasses :class:`KeyError` (was :class:`ValueError`) and is raised by + :meth:`Marker.evaluate` for missing environment keys, where a bare + ``KeyError`` was raised before. + """ + + +class Environment(TypedDict): + """ + A dictionary that represents a Python environment as captured by + :func:`default_environment`. All fields are required. + """ + + implementation_name: str + """The implementation's identifier, e.g. ``'cpython'``.""" + + implementation_version: str + """ + The implementation's version, e.g. ``'3.13.0a2'`` for CPython 3.13.0a2, or + ``'7.3.13'`` for PyPy3.10 v7.3.13. + """ + + os_name: str + """ + The value of :py:data:`os.name`. The name of the operating system dependent module + imported, e.g. ``'posix'``. + """ + + platform_machine: str + """ + Returns the machine type, e.g. ``'i386'``. + + An empty string if the value cannot be determined. + """ + + platform_release: str + """ + The system's release, e.g. ``'2.2.0'`` or ``'NT'``. + + An empty string if the value cannot be determined. + """ + + platform_system: str + """ + The system/OS name, e.g. ``'Linux'``, ``'Windows'`` or ``'Java'``. + + An empty string if the value cannot be determined. + """ + + platform_version: str + """ + The system's release version, e.g. ``'#3 on degas'``. + + An empty string if the value cannot be determined. + """ + + python_full_version: str + """ + The Python version as string ``'major.minor.patchlevel'``. + + Note that unlike the Python :py:data:`sys.version`, this value will always include + the patchlevel (it defaults to 0). + """ + + platform_python_implementation: str + """ + A string identifying the Python implementation, e.g. ``'CPython'``. + """ + + python_version: str + """The Python version as string ``'major.minor'``.""" + + sys_platform: str + """ + This string contains a platform identifier that can be used to append + platform-specific components to :py:data:`sys.path`, for instance. + + For Unix systems, except on Linux and AIX, this is the lowercased OS name as + returned by ``uname -s`` with the first part of the version as returned by + ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, at the time when Python + was built. + """ + + +def _normalize_extras( + result: MarkerList | MarkerAtom | str, +) -> MarkerList | MarkerAtom | str: + if isinstance(result, list): + return [_normalize_extras(r) for r in result] + if not isinstance(result, tuple): + return result + + lhs, op, rhs = result + if isinstance(lhs, Variable) and lhs.value == "extra" and isinstance(rhs, Value): + normalized_extra = canonicalize_name(rhs.value) + rhs = Value(normalized_extra) + elif isinstance(rhs, Variable) and rhs.value == "extra" and isinstance(lhs, Value): + normalized_extra = canonicalize_name(lhs.value) + lhs = Value(normalized_extra) + elif ( + isinstance(rhs, Variable) + and rhs.value in MARKERS_ALLOWING_SET + and isinstance(lhs, Value) + ): + # PEP 685 (extras) / PEP 735 (dependency_groups): the set-valued membership + # literal must also be normalized. evaluate() already canonicalizes both + # operands for these keys (see _normalize), so normalizing the literal at + # parse time keeps __str__/__eq__/__hash__ consistent with evaluate() -- e.g. + # Marker('"Foo" in extras') and Marker('"foo" in extras') must compare and + # hash equal (the membership variable is always the right-hand operand). + lhs = Value(canonicalize_name(lhs.value)) + return lhs, op, rhs + + +def _normalize_extra_values(results: MarkerList) -> MarkerList: + """ + Normalize extra values. + """ + + return [_normalize_extras(r) for r in results] + + +def _format_marker( + marker: list[str] | MarkerAtom | str, first: bool | None = True +) -> str: + assert isinstance(marker, (list, tuple, str)) + + # Unwrap a redundant [[...]] wrapper, but keep the nesting context so a + # nested group keeps the parentheses its and/or precedence needs. + if ( + isinstance(marker, list) + and len(marker) == 1 + and isinstance(marker[0], (list, tuple)) + ): + return _format_marker(marker[0], first=first) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators: dict[str, Operator] = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": lambda _lhs, _rhs: False, + "<=": operator.eq, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.eq, + ">": lambda _lhs, _rhs: False, +} + + +def _eval_op(lhs: str, op: Op, rhs: str | AbstractSet[str], *, key: str) -> bool: + op_str = op.serialize() + if key in MARKERS_REQUIRING_VERSION: + try: + spec = Specifier(f"{op_str}{rhs}") + except InvalidSpecifier: + pass + else: + return spec.contains(lhs, prereleases=True) + + oper: Operator | None = _operators.get(op_str) + if oper is None: + raise UndefinedComparison(f"Undefined {op!r} on {lhs!r} and {rhs!r}.") + + return oper(lhs, rhs) + + +def _normalize( + lhs: str, rhs: str | AbstractSet[str], key: str +) -> tuple[str, str | AbstractSet[str]]: + # PEP 685 - Comparison of extra names for optional distribution dependencies + # https://peps.python.org/pep-0685/ + # > When comparing extra names, tools MUST normalize the names being + # > compared using the semantics outlined in PEP 503 for names + if key == "extra": + assert isinstance(rhs, str), "extra value must be a string" + # Both sides are normalized at this point already + return (lhs, rhs) + if key in MARKERS_ALLOWING_SET: + if isinstance(rhs, str): # pragma: no cover + return (canonicalize_name(lhs), canonicalize_name(rhs)) + else: + return (canonicalize_name(lhs), {canonicalize_name(v) for v in rhs}) + + # other environment markers don't have such standards + return lhs, rhs + + +def _lookup_environment( + environment: dict[str, str | AbstractSet[str]], key: str +) -> str | AbstractSet[str]: + try: + return environment[key] + except KeyError: + raise UndefinedEnvironmentName(key) from None + + +def _evaluate_markers( + markers: MarkerList, environment: dict[str, str | AbstractSet[str]] +) -> bool: + groups: list[list[bool]] = [[]] + + for marker in markers: + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + environment_key = lhs.value + lhs_value = _lookup_environment(environment, environment_key) + rhs_value = rhs.value + else: + lhs_value = lhs.value + environment_key = rhs.value + rhs_value = _lookup_environment(environment, environment_key) + + if not isinstance(lhs_value, str): + raise UndefinedComparison( + f"Set-valued marker {environment_key!r} can only be used " + f'with the membership form (e.g. "" in ' + f"{environment_key}); it cannot appear on the left-hand " + f"side of {op.serialize()!r}." + ) + lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key) + groups[-1].append(_eval_op(lhs_value, op, rhs_value, key=environment_key)) + elif marker == "or": + groups.append([]) + elif marker == "and": + pass + else: # pragma: nocover + raise TypeError(f"Unexpected marker {marker!r}") + + return any(all(item) for item in groups) + + +def _format_full_version(info: sys._version_info) -> str: + version = f"{info.major}.{info.minor}.{info.micro}" + kind = info.releaselevel + if kind != "final": + version += kind[0] + str(info.serial) + return version + + +@functools.cache +def _cached_default_environment() -> Environment: + """Build the default marker environment for the current Python process. + + The values are derived from process-constant data (the running interpreter + and the host platform), so this is cached and built only once. The result is + shared between callers and must never be mutated; :func:`default_environment` + returns a fresh copy. + """ + iver = _format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": ".".join(platform.python_version_tuple()[:2]), + "sys_platform": sys.platform, + } + + +def default_environment() -> Environment: + """Return the default marker environment for the current Python process. + + This is the base environment used by :meth:`Marker.evaluate`. A fresh copy + is returned on every call so callers may freely mutate the result; a shallow + copy suffices because all values are immutable strings. + + .. versionchanged:: 26.3 + The environment is computed once per process and cached, since it is + derived from process-constant data. Patching ``platform``/``sys``/``os`` + after the first call has no effect; pass an explicit ``environment`` to + :meth:`Marker.evaluate` to evaluate against different values. + """ + return cast("Environment", dict(_cached_default_environment())) + + +class Marker: + """Represents a parsed dependency marker expression. + + Marker expressions are parsed according to the + :ref:`specification of dependency specifiers `. + + :param marker: The string representation of a marker expression. + :raises InvalidMarker: If ``marker`` cannot be parsed. + + Instances are safe to serialize with :mod:`pickle`. They use a stable + format so the same pickle can be loaded in future packaging releases. + + .. versionchanged:: 26.2 + + Added a stable pickle format. Pickles created with packaging 26.2+ can + be unpickled with future releases. Backward compatibility with pickles + from packaging < 26.2 is supported but may be removed in a future + release. + """ + + __slots__ = ("_markers",) + + def __init__(self, marker: str) -> None: + # Note: We create a Marker object without calling this constructor in + # packaging.requirements.Requirement. If any additional logic is + # added here, make sure to mirror/adapt Requirement. + + # If this fails and throws an error, the repr still expects _markers to + # be defined. + self._markers: MarkerList = [] + + try: + self._markers = _normalize_extra_values(_parse_marker(marker)) + # The attribute `_markers` can be described in terms of a recursive type: + # MarkerList = List[Union[Tuple[Node, ...], str, MarkerList]] + # + # For example, the following expression: + # python_version > "3.6" or (python_version == "3.6" and os_name == "unix") + # + # is parsed into: + # [ + # (, ')>, ), + # 'and', + # [ + # (, , ), + # 'or', + # (, , ) + # ] + # ] + except ParserSyntaxError as e: + raise InvalidMarker(str(e)) from e + + @classmethod + def _from_markers(cls, markers: MarkerList) -> Marker: + """Create a Marker instance from a pre-parsed marker tree. + + This avoids re-parsing serialised marker strings when combining markers. + """ + new = cls.__new__(cls) + new._markers = markers + return new + + def __str__(self) -> str: + return _format_marker(self._markers) + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}({str(self)!r})>" + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Marker): + return NotImplemented + + return str(self) == str(other) + + def __getstate__(self) -> str: + # Return the marker expression string for compactness and stability. + # Internal Node objects are excluded; the string is re-parsed on load. + return str(self) + + def __setstate__(self, state: object) -> None: + if isinstance(state, str): + # New format (26.2+): just the marker expression string. + try: + self._markers = _normalize_extra_values(_parse_marker(state)) + except ParserSyntaxError as exc: + raise TypeError(f"Cannot restore Marker from {state!r}") from exc + return + if isinstance(state, dict) and "_markers" in state: + # Old format (packaging <= 26.1, no __slots__): plain __dict__. + markers = state["_markers"] + if isinstance(markers, list): + self._markers = markers + return + if isinstance(state, tuple) and len(state) == 2: + # Old format (packaging <= 26.1, __slots__): (None, {slot: value}). + _, slot_dict = state + if isinstance(slot_dict, dict) and "_markers" in slot_dict: + markers = slot_dict["_markers"] + if isinstance(markers, list): + self._markers = markers + return + raise TypeError(f"Cannot restore Marker from {state!r}") + + def __and__(self, other: Marker) -> Marker: + """Combine this marker with another using ``and``. + + .. versionadded:: 26.1 + """ + if not isinstance(other, Marker): + return NotImplemented + return self._from_markers([self._markers, "and", other._markers]) + + def __or__(self, other: Marker) -> Marker: + """Combine this marker with another using ``or``. + + .. versionadded:: 26.1 + """ + if not isinstance(other, Marker): + return NotImplemented + return self._from_markers([self._markers, "or", other._markers]) + + def evaluate( + self, + environment: Mapping[str, str | AbstractSet[str]] | None = None, + context: EvaluateContext = "metadata", + ) -> bool: + """Evaluate a marker. + + Return the boolean from evaluating this marker against the environment. + The environment is determined from the current Python process unless + passed in explicitly. + + :param environment: Mapping containing keys and values to override the + detected environment. + :param EvaluateContext context: The context in which the marker is + evaluated, which influences what marker names are considered valid. + Accepted values are ``"metadata"`` (for core metadata; default), + ``"lock_file"``, and ``"requirement"`` (i.e. all other situations). + :raises UndefinedComparison: If the marker uses a comparison on values + that are not valid versions per the :ref:`specification of version + specifiers `. + :raises UndefinedEnvironmentName: If the marker references a value that + is missing from the evaluation environment. + :returns: ``True`` if the marker matches, otherwise ``False``. + + .. versionchanged:: 25.0 + Added the ``context`` parameter, which influences which marker names + are considered valid. + """ + current_environment = cast( + "dict[str, str | AbstractSet[str]]", default_environment() + ) + if context == "lock_file": + current_environment |= { + "extras": frozenset(), + "dependency_groups": frozenset(), + } + elif context == "metadata": + current_environment["extra"] = "" + + if environment is not None: + current_environment |= environment + if "extra" in current_environment: + # The API used to allow setting extra to None. We need to handle + # this case for backwards compatibility. Also skip running + # normalize name if extra is empty. + extra = cast("str | None", current_environment["extra"]) + current_environment["extra"] = canonicalize_name(extra) if extra else "" + + return _evaluate_markers( + self._markers, _repair_python_full_version(current_environment) + ) + + +def _pep440_python_full_version(python_full_version: str) -> str: + """ + Work around platform.python_version() returning something that is not PEP 440 + compliant for non-tagged Python builds. + """ + if python_full_version.endswith("+"): + return f"{python_full_version}local" + return python_full_version + + +def _repair_python_full_version( + env: dict[str, str | AbstractSet[str]], +) -> dict[str, str | AbstractSet[str]]: + """ + Work around platform.python_version() returning something that is not PEP 440 + compliant for non-tagged Python builds. + """ + python_full_version = cast("str", env["python_full_version"]) + env["python_full_version"] = _pep440_python_full_version(python_full_version) + return env diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py new file mode 100644 index 00000000000..10611050051 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py @@ -0,0 +1,1054 @@ +from __future__ import annotations + +import email.header +import email.message +import email.parser +import email.policy +import keyword +import pathlib +import re +import typing +from typing import ( + Any, + Callable, + Generic, + Literal, + TypedDict, + cast, +) + +from . import licenses, requirements, specifiers, utils +from . import version as version_module +from .errors import ExceptionGroup, _ErrorCollector + +if typing.TYPE_CHECKING: + from .licenses import NormalizedLicenseExpression + from .version import Version + +T = typing.TypeVar("T") + + +__all__ = [ + "ExceptionGroup", # Keep this for a bit (makes mypy happy w/ 26.0 compat) + "InvalidMetadata", + "Metadata", + "RFC822Message", + "RFC822Policy", + "RawMetadata", + "parse_email", +] + + +def __dir__() -> list[str]: + return __all__ + + +class InvalidMetadata(ValueError): + """A metadata field contains invalid data. + + .. versionadded:: 23.2 + """ + + field: str + """The name of the field that contains invalid data.""" + + def __init__(self, field: str, message: str) -> None: + self.field = field + super().__init__(message) + + # Support pickling; ``args`` does not match ``__init__``'s signature. + def __reduce__(self) -> tuple[type[InvalidMetadata], tuple[str, str]]: + return (self.__class__, (self.field, self.args[0])) + + +# The RawMetadata class attempts to make as few assumptions about the underlying +# serialization formats as possible. The idea is that as long as a serialization +# formats offer some very basic primitives in *some* way then we can support +# serializing to and from that format. +class RawMetadata(TypedDict, total=False): + """A dictionary of raw core metadata. + + Each field in core metadata maps to a key of this dictionary (when data is + provided). The key is lower-case and underscores are used instead of dashes + compared to the equivalent core metadata field. Any core metadata field that + can be specified multiple times or can hold multiple values in a single + field have a key with a plural name. See :class:`Metadata` whose attributes + match the keys of this dictionary. + + Core metadata fields that can be specified multiple times are stored as a + list or dict depending on which is appropriate for the field. Any fields + which hold multiple values in a single field are stored as a list. All fields + are considered optional. + """ + + # Metadata 1.0 - PEP 241 + metadata_version: str + name: str + version: str + platforms: list[str] + summary: str + description: str + keywords: list[str] + home_page: str + author: str + author_email: str + license: str + + # Metadata 1.1 - PEP 314 + supported_platforms: list[str] + download_url: str + classifiers: list[str] + requires: list[str] + provides: list[str] + obsoletes: list[str] + + # Metadata 1.2 - PEP 345 + maintainer: str + maintainer_email: str + requires_dist: list[str] + provides_dist: list[str] + obsoletes_dist: list[str] + requires_python: str + requires_external: list[str] + project_urls: dict[str, str] + + # Metadata 2.0 + # PEP 426 attempted to completely revamp the metadata format + # but got stuck without ever being able to build consensus on + # it and ultimately ended up withdrawn. + # + # However, a number of tools had started emitting METADATA with + # `2.0` Metadata-Version, so for historical reasons, this version + # was skipped. + + # Metadata 2.1 - PEP 566 + description_content_type: str + provides_extra: list[str] + + # Metadata 2.2 - PEP 643 + dynamic: list[str] + + # Metadata 2.3 - PEP 685 + # No new fields were added in PEP 685, just some edge case were + # tightened up to provide better interoperability. + + # Metadata 2.4 - PEP 639 + license_expression: str + """.. versionadded:: 24.2""" + license_files: list[str] + """.. versionadded:: 24.2""" + + # Metadata 2.5 - PEP 794 + import_names: list[str] + """.. versionadded:: 26.0""" + import_namespaces: list[str] + """.. versionadded:: 26.0""" + + # Metadata 2.6 - PEP 808 (no new fields, behavior change for Dynamic) + + +# 'keywords' is special as it's a string in the core metadata spec, but we +# represent it as a list. +_STRING_FIELDS = { + "author", + "author_email", + "description", + "description_content_type", + "download_url", + "home_page", + "license", + "license_expression", + "maintainer", + "maintainer_email", + "metadata_version", + "name", + "requires_python", + "summary", + "version", +} + +_LIST_FIELDS = { + "classifiers", + "dynamic", + "license_files", + "obsoletes", + "obsoletes_dist", + "platforms", + "provides", + "provides_dist", + "provides_extra", + "requires", + "requires_dist", + "requires_external", + "supported_platforms", + "import_names", + "import_namespaces", +} + +_DICT_FIELDS = { + "project_urls", +} + + +def _parse_keywords(data: str) -> list[str]: + """Split a string of comma-separated keywords into a list of keywords.""" + return [k.strip() for k in data.split(",")] + + +def _parse_project_urls(data: list[str]) -> dict[str, str]: + """Parse a list of label/URL string pairings separated by a comma.""" + urls = {} + for pair in data: + # Our logic is slightly tricky here as we want to try and do + # *something* reasonable with malformed data. + # + # The main thing that we have to worry about, is data that does + # not have a ',' at all to split the label from the Value. There + # isn't a singular right answer here, and we will fail validation + # later on (if the caller is validating) so it doesn't *really* + # matter, but since the missing value has to be an empty str + # and our return value is dict[str, str], if we let the key + # be the missing value, then they'd have multiple '' values that + # overwrite each other in a accumulating dict. + # + # The other potential issue is that it's possible to have the + # same label multiple times in the metadata, with no solid "right" + # answer with what to do in that case. As such, we'll do the only + # thing we can, which is treat the field as unparsable and add it + # to our list of unparsed fields. + # + # TODO: The spec doesn't say anything about if the keys should be + # considered case sensitive or not... logically they should + # be case-preserving and case-insensitive, but doing that + # would open up more cases where we might have duplicate + # entries. + label, _, url = (s.strip() for s in pair.partition(",")) + + if label in urls: + # The label already exists in our set of urls, so this field + # is unparsable, and we can just add the whole thing to our + # unparsable data and stop processing it. + raise KeyError("duplicate labels in project urls") + urls[label] = url + + return urls + + +def _get_payload(msg: email.message.Message, source: bytes | str) -> str: + """Get the body of the message.""" + # If our source is a str, then our caller has managed encodings for us, + # and we don't need to deal with it. + if isinstance(source, str): + payload = msg.get_payload() + # A multipart payload makes get_payload() return a list of messages + # rather than a str; route it to ``unparsed``. + if not isinstance(payload, str): + raise ValueError("payload is not a string") # noqa: TRY004 + return payload + # If our source is a bytes, then we're managing the encoding and we need + # to deal with it. + else: + bpayload = msg.get_payload(decode=True) + # A multipart payload makes get_payload(decode=True) return None; + # route it to ``unparsed``. + if not isinstance(bpayload, bytes): + raise ValueError("payload in an invalid encoding") # noqa: TRY004 + try: + return bpayload.decode("utf8", "strict") + except UnicodeDecodeError as exc: + raise ValueError("payload in an invalid encoding") from exc + + +# The various parse_FORMAT functions here are intended to be as lenient as +# possible in their parsing, while still returning a correctly typed +# RawMetadata. +# +# To aid in this, we also generally want to do as little touching of the +# data as possible, except where there are possibly some historic holdovers +# that make valid data awkward to work with. +# +# While this is a lower level, intermediate format than our ``Metadata`` +# class, some light touch ups can make a massive difference in usability. + +# Map METADATA fields to RawMetadata. +_EMAIL_TO_RAW_MAPPING = { + "author": "author", + "author-email": "author_email", + "classifier": "classifiers", + "description": "description", + "description-content-type": "description_content_type", + "download-url": "download_url", + "dynamic": "dynamic", + "home-page": "home_page", + "import-name": "import_names", + "import-namespace": "import_namespaces", + "keywords": "keywords", + "license": "license", + "license-expression": "license_expression", + "license-file": "license_files", + "maintainer": "maintainer", + "maintainer-email": "maintainer_email", + "metadata-version": "metadata_version", + "name": "name", + "obsoletes": "obsoletes", + "obsoletes-dist": "obsoletes_dist", + "platform": "platforms", + "project-url": "project_urls", + "provides": "provides", + "provides-dist": "provides_dist", + "provides-extra": "provides_extra", + "requires": "requires", + "requires-dist": "requires_dist", + "requires-external": "requires_external", + "requires-python": "requires_python", + "summary": "summary", + "supported-platform": "supported_platforms", + "version": "version", +} +_RAW_TO_EMAIL_MAPPING = {raw: email for email, raw in _EMAIL_TO_RAW_MAPPING.items()} + + +# A bare "\r" makes the email generator raise ``HeaderWriteError``, and on +# CPython releases without the CVE-2024-6923 fix any ``str.splitlines`` +# boundary ends the header line, so fold all of them, not just "\n". +_LINE_BOUNDARY_RE = re.compile(r"\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]") + + +# This class is for writing RFC822 messages +class RFC822Policy(email.policy.EmailPolicy): + """ + This is :class:`email.policy.EmailPolicy`, but with a simple ``header_store_parse`` + implementation that handles multi-line values, and some nice defaults. + + .. versionadded:: 26.0 + """ + + utf8 = True + mangle_from_ = False + max_line_length = 0 + + def header_store_parse(self, name: str, value: str) -> tuple[str, str]: + size = len(name) + 2 + value = _LINE_BOUNDARY_RE.sub("\n" + " " * size, value) + return (name, value) + + +# This class is for writing RFC822 messages +class RFC822Message(email.message.EmailMessage): + """ + This is :class:`email.message.EmailMessage` with two small changes: it defaults to + our `RFC822Policy`, and it correctly writes unicode when being called + with `bytes()`. + + .. versionadded:: 26.0 + """ + + def __init__(self) -> None: + super().__init__(policy=RFC822Policy()) + + def as_bytes( + self, unixfrom: bool = False, policy: email.policy.Policy | None = None + ) -> bytes: + """ + Return the bytes representation of the message. + + This handles unicode encoding. + """ + return self.as_string(unixfrom, policy=policy).encode("utf-8") + + +def parse_email(data: bytes | str) -> tuple[RawMetadata, dict[str, list[str]]]: + """Parse a distribution's metadata stored as email headers (e.g. from ``METADATA``). + + This function returns a two-item tuple of dicts. The first dict is of + recognized fields from the core metadata specification. Fields that can be + parsed and translated into Python's built-in types are converted + appropriately. All other fields are left as-is. Fields that are allowed to + appear multiple times are stored as lists. + + The second dict contains all other fields from the metadata. This includes + any unrecognized fields. It also includes any fields which are expected to + be parsed into a built-in type but were not formatted appropriately. Finally, + any fields that are expected to appear only once but are repeated are + included in this dict. + + """ + raw: dict[str, str | list[str] | dict[str, str]] = {} + unparsed: dict[str, list[str]] = {} + + if isinstance(data, str): + parsed = email.parser.Parser(policy=email.policy.compat32).parsestr(data) + else: + parsed = email.parser.BytesParser(policy=email.policy.compat32).parsebytes(data) + + # We have to wrap parsed.keys() in a set, because in the case of multiple + # values for a key (a list), the key will appear multiple times in the + # list of keys, but we're avoiding that by using get_all(). + for name_with_case in frozenset(parsed.keys()): + # Header names in RFC are case insensitive, so we'll normalize to all + # lower case to make comparisons easier. + name = name_with_case.lower() + + # We use get_all() here, even for fields that aren't multiple use, + # because otherwise someone could have e.g. two Name fields, and we + # would just silently ignore it rather than doing something about it. + headers = parsed.get_all(name) or [] + + # The way the email module works when parsing bytes is that it + # unconditionally decodes the bytes as ascii using the surrogateescape + # handler. When you pull that data back out (such as with get_all() ), + # it looks to see if the str has any surrogate escapes, and if it does + # it wraps it in a Header object instead of returning the string. + # + # As such, we'll look for those Header objects, and fix up the encoding. + value = [] + # Flag if we have run into any issues processing the headers, thus + # signalling that the data belongs in 'unparsed'. + valid_encoding = True + for h in headers: + # It's unclear if this can return more types than just a Header or + # a str, so we'll just assert here to make sure. + assert isinstance(h, (email.header.Header, str)) + + # If it's a header object, we need to do our little dance to get + # the real data out of it. In cases where there is invalid data + # we're going to end up with mojibake, but there's no obvious, good + # way around that without reimplementing parts of the Header object + # ourselves. + # + # That should be fine since, if mojibacked happens, this key is + # going into the unparsed dict anyways. + if isinstance(h, email.header.Header): + # The Header object stores it's data as chunks, and each chunk + # can be independently encoded, so we'll need to check each + # of them. + chunks: list[tuple[bytes, str | None]] = [] + for binary, _encoding in email.header.decode_header(h): + try: + binary.decode("utf8", "strict") + except UnicodeDecodeError: + # Enable mojibake. + encoding = "latin1" + valid_encoding = False + else: + encoding = "utf8" + chunks.append((binary, encoding)) + + # Turn our chunks back into a Header object, then let that + # Header object do the right thing to turn them into a + # string for us. + value.append(str(email.header.make_header(chunks))) + # This is already a string, so just add it. + else: + value.append(h) + + # We've processed all of our values to get them into a list of str, + # but we may have mojibake data, in which case this is an unparsed + # field. + if not valid_encoding: + unparsed[name] = value + continue + + raw_name = _EMAIL_TO_RAW_MAPPING.get(name) + if raw_name is None: + # This is a bit of a weird situation, we've encountered a key that + # we don't know what it means, so we don't know whether it's meant + # to be a list or not. + # + # Since we can't really tell one way or another, we'll just leave it + # as a list, even though it may be a single item list, because that's + # what makes the most sense for email headers. + unparsed[name] = value + continue + + # If this is one of our string fields, then we'll check to see if our + # value is a list of a single item. If it is then we'll assume that + # it was emitted as a single string, and unwrap the str from inside + # the list. + # + # If it's any other kind of data, then we haven't the faintest clue + # what we should parse it as, and we have to just add it to our list + # of unparsed stuff. + if raw_name in _STRING_FIELDS and len(value) == 1: + raw[raw_name] = value[0] + # If this is import_names, we need to special case the empty field + # case, which converts to an empty list instead of None. We can't let + # the empty case slip through, as it will fail validation. + elif raw_name == "import_names" and value == [""]: + raw[raw_name] = [] + # If this is one of our list of string fields, then we can just assign + # the value, since email *only* has strings, and our get_all() call + # above ensures that this is a list. + elif raw_name in _LIST_FIELDS: + raw[raw_name] = value + # Special Case: Keywords + # The keywords field is implemented in the metadata spec as a str, + # but it conceptually is a list of strings, and is serialized using + # ", ".join(keywords), so we'll do some light data massaging to turn + # this into what it logically is. + elif raw_name == "keywords" and len(value) == 1: + raw[raw_name] = _parse_keywords(value[0]) + # Special Case: Project-URL + # The project urls is implemented in the metadata spec as a list of + # specially-formatted strings that represent a key and a value, which + # is fundamentally a mapping, however the email format doesn't support + # mappings in a sane way, so it was crammed into a list of strings + # instead. + # + # We will do a little light data massaging to turn this into a map as + # it logically should be. + elif raw_name == "project_urls": + try: + raw[raw_name] = _parse_project_urls(value) + except KeyError: + unparsed[name] = value + # Nothing that we've done has managed to parse this, so it'll just + # throw it in our unparsable data and move on. + else: + unparsed[name] = value + + # We need to support getting the Description from the message payload in + # addition to getting it from the the headers. This does mean, though, there + # is the possibility of it being set both ways, in which case we put both + # in 'unparsed' since we don't know which is right. + try: + payload = _get_payload(parsed, data) + except ValueError: + unparsed.setdefault("description", []).append( + parsed.get_payload(decode=isinstance(data, bytes)) # type: ignore[call-overload] + ) + else: + if payload: + # Check to see if we've already got a description, if so then both + # it, and this body move to unparsable. + if "description" in raw: + description_header = cast("str", raw.pop("description")) + unparsed.setdefault("description", []).extend( + [description_header, payload] + ) + elif "description" in unparsed: + unparsed["description"].append(payload) + else: + raw["description"] = payload + + # We need to cast our `raw` to a metadata, because a TypedDict only support + # literal key names, but we're computing our key names on purpose, but the + # way this function is implemented, our `TypedDict` can only have valid key + # names. + return cast("RawMetadata", raw), unparsed + + +_NOT_FOUND = object() + + +# Keep the two values in sync. +_VALID_METADATA_VERSIONS = [ + "1.0", + "1.1", + "1.2", + "2.1", + "2.2", + "2.3", + "2.4", + "2.5", + "2.6", +] +_MetadataVersion = Literal[ + "1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6" +] + +_REQUIRED_ATTRS = frozenset(["metadata_version", "name", "version"]) + + +class _Validator(Generic[T]): + """Validate a metadata field. + + All _process_*() methods correspond to a core metadata field. The method is + called with the field's raw value. If the raw value is valid it is returned + in its "enriched" form (e.g. ``version.Version`` for the ``Version`` field). + If the raw value is invalid, :exc:`InvalidMetadata` is raised (with a cause + as appropriate). + """ + + name: str + raw_name: str + added: _MetadataVersion + + def __init__( + self, + *, + added: _MetadataVersion = "1.0", + ) -> None: + self.added = added + + def __set_name__(self, _owner: Metadata, name: str) -> None: + self.name = name + self.raw_name = _RAW_TO_EMAIL_MAPPING[name] + + def __get__(self, instance: Metadata, _owner: type[Metadata]) -> T: + # With Python 3.8, the caching can be replaced with functools.cached_property(). + # No need to check the cache as attribute lookup will resolve into the + # instance's __dict__ before __get__ is called. + cache = instance.__dict__ + value = instance._raw.get(self.name) + + # To make the _process_* methods easier, we'll check if the value is None + # and if this field is NOT a required attribute, and if both of those + # things are true, we'll skip the the converter. This will mean that the + # converters never have to deal with the None union. + if self.name in _REQUIRED_ATTRS or value is not None: + try: + converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}") + except AttributeError: + pass + else: + value = converter(value) + + cache[self.name] = value + try: + del instance._raw[self.name] # type: ignore[misc] + except KeyError: + pass + + return cast("T", value) + + def _invalid_metadata( + self, msg: str, cause: Exception | None = None + ) -> InvalidMetadata: + exc = InvalidMetadata(self.raw_name, msg) + exc.__cause__ = cause + return exc + + def _process_metadata_version(self, value: str) -> _MetadataVersion: + # Implicitly makes Metadata-Version required. + if value not in _VALID_METADATA_VERSIONS: + raise self._invalid_metadata(f"{value!r} is not a valid metadata version") + return cast("_MetadataVersion", value) + + def _process_name(self, value: str) -> str: + if not value: + raise self._invalid_metadata(f"{self.raw_name!r} is a required field") + # Validate the name as a side-effect. + try: + utils.canonicalize_name(value, validate=True) + except utils.InvalidName as exc: + raise self._invalid_metadata( + f"{value!r} is invalid for {self.raw_name!r}", cause=exc + ) from exc + else: + return value + + def _process_version(self, value: str) -> Version: + if not value: + raise self._invalid_metadata(f"{self.raw_name!r} is a required field") + try: + return version_module.parse(value) + except version_module.InvalidVersion as exc: + raise self._invalid_metadata( + f"{value!r} is invalid for {self.raw_name!r}", cause=exc + ) from exc + + def _process_summary(self, value: str) -> str: + """Check the field contains no line breaks.""" + if _LINE_BOUNDARY_RE.search(value): + raise self._invalid_metadata(f"{self.raw_name!r} must be a single line") + return value + + def _process_description_content_type(self, value: str) -> str: + content_types = {"text/plain", "text/x-rst", "text/markdown"} + invalid_msg = ( + f"{self.raw_name!r} must be one of {list(content_types)}, not {value!r}" + ) + message = email.message.EmailMessage() + try: + message["content-type"] = value + # The email parser can raise IndexError on malformed RFC 2231 + # parameters such as "text/plain; x*". + except (ValueError, IndexError) as exc: + msg = f"{value!r} is not a valid content type for {self.raw_name!r}" + raise self._invalid_metadata(msg, cause=exc) from exc + content_type_header = message["content-type"] + if content_type_header.defects: + defect = content_type_header.defects[0] + msg = ( + f"{value!r} is not a valid content type for {self.raw_name!r}: {defect}" + ) + raise self._invalid_metadata(msg, cause=defect) from defect + + content_type, parameters = ( + # Defaults to `text/plain` if parsing failed. + message.get_content_type().lower(), + content_type_header.params, + ) + # Check if content-type is valid or defaulted to `text/plain` and thus was + # not parseable. + if content_type not in content_types or content_type not in value.lower(): + raise self._invalid_metadata(invalid_msg) + + charset = parameters.get("charset", "UTF-8") + if charset.lower() != "utf-8": + raise self._invalid_metadata( + f"{self.raw_name!r} can only specify the UTF-8 charset, not {charset!r}" + ) + + markdown_variants = {"GFM", "CommonMark"} + variant = parameters.get("variant", "GFM") # Use an acceptable default. + if content_type == "text/markdown" and variant not in markdown_variants: + raise self._invalid_metadata( + f"valid Markdown variants for {self.raw_name!r} are " + f"{list(markdown_variants)}, not {variant!r}", + ) + return value + + def _process_dynamic(self, value: list[str]) -> list[str]: + dynamic_fields = list(map(str.lower, value)) + for dynamic_field in dynamic_fields: + if dynamic_field in {"name", "version", "metadata-version"}: + raise self._invalid_metadata( + f"{dynamic_field!r} is not allowed as a dynamic field" + ) + elif dynamic_field not in _EMAIL_TO_RAW_MAPPING: + raise self._invalid_metadata( + f"{dynamic_field!r} is not a valid dynamic field" + ) + return dynamic_fields + + def _process_provides_extra( + self, + value: list[str], + ) -> list[utils.NormalizedName]: + normalized_names = [] + try: + for name in value: + normalized_names.append(utils.canonicalize_name(name, validate=True)) + except utils.InvalidName as exc: + raise self._invalid_metadata( + f"{name!r} is invalid for {self.raw_name!r}", cause=exc + ) from exc + else: + return normalized_names + + def _process_requires_python(self, value: str) -> specifiers.SpecifierSet: + try: + return specifiers.SpecifierSet(value) + except specifiers.InvalidSpecifier as exc: + raise self._invalid_metadata( + f"{value!r} is invalid for {self.raw_name!r}", cause=exc + ) from exc + + def _process_requires_dist( + self, + value: list[str], + ) -> list[requirements.Requirement]: + reqs = [] + try: + for req in value: + reqs.append(requirements.Requirement(req)) + except requirements.InvalidRequirement as exc: + raise self._invalid_metadata( + f"{req!r} is invalid for {self.raw_name!r}", cause=exc + ) from exc + else: + return reqs + + def _process_license_expression(self, value: str) -> NormalizedLicenseExpression: + try: + return licenses.canonicalize_license_expression(value) + except ValueError as exc: + raise self._invalid_metadata( + f"{value!r} is invalid for {self.raw_name!r}", cause=exc + ) from exc + + def _process_license_files(self, value: list[str]) -> list[str]: + paths = [] + for path in value: + if ".." in path: + raise self._invalid_metadata( + f"{path!r} is invalid for {self.raw_name!r}, " + "parent directory indicators are not allowed" + ) + if "*" in path: + raise self._invalid_metadata( + f"{path!r} is invalid for {self.raw_name!r}, paths must be resolved" + ) + if ( + pathlib.PurePosixPath(path).is_absolute() + or pathlib.PureWindowsPath(path).is_absolute() + ): + raise self._invalid_metadata( + f"{path!r} is invalid for {self.raw_name!r}, paths must be relative" + ) + if pathlib.PureWindowsPath(path).as_posix() != path: + raise self._invalid_metadata( + f"{path!r} is invalid for {self.raw_name!r}, " + "paths must use '/' delimiter" + ) + paths.append(path) + return paths + + def _process_import_names(self, value: list[str]) -> list[str]: + for import_name in value: + name, semicolon, private = import_name.partition(";") + name = name.rstrip() + for identifier in name.split("."): + if not identifier.isidentifier(): + raise self._invalid_metadata( + f"{name!r} is invalid for {self.raw_name!r}; " + f"{identifier!r} is not a valid identifier" + ) + elif keyword.iskeyword(identifier): + raise self._invalid_metadata( + f"{name!r} is invalid for {self.raw_name!r}; " + f"{identifier!r} is a keyword" + ) + if semicolon and private.lstrip() != "private": + raise self._invalid_metadata( + f"{import_name!r} is invalid for {self.raw_name!r}; " + "the only valid option is 'private'" + ) + return value + + _process_import_namespaces = _process_import_names + + +class Metadata: + """Representation of distribution metadata. + + Compared to :class:`RawMetadata`, this class provides objects representing + metadata fields instead of only using built-in types. Any invalid metadata + will cause :exc:`InvalidMetadata` to be raised (with a + :py:attr:`~BaseException.__cause__` attribute as appropriate). + + .. versionadded:: 23.2 + + .. versionchanged:: 24.0 + Optional attributes now return None when the field is absent instead of + raising. + """ + + _raw: RawMetadata + + @classmethod + def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> Metadata: + """Create an instance from :class:`RawMetadata`. + + If *validate* is true, all metadata will be validated and all related + exceptions will be gathered and raised as an :class:`ExceptionGroup`; + otherwise, validation happens per attribute when it is accessed. + """ + ins = cls() + ins._raw = data.copy() # Mutations occur due to caching enriched values. + + if validate: + collector = _ErrorCollector() + metadata_version = None + with collector.collect(InvalidMetadata): + metadata_version = ins.metadata_version + metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version) + + # Make sure to check for the fields that are present, the required + # fields (so their absence can be reported). + fields_to_check = frozenset(ins._raw) | _REQUIRED_ATTRS + # Remove fields that have already been checked. + fields_to_check -= {"metadata_version"} + + for key in fields_to_check: + try: + if metadata_version: + # Can't use getattr() as that triggers descriptor protocol which + # will fail due to no value for the instance argument. + try: + field_metadata_version = cls.__dict__[key].added + except KeyError: + exc = InvalidMetadata(key, f"unrecognized field: {key!r}") + collector.error(exc) + continue + field_age = _VALID_METADATA_VERSIONS.index( + field_metadata_version + ) + if field_age > metadata_age: + field = _RAW_TO_EMAIL_MAPPING[key] + exc = InvalidMetadata( + field, + f"{field} introduced in metadata version " + f"{field_metadata_version}, not {metadata_version}", + ) + collector.error(exc) + continue + getattr(ins, key) + except InvalidMetadata as exc: + collector.error(exc) + + collector.finalize("invalid metadata") + + return ins + + @classmethod + def from_email(cls, data: bytes | str, *, validate: bool = True) -> Metadata: + """Parse metadata from email headers. + + If *validate* is true, the metadata will be validated. All exceptions + related to validation will be gathered and raised as an :class:`ExceptionGroup`. + """ + raw, unparsed = parse_email(data) + + if validate: + with _ErrorCollector().on_exit("invalid or unparsed metadata") as collector: + for unparsed_key in unparsed: + if unparsed_key in _EMAIL_TO_RAW_MAPPING: + message = f"{unparsed_key!r} has invalid data" + else: + message = f"unrecognized field: {unparsed_key!r}" + collector.error(InvalidMetadata(unparsed_key, message)) + try: + validated = cls.from_raw(raw, validate=validate) + except ExceptionGroup as exc_group: + # The no-branch pragmas cover arcs only seen by Python 3.9. + for exc in exc_group.exceptions: # pragma: no branch + # A required field reported above as unparsed is absent + # from `raw`, so skip from_raw's duplicate "missing" + # complaint. + if not ( + isinstance(exc, InvalidMetadata) + and exc.field in unparsed + and _EMAIL_TO_RAW_MAPPING.get(exc.field) not in raw + ): + collector.error(exc) + else: + if not collector.errors: # pragma: no branch + return validated + + return cls.from_raw(raw, validate=validate) + + metadata_version: _Validator[_MetadataVersion] = _Validator() + """:external:ref:`core-metadata-metadata-version` + (required; validated to be a valid metadata version)""" + # `name` is not normalized/typed to NormalizedName so as to provide access to + # the original/raw name. + name: _Validator[str] = _Validator() + """:external:ref:`core-metadata-name` + (required; validated using :func:`~packaging.utils.canonicalize_name` and its + *validate* parameter)""" + version: _Validator[Version] = _Validator() + """:external:ref:`core-metadata-version` (required)""" + dynamic: _Validator[list[str] | None] = _Validator( + added="2.2", + ) + """:external:ref:`core-metadata-dynamic` + (validated against core metadata field names and lowercased)""" + platforms: _Validator[list[str] | None] = _Validator() + """:external:ref:`core-metadata-platform`""" + supported_platforms: _Validator[list[str] | None] = _Validator(added="1.1") + """:external:ref:`core-metadata-supported-platform`""" + summary: _Validator[str | None] = _Validator() + """:external:ref:`core-metadata-summary` (validated to contain no newlines)""" + description: _Validator[str | None] = _Validator() # TODO 2.1: can be in body + """:external:ref:`core-metadata-description`""" + description_content_type: _Validator[str | None] = _Validator(added="2.1") + """:external:ref:`core-metadata-description-content-type` (validated)""" + keywords: _Validator[list[str] | None] = _Validator() + """:external:ref:`core-metadata-keywords`""" + home_page: _Validator[str | None] = _Validator() + """:external:ref:`core-metadata-home-page`""" + download_url: _Validator[str | None] = _Validator(added="1.1") + """:external:ref:`core-metadata-download-url`""" + author: _Validator[str | None] = _Validator() + """:external:ref:`core-metadata-author`""" + author_email: _Validator[str | None] = _Validator() + """:external:ref:`core-metadata-author-email`""" + maintainer: _Validator[str | None] = _Validator(added="1.2") + """:external:ref:`core-metadata-maintainer`""" + maintainer_email: _Validator[str | None] = _Validator(added="1.2") + """:external:ref:`core-metadata-maintainer-email`""" + license: _Validator[str | None] = _Validator() + """:external:ref:`core-metadata-license`""" + license_expression: _Validator[NormalizedLicenseExpression | None] = _Validator( + added="2.4" + ) + """:external:ref:`core-metadata-license-expression` + + .. versionadded:: 24.2 + """ + license_files: _Validator[list[str] | None] = _Validator(added="2.4") + """:external:ref:`core-metadata-license-file` + + .. versionadded:: 24.2 + """ + classifiers: _Validator[list[str] | None] = _Validator(added="1.1") + """:external:ref:`core-metadata-classifier`""" + requires_dist: _Validator[list[requirements.Requirement] | None] = _Validator( + added="1.2" + ) + """:external:ref:`core-metadata-requires-dist`""" + requires_python: _Validator[specifiers.SpecifierSet | None] = _Validator( + added="1.2" + ) + """:external:ref:`core-metadata-requires-python`""" + # Because `Requires-External` allows for non-PEP 440 version specifiers, we + # don't do any processing on the values. + requires_external: _Validator[list[str] | None] = _Validator(added="1.2") + """:external:ref:`core-metadata-requires-external`""" + project_urls: _Validator[dict[str, str] | None] = _Validator(added="1.2") + """:external:ref:`core-metadata-project-url`""" + # PEP 685 lets us raise an error if an extra doesn't pass `Name` validation + # regardless of metadata version. + provides_extra: _Validator[list[utils.NormalizedName] | None] = _Validator( + added="2.1", + ) + """:external:ref:`core-metadata-provides-extra`""" + provides_dist: _Validator[list[str] | None] = _Validator(added="1.2") + """:external:ref:`core-metadata-provides-dist`""" + obsoletes_dist: _Validator[list[str] | None] = _Validator(added="1.2") + """:external:ref:`core-metadata-obsoletes-dist`""" + import_names: _Validator[list[str] | None] = _Validator(added="2.5") + """:external:ref:`core-metadata-import-name` + + .. versionadded:: 26.0 + """ + import_namespaces: _Validator[list[str] | None] = _Validator(added="2.5") + """:external:ref:`core-metadata-import-namespace` + + .. versionadded:: 26.0 + """ + requires: _Validator[list[str] | None] = _Validator(added="1.1") + """``Requires`` (deprecated)""" + provides: _Validator[list[str] | None] = _Validator(added="1.1") + """``Provides`` (deprecated)""" + obsoletes: _Validator[list[str] | None] = _Validator(added="1.1") + """``Obsoletes`` (deprecated)""" + + def as_rfc822(self) -> RFC822Message: + """ + Return an RFC822 message with the metadata. + + .. versionadded:: 26.0 + """ + message = RFC822Message() + self._write_metadata(message) + return message + + def _write_metadata(self, message: RFC822Message) -> None: + """ + Return an RFC822 message with the metadata. + """ + for name, validator in self.__class__.__dict__.items(): + if isinstance(validator, _Validator) and name != "description": + value = getattr(self, name) + email_name = _RAW_TO_EMAIL_MAPPING[name] + if value is not None: + if email_name == "project-url": + for label, url in value.items(): + message[email_name] = f"{label}, {url}" + elif email_name == "keywords": + message[email_name] = ",".join(value) + elif email_name == "import-name" and value == []: + message[email_name] = "" + elif isinstance(value, list): + for item in value: + message[email_name] = str(item) + else: + message[email_name] = str(value) + + # The description is a special case because it is in the body of the message. + if self.description is not None: + message.set_payload(self.description) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py new file mode 100644 index 00000000000..5e774e4f0bb --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py @@ -0,0 +1,943 @@ +from __future__ import annotations + +import dataclasses +import logging +import re +from collections.abc import Mapping, Sequence +from dataclasses import dataclass +from datetime import datetime +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Protocol, + TypeVar, + cast, +) +from urllib.parse import unquote, urlparse + +from .markers import ( + Environment, + Marker, + _pep440_python_full_version, + default_environment, +) +from .specifiers import SpecifierSet +from .tags import create_compatible_tags_selector, sys_tags +from .utils import ( + NormalizedName, + is_normalized_name, + parse_sdist_filename, + parse_wheel_filename, +) +from .version import Version + +if TYPE_CHECKING: # pragma: no cover + from collections.abc import Collection, Iterator + from pathlib import Path + + from opentelemetry.agent._vendor.typing_extensions import Self + + from .tags import Tag + +_logger = logging.getLogger(__name__) + +__all__ = [ + "Package", + "PackageArchive", + "PackageDirectory", + "PackageSdist", + "PackageVcs", + "PackageWheel", + "Pylock", + "PylockSelectError", + "PylockUnsupportedVersionError", + "PylockValidationError", + "is_valid_pylock_path", +] + + +def __dir__() -> list[str]: + return __all__ + + +_T = TypeVar("_T") +_T2 = TypeVar("_T2") + + +class _FromMappingProtocol(Protocol): # pragma: no cover + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: ... + + +_FromMappingProtocolT = TypeVar("_FromMappingProtocolT", bound=_FromMappingProtocol) + + +_PYLOCK_FILE_NAME_RE = re.compile(r"^pylock\.([^.]+)\.toml$") + + +def is_valid_pylock_path(path: Path) -> bool: + """Check if the given path is a valid pylock file path.""" + return path.name == "pylock.toml" or bool(_PYLOCK_FILE_NAME_RE.match(path.name)) + + +def _toml_key(key: str) -> str: + return key.replace("_", "-") + + +def _toml_value(key: str, value: Any) -> Any: # noqa: ANN401 + if isinstance(value, (Version, Marker, SpecifierSet)): + return str(value) + if isinstance(value, Sequence) and key == "environments": + return [str(v) for v in value] + return value + + +def _toml_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]: + return { + _toml_key(key): _toml_value(key, value) + for key, value in data + if value is not None + } + + +def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None: + """Get a value from the dictionary and verify it's the expected type.""" + if (value := d.get(key)) is None: + return None + if not isinstance(value, expected_type) or ( + # Special case: bool is a subclass of int, but TOML distinguishes the two + expected_type is int and isinstance(value, bool) + ): + raise PylockValidationError( + f"Unexpected type {type(value).__name__} " + f"(expected {expected_type.__name__})", + context=key, + ) + return value + + +def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T: + """Get a required value from the dictionary and verify it's the expected type.""" + if (value := _get(d, expected_type, key)) is None: + raise _PylockRequiredKeyError(key) + return value + + +def _get_sequence( + d: Mapping[str, Any], expected_item_type: type[_T], key: str +) -> Sequence[_T] | None: + """Get a list value from the dictionary and verify it's the expected items type.""" + if (value := _get(d, Sequence, key)) is None: # type: ignore[type-abstract] + return None + if isinstance(value, (str, bytes)): + # special case: str and bytes are Sequences, but we want to reject it + raise PylockValidationError( + f"Unexpected type {type(value).__name__} (expected Sequence)", + context=key, + ) + for i, item in enumerate(value): + if not isinstance(item, expected_item_type): + raise PylockValidationError( + f"Unexpected type {type(item).__name__} " + f"(expected {expected_item_type.__name__})", + context=f"{key}[{i}]", + ) + return value + + +def _get_as( + d: Mapping[str, Any], + expected_type: type[_T], + target_type: Callable[[_T], _T2], + key: str, +) -> _T2 | None: + """Get a value from the dictionary, verify it's the expected type, + and convert to the target type. + + This assumes the target_type constructor accepts the value. + """ + if (value := _get(d, expected_type, key)) is None: + return None + try: + return target_type(value) + except Exception as e: + raise PylockValidationError(e, context=key) from e + + +def _get_required_as( + d: Mapping[str, Any], + expected_type: type[_T], + target_type: Callable[[_T], _T2], + key: str, +) -> _T2: + """Get a required value from the dict, verify it's the expected type, + and convert to the target type.""" + if (value := _get_as(d, expected_type, target_type, key)) is None: + raise _PylockRequiredKeyError(key) + return value + + +def _get_sequence_as( + d: Mapping[str, Any], + expected_item_type: type[_T], + target_item_type: Callable[[_T], _T2], + key: str, +) -> list[_T2] | None: + """Get list value from dictionary and verify expected items type.""" + if (value := _get_sequence(d, expected_item_type, key)) is None: + return None + result = [] + try: + for item in value: + typed_item = target_item_type(item) + result.append(typed_item) + except Exception as e: + raise PylockValidationError(e, context=f"{key}[{len(result)}]") from e + return result + + +def _get_object( + d: Mapping[str, Any], target_type: type[_FromMappingProtocolT], key: str +) -> _FromMappingProtocolT | None: + """Get a dictionary value from the dictionary and convert it to a dataclass.""" + if (value := _get(d, Mapping, key)) is None: # type: ignore[type-abstract] + return None + try: + return target_type._from_dict(value) + except Exception as e: + raise PylockValidationError(e, context=key) from e + + +def _get_sequence_of_objects( + d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str +) -> list[_FromMappingProtocolT] | None: + """Get a list value from the dictionary and convert its items to a dataclass.""" + if (value := _get_sequence(d, Mapping, key)) is None: # type: ignore[type-abstract] + return None + result: list[_FromMappingProtocolT] = [] + try: + for item in value: + typed_item = target_item_type._from_dict(item) + result.append(typed_item) + except Exception as e: + raise PylockValidationError(e, context=f"{key}[{len(result)}]") from e + return result + + +def _get_required_sequence_of_objects( + d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str +) -> Sequence[_FromMappingProtocolT]: + """Get a required list value from the dictionary and convert its items to a + dataclass.""" + if (result := _get_sequence_of_objects(d, target_item_type, key)) is None: + raise _PylockRequiredKeyError(key) + return result + + +def _validate_normalized_name(name: str) -> NormalizedName: + """Validate that a string is a NormalizedName.""" + if not is_normalized_name(name): + raise PylockValidationError(f"Name {name!r} is not normalized") + return NormalizedName(name) + + +def _validate_path_url(path: str | None, url: str | None) -> None: + if not path and not url: + raise PylockValidationError("path or url must be provided") + + +def _path_name(path: str | None) -> str | None: + if not path: + return None + # If the path is relative it MAY use POSIX-style path separators explicitly + # for portability + if "/" in path: + return path.rsplit("/", 1)[-1] + elif "\\" in path: + return path.rsplit("\\", 1)[-1] + else: + return path + + +def _url_name(url: str | None) -> str | None: + if not url: + return None + url_path = urlparse(url).path + # The last path component is percent-encoded, so decode it to the file name + return unquote(url_path.rsplit("/", 1)[-1]) + + +def _validate_hashes(hashes: Mapping[str, Any]) -> Mapping[str, Any]: + if not hashes: + raise PylockValidationError("At least one hash must be provided") + if not all(isinstance(hash_val, str) for hash_val in hashes.values()): + raise PylockValidationError("Hash values must be strings") + return hashes + + +class PylockValidationError(Exception): + """Raised when when input data is not spec-compliant.""" + + context: str | None = None + message: str + + def __init__( + self, + cause: str | Exception, + *, + context: str | None = None, + ) -> None: + if isinstance(cause, PylockValidationError): + if cause.context: + self.context = ( + f"{context}.{cause.context}" if context else cause.context + ) + else: + self.context = context + self.message = cause.message + else: + self.context = context + self.message = str(cause) + + def __str__(self) -> str: + if self.context: + return f"{self.message} in {self.context!r}" + return self.message + + +class _PylockRequiredKeyError(PylockValidationError): + def __init__(self, key: str) -> None: + super().__init__("Missing required value", context=key) + + +class PylockUnsupportedVersionError(PylockValidationError): + """Raised when encountering an unsupported `lock_version`.""" + + +class PylockSelectError(Exception): + """Base exception for errors raised by :meth:`Pylock.select`. + + .. versionadded:: 26.1 + """ + + +@dataclass(frozen=True, init=False) +class PackageVcs: + type: str + url: str | None = None + path: str | None = None + requested_revision: str | None = None + commit_id: str # type: ignore[misc] + subdirectory: str | None = None + + def __init__( + self, + *, + type: str, + url: str | None = None, + path: str | None = None, + requested_revision: str | None = None, + commit_id: str, + subdirectory: str | None = None, + ) -> None: + # In Python 3.10+ make dataclass kw_only=True and remove __init__ + object.__setattr__(self, "type", type) + object.__setattr__(self, "url", url) + object.__setattr__(self, "path", path) + object.__setattr__(self, "requested_revision", requested_revision) + object.__setattr__(self, "commit_id", commit_id) + object.__setattr__(self, "subdirectory", subdirectory) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + package_vcs = cls( + type=_get_required(d, str, "type"), + url=_get(d, str, "url"), + path=_get(d, str, "path"), + requested_revision=_get(d, str, "requested-revision"), + commit_id=_get_required(d, str, "commit-id"), + subdirectory=_get(d, str, "subdirectory"), + ) + _validate_path_url(package_vcs.path, package_vcs.url) + return package_vcs + + +@dataclass(frozen=True, init=False) +class PackageDirectory: + path: str + editable: bool | None = None + subdirectory: str | None = None + + def __init__( + self, + *, + path: str, + editable: bool | None = None, + subdirectory: str | None = None, + ) -> None: + # In Python 3.10+ make dataclass kw_only=True and remove __init__ + object.__setattr__(self, "path", path) + object.__setattr__(self, "editable", editable) + object.__setattr__(self, "subdirectory", subdirectory) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + return cls( + path=_get_required(d, str, "path"), + editable=_get(d, bool, "editable"), + subdirectory=_get(d, str, "subdirectory"), + ) + + +@dataclass(frozen=True, init=False) +class PackageArchive: + url: str | None = None + path: str | None = None + size: int | None = None + upload_time: datetime | None = None + hashes: Mapping[str, str] # type: ignore[misc] + subdirectory: str | None = None + + def __init__( + self, + *, + url: str | None = None, + path: str | None = None, + size: int | None = None, + upload_time: datetime | None = None, + hashes: Mapping[str, str], + subdirectory: str | None = None, + ) -> None: + # In Python 3.10+ make dataclass kw_only=True and remove __init__ + object.__setattr__(self, "url", url) + object.__setattr__(self, "path", path) + object.__setattr__(self, "size", size) + object.__setattr__(self, "upload_time", upload_time) + object.__setattr__(self, "hashes", hashes) + object.__setattr__(self, "subdirectory", subdirectory) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + package_archive = cls( + url=_get(d, str, "url"), + path=_get(d, str, "path"), + size=_get(d, int, "size"), + upload_time=_get(d, datetime, "upload-time"), + hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] + subdirectory=_get(d, str, "subdirectory"), + ) + _validate_path_url(package_archive.path, package_archive.url) + return package_archive + + +@dataclass(frozen=True, init=False) +class PackageSdist: + name: str | None = None + upload_time: datetime | None = None + url: str | None = None + path: str | None = None + size: int | None = None + hashes: Mapping[str, str] # type: ignore[misc] + + def __init__( + self, + *, + name: str | None = None, + upload_time: datetime | None = None, + url: str | None = None, + path: str | None = None, + size: int | None = None, + hashes: Mapping[str, str], + ) -> None: + # In Python 3.10+ make dataclass kw_only=True and remove __init__ + object.__setattr__(self, "name", name) + object.__setattr__(self, "upload_time", upload_time) + object.__setattr__(self, "url", url) + object.__setattr__(self, "path", path) + object.__setattr__(self, "size", size) + object.__setattr__(self, "hashes", hashes) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + package_sdist = cls( + name=_get(d, str, "name"), + upload_time=_get(d, datetime, "upload-time"), + url=_get(d, str, "url"), + path=_get(d, str, "path"), + size=_get(d, int, "size"), + hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] + ) + _validate_path_url(package_sdist.path, package_sdist.url) + return package_sdist + + @property + def filename(self) -> str: + """Get the filename of the sdist. + + .. versionadded:: 26.1 + """ + filename = self.name or _path_name(self.path) or _url_name(self.url) + if not filename: + raise PylockValidationError("Cannot determine sdist filename") + return filename + + +@dataclass(frozen=True, init=False) +class PackageWheel: + name: str | None = None + upload_time: datetime | None = None + url: str | None = None + path: str | None = None + size: int | None = None + hashes: Mapping[str, str] # type: ignore[misc] + + def __init__( + self, + *, + name: str | None = None, + upload_time: datetime | None = None, + url: str | None = None, + path: str | None = None, + size: int | None = None, + hashes: Mapping[str, str], + ) -> None: + # In Python 3.10+ make dataclass kw_only=True and remove __init__ + object.__setattr__(self, "name", name) + object.__setattr__(self, "upload_time", upload_time) + object.__setattr__(self, "url", url) + object.__setattr__(self, "path", path) + object.__setattr__(self, "size", size) + object.__setattr__(self, "hashes", hashes) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + package_wheel = cls( + name=_get(d, str, "name"), + upload_time=_get(d, datetime, "upload-time"), + url=_get(d, str, "url"), + path=_get(d, str, "path"), + size=_get(d, int, "size"), + hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] + ) + _validate_path_url(package_wheel.path, package_wheel.url) + return package_wheel + + @property + def filename(self) -> str: + """Get the filename of the wheel.""" + filename = self.name or _path_name(self.path) or _url_name(self.url) + if not filename: + raise PylockValidationError("Cannot determine wheel filename") + return filename + + +@dataclass(frozen=True, init=False) +class Package: + name: NormalizedName + version: Version | None = None + marker: Marker | None = None + requires_python: SpecifierSet | None = None + dependencies: Sequence[Mapping[str, Any]] | None = None + vcs: PackageVcs | None = None + directory: PackageDirectory | None = None + archive: PackageArchive | None = None + index: str | None = None + sdist: PackageSdist | None = None + wheels: Sequence[PackageWheel] | None = None + attestation_identities: Sequence[Mapping[str, Any]] | None = None + tool: Mapping[str, Any] | None = None + + def __init__( + self, + *, + name: NormalizedName, + version: Version | None = None, + marker: Marker | None = None, + requires_python: SpecifierSet | None = None, + dependencies: Sequence[Mapping[str, Any]] | None = None, + vcs: PackageVcs | None = None, + directory: PackageDirectory | None = None, + archive: PackageArchive | None = None, + index: str | None = None, + sdist: PackageSdist | None = None, + wheels: Sequence[PackageWheel] | None = None, + attestation_identities: Sequence[Mapping[str, Any]] | None = None, + tool: Mapping[str, Any] | None = None, + ) -> None: + # In Python 3.10+ make dataclass kw_only=True and remove __init__ + object.__setattr__(self, "name", name) + object.__setattr__(self, "version", version) + object.__setattr__(self, "marker", marker) + object.__setattr__(self, "requires_python", requires_python) + object.__setattr__(self, "dependencies", dependencies) + object.__setattr__(self, "vcs", vcs) + object.__setattr__(self, "directory", directory) + object.__setattr__(self, "archive", archive) + object.__setattr__(self, "index", index) + object.__setattr__(self, "sdist", sdist) + object.__setattr__(self, "wheels", wheels) + object.__setattr__(self, "attestation_identities", attestation_identities) + object.__setattr__(self, "tool", tool) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + package = cls( + name=_get_required_as(d, str, _validate_normalized_name, "name"), + version=_get_as(d, str, Version, "version"), + requires_python=_get_as(d, str, SpecifierSet, "requires-python"), + dependencies=_get_sequence(d, Mapping, "dependencies"), # type: ignore[type-abstract] + marker=_get_as(d, str, Marker, "marker"), + vcs=_get_object(d, PackageVcs, "vcs"), + directory=_get_object(d, PackageDirectory, "directory"), + archive=_get_object(d, PackageArchive, "archive"), + index=_get(d, str, "index"), + sdist=_get_object(d, PackageSdist, "sdist"), + wheels=_get_sequence_of_objects(d, PackageWheel, "wheels"), + attestation_identities=_get_sequence(d, Mapping, "attestation-identities"), # type: ignore[type-abstract] + tool=_get(d, Mapping, "tool"), # type: ignore[type-abstract] + ) + distributions = bool(package.sdist) + len(package.wheels or []) + direct_urls = ( + bool(package.vcs) + bool(package.directory) + bool(package.archive) + ) + if distributions > 0 and direct_urls > 0: + raise PylockValidationError( + "None of vcs, directory, archive must be set if sdist or wheels are set" + ) + if distributions == 0 and direct_urls != 1: + raise PylockValidationError( + "Exactly one of vcs, directory, archive must be set " + "if sdist and wheels are not set" + ) + for i, wheel in enumerate(package.wheels or []): + try: + (name, version, _, _) = parse_wheel_filename(wheel.filename) + except Exception as e: + raise PylockValidationError( + f"Invalid wheel filename {wheel.filename!r}", + context=f"wheels[{i}]", + ) from e + if name != package.name: + raise PylockValidationError( + f"Name in {wheel.filename!r} is not consistent with " + f"package name {package.name!r}", + context=f"wheels[{i}]", + ) + if package.version and version != package.version: + raise PylockValidationError( + f"Version in {wheel.filename!r} is not consistent with " + f"package version {str(package.version)!r}", + context=f"wheels[{i}]", + ) + if package.sdist: + try: + name, version = parse_sdist_filename(package.sdist.filename) + except Exception as e: + raise PylockValidationError( + f"Invalid sdist filename {package.sdist.filename!r}", + context="sdist", + ) from e + if name != package.name: + raise PylockValidationError( + f"Name in {package.sdist.filename!r} is not consistent with " + f"package name {package.name!r}", + context="sdist", + ) + if package.version and version != package.version: + raise PylockValidationError( + f"Version in {package.sdist.filename!r} is not consistent with " + f"package version {str(package.version)!r}", + context="sdist", + ) + try: + for i, attestation_identity in enumerate( # noqa: B007 + package.attestation_identities or [] + ): + _get_required(attestation_identity, str, "kind") + except Exception as e: + raise PylockValidationError( + e, context=f"attestation-identities[{i}]" + ) from e + return package + + @property + def is_direct(self) -> bool: + return not (self.sdist or self.wheels) + + +@dataclass(frozen=True, init=False) +class Pylock: + """A class representing a pylock file.""" + + lock_version: Version + environments: Sequence[Marker] | None = None + requires_python: SpecifierSet | None = None + extras: Sequence[NormalizedName] | None = None + dependency_groups: Sequence[str] | None = None + default_groups: Sequence[str] | None = None + created_by: str # type: ignore[misc] + packages: Sequence[Package] # type: ignore[misc] + tool: Mapping[str, Any] | None = None + + def __init__( + self, + *, + lock_version: Version, + environments: Sequence[Marker] | None = None, + requires_python: SpecifierSet | None = None, + extras: Sequence[NormalizedName] | None = None, + dependency_groups: Sequence[str] | None = None, + default_groups: Sequence[str] | None = None, + created_by: str, + packages: Sequence[Package], + tool: Mapping[str, Any] | None = None, + ) -> None: + # In Python 3.10+ make dataclass kw_only=True and remove __init__ + object.__setattr__(self, "lock_version", lock_version) + object.__setattr__(self, "environments", environments) + object.__setattr__(self, "requires_python", requires_python) + object.__setattr__(self, "extras", extras) + object.__setattr__(self, "dependency_groups", dependency_groups) + object.__setattr__(self, "default_groups", default_groups) + object.__setattr__(self, "created_by", created_by) + object.__setattr__(self, "packages", packages) + object.__setattr__(self, "tool", tool) + + @classmethod + def _from_dict(cls, d: Mapping[str, Any]) -> Self: + pylock = cls( + lock_version=_get_required_as(d, str, Version, "lock-version"), + environments=_get_sequence_as(d, str, Marker, "environments"), + extras=_get_sequence_as(d, str, _validate_normalized_name, "extras"), + dependency_groups=_get_sequence(d, str, "dependency-groups"), + default_groups=_get_sequence(d, str, "default-groups"), + created_by=_get_required(d, str, "created-by"), + requires_python=_get_as(d, str, SpecifierSet, "requires-python"), + packages=_get_required_sequence_of_objects(d, Package, "packages"), + tool=_get(d, Mapping, "tool"), # type: ignore[type-abstract] + ) + if not Version("1") <= pylock.lock_version < Version("2"): + raise PylockUnsupportedVersionError( + f"pylock version {pylock.lock_version} is not supported" + ) + if pylock.lock_version > Version("1.0"): + _logger.warning( + "pylock minor version %s is not supported", pylock.lock_version + ) + return pylock + + @classmethod + def from_dict(cls, d: Mapping[str, Any], /) -> Self: + """Create and validate a Pylock instance from a TOML dictionary. + + Raises :class:`PylockValidationError` if the input data is not + spec-compliant. + """ + return cls._from_dict(d) + + def to_dict(self) -> Mapping[str, Any]: + """Convert the Pylock instance to a TOML dictionary.""" + return dataclasses.asdict(self, dict_factory=_toml_dict_factory) + + def validate(self) -> None: + """Validate the Pylock instance against the specification. + + Raises :class:`PylockValidationError` otherwise.""" + self.from_dict(self.to_dict()) + + def select( + self, + *, + environment: Environment | None = None, + tags: Sequence[Tag] | None = None, + extras: Collection[str] | None = None, + dependency_groups: Collection[str] | None = None, + prefer_sdist_predicate: Callable[[NormalizedName], bool] | None = None, + ) -> Iterator[ + tuple[ + Package, + PackageVcs + | PackageDirectory + | PackageArchive + | PackageWheel + | PackageSdist, + ] + ]: + """Select what to install from the lock file. + + The *environment* and *tags* parameters represent the environment being + selected for. If unspecified, ``packaging.markers.default_environment()`` and + ``packaging.tags.sys_tags()`` are used. + + The *extras* parameter represents the extras to install. + + The *dependency_groups* parameter represents the groups to install. If + unspecified, the default groups are used. + + The *prefer_sdist_predicate* parameter is called for packages with a source + distribution. If it returns ``True``, the source distribution is selected + before attempting wheel compatibility. If no source distribution is + available, wheel selection proceeds as usual without calling the predicate. + + This method must be used on valid Pylock instances (i.e. one obtained + from :meth:`Pylock.from_dict` or if constructed manually, after calling + :meth:`Pylock.validate`). + + .. versionadded:: 26.1 + + .. versionchanged:: 26.3 + Added the *prefer_sdist_predicate* parameter. + """ + compatible_tags_selector = create_compatible_tags_selector( + tags if tags is not None else sys_tags() + ) + + # #. Gather the extras and dependency groups to install and set ``extras`` and + # ``dependency_groups`` for marker evaluation, respectively. + # + # #. ``extras`` SHOULD be set to the empty set by default. + # #. ``dependency_groups`` SHOULD be the set created from + # :ref:`pylock-default-groups` by default. + env = cast( + "dict[str, str | frozenset[str]]", + dict( + environment or {}, # Marker.evaluate will fill-up + extras=frozenset(extras or []), + dependency_groups=frozenset( + (self.default_groups or []) + if dependency_groups is None # to allow selecting no group + else dependency_groups + ), + ), + ) + env_python_full_version = _pep440_python_full_version( + environment["python_full_version"] + if environment + else default_environment()["python_full_version"] + ) + + # #. Check if the metadata version specified by :ref:`pylock-lock-version` is + # supported; an error or warning MUST be raised as appropriate. + # Covered by lock.validate() which is a precondition for this method. + + # #. If :ref:`pylock-requires-python` is specified, check that the environment + # being installed for meets the requirement; an error MUST be raised if it is + # not met. + if self.requires_python and not self.requires_python.contains( + env_python_full_version, + ): + raise PylockSelectError( + f"python_full_version {env_python_full_version!r} " + f"in provided environment does not satisfy the Python version " + f"requirement {str(self.requires_python)!r}" + ) + + # #. If :ref:`pylock-environments` is specified, check that at least one of the + # environment marker expressions is satisfied; an error MUST be raised if no + # expression is satisfied. + if self.environments: + for env_marker in self.environments: + if env_marker.evaluate( + cast("dict[str, str]", environment or {}), context="requirement" + ): + break + else: + raise PylockSelectError( + "Provided environment does not satisfy any of the " + "environments specified in the lock file" + ) + + # #. For each package listed in :ref:`pylock-packages`: + selected_packages_by_name: dict[str, tuple[int, Package]] = {} + for package_index, package in enumerate(self.packages): + # #. If :ref:`pylock-packages-marker` is specified, check if it is + # satisfied;if it isn't, skip to the next package. + if package.marker and not package.marker.evaluate(env, context="lock_file"): + continue + + # #. If :ref:`pylock-packages-requires-python` is specified, check if it is + # satisfied; an error MUST be raised if it isn't. + if package.requires_python and not package.requires_python.contains( + env_python_full_version, + ): + raise PylockSelectError( + f"python_full_version {env_python_full_version!r} " + f"in provided environment does not satisfy the Python version " + f"requirement {str(package.requires_python)!r} for package " + f"{package.name!r} at packages[{package_index}]" + ) + + # #. Check that no other conflicting instance of the package has been slated + # to be installed; an error about the ambiguity MUST be raised otherwise. + if package.name in selected_packages_by_name: + raise PylockSelectError( + f"Multiple packages with the name {package.name!r} are " + f"selected at packages[{package_index}] and " + f"packages[{selected_packages_by_name[package.name][0]}]" + ) + + # #. Check that the source of the package is specified appropriately (i.e. + # there are no conflicting sources in the package entry); + # an error MUST be raised if any issues are found. + # Covered by lock.validate() which is a precondition for this method. + + # #. Add the package to the set of packages to install. + selected_packages_by_name[package.name] = (package_index, package) + + # #. For each package to be installed: + for package_index, package in selected_packages_by_name.values(): + # - If :ref:`pylock-packages-vcs` is set: + if package.vcs is not None: + yield package, package.vcs + + # - Else if :ref:`pylock-packages-directory` is set: + elif package.directory is not None: + yield package, package.directory + + # - Else if :ref:`pylock-packages-archive` is set: + elif package.archive is not None: + yield package, package.archive + + # - Else if source preference selects an available + # :ref:`pylock-packages-sdist`: + elif ( + package.sdist is not None + and prefer_sdist_predicate is not None + and prefer_sdist_predicate(package.name) + ): + yield package, package.sdist + + # - Else if there are entries for :ref:`pylock-packages-wheels`: + elif package.wheels: + # #. Look for the appropriate wheel file based on + # :ref:`pylock-packages-wheels-name`; if one is not found then move + # on to :ref:`pylock-packages-sdist` or an error MUST be raised about + # a lack of source for the project. + best_wheel = next( + compatible_tags_selector( + (wheel, parse_wheel_filename(wheel.filename)[-1]) + for wheel in package.wheels + ), + None, + ) + if best_wheel: + yield package, best_wheel + elif package.sdist is not None: + yield package, package.sdist + else: + raise PylockSelectError( + f"No wheel found matching the provided tags " + f"for package {package.name!r} " + f"at packages[{package_index}], " + f"and no sdist available as a fallback" + ) + + # - Else if no :ref:`pylock-packages-wheels` file is found or + # :ref:`pylock-packages-sdist` is solely set: + elif package.sdist is not None: + yield package, package.sdist + + else: + # Covered by lock.validate() which is a precondition for this method. + raise NotImplementedError # pragma: no cover diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py new file mode 100644 index 00000000000..8144a65c4d2 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py @@ -0,0 +1,2067 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +"""Public :class:`VersionRange` API. + +A set-algebra view of the versions accepted by a +:class:`~packaging.specifiers.SpecifierSet`. Ranges support intersection, +union, complement, and difference; membership and filtering match the +originating specifier set; and conversion back to a +:class:`~packaging.specifiers.SpecifierSet` is available where a PEP 440 form +exists. + +.. testsetup:: + + from packaging.ranges import VersionRange + from packaging.specifiers import SpecifierSet + from packaging.version import Version +""" + +from __future__ import annotations + +import enum +import typing +from typing import ( + TYPE_CHECKING, + Any, + TypeVar, + Union, +) + +from ._ranges import ( + FULL_RANGE, + MIN_VERSION, + NEG_INF, + POS_INF, + BoundaryKind, + BoundaryVersion, + LowerBound, + UpperBound, + coerce_version, + filter_by_ranges, + intersect_ranges, + least_version_above, + matches_bounds_only, + range_is_empty, + ranges_are_prerelease_only, + trim_release, +) +from .version import Version + +if TYPE_CHECKING: + from collections.abc import Callable, Iterable, Iterator, Sequence + + from ._ranges import Interval + from .specifiers import SpecifierSet + + +__all__ = ["VersionRange"] + +T = TypeVar("T") +UnparsedVersion = Union[Version, str] +UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion) + +#: The most ``!=`` exclusion fragments (``!=V`` points or ``!=P.*`` prefixes) +#: that :meth:`VersionRange.to_specifier_set` will materialize to spell a +#: single gap or run. Every site that expands a version-number-driven chain +#: charges it against this cap, and chains that spell one gap together share +#: it (see :func:`_decompose_dev0_gap` and :func:`_encode_gap`), +#: so no gap ever materializes more than this many exclusions. Past the cap +#: the recovery returns ``None`` rather than emit the unbounded chain a range +#: such as ``==5.* | ==1000000.*`` would otherwise drive. +_MAX_EXCLUSION_RUN = 128 + + +class _SetOp(enum.Enum): + """The binary set operation ``_combine_literals`` resolves over ``===`` literals.""" + + INTERSECTION = enum.auto() + UNION = enum.auto() + DIFFERENCE = enum.auto() + + +def __dir__() -> list[str]: + return __all__ + + +# Range algebra: intersection and the empty-interval test live in the engine +# (``intersect_ranges`` / ``range_is_empty``); union and complement are only +# needed here, so they live in this module. + + +def _union_ranges( + left: Sequence[Interval], + right: Sequence[Interval], +) -> list[Interval]: + """Union two sorted, non-overlapping interval lists. + + A linear merge over the two pre-sorted inputs followed by a single + coalescing pass: adjacent or overlapping intervals collapse so the result + is itself sorted and non-overlapping. + """ + if not left: + return list(right) + if not right: + return list(left) + + merged_input: list[Interval] = [] + left_index = right_index = 0 + while left_index < len(left) and right_index < len(right): + if left[left_index][0] <= right[right_index][0]: + merged_input.append(left[left_index]) + left_index += 1 + else: + merged_input.append(right[right_index]) + right_index += 1 + merged_input.extend(left[left_index:]) + merged_input.extend(right[right_index:]) + + merged: list[Interval] = [merged_input[0]] + for lower, upper in merged_input[1:]: + prev_lower, prev_upper = merged[-1] + + if ( + prev_upper.version is None + or lower.version is None + or prev_upper.version > lower.version + ): + overlaps = True + elif prev_upper.version == lower.version: + overlaps = prev_upper.inclusive or lower.inclusive + else: + # An ordering gap may still hold no version when the two bounds + # straddle a synthetic boundary; merge across an empty gap to + # stay canonical. + gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive) + gap_upper = UpperBound(lower.version, not lower.inclusive) + overlaps = range_is_empty(gap_lower, gap_upper) + + if overlaps: + merged[-1] = (prev_lower, max(prev_upper, upper)) + else: + merged.append((lower, upper)) + + return merged + + +def _complement_ranges(ranges: Sequence[Interval]) -> list[Interval]: + """Complement a sorted, non-overlapping interval list. + + Yields the gaps between intervals plus a leading gap before the first and + a trailing gap after the last. Bound inclusivity flips so that + complement-of-complement round-trips back to the input. + """ + if not ranges: + return list(FULL_RANGE) + + result: list[Interval] = [] + prev_upper: UpperBound | None = None + + for lower, upper in ranges: + if prev_upper is None: + # Leading gap below the first interval. Every range reaching here is + # floor-canonical: ``_canonical_floor`` has already folded an + # inclusive lower at or below ``0.dev0`` into ``-inf``. So a finite + # first lower always leaves a non-empty gap down to ``-inf``, while a + # ``-inf`` lower leaves no leading gap at all. + if lower.version is not None: + gap_upper = UpperBound(lower.version, not lower.inclusive) + result.append((NEG_INF, gap_upper)) + else: + gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive) + gap_upper = UpperBound(lower.version, not lower.inclusive) + # Input intervals are canonical (sorted, disjoint, non-touching), + # so the gap between two of them always holds at least one version. + result.append((gap_lower, gap_upper)) + prev_upper = upper + + # The empty-input early return guarantees the loop ran. + assert prev_upper is not None + if prev_upper.version is not None: + gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive) + result.append((gap_lower, POS_INF)) + + return result + + +def _canonical_floor(bounds: tuple[Interval, ...]) -> tuple[Interval, ...]: + """Collapse the PEP 440 floor in a sorted interval list. + + Only the first interval can touch ``0.dev0`` (the minimum version). An + inclusive lower at or below it admits everything below, the same as + ``-inf``, so ``>=0.dev0`` becomes the one canonical full range. An + exclusive upper at or below it leaves the interval empty, so it is dropped. + """ + if not bounds: + return bounds + + lower, upper = bounds[0] + if range_is_empty(NEG_INF, upper): + return bounds[1:] + + if ( + lower.inclusive + and isinstance(lower.version, Version) + and lower.version <= MIN_VERSION + ): + return ((NEG_INF, upper), *bounds[1:]) + + return bounds + + +def _predecessor_boundary(version: Version) -> BoundaryVersion | None: + """The boundary whose least successor is *version*, or ``None``. + + Inverse of :func:`~packaging._ranges.least_version_above`. A plain version + that is exactly such a successor (``1.0a2.dev0`` sits just above + ``AFTER_POSTS(1.0a1)``) folds back to that boundary, so ``>=1.0a2.dev0`` and + ``>1.0a1`` share one form. The proposed boundary is confirmed by + round-tripping through ``least_version_above``. + """ + # Only a least successor carries a dev segment, so nothing else can fold. + if version.dev is None: + return None + + candidate: BoundaryVersion | None = None + if version.pre is not None and version.dev == 0 and version.post is None: + # 1.0a2.dev0 -> AFTER_POSTS(1.0a1) + kind, number = version.pre + if number >= 1: + candidate = BoundaryVersion( + version.__replace__(pre=(kind, number - 1), dev=None), + BoundaryKind.AFTER_POSTS, + ) + elif version.dev >= 1: + # 1.0.dev3 -> AFTER_LOCALS(1.0.dev2) + candidate = BoundaryVersion( + version.__replace__(dev=version.dev - 1), BoundaryKind.AFTER_LOCALS + ) + elif version.dev == 0 and version.post is not None: + # 1.0.post1.dev0 -> AFTER_LOCALS(1.0.post0); 1.0.post0.dev0 -> AFTER_LOCALS(1.0) + base = ( + version.__replace__(post=None, dev=None) + if version.post == 0 + else version.__replace__(post=version.post - 1, dev=None) + ) + candidate = BoundaryVersion(base, BoundaryKind.AFTER_LOCALS) + + if candidate is not None and least_version_above(candidate) == version: + return candidate + return None + + +def _canonicalize(bounds: tuple[Interval, ...]) -> tuple[Interval, ...]: + """Fold least-successor bounds to their boundary form. + + ``>=1.0a2.dev0`` and ``>1.0a1`` denote the same set, so both must reduce to + one representation for ``==`` and ``hash`` to agree. An inclusive lower or + exclusive upper sitting on a boundary's least successor becomes that + boundary; the engine's emptiness check has already dropped the synthetic + gaps such intervals would otherwise leave. + """ + result: list[Interval] = [] + for lower, upper in bounds: + new_lower, new_upper = lower, upper + + if isinstance(lower.version, Version) and lower.inclusive: + boundary = _predecessor_boundary(lower.version) + if boundary is not None: + new_lower = LowerBound(boundary, inclusive=False) + + if isinstance(upper.version, Version) and not upper.inclusive: + boundary = _predecessor_boundary(upper.version) + if boundary is not None: + new_upper = UpperBound(boundary, inclusive=True) + + result.append((new_lower, new_upper)) + return tuple(result) + + +def _struct_admits( + bounds: tuple[Interval, ...], admit_arbitrary: bool, literal: str +) -> bool: + """True when the bounds (plus arbitrary admission) admit ``literal``. + + Skips the explicit admit/reject sets, which the caller layers on top. A + non-version string matches via ``admit_arbitrary`` only on full bounds; + on narrower bounds the flag is metadata only. + """ + parsed = coerce_version(literal) + if parsed is None: + return admit_arbitrary and bounds == FULL_RANGE + + return matches_bounds_only(bounds, parsed) + + +# Repr helpers: + + +def _bound_version_str(value: BoundaryVersion | Version) -> str: + """Printout for a bound's inner value, kind-tagged for boundaries.""" + if isinstance(value, BoundaryVersion): + return f"{value.version}[{value.kind.name}]" + return str(value) + + +def _format_lower(bound: LowerBound) -> str: + if bound.version is None: + return "(-inf" + bracket = "[" if bound.inclusive else "(" + return f"{bracket}{_bound_version_str(bound.version)}" + + +def _format_upper(bound: UpperBound) -> str: + if bound.version is None: + return "+inf)" + bracket = "]" if bound.inclusive else ")" + return f"{_bound_version_str(bound.version)}{bracket}" + + +def _format_intervals(intervals: Sequence[Interval]) -> str: + """Render a sorted interval list as ``lower, upper | lower, upper``.""" + return " | ".join( + f"{_format_lower(lower)}, {_format_upper(upper)}" for lower, upper in intervals + ) + + +# ``to_specifier_set`` recovery: encode a range's interval list back into +# specifier fragments. Each helper returns ``None`` when its shape has no +# PEP 440 form. The ``keep_dev0`` argument threaded through is a spelling +# mode, not a pre-release policy: false emits a prerelease-free form (no +# synthetic ``.dev0``, so the recovered range has an empty opt-in region), +# true keeps the ``.dev0`` markers (so the range opts its bounds in). +# ``to_specifier_set`` encodes in both modes and keeps whichever round-trips. +# +# Bound and interval encoding: turn one interval's bounds into fragments. + + +def _is_dev0_version(version: Version) -> bool: + """True when version is exactly ``X[.Y]*.dev0`` (the shape `` list[str] | None: + """A prerelease-free spelling for an inclusive ``[version`` lower, or ``None``. + + Several ``[V`` lowers come from an operator whose own spelling carries no + synthetic ``.dev0``. Recovering that spelling gives the range an empty opt-in + region, so it is offered in the prerelease-free spelling mode (see + :meth:`VersionRange.to_specifier_set`). + """ + if version.dev != 0 or version.pre is not None or version.local is not None: + return None + + # ``[B.post(k).dev0`` is the lower ``>B.post(k-1)`` builds (k >= 1). + if version.post is not None: + if version.post < 1: + return None + return [f">{version.__replace__(post=version.post - 1, dev=None)}"] + + # ``[F.dev0`` is family F's base. The prefix P just below F has + # ``==P.* == [P.dev0, F.dev0)``, so ``>=P,!=P.*`` lands exactly on ``[F.dev0``. + family = trim_release(version.release) + last = family[-1] + if last < 1: + return None + + below_release = (*family[:-1], last - 1) + below = Version.from_parts(epoch=version.epoch, release=below_release) + + # At the epoch-0 floor ``==P.*`` already reaches ``0.dev0``, so the ``>=P`` + # half is redundant: ``[1.dev0, +inf)`` is plain ``!=0.*``. + if version.epoch == 0 and not any(below_release): + return [f"!={below}.*"] + + return [f">={below}", f"!={below}.*"] + + +def _epoch_floor_lower( + lower: LowerBound, upper: UpperBound +) -> tuple[Version, int, bool] | None: + """The ``E!0`` family of a lower sitting on an epoch>0 zero-family floor. + + An epoch>0 zero-family base such as ``1!0.dev0`` has no ``>=P,!=P.*`` spelling + since no version sorts below ``E!0`` within the epoch. While the interval + stays within ``==E!0.*`` it is that wildcard, trimmed by the upper and with a + leading ``.dev`` run excluded: an ``AFTER_LOCALS(E!0.dev(k))`` lower drops + ``E!0.dev0..E!0.dev(k)``, a plain inclusive ``E!0.dev0`` lower drops none. + Returns the ``E!0`` family, how many leading ``.dev`` releases to exclude, and + whether the upper sits at the family cap (so ``==E!0.*`` needs no upper), else + ``None``. + """ + version = lower.version + if isinstance(version, BoundaryVersion): + if version.kind != BoundaryKind.AFTER_LOCALS: + return None + version = version.version + if version.dev is None: + return None + excluded_devs = version.dev + 1 + elif isinstance(version, Version) and lower.inclusive: + # A plain inclusive lower only reaches the floor as ``>=E!0.dev0``; + # higher ``.dev`` would have canonicalized to an AFTER_LOCALS boundary. + if version.dev != 0: + return None + excluded_devs = 0 + else: + return None + + # Only the bare ``E!0`` floor of a non-zero epoch qualifies. + if version.epoch == 0: + return None + if version.pre is not None or version.post is not None or version.local is not None: + return None + if any(trim_release(version.release)): + return None + + # ``==E!0.*`` spans ``[E!0.dev0, E!1.dev0)``; it fits only below that cap. + next_family = Version.from_parts(epoch=version.epoch, release=(1,), dev=0) + cap = UpperBound(next_family, False) + if upper > cap: + return None + + family = Version.from_parts(epoch=version.epoch, release=(0,)) + return family, excluded_devs, upper == cap + + +def _dev_family_anchor(family: Version) -> list[str] | None: + """Prerelease-free fragments for ``[family, ..)``, or ``None`` if it has none. + + ``family`` is an ``X.dev0``. The floor gives ``[]`` (every version); a release + base its ``_clean_lower`` family-floor spelling (``!=0.*`` ...); an ``X.post0`` + base ``>=X,!=X``. A pre-release base has no prerelease-free spelling. + """ + if family <= MIN_VERSION: + return [] + clean = _clean_lower(family) + if clean is not None: + return clean + if family.pre is None and family.post == 0: + base = family.__replace__(post=None, dev=None) + return [f">={base}", f"!={base}"] + return None + + +def _encode_lower(lower: LowerBound, keep_dev0: bool) -> list[str] | None: + """Encode a lower bound as specifier fragments, or ``None``. + + ``[]`` for ``-inf``. An ``AFTER_POSTS(V)`` lower is ``>V``. An + ``AFTER_LOCALS(V)`` lower is the set ``[successor, ..)`` and emits ``>=V,!=V``, + except in the prerelease-free spelling mode (``keep_dev0`` false), where it + recovers a spelling with no synthetic ``.dev0`` when one exists: + ``>3.8.post1`` for a post release, or a dev family's anchor plus the dev run + up to V for a ``.dev`` release. + """ + lower_version = lower.version + if lower_version is None: + return [] + + if isinstance(lower_version, BoundaryVersion): + if lower_version.kind == BoundaryKind.AFTER_POSTS: + # AFTER_POSTS only ever appears as an exclusive ``>V`` lower. + return [f">{lower_version.version}"] + inner = lower_version.version + if inner <= MIN_VERSION: + # The ``(-inf, V)`` side was dropped at the floor, so the lone + # ``(AFTER_LOCALS(0.dev0), +inf)`` interval is exactly ``!=0.dev0``. + return [f"!={inner}"] + # An ``(AFTER_LOCALS(V), ..)`` lower is the set ``[successor, ..)``. In + # the prerelease-free mode, recover a spelling with no synthetic ``.dev0`` + # so the range's opt-in region stays empty. + if not keep_dev0: + if inner.dev is not None: + # A ``.dev`` V makes ``[successor, ..)`` its dev family's + # prerelease-free anchor minus the finite dev run up to ``V`` + # (e.g. ``>=1.0,!=1.0,!=1.0.post0.dev0``), carrying no synthetic + # ``.dev0``. + family = inner.__replace__(dev=0) + anchor = _dev_family_anchor(family) + if anchor is not None: + if inner.dev + 1 > _MAX_EXCLUSION_RUN: + return None + run = [ + f"!={family.__replace__(dev=d)}" for d in range(inner.dev + 1) + ] + return anchor + run + else: + # A ``.post`` release recovers its prerelease-free ``>`` spelling + # from the successor (``>3.8.post1`` for ``AFTER_LOCALS(3.8.post1)``). + successor = least_version_above(lower_version) + clean = _clean_lower(successor) if successor is not None else None + if clean is not None: + return clean + # Otherwise it is ``[V, ..)`` minus V's local family, i.e. ``>=V,!=V``. + # The prerelease-free recoveries above have already returned in that mode; + # a residual ``.dev`` V here opts pre-releases in, so this spelling round + # trips only for a range whose opt-in region wants it. + return [f">={inner}", f"!={inner}"] + + if not lower.inclusive: + return None + + # In the prerelease-free mode a ``.dev0`` lower prefers its clean spelling. + if not keep_dev0: + clean = _clean_lower(lower_version) + if clean is not None: + return clean + return [f">={lower_version}"] + + +def _encode_upper(upper: UpperBound, keep_dev0: bool) -> list[str] | None: + """Encode an upper bound as specifier fragments, or ``None``. + + ``[]`` for ``+inf``. In the prerelease-free spelling mode (``keep_dev0`` + false) the `` Version | None: + """If ``[lower, upper)`` is the ``==V.*`` shape, return ``V``.""" + if isinstance(lower.version, BoundaryVersion) or isinstance( + upper.version, BoundaryVersion + ): + return None + if lower.version is None or upper.version is None: + return None + if not lower.inclusive or upper.inclusive: + return None + if not (_is_dev0_version(lower.version) and _is_dev0_version(upper.version)): + return None + if lower.version.epoch != upper.version.epoch: + return None + + lower_release = trim_release(lower.version.release) + upper_release = trim_release(upper.version.release) + padded_length = max(len(lower_release), len(upper_release)) + assert padded_length > 0 + lower_release += (0,) * (padded_length - len(lower_release)) + upper_release += (0,) * (padded_length - len(upper_release)) + + if lower_release[:-1] != upper_release[:-1]: + return None + + # A genuine ``==V.*`` spans one family: the upper is exactly the next prefix. + # A wider span like ``[3.8.dev0, 3.14.dev0)`` shares the prefix but is not a + # single wildcard, so it falls through to the generic ``>=...,<...`` form. + if upper_release[-1] != lower_release[-1] + 1: + return None + + return lower.version.__replace__(release=lower_release, dev=None) + + +def _encode_interval( + lower: LowerBound, upper: UpperBound, keep_dev0: bool +) -> list[str] | None: + """Encode one interval as specifier fragments, or ``None``. + + Special-cases the ``==V`` singleton (``[V, AFTER_LOCALS(V)]`` for a plain + ``V``, and ``[V+local, V+local]`` for a local one) and the ``==V.*`` shape + so the fragment is one equality rather than a bound pair. + """ + # ``[V+local, V+local]`` (an inclusive local point) is the singleton ``==V+local``. + if ( + lower.version is not None + and upper.version is not None + and not isinstance(lower.version, BoundaryVersion) + and not isinstance(upper.version, BoundaryVersion) + and lower.inclusive + and upper.inclusive + and lower.version == upper.version + and lower.version.local is not None + ): + return [f"=={lower.version}"] + + # ``[V, AFTER_LOCALS(V)]`` (V without a local) is the singleton ``==V``, + # which also matches V's local family: one equality, not ``>=V,<=V``. + if ( + isinstance(lower.version, Version) + and lower.inclusive + and upper.inclusive + and isinstance(upper.version, BoundaryVersion) + and upper.version.kind == BoundaryKind.AFTER_LOCALS + and upper.version.version == lower.version + ): + return [f"=={lower.version}"] + + wildcard = _detect_equal_wildcard(lower, upper) + if wildcard is not None: + return [f"=={wildcard}.*"] + + # A ``[E!0.dev0`` lower has no prerelease-free ``>=`` spelling; within its own + # family it is ``==E!0.*`` trimmed by the upper. + floor = _epoch_floor_lower(lower, upper) if not keep_dev0 else None + if floor is not None: + family, excluded_devs, upper_at_cap = floor + if excluded_devs > _MAX_EXCLUSION_RUN: + return None + parts = [f"=={family}.*"] + parts.extend(f"!={family.__replace__(dev=d)}" for d in range(excluded_devs)) + + # ``==E!0.*`` already caps at the next family; add the upper only if tighter. + if not upper_at_cap: + upper_parts = _encode_upper(upper, keep_dev0) + if upper_parts is None: + return None + parts.extend(upper_parts) + + return parts + + lower_parts = _encode_lower(lower, keep_dev0) + if lower_parts is None: + return None + + upper_parts = _encode_upper(upper, keep_dev0) + if upper_parts is None: + return None + + return lower_parts + upper_parts + + +# Gap encoding: spell the gap between two adjacent intervals as exclusions. + + +def _detect_not_equal( + left_upper: UpperBound, right_lower: LowerBound +) -> list[Version] | None: + """If the gap between two intervals is a ``!=V`` chain, list its points. + + A plain exclusive left upper names the first excluded V directly; an inclusive + boundary left upper names it via its least successor. Adjacent exclusions + (``V`` and its immediate successors) share a single gap spanning a contiguous + dev run, so one gap can name a short chain: ``!=1.0,!=1.0.post0.dev0`` is one + gap from ``1.0`` up to ``AFTER_LOCALS(1.0.post0.dev0)``. + """ + if isinstance(left_upper.version, BoundaryVersion): + # A boundary upper is always inclusive; its least successor is the first + # excluded V (``None`` for a final AFTER_POSTS, which names no point). + first = least_version_above(left_upper.version) + if first is None: + return None + elif left_upper.version is None or left_upper.inclusive: + return None + else: + first = left_upper.version + + if not isinstance(right_lower.version, BoundaryVersion): + if ( + right_lower.version is not None + and not right_lower.inclusive + and right_lower.version == first + and first.local is not None + ): + return [first] + return None + + if right_lower.version.kind != BoundaryKind.AFTER_LOCALS: + return None + + # The right interval resumes just above the last excluded V and its locals. + last = right_lower.version.version + if first == last: + return [first] + + # Adjacent exclusions: the successor of ``first`` opens a ``.dev`` family and + # every later point is a higher ``.dev`` in that same family, so the gap is + # exactly ``first`` plus a contiguous dev run up to ``last``. Any other gap + # (e.g. ``2.3`` to ``AFTER_LOCALS(2.7)`` from complementing ``>=2.3,<=2.7``) + # spans a whole interval and fails this test. + second = least_version_above(BoundaryVersion(first, BoundaryKind.AFTER_LOCALS)) + if ( + second is not None + and second.dev is not None + and last.dev is not None + and last.dev >= second.dev + and last.__replace__(dev=second.dev) == second + ): + # ``first`` and the run spell this gap together, so they share the cap. + if last.dev - second.dev + 2 > _MAX_EXCLUSION_RUN: + return None + run = (second.__replace__(dev=d) for d in range(second.dev, last.dev + 1)) + return [first, *run] + return None + + +def _decompose_dev0_gap( + lower_trim: tuple[int, ...], + upper_trim: tuple[int, ...], + epoch: int, + budget: int = _MAX_EXCLUSION_RUN, +) -> list[Version] | None: + """Decompose the gap ``[L.dev0, U.dev0)`` into wildcard prefixes. + + ``lower_trim``/``upper_trim`` are trimmed release tuples with + ``lower_trim < upper_trim`` lexicographically. The chain sweeps at the + first differing level. The gap is undecomposable when L has trailing + components below that level (the chain cannot escape L's subtree), or when + the chain, summed across levels, would exceed ``budget`` prefixes. + """ + diff = 0 + while ( + diff < len(lower_trim) + and diff < len(upper_trim) + and lower_trim[diff] == upper_trim[diff] + ): + diff += 1 + + if len(lower_trim) > diff + 1: + return None + + common = lower_trim[:diff] + lower_val = lower_trim[diff] if len(lower_trim) > diff else 0 + upper_val = upper_trim[diff] + + span = upper_val - lower_val + if span > budget: + return None + + fragments = [ + Version.from_parts(epoch=epoch, release=(*common, segment)) + for segment in range(lower_val, upper_val) + ] + + if len(upper_trim) == diff + 1: + return fragments + + # Recurse into the next release component, charging at least one to the budget + # per level (not just the span), so a run of zero-span levels (a release with + # many trailing components) exhausts the budget and returns None instead of + # recursing past the interpreter's stack limit. + tail = _decompose_dev0_gap( + (*common, upper_val), upper_trim, epoch, budget - max(span, 1) + ) + if tail is None: + return None + return fragments + tail + + +def _encode_gap(left_upper: UpperBound, right_lower: LowerBound) -> list[str] | None: + """Encode the gap between two adjacent intervals as ``!=`` fragments. + + A point chain becomes ``!=V`` fragments and a dev0 family span becomes + ``!=P.*`` prefixes, followed by a leading dev run in the last family when + the gap ends inside it. Any other gap has no exclusion form and returns + ``None``. + """ + # Cheapest first: a plain ``!=V`` chain never pays for the budgeted + # wildcard sweep below. + points = _detect_not_equal(left_upper, right_lower) + if points is not None: + return [f"!={point}" for point in points] + + # Both wildcard shapes start at an exclusive family base ``L.dev0``. + left_v = left_upper.version + if ( + not isinstance(left_v, Version) + or left_upper.inclusive + or not _is_dev0_version(left_v) + ): + return None + + right_v = right_lower.version + if isinstance(right_v, Version) and right_lower.inclusive: + # ``[L.dev0, U.dev0)`` is a pure ``!=P.*`` chain up to U's family. + upper_dev0 = right_v + run_length = 0 + budget = _MAX_EXCLUSION_RUN + elif ( + isinstance(right_v, BoundaryVersion) + and right_v.kind == BoundaryKind.AFTER_LOCALS + and not right_lower.inclusive + ): + # ``[L.dev0, AFTER_LOCALS(U.dev(k))]`` ends inside U's family: the + # ``!=P.*`` chain, then the ``U.dev0..U.dev(k)`` run. Both spell the + # gap together, so they share one ``_MAX_EXCLUSION_RUN`` budget. + upper = right_v.version + if upper.dev is None or upper.dev + 1 > _MAX_EXCLUSION_RUN: + return None + upper_dev0 = upper.__replace__(dev=0) + run_length = upper.dev + 1 + budget = _MAX_EXCLUSION_RUN - run_length + else: + return None + + # ``U`` must be a plain release base in L's epoch, above L. + # ``_is_dev0_version`` on ``U.dev0`` rejects any pre/post/local on ``U``. + if not _is_dev0_version(upper_dev0): + return None + if left_v.epoch != upper_dev0.epoch or left_v >= upper_dev0: + return None + + prefixes = _decompose_dev0_gap( + trim_release(left_v.release), + trim_release(upper_dev0.release), + left_v.epoch, + budget, + ) + if prefixes is None: + return None + + exclusions = [f"!={prefix}.*" for prefix in prefixes] + exclusions.extend(f"!={upper_dev0.__replace__(dev=d)}" for d in range(run_length)) + return exclusions + + +def _encode_gaps(bounds: Sequence[Interval]) -> list[str] | None: + """Encode every between-interval gap as ``!=`` fragments, or ``None``. + + When each gap has an exclusion spelling, the intervals fuse into one + contiguous span (``==1.* | ==3.*`` is ``!=0.*,!=2.*,<4``): the outer + interval across all the bounds plus these exclusions. A gap with no + exclusion spelling makes the bounds a disjoint union, which no single + set expresses. + """ + exclusions: list[str] = [] + + for index in range(1, len(bounds)): + gap = _encode_gap(bounds[index - 1][1], bounds[index][0]) + if gap is None: + return None + exclusions.extend(gap) + + return exclusions + + +def _tighten_no_prereleases(bounds: tuple[Interval, ...]) -> tuple[Interval, ...]: + """Snap the range's final upper out of the pre-release band ``False`` drops. + + An exclusive upper at a final ``V`` admits the versions in ``[V.dev0, V)`` at + the bounds level, but a ``prereleases=False`` policy filters them all out, so + it accepts the same releases as ``>> r = SpecifierSet(">=1.0,<2.0").to_range() + >>> "1.5" in r + True + >>> "2.0" in r + False + >>> SpecifierSet(">=2.0,<1.0").to_range().is_empty + True + + PEP 440's ``===`` operator matches a candidate string verbatim + (case-insensitive) rather than a set of versions. Ranges built from + ``===`` specifiers still support membership, set operations, and conversion + back to a :class:`~packaging.specifiers.SpecifierSet`; matching follows the + literal-equality rule. A ``===`` literal that names a pre-release is + admitted under the default policy by both :meth:`contains` and + :meth:`filter`, since it was named outright. + + .. versionadded:: 26.3 + """ + + __slots__ = ( + "_admit", + "_admit_arbitrary", + "_bounds", + "_pre_region", + "_prereleases_configured", + "_reject", + ) + + #: The disjoint, sorted, non-overlapping interval list. + _bounds: tuple[Interval, ...] + + #: Whether this range matches non-version strings as well as versions. + #: True only by construction on ``SpecifierSet("")`` / :meth:`full`. The flag + #: rides set algebra but is inert except at full bounds (see + #: :meth:`_arbitrary_active`). An intersection or difference that shrinks + #: the bounds drops it (``full() & ~full()`` is plain empty, and + #: ``full() - r == full() & ~r``); :meth:`complement` and a union of + #: empty-bounds operands keep it, so ``~~full() == full()`` and + #: ``~full() | ~full() == ~full()``. Part of equality, since membership + #: reads it. + _admit_arbitrary: bool + + #: Case-folded strings the range admits in addition to its bounds. + #: ``===wat`` produces ``_admit = {"wat"}``. + _admit: frozenset[str] + + #: Case-folded strings the range rejects (overrides ``_admit`` and the + #: bounds). Populated by :meth:`complement` of an admit-bearing range and by + #: literal resolution in :meth:`_combine_literals`. + _reject: frozenset[str] + + #: Sorted, disjoint intervals where pre-releases are force-admitted under + #: the PEP 440 default policy (a ``None`` ``prereleases`` argument and no + #: configured override). The opt-in flows only from the pre-release-naming + #: specifiers that built the range. :meth:`_build` clips the region to the + #: bounds, so it is always a subset of them: an opt-in that overflowed its + #: own cap cannot ride a later union into versions no specifier asked for. + #: :meth:`union` and :meth:`intersection` accumulate the operands' clipped + #: regions and re-clip to the result bounds; :meth:`difference` keeps only + #: the minuend's; and :meth:`complement` drops it, since an exclusion grants + #: no opt-in. Equality keys on the clipped region, so it stays a congruence. + _pre_region: tuple[Interval, ...] + + #: Raw configured pre-release override of the originating specifier set + #: (an explicit ``True`` / ``False``, else ``None``). When set, :meth:`_build` + #: forces ``_pre_region`` empty since the policy governs globally. + #: :meth:`intersection` and :meth:`union` require it to match on both + #: operands. Part of equality. + _prereleases_configured: bool | None + + def __new__(cls, *args: object, **kwargs: object) -> VersionRange: # noqa: PYI034 + raise TypeError( + "cannot create 'VersionRange' instances directly; use " + "SpecifierSet.to_range(), VersionRange.full(), " + "VersionRange.empty(), or VersionRange.singleton() instead" + ) + + @classmethod + def _build( + cls, + bounds: tuple[Interval, ...], + admit: frozenset[str] = frozenset(), + reject: frozenset[str] = frozenset(), + admit_arbitrary: bool = False, + *, + pre_region: tuple[Interval, ...] = (), + prereleases_configured: bool | None = None, + ) -> VersionRange: + """Internal factory; bypasses :meth:`__new__`. + + Canonicalizes the bounds so equal version sets share one representation, + then drops admit literals the bounds already admit and reject literals + the bounds do not match anyway. Reject wins over admit on overlap. The + pre-release policy is set here and never reassigned afterwards; + ``pre_region`` is canonicalized like the bounds and clipped to them, + or dropped when a configured policy makes it inert. + """ + bounds = _canonicalize(bounds) + + if admit and reject: + admit = admit - reject + if admit: + admit = frozenset( + literal + for literal in admit + if not _struct_admits(bounds, admit_arbitrary, literal) + ) + if reject: + reject = frozenset( + literal + for literal in reject + if _struct_admits(bounds, admit_arbitrary, literal) + ) + + instance = object.__new__(cls) + instance._bounds = bounds + instance._admit = admit + instance._reject = reject + instance._admit_arbitrary = admit_arbitrary + instance._prereleases_configured = prereleases_configured + + # A configured policy makes the region inert, so drop it. Otherwise fold + # least-successor bounds (_from_specifier_set passes the region unfolded), + # so ``>1.0a1`` and ``>=1.0a2.dev0`` carry the same region, then clip it + # to the bounds so the opt-in never reaches past the range's own versions. + if prereleases_configured is not None or not pre_region: + instance._pre_region = () + else: + instance._pre_region = tuple( + intersect_ranges(_canonicalize(pre_region), bounds) + ) + + return instance + + def _has_literals(self) -> bool: + return bool(self._admit) or bool(self._reject) + + def _arbitrary_active(self) -> bool: + """True when ``_admit_arbitrary`` actually admits non-version strings. + + The flag rides through set algebra but only fires admission on full + bounds. Intersection and difference drop it when the bounds shrink, so + away from full bounds it survives only on empty-bounds ranges, where + it keeps ``~~full() == full()`` and union idempotent. + """ + return self._admit_arbitrary and self._bounds == FULL_RANGE + + def _is_plain(self) -> bool: + """True when membership is decided by ``_bounds`` alone, enabling the + bounds-only fast paths in :meth:`is_subset` and :meth:`is_disjoint`. + """ + return ( + not self._has_literals() + and not self._admit_arbitrary + and self._prereleases_configured is not False + ) + + def _check_policy_compat(self, other: VersionRange) -> None: + """Refuse combining ranges with different pre-release policies.""" + if not isinstance(other, VersionRange): + raise TypeError(f"expected VersionRange, got {type(other).__name__}") + if self._prereleases_configured != other._prereleases_configured: + raise ValueError( + "Cannot combine VersionRange operands with different " + f"pre-release policies: {self._prereleases_configured!r} " + f"and {other._prereleases_configured!r}" + ) + + def _merged_region(self, other: VersionRange) -> tuple[Interval, ...]: + """Union of ``self`` and ``other``'s opt-in regions. + + Used by :meth:`union` and :meth:`intersection`; :meth:`_build` clips the + merge to the result bounds. A configured operand carries an empty region, + so it contributes nothing to the merge. + """ + # Reuse an operand's canonical tuple when only one side has a region; + # an empty side contributes nothing to the union. + if not other._pre_region: + return self._pre_region + if not self._pre_region: + return other._pre_region + + # Both sides carry a region; merge them. _build re-canonicalizes and + # clips, so the plain union is fine here. + return tuple(_union_ranges(self._pre_region, other._pre_region)) + + def _with_policy( + self, *, pre_region: tuple[Interval, ...], configured: bool | None + ) -> VersionRange: + """A structural copy of this range carrying the given pre-release policy.""" + return self._build( + self._bounds, + admit=self._admit, + reject=self._reject, + admit_arbitrary=self._admit_arbitrary, + pre_region=pre_region, + prereleases_configured=configured, + ) + + @classmethod + def empty(cls, *, prereleases: bool | None = None) -> VersionRange: + """Return the empty range. No version satisfies it. + + >>> VersionRange.empty().is_empty + True + >>> "1.0" in VersionRange.empty() + False + """ + return cls._build((), prereleases_configured=prereleases) + + @classmethod + def full( + cls, *, admit_arbitrary: bool = True, prereleases: bool | None = None + ) -> VersionRange: + """Return the full range. Every PEP 440 version satisfies it. + + ``admit_arbitrary=False`` restricts the range to PEP 440 versions only + (matching the same versions as ``SpecifierSet(">=0.dev0").to_range()``); + its complement is :meth:`empty`. The flag propagates through set algebra + and is part of equality. Default ``True`` so that ``r & full()`` + preserves ``r``'s own flag structurally. + + >>> "1.0" in VersionRange.full() + True + >>> "wat" in VersionRange.full() + True + >>> "wat" in VersionRange.full(admit_arbitrary=False) + False + """ + return cls._build( + FULL_RANGE, + admit_arbitrary=admit_arbitrary, + prereleases_configured=prereleases, + ) + + @classmethod + def singleton( + cls, version: Version | str, *, prereleases: bool | None = None + ) -> VersionRange: + """Return the strict singleton range ``{version}``. + + Built as the closed interval ``[version, version]`` with strict + equality. ``Specifier("==V")`` matches ``V+local`` too, so the strict + singleton is narrower: + + >>> "1.0+local" in VersionRange.singleton("1.0") + False + >>> "1.0+local" in SpecifierSet("==1.0").to_range() + True + + :raises packaging.version.InvalidVersion: if version is a string that + does not parse as a PEP 440 version. + """ + if not isinstance(version, Version): + version = Version(version) + + lower = LowerBound(version, True) + upper = UpperBound(version, True) + + # Collapse the floor: nothing sorts below ``MIN_VERSION``, so the + # ``0.dev0`` singleton is ``(-inf, 0.dev0]`` in canonical form. + return cls._build( + _canonical_floor(((lower, upper),)), + prereleases_configured=prereleases, + ) + + def intersection(self, other: VersionRange) -> VersionRange: + """Range containing exactly the versions in both self and other. + + Both operands must share the same configured pre-release policy; + otherwise :exc:`ValueError` is raised. + + >>> a = SpecifierSet(">=1.0").to_range() + >>> b = SpecifierSet("<2.0").to_range() + >>> a.intersection(b) == SpecifierSet(">=1.0,<2.0").to_range() + True + """ + self._check_policy_compat(other) + + configured = self._prereleases_configured + new_bounds = tuple(intersect_ranges(self._bounds, other._bounds)) + new_region = self._merged_region(other) + + # An empty intersection (e.g. ``full() & ~full()``) is the empty range, + # so it drops the arbitrary flag, agreeing with difference when the + # subtrahend consumes the bounds. + combined_arb = ( + self._admit_arbitrary and other._admit_arbitrary and bool(new_bounds) + ) + + if not self._has_literals() and not other._has_literals(): + return self._build( + new_bounds, + admit_arbitrary=combined_arb, + pre_region=new_region, + prereleases_configured=configured, + ) + + return self._combine_literals( + other, + new_bounds, + op=_SetOp.INTERSECTION, + admit_arbitrary=combined_arb, + pre_region=new_region, + prereleases_configured=configured, + ) + + def union(self, other: VersionRange) -> VersionRange: + """Range containing every version in self or other. + + Both operands must share the same configured pre-release policy; + otherwise :exc:`ValueError` is raised. + + >>> a = VersionRange.singleton("1.0") + >>> b = VersionRange.singleton("2.0") + >>> "1.0" in a.union(b) and "2.0" in a.union(b) + True + >>> "1.5" in a.union(b) + False + """ + self._check_policy_compat(other) + + configured = self._prereleases_configured + new_bounds = tuple(_union_ranges(self._bounds, other._bounds)) + new_region = self._merged_region(other) + + # An empty-bounds operand (e.g. ``~full()``) carries an inert arbitrary + # flag only to keep complement an involution; it admits nothing, so it + # must not revive arbitrary admission as the union re-widens the bounds. + if new_bounds: + combined_arb = (self._admit_arbitrary and bool(self._bounds)) or ( + other._admit_arbitrary and bool(other._bounds) + ) + else: + # Nothing widened, so keeping the flags keeps ``r | r == r``. + combined_arb = self._admit_arbitrary or other._admit_arbitrary + + if not self._has_literals() and not other._has_literals(): + return self._build( + new_bounds, + admit_arbitrary=combined_arb, + pre_region=new_region, + prereleases_configured=configured, + ) + + return self._combine_literals( + other, + new_bounds, + op=_SetOp.UNION, + admit_arbitrary=combined_arb, + pre_region=new_region, + prereleases_configured=configured, + ) + + def complement(self) -> VersionRange: + """Range containing every version not in self. + + Preserves the configured pre-release policy. On the version set, double + negation holds for a range with no ``===`` literals (the arbitrary-string + flag round-trips, so ``~~full() == full()``); for ``===`` ranges + complement is one-way. The opt-in region is not restored (see below). + + The opt-in region is dropped: a complement is an exclusion, and an + exclusion expresses no pre-release preference. This is what lets + ``a & ~b`` shed ``b``'s opt-in, so an excluded ``b`` never force-admits a + pre-release into the result. Complement stays involutive on the version + set, but not on the opt-in region: ``~~r`` covers the same versions as + ``r`` yet force-admits none of its pre-releases. + + >>> r = SpecifierSet(">=1.0").to_range() + >>> "0.5" in r.complement() + True + >>> "1.5" in r.complement() + False + >>> r.complement().complement() == r + True + """ + # Complement swaps literal admission: what the range rejects, its + # complement admits. + return self._build( + tuple(_complement_ranges(self._bounds)), + admit=self._reject, + reject=self._admit, + admit_arbitrary=self._admit_arbitrary, + pre_region=(), + prereleases_configured=self._prereleases_configured, + ) + + def difference(self, other: VersionRange) -> VersionRange: + """Range containing the versions in self but not in other. + + Matches ``self & ~other`` on the version set and the opt-in region; + ``other`` acts as a bounds-only exclusion that grants no opt-in. The + arbitrary-string flag survives only when ``other`` removed no versions: + a difference that shrinks the bounds forgets it, as ``self & ~other`` + would, so no later widening union can revive it. They still part on + ``===`` literals, whose complement is one-way: a ``===`` literal stays + when ``self`` admits it and ``other`` does not. Both operands must + share the same configured pre-release policy (as :meth:`intersection` + and :meth:`union` require); otherwise :exc:`ValueError` is raised. + ``a - empty()`` returns a range equal to ``a``. + + >>> a = SpecifierSet(">=1.0").to_range() + >>> b = SpecifierSet(">=2.0").to_range() + >>> "1.5" in a.difference(b) + True + >>> "2.0" in a.difference(b) + False + >>> a.difference(VersionRange.empty()) == a + True + """ + self._check_policy_compat(other) + + # Subtracting a nothing-admitting set is a no-op; return self unchanged. + if not other._bounds and not other._admit: + return self + + # Bound complement is two-way, so subtracting other's versions is an + # intersection with its gaps. + new_bounds = tuple( + intersect_ranges(self._bounds, _complement_ranges(other._bounds)) + ) + + # Match ``self & ~other`` on the opt-in region: a complement carries no + # opt-in, so only ``self``'s region survives. ``other`` acts as a + # bounds-only exclusion. A configured ``self`` keeps no region. + new_region: tuple[Interval, ...] = () + if self._prereleases_configured is None: + new_region = self._pre_region + + # Keep self's arbitrary admission only when subtracting removed no + # versions. A difference that shrinks the bounds forgets the flag, as + # ``self & ~other`` would, so no later widening union can revive an + # admission neither operand had. + combined_arb = self._admit_arbitrary and new_bounds == self._bounds + + if not self._has_literals() and not other._has_literals(): + return self._build( + new_bounds, + admit_arbitrary=combined_arb, + pre_region=new_region, + prereleases_configured=self._prereleases_configured, + ) + + return self._combine_literals( + other, + new_bounds, + op=_SetOp.DIFFERENCE, + admit_arbitrary=combined_arb, + pre_region=new_region, + prereleases_configured=self._prereleases_configured, + ) + + def _combine_literals( + self, + other: VersionRange, + new_bounds: tuple[Interval, ...], + *, + op: _SetOp, + admit_arbitrary: bool, + pre_region: tuple[Interval, ...], + prereleases_configured: bool | None, + ) -> VersionRange: + """Resolve admit/reject for ``self`` ``op`` ``other`` over their literals.""" + admits: set[str] = set() + rejects: set[str] = set() + + # Each literal is decided independently of the others. + for literal in self._admit | self._reject | other._admit | other._reject: + self_in = self._matches_literal(literal) + other_in = other._matches_literal(literal) + + if op is _SetOp.INTERSECTION: + want = self_in and other_in + elif op is _SetOp.UNION: + want = self_in or other_in + else: + want = self_in and not other_in + + if want: + admits.add(literal) + else: + rejects.add(literal) + + return self._build( + new_bounds, + admit=frozenset(admits), + reject=frozenset(rejects), + admit_arbitrary=admit_arbitrary, + pre_region=pre_region, + prereleases_configured=prereleases_configured, + ) + + def _matches_literal(self, literal: str) -> bool: + """Whether literal (case-folded) matches this range's predicate.""" + if literal in self._reject: + return False + if literal in self._admit: + return True + + parsed = coerce_version(literal) + if parsed is None: + return self._arbitrary_active() + return matches_bounds_only(self._bounds, parsed) + + def __and__(self, other: object) -> VersionRange: + """Operator alias for :meth:`intersection`.""" + if not isinstance(other, VersionRange): + return NotImplemented + return self.intersection(other) + + def __or__(self, other: object) -> VersionRange: + """Operator alias for :meth:`union`.""" + if not isinstance(other, VersionRange): + return NotImplemented + return self.union(other) + + def __invert__(self) -> VersionRange: + """Operator alias for :meth:`complement`.""" + return self.complement() + + def __sub__(self, other: object) -> VersionRange: + """Operator alias for :meth:`difference`.""" + if not isinstance(other, VersionRange): + return NotImplemented + return self.difference(other) + + def is_subset(self, other: VersionRange) -> bool: + """Return whether every member of self is also a member of other. + + On versions and ``===`` literals this is + ``self.difference(other).is_empty``: subtracting other leaves nothing + behind. A live arbitrary admission (the flag at full bounds) is only a + subset of another live one. + + Both operands must share the same configured pre-release policy; + otherwise :exc:`ValueError` is raised. + + >>> inner = SpecifierSet(">=1.5,<1.8").to_range() + >>> outer = SpecifierSet(">=1.0,<2.0").to_range() + >>> inner.is_subset(outer) + True + >>> outer.is_subset(inner) + False + >>> VersionRange.empty().is_subset(outer) + True + """ + self._check_policy_compat(other) + + # A live arbitrary admission has non-version strings as members, which + # no bounds cover; only another live admission contains them. + if self._arbitrary_active() and not other._arbitrary_active(): + return False + + # Plain ranges: subset reduces to bounds containment, no algebra needed. + if self._is_plain() and other._is_plain(): + return not intersect_ranges(self._bounds, _complement_ranges(other._bounds)) + + # difference (unlike intersection with the one-way complement) resolves + # ``===`` literals against both operands, so it stays correct for them. + return self.difference(other).is_empty + + def is_superset(self, other: VersionRange) -> bool: + """Return whether every member of other is also a member of self. + + The mirror of :meth:`is_subset`: ``a.is_superset(b)`` is + ``b.is_subset(a)``. + + Both operands must share the same configured pre-release policy; + otherwise :exc:`ValueError` is raised. + + >>> outer = SpecifierSet(">=1.0,<2.0").to_range() + >>> outer.is_superset(SpecifierSet(">=1.5,<1.8").to_range()) + True + """ + # Type-guards a non-VersionRange other before delegating to is_subset. + self._check_policy_compat(other) + return other.is_subset(self) + + def is_disjoint(self, other: VersionRange) -> bool: + """Return whether self and other share no member. + + Equivalent to ``(self & other).is_empty``. + + Both operands must share the same configured pre-release policy; + otherwise :exc:`ValueError` is raised. + + >>> a = SpecifierSet(">=1.0,<2.0").to_range() + >>> a.is_disjoint(SpecifierSet(">=2.0,<3.0").to_range()) + True + >>> a.is_disjoint(SpecifierSet(">=1.5,<2.5").to_range()) + False + """ + self._check_policy_compat(other) + + # Plain ranges: disjointness is an empty bounds intersection. + if self._is_plain() and other._is_plain(): + return not intersect_ranges(self._bounds, other._bounds) + return self.intersection(other).is_empty + + def _same_releases(self, other: VersionRange) -> bool: + """Whether self and other admit the same non-pre-release versions. + + Used by :meth:`to_specifier_set` under a ``prereleases=False`` policy, + where pre-releases are unobservable: the symmetric difference is empty + exactly when the two ranges accept the same releases. Both operands + carry that policy, so the difference below reads emptiness through it. + """ + return self.difference(other).is_empty and other.difference(self).is_empty + + @typing.overload + def filter( + self, + iterable: Iterable[UnparsedVersionVar], + prereleases: bool | None = None, + key: None = ..., + ) -> Iterator[UnparsedVersionVar]: ... + + @typing.overload + def filter( + self, + iterable: Iterable[T], + prereleases: bool | None = None, + key: Callable[[T], UnparsedVersion] = ..., + ) -> Iterator[T]: ... + + def filter( + self, + iterable: Iterable[Any], + prereleases: bool | None = None, + key: Callable[[Any], Version | str] | None = None, + ) -> Iterator[Any]: + """Yield items from iterable whose version falls inside the range. + + With prereleases ``None`` the PEP 440 default applies: pre-releases are + buffered and only emitted if no final release in iterable is in range, + except that a pre-release inside the autodetected opt-in region, or named + outright by a ``===`` literal, is force-admitted in place (as + ``prereleases=True`` would yield it). A flushed buffer comes after + every in-place yield, so the output is not version-sorted. + + The signature mirrors + :meth:`~packaging.specifiers.SpecifierSet.filter`. + + >>> r = SpecifierSet(">=1.0,<2.0").to_range() + >>> list(r.filter(["0.9", "1.5", "2.0"])) + ['1.5'] + """ + region: tuple[Interval, ...] = () + if prereleases is None: + # The region applies only under the autodetect default; a configured + # policy governs instead (and then ``_pre_region`` is already empty). + prereleases = self._prereleases_configured + region = self._pre_region + + arbitrary_active = self._arbitrary_active() + if not self._admit and not self._reject and not arbitrary_active: + # A region spanning the whole bounds force-admits every in-bounds + # pre-release, i.e. ``prereleases=True``; take the cheaper no-buffer + # path. (Confined to this branch: the admission path orders arbitrary + # strings differently under True than under the region.) + if region and region == self._bounds: + return filter_by_ranges(self._bounds, iterable, key, True) + return filter_by_ranges(self._bounds, iterable, key, prereleases, region) + return self._filter_with_admission( + iterable, key, prereleases, arbitrary_active, region + ) + + def _filter_with_admission( + self, + iterable: Iterable[Any], + key: Callable[[Any], Version | str] | None, + prereleases: bool | None, + arbitrary_active: bool, + region: tuple[Interval, ...], + ) -> Iterator[Any]: + """Filter for ranges with admit/reject literals or live arbitrary + admission (including the universal ``SpecifierSet("")`` range).""" + admit_set = self._admit + reject_set = self._reject + + def admit(item: Any) -> tuple[bool, Version | None, bool]: # noqa: ANN401 + raw: Version | str = item if key is None else key(item) + raw_lower = str(raw).lower() + + if reject_set and raw_lower in reject_set: + return False, None, False + if admit_set and raw_lower in admit_set: + # An explicit ``===`` literal names this version outright. + return True, coerce_version(raw), True + + parsed = coerce_version(raw) + if parsed is None: + return arbitrary_active, None, False + if not matches_bounds_only(self._bounds, parsed): + return False, None, False + return True, parsed, False + + if prereleases is True: + for item in iterable: + ok, _, _ = admit(item) + if ok: + yield item + return + + if prereleases is False: + for item in iterable: + ok, parsed, _ = admit(item) + if not ok: + continue + if parsed is not None and parsed.is_prerelease: + continue + yield item + return + + # PEP 440 default: emit finals eagerly and buffer the other pre-releases, + # releasing the buffer only if no final ever matches. + all_nonfinal: list[Any] = [] + arbitrary_strings: list[Any] = [] + found_final = False + + for item in iterable: + ok, parsed, by_literal = admit(item) + if not ok: + continue + + if parsed is None: + if found_final: + yield item + else: + arbitrary_strings.append(item) + all_nonfinal.append(item) + continue + + if not parsed.is_prerelease: + if not found_final: + yield from arbitrary_strings + arbitrary_strings.clear() + found_final = True + yield item + continue + + # A pre-release is force-admitted when it is named outright by a + # ``===`` literal or falls in the opt-in region, as ``prereleases=True`` + # would yield it; otherwise the PEP 440 default buffers it. + if by_literal or (region and matches_bounds_only(region, parsed)): + yield item + continue + + if not found_final: + all_nonfinal.append(item) + + if not found_final: + yield from all_nonfinal + + @classmethod + def _from_specifier_set(cls, specifier_set: SpecifierSet) -> VersionRange: + """Build the range accepted by ``specifier_set``. + + Friend constructor for :meth:`~packaging.specifiers.SpecifierSet.to_range`. + The intersection of every specifier in the set: an empty set yields the + full range, an unsatisfiable set yields the empty range, and ``===`` + specifiers contribute literal-string admission. + """ + if not specifier_set: + result = cls.full() + elif not specifier_set._has_arbitrary: + result = cls._build( + bounds=_canonical_floor(tuple(specifier_set._get_ranges())) + ) + else: + result = cls.full() + for spec in specifier_set: + if spec.operator == "===": + operand = cls._build( + bounds=(), admit=frozenset({spec.version.lower()}) + ) + else: + operand = cls._build( + bounds=_canonical_floor(tuple(spec._to_ranges())) + ) + result = result.intersection(operand) + + # Each pre-release-naming specifier opts its own versions in; their union, + # clipped to the set's bounds by _build, is the region. Clipping refolds + # under intersection, so a set built directly equals one built by + # intersecting its specifiers one at a time. + region: list[Interval] = [] + if specifier_set._prereleases is None: # a configured policy has no region + for spec in specifier_set: + # ``===`` literals are not a range; filter force-admits them. + if spec.operator != "===" and spec.prereleases: + spec_bounds = _canonical_floor(tuple(spec._to_ranges())) + region = _union_ranges(region, spec_bounds) + + return result._with_policy( + pre_region=tuple(region), + configured=specifier_set._prereleases, + ) + + def to_specifier_set(self) -> SpecifierSet | None: + """Return a :class:`~packaging.specifiers.SpecifierSet` matching the same + versions as self, or ``None`` if no single set expresses it. + + PEP 440 has no syntax for the strict singleton ``{V}`` (an exclusive + plain-version bound), a disjoint union of two or more intervals, or a + partial pre-release opt-in region, so ranges built by set algebra often + return ``None``. A gap that takes more than ``_MAX_EXCLUSION_RUN`` + contiguous ``!=`` exclusions to spell returns ``None`` too, + rather than a pathologically long chain; reaching that cap takes either + set algebra or a specifier set that already spells the gap out with + over a hundred contiguous ``!=N.*`` exclusions. An empty range maps to + ``SpecifierSet("<0")``, unless it still carries the arbitrary-string + flag (which no set reproduces), and a full range that admits arbitrary + strings maps to ``SpecifierSet("")``. + + A range built from a :class:`~packaging.specifiers.SpecifierSet` + re-encodes, short of that exclusion cap. The result is the simplest + candidate whose own + :meth:`~packaging.specifiers.SpecifierSet.to_range` reproduces self + exactly (bounds, ``===`` literals, and the opt-in region are all part of + equality), so it filters the same versions. Two cases relax that + exactness without changing what is filtered: an empty range recovers as + the canonical empty range (same versions, none, but not self's bounds), + and under a ``prereleases=False`` policy the result need only match self's + releases, so ``(-inf, 3.14)`` recovers as the tighter ``<3.14`` rather + than ``!=3.14,<=3.14``. + + Each call encodes a handful of candidate spellings and keeps the + simplest one that verifies, where verifying means parsing the candidate + and round-tripping it through + :meth:`~packaging.specifiers.SpecifierSet.to_range`. The work grows + with the number of intervals and exclusions in the range, and the + result is not cached, so convert once and reuse the returned set rather + than converting per candidate version in a hot loop. + + >>> str(SpecifierSet(">=1.0,<2.0").to_range().to_specifier_set()) + '<2.0,>=1.0' + >>> str(SpecifierSet("==1.0").to_range().to_specifier_set()) + '==1.0' + >>> VersionRange.singleton("1.5").to_specifier_set() is None + True + """ + from .specifiers import InvalidSpecifier, SpecifierSet # noqa: PLC0415 + + configured = self._prereleases_configured + + if self._reject: + return None + if self._admit_arbitrary and self._bounds != FULL_RANGE: + return None + if self.is_empty: + # Every member-free spelling accepts the same versions (none), so the + # canonical ``<0`` stands in for all of them; a configured policy + # rides along it. + return SpecifierSet("<0", prereleases=configured) + + if not self._bounds: + # Pure ``===`` literals; only a single literal has a single-set form. + if len(self._admit) != 1: + return None + (literal,) = self._admit + bases = [f"==={literal}"] + elif self._admit: + # Bounds plus literals cannot be one set. + return None + elif self._bounds == FULL_RANGE: + bases = ["" if self._admit_arbitrary else ">=0.dev0"] + else: + # Under ``prereleases=False`` an exclusive final upper admits the same + # releases as ``=0.dev0`` floor restores a ``True`` opt-in that + # rode on a floor the clean encoding dropped (e.g. ``>=0.dev0,!=1.0``). + # It always recovers the whole bounds as the opt-in region, so it can + # only round-trip when self opts everything in. + add_floor = configured is None and self._pre_region == self._bounds + + # Keep the simplest candidate that recovers self. ``==`` compares bounds, + # literals, and the opt-in region, so a candidate that would filter + # differently, or an op-built range with no single-set form, is rejected + # below. Under ``prereleases=False`` a candidate need only match self's + # releases (policies never mix, so the excluded pre-releases are + # unobservable), which admits the tightened spellings above. + best: SpecifierSet | None = None + best_key = (0, 0) + + for base in bases: + candidates = [base] + if add_floor: + candidates.append(f"{base},>=0.dev0" if base else ">=0.dev0") + + for spec_str in candidates: + # A ``===`` literal can hold a comma (its arbitrary version + # excludes only whitespace, ``;`` and ``)``), which the set + # string splits on. Such a literal has no single specifier-set + # spelling, so drop the unparsable candidate and let the range + # fall through to ``None`` rather than raise. + try: + recovered = SpecifierSet(spec_str, prereleases=configured) + except InvalidSpecifier: + continue + # Fewest fragments, then shortest string. Rank before the round + # trip so a candidate that cannot beat the best skips the check + # (its ``==`` and, under ``False``, two ``difference`` calls). + key = (len(recovered), len(str(recovered))) + if best is not None and key >= best_key: + continue + + # Accept an exact round trip, or (under ``False``) one that only + # matches the releases the policy leaves observable. + candidate = recovered.to_range() + matches = candidate == self or ( + configured is False and self._same_releases(candidate) + ) + if matches: + best, best_key = recovered, key + + return best + + @property + def is_empty(self) -> bool: + """``True`` if no version or string satisfies this range. + + Agrees with :meth:`~packaging.specifiers.SpecifierSet.is_unsatisfiable`, + including the pre-release policy: a range whose only members are + pre-releases is empty when that policy excludes them. + + >>> SpecifierSet(">=2,<1").to_range().is_empty + True + >>> SpecifierSet(">=1,<2").to_range().is_empty + False + >>> SpecifierSet("==1.0a1", prereleases=False).to_range().is_empty + True + """ + # An arbitrary-string admission or a surviving ``===`` literal is a + # member; a literal that is a pre-release is dropped when the policy is. + if self._arbitrary_active(): + return False + + excludes_prereleases = self._prereleases_configured is False + for literal in self._admit: + if excludes_prereleases: + parsed = coerce_version(literal) + if parsed is not None and parsed.is_prerelease: + continue + return False + + if not self._bounds: + return True + + return excludes_prereleases and ranges_are_prerelease_only(self._bounds) + + def contains( + self, + item: Version | str, + prereleases: bool | None = None, + installed: bool | None = None, + ) -> bool: + """Return whether item is contained in this range. + + :param item: a version string or :class:`~packaging.version.Version`. + :param prereleases: whether to match pre-releases. ``None`` (default) + uses the range's own policy. + :param installed: when ``True``, accept a pre-release item even if the + range would not otherwise allow it. + + Unlike :meth:`filter`, this does not consult the autodetected pre-release + opt-in region; it reads only the configured policy. This mirrors + :meth:`~packaging.specifiers.SpecifierSet.contains` versus + :meth:`~packaging.specifiers.SpecifierSet.filter`. + + Unparsable strings do not match, except where the full + ``SpecifierSet`` would also match: the full range admits any string, + and a ``===`` range admits items equal to the literal + case-insensitively. + + >>> r = SpecifierSet(">=1.0,<2.0").to_range() + >>> r.contains("1.5") + True + >>> r.contains("2.0") + False + + :raises TypeError: if item is not a str or Version. + """ + if not isinstance(item, (str, Version)): + raise TypeError( + f"VersionRange.contains() expected str or Version, " + f"got {type(item).__name__}" + ) + + parsed: Version | None = item if isinstance(item, Version) else None + if installed and parsed is None: + parsed = coerce_version(item) + if installed and parsed is not None and parsed.is_prerelease: + prereleases = True + + effective_pre = ( + self._prereleases_configured if prereleases is None else prereleases + ) + + if self._admit or self._reject: + item_str = str(item).lower() + if item_str in self._reject: + return False + if item_str in self._admit: + if effective_pre is False: + literal_parsed = coerce_version(item_str) + if literal_parsed is not None and literal_parsed.is_prerelease: + return False + return True + + if not isinstance(item, Version): + if parsed is None: + parsed = coerce_version(item) + if parsed is None: + return self._arbitrary_active() + item = parsed + + if effective_pre is False and item.is_prerelease: + return False + return matches_bounds_only(self._bounds, item) + + def __contains__(self, item: Version | str) -> bool: + """Return whether item is contained in this range. + + Forwards to :meth:`contains` with default arguments. + + >>> "1.5" in SpecifierSet(">=1.0,<2.0").to_range() + True + """ + return self.contains(item) + + def __eq__(self, other: object) -> bool: + """Structural equality. + + Compares the bounds, the ``===`` admit/reject literals, the + arbitrary-string flag, the configured pre-release policy, and the + opt-in region, not just the version set. Keying on the region makes + equality a congruence (equal ranges stay equal under further operations), + so equal implies same :meth:`contains` and :meth:`filter`, but not the + converse: an empty range keeps the flag it was built with, so two empty + ranges need not be equal. + + Different specifiers for the same range fold to one canonical form: + + >>> SpecifierSet(">1.0a1").to_range() == SpecifierSet(">=1.0a2.dev0").to_range() + True + + The opt-in region is part of equality, so ``<=1.0`` (no pre-releases) and + ``<1.0.post0.dev0`` (autodetects a ``.dev`` opt-in) cover the same + versions yet compare unequal: + + >>> le, lt = SpecifierSet("<=1.0"), SpecifierSet("<1.0.post0.dev0") + >>> le.to_range() == lt.to_range() + False + + >>> r = SpecifierSet(">=1.0,<2.0").to_range() + >>> r == SpecifierSet(">=1.0,<2.0").to_range() + True + """ + if not isinstance(other, VersionRange): + return NotImplemented + return ( + self._bounds == other._bounds + and self._admit == other._admit + and self._reject == other._reject + and self._admit_arbitrary == other._admit_arbitrary + and self._prereleases_configured == other._prereleases_configured + and self._pre_region == other._pre_region + ) + + def __hash__(self) -> int: + return hash( + ( + self._bounds, + self._admit, + self._reject, + self._admit_arbitrary, + self._prereleases_configured, + self._pre_region, + ) + ) + + def __repr__(self) -> str: + """Human-readable representation for debugging. + + >>> SpecifierSet(">=1.0,<2.0").to_range() + + >>> SpecifierSet("").to_range() + + >>> SpecifierSet(">=2.0,<1.0").to_range() + + """ + # Body: the bounds and any ``===``-admitted literals. + parts: list[str] = [] + if self._bounds: + parts.append(_format_intervals(self._bounds)) + if self._admit: + parts.append("{" + ", ".join(sorted(self._admit)) + "}") + body = " | ".join(parts) if parts else "(empty)" + + # Rejected literals subtract from the body. + if self._reject: + body = f"{body} \\ {{{', '.join(sorted(self._reject))}}}" + + # Tail: the policy flags carried alongside the version set. + tail = "" + if self._admit_arbitrary: + tail += " arbitrary" + if self._prereleases_configured is not None: + tail += f" pre={self._prereleases_configured}" + if self._pre_region: + tail += f" pre-region={_format_intervals(self._pre_region)!r}" + + return f"<{self.__class__.__name__} {body!r}{tail}>" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py new file mode 100644 index 00000000000..adcc8adbb74 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py @@ -0,0 +1,192 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import annotations + +from typing import TYPE_CHECKING + +from ._parser import parse_requirement as _parse_requirement +from ._tokenizer import ParserSyntaxError +from .markers import Marker, _normalize_extra_values +from .specifiers import InvalidSpecifier, SpecifierSet +from .utils import canonicalize_name + +if TYPE_CHECKING: + from collections.abc import Iterator + +__all__ = [ + "InvalidRequirement", + "Requirement", +] + + +def __dir__() -> list[str]: + return __all__ + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + + .. versionadded:: 16.1 + """ + + +class Requirement: + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + + .. versionadded:: 16.1 + + .. versionchanged:: 22.0 + Added equality (``__eq__``) and hashing (``__hash__``) so requirements + can be compared and stored in sets / dicts. + + .. versionchanged:: 23.2 + Equality and hashing began canonicalizing requirement names, so + requirements whose names differ only by normalization (e.g. + ``Requirement("Foo")`` vs ``Requirement("foo")``) now compare and hash + equal. + + Instances are safe to serialize with :mod:`pickle`. They use a stable + format so the same pickle can be loaded in future packaging releases. + + .. versionchanged:: 26.2 + + Added a stable pickle format. Pickles created with packaging 26.2+ can + be unpickled with future releases. Backward compatibility with pickles + from packaging < 26.2 is supported but may be removed in a future + release. + + .. versionchanged:: 26.3 + + The dedicated pickle support introduced in 26.2 did not preserve the + specifier's explicit :attr:`~packaging.specifiers.SpecifierSet.prereleases` + override; it is now included again. + + Equality and hashing normalize requirement names, extras, and + equivalent specifiers. The string representation still preserves the + parsed name and extras spelling. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + __slots__ = ("extras", "marker", "name", "specifier", "url") + + def __init__(self, requirement_string: str) -> None: + try: + parsed = _parse_requirement(requirement_string) + except ParserSyntaxError as e: + raise InvalidRequirement(str(e)) from e + + self.name: str = parsed.name + self.url: str | None = parsed.url or None + self.extras: set[str] = set(parsed.extras) + try: + self.specifier: SpecifierSet = SpecifierSet(parsed.specifier) + except InvalidSpecifier as e: + raise InvalidRequirement(str(e)) from e + self.marker: Marker | None = None + if parsed.marker is not None: + self.marker = Marker.__new__(Marker) + self.marker._markers = _normalize_extra_values(parsed.marker) + + def _iter_parts(self, name: str) -> Iterator[str]: + yield name + + if self.extras: + formatted_extras = ",".join(sorted(self.extras)) + yield f"[{formatted_extras}]" + + if self.specifier: + yield str(self.specifier) + + if self.url: + yield f" @ {self.url}" + if self.marker: + yield " " + + if self.marker: + yield f"; {self.marker}" + + def __getstate__(self) -> tuple[str, bool | None]: + # Return the requirement string for compactness and stability, paired + # with the specifier's explicit prereleases override, which is not + # captured by the string form. Re-parsed on load to reconstruct all + # other fields. + return (str(self), self.specifier._prereleases) + + def __setstate__(self, state: object) -> None: + if isinstance(state, str): + # Format (26.2): just the requirement string. + requirement_string: str = state + prereleases: bool | None = None + elif ( + isinstance(state, tuple) + and len(state) == 2 + and isinstance(state[0], str) + and (state[1] is None or isinstance(state[1], bool)) + ): + # New format (26.3+): (requirement string, specifier prereleases). + requirement_string, prereleases = state + elif isinstance(state, dict) and state.keys() >= set(self.__slots__): + # Old format (packaging <= 26.1, no __slots__): plain __dict__. + for key in self.__slots__: + setattr(self, key, state[key]) + return + else: + raise TypeError(f"Cannot restore Requirement from {state!r}") + + try: + tmp = Requirement(requirement_string) + except InvalidRequirement as exc: + raise TypeError(f"Cannot restore Requirement from {state!r}") from exc + self.name = tmp.name + self.url = tmp.url + self.extras = tmp.extras + self.specifier = tmp.specifier + self.specifier._prereleases = prereleases + self.marker = tmp.marker + + def __str__(self) -> str: + return "".join(self._iter_parts(self.name)) + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}({str(self)!r})>" + + def __hash__(self) -> int: + # Mirror __eq__ by hashing the canonical specifier object rather than + # its raw string. ``_iter_parts`` yields ``str(self.specifier)``, which + # is non-canonical, so trailing-zero-equivalent requirements such as + # ``foo==1.0.0`` and ``foo==1.0.0.0`` (which compare equal) would + # otherwise hash differently, breaking the hash/__eq__ invariant. + return hash( + ( + canonicalize_name(self.name), + frozenset(canonicalize_name(e) for e in self.extras), + self.specifier, + self.url, + self.marker, + ) + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Requirement): + return NotImplemented + + # Extras must be normalized before comparison as per PEP 685. + self_extras = frozenset(canonicalize_name(e) for e in self.extras) + other_extras = frozenset(canonicalize_name(e) for e in other.extras) + return ( + canonicalize_name(self.name) == canonicalize_name(other.name) + and self_extras == other_extras + and self.specifier == other.specifier + and self.url == other.url + and self.marker == other.marker + ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py new file mode 100644 index 00000000000..5128e306e47 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py @@ -0,0 +1,1457 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +""" +.. testsetup:: + + from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier + from packaging.version import Version +""" + +from __future__ import annotations + +import abc +import re +import typing +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Final, + TypeVar, + Union, +) + +from ._ranges import ( + FULL_RANGE, + bounds_for_spec, + coerce_version, + filter_by_ranges, + intersect_specifier_bounds, + matches_bounds_only, + ranges_are_prerelease_only, + resolve_prereleases, + trim_release, +) +from .utils import canonicalize_version +from .version import Version + +if TYPE_CHECKING: + import sys + from collections.abc import Iterable, Iterator, Sequence + + if sys.version_info >= (3, 10): + from typing import TypeGuard + else: + from opentelemetry.agent._vendor.typing_extensions import TypeGuard + + from . import ranges + from ._ranges import Interval + + +__all__ = [ + "BaseSpecifier", + "InvalidSpecifier", + "Specifier", + "SpecifierSet", +] + + +def __dir__() -> list[str]: + return __all__ + + +def _validate_spec(spec: object, /) -> TypeGuard[tuple[str, str]]: + return ( + isinstance(spec, tuple) + and len(spec) == 2 + and isinstance(spec[0], str) + and isinstance(spec[1], str) + ) + + +def _validate_pre(pre: object, /) -> TypeGuard[bool | None]: + return pre is None or isinstance(pre, bool) + + +T = TypeVar("T") +UnparsedVersion = Union[Version, str] +UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion) + + +# Operators whose result is just a direct Version comparison, given a parsed +# item with no local. ``<=``/``==``/``!=`` need that no-local guard because +# PEP 440 strips locals on those; ``>=`` works regardless. +_DIRECT_COMPARE_OPS: dict[str, Callable[[Version, Version], bool]] = { + ">=": Version.__ge__, + "<=": Version.__le__, + "==": Version.__eq__, + "!=": Version.__ne__, +} + + +def _fast_match(specifier: Specifier, parsed: Version) -> bool | None: + """Match ``parsed`` against ``specifier`` without building a range. + + Handles ``>=``, ``<=``, ``==``, ``!=``, ``<``, ``>`` when the spec is + not a wildcard and ``parsed`` has no local. Returns ``None`` when the + range path must be used. Pre-release policy is left to the caller. + """ + op_str, ver_str = specifier._spec + if ver_str.endswith(".*") or parsed.local is not None: + return None + + direct_compare = _DIRECT_COMPARE_OPS.get(op_str) + if direct_compare is not None: + return direct_compare(parsed, specifier._require_spec_version(ver_str)) + + if op_str in ("<", ">"): + spec_v = specifier._require_spec_version(ver_str) + # ``V`` carve out V's family (pre/dev/post); that only + # matters when parsed shares V's epoch and trimmed release. + # Otherwise a direct cmpkey comparison is correct. + if parsed.epoch != spec_v.epoch or trim_release(parsed.release) != trim_release( + spec_v.release + ): + return parsed < spec_v if op_str == "<" else parsed > spec_v + return None + + return None + + +class InvalidSpecifier(ValueError): + """ + Raised when attempting to create a :class:`Specifier` with a specifier + string that is invalid. + + >>> Specifier("lolwat") + Traceback (most recent call last): + ... + packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat' + """ + + +class BaseSpecifier(metaclass=abc.ABCMeta): + """ + Abstract base class for :class:`Specifier` and :class:`SpecifierSet`. + """ + + __slots__ = () + __match_args__ = ("_str",) + + @property + def _str(self) -> str: + """Internal property for match_args""" + return str(self) + + @abc.abstractmethod + def __str__(self) -> str: + """ + Returns the str representation of this Specifier-like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self) -> int: + """ + Returns a hash value for this Specifier-like object. + """ + + @abc.abstractmethod + def __eq__(self, other: object) -> bool: + """ + Returns a boolean representing whether or not the two Specifier-like + objects are equal. + + :param other: The other object to check against. + """ + + @property + @abc.abstractmethod + def prereleases(self) -> bool | None: + """Whether or not pre-releases as a whole are allowed. + + This can be set to either ``True`` or ``False`` to explicitly enable or disable + prereleases or it can be set to ``None`` (the default) to use default semantics. + """ + + @prereleases.setter # noqa: B027 + def prereleases(self, value: bool) -> None: + """Setter for :attr:`prereleases`. + + :param value: The value to set. + """ + + @abc.abstractmethod + def contains(self, item: str, prereleases: bool | None = None) -> bool: + """ + Determines if the given item is contained within this specifier. + """ + + @typing.overload + def filter( + self, + iterable: Iterable[UnparsedVersionVar], + prereleases: bool | None = None, + key: None = ..., + ) -> Iterator[UnparsedVersionVar]: ... + + @typing.overload + def filter( + self, + iterable: Iterable[T], + prereleases: bool | None = None, + key: Callable[[T], UnparsedVersion] = ..., + ) -> Iterator[T]: ... + + @abc.abstractmethod + def filter( + self, + iterable: Iterable[Any], + prereleases: bool | None = None, + key: Callable[[Any], UnparsedVersion] | None = None, + ) -> Iterator[Any]: + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class Specifier(BaseSpecifier): + """This class abstracts handling of version specifiers. + + .. tip:: + + It is generally not required to instantiate this manually. You should instead + prefer to work with :class:`SpecifierSet` instead, which can parse + comma-separated version specifiers (which is what package metadata contains). + + Instances are safe to serialize with :mod:`pickle`. They use a stable + format so the same pickle can be loaded in future packaging releases. + + .. versionchanged:: 26.2 + + Added a stable pickle format. Pickles created with packaging 26.2+ can + be unpickled with future releases. Backward compatibility with pickles + from packaging < 26.2 is supported but may be removed in a future + release. + """ + + __slots__ = ( + "_prereleases", + "_ranges", + "_spec", + "_spec_version", + ) + + _specifier_regex_str = r""" + (?: + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + === # Only match for the identity operator + \s* + [^\s;)]* # The arbitrary version can be just about anything, + # we match everything except for whitespace, a + # semi-colon for marker support, and a closing paren + # since versions can be enclosed in them. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?:==|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + + # You cannot use a wild card and a pre-release, post-release, a dev or + # local version together so group them with a | and make them optional. + (?: + \.\* # Wild card syntax of .* + | + (?a: # pre release + [-_\.]? + (alpha|beta|preview|pre|a|b|c|rc) + [-_\.]? + [0-9]* + )? + (?a: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?a:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?a:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?:~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (alpha|beta|preview|pre|a|b|c|rc) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?:<=|>=|<|>) + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?a: # pre release + [-_\.]? + (alpha|beta|preview|pre|a|b|c|rc) + [-_\.]? + [0-9]* + )? + (?a: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?a:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + + _regex = re.compile( + r"\s*" + _specifier_regex_str + r"\s*", re.VERBOSE | re.IGNORECASE + ) + + # Legacy unused attribute, kept for backward compatibility + _operators: Final = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + def __init__(self, spec: str = "", prereleases: bool | None = None) -> None: + """Initialize a Specifier instance. + + :param spec: + The string representation of a specifier which will be parsed and + normalized before use. + :param prereleases: + This tells the specifier if it should accept prerelease versions if + applicable or not. The default of ``None`` will autodetect it from the + given specifiers. + :raises InvalidSpecifier: + If the given specifier is invalid (i.e. bad syntax). + """ + if not self._regex.fullmatch(spec): + raise InvalidSpecifier(f"Invalid specifier: {spec!r}") + + spec = spec.strip() + if spec.startswith("==="): + operator, version = spec[:3], spec[3:].strip() + elif spec.startswith(("~=", "==", "!=", "<=", ">=")): + operator, version = spec[:2], spec[2:].strip() + else: + operator, version = spec[:1], spec[1:].strip() + + self._spec: tuple[str, str] = (operator, version) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + # Specifier version cache + self._spec_version: tuple[str, Version] | None = None + + # Version range cache (populated by _to_ranges) + self._ranges: Sequence[Interval] | None = None + + def _get_spec_version(self, version: str) -> Version | None: + """One element cache, as only one spec Version is needed per Specifier.""" + if self._spec_version is not None and self._spec_version[0] == version: + return self._spec_version[1] + + version_specifier = coerce_version(version) + if version_specifier is None: + return None + + self._spec_version = (version, version_specifier) + return version_specifier + + def _require_spec_version(self, version: str) -> Version: + """Get spec version, asserting it's valid (not for === operator). + + This method should only be called for operators where version + strings are guaranteed to be valid PEP 440 versions (not ===). + """ + spec_version = self._get_spec_version(version) + assert spec_version is not None + return spec_version + + def _to_ranges(self) -> Sequence[Interval]: + """Convert this specifier to sorted, non-overlapping version ranges. + + Each standard operator maps to one or two ranges. ``===`` is + modeled as full range (actual check done separately). Cached. + """ + if self._ranges is not None: + return self._ranges + + op = self.operator + ver_str = self.version + + if op == "===": + result: Sequence[Interval] = FULL_RANGE + else: + version = self._require_spec_version(ver_str.removesuffix(".*")) + result = bounds_for_spec(op, ver_str, version) + + self._ranges = result + return result + + @property + def prereleases(self) -> bool | None: + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Only the "!=" operator does not imply prereleases when + # the version in the specifier is a prerelease. + operator, version_str = self._spec + if operator == "!=": + return False + + # The == specifier with trailing .* cannot include prereleases + # e.g. "==1.0a1.*" is not valid. + if operator == "==" and version_str.endswith(".*"): + return False + + # "===" can have arbitrary string versions, so we cannot parse + # those, we take prereleases as unknown (None) for those. + version = self._get_spec_version(version_str) + if version is None: + return None + + # For all other operators, use the check if spec Version + # object implies pre-releases. + return version.is_prerelease + + @prereleases.setter + def prereleases(self, value: bool | None) -> None: + self._prereleases = value + + def __getstate__(self) -> tuple[tuple[str, str], bool | None]: + # Return state as a 2-item tuple for compactness: + # ((operator, version), prereleases) + # Cache members are excluded and will be recomputed on demand. + return (self._spec, self._prereleases) + + def __setstate__(self, state: object) -> None: + # Always discard cached values - they will be recomputed on demand. + self._spec_version = None + self._ranges = None + + if isinstance(state, tuple): + if len(state) == 2: + # New format (26.2+): ((operator, version), prereleases) + spec, prereleases = state + if _validate_spec(spec) and _validate_pre(prereleases): + self._spec = spec + self._prereleases = prereleases + return + if len(state) == 2 and isinstance(state[1], dict): + # Format (packaging 26.0-26.1): (None, {slot: value}). + _, slot_dict = state + spec = slot_dict.get("_spec") + prereleases = slot_dict.get("_prereleases", "invalid") + if _validate_spec(spec) and _validate_pre(prereleases): + self._spec = spec + self._prereleases = prereleases + return + if isinstance(state, dict): + # Old format (packaging <= 25.x, no __slots__): state is a plain dict. + spec = state.get("_spec") + prereleases = state.get("_prereleases", "invalid") + if _validate_spec(spec) and _validate_pre(prereleases): + self._spec = spec + self._prereleases = prereleases + return + + raise TypeError(f"Cannot restore Specifier from {state!r}") + + @property + def operator(self) -> str: + """The operator of this specifier. + + >>> Specifier("==1.2.3").operator + '==' + """ + return self._spec[0] + + @property + def version(self) -> str: + """The version of this specifier. + + >>> Specifier("==1.2.3").version + '1.2.3' + """ + return self._spec[1] + + def __repr__(self) -> str: + """A representation of the Specifier that shows all internal state. + + >>> Specifier('>=1.0.0') + =1.0.0')> + >>> Specifier('>=1.0.0', prereleases=False) + =1.0.0', prereleases=False)> + >>> Specifier('>=1.0.0', prereleases=True) + =1.0.0', prereleases=True)> + """ + pre = ( + f", prereleases={self.prereleases!r}" + if self._prereleases is not None + else "" + ) + + return f"<{self.__class__.__name__}({str(self)!r}{pre})>" + + def __str__(self) -> str: + """A string representation of the Specifier that can be round-tripped. + + >>> str(Specifier('>=1.0.0')) + '>=1.0.0' + >>> str(Specifier('>=1.0.0', prereleases=False)) + '>=1.0.0' + """ + return "{}{}".format(*self._spec) + + @property + def _canonical_spec(self) -> tuple[str, str]: + operator, version = self._spec + if operator == "===" or version.endswith(".*"): + return operator, version + + spec_version = self._require_spec_version(version) + + canonical_version = canonicalize_version( + spec_version, strip_trailing_zero=(operator != "~=") + ) + + return operator, canonical_version + + def __hash__(self) -> int: + return hash(self._canonical_spec) + + def __eq__(self, other: object) -> bool: + """Whether or not the two Specifier-like objects are equal. + + :param other: The other object to check against. + + The value of :attr:`prereleases` is ignored. + + >>> Specifier("==1.2.3") == Specifier("== 1.2.3.0") + True + >>> (Specifier("==1.2.3", prereleases=False) == + ... Specifier("==1.2.3", prereleases=True)) + True + >>> Specifier("==1.2.3") == "==1.2.3" + True + >>> Specifier("==1.2.3") == Specifier("==1.2.4") + False + >>> Specifier("==1.2.3") == Specifier("~=1.2.3") + False + """ + if isinstance(other, str): + try: + other = self.__class__(str(other)) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._canonical_spec == other._canonical_spec + + def __contains__(self, item: str | Version) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: The item to check for. + + This is used for the ``in`` operator and behaves the same as + :meth:`contains` with no ``prereleases`` argument passed. + + >>> "1.2.3" in Specifier(">=1.2.3") + True + >>> Version("1.2.3") in Specifier(">=1.2.3") + True + >>> "1.0.0" in Specifier(">=1.2.3") + False + >>> "1.3.0a1" in Specifier(">=1.2.3") + True + >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True) + True + """ + return self.contains(item) + + def contains(self, item: UnparsedVersion, prereleases: bool | None = None) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: + The item to check for, which can be a version string or a + :class:`~packaging.version.Version` instance. + :param prereleases: + Whether or not to match prereleases with this Specifier. If set to + ``None`` (the default), it will follow the recommendation from + :pep:`440` and match prereleases, as there are no other versions. + + >>> Specifier(">=1.2.3").contains("1.2.3") + True + >>> Specifier(">=1.2.3").contains(Version("1.2.3")) + True + >>> Specifier(">=1.2.3").contains("1.0.0") + False + >>> Specifier(">=1.2.3").contains("1.3.0a1") + True + >>> Specifier(">=1.2.3", prereleases=False).contains("1.3.0a1") + False + >>> Specifier(">=1.2.3").contains("1.3.0a1") + True + + .. versionchanged:: 26.0 + + With ``prereleases=None``, a prerelease now matches. A single + version has no alternatives, so the :pep:`440` rule to accept + prereleases when nothing else satisfies the specifier applies. + Earlier versions rejected it. An unparsable version now returns + ``False`` instead of raising :exc:`~packaging.version.InvalidVersion`. + """ + # ``===`` compares the raw string, so a Version parse here would + # be wasted. + if self._spec[0] == "===": + return bool(list(self.filter([item], prereleases=prereleases))) + + parsed = coerce_version(item) + if parsed is None: + # Standard operators never match an unparsable input. + return False + + if prereleases is None: + prereleases = resolve_prereleases(self._prereleases, self.prereleases) + + if prereleases is False and parsed.is_prerelease: + return False + + # ``_fast_match`` answers the simple operators without building a + # range; otherwise fall back to the engine's bounds membership. + match = _fast_match(self, parsed) + if match is not None: + return match + + return matches_bounds_only(self._to_ranges(), parsed) + + @typing.overload + def filter( + self, + iterable: Iterable[UnparsedVersionVar], + prereleases: bool | None = None, + key: None = ..., + ) -> Iterator[UnparsedVersionVar]: ... + + @typing.overload + def filter( + self, + iterable: Iterable[T], + prereleases: bool | None = None, + key: Callable[[T], UnparsedVersion] = ..., + ) -> Iterator[T]: ... + + def filter( + self, + iterable: Iterable[Any], + prereleases: bool | None = None, + key: Callable[[Any], UnparsedVersion] | None = None, + ) -> Iterator[Any]: + """Filter items in the given iterable, that match the specifier. + + :param iterable: + An iterable that can contain version strings and + :class:`~packaging.version.Version` instances. The items in the + iterable will be filtered according to the specifier. + :param prereleases: + Whether or not to allow prereleases in the returned iterator. If set to + ``None`` (the default), it will follow the recommendation from :pep:`440` + and match prereleases if there are no other versions. + :param key: + A callable that takes a single argument (an item from the iterable) and + returns a version string or :class:`~packaging.version.Version` + instance to be used for filtering. + + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) + ['1.3'] + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")])) + ['1.2.3', '1.3', ] + >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"])) + ['1.5a1'] + >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + >>> list(Specifier(">=1.2.3").filter( + ... [{"ver": "1.2"}, {"ver": "1.3"}], + ... key=lambda x: x["ver"])) + [{'ver': '1.3'}] + + .. versionchanged:: 26.1 + + Added the ``key`` parameter. + """ + if prereleases is None: + prereleases = resolve_prereleases(self._prereleases, self.prereleases) + + if self.operator == "===": + spec_lower = self.version.lower() + matches = ( + item + for item in iterable + if str(item if key is None else key(item)).lower() == spec_lower + ) + return _apply_prereleases_filter(matches, key, prereleases) + + return filter_by_ranges(self._to_ranges(), iterable, key, prereleases) + + +def _apply_prereleases_filter( + matches: Iterable[Any], + key: Callable[[Any], UnparsedVersion] | None, + prereleases: bool | None, +) -> Iterator[Any]: + """Apply ``prereleases=`` handling to an already-matched iterable. + + ``None`` means PEP 440 default (buffer pre-releases until a final + appears); ``True`` yields everything; ``False`` drops pre-releases. + """ + if prereleases is None: + return _pep440_filter_prereleases(matches, key) + if prereleases: + return iter(matches) + return ( + item + for item in matches + if (parsed := coerce_version(item if key is None else key(item))) is None + or not parsed.is_prerelease + ) + + +class SpecifierSet(BaseSpecifier): + """This class abstracts handling of a set of version specifiers. + + It can be passed a single specifier (``>=3.0``), a comma-separated list of + specifiers (``>=3.0,!=3.1``), or no specifier at all. + + Instances are safe to serialize with :mod:`pickle`. They use a stable + format so the same pickle can be loaded in future packaging + releases. + + .. versionchanged:: 26.2 + + Added a stable pickle format. Pickles created with + packaging 26.2+ can be unpickled with future releases. + Backward compatibility with pickles from + packaging < 26.2 is supported but may be removed in a future + release. + """ + + __slots__ = ( + "_canonicalized", + "_has_arbitrary", + "_is_unsatisfiable", + "_prereleases", + "_ranges", + "_specs", + ) + + def __init__( + self, + specifiers: str | Iterable[Specifier] = "", + prereleases: bool | None = None, + ) -> None: + """Initialize a SpecifierSet instance. + + :param specifiers: + The string representation of a specifier or a comma-separated list of + specifiers which will be parsed and normalized before use. + May also be an iterable of ``Specifier`` instances, which will be used + as is. + :param prereleases: + This tells the SpecifierSet if it should accept prerelease versions if + applicable or not. The default of ``None`` will autodetect it from the + given specifiers. + + :raises InvalidSpecifier: + If the given ``specifiers`` are not parseable than this exception will be + raised. + """ + + if isinstance(specifiers, str): + # Split on `,` to break each individual specifier into its own item, and + # strip each item to remove leading/trailing whitespace. + split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + self._specs: tuple[Specifier, ...] = tuple(map(Specifier, split_specifiers)) + # Fast substring check; avoids iterating parsed specs. + self._has_arbitrary = "===" in specifiers + else: + self._specs = tuple(specifiers) + # Substring check works for both Specifier objects and plain + # strings (setuptools passes lists of strings). + self._has_arbitrary = any("===" in str(s) for s in self._specs) + + self._canonicalized = len(self._specs) <= 1 + self._is_unsatisfiable: bool | None = None + self._ranges: Sequence[Interval] | None = None + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def _canonical_specs(self) -> tuple[Specifier, ...]: + """Deduplicate, sort, and cache specs for order-sensitive operations.""" + if not self._canonicalized: + self._specs = tuple(dict.fromkeys(sorted(self._specs, key=str))) + self._canonicalized = True + return self._specs + + @property + def prereleases(self) -> bool | None: + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + if any(s.prereleases for s in self._specs): + return True + + return None + + @prereleases.setter + def prereleases(self, value: bool | None) -> None: + self._prereleases = value + self._is_unsatisfiable = None + + def __getstate__(self) -> tuple[tuple[Specifier, ...], bool | None]: + # Return state as a 2-item tuple for compactness: + # (specs, prereleases) + # Cache members are excluded and will be recomputed on demand. + return (self._specs, self._prereleases) + + def __setstate__(self, state: object) -> None: + # Always discard cached values - they will be recomputed on demand. + self._ranges = None + self._is_unsatisfiable = None + + if isinstance(state, tuple): + if len(state) == 2: + # New format (26.2+): (specs, prereleases) + specs, prereleases = state + if ( + isinstance(specs, tuple) + and all(isinstance(s, Specifier) for s in specs) + and _validate_pre(prereleases) + ): + self._specs = specs + self._prereleases = prereleases + self._canonicalized = len(specs) <= 1 + self._has_arbitrary = any("===" in str(s) for s in specs) + return + if len(state) == 2 and isinstance(state[1], dict): + # Format (packaging 26.0-26.1): (None, {slot: value}). + _, slot_dict = state + specs = slot_dict.get("_specs", ()) + prereleases = slot_dict.get("_prereleases") + # Convert frozenset to tuple (26.0 stored as frozenset) + if isinstance(specs, frozenset): + specs = tuple(sorted(specs, key=str)) + if ( + isinstance(specs, tuple) + and all(isinstance(s, Specifier) for s in specs) + and _validate_pre(prereleases) + ): + self._specs = specs + self._prereleases = prereleases + self._canonicalized = len(self._specs) <= 1 + self._has_arbitrary = any("===" in str(s) for s in self._specs) + return + if isinstance(state, dict): + # Old format (packaging <= 25.x, no __slots__): state is a plain dict. + specs = state.get("_specs", ()) + prereleases = state.get("_prereleases") + # Convert frozenset to tuple (26.0 stored as frozenset) + if isinstance(specs, frozenset): + specs = tuple(sorted(specs, key=str)) + if ( + isinstance(specs, tuple) + and all(isinstance(s, Specifier) for s in specs) + and _validate_pre(prereleases) + ): + self._specs = specs + self._prereleases = prereleases + self._canonicalized = len(self._specs) <= 1 + self._has_arbitrary = any("===" in str(s) for s in self._specs) + return + + raise TypeError(f"Cannot restore SpecifierSet from {state!r}") + + def __repr__(self) -> str: + """A representation of the specifier set that shows all internal state. + + Note that the ordering of the individual specifiers within the set may not + match the input string. + + >>> SpecifierSet('>=1.0.0,!=2.0.0') + =1.0.0')> + >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False) + =1.0.0', prereleases=False)> + >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True) + =1.0.0', prereleases=True)> + """ + pre = ( + f", prereleases={self.prereleases!r}" + if self._prereleases is not None + else "" + ) + + return f"<{self.__class__.__name__}({str(self)!r}{pre})>" + + def __str__(self) -> str: + """A string representation of the specifier set that can be round-tripped. + + Note that the ordering of the individual specifiers within the set may not + match the input string. + + >>> str(SpecifierSet(">=1.0.0,!=1.0.1")) + '!=1.0.1,>=1.0.0' + >>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False)) + '!=1.0.1,>=1.0.0' + """ + return ",".join(str(s) for s in self._canonical_specs()) + + def __hash__(self) -> int: + return hash(self._canonical_specs()) + + def __and__(self, other: SpecifierSet | str) -> SpecifierSet: + """Return a SpecifierSet which is a combination of the two sets. + + :param other: The other object to combine with. + + >>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1' + =1.0.0')> + >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1') + =1.0.0')> + """ + if isinstance(other, str): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = self._specs + other._specs + specifier._canonicalized = len(specifier._specs) <= 1 + specifier._has_arbitrary = self._has_arbitrary or other._has_arbitrary + + # Combine prerelease settings: use common or non-None value + if self._prereleases is None or self._prereleases == other._prereleases: + specifier._prereleases = other._prereleases + elif other._prereleases is None: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease overrides." + ) + + return specifier + + def __eq__(self, other: object) -> bool: + """Whether or not the two SpecifierSet-like objects are equal. + + :param other: The other object to check against. + + The value of :attr:`prereleases` is ignored. + + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) == + ... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)) + True + >>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1" + True + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2") + False + """ + if isinstance(other, (str, Specifier)): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._canonical_specs() == other._canonical_specs() + + def __len__(self) -> int: + """Returns the number of specifiers in this specifier set.""" + return len(self._specs) + + def __iter__(self) -> Iterator[Specifier]: + """ + Returns an iterator over all the underlying :class:`Specifier` instances + in this specifier set. + + >>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str) + [, =1.0.0')>] + """ + return iter(self._specs) + + def _get_ranges(self) -> Sequence[Interval]: + """Intersect all specifiers into a single sequence of version ranges. + + Empty when unsatisfiable. Callers must ensure ``self._specs`` + is non-empty. + """ + if self._ranges is not None: + return self._ranges + + self._ranges = intersect_specifier_bounds(s._to_ranges() for s in self._specs) + return self._ranges + + def is_unsatisfiable(self) -> bool: + """Check whether this specifier set can never be satisfied. + + Returns True if no version can satisfy all specifiers simultaneously. + + >>> SpecifierSet(">=2.0,<1.0").is_unsatisfiable() + True + >>> SpecifierSet(">=1.0,<2.0").is_unsatisfiable() + False + >>> SpecifierSet("").is_unsatisfiable() + False + >>> SpecifierSet("==1.0,!=1.0").is_unsatisfiable() + True + + .. versionadded:: 26.1 + """ + cached = self._is_unsatisfiable + if cached is not None: + return cached + + if not self._specs: + self._is_unsatisfiable = False + return False + + result = not self._get_ranges() + + if not result: + result = self._check_arbitrary_unsatisfiable() + + if not result and self.prereleases is False: + result = ranges_are_prerelease_only(self._get_ranges()) + + self._is_unsatisfiable = result + return result + + def _check_arbitrary_unsatisfiable(self) -> bool: + """Check === (arbitrary equality) specs for unsatisfiability. + + === uses case-insensitive string comparison, so the only candidate + that can match ``===V`` is the literal string V. This method + checks whether that candidate is excluded by other specifiers. + """ + arbitrary = [s for s in self._specs if s.operator == "==="] + if not arbitrary: + return False + + # Multiple === must agree on the same string (case-insensitive). + first = arbitrary[0].version.lower() + if any(s.version.lower() != first for s in arbitrary[1:]): + return True + + # The sole candidate is the === version string. Check whether + # it can satisfy every standard spec. + candidate = coerce_version(arbitrary[0].version) + + # With prereleases=False, a prerelease candidate is excluded + # by contains() before the === string check even runs. + if ( + self.prereleases is False + and candidate is not None + and candidate.is_prerelease + ): + return True + + standard = [s for s in self._specs if s.operator != "==="] + if not standard: + return False + + if candidate is None: + # Unparsable string cannot satisfy any standard spec. + return True + + return not all(s.contains(candidate) for s in standard) + + def to_range(self) -> ranges.VersionRange: + """Return the :class:`~packaging.ranges.VersionRange` this set accepts. + + An empty set yields the full range; an unsatisfiable set yields the + empty range. ``===`` specifiers contribute literal-string admission. + + >>> SpecifierSet(">=1.0,<2.0").to_range() + + + .. versionadded:: 26.3 + """ + from .ranges import VersionRange # noqa: PLC0415 + + return VersionRange._from_specifier_set(self) + + def _check_relation_operand(self, other: object) -> None: + if not isinstance(other, SpecifierSet): + raise TypeError("expected a SpecifierSet") + if self._has_arbitrary or other._has_arbitrary: + raise ValueError("set relations do not support === specifiers") + + def is_subset(self, other: SpecifierSet) -> bool: + """Return whether every version matching this set also matches other. + + :raises ValueError: + If either set uses ``===`` specifiers, or the two sets were + given different ``prereleases`` arguments (unset on one side + counts as different). + :raises TypeError: + If other is not a :class:`SpecifierSet`. + + >>> SpecifierSet(">=3.12,<3.13").is_subset(SpecifierSet(">=3.12")) + True + >>> SpecifierSet(">=3.12").is_subset(SpecifierSet(">=3.12,<3.13")) + False + + .. versionadded:: 26.3 + """ + self._check_relation_operand(other) + return self.to_range().is_subset(other.to_range()) + + def is_superset(self, other: SpecifierSet) -> bool: + """Return whether every version matching other also matches this set. + + :raises ValueError: + If either set uses ``===`` specifiers, or the two sets were + given different ``prereleases`` arguments (unset on one side + counts as different). + :raises TypeError: + If other is not a :class:`SpecifierSet`. + + >>> SpecifierSet(">=3.12").is_superset(SpecifierSet(">=3.12,<3.13")) + True + + .. versionadded:: 26.3 + """ + self._check_relation_operand(other) + return self.to_range().is_superset(other.to_range()) + + def is_disjoint(self, other: SpecifierSet) -> bool: + """Return whether this set and other share no matching versions. + + :raises ValueError: + If either set uses ``===`` specifiers, or the two sets were + given different ``prereleases`` arguments (unset on one side + counts as different). + :raises TypeError: + If other is not a :class:`SpecifierSet`. + + >>> SpecifierSet("<3.12").is_disjoint(SpecifierSet(">=3.12")) + True + >>> SpecifierSet("<3.12").is_disjoint(SpecifierSet(">=3.11")) + False + + .. versionadded:: 26.3 + """ + self._check_relation_operand(other) + return self.to_range().is_disjoint(other.to_range()) + + def __contains__(self, item: UnparsedVersion) -> bool: + """Return whether or not the item is contained in this specifier. + + :param item: The item to check for. + + This is used for the ``in`` operator and behaves the same as + :meth:`contains` with no ``prereleases`` argument passed. + + >>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1") + False + >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1") + True + >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True) + True + """ + return self.contains(item) + + def contains( + self, + item: UnparsedVersion, + prereleases: bool | None = None, + installed: bool | None = None, + ) -> bool: + """Return whether or not the item is contained in this SpecifierSet. + + :param item: + The item to check for, which can be a version string or a + :class:`~packaging.version.Version` instance. + :param prereleases: + Whether or not to match prereleases with this SpecifierSet. If set to + ``None`` (the default), it will follow the recommendation from :pep:`440` + and match prereleases, as there are no other versions. + :param installed: + Whether or not the item is installed. If set to ``True``, it will + accept prerelease versions even if the specifier does not allow them. + + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3") + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3")) + True + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1") + True + >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False).contains("1.3.0a1") + False + >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True) + True + + .. versionchanged:: 26.0 + + With ``prereleases=None``, a prerelease now matches. A single + version has no alternatives, so the :pep:`440` rule to accept + prereleases when nothing else satisfies the specifiers applies. + Earlier versions rejected it. An unparsable version now returns + ``False`` instead of raising :exc:`~packaging.version.InvalidVersion`. + """ + version = coerce_version(item) + + if version is not None and installed and version.is_prerelease: + prereleases = True + + # When item is a string and === is involved, keep it as-is + # so the comparison isn't done against the normalized form. + if version is None or (self._has_arbitrary and not isinstance(item, Version)): + check_item = item + else: + check_item = version + + # Fast path: a parseable, local-free version against a rangelike set. + # A local on ``version`` needs PEP 440 stripping that the range path + # applies. + if ( + version is not None + and not self._has_arbitrary + and version.local is None + and self._specs + ): + if version.is_prerelease and ( + prereleases is False + or (prereleases is None and self._prereleases is False) + ): + return False + + bounds = self._ranges + if bounds is None: + # Per-spec ``_fast_match`` answers a set of simple specifiers + # without folding anything. If a spec needs the range path, + # fold the intersected bounds once and cache them so repeated + # checks on the same set stay cheap. + for spec in self._specs: + match = _fast_match(spec, version) + if match is None: + break + if not match: + return False + else: + return True + + bounds = self._ranges = self._get_ranges() + + return matches_bounds_only(bounds, version) + + return bool(list(self.filter([check_item], prereleases=prereleases))) + + @typing.overload + def filter( + self, + iterable: Iterable[UnparsedVersionVar], + prereleases: bool | None = None, + key: None = ..., + ) -> Iterator[UnparsedVersionVar]: ... + + @typing.overload + def filter( + self, + iterable: Iterable[T], + prereleases: bool | None = None, + key: Callable[[T], UnparsedVersion] = ..., + ) -> Iterator[T]: ... + + def filter( + self, + iterable: Iterable[Any], + prereleases: bool | None = None, + key: Callable[[Any], UnparsedVersion] | None = None, + ) -> Iterator[Any]: + """Filter items in the given iterable, that match the specifiers in this set. + + :param iterable: + An iterable that can contain version strings and + :class:`~packaging.version.Version` instances. The items in the + iterable will be filtered according to the specifier. + :param prereleases: + Whether or not to allow prereleases in the returned iterator. If set to + ``None`` (the default), it will follow the recommendation from :pep:`440` + and match prereleases if there are no other versions. + :param key: + A callable that takes a single argument (an item from the iterable) and + returns a version string or :class:`~packaging.version.Version` + instance to be used for filtering. + + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) + ['1.3'] + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")])) + ['1.3', ] + >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"])) + ['1.5a1'] + >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + >>> list(SpecifierSet(">=1.2.3").filter( + ... [{"ver": "1.2"}, {"ver": "1.3"}], + ... key=lambda x: x["ver"])) + [{'ver': '1.3'}] + + An "empty" SpecifierSet will filter items based on the presence of prerelease + versions in the set. + + >>> list(SpecifierSet("").filter(["1.3", "1.5a1"])) + ['1.3'] + >>> list(SpecifierSet("").filter(["1.5a1"])) + ['1.5a1'] + >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"])) + ['1.3', '1.5a1'] + >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True)) + ['1.3', '1.5a1'] + + .. versionchanged:: 26.0 + + Prerelease filtering now follows the PEP 440 recommendation of + yielding prereleases only when no final release is present. + + .. versionchanged:: 26.1 + + Added the ``key`` parameter. + """ + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None and self.prereleases is not None: + prereleases = self.prereleases + + if self._specs: + if self._has_arbitrary: + # Slow path for === + specs = self._specs + matches = ( + item + for item in iterable + if all( + s.contains(item if key is None else key(item), prereleases=True) + for s in specs + ) + ) + return _apply_prereleases_filter(matches, key, prereleases) + + ranges = self._ranges + if ranges is None: + ranges = self._get_ranges() + return filter_by_ranges(ranges, iterable, key, prereleases) + + # Empty SpecifierSet. + return _apply_prereleases_filter(iterable, key, prereleases) + + +def _pep440_filter_prereleases( + iterable: Iterable[Any], key: Callable[[Any], UnparsedVersion] | None +) -> Iterator[Any]: + """Filter per PEP 440: exclude prereleases unless no finals exist.""" + # Two lists used: + # * all_nonfinal to preserve order if no finals exist + # * arbitrary_strings for streaming when first final found + all_nonfinal: list[Any] = [] + arbitrary_strings: list[Any] = [] + + found_final = False + for item in iterable: + parsed = coerce_version(item if key is None else key(item)) + + if parsed is None: + # Arbitrary strings are always included as it is not + # possible to determine if they are prereleases, + # and they have already passed all specifiers. + if found_final: + yield item + else: + arbitrary_strings.append(item) + all_nonfinal.append(item) + continue + + if not parsed.is_prerelease: + # Final release found - flush arbitrary strings, then yield + if not found_final: + yield from arbitrary_strings + found_final = True + yield item + continue + + # Prerelease - buffer if no finals yet, otherwise skip + if not found_final: + all_nonfinal.append(item) + + # No finals found - yield all buffered items + if not found_final: + yield from all_nonfinal diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py new file mode 100644 index 00000000000..dd1ea911e17 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py @@ -0,0 +1,1053 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import logging +import operator +import platform +import re +import struct +import subprocess +import sys +import sysconfig +from collections.abc import Iterable, Iterator, Sequence +from importlib.machinery import EXTENSION_SUFFIXES +from typing import ( + TYPE_CHECKING, + TypeVar, + cast, +) + +from . import _manylinux, _musllinux + +if TYPE_CHECKING: + from collections.abc import Callable + from collections.abc import Set as AbstractSet + + +__all__ = [ + "INTERPRETER_SHORT_NAMES", + "AppleVersion", + "InvalidTag", + "PythonVersion", + "Tag", + "TooManyTagsError", + "UnsortedTagsError", + "android_platforms", + "compatible_tags", + "cpython_tags", + "create_compatible_tags_selector", + "generic_tags", + "interpreter_name", + "interpreter_version", + "ios_platforms", + "mac_platforms", + "parse_tag", + "platform_tags", + "pure_python_tags", + "sys_tags", +] + + +def __dir__() -> list[str]: + return __all__ + + +logger = logging.getLogger(__name__) + +PythonVersion = Sequence[int] +""" +A sequence of integers describing a Python version, e.g. ``(3, 13)``. + +.. versionadded:: 20.0 +""" + +AppleVersion = tuple[int, int] +""" +A ``(major, minor)`` integer pair describing an Apple OS version. + +.. versionadded:: 24.2 +""" +_T = TypeVar("_T") + +INTERPRETER_SHORT_NAMES: dict[str, str] = { + "python": "py", # Generic. + "cpython": "cp", + "pypy": "pp", + "ironpython": "ip", + "jython": "jy", +} + + +# This function can be unit tested without reloading the module +# (Unlike _32_BIT_INTERPRETER) +def _compute_32_bit_interpreter() -> bool: + return struct.calcsize("P") == 4 + + +_32_BIT_INTERPRETER = _compute_32_bit_interpreter() + + +class UnsortedTagsError(ValueError): + """ + Raised when a tag component is not in sorted order per PEP 425. + + .. versionadded:: 26.1 + """ + + +class InvalidTag(ValueError): + """ + Raised when an interpreter component is not an identifier, a tag component + is empty, or a tag does not have exactly three components. + + .. versionadded:: 26.3 + """ + + +class TooManyTagsError(ValueError): + """ + Raised when a compressed tag set exceeds the configured limit. + + .. versionadded:: 26.3 + """ + + +class Tag: + """ + A representation of the tag triple for a wheel. + + Instances are considered immutable and thus are hashable. Equality checking + is also supported. + + Instances are safe to serialize with :mod:`pickle`. They use a stable + format so the same pickle can be loaded in future packaging releases. + + .. versionchanged:: 26.2 + + Added a stable pickle format. Pickles created with packaging 26.2+ can + be unpickled with future releases. Backward compatibility with pickles + from packaging < 26.2 is supported but may be removed in a future + release. + """ + + __slots__ = ["_abi", "_hash", "_interpreter", "_platform"] + + def __init__(self, interpreter: str, abi: str, platform: str) -> None: + """ + :param str interpreter: The interpreter name, e.g. ``"py"`` + (see :attr:`INTERPRETER_SHORT_NAMES` for mapping + well-known interpreter names to their short names). + :param str abi: The ABI that a wheel supports, e.g. ``"cp37m"``. + :param str platform: The OS/platform the wheel supports, + e.g. ``"win_amd64"``. + """ + self._interpreter = interpreter.lower() + self._abi = abi.lower() + self._platform = platform.lower() + # The __hash__ of every single element in a Set[Tag] will be evaluated each time + # that a set calls its `.disjoint()` method, which may be called hundreds of + # times when scanning a page of links for packages with tags matching that + # Set[Tag]. Pre-computing the value here produces significant speedups for + # downstream consumers. + self._hash = hash((self._interpreter, self._abi, self._platform)) + + @property + def interpreter(self) -> str: + """ + The interpreter name, e.g. ``"py"`` (see + :attr:`INTERPRETER_SHORT_NAMES` for mapping well-known interpreter + names to their short names). + """ + return self._interpreter + + @property + def abi(self) -> str: + """ + The supported ABI. + """ + return self._abi + + @property + def platform(self) -> str: + """ + The OS/platform. + """ + return self._platform + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Tag): + return NotImplemented + + return ( + (self._hash == other._hash) # Short-circuit ASAP for perf reasons. + and (self._platform == other._platform) + and (self._abi == other._abi) + and (self._interpreter == other._interpreter) + ) + + def __hash__(self) -> int: + return self._hash + + def __str__(self) -> str: + return f"{self._interpreter}-{self._abi}-{self._platform}" + + def __repr__(self) -> str: + return f"<{self} @ {id(self)}>" + + def __getstate__(self) -> tuple[str, str, str]: + # Return state as a 3-item tuple: (interpreter, abi, platform). + # Cache member _hash is excluded and will be recomputed. + return (self._interpreter, self._abi, self._platform) + + def __setstate__(self, state: object) -> None: + if isinstance(state, tuple): + if len(state) == 3 and all(isinstance(s, str) for s in state): + # New format (26.2+): (interpreter, abi, platform) + self._interpreter, self._abi, self._platform = state + self._hash = hash((self._interpreter, self._abi, self._platform)) + return + if len(state) == 2 and isinstance(state[1], dict): + # Old format (packaging <= 26.1, __slots__): (None, {slot: value}). + _, slots = state + try: + interpreter = slots["_interpreter"] + abi = slots["_abi"] + platform = slots["_platform"] + except KeyError: + raise TypeError(f"Cannot restore Tag from {state!r}") from None + if not all( + isinstance(value, str) for value in (interpreter, abi, platform) + ): + raise TypeError(f"Cannot restore Tag from {state!r}") + self._interpreter = interpreter.lower() + self._abi = abi.lower() + self._platform = platform.lower() + self._hash = hash((self._interpreter, self._abi, self._platform)) + return + raise TypeError(f"Cannot restore Tag from {state!r}") + + +def parse_tag( + tag: str, *, validate_order: bool = False, limit: int | None = None +) -> frozenset[Tag]: + """ + Parses the provided tag (e.g. `py3-none-any`) into a frozenset of + :class:`Tag` instances. + + Returning a set is required due to the possibility that the tag is a + `compressed tag set`_, e.g. ``"py2.py3-none-any"`` which supports both + Python 2 and Python 3. + + If **validate_order** is true, compressed tag set components are checked + to be in sorted order as required by PEP 425. + + If **limit** is not ``None``, the compressed tag set can generate at most + that many tags. + + :param str tag: The tag to parse, e.g. ``"py3-none-any"``. + :param bool validate_order: Check whether compressed tag set components + are in sorted order. + :param int | None limit: The maximum number of tags to parse. + :raises UnsortedTagsError: If **validate_order** is true and any compressed tag + set component is not in sorted order. + :raises InvalidTag: If the interpreter field is not an identifier; if the + interpreter, ABI, or platform field (or any member of a compressed tag + set) is empty; or if the tag does not have exactly three components. + :raises TooManyTagsError: If **limit** is not ``None`` and the compressed tag + set would generate more than **limit** tags. + :raises ValueError: If **limit** is negative. + + .. versionadded:: 26.1 + The *validate_order* parameter. + + .. versionadded:: 26.3 + Raises :class:`InvalidTag` when an interpreter component is not an + identifier, a tag component is empty, or a tag does not have exactly + three components. + Added the *limit* parameter. Raises :class:`TooManyTagsError` if the compressed + tag set would generate more than *limit* tags. + """ + + if limit is not None and limit < 0: + raise ValueError("limit must be non-negative") + + component_parts = [component.split(".") for component in tag.split("-")] + for parts in component_parts: + if "" in parts: + component = ".".join(parts) + raise InvalidTag(f"Tag {tag!r} has an empty component: {component!r}") + if validate_order and parts != sorted(parts): + component = ".".join(parts) + raise UnsortedTagsError( + f"Tag component {component!r} is not in sorted order per PEP 425" + ) + + tag_count = 1 + for parts in component_parts: + tag_count *= len(parts) + + if limit is not None and tag_count > limit: + raise TooManyTagsError( + f"Compressed tag set would generate {tag_count} tags, exceeding " + f"limit {limit}" + ) + + try: + interpreters, abis, platforms = component_parts + except ValueError as exc: + raise InvalidTag(f"Tag {tag!r} must have exactly three components") from exc + for interpreter in interpreters: + if not interpreter.isidentifier(): + raise InvalidTag(f"Tag {tag!r} has an invalid interpreter: {interpreter!r}") + return frozenset( + Tag(interpreter, abi, platform_) + for interpreter in interpreters + for abi in abis + for platform_ in platforms + ) + + +def _get_config_var(name: str, warn: bool = False) -> int | str | None: + value: int | str | None = sysconfig.get_config_var(name) + if value is None and warn: + logger.debug( + "Config variable '%s' is unset, Python ABI tag may be incorrect", name + ) + return value + + +def _normalize_string(string: str) -> str: + return string.replace(".", "_").replace("-", "_").replace(" ", "_") + + +def _is_threaded_cpython(abis: list[str]) -> bool: + """ + Determine if the ABI corresponds to a threaded (`--disable-gil`) build. + + The threaded builds are indicated by a "t" in the abiflags. + """ + if len(abis) == 0: + return False + # expect e.g., cp313 + m = re.match(r"cp\d+(.*)", abis[0]) + if not m: + return False + abiflags = m.group(1) + return "t" in abiflags + + +def _abi3_applies(python_version: PythonVersion, threading: bool) -> bool: + """ + Determine if the Python version supports abi3. + + PEP 384 was first implemented in Python 3.2. The free-threaded + builds do not support abi3. + """ + return len(python_version) > 1 and tuple(python_version) >= (3, 2) and not threading + + +def _abi3t_applies(python_version: PythonVersion, threading: bool) -> bool: + """ + Determine if the Python version supports abi3t. + + PEP 803 was first implemented in Python 3.15 but, per PEP 803, this + returns tags going back to Python 3.2 to mirror the abi3 + implementation and leave open the possibility of abi3t wheels + supporting older Python versions. + + """ + return len(python_version) > 1 and tuple(python_version) >= (3, 2) and threading + + +def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> list[str]: + py_version = tuple(py_version) # To allow for version comparison. + abis = [] + version = _version_nodot(py_version[:2]) + threading = debug = pymalloc = ucs4 = "" + with_debug = _get_config_var("Py_DEBUG", warn) + has_refcount = hasattr(sys, "gettotalrefcount") + # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled + # extension modules is the best option. + # https://github.com/pypa/pip/issues/3383#issuecomment-173267692 + has_ext = "_d.pyd" in EXTENSION_SUFFIXES + if with_debug or (with_debug is None and (has_refcount or has_ext)): + debug = "d" + if py_version >= (3, 13) and _get_config_var("Py_GIL_DISABLED", warn): + threading = "t" + if py_version < (3, 8): + with_pymalloc = _get_config_var("WITH_PYMALLOC", warn) + if with_pymalloc or with_pymalloc is None: + pymalloc = "m" + if py_version < (3, 3): + unicode_size = _get_config_var("Py_UNICODE_SIZE", warn) + if unicode_size == 4 or ( + unicode_size is None and sys.maxunicode == 0x10FFFF + ): + ucs4 = "u" + elif debug: + # Debug builds can also load "normal" extension modules. + # We can also assume no UCS-4 or pymalloc requirement. + abis.append(f"cp{version}{threading}") + abis.insert(0, f"cp{version}{threading}{debug}{pymalloc}{ucs4}") + return abis + + +def cpython_tags( + python_version: PythonVersion | None = None, + abis: Iterable[str] | None = None, + platforms: Iterable[str] | None = None, + *, + warn: bool = False, +) -> Iterator[Tag]: + """ + Yields the tags for the CPython interpreter. + + The specific tags generated are: + + - ``cp--`` + - ``cp--`` + - ``cp-none-`` + - ``cp--`` where "older version" is all older + minor versions down to Python 3.2 (when ``abi3`` was introduced) + + If ``python_version`` only provides a major-only version then only + user-provided ABIs via ``abis`` and the ``none`` ABI will be used. + + The ``stable_abi`` will be either ``abi3`` or ``abi3t`` if `abi` is a + GIL-enabled ABI like `"cp315"` or a free-threaded ABI like `"cp315t"`, + respectively. + + :param Sequence python_version: A one- or two-item sequence representing the + targeted Python version. Defaults to + ``sys.version_info[:2]``. + :param Iterable abis: Iterable of compatible ABIs. Defaults to the ABIs + compatible with the current system. + :param Iterable platforms: Iterable of compatible platforms. Defaults to the + platforms compatible with the current system. + :param bool warn: Whether warnings should be logged. Defaults to ``False``. + + .. versionadded:: 20.0 + """ + if not python_version: + python_version = sys.version_info[:2] + + interpreter = f"cp{_version_nodot(python_version[:2])}" + + if abis is None: + abis = _cpython_abis(python_version, warn) if len(python_version) > 1 else [] + abis = list(abis) + threading = _is_threaded_cpython(abis) + # Stable ABIs and 'none' are explicitly handled later. + explicit_abis = ("abi3", "abi3t", "none") if threading else ("abi3", "none") + for explicit_abi in explicit_abis: + try: + abis.remove(explicit_abi) + except ValueError: # noqa: PERF203 + pass + + platforms = list(platforms or platform_tags()) + for abi in abis: + for platform_ in platforms: + yield Tag(interpreter, abi, platform_) + + use_abi3 = _abi3_applies(python_version, threading) + use_abi3t = _abi3t_applies(python_version, threading) + if use_abi3: + yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms) + if use_abi3t: + yield from (Tag(interpreter, "abi3t", platform_) for platform_ in platforms) + + yield from (Tag(interpreter, "none", platform_) for platform_ in platforms) + + if use_abi3 or use_abi3t: + for minor_version in range(python_version[1] - 1, 1, -1): + for platform_ in platforms: + version = _version_nodot((python_version[0], minor_version)) + interpreter = f"cp{version}" + if use_abi3: + yield Tag(interpreter, "abi3", platform_) + if use_abi3t: + # Support for abi3t was introduced in Python 3.15, but in + # principle abi3t wheels are possible for older limited API + # versions, so allow things like ("cp37", "abi3t", "platform") + yield Tag(interpreter, "abi3t", platform_) + + +def _generic_abi() -> list[str]: + """ + Return the ABI tag based on EXT_SUFFIX. + """ + # The following are examples of `EXT_SUFFIX`. + # We want to keep the parts which are related to the ABI and remove the + # parts which are related to the platform: + # - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310 + # - mac: '.cpython-310-darwin.so' => cp310 + # - win: '.cp310-win_amd64.pyd' => cp310 + # - win: '.pyd' => cp37 (uses _cpython_abis()) + # - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73 + # - graalpy: '.graalpy-38-native-x86_64-darwin.dylib' + # => graalpy_38_native + + ext_suffix = _get_config_var("EXT_SUFFIX", warn=True) + if not isinstance(ext_suffix, str) or not ext_suffix.startswith("."): + raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')") + parts = ext_suffix.split(".") + if len(parts) < 3: + # CPython3.7 and earlier uses ".pyd" on Windows. + return _cpython_abis(sys.version_info[:2]) + soabi = parts[1] + if soabi.startswith("cpython"): + # non-windows + cpython_parts = soabi.split("-") + if len(cpython_parts) < 2 or not cpython_parts[1]: + raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')") + abi = "cp" + cpython_parts[1] + elif soabi.startswith("cp"): + # windows + abi = soabi.split("-")[0] + elif soabi.startswith("pypy"): + abi = "-".join(soabi.split("-")[:2]) + elif soabi.startswith("graalpy"): + abi = "-".join(soabi.split("-")[:3]) + elif soabi: + # pyston, ironpython, others? + abi = soabi + else: + return [] + return [_normalize_string(abi)] + + +def generic_tags( + interpreter: str | None = None, + abis: Iterable[str] | None = None, + platforms: Iterable[str] | None = None, + *, + warn: bool = False, +) -> Iterator[Tag]: + """ + Yields the tags for an interpreter which requires no specialization. + + This function should be used if one of the other interpreter-specific + functions provided by this module is not appropriate (i.e. not calculating + tags for a CPython interpreter). + + The specific tags generated are: + + - ``--`` + + The ``"none"`` ABI will be added if it was not explicitly provided. + + :param str interpreter: The name of the interpreter. Defaults to being + calculated. + :param Iterable abis: Iterable of compatible ABIs. Defaults to the ABIs + compatible with the current system. + :param Iterable platforms: Iterable of compatible platforms. Defaults to the + platforms compatible with the current system. + :param bool warn: Whether warnings should be logged. Defaults to ``False``. + + .. versionadded:: 20.0 + """ + if not interpreter: + interp_name = interpreter_name() + interp_version = interpreter_version(warn=warn) + interpreter = f"{interp_name}{interp_version}" + abis = _generic_abi() if abis is None else list(abis) + platforms = list(platforms or platform_tags()) + if "none" not in abis: + abis.append("none") + for abi in abis: + for platform_ in platforms: + yield Tag(interpreter, abi, platform_) + + +def _py_interpreter_range(py_version: PythonVersion) -> Iterator[str]: + """ + Yields Python versions in descending order. + + After the latest version, the major-only version will be yielded, and then + all previous versions of that major version. + """ + if len(py_version) > 1: + yield f"py{_version_nodot(py_version[:2])}" + yield f"py{py_version[0]}" + if len(py_version) > 1: + for minor in range(py_version[1] - 1, -1, -1): + yield f"py{_version_nodot((py_version[0], minor))}" + + +def pure_python_tags( + python_version: PythonVersion | None = None, +) -> Iterator[Tag]: + """ + Yields the pure-Python tags compatible with ``python_version``. + + The tags use the ``"none"`` ABI and ``"any"`` platform, so their + generation does not depend on the running platform. + + .. versionadded:: 26.3 + + :param Sequence python_version: A one- or two-item sequence representing the + compatible version of Python. Defaults to + ``sys.version_info[:2]``. + :raises ValueError: If ``python_version`` is an empty sequence. + """ + if python_version is None: + python_version = sys.version_info[:2] + elif not python_version: + raise ValueError("python_version must contain at least one item") + for version in _py_interpreter_range(python_version): + yield Tag(version, "none", "any") + + +def compatible_tags( + python_version: PythonVersion | None = None, + interpreter: str | None = None, + platforms: Iterable[str] | None = None, +) -> Iterator[Tag]: + """ + Yields the tags for an interpreter compatible with the Python version + specified by ``python_version``. + + The specific tags generated are: + + - ``py*-none-`` + - ``-none-any`` if ``interpreter`` is provided + - ``py*-none-any`` + + :param Sequence python_version: A one- or two-item sequence representing the + compatible version of Python. Defaults to + ``sys.version_info[:2]``. + :param str interpreter: The name of the interpreter (if known), e.g. + ``"cp38"``. Defaults to the current interpreter. + :param Iterable platforms: Iterable of compatible platforms. Defaults to the + platforms compatible with the current system. + + .. versionadded:: 20.0 + """ + if not python_version: + python_version = sys.version_info[:2] + platforms = list(platforms or platform_tags()) + for version in _py_interpreter_range(python_version): + for platform_ in platforms: + yield Tag(version, "none", platform_) + if interpreter: + yield Tag(interpreter, "none", "any") + yield from pure_python_tags(python_version) + + +def _mac_arch(arch: str, is_32bit: bool = _32_BIT_INTERPRETER) -> str: + if not is_32bit: + return arch + + if arch.startswith("ppc"): + return "ppc" + + return "i386" + + +def _mac_binary_formats(version: AppleVersion, cpu_arch: str) -> list[str]: + formats = [cpu_arch] + if cpu_arch == "x86_64": + if version < (10, 4): + return [] + formats.extend(["intel", "fat64", "fat3"]) + + elif cpu_arch == "i386": + if version < (10, 4): + return [] + formats.extend(["intel", "fat3", "fat"]) + + elif cpu_arch == "ppc64": + # TODO: Need to care about 32-bit PPC for ppc64 through 10.2? + if version > (10, 5) or version < (10, 4): + return [] + formats.append("fat64") + + elif cpu_arch == "ppc": + if version > (10, 6): + return [] + formats.extend(["fat3", "fat"]) + + if cpu_arch in {"arm64", "x86_64"}: + formats.append("universal2") + + if cpu_arch in {"x86_64", "i386", "ppc64", "ppc", "intel"}: + formats.append("universal") + + return formats + + +def mac_platforms( + version: AppleVersion | None = None, arch: str | None = None +) -> Iterator[str]: + """ + Yields the :attr:`~Tag.platform` tags for macOS. + + The `version` parameter is a two-item tuple specifying the macOS version to + generate platform tags for. The `arch` parameter is the CPU architecture to + generate platform tags for. Both parameters default to the appropriate value + for the current system. + + :param tuple version: A two-item tuple representing the version of macOS. + Defaults to the current system's version. + :param str arch: The CPU architecture. Defaults to the architecture of the + current system, e.g. ``"x86_64"``. + + .. note:: + Equivalent support for the other major platforms is purposefully not + provided: + + - On Windows, platform compatibility is statically specified + - On Linux, code must be run on the system itself to determine + compatibility + + .. versionadded:: 20.0 + """ + if version is None or arch is None: + version_str, _, cpu_arch = platform.mac_ver() + if version is None: + version = cast("AppleVersion", tuple(map(int, version_str.split(".")[:2]))) + if version == (10, 16): + # When built against an older macOS SDK, Python will report macOS 10.16 + # instead of the real version. + version_str = subprocess.run( + [ + sys.executable, + "-sS", + "-c", + "import platform; print(platform.mac_ver()[0])", + ], + check=True, + env={"SYSTEM_VERSION_COMPAT": "0"}, + stdout=subprocess.PIPE, + text=True, + ).stdout + version = cast( + "AppleVersion", tuple(map(int, version_str.split(".")[:2])) + ) + if arch is None: + arch = _mac_arch(cpu_arch) + + if (10, 0) <= version < (11, 0): + # Prior to Mac OS 11, each yearly release of Mac OS bumped the + # "minor" version number. The major version was always 10. + major_version = 10 + for minor_version in range(version[1], -1, -1): + compat_version = major_version, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield f"macosx_{major_version}_{minor_version}_{binary_format}" + + if version >= (11, 0): + # Starting with Mac OS 11, each yearly release bumps the major version + # number. The minor versions are now the midyear updates. + minor_version = 0 + for major_version in range(version[0], 10, -1): + compat_version = major_version, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield f"macosx_{major_version}_{minor_version}_{binary_format}" + + # Mac OS 11 on x86_64 is compatible with binaries from previous releases. + # Arm64 support was introduced in 11.0, so no Arm binaries from previous + # releases exist. + # + # However, the "universal2" binary format can have a + # macOS version earlier than 11.0 when the x86_64 part of the binary supports + # that version of macOS. + major_version = 10 + if arch == "x86_64": + for minor_version in range(16, 3, -1): + compat_version = major_version, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield f"macosx_{major_version}_{minor_version}_{binary_format}" + else: + for minor_version in range(16, 3, -1): + compat_version = major_version, minor_version + binary_format = "universal2" + yield f"macosx_{major_version}_{minor_version}_{binary_format}" + + +def ios_platforms( + version: AppleVersion | None = None, multiarch: str | None = None +) -> Iterator[str]: + """ + + Yields the :attr:`~Tag.platform` tags for iOS. + + :param tuple version: A two-item tuple representing the version of iOS. + Defaults to the current system's version. + :param str multiarch: The CPU architecture+ABI to be used. This should be in + the format by ``sys.implementation._multiarch`` (e.g., + ``arm64_iphoneos`` or ``x86_64_iphonesimulator``). + Defaults to the current system's multiarch value. + + .. note:: + Behavior of this method is undefined if invoked on non-iOS platforms + without providing explicit version and multiarch arguments. + + .. versionadded:: 24.2 + """ + if version is None: + # if iOS is the current platform, ios_ver *must* be defined. However, + # it won't exist for CPython versions before 3.13, which causes a mypy + # error. + _, release, _, _ = platform.ios_ver() # type: ignore[attr-defined, unused-ignore] + version = cast("AppleVersion", tuple(map(int, release.split(".")[:2]))) + + if multiarch is None: + multiarch = sys.implementation._multiarch + multiarch = multiarch.replace("-", "_") + + ios_platform_template = "ios_{major}_{minor}_{multiarch}" + + # Consider any iOS major.minor version from the version requested, down to + # 12.0. 12.0 is the first iOS version that is known to have enough features + # to support CPython. Consider every possible minor release up to X.9. There + # highest the minor has ever gone is 8 (14.8 and 15.8) but having some extra + # candidates that won't ever match doesn't really hurt, and it saves us from + # having to keep an explicit list of known iOS versions in the code. Return + # the results descending order of version number. + + # If the requested major version is less than 12, there won't be any matches. + if version[0] < 12: + return + + # Consider the actual X.Y version that was requested. + yield ios_platform_template.format( + major=version[0], minor=version[1], multiarch=multiarch + ) + + # Consider every minor version from X.0 to the minor version prior to the + # version requested by the platform. + for minor in range(version[1] - 1, -1, -1): + yield ios_platform_template.format( + major=version[0], minor=minor, multiarch=multiarch + ) + + for major in range(version[0] - 1, 11, -1): + for minor in range(9, -1, -1): + yield ios_platform_template.format( + major=major, minor=minor, multiarch=multiarch + ) + + +def android_platforms( + api_level: int | None = None, abi: str | None = None +) -> Iterator[str]: + """ + Yields the :attr:`~Tag.platform` tags for Android. If this function is invoked on + non-Android platforms, the ``api_level`` and ``abi`` arguments are required. + + :param int api_level: The maximum `API level + `__ to return. Defaults + to the current system's version, as returned by ``platform.android_ver``. + :param str abi: The `Android ABI `__, + e.g. ``arm64_v8a``. Defaults to the current system's ABI , as returned by + ``sysconfig.get_platform``. Hyphens and periods will be replaced with + underscores. + + .. versionadded:: 25.0 + """ + if platform.system() != "Android" and (api_level is None or abi is None): + raise TypeError( + "on non-Android platforms, the api_level and abi arguments are required" + ) + + if api_level is None: + # Python 3.13 was the first version to return platform.system() == "Android", + # and also the first version to define platform.android_ver(). + api_level = platform.android_ver().api_level # type: ignore[attr-defined] + + if abi is None: + abi = sysconfig.get_platform().split("-")[-1] + abi = _normalize_string(abi) + + # 16 is the minimum API level known to have enough features to support CPython + # without major patching. Yield every API level from the maximum down to the + # minimum, inclusive. + min_api_level = 16 + for ver in range(api_level, min_api_level - 1, -1): + yield f"android_{ver}_{abi}" + + +def _linux_platforms(is_32bit: bool = _32_BIT_INTERPRETER) -> Iterator[str]: + linux = _normalize_string(sysconfig.get_platform()) + if not linux.startswith("linux_"): + # we should never be here, just yield the sysconfig one and return + yield linux + return + if is_32bit: + if linux == "linux_x86_64": + linux = "linux_i686" + elif linux == "linux_aarch64": + linux = "linux_armv8l" + _, arch = linux.split("_", 1) + archs = {"armv8l": ["armv8l", "armv7l"]}.get(arch, [arch]) + for arch in archs: + yield f"linux_{arch}" + yield from _manylinux.platform_tags(archs) + yield from _musllinux.platform_tags(archs) + + +def _emscripten_platforms() -> Iterator[str]: + pyemscripten_platform_version = sysconfig.get_config_var( + "PYEMSCRIPTEN_PLATFORM_VERSION" + ) + if pyemscripten_platform_version: + yield f"pyemscripten_{pyemscripten_platform_version}_wasm32" + yield from _generic_platforms() + + +def _generic_platforms() -> Iterator[str]: + yield _normalize_string(sysconfig.get_platform()) + + +def platform_tags() -> Iterator[str]: + """ + Yields the :attr:`~Tag.platform` tags for the running interpreter. + + .. versionadded:: 21.1 + """ + if platform.system() == "Darwin": + return mac_platforms() + elif platform.system() == "iOS": + return ios_platforms() + elif platform.system() == "Android": + return android_platforms() + elif platform.system() == "Linux": + return _linux_platforms() + elif platform.system() == "Emscripten": + return _emscripten_platforms() + else: + return _generic_platforms() + + +def interpreter_name() -> str: + """ + Returns the name of the running interpreter. + + Some implementations have a reserved, two-letter abbreviation which will + be returned when appropriate. + + This typically acts as the prefix to the :attr:`~Tag.interpreter` tag. + + .. versionadded:: 20.0 + """ + name = sys.implementation.name + return INTERPRETER_SHORT_NAMES.get(name) or name + + +def interpreter_version(*, warn: bool = False) -> str: + """ + Returns the running interpreter's version. + + This typically acts as the suffix to the :attr:`~Tag.interpreter` tag. + + :param bool warn: Whether warnings should be logged. Defaults to ``False``. + + .. versionadded:: 20.0 + """ + version = _get_config_var("py_version_nodot", warn=warn) + return str(version) if version else _version_nodot(sys.version_info[:2]) + + +def _version_nodot(version: PythonVersion) -> str: + return "".join(map(str, version)) + + +def sys_tags(*, warn: bool = False) -> Iterator[Tag]: + """ + Yields the sequence of tag triples that the running interpreter supports. + + The iterable is ordered so that the best-matching tag is first in the + sequence. The exact preferential order to tags is interpreter-specific, but + in general the tag importance is in the order of: + + 1. Interpreter + 2. Platform + 3. ABI + + This order is due to the fact that an ABI is inherently tied to the + platform, but platform-specific code is not necessarily tied to the ABI. The + interpreter is the most important tag as it dictates basic support for any + wheel. + + The function returns an iterable in order to allow for the possible + short-circuiting of tag generation if the entire sequence is not necessary + and tag calculation happens to be expensive. + + :param bool warn: Whether warnings should be logged. Defaults to ``False``. + + .. versionchanged:: 21.3 + Added the `pp3-none-any` tag (:issue:`311`). + .. versionchanged:: 26.1 + Added the `abi3t` tag (:issue:`1099`). + .. versionchanged:: 26.3 + Native ``linux_*`` platform tags are now ordered before ``manylinux`` + and ``musllinux`` tags (:issue:`160`). + """ + + interp_name = interpreter_name() + if interp_name == "cp": + yield from cpython_tags(warn=warn) + else: + yield from generic_tags(warn=warn) + + if interp_name == "pp": + interp = "pp3" + elif interp_name == "cp": + interp = "cp" + interpreter_version(warn=warn) + else: + interp = None + yield from compatible_tags(interpreter=interp) + + +def create_compatible_tags_selector( + tags: Iterable[Tag], +) -> Callable[[Iterable[tuple[_T, AbstractSet[Tag]]]], Iterator[_T]]: + """Create a callable to select things compatible with supported tags. + + This function accepts an ordered sequence of tags, with the preferred + tags first. + + The returned callable accepts an iterable of tuples (thing, set[Tag]), + and returns an iterator of things, with the things with the best + matching tags first. + + Example to select compatible wheel filenames: + + >>> from packaging import tags + >>> from packaging.utils import parse_wheel_filename + >>> selector = tags.create_compatible_tags_selector(tags.sys_tags()) + >>> filenames = ["foo-1.0-py3-none-any.whl", "foo-1.0-py2-none-any.whl"] + >>> list(selector([ + ... (filename, parse_wheel_filename(filename)[-1]) for filename in filenames + ... ])) + ['foo-1.0-py3-none-any.whl'] + + .. versionadded:: 26.1 + """ + tag_ranks: dict[Tag, int] = {} + for rank, tag in enumerate(tags): + tag_ranks.setdefault(tag, rank) # ignore duplicate tags, keep first + supported_tags = tag_ranks.keys() + + def selector( + tagged_things: Iterable[tuple[_T, AbstractSet[Tag]]], + ) -> Iterator[_T]: + ranked_things: list[tuple[_T, int]] = [] + for thing, thing_tags in tagged_things: + supported_thing_tags = thing_tags & supported_tags + if supported_thing_tags: + thing_rank = min(tag_ranks[t] for t in supported_thing_tags) + ranked_things.append((thing, thing_rank)) + return iter( + thing for thing, _ in sorted(ranked_things, key=operator.itemgetter(1)) + ) + + return selector diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py new file mode 100644 index 00000000000..2f0ce207447 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py @@ -0,0 +1,370 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import annotations + +import re +from typing import NewType, Union, cast + +from .tags import InvalidTag, Tag, UnsortedTagsError, parse_tag +from .version import InvalidVersion, Version, _TrimmedRelease + +__all__ = [ + "BuildTag", + "InvalidName", + "InvalidSdistFilename", + "InvalidWheelFilename", + "NormalizedName", + "canonicalize_name", + "canonicalize_version", + "is_normalized_name", + "parse_sdist_filename", + "parse_wheel_filename", +] + + +def __dir__() -> list[str]: + return __all__ + + +BuildTag = Union[tuple[()], tuple[int, str]] +""" +A wheel build tag: an empty tuple, or a ``(build number, build tag suffix)`` pair. + +.. versionadded:: 20.9 +""" + +NormalizedName = NewType("NormalizedName", str) +""" +A :class:`typing.NewType` of :class:`str`, representing a normalized name. + +.. versionadded:: 20.4 +""" + + +class InvalidName(ValueError): + """ + An invalid distribution name; users should refer to the packaging user guide. + + .. versionadded:: 23.2 + """ + + +class InvalidWheelFilename(ValueError): + """ + An invalid wheel filename was found, users should refer to PEP 427. + + .. versionadded:: 20.9 + """ + + +class InvalidSdistFilename(ValueError): + """ + An invalid sdist filename was found, users should refer to the packaging user guide. + + .. versionadded:: 20.9 + """ + + +# Core metadata spec for `Name` +_validate_regex = re.compile( + r"[a-z0-9]|[a-z0-9][a-z0-9._-]*[a-z0-9]", re.IGNORECASE | re.ASCII +) +_normalized_regex = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*", re.ASCII) +# PEP 427: The build number must start with a digit. +_build_tag_regex = re.compile(r"(\d+)(.*)", re.ASCII) +# PEP 427: Valid characters for an escaped project name in a wheel filename. +# Requires at least one character so an empty project name is rejected. +_wheel_name_regex = re.compile(r"^[\w._]+\Z", re.UNICODE) + + +def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName: + """ + This function takes a valid Python package or extra name, and returns the + normalized form of it. + + The return type is typed as :class:`NormalizedName`. This allows type + checkers to help require that a string has passed through this function + before use. + + If **validate** is true, then the function will check if **name** is a valid + distribution name before normalizing. + + :param str name: The name to normalize. + :param bool validate: Check whether the name is a valid distribution name. + :raises InvalidName: If **validate** is true and the name is not an + acceptable distribution name. + + >>> from packaging.utils import canonicalize_name + >>> canonicalize_name("Django") + 'django' + >>> canonicalize_name("oslo.concurrency") + 'oslo-concurrency' + >>> canonicalize_name("requests") + 'requests' + + .. versionadded:: 16.2 + + .. versionchanged:: 20.4 + The return type was changed to :class:`NormalizedName`. + + .. versionchanged:: 23.2 + Added the *validate* keyword parameter. + """ + if validate and not _validate_regex.fullmatch(name): + raise InvalidName(f"name is invalid: {name!r}") + # Ensure all ``.`` and ``_`` are ``-`` + # Emulates ``re.sub(r"[-_.]+", "-", name).lower()`` from PEP 503 + # Much faster than re, and even faster than str.translate + value = name.lower().replace("_", "-").replace(".", "-") + # Condense repeats (faster than regex) + while "--" in value: + value = value.replace("--", "-") + return cast("NormalizedName", value) + + +def is_normalized_name(name: str) -> bool: + """ + Check if a name is a normalized project name (i.e. a valid name that + :func:`canonicalize_name` would roundtrip to the same value). + + The roundtrip only characterizes normalized names for *valid* names. A name + must start and end with an ASCII letter or digit, which + :func:`canonicalize_name` does not enforce: it leaves a leading or trailing + hyphen in place, so such a name roundtrips without being normalized. + + :param str name: The name to check. + + >>> from packaging.utils import canonicalize_name, is_normalized_name + >>> is_normalized_name("requests") + True + >>> is_normalized_name("Django") + False + >>> canonicalize_name("_not_legal") + '-not-legal' + >>> is_normalized_name("-not-legal") # roundtrips, but not a valid name + False + + .. versionadded:: 23.2 + """ + return _normalized_regex.fullmatch(name) is not None + + +def canonicalize_version( + version: Version | str, *, strip_trailing_zero: bool = True +) -> str: + """Return a canonical form of a version as a string. + + This function takes a string representing a package version (or a + :class:`~packaging.version.Version` instance), and returns the + normalized form of it. By default, it strips trailing zeros from + the release segment. + + >>> from packaging.utils import canonicalize_version + >>> canonicalize_version('1.0.1') + '1.0.1' + + Per PEP 625, versions may have multiple canonical forms, differing + only by trailing zeros. + + >>> canonicalize_version('1.0.0') + '1' + >>> canonicalize_version('1.0.0', strip_trailing_zero=False) + '1.0.0' + + Invalid versions are returned unaltered. + + >>> canonicalize_version('foo bar baz') + 'foo bar baz' + + >>> canonicalize_version('1.4.0.0.0') + '1.4' + + .. versionadded:: 17.1 + + .. versionchanged:: 21.0 + The return type was narrowed to :class:`str`. + + .. versionchanged:: 22.0 + Added the *strip_trailing_zero* keyword parameter. + """ + if isinstance(version, str): + try: + version = Version(version) + except InvalidVersion: + return str(version) + return str(_TrimmedRelease(version) if strip_trailing_zero else version) + + +def parse_wheel_filename( + filename: str, + *, + validate_order: bool = False, +) -> tuple[NormalizedName, Version, BuildTag, frozenset[Tag]]: + """ + This function takes the filename of a wheel file, and parses it, + returning a tuple of name, version, build number, and tags. + + The name part of the tuple is normalized and typed as + :class:`NormalizedName`. The version portion is an instance of + :class:`~packaging.version.Version`. The build number is ``()`` if + there is no build number in the wheel filename, otherwise a + two-item tuple of an integer for the leading digits and + a string for the rest of the build number. The tags portion is a + frozen set of :class:`~packaging.tags.Tag` instances (as the tag + string format allows multiple tags to be combined into a single + string). + + If **validate_order** is true, compressed tag set components are + checked to be in sorted order as required by PEP 425. + + :param str filename: The name of the wheel file. + :param bool validate_order: Check whether compressed tag set components + are in sorted order. + :raises InvalidWheelFilename: If the filename in question + does not follow the :ref:`wheel specification + `. + + >>> from packaging.utils import parse_wheel_filename + >>> from packaging.tags import Tag + >>> from packaging.version import Version + >>> name, ver, build, tags = parse_wheel_filename("foo-1.0-py3-none-any.whl") + >>> name + 'foo' + >>> ver == Version('1.0') + True + >>> tags == {Tag("py3", "none", "any")} + True + >>> not build + True + + .. versionadded:: 20.9 + + .. versionchanged:: 23.2 + Raises :class:`InvalidWheelFilename` when the version component is invalid. + + .. versionadded:: 26.1 + The *validate_order* parameter. + + .. versionchanged:: 26.3 + Raises :class:`InvalidWheelFilename` when an interpreter component is + not an identifier, a tag set component is empty, or the project name is + empty. + """ + if not filename.endswith(".whl"): + raise InvalidWheelFilename( + f"Invalid wheel filename (extension must be '.whl'): {filename!r}" + ) + + filename = filename[:-4] + dashes = filename.count("-") + if dashes not in (4, 5): + raise InvalidWheelFilename( + f"Invalid wheel filename (wrong number of parts): {filename!r}" + ) + + parts = filename.split("-", dashes - 2) + name_part = parts[0] + # See PEP 427 for the rules on escaping the project name. + if "__" in name_part or _wheel_name_regex.match(name_part) is None: + raise InvalidWheelFilename(f"Invalid project name: {filename!r}") + name = canonicalize_name(name_part) + + try: + version = Version(parts[1]) + except InvalidVersion as e: + raise InvalidWheelFilename( + f"Invalid wheel filename (invalid version): {filename!r}" + ) from e + + if dashes == 5: + build_part = parts[2] + build_match = _build_tag_regex.match(build_part) + if build_match is None: + raise InvalidWheelFilename( + f"Invalid build number: {build_part} in {filename!r}" + ) + build = cast("BuildTag", (int(build_match.group(1)), build_match.group(2))) + else: + build = () + tag_str = parts[-1] + try: + tags = parse_tag(tag_str, validate_order=validate_order) + except UnsortedTagsError: + raise InvalidWheelFilename( + f"Invalid wheel filename (compressed tag set components must be in " + f"sorted order per PEP 425): {filename!r}" + ) from None + except InvalidTag: + raise InvalidWheelFilename( + f"Invalid wheel filename (invalid tag component): {filename!r}" + ) from None + return (name, version, build, tags) + + +def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]: + """ + This function takes the filename of a sdist file (as specified + in the `Source distribution format`_ documentation), and parses + it, returning a tuple of the normalized name and version as + represented by an instance of :class:`~packaging.version.Version`. + + :param str filename: The name of the sdist file. + :raises InvalidSdistFilename: If the filename does not end + with an sdist extension (``.zip`` or ``.tar.gz``), if it does not + contain a dash separating the name and the version of the distribution, + if the project name is empty, or if the version portion is not a valid + version. + + >>> from packaging.utils import parse_sdist_filename + >>> from packaging.version import Version + >>> name, ver = parse_sdist_filename("foo-1.0.tar.gz") + >>> name + 'foo' + >>> ver == Version('1.0') + True + + .. versionadded:: 20.9 + + .. versionchanged:: 21.0 + Added support for ``.zip`` source distributions. + + .. versionchanged:: 23.2 + Raises :class:`InvalidSdistFilename` when the version component is invalid. + + .. versionchanged:: 26.3 + Raises :class:`InvalidSdistFilename` on an empty project name. + + .. _Source distribution format: https://packaging.python.org/specifications/source-distribution-format/#source-distribution-file-name + """ + if filename.endswith(".tar.gz"): + file_stem = filename[: -len(".tar.gz")] + elif filename.endswith(".zip"): + file_stem = filename[: -len(".zip")] + else: + raise InvalidSdistFilename( + f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):" + f" {filename!r}" + ) + + # We are requiring a PEP 440 version, which cannot contain dashes, + # so we split on the last dash. + name_part, sep, version_part = file_stem.rpartition("-") + if not sep: + raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}") + if not name_part: + raise InvalidSdistFilename( + f"Invalid sdist filename (empty project name): {filename!r}" + ) + + name = canonicalize_name(name_part) + + try: + version = Version(version_part) + except InvalidVersion as e: + raise InvalidSdistFilename( + f"Invalid sdist filename (invalid version): {filename!r}" + ) from e + + return (name, version) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py new file mode 100644 index 00000000000..48e214004c7 --- /dev/null +++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py @@ -0,0 +1,1252 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +""" +.. testsetup:: + + from packaging.version import parse, normalize_pre, Version, _cmpkey +""" + +from __future__ import annotations + +import re +import sys +import typing +from typing import ( + Any, + Callable, + Literal, + NamedTuple, + SupportsInt, + TypedDict, + Union, +) + +if typing.TYPE_CHECKING: + from opentelemetry.agent._vendor.typing_extensions import Self, Unpack + +if sys.version_info >= (3, 13): # pragma: no cover + from warnings import deprecated as _deprecated +elif typing.TYPE_CHECKING: + from opentelemetry.agent._vendor.typing_extensions import deprecated as _deprecated +else: # pragma: no cover + import functools + import warnings + + def _deprecated(message: str) -> object: + def decorator(func: Callable[[...], object]) -> object: + @functools.wraps(func) + def wrapper(*args: object, **kwargs: object) -> object: + warnings.warn( + message, + category=DeprecationWarning, + stacklevel=2, + ) + return func(*args, **kwargs) + + return wrapper + + return decorator + + +_LETTER_NORMALIZATION = { + "alpha": "a", + "beta": "b", + "c": "rc", + "pre": "rc", + "preview": "rc", + "rev": "post", + "r": "post", +} + +__all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "normalize_pre", "parse"] + + +def __dir__() -> list[str]: + return __all__ + + +LocalType = tuple[Union[int, str], ...] + +CmpLocalType = tuple[tuple[int, str], ...] +CmpSuffix = tuple[int, int, int, int, int, int] +CmpKey = Union[ + tuple[int, tuple[int, ...], CmpSuffix], + tuple[int, tuple[int, ...], CmpSuffix, CmpLocalType], +] +VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool] + + +class _VersionReplace(TypedDict, total=False): + epoch: int | None + release: tuple[int, ...] | None + pre: tuple[str, int] | None + post: int | None + dev: int | None + local: str | None + + +def normalize_pre(letter: str, /) -> str: + """Normalize the pre-release segment of a version string. + + Returns a lowercase version of the string if not a known pre-release + identifier. + + >>> normalize_pre('alpha') + 'a' + >>> normalize_pre('BETA') + 'b' + >>> normalize_pre('rc') + 'rc' + + :param letter: + + .. versionadded:: 26.1 + """ + letter = letter.lower() + return _LETTER_NORMALIZATION.get(letter, letter) + + +def parse(version: str) -> Version: + """Parse the given version string. + + This is identical to the :class:`Version` constructor. + + >>> parse('1.0.dev1') + + + :param version: The version string to parse. + :raises InvalidVersion: When the version string is not a valid version. + """ + return Version(version) + + +class InvalidVersion(ValueError): + """Raised when a version string is not a valid version. + + >>> Version("invalid") + Traceback (most recent call last): + ... + packaging.version.InvalidVersion: Invalid version: 'invalid' + """ + + +class _BaseVersion: + __slots__ = () + + # This can also be a normal member (see the packaging_legacy package); + # we are just requiring it to be readable. Actually defining a property + # has runtime effect on subclasses, so it's typing only. + if typing.TYPE_CHECKING: + + @property + def _key(self) -> tuple[Any, ...]: ... + + def __hash__(self) -> int: + return hash(self._key) + + # Please keep the duplicated `isinstance` check + # in the six comparisons hereunder + # unless you find a way to avoid adding overhead function calls. + def __lt__(self, other: _BaseVersion) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key < other._key + + def __le__(self, other: _BaseVersion) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key <= other._key + + def __eq__(self, other: object) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key == other._key + + def __ge__(self, other: _BaseVersion) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key >= other._key + + def __gt__(self, other: _BaseVersion) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key > other._key + + def __ne__(self, other: object) -> bool: + if not isinstance(other, _BaseVersion): + return NotImplemented + + return self._key != other._key + + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse + +# Note that ++ doesn't behave identically on CPython and PyPy, so not using it here +_VERSION_PATTERN = r""" + v?+ # optional leading v + (?a: + (?:(?P[0-9]+)!)?+ # epoch + (?P[0-9]+(?:\.[0-9]+)*+) # release segment + (?P
                                          # pre-release
+            [._-]?+
+            (?Palpha|a|beta|b|preview|pre|c|rc)
+            [._-]?+
+            (?P[0-9]+)?
+        )?+
+        (?P                                         # post release
+            (?:-(?P[0-9]+))
+            |
+            (?:
+                [._-]?
+                (?Ppost|rev|r)
+                [._-]?
+                (?P[0-9]+)?
+            )
+        )?+
+        (?P                                          # dev release
+            [._-]?+
+            (?Pdev)
+            [._-]?+
+            (?P[0-9]+)?
+        )?+
+    )
+    (?a:\+
+        (?P                                        # local version
+            [a-z0-9]+
+            (?:[._-][a-z0-9]+)*+
+        )
+    )?+
+"""
+
+_VERSION_PATTERN_OLD = _VERSION_PATTERN.replace("*+", "*").replace("?+", "?")
+
+# Possessive qualifiers were added in Python 3.11.
+# CPython 3.11.0-3.11.4 had a bug: https://github.com/python/cpython/pull/107795
+# Older PyPy also had a bug.
+VERSION_PATTERN = (
+    _VERSION_PATTERN_OLD
+    if (sys.implementation.name == "cpython" and sys.version_info < (3, 11, 5))
+    or (sys.implementation.name == "pypy" and sys.version_info < (3, 11, 13))
+    or sys.version_info < (3, 11)
+    else _VERSION_PATTERN
+)
+"""
+A string containing the regular expression used to match a valid version.
+
+The pattern is not anchored at either end, and is intended for embedding in larger
+expressions (for example, matching a version number as part of a file name). The
+regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE``
+flags set.
+
+.. versionchanged:: 26.0
+
+   The regex now uses possessive qualifiers on Python 3.11 if they are
+   supported (CPython 3.11.5+, PyPy 3.11.13+).
+
+:meta hide-value:
+"""
+
+
+# Validation pattern for local version in replace()
+_LOCAL_PATTERN = re.compile(r"[a-z0-9]+(?:[._-][a-z0-9]+)*", re.IGNORECASE | re.ASCII)
+
+# Fast path: If a version has only digits and dots then we
+# can skip the regex and parse it as a release segment
+_SIMPLE_VERSION_INDICATORS = frozenset(".0123456789")
+
+
+def _validate_epoch(value: object, /) -> int:
+    epoch = value or 0
+    if isinstance(epoch, int) and epoch >= 0:
+        return epoch
+    msg = f"epoch must be non-negative integer, got {epoch}"
+    raise InvalidVersion(msg)
+
+
+def _validate_release(value: object, /) -> tuple[int, ...]:
+    release = (0,) if value is None else value
+    if (
+        isinstance(release, tuple)
+        and len(release) > 0
+        and all(isinstance(i, int) and i >= 0 for i in release)
+    ):
+        return release
+    msg = f"release must be a non-empty tuple of non-negative integers, got {release}"
+    raise InvalidVersion(msg)
+
+
+def _validate_pre(value: object, /) -> tuple[Literal["a", "b", "rc"], int] | None:
+    if value is None:
+        return value
+    if isinstance(value, tuple) and len(value) == 2:
+        letter, number = value
+        # The letter must be a string before it can be normalized.
+        if (
+            isinstance(letter, str)
+            and (normalized := normalize_pre(letter)) in {"a", "b", "rc"}
+            and isinstance(number, int)
+            and number >= 0
+        ):
+            # type checkers can't infer the Literal type here on letter
+            return (normalized, number)  # type: ignore[return-value]
+    msg = f"pre must be a tuple of ('a'|'b'|'rc', non-negative int), got {value}"
+    raise InvalidVersion(msg)
+
+
+def _validate_post(value: object, /) -> tuple[Literal["post"], int] | None:
+    if value is None:
+        return value
+    if isinstance(value, int) and value >= 0:
+        return ("post", value)
+    msg = f"post must be non-negative integer, got {value}"
+    raise InvalidVersion(msg)
+
+
+def _validate_dev(value: object, /) -> tuple[Literal["dev"], int] | None:
+    if value is None:
+        return value
+    if isinstance(value, int) and value >= 0:
+        return ("dev", value)
+    msg = f"dev must be non-negative integer, got {value}"
+    raise InvalidVersion(msg)
+
+
+def _validate_local(value: object, /) -> LocalType | None:
+    if value is None:
+        return value
+    if isinstance(value, str) and _LOCAL_PATTERN.fullmatch(value):
+        return _parse_local_version(value)
+    msg = f"local must be a valid version string, got {value!r}"
+    raise InvalidVersion(msg)
+
+
+# Backward compatibility for internals before 26.0. Do not use.
+class _Version(NamedTuple):
+    epoch: int
+    release: tuple[int, ...]
+    dev: tuple[Literal["dev"], int] | None
+    pre: tuple[Literal["a", "b", "rc"], int] | None
+    post: tuple[Literal["post"], int] | None
+    local: LocalType | None
+
+
+class Version(_BaseVersion):
+    """This class abstracts handling of a project's versions.
+
+    A :class:`Version` instance is comparison aware and can be compared and
+    sorted using the standard Python interfaces.
+
+    >>> v1 = Version("1.0a5")
+    >>> v2 = Version("1.0")
+    >>> v1
+    
+    >>> v2
+    
+    >>> v1 < v2
+    True
+    >>> v1 == v2
+    False
+    >>> v1 > v2
+    False
+    >>> v1 >= v2
+    False
+    >>> v1 <= v2
+    True
+
+    :class:`Version` is immutable; use :meth:`__replace__` to change
+    part of a version.
+
+    Instances are safe to serialize with :mod:`pickle`. They use a stable
+    format so the same pickle can be loaded in future packaging releases.
+
+    .. versionchanged:: 26.2
+
+        Added a stable pickle format. Pickles created with packaging 26.2+ can
+        be unpickled with future releases.  Backward compatibility with pickles
+        from packaging < 26.2 is supported but may be removed in a future
+        release.
+    """
+
+    __slots__ = (
+        "_dev",
+        "_epoch",
+        "_hash_cache",
+        "_key_cache",
+        "_local",
+        "_post",
+        "_pre",
+        "_release",
+    )
+    __match_args__ = ("_str",)
+    """
+    Pattern matching is supported on Python 3.10+.
+
+    .. versionadded:: 26.0
+
+    :meta hide-value:
+    """
+
+    _regex = re.compile(r"\s*" + VERSION_PATTERN + r"\s*", re.VERBOSE | re.IGNORECASE)
+
+    _epoch: int
+    _release: tuple[int, ...]
+    _dev: tuple[Literal["dev"], int] | None
+    _pre: tuple[Literal["a", "b", "rc"], int] | None
+    _post: tuple[Literal["post"], int] | None
+    _local: LocalType | None
+
+    _hash_cache: int | None
+    _key_cache: CmpKey | None
+
+    def __init__(self, version: str) -> None:
+        """Initialize a Version object.
+
+        :param version:
+            The string representation of a version which will be parsed and normalized
+            before use.
+        :raises InvalidVersion:
+            If the ``version`` does not conform to PEP 440 in any way then this
+            exception will be raised.
+        """
+        try:
+            is_simple = _SIMPLE_VERSION_INDICATORS.issuperset(version)
+        except TypeError:
+            raise InvalidVersion(f"Invalid version: {version!r}") from None
+
+        if is_simple:
+            try:
+                self._release = tuple(map(int, version.split(".")))
+            except AttributeError:
+                raise InvalidVersion(f"Invalid version: {version!r}") from None
+            except ValueError:
+                # Empty parts (from "1..2", ".1", etc.) are invalid versions.
+                # Any other ValueError (e.g. int str-digits limit) should
+                # propagate to the caller.
+                if "" in version.split("."):
+                    raise InvalidVersion(f"Invalid version: {version!r}") from None
+                # TODO: remove "no cover" when Python 3.9 is dropped.
+                raise  # pragma: no cover
+
+            self._epoch = 0
+            self._pre = None
+            self._post = None
+            self._dev = None
+            self._local = None
+            self._key_cache = None
+            self._hash_cache = None
+            return
+
+        # Validate the version and parse it into pieces
+        try:
+            match = self._regex.fullmatch(version)
+        except TypeError:
+            raise InvalidVersion(f"Invalid version: {version!r}") from None
+        if not match:
+            raise InvalidVersion(f"Invalid version: {version!r}")
+        self._epoch = int(match.group("epoch")) if match.group("epoch") else 0
+        self._release = tuple(map(int, match.group("release").split(".")))
+        # We can type ignore the assignments below because the regex guarantees
+        # the correct strings
+        self._pre = _parse_letter_version(match.group("pre_l"), match.group("pre_n"))  # type: ignore[assignment]
+        self._post = _parse_letter_version(  # type: ignore[assignment]
+            match.group("post_l"), match.group("post_n1") or match.group("post_n2")
+        )
+        self._dev = _parse_letter_version(match.group("dev_l"), match.group("dev_n"))  # type: ignore[assignment]
+        self._local = _parse_local_version(match.group("local"))
+
+        # Key which will be used for sorting
+        self._key_cache = None
+        self._hash_cache = None
+
+    @classmethod
+    def from_parts(
+        cls,
+        *,
+        epoch: int = 0,
+        release: tuple[int, ...],
+        pre: tuple[str, int] | None = None,
+        post: int | None = None,
+        dev: int | None = None,
+        local: str | None = None,
+    ) -> Self:
+        """
+        Return a new version composed of the various parts.
+
+        This allows you to build a version without going though a string and
+        running a regular expression. It normalizes pre-release strings. The
+        ``release=`` keyword argument is required.
+
+        >>> Version.from_parts(release=(1,2,3))
+        
+        >>> Version.from_parts(release=(0,1,0), pre=("b", 1))
+        
+
+        :param epoch:
+        :param release: This version tuple is required
+
+        .. versionadded:: 26.1
+        """
+        _epoch = _validate_epoch(epoch)
+        _release = _validate_release(release)
+        _pre = _validate_pre(pre) if pre is not None else None
+        _post = _validate_post(post) if post is not None else None
+        _dev = _validate_dev(dev) if dev is not None else None
+        _local = _validate_local(local) if local is not None else None
+
+        new_version = cls.__new__(cls)
+        new_version._key_cache = None
+        new_version._hash_cache = None
+        new_version._epoch = _epoch
+        new_version._release = _release
+        new_version._pre = _pre
+        new_version._post = _post
+        new_version._dev = _dev
+        new_version._local = _local
+
+        return new_version
+
+    def __replace__(self, **kwargs: Unpack[_VersionReplace]) -> Self:
+        """
+        __replace__(*, epoch=..., release=..., pre=..., post=..., dev=..., local=...)
+
+        Return a new version with parts replaced.
+
+        This returns a new version (unless no parts were changed). The
+        pre-release is normalized. Setting a value to ``None`` clears it.
+
+        >>> v = Version("1.2.3")
+        >>> v.__replace__(pre=("a", 1))
+        
+
+        :param int | None epoch:
+        :param tuple[int, ...] | None release:
+        :param tuple[str, int] | None pre:
+        :param int | None post:
+        :param int | None dev:
+        :param str | None local:
+
+        .. versionadded:: 26.0
+        .. versionchanged:: 26.1
+
+           The pre-release portion is now normalized.
+        """
+        epoch = _validate_epoch(kwargs["epoch"]) if "epoch" in kwargs else self._epoch
+        release = (
+            _validate_release(kwargs["release"])
+            if "release" in kwargs
+            else self._release
+        )
+        pre = _validate_pre(kwargs["pre"]) if "pre" in kwargs else self._pre
+        post = _validate_post(kwargs["post"]) if "post" in kwargs else self._post
+        dev = _validate_dev(kwargs["dev"]) if "dev" in kwargs else self._dev
+        local = _validate_local(kwargs["local"]) if "local" in kwargs else self._local
+
+        if (
+            epoch == self._epoch
+            and release == self._release
+            and pre == self._pre
+            and post == self._post
+            and dev == self._dev
+            and local == self._local
+        ):
+            return self
+
+        new_version = self.__class__.__new__(self.__class__)
+        new_version._key_cache = None
+        new_version._hash_cache = None
+        new_version._epoch = epoch
+        new_version._release = release
+        new_version._pre = pre
+        new_version._post = post
+        new_version._dev = dev
+        new_version._local = local
+
+        return new_version
+
+    @property
+    def _key(self) -> CmpKey:
+        if self._key_cache is None:
+            self._key_cache = _cmpkey(
+                self._epoch,
+                self._release,
+                self._pre,
+                self._post,
+                self._dev,
+                self._local,
+            )
+        return self._key_cache
+
+    # __hash__ must be defined when __eq__ is overridden,
+    # otherwise Python sets __hash__ to None.
+    def __hash__(self) -> int:
+        if (cached_hash := self._hash_cache) is not None:
+            return cached_hash
+
+        if (key := self._key_cache) is None:
+            self._key_cache = key = _cmpkey(
+                self._epoch,
+                self._release,
+                self._pre,
+                self._post,
+                self._dev,
+                self._local,
+            )
+        self._hash_cache = cached_hash = hash(key)
+        return cached_hash
+
+    # Override comparison methods to use direct _key_cache access
+    # This is faster than property access, especially before Python 3.12
+    def __lt__(self, other: _BaseVersion) -> bool:
+        if isinstance(other, Version):
+            if self._key_cache is None:
+                self._key_cache = _cmpkey(
+                    self._epoch,
+                    self._release,
+                    self._pre,
+                    self._post,
+                    self._dev,
+                    self._local,
+                )
+            if other._key_cache is None:
+                other._key_cache = _cmpkey(
+                    other._epoch,
+                    other._release,
+                    other._pre,
+                    other._post,
+                    other._dev,
+                    other._local,
+                )
+            return self._key_cache < other._key_cache
+
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return super().__lt__(other)
+
+    def __le__(self, other: _BaseVersion) -> bool:
+        if isinstance(other, Version):
+            if self._key_cache is None:
+                self._key_cache = _cmpkey(
+                    self._epoch,
+                    self._release,
+                    self._pre,
+                    self._post,
+                    self._dev,
+                    self._local,
+                )
+            if other._key_cache is None:
+                other._key_cache = _cmpkey(
+                    other._epoch,
+                    other._release,
+                    other._pre,
+                    other._post,
+                    other._dev,
+                    other._local,
+                )
+            return self._key_cache <= other._key_cache
+
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return super().__le__(other)
+
+    def __eq__(self, other: object) -> bool:
+        if isinstance(other, Version):
+            if self._key_cache is None:
+                self._key_cache = _cmpkey(
+                    self._epoch,
+                    self._release,
+                    self._pre,
+                    self._post,
+                    self._dev,
+                    self._local,
+                )
+            if other._key_cache is None:
+                other._key_cache = _cmpkey(
+                    other._epoch,
+                    other._release,
+                    other._pre,
+                    other._post,
+                    other._dev,
+                    other._local,
+                )
+            return self._key_cache == other._key_cache
+
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return super().__eq__(other)
+
+    def __ge__(self, other: _BaseVersion) -> bool:
+        if isinstance(other, Version):
+            if self._key_cache is None:
+                self._key_cache = _cmpkey(
+                    self._epoch,
+                    self._release,
+                    self._pre,
+                    self._post,
+                    self._dev,
+                    self._local,
+                )
+            if other._key_cache is None:
+                other._key_cache = _cmpkey(
+                    other._epoch,
+                    other._release,
+                    other._pre,
+                    other._post,
+                    other._dev,
+                    other._local,
+                )
+            return self._key_cache >= other._key_cache
+
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return super().__ge__(other)
+
+    def __gt__(self, other: _BaseVersion) -> bool:
+        if isinstance(other, Version):
+            if self._key_cache is None:
+                self._key_cache = _cmpkey(
+                    self._epoch,
+                    self._release,
+                    self._pre,
+                    self._post,
+                    self._dev,
+                    self._local,
+                )
+            if other._key_cache is None:
+                other._key_cache = _cmpkey(
+                    other._epoch,
+                    other._release,
+                    other._pre,
+                    other._post,
+                    other._dev,
+                    other._local,
+                )
+            return self._key_cache > other._key_cache
+
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return super().__gt__(other)
+
+    def __ne__(self, other: object) -> bool:
+        if isinstance(other, Version):
+            if self._key_cache is None:
+                self._key_cache = _cmpkey(
+                    self._epoch,
+                    self._release,
+                    self._pre,
+                    self._post,
+                    self._dev,
+                    self._local,
+                )
+            if other._key_cache is None:
+                other._key_cache = _cmpkey(
+                    other._epoch,
+                    other._release,
+                    other._pre,
+                    other._post,
+                    other._dev,
+                    other._local,
+                )
+            return self._key_cache != other._key_cache
+
+        if not isinstance(other, _BaseVersion):
+            return NotImplemented
+
+        return super().__ne__(other)
+
+    def __getstate__(
+        self,
+    ) -> tuple[
+        int,
+        tuple[int, ...],
+        tuple[str, int] | None,
+        tuple[str, int] | None,
+        tuple[str, int] | None,
+        LocalType | None,
+    ]:
+        # Return state as a 6-item tuple for compactness:
+        #   (epoch, release, pre, post, dev, local)
+        # Cache members are excluded and will be recomputed on demand
+        return (
+            self._epoch,
+            self._release,
+            self._pre,
+            self._post,
+            self._dev,
+            self._local,
+        )
+
+    def __setstate__(self, state: object) -> None:
+        # Always discard cached values — they may contain stale references
+        # (e.g. packaging._structures.InfinityType from pre-26.1 pickles)
+        # and will be recomputed on demand from the core fields above.
+        self._key_cache = None
+        self._hash_cache = None
+
+        if isinstance(state, tuple):
+            if len(state) == 6:
+                # New format (26.2+): (epoch, release, pre, post, dev, local)
+                (
+                    self._epoch,
+                    self._release,
+                    self._pre,
+                    self._post,
+                    self._dev,
+                    self._local,
+                ) = state
+                return
+            if len(state) == 2:
+                # Format (packaging 26.0-26.1): (None, {slot: value}).
+                _, slot_dict = state
+                if isinstance(slot_dict, dict):
+                    self._epoch = slot_dict["_epoch"]
+                    self._release = slot_dict["_release"]
+                    self._pre = slot_dict.get("_pre")
+                    self._post = slot_dict.get("_post")
+                    self._dev = slot_dict.get("_dev")
+                    self._local = slot_dict.get("_local")
+                    return
+        if isinstance(state, dict):
+            # Old format (packaging <= 25.x, no __slots__): state is a plain
+            # dict with "_version" (_Version NamedTuple) and "_key" entries.
+            version_nt = state.get("_version")
+            if version_nt is not None:
+                self._epoch = version_nt.epoch
+                self._release = version_nt.release
+                self._pre = version_nt.pre
+                self._post = version_nt.post
+                self._dev = version_nt.dev
+                self._local = version_nt.local
+                return
+
+        raise TypeError(f"Cannot restore Version from {state!r}")
+
+    @property
+    @_deprecated("Version._version is private and will be removed soon")
+    def _version(self) -> _Version:
+        return _Version(
+            self._epoch, self._release, self._dev, self._pre, self._post, self._local
+        )
+
+    @_version.setter
+    @_deprecated("Version._version is private and will be removed soon")
+    def _version(self, value: _Version) -> None:
+        self._epoch = value.epoch
+        self._release = value.release
+        self._dev = value.dev
+        self._pre = value.pre
+        self._post = value.post
+        self._local = value.local
+        self._key_cache = None
+        self._hash_cache = None
+
+    def __repr__(self) -> str:
+        """A representation of the Version that shows all internal state.
+
+        >>> Version('1.0.0')
+        
+        """
+        return f"<{self.__class__.__name__}({str(self)!r})>"
+
+    def __str__(self) -> str:
+        """A string representation of the version that can be round-tripped.
+
+        >>> str(Version("1.0a5"))
+        '1.0a5'
+        """
+        # This is a hot function, so not calling self.base_version
+        version = ".".join(map(str, self.release))
+
+        # Epoch
+        if self.epoch:
+            version = f"{self.epoch}!{version}"
+
+        # Pre-release
+        if self.pre is not None:
+            version += "".join(map(str, self.pre))
+
+        # Post-release
+        if self.post is not None:
+            version += f".post{self.post}"
+
+        # Development release
+        if self.dev is not None:
+            version += f".dev{self.dev}"
+
+        # Local version segment
+        if self.local is not None:
+            version += f"+{self.local}"
+
+        return version
+
+    @property
+    def _str(self) -> str:
+        """Internal property for match_args"""
+        return str(self)
+
+    @property
+    def epoch(self) -> int:
+        """The epoch of the version.
+
+        >>> Version("2.0.0").epoch
+        0
+        >>> Version("1!2.0.0").epoch
+        1
+        """
+        return self._epoch
+
+    @property
+    def release(self) -> tuple[int, ...]:
+        """The components of the "release" segment of the version.
+
+        >>> Version("1.2.3").release
+        (1, 2, 3)
+        >>> Version("2.0.0").release
+        (2, 0, 0)
+        >>> Version("1!2.0.0.post0").release
+        (2, 0, 0)
+
+        Includes trailing zeroes but not the epoch or any pre-release / development /
+        post-release suffixes.
+        """
+        return self._release
+
+    @property
+    def pre(self) -> tuple[Literal["a", "b", "rc"], int] | None:
+        """The pre-release segment of the version.
+
+        >>> print(Version("1.2.3").pre)
+        None
+        >>> Version("1.2.3a1").pre
+        ('a', 1)
+        >>> Version("1.2.3b1").pre
+        ('b', 1)
+        >>> Version("1.2.3rc1").pre
+        ('rc', 1)
+        """
+        return self._pre
+
+    @property
+    def post(self) -> int | None:
+        """The post-release number of the version.
+
+        >>> print(Version("1.2.3").post)
+        None
+        >>> Version("1.2.3.post1").post
+        1
+        """
+        return self._post[1] if self._post else None
+
+    @property
+    def dev(self) -> int | None:
+        """The development number of the version.
+
+        >>> print(Version("1.2.3").dev)
+        None
+        >>> Version("1.2.3.dev1").dev
+        1
+        """
+        return self._dev[1] if self._dev else None
+
+    @property
+    def local(self) -> str | None:
+        """The local version segment of the version.
+
+        >>> print(Version("1.2.3").local)
+        None
+        >>> Version("1.2.3+abc").local
+        'abc'
+        """
+        if self._local:
+            return ".".join(str(x) for x in self._local)
+        else:
+            return None
+
+    @property
+    def public(self) -> str:
+        """The public portion of the version.
+
+        This returns a string. If you want a :class:`Version` again and care
+        about performance, use ``v.__replace__(local=None)`` instead.
+
+        >>> Version("1.2.3").public
+        '1.2.3'
+        >>> Version("1.2.3+abc").public
+        '1.2.3'
+        >>> Version("1!1.2.3dev1+abc").public
+        '1!1.2.3.dev1'
+        """
+        return str(self).split("+", 1)[0]
+
+    @property
+    def base_version(self) -> str:
+        """The "base version" of the version.
+
+        This returns a string. If you want a :class:`Version` again and care
+        about performance, use
+        ``v.__replace__(pre=None, post=None, dev=None, local=None)`` instead.
+
+        >>> Version("1.2.3").base_version
+        '1.2.3'
+        >>> Version("1.2.3+abc").base_version
+        '1.2.3'
+        >>> Version("1!1.2.3dev1+abc").base_version
+        '1!1.2.3'
+
+        The "base version" is the public version of the project without any pre or post
+        release markers.
+        """
+        release_segment = ".".join(map(str, self.release))
+        return f"{self.epoch}!{release_segment}" if self.epoch else release_segment
+
+    @property
+    def is_prerelease(self) -> bool:
+        """Whether this version is a pre-release.
+
+        >>> Version("1.2.3").is_prerelease
+        False
+        >>> Version("1.2.3a1").is_prerelease
+        True
+        >>> Version("1.2.3b1").is_prerelease
+        True
+        >>> Version("1.2.3rc1").is_prerelease
+        True
+        >>> Version("1.2.3dev1").is_prerelease
+        True
+        """
+        return self.dev is not None or self.pre is not None
+
+    @property
+    def is_postrelease(self) -> bool:
+        """Whether this version is a post-release.
+
+        >>> Version("1.2.3").is_postrelease
+        False
+        >>> Version("1.2.3.post1").is_postrelease
+        True
+        """
+        return self.post is not None
+
+    @property
+    def is_devrelease(self) -> bool:
+        """Whether this version is a development release.
+
+        >>> Version("1.2.3").is_devrelease
+        False
+        >>> Version("1.2.3.dev1").is_devrelease
+        True
+        """
+        return self.dev is not None
+
+    @property
+    def major(self) -> int:
+        """The first item of :attr:`release` or ``0`` if unavailable.
+
+        >>> Version("1.2.3").major
+        1
+
+        .. versionadded:: 20.0
+        """
+        return self.release[0] if len(self.release) >= 1 else 0
+
+    @property
+    def minor(self) -> int:
+        """The second item of :attr:`release` or ``0`` if unavailable.
+
+        >>> Version("1.2.3").minor
+        2
+        >>> Version("1").minor
+        0
+
+        .. versionadded:: 20.0
+        """
+        return self.release[1] if len(self.release) >= 2 else 0
+
+    @property
+    def micro(self) -> int:
+        """The third item of :attr:`release` or ``0`` if unavailable.
+
+        >>> Version("1.2.3").micro
+        3
+        >>> Version("1").micro
+        0
+
+        .. versionadded:: 20.0
+        """
+        return self.release[2] if len(self.release) >= 3 else 0
+
+
+class _TrimmedRelease(Version):
+    __slots__ = ()
+
+    def __init__(self, version: str | Version) -> None:
+        if isinstance(version, Version):
+            self._epoch = version._epoch
+            self._release = version._release
+            self._dev = version._dev
+            self._pre = version._pre
+            self._post = version._post
+            self._local = version._local
+            self._key_cache = version._key_cache
+            self._hash_cache = version._hash_cache
+            return
+        super().__init__(version)  # pragma: no cover
+
+    @property
+    def release(self) -> tuple[int, ...]:
+        """
+        Release segment without any trailing zeros.
+
+        >>> _TrimmedRelease('1.0.0').release
+        (1,)
+        >>> _TrimmedRelease('0.0').release
+        (0,)
+        """
+        # This leaves one 0.
+        rel = super().release
+        len_release = len(rel)
+        i = len_release
+        while i > 1 and rel[i - 1] == 0:
+            i -= 1
+        return rel if i == len_release else rel[:i]
+
+
+def _parse_letter_version(
+    letter: str | None, number: str | bytes | SupportsInt | None
+) -> tuple[str, int] | None:
+    if letter:
+        # We normalize any letters to their lower case form
+        letter = letter.lower()
+
+        # We consider some words to be alternate spellings of other words and
+        # in those cases we want to normalize the spellings to our preferred
+        # spelling.
+        letter = _LETTER_NORMALIZATION.get(letter, letter)
+
+        # We consider there to be an implicit 0 in a pre-release if there is
+        # not a numeral associated with it.
+        return letter, int(number or 0)
+
+    if number:
+        # We assume if we are given a number, but we are not given a letter
+        # then this is using the implicit post release syntax (e.g. 1.0-1)
+        return "post", int(number)
+
+    return None
+
+
+_local_version_separators = re.compile(r"[\._-]")
+
+
+def _parse_local_version(local: str | None) -> LocalType | None:
+    """
+    Takes a string like ``"abc.1.twelve"`` and turns it into
+    ``("abc", 1, "twelve")``.
+    """
+    if local is not None:
+        return tuple(
+            part.lower() if not part.isdigit() else int(part)
+            for part in _local_version_separators.split(local)
+        )
+    return None
+
+
+# Sort ranks for pre-release: dev-only < a < b < rc < stable (no pre-release).
+_PRE_RANK = {"a": 0, "b": 1, "rc": 2}
+_PRE_RANK_DEV_ONLY = -1  # sorts before a(0)
+_PRE_RANK_STABLE = 3  # sorts after rc(2)
+
+# In local version segments, strings sort before ints per PEP 440.
+_LOCAL_STR_RANK = -1  # sorts before all non-negative ints
+
+# Pre-computed suffix for stable releases (no pre, post, or dev segments).
+# See _cmpkey() for the suffix layout.
+_STABLE_SUFFIX = (_PRE_RANK_STABLE, 0, 0, 0, 1, 0)
+
+
+def _cmpkey(
+    epoch: int,
+    release: tuple[int, ...],
+    pre: tuple[str, int] | None,
+    post: tuple[str, int] | None,
+    dev: tuple[str, int] | None,
+    local: LocalType | None,
+) -> CmpKey:
+    """Build a comparison key for PEP 440 ordering.
+
+    Returns ``(epoch, release, suffix)`` or
+    ``(epoch, release, suffix, local)`` so that plain tuple
+    comparison gives the correct order.
+
+    Trailing zeros are stripped from the release so that ``1.0.0 == 1``.
+
+    The suffix is a flat 6-int tuple that encodes pre/post/dev:
+    ``(pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)``
+
+    pre_rank: dev-only=-1, a=0, b=1, rc=2, no-pre=3
+        Dev-only releases (no pre or post) get -1 so they sort before
+        any alpha/beta/rc.  Releases without a pre-release tag get 3
+        so they sort after rc.
+    post_rank: no-post=0, post=1
+        Releases without a post segment sort before those with one.
+    dev_rank: dev=0, no-dev=1
+        Releases without a dev segment sort after those with one.
+
+    Local segments use ``(n, "")`` for ints and ``(-1, s)`` for strings,
+    following PEP 440: strings sort before ints, strings compare
+    lexicographically, ints compare numerically, and shorter segments
+    sort before longer when prefixes match.  Versions without a local
+    segment sort before those with one (3-tuple < 4-tuple).
+
+    >>> _cmpkey(0, (1, 0, 0), None, None, None, None)
+    (0, (1,), (3, 0, 0, 0, 1, 0))
+    >>> _cmpkey(0, (1,), ("a", 1), None, None, None)
+    (0, (1,), (0, 1, 0, 0, 1, 0))
+    >>> _cmpkey(0, (1,), None, None, None, ("ubuntu", 1))
+    (0, (1,), (3, 0, 0, 0, 1, 0), ((-1, 'ubuntu'), (1, '')))
+    """
+    # Strip trailing zeros: 1.0.0 compares equal to 1.
+    len_release = len(release)
+    i = len_release
+    while i and release[i - 1] == 0:
+        i -= 1
+    trimmed = release if i == len_release else release[:i]
+
+    # Fast path: stable release with no local segment.
+    if pre is None and post is None and dev is None and local is None:
+        return epoch, trimmed, _STABLE_SUFFIX
+
+    if pre is None and post is None and dev is not None:
+        # dev-only (e.g. 1.0.dev1) sorts before all pre-releases.
+        pre_rank, pre_n = _PRE_RANK_DEV_ONLY, 0
+    elif pre is None:
+        pre_rank, pre_n = _PRE_RANK_STABLE, 0
+    else:
+        pre_rank, pre_n = _PRE_RANK[pre[0]], pre[1]
+
+    post_rank = 0 if post is None else 1
+    post_n = 0 if post is None else post[1]
+
+    dev_rank = 1 if dev is None else 0
+    dev_n = 0 if dev is None else dev[1]
+
+    suffix = (pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)
+
+    if local is None:
+        return epoch, trimmed, suffix
+
+    cmp_local: CmpLocalType = tuple(
+        (seg, "") if isinstance(seg, int) else (_LOCAL_STR_RANK, seg) for seg in local
+    )
+    return epoch, trimmed, suffix, cmp_local
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE
new file mode 100644
index 00000000000..261eeb9e9f8
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE
new file mode 100644
index 00000000000..59efb6c783b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE
@@ -0,0 +1,5 @@
+Prometheus instrumentation library for Python applications
+Copyright 2015 The Prometheus Authors
+
+This product bundles decorator 4.0.10 which is available under a "2-clause BSD"
+license. For details, see prometheus_client/decorator.py.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py
new file mode 100644
index 00000000000..221ad273972
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+from . import (
+    exposition, gc_collector, metrics, metrics_core, platform_collector,
+    process_collector, registry,
+)
+from .exposition import (
+    CONTENT_TYPE_LATEST, CONTENT_TYPE_PLAIN_0_0_4, CONTENT_TYPE_PLAIN_1_0_0,
+    delete_from_gateway, generate_latest, instance_ip_grouping_key,
+    make_asgi_app, make_wsgi_app, MetricsHandler, push_to_gateway,
+    pushadd_to_gateway, start_http_server, start_wsgi_server,
+    write_to_textfile,
+)
+from .gc_collector import GC_COLLECTOR, GCCollector
+from .metrics import (
+    Counter, disable_created_metrics, enable_created_metrics, Enum, Gauge,
+    Histogram, Info, Summary,
+)
+from .metrics_core import Metric
+from .platform_collector import PLATFORM_COLLECTOR, PlatformCollector
+from .process_collector import PROCESS_COLLECTOR, ProcessCollector
+from .registry import CollectorRegistry, REGISTRY
+
+__all__ = (
+    'CollectorRegistry',
+    'REGISTRY',
+    'Metric',
+    'Counter',
+    'Gauge',
+    'Summary',
+    'Histogram',
+    'Info',
+    'Enum',
+    'enable_created_metrics',
+    'disable_created_metrics',
+    'CONTENT_TYPE_LATEST',
+    'CONTENT_TYPE_PLAIN_0_0_4',
+    'CONTENT_TYPE_PLAIN_1_0_0',
+    'generate_latest',
+    'MetricsHandler',
+    'make_wsgi_app',
+    'make_asgi_app',
+    'start_http_server',
+    'start_wsgi_server',
+    'write_to_textfile',
+    'push_to_gateway',
+    'pushadd_to_gateway',
+    'delete_from_gateway',
+    'instance_ip_grouping_key',
+    'ProcessCollector',
+    'PROCESS_COLLECTOR',
+    'PlatformCollector',
+    'PLATFORM_COLLECTOR',
+    'GCCollector',
+    'GC_COLLECTOR',
+)
+
+if __name__ == '__main__':
+    c = Counter('cc', 'A counter')
+    c.inc()
+
+    g = Gauge('gg', 'A gauge')
+    g.set(17)
+
+    s = Summary('ss', 'A summary', ['a', 'b'])
+    s.labels('c', 'd').observe(17)
+
+    h = Histogram('hh', 'A histogram')
+    h.observe(.6)
+
+    start_http_server(8000)
+    import time
+
+    while True:
+        time.sleep(1)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py
new file mode 100644
index 00000000000..6e527ca960e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py
@@ -0,0 +1,40 @@
+from typing import Callable
+from urllib.parse import parse_qs
+
+from .exposition import _bake_output
+from .registry import Collector, REGISTRY
+
+
+def make_asgi_app(registry: Collector = REGISTRY, disable_compression: bool = False) -> Callable:
+    """Create a ASGI app which serves the metrics from a registry."""
+
+    async def prometheus_app(scope, receive, send):
+        assert scope.get("type") == "http"
+        # Prepare parameters
+        params = parse_qs(scope.get('query_string', b'').decode("utf8"))
+        accept_header = ",".join([
+            value.decode("utf8") for (name, value) in scope.get('headers')
+            if name.decode("utf8").lower() == 'accept'
+        ])
+        accept_encoding_header = ",".join([
+            value.decode("utf8") for (name, value) in scope.get('headers')
+            if name.decode("utf8").lower() == 'accept-encoding'
+        ])
+        # Bake output
+        status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression)
+        formatted_headers = []
+        for header in headers:
+            formatted_headers.append(tuple(x.encode('utf8') for x in header))
+        # Return output
+        payload = await receive()
+        if payload.get("type") == "http.request":
+            await send(
+                {
+                    "type": "http.response.start",
+                    "status": int(status.split(' ')[0]),
+                    "headers": formatted_headers,
+                }
+            )
+            await send({"type": "http.response.body", "body": output})
+
+    return prometheus_app
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py
new file mode 100644
index 00000000000..235324b2a41
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+
+import logging
+import re
+import socket
+import threading
+import time
+from timeit import default_timer
+from typing import Callable, Tuple
+
+from ..registry import Collector, REGISTRY
+
+# Roughly, have to keep to what works as a file name.
+# We also remove periods, so labels can be distinguished.
+
+_INVALID_GRAPHITE_CHARS = re.compile(r"[^a-zA-Z0-9_-]")
+
+
+def _sanitize(s):
+    return _INVALID_GRAPHITE_CHARS.sub('_', s)
+
+
+class _RegularPush(threading.Thread):
+    def __init__(self, pusher, interval, prefix):
+        super().__init__()
+        self._pusher = pusher
+        self._interval = interval
+        self._prefix = prefix
+
+    def run(self):
+        wait_until = default_timer()
+        while True:
+            while True:
+                now = default_timer()
+                if now >= wait_until:
+                    # May need to skip some pushes.
+                    while wait_until < now:
+                        wait_until += self._interval
+                    break
+                # time.sleep can return early.
+                time.sleep(wait_until - now)
+            try:
+                self._pusher.push(prefix=self._prefix)
+            except OSError:
+                logging.exception("Push failed")
+
+
+class GraphiteBridge:
+    def __init__(self,
+                 address: Tuple[str, int],
+                 registry: Collector = REGISTRY,
+                 timeout_seconds: float = 30,
+                 _timer: Callable[[], float] = time.time,
+                 tags: bool = False,
+                 ):
+        self._address = address
+        self._registry = registry
+        self._tags = tags
+        self._timeout = timeout_seconds
+        self._timer = _timer
+
+    def push(self, prefix: str = '') -> None:
+        now = int(self._timer())
+        output = []
+
+        prefixstr = ''
+        if prefix:
+            prefixstr = prefix + '.'
+
+        for metric in self._registry.collect():
+            for s in metric.samples:
+                if s.labels:
+                    if self._tags:
+                        sep = ';'
+                        fmt = '{0}={1}'
+                    else:
+                        sep = '.'
+                        fmt = '{0}.{1}'
+                    labelstr = sep + sep.join(
+                        [fmt.format(
+                            _sanitize(k), _sanitize(v))
+                            for k, v in sorted(s.labels.items())])
+                else:
+                    labelstr = ''
+                output.append(f'{prefixstr}{_sanitize(s.name)}{labelstr} {float(s.value)} {now}\n')
+
+        conn = socket.create_connection(self._address, self._timeout)
+        conn.sendall(''.join(output).encode('ascii'))
+        conn.close()
+
+    def start(self, interval: float = 60.0, prefix: str = '') -> None:
+        t = _RegularPush(self, interval, prefix)
+        t.daemon = True
+        t.start()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py
new file mode 100644
index 00000000000..3e8d7ced549
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py
@@ -0,0 +1,83 @@
+from timeit import default_timer
+from types import TracebackType
+from typing import (
+    Any, Callable, Literal, Optional, Tuple, Type, TYPE_CHECKING, TypeVar,
+    Union,
+)
+
+from .decorator import decorate
+
+if TYPE_CHECKING:
+    from . import Counter
+    F = TypeVar("F", bound=Callable[..., Any])
+
+
+class ExceptionCounter:
+    def __init__(self, counter: "Counter", exception: Union[Type[BaseException], Tuple[Type[BaseException], ...]]) -> None:
+        self._counter = counter
+        self._exception = exception
+
+    def __enter__(self) -> None:
+        pass
+
+    def __exit__(self, typ: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> Literal[False]:
+        if isinstance(value, self._exception):
+            self._counter.inc()
+        return False
+
+    def __call__(self, f: "F") -> "F":
+        def wrapped(func, *args, **kwargs):
+            with self:
+                return func(*args, **kwargs)
+
+        return decorate(f, wrapped)
+
+
+class InprogressTracker:
+    def __init__(self, gauge):
+        self._gauge = gauge
+
+    def __enter__(self):
+        self._gauge.inc()
+
+    def __exit__(self, typ, value, traceback):
+        self._gauge.dec()
+
+    def __call__(self, f: "F") -> "F":
+        def wrapped(func, *args, **kwargs):
+            with self:
+                return func(*args, **kwargs)
+
+        return decorate(f, wrapped)
+
+
+class Timer:
+    def __init__(self, metric, callback_name):
+        self._metric = metric
+        self._callback_name = callback_name
+        self.duration = None
+
+    def _new_timer(self):
+        return self.__class__(self._metric, self._callback_name)
+
+    def __enter__(self):
+        self._start = default_timer()
+        return self
+
+    def __exit__(self, typ, value, traceback):
+        # Time can go backwards.
+        self.duration = max(default_timer() - self._start, 0)
+        callback = getattr(self._metric, self._callback_name)
+        callback(self.duration)
+
+    def labels(self, *args, **kw):
+        self._metric = self._metric.labels(*args, **kw)
+
+    def __call__(self, f: "F") -> "F":
+        def wrapped(func, *args, **kwargs):
+            # Obtaining new instance of timer every time
+            # ensures thread safety and reentrancy.
+            with self._new_timer():
+                return func(*args, **kwargs)
+
+        return decorate(f, wrapped)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py
new file mode 100644
index 00000000000..045e90ab9b7
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py
@@ -0,0 +1,35 @@
+from .metrics import Counter, Enum, Gauge, Histogram, Info, Summary
+from .metrics_core import (
+    CounterMetricFamily, GaugeHistogramMetricFamily, GaugeMetricFamily,
+    HistogramMetricFamily, InfoMetricFamily, Metric, StateSetMetricFamily,
+    SummaryMetricFamily, UnknownMetricFamily, UntypedMetricFamily,
+)
+from .registry import CollectorRegistry, DuplicateTimeseries, REGISTRY
+from .samples import BucketSpan, Exemplar, NativeHistogram, Sample, Timestamp
+
+__all__ = (
+    'BucketSpan',
+    'CollectorRegistry',
+    'Counter',
+    'CounterMetricFamily',
+    'DuplicateTimeseries',
+    'Enum',
+    'Exemplar',
+    'Gauge',
+    'GaugeHistogramMetricFamily',
+    'GaugeMetricFamily',
+    'Histogram',
+    'HistogramMetricFamily',
+    'Info',
+    'InfoMetricFamily',
+    'Metric',
+    'NativeHistogram',
+    'REGISTRY',
+    'Sample',
+    'StateSetMetricFamily',
+    'Summary',
+    'SummaryMetricFamily',
+    'Timestamp',
+    'UnknownMetricFamily',
+    'UntypedMetricFamily',
+)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py
new file mode 100644
index 00000000000..1ad2c9770ec
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py
@@ -0,0 +1,427 @@
+# #########################     LICENSE     ############################ #
+
+# Copyright (c) 2005-2016, Michele Simionato
+# All rights reserved.
+
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+
+#   Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#   Redistributions in bytecode form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+"""
+Decorator module, see http://pypi.python.org/pypi/decorator
+for the documentation.
+"""
+from __future__ import print_function
+
+import collections
+import inspect
+import itertools
+import operator
+import re
+import sys
+
+__version__ = '4.0.10'
+
+if sys.version_info >= (3,):
+    from inspect import getfullargspec
+
+
+    def get_init(cls):
+        return cls.__init__
+else:
+    class getfullargspec(object):
+        "A quick and dirty replacement for getfullargspec for Python 2.X"
+
+        def __init__(self, f):
+            self.args, self.varargs, self.varkw, self.defaults = \
+                inspect.getargspec(f)
+            self.kwonlyargs = []
+            self.kwonlydefaults = None
+
+        def __iter__(self):
+            yield self.args
+            yield self.varargs
+            yield self.varkw
+            yield self.defaults
+
+        getargspec = inspect.getargspec
+
+
+    def get_init(cls):
+        return cls.__init__.__func__
+
+# getargspec has been deprecated in Python 3.5
+ArgSpec = collections.namedtuple(
+    'ArgSpec', 'args varargs varkw defaults')
+
+
+def getargspec(f):
+    """A replacement for inspect.getargspec"""
+    spec = getfullargspec(f)
+    return ArgSpec(spec.args, spec.varargs, spec.varkw, spec.defaults)
+
+
+DEF = re.compile(r'\s*def\s*([_\w][_\w\d]*)\s*\(')
+
+
+# basic functionality
+class FunctionMaker(object):
+    """
+    An object with the ability to create functions with a given signature.
+    It has attributes name, doc, module, signature, defaults, dict and
+    methods update and make.
+    """
+
+    # Atomic get-and-increment provided by the GIL
+    _compile_count = itertools.count()
+
+    def __init__(self, func=None, name=None, signature=None,
+                 defaults=None, doc=None, module=None, funcdict=None):
+        self.shortsignature = signature
+        if func:
+            # func can be a class or a callable, but not an instance method
+            self.name = func.__name__
+            if self.name == '':  # small hack for lambda functions
+                self.name = '_lambda_'
+            self.doc = func.__doc__
+            self.module = func.__module__
+            if inspect.isfunction(func):
+                argspec = getfullargspec(func)
+                self.annotations = getattr(func, '__annotations__', {})
+                for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs',
+                          'kwonlydefaults'):
+                    setattr(self, a, getattr(argspec, a))
+                for i, arg in enumerate(self.args):
+                    setattr(self, 'arg%d' % i, arg)
+                if sys.version_info < (3,):  # easy way
+                    self.shortsignature = self.signature = (
+                        inspect.formatargspec(
+                            formatvalue=lambda val: "", *argspec)[1:-1])
+                else:  # Python 3 way
+                    allargs = list(self.args)
+                    allshortargs = list(self.args)
+                    if self.varargs:
+                        allargs.append('*' + self.varargs)
+                        allshortargs.append('*' + self.varargs)
+                    elif self.kwonlyargs:
+                        allargs.append('*')  # single star syntax
+                    for a in self.kwonlyargs:
+                        allargs.append('%s=None' % a)
+                        allshortargs.append('%s=%s' % (a, a))
+                    if self.varkw:
+                        allargs.append('**' + self.varkw)
+                        allshortargs.append('**' + self.varkw)
+                    self.signature = ', '.join(allargs)
+                    self.shortsignature = ', '.join(allshortargs)
+                self.dict = func.__dict__.copy()
+        # func=None happens when decorating a caller
+        if name:
+            self.name = name
+        if signature is not None:
+            self.signature = signature
+        if defaults:
+            self.defaults = defaults
+        if doc:
+            self.doc = doc
+        if module:
+            self.module = module
+        if funcdict:
+            self.dict = funcdict
+        # check existence required attributes
+        assert hasattr(self, 'name')
+        if not hasattr(self, 'signature'):
+            raise TypeError('You are decorating a non function: %s' % func)
+
+    def update(self, func, **kw):
+        "Update the signature of func with the data in self"
+        func.__name__ = self.name
+        func.__doc__ = getattr(self, 'doc', None)
+        func.__dict__ = getattr(self, 'dict', {})
+        func.__defaults__ = getattr(self, 'defaults', ())
+        func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
+        func.__annotations__ = getattr(self, 'annotations', None)
+        try:
+            frame = sys._getframe(3)
+        except AttributeError:  # for IronPython and similar implementations
+            callermodule = '?'
+        else:
+            callermodule = frame.f_globals.get('__name__', '?')
+        func.__module__ = getattr(self, 'module', callermodule)
+        func.__dict__.update(kw)
+
+    def make(self, src_templ, evaldict=None, addsource=False, **attrs):
+        "Make a new function from a given template and update the signature"
+        src = src_templ % vars(self)  # expand name and signature
+        evaldict = evaldict or {}
+        mo = DEF.match(src)
+        if mo is None:
+            raise SyntaxError('not a valid function template\n%s' % src)
+        name = mo.group(1)  # extract the function name
+        names = set([name] + [arg.strip(' *') for arg in
+                              self.shortsignature.split(',')])
+        for n in names:
+            if n in ('_func_', '_call_'):
+                raise NameError('%s is overridden in\n%s' % (n, src))
+
+        if not src.endswith('\n'):  # add a newline for old Pythons
+            src += '\n'
+
+        # Ensure each generated function has a unique filename for profilers
+        # (such as cProfile) that depend on the tuple of (,
+        # , ) being unique.
+        filename = '' % (next(self._compile_count),)
+        try:
+            code = compile(src, filename, 'single')
+            exec(code, evaldict)
+        except:
+            print('Error in generated code:', file=sys.stderr)
+            print(src, file=sys.stderr)
+            raise
+        func = evaldict[name]
+        if addsource:
+            attrs['__source__'] = src
+        self.update(func, **attrs)
+        return func
+
+    @classmethod
+    def create(cls, obj, body, evaldict, defaults=None,
+               doc=None, module=None, addsource=True, **attrs):
+        """
+        Create a function from the strings name, signature and body.
+        evaldict is the evaluation dictionary. If addsource is true an
+        attribute __source__ is added to the result. The attributes attrs
+        are added, if any.
+        """
+        if isinstance(obj, str):  # "name(signature)"
+            name, rest = obj.strip().split('(', 1)
+            signature = rest[:-1]  # strip a right parens
+            func = None
+        else:  # a function
+            name = None
+            signature = None
+            func = obj
+        self = cls(func, name, signature, defaults, doc, module)
+        ibody = '\n'.join('    ' + line for line in body.splitlines())
+        return self.make('def %(name)s(%(signature)s):\n' + ibody,
+                         evaldict, addsource, **attrs)
+
+
+def decorate(func, caller):
+    """
+    decorate(func, caller) decorates a function using a caller.
+    """
+    evaldict = dict(_call_=caller, _func_=func)
+    fun = FunctionMaker.create(
+        func, "return _call_(_func_, %(shortsignature)s)",
+        evaldict, __wrapped__=func)
+    if hasattr(func, '__qualname__'):
+        fun.__qualname__ = func.__qualname__
+    return fun
+
+
+def decorator(caller, _func=None):
+    """decorator(caller) converts a caller function into a decorator"""
+    if _func is not None:  # return a decorated function
+        # this is obsolete behavior; you should use decorate instead
+        return decorate(_func, caller)
+    # else return a decorator function
+    if inspect.isclass(caller):
+        name = caller.__name__.lower()
+        doc = 'decorator(%s) converts functions/generators into ' \
+              'factories of %s objects' % (caller.__name__, caller.__name__)
+    elif inspect.isfunction(caller):
+        if caller.__name__ == '':
+            name = '_lambda_'
+        else:
+            name = caller.__name__
+        doc = caller.__doc__
+    else:  # assume caller is an object with a __call__ method
+        name = caller.__class__.__name__.lower()
+        doc = caller.__call__.__doc__
+    evaldict = dict(_call_=caller, _decorate_=decorate)
+    return FunctionMaker.create(
+        '%s(func)' % name, 'return _decorate_(func, _call_)',
+        evaldict, doc=doc, module=caller.__module__,
+        __wrapped__=caller)
+
+
+# ####################### contextmanager ####################### #
+
+try:  # Python >= 3.2
+    from contextlib import _GeneratorContextManager
+except ImportError:  # Python >= 2.5
+    from contextlib import GeneratorContextManager as _GeneratorContextManager
+
+
+class ContextManager(_GeneratorContextManager):
+    def __call__(self, func):
+        """Context manager decorator"""
+        return FunctionMaker.create(
+            func, "with _self_: return _func_(%(shortsignature)s)",
+            dict(_self_=self, _func_=func), __wrapped__=func)
+
+
+init = getfullargspec(_GeneratorContextManager.__init__)
+n_args = len(init.args)
+if n_args == 2 and not init.varargs:  # (self, genobj) Python 2.7
+    def __init__(self, g, *a, **k):
+        return _GeneratorContextManager.__init__(self, g(*a, **k))
+
+
+    ContextManager.__init__ = __init__
+elif n_args == 2 and init.varargs:  # (self, gen, *a, **k) Python 3.4
+    pass
+elif n_args == 4:  # (self, gen, args, kwds) Python 3.5
+    def __init__(self, g, *a, **k):
+        return _GeneratorContextManager.__init__(self, g, a, k)
+
+
+    ContextManager.__init__ = __init__
+
+contextmanager = decorator(ContextManager)
+
+
+# ############################ dispatch_on ############################ #
+
+def append(a, vancestors):
+    """
+    Append ``a`` to the list of the virtual ancestors, unless it is already
+    included.
+    """
+    add = True
+    for j, va in enumerate(vancestors):
+        if issubclass(va, a):
+            add = False
+            break
+        if issubclass(a, va):
+            vancestors[j] = a
+            add = False
+    if add:
+        vancestors.append(a)
+
+
+# inspired from simplegeneric by P.J. Eby and functools.singledispatch
+def dispatch_on(*dispatch_args):
+    """
+    Factory of decorators turning a function into a generic function
+    dispatching on the given arguments.
+    """
+    assert dispatch_args, 'No dispatch args passed'
+    dispatch_str = '(%s,)' % ', '.join(dispatch_args)
+
+    def check(arguments, wrong=operator.ne, msg=''):
+        """Make sure one passes the expected number of arguments"""
+        if wrong(len(arguments), len(dispatch_args)):
+            raise TypeError('Expected %d arguments, got %d%s' %
+                            (len(dispatch_args), len(arguments), msg))
+
+    def gen_func_dec(func):
+        """Decorator turning a function into a generic function"""
+
+        # first check the dispatch arguments
+        argset = set(getfullargspec(func).args)
+        if not set(dispatch_args) <= argset:
+            raise NameError('Unknown dispatch arguments %s' % dispatch_str)
+
+        typemap = {}
+
+        def vancestors(*types):
+            """
+            Get a list of sets of virtual ancestors for the given types
+            """
+            check(types)
+            ras = [[] for _ in range(len(dispatch_args))]
+            for types_ in typemap:
+                for t, type_, ra in zip(types, types_, ras):
+                    if issubclass(t, type_) and type_ not in t.__mro__:
+                        append(type_, ra)
+            return [set(ra) for ra in ras]
+
+        def ancestors(*types):
+            """
+            Get a list of virtual MROs, one for each type
+            """
+            check(types)
+            lists = []
+            for t, vas in zip(types, vancestors(*types)):
+                n_vas = len(vas)
+                if n_vas > 1:
+                    raise RuntimeError(
+                        'Ambiguous dispatch for %s: %s' % (t, vas))
+                elif n_vas == 1:
+                    va, = vas
+                    mro = type('t', (t, va), {}).__mro__[1:]
+                else:
+                    mro = t.__mro__
+                lists.append(mro[:-1])  # discard t and object
+            return lists
+
+        def register(*types):
+            """
+            Decorator to register an implementation for the given types
+            """
+            check(types)
+
+            def dec(f):
+                check(getfullargspec(f).args, operator.lt, ' in ' + f.__name__)
+                typemap[types] = f
+                return f
+
+            return dec
+
+        def dispatch_info(*types):
+            """
+            An utility to introspect the dispatch algorithm
+            """
+            check(types)
+            lst = []
+            for anc in itertools.product(*ancestors(*types)):
+                lst.append(tuple(a.__name__ for a in anc))
+            return lst
+
+        def _dispatch(dispatch_args, *args, **kw):
+            types = tuple(type(arg) for arg in dispatch_args)
+            try:  # fast path
+                f = typemap[types]
+            except KeyError:
+                pass
+            else:
+                return f(*args, **kw)
+            combinations = itertools.product(*ancestors(*types))
+            next(combinations)  # the first one has been already tried
+            for types_ in combinations:
+                f = typemap.get(types_)
+                if f is not None:
+                    return f(*args, **kw)
+
+            # else call the default implementation
+            return func(*args, **kw)
+
+        return FunctionMaker.create(
+            func, 'return _f_(%s, %%(shortsignature)s)' % dispatch_str,
+            dict(_f_=_dispatch), register=register, default=func,
+            typemap=typemap, vancestors=vancestors, ancestors=ancestors,
+            dispatch_info=dispatch_info, __wrapped__=func)
+
+    gen_func_dec.__name__ = 'dispatch_on' + dispatch_str
+    return gen_func_dec
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py
new file mode 100644
index 00000000000..0b63f6f6efb
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py
@@ -0,0 +1,828 @@
+import base64
+from contextlib import closing
+from functools import partial
+import gzip
+from http.server import BaseHTTPRequestHandler
+import os
+import socket
+from socketserver import ThreadingMixIn
+import ssl
+import sys
+import threading
+from typing import (
+    Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union,
+)
+from urllib.error import HTTPError
+from urllib.parse import parse_qs, quote_plus, urlparse
+from urllib.request import (
+    BaseHandler, build_opener, HTTPHandler, HTTPRedirectHandler, HTTPSHandler,
+    Request,
+)
+from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer
+
+from .openmetrics import exposition as openmetrics
+from .registry import Collector, REGISTRY
+from .utils import floatToGoString, parse_version
+
+try:
+    import snappy  # type: ignore
+    SNAPPY_AVAILABLE = True
+except ImportError:
+    snappy = None  # type: ignore
+    SNAPPY_AVAILABLE = False
+
+__all__ = (
+    'CONTENT_TYPE_LATEST',
+    'CONTENT_TYPE_PLAIN_0_0_4',
+    'CONTENT_TYPE_PLAIN_1_0_0',
+    'delete_from_gateway',
+    'generate_latest',
+    'instance_ip_grouping_key',
+    'make_asgi_app',
+    'make_wsgi_app',
+    'MetricsHandler',
+    'push_to_gateway',
+    'pushadd_to_gateway',
+    'start_http_server',
+    'start_wsgi_server',
+    'write_to_textfile',
+)
+
+CONTENT_TYPE_PLAIN_0_0_4 = 'text/plain; version=0.0.4; charset=utf-8'
+"""Content type of the compatibility format"""
+
+CONTENT_TYPE_PLAIN_1_0_0 = 'text/plain; version=1.0.0; charset=utf-8'
+"""Content type of the latest format"""
+
+CONTENT_TYPE_LATEST = CONTENT_TYPE_PLAIN_1_0_0
+CompressionType = Optional[Literal['gzip', 'snappy']]
+
+
+class _PrometheusRedirectHandler(HTTPRedirectHandler):
+    """
+    Allow additional methods (e.g. PUT) and data forwarding in redirects.
+
+    Use of this class constitute a user's explicit agreement to the
+    redirect responses the Prometheus client will receive when using it.
+    You should only use this class if you control or otherwise trust the
+    redirect behavior involved and are certain it is safe to full transfer
+    the original request (method and data) to the redirected URL. For
+    example, if you know there is a cosmetic URL redirect in front of a
+    local deployment of a Prometheus server, and all redirects are safe,
+    this is the class to use to handle redirects in that case.
+
+    The standard HTTPRedirectHandler does not forward request data nor
+    does it allow redirected PUT requests (which Prometheus uses for some
+    operations, for example `push_to_gateway`) because these cannot
+    generically guarantee no violations of HTTP RFC 2616 requirements for
+    the user to explicitly confirm redirects that could have unexpected
+    side effects (such as rendering a PUT request non-idempotent or
+    creating multiple resources not named in the original request).
+    """
+
+    def redirect_request(self, req, fp, code, msg, headers, newurl):
+        """
+        Apply redirect logic to a request.
+
+        See parent HTTPRedirectHandler.redirect_request for parameter info.
+
+        If the redirect is disallowed, this raises the corresponding HTTP error.
+        If the redirect can't be determined, return None to allow other handlers
+        to try. If the redirect is allowed, return the new request.
+
+        This method specialized for the case when (a) the user knows that the
+        redirect will not cause unacceptable side effects for any request method,
+        and (b) the user knows that any request data should be passed through to
+        the redirect. If either condition is not met, this should not be used.
+        """
+        # note that requests being provided by a handler will use get_method to
+        # indicate the method, by monkeypatching this, instead of setting the
+        # Request object's method attribute.
+        m = getattr(req, "method", req.get_method())
+        if not (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
+                or code in (301, 302, 303) and m in ("POST", "PUT")):
+            raise HTTPError(req.full_url, code, msg, headers, fp)
+        new_request = Request(
+            newurl.replace(' ', '%20'),  # space escaping in new url if needed.
+            headers=req.headers,
+            origin_req_host=req.origin_req_host,
+            unverifiable=True,
+            data=req.data,
+        )
+        new_request.method = m
+        return new_request
+
+
+def _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression):
+    """Bake output for metrics output."""
+    # Choose the correct plain text format of the output.
+    encoder, content_type = choose_encoder(accept_header)
+    if 'name[]' in params:
+        registry = registry.restricted_registry(params['name[]'])
+    output = encoder(registry)
+    headers = [('Content-Type', content_type)]
+    # If gzip encoding required, gzip the output.
+    if not disable_compression and gzip_accepted(accept_encoding_header):
+        output = gzip.compress(output)
+        headers.append(('Content-Encoding', 'gzip'))
+    return '200 OK', headers, output
+
+
+def make_wsgi_app(registry: Collector = REGISTRY, disable_compression: bool = False) -> Callable:
+    """Create a WSGI app which serves the metrics from a registry."""
+
+    def prometheus_app(environ, start_response):
+        # Prepare parameters
+        accept_header = environ.get('HTTP_ACCEPT')
+        accept_encoding_header = environ.get('HTTP_ACCEPT_ENCODING')
+        params = parse_qs(environ.get('QUERY_STRING', ''))
+        method = environ['REQUEST_METHOD']
+
+        if method == 'OPTIONS':
+            status = '200 OK'
+            headers = [('Allow', 'OPTIONS,GET')]
+            output = b''
+        elif method != 'GET':
+            status = '405 Method Not Allowed'
+            headers = [('Allow', 'OPTIONS,GET')]
+            output = '# HTTP {}: {}; use OPTIONS or GET\n'.format(status, method).encode()
+        elif environ['PATH_INFO'] == '/favicon.ico':
+            # Serve empty response for browsers
+            status = '200 OK'
+            headers = []
+            output = b''
+        else:
+            # Note: For backwards compatibility, the URI path for GET is not
+            # constrained to the documented /metrics, but any path is allowed.
+            # Bake output
+            status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression)
+        # Return output
+        start_response(status, headers)
+        return [output]
+
+    return prometheus_app
+
+
+class _SilentHandler(WSGIRequestHandler):
+    """WSGI handler that does not log requests."""
+
+    def log_message(self, format, *args):
+        """Log nothing."""
+
+
+class ThreadingWSGIServer(ThreadingMixIn, WSGIServer):
+    """Thread per request HTTP server."""
+    # Make worker threads "fire and forget". Beginning with Python 3.7 this
+    # prevents a memory leak because ``ThreadingMixIn`` starts to gather all
+    # non-daemon threads in a list in order to join on them at server close.
+    daemon_threads = True
+
+
+def _get_best_family(address, port):
+    """Automatically select address family depending on address"""
+    # HTTPServer defaults to AF_INET, which will not start properly if
+    # binding an ipv6 address is requested.
+    # This function is based on what upstream python did for http.server
+    # in https://github.com/python/cpython/pull/11767
+    infos = socket.getaddrinfo(address, port, type=socket.SOCK_STREAM, flags=socket.AI_PASSIVE)
+    family, _, _, _, sockaddr = next(iter(infos))
+    return family, sockaddr[0]
+
+
+def _get_ssl_ctx(
+        certfile: str,
+        keyfile: str,
+        protocol: int,
+        cafile: Optional[str] = None,
+        capath: Optional[str] = None,
+        client_auth_required: bool = False,
+        tls_min_version: Optional[ssl.TLSVersion] = None,
+        tls_max_version: Optional[ssl.TLSVersion] = None
+) -> ssl.SSLContext:
+    """Load context supports SSL."""
+    ssl_cxt = ssl.SSLContext(protocol=protocol)
+
+    if cafile is not None or capath is not None:
+        try:
+            ssl_cxt.load_verify_locations(cafile, capath)
+        except IOError as exc:
+            exc_type = type(exc)
+            msg = str(exc)
+            raise exc_type(f"Cannot load CA certificate chain from file "
+                           f"{cafile!r} or directory {capath!r}: {msg}")
+    else:
+        try:
+            ssl_cxt.load_default_certs(purpose=ssl.Purpose.CLIENT_AUTH)
+        except IOError as exc:
+            exc_type = type(exc)
+            msg = str(exc)
+            raise exc_type(f"Cannot load default CA certificate chain: {msg}")
+
+    if client_auth_required:
+        ssl_cxt.verify_mode = ssl.CERT_REQUIRED
+
+    try:
+        ssl_cxt.load_cert_chain(certfile=certfile, keyfile=keyfile)
+    except IOError as exc:
+        exc_type = type(exc)
+        msg = str(exc)
+        raise exc_type(f"Cannot load server certificate file {certfile!r} or "
+                       f"its private key file {keyfile!r}: {msg}")
+
+    if tls_min_version is not None:
+        ssl_cxt.minimum_version = tls_min_version
+    if tls_max_version is not None:
+        ssl_cxt.maximum_version = tls_max_version
+
+    return ssl_cxt
+
+
+def start_wsgi_server(
+        port: int,
+        addr: str = '0.0.0.0',
+        registry: Collector = REGISTRY,
+        certfile: Optional[str] = None,
+        keyfile: Optional[str] = None,
+        client_cafile: Optional[str] = None,
+        client_capath: Optional[str] = None,
+        protocol: int = ssl.PROTOCOL_TLS_SERVER,
+        client_auth_required: bool = False,
+        tls_min_version: Optional[ssl.TLSVersion] = None,
+        tls_max_version: Optional[ssl.TLSVersion] = None
+) -> Tuple[WSGIServer, threading.Thread]:
+    """Starts a WSGI server for prometheus metrics as a daemon thread."""
+
+    class TmpServer(ThreadingWSGIServer):
+        """Copy of ThreadingWSGIServer to update address_family locally"""
+
+    TmpServer.address_family, addr = _get_best_family(addr, port)
+    app = make_wsgi_app(registry)
+    httpd = make_server(addr, port, app, TmpServer, handler_class=_SilentHandler)
+    if certfile and keyfile:
+        context = _get_ssl_ctx(
+            certfile,
+            keyfile,
+            protocol,
+            client_cafile,
+            client_capath,
+            client_auth_required,
+            tls_min_version,
+            tls_max_version
+        )
+        httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
+    t = threading.Thread(target=httpd.serve_forever)
+    t.daemon = True
+    t.start()
+
+    return httpd, t
+
+
+start_http_server = start_wsgi_server
+
+
+def generate_latest(registry: Collector = REGISTRY, escaping: str = openmetrics.UNDERSCORES) -> bytes:
+    """
+    Generates the exposition format using the basic Prometheus text format.
+
+    Params:
+        registry: Collector to export data from.
+        escaping: Escaping scheme used for metric and label names.
+
+    Returns: UTF-8 encoded string containing the metrics in text format.
+    """
+
+    def sample_line(samples):
+        if samples.labels:
+            labelstr = '{0}'.format(','.join(
+                # Label values always support UTF-8
+                ['{}="{}"'.format(
+                    openmetrics.escape_label_name(k, escaping), openmetrics._escape(v, openmetrics.ALLOWUTF8, False))
+                    for k, v in sorted(samples.labels.items())]))
+        else:
+            labelstr = ''
+        timestamp = ''
+        if samples.timestamp is not None:
+            # Convert to milliseconds.
+            timestamp = f' {int(float(samples.timestamp) * 1000):d}'
+        if escaping != openmetrics.ALLOWUTF8 or openmetrics._is_valid_legacy_metric_name(samples.name):
+            if labelstr:
+                labelstr = '{{{0}}}'.format(labelstr)
+            return f'{openmetrics.escape_metric_name(samples.name, escaping)}{labelstr} {floatToGoString(samples.value)}{timestamp}\n'
+        maybe_comma = ''
+        if labelstr:
+            maybe_comma = ','
+        return f'{{{openmetrics.escape_metric_name(samples.name, escaping)}{maybe_comma}{labelstr}}} {floatToGoString(samples.value)}{timestamp}\n'
+
+    output = []
+    for metric in registry.collect():
+        try:
+            mname = metric.name
+            mtype = metric.type
+            # Munging from OpenMetrics into Prometheus format.
+            if mtype == 'counter':
+                mname = mname + '_total'
+            elif mtype == 'info':
+                mname = mname + '_info'
+                mtype = 'gauge'
+            elif mtype == 'stateset':
+                mtype = 'gauge'
+            elif mtype == 'gaugehistogram':
+                # A gauge histogram is really a gauge,
+                # but this captures the structure better.
+                mtype = 'histogram'
+            elif mtype == 'unknown':
+                mtype = 'untyped'
+
+            output.append('# HELP {} {}\n'.format(
+                openmetrics.escape_metric_name(mname, escaping), metric.documentation.replace('\\', r'\\').replace('\n', r'\n')))
+            output.append(f'# TYPE {openmetrics.escape_metric_name(mname, escaping)} {mtype}\n')
+
+            om_samples: Dict[str, List[str]] = {}
+            for s in metric.samples:
+                for suffix in ['_created', '_gsum', '_gcount']:
+                    if s.name == metric.name + suffix:
+                        # OpenMetrics specific sample, put in a gauge at the end.
+                        om_samples.setdefault(suffix, []).append(sample_line(s))
+                        break
+                else:
+                    output.append(sample_line(s))
+        except Exception as exception:
+            exception.args = (exception.args or ('',)) + (metric,)
+            raise
+
+        for suffix, lines in sorted(om_samples.items()):
+            output.append('# HELP {} {}\n'.format(openmetrics.escape_metric_name(metric.name + suffix, escaping),
+                                                  metric.documentation.replace('\\', r'\\').replace('\n', r'\n')))
+            output.append(f'# TYPE {openmetrics.escape_metric_name(metric.name + suffix, escaping)} gauge\n')
+            output.extend(lines)
+    return ''.join(output).encode('utf-8')
+
+
+def choose_encoder(accept_header: str) -> Tuple[Callable[[Collector], bytes], str]:
+    # Python client library accepts a narrower range of content-types than
+    # Prometheus does.
+    accept_header = accept_header or ''
+    escaping = openmetrics.UNDERSCORES
+    for accepted in accept_header.split(','):
+        if accepted.split(';')[0].strip() == 'application/openmetrics-text':
+            toks = accepted.split(';')
+            version = _get_version(toks)
+            escaping = _get_escaping(toks)
+            # Only return an escaping header if we have a good version and
+            # mimetype.
+            if not version:
+                return (partial(openmetrics.generate_latest, escaping=openmetrics.UNDERSCORES, version="1.0.0"), openmetrics.CONTENT_TYPE_LATEST)
+            if version and parse_version(version) >= (1, 0, 0):
+                return (partial(openmetrics.generate_latest, escaping=escaping, version=version),
+                        f'application/openmetrics-text; version={version}; charset=utf-8; escaping=' + str(escaping))
+        elif accepted.split(';')[0].strip() == 'text/plain':
+            toks = accepted.split(';')
+            version = _get_version(toks)
+            escaping = _get_escaping(toks)
+            # Only return an escaping header if we have a good version and
+            # mimetype.
+            if version and parse_version(version) >= (1, 0, 0):
+                return (partial(generate_latest, escaping=escaping),
+                        CONTENT_TYPE_LATEST + '; escaping=' + str(escaping))
+    return generate_latest, CONTENT_TYPE_PLAIN_0_0_4
+
+
+def _get_version(accept_header: List[str]) -> str:
+    """Return the version tag from the Accept header.
+
+    If no version is specified, returns empty string."""
+
+    for tok in accept_header:
+        if '=' not in tok:
+            continue
+        key, value = tok.strip().split('=', 1)
+        if key == 'version':
+            return value
+    return ""
+
+
+def _get_escaping(accept_header: List[str]) -> str:
+    """Return the escaping scheme from the Accept header.
+
+    If no escaping scheme is specified or the scheme is not one of the allowed
+    strings, defaults to UNDERSCORES."""
+
+    for tok in accept_header:
+        if '=' not in tok:
+            continue
+        key, value = tok.strip().split('=', 1)
+        if key != 'escaping':
+            continue
+        if value == openmetrics.ALLOWUTF8:
+            return openmetrics.ALLOWUTF8
+        elif value == openmetrics.UNDERSCORES:
+            return openmetrics.UNDERSCORES
+        elif value == openmetrics.DOTS:
+            return openmetrics.DOTS
+        elif value == openmetrics.VALUES:
+            return openmetrics.VALUES
+        else:
+            return openmetrics.UNDERSCORES
+    return openmetrics.UNDERSCORES
+
+
+def gzip_accepted(accept_encoding_header: str) -> bool:
+    accept_encoding_header = accept_encoding_header or ''
+    for accepted in accept_encoding_header.split(','):
+        if accepted.split(';')[0].strip().lower() == 'gzip':
+            return True
+    return False
+
+
+class MetricsHandler(BaseHTTPRequestHandler):
+    """HTTP handler that gives metrics from ``REGISTRY``."""
+    registry: Collector = REGISTRY
+
+    def do_GET(self) -> None:
+        # Prepare parameters
+        registry = self.registry
+        accept_header = self.headers.get('Accept')
+        accept_encoding_header = self.headers.get('Accept-Encoding')
+        params = parse_qs(urlparse(self.path).query)
+        # Bake output
+        status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, False)
+        # Return output
+        self.send_response(int(status.split(' ')[0]))
+        for header in headers:
+            self.send_header(*header)
+        self.end_headers()
+        self.wfile.write(output)
+
+    def log_message(self, format: str, *args: Any) -> None:
+        """Log nothing."""
+
+    @classmethod
+    def factory(cls, registry: Collector) -> type:
+        """Returns a dynamic MetricsHandler class tied
+           to the passed registry.
+        """
+        # This implementation relies on MetricsHandler.registry
+        #  (defined above and defaulted to REGISTRY).
+
+        # As we have unicode_literals, we need to create a str()
+        #  object for type().
+        cls_name = str(cls.__name__)
+        MyMetricsHandler = type(cls_name, (cls, object),
+                                {"registry": registry})
+        return MyMetricsHandler
+
+
+def write_to_textfile(path: str, registry: Collector, escaping: str = openmetrics.ALLOWUTF8, tmpdir: Optional[str] = None) -> None:
+    """Write metrics to the given path.
+
+    This is intended for use with the Node exporter textfile collector.
+    The path must end in .prom for the textfile collector to process it.
+
+    An optional tmpdir parameter can be set to determine where the
+    metrics will be temporarily written to. If not set, it will be in
+    the same directory as the .prom file. If provided, the path MUST be
+    on the same filesystem."""
+    if tmpdir is not None:
+        filename = os.path.basename(path)
+        tmppath = f'{os.path.join(tmpdir, filename)}.{os.getpid()}.{threading.current_thread().ident}'
+    else:
+        tmppath = f'{path}.{os.getpid()}.{threading.current_thread().ident}'
+    try:
+        with open(tmppath, 'wb') as f:
+            f.write(generate_latest(registry, escaping))
+
+        # rename(2) is atomic but fails on Windows if the destination file exists
+        if os.name == 'nt':
+            os.replace(tmppath, path)
+        else:
+            os.rename(tmppath, path)
+    except Exception:
+        if os.path.exists(tmppath):
+            os.remove(tmppath)
+        raise
+
+
+def _make_handler(
+        url: str,
+        method: str,
+        timeout: Optional[float],
+        headers: Sequence[Tuple[str, str]],
+        data: bytes,
+        base_handler: Union[BaseHandler, type],
+) -> Callable[[], None]:
+    def handle() -> None:
+        request = Request(url, data=data)
+        request.get_method = lambda: method  # type: ignore
+        for k, v in headers:
+            request.add_header(k, v)
+        resp = build_opener(base_handler).open(request, timeout=timeout)
+        if resp.code >= 400:
+            raise OSError(f"error talking to pushgateway: {resp.code} {resp.msg}")
+
+    return handle
+
+
+def default_handler(
+        url: str,
+        method: str,
+        timeout: Optional[float],
+        headers: List[Tuple[str, str]],
+        data: bytes,
+) -> Callable[[], None]:
+    """Default handler that implements HTTP/HTTPS connections.
+
+    Used by the push_to_gateway functions. Can be re-used by other handlers."""
+
+    return _make_handler(url, method, timeout, headers, data, HTTPHandler)
+
+
+def passthrough_redirect_handler(
+        url: str,
+        method: str,
+        timeout: Optional[float],
+        headers: List[Tuple[str, str]],
+        data: bytes,
+) -> Callable[[], None]:
+    """
+    Handler that automatically trusts redirect responses for all HTTP methods.
+
+    Augments standard HTTPRedirectHandler capability by permitting PUT requests,
+    preserving the method upon redirect, and passing through all headers and
+    data from the original request. Only use this handler if you control or
+    trust the source of redirect responses you encounter when making requests
+    via the Prometheus client. This handler will simply repeat the identical
+    request, including same method and data, to the new redirect URL."""
+
+    return _make_handler(url, method, timeout, headers, data, _PrometheusRedirectHandler)
+
+
+def basic_auth_handler(
+        url: str,
+        method: str,
+        timeout: Optional[float],
+        headers: List[Tuple[str, str]],
+        data: bytes,
+        username: Optional[str] = None,
+        password: Optional[str] = None,
+) -> Callable[[], None]:
+    """Handler that implements HTTP/HTTPS connections with Basic Auth.
+
+    Sets auth headers using supplied 'username' and 'password', if set.
+    Used by the push_to_gateway functions. Can be re-used by other handlers."""
+
+    def handle():
+        """Handler that implements HTTP Basic Auth.
+        """
+        if username is not None and password is not None:
+            auth_value = f'{username}:{password}'.encode()
+            auth_token = base64.b64encode(auth_value)
+            auth_header = b'Basic ' + auth_token
+            headers.append(('Authorization', auth_header))
+        default_handler(url, method, timeout, headers, data)()
+
+    return handle
+
+
+def tls_auth_handler(
+        url: str,
+        method: str,
+        timeout: Optional[float],
+        headers: List[Tuple[str, str]],
+        data: bytes,
+        certfile: str,
+        keyfile: str,
+        cafile: Optional[str] = None,
+        protocol: int = ssl.PROTOCOL_TLS_CLIENT,
+        insecure_skip_verify: bool = False,
+) -> Callable[[], None]:
+    """Handler that implements an HTTPS connection with TLS Auth.
+
+    The default protocol (ssl.PROTOCOL_TLS_CLIENT) will also enable
+    ssl.CERT_REQUIRED and SSLContext.check_hostname by default. This can be
+    disabled by setting insecure_skip_verify to True.
+
+    Both this handler and the TLS feature on pushgateay are experimental."""
+    context = ssl.SSLContext(protocol=protocol)
+    if cafile is not None:
+        context.load_verify_locations(cafile)
+    else:
+        context.load_default_certs()
+
+    if insecure_skip_verify:
+        context.check_hostname = False
+        context.verify_mode = ssl.CERT_NONE
+
+    context.load_cert_chain(certfile=certfile, keyfile=keyfile)
+    handler = HTTPSHandler(context=context)
+    return _make_handler(url, method, timeout, headers, data, handler)
+
+
+def push_to_gateway(
+        gateway: str,
+        job: str,
+        registry: Collector,
+        grouping_key: Optional[Dict[str, Any]] = None,
+        timeout: Optional[float] = 30,
+        handler: Callable = default_handler,
+        compression: CompressionType = None,
+) -> None:
+    """Push metrics to the given pushgateway.
+
+    `gateway` the url for your push gateway. Either of the form
+              'http://pushgateway.local', or 'pushgateway.local'.
+              Scheme defaults to 'http' if none is provided
+    `job` is the job label to be attached to all pushed metrics
+    `registry` is a Collector, normally an instance of CollectorRegistry
+    `grouping_key` please see the pushgateway documentation for details.
+                   Defaults to None
+    `timeout` is how long push will attempt to connect before giving up.
+              Defaults to 30s, can be set to None for no timeout.
+    `handler` is an optional function which can be provided to perform
+              requests to the 'gateway'.
+              Defaults to None, in which case an http or https request
+              will be carried out by a default handler.
+              If not None, the argument must be a function which accepts
+              the following arguments:
+              url, method, timeout, headers, and content
+              May be used to implement additional functionality not
+              supported by the built-in default handler (such as SSL
+              client certicates, and HTTP authentication mechanisms).
+              'url' is the URL for the request, the 'gateway' argument
+              described earlier will form the basis of this URL.
+              'method' is the HTTP method which should be used when
+              carrying out the request.
+              'timeout' requests not successfully completed after this
+              many seconds should be aborted.  If timeout is None, then
+              the handler should not set a timeout.
+              'headers' is a list of ("header-name","header-value") tuples
+              which must be passed to the pushgateway in the form of HTTP
+              request headers.
+              The function should raise an exception (e.g. IOError) on
+              failure.
+              'content' is the data which should be used to form the HTTP
+              Message Body.
+    `compression` selects the payload compression. Supported values are 'gzip'
+                  and 'snappy'. Defaults to None (no compression).
+
+    This overwrites all metrics with the same job and grouping_key.
+    This uses the PUT HTTP method."""
+    _use_gateway('PUT', gateway, job, registry, grouping_key, timeout, handler, compression)
+
+
+def pushadd_to_gateway(
+        gateway: str,
+        job: str,
+        registry: Optional[Collector],
+        grouping_key: Optional[Dict[str, Any]] = None,
+        timeout: Optional[float] = 30,
+        handler: Callable = default_handler,
+        compression: CompressionType = None,
+) -> None:
+    """PushAdd metrics to the given pushgateway.
+
+    `gateway` the url for your push gateway. Either of the form
+              'http://pushgateway.local', or 'pushgateway.local'.
+              Scheme defaults to 'http' if none is provided
+    `job` is the job label to be attached to all pushed metrics
+    `registry` is a Collector, normally an instance of CollectorRegistry
+    `grouping_key` please see the pushgateway documentation for details.
+                   Defaults to None
+    `timeout` is how long push will attempt to connect before giving up.
+              Defaults to 30s, can be set to None for no timeout.
+    `handler` is an optional function which can be provided to perform
+              requests to the 'gateway'.
+              Defaults to None, in which case an http or https request
+              will be carried out by a default handler.
+              See the 'prometheus_client.push_to_gateway' documentation
+              for implementation requirements.
+    `compression` selects the payload compression. Supported values are 'gzip'
+                  and 'snappy'. Defaults to None (no compression).
+
+    This replaces metrics with the same name, job and grouping_key.
+    This uses the POST HTTP method."""
+    _use_gateway('POST', gateway, job, registry, grouping_key, timeout, handler, compression)
+
+
+def delete_from_gateway(
+        gateway: str,
+        job: str,
+        grouping_key: Optional[Dict[str, Any]] = None,
+        timeout: Optional[float] = 30,
+        handler: Callable = default_handler,
+) -> None:
+    """Delete metrics from the given pushgateway.
+
+    `gateway` the url for your push gateway. Either of the form
+              'http://pushgateway.local', or 'pushgateway.local'.
+              Scheme defaults to 'http' if none is provided
+    `job` is the job label to be attached to all pushed metrics
+    `grouping_key` please see the pushgateway documentation for details.
+                   Defaults to None
+    `timeout` is how long delete will attempt to connect before giving up.
+              Defaults to 30s, can be set to None for no timeout.
+    `handler` is an optional function which can be provided to perform
+              requests to the 'gateway'.
+              Defaults to None, in which case an http or https request
+              will be carried out by a default handler.
+              See the 'prometheus_client.push_to_gateway' documentation
+              for implementation requirements.
+
+    This deletes metrics with the given job and grouping_key.
+    This uses the DELETE HTTP method."""
+    _use_gateway('DELETE', gateway, job, None, grouping_key, timeout, handler)
+
+
+def _use_gateway(
+        method: str,
+        gateway: str,
+        job: str,
+        registry: Optional[Collector],
+        grouping_key: Optional[Dict[str, Any]],
+        timeout: Optional[float],
+        handler: Callable,
+        compression: CompressionType = None,
+) -> None:
+    gateway_url = urlparse(gateway)
+    # See https://bugs.python.org/issue27657 for details on urlparse in py>=3.7.6.
+    if not gateway_url.scheme or gateway_url.scheme not in ['http', 'https']:
+        gateway = f'http://{gateway}'
+
+    gateway = gateway.rstrip('/')
+    url = '{}/metrics/{}/{}'.format(gateway, *_escape_grouping_key("job", job))
+
+    if grouping_key is None:
+        grouping_key = {}
+    url += ''.join(
+        '/{}/{}'.format(*_escape_grouping_key(str(k), str(v)))
+        for k, v in sorted(grouping_key.items()))
+
+    data = b''
+    headers: List[Tuple[str, str]] = []
+    if method != 'DELETE':
+        if registry is None:
+            registry = REGISTRY
+        data = generate_latest(registry)
+        data, headers = _compress_payload(data, compression)
+    else:
+        # DELETE requests still need Content-Type header per test expectations
+        headers = [('Content-Type', CONTENT_TYPE_PLAIN_0_0_4)]
+        if compression is not None:
+            raise ValueError('Compression is not supported for DELETE requests.')
+
+    handler(
+        url=url, method=method, timeout=timeout,
+        headers=headers, data=data,
+    )()
+
+
+def _compress_payload(data: bytes, compression: CompressionType) -> Tuple[bytes, List[Tuple[str, str]]]:
+    headers = [('Content-Type', CONTENT_TYPE_PLAIN_0_0_4)]
+    if compression is None:
+        return data, headers
+
+    encoding = compression.lower()
+    if encoding == 'gzip':
+        headers.append(('Content-Encoding', 'gzip'))
+        return gzip.compress(data), headers
+    if encoding == 'snappy':
+        if not SNAPPY_AVAILABLE:
+            raise RuntimeError('Snappy compression requires the python-snappy package to be installed.')
+        headers.append(('Content-Encoding', 'snappy'))
+        compressor = snappy.StreamCompressor()
+        compressed = compressor.compress(data)
+        flush = getattr(compressor, 'flush', None)
+        if callable(flush):
+            compressed += flush()
+        return compressed, headers
+    raise ValueError(f"Unsupported compression type: {compression}")
+
+
+def _escape_grouping_key(k, v):
+    if v == "":
+        # Per https://github.com/prometheus/pushgateway/pull/346.
+        return k + "@base64", "="
+    elif '/' in v or ' ' in v:
+        # Added in Pushgateway 0.9.0.
+        # Use base64 encoding for values containing slashes or spaces
+        return k + "@base64", base64.urlsafe_b64encode(v.encode("utf-8")).decode("utf-8")
+    else:
+        return k, quote_plus(v)
+
+
+def instance_ip_grouping_key() -> Dict[str, Any]:
+    """Grouping key with instance set to the IP Address of this host."""
+    with closing(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) as s:
+        if sys.platform == 'darwin':
+            # This check is done this way only on MacOS devices
+            # it is done this way because the localhost method does
+            # not work.
+            # This method was adapted from this StackOverflow answer:
+            # https://stackoverflow.com/a/28950776
+            s.connect(('10.255.255.255', 1))
+        else:
+            s.connect(('localhost', 0))
+
+        return {'instance': s.getsockname()[0]}
+
+
+from .asgi import make_asgi_app  # noqa
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py
new file mode 100644
index 00000000000..06e52dfc3c8
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py
@@ -0,0 +1,45 @@
+import gc
+import platform
+from typing import Iterable
+
+from .metrics_core import CounterMetricFamily, Metric
+from .registry import Collector, CollectorRegistry, REGISTRY
+
+
+class GCCollector(Collector):
+    """Collector for Garbage collection statistics."""
+
+    def __init__(self, registry: CollectorRegistry = REGISTRY):
+        if not hasattr(gc, 'get_stats') or platform.python_implementation() != 'CPython':
+            return
+        registry.register(self)
+
+    def collect(self) -> Iterable[Metric]:
+        collected = CounterMetricFamily(
+            'python_gc_objects_collected',
+            'Objects collected during gc',
+            labels=['generation'],
+        )
+        uncollectable = CounterMetricFamily(
+            'python_gc_objects_uncollectable',
+            'Uncollectable objects found during GC',
+            labels=['generation'],
+        )
+
+        collections = CounterMetricFamily(
+            'python_gc_collections',
+            'Number of times this generation was collected',
+            labels=['generation'],
+        )
+
+        for gen, stat in enumerate(gc.get_stats()):
+            generation = str(gen)
+            collected.add_metric([generation], value=stat['collected'])
+            uncollectable.add_metric([generation], value=stat['uncollectable'])
+            collections.add_metric([generation], value=stat['collections'])
+
+        return [collected, uncollectable, collections]
+
+
+GC_COLLECTOR = GCCollector()
+"""Default GCCollector in default Registry REGISTRY."""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py
new file mode 100644
index 00000000000..e3fe5323104
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py
@@ -0,0 +1,804 @@
+import os
+from threading import Lock
+import time
+import types
+from typing import (
+    Any, Callable, Dict, Iterable, List, Literal, Optional, Sequence, Tuple,
+    Type, TypeVar, Union,
+)
+import warnings
+
+from . import values  # retain this import style for testability
+from .context_managers import ExceptionCounter, InprogressTracker, Timer
+from .metrics_core import Metric
+from .registry import Collector, CollectorRegistry, REGISTRY
+from .samples import Exemplar, Sample
+from .utils import floatToGoString, INF
+from .validation import (
+    _validate_exemplar, _validate_labelnames, _validate_metric_name,
+)
+
+T = TypeVar('T', bound='MetricWrapperBase')
+F = TypeVar("F", bound=Callable[..., Any])
+
+
+def _build_full_name(metric_type, name, namespace, subsystem, unit):
+    if not name:
+        raise ValueError('Metric name should not be empty')
+    full_name = ''
+    if namespace:
+        full_name += namespace + '_'
+    if subsystem:
+        full_name += subsystem + '_'
+    full_name += name
+    if metric_type == 'counter' and full_name.endswith('_total'):
+        full_name = full_name[:-6]  # Munge to OpenMetrics.
+    if unit and not full_name.endswith("_" + unit):
+        full_name += "_" + unit
+    if unit and metric_type in ('info', 'stateset'):
+        raise ValueError('Metric name is of a type that cannot have a unit: ' + full_name)
+    return full_name
+
+
+
+def _get_use_created() -> bool:
+    return os.environ.get("PROMETHEUS_DISABLE_CREATED_SERIES", 'False').lower() not in ('true', '1', 't')
+
+
+_use_created = _get_use_created()
+
+
+def disable_created_metrics():
+    """Disable exporting _created metrics on counters, histograms, and summaries."""
+    global _use_created
+    _use_created = False
+
+
+def enable_created_metrics():
+    """Enable exporting _created metrics on counters, histograms, and summaries."""
+    global _use_created
+    _use_created = True
+
+
+class MetricWrapperBase(Collector):
+    _type: Optional[str] = None
+    _reserved_labelnames: Sequence[str] = ()
+
+    def _is_observable(self):
+        # Whether this metric is observable, i.e.
+        # * a metric without label names and values, or
+        # * the child of a labelled metric.
+        return not self._labelnames or (self._labelnames and self._labelvalues)
+
+    def _raise_if_not_observable(self):
+        # Functions that mutate the state of the metric, for example incrementing
+        # a counter, will fail if the metric is not observable, because only if a
+        # metric is observable will the value be initialized.
+        if not self._is_observable():
+            raise ValueError('%s metric is missing label values' % str(self._type))
+
+    def _is_parent(self):
+        return self._labelnames and not self._labelvalues
+
+    def _get_metric(self):
+        return Metric(self._name, self._documentation, self._type, self._unit)
+
+    def describe(self) -> Iterable[Metric]:
+        return [self._get_metric()]
+
+    def collect(self) -> Iterable[Metric]:
+        metric = self._get_metric()
+        for suffix, labels, value, timestamp, exemplar, native_histogram_value in self._samples():
+            metric.add_sample(self._name + suffix, labels, value, timestamp, exemplar, native_histogram_value)
+        return [metric]
+
+    def __str__(self) -> str:
+        return f"{self._type}:{self._name}"
+
+    def __repr__(self) -> str:
+        metric_type = type(self)
+        return f"{metric_type.__module__}.{metric_type.__name__}({self._name})"
+
+    def __init__(self: T,
+                 name: str,
+                 documentation: str,
+                 labelnames: Iterable[str] = (),
+                 namespace: str = '',
+                 subsystem: str = '',
+                 unit: str = '',
+                 registry: Optional[CollectorRegistry] = REGISTRY,
+                 _labelvalues: Optional[Sequence[str]] = None,
+                 ) -> None:
+
+        self._original_name = name
+        self._namespace = namespace
+        self._subsystem = subsystem
+        self._name = _build_full_name(self._type, name, namespace, subsystem, unit)
+        self._labelnames = _validate_labelnames(self, labelnames)
+        self._labelvalues = tuple(_labelvalues or ())
+        self._kwargs: Dict[str, Any] = {}
+        self._documentation = documentation
+        self._unit = unit
+
+        _validate_metric_name(self._name)
+
+        if self._is_parent():
+            # Prepare the fields needed for child metrics.
+            self._lock = Lock()
+            self._metrics: Dict[Sequence[str], T] = {}
+
+        if self._is_observable():
+            self._metric_init()
+
+        if not self._labelvalues:
+            # Register the multi-wrapper parent metric, or if a label-less metric, the whole shebang.
+            if registry:
+                registry.register(self)
+
+    def labels(self: T, *labelvalues: object, **labelkwargs: object) -> T:
+        """Return the child for the given labelset.
+
+        All metrics can have labels, allowing grouping of related time series.
+        Taking a counter as an example:
+
+            from prometheus_client import Counter
+
+            c = Counter('my_requests_total', 'HTTP Failures', ['method', 'endpoint'])
+            c.labels('get', '/').inc()
+            c.labels('post', '/submit').inc()
+
+        Labels can also be provided as keyword arguments:
+
+            from prometheus_client import Counter
+
+            c = Counter('my_requests_total', 'HTTP Failures', ['method', 'endpoint'])
+            c.labels(method='get', endpoint='/').inc()
+            c.labels(method='post', endpoint='/submit').inc()
+
+        See the best practices on [naming](http://prometheus.io/docs/practices/naming/)
+        and [labels](http://prometheus.io/docs/practices/instrumentation/#use-labels).
+        """
+        if not self._labelnames:
+            raise ValueError('No label names were set when constructing %s' % self)
+
+        if self._labelvalues:
+            raise ValueError('{} already has labels set ({}); can not chain calls to .labels()'.format(
+                self,
+                dict(zip(self._labelnames, self._labelvalues))
+            ))
+
+        if labelvalues and labelkwargs:
+            raise ValueError("Can't pass both *args and **kwargs")
+
+        if labelkwargs:
+            if sorted(labelkwargs) != sorted(self._labelnames):
+                raise ValueError('Incorrect label names')
+            str_labelvalues = tuple(str(labelkwargs[l]) for l in self._labelnames)
+        else:
+            if len(labelvalues) != len(self._labelnames):
+                raise ValueError('Incorrect label count')
+            str_labelvalues = tuple(str(l) for l in labelvalues)
+        with self._lock:
+            if str_labelvalues not in self._metrics:
+
+                original_name = getattr(self, '_original_name', self._name)
+                namespace = getattr(self, '_namespace', '')
+                subsystem = getattr(self, '_subsystem', '')
+                unit = getattr(self, '_unit', '')
+
+                child_kwargs = dict(self._kwargs) if self._kwargs else {}
+                for k in ('namespace', 'subsystem', 'unit'):
+                    child_kwargs.pop(k, None)
+
+                self._metrics[str_labelvalues] = self.__class__(
+                    original_name,
+                    documentation=self._documentation,
+                    labelnames=self._labelnames,
+                    namespace=namespace,
+                    subsystem=subsystem,
+                    unit=unit,
+                    _labelvalues=str_labelvalues,
+                    **child_kwargs
+                )
+            return self._metrics[str_labelvalues]
+
+    def remove(self, *labelvalues: Any) -> None:
+        if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
+            warnings.warn(
+                "Removal of labels has not been implemented in  multi-process mode yet.",
+                UserWarning)
+
+        if not self._labelnames:
+            raise ValueError('No label names were set when constructing %s' % self)
+
+        """Remove the given labelset from the metric."""
+        if len(labelvalues) != len(self._labelnames):
+            raise ValueError('Incorrect label count (expected %d, got %s)' % (len(self._labelnames), labelvalues))
+        labelvalues = tuple(str(l) for l in labelvalues)
+        with self._lock:
+            if labelvalues in self._metrics:
+                del self._metrics[labelvalues]
+
+    def remove_by_labels(self, labels: dict[str, str]) -> None:
+        """Remove all series whose labelset partially matches the given labels."""
+        if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
+            warnings.warn(
+                "Removal of labels has not been implemented in  multi-process mode yet.",
+                UserWarning
+            )
+
+        if not self._labelnames:
+            raise ValueError('No label names were set when constructing %s' % self)
+        
+        if not isinstance(labels, dict):
+            raise TypeError("labels must be a dict of {label_name: label_value}")
+    
+        if not labels:
+            return  # no operation
+    
+        invalid = [k for k in labels.keys() if k not in self._labelnames]
+        if invalid:
+            raise ValueError(
+                'Unknown label names: %s; expected %s' % (invalid, self._labelnames)
+            )
+        
+        pos_filter = {self._labelnames.index(k): str(v) for k, v in labels.items()}
+
+        with self._lock:
+            # list(...) to avoid "dictionary changed size during iteration"
+            for lv in list(self._metrics.keys()):
+                if all(lv[pos] == want for pos, want in pos_filter.items()):
+                    # pop with default avoids KeyError if concurrently removed
+                    self._metrics.pop(lv, None)
+        
+
+    def clear(self) -> None:
+        """Remove all labelsets from the metric"""
+        if not self._labelnames:
+            return
+        if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
+            warnings.warn(
+                "Clearing labels has not been implemented in multi-process mode yet",
+                UserWarning)
+        with self._lock:
+            self._metrics = {}
+
+    def _samples(self) -> Iterable[Sample]:
+        if self._is_parent():
+            return self._multi_samples()
+        else:
+            return self._child_samples()
+
+    def _multi_samples(self) -> Iterable[Sample]:
+        with self._lock:
+            metrics = self._metrics.copy()
+        for labels, metric in metrics.items():
+            series_labels = list(zip(self._labelnames, labels))
+            for suffix, sample_labels, value, timestamp, exemplar, native_histogram_value in metric._samples():
+                yield Sample(suffix, dict(series_labels + list(sample_labels.items())), value, timestamp, exemplar, native_histogram_value)
+
+    def _child_samples(self) -> Iterable[Sample]:  # pragma: no cover
+        raise NotImplementedError('_child_samples() must be implemented by %r' % self)
+
+    def _metric_init(self):  # pragma: no cover
+        """
+        Initialize the metric object as a child, i.e. when it has labels (if any) set.
+
+        This is factored as a separate function to allow for deferred initialization.
+        """
+        raise NotImplementedError('_metric_init() must be implemented by %r' % self)
+
+
+class Counter(MetricWrapperBase):
+    """A Counter tracks counts of events or running totals.
+
+    Example use cases for Counters:
+    - Number of requests processed
+    - Number of items that were inserted into a queue
+    - Total amount of data that a system has processed
+
+    Counters can only go up (and be reset when the process restarts). If your use case can go down,
+    you should use a Gauge instead.
+
+    An example for a Counter:
+
+        from prometheus_client import Counter
+
+        c = Counter('my_failures_total', 'Description of counter')
+        c.inc()     # Increment by 1
+        c.inc(1.6)  # Increment by given value
+
+    There are utilities to count exceptions raised:
+
+        @c.count_exceptions()
+        def f():
+            pass
+
+        with c.count_exceptions():
+            pass
+
+        # Count only one type of exception
+        with c.count_exceptions(ValueError):
+            pass
+            
+    You can also reset the counter to zero in case your logical "process" restarts
+    without restarting the actual python process.
+
+       c.reset()
+
+    """
+    _type = 'counter'
+
+    def _metric_init(self) -> None:
+        self._value = values.ValueClass(self._type, self._name, self._name + '_total', self._labelnames,
+                                        self._labelvalues, self._documentation)
+        self._created = time.time()
+
+    def inc(self, amount: float = 1, exemplar: Optional[Dict[str, str]] = None) -> None:
+        """Increment counter by the given amount."""
+        self._raise_if_not_observable()
+        if amount < 0:
+            raise ValueError('Counters can only be incremented by non-negative amounts.')
+        self._value.inc(amount)
+        if exemplar:
+            _validate_exemplar(exemplar)
+            self._value.set_exemplar(Exemplar(exemplar, amount, time.time()))
+
+    def reset(self) -> None:
+        """Reset the counter to zero. Use this when a logical process restarts without restarting the actual python process."""
+        self._value.set(0)
+        self._created = time.time()
+
+    def count_exceptions(self, exception: Union[Type[BaseException], Tuple[Type[BaseException], ...]] = Exception) -> ExceptionCounter:
+        """Count exceptions in a block of code or function.
+
+        Can be used as a function decorator or context manager.
+        Increments the counter when an exception of the given
+        type is raised up out of the code.
+        """
+        self._raise_if_not_observable()
+        return ExceptionCounter(self, exception)
+
+    def _child_samples(self) -> Iterable[Sample]:
+        sample = Sample('_total', {}, self._value.get(), None, self._value.get_exemplar())
+        if _use_created:
+            return (
+                sample,
+                Sample('_created', {}, self._created, None, None)
+            )
+        return (sample,)
+
+
+class Gauge(MetricWrapperBase):
+    """Gauge metric, to report instantaneous values.
+
+     Examples of Gauges include:
+        - Inprogress requests
+        - Number of items in a queue
+        - Free memory
+        - Total memory
+        - Temperature
+
+     Gauges can go both up and down.
+
+        from prometheus_client import Gauge
+
+        g = Gauge('my_inprogress_requests', 'Description of gauge')
+        g.inc()      # Increment by 1
+        g.dec(10)    # Decrement by given value
+        g.set(4.2)   # Set to a given value
+
+     There are utilities for common use cases:
+
+        g.set_to_current_time()   # Set to current unixtime
+
+        # Increment when entered, decrement when exited.
+        @g.track_inprogress()
+        def f():
+            pass
+
+        with g.track_inprogress():
+            pass
+
+     A Gauge can also take its value from a callback:
+
+        d = Gauge('data_objects', 'Number of objects')
+        my_dict = {}
+        d.set_function(lambda: len(my_dict))
+    """
+    _type = 'gauge'
+    _MULTIPROC_MODES = frozenset(('all', 'liveall', 'min', 'livemin', 'max', 'livemax', 'sum', 'livesum', 'mostrecent', 'livemostrecent'))
+    _MOST_RECENT_MODES = frozenset(('mostrecent', 'livemostrecent'))
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 labelnames: Iterable[str] = (),
+                 namespace: str = '',
+                 subsystem: str = '',
+                 unit: str = '',
+                 registry: Optional[CollectorRegistry] = REGISTRY,
+                 _labelvalues: Optional[Sequence[str]] = None,
+                 multiprocess_mode: Literal['all', 'liveall', 'min', 'livemin', 'max', 'livemax', 'sum', 'livesum', 'mostrecent', 'livemostrecent'] = 'all',
+                 ):
+        self._multiprocess_mode = multiprocess_mode
+        if multiprocess_mode not in self._MULTIPROC_MODES:
+            raise ValueError('Invalid multiprocess mode: ' + multiprocess_mode)
+        super().__init__(
+            name=name,
+            documentation=documentation,
+            labelnames=labelnames,
+            namespace=namespace,
+            subsystem=subsystem,
+            unit=unit,
+            registry=registry,
+            _labelvalues=_labelvalues,
+        )
+        self._kwargs['multiprocess_mode'] = self._multiprocess_mode
+        self._is_most_recent = self._multiprocess_mode in self._MOST_RECENT_MODES
+
+    def _metric_init(self) -> None:
+        self._value = values.ValueClass(
+            self._type, self._name, self._name, self._labelnames, self._labelvalues,
+            self._documentation, multiprocess_mode=self._multiprocess_mode
+        )
+
+    def inc(self, amount: float = 1) -> None:
+        """Increment gauge by the given amount."""
+        if self._is_most_recent:
+            raise RuntimeError("inc must not be used with the mostrecent mode")
+        self._raise_if_not_observable()
+        self._value.inc(amount)
+
+    def dec(self, amount: float = 1) -> None:
+        """Decrement gauge by the given amount."""
+        if self._is_most_recent:
+            raise RuntimeError("dec must not be used with the mostrecent mode")
+        self._raise_if_not_observable()
+        self._value.inc(-amount)
+
+    def set(self, value: float) -> None:
+        """Set gauge to the given value."""
+        self._raise_if_not_observable()
+        if self._is_most_recent:
+            self._value.set(float(value), timestamp=time.time())
+        else:
+            self._value.set(float(value))
+
+    def set_to_current_time(self) -> None:
+        """Set gauge to the current unixtime."""
+        self.set(time.time())
+
+    def track_inprogress(self) -> InprogressTracker:
+        """Track inprogress blocks of code or functions.
+
+        Can be used as a function decorator or context manager.
+        Increments the gauge when the code is entered,
+        and decrements when it is exited.
+        """
+        self._raise_if_not_observable()
+        return InprogressTracker(self)
+
+    def time(self) -> Timer:
+        """Time a block of code or function, and set the duration in seconds.
+
+        Can be used as a function decorator or context manager.
+        """
+        return Timer(self, 'set')
+
+    def set_function(self, f: Callable[[], float]) -> None:
+        """Call the provided function to return the Gauge value.
+
+        The function must return a float, and may be called from
+        multiple threads. All other methods of the Gauge become NOOPs.
+        """
+
+        self._raise_if_not_observable()
+
+        def samples(_: Gauge) -> Iterable[Sample]:
+            return (Sample('', {}, float(f()), None, None),)
+
+        self._child_samples = types.MethodType(samples, self)  # type: ignore
+
+    def _child_samples(self) -> Iterable[Sample]:
+        return (Sample('', {}, self._value.get(), None, None),)
+
+
+class Summary(MetricWrapperBase):
+    """A Summary tracks the size and number of events.
+
+    Example use cases for Summaries:
+    - Response latency
+    - Request size
+
+    Example for a Summary:
+
+        from prometheus_client import Summary
+
+        s = Summary('request_size_bytes', 'Request size (bytes)')
+        s.observe(512)  # Observe 512 (bytes)
+
+    Example for a Summary using time:
+
+        from prometheus_client import Summary
+
+        REQUEST_TIME = Summary('response_latency_seconds', 'Response latency (seconds)')
+
+        @REQUEST_TIME.time()
+        def create_response(request):
+          '''A dummy function'''
+          time.sleep(1)
+
+    Example for using the same Summary object as a context manager:
+
+        with REQUEST_TIME.time():
+            pass  # Logic to be timed
+    """
+    _type = 'summary'
+    _reserved_labelnames = ['quantile']
+
+    def _metric_init(self) -> None:
+        self._count = values.ValueClass(self._type, self._name, self._name + '_count', self._labelnames,
+                                        self._labelvalues, self._documentation)
+        self._sum = values.ValueClass(self._type, self._name, self._name + '_sum', self._labelnames, self._labelvalues, self._documentation)
+        self._created = time.time()
+
+    def observe(self, amount: float) -> None:
+        """Observe the given amount.
+
+        The amount is usually positive or zero. Negative values are
+        accepted but prevent current versions of Prometheus from
+        properly detecting counter resets in the sum of
+        observations. See
+        https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
+        for details.
+        """
+        self._raise_if_not_observable()
+        self._count.inc(1)
+        self._sum.inc(amount)
+
+    def time(self) -> Timer:
+        """Time a block of code or function, and observe the duration in seconds.
+
+        Can be used as a function decorator or context manager.
+        """
+        return Timer(self, 'observe')
+
+    def _child_samples(self) -> Iterable[Sample]:
+        samples = [
+            Sample('_count', {}, self._count.get(), None, None),
+            Sample('_sum', {}, self._sum.get(), None, None),
+        ]
+        if _use_created:
+            samples.append(Sample('_created', {}, self._created, None, None))
+        return tuple(samples)
+
+
+class Histogram(MetricWrapperBase):
+    """A Histogram tracks the size and number of events in buckets.
+
+    You can use Histograms for aggregatable calculation of quantiles.
+
+    Example use cases:
+    - Response latency
+    - Request size
+
+    Example for a Histogram:
+
+        from prometheus_client import Histogram
+
+        h = Histogram('request_size_bytes', 'Request size (bytes)')
+        h.observe(512)  # Observe 512 (bytes)
+
+    Example for a Histogram using time:
+
+        from prometheus_client import Histogram
+
+        REQUEST_TIME = Histogram('response_latency_seconds', 'Response latency (seconds)')
+
+        @REQUEST_TIME.time()
+        def create_response(request):
+          '''A dummy function'''
+          time.sleep(1)
+
+    Example of using the same Histogram object as a context manager:
+
+        with REQUEST_TIME.time():
+            pass  # Logic to be timed
+
+    The default buckets are intended to cover a typical web/rpc request from milliseconds to seconds.
+    They can be overridden by passing `buckets` keyword argument to `Histogram`.
+    """
+    _type = 'histogram'
+    _reserved_labelnames = ['le']
+    DEFAULT_BUCKETS = (.005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, 2.5, 5.0, 7.5, 10.0, INF)
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 labelnames: Iterable[str] = (),
+                 namespace: str = '',
+                 subsystem: str = '',
+                 unit: str = '',
+                 registry: Optional[CollectorRegistry] = REGISTRY,
+                 _labelvalues: Optional[Sequence[str]] = None,
+                 buckets: Sequence[Union[float, str]] = DEFAULT_BUCKETS,
+                 ):
+        self._prepare_buckets(buckets)
+        super().__init__(
+            name=name,
+            documentation=documentation,
+            labelnames=labelnames,
+            namespace=namespace,
+            subsystem=subsystem,
+            unit=unit,
+            registry=registry,
+            _labelvalues=_labelvalues,
+        )
+        self._kwargs['buckets'] = buckets
+
+    def _prepare_buckets(self, source_buckets: Sequence[Union[float, str]]) -> None:
+        buckets = [float(b) for b in source_buckets]
+        if buckets != sorted(buckets):
+            # This is probably an error on the part of the user,
+            # so raise rather than sorting for them.
+            raise ValueError('Buckets not in sorted order')
+        if buckets and buckets[-1] != INF:
+            buckets.append(INF)
+        if len(buckets) < 2:
+            raise ValueError('Must have at least two buckets')
+        self._upper_bounds = buckets
+
+    def _metric_init(self) -> None:
+        self._buckets: List[values.ValueClass] = []
+        self._created = time.time()
+        bucket_labelnames = self._labelnames + ('le',)
+        self._sum = values.ValueClass(self._type, self._name, self._name + '_sum', self._labelnames, self._labelvalues, self._documentation)
+        for b in self._upper_bounds:
+            self._buckets.append(values.ValueClass(
+                self._type,
+                self._name,
+                self._name + '_bucket',
+                bucket_labelnames,
+                self._labelvalues + (floatToGoString(b),),
+                self._documentation)
+            )
+
+    def observe(self, amount: float, exemplar: Optional[Dict[str, str]] = None) -> None:
+        """Observe the given amount.
+
+        The amount is usually positive or zero. Negative values are
+        accepted but prevent current versions of Prometheus from
+        properly detecting counter resets in the sum of
+        observations. See
+        https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
+        for details.
+        """
+        self._raise_if_not_observable()
+        self._sum.inc(amount)
+        for i, bound in enumerate(self._upper_bounds):
+            if amount <= bound:
+                self._buckets[i].inc(1)
+                if exemplar:
+                    _validate_exemplar(exemplar)
+                    self._buckets[i].set_exemplar(Exemplar(exemplar, amount, time.time()))
+                break
+
+    def time(self) -> Timer:
+        """Time a block of code or function, and observe the duration in seconds.
+
+        Can be used as a function decorator or context manager.
+        """
+        return Timer(self, 'observe')
+
+    def _child_samples(self) -> Iterable[Sample]:
+        samples = []
+        acc = 0.0
+        for i, bound in enumerate(self._upper_bounds):
+            acc += self._buckets[i].get()
+            samples.append(Sample('_bucket', {'le': floatToGoString(bound)}, acc, None, self._buckets[i].get_exemplar()))
+        samples.append(Sample('_count', {}, acc, None, None))
+        if self._upper_bounds[0] >= 0:
+            samples.append(Sample('_sum', {}, self._sum.get(), None, None))
+        if _use_created:
+            samples.append(Sample('_created', {}, self._created, None, None))
+        return tuple(samples)
+
+
+class Info(MetricWrapperBase):
+    """Info metric, key-value pairs.
+
+     Examples of Info include:
+        - Build information
+        - Version information
+        - Potential target metadata
+
+     Example usage:
+        from prometheus_client import Info
+
+        i = Info('my_build', 'Description of info')
+        i.info({'version': '1.2.3', 'buildhost': 'foo@bar'})
+
+     Info metrics do not work in multiprocess mode.
+    """
+    _type = 'info'
+
+    def _metric_init(self):
+        self._labelname_set = set(self._labelnames)
+        self._lock = Lock()
+        self._value = {}
+
+    def info(self, val: Dict[str, str]) -> None:
+        """Set info metric."""
+        if self._labelname_set.intersection(val.keys()):
+            raise ValueError('Overlapping labels for Info metric, metric: {} child: {}'.format(
+                self._labelnames, val))
+        if any(i is None for i in val.values()):
+            raise ValueError('Label value cannot be None')
+        with self._lock:
+            self._value = dict(val)
+
+    def _child_samples(self) -> Iterable[Sample]:
+        with self._lock:
+            return (Sample('_info', self._value, 1.0, None, None),)
+
+
+class Enum(MetricWrapperBase):
+    """Enum metric, which of a set of states is true.
+
+     Example usage:
+        from prometheus_client import Enum
+
+        e = Enum('task_state', 'Description of enum',
+          states=['starting', 'running', 'stopped'])
+        e.state('running')
+
+     The first listed state will be the default.
+     Enum metrics do not work in multiprocess mode.
+    """
+    _type = 'stateset'
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 labelnames: Sequence[str] = (),
+                 namespace: str = '',
+                 subsystem: str = '',
+                 unit: str = '',
+                 registry: Optional[CollectorRegistry] = REGISTRY,
+                 _labelvalues: Optional[Sequence[str]] = None,
+                 states: Optional[Sequence[str]] = None,
+                 ):
+        if name in labelnames:
+            raise ValueError(f'Overlapping labels for Enum metric: {name}')
+        if not states:
+            raise ValueError(f'No states provided for Enum metric: {name}')
+        super().__init__(
+            name=name,
+            documentation=documentation,
+            labelnames=labelnames,
+            namespace=namespace,
+            subsystem=subsystem,
+            unit=unit,
+            registry=registry,
+            _labelvalues=_labelvalues,
+        )
+        self._kwargs['states'] = self._states = states
+
+    def _metric_init(self) -> None:
+        self._value = 0
+        self._lock = Lock()
+
+    def state(self, state: str) -> None:
+        """Set enum metric state."""
+        self._raise_if_not_observable()
+        with self._lock:
+            self._value = self._states.index(state)
+
+    def _child_samples(self) -> Iterable[Sample]:
+        with self._lock:
+            return [
+                Sample('', {self._name: s}, 1 if i == self._value else 0, None, None)
+                for i, s
+                in enumerate(self._states)
+            ]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py
new file mode 100644
index 00000000000..27d1712ddaa
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py
@@ -0,0 +1,415 @@
+from typing import Dict, List, Optional, Sequence, Tuple, Union
+
+from .samples import Exemplar, NativeHistogram, Sample, Timestamp
+from .validation import _validate_metric_name
+
+METRIC_TYPES = (
+    'counter', 'gauge', 'summary', 'histogram',
+    'gaugehistogram', 'unknown', 'info', 'stateset',
+)
+
+
+class Metric:
+    """A single metric family and its samples.
+
+    This is intended only for internal use by the instrumentation client.
+
+    Custom collectors should use GaugeMetricFamily, CounterMetricFamily
+    and SummaryMetricFamily instead.
+    """
+
+    def __init__(self, name: str, documentation: str, typ: str, unit: str = ''):
+        if unit and not name.endswith("_" + unit):
+            name += "_" + unit
+        _validate_metric_name(name)
+        self.name: str = name
+        self.documentation: str = documentation
+        self.unit: str = unit
+        if typ == 'untyped':
+            typ = 'unknown'
+        if typ not in METRIC_TYPES:
+            raise ValueError('Invalid metric type: ' + typ)
+        self.type: str = typ
+        self.samples: List[Sample] = []
+
+    def add_sample(self, name: str, labels: Dict[str, str], value: float, timestamp: Optional[Union[Timestamp, float]] = None, exemplar: Optional[Exemplar] = None, native_histogram: Optional[NativeHistogram] = None) -> None:
+        """Add a sample to the metric.
+
+        Internal-only, do not use."""
+        self.samples.append(Sample(name, labels, value, timestamp, exemplar, native_histogram))
+
+    def __eq__(self, other: object) -> bool:
+        return (isinstance(other, Metric)
+                and self.name == other.name
+                and self.documentation == other.documentation
+                and self.type == other.type
+                and self.unit == other.unit
+                and self.samples == other.samples)
+
+    def __repr__(self) -> str:
+        return "Metric({}, {}, {}, {}, {})".format(
+            self.name,
+            self.documentation,
+            self.type,
+            self.unit,
+            self.samples,
+        )
+
+    def _restricted_metric(self, names):
+        """Build a snapshot of a metric with samples restricted to a given set of names."""
+        samples = [s for s in self.samples if s[0] in names]
+        if samples:
+            m = Metric(self.name, self.documentation, self.type)
+            m.samples = samples
+            return m
+        return None
+
+
+class UnknownMetricFamily(Metric):
+    """A single unknown metric and its samples.
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 value: Optional[float] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 unit: str = '',
+                 ):
+        Metric.__init__(self, name, documentation, 'unknown', unit)
+        if labels is not None and value is not None:
+            raise ValueError('Can only specify at most one of value and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        if value is not None:
+            self.add_metric([], value)
+
+    def add_metric(self, labels: Sequence[str], value: float, timestamp: Optional[Union[Timestamp, float]] = None) -> None:
+        """Add a metric to the metric family.
+        Args:
+        labels: A list of label values
+        value: The value of the metric.
+        """
+        self.samples.append(Sample(self.name, dict(zip(self._labelnames, labels)), value, timestamp))
+
+
+# For backward compatibility.
+UntypedMetricFamily = UnknownMetricFamily
+
+
+class CounterMetricFamily(Metric):
+    """A single counter and its samples.
+
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 value: Optional[float] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 created: Optional[float] = None,
+                 unit: str = '',
+                 exemplar: Optional[Exemplar] = None,
+                 ):
+        # Glue code for pre-OpenMetrics metrics.
+        if name.endswith('_total'):
+            name = name[:-6]
+        Metric.__init__(self, name, documentation, 'counter', unit)
+        if labels is not None and value is not None:
+            raise ValueError('Can only specify at most one of value and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        if value is not None:
+            self.add_metric([], value, created, exemplar=exemplar)
+
+    def add_metric(self,
+                   labels: Sequence[str],
+                   value: float,
+                   created: Optional[float] = None,
+                   timestamp: Optional[Union[Timestamp, float]] = None,
+                   exemplar: Optional[Exemplar] = None,
+                   ) -> None:
+        """Add a metric to the metric family.
+
+        Args:
+          labels: A list of label values
+          value: The value of the metric
+          created: Optional unix timestamp the child was created at.
+        """
+        self.samples.append(Sample(self.name + '_total', dict(zip(self._labelnames, labels)), value, timestamp, exemplar))
+        if created is not None:
+            self.samples.append(Sample(self.name + '_created', dict(zip(self._labelnames, labels)), created, timestamp))
+
+
+class GaugeMetricFamily(Metric):
+    """A single gauge and its samples.
+
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 value: Optional[float] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 unit: str = '',
+                 ):
+        Metric.__init__(self, name, documentation, 'gauge', unit)
+        if labels is not None and value is not None:
+            raise ValueError('Can only specify at most one of value and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        if value is not None:
+            self.add_metric([], value)
+
+    def add_metric(self, labels: Sequence[str], value: float, timestamp: Optional[Union[Timestamp, float]] = None) -> None:
+        """Add a metric to the metric family.
+
+        Args:
+          labels: A list of label values
+          value: A float
+        """
+        self.samples.append(Sample(self.name, dict(zip(self._labelnames, labels)), value, timestamp))
+
+
+class SummaryMetricFamily(Metric):
+    """A single summary and its samples.
+
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 count_value: Optional[int] = None,
+                 sum_value: Optional[float] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 unit: str = '',
+                 ):
+        Metric.__init__(self, name, documentation, 'summary', unit)
+        if (sum_value is None) != (count_value is None):
+            raise ValueError('count_value and sum_value must be provided together.')
+        if labels is not None and count_value is not None:
+            raise ValueError('Can only specify at most one of value and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        # The and clause is necessary only for typing, the above ValueError will raise if only one is set.
+        if count_value is not None and sum_value is not None:
+            self.add_metric([], count_value, sum_value)
+
+    def add_metric(self,
+                   labels: Sequence[str],
+                   count_value: int,
+                   sum_value: float,
+                   timestamp:
+                   Optional[Union[float, Timestamp]] = None
+                   ) -> None:
+        """Add a metric to the metric family.
+
+        Args:
+          labels: A list of label values
+          count_value: The count value of the metric.
+          sum_value: The sum value of the metric.
+        """
+        self.samples.append(Sample(self.name + '_count', dict(zip(self._labelnames, labels)), count_value, timestamp))
+        self.samples.append(Sample(self.name + '_sum', dict(zip(self._labelnames, labels)), sum_value, timestamp))
+
+
+class HistogramMetricFamily(Metric):
+    """A single histogram and its samples.
+
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 buckets: Optional[Sequence[Union[Tuple[str, float], Tuple[str, float, Exemplar]]]] = None,
+                 sum_value: Optional[float] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 unit: str = '',
+                 ):
+        Metric.__init__(self, name, documentation, 'histogram', unit)
+        if sum_value is not None and buckets is None:
+            raise ValueError('sum value cannot be provided without buckets.')
+        if labels is not None and buckets is not None:
+            raise ValueError('Can only specify at most one of buckets and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        if buckets is not None:
+            self.add_metric([], buckets, sum_value)
+
+    def add_metric(self,
+                   labels: Sequence[str],
+                   buckets: Sequence[Union[Tuple[str, float], Tuple[str, float, Exemplar]]],
+                   sum_value: Optional[float],
+                   timestamp: Optional[Union[Timestamp, float]] = None) -> None:
+        """Add a metric to the metric family.
+
+        Args:
+          labels: A list of label values
+          buckets: A list of lists.
+              Each inner list can be a pair of bucket name and value,
+              or a triple of bucket name, value, and exemplar.
+              The buckets must be sorted, and +Inf present.
+          sum_value: The sum value of the metric.
+        """
+        for b in buckets:
+            bucket, value = b[:2]
+            exemplar = None
+            if len(b) == 3:
+                exemplar = b[2]  # type: ignore
+            self.samples.append(Sample(
+                self.name + '_bucket',
+                dict(list(zip(self._labelnames, labels)) + [('le', bucket)]),
+                value,
+                timestamp,
+                exemplar,
+            ))
+        # Don't include sum and thus count if there's negative buckets.
+        if float(buckets[0][0]) >= 0 and sum_value is not None:
+            # +Inf is last and provides the count value.
+            self.samples.append(
+                Sample(self.name + '_count', dict(zip(self._labelnames, labels)), buckets[-1][1], timestamp))
+            self.samples.append(
+                Sample(self.name + '_sum', dict(zip(self._labelnames, labels)), sum_value, timestamp))
+
+
+class GaugeHistogramMetricFamily(Metric):
+    """A single gauge histogram and its samples.
+
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 buckets: Optional[Sequence[Tuple[str, float]]] = None,
+                 gsum_value: Optional[float] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 unit: str = '',
+                 ):
+        Metric.__init__(self, name, documentation, 'gaugehistogram', unit)
+        if labels is not None and buckets is not None:
+            raise ValueError('Can only specify at most one of buckets and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        if buckets is not None:
+            self.add_metric([], buckets, gsum_value)
+
+    def add_metric(self,
+                   labels: Sequence[str],
+                   buckets: Sequence[Tuple[str, float]],
+                   gsum_value: Optional[float],
+                   timestamp: Optional[Union[float, Timestamp]] = None,
+                   ) -> None:
+        """Add a metric to the metric family.
+
+        Args:
+          labels: A list of label values
+          buckets: A list of pairs of bucket names and values.
+              The buckets must be sorted, and +Inf present.
+          gsum_value: The sum value of the metric.
+        """
+        for bucket, value in buckets:
+            self.samples.append(Sample(
+                self.name + '_bucket',
+                dict(list(zip(self._labelnames, labels)) + [('le', bucket)]),
+                value, timestamp))
+        # +Inf is last and provides the count value.
+        self.samples.extend([
+            Sample(self.name + '_gcount', dict(zip(self._labelnames, labels)), buckets[-1][1], timestamp),
+            # TODO: Handle None gsum_value correctly. Currently a None will fail exposition but is allowed here.
+            Sample(self.name + '_gsum', dict(zip(self._labelnames, labels)), gsum_value, timestamp),  # type: ignore
+        ])
+
+
+class InfoMetricFamily(Metric):
+    """A single info and its samples.
+
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 value: Optional[Dict[str, str]] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 ):
+        Metric.__init__(self, name, documentation, 'info')
+        if labels is not None and value is not None:
+            raise ValueError('Can only specify at most one of value and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        if value is not None:
+            self.add_metric([], value)
+
+    def add_metric(self,
+                   labels: Sequence[str],
+                   value: Dict[str, str],
+                   timestamp: Optional[Union[Timestamp, float]] = None,
+                   ) -> None:
+        """Add a metric to the metric family.
+
+        Args:
+          labels: A list of label values
+          value: A dict of labels
+        """
+        self.samples.append(Sample(
+            self.name + '_info',
+            dict(dict(zip(self._labelnames, labels)), **value),
+            1,
+            timestamp,
+        ))
+
+
+class StateSetMetricFamily(Metric):
+    """A single stateset and its samples.
+
+    For use by custom collectors.
+    """
+
+    def __init__(self,
+                 name: str,
+                 documentation: str,
+                 value: Optional[Dict[str, bool]] = None,
+                 labels: Optional[Sequence[str]] = None,
+                 ):
+        Metric.__init__(self, name, documentation, 'stateset')
+        if labels is not None and value is not None:
+            raise ValueError('Can only specify at most one of value and labels.')
+        if labels is None:
+            labels = []
+        self._labelnames = tuple(labels)
+        if value is not None:
+            self.add_metric([], value)
+
+    def add_metric(self,
+                   labels: Sequence[str],
+                   value: Dict[str, bool],
+                   timestamp: Optional[Union[Timestamp, float]] = None,
+                   ) -> None:
+        """Add a metric to the metric family.
+
+        Args:
+          labels: A list of label values
+          value: A dict of string state names to booleans
+        """
+        labels = tuple(labels)
+        for state, enabled in sorted(value.items()):
+            v = (1 if enabled else 0)
+            self.samples.append(Sample(
+                self.name,
+                dict(zip(self._labelnames + (self.name,), labels + (state,))),
+                v,
+                timestamp,
+            ))
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py
new file mode 100644
index 00000000000..edd895cda9d
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py
@@ -0,0 +1,145 @@
+import json
+import mmap
+import os
+import struct
+from typing import List
+
+_INITIAL_MMAP_SIZE = 1 << 16
+_pack_integer_func = struct.Struct(b'i').pack
+_pack_two_doubles_func = struct.Struct(b'dd').pack
+_unpack_integer = struct.Struct(b'i').unpack_from
+_unpack_two_doubles = struct.Struct(b'dd').unpack_from
+
+
+# struct.pack_into has atomicity issues because it will temporarily write 0 into
+# the mmap, resulting in false reads to 0 when experiencing a lot of writes.
+# Using direct assignment solves this issue.
+
+
+def _pack_two_doubles(data, pos, value, timestamp):
+    data[pos:pos + 16] = _pack_two_doubles_func(value, timestamp)
+
+
+def _pack_integer(data, pos, value):
+    data[pos:pos + 4] = _pack_integer_func(value)
+
+
+def _read_all_values(data, used=0):
+    """Yield (key, value, timestamp, pos). No locking is performed."""
+
+    if used <= 0:
+        # If not valid `used` value is passed in, read it from the file.
+        used = _unpack_integer(data, 0)[0]
+
+    pos = 8
+
+    while pos < used:
+        encoded_len = _unpack_integer(data, pos)[0]
+        # check we are not reading beyond bounds
+        if encoded_len + pos > used:
+            raise RuntimeError('Read beyond file size detected, file is corrupted.')
+        pos += 4
+        encoded_key = data[pos:pos + encoded_len]
+        padded_len = encoded_len + (8 - (encoded_len + 4) % 8)
+        pos += padded_len
+        value, timestamp = _unpack_two_doubles(data, pos)
+        yield encoded_key.decode('utf-8'), value, timestamp, pos
+        pos += 16
+
+
+class MmapedDict:
+    """A dict of doubles, backed by an mmapped file.
+
+    The file starts with a 4 byte int, indicating how much of it is used.
+    Then 4 bytes of padding.
+    There's then a number of entries, consisting of a 4 byte int which is the
+    size of the next field, a utf-8 encoded string key, padding to a 8 byte
+    alignment, and then a 8 byte float which is the value and a 8 byte float
+    which is a UNIX timestamp in seconds.
+
+    Not thread safe.
+    """
+
+    def __init__(self, filename, read_mode=False):
+        self._f = open(filename, 'rb' if read_mode else 'a+b')
+        self._fname = filename
+        capacity = os.fstat(self._f.fileno()).st_size
+        if capacity == 0:
+            self._f.truncate(_INITIAL_MMAP_SIZE)
+            capacity = _INITIAL_MMAP_SIZE
+        self._capacity = capacity
+        self._m = mmap.mmap(self._f.fileno(), self._capacity,
+                            access=mmap.ACCESS_READ if read_mode else mmap.ACCESS_WRITE)
+
+        self._positions = {}
+        self._used = _unpack_integer(self._m, 0)[0]
+        if self._used == 0:
+            self._used = 8
+            _pack_integer(self._m, 0, self._used)
+        else:
+            if not read_mode:
+                for key, _, _, pos in self._read_all_values():
+                    self._positions[key] = pos
+
+    @staticmethod
+    def read_all_values_from_file(filename):
+        with open(filename, 'rb') as infp:
+            # Read the first block of data, including the first 4 bytes which tell us
+            # how much of the file (which is preallocated to _INITIAL_MMAP_SIZE bytes) is occupied.
+            data = infp.read(mmap.PAGESIZE)
+            used = _unpack_integer(data, 0)[0]
+            if used > len(data):  # Then read in the rest, if needed.
+                data += infp.read(used - len(data))
+        return _read_all_values(data, used)
+
+    def _init_value(self, key):
+        """Initialize a value. Lock must be held by caller."""
+        encoded = key.encode('utf-8')
+        # Pad to be 8-byte aligned.
+        padded = encoded + (b' ' * (8 - (len(encoded) + 4) % 8))
+        value = struct.pack(f'i{len(padded)}sdd'.encode(), len(encoded), padded, 0.0, 0.0)
+        while self._used + len(value) > self._capacity:
+            self._capacity *= 2
+            self._f.truncate(self._capacity)
+            self._m = mmap.mmap(self._f.fileno(), self._capacity)
+        self._m[self._used:self._used + len(value)] = value
+
+        # Update how much space we've used.
+        self._used += len(value)
+        _pack_integer(self._m, 0, self._used)
+        self._positions[key] = self._used - 16
+
+    def _read_all_values(self):
+        """Yield (key, value, pos). No locking is performed."""
+        return _read_all_values(data=self._m, used=self._used)
+
+    def read_all_values(self):
+        """Yield (key, value, timestamp). No locking is performed."""
+        for k, v, ts, _ in self._read_all_values():
+            yield k, v, ts
+
+    def read_value(self, key):
+        if key not in self._positions:
+            self._init_value(key)
+        pos = self._positions[key]
+        return _unpack_two_doubles(self._m, pos)
+
+    def write_value(self, key, value, timestamp):
+        if key not in self._positions:
+            self._init_value(key)
+        pos = self._positions[key]
+        _pack_two_doubles(self._m, pos, value, timestamp)
+
+    def close(self):
+        if self._f:
+            self._m.close()
+            self._m = None
+            self._f.close()
+            self._f = None
+
+
+def mmap_key(metric_name: str, name: str, labelnames: List[str], labelvalues: List[str], help_text: str) -> str:
+    """Format a key for use in the mmap file."""
+    # ensure labels are in consistent order for identity
+    labels = dict(zip(labelnames, labelvalues))
+    return json.dumps([metric_name, name, labels, help_text], sort_keys=True)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py
new file mode 100644
index 00000000000..db55874e0b8
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py
@@ -0,0 +1,183 @@
+from collections import defaultdict
+import glob
+import json
+import os
+import warnings
+
+from .metrics import Gauge
+from .metrics_core import Metric
+from .mmap_dict import MmapedDict
+from .samples import Sample
+from .utils import floatToGoString
+
+try:  # Python3
+    FileNotFoundError
+except NameError:  # Python >= 2.5
+    FileNotFoundError = IOError
+
+
+class MultiProcessCollector:
+    """Collector for files for multi-process mode."""
+
+    def __init__(self, registry, path=None):
+        if path is None:
+            # This deprecation warning can go away in a few releases when removing the compatibility
+            if 'prometheus_multiproc_dir' in os.environ and 'PROMETHEUS_MULTIPROC_DIR' not in os.environ:
+                os.environ['PROMETHEUS_MULTIPROC_DIR'] = os.environ['prometheus_multiproc_dir']
+                warnings.warn("prometheus_multiproc_dir variable has been deprecated in favor of the upper case naming PROMETHEUS_MULTIPROC_DIR", DeprecationWarning)
+            path = os.environ.get('PROMETHEUS_MULTIPROC_DIR')
+        if not path or not os.path.isdir(path):
+            raise ValueError('env PROMETHEUS_MULTIPROC_DIR is not set or not a directory')
+        self._path = path
+        if registry:
+            registry.register(self)
+
+    @staticmethod
+    def merge(files, accumulate=True):
+        """Merge metrics from given mmap files.
+
+        By default, histograms are accumulated, as per prometheus wire format.
+        But if writing the merged data back to mmap files, use
+        accumulate=False to avoid compound accumulation.
+        """
+        metrics = MultiProcessCollector._read_metrics(files)
+        return MultiProcessCollector._accumulate_metrics(metrics, accumulate)
+
+    @staticmethod
+    def _read_metrics(files):
+        metrics = {}
+        key_cache = {}
+
+        def _parse_key(key):
+            val = key_cache.get(key)
+            if not val:
+                metric_name, name, labels, help_text = json.loads(key)
+                labels_key = tuple(sorted(labels.items()))
+                val = key_cache[key] = (metric_name, name, labels, labels_key, help_text)
+            return val
+
+        for f in files:
+            parts = os.path.basename(f).split('_')
+            typ = parts[0]
+            try:
+                file_values = MmapedDict.read_all_values_from_file(f)
+            except FileNotFoundError:
+                if typ == 'gauge' and parts[1].startswith('live'):
+                    # Files for 'live*' gauges can be deleted between the glob of collect
+                    # and now (via a mark_process_dead call) so don't fail if
+                    # the file is missing
+                    continue
+                raise
+            for key, value, timestamp, _ in file_values:
+                metric_name, name, labels, labels_key, help_text = _parse_key(key)
+
+                metric = metrics.get(metric_name)
+                if metric is None:
+                    metric = Metric(metric_name, help_text, typ)
+                    metrics[metric_name] = metric
+
+                if typ == 'gauge':
+                    pid = parts[2][:-3]
+                    metric._multiprocess_mode = parts[1]
+                    metric.add_sample(name, labels_key + (('pid', pid),), value, timestamp)
+                else:
+                    # The duplicates and labels are fixed in the next for.
+                    metric.add_sample(name, labels_key, value)
+        return metrics
+
+    @staticmethod
+    def _accumulate_metrics(metrics, accumulate):
+        for metric in metrics.values():
+            samples = defaultdict(lambda: defaultdict(float))
+            sample_timestamps = defaultdict(lambda: defaultdict(float))
+            buckets = defaultdict(lambda: defaultdict(float))
+            for s in metric.samples:
+                name, labels, value, timestamp, exemplar, native_histogram_value = s
+
+                if (
+                    metric.type == 'gauge'
+                    and metric._multiprocess_mode in (
+                        'min', 'livemin',
+                        'max', 'livemax',
+                        'sum', 'livesum',
+                        'mostrecent', 'livemostrecent',
+                    )
+                ):
+                    labels = tuple(l for l in labels if l[0] != 'pid')
+
+                if metric.type == 'gauge':
+                    if metric._multiprocess_mode in ('min', 'livemin'):
+                        current = samples[labels].setdefault((name, labels), value)
+                        if value < current:
+                            samples[labels][(name, labels)] = value
+                    elif metric._multiprocess_mode in ('max', 'livemax'):
+                        current = samples[labels].setdefault((name, labels), value)
+                        if value > current:
+                            samples[labels][(name, labels)] = value
+                    elif metric._multiprocess_mode in ('sum', 'livesum'):
+                        samples[labels][(name, labels)] += value
+                    elif metric._multiprocess_mode in ('mostrecent', 'livemostrecent'):
+                        current_timestamp = sample_timestamps[labels][name]
+                        timestamp = float(timestamp or 0)
+                        if current_timestamp < timestamp:
+                            samples[labels][(name, labels)] = value
+                            sample_timestamps[labels][name] = timestamp
+                    else:  # all/liveall
+                        samples[labels][(name, labels)] = value
+
+                elif metric.type == 'histogram':
+                    # A for loop with early exit is faster than a genexpr
+                    # or a listcomp that ends up building unnecessary things
+                    for l in labels:
+                        if l[0] == 'le':
+                            bucket_value = float(l[1])
+                            # _bucket
+                            without_le = tuple(l for l in labels if l[0] != 'le')
+                            buckets[without_le][bucket_value] += value
+                            break
+                    else:  # did not find the `le` key
+                        # _sum/_count
+                        samples[labels][(name, labels)] += value
+                else:
+                    # Counter and Summary.
+                    samples[labels][(name, labels)] += value
+
+            # Accumulate bucket values.
+            if metric.type == 'histogram':
+                for labels, values in buckets.items():
+                    acc = 0.0
+                    for bucket, value in sorted(values.items()):
+                        sample_key = (
+                            metric.name + '_bucket',
+                            labels + (('le', floatToGoString(bucket)),),
+                        )
+                        if accumulate:
+                            acc += value
+                            samples[labels][sample_key] = acc
+                        else:
+                            samples[labels][sample_key] = value
+                    if accumulate:
+                        samples[labels][(metric.name + '_count', labels)] = acc
+
+            # Convert to correct sample format.
+            metric.samples = []
+            for _, samples_by_labels in samples.items():
+                for (name_, labels), value in samples_by_labels.items():
+                    metric.samples.append(Sample(name_, dict(labels), value))
+        return metrics.values()
+
+    def collect(self):
+        files = glob.glob(os.path.join(self._path, '*.db'))
+        return self.merge(files, accumulate=True)
+
+
+_LIVE_GAUGE_MULTIPROCESS_MODES = {m for m in Gauge._MULTIPROC_MODES if m.startswith('live')}
+
+
+def mark_process_dead(pid, path=None):
+    """Do bookkeeping for when one process dies in a multi-process setup."""
+    if path is None:
+        path = os.environ.get('PROMETHEUS_MULTIPROC_DIR', os.environ.get('prometheus_multiproc_dir'))
+    for mode in _LIVE_GAUGE_MULTIPROCESS_MODES:
+        for f in glob.glob(os.path.join(path, f'gauge_{mode}_{pid}.db')):
+            os.remove(f)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py
new file mode 100644
index 00000000000..5a7711b027b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python
+
+from io import StringIO
+from sys import maxunicode
+from typing import Callable
+
+from ..utils import floatToGoString, parse_version
+from ..validation import (
+    _is_valid_legacy_labelname, _is_valid_legacy_metric_name,
+)
+
+CONTENT_TYPE_LATEST = 'application/openmetrics-text; version=1.0.0; charset=utf-8'
+"""Content type of the latest OpenMetrics 1.0 text format"""
+CONTENT_TYPE_LATEST_2_0 = 'application/openmetrics-text; version=2.0.0; charset=utf-8'
+"""Content type of the OpenMetrics 2.0 text format"""
+ESCAPING_HEADER_TAG = 'escaping'
+
+
+ALLOWUTF8 = 'allow-utf-8'
+UNDERSCORES = 'underscores'
+DOTS = 'dots'
+VALUES = 'values'
+
+
+def _is_valid_exemplar_metric(metric, sample):
+    if metric.type == 'counter' and sample.name.endswith('_total'):
+        return True
+    if metric.type == 'gaugehistogram' and sample.name.endswith('_bucket'):
+        return True
+    if metric.type == 'histogram' and (sample.name.endswith('_bucket') or sample.name == metric.name):
+        return True
+    return False
+
+
+def _compose_exemplar_string(metric, sample, exemplar):
+    """Constructs an exemplar string."""
+    if not _is_valid_exemplar_metric(metric, sample):
+        raise ValueError(f"Metric {metric.name} has exemplars, but is not a histogram bucket or counter")
+    labels = '{{{0}}}'.format(','.join(
+        ['{}="{}"'.format(
+            k, v.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"'))
+            for k, v in sorted(exemplar.labels.items())]))
+    if exemplar.timestamp is not None:
+        exemplarstr = ' # {} {} {}'.format(
+            labels,
+            floatToGoString(exemplar.value),
+            exemplar.timestamp,
+        )
+    else:
+        exemplarstr = ' # {} {}'.format(
+            labels,
+            floatToGoString(exemplar.value),
+        )
+
+    return exemplarstr
+
+
+def generate_latest(registry, escaping=UNDERSCORES, version="1.0.0"):
+    '''Returns the metrics from the registry in latest text format as a string.'''
+    output = []
+    for metric in registry.collect():
+        try:
+            mname = metric.name
+            output.append('# HELP {} {}\n'.format(
+                escape_metric_name(mname, escaping), _escape(metric.documentation, ALLOWUTF8, _is_legacy_labelname_rune)))
+            output.append(f'# TYPE {escape_metric_name(mname, escaping)} {metric.type}\n')
+            if metric.unit:
+                output.append(f'# UNIT {escape_metric_name(mname, escaping)} {metric.unit}\n')
+            for s in metric.samples:
+                if escaping == ALLOWUTF8 and not _is_valid_legacy_metric_name(s.name):
+                    labelstr = escape_metric_name(s.name, escaping)
+                    if s.labels:
+                        labelstr += ','
+                else:
+                    labelstr = ''
+
+                if s.labels:
+                    items = sorted(s.labels.items())
+                    # Label values always support UTF-8
+                    labelstr += ','.join(
+                        ['{}="{}"'.format(
+                            escape_label_name(k, escaping), _escape(v, ALLOWUTF8, _is_legacy_labelname_rune))
+                            for k, v in items])
+                if labelstr:
+                    labelstr = "{" + labelstr + "}"
+                if s.exemplar:
+                    exemplarstr = _compose_exemplar_string(metric, s, s.exemplar)
+                else:
+                    exemplarstr = ''
+                timestamp = ''
+                if s.timestamp is not None:
+                    timestamp = f' {s.timestamp}'
+                
+                # Skip native histogram samples entirely if version < 2.0.0
+                if s.native_histogram and parse_version(version) < (2, 0, 0):
+                    continue
+                
+                native_histogram = ''
+                negative_spans = ''
+                negative_deltas = ''
+                positive_spans = ''
+                positive_deltas = ''
+                     
+                if s.native_histogram:
+                    # Initialize basic nh template
+                    nh_sample_template = '{{count:{},sum:{},schema:{},zero_threshold:{},zero_count:{}'
+
+                    args = [
+                        s.native_histogram.count_value,
+                        s.native_histogram.sum_value,
+                        s.native_histogram.schema,
+                        s.native_histogram.zero_threshold,
+                        s.native_histogram.zero_count,
+                    ]
+                  
+                    # If there are neg spans, append them and the neg deltas to the template and args
+                    if s.native_histogram.neg_spans:
+                        negative_spans = ','.join([f'{ns[0]}:{ns[1]}' for ns in s.native_histogram.neg_spans])
+                        negative_deltas = ','.join(str(nd) for nd in s.native_histogram.neg_deltas)
+                        nh_sample_template += ',negative_spans:[{}]'
+                        args.append(negative_spans)
+                        nh_sample_template += ',negative_deltas:[{}]'
+                        args.append(negative_deltas)
+
+                    # If there are pos spans, append them and the pos spans to the template and args
+                    if s.native_histogram.pos_spans:
+                        positive_spans = ','.join([f'{ps[0]}:{ps[1]}' for ps in s.native_histogram.pos_spans])
+                        positive_deltas = ','.join(f'{pd}' for pd in s.native_histogram.pos_deltas)
+                        nh_sample_template += ',positive_spans:[{}]'
+                        args.append(positive_spans)
+                        nh_sample_template += ',positive_deltas:[{}]'
+                        args.append(positive_deltas)                       
+                                                  
+                    # Add closing brace
+                    nh_sample_template += '}}'
+
+                    # Format the template with the args
+                    native_histogram = nh_sample_template.format(*args)
+                    
+                    if s.native_histogram.nh_exemplars:
+                        for nh_ex in s.native_histogram.nh_exemplars:
+                            nh_exemplarstr = _compose_exemplar_string(metric, s, nh_ex)
+                            exemplarstr += nh_exemplarstr
+
+                value = ''
+                if s.native_histogram:
+                    value = native_histogram
+                elif s.value is not None:
+                    value = floatToGoString(s.value)
+                if (escaping != ALLOWUTF8) or _is_valid_legacy_metric_name(s.name):
+                    output.append('{}{} {}{}{}\n'.format(
+                        _escape(s.name, escaping, _is_legacy_labelname_rune),
+                        labelstr,
+                        value,
+                        timestamp,
+                        exemplarstr
+                    ))
+                else:
+                    output.append('{} {}{}{}\n'.format(
+                        labelstr,
+                        value,
+                        timestamp,
+                        exemplarstr
+                    ))
+        except Exception as exception:
+            exception.args = (exception.args or ('',)) + (metric,)
+            raise
+
+    output.append('# EOF\n')
+    return ''.join(output).encode('utf-8')
+
+
+def escape_metric_name(s: str, escaping: str = UNDERSCORES) -> str:
+    """Escapes the metric name and puts it in quotes iff the name does not
+    conform to the legacy Prometheus character set.
+    """
+    if len(s) == 0:
+        return s
+    if escaping == ALLOWUTF8:
+        if not _is_valid_legacy_metric_name(s):
+            return '"{}"'.format(_escape(s, escaping, _is_legacy_metric_rune))
+        return _escape(s, escaping, _is_legacy_metric_rune)
+    elif escaping == UNDERSCORES:
+        if _is_valid_legacy_metric_name(s):
+            return s
+        return _escape(s, escaping, _is_legacy_metric_rune)
+    elif escaping == DOTS:
+        return _escape(s, escaping, _is_legacy_metric_rune)
+    elif escaping == VALUES:
+        if _is_valid_legacy_metric_name(s):
+            return s
+        return _escape(s, escaping, _is_legacy_metric_rune)
+    return s
+
+
+def escape_label_name(s: str, escaping: str = UNDERSCORES) -> str:
+    """Escapes the label name and puts it in quotes iff the name does not
+    conform to the legacy Prometheus character set.
+    """
+    if len(s) == 0:
+        return s
+    if escaping == ALLOWUTF8:
+        if not _is_valid_legacy_labelname(s):
+            return '"{}"'.format(_escape(s, escaping, _is_legacy_labelname_rune))
+        return _escape(s, escaping, _is_legacy_labelname_rune)
+    elif escaping == UNDERSCORES:
+        if _is_valid_legacy_labelname(s):
+            return s
+        return _escape(s, escaping, _is_legacy_labelname_rune)
+    elif escaping == DOTS:
+        return _escape(s, escaping, _is_legacy_labelname_rune)
+    elif escaping == VALUES:
+        if _is_valid_legacy_labelname(s):
+            return s
+        return _escape(s, escaping, _is_legacy_labelname_rune)
+    return s
+
+
+def _escape(s: str, escaping: str, valid_rune_fn: Callable[[str, int], bool]) -> str:
+    """Performs backslash escaping on backslash, newline, and double-quote characters.
+
+    valid_rune_fn takes the input character and its index in the containing string."""
+    if escaping == ALLOWUTF8:
+        return s.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"')
+    elif escaping == UNDERSCORES:
+        escaped = StringIO()
+        for i, b in enumerate(s):
+            if valid_rune_fn(b, i):
+                escaped.write(b)
+            else:
+                escaped.write('_')
+        return escaped.getvalue()
+    elif escaping == DOTS:
+        escaped = StringIO()
+        for i, b in enumerate(s):
+            if b == '_':
+                escaped.write('__')
+            elif b == '.':
+                escaped.write('_dot_')
+            elif valid_rune_fn(b, i):
+                escaped.write(b)
+            else:
+                escaped.write('__')
+        return escaped.getvalue()
+    elif escaping == VALUES:
+        escaped = StringIO()
+        escaped.write("U__")
+        for i, b in enumerate(s):
+            if b == '_':
+                escaped.write("__")
+            elif valid_rune_fn(b, i):
+                escaped.write(b)
+            elif not _is_valid_utf8(b):
+                escaped.write("_FFFD_")
+            else:
+                escaped.write('_')
+                escaped.write(format(ord(b), 'x'))
+                escaped.write('_')
+        return escaped.getvalue()
+    return s
+
+
+def _is_legacy_metric_rune(b: str, i: int) -> bool:
+    return _is_legacy_labelname_rune(b, i) or b == ':'
+
+
+def _is_legacy_labelname_rune(b: str, i: int) -> bool:
+    if len(b) != 1:
+        raise ValueError("Input 'b' must be a single character.")
+    return (
+        ('a' <= b <= 'z')
+        or ('A' <= b <= 'Z')
+        or (b == '_')
+        or ('0' <= b <= '9' and i > 0)
+    )
+
+
+_SURROGATE_MIN = 0xD800
+_SURROGATE_MAX = 0xDFFF
+
+
+def _is_valid_utf8(s: str) -> bool:
+    if 0 <= ord(s) < _SURROGATE_MIN:
+        return True
+    if _SURROGATE_MAX < ord(s) <= maxunicode:
+        return True
+    return False
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py
new file mode 100644
index 00000000000..0c5c9c414ce
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py
@@ -0,0 +1,653 @@
+#!/usr/bin/env python
+
+
+import io as StringIO
+import math
+import re
+
+from ..metrics_core import Metric
+from ..parser import (
+    _last_unquoted_char, _next_unquoted_char, _parse_value, _split_quoted,
+    _unquote_unescape, parse_labels,
+)
+from ..samples import BucketSpan, Exemplar, NativeHistogram, Sample, Timestamp
+from ..utils import floatToGoString
+from ..validation import _is_valid_legacy_metric_name, _validate_metric_name
+
+
+def text_string_to_metric_families(text):
+    """Parse Openmetrics text format from a unicode string.
+
+    See text_fd_to_metric_families.
+    """
+    yield from text_fd_to_metric_families(StringIO.StringIO(text))
+
+
+_CANONICAL_NUMBERS = {float("inf")}
+
+
+def _isUncanonicalNumber(s):
+    f = float(s)
+    if f not in _CANONICAL_NUMBERS:
+        return False  # Only the canonical numbers are required to be canonical.
+    return s != floatToGoString(f)
+
+
+ESCAPE_SEQUENCES = {
+    '\\\\': '\\',
+    '\\n': '\n',
+    '\\"': '"',
+}
+
+
+def _replace_escape_sequence(match):
+    return ESCAPE_SEQUENCES[match.group(0)]
+
+
+ESCAPING_RE = re.compile(r'\\[\\n"]')
+
+
+def _replace_escaping(s):
+    return ESCAPING_RE.sub(_replace_escape_sequence, s)
+
+
+def _unescape_help(text):
+    result = []
+    slash = False
+
+    for char in text:
+        if slash:
+            if char == '\\':
+                result.append('\\')
+            elif char == '"':
+                result.append('"')
+            elif char == 'n':
+                result.append('\n')
+            else:
+                result.append('\\' + char)
+            slash = False
+        else:
+            if char == '\\':
+                slash = True
+            else:
+                result.append(char)
+
+    if slash:
+        result.append('\\')
+
+    return ''.join(result)
+
+
+def _parse_timestamp(timestamp):
+    timestamp = ''.join(timestamp)
+    if not timestamp:
+        return None
+    if timestamp != timestamp.strip() or '_' in timestamp:
+        raise ValueError(f"Invalid timestamp: {timestamp!r}")
+    try:
+        # Simple int.
+        return Timestamp(int(timestamp), 0)
+    except ValueError:
+        try:
+            # aaaa.bbbb. Nanosecond resolution supported.
+            parts = timestamp.split('.', 1)
+            return Timestamp(int(parts[0]), int(parts[1][:9].ljust(9, "0")))
+        except ValueError:
+            # Float.
+            ts = float(timestamp)
+            if math.isnan(ts) or math.isinf(ts):
+                raise ValueError(f"Invalid timestamp: {timestamp!r}")
+            return ts
+
+
+def _is_character_escaped(s, charpos):
+    num_bslashes = 0
+    while (charpos > num_bslashes
+           and s[charpos - 1 - num_bslashes] == '\\'):
+        num_bslashes += 1
+    return num_bslashes % 2 == 1
+
+
+def _parse_sample(text):
+    separator = " # "
+    # Detect the labels in the text
+    label_start = _next_unquoted_char(text, '{')
+    if label_start == -1 or separator in text[:label_start]:
+        # We don't have labels, but there could be an exemplar.
+        name_end = _next_unquoted_char(text, ' ')
+        name = text[:name_end]
+        if not _is_valid_legacy_metric_name(name):
+            raise ValueError("invalid metric name:" + text)
+        # Parse the remaining text after the name
+        remaining_text = text[name_end + 1:]
+        value, timestamp, exemplar = _parse_remaining_text(remaining_text)
+        return Sample(name, {}, value, timestamp, exemplar)
+    name = text[:label_start]
+    label_end = _next_unquoted_char(text, '}')
+    labels = parse_labels(text[label_start + 1:label_end], True)
+    if not name:
+        # Name might be in the labels
+        if '__name__' not in labels:
+            raise ValueError
+        name = labels['__name__']
+        del labels['__name__']
+    elif '__name__' in labels:
+        raise ValueError("metric name specified more than once")
+    # Parsing labels succeeded, continue parsing the remaining text
+    remaining_text = text[label_end + 2:]
+    value, timestamp, exemplar = _parse_remaining_text(remaining_text)
+    return Sample(name, labels, value, timestamp, exemplar)
+
+
+def _parse_remaining_text(text):
+    split_text = text.split(" ", 1)
+    val = _parse_value(split_text[0])
+    if len(split_text) == 1:
+        # We don't have timestamp or exemplar
+        return val, None, None  
+
+    timestamp = []
+    exemplar_value = []
+    exemplar_timestamp = []
+    exemplar_labels = None
+
+    state = 'timestamp'
+    text = split_text[1]
+
+    it = iter(text)
+    in_quotes = False
+    for char in it:
+        if char == '"':
+            in_quotes = not in_quotes
+        if in_quotes:
+            continue
+        if state == 'timestamp':
+            if char == '#' and not timestamp:
+                state = 'exemplarspace'
+            elif char == ' ':
+                state = 'exemplarhash'
+            else:
+                timestamp.append(char)
+        elif state == 'exemplarhash':
+            if char == '#':
+                state = 'exemplarspace'
+            else:
+                raise ValueError("Invalid line: " + text)
+        elif state == 'exemplarspace':
+            if char == ' ':
+                state = 'exemplarstartoflabels'
+            else:
+                raise ValueError("Invalid line: " + text)
+        elif state == 'exemplarstartoflabels':
+            if char == '{':
+                label_start = _next_unquoted_char(text, '{')
+                label_end = _last_unquoted_char(text, '}')
+                exemplar_labels = parse_labels(text[label_start + 1:label_end], True)
+                state = 'exemplarparsedlabels'
+            else:
+                raise ValueError("Invalid line: " + text)
+        elif state == 'exemplarparsedlabels':
+            if char == '}':
+                state = 'exemplarvaluespace'
+        elif state == 'exemplarvaluespace':
+            if char == ' ':
+                state = 'exemplarvalue'
+            else:
+                raise ValueError("Invalid line: " + text)
+        elif state == 'exemplarvalue':
+            if char == ' ' and not exemplar_value:
+                raise ValueError("Invalid line: " + text)
+            elif char == ' ':
+                state = 'exemplartimestamp'
+            else:
+                exemplar_value.append(char)
+        elif state == 'exemplartimestamp':
+            exemplar_timestamp.append(char)
+
+    # Trailing space after value.
+    if state == 'timestamp' and not timestamp:
+        raise ValueError("Invalid line: " + text)
+
+    # Trailing space after value.
+    if state == 'exemplartimestamp' and not exemplar_timestamp:
+        raise ValueError("Invalid line: " + text)
+
+    # Incomplete exemplar.
+    if state in ['exemplarhash', 'exemplarspace', 'exemplarstartoflabels', 'exemplarparsedlabels']:
+        raise ValueError("Invalid line: " + text)
+
+    ts = _parse_timestamp(timestamp)
+    exemplar = None
+    if exemplar_labels is not None:
+        exemplar_length = sum(len(k) + len(v) for k, v in exemplar_labels.items())
+        if exemplar_length > 128:
+            raise ValueError("Exemplar labels are too long: " + text)
+        exemplar = Exemplar(
+            exemplar_labels,
+            _parse_value(exemplar_value),
+            _parse_timestamp(exemplar_timestamp),
+        )
+
+    return val, ts, exemplar
+
+
+def _parse_nh_sample(text, suffixes):
+    """Determines if the line has a native histogram sample, and parses it if so."""
+    labels_start = _next_unquoted_char(text, '{')
+    labels_end = -1
+
+    # Finding a native histogram sample requires careful parsing of
+    # possibly-quoted text, which can appear in metric names, label names, and
+    # values.
+    # 
+    # First, we need to determine if there are metric labels. Find the space
+    # between the metric definition and the rest of the line. Look for unquoted
+    # space or {.
+    i = 0
+    has_metric_labels = False
+    i = _next_unquoted_char(text, ' {')
+    if i == -1:
+        return
+
+    # If the first unquoted char was a {, then that is the metric labels (which
+    # could contain a UTF-8 metric name).
+    if text[i] == '{':
+        has_metric_labels = True
+        # Consume the labels -- jump ahead to the close bracket.
+        labels_end = i = _next_unquoted_char(text, '}', i)
+        if labels_end == -1:
+            raise ValueError
+    
+    # If there is no subsequent unquoted {, then it's definitely not a nh.
+    nh_value_start = _next_unquoted_char(text, '{', i + 1)
+    if nh_value_start == -1:
+        return
+    
+    # Edge case: if there is an unquoted # between the metric definition and the {,
+    # then this is actually an exemplar
+    exemplar = _next_unquoted_char(text, '#', i + 1)
+    if exemplar != -1 and exemplar < nh_value_start:
+        return
+    
+    nh_value_end = _next_unquoted_char(text, '}', nh_value_start)
+    if nh_value_end == -1:
+        raise ValueError
+    
+    if has_metric_labels:
+        labelstext = text[labels_start + 1:labels_end]
+        labels = parse_labels(labelstext, True)
+        name_end = labels_start
+        name = text[:name_end]
+        if name.endswith(suffixes):
+            raise ValueError("the sample name of a native histogram with labels should have no suffixes", name)
+        if not name:
+            # Name might be in the labels
+            if '__name__' not in labels:
+                raise ValueError
+            name = labels['__name__']
+            del labels['__name__']
+            # Edge case: the only "label" is the name definition.
+            if not labels:
+                labels = None
+             
+        nh_value = text[nh_value_start:]
+        nat_hist_value = _parse_nh_struct(nh_value)
+        return Sample(name, labels, None, None, None, nat_hist_value)
+    # check if it's a native histogram
+    else:
+        nh_value = text[nh_value_start:]
+        name_end = nh_value_start - 1
+        name = text[:name_end]
+        if name.endswith(suffixes):
+            raise ValueError("the sample name of a native histogram should have no suffixes", name)
+        # Not possible for UTF-8 name here, that would have been caught as having a labelset.
+        nat_hist_value = _parse_nh_struct(nh_value)
+        return Sample(name, None, None, None, None, nat_hist_value)      
+
+
+def _parse_nh_struct(text):
+    pattern = r'(\w+):\s*([^,}]+)'
+    re_spans = re.compile(r'(positive_spans|negative_spans):\[(\d+:\d+(,\d+:\d+)*)\]')
+    re_deltas = re.compile(r'(positive_deltas|negative_deltas):\[(-?\d+(?:,-?\d+)*)\]')
+
+    items = dict(re.findall(pattern, text))
+    span_matches = re_spans.findall(text)
+    deltas = dict(re_deltas.findall(text))
+
+    count_value = int(items['count'])
+    sum_value = float(items['sum'])
+    schema = int(items['schema'])
+    zero_threshold = float(items['zero_threshold'])
+    zero_count = int(items['zero_count'])
+
+    pos_spans = _compose_spans(span_matches, 'positive_spans')
+    neg_spans = _compose_spans(span_matches, 'negative_spans')
+    pos_deltas = _compose_deltas(deltas, 'positive_deltas')
+    neg_deltas = _compose_deltas(deltas, 'negative_deltas')
+      
+    return NativeHistogram(
+        count_value=count_value,
+        sum_value=sum_value,
+        schema=schema,
+        zero_threshold=zero_threshold,
+        zero_count=zero_count,
+        pos_spans=pos_spans,
+        neg_spans=neg_spans,
+        pos_deltas=pos_deltas,
+        neg_deltas=neg_deltas
+    )
+  
+
+def _compose_spans(span_matches, spans_name):
+    """Takes a list of span matches (expected to be a list of tuples) and a string 
+    (the expected span list name) and processes the list so that the values extracted 
+    from the span matches can be used to compose a tuple of BucketSpan objects"""
+    spans = {}
+    for match in span_matches:
+        # Extract the key from the match (first element of the tuple).
+        key = match[0]
+        # Extract the value from the match (second element of the tuple).
+        # Split the value string by commas to get individual pairs, 
+        # split each pair by ':' to get start and end, and convert them to integers.
+        value = [tuple(map(int, pair.split(':'))) for pair in match[1].split(',')]
+        # Store the processed value in the spans dictionary with the key.
+        spans[key] = value
+    if spans_name not in spans:
+        return None
+    out_spans = []
+    # Iterate over each start and end tuple in the list of tuples for the specified spans_name.
+    for start, end in spans[spans_name]:
+        # Compose a BucketSpan object with the start and end values 
+        # and append it to the out_spans list.
+        out_spans.append(BucketSpan(start, end))
+        # Convert to tuple
+    out_spans_tuple = tuple(out_spans)
+    return out_spans_tuple
+
+
+def _compose_deltas(deltas, deltas_name):
+    """Takes a list of deltas matches (a dictionary) and a string (the expected delta list name),
+    and processes its elements to compose a tuple of integers representing the deltas"""
+    if deltas_name not in deltas:
+        return None
+    out_deltas = deltas.get(deltas_name)
+    if out_deltas is not None and out_deltas.strip():
+        elems = out_deltas.split(',')
+    # Convert each element in the list elems to an integer 
+    # after stripping whitespace and create a tuple from these integers.
+    out_deltas_tuple = tuple(int(x.strip()) for x in elems)
+    return out_deltas_tuple
+        
+
+def _group_for_sample(sample, name, typ):
+    if typ == 'info':
+        # We can't distinguish between groups for info metrics.
+        return {}
+    if typ == 'summary' and sample.name == name:
+        d = sample.labels.copy()
+        del d['quantile']
+        return d
+    if typ == 'stateset':
+        d = sample.labels.copy()
+        del d[name]
+        return d
+    if typ in ['histogram', 'gaugehistogram'] and sample.name == name + '_bucket':
+        d = sample.labels.copy()
+        del d['le']
+        return d
+    return sample.labels
+
+
+def _check_histogram(samples, name):
+    group = None
+    timestamp = None
+
+    def do_checks():
+        if bucket != float('+Inf'):
+            raise ValueError("+Inf bucket missing: " + name)
+        if count is not None and value != count:
+            raise ValueError("Count does not match +Inf value: " + name)
+        if has_sum and count is None:
+            raise ValueError("_count must be present if _sum is present: " + name)
+        if has_gsum and count is None:
+            raise ValueError("_gcount must be present if _gsum is present: " + name)
+        if not (has_sum or has_gsum) and count is not None:
+            raise ValueError("_sum/_gsum must be present if _count is present: " + name)
+        if has_negative_buckets and has_sum:
+            raise ValueError("Cannot have _sum with negative buckets: " + name)
+        if not has_negative_buckets and has_negative_gsum:
+            raise ValueError("Cannot have negative _gsum with non-negative buckets: " + name)
+
+    for s in samples:
+        suffix = s.name[len(name):]
+        g = _group_for_sample(s, name, 'histogram')
+        if len(suffix) == 0:
+            continue
+        if g != group or s.timestamp != timestamp:
+            if group is not None:
+                do_checks()
+            count = None
+            bucket = None
+            has_negative_buckets = False
+            has_sum = False
+            has_gsum = False
+            has_negative_gsum = False
+            value = 0
+        group = g
+        timestamp = s.timestamp
+
+        if suffix == '_bucket':
+            b = float(s.labels['le'])
+            if b < 0:
+                has_negative_buckets = True
+            if bucket is not None and b <= bucket:
+                raise ValueError("Buckets out of order: " + name)
+            if s.value < value:
+                raise ValueError("Bucket values out of order: " + name)
+            bucket = b
+            value = s.value
+        elif suffix in ['_count', '_gcount']:
+            count = s.value
+        elif suffix in ['_sum']:
+            has_sum = True
+        elif suffix in ['_gsum']:
+            has_gsum = True
+            if s.value < 0:
+                has_negative_gsum = True
+
+    if group is not None:
+        do_checks()
+
+
+def text_fd_to_metric_families(fd):
+    """Parse Prometheus text format from a file descriptor.
+
+    This is a laxer parser than the main Go parser,
+    so successful parsing does not imply that the parsed
+    text meets the specification.
+
+    Yields Metric's.
+    """
+    name = None
+    allowed_names = []
+    eof = False
+
+    seen_names = set()
+    type_suffixes = {
+        'counter': ['_total', '_created'],
+        'summary': ['', '_count', '_sum', '_created'],
+        'histogram': ['_count', '_sum', '_bucket', '_created'],
+        'gaugehistogram': ['_gcount', '_gsum', '_bucket'],
+        'info': ['_info'],
+    }
+
+    def build_metric(name, documentation, typ, unit, samples):
+        if typ is None:
+            typ = 'unknown'
+        for suffix in set(type_suffixes.get(typ, []) + [""]):
+            if name + suffix in seen_names:
+                raise ValueError("Clashing name: " + name + suffix)
+            seen_names.add(name + suffix)
+        if documentation is None:
+            documentation = ''
+        if unit is None:
+            unit = ''
+        if unit and not name.endswith("_" + unit):
+            raise ValueError("Unit does not match metric name: " + name)
+        if unit and typ in ['info', 'stateset']:
+            raise ValueError("Units not allowed for this metric type: " + name)
+        if typ in ['histogram', 'gaugehistogram']:
+            _check_histogram(samples, name)
+        _validate_metric_name(name)
+        metric = Metric(name, documentation, typ, unit)
+        # TODO: check labelvalues are valid utf8
+        metric.samples = samples
+        return metric
+
+    is_nh = False
+    typ = None
+    for line in fd:
+        if line[-1] == '\n':
+            line = line[:-1]
+
+        if eof:
+            raise ValueError("Received line after # EOF: " + line)
+
+        if not line:
+            raise ValueError("Received blank line")
+
+        if line == '# EOF':
+            eof = True
+        elif line.startswith('#'):
+            parts = _split_quoted(line, ' ', 3)
+            if len(parts) < 4:
+                raise ValueError("Invalid line: " + line)
+            candidate_name, quoted = _unquote_unescape(parts[2])
+            if not quoted and not _is_valid_legacy_metric_name(candidate_name):
+                raise ValueError
+            if candidate_name == name and samples:
+                raise ValueError("Received metadata after samples: " + line)
+            if candidate_name != name:
+                if name is not None:
+                    yield build_metric(name, documentation, typ, unit, samples)
+                # New metric
+                name = candidate_name
+                unit = None
+                typ = None
+                documentation = None
+                group = None
+                seen_groups = set()
+                group_timestamp = None
+                group_timestamp_samples = set()
+                samples = []
+                allowed_names = [candidate_name]
+            
+            if parts[1] == 'HELP':
+                if documentation is not None:
+                    raise ValueError("More than one HELP for metric: " + line)
+                documentation = _unescape_help(parts[3])
+            elif parts[1] == 'TYPE':
+                if typ is not None:
+                    raise ValueError("More than one TYPE for metric: " + line)
+                typ = parts[3]
+                if typ == 'untyped':
+                    raise ValueError("Invalid TYPE for metric: " + line)
+                allowed_names = [name + n for n in type_suffixes.get(typ, [''])]
+            elif parts[1] == 'UNIT':
+                if unit is not None:
+                    raise ValueError("More than one UNIT for metric: " + line)
+                unit = parts[3]
+            else:
+                raise ValueError("Invalid line: " + line)
+        else:
+            if typ == 'histogram':
+                # set to true to account for native histograms naming exceptions/sanitizing differences
+                is_nh = True
+                sample = _parse_nh_sample(line, tuple(type_suffixes['histogram']))
+                # It's not a native histogram
+                if sample is None:
+                    is_nh = False
+                    sample = _parse_sample(line)              
+            else:
+                is_nh = False
+                sample = _parse_sample(line)
+            if sample.name not in allowed_names and not is_nh:
+                if name is not None:
+                    yield build_metric(name, documentation, typ, unit, samples)
+                # Start an unknown metric.
+                candidate_name, quoted = _unquote_unescape(sample.name)
+                if not quoted and not _is_valid_legacy_metric_name(candidate_name):
+                    raise ValueError
+                name = candidate_name
+                documentation = None
+                unit = None
+                typ = 'unknown'
+                samples = []
+                group = None
+                group_timestamp = None
+                group_timestamp_samples = set()
+                seen_groups = set()
+                allowed_names = [sample.name]
+
+            if typ == 'stateset' and name not in sample.labels:
+                raise ValueError("Stateset missing label: " + line)
+            if (name + '_bucket' == sample.name
+                    and (sample.labels.get('le', "NaN") == "NaN"
+                         or _isUncanonicalNumber(sample.labels['le']))):
+                raise ValueError("Invalid le label: " + line)
+            if (name + '_bucket' == sample.name
+                    and (not isinstance(sample.value, int) and not sample.value.is_integer())):
+                raise ValueError("Bucket value must be an integer: " + line)
+            if ((name + '_count' == sample.name or name + '_gcount' == sample.name)
+                    and (not isinstance(sample.value, int) and not sample.value.is_integer())):
+                raise ValueError("Count value must be an integer: " + line)
+            if (typ == 'summary' and name == sample.name
+                    and (not (0 <= float(sample.labels.get('quantile', -1)) <= 1)
+                         or _isUncanonicalNumber(sample.labels['quantile']))):
+                raise ValueError("Invalid quantile label: " + line)
+
+            if not is_nh:
+                g = tuple(sorted(_group_for_sample(sample, name, typ).items()))
+                if group is not None and g != group and g in seen_groups:
+                    raise ValueError("Invalid metric grouping: " + line)
+                if group is not None and g == group:
+                    if (sample.timestamp is None) != (group_timestamp is None):
+                        raise ValueError("Mix of timestamp presence within a group: " + line)
+                    if group_timestamp is not None and group_timestamp > sample.timestamp and typ != 'info':
+                        raise ValueError("Timestamps went backwards within a group: " + line)
+                else:
+                    group_timestamp_samples = set()
+
+                series_id = (sample.name, tuple(sorted(sample.labels.items())))
+                if sample.timestamp != group_timestamp or series_id not in group_timestamp_samples:
+                    # Not a duplicate due to timestamp truncation.
+                    samples.append(sample)
+                group_timestamp_samples.add(series_id)
+
+                group = g
+                group_timestamp = sample.timestamp
+                seen_groups.add(g)
+            else:
+                samples.append(sample)
+
+            if typ == 'stateset' and sample.value not in [0, 1]:
+                raise ValueError("Stateset samples can only have values zero and one: " + line)
+            if typ == 'info' and sample.value != 1:
+                raise ValueError("Info samples can only have value one: " + line)
+            if typ == 'summary' and name == sample.name and sample.value < 0:
+                raise ValueError("Quantile values cannot be negative: " + line)
+            if sample.name[len(name):] in ['_total', '_sum', '_count', '_bucket', '_gcount', '_gsum'] and math.isnan(
+                    sample.value):
+                raise ValueError("Counter-like samples cannot be NaN: " + line)
+            if sample.name[len(name):] in ['_total', '_sum', '_count', '_bucket', '_gcount'] and sample.value < 0:
+                raise ValueError("Counter-like samples cannot be negative: " + line)
+            if sample.exemplar and not (
+                    (typ in ['histogram', 'gaugehistogram'] and sample.name.endswith('_bucket'))
+                    or (typ in ['counter'] and sample.name.endswith('_total'))):
+                raise ValueError("Invalid line only histogram/gaugehistogram buckets and counters can have exemplars: " + line)
+    
+    if name is not None:
+        yield build_metric(name, documentation, typ, unit, samples)
+
+    if not eof:
+        raise ValueError("Missing # EOF at end")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py
new file mode 100644
index 00000000000..ceca273b42e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py
@@ -0,0 +1,370 @@
+import io as StringIO
+import re
+import string
+from typing import Dict, Iterable, List, Match, Optional, TextIO, Tuple
+
+from .metrics_core import Metric
+from .samples import Sample
+from .validation import (
+    _is_valid_legacy_metric_name, _validate_labelname, _validate_metric_name,
+)
+
+
+def text_string_to_metric_families(text: str) -> Iterable[Metric]:
+    """Parse Prometheus text format from a unicode string.
+
+    See text_fd_to_metric_families.
+    """
+    yield from text_fd_to_metric_families(StringIO.StringIO(text))
+
+
+ESCAPE_SEQUENCES = {
+    '\\\\': '\\',
+    '\\n': '\n',
+    '\\"': '"',
+}
+
+
+def replace_escape_sequence(match: Match[str]) -> str:
+    return ESCAPE_SEQUENCES[match.group(0)]
+
+
+HELP_ESCAPING_RE = re.compile(r'\\[\\n]')
+ESCAPING_RE = re.compile(r'\\[\\n"]')
+
+
+def _replace_help_escaping(s: str) -> str:
+    return HELP_ESCAPING_RE.sub(replace_escape_sequence, s)
+
+
+def _replace_escaping(s: str) -> str:
+    return ESCAPING_RE.sub(replace_escape_sequence, s)
+
+
+def _is_character_escaped(s: str, charpos: int) -> bool:
+    num_bslashes = 0
+    while (charpos > num_bslashes
+           and s[charpos - 1 - num_bslashes] == '\\'):
+        num_bslashes += 1
+    return num_bslashes % 2 == 1
+
+
+def parse_labels(labels_string: str, openmetrics: bool = False) -> Dict[str, str]:
+    labels: Dict[str, str] = {}
+
+    # Copy original labels
+    sub_labels = labels_string.strip()
+    if openmetrics and sub_labels and sub_labels[0] == ',':
+        raise ValueError("leading comma: " + labels_string)
+    try:
+        # Process one label at a time
+        while sub_labels:
+            # The label name is before the equal, or if there's no equal, that's the
+            # metric name.
+            
+            name_term, value_term, sub_labels = _next_term(sub_labels, openmetrics)
+            if not value_term:
+                if openmetrics:
+                    raise ValueError("empty term in line: " + labels_string)
+                continue
+            
+            label_name, quoted_name = _unquote_unescape(name_term)
+                
+            if not quoted_name and not _is_valid_legacy_metric_name(label_name):
+                raise ValueError("unquoted UTF-8 metric name")
+                
+            # Check for missing quotes 
+            if not value_term or value_term[0] != '"':
+                raise ValueError
+
+            # The first quote is guaranteed to be after the equal.
+            # Make sure that the next unescaped quote is the last character.
+            i = 1
+            while i < len(value_term):
+                i = value_term.index('"', i)
+                if not _is_character_escaped(value_term[:i], i):
+                    break
+                i += 1
+            # The label value is between the first and last quote
+            quote_end = i + 1
+            if quote_end != len(value_term):
+                raise ValueError("unexpected text after quote: " + labels_string)
+
+            label_value, _ = _unquote_unescape(value_term)
+            if label_name == '__name__':
+                _validate_metric_name(label_name)
+            else:
+                _validate_labelname(label_name)
+            if label_name in labels:
+                raise ValueError("invalid line, duplicate label name: " + labels_string)
+            labels[label_name] = label_value
+        return labels
+    except ValueError:
+        raise ValueError("Invalid labels: " + labels_string)
+    
+
+def _next_term(text: str, openmetrics: bool) -> Tuple[str, str, str]:
+    """Extract the next comma-separated label term from the text. The results
+    are stripped terms for the label name, label value, and then the remainder
+    of the string including the final , or }.
+    
+    Raises ValueError if the term is empty and we're in openmetrics mode.
+    """
+    
+    # There may be a leading comma, which is fine here.
+    if text[0] == ',':
+        text = text[1:]
+        if not text:
+            return "", "", ""
+        if text[0] == ',':
+            raise ValueError("multiple commas")
+
+    splitpos = _next_unquoted_char(text, '=,}')
+    if splitpos >= 0 and text[splitpos] == "=":
+        labelname = text[:splitpos]
+        text = text[splitpos + 1:]
+        splitpos = _next_unquoted_char(text, ',}')
+    else:
+        labelname = "__name__"
+
+    if splitpos == -1:
+        splitpos = len(text)
+    term = text[:splitpos]
+    if not term and openmetrics:
+        raise ValueError("empty term:", term)
+    
+    rest = text[splitpos:]
+    return labelname, term.strip(), rest.strip()
+
+
+def _next_unquoted_char(text: str, chs: Optional[str], startidx: int = 0) -> int:
+    """Return position of next unquoted character in tuple, or -1 if not found.
+    
+    It is always assumed that the first character being checked is not already
+    inside quotes.
+    """
+    in_quotes = False
+    if chs is None:
+        chs = string.whitespace
+
+    for i, c in enumerate(text[startidx:]):
+        if c == '"' and not _is_character_escaped(text, startidx + i):
+            in_quotes = not in_quotes
+        if not in_quotes:
+            if c in chs:
+                return startidx + i
+    return -1
+
+
+def _last_unquoted_char(text: str, chs: Optional[str]) -> int:
+    """Return position of last unquoted character in list, or -1 if not found."""
+    i = len(text) - 1
+    in_quotes = False
+    if chs is None:
+        chs = string.whitespace
+    while i > 0:
+        if text[i] == '"' and not _is_character_escaped(text, i):
+            in_quotes = not in_quotes
+            
+        if not in_quotes:
+            if text[i] in chs:
+                return i
+        i -= 1
+    return -1
+
+
+def _split_quoted(text, separator, maxsplit=0):
+    """Splits on split_ch similarly to strings.split, skipping separators if
+    they are inside quotes.
+    """
+
+    tokens = ['']
+    x = 0
+    while x < len(text):
+        split_pos = _next_unquoted_char(text, separator, x)
+        if split_pos == -1:
+            tokens[-1] = text[x:]
+            x = len(text)
+            continue
+        # If the first character is the separator keep going. This happens when
+        # there are double whitespace characters separating symbols.
+        if split_pos == x:
+            x += 1
+            continue
+
+        if maxsplit > 0 and len(tokens) > maxsplit:
+            tokens[-1] = text[x:]
+            break
+        tokens[-1] = text[x:split_pos]
+        x = split_pos + 1
+        tokens.append('')
+    return tokens
+
+
+def _unquote_unescape(text):
+    """Returns the string, and true if it was quoted."""
+    if not text:
+        return text, False
+    quoted = False
+    text = text.strip()
+    if text[0] == '"':
+        if len(text) == 1 or text[-1] != '"':
+            raise ValueError("missing close quote")
+        text = text[1:-1]
+        quoted = True
+    if "\\" in text:
+        text = _replace_escaping(text)
+    return text, quoted
+
+
+# If we have multiple values only consider the first
+def _parse_value_and_timestamp(s: str) -> Tuple[float, Optional[float]]:
+    s = s.lstrip()
+    separator = " "
+    if separator not in s:
+        separator = "\t"
+    values = [value.strip() for value in s.split(separator) if value.strip()]
+    if not values:
+        return float(s), None
+    value = _parse_value(values[0])
+    timestamp = (_parse_value(values[-1]) / 1000) if len(values) > 1 else None
+    return value, timestamp
+
+
+def _parse_value(value):
+    value = ''.join(value)
+    if value != value.strip() or '_' in value:
+        raise ValueError(f"Invalid value: {value!r}")
+    try:
+        return int(value)
+    except ValueError:
+        return float(value)
+    
+
+def _parse_sample(text):
+    separator = " # "
+    # Detect the labels in the text
+    label_start = _next_unquoted_char(text, '{')
+    if label_start == -1 or separator in text[:label_start]:
+        # We don't have labels, but there could be an exemplar.
+        name_end = _next_unquoted_char(text, ' \t')
+        name = text[:name_end].strip()
+        if not _is_valid_legacy_metric_name(name):
+            raise ValueError("invalid metric name:" + text)
+        # Parse the remaining text after the name
+        remaining_text = text[name_end + 1:]
+        value, timestamp = _parse_value_and_timestamp(remaining_text)
+        return Sample(name, {}, value, timestamp)
+    name = text[:label_start].strip()
+    label_end = _next_unquoted_char(text[label_start:], '}') + label_start
+    labels = parse_labels(text[label_start + 1:label_end], False)
+    if not name:
+        # Name might be in the labels
+        if '__name__' not in labels:
+            raise ValueError
+        name = labels['__name__']
+        del labels['__name__']
+    elif '__name__' in labels:
+        raise ValueError("metric name specified more than once")
+    # Parsing labels succeeded, continue parsing the remaining text
+    remaining_text = text[label_end + 1:]
+    value, timestamp = _parse_value_and_timestamp(remaining_text)
+    return Sample(name, labels, value, timestamp)
+
+
+def text_fd_to_metric_families(fd: TextIO) -> Iterable[Metric]:
+    """Parse Prometheus text format from a file descriptor.
+
+    This is a laxer parser than the main Go parser,
+    so successful parsing does not imply that the parsed
+    text meets the specification.
+
+    Yields Metric's.
+    """
+    name = ''
+    documentation = ''
+    typ = 'untyped'
+    samples: List[Sample] = []
+    allowed_names = []
+
+    def build_metric(name: str, documentation: str, typ: str, samples: List[Sample]) -> Metric:
+        # Munge counters into OpenMetrics representation
+        # used internally.
+        if typ == 'counter':
+            if name.endswith('_total'):
+                name = name[:-6]
+            else:
+                new_samples = []
+                for s in samples:
+                    new_samples.append(Sample(s[0] + '_total', *s[1:]))
+                    samples = new_samples
+        metric = Metric(name, documentation, typ)
+        metric.samples = samples
+        return metric
+
+    for line in fd:
+        line = line.strip()
+
+        if line.startswith('#'):
+            parts = _split_quoted(line, None, 3)
+            if len(parts) < 2:
+                continue
+            candidate_name, quoted = '', False
+            if len(parts) > 2:
+                # Ignore comment tokens
+                if parts[1] != 'TYPE' and parts[1] != 'HELP':
+                    continue
+                candidate_name, quoted = _unquote_unescape(parts[2])
+                if not quoted and not _is_valid_legacy_metric_name(candidate_name):
+                    raise ValueError
+            if parts[1] == 'HELP':
+                if candidate_name != name:
+                    if name != '':
+                        yield build_metric(name, documentation, typ, samples)
+                    # New metric
+                    name = candidate_name
+                    typ = 'untyped'
+                    samples = []
+                    allowed_names = [candidate_name]
+                if len(parts) == 4:
+                    documentation = _replace_help_escaping(parts[3])
+                else:
+                    documentation = ''
+            elif parts[1] == 'TYPE':
+                if len(parts) < 4:
+                    raise ValueError
+                if candidate_name != name:
+                    if name != '':
+                        yield build_metric(name, documentation, typ, samples)
+                    # New metric
+                    name = candidate_name
+                    documentation = ''
+                    samples = []
+                typ = parts[3]
+                allowed_names = {
+                    'counter': [''],
+                    'gauge': [''],
+                    'summary': ['_count', '_sum', ''],
+                    'histogram': ['_count', '_sum', '_bucket'],
+                }.get(typ, [''])
+                allowed_names = [name + n for n in allowed_names]
+        elif line == '':
+            # Ignore blank lines
+            pass
+        else:
+            sample = _parse_sample(line)
+            if sample.name not in allowed_names:
+                if name != '':
+                    yield build_metric(name, documentation, typ, samples)
+                # New metric, yield immediately as untyped singleton
+                name = ''
+                documentation = ''
+                typ = 'untyped'
+                samples = []
+                allowed_names = []
+                yield build_metric(sample[0], documentation, typ, [sample])
+            else:
+                samples.append(sample)
+
+    if name != '':
+        yield build_metric(name, documentation, typ, samples)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py
new file mode 100644
index 00000000000..6040fcce622
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py
@@ -0,0 +1,59 @@
+import platform as pf
+from typing import Any, Iterable, Optional
+
+from .metrics_core import GaugeMetricFamily, Metric
+from .registry import Collector, CollectorRegistry, REGISTRY
+
+
+class PlatformCollector(Collector):
+    """Collector for python platform information"""
+
+    def __init__(self,
+                 registry: Optional[CollectorRegistry] = REGISTRY,
+                 platform: Optional[Any] = None,
+                 ):
+        self._platform = pf if platform is None else platform
+        info = self._info()
+        system = self._platform.system()
+        if system == "Java":
+            info.update(self._java())
+        self._metrics = [
+            self._add_metric("python_info", "Python platform information", info)
+        ]
+        if registry:
+            registry.register(self)
+
+    def collect(self) -> Iterable[Metric]:
+        return self._metrics
+
+    @staticmethod
+    def _add_metric(name, documentation, data):
+        labels = data.keys()
+        values = [data[k] for k in labels]
+        g = GaugeMetricFamily(name, documentation, labels=labels)
+        g.add_metric(values, 1)
+        return g
+
+    def _info(self):
+        major, minor, patchlevel = self._platform.python_version_tuple()
+        return {
+            "version": self._platform.python_version(),
+            "implementation": self._platform.python_implementation(),
+            "major": major,
+            "minor": minor,
+            "patchlevel": patchlevel
+        }
+
+    def _java(self):
+        java_version, _, vminfo, osinfo = self._platform.java_ver()
+        vm_name, vm_release, vm_vendor = vminfo
+        return {
+            "jvm_version": java_version,
+            "jvm_release": vm_release,
+            "jvm_vendor": vm_vendor,
+            "jvm_name": vm_name
+        }
+
+
+PLATFORM_COLLECTOR = PlatformCollector()
+"""PlatformCollector in default Registry REGISTRY"""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py
new file mode 100644
index 00000000000..2894e874502
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py
@@ -0,0 +1,101 @@
+import os
+from typing import Callable, Iterable, Optional, Union
+
+from .metrics_core import CounterMetricFamily, GaugeMetricFamily, Metric
+from .registry import Collector, CollectorRegistry, REGISTRY
+
+try:
+    import resource
+
+    _PAGESIZE = resource.getpagesize()
+except ImportError:
+    # Not Unix
+    _PAGESIZE = 4096
+
+
+class ProcessCollector(Collector):
+    """Collector for Standard Exports such as cpu and memory."""
+
+    def __init__(self,
+                 namespace: str = '',
+                 pid: Callable[[], Union[int, str]] = lambda: 'self',
+                 proc: str = '/proc',
+                 registry: Optional[CollectorRegistry] = REGISTRY):
+        self._namespace = namespace
+        self._pid = pid
+        self._proc = proc
+        if namespace:
+            self._prefix = namespace + '_process_'
+        else:
+            self._prefix = 'process_'
+        self._ticks = 100.0
+        try:
+            self._ticks = os.sysconf('SC_CLK_TCK')
+        except (ValueError, TypeError, AttributeError, OSError):
+            pass
+
+        self._pagesize = _PAGESIZE
+
+        # This is used to test if we can access /proc.
+        self._btime = 0
+        try:
+            self._btime = self._boot_time()
+        except OSError:
+            pass
+        if registry:
+            registry.register(self)
+
+    def _boot_time(self):
+        with open(os.path.join(self._proc, 'stat'), 'rb') as stat:
+            for line in stat:
+                if line.startswith(b'btime '):
+                    return float(line.split()[1])
+
+    def collect(self) -> Iterable[Metric]:
+        if not self._btime:
+            return []
+
+        pid = os.path.join(self._proc, str(self._pid()).strip())
+
+        result = []
+        try:
+            with open(os.path.join(pid, 'stat'), 'rb') as stat:
+                parts = (stat.read().split(b')')[-1].split())
+
+            vmem = GaugeMetricFamily(self._prefix + 'virtual_memory_bytes',
+                                     'Virtual memory size in bytes.', value=float(parts[20]))
+            rss = GaugeMetricFamily(self._prefix + 'resident_memory_bytes', 'Resident memory size in bytes.',
+                                    value=float(parts[21]) * self._pagesize)
+            start_time_secs = float(parts[19]) / self._ticks
+            start_time = GaugeMetricFamily(self._prefix + 'start_time_seconds',
+                                           'Start time of the process since unix epoch in seconds.',
+                                           value=start_time_secs + self._btime)
+            utime = float(parts[11]) / self._ticks
+            stime = float(parts[12]) / self._ticks
+            cpu = CounterMetricFamily(self._prefix + 'cpu_seconds_total',
+                                      'Total user and system CPU time spent in seconds.',
+                                      value=utime + stime)
+            result.extend([vmem, rss, start_time, cpu])
+        except OSError:
+            pass
+
+        try:
+            with open(os.path.join(pid, 'limits'), 'rb') as limits:
+                for line in limits:
+                    if line.startswith(b'Max open file'):
+                        max_fds = GaugeMetricFamily(self._prefix + 'max_fds',
+                                                    'Maximum number of open file descriptors.',
+                                                    value=float(line.split()[3]))
+                        break
+            open_fds = GaugeMetricFamily(self._prefix + 'open_fds',
+                                         'Number of open file descriptors.',
+                                         len(os.listdir(os.path.join(pid, 'fd'))))
+            result.extend([open_fds, max_fds])
+        except OSError:
+            pass
+
+        return result
+
+
+PROCESS_COLLECTOR = ProcessCollector()
+"""Default ProcessCollector in default Registry REGISTRY."""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py
new file mode 100644
index 00000000000..63f8ab03abe
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py
@@ -0,0 +1,178 @@
+import copy
+from threading import Lock
+from typing import Dict, Iterable, List, Optional, Protocol, Set
+
+from .metrics_core import Metric
+
+
+class Collector(Protocol):
+    def collect(self) -> Iterable[Metric]:
+        """Collect metrics."""
+
+
+class _EmptyCollector:
+    def collect(self) -> Iterable[Metric]:
+        return []
+
+
+class DuplicateTimeseries(ValueError):
+    def __init__(self, duplicates: Set[str]):
+        msg = 'Duplicated timeseries in CollectorRegistry: {}'.format(
+            duplicates)
+        super().__init__(msg)
+        self.duplicates: Set[str] = duplicates
+
+
+class CollectorRegistry:
+    """Metric collector registry.
+
+    Collectors must have a no-argument method 'collect' that returns a list of
+    Metric objects. The returned metrics should be consistent with the Prometheus
+    exposition formats.
+    """
+
+    def __init__(self, auto_describe: bool = False, target_info: Optional[Dict[str, str]] = None,
+                 support_collectors_without_names: bool = False):
+        self._collector_to_names: Dict[Collector, List[str]] = {}
+        self._names_to_collectors: Dict[str, Collector] = {}
+        self._auto_describe = auto_describe
+        self._lock = Lock()
+        self._target_info: Optional[Dict[str, str]] = {}
+        self._support_collectors_without_names = support_collectors_without_names
+        self._collectors_without_names: List[Collector] = []
+        self.set_target_info(target_info)
+
+    def register(self, collector: Collector) -> None:
+        """Add a collector to the registry."""
+        with self._lock:
+            names = self._get_names(collector)
+            duplicates = set(self._names_to_collectors).intersection(names)
+            if duplicates:
+                raise DuplicateTimeseries(duplicates)
+            for name in names:
+                self._names_to_collectors[name] = collector
+            self._collector_to_names[collector] = names
+            if self._support_collectors_without_names and not names:
+                self._collectors_without_names.append(collector)
+
+    def unregister(self, collector: Collector) -> None:
+        """Remove a collector from the registry."""
+        with self._lock:
+            for name in self._collector_to_names[collector]:
+                del self._names_to_collectors[name]
+            del self._collector_to_names[collector]
+            if collector in self._collectors_without_names:
+                self._collectors_without_names.remove(collector)
+
+    def _get_names(self, collector):
+        """Get names of timeseries the collector produces and clashes with."""
+        desc_func = None
+        # If there's a describe function, use it.
+        try:
+            desc_func = collector.describe
+        except AttributeError:
+            pass
+        # Otherwise, if auto describe is enabled use the collect function.
+        if not desc_func and self._auto_describe:
+            desc_func = collector.collect
+
+        if not desc_func:
+            return []
+
+        result = []
+        type_suffixes = {
+            'counter': ['_total', '_created'],
+            'summary': ['_sum', '_count', '_created'],
+            'histogram': ['_bucket', '_sum', '_count', '_created'],
+            'gaugehistogram': ['_bucket', '_gsum', '_gcount'],
+            'info': ['_info'],
+        }
+        for metric in desc_func():
+            result.append(metric.name)
+            for suffix in type_suffixes.get(metric.type, []):
+                result.append(metric.name + suffix)
+        return result
+
+    def collect(self) -> Iterable[Metric]:
+        """Yields metrics from the collectors in the registry."""
+        collectors = None
+        ti = None
+        with self._lock:
+            collectors = copy.copy(self._collector_to_names)
+            if self._target_info:
+                ti = self._target_info_metric()
+        if ti:
+            yield ti
+        for collector in collectors:
+            yield from collector.collect()
+
+    def restricted_registry(self, names: Iterable[str]) -> "RestrictedRegistry":
+        """Returns object that only collects some metrics.
+
+        Returns an object which upon collect() will return
+        only samples with the given names.
+
+        Intended usage is:
+            generate_latest(REGISTRY.restricted_registry(['a_timeseries']), escaping)
+
+        Experimental."""
+        names = set(names)
+        return RestrictedRegistry(names, self)
+
+    def set_target_info(self, labels: Optional[Dict[str, str]]) -> None:
+        with self._lock:
+            if labels:
+                if not self._target_info and 'target_info' in self._names_to_collectors:
+                    raise ValueError('CollectorRegistry already contains a target_info metric')
+                self._names_to_collectors['target_info'] = _EmptyCollector()
+            elif self._target_info:
+                self._names_to_collectors.pop('target_info', None)
+            self._target_info = labels
+
+    def get_target_info(self) -> Optional[Dict[str, str]]:
+        with self._lock:
+            return self._target_info
+
+    def _target_info_metric(self):
+        m = Metric('target', 'Target metadata', 'info')
+        m.add_sample('target_info', self._target_info, 1)
+        return m
+
+    def get_sample_value(self, name: str, labels: Optional[Dict[str, str]] = None) -> Optional[float]:
+        """Returns the sample value, or None if not found.
+
+        This is inefficient, and intended only for use in unittests.
+        """
+        if labels is None:
+            labels = {}
+        for metric in self.collect():
+            for s in metric.samples:
+                if s.name == name and s.labels == labels:
+                    return s.value
+        return None
+
+
+class RestrictedRegistry:
+    def __init__(self, names: Iterable[str], registry: CollectorRegistry):
+        self._name_set = set(names)
+        self._registry = registry
+
+    def collect(self) -> Iterable[Metric]:
+        collectors = set(self._registry._collectors_without_names)
+        target_info_metric = None
+        with self._registry._lock:
+            if 'target_info' in self._name_set and self._registry._target_info:
+                target_info_metric = self._registry._target_info_metric()
+            for name in self._name_set:
+                if name != 'target_info' and name in self._registry._names_to_collectors:
+                    collectors.add(self._registry._names_to_collectors[name])
+        if target_info_metric:
+            yield target_info_metric
+        for collector in collectors:
+            for metric in collector.collect():
+                m = metric._restricted_metric(self._name_set)
+                if m:
+                    yield m
+
+
+REGISTRY = CollectorRegistry(auto_describe=True)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py
new file mode 100644
index 00000000000..994d12817ac
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py
@@ -0,0 +1,74 @@
+from typing import Dict, NamedTuple, Optional, Sequence, Union
+
+
+class Timestamp:
+    """A nanosecond-resolution timestamp."""
+
+    def __init__(self, sec: float, nsec: float) -> None:
+        if nsec < 0 or nsec >= 1e9:
+            raise ValueError(f"Invalid value for nanoseconds in Timestamp: {nsec}")
+        if sec < 0:
+            nsec = -nsec
+        self.sec: int = int(sec)
+        self.nsec: int = int(nsec)
+
+    def __str__(self) -> str:
+        return f"{self.sec}.{self.nsec:09d}"
+
+    def __repr__(self) -> str:
+        return f"Timestamp({self.sec}, {self.nsec})"
+
+    def __float__(self) -> float:
+        return float(self.sec) + float(self.nsec) / 1e9
+
+    def __eq__(self, other: object) -> bool:
+        return isinstance(other, Timestamp) and self.sec == other.sec and self.nsec == other.nsec
+
+    def __ne__(self, other: object) -> bool:
+        return not self == other
+
+    def __gt__(self, other: "Timestamp") -> bool:
+        return self.nsec > other.nsec if self.sec == other.sec else self.sec > other.sec
+
+    def __lt__(self, other: "Timestamp") -> bool:
+        return self.nsec < other.nsec if self.sec == other.sec else self.sec < other.sec
+
+
+# BucketSpan is experimental and subject to change at any time.
+class BucketSpan(NamedTuple):
+    offset: int
+    length: int
+
+
+# Timestamp and exemplar are optional.
+# Value can be an int or a float.
+# Timestamp can be a float containing a unixtime in seconds,
+# a Timestamp object, or None.
+# Exemplar can be an Exemplar object, or None.
+class Exemplar(NamedTuple):
+    labels: Dict[str, str]
+    value: float
+    timestamp: Optional[Union[float, Timestamp]] = None
+
+
+# NativeHistogram is experimental and subject to change at any time.
+class NativeHistogram(NamedTuple):
+    count_value: float
+    sum_value: float
+    schema: int
+    zero_threshold: float
+    zero_count: float
+    pos_spans: Optional[Sequence[BucketSpan]] = None
+    neg_spans: Optional[Sequence[BucketSpan]] = None
+    pos_deltas: Optional[Sequence[int]] = None
+    neg_deltas: Optional[Sequence[int]] = None
+    nh_exemplars: Optional[Sequence[Exemplar]] = None
+
+
+class Sample(NamedTuple):
+    name: str
+    labels: Dict[str, str]
+    value: float
+    timestamp: Optional[Union[float, Timestamp]] = None
+    exemplar: Optional[Exemplar] = None
+    native_histogram: Optional[NativeHistogram] = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py
new file mode 100644
index 00000000000..52c852ab813
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py
@@ -0,0 +1,36 @@
+import math
+from typing import Union
+
+INF = float("inf")
+MINUS_INF = float("-inf")
+NaN = float("NaN")
+
+
+def floatToGoString(d):
+    d = float(d)
+    if d == INF:
+        return '+Inf'
+    elif d == MINUS_INF:
+        return '-Inf'
+    elif math.isnan(d):
+        return 'NaN'
+    else:
+        s = repr(d)
+        dot = s.find('.')
+        # Go switches to exponents sooner than Python.
+        # We only need to care about positive values for le/quantile.
+        if d > 0 and dot > 6:
+            mantissa = f'{s[0]}.{s[1:dot]}{s[dot + 1:]}'.rstrip('0.')
+            return f'{mantissa}e+{dot - 1:02d}'
+        return s
+
+
+def parse_version(version_str: str) -> tuple[Union[int, str], ...]:
+    version: list[Union[int, str]] = []
+    for part in version_str.split('.'):
+        try:
+            version.append(int(part))
+        except ValueError:
+            version.append(part)
+
+    return tuple(version)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py
new file mode 100644
index 00000000000..6fcc80183a2
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py
@@ -0,0 +1,124 @@
+import os
+import re
+
+METRIC_NAME_RE = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$')
+METRIC_LABEL_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
+RESERVED_METRIC_LABEL_NAME_RE = re.compile(r'^__.*$')
+
+
+def _init_legacy_validation() -> bool:
+    """Retrieve name validation setting from environment."""
+    return os.environ.get("PROMETHEUS_LEGACY_NAME_VALIDATION", 'False').lower() in ('true', '1', 't')
+
+
+_legacy_validation = _init_legacy_validation()
+
+
+def get_legacy_validation() -> bool:
+    """Return the current status of the legacy validation setting."""
+    return _legacy_validation
+
+
+def disable_legacy_validation():
+    """Disable legacy name validation, instead allowing all UTF8 characters."""
+    global _legacy_validation
+    _legacy_validation = False
+
+
+def enable_legacy_validation():
+    """Enable legacy name validation instead of allowing all UTF8 characters."""
+    global _legacy_validation
+    _legacy_validation = True
+
+
+def _validate_metric_name(name: str) -> None:
+    """Raises ValueError if the provided name is not a valid metric name.
+    
+    This check uses the global legacy validation setting to determine the validation scheme.
+    """
+    if not name:
+        raise ValueError("metric name cannot be empty")
+    if _legacy_validation:
+        if not METRIC_NAME_RE.match(name):
+            raise ValueError("invalid metric name " + name)
+    try:
+        name.encode('utf-8')
+    except UnicodeDecodeError:
+        raise ValueError("invalid metric name " + name)
+
+
+def _is_valid_legacy_metric_name(name: str) -> bool:
+    """Returns true if the provided metric name conforms to the legacy validation scheme."""
+    if len(name) == 0:
+        return False
+    return METRIC_NAME_RE.match(name) is not None
+
+
+def _validate_metric_label_name_token(tok: str) -> None:
+    """Raises ValueError if a parsed label name token is invalid. 
+    
+    UTF-8 names must be quoted.
+    """
+    if not tok:
+        raise ValueError("invalid label name token " + tok)
+    quoted = tok[0] == '"' and tok[-1] == '"'
+    if not quoted or _legacy_validation:
+        if not METRIC_LABEL_NAME_RE.match(tok):
+            raise ValueError("invalid label name token " + tok)
+        return
+    try:
+        tok.encode('utf-8')
+    except UnicodeDecodeError:
+        raise ValueError("invalid label name token " + tok)
+
+
+def _validate_labelname(l):
+    """Raises ValueError if the provided name is not a valid label name.
+    
+    This check uses the global legacy validation setting to determine the validation scheme.
+    """
+    if get_legacy_validation():
+        if not METRIC_LABEL_NAME_RE.match(l):
+            raise ValueError('Invalid label metric name: ' + l)
+        if RESERVED_METRIC_LABEL_NAME_RE.match(l):
+            raise ValueError('Reserved label metric name: ' + l)
+    else:
+        try:
+            l.encode('utf-8')
+        except UnicodeDecodeError:
+            raise ValueError('Invalid label metric name: ' + l)
+        if RESERVED_METRIC_LABEL_NAME_RE.match(l):
+            raise ValueError('Reserved label metric name: ' + l)
+        
+
+def _is_valid_legacy_labelname(l: str) -> bool:
+    """Returns true if the provided label name conforms to the legacy validation scheme."""
+    if len(l) == 0:
+        return False
+    if METRIC_LABEL_NAME_RE.match(l) is None:
+        return False
+    return RESERVED_METRIC_LABEL_NAME_RE.match(l) is None
+
+
+def _validate_labelnames(cls, labelnames):
+    """Raises ValueError if any of the provided names is not a valid label name.
+    
+    This check uses the global legacy validation setting to determine the validation scheme.
+    """
+    labelnames = tuple(labelnames)
+    for l in labelnames:
+        _validate_labelname(l)
+        if l in cls._reserved_labelnames:
+            raise ValueError('Reserved label methe fric name: ' + l)
+    return labelnames
+
+
+def _validate_exemplar(exemplar):
+    """Raises ValueError if the exemplar is invalid."""
+    runes = 0
+    for k, v in exemplar.items():
+        _validate_labelname(k)
+        runes += len(k)
+        runes += len(v)
+    if runes > 128:
+        raise ValueError('Exemplar labels have %d UTF-8 characters, exceeding the limit of 128')
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py
new file mode 100644
index 00000000000..16c745ed65a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py
@@ -0,0 +1,163 @@
+import os
+from threading import Lock
+from typing import Callable, List
+import warnings
+
+from .mmap_dict import mmap_key, MmapedDict
+
+_multi_process_cleanups: List[Callable[[], None]] = []
+
+
+def close_all_multiprocess_files():
+    for cleanup in _multi_process_cleanups:
+        cleanup()
+    _multi_process_cleanups.clear()
+
+
+class MutexValue:
+    """A float protected by a mutex."""
+
+    _multiprocess = False
+
+    def __init__(self, typ, metric_name, name, labelnames, labelvalues, help_text, **kwargs):
+        self._value = 0.0
+        self._exemplar = None
+        self._lock = Lock()
+
+    def inc(self, amount):
+        with self._lock:
+            self._value += amount
+
+    def set(self, value, timestamp=None):
+        with self._lock:
+            self._value = value
+
+    def set_exemplar(self, exemplar):
+        with self._lock:
+            self._exemplar = exemplar
+
+    def get(self):
+        with self._lock:
+            return self._value
+
+    def get_exemplar(self):
+        with self._lock:
+            return self._exemplar
+
+
+def MultiProcessValue(process_identifier=os.getpid):
+    """Returns a MmapedValue class based on a process_identifier function.
+
+    The 'process_identifier' function MUST comply with this simple rule:
+    when called in simultaneously running processes it MUST return distinct values.
+
+    Using a different function than the default 'os.getpid' is at your own risk.
+    """
+    files = {}
+    values = []
+    pid = {'value': process_identifier()}
+    # Use a single global lock when in multi-processing mode
+    # as we presume this means there is no threading going on.
+    # This avoids the need to also have mutexes in __MmapDict.
+    lock = Lock()
+
+    def cleanup():
+        for f in files.values():
+            f.close()
+        files.clear()
+        values.clear()
+    _multi_process_cleanups.append(cleanup)
+
+    class MmapedValue:
+        """A float protected by a mutex backed by a per-process mmaped file."""
+
+        _multiprocess = True
+
+        def __init__(self, typ, metric_name, name, labelnames, labelvalues, help_text, multiprocess_mode='', **kwargs):
+            self._params = typ, metric_name, name, labelnames, labelvalues, help_text, multiprocess_mode
+            # This deprecation warning can go away in a few releases when removing the compatibility
+            if 'prometheus_multiproc_dir' in os.environ and 'PROMETHEUS_MULTIPROC_DIR' not in os.environ:
+                os.environ['PROMETHEUS_MULTIPROC_DIR'] = os.environ['prometheus_multiproc_dir']
+                warnings.warn("prometheus_multiproc_dir variable has been deprecated in favor of the upper case naming PROMETHEUS_MULTIPROC_DIR", DeprecationWarning)
+            with lock:
+                self.__check_for_pid_change()
+                self.__reset()
+                values.append(self)
+
+        def __reset(self):
+            typ, metric_name, name, labelnames, labelvalues, help_text, multiprocess_mode = self._params
+            if typ == 'gauge':
+                file_prefix = typ + '_' + multiprocess_mode
+            else:
+                file_prefix = typ
+            if file_prefix not in files:
+                filename = os.path.join(
+                    os.environ.get('PROMETHEUS_MULTIPROC_DIR'),
+                    '{}_{}.db'.format(file_prefix, pid['value']))
+
+                files[file_prefix] = MmapedDict(filename)
+            self._file = files[file_prefix]
+            self._key = mmap_key(metric_name, name, labelnames, labelvalues, help_text)
+            self._value, self._timestamp = self._file.read_value(self._key)
+
+        def __check_for_pid_change(self):
+            actual_pid = process_identifier()
+            if pid['value'] != actual_pid:
+                pid['value'] = actual_pid
+                # There has been a fork(), reset all the values.
+                for f in files.values():
+                    f.close()
+                files.clear()
+                for value in values:
+                    value.__reset()
+
+        def inc(self, amount):
+            with lock:
+                self.__check_for_pid_change()
+                self._value += amount
+                self._timestamp = 0.0
+                self._file.write_value(self._key, self._value, self._timestamp)
+
+        def set(self, value, timestamp=None):
+            with lock:
+                self.__check_for_pid_change()
+                self._value = value
+                self._timestamp = timestamp or 0.0
+                self._file.write_value(self._key, self._value, self._timestamp)
+
+        def set_exemplar(self, exemplar):
+            # TODO: Implement exemplars for multiprocess mode.
+            return
+
+        def get(self):
+            with lock:
+                self.__check_for_pid_change()
+                return self._value
+
+        def get_exemplar(self):
+            # TODO: Implement exemplars for multiprocess mode.
+            return None
+
+        @classmethod
+        def close_all_files(cls):
+            with lock:
+                for f in files.values():
+                    f.close()
+                files.clear()
+                values.clear()
+
+    return MmapedValue
+
+
+def get_value_class():
+    # Should we enable multi-process mode?
+    # This needs to be chosen before the first metric is constructed,
+    # and as that may be in some arbitrary library the user/admin has
+    # no control over we use an environment variable.
+    if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
+        return MultiProcessValue()
+    else:
+        return MutexValue
+
+
+ValueClass = get_value_class()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE
new file mode 100644
index 00000000000..19b305b0006
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE
@@ -0,0 +1,32 @@
+Copyright 2008 Google Inc.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it.  This code is not
+standalone and requires a support library to be linked with it.  This
+support library is itself covered by the above license.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE
new file mode 100644
index 00000000000..67db8588217
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE
@@ -0,0 +1,175 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE
new file mode 100644
index 00000000000..1ff62db6882
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE
@@ -0,0 +1,2 @@
+Requests
+Copyright 2019 Kenneth Reitz
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py
new file mode 100644
index 00000000000..84d8c88a6a0
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py
@@ -0,0 +1,217 @@
+#   __
+#  /__)  _  _     _   _ _/   _
+# / (   (- (/ (/ (- _)  /  _)
+#          /
+
+"""
+Requests HTTP Library
+~~~~~~~~~~~~~~~~~~~~~
+
+Requests is an HTTP library, written in Python, for human beings.
+Basic GET usage:
+
+   >>> import requests
+   >>> r = requests.get('https://www.python.org')
+   >>> r.status_code
+   200
+   >>> b'Python is a programming language' in r.content
+   True
+
+... or POST:
+
+   >>> payload = dict(key1='value1', key2='value2')
+   >>> r = requests.post('https://httpbin.org/post', data=payload)
+   >>> print(r.text)
+   {
+     ...
+     "form": {
+       "key1": "value1",
+       "key2": "value2"
+     },
+     ...
+   }
+
+The other HTTP methods are supported - see `requests.api`. Full documentation
+is at .
+
+:copyright: (c) 2017 by Kenneth Reitz.
+:license: Apache 2.0, see LICENSE for more details.
+"""
+
+from __future__ import annotations
+
+import warnings
+
+from opentelemetry.agent._vendor import urllib3
+
+from .exceptions import RequestsDependencyWarning
+
+try:
+    from opentelemetry.agent._vendor.charset_normalizer import __version__ as charset_normalizer_version
+except ImportError:
+    charset_normalizer_version = None
+
+# Only the vendored charset_normalizer is used, never the application's chardet.
+chardet_version = None
+
+
+def check_compatibility(
+    urllib3_version: str,
+    chardet_version: str | None,
+    charset_normalizer_version: str | None,
+) -> None:
+    urllib3_version_list = urllib3_version.split(".")[:3]
+    assert urllib3_version_list != ["dev"]  # Verify urllib3 isn't installed from git.
+
+    # Sometimes, urllib3 only reports its version as 16.1.
+    if len(urllib3_version_list) == 2:
+        urllib3_version_list.append("0")
+
+    # Check urllib3 for compatibility.
+    major, minor, patch = urllib3_version_list  # noqa: F811
+    major, minor, patch = int(major), int(minor), int(patch)
+    # urllib3 >= 1.21.1
+    assert major >= 1
+    if major == 1:
+        assert minor >= 21
+
+    # Check charset_normalizer for compatibility.
+    if chardet_version:
+        major, minor, patch = chardet_version.split(".")[:3]
+        major, minor, patch = int(major), int(minor), int(patch)
+        # chardet_version >= 3.0.2, < 8.0.0
+        assert (3, 0, 2) <= (major, minor, patch) < (8, 0, 0)
+    elif charset_normalizer_version:
+        major, minor, patch = charset_normalizer_version.split(".")[:3]
+        major, minor, patch = int(major), int(minor), int(patch)
+        # charset_normalizer >= 2.0.0 < 4.0.0
+        assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0)
+    else:
+        warnings.warn(
+            "Unable to find acceptable character detection dependency "
+            "(chardet or charset_normalizer).",
+            RequestsDependencyWarning,
+        )
+
+
+def _check_cryptography(cryptography_version: str) -> None:
+    # cryptography < 1.3.4
+    try:
+        cryptography_version_list = list(map(int, cryptography_version.split(".")))
+    except ValueError:
+        return
+
+    if cryptography_version_list < [1, 3, 4]:
+        warning = f"Old version of cryptography ({cryptography_version_list}) may cause slowdown."
+        warnings.warn(warning, RequestsDependencyWarning)
+
+
+# Check imported dependencies for compatibility.
+try:
+    check_compatibility(
+        urllib3.__version__,  # type: ignore[reportPrivateImportUsage]
+        chardet_version,  # type: ignore[reportUnknownArgumentType]
+        charset_normalizer_version,
+    )
+except (AssertionError, ValueError):
+    warnings.warn(
+        f"urllib3 ({urllib3.__version__}) or chardet "  # type: ignore[reportPrivateImportUsage]
+        f"({chardet_version})/charset_normalizer ({charset_normalizer_version}) "
+        "doesn't match a supported version!",
+        RequestsDependencyWarning,
+    )
+
+# Attempt to enable urllib3's fallback for SNI support
+# if the standard library doesn't support SNI or the
+# 'ssl' library isn't available.
+try:
+    try:
+        import ssl
+    except ImportError:
+        ssl = None
+
+    if not getattr(ssl, "HAS_SNI", False):
+        from opentelemetry.agent._vendor.urllib3.contrib import pyopenssl
+
+        pyopenssl.inject_into_urllib3()
+
+        # Check cryptography version
+        from cryptography import (  # type: ignore[reportMissingImports]
+            __version__ as cryptography_version,  # type: ignore[reportUnknownVariableType]
+        )
+
+        _check_cryptography(cryptography_version)  # type: ignore[reportUnknownArgumentType]
+except ImportError:
+    pass
+
+# urllib3's DependencyWarnings should be silenced.
+from opentelemetry.agent._vendor.urllib3.exceptions import DependencyWarning
+
+warnings.simplefilter("ignore", DependencyWarning)
+
+# Set default logging handler to avoid "No handler found" warnings.
+import logging
+from logging import NullHandler
+
+from . import packages, utils
+from .__version__ import (
+    __author__,
+    __author_email__,
+    __build__,
+    __cake__,
+    __copyright__,
+    __description__,
+    __license__,
+    __title__,
+    __url__,
+    __version__,
+)
+from .api import delete, get, head, options, patch, post, put, request
+from .exceptions import (
+    ConnectionError,
+    ConnectTimeout,
+    FileModeWarning,
+    HTTPError,
+    JSONDecodeError,
+    ReadTimeout,
+    RequestException,
+    Timeout,
+    TooManyRedirects,
+    URLRequired,
+)
+from .models import PreparedRequest, Request, Response
+from .sessions import Session, session
+from .status_codes import codes
+
+__all__ = (
+    "ConnectionError",
+    "ConnectTimeout",
+    "HTTPError",
+    "JSONDecodeError",
+    "PreparedRequest",
+    "ReadTimeout",
+    "Request",
+    "RequestException",
+    "Response",
+    "Session",
+    "Timeout",
+    "TooManyRedirects",
+    "URLRequired",
+    "codes",
+    "delete",
+    "get",
+    "head",
+    "options",
+    "packages",
+    "patch",
+    "post",
+    "put",
+    "request",
+    "session",
+    "utils",
+)
+
+logging.getLogger(__name__).addHandler(NullHandler())
+
+# FileModeWarnings go off per the default.
+warnings.simplefilter("default", FileModeWarning, append=True)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py
new file mode 100644
index 00000000000..fea814e5827
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py
@@ -0,0 +1,14 @@
+# .-. .-. .-. . . .-. .-. .-. .-.
+# |(  |-  |.| | | |-  `-.  |  `-.
+# ' ' `-' `-`.`-' `-' `-'  '  `-'
+
+__title__ = "requests"
+__description__ = "Python HTTP for Humans."
+__url__ = "https://requests.readthedocs.io"
+__version__ = "2.34.2"
+__build__ = 0x023402
+__author__ = "Kenneth Reitz"
+__author_email__ = "me@kennethreitz.org"
+__license__ = "Apache-2.0"
+__copyright__ = "Copyright Kenneth Reitz"
+__cake__ = "\u2728 \U0001f370 \u2728"
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py
new file mode 100644
index 00000000000..0466a7d347d
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py
@@ -0,0 +1,51 @@
+"""
+requests._internal_utils
+~~~~~~~~~~~~~~
+
+Provides utility functions that are consumed internally by Requests
+which depend on extremely few external helpers (such as compat)
+"""
+
+import re
+
+from .compat import builtin_str
+
+_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*\Z")
+_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*\Z")
+_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*\Z|^\Z")
+_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*\Z|^\Z")
+
+_HEADER_VALIDATORS_STR = (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR)
+_HEADER_VALIDATORS_BYTE = (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE)
+HEADER_VALIDATORS = {
+    bytes: _HEADER_VALIDATORS_BYTE,
+    str: _HEADER_VALIDATORS_STR,
+}
+
+
+def to_native_string(string: str | bytes, encoding: str = "ascii") -> str:
+    """Given a string object, regardless of type, returns a representation of
+    that string in the native string type, encoding and decoding where
+    necessary. This assumes ASCII unless told otherwise.
+    """
+    if isinstance(string, builtin_str):
+        out = string
+    else:
+        out = string.decode(encoding)
+
+    return out
+
+
+def unicode_is_ascii(u_string: str) -> bool:
+    """Determine if unicode string only contains ASCII characters.
+
+    :param str u_string: unicode string to check. Must be unicode
+        and not Python 2 `str`.
+    :rtype: bool
+    """
+    assert isinstance(u_string, str)
+    try:
+        u_string.encode("ascii")
+        return True
+    except UnicodeEncodeError:
+        return False
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py
new file mode 100644
index 00000000000..48ddfaafcf3
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py
@@ -0,0 +1,183 @@
+"""
+requests._types
+~~~~~~~~~~~~~~~
+
+This module contains type aliases used internally by the Requests library.
+These types are not part of the public API and must not be relied upon
+by external code.
+"""
+
+from __future__ import annotations
+
+from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Protocol,
+    TypeAlias,
+    TypeVar,
+    runtime_checkable,
+)
+
+_T_co = TypeVar("_T_co", covariant=True)
+_KT_co = TypeVar("_KT_co", covariant=True)
+_VT_co = TypeVar("_VT_co", covariant=True)
+
+
+@runtime_checkable
+class SupportsRead(Protocol[_T_co]):
+    def read(self, length: int = ..., /) -> _T_co: ...
+
+
+@runtime_checkable
+class SupportsItems(Protocol[_KT_co, _VT_co]):
+    def items(self) -> Iterable[tuple[_KT_co, _VT_co]]: ...
+
+
+# These are needed at runtime for default_hooks() return type
+HookType: TypeAlias = Callable[["Response"], Any]
+HooksInputType: TypeAlias = Mapping[str, Iterable[HookType] | HookType]
+
+
+def is_prepared(request: PreparedRequest) -> TypeIs[_ValidatedRequest]:
+    """Verify a PreparedRequest has been fully prepared."""
+    if TYPE_CHECKING:
+        return request.url is not None and request.method is not None
+    # noop at runtime to avoid AssertionError
+    return True
+
+
+if TYPE_CHECKING:
+    from http.cookiejar import CookieJar
+    from typing import TypeAlias, TypedDict
+
+    from opentelemetry.agent._vendor.typing_extensions import (
+        Buffer,  # TODO: move to collections.abc when Python >= 3.12
+        TypeIs,  # TODO: move to typing when Python >= 3.13
+    )
+
+    from .auth import AuthBase
+    from .cookies import RequestsCookieJar
+    from .models import PreparedRequest, Response
+    from .structures import CaseInsensitiveDict
+
+    class _ValidatedRequest(PreparedRequest):
+        """Subtype asserting a PreparedRequest has been fully prepared before calling.
+
+        The override suppression is required because mutable attribute types are
+        invariant (Liskov), but we only narrow after preparation is complete. This
+        is the explicit contract for Requests but Python's typing doesn't have a
+        better way to represent the requirement.
+        """
+
+        url: str  # type: ignore[reportIncompatibleVariableOverride]
+        method: str  # type: ignore[reportIncompatibleVariableOverride]
+
+    # Type aliases for core API concepts (ordered by request() signature)
+    UriType: TypeAlias = str | bytes
+
+    _ParamsMappingKeyType: TypeAlias = str | bytes | int | float
+    _ParamsMappingValueType: TypeAlias = (
+        str | bytes | int | float | Iterable[str | bytes | int | float] | None
+    )
+    ParamsType: TypeAlias = (
+        SupportsItems[_ParamsMappingKeyType, _ParamsMappingValueType]
+        | tuple[tuple[_ParamsMappingKeyType, _ParamsMappingValueType], ...]
+        | Iterable[tuple[_ParamsMappingKeyType, _ParamsMappingValueType]]
+        | str
+        | bytes
+        | None
+    )
+
+    KVDataType: TypeAlias = Iterable[tuple[Any, Any]] | SupportsItems[Any, Any]
+
+    RawDataType: TypeAlias = KVDataType | str | bytes
+    StreamDataType: TypeAlias = SupportsRead[str | bytes]
+    EncodableDataType: TypeAlias = RawDataType | StreamDataType
+
+    DataType: TypeAlias = (
+        KVDataType
+        | Iterable[bytes | str]
+        | str
+        | bytes
+        | Buffer
+        | SupportsRead[str | bytes]
+        | None
+    )
+
+    BodyType: TypeAlias = (
+        bytes | str | Iterable[bytes | str] | SupportsRead[bytes | str] | None
+    )
+
+    HeadersType: TypeAlias = Mapping[str, str | bytes] | None
+
+    CookiesType: TypeAlias = RequestsCookieJar | Mapping[str, str]
+
+    # Building blocks for FilesType
+    _FileName: TypeAlias = str | None
+    _FileContent: TypeAlias = SupportsRead[str | bytes] | str | bytes
+    _FileSpecBasic: TypeAlias = tuple[_FileName, _FileContent]
+    _FileSpecWithContentType: TypeAlias = tuple[_FileName, _FileContent, str]
+    _FileSpecWithHeaders: TypeAlias = tuple[
+        _FileName, _FileContent, str, CaseInsensitiveDict[str] | Mapping[str, str]
+    ]
+    _FileSpec: TypeAlias = (
+        _FileContent | _FileSpecBasic | _FileSpecWithContentType | _FileSpecWithHeaders
+    )
+    FilesType: TypeAlias = (
+        Mapping[str, _FileSpec] | Iterable[tuple[str, _FileSpec]] | None
+    )
+
+    AuthType: TypeAlias = (
+        tuple[str, str] | AuthBase | Callable[[PreparedRequest], PreparedRequest] | None
+    )
+
+    TimeoutType: TypeAlias = float | tuple[float | None, float | None] | None
+    ProxiesType: TypeAlias = MutableMapping[str, str]
+    HooksType: TypeAlias = dict[str, list[HookType]] | None
+    VerifyType: TypeAlias = bool | str
+    CertType: TypeAlias = str | tuple[str, str] | None
+    JsonType: TypeAlias = (
+        None
+        | bool
+        | int
+        | float
+        | str
+        | Sequence["JsonType"]
+        | Mapping[str, "JsonType"]
+    )
+
+    # TypedDicts for Unpack kwargs (PEP 692)
+
+    class BaseRequestKwargs(TypedDict, total=False):
+        headers: HeadersType
+        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
+        files: FilesType
+        auth: AuthType
+        timeout: TimeoutType
+        allow_redirects: bool
+        proxies: dict[str, str] | None
+        hooks: HooksInputType | None
+        stream: bool | None
+        verify: VerifyType | None
+        cert: CertType
+
+    class RequestKwargs(BaseRequestKwargs, total=False):
+        """kwargs for request(), options(), head(), delete()."""
+
+        params: ParamsType
+        data: DataType
+        json: JsonType
+
+    class GetKwargs(BaseRequestKwargs, total=False):
+        data: DataType
+        json: JsonType
+
+    class PostKwargs(BaseRequestKwargs, total=False):
+        params: ParamsType
+
+    class DataKwargs(BaseRequestKwargs, total=False):
+        """kwargs for put(), patch()."""
+
+        params: ParamsType
+        json: JsonType
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py
new file mode 100644
index 00000000000..03bf43137e7
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py
@@ -0,0 +1,748 @@
+"""
+requests.adapters
+~~~~~~~~~~~~~~~~~
+
+This module contains the transport adapters that Requests uses to define
+and maintain connections.
+"""
+
+from __future__ import annotations
+
+import os.path
+import socket  # noqa: F401  # type: ignore[reportUnusedImport]
+import typing
+import warnings
+from typing import Any
+
+from opentelemetry.agent._vendor.urllib3.exceptions import (
+    ClosedPoolError,
+    ConnectTimeoutError,
+    LocationValueError,
+    MaxRetryError,
+    NewConnectionError,
+    ProtocolError,
+    ReadTimeoutError,
+    ResponseError,
+)
+from opentelemetry.agent._vendor.urllib3.exceptions import HTTPError as _HTTPError
+from opentelemetry.agent._vendor.urllib3.exceptions import InvalidHeader as _InvalidHeader
+from opentelemetry.agent._vendor.urllib3.exceptions import ProxyError as _ProxyError
+from opentelemetry.agent._vendor.urllib3.exceptions import SSLError as _SSLError
+from opentelemetry.agent._vendor.urllib3.poolmanager import PoolManager, proxy_from_url
+from opentelemetry.agent._vendor.urllib3.util import Timeout as TimeoutSauce
+from opentelemetry.agent._vendor.urllib3.util import parse_url
+from opentelemetry.agent._vendor.urllib3.util.retry import Retry
+
+from .auth import _basic_auth_str  # type: ignore[reportPrivateUsage]
+from .compat import basestring, urlparse
+from .cookies import extract_cookies_to_jar
+from .exceptions import (
+    ConnectionError,
+    ConnectTimeout,
+    InvalidHeader,
+    InvalidProxyURL,
+    InvalidSchema,
+    InvalidURL,
+    ProxyError,
+    ReadTimeout,
+    RetryError,
+    SSLError,
+)
+from .models import Response
+from .structures import CaseInsensitiveDict
+from .utils import (
+    DEFAULT_CA_BUNDLE_PATH,
+    get_auth_from_url,
+    get_encoding_from_headers,
+    prepend_scheme_if_needed,
+    select_proxy,
+    urldefragauth,
+)
+
+try:
+    from opentelemetry.agent._vendor.urllib3.contrib.socks import SOCKSProxyManager  # type: ignore[assignment]
+except ImportError:
+
+    def SOCKSProxyManager(*args: Any, **kwargs: Any) -> None:
+        raise InvalidSchema("Missing dependencies for SOCKS support.")
+
+
+if typing.TYPE_CHECKING:
+    from opentelemetry.agent._vendor.urllib3.connectionpool import HTTPConnectionPool
+    from opentelemetry.agent._vendor.urllib3.poolmanager import PoolManager as _PoolManager
+
+    from . import _types as _t
+    from .models import PreparedRequest
+
+from ._types import is_prepared as _is_prepared
+
+DEFAULT_POOLBLOCK = False
+DEFAULT_POOLSIZE = 10
+DEFAULT_RETRIES = 0
+DEFAULT_POOL_TIMEOUT = None
+
+
+def _urllib3_request_context(
+    request: PreparedRequest,
+    verify: bool | str | None,
+    client_cert: tuple[str, str] | str | None,
+    poolmanager: PoolManager,
+) -> tuple[dict[str, Any], dict[str, Any]]:
+    host_params: dict[str, Any] = {}
+    pool_kwargs: dict[str, Any] = {}
+    parsed_request_url = urlparse(request.url)
+    scheme = parsed_request_url.scheme.lower()
+    port = parsed_request_url.port
+
+    cert_reqs = "CERT_REQUIRED"
+    if verify is False:
+        cert_reqs = "CERT_NONE"
+    elif isinstance(verify, str):
+        if not os.path.isdir(verify):
+            pool_kwargs["ca_certs"] = verify
+        else:
+            pool_kwargs["ca_cert_dir"] = verify
+    pool_kwargs["cert_reqs"] = cert_reqs
+    if client_cert is not None:
+        if isinstance(client_cert, tuple) and len(client_cert) == 2:
+            pool_kwargs["cert_file"] = client_cert[0]
+            pool_kwargs["key_file"] = client_cert[1]
+        else:
+            # According to our docs, we allow users to specify just the client
+            # cert path
+            pool_kwargs["cert_file"] = client_cert
+    host_params = {
+        "scheme": scheme,
+        "host": parsed_request_url.hostname,
+        "port": port,
+    }
+    return host_params, pool_kwargs
+
+
+class BaseAdapter:
+    """The Base Transport Adapter"""
+
+    def __init__(self) -> None:
+        super().__init__()
+
+    def send(
+        self,
+        request: PreparedRequest,
+        stream: bool = False,
+        timeout: _t.TimeoutType = None,
+        verify: _t.VerifyType = True,
+        cert: _t.CertType = None,
+        proxies: dict[str, str] | None = None,
+    ) -> Response:
+        """Sends PreparedRequest object. Returns Response object.
+
+        :param request: The :class:`PreparedRequest ` being sent.
+        :param stream: (optional) Whether to stream the request content.
+        :param timeout: (optional) How long to wait for the server to send
+            data before giving up, as a float, or a :ref:`(connect timeout,
+            read timeout) ` tuple.
+        :type timeout: float or tuple
+        :param verify: (optional) Either a boolean, in which case it controls whether we verify
+            the server's TLS certificate, or a string, in which case it must be a path
+            to a CA bundle to use
+        :param cert: (optional) Any user-provided SSL certificate to be trusted.
+        :param proxies: (optional) The proxies dictionary to apply to the request.
+        """
+        raise NotImplementedError
+
+    def close(self) -> None:
+        """Cleans up adapter specific items."""
+        raise NotImplementedError
+
+
+class HTTPAdapter(BaseAdapter):
+    """The built-in HTTP Adapter for urllib3.
+
+    Provides a general-case interface for Requests sessions to contact HTTP and
+    HTTPS urls by implementing the Transport Adapter interface. This class will
+    usually be created by the :class:`Session ` class under the
+    covers.
+
+    :param pool_connections: The number of urllib3 connection pools to cache.
+    :param pool_maxsize: The maximum number of connections to save in the pool.
+    :param max_retries: The maximum number of retries each connection
+        should attempt. Note, this applies only to failed DNS lookups, socket
+        connections and connection timeouts, never to requests where data has
+        made it to the server. By default, Requests does not retry failed
+        connections. If you need granular control over the conditions under
+        which we retry a request, import urllib3's ``Retry`` class and pass
+        that instead.
+    :param pool_block: Whether the connection pool should block for connections.
+
+    Usage::
+
+      >>> import requests
+      >>> s = requests.Session()
+      >>> a = requests.adapters.HTTPAdapter(max_retries=3)
+      >>> s.mount('http://', a)
+    """
+
+    __attrs__: list[str] = [
+        "max_retries",
+        "config",
+        "_pool_connections",
+        "_pool_maxsize",
+        "_pool_block",
+    ]
+
+    max_retries: Retry
+    config: dict[str, Any]
+    proxy_manager: dict[str, Any]
+    _pool_connections: int
+    _pool_maxsize: int
+    _pool_block: bool
+    poolmanager: _PoolManager
+
+    def __init__(
+        self,
+        pool_connections: int = DEFAULT_POOLSIZE,
+        pool_maxsize: int = DEFAULT_POOLSIZE,
+        max_retries: int | Retry = DEFAULT_RETRIES,
+        pool_block: bool = DEFAULT_POOLBLOCK,
+    ) -> None:
+        if max_retries == DEFAULT_RETRIES:
+            self.max_retries = Retry(0, read=False)
+        else:
+            self.max_retries = Retry.from_int(max_retries)
+        self.config = {}
+        self.proxy_manager = {}
+
+        super().__init__()
+
+        self._pool_connections = pool_connections
+        self._pool_maxsize = pool_maxsize
+        self._pool_block = pool_block
+
+        self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
+
+    def __getstate__(self) -> dict[str, Any]:
+        return {attr: getattr(self, attr, None) for attr in self.__attrs__}
+
+    def __setstate__(self, state: dict[str, Any]) -> None:
+        # Can't handle by adding 'proxy_manager' to self.__attrs__ because
+        # self.poolmanager uses a lambda function, which isn't pickleable.
+        self.proxy_manager = {}
+        self.config = {}
+
+        for attr, value in state.items():
+            setattr(self, attr, value)
+
+        self.init_poolmanager(
+            self._pool_connections, self._pool_maxsize, block=self._pool_block
+        )
+
+    def init_poolmanager(
+        self,
+        connections: int,
+        maxsize: int,
+        block: bool = DEFAULT_POOLBLOCK,
+        **pool_kwargs: Any,
+    ) -> None:
+        """Initializes a urllib3 PoolManager.
+
+        This method should not be called from user code, and is only
+        exposed for use when subclassing the
+        :class:`HTTPAdapter `.
+
+        :param connections: The number of urllib3 connection pools to cache.
+        :param maxsize: The maximum number of connections to save in the pool.
+        :param block: Block when no free connections are available.
+        :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
+        """
+        # save these values for pickling
+        self._pool_connections = connections
+        self._pool_maxsize = maxsize
+        self._pool_block = block
+
+        self.poolmanager = PoolManager(
+            num_pools=connections,
+            maxsize=maxsize,
+            block=block,
+            **pool_kwargs,
+        )
+
+    def proxy_manager_for(self, proxy: str, **proxy_kwargs: Any) -> Any:
+        """Return urllib3 ProxyManager for the given proxy.
+
+        This method should not be called from user code, and is only
+        exposed for use when subclassing the
+        :class:`HTTPAdapter `.
+
+        :param proxy: The proxy to return a urllib3 ProxyManager for.
+        :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
+        :returns: ProxyManager
+        :rtype: urllib3.ProxyManager
+        """
+        if proxy in self.proxy_manager:
+            manager = self.proxy_manager[proxy]
+        elif proxy.lower().startswith("socks"):
+            username, password = get_auth_from_url(proxy)
+            manager = self.proxy_manager[proxy] = SOCKSProxyManager(
+                proxy,
+                username=username,
+                password=password,
+                num_pools=self._pool_connections,
+                maxsize=self._pool_maxsize,
+                block=self._pool_block,
+                **proxy_kwargs,
+            )
+        else:
+            proxy_headers = self.proxy_headers(proxy)
+            manager = self.proxy_manager[proxy] = proxy_from_url(
+                proxy,
+                proxy_headers=proxy_headers,
+                num_pools=self._pool_connections,
+                maxsize=self._pool_maxsize,
+                block=self._pool_block,
+                **proxy_kwargs,
+            )
+
+        return manager
+
+    def cert_verify(
+        self, conn: Any, url: str, verify: _t.VerifyType, cert: _t.CertType
+    ) -> None:
+        """Verify a SSL certificate. This method should not be called from user
+        code, and is only exposed for use when subclassing the
+        :class:`HTTPAdapter `.
+
+        :param conn: The urllib3 connection object associated with the cert.
+        :param url: The requested URL.
+        :param verify: Either a boolean, in which case it controls whether we verify
+            the server's TLS certificate, or a string, in which case it must be a path
+            to a CA bundle to use
+        :param cert: The SSL certificate to verify.
+        """
+        if url.lower().startswith("https") and verify:
+            cert_loc = None
+
+            # Allow self-specified cert location.
+            if verify is not True:
+                cert_loc = verify
+
+            if not cert_loc:
+                cert_loc = DEFAULT_CA_BUNDLE_PATH
+
+            if not cert_loc or not os.path.exists(cert_loc):
+                raise OSError(
+                    f"Could not find a suitable TLS CA certificate bundle, "
+                    f"invalid path: {cert_loc}"
+                )
+
+            conn.cert_reqs = "CERT_REQUIRED"
+
+            if not os.path.isdir(cert_loc):
+                conn.ca_certs = cert_loc
+            else:
+                conn.ca_cert_dir = cert_loc
+        else:
+            conn.cert_reqs = "CERT_NONE"
+            conn.ca_certs = None
+            conn.ca_cert_dir = None
+
+        if cert:
+            if not isinstance(cert, basestring):
+                conn.cert_file = cert[0]
+                conn.key_file = cert[1]
+            else:
+                conn.cert_file = cert
+                conn.key_file = None
+            if conn.cert_file and not os.path.exists(conn.cert_file):
+                raise OSError(
+                    f"Could not find the TLS certificate file, "
+                    f"invalid path: {conn.cert_file}"
+                )
+            if conn.key_file and not os.path.exists(conn.key_file):
+                raise OSError(
+                    f"Could not find the TLS key file, invalid path: {conn.key_file}"
+                )
+
+    def build_response(self, req: PreparedRequest, resp: Any) -> Response:
+        """Builds a :class:`Response ` object from a urllib3
+        response. This should not be called from user code, and is only exposed
+        for use when subclassing the
+        :class:`HTTPAdapter `
+
+        :param req: The :class:`PreparedRequest ` used to generate the response.
+        :param resp: The urllib3 response object.
+        :rtype: requests.Response
+        """
+        assert _is_prepared(req)
+        response = Response()
+
+        # Fallback to None if there's no status_code, for whatever reason.
+        response.status_code = getattr(resp, "status", None)  # type: ignore[assignment]
+
+        # Make headers case-insensitive.
+        response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
+
+        # Set encoding.
+        response.encoding = get_encoding_from_headers(response.headers)
+        response.raw = resp
+        response.reason = response.raw.reason
+
+        if isinstance(req.url, bytes):
+            response.url = req.url.decode("utf-8")
+        else:
+            response.url = req.url
+
+        # Add new cookies from the server.
+        extract_cookies_to_jar(response.cookies, req, resp)
+
+        # Give the Response some context.
+        response.request = req
+        response.connection = self
+
+        return response
+
+    def build_connection_pool_key_attributes(
+        self, request: PreparedRequest, verify: _t.VerifyType, cert: _t.CertType = None
+    ) -> tuple[dict[str, Any], dict[str, Any]]:
+        """Build the PoolKey attributes used by urllib3 to return a connection.
+
+        This looks at the PreparedRequest, the user-specified verify value,
+        and the value of the cert parameter to determine what PoolKey values
+        to use to select a connection from a given urllib3 Connection Pool.
+
+        The SSL related pool key arguments are not consistently set. As of
+        this writing, use the following to determine what keys may be in that
+        dictionary:
+
+        * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the
+          default Requests SSL Context
+        * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but
+          ``"cert_reqs"`` will be set
+        * If ``verify`` is a string, (i.e., it is a user-specified trust bundle)
+          ``"ca_certs"`` will be set if the string is not a directory recognized
+          by :py:func:`os.path.isdir`, otherwise ``"ca_cert_dir"`` will be
+          set.
+        * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If
+          ``"cert"`` is a tuple with a second item, ``"key_file"`` will also
+          be present
+
+        To override these settings, one may subclass this class, call this
+        method and use the above logic to change parameters as desired. For
+        example, if one wishes to use a custom :py:class:`ssl.SSLContext` one
+        must both set ``"ssl_context"`` and based on what else they require,
+        alter the other keys to ensure the desired behaviour.
+
+        :param request:
+            The PreparedRequest being sent over the connection.
+        :type request:
+            :class:`~requests.models.PreparedRequest`
+        :param verify:
+            Either a boolean, in which case it controls whether
+            we verify the server's TLS certificate, or a string, in which case it
+            must be a path to a CA bundle to use.
+        :param cert:
+            (optional) Any user-provided SSL certificate for client
+            authentication (a.k.a., mTLS). This may be a string (i.e., just
+            the path to a file which holds both certificate and key) or a
+            tuple of length 2 with the certificate file path and key file
+            path.
+        :returns:
+            A tuple of two dictionaries. The first is the "host parameters"
+            portion of the Pool Key including scheme, hostname, and port. The
+            second is a dictionary of SSLContext related parameters.
+        """
+        return _urllib3_request_context(request, verify, cert, self.poolmanager)
+
+    def get_connection_with_tls_context(
+        self,
+        request: PreparedRequest,
+        verify: _t.VerifyType,
+        proxies: dict[str, str] | None = None,
+        cert: _t.CertType = None,
+    ) -> HTTPConnectionPool:
+        """Returns a urllib3 connection for the given request and TLS settings.
+        This should not be called from user code, and is only exposed for use
+        when subclassing the :class:`HTTPAdapter `.
+
+        :param request:
+            The :class:`PreparedRequest ` object to be sent
+            over the connection.
+        :param verify:
+            Either a boolean, in which case it controls whether we verify the
+            server's TLS certificate, or a string, in which case it must be a
+            path to a CA bundle to use.
+        :param proxies:
+            (optional) The proxies dictionary to apply to the request.
+        :param cert:
+            (optional) Any user-provided SSL certificate to be used for client
+            authentication (a.k.a., mTLS).
+        :rtype:
+            urllib3.HTTPConnectionPool
+        """
+        assert _is_prepared(request)
+
+        proxy = select_proxy(request.url, proxies)
+        try:
+            host_params, pool_kwargs = self.build_connection_pool_key_attributes(
+                request,
+                verify,
+                cert,
+            )
+        except ValueError as e:
+            raise InvalidURL(e, request=request)
+        if proxy:
+            proxy = prepend_scheme_if_needed(proxy, "http")
+            proxy_url = parse_url(proxy)
+            if not proxy_url.host:
+                raise InvalidProxyURL(
+                    "Please check proxy URL. It is malformed "
+                    "and could be missing the host."
+                )
+            proxy_manager = self.proxy_manager_for(proxy)
+            conn = proxy_manager.connection_from_host(
+                **host_params, pool_kwargs=pool_kwargs
+            )
+        else:
+            # Only scheme should be lower case
+            conn = self.poolmanager.connection_from_host(
+                **host_params, pool_kwargs=pool_kwargs
+            )
+
+        return conn
+
+    def get_connection(
+        self, url: str, proxies: dict[str, str] | None = None
+    ) -> HTTPConnectionPool:
+        """DEPRECATED: Users should move to `get_connection_with_tls_context`
+        for all subclasses of HTTPAdapter using Requests>=2.32.2.
+
+        Returns a urllib3 connection for the given URL. This should not be
+        called from user code, and is only exposed for use when subclassing the
+        :class:`HTTPAdapter `.
+
+        :param url: The URL to connect to.
+        :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
+        :rtype: urllib3.HTTPConnectionPool
+        """
+        warnings.warn(
+            (
+                "`get_connection` has been deprecated in favor of "
+                "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses "
+                "will need to migrate for Requests>=2.32.2. Please see "
+                "https://github.com/psf/requests/pull/6710 for more details."
+            ),
+            DeprecationWarning,
+        )
+        proxy = select_proxy(url, proxies)
+
+        if proxy:
+            proxy = prepend_scheme_if_needed(proxy, "http")
+            proxy_url = parse_url(proxy)
+            if not proxy_url.host:
+                raise InvalidProxyURL(
+                    "Please check proxy URL. It is malformed "
+                    "and could be missing the host."
+                )
+            proxy_manager = self.proxy_manager_for(proxy)
+            conn = proxy_manager.connection_from_url(url)
+        else:
+            # Only scheme should be lower case
+            parsed = urlparse(url)
+            url = parsed.geturl()
+            conn = self.poolmanager.connection_from_url(url)
+
+        return conn
+
+    def close(self) -> None:
+        """Disposes of any internal state.
+
+        Currently, this closes the PoolManager and any active ProxyManager,
+        which closes any pooled connections.
+        """
+        self.poolmanager.clear()
+        for proxy in self.proxy_manager.values():
+            proxy.clear()
+
+    def request_url(
+        self, request: PreparedRequest, proxies: dict[str, str] | None
+    ) -> str:
+        """Obtain the url to use when making the final request.
+
+        If the message is being sent through a HTTP proxy, the full URL has to
+        be used. Otherwise, we should only use the path portion of the URL.
+
+        This should not be called from user code, and is only exposed for use
+        when subclassing the
+        :class:`HTTPAdapter `.
+
+        :param request: The :class:`PreparedRequest ` being sent.
+        :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
+        :rtype: str
+        """
+        assert _is_prepared(request)
+
+        proxy = select_proxy(request.url, proxies)
+        scheme = urlparse(request.url).scheme
+
+        is_proxied_http_request = proxy and scheme != "https"
+        using_socks_proxy = False
+        if proxy:
+            proxy_scheme = urlparse(proxy).scheme.lower()
+            using_socks_proxy = proxy_scheme.startswith("socks")
+
+        url = request.path_url
+
+        if is_proxied_http_request and not using_socks_proxy:
+            url = urldefragauth(request.url)
+
+        return url
+
+    def add_headers(self, request: PreparedRequest, **kwargs: Any) -> None:
+        """Add any headers needed by the connection. As of v2.0 this does
+        nothing by default, but is left for overriding by users that subclass
+        the :class:`HTTPAdapter `.
+
+        This should not be called from user code, and is only exposed for use
+        when subclassing the
+        :class:`HTTPAdapter `.
+
+        :param request: The :class:`PreparedRequest ` to add headers to.
+        :param kwargs: The keyword arguments from the call to send().
+        """
+        pass
+
+    def proxy_headers(self, proxy: str) -> dict[str, str]:
+        """Returns a dictionary of the headers to add to any request sent
+        through a proxy. This works with urllib3 magic to ensure that they are
+        correctly sent to the proxy, rather than in a tunnelled request if
+        CONNECT is being used.
+
+        This should not be called from user code, and is only exposed for use
+        when subclassing the
+        :class:`HTTPAdapter `.
+
+        :param proxy: The url of the proxy being used for this request.
+        :rtype: dict
+        """
+        headers: dict[str, str] = {}
+        username, password = get_auth_from_url(proxy)
+
+        if username:
+            headers["Proxy-Authorization"] = _basic_auth_str(username, password)
+
+        return headers
+
+    def send(
+        self,
+        request: PreparedRequest,
+        stream: bool = False,
+        timeout: _t.TimeoutType = None,
+        verify: _t.VerifyType = True,
+        cert: _t.CertType = None,
+        proxies: dict[str, str] | None = None,
+    ) -> Response:
+        """Sends PreparedRequest object. Returns Response object.
+
+        :param request: The :class:`PreparedRequest ` being sent.
+        :param stream: (optional) Whether to stream the request content.
+        :param timeout: (optional) How long to wait for the server to send
+            data before giving up, as a float, or a :ref:`(connect timeout,
+            read timeout) ` tuple.
+        :type timeout: float or tuple or urllib3 Timeout object
+        :param verify: (optional) Either a boolean, in which case it controls whether
+            we verify the server's TLS certificate, or a string, in which case it
+            must be a path to a CA bundle to use
+        :param cert: (optional) Any user-provided SSL certificate to be trusted.
+        :param proxies: (optional) The proxies dictionary to apply to the request.
+        :rtype: requests.Response
+        """
+
+        assert _is_prepared(request)
+
+        try:
+            conn = self.get_connection_with_tls_context(
+                request, verify, proxies=proxies, cert=cert
+            )
+        except LocationValueError as e:
+            raise InvalidURL(e, request=request)
+
+        self.cert_verify(conn, request.url, verify, cert)
+        url = self.request_url(request, proxies)
+        self.add_headers(
+            request,
+            stream=stream,
+            timeout=timeout,
+            verify=verify,
+            cert=cert,
+            proxies=proxies,
+        )
+
+        chunked = not (request.body is None or "Content-Length" in request.headers)
+
+        if isinstance(timeout, tuple):
+            try:
+                connect, read = timeout
+                resolved_timeout = TimeoutSauce(connect=connect, read=read)
+            except ValueError:
+                raise ValueError(
+                    f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
+                    f"or a single float to set both timeouts to the same value."
+                )
+        elif isinstance(timeout, TimeoutSauce):
+            resolved_timeout = timeout
+        else:
+            resolved_timeout = TimeoutSauce(connect=timeout, read=timeout)
+
+        try:
+            resp = conn.urlopen(
+                method=request.method,
+                url=url,
+                body=request.body,  # type: ignore[arg-type]  # urllib3 stubs don't accept Iterable[bytes | str]
+                headers=request.headers,  # type: ignore[arg-type]  # urllib3#3072
+                redirect=False,
+                assert_same_host=False,
+                preload_content=False,
+                decode_content=False,
+                retries=self.max_retries,
+                timeout=resolved_timeout,
+                chunked=chunked,
+            )
+
+        except (ProtocolError, OSError) as err:
+            raise ConnectionError(err, request=request)
+
+        except MaxRetryError as e:
+            if isinstance(e.reason, ConnectTimeoutError):
+                # TODO: Remove this in 3.0.0: see #2811
+                if not isinstance(e.reason, NewConnectionError):
+                    raise ConnectTimeout(e, request=request)
+
+            if isinstance(e.reason, ResponseError):
+                raise RetryError(e, request=request)
+
+            if isinstance(e.reason, _ProxyError):
+                raise ProxyError(e, request=request)
+
+            if isinstance(e.reason, _SSLError):
+                # This branch is for urllib3 v1.22 and later.
+                raise SSLError(e, request=request)
+
+            raise ConnectionError(e, request=request)
+
+        except ClosedPoolError as e:
+            raise ConnectionError(e, request=request)
+
+        except _ProxyError as e:
+            raise ProxyError(e)
+
+        except (_SSLError, _HTTPError) as e:
+            if isinstance(e, _SSLError):
+                # This branch is for urllib3 versions earlier than v1.22
+                raise SSLError(e, request=request)
+            elif isinstance(e, ReadTimeoutError):
+                raise ReadTimeout(e, request=request)
+            elif isinstance(e, _InvalidHeader):
+                raise InvalidHeader(e, request=request)
+            else:
+                raise
+
+        return self.build_response(request, resp)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py
new file mode 100644
index 00000000000..5b3cf13f4b9
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py
@@ -0,0 +1,180 @@
+"""
+requests.api
+~~~~~~~~~~~~
+
+This module implements the Requests API.
+
+:copyright: (c) 2012 by Kenneth Reitz.
+:license: Apache2, see LICENSE for more details.
+"""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+from . import sessions
+from .models import Response
+
+if TYPE_CHECKING:
+    from opentelemetry.agent._vendor.typing_extensions import Unpack
+
+    from . import _types as _t
+
+
+def request(
+    method: str, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]
+) -> Response:
+    """Constructs and sends a :class:`Request `.
+
+    :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
+    :param url: URL for the new :class:`Request` object.
+    :param params: (optional) Dictionary, list of tuples or bytes to send
+        in the query string for the :class:`Request`.
+    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+        object to send in the body of the :class:`Request`.
+    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
+    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
+    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
+        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
+        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content_type'`` is a string
+        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
+        to add for the file.
+    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
+    :param timeout: (optional) How many seconds to wait for the server to send data
+        before giving up, as a float, or a :ref:`(connect timeout, read
+        timeout) ` tuple.
+    :type timeout: float or tuple
+    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
+    :type allow_redirects: bool
+    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
+    :param verify: (optional) Either a boolean, in which case it controls whether we verify
+            the server's TLS certificate, or a string, in which case it must be a path
+            to a CA bundle to use. Defaults to ``True``.
+    :param stream: (optional) if ``False``, the response content will be immediately downloaded.
+    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+
+    Usage::
+
+      >>> import requests
+      >>> req = requests.request('GET', 'https://httpbin.org/get')
+      >>> req
+      
+    """
+
+    # By using the 'with' statement we are sure the session is closed, thus we
+    # avoid leaving sockets open which can trigger a ResourceWarning in some
+    # cases, and look like a memory leak in others.
+    with sessions.Session() as session:
+        return session.request(method=method, url=url, **kwargs)
+
+
+def get(
+    url: _t.UriType, params: _t.ParamsType = None, **kwargs: Unpack[_t.GetKwargs]
+) -> Response:
+    r"""Sends a GET request.
+
+    :param url: URL for the new :class:`Request` object.
+    :param params: (optional) Dictionary, list of tuples or bytes to send
+        in the query string for the :class:`Request`.
+    :param \*\*kwargs: Optional arguments that ``request`` takes.
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+    """
+
+    return request("get", url, params=params, **kwargs)
+
+
+def options(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
+    r"""Sends an OPTIONS request.
+
+    :param url: URL for the new :class:`Request` object.
+    :param \*\*kwargs: Optional arguments that ``request`` takes.
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+    """
+
+    return request("options", url, **kwargs)
+
+
+def head(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
+    r"""Sends a HEAD request.
+
+    :param url: URL for the new :class:`Request` object.
+    :param \*\*kwargs: Optional arguments that ``request`` takes. If
+        `allow_redirects` is not provided, it will be set to `False` (as
+        opposed to the default :meth:`request` behavior).
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+    """
+
+    kwargs.setdefault("allow_redirects", False)
+    return request("head", url, **kwargs)
+
+
+def post(
+    url: _t.UriType,
+    data: _t.DataType = None,
+    json: _t.JsonType = None,
+    **kwargs: Unpack[_t.PostKwargs],
+) -> Response:
+    r"""Sends a POST request.
+
+    :param url: URL for the new :class:`Request` object.
+    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+        object to send in the body of the :class:`Request`.
+    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+    :param \*\*kwargs: Optional arguments that ``request`` takes.
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+    """
+
+    return request("post", url, data=data, json=json, **kwargs)
+
+
+def put(
+    url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
+) -> Response:
+    r"""Sends a PUT request.
+
+    :param url: URL for the new :class:`Request` object.
+    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+        object to send in the body of the :class:`Request`.
+    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+    :param \*\*kwargs: Optional arguments that ``request`` takes.
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+    """
+
+    return request("put", url, data=data, **kwargs)
+
+
+def patch(
+    url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
+) -> Response:
+    r"""Sends a PATCH request.
+
+    :param url: URL for the new :class:`Request` object.
+    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+        object to send in the body of the :class:`Request`.
+    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+    :param \*\*kwargs: Optional arguments that ``request`` takes.
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+    """
+
+    return request("patch", url, data=data, **kwargs)
+
+
+def delete(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
+    r"""Sends a DELETE request.
+
+    :param url: URL for the new :class:`Request` object.
+    :param \*\*kwargs: Optional arguments that ``request`` takes.
+    :return: :class:`Response ` object
+    :rtype: requests.Response
+    """
+
+    return request("delete", url, **kwargs)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py
new file mode 100644
index 00000000000..2af481dbf59
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py
@@ -0,0 +1,354 @@
+"""
+requests.auth
+~~~~~~~~~~~~~
+
+This module contains the authentication handlers for Requests.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import os
+import re
+import threading
+import time
+import warnings
+from base64 import b64encode
+from typing import TYPE_CHECKING, Any, Final, cast, overload
+
+from ._internal_utils import to_native_string
+from .compat import basestring, str, urlparse
+from .cookies import extract_cookies_to_jar
+from .utils import parse_dict_header
+
+if TYPE_CHECKING:
+    from http.cookiejar import CookieJar
+    from typing import Any
+
+    from .models import PreparedRequest, Response
+
+CONTENT_TYPE_FORM_URLENCODED: Final = "application/x-www-form-urlencoded"
+CONTENT_TYPE_MULTI_PART: Final = "multipart/form-data"
+
+
+def _basic_auth_str(username: bytes | str, password: bytes | str) -> str:
+    """Returns a Basic Auth string."""
+
+    # "I want us to put a big-ol' comment on top of it that
+    # says that this behaviour is dumb but we need to preserve
+    # it because people are relying on it."
+    #    - Lukasa
+    #
+    # These are here solely to maintain backwards compatibility
+    # for things like ints. This will be removed in 3.0.0.
+    if not isinstance(username, basestring):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard for non-str/bytes
+        warnings.warn(
+            "Non-string usernames will no longer be supported in Requests "
+            f"3.0.0. Please convert the object you've passed in ({username!r}) to "
+            "a string or bytes object in the near future to avoid "
+            "problems.",
+            category=DeprecationWarning,
+        )
+        username = str(username)
+
+    if not isinstance(password, basestring):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard for non-str/bytes
+        warnings.warn(
+            "Non-string passwords will no longer be supported in Requests "
+            f"3.0.0. Please convert the object you've passed in ({type(password)!r}) to "
+            "a string or bytes object in the near future to avoid "
+            "problems.",
+            category=DeprecationWarning,
+        )
+        password = str(password)
+    # -- End Removal --
+
+    if isinstance(username, str):
+        username = username.encode("latin1")
+
+    if isinstance(password, str):
+        password = password.encode("latin1")
+
+    authstr = "Basic " + to_native_string(
+        b64encode(b":".join((username, password))).strip()
+    )
+
+    return authstr
+
+
+class AuthBase:
+    """Base class that all auth implementations derive from"""
+
+    def __call__(self, r: PreparedRequest) -> PreparedRequest:
+        raise NotImplementedError("Auth hooks must be callable.")
+
+
+class HTTPBasicAuth(AuthBase):
+    """Attaches HTTP Basic Authentication to the given Request object."""
+
+    username: bytes | str
+    password: bytes | str
+
+    @overload
+    def __init__(self, username: str, password: str) -> None: ...
+    @overload
+    def __init__(self, username: bytes, password: bytes) -> None: ...
+
+    def __init__(self, username: bytes | str, password: bytes | str) -> None:
+        self.username = username
+        self.password = password
+
+    def __eq__(self, other: object) -> bool:
+        return all(
+            [
+                self.username == getattr(other, "username", None),
+                self.password == getattr(other, "password", None),
+            ]
+        )
+
+    def __ne__(self, other: Any) -> bool:
+        return not self == other
+
+    def __call__(self, r: PreparedRequest) -> PreparedRequest:
+        r.headers["Authorization"] = _basic_auth_str(self.username, self.password)
+        return r
+
+
+class HTTPProxyAuth(HTTPBasicAuth):
+    """Attaches HTTP Proxy Authentication to a given Request object."""
+
+    def __call__(self, r: PreparedRequest) -> PreparedRequest:
+        r.headers["Proxy-Authorization"] = _basic_auth_str(self.username, self.password)
+        return r
+
+
+class HTTPDigestAuth(AuthBase):
+    """Attaches HTTP Digest Authentication to the given Request object."""
+
+    username: bytes | str
+    password: bytes | str
+    _thread_local: threading.local
+    last_nonce: str
+    nonce_count: int
+    chal: dict[str, str]
+    pos: int | None
+    num_401_calls: int | None
+
+    @overload
+    def __init__(self, username: str, password: str) -> None: ...
+    @overload
+    def __init__(self, username: bytes, password: bytes) -> None: ...
+
+    def __init__(self, username: bytes | str, password: bytes | str) -> None:
+        self.username = username
+        self.password = password
+        # Keep state in per-thread local storage
+        self._thread_local = threading.local()
+
+    def init_per_thread_state(self) -> None:
+        # Ensure state is initialized just once per-thread
+        if not hasattr(self._thread_local, "init"):
+            self._thread_local.init = True
+            self._thread_local.last_nonce = ""
+            self._thread_local.nonce_count = 0
+            self._thread_local.chal = {}
+            self._thread_local.pos = None
+            self._thread_local.num_401_calls = None
+
+    def build_digest_header(self, method: str, url: str) -> str | None:
+        """
+        :rtype: str
+        """
+
+        realm = self._thread_local.chal["realm"]
+        nonce = self._thread_local.chal["nonce"]
+        qop = self._thread_local.chal.get("qop")
+        algorithm = self._thread_local.chal.get("algorithm")
+        opaque = self._thread_local.chal.get("opaque")
+        hash_utf8 = None
+
+        if algorithm is None:
+            _algorithm = "MD5"
+        else:
+            _algorithm = algorithm.upper()
+        # lambdas assume digest modules are imported at the top level
+        if _algorithm == "MD5" or _algorithm == "MD5-SESS":
+
+            def md5_utf8(x: str | bytes) -> str:
+                if isinstance(x, str):
+                    x = x.encode("utf-8")
+                return hashlib.md5(x, usedforsecurity=False).hexdigest()
+
+            hash_utf8 = md5_utf8
+        elif _algorithm == "SHA":
+
+            def sha_utf8(x: str | bytes) -> str:
+                if isinstance(x, str):
+                    x = x.encode("utf-8")
+                return hashlib.sha1(x, usedforsecurity=False).hexdigest()
+
+            hash_utf8 = sha_utf8
+        elif _algorithm == "SHA-256":
+
+            def sha256_utf8(x: str | bytes) -> str:
+                if isinstance(x, str):
+                    x = x.encode("utf-8")
+                return hashlib.sha256(x, usedforsecurity=False).hexdigest()
+
+            hash_utf8 = sha256_utf8
+        elif _algorithm == "SHA-512":
+
+            def sha512_utf8(x: str | bytes) -> str:
+                if isinstance(x, str):
+                    x = x.encode("utf-8")
+                return hashlib.sha512(x, usedforsecurity=False).hexdigest()
+
+            hash_utf8 = sha512_utf8
+
+        if hash_utf8 is None:
+            return None
+
+        def KD(s: str, d: str) -> str:
+            return hash_utf8(f"{s}:{d}")
+
+        # XXX not implemented yet
+        entdig = None
+        p_parsed = urlparse(url)
+        #: path is request-uri defined in RFC 2616 which should not be empty
+        path = p_parsed.path or "/"
+        if p_parsed.query:
+            path += f"?{p_parsed.query}"
+
+        A1 = f"{self.username}:{realm}:{self.password}"
+        A2 = f"{method}:{path}"
+
+        HA1 = hash_utf8(A1)
+        HA2 = hash_utf8(A2)
+
+        if nonce == self._thread_local.last_nonce:
+            self._thread_local.nonce_count += 1
+        else:
+            self._thread_local.nonce_count = 1
+        ncvalue = f"{self._thread_local.nonce_count:08x}"
+        s = str(self._thread_local.nonce_count).encode("utf-8")
+        s += nonce.encode("utf-8")
+        s += time.ctime().encode("utf-8")
+        s += os.urandom(8)
+
+        cnonce = hashlib.sha1(s, usedforsecurity=False).hexdigest()[:16]
+        if _algorithm == "MD5-SESS":
+            HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}")  # type: ignore[reportConstantRedefinition]  # RFC 2617 terminology
+
+        if not qop:
+            respdig = KD(HA1, f"{nonce}:{HA2}")
+        elif qop == "auth" or "auth" in qop.split(","):
+            noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}"
+            respdig = KD(HA1, noncebit)
+        else:
+            # XXX handle auth-int.
+            return None
+
+        self._thread_local.last_nonce = nonce
+
+        # XXX should the partial digests be encoded too?
+        base = (
+            f'username="{self.username}", realm="{realm}", nonce="{nonce}", '
+            f'uri="{path}", response="{respdig}"'
+        )
+        if opaque:
+            base += f', opaque="{opaque}"'
+        if algorithm:
+            base += f', algorithm="{algorithm}"'
+        if entdig:
+            base += f', digest="{entdig}"'
+        if qop:
+            base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"'
+
+        return f"Digest {base}"
+
+    def handle_redirect(self, r: Response, **kwargs: Any) -> None:
+        """Reset num_401_calls counter on redirects."""
+        if r.is_redirect:
+            self._thread_local.num_401_calls = 1
+
+    def handle_401(self, r: Response, **kwargs: Any) -> Response:
+        """
+        Takes the given response and tries digest-auth, if needed.
+
+        :rtype: requests.Response
+        """
+
+        # If response is not 4xx, do not auth
+        # See https://github.com/psf/requests/issues/3772
+        if not 400 <= r.status_code < 500:
+            self._thread_local.num_401_calls = 1
+            return r
+
+        if self._thread_local.pos is not None:
+            # Rewind the file position indicator of the body to where
+            # it was to resend the request.
+            if (seek := getattr(r.request.body, "seek", None)) is not None:
+                seek(self._thread_local.pos)
+        s_auth = r.headers.get("www-authenticate", "")
+
+        if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2:
+            self._thread_local.num_401_calls += 1
+            pat = re.compile(r"digest ", flags=re.IGNORECASE)
+            self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1))
+
+            # Consume content and release the original connection
+            # to allow our new request to reuse the same one.
+            r.content
+            r.close()
+            prep = r.request.copy()
+            cookie_jar = cast("CookieJar", prep._cookies)  # type: ignore[reportPrivateUsage]
+            extract_cookies_to_jar(cookie_jar, r.request, r.raw)
+            prep.prepare_cookies(cookie_jar)
+
+            _digest_auth = self.build_digest_header(
+                cast(str, prep.method), cast(str, prep.url)
+            )
+            if _digest_auth:
+                prep.headers["Authorization"] = _digest_auth
+            _r = r.connection.send(prep, **kwargs)
+            _r.history.append(r)
+            _r.request = prep
+
+            return _r
+
+        self._thread_local.num_401_calls = 1
+        return r
+
+    def __call__(self, r: PreparedRequest) -> PreparedRequest:
+        # Initialize per-thread state, if needed
+        self.init_per_thread_state()
+        # If we have a saved nonce, skip the 401
+        if self._thread_local.last_nonce:
+            _digest_auth = self.build_digest_header(
+                cast(str, r.method), cast(str, r.url)
+            )
+            if _digest_auth:
+                r.headers["Authorization"] = _digest_auth
+        if (tell := getattr(r.body, "tell", None)) is not None:
+            self._thread_local.pos = tell()
+        else:
+            # In the case of HTTPDigestAuth being reused and the body of
+            # the previous request was a file-like object, pos has the
+            # file position of the previous body. Ensure it's set to
+            # None.
+            self._thread_local.pos = None
+        r.register_hook("response", self.handle_401)
+        r.register_hook("response", self.handle_redirect)
+        self._thread_local.num_401_calls = 1
+
+        return r
+
+    def __eq__(self, other: object) -> bool:
+        return all(
+            [
+                self.username == getattr(other, "username", None),
+                self.password == getattr(other, "password", None),
+            ]
+        )
+
+    def __ne__(self, other: Any) -> bool:
+        return not self == other
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py
new file mode 100644
index 00000000000..15262c79c60
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+
+"""
+requests.certs
+~~~~~~~~~~~~~~
+
+This module returns the preferred default CA certificate bundle. There is
+only one — the one from the certifi package.
+
+If you are packaging Requests, e.g., for a Linux distribution or a managed
+environment, you can change the definition of where() to return a separately
+packaged CA bundle.
+"""
+
+from opentelemetry.agent._vendor.certifi import where
+
+if __name__ == "__main__":
+    print(where())
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py
new file mode 100644
index 00000000000..28899bea391
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py
@@ -0,0 +1,102 @@
+"""
+requests.compat
+~~~~~~~~~~~~~~~
+
+This module previously handled import compatibility issues
+between Python 2 and Python 3. It remains for backwards
+compatibility until the next major version.
+"""
+
+# pyright: reportUnusedImport=false
+
+from __future__ import annotations
+
+import importlib
+import sys
+from types import ModuleType
+
+# -------
+# urllib3
+# -------
+from opentelemetry.agent._vendor.urllib3 import (
+    __version__ as urllib3_version,  # type: ignore[reportPrivateImportUsage]
+)
+
+# Detect which major version of urllib3 is being used.
+try:
+    is_urllib3_1 = int(urllib3_version.split(".")[0]) == 1
+except (TypeError, AttributeError):
+    # If we can't discern a version, prefer old functionality.
+    is_urllib3_1 = True
+
+# -------------------
+# Character Detection
+# -------------------
+
+
+# Always use the vendored charset_normalizer, never the application's chardet.
+from opentelemetry.agent._vendor import charset_normalizer as chardet
+
+# -------
+# Pythons
+# -------
+
+# Syntax sugar.
+_ver = sys.version_info
+
+#: Python 2.x?
+is_py2 = _ver[0] == 2
+
+#: Python 3.x?
+is_py3 = _ver[0] == 3
+
+# json/simplejson module import resolution
+has_simplejson = False
+try:
+    import simplejson as json  # type: ignore[import-not-found]
+
+    has_simplejson = True
+except ImportError:
+    import json
+
+if has_simplejson:
+    from simplejson import JSONDecodeError  # type: ignore[import-not-found]
+else:
+    from json import JSONDecodeError
+
+# Keep OrderedDict for backwards compatibility.
+from collections import OrderedDict
+from collections.abc import Callable, Mapping, MutableMapping
+from http import cookiejar as cookielib
+from http.cookies import Morsel
+from io import StringIO
+
+# --------------
+# Legacy Imports
+# --------------
+from urllib.parse import (
+    quote,
+    quote_plus,
+    unquote,
+    unquote_plus,
+    urldefrag,
+    urlencode,
+    urljoin,
+    urlparse,
+    urlsplit,
+    urlunparse,
+)
+from urllib.request import (
+    getproxies,
+    getproxies_environment,
+    parse_http_list,
+    proxy_bypass,
+    proxy_bypass_environment,  # type: ignore[attr-defined]  # https://github.com/python/cpython/issues/145331
+)
+
+builtin_str = str
+str = str
+bytes = bytes
+basestring = (str, bytes)
+numeric_types = (int, float)
+integer_types = (int,)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py
new file mode 100644
index 00000000000..2e3fc215095
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py
@@ -0,0 +1,625 @@
+"""
+requests.cookies
+~~~~~~~~~~~~~~~~
+
+Compatibility code to be able to use `http.cookiejar.CookieJar` with requests.
+
+requests.utils imports from here, so be careful with imports.
+"""
+
+from __future__ import annotations
+
+import calendar
+import copy
+import time
+from collections.abc import Iterator, MutableMapping
+from http.cookiejar import Cookie, CookieJar, CookiePolicy
+from typing import TYPE_CHECKING, Any, TypeVar, overload
+
+from ._internal_utils import to_native_string
+from ._types import is_prepared as _is_prepared
+from .compat import Morsel, cookielib, urlparse, urlunparse
+
+if TYPE_CHECKING:
+    from _typeshed import SupportsKeysAndGetItem
+
+    from .models import PreparedRequest
+
+import threading
+
+
+class MockRequest:
+    """Wraps a `requests.PreparedRequest` to mimic a `urllib2.Request`.
+
+    The code in `http.cookiejar.CookieJar` expects this interface in order to correctly
+    manage cookie policies, i.e., determine whether a cookie can be set, given the
+    domains of the request and the cookie.
+
+    The original request object is read-only. The client is responsible for collecting
+    the new headers via `get_new_headers()` and interpreting them appropriately. You
+    probably want `get_cookie_header`, defined below.
+    """
+
+    type: str
+
+    def __init__(self, request: PreparedRequest) -> None:
+        assert _is_prepared(request)
+        self._r = request
+        self._new_headers: dict[str, str] = {}
+        self.type = urlparse(self._r.url).scheme
+
+    def get_type(self) -> str:
+        return self.type
+
+    def get_host(self) -> str:
+        return urlparse(self._r.url).netloc
+
+    def get_origin_req_host(self) -> str:
+        return self.get_host()
+
+    def get_full_url(self) -> str:
+        # Only return the response's URL if the user hadn't set the Host
+        # header
+        if not self._r.headers.get("Host"):
+            return self._r.url
+        # If they did set it, retrieve it and reconstruct the expected domain
+        host = to_native_string(self._r.headers["Host"], encoding="utf-8")
+        parsed = urlparse(self._r.url)
+        # Reconstruct the URL as we expect it
+        return urlunparse(
+            [
+                parsed.scheme,
+                host,
+                parsed.path,
+                parsed.params,
+                parsed.query,
+                parsed.fragment,
+            ]
+        )
+
+    def is_unverifiable(self) -> bool:
+        return True
+
+    def has_header(self, name: str) -> bool:
+        return name in self._r.headers or name in self._new_headers
+
+    def get_header(self, name: str, default: str | None = None) -> str | None:
+        return self._r.headers.get(name, self._new_headers.get(name, default))  # type: ignore[return-value]
+
+    def add_header(self, key: str, val: str) -> None:
+        """cookiejar has no legitimate use for this method; add it back if you find one."""
+        raise NotImplementedError(
+            "Cookie headers should be added with add_unredirected_header()"
+        )
+
+    def add_unredirected_header(self, name: str, value: str) -> None:
+        self._new_headers[name] = value
+
+    def get_new_headers(self) -> dict[str, str]:
+        return self._new_headers
+
+    @property
+    def unverifiable(self) -> bool:
+        return self.is_unverifiable()
+
+    @property
+    def origin_req_host(self) -> str:
+        return self.get_origin_req_host()
+
+    @property
+    def host(self) -> str:
+        return self.get_host()
+
+
+class MockResponse:
+    """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
+
+    ...what? Basically, expose the parsed HTTP headers from the server response
+    the way `http.cookiejar` expects to see them.
+    """
+
+    def __init__(self, headers: Any) -> None:
+        """Make a MockResponse for `cookiejar` to read.
+
+        :param headers: a httplib.HTTPMessage or analogous carrying the headers
+        """
+        self._headers = headers
+
+    def info(self) -> Any:
+        return self._headers
+
+    def getheaders(self, name: str) -> Any:
+        self._headers.getheaders(name)
+
+
+def extract_cookies_to_jar(
+    jar: CookieJar, request: PreparedRequest, response: Any
+) -> None:
+    """Extract the cookies from the response into a CookieJar.
+
+    :param jar: http.cookiejar.CookieJar (not necessarily a RequestsCookieJar)
+    :param request: our own requests.Request object
+    :param response: urllib3.HTTPResponse object
+    """
+    if not (hasattr(response, "_original_response") and response._original_response):
+        return
+    # the _original_response field is the wrapped httplib.HTTPResponse object,
+    req = MockRequest(request)
+    # pull out the HTTPMessage with the headers and put it in the mock:
+    res = MockResponse(response._original_response.msg)
+    jar.extract_cookies(res, req)  # type: ignore[arg-type]
+
+
+def get_cookie_header(jar: CookieJar, request: PreparedRequest) -> str | None:
+    """
+    Produce an appropriate Cookie header string to be sent with `request`, or None.
+
+    :rtype: str
+    """
+    r = MockRequest(request)
+    jar.add_cookie_header(r)  # type: ignore[arg-type]
+    return r.get_new_headers().get("Cookie")
+
+
+def remove_cookie_by_name(
+    cookiejar: CookieJar, name: str, domain: str | None = None, path: str | None = None
+) -> None:
+    """Unsets a cookie by name, by default over all domains and paths.
+
+    Wraps CookieJar.clear(), is O(n).
+    """
+    clearables: list[tuple[str, str, str]] = []
+    for cookie in cookiejar:
+        if cookie.name != name:
+            continue
+        if domain is not None and domain != cookie.domain:
+            continue
+        if path is not None and path != cookie.path:
+            continue
+        clearables.append((cookie.domain, cookie.path, cookie.name))
+
+    for domain, path, name in clearables:
+        cookiejar.clear(domain, path, name)
+
+
+class CookieConflictError(RuntimeError):
+    """There are two cookies that meet the criteria specified in the cookie jar.
+    Use .get and .set and include domain and path args in order to be more specific.
+    """
+
+
+class RequestsCookieJar(CookieJar, MutableMapping[str, str | None]):  # type: ignore[misc]
+    """Compatibility class; is a http.cookiejar.CookieJar, but exposes a dict
+    interface.
+
+    This is the CookieJar we create by default for requests and sessions that
+    don't specify one, since some clients may expect response.cookies and
+    session.cookies to support dict operations.
+
+    Requests does not use the dict interface internally; it's just for
+    compatibility with external client code. All requests code should work
+    out of the box with externally provided instances of ``CookieJar``, e.g.
+    ``LWPCookieJar`` and ``FileCookieJar``.
+
+    Unlike a regular CookieJar, this class is pickleable.
+
+    .. warning:: dictionary operations that are normally O(1) may be O(n).
+    """
+
+    _policy: CookiePolicy
+
+    def get(  # type: ignore[override]
+        self,
+        name: str,
+        default: str | None = None,
+        domain: str | None = None,
+        path: str | None = None,
+    ) -> str | None:
+        """Dict-like get() that also supports optional domain and path args in
+        order to resolve naming collisions from using one cookie jar over
+        multiple domains.
+
+        .. warning:: operation is O(n), not O(1).
+        """
+        try:
+            return self._find_no_duplicates(name, domain, path)
+        except KeyError:
+            return default
+
+    def set(
+        self, name: str, value: str | Morsel[dict[str, str]] | None, **kwargs: Any
+    ) -> Cookie | None:
+        """Dict-like set() that also supports optional domain and path args in
+        order to resolve naming collisions from using one cookie jar over
+        multiple domains.
+        """
+        # support client code that unsets cookies by assignment of a None value:
+        if value is None:
+            remove_cookie_by_name(
+                self, name, domain=kwargs.get("domain"), path=kwargs.get("path")
+            )
+            return
+
+        if isinstance(value, Morsel):
+            c = morsel_to_cookie(value)
+        else:
+            c = create_cookie(name, value, **kwargs)
+        self.set_cookie(c)
+        return c
+
+    def iterkeys(self) -> Iterator[str]:
+        """Dict-like iterkeys() that returns an iterator of names of cookies
+        from the jar.
+
+        .. seealso:: itervalues() and iteritems().
+        """
+        for cookie in iter(self):
+            yield cookie.name
+
+    def keys(self) -> list[str]:  # type: ignore[override]
+        """Dict-like keys() that returns a list of names of cookies from the
+        jar.
+
+        .. seealso:: values() and items().
+        """
+        return list(self.iterkeys())
+
+    def itervalues(self) -> Iterator[str | None]:
+        """Dict-like itervalues() that returns an iterator of values of cookies
+        from the jar.
+
+        .. seealso:: iterkeys() and iteritems().
+        """
+        for cookie in iter(self):
+            yield cookie.value
+
+    def values(self) -> list[str | None]:  # type: ignore[override]
+        """Dict-like values() that returns a list of values of cookies from the
+        jar.
+
+        .. seealso:: keys() and items().
+        """
+        return list(self.itervalues())
+
+    def iteritems(self) -> Iterator[tuple[str, str | None]]:
+        """Dict-like iteritems() that returns an iterator of name-value tuples
+        from the jar.
+
+        .. seealso:: iterkeys() and itervalues().
+        """
+        for cookie in iter(self):
+            yield cookie.name, cookie.value
+
+    def items(self) -> list[tuple[str, str | None]]:  # type: ignore[override]
+        """Dict-like items() that returns a list of name-value tuples from the
+        jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a
+        vanilla python dict of key value pairs.
+
+        .. seealso:: keys() and values().
+        """
+        return list(self.iteritems())
+
+    def list_domains(self) -> list[str]:
+        """Utility method to list all the domains in the jar."""
+        domains: list[str] = []
+        for cookie in iter(self):
+            if cookie.domain not in domains:
+                domains.append(cookie.domain)
+        return domains
+
+    def list_paths(self) -> list[str]:
+        """Utility method to list all the paths in the jar."""
+        paths: list[str] = []
+        for cookie in iter(self):
+            if cookie.path not in paths:
+                paths.append(cookie.path)
+        return paths
+
+    def multiple_domains(self) -> bool:
+        """Returns True if there are multiple domains in the jar.
+        Returns False otherwise.
+
+        :rtype: bool
+        """
+        domains: list[str] = []
+        for cookie in iter(self):
+            if cookie.domain is not None and cookie.domain in domains:  # type: ignore[reportUnnecessaryComparison]  # defensive check
+                return True
+            domains.append(cookie.domain)
+        return False  # there is only one domain in jar
+
+    def get_dict(
+        self, domain: str | None = None, path: str | None = None
+    ) -> dict[str, str | None]:
+        """Takes as an argument an optional domain and path and returns a plain
+        old Python dict of name-value pairs of cookies that meet the
+        requirements.
+
+        :rtype: dict
+        """
+        dictionary: dict[str, str | None] = {}
+        for cookie in iter(self):
+            if (domain is None or cookie.domain == domain) and (
+                path is None or cookie.path == path
+            ):
+                dictionary[cookie.name] = cookie.value
+        return dictionary
+
+    def __iter__(self) -> Iterator[Cookie]:  # type: ignore[override]
+        """RequestCookieJar's __iter__ comes from CookieJar not MutableMapping."""
+        return super().__iter__()
+
+    def __contains__(self, name: object) -> bool:
+        try:
+            return super().__contains__(name)
+        except CookieConflictError:
+            return True
+
+    def __getitem__(self, name: str) -> str | None:
+        """Dict-like __getitem__() for compatibility with client code. Throws
+        exception if there are more than one cookie with name. In that case,
+        use the more explicit get() method instead.
+
+        .. warning:: operation is O(n), not O(1).
+        """
+        return self._find_no_duplicates(name)
+
+    def __setitem__(
+        self, name: str, value: str | Morsel[dict[str, str]] | None
+    ) -> None:
+        """Dict-like __setitem__ for compatibility with client code. Throws
+        exception if there is already a cookie of that name in the jar. In that
+        case, use the more explicit set() method instead.
+        """
+        self.set(name, value)
+
+    def __delitem__(self, name: str) -> None:
+        """Deletes a cookie given a name. Wraps ``http.cookiejar.CookieJar``'s
+        ``remove_cookie_by_name()``.
+        """
+        remove_cookie_by_name(self, name)
+
+    def set_cookie(self, cookie: Cookie, *args: Any, **kwargs: Any) -> None:
+        if (
+            (value := cookie.value) is not None
+            and value.startswith('"')
+            and value.endswith('"')
+        ):
+            cookie.value = value.replace('\\"', "")
+        return super().set_cookie(cookie, *args, **kwargs)
+
+    def update(  # type: ignore[override]
+        self, other: CookieJar | SupportsKeysAndGetItem[str, str]
+    ) -> None:
+        """Updates this jar with cookies from another CookieJar or dict-like"""
+        if isinstance(other, cookielib.CookieJar):
+            for cookie in other:
+                self.set_cookie(copy.copy(cookie))
+        else:
+            super().update(other)
+
+    def _find(
+        self, name: str, domain: str | None = None, path: str | None = None
+    ) -> str | None:
+        """Requests uses this method internally to get cookie values.
+
+        If there are conflicting cookies, _find arbitrarily chooses one.
+        See _find_no_duplicates if you want an exception thrown if there are
+        conflicting cookies.
+
+        :param name: a string containing name of cookie
+        :param domain: (optional) string containing domain of cookie
+        :param path: (optional) string containing path of cookie
+        :return: cookie.value
+        """
+        for cookie in iter(self):
+            if cookie.name == name:
+                if domain is None or cookie.domain == domain:
+                    if path is None or cookie.path == path:
+                        return cookie.value
+
+        raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
+
+    def _find_no_duplicates(
+        self, name: str, domain: str | None = None, path: str | None = None
+    ) -> str:
+        """Both ``__get_item__`` and ``get`` call this function: it's never
+        used elsewhere in Requests.
+
+        :param name: a string containing name of cookie
+        :param domain: (optional) string containing domain of cookie
+        :param path: (optional) string containing path of cookie
+        :raises KeyError: if cookie is not found
+        :raises CookieConflictError: if there are multiple cookies
+            that match name and optionally domain and path
+        :return: cookie.value
+        """
+        toReturn = None
+        for cookie in iter(self):
+            if cookie.name == name:
+                if domain is None or cookie.domain == domain:
+                    if path is None or cookie.path == path:
+                        if toReturn is not None:
+                            # if there are multiple cookies that meet passed in criteria
+                            raise CookieConflictError(
+                                f"There are multiple cookies with name, {name!r}"
+                            )
+                        # we will eventually return this as long as no cookie conflict
+                        toReturn = cookie.value
+
+        if toReturn is not None:
+            return toReturn
+        raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
+
+    def __getstate__(self) -> dict[str, Any]:
+        """Unlike a normal CookieJar, this class is pickleable."""
+        state = self.__dict__.copy()
+        # remove the unpickleable RLock object
+        state.pop("_cookies_lock")
+        return state
+
+    def __setstate__(self, state: dict[str, Any]) -> None:
+        """Unlike a normal CookieJar, this class is pickleable."""
+        self.__dict__.update(state)
+        if "_cookies_lock" not in self.__dict__:
+            self._cookies_lock = threading.RLock()
+
+    def copy(self) -> RequestsCookieJar:
+        """Return a copy of this RequestsCookieJar."""
+        new_cj = RequestsCookieJar()
+        new_cj.set_policy(self.get_policy())
+        new_cj.update(self)
+        return new_cj
+
+    def get_policy(self) -> CookiePolicy:
+        """Return the CookiePolicy instance used."""
+        return self._policy
+
+
+def _copy_cookie_jar(jar: CookieJar | None) -> CookieJar | None:  # type: ignore[reportUnusedFunction]  # cross-module usage in models.py
+    if jar is None:
+        return None
+
+    if copy_method := getattr(jar, "copy", None):
+        # We're dealing with an instance of RequestsCookieJar
+        return copy_method()
+    # We're dealing with a generic CookieJar instance
+    new_jar = copy.copy(jar)
+    new_jar.clear()
+    for cookie in jar:
+        new_jar.set_cookie(copy.copy(cookie))
+    return new_jar
+
+
+def create_cookie(name: str, value: str, **kwargs: Any) -> Cookie:
+    """Make a cookie from underspecified parameters.
+
+    By default, the pair of `name` and `value` will be set for the domain ''
+    and sent on every request (this is sometimes called a "supercookie").
+    """
+    result: dict[str, Any] = {
+        "version": 0,
+        "name": name,
+        "value": value,
+        "port": None,
+        "domain": "",
+        "path": "/",
+        "secure": False,
+        "expires": None,
+        "discard": True,
+        "comment": None,
+        "comment_url": None,
+        "rest": {"HttpOnly": None},
+        "rfc2109": False,
+    }
+
+    badargs = set(kwargs) - set(result)
+    if badargs:
+        raise TypeError(
+            f"create_cookie() got unexpected keyword arguments: {list(badargs)}"
+        )
+
+    result.update(kwargs)
+    result["port_specified"] = bool(result["port"])
+    result["domain_specified"] = bool(result["domain"])
+    result["domain_initial_dot"] = result["domain"].startswith(".")
+    result["path_specified"] = bool(result["path"])
+
+    return cookielib.Cookie(**result)
+
+
+def morsel_to_cookie(morsel: Morsel[Any]) -> Cookie:
+    """Convert a Morsel object into a Cookie containing the one k/v pair."""
+
+    expires: int | None = None
+    if morsel["max-age"]:
+        try:
+            expires = int(time.time() + int(morsel["max-age"]))
+        except ValueError:
+            raise TypeError(f"max-age: {morsel['max-age']} must be integer")
+    elif morsel["expires"]:
+        time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
+        expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
+    return create_cookie(
+        comment=morsel["comment"],
+        comment_url=bool(morsel["comment"]),
+        discard=False,
+        domain=morsel["domain"],
+        expires=expires,
+        name=morsel.key,
+        path=morsel["path"],
+        port=None,
+        rest={"HttpOnly": morsel["httponly"]},
+        rfc2109=False,
+        secure=bool(morsel["secure"]),
+        value=morsel.value,
+        version=morsel["version"] or 0,
+    )
+
+
+_CookieJarT = TypeVar("_CookieJarT", bound=CookieJar)
+
+
+@overload
+def cookiejar_from_dict(
+    cookie_dict: dict[str, str] | None,
+    cookiejar: None = None,
+    overwrite: bool = True,
+) -> RequestsCookieJar: ...
+
+
+@overload
+def cookiejar_from_dict(
+    cookie_dict: dict[str, str] | None,
+    cookiejar: _CookieJarT,
+    overwrite: bool = True,
+) -> _CookieJarT: ...
+
+
+def cookiejar_from_dict(
+    cookie_dict: dict[str, str] | None,
+    cookiejar: CookieJar | None = None,
+    overwrite: bool = True,
+) -> CookieJar:
+    """Returns a CookieJar from a key/value dictionary.
+
+    :param cookie_dict: Dict of key/values to insert into CookieJar.
+    :param cookiejar: (optional) A cookiejar to add the cookies to.
+    :param overwrite: (optional) If False, will not replace cookies
+        already in the jar with new ones.
+    :rtype: CookieJar
+    """
+    if cookiejar is None:
+        cookiejar = RequestsCookieJar()
+
+    if cookie_dict is not None:
+        names_from_jar = [cookie.name for cookie in cookiejar]
+        for name in cookie_dict:
+            if overwrite or (name not in names_from_jar):
+                cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
+
+    return cookiejar
+
+
+def merge_cookies(
+    cookiejar: CookieJar, cookies: dict[str, str] | CookieJar | None
+) -> CookieJar:
+    """Add cookies to cookiejar and returns a merged CookieJar.
+
+    :param cookiejar: CookieJar object to add the cookies to.
+    :param cookies: Dictionary or CookieJar object to be added.
+    :rtype: CookieJar
+    """
+    if not isinstance(cookiejar, cookielib.CookieJar):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard
+        raise ValueError("You can only merge into CookieJar")
+
+    if isinstance(cookies, dict):
+        cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False)
+    elif isinstance(cookies, cookielib.CookieJar):
+        if update_method := getattr(cookiejar, "update", None):
+            update_method(cookies)
+        else:
+            for cookie_in_jar in cookies:
+                cookiejar.set_cookie(cookie_in_jar)
+
+    return cookiejar
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py
new file mode 100644
index 00000000000..936d7987a68
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py
@@ -0,0 +1,162 @@
+"""
+requests.exceptions
+~~~~~~~~~~~~~~~~~~~
+
+This module contains the set of Requests' exceptions.
+"""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
+
+from opentelemetry.agent._vendor.urllib3.exceptions import HTTPError as BaseHTTPError
+
+from .compat import JSONDecodeError as CompatJSONDecodeError
+
+if TYPE_CHECKING:
+    from .models import PreparedRequest, Request, Response
+
+
+class RequestException(IOError):
+    """There was an ambiguous exception that occurred while handling your
+    request.
+    """
+
+    response: Response | None
+    request: Request | PreparedRequest | None
+
+    def __init__(self, *args: Any, **kwargs: Any) -> None:
+        """Initialize RequestException with `request` and `response` objects."""
+        response: Response | None = kwargs.pop("response", None)
+        self.response = response
+        self.request = kwargs.pop("request", None)
+        if response is not None and not self.request and hasattr(response, "request"):
+            self.request = response.request
+        super().__init__(*args, **kwargs)
+
+
+class InvalidJSONError(RequestException):
+    """A JSON error occurred."""
+
+
+class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
+    """Couldn't decode the text into json"""
+
+    def __init__(self, *args: Any, **kwargs: Any) -> None:
+        """
+        Construct the JSONDecodeError instance first with all
+        args. Then use it's args to construct the IOError so that
+        the json specific args aren't used as IOError specific args
+        and the error message from JSONDecodeError is preserved.
+        """
+        CompatJSONDecodeError.__init__(self, *args)
+        InvalidJSONError.__init__(self, *self.args, **kwargs)
+
+    def __reduce__(self) -> tuple[Any, ...] | str:
+        """
+        The __reduce__ method called when pickling the object must
+        be the one from the JSONDecodeError (be it json/simplejson)
+        as it expects all the arguments for instantiation, not just
+        one like the IOError, and the MRO would by default call the
+        __reduce__ method from the IOError due to the inheritance order.
+        """
+        return CompatJSONDecodeError.__reduce__(self)
+
+
+class HTTPError(RequestException):
+    """An HTTP error occurred."""
+
+
+class ConnectionError(RequestException):
+    """A Connection error occurred."""
+
+
+class ProxyError(ConnectionError):
+    """A proxy error occurred."""
+
+
+class SSLError(ConnectionError):
+    """An SSL error occurred."""
+
+
+class Timeout(RequestException):
+    """The request timed out.
+
+    Catching this error will catch both
+    :exc:`~requests.exceptions.ConnectTimeout` and
+    :exc:`~requests.exceptions.ReadTimeout` errors.
+    """
+
+
+class ConnectTimeout(ConnectionError, Timeout):
+    """The request timed out while trying to connect to the remote server.
+
+    Requests that produced this error are safe to retry.
+    """
+
+
+class ReadTimeout(Timeout):
+    """The server did not send any data in the allotted amount of time."""
+
+
+class URLRequired(RequestException):
+    """A valid URL is required to make a request."""
+
+
+class TooManyRedirects(RequestException):
+    """Too many redirects."""
+
+
+class MissingSchema(RequestException, ValueError):
+    """The URL scheme (e.g. http or https) is missing."""
+
+
+class InvalidSchema(RequestException, ValueError):
+    """The URL scheme provided is either invalid or unsupported."""
+
+
+class InvalidURL(RequestException, ValueError):
+    """The URL provided was somehow invalid."""
+
+
+class InvalidHeader(RequestException, ValueError):
+    """The header value provided was somehow invalid."""
+
+
+class InvalidProxyURL(InvalidURL):
+    """The proxy URL provided is invalid."""
+
+
+class ChunkedEncodingError(RequestException):
+    """The server declared chunked encoding but sent an invalid chunk."""
+
+
+class ContentDecodingError(RequestException, BaseHTTPError):
+    """Failed to decode response content."""
+
+
+class StreamConsumedError(RequestException, TypeError):
+    """The content for this response was already consumed."""
+
+
+class RetryError(RequestException):
+    """Custom retries logic failed"""
+
+
+class UnrewindableBodyError(RequestException):
+    """Requests encountered an error when trying to rewind a body."""
+
+
+# Warnings
+
+
+class RequestsWarning(Warning):
+    """Base warning for Requests."""
+
+
+class FileModeWarning(RequestsWarning, DeprecationWarning):
+    """A file was opened in text mode, but Requests determined its binary length."""
+
+
+class RequestsDependencyWarning(RequestsWarning):
+    """An imported dependency doesn't match the expected version range."""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py
new file mode 100644
index 00000000000..11ff9e9f27e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py
@@ -0,0 +1,48 @@
+"""
+requests.hooks
+~~~~~~~~~~~~~~
+
+This module provides the capabilities for the Requests hooks system.
+
+Available hooks:
+
+``response``:
+    The response generated from a Request.
+"""
+
+from __future__ import annotations
+
+from collections.abc import Callable, Iterable
+from typing import TYPE_CHECKING, Any
+
+if TYPE_CHECKING:
+    from . import _types as _t
+    from .models import Response
+
+HOOKS: list[str] = ["response"]
+
+
+def default_hooks() -> dict[str, list[_t.HookType]]:
+    return {event: [] for event in HOOKS}
+
+
+# TODO: response is the only one
+
+
+def dispatch_hook(
+    key: str,
+    hooks: _t.HooksInputType | None,
+    hook_data: Response,
+    **kwargs: Any,
+) -> Response:
+    """Dispatches a hook dictionary on a given piece of data."""
+    hooks_dict = hooks or {}
+    hook_list: Iterable[_t.HookType] | _t.HookType | None = hooks_dict.get(key)
+    if hook_list:
+        if isinstance(hook_list, Callable):
+            hook_list = [hook_list]
+        for hook in hook_list:
+            _hook_data = hook(hook_data, **kwargs)
+            if _hook_data is not None:
+                hook_data = _hook_data
+    return hook_data
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py
new file mode 100644
index 00000000000..2e0ae54a07f
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py
@@ -0,0 +1,1180 @@
+"""
+requests.models
+~~~~~~~~~~~~~~~
+
+This module contains the primary objects that power Requests.
+"""
+
+from __future__ import annotations
+
+import datetime
+
+# Import encoding now, to avoid implicit import later.
+# Implicit import within threads may cause LookupError when standard library is in a ZIP,
+# such as in Embedded Python. See https://github.com/psf/requests/issues/3578.
+import encodings.idna  # noqa: F401  # type: ignore[reportUnusedImport]
+from collections.abc import Callable, Generator, Iterable, Iterator, Mapping
+from io import UnsupportedOperation
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Final,
+    Literal,
+    cast,
+    overload,
+)
+
+from opentelemetry.agent._vendor.urllib3.exceptions import (
+    DecodeError,
+    LocationParseError,
+    ProtocolError,
+    ReadTimeoutError,
+    SSLError,
+)
+from opentelemetry.agent._vendor.urllib3.fields import RequestField
+from opentelemetry.agent._vendor.urllib3.filepost import encode_multipart_formdata
+from opentelemetry.agent._vendor.urllib3.util import parse_url
+
+from ._internal_utils import to_native_string, unicode_is_ascii
+from ._types import SupportsRead as _SupportsRead
+from .auth import HTTPBasicAuth
+from .compat import (
+    JSONDecodeError,
+    basestring,
+    builtin_str,
+    chardet,
+    cookielib,
+    urlencode,
+    urlsplit,
+    urlunparse,
+)
+from .compat import json as complexjson
+from .cookies import (
+    _copy_cookie_jar,  # type: ignore[reportPrivateUsage]
+    cookiejar_from_dict,
+    get_cookie_header,
+)
+from .exceptions import (
+    ChunkedEncodingError,
+    ConnectionError,
+    ContentDecodingError,
+    HTTPError,
+    InvalidJSONError,
+    InvalidURL,
+    MissingSchema,
+    StreamConsumedError,
+)
+from .exceptions import JSONDecodeError as RequestsJSONDecodeError
+from .exceptions import SSLError as RequestsSSLError
+from .hooks import default_hooks
+from .status_codes import codes
+from .structures import CaseInsensitiveDict
+from .utils import (
+    check_header_validity,
+    get_auth_from_url,
+    guess_filename,
+    guess_json_utf,
+    iter_slices,
+    parse_header_links,
+    requote_uri,
+    stream_decode_response_unicode,
+    super_len,
+    to_key_val_list,
+)
+
+if TYPE_CHECKING:
+    from http.cookiejar import CookieJar
+
+    from opentelemetry.agent._vendor.typing_extensions import Self
+
+    from . import _types as _t
+    from .adapters import HTTPAdapter
+    from .cookies import RequestsCookieJar
+
+#: The set of HTTP status codes that indicate an automatically
+#: processable redirect.
+REDIRECT_STATI: Final[tuple[int, ...]] = (  # type: ignore[assignment]
+    codes.moved,  # 301
+    codes.found,  # 302
+    codes.other,  # 303
+    codes.temporary_redirect,  # 307
+    codes.permanent_redirect,  # 308
+)
+
+DEFAULT_REDIRECT_LIMIT: int = 30
+CONTENT_CHUNK_SIZE: int = 10 * 1024
+ITER_CHUNK_SIZE: int = 512
+
+
+class RequestEncodingMixin:
+    url: str | None
+
+    @property
+    def path_url(self) -> str:
+        """Build the path URL to use."""
+
+        url: list[str] = []
+
+        p = urlsplit(cast(str, self.url))
+
+        path = p.path
+        if not path:
+            path = "/"
+
+        url.append(path)
+
+        query = p.query
+        if query:
+            url.append("?")
+            url.append(query)
+
+        return "".join(url)
+
+    @overload
+    @staticmethod
+    def _encode_params(data: str) -> str: ...
+
+    @overload
+    @staticmethod
+    def _encode_params(data: bytes) -> bytes: ...
+
+    @overload
+    @staticmethod
+    def _encode_params(
+        data: _t.SupportsRead[str | bytes],
+    ) -> _t.SupportsRead[str | bytes]: ...
+
+    @overload
+    @staticmethod
+    def _encode_params(data: _t.KVDataType) -> str: ...
+
+    @staticmethod
+    def _encode_params(
+        data: _t.EncodableDataType,
+    ) -> str | bytes | _t.SupportsRead[str | bytes]:
+        """Encode parameters in a piece of data.
+
+        Will successfully encode parameters when passed as a dict or a list of
+        2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
+        if parameters are supplied as a dict.
+        """
+
+        if isinstance(data, (str, bytes)):
+            return data
+        elif isinstance(data, _SupportsRead):
+            return data
+        elif hasattr(data, "__iter__"):
+            result: list[tuple[bytes, bytes]] = []
+            for k, vs in to_key_val_list(data):
+                if isinstance(vs, basestring) or not hasattr(vs, "__iter__"):
+                    vs = [vs]
+                for v in vs:
+                    if v is not None:
+                        result.append(
+                            (
+                                k.encode("utf-8") if isinstance(k, str) else k,
+                                v.encode("utf-8") if isinstance(v, str) else v,
+                            )
+                        )
+            return urlencode(result, doseq=True)
+        else:
+            return data  # type: ignore[return-value]  # unreachable for valid _t.DataType
+
+    @staticmethod
+    def _encode_files(
+        files: _t.FilesType, data: _t.RawDataType | None
+    ) -> tuple[bytes, str]:
+        """Build the body for a multipart/form-data request.
+
+        Will successfully encode files when passed as a dict or a list of
+        tuples. Order is retained if data is a list of tuples but arbitrary
+        if parameters are supplied as a dict.
+        The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
+        or 4-tuples (filename, fileobj, contentype, custom_headers).
+        """
+        if not files:
+            raise ValueError("Files must be provided.")
+        elif isinstance(data, basestring):
+            raise ValueError("Data must not be a string.")
+
+        new_fields: list[RequestField | tuple[str, bytes]] = []
+        fields = to_key_val_list(data or {})
+        files = to_key_val_list(files or {})
+
+        for field, val in fields:
+            if isinstance(val, basestring) or not hasattr(val, "__iter__"):
+                val = [val]
+            for v in val:
+                if v is not None:
+                    # Don't call str() on bytestrings: in Py3 it all goes wrong.
+                    if not isinstance(v, bytes):
+                        v = str(v)
+
+                    new_fields.append(
+                        (
+                            field.decode("utf-8")
+                            if isinstance(field, bytes)
+                            else field,
+                            v.encode("utf-8") if isinstance(v, str) else v,
+                        )
+                    )
+
+        for k, v in files:
+            # support for explicit filename
+            ft = None
+            fh = None
+            if isinstance(v, (tuple, list)):
+                if len(v) == 2:
+                    fn, fp = v
+                elif len(v) == 3:
+                    fn, fp, ft = v
+                else:
+                    fn, fp, ft, fh = v
+            else:
+                fn = guess_filename(v) or k
+                fp = v
+
+            if isinstance(fp, (str, bytes, bytearray)):
+                fdata = fp
+            elif isinstance(fp, _SupportsRead):  # type: ignore[reportUnnecessaryIsInstance]  # defensive check for untyped callers
+                fdata = fp.read()
+            elif fp is None:  # type: ignore[reportUnnecessaryComparison]  # defensive check for untyped callers
+                continue
+            else:
+                fdata = fp
+
+            rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
+            rf.make_multipart(content_type=ft)
+            new_fields.append(rf)
+
+        body, content_type = encode_multipart_formdata(new_fields)
+
+        return body, content_type
+
+
+class RequestHooksMixin:
+    hooks: dict[str, list[_t.HookType]]
+
+    def register_hook(
+        self, event: str, hook: Iterable[_t.HookType] | _t.HookType
+    ) -> None:
+        """Properly register a hook."""
+
+        if event not in self.hooks:
+            raise ValueError(f'Unsupported event specified, with event name "{event}"')
+
+        if isinstance(hook, Callable):
+            self.hooks[event].append(hook)
+        elif hasattr(hook, "__iter__"):
+            self.hooks[event].extend(h for h in hook if isinstance(h, Callable))  # type: ignore[reportUnnecessaryIsInstance]  # defensive runtime filter
+
+    def deregister_hook(self, event: str, hook: _t.HookType) -> bool:
+        """Deregister a previously registered hook.
+        Returns True if the hook existed, False if not.
+        """
+
+        try:
+            self.hooks[event].remove(hook)
+            return True
+        except ValueError:
+            return False
+
+
+class Request(RequestHooksMixin):
+    """A user-created :class:`Request ` object.
+
+    Used to prepare a :class:`PreparedRequest `, which is sent to the server.
+
+    :param method: HTTP method to use.
+    :param url: URL to send.
+    :param headers: dictionary of headers to send.
+    :param files: dictionary of {filename: fileobject} files to multipart upload.
+    :param data: the body to attach to the request. If a dictionary or
+        list of tuples ``[(key, value)]`` is provided, form-encoding will
+        take place.
+    :param json: json for the body to attach to the request (if files or data is not specified).
+    :param params: URL parameters to append to the URL. If a dictionary or
+        list of tuples ``[(key, value)]`` is provided, form-encoding will
+        take place.
+    :param auth: Auth handler or (user, pass) tuple.
+    :param cookies: dictionary or CookieJar of cookies to attach to this request.
+    :param hooks: dictionary of callback hooks, for internal usage.
+
+    Usage::
+
+      >>> import requests
+      >>> req = requests.Request('GET', 'https://httpbin.org/get')
+      >>> req.prepare()
+      
+    """
+
+    method: str | None
+    url: _t.UriType | None
+    headers: Mapping[str, str | bytes]
+    files: _t.FilesType
+    data: _t.DataType
+    json: _t.JsonType
+    params: _t.ParamsType
+    auth: _t.AuthType
+    cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
+
+    def __init__(
+        self,
+        method: str | None = None,
+        url: _t.UriType | None = None,
+        headers: _t.HeadersType = None,
+        files: _t.FilesType = None,
+        data: _t.DataType = None,
+        params: _t.ParamsType = None,
+        auth: _t.AuthType = None,
+        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
+        hooks: _t.HooksInputType | None = None,
+        json: _t.JsonType = None,
+    ) -> None:
+        # Default empty dicts for dict params.
+        data = [] if data is None else data
+        files = [] if files is None else files
+        headers = {} if headers is None else headers
+        params = {} if params is None else params
+        hooks = {} if hooks is None else hooks
+
+        self.hooks = default_hooks()
+        for k, v in list(hooks.items()):
+            self.register_hook(event=k, hook=v)
+
+        self.method = method
+        self.url = url
+        self.headers = headers
+        self.files = files
+        self.data = data
+        self.json = json
+        self.params = params
+        self.auth = auth
+        self.cookies = cookies
+
+    def __repr__(self) -> str:
+        return f""
+
+    def prepare(self) -> PreparedRequest:
+        """Constructs a :class:`PreparedRequest ` for transmission and returns it."""
+        p = PreparedRequest()
+        p.prepare(
+            method=self.method,
+            url=self.url,
+            headers=self.headers,
+            files=self.files,
+            data=self.data,
+            json=self.json,
+            params=self.params,
+            auth=self.auth,
+            cookies=self.cookies,
+            hooks=self.hooks,
+        )
+        return p
+
+
+class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
+    """The fully mutable :class:`PreparedRequest ` object,
+    containing the exact bytes that will be sent to the server.
+
+    Instances are generated from a :class:`Request ` object, and
+    should not be instantiated manually; doing so may produce undesirable
+    effects.
+
+    Usage::
+
+      >>> import requests
+      >>> req = requests.Request('GET', 'https://httpbin.org/get')
+      >>> r = req.prepare()
+      >>> r
+      
+
+      >>> s = requests.Session()
+      >>> s.send(r)
+      
+    """
+
+    method: str | None
+    url: str | None
+    headers: CaseInsensitiveDict[str | bytes]
+    _cookies: RequestsCookieJar | CookieJar | None
+    body: _t.BodyType
+    hooks: dict[str, list[_t.HookType]]
+    _body_position: int | object | None
+
+    def __init__(self) -> None:
+        #: HTTP verb to send to the server.
+        self.method = None
+        #: HTTP URL to send the request to.
+        self.url = None
+        #: dictionary of HTTP headers.
+        self.headers = None  # type: ignore[assignment]
+        # The `CookieJar` used to create the Cookie header will be stored here
+        # after prepare_cookies is called
+        self._cookies = None
+        #: request body to send to the server.
+        self.body = None
+        #: dictionary of callback hooks, for internal usage.
+        self.hooks = default_hooks()
+        #: integer denoting starting position of a readable file-like body.
+        self._body_position = None
+
+    def prepare(
+        self,
+        method: str | None = None,
+        url: _t.UriType | None = None,
+        headers: Mapping[str, str | bytes] | None = None,
+        files: _t.FilesType = None,
+        data: _t.DataType = None,
+        params: _t.ParamsType = None,
+        auth: _t.AuthType = None,
+        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
+        hooks: _t.HooksInputType | None = None,
+        json: _t.JsonType = None,
+    ) -> None:
+        """Prepares the entire request with the given parameters."""
+
+        url = cast("_t.UriType", url)
+        self.prepare_method(method)
+        self.prepare_url(url, params)
+        self.prepare_headers(headers)
+        self.prepare_cookies(cookies)
+        self.prepare_body(data, files, json)
+        self.prepare_auth(auth, url)
+
+        # Note that prepare_auth must be last to enable authentication schemes
+        # such as OAuth to work on a fully prepared request.
+
+        # This MUST go after prepare_auth. Authenticators could add a hook
+        self.prepare_hooks(hooks)
+
+    def __repr__(self) -> str:
+        return f""
+
+    def copy(self) -> PreparedRequest:
+        p = PreparedRequest()
+        p.method = self.method
+        p.url = self.url
+        p.headers = self.headers.copy() if self.headers is not None else None  # type: ignore[assignment]
+        p._cookies = _copy_cookie_jar(self._cookies)
+        p.body = self.body
+        p.hooks = self.hooks
+        p._body_position = self._body_position
+        return p
+
+    def prepare_method(self, method: str | None) -> None:
+        """Prepares the given HTTP method."""
+        self.method = method
+        if self.method is not None:
+            self.method = to_native_string(self.method.upper())
+
+    @staticmethod
+    def _get_idna_encoded_host(host: str) -> str:
+        from opentelemetry.agent._vendor import idna
+
+        try:
+            host = idna.encode(host, uts46=True).decode("utf-8")
+        except idna.IDNAError:
+            raise UnicodeError
+        return host
+
+    def prepare_url(
+        self,
+        url: _t.UriType,
+        params: _t.ParamsType,
+    ) -> None:
+        """Prepares the given HTTP URL."""
+        #: Accept objects that have string representations.
+        #: We're unable to blindly call unicode/str functions
+        #: as this will include the bytestring indicator (b'')
+        #: on python 3.x.
+        #: https://github.com/psf/requests/pull/2238
+        if isinstance(url, bytes):
+            url = url.decode("utf8")
+        else:
+            url = str(url)
+
+        # Remove leading whitespaces from url
+        url = url.lstrip()
+
+        # Don't do any URL preparation for non-HTTP schemes like `mailto`,
+        # `data` etc to work around exceptions from `url_parse`, which
+        # handles RFC 3986 only.
+        if ":" in url and not url.lower().startswith("http"):
+            self.url = url
+            return
+
+        # Support for unicode domain names and paths.
+        try:
+            scheme, auth, host, port, path, query, fragment = parse_url(url)
+        except LocationParseError as e:
+            raise InvalidURL(*e.args)
+
+        if not scheme:
+            raise MissingSchema(
+                f"Invalid URL {url!r}: No scheme supplied. "
+                f"Perhaps you meant https://{url}?"
+            )
+
+        if not host:
+            raise InvalidURL(f"Invalid URL {url!r}: No host supplied")
+
+        # In general, we want to try IDNA encoding the hostname if the string contains
+        # non-ASCII characters. This allows users to automatically get the correct IDNA
+        # behaviour. For strings containing only ASCII characters, we need to also verify
+        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
+        if not unicode_is_ascii(host):
+            try:
+                host = self._get_idna_encoded_host(host)
+            except UnicodeError:
+                raise InvalidURL("URL has an invalid label.")
+        elif host.startswith(("*", ".")):
+            raise InvalidURL("URL has an invalid label.")
+
+        # Carefully reconstruct the network location
+        netloc = auth or ""
+        if netloc:
+            netloc += "@"
+        netloc += host
+        if port:
+            netloc += f":{port}"
+
+        # Bare domains aren't valid URLs.
+        if not path:
+            path = "/"
+
+        if isinstance(params, (str, bytes)):
+            params = to_native_string(params)
+
+        if params is not None:
+            enc_params = self._encode_params(params)
+        else:
+            enc_params = ""
+
+        if enc_params:
+            if query:
+                query = f"{query}&{enc_params}"
+            else:
+                query = enc_params
+
+        url = requote_uri(urlunparse((scheme, netloc, path, "", query, fragment)))
+        self.url = url
+
+    def prepare_headers(self, headers: Mapping[str, str | bytes] | None) -> None:
+        """Prepares the given HTTP headers."""
+
+        self.headers = CaseInsensitiveDict()
+        if headers:
+            for header in headers.items():
+                # Raise exception on invalid header value.
+                check_header_validity(header)
+                name, value = header
+                self.headers[to_native_string(name)] = value
+
+    def prepare_body(
+        self, data: _t.DataType, files: _t.FilesType, json: _t.JsonType = None
+    ) -> None:
+        """Prepares the given HTTP body data."""
+
+        # Check if file, fo, generator, iterator.
+        # If not, run through normal process.
+
+        # Nottin' on you.
+        body = None
+        content_type = None
+
+        if not data and json is not None:
+            # urllib3 requires a bytes-like body. Python 2's json.dumps
+            # provides this natively, but Python 3 gives a Unicode string.
+            content_type = "application/json"
+
+            try:
+                body = complexjson.dumps(json, allow_nan=False)
+            except ValueError as ve:
+                raise InvalidJSONError(ve, request=self)
+
+            if not isinstance(body, bytes):
+                body = body.encode("utf-8")
+
+        # data that proxies attributes to underlying objects needs hasattr
+        is_iterable = isinstance(data, Iterable) or hasattr(data, "__iter__")
+        if is_iterable and not isinstance(data, (str, bytes, list, tuple, Mapping)):
+            try:
+                length = super_len(data)
+            except (TypeError, AttributeError, UnsupportedOperation):
+                length = None
+
+            body = data
+
+            if getattr(body, "tell", None) is not None:
+                # Record the current file position before reading.
+                # This will allow us to rewind a file in the event
+                # of a redirect.
+                try:
+                    self._body_position = body.tell()  # type: ignore[union-attr]  # guarded by getattr check
+                except OSError:
+                    # This differentiates from None, allowing us to catch
+                    # a failed `tell()` later when trying to rewind the body
+                    self._body_position = object()
+
+            if files:
+                raise NotImplementedError(
+                    "Streamed bodies and files are mutually exclusive."
+                )
+
+            if length:
+                self.headers["Content-Length"] = builtin_str(length)
+            else:
+                self.headers["Transfer-Encoding"] = "chunked"
+        else:
+            # After is_stream filtering, remaining data is raw (not streamed)
+            raw_data = cast("_t.RawDataType | None", data)
+
+            # Multi-part file uploads.
+            if files:
+                (body, content_type) = self._encode_files(files, raw_data)
+            else:
+                if raw_data:
+                    body = self._encode_params(raw_data)
+                    if isinstance(data, basestring) or isinstance(data, _SupportsRead):
+                        content_type = None
+                    else:
+                        content_type = "application/x-www-form-urlencoded"
+
+            self.prepare_content_length(body)
+
+            # Add content-type if it wasn't explicitly provided.
+            if content_type and ("content-type" not in self.headers):
+                self.headers["Content-Type"] = content_type
+
+        self.body = body  # type: ignore[assignment]  # body transforms from DataType to BodyType
+
+    def prepare_content_length(self, body: _t.BodyType) -> None:
+        """Prepare Content-Length header based on request method and body"""
+        if body is not None:
+            length = super_len(body)
+            if length:
+                # If length exists, set it. Otherwise, we fallback
+                # to Transfer-Encoding: chunked.
+                self.headers["Content-Length"] = builtin_str(length)
+        elif (
+            self.method not in ("GET", "HEAD")
+            and self.headers.get("Content-Length") is None
+        ):
+            # Set Content-Length to 0 for methods that can have a body
+            # but don't provide one. (i.e. not GET or HEAD)
+            self.headers["Content-Length"] = "0"
+
+    def prepare_auth(
+        self,
+        auth: _t.AuthType,
+        url: _t.UriType = "",
+    ) -> None:
+        """Prepares the given HTTP auth data."""
+
+        # If no Auth is explicitly provided, extract it from the URL first.
+        if auth is None:
+            url_auth = get_auth_from_url(cast(str, self.url))
+            auth = url_auth if any(url_auth) else None
+
+        if auth:
+            if isinstance(auth, tuple) and len(auth) == 2:  # type: ignore[arg-type]  # pyright widens tuple from Callable in AuthType
+                # special-case basic HTTP auth
+                auth_handler = HTTPBasicAuth(*auth)  # type: ignore[arg-type]  # pyright widens tuple from Callable in AuthType
+            else:
+                # TODO: can be fixed by flipping the conditionals
+                auth_handler = cast("Callable[..., PreparedRequest]", auth)
+
+            # Allow auth to make its changes.
+            r = auth_handler(self)
+
+            # Update self to reflect the auth changes.
+            self.__dict__.update(r.__dict__)
+
+            # Recompute Content-Length
+            self.prepare_content_length(self.body)
+
+    def prepare_cookies(
+        self, cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
+    ) -> None:
+        """Prepares the given HTTP cookie data.
+
+        This function eventually generates a ``Cookie`` header from the
+        given cookies using cookielib. Due to cookielib's design, the header
+        will not be regenerated if it already exists, meaning this function
+        can only be called once for the life of the
+        :class:`PreparedRequest ` object. Any subsequent calls
+        to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
+        header is removed beforehand.
+        """
+        if isinstance(cookies, cookielib.CookieJar):
+            self._cookies = cookies
+        else:
+            self._cookies = cookiejar_from_dict(cookies)
+
+        cookies_jar = cast("CookieJar", self._cookies)
+        cookie_header = get_cookie_header(cookies_jar, self)
+        if cookie_header is not None:
+            self.headers["Cookie"] = cookie_header
+
+    def prepare_hooks(self, hooks: _t.HooksInputType | None) -> None:
+        """Prepares the given hooks."""
+        # hooks can be passed as None to the prepare method and to this
+        # method. To prevent iterating over None, simply use an empty list
+        # if hooks is False-y
+        hooks = hooks or {}
+        for event in hooks:
+            self.register_hook(event, hooks[event])
+
+
+class Response:
+    """The :class:`Response ` object, which contains a
+    server's response to an HTTP request.
+    """
+
+    _content: bytes | Literal[False] | None
+    _content_consumed: bool
+    _next: PreparedRequest | None
+    status_code: int
+    headers: CaseInsensitiveDict[str]
+    raw: Any
+    url: str
+    encoding: str | None
+    history: list[Response]
+    reason: str
+    cookies: RequestsCookieJar
+    elapsed: datetime.timedelta
+    request: PreparedRequest
+    connection: HTTPAdapter
+
+    __attrs__: list[str] = [
+        "_content",
+        "status_code",
+        "headers",
+        "url",
+        "history",
+        "encoding",
+        "reason",
+        "cookies",
+        "elapsed",
+        "request",
+    ]
+
+    def __init__(self) -> None:
+        self._content = False
+        self._content_consumed = False
+        self._next = None
+
+        #: Integer Code of responded HTTP Status, e.g. 404 or 200.
+        self.status_code = None  # type: ignore[assignment]
+
+        #: Case-insensitive Dictionary of Response Headers.
+        #: For example, ``headers['content-encoding']`` will return the
+        #: value of a ``'Content-Encoding'`` response header.
+        self.headers = CaseInsensitiveDict()
+
+        #: File-like object representation of response (for advanced usage).
+        #: Use of ``raw`` requires that ``stream=True`` be set on the request.
+        #: This requirement does not apply for use internally to Requests.
+        self.raw = None
+
+        #: Final URL location of Response.
+        self.url = None  # type: ignore[assignment]
+
+        #: Encoding to decode with when accessing r.text.
+        self.encoding = None
+
+        #: A list of :class:`Response ` objects from
+        #: the history of the Request. Any redirect responses will end
+        #: up here. The list is sorted from the oldest to the most recent request.
+        self.history = []
+
+        #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK".
+        self.reason = None  # type: ignore[assignment]
+
+        #: A CookieJar of Cookies the server sent back.
+        self.cookies = cookiejar_from_dict({})
+
+        #: The amount of time elapsed between sending the request
+        #: and the arrival of the response (as a timedelta).
+        #: This property specifically measures the time taken between sending
+        #: the first byte of the request and finishing parsing the headers. It
+        #: is therefore unaffected by consuming the response content or the
+        #: value of the ``stream`` keyword argument.
+        self.elapsed = datetime.timedelta(0)
+
+        #: The :class:`PreparedRequest ` object to which this
+        #: is a response.
+        self.request = None  # type: ignore[assignment]
+
+    def __enter__(self) -> Self:
+        return self
+
+    def __exit__(self, *args: Any) -> None:
+        self.close()
+
+    def __getstate__(self) -> dict[str, Any]:
+        # Consume everything; accessing the content attribute makes
+        # sure the content has been fully read.
+        if not self._content_consumed:
+            self.content
+
+        return {attr: getattr(self, attr, None) for attr in self.__attrs__}
+
+    def __setstate__(self, state: dict[str, Any]) -> None:
+        for name, value in state.items():
+            setattr(self, name, value)
+
+        # pickled objects do not have .raw
+        setattr(self, "_content_consumed", True)
+        setattr(self, "raw", None)
+
+    def __repr__(self) -> str:
+        return f""
+
+    def __bool__(self) -> bool:
+        """Returns True if :attr:`status_code` is less than 400.
+
+        This attribute checks if the status code of the response is between
+        400 and 600 to see if there was a client error or a server error. If
+        the status code, is between 200 and 400, this will return True. This
+        is **not** a check to see if the response code is ``200 OK``.
+        """
+        return self.ok
+
+    def __nonzero__(self) -> bool:
+        """Returns True if :attr:`status_code` is less than 400.
+
+        This attribute checks if the status code of the response is between
+        400 and 600 to see if there was a client error or a server error. If
+        the status code, is between 200 and 400, this will return True. This
+        is **not** a check to see if the response code is ``200 OK``.
+        """
+        return self.ok
+
+    def __iter__(self) -> Iterator[bytes]:
+        """Allows you to use a response as an iterator."""
+        return self.iter_content(128)
+
+    @property
+    def ok(self) -> bool:
+        """Returns True if :attr:`status_code` is less than 400, False if not.
+
+        This attribute checks if the status code of the response is between
+        400 and 600 to see if there was a client error or a server error. If
+        the status code is between 200 and 400, this will return True. This
+        is **not** a check to see if the response code is ``200 OK``.
+        """
+        try:
+            self.raise_for_status()
+        except HTTPError:
+            return False
+        return True
+
+    @property
+    def is_redirect(self) -> bool:
+        """True if this Response is a well-formed HTTP redirect that could have
+        been processed automatically (by :meth:`Session.resolve_redirects`).
+        """
+        return "location" in self.headers and self.status_code in REDIRECT_STATI
+
+    @property
+    def is_permanent_redirect(self) -> bool:
+        """True if this Response one of the permanent versions of redirect."""
+        return "location" in self.headers and self.status_code in (
+            codes.moved_permanently,
+            codes.permanent_redirect,
+        )
+
+    @property
+    def next(self) -> PreparedRequest | None:
+        """Returns a PreparedRequest for the next request in a redirect chain, if there is one."""
+        return self._next
+
+    @property
+    def apparent_encoding(self) -> str | None:
+        """The apparent encoding, provided by the charset_normalizer or chardet libraries."""
+        if chardet is not None:
+            return chardet.detect(self.content)["encoding"]
+        else:
+            # If no character detection library is available, we'll fall back
+            # to a standard Python utf-8 str.
+            return "utf-8"
+
+    @overload
+    def iter_content(
+        self, chunk_size: int | None = 1, decode_unicode: Literal[False] = False
+    ) -> Iterator[bytes]: ...
+    @overload
+    def iter_content(
+        self, chunk_size: int | None = 1, *, decode_unicode: Literal[True]
+    ) -> Iterator[str | bytes]: ...
+    def iter_content(
+        self, chunk_size: int | None = 1, decode_unicode: bool = False
+    ) -> Iterator[str | bytes]:
+        """Iterates over the response data.  When stream=True is set on the
+        request, this avoids reading the content at once into memory for
+        large responses.  The chunk size is the number of bytes it should
+        read into memory.  This is not necessarily the length of each item
+        returned as decoding can take place.
+
+        chunk_size must be of type int or None. A value of None will
+        function differently depending on the value of `stream`.
+        stream=True will read data as it arrives in whatever size the
+        chunks are received. If stream=False, data is returned as
+        a single chunk.
+
+        If decode_unicode is True, content will be decoded using encoding
+        information from the response. If no encoding information is available,
+        bytes will be returned. This can be bypassed by manually setting
+        `encoding` on the response.
+        """
+
+        def generate() -> Generator[bytes, None, None]:
+            # Special case for urllib3.
+            if hasattr(self.raw, "stream"):
+                try:
+                    yield from self.raw.stream(chunk_size, decode_content=True)
+                except ProtocolError as e:
+                    raise ChunkedEncodingError(e)
+                except DecodeError as e:
+                    raise ContentDecodingError(e)
+                except ReadTimeoutError as e:
+                    raise ConnectionError(e)
+                except SSLError as e:
+                    raise RequestsSSLError(e)
+            else:
+                # Standard file-like object.
+                while True:
+                    chunk = self.raw.read(chunk_size)
+                    if not chunk:
+                        break
+                    yield chunk
+
+            self._content_consumed = True
+
+        if self._content_consumed and isinstance(self._content, bool):
+            raise StreamConsumedError()
+        elif chunk_size is not None and not isinstance(chunk_size, int):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard for untyped callers
+            raise TypeError(
+                f"chunk_size must be an int, it is instead a {type(chunk_size)}."
+            )
+
+        if self._content_consumed:
+            # simulate reading small chunks of the content
+            content = cast(bytes, self._content)
+            chunks = iter_slices(content, chunk_size)
+        else:
+            chunks = generate()
+
+        if decode_unicode:
+            chunks = stream_decode_response_unicode(chunks, self)
+
+        return chunks
+
+    @overload
+    def iter_lines(
+        self,
+        chunk_size: int = ITER_CHUNK_SIZE,
+        decode_unicode: Literal[False] = False,
+        delimiter: bytes | None = None,
+    ) -> Iterator[bytes]: ...
+    @overload
+    def iter_lines(
+        self,
+        chunk_size: int = ITER_CHUNK_SIZE,
+        *,
+        decode_unicode: Literal[True],
+        delimiter: str | bytes | None = None,
+    ) -> Iterator[str | bytes]: ...
+    def iter_lines(
+        self,
+        chunk_size: int = ITER_CHUNK_SIZE,
+        decode_unicode: bool = False,
+        delimiter: str | bytes | None = None,
+    ) -> Iterator[str | bytes]:
+        """Iterates over the response data, one line at a time.  When
+        stream=True is set on the request, this avoids reading the
+        content at once into memory for large responses.
+
+        The decode_unicode param works the same as in `iter_content`, with the
+        same caveats.
+
+        .. note:: This method is not reentrant safe.
+        """
+
+        pending: str | bytes | None = None
+
+        for chunk in self.iter_content(
+            chunk_size=chunk_size, decode_unicode=decode_unicode
+        ):
+            if pending is not None:
+                # TODO: remove cast after iter_lines rewrite
+                chunk = cast("str | bytes", pending + chunk)  # type: ignore[operator]
+
+            if delimiter:
+                lines = chunk.split(delimiter)  # type: ignore[arg-type]
+            else:
+                lines = chunk.splitlines()
+
+            if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
+                pending = lines.pop()
+            else:
+                pending = None
+
+            yield from lines
+
+        if pending is not None:
+            yield pending
+
+    @property
+    def content(self) -> bytes:
+        """Content of the response, in bytes."""
+
+        if self._content is False:
+            # Read the contents.
+            if self._content_consumed:
+                raise RuntimeError("The content for this response was already consumed")
+
+            if self.status_code == 0 or self.raw is None:
+                self._content = None
+            else:
+                self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
+
+        self._content_consumed = True
+        # don't need to release the connection; that's been handled by urllib3
+        # since we exhausted the data.
+        return self._content  # type: ignore[return-value]
+
+    @property
+    def text(self) -> str:
+        """Content of the response, in unicode.
+
+        If Response.encoding is None, encoding will be guessed using
+        ``charset_normalizer`` or ``chardet``.
+
+        The encoding of the response content is determined based solely on HTTP
+        headers, following RFC 2616 to the letter. If you can take advantage of
+        non-HTTP knowledge to make a better guess at the encoding, you should
+        set ``r.encoding`` appropriately before accessing this property.
+        """
+
+        # Try charset from content-type
+        content = None
+        encoding = self.encoding
+
+        if not self.content:
+            return ""
+
+        # Fallback to auto-detected encoding.
+        if self.encoding is None:
+            encoding = self.apparent_encoding
+
+        # Decode unicode from given encoding.
+        try:
+            content = str(self.content, encoding or "utf-8", errors="replace")
+        except (LookupError, TypeError):
+            # A LookupError is raised if the encoding was not found which could
+            # indicate a misspelling or similar mistake.
+            #
+            # A TypeError can be raised if encoding is None
+            #
+            # So we try blindly encoding.
+            content = str(self.content, errors="replace")
+
+        return content
+
+    def json(self, **kwargs: Any) -> Any:
+        r"""Decodes the JSON response body (if any) as a Python object.
+
+        This may return a dictionary, list, etc. depending on what is in the response.
+
+        :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
+        :raises requests.exceptions.JSONDecodeError: If the response body does not
+            contain valid json.
+        """
+
+        if not self.encoding and self.content and len(self.content) > 3:
+            # No encoding set. JSON RFC 4627 section 3 states we should expect
+            # UTF-8, -16 or -32. Detect which one to use; If the detection or
+            # decoding fails, fall back to `self.text` (using charset_normalizer to make
+            # a best guess).
+            encoding = guess_json_utf(self.content)
+            if encoding is not None:
+                try:
+                    return complexjson.loads(self.content.decode(encoding), **kwargs)
+                except UnicodeDecodeError:
+                    # Wrong UTF codec detected; usually because it's not UTF-8
+                    # but some other 8-bit codec.  This is an RFC violation,
+                    # and the server didn't bother to tell us what codec *was*
+                    # used.
+                    pass
+                except JSONDecodeError as e:
+                    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
+
+        try:
+            return complexjson.loads(self.text, **kwargs)
+        except JSONDecodeError as e:
+            # Catch JSON-related errors and raise as requests.JSONDecodeError
+            # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
+            raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
+
+    @property
+    def links(self) -> dict[str, dict[str, str]]:
+        """Returns the parsed header links of the response, if any."""
+
+        header = self.headers.get("link")
+
+        resolved_links: dict[str, dict[str, str]] = {}
+
+        if header:
+            links = parse_header_links(header)
+
+            for link in links:
+                key = link.get("rel") or link.get("url")
+                if key is not None:
+                    resolved_links[key] = link
+
+        return resolved_links
+
+    def raise_for_status(self) -> None:
+        """Raises :class:`HTTPError`, if one occurred."""
+
+        http_error_msg = ""
+        if isinstance(self.reason, bytes):
+            # We attempt to decode utf-8 first because some servers
+            # choose to localize their reason strings. If the string
+            # isn't utf-8, we fall back to iso-8859-1 for all other
+            # encodings. (See PR #3538)
+            try:
+                reason = self.reason.decode("utf-8")
+            except UnicodeDecodeError:
+                reason = self.reason.decode("iso-8859-1")
+        else:
+            reason = self.reason
+
+        if 400 <= self.status_code < 500:
+            http_error_msg = (
+                f"{self.status_code} Client Error: {reason} for url: {self.url}"
+            )
+
+        elif 500 <= self.status_code < 600:
+            http_error_msg = (
+                f"{self.status_code} Server Error: {reason} for url: {self.url}"
+            )
+
+        if http_error_msg:
+            raise HTTPError(http_error_msg, response=self)
+
+    def close(self) -> None:
+        """Releases the connection back to the pool. Once this method has been
+        called the underlying ``raw`` object must not be accessed again.
+
+        *Note: Should not normally need to be called explicitly.*
+        """
+        if not self._content_consumed:
+            self.raw.close()
+
+        release_conn = getattr(self.raw, "release_conn", None)
+        if release_conn is not None:
+            release_conn()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py
new file mode 100644
index 00000000000..e183060ee4b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py
@@ -0,0 +1,4 @@
+# The upstream module imports urllib3, idna and chardet by their top-level names and
+# registers them as `requests.packages.*` in the global sys.modules. In the vendored copy
+# that would load (and alias) the application's own packages, so the backwards
+# compatibility aliases are disabled.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py
new file mode 100644
index 00000000000..d0e28e39d4a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py
@@ -0,0 +1,920 @@
+"""
+requests.sessions
+~~~~~~~~~~~~~~~~~
+
+This module provides a Session object to manage and persist settings across
+requests (cookies, auth, proxies).
+"""
+
+from __future__ import annotations
+
+import os
+import sys
+import time
+from collections import OrderedDict
+from collections.abc import Generator, Mapping, MutableMapping
+from datetime import timedelta
+from typing import TYPE_CHECKING, Any, cast
+
+from ._internal_utils import to_native_string
+from ._types import is_prepared as _is_prepared
+from .adapters import HTTPAdapter
+from .auth import _basic_auth_str  # type: ignore[reportPrivateUsage]
+from .compat import cookielib, urljoin, urlparse
+from .cookies import (
+    RequestsCookieJar,
+    cookiejar_from_dict,
+    extract_cookies_to_jar,
+    merge_cookies,
+)
+from .exceptions import (
+    ChunkedEncodingError,
+    ContentDecodingError,
+    InvalidSchema,
+    TooManyRedirects,
+)
+from .hooks import default_hooks, dispatch_hook
+
+# formerly defined here, reexposed here for backward compatibility
+from .models import (  # noqa: F401
+    DEFAULT_REDIRECT_LIMIT,
+    REDIRECT_STATI,  # type: ignore[reportUnusedImport]
+    PreparedRequest,
+    Request,
+    Response,
+)
+from .status_codes import codes
+from .structures import CaseInsensitiveDict
+from .utils import (  # noqa: F401
+    DEFAULT_PORTS,
+    default_headers,
+    get_auth_from_url,
+    get_environ_proxies,
+    get_netrc_auth,
+    requote_uri,
+    resolve_proxies,
+    rewind_body,
+    should_bypass_proxies,  # type: ignore[reportUnusedImport]  # re-export for external consumers
+    to_key_val_list,
+)
+
+if TYPE_CHECKING:
+    from http.cookiejar import CookieJar
+
+    from opentelemetry.agent._vendor.typing_extensions import Self, Unpack
+
+    from . import _types as _t
+    from .adapters import BaseAdapter
+
+# Preferred clock, based on which one is more accurate on a given system.
+if sys.platform == "win32":
+    preferred_clock = time.perf_counter
+else:
+    preferred_clock = time.time
+
+
+def merge_setting(
+    request_setting: Any, session_setting: Any, dict_class: type = OrderedDict
+) -> Any:
+    """Determines appropriate setting for a given request, taking into account
+    the explicit setting on that request, and the setting in the session. If a
+    setting is a dictionary, they will be merged together using `dict_class`
+    """
+
+    if session_setting is None:
+        return request_setting
+
+    if request_setting is None:
+        return session_setting
+
+    # Bypass if not a dictionary (e.g. verify)
+    if not (
+        isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
+    ):
+        return request_setting
+
+    merged_setting = dict_class(to_key_val_list(session_setting))  # type: ignore[arg-type]  # isinstance narrows Any to Mapping[Unknown]
+    merged_setting.update(to_key_val_list(request_setting))  # type: ignore[arg-type]
+
+    # Remove keys that are set to None. Extract keys first to avoid altering
+    # the dictionary during iteration.
+    none_keys = [k for (k, v) in merged_setting.items() if v is None]
+    for key in none_keys:
+        del merged_setting[key]
+
+    return merged_setting
+
+
+def merge_hooks(
+    request_hooks: _t.HooksType,
+    session_hooks: _t.HooksType,
+    dict_class: type = OrderedDict,
+) -> _t.HooksType:
+    """Properly merges both requests and session hooks.
+
+    This is necessary because when request_hooks == {'response': []}, the
+    merge breaks Session hooks entirely.
+    """
+    if session_hooks is None or session_hooks.get("response") == []:
+        return request_hooks
+
+    if request_hooks is None or request_hooks.get("response") == []:
+        return session_hooks
+
+    return merge_setting(request_hooks, session_hooks, dict_class)
+
+
+class SessionRedirectMixin:
+    max_redirects: int
+    trust_env: bool
+    cookies: RequestsCookieJar
+
+    def send(self, request: PreparedRequest, **kwargs: Any) -> Response: ...
+
+    def get_redirect_target(self, resp: Response) -> str | None:
+        """Receives a Response. Returns a redirect URI or ``None``"""
+        # Due to the nature of how requests processes redirects this method will
+        # be called at least once upon the original response and at least twice
+        # on each subsequent redirect response (if any).
+        # If a custom mixin is used to handle this logic, it may be advantageous
+        # to cache the redirect location onto the response object as a private
+        # attribute.
+        if resp.is_redirect:
+            location = resp.headers["location"]
+            # Currently the underlying http module on py3 decode headers
+            # in latin1, but empirical evidence suggests that latin1 is very
+            # rarely used with non-ASCII characters in HTTP headers.
+            # It is more likely to get UTF8 header rather than latin1.
+            # This causes incorrect handling of UTF8 encoded location headers.
+            # To solve this, we re-encode the location in latin1.
+            location = location.encode("latin1")
+            return to_native_string(location, "utf8")
+        return None
+
+    def should_strip_auth(self, old_url: str, new_url: str) -> bool:
+        """Decide whether Authorization header should be removed when redirecting"""
+        old_parsed = urlparse(old_url)
+        new_parsed = urlparse(new_url)
+        if old_parsed.hostname != new_parsed.hostname:
+            return True
+        # Special case: allow http -> https redirect when using the standard
+        # ports. This isn't specified by RFC 7235, but is kept to avoid
+        # breaking backwards compatibility with older versions of requests
+        # that allowed any redirects on the same host.
+        if (
+            old_parsed.scheme == "http"
+            and old_parsed.port in (80, None)
+            and new_parsed.scheme == "https"
+            and new_parsed.port in (443, None)
+        ):
+            return False
+
+        # Handle default port usage corresponding to scheme.
+        changed_port = old_parsed.port != new_parsed.port
+        changed_scheme = old_parsed.scheme != new_parsed.scheme
+        default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)
+        if (
+            not changed_scheme
+            and old_parsed.port in default_port
+            and new_parsed.port in default_port
+        ):
+            return False
+
+        # Standard case: root URI must match
+        return changed_port or changed_scheme
+
+    def resolve_redirects(
+        self,
+        resp: Response,
+        req: PreparedRequest,
+        stream: bool = False,
+        timeout: _t.TimeoutType = None,
+        verify: _t.VerifyType = True,
+        cert: _t.CertType = None,
+        proxies: dict[str, str] | None = None,
+        yield_requests: bool = False,
+        **adapter_kwargs: Any,
+    ) -> Generator[Response, None, None]:
+        """Receives a Response. Returns a generator of Responses or Requests."""
+
+        hist: list[Response] = []  # keep track of history
+
+        url = self.get_redirect_target(resp)
+        previous_fragment = urlparse(req.url).fragment
+        while url:
+            prepared_request = req.copy()
+
+            # Update history and keep track of redirects.
+            resp.history = hist[:]
+            hist.append(resp)
+
+            try:
+                resp.content  # Consume socket so it can be released
+            except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
+                resp.raw.read(decode_content=False)
+
+            if len(resp.history) >= self.max_redirects:
+                raise TooManyRedirects(
+                    f"Exceeded {self.max_redirects} redirects.", response=resp
+                )
+
+            # Release the connection back into the pool.
+            resp.close()
+
+            # Handle redirection without scheme (see: RFC 1808 Section 4)
+            if url.startswith("//"):
+                parsed_rurl = urlparse(resp.url)
+                url = ":".join([to_native_string(parsed_rurl.scheme), url])
+
+            # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
+            parsed = urlparse(url)
+            if parsed.fragment == "" and previous_fragment:
+                parsed = parsed._replace(fragment=previous_fragment)
+            elif parsed.fragment:
+                previous_fragment = parsed.fragment
+            url = parsed.geturl()
+
+            # Facilitate relative 'location' headers, as allowed by RFC 7231.
+            # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
+            # Compliant with RFC3986, we percent encode the url.
+            if not parsed.netloc:
+                url = urljoin(resp.url, requote_uri(url))
+            else:
+                url = requote_uri(url)
+
+            prepared_request.url = to_native_string(url)
+
+            self.rebuild_method(prepared_request, resp)
+
+            # https://github.com/psf/requests/issues/1084
+            if resp.status_code not in (
+                codes.temporary_redirect,
+                codes.permanent_redirect,
+            ):
+                # https://github.com/psf/requests/issues/3490
+                purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding")
+                for header in purged_headers:
+                    prepared_request.headers.pop(header, None)
+                prepared_request.body = None
+
+            headers = prepared_request.headers
+            headers.pop("Cookie", None)
+
+            # Extract any cookies sent on the response to the cookiejar
+            # in the new request. Because we've mutated our copied prepared
+            # request, use the old one that we haven't yet touched.
+            cookie_jar = cast("CookieJar", prepared_request._cookies)  # type: ignore[reportPrivateUsage]
+            extract_cookies_to_jar(cookie_jar, req, resp.raw)
+            merge_cookies(cookie_jar, self.cookies)
+            prepared_request.prepare_cookies(cookie_jar)
+
+            # Rebuild auth and proxy information.
+            proxies = self.rebuild_proxies(prepared_request, proxies)
+            self.rebuild_auth(prepared_request, resp)
+
+            # A failed tell() sets `_body_position` to `object()`. This non-None
+            # value ensures `rewindable` will be True, allowing us to raise an
+            # UnrewindableBodyError, instead of hanging the connection.
+            rewindable = prepared_request._body_position is not None and (  # type: ignore[reportPrivateUsage]
+                "Content-Length" in headers or "Transfer-Encoding" in headers
+            )
+
+            # Attempt to rewind consumed file-like object.
+            if rewindable:
+                rewind_body(prepared_request)
+
+            # Override the original request.
+            req = prepared_request
+
+            if yield_requests:
+                yield req  # type: ignore[misc]  # Internal use only, returns PreparedRequest
+            else:
+                resp = self.send(
+                    req,
+                    stream=stream,
+                    timeout=timeout,
+                    verify=verify,
+                    cert=cert,
+                    proxies=proxies,
+                    allow_redirects=False,
+                    **adapter_kwargs,
+                )
+
+                extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
+
+                # extract redirect url, if any, for the next loop
+                url = self.get_redirect_target(resp)
+                yield resp
+
+    def rebuild_auth(
+        self, prepared_request: PreparedRequest, response: Response
+    ) -> None:
+        """When being redirected we may want to strip authentication from the
+        request to avoid leaking credentials. This method intelligently removes
+        and reapplies authentication where possible to avoid credential loss.
+        """
+        original_request = response.request
+        assert _is_prepared(original_request)
+        assert _is_prepared(prepared_request)
+
+        headers = prepared_request.headers
+        original_url = original_request.url
+        url = prepared_request.url
+
+        if "Authorization" in headers and self.should_strip_auth(original_url, url):
+            # If we get redirected to a new host, we should strip out any
+            # authentication headers.
+            del headers["Authorization"]
+
+        # .netrc might have more auth for us on our new host.
+        new_auth = get_netrc_auth(url) if self.trust_env else None
+        if new_auth is not None:
+            prepared_request.prepare_auth(new_auth)
+
+    def rebuild_proxies(
+        self,
+        prepared_request: PreparedRequest,
+        proxies: dict[str, str] | None,
+    ) -> dict[str, str]:
+        """This method re-evaluates the proxy configuration by considering the
+        environment variables. If we are redirected to a URL covered by
+        NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
+        proxy keys for this URL (in case they were stripped by a previous
+        redirect).
+
+        This method also replaces the Proxy-Authorization header where
+        necessary.
+
+        :rtype: dict
+        """
+        assert _is_prepared(prepared_request)
+        headers = prepared_request.headers
+        scheme = urlparse(prepared_request.url).scheme
+        new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
+
+        if "Proxy-Authorization" in headers:
+            del headers["Proxy-Authorization"]
+
+        try:
+            username, password = get_auth_from_url(new_proxies[scheme])
+        except KeyError:
+            username, password = None, None
+
+        # urllib3 handles proxy authorization for us in the standard adapter.
+        # Avoid appending this to TLS tunneled requests where it may be leaked.
+        if not scheme.startswith("https") and username and password:
+            headers["Proxy-Authorization"] = _basic_auth_str(username, password)
+
+        return new_proxies
+
+    def rebuild_method(
+        self, prepared_request: PreparedRequest, response: Response
+    ) -> None:
+        """When being redirected we may want to change the method of the request
+        based on certain specs or browser behavior.
+        """
+        method = prepared_request.method
+
+        # https://tools.ietf.org/html/rfc7231#section-6.4.4
+        if response.status_code == codes.see_other and method != "HEAD":
+            method = "GET"
+
+        # Do what the browsers do, despite standards...
+        # First, turn 302s into GETs.
+        if response.status_code == codes.found and method != "HEAD":
+            method = "GET"
+
+        # Second, if a POST is responded to with a 301, turn it into a GET.
+        # This bizarre behaviour is explained in Issue 1704.
+        if response.status_code == codes.moved and method == "POST":
+            method = "GET"
+
+        prepared_request.method = method
+
+
+class Session(SessionRedirectMixin):
+    """A Requests session.
+
+    Provides cookie persistence, connection-pooling, and configuration.
+
+    Basic Usage::
+
+      >>> import requests
+      >>> s = requests.Session()
+      >>> s.get('https://httpbin.org/get')
+      
+
+    Or as a context manager::
+
+      >>> with requests.Session() as s:
+      ...     s.get('https://httpbin.org/get')
+      
+    """
+
+    headers: CaseInsensitiveDict[str]
+    auth: _t.AuthType
+    proxies: dict[str, str]
+    hooks: dict[str, list[_t.HookType]]
+    params: MutableMapping[str, Any]
+    stream: bool
+    verify: _t.VerifyType
+    cert: _t.CertType
+    max_redirects: int
+    trust_env: bool
+    cookies: RequestsCookieJar
+    adapters: MutableMapping[str, BaseAdapter]
+
+    __attrs__: list[str] = [
+        "headers",
+        "cookies",
+        "auth",
+        "proxies",
+        "hooks",
+        "params",
+        "verify",
+        "cert",
+        "adapters",
+        "stream",
+        "trust_env",
+        "max_redirects",
+    ]
+
+    def __init__(self) -> None:
+        #: A case-insensitive dictionary of headers to be sent on each
+        #: :class:`Request ` sent from this
+        #: :class:`Session `.
+        self.headers = default_headers()
+
+        #: Default Authentication tuple or object to attach to
+        #: :class:`Request `.
+        self.auth = None
+
+        #: Dictionary mapping protocol or protocol and host to the URL of the proxy
+        #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to
+        #: be used on each :class:`Request `.
+        self.proxies = {}
+
+        #: Event-handling hooks.
+        self.hooks = default_hooks()
+
+        #: Dictionary of querystring data to attach to each
+        #: :class:`Request `. The dictionary values may be lists for
+        #: representing multivalued query parameters.
+        self.params = {}
+
+        #: Stream response content default.
+        self.stream = False
+
+        #: SSL Verification default.
+        #: Defaults to `True`, requiring requests to verify the TLS certificate at the
+        #: remote end.
+        #: If verify is set to `False`, requests will accept any TLS certificate
+        #: presented by the server, and will ignore hostname mismatches and/or
+        #: expired certificates, which will make your application vulnerable to
+        #: man-in-the-middle (MitM) attacks.
+        #: Only set this to `False` for testing.
+        #: If verify is set to a string, it must be the path to a CA bundle file
+        #: that will be used to verify the TLS certificate.
+        self.verify = True
+
+        #: SSL client certificate default, if String, path to ssl client
+        #: cert file (.pem). If Tuple, ('cert', 'key') pair.
+        self.cert = None
+
+        #: Maximum number of redirects allowed. If the request exceeds this
+        #: limit, a :class:`TooManyRedirects` exception is raised.
+        #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is
+        #: 30.
+        self.max_redirects = DEFAULT_REDIRECT_LIMIT
+
+        #: Trust environment settings for proxy configuration, default
+        #: authentication and similar.
+        self.trust_env = True
+
+        #: A CookieJar containing all currently outstanding cookies set on this
+        #: session. By default it is a
+        #: :class:`RequestsCookieJar `, but
+        #: may be any other ``cookielib.CookieJar`` compatible object.
+        self.cookies = cookiejar_from_dict({})
+
+        # Default connection adapters.
+        self.adapters = OrderedDict()
+        self.mount("https://", HTTPAdapter())
+        self.mount("http://", HTTPAdapter())
+
+    def __enter__(self) -> Self:
+        return self
+
+    def __exit__(self, *args: Any) -> None:
+        self.close()
+
+    def prepare_request(self, request: Request) -> PreparedRequest:
+        """Constructs a :class:`PreparedRequest ` for
+        transmission and returns it. The :class:`PreparedRequest` has settings
+        merged from the :class:`Request ` instance and those of the
+        :class:`Session`.
+
+        :param request: :class:`Request` instance to prepare with this
+            session's settings.
+        :rtype: requests.PreparedRequest
+        """
+        url = cast("_t.UriType", request.url)
+        method = cast(str, request.method)
+
+        cookies = request.cookies or {}
+
+        # Bootstrap CookieJar.
+        if not isinstance(cookies, cookielib.CookieJar):
+            cookies = cookiejar_from_dict(cookies)
+
+        # Merge with session cookies
+        merged_cookies = merge_cookies(
+            merge_cookies(RequestsCookieJar(), self.cookies), cookies
+        )
+
+        # Set environment's basic authentication if not explicitly set.
+        auth = request.auth
+        if self.trust_env and not auth and not self.auth:
+            auth = get_netrc_auth(url)
+
+        p = PreparedRequest()
+        p.prepare(
+            method=method.upper(),
+            url=url,
+            files=request.files,
+            data=request.data,
+            json=request.json,
+            headers=merge_setting(
+                request.headers, self.headers, dict_class=CaseInsensitiveDict
+            ),
+            params=merge_setting(request.params, self.params),
+            auth=merge_setting(auth, self.auth),
+            cookies=merged_cookies,
+            hooks=merge_hooks(request.hooks, self.hooks),
+        )
+        return p
+
+    def request(
+        self,
+        method: str,
+        url: _t.UriType,
+        params: _t.ParamsType = None,
+        data: _t.DataType = None,
+        headers: _t.HeadersType = None,
+        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
+        files: _t.FilesType = None,
+        auth: _t.AuthType = None,
+        timeout: _t.TimeoutType = None,
+        allow_redirects: bool = True,
+        proxies: dict[str, str] | None = None,
+        hooks: _t.HooksInputType | None = None,
+        stream: bool | None = None,
+        verify: _t.VerifyType | None = None,
+        cert: _t.CertType = None,
+        json: _t.JsonType = None,
+    ) -> Response:
+        """Constructs a :class:`Request `, prepares it and sends it.
+        Returns :class:`Response ` object.
+
+        :param method: method for the new :class:`Request` object.
+        :param url: URL for the new :class:`Request` object.
+        :param params: (optional) Dictionary or bytes to be sent in the query
+            string for the :class:`Request`.
+        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+            object to send in the body of the :class:`Request`.
+        :param json: (optional) json to send in the body of the
+            :class:`Request`.
+        :param headers: (optional) Dictionary of HTTP Headers to send with the
+            :class:`Request`.
+        :param cookies: (optional) Dict or CookieJar object to send with the
+            :class:`Request`.
+        :param files: (optional) Dictionary of ``'filename': file-like-objects``
+            for multipart encoding upload.
+        :param auth: (optional) Auth tuple or callable to enable
+            Basic/Digest/Custom HTTP Auth.
+        :param timeout: (optional) How many seconds to wait for the server to send
+            data before giving up, as a float, or a :ref:`(connect timeout,
+            read timeout) ` tuple.
+        :type timeout: float or tuple
+        :param allow_redirects: (optional) Set to True by default.
+        :type allow_redirects: bool
+        :param proxies: (optional) Dictionary mapping protocol or protocol and
+            hostname to the URL of the proxy.
+        :param hooks: (optional) Dictionary mapping hook name to one event or
+            list of events, event must be callable.
+        :param stream: (optional) whether to immediately download the response
+            content. Defaults to ``False``.
+        :param verify: (optional) Either a boolean, in which case it controls whether we verify
+            the server's TLS certificate, or a string, in which case it must be a path
+            to a CA bundle to use. Defaults to ``True``. When set to
+            ``False``, requests will accept any TLS certificate presented by
+            the server, and will ignore hostname mismatches and/or expired
+            certificates, which will make your application vulnerable to
+            man-in-the-middle (MitM) attacks. Setting verify to ``False``
+            may be useful during local development or testing.
+        :param cert: (optional) if String, path to ssl client cert file (.pem).
+            If Tuple, ('cert', 'key') pair.
+        :rtype: requests.Response
+        """
+        if isinstance(url, bytes):
+            url = url.decode("utf-8")
+
+        # Create the Request.
+        req = Request(
+            method=method.upper(),
+            url=url,
+            headers=headers,
+            files=files,
+            data=data or {},
+            json=json,
+            params=params or {},
+            auth=auth,
+            cookies=cookies,
+            hooks=hooks,
+        )
+        prep = self.prepare_request(req)
+
+        assert _is_prepared(prep)
+
+        proxies = proxies or {}
+
+        settings = self.merge_environment_settings(
+            prep.url, proxies, stream, verify, cert
+        )
+
+        # Send the request.
+        send_kwargs = {
+            "timeout": timeout,
+            "allow_redirects": allow_redirects,
+        }
+        send_kwargs.update(settings)
+        resp = self.send(prep, **send_kwargs)
+
+        return resp
+
+    def get(
+        self,
+        url: _t.UriType,
+        params: _t.ParamsType = None,
+        **kwargs: Unpack[_t.GetKwargs],
+    ) -> Response:
+        r"""Sends a GET request. Returns :class:`Response` object.
+
+        :param url: URL for the new :class:`Request` object.
+        :param params: (optional) Dictionary, list of tuples or bytes to send
+        in the query string for the :class:`Request`.
+        :param \*\*kwargs: Optional arguments that ``request`` takes.
+        :rtype: requests.Response
+        """
+
+        kwargs.setdefault("allow_redirects", True)
+        return self.request("GET", url, params=params, **kwargs)
+
+    def options(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
+        r"""Sends a OPTIONS request. Returns :class:`Response` object.
+
+        :param url: URL for the new :class:`Request` object.
+        :param \*\*kwargs: Optional arguments that ``request`` takes.
+        :rtype: requests.Response
+        """
+
+        kwargs.setdefault("allow_redirects", True)
+        return self.request("OPTIONS", url, **kwargs)
+
+    def head(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
+        r"""Sends a HEAD request. Returns :class:`Response` object.
+
+        :param url: URL for the new :class:`Request` object.
+        :param \*\*kwargs: Optional arguments that ``request`` takes.
+        :rtype: requests.Response
+        """
+
+        kwargs.setdefault("allow_redirects", False)
+        return self.request("HEAD", url, **kwargs)
+
+    def post(
+        self,
+        url: _t.UriType,
+        data: _t.DataType = None,
+        json: _t.JsonType = None,
+        **kwargs: Unpack[_t.PostKwargs],
+    ) -> Response:
+        r"""Sends a POST request. Returns :class:`Response` object.
+
+        :param url: URL for the new :class:`Request` object.
+        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+            object to send in the body of the :class:`Request`.
+        :param json: (optional) json to send in the body of the :class:`Request`.
+        :param \*\*kwargs: Optional arguments that ``request`` takes.
+        :rtype: requests.Response
+        """
+
+        return self.request("POST", url, data=data, json=json, **kwargs)
+
+    def put(
+        self, url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
+    ) -> Response:
+        r"""Sends a PUT request. Returns :class:`Response` object.
+
+        :param url: URL for the new :class:`Request` object.
+        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+            object to send in the body of the :class:`Request`.
+        :param \*\*kwargs: Optional arguments that ``request`` takes.
+        :rtype: requests.Response
+        """
+
+        return self.request("PUT", url, data=data, **kwargs)
+
+    def patch(
+        self, url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
+    ) -> Response:
+        r"""Sends a PATCH request. Returns :class:`Response` object.
+
+        :param url: URL for the new :class:`Request` object.
+        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+            object to send in the body of the :class:`Request`.
+        :param \*\*kwargs: Optional arguments that ``request`` takes.
+        :rtype: requests.Response
+        """
+
+        return self.request("PATCH", url, data=data, **kwargs)
+
+    def delete(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
+        r"""Sends a DELETE request. Returns :class:`Response` object.
+
+        :param url: URL for the new :class:`Request` object.
+        :param \*\*kwargs: Optional arguments that ``request`` takes.
+        :rtype: requests.Response
+        """
+
+        return self.request("DELETE", url, **kwargs)
+
+    def send(self, request: PreparedRequest, **kwargs: Any) -> Response:
+        """Send a given PreparedRequest.
+
+        :rtype: requests.Response
+        """
+        # Set defaults that the hooks can utilize to ensure they always have
+        # the correct parameters to reproduce the previous request.
+        kwargs.setdefault("stream", self.stream)
+        kwargs.setdefault("verify", self.verify)
+        kwargs.setdefault("cert", self.cert)
+        if "proxies" not in kwargs:
+            kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env)
+
+        # It's possible that users might accidentally send a Request object.
+        # Guard against that specific failure case.
+        if isinstance(request, Request):
+            raise ValueError("You can only send PreparedRequests.")
+
+        assert _is_prepared(request)
+
+        # Set up variables needed for resolve_redirects and dispatching of hooks
+        allow_redirects = kwargs.pop("allow_redirects", True)
+        stream = kwargs.get("stream")
+        hooks = request.hooks
+
+        # Get the appropriate adapter to use
+        adapter = self.get_adapter(url=request.url)
+
+        # Start time (approximately) of the request
+        start = preferred_clock()
+
+        # Send the request
+        r = adapter.send(request, **kwargs)
+
+        # Total elapsed time of the request (approximately)
+        elapsed = preferred_clock() - start
+        r.elapsed = timedelta(seconds=elapsed)
+
+        # Response manipulation hooks
+        r = dispatch_hook("response", hooks, r, **kwargs)
+
+        # Persist cookies
+        if r.history:
+            # If the hooks create history then we want those cookies too
+            for resp in r.history:
+                extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
+
+        extract_cookies_to_jar(self.cookies, request, r.raw)
+
+        # Resolve redirects if allowed.
+        if allow_redirects:
+            # Redirect resolving generator.
+            gen = self.resolve_redirects(r, request, **kwargs)
+            history = [resp for resp in gen]
+        else:
+            history = []
+
+        # Shuffle things around if there's history.
+        if history:
+            # Insert the first (original) request at the start
+            history.insert(0, r)
+            # Get the last request made
+            r = history.pop()
+            r.history = history
+
+        # If redirects aren't being followed, store the response on the Request for Response.next().
+        if not allow_redirects:
+            try:
+                r._next = next(  # type: ignore[assignment]  # yield_requests=True returns PreparedRequest
+                    self.resolve_redirects(r, request, yield_requests=True, **kwargs)
+                )
+            except StopIteration:
+                pass
+
+        if not stream:
+            r.content
+
+        return r
+
+    def merge_environment_settings(
+        self,
+        url: str,
+        proxies: dict[str, str] | None,
+        stream: bool | None,
+        verify: _t.VerifyType | None,
+        cert: _t.CertType,
+    ) -> dict[str, Any]:
+        """
+        Check the environment and merge it with some settings.
+
+        :rtype: dict
+        """
+        # Gather clues from the surrounding environment.
+        if self.trust_env:
+            # Set environment's proxies.
+            no_proxy = proxies.get("no_proxy") if proxies is not None else None
+            env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
+            if proxies is not None:
+                for k, v in env_proxies.items():
+                    proxies.setdefault(k, v)
+
+            # Look for requests environment configuration
+            # and be compatible with cURL.
+            if verify is True or verify is None:
+                verify = (
+                    os.environ.get("REQUESTS_CA_BUNDLE")
+                    or os.environ.get("CURL_CA_BUNDLE")
+                    or verify
+                )
+
+        # Merge all the kwargs.
+        proxies = merge_setting(proxies, self.proxies)
+        stream = merge_setting(stream, self.stream)
+        verify = merge_setting(verify, self.verify)
+        cert = merge_setting(cert, self.cert)
+
+        return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
+
+    def get_adapter(self, url: str) -> BaseAdapter:
+        """
+        Returns the appropriate connection adapter for the given URL.
+
+        :rtype: requests.adapters.BaseAdapter
+        """
+        for prefix, adapter in self.adapters.items():
+            if url.lower().startswith(prefix.lower()):
+                return adapter
+
+        # Nothing matches :-/
+        raise InvalidSchema(f"No connection adapters were found for {url!r}")
+
+    def close(self) -> None:
+        """Closes all adapters and as such the session"""
+        for v in self.adapters.values():
+            v.close()
+
+    def mount(self, prefix: str, adapter: BaseAdapter) -> None:
+        """Registers a connection adapter to a prefix.
+
+        Adapters are sorted in descending order by prefix length.
+        """
+        self.adapters[prefix] = adapter
+        keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
+
+        for key in keys_to_move:
+            self.adapters[key] = self.adapters.pop(key)
+
+    def __getstate__(self) -> dict[str, Any]:
+        state = {attr: getattr(self, attr, None) for attr in self.__attrs__}
+        return state
+
+    def __setstate__(self, state: dict[str, Any]) -> None:
+        for attr, value in state.items():
+            setattr(self, attr, value)
+
+
+def session() -> Session:
+    """
+    Returns a :class:`Session` for context-management.
+
+    .. deprecated:: 1.0.0
+
+        This method has been deprecated since version 1.0.0 and is only kept for
+        backwards compatibility. New code should use :class:`~requests.sessions.Session`
+        to create a session. This may be removed at a future date.
+
+    :rtype: Session
+    """
+    return Session()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py
new file mode 100644
index 00000000000..6c59d6baec8
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py
@@ -0,0 +1,128 @@
+r"""
+The ``codes`` object defines a mapping from common names for HTTP statuses
+to their numerical codes, accessible either as attributes or as dictionary
+items.
+
+Example::
+
+    >>> import requests
+    >>> requests.codes['temporary_redirect']
+    307
+    >>> requests.codes.teapot
+    418
+    >>> requests.codes['\o/']
+    200
+
+Some codes have multiple names, and both upper- and lower-case versions of
+the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
+``codes.okay`` all correspond to the HTTP status code 200.
+"""
+
+from .structures import LookupDict
+
+_codes = {
+    # Informational.
+    100: ("continue",),
+    101: ("switching_protocols",),
+    102: ("processing", "early-hints"),
+    103: ("checkpoint",),
+    122: ("uri_too_long", "request_uri_too_long"),
+    200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", "✓"),
+    201: ("created",),
+    202: ("accepted",),
+    203: ("non_authoritative_info", "non_authoritative_information"),
+    204: ("no_content",),
+    205: ("reset_content", "reset"),
+    206: ("partial_content", "partial"),
+    207: ("multi_status", "multiple_status", "multi_stati", "multiple_stati"),
+    208: ("already_reported",),
+    226: ("im_used",),
+    # Redirection.
+    300: ("multiple_choices",),
+    301: ("moved_permanently", "moved", "\\o-"),
+    302: ("found",),
+    303: ("see_other", "other"),
+    304: ("not_modified",),
+    305: ("use_proxy",),
+    306: ("switch_proxy",),
+    307: ("temporary_redirect", "temporary_moved", "temporary"),
+    308: (
+        "permanent_redirect",
+        "resume_incomplete",
+        "resume",
+    ),  # "resume" and "resume_incomplete" to be removed in 3.0
+    # Client Error.
+    400: ("bad_request", "bad"),
+    401: ("unauthorized",),
+    402: ("payment_required", "payment"),
+    403: ("forbidden",),
+    404: ("not_found", "-o-"),
+    405: ("method_not_allowed", "not_allowed"),
+    406: ("not_acceptable",),
+    407: ("proxy_authentication_required", "proxy_auth", "proxy_authentication"),
+    408: ("request_timeout", "timeout"),
+    409: ("conflict",),
+    410: ("gone",),
+    411: ("length_required",),
+    412: ("precondition_failed", "precondition"),
+    413: ("request_entity_too_large", "content_too_large"),
+    414: ("request_uri_too_large", "uri_too_long"),
+    415: ("unsupported_media_type", "unsupported_media", "media_type"),
+    416: (
+        "requested_range_not_satisfiable",
+        "requested_range",
+        "range_not_satisfiable",
+    ),
+    417: ("expectation_failed",),
+    418: ("im_a_teapot", "teapot", "i_am_a_teapot"),
+    421: ("misdirected_request",),
+    422: ("unprocessable_entity", "unprocessable", "unprocessable_content"),
+    423: ("locked",),
+    424: ("failed_dependency", "dependency"),
+    425: ("unordered_collection", "unordered", "too_early"),
+    426: ("upgrade_required", "upgrade"),
+    428: ("precondition_required", "precondition"),
+    429: ("too_many_requests", "too_many"),
+    431: ("header_fields_too_large", "fields_too_large"),
+    444: ("no_response", "none"),
+    449: ("retry_with", "retry"),
+    450: ("blocked_by_windows_parental_controls", "parental_controls"),
+    451: ("unavailable_for_legal_reasons", "legal_reasons"),
+    499: ("client_closed_request",),
+    # Server Error.
+    500: ("internal_server_error", "server_error", "/o\\", "✗"),
+    501: ("not_implemented",),
+    502: ("bad_gateway",),
+    503: ("service_unavailable", "unavailable"),
+    504: ("gateway_timeout",),
+    505: ("http_version_not_supported", "http_version"),
+    506: ("variant_also_negotiates",),
+    507: ("insufficient_storage",),
+    509: ("bandwidth_limit_exceeded", "bandwidth"),
+    510: ("not_extended",),
+    511: ("network_authentication_required", "network_auth", "network_authentication"),
+}
+
+codes: LookupDict[int] = LookupDict(name="status_codes")
+
+
+def _init():
+    for code, titles in _codes.items():
+        for title in titles:
+            setattr(codes, title, code)
+            if not title.startswith(("\\", "/")):
+                setattr(codes, title.upper(), code)
+
+    def doc(code: int) -> str:
+        names = ", ".join(f"``{n}``" for n in _codes[code])
+        return "* %d: %s" % (code, names)
+
+    global __doc__
+    __doc__ = (
+        __doc__ + "\n" + "\n".join(doc(code) for code in sorted(_codes))
+        if __doc__ is not None
+        else None
+    )
+
+
+_init()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py
new file mode 100644
index 00000000000..7675eaf15a1
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py
@@ -0,0 +1,130 @@
+"""
+requests.structures
+~~~~~~~~~~~~~~~~~~~
+
+Data structures that power Requests.
+"""
+
+from __future__ import annotations
+
+from collections import OrderedDict
+from collections.abc import Iterable, Iterator, Mapping
+from typing import Any, Generic, TypeVar, overload
+
+from .compat import MutableMapping
+
+_VT = TypeVar("_VT")
+_D = TypeVar("_D")
+
+
+class CaseInsensitiveDict(MutableMapping[str, _VT], Generic[_VT]):
+    """A case-insensitive ``dict``-like object.
+
+    Implements all methods and operations of
+    ``MutableMapping`` as well as dict's ``copy``. Also
+    provides ``lower_items``.
+
+    All keys are expected to be strings. The structure remembers the
+    case of the last key to be set, and ``iter(instance)``,
+    ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
+    will contain case-sensitive keys. However, querying and contains
+    testing is case insensitive::
+
+        cid = CaseInsensitiveDict()
+        cid['Accept'] = 'application/json'
+        cid['aCCEPT'] == 'application/json'  # True
+        list(cid) == ['Accept']  # True
+
+    For example, ``headers['content-encoding']`` will return the
+    value of a ``'Content-Encoding'`` response header, regardless
+    of how the header name was originally stored.
+
+    If the constructor, ``.update``, or equality comparison
+    operations are given keys that have equal ``.lower()``s, the
+    behavior is undefined.
+    """
+
+    _store: OrderedDict[str, tuple[str, _VT]]
+
+    def __init__(
+        self,
+        data: Mapping[str, _VT] | Iterable[tuple[str, _VT]] | None = None,
+        **kwargs: _VT,
+    ) -> None:
+        self._store = OrderedDict()
+        if data is None:
+            data = {}
+        self.update(data, **kwargs)
+
+    def __setitem__(self, key: str, value: _VT) -> None:
+        # Use the lowercased key for lookups, but store the actual
+        # key alongside the value.
+        self._store[key.lower()] = (key, value)
+
+    def __getitem__(self, key: str) -> _VT:
+        return self._store[key.lower()][1]
+
+    def __delitem__(self, key: str) -> None:
+        del self._store[key.lower()]
+
+    def __iter__(self) -> Iterator[str]:
+        return (casedkey for casedkey, _ in self._store.values())
+
+    def __len__(self) -> int:
+        return len(self._store)
+
+    def lower_items(self) -> Iterator[tuple[str, _VT]]:
+        """Like iteritems(), but with all lowercase keys."""
+        return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
+
+    def __eq__(self, other: object) -> bool:
+        if isinstance(other, Mapping):
+            other_dict: CaseInsensitiveDict[Any] = CaseInsensitiveDict(other)  # type: ignore[reportUnknownArgumentType]
+        else:
+            return NotImplemented
+        # Compare insensitively
+        return dict(self.lower_items()) == dict(other_dict.lower_items())
+
+    # Copy is required
+    def copy(self) -> CaseInsensitiveDict[_VT]:
+        return CaseInsensitiveDict(self._store.values())
+
+    def __repr__(self) -> str:
+        return str(dict(self.items()))
+
+
+class LookupDict(dict[str, _VT]):
+    """Dictionary lookup object."""
+
+    name: Any
+
+    def __init__(self, name: Any = None) -> None:
+        self.name = name
+        super().__init__()
+
+    def __repr__(self) -> str:
+        return f""
+
+    def __getattr__(self, key: str) -> _VT | None:
+        # We need this for type checkers to infer typing
+        # on attribute access with status_codes.py
+        if key in self.__dict__:
+            return self.__dict__[key]
+        else:
+            raise AttributeError(
+                f"'{type(self).__name__}' object has no attribute '{key}'"
+            )
+
+    def __getitem__(self, key: str) -> _VT | None:  # type: ignore[override]
+        # We allow fall-through here, so values default to None
+
+        return self.__dict__.get(key, None)
+
+    @overload
+    def get(self, key: str, default: None = None) -> _VT | None: ...
+
+    @overload
+    def get(self, key: str, default: _D | _VT) -> _D | _VT: ...
+
+    def get(self, key: str, default: _D | None = None) -> _VT | _D | None:
+        return self.__dict__.get(key, default)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py
new file mode 100644
index 00000000000..c3e50de429c
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py
@@ -0,0 +1,1155 @@
+"""
+requests.utils
+~~~~~~~~~~~~~~
+
+This module provides utility functions that are used within Requests
+that are also useful for external consumption.
+"""
+
+from __future__ import annotations
+
+import codecs
+import contextlib
+import io
+import os
+import re
+import socket
+import struct
+import sys
+import tempfile
+import warnings
+import zipfile
+from collections import OrderedDict
+from collections.abc import Generator, Iterable
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Final,
+    TypeVar,
+    cast,
+    overload,
+)
+
+from opentelemetry.agent._vendor.urllib3.util import make_headers, parse_url
+
+from . import certs
+from .__version__ import __version__
+
+# to_native_string is unused here, but imported here for backwards compatibility
+from ._internal_utils import (  # noqa: F401
+    _HEADER_VALIDATORS_BYTE,  # type: ignore[reportPrivateUsage]
+    _HEADER_VALIDATORS_STR,  # type: ignore[reportPrivateUsage]
+    HEADER_VALIDATORS,  # type: ignore[reportUnusedImport]
+    to_native_string,  # type: ignore[reportUnusedImport]
+)
+from ._types import SupportsItems as _SupportsItems
+from .compat import (
+    Mapping,
+    bytes,
+    getproxies,
+    getproxies_environment,
+    integer_types,
+    is_urllib3_1,
+    proxy_bypass,
+    proxy_bypass_environment,  # type: ignore[attr-defined]  # https://github.com/python/cpython/issues/145331
+    quote,
+    str,
+    unquote,
+    urlparse,
+    urlunparse,
+)
+from .compat import parse_http_list as _parse_list_header
+from .cookies import cookiejar_from_dict
+from .exceptions import (
+    FileModeWarning,
+    InvalidHeader,
+    InvalidURL,
+    UnrewindableBodyError,
+)
+from .structures import CaseInsensitiveDict
+
+if TYPE_CHECKING:
+    from http.cookiejar import CookieJar
+    from io import BufferedWriter
+
+    from . import _types as _t
+    from .models import PreparedRequest, Request, Response
+
+NETRC_FILES: Final = (".netrc", "_netrc")
+
+
+# Certificate is extracted by certifi when needed.
+DEFAULT_CA_BUNDLE_PATH: str = certs.where()
+
+
+DEFAULT_PORTS: Final = {"http": 80, "https": 443}
+
+_KT = TypeVar("_KT")
+_VT = TypeVar("_VT")
+
+# Ensure that ', ' is used to preserve previous delimiter behavior.
+DEFAULT_ACCEPT_ENCODING: Final = ", ".join(
+    re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"])
+)
+
+
+if sys.platform == "win32":
+    # provide a proxy_bypass version on Windows without DNS lookups
+
+    def proxy_bypass_registry(host: str) -> bool:
+        try:
+            import winreg
+        except ImportError:
+            return False
+
+        try:
+            internetSettings = winreg.OpenKey(
+                winreg.HKEY_CURRENT_USER,
+                r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",
+            )
+            # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it
+            proxyEnable = int(winreg.QueryValueEx(internetSettings, "ProxyEnable")[0])
+            # ProxyOverride is almost always a string
+            proxyOverride = winreg.QueryValueEx(internetSettings, "ProxyOverride")[0]
+        except (OSError, ValueError):
+            return False
+        if not proxyEnable or not proxyOverride:
+            return False
+
+        # make a check value list from the registry entry: replace the
+        # '' string by the localhost entry and the corresponding
+        # canonical entry.
+        proxyOverride = proxyOverride.split(";")
+        # filter out empty strings to avoid re.match return true in the following code.
+        proxyOverride = filter(None, proxyOverride)
+        # now check if we match one of the registry values.
+        for test in proxyOverride:
+            if test == "":
+                if "." not in host:
+                    return True
+            test = test.replace(".", r"\.")  # mask dots
+            test = test.replace("*", r".*")  # change glob sequence
+            test = test.replace("?", r".")  # change glob char
+            if re.match(test, host, re.I):
+                return True
+        return False
+
+    def proxy_bypass(host: str) -> bool:  # noqa
+        """Return True, if the host should be bypassed.
+
+        Checks proxy settings gathered from the environment, if specified,
+        or the registry.
+        """
+        if getproxies_environment():
+            return proxy_bypass_environment(host)
+        else:
+            return proxy_bypass_registry(host)
+
+
+def dict_to_sequence(
+    d: _t.SupportsItems[Any, Any] | Iterable[tuple[Any, Any]],
+) -> Iterable[tuple[Any, Any]]:
+    """Returns an internal sequence dictionary update."""
+
+    if isinstance(d, _SupportsItems):
+        return d.items()
+
+    return d
+
+
+def super_len(o: Any) -> int:
+    total_length = None
+    current_position = 0
+
+    if not is_urllib3_1 and isinstance(o, str):
+        # urllib3 2.x+ treats all strings as utf-8 instead
+        # of latin-1 (iso-8859-1) like http.client.
+        o = o.encode("utf-8")
+
+    if hasattr(o, "__len__"):
+        total_length = len(o)
+
+    elif hasattr(o, "len"):
+        total_length = o.len
+
+    elif hasattr(o, "fileno"):
+        try:
+            fileno = o.fileno()
+        except (io.UnsupportedOperation, AttributeError):
+            # AttributeError is a surprising exception, seeing as how we've just checked
+            # that `hasattr(o, 'fileno')`.  It happens for objects obtained via
+            # `Tarfile.extractfile()`, per issue 5229.
+            pass
+        else:
+            total_length = os.fstat(fileno).st_size
+
+            # Having used fstat to determine the file length, we need to
+            # confirm that this file was opened up in binary mode.
+            if "b" not in o.mode:
+                warnings.warn(
+                    (
+                        "Requests has determined the content-length for this "
+                        "request using the binary size of the file: however, the "
+                        "file has been opened in text mode (i.e. without the 'b' "
+                        "flag in the mode). This may lead to an incorrect "
+                        "content-length. In Requests 3.0, support will be removed "
+                        "for files in text mode."
+                    ),
+                    FileModeWarning,
+                )
+
+    if hasattr(o, "tell"):
+        try:
+            current_position = o.tell()
+        except OSError:
+            # This can happen in some weird situations, such as when the file
+            # is actually a special file descriptor like stdin. In this
+            # instance, we don't know what the length is, so set it to zero and
+            # let requests chunk it instead.
+            if total_length is not None:
+                current_position = total_length
+        else:
+            if hasattr(o, "seek") and total_length is None:
+                # StringIO and BytesIO have seek but no usable fileno
+                try:
+                    # seek to end of file
+                    o.seek(0, 2)
+                    total_length = o.tell()
+
+                    # seek back to current position to support
+                    # partially read file-like objects
+                    o.seek(current_position or 0)
+                except OSError:
+                    total_length = 0
+
+    if total_length is None:
+        total_length = 0
+
+    return max(0, total_length - current_position)
+
+
+def get_netrc_auth(
+    url: _t.UriType, raise_errors: bool = False
+) -> tuple[str, str] | None:
+    """Returns the Requests tuple auth for a given url from netrc."""
+
+    if isinstance(url, bytes):
+        url = url.decode("utf-8")
+
+    netrc_file = os.environ.get("NETRC")
+    if netrc_file is not None:
+        netrc_locations = (netrc_file,)
+    else:
+        netrc_locations = (f"~/{f}" for f in NETRC_FILES)
+
+    try:
+        from netrc import NetrcParseError, netrc
+
+        netrc_path = None
+
+        for f in netrc_locations:
+            loc = os.path.expanduser(f)
+            if os.path.exists(loc):
+                netrc_path = loc
+                break
+
+        # Abort early if there isn't one.
+        if netrc_path is None:
+            return
+
+        ri = urlparse(url)
+        host = ri.hostname
+
+        if host is None:
+            return
+
+        try:
+            _netrc = netrc(netrc_path).authenticators(host)
+            if _netrc and any(_netrc):
+                # Return with login / password
+                login_i = 0 if _netrc[0] else 1
+                return (_netrc[login_i] or "", _netrc[2] or "")
+        except (NetrcParseError, OSError):
+            # If there was a parsing error or a permissions issue reading the file,
+            # we'll just skip netrc auth unless explicitly asked to raise errors.
+            if raise_errors:
+                raise
+
+    # App Engine hackiness.
+    except (ImportError, AttributeError):
+        pass
+
+
+def guess_filename(obj: Any) -> str | None:
+    """Tries to guess the filename of the given object."""
+    name = getattr(obj, "name", None)
+    if name and isinstance(name, (str, bytes)) and name[0] != "<" and name[-1] != ">":
+        return os.path.basename(name)  # type: ignore[return-value]  # urllib3 accepts bytes but types str only
+
+
+def extract_zipped_paths(path: str) -> str:
+    """Replace nonexistent paths that look like they refer to a member of a zip
+    archive with the location of an extracted copy of the target, or else
+    just return the provided path unchanged.
+    """
+    if os.path.exists(path):
+        # this is already a valid path, no need to do anything further
+        return path
+
+    # find the first valid part of the provided path and treat that as a zip archive
+    # assume the rest of the path is the name of a member in the archive
+    archive, member = os.path.split(path)
+    while archive and not os.path.exists(archive):
+        archive, prefix = os.path.split(archive)
+        if not prefix:
+            # If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split),
+            # we _can_ end up in an infinite loop on a rare corner case affecting a small number of users
+            break
+        member = "/".join([prefix, member])
+
+    if not zipfile.is_zipfile(archive):
+        return path
+
+    zip_file = zipfile.ZipFile(archive)
+    if member not in zip_file.namelist():
+        return path
+
+    # we have a valid zip archive and a valid member of that archive
+    suffix = os.path.splitext(member.split("/")[-1])[-1]
+    fd, extracted_path = tempfile.mkstemp(suffix=suffix)
+    try:
+        os.write(fd, zip_file.read(member))
+    finally:
+        os.close(fd)
+
+    return extracted_path
+
+
+@contextlib.contextmanager
+def atomic_open(filename: str) -> Generator[BufferedWriter, None, None]:
+    """Write a file to the disk in an atomic fashion"""
+    tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
+    try:
+        with os.fdopen(tmp_descriptor, "wb") as tmp_handler:
+            yield tmp_handler
+        os.replace(tmp_name, filename)
+    except BaseException:
+        os.remove(tmp_name)
+        raise
+
+
+def from_key_val_list(
+    value: Mapping[Any, Any] | Iterable[tuple[Any, Any]] | None,
+) -> dict[Any, Any] | None:
+    """Take an object and test to see if it can be represented as a
+    dictionary. Unless it can not be represented as such, return an
+    OrderedDict, e.g.,
+
+    ::
+
+        >>> from_key_val_list([('key', 'val')])
+        OrderedDict([('key', 'val')])
+        >>> from_key_val_list('string')
+        Traceback (most recent call last):
+        ...
+        ValueError: cannot encode objects that are not 2-tuples
+        >>> from_key_val_list({'key': 'val'})
+        OrderedDict([('key', 'val')])
+
+    :rtype: OrderedDict
+    """
+    if value is None:
+        return None
+
+    if isinstance(value, (str, bytes, bool, int)):
+        raise ValueError("cannot encode objects that are not 2-tuples")
+
+    return OrderedDict(value)
+
+
+@overload
+def to_key_val_list(value: None) -> None: ...
+@overload
+def to_key_val_list(
+    value: _t.SupportsItems[_KT, _VT] | Iterable[tuple[_KT, _VT]],
+) -> list[tuple[_KT, _VT]]: ...
+def to_key_val_list(
+    value: _t.SupportsItems[_KT, _VT] | Iterable[tuple[_KT, _VT]] | None,
+) -> list[tuple[_KT, _VT]] | None:
+    """Take an object and test to see if it can be represented as a
+    dictionary. If it can be, return a list of tuples, e.g.,
+
+    ::
+
+        >>> to_key_val_list([('key', 'val')])
+        [('key', 'val')]
+        >>> to_key_val_list({'key': 'val'})
+        [('key', 'val')]
+        >>> to_key_val_list('string')
+        Traceback (most recent call last):
+        ...
+        ValueError: cannot encode objects that are not 2-tuples
+
+    :rtype: list
+    """
+    if value is None:
+        return None
+
+    if isinstance(value, (str, bytes, bool, int)):
+        raise ValueError("cannot encode objects that are not 2-tuples")
+
+    if isinstance(value, _SupportsItems):
+        return list(value.items())
+
+    return list(value)
+
+
+# From mitsuhiko/werkzeug (used with permission).
+def parse_list_header(value: str) -> list[str]:
+    """Parse lists as described by RFC 2068 Section 2.
+
+    In particular, parse comma-separated lists where the elements of
+    the list may include quoted-strings.  A quoted-string could
+    contain a comma.  A non-quoted string could have quotes in the
+    middle.  Quotes are removed automatically after parsing.
+
+    It basically works like :func:`parse_set_header` just that items
+    may appear multiple times and case sensitivity is preserved.
+
+    The return value is a standard :class:`list`:
+
+    >>> parse_list_header('token, "quoted value"')
+    ['token', 'quoted value']
+
+    To create a header from the :class:`list` again, use the
+    :func:`dump_header` function.
+
+    :param value: a string with a list header.
+    :return: :class:`list`
+    :rtype: list
+    """
+    result: list[str] = []
+    for item in _parse_list_header(value):
+        if item[:1] == item[-1:] == '"':
+            item = unquote_header_value(item[1:-1])
+        result.append(item)
+    return result
+
+
+# From mitsuhiko/werkzeug (used with permission).
+def parse_dict_header(value: str) -> dict[str, str | None]:
+    """Parse lists of key, value pairs as described by RFC 2068 Section 2 and
+    convert them into a python dict:
+
+    >>> d = parse_dict_header('foo="is a fish", bar="as well"')
+    >>> type(d) is dict
+    True
+    >>> sorted(d.items())
+    [('bar', 'as well'), ('foo', 'is a fish')]
+
+    If there is no value for a key it will be `None`:
+
+    >>> parse_dict_header('key_without_value')
+    {'key_without_value': None}
+
+    To create a header from the :class:`dict` again, use the
+    :func:`dump_header` function.
+
+    :param value: a string with a dict header.
+    :return: :class:`dict`
+    :rtype: dict
+    """
+    result: dict[str, str | None] = {}
+    for item in _parse_list_header(value):
+        if "=" not in item:
+            result[item] = None
+            continue
+        name, value = item.split("=", 1)
+        if value[:1] == value[-1:] == '"':
+            value = unquote_header_value(value[1:-1])
+        result[name] = value
+    return result
+
+
+# From mitsuhiko/werkzeug (used with permission).
+def unquote_header_value(value: str, is_filename: bool = False) -> str:
+    r"""Unquotes a header value.  (Reversal of :func:`quote_header_value`).
+    This does not use the real unquoting but what browsers are actually
+    using for quoting.
+
+    :param value: the header value to unquote.
+    :rtype: str
+    """
+    if value and value[0] == value[-1] == '"':
+        # this is not the real unquoting, but fixing this so that the
+        # RFC is met will result in bugs with internet explorer and
+        # probably some other browsers as well.  IE for example is
+        # uploading files with "C:\foo\bar.txt" as filename
+        value = value[1:-1]
+
+        # if this is a filename and the starting characters look like
+        # a UNC path, then just return the value without quotes.  Using the
+        # replace sequence below on a UNC path has the effect of turning
+        # the leading double slash into a single slash and then
+        # _fix_ie_filename() doesn't work correctly.  See #458.
+        if not is_filename or value[:2] != "\\\\":
+            return value.replace("\\\\", "\\").replace('\\"', '"')
+    return value
+
+
+def dict_from_cookiejar(cj: CookieJar) -> dict[str, str | None]:
+    """Returns a key/value dictionary from a CookieJar.
+
+    :param cj: CookieJar object to extract cookies from.
+    :rtype: dict
+    """
+
+    cookie_dict = {cookie.name: cookie.value for cookie in cj}
+    return cookie_dict
+
+
+def add_dict_to_cookiejar(cj: CookieJar, cookie_dict: dict[str, str]) -> CookieJar:
+    """Returns a CookieJar from a key/value dictionary.
+
+    :param cj: CookieJar to insert cookies into.
+    :param cookie_dict: Dict of key/values to insert into CookieJar.
+    :rtype: CookieJar
+    """
+
+    return cookiejar_from_dict(cookie_dict, cj)
+
+
+def get_encodings_from_content(content: str) -> list[str]:
+    """Returns encodings from given content string.
+
+    :param content: bytestring to extract encodings from.
+    """
+    warnings.warn(
+        (
+            "In requests 3.0, get_encodings_from_content will be removed. For "
+            "more information, please see the discussion on issue #2266. (This"
+            " warning should only appear once.)"
+        ),
+        DeprecationWarning,
+    )
+
+    charset_re = re.compile(r']', flags=re.I)
+    pragma_re = re.compile(r']', flags=re.I)
+    xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]')
+
+    return (
+        charset_re.findall(content)
+        + pragma_re.findall(content)
+        + xml_re.findall(content)
+    )
+
+
+def _parse_content_type_header(header: str) -> tuple[str, dict[str, Any]]:
+    """Returns content type and parameters from given header.
+
+    :param header: string
+    :return: tuple containing content type and dictionary of
+         parameters.
+    """
+
+    tokens = header.split(";")
+    content_type, params = tokens[0].strip(), tokens[1:]
+    params_dict: dict[str, str | bool] = {}
+    strip_chars = "\"' "
+
+    for param in params:
+        param = param.strip()
+        if param and (idx := param.find("=")) != -1:
+            key = param[:idx].strip(strip_chars)
+            value = param[idx + 1 :].strip(strip_chars)
+            params_dict[key.lower()] = value
+    return content_type, params_dict
+
+
+def get_encoding_from_headers(headers: CaseInsensitiveDict[str]) -> str | None:
+    """Returns encodings from given HTTP Header Dict.
+
+    :param headers: dictionary to extract encoding from.
+    :rtype: str
+    """
+
+    content_type = headers.get("content-type")
+
+    if not content_type:
+        return None
+
+    content_type, params = _parse_content_type_header(content_type)
+
+    if "charset" in params:
+        return params["charset"].strip("'\"")
+
+    if "text" in content_type:
+        return "ISO-8859-1"
+
+    if "application/json" in content_type:
+        # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset
+        return "utf-8"
+
+
+def stream_decode_response_unicode(
+    iterator: Iterable[bytes], r: Response
+) -> Generator[str | bytes, None, None]:
+    """Stream decodes an iterator."""
+
+    if r.encoding is None:
+        yield from iterator
+        return
+
+    decoder = codecs.getincrementaldecoder(r.encoding)(errors="replace")
+    for chunk in iterator:
+        rv = decoder.decode(chunk)
+        if rv:
+            yield rv
+    rv = decoder.decode(b"", final=True)
+    if rv:
+        yield rv
+
+
+@overload
+def iter_slices(
+    string: bytes, slice_length: int | None
+) -> Generator[bytes, None, None]: ...
+@overload
+def iter_slices(
+    string: str, slice_length: int | None
+) -> Generator[str, None, None]: ...
+def iter_slices(
+    string: bytes | str, slice_length: int | None
+) -> Generator[bytes | str, None, None]:
+    """Iterate over slices of a string."""
+    pos = 0
+    if slice_length is None or slice_length <= 0:
+        slice_length = len(string)
+    while pos < len(string):
+        yield string[pos : pos + slice_length]
+        pos += slice_length
+
+
+def get_unicode_from_response(r: Response) -> str | bytes | None:
+    """Returns the requested content back in unicode.
+
+    :param r: Response object to get unicode content from.
+
+    Tried:
+
+    1. charset from content-type
+    2. fall back and replace all unicode characters
+
+    :rtype: str
+    """
+    warnings.warn(
+        (
+            "In requests 3.0, get_unicode_from_response will be removed. For "
+            "more information, please see the discussion on issue #2266. (This"
+            " warning should only appear once.)"
+        ),
+        DeprecationWarning,
+    )
+    if r.content is None:  # type: ignore[reportUnnecessaryComparison]
+        return None
+
+    tried_encodings: list[str] = []
+
+    # Try charset from content-type
+    encoding = get_encoding_from_headers(r.headers)
+
+    if encoding:
+        try:
+            return str(r.content, encoding)
+        except UnicodeError:
+            tried_encodings.append(encoding)
+
+    # Fall back:
+    try:
+        return str(r.content, encoding or "utf-8", errors="replace")
+    except TypeError:
+        return r.content
+
+
+# The unreserved URI characters (RFC 3986)
+UNRESERVED_SET: Final = frozenset(
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~"
+)
+
+
+def unquote_unreserved(uri: str) -> str:
+    """Un-escape any percent-escape sequences in a URI that are unreserved
+    characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
+
+    :rtype: str
+    """
+    parts = uri.split("%")
+    for i in range(1, len(parts)):
+        h = parts[i][0:2]
+        if len(h) == 2 and h.isalnum():
+            try:
+                c = chr(int(h, 16))
+            except ValueError:
+                raise InvalidURL(f"Invalid percent-escape sequence: '{h}'")
+
+            if c in UNRESERVED_SET:
+                parts[i] = c + parts[i][2:]
+            else:
+                parts[i] = f"%{parts[i]}"
+        else:
+            parts[i] = f"%{parts[i]}"
+    return "".join(parts)
+
+
+def requote_uri(uri: str) -> str:
+    """Re-quote the given URI.
+
+    This function passes the given URI through an unquote/quote cycle to
+    ensure that it is fully and consistently quoted.
+
+    :rtype: str
+    """
+    safe_with_percent = "!#$%&'()*+,/:;=?@[]~"
+    safe_without_percent = "!#$&'()*+,/:;=?@[]~"
+    try:
+        # Unquote only the unreserved characters
+        # Then quote only illegal characters (do not quote reserved,
+        # unreserved, or '%')
+        return quote(unquote_unreserved(uri), safe=safe_with_percent)
+    except InvalidURL:
+        # We couldn't unquote the given URI, so let's try quoting it, but
+        # there may be unquoted '%'s in the URI. We need to make sure they're
+        # properly quoted so they do not cause issues elsewhere.
+        return quote(uri, safe=safe_without_percent)
+
+
+def address_in_network(ip: str, net: str) -> bool:
+    """This function allows you to check if an IP belongs to a network subnet
+
+    Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
+             returns False if ip = 192.168.1.1 and net = 192.168.100.0/24
+
+    :rtype: bool
+    """
+    ipaddr = struct.unpack("=L", socket.inet_aton(ip))[0]
+    netaddr, bits = net.split("/")
+    netmask = struct.unpack("=L", socket.inet_aton(dotted_netmask(int(bits))))[0]
+    network = struct.unpack("=L", socket.inet_aton(netaddr))[0] & netmask
+    return (ipaddr & netmask) == (network & netmask)
+
+
+def dotted_netmask(mask: int) -> str:
+    """Converts mask from /xx format to xxx.xxx.xxx.xxx
+
+    Example: if mask is 24 function returns 255.255.255.0
+
+    :rtype: str
+    """
+    bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1
+    return socket.inet_ntoa(struct.pack(">I", bits))
+
+
+def is_ipv4_address(string_ip: str) -> bool:
+    """
+    :rtype: bool
+    """
+    try:
+        socket.inet_aton(string_ip)
+    except OSError:
+        return False
+    return True
+
+
+def is_valid_cidr(string_network: str) -> bool:
+    """
+    Very simple check of the cidr format in no_proxy variable.
+
+    :rtype: bool
+    """
+    if string_network.count("/") == 1:
+        try:
+            mask = int(string_network.split("/")[1])
+        except ValueError:
+            return False
+
+        if mask < 1 or mask > 32:
+            return False
+
+        try:
+            socket.inet_aton(string_network.split("/")[0])
+        except OSError:
+            return False
+    else:
+        return False
+    return True
+
+
+@contextlib.contextmanager
+def set_environ(env_name: str, value: str | None) -> Generator[None, None, None]:
+    """Set the environment variable 'env_name' to 'value'
+
+    Save previous value, yield, and then restore the previous value stored in
+    the environment variable 'env_name'.
+
+    If 'value' is None, do nothing"""
+    value_changed = value is not None
+    old_value: str | None = None
+    if value_changed:
+        old_value = os.environ.get(env_name)
+        os.environ[env_name] = value
+    try:
+        yield
+    finally:
+        if value_changed:
+            if old_value is None:
+                del os.environ[env_name]
+            else:
+                os.environ[env_name] = old_value
+
+
+def should_bypass_proxies(url: str, no_proxy: str | None) -> bool:
+    """
+    Returns whether we should bypass proxies or not.
+
+    :rtype: bool
+    """
+
+    # Prioritize lowercase environment variables over uppercase
+    # to keep a consistent behaviour with other http projects (curl, wget).
+    def get_proxy(key: str) -> str | None:
+        return os.environ.get(key) or os.environ.get(key.upper())
+
+    # First check whether no_proxy is defined. If it is, check that the URL
+    # we're getting isn't in the no_proxy list.
+    no_proxy_arg = no_proxy
+    if no_proxy is None:
+        no_proxy = get_proxy("no_proxy")
+    parsed = urlparse(url)
+    hostname = parsed.hostname
+
+    if hostname is None:
+        # URLs don't always have hostnames, e.g. file:/// urls.
+        return True
+
+    if no_proxy:
+        # We need to check whether we match here. We need to see if we match
+        # the end of the hostname, both with and without the port.
+        no_proxy_hosts = (host for host in no_proxy.replace(" ", "").split(",") if host)
+
+        if is_ipv4_address(hostname):
+            for proxy_ip in no_proxy_hosts:
+                if is_valid_cidr(proxy_ip):
+                    if address_in_network(hostname, proxy_ip):
+                        return True
+                elif hostname == proxy_ip:
+                    # If no_proxy ip was defined in plain IP notation instead of cidr notation &
+                    # matches the IP of the index
+                    return True
+        else:
+            host_with_port = hostname
+            if parsed.port:
+                host_with_port += f":{parsed.port}"
+
+            for host in no_proxy_hosts:
+                host = host.lstrip(".")
+                if hostname == host or host_with_port == host:
+                    return True
+                host = "." + host
+                if hostname.endswith(host) or host_with_port.endswith(host):
+                    return True
+
+    with set_environ("no_proxy", no_proxy_arg):
+        try:
+            bypass = proxy_bypass(hostname)
+        except (TypeError, socket.gaierror):
+            bypass = False
+
+    if bypass:
+        return True
+
+    return False
+
+
+def get_environ_proxies(url: str, no_proxy: str | None = None) -> dict[str, str]:
+    """
+    Return a dict of environment proxies.
+
+    :rtype: dict
+    """
+    if should_bypass_proxies(url, no_proxy=no_proxy):
+        return {}
+    else:
+        return getproxies()
+
+
+def select_proxy(url: str, proxies: dict[str, str] | None) -> str | None:
+    """Select a proxy for the url, if applicable.
+
+    :param url: The url being for the request
+    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
+    """
+    proxies = proxies or {}
+    urlparts = urlparse(url)
+    if urlparts.hostname is None:
+        return proxies.get(urlparts.scheme, proxies.get("all"))
+
+    proxy_keys = [
+        urlparts.scheme + "://" + urlparts.hostname,
+        urlparts.scheme,
+        "all://" + urlparts.hostname,
+        "all",
+    ]
+    proxy = None
+    for proxy_key in proxy_keys:
+        if proxy_key in proxies:
+            proxy = proxies[proxy_key]
+            break
+
+    return proxy
+
+
+def resolve_proxies(
+    request: Request | PreparedRequest,
+    proxies: dict[str, str] | None,
+    trust_env: bool = True,
+) -> dict[str, str]:
+    """This method takes proxy information from a request and configuration
+    input to resolve a mapping of target proxies. This will consider settings
+    such as NO_PROXY to strip proxy configurations.
+
+    :param request: Request or PreparedRequest
+    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
+    :param trust_env: Boolean declaring whether to trust environment configs
+
+    :rtype: dict
+    """
+    proxies = proxies if proxies is not None else {}
+    url = cast(str, request.url)
+    scheme = urlparse(url).scheme
+    no_proxy = proxies.get("no_proxy")
+    new_proxies = proxies.copy()
+
+    if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
+        environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
+
+        proxy = environ_proxies.get(scheme, environ_proxies.get("all"))
+
+        if proxy:
+            new_proxies.setdefault(scheme, proxy)
+    return new_proxies
+
+
+def default_user_agent(name: str = "python-requests") -> str:
+    """
+    Return a string representing the default user agent.
+
+    :rtype: str
+    """
+    return f"{name}/{__version__}"
+
+
+def default_headers() -> CaseInsensitiveDict[str]:
+    """
+    :rtype: requests.structures.CaseInsensitiveDict
+    """
+    return CaseInsensitiveDict(
+        {
+            "User-Agent": default_user_agent(),
+            "Accept-Encoding": DEFAULT_ACCEPT_ENCODING,
+            "Accept": "*/*",
+            "Connection": "keep-alive",
+        }
+    )
+
+
+def parse_header_links(value: str) -> list[dict[str, str]]:
+    """Return a list of parsed link headers proxies.
+
+    i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg"
+
+    :rtype: list
+    """
+
+    links: list[dict[str, str]] = []
+
+    replace_chars = " '\""
+
+    value = value.strip(replace_chars)
+    if not value:
+        return links
+
+    for val in re.split(", *<", value):
+        try:
+            url, params = val.split(";", 1)
+        except ValueError:
+            url, params = val, ""
+
+        link: dict[str, str] = {"url": url.strip("<> '\"")}
+
+        for param in params.split(";"):
+            try:
+                key, value = param.split("=")
+            except ValueError:
+                break
+
+            link[key.strip(replace_chars)] = value.strip(replace_chars)
+
+        links.append(link)
+
+    return links
+
+
+# Null bytes; no need to recreate these on each call to guess_json_utf
+_null = "\x00".encode("ascii")  # encoding to ASCII for Python 3
+_null2 = _null * 2
+_null3 = _null * 3
+
+
+def guess_json_utf(data: bytes) -> str | None:
+    """
+    :rtype: str
+    """
+    # JSON always starts with two ASCII characters, so detection is as
+    # easy as counting the nulls and from their location and count
+    # determine the encoding. Also detect a BOM, if present.
+    sample = data[:4]
+    if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):
+        return "utf-32"  # BOM included
+    if sample[:3] == codecs.BOM_UTF8:
+        return "utf-8-sig"  # BOM included, MS style (discouraged)
+    if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):
+        return "utf-16"  # BOM included
+    nullcount = sample.count(_null)
+    if nullcount == 0:
+        return "utf-8"
+    if nullcount == 2:
+        if sample[::2] == _null2:  # 1st and 3rd are null
+            return "utf-16-be"
+        if sample[1::2] == _null2:  # 2nd and 4th are null
+            return "utf-16-le"
+        # Did not detect 2 valid UTF-16 ascii-range characters
+    if nullcount == 3:
+        if sample[:3] == _null3:
+            return "utf-32-be"
+        if sample[1:] == _null3:
+            return "utf-32-le"
+        # Did not detect a valid UTF-32 ascii-range character
+    return None
+
+
+def prepend_scheme_if_needed(url: str, new_scheme: str) -> str:
+    """Given a URL that may or may not have a scheme, prepend the given scheme.
+    Does not replace a present scheme with the one provided as an argument.
+
+    :rtype: str
+    """
+    parsed = parse_url(url)
+    scheme, auth, _host, _port, path, query, fragment = parsed
+
+    # A defect in urlparse determines that there isn't a netloc present in some
+    # urls. We previously assumed parsing was overly cautious, and swapped the
+    # netloc and path. Due to a lack of tests on the original defect, this is
+    # maintained with parse_url for backwards compatibility.
+    netloc = parsed.netloc
+    if not netloc:
+        netloc, path = path, netloc
+
+    if auth:
+        # parse_url doesn't provide the netloc with auth
+        # so we'll add it ourselves.
+        netloc = cast(str, netloc)
+        netloc = "@".join([auth, netloc])
+    if scheme is None:
+        scheme = new_scheme
+    if path is None:
+        path = ""
+
+    return urlunparse((scheme, netloc, path, "", query, fragment))
+
+
+def get_auth_from_url(url: str) -> tuple[str, str]:
+    """Given a url with authentication components, extract them into a tuple of
+    username,password.
+
+    :rtype: (str,str)
+    """
+    parsed = urlparse(url)
+
+    try:
+        # except handles parsed.username/password being None
+        auth = (unquote(parsed.username), unquote(parsed.password))  # type: ignore[arg-type]
+    except (AttributeError, TypeError):
+        auth = ("", "")
+
+    return auth
+
+
+def check_header_validity(header: tuple[str | bytes, str | bytes]) -> None:
+    """Verifies that header parts don't contain leading whitespace
+    reserved characters, or return characters.
+
+    :param header: tuple, in the format (name, value).
+    """
+    name, value = header
+    _validate_header_part(header, name, 0)
+    _validate_header_part(header, value, 1)
+
+
+def _validate_header_part(
+    header: tuple[str | bytes, str | bytes],
+    header_part: str | bytes,
+    header_validator_index: int,
+) -> None:
+    if isinstance(header_part, str):
+        validator = _HEADER_VALIDATORS_STR[header_validator_index]
+    elif isinstance(header_part, bytes):  # type: ignore[reportUnnecessaryIsInstance]
+        # runtime guard for non-str/bytes input
+        validator = _HEADER_VALIDATORS_BYTE[header_validator_index]
+    else:
+        raise InvalidHeader(
+            f"Header part ({header_part!r}) from {header} "
+            f"must be of type str or bytes, not {type(header_part)}"
+        )
+
+    if not validator.match(header_part):  # type: ignore[arg-type]
+        header_kind = "name" if header_validator_index == 0 else "value"
+        raise InvalidHeader(
+            f"Invalid leading whitespace, reserved character(s), or return "
+            f"character(s) in header {header_kind}: {header_part!r}"
+        )
+
+
+def urldefragauth(url: str) -> str:
+    """
+    Given a url remove the fragment and the authentication part.
+
+    :rtype: str
+    """
+    scheme, netloc, path, params, query, _fragment = urlparse(url)
+
+    # see func:`prepend_scheme_if_needed`
+    if not netloc:
+        netloc, path = path, netloc
+
+    netloc = netloc.rsplit("@", 1)[-1]
+
+    return urlunparse((scheme, netloc, path, params, query, ""))
+
+
+def rewind_body(prepared_request: PreparedRequest) -> None:
+    """Move file pointer back to its recorded starting position
+    so it can be read again on redirect.
+    """
+    body_seek = getattr(prepared_request.body, "seek", None)
+    if body_seek is not None and isinstance(
+        prepared_request._body_position,  # type: ignore[reportPrivateUsage]
+        integer_types,
+    ):
+        try:
+            body_seek(prepared_request._body_position)  # type: ignore[reportPrivateUsage]
+        except OSError:
+            raise UnrewindableBodyError(
+                "An error occurred when rewinding request body for redirect."
+            )
+    else:
+        raise UnrewindableBodyError("Unable to rewind request body for redirect.")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt
index 3c12e957441..1ee43e94b17 100644
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requirements.txt
@@ -1,5 +1,5 @@
 # This file was autogenerated by uv via the following command:
-#    uv pip compile --python 3.10 --universal --generate-hashes vendor.in -o src/opentelemetry/agent/_vendor/requirements.txt
+#    uv pip compile --python 3.10 --universal --generate-hashes --excludes vendor-excludes.txt vendor.in -o src/opentelemetry/agent/_vendor/requirements.txt
 certifi==2026.10.23 \
     --hash=sha256:a9895e6e2758b371e0545e321a3a8fd1fcfd9829ada8824a936dfb16aaaf36cd \
     --hash=sha256:e9b54de76e530bb6cf0ccd036787103acb58fd42ba930ea8bf948ddbaa2f61d1
@@ -178,10 +178,147 @@ charset-normalizer==3.5.2 \
     --hash=sha256:fd1fbe0f116b6e55da77aca2c6ddcddcfac2186cbf78bdebf40fc156efca389d \
     --hash=sha256:fe9753dfee015c570d73df76f899f18444d41388bffcde097deba51c4fadbb9f
     # via requests
+fastjsonschema==2.22.3 \
+    --hash=sha256:8330c91b027dcf941efcb7b1f0998515ff95d177ea15bbabdfe8671965620901 \
+    --hash=sha256:f670b443830b75aca3f00b75949efa20f4b2a80302ec7a21505c28dd54cffd43
+    # via -r vendor.in
+googleapis-common-protos==1.76.0 \
+    --hash=sha256:59e13344a9f3651aa201a03e2bee815a3bf43a4baf1f9ff8a9b62a840ce25fac \
+    --hash=sha256:71db0e44a1d4c2dd024ebad44ca67129cc1e2892e4861df466764749d5ef8642
+    # via opentelemetry-exporter-otlp-proto-http
 idna==3.20 \
     --hash=sha256:a7db850025b95ded1eae8a46181a1a6c56c92c96f0e2b005d9ff8dc0210cab44 \
     --hash=sha256:ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c
     # via requests
+opentelemetry-api==1.45.2 \
+    --hash=sha256:2cbd737377e710ee740d261c94e93fa0f08e6d037c18f17513cc0a2d94479a34 \
+    --hash=sha256:d7b0008e21e5fd61cbe7a7f34ca3b6905a78ab677d9bc395e299359c75cda6b4
+    # via
+    #   -r vendor.in
+    #   opentelemetry-configuration
+    #   opentelemetry-distro
+    #   opentelemetry-exporter-http-transport
+    #   opentelemetry-exporter-otlp-proto-http
+    #   opentelemetry-exporter-prometheus
+    #   opentelemetry-instrumentation
+    #   opentelemetry-instrumentation-aiohttp-client
+    #   opentelemetry-propagator-b3
+    #   opentelemetry-sdk
+    #   opentelemetry-semantic-conventions
+opentelemetry-configuration==0.66b2 \
+    --hash=sha256:2427a005b9cf0d2dc77cf26cbeef11ae549fecb3089818b702e6e71f27a9091b \
+    --hash=sha256:de7f1b5682cab12d35f22330f025ed5a54d2a8151515eede5b0a3ed9629dcc61
+    # via -r vendor.in
+opentelemetry-distro==0.66b2 \
+    --hash=sha256:a488231479bbc17f5c34d4ef740e9285fa8f8cd1114f73078cac9d8520eacfbd \
+    --hash=sha256:b12af671779fbd31abdfe8b8dd49a31f6c0ae5d4cfe503e7d5e8d84ba0658fed
+    # via -r vendor.in
+opentelemetry-exporter-http-transport==0.66b2 \
+    --hash=sha256:66d6ed810a515432c8891da9a834464332fd70badeca45bdeeae81b4280c903b \
+    --hash=sha256:fd5f5b490c099acda1cd7b909d5e8981436bf18cc8c6098d302d114c271720e9
+    # via
+    #   -r vendor.in
+    #   opentelemetry-exporter-otlp-json-http
+    #   opentelemetry-exporter-otlp-proto-http
+opentelemetry-exporter-otlp-common==0.66b2 \
+    --hash=sha256:06f5a9b88638e310efa1f1d206cdf6b75393e112aba4e174a963416192bd1028 \
+    --hash=sha256:ace86efb75489f925f1ef809856ae5f0c7db534e4afdc624530222228b1236a5
+    # via
+    #   -r vendor.in
+    #   opentelemetry-exporter-otlp-json-file
+    #   opentelemetry-exporter-otlp-json-http
+    #   opentelemetry-exporter-otlp-proto-http
+opentelemetry-exporter-otlp-json-common==0.66b2 \
+    --hash=sha256:6e83ba9312edb60fc1d4929b73457e8cca7579db4b4492b32cb71a1a8ddecdc7 \
+    --hash=sha256:fa3e4e7d19d5bc63e0a6855b839651a0a20070f3ec9f72744449dce883c36933
+    # via
+    #   -r vendor.in
+    #   opentelemetry-exporter-otlp-json-file
+    #   opentelemetry-exporter-otlp-json-http
+opentelemetry-exporter-otlp-json-file==0.66b2 \
+    --hash=sha256:a500f13bcc7760a74b5db7ece7d72ec8a78e0b515539fec81705970cb2efd7ca \
+    --hash=sha256:e0b64653b7bb37a67ce60051bf9e35bfa968a52081eb178a38b420f6fb73eaa6
+    # via -r vendor.in
+opentelemetry-exporter-otlp-json-http==0.66b2 \
+    --hash=sha256:35cab5377d5c4f9934a4f3e4638b605bd20a82ab7d4097ecbbcbf64d50557f1b \
+    --hash=sha256:56a91c92e09c83c01d07380f48df6f649f3ce89fd47aa8c4862ef84de8e47ddb
+    # via -r vendor.in
+opentelemetry-exporter-otlp-proto-common==1.45.2 \
+    --hash=sha256:af483b24217028892f017096731b794b196b785025d2e6808874720fd0b05a80 \
+    --hash=sha256:f1f2806f3f28ce7938033823e50934fcd91595a39de38e69a28a51e19f40fc6d
+    # via
+    #   -r vendor.in
+    #   opentelemetry-exporter-otlp-proto-http
+opentelemetry-exporter-otlp-proto-http==1.45.2 \
+    --hash=sha256:5984a3fb46bc4628e4e2b85d4a6e72637e03962aae6cf372791137768a4ad939 \
+    --hash=sha256:6e4d025138829d0ee57946930c2ccad6491ad4d92a958e9c7eea69278fe60cfc
+    # via -r vendor.in
+opentelemetry-exporter-prometheus==0.66b2 \
+    --hash=sha256:ada6b2507a31e10405f686e6a8498cb463a6931b5791337b04cfe14288db497f \
+    --hash=sha256:b73998788aa30bec3bfe20fae312650878adb59f6563ed8bf37c188cb450a189
+    # via -r vendor.in
+opentelemetry-instrumentation==0.66b2 \
+    --hash=sha256:02b094150e53b76f5906d75e628dbb3833bbc6e62fa109b5c7ba0c081865e923 \
+    --hash=sha256:fa9ccfdab147a14af8107d19ef0a7b5015675273c5adced7a1fc38f28b42ec4c
+    # via
+    #   -r vendor.in
+    #   opentelemetry-distro
+    #   opentelemetry-instrumentation-aiohttp-client
+opentelemetry-instrumentation-aiohttp-client==0.66b2 \
+    --hash=sha256:33c51743ca225c2405b81b40ac744697804aef44b530f64d1f524c9a9cd3dca2 \
+    --hash=sha256:9b1b3ec682b7b1df3d3c8f7ad1745703be847391bb722c9bd39b661902c667a4
+    # via -r vendor.in
+opentelemetry-propagator-b3==1.45.2 \
+    --hash=sha256:86c7f921a8390c0f7d88a27450765b6d075a3579f2592baa623723e9e527a1b8 \
+    --hash=sha256:e3ab95b91a3fd70c89b30bc366702984f1eb811a53416bf8555e700c290997ab
+    # via -r vendor.in
+opentelemetry-proto==1.45.2 \
+    --hash=sha256:03a7ca1b43f89fd5b965d5975902bb2515c0c86e2428b456836e9a6149c6235a \
+    --hash=sha256:bd8d23cf770605b0af9b7be2071d26a464fea289d35429abfd2a66226114ad64
+    # via
+    #   -r vendor.in
+    #   opentelemetry-exporter-otlp-proto-common
+    #   opentelemetry-exporter-otlp-proto-http
+opentelemetry-proto-json==0.66b2 \
+    --hash=sha256:0d6e905393710d4fca041b22aea8685f825c2da177de0de2d9ebf4218f5a6654 \
+    --hash=sha256:4da45dc527e68bc00fd4d16773c58b6a9a229ebb7a8dce997403414eaa03b3bb
+    # via
+    #   -r vendor.in
+    #   opentelemetry-exporter-otlp-json-common
+    #   opentelemetry-exporter-otlp-json-http
+opentelemetry-sdk==1.45.2 \
+    --hash=sha256:7eec4de13dd21ff3a1670dcb0e02079e692736f94d733dfdce5af461d884248d \
+    --hash=sha256:ff974ea70ee4f1d51e2ec152db37c2b626c7bf82bb3f7d86114fd8704e7199c6
+    # via
+    #   -r vendor.in
+    #   opentelemetry-configuration
+    #   opentelemetry-distro
+    #   opentelemetry-exporter-otlp-common
+    #   opentelemetry-exporter-otlp-json-common
+    #   opentelemetry-exporter-otlp-json-file
+    #   opentelemetry-exporter-otlp-json-http
+    #   opentelemetry-exporter-otlp-proto-http
+    #   opentelemetry-exporter-prometheus
+opentelemetry-semantic-conventions==0.66b2 \
+    --hash=sha256:4cbe61e5f9275d57ab31708446e7938ef4291ebbe6a7fca6f7a629c5acae87d8 \
+    --hash=sha256:7da5f1a5dc4383eb66711d4d3d3e71824d9403ac1559fea021cc103c1a4c4976
+    # via
+    #   -r vendor.in
+    #   opentelemetry-instrumentation
+    #   opentelemetry-instrumentation-aiohttp-client
+    #   opentelemetry-sdk
+opentelemetry-util-http==0.66b2 \
+    --hash=sha256:7ba066ea609202e474679ddf1d0f753a1e6619bd206b36afaecba4bbb86e25d0 \
+    --hash=sha256:c4bb5d6744e60353bcaa3e325bc529a1515346b51cb4d9c8e5b730579337e06d
+    # via opentelemetry-instrumentation-aiohttp-client
+packaging==26.3 \
+    --hash=sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79 \
+    --hash=sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c
+    # via opentelemetry-instrumentation
+prometheus-client==0.26.0 \
+    --hash=sha256:04a91bcf94e2cf74a44a1a874d651a2e853ed354b6e822f3b7487751465d5c2b \
+    --hash=sha256:fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6
+    # via opentelemetry-exporter-prometheus
 protobuf==7.36.2 \
     --hash=sha256:497d0463ff3316681da6c0b9e8d06cb465d61abce00b613ab42226175644d1bb \
     --hash=sha256:89f23aa53c24553a2416fd4fd1ec06f74fa42b14b546d8883128813f775bbfd2 \
@@ -191,16 +328,139 @@ protobuf==7.36.2 \
     --hash=sha256:cbc70b17ee27e28894c7fee8bb04be1abead49e936bc70eb60052531eee2079e \
     --hash=sha256:e11e1f0180583a2af89db6a2ecd9e8dc40aa6d2988ca175bfd0e6d12ea72d74e \
     --hash=sha256:f4fee11ec330d238b34a05c9b675f693c20415d1c5bd7d5320cc2f8a798eb9cf
-    # via -r vendor.in
+    # via
+    #   -r vendor.in
+    #   googleapis-common-protos
+    #   opentelemetry-proto
 requests==2.34.2 \
     --hash=sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0 \
     --hash=sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed
+    # via
+    #   -r vendor.in
+    #   opentelemetry-exporter-http-transport
+    #   opentelemetry-exporter-otlp-proto-http
+ruamel-yaml==0.19.1 \
+    --hash=sha256:27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93 \
+    --hash=sha256:53eb66cd27849eff968ebf8f0bf61f46cdac2da1d1f3576dd4ccee9b25c31993
     # via -r vendor.in
 typing-extensions==4.16.0 \
     --hash=sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8 \
     --hash=sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5
-    # via -r vendor.in
+    # via
+    #   -r vendor.in
+    #   opentelemetry-api
+    #   opentelemetry-exporter-otlp-proto-http
+    #   opentelemetry-propagator-b3
+    #   opentelemetry-sdk
+    #   opentelemetry-semantic-conventions
 urllib3==2.8.0 \
     --hash=sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3 \
     --hash=sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63
-    # via requests
+    # via
+    #   opentelemetry-exporter-http-transport
+    #   requests
+wrapt==2.5.2 \
+    --hash=sha256:01ace38a377198e0b981b027a46cbdb5502d0123bd39c1a0f60a83a5eab7698e \
+    --hash=sha256:035cd71e2aadfc0ad366ab4785b49e62093370885ea4b527b61b308b7a92ff14 \
+    --hash=sha256:04703a2a4eea122c3a6b3af89e72bbbaa20779e5c7199c3d06e3fcb6601bc7d4 \
+    --hash=sha256:0743950d3dda9940e56f81f5334ba051c4fe2e1421e4e4a4ef8eb8fb86a90894 \
+    --hash=sha256:08d1d7bcb7dd277b7b976fd914455c3c1088f5c101ac7469ae5a5b8c03be0a0a \
+    --hash=sha256:092472b7b1494deef40dac5e9f6295013a9d51b112b5fbc4350f64dc2574e46a \
+    --hash=sha256:0d7639c3287d4efcdc2c8837f1854d1ecf27aae761714ba3d95e61fe8eb48db3 \
+    --hash=sha256:0fa61d2f1033039aa47f8f1b4e076ca3c9d0fc08e448c4b1bd06d8b59da89cbf \
+    --hash=sha256:11655df8e17658a67628cdc97fe95d6b263e023213cf18067f21e5ec0b0285f3 \
+    --hash=sha256:1433ddff7786f2d0d4096646530a7aa04de0e776715014b80bc289e874fd8538 \
+    --hash=sha256:143a3f8b33984e35950ae5d0159be2bac93356b6f79b509af9941a4be64c4368 \
+    --hash=sha256:18819c05409a161999be68da8e451636470c35f77e25c8201825a33a7d88c89c \
+    --hash=sha256:1ad706a42b139ad7f03f32aed57da5e10fe8ed707e29849cfa94f1d49cba1405 \
+    --hash=sha256:1c17ca5ce83c7145eddaa20073398ec2192dad65c8d8ff4d9b78fd2917c46a75 \
+    --hash=sha256:217798fb0cfb31479a264f841b0242bc1bed1ffc70d233e8444a876cec57928c \
+    --hash=sha256:229859aebfc909626ea6b5a3ae9523aba43c63fd828f876f2a813f4a5767726f \
+    --hash=sha256:244d57e361833389278820e5242f4a364305f633572d9500d3a85f40417aefee \
+    --hash=sha256:2594e0be4ee09b2f19828265a39df90e591def44215fe8c5b8d6b83aa4cc18b5 \
+    --hash=sha256:269321b17467a10997cc6e14793bf1816e6ce488f9711c74b72552466d206739 \
+    --hash=sha256:2861d50a4f330fa140ddc2a9ddee33f7e4f9bdb649a23dc9be8ed6310ffa47fc \
+    --hash=sha256:2bf23cde96e0f771a6a2c68973c1ded45c9707f8bd519ede30ecf075f3c720f6 \
+    --hash=sha256:2c17ec4310cc06f864799a4c37c1c716d5dcf05ceead2e63ca992a9466903b73 \
+    --hash=sha256:32c0387872e67b9dfdd2b599bf31fe127e597ed8526c5f192cdaca57a491e9dc \
+    --hash=sha256:36021ef761856bdbc10d5f3da9a95af93ef60d6acf9c72c8f849937ba2b902aa \
+    --hash=sha256:3b6885250b809532a634acd56e360d57c201c1cdc75cbf2b5e106241ece6cbc3 \
+    --hash=sha256:40e03506f09dbf4854fd69848e843dadd9b7fbbdd217837cb27b37fb8f0b5bc3 \
+    --hash=sha256:40f8ae3eb1388763fd2e60b55e1d569f66e80552e02a333f3d2fa9139a509d1e \
+    --hash=sha256:430070776fb30d925a7a1e13d68086e4731b63eedf4c43ee62fc4c8108920cce \
+    --hash=sha256:450cc93f5a2d58d4a74d384d52db4b41d5728065c0057c9bb4666c6115f2a2c9 \
+    --hash=sha256:459bb66cd4bc43e35cba1f1ab2bdfb9b507e0d8dc0ec40c93a060c9cb0c5415e \
+    --hash=sha256:46cee4400437c9f33e755522be9e7ce6ebd097273f464eb6f57bee09787f0c59 \
+    --hash=sha256:48fd5026977adb3e2fda292a6a796967b511935d23f97dc2ae1f127a3a8639d5 \
+    --hash=sha256:4d5faf5c3e435207b3a51294ed5a00e5e17e3842442ccbbd864ee9bc0efc63fb \
+    --hash=sha256:4e86f3543c67d72b4d4c08c3e351523c2d69cd05932df65937d79bc472e9d62f \
+    --hash=sha256:51465dcbab69d9c02e8ca943befa1eabc37ccb07f9335c240d78a78330285a2d \
+    --hash=sha256:53cf804402d49fa2c920a90dfab971a82bca67fb43e54adc7c3b24c054485b4d \
+    --hash=sha256:550a597a9c0510fb8bd79864025225f4fc51717adb617191561295565337f068 \
+    --hash=sha256:551cb49e88b3722faad780303833bc4fa70685fb1773270fb98b40d39d9fddbf \
+    --hash=sha256:5726faa7342ba473041bc1a276486d232b42e3927d35427729b266b1b5ecaa42 \
+    --hash=sha256:594c6d10b9cfb951a09f7338531a41d31194e7eee9dee206c0a8992421682719 \
+    --hash=sha256:59b7e6d1dea7c3f38bab21954f587499c27c16ea537058eee4add6e4da1780ea \
+    --hash=sha256:5ab31d929ca8b2b7bf9320ad2a927edfb1841609951a869a9b98723b285ffbc6 \
+    --hash=sha256:61eb54e9540ea522c2c4752a57549a83d3c67e6704ed708403d28e067aaf90f0 \
+    --hash=sha256:62b339565cfdfcc0ba71c527b4ad13ac9de25504d474fa4ae5db95d1c7e4c6a2 \
+    --hash=sha256:73d432588d1e0a8fcb88d46ef2733e848ff0c3e14111a0420c77199fd2a8cd30 \
+    --hash=sha256:7a7efde469ad904b8e05f98c76d63b437f4756c30ec7b9136bef02bdb5d1b14c \
+    --hash=sha256:7f89423965b23aa62a90bf21c20353056a829ca9a60c01fde9aec9876c99392e \
+    --hash=sha256:7ffa0be31f651da63ee51e5b74701339feac1860b561a985c7b4869d4600e800 \
+    --hash=sha256:80eec154f8ce6d26a553481772f111a064091b7e37700c690e0024921d57c569 \
+    --hash=sha256:81bdf0bd141d9b1706a0751b2ee068c7afe6be4042712d427b32b3072d5c40b9 \
+    --hash=sha256:81e685c7662fab9958a852b9c86f3b5b8eee45d047a2766d6c23b63ad1eee423 \
+    --hash=sha256:84619ca6b6f67a7dd53754ad402cafceb4ddc9d8981f144f62718b783f05786e \
+    --hash=sha256:8581eab7cb0a3bc6e8c8f64f853a1a814664d71f7ca74efb3011b4df2a40314b \
+    --hash=sha256:858511731d6ede4217960c5fecdb5ecbf90e306dfd93b837395658d61374a498 \
+    --hash=sha256:88f982c2bb306732271aa15cded4002ce28b5d9023de9d11e927da4dcf65e441 \
+    --hash=sha256:8b039b3a296762db1908d6108365225393c4fb33c1dbc5f00aa36f8302eaeaa0 \
+    --hash=sha256:8b240a879405591da10e2d20c2d1ad29b978d40ec37e24801296cfee1d4c04f9 \
+    --hash=sha256:90dad90c8a74293d2cb3ed225760a8c8f20009522efe519d6380f5de7f5caece \
+    --hash=sha256:99978d196df45c115273c6119e4d0dacbc67bc267a196506625bf7084b741f0b \
+    --hash=sha256:9c0e0342eba94829491985516e951d1b6a2de402ae4a44d1ea0debbd929cb7a9 \
+    --hash=sha256:9cb33f293e3aa04b36f7d165dc05b42db85e0a88e20a8fd81f60426d1f17d535 \
+    --hash=sha256:9d4e1cdf2efdc7181c8177f6090886e22278e70f7257df12863d2f52a9dcbbd7 \
+    --hash=sha256:a0541e62f7b9c0d42130e3469d6ac3b1767f019314ae795646a2850a75c64412 \
+    --hash=sha256:a60863d874cc6ac917bbf44324e3f195564064dee15c84e83b19e1fbbccd3169 \
+    --hash=sha256:a829b0febab0828f5d47903b11474f9f23711da5ac55e15d0d177e907d3c15e7 \
+    --hash=sha256:a8626135ecbb0b892ca79c388581ab0ef57e087f09dc0e51a2f34185d3682055 \
+    --hash=sha256:ac00ba7d22d55d3c8d085005ce4942ff3bb118d480f889b5984f1d3454052917 \
+    --hash=sha256:ad9daa883bb795b8cbe960570590878280a444173fece51f7bbfb7532a9538e2 \
+    --hash=sha256:ae84013e89ec1874415549a46cfea373e28ddecbb72e1f5456cddfa2b76a28e6 \
+    --hash=sha256:af9cecb68173b0945a53e7aaabc65ef6ef458f6dd201a9ebb23139e804f1f5e7 \
+    --hash=sha256:afd99530994449aaac9a58e1e268eb080bb1ffd758be43ab2f8a249ce8970c9c \
+    --hash=sha256:b3ebc07822649eda442382c1d20983bc6ec5aa2bf79a600da11b29ecb62a0fb2 \
+    --hash=sha256:b528eb5dbf54cf9c3e9b9c5b1680e0f4965eb8750ae738f43dd14d1bc332fa42 \
+    --hash=sha256:b632d90ac0d04e3ba8821b19954d6c36ea8f714b75db53c58015025fefccb1ac \
+    --hash=sha256:b680bef5200899524667f813fa34dcfde9313fef9f9fa432985d4bc7b4195ba3 \
+    --hash=sha256:b9ce67ec8803e6c56e78c9ebf726f61116516212c28dfa3683d0962e15cf9a62 \
+    --hash=sha256:b9f41029f9bc6ba80755b9c07f5e77e9e7aafb71c625b9f67614e4ebfb24302a \
+    --hash=sha256:bbb6e959c1e2c32bbad291f83af6320c8c46bb64e256801e85f55d88a09522d5 \
+    --hash=sha256:bec3b6b1ae2f7ed763fb0ba1776b9b5f11283e6ff40c9cbe3a855ea652c326cf \
+    --hash=sha256:c1ea16d7dfe7d235d29435307b1539495b4925e88b135d532892973a04569245 \
+    --hash=sha256:c60a5cd8b7b510056f2643d94f1c144533a568ade2891a9dd35733f5e0055777 \
+    --hash=sha256:c6b4bd8c662c333518a9aedb35bb9f4f7d1584fbef4bc1507a6c6a47357c628e \
+    --hash=sha256:c954a582cd96faa9a7598b634efdc92c9fa7710538dae93fbd9222c3a1e13beb \
+    --hash=sha256:cfd508866c421687a99bed9ce5b7b4f26fd9b93d3753685d81947ab37d54c496 \
+    --hash=sha256:d108bd98ab2c5ccbf55cf2154e0a73341df930030df2e01ee35d71a44a99d3ad \
+    --hash=sha256:d41c45517912610de55546188695e2bd0fbcd70b585087cd759f85a96f47be7e \
+    --hash=sha256:d5322e78248f6079f6525f0a9476750112750ea0a3f3fca13fd5f18a1c864d3b \
+    --hash=sha256:d8dc92a832446351ce3bf5876aa558e4f6b456ca0613d02969ce0db4762394b2 \
+    --hash=sha256:da51f5ac290f2e024ee842799c6592f68cd880c20f6b3a54305d1b6aeab459a4 \
+    --hash=sha256:ded0118adcb43b080cfcbe2a96dcf27171b8fd73d0b418603d899f4e6309ac50 \
+    --hash=sha256:e1af6136ac5bcfab17190a70b25d8437eb8d8f9ca2b821a0655d39275a8cb7e7 \
+    --hash=sha256:e1fb4af8aac3573770ed3e64efc39d953342b12bcb6e6479512a945eb5557523 \
+    --hash=sha256:e33578755e07edf3a70df3241f4cf376dad507e2cc73e737311bb00b5067f4d7 \
+    --hash=sha256:e4362b3b4e4b050b8f1f518e0c71a09f2e938a9f62ee559ea1743a13b3c9e8f1 \
+    --hash=sha256:e57d79e3338b3cecee1dd80d6ef8f945f8ea7b92f0d8d5591f840ffa0afc14dc \
+    --hash=sha256:eeaa40251c40e18c5c97ef11d5dbbad28a7b7b99fdd7a7469662799100d74dc7 \
+    --hash=sha256:eff91af619ad5d587f8855f6c02164e12d33d205c702eb73d487deb499520265 \
+    --hash=sha256:f00c726586871c22f542df6d5ce57a81e60e9339e4d40bcc7d7d5c6130db3cce \
+    --hash=sha256:f01f56a6ddffd89179bf0424c3b5bbd187690cfa2f972472aa2d563a4e0a7fdb \
+    --hash=sha256:fa642d3781c061579cb138773add4a55b16f99de9ebc41603e89a756cf9e62c6 \
+    --hash=sha256:fabc60720d1e4a36bbe8aaf1c32024f04c6674991313f5acaca5eeadb564c600
+    # via
+    #   opentelemetry-instrumentation
+    #   opentelemetry-instrumentation-aiohttp-client
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE
new file mode 100644
index 00000000000..c781ecbf698
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE
@@ -0,0 +1,21 @@
+ The MIT License (MIT)
+
+ Copyright (c) 2014-2026 Anthon van der Neut, Ruamel bvba
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py
new file mode 100644
index 00000000000..bd6df7d3858
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py
@@ -0,0 +1,51 @@
+
+from __future__ import annotations
+
+if False:  # MYPY
+    from typing import Dict, Any  # NOQA
+
+_package_data = dict(
+    full_package_name='ruamel.yaml',
+    version_info=(0, 19, 1),
+    __version__='0.19.1',
+    version_timestamp='2026-01-02 17:17:31',
+    author='Anthon van der Neut',
+    author_email='a.van.der.neut@ruamel.eu',
+    description='ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order',  # NOQA
+    entry_points=None,
+    since=2014,
+    extras_require={
+        'oldlibyaml' : ['ruamel.yaml.clib; platform_python_implementation=="CPython"'],  # NOQA
+        'libyaml' : ['ruamel.yaml.clibz>=0.3.7; platform_python_implementation=="CPython"'],  # NOQA
+        'jinja2': ['ruamel.yaml.jinja2>=0.2'],
+        'docs': ['ryd', 'mercurial>5.7'],
+    },
+    classifiers=[
+        'Programming Language :: Python :: Implementation :: CPython',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+        'Topic :: Text Processing :: Markup',
+        'Typing :: Typed',
+    ],
+    keywords='yaml 1.2 parser round-trip preserve quotes order config',
+    url_doc='https://yaml.dev/doc/{full_package_name}',
+    tox=dict(
+        env='*',
+        fl8excl='_test/lib,branch_default',
+    ),
+    # universal=True,
+    supported=[(3, 9)],  # minimum
+)  # type: Dict[Any, Any]
+
+
+version_info = _package_data['version_info']
+__version__ = _package_data['__version__']
+
+try:
+    from .cyaml import *  # NOQA
+
+    __with_libyaml__ = True
+except (ImportError, ValueError):  # for Jython
+    __with_libyaml__ = False
+    __yaml_lib = None
+
+from opentelemetry.agent._vendor.ruamel.yaml.main import *  # NOQA
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py
new file mode 100644
index 00000000000..4f342f3e0b9
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py
@@ -0,0 +1,20 @@
+
+from __future__ import annotations
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Union, Iterator  # NOQA
+
+anchor_attrib = '_yaml_anchor'
+
+
+class Anchor:
+    __slots__ = 'value', 'always_dump'
+    attrib = anchor_attrib
+
+    def __init__(self) -> None:
+        self.value = None
+        self.always_dump = False
+
+    def __repr__(self) -> Any:
+        ad = ', (always dump)' if self.always_dump else ""
+        return f'Anchor({self.value!r}{ad})'
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py
new file mode 100644
index 00000000000..fe652fc449c
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py
@@ -0,0 +1,1208 @@
+
+from __future__ import annotations
+
+"""
+stuff to deal with comments and formatting on dict/list/ordereddict/set
+these are not really related, formatting could be factored out as
+a separate base
+"""
+
+import sys
+import copy
+
+
+from opentelemetry.agent._vendor.ruamel.yaml.compat import ordereddict
+from opentelemetry.agent._vendor.ruamel.yaml.compat import MutableSliceableSequence, nprintf  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.scalarstring import ScalarString
+from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
+from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
+
+from collections.abc import MutableSet, Sized, Set, Mapping
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Union, Iterator  # NOQA
+
+# fmt: off
+__all__ = ['CommentedSeq', 'CommentedKeySeq',
+           'CommentedMap', 'CommentedOrderedMap',
+           'CommentedSet', 'comment_attrib', 'merge_attrib',
+           'TaggedScalar',
+           'C_POST', 'C_PRE', 'C_SPLIT_ON_FIRST_BLANK', 'C_BLANK_LINE_PRESERVE_SPACE',
+           ]
+# fmt: on
+
+# splitting of comments by the scanner
+# an EOLC (End-Of-Line Comment) is preceded by some token
+# an FLC (Full Line Comment) is a comment not preceded by a token, i.e. # is
+#   the first non-blank on line
+# a BL is a blank line i.e. empty or spaces/tabs only
+# bits 0 and 1 are combined, you can choose only one
+C_POST = 0b00
+C_PRE = 0b01
+C_SPLIT_ON_FIRST_BLANK = 0b10  # as C_POST, but if blank line then C_PRE all lines before
+# first blank goes to POST even if no following real FLC
+# (first blank -> first of post)
+# 0b11 -> reserved for future use
+C_BLANK_LINE_PRESERVE_SPACE = 0b100
+# C_EOL_PRESERVE_SPACE2 = 0b1000
+
+
+class IDX:
+    # temporary auto increment, so rearranging is easier
+    def __init__(self) -> None:
+        self._idx = 0
+
+    def __call__(self) -> Any:
+        x = self._idx
+        self._idx += 1
+        return x
+
+    def __str__(self) -> Any:
+        return str(self._idx)
+
+
+cidx = IDX()
+
+# more or less in order of subjective expected likelyhood
+# the _POST and _PRE ones are lists themselves
+C_VALUE_EOL = C_ELEM_EOL = cidx()
+C_KEY_EOL = cidx()
+C_KEY_PRE = C_ELEM_PRE = cidx()  # not this is not value
+C_VALUE_POST = C_ELEM_POST = cidx()  # not this is not value
+C_VALUE_PRE = cidx()
+C_KEY_POST = cidx()
+C_TAG_EOL = cidx()
+C_TAG_POST = cidx()
+C_TAG_PRE = cidx()
+C_ANCHOR_EOL = cidx()
+C_ANCHOR_POST = cidx()
+C_ANCHOR_PRE = cidx()
+
+
+comment_attrib = '_yaml_comment'
+format_attrib = '_yaml_format'
+line_col_attrib = '_yaml_line_col'
+merge_attrib = '_yaml_merge'
+
+
+class Comment:
+    # using sys.getsize tested the Comment objects, __slots__ makes them bigger
+    # and adding self.end did not matter
+    __slots__ = 'comment', '_items', '_post', '_pre'
+    attrib = comment_attrib
+
+    def __init__(self, old: bool = True) -> None:
+        self._pre = None if old else []  # type: ignore
+        self.comment = None  # [post, [pre]]
+        # map key (mapping/omap/dict) or index (sequence/list) to a  list of
+        # dict: post_key, pre_key, post_value, pre_value
+        # list: pre item, post item
+        self._items: Dict[Any, Any] = {}
+        # self._start = [] # should not put these on first item
+        self._post: List[Any] = []  # end of document comments
+
+    def __str__(self) -> str:
+        if bool(self._post):
+            end = ',\n  end=' + str(self._post)
+        else:
+            end = ""
+        return f'Comment(comment={self.comment},\n  items={self._items}{end})'
+
+    def _old__repr__(self) -> str:
+        if bool(self._post):
+            end = ',\n  end=' + str(self._post)
+        else:
+            end = ""
+        try:
+            ln = max([len(str(k)) for k in self._items]) + 1
+        except ValueError:
+            ln = ''  # type: ignore
+        it = '    '.join([f'{str(k) + ":":{ln}} {v}\n' for k, v in self._items.items()])
+        if it:
+            it = '\n    ' + it + '  '
+        return f'Comment(\n  start={self.comment},\n  items={{{it}}}{end})'
+
+    def __repr__(self) -> str:
+        if self._pre is None:
+            return self._old__repr__()
+        if bool(self._post):
+            end = ',\n  end=' + repr(self._post)
+        else:
+            end = ""
+        try:
+            ln = max([len(str(k)) for k in self._items]) + 1
+        except ValueError:
+            ln = ''  # type: ignore
+        it = '    '.join([f'{str(k) + ":":{ln}} {v}\n' for k, v in self._items.items()])
+        if it:
+            it = '\n    ' + it + '  '
+        return f'Comment(\n  pre={self.pre},\n  items={{{it}}}{end})'
+
+    @property
+    def items(self) -> Any:
+        return self._items
+
+    @property
+    def end(self) -> Any:
+        return self._post
+
+    @end.setter
+    def end(self, value: Any) -> None:
+        self._post = value
+
+    @property
+    def pre(self) -> Any:
+        return self._pre
+
+    @pre.setter
+    def pre(self, value: Any) -> None:
+        self._pre = value
+
+    def get(self, item: Any, pos: Any) -> Any:
+        x = self._items.get(item)
+        if x is None or len(x) < pos:
+            return None
+        return x[pos]  # can be None
+
+    def set(self, item: Any, pos: Any, value: Any) -> Any:
+        x = self._items.get(item)
+        if x is None:
+            self._items[item] = x = [None] * (pos + 1)
+        else:
+            while len(x) <= pos:
+                x.append(None)
+        assert x[pos] is None
+        x[pos] = value
+
+    def __contains__(self, x: Any) -> Any:
+        # test if a substring is in any of the attached comments
+        if self.comment:
+            if self.comment[0] and x in self.comment[0].value:
+                return True
+            if self.comment[1]:
+                for c in self.comment[1]:
+                    if x in c.value:
+                        return True
+        for value in self.items.values():
+            if not value:
+                continue
+            for c in value:
+                if c and x in c.value:
+                    return True
+        if self.end:
+            for c in self.end:
+                if x in c.value:
+                    return True
+        return False
+
+
+# to distinguish key from None
+class NotNone:
+    pass  # NOQA
+
+
+class Format:
+    __slots__ = ('_flow_style',)
+    attrib = format_attrib
+
+    def __init__(self) -> None:
+        self._flow_style: Any = None
+
+    def set_flow_style(self) -> None:
+        self._flow_style = True
+
+    def set_block_style(self) -> None:
+        self._flow_style = False
+
+    def flow_style(self, default: Optional[Any] = None) -> Any:
+        """if default (the flow_style) is None, the flow style tacked on to
+        the object explicitly will be taken. If that is None as well the
+        default flow style rules the format down the line, or the type
+        of the constituent values (simple -> flow, map/list -> block)"""
+        if self._flow_style is None:
+            return default
+        return self._flow_style
+
+    def __repr__(self) -> str:
+        return f'Format({self._flow_style})'
+
+
+class LineCol:
+    """
+    line and column information wrt document, values start at zero (0)
+    """
+
+    attrib = line_col_attrib
+
+    def __init__(self) -> None:
+        self.line = None
+        self.col = None
+        self.data: Optional[Dict[Any, Any]] = None
+
+    def add_kv_line_col(self, key: Any, data: Any) -> None:
+        if self.data is None:
+            self.data = {}
+        self.data[key] = data
+
+    def key(self, k: Any) -> Any:
+        return self._kv(k, 0, 1)
+
+    def value(self, k: Any) -> Any:
+        return self._kv(k, 2, 3)
+
+    def _kv(self, k: Any, x0: Any, x1: Any) -> Any:
+        if self.data is None:
+            return None
+        data = self.data[k]
+        return data[x0], data[x1]
+
+    def item(self, idx: Any) -> Any:
+        if self.data is None:
+            return None
+        return self.data[idx][0], self.data[idx][1]
+
+    def add_idx_line_col(self, key: Any, data: Any) -> None:
+        if self.data is None:
+            self.data = {}
+        self.data[key] = data
+
+    def __repr__(self) -> str:
+        return f'LineCol({self.line}, {self.col})'
+
+
+class CommentedBase:
+    @property
+    def ca(self):
+        # type: () -> Any
+        if not hasattr(self, Comment.attrib):
+            setattr(self, Comment.attrib, Comment())
+        return getattr(self, Comment.attrib)
+
+    def yaml_end_comment_extend(self, comment: Any, clear: bool = False) -> None:
+        if comment is None:
+            return
+        if clear or self.ca.end is None:
+            self.ca.end = []
+        self.ca.end.extend(comment)
+
+    def yaml_key_comment_extend(self, key: Any, comment: Any, clear: bool = False) -> None:
+        r = self.ca._items.setdefault(key, [None, None, None, None])
+        if clear or r[1] is None:
+            if comment[1] is not None:
+                assert isinstance(comment[1], list)
+            r[1] = comment[1]
+        else:
+            r[1].extend(comment[0])
+        r[0] = comment[0]
+
+    def yaml_value_comment_extend(self, key: Any, comment: Any, clear: bool = False) -> None:
+        r = self.ca._items.setdefault(key, [None, None, None, None])
+        if clear or r[3] is None:
+            if comment[1] is not None:
+                assert isinstance(comment[1], list)
+            r[3] = comment[1]
+        else:
+            r[3].extend(comment[0])
+        r[2] = comment[0]
+
+    def yaml_set_start_comment(self, comment: Any, indent: Any = 0) -> None:
+        """overwrites any preceding comment lines on an object
+        expects comment to be without `#` and possible have multiple lines
+        """
+        from .error import CommentMark
+        from .tokens import CommentToken
+
+        pre_comments = self._yaml_clear_pre_comment()  # type: ignore
+        if comment[-1] == '\n':
+            comment = comment[:-1]  # strip final newline if there
+        start_mark = CommentMark(indent)
+        for com in comment.split('\n'):
+            c = com.strip()
+            if len(c) > 0 and c[0] != '#':
+                com = '# ' + com
+            pre_comments.append(CommentToken(com + '\n', start_mark))
+
+    def yaml_set_comment_before_after_key(
+        self,
+        key: Any,
+        before: Any = None,
+        indent: Any = 0,
+        after: Any = None,
+        after_indent: Any = None,
+    ) -> None:
+        """
+        expects comment (before/after) to be without `#` and possible have multiple lines
+        """
+        from opentelemetry.agent._vendor.ruamel.yaml.error import CommentMark
+        from opentelemetry.agent._vendor.ruamel.yaml.tokens import CommentToken
+
+        def comment_token(s: Any, mark: Any) -> Any:
+            # handle empty lines as having no comment
+            return CommentToken(('# ' if s else "") + s + '\n', mark)
+
+        if after_indent is None:
+            after_indent = indent + 2
+        if before and (len(before) > 1) and before[-1] == '\n':
+            before = before[:-1]  # strip final newline if there
+        if after and after[-1] == '\n':
+            after = after[:-1]  # strip final newline if there
+        start_mark = CommentMark(indent)
+        c = self.ca.items.setdefault(key, [None, [], None, None])
+        if before is not None:
+            if c[1] is None:
+                c[1] = []
+            if before == '\n':
+                c[1].append(comment_token("", start_mark))  # type: ignore
+            else:
+                for com in before.split('\n'):
+                    c[1].append(comment_token(com, start_mark))  # type: ignore
+        if after:
+            start_mark = CommentMark(after_indent)
+            if c[3] is None:
+                c[3] = []
+            for com in after.split('\n'):
+                c[3].append(comment_token(com, start_mark))  # type: ignore
+
+    @property
+    def fa(self) -> Any:
+        """format attribute
+
+        set_flow_style()/set_block_style()"""
+        if not hasattr(self, Format.attrib):
+            setattr(self, Format.attrib, Format())
+        return getattr(self, Format.attrib)
+
+    def yaml_add_eol_comment(
+        self, comment: Any, key: Optional[Any] = NotNone, column: Optional[Any] = None,
+    ) -> None:
+        """
+        there is a problem as eol comments should start with ' #'
+        (but at the beginning of the line the space doesn't have to be before
+        the #. The column index is for the # mark
+        """
+        from .tokens import CommentToken
+        from .error import CommentMark
+
+        if column is None:
+            try:
+                column = self._yaml_get_column(key)
+            except AttributeError:
+                column = 0
+        if comment[0] != '#':
+            comment = '# ' + comment
+        if column is None:
+            if comment[0] == '#':
+                comment = ' ' + comment
+                column = 0
+        start_mark = CommentMark(column)
+        ct = [CommentToken(comment, start_mark), None]
+        self._yaml_add_eol_comment(ct, key=key)
+
+    @property
+    def lc(self) -> Any:
+        if not hasattr(self, LineCol.attrib):
+            setattr(self, LineCol.attrib, LineCol())
+        return getattr(self, LineCol.attrib)
+
+    def _yaml_set_line_col(self, line: Any, col: Any) -> None:
+        self.lc.line = line
+        self.lc.col = col
+
+    def _yaml_set_kv_line_col(self, key: Any, data: Any) -> None:
+        self.lc.add_kv_line_col(key, data)
+
+    def _yaml_set_idx_line_col(self, key: Any, data: Any) -> None:
+        self.lc.add_idx_line_col(key, data)
+
+    @property
+    def anchor(self) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            setattr(self, Anchor.attrib, Anchor())
+        return getattr(self, Anchor.attrib)
+
+    def yaml_anchor(self) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            return None
+        return self.anchor
+
+    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
+        self.anchor.value = value
+        self.anchor.always_dump = always_dump
+
+    @property
+    def tag(self) -> Any:
+        if not hasattr(self, Tag.attrib):
+            setattr(self, Tag.attrib, Tag())
+        return getattr(self, Tag.attrib)
+
+    def yaml_set_ctag(self, value: Tag) -> None:
+        setattr(self, Tag.attrib, value)
+
+    def copy_attributes(self, t: Any, memo: Any = None) -> Any:
+        """
+        copies the YAML related attributes, not e.g. .values
+        returns target
+        """
+        # fmt: off
+        for a in [Comment.attrib, Format.attrib, LineCol.attrib, Anchor.attrib,
+                  Tag.attrib, merge_attrib]:
+            if hasattr(self, a):
+                if memo is not None:
+                    setattr(t, a, copy.deepcopy(getattr(self, a, memo)))
+                else:
+                    setattr(t, a, getattr(self, a))
+        return t
+        # fmt: on
+
+    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
+        raise NotImplementedError
+
+    def _yaml_get_pre_comment(self) -> Any:
+        raise NotImplementedError
+
+    def _yaml_get_column(self, key: Any) -> Any:
+        raise NotImplementedError
+
+
+class CommentedSeq(MutableSliceableSequence, list, CommentedBase):  # type: ignore
+    __slots__ = (Comment.attrib, '_lst')
+
+    def __init__(self, *args: Any, **kw: Any) -> None:
+        list.__init__(self, *args, **kw)
+
+    def __getsingleitem__(self, idx: Any) -> Any:
+        return list.__getitem__(self, idx)
+
+    def __setsingleitem__(self, idx: Any, value: Any) -> None:
+        # try to preserve the scalarstring type if setting an existing key to a new value
+        if idx < len(self):
+            if (
+                isinstance(value, str)
+                and not isinstance(value, ScalarString)
+                and isinstance(self[idx], ScalarString)
+            ):
+                value = type(self[idx])(value)
+        list.__setitem__(self, idx, value)
+
+    def __delsingleitem__(self, idx: Any = None) -> Any:
+        list.__delitem__(self, idx)
+        self.ca.items.pop(idx, None)  # might not be there -> default value
+        for list_index in sorted(self.ca.items):
+            if list_index < idx:
+                continue
+            self.ca.items[list_index - 1] = self.ca.items.pop(list_index)
+
+    def __len__(self) -> int:
+        return list.__len__(self)
+
+    def insert(self, idx: Any, val: Any) -> None:
+        """the comments after the insertion have to move forward"""
+        list.insert(self, idx, val)
+        for list_index in sorted(self.ca.items, reverse=True):
+            if list_index < idx:
+                break
+            self.ca.items[list_index + 1] = self.ca.items.pop(list_index)
+
+    def extend(self, val: Any) -> None:
+        list.extend(self, val)
+
+    def __eq__(self, other: Any) -> bool:
+        return list.__eq__(self, other)
+
+    def _yaml_add_comment(self, comment: Any, key: Optional[Any] = NotNone) -> None:
+        if key is not NotNone:
+            self.yaml_key_comment_extend(key, comment)
+        else:
+            self.ca.comment = comment
+
+    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
+        self._yaml_add_comment(comment, key=key)
+
+    def _yaml_get_columnX(self, key: Any) -> Any:
+        return self.ca.items[key][0].start_mark.column
+
+    def _yaml_get_column(self, key: Any) -> Any:
+        column = None
+        sel_idx = None
+        pre, post = key - 1, key + 1
+        if pre in self.ca.items:
+            sel_idx = pre
+        elif post in self.ca.items:
+            sel_idx = post
+        else:
+            # self.ca.items is not ordered
+            for row_idx, _k1 in enumerate(self):
+                if row_idx >= key:
+                    break
+                if row_idx not in self.ca.items:
+                    continue
+                sel_idx = row_idx
+        if sel_idx is not None:
+            column = self._yaml_get_columnX(sel_idx)
+        return column
+
+    def _yaml_get_pre_comment(self) -> Any:
+        pre_comments: List[Any] = []
+        if self.ca.comment is None:
+            self.ca.comment = [None, pre_comments]
+        else:
+            pre_comments = self.ca.comment[1]
+        return pre_comments
+
+    def _yaml_clear_pre_comment(self) -> Any:
+        pre_comments: List[Any] = []
+        if self.ca.comment is None:
+            self.ca.comment = [None, pre_comments]
+        else:
+            self.ca.comment[1] = pre_comments
+        return pre_comments
+
+    def __deepcopy__(self, memo: Any) -> Any:
+        res = self.__class__()
+        memo[id(self)] = res
+        for k in self:
+            res.append(copy.deepcopy(k, memo))
+            self.copy_attributes(res, memo=memo)
+        return res
+
+    def __add__(self, other: Any) -> Any:
+        return list.__add__(self, other)
+
+    def sort(self, key: Any = None, reverse: bool = False) -> None:
+        if key is None:
+            tmp_lst = sorted(zip(self, range(len(self))), reverse=reverse)
+            list.__init__(self, [x[0] for x in tmp_lst])
+        else:
+            tmp_lst = sorted(
+                zip(map(key, list.__iter__(self)), range(len(self))), reverse=reverse,
+            )
+            list.__init__(self, [list.__getitem__(self, x[1]) for x in tmp_lst])
+        itm = self.ca.items
+        self.ca._items = {}
+        for idx, x in enumerate(tmp_lst):
+            old_index = x[1]
+            if old_index in itm:
+                self.ca.items[idx] = itm[old_index]
+
+    def __repr__(self) -> Any:
+        return list.__repr__(self)
+
+
+class CommentedKeySeq(tuple, CommentedBase):  # type: ignore
+    """This primarily exists to be able to roundtrip keys that are sequences"""
+
+    def _yaml_add_comment(self, comment: Any, key: Optional[Any] = NotNone) -> None:
+        if key is not NotNone:
+            self.yaml_key_comment_extend(key, comment)
+        else:
+            self.ca.comment = comment
+
+    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
+        self._yaml_add_comment(comment, key=key)
+
+    def _yaml_get_columnX(self, key: Any) -> Any:
+        return self.ca.items[key][0].start_mark.column
+
+    def _yaml_get_column(self, key: Any) -> Any:
+        column = None
+        sel_idx = None
+        pre, post = key - 1, key + 1
+        if pre in self.ca.items:
+            sel_idx = pre
+        elif post in self.ca.items:
+            sel_idx = post
+        else:
+            # self.ca.items is not ordered
+            for row_idx, _k1 in enumerate(self):
+                if row_idx >= key:
+                    break
+                if row_idx not in self.ca.items:
+                    continue
+                sel_idx = row_idx
+        if sel_idx is not None:
+            column = self._yaml_get_columnX(sel_idx)
+        return column
+
+    def _yaml_get_pre_comment(self) -> Any:
+        pre_comments: List[Any] = []
+        if self.ca.comment is None:
+            self.ca.comment = [None, pre_comments]
+        else:
+            pre_comments = self.ca.comment[1]
+        return pre_comments
+
+    def _yaml_clear_pre_comment(self) -> Any:
+        pre_comments: List[Any] = []
+        if self.ca.comment is None:
+            self.ca.comment = [None, pre_comments]
+        else:
+            self.ca.comment[1] = pre_comments
+        return pre_comments
+
+
+class CommentedMapView(Sized):
+    __slots__ = ('_mapping',)
+
+    def __init__(self, mapping: Any) -> None:
+        self._mapping = mapping
+
+    def __len__(self) -> int:
+        count = len(self._mapping)
+        return count
+
+
+class CommentedMapKeysView(CommentedMapView, Set):  # type: ignore
+    __slots__ = ()
+
+    @classmethod
+    def _from_iterable(self, it: Any) -> Any:
+        return set(it)
+
+    def __contains__(self, key: Any) -> Any:
+        return key in self._mapping
+
+    def __iter__(self) -> Any:
+        # yield from self._mapping  # not in py27, pypy
+        # for x in self._mapping._keys():
+        for x in self._mapping:
+            yield x
+
+
+class CommentedMapItemsView(CommentedMapView, Set):  # type: ignore
+    __slots__ = ()
+
+    @classmethod
+    def _from_iterable(self, it: Any) -> Any:
+        return set(it)
+
+    def __contains__(self, item: Any) -> Any:
+        key, value = item
+        try:
+            v = self._mapping[key]
+        except KeyError:
+            return False
+        else:
+            return v == value
+
+    def __iter__(self) -> Any:
+        for key in self._mapping._keys():
+            yield (key, self._mapping[key])
+
+
+class CommentedMapValuesView(CommentedMapView):
+    __slots__ = ()
+
+    def __contains__(self, value: Any) -> Any:
+        for key in self._mapping:
+            if value == self._mapping[key]:
+                return True
+        return False
+
+    def __iter__(self) -> Any:
+        for key in self._mapping._keys():
+            yield self._mapping[key]
+
+
+class CommentedMap(ordereddict, CommentedBase):
+    __slots__ = (Comment.attrib, '_ok', '_ref')
+
+    def __init__(self, *args: Any, **kw: Any) -> None:
+        self._ok: MutableSet[Any] = set()  # own keys
+        self._ref: List[CommentedMap] = []
+        ordereddict.__init__(self, *args, **kw)
+
+    def _yaml_add_comment(
+        self, comment: Any, key: Optional[Any] = NotNone, value: Optional[Any] = NotNone,
+    ) -> None:
+        """values is set to key to indicate a value attachment of comment"""
+        if key is not NotNone:
+            self.yaml_key_comment_extend(key, comment)
+            return
+        if value is not NotNone:
+            self.yaml_value_comment_extend(value, comment)
+        else:
+            self.ca.comment = comment
+
+    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
+        """add on the value line, with value specified by the key"""
+        self._yaml_add_comment(comment, value=key)
+
+    def _yaml_get_columnX(self, key: Any) -> Any:
+        return self.ca.items[key][2].start_mark.column
+
+    def _yaml_get_column(self, key: Any) -> Any:
+        column = None
+        sel_idx = None
+        pre, post, last = None, None, None
+        for x in self:
+            if pre is not None and x != key:
+                post = x
+                break
+            if x == key:
+                pre = last
+            last = x
+        if pre in self.ca.items:
+            sel_idx = pre
+        elif post in self.ca.items:
+            sel_idx = post
+        else:
+            # self.ca.items is not ordered
+            for k1 in self:
+                if k1 >= key:
+                    break
+                if k1 not in self.ca.items:
+                    continue
+                sel_idx = k1
+        if sel_idx is not None:
+            column = self._yaml_get_columnX(sel_idx)
+        return column
+
+    def _yaml_get_pre_comment(self) -> Any:
+        pre_comments: List[Any] = []
+        if self.ca.comment is None:
+            self.ca.comment = [None, pre_comments]
+        else:
+            pre_comments = self.ca.comment[1]
+        return pre_comments
+
+    def _yaml_clear_pre_comment(self) -> Any:
+        pre_comments: List[Any] = []
+        if self.ca.comment is None:
+            self.ca.comment = [None, pre_comments]
+        else:
+            self.ca.comment[1] = pre_comments
+        return pre_comments
+
+    def update(self, *vals: Any, **kw: Any) -> None:
+        try:
+            ordereddict.update(self, *vals, **kw)
+        except TypeError:
+            # probably a dict that is used
+            for x in vals[0]:
+                self[x] = vals[0][x]
+        if vals:
+            try:
+                self._ok.update(vals[0].keys())  # type: ignore
+            except AttributeError:
+                # assume one argument that is a list/tuple of two element lists/tuples
+                for x in vals[0]:
+                    self._ok.add(x[0])
+        if kw:
+            self._ok.update(*kw.keys())  # type: ignore
+
+    def insert(self, pos: Any, key: Any, value: Any, comment: Optional[Any] = None) -> None:
+        """insert key value into given position, as defined by source YAML
+        attach comment if provided
+        """
+        if key in self._ok:
+            del self[key]
+        keys = [k for k in self.keys() if k in self._ok]
+        try:
+            merge_value = getattr(self, merge_attrib)
+            merge_pos = merge_value.merge_pos
+        except (AttributeError, IndexError):
+            merge_pos = -1
+        if merge_pos >= 0:
+            if merge_pos >= pos:
+                # getattr(self, merge_attrib)[0] = (merge_pos + 1, ma0[1])
+                merge_value.merge_pos += 1
+                idx_min = pos
+                idx_max = len(self._ok)
+            else:
+                idx_min = pos - 1
+                idx_max = len(self._ok)
+        else:
+            idx_min = pos
+            idx_max = len(self._ok)
+        self[key] = value  # at the end
+        # print(f'{idx_min=} {idx_max=}')
+        for idx in range(idx_min, idx_max):
+            self.move_to_end(keys[idx])
+        self._ok.add(key)
+        # for referer in self._ref:
+        #     for keytmp in keys:
+        #         referer.update_key_value(keytmp)
+        if comment is not None:
+            self.yaml_add_eol_comment(comment, key=key)
+
+    def mlget(self, key: Any, default: Any = None, list_ok: Any = False) -> Any:
+        """multi-level get that expects dicts within dicts"""
+        if not isinstance(key, list):
+            return self.get(key, default)
+        # assume that the key is a list of recursively accessible dicts
+
+        def get_one_level(key_list: Any, level: Any, d: Any) -> Any:
+            if not list_ok:
+                assert isinstance(d, dict)
+            if level >= len(key_list):
+                if level > len(key_list):
+                    raise IndexError
+                return d[key_list[level - 1]]
+            return get_one_level(key_list, level + 1, d[key_list[level - 1]])
+
+        try:
+            return get_one_level(key, 1, self)
+        except KeyError:
+            return default
+        except (TypeError, IndexError):
+            if not list_ok:
+                raise
+            return default
+
+    def __getitem__(self, key: Any) -> Any:
+        try:
+            return ordereddict.__getitem__(self, key)
+        except KeyError:
+            for merged in getattr(self, merge_attrib, []):
+                # if isinstance(merged, tuple):
+                #     if key in merged[1]:
+                #         return merged[1][key]
+                # else:
+                if True:
+                    if key in merged:
+                        return merged[key]
+            raise
+
+    def __setitem__(self, key: Any, value: Any) -> None:
+        # try to preserve the scalarstring type if setting an existing key to a new value
+        if key in self:
+            if (
+                isinstance(value, str)
+                and not isinstance(value, ScalarString)
+                and isinstance(self[key], ScalarString)
+            ):
+                value = type(self[key])(value)
+        ordereddict.__setitem__(self, key, value)
+        self._ok.add(key)
+
+    def _unmerged_contains(self, key: Any) -> Any:
+        if key in self._ok:
+            return True
+        return None
+
+    def __contains__(self, key: Any) -> bool:
+        return bool(ordereddict.__contains__(self, key))
+
+    def get(self, key: Any, default: Any = None) -> Any:
+        try:
+            return self.__getitem__(key)
+        except:  # NOQA
+            return default
+
+    def __repr__(self) -> Any:
+        res = '{'
+        sep = ''
+        for k, v in self.items():
+            res += f'{sep}{k!r}: {v!r}'
+            if not sep:
+                sep = ', '
+        res += '}'
+        return res
+
+    def non_merged_items(self) -> Any:
+        for x in ordereddict.__iter__(self):
+            if x in self._ok:
+                yield x, ordereddict.__getitem__(self, x)
+
+    def __delitem__(self, key: Any) -> None:
+        # for merged in getattr(self, merge_attrib, []):
+        #     if key in merged[1]:
+        #         value = merged[1][key]
+        #         break
+        # else:
+        #     # not found in merged in stuff
+        #     ordereddict.__delitem__(self, key)
+        #    for referer in self._ref:
+        #        referer.update=_key_value(key)
+        #    return
+        #
+        # ordereddict.__setitem__(self, key, value)  # merge might have different value
+        # self._ok.discard(key)
+
+        try:
+            merge_value = getattr(self, merge_attrib)
+            merge_pos = merge_value.merge_pos
+        except AttributeError:
+            merge_pos = -1
+        if merge_pos >= 0:
+            try:
+                pos = list(ordereddict.keys(self)).index(key)
+                # the merge is not in the dict, so don't use >=
+                if merge_pos > pos:
+                    merge_value.merge_pos -= 1
+            except ValueError:
+                pass  # let the removal of the key throw a "normal" error
+        self._ok.discard(key)
+        ordereddict.__delitem__(self, key)
+        for referer in self._ref:
+            referer.update_key_value(key)
+
+    def __iter__(self) -> Any:
+        for x in ordereddict.__iter__(self):
+            yield x
+
+    def pop(self, key: Any, default: Any = NotNone) -> Any:
+        try:
+            result = self[key]
+        except KeyError:
+            if default is NotNone:
+                raise
+            return default
+        del self[key]
+        return result
+
+    def _keys(self) -> Any:
+        for x in ordereddict.__iter__(self):
+            yield x
+
+    def __len__(self) -> int:
+        return int(ordereddict.__len__(self))
+
+    def __eq__(self, other: Any) -> bool:
+        return bool(dict(self) == other)
+
+    def keys(self) -> Any:
+        return CommentedMapKeysView(self)
+
+    def values(self) -> Any:
+        return CommentedMapValuesView(self)
+
+    def _items(self) -> Any:
+        for x in ordereddict.__iter__(self):
+            yield x, ordereddict.__getitem__(self, x)
+
+    def items(self) -> Any:
+        return CommentedMapItemsView(self)
+
+    @property
+    def merge(self) -> Any:
+        if not hasattr(self, merge_attrib):
+            setattr(self, merge_attrib, [])
+        return getattr(self, merge_attrib)
+
+    def copy(self) -> Any:
+        x = type(self)()  # update doesn't work
+        for k, v in self._items():
+            x[k] = v
+        self.copy_attributes(x)
+        return x
+
+    def add_referent(self, cm: Any) -> None:
+        if cm not in self._ref:
+            self._ref.append(cm)
+
+    def add_yaml_merge(self, value: Any) -> None:
+        assert not hasattr(self, merge_attrib)
+        setattr(self, merge_attrib, value)
+        for v in value:
+            # if isinstance(v, tuple):
+            #     assert len(v) == 2
+            #     # print('vvv', v, type(v[1]))
+            #     v[1].add_referent(self)
+            #     for k1, v1 in v[1].items():
+            #         if ordereddict.__contains__(self, k1):
+            #             continue
+            #         ordereddict.__setitem__(self, k1, v1)
+            # else:
+            if True:
+                v.add_referent(self)
+                for k1, v1 in v.items():
+                    if ordereddict.__contains__(self, k1):
+                        continue
+                    ordereddict.__setitem__(self, k1, v1)
+
+    def update_key_value(self, key: Any) -> None:
+        if key in self._ok:
+            return
+        for v in self.merge:
+            if key in v[1]:
+                ordereddict.__setitem__(self, key, v[1][key])
+                return
+        ordereddict.__delitem__(self, key)
+
+    def __deepcopy__(self, memo: Any) -> Any:
+        res = self.__class__()
+        memo[id(self)] = res
+        for k in self:
+            res[k] = copy.deepcopy(self[k], memo)
+        self.copy_attributes(res, memo=memo)
+        return res
+
+
+# based on brownie mappings
+@classmethod  # type: ignore
+def raise_immutable(cls: Any, *args: Any, **kwargs: Any) -> None:
+    raise TypeError(f'{cls.__name__} objects are immutable')
+
+
+class CommentedKeyMap(CommentedBase, Mapping):  # type: ignore
+    __slots__ = Comment.attrib, '_od'
+    """This primarily exists to be able to roundtrip keys that are mappings"""
+
+    def __init__(self, *args: Any, **kw: Any) -> None:
+        if hasattr(self, '_od'):
+            raise_immutable(self)
+        try:
+            self._od = ordereddict(*args, **kw)
+        except TypeError:
+            raise
+
+    __delitem__ = __setitem__ = clear = pop = popitem = setdefault = update = raise_immutable
+
+    # need to implement __getitem__, __iter__ and __len__
+    def __getitem__(self, index: Any) -> Any:
+        return self._od[index]
+
+    def __iter__(self) -> Iterator[Any]:
+        for x in self._od.__iter__():
+            yield x
+
+    def __len__(self) -> int:
+        return len(self._od)
+
+    def __hash__(self) -> Any:
+        return hash(tuple(self.items()))
+
+    def __repr__(self) -> Any:
+        if not hasattr(self, merge_attrib):
+            return self._od.__repr__()
+        return 'ordereddict(' + repr(list(self._od.items())) + ')'
+
+    @classmethod
+    def fromkeys(keys: Any, v: Any = None) -> Any:
+        return CommentedKeyMap(dict.fromkeys(keys, v))
+
+    def _yaml_add_comment(self, comment: Any, key: Optional[Any] = NotNone) -> None:
+        if key is not NotNone:
+            self.yaml_key_comment_extend(key, comment)
+        else:
+            self.ca.comment = comment
+
+    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
+        self._yaml_add_comment(comment, key=key)
+
+    def _yaml_get_columnX(self, key: Any) -> Any:
+        return self.ca.items[key][0].start_mark.column
+
+    def _yaml_get_column(self, key: Any) -> Any:
+        column = None
+        sel_idx = None
+        pre, post = key - 1, key + 1
+        if pre in self.ca.items:
+            sel_idx = pre
+        elif post in self.ca.items:
+            sel_idx = post
+        else:
+            # self.ca.items is not ordered
+            for row_idx, _k1 in enumerate(self):
+                if row_idx >= key:
+                    break
+                if row_idx not in self.ca.items:
+                    continue
+                sel_idx = row_idx
+        if sel_idx is not None:
+            column = self._yaml_get_columnX(sel_idx)
+        return column
+
+    def _yaml_get_pre_comment(self) -> Any:
+        pre_comments: List[Any] = []
+        if self.ca.comment is None:
+            self.ca.comment = [None, pre_comments]
+        else:
+            self.ca.comment[1] = pre_comments
+        return pre_comments
+
+
+class CommentedOrderedMap(CommentedMap):
+    __slots__ = (Comment.attrib,)
+
+
+class CommentedSet(MutableSet, CommentedBase):  # type: ignore  # NOQA
+    __slots__ = Comment.attrib, 'odict'
+
+    def __init__(self, values: Any = None) -> None:
+        self.odict = ordereddict()
+        MutableSet.__init__(self)
+        if values is not None:
+            self |= values
+
+    def _yaml_add_comment(
+        self, comment: Any, key: Optional[Any] = NotNone, value: Optional[Any] = NotNone,
+    ) -> None:
+        """values is set to key to indicate a value attachment of comment"""
+        if key is not NotNone:
+            self.yaml_key_comment_extend(key, comment)
+            return
+        if value is not NotNone:
+            self.yaml_value_comment_extend(value, comment)
+        else:
+            self.ca.comment = comment
+
+    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
+        """add on the value line, with value specified by the key"""
+        self._yaml_add_comment(comment, value=key)
+
+    def add(self, value: Any) -> None:
+        """Add an element."""
+        self.odict[value] = None
+
+    def discard(self, value: Any) -> None:
+        """Remove an element.  Do not raise an exception if absent."""
+        del self.odict[value]
+
+    def __contains__(self, x: Any) -> Any:
+        return x in self.odict
+
+    def __iter__(self) -> Any:
+        for x in self.odict:
+            yield x
+
+    def __len__(self) -> int:
+        return len(self.odict)
+
+    def __repr__(self) -> str:
+        return f'set({self.odict.keys()!r})'
+
+
+class TaggedScalar(CommentedBase):
+    # the value and style attributes are set during roundtrip construction
+    def __init__(self, value: Any = None, style: Any = None, tag: Any = None) -> None:
+        self.value = value
+        self.style = style
+        if tag is not None:
+            if isinstance(tag, str):
+                tag = Tag(suffix=tag)
+            self.yaml_set_ctag(tag)
+
+    def __str__(self) -> Any:
+        return self.value
+
+    def count(self, s: str, start: Optional[int] = None, end: Optional[int] = None) -> Any:
+        return self.value.count(s, start, end)
+
+    def __getitem__(self, pos: int) -> Any:
+        return self.value[pos]
+
+    def __repr__(self) -> str:
+        return f'TaggedScalar(value={self.value!r}, style={self.style!r}, tag={self.tag!r})'
+
+
+def dump_comments(d: Any, name: str = "", sep: str = '.', out: Any = sys.stdout) -> None:
+    """
+    recursively dump comments, all but the toplevel preceded by the path
+    in dotted form x.0.a
+    """
+    if isinstance(d, dict) and hasattr(d, 'ca'):
+        if name:
+            out.write(f'{name} {type(d)}\n')
+        out.write(f'{d.ca!r}\n')
+        for k in d:
+            dump_comments(d[k], name=(name + sep + str(k)) if name else k, sep=sep, out=out)
+    elif isinstance(d, list) and hasattr(d, 'ca'):
+        if name:
+            out.write(f'{name} {type(d)}\n')
+        out.write(f'{d.ca!r}\n')
+        for idx, k in enumerate(d):
+            dump_comments(
+                k, name=(name + sep + str(idx)) if name else str(idx), sep=sep, out=out,
+            )
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py
new file mode 100644
index 00000000000..3dfbdbe39bd
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py
@@ -0,0 +1,236 @@
+
+from __future__ import annotations
+
+# partially from package six by Benjamin Peterson
+
+import sys
+import os
+import io
+from abc import abstractmethod
+import collections.abc
+
+
+from opentelemetry.agent._vendor.ruamel.yaml.docinfo import Version  # NOQA
+# fmt: off
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Union, BinaryIO, IO, Text, Tuple  # NOQA
+    from typing import Optional  # NOQA
+    try:
+        from typing import SupportsIndex as SupportsIndex  # in order to reexport for mypy
+    except ImportError:
+        SupportsIndex = int  # type: ignore
+
+    StreamType = Any
+    StreamTextType = StreamType
+    VersionType = Union[str , Tuple[int, int] , List[int] , Version , None]
+# fmt: on
+
+_DEFAULT_YAML_VERSION = (1, 2)
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict  # type: ignore
+
+    # to get the right name import ... as ordereddict doesn't do that
+
+
+class ordereddict(OrderedDict):  # type: ignore
+    if not hasattr(OrderedDict, 'insert'):
+
+        def insert(self, pos: int, key: Any, value: Any) -> None:
+            if pos >= len(self):
+                self[key] = value
+                return
+            od = ordereddict()
+            od.update(self)
+            for k in od:
+                del self[k]
+            for index, old_key in enumerate(od):
+                if pos == index:
+                    self[key] = value
+                self[old_key] = od[old_key]
+
+
+StringIO = io.StringIO
+BytesIO = io.BytesIO
+
+
+builtins_module = 'builtins'
+
+
+def with_metaclass(meta: Any, *bases: Any) -> Any:
+    """Create a base class with a metaclass."""
+    return meta('NewBase', bases, {})
+
+
+DBG_TOKEN = 1
+DBG_EVENT = 2
+DBG_NODE = 4
+
+
+_debug: Optional[int] = None
+if 'RUAMEL_DEBUG' in os.environ:
+    _debugx = os.environ.get('RUAMEL_DEBUG')
+    if _debugx is None:
+        _debug = 0
+    else:
+        _debug = int(_debugx)
+
+
+if bool(_debug):
+
+    class ObjectCounter:
+        def __init__(self) -> None:
+            self.map: Dict[Any, Any] = {}
+
+        def __call__(self, k: Any) -> None:
+            self.map[k] = self.map.get(k, 0) + 1
+
+        def dump(self) -> None:
+            for k in sorted(self.map):
+                sys.stdout.write(f'{k} -> {self.map[k]}')
+
+    object_counter = ObjectCounter()
+
+
+# used from yaml util when testing
+def dbg(val: Any = None) -> Any:
+    debug = _debug
+    if debug is None:
+        # set to true or false
+        _debugx = os.environ.get('YAMLDEBUG')
+        if _debugx is None:
+            debug = 0
+        else:
+            debug = int(_debugx)
+    if val is None:
+        return debug
+    return debug & val
+
+
+class Nprint:
+    def __init__(self, file_name: Any = None) -> None:
+        self._max_print: Any = None
+        self._count: Any = None
+        self._file_name = file_name
+
+    def __call__(self, *args: Any, **kw: Any) -> None:
+        if not bool(_debug):
+            return
+        import traceback
+
+        out = sys.stdout if self._file_name is None else open(self._file_name, 'a')
+        dbgprint = print  # to fool checking for print statements by dv utility
+        kw1 = kw.copy()
+        kw1['file'] = out
+        dbgprint(*args, **kw1)
+        out.flush()
+        if self._max_print is not None:
+            if self._count is None:
+                self._count = self._max_print
+            self._count -= 1
+            if self._count == 0:
+                dbgprint('forced exit\n')
+                traceback.print_stack()
+                out.flush()
+                sys.exit(0)
+        if self._file_name:
+            out.close()
+
+    def set_max_print(self, i: int) -> None:
+        self._max_print = i
+        self._count = None
+
+    def fp(self, mode: str = 'a') -> Any:
+        out = sys.stdout if self._file_name is None else open(self._file_name, mode)
+        return out
+
+
+nprint = Nprint()
+nprintf = Nprint('/var/tmp/ruamel.yaml.log')
+
+# char checkers following production rules
+
+
+def check_namespace_char(ch: Any) -> bool:
+    if '\x21' <= ch <= '\x7E':  # ! to ~
+        return True
+    if '\xA0' <= ch <= '\uD7FF':
+        return True
+    if ('\uE000' <= ch <= '\uFFFD') and ch != '\uFEFF':  # excl. byte order mark
+        return True
+    if '\U00010000' <= ch <= '\U0010FFFF':
+        return True
+    return False
+
+
+def check_anchorname_char(ch: Any) -> bool:
+    if ch in ',[]{}':
+        return False
+    return check_namespace_char(ch)
+
+
+def version_tnf(t1: Any, t2: Any = None) -> Any:
+    """
+    return True if ruamel.yaml version_info < t1, None if t2 is specified and bigger else False
+    """
+    from opentelemetry.agent._vendor.ruamel.yaml import version_info  # NOQA
+
+    if version_info < t1:
+        return True
+    if t2 is not None and version_info < t2:
+        return None
+    return False
+
+
+class MutableSliceableSequence(collections.abc.MutableSequence):  # type: ignore
+    __slots__ = ()
+
+    def __getitem__(self, index: Any) -> Any:
+        if not isinstance(index, slice):
+            return self.__getsingleitem__(index)
+        return type(self)([self[i] for i in range(*index.indices(len(self)))])  # type: ignore
+
+    def __setitem__(self, index: Any, value: Any) -> None:
+        if not isinstance(index, slice):
+            return self.__setsingleitem__(index, value)
+        assert iter(value)
+        # nprint(index.start, index.stop, index.step, index.indices(len(self)))
+        if index.step is None:
+            del self[index.start : index.stop]
+            for elem in reversed(value):
+                self.insert(0 if index.start is None else index.start, elem)
+        else:
+            range_parms = index.indices(len(self))
+            nr_assigned_items = (range_parms[1] - range_parms[0] - 1) // range_parms[2] + 1
+            # need to test before changing, in case TypeError is caught
+            if nr_assigned_items < len(value):
+                raise TypeError(
+                    f'too many elements in value {nr_assigned_items} < {len(value)}',
+                )
+            elif nr_assigned_items > len(value):
+                raise TypeError(
+                    f'not enough elements in value {nr_assigned_items} > {len(value)}',
+                )
+            for idx, i in enumerate(range(*range_parms)):
+                self[i] = value[idx]
+
+    def __delitem__(self, index: Any) -> None:
+        if not isinstance(index, slice):
+            return self.__delsingleitem__(index)
+        # nprint(index.start, index.stop, index.step, index.indices(len(self)))
+        for i in reversed(range(*index.indices(len(self)))):
+            del self[i]
+
+    @abstractmethod
+    def __getsingleitem__(self, index: Any) -> Any:
+        raise IndexError
+
+    @abstractmethod
+    def __setsingleitem__(self, index: Any, value: Any) -> None:
+        raise IndexError
+
+    @abstractmethod
+    def __delsingleitem__(self, index: Any) -> None:
+        raise IndexError
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py
new file mode 100644
index 00000000000..d60de8f42e5
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py
@@ -0,0 +1,246 @@
+
+from __future__ import annotations
+
+import warnings
+
+from opentelemetry.agent._vendor.ruamel.yaml.error import MarkedYAMLError, ReusedAnchorWarning
+from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, nprintf  # NOQA
+
+from opentelemetry.agent._vendor.ruamel.yaml.events import (
+    StreamStartEvent,
+    StreamEndEvent,
+    MappingStartEvent,
+    MappingEndEvent,
+    SequenceStartEvent,
+    SequenceEndEvent,
+    AliasEvent,
+    ScalarEvent,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List  # NOQA
+
+__all__ = ['Composer', 'ComposerError', 'MaxDepthExceededError']
+
+
+class ComposerError(MarkedYAMLError):
+    pass
+
+
+class MaxDepthExceededError(MarkedYAMLError):
+    pass
+
+
+class Composer:
+    def __init__(self, loader: Any = None) -> None:
+        self.loader = loader
+        if self.loader is not None and getattr(self.loader, '_composer', None) is None:
+            self.loader._composer = self
+        self.anchors: Dict[Any, Any] = {}
+        self.warn_double_anchors = True
+        self.depth = 0
+
+    @property
+    def parser(self) -> Any:
+        if hasattr(self.loader, 'typ'):
+            self.loader.parser
+        return self.loader._parser
+
+    @property
+    def resolver(self) -> Any:
+        # assert self.loader._resolver is not None
+        if hasattr(self.loader, 'typ'):
+            self.loader.resolver
+        return self.loader._resolver
+
+    def check_node(self) -> Any:
+        # Drop the STREAM-START event.
+        if self.parser.check_event(StreamStartEvent):
+            self.parser.get_event()
+
+        # If there are more documents available?
+        return not self.parser.check_event(StreamEndEvent)
+
+    def get_node(self) -> Any:
+        # Get the root node of the next document.
+        if not self.parser.check_event(StreamEndEvent):
+            return self.compose_document()
+
+    def get_single_node(self) -> Any:
+        # Drop the STREAM-START event.
+        self.parser.get_event()
+
+        # Compose a document if the stream is not empty.
+        document: Any = None
+        if not self.parser.check_event(StreamEndEvent):
+            document = self.compose_document()
+
+        # Ensure that the stream contains no more documents.
+        if not self.parser.check_event(StreamEndEvent):
+            event = self.parser.get_event()
+            raise ComposerError(
+                'expected a single document in the stream',
+                document.start_mark,
+                'but found another document',
+                event.start_mark,
+            )
+
+        # Drop the STREAM-END event.
+        self.parser.get_event()
+
+        return document
+
+    def compose_document(self: Any) -> Any:
+        self.anchors = {}
+        # Drop the DOCUMENT-START event.
+        self.parser.get_event()
+
+        # Compose the root node.
+        node = self.compose_node(None, None)
+
+        # Drop the DOCUMENT-END event.
+        self.parser.get_event()
+
+        return node
+
+    def return_alias(self, a: Any) -> Any:
+        return a
+
+    def compose_node(self, parent: Any, index: Any) -> Any:
+        if self.parser.check_event(AliasEvent):
+            event = self.parser.get_event()
+            alias = event.anchor
+            if alias not in self.anchors:
+                raise ComposerError(
+                    None, None, f'found undefined alias {alias!r}', event.start_mark,
+                )
+            return self.return_alias(self.anchors[alias])
+        self.depth += 1
+        event = self.parser.peek_event()
+        if self.loader.max_depth and self.depth > self.loader.max_depth:
+            raise MaxDepthExceededError(
+                None,
+                None,
+                f'maximum depth of data structure exceeded ({self.depth}), '
+                'if necessary increase YAML().max_depth',
+                event.start_mark,
+            )
+        anchor = event.anchor
+        if anchor is not None:  # have an anchor
+            if self.warn_double_anchors and anchor in self.anchors:
+                ws = (
+                    f'\nfound duplicate anchor {anchor!r}\n'
+                    f'first occurrence {self.anchors[anchor].start_mark}\n'
+                    f'second occurrence {event.start_mark}'
+                )
+                warnings.warn(ws, ReusedAnchorWarning, stacklevel=2)
+        self.resolver.descend_resolver(parent, index)
+        if self.parser.check_event(ScalarEvent):
+            node = self.compose_scalar_node(anchor)
+        elif self.parser.check_event(SequenceStartEvent):
+            node = self.compose_sequence_node(anchor)
+        elif self.parser.check_event(MappingStartEvent):
+            node = self.compose_mapping_node(anchor)
+        self.resolver.ascend_resolver()
+        self.depth -= 1
+        return node
+
+    def compose_scalar_node(self, anchor: Any) -> Any:
+        event = self.parser.get_event()
+        tag = event.ctag
+        if tag is None or str(tag) == '!':
+            tag = self.resolver.resolve(ScalarNode, event.value, event.implicit)
+            assert not isinstance(tag, str)
+            # e.g tag.yaml.org,2002:str
+        node = ScalarNode(
+            tag,
+            event.value,
+            event.start_mark,
+            event.end_mark,
+            style=event.style,
+            comment=event.comment,
+            anchor=anchor,
+        )
+        if anchor is not None:
+            self.anchors[anchor] = node
+        return node
+
+    def compose_sequence_node(self, anchor: Any) -> Any:
+        start_event = self.parser.get_event()
+        tag = start_event.ctag
+        if tag is None or str(tag) == '!':
+            tag = self.resolver.resolve(SequenceNode, None, start_event.implicit)
+            assert not isinstance(tag, str)
+        node = SequenceNode(
+            tag,
+            [],
+            start_event.start_mark,
+            None,
+            flow_style=start_event.flow_style,
+            comment=start_event.comment,
+            anchor=anchor,
+        )
+        if anchor is not None:
+            self.anchors[anchor] = node
+        index = 0
+        while not self.parser.check_event(SequenceEndEvent):
+            node.value.append(self.compose_node(node, index))
+            index += 1
+        end_event = self.parser.get_event()
+        if node.flow_style is True and end_event.comment is not None:
+            if node.comment is not None:
+                x = node.flow_style
+                nprint(
+                    f'Warning: unexpected end_event commment in sequence node {x}\n',
+                    '    if possible, please report an issue with reproducable data/code',
+                )
+            node.comment = end_event.comment
+        node.end_mark = end_event.end_mark
+        self.check_end_doc_comment(end_event, node)
+        return node
+
+    def compose_mapping_node(self, anchor: Any) -> Any:
+        start_event = self.parser.get_event()
+        tag = start_event.ctag
+        if tag is None or str(tag) == '!':
+            tag = self.resolver.resolve(MappingNode, None, start_event.implicit)
+            assert not isinstance(tag, str)
+        node = MappingNode(
+            tag,
+            [],
+            start_event.start_mark,
+            None,
+            flow_style=start_event.flow_style,
+            comment=start_event.comment,
+            anchor=anchor,
+        )
+        if anchor is not None:
+            self.anchors[anchor] = node
+        while not self.parser.check_event(MappingEndEvent):
+            # key_event = self.parser.peek_event()
+            item_key = self.compose_node(node, None)
+            # if item_key in node.value:
+            #     raise ComposerError("while composing a mapping",
+            #             start_event.start_mark,
+            #             "found duplicate key", key_event.start_mark)
+            item_value = self.compose_node(node, item_key)
+            # node.value[item_key] = item_value
+            node.value.append((item_key, item_value))
+        end_event = self.parser.get_event()
+        if node.flow_style is True and end_event.comment is not None:
+            node.comment = end_event.comment
+        node.end_mark = end_event.end_mark
+        self.check_end_doc_comment(end_event, node)
+        return node
+
+    def check_end_doc_comment(self, end_event: Any, node: Any) -> None:
+        if end_event.comment and end_event.comment[1]:
+            # pre comments on an end_event, no following to move to
+            if node.comment is None:
+                node.comment = [None, None]
+            assert not isinstance(node, ScalarEvent)
+            # this is a post comment on a mapping node, add as third element
+            # in the list
+            node.comment.append(end_event.comment[1])
+            end_event.comment[1] = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py
new file mode 100644
index 00000000000..0b6de66d1fb
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py
@@ -0,0 +1,17 @@
+
+from __future__ import annotations
+
+import warnings
+
+from opentelemetry.agent._vendor.ruamel.yaml.util import configobj_walker as new_configobj_walker
+
+if False:  # MYPY
+    from typing import Any
+
+
+def configobj_walker(cfg: Any) -> Any:
+    warnings.warn(
+        'configobj_walker has moved to ruamel.yaml.util, please update your code',
+        stacklevel=2,
+    )
+    return new_configobj_walker(cfg)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py
new file mode 100644
index 00000000000..b20ae25d56a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py
@@ -0,0 +1,1724 @@
+
+from __future__ import annotations
+
+import datetime
+from datetime import timedelta as TimeDelta
+import binascii
+import sys
+import types
+import warnings
+from collections.abc import Hashable, MutableSequence, MutableMapping
+
+# fmt: off
+from opentelemetry.agent._vendor.ruamel.yaml.error import (MarkedYAMLError, MarkedYAMLFutureWarning,
+                               MantissaNoDotYAML1_1Warning)
+from opentelemetry.agent._vendor.ruamel.yaml.nodes import *                               # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.nodes import (SequenceNode, MappingNode, ScalarNode)
+from opentelemetry.agent._vendor.ruamel.yaml.compat import (builtins_module, # NOQA
+                                nprint, nprintf, version_tnf)
+from opentelemetry.agent._vendor.ruamel.yaml.compat import ordereddict
+
+from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
+from opentelemetry.agent._vendor.ruamel.yaml.comments import *                               # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.comments import (CommentedMap, CommentedOrderedMap, CommentedSet,
+                                  CommentedKeySeq, CommentedSeq, TaggedScalar,
+                                  CommentedKeyMap,
+                                  C_KEY_PRE, C_KEY_EOL, C_KEY_POST,
+                                  C_VALUE_PRE, C_VALUE_EOL, C_VALUE_POST,
+                                  )
+from opentelemetry.agent._vendor.ruamel.yaml.scalarstring import (SingleQuotedScalarString, DoubleQuotedScalarString,
+                                      LiteralScalarString, FoldedScalarString,
+                                      PlainScalarString, ScalarString)
+from opentelemetry.agent._vendor.ruamel.yaml.scalarint import ScalarInt, BinaryInt, OctalInt, HexInt, HexCapsInt
+from opentelemetry.agent._vendor.ruamel.yaml.scalarfloat import ScalarFloat
+from opentelemetry.agent._vendor.ruamel.yaml.scalarbool import ScalarBoolean
+from opentelemetry.agent._vendor.ruamel.yaml.timestamp import TimeStamp
+from opentelemetry.agent._vendor.ruamel.yaml.util import timestamp_regexp, create_timestamp
+
+if False:  # MYPY
+    from typing import Any, Dict, List, Set, Iterator, Union, Optional  # NOQA
+
+
+__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
+           'ConstructorError', 'RoundTripConstructor']
+# fmt: on
+
+
+class ConstructorError(MarkedYAMLError):
+    pass
+
+
+class DuplicateKeyFutureWarning(MarkedYAMLFutureWarning):
+    pass
+
+
+DUPKEY_URL = 'https://yaml.dev/doc/ruamel.yaml/api/#Duplicate_keys'
+
+
+class DuplicateKeyError(MarkedYAMLError):
+    pass
+
+
+class BaseConstructor:
+
+    yaml_constructors = {}  # type: Dict[Any, Any]
+    yaml_multi_constructors = {}  # type: Dict[Any, Any]
+
+    def __init__(self, preserve_quotes: Optional[bool] = None, loader: Any = None) -> None:
+        self.loader = loader
+        if self.loader is not None and getattr(self.loader, '_constructor', None) is None:
+            self.loader._constructor = self
+        self.loader = loader
+        self.yaml_base_dict_type = dict
+        self.yaml_base_list_type = list
+        self.constructed_objects: Dict[Any, Any] = {}
+        self.recursive_objects: Dict[Any, Any] = {}
+        self.state_generators: List[Any] = []
+        self.deep_construct = False
+        self._preserve_quotes = preserve_quotes
+        self.allow_duplicate_keys = version_tnf((0, 15, 1), (0, 16))
+
+    @property
+    def composer(self) -> Any:
+        if hasattr(self.loader, 'typ'):
+            return self.loader.composer
+        try:
+            return self.loader._composer
+        except AttributeError:
+            sys.stdout.write(f'slt {type(self)}\n')
+            sys.stdout.write(f'slc {self.loader._composer}\n')
+            sys.stdout.write(f'{dir(self)}\n')
+            raise
+
+    @property
+    def resolver(self) -> Any:
+        if hasattr(self.loader, 'typ'):
+            return self.loader.resolver
+        return self.loader._resolver
+
+    @property
+    def scanner(self) -> Any:
+        # needed to get to the expanded comments
+        if hasattr(self.loader, 'typ'):
+            return self.loader.scanner
+        return self.loader._scanner
+
+    def check_data(self) -> Any:
+        # If there are more documents available?
+        return self.composer.check_node()
+
+    def get_data(self) -> Any:
+        # Construct and return the next document.
+        if self.composer.check_node():
+            return self.construct_document(self.composer.get_node())
+
+    def get_single_data(self) -> Any:
+        # Ensure that the stream contains a single document and construct it.
+        node = self.composer.get_single_node()
+        if node is not None:
+            return self.construct_document(node)
+        return None
+
+    def construct_document(self, node: Any) -> Any:
+        data = self.construct_object(node)
+        while bool(self.state_generators):
+            state_generators = self.state_generators
+            self.state_generators = []
+            for generator in state_generators:
+                for _dummy in generator:
+                    pass
+        self.constructed_objects = {}
+        self.recursive_objects = {}
+        self.deep_construct = False
+        return data
+
+    def construct_object(self, node: Any, deep: bool = False) -> Any:
+        """deep is True when creating an object/mapping recursively,
+        in that case want the underlying elements available during construction
+        """
+        if node in self.constructed_objects:
+            return self.constructed_objects[node]
+        if deep:
+            old_deep = self.deep_construct
+            self.deep_construct = True
+        if node in self.recursive_objects:
+            return self.recursive_objects[node]
+            # raise ConstructorError(
+            #     None, None, 'found unconstructable recursive node', node.start_mark
+            # )
+        self.recursive_objects[node] = None
+        data = self.construct_non_recursive_object(node)
+
+        self.constructed_objects[node] = data
+        del self.recursive_objects[node]
+        if deep:
+            self.deep_construct = old_deep
+        return data
+
+    def construct_non_recursive_object(self, node: Any, tag: Optional[str] = None) -> Any:
+        constructor: Any = None
+        tag_suffix = None
+        if tag is None:
+            tag = node.tag
+        if tag in self.yaml_constructors:
+            constructor = self.yaml_constructors[tag]
+        else:
+            for tag_prefix in self.yaml_multi_constructors:
+                if tag.startswith(tag_prefix):
+                    tag_suffix = tag[len(tag_prefix) :]
+                    constructor = self.yaml_multi_constructors[tag_prefix]
+                    break
+            else:
+                if None in self.yaml_multi_constructors:
+                    tag_suffix = tag
+                    constructor = self.yaml_multi_constructors[None]
+                elif None in self.yaml_constructors:
+                    constructor = self.yaml_constructors[None]
+                elif isinstance(node, ScalarNode):
+                    constructor = self.__class__.construct_scalar
+                elif isinstance(node, SequenceNode):
+                    constructor = self.__class__.construct_sequence
+                elif isinstance(node, MappingNode):
+                    constructor = self.__class__.construct_mapping
+        if tag_suffix is None:
+            data = constructor(self, node)
+        else:
+            data = constructor(self, tag_suffix, node)
+        if isinstance(data, types.GeneratorType):
+            generator = data
+            data = next(generator)
+            if self.deep_construct:
+                for _dummy in generator:
+                    pass
+            else:
+                self.state_generators.append(generator)
+        return data
+
+    def construct_scalar(self, node: Any) -> Any:
+        if not isinstance(node, ScalarNode):
+            raise ConstructorError(
+                None, None, f'expected a scalar node, but found {node.id!s}', node.start_mark,
+            )
+        return node.value
+
+    def construct_sequence(self, node: Any, deep: bool = False) -> Any:
+        """deep is True when creating an object/mapping recursively,
+        in that case want the underlying elements available during construction
+        """
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError(
+                None,
+                None,
+                f'expected a sequence node, but found {node.id!s}',
+                node.start_mark,
+            )
+        return [self.construct_object(child, deep=deep) for child in node.value]
+
+    def construct_mapping(self, node: Any, deep: bool = False) -> Any:
+        """deep is True when creating an object/mapping recursively,
+        in that case want the underlying elements available during construction
+        """
+        if not isinstance(node, MappingNode):
+            raise ConstructorError(
+                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
+            )
+        total_mapping = self.yaml_base_dict_type()
+        if getattr(node, 'merge', None) is not None:
+            todo = [(node.merge, False), (node.value, False)]
+        else:
+            todo = [(node.value, True)]
+        for values, check in todo:
+            mapping: Dict[Any, Any] = self.yaml_base_dict_type()
+            for key_node, value_node in values:
+                # keys can be list -> deep
+                key = self.construct_object(key_node, deep=True)
+                # lists are not hashable, but tuples are
+                if not isinstance(key, Hashable):
+                    if isinstance(key, list):
+                        key = tuple(key)
+                if not isinstance(key, Hashable):
+                    raise ConstructorError(
+                        'while constructing a mapping',
+                        node.start_mark,
+                        'found unhashable key',
+                        key_node.start_mark,
+                    )
+
+                value = self.construct_object(value_node, deep=deep)
+                if check:
+                    if self.check_mapping_key(node, key_node, mapping, key, value):
+                        mapping[key] = value
+                else:
+                    mapping[key] = value
+            total_mapping.update(mapping)
+        return total_mapping
+
+    def check_mapping_key(
+        self, node: Any, key_node: Any, mapping: Any, key: Any, value: Any,
+    ) -> bool:
+        """return True if key is unique"""
+        if key in mapping:
+            if not self.allow_duplicate_keys:
+                mk = mapping.get(key)
+                args = [
+                    'while constructing a mapping',
+                    node.start_mark,
+                    f'found duplicate key "{key}" with value "{value}" '
+                    f'(original value: "{mk}")',
+                    key_node.start_mark,
+                    f"""
+                    To suppress this check see:
+                        {DUPKEY_URL}
+                    """,
+                    """\
+                    Duplicate keys will become an error in future releases, and are errors
+                    by default when using the new API.
+                    """,
+                ]
+                if self.allow_duplicate_keys is None:
+                    warnings.warn(DuplicateKeyFutureWarning(*args), stacklevel=1)
+                else:
+                    raise DuplicateKeyError(*args)
+            return False
+        return True
+
+    def check_set_key(self: Any, node: Any, key_node: Any, setting: Any, key: Any) -> None:
+        if key in setting:
+            if not self.allow_duplicate_keys:
+                args = [
+                    'while constructing a set',
+                    node.start_mark,
+                    f'found duplicate key "{key}"',
+                    key_node.start_mark,
+                    f"""
+                    To suppress this check see:
+                        {DUPKEY_URL}
+                    """,
+                    """\
+                    Duplicate keys will become an error in future releases, and are errors
+                    by default when using the new API.
+                    """,
+                ]
+                if self.allow_duplicate_keys is None:
+                    warnings.warn(DuplicateKeyFutureWarning(*args), stacklevel=1)
+                else:
+                    raise DuplicateKeyError(*args)
+
+    def construct_pairs(self, node: Any, deep: bool = False) -> Any:
+        if not isinstance(node, MappingNode):
+            raise ConstructorError(
+                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
+            )
+        pairs = []
+        for key_node, value_node in node.value:
+            key = self.construct_object(key_node, deep=deep)
+            value = self.construct_object(value_node, deep=deep)
+            pairs.append((key, value))
+        return pairs
+
+    # ToDo: putting stuff on the class makes it global, consider making this to work on an
+    # instance variable once function load is dropped.
+    @classmethod
+    def add_constructor(cls, tag: Any, constructor: Any) -> Any:
+        if isinstance(tag, Tag):
+            tag = str(tag)
+        if 'yaml_constructors' not in cls.__dict__:
+            cls.yaml_constructors = cls.yaml_constructors.copy()
+        ret_val = cls.yaml_constructors.get(tag, None)
+        cls.yaml_constructors[tag] = constructor
+        return ret_val
+
+    @classmethod
+    def add_multi_constructor(cls, tag_prefix: Any, multi_constructor: Any) -> None:
+        if 'yaml_multi_constructors' not in cls.__dict__:
+            cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
+        cls.yaml_multi_constructors[tag_prefix] = multi_constructor
+
+    @classmethod
+    def add_default_constructor(
+        cls, tag: str, method: Any = None, tag_base: str = 'tag:yaml.org,2002:',
+    ) -> None:
+        if not tag.startswith('tag:'):
+            if method is None:
+                method = 'construct_yaml_' + tag
+            tag = tag_base + tag
+        cls.add_constructor(tag, getattr(cls, method))
+
+
+class SafeConstructor(BaseConstructor):
+    def construct_scalar(self, node: Any) -> Any:
+        if isinstance(node, MappingNode):
+            for key_node, value_node in node.value:
+                if key_node.tag == 'tag:yaml.org,2002:value':
+                    return self.construct_scalar(value_node)
+        return BaseConstructor.construct_scalar(self, node)
+
+    def flatten_mapping(self, node: Any) -> Any:  # SafeConstructor
+        """
+        This implements the merge key feature http://yaml.org/type/merge.html
+        by inserting keys from the merge dict/list of dicts if not yet
+        available in this node
+        """
+        merge: List[Any] = []
+        index = 0
+        while index < len(node.value):
+            key_node, value_node = node.value[index]
+            if key_node.tag == 'tag:yaml.org,2002:merge':
+                if merge:  # double << key
+                    if self.allow_duplicate_keys:
+                        del node.value[index]
+                        index += 1
+                        continue
+                    args = [
+                        'while constructing a mapping',
+                        node.start_mark,
+                        'found duplicate merge key "<<"',
+                        key_node.start_mark,
+                        """\
+                        Duplicate merge keys are never allowed, not even when
+                        `.allow_duplicate_keys` is set to True
+                        """,
+                    ]
+                    raise DuplicateKeyError(*args)
+                del node.value[index]
+                if isinstance(value_node, MappingNode):
+                    self.flatten_mapping(value_node)
+                    merge.extend(value_node.value)
+                elif isinstance(value_node, SequenceNode):
+                    submerge = []
+                    for subnode in value_node.value:
+                        if not isinstance(subnode, MappingNode):
+                            raise ConstructorError(
+                                'while constructing a mapping',
+                                node.start_mark,
+                                f'expected a mapping for merging, but found {subnode.id!s}',
+                                subnode.start_mark,
+                            )
+                        self.flatten_mapping(subnode)
+                        submerge.append(subnode.value)
+                    submerge.reverse()
+                    for value in submerge:
+                        merge.extend(value)
+                else:
+                    raise ConstructorError(
+                        'while constructing a mapping',
+                        node.start_mark,
+                        'expected a mapping or list of mappings for merging, '
+                        f'but found {value_node.id!s}',
+                        value_node.start_mark,
+                    )
+            elif key_node.tag == 'tag:yaml.org,2002:value':
+                key_node.tag = 'tag:yaml.org,2002:str'
+                index += 1
+            else:
+                index += 1
+        if bool(merge):
+            node.merge = merge  # separate merge keys to be able to update without duplicate
+            node.value = merge + node.value
+
+    def construct_mapping(self, node: Any, deep: bool = False) -> Any:
+        """deep is True when creating an object/mapping recursively,
+        in that case want the underlying elements available during construction
+        """
+        if isinstance(node, MappingNode):
+            self.flatten_mapping(node)
+        return BaseConstructor.construct_mapping(self, node, deep=deep)
+
+    def construct_yaml_null(self, node: Any) -> Any:
+        self.construct_scalar(node)
+        return None
+
+    # YAML 1.2 spec doesn't mention yes/no etc any more, 1.1 does
+    bool_values = {
+        'yes': True,
+        'no': False,
+        'y': True,
+        'n': False,
+        'true': True,
+        'false': False,
+        'on': True,
+        'off': False,
+    }
+
+    def construct_yaml_bool(self, node: Any) -> bool:
+        value = self.construct_scalar(node)
+        return self.bool_values[value.lower()]
+
+    def construct_yaml_int(self, node: Any) -> int:
+        value_s = self.construct_scalar(node)
+        value_s = value_s.replace('_', "")
+        sign = +1
+        if value_s[0] == '-':
+            sign = -1
+        if value_s[0] in '+-':
+            value_s = value_s[1:]
+        if value_s == '0':
+            return 0
+        elif value_s.startswith('0b'):
+            return sign * int(value_s[2:], 2)
+        elif value_s.startswith('0x'):
+            return sign * int(value_s[2:], 16)
+        elif value_s.startswith('0o'):
+            return sign * int(value_s[2:], 8)
+        elif self.resolver.processing_version == (1, 1) and value_s[0] == '0':
+            return sign * int(value_s, 8)
+        elif self.resolver.processing_version == (1, 1) and ':' in value_s:
+            digits = [int(part) for part in value_s.split(':')]
+            digits.reverse()
+            base = 1
+            value = 0
+            for digit in digits:
+                value += digit * base
+                base *= 60
+            return sign * value
+        else:
+            return sign * int(value_s)
+
+    inf_value = 1e300
+    while inf_value != inf_value * inf_value:
+        inf_value *= inf_value
+    nan_value = -inf_value / inf_value  # Trying to make a quiet NaN (like C99).
+
+    def construct_yaml_float(self, node: Any) -> float:
+        value_so = self.construct_scalar(node)
+        value_s = value_so.replace('_', "").lower()
+        sign = +1
+        if value_s[0] == '-':
+            sign = -1
+        if value_s[0] in '+-':
+            value_s = value_s[1:]
+        if value_s == '.inf':
+            return sign * self.inf_value
+        elif value_s == '.nan':
+            return self.nan_value
+        elif self.resolver.processing_version != (1, 2) and ':' in value_s:
+            digits = [float(part) for part in value_s.split(':')]
+            digits.reverse()
+            base = 1
+            value = 0.0
+            for digit in digits:
+                value += digit * base
+                base *= 60
+            return sign * value
+        else:
+            if self.resolver.processing_version != (1, 2) and 'e' in value_s:
+                # value_s is lower case independent of input
+                mantissa, exponent = value_s.split('e')
+                if '.' not in mantissa:
+                    warnings.warn(MantissaNoDotYAML1_1Warning(node, value_so), stacklevel=1)
+            return sign * float(value_s)
+
+    def construct_yaml_binary(self, node: Any) -> Any:
+        import base64
+
+        try:
+            value = self.construct_scalar(node).encode('ascii')
+        except UnicodeEncodeError as exc:
+            raise ConstructorError(
+                None,
+                None,
+                f'failed to convert base64 data into ascii: {exc!s}',
+                node.start_mark,
+            )
+        try:
+            return base64.decodebytes(value)
+        except binascii.Error as exc:
+            raise ConstructorError(
+                None, None, f'failed to decode base64 data: {exc!s}', node.start_mark,
+            )
+
+    timestamp_regexp = timestamp_regexp  # moved to util 0.17.17
+
+    def construct_yaml_timestamp(self, node: Any, values: Any = None) -> Any:
+        if values is None:
+            try:
+                match = self.timestamp_regexp.match(node.value)
+            except TypeError:
+                match = None
+            if match is None:
+                raise ConstructorError(
+                    None,
+                    None,
+                    f'failed to construct timestamp from "{node.value}"',
+                    node.start_mark,
+                )
+            values = match.groupdict()
+        return create_timestamp(**values)
+
+    def construct_yaml_omap(self, node: Any) -> Any:
+        # Note: we do now check for duplicate keys
+        omap = ordereddict()
+        yield omap
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError(
+                'while constructing an ordered map',
+                node.start_mark,
+                f'expected a sequence, but found {node.id!s}',
+                node.start_mark,
+            )
+        for subnode in node.value:
+            if not isinstance(subnode, MappingNode):
+                raise ConstructorError(
+                    'while constructing an ordered map',
+                    node.start_mark,
+                    f'expected a mapping of length 1, but found {subnode.id!s}',
+                    subnode.start_mark,
+                )
+            if len(subnode.value) != 1:
+                raise ConstructorError(
+                    'while constructing an ordered map',
+                    node.start_mark,
+                    f'expected a single mapping item, but found {len(subnode.value):d} items',
+                    subnode.start_mark,
+                )
+            key_node, value_node = subnode.value[0]
+            key = self.construct_object(key_node)
+            assert key not in omap
+            value = self.construct_object(value_node)
+            omap[key] = value
+
+    def construct_yaml_pairs(self, node: Any) -> Any:
+        # Note: the same code as `construct_yaml_omap`.
+        pairs: List[Any] = []
+        yield pairs
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError(
+                'while constructing pairs',
+                node.start_mark,
+                f'expected a sequence, but found {node.id!s}',
+                node.start_mark,
+            )
+        for subnode in node.value:
+            if not isinstance(subnode, MappingNode):
+                raise ConstructorError(
+                    'while constructing pairs',
+                    node.start_mark,
+                    f'expected a mapping of length 1, but found {subnode.id!s}',
+                    subnode.start_mark,
+                )
+            if len(subnode.value) != 1:
+                raise ConstructorError(
+                    'while constructing pairs',
+                    node.start_mark,
+                    f'expected a single mapping item, but found {len(subnode.value):d} items',
+                    subnode.start_mark,
+                )
+            key_node, value_node = subnode.value[0]
+            key = self.construct_object(key_node)
+            value = self.construct_object(value_node)
+            pairs.append((key, value))
+
+    def construct_yaml_set(self, node: Any) -> Any:
+        data: Set[Any] = set()
+        yield data
+        value = self.construct_mapping(node)
+        data.update(value)
+
+    def construct_yaml_str(self, node: Any) -> Any:
+        value = self.construct_scalar(node)
+        return value
+
+    def construct_yaml_seq(self, node: Any) -> Any:
+        data: List[Any] = self.yaml_base_list_type()
+        yield data
+        data.extend(self.construct_sequence(node))
+
+    def construct_yaml_map(self, node: Any) -> Any:
+        data: Dict[Any, Any] = self.yaml_base_dict_type()
+        yield data
+        value = self.construct_mapping(node)
+        data.update(value)
+
+    def construct_yaml_object(self, node: Any, cls: Any) -> Any:
+        data = cls.__new__(cls)
+        yield data
+        if hasattr(data, '__setstate__'):
+            state = self.construct_mapping(node, deep=True)
+            data.__setstate__(state)
+        else:
+            state = self.construct_mapping(node)
+            data.__dict__.update(state)
+
+    def construct_undefined(self, node: Any) -> None:
+        raise ConstructorError(
+            None,
+            None,
+            f'could not determine a constructor for the tag {node.tag!r}',
+            node.start_mark,
+        )
+
+
+for tag in 'null bool int float binary timestamp omap pairs set str seq map'.split():
+    SafeConstructor.add_default_constructor(tag)
+
+SafeConstructor.add_constructor(None, SafeConstructor.construct_undefined)
+
+
+class Constructor(SafeConstructor):
+    def construct_python_str(self, node: Any) -> Any:
+        return self.construct_scalar(node)
+
+    def construct_python_unicode(self, node: Any) -> Any:
+        return self.construct_scalar(node)
+
+    def construct_python_bytes(self, node: Any) -> Any:
+        import base64
+
+        try:
+            value = self.construct_scalar(node).encode('ascii')
+        except UnicodeEncodeError as exc:
+            raise ConstructorError(
+                None,
+                None,
+                f'failed to convert base64 data into ascii: {exc!s}',
+                node.start_mark,
+            )
+        try:
+            return base64.decodebytes(value)
+        except binascii.Error as exc:
+            raise ConstructorError(
+                None, None, f'failed to decode base64 data: {exc!s}', node.start_mark,
+            )
+
+    def construct_python_long(self, node: Any) -> int:
+        val = self.construct_yaml_int(node)
+        return val
+
+    def construct_python_complex(self, node: Any) -> Any:
+        return complex(self.construct_scalar(node))
+
+    def construct_python_tuple(self, node: Any) -> Any:
+        return tuple(self.construct_sequence(node))
+
+    def find_python_module(self, name: Any, mark: Any) -> Any:
+        if not name:
+            raise ConstructorError(
+                'while constructing a Python module',
+                mark,
+                'expected non-empty name appended to the tag',
+                mark,
+            )
+        try:
+            __import__(name)
+        except ImportError as exc:
+            raise ConstructorError(
+                'while constructing a Python module',
+                mark,
+                f'cannot find module {name!r} ({exc!s})',
+                mark,
+            )
+        return sys.modules[name]
+
+    def find_python_name(self, name: Any, mark: Any) -> Any:
+        if not name:
+            raise ConstructorError(
+                'while constructing a Python object',
+                mark,
+                'expected non-empty name appended to the tag',
+                mark,
+            )
+        if '.' in name:
+            lname = name.split('.')
+            lmodule_name = lname
+            lobject_name: List[Any] = []
+            while len(lmodule_name) > 1:
+                lobject_name.insert(0, lmodule_name.pop())
+                module_name = '.'.join(lmodule_name)
+                try:
+                    __import__(module_name)
+                    # object_name = '.'.join(object_name)
+                    break
+                except ImportError:
+                    continue
+        else:
+            module_name = builtins_module
+            lobject_name = [name]
+        try:
+            __import__(module_name)
+        except ImportError as exc:
+            raise ConstructorError(
+                'while constructing a Python object',
+                mark,
+                f'cannot find module {module_name!r} ({exc!s})',
+                mark,
+            )
+        module = sys.modules[module_name]
+        object_name = '.'.join(lobject_name)
+        obj = module
+        while lobject_name:
+            if not hasattr(obj, lobject_name[0]):
+
+                raise ConstructorError(
+                    'while constructing a Python object',
+                    mark,
+                    f'cannot find {object_name!r} in the module {module.__name__!r}',
+                    mark,
+                )
+            obj = getattr(obj, lobject_name.pop(0))
+        return obj
+
+    def construct_python_name(self, suffix: Any, node: Any) -> Any:
+        value = self.construct_scalar(node)
+        if value:
+            raise ConstructorError(
+                'while constructing a Python name',
+                node.start_mark,
+                f'expected the empty value, but found {value!r}',
+                node.start_mark,
+            )
+        return self.find_python_name(suffix, node.start_mark)
+
+    def construct_python_module(self, suffix: Any, node: Any) -> Any:
+        value = self.construct_scalar(node)
+        if value:
+            raise ConstructorError(
+                'while constructing a Python module',
+                node.start_mark,
+                f'expected the empty value, but found {value!r}',
+                node.start_mark,
+            )
+        return self.find_python_module(suffix, node.start_mark)
+
+    def make_python_instance(
+        self, suffix: Any, node: Any, args: Any = None, kwds: Any = None, newobj: bool = False,
+    ) -> Any:
+        if not args:
+            args = []
+        if not kwds:
+            kwds = {}
+        cls = self.find_python_name(suffix, node.start_mark)
+        if newobj and isinstance(cls, type):
+            return cls.__new__(cls, *args, **kwds)
+        else:
+            return cls(*args, **kwds)
+
+    def set_python_instance_state(self, instance: Any, state: Any) -> None:
+        if hasattr(instance, '__setstate__'):
+            instance.__setstate__(state)
+        else:
+            slotstate: Dict[Any, Any] = {}
+            if isinstance(state, tuple) and len(state) == 2:
+                state, slotstate = state
+            if hasattr(instance, '__dict__'):
+                instance.__dict__.update(state)
+            elif state:
+                slotstate.update(state)
+            for key, value in slotstate.items():
+                setattr(instance, key, value)
+
+    def construct_python_object(self, suffix: Any, node: Any) -> Any:
+        # Format:
+        #   !!python/object:module.name { ... state ... }
+        instance = self.make_python_instance(suffix, node, newobj=True)
+        self.recursive_objects[node] = instance
+        yield instance
+        deep = hasattr(instance, '__setstate__')
+        state = self.construct_mapping(node, deep=deep)
+        self.set_python_instance_state(instance, state)
+
+    def construct_python_object_apply(
+        self, suffix: Any, node: Any, newobj: bool = False,
+    ) -> Any:
+        # Format:
+        #   !!python/object/apply       # (or !!python/object/new)
+        #   args: [ ... arguments ... ]
+        #   kwds: { ... keywords ... }
+        #   state: ... state ...
+        #   listitems: [ ... listitems ... ]
+        #   dictitems: { ... dictitems ... }
+        # or short format:
+        #   !!python/object/apply [ ... arguments ... ]
+        # The difference between !!python/object/apply and !!python/object/new
+        # is how an object is created, check make_python_instance for details.
+        if isinstance(node, SequenceNode):
+            args = self.construct_sequence(node, deep=True)
+            kwds: Dict[Any, Any] = {}
+            state: Dict[Any, Any] = {}
+            listitems: List[Any] = []
+            dictitems: Dict[Any, Any] = {}
+        else:
+            value = self.construct_mapping(node, deep=True)
+            args = value.get('args', [])
+            kwds = value.get('kwds', {})
+            state = value.get('state', {})
+            listitems = value.get('listitems', [])
+            dictitems = value.get('dictitems', {})
+        instance = self.make_python_instance(suffix, node, args, kwds, newobj)
+        if bool(state):
+            self.set_python_instance_state(instance, state)
+        if bool(listitems):
+            instance.extend(listitems)
+        if bool(dictitems):
+            for key in dictitems:
+                instance[key] = dictitems[key]
+        return instance
+
+    def construct_python_object_new(self, suffix: Any, node: Any) -> Any:
+        return self.construct_python_object_apply(suffix, node, newobj=True)
+
+    @classmethod
+    def add_default_constructor(
+        cls, tag: str, method: Any = None, tag_base: str = 'tag:yaml.org,2002:python/',
+    ) -> None:
+        if not tag.startswith('tag:'):
+            if method is None:
+                method = 'construct_yaml_' + tag
+            tag = tag_base + tag
+        cls.add_constructor(tag, getattr(cls, method))
+
+
+Constructor.add_constructor('tag:yaml.org,2002:python/none', Constructor.construct_yaml_null)
+
+Constructor.add_constructor('tag:yaml.org,2002:python/bool', Constructor.construct_yaml_bool)
+
+Constructor.add_constructor('tag:yaml.org,2002:python/str', Constructor.construct_python_str)
+
+Constructor.add_constructor(
+    'tag:yaml.org,2002:python/unicode', Constructor.construct_python_unicode,
+)
+
+Constructor.add_constructor(
+    'tag:yaml.org,2002:python/bytes', Constructor.construct_python_bytes,
+)
+
+Constructor.add_constructor('tag:yaml.org,2002:python/int', Constructor.construct_yaml_int)
+
+Constructor.add_constructor('tag:yaml.org,2002:python/long', Constructor.construct_python_long)
+
+Constructor.add_constructor('tag:yaml.org,2002:python/float', Constructor.construct_yaml_float)
+
+Constructor.add_constructor(
+    'tag:yaml.org,2002:python/complex', Constructor.construct_python_complex,
+)
+
+Constructor.add_constructor('tag:yaml.org,2002:python/list', Constructor.construct_yaml_seq)
+
+Constructor.add_constructor(
+    'tag:yaml.org,2002:python/tuple', Constructor.construct_python_tuple,
+)
+# for tag in 'bool str unicode bytes int long float complex tuple'.split():
+#    Constructor.add_default_constructor(tag)
+
+Constructor.add_constructor('tag:yaml.org,2002:python/dict', Constructor.construct_yaml_map)
+
+Constructor.add_multi_constructor(
+    'tag:yaml.org,2002:python/name:', Constructor.construct_python_name,
+)
+
+Constructor.add_multi_constructor(
+    'tag:yaml.org,2002:python/module:', Constructor.construct_python_module,
+)
+
+Constructor.add_multi_constructor(
+    'tag:yaml.org,2002:python/object:', Constructor.construct_python_object,
+)
+
+Constructor.add_multi_constructor(
+    'tag:yaml.org,2002:python/object/apply:', Constructor.construct_python_object_apply,
+)
+
+Constructor.add_multi_constructor(
+    'tag:yaml.org,2002:python/object/new:', Constructor.construct_python_object_new,
+)
+
+
+class RoundTripConstructor(SafeConstructor):
+    """need to store the comments on the node itself,
+    as well as on the items
+    """
+
+    def comment(self, idx: Any) -> Any:
+        assert self.loader.comment_handling is not None
+        x = self.scanner.comments[idx]
+        x.set_assigned()
+        return x
+
+    def comments(self, list_of_comments: Any, idx: Optional[Any] = None) -> Any:
+        # hand in the comment and optional pre, eol, post segment
+        if list_of_comments is None:
+            return []
+        if idx is not None:
+            if list_of_comments[idx] is None:
+                return []
+            list_of_comments = list_of_comments[idx]
+        for x in list_of_comments:
+            yield self.comment(x)
+
+    def construct_scalar(self, node: Any) -> Any:
+        if not isinstance(node, ScalarNode):
+            raise ConstructorError(
+                None, None, f'expected a scalar node, but found {node.id!s}', node.start_mark,
+            )
+
+        if node.style == '|' and isinstance(node.value, str):
+            lss = LiteralScalarString(node.value, anchor=node.anchor)
+            if self.loader and self.loader.comment_handling is None:
+                if node.comment and node.comment[1]:
+                    lss.comment = node.comment[1][0]  # type: ignore
+            else:
+                # NEWCMNT
+                if node.comment is not None and node.comment[1]:
+                    # nprintf('>>>>nc1', node.comment)
+                    # EOL comment after |
+                    lss.comment = self.comment(node.comment[1][0])  # type: ignore
+            return lss
+        if node.style == '>' and isinstance(node.value, str):
+            fold_positions: List[int] = []
+            idx = -1
+            while True:
+                idx = node.value.find('\a', idx + 1)
+                if idx < 0:
+                    break
+                fold_positions.append(idx - len(fold_positions))
+            fss = FoldedScalarString(node.value.replace('\a', ''), anchor=node.anchor)
+            if self.loader and self.loader.comment_handling is None:
+                if node.comment and node.comment[1]:
+                    fss.comment = node.comment[1][0]  # type: ignore
+            else:
+                # NEWCMNT
+                if node.comment is not None and node.comment[1]:
+                    # nprintf('>>>>nc2', node.comment)
+                    # EOL comment after >
+                    fss.comment = self.comment(node.comment[1][0])  # type: ignore
+            if fold_positions:
+                fss.fold_pos = fold_positions  # type: ignore
+            return fss
+        elif bool(self._preserve_quotes) and isinstance(node.value, str):
+            if node.style == "'":
+                return SingleQuotedScalarString(node.value, anchor=node.anchor)
+            if node.style == '"':
+                return DoubleQuotedScalarString(node.value, anchor=node.anchor)
+        # if node.ctag:
+        #     data2 = TaggedScalar()
+        #     data2.value = node.value
+        #     data2.style = node.style
+        #     data2.yaml_set_ctag(node.ctag)
+        #     if node.anchor:
+        #         from ruamel.yaml.serializer import templated_id
+
+        #         if not templated_id(node.anchor):
+        #             data2.yaml_set_anchor(node.anchor, always_dump=True)
+        #     return data2
+        if node.anchor:
+            return PlainScalarString(node.value, anchor=node.anchor)
+        return node.value
+
+    def construct_yaml_int(self, node: Any) -> Any:
+        width: Any = None
+        value_su = self.construct_scalar(node)
+        try:
+            sx = value_su.rstrip('_')
+            underscore: Any = [len(sx) - sx.rindex('_') - 1, False, False]
+        except ValueError:
+            underscore = None
+        except IndexError:
+            underscore = None
+        value_s = value_su.replace('_', "")
+        sign = +1
+        if value_s[0] in '+-':
+            if value_s[0] == '-':
+                sign = -1
+            value_s = value_s[1:]
+        if value_s.startswith('0b'):
+            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
+                width = len(value_s[2:])
+            if underscore is not None:
+                underscore[1] = value_su[2] == '_'
+                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
+            return BinaryInt(
+                sign * int(value_s[2:], 2),
+                width=width,
+                underscore=underscore,
+                anchor=node.anchor,
+            )
+        elif value_s.startswith('0x'):
+            # default to lower-case if no a-fA-F in string
+            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
+                width = len(value_s[2:])
+            hex_fun: Any = HexInt
+            for ch in value_s[2:]:
+                if ch in 'ABCDEF':  # first non-digit is capital
+                    hex_fun = HexCapsInt
+                    break
+                if ch in 'abcdef':
+                    break
+            if underscore is not None:
+                underscore[1] = value_su[2] == '_'
+                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
+            return hex_fun(
+                sign * int(value_s[2:], 16),
+                width=width,
+                underscore=underscore,
+                anchor=node.anchor,
+            )
+        elif value_s.startswith('0o'):
+            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
+                width = len(value_s[2:])
+            if underscore is not None:
+                underscore[1] = value_su[2] == '_'
+                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
+            return OctalInt(
+                sign * int(value_s[2:], 8),
+                width=width,
+                underscore=underscore,
+                anchor=node.anchor,
+            )
+        elif (
+            self.resolver.processing_version != (1, 2)
+            and len(value_s) > 1
+            and value_s[0] == '0'
+        ):
+            return OctalInt(
+                sign * int(value_s, 8), width=width, underscore=underscore, anchor=node.anchor,
+            )
+        elif self.resolver.processing_version != (1, 2) and ':' in value_s:
+            digits = [int(part) for part in value_s.split(':')]
+            digits.reverse()
+            base = 1
+            value = 0
+            for digit in digits:
+                value += digit * base
+                base *= 60
+            return sign * value
+        elif self.resolver.processing_version > (1, 1) and value_s[0] == '0':
+            # not an octal, an integer with leading zero(s)
+            if underscore is not None:
+                # cannot have a leading underscore
+                underscore[2] = len(value_su) > 1 and value_su[-1] == '_'
+            return ScalarInt(
+                sign * int(value_s),
+                width=len(value_s),
+                underscore=underscore,
+                anchor=node.anchor,
+            )
+        elif underscore:
+            # cannot have a leading underscore
+            underscore[2] = len(value_su) > 1 and value_su[-1] == '_'
+            return ScalarInt(
+                sign * int(value_s), width=None, underscore=underscore, anchor=node.anchor,
+            )
+        elif node.anchor:
+            return ScalarInt(sign * int(value_s), width=None, anchor=node.anchor)
+        else:
+            return sign * int(value_s)
+
+    def construct_yaml_float(self, node: Any) -> Any:
+        def leading_zeros(v: Any) -> int:
+            lead0 = 0
+            idx = 0
+            while idx < len(v) and v[idx] in '0.':
+                if v[idx] == '0':
+                    lead0 += 1
+                idx += 1
+            return lead0
+
+        # underscore = None
+        m_sign: Any = False
+        value_so = self.construct_scalar(node)
+        value_s = value_so.replace('_', "").lower()
+        sign = +1
+        if value_s[0] == '-':
+            sign = -1
+        if value_s[0] in '+-':
+            m_sign = value_s[0]
+            value_s = value_s[1:]
+        if value_s == '.inf':
+            return sign * self.inf_value
+        if value_s == '.nan':
+            return self.nan_value
+        if self.resolver.processing_version != (1, 2) and ':' in value_s:
+            digits = [float(part) for part in value_s.split(':')]
+            digits.reverse()
+            base = 1
+            value = 0.0
+            for digit in digits:
+                value += digit * base
+                base *= 60
+            return sign * value
+        if 'e' in value_s:
+            try:
+                mantissa, exponent = value_so.split('e')
+                exp = 'e'
+            except ValueError:
+                mantissa, exponent = value_so.split('E')
+                exp = 'E'
+            if self.resolver.processing_version != (1, 2):
+                # value_s is lower case independent of input
+                if '.' not in mantissa:
+                    warnings.warn(MantissaNoDotYAML1_1Warning(node, value_so), stacklevel=1)
+            lead0 = leading_zeros(mantissa)
+            width = len(mantissa)
+            prec = mantissa.find('.')
+            if m_sign:
+                width -= 1
+            e_width = len(exponent)
+            e_sign = exponent[0] in '+-'
+            # nprint('sf', width, prec, m_sign, exp, e_width, e_sign)
+            return ScalarFloat(
+                sign * float(value_s),
+                width=width,
+                prec=prec,
+                m_sign=m_sign,
+                m_lead0=lead0,
+                exp=exp,
+                e_width=e_width,
+                e_sign=e_sign,
+                anchor=node.anchor,
+            )
+        width = len(value_so)
+        # you can't use index, !!float 42 would be a float without a dot
+        prec = value_so.find('.')
+        lead0 = leading_zeros(value_so)
+        return ScalarFloat(
+            sign * float(value_s),
+            width=width,
+            prec=prec,
+            m_sign=m_sign,
+            m_lead0=lead0,
+            anchor=node.anchor,
+        )
+
+    def construct_yaml_str(self, node: Any) -> Any:
+        if node.ctag.handle:
+            value = self.construct_unknown(node)
+        else:
+            value = self.construct_scalar(node)
+        if isinstance(value, ScalarString):
+            return value
+        return value
+
+    def construct_rt_sequence(self, node: Any, seqtyp: Any, deep: bool = False) -> Any:
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError(
+                None,
+                None,
+                f'expected a sequence node, but found {node.id!s}',
+                node.start_mark,
+            )
+        ret_val = []
+        if self.loader and self.loader.comment_handling is None:
+            if node.comment:
+                seqtyp._yaml_add_comment(node.comment[:2])
+                if len(node.comment) > 2:
+                    # this happens e.g. if you have a sequence element that is a flow-style
+                    # mapping and that has no EOL comment but a following commentline or
+                    # empty line
+                    seqtyp.yaml_end_comment_extend(node.comment[2], clear=True)
+        else:
+            # NEWCMNT
+            if node.comment:
+                nprintf('nc3', node.comment)
+        if node.anchor:
+            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
+
+            if not templated_id(node.anchor):
+                seqtyp.yaml_set_anchor(node.anchor)
+        for idx, child in enumerate(node.value):
+            if child.comment:
+                seqtyp._yaml_add_comment(child.comment, key=idx)
+                child.comment = None  # if moved to sequence remove from child
+            ret_val.append(self.construct_object(child, deep=deep))
+            seqtyp._yaml_set_idx_line_col(
+                idx, [child.start_mark.line, child.start_mark.column],
+            )
+        return ret_val
+
+    def flatten_mapping(self, node: Any) -> Any:  # RTConstructor
+        """
+        This implements the merge key feature http://yaml.org/type/merge.html
+        by referencing the merge dict/list of dicts
+        """
+        from opentelemetry.agent._vendor.ruamel.yaml.mergevalue import MergeValue
+
+        def constructed(value_node: Any) -> Any:
+            # If the contents of a merge are defined within the
+            # merge marker, then they won't have been constructed
+            # yet. But if they were already constructed, we need to use
+            # the existing object.
+            if value_node in self.constructed_objects:
+                value = self.constructed_objects[value_node]
+            else:
+                value = self.construct_object(value_node, deep=True)
+            return value
+
+        # merge = []
+        # merge_map_list: List[Any] = []
+        merge_map_list = MergeValue()
+        index = 0
+        while index < len(node.value):
+            key_node, value_node = node.value[index]
+            if key_node.tag == 'tag:yaml.org,2002:merge':
+                if len(merge_map_list):  # double << key
+                    args = [
+                        'while constructing a mapping',
+                        node.start_mark,
+                        'found duplicate merge key "<<"',
+                        key_node.start_mark,
+                        """\
+                        Duplicate merge keys are never allowed, not even when
+                        `.allow_duplicate_keys` is set to True
+                        """,
+                    ]
+                    raise DuplicateKeyError(*args)
+                del node.value[index]
+                merge_map_list.merge_pos = index
+                if isinstance(value_node, MappingNode):
+                    merge_map_list.append(constructed(value_node))
+                elif isinstance(value_node, SequenceNode):
+                    # submerge = []
+                    merge_map_list.set_sequence(constructed(value_node))
+                    for subnode in value_node.value:
+                        if not isinstance(subnode, MappingNode):
+                            raise ConstructorError(
+                                'while constructing a mapping',
+                                node.start_mark,
+                                f'expected a mapping for merging, but found {subnode.id!s}',
+                                subnode.start_mark,
+                            )
+                        merge_map_list.append(constructed(subnode))
+                else:
+                    raise ConstructorError(
+                        'while constructing a mapping',
+                        node.start_mark,
+                        'expected a mapping or list of mappings for merging, '
+                        f'but found {value_node.id!s}',
+                        value_node.start_mark,
+                    )
+            elif key_node.tag == 'tag:yaml.org,2002:value':
+                key_node.tag = 'tag:yaml.org,2002:str'
+                index += 1
+            else:
+                index += 1
+        return merge_map_list
+        # if merge:
+        #     node.value = merge + node.value
+
+    def _sentinel(self) -> None:
+        pass
+
+    # RoundTrip
+    def construct_mapping(self, node: Any, maptyp: Any, deep: bool = False) -> Any:  # type: ignore # NOQA
+        if not isinstance(node, MappingNode):
+            raise ConstructorError(
+                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
+            )
+        merge_map = self.flatten_mapping(node)
+        # mapping = {}
+        if self.loader and self.loader.comment_handling is None:
+            if node.comment:
+                maptyp._yaml_add_comment(node.comment[:2])
+                if len(node.comment) > 2:
+                    maptyp.yaml_end_comment_extend(node.comment[2], clear=True)
+        else:
+            # NEWCMNT
+            if node.comment:
+                # nprintf('nc4', node.comment, node.start_mark)
+                if maptyp.ca.pre is None:
+                    maptyp.ca.pre = []
+                for cmnt in self.comments(node.comment, 0):
+                    maptyp.ca.pre.append(cmnt)
+        if node.anchor:
+            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
+
+            if not templated_id(node.anchor):
+                maptyp.yaml_set_anchor(node.anchor)
+        last_key, last_value = None, self._sentinel
+        for key_node, value_node in node.value:
+            # keys can be list -> deep
+            key = self.construct_object(key_node, deep=True)
+            # lists are not hashable, but tuples are
+            if not isinstance(key, Hashable):
+                if isinstance(key, MutableSequence):
+                    key_s = CommentedKeySeq(key)
+                    if key_node.flow_style is True:
+                        key_s.fa.set_flow_style()
+                    elif key_node.flow_style is False:
+                        key_s.fa.set_block_style()
+                    key_s._yaml_set_line_col(key.lc.line, key.lc.col)  # type: ignore
+                    key = key_s
+                elif isinstance(key, MutableMapping):
+                    key_m = CommentedKeyMap(key)
+                    if key_node.flow_style is True:
+                        key_m.fa.set_flow_style()
+                    elif key_node.flow_style is False:
+                        key_m.fa.set_block_style()
+                    key_m._yaml_set_line_col(key.lc.line, key.lc.col)  # type: ignore
+                    key = key_m
+            if not isinstance(key, Hashable):
+                raise ConstructorError(
+                    'while constructing a mapping',
+                    node.start_mark,
+                    'found unhashable key',
+                    key_node.start_mark,
+                )
+            value = self.construct_object(value_node, deep=deep)
+            if self.check_mapping_key(node, key_node, maptyp, key, value):
+                if self.loader and self.loader.comment_handling is None:
+                    if key_node.comment and len(key_node.comment) > 4 and key_node.comment[4]:
+                        if last_value is None:
+                            key_node.comment[0] = key_node.comment.pop(4)
+                            maptyp._yaml_add_comment(key_node.comment, value=last_key)
+                        else:
+                            key_node.comment[2] = key_node.comment.pop(4)
+                            maptyp._yaml_add_comment(key_node.comment, key=key)
+                        key_node.comment = None
+                    if key_node.comment:
+                        maptyp._yaml_add_comment(key_node.comment, key=key)
+                    if value_node.comment:
+                        maptyp._yaml_add_comment(value_node.comment, value=key)
+                else:
+                    # NEWCMNT
+                    if key_node.comment:
+                        # nprintf('nc5a', key, key_node.comment)
+                        if key_node.comment[0]:
+                            maptyp.ca.set(key, C_KEY_PRE, key_node.comment[0])
+                        if key_node.comment[1]:
+                            maptyp.ca.set(key, C_KEY_EOL, key_node.comment[1])
+                        if key_node.comment[2]:
+                            maptyp.ca.set(key, C_KEY_POST, key_node.comment[2])
+                    if value_node.comment:
+                        nprintf('nc5b', key, value_node.comment)
+                        if value_node.comment[0]:
+                            maptyp.ca.set(key, C_VALUE_PRE, value_node.comment[0])
+                        if value_node.comment[1]:
+                            maptyp.ca.set(key, C_VALUE_EOL, value_node.comment[1])
+                        if value_node.comment[2]:
+                            maptyp.ca.set(key, C_VALUE_POST, value_node.comment[2])
+                maptyp._yaml_set_kv_line_col(
+                    key,
+                    [
+                        key_node.start_mark.line,
+                        key_node.start_mark.column,
+                        value_node.start_mark.line,
+                        value_node.start_mark.column,
+                    ],
+                )
+                maptyp[key] = value
+                last_key, last_value = key, value  # could use indexing
+        # do this last, or <<: before a key will prevent insertion in instances
+        # of collections.OrderedDict (as they have no __contains__
+        if merge_map:
+            maptyp.add_yaml_merge(merge_map)
+
+    def construct_setting(self, node: Any, typ: Any, deep: bool = False) -> Any:
+        if not isinstance(node, MappingNode):
+            raise ConstructorError(
+                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
+            )
+        if self.loader and self.loader.comment_handling is None:
+            if node.comment:
+                typ._yaml_add_comment(node.comment[:2])
+                if len(node.comment) > 2:
+                    typ.yaml_end_comment_extend(node.comment[2], clear=True)
+        else:
+            # NEWCMNT
+            if node.comment:
+                nprintf('nc6', node.comment)
+        if node.anchor:
+            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
+
+            if not templated_id(node.anchor):
+                typ.yaml_set_anchor(node.anchor)
+        for key_node, value_node in node.value:
+            # keys can be list -> deep
+            key = self.construct_object(key_node, deep=True)
+            # lists are not hashable, but tuples are
+            if not isinstance(key, Hashable):
+                if isinstance(key, list):
+                    key = tuple(key)
+            if not isinstance(key, Hashable):
+                raise ConstructorError(
+                    'while constructing a mapping',
+                    node.start_mark,
+                    'found unhashable key',
+                    key_node.start_mark,
+                )
+            # construct but should be null
+            value = self.construct_object(value_node, deep=deep)  # NOQA
+            self.check_set_key(node, key_node, typ, key)
+            if self.loader and self.loader.comment_handling is None:
+                if key_node.comment:
+                    typ._yaml_add_comment(key_node.comment, key=key)
+                if value_node.comment:
+                    typ._yaml_add_comment(value_node.comment, value=key)
+            else:
+                # NEWCMNT
+                if key_node.comment:
+                    nprintf('nc7a', key_node.comment)
+                if value_node.comment:
+                    nprintf('nc7b', value_node.comment)
+            typ.add(key)
+
+    def construct_yaml_seq(self, node: Any) -> Iterator[CommentedSeq]:
+        data = CommentedSeq()
+        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
+        # if node.comment:
+        #    data._yaml_add_comment(node.comment)
+        yield data
+        data.extend(self.construct_rt_sequence(node, data))
+        self.set_collection_style(data, node)
+
+    def construct_yaml_map(self, node: Any) -> Iterator[CommentedMap]:
+        data = CommentedMap()
+        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
+        yield data
+        self.construct_mapping(node, data, deep=True)
+        self.set_collection_style(data, node)
+
+    def set_collection_style(self, data: Any, node: Any) -> None:
+        if len(data) == 0:
+            return
+        if node.flow_style is True:
+            data.fa.set_flow_style()
+        elif node.flow_style is False:
+            data.fa.set_block_style()
+
+    def construct_yaml_object(self, node: Any, cls: Any) -> Any:
+        from dataclasses import is_dataclass, InitVar, MISSING
+
+        data = cls.__new__(cls)
+        yield data
+        if hasattr(data, '__setstate__'):
+            state = SafeConstructor.construct_mapping(self, node, deep=True)
+            data.__setstate__(state)
+        elif is_dataclass(data):
+            mapping = SafeConstructor.construct_mapping(self, node, deep=True)
+            init_var_defaults = {}
+            for field in data.__dataclass_fields__.values():
+                # nprintf('field', field, field.default is MISSING, isinstance(field.type, InitVar))  # NOQA
+                # in 3.7, InitVar is a singleton
+                if (
+                    isinstance(field.type, InitVar)
+                    or field.type is InitVar
+                    # this following is for handling from __future__ import allocations
+                    or (isinstance(field.type, str) and field.type.startswith('InitVar'))
+                ) and field.default is not MISSING:
+                    init_var_defaults[field.name] = field.default
+            for attr, value in mapping.items():
+                if attr not in init_var_defaults:
+                    setattr(data, attr, value)
+            post_init = getattr(data, '__post_init__', None)
+            if post_init is not None:
+                kw = {}
+                for name, default in init_var_defaults.items():
+                    kw[name] = mapping.get(name, default)
+                post_init(**kw)
+            for field in data.__dataclass_fields__.values():
+                if field.name not in mapping and field.default_factory is not MISSING:
+                    setattr(data, field.name, field.default_factory())
+        else:
+            state = SafeConstructor.construct_mapping(self, node)
+            if hasattr(data, '__attrs_attrs__'):  # issue 394
+                data.__init__(**state)
+            else:
+                data.__dict__.update(state)
+        if node.anchor:
+            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
+            from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
+
+            if not templated_id(node.anchor):
+                if not hasattr(data, Anchor.attrib):
+                    a = Anchor()
+                    setattr(data, Anchor.attrib, a)
+                else:
+                    a = getattr(data, Anchor.attrib)
+                a.value = node.anchor
+
+    def construct_yaml_omap(self, node: Any) -> Iterator[CommentedOrderedMap]:
+        # Note: we do now check for duplicate keys
+        omap = CommentedOrderedMap()
+        omap._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
+        if node.flow_style is True:
+            omap.fa.set_flow_style()
+        elif node.flow_style is False:
+            omap.fa.set_block_style()
+        yield omap
+        if self.loader and self.loader.comment_handling is None:
+            if node.comment:
+                omap._yaml_add_comment(node.comment[:2])
+                if len(node.comment) > 2:
+                    omap.yaml_end_comment_extend(node.comment[2], clear=True)
+        else:
+            # NEWCMNT
+            if node.comment:
+                nprintf('nc8', node.comment)
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError(
+                'while constructing an ordered map',
+                node.start_mark,
+                f'expected a sequence, but found {node.id!s}',
+                node.start_mark,
+            )
+        for subnode in node.value:
+            if not isinstance(subnode, MappingNode):
+                raise ConstructorError(
+                    'while constructing an ordered map',
+                    node.start_mark,
+                    f'expected a mapping of length 1, but found {subnode.id!s}',
+                    subnode.start_mark,
+                )
+            if len(subnode.value) != 1:
+                raise ConstructorError(
+                    'while constructing an ordered map',
+                    node.start_mark,
+                    f'expected a single mapping item, but found {len(subnode.value):d} items',
+                    subnode.start_mark,
+                )
+            key_node, value_node = subnode.value[0]
+            key = self.construct_object(key_node)
+            assert key not in omap
+            value = self.construct_object(value_node)
+            if self.loader and self.loader.comment_handling is None:
+                if key_node.comment:
+                    omap._yaml_add_comment(key_node.comment, key=key)
+                if subnode.comment:
+                    omap._yaml_add_comment(subnode.comment, key=key)
+                if value_node.comment:
+                    omap._yaml_add_comment(value_node.comment, value=key)
+            else:
+                # NEWCMNT
+                if key_node.comment:
+                    nprintf('nc9a', key_node.comment)
+                if subnode.comment:
+                    nprintf('nc9b', subnode.comment)
+                if value_node.comment:
+                    nprintf('nc9c', value_node.comment)
+            omap[key] = value
+
+    def construct_yaml_set(self, node: Any) -> Iterator[CommentedSet]:
+        data = CommentedSet()
+        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
+        if node.flow_style is True:
+            data.fa.set_flow_style()
+        elif node.flow_style is False:
+            data.fa.set_block_style()
+        yield data
+        self.construct_setting(node, data)
+
+    def construct_unknown(
+        self, node: Any,
+    ) -> Iterator[Union[CommentedMap, TaggedScalar, CommentedSeq]]:
+        try:
+            if isinstance(node, MappingNode):
+                data = CommentedMap()
+                data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
+                if node.flow_style is True:
+                    data.fa.set_flow_style()
+                elif node.flow_style is False:
+                    data.fa.set_block_style()
+                data.yaml_set_ctag(node.ctag)
+                yield data
+                if node.anchor:
+                    from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
+
+                    if not templated_id(node.anchor):
+                        data.yaml_set_anchor(node.anchor)
+                self.construct_mapping(node, data)
+                return
+            elif isinstance(node, ScalarNode):
+                data2 = TaggedScalar()
+                data2.value = self.construct_scalar(node)
+                data2.style = node.style
+                data2.yaml_set_ctag(node.ctag)
+                yield data2
+                if node.anchor:
+                    from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
+
+                    if not templated_id(node.anchor):
+                        data2.yaml_set_anchor(node.anchor, always_dump=True)
+                return
+            elif isinstance(node, SequenceNode):
+                data3 = CommentedSeq()
+                data3._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
+                if node.flow_style is True:
+                    data3.fa.set_flow_style()
+                elif node.flow_style is False:
+                    data3.fa.set_block_style()
+                data3.yaml_set_ctag(node.ctag)
+                yield data3
+                if node.anchor:
+                    from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
+
+                    if not templated_id(node.anchor):
+                        data3.yaml_set_anchor(node.anchor)
+                data3.extend(self.construct_sequence(node))
+                return
+        except:  # NOQA
+            pass
+        raise ConstructorError(
+            None,
+            None,
+            f'could not determine a constructor for the tag {node.tag!r}',
+            node.start_mark,
+        )
+
+    def construct_yaml_timestamp(
+        self, node: Any, values: Any = None,
+    ) -> Union[datetime.date, datetime.datetime, TimeStamp]:
+        try:
+            match = self.timestamp_regexp.match(node.value)
+        except TypeError:
+            match = None
+        if match is None:
+            raise ConstructorError(
+                None,
+                None,
+                f'failed to construct timestamp from "{node.value}"',
+                node.start_mark,
+            )
+        values = match.groupdict()
+        if not values['hour']:
+            return create_timestamp(**values)
+            # return SafeConstructor.construct_yaml_timestamp(self, node, values)
+        for part in ['t', 'tz_sign', 'tz_hour', 'tz_minute']:
+            if values[part]:
+                break
+        else:
+            return create_timestamp(**values)
+            # return SafeConstructor.construct_yaml_timestamp(self, node, values)
+        # print('>>>>>>>> here', values)
+        dd = create_timestamp(**values)  # this has tzinfo
+        delta = None
+        if values['tz_sign']:
+            hours = values['tz_hour']
+            tz_hour = int(hours)
+            minutes = values['tz_minute']
+            tz_minute = int(minutes) if minutes else 0
+            # ToDo: double work, replace with extraction from dd.tzinfo
+            delta = TimeDelta(hours=tz_hour, minutes=tz_minute)
+            if values['tz_sign'] == '-':
+                delta = -delta
+        if isinstance(dd, datetime.datetime):
+            data = TimeStamp(
+                dd.year, dd.month, dd.day, dd.hour, dd.minute, dd.second, dd.microsecond, dd.tzinfo,  # NOQA
+            )
+        else:
+            # ToDo: make this into a DateStamp?
+            data = TimeStamp(dd.year, dd.month, dd.day, 0, 0, 0, 0)
+            return data
+        if delta:
+            data._yaml['delta'] = delta
+            tz = values['tz_sign'] + values['tz_hour']
+            if values['tz_minute']:
+                tz += ':' + values['tz_minute']
+            data._yaml['tz'] = tz
+        else:
+            if values['tz']:  # no delta
+                data._yaml['tz'] = values['tz']
+        if values['t']:
+            data._yaml['t'] = True
+        return data
+
+    def construct_yaml_sbool(self, node: Any) -> Union[bool, ScalarBoolean]:
+        b = SafeConstructor.construct_yaml_bool(self, node)
+        if node.anchor:
+            return ScalarBoolean(b, anchor=node.anchor)
+        return b
+
+
+RoundTripConstructor.add_default_constructor('bool', method='construct_yaml_sbool')
+
+for tag in 'null int float binary timestamp omap pairs set str seq map'.split():
+    RoundTripConstructor.add_default_constructor(tag)
+
+RoundTripConstructor.add_constructor(None, RoundTripConstructor.construct_unknown)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py
new file mode 100644
index 00000000000..1c9254bc14e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py
@@ -0,0 +1,130 @@
+
+from __future__ import annotations
+
+"""
+DocInfo
+
+Although it was possible to read tag directives before this, all handle/prefix
+pairs for all documents in all streams were stored in one dictionary per
+YAML instance, making it impossible to distinguish where such a pair came
+from without sublassing the scanner.
+
+ToDo:
+DocInfo can be used by a yaml dumper to dump a class
+- if connected to the root of a data structure
+- if provided to the dumper?
+"""
+
+if False:  # MYPY
+    from typing import Optional, Tuple, Any
+
+# from dataclasses import dataclass, field, MISSING  # NOQA
+
+
+# @dataclass(order=True, frozen=True)
+class Version:
+    # major: int
+    # minor: int
+    def __init__(self, major: int, minor: int) -> None:
+        self._major = major
+        self._minor = minor
+
+    @property
+    def major(self) -> int:
+        return self._major
+
+    @property
+    def minor(self) -> int:
+        return self._minor
+
+    def __eq__(self, v: Any) -> bool:
+        if not isinstance(v, Version):
+            return False
+        return self._major == v._major and self._minor == v._minor
+
+    def __lt__(self, v: Version) -> bool:
+        if self._major < v._major:
+            return True
+        if self._major > v._major:
+            return False
+        return self._minor < v._minor
+
+    def __le__(self, v: Version) -> bool:
+        if self._major < v._major:
+            return True
+        if self._major > v._major:
+            return False
+        return self._minor <= v._minor
+
+    def __gt__(self, v: Version) -> bool:
+        if self._major > v._major:
+            return True
+        if self._major < v._major:
+            return False
+        return self._minor > v._minor
+
+    def __ge__(self, v: Version) -> bool:
+        if self._major > v._major:
+            return True
+        if self._major < v._major:
+            return False
+        return self._minor >= v._minor
+
+
+def version(
+    major: int | str | Tuple[int, int] | None,
+    minor: Optional[int] = None,
+) -> Optional[Version]:
+    if major is None:
+        assert minor is None
+        return None
+    if isinstance(major, str):
+        assert minor is None
+        parts = major.split('.')
+        assert len(parts) == 2
+        return Version(int(parts[0]), int(parts[1]))
+    elif isinstance(major, tuple):
+        assert minor is None
+        assert len(major) == 2
+        major, minor = major
+    assert minor is not None
+    return Version(major, minor)
+
+
+# @dataclass(frozen=True)
+class Tag:
+    # handle: str
+    # prefix: str
+    def __init__(self, handle: str, prefix: str) -> None:
+        self._handle = handle
+        self._prefix = prefix
+
+    @property
+    def handle(self) -> str:
+        return self._handle
+
+    @property
+    def prefix(self) -> str:
+        return self._prefix
+
+
+# @dataclass
+class DocInfo:
+    """
+    Store document information, can be used for analysis of a loaded YAML document
+    requested_version: if explicitly set before load
+    doc_version: from %YAML directive
+    tags: from %TAG directives in scanned order
+    """
+    # requested_version: Optional[Version] = None
+    # doc_version: Optional[Version] = None
+    # tags: list[Tag] = field(default_factory=list)
+    def __init__(
+        self,
+        requested_version: Optional[Version] = None,
+        doc_version: Optional[Version] = None,
+        tags: Optional[list[Tag]] = None,
+    ):
+        self.requested_version = requested_version
+        self.doc_version = doc_version
+        self.tags = [] if tags is None else tags
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py
new file mode 100644
index 00000000000..ef11237a173
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py
@@ -0,0 +1,220 @@
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.emitter import Emitter
+from opentelemetry.agent._vendor.ruamel.yaml.serializer import Serializer
+from opentelemetry.agent._vendor.ruamel.yaml.representer import (
+    Representer,
+    SafeRepresenter,
+    BaseRepresenter,
+    RoundTripRepresenter,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.resolver import Resolver, BaseResolver, VersionedResolver
+
+if False:  # MYPY
+    from typing import Any, Dict, List, Union, Optional  # NOQA
+    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamType, VersionType  # NOQA
+
+__all__ = ['BaseDumper', 'SafeDumper', 'Dumper', 'RoundTripDumper']
+
+
+class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
+    def __init__(
+        self: Any,
+        stream: StreamType,
+        default_style: Any = None,
+        default_flow_style: Any = None,
+        canonical: Optional[bool] = None,
+        indent: Optional[int] = None,
+        width: Optional[int] = None,
+        allow_unicode: Optional[bool] = None,
+        line_break: Any = None,
+        encoding: Any = None,
+        explicit_start: Optional[bool] = None,
+        explicit_end: Optional[bool] = None,
+        version: Any = None,
+        tags: Any = None,
+        block_seq_indent: Any = None,
+        top_level_colon_align: Any = None,
+        prefix_colon: Any = None,
+    ) -> None:
+        # NOQA
+        Emitter.__init__(
+            self,
+            stream,
+            canonical=canonical,
+            indent=indent,
+            width=width,
+            allow_unicode=allow_unicode,
+            line_break=line_break,
+            block_seq_indent=block_seq_indent,
+            dumper=self,
+        )
+        Serializer.__init__(
+            self,
+            encoding=encoding,
+            explicit_start=explicit_start,
+            explicit_end=explicit_end,
+            version=version,
+            tags=tags,
+            dumper=self,
+        )
+        BaseRepresenter.__init__(
+            self,
+            default_style=default_style,
+            default_flow_style=default_flow_style,
+            dumper=self,
+        )
+        BaseResolver.__init__(self, loadumper=self)
+
+
+class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
+    def __init__(
+        self,
+        stream: StreamType,
+        default_style: Any = None,
+        default_flow_style: Any = None,
+        canonical: Optional[bool] = None,
+        indent: Optional[int] = None,
+        width: Optional[int] = None,
+        allow_unicode: Optional[bool] = None,
+        line_break: Any = None,
+        encoding: Any = None,
+        explicit_start: Optional[bool] = None,
+        explicit_end: Optional[bool] = None,
+        version: Any = None,
+        tags: Any = None,
+        block_seq_indent: Any = None,
+        top_level_colon_align: Any = None,
+        prefix_colon: Any = None,
+    ) -> None:
+        # NOQA
+        Emitter.__init__(
+            self,
+            stream,
+            canonical=canonical,
+            indent=indent,
+            width=width,
+            allow_unicode=allow_unicode,
+            line_break=line_break,
+            block_seq_indent=block_seq_indent,
+            dumper=self,
+        )
+        Serializer.__init__(
+            self,
+            encoding=encoding,
+            explicit_start=explicit_start,
+            explicit_end=explicit_end,
+            version=version,
+            tags=tags,
+            dumper=self,
+        )
+        SafeRepresenter.__init__(
+            self,
+            default_style=default_style,
+            default_flow_style=default_flow_style,
+            dumper=self,
+        )
+        Resolver.__init__(self, loadumper=self)
+
+
+class Dumper(Emitter, Serializer, Representer, Resolver):
+    def __init__(
+        self,
+        stream: StreamType,
+        default_style: Any = None,
+        default_flow_style: Any = None,
+        canonical: Optional[bool] = None,
+        indent: Optional[int] = None,
+        width: Optional[int] = None,
+        allow_unicode: Optional[bool] = None,
+        line_break: Any = None,
+        encoding: Any = None,
+        explicit_start: Optional[bool] = None,
+        explicit_end: Optional[bool] = None,
+        version: Any = None,
+        tags: Any = None,
+        block_seq_indent: Any = None,
+        top_level_colon_align: Any = None,
+        prefix_colon: Any = None,
+    ) -> None:
+        # NOQA
+        Emitter.__init__(
+            self,
+            stream,
+            canonical=canonical,
+            indent=indent,
+            width=width,
+            allow_unicode=allow_unicode,
+            line_break=line_break,
+            block_seq_indent=block_seq_indent,
+            dumper=self,
+        )
+        Serializer.__init__(
+            self,
+            encoding=encoding,
+            explicit_start=explicit_start,
+            explicit_end=explicit_end,
+            version=version,
+            tags=tags,
+            dumper=self,
+        )
+        Representer.__init__(
+            self,
+            default_style=default_style,
+            default_flow_style=default_flow_style,
+            dumper=self,
+        )
+        Resolver.__init__(self, loadumper=self)
+
+
+class RoundTripDumper(Emitter, Serializer, RoundTripRepresenter, VersionedResolver):
+    def __init__(
+        self,
+        stream: StreamType,
+        default_style: Any = None,
+        default_flow_style: Optional[bool] = None,
+        canonical: Optional[int] = None,
+        indent: Optional[int] = None,
+        width: Optional[int] = None,
+        allow_unicode: Optional[bool] = None,
+        line_break: Any = None,
+        encoding: Any = None,
+        explicit_start: Optional[bool] = None,
+        explicit_end: Optional[bool] = None,
+        version: Any = None,
+        tags: Any = None,
+        block_seq_indent: Any = None,
+        top_level_colon_align: Any = None,
+        prefix_colon: Any = None,
+    ) -> None:
+        # NOQA
+        Emitter.__init__(
+            self,
+            stream,
+            canonical=canonical,
+            indent=indent,
+            width=width,
+            allow_unicode=allow_unicode,
+            line_break=line_break,
+            block_seq_indent=block_seq_indent,
+            top_level_colon_align=top_level_colon_align,
+            prefix_colon=prefix_colon,
+            dumper=self,
+        )
+        Serializer.__init__(
+            self,
+            encoding=encoding,
+            explicit_start=explicit_start,
+            explicit_end=explicit_end,
+            version=version,
+            tags=tags,
+            dumper=self,
+        )
+        RoundTripRepresenter.__init__(
+            self,
+            default_style=default_style,
+            default_flow_style=default_flow_style,
+            dumper=self,
+        )
+        VersionedResolver.__init__(self, loader=self)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py
new file mode 100644
index 00000000000..6e422a1e362
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py
@@ -0,0 +1,1802 @@
+
+from __future__ import annotations
+
+# Emitter expects events obeying the following grammar:
+# stream ::= STREAM-START document* STREAM-END
+# document ::= DOCUMENT-START node DOCUMENT-END
+# node ::= SCALAR | sequence | mapping
+# sequence ::= SEQUENCE-START node* SEQUENCE-END
+# mapping ::= MAPPING-START (node node)* MAPPING-END
+
+import sys
+from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError, YAMLStreamError
+from opentelemetry.agent._vendor.ruamel.yaml.events import *  # NOQA
+
+# fmt: off
+from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, dbg, DBG_EVENT, \
+    check_anchorname_char, nprintf  # NOQA
+# fmt: on
+
+
+if False:  # MYPY
+    from typing import Any, Dict, List, Union, Text, Tuple, Optional  # NOQA
+    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamType  # NOQA
+
+__all__ = ['Emitter', 'EmitterError']
+
+
+class EmitterError(YAMLError):
+    pass
+
+
+class ScalarAnalysis:
+    def __init__(
+        self,
+        scalar: Any,
+        empty: Any,
+        multiline: Any,
+        allow_flow_plain: bool,
+        allow_block_plain: bool,
+        allow_single_quoted: bool,
+        allow_double_quoted: bool,
+        allow_block: bool,
+    ) -> None:
+        self.scalar = scalar
+        self.empty = empty
+        self.multiline = multiline
+        self.allow_flow_plain = allow_flow_plain
+        self.allow_block_plain = allow_block_plain
+        self.allow_single_quoted = allow_single_quoted
+        self.allow_double_quoted = allow_double_quoted
+        self.allow_block = allow_block
+
+    def __repr__(self) -> str:
+        return f'scalar={self.scalar!r}, empty={self.empty}, multiline={self.multiline}, allow_flow_plain={self.allow_flow_plain}, allow_block_plain={self.allow_block_plain}, allow_single_quoted={self.allow_single_quoted}, allow_double_quoted={self.allow_double_quoted}, allow_block={self.allow_block}'  # NOQA
+
+
+class Indents:
+    # replacement for the list based stack of None/int
+    def __init__(self) -> None:
+        self.values: List[Tuple[Any, bool]] = []
+
+    def append(self, val: Any, seq: Any) -> None:
+        self.values.append((val, seq))
+
+    def pop(self) -> Any:
+        return self.values.pop()[0]
+
+    def seq_seq(self) -> bool:
+        try:
+            if self.values[-2][1] and self.values[-1][1]:
+                return True
+        except IndexError:
+            pass
+        return False
+
+    def last_seq(self) -> bool:
+        # return the seq(uence) value for the element added before the last one
+        # in increase_indent()
+        try:
+            return self.values[-2][1]
+        except IndexError:
+            return False
+
+    def seq_flow_align(
+        self, seq_indent: int, column: int, pre_comment: Optional[bool] = False,
+    ) -> int:
+        # extra spaces because of dash
+        # nprint('seq_flow_align', self.values, pre_comment)
+        if len(self.values) < 2 or not self.values[-1][1]:
+            if len(self.values) == 0 or not pre_comment:
+                return 0
+        base = self.values[-1][0] if self.values[-1][0] is not None else 0
+        if pre_comment:
+            return base + seq_indent  # type: ignore
+            # return (len(self.values)) * seq_indent
+        # -1 for the dash
+        return base + seq_indent - column - 1  # type: ignore
+
+    def __len__(self) -> int:
+        return len(self.values)
+
+
+class Emitter:
+    # fmt: off
+    DEFAULT_TAG_PREFIXES = {
+        '!': '!',
+        'tag:yaml.org,2002:': '!!',
+        '!!': '!!',
+    }
+    # fmt: on
+
+    MAX_SIMPLE_KEY_LENGTH = 128
+    flow_seq_start = '['
+    flow_seq_end = ']'
+    flow_seq_separator = ','
+    flow_map_start = '{'
+    flow_map_end = '}'
+    flow_map_separator = ','
+
+    def __init__(
+        self,
+        stream: StreamType,
+        canonical: Any = None,
+        indent: Optional[int] = None,
+        width: Optional[int] = None,
+        allow_unicode: Optional[bool] = None,
+        line_break: Any = None,
+        block_seq_indent: Optional[int] = None,
+        top_level_colon_align: Optional[bool] = None,
+        prefix_colon: Any = None,
+        brace_single_entry_mapping_in_flow_sequence: Optional[bool] = None,
+        dumper: Any = None,
+    ) -> None:
+        # NOQA
+        self.dumper = dumper
+        if self.dumper is not None and getattr(self.dumper, '_emitter', None) is None:
+            self.dumper._emitter = self
+        self.stream = stream
+
+        # Encoding can be overriden by STREAM-START.
+        self.encoding: Optional[Text] = None
+        self.allow_space_break = None
+
+        # Emitter is a state machine with a stack of states to handle nested
+        # structures.
+        self.states: List[Any] = []
+        self.state: Any = self.expect_stream_start
+
+        # Current event and the event queue.
+        self.events: List[Any] = []
+        self.event: Any = None
+
+        # The current indentation level and the stack of previous indents.
+        self.indents = Indents()
+        self.indent: Optional[int] = None
+
+        # flow_context is an expanding/shrinking list consisting of '{' and '['
+        # for each unclosed flow context. If empty list that means block context
+        self.flow_context: List[Text] = []
+
+        # Contexts.
+        self.root_context = False
+        self.sequence_context = False
+        self.mapping_context = False
+        self.simple_key_context = False
+
+        # Characteristics of the last emitted character:
+        #  - current position.
+        #  - is it a whitespace?
+        #  - is it an indention character
+        #    (indentation space, '-', '?', or ':')?
+        self.line = 0
+        self.column = 0
+        self.whitespace = True
+        self.indention = True
+        self.compact_seq_seq = True  # dash after dash
+        self.compact_seq_map = True  # key after dash
+        # self.compact_ms = False   # dash after key, only when excplicit key with ?
+        self.no_newline: Optional[bool] = None  # set if directly after `- `
+
+        # Whether the document requires an explicit document end indicator
+        self.open_ended = False
+
+        # colon handling
+        self.colon = ':'
+        self.prefixed_colon = self.colon if prefix_colon is None else prefix_colon + self.colon
+        # single entry mappings in flow sequence
+        self.brace_single_entry_mapping_in_flow_sequence = (
+            brace_single_entry_mapping_in_flow_sequence  # NOQA
+        )
+
+        # Formatting details.
+        self.canonical = canonical
+        self.allow_unicode = allow_unicode
+        # set to False to get "\Uxxxxxxxx" for non-basic unicode like emojis
+        self.unicode_supplementary = sys.maxunicode > 0xFFFF
+        self.sequence_dash_offset = block_seq_indent if block_seq_indent else 0
+        self.top_level_colon_align = top_level_colon_align
+        self.best_sequence_indent = 2
+        self.requested_indent = indent  # specific for literal zero indent
+        if indent and 1 < indent < 10:
+            self.best_sequence_indent = indent
+        self.best_map_indent = self.best_sequence_indent
+        # if self.best_sequence_indent < self.sequence_dash_offset + 1:
+        #     self.best_sequence_indent = self.sequence_dash_offset + 1
+        self.best_width = 80
+        if width and width > self.best_sequence_indent * 2:
+            self.best_width = width
+        self.best_line_break: Any = '\n'
+        if line_break in ['\r', '\n', '\r\n']:
+            self.best_line_break = line_break
+
+        # Tag prefixes.
+        self.tag_prefixes: Any = None
+
+        # Prepared anchor and tag.
+        self.prepared_anchor: Any = None
+        self.prepared_tag: Any = None
+
+        # Scalar analysis and style.
+        self.analysis: Any = None
+        self.style: Any = None
+
+        self.scalar_after_indicator = True  # write a scalar on the same line as `---`
+
+        self.alt_null = 'null'
+
+    @property
+    def stream(self) -> Any:
+        try:
+            return self._stream
+        except AttributeError:
+            raise YAMLStreamError('output stream needs to be specified')
+
+    @stream.setter
+    def stream(self, val: Any) -> None:
+        if val is None:
+            return
+        if not hasattr(val, 'write'):
+            raise YAMLStreamError('stream argument needs to have a write() method')
+        self._stream = val
+
+    @property
+    def serializer(self) -> Any:
+        try:
+            if hasattr(self.dumper, 'typ'):
+                return self.dumper.serializer
+            return self.dumper._serializer
+        except AttributeError:
+            return self  # cyaml
+
+    @property
+    def flow_level(self) -> int:
+        return len(self.flow_context)
+
+    def dispose(self) -> None:
+        # Reset the state attributes (to clear self-references)
+        self.states = []
+        self.state = None
+
+    def emit(self, event: Any) -> None:
+        if dbg(DBG_EVENT):
+            nprint(event)
+        self.events.append(event)
+        while not self.need_more_events():
+            self.event = self.events.pop(0)
+            self.state()
+            self.event = None
+
+    # In some cases, we wait for a few next events before emitting.
+
+    def need_more_events(self) -> bool:
+        if not self.events:
+            return True
+        event = self.events[0]
+        if isinstance(event, DocumentStartEvent):
+            return self.need_events(1)
+        elif isinstance(event, SequenceStartEvent):
+            return self.need_events(2)
+        elif isinstance(event, MappingStartEvent):
+            return self.need_events(3)
+        else:
+            return False
+
+    def need_events(self, count: int) -> bool:
+        level = 0
+        for event in self.events[1:]:
+            if isinstance(event, (DocumentStartEvent, CollectionStartEvent)):
+                level += 1
+            elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)):
+                level -= 1
+            elif isinstance(event, StreamEndEvent):
+                level = -1
+            if level < 0:
+                return False
+        return len(self.events) < count + 1
+
+    def increase_indent(
+        self, flow: bool = False, sequence: Optional[bool] = None, indentless: bool = False,
+    ) -> None:
+        self.indents.append(self.indent, sequence)
+        if self.indent is None:  # top level
+            if flow:
+                # self.indent = self.best_sequence_indent if self.indents.last_seq() else \
+                #              self.best_map_indent
+                # self.indent = self.best_sequence_indent
+                self.indent = self.requested_indent
+            else:
+                self.indent = 0
+        elif not indentless:
+            self.indent += (
+                self.best_sequence_indent if self.indents.last_seq() else self.best_map_indent
+            )
+            # if self.indents.last_seq():
+            #     if self.indent == 0: # top level block sequence
+            #         self.indent = self.best_sequence_indent - self.sequence_dash_offset
+            #     else:
+            #         self.indent += self.best_sequence_indent
+            # else:
+            #     self.indent += self.best_map_indent
+
+    # States.
+
+    # Stream handlers.
+
+    def expect_stream_start(self) -> None:
+        if isinstance(self.event, StreamStartEvent):
+            if self.event.encoding and not hasattr(self.stream, 'encoding'):
+                self.encoding = self.event.encoding
+            self.write_stream_start()
+            self.state = self.expect_first_document_start
+        else:
+            raise EmitterError(f'expected StreamStartEvent, but got {self.event!s}')
+
+    def expect_nothing(self) -> None:
+        raise EmitterError(f'expected nothing, but got {self.event!s}')
+
+    # Document handlers.
+
+    def expect_first_document_start(self) -> Any:
+        return self.expect_document_start(first=True)
+
+    def expect_document_start(self, first: bool = False) -> None:
+        if isinstance(self.event, DocumentStartEvent):
+            if (self.event.version or self.event.tags) and self.open_ended:
+                self.write_indicator('...', True)
+                self.write_indent()
+            if self.event.version:
+                version_text = self.prepare_version(self.event.version)
+                self.write_version_directive(version_text)
+            self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy()
+            if self.event.tags:
+                handles = sorted(self.event.tags.keys())
+                for handle in handles:
+                    prefix = self.event.tags[handle]
+                    self.tag_prefixes[prefix] = handle
+                    handle_text = self.prepare_tag_handle(handle)
+                    prefix_text = self.prepare_tag_prefix(prefix)
+                    self.write_tag_directive(handle_text, prefix_text)
+            implicit = (
+                first
+                and not self.event.explicit
+                and not self.canonical
+                and not self.event.version
+                and not self.event.tags
+                and not self.check_empty_document()
+            )
+            if not implicit:
+                self.write_indent()
+                self.write_indicator('---', True)
+                if self.canonical:
+                    self.write_indent()
+            self.state = self.expect_document_root
+        elif isinstance(self.event, StreamEndEvent):
+            if self.open_ended:
+                self.write_indicator('...', True)
+                self.write_indent()
+            self.write_stream_end()
+            self.state = self.expect_nothing
+        else:
+            raise EmitterError(f'expected DocumentStartEvent, but got {self.event!s}')
+
+    def expect_document_end(self) -> None:
+        if isinstance(self.event, DocumentEndEvent):
+            self.write_indent()
+            if self.event.explicit:
+                self.write_indicator('...', True)
+                self.write_indent()
+            self.flush_stream()
+            self.state = self.expect_document_start
+        else:
+            raise EmitterError(f'expected DocumentEndEvent, but got {self.event!s}')
+
+    def expect_document_root(self) -> None:
+        self.states.append(self.expect_document_end)
+        self.expect_node(root=True)
+
+    # Node handlers.
+
+    def expect_node(
+        self,
+        root: bool = False,
+        sequence: bool = False,
+        mapping: bool = False,
+        simple_key: bool = False,
+    ) -> None:
+        self.root_context = root
+        self.sequence_context = sequence  # not used in PyYAML
+        force_flow_indent = False
+        self.mapping_context = mapping
+        self.simple_key_context = simple_key
+        if isinstance(self.event, AliasEvent):
+            self.expect_alias()
+        elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)):
+            if (
+                self.process_anchor('&')
+                and isinstance(self.event, ScalarEvent)
+                and self.sequence_context
+            ):
+                self.sequence_context = False
+            if (
+                root
+                and isinstance(self.event, ScalarEvent)
+                and not self.scalar_after_indicator
+            ):
+                self.write_indent()
+            self.process_tag()
+            if isinstance(self.event, ScalarEvent):
+                # nprint('@', self.indention, self.no_newline, self.column)
+                self.expect_scalar()
+            elif isinstance(self.event, SequenceStartEvent):
+                i2, n2 = self.indention, self.no_newline  # NOQA
+                if self.event.comment:
+                    if self.event.flow_style is False:
+                        if self.write_post_comment(self.event):
+                            self.indention = False
+                            self.no_newline = True
+                    if self.event.flow_style:
+                        column = self.column
+                    if self.write_pre_comment(self.event):
+                        if self.event.flow_style:
+                            # force_flow_indent = True
+                            force_flow_indent = not self.indents.values[-1][1]
+                        self.indention = i2
+                        self.no_newline = not self.indention
+                    if self.event.flow_style:
+                        self.column = column
+                if (
+                    self.flow_level
+                    or self.canonical
+                    or self.event.flow_style
+                    or self.check_empty_sequence()
+                ):
+                    self.expect_flow_sequence(force_flow_indent)
+                else:
+                    self.expect_block_sequence()
+                if self.indents.seq_seq():
+                    # - -
+                    self.indention = True
+                    self.no_newline = False
+            elif isinstance(self.event, MappingStartEvent):
+                if self.event.flow_style is False and self.event.comment:
+                    self.write_post_comment(self.event)
+                if self.event.comment and self.event.comment[1]:
+                    self.write_pre_comment(self.event)
+                    if self.event.flow_style and self.indents.values:
+                        force_flow_indent = not self.indents.values[-1][1]
+                if (
+                    self.flow_level
+                    or self.canonical
+                    or self.event.flow_style
+                    or self.check_empty_mapping()
+                ):
+                    self.expect_flow_mapping(
+                        single=self.event.nr_items == 1, force_flow_indent=force_flow_indent,
+                    )
+                else:
+                    self.expect_block_mapping()
+        else:
+            raise EmitterError(f'expected NodeEvent, but got {self.event!s}')
+
+    def expect_alias(self) -> None:
+        if self.event.anchor is None:
+            raise EmitterError('anchor is not specified for alias')
+        self.process_anchor('*')
+        self.state = self.states.pop()
+
+    def expect_scalar(self) -> None:
+        self.increase_indent(flow=True)
+        self.process_scalar()
+        self.indent = self.indents.pop()
+        self.state = self.states.pop()
+
+    # Flow sequence handlers.
+
+    def expect_flow_sequence(self, force_flow_indent: Optional[bool] = False) -> None:
+        if force_flow_indent:
+            self.increase_indent(flow=True, sequence=True)
+        ind = self.indents.seq_flow_align(
+            self.best_sequence_indent, self.column, force_flow_indent,
+        )
+        self.write_indicator(' ' * ind + self.flow_seq_start, True, whitespace=True)
+        if not force_flow_indent:
+            self.increase_indent(flow=True, sequence=True)
+        self.flow_context.append('[')
+        self.state = self.expect_first_flow_sequence_item
+
+    def expect_first_flow_sequence_item(self) -> None:
+        if isinstance(self.event, SequenceEndEvent):
+            self.indent = self.indents.pop()
+            popped = self.flow_context.pop()
+            assert popped == '['
+            self.write_indicator(self.flow_seq_end, False)
+            if self.event.comment and self.event.comment[0]:
+                # eol comment on empty flow sequence
+                self.write_post_comment(self.event)
+            elif self.flow_level == 0:
+                self.write_line_break()
+            self.state = self.states.pop()
+        else:
+            if self.canonical or self.column > self.best_width:
+                self.write_indent()
+            self.states.append(self.expect_flow_sequence_item)
+            self.expect_node(sequence=True)
+
+    def expect_flow_sequence_item(self) -> None:
+        if isinstance(self.event, SequenceEndEvent):
+            self.indent = self.indents.pop()
+            popped = self.flow_context.pop()
+            assert popped == '['
+            if self.canonical:
+                # ToDo: so-39595807, maybe add a space to the flow_seq_separator
+                # and strip the last space, if space then indent, else do not
+                # not sure that [1,2,3] is a valid YAML seq
+                self.write_indicator(self.flow_seq_separator, False)
+                self.write_indent()
+            self.write_indicator(self.flow_seq_end, False)
+            if self.event.comment and self.event.comment[0]:
+                # eol comment on flow sequence
+                self.write_post_comment(self.event)
+            else:
+                self.no_newline = False
+            self.state = self.states.pop()
+        else:
+            self.write_indicator(self.flow_seq_separator, False)
+            if self.canonical or self.column > self.best_width:
+                self.write_indent()
+            self.states.append(self.expect_flow_sequence_item)
+            self.expect_node(sequence=True)
+
+    # Flow mapping handlers.
+
+    def expect_flow_mapping(
+        self, single: Optional[bool] = False, force_flow_indent: Optional[bool] = False,
+    ) -> None:
+        if force_flow_indent:
+            self.increase_indent(flow=True, sequence=False)
+        ind = self.indents.seq_flow_align(
+            self.best_sequence_indent, self.column, force_flow_indent,
+        )
+        map_init = self.flow_map_start
+        if (
+            single
+            and self.flow_level
+            and self.flow_context[-1] == '['
+            and not self.canonical
+            and not self.brace_single_entry_mapping_in_flow_sequence
+        ):
+            # single map item with flow context, no curly braces necessary
+            map_init = ''
+        self.write_indicator(' ' * ind + map_init, True, whitespace=True)
+        self.flow_context.append(map_init)
+        if not force_flow_indent:
+            self.increase_indent(flow=True, sequence=False)
+        self.state = self.expect_first_flow_mapping_key
+
+    def expect_first_flow_mapping_key(self) -> None:
+        if isinstance(self.event, MappingEndEvent):
+            self.indent = self.indents.pop()
+            popped = self.flow_context.pop()
+            assert popped == '{'  # empty flow mapping
+            self.write_indicator(self.flow_map_end, False)
+            if self.event.comment and self.event.comment[0]:
+                # eol comment on empty mapping
+                self.write_post_comment(self.event)
+            elif self.flow_level == 0:
+                self.write_line_break()
+            self.state = self.states.pop()
+        else:
+            if self.canonical or self.column > self.best_width:
+                self.write_indent()
+            if not self.canonical and self.check_simple_key():
+                self.states.append(self.expect_flow_mapping_simple_value)
+                self.expect_node(mapping=True, simple_key=True)
+            else:
+                self.write_indicator('?', True)
+                self.states.append(self.expect_flow_mapping_value)
+                self.expect_node(mapping=True)
+
+    def expect_flow_mapping_key(self) -> None:
+        if isinstance(self.event, MappingEndEvent):
+            # if self.event.comment and self.event.comment[1]:
+            #     self.write_pre_comment(self.event)
+            self.indent = self.indents.pop()
+            popped = self.flow_context.pop()
+            assert popped in ['{', '']
+            if self.canonical:
+                self.write_indicator(self.flow_map_separator, False)
+                self.write_indent()
+            if popped != '':
+                self.write_indicator(self.flow_map_end, False)
+            if self.event.comment and self.event.comment[0]:
+                # eol comment on flow mapping, never reached on empty mappings
+                self.write_post_comment(self.event)
+            else:
+                self.no_newline = False
+            self.state = self.states.pop()
+        else:
+            self.write_indicator(self.flow_map_separator, False)
+            if self.canonical or self.column > self.best_width:
+                self.write_indent()
+            if not self.canonical and self.check_simple_key():
+                self.states.append(self.expect_flow_mapping_simple_value)
+                self.expect_node(mapping=True, simple_key=True)
+            else:
+                self.write_indicator('?', True)
+                self.states.append(self.expect_flow_mapping_value)
+                self.expect_node(mapping=True)
+
+    def expect_flow_mapping_simple_value(self) -> None:
+        if getattr(self.event, 'style', '?') != '-':  # suppress for flow style sets
+            self.write_indicator(self.prefixed_colon, False)
+        self.states.append(self.expect_flow_mapping_key)
+        self.expect_node(mapping=True)
+
+    def expect_flow_mapping_value(self) -> None:
+        if self.canonical or self.column > self.best_width:
+            self.write_indent()
+        self.write_indicator(self.prefixed_colon, True)
+        self.states.append(self.expect_flow_mapping_key)
+        self.expect_node(mapping=True)
+
+    # Block sequence handlers.
+
+    def expect_block_sequence(self) -> None:
+        if self.mapping_context:
+            indentless = not self.indention
+        else:
+            indentless = False
+            if not self.compact_seq_seq and self.column != 0:
+                self.write_line_break()
+        self.increase_indent(flow=False, sequence=True, indentless=indentless)
+        self.state = self.expect_first_block_sequence_item
+
+    def expect_first_block_sequence_item(self) -> Any:
+        return self.expect_block_sequence_item(first=True)
+
+    def expect_block_sequence_item(self, first: bool = False) -> None:
+        if not first and isinstance(self.event, SequenceEndEvent):
+            if self.event.comment and self.event.comment[1]:
+                # final comments on a block list e.g. empty line
+                self.write_pre_comment(self.event)
+            self.indent = self.indents.pop()
+            self.state = self.states.pop()
+            self.no_newline = False
+        else:
+            if self.event.comment and self.event.comment[1]:
+                self.write_pre_comment(self.event)
+            nonl = self.no_newline if self.column == 0 else False
+            self.write_indent()
+            ind = self.sequence_dash_offset  # if  len(self.indents) > 1 else 0
+            self.write_indicator(' ' * ind + '-', True, indention=True)
+            if nonl or self.sequence_dash_offset + 2 > self.best_sequence_indent:
+                self.no_newline = True
+            self.states.append(self.expect_block_sequence_item)
+            self.expect_node(sequence=True)
+
+    # Block mapping handlers.
+
+    def expect_block_mapping(self) -> None:
+        if not self.mapping_context and not (self.compact_seq_map or self.column == 0):
+            self.write_line_break()
+        self.increase_indent(flow=False, sequence=False)
+        self.state = self.expect_first_block_mapping_key
+
+    def expect_first_block_mapping_key(self) -> None:
+        return self.expect_block_mapping_key(first=True)
+
+    def expect_block_mapping_key(self, first: Any = False) -> None:
+        if not first and isinstance(self.event, MappingEndEvent):
+            if self.event.comment and self.event.comment[1]:
+                # final comments from a doc
+                self.write_pre_comment(self.event)
+            self.indent = self.indents.pop()
+            self.state = self.states.pop()
+        else:
+            if self.event.comment and self.event.comment[1]:
+                # final comments from a doc
+                self.write_pre_comment(self.event)
+            self.write_indent()
+            if self.check_simple_key():
+                if not isinstance(
+                    self.event, (SequenceStartEvent, MappingStartEvent),
+                ):  # sequence keys
+                    try:
+                        if self.event.style == '?':
+                            self.write_indicator('?', True, indention=True)
+                    except AttributeError:  # aliases have no style
+                        pass
+                self.states.append(self.expect_block_mapping_simple_value)
+                self.expect_node(mapping=True, simple_key=True)
+                # test on style for alias in !!set
+                if isinstance(self.event, AliasEvent) and not self.event.style == '?':
+                    self.stream.write(' ')
+            else:
+                self.write_indicator('?', True, indention=True)
+                self.states.append(self.expect_block_mapping_value)
+                self.expect_node(mapping=True)
+
+    def expect_block_mapping_simple_value(self) -> None:
+        if getattr(self.event, 'style', None) != '?':
+            # prefix = ''
+            if self.indent == 0 and self.top_level_colon_align is not None:
+                # write non-prefixed colon
+                c = ' ' * (self.top_level_colon_align - self.column) + self.colon
+            else:
+                c = self.prefixed_colon
+            self.write_indicator(c, False)
+        self.states.append(self.expect_block_mapping_key)
+        self.expect_node(mapping=True)
+
+    def expect_block_mapping_value(self) -> None:
+        self.write_indent()
+        self.write_indicator(self.prefixed_colon, True, indention=True)
+        self.states.append(self.expect_block_mapping_key)
+        self.expect_node(mapping=True)
+
+    # Checkers.
+
+    def check_empty_sequence(self) -> bool:
+        return (
+            isinstance(self.event, SequenceStartEvent)
+            and bool(self.events)
+            and isinstance(self.events[0], SequenceEndEvent)
+        )
+
+    def check_empty_mapping(self) -> bool:
+        return (
+            isinstance(self.event, MappingStartEvent)
+            and bool(self.events)
+            and isinstance(self.events[0], MappingEndEvent)
+        )
+
+    def check_empty_document(self) -> bool:
+        if not isinstance(self.event, DocumentStartEvent) or not self.events:
+            return False
+        event = self.events[0]
+        return (
+            isinstance(event, ScalarEvent)
+            and event.anchor is None
+            and event.tag is None
+            and event.implicit
+            and event.value == ""
+        )
+
+    def check_simple_key(self) -> bool:
+        length = 0
+        if isinstance(self.event, NodeEvent) and self.event.anchor is not None:
+            if self.prepared_anchor is None:
+                self.prepared_anchor = self.prepare_anchor(self.event.anchor)
+            length += len(self.prepared_anchor)
+        if (
+            isinstance(self.event, (ScalarEvent, CollectionStartEvent))
+            and self.event.tag is not None
+        ):
+            if self.prepared_tag is None:
+                self.prepared_tag = self.prepare_tag(self.event.ctag)
+            length += len(self.prepared_tag)
+        if isinstance(self.event, ScalarEvent):
+            if self.analysis is None:
+                self.analysis = self.analyze_scalar(self.event.value)
+            length += len(self.analysis.scalar)
+        return length < self.MAX_SIMPLE_KEY_LENGTH and (
+            isinstance(self.event, AliasEvent)
+            or (isinstance(self.event, SequenceStartEvent) and self.event.flow_style is True)
+            or (isinstance(self.event, MappingStartEvent) and self.event.flow_style is True)
+            or (
+                isinstance(self.event, ScalarEvent)
+                # if there is an explicit style for an empty string, it is a simple key
+                and not (self.analysis.empty and self.style and self.style not in '\'"')
+                and not self.analysis.multiline
+            )
+            or self.check_empty_sequence()
+            or self.check_empty_mapping()
+        )
+
+    # Anchor, Tag, and Scalar processors.
+
+    def process_anchor(self, indicator: Any) -> bool:
+        if self.event.anchor is None:
+            self.prepared_anchor = None
+            return False
+        if self.prepared_anchor is None:
+            self.prepared_anchor = self.prepare_anchor(self.event.anchor)
+        if self.prepared_anchor:
+            self.write_indicator(indicator + self.prepared_anchor, True)
+            # issue 288
+            self.no_newline = False
+        self.prepared_anchor = None
+        return True
+
+    def process_tag(self) -> None:
+        tag = self.event.tag
+        if isinstance(self.event, ScalarEvent):
+            if self.style is None:
+                self.style = self.choose_scalar_style()
+                if (
+                    self.event.value == ''
+                    and self.style == "'"
+                    and tag == 'tag:yaml.org,2002:null'
+                    and self.alt_null is not None
+                ):
+                    self.event.value = self.alt_null
+                    self.analysis = None
+                    self.style = self.choose_scalar_style()
+            if (not self.canonical or tag is None) and (
+                (self.style == "" and self.event.implicit[0])
+                or (self.style != "" and self.event.implicit[1])
+            ):
+                self.prepared_tag = None
+                return
+            if self.event.implicit[0] and tag is None:
+                tag = '!'
+                self.prepared_tag = None
+        else:
+            if (not self.canonical or tag is None) and self.event.implicit:
+                self.prepared_tag = None
+                return
+        if tag is None:
+            raise EmitterError('tag is not specified')
+        if self.prepared_tag is None:
+            self.prepared_tag = self.prepare_tag(self.event.ctag)
+        if self.prepared_tag:
+            self.write_indicator(self.prepared_tag, True)
+            if (
+                self.sequence_context
+                and not self.flow_level
+                and isinstance(self.event, ScalarEvent)
+            ):
+                self.no_newline = True
+        self.prepared_tag = None
+
+    def choose_scalar_style(self) -> Any:
+        # issue 449 needs this otherwise emits single quoted empty string
+        if self.event.value == '' and self.event.ctag.handle == '!!':
+            return None
+        if self.analysis is None:
+            self.analysis = self.analyze_scalar(self.event.value)
+        if self.event.style == '"' or self.canonical:
+            return '"'
+        if (not self.event.style or self.event.style == '?' or self.event.style == '-') and (
+            self.event.implicit[0] or not self.event.implicit[2]
+        ):
+            if not (
+                self.simple_key_context and (self.analysis.empty or self.analysis.multiline)
+            ) and (
+                self.flow_level
+                and self.analysis.allow_flow_plain
+                or (not self.flow_level and self.analysis.allow_block_plain)
+            ):
+                return ""
+            if self.event.style == '-':
+                return ""
+        self.analysis.allow_block = True
+        if self.event.style and self.event.style in '|>':
+            if (
+                not self.flow_level
+                and not self.simple_key_context
+                and self.analysis.allow_block
+            ):
+                return self.event.style
+        if not self.event.style and self.analysis.allow_double_quoted:
+            if "'" in self.event.value or '\n' in self.event.value:
+                return '"'
+        if not self.event.style or self.event.style == "'":
+            if self.analysis.allow_single_quoted and not (
+                self.simple_key_context and self.analysis.multiline
+            ):
+                return "'"
+        return '"'
+
+    def process_scalar(self) -> None:
+        if self.analysis is None:
+            self.analysis = self.analyze_scalar(self.event.value)
+        if self.style is None:
+            self.style = self.choose_scalar_style()
+        split = not self.simple_key_context
+        # if self.analysis.multiline and split    \
+        #         and (not self.style or self.style in '\'\"'):
+        #     self.write_indent()
+        # nprint('xx', self.sequence_context, self.flow_level)
+        if self.sequence_context and not self.flow_level:
+            self.write_indent()
+        if self.style == '"':
+            self.write_double_quoted(self.analysis.scalar, split)
+        elif self.style == "'":
+            self.write_single_quoted(self.analysis.scalar, split)
+        elif self.style == '>':
+            try:
+                cmx = self.event.comment[1][0]
+            except (IndexError, TypeError) as e:  # NOQA
+                cmx = ""
+            self.write_folded(self.analysis.scalar, cmx)
+            if (
+                self.event.comment
+                and self.event.comment[0]
+                and self.event.comment[0].column >= self.indent
+            ):
+                # comment following a folded scalar must dedent (issue 376)
+                self.event.comment[0].column = self.indent - 1  # type: ignore
+        elif self.style == '|':
+            # self.write_literal(self.analysis.scalar, self.event.comment)
+            try:
+                cmx = self.event.comment[1][0]
+            except (IndexError, TypeError):
+                cmx = ""
+            self.write_literal(self.analysis.scalar, cmx)
+            if (
+                self.event.comment
+                and self.event.comment[0]
+                and self.event.comment[0].column >= self.indent
+            ):
+                # comment following a literal scalar must dedent (issue 376)
+                self.event.comment[0].column = self.indent - 1  # type: ignore
+        else:
+            self.write_plain(self.analysis.scalar, split)
+        self.analysis = None
+        self.style = None
+        if self.event.comment:
+            self.write_post_comment(self.event)
+
+    # Analyzers.
+
+    def prepare_version(self, version: Any) -> Any:
+        major, minor = version
+        if major != 1:
+            raise EmitterError(f'unsupported YAML version: {major:d}.{minor:d}')
+        return f'{major:d}.{minor:d}'
+
+    def prepare_tag_handle(self, handle: Any) -> Any:
+        if not handle:
+            raise EmitterError('tag handle must not be empty')
+        if handle[0] != '!' or handle[-1] != '!':
+            raise EmitterError(f"tag handle must start and end with '!': {handle!r}")
+        for ch in handle[1:-1]:
+            if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in '-_'):
+                raise EmitterError(f'invalid character {ch!r} in the tag handle: {handle!r}')
+        return handle
+
+    def prepare_tag_prefix(self, prefix: Any) -> Any:
+        if not prefix:
+            raise EmitterError('tag prefix must not be empty')
+        chunks: List[Any] = []
+        start = end = 0
+        if prefix[0] == '!':
+            end = 1
+        ch_set = "-;/?:@&=+$,_.~*'()[]"
+        if self.dumper:
+            version = getattr(self.dumper, 'version', (1, 2))
+            if version is None or version >= (1, 2):
+                ch_set += '#'
+        while end < len(prefix):
+            ch = prefix[end]
+            if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in ch_set:
+                end += 1
+            else:
+                if start < end:
+                    chunks.append(prefix[start:end])
+                start = end = end + 1
+                data = ch
+                for ch in data:
+                    chunks.append(f'%{ord(ch):02X}')
+        if start < end:
+            chunks.append(prefix[start:end])
+        return "".join(chunks)
+
+    def prepare_tag(self, tag: Any) -> Any:
+        if not tag:
+            raise EmitterError('tag must not be empty')
+        tag = str(tag)
+        if tag == '!' or tag == '!!':
+            return tag
+        handle = None
+        suffix = tag
+        prefixes = sorted(self.tag_prefixes.keys())
+        for prefix in prefixes:
+            if tag.startswith(prefix) and (prefix == '!' or len(prefix) < len(tag)):
+                handle = self.tag_prefixes[prefix]
+                suffix = tag[len(prefix) :]
+        chunks: List[Any] = []
+        start = end = 0
+        ch_set = "-;/?:@&=+$,_.~*'()[]"
+        if self.dumper:
+            version = getattr(self.dumper, 'version', (1, 2))
+            if version is None or version >= (1, 2):
+                ch_set += '#'
+        while end < len(suffix):
+            ch = suffix[end]
+            if (
+                '0' <= ch <= '9'
+                or 'A' <= ch <= 'Z'
+                or 'a' <= ch <= 'z'
+                or ch in ch_set
+                or (ch == '!' and handle != '!')
+            ):
+                end += 1
+            else:
+                if start < end:
+                    chunks.append(suffix[start:end])
+                start = end = end + 1
+                data = ch
+                for ch in data:
+                    chunks.append(f'%{ord(ch):02X}')
+        if start < end:
+            chunks.append(suffix[start:end])
+        suffix_text = "".join(chunks)
+        if handle:
+            return f'{handle!s}{suffix_text!s}'
+        else:
+            return f'!<{suffix_text!s}>'
+
+    def prepare_anchor(self, anchor: Any) -> Any:
+        if not anchor:
+            raise EmitterError('anchor must not be empty')
+        for ch in anchor:
+            if not check_anchorname_char(ch):
+                raise EmitterError(f'invalid character {ch!r} in the anchor: {anchor!r}')
+        return anchor
+
+    def analyze_scalar(self, scalar: Any) -> Any:
+        # Empty scalar is a special case.
+        if not scalar:
+            return ScalarAnalysis(
+                scalar=scalar,
+                empty=True,
+                multiline=False,
+                allow_flow_plain=False,
+                allow_block_plain=True,
+                allow_single_quoted=True,
+                allow_double_quoted=True,
+                allow_block=False,
+            )
+
+        # Indicators and special characters.
+        block_indicators = False
+        flow_indicators = False
+        line_breaks = False
+        special_characters = False
+
+        # Important whitespace combinations.
+        leading_space = False
+        leading_break = False
+        trailing_space = False
+        trailing_break = False
+        break_space = False
+        space_break = False
+
+        # Check document indicators.
+        if scalar.startswith('---') or scalar.startswith('...'):
+            block_indicators = True
+            flow_indicators = True
+
+        # First character or preceded by a whitespace.
+        preceeded_by_whitespace = True
+
+        # Last character or followed by a whitespace.
+        followed_by_whitespace = len(scalar) == 1 or scalar[1] in '\0 \t\r\n\x85\u2028\u2029'
+
+        # The previous character is a space.
+        previous_space = False
+
+        # The previous character is a break.
+        previous_break = False
+
+        index = 0
+        while index < len(scalar):
+            ch = scalar[index]
+
+            # Check for indicators.
+            if index == 0:
+                # Leading indicators are special characters.
+                if ch in '#,[]{}&*!|>\'"%@`':
+                    flow_indicators = True
+                    block_indicators = True
+                if ch in '?:':  # ToDo
+                    if self.serializer.use_version == (1, 1):
+                        flow_indicators = True
+                    elif len(scalar) == 1:  # single character
+                        flow_indicators = True
+                    if followed_by_whitespace:
+                        block_indicators = True
+                if ch == '-' and followed_by_whitespace:
+                    flow_indicators = True
+                    block_indicators = True
+            else:
+                # Some indicators cannot appear within a scalar as well.
+                if ch in ',[]{}':  # http://yaml.org/spec/1.2/spec.html#id2788859
+                    flow_indicators = True
+                if ch == '?' and self.serializer.use_version == (1, 1):
+                    flow_indicators = True
+                if ch == ':':
+                    if followed_by_whitespace:
+                        flow_indicators = True
+                        block_indicators = True
+                if ch == '#' and preceeded_by_whitespace:
+                    flow_indicators = True
+                    block_indicators = True
+
+            # Check for line breaks, special, and unicode characters.
+            if ch in '\n\x85\u2028\u2029':
+                line_breaks = True
+            if not (ch == '\n' or '\x20' <= ch <= '\x7E'):
+                if (
+                    ch == '\x85'
+                    or '\xA0' <= ch <= '\uD7FF'
+                    or '\uE000' <= ch <= '\uFFFD'
+                    or (self.unicode_supplementary and ('\U00010000' <= ch <= '\U0010FFFF'))
+                ) and ch != '\uFEFF':
+                    # unicode_characters = True
+                    if not self.allow_unicode:
+                        special_characters = True
+                else:
+                    special_characters = True
+
+            # Detect important whitespace combinations.
+            if ch == ' ':
+                if index == 0:
+                    leading_space = True
+                if index == len(scalar) - 1:
+                    trailing_space = True
+                if previous_break:
+                    break_space = True
+                previous_space = True
+                previous_break = False
+            elif ch in '\n\x85\u2028\u2029':
+                if index == 0:
+                    leading_break = True
+                if index == len(scalar) - 1:
+                    trailing_break = True
+                if previous_space:
+                    space_break = True
+                previous_space = False
+                previous_break = True
+            else:
+                previous_space = False
+                previous_break = False
+
+            # Prepare for the next character.
+            index += 1
+            preceeded_by_whitespace = ch in '\0 \t\r\n\x85\u2028\u2029'
+            followed_by_whitespace = (
+                index + 1 >= len(scalar) or scalar[index + 1] in '\0 \t\r\n\x85\u2028\u2029'
+            )
+
+        # Let's decide what styles are allowed.
+        allow_flow_plain = True
+        allow_block_plain = True
+        allow_single_quoted = True
+        allow_double_quoted = True
+        allow_block = True
+
+        # Leading and trailing whitespaces are bad for plain scalars.
+        if leading_space or leading_break or trailing_space or trailing_break:
+            allow_flow_plain = allow_block_plain = False
+
+        # We do not permit trailing spaces for block scalars.
+        if trailing_space:
+            allow_block = False
+
+        # Spaces at the beginning of a new line are only acceptable for block
+        # scalars.
+        if break_space:
+            allow_flow_plain = allow_block_plain = allow_single_quoted = False
+
+        # Spaces followed by breaks, as well as special character are only
+        # allowed for double quoted scalars.
+        if special_characters:
+            allow_flow_plain = allow_block_plain = allow_single_quoted = allow_block = False
+        elif space_break:
+            allow_flow_plain = allow_block_plain = allow_single_quoted = False
+            if not self.allow_space_break:
+                allow_block = False
+
+        # Although the plain scalar writer supports breaks, we never emit
+        # multiline plain scalars.
+        if line_breaks:
+            allow_flow_plain = allow_block_plain = False
+
+        # Flow indicators are forbidden for flow plain scalars.
+        if flow_indicators:
+            allow_flow_plain = False
+
+        # Block indicators are forbidden for block plain scalars.
+        if block_indicators:
+            allow_block_plain = False
+
+        return ScalarAnalysis(
+            scalar=scalar,
+            empty=False,
+            multiline=line_breaks,
+            allow_flow_plain=allow_flow_plain,
+            allow_block_plain=allow_block_plain,
+            allow_single_quoted=allow_single_quoted,
+            allow_double_quoted=allow_double_quoted,
+            allow_block=allow_block,
+        )
+
+    # Writers.
+
+    def flush_stream(self) -> None:
+        if hasattr(self.stream, 'flush'):
+            self.stream.flush()
+
+    def write_stream_start(self) -> None:
+        # Write BOM if needed.
+        if self.encoding and self.encoding.startswith('utf-16'):
+            self.stream.write('\uFEFF'.encode(self.encoding))
+
+    def write_stream_end(self) -> None:
+        self.flush_stream()
+
+    def write_indicator(
+        self,
+        indicator: Any,
+        need_whitespace: Any,
+        whitespace: bool = False,
+        indention: bool = False,
+    ) -> None:
+        if self.whitespace or not need_whitespace:
+            data = indicator
+        else:
+            data = ' ' + indicator
+        self.whitespace = whitespace
+        self.indention = self.indention and indention
+        self.column += len(data)
+        self.open_ended = False
+        if bool(self.encoding):
+            data = data.encode(self.encoding)
+        self.stream.write(data)
+
+    def write_indent(self) -> None:
+        indent = self.indent or 0
+        if (
+            not self.indention
+            or self.column > indent
+            or (self.column == indent and not self.whitespace)
+        ):
+            if bool(self.no_newline):
+                self.no_newline = False
+            else:
+                self.write_line_break()
+        if self.column < indent:
+            self.whitespace = True
+            data = ' ' * (indent - self.column)
+            self.column = indent
+            if self.encoding:
+                data = data.encode(self.encoding)  # type: ignore
+            self.stream.write(data)
+
+    def write_line_break(self, data: Any = None) -> None:
+        if data is None:
+            data = self.best_line_break
+        self.whitespace = True
+        self.indention = True
+        self.line += 1
+        self.column = 0
+        if bool(self.encoding):
+            data = data.encode(self.encoding)
+        self.stream.write(data)
+
+    def write_version_directive(self, version_text: Any) -> None:
+        data: Any = f'%YAML {version_text!s}'
+        if self.encoding:
+            data = data.encode(self.encoding)
+        self.stream.write(data)
+        self.write_line_break()
+
+    def write_tag_directive(self, handle_text: Any, prefix_text: Any) -> None:
+        data: Any = f'%TAG {handle_text!s} {prefix_text!s}'
+        if self.encoding:
+            data = data.encode(self.encoding)
+        self.stream.write(data)
+        self.write_line_break()
+
+    # Scalar streams.
+
+    def write_single_quoted(self, text: Any, split: Any = True) -> None:
+        if self.root_context:
+            if self.requested_indent is not None:
+                self.write_line_break()
+                if self.requested_indent != 0:
+                    self.write_indent()
+        self.write_indicator("'", True)
+        spaces = False
+        breaks = False
+        start = end = 0
+        while end <= len(text):
+            ch = None
+            if end < len(text):
+                ch = text[end]
+            if spaces:
+                if ch is None or ch != ' ':
+                    if (
+                        start + 1 == end
+                        and self.column > self.best_width
+                        and split
+                        and start != 0
+                        and end != len(text)
+                    ):
+                        self.write_indent()
+                    else:
+                        data = text[start:end]
+                        self.column += len(data)
+                        if bool(self.encoding):
+                            data = data.encode(self.encoding)
+                        self.stream.write(data)
+                    start = end
+            elif breaks:
+                if ch is None or ch not in '\n\x85\u2028\u2029':
+                    if text[start] == '\n':
+                        self.write_line_break()
+                    for br in text[start:end]:
+                        if br == '\n':
+                            self.write_line_break()
+                        else:
+                            self.write_line_break(br)
+                    self.write_indent()
+                    start = end
+            else:
+                if ch is None or ch in ' \n\x85\u2028\u2029' or ch == "'":
+                    if start < end:
+                        data = text[start:end]
+                        self.column += len(data)
+                        if bool(self.encoding):
+                            data = data.encode(self.encoding)
+                        self.stream.write(data)
+                        start = end
+            if ch == "'":
+                data = "''"
+                self.column += 2
+                if bool(self.encoding):
+                    data = data.encode(self.encoding)
+                self.stream.write(data)
+                start = end + 1
+            if ch is not None:
+                spaces = ch == ' '
+                breaks = ch in '\n\x85\u2028\u2029'
+            end += 1
+        self.write_indicator("'", False)
+
+    ESCAPE_REPLACEMENTS = {
+        '\0': '0',
+        '\x07': 'a',
+        '\x08': 'b',
+        '\x09': 't',
+        '\x0A': 'n',
+        '\x0B': 'v',
+        '\x0C': 'f',
+        '\x0D': 'r',
+        '\x1B': 'e',
+        '"': '"',
+        '\\': '\\',
+        '\x85': 'N',
+        '\xA0': '_',
+        '\u2028': 'L',
+        '\u2029': 'P',
+    }
+
+    def write_double_quoted(self, text: Any, split: Any = True) -> None:
+        """
+        a newline, as written by self.write_indent(), might need to be escaped with a backslash
+        as on reading this will produce a possibly unwanted space.
+        """
+        if self.root_context:
+            if self.requested_indent is not None:
+                self.write_line_break()
+                if self.requested_indent != 0:
+                    self.write_indent()
+        self.write_indicator('"', True)
+        start = end = 0
+        while end <= len(text):
+            ch = None
+            if end < len(text):
+                ch = text[end]
+            if (
+                ch is None
+                or ch in '"\\\x85\u2028\u2029\uFEFF'
+                or not (
+                    '\x20' <= ch <= '\x7E'
+                    or (
+                        self.allow_unicode
+                        and (
+                            ('\xA0' <= ch <= '\uD7FF')
+                            or ('\uE000' <= ch <= '\uFFFD')
+                            or ('\U00010000' <= ch <= '\U0010FFFF')
+                        )
+                    )
+                )
+            ):
+                if start < end:
+                    data = text[start:end]
+                    self.column += len(data)
+                    if bool(self.encoding):
+                        data = data.encode(self.encoding)
+                    self.stream.write(data)
+                    start = end
+                if ch is not None:
+                    if ch in self.ESCAPE_REPLACEMENTS:
+                        data = '\\' + self.ESCAPE_REPLACEMENTS[ch]
+                    elif ch <= '\xFF':
+                        data = '\\x%02X' % ord(ch)
+                    elif ch <= '\uFFFF':
+                        data = '\\u%04X' % ord(ch)
+                    else:
+                        data = '\\U%08X' % ord(ch)
+                    self.column += len(data)
+                    if bool(self.encoding):
+                        data = data.encode(self.encoding)
+                    self.stream.write(data)
+                    start = end + 1
+            if (
+                0 < end < len(text) - 1
+                and (ch == ' ' or start >= end)
+                and self.column + (end - start) > self.best_width
+                and split
+            ):
+                # SO https://stackoverflow.com/a/75634614/1307905
+                # data = text[start:end] + u'\\'  # <<< replaced with following lines
+                need_backslash = True
+                if len(text) > end:
+                    try:
+                        space_pos = text.index(' ', end)
+                        try:
+                            space_pos = text.index('\n', end, space_pos)
+                        except (ValueError, IndexError):
+                            pass
+                        # nprint('backslash?', space_pos, repr(text[:space_pos]), repr(text[space_pos:]), (text[space_pos] == '\n' and text[space_pos+1] == ' '))  # NOQA
+                        if (text[space_pos] == '\n' and text[space_pos + 1] != ' '):
+                            pass
+                        elif (
+                            '"' not in text[end:space_pos]
+                            and "'" not in text[end:space_pos]
+                            # and text[space_pos + 1] != ' '
+                            and text[space_pos + 1] not in ' \n'
+                            and text[end - 1 : end + 1] != '  '
+                            and start != end
+                        ):
+                            need_backslash = False
+                    except (ValueError, IndexError):
+                        pass
+                data = text[start:end] + ('\\' if need_backslash else '')
+                if start < end:
+                    start = end
+                self.column += len(data)
+                if bool(self.encoding):
+                    data = data.encode(self.encoding)
+                self.stream.write(data)
+                self.write_indent()
+                self.whitespace = False
+                self.indention = False
+                if text[start] == ' ':
+                    if not need_backslash:
+                        # remove leading space it will load from the newline
+                        start += 1
+                    # data = u'\\'    # <<< replaced with following line
+                    data = '\\' if need_backslash else ''
+                    self.column += len(data)
+                    if bool(self.encoding):
+                        data = data.encode(self.encoding)
+                    self.stream.write(data)
+            end += 1
+        self.write_indicator('"', False)
+
+    def determine_block_hints(self, text: Any) -> Any:
+        indent = 0
+        indicator = ''
+        hints = ''
+        if text:
+            if text[0] in ' \n\x85\u2028\u2029':
+                indent = 2
+                hints += str(indent)
+            elif self.root_context:
+                for end in ['---', '...']:
+                    position = -1
+                    pos = 0
+                    while position == -1:
+                        pos = text.find(end, pos)
+                        if pos == -1:
+                            break
+                        if pos != 0:
+                            if text[pos - 1] != '\n':
+                                pos += 1
+                                continue
+                        try:
+                            if text[pos + len(end)] in ' \r\n':
+                                position = pos
+                                break
+                        except IndexError:
+                            pass
+                        pos += 1
+                    if position != -1:
+                        break
+                if position != -1:
+                    indent = 2
+            if text[-1] not in '\n\x85\u2028\u2029':
+                indicator = '-'
+            elif len(text) == 1 or text[-2] in '\n\x85\u2028\u2029':
+                indicator = '+'
+        hints += indicator
+        return hints, indent, indicator
+
+    def write_folded(self, text: Any, comment: Any) -> None:
+        hints, _indent, _indicator = self.determine_block_hints(text)
+        if not isinstance(comment, str):
+            comment = ''
+        self.write_indicator('>' + hints + comment, True)
+        if _indicator == '+':
+            self.open_ended = True
+        self.write_line_break()
+        leading_space = True
+        spaces = False
+        breaks = True
+        start = end = 0
+        while end <= len(text):
+            ch = None
+            if end < len(text):
+                ch = text[end]
+            if breaks:
+                if ch is None or ch not in '\n\x85\u2028\u2029\a':
+                    if (
+                        not leading_space
+                        and ch is not None
+                        and ch != ' '
+                        and text[start] == '\n'
+                    ):
+                        self.write_line_break()
+                    leading_space = ch == ' '
+                    for br in text[start:end]:
+                        if br == '\n':
+                            self.write_line_break()
+                        else:
+                            self.write_line_break(br)
+                    if ch is not None:
+                        self.write_indent()
+                    start = end
+            elif spaces:
+                if ch != ' ':
+                    if start + 1 == end and self.column > self.best_width:
+                        self.write_indent()
+                    else:
+                        data = text[start:end]
+                        self.column += len(data)
+                        if bool(self.encoding):
+                            data = data.encode(self.encoding)
+                        self.stream.write(data)
+                    start = end
+            else:
+                if ch is None or ch in ' \n\x85\u2028\u2029\a':
+                    data = text[start:end]
+                    self.column += len(data)
+                    if bool(self.encoding):
+                        data = data.encode(self.encoding)
+                    self.stream.write(data)
+                    if ch == '\a':
+                        if end < (len(text) - 1) and not text[end + 2].isspace():
+                            self.write_line_break()
+                            self.write_indent()
+                            end += 2  # \a and the space that is inserted on the fold
+                        else:
+                            raise EmitterError('unexcpected fold indicator \\a before space')
+                    if ch is None:
+                        self.write_line_break()
+                    start = end
+            if ch is not None:
+                breaks = ch in '\n\x85\u2028\u2029'
+                spaces = ch == ' '
+            end += 1
+
+    def write_literal(self, text: Any, comment: Any = None) -> None:
+        hints, _indent, _indicator = self.determine_block_hints(text)
+        # if comment is not None:
+        #    try:
+        #        hints += comment[1][0]
+        #    except (TypeError, IndexError) as e:
+        #        pass
+        if not isinstance(comment, str):
+            comment = ''
+        self.write_indicator('|' + hints + comment, True)
+        # try:
+        #    nprintf('selfev', comment)
+        #    cmx = comment[1][0]
+        #    if cmx:
+        #        self.stream.write(cmx)
+        # except (TypeError, IndexError) as e:
+        #    pass
+        if _indicator == '+':
+            self.open_ended = True
+        self.write_line_break()
+        breaks = True
+        start = end = 0
+        while end <= len(text):
+            ch = None
+            if end < len(text):
+                ch = text[end]
+            if breaks:
+                if ch is None or ch not in '\n\x85\u2028\u2029':
+                    for br in text[start:end]:
+                        if br == '\n':
+                            self.write_line_break()
+                        else:
+                            self.write_line_break(br)
+                    if ch is not None:
+                        if self.root_context:
+                            idnx = self.indent if self.indent is not None else 0
+                            self.stream.write(' ' * (_indent + idnx))
+                        else:
+                            self.write_indent()
+                    start = end
+            else:
+                if ch is None or ch in '\n\x85\u2028\u2029':
+                    data = text[start:end]
+                    if bool(self.encoding):
+                        data = data.encode(self.encoding)
+                    self.stream.write(data)
+                    if ch is None:
+                        self.write_line_break()
+                    start = end
+            if ch is not None:
+                breaks = ch in '\n\x85\u2028\u2029'
+            end += 1
+
+    def write_plain(self, text: Any, split: Any = True) -> None:
+        if self.root_context:
+            if self.requested_indent is not None:
+                self.write_line_break()
+                if self.requested_indent != 0:
+                    self.write_indent()
+            else:
+                self.open_ended = True
+        if not text:
+            return
+        if not self.whitespace:
+            data = ' '
+            self.column += len(data)
+            if self.encoding:
+                data = data.encode(self.encoding)  # type: ignore
+            self.stream.write(data)
+        self.whitespace = False
+        self.indention = False
+        spaces = False
+        breaks = False
+        start = end = 0
+        while end <= len(text):
+            # ToDo: there is an empty space at the end of the wrapped line, if that line
+            # does not exceed self.best_width, that space is superfluous if wrapping is on
+            ch = None
+            if end < len(text):
+                ch = text[end]
+            if spaces:
+                if ch != ' ':
+                    if start + 1 == end and self.column >= self.best_width and split:
+                        self.write_indent()
+                        self.whitespace = False
+                        self.indention = False
+                    else:
+                        data = text[start:end]
+                        self.column += len(data)
+                        if self.encoding:
+                            data = data.encode(self.encoding)  # type: ignore
+                        self.stream.write(data)
+                    start = end
+            elif breaks:
+                if ch not in '\n\x85\u2028\u2029':  # type: ignore
+                    if text[start] == '\n':
+                        self.write_line_break()
+                    for br in text[start:end]:
+                        if br == '\n':
+                            self.write_line_break()
+                        else:
+                            self.write_line_break(br)
+                    self.write_indent()
+                    self.whitespace = False
+                    self.indention = False
+                    start = end
+            else:
+                if ch is None or ch in ' \n\x85\u2028\u2029':
+                    data = text[start:end]
+                    if (
+                        (len(data) + self.column) > self.best_width
+                        and self.indent is not None
+                        and self.column > self.indent
+                    ):
+                        # words longer than line length get a line of their own
+                        self.write_indent()
+                    self.column += len(data)
+                    if self.encoding:
+                        data = data.encode(self.encoding)  # type: ignore
+                    try:
+                        self.stream.write(data)
+                    except:  # NOQA
+                        sys.stdout.write(repr(data) + '\n')
+                        raise
+                    start = end
+            if ch is not None:
+                spaces = ch == ' '
+                breaks = ch in '\n\x85\u2028\u2029'
+            end += 1
+
+    def write_comment(self, comment: Any, pre: bool = False) -> None:
+        value = comment.value
+        # nprintf(f'{self.column:02d} {comment.start_mark.column:02d} {value!r}')
+        if not pre and value[-1] == '\n':
+            value = value[:-1]
+        try:
+            # get original column position
+            col = comment.start_mark.column
+            if comment.value and comment.value.startswith('\n'):
+                # never inject extra spaces if the comment starts with a newline
+                # and not a real comment (e.g. if you have an empty line following a key-value
+                col = self.column
+            elif col < self.column + 1:
+                ValueError
+        except ValueError:
+            col = self.column + 1
+        # nprint('post_comment', self.line, self.column, value)
+        try:
+            # at least one space if the current column >= the start column of the comment
+            # but not at the start of a line
+            nr_spaces = col - self.column
+            if self.column and value.strip() and nr_spaces < 1 and value[0] != '\n':
+                nr_spaces = 1
+            value = ' ' * nr_spaces + value
+            try:
+                if bool(self.encoding):
+                    value = value.encode(self.encoding)
+            except UnicodeDecodeError:
+                pass
+            self.stream.write(value)
+        except TypeError:
+            raise
+        if not pre:
+            self.write_line_break()
+
+    def write_pre_comment(self, event: Any) -> bool:
+        if event.comment is None:
+            return False
+        comments = event.comment[1]
+        if comments is None:
+            return False
+        try:
+            start_events = (MappingStartEvent, SequenceStartEvent)
+            for comment in comments:
+                if isinstance(event, start_events) and getattr(comment, 'pre_done', None):
+                    continue
+                if self.column != 0:
+                    self.write_line_break()
+                self.write_comment(comment, pre=True)
+                if isinstance(event, start_events):
+                    comment.pre_done = True
+        except TypeError:
+            sys.stdout.write(f'eventtt {type(event)} {event}')
+            raise
+        return True
+
+    def write_post_comment(self, event: Any) -> bool:
+        if self.event.comment[0] is None:
+            return False
+        comment = event.comment[0]
+        self.write_comment(comment)
+        return True
+
+
+class RoundTripEmitter(Emitter):
+    def prepare_tag(self, ctag: Any) -> Any:
+        if not ctag:
+            raise EmitterError('tag must not be empty')
+        tag = str(ctag)
+        if tag == '!' or tag == '!!':
+            return tag
+        handle = ctag.handle
+        suffix = ctag.suffix
+        prefixes = sorted(self.tag_prefixes.keys())
+        # print('handling', repr(tag), repr(suffix), repr(handle))
+        if handle is None:
+            for prefix in prefixes:
+                if tag.startswith(prefix) and (prefix == '!' or len(prefix) < len(tag)):
+                    handle = self.tag_prefixes[prefix]
+                    suffix = suffix[len(prefix) :]
+        if handle:
+            return f'{handle!s}{suffix!s}'
+        else:
+            return f'!<{suffix!s}>'
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py
new file mode 100644
index 00000000000..1f1e1f5b6b8
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py
@@ -0,0 +1,328 @@
+
+from __future__ import annotations
+
+import warnings
+# import textwrap
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Text  # NOQA
+
+
+__all__ = [
+    'FileMark',
+    'StringMark',
+    'CommentMark',
+    'YAMLError',
+    'MarkedYAMLError',
+    'ReusedAnchorWarning',
+    'UnsafeLoaderWarning',
+    'MarkedYAMLWarning',
+    'MarkedYAMLFutureWarning',
+]
+
+
+class StreamMark:
+    __slots__ = 'name', 'index', 'line', 'column'
+
+    def __init__(self, name: Any, index: int, line: int, column: int) -> None:
+        self.name = name
+        self.index = index
+        self.line = line
+        self.column = column
+
+    def __str__(self) -> Any:
+        where = f'  in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
+        return where
+
+    def __eq__(self, other: Any) -> bool:
+        if self.line != other.line or self.column != other.column:
+            return False
+        if self.name != other.name or self.index != other.index:
+            return False
+        return True
+
+    def __ne__(self, other: Any) -> bool:
+        return not self.__eq__(other)
+
+
+class FileMark(StreamMark):
+    __slots__ = ()
+
+
+class StringMark(StreamMark):
+    __slots__ = 'name', 'index', 'line', 'column', 'buffer', 'pointer'
+
+    def __init__(
+        self, name: Any, index: int, line: int, column: int, buffer: Any, pointer: Any,
+    ) -> None:
+        StreamMark.__init__(self, name, index, line, column)
+        self.buffer = buffer
+        self.pointer = pointer
+
+    def get_snippet(self, indent: int = 4, max_length: int = 75) -> Any:
+        if self.buffer is None:  # always False
+            return None
+        head = ""
+        start = self.pointer
+        while start > 0 and self.buffer[start - 1] not in '\0\r\n\x85\u2028\u2029':
+            start -= 1
+            if self.pointer - start > max_length / 2 - 1:
+                head = ' ... '
+                start += 5
+                break
+        tail = ""
+        end = self.pointer
+        while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029':
+            end += 1
+            if end - self.pointer > max_length / 2 - 1:
+                tail = ' ... '
+                end -= 5
+                break
+        snippet = self.buffer[start:end]
+        caret = '^'
+        caret = f'^ (line: {self.line + 1})'
+        return (
+            ' ' * indent
+            + head
+            + snippet
+            + tail
+            + '\n'
+            + ' ' * (indent + self.pointer - start + len(head))
+            + caret
+        )
+
+    def __str__(self) -> Any:
+        snippet = self.get_snippet()
+        where = f'  in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
+        if snippet is not None:
+            where += ':\n' + snippet
+        return where
+
+    def __repr__(self) -> Any:
+        snippet = self.get_snippet()
+        where = f'  in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
+        if snippet is not None:
+            where += ':\n' + snippet
+        return where
+
+
+class CommentMark:
+    __slots__ = ('column',)
+
+    def __init__(self, column: Any) -> None:
+        self.column = column
+
+
+class YAMLError(Exception):
+    pass
+
+
+class MarkedYAMLError(YAMLError):
+    def __init__(  # NOQA
+        self,
+        context: Any = None,
+        context_mark: Any = None,
+        problem: Any = None,
+        problem_mark: Any = None,
+        note: Any = None,
+        warn: Any = None,
+    ) -> None:
+        self.context = context
+        self.context_mark = context_mark
+        self.problem = problem
+        self.problem_mark = problem_mark
+        self.note = note
+        # warn is ignored
+
+    def __str__(self) -> Any:
+        lines: list[str] = []
+        if self.context is not None:
+            lines.append(self.context)
+        if self.context_mark is not None and (
+            self.problem is None
+            or self.problem_mark is None
+            or self.context_mark.name != self.problem_mark.name
+            or self.context_mark.line != self.problem_mark.line
+            or self.context_mark.column != self.problem_mark.column
+        ):
+            lines.append(str(self.context_mark))
+        if self.problem is not None:
+            lines.append(self.problem)
+        if self.problem_mark is not None:
+            lines.append(str(self.problem_mark))
+        # if self.note is not None and self.note:
+        #     note = textwrap.dedent(self.note)
+        #     lines.append(note)
+        self.check_append(lines, self.note)
+        return '\n'.join(lines)
+
+    def check_append(self, lines: list[str], val: Optional[str]) -> None:
+        if val is None or not val:
+            return
+        import textwrap
+
+        note = textwrap.dedent(val)
+        lines.append(note)
+
+
+class YAMLStreamError(Exception):
+    pass
+
+
+class YAMLWarning(Warning):
+    pass
+
+
+class MarkedYAMLWarning(YAMLWarning):
+    def __init__(  # NOQA
+        self,
+        context: Any = None,
+        context_mark: Any = None,
+        problem: Any = None,
+        problem_mark: Any = None,
+        note: Any = None,
+        warn: Any = None,
+    ) -> None:
+        self.context = context
+        self.context_mark = context_mark
+        self.problem = problem
+        self.problem_mark = problem_mark
+        self.note = note
+        self.warn = warn
+
+    def __str__(self) -> Any:
+        lines: List[str] = []
+        if self.context is not None:
+            lines.append(self.context)
+        if self.context_mark is not None and (
+            self.problem is None
+            or self.problem_mark is None
+            or self.context_mark.name != self.problem_mark.name
+            or self.context_mark.line != self.problem_mark.line
+            or self.context_mark.column != self.problem_mark.column
+        ):
+            lines.append(str(self.context_mark))
+        if self.problem is not None:
+            lines.append(self.problem)
+        if self.problem_mark is not None:
+            lines.append(str(self.problem_mark))
+        # if self.note is not None and self.note:
+        #     note = textwrap.dedent(self.note)
+        #     lines.append(note)
+        self.check_append(lines, self.note)
+        # if self.warn is not None and self.warn:
+        #     warn = textwrap.dedent(self.warn)
+        #     lines.append(warn)
+        self.check_append(lines, self.warn)
+        return '\n'.join(lines)
+
+    def check_append(self, lines: list[str], val: Optional[str]) -> None:
+        if val is None or not val:
+            return
+        import textwrap
+
+        note = textwrap.dedent(val)
+        lines.append(note)
+
+
+class ReusedAnchorWarning(YAMLWarning):
+    pass
+
+
+class UnsafeLoaderWarning(YAMLWarning):
+    text = """
+The default 'Loader' for 'load(stream)' without further arguments can be unsafe.
+Use 'load(stream, Loader=ruamel.yaml.Loader)' explicitly if that is OK.
+Alternatively include the following in your code:
+
+  import warnings
+  warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)
+
+In most other cases you should consider using 'safe_load(stream)'"""
+    pass
+
+
+warnings.simplefilter('once', UnsafeLoaderWarning)
+
+
+class MantissaNoDotYAML1_1Warning(YAMLWarning):
+    def __init__(self, node: Any, flt_str: Any) -> None:  # NOQA
+        self.node = node
+        self.flt = flt_str
+
+    def __str__(self) -> Any:
+        line = self.node.start_mark.line
+        col = self.node.start_mark.column
+        return f"""
+In YAML 1.1 floating point values should have a dot ('.') in their mantissa.
+See the Floating-Point Language-Independent Type for YAML™ Version 1.1 specification
+( http://yaml.org/type/float.html ). This dot is not required for JSON nor for YAML 1.2
+
+Correct your float: "{self.flt}" on line: {line}, column: {col}
+
+or alternatively include the following in your code:
+
+  import warnings
+  warnings.simplefilter('ignore', ruamel.yaml.error.MantissaNoDotYAML1_1Warning)
+
+"""
+
+
+warnings.simplefilter('once', MantissaNoDotYAML1_1Warning)
+
+
+class YAMLFutureWarning(Warning):
+    pass
+
+
+class MarkedYAMLFutureWarning(YAMLFutureWarning):
+    def __init__(  # NOQA
+        self,
+        context: Any = None,
+        context_mark: Any = None,
+        problem: Any = None,
+        problem_mark: Any = None,
+        note: Any = None,
+        warn: Any = None,
+    ) -> None:
+        self.context = context
+        self.context_mark = context_mark
+        self.problem = problem
+        self.problem_mark = problem_mark
+        self.note = note
+        self.warn = warn
+
+    def __str__(self) -> Any:
+        lines: List[str] = []
+        if self.context is not None:
+            lines.append(self.context)
+
+        if self.context_mark is not None and (
+            self.problem is None
+            or self.problem_mark is None
+            or self.context_mark.name != self.problem_mark.name
+            or self.context_mark.line != self.problem_mark.line
+            or self.context_mark.column != self.problem_mark.column
+        ):
+            lines.append(str(self.context_mark))
+        if self.problem is not None:
+            lines.append(self.problem)
+        if self.problem_mark is not None:
+            lines.append(str(self.problem_mark))
+        # if self.note is not None and self.note:
+        #     note = textwrap.dedent(self.note)
+        #     lines.append(note)
+        self.check_append(lines, self.note)
+        # if self.warn is not None and self.warn:
+        #     warn = textwrap.dedent(self.warn)
+        #     lines.append(warn)
+        self.check_append(lines, self.warn)
+        return '\n'.join(lines)
+
+    def check_append(self, lines: list[str], val: Optional[str]) -> None:
+        if val is None or not val:
+            return
+        import textwrap
+
+        note = textwrap.dedent(val)
+        lines.append(note)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py
new file mode 100644
index 00000000000..cc61c9ea50b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py
@@ -0,0 +1,266 @@
+
+from __future__ import annotations
+
+# Abstract classes.
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
+
+SHOW_LINES = False
+
+
+def CommentCheck() -> None:
+    pass
+
+
+class Event:
+    __slots__ = 'start_mark', 'end_mark', 'comment'
+    crepr = 'Unspecified Event'
+
+    def __init__(
+        self, start_mark: Any = None, end_mark: Any = None, comment: Any = CommentCheck,
+    ) -> None:
+        self.start_mark = start_mark
+        self.end_mark = end_mark
+        # assert comment is not CommentCheck
+        if comment is CommentCheck:
+            comment = None
+        self.comment = comment
+
+    def __repr__(self) -> Any:
+        if True:
+            arguments = []
+            if hasattr(self, 'value'):
+                # if you use repr(getattr(self, 'value')) then flake8 complains about
+                # abuse of getattr with a constant. When you change to self.value
+                # then mypy throws an error
+                arguments.append(repr(self.value))
+            for key in ['anchor', 'tag', 'implicit', 'flow_style', 'style']:
+                v = getattr(self, key, None)
+                if v is not None:
+                    arguments.append(f'{key!s}={v!r}')
+            if self.comment not in [None, CommentCheck]:
+                arguments.append(f'comment={self.comment!r}')
+            if SHOW_LINES:
+                arguments.append(
+                    f'({self.start_mark.line}:{self.start_mark.column}/'
+                    f'{self.end_mark.line}:{self.end_mark.column})',
+                )
+            arguments = ', '.join(arguments)  # type: ignore
+        else:
+            attributes = [
+                key
+                for key in ['anchor', 'tag', 'implicit', 'value', 'flow_style', 'style']
+                if hasattr(self, key)
+            ]
+            arguments = ', '.join([f'{key!s}={getattr(self, key)!r}' for key in attributes])
+            if self.comment not in [None, CommentCheck]:
+                arguments += f', comment={self.comment!r}'
+        return f'{self.__class__.__name__!s}({arguments!s})'
+
+    def compact_repr(self) -> str:
+        return f'{self.crepr}'
+
+
+class NodeEvent(Event):
+    __slots__ = ('anchor',)
+
+    def __init__(
+        self, anchor: Any, start_mark: Any = None, end_mark: Any = None, comment: Any = None,
+    ) -> None:
+        Event.__init__(self, start_mark, end_mark, comment)
+        self.anchor = anchor
+
+
+class CollectionStartEvent(NodeEvent):
+    __slots__ = 'ctag', 'implicit', 'flow_style', 'nr_items'
+
+    def __init__(
+        self,
+        anchor: Any,
+        tag: Any,
+        implicit: Any,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        flow_style: Any = None,
+        comment: Any = None,
+        nr_items: Optional[int] = None,
+    ) -> None:
+        NodeEvent.__init__(self, anchor, start_mark, end_mark, comment)
+        self.ctag = tag
+        self.implicit = implicit
+        self.flow_style = flow_style
+        self.nr_items = nr_items
+
+    @property
+    def tag(self) -> Optional[str]:
+        return None if self.ctag is None else str(self.ctag)
+
+
+class CollectionEndEvent(Event):
+    __slots__ = ()
+
+
+# Implementations.
+
+
+class StreamStartEvent(Event):
+    __slots__ = ('encoding',)
+    crepr = '+STR'
+
+    def __init__(
+        self,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        encoding: Any = None,
+        comment: Any = None,
+    ) -> None:
+        Event.__init__(self, start_mark, end_mark, comment)
+        self.encoding = encoding
+
+
+class StreamEndEvent(Event):
+    __slots__ = ()
+    crepr = '-STR'
+
+
+class DocumentStartEvent(Event):
+    __slots__ = 'explicit', 'version', 'tags'
+    crepr = '+DOC'
+
+    def __init__(
+        self,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        explicit: Any = None,
+        version: Any = None,
+        tags: Any = None,
+        comment: Any = None,
+    ) -> None:
+        Event.__init__(self, start_mark, end_mark, comment)
+        self.explicit = explicit
+        self.version = version
+        self.tags = tags
+
+    def compact_repr(self) -> str:
+        start = ' ---' if self.explicit else ''
+        return f'{self.crepr}{start}'
+
+
+class DocumentEndEvent(Event):
+    __slots__ = ('explicit',)
+    crepr = '-DOC'
+
+    def __init__(
+        self,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        explicit: Any = None,
+        comment: Any = None,
+    ) -> None:
+        Event.__init__(self, start_mark, end_mark, comment)
+        self.explicit = explicit
+
+    def compact_repr(self) -> str:
+        end = ' ...' if self.explicit else ''
+        return f'{self.crepr}{end}'
+
+
+class AliasEvent(NodeEvent):
+    __slots__ = 'style'
+    crepr = '=ALI'
+
+    def __init__(
+        self,
+        anchor: Any,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        style: Any = None,
+        comment: Any = None,
+    ) -> None:
+        NodeEvent.__init__(self, anchor, start_mark, end_mark, comment)
+        self.style = style
+
+    def compact_repr(self) -> str:
+        return f'{self.crepr} *{self.anchor}'
+
+
+class ScalarEvent(NodeEvent):
+    __slots__ = 'ctag', 'implicit', 'value', 'style'
+    crepr = '=VAL'
+
+    def __init__(
+        self,
+        anchor: Any,
+        tag: Any,
+        implicit: Any,
+        value: Any,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        style: Any = None,
+        comment: Any = None,
+    ) -> None:
+        NodeEvent.__init__(self, anchor, start_mark, end_mark, comment)
+        self.ctag = tag
+        self.implicit = implicit
+        self.value = value
+        self.style = style
+
+    @property
+    def tag(self) -> Optional[str]:
+        return None if self.ctag is None else str(self.ctag)
+
+    @tag.setter
+    def tag(self, val: Any) -> None:
+        if isinstance(val, str):
+            val = Tag(suffix=val)
+        self.ctag = val
+
+    def compact_repr(self) -> str:
+        style = ':' if self.style is None else self.style
+        anchor = f'&{self.anchor} ' if self.anchor else ''
+        tag = f'<{self.tag!s}> ' if self.tag else ''
+        value = self.value
+        for ch, rep in [
+            ('\\', '\\\\'),
+            ('\t', '\\t'),
+            ('\n', '\\n'),
+            ('\a', ''),  # remove from folded
+            ('\r', '\\r'),
+            ('\b', '\\b'),
+        ]:
+            value = value.replace(ch, rep)
+        return f'{self.crepr} {anchor}{tag}{style}{value}'
+
+
+class SequenceStartEvent(CollectionStartEvent):
+    __slots__ = ()
+    crepr = '+SEQ'
+
+    def compact_repr(self) -> str:
+        flow = ' []' if self.flow_style else ''
+        anchor = f' &{self.anchor}' if self.anchor else ''
+        tag = f' <{self.tag!s}>' if self.tag else ''
+        return f'{self.crepr}{flow}{anchor}{tag}'
+
+
+class SequenceEndEvent(CollectionEndEvent):
+    __slots__ = ()
+    crepr = '-SEQ'
+
+
+class MappingStartEvent(CollectionStartEvent):
+    __slots__ = ()
+    crepr = '+MAP'
+
+    def compact_repr(self) -> str:
+        flow = ' {}' if self.flow_style else ''
+        anchor = f' &{self.anchor}' if self.anchor else ''
+        tag = f' <{self.tag!s}>' if self.tag else ''
+        return f'{self.crepr}{flow}{anchor}{tag}'
+
+
+class MappingEndEvent(CollectionEndEvent):
+    __slots__ = ()
+    crepr = '-MAP'
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py
new file mode 100644
index 00000000000..07c6febc0e7
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py
@@ -0,0 +1,92 @@
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.reader import Reader
+from opentelemetry.agent._vendor.ruamel.yaml.scanner import Scanner, RoundTripScanner
+from opentelemetry.agent._vendor.ruamel.yaml.parser import Parser, RoundTripParser
+from opentelemetry.agent._vendor.ruamel.yaml.composer import Composer
+from opentelemetry.agent._vendor.ruamel.yaml.constructor import (
+    BaseConstructor,
+    SafeConstructor,
+    Constructor,
+    RoundTripConstructor,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.resolver import VersionedResolver
+
+if False:  # MYPY
+    from typing import Any, Dict, List, Union, Optional  # NOQA
+    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamTextType, VersionType  # NOQA
+
+__all__ = ['BaseLoader', 'SafeLoader', 'Loader', 'RoundTripLoader']
+
+
+class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, VersionedResolver):
+    def __init__(
+        self,
+        stream: StreamTextType,
+        version: Optional[VersionType] = None,
+        preserve_quotes: Optional[bool] = None,
+    ) -> None:
+        self.comment_handling = None
+        Reader.__init__(self, stream, loader=self)
+        Scanner.__init__(self, loader=self)
+        Parser.__init__(self, loader=self)
+        Composer.__init__(self, loader=self)
+        BaseConstructor.__init__(self, loader=self)
+        VersionedResolver.__init__(self, version, loader=self)
+
+
+class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, VersionedResolver):
+    def __init__(
+        self,
+        stream: StreamTextType,
+        version: Optional[VersionType] = None,
+        preserve_quotes: Optional[bool] = None,
+    ) -> None:
+        self.comment_handling = None
+        Reader.__init__(self, stream, loader=self)
+        Scanner.__init__(self, loader=self)
+        Parser.__init__(self, loader=self)
+        Composer.__init__(self, loader=self)
+        SafeConstructor.__init__(self, loader=self)
+        VersionedResolver.__init__(self, version, loader=self)
+
+
+class Loader(Reader, Scanner, Parser, Composer, Constructor, VersionedResolver):
+    def __init__(
+        self,
+        stream: StreamTextType,
+        version: Optional[VersionType] = None,
+        preserve_quotes: Optional[bool] = None,
+    ) -> None:
+        self.comment_handling = None
+        Reader.__init__(self, stream, loader=self)
+        Scanner.__init__(self, loader=self)
+        Parser.__init__(self, loader=self)
+        Composer.__init__(self, loader=self)
+        Constructor.__init__(self, loader=self)
+        VersionedResolver.__init__(self, version, loader=self)
+
+
+class RoundTripLoader(
+    Reader,
+    RoundTripScanner,
+    RoundTripParser,
+    Composer,
+    RoundTripConstructor,
+    VersionedResolver,
+):
+    def __init__(
+        self,
+        stream: StreamTextType,
+        version: Optional[VersionType] = None,
+        preserve_quotes: Optional[bool] = None,
+    ) -> None:
+        # self.reader = Reader.__init__(self, stream)
+        self.comment_handling = None  # issue 385
+        Reader.__init__(self, stream, loader=self)
+        RoundTripScanner.__init__(self, loader=self)
+        RoundTripParser.__init__(self, loader=self)
+        Composer.__init__(self, loader=self)
+        RoundTripConstructor.__init__(self, preserve_quotes=preserve_quotes, loader=self)
+        VersionedResolver.__init__(self, version, loader=self)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py
new file mode 100644
index 00000000000..34bce4458f9
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py
@@ -0,0 +1,1519 @@
+
+from __future__ import annotations
+
+import sys
+import os
+import warnings
+import glob
+from importlib import import_module
+
+
+import opentelemetry.agent._vendor.ruamel.yaml
+from opentelemetry.agent._vendor import ruamel
+from opentelemetry.agent._vendor import opentelemetry
+from opentelemetry.agent._vendor.ruamel.yaml.error import UnsafeLoaderWarning, YAMLError  # NOQA
+
+from opentelemetry.agent._vendor.ruamel.yaml.tokens import *  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.events import *  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.nodes import *  # NOQA
+
+from opentelemetry.agent._vendor.ruamel.yaml.loader import BaseLoader, SafeLoader, Loader, RoundTripLoader  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.dumper import BaseDumper, SafeDumper, Dumper, RoundTripDumper  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.compat import StringIO, BytesIO, with_metaclass, nprint, nprintf  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.resolver import VersionedResolver, Resolver  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.representer import (
+    BaseRepresenter,
+    SafeRepresenter,
+    Representer,
+    RoundTripRepresenter,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.constructor import (
+    BaseConstructor,
+    SafeConstructor,
+    Constructor,
+    RoundTripConstructor,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.loader import Loader as UnsafeLoader  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.comments import CommentedMap, CommentedSeq, C_PRE
+from opentelemetry.agent._vendor.ruamel.yaml.docinfo import DocInfo, version, Version
+
+from typing import List, Set, Dict, Tuple, Union, Any, Callable, Optional, Text, Type  # NOQA
+if False:  # MYPY
+    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamType, StreamTextType, VersionType  # NOQA
+    from types import TracebackType
+    from pathlib import Path
+
+# opentelemetry-agent: always use the pure-Python parser and emitter; the libyaml binding
+# (_ruamel_yaml) would be the application's, not vendored.
+CParser = CEmitter = None
+
+# import io
+
+
+# YAML is an acronym, i.e. spoken: rhymes with "camel". And thus a
+# subset of abbreviations, which should be all caps according to PEP8
+
+
+class YAML:
+    def __init__(
+        self: Any,
+        *,
+        typ: Optional[Union[List[Text], Text]] = None,
+        pure: Any = False,
+        output: Any = None,
+        plug_ins: Any = None,
+    ) -> None:  # input=None,
+        """
+        typ: 'rt'/None -> RoundTripLoader/RoundTripDumper,  (default)
+             'safe'    -> SafeLoader/SafeDumper,
+             'unsafe'  -> normal/unsafe Loader/Dumper (pending deprecation)
+             'full'    -> full Dumper only, including python built-ins that are
+                          potentially unsafe to load
+             'base'    -> baseloader
+        pure: if True only use Python modules
+        input/output: needed to work as context manager
+        plug_ins: a list of plug-in files
+        """
+
+        self.typ = ['rt'] if typ is None else (typ if isinstance(typ, list) else [typ])
+        self.pure = pure
+
+        # self._input = input
+        self._output = output
+        self._context_manager: Any = None
+
+        self.plug_ins: List[Any] = []
+        for pu in ([] if plug_ins is None else plug_ins) + self.official_plug_ins():
+            file_name = pu.replace(os.sep, '.')
+            self.plug_ins.append(import_module(file_name))
+        self.Resolver: Any = ruamel.yaml.resolver.VersionedResolver
+        self.allow_unicode = True
+        self.Reader: Any = None
+        self.Representer: Any = None
+        self.Constructor: Any = None
+        self.Scanner: Any = None
+        self.Serializer: Any = None
+        self.default_flow_style: Any = None
+        self.comment_handling = None
+        self.max_depth = 0
+        typ_found = 1
+        setup_rt = False
+        if 'rt' in self.typ:
+            setup_rt = True
+        elif 'safe' in self.typ:
+            self.Emitter = (
+                ruamel.yaml.emitter.Emitter if pure or CEmitter is None else CEmitter
+            )
+            self.Representer = ruamel.yaml.representer.SafeRepresenter
+            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
+            self.Composer = ruamel.yaml.composer.Composer
+            self.Constructor = ruamel.yaml.constructor.SafeConstructor
+        elif 'base' in self.typ:
+            self.Emitter = ruamel.yaml.emitter.Emitter
+            self.Representer = ruamel.yaml.representer.BaseRepresenter
+            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
+            self.Composer = ruamel.yaml.composer.Composer
+            self.Constructor = ruamel.yaml.constructor.BaseConstructor
+        elif 'unsafe' in self.typ:
+            warnings.warn(
+                "\nyou should no longer specify 'unsafe'.\nFor **dumping only** use yaml=YAML(typ='full')\n",  # NOQA
+                PendingDeprecationWarning,
+                stacklevel=2,
+            )
+            self.Emitter = (
+                ruamel.yaml.emitter.Emitter if pure or CEmitter is None else CEmitter
+            )
+            self.Representer = ruamel.yaml.representer.Representer
+            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
+            self.Composer = ruamel.yaml.composer.Composer
+            self.Constructor = ruamel.yaml.constructor.Constructor
+        elif 'full' in self.typ:
+            self.Emitter = (
+                ruamel.yaml.emitter.Emitter if pure or CEmitter is None else CEmitter
+            )
+            self.Representer = ruamel.yaml.representer.Representer
+            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
+            # self.Composer = ruamel.yaml.composer.Composer
+            # self.Constructor = ruamel.yaml.constructor.Constructor
+        elif 'rtsc' in self.typ:
+            self.default_flow_style = False
+            # no optimized rt-dumper yet
+            self.Emitter = ruamel.yaml.emitter.RoundTripEmitter
+            self.Serializer = ruamel.yaml.serializer.Serializer
+            self.Representer = ruamel.yaml.representer.RoundTripRepresenter
+            self.Scanner = ruamel.yaml.scanner.RoundTripScannerSC
+            # no optimized rt-parser yet
+            self.Parser = ruamel.yaml.parser.RoundTripParserSC
+            self.Composer = ruamel.yaml.composer.Composer
+            self.Constructor = ruamel.yaml.constructor.RoundTripConstructor
+            self.comment_handling = C_PRE
+        else:
+            setup_rt = True
+            typ_found = 0
+        if setup_rt:
+            self.default_flow_style = False
+            # no optimized rt-dumper yet
+            self.Emitter = ruamel.yaml.emitter.RoundTripEmitter
+            self.Serializer = ruamel.yaml.serializer.Serializer
+            self.Representer = ruamel.yaml.representer.RoundTripRepresenter
+            self.Scanner = ruamel.yaml.scanner.RoundTripScanner
+            # no optimized rt-parser yet
+            self.Parser = ruamel.yaml.parser.RoundTripParser
+            self.Composer = ruamel.yaml.composer.Composer
+            self.Constructor = ruamel.yaml.constructor.RoundTripConstructor
+        del setup_rt
+        self.stream = None
+        self.canonical = None
+        self.old_indent = None
+        self.width: Union[int, None] = None
+        self.line_break = None
+
+        self.map_indent: Union[int, None] = None
+        self.sequence_indent: Union[int, None] = None
+        self.sequence_dash_offset: int = 0
+        self.compact_seq_seq = None
+        self.compact_seq_map = None
+        self.sort_base_mapping_type_on_output = None  # default: sort
+
+        self.top_level_colon_align = None
+        self.prefix_colon = None
+        self._version: Optional[Any] = None
+        self.preserve_quotes: Optional[bool] = None
+        self.allow_duplicate_keys = False  # duplicate keys in map, set
+        self.encoding = 'utf-8'
+        self.explicit_start: Union[bool, None] = None
+        self.explicit_end: Union[bool, None] = None
+        self._tags = None
+        self.doc_infos: List[DocInfo] = []
+        self.default_style = None
+        self.top_level_block_style_scalar_no_indent_error_1_1 = False
+        # directives end indicator with single scalar document
+        self.scalar_after_indicator: Optional[bool] = None
+        # [a, b: 1, c: {d: 2}]  vs. [a, {b: 1}, {c: {d: 2}}]
+        self.brace_single_entry_mapping_in_flow_sequence = False
+        for module in self.plug_ins:
+            if getattr(module, 'typ', None) in self.typ:
+                typ_found += 1
+                module.init_typ(self)
+                break
+        if typ_found == 0:
+            raise NotImplementedError(
+                f'typ "{self.typ}" not recognised (need to install plug-in?)',
+            )
+
+    @property
+    def reader(self) -> Any:
+        try:
+            return self._reader  # type: ignore
+        except AttributeError:
+            self._reader = self.Reader(None, loader=self)
+            return self._reader
+
+    @property
+    def scanner(self) -> Any:
+        try:
+            return self._scanner  # type: ignore
+        except AttributeError:
+            if self.Scanner is None:
+                raise
+            self._scanner = self.Scanner(loader=self)
+            return self._scanner
+
+    @property
+    def parser(self) -> Any:
+        attr = '_' + sys._getframe().f_code.co_name
+        if not hasattr(self, attr):
+            if self.Parser is not CParser:
+                setattr(self, attr, self.Parser(loader=self))
+            else:
+                if getattr(self, '_stream', None) is None:
+                    # wait for the stream
+                    return None
+                else:
+                    # if not hasattr(self._stream, 'read') and hasattr(self._stream, 'open'):
+                    #     # pathlib.Path() instance
+                    #     setattr(self, attr, CParser(self._stream))
+                    # else:
+                    setattr(self, attr, CParser(self._stream))
+                    # self._parser = self._composer = self
+                    # nprint('scanner', self.loader.scanner)
+
+        return getattr(self, attr)
+
+    @property
+    def composer(self) -> Any:
+        attr = '_' + sys._getframe().f_code.co_name
+        if not hasattr(self, attr):
+            setattr(self, attr, self.Composer(loader=self))
+        return getattr(self, attr)
+
+    @property
+    def constructor(self) -> Any:
+        attr = '_' + sys._getframe().f_code.co_name
+        if not hasattr(self, attr):
+            if self.Constructor is None:
+                if 'full' in self.typ:
+                    raise YAMLError(
+                        "\nyou can only use yaml=YAML(typ='full') for dumping\n",  # NOQA
+                    )
+            cnst = self.Constructor(preserve_quotes=self.preserve_quotes, loader=self)  # type: ignore # NOQA
+            cnst.allow_duplicate_keys = self.allow_duplicate_keys
+            setattr(self, attr, cnst)
+        return getattr(self, attr)
+
+    @property
+    def resolver(self) -> Any:
+        try:
+            rslvr = self._resolver  # type: ignore
+        except AttributeError:
+            rslvr = None
+        if rslvr is None or rslvr._loader_version != self.version:
+            rslvr = self._resolver = self.Resolver(version=self.version, loader=self)
+        return rslvr
+
+    @property
+    def emitter(self) -> Any:
+        attr = '_' + sys._getframe().f_code.co_name
+        if not hasattr(self, attr):
+            if self.Emitter is not CEmitter:
+                _emitter = self.Emitter(
+                    None,
+                    canonical=self.canonical,
+                    indent=self.old_indent,
+                    width=self.width,
+                    allow_unicode=self.allow_unicode,
+                    line_break=self.line_break,
+                    prefix_colon=self.prefix_colon,
+                    brace_single_entry_mapping_in_flow_sequence=self.brace_single_entry_mapping_in_flow_sequence,  # NOQA
+                    dumper=self,
+                )
+                setattr(self, attr, _emitter)
+                if self.map_indent is not None:
+                    _emitter.best_map_indent = self.map_indent
+                if self.sequence_indent is not None:
+                    _emitter.best_sequence_indent = self.sequence_indent
+                if self.sequence_dash_offset is not None:
+                    _emitter.sequence_dash_offset = self.sequence_dash_offset
+                    # _emitter.block_seq_indent = self.sequence_dash_offset
+                if self.compact_seq_seq is not None:
+                    _emitter.compact_seq_seq = self.compact_seq_seq
+                if self.compact_seq_map is not None:
+                    _emitter.compact_seq_map = self.compact_seq_map
+            else:
+                if getattr(self, '_stream', None) is None:
+                    # wait for the stream
+                    return None
+                return None
+        return getattr(self, attr)
+
+    @property
+    def serializer(self) -> Any:
+        attr = '_' + sys._getframe().f_code.co_name
+        if not hasattr(self, attr):
+            setattr(
+                self,
+                attr,
+                self.Serializer(
+                    encoding=self.encoding,
+                    explicit_start=self.explicit_start,
+                    explicit_end=self.explicit_end,
+                    version=self.version,
+                    tags=self.tags,
+                    dumper=self,
+                ),
+            )
+        return getattr(self, attr)
+
+    @property
+    def representer(self) -> Any:
+        attr = '_' + sys._getframe().f_code.co_name
+        if not hasattr(self, attr):
+            repres = self.Representer(
+                default_style=self.default_style,
+                default_flow_style=self.default_flow_style,
+                dumper=self,
+            )
+            if self.sort_base_mapping_type_on_output is not None:
+                repres.sort_base_mapping_type_on_output = self.sort_base_mapping_type_on_output
+            setattr(self, attr, repres)
+        return getattr(self, attr)
+
+    def scan(self, stream: StreamTextType) -> Any:
+        """
+        Scan a YAML stream and produce scanning tokens.
+        """
+        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
+            # pathlib.Path() instance
+            with stream.open('rb') as fp:
+                return self.scan(fp)
+        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
+        self.tags = {}
+        _, parser = self.get_constructor_parser(stream)
+        try:
+            while self.scanner.check_token():
+                yield self.scanner.get_token()
+        finally:
+            parser.dispose()
+            for comp in ('reader', 'scanner'):
+                try:
+                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
+                except AttributeError:
+                    pass
+
+    def parse(self, stream: StreamTextType) -> Any:
+        """
+        Parse a YAML stream and produce parsing events.
+        """
+        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
+            # pathlib.Path() instance
+            with stream.open('rb') as fp:
+                return self.parse(fp)
+        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
+        self.tags = {}
+        _, parser = self.get_constructor_parser(stream)
+        try:
+            while parser.check_event():
+                yield parser.get_event()
+        finally:
+            parser.dispose()
+            for comp in ('reader', 'scanner'):
+                try:
+                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
+                except AttributeError:
+                    pass
+
+    def compose(self, stream: Union[Path, StreamTextType]) -> Any:
+        """
+        Parse the first YAML document in a stream
+        and produce the corresponding representation tree.
+        """
+        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
+            # pathlib.Path() instance
+            with stream.open('rb') as fp:
+                return self.compose(fp)
+        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
+        self.tags = {}
+        constructor, parser = self.get_constructor_parser(stream)
+        try:
+            return constructor.composer.get_single_node()
+        finally:
+            parser.dispose()
+            for comp in ('reader', 'scanner'):
+                try:
+                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
+                except AttributeError:
+                    pass
+
+    def compose_all(self, stream: Union[Path, StreamTextType]) -> Any:
+        """
+        Parse all YAML documents in a stream
+        and produce corresponding representation trees.
+        """
+        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
+        self.tags = {}
+        constructor, parser = self.get_constructor_parser(stream)
+        try:
+            while constructor.composer.check_node():
+                yield constructor.composer.get_node()
+        finally:
+            parser.dispose()
+            for comp in ('reader', 'scanner'):
+                try:
+                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
+                except AttributeError:
+                    pass
+
+    # separate output resolver?
+
+    # def load(self, stream=None):
+    #     if self._context_manager:
+    #        if not self._input:
+    #             raise TypeError("Missing input stream while dumping from context manager")
+    #         for data in self._context_manager.load():
+    #             yield data
+    #         return
+    #     if stream is None:
+    #         raise TypeError("Need a stream argument when not loading from context manager")
+    #     return self.load_one(stream)
+
+    def load(self, stream: Union[Path, StreamTextType]) -> Any:
+        """
+        at this point you either have the non-pure Parser (which has its own reader and
+        scanner) or you have the pure Parser.
+        If the pure Parser is set, then set the Reader and Scanner, if not already set.
+        If either the Scanner or Reader are set, you cannot use the non-pure Parser,
+            so reset it to the pure parser and set the Reader resp. Scanner if necessary
+        """
+        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
+            # pathlib.Path() instance
+            with stream.open('rb') as fp:
+                return self.load(fp)
+        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
+        self.tags = {}
+        constructor, parser = self.get_constructor_parser(stream)
+        try:
+            return constructor.get_single_data()
+        finally:
+            parser.dispose()
+            for comp in ('reader', 'scanner'):
+                try:
+                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
+                except AttributeError:
+                    pass
+
+    def load_all(self, stream: Union[Path, StreamTextType]) -> Any:  # *, skip=None):
+        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
+            # pathlib.Path() instance
+            with stream.open('r') as fp:
+                for d in self.load_all(fp):
+                    yield d
+                return
+        # if skip is None:
+        #     skip = []
+        # elif isinstance(skip, int):
+        #     skip = [skip]
+        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
+        self.tags = {}
+        constructor, parser = self.get_constructor_parser(stream)
+        try:
+            while constructor.check_data():
+                yield constructor.get_data()
+                self.doc_infos.append(DocInfo(requested_version=version(self.version)))
+        finally:
+            parser.dispose()
+            for comp in ('reader', 'scanner'):
+                try:
+                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
+                except AttributeError:
+                    pass
+
+    def get_constructor_parser(self, stream: StreamTextType) -> Any:
+        """
+        the old cyaml needs special setup, and therefore the stream
+        """
+        if self.Constructor is None:
+            if 'full' in self.typ:
+                raise YAMLError(
+                     "\nyou can only use yaml=YAML(typ='full') for dumping\n",  # NOQA
+                )
+        if self.Parser is not CParser:
+            if self.Reader is None:
+                self.Reader = ruamel.yaml.reader.Reader
+            if self.Scanner is None:
+                self.Scanner = ruamel.yaml.scanner.Scanner
+            self.reader.stream = stream
+        else:
+            if self.Reader is not None:
+                if self.Scanner is None:
+                    self.Scanner = ruamel.yaml.scanner.Scanner
+                self.Parser = ruamel.yaml.parser.Parser
+                self.reader.stream = stream
+            elif self.Scanner is not None:
+                if self.Reader is None:
+                    self.Reader = ruamel.yaml.reader.Reader
+                self.Parser = ruamel.yaml.parser.Parser
+                self.reader.stream = stream
+            else:
+                # combined C level reader>scanner>parser
+                # does some calls to the resolver, e.g. BaseResolver.descend_resolver
+                # if you just initialise the CParser, too much of resolver.py
+                # is actually used
+                rslvr = self.Resolver
+                # if rslvr is ruamel.yaml.resolver.VersionedResolver:
+                #     rslvr = ruamel.yaml.resolver.Resolver
+
+                class XLoader(self.Parser, self.Constructor, rslvr):  # type: ignore
+                    def __init__(
+                        selfx,
+                        stream: StreamTextType,
+                        version: Optional[VersionType] = self.version,
+                        preserve_quotes: Optional[bool] = None,
+                    ) -> None:
+                        # NOQA
+                        CParser.__init__(selfx, stream)
+                        selfx._parser = selfx._composer = selfx
+                        self.Constructor.__init__(selfx, loader=selfx)
+                        selfx.allow_duplicate_keys = self.allow_duplicate_keys
+                        rslvr.__init__(selfx, version=version, loadumper=selfx)
+
+                self._stream = stream
+                loader = XLoader(stream)
+                self._scanner = loader
+                return loader, loader
+        return self.constructor, self.parser
+
+    def emit(self, events: Any, stream: Any) -> None:
+        """
+        Emit YAML parsing events into a stream.
+        If stream is None, return the produced string instead.
+        """
+        _, _, emitter = self.get_serializer_representer_emitter(stream, None)
+        try:
+            for event in events:
+                emitter.emit(event)
+        finally:
+            try:
+                emitter.dispose()
+            except AttributeError:
+                raise
+
+    def serialize(self, node: Any, stream: Optional[StreamType]) -> Any:
+        """
+        Serialize a representation tree into a YAML stream.
+        If stream is None, return the produced string instead.
+        """
+        self.serialize_all([node], stream)
+
+    def serialize_all(self, nodes: Any, stream: Optional[StreamType]) -> Any:
+        """
+        Serialize a sequence of representation trees into a YAML stream.
+        If stream is None, return the produced string instead.
+        """
+        serializer, _, emitter = self.get_serializer_representer_emitter(stream, None)
+        try:
+            serializer.open()
+            for node in nodes:
+                serializer.serialize(node)
+            serializer.close()
+        finally:
+            try:
+                emitter.dispose()
+            except AttributeError:
+                raise
+
+    def dump(
+        self: Any, data: Union[Path, StreamType], stream: Any = None, *, transform: Any = None,
+    ) -> Any:
+        if self._context_manager:
+            if not self._output:
+                raise TypeError('Missing output stream while dumping from context manager')
+            if transform is not None:
+                x = self.__class__.__name__
+                raise TypeError(
+                    f'{x}.dump() in the context manager cannot have transform keyword',
+                )
+            self._context_manager.dump(data)
+        else:  # old style
+            if stream is None:
+                raise TypeError('Need a stream argument when not dumping from context manager')
+            return self.dump_all([data], stream, transform=transform)
+
+    def dump_all(
+        self, documents: Any, stream: Union[Path, StreamType], *, transform: Any = None,
+    ) -> Any:
+        if self._context_manager:
+            raise NotImplementedError
+        self._output = stream
+        self._context_manager = YAMLContextManager(self, transform=transform)
+        for data in documents:
+            self._context_manager.dump(data)
+        self._context_manager.teardown_output()
+        self._output = None
+        self._context_manager = None
+
+    def Xdump_all(self, documents: Any, stream: Any, *, transform: Any = None) -> Any:
+        """
+        Serialize a sequence of Python objects into a YAML stream.
+        """
+        if not hasattr(stream, 'write') and hasattr(stream, 'open'):
+            # pathlib.Path() instance
+            with stream.open('w') as fp:
+                return self.dump_all(documents, fp, transform=transform)
+        # The stream should have the methods `write` and possibly `flush`.
+        if self.top_level_colon_align is True:
+            tlca: Any = max([len(str(x)) for x in documents[0]])
+        else:
+            tlca = self.top_level_colon_align
+        if transform is not None:
+            fstream = stream
+            if self.encoding is None:
+                stream = StringIO()
+            else:
+                stream = BytesIO()
+        serializer, representer, emitter = self.get_serializer_representer_emitter(
+            stream, tlca,
+        )
+        try:
+            self.serializer.open()
+            for data in documents:
+                try:
+                    self.representer.represent(data)
+                except AttributeError:
+                    # nprint(dir(dumper._representer))
+                    raise
+            self.serializer.close()
+        finally:
+            try:
+                self.emitter.dispose()
+            except AttributeError:
+                raise
+                # self.dumper.dispose()  # cyaml
+            delattr(self, '_serializer')  # NOQA
+            delattr(self, '_emitter')  # NOQA
+        if transform:
+            val = stream.getvalue()
+            if self.encoding:
+                val = val.decode(self.encoding)
+            if fstream is None:
+                transform(val)
+            else:
+                fstream.write(transform(val))
+        return None
+
+    def get_serializer_representer_emitter(self, stream: StreamType, tlca: Any) -> Any:
+        # we have only .Serializer to deal with (vs .Reader & .Scanner), much simpler
+        if self.Emitter is not CEmitter:
+            if self.Serializer is None:
+                self.Serializer = ruamel.yaml.serializer.Serializer
+            self.emitter.stream = stream
+            self.emitter.top_level_colon_align = tlca
+            if self.scalar_after_indicator is not None:
+                self.emitter.scalar_after_indicator = self.scalar_after_indicator
+            return self.serializer, self.representer, self.emitter
+        if self.Serializer is not None:
+            # cannot set serializer with CEmitter
+            self.Emitter = ruamel.yaml.emitter.Emitter
+            self.emitter.stream = stream
+            self.emitter.top_level_colon_align = tlca
+            if self.scalar_after_indicator is not None:
+                self.emitter.scalar_after_indicator = self.scalar_after_indicator
+            return self.serializer, self.representer, self.emitter
+        # C routines
+
+        rslvr = (
+            ruamel.yaml.resolver.BaseResolver
+            if 'base' in self.typ
+            else ruamel.yaml.resolver.Resolver
+        )
+
+        class XDumper(CEmitter, self.Representer, rslvr):  # type: ignore
+            def __init__(
+                selfx: StreamType,
+                stream: Any,
+                default_style: Any = None,
+                default_flow_style: Any = None,
+                canonical: Optional[bool] = None,
+                indent: Optional[int] = None,
+                width: Optional[int] = None,
+                allow_unicode: Optional[bool] = None,
+                line_break: Any = None,
+                encoding: Any = None,
+                explicit_start: Optional[bool] = None,
+                explicit_end: Optional[bool] = None,
+                version: Any = None,
+                tags: Any = None,
+                block_seq_indent: Any = None,
+                top_level_colon_align: Any = None,
+                prefix_colon: Any = None,
+            ) -> None:
+                # NOQA
+                CEmitter.__init__(
+                    selfx,
+                    stream,
+                    canonical=canonical,
+                    indent=indent,
+                    width=width,
+                    encoding=encoding,
+                    allow_unicode=allow_unicode,
+                    line_break=line_break,
+                    explicit_start=explicit_start,
+                    explicit_end=explicit_end,
+                    version=version,
+                    tags=tags,
+                )
+                selfx._emitter = selfx._serializer = selfx._representer = selfx
+                self.Representer.__init__(
+                    selfx, default_style=default_style, default_flow_style=default_flow_style,
+                )
+                rslvr.__init__(selfx)
+
+        self._stream = stream
+        dumper = XDumper(
+            stream,
+            default_style=self.default_style,
+            default_flow_style=self.default_flow_style,
+            canonical=self.canonical,
+            indent=self.old_indent,
+            width=self.width,
+            allow_unicode=self.allow_unicode,
+            line_break=self.line_break,
+            encoding=self.encoding,
+            explicit_start=self.explicit_start,
+            explicit_end=self.explicit_end,
+            version=self.version,
+            tags=self.tags,
+        )
+        self._emitter = self._serializer = dumper
+        return dumper, dumper, dumper
+
+    # basic types
+    def map(self, **kw: Any) -> Any:
+        if 'rt' in self.typ:
+            return CommentedMap(**kw)
+        else:
+            return dict(**kw)
+
+    def seq(self, *args: Any) -> Any:
+        if 'rt' in self.typ:
+            return CommentedSeq(*args)
+        else:
+            return list(*args)
+
+    # helpers
+    def official_plug_ins(self) -> Any:
+        """search for list of subdirs that are plug-ins, if __file__ is not available, e.g.
+        single file installers that are not properly emulating a file-system (issue 324)
+        no plug-ins will be found. If any are packaged, you know which file that are
+        and you can explicitly provide it during instantiation:
+            yaml = ruamel.yaml.YAML(plug_ins=['ruamel/yaml/jinja2/__plug_in__'])
+        """
+        try:
+            bd = os.path.dirname(__file__)
+        except NameError:
+            return []
+        gpbd = os.path.dirname(os.path.dirname(bd))
+        res = [x.replace(gpbd, "")[1:-3] for x in glob.glob(bd + '/*/__plug_in__.py')]
+        return res
+
+    def register_class(self, cls: Any) -> Any:
+        """
+        register a class for dumping/loading
+        - if it has attribute yaml_tag use that to register, else use class name
+        - if it has methods to_yaml/from_yaml use those to dump/load else dump attributes
+          as mapping
+        """
+        tag = getattr(cls, 'yaml_tag', '!' + cls.__name__)
+        try:
+            self.representer.add_representer(cls, cls.to_yaml)
+        except AttributeError:
+
+            def t_y(representer: Any, data: Any) -> Any:
+                return representer.represent_yaml_object(
+                    tag, data, cls, flow_style=representer.default_flow_style,
+                )
+
+            self.representer.add_representer(cls, t_y)
+        try:
+            self.constructor.add_constructor(tag, cls.from_yaml)
+        except AttributeError:
+
+            def f_y(constructor: Any, node: Any) -> Any:
+                return constructor.construct_yaml_object(node, cls)
+
+            self.constructor.add_constructor(tag, f_y)
+        return cls
+
+    # ### context manager
+
+    def __enter__(self) -> Any:
+        self._context_manager = YAMLContextManager(self)
+        return self
+
+    def __exit__(
+        self,
+        typ: Optional[Type[BaseException]],
+        value: Optional[BaseException],
+        traceback: Optional[TracebackType],
+    ) -> None:
+        if typ:
+            nprint('typ', typ)
+        self._context_manager.teardown_output()
+        # self._context_manager.teardown_input()
+        self._context_manager = None
+
+    # ### backwards compatibility
+    def _indent(self, mapping: Any = None, sequence: Any = None, offset: Any = None) -> None:
+        if mapping is not None:
+            self.map_indent = mapping
+        if sequence is not None:
+            self.sequence_indent = sequence
+        if offset is not None:
+            self.sequence_dash_offset = offset
+
+    @property
+    def version(self) -> Optional[Tuple[int, int]]:
+        return self._version
+
+    @version.setter
+    def version(self, val: VersionType) -> None:
+        if val is None:
+            self._version = val
+            return
+        elif isinstance(val, str):
+            sval = tuple(int(x) for x in val.split('.'))
+        elif isinstance(val, (list, tuple)):
+            sval = tuple(int(x) for x in val)
+        elif isinstance(val, Version):
+            sval = (val.major, val.minor)
+        else:
+            raise TypeError(f'unknown version type {type(val)}')
+        assert len(sval) == 2, f'version can only have major.minor, got {val}'
+        assert sval[0] == 1, f'version major part can only be 1, got {val}'
+        assert sval[1] in [1, 2], f'version minor part can only be 2 or 1, got {val}'
+        self._version = sval
+
+    @property
+    def tags(self) -> Any:
+        return self._tags
+
+    @tags.setter
+    def tags(self, val: Any) -> None:
+        self._tags = val
+
+    @property
+    def indent(self) -> Any:
+        return self._indent
+
+    @indent.setter
+    def indent(self, val: Any) -> None:
+        self.old_indent = val
+
+    @property
+    def block_seq_indent(self) -> Any:
+        return self.sequence_dash_offset
+
+    @block_seq_indent.setter
+    def block_seq_indent(self, val: Any) -> None:
+        self.sequence_dash_offset = val
+
+    def compact(self, seq_seq: Any = None, seq_map: Any = None) -> None:
+        self.compact_seq_seq = seq_seq
+        self.compact_seq_map = seq_map
+
+
+class YAMLContextManager:
+    def __init__(self, yaml: Any, transform: Any = None) -> None:
+        # used to be: (Any, Optional[Callable]) -> None
+        self._yaml = yaml
+        self._output_inited = False
+        self._output_path = None
+        self._output = self._yaml._output
+        self._transform = transform
+
+        # self._input_inited = False
+        # self._input = input
+        # self._input_path = None
+        # self._transform = yaml.transform
+        # self._fstream = None
+
+        if not hasattr(self._output, 'write') and hasattr(self._output, 'open'):
+            # pathlib.Path() instance, open with the same mode
+            self._output_path = self._output
+            self._output = self._output_path.open('w')
+
+        # if not hasattr(self._stream, 'write') and hasattr(stream, 'open'):
+        # if not hasattr(self._input, 'read') and hasattr(self._input, 'open'):
+        #    # pathlib.Path() instance, open with the same mode
+        #    self._input_path = self._input
+        #    self._input = self._input_path.open('r')
+
+        if self._transform is not None:
+            self._fstream = self._output
+            if self._yaml.encoding is None:
+                self._output = StringIO()
+            else:
+                self._output = BytesIO()
+
+    def teardown_output(self) -> None:
+        if self._output_inited:
+            self._yaml.serializer.close()
+        else:
+            return
+        try:
+            self._yaml.emitter.dispose()
+        except AttributeError:
+            raise
+            # self.dumper.dispose()  # cyaml
+        try:
+            delattr(self._yaml, '_serializer')  # NOQA
+            delattr(self._yaml, '_emitter')  # NOQA
+        except AttributeError:
+            raise
+        if self._transform:
+            val = self._output.getvalue()
+            if self._yaml.encoding:
+                val = val.decode(self._yaml.encoding)
+            if self._fstream is None:
+                self._transform(val)
+            else:
+                self._fstream.write(self._transform(val))
+                self._fstream.flush()
+                self._output = self._fstream  # maybe not necessary
+        if self._output_path is not None:
+            self._output.close()
+
+    def init_output(self, first_data: Any) -> None:
+        if self._yaml.top_level_colon_align is True:
+            tlca: Any = max([len(str(x)) for x in first_data])
+        else:
+            tlca = self._yaml.top_level_colon_align
+        self._yaml.get_serializer_representer_emitter(self._output, tlca)
+        self._yaml.serializer.open()
+        self._output_inited = True
+
+    def dump(self, data: Any) -> None:
+        if not self._output_inited:
+            self.init_output(data)
+        try:
+            self._yaml.representer.represent(data)
+        except AttributeError:
+            # nprint(dir(dumper._representer))
+            raise
+
+    # def teardown_input(self):
+    #     pass
+    #
+    # def init_input(self):
+    #     # set the constructor and parser on YAML() instance
+    #     self._yaml.get_constructor_parser(stream)
+    #
+    # def load(self):
+    #     if not self._input_inited:
+    #         self.init_input()
+    #     try:
+    #         while self._yaml.constructor.check_data():
+    #             yield self._yaml.constructor.get_data()
+    #     finally:
+    #         parser.dispose()
+    #         try:
+    #             self._reader.reset_reader()  # type: ignore
+    #         except AttributeError:
+    #             pass
+    #         try:
+    #             self._scanner.reset_scanner()  # type: ignore
+    #         except AttributeError:
+    #             pass
+
+
+def yaml_object(yml: Any) -> Any:
+    """ decorator for classes that needs to dump/load objects
+    The tag for such objects is taken from the class attribute yaml_tag (or the
+    class name in lowercase in case unavailable)
+    If methods to_yaml and/or from_yaml are available, these are called for dumping resp.
+    loading, default routines (dumping a mapping of the attributes) used otherwise.
+    """
+
+    def yo_deco(cls: Any) -> Any:
+        tag = getattr(cls, 'yaml_tag', '!' + cls.__name__)
+        try:
+            yml.representer.add_representer(cls, cls.to_yaml)
+        except AttributeError:
+
+            def t_y(representer: Any, data: Any) -> Any:
+                return representer.represent_yaml_object(
+                    tag, data, cls, flow_style=representer.default_flow_style,
+                )
+
+            yml.representer.add_representer(cls, t_y)
+        try:
+            yml.constructor.add_constructor(tag, cls.from_yaml)
+        except AttributeError:
+
+            def f_y(constructor: Any, node: Any) -> Any:
+                return constructor.construct_yaml_object(node, cls)
+
+            yml.constructor.add_constructor(tag, f_y)
+        return cls
+
+    return yo_deco
+
+
+########################################################################################
+def warn_deprecation(fun: Any, method: Any, arg: str = '') -> None:
+    warnings.warn(
+        f'\n{fun} will be removed, use\n\n  yaml=YAML({arg})\n  yaml.{method}(...)\n\ninstead',  # NOQA
+        PendingDeprecationWarning,  # this will show when testing with pytest/tox
+        stacklevel=3,
+    )
+
+
+def error_deprecation(fun: Any, method: Any, arg: str = '', comment: str = 'instead of') -> None:  # NOQA
+    import inspect
+
+    s = f'\n"{fun}()" has been removed, use\n\n  yaml = YAML({arg})\n  yaml.{method}(...)\n\n{comment}'  # NOQA
+    try:
+        info = inspect.getframeinfo(inspect.stack()[2][0])
+        context = '' if info.code_context is None else "".join(info.code_context)
+        s += f' file "{info.filename}", line {info.lineno}\n\n{context}'
+    except Exception as e:
+        _ = e
+    s += '\n'
+    if sys.version_info < (3, 10):
+        raise AttributeError(s)
+    else:
+        raise AttributeError(s, name=None)
+
+
+_error_dep_arg = "typ='rt'"
+_error_dep_comment = "and register any classes that you use, or check the tag attribute on the loaded data,\ninstead of"  # NOQA
+
+########################################################################################
+
+
+def scan(stream: StreamTextType, Loader: Any = Loader) -> Any:
+    """
+    Scan a YAML stream and produce scanning tokens.
+    """
+    error_deprecation('scan', 'scan', arg=_error_dep_arg, comment=_error_dep_comment)
+
+
+def parse(stream: StreamTextType, Loader: Any = Loader) -> Any:
+    """
+    Parse a YAML stream and produce parsing events.
+    """
+    error_deprecation('parse', 'parse', arg=_error_dep_arg, comment=_error_dep_comment)
+
+
+def compose(stream: StreamTextType, Loader: Any = Loader) -> Any:
+    """
+    Parse the first YAML document in a stream
+    and produce the corresponding representation tree.
+    """
+    error_deprecation('compose', 'compose', arg=_error_dep_arg, comment=_error_dep_comment)
+
+
+def compose_all(stream: StreamTextType, Loader: Any = Loader) -> Any:
+    """
+    Parse all YAML documents in a stream
+    and produce corresponding representation trees.
+    """
+    error_deprecation('compose', 'compose', arg=_error_dep_arg, comment=_error_dep_comment)
+
+
+def load(
+    stream: Any, Loader: Any = None, version: Any = None, preserve_quotes: Any = None,
+) -> Any:
+    """
+    Parse the first YAML document in a stream
+    and produce the corresponding Python object.
+    """
+    error_deprecation('load', 'load', arg=_error_dep_arg, comment=_error_dep_comment)
+
+
+def load_all(
+    stream: Any, Loader: Any = None, version: Any = None, preserve_quotes: Any = None,
+) -> Any:
+    # NOQA
+    """
+    Parse all YAML documents in a stream
+    and produce corresponding Python objects.
+    """
+    error_deprecation('load_all', 'load_all', arg=_error_dep_arg, comment=_error_dep_comment)
+
+
+def safe_load(stream: StreamTextType, version: Optional[VersionType] = None) -> Any:
+    """
+    Parse the first YAML document in a stream
+    and produce the corresponding Python object.
+    Resolve only basic YAML tags.
+    """
+    error_deprecation('safe_load', 'load', arg="typ='safe', pure=True")
+
+
+def safe_load_all(stream: StreamTextType, version: Optional[VersionType] = None) -> Any:
+    """
+    Parse all YAML documents in a stream
+    and produce corresponding Python objects.
+    Resolve only basic YAML tags.
+    """
+    error_deprecation('safe_load_all', 'load_all', arg="typ='safe', pure=True")
+
+
+def round_trip_load(
+    stream: StreamTextType,
+    version: Optional[VersionType] = None,
+    preserve_quotes: Optional[bool] = None,
+) -> Any:
+    """
+    Parse the first YAML document in a stream
+    and produce the corresponding Python object.
+    Resolve only basic YAML tags.
+    """
+    error_deprecation('round_trip_load_all', 'load')
+
+
+def round_trip_load_all(
+    stream: StreamTextType,
+    version: Optional[VersionType] = None,
+    preserve_quotes: Optional[bool] = None,
+) -> Any:
+    """
+    Parse all YAML documents in a stream
+    and produce corresponding Python objects.
+    Resolve only basic YAML tags.
+    """
+    error_deprecation('round_trip_load_all', 'load_all')
+
+
+def emit(
+    events: Any,
+    stream: Optional[StreamType] = None,
+    Dumper: Any = Dumper,
+    canonical: Optional[bool] = None,
+    indent: Union[int, None] = None,
+    width: Optional[int] = None,
+    allow_unicode: Optional[bool] = None,
+    line_break: Any = None,
+) -> Any:
+    # NOQA
+    """
+    Emit YAML parsing events into a stream.
+    If stream is None, return the produced string instead.
+    """
+    error_deprecation('emit', 'emit', arg="typ='safe', pure=True")
+
+
+enc = None
+
+
+def serialize_all(
+    nodes: Any,
+    stream: Optional[StreamType] = None,
+    Dumper: Any = Dumper,
+    canonical: Any = None,
+    indent: Optional[int] = None,
+    width: Optional[int] = None,
+    allow_unicode: Optional[bool] = None,
+    line_break: Any = None,
+    encoding: Any = enc,
+    explicit_start: Optional[bool] = None,
+    explicit_end: Optional[bool] = None,
+    version: Optional[VersionType] = None,
+    tags: Any = None,
+) -> Any:
+    # NOQA
+    """
+    Serialize a sequence of representation trees into a YAML stream.
+    If stream is None, return the produced string instead.
+    """
+    error_deprecation('serialize_all', 'serialize_all', arg="typ='safe', pure=True")
+
+
+def serialize(
+    node: Any, stream: Optional[StreamType] = None, Dumper: Any = Dumper, **kwds: Any,
+) -> Any:
+    """
+    Serialize a representation tree into a YAML stream.
+    If stream is None, return the produced string instead.
+    """
+    error_deprecation('serialize', 'serialize', arg="typ='safe', pure=True")
+
+
+def dump_all(
+    documents: Any,
+    stream: Optional[StreamType] = None,
+    Dumper: Any = Dumper,
+    default_style: Any = None,
+    default_flow_style: Any = None,
+    canonical: Optional[bool] = None,
+    indent: Optional[int] = None,
+    width: Optional[int] = None,
+    allow_unicode: Optional[bool] = None,
+    line_break: Any = None,
+    encoding: Any = enc,
+    explicit_start: Optional[bool] = None,
+    explicit_end: Optional[bool] = None,
+    version: Any = None,
+    tags: Any = None,
+    block_seq_indent: Any = None,
+    top_level_colon_align: Any = None,
+    prefix_colon: Any = None,
+) -> Any:
+    # NOQA
+    """
+    Serialize a sequence of Python objects into a YAML stream.
+    If stream is None, return the produced string instead.
+    """
+    error_deprecation('dump_all', 'dump_all', arg="typ='unsafe', pure=True")
+
+
+def dump(
+    data: Any,
+    stream: Optional[StreamType] = None,
+    Dumper: Any = Dumper,
+    default_style: Any = None,
+    default_flow_style: Any = None,
+    canonical: Optional[bool] = None,
+    indent: Optional[int] = None,
+    width: Optional[int] = None,
+    allow_unicode: Optional[bool] = None,
+    line_break: Any = None,
+    encoding: Any = enc,
+    explicit_start: Optional[bool] = None,
+    explicit_end: Optional[bool] = None,
+    version: Optional[VersionType] = None,
+    tags: Any = None,
+    block_seq_indent: Any = None,
+) -> Any:
+    # NOQA
+    """
+    Serialize a Python object into a YAML stream.
+    If stream is None, return the produced string instead.
+
+    default_style ∈ None, '', '"', "'", '|', '>'
+
+    """
+    error_deprecation('dump', 'dump', arg="typ='unsafe', pure=True")
+
+
+def safe_dump(data: Any, stream: Optional[StreamType] = None, **kwds: Any) -> Any:
+    """
+    Serialize a Python object into a YAML stream.
+    Produce only basic YAML tags.
+    If stream is None, return the produced string instead.
+    """
+    error_deprecation('safe_dump', 'dump', arg="typ='safe', pure=True")
+
+
+def round_trip_dump(
+    data: Any,
+    stream: Optional[StreamType] = None,
+    Dumper: Any = RoundTripDumper,
+    default_style: Any = None,
+    default_flow_style: Any = None,
+    canonical: Optional[bool] = None,
+    indent: Optional[int] = None,
+    width: Optional[int] = None,
+    allow_unicode: Optional[bool] = None,
+    line_break: Any = None,
+    encoding: Any = enc,
+    explicit_start: Optional[bool] = None,
+    explicit_end: Optional[bool] = None,
+    version: Optional[VersionType] = None,
+    tags: Any = None,
+    block_seq_indent: Any = None,
+    top_level_colon_align: Any = None,
+    prefix_colon: Any = None,
+) -> Any:
+    allow_unicode = True if allow_unicode is None else allow_unicode
+    error_deprecation('round_trip_dump', 'dump')
+
+
+# Loader/Dumper are no longer composites, to get to the associated
+# Resolver()/Representer(), etc., you need to instantiate the class
+
+
+def add_implicit_resolver(
+    tag: Any,
+    regexp: Any,
+    first: Any = None,
+    Loader: Any = None,
+    Dumper: Any = None,
+    resolver: Any = Resolver,
+) -> None:
+    """
+    Add an implicit scalar detector.
+    If an implicit scalar value matches the given regexp,
+    the corresponding tag is assigned to the scalar.
+    first is a sequence of possible initial characters or None.
+    """
+    if Loader is None and Dumper is None:
+        resolver.add_implicit_resolver(tag, regexp, first)
+        return
+    if Loader:
+        if hasattr(Loader, 'add_implicit_resolver'):
+            Loader.add_implicit_resolver(tag, regexp, first)
+        elif issubclass(
+            Loader, (BaseLoader, SafeLoader, ruamel.yaml.loader.Loader, RoundTripLoader),
+        ):
+            Resolver.add_implicit_resolver(tag, regexp, first)
+        else:
+            raise NotImplementedError
+    if Dumper:
+        if hasattr(Dumper, 'add_implicit_resolver'):
+            Dumper.add_implicit_resolver(tag, regexp, first)
+        elif issubclass(
+            Dumper, (BaseDumper, SafeDumper, ruamel.yaml.dumper.Dumper, RoundTripDumper),
+        ):
+            Resolver.add_implicit_resolver(tag, regexp, first)
+        else:
+            raise NotImplementedError
+
+
+# this code currently not tested
+def add_path_resolver(
+    tag: Any,
+    path: Any,
+    kind: Any = None,
+    Loader: Any = None,
+    Dumper: Any = None,
+    resolver: Any = Resolver,
+) -> None:
+    """
+    Add a path based resolver for the given tag.
+    A path is a list of keys that forms a path
+    to a node in the representation tree.
+    Keys can be string values, integers, or None.
+    """
+    if Loader is None and Dumper is None:
+        resolver.add_path_resolver(tag, path, kind)
+        return
+    if Loader:
+        if hasattr(Loader, 'add_path_resolver'):
+            Loader.add_path_resolver(tag, path, kind)
+        elif issubclass(
+            Loader, (BaseLoader, SafeLoader, ruamel.yaml.loader.Loader, RoundTripLoader),
+        ):
+            Resolver.add_path_resolver(tag, path, kind)
+        else:
+            raise NotImplementedError
+    if Dumper:
+        if hasattr(Dumper, 'add_path_resolver'):
+            Dumper.add_path_resolver(tag, path, kind)
+        elif issubclass(
+            Dumper, (BaseDumper, SafeDumper, ruamel.yaml.dumper.Dumper, RoundTripDumper),
+        ):
+            Resolver.add_path_resolver(tag, path, kind)
+        else:
+            raise NotImplementedError
+
+
+def add_constructor(
+    tag: Any, object_constructor: Any, Loader: Any = None, constructor: Any = Constructor,
+) -> None:
+    """
+    Add an object constructor for the given tag.
+    object_onstructor is a function that accepts a Loader instance
+    and a node object and produces the corresponding Python object.
+    """
+    if Loader is None:
+        constructor.add_constructor(tag, object_constructor)
+    else:
+        if hasattr(Loader, 'add_constructor'):
+            Loader.add_constructor(tag, object_constructor)
+            return
+        if issubclass(Loader, BaseLoader):
+            BaseConstructor.add_constructor(tag, object_constructor)
+        elif issubclass(Loader, SafeLoader):
+            SafeConstructor.add_constructor(tag, object_constructor)
+        elif issubclass(Loader, Loader):
+            Constructor.add_constructor(tag, object_constructor)
+        elif issubclass(Loader, RoundTripLoader):
+            RoundTripConstructor.add_constructor(tag, object_constructor)
+        else:
+            raise NotImplementedError
+
+
+def add_multi_constructor(
+    tag_prefix: Any, multi_constructor: Any, Loader: Any = None, constructor: Any = Constructor,  # NOQA
+) -> None:
+    """
+    Add a multi-constructor for the given tag prefix.
+    Multi-constructor is called for a node if its tag starts with tag_prefix.
+    Multi-constructor accepts a Loader instance, a tag suffix,
+    and a node object and produces the corresponding Python object.
+    """
+    if Loader is None:
+        constructor.add_multi_constructor(tag_prefix, multi_constructor)
+    else:
+        if False and hasattr(Loader, 'add_multi_constructor'):
+            Loader.add_multi_constructor(tag_prefix, constructor)
+            return
+        if issubclass(Loader, BaseLoader):
+            BaseConstructor.add_multi_constructor(tag_prefix, multi_constructor)
+        elif issubclass(Loader, SafeLoader):
+            SafeConstructor.add_multi_constructor(tag_prefix, multi_constructor)
+        elif issubclass(Loader, ruamel.yaml.loader.Loader):
+            Constructor.add_multi_constructor(tag_prefix, multi_constructor)
+        elif issubclass(Loader, RoundTripLoader):
+            RoundTripConstructor.add_multi_constructor(tag_prefix, multi_constructor)
+        else:
+            raise NotImplementedError
+
+
+def add_representer(
+    data_type: Any, object_representer: Any, Dumper: Any = None, representer: Any = Representer,  # NOQA
+) -> None:
+    """
+    Add a representer for the given type.
+    object_representer is a function accepting a Dumper instance
+    and an instance of the given data type
+    and producing the corresponding representation node.
+    """
+    if Dumper is None:
+        representer.add_representer(data_type, object_representer)
+    else:
+        if hasattr(Dumper, 'add_representer'):
+            Dumper.add_representer(data_type, object_representer)
+            return
+        if issubclass(Dumper, BaseDumper):
+            BaseRepresenter.add_representer(data_type, object_representer)
+        elif issubclass(Dumper, SafeDumper):
+            SafeRepresenter.add_representer(data_type, object_representer)
+        elif issubclass(Dumper, Dumper):
+            Representer.add_representer(data_type, object_representer)
+        elif issubclass(Dumper, RoundTripDumper):
+            RoundTripRepresenter.add_representer(data_type, object_representer)
+        else:
+            raise NotImplementedError
+
+
+# this code currently not tested
+def add_multi_representer(
+    data_type: Any, multi_representer: Any, Dumper: Any = None, representer: Any = Representer,
+) -> None:
+    """
+    Add a representer for the given type.
+    multi_representer is a function accepting a Dumper instance
+    and an instance of the given data type or subtype
+    and producing the corresponding representation node.
+    """
+    if Dumper is None:
+        representer.add_multi_representer(data_type, multi_representer)
+    else:
+        if hasattr(Dumper, 'add_multi_representer'):
+            Dumper.add_multi_representer(data_type, multi_representer)
+            return
+        if issubclass(Dumper, BaseDumper):
+            BaseRepresenter.add_multi_representer(data_type, multi_representer)
+        elif issubclass(Dumper, SafeDumper):
+            SafeRepresenter.add_multi_representer(data_type, multi_representer)
+        elif issubclass(Dumper, Dumper):
+            Representer.add_multi_representer(data_type, multi_representer)
+        elif issubclass(Dumper, RoundTripDumper):
+            RoundTripRepresenter.add_multi_representer(data_type, multi_representer)
+        else:
+            raise NotImplementedError
+
+
+class YAMLObjectMetaclass(type):
+    """
+    The metaclass for YAMLObject.
+    """
+
+    def __init__(cls, name: Any, bases: Any, kwds: Any) -> None:
+        super().__init__(name, bases, kwds)
+        if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
+            cls.yaml_constructor.add_constructor(cls.yaml_tag, cls.from_yaml)  # type: ignore
+            cls.yaml_representer.add_representer(cls, cls.to_yaml)  # type: ignore
+
+
+class YAMLObject(with_metaclass(YAMLObjectMetaclass)):  # type: ignore
+    """
+    An object that can dump itself to a YAML stream
+    and load itself from a YAML stream.
+    """
+
+    __slots__ = ()  # no direct instantiation, so allow immutable subclasses
+
+    yaml_constructor = Constructor
+    yaml_representer = Representer
+
+    yaml_tag: Any = None
+    yaml_flow_style: Any = None
+
+    @classmethod
+    def from_yaml(cls, constructor: Any, node: Any) -> Any:
+        """
+        Convert a representation node to a Python object.
+        """
+        return constructor.construct_yaml_object(node, cls)
+
+    @classmethod
+    def to_yaml(cls, representer: Any, data: Any) -> Any:
+        """
+        Convert a Python object to a representation node.
+        """
+        return representer.represent_yaml_object(
+            cls.yaml_tag, data, cls, flow_style=cls.yaml_flow_style,
+        )
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py
new file mode 100644
index 00000000000..742d9dab23a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py
@@ -0,0 +1,39 @@
+
+from __future__ import annotations
+
+if False:  # MYPY
+    from typing import Any, Dict, List, Union, Optional, Iterator  # NOQA
+
+
+merge_attrib = '_yaml_merge'
+
+
+class MergeValue:
+    attrib = merge_attrib
+
+    def __init__(self) -> None:
+        self.value: List[Any] = []
+        self.sequence = None
+        self.merge_pos: Optional[int] = None  # position of merge in the mapping
+
+    def __getitem__(self, index: Any) -> Any:
+        return self.value[index]
+
+    def __setitem__(self, index: Any, val: Any) -> None:
+        self.value[index] = val
+
+    def __repr__(self) -> Any:
+        return f'MergeValue({self.value!r})'
+
+    def __len__(self) -> Any:
+        return len(self.value)
+
+    def append(self, elem: Any) -> Any:
+        self.value.append(elem)
+
+    def extend(self, elements: Any) -> None:
+        self.value.extend(elements)
+
+    def set_sequence(self, seq: Any) -> None:
+        # print('mergevalue.set_sequence node', node.anchor)
+        self.sequence = seq
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py
new file mode 100644
index 00000000000..fb6d60fed68
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py
@@ -0,0 +1,149 @@
+
+from __future__ import annotations
+
+import sys
+
+if False:  # MYPY
+    from typing import Dict, Any, Text, Optional  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
+
+
+class Node:
+    __slots__ = 'ctag', 'value', 'start_mark', 'end_mark', 'comment', 'anchor'
+
+    def __init__(
+        self,
+        tag: Any,
+        value: Any,
+        start_mark: Any,
+        end_mark: Any,
+        comment: Any = None,
+        anchor: Any = None,
+    ) -> None:
+        # you can still get a string from the serializer
+        self.ctag = tag if isinstance(tag, Tag) else Tag(suffix=tag)
+        self.value = value
+        self.start_mark = start_mark
+        self.end_mark = end_mark
+        self.comment = comment
+        self.anchor = anchor
+
+    @property
+    def tag(self) -> Optional[str]:
+        return None if self.ctag is None else str(self.ctag)
+
+    @tag.setter
+    def tag(self, val: Any) -> None:
+        if isinstance(val, str):
+            val = Tag(suffix=val)
+        self.ctag = val
+
+    def __repr__(self) -> Any:
+        value = self.value
+        # if isinstance(value, list):
+        #     if len(value) == 0:
+        #         value = ''
+        #     elif len(value) == 1:
+        #         value = '<1 item>'
+        #     else:
+        #         value = f'<{len(value)} items>'
+        # else:
+        #     if len(value) > 75:
+        #         value = repr(value[:70]+' ... ')
+        #     else:
+        #         value = repr(value)
+        value = repr(value)
+        if self.anchor is not None:
+            return f'{self.__class__.__name__!s}(tag={self.tag!r}, anchor={self.anchor!r}, value={value!s})'  # NOQA
+        return f'{self.__class__.__name__!s}(tag={self.tag!r}, value={value!s})'
+
+    def dump(self, indent: int = 0) -> None:
+        xx = self.__class__.__name__
+        xi = '  ' * indent
+        if isinstance(self.value, str):
+            sys.stdout.write(f'{xi}{xx}(tag={self.tag!r}, value={self.value!r})\n')
+            if self.comment:
+                sys.stdout.write(f'    {xi}comment: {self.comment})\n')
+            return
+        sys.stdout.write(f'{xi}{xx}(tag={self.tag!r})\n')
+        if self.comment:
+            sys.stdout.write(f'    {xi}comment: {self.comment})\n')
+        for v in self.value:
+            if isinstance(v, tuple):
+                for v1 in v:
+                    v1.dump(indent + 1)
+            elif isinstance(v, Node):
+                v.dump(indent + 1)
+            else:
+                sys.stdout.write(f'Node value type? {type(v)}\n')
+
+
+class ScalarNode(Node):
+    """
+    styles:
+      ? -> set() ? key, no value
+      - -> suppressable null value in set
+      " -> double quoted
+      ' -> single quoted
+      | -> literal style
+      > -> folding style
+    """
+
+    __slots__ = ('style',)
+    id = 'scalar'
+
+    def __init__(
+        self,
+        tag: Any,
+        value: Any,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        style: Any = None,
+        comment: Any = None,
+        anchor: Any = None,
+    ) -> None:
+        Node.__init__(self, tag, value, start_mark, end_mark, comment=comment, anchor=anchor)
+        self.style = style
+
+
+class CollectionNode(Node):
+    __slots__ = ('flow_style',)
+
+    def __init__(
+        self,
+        tag: Any,
+        value: Any,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        flow_style: Any = None,
+        comment: Any = None,
+        anchor: Any = None,
+    ) -> None:
+        Node.__init__(self, tag, value, start_mark, end_mark, comment=comment)
+        self.flow_style = flow_style
+        self.anchor = anchor
+
+
+class SequenceNode(CollectionNode):
+    __slots__ = ()
+    id = 'sequence'
+
+
+class MappingNode(CollectionNode):
+    __slots__ = ('merge',)
+    id = 'mapping'
+
+    def __init__(
+        self,
+        tag: Any,
+        value: Any,
+        start_mark: Any = None,
+        end_mark: Any = None,
+        flow_style: Any = None,
+        comment: Any = None,
+        anchor: Any = None,
+    ) -> None:
+        CollectionNode.__init__(
+            self, tag, value, start_mark, end_mark, flow_style, comment, anchor,
+        )
+        self.merge = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py
new file mode 100644
index 00000000000..06c43c3a1aa
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py
@@ -0,0 +1,862 @@
+
+from __future__ import annotations
+
+# The following YAML grammar is LL(1) and is parsed by a recursive descent
+# parser.
+#
+# stream            ::= STREAM-START implicit_document? explicit_document*
+#                                                                   STREAM-END
+# implicit_document ::= block_node DOCUMENT-END*
+# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+# block_node_or_indentless_sequence ::=
+#                       ALIAS
+#                       | properties (block_content |
+#                                                   indentless_block_sequence)?
+#                       | block_content
+#                       | indentless_block_sequence
+# block_node        ::= ALIAS
+#                       | properties block_content?
+#                       | block_content
+# flow_node         ::= ALIAS
+#                       | properties flow_content?
+#                       | flow_content
+# properties        ::= TAG ANCHOR? | ANCHOR TAG?
+# block_content     ::= block_collection | flow_collection | SCALAR
+# flow_content      ::= flow_collection | SCALAR
+# block_collection  ::= block_sequence | block_mapping
+# flow_collection   ::= flow_sequence | flow_mapping
+# block_sequence    ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)*
+#                                                                   BLOCK-END
+# indentless_sequence   ::= (BLOCK-ENTRY block_node?)+
+# block_mapping     ::= BLOCK-MAPPING_START
+#                       ((KEY block_node_or_indentless_sequence?)?
+#                       (VALUE block_node_or_indentless_sequence?)?)*
+#                       BLOCK-END
+# flow_sequence     ::= FLOW-SEQUENCE-START
+#                       (flow_sequence_entry FLOW-ENTRY)*
+#                       flow_sequence_entry?
+#                       FLOW-SEQUENCE-END
+# flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+# flow_mapping      ::= FLOW-MAPPING-START
+#                       (flow_mapping_entry FLOW-ENTRY)*
+#                       flow_mapping_entry?
+#                       FLOW-MAPPING-END
+# flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+#
+# FIRST sets:
+#
+# stream: { STREAM-START <}
+# explicit_document: { DIRECTIVE DOCUMENT-START }
+# implicit_document: FIRST(block_node)
+# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START
+#                  BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START
+#                               FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
+# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
+# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START }
+# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# block_sequence: { BLOCK-SEQUENCE-START }
+# block_mapping: { BLOCK-MAPPING-START }
+# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR
+#               BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START
+#               FLOW-MAPPING-START BLOCK-ENTRY }
+# indentless_sequence: { ENTRY }
+# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# flow_sequence: { FLOW-SEQUENCE-START }
+# flow_mapping: { FLOW-MAPPING-START }
+# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START
+#                                                    FLOW-MAPPING-START KEY }
+# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START
+#                                                    FLOW-MAPPING-START KEY }
+
+# need to have full path with import, as pkg_resources tries to load parser.py in __init__.py
+# only to not do anything with the package afterwards
+# and for Jython too
+
+
+from opentelemetry.agent._vendor.ruamel.yaml.error import MarkedYAMLError
+from opentelemetry.agent._vendor.ruamel.yaml.tokens import *  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.events import *  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.scanner import Scanner, RoundTripScanner, ScannerError  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.scanner import BlankLineComment
+from opentelemetry.agent._vendor.ruamel.yaml.comments import C_PRE, C_POST, C_SPLIT_ON_FIRST_BLANK
+from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, nprintf  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Optional  # NOQA
+
+__all__ = ['Parser', 'RoundTripParser', 'ParserError']
+
+
+def xprintf(*args: Any, **kw: Any) -> Any:
+    return nprintf(*args, **kw)
+    pass
+
+
+class ParserError(MarkedYAMLError):
+    pass
+
+
+class Parser:
+    # Since writing a recursive-descendant parser is a straightforward task, we
+    # do not give many comments here.
+
+    DEFAULT_TAGS = {'!': '!', '!!': 'tag:yaml.org,2002:'}
+
+    def __init__(self, loader: Any) -> None:
+        self.loader = loader
+        if self.loader is not None and getattr(self.loader, '_parser', None) is None:
+            self.loader._parser = self
+        self.reset_parser()
+
+    def reset_parser(self) -> None:
+        # Reset the state attributes (to clear self-references)
+        self.current_event = self.last_event = None
+        self.tag_handles: Dict[Any, Any] = {}
+        self.states: List[Any] = []
+        self.marks: List[Any] = []
+        self.state: Any = self.parse_stream_start
+
+    def dispose(self) -> None:
+        self.reset_parser()
+
+    @property
+    def scanner(self) -> Any:
+        if hasattr(self.loader, 'typ'):
+            return self.loader.scanner
+        return self.loader._scanner
+
+    @property
+    def resolver(self) -> Any:
+        if hasattr(self.loader, 'typ'):
+            return self.loader.resolver
+        return self.loader._resolver
+
+    def check_event(self, *choices: Any) -> bool:
+        # Check the type of the next event.
+        if self.current_event is None:
+            if self.state:
+                self.current_event = self.state()
+        if self.current_event is not None:
+            if not choices:
+                return True
+            for choice in choices:
+                if isinstance(self.current_event, choice):
+                    return True
+        return False
+
+    def peek_event(self) -> Any:
+        # Get the next event.
+        if self.current_event is None:
+            if self.state:
+                self.current_event = self.state()
+        return self.current_event
+
+    def get_event(self) -> Any:
+        # Get the next event and proceed further.
+        if self.current_event is None:
+            if self.state:
+                self.current_event = self.state()
+        # assert self.current_event is not None
+        # if self.current_event.end_mark.line != self.peek_event().start_mark.line:
+        # xprintf('get_event', repr(self.current_event), self.peek_event().start_mark.line)
+        self.last_event = value = self.current_event
+        self.current_event = None
+        return value
+
+    # stream    ::= STREAM-START implicit_document? explicit_document*
+    #                                                               STREAM-END
+    # implicit_document ::= block_node DOCUMENT-END*
+    # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
+
+    def parse_stream_start(self) -> Any:
+        # Parse the stream start.
+        token = self.scanner.get_token()
+        self.move_token_comment(token)
+        event = StreamStartEvent(token.start_mark, token.end_mark, encoding=token.encoding)
+
+        # Prepare the next state.
+        self.state = self.parse_implicit_document_start
+
+        return event
+
+    def parse_implicit_document_start(self) -> Any:
+        # Parse an implicit document.
+        if not self.scanner.check_token(DirectiveToken, DocumentStartToken, StreamEndToken):
+            # don't need copy, as an implicit tag doesn't add tag_handles
+            self.tag_handles = self.DEFAULT_TAGS
+            token = self.scanner.peek_token()
+            start_mark = end_mark = token.start_mark
+            event = DocumentStartEvent(start_mark, end_mark, explicit=False)
+
+            # Prepare the next state.
+            self.states.append(self.parse_document_end)
+            self.state = self.parse_block_node
+
+            return event
+
+        else:
+            return self.parse_document_start()
+
+    def parse_document_start(self) -> Any:
+        # Parse any extra document end indicators.
+        while self.scanner.check_token(DocumentEndToken):
+            self.scanner.get_token()
+        # Parse an explicit document.
+        if not self.scanner.check_token(StreamEndToken):
+            version, tags = self.process_directives()
+            if not self.scanner.check_token(DocumentStartToken):
+                raise ParserError(
+                    None,
+                    None,
+                    "expected '', "
+                    f'but found {self.scanner.peek_token().id,!r}',
+                    self.scanner.peek_token().start_mark,
+                )
+            token = self.scanner.get_token()
+            start_mark = token.start_mark
+            end_mark = token.end_mark
+            # if self.loader is not None and \
+            #    end_mark.line != self.scanner.peek_token().start_mark.line:
+            #     self.loader.scalar_after_indicator = False
+            event: Any = DocumentStartEvent(
+                start_mark,
+                end_mark,
+                explicit=True,
+                version=version,
+                tags=tags,
+                comment=token.comment,
+            )
+            self.states.append(self.parse_document_end)
+            self.state = self.parse_document_content
+        else:
+            # Parse the end of the stream.
+            token = self.scanner.get_token()
+            event = StreamEndEvent(token.start_mark, token.end_mark, comment=token.comment)
+            assert not self.states
+            assert not self.marks
+            self.state = None
+        return event
+
+    def parse_document_end(self) -> Any:
+        # Parse the document end.
+        token = self.scanner.peek_token()
+        start_mark = end_mark = token.start_mark
+        explicit = False
+        if self.scanner.check_token(DocumentEndToken):
+            token = self.scanner.get_token()
+            # if token.end_mark.line != self.peek_event().start_mark.line:
+            pt = self.scanner.peek_token()
+            if not isinstance(pt, StreamEndToken) and (
+                token.end_mark.line == pt.start_mark.line
+            ):
+                raise ParserError(
+                    None,
+                    None,
+                    'found non-comment content after document end marker, '
+                    f'{self.scanner.peek_token().id,!r}',
+                    self.scanner.peek_token().start_mark,
+                )
+            end_mark = token.end_mark
+            explicit = True
+        event = DocumentEndEvent(start_mark, end_mark, explicit=explicit)
+
+        # Prepare the next state.
+        if self.resolver.processing_version == (1, 1):
+            self.state = self.parse_document_start
+        else:
+            if explicit:
+                # found a document end marker, can be followed by implicit document
+                self.state = self.parse_implicit_document_start
+            else:
+                self.state = self.parse_document_start
+
+        return event
+
+    def parse_document_content(self) -> Any:
+        if self.scanner.check_token(
+            DirectiveToken, DocumentStartToken, DocumentEndToken, StreamEndToken,
+        ):
+            event = self.process_empty_scalar(self.scanner.peek_token().start_mark)
+            self.state = self.states.pop()
+            return event
+        else:
+            return self.parse_block_node()
+
+    def process_directives(self) -> Any:
+        yaml_version = None
+        self.tag_handles = {}
+        while self.scanner.check_token(DirectiveToken):
+            token = self.scanner.get_token()
+            if token.name == 'YAML':
+                if yaml_version is not None:
+                    raise ParserError(
+                        None, None, 'found duplicate YAML directive', token.start_mark,
+                    )
+                major, minor = token.value
+                if major != 1:
+                    raise ParserError(
+                        None,
+                        None,
+                        'found incompatible YAML document (version 1.* is required)',
+                        token.start_mark,
+                    )
+                yaml_version = token.value
+            elif token.name == 'TAG':
+                handle, prefix = token.value
+                if handle in self.tag_handles:
+                    raise ParserError(
+                        None, None, f'duplicate tag handle {handle!r}', token.start_mark,
+                    )
+                self.tag_handles[handle] = prefix
+        if bool(self.tag_handles):
+            value: Any = (yaml_version, self.tag_handles.copy())
+        else:
+            value = yaml_version, None
+        if self.loader is not None and hasattr(self.loader, 'tags'):
+            # ToDo: this is used to keep a single loaded file from losing its version
+            # info, but  it affects following versions that have no explicit directive
+            self.loader.version = yaml_version
+            if self.loader.tags is None:
+                self.loader.tags = {}
+            for k in self.tag_handles:
+                self.loader.tags[k] = self.tag_handles[k]
+                self.loader.doc_infos[-1].tags.append((k, self.tag_handles[k]))
+        for key in self.DEFAULT_TAGS:
+            if key not in self.tag_handles:
+                self.tag_handles[key] = self.DEFAULT_TAGS[key]
+        return value
+
+    # block_node_or_indentless_sequence ::= ALIAS
+    #               | properties (block_content | indentless_block_sequence)?
+    #               | block_content
+    #               | indentless_block_sequence
+    # block_node    ::= ALIAS
+    #                   | properties block_content?
+    #                   | block_content
+    # flow_node     ::= ALIAS
+    #                   | properties flow_content?
+    #                   | flow_content
+    # properties    ::= TAG ANCHOR? | ANCHOR TAG?
+    # block_content     ::= block_collection | flow_collection | SCALAR
+    # flow_content      ::= flow_collection | SCALAR
+    # block_collection  ::= block_sequence | block_mapping
+    # flow_collection   ::= flow_sequence | flow_mapping
+
+    def parse_block_node(self) -> Any:
+        return self.parse_node(block=True)
+
+    def parse_flow_node(self) -> Any:
+        return self.parse_node()
+
+    def parse_block_node_or_indentless_sequence(self) -> Any:
+        return self.parse_node(block=True, indentless_sequence=True)
+
+    # def transform_tag(self, handle: Any, suffix: Any) -> Any:
+    #     return self.tag_handles[handle] + suffix
+
+    def select_tag_transform(self, tag: Tag) -> None:
+        if tag is None:
+            return
+        tag.select_transform(False)
+
+    def parse_node(self, block: bool = False, indentless_sequence: bool = False) -> Any:
+        if self.scanner.check_token(AliasToken):
+            token = self.scanner.get_token()
+            event: Any = AliasEvent(token.value, token.start_mark, token.end_mark)
+            self.state = self.states.pop()
+            return event
+
+        anchor = None
+        tag = None
+        start_mark = end_mark = tag_mark = None
+        if self.scanner.check_token(AnchorToken):
+            token = self.scanner.get_token()
+            self.move_token_comment(token)
+            start_mark = token.start_mark
+            end_mark = token.end_mark
+            anchor = token.value
+            if self.scanner.check_token(TagToken):
+                token = self.scanner.get_token()
+                tag_mark = token.start_mark
+                end_mark = token.end_mark
+                # tag = token.value
+                tag = Tag(
+                    handle=token.value[0], suffix=token.value[1], handles=self.tag_handles,
+                )
+        elif self.scanner.check_token(TagToken):
+            token = self.scanner.get_token()
+            try:
+                self.move_token_comment(token)
+            except NotImplementedError:
+                pass
+            start_mark = tag_mark = token.start_mark
+            end_mark = token.end_mark
+            # tag = token.value
+            tag = Tag(handle=token.value[0], suffix=token.value[1], handles=self.tag_handles)
+            if self.scanner.check_token(AnchorToken):
+                token = self.scanner.get_token()
+                start_mark = tag_mark = token.start_mark
+                end_mark = token.end_mark
+                anchor = token.value
+        if tag is not None:
+            self.select_tag_transform(tag)
+            if tag.check_handle():
+                raise ParserError(
+                    'while parsing a node',
+                    start_mark,
+                    f'found undefined tag handle {tag.handle!r}',
+                    tag_mark,
+                )
+        if start_mark is None:
+            start_mark = end_mark = self.scanner.peek_token().start_mark
+        event = None
+        implicit = tag is None or str(tag) == '!'
+        if indentless_sequence and self.scanner.check_token(BlockEntryToken):
+            comment = None
+            pt = self.scanner.peek_token()
+            if self.loader and self.loader.comment_handling is None:
+                if pt.comment and pt.comment[0]:
+                    comment = [pt.comment[0], []]
+                    pt.comment[0] = None
+                elif pt.comment and pt.comment[0] is None and pt.comment[1]:
+                    comment = [None, pt.comment[1]]
+                    pt.comment[1] = None
+            elif self.loader:
+                if pt.comment:
+                    comment = pt.comment
+            end_mark = self.scanner.peek_token().end_mark
+            event = SequenceStartEvent(
+                anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment,
+            )
+            self.state = self.parse_indentless_sequence_entry
+            return event
+
+        if self.scanner.check_token(ScalarToken):
+            token = self.scanner.get_token()
+            # self.scanner.peek_token_same_line_comment(token)
+            end_mark = token.end_mark
+            if (token.plain and tag is None) or str(tag) == '!':
+                dimplicit = (True, False)
+            elif tag is None:
+                dimplicit = (False, True)
+            else:
+                dimplicit = (False, False)
+            event = ScalarEvent(
+                anchor,
+                tag,
+                dimplicit,
+                token.value,
+                start_mark,
+                end_mark,
+                style=token.style,
+                comment=token.comment,
+            )
+            self.state = self.states.pop()
+        elif self.scanner.check_token(FlowSequenceStartToken):
+            pt = self.scanner.peek_token()
+            end_mark = pt.end_mark
+            event = SequenceStartEvent(
+                anchor,
+                tag,
+                implicit,
+                start_mark,
+                end_mark,
+                flow_style=True,
+                comment=pt.comment,
+            )
+            self.state = self.parse_flow_sequence_first_entry
+        elif self.scanner.check_token(FlowMappingStartToken):
+            pt = self.scanner.peek_token()
+            end_mark = pt.end_mark
+            event = MappingStartEvent(
+                anchor,
+                tag,
+                implicit,
+                start_mark,
+                end_mark,
+                flow_style=True,
+                comment=pt.comment,
+            )
+            self.state = self.parse_flow_mapping_first_key
+        elif block and self.scanner.check_token(BlockSequenceStartToken):
+            end_mark = self.scanner.peek_token().start_mark
+            # should inserting the comment be dependent on the
+            # indentation?
+            pt = self.scanner.peek_token()
+            comment = pt.comment
+            # nprint('pt0', type(pt))
+            if comment is None or comment[1] is None:
+                comment = pt.split_old_comment()
+            # nprint('pt1', comment)
+            event = SequenceStartEvent(
+                anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment,
+            )
+            self.state = self.parse_block_sequence_first_entry
+        elif block and self.scanner.check_token(BlockMappingStartToken):
+            end_mark = self.scanner.peek_token().start_mark
+            comment = self.scanner.peek_token().comment
+            event = MappingStartEvent(
+                anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment,
+            )
+            self.state = self.parse_block_mapping_first_key
+        elif anchor is not None or tag is not None:
+            # Empty scalars are allowed even if a tag or an anchor is
+            # specified.
+            event = ScalarEvent(anchor, tag, (implicit, False), "", start_mark, end_mark)
+            self.state = self.states.pop()
+        else:
+            if block:
+                node = 'block'
+            else:
+                node = 'flow'
+            token = self.scanner.peek_token()
+            raise ParserError(
+                f'while parsing a {node!s} node',
+                start_mark,
+                f'expected the node content, but found {token.id!r}',
+                token.start_mark,
+            )
+        return event
+
+    # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)*
+    #                                                               BLOCK-END
+
+    def parse_block_sequence_first_entry(self) -> Any:
+        token = self.scanner.get_token()
+        # move any comment from start token
+        # self.move_token_comment(token)
+        self.marks.append(token.start_mark)
+        return self.parse_block_sequence_entry()
+
+    def parse_block_sequence_entry(self) -> Any:
+        if self.scanner.check_token(BlockEntryToken):
+            token = self.scanner.get_token()
+            self.move_token_comment(token)
+            if not self.scanner.check_token(BlockEntryToken, BlockEndToken):
+                self.states.append(self.parse_block_sequence_entry)
+                return self.parse_block_node()
+            else:
+                self.state = self.parse_block_sequence_entry
+                return self.process_empty_scalar(token.end_mark)
+        if not self.scanner.check_token(BlockEndToken):
+            token = self.scanner.peek_token()
+            raise ParserError(
+                'while parsing a block collection',
+                self.marks[-1],
+                f'expected , but found {token.id!r}',
+                token.start_mark,
+            )
+        token = self.scanner.get_token()  # BlockEndToken
+        event = SequenceEndEvent(token.start_mark, token.end_mark, comment=token.comment)
+        self.state = self.states.pop()
+        self.marks.pop()
+        return event
+
+    # indentless_sequence ::= (BLOCK-ENTRY block_node?)+
+
+    # indentless_sequence?
+    # sequence:
+    # - entry
+    #  - nested
+
+    def parse_indentless_sequence_entry(self) -> Any:
+        if self.scanner.check_token(BlockEntryToken):
+            token = self.scanner.get_token()
+            self.move_token_comment(token)
+            if not self.scanner.check_token(
+                BlockEntryToken, KeyToken, ValueToken, BlockEndToken,
+            ):
+                self.states.append(self.parse_indentless_sequence_entry)
+                return self.parse_block_node()
+            else:
+                self.state = self.parse_indentless_sequence_entry
+                return self.process_empty_scalar(token.end_mark)
+        token = self.scanner.peek_token()
+        c = None
+        if self.loader and self.loader.comment_handling is None:
+            c = token.comment
+            start_mark = token.start_mark
+        else:
+            start_mark = self.last_event.end_mark  # type: ignore
+            c = self.distribute_comment(token.comment, start_mark.line)  # type: ignore
+        event = SequenceEndEvent(start_mark, start_mark, comment=c)
+        self.state = self.states.pop()
+        return event
+
+    # block_mapping     ::= BLOCK-MAPPING_START
+    #                       ((KEY block_node_or_indentless_sequence?)?
+    #                       (VALUE block_node_or_indentless_sequence?)?)*
+    #                       BLOCK-END
+
+    def parse_block_mapping_first_key(self) -> Any:
+        token = self.scanner.get_token()
+        self.marks.append(token.start_mark)
+        return self.parse_block_mapping_key()
+
+    def parse_block_mapping_key(self) -> Any:
+        if self.scanner.check_token(KeyToken):
+            token = self.scanner.get_token()
+            self.move_token_comment(token)
+            if not self.scanner.check_token(KeyToken, ValueToken, BlockEndToken):
+                self.states.append(self.parse_block_mapping_value)
+                return self.parse_block_node_or_indentless_sequence()
+            else:
+                self.state = self.parse_block_mapping_value
+                return self.process_empty_scalar(token.end_mark)
+        if self.resolver.processing_version > (1, 1) and self.scanner.check_token(ValueToken):
+            self.state = self.parse_block_mapping_value
+            return self.process_empty_scalar(self.scanner.peek_token().start_mark)
+        if not self.scanner.check_token(BlockEndToken):
+            token = self.scanner.peek_token()
+            raise ParserError(
+                'while parsing a block mapping',
+                self.marks[-1],
+                f'expected , but found {token.id!r}',
+                token.start_mark,
+            )
+        token = self.scanner.get_token()
+        self.move_token_comment(token)
+        event = MappingEndEvent(token.start_mark, token.end_mark, comment=token.comment)
+        self.state = self.states.pop()
+        self.marks.pop()
+        return event
+
+    def parse_block_mapping_value(self) -> Any:
+        if self.scanner.check_token(ValueToken):
+            token = self.scanner.get_token()
+            # value token might have post comment move it to e.g. block
+            if self.scanner.check_token(ValueToken):
+                self.move_token_comment(token)
+            else:
+                if not self.scanner.check_token(KeyToken):
+                    self.move_token_comment(token, empty=True)
+                # else: empty value for this key cannot move token.comment
+            if not self.scanner.check_token(KeyToken, ValueToken, BlockEndToken):
+                self.states.append(self.parse_block_mapping_key)
+                return self.parse_block_node_or_indentless_sequence()
+            else:
+                self.state = self.parse_block_mapping_key
+                comment = token.comment
+                if comment is None:
+                    token = self.scanner.peek_token()
+                    comment = token.comment
+                    if comment:
+                        token._comment = [None, comment[1]]
+                        comment = [comment[0], None]
+                return self.process_empty_scalar(token.end_mark, comment=comment)
+        else:
+            self.state = self.parse_block_mapping_key
+            token = self.scanner.peek_token()
+            return self.process_empty_scalar(token.start_mark)
+
+    # flow_sequence     ::= FLOW-SEQUENCE-START
+    #                       (flow_sequence_entry FLOW-ENTRY)*
+    #                       flow_sequence_entry?
+    #                       FLOW-SEQUENCE-END
+    # flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+    #
+    # Note that while production rules for both flow_sequence_entry and
+    # flow_mapping_entry are equal, their interpretations are different.
+    # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?`
+    # generate an inline mapping (set syntax).
+
+    def parse_flow_sequence_first_entry(self) -> Any:
+        token = self.scanner.get_token()
+        self.marks.append(token.start_mark)
+        return self.parse_flow_sequence_entry(first=True)
+
+    def parse_flow_sequence_entry(self, first: bool = False) -> Any:
+        if not self.scanner.check_token(FlowSequenceEndToken):
+            if not first:
+                if self.scanner.check_token(FlowEntryToken):
+                    self.scanner.get_token()
+                else:
+                    token = self.scanner.peek_token()
+                    raise ParserError(
+                        'while parsing a flow sequence',
+                        self.marks[-1],
+                        f"expected ',' or ']', but got {token.id!r}",
+                        token.start_mark,
+                    )
+
+            if self.scanner.check_token(KeyToken):
+                token = self.scanner.peek_token()
+                event: Any = MappingStartEvent(
+                    None, None, True, token.start_mark, token.end_mark, flow_style=True,
+                )
+                self.state = self.parse_flow_sequence_entry_mapping_key
+                return event
+            elif not self.scanner.check_token(FlowSequenceEndToken):
+                self.states.append(self.parse_flow_sequence_entry)
+                return self.parse_flow_node()
+        token = self.scanner.get_token()
+        event = SequenceEndEvent(token.start_mark, token.end_mark, comment=token.comment)
+        self.state = self.states.pop()
+        self.marks.pop()
+        return event
+
+    def parse_flow_sequence_entry_mapping_key(self) -> Any:
+        token = self.scanner.get_token()
+        if not self.scanner.check_token(ValueToken, FlowEntryToken, FlowSequenceEndToken):
+            self.states.append(self.parse_flow_sequence_entry_mapping_value)
+            return self.parse_flow_node()
+        else:
+            self.state = self.parse_flow_sequence_entry_mapping_value
+            return self.process_empty_scalar(token.end_mark)
+
+    def parse_flow_sequence_entry_mapping_value(self) -> Any:
+        if self.scanner.check_token(ValueToken):
+            token = self.scanner.get_token()
+            if not self.scanner.check_token(FlowEntryToken, FlowSequenceEndToken):
+                self.states.append(self.parse_flow_sequence_entry_mapping_end)
+                return self.parse_flow_node()
+            else:
+                self.state = self.parse_flow_sequence_entry_mapping_end
+                return self.process_empty_scalar(token.end_mark)
+        else:
+            self.state = self.parse_flow_sequence_entry_mapping_end
+            token = self.scanner.peek_token()
+            return self.process_empty_scalar(token.start_mark)
+
+    def parse_flow_sequence_entry_mapping_end(self) -> Any:
+        self.state = self.parse_flow_sequence_entry
+        token = self.scanner.peek_token()
+        return MappingEndEvent(token.start_mark, token.start_mark)
+
+    # flow_mapping  ::= FLOW-MAPPING-START
+    #                   (flow_mapping_entry FLOW-ENTRY)*
+    #                   flow_mapping_entry?
+    #                   FLOW-MAPPING-END
+    # flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+
+    def parse_flow_mapping_first_key(self) -> Any:
+        token = self.scanner.get_token()
+        self.marks.append(token.start_mark)
+        return self.parse_flow_mapping_key(first=True)
+
+    def parse_flow_mapping_key(self, first: Any = False) -> Any:
+        if not self.scanner.check_token(FlowMappingEndToken):
+            if not first:
+                if self.scanner.check_token(FlowEntryToken):
+                    self.scanner.get_token()
+                else:
+                    token = self.scanner.peek_token()
+                    raise ParserError(
+                        'while parsing a flow mapping',
+                        self.marks[-1],
+                        f"expected ',' or '}}', but got {token.id!r}",
+                        token.start_mark,
+                    )
+            if self.scanner.check_token(KeyToken):
+                token = self.scanner.get_token()
+                if not self.scanner.check_token(
+                    ValueToken, FlowEntryToken, FlowMappingEndToken,
+                ):
+                    self.states.append(self.parse_flow_mapping_value)
+                    return self.parse_flow_node()
+                else:
+                    self.state = self.parse_flow_mapping_value
+                    return self.process_empty_scalar(token.end_mark)
+            elif self.resolver.processing_version > (1, 1) and self.scanner.check_token(
+                ValueToken,
+            ):
+                self.state = self.parse_flow_mapping_value
+                return self.process_empty_scalar(self.scanner.peek_token().end_mark)
+            elif not self.scanner.check_token(FlowMappingEndToken):
+                self.states.append(self.parse_flow_mapping_empty_value)
+                return self.parse_flow_node()
+        token = self.scanner.get_token()
+        event = MappingEndEvent(token.start_mark, token.end_mark, comment=token.comment)
+        self.state = self.states.pop()
+        self.marks.pop()
+        return event
+
+    def parse_flow_mapping_value(self) -> Any:
+        if self.scanner.check_token(ValueToken):
+            token = self.scanner.get_token()
+            if not self.scanner.check_token(FlowEntryToken, FlowMappingEndToken):
+                self.states.append(self.parse_flow_mapping_key)
+                return self.parse_flow_node()
+            else:
+                self.state = self.parse_flow_mapping_key
+                return self.process_empty_scalar(token.end_mark)
+        else:
+            self.state = self.parse_flow_mapping_key
+            token = self.scanner.peek_token()
+            return self.process_empty_scalar(token.start_mark)
+
+    def parse_flow_mapping_empty_value(self) -> Any:
+        self.state = self.parse_flow_mapping_key
+        return self.process_empty_scalar(self.scanner.peek_token().start_mark)
+
+    def process_empty_scalar(self, mark: Any, comment: Any = None) -> Any:
+        return ScalarEvent(None, None, (True, False), "", mark, mark, comment=comment)
+
+    def move_token_comment(
+        self, token: Any, nt: Optional[Any] = None, empty: Optional[bool] = False,
+    ) -> Any:
+        pass
+
+
+class RoundTripParser(Parser):
+    """roundtrip is a safe loader, that wants to see the unmangled tag"""
+
+    def select_tag_transform(self, tag: Tag) -> None:
+        if tag is None:
+            return
+        tag.select_transform(True)
+
+    def move_token_comment(
+        self, token: Any, nt: Optional[Any] = None, empty: Optional[bool] = False,
+    ) -> Any:
+        token.move_old_comment(self.scanner.peek_token() if nt is None else nt, empty=empty)
+
+
+class RoundTripParserSC(RoundTripParser):
+    """roundtrip is a safe loader, that wants to see the unmangled tag"""
+
+    # some of the differences are based on the superclass testing
+    # if self.loader.comment_handling is not None
+
+    def move_token_comment(
+        self: Any, token: Any, nt: Any = None, empty: Optional[bool] = False,
+    ) -> None:
+        token.move_new_comment(self.scanner.peek_token() if nt is None else nt, empty=empty)
+
+    def distribute_comment(self, comment: Any, line: Any) -> Any:
+        # ToDo, look at indentation of the comment to determine attachment
+        if comment is None:
+            return None
+        if not comment[0]:
+            return None
+        # if comment[0][0] != line + 1:
+        #     nprintf('>>>dcxxx', comment, line)
+        assert comment[0][0] == line + 1
+        # if comment[0] - line > 1:
+        #     return
+        typ = self.loader.comment_handling & 0b11
+        # nprintf('>>>dca', comment, line, typ)
+        if typ == C_POST:
+            return None
+        if typ == C_PRE:
+            c = [None, None, comment[0]]
+            comment[0] = None
+            return c
+        # nprintf('>>>dcb', comment[0])
+        for _idx, cmntidx in enumerate(comment[0]):
+            # nprintf('>>>dcb', cmntidx)
+            if isinstance(self.scanner.comments[cmntidx], BlankLineComment):
+                break
+        else:
+            return None  # no space found
+        if _idx == 0:
+            return None  # first line was blank
+        # nprintf('>>>dcc', idx)
+        if typ == C_SPLIT_ON_FIRST_BLANK:
+            c = [None, None, comment[0][:_idx]]
+            comment[0] = comment[0][_idx:]
+            return c
+        raise NotImplementedError  # reserved
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py
new file mode 100644
index 00000000000..beee35826ad
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py
@@ -0,0 +1,277 @@
+
+from __future__ import annotations
+
+# This module contains abstractions for the input stream. You don't have to
+# looks further, there are no pretty code.
+#
+# We define two classes here.
+#
+#   Mark(source, line, column)
+# It's just a record and its only use is producing nice error messages.
+# Parser does not use it for any other purposes.
+#
+#   Reader(source, data)
+# Reader determines the encoding of `data` and converts it to unicode.
+# Reader provides the following methods and attributes:
+#   reader.peek(length=1) - return the next `length` characters
+#   reader.forward(length=1) - move the current position to `length`
+#      characters.
+#   reader.index - the number of the current character.
+#   reader.line, stream.column - the line and the column of the current
+#      character.
+
+import codecs
+
+from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError, FileMark, StringMark, YAMLStreamError
+from opentelemetry.agent._vendor.ruamel.yaml.util import RegExp
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Union, Text, Tuple, Optional  # NOQA
+# from ruamel.yaml.compat import StreamTextType  # NOQA
+
+__all__ = ['Reader', 'ReaderError']
+
+
+class ReaderError(YAMLError):
+    def __init__(  # NOQA
+        self, name: Any, position: Any, character: Any, encoding: Any, reason: Any,
+    ) -> None:
+        self.name = name
+        self.character = character
+        self.position = position
+        self.encoding = encoding
+        self.reason = reason
+
+    def __str__(self) -> Any:
+        if isinstance(self.character, bytes):
+            return (
+                f"'{self.encoding!s}' codec can't decode byte #x{ord(self.character):02x}: "
+                f'{self.reason!s}\n'
+                f'  in "{self.name!s}", position {self.position:d}'
+            )
+        else:
+            return (
+                f'unacceptable character #x{self.character:04x}: {self.reason!s}\n'
+                f'  in "{self.name!s}", position {self.position:d}'
+            )
+
+
+class Reader:
+    # Reader:
+    # - determines the data encoding and converts it to a unicode string,
+    # - checks if characters are in allowed range,
+    # - adds '\0' to the end.
+
+    # Reader accepts
+    #  - a `bytes` object,
+    #  - a `str` object,
+    #  - a file-like object with its `read` method returning `str`,
+    #  - a file-like object with its `read` method returning `unicode`.
+
+    # Yeah, it's ugly and slow.
+
+    def __init__(self, stream: Any, loader: Any = None) -> None:
+        self.loader = loader
+        if self.loader is not None and getattr(self.loader, '_reader', None) is None:
+            self.loader._reader = self
+        self.reset_reader()
+        self.stream: Any = stream  # as .read is called
+
+    def reset_reader(self) -> None:
+        self.name: Any = None
+        self.stream_pointer = 0
+        self.eof = True
+        self.buffer = ""
+        self.pointer = 0
+        self.raw_buffer: Any = None
+        self.raw_decode = None
+        self.encoding: Optional[Text] = None
+        self.index = 0
+        self.line = 0
+        self.column = 0
+
+    @property
+    def stream(self) -> Any:
+        try:
+            return self._stream
+        except AttributeError:
+            raise YAMLStreamError('input stream needs to be specified')
+
+    @stream.setter
+    def stream(self, val: Any) -> None:
+        if val is None:
+            return
+        self._stream = None
+        if isinstance(val, str):
+            self.name = ''
+            self.check_printable(val)
+            self.buffer = val + '\0'
+        elif isinstance(val, bytes):
+            self.name = ''
+            self.raw_buffer = val
+            self.determine_encoding()
+        else:
+            if not hasattr(val, 'read'):
+                raise YAMLStreamError('stream argument needs to have a read() method')
+            self._stream = val
+            self.name = getattr(self.stream, 'name', '')
+            self.eof = False
+            self.raw_buffer = None
+            self.determine_encoding()
+
+    def peek(self, index: int = 0) -> Text:
+        try:
+            return self.buffer[self.pointer + index]
+        except IndexError:
+            self.update(index + 1)
+            return self.buffer[self.pointer + index]
+
+    def prefix(self, length: int = 1) -> Any:
+        if self.pointer + length >= len(self.buffer):
+            self.update(length)
+        return self.buffer[self.pointer : self.pointer + length]
+
+    def forward_1_1(self, length: int = 1) -> None:
+        if self.pointer + length + 1 >= len(self.buffer):
+            self.update(length + 1)
+        while length != 0:
+            ch = self.buffer[self.pointer]
+            self.pointer += 1
+            self.index += 1
+            if ch in '\n\x85\u2028\u2029' or (
+                ch == '\r' and self.buffer[self.pointer] != '\n'
+            ):
+                self.line += 1
+                self.column = 0
+            elif ch != '\uFEFF':
+                self.column += 1
+            length -= 1
+
+    def forward(self, length: int = 1) -> None:
+        if self.pointer + length + 1 >= len(self.buffer):
+            self.update(length + 1)
+        while length != 0:
+            ch = self.buffer[self.pointer]
+            self.pointer += 1
+            self.index += 1
+            if ch == '\n' or (ch == '\r' and self.buffer[self.pointer] != '\n'):
+                self.line += 1
+                self.column = 0
+            elif ch != '\uFEFF':
+                self.column += 1
+            length -= 1
+
+    def get_mark(self) -> Any:
+        if self.stream is None:
+            return StringMark(
+                self.name, self.index, self.line, self.column, self.buffer, self.pointer,
+            )
+        else:
+            return FileMark(self.name, self.index, self.line, self.column)
+
+    def determine_encoding(self) -> None:
+        while not self.eof and (self.raw_buffer is None or len(self.raw_buffer) < 2):
+            self.update_raw()
+        if isinstance(self.raw_buffer, bytes):
+            if self.raw_buffer.startswith(codecs.BOM_UTF16_LE):
+                self.raw_decode = codecs.utf_16_le_decode  # type: ignore
+                self.encoding = 'utf-16-le'
+            elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE):
+                self.raw_decode = codecs.utf_16_be_decode  # type: ignore
+                self.encoding = 'utf-16-be'
+            else:
+                self.raw_decode = codecs.utf_8_decode  # type: ignore
+                self.encoding = 'utf-8'
+        self.update(1)
+
+    NON_PRINTABLE = RegExp(
+        '[^\x09\x0A\x0D\x20-\x7E\x85' '\xA0-\uD7FF' '\uE000-\uFFFD' '\U00010000-\U0010FFFF' ']'  # NOQA
+    )
+
+    _printable_ascii = ('\x09\x0A\x0D' + "".join(map(chr, range(0x20, 0x7F)))).encode('ascii')
+
+    @classmethod
+    def _get_non_printable_ascii(cls: Text, data: bytes) -> Optional[Tuple[int, Text]]:  # type: ignore # NOQA
+        ascii_bytes = data.encode('ascii')  # type: ignore
+        non_printables = ascii_bytes.translate(None, cls._printable_ascii)  # type: ignore
+        if not non_printables:
+            return None
+        non_printable = non_printables[:1]
+        return ascii_bytes.index(non_printable), non_printable.decode('ascii')
+
+    @classmethod
+    def _get_non_printable_regex(cls, data: Text) -> Optional[Tuple[int, Text]]:
+        match = cls.NON_PRINTABLE.search(data)
+        if not bool(match):
+            return None
+        return match.start(), match.group()
+
+    @classmethod
+    def _get_non_printable(cls, data: Text) -> Optional[Tuple[int, Text]]:
+        try:
+            return cls._get_non_printable_ascii(data)  # type: ignore
+        except UnicodeEncodeError:
+            return cls._get_non_printable_regex(data)
+
+    def check_printable(self, data: Any) -> None:
+        non_printable_match = self._get_non_printable(data)
+        if non_printable_match is not None:
+            start, character = non_printable_match
+            position = self.index + (len(self.buffer) - self.pointer) + start
+            raise ReaderError(
+                self.name,
+                position,
+                ord(character),
+                'unicode',
+                'special characters are not allowed',
+            )
+
+    def update(self, length: int) -> None:
+        if self.raw_buffer is None:
+            return
+        self.buffer = self.buffer[self.pointer :]
+        self.pointer = 0
+        while len(self.buffer) < length:
+            if not self.eof:
+                self.update_raw()
+            if self.raw_decode is not None:
+                try:
+                    data, converted = self.raw_decode(self.raw_buffer, 'strict', self.eof)
+                except UnicodeDecodeError as exc:
+                    character = self.raw_buffer[exc.start]
+                    if self.stream is not None:
+                        position = self.stream_pointer - len(self.raw_buffer) + exc.start
+                    elif self.stream is not None:
+                        position = self.stream_pointer - len(self.raw_buffer) + exc.start
+                    else:
+                        position = exc.start
+                    raise ReaderError(self.name, position, character, exc.encoding, exc.reason)
+            else:
+                data = self.raw_buffer
+                converted = len(data)
+            self.check_printable(data)
+            self.buffer += data
+            self.raw_buffer = self.raw_buffer[converted:]
+            if self.eof:
+                self.buffer += '\0'
+                self.raw_buffer = None
+                break
+
+    def update_raw(self, size: Optional[int] = None) -> None:
+        if size is None:
+            size = 4096
+        data = self.stream.read(size)
+        if self.raw_buffer is None:
+            self.raw_buffer = data
+        else:
+            self.raw_buffer += data
+        self.stream_pointer += len(data)
+        if not data:
+            self.eof = True
+
+
+# try:
+#     import psyco
+#     psyco.bind(Reader)
+# except ImportError:
+#     pass
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py
new file mode 100644
index 00000000000..28e2a10607c
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py
@@ -0,0 +1,1139 @@
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.error import *  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.nodes import *  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.compat import ordereddict
+from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, nprintf  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.scalarstring import (
+    LiteralScalarString,
+    FoldedScalarString,
+    SingleQuotedScalarString,
+    DoubleQuotedScalarString,
+    PlainScalarString,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.comments import (
+    CommentedMap,
+    CommentedOrderedMap,
+    CommentedSeq,
+    CommentedKeySeq,
+    CommentedKeyMap,
+    CommentedSet,
+    comment_attrib,
+    merge_attrib,
+    TaggedScalar,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.scalarint import ScalarInt, BinaryInt, OctalInt, HexInt, HexCapsInt
+from opentelemetry.agent._vendor.ruamel.yaml.scalarfloat import ScalarFloat
+from opentelemetry.agent._vendor.ruamel.yaml.scalarbool import ScalarBoolean
+from opentelemetry.agent._vendor.ruamel.yaml.timestamp import TimeStamp
+from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
+
+import collections
+import datetime
+import types
+
+import copyreg
+import base64
+
+if False:  # MYPY
+    from typing import Dict, List, Any, Union, Text, Optional  # NOQA
+
+# fmt: off
+__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
+           'RepresenterError', 'RoundTripRepresenter']
+# fmt: on
+
+
+class RepresenterError(YAMLError):
+    pass
+
+
+class BaseRepresenter:
+
+    yaml_representers: Dict[Any, Any] = {}
+    yaml_multi_representers: Dict[Any, Any] = {}
+
+    def __init__(
+        self: Any,
+        default_style: Any = None,
+        default_flow_style: Any = None,
+        dumper: Any = None,
+    ) -> None:
+        self.dumper = dumper
+        if self.dumper is not None:
+            self.dumper._representer = self
+        self.default_style = default_style
+        self.default_flow_style = default_flow_style
+        self.represented_objects: Dict[Any, Any] = {}
+        self.object_keeper: List[Any] = []
+        self.alias_key: Optional[int] = None
+        self.sort_base_mapping_type_on_output = True
+
+    @property
+    def serializer(self) -> Any:
+        try:
+            if hasattr(self.dumper, 'typ'):
+                return self.dumper.serializer
+            return self.dumper._serializer
+        except AttributeError:
+            return self  # cyaml
+
+    def represent(self, data: Any) -> None:
+        node = self.represent_data(data)
+        self.serializer.serialize(node)
+        self.represented_objects = {}
+        self.object_keeper = []
+        self.alias_key = None
+
+    def represent_data(self, data: Any) -> Any:
+        if self.ignore_aliases(data):
+            self.alias_key = None
+        else:
+            self.alias_key = id(data)
+        if self.alias_key is not None:
+            if self.alias_key in self.represented_objects:
+                node = self.represented_objects[self.alias_key]
+                # if node is None:
+                #     raise RepresenterError(
+                #          f"recursive objects are not allowed: {data!r}")
+                return node
+            # self.represented_objects[alias_key] = None
+            self.object_keeper.append(data)
+        data_types = type(data).__mro__
+        if data_types[0] in self.yaml_representers:
+            node = self.yaml_representers[data_types[0]](self, data)
+        else:
+            for data_type in data_types:
+                if data_type in self.yaml_multi_representers:
+                    node = self.yaml_multi_representers[data_type](self, data)
+                    break
+            else:
+                if None in self.yaml_multi_representers:
+                    node = self.yaml_multi_representers[None](self, data)
+                elif None in self.yaml_representers:
+                    node = self.yaml_representers[None](self, data)
+                else:
+                    node = ScalarNode(None, str(data))
+        # if alias_key is not None:
+        #     self.represented_objects[alias_key] = node
+        return node
+
+    def represent_key(self, data: Any) -> Any:
+        """
+        David Fraser: Extract a method to represent keys in mappings, so that
+        a subclass can choose not to quote them (for example)
+        used in represent_mapping
+        https://bitbucket.org/davidfraser/pyyaml/commits/d81df6eb95f20cac4a79eed95ae553b5c6f77b8c
+        """
+        return self.represent_data(data)
+
+    @classmethod
+    def add_representer(cls, data_type: Any, representer: Any) -> None:
+        if 'yaml_representers' not in cls.__dict__:
+            cls.yaml_representers = cls.yaml_representers.copy()
+        cls.yaml_representers[data_type] = representer
+
+    @classmethod
+    def add_multi_representer(cls, data_type: Any, representer: Any) -> None:
+        if 'yaml_multi_representers' not in cls.__dict__:
+            cls.yaml_multi_representers = cls.yaml_multi_representers.copy()
+        cls.yaml_multi_representers[data_type] = representer
+
+    def represent_scalar(
+        self, tag: Any, value: Any, style: Any = None, anchor: Any = None,
+    ) -> ScalarNode:
+        if style is None:
+            style = self.default_style
+        comment = None
+        if style and style[0] in '|>':
+            comment = getattr(value, 'comment', None)
+            if comment:
+                comment = [None, [comment]]
+        if isinstance(tag, str):
+            tag = Tag(suffix=tag)
+        node = ScalarNode(tag, value, style=style, comment=comment, anchor=anchor)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        return node
+
+    def represent_sequence(
+        self, tag: Any, sequence: Any, flow_style: Any = None,
+    ) -> SequenceNode:
+        value: List[Any] = []
+        if isinstance(tag, str):
+            tag = Tag(suffix=tag)
+        node = SequenceNode(tag, value, flow_style=flow_style)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        for item in sequence:
+            node_item = self.represent_data(item)
+            if not (isinstance(node_item, ScalarNode) and not node_item.style):
+                best_style = False
+            value.append(node_item)
+        if flow_style is None:
+            if self.default_flow_style is not None:
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        return node
+
+    def represent_omap(self, tag: Any, omap: Any, flow_style: Any = None) -> SequenceNode:
+        value: List[Any] = []
+        if isinstance(tag, str):
+            tag = Tag(suffix=tag)
+        node = SequenceNode(tag, value, flow_style=flow_style)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        for item_key in omap:
+            item_val = omap[item_key]
+            node_item = self.represent_data({item_key: item_val})
+            # if not (isinstance(node_item, ScalarNode) \
+            #    and not node_item.style):
+            #     best_style = False
+            value.append(node_item)
+        if flow_style is None:
+            if self.default_flow_style is not None:
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        return node
+
+    def represent_mapping(self, tag: Any, mapping: Any, flow_style: Any = None) -> MappingNode:
+        value: List[Any] = []
+        if isinstance(tag, str):
+            tag = Tag(suffix=tag)
+        node = MappingNode(tag, value, flow_style=flow_style)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        if hasattr(mapping, 'items'):
+            mapping = list(mapping.items())
+            if self.sort_base_mapping_type_on_output:
+                try:
+                    mapping = sorted(mapping)
+                except TypeError:
+                    pass
+        for item_key, item_value in mapping:
+            node_key = self.represent_key(item_key)
+            node_value = self.represent_data(item_value)
+            if not (isinstance(node_key, ScalarNode) and not node_key.style):
+                best_style = False
+            if not (isinstance(node_value, ScalarNode) and not node_value.style):
+                best_style = False
+            value.append((node_key, node_value))
+        if flow_style is None:
+            if self.default_flow_style is not None:
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        return node
+
+    def ignore_aliases(self, data: Any) -> bool:
+        return False
+
+
+class SafeRepresenter(BaseRepresenter):
+    def ignore_aliases(self, data: Any) -> bool:
+        # https://docs.python.org/3/reference/expressions.html#parenthesized-forms :
+        # "i.e. two occurrences of the empty tuple may or may not yield the same object"
+        # so "data is ()" should not be used
+        if data is None or (isinstance(data, tuple) and data == ()):
+            return True
+        if isinstance(data, (bytes, str, bool, int, float)):
+            return True
+        return False
+
+    def represent_none(self, data: Any) -> ScalarNode:
+        return self.represent_scalar('tag:yaml.org,2002:null', 'null')
+
+    def represent_str(self, data: Any) -> Any:
+        return self.represent_scalar('tag:yaml.org,2002:str', data)
+
+    def represent_binary(self, data: Any) -> ScalarNode:
+        if hasattr(base64, 'encodebytes'):
+            data = base64.encodebytes(data).decode('ascii')
+        else:
+            # check py2 only?
+            data = base64.encodestring(data).decode('ascii')  # type: ignore
+        return self.represent_scalar('tag:yaml.org,2002:binary', data, style='|')
+
+    def represent_bool(self, data: Any, anchor: Optional[Any] = None) -> ScalarNode:
+        try:
+            value = self.dumper.boolean_representation[bool(data)]
+        except AttributeError:
+            if data:
+                value = 'true'
+            else:
+                value = 'false'
+        return self.represent_scalar('tag:yaml.org,2002:bool', value, anchor=anchor)
+
+    def represent_int(self, data: Any) -> ScalarNode:
+        return self.represent_scalar('tag:yaml.org,2002:int', str(data))
+
+    inf_value = 1e300
+    while repr(inf_value) != repr(inf_value * inf_value):
+        inf_value *= inf_value
+
+    def represent_float(self, data: Any) -> ScalarNode:
+        if data != data or (data == 0.0 and data == 1.0):
+            value = '.nan'
+        elif data == self.inf_value:
+            value = '.inf'
+        elif data == -self.inf_value:
+            value = '-.inf'
+        else:
+            value = repr(data).lower()
+            if getattr(self.serializer, 'use_version', None) == (1, 1):
+                if '.' not in value and 'e' in value:
+                    # Note that in some cases `repr(data)` represents a float number
+                    # without the decimal parts.  For instance:
+                    #   >>> repr(1e17)
+                    #   '1e17'
+                    # Unfortunately, this is not a valid float representation according
+                    # to the definition of the `!!float` tag in YAML 1.1.  We fix
+                    # this by adding '.0' before the 'e' symbol.
+                    value = value.replace('e', '.0e', 1)
+        return self.represent_scalar('tag:yaml.org,2002:float', value)
+
+    def represent_list(self, data: Any) -> SequenceNode:
+        # pairs = (len(data) > 0 and isinstance(data, list))
+        # if pairs:
+        #     for item in data:
+        #         if not isinstance(item, tuple) or len(item) != 2:
+        #             pairs = False
+        #             break
+        # if not pairs:
+        return self.represent_sequence('tag:yaml.org,2002:seq', data)
+
+    # value = []
+    # for item_key, item_value in data:
+    #     value.append(self.represent_mapping('tag:yaml.org,2002:map',
+    #         [(item_key, item_value)]))
+    # return SequenceNode('tag:yaml.org,2002:pairs', value)
+
+    def represent_dict(self, data: Any) -> MappingNode:
+        return self.represent_mapping('tag:yaml.org,2002:map', data)
+
+    def represent_ordereddict(self, data: Any) -> SequenceNode:
+        return self.represent_omap('tag:yaml.org,2002:omap', data)
+
+    def represent_set(self, data: Any) -> MappingNode:
+        value: Dict[Any, None] = {}
+        for key in data:
+            value[key] = None
+        return self.represent_mapping('tag:yaml.org,2002:set', value)
+
+    def represent_date(self, data: Any) -> ScalarNode:
+        value = data.isoformat()
+        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
+
+    def represent_datetime(self, data: Any) -> ScalarNode:
+        value = data.isoformat(' ')
+        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
+
+    def represent_yaml_object(
+        self, tag: Any, data: Any, cls: Any, flow_style: Any = None,
+    ) -> MappingNode:
+        if hasattr(data, '__getstate__'):
+            state = data.__getstate__()
+        else:
+            state = data.__dict__.copy()
+        return self.represent_mapping(tag, state, flow_style=flow_style)
+
+    def represent_undefined(self, data: Any) -> None:
+        raise RepresenterError(f'cannot represent an object: {data!r}')
+
+
+SafeRepresenter.add_representer(type(None), SafeRepresenter.represent_none)
+
+SafeRepresenter.add_representer(str, SafeRepresenter.represent_str)
+
+SafeRepresenter.add_representer(bytes, SafeRepresenter.represent_binary)
+
+SafeRepresenter.add_representer(bool, SafeRepresenter.represent_bool)
+
+SafeRepresenter.add_representer(int, SafeRepresenter.represent_int)
+
+SafeRepresenter.add_representer(float, SafeRepresenter.represent_float)
+
+SafeRepresenter.add_representer(list, SafeRepresenter.represent_list)
+
+SafeRepresenter.add_representer(tuple, SafeRepresenter.represent_list)
+
+SafeRepresenter.add_representer(dict, SafeRepresenter.represent_dict)
+
+SafeRepresenter.add_representer(set, SafeRepresenter.represent_set)
+
+SafeRepresenter.add_representer(ordereddict, SafeRepresenter.represent_ordereddict)
+
+SafeRepresenter.add_representer(
+    collections.OrderedDict, SafeRepresenter.represent_ordereddict,
+)
+
+SafeRepresenter.add_representer(datetime.date, SafeRepresenter.represent_date)
+
+SafeRepresenter.add_representer(datetime.datetime, SafeRepresenter.represent_datetime)
+
+SafeRepresenter.add_representer(None, SafeRepresenter.represent_undefined)
+
+
+class Representer(SafeRepresenter):
+    def represent_complex(self, data: Any) -> Any:
+        if data.imag == 0.0:
+            data = repr(data.real)
+        elif data.real == 0.0:
+            data = f'{data.imag!r}j'
+        elif data.imag > 0:
+            data = f'{data.real!r}+{data.imag!r}j'
+        else:
+            data = f'{data.real!r}{data.imag!r}j'
+        return self.represent_scalar('tag:yaml.org,2002:python/complex', data)
+
+    def represent_tuple(self, data: Any) -> SequenceNode:
+        return self.represent_sequence('tag:yaml.org,2002:python/tuple', data)
+
+    def represent_name(self, data: Any) -> ScalarNode:
+        try:
+            name = f'{data.__module__!s}.{data.__qualname__!s}'
+        except AttributeError:
+            # ToDo: check if this can be reached in Py3
+            name = f'{data.__module__!s}.{data.__name__!s}'
+        return self.represent_scalar('tag:yaml.org,2002:python/name:' + name, "")
+
+    def represent_module(self, data: Any) -> ScalarNode:
+        return self.represent_scalar('tag:yaml.org,2002:python/module:' + data.__name__, "")
+
+    def represent_object(self, data: Any) -> Union[SequenceNode, MappingNode]:
+        # We use __reduce__ API to save the data. data.__reduce__ returns
+        # a tuple of length 2-5:
+        #   (function, args, state, listitems, dictitems)
+
+        # For reconstructing, we calls function(*args), then set its state,
+        # listitems, and dictitems if they are not None.
+
+        # A special case is when function.__name__ == '__newobj__'. In this
+        # case we create the object with args[0].__new__(*args).
+
+        # Another special case is when __reduce__ returns a string - we don't
+        # support it.
+
+        # We produce a !!python/object, !!python/object/new or
+        # !!python/object/apply node.
+
+        cls = type(data)
+        if cls in copyreg.dispatch_table:
+            reduce: Any = copyreg.dispatch_table[cls](data)
+        elif hasattr(data, '__reduce_ex__'):
+            reduce = data.__reduce_ex__(2)
+        elif hasattr(data, '__reduce__'):
+            reduce = data.__reduce__()
+        else:
+            raise RepresenterError(f'cannot represent object: {data!r}')
+        reduce = (list(reduce) + [None] * 5)[:5]
+        function, args, state, listitems, dictitems = reduce
+        args = list(args)
+        if state is None:
+            state = {}
+        if listitems is not None:
+            listitems = list(listitems)
+        if dictitems is not None:
+            dictitems = dict(dictitems)
+        if function.__name__ == '__newobj__':
+            function = args[0]
+            args = args[1:]
+            tag = 'tag:yaml.org,2002:python/object/new:'
+            newobj = True
+        else:
+            tag = 'tag:yaml.org,2002:python/object/apply:'
+            newobj = False
+        try:
+            function_name = f'{function.__module__!s}.{function.__qualname__!s}'
+        except AttributeError:
+            # ToDo: check if this can be reached in Py3
+            function_name = f'{function.__module__!s}.{function.__name__!s}'
+        if not args and not listitems and not dictitems and isinstance(state, dict) and newobj:
+            return self.represent_mapping(
+                'tag:yaml.org,2002:python/object:' + function_name, state,
+            )
+        if not listitems and not dictitems and isinstance(state, dict) and not state:
+            return self.represent_sequence(tag + function_name, args)
+        value = {}
+        if args:
+            value['args'] = args
+        if state or not isinstance(state, dict):
+            value['state'] = state
+        if listitems:
+            value['listitems'] = listitems
+        if dictitems:
+            value['dictitems'] = dictitems
+        return self.represent_mapping(tag + function_name, value)
+
+
+Representer.add_representer(complex, Representer.represent_complex)
+
+Representer.add_representer(tuple, Representer.represent_tuple)
+
+Representer.add_representer(type, Representer.represent_name)
+
+Representer.add_representer(types.FunctionType, Representer.represent_name)
+
+Representer.add_representer(types.BuiltinFunctionType, Representer.represent_name)
+
+Representer.add_representer(types.ModuleType, Representer.represent_module)
+
+Representer.add_multi_representer(object, Representer.represent_object)
+
+Representer.add_multi_representer(type, Representer.represent_name)
+
+
+class RoundTripRepresenter(SafeRepresenter):
+    # need to add type here and write out the .comment
+    # in serializer and emitter
+
+    def __init__(
+        self, default_style: Any = None, default_flow_style: Any = None, dumper: Any = None,
+    ) -> None:
+        if not hasattr(dumper, 'typ') and default_flow_style is None:
+            default_flow_style = False
+        SafeRepresenter.__init__(
+            self,
+            default_style=default_style,
+            default_flow_style=default_flow_style,
+            dumper=dumper,
+        )
+
+    def ignore_aliases(self, data: Any) -> bool:
+        try:
+            if data.anchor is not None and data.anchor.value is not None:
+                return False
+        except AttributeError:
+            pass
+        return SafeRepresenter.ignore_aliases(self, data)
+
+    def represent_none(self, data: Any) -> ScalarNode:
+        if len(self.represented_objects) == 0 and not self.serializer.use_explicit_start:
+            # this will be open ended (although it is not yet)
+            return self.represent_scalar('tag:yaml.org,2002:null', 'null')
+        return self.represent_scalar('tag:yaml.org,2002:null', "")
+
+    def represent_literal_scalarstring(self, data: Any) -> ScalarNode:
+        tag = None
+        style = '|'
+        anchor = data.yaml_anchor(any=True)
+        tag = 'tag:yaml.org,2002:str'
+        return self.represent_scalar(tag, data, style=style, anchor=anchor)
+
+    represent_preserved_scalarstring = represent_literal_scalarstring
+
+    def represent_folded_scalarstring(self, data: Any) -> ScalarNode:
+        tag = None
+        style = '>'
+        anchor = data.yaml_anchor(any=True)
+        for fold_pos in reversed(getattr(data, 'fold_pos', [])):
+            if (
+                data[fold_pos] == ' '
+                and (fold_pos > 0 and not data[fold_pos - 1].isspace())
+                and (fold_pos < len(data) and not data[fold_pos + 1].isspace())
+            ):
+                data = data[:fold_pos] + '\a' + data[fold_pos:]
+        tag = 'tag:yaml.org,2002:str'
+        return self.represent_scalar(tag, data, style=style, anchor=anchor)
+
+    def represent_single_quoted_scalarstring(self, data: Any) -> ScalarNode:
+        tag = None
+        style = "'"
+        anchor = data.yaml_anchor(any=True)
+        tag = 'tag:yaml.org,2002:str'
+        return self.represent_scalar(tag, data, style=style, anchor=anchor)
+
+    def represent_double_quoted_scalarstring(self, data: Any) -> ScalarNode:
+        tag = None
+        style = '"'
+        anchor = data.yaml_anchor(any=True)
+        tag = 'tag:yaml.org,2002:str'
+        return self.represent_scalar(tag, data, style=style, anchor=anchor)
+
+    def represent_plain_scalarstring(self, data: Any) -> ScalarNode:
+        tag = None
+        style = ''
+        anchor = data.yaml_anchor(any=True)
+        tag = 'tag:yaml.org,2002:str'
+        return self.represent_scalar(tag, data, style=style, anchor=anchor)
+
+    def insert_underscore(
+        self, prefix: Any, s: Any, underscore: Any, anchor: Any = None,
+    ) -> ScalarNode:
+        if underscore is None:
+            return self.represent_scalar('tag:yaml.org,2002:int', prefix + s, anchor=anchor)
+        if underscore[0]:
+            sl = list(s)
+            pos = len(s) - underscore[0]
+            while pos > 0:
+                sl.insert(pos, '_')
+                pos -= underscore[0]
+            s = "".join(sl)
+        if underscore[1]:
+            s = '_' + s
+        if underscore[2]:
+            s += '_'
+        return self.represent_scalar('tag:yaml.org,2002:int', prefix + s, anchor=anchor)
+
+    def represent_scalar_int(self, data: Any) -> ScalarNode:
+        if data._width is not None:
+            s = f'{data:0{data._width}d}'
+        else:
+            s = format(data, 'd')
+        anchor = data.yaml_anchor(any=True)
+        return self.insert_underscore("", s, data._underscore, anchor=anchor)
+
+    def represent_binary_int(self, data: Any) -> ScalarNode:
+        if data._width is not None:
+            # cannot use '{:#0{}b}', that strips the zeros
+            s = f'{data:0{data._width}b}'
+        else:
+            s = format(data, 'b')
+        anchor = data.yaml_anchor(any=True)
+        return self.insert_underscore('0b', s, data._underscore, anchor=anchor)
+
+    def represent_octal_int(self, data: Any) -> ScalarNode:
+        if data._width is not None:
+            # cannot use '{:#0{}o}', that strips the zeros
+            s = f'{data:0{data._width}o}'
+        else:
+            s = format(data, 'o')
+        anchor = data.yaml_anchor(any=True)
+        prefix = '0o'
+        if getattr(self.serializer, 'use_version', None) == (1, 1):
+            prefix = '0'
+        return self.insert_underscore(prefix, s, data._underscore, anchor=anchor)
+
+    def represent_hex_int(self, data: Any) -> ScalarNode:
+        if data._width is not None:
+            # cannot use '{:#0{}x}', that strips the zeros
+            s = f'{data:0{data._width}x}'
+        else:
+            s = format(data, 'x')
+        anchor = data.yaml_anchor(any=True)
+        return self.insert_underscore('0x', s, data._underscore, anchor=anchor)
+
+    def represent_hex_caps_int(self, data: Any) -> ScalarNode:
+        if data._width is not None:
+            # cannot use '{:#0{}X}', that strips the zeros
+            s = f'{data:0{data._width}X}'
+        else:
+            s = format(data, 'X')
+        anchor = data.yaml_anchor(any=True)
+        return self.insert_underscore('0x', s, data._underscore, anchor=anchor)
+
+    def represent_scalar_float(self, data: Any) -> ScalarNode:
+        """ this is way more complicated """
+        value = None
+        anchor = data.yaml_anchor(any=True)
+        if data != data or (data == 0.0 and data == 1.0):
+            value = '.nan'
+        elif data == self.inf_value:
+            value = '.inf'
+        elif data == -self.inf_value:
+            value = '-.inf'
+        if value:
+            return self.represent_scalar('tag:yaml.org,2002:float', value, anchor=anchor)
+        if data._exp is None and data._prec > 0 and data._prec == data._width - 1:
+            # no exponent, but trailing dot
+            value = f'{data._m_sign if data._m_sign else ""}{abs(int(data)):d}.'
+        elif data._exp is None:
+            # no exponent, "normal" dot
+            prec = data._prec
+            ms = data._m_sign if data._m_sign else ""
+            if prec < 0:
+                value = f'{ms}{abs(int(data)):0{data._width - len(ms)}d}'
+            else:
+                # -1 for the dot
+                value = f'{ms}{abs(data):0{data._width - len(ms)}.{data._width - prec - 1}f}'
+                if prec == 0 or (prec == 1 and ms != ""):
+                    value = value.replace('0.', '.')
+            while len(value) < data._width:
+                value += '0'
+        else:
+            # exponent
+            (
+                m,
+                es,
+            ) = f'{data:{data._width}.{data._width + (1 if data._m_sign else 0)}e}'.split('e')
+            w = data._width if data._prec > 0 else (data._width + 1)
+            if data < 0:
+                w += 1
+            m = m[:w]
+            e = int(es)
+            m1, m2 = m.split('.')  # always second?
+            while len(m1) + len(m2) < data._width - (1 if data._prec >= 0 else 0):
+                m2 += '0'
+            if data._m_sign and data > 0:
+                m1 = '+' + m1
+            esgn = '+' if data._e_sign else ""
+            if data._prec < 0:  # mantissa without dot
+                if m2 != '0':
+                    e -= len(m2)
+                else:
+                    m2 = ""
+                while (len(m1) + len(m2) - (1 if data._m_sign else 0)) < data._width:
+                    m2 += '0'
+                    e -= 1
+                value = m1 + m2 + data._exp + f'{e:{esgn}0{data._e_width}d}'
+            elif data._prec == 0:  # mantissa with trailing dot
+                e -= len(m2)
+                value = m1 + m2 + '.' + data._exp + f'{e:{esgn}0{data._e_width}d}'
+            else:
+                if data._m_lead0 > 0:
+                    m2 = '0' * (data._m_lead0 - 1) + m1 + m2
+                    m1 = '0'
+                    m2 = m2[: -data._m_lead0]  # these should be zeros
+                    e += data._m_lead0
+                while len(m1) < data._prec:
+                    m1 += m2[0]
+                    m2 = m2[1:]
+                    e -= 1
+                value = m1 + '.' + m2 + data._exp + f'{e:{esgn}0{data._e_width}d}'
+
+        if value is None:
+            value = repr(data).lower()
+        return self.represent_scalar('tag:yaml.org,2002:float', value, anchor=anchor)
+
+    def represent_sequence(
+        self, tag: Any, sequence: Any, flow_style: Any = None,
+    ) -> SequenceNode:
+        value: List[Any] = []
+        # if the flow_style is None, the flow style tacked on to the object
+        # explicitly will be taken. If that is None as well the default flow
+        # style rules
+        try:
+            flow_style = sequence.fa.flow_style(flow_style)
+        except AttributeError:
+            flow_style = flow_style
+        try:
+            anchor = sequence.yaml_anchor()
+        except AttributeError:
+            anchor = None
+        if isinstance(tag, str):
+            tag = Tag(suffix=tag)
+        node = SequenceNode(tag, value, flow_style=flow_style, anchor=anchor)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        try:
+            comment = getattr(sequence, comment_attrib)
+            node.comment = comment.comment
+            # reset any comment already printed information
+            if node.comment and node.comment[1]:
+                for ct in node.comment[1]:
+                    ct.reset()
+            item_comments = comment.items
+            for v in item_comments.values():
+                if v and v[1]:
+                    for ct in v[1]:
+                        ct.reset()
+            item_comments = comment.items
+            if node.comment is None:
+                node.comment = comment.comment
+            else:
+                # as we are potentially going to extend this, make a new list
+                node.comment = comment.comment[:]
+            try:
+                node.comment.append(comment.end)
+            except AttributeError:
+                pass
+        except AttributeError:
+            item_comments = {}
+        for idx, item in enumerate(sequence):
+            node_item = self.represent_data(item)
+            self.merge_comments(node_item, item_comments.get(idx))
+            if not (isinstance(node_item, ScalarNode) and not node_item.style):
+                best_style = False
+            value.append(node_item)
+        if flow_style is None:
+            if len(sequence) != 0 and self.default_flow_style is not None:
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        return node
+
+    def merge_comments(self, node: Any, comments: Any) -> Any:
+        if comments is None:
+            assert hasattr(node, 'comment')
+            return node
+        if getattr(node, 'comment', None) is not None:
+            for idx, val in enumerate(comments):
+                if idx >= len(node.comment):
+                    continue
+                nc = node.comment[idx]
+                if nc is not None:
+                    assert val is None or val == nc
+                    comments[idx] = nc
+        node.comment = comments
+        return node
+
+    def represent_key(self, data: Any) -> Any:
+        if isinstance(data, CommentedKeySeq):
+            self.alias_key = None
+            return self.represent_sequence('tag:yaml.org,2002:seq', data, flow_style=True)
+        if isinstance(data, CommentedKeyMap):
+            self.alias_key = None
+            return self.represent_mapping('tag:yaml.org,2002:map', data, flow_style=True)
+        return SafeRepresenter.represent_key(self, data)
+
+    def represent_mapping(self, tag: Any, mapping: Any, flow_style: Any = None) -> MappingNode:
+        value: List[Any] = []
+        try:
+            flow_style = mapping.fa.flow_style(flow_style)
+        except AttributeError:
+            flow_style = flow_style
+        try:
+            anchor = mapping.yaml_anchor()
+        except AttributeError:
+            anchor = None
+        if isinstance(tag, str):
+            tag = Tag(suffix=tag)
+        node = MappingNode(tag, value, flow_style=flow_style, anchor=anchor)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        # no sorting! !!
+        try:
+            comment = getattr(mapping, comment_attrib)
+            if node.comment is None:
+                node.comment = comment.comment
+            else:
+                # as we are potentially going to extend this, make a new list
+                node.comment = comment.comment[:]
+            if node.comment and node.comment[1]:
+                for ct in node.comment[1]:
+                    ct.reset()
+            item_comments = comment.items
+            if self.dumper.comment_handling is None:
+                for v in item_comments.values():
+                    if v and v[1]:
+                        for ct in v[1]:
+                            ct.reset()
+                try:
+                    node.comment.append(comment.end)
+                except AttributeError:
+                    pass
+            else:
+                # NEWCMNT
+                pass
+        except AttributeError:
+            item_comments = {}
+        merge_value = getattr(mapping, merge_attrib, [])
+        # merge_list = [m[1] for m in merge_value]
+        # merge_list = [m for m in merge_value]
+        try:
+            # merge_pos = getattr(mapping, merge_attrib, [[0]])[0][0]
+            # print('merge_pos', merge_pos, merge_value.merge_pos)
+            merge_pos = merge_value.merge_pos  # type: ignore
+        except (AttributeError, IndexError):
+            merge_pos = 0
+        item_count = 0
+        # if bool(merge_list):
+        if len(merge_value) > 0:
+            items = mapping.non_merged_items()
+        else:
+            items = mapping.items()
+        for item_key, item_value in items:
+            item_count += 1
+            node_key = self.represent_key(item_key)
+            node_value = self.represent_data(item_value)
+            item_comment = item_comments.get(item_key)
+            if item_comment:
+                # assert getattr(node_key, 'comment', None) is None
+                # issue 351 did throw this because the comment from the list item was
+                # moved to the dict
+                node_key.comment = item_comment[:2]
+                nvc = getattr(node_value, 'comment', None)
+                if nvc is not None:  # end comment already there
+                    nvc[0] = item_comment[2]
+                    nvc[1] = item_comment[3]
+                else:
+                    node_value.comment = item_comment[2:]
+            if not (isinstance(node_key, ScalarNode) and not node_key.style):
+                best_style = False
+            if not (isinstance(node_value, ScalarNode) and not node_value.style):
+                best_style = False
+            value.append((node_key, node_value))
+        if flow_style is None:
+            if ((item_count != 0) or (len(merge_value) > 0)) and self.default_flow_style is not None:  # NOQA
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        if len(merge_value) > 0:
+            # because of the call to represent_data here, the anchors
+            # are marked as being used and thereby created
+            # if len(merge_list) == 1:
+            if merge_value.sequence is None:  # type: ignore
+                arg = self.represent_data(merge_value[0])
+            else:
+                # arg = self.represent_data(merge_list)
+                # arg.flow_style = True
+                arg = self.represent_data(merge_value.sequence)  # type: ignore
+            value.insert(
+                merge_pos, (ScalarNode(Tag(suffix='tag:yaml.org,2002:merge'), '<<'), arg),
+            )
+        return node
+
+    def represent_omap(self, tag: Any, omap: Any, flow_style: Any = None) -> SequenceNode:
+        value: List[Any] = []
+        try:
+            flow_style = omap.fa.flow_style(flow_style)
+        except AttributeError:
+            flow_style = flow_style
+        try:
+            anchor = omap.yaml_anchor()
+        except AttributeError:
+            anchor = None
+        if isinstance(tag, str):
+            tag = Tag(suffix=tag)
+        node = SequenceNode(tag, value, flow_style=flow_style, anchor=anchor)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        try:
+            comment = getattr(omap, comment_attrib)
+            if node.comment is None:
+                node.comment = comment.comment
+            else:
+                # as we are potentially going to extend this, make a new list
+                node.comment = comment.comment[:]
+            if node.comment and node.comment[1]:
+                for ct in node.comment[1]:
+                    ct.reset()
+            item_comments = comment.items
+            for v in item_comments.values():
+                if v and v[1]:
+                    for ct in v[1]:
+                        ct.reset()
+            try:
+                node.comment.append(comment.end)
+            except AttributeError:
+                pass
+        except AttributeError:
+            item_comments = {}
+        for item_key in omap:
+            item_val = omap[item_key]
+            node_item = self.represent_data({item_key: item_val})
+            # node_item.flow_style = False
+            # node item has two scalars in value: node_key and node_value
+            item_comment = item_comments.get(item_key)
+            if item_comment:
+                if item_comment[1]:
+                    node_item.comment = [None, item_comment[1]]
+                assert getattr(node_item.value[0][0], 'comment', None) is None
+                node_item.value[0][0].comment = [item_comment[0], None]
+                nvc = getattr(node_item.value[0][1], 'comment', None)
+                if nvc is not None:  # end comment already there
+                    nvc[0] = item_comment[2]
+                    nvc[1] = item_comment[3]
+                else:
+                    node_item.value[0][1].comment = item_comment[2:]
+            # if not (isinstance(node_item, ScalarNode) \
+            #    and not node_item.style):
+            #     best_style = False
+            value.append(node_item)
+        if flow_style is None:
+            if self.default_flow_style is not None:
+                node.flow_style = self.default_flow_style
+            else:
+                node.flow_style = best_style
+        return node
+
+    def represent_set(self, setting: Any) -> MappingNode:
+        flow_style = False
+        tag = Tag(suffix='tag:yaml.org,2002:set')
+        # return self.represent_mapping(tag, value)
+        value: List[Any] = []
+        flow_style = setting.fa.flow_style(flow_style)
+        try:
+            anchor = setting.yaml_anchor()
+        except AttributeError:
+            anchor = None
+        node = MappingNode(tag, value, flow_style=flow_style, anchor=anchor)
+        if self.alias_key is not None:
+            self.represented_objects[self.alias_key] = node
+        best_style = True
+        # no sorting! !!
+        try:
+            comment = getattr(setting, comment_attrib)
+            if node.comment is None:
+                node.comment = comment.comment
+            else:
+                # as we are potentially going to extend this, make a new list
+                node.comment = comment.comment[:]
+            if node.comment and node.comment[1]:
+                for ct in node.comment[1]:
+                    ct.reset()
+            item_comments = comment.items
+            for v in item_comments.values():
+                if v and v[1]:
+                    for ct in v[1]:
+                        ct.reset()
+            try:
+                node.comment.append(comment.end)
+            except AttributeError:
+                pass
+        except AttributeError:
+            item_comments = {}
+        for item_key in setting.odict:
+            node_key = self.represent_key(item_key)
+            node_value = self.represent_data(None)
+            item_comment = item_comments.get(item_key)
+            if item_comment:
+                assert getattr(node_key, 'comment', None) is None
+                node_key.comment = item_comment[:2]
+            node_key.style = '?'
+            node_value.style = '-' if flow_style else '?'
+            if not (isinstance(node_key, ScalarNode) and not node_key.style):
+                best_style = False
+            if not (isinstance(node_value, ScalarNode) and not node_value.style):
+                best_style = False
+            value.append((node_key, node_value))
+        best_style = best_style
+        return node
+
+    def represent_dict(self, data: Any) -> MappingNode:
+        """write out tag if saved on loading"""
+        try:
+            _ = data.tag
+        except AttributeError:
+            tag = Tag(suffix='tag:yaml.org,2002:map')
+        else:
+            if data.tag.trval:
+                if data.tag.startswith('!!'):
+                    tag = Tag(suffix='tag:yaml.org,2002:' + data.tag.trval[2:])
+                else:
+                    tag = data.tag
+            else:
+                tag = Tag(suffix='tag:yaml.org,2002:map')
+        return self.represent_mapping(tag, data)
+
+    def represent_list(self, data: Any) -> SequenceNode:
+        try:
+            _ = data.tag
+        except AttributeError:
+            tag = Tag(suffix='tag:yaml.org,2002:seq')
+        else:
+            if data.tag.trval:
+                if data.tag.startswith('!!'):
+                    tag = Tag(suffix='tag:yaml.org,2002:' + data.tag.trval[2:])
+                else:
+                    tag = data.tag
+            else:
+                tag = Tag(suffix='tag:yaml.org,2002:seq')
+        return self.represent_sequence(tag, data)
+
+    def represent_datetime(self, data: Any) -> ScalarNode:
+        inter = 'T' if data._yaml['t'] else ' '
+        _yaml = data._yaml
+        if False and _yaml['delta']:
+            data += _yaml['delta']
+            value = data.isoformat(inter)
+        else:
+            value = data.isoformat(inter).strip()
+        if False and _yaml['tz']:
+            value += _yaml['tz']
+        if data.tzinfo and str(data.tzinfo):
+            if value[-6] in '+-':
+                value = value[:-6] + str(data.tzinfo)
+        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
+
+    def represent_tagged_scalar(self, data: Any) -> ScalarNode:
+        try:
+            if data.tag.handle == '!!':
+                tag = f'{data.tag.handle} {data.tag.suffix}'
+            else:
+                tag = data.tag
+        except AttributeError:
+            tag = None
+        try:
+            anchor = data.yaml_anchor()
+        except AttributeError:
+            anchor = None
+        return self.represent_scalar(tag, data.value, style=data.style, anchor=anchor)
+
+    def represent_scalar_bool(self, data: Any) -> ScalarNode:
+        try:
+            anchor = data.yaml_anchor()
+        except AttributeError:
+            anchor = None
+        return SafeRepresenter.represent_bool(self, data, anchor=anchor)
+
+    def represent_yaml_object(
+        self, tag: Any, data: Any, cls: Any, flow_style: Optional[Any] = None,
+    ) -> MappingNode:
+        if hasattr(data, '__getstate__'):
+            state = data.__getstate__()
+        else:
+            state = data.__dict__.copy()
+        anchor = state.pop(Anchor.attrib, None)
+        res = self.represent_mapping(tag, state, flow_style=flow_style)
+        if anchor is not None:
+            res.anchor = anchor
+        return res
+
+
+RoundTripRepresenter.add_representer(type(None), RoundTripRepresenter.represent_none)
+
+RoundTripRepresenter.add_representer(
+    LiteralScalarString, RoundTripRepresenter.represent_literal_scalarstring,
+)
+
+RoundTripRepresenter.add_representer(
+    FoldedScalarString, RoundTripRepresenter.represent_folded_scalarstring,
+)
+
+RoundTripRepresenter.add_representer(
+    SingleQuotedScalarString, RoundTripRepresenter.represent_single_quoted_scalarstring,
+)
+
+RoundTripRepresenter.add_representer(
+    DoubleQuotedScalarString, RoundTripRepresenter.represent_double_quoted_scalarstring,
+)
+
+RoundTripRepresenter.add_representer(
+    PlainScalarString, RoundTripRepresenter.represent_plain_scalarstring,
+)
+
+# RoundTripRepresenter.add_representer(tuple, Representer.represent_tuple)
+
+RoundTripRepresenter.add_representer(ScalarInt, RoundTripRepresenter.represent_scalar_int)
+
+RoundTripRepresenter.add_representer(BinaryInt, RoundTripRepresenter.represent_binary_int)
+
+RoundTripRepresenter.add_representer(OctalInt, RoundTripRepresenter.represent_octal_int)
+
+RoundTripRepresenter.add_representer(HexInt, RoundTripRepresenter.represent_hex_int)
+
+RoundTripRepresenter.add_representer(HexCapsInt, RoundTripRepresenter.represent_hex_caps_int)
+
+RoundTripRepresenter.add_representer(ScalarFloat, RoundTripRepresenter.represent_scalar_float)
+
+RoundTripRepresenter.add_representer(ScalarBoolean, RoundTripRepresenter.represent_scalar_bool)
+
+RoundTripRepresenter.add_representer(CommentedSeq, RoundTripRepresenter.represent_list)
+
+RoundTripRepresenter.add_representer(CommentedMap, RoundTripRepresenter.represent_dict)
+
+RoundTripRepresenter.add_representer(
+    CommentedOrderedMap, RoundTripRepresenter.represent_ordereddict,
+)
+
+RoundTripRepresenter.add_representer(
+    collections.OrderedDict, RoundTripRepresenter.represent_ordereddict,
+)
+
+RoundTripRepresenter.add_representer(CommentedSet, RoundTripRepresenter.represent_set)
+
+RoundTripRepresenter.add_representer(
+    TaggedScalar, RoundTripRepresenter.represent_tagged_scalar,
+)
+
+RoundTripRepresenter.add_representer(TimeStamp, RoundTripRepresenter.represent_datetime)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py
new file mode 100644
index 00000000000..0365cfce84d
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py
@@ -0,0 +1,392 @@
+
+from __future__ import annotations
+
+import re
+
+if False:  # MYPY
+    from typing import Any, Dict, List, Union, Text, Optional  # NOQA
+    from opentelemetry.agent._vendor.ruamel.yaml.compat import VersionType  # NOQA
+
+from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
+from opentelemetry.agent._vendor.ruamel.yaml.compat import _DEFAULT_YAML_VERSION  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.error import *  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.util import RegExp  # NOQA
+
+__all__ = ['BaseResolver', 'Resolver', 'VersionedResolver']
+
+
+# fmt: off
+# resolvers consist of
+# - a list of applicable version
+# - a tag
+# - a regexp
+# - a list of first characters to match
+implicit_resolvers = [
+    ([(1, 2)],
+        'tag:yaml.org,2002:bool',
+        RegExp('''^(?:true|True|TRUE|false|False|FALSE)$''', re.X),
+        list('tTfF')),
+    ([(1, 1)],
+        'tag:yaml.org,2002:bool',
+        RegExp('''^(?:y|Y|yes|Yes|YES|n|N|no|No|NO
+        |true|True|TRUE|false|False|FALSE
+        |on|On|ON|off|Off|OFF)$''', re.X),
+        list('yYnNtTfFoO')),
+    ([(1, 2)],
+        'tag:yaml.org,2002:float',
+        RegExp('''^(?:
+         [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
+        |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
+        |[-+]?\\.[0-9_]+(?:[eE][-+][0-9]+)?
+        |[-+]?\\.(?:inf|Inf|INF)
+        |\\.(?:nan|NaN|NAN))$''', re.X),
+        list('-+0123456789.')),
+    ([(1, 1)],
+        'tag:yaml.org,2002:float',
+        RegExp('''^(?:
+         [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
+        |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
+        |\\.[0-9_]+(?:[eE][-+][0-9]+)?
+        |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*  # sexagesimal float
+        |[-+]?\\.(?:inf|Inf|INF)
+        |\\.(?:nan|NaN|NAN))$''', re.X),
+        list('-+0123456789.')),
+    ([(1, 2)],
+        'tag:yaml.org,2002:int',
+        RegExp('''^(?:[-+]?0b[0-1_]+
+        |[-+]?0o?[0-7_]+
+        |[-+]?[0-9_]+
+        |[-+]?0x[0-9a-fA-F_]+)$''', re.X),
+        list('-+0123456789')),
+    ([(1, 1)],
+        'tag:yaml.org,2002:int',
+        RegExp('''^(?:[-+]?0b[0-1_]+
+        |[-+]?0?[0-7_]+
+        |[-+]?(?:0|[1-9][0-9_]*)
+        |[-+]?0x[0-9a-fA-F_]+
+        |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),  # sexagesimal int
+        list('-+0123456789')),
+    ([(1, 2), (1, 1)],
+        'tag:yaml.org,2002:merge',
+        RegExp('^(?:<<)$'),
+        ['<']),
+    ([(1, 2), (1, 1)],
+        'tag:yaml.org,2002:null',
+        RegExp('''^(?: ~
+        |null|Null|NULL
+        | )$''', re.X),
+        ['~', 'n', 'N', '']),
+    ([(1, 2), (1, 1)],
+        'tag:yaml.org,2002:timestamp',
+        RegExp('''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
+        |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
+        (?:[Tt]|[ \\t]+)[0-9][0-9]?
+        :[0-9][0-9] :[0-9][0-9] (?:\\.[0-9]*)?
+        (?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
+        list('0123456789')),
+    ([(1, 2), (1, 1)],
+        'tag:yaml.org,2002:value',
+        RegExp('^(?:=)$'),
+        ['=']),
+    # The following resolver is only for documentation purposes. It cannot work
+    # because plain scalars cannot start with '!', '&', or '*'.
+    ([(1, 2), (1, 1)],
+        'tag:yaml.org,2002:yaml',
+        RegExp('^(?:!|&|\\*)$'),
+        list('!&*')),
+]
+# fmt: on
+
+
+class ResolverError(YAMLError):
+    pass
+
+
+class BaseResolver:
+
+    DEFAULT_SCALAR_TAG = Tag(suffix='tag:yaml.org,2002:str')
+    DEFAULT_SEQUENCE_TAG = Tag(suffix='tag:yaml.org,2002:seq')
+    DEFAULT_MAPPING_TAG = Tag(suffix='tag:yaml.org,2002:map')
+
+    yaml_implicit_resolvers: Dict[Any, Any] = {}
+    yaml_path_resolvers: Dict[Any, Any] = {}
+
+    def __init__(self: Any, loadumper: Any = None) -> None:
+        self.loadumper = loadumper
+        if self.loadumper is not None and getattr(self.loadumper, '_resolver', None) is None:
+            self.loadumper._resolver = self.loadumper
+        self._loader_version: Any = None
+        self.resolver_exact_paths: List[Any] = []
+        self.resolver_prefix_paths: List[Any] = []
+
+    @property
+    def parser(self) -> Any:
+        if self.loadumper is not None:
+            if hasattr(self.loadumper, 'typ'):
+                return self.loadumper.parser
+            return self.loadumper._parser
+        return None
+
+    @classmethod
+    def add_implicit_resolver_base(cls, tag: Any, regexp: Any, first: Any) -> None:
+        if 'yaml_implicit_resolvers' not in cls.__dict__:
+            # deepcopy doesn't work here
+            cls.yaml_implicit_resolvers = {
+                k: cls.yaml_implicit_resolvers[k][:] for k in cls.yaml_implicit_resolvers
+            }
+        if first is None:
+            first = [None]
+        for ch in first:
+            cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
+
+    @classmethod
+    def add_implicit_resolver(cls, tag: Any, regexp: Any, first: Any) -> None:
+        if 'yaml_implicit_resolvers' not in cls.__dict__:
+            # deepcopy doesn't work here
+            cls.yaml_implicit_resolvers = {
+                k: cls.yaml_implicit_resolvers[k][:] for k in cls.yaml_implicit_resolvers
+            }
+        if first is None:
+            first = [None]
+        for ch in first:
+            cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
+        implicit_resolvers.append(([(1, 2), (1, 1)], tag, regexp, first))
+
+    # @classmethod
+    # def add_implicit_resolver(cls, tag, regexp, first):
+
+    @classmethod
+    def add_path_resolver(cls, tag: Any, path: Any, kind: Any = None) -> None:
+        # Note: `add_path_resolver` is experimental.  The API could be changed.
+        # `new_path` is a pattern that is matched against the path from the
+        # root to the node that is being considered.  `node_path` elements are
+        # tuples `(node_check, index_check)`.  `node_check` is a node class:
+        # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`.  `None`
+        # matches any kind of a node.  `index_check` could be `None`, a boolean
+        # value, a string value, or a number.  `None` and `False` match against
+        # any _value_ of sequence and mapping nodes.  `True` matches against
+        # any _key_ of a mapping node.  A string `index_check` matches against
+        # a mapping value that corresponds to a scalar key which content is
+        # equal to the `index_check` value.  An integer `index_check` matches
+        # against a sequence value with the index equal to `index_check`.
+        if 'yaml_path_resolvers' not in cls.__dict__:
+            cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy()
+        new_path: List[Any] = []
+        for element in path:
+            if isinstance(element, (list, tuple)):
+                if len(element) == 2:
+                    node_check, index_check = element
+                elif len(element) == 1:
+                    node_check = element[0]
+                    index_check = True
+                else:
+                    raise ResolverError(f'Invalid path element: {element!s}')
+            else:
+                node_check = None
+                index_check = element
+            if node_check is str:
+                node_check = ScalarNode
+            elif node_check is list:
+                node_check = SequenceNode
+            elif node_check is dict:
+                node_check = MappingNode
+            elif (
+                node_check not in [ScalarNode, SequenceNode, MappingNode]
+                and not isinstance(node_check, str)
+                and node_check is not None
+            ):
+                raise ResolverError(f'Invalid node checker: {node_check!s}')
+            if not isinstance(index_check, (str, int)) and index_check is not None:
+                raise ResolverError(f'Invalid index checker: {index_check!s}')
+            new_path.append((node_check, index_check))
+        if kind is str:
+            kind = ScalarNode
+        elif kind is list:
+            kind = SequenceNode
+        elif kind is dict:
+            kind = MappingNode
+        elif kind not in [ScalarNode, SequenceNode, MappingNode] and kind is not None:
+            raise ResolverError(f'Invalid node kind: {kind!s}')
+        cls.yaml_path_resolvers[tuple(new_path), kind] = tag
+
+    def descend_resolver(self, current_node: Any, current_index: Any) -> None:
+        if not self.yaml_path_resolvers:
+            return
+        exact_paths = {}
+        prefix_paths = []
+        if current_node:
+            depth = len(self.resolver_prefix_paths)
+            for path, kind in self.resolver_prefix_paths[-1]:
+                if self.check_resolver_prefix(depth, path, kind, current_node, current_index):
+                    if len(path) > depth:
+                        prefix_paths.append((path, kind))
+                    else:
+                        exact_paths[kind] = self.yaml_path_resolvers[path, kind]
+        else:
+            for path, kind in self.yaml_path_resolvers:
+                if not path:
+                    exact_paths[kind] = self.yaml_path_resolvers[path, kind]
+                else:
+                    prefix_paths.append((path, kind))
+        self.resolver_exact_paths.append(exact_paths)
+        self.resolver_prefix_paths.append(prefix_paths)
+
+    def ascend_resolver(self) -> None:
+        if not self.yaml_path_resolvers:
+            return
+        self.resolver_exact_paths.pop()
+        self.resolver_prefix_paths.pop()
+
+    def check_resolver_prefix(
+        self, depth: int, path: Any, kind: Any, current_node: Any, current_index: Any,
+    ) -> bool:
+        node_check, index_check = path[depth - 1]
+        if isinstance(node_check, str):
+            if current_node.tag != node_check:
+                return False
+        elif node_check is not None:
+            if not isinstance(current_node, node_check):
+                return False
+        if index_check is True and current_index is not None:
+            return False
+        if (index_check is False or index_check is None) and current_index is None:
+            return False
+        if isinstance(index_check, str):
+            if not (
+                isinstance(current_index, ScalarNode) and index_check == current_index.value
+            ):
+                return False
+        elif isinstance(index_check, int) and not isinstance(index_check, bool):
+            if index_check != current_index:
+                return False
+        return True
+
+    def resolve(self, kind: Any, value: Any, implicit: Any) -> Any:
+        if kind is ScalarNode and implicit[0]:
+            if value == "":
+                resolvers = self.yaml_implicit_resolvers.get("", [])
+            else:
+                resolvers = self.yaml_implicit_resolvers.get(value[0], [])
+            resolvers += self.yaml_implicit_resolvers.get(None, [])
+            for tag, regexp in resolvers:
+                if regexp.match(value):
+                    return Tag(suffix=tag)
+            implicit = implicit[1]
+        if bool(self.yaml_path_resolvers):
+            exact_paths = self.resolver_exact_paths[-1]
+            if kind in exact_paths:
+                return Tag(suffix=exact_paths[kind])
+            if None in exact_paths:
+                return Tag(suffix=exact_paths[None])
+        if kind is ScalarNode:
+            return self.DEFAULT_SCALAR_TAG
+        elif kind is SequenceNode:
+            return self.DEFAULT_SEQUENCE_TAG
+        elif kind is MappingNode:
+            return self.DEFAULT_MAPPING_TAG
+
+    @property
+    def processing_version(self) -> Any:
+        return None
+
+
+class Resolver(BaseResolver):
+    pass
+
+
+for ir in implicit_resolvers:
+    if (1, 2) in ir[0]:
+        Resolver.add_implicit_resolver_base(*ir[1:])
+
+
+class VersionedResolver(BaseResolver):
+    """
+    contrary to the "normal" resolver, the smart resolver delays loading
+    the pattern matching rules. That way it can decide to load 1.1 rules
+    or the (default) 1.2 rules, that no longer support octal without 0o, sexagesimals
+    and Yes/No/On/Off booleans.
+    """
+
+    def __init__(
+        self, version: Optional[VersionType] = None, loader: Any = None, loadumper: Any = None,
+    ) -> None:
+        if loader is None and loadumper is not None:
+            loader = loadumper
+        BaseResolver.__init__(self, loader)
+        self._loader_version = self.get_loader_version(version)
+        self._version_implicit_resolver: Dict[Any, Any] = {}
+
+    def add_version_implicit_resolver(
+        self, version: VersionType, tag: Any, regexp: Any, first: Any,
+    ) -> None:
+        if first is None:
+            first = [None]
+        impl_resolver = self._version_implicit_resolver.setdefault(version, {})
+        for ch in first:
+            impl_resolver.setdefault(ch, []).append((tag, regexp))
+
+    def get_loader_version(self, version: Optional[VersionType]) -> Any:
+        if version is None or isinstance(version, tuple):
+            return version
+        if isinstance(version, list):
+            return tuple(version)
+        # assume string
+        assert isinstance(version, str)
+        return tuple(map(int, version.split('.')))
+
+    @property
+    def versioned_resolver(self) -> Any:
+        """
+        select the resolver based on the version we are parsing
+        """
+        version = self.processing_version
+        if isinstance(version, str):
+            version = tuple(map(int, version.split('.')))
+        if version not in self._version_implicit_resolver:
+            for x in implicit_resolvers:
+                if version in x[0]:
+                    self.add_version_implicit_resolver(version, x[1], x[2], x[3])
+        return self._version_implicit_resolver[version]
+
+    def resolve(self, kind: Any, value: Any, implicit: Any) -> Any:
+        if kind is ScalarNode and implicit[0]:
+            if value == "":
+                resolvers = self.versioned_resolver.get("", [])
+            else:
+                resolvers = self.versioned_resolver.get(value[0], [])
+            resolvers += self.versioned_resolver.get(None, [])
+            for tag, regexp in resolvers:
+                if regexp.match(value):
+                    return Tag(suffix=tag)
+            implicit = implicit[1]
+        if bool(self.yaml_path_resolvers):
+            exact_paths = self.resolver_exact_paths[-1]
+            if kind in exact_paths:
+                return Tag(suffix=exact_paths[kind])
+            if None in exact_paths:
+                return Tag(suffix=exact_paths[None])
+        if kind is ScalarNode:
+            return self.DEFAULT_SCALAR_TAG
+        elif kind is SequenceNode:
+            return self.DEFAULT_SEQUENCE_TAG
+        elif kind is MappingNode:
+            return self.DEFAULT_MAPPING_TAG
+
+    @property
+    def processing_version(self) -> Any:
+        try:
+            version = self.loadumper._scanner.yaml_version
+        except AttributeError:
+            try:
+                if hasattr(self.loadumper, 'typ'):
+                    version = self.loadumper.version
+                else:
+                    version = self.loadumper._serializer.use_version  # dumping
+            except AttributeError:
+                version = None
+        if version is None:
+            version = self._loader_version
+            if version is None:
+                version = _DEFAULT_YAML_VERSION
+        return version
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py
new file mode 100644
index 00000000000..e834f89ca8f
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py
@@ -0,0 +1,43 @@
+"""
+You cannot subclass bool, and this is necessary for round-tripping anchored
+bool values (and also if you want to preserve the original way of writing)
+
+bool.__bases__ is type 'int', so that is what is used as the basis for ScalarBoolean as well.
+
+You can use these in an if statement, but not when testing equivalence
+"""
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
+
+if False:  # MYPY
+    from typing import Text, Any, Dict, List  # NOQA
+
+__all__ = ['ScalarBoolean']
+
+
+class ScalarBoolean(int):
+    def __new__(cls: Any, *args: Any, **kw: Any) -> Any:
+        anchor = kw.pop('anchor', None)
+        b = int.__new__(cls, *args, **kw)
+        if anchor is not None:
+            b.yaml_set_anchor(anchor, always_dump=True)
+        return b
+
+    @property
+    def anchor(self) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            setattr(self, Anchor.attrib, Anchor())
+        return getattr(self, Anchor.attrib)
+
+    def yaml_anchor(self, any: bool = False) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            return None
+        if any or self.anchor.always_dump:
+            return self.anchor
+        return None
+
+    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
+        self.anchor.value = value
+        self.anchor.always_dump = always_dump
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py
new file mode 100644
index 00000000000..aaad4627d7f
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py
@@ -0,0 +1,105 @@
+
+from __future__ import annotations
+
+import sys
+from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
+
+if False:  # MYPY
+    from typing import Text, Any, Dict, List  # NOQA
+
+__all__ = ['ScalarFloat', 'ExponentialFloat', 'ExponentialCapsFloat']
+
+
+class ScalarFloat(float):
+    def __new__(cls: Any, *args: Any, **kw: Any) -> Any:
+        width = kw.pop('width', None)
+        prec = kw.pop('prec', None)
+        m_sign = kw.pop('m_sign', None)
+        m_lead0 = kw.pop('m_lead0', 0)
+        exp = kw.pop('exp', None)
+        e_width = kw.pop('e_width', None)
+        e_sign = kw.pop('e_sign', None)
+        underscore = kw.pop('underscore', None)
+        anchor = kw.pop('anchor', None)
+        v = float.__new__(cls, *args, **kw)
+        v._width = width
+        v._prec = prec
+        v._m_sign = m_sign
+        v._m_lead0 = m_lead0
+        v._exp = exp
+        v._e_width = e_width
+        v._e_sign = e_sign
+        v._underscore = underscore
+        if anchor is not None:
+            v.yaml_set_anchor(anchor, always_dump=True)
+        return v
+
+    def __iadd__(self, a: Any) -> Any:  # type: ignore
+        return float(self) + a
+        x = type(self)(self + a)
+        x._width = self._width
+        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
+        return x
+
+    def __ifloordiv__(self, a: Any) -> Any:  # type: ignore
+        return float(self) // a
+        x = type(self)(self // a)
+        x._width = self._width
+        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
+        return x
+
+    def __imul__(self, a: Any) -> Any:  # type: ignore
+        return float(self) * a
+        x = type(self)(self * a)
+        x._width = self._width
+        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
+        x._prec = self._prec  # check for others
+        return x
+
+    def __ipow__(self, a: Any) -> Any:  # type: ignore
+        return float(self) ** a
+        x = type(self)(self ** a)
+        x._width = self._width
+        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
+        return x
+
+    def __isub__(self, a: Any) -> Any:  # type: ignore
+        return float(self) - a
+        x = type(self)(self - a)
+        x._width = self._width
+        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
+        return x
+
+    @property
+    def anchor(self) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            setattr(self, Anchor.attrib, Anchor())
+        return getattr(self, Anchor.attrib)
+
+    def yaml_anchor(self, any: bool = False) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            return None
+        if any or self.anchor.always_dump:
+            return self.anchor
+        return None
+
+    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
+        self.anchor.value = value
+        self.anchor.always_dump = always_dump
+
+    def dump(self, out: Any = sys.stdout) -> None:
+        out.write(
+            f'ScalarFloat({self}| w:{self._width}, p:{self._prec}, '  # type: ignore
+            f's:{self._m_sign}, lz:{self._m_lead0}, _:{self._underscore}|{self._exp}'
+            f', w:{self._e_width}, s:{self._e_sign})\n',
+        )
+
+
+class ExponentialFloat(ScalarFloat):
+    def __new__(cls, value: Any, width: Any = None, underscore: Any = None) -> Any:
+        return ScalarFloat.__new__(cls, value, width=width, underscore=underscore)
+
+
+class ExponentialCapsFloat(ScalarFloat):
+    def __new__(cls, value: Any, width: Any = None, underscore: Any = None) -> Any:
+        return ScalarFloat.__new__(cls, value, width=width, underscore=underscore)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py
new file mode 100644
index 00000000000..bb0d1681d66
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py
@@ -0,0 +1,124 @@
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
+
+if False:  # MYPY
+    from typing import Text, Any, Dict, List  # NOQA
+
+__all__ = ['ScalarInt', 'BinaryInt', 'OctalInt', 'HexInt', 'HexCapsInt', 'DecimalInt']
+
+
+class ScalarInt(int):
+    def __new__(cls: Any, *args: Any, **kw: Any) -> Any:
+        width = kw.pop('width', None)
+        underscore = kw.pop('underscore', None)
+        anchor = kw.pop('anchor', None)
+        v = int.__new__(cls, *args, **kw)
+        v._width = width
+        v._underscore = underscore
+        if anchor is not None:
+            v.yaml_set_anchor(anchor, always_dump=True)
+        return v
+
+    def __iadd__(self, a: Any) -> Any:  # type: ignore
+        x = type(self)(self + a)
+        x._width = self._width  # type: ignore
+        x._underscore = (  # type: ignore
+            self._underscore[:] if self._underscore is not None else None  # type: ignore
+        )  # NOQA
+        return x
+
+    def __ifloordiv__(self, a: Any) -> Any:  # type: ignore
+        x = type(self)(self // a)
+        x._width = self._width  # type: ignore
+        x._underscore = (  # type: ignore
+            self._underscore[:] if self._underscore is not None else None  # type: ignore
+        )  # NOQA
+        return x
+
+    def __imul__(self, a: Any) -> Any:  # type: ignore
+        x = type(self)(self * a)
+        x._width = self._width  # type: ignore
+        x._underscore = (  # type: ignore
+            self._underscore[:] if self._underscore is not None else None  # type: ignore
+        )  # NOQA
+        return x
+
+    def __ipow__(self, a: Any) -> Any:  # type: ignore
+        x = type(self)(self ** a)
+        x._width = self._width  # type: ignore
+        x._underscore = (  # type: ignore
+            self._underscore[:] if self._underscore is not None else None  # type: ignore
+        )  # NOQA
+        return x
+
+    def __isub__(self, a: Any) -> Any:  # type: ignore
+        x = type(self)(self - a)
+        x._width = self._width  # type: ignore
+        x._underscore = (  # type: ignore
+            self._underscore[:] if self._underscore is not None else None  # type: ignore
+        )  # NOQA
+        return x
+
+    @property
+    def anchor(self) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            setattr(self, Anchor.attrib, Anchor())
+        return getattr(self, Anchor.attrib)
+
+    def yaml_anchor(self, any: bool = False) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            return None
+        if any or self.anchor.always_dump:
+            return self.anchor
+        return None
+
+    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
+        self.anchor.value = value
+        self.anchor.always_dump = always_dump
+
+
+class BinaryInt(ScalarInt):
+    def __new__(
+        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
+    ) -> Any:
+        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
+
+
+class OctalInt(ScalarInt):
+    def __new__(
+        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
+    ) -> Any:
+        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
+
+
+# mixed casing of A-F is not supported, when loading the first non digit
+# determines the case
+
+
+class HexInt(ScalarInt):
+    """uses lower case (a-f)"""
+
+    def __new__(
+        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
+    ) -> Any:
+        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
+
+
+class HexCapsInt(ScalarInt):
+    """uses upper case (A-F)"""
+
+    def __new__(
+        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
+    ) -> Any:
+        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
+
+
+class DecimalInt(ScalarInt):
+    """needed if anchor"""
+
+    def __new__(
+        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
+    ) -> Any:
+        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py
new file mode 100644
index 00000000000..4c7d2248fa7
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py
@@ -0,0 +1,142 @@
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
+
+if False:  # MYPY
+    from typing import Text, Any, Dict, List  # NOQA
+    from opentelemetry.agent._vendor.ruamel.yaml.compat import SupportsIndex
+
+__all__ = [
+    'ScalarString',
+    'LiteralScalarString',
+    'FoldedScalarString',
+    'SingleQuotedScalarString',
+    'DoubleQuotedScalarString',
+    'PlainScalarString',
+    # PreservedScalarString is the old name, as it was the first to be preserved on rt,
+    # use LiteralScalarString instead
+    'PreservedScalarString',
+]
+
+
+class ScalarString(str):
+    __slots__ = Anchor.attrib
+
+    def __new__(cls, *args: Any, **kw: Any) -> Any:
+        anchor = kw.pop('anchor', None)
+        ret_val = str.__new__(cls, *args, **kw)
+        if anchor is not None:
+            ret_val.yaml_set_anchor(anchor, always_dump=True)
+        return ret_val
+
+    def replace(self, old: Any, new: Any, maxreplace: SupportsIndex = -1) -> Any:
+        return type(self)((str.replace(self, old, new, maxreplace)))
+
+    @property
+    def anchor(self) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            setattr(self, Anchor.attrib, Anchor())
+        return getattr(self, Anchor.attrib)
+
+    def yaml_anchor(self, any: bool = False) -> Any:
+        if not hasattr(self, Anchor.attrib):
+            return None
+        if any or self.anchor.always_dump:
+            return self.anchor
+        return None
+
+    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
+        self.anchor.value = value
+        self.anchor.always_dump = always_dump
+
+
+class LiteralScalarString(ScalarString):
+    __slots__ = 'comment'  # the comment after the | on the first line
+
+    style = '|'
+
+    def __new__(cls, value: Text, anchor: Any = None) -> Any:
+        return ScalarString.__new__(cls, value, anchor=anchor)
+
+
+PreservedScalarString = LiteralScalarString
+
+
+class FoldedScalarString(ScalarString):
+    __slots__ = ('fold_pos', 'comment')  # the comment after the > on the first line
+
+    style = '>'
+
+    def __new__(cls, value: Text, anchor: Any = None) -> Any:
+        return ScalarString.__new__(cls, value, anchor=anchor)
+
+
+class SingleQuotedScalarString(ScalarString):
+    __slots__ = ()
+
+    style = "'"
+
+    def __new__(cls, value: Text, anchor: Any = None) -> Any:
+        return ScalarString.__new__(cls, value, anchor=anchor)
+
+
+class DoubleQuotedScalarString(ScalarString):
+    __slots__ = ()
+
+    style = '"'
+
+    def __new__(cls, value: Text, anchor: Any = None) -> Any:
+        return ScalarString.__new__(cls, value, anchor=anchor)
+
+
+class PlainScalarString(ScalarString):
+    __slots__ = ()
+
+    style = ''
+
+    def __new__(cls, value: Text, anchor: Any = None) -> Any:
+        return ScalarString.__new__(cls, value, anchor=anchor)
+
+
+def preserve_literal(s: Text) -> Text:
+    return LiteralScalarString(s.replace('\r\n', '\n').replace('\r', '\n'))
+
+
+def walk_tree(base: Any, map: Any = None) -> None:
+    """
+    the routine here walks over a simple yaml tree (recursing in
+    dict values and list items) and converts strings that
+    have multiple lines to literal scalars
+
+    You can also provide an explicit (ordered) mapping for multiple transforms
+    (first of which is executed):
+        map = ruamel.yaml.compat.ordereddict
+        map['\n'] = preserve_literal
+        map[':'] = SingleQuotedScalarString
+        walk_tree(data, map=map)
+    """
+    from collections.abc import MutableMapping, MutableSequence
+
+    if map is None:
+        map = {'\n': preserve_literal}
+
+    if isinstance(base, MutableMapping):
+        for k in base:
+            v: Text = base[k]
+            if isinstance(v, str):
+                for ch in map:
+                    if ch in v:
+                        base[k] = map[ch](v)
+                        break
+            else:
+                walk_tree(v, map=map)
+    elif isinstance(base, MutableSequence):
+        for idx, elem in enumerate(base):
+            if isinstance(elem, str):
+                for ch in map:
+                    if ch in elem:
+                        base[idx] = map[ch](elem)
+                        break
+            else:
+                walk_tree(elem, map=map)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py
new file mode 100644
index 00000000000..3a8cfcd3f5e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py
@@ -0,0 +1,2390 @@
+
+from __future__ import annotations
+
+# Scanner produces tokens of the following types:
+# STREAM-START
+# STREAM-END
+# DIRECTIVE(name, value)
+# DOCUMENT-START
+# DOCUMENT-END
+# BLOCK-SEQUENCE-START
+# BLOCK-MAPPING-START
+# BLOCK-END
+# FLOW-SEQUENCE-START
+# FLOW-MAPPING-START
+# FLOW-SEQUENCE-END
+# FLOW-MAPPING-END
+# BLOCK-ENTRY
+# FLOW-ENTRY
+# KEY
+# VALUE
+# ALIAS(value)
+# ANCHOR(value)
+# TAG(value)
+# SCALAR(value, plain, style)
+#
+# RoundTripScanner
+# COMMENT(value)
+#
+# Read comments in the Scanner code for more details.
+#
+
+from opentelemetry.agent._vendor.ruamel.yaml.error import MarkedYAMLError
+from opentelemetry.agent._vendor.ruamel.yaml import tokens as tokens
+from opentelemetry.agent._vendor.ruamel.yaml.docinfo import Version  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.compat import check_anchorname_char, _debug, nprint, nprintf  # NOQA
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Union, Text, Tuple  # NOQA
+
+__all__ = ['Scanner', 'RoundTripScanner', 'ScannerError']
+
+
+_THE_END = '\n\0\r\x85\u2028\u2029'
+_THE_END_SPACE_TAB = ' \n\0\t\r\x85\u2028\u2029'
+_SPACE_TAB = ' \t'
+
+
+if _debug != 0:
+    def xprintf(*args: Any, **kw: Any) -> Any:
+        return nprintf(*args, **kw)
+
+
+class ScannerError(MarkedYAMLError):
+    pass
+
+
+class SimpleKey:
+    # See below simple keys treatment.
+
+    def __init__(
+        self, token_number: Any, required: Any, index: int, line: int, column: int, mark: Any,
+    ) -> None:
+        self.token_number = token_number
+        self.required = required
+        self.index = index
+        self.line = line
+        self.column = column
+        self.mark = mark
+
+
+class Scanner:
+    def __init__(self, loader: Any = None) -> None:
+        """Initialize the scanner."""
+        # It is assumed that Scanner and Reader will have a common descendant.
+        # Reader do the dirty work of checking for BOM and converting the
+        # input data to Unicode. It also adds NUL to the end.
+        #
+        # Reader supports the following methods
+        #   self.peek(i=0)    # peek the next i-th character
+        #   self.prefix(l=1)  # peek the next l characters
+        #   self.forward(l=1) # read the next l characters and move the pointer
+
+        self.loader = loader
+        if self.loader is not None and getattr(self.loader, '_scanner', None) is None:
+            self.loader._scanner = self
+        self.reset_scanner()
+        self.first_time = False
+
+    @property
+    def flow_level(self) -> int:
+        return len(self.flow_context)
+
+    def reset_scanner(self) -> None:
+        # Had we reached the end of the stream?
+        self.done = False
+
+        # flow_context is an expanding/shrinking list consisting of '{' and '['
+        # for each unclosed flow context. If empty list that means block context
+        self.flow_context: List[Text] = []
+
+        # List of processed tokens that are not yet emitted.
+        self.tokens: List[Any] = []
+
+        # Add the STREAM-START token.
+        self.fetch_stream_start()
+
+        # Number of tokens that were emitted through the `get_token` method.
+        self.tokens_taken = 0
+
+        # The current indentation level.
+        self.indent = -1
+
+        # Past indentation levels.
+        self.indents: List[int] = []
+
+        # Variables related to simple keys treatment.
+
+        # A simple key is a key that is not denoted by the '?' indicator.
+        # Example of simple keys:
+        #   ---
+        #   block simple key: value
+        #   ? not a simple key:
+        #   : { flow simple key: value }
+        # We emit the KEY token before all keys, so when we find a potential
+        # simple key, we try to locate the corresponding ':' indicator.
+        # Simple keys should be limited to a single line and 1024 characters.
+
+        # Can a simple key start at the current position? A simple key may
+        # start:
+        # - at the beginning of the line, not counting indentation spaces
+        #       (in block context),
+        # - after '{', '[', ',' (in the flow context),
+        # - after '?', ':', '-' (in the block context).
+        # In the block context, this flag also signifies if a block collection
+        # may start at the current position.
+        self.allow_simple_key = True
+
+        # Keep track of possible simple keys. This is a dictionary. The key
+        # is `flow_level`; there can be no more that one possible simple key
+        # for each level. The value is a SimpleKey record:
+        #   (token_number, required, index, line, column, mark)
+        # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow),
+        # '[', or '{' tokens.
+        self.possible_simple_keys: Dict[Any, Any] = {}
+        self.yaml_version: Any = None
+        self.tag_directives: List[Tuple[Any, Any]] = []
+
+    @property
+    def reader(self) -> Any:
+        try:
+            return self._scanner_reader  # type: ignore
+        except AttributeError:
+            if hasattr(self.loader, 'typ'):
+                self._scanner_reader = self.loader.reader
+            else:
+                self._scanner_reader = self.loader._reader
+            return self._scanner_reader
+
+    @property
+    def scanner_processing_version(self) -> Any:  # prefix until un-composited
+        if hasattr(self.loader, 'typ'):
+            return self.loader.resolver.processing_version
+        return self.loader.processing_version
+
+    # Public methods.
+
+    def check_token(self, *choices: Any) -> bool:
+        # Check if the next token is one of the given types.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        if len(self.tokens) > 0:
+            if not choices:
+                return True
+            for choice in choices:
+                if isinstance(self.tokens[0], choice):
+                    return True
+        return False
+
+    def peek_token(self) -> Any:
+        # Return the next token, but do not delete if from the queue.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        if len(self.tokens) > 0:
+            return self.tokens[0]
+
+    def get_token(self) -> Any:
+        # Return the next token.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        if len(self.tokens) > 0:
+            self.tokens_taken += 1
+            return self.tokens.pop(0)
+
+    # Private methods.
+
+    def need_more_tokens(self) -> bool:
+        if self.done:
+            return False
+        if len(self.tokens) == 0:
+            return True
+        # The current token may be a potential simple key, so we
+        # need to look further.
+        self.stale_possible_simple_keys()
+        if self.next_possible_simple_key() == self.tokens_taken:
+            return True
+        return False
+
+    def fetch_comment(self, comment: Any) -> None:
+        raise NotImplementedError
+
+    def fetch_more_tokens(self) -> Any:
+        # Eat whitespaces and comments until we reach the next token.
+        comment = self.scan_to_next_token()
+        if comment is not None:  # never happens for base scanner
+            return self.fetch_comment(comment)
+        # Remove obsolete possible simple keys.
+        self.stale_possible_simple_keys()
+
+        # Compare the current indentation and column. It may add some tokens
+        # and decrease the current indentation level.
+        self.unwind_indent(self.reader.column)
+
+        # Peek the next character.
+        ch = self.reader.peek()
+
+        # Is it the end of stream?
+        if ch == '\0':
+            return self.fetch_stream_end()
+
+        # Is it a directive?
+        if ch == '%' and self.check_directive():
+            return self.fetch_directive()
+
+        # Is it the document start?
+        if ch == '-' and self.check_document_start():
+            return self.fetch_document_start()
+
+        # Is it the document end?
+        if ch == '.' and self.check_document_end():
+            return self.fetch_document_end()
+
+        # TODO: support for BOM within a stream.
+        # if ch == '\uFEFF':
+        #     return self.fetch_bom()    <-- issue BOMToken
+
+        # Note: the order of the following checks is NOT significant.
+
+        # Is it the flow sequence start indicator?
+        if ch == '[':
+            return self.fetch_flow_sequence_start()
+
+        # Is it the flow mapping start indicator?
+        if ch == '{':
+            return self.fetch_flow_mapping_start()
+
+        # Is it the flow sequence end indicator?
+        if ch == ']':
+            return self.fetch_flow_sequence_end()
+
+        # Is it the flow mapping end indicator?
+        if ch == '}':
+            return self.fetch_flow_mapping_end()
+
+        # Is it the flow entry indicator?
+        if ch == ',':
+            return self.fetch_flow_entry()
+
+        # Is it the block entry indicator?
+        if ch == '-' and self.check_block_entry():
+            return self.fetch_block_entry()
+
+        # Is it the key indicator?
+        if ch == '?' and self.check_key():
+            return self.fetch_key()
+
+        # Is it the value indicator?
+        if ch == ':' and self.check_value():
+            return self.fetch_value()
+
+        # Is it an alias?
+        if ch == '*':
+            return self.fetch_alias()
+
+        # Is it an anchor?
+        if ch == '&':
+            return self.fetch_anchor()
+
+        # Is it a tag?
+        if ch == '!':
+            return self.fetch_tag()
+
+        # Is it a literal scalar?
+        if ch == '|' and not self.flow_level:
+            return self.fetch_literal()
+
+        # Is it a folded scalar?
+        if ch == '>' and not self.flow_level:
+            return self.fetch_folded()
+
+        # Is it a single quoted scalar?
+        if ch == "'":
+            return self.fetch_single()
+
+        # Is it a double quoted scalar?
+        if ch == '"':
+            return self.fetch_double()
+
+        # It must be a plain scalar then.
+        if self.check_plain():
+            return self.fetch_plain()
+
+        # No? It's an error. Let's produce a nice error message.
+        raise ScannerError(
+            'while scanning for the next token',
+            None,
+            f'found character {ch!r} that cannot start any token',
+            self.reader.get_mark(),
+        )
+
+    # Simple keys treatment.
+
+    def next_possible_simple_key(self) -> Any:
+        # Return the number of the nearest possible simple key. Actually we
+        # don't need to loop through the whole dictionary. We may replace it
+        # with the following code:
+        #   if not self.possible_simple_keys:
+        #       return None
+        #   return self.possible_simple_keys[
+        #           min(self.possible_simple_keys.keys())].token_number
+        min_token_number = None
+        for level in self.possible_simple_keys:
+            key = self.possible_simple_keys[level]
+            if min_token_number is None or key.token_number < min_token_number:
+                min_token_number = key.token_number
+        return min_token_number
+
+    def stale_possible_simple_keys(self) -> None:
+        # Remove entries that are no longer possible simple keys. According to
+        # the YAML specification, simple keys
+        # - should be limited to a single line,
+        # - should be no longer than 1024 characters.
+        # Disabling this procedure will allow simple keys of any length and
+        # height (may cause problems if indentation is broken though).
+        for level in list(self.possible_simple_keys):
+            key = self.possible_simple_keys[level]
+            if key.line != self.reader.line or self.reader.index - key.index > 1024:
+                if key.required:
+                    raise ScannerError(
+                        'while scanning a simple key',
+                        key.mark,
+                        "could not find expected ':'",
+                        self.reader.get_mark(),
+                    )
+                del self.possible_simple_keys[level]
+
+    def save_possible_simple_key(self) -> None:
+        # The next token may start a simple key. We check if it's possible
+        # and save its position. This function is called for
+        #   ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'.
+
+        # Check if a simple key is required at the current position.
+        required = not self.flow_level and self.indent == self.reader.column
+
+        # The next token might be a simple key. Let's save it's number and
+        # position.
+        if self.allow_simple_key:
+            self.remove_possible_simple_key()
+            token_number = self.tokens_taken + len(self.tokens)
+            key = SimpleKey(
+                token_number,
+                required,
+                self.reader.index,
+                self.reader.line,
+                self.reader.column,
+                self.reader.get_mark(),
+            )
+            self.possible_simple_keys[self.flow_level] = key
+
+    def remove_possible_simple_key(self) -> None:
+        # Remove the saved possible key position at the current flow level.
+        if self.flow_level in self.possible_simple_keys:
+            key = self.possible_simple_keys[self.flow_level]
+
+            if key.required:
+                raise ScannerError(
+                    'while scanning a simple key',
+                    key.mark,
+                    "could not find expected ':'",
+                    self.reader.get_mark(),
+                )
+
+            del self.possible_simple_keys[self.flow_level]
+
+    # Indentation functions.
+
+    def unwind_indent(self, column: Any) -> None:
+        # In flow context, tokens should respect indentation.
+        # Actually the condition should be `self.indent >= column` according to
+        # the spec. But this condition will prohibit intuitively correct
+        # constructions such as
+        # key : {
+        # }
+        # ####
+        # if self.flow_level and self.indent > column:
+        #     raise ScannerError(None, None,
+        #             "invalid intendation or unclosed '[' or '{'",
+        #             self.reader.get_mark())
+
+        # In the flow context, indentation is ignored. We make the scanner less
+        # restrictive then specification requires.
+        if bool(self.flow_level):
+            return
+
+        # In block context, we may need to issue the BLOCK-END tokens.
+        while self.indent > column:
+            mark = self.reader.get_mark()
+            self.indent = self.indents.pop()
+            self.tokens.append(tokens.BlockEndToken(mark, mark))
+
+    def add_indent(self, column: int) -> bool:
+        # Check if we need to increase indentation.
+        if self.indent < column:
+            self.indents.append(self.indent)
+            self.indent = column
+            return True
+        return False
+
+    # Fetchers.
+
+    def fetch_stream_start(self) -> None:
+        # We always add STREAM-START as the first token and STREAM-END as the
+        # last token.
+        # Read the token.
+        mark = self.reader.get_mark()
+        # Add STREAM-START.
+        self.tokens.append(tokens.StreamStartToken(mark, mark, encoding=self.reader.encoding))
+
+    def fetch_stream_end(self) -> None:
+        # Set the current intendation to -1.
+        self.unwind_indent(-1)
+        # Reset simple keys.
+        self.remove_possible_simple_key()
+        self.allow_simple_key = False
+        self.possible_simple_keys = {}
+        # Read the token.
+        mark = self.reader.get_mark()
+        # Add STREAM-END.
+        self.tokens.append(tokens.StreamEndToken(mark, mark))
+        # The steam is finished.
+        self.done = True
+
+    def fetch_directive(self) -> None:
+        # Set the current intendation to -1.
+        self.unwind_indent(-1)
+
+        # Reset simple keys.
+        self.remove_possible_simple_key()
+        self.allow_simple_key = False
+
+        # Scan and add DIRECTIVE.
+        self.tokens.append(self.scan_directive())
+
+    def fetch_document_start(self) -> None:
+        self.fetch_document_indicator(tokens.DocumentStartToken)
+
+    def fetch_document_end(self) -> None:
+        self.fetch_document_indicator(tokens.DocumentEndToken)
+
+    def fetch_document_indicator(self, TokenClass: Any) -> None:
+        # Set the current intendation to -1.
+        self.unwind_indent(-1)
+
+        # Reset simple keys. Note that there could not be a block collection
+        # after '---'.
+        self.remove_possible_simple_key()
+        self.allow_simple_key = False
+
+        # Add DOCUMENT-START or DOCUMENT-END.
+        start_mark = self.reader.get_mark()
+        self.reader.forward(3)
+        end_mark = self.reader.get_mark()
+        self.tokens.append(TokenClass(start_mark, end_mark))
+
+    def fetch_flow_sequence_start(self) -> None:
+        self.fetch_flow_collection_start(tokens.FlowSequenceStartToken, to_push='[')
+
+    def fetch_flow_mapping_start(self) -> None:
+        self.fetch_flow_collection_start(tokens.FlowMappingStartToken, to_push='{')
+
+    def fetch_flow_collection_start(self, TokenClass: Any, to_push: Text) -> None:
+        # '[' and '{' may start a simple key.
+        self.save_possible_simple_key()
+        # Increase the flow level.
+        self.flow_context.append(to_push)
+        # Simple keys are allowed after '[' and '{'.
+        self.allow_simple_key = True
+        # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START.
+        start_mark = self.reader.get_mark()
+        self.reader.forward()
+        end_mark = self.reader.get_mark()
+        self.tokens.append(TokenClass(start_mark, end_mark))
+
+    def fetch_flow_sequence_end(self) -> None:
+        self.fetch_flow_collection_end(tokens.FlowSequenceEndToken)
+
+    def fetch_flow_mapping_end(self) -> None:
+        self.fetch_flow_collection_end(tokens.FlowMappingEndToken)
+
+    def fetch_flow_collection_end(self, TokenClass: Any) -> None:
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+        # Decrease the flow level.
+        try:
+            popped = self.flow_context.pop()  # NOQA
+        except IndexError:
+            # We must not be in a list or object.
+            # Defer error handling to the parser.
+            pass
+        # No simple keys after ']' or '}'.
+        self.allow_simple_key = False
+        # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END.
+        start_mark = self.reader.get_mark()
+        self.reader.forward()
+        end_mark = self.reader.get_mark()
+        self.tokens.append(TokenClass(start_mark, end_mark))
+
+    def fetch_flow_entry(self) -> None:
+        # Simple keys are allowed after ','.
+        self.allow_simple_key = True
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+        # Add FLOW-ENTRY.
+        start_mark = self.reader.get_mark()
+        self.reader.forward()
+        end_mark = self.reader.get_mark()
+        self.tokens.append(tokens.FlowEntryToken(start_mark, end_mark))
+
+    def fetch_block_entry(self) -> None:
+        # Block context needs additional checks.
+        if not self.flow_level:
+            # Are we allowed to start a new entry?
+            if not self.allow_simple_key:
+                raise ScannerError(
+                    None,
+                    None,
+                    'sequence entries are not allowed here',
+                    self.reader.get_mark(),
+                )
+            # We may need to add BLOCK-SEQUENCE-START.
+            if self.add_indent(self.reader.column):
+                mark = self.reader.get_mark()
+                self.tokens.append(tokens.BlockSequenceStartToken(mark, mark))
+        # It's an error for the block entry to occur in the flow context,
+        # but we let the parser detect this.
+        else:
+            pass
+        # Simple keys are allowed after '-'.
+        self.allow_simple_key = True
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+
+        # Add BLOCK-ENTRY.
+        start_mark = self.reader.get_mark()
+        self.reader.forward()
+        end_mark = self.reader.get_mark()
+        self.tokens.append(tokens.BlockEntryToken(start_mark, end_mark))
+
+    def fetch_key(self) -> None:
+        # Block context needs additional checks.
+        if not self.flow_level:
+
+            # Are we allowed to start a key (not nessesary a simple)?
+            if not self.allow_simple_key:
+                raise ScannerError(
+                    None, None, 'mapping keys are not allowed here', self.reader.get_mark(),
+                )
+
+            # We may need to add BLOCK-MAPPING-START.
+            if self.add_indent(self.reader.column):
+                mark = self.reader.get_mark()
+                self.tokens.append(tokens.BlockMappingStartToken(mark, mark))
+
+        # Simple keys are allowed after '?' in the block context.
+        self.allow_simple_key = not self.flow_level
+
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+
+        # Add KEY.
+        start_mark = self.reader.get_mark()
+        self.reader.forward()
+        end_mark = self.reader.get_mark()
+        self.tokens.append(tokens.KeyToken(start_mark, end_mark))
+
+    def fetch_value(self) -> None:
+        # Do we determine a simple key?
+        if self.flow_level in self.possible_simple_keys:
+            # Add KEY.
+            key = self.possible_simple_keys[self.flow_level]
+            del self.possible_simple_keys[self.flow_level]
+            self.tokens.insert(
+                key.token_number - self.tokens_taken, tokens.KeyToken(key.mark, key.mark),
+            )
+
+            # If this key starts a new block mapping, we need to add
+            # BLOCK-MAPPING-START.
+            if not self.flow_level:
+                if self.add_indent(key.column):
+                    self.tokens.insert(
+                        key.token_number - self.tokens_taken,
+                        tokens.BlockMappingStartToken(key.mark, key.mark),
+                    )
+
+            # There cannot be two simple keys one after another.
+            self.allow_simple_key = False
+
+        # It must be a part of a complex key.
+        else:
+
+            # Block context needs additional checks.
+            # (Do we really need them? They will be caught by the parser
+            # anyway.)
+            if not self.flow_level:
+
+                # We are allowed to start a complex value if and only if
+                # we can start a simple key.
+                if not self.allow_simple_key:
+                    raise ScannerError(
+                        None,
+                        None,
+                        'mapping values are not allowed here',
+                        self.reader.get_mark(),
+                    )
+
+            # If this value starts a new block mapping, we need to add
+            # BLOCK-MAPPING-START.  It will be detected as an error later by
+            # the parser.
+            if not self.flow_level:
+                if self.add_indent(self.reader.column):
+                    mark = self.reader.get_mark()
+                    self.tokens.append(tokens.BlockMappingStartToken(mark, mark))
+
+            # Simple keys are allowed after ':' in the block context.
+            self.allow_simple_key = not self.flow_level
+
+            # Reset possible simple key on the current level.
+            self.remove_possible_simple_key()
+
+        # Add VALUE.
+        start_mark = self.reader.get_mark()
+        self.reader.forward()
+        end_mark = self.reader.get_mark()
+        self.tokens.append(tokens.ValueToken(start_mark, end_mark))
+
+    def fetch_alias(self) -> None:
+        # ALIAS could be a simple key.
+        self.save_possible_simple_key()
+        # No simple keys after ALIAS.
+        self.allow_simple_key = False
+        # Scan and add ALIAS.
+        self.tokens.append(self.scan_anchor(tokens.AliasToken))
+
+    def fetch_anchor(self) -> None:
+        # ANCHOR could start a simple key.
+        self.save_possible_simple_key()
+        # No simple keys after ANCHOR.
+        self.allow_simple_key = False
+        # Scan and add ANCHOR.
+        self.tokens.append(self.scan_anchor(tokens.AnchorToken))
+
+    def fetch_tag(self) -> None:
+        # TAG could start a simple key.
+        self.save_possible_simple_key()
+        # No simple keys after TAG.
+        self.allow_simple_key = False
+        # Scan and add TAG.
+        self.tokens.append(self.scan_tag())
+
+    def fetch_literal(self) -> None:
+        self.fetch_block_scalar(style='|')
+
+    def fetch_folded(self) -> None:
+        self.fetch_block_scalar(style='>')
+
+    def fetch_block_scalar(self, style: Any) -> None:
+        # A simple key may follow a block scalar.
+        self.allow_simple_key = True
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+        # Scan and add SCALAR.
+        self.tokens.append(self.scan_block_scalar(style))
+
+    def fetch_single(self) -> None:
+        self.fetch_flow_scalar(style="'")
+
+    def fetch_double(self) -> None:
+        self.fetch_flow_scalar(style='"')
+
+    def fetch_flow_scalar(self, style: Any) -> None:
+        # A flow scalar could be a simple key.
+        self.save_possible_simple_key()
+        # No simple keys after flow scalars.
+        self.allow_simple_key = False
+        # Scan and add SCALAR.
+        self.tokens.append(self.scan_flow_scalar(style))
+
+    def fetch_plain(self) -> None:
+        # A plain scalar could be a simple key.
+        self.save_possible_simple_key()
+        # No simple keys after plain scalars. But note that `scan_plain` will
+        # change this flag if the scan is finished at the beginning of the
+        # line.
+        self.allow_simple_key = False
+        # Scan and add SCALAR. May change `allow_simple_key`.
+        self.tokens.append(self.scan_plain())
+
+    # Checkers.
+
+    def check_directive(self) -> Any:
+        # DIRECTIVE:        ^ '%' ...
+        # The '%' indicator is already checked.
+        if self.reader.column == 0:
+            return True
+        return None
+
+    def check_document_start(self) -> Any:
+        # DOCUMENT-START:   ^ '---' (' '|'\n')
+        if self.reader.column == 0:
+            if self.reader.prefix(3) == '---' and self.reader.peek(3) in _THE_END_SPACE_TAB:
+                return True
+        return None
+
+    def check_document_end(self) -> Any:
+        # DOCUMENT-END:     ^ '...' (' '|'\n')
+        if self.reader.column == 0:
+            if self.reader.prefix(3) == '...' and self.reader.peek(3) in _THE_END_SPACE_TAB:
+                return True
+        return None
+
+    def check_block_entry(self) -> Any:
+        # BLOCK-ENTRY:      '-' (' '|'\n')
+        return self.reader.peek(1) in _THE_END_SPACE_TAB
+
+    def check_key(self) -> Any:
+        # KEY(flow context):    '?'
+        if bool(self.flow_level):
+            return True
+        # KEY(block context):   '?' (' '|'\n')
+        return self.reader.peek(1) in _THE_END_SPACE_TAB
+
+    def check_value(self) -> Any:
+        # VALUE(flow context):  ':'
+        if self.scanner_processing_version == (1, 1):
+            if bool(self.flow_level):
+                return True
+        else:
+            if bool(self.flow_level):
+                if self.flow_context[-1] == '[':
+                    if self.reader.peek(1) not in _THE_END_SPACE_TAB:
+                        return False
+                elif self.tokens and isinstance(self.tokens[-1], tokens.ValueToken):
+                    # mapping flow context scanning a value token
+                    if self.reader.peek(1) not in _THE_END_SPACE_TAB:
+                        return False
+                return True
+        # VALUE(block context): ':' (' '|'\n')
+        return self.reader.peek(1) in _THE_END_SPACE_TAB
+
+    def check_plain(self) -> Any:
+        # A plain scalar may start with any non-space character except:
+        #   '-', '?', ':', ',', '[', ']', '{', '}',
+        #   '#', '&', '*', '!', '|', '>', '\'', '\"',
+        #   '%', '@', '`'.
+        #
+        # It may also start with
+        #   '-', '?', ':'
+        # if it is followed by a non-space character.
+        #
+        # Note that we limit the last rule to the block context (except the
+        # '-' character) because we want the flow context to be space
+        # independent.
+        srp = self.reader.peek
+        ch = srp()
+        if self.scanner_processing_version == (1, 1):
+            return ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'"%@`' or (
+                srp(1) not in _THE_END_SPACE_TAB
+                and (ch == '-' or (not self.flow_level and ch in '?:'))
+            )
+        # YAML 1.2
+        if ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'"%@`':
+            # ###################                ^ ???
+            return True
+        ch1 = srp(1)
+        if ch == '-' and ch1 not in _THE_END_SPACE_TAB:
+            return True
+        if ch == ':' and bool(self.flow_level) and ch1 not in _SPACE_TAB:
+            return True
+
+        return srp(1) not in _THE_END_SPACE_TAB and (
+            ch == '-' or (not self.flow_level and ch in '?:')
+        )
+
+    # Scanners.
+
+    def scan_to_next_token(self) -> Any:
+        # We ignore spaces, line breaks and comments.
+        # If we find a line break in the block context, we set the flag
+        # `allow_simple_key` on.
+        # The byte order mark is stripped if it's the first character in the
+        # stream. We do not yet support BOM inside the stream as the
+        # specification requires. Any such mark will be considered as a part
+        # of the document.
+        #
+        # TODO: We need to make tab handling rules more sane. A good rule is
+        #   Tabs cannot precede tokens
+        #   BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END,
+        #   KEY(block), VALUE(block), BLOCK-ENTRY
+        # So the checking code is
+        #   if :
+        #       self.allow_simple_keys = False
+        # We also need to add the check for `allow_simple_keys == True` to
+        # `unwind_indent` before issuing BLOCK-END.
+        # Scanners for block, flow, and plain scalars need to be modified.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        if self.reader.index == 0 and srp() == '\uFEFF':
+            srf()
+        found = False
+        _the_end = _THE_END
+        white_space = ' \t' if self.flow_level > 0 else ' '
+        while not found:
+            while srp() in white_space:
+                srf()
+            if srp() == '#':
+                while srp() not in _the_end:
+                    srf()
+            if self.scan_line_break():
+                if not self.flow_level:
+                    self.allow_simple_key = True
+            else:
+                found = True
+        return None
+
+    def scan_directive(self) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        start_mark = self.reader.get_mark()
+        srf()
+        name = self.scan_directive_name(start_mark)
+        value = None
+        if name == 'YAML':
+            value = self.scan_yaml_directive_value(start_mark)
+            end_mark = self.reader.get_mark()
+        elif name == 'TAG':
+            value = self.scan_tag_directive_value(start_mark)
+            end_mark = self.reader.get_mark()
+        else:
+            end_mark = self.reader.get_mark()
+            while srp() not in _THE_END:
+                srf()
+        self.scan_directive_ignored_line(start_mark)
+        return tokens.DirectiveToken(name, value, start_mark, end_mark)
+
+    def scan_directive_name(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        length = 0
+        srp = self.reader.peek
+        ch = srp(length)
+        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in '-_:.':
+            length += 1
+            ch = srp(length)
+        if not length:
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f'expected alphabetic or numeric character, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        value = self.reader.prefix(length)
+        self.reader.forward(length)
+        ch = srp()
+        if ch not in '\0 \r\n\x85\u2028\u2029':
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f'expected alphabetic or numeric character, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        return value
+
+    def scan_yaml_directive_value(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        while srp() == ' ':
+            srf()
+        major = self.scan_yaml_directive_number(start_mark)
+        if srp() != '.':
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f"expected a digit or '.', but found {srp()!r}",
+                self.reader.get_mark(),
+            )
+        srf()
+        minor = self.scan_yaml_directive_number(start_mark)
+        if srp() not in '\0 \r\n\x85\u2028\u2029':
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f"expected a digit or '.', but found {srp()!r}",
+                self.reader.get_mark(),
+            )
+        self.yaml_version = (major, minor)
+        self.loader.doc_infos[-1].doc_version = Version(major, minor)
+        return self.yaml_version
+
+    def scan_yaml_directive_number(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        ch = srp()
+        if not ('0' <= ch <= '9'):
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f'expected a digit, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        length = 0
+        while '0' <= srp(length) <= '9':
+            length += 1
+        value = int(self.reader.prefix(length))
+        srf(length)
+        return value
+
+    def scan_tag_directive_value(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        while srp() == ' ':
+            srf()
+        handle = self.scan_tag_directive_handle(start_mark)
+        while srp() == ' ':
+            srf()
+        prefix = self.scan_tag_directive_prefix(start_mark)
+        ret_val = (handle, prefix)
+        self.tag_directives.append(ret_val)
+        return ret_val
+
+    def scan_tag_directive_handle(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        value = self.scan_tag_handle('directive', start_mark)
+        ch = self.reader.peek()
+        if ch != ' ':
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f"expected ' ', but found {ch!r}",
+                self.reader.get_mark(),
+            )
+        return value
+
+    def scan_tag_directive_prefix(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        value = self.scan_tag_uri('directive', start_mark)
+        ch = self.reader.peek()
+        if ch not in '\0 \r\n\x85\u2028\u2029':
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f"expected ' ', but found {ch!r}",
+                self.reader.get_mark(),
+            )
+        return value
+
+    def scan_directive_ignored_line(self, start_mark: Any) -> None:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        while srp() == ' ':
+            srf()
+        if srp() == '#':
+            while srp() not in _THE_END:
+                srf()
+        ch = srp()
+        if ch not in _THE_END:
+            raise ScannerError(
+                'while scanning a directive',
+                start_mark,
+                f'expected a comment or a line break, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        self.scan_line_break()
+
+    def scan_anchor(self, TokenClass: Any) -> Any:
+        # The specification does not restrict characters for anchors and
+        # aliases. This may lead to problems, for instance, the document:
+        #   [ *alias, value ]
+        # can be interpteted in two ways, as
+        #   [ "value" ]
+        # and
+        #   [ *alias , "value" ]
+        # Therefore we restrict aliases to numbers and ASCII letters.
+        srp = self.reader.peek
+        start_mark = self.reader.get_mark()
+        indicator = srp()
+        if indicator == '*':
+            name = 'alias'
+        else:
+            name = 'anchor'
+        self.reader.forward()
+        length = 0
+        ch = srp(length)
+        # while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \
+        #         or ch in '-_':
+        while check_anchorname_char(ch):
+            length += 1
+            ch = srp(length)
+        if not length:
+            raise ScannerError(
+                f'while scanning an {name!s}',
+                start_mark,
+                f'expected alphabetic or numeric character, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        value = self.reader.prefix(length)
+        self.reader.forward(length)
+        # ch1 = ch
+        # ch = srp()   # no need to peek, ch is already set
+        # assert ch1 == ch
+        if ch not in '\0 \t\r\n\x85\u2028\u2029?:,[]{}%@`':
+            raise ScannerError(
+                f'while scanning an {name!s}',
+                start_mark,
+                f'expected alphabetic or numeric character, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        end_mark = self.reader.get_mark()
+        return TokenClass(value, start_mark, end_mark)
+
+    def scan_tag(self) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        start_mark = self.reader.get_mark()
+        ch = srp(1)
+        short_handle = '!'
+        if ch == '!':
+            short_handle = '!!'
+            self.reader.forward()
+            srp = self.reader.peek
+            ch = srp(1)
+
+        if ch == '<':
+            handle = None
+            self.reader.forward(2)
+            suffix = self.scan_tag_uri('tag', start_mark)
+            if srp() != '>':
+                raise ScannerError(
+                    'while parsing a tag',
+                    start_mark,
+                    f"expected '>' but found {srp()!r}",
+                    self.reader.get_mark(),
+                )
+            self.reader.forward()
+        elif ch in _THE_END_SPACE_TAB:
+            handle = None
+            suffix = short_handle
+            self.reader.forward()
+        else:
+            length = 1
+            use_handle = False
+            while ch not in '\0 \r\n\x85\u2028\u2029':
+                if ch == '!':
+                    use_handle = True
+                    break
+                length += 1
+                ch = srp(length)
+            handle = short_handle
+            if use_handle:
+                handle = self.scan_tag_handle('tag', start_mark)
+            else:
+                handle = short_handle
+                self.reader.forward()
+            suffix = self.scan_tag_uri('tag', start_mark)
+        ch = srp()
+        if ch not in '\0 \r\n\x85\u2028\u2029':
+            raise ScannerError(
+                'while scanning a tag',
+                start_mark,
+                f"expected ' ', but found {ch!r}",
+                self.reader.get_mark(),
+            )
+        value = (handle, suffix)
+        end_mark = self.reader.get_mark()
+        return tokens.TagToken(value, start_mark, end_mark)
+
+    def scan_block_scalar(self, style: Any, rt: Optional[bool] = False) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        if style == '>':
+            folded = True
+        else:
+            folded = False
+
+        chunks: List[Any] = []
+        start_mark = self.reader.get_mark()
+
+        # Scan the header.
+        self.reader.forward()
+        chomping, increment = self.scan_block_scalar_indicators(start_mark)
+        # block scalar comment e.g. : |+  # comment text
+        block_scalar_comment = self.scan_block_scalar_ignored_line(start_mark)
+
+        # Determine the indentation level and go to the first non-empty line.
+        min_indent = self.indent + 1
+        if increment is None:
+            # no increment and top level, min_indent could be 0
+            if min_indent < 1 and (
+                style not in '|>'
+                or (self.scanner_processing_version == (1, 1))
+                and getattr(
+                    self.loader, 'top_level_block_style_scalar_no_indent_error_1_1', False,
+                )
+            ):
+                min_indent = 1
+            breaks, max_indent, end_mark = self.scan_block_scalar_indentation()
+            indent = max(min_indent, max_indent)
+        else:
+            if min_indent < 1:
+                min_indent = 1
+            indent = min_indent + increment - 1
+            breaks, end_mark = self.scan_block_scalar_breaks(indent)
+        line_break = ""
+
+        # Scan the inner part of the block scalar.
+        while self.reader.column == indent and srp() != '\0':
+            chunks.extend(breaks)
+            leading_non_space = srp() not in ' \t'
+            length = 0
+            while srp(length) not in _THE_END:
+                length += 1
+            chunks.append(self.reader.prefix(length))
+            self.reader.forward(length)
+            line_break = self.scan_line_break()
+            breaks, end_mark = self.scan_block_scalar_breaks(indent)
+            if style in '|>' and min_indent == 0:
+                # at the beginning of a line, if in block style see if
+                # end of document/start_new_document
+                if self.check_document_start() or self.check_document_end():
+                    break
+            if self.reader.column == indent and srp() != '\0':
+
+                # Unfortunately, folding rules are ambiguous.
+                #
+                # This is the folding according to the specification:
+
+                if rt and folded and line_break == '\n':
+                    chunks.append('\a')
+                if folded and line_break == '\n' and leading_non_space and srp() not in ' \t':
+                    if not breaks:
+                        chunks.append(' ')
+                else:
+                    chunks.append(line_break)
+
+                # This is Clark Evans's interpretation (also in the spec
+                # examples):
+                #
+                # if folded and line_break == '\n':
+                #     if not breaks:
+                #         if srp() not in ' \t':
+                #             chunks.append(' ')
+                #         else:
+                #             chunks.append(line_break)
+                # else:
+                #     chunks.append(line_break)
+            else:
+                break
+
+        # Process trailing line breaks. The 'chomping' setting determines
+        # whether they are included in the value.
+        trailing: List[Any] = []
+        if chomping in [None, True]:
+            chunks.append(line_break)
+        if chomping is True:
+            chunks.extend(breaks)
+        elif chomping in [None, False]:
+            trailing.extend(breaks)
+
+        # We are done.
+        token = tokens.ScalarToken("".join(chunks), False, start_mark, end_mark, style)
+        if self.loader is not None:
+            comment_handler = getattr(self.loader, 'comment_handling', False)
+            if comment_handler is None:
+                if block_scalar_comment is not None:
+                    token.add_pre_comments([block_scalar_comment])
+        if len(trailing) > 0:
+            # Eat whitespaces and comments until we reach the next token.
+            if self.loader is not None:
+                comment_handler = getattr(self.loader, 'comment_handling', None)
+                if comment_handler is not None:
+                    line = end_mark.line - len(trailing)
+                    for x in trailing:
+                        assert x[-1] == '\n'
+                        self.comments.add_blank_line(x, 0, line)  # type: ignore
+                        line += 1
+            comment = self.scan_to_next_token()
+            while comment:
+                trailing.append(' ' * comment[1].column + comment[0])
+                comment = self.scan_to_next_token()
+            if self.loader is not None:
+                comment_handler = getattr(self.loader, 'comment_handling', False)
+                if comment_handler is None:
+                    # Keep track of the trailing whitespace and following comments
+                    # as a comment token, if isn't all included in the actual value.
+                    comment_end_mark = self.reader.get_mark()
+                    comment = tokens.CommentToken("".join(trailing),
+                                                  end_mark,
+                                                  comment_end_mark)
+                    token.add_post_comment(comment)
+        return token
+
+    def scan_block_scalar_indicators(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        chomping = None
+        increment = None
+        ch = srp()
+        if ch in '+-':
+            if ch == '+':
+                chomping = True
+            else:
+                chomping = False
+            self.reader.forward()
+            ch = srp()
+            if ch in '0123456789':
+                increment = int(ch)
+                if increment == 0:
+                    raise ScannerError(
+                        'while scanning a block scalar',
+                        start_mark,
+                        'expected indentation indicator in the range 1-9, ' 'but found 0',
+                        self.reader.get_mark(),
+                    )
+                self.reader.forward()
+        elif ch in '0123456789':
+            increment = int(ch)
+            if increment == 0:
+                raise ScannerError(
+                    'while scanning a block scalar',
+                    start_mark,
+                    'expected indentation indicator in the range 1-9, ' 'but found 0',
+                    self.reader.get_mark(),
+                )
+            self.reader.forward()
+            ch = srp()
+            if ch in '+-':
+                if ch == '+':
+                    chomping = True
+                else:
+                    chomping = False
+                self.reader.forward()
+        ch = srp()
+        if ch not in '\0 \r\n\x85\u2028\u2029':
+            raise ScannerError(
+                'while scanning a block scalar',
+                start_mark,
+                f'expected chomping or indentation indicators, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        return chomping, increment
+
+    def scan_block_scalar_ignored_line(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        prefix = ''
+        comment = None
+        while srp() == ' ':
+            prefix += srp()
+            srf()
+        if srp() == '#':
+            comment = prefix
+            while srp() not in _THE_END:
+                comment += srp()
+                srf()
+        ch = srp()
+        if ch not in _THE_END:
+            raise ScannerError(
+                'while scanning a block scalar',
+                start_mark,
+                f'expected a comment or a line break, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        self.scan_line_break()
+        return comment
+
+    def scan_block_scalar_indentation(self) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        chunks = []
+        first_indent = -1
+        max_indent = 0
+        end_mark = self.reader.get_mark()
+        while srp() in ' \r\n\x85\u2028\u2029':
+            if srp() != ' ':
+                if first_indent < 0:
+                    first_indent = self.reader.column
+                chunks.append(self.scan_line_break())
+                end_mark = self.reader.get_mark()
+            else:
+                srf()
+                if self.reader.column > max_indent:
+                    max_indent = self.reader.column
+        if first_indent > 0 and max_indent > first_indent:
+            start_mark = self.reader.get_mark()
+            raise ScannerError(
+                'more indented follow up line than first in a block scalar', start_mark,
+            )
+        return chunks, max_indent, end_mark
+
+    def scan_block_scalar_breaks(self, indent: int) -> Any:
+        # See the specification for details.
+        chunks = []
+        srp = self.reader.peek
+        srf = self.reader.forward
+        end_mark = self.reader.get_mark()
+        while self.reader.column < indent and srp() == ' ':
+            srf()
+        while srp() in '\r\n\x85\u2028\u2029':
+            chunks.append(self.scan_line_break())
+            end_mark = self.reader.get_mark()
+            while self.reader.column < indent and srp() == ' ':
+                srf()
+        return chunks, end_mark
+
+    def scan_flow_scalar(self, style: Any) -> Any:
+        # See the specification for details.
+        # Note that we loose indentation rules for quoted scalars. Quoted
+        # scalars don't need to adhere indentation because " and ' clearly
+        # mark the beginning and the end of them. Therefore we are less
+        # restrictive then the specification requires. We only need to check
+        # that document separators are not included in scalars.
+        if style == '"':
+            double = True
+        else:
+            double = False
+        srp = self.reader.peek
+        chunks: List[Any] = []
+        start_mark = self.reader.get_mark()
+        quote = srp()
+        self.reader.forward()
+        chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
+        while srp() != quote:
+            chunks.extend(self.scan_flow_scalar_spaces(double, start_mark))
+            chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
+        self.reader.forward()
+        end_mark = self.reader.get_mark()
+        return tokens.ScalarToken("".join(chunks), False, start_mark, end_mark, style)
+
+    ESCAPE_REPLACEMENTS = {
+        '0': '\0',
+        'a': '\x07',
+        'b': '\x08',
+        't': '\x09',
+        '\t': '\x09',
+        'n': '\x0A',
+        'v': '\x0B',
+        'f': '\x0C',
+        'r': '\x0D',
+        'e': '\x1B',
+        ' ': '\x20',
+        '"': '"',
+        '/': '/',  # as per http://www.json.org/
+        '\\': '\\',
+        'N': '\x85',
+        '_': '\xA0',
+        'L': '\u2028',
+        'P': '\u2029',
+    }
+
+    ESCAPE_CODES = {'x': 2, 'u': 4, 'U': 8}
+
+    def scan_flow_scalar_non_spaces(self, double: Any, start_mark: Any) -> Any:
+        # See the specification for details.
+        chunks: List[Any] = []
+        srp = self.reader.peek
+        srf = self.reader.forward
+        while True:
+            length = 0
+            while srp(length) not in ' \n\'"\\\0\t\r\x85\u2028\u2029':
+                length += 1
+            if length != 0:
+                chunks.append(self.reader.prefix(length))
+                srf(length)
+            ch = srp()
+            if not double and ch == "'" and srp(1) == "'":
+                chunks.append("'")
+                srf(2)
+            elif (double and ch == "'") or (not double and ch in '"\\'):
+                chunks.append(ch)
+                srf()
+            elif double and ch == '\\':
+                srf()
+                ch = srp()
+                if ch in self.ESCAPE_REPLACEMENTS:
+                    chunks.append(self.ESCAPE_REPLACEMENTS[ch])
+                    srf()
+                elif ch in self.ESCAPE_CODES:
+                    length = self.ESCAPE_CODES[ch]
+                    srf()
+                    for k in range(length):
+                        if srp(k) not in '0123456789ABCDEFabcdef':
+                            raise ScannerError(
+                                'while scanning a double-quoted scalar',
+                                start_mark,
+                                f'expected escape sequence of {length:d} '
+                                f'hexdecimal numbers, but found {srp(k)!r}',
+                                self.reader.get_mark(),
+                            )
+                    code = int(self.reader.prefix(length), 16)
+                    chunks.append(chr(code))
+                    srf(length)
+                elif ch in '\n\r\x85\u2028\u2029':
+                    self.scan_line_break()
+                    chunks.extend(self.scan_flow_scalar_breaks(double, start_mark))
+                else:
+                    raise ScannerError(
+                        'while scanning a double-quoted scalar',
+                        start_mark,
+                        f'found unknown escape character {ch!r}',
+                        self.reader.get_mark(),
+                    )
+            else:
+                return chunks
+
+    def scan_flow_scalar_spaces(self, double: Any, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        chunks = []
+        length = 0
+        while srp(length) in ' \t':
+            length += 1
+        whitespaces = self.reader.prefix(length)
+        self.reader.forward(length)
+        ch = srp()
+        if ch == '\0':
+            raise ScannerError(
+                'while scanning a quoted scalar',
+                start_mark,
+                'found unexpected end of stream',
+                self.reader.get_mark(),
+            )
+        elif ch in '\r\n\x85\u2028\u2029':
+            line_break = self.scan_line_break()
+            breaks = self.scan_flow_scalar_breaks(double, start_mark)
+            if line_break != '\n':
+                chunks.append(line_break)
+            elif not breaks:
+                chunks.append(' ')
+            chunks.extend(breaks)
+        else:
+            chunks.append(whitespaces)
+        return chunks
+
+    def scan_flow_scalar_breaks(self, double: Any, start_mark: Any) -> Any:
+        # See the specification for details.
+        chunks: List[Any] = []
+        srp = self.reader.peek
+        srf = self.reader.forward
+        while True:
+            # Instead of checking indentation, we check for document
+            # separators.
+            prefix = self.reader.prefix(3)
+            if (prefix == '---' or prefix == '...') and srp(3) in _THE_END_SPACE_TAB:
+                raise ScannerError(
+                    'while scanning a quoted scalar',
+                    start_mark,
+                    'found unexpected document separator',
+                    self.reader.get_mark(),
+                )
+            while srp() in ' \t':
+                srf()
+            if srp() in '\r\n\x85\u2028\u2029':
+                chunks.append(self.scan_line_break())
+            else:
+                return chunks
+
+    def scan_plain(self) -> Any:
+        # See the specification for details.
+        # We add an additional restriction for the flow context:
+        #   plain scalars in the flow context cannot contain ',', ': '  and '?'.
+        # We also keep track of the `allow_simple_key` flag here.
+        # Indentation rules are loosed for the flow context.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        chunks: List[Any] = []
+        start_mark = self.reader.get_mark()
+        end_mark = start_mark
+        indent = self.indent + 1
+        # We allow zero indentation for scalars, but then we need to check for
+        # document separators at the beginning of the line.
+        # if indent == 0:
+        #     indent = 1
+        spaces: List[Any] = []
+        while True:
+            length = 0
+            if srp() == '#':
+                break
+            while True:
+                ch = srp(length)
+                if False and ch == ':' and srp(length + 1) == ',':
+                    break
+                elif ch == ':' and srp(length + 1) not in _THE_END_SPACE_TAB:
+                    pass
+                elif ch == '?' and self.scanner_processing_version != (1, 1):
+                    pass
+                elif (
+                    ch in _THE_END_SPACE_TAB
+                    or (
+                        not self.flow_level
+                        and ch == ':'
+                        and srp(length + 1) in _THE_END_SPACE_TAB
+                    )
+                    or (self.flow_level and ch in ',:?[]{}')
+                ):
+                    break
+                length += 1
+            # It's not clear what we should do with ':' in the flow context.
+            if (
+                self.flow_level
+                and ch == ':'
+                and srp(length + 1) not in '\0 \t\r\n\x85\u2028\u2029,[]{}'
+            ):
+                srf(length)
+                raise ScannerError(
+                    'while scanning a plain scalar',
+                    start_mark,
+                    "found unexpected ':'",
+                    self.reader.get_mark(),
+                    'Please check '
+                    'http://pyyaml.org/wiki/YAMLColonInFlowContext '
+                    'for details.',
+                )
+            if length == 0:
+                break
+            self.allow_simple_key = False
+            chunks.extend(spaces)
+            chunks.append(self.reader.prefix(length))
+            srf(length)
+            end_mark = self.reader.get_mark()
+            spaces = self.scan_plain_spaces(indent, start_mark)
+            if (
+                not spaces
+                or srp() == '#'
+                or (not self.flow_level and self.reader.column < indent)
+            ):
+                break
+
+        token = tokens.ScalarToken("".join(chunks), True, start_mark, end_mark)
+        # getattr provides True so C type loader, which cannot handle comment,
+        # will not make CommentToken
+        if self.loader is not None:
+            comment_handler = getattr(self.loader, 'comment_handling', False)
+            if comment_handler is None:
+                if spaces and spaces[0] == '\n':
+                    # Create a comment token to preserve the trailing line breaks.
+                    comment = tokens.CommentToken("".join(spaces) + '\n', start_mark, end_mark)
+                    token.add_post_comment(comment)
+            elif comment_handler is not False:
+                line = start_mark.line + 1
+                for ch in spaces:
+                    if ch == '\n':
+                        self.comments.add_blank_line('\n', 0, line)  # type: ignore
+                        line += 1
+
+        return token
+
+    def scan_plain_spaces(self, indent: Any, start_mark: Any) -> Any:
+        # See the specification for details.
+        # The specification is really confusing about tabs in plain scalars.
+        # We just forbid them completely. Do not use tabs in YAML!
+        srp = self.reader.peek
+        srf = self.reader.forward
+        chunks = []
+        length = 0
+        while srp(length) in ' ':
+            length += 1
+        whitespaces = self.reader.prefix(length)
+        self.reader.forward(length)
+        ch = srp()
+        if ch in '\r\n\x85\u2028\u2029':
+            line_break = self.scan_line_break()
+            self.allow_simple_key = True
+            prefix = self.reader.prefix(3)
+            if (prefix == '---' or prefix == '...') and srp(3) in _THE_END_SPACE_TAB:
+                return
+            breaks = []
+            while srp() in ' \r\n\x85\u2028\u2029':
+                if srp() == ' ':
+                    srf()
+                else:
+                    breaks.append(self.scan_line_break())
+                    prefix = self.reader.prefix(3)
+                    if (prefix == '---' or prefix == '...') and srp(3) in _THE_END_SPACE_TAB:
+                        return
+            if line_break != '\n':
+                chunks.append(line_break)
+            elif not breaks:
+                chunks.append(' ')
+            chunks.extend(breaks)
+        elif whitespaces:
+            chunks.append(whitespaces)
+        return chunks
+
+    def scan_tag_handle(self, name: Any, start_mark: Any) -> Any:
+        # See the specification for details.
+        # For some strange reasons, the specification does not allow '_' in
+        # tag handles. I have allowed it anyway.
+        srp = self.reader.peek
+        ch = srp()
+        if ch != '!':
+            raise ScannerError(
+                f'while scanning an {name!s}',
+                start_mark,
+                f"expected '!', but found {ch!r}",
+                self.reader.get_mark(),
+            )
+        length = 1
+        ch = srp(length)
+        if ch != ' ':
+            while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in '-_':
+                length += 1
+                ch = srp(length)
+            if ch != '!':
+                self.reader.forward(length)
+                raise ScannerError(
+                    f'while scanning an {name!s}',
+                    start_mark,
+                    f"expected '!' but found {ch!r}",
+                    self.reader.get_mark(),
+                )
+            length += 1
+        value = self.reader.prefix(length)
+        self.reader.forward(length)
+        return value
+
+    def scan_tag_uri(self, name: Any, start_mark: Any) -> Any:
+        # See the specification for details.
+        # Note: we do not check if URI is well-formed.
+        srp = self.reader.peek
+        chunks = []
+        length = 0
+        ch = srp(length)
+        while (
+            '0' <= ch <= '9'
+            or 'A' <= ch <= 'Z'
+            or 'a' <= ch <= 'z'
+            or ch in "-;/?:@&=+$,_.!~*'()[]%"
+            or ((self.scanner_processing_version > (1, 1)) and ch == '#')
+        ):
+            if ch == '%':
+                chunks.append(self.reader.prefix(length))
+                self.reader.forward(length)
+                length = 0
+                chunks.append(self.scan_uri_escapes(name, start_mark))
+            else:
+                length += 1
+            ch = srp(length)
+        if length != 0:
+            chunks.append(self.reader.prefix(length))
+            self.reader.forward(length)
+            length = 0
+        if not chunks:
+            raise ScannerError(
+                f'while parsing an {name!s}',
+                start_mark,
+                f'expected URI, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        return "".join(chunks)
+
+    def scan_uri_escapes(self, name: Any, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        code_bytes: List[Any] = []
+        mark = self.reader.get_mark()
+        while srp() == '%':
+            srf()
+            for k in range(2):
+                if srp(k) not in '0123456789ABCDEFabcdef':
+                    raise ScannerError(
+                        f'while scanning an {name!s}',
+                        start_mark,
+                        f'expected URI escape sequence of 2 hexdecimal numbers, '
+                        f'but found {srp(k)!r}',
+                        self.reader.get_mark(),
+                    )
+            code_bytes.append(int(self.reader.prefix(2), 16))
+            srf(2)
+        try:
+            value = bytes(code_bytes).decode('utf-8')
+        except UnicodeDecodeError as exc:
+            raise ScannerError(f'while scanning an {name!s}', start_mark, str(exc), mark)
+        return value
+
+    def scan_line_break(self) -> Any:
+        # Transforms:
+        #   '\r\n'      :   '\n'
+        #   '\r'        :   '\n'
+        #   '\n'        :   '\n'
+        #   '\x85'      :   '\n'
+        #   '\u2028'    :   '\u2028'
+        #   '\u2029     :   '\u2029'
+        #   default     :   ''
+        ch = self.reader.peek()
+        if ch in '\r\n\x85':
+            if self.reader.prefix(2) == '\r\n':
+                self.reader.forward(2)
+            else:
+                self.reader.forward()
+            return '\n'
+        elif ch in '\u2028\u2029':
+            self.reader.forward()
+            return ch
+        return ""
+
+
+class RoundTripScanner(Scanner):
+    def check_token(self, *choices: Any) -> bool:
+        # Check if the next token is one of the given types.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        self._gather_comments()
+        if len(self.tokens) > 0:
+            if not choices:
+                return True
+            for choice in choices:
+                if isinstance(self.tokens[0], choice):
+                    return True
+        return False
+
+    def peek_token(self) -> Any:
+        # Return the next token, but do not delete if from the queue.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        self._gather_comments()
+        if len(self.tokens) > 0:
+            return self.tokens[0]
+        return None
+
+    def _gather_comments(self) -> Any:
+        """combine multiple comment lines and assign to next non-comment-token"""
+        comments: List[Any] = []
+        if not self.tokens:
+            return comments
+        if isinstance(self.tokens[0], tokens.CommentToken):
+            comment = self.tokens.pop(0)
+            self.tokens_taken += 1
+            comments.append(comment)
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+            if not self.tokens:
+                return comments
+            if isinstance(self.tokens[0], tokens.CommentToken):
+                self.tokens_taken += 1
+                comment = self.tokens.pop(0)
+                # nprint('dropping2', comment)
+                comments.append(comment)
+        if len(comments) >= 1:
+            self.tokens[0].add_pre_comments(comments)
+        # pull in post comment on e.g. ':'
+        if not self.done and len(self.tokens) < 2:
+            self.fetch_more_tokens()
+
+    def get_token(self) -> Any:
+        # Return the next token.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        self._gather_comments()
+        if len(self.tokens) > 0:
+            # nprint('tk', self.tokens)
+            # only add post comment to single line tokens:
+            # scalar, value token. FlowXEndToken, otherwise
+            # hidden streamtokens could get them (leave them and they will be
+            # pre comments for the next map/seq
+            if (
+                len(self.tokens) > 1
+                and isinstance(
+                    self.tokens[0],
+                    (tokens.ScalarToken, tokens.ValueToken, tokens.FlowSequenceEndToken,
+                     tokens.FlowMappingEndToken),
+                )
+                and isinstance(self.tokens[1], tokens.CommentToken)
+                and self.tokens[0].end_mark.line == self.tokens[1].start_mark.line
+            ):
+                self.tokens_taken += 1
+                c = self.tokens.pop(1)
+                self.fetch_more_tokens()
+                while len(self.tokens) > 1 and isinstance(self.tokens[1], tokens.CommentToken):
+                    self.tokens_taken += 1
+                    c1 = self.tokens.pop(1)
+                    c.value = c.value + (' ' * c1.start_mark.column) + c1.value
+                    self.fetch_more_tokens()
+                self.tokens[0].add_post_comment(c)
+            elif (
+                len(self.tokens) > 1
+                and isinstance(self.tokens[0], tokens.ScalarToken)
+                and isinstance(self.tokens[1], tokens.CommentToken)
+                and self.tokens[0].end_mark.line != self.tokens[1].start_mark.line
+            ):
+                self.tokens_taken += 1
+                c = self.tokens.pop(1)
+                c.value = (
+                    '\n' * (c.start_mark.line - self.tokens[0].end_mark.line)
+                    + (' ' * c.start_mark.column)
+                    + c.value
+                )
+                self.tokens[0].add_post_comment(c)
+                self.fetch_more_tokens()
+                while len(self.tokens) > 1 and isinstance(self.tokens[1], tokens.CommentToken):
+                    self.tokens_taken += 1
+                    c1 = self.tokens.pop(1)
+                    c.value = c.value + (' ' * c1.start_mark.column) + c1.value
+                    self.fetch_more_tokens()
+            self.tokens_taken += 1
+            return self.tokens.pop(0)
+        return None
+
+    def fetch_comment(self, comment: Any) -> None:
+        value, start_mark, end_mark = comment
+        while value and value[-1] == ' ':
+            # empty line within indented key context
+            # no need to update end-mark, that is not used
+            value = value[:-1]
+        self.tokens.append(tokens.CommentToken(value, start_mark, end_mark))
+
+    # scanner
+
+    def scan_to_next_token(self) -> Any:
+        # We ignore spaces, line breaks and comments.
+        # If we find a line break in the block context, we set the flag
+        # `allow_simple_key` on.
+        # The byte order mark is stripped if it's the first character in the
+        # stream. We do not yet support BOM inside the stream as the
+        # specification requires. Any such mark will be considered as a part
+        # of the document.
+        #
+        # TODO: We need to make tab handling rules more sane. A good rule is
+        #   Tabs cannot precede tokens
+        #   BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END,
+        #   KEY(block), VALUE(block), BLOCK-ENTRY
+        # So the checking code is
+        #   if :
+        #       self.allow_simple_keys = False
+        # We also need to add the check for `allow_simple_keys == True` to
+        # `unwind_indent` before issuing BLOCK-END.
+        # Scanners for block, flow, and plain scalars need to be modified.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        if self.reader.index == 0 and srp() == '\uFEFF':
+            srf()
+        found = False
+        white_space = ' \t' if self.flow_level > 0 else ' '
+        while not found:
+            while srp() in white_space:
+                srf()
+            ch = srp()
+            if ch == '#':
+                start_mark = self.reader.get_mark()
+                comment = ch
+                srf()
+                while ch not in _THE_END:
+                    ch = srp()
+                    if ch == '\0':  # don't gobble the end-of-stream character
+                        # but add an explicit newline as "YAML processors should terminate
+                        # the stream with an explicit line break
+                        # https://yaml.org/spec/1.2/spec.html#id2780069
+                        comment += '\n'
+                        break
+                    comment += ch
+                    srf()
+                # gather any blank lines following the comment
+                ch = self.scan_line_break()
+                while len(ch) > 0:
+                    comment += ch
+                    ch = self.scan_line_break()
+                end_mark = self.reader.get_mark()
+                if not self.flow_level:
+                    self.allow_simple_key = True
+                return comment, start_mark, end_mark
+            if self.scan_line_break() != '':
+                start_mark = self.reader.get_mark()
+                if not self.flow_level:
+                    self.allow_simple_key = True
+                ch = srp()
+                if ch == '\n':  # empty toplevel lines
+                    start_mark = self.reader.get_mark()
+                    comment = ""
+                    while ch:
+                        ch = self.scan_line_break(empty_line=True)
+                        comment += ch
+                    if srp() == '#':
+                        # empty line followed by indented real comment
+                        comment = comment.rsplit('\n', 1)[0] + '\n'
+                    end_mark = self.reader.get_mark()
+                    return comment, start_mark, end_mark
+            else:
+                found = True
+        return None
+
+    def scan_line_break(self, empty_line: bool = False) -> Text:
+        # Transforms:
+        #   '\r\n'      :   '\n'
+        #   '\r'        :   '\n'
+        #   '\n'        :   '\n'
+        #   '\x85'      :   '\n'
+        #   '\u2028'    :   '\u2028'
+        #   '\u2029     :   '\u2029'
+        #   default     :   ''
+        ch: Text = self.reader.peek()
+        if ch in '\r\n\x85':
+            if self.reader.prefix(2) == '\r\n':
+                self.reader.forward(2)
+            else:
+                self.reader.forward()
+            return '\n'
+        elif ch in '\u2028\u2029':
+            self.reader.forward()
+            return ch
+        elif empty_line and ch in '\t ':
+            self.reader.forward()
+            return ch
+        return ""
+
+    def scan_block_scalar(self, style: Any, rt: Optional[bool] = True) -> Any:
+        return Scanner.scan_block_scalar(self, style, rt=rt)
+
+    def scan_uri_escapes(self, name: Any, start_mark: Any) -> Any:
+        """
+        The roundtripscanner doesn't do URI escaping
+        """
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        code_bytes: List[Any] = []
+        chunk = ''
+        mark = self.reader.get_mark()
+        while srp() == '%':
+            chunk += '%'
+            srf()
+            for k in range(2):
+                if srp(k) not in '0123456789ABCDEFabcdef':
+                    raise ScannerError(
+                        f'while scanning an {name!s}',
+                        start_mark,
+                        f'expected URI escape sequence of 2 hexdecimal numbers, '
+                        f'but found {srp(k)!r}',
+                        self.reader.get_mark(),
+                    )
+            code_bytes.append(int(self.reader.prefix(2), 16))
+            chunk += self.reader.prefix(2)
+            srf(2)
+        try:
+            _ = bytes(code_bytes).decode('utf-8')
+        except UnicodeDecodeError as exc:
+            raise ScannerError(f'while scanning an {name!s}', start_mark, str(exc), mark)
+        return chunk
+
+
+# commenthandling 2021, differentiatiation not needed
+
+VALUECMNT = 0
+KEYCMNT = 0  # 1
+# TAGCMNT = 2
+# ANCHORCMNT = 3
+
+
+class CommentBase:
+    __slots__ = ('value', 'line', 'column', 'used', 'function', 'fline', 'ufun', 'uline')
+
+    def __init__(self, value: Any, line: Any, column: Any) -> None:
+        self.value = value
+        self.line = line
+        self.column = column
+        self.used = ' '
+        if _debug != 0:
+            import inspect
+
+            info = inspect.getframeinfo(inspect.stack()[3][0])
+            self.function = info.function
+            self.fline = info.lineno
+            self.ufun = None
+            self.uline = None
+
+    def set_used(self, v: Any = '+') -> None:
+        self.used = v
+        if _debug != 0:
+            import inspect
+
+            info = inspect.getframeinfo(inspect.stack()[1][0])
+            self.ufun = info.function  # type: ignore
+            self.uline = info.lineno  # type: ignore
+
+    def set_assigned(self) -> None:
+        self.used = '|'
+
+    def __str__(self) -> str:
+        return f'{self.value}'
+
+    def __repr__(self) -> str:
+        return f'{self.value!r}'
+
+    def info(self) -> str:
+        xv = self.value + '"'
+        name = self.name  # type: ignore
+        return (
+            f'{name}{self.used} {self.line:2}:{self.column:<2} "{xv:40s} '
+            f'{self.function}:{self.fline} {self.ufun}:{self.uline}'
+        )
+
+
+class EOLComment(CommentBase):
+    name = 'EOLC'
+
+    def __init__(self, value: Any, line: Any, column: Any) -> None:
+        super().__init__(value, line, column)
+
+
+class FullLineComment(CommentBase):
+    name = 'FULL'
+
+    def __init__(self, value: Any, line: Any, column: Any) -> None:
+        super().__init__(value, line, column)
+
+
+class BlankLineComment(CommentBase):
+    name = 'BLNK'
+
+    def __init__(self, value: Any, line: Any, column: Any) -> None:
+        super().__init__(value, line, column)
+
+
+class ScannedComments:
+    def __init__(self: Any) -> None:
+        self.comments = {}  # type: ignore
+        self.unused = []  # type: ignore
+
+    def add_eol_comment(self, comment: Any, column: Any, line: Any) -> Any:
+        # info = inspect.getframeinfo(inspect.stack()[1][0])
+        if comment.count('\n') == 1:
+            assert comment[-1] == '\n'
+        else:
+            assert '\n' not in comment
+        self.comments[line] = retval = EOLComment(comment[:-1], line, column)
+        self.unused.append(line)
+        return retval
+
+    def add_blank_line(self, comment: Any, column: Any, line: Any) -> Any:
+        # info = inspect.getframeinfo(inspect.stack()[1][0])
+        assert comment.count('\n') == 1 and comment[-1] == '\n'
+        assert line not in self.comments
+        self.comments[line] = retval = BlankLineComment(comment[:-1], line, column)
+        self.unused.append(line)
+        return retval
+
+    def add_full_line_comment(self, comment: Any, column: Any, line: Any) -> Any:
+        # info = inspect.getframeinfo(inspect.stack()[1][0])
+        assert comment.count('\n') == 1 and comment[-1] == '\n'
+        # if comment.startswith('# C12'):
+        #    raise
+        # this raises in line 2127 fro 330
+        self.comments[line] = retval = FullLineComment(comment[:-1], line, column)
+        self.unused.append(line)
+        return retval
+
+    def __getitem__(self, idx: Any) -> Any:
+        return self.comments[idx]
+
+    def __str__(self) -> Any:
+        return (
+            'ParsedComments:\n  '
+            + '\n  '.join((f'{lineno:2} {x.info()}' for lineno, x in self.comments.items()))
+            + '\n'
+        )
+
+    def last(self) -> str:
+        lineno, x = list(self.comments.items())[-1]
+        return f'{lineno:2} {x.info()}\n'
+
+    def any_unprocessed(self) -> bool:
+        # ToDo: might want to differentiate based on lineno
+        return len(self.unused) > 0
+        # for lno, comment in reversed(self.comments.items()):
+        #    if comment.used == ' ':
+        #        return True
+        # return False
+
+    def unprocessed(self, use: Any = False) -> Any:
+        while len(self.unused) > 0:
+            if _debug != 0:
+                import inspect
+
+                first = self.unused.pop(0) if use else self.unused[0]
+                info = inspect.getframeinfo(inspect.stack()[1][0])
+                xprintf('using', first, self.comments[first].value, info.function, info.lineno)
+            yield first, self.comments[first]
+            if use:
+                self.comments[first].set_used()
+
+    def assign_pre(self, token: Any) -> Any:
+        token_line = token.start_mark.line
+        if _debug != 0:
+            import inspect
+
+            info = inspect.getframeinfo(inspect.stack()[1][0])
+            xprintf('assign_pre', token_line, self.unused, info.function, info.lineno)
+        gobbled = False
+        while self.unused and self.unused[0] < token_line:
+            gobbled = True
+            first = self.unused.pop(0)
+            if _debug != 0:
+                xprintf('assign_pre < ', first)
+            self.comments[first].set_used()
+            token.add_comment_pre(first)
+        return gobbled
+
+    def assign_eol(self, tokens: Any) -> Any:
+        try:
+            comment_line = self.unused[0]
+        except IndexError:
+            return
+        if not isinstance(self.comments[comment_line], EOLComment):
+            return
+        idx = 1
+        while tokens[-idx].start_mark.line > comment_line or isinstance(
+            tokens[-idx], tokens.ValueToken,
+        ):
+            idx += 1
+        if _debug != 0:
+            xprintf('idx1', idx)
+        if (
+            len(tokens) > idx
+            and isinstance(tokens[-idx], tokens.ScalarToken)
+            and isinstance(tokens[-(idx + 1)], tokens.ScalarToken)
+        ):
+            return
+        try:
+            if isinstance(tokens[-idx], tokens.ScalarToken) and isinstance(
+                tokens[-(idx + 1)], tokens.KeyToken,
+            ):
+                try:
+                    eol_idx = self.unused.pop(0)
+                    self.comments[eol_idx].set_used()
+                    if _debug != 0:
+                        xprintf('>>>>>a', idx, eol_idx, KEYCMNT)
+                    tokens[-idx].add_comment_eol(eol_idx, KEYCMNT)
+                except IndexError:
+                    raise NotImplementedError
+                return
+        except IndexError:
+            if _debug != 0:
+                xprintf('IndexError1')
+            pass
+        try:
+            if isinstance(tokens[-idx], tokens.ScalarToken) and isinstance(
+                tokens[-(idx + 1)], (tokens.ValueToken, tokens.BlockEntryToken),
+            ):
+                try:
+                    eol_idx = self.unused.pop(0)
+                    self.comments[eol_idx].set_used()
+                    tokens[-idx].add_comment_eol(eol_idx, VALUECMNT)
+                except IndexError:
+                    raise NotImplementedError
+                return
+        except IndexError:
+            if _debug != 0:
+                xprintf('IndexError2')
+            pass
+        for t in tokens:
+            xprintf('tt-', t)
+        if _debug != 0:
+            xprintf('not implemented EOL', type(tokens[-idx]))
+        import sys
+
+        sys.exit(0)
+
+    def assign_post(self, token: Any) -> Any:
+        token_line = token.start_mark.line
+        if _debug != 0:
+            import inspect
+
+            info = inspect.getframeinfo(inspect.stack()[1][0])
+            xprintf('assign_post', token_line, self.unused, info.function, info.lineno)
+        gobbled = False
+        while self.unused and self.unused[0] < token_line:
+            gobbled = True
+            first = self.unused.pop(0)
+            if _debug != 0:
+                xprintf('assign_post < ', first)
+            self.comments[first].set_used()
+            token.add_comment_post(first)
+        return gobbled
+
+    def str_unprocessed(self) -> Any:
+        return ''.join(
+            (f'  {ind:2} {x.info()}\n' for ind, x in self.comments.items() if x.used == ' '),
+        )
+
+
+class RoundTripScannerSC(Scanner):  # RoundTripScanner Split Comments
+    def __init__(self, *arg: Any, **kw: Any) -> None:
+        super().__init__(*arg, **kw)
+        assert self.loader is not None
+        # comments isinitialised on .need_more_tokens and persist on
+        # self.loader.parsed_comments
+        self.comments = None
+
+    def get_token(self) -> Any:
+        # Return the next token.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        if len(self.tokens) > 0:
+            if isinstance(self.tokens[0], tokens.BlockEndToken):
+                self.comments.assign_post(self.tokens[0])  # type: ignore
+            else:
+                self.comments.assign_pre(self.tokens[0])  # type: ignore
+            self.tokens_taken += 1
+            return self.tokens.pop(0)
+
+    def need_more_tokens(self) -> bool:
+        if self.comments is None:
+            self.loader.parsed_comments = self.comments = ScannedComments()  # type: ignore
+        if self.done:
+            return False
+        if len(self.tokens) == 0:
+            return True
+        # The current token may be a potential simple key, so we
+        # need to look further.
+        self.stale_possible_simple_keys()
+        if self.next_possible_simple_key() == self.tokens_taken:
+            return True
+        if len(self.tokens) < 2:
+            return True
+        if self.tokens[0].start_mark.line == self.tokens[-1].start_mark.line:
+            return True
+        if True:
+            if _debug != 0:
+                xprintf('-x--', len(self.tokens))
+                for t in self.tokens:
+                    xprintf(t)
+                # xprintf(self.comments.last())
+                xprintf(self.comments.str_unprocessed())  # type: ignore
+        self.comments.assign_pre(self.tokens[0])  # type: ignore
+        self.comments.assign_eol(self.tokens)  # type: ignore
+        return False
+
+    def scan_to_next_token(self) -> None:
+        srp = self.reader.peek
+        srf = self.reader.forward
+        if self.reader.index == 0 and srp() == '\uFEFF':
+            srf()
+        start_mark = self.reader.get_mark()
+        # xprintf('current_mark', start_mark.line, start_mark.column)
+        found = False
+        while not found:
+            while srp() == ' ':
+                srf()
+            ch = srp()
+            if ch == '#':
+                comment_start_mark = self.reader.get_mark()
+                comment = ch
+                srf()  # skipt the '#'
+                while ch not in _THE_END:
+                    ch = srp()
+                    if ch == '\0':  # don't gobble the end-of-stream character
+                        # but add an explicit newline as "YAML processors should terminate
+                        # the stream with an explicit line break
+                        # https://yaml.org/spec/1.2/spec.html#id2780069
+                        comment += '\n'
+                        break
+                    comment += ch
+                    srf()
+                # we have a comment
+                if start_mark.column == 0:
+                    self.comments.add_full_line_comment(  # type: ignore
+                        comment, comment_start_mark.column, comment_start_mark.line,
+                    )
+                else:
+                    self.comments.add_eol_comment(  # type: ignore
+                        comment, comment_start_mark.column, comment_start_mark.line,
+                    )
+                    comment = ""
+                # gather any blank lines or full line comments following the comment as well
+                self.scan_empty_or_full_line_comments()
+                if not self.flow_level:
+                    self.allow_simple_key = True
+                return
+            if bool(self.scan_line_break()):
+                # start_mark = self.reader.get_mark()
+                if not self.flow_level:
+                    self.allow_simple_key = True
+                self.scan_empty_or_full_line_comments()
+                return None
+                ch = srp()
+                if ch == '\n':  # empty toplevel lines
+                    start_mark = self.reader.get_mark()
+                    comment = ""
+                    while ch:
+                        ch = self.scan_line_break(empty_line=True)
+                        comment += ch
+                    if srp() == '#':
+                        # empty line followed by indented real comment
+                        comment = comment.rsplit('\n', 1)[0] + '\n'
+                    _ = self.reader.get_mark()  # gobble end_mark
+                    return None
+            else:
+                found = True
+        return None
+
+    def scan_empty_or_full_line_comments(self) -> None:
+        blmark = self.reader.get_mark()
+        assert blmark.column == 0
+        blanks = ""
+        comment = None
+        mark = None
+        ch = self.reader.peek()
+        while True:
+            # nprint('ch', repr(ch), self.reader.get_mark().column)
+            if ch in '\r\n\x85\u2028\u2029':
+                if self.reader.prefix(2) == '\r\n':
+                    self.reader.forward(2)
+                else:
+                    self.reader.forward()
+                if comment is not None:
+                    comment += '\n'
+                    self.comments.add_full_line_comment(comment, mark.column, mark.line)
+                    comment = None
+                else:
+                    blanks += '\n'
+                    self.comments.add_blank_line(blanks, blmark.column, blmark.line)  # type: ignore # NOQA
+                blanks = ""
+                blmark = self.reader.get_mark()
+                ch = self.reader.peek()
+                continue
+            if comment is None:
+                if ch in ' \t':
+                    blanks += ch
+                elif ch == '#':
+                    mark = self.reader.get_mark()
+                    comment = '#'
+                else:
+                    # xprintf('breaking on', repr(ch))
+                    break
+            else:
+                comment += ch
+            self.reader.forward()
+            ch = self.reader.peek()
+
+    def scan_block_scalar_ignored_line(self, start_mark: Any) -> Any:
+        # See the specification for details.
+        srp = self.reader.peek
+        srf = self.reader.forward
+        prefix = ''
+        comment = None
+        while srp() == ' ':
+            prefix += srp()
+            srf()
+        if srp() == '#':
+            comment = ''
+            mark = self.reader.get_mark()
+            while srp() not in _THE_END:
+                comment += srp()
+                srf()
+            comment += '\n'  # type: ignore
+        ch = srp()
+        if ch not in _THE_END:
+            raise ScannerError(
+                'while scanning a block scalar',
+                start_mark,
+                f'expected a comment or a line break, but found {ch!r}',
+                self.reader.get_mark(),
+            )
+        if comment is not None:
+            self.comments.add_eol_comment(comment, mark.column, mark.line)  # type: ignore
+        self.scan_line_break()
+        return None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py
new file mode 100644
index 00000000000..7ca2d75ca0e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py
@@ -0,0 +1,233 @@
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError
+from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, DBG_NODE, dbg, nprintf  # NOQA
+from opentelemetry.agent._vendor.ruamel.yaml.util import RegExp
+
+from opentelemetry.agent._vendor.ruamel.yaml.events import (
+    StreamStartEvent,
+    StreamEndEvent,
+    MappingStartEvent,
+    MappingEndEvent,
+    SequenceStartEvent,
+    SequenceEndEvent,
+    AliasEvent,
+    ScalarEvent,
+    DocumentStartEvent,
+    DocumentEndEvent,
+)
+from opentelemetry.agent._vendor.ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode
+
+if False:  # MYPY
+    from typing import Any, Dict, Union, Text, Optional  # NOQA
+    from opentelemetry.agent._vendor.ruamel.yaml.compat import VersionType  # NOQA
+
+__all__ = ['Serializer', 'SerializerError']
+
+
+class SerializerError(YAMLError):
+    pass
+
+
+class Serializer:
+
+    # 'id' and 3+ numbers, but not 000
+    ANCHOR_TEMPLATE = 'id{:03d}'
+    ANCHOR_RE = RegExp('id(?!000$)\\d{3,}')
+
+    def __init__(
+        self,
+        encoding: Any = None,
+        explicit_start: Optional[bool] = None,
+        explicit_end: Optional[bool] = None,
+        version: Optional[VersionType] = None,
+        tags: Any = None,
+        dumper: Any = None,
+    ) -> None:
+        # NOQA
+        self.dumper = dumper
+        if self.dumper is not None:
+            self.dumper._serializer = self
+        self.use_encoding = encoding
+        self.use_explicit_start = explicit_start
+        self.use_explicit_end = explicit_end
+        if isinstance(version, str):
+            self.use_version = tuple(map(int, version.split('.')))
+        else:
+            self.use_version = version  # type: ignore
+        self.use_tags = tags
+        self.serialized_nodes: Dict[Any, Any] = {}
+        self.anchors: Dict[Any, Any] = {}
+        self.last_anchor_id = 0
+        self.closed: Optional[bool] = None
+        self._templated_id = None
+
+    @property
+    def emitter(self) -> Any:
+        if hasattr(self.dumper, 'typ'):
+            return self.dumper.emitter
+        return self.dumper._emitter
+
+    @property
+    def resolver(self) -> Any:
+        if hasattr(self.dumper, 'typ'):
+            self.dumper.resolver
+        return self.dumper._resolver
+
+    def open(self) -> None:
+        if self.closed is None:
+            self.emitter.emit(StreamStartEvent(encoding=self.use_encoding))
+            self.closed = False
+        elif self.closed:
+            raise SerializerError('serializer is closed')
+        else:
+            raise SerializerError('serializer is already opened')
+
+    def close(self) -> None:
+        if self.closed is None:
+            raise SerializerError('serializer is not opened')
+        elif not self.closed:
+            self.emitter.emit(StreamEndEvent())
+            self.closed = True
+
+    # def __del__(self):
+    #     self.close()
+
+    def serialize(self, node: Any) -> None:
+        if dbg(DBG_NODE):
+            nprint('Serializing nodes')
+            node.dump()
+        if self.closed is None:
+            raise SerializerError('serializer is not opened')
+        elif self.closed:
+            raise SerializerError('serializer is closed')
+        self.emitter.emit(
+            DocumentStartEvent(
+                explicit=self.use_explicit_start, version=self.use_version, tags=self.use_tags,
+            ),
+        )
+        self.anchor_node(node)
+        self.serialize_node(node, None, None)
+        self.emitter.emit(DocumentEndEvent(explicit=self.use_explicit_end))
+        self.serialized_nodes = {}
+        self.anchors = {}
+        self.last_anchor_id = 0
+
+    def anchor_node(self, node: Any) -> None:
+        if node in self.anchors:
+            if self.anchors[node] is None:
+                self.anchors[node] = self.generate_anchor(node)
+        else:
+            anchor = None
+            try:
+                if node.anchor.always_dump:
+                    anchor = node.anchor.value
+            except:  # NOQA
+                pass
+            self.anchors[node] = anchor
+            if isinstance(node, SequenceNode):
+                for item in node.value:
+                    self.anchor_node(item)
+            elif isinstance(node, MappingNode):
+                for key, value in node.value:
+                    self.anchor_node(key)
+                    self.anchor_node(value)
+
+    def generate_anchor(self, node: Any) -> Any:
+        try:
+            anchor = node.anchor.value
+        except:  # NOQA
+            anchor = None
+        if anchor is None:
+            self.last_anchor_id += 1
+            return self.ANCHOR_TEMPLATE.format(self.last_anchor_id)
+        return anchor
+
+    def serialize_node(self, node: Any, parent: Any, index: Any) -> None:
+        alias = self.anchors[node]
+        if node in self.serialized_nodes:
+            node_style = getattr(node, 'style', None)
+            if node_style != '?':
+                node_style = None
+            self.emitter.emit(AliasEvent(alias, style=node_style))
+        else:
+            self.serialized_nodes[node] = True
+            self.resolver.descend_resolver(parent, index)
+            if isinstance(node, ScalarNode):
+                # here check if the node.tag equals the one that would result from parsing
+                # if not equal quoting is necessary for strings
+                detected_tag = self.resolver.resolve(ScalarNode, node.value, (True, False))
+                default_tag = self.resolver.resolve(ScalarNode, node.value, (False, True))
+                implicit = (
+                    (node.ctag == detected_tag),
+                    (node.ctag == default_tag),
+                    node.tag.startswith('tag:yaml.org,2002:'),  # type: ignore
+                )
+                self.emitter.emit(
+                    ScalarEvent(
+                        alias,
+                        node.ctag,
+                        implicit,
+                        node.value,
+                        style=node.style,
+                        comment=node.comment,
+                    ),
+                )
+            elif isinstance(node, SequenceNode):
+                implicit = node.ctag == self.resolver.resolve(SequenceNode, node.value, True)
+                comment = node.comment
+                end_comment = None
+                seq_comment = None
+                if node.flow_style is True:
+                    if comment:  # eol comment on flow style sequence
+                        seq_comment = comment[0]
+                        # comment[0] = None
+                if comment and len(comment) > 2:
+                    end_comment = comment[2]
+                else:
+                    end_comment = None
+                self.emitter.emit(
+                    SequenceStartEvent(
+                        alias,
+                        node.ctag,
+                        implicit,
+                        flow_style=node.flow_style,
+                        comment=node.comment,
+                    ),
+                )
+                index = 0
+                for item in node.value:
+                    self.serialize_node(item, node, index)
+                    index += 1
+                self.emitter.emit(SequenceEndEvent(comment=[seq_comment, end_comment]))
+            elif isinstance(node, MappingNode):
+                implicit = node.ctag == self.resolver.resolve(MappingNode, node.value, True)
+                comment = node.comment
+                end_comment = None
+                map_comment = None
+                if node.flow_style is True:
+                    if comment:  # eol comment on flow style sequence
+                        map_comment = comment[0]
+                        # comment[0] = None
+                if comment and len(comment) > 2:
+                    end_comment = comment[2]
+                self.emitter.emit(
+                    MappingStartEvent(
+                        alias,
+                        node.ctag,
+                        implicit,
+                        flow_style=node.flow_style,
+                        comment=node.comment,
+                        nr_items=len(node.value),
+                    ),
+                )
+                for key, value in node.value:
+                    self.serialize_node(key, node, None)
+                    self.serialize_node(value, node, key)
+                self.emitter.emit(MappingEndEvent(comment=[map_comment, end_comment]))
+            self.resolver.ascend_resolver()
+
+
+def templated_id(s: Text) -> Any:
+    return Serializer.ANCHOR_RE.match(s)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py
new file mode 100644
index 00000000000..f85dd031185
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py
@@ -0,0 +1,126 @@
+
+from __future__ import annotations
+
+"""
+In round-trip mode the original tag needs to be preserved, but the tag
+transformed based on the directives needs to be available as well.
+
+A Tag that is created during loading has a handle and a suffix.
+Not all objects loaded currently have a Tag, that .tag attribute can be None
+A Tag that is created for dumping only (on an object loaded without a tag) has a suffix
+only.
+"""
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Union, Iterator  # NOQA
+
+tag_attrib = '_yaml_tag'
+
+
+class Tag:
+    """store original tag information for roundtripping"""
+
+    attrib = tag_attrib
+
+    def __init__(self, handle: Any = None, suffix: Any = None, handles: Any = None) -> None:
+        self.handle = handle
+        self.suffix = suffix
+        self.handles = handles
+        self._transform_type: Optional[bool] = None
+
+    def __repr__(self) -> str:
+        return f'{self.__class__.__name__}({self.trval!r})'
+
+    def __str__(self) -> str:
+        return f'{self.trval}'
+
+    def __hash__(self) -> int:
+        try:
+            return self._hash_id  # type: ignore
+        except AttributeError:
+            self._hash_id = res = hash((self.handle, self.suffix))
+            return res
+
+    def __eq__(self, other: Any) -> bool:
+        # other should not be a string, but the serializer sometimes provides these
+        if isinstance(other, str):
+            return self.trval == other
+        return bool(self.trval == other.trval)
+
+    def startswith(self, x: str) -> bool:
+        if self.trval is not None:
+            return self.trval.startswith(x)
+        return False
+
+    @property
+    def trval(self) -> Optional[str]:
+        try:
+            return self._trval
+        except AttributeError:
+            pass
+        if self.handle is None:
+            self._trval: Optional[str] = self.uri_decoded_suffix
+            return self._trval
+        assert self._transform_type is not None
+        if not self._transform_type:
+            # the non-round-trip case
+            self._trval = self.handles[self.handle] + self.uri_decoded_suffix
+            return self._trval
+        # round-trip case
+        if self.handle == '!!' and self.suffix in (
+            'null',
+            'bool',
+            'int',
+            'float',
+            'binary',
+            'timestamp',
+            'omap',
+            'pairs',
+            'set',
+            'str',
+            'seq',
+            'map',
+        ):
+            self._trval = self.handles[self.handle] + self.uri_decoded_suffix
+        else:
+            # self._trval = self.handle + self.suffix
+            self._trval = self.handles[self.handle] + self.uri_decoded_suffix
+        return self._trval
+
+    value = trval
+
+    @property
+    def uri_decoded_suffix(self) -> Optional[str]:
+        try:
+            return self._uri_decoded_suffix
+        except AttributeError:
+            pass
+        if self.suffix is None:
+            self._uri_decoded_suffix: Optional[str] = None
+            return None
+        res = ''
+        # don't have to check for scanner errors here
+        idx = 0
+        while idx < len(self.suffix):
+            ch = self.suffix[idx]
+            idx += 1
+            if ch != '%':
+                res += ch
+            else:
+                res += chr(int(self.suffix[idx : idx + 2], 16))
+                idx += 2
+        self._uri_decoded_suffix = res
+        return res
+
+    def select_transform(self, val: bool) -> None:
+        """
+        val: False -> non-round-trip
+             True -> round-trip
+        """
+        assert self._transform_type is None
+        self._transform_type = val
+
+    def check_handle(self) -> bool:
+        if self.handle is None:
+            return False
+        return self.handle not in self.handles
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py
new file mode 100644
index 00000000000..55efa0a45f1
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py
@@ -0,0 +1,63 @@
+
+from __future__ import annotations
+
+import copy
+import datetime
+
+# ToDo: at least on PY3 you could probably attach the tzinfo correctly to the object
+#       a more complete datetime might be used by safe loading as well
+#
+#       add type information (iso8601, spaced)
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List  # NOQA
+
+
+class TimeStamp(datetime.datetime):
+    def __init__(self, *args: Any, **kw: Any) -> None:
+        self._yaml: Dict[str, Any] = dict(t=False, tz=None, delta=0)
+
+    def __new__(cls, *args: Any, **kw: Any) -> Any:  # datetime is immutable
+        return datetime.datetime.__new__(cls, *args, **kw)
+
+    def __deepcopy__(self, memo: Any) -> Any:
+        ts = TimeStamp(self.year, self.month, self.day, self.hour, self.minute, self.second)
+        ts._yaml = copy.deepcopy(self._yaml)
+        return ts
+
+    def replace(
+        self,
+        year: Any = None,
+        month: Any = None,
+        day: Any = None,
+        hour: Any = None,
+        minute: Any = None,
+        second: Any = None,
+        microsecond: Any = None,
+        tzinfo: Any = True,
+        fold: Any = None,
+    ) -> Any:
+        if year is None:
+            year = self.year
+        if month is None:
+            month = self.month
+        if day is None:
+            day = self.day
+        if hour is None:
+            hour = self.hour
+        if minute is None:
+            minute = self.minute
+        if second is None:
+            second = self.second
+        if microsecond is None:
+            microsecond = self.microsecond
+        if tzinfo is True:
+            tzinfo = self.tzinfo
+        if fold is None:
+            fold = self.fold
+        ts = type(self)(year, month, day, hour, minute, second, microsecond, tzinfo, fold=fold)
+        ts._yaml = copy.deepcopy(self._yaml)
+        return ts
+
+    def __str__(self) -> str:
+        return self.isoformat('T' if self._yaml['t'] else ' ')
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py
new file mode 100644
index 00000000000..5c23c19e56d
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py
@@ -0,0 +1,384 @@
+
+from __future__ import annotations
+
+from opentelemetry.agent._vendor.ruamel.yaml.compat import nprintf  # NOQA
+
+if False:  # MYPY
+    from typing import Text, Any, Dict, Optional, List  # NOQA
+from .error import StreamMark  # NOQA
+
+SHOW_LINES = True
+
+
+class Token:
+    __slots__ = 'start_mark', 'end_mark', '_comment'
+
+    def __init__(self, start_mark: StreamMark, end_mark: StreamMark) -> None:
+        self.start_mark = start_mark
+        self.end_mark = end_mark
+
+    def __repr__(self) -> Any:
+        # attributes = [key for key in self.__slots__ if not key.endswith('_mark') and
+        #               hasattr('self', key)]
+        attributes = [key for key in self.__slots__ if not key.endswith('_mark')]
+        attributes.sort()
+        # arguments = ', '.join(
+        #  [f'{key!s}={getattr(self, key)!r})' for key in attributes]
+        # )
+        arguments = [f'{key!s}={getattr(self, key)!r}' for key in attributes]
+        if SHOW_LINES:
+            try:
+                arguments.append('line: ' + str(self.start_mark.line))
+            except:  # NOQA
+                pass
+        try:
+            arguments.append('comment: ' + str(self._comment))
+        except:  # NOQA
+            pass
+        return f'{self.__class__.__name__}({", ".join(arguments)})'
+
+    @property
+    def column(self) -> int:
+        return self.start_mark.column
+
+    @column.setter
+    def column(self, pos: Any) -> None:
+        self.start_mark.column = pos
+
+    # old style ( <= 0.17) is a TWO element list with first being the EOL
+    # comment concatenated with following FLC/BLNK; and second being a list of FLC/BLNK
+    # preceding the token
+    # new style ( >= 0.17 ) is a THREE element list with the first being a list of
+    # preceding FLC/BLNK, the second EOL and the third following FLC/BLNK
+    # note that new style has differing order, and does not consist of CommentToken(s)
+    # but of CommentInfo instances
+    # any non-assigned values in new style are None, but first and last can be empty list
+    # new style routines add one comment at a time
+
+    # going to be deprecated in favour of add_comment_eol/post
+    def add_post_comment(self, comment: Any) -> None:
+        if not hasattr(self, '_comment'):
+            self._comment = [None, None]
+        else:
+            assert len(self._comment) in [2, 5]  # make sure it is version 0
+        # if isinstance(comment, CommentToken):
+        #    if comment.value.startswith('# C09'):
+        #        raise
+        self._comment[0] = comment
+
+    # going to be deprecated in favour of add_comment_pre
+    def add_pre_comments(self, comments: Any) -> None:
+        if not hasattr(self, '_comment'):
+            self._comment = [None, None]
+        else:
+            assert len(self._comment) == 2  # make sure it is version 0
+        assert self._comment[1] is None
+        self._comment[1] = comments
+        return
+
+    # new style
+    def add_comment_pre(self, comment: Any) -> None:
+        if not hasattr(self, '_comment'):
+            self._comment = [[], None, None]  # type: ignore
+        else:
+            assert len(self._comment) == 3
+            if self._comment[0] is None:
+                self._comment[0] = []  # type: ignore
+        self._comment[0].append(comment)  # type: ignore
+
+    def add_comment_eol(self, comment: Any, comment_type: Any) -> None:
+        if not hasattr(self, '_comment'):
+            self._comment = [None, None, None]
+        else:
+            assert len(self._comment) == 3
+            assert self._comment[1] is None
+        if self.comment[1] is None:
+            self._comment[1] = []  # type: ignore
+        self._comment[1].extend([None] * (comment_type + 1 - len(self.comment[1])))  # type: ignore # NOQA
+        # nprintf('commy', self.comment, comment_type)
+        self._comment[1][comment_type] = comment  # type: ignore
+
+    def add_comment_post(self, comment: Any) -> None:
+        if not hasattr(self, '_comment'):
+            self._comment = [None, None, []]  # type: ignore
+        else:
+            assert len(self._comment) == 3
+            if self._comment[2] is None:
+                self._comment[2] = []  # type: ignore
+        self._comment[2].append(comment)  # type: ignore
+
+    # def get_comment(self) -> Any:
+    #     return getattr(self, '_comment', None)
+
+    @property
+    def comment(self) -> Any:
+        return getattr(self, '_comment', None)
+
+    def move_old_comment(self, target: Any, empty: bool = False) -> Any:
+        """move a comment from this token to target (normally next token)
+        used to combine e.g. comments before a BlockEntryToken to the
+        ScalarToken that follows it
+        empty is a special for empty values -> comment after key
+        """
+        c = self.comment
+        if c is None:
+            return
+        # don't push beyond last element
+        if isinstance(target, (StreamEndToken, DocumentStartToken)):
+            return
+        delattr(self, '_comment')  # NOQA
+        tc = target.comment
+        if not tc:  # target comment, just insert
+            # special for empty value in key: value issue 25
+            if empty:
+                c = [c[0], c[1], None, None, c[0]]
+            target._comment = c
+            # nprint('mco2:', self, target, target.comment, empty)
+            return self
+        if c[0] and tc[0] or c[1] and tc[1]:
+            if isinstance(c[1], list) and isinstance(tc[1], list):
+                c[1].extend(tc[1])
+            else:
+                raise NotImplementedError(f'overlap in comment {c!r} {tc!r}')
+        if c[0]:
+            tc[0] = c[0]
+        if c[1]:
+            tc[1] = c[1]
+        return self
+
+    def split_old_comment(self) -> Any:
+        """ split the post part of a comment, and return it
+        as comment to be added. Delete second part if [None, None]
+         abc:  # this goes to sequence
+           # this goes to first element
+           - first element
+        """
+        comment = self.comment
+        if comment is None or comment[0] is None:
+            return None  # nothing to do
+        ret_val = [comment[0], None]
+        if comment[1] is None:
+            delattr(self, '_comment')  # NOQA
+        return ret_val
+
+    def move_new_comment(self, target: Any, empty: bool = False) -> Any:
+        """move a comment from this token to target (normally next token)
+        used to combine e.g. comments before a BlockEntryToken to the
+        ScalarToken that follows it
+        empty is a special for empty values -> comment after key
+        """
+        c = self.comment
+        if c is None:
+            return
+        # don't push beyond last element
+        if isinstance(target, (StreamEndToken, DocumentStartToken)):
+            return
+        delattr(self, '_comment')  # NOQA
+        tc = target.comment
+        if not tc:  # target comment, just insert
+            # special for empty value in key: value issue 25
+            if empty:
+                c = [c[0], c[1], c[2]]
+            target._comment = c
+            # nprint('mco2:', self, target, target.comment, empty)
+            return self
+        # if self and target have both pre, eol or post comments, something seems wrong
+        for idx in range(3):
+            if c[idx] is not None and tc[idx] is not None:
+                raise NotImplementedError(f'overlap in comment {c!r} {tc!r}')
+        # move the comment parts
+        for idx in range(3):
+            if c[idx]:
+                tc[idx] = c[idx]
+        return self
+
+
+# class BOMToken(Token):
+#     id = ''
+
+
+class DirectiveToken(Token):
+    __slots__ = 'name', 'value'
+    id = ''
+
+    def __init__(self, name: Any, value: Any, start_mark: Any, end_mark: Any) -> None:
+        Token.__init__(self, start_mark, end_mark)
+        self.name = name
+        self.value = value
+
+
+class DocumentStartToken(Token):
+    __slots__ = ()
+    id = ''
+
+
+class DocumentEndToken(Token):
+    __slots__ = ()
+    id = ''
+
+
+class StreamStartToken(Token):
+    __slots__ = ('encoding',)
+    id = ''
+
+    def __init__(
+        self, start_mark: Any = None, end_mark: Any = None, encoding: Any = None,
+    ) -> None:
+        Token.__init__(self, start_mark, end_mark)
+        self.encoding = encoding
+
+
+class StreamEndToken(Token):
+    __slots__ = ()
+    id = ''
+
+
+class BlockSequenceStartToken(Token):
+    __slots__ = ()
+    id = ''
+
+
+class BlockMappingStartToken(Token):
+    __slots__ = ()
+    id = ''
+
+
+class BlockEndToken(Token):
+    __slots__ = ()
+    id = ''
+
+
+class FlowSequenceStartToken(Token):
+    __slots__ = ()
+    id = '['
+
+
+class FlowMappingStartToken(Token):
+    __slots__ = ()
+    id = '{'
+
+
+class FlowSequenceEndToken(Token):
+    __slots__ = ()
+    id = ']'
+
+
+class FlowMappingEndToken(Token):
+    __slots__ = ()
+    id = '}'
+
+
+class KeyToken(Token):
+    __slots__ = ()
+    id = '?'
+
+#   def x__repr__(self):
+#       return f'KeyToken({self.start_mark.buffer[self.start_mark.index:].split(None, 1)[0]})'
+
+
+class ValueToken(Token):
+    __slots__ = ()
+    id = ':'
+
+
+class BlockEntryToken(Token):
+    __slots__ = ()
+    id = '-'
+
+
+class FlowEntryToken(Token):
+    __slots__ = ()
+    id = ','
+
+
+class AliasToken(Token):
+    __slots__ = ('value',)
+    id = ''
+
+    def __init__(self, value: Any, start_mark: Any, end_mark: Any) -> None:
+        Token.__init__(self, start_mark, end_mark)
+        self.value = value
+
+
+class AnchorToken(Token):
+    __slots__ = ('value',)
+    id = ''
+
+    def __init__(self, value: Any, start_mark: Any, end_mark: Any) -> None:
+        Token.__init__(self, start_mark, end_mark)
+        self.value = value
+
+
+class TagToken(Token):
+    __slots__ = ('value',)
+    id = ''
+
+    def __init__(self, value: Any, start_mark: Any, end_mark: Any) -> None:
+        Token.__init__(self, start_mark, end_mark)
+        self.value = value
+
+
+class ScalarToken(Token):
+    __slots__ = 'value', 'plain', 'style'
+    id = ''
+
+    def __init__(
+        self, value: Any, plain: Any, start_mark: Any, end_mark: Any, style: Any = None,
+    ) -> None:
+        Token.__init__(self, start_mark, end_mark)
+        self.value = value
+        self.plain = plain
+        self.style = style
+
+
+class CommentToken(Token):
+    __slots__ = '_value', '_column', 'pre_done'
+    id = ''
+
+    def __init__(
+        self, value: Any, start_mark: Any = None, end_mark: Any = None, column: Any = None,
+    ) -> None:
+        if start_mark is None:
+            assert column is not None
+            self._column = column
+        Token.__init__(self, start_mark, end_mark)
+        self._value = value
+
+    @property
+    def value(self) -> str:
+        if isinstance(self._value, str):
+            return self._value
+        return "".join(self._value)
+
+    @value.setter
+    def value(self, val: Any) -> None:
+        self._value = val
+
+    def reset(self) -> None:
+        if hasattr(self, 'pre_done'):
+            delattr(self, 'pre_done')  # NOQA
+
+    def __repr__(self) -> Any:
+        v = f'{self.value!r}'
+        if SHOW_LINES:
+            try:
+                v += ', line: ' + str(self.start_mark.line)
+            except:  # NOQA
+                pass
+            try:
+                v += ', col: ' + str(self.start_mark.column)
+            except:  # NOQA
+                pass
+        return f'CommentToken({v})'
+
+    def __eq__(self, other: Any) -> bool:
+        if self.start_mark != other.start_mark:
+            return False
+        if self.end_mark != other.end_mark:
+            return False
+        if self.value != other.value:
+            return False
+        return True
+
+    def __ne__(self, other: Any) -> bool:
+        return not self.__eq__(other)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py
new file mode 100644
index 00000000000..398e0e9cf75
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py
@@ -0,0 +1,264 @@
+
+
+"""
+some helper functions that might be generally useful
+"""
+
+from __future__ import annotations
+
+import datetime
+from functools import partial
+import re
+
+
+if False:  # MYPY
+    from typing import Any, Dict, Optional, List, Text, Callable, Union  # NOQA
+    from .compat import StreamTextType  # NOQA
+
+
+class LazyEval:
+    """
+    Lightweight wrapper around lazily evaluated func(*args, **kwargs).
+
+    func is only evaluated when any attribute of its return value is accessed.
+    Every attribute access is passed through to the wrapped value.
+    (This only excludes special cases like method-wrappers, e.g., __hash__.)
+    The sole additional attribute is the lazy_self function which holds the
+    return value (or, prior to evaluation, func and arguments), in its closure.
+    """
+
+    def __init__(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
+        def lazy_self() -> Any:
+            return_value = func(*args, **kwargs)
+            object.__setattr__(self, 'lazy_self', lambda: return_value)
+            return return_value
+
+        object.__setattr__(self, 'lazy_self', lazy_self)
+
+    def __getattribute__(self, name: str) -> Any:
+        lazy_self = object.__getattribute__(self, 'lazy_self')
+        if name == 'lazy_self':
+            return lazy_self
+        return getattr(lazy_self(), name)
+
+    def __setattr__(self, name: str, value: Any) -> None:
+        setattr(self.lazy_self(), name, value)
+
+
+RegExp = partial(LazyEval, re.compile)
+
+timestamp_regexp = RegExp(
+    """^(?P[0-9][0-9][0-9][0-9])
+       -(?P[0-9][0-9]?)
+       -(?P[0-9][0-9]?)
+       (?:((?P[Tt])|[ \\t]+)   # explictly not retaining extra spaces
+       (?P[0-9][0-9]?)
+       :(?P[0-9][0-9])
+       :(?P[0-9][0-9])
+       (?:\\.(?P[0-9]*))?
+        (?:[ \\t]*(?PZ|(?P[-+])(?P[0-9][0-9]?)
+       (?::(?P[0-9][0-9]))?))?)?$""",
+    re.X,
+)
+
+
+def create_timestamp(
+    year: Any,
+    month: Any,
+    day: Any,
+    t: Any,
+    hour: Any,
+    minute: Any,
+    second: Any,
+    fraction: Any,
+    tz: Any,
+    tz_sign: Any,
+    tz_hour: Any,
+    tz_minute: Any,
+) -> Union[datetime.datetime, datetime.date]:
+    # create a timestamp from matching against timestamp_regexp
+    MAX_FRAC = 999999
+    year = int(year)
+    month = int(month)
+    day = int(day)
+    if hour is None:
+        return datetime.date(year, month, day)
+    hour = int(hour)
+    minute = int(minute)
+    second = int(second)
+    frac = 0
+    if fraction:
+        frac_s = fraction[:6]
+        while len(frac_s) < 6:
+            frac_s += '0'
+        frac = int(frac_s)
+        if len(fraction) > 6 and int(fraction[6]) > 4:
+            frac += 1
+        if frac > MAX_FRAC:
+            fraction = 0
+        else:
+            fraction = frac
+    else:
+        fraction = 0
+    tzinfo = None
+    delta = None
+    if tz_sign:
+        tz_hour = int(tz_hour)
+        tz_minute = int(tz_minute) if tz_minute else 0
+        td = datetime.timedelta(
+            hours=tz_hour, minutes=tz_minute,
+        )
+        if tz_sign == '-':
+            td = -td
+        tzinfo = datetime.timezone(td, name=tz)
+    elif tz == 'Z':
+        tzinfo = datetime.timezone(datetime.timedelta(hours=0), name=tz)
+    if frac > MAX_FRAC:
+        delta = -datetime.timedelta(seconds=1)
+    # should do something else instead (or hook this up to the preceding if statement
+    # in reverse
+    #  if delta is None:
+    #      return datetime.datetime(year, month, day, hour, minute, second, fraction)
+    #  return datetime.datetime(year, month, day, hour, minute, second, fraction,
+    #                           datetime.timezone.utc)
+    # the above is not good enough though, should provide tzinfo. In Python3 that is easily
+    # doable drop that kind of support for Python2 as it has not native tzinfo
+    data = datetime.datetime(year, month, day, hour, minute, second, fraction, tzinfo)
+    if delta:
+        data -= delta
+    return data
+
+
+# originally as comment
+# https://github.com/pre-commit/pre-commit/pull/211#issuecomment-186466605
+# if you use this in your code, I suggest adding a test in your test suite
+# that check this routines output against a known piece of your YAML
+# before upgrades to this code break your round-tripped YAML
+def load_yaml_guess_indent(stream: StreamTextType, **kw: Any) -> Any:
+    """guess the indent and block sequence indent of yaml stream/string
+
+    returns round_trip_loaded stream, indent level, block sequence indent
+    - block sequence indent is the number of spaces before a dash relative to previous indent
+    - if there are no block sequences, indent is taken from nested mappings, block sequence
+      indent is unset (None) in that case
+    """
+    from .main import YAML
+
+    # load a YAML document, guess the indentation, if you use TABs you are on your own
+    def leading_spaces(line: Any) -> int:
+        idx = 0
+        while idx < len(line) and line[idx] == ' ':
+            idx += 1
+        return idx
+
+    if isinstance(stream, str):
+        yaml_str: Any = stream
+    elif isinstance(stream, bytes):
+        # most likely, but the Reader checks BOM for this
+        yaml_str = stream.decode('utf-8')
+    else:
+        yaml_str = stream.read()
+    map_indent = None
+    indent = None  # default if not found for some reason
+    block_seq_indent = None
+    prev_line_key_only = None
+    key_indent = 0
+    for line in yaml_str.splitlines():
+        rline = line.rstrip()
+        lline = rline.lstrip()
+        if lline.startswith('- '):
+            l_s = leading_spaces(line)
+            block_seq_indent = l_s - key_indent
+            idx = l_s + 1
+            while line[idx] == ' ':  # this will end as we rstripped
+                idx += 1
+            if line[idx] == '#':  # comment after -
+                continue
+            indent = idx - key_indent
+            break
+        if map_indent is None and prev_line_key_only is not None and rline:
+            idx = 0
+            while line[idx] in ' -':
+                idx += 1
+            if idx > prev_line_key_only:
+                map_indent = idx - prev_line_key_only
+        if rline.endswith(':'):
+            key_indent = leading_spaces(line)
+            idx = 0
+            while line[idx] == ' ':  # this will end on ':'
+                idx += 1
+            prev_line_key_only = idx
+            continue
+        prev_line_key_only = None
+    if indent is None and map_indent is not None:
+        indent = map_indent
+    yaml = YAML() if 'yaml' not in kw else kw.pop('yaml')
+    return yaml.load(yaml_str, **kw), indent, block_seq_indent
+
+
+def configobj_walker(cfg: Any) -> Any:
+    """
+    walks over a ConfigObj (INI file with comments) generating
+    corresponding YAML output (including comments
+    """
+    from configobj import ConfigObj  # type: ignore
+
+    assert isinstance(cfg, ConfigObj)
+    for c in cfg.initial_comment:
+        if c.strip():
+            yield c
+    for s in _walk_section(cfg):
+        if s.strip():
+            yield s
+    for c in cfg.final_comment:
+        if c.strip():
+            yield c
+
+
+def _walk_section(s: Any, level: int = 0) -> Any:
+    from configobj import Section
+
+    assert isinstance(s, Section)
+    indent = '  ' * level
+    for name in s.scalars:
+        for c in s.comments[name]:
+            yield indent + c.strip()
+        x = s[name]
+        if '\n' in x:
+            i = indent + '  '
+            x = '|\n' + i + x.strip().replace('\n', '\n' + i)
+        elif ':' in x:
+            x = "'" + x.replace("'", "''") + "'"
+        line = f'{indent}{name}: {x}'
+        c = s.inline_comments[name]
+        if c:
+            line += ' ' + c
+        yield line
+    for name in s.sections:
+        for c in s.comments[name]:
+            yield indent + c.strip()
+        line = f'{indent}{name}:'
+        c = s.inline_comments[name]
+        if c:
+            line += ' ' + c
+        yield line
+        for val in _walk_section(s[name], level=level + 1):
+            yield val
+
+
+# def config_obj_2_rt_yaml(cfg):
+#     from .comments import CommentedMap, CommentedSeq
+#     from configobj import ConfigObj
+#     assert isinstance(cfg, ConfigObj)
+#     #for c in cfg.initial_comment:
+#     #    if c.strip():
+#     #        pass
+#     cm = CommentedMap()
+#     for name in s.sections:
+#         cm[name] = d = CommentedMap()
+#
+#
+#     #for c in cfg.final_comment:
+#     #    if c.strip():
+#     #        yield c
+#     return cm
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE
new file mode 100644
index 00000000000..f26bcf4d2de
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE
@@ -0,0 +1,279 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see https://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations, which became
+Zope Corporation.  In 2001, the Python Software Foundation (PSF, see
+https://www.python.org/psf/) was formed, a non-profit organization
+created specifically to own Python-related Intellectual Property.
+Zope Corporation was a sponsoring member of the PSF.
+
+All Python releases are Open Source (see https://opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2 and above   2.1.1       2001-now    PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+Python software and documentation are licensed under the
+Python Software Foundation License Version 2.
+
+Starting with Python 3.8.6, examples, recipes, and other code in
+the documentation are dual licensed under the PSF License Version 2
+and the Zero-Clause BSD license.
+
+Some software incorporated into Python is under different licenses.
+The licenses are listed with code falling under that license.
+
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation;
+All Rights Reserved" are retained in Python alone or in any derivative version
+prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION
+----------------------------------------------------------------------
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py
new file mode 100644
index 00000000000..ced78373258
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py
@@ -0,0 +1,4422 @@
+import abc
+import builtins
+import collections
+import collections.abc
+import contextlib
+import enum
+import functools
+import inspect
+import io
+import keyword
+import operator
+import sys
+import types as _types
+import typing
+import warnings
+
+# Breakpoint: https://github.com/python/cpython/pull/119891
+if sys.version_info >= (3, 14):
+    import annotationlib
+
+__all__ = [
+    # Super-special typing primitives.
+    'Any',
+    'ClassVar',
+    'Concatenate',
+    'Final',
+    'LiteralString',
+    'ParamSpec',
+    'ParamSpecArgs',
+    'ParamSpecKwargs',
+    'Self',
+    'Type',
+    'TypeVar',
+    'TypeVarTuple',
+    'Unpack',
+
+    # ABCs (from collections.abc).
+    'Awaitable',
+    'AsyncIterator',
+    'AsyncIterable',
+    'Coroutine',
+    'AsyncGenerator',
+    'AsyncContextManager',
+    'Buffer',
+    'ChainMap',
+
+    # Concrete collection types.
+    'ContextManager',
+    'Counter',
+    'Deque',
+    'DefaultDict',
+    'NamedTuple',
+    'OrderedDict',
+    'TypedDict',
+
+    # Structural checks, a.k.a. protocols.
+    'SupportsAbs',
+    'SupportsBytes',
+    'SupportsComplex',
+    'SupportsFloat',
+    'SupportsIndex',
+    'SupportsInt',
+    'SupportsRound',
+    'Reader',
+    'Writer',
+
+    # One-off things.
+    'Annotated',
+    'assert_never',
+    'assert_type',
+    'clear_overloads',
+    'dataclass_transform',
+    'deprecated',
+    'disjoint_base',
+    'Doc',
+    'evaluate_forward_ref',
+    'get_overloads',
+    'final',
+    'Format',
+    'get_annotations',
+    'get_args',
+    'get_origin',
+    'get_original_bases',
+    'get_protocol_members',
+    'get_type_hints',
+    'IntVar',
+    'is_protocol',
+    'is_typeddict',
+    'Literal',
+    'NewType',
+    'overload',
+    'override',
+    'Protocol',
+    'sentinel',
+    'Sentinel',
+    'reveal_type',
+    'runtime',
+    'runtime_checkable',
+    'Text',
+    'TypeAlias',
+    'TypeAliasType',
+    'TypeForm',
+    'TypeGuard',
+    'TypeIs',
+    'TYPE_CHECKING',
+    'type_repr',
+    'Never',
+    'NoReturn',
+    'ReadOnly',
+    'Required',
+    'NotRequired',
+    'NoDefault',
+    'NoExtraItems',
+
+    # Pure aliases, have always been in typing
+    'AbstractSet',
+    'AnyStr',
+    'BinaryIO',
+    'Callable',
+    'Collection',
+    'Container',
+    'Dict',
+    'ForwardRef',
+    'FrozenSet',
+    'Generator',
+    'Generic',
+    'Hashable',
+    'IO',
+    'ItemsView',
+    'Iterable',
+    'Iterator',
+    'KeysView',
+    'List',
+    'Mapping',
+    'MappingView',
+    'Match',
+    'MutableMapping',
+    'MutableSequence',
+    'MutableSet',
+    'Optional',
+    'Pattern',
+    'Reversible',
+    'Sequence',
+    'Set',
+    'Sized',
+    'TextIO',
+    'Tuple',
+    'Union',
+    'ValuesView',
+    'cast',
+    'no_type_check',
+]
+
+# for backward compatibility
+PEP_560 = True
+GenericMeta = type
+# Breakpoint: https://github.com/python/cpython/pull/116129
+_PEP_696_IMPLEMENTED = sys.version_info >= (3, 13, 0, "beta")
+
+# Added with bpo-45166 to 3.10.1+ and some 3.9 versions
+_FORWARD_REF_HAS_CLASS = "__forward_is_class__" in typing.ForwardRef.__slots__
+
+
+def _caller(depth=1, default='__main__'):
+    try:
+        return sys._getframemodulename(depth + 1) or default
+    except AttributeError:  # For platforms without _getframemodulename()
+        pass
+    try:
+        return sys._getframe(depth + 1).f_globals.get('__name__', default)
+    except (AttributeError, ValueError):  # For platforms without _getframe()
+        pass
+    return None
+
+
+# Placeholder for sentinel methods, because sentinels can not have their own sentinels
+_sentinel_placeholder = object()
+
+if hasattr(builtins, "sentinel"):  # 3.15+
+    sentinel = builtins.sentinel
+else:
+    class sentinel:
+        """Create a unique sentinel object.
+
+        *name* should be the name of the variable to which the return value
+        shall be assigned.
+        """
+
+        def __init__(
+            self,
+            __name: str = _sentinel_placeholder,
+            __repr: typing.Optional[str] = _sentinel_placeholder,
+            /,
+            *,
+            repr: typing.Optional[str] = None,
+            name: str = _sentinel_placeholder,
+        ) -> None:
+            if name is not _sentinel_placeholder:
+                warnings.warn(
+                    "Passing 'name' as a keyword argument is deprecated; "
+                    "pass it positionally instead.",
+                    DeprecationWarning,
+                    stacklevel=2,
+                )
+                __name = name
+            if __name is _sentinel_placeholder:
+                raise TypeError("First parameter 'name' is required")
+            if __repr is not _sentinel_placeholder:
+                warnings.warn(
+                    "Passing 'repr' as a positional argument is deprecated; "
+                    "pass it by keyword instead.",
+                    DeprecationWarning,
+                    stacklevel=2,
+                )
+                repr = __repr
+
+            self._name = __name
+            self._repr = repr if repr is not None else __name
+
+            # For pickling as a singleton:
+            self.__module__ = _caller()
+
+        def __init_subclass__(cls):
+            warnings.warn(
+                "Subclassing sentinel is deprecated "
+                "and will be disallowed in Python 3.15",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+            super().__init_subclass__()
+
+        def __setattr__(self, attr: str, value: object) -> None:
+            if attr not in {"_name", "_repr", "__module__"}:
+                warnings.warn(
+                    f"Setting attribute {attr!r} on sentinel objects is deprecated "
+                    "and will be disallowed in Python 3.15.",
+                    DeprecationWarning,
+                    stacklevel=2,
+                )
+            super().__setattr__(attr, value)
+
+        @property
+        def __name__(self) -> str:
+            return self._name
+
+        @__name__.setter
+        def __name__(self, value: str) -> None:
+            self._name = value
+
+        def __repr__(self) -> str:
+            return self._repr
+
+        if sys.version_info < (3, 11):
+            # The presence of this method convinces typing._type_check
+            # that Sentinels are types.
+            def __call__(self, *args, **kwargs):
+                raise TypeError(f"{type(self).__name__!r} object is not callable")
+
+        # Breakpoint: https://github.com/python/cpython/pull/21515
+        if sys.version_info >= (3, 10):
+            def __or__(self, other):
+                return typing.Union[self, other]
+
+            def __ror__(self, other):
+                return typing.Union[other, self]
+
+        def __reduce__(self) -> str:
+            """Reduce this sentinel to a singleton."""
+            return self.__name__  # Module is taken from the __module__ attribute
+
+Sentinel = sentinel
+
+_marker = sentinel("sentinel")
+
+
+# The functions below are modified copies of typing internal helpers.
+# They are needed by _ProtocolMeta and they provide support for PEP 646.
+
+# Breakpoint: https://github.com/python/cpython/pull/27342
+if sys.version_info >= (3, 10):
+    def _should_collect_from_parameters(t):
+        return isinstance(
+            t, (typing._GenericAlias, _types.GenericAlias, _types.UnionType)
+        )
+else:
+    def _should_collect_from_parameters(t):
+        return isinstance(t, (typing._GenericAlias, _types.GenericAlias))
+
+
+NoReturn = typing.NoReturn
+
+# Some unconstrained type variables.  These are used by the container types.
+# (These are not for export.)
+T = typing.TypeVar('T')  # Any type.
+KT = typing.TypeVar('KT')  # Key type.
+VT = typing.TypeVar('VT')  # Value type.
+T_co = typing.TypeVar('T_co', covariant=True)  # Any type covariant containers.
+T_contra = typing.TypeVar('T_contra', contravariant=True)  # Ditto contravariant.
+
+
+# Breakpoint: https://github.com/python/cpython/pull/31841
+if sys.version_info >= (3, 11):
+    from typing import Any
+else:
+
+    class _AnyMeta(type):
+        def __instancecheck__(self, obj):
+            if self is Any:
+                raise TypeError("typing_extensions.Any cannot be used with isinstance()")
+            return super().__instancecheck__(obj)
+
+        def __repr__(self):
+            if self is Any:
+                return "typing_extensions.Any"
+            return super().__repr__()
+
+    class Any(metaclass=_AnyMeta):
+        """Special type indicating an unconstrained type.
+        - Any is compatible with every type.
+        - Any assumed to have all methods.
+        - All values assumed to be instances of Any.
+        Note that all the above statements are true from the point of view of
+        static type checkers. At runtime, Any should not be used with instance
+        checks.
+        """
+        def __new__(cls, *args, **kwargs):
+            if cls is Any:
+                raise TypeError("Any cannot be instantiated")
+            return super().__new__(cls, *args, **kwargs)
+
+
+ClassVar = typing.ClassVar
+
+# Vendored from cpython typing._SpecialFrom
+# Having a separate class means that instances will not be rejected by
+# typing._type_check.
+class _SpecialForm(typing._Final, _root=True):
+    __slots__ = ('_name', '__doc__', '_getitem')
+
+    def __init__(self, getitem):
+        self._getitem = getitem
+        self._name = getitem.__name__
+        self.__doc__ = getitem.__doc__
+
+    def __getattr__(self, item):
+        if item in {'__name__', '__qualname__'}:
+            return self._name
+
+        raise AttributeError(item)
+
+    def __mro_entries__(self, bases):
+        raise TypeError(f"Cannot subclass {self!r}")
+
+    def __repr__(self):
+        return f'typing_extensions.{self._name}'
+
+    def __reduce__(self):
+        return self._name
+
+    def __call__(self, *args, **kwds):
+        raise TypeError(f"Cannot instantiate {self!r}")
+
+    def __or__(self, other):
+        return typing.Union[self, other]
+
+    def __ror__(self, other):
+        return typing.Union[other, self]
+
+    def __instancecheck__(self, obj):
+        raise TypeError(f"{self} cannot be used with isinstance()")
+
+    def __subclasscheck__(self, cls):
+        raise TypeError(f"{self} cannot be used with issubclass()")
+
+    @typing._tp_cache
+    def __getitem__(self, parameters):
+        return self._getitem(self, parameters)
+
+
+# Note that inheriting from this class means that the object will be
+# rejected by typing._type_check, so do not use it if the special form
+# is arguably valid as a type by itself.
+class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
+    def __repr__(self):
+        return 'typing_extensions.' + self._name
+
+
+Final = typing.Final
+
+# Breakpoint: https://github.com/python/cpython/pull/30530
+if sys.version_info >= (3, 11):
+    final = typing.final
+else:
+    # @final exists in 3.8+, but we backport it for all versions
+    # before 3.11 to keep support for the __final__ attribute.
+    # See https://bugs.python.org/issue46342
+    def final(f):
+        """This decorator can be used to indicate to type checkers that
+        the decorated method cannot be overridden, and decorated class
+        cannot be subclassed. For example:
+
+            class Base:
+                @final
+                def done(self) -> None:
+                    ...
+            class Sub(Base):
+                def done(self) -> None:  # Error reported by type checker
+                    ...
+            @final
+            class Leaf:
+                ...
+            class Other(Leaf):  # Error reported by type checker
+                ...
+
+        There is no runtime checking of these properties. The decorator
+        sets the ``__final__`` attribute to ``True`` on the decorated object
+        to allow runtime introspection.
+        """
+        try:
+            f.__final__ = True
+        except (AttributeError, TypeError):
+            # Skip the attribute silently if it is not writable.
+            # AttributeError happens if the object has __slots__ or a
+            # read-only property, TypeError if it's a builtin class.
+            pass
+        return f
+
+
+if hasattr(typing, "disjoint_base"):  # 3.15
+    disjoint_base = typing.disjoint_base
+else:
+    def disjoint_base(cls):
+        """This decorator marks a class as a disjoint base.
+
+        Child classes of a disjoint base cannot inherit from other disjoint bases that are
+        not parent classes of the disjoint base.
+
+        For example:
+
+            @disjoint_base
+            class Disjoint1: pass
+
+            @disjoint_base
+            class Disjoint2: pass
+
+            class Disjoint3(Disjoint1, Disjoint2): pass  # Type checker error
+
+        Type checkers can use knowledge of disjoint bases to detect unreachable code
+        and determine when two types can overlap.
+
+        See PEP 800."""
+        cls.__disjoint_base__ = True
+        return cls
+
+
+def IntVar(name):
+    return typing.TypeVar(name)
+
+
+# A Literal bug was fixed in 3.11.0, 3.10.1 and 3.9.8
+# Breakpoint: https://github.com/python/cpython/pull/29334
+if sys.version_info >= (3, 10, 1):
+    Literal = typing.Literal
+else:
+    def _flatten_literal_params(parameters):
+        """An internal helper for Literal creation: flatten Literals among parameters"""
+        params = []
+        for p in parameters:
+            if isinstance(p, _LiteralGenericAlias):
+                params.extend(p.__args__)
+            else:
+                params.append(p)
+        return tuple(params)
+
+    def _value_and_type_iter(params):
+        for p in params:
+            yield p, type(p)
+
+    class _LiteralGenericAlias(typing._GenericAlias, _root=True):
+        def __eq__(self, other):
+            if not isinstance(other, _LiteralGenericAlias):
+                return NotImplemented
+            these_args_deduped = set(_value_and_type_iter(self.__args__))
+            other_args_deduped = set(_value_and_type_iter(other.__args__))
+            return these_args_deduped == other_args_deduped
+
+        def __hash__(self):
+            return hash(frozenset(_value_and_type_iter(self.__args__)))
+
+    class _LiteralForm(_ExtensionsSpecialForm, _root=True):
+        def __init__(self, doc: str):
+            self._name = 'Literal'
+            self._doc = self.__doc__ = doc
+
+        def __getitem__(self, parameters):
+            if not isinstance(parameters, tuple):
+                parameters = (parameters,)
+
+            parameters = _flatten_literal_params(parameters)
+
+            val_type_pairs = list(_value_and_type_iter(parameters))
+            try:
+                deduped_pairs = set(val_type_pairs)
+            except TypeError:
+                # unhashable parameters
+                pass
+            else:
+                # similar logic to typing._deduplicate on Python 3.9+
+                if len(deduped_pairs) < len(val_type_pairs):
+                    new_parameters = []
+                    for pair in val_type_pairs:
+                        if pair in deduped_pairs:
+                            new_parameters.append(pair[0])
+                            deduped_pairs.remove(pair)
+                    assert not deduped_pairs, deduped_pairs
+                    parameters = tuple(new_parameters)
+
+            return _LiteralGenericAlias(self, parameters)
+
+    Literal = _LiteralForm(doc="""\
+                           A type that can be used to indicate to type checkers
+                           that the corresponding value has a value literally equivalent
+                           to the provided parameter. For example:
+
+                               var: Literal[4] = 4
+
+                           The type checker understands that 'var' is literally equal to
+                           the value 4 and no other value.
+
+                           Literal[...] cannot be subclassed. There is no runtime
+                           checking verifying that the parameter is actually a value
+                           instead of a type.""")
+
+
+_overload_dummy = typing._overload_dummy
+
+
+if hasattr(typing, "get_overloads"):  # 3.11+
+    overload = typing.overload
+    get_overloads = typing.get_overloads
+    clear_overloads = typing.clear_overloads
+else:
+    # {module: {qualname: {firstlineno: func}}}
+    _overload_registry = collections.defaultdict(
+        functools.partial(collections.defaultdict, dict)
+    )
+
+    def overload(func):
+        """Decorator for overloaded functions/methods.
+
+        In a stub file, place two or more stub definitions for the same
+        function in a row, each decorated with @overload.  For example:
+
+        @overload
+        def utf8(value: None) -> None: ...
+        @overload
+        def utf8(value: bytes) -> bytes: ...
+        @overload
+        def utf8(value: str) -> bytes: ...
+
+        In a non-stub file (i.e. a regular .py file), do the same but
+        follow it with an implementation.  The implementation should *not*
+        be decorated with @overload.  For example:
+
+        @overload
+        def utf8(value: None) -> None: ...
+        @overload
+        def utf8(value: bytes) -> bytes: ...
+        @overload
+        def utf8(value: str) -> bytes: ...
+        def utf8(value):
+            # implementation goes here
+
+        The overloads for a function can be retrieved at runtime using the
+        get_overloads() function.
+        """
+        # classmethod and staticmethod
+        f = getattr(func, "__func__", func)
+        try:
+            _overload_registry[f.__module__][f.__qualname__][
+                f.__code__.co_firstlineno
+            ] = func
+        except AttributeError:
+            # Not a normal function; ignore.
+            pass
+        return _overload_dummy
+
+    def get_overloads(func):
+        """Return all defined overloads for *func* as a sequence."""
+        # classmethod and staticmethod
+        f = getattr(func, "__func__", func)
+        if f.__module__ not in _overload_registry:
+            return []
+        mod_dict = _overload_registry[f.__module__]
+        if f.__qualname__ not in mod_dict:
+            return []
+        return list(mod_dict[f.__qualname__].values())
+
+    def clear_overloads():
+        """Clear all overloads in the registry."""
+        _overload_registry.clear()
+
+
+# This is not a real generic class.  Don't use outside annotations.
+Type = typing.Type
+
+# Various ABCs mimicking those in collections.abc.
+# A few are simply re-exported for completeness.
+Awaitable = typing.Awaitable
+Coroutine = typing.Coroutine
+AsyncIterable = typing.AsyncIterable
+AsyncIterator = typing.AsyncIterator
+Deque = typing.Deque
+DefaultDict = typing.DefaultDict
+OrderedDict = typing.OrderedDict
+Counter = typing.Counter
+ChainMap = typing.ChainMap
+Text = typing.Text
+TYPE_CHECKING = typing.TYPE_CHECKING
+
+
+# Breakpoint: https://github.com/python/cpython/pull/118681
+if sys.version_info >= (3, 13, 0, "beta"):
+    from typing import AsyncContextManager, AsyncGenerator, ContextManager, Generator
+else:
+    def _is_dunder(attr):
+        return attr.startswith('__') and attr.endswith('__')
+
+
+    class _SpecialGenericAlias(typing._SpecialGenericAlias, _root=True):
+        def __init__(self, origin, nparams, *, defaults, inst=True, name=None):
+            assert nparams > 0, "`nparams` must be a positive integer"
+            assert defaults, "Must always specify a non-empty sequence for `defaults`"
+            super().__init__(origin, nparams, inst=inst, name=name)
+            self._defaults = defaults
+
+        def __setattr__(self, attr, val):
+            allowed_attrs = {'_name', '_inst', '_nparams', '_defaults'}
+            if _is_dunder(attr) or attr in allowed_attrs:
+                object.__setattr__(self, attr, val)
+            else:
+                setattr(self.__origin__, attr, val)
+
+        @typing._tp_cache
+        def __getitem__(self, params):
+            if not isinstance(params, tuple):
+                params = (params,)
+            msg = "Parameters to generic types must be types."
+            params = tuple(typing._type_check(p, msg) for p in params)
+            if (
+                len(params) < self._nparams
+                and len(params) + len(self._defaults) >= self._nparams
+            ):
+                params = (*params, *self._defaults[len(params) - self._nparams:])
+            actual_len = len(params)
+
+            if actual_len != self._nparams:
+                expected = f"at least {self._nparams - len(self._defaults)}"
+                raise TypeError(
+                    f"Too {'many' if actual_len > self._nparams else 'few'}"
+                    f" arguments for {self};"
+                    f" actual {actual_len}, expected {expected}"
+                )
+            return self.copy_with(params)
+
+    _NoneType = type(None)
+    Generator = _SpecialGenericAlias(
+        collections.abc.Generator, 3, defaults=(_NoneType, _NoneType)
+    )
+    AsyncGenerator = _SpecialGenericAlias(
+        collections.abc.AsyncGenerator, 2, defaults=(_NoneType,)
+    )
+    ContextManager = _SpecialGenericAlias(
+        contextlib.AbstractContextManager,
+        2,
+        name="ContextManager",
+        defaults=(typing.Optional[bool],)
+    )
+    AsyncContextManager = _SpecialGenericAlias(
+        contextlib.AbstractAsyncContextManager,
+        2,
+        name="AsyncContextManager",
+        defaults=(typing.Optional[bool],)
+    )
+
+
+_PROTO_ALLOWLIST = {
+    'collections.abc': [
+        'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable',
+        'AsyncIterator', 'Hashable', 'Sized', 'Container', 'Collection',
+        'Reversible', 'Buffer',
+    ],
+    'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'],
+    'io': ['Reader', 'Writer'],
+    'typing_extensions': ['Buffer'],
+    'os': ['PathLike'],
+}
+
+
+_EXCLUDED_ATTRS = frozenset(typing.EXCLUDED_ATTRIBUTES) | {
+    "__match_args__", "__protocol_attrs__", "__non_callable_proto_members__",
+    "__final__",
+}
+
+
+def _get_protocol_attrs(cls):
+    attrs = set()
+    for base in cls.__mro__[:-1]:  # without object
+        if base.__name__ in {'Protocol', 'Generic'}:
+            continue
+        annotations = getattr(base, '__annotations__', {})
+        for attr in (*base.__dict__, *annotations):
+            if (not attr.startswith('_abc_') and attr not in _EXCLUDED_ATTRS):
+                attrs.add(attr)
+    return attrs
+
+
+# `__match_args__` attribute was removed from protocol members in 3.13,
+# we want to backport this change to older Python versions.
+# 3.14 additionally added `io.Reader`, `io.Writer` and `os.PathLike` to
+# the list of allowed protocol allowlist.
+# https://github.com/python/cpython/issues/127647
+if sys.version_info >= (3, 14):
+    Protocol = typing.Protocol
+else:
+    def _allow_reckless_class_checks(depth=2):
+        """Allow instance and class checks for special stdlib modules.
+        The abc and functools modules indiscriminately call isinstance() and
+        issubclass() on the whole MRO of a user class, which may contain protocols.
+        """
+        return _caller(depth) in {'abc', 'functools', None}
+
+    def _no_init(self, *args, **kwargs):
+        if type(self)._is_protocol:
+            raise TypeError('Protocols cannot be instantiated')
+
+    def _type_check_issubclass_arg_1(arg):
+        """Raise TypeError if `arg` is not an instance of `type`
+        in `issubclass(arg, )`.
+
+        In most cases, this is verified by type.__subclasscheck__.
+        Checking it again unnecessarily would slow down issubclass() checks,
+        so, we don't perform this check unless we absolutely have to.
+
+        For various error paths, however,
+        we want to ensure that *this* error message is shown to the user
+        where relevant, rather than a typing.py-specific error message.
+        """
+        if not isinstance(arg, type):
+            # Same error message as for issubclass(1, int).
+            raise TypeError('issubclass() arg 1 must be a class')
+
+    # Inheriting from typing._ProtocolMeta isn't actually desirable,
+    # but is necessary to allow typing.Protocol and typing_extensions.Protocol
+    # to mix without getting TypeErrors about "metaclass conflict"
+    class _ProtocolMeta(type(typing.Protocol)):
+        # This metaclass is somewhat unfortunate,
+        # but is necessary for several reasons...
+        #
+        # NOTE: DO NOT call super() in any methods in this class
+        # That would call the methods on typing._ProtocolMeta on Python <=3.11
+        # and those are slow
+        def __new__(mcls, name, bases, namespace, **kwargs):
+            if name == "Protocol" and len(bases) < 2:
+                pass
+            elif {Protocol, typing.Protocol} & set(bases):
+                for base in bases:
+                    if not (
+                        base in {object, typing.Generic, Protocol, typing.Protocol}
+                        or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, [])
+                        or is_protocol(base)
+                    ):
+                        raise TypeError(
+                            f"Protocols can only inherit from other protocols, "
+                            f"got {base!r}"
+                        )
+            return abc.ABCMeta.__new__(mcls, name, bases, namespace, **kwargs)
+
+        def __init__(cls, *args, **kwargs):
+            abc.ABCMeta.__init__(cls, *args, **kwargs)
+            if getattr(cls, "_is_protocol", False):
+                cls.__protocol_attrs__ = _get_protocol_attrs(cls)
+
+        def __subclasscheck__(cls, other):
+            if cls is Protocol:
+                return type.__subclasscheck__(cls, other)
+            if (
+                getattr(cls, '_is_protocol', False)
+                and not _allow_reckless_class_checks()
+            ):
+                if not getattr(cls, '_is_runtime_protocol', False):
+                    _type_check_issubclass_arg_1(other)
+                    raise TypeError(
+                        "Instance and class checks can only be used with "
+                        "@runtime_checkable protocols"
+                    )
+                if (
+                    # this attribute is set by @runtime_checkable:
+                    cls.__non_callable_proto_members__
+                    and cls.__dict__.get("__subclasshook__") is _proto_hook
+                ):
+                    _type_check_issubclass_arg_1(other)
+                    non_method_attrs = sorted(cls.__non_callable_proto_members__)
+                    raise TypeError(
+                        "Protocols with non-method members don't support issubclass()."
+                        f" Non-method members: {str(non_method_attrs)[1:-1]}."
+                    )
+            return abc.ABCMeta.__subclasscheck__(cls, other)
+
+        def __instancecheck__(cls, instance):
+            # We need this method for situations where attributes are
+            # assigned in __init__.
+            if cls is Protocol:
+                return type.__instancecheck__(cls, instance)
+            if not getattr(cls, "_is_protocol", False):
+                # i.e., it's a concrete subclass of a protocol
+                return abc.ABCMeta.__instancecheck__(cls, instance)
+
+            if (
+                not getattr(cls, '_is_runtime_protocol', False) and
+                not _allow_reckless_class_checks()
+            ):
+                raise TypeError("Instance and class checks can only be used with"
+                                " @runtime_checkable protocols")
+
+            if abc.ABCMeta.__instancecheck__(cls, instance):
+                return True
+
+            for attr in cls.__protocol_attrs__:
+                try:
+                    val = inspect.getattr_static(instance, attr)
+                except AttributeError:
+                    break
+                # this attribute is set by @runtime_checkable:
+                if val is None and attr not in cls.__non_callable_proto_members__:
+                    break
+            else:
+                return True
+
+            return False
+
+        def __eq__(cls, other):
+            # Hack so that typing.Generic.__class_getitem__
+            # treats typing_extensions.Protocol
+            # as equivalent to typing.Protocol
+            if abc.ABCMeta.__eq__(cls, other) is True:
+                return True
+            return cls is Protocol and other is typing.Protocol
+
+        # This has to be defined, or the abc-module cache
+        # complains about classes with this metaclass being unhashable,
+        # if we define only __eq__!
+        def __hash__(cls) -> int:
+            return type.__hash__(cls)
+
+    @classmethod
+    def _proto_hook(cls, other):
+        if not cls.__dict__.get('_is_protocol', False):
+            return NotImplemented
+
+        for attr in cls.__protocol_attrs__:
+            for base in other.__mro__:
+                # Check if the members appears in the class dictionary...
+                if attr in base.__dict__:
+                    if base.__dict__[attr] is None:
+                        return NotImplemented
+                    break
+
+                # ...or in annotations, if it is a sub-protocol.
+                annotations = getattr(base, '__annotations__', {})
+                if (
+                    isinstance(annotations, collections.abc.Mapping)
+                    and attr in annotations
+                    and is_protocol(other)
+                ):
+                    break
+            else:
+                return NotImplemented
+        return True
+
+    class Protocol(typing.Generic, metaclass=_ProtocolMeta):
+        __doc__ = typing.Protocol.__doc__
+        __slots__ = ()
+        _is_protocol = True
+        _is_runtime_protocol = False
+
+        def __init_subclass__(cls, *args, **kwargs):
+            super().__init_subclass__(*args, **kwargs)
+
+            # Determine if this is a protocol or a concrete subclass.
+            if not cls.__dict__.get('_is_protocol', False):
+                cls._is_protocol = any(b is Protocol for b in cls.__bases__)
+
+            # Set (or override) the protocol subclass hook.
+            if '__subclasshook__' not in cls.__dict__:
+                cls.__subclasshook__ = _proto_hook
+
+            # Prohibit instantiation for protocol classes
+            if cls._is_protocol and cls.__init__ is Protocol.__init__:
+                cls.__init__ = _no_init
+
+
+# Breakpoint: https://github.com/python/cpython/pull/113401
+if sys.version_info >= (3, 13):
+    runtime_checkable = typing.runtime_checkable
+else:
+    def runtime_checkable(cls):
+        """Mark a protocol class as a runtime protocol.
+
+        Such protocol can be used with isinstance() and issubclass().
+        Raise TypeError if applied to a non-protocol class.
+        This allows a simple-minded structural check very similar to
+        one trick ponies in collections.abc such as Iterable.
+
+        For example::
+
+            @runtime_checkable
+            class Closable(Protocol):
+                def close(self): ...
+
+            assert isinstance(open('/some/file'), Closable)
+
+        Warning: this will check only the presence of the required methods,
+        not their type signatures!
+        """
+        if not issubclass(cls, typing.Generic) or not getattr(cls, '_is_protocol', False):
+            raise TypeError(f'@runtime_checkable can be only applied to protocol classes,'
+                            f' got {cls!r}')
+        cls._is_runtime_protocol = True
+
+        # typing.Protocol classes on <=3.11 break if we execute this block,
+        # because typing.Protocol classes on <=3.11 don't have a
+        # `__protocol_attrs__` attribute, and this block relies on the
+        # `__protocol_attrs__` attribute. Meanwhile, typing.Protocol classes on 3.12.2+
+        # break if we *don't* execute this block, because *they* assume that all
+        # protocol classes have a `__non_callable_proto_members__` attribute
+        # (which this block sets)
+        if isinstance(cls, _ProtocolMeta) or sys.version_info >= (3, 12, 2):
+            # PEP 544 prohibits using issubclass()
+            # with protocols that have non-method members.
+            # See gh-113320 for why we compute this attribute here,
+            # rather than in `_ProtocolMeta.__init__`
+            cls.__non_callable_proto_members__ = set()
+            for attr in cls.__protocol_attrs__:
+                try:
+                    is_callable = callable(getattr(cls, attr, None))
+                except Exception as e:
+                    raise TypeError(
+                        f"Failed to determine whether protocol member {attr!r} "
+                        "is a method member"
+                    ) from e
+                else:
+                    if not is_callable:
+                        cls.__non_callable_proto_members__.add(attr)
+
+        return cls
+
+
+# The "runtime" alias exists for backwards compatibility.
+runtime = runtime_checkable
+
+
+# Our version of runtime-checkable protocols is faster on Python <=3.11
+# Breakpoint: https://github.com/python/cpython/pull/112717
+if sys.version_info >= (3, 12):
+    SupportsInt = typing.SupportsInt
+    SupportsFloat = typing.SupportsFloat
+    SupportsComplex = typing.SupportsComplex
+    SupportsBytes = typing.SupportsBytes
+    SupportsIndex = typing.SupportsIndex
+    SupportsAbs = typing.SupportsAbs
+    SupportsRound = typing.SupportsRound
+else:
+    @runtime_checkable
+    class SupportsInt(Protocol):
+        """An ABC with one abstract method __int__."""
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __int__(self) -> int:
+            pass
+
+    @runtime_checkable
+    class SupportsFloat(Protocol):
+        """An ABC with one abstract method __float__."""
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __float__(self) -> float:
+            pass
+
+    @runtime_checkable
+    class SupportsComplex(Protocol):
+        """An ABC with one abstract method __complex__."""
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __complex__(self) -> complex:
+            pass
+
+    @runtime_checkable
+    class SupportsBytes(Protocol):
+        """An ABC with one abstract method __bytes__."""
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __bytes__(self) -> bytes:
+            pass
+
+    @runtime_checkable
+    class SupportsIndex(Protocol):
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __index__(self) -> int:
+            pass
+
+    @runtime_checkable
+    class SupportsAbs(Protocol[T_co]):
+        """
+        An ABC with one abstract method __abs__ that is covariant in its return type.
+        """
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __abs__(self) -> T_co:
+            pass
+
+    @runtime_checkable
+    class SupportsRound(Protocol[T_co]):
+        """
+        An ABC with one abstract method __round__ that is covariant in its return type.
+        """
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def __round__(self, ndigits: int = 0) -> T_co:
+            pass
+
+
+if hasattr(io, "Reader") and hasattr(io, "Writer"):
+    Reader = io.Reader
+    Writer = io.Writer
+else:
+    @runtime_checkable
+    class Reader(Protocol[T_co]):
+        """Protocol for simple I/O reader instances.
+
+        This protocol only supports blocking I/O.
+        """
+
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def read(self, size: int = ..., /) -> T_co:
+            """Read data from the input stream and return it.
+
+            If *size* is specified, at most *size* items (bytes/characters) will be
+            read.
+            """
+
+    @runtime_checkable
+    class Writer(Protocol[T_contra]):
+        """Protocol for simple I/O writer instances.
+
+        This protocol only supports blocking I/O.
+        """
+
+        __slots__ = ()
+
+        @abc.abstractmethod
+        def write(self, data: T_contra, /) -> int:
+            """Write *data* to the output stream and return the number of items written."""  # noqa: E501
+
+
+_NEEDS_SINGLETONMETA = (
+    not hasattr(typing, "NoDefault") or not hasattr(typing, "NoExtraItems")
+)
+
+if _NEEDS_SINGLETONMETA:
+    class SingletonMeta(type):
+        def __setattr__(cls, attr, value):
+            # TypeError is consistent with the behavior of NoneType
+            raise TypeError(
+                f"cannot set {attr!r} attribute of immutable type {cls.__name__!r}"
+            )
+
+
+if hasattr(typing, "NoDefault"):
+    NoDefault = typing.NoDefault
+else:
+    class NoDefaultType(metaclass=SingletonMeta):
+        """The type of the NoDefault singleton."""
+
+        __slots__ = ()
+
+        def __new__(cls):
+            return globals().get("NoDefault") or object.__new__(cls)
+
+        def __repr__(self):
+            return "typing_extensions.NoDefault"
+
+        def __reduce__(self):
+            return "NoDefault"
+
+    NoDefault = NoDefaultType()
+    del NoDefaultType
+
+if hasattr(typing, "NoExtraItems"):
+    NoExtraItems = typing.NoExtraItems
+else:
+    class NoExtraItemsType(metaclass=SingletonMeta):
+        """The type of the NoExtraItems singleton."""
+
+        __slots__ = ()
+
+        def __new__(cls):
+            return globals().get("NoExtraItems") or object.__new__(cls)
+
+        def __repr__(self):
+            return "typing_extensions.NoExtraItems"
+
+        def __reduce__(self):
+            return "NoExtraItems"
+
+    NoExtraItems = NoExtraItemsType()
+    del NoExtraItemsType
+
+if _NEEDS_SINGLETONMETA:
+    del SingletonMeta
+
+
+# Update this to something like >=3.13.0b1 if and when
+# PEP 764 is implemented in CPython
+_PEP_764_IMPLEMENTED = False
+
+if _PEP_764_IMPLEMENTED:
+    # The standard library TypedDict in Python 3.9.0/1 does not honour the "total"
+    # keyword with old-style TypedDict().  See https://bugs.python.org/issue42059
+    # The standard library TypedDict below Python 3.11 does not store runtime
+    # information about optional and required keys when using Required or NotRequired.
+    # Generic TypedDicts are also impossible using typing.TypedDict on Python <3.11.
+    # Aaaand on 3.12 we add __orig_bases__ to TypedDict
+    # to enable better runtime introspection.
+    # On 3.13 we deprecate some odd ways of creating TypedDicts.
+    # Also on 3.13, PEP 705 adds the ReadOnly[] qualifier.
+    # PEP 728 (Python 3.15+) adds the `extra_items` and `closed` keywords.
+    # PEP 764 (still pending) allows the `TypedDict` special form to be subscripted.
+    TypedDict = typing.TypedDict
+    _TypedDictMeta = typing._TypedDictMeta
+    is_typeddict = typing.is_typeddict
+else:
+    # 3.10.0 and later
+    _TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters
+
+    def _get_typeddict_qualifiers(annotation_type):
+        while True:
+            annotation_origin = get_origin(annotation_type)
+            if annotation_origin is Annotated:
+                annotation_args = get_args(annotation_type)
+                if annotation_args:
+                    annotation_type = annotation_args[0]
+                else:
+                    break
+            elif annotation_origin is Required:
+                yield Required
+                annotation_type, = get_args(annotation_type)
+            elif annotation_origin is NotRequired:
+                yield NotRequired
+                annotation_type, = get_args(annotation_type)
+            elif annotation_origin is ReadOnly:
+                yield ReadOnly
+                annotation_type, = get_args(annotation_type)
+            else:
+                break
+
+    class _TypedDictMeta(type):
+
+        def __new__(cls, name, bases, ns, *, total=True, closed=None,
+                    extra_items=NoExtraItems):
+            """Create new typed dict class object.
+
+            This method is called when TypedDict is subclassed,
+            or when TypedDict is instantiated. This way
+            TypedDict supports all three syntax forms described in its docstring.
+            Subclasses and instances of TypedDict return actual dictionaries.
+            """
+            for base in bases:
+                if type(base) is not _TypedDictMeta and base is not typing.Generic:
+                    raise TypeError('cannot inherit from both a TypedDict type '
+                                    'and a non-TypedDict base class')
+            if closed is not None and extra_items is not NoExtraItems:
+                raise TypeError(f"Cannot combine closed={closed!r} and extra_items")
+
+            if any(issubclass(b, typing.Generic) for b in bases):
+                generic_base = (typing.Generic,)
+            else:
+                generic_base = ()
+
+            ns_annotations = ns.pop('__annotations__', None)
+
+            # typing.py generally doesn't let you inherit from plain Generic, unless
+            # the name of the class happens to be "Protocol"
+            tp_dict = type.__new__(_TypedDictMeta, "Protocol", (*generic_base, dict), ns)
+            tp_dict.__name__ = name
+            if tp_dict.__qualname__ == "Protocol":
+                tp_dict.__qualname__ = name
+
+            if not hasattr(tp_dict, '__orig_bases__'):
+                tp_dict.__orig_bases__ = bases
+
+            annotations = {}
+            own_annotate = None
+            if ns_annotations is not None:
+                own_annotations = ns_annotations
+            elif sys.version_info >= (3, 14):
+                if hasattr(annotationlib, "get_annotate_from_class_namespace"):
+                    own_annotate = annotationlib.get_annotate_from_class_namespace(ns)
+                else:
+                    # 3.14.0a7 and earlier
+                    own_annotate = ns.get("__annotate__")
+                if own_annotate is not None:
+                    own_annotations = annotationlib.call_annotate_function(
+                        own_annotate, Format.FORWARDREF, owner=tp_dict
+                    )
+                else:
+                    own_annotations = {}
+            else:
+                own_annotations = {}
+            msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
+            if _TAKES_MODULE:
+                own_checked_annotations = {
+                    n: typing._type_check(tp, msg, module=tp_dict.__module__)
+                    for n, tp in own_annotations.items()
+                }
+            else:
+                own_checked_annotations = {
+                    n: typing._type_check(tp, msg)
+                    for n, tp in own_annotations.items()
+                }
+            required_keys = set()
+            optional_keys = set()
+            readonly_keys = set()
+            mutable_keys = set()
+            extra_items_type = extra_items
+
+            for base in bases:
+                base_dict = base.__dict__
+
+                if sys.version_info <= (3, 14):
+                    annotations.update(base_dict.get('__annotations__', {}))
+                base_required = base_dict.get('__required_keys__', set())
+                required_keys |= base_required
+                optional_keys -= base_required
+
+                base_optional = base_dict.get('__optional_keys__', set())
+                required_keys -= base_optional
+                optional_keys |= base_optional
+
+                readonly_keys.update(base_dict.get('__readonly_keys__', ()))
+                mutable_keys.update(base_dict.get('__mutable_keys__', ()))
+
+            # This was specified in an earlier version of PEP 728. Support
+            # is retained for backwards compatibility, but only for Python
+            # 3.13 and lower.
+            if (closed and sys.version_info < (3, 14)
+                       and "__extra_items__" in own_checked_annotations):
+                annotation_type = own_checked_annotations.pop("__extra_items__")
+                qualifiers = set(_get_typeddict_qualifiers(annotation_type))
+                if Required in qualifiers:
+                    raise TypeError(
+                        "Special key __extra_items__ does not support "
+                        "Required"
+                    )
+                if NotRequired in qualifiers:
+                    raise TypeError(
+                        "Special key __extra_items__ does not support "
+                        "NotRequired"
+                    )
+                extra_items_type = annotation_type
+
+            annotations.update(own_checked_annotations)
+            for annotation_key, annotation_type in own_checked_annotations.items():
+                qualifiers = set(_get_typeddict_qualifiers(annotation_type))
+
+                if Required in qualifiers:
+                    is_required = True
+                elif NotRequired in qualifiers:
+                    is_required = False
+                else:
+                    is_required = total
+
+                if is_required:
+                    required_keys.add(annotation_key)
+                    optional_keys.discard(annotation_key)
+                else:
+                    optional_keys.add(annotation_key)
+                    required_keys.discard(annotation_key)
+
+                if ReadOnly in qualifiers:
+                    mutable_keys.discard(annotation_key)
+                    readonly_keys.add(annotation_key)
+                else:
+                    mutable_keys.add(annotation_key)
+                    readonly_keys.discard(annotation_key)
+
+            # Breakpoint: https://github.com/python/cpython/pull/119891
+            if sys.version_info >= (3, 14):
+                def __annotate__(format):
+                    annos = {}
+                    for base in bases:
+                        if base is Generic:
+                            continue
+                        base_annotate = base.__annotate__
+                        if base_annotate is None:
+                            continue
+                        base_annos = annotationlib.call_annotate_function(
+                            base_annotate, format, owner=base)
+                        annos.update(base_annos)
+                    if own_annotate is not None:
+                        own = annotationlib.call_annotate_function(
+                            own_annotate, format, owner=tp_dict)
+                        if format != Format.STRING:
+                            own = {
+                                n: typing._type_check(tp, msg, module=tp_dict.__module__)
+                                for n, tp in own.items()
+                            }
+                    elif format == Format.STRING:
+                        own = annotationlib.annotations_to_string(own_annotations)
+                    elif format in (Format.FORWARDREF, Format.VALUE):
+                        own = own_checked_annotations
+                    else:
+                        raise NotImplementedError(format)
+                    annos.update(own)
+                    return annos
+
+                tp_dict.__annotate__ = __annotate__
+            else:
+                tp_dict.__annotations__ = annotations
+            tp_dict.__required_keys__ = frozenset(required_keys)
+            tp_dict.__optional_keys__ = frozenset(optional_keys)
+            tp_dict.__readonly_keys__ = frozenset(readonly_keys)
+            tp_dict.__mutable_keys__ = frozenset(mutable_keys)
+            tp_dict.__total__ = total
+            tp_dict.__closed__ = closed
+            tp_dict.__extra_items__ = extra_items_type
+            return tp_dict
+
+        __call__ = dict  # static method
+
+        def __subclasscheck__(cls, other):
+            # Typed dicts are only for static structural subtyping.
+            raise TypeError('TypedDict does not support instance and class checks')
+
+        __instancecheck__ = __subclasscheck__
+
+    _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
+
+    def _create_typeddict(
+        typename,
+        fields,
+        /,
+        *,
+        typing_is_inline,
+        total,
+        closed,
+        extra_items,
+        **kwargs,
+    ):
+        if fields is _marker or fields is None:
+            if fields is _marker:
+                deprecated_thing = (
+                    "Failing to pass a value for the 'fields' parameter"
+                )
+            else:
+                deprecated_thing = "Passing `None` as the 'fields' parameter"
+
+            example = f"`{typename} = TypedDict({typename!r}, {{}})`"
+            deprecation_msg = (
+                f"{deprecated_thing} is deprecated and will be disallowed in "
+                "Python 3.15. To create a TypedDict class with 0 fields "
+                "using the functional syntax, pass an empty dictionary, e.g. "
+            ) + example + "."
+            warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2)
+            # Support a field called "closed"
+            if closed is not False and closed is not True and closed is not None:
+                kwargs["closed"] = closed
+                closed = None
+            # Or "extra_items"
+            if extra_items is not NoExtraItems:
+                kwargs["extra_items"] = extra_items
+                extra_items = NoExtraItems
+            fields = kwargs
+        elif kwargs:
+            raise TypeError("TypedDict takes either a dict or keyword arguments,"
+                            " but not both")
+        if kwargs:
+            # Breakpoint: https://github.com/python/cpython/pull/104891
+            if sys.version_info >= (3, 13):
+                raise TypeError("TypedDict takes no keyword arguments")
+            warnings.warn(
+                "The kwargs-based syntax for TypedDict definitions is deprecated "
+                "in Python 3.11, will be removed in Python 3.13, and may not be "
+                "understood by third-party type checkers.",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+
+        ns = {'__annotations__': dict(fields)}
+        module = _caller(depth=4 if typing_is_inline else 2)
+        if module is not None:
+            # Setting correct module is necessary to make typed dict classes
+            # pickleable.
+            ns['__module__'] = module
+
+        td = _TypedDictMeta(typename, (), ns, total=total, closed=closed,
+                            extra_items=extra_items)
+        td.__orig_bases__ = (TypedDict,)
+        return td
+
+    class _TypedDictSpecialForm(_SpecialForm, _root=True):
+        def __call__(
+            self,
+            typename,
+            fields=_marker,
+            /,
+            *,
+            total=True,
+            closed=None,
+            extra_items=NoExtraItems,
+            **kwargs
+        ):
+            return _create_typeddict(
+                typename,
+                fields,
+                typing_is_inline=False,
+                total=total,
+                closed=closed,
+                extra_items=extra_items,
+                **kwargs,
+            )
+
+        def __mro_entries__(self, bases):
+            return (_TypedDict,)
+
+    @_TypedDictSpecialForm
+    def TypedDict(self, args):
+        """A simple typed namespace. At runtime it is equivalent to a plain dict.
+
+        TypedDict creates a dictionary type such that a type checker will expect all
+        instances to have a certain set of keys, where each key is
+        associated with a value of a consistent type. This expectation
+        is not checked at runtime.
+
+        Usage::
+
+            class Point2D(TypedDict):
+                x: int
+                y: int
+                label: str
+
+            a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
+            b: Point2D = {'z': 3, 'label': 'bad'}           # Fails type check
+
+            assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
+
+        The type info can be accessed via the Point2D.__annotations__ dict, and
+        the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
+        TypedDict supports an additional equivalent form::
+
+            Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
+
+        By default, all keys must be present in a TypedDict. It is possible
+        to override this by specifying totality::
+
+            class Point2D(TypedDict, total=False):
+                x: int
+                y: int
+
+        This means that a Point2D TypedDict can have any of the keys omitted. A type
+        checker is only expected to support a literal False or True as the value of
+        the total argument. True is the default, and makes all items defined in the
+        class body be required.
+
+        The Required and NotRequired special forms can also be used to mark
+        individual keys as being required or not required::
+
+            class Point2D(TypedDict):
+                x: int  # the "x" key must always be present (Required is the default)
+                y: NotRequired[int]  # the "y" key can be omitted
+
+        See PEP 655 for more details on Required and NotRequired.
+        """
+        # This runs when creating inline TypedDicts:
+        if not isinstance(args, dict):
+            raise TypeError(
+                "TypedDict[...] should be used with a single dict argument"
+            )
+
+        return _create_typeddict(
+            "",
+            args,
+            typing_is_inline=True,
+            total=True,
+            closed=True,
+            extra_items=NoExtraItems,
+        )
+
+    _TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta)
+
+    def is_typeddict(tp):
+        """Check if an annotation is a TypedDict class
+
+        For example::
+            class Film(TypedDict):
+                title: str
+                year: int
+
+            is_typeddict(Film)  # => True
+            is_typeddict(Union[list, str])  # => False
+        """
+        return isinstance(tp, _TYPEDDICT_TYPES)
+
+
+if hasattr(typing, "assert_type"):
+    assert_type = typing.assert_type
+
+else:
+    def assert_type(val, typ, /):
+        """Assert (to the type checker) that the value is of the given type.
+
+        When the type checker encounters a call to assert_type(), it
+        emits an error if the value is not of the specified type::
+
+            def greet(name: str) -> None:
+                assert_type(name, str)  # ok
+                assert_type(name, int)  # type checker error
+
+        At runtime this returns the first argument unchanged and otherwise
+        does nothing.
+        """
+        return val
+
+
+if hasattr(typing, "ReadOnly"):  # 3.13+
+    get_type_hints = typing.get_type_hints
+else:  # <=3.13
+    # replaces _strip_annotations()
+    def _strip_extras(t):
+        """Strips Annotated, Required and NotRequired from a given type."""
+        if isinstance(t, typing._AnnotatedAlias):
+            return _strip_extras(t.__origin__)
+        if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired, ReadOnly):
+            return _strip_extras(t.__args__[0])
+        if isinstance(t, typing._GenericAlias):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return t.copy_with(stripped_args)
+        if hasattr(_types, "GenericAlias") and isinstance(t, _types.GenericAlias):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return _types.GenericAlias(t.__origin__, stripped_args)
+        if hasattr(_types, "UnionType") and isinstance(t, _types.UnionType):
+            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
+            if stripped_args == t.__args__:
+                return t
+            return functools.reduce(operator.or_, stripped_args)
+
+        return t
+
+    def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
+        """Return type hints for an object.
+
+        This is often the same as obj.__annotations__, but it handles
+        forward references encoded as string literals, adds Optional[t] if a
+        default value equal to None is set and recursively replaces all
+        'Annotated[T, ...]', 'Required[T]' or 'NotRequired[T]' with 'T'
+        (unless 'include_extras=True').
+
+        The argument may be a module, class, method, or function. The annotations
+        are returned as a dictionary. For classes, annotations include also
+        inherited members.
+
+        TypeError is raised if the argument is not of a type that can contain
+        annotations, and an empty dictionary is returned if no annotations are
+        present.
+
+        BEWARE -- the behavior of globalns and localns is counterintuitive
+        (unless you are familiar with how eval() and exec() work).  The
+        search order is locals first, then globals.
+
+        - If no dict arguments are passed, an attempt is made to use the
+          globals from obj (or the respective module's globals for classes),
+          and these are also used as the locals.  If the object does not appear
+          to have globals, an empty dictionary is used.
+
+        - If one dict argument is passed, it is used for both globals and
+          locals.
+
+        - If two dict arguments are passed, they specify globals and
+          locals, respectively.
+        """
+        hint = typing.get_type_hints(
+            obj, globalns=globalns, localns=localns, include_extras=True
+        )
+        # Breakpoint: https://github.com/python/cpython/pull/30304
+        if sys.version_info < (3, 11):
+            _clean_optional(obj, hint, globalns, localns)
+        if include_extras:
+            return hint
+        return {k: _strip_extras(t) for k, t in hint.items()}
+
+    _NoneType = type(None)
+
+    def _could_be_inserted_optional(t):
+        """detects Union[..., None] pattern"""
+        if not isinstance(t, typing._UnionGenericAlias):
+            return False
+        # Assume if last argument is not None they are user defined
+        if t.__args__[-1] is not _NoneType:
+            return False
+        return True
+
+    # < 3.11
+    def _clean_optional(obj, hints, globalns=None, localns=None):
+        # reverts injected Union[..., None] cases from typing.get_type_hints
+        # when a None default value is used.
+        # see https://github.com/python/typing_extensions/issues/310
+        if not hints or isinstance(obj, type):
+            return
+        defaults = typing._get_defaults(obj)  # avoid accessing __annotations___
+        if not defaults:
+            return
+        original_hints = obj.__annotations__
+        for name, value in hints.items():
+            # Not a Union[..., None] or replacement conditions not fullfilled
+            if (not _could_be_inserted_optional(value)
+                or name not in defaults
+                or defaults[name] is not None
+            ):
+                continue
+            original_value = original_hints[name]
+            # value=NoneType should have caused a skip above but check for safety
+            if original_value is None:
+                original_value = _NoneType
+            # Forward reference
+            if isinstance(original_value, str):
+                if globalns is None:
+                    if isinstance(obj, _types.ModuleType):
+                        globalns = obj.__dict__
+                    else:
+                        nsobj = obj
+                        # Find globalns for the unwrapped object.
+                        while hasattr(nsobj, '__wrapped__'):
+                            nsobj = nsobj.__wrapped__
+                        globalns = getattr(nsobj, '__globals__', {})
+                    if localns is None:
+                        localns = globalns
+                elif localns is None:
+                    localns = globalns
+
+                original_value = ForwardRef(
+                    original_value,
+                    is_argument=not isinstance(obj, _types.ModuleType)
+                )
+            original_evaluated = typing._eval_type(original_value, globalns, localns)
+            # Compare if values differ. Note that even if equal
+            # value might be cached by typing._tp_cache contrary to original_evaluated
+            if original_evaluated != value or (
+                # 3.10: ForwardRefs of UnionType might be turned into _UnionGenericAlias
+                hasattr(_types, "UnionType")
+                and isinstance(original_evaluated, _types.UnionType)
+                and not isinstance(value, _types.UnionType)
+            ):
+                hints[name] = original_evaluated
+
+# Python 3.9 has get_origin() and get_args() but those implementations don't support
+# ParamSpecArgs and ParamSpecKwargs, so only Python 3.10's versions will do.
+# Breakpoint: https://github.com/python/cpython/pull/25298
+if sys.version_info >= (3, 10):
+    get_origin = typing.get_origin
+    get_args = typing.get_args
+# 3.9
+else:
+    def get_origin(tp):
+        """Get the unsubscripted version of a type.
+
+        This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
+        and Annotated. Return None for unsupported types. Examples::
+
+            get_origin(Literal[42]) is Literal
+            get_origin(int) is None
+            get_origin(ClassVar[int]) is ClassVar
+            get_origin(Generic) is Generic
+            get_origin(Generic[T]) is Generic
+            get_origin(Union[T, int]) is Union
+            get_origin(List[Tuple[T, T]][int]) == list
+            get_origin(P.args) is P
+        """
+        if isinstance(tp, typing._AnnotatedAlias):
+            return Annotated
+        if isinstance(tp, (typing._BaseGenericAlias, _types.GenericAlias,
+                           ParamSpecArgs, ParamSpecKwargs)):
+            return tp.__origin__
+        if tp is typing.Generic:
+            return typing.Generic
+        return None
+
+    def get_args(tp):
+        """Get type arguments with all substitutions performed.
+
+        For unions, basic simplifications used by Union constructor are performed.
+        Examples::
+            get_args(Dict[str, int]) == (str, int)
+            get_args(int) == ()
+            get_args(Union[int, Union[T, int], str][int]) == (int, str)
+            get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
+            get_args(Callable[[], T][int]) == ([], int)
+        """
+        if isinstance(tp, typing._AnnotatedAlias):
+            return (tp.__origin__, *tp.__metadata__)
+        if isinstance(tp, (typing._GenericAlias, _types.GenericAlias)):
+            res = tp.__args__
+            if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis:
+                res = (list(res[:-1]), res[-1])
+            return res
+        return ()
+
+
+# 3.10+
+if hasattr(typing, 'TypeAlias'):
+    TypeAlias = typing.TypeAlias
+# 3.9
+else:
+    @_ExtensionsSpecialForm
+    def TypeAlias(self, parameters):
+        """Special marker indicating that an assignment should
+        be recognized as a proper type alias definition by type
+        checkers.
+
+        For example::
+
+            Predicate: TypeAlias = Callable[..., bool]
+
+        It's invalid when used anywhere except as in the example above.
+        """
+        raise TypeError(f"{self} is not subscriptable")
+
+
+def _set_default(type_param, default):
+    type_param.has_default = lambda: default is not NoDefault
+    type_param.__default__ = default
+
+
+def _set_module(typevarlike):
+    # for pickling:
+    def_mod = _caller(depth=2)
+    if def_mod != 'typing_extensions':
+        typevarlike.__module__ = def_mod
+
+
+class _DefaultMixin:
+    """Mixin for TypeVarLike defaults."""
+
+    __slots__ = ()
+    __init__ = _set_default
+
+
+# Classes using this metaclass must provide a _backported_typevarlike ClassVar
+class _TypeVarLikeMeta(type):
+    def __instancecheck__(cls, __instance: Any) -> bool:
+        return isinstance(__instance, cls._backported_typevarlike)
+
+
+if _PEP_696_IMPLEMENTED:
+    from typing import TypeVar
+else:
+    # Add default and infer_variance parameters from PEP 696 and 695
+    class TypeVar(metaclass=_TypeVarLikeMeta):
+        """Type variable."""
+
+        _backported_typevarlike = typing.TypeVar
+
+        def __new__(cls, name, *constraints, bound=None,
+                    covariant=False, contravariant=False,
+                    default=NoDefault, infer_variance=False):
+            if hasattr(typing, "TypeAliasType"):
+                # PEP 695 implemented (3.12+), can pass infer_variance to typing.TypeVar
+                typevar = typing.TypeVar(name, *constraints, bound=bound,
+                                         covariant=covariant, contravariant=contravariant,
+                                         infer_variance=infer_variance)
+            else:
+                typevar = typing.TypeVar(name, *constraints, bound=bound,
+                                         covariant=covariant, contravariant=contravariant)
+                if infer_variance and (covariant or contravariant):
+                    raise ValueError("Variance cannot be specified with infer_variance.")
+                typevar.__infer_variance__ = infer_variance
+
+            _set_default(typevar, default)
+            _set_module(typevar)
+
+            def _tvar_prepare_subst(alias, args):
+                if (
+                    typevar.has_default()
+                    and alias.__parameters__.index(typevar) == len(args)
+                ):
+                    args += (typevar.__default__,)
+                return args
+
+            typevar.__typing_prepare_subst__ = _tvar_prepare_subst
+            return typevar
+
+        def __init_subclass__(cls) -> None:
+            raise TypeError(f"type '{__name__}.TypeVar' is not an acceptable base type")
+
+
+# Python 3.10+ has PEP 612
+if hasattr(typing, 'ParamSpecArgs'):
+    ParamSpecArgs = typing.ParamSpecArgs
+    ParamSpecKwargs = typing.ParamSpecKwargs
+# 3.9
+else:
+    class _Immutable:
+        """Mixin to indicate that object should not be copied."""
+        __slots__ = ()
+
+        def __copy__(self):
+            return self
+
+        def __deepcopy__(self, memo):
+            return self
+
+    class ParamSpecArgs(_Immutable):
+        """The args for a ParamSpec object.
+
+        Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.
+
+        ParamSpecArgs objects have a reference back to their ParamSpec:
+
+        P.args.__origin__ is P
+
+        This type is meant for runtime introspection and has no special meaning to
+        static type checkers.
+        """
+        def __init__(self, origin):
+            self.__origin__ = origin
+
+        def __repr__(self):
+            return f"{self.__origin__.__name__}.args"
+
+        def __eq__(self, other):
+            if not isinstance(other, ParamSpecArgs):
+                return NotImplemented
+            return self.__origin__ == other.__origin__
+
+    class ParamSpecKwargs(_Immutable):
+        """The kwargs for a ParamSpec object.
+
+        Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.
+
+        ParamSpecKwargs objects have a reference back to their ParamSpec:
+
+        P.kwargs.__origin__ is P
+
+        This type is meant for runtime introspection and has no special meaning to
+        static type checkers.
+        """
+        def __init__(self, origin):
+            self.__origin__ = origin
+
+        def __repr__(self):
+            return f"{self.__origin__.__name__}.kwargs"
+
+        def __eq__(self, other):
+            if not isinstance(other, ParamSpecKwargs):
+                return NotImplemented
+            return self.__origin__ == other.__origin__
+
+
+if _PEP_696_IMPLEMENTED:
+    from typing import ParamSpec
+
+# 3.10+
+elif hasattr(typing, 'ParamSpec'):
+
+    # Add default parameter - PEP 696
+    class ParamSpec(metaclass=_TypeVarLikeMeta):
+        """Parameter specification."""
+
+        _backported_typevarlike = typing.ParamSpec
+
+        def __new__(cls, name, *, bound=None,
+                    covariant=False, contravariant=False,
+                    infer_variance=False, default=NoDefault):
+            if hasattr(typing, "TypeAliasType"):
+                # PEP 695 implemented, can pass infer_variance to typing.TypeVar
+                paramspec = typing.ParamSpec(name, bound=bound,
+                                             covariant=covariant,
+                                             contravariant=contravariant,
+                                             infer_variance=infer_variance)
+            else:
+                paramspec = typing.ParamSpec(name, bound=bound,
+                                             covariant=covariant,
+                                             contravariant=contravariant)
+                paramspec.__infer_variance__ = bool(infer_variance)
+
+            _set_default(paramspec, default)
+            _set_module(paramspec)
+
+            def _paramspec_prepare_subst(alias, args):
+                params = alias.__parameters__
+                i = params.index(paramspec)
+                if i == len(args) and paramspec.has_default():
+                    args = [*args, paramspec.__default__]
+                if i >= len(args):
+                    raise TypeError(f"Too few arguments for {alias}")
+                # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.
+                if len(params) == 1 and not typing._is_param_expr(args[0]):
+                    assert i == 0
+                    args = (args,)
+                # Convert lists to tuples to help other libraries cache the results.
+                elif isinstance(args[i], list):
+                    args = (*args[:i], tuple(args[i]), *args[i + 1:])
+                return args
+
+            paramspec.__typing_prepare_subst__ = _paramspec_prepare_subst
+            return paramspec
+
+        def __init_subclass__(cls) -> None:
+            raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type")
+
+# 3.9
+else:
+
+    # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
+    class ParamSpec(list, _DefaultMixin):
+        """Parameter specification variable.
+
+        Usage::
+
+           P = ParamSpec('P')
+
+        Parameter specification variables exist primarily for the benefit of static
+        type checkers.  They are used to forward the parameter types of one
+        callable to another callable, a pattern commonly found in higher order
+        functions and decorators.  They are only valid when used in ``Concatenate``,
+        or s the first argument to ``Callable``. In Python 3.10 and higher,
+        they are also supported in user-defined Generics at runtime.
+        See class Generic for more information on generic types.  An
+        example for annotating a decorator::
+
+           T = TypeVar('T')
+           P = ParamSpec('P')
+
+           def add_logging(f: Callable[P, T]) -> Callable[P, T]:
+               '''A type-safe decorator to add logging to a function.'''
+               def inner(*args: P.args, **kwargs: P.kwargs) -> T:
+                   logging.info(f'{f.__name__} was called')
+                   return f(*args, **kwargs)
+               return inner
+
+           @add_logging
+           def add_two(x: float, y: float) -> float:
+               '''Add two numbers together.'''
+               return x + y
+
+        Parameter specification variables defined with covariant=True or
+        contravariant=True can be used to declare covariant or contravariant
+        generic types.  These keyword arguments are valid, but their actual semantics
+        are yet to be decided.  See PEP 612 for details.
+
+        Parameter specification variables can be introspected. e.g.:
+
+           P.__name__ == 'T'
+           P.__bound__ == None
+           P.__covariant__ == False
+           P.__contravariant__ == False
+
+        Note that only parameter specification variables defined in global scope can
+        be pickled.
+        """
+
+        # Trick Generic __parameters__.
+        __class__ = typing.TypeVar
+
+        @property
+        def args(self):
+            return ParamSpecArgs(self)
+
+        @property
+        def kwargs(self):
+            return ParamSpecKwargs(self)
+
+        def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
+                     infer_variance=False, default=NoDefault):
+            list.__init__(self, [self])
+            self.__name__ = name
+            self.__covariant__ = bool(covariant)
+            self.__contravariant__ = bool(contravariant)
+            self.__infer_variance__ = bool(infer_variance)
+            self.__bound__ = bound
+            _DefaultMixin.__init__(self, default)
+
+            # for pickling:
+            def_mod = _caller()
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+
+        def __repr__(self):
+            if self.__infer_variance__:
+                prefix = ''
+            elif self.__covariant__:
+                prefix = '+'
+            elif self.__contravariant__:
+                prefix = '-'
+            else:
+                prefix = '~'
+            return prefix + self.__name__
+
+        def __hash__(self):
+            return object.__hash__(self)
+
+        def __eq__(self, other):
+            return self is other
+
+        def __reduce__(self):
+            return self.__name__
+
+        # Hack to get typing._type_check to pass.
+        def __call__(self, *args, **kwargs):
+            pass
+
+        def __init_subclass__(cls) -> None:
+            raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type")
+
+
+# 3.9
+if not hasattr(typing, 'Concatenate'):
+    # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
+
+    # 3.9.0-1
+    if not hasattr(typing, '_type_convert'):
+        def _type_convert(arg, module=None, *, allow_special_forms=False):
+            """For converting None to type(None), and strings to ForwardRef."""
+            if arg is None:
+                return type(None)
+            if isinstance(arg, str):
+                if sys.version_info <= (3, 9, 6):
+                    return ForwardRef(arg)
+                if sys.version_info <= (3, 9, 7):
+                    return ForwardRef(arg, module=module)
+                return ForwardRef(arg, module=module, is_class=allow_special_forms)
+            return arg
+    else:
+        _type_convert = typing._type_convert
+
+    class _ConcatenateGenericAlias(list):
+
+        # Trick Generic into looking into this for __parameters__.
+        __class__ = typing._GenericAlias
+
+        def __init__(self, origin, args):
+            # Cannot use `super().__init__` here because of the `__class__` assignment
+            # in the class body (https://github.com/python/typing_extensions/issues/661)
+            list.__init__(self, args)
+            self.__origin__ = origin
+            self.__args__ = args
+
+        def __repr__(self):
+            _type_repr = typing._type_repr
+            return (f'{_type_repr(self.__origin__)}'
+                    f'[{", ".join(_type_repr(arg) for arg in self.__args__)}]')
+
+        def __hash__(self):
+            return hash((self.__origin__, self.__args__))
+
+        # Hack to get typing._type_check to pass in Generic.
+        def __call__(self, *args, **kwargs):
+            pass
+
+        @property
+        def __parameters__(self):
+            return tuple(
+                tp for tp in self.__args__ if isinstance(tp, (typing.TypeVar, ParamSpec))
+            )
+
+        # 3.9 used by __getitem__ below
+        def copy_with(self, params):
+            if isinstance(params[-1], _ConcatenateGenericAlias):
+                params = (*params[:-1], *params[-1].__args__)
+            elif isinstance(params[-1], (list, tuple)):
+                return (*params[:-1], *params[-1])
+            elif (not (params[-1] is ... or isinstance(params[-1], ParamSpec))):
+                raise TypeError("The last parameter to Concatenate should be a "
+                        "ParamSpec variable or ellipsis.")
+            return self.__class__(self.__origin__, params)
+
+        # 3.9; accessed during GenericAlias.__getitem__ when substituting
+        def __getitem__(self, args):
+            if self.__origin__ in (Generic, Protocol):
+                # Can't subscript Generic[...] or Protocol[...].
+                raise TypeError(f"Cannot subscript already-subscripted {self}")
+            if not self.__parameters__:
+                raise TypeError(f"{self} is not a generic class")
+
+            if not isinstance(args, tuple):
+                args = (args,)
+            args = _unpack_args(*(_type_convert(p) for p in args))
+            params = self.__parameters__
+            for param in params:
+                prepare = getattr(param, "__typing_prepare_subst__", None)
+                if prepare is not None:
+                    args = prepare(self, args)
+                # 3.9 & typing.ParamSpec
+                elif isinstance(param, ParamSpec):
+                    i = params.index(param)
+                    if (
+                        i == len(args)
+                        and getattr(param, '__default__', NoDefault) is not NoDefault
+                    ):
+                        args = [*args, param.__default__]
+                    if i >= len(args):
+                        raise TypeError(f"Too few arguments for {self}")
+                    # Special case for Z[[int, str, bool]] == Z[int, str, bool]
+                    if len(params) == 1 and not _is_param_expr(args[0]):
+                        assert i == 0
+                        args = (args,)
+                    elif (
+                        isinstance(args[i], list)
+                        # 3.9
+                        # This class inherits from list do not convert
+                        and not isinstance(args[i], _ConcatenateGenericAlias)
+                    ):
+                        args = (*args[:i], tuple(args[i]), *args[i + 1:])
+
+            alen = len(args)
+            plen = len(params)
+            if alen != plen:
+                raise TypeError(
+                    f"Too {'many' if alen > plen else 'few'} arguments for {self};"
+                    f" actual {alen}, expected {plen}"
+                )
+
+            subst = dict(zip(self.__parameters__, args))
+            # determine new args
+            new_args = []
+            for arg in self.__args__:
+                if isinstance(arg, type):
+                    new_args.append(arg)
+                    continue
+                if isinstance(arg, TypeVar):
+                    arg = subst[arg]
+                    if (
+                        (isinstance(arg, typing._GenericAlias) and _is_unpack(arg))
+                        or (
+                            hasattr(_types, "GenericAlias")
+                            and isinstance(arg, _types.GenericAlias)
+                            and getattr(arg, "__unpacked__", False)
+                        )
+                    ):
+                        raise TypeError(f"{arg} is not valid as type argument")
+
+                elif isinstance(arg,
+                    typing._GenericAlias
+                    if not hasattr(_types, "GenericAlias") else
+                    (typing._GenericAlias, _types.GenericAlias)
+                ):
+                    subparams = arg.__parameters__
+                    if subparams:
+                        subargs = tuple(subst[x] for x in subparams)
+                        arg = arg[subargs]
+                new_args.append(arg)
+            return self.copy_with(tuple(new_args))
+
+# 3.10+
+else:
+    _ConcatenateGenericAlias = typing._ConcatenateGenericAlias
+
+    # 3.10
+    if sys.version_info < (3, 11):
+
+        class _ConcatenateGenericAlias(typing._ConcatenateGenericAlias, _root=True):
+            # needed for checks in collections.abc.Callable to accept this class
+            __module__ = "typing"
+
+            def copy_with(self, params):
+                if isinstance(params[-1], (list, tuple)):
+                    return (*params[:-1], *params[-1])
+                if isinstance(params[-1], typing._ConcatenateGenericAlias):
+                    params = (*params[:-1], *params[-1].__args__)
+                elif not (params[-1] is ... or isinstance(params[-1], ParamSpec)):
+                    raise TypeError("The last parameter to Concatenate should be a "
+                            "ParamSpec variable or ellipsis.")
+                return super(typing._ConcatenateGenericAlias, self).copy_with(params)
+
+            def __getitem__(self, args):
+                value = super().__getitem__(args)
+                if isinstance(value, tuple) and any(_is_unpack(t) for t in value):
+                    return tuple(_unpack_args(*(n for n in value)))
+                return value
+
+
+# 3.9.2
+class _EllipsisDummy: ...
+
+
+# <=3.10
+def _create_concatenate_alias(origin, parameters):
+    if parameters[-1] is ... and sys.version_info < (3, 9, 2):
+        # Hack: Arguments must be types, replace it with one.
+        parameters = (*parameters[:-1], _EllipsisDummy)
+    if sys.version_info >= (3, 10, 3):
+        concatenate = _ConcatenateGenericAlias(origin, parameters,
+                                        _typevar_types=(TypeVar, ParamSpec),
+                                        _paramspec_tvars=True)
+    else:
+        concatenate = _ConcatenateGenericAlias(origin, parameters)
+    if parameters[-1] is not _EllipsisDummy:
+        return concatenate
+    # Remove dummy again
+    concatenate.__args__ = tuple(p if p is not _EllipsisDummy else ...
+                                    for p in concatenate.__args__)
+    if sys.version_info < (3, 10):
+        # backport needs __args__ adjustment only
+        return concatenate
+    concatenate.__parameters__ = tuple(p for p in concatenate.__parameters__
+                                        if p is not _EllipsisDummy)
+    return concatenate
+
+
+# <=3.10
+@typing._tp_cache
+def _concatenate_getitem(self, parameters):
+    if parameters == ():
+        raise TypeError("Cannot take a Concatenate of no types.")
+    if not isinstance(parameters, tuple):
+        parameters = (parameters,)
+    if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)):
+        raise TypeError("The last parameter to Concatenate should be a "
+                        "ParamSpec variable or ellipsis.")
+    msg = "Concatenate[arg, ...]: each arg must be a type."
+    parameters = (*(typing._type_check(p, msg) for p in parameters[:-1]),
+                    parameters[-1])
+    return _create_concatenate_alias(self, parameters)
+
+
+# 3.11+; Concatenate does not accept ellipsis in 3.10
+# Breakpoint: https://github.com/python/cpython/pull/30969
+if sys.version_info >= (3, 11):
+    Concatenate = typing.Concatenate
+# <=3.10
+else:
+    @_ExtensionsSpecialForm
+    def Concatenate(self, parameters):
+        """Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a
+        higher order function which adds, removes or transforms parameters of a
+        callable.
+
+        For example::
+
+           Callable[Concatenate[int, P], int]
+
+        See PEP 612 for detailed information.
+        """
+        return _concatenate_getitem(self, parameters)
+
+
+# 3.10+
+if hasattr(typing, 'TypeGuard'):
+    TypeGuard = typing.TypeGuard
+# 3.9
+else:
+    @_ExtensionsSpecialForm
+    def TypeGuard(self, parameters):
+        """Special typing form used to annotate the return type of a user-defined
+        type guard function.  ``TypeGuard`` only accepts a single type argument.
+        At runtime, functions marked this way should return a boolean.
+
+        ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static
+        type checkers to determine a more precise type of an expression within a
+        program's code flow.  Usually type narrowing is done by analyzing
+        conditional code flow and applying the narrowing to a block of code.  The
+        conditional expression here is sometimes referred to as a "type guard".
+
+        Sometimes it would be convenient to use a user-defined boolean function
+        as a type guard.  Such a function should use ``TypeGuard[...]`` as its
+        return type to alert static type checkers to this intention.
+
+        Using  ``-> TypeGuard`` tells the static type checker that for a given
+        function:
+
+        1. The return value is a boolean.
+        2. If the return value is ``True``, the type of its argument
+        is the type inside ``TypeGuard``.
+
+        For example::
+
+            def is_str(val: Union[str, float]):
+                # "isinstance" type guard
+                if isinstance(val, str):
+                    # Type of ``val`` is narrowed to ``str``
+                    ...
+                else:
+                    # Else, type of ``val`` is narrowed to ``float``.
+                    ...
+
+        Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower
+        form of ``TypeA`` (it can even be a wider form) and this may lead to
+        type-unsafe results.  The main reason is to allow for things like
+        narrowing ``List[object]`` to ``List[str]`` even though the latter is not
+        a subtype of the former, since ``List`` is invariant.  The responsibility of
+        writing type-safe type guards is left to the user.
+
+        ``TypeGuard`` also works with type variables.  For more information, see
+        PEP 647 (User-Defined Type Guards).
+        """
+        item = typing._type_check(parameters, f'{self} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+
+# 3.13+
+if hasattr(typing, 'TypeIs'):
+    TypeIs = typing.TypeIs
+# <=3.12
+else:
+    @_ExtensionsSpecialForm
+    def TypeIs(self, parameters):
+        """Special typing form used to annotate the return type of a user-defined
+        type narrower function.  ``TypeIs`` only accepts a single type argument.
+        At runtime, functions marked this way should return a boolean.
+
+        ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static
+        type checkers to determine a more precise type of an expression within a
+        program's code flow.  Usually type narrowing is done by analyzing
+        conditional code flow and applying the narrowing to a block of code.  The
+        conditional expression here is sometimes referred to as a "type guard".
+
+        Sometimes it would be convenient to use a user-defined boolean function
+        as a type guard.  Such a function should use ``TypeIs[...]`` as its
+        return type to alert static type checkers to this intention.
+
+        Using  ``-> TypeIs`` tells the static type checker that for a given
+        function:
+
+        1. The return value is a boolean.
+        2. If the return value is ``True``, the type of its argument
+        is the intersection of the type inside ``TypeIs`` and the argument's
+        previously known type.
+
+        For example::
+
+            def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]:
+                return hasattr(val, '__await__')
+
+            def f(val: Union[int, Awaitable[int]]) -> int:
+                if is_awaitable(val):
+                    assert_type(val, Awaitable[int])
+                else:
+                    assert_type(val, int)
+
+        ``TypeIs`` also works with type variables.  For more information, see
+        PEP 742 (Narrowing types with TypeIs).
+        """
+        item = typing._type_check(parameters, f'{self} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+
+# 3.15+?
+if hasattr(typing, 'TypeForm'):
+    TypeForm = typing.TypeForm
+# <=3.14
+else:
+    class _TypeFormForm(_ExtensionsSpecialForm, _root=True):
+        # TypeForm(X) is equivalent to X but indicates to the type checker
+        # that the object is a TypeForm.
+        def __call__(self, obj, /):
+            return obj
+
+    @_TypeFormForm
+    def TypeForm(self, parameters):
+        """A special form representing the value that results from the evaluation
+        of a type expression. This value encodes the information supplied in the
+        type expression, and it represents the type described by that type expression.
+
+        When used in a type expression, TypeForm describes a set of type form objects.
+        It accepts a single type argument, which must be a valid type expression.
+        ``TypeForm[T]`` describes the set of all type form objects that represent
+        the type T or types that are assignable to T.
+
+        Usage:
+
+            def cast[T](typ: TypeForm[T], value: Any) -> T: ...
+
+            reveal_type(cast(int, "x"))  # int
+
+        See PEP 747 for more information.
+        """
+        item = typing._type_check(parameters, f'{self} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+
+
+
+if hasattr(typing, "LiteralString"):  # 3.11+
+    LiteralString = typing.LiteralString
+else:
+    @_SpecialForm
+    def LiteralString(self, params):
+        """Represents an arbitrary literal string.
+
+        Example::
+
+          from typing_extensions import LiteralString
+
+          def query(sql: LiteralString) -> ...:
+              ...
+
+          query("SELECT * FROM table")  # ok
+          query(f"SELECT * FROM {input()}")  # not ok
+
+        See PEP 675 for details.
+
+        """
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, "Self"):  # 3.11+
+    Self = typing.Self
+else:
+    @_SpecialForm
+    def Self(self, params):
+        """Used to spell the type of "self" in classes.
+
+        Example::
+
+          from typing import Self
+
+          class ReturnsSelf:
+              def parse(self, data: bytes) -> Self:
+                  ...
+                  return self
+
+        """
+
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, "Never"):  # 3.11+
+    Never = typing.Never
+else:
+    @_SpecialForm
+    def Never(self, params):
+        """The bottom type, a type that has no members.
+
+        This can be used to define a function that should never be
+        called, or a function that never returns::
+
+            from typing_extensions import Never
+
+            def never_call_me(arg: Never) -> None:
+                pass
+
+            def int_or_str(arg: int | str) -> None:
+                never_call_me(arg)  # type checker error
+                match arg:
+                    case int():
+                        print("It's an int")
+                    case str():
+                        print("It's a str")
+                    case _:
+                        never_call_me(arg)  # ok, arg is of type Never
+
+        """
+
+        raise TypeError(f"{self} is not subscriptable")
+
+
+if hasattr(typing, 'Required'):  # 3.11+
+    Required = typing.Required
+    NotRequired = typing.NotRequired
+else:  # <=3.10
+    @_ExtensionsSpecialForm
+    def Required(self, parameters):
+        """A special typing construct to mark a key of a total=False TypedDict
+        as required. For example:
+
+            class Movie(TypedDict, total=False):
+                title: Required[str]
+                year: int
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+
+        There is no runtime checking that a required key is actually provided
+        when instantiating a related TypedDict.
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+    @_ExtensionsSpecialForm
+    def NotRequired(self, parameters):
+        """A special typing construct to mark a key of a TypedDict as
+        potentially missing. For example:
+
+            class Movie(TypedDict):
+                title: str
+                year: NotRequired[int]
+
+            m = Movie(
+                title='The Matrix',  # typechecker error if key is omitted
+                year=1999,
+            )
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+
+if hasattr(typing, 'ReadOnly'):
+    ReadOnly = typing.ReadOnly
+else:  # <=3.12
+    @_ExtensionsSpecialForm
+    def ReadOnly(self, parameters):
+        """A special typing construct to mark an item of a TypedDict as read-only.
+
+        For example:
+
+            class Movie(TypedDict):
+                title: ReadOnly[str]
+                year: int
+
+            def mutate_movie(m: Movie) -> None:
+                m["year"] = 1992  # allowed
+                m["title"] = "The Matrix"  # typechecker error
+
+        There is no runtime checking for this property.
+        """
+        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
+        return typing._GenericAlias(self, (item,))
+
+
+_UNPACK_DOC = """\
+Type unpack operator.
+
+The type unpack operator takes the child types from some container type,
+such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For
+example:
+
+  # For some generic class `Foo`:
+  Foo[Unpack[tuple[int, str]]]  # Equivalent to Foo[int, str]
+
+  Ts = TypeVarTuple('Ts')
+  # Specifies that `Bar` is generic in an arbitrary number of types.
+  # (Think of `Ts` as a tuple of an arbitrary number of individual
+  #  `TypeVar`s, which the `Unpack` is 'pulling out' directly into the
+  #  `Generic[]`.)
+  class Bar(Generic[Unpack[Ts]]): ...
+  Bar[int]  # Valid
+  Bar[int, str]  # Also valid
+
+From Python 3.11, this can also be done using the `*` operator:
+
+    Foo[*tuple[int, str]]
+    class Bar(Generic[*Ts]): ...
+
+The operator can also be used along with a `TypedDict` to annotate
+`**kwargs` in a function signature. For instance:
+
+  class Movie(TypedDict):
+    name: str
+    year: int
+
+  # This function expects two keyword arguments - *name* of type `str` and
+  # *year* of type `int`.
+  def foo(**kwargs: Unpack[Movie]): ...
+
+Note that there is only some runtime checking of this operator. Not
+everything the runtime allows may be accepted by static type checkers.
+
+For more information, see PEP 646 and PEP 692.
+"""
+
+
+# PEP 692 changed the repr of Unpack[]
+# Breakpoint: https://github.com/python/cpython/pull/104048
+if sys.version_info >= (3, 12):
+    Unpack = typing.Unpack
+
+    def _is_unpack(obj):
+        return get_origin(obj) is Unpack
+
+else:  # <=3.11
+    class _UnpackSpecialForm(_ExtensionsSpecialForm, _root=True):
+        def __init__(self, getitem):
+            super().__init__(getitem)
+            self.__doc__ = _UNPACK_DOC
+
+    class _UnpackAlias(typing._GenericAlias, _root=True):
+        if sys.version_info < (3, 11):
+            # needed for compatibility with Generic[Unpack[Ts]]
+            __class__ = typing.TypeVar
+
+        @property
+        def __typing_unpacked_tuple_args__(self):
+            assert self.__origin__ is Unpack
+            assert len(self.__args__) == 1
+            arg, = self.__args__
+            if isinstance(arg, (typing._GenericAlias, _types.GenericAlias)):
+                if arg.__origin__ is not tuple:
+                    raise TypeError("Unpack[...] must be used with a tuple type")
+                return arg.__args__
+            return None
+
+        @property
+        def __typing_is_unpacked_typevartuple__(self):
+            assert self.__origin__ is Unpack
+            assert len(self.__args__) == 1
+            return isinstance(self.__args__[0], TypeVarTuple)
+
+        def __getitem__(self, args):
+            if self.__typing_is_unpacked_typevartuple__:
+                return args
+            # Cannot use `super().__getitem__` here because of the `__class__` assignment
+            # in the class body on Python <=3.11
+            # (https://github.com/python/typing_extensions/issues/661)
+            return typing._GenericAlias.__getitem__(self, args)
+
+    @_UnpackSpecialForm
+    def Unpack(self, parameters):
+        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
+        return _UnpackAlias(self, (item,))
+
+    def _is_unpack(obj):
+        return isinstance(obj, _UnpackAlias)
+
+
+def _unpack_args(*args):
+    newargs = []
+    for arg in args:
+        subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
+        if subargs is not None and (not (subargs and subargs[-1] is ...)):
+            newargs.extend(subargs)
+        else:
+            newargs.append(arg)
+    return newargs
+
+
+if sys.version_info >= (3, 15):
+    from typing import TypeVarTuple
+
+elif hasattr(typing, "TypeVarTuple"):  # 3.11+
+
+    # Add default parameter - PEP 696 and bound/variance parameters
+    class TypeVarTuple(metaclass=_TypeVarLikeMeta):
+        """Type variable tuple."""
+
+        _backported_typevarlike = typing.TypeVarTuple
+
+        def __new__(cls, name, *, bound=None,
+                    covariant=False, contravariant=False,
+                    infer_variance=False, default=NoDefault):
+
+            if _PEP_696_IMPLEMENTED:
+                # can pass default argument
+                tvt = typing.TypeVarTuple(name, default=default)
+            else:
+                tvt = typing.TypeVarTuple(name)
+                _set_default(tvt, default)
+
+            tvt.__bound__ = bound
+            tvt.__covariant__ = bool(covariant)
+            tvt.__contravariant__ = bool(contravariant)
+            tvt.__infer_variance__ = bool(infer_variance)
+
+            _set_module(tvt)
+
+            def _typevartuple_prepare_subst(alias, args):
+                params = alias.__parameters__
+                typevartuple_index = params.index(tvt)
+                for param in params[typevartuple_index + 1:]:
+                    if isinstance(param, TypeVarTuple):
+                        raise TypeError(
+                            f"More than one TypeVarTuple parameter in {alias}"
+                        )
+
+                alen = len(args)
+                plen = len(params)
+                left = typevartuple_index
+                right = plen - typevartuple_index - 1
+                var_tuple_index = None
+                fillarg = None
+                for k, arg in enumerate(args):
+                    if not isinstance(arg, type):
+                        subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
+                        if subargs and len(subargs) == 2 and subargs[-1] is ...:
+                            if var_tuple_index is not None:
+                                raise TypeError(
+                                    "More than one unpacked "
+                                    "arbitrary-length tuple argument"
+                                )
+                            var_tuple_index = k
+                            fillarg = subargs[0]
+                if var_tuple_index is not None:
+                    left = min(left, var_tuple_index)
+                    right = min(right, alen - var_tuple_index - 1)
+                elif left + right > alen:
+                    raise TypeError(f"Too few arguments for {alias};"
+                                    f" actual {alen}, expected at least {plen - 1}")
+                if left == alen - right and tvt.has_default():
+                    replacement = _unpack_args(tvt.__default__)
+                else:
+                    replacement = args[left: alen - right]
+
+                return (
+                    *args[:left],
+                    *([fillarg] * (typevartuple_index - left)),
+                    replacement,
+                    *([fillarg] * (plen - right - left - typevartuple_index - 1)),
+                    *args[alen - right:],
+                )
+
+            tvt.__typing_prepare_subst__ = _typevartuple_prepare_subst
+            return tvt
+
+        def __init_subclass__(self, *args, **kwds):
+            raise TypeError("Cannot subclass special typing classes")
+
+else:  # <=3.10
+    class TypeVarTuple(_DefaultMixin):
+        """Type variable tuple.
+
+        Usage::
+
+            Ts = TypeVarTuple('Ts')
+
+        In the same way that a normal type variable is a stand-in for a single
+        type such as ``int``, a type variable *tuple* is a stand-in for a *tuple*
+        type such as ``Tuple[int, str]``.
+
+        Type variable tuples can be used in ``Generic`` declarations.
+        Consider the following example::
+
+            class Array(Generic[*Ts]): ...
+
+        The ``Ts`` type variable tuple here behaves like ``tuple[T1, T2]``,
+        where ``T1`` and ``T2`` are type variables. To use these type variables
+        as type parameters of ``Array``, we must *unpack* the type variable tuple using
+        the star operator: ``*Ts``. The signature of ``Array`` then behaves
+        as if we had simply written ``class Array(Generic[T1, T2]): ...``.
+        In contrast to ``Generic[T1, T2]``, however, ``Generic[*Shape]`` allows
+        us to parameterise the class with an *arbitrary* number of type parameters.
+
+        Type variable tuples can be used anywhere a normal ``TypeVar`` can.
+        This includes class definitions, as shown above, as well as function
+        signatures and variable annotations::
+
+            class Array(Generic[*Ts]):
+
+                def __init__(self, shape: Tuple[*Ts]):
+                    self._shape: Tuple[*Ts] = shape
+
+                def get_shape(self) -> Tuple[*Ts]:
+                    return self._shape
+
+            shape = (Height(480), Width(640))
+            x: Array[Height, Width] = Array(shape)
+            y = abs(x)  # Inferred type is Array[Height, Width]
+            z = x + x   #        ...    is Array[Height, Width]
+            x.get_shape()  #     ...    is tuple[Height, Width]
+
+        """
+
+        # Trick Generic __parameters__.
+        __class__ = typing.TypeVar
+
+        def __iter__(self):
+            yield self.__unpacked__
+
+        def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
+                     infer_variance=False, default=NoDefault):
+            self.__name__ = name
+            self.__covariant__ = bool(covariant)
+            self.__contravariant__ = bool(contravariant)
+            self.__infer_variance__ = bool(infer_variance)
+            self.__bound__ = bound
+            _DefaultMixin.__init__(self, default)
+
+            # for pickling:
+            def_mod = _caller()
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+
+            self.__unpacked__ = Unpack[self]
+
+        def __repr__(self):
+            if self.__infer_variance__:
+                prefix = ''
+            elif self.__covariant__:
+                prefix = '+'
+            elif self.__contravariant__:
+                prefix = '-'
+            else:
+                prefix = '~'
+            return prefix + self.__name__
+
+        def __hash__(self):
+            return object.__hash__(self)
+
+        def __eq__(self, other):
+            return self is other
+
+        def __reduce__(self):
+            return self.__name__
+
+        def __init_subclass__(self, *args, **kwds):
+            if '_root' not in kwds:
+                raise TypeError("Cannot subclass special typing classes")
+
+
+if hasattr(typing, "reveal_type"):  # 3.11+
+    reveal_type = typing.reveal_type
+else:  # <=3.10
+    def reveal_type(obj: T, /) -> T:
+        """Reveal the inferred type of a variable.
+
+        When a static type checker encounters a call to ``reveal_type()``,
+        it will emit the inferred type of the argument::
+
+            x: int = 1
+            reveal_type(x)
+
+        Running a static type checker (e.g., ``mypy``) on this example
+        will produce output similar to 'Revealed type is "builtins.int"'.
+
+        At runtime, the function prints the runtime type of the
+        argument and returns it unchanged.
+
+        """
+        print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
+        return obj
+
+
+if hasattr(typing, "_ASSERT_NEVER_REPR_MAX_LENGTH"):  # 3.11+
+    _ASSERT_NEVER_REPR_MAX_LENGTH = typing._ASSERT_NEVER_REPR_MAX_LENGTH
+else:  # <=3.10
+    _ASSERT_NEVER_REPR_MAX_LENGTH = 100
+
+
+if hasattr(typing, "assert_never"):  # 3.11+
+    assert_never = typing.assert_never
+else:  # <=3.10
+    def assert_never(arg: Never, /) -> Never:
+        """Assert to the type checker that a line of code is unreachable.
+
+        Example::
+
+            def int_or_str(arg: int | str) -> None:
+                match arg:
+                    case int():
+                        print("It's an int")
+                    case str():
+                        print("It's a str")
+                    case _:
+                        assert_never(arg)
+
+        If a type checker finds that a call to assert_never() is
+        reachable, it will emit an error.
+
+        At runtime, this throws an exception when called.
+
+        """
+        value = repr(arg)
+        if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH:
+            value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...'
+        raise AssertionError(f"Expected code to be unreachable, but got: {value}")
+
+
+# dataclass_transform exists in 3.11 but lacks the frozen_default parameter
+# Breakpoint: https://github.com/python/cpython/pull/99958
+if sys.version_info >= (3, 12):  # 3.12+
+    dataclass_transform = typing.dataclass_transform
+else:  # <=3.11
+    def dataclass_transform(
+        *,
+        eq_default: bool = True,
+        order_default: bool = False,
+        kw_only_default: bool = False,
+        frozen_default: bool = False,
+        field_specifiers: typing.Tuple[
+            typing.Union[typing.Type[typing.Any], typing.Callable[..., typing.Any]],
+            ...
+        ] = (),
+        **kwargs: typing.Any,
+    ) -> typing.Callable[[T], T]:
+        """Decorator that marks a function, class, or metaclass as providing
+        dataclass-like behavior.
+
+        Example:
+
+            from typing_extensions import dataclass_transform
+
+            _T = TypeVar("_T")
+
+            # Used on a decorator function
+            @dataclass_transform()
+            def create_model(cls: type[_T]) -> type[_T]:
+                ...
+                return cls
+
+            @create_model
+            class CustomerModel:
+                id: int
+                name: str
+
+            # Used on a base class
+            @dataclass_transform()
+            class ModelBase: ...
+
+            class CustomerModel(ModelBase):
+                id: int
+                name: str
+
+            # Used on a metaclass
+            @dataclass_transform()
+            class ModelMeta(type): ...
+
+            class ModelBase(metaclass=ModelMeta): ...
+
+            class CustomerModel(ModelBase):
+                id: int
+                name: str
+
+        Each of the ``CustomerModel`` classes defined in this example will now
+        behave similarly to a dataclass created with the ``@dataclasses.dataclass``
+        decorator. For example, the type checker will synthesize an ``__init__``
+        method.
+
+        The arguments to this decorator can be used to customize this behavior:
+        - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be
+          True or False if it is omitted by the caller.
+        - ``order_default`` indicates whether the ``order`` parameter is
+          assumed to be True or False if it is omitted by the caller.
+        - ``kw_only_default`` indicates whether the ``kw_only`` parameter is
+          assumed to be True or False if it is omitted by the caller.
+        - ``frozen_default`` indicates whether the ``frozen`` parameter is
+          assumed to be True or False if it is omitted by the caller.
+        - ``field_specifiers`` specifies a static list of supported classes
+          or functions that describe fields, similar to ``dataclasses.field()``.
+
+        At runtime, this decorator records its arguments in the
+        ``__dataclass_transform__`` attribute on the decorated object.
+
+        See PEP 681 for details.
+
+        """
+        def decorator(cls_or_fn):
+            cls_or_fn.__dataclass_transform__ = {
+                "eq_default": eq_default,
+                "order_default": order_default,
+                "kw_only_default": kw_only_default,
+                "frozen_default": frozen_default,
+                "field_specifiers": field_specifiers,
+                "kwargs": kwargs,
+            }
+            return cls_or_fn
+        return decorator
+
+
+if hasattr(typing, "override"):  # 3.12+
+    override = typing.override
+else:  # <=3.11
+    _F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any])
+
+    def override(arg: _F, /) -> _F:
+        """Indicate that a method is intended to override a method in a base class.
+
+        Usage:
+
+            class Base:
+                def method(self) -> None:
+                    pass
+
+            class Child(Base):
+                @override
+                def method(self) -> None:
+                    super().method()
+
+        When this decorator is applied to a method, the type checker will
+        validate that it overrides a method with the same name on a base class.
+        This helps prevent bugs that may occur when a base class is changed
+        without an equivalent change to a child class.
+
+        There is no runtime checking of these properties. The decorator
+        sets the ``__override__`` attribute to ``True`` on the decorated object
+        to allow runtime introspection.
+
+        See PEP 698 for details.
+
+        """
+        try:
+            arg.__override__ = True
+        except (AttributeError, TypeError):
+            # Skip the attribute silently if it is not writable.
+            # AttributeError happens if the object has __slots__ or a
+            # read-only property, TypeError if it's a builtin class.
+            pass
+        return arg
+
+
+# Python 3.13.8+ and 3.14.1+ contain a fix for the wrapped __init_subclass__
+# Breakpoint: https://github.com/python/cpython/pull/138210
+if ((3, 13, 8) <= sys.version_info < (3, 14)) or sys.version_info >= (3, 14, 1):
+    deprecated = warnings.deprecated
+else:
+    _T = typing.TypeVar("_T")
+
+    class deprecated:
+        """Indicate that a class, function or overload is deprecated.
+
+        When this decorator is applied to an object, the type checker
+        will generate a diagnostic on usage of the deprecated object.
+
+        Usage:
+
+            @deprecated("Use B instead")
+            class A:
+                pass
+
+            @deprecated("Use g instead")
+            def f():
+                pass
+
+            @overload
+            @deprecated("int support is deprecated")
+            def g(x: int) -> int: ...
+            @overload
+            def g(x: str) -> int: ...
+
+        The warning specified by *category* will be emitted at runtime
+        on use of deprecated objects. For functions, that happens on calls;
+        for classes, on instantiation and on creation of subclasses.
+        If the *category* is ``None``, no warning is emitted at runtime.
+        The *stacklevel* determines where the
+        warning is emitted. If it is ``1`` (the default), the warning
+        is emitted at the direct caller of the deprecated object; if it
+        is higher, it is emitted further up the stack.
+        Static type checker behavior is not affected by the *category*
+        and *stacklevel* arguments.
+
+        The deprecation message passed to the decorator is saved in the
+        ``__deprecated__`` attribute on the decorated object.
+        If applied to an overload, the decorator
+        must be after the ``@overload`` decorator for the attribute to
+        exist on the overload as returned by ``get_overloads()``.
+
+        See PEP 702 for details.
+
+        """
+        def __init__(
+            self,
+            message: str,
+            /,
+            *,
+            category: typing.Optional[typing.Type[Warning]] = DeprecationWarning,
+            stacklevel: int = 1,
+        ) -> None:
+            if not isinstance(message, str):
+                raise TypeError(
+                    "Expected an object of type str for 'message', not "
+                    f"{type(message).__name__!r}"
+                )
+            self.message = message
+            self.category = category
+            self.stacklevel = stacklevel
+
+        def __call__(self, arg: _T, /) -> _T:
+            # Make sure the inner functions created below don't
+            # retain a reference to self.
+            msg = self.message
+            category = self.category
+            stacklevel = self.stacklevel
+            if category is None:
+                arg.__deprecated__ = msg
+                return arg
+            elif isinstance(arg, type):
+                import functools
+                from types import MethodType
+
+                original_new = arg.__new__
+
+                @functools.wraps(original_new)
+                def __new__(cls, /, *args, **kwargs):
+                    if cls is arg:
+                        warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
+                    if original_new is not object.__new__:
+                        return original_new(cls, *args, **kwargs)
+                    # Mirrors a similar check in object.__new__.
+                    elif cls.__init__ is object.__init__ and (args or kwargs):
+                        raise TypeError(f"{cls.__name__}() takes no arguments")
+                    else:
+                        return original_new(cls)
+
+                arg.__new__ = staticmethod(__new__)
+
+                if "__init_subclass__" in arg.__dict__:
+                    # __init_subclass__ is directly present on the decorated class.
+                    # Synthesize a wrapper that calls this method directly.
+                    original_init_subclass = arg.__init_subclass__
+                    # We need slightly different behavior if __init_subclass__
+                    # is a bound method (likely if it was implemented in Python).
+                    # Otherwise, it likely means it's a builtin such as
+                    # object's implementation of __init_subclass__.
+                    if isinstance(original_init_subclass, MethodType):
+                        original_init_subclass = original_init_subclass.__func__
+
+                    @functools.wraps(original_init_subclass)
+                    def __init_subclass__(*args, **kwargs):
+                        warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
+                        return original_init_subclass(*args, **kwargs)
+                else:
+                    def __init_subclass__(cls, *args, **kwargs):
+                        warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
+                        return super(arg, cls).__init_subclass__(*args, **kwargs)
+
+                arg.__init_subclass__ = classmethod(__init_subclass__)
+
+                arg.__deprecated__ = __new__.__deprecated__ = msg
+                __init_subclass__.__deprecated__ = msg
+                return arg
+            elif callable(arg):
+                import functools
+                import inspect
+
+                @functools.wraps(arg)
+                def wrapper(*args, **kwargs):
+                    warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
+                    return arg(*args, **kwargs)
+
+                if inspect.iscoroutinefunction(arg):
+                    # Breakpoint: https://github.com/python/cpython/pull/99247
+                    if sys.version_info >= (3, 12):
+                        wrapper = inspect.markcoroutinefunction(wrapper)
+                    else:
+                        import asyncio.coroutines
+
+                        wrapper._is_coroutine = asyncio.coroutines._is_coroutine
+
+                arg.__deprecated__ = wrapper.__deprecated__ = msg
+                return wrapper
+            else:
+                raise TypeError(
+                    "@deprecated decorator with non-None category must be applied to "
+                    f"a class or callable, not {arg!r}"
+                )
+
+# Breakpoint: https://github.com/python/cpython/pull/23702
+if sys.version_info < (3, 10):
+    def _is_param_expr(arg):
+        return arg is ... or isinstance(
+            arg, (tuple, list, ParamSpec, _ConcatenateGenericAlias)
+        )
+else:
+    def _is_param_expr(arg):
+        return arg is ... or isinstance(
+            arg,
+            (
+                tuple,
+                list,
+                ParamSpec,
+                _ConcatenateGenericAlias,
+                typing._ConcatenateGenericAlias,
+            ),
+        )
+
+
+# We have to do some monkey patching to deal with the dual nature of
+# Unpack/TypeVarTuple:
+# - We want Unpack to be a kind of TypeVar so it gets accepted in
+#   Generic[Unpack[Ts]]
+# - We want it to *not* be treated as a TypeVar for the purposes of
+#   counting generic parameters, so that when we subscript a generic,
+#   the runtime doesn't try to substitute the Unpack with the subscripted type.
+if not hasattr(typing, "TypeVarTuple"):
+    def _check_generic(cls, parameters, elen=_marker):
+        """Check correct count for parameters of a generic cls (internal helper).
+
+        This gives a nice error message in case of count mismatch.
+        """
+        # If substituting a single ParamSpec with multiple arguments
+        # we do not check the count
+        if (inspect.isclass(cls) and issubclass(cls, typing.Generic)
+            and len(cls.__parameters__) == 1
+            and isinstance(cls.__parameters__[0], ParamSpec)
+            and parameters
+            and not _is_param_expr(parameters[0])
+        ):
+            # Generic modifies parameters variable, but here we cannot do this
+            return
+
+        if not elen:
+            raise TypeError(f"{cls} is not a generic class")
+        if elen is _marker:
+            if not hasattr(cls, "__parameters__") or not cls.__parameters__:
+                raise TypeError(f"{cls} is not a generic class")
+            elen = len(cls.__parameters__)
+        alen = len(parameters)
+        if alen != elen:
+            expect_val = elen
+            if hasattr(cls, "__parameters__"):
+                parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
+                num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters)
+                if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples):
+                    return
+
+                # deal with TypeVarLike defaults
+                # required TypeVarLikes cannot appear after a defaulted one.
+                if alen < elen:
+                    # since we validate TypeVarLike default in _collect_type_vars
+                    # or _collect_parameters we can safely check parameters[alen]
+                    if (
+                        getattr(parameters[alen], '__default__', NoDefault)
+                        is not NoDefault
+                    ):
+                        return
+
+                    num_default_tv = sum(getattr(p, '__default__', NoDefault)
+                                         is not NoDefault for p in parameters)
+
+                    elen -= num_default_tv
+
+                    expect_val = f"at least {elen}"
+
+            # Breakpoint: https://github.com/python/cpython/pull/27515
+            things = "arguments" if sys.version_info >= (3, 10) else "parameters"
+            raise TypeError(f"Too {'many' if alen > elen else 'few'} {things}"
+                            f" for {cls}; actual {alen}, expected {expect_val}")
+else:
+    # Python 3.11+
+
+    def _check_generic(cls, parameters, elen):
+        """Check correct count for parameters of a generic cls (internal helper).
+
+        This gives a nice error message in case of count mismatch.
+        """
+        if not elen:
+            raise TypeError(f"{cls} is not a generic class")
+        alen = len(parameters)
+        if alen != elen:
+            expect_val = elen
+            if hasattr(cls, "__parameters__"):
+                parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
+
+                # deal with TypeVarLike defaults
+                # required TypeVarLikes cannot appear after a defaulted one.
+                if alen < elen:
+                    # since we validate TypeVarLike default in _collect_type_vars
+                    # or _collect_parameters we can safely check parameters[alen]
+                    if (
+                        getattr(parameters[alen], '__default__', NoDefault)
+                        is not NoDefault
+                    ):
+                        return
+
+                    num_default_tv = sum(getattr(p, '__default__', NoDefault)
+                                         is not NoDefault for p in parameters)
+
+                    elen -= num_default_tv
+
+                    expect_val = f"at least {elen}"
+
+            raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments"
+                            f" for {cls}; actual {alen}, expected {expect_val}")
+
+if not _PEP_696_IMPLEMENTED:
+    typing._check_generic = _check_generic
+
+
+def _has_generic_or_protocol_as_origin() -> bool:
+    try:
+        frame = sys._getframe(2)
+    # - Catch AttributeError: not all Python implementations have sys._getframe()
+    # - Catch ValueError: maybe we're called from an unexpected module
+    #   and the call stack isn't deep enough
+    except (AttributeError, ValueError):
+        return False  # err on the side of leniency
+    else:
+        # If we somehow get invoked from outside typing.py,
+        # also err on the side of leniency
+        if frame.f_globals.get("__name__") != "typing":
+            return False
+        origin = frame.f_locals.get("origin")
+        # Cannot use "in" because origin may be an object with a buggy __eq__ that
+        # throws an error.
+        return origin is typing.Generic or origin is Protocol or origin is typing.Protocol
+
+
+_TYPEVARTUPLE_TYPES = {TypeVarTuple, getattr(typing, "TypeVarTuple", None)}
+
+
+def _is_unpacked_typevartuple(x) -> bool:
+    if get_origin(x) is not Unpack:
+        return False
+    args = get_args(x)
+    return (
+        bool(args)
+        and len(args) == 1
+        and type(args[0]) in _TYPEVARTUPLE_TYPES
+    )
+
+
+# Python 3.11+ _collect_type_vars was renamed to _collect_parameters
+if hasattr(typing, '_collect_type_vars'):
+    def _collect_type_vars(types, typevar_types=None):
+        """Collect all type variable contained in types in order of
+        first appearance (lexicographic order). For example::
+
+            _collect_type_vars((T, List[S, T])) == (T, S)
+        """
+        if typevar_types is None:
+            typevar_types = typing.TypeVar
+        tvars = []
+
+        # A required TypeVarLike cannot appear after a TypeVarLike with a default
+        # if it was a direct call to `Generic[]` or `Protocol[]`
+        enforce_default_ordering = _has_generic_or_protocol_as_origin()
+        default_encountered = False
+
+        # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
+        type_var_tuple_encountered = False
+
+        for t in types:
+            if _is_unpacked_typevartuple(t):
+                type_var_tuple_encountered = True
+            elif (
+                isinstance(t, typevar_types) and not isinstance(t, _UnpackAlias)
+                and t not in tvars
+            ):
+                if enforce_default_ordering:
+                    has_default = getattr(t, '__default__', NoDefault) is not NoDefault
+                    if has_default:
+                        if type_var_tuple_encountered:
+                            raise TypeError('Type parameter with a default'
+                                            ' follows TypeVarTuple')
+                        default_encountered = True
+                    elif default_encountered:
+                        raise TypeError(f'Type parameter {t!r} without a default'
+                                        ' follows type parameter with a default')
+
+                tvars.append(t)
+            if _should_collect_from_parameters(t):
+                tvars.extend([t for t in t.__parameters__ if t not in tvars])
+            elif isinstance(t, tuple):
+                # Collect nested type_vars
+                # tuple wrapped by  _prepare_paramspec_params(cls, params)
+                for x in t:
+                    for collected in _collect_type_vars([x]):
+                        if collected not in tvars:
+                            tvars.append(collected)
+        return tuple(tvars)
+
+    typing._collect_type_vars = _collect_type_vars
+else:
+    def _collect_parameters(args):
+        """Collect all type variables and parameter specifications in args
+        in order of first appearance (lexicographic order).
+
+        For example::
+
+            assert _collect_parameters((T, Callable[P, T])) == (T, P)
+        """
+        parameters = []
+
+        # A required TypeVarLike cannot appear after a TypeVarLike with default
+        # if it was a direct call to `Generic[]` or `Protocol[]`
+        enforce_default_ordering = _has_generic_or_protocol_as_origin()
+        default_encountered = False
+
+        # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
+        type_var_tuple_encountered = False
+
+        for t in args:
+            if isinstance(t, type):
+                # We don't want __parameters__ descriptor of a bare Python class.
+                pass
+            elif isinstance(t, tuple):
+                # `t` might be a tuple, when `ParamSpec` is substituted with
+                # `[T, int]`, or `[int, *Ts]`, etc.
+                for x in t:
+                    for collected in _collect_parameters([x]):
+                        if collected not in parameters:
+                            parameters.append(collected)
+            elif hasattr(t, '__typing_subst__'):
+                if t not in parameters:
+                    if enforce_default_ordering:
+                        has_default = (
+                            getattr(t, '__default__', NoDefault) is not NoDefault
+                        )
+
+                        if type_var_tuple_encountered and has_default:
+                            raise TypeError('Type parameter with a default'
+                                            ' follows TypeVarTuple')
+
+                        if has_default:
+                            default_encountered = True
+                        elif default_encountered:
+                            raise TypeError(f'Type parameter {t!r} without a default'
+                                            ' follows type parameter with a default')
+
+                    parameters.append(t)
+            else:
+                if _is_unpacked_typevartuple(t):
+                    type_var_tuple_encountered = True
+                for x in getattr(t, '__parameters__', ()):
+                    if x not in parameters:
+                        parameters.append(x)
+
+        return tuple(parameters)
+
+    if not _PEP_696_IMPLEMENTED:
+        typing._collect_parameters = _collect_parameters
+
+# Backport typing.NamedTuple as it exists in Python 3.13.
+# In 3.11, the ability to define generic `NamedTuple`s was supported.
+# This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8.
+# On 3.12, we added __orig_bases__ to call-based NamedTuples
+# On 3.13, we deprecated kwargs-based NamedTuples
+# Breakpoint: https://github.com/python/cpython/pull/105609
+if sys.version_info >= (3, 13):
+    NamedTuple = typing.NamedTuple
+else:
+    def _make_nmtuple(name, types, module, defaults=()):
+        fields = [n for n, t in types]
+        annotations = {n: typing._type_check(t, f"field {n} annotation must be a type")
+                       for n, t in types}
+        nm_tpl = collections.namedtuple(name, fields,
+                                        defaults=defaults, module=module)
+        nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = annotations
+        return nm_tpl
+
+    _prohibited_namedtuple_fields = typing._prohibited
+    _special_namedtuple_fields = frozenset({'__module__', '__name__', '__annotations__'})
+
+    class _NamedTupleMeta(type):
+        def __new__(cls, typename, bases, ns):
+            assert _NamedTuple in bases
+            for base in bases:
+                if base is not _NamedTuple and base is not typing.Generic:
+                    raise TypeError(
+                        'can only inherit from a NamedTuple type and Generic')
+            bases = tuple(tuple if base is _NamedTuple else base for base in bases)
+            if "__annotations__" in ns:
+                types = ns["__annotations__"]
+            elif "__annotate__" in ns:
+                # TODO: Use inspect.VALUE here, and make the annotations lazily evaluated
+                types = ns["__annotate__"](1)
+            else:
+                types = {}
+            default_names = []
+            for field_name in types:
+                if field_name in ns:
+                    default_names.append(field_name)
+                elif default_names:
+                    raise TypeError(f"Non-default namedtuple field {field_name} "
+                                    f"cannot follow default field"
+                                    f"{'s' if len(default_names) > 1 else ''} "
+                                    f"{', '.join(default_names)}")
+            nm_tpl = _make_nmtuple(
+                typename, types.items(),
+                defaults=[ns[n] for n in default_names],
+                module=ns['__module__']
+            )
+            nm_tpl.__bases__ = bases
+            if typing.Generic in bases:
+                if hasattr(typing, '_generic_class_getitem'):  # 3.12+
+                    nm_tpl.__class_getitem__ = classmethod(typing._generic_class_getitem)
+                else:
+                    class_getitem = typing.Generic.__class_getitem__.__func__
+                    nm_tpl.__class_getitem__ = classmethod(class_getitem)
+            # update from user namespace without overriding special namedtuple attributes
+            for key, val in ns.items():
+                if key in _prohibited_namedtuple_fields:
+                    raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
+                elif key not in _special_namedtuple_fields:
+                    if key not in nm_tpl._fields:
+                        setattr(nm_tpl, key, ns[key])
+                    try:
+                        set_name = type(val).__set_name__
+                    except AttributeError:
+                        pass
+                    else:
+                        try:
+                            set_name(val, nm_tpl, key)
+                        except BaseException as e:
+                            msg = (
+                                f"Error calling __set_name__ on {type(val).__name__!r} "
+                                f"instance {key!r} in {typename!r}"
+                            )
+                            # BaseException.add_note() existed on py311,
+                            # but the __set_name__ machinery didn't start
+                            # using add_note() until py312.
+                            # Making sure exceptions are raised in the same way
+                            # as in "normal" classes seems most important here.
+                            # Breakpoint: https://github.com/python/cpython/pull/95915
+                            if sys.version_info >= (3, 12):
+                                e.add_note(msg)
+                                raise
+                            else:
+                                raise RuntimeError(msg) from e
+
+            if typing.Generic in bases:
+                nm_tpl.__init_subclass__()
+            return nm_tpl
+
+    _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
+
+    def _namedtuple_mro_entries(bases):
+        assert NamedTuple in bases
+        return (_NamedTuple,)
+
+    def NamedTuple(typename, fields=_marker, /, **kwargs):
+        """Typed version of namedtuple.
+
+        Usage::
+
+            class Employee(NamedTuple):
+                name: str
+                id: int
+
+        This is equivalent to::
+
+            Employee = collections.namedtuple('Employee', ['name', 'id'])
+
+        The resulting class has an extra __annotations__ attribute, giving a
+        dict that maps field names to types.  (The field names are also in
+        the _fields attribute, which is part of the namedtuple API.)
+        An alternative equivalent functional syntax is also accepted::
+
+            Employee = NamedTuple('Employee', [('name', str), ('id', int)])
+        """
+        if fields is _marker:
+            if kwargs:
+                deprecated_thing = "Creating NamedTuple classes using keyword arguments"
+                deprecation_msg = (
+                    "{name} is deprecated and will be disallowed in Python {remove}. "
+                    "Use the class-based or functional syntax instead."
+                )
+            else:
+                deprecated_thing = "Failing to pass a value for the 'fields' parameter"
+                example = f"`{typename} = NamedTuple({typename!r}, [])`"
+                deprecation_msg = (
+                    "{name} is deprecated and will be disallowed in Python {remove}. "
+                    "To create a NamedTuple class with 0 fields "
+                    "using the functional syntax, "
+                    "pass an empty list, e.g. "
+                ) + example + "."
+        elif fields is None:
+            if kwargs:
+                raise TypeError(
+                    "Cannot pass `None` as the 'fields' parameter "
+                    "and also specify fields using keyword arguments"
+                )
+            else:
+                deprecated_thing = "Passing `None` as the 'fields' parameter"
+                example = f"`{typename} = NamedTuple({typename!r}, [])`"
+                deprecation_msg = (
+                    "{name} is deprecated and will be disallowed in Python {remove}. "
+                    "To create a NamedTuple class with 0 fields "
+                    "using the functional syntax, "
+                    "pass an empty list, e.g. "
+                ) + example + "."
+        elif kwargs:
+            raise TypeError("Either list of fields or keywords"
+                            " can be provided to NamedTuple, not both")
+        if fields is _marker or fields is None:
+            warnings.warn(
+                deprecation_msg.format(name=deprecated_thing, remove="3.15"),
+                DeprecationWarning,
+                stacklevel=2,
+            )
+            fields = kwargs.items()
+        nt = _make_nmtuple(typename, fields, module=_caller())
+        nt.__orig_bases__ = (NamedTuple,)
+        return nt
+
+    NamedTuple.__mro_entries__ = _namedtuple_mro_entries
+
+
+if hasattr(collections.abc, "Buffer"):
+    Buffer = collections.abc.Buffer
+else:
+    class Buffer(abc.ABC):  # noqa: B024
+        """Base class for classes that implement the buffer protocol.
+
+        The buffer protocol allows Python objects to expose a low-level
+        memory buffer interface. Before Python 3.12, it is not possible
+        to implement the buffer protocol in pure Python code, or even
+        to check whether a class implements the buffer protocol. In
+        Python 3.12 and higher, the ``__buffer__`` method allows access
+        to the buffer protocol from Python code, and the
+        ``collections.abc.Buffer`` ABC allows checking whether a class
+        implements the buffer protocol.
+
+        To indicate support for the buffer protocol in earlier versions,
+        inherit from this ABC, either in a stub file or at runtime,
+        or use ABC registration. This ABC provides no methods, because
+        there is no Python-accessible methods shared by pre-3.12 buffer
+        classes. It is useful primarily for static checks.
+
+        """
+
+    # As a courtesy, register the most common stdlib buffer classes.
+    Buffer.register(memoryview)
+    Buffer.register(bytearray)
+    Buffer.register(bytes)
+
+
+# Backport of types.get_original_bases, available on 3.12+ in CPython
+if hasattr(_types, "get_original_bases"):
+    get_original_bases = _types.get_original_bases
+else:
+    def get_original_bases(cls, /):
+        """Return the class's "original" bases prior to modification by `__mro_entries__`.
+
+        Examples::
+
+            from typing import TypeVar, Generic
+            from typing_extensions import NamedTuple, TypedDict
+
+            T = TypeVar("T")
+            class Foo(Generic[T]): ...
+            class Bar(Foo[int], float): ...
+            class Baz(list[str]): ...
+            Eggs = NamedTuple("Eggs", [("a", int), ("b", str)])
+            Spam = TypedDict("Spam", {"a": int, "b": str})
+
+            assert get_original_bases(Bar) == (Foo[int], float)
+            assert get_original_bases(Baz) == (list[str],)
+            assert get_original_bases(Eggs) == (NamedTuple,)
+            assert get_original_bases(Spam) == (TypedDict,)
+            assert get_original_bases(int) == (object,)
+        """
+        try:
+            return cls.__dict__.get("__orig_bases__", cls.__bases__)
+        except AttributeError:
+            raise TypeError(
+                f'Expected an instance of type, not {type(cls).__name__!r}'
+            ) from None
+
+
+# NewType is a class on Python 3.10+, making it pickleable
+# The error message for subclassing instances of NewType was improved on 3.11+
+# Breakpoint: https://github.com/python/cpython/pull/30268
+if sys.version_info >= (3, 11):
+    NewType = typing.NewType
+else:
+    class NewType:
+        """NewType creates simple unique types with almost zero
+        runtime overhead. NewType(name, tp) is considered a subtype of tp
+        by static type checkers. At runtime, NewType(name, tp) returns
+        a dummy callable that simply returns its argument. Usage::
+            UserId = NewType('UserId', int)
+            def name_by_id(user_id: UserId) -> str:
+                ...
+            UserId('user')          # Fails type check
+            name_by_id(42)          # Fails type check
+            name_by_id(UserId(42))  # OK
+            num = UserId(5) + 1     # type: int
+        """
+
+        def __call__(self, obj, /):
+            return obj
+
+        def __init__(self, name, tp):
+            self.__qualname__ = name
+            if '.' in name:
+                name = name.rpartition('.')[-1]
+            self.__name__ = name
+            self.__supertype__ = tp
+            def_mod = _caller()
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+
+        def __mro_entries__(self, bases):
+            # We defined __mro_entries__ to get a better error message
+            # if a user attempts to subclass a NewType instance. bpo-46170
+            supercls_name = self.__name__
+
+            class Dummy:
+                def __init_subclass__(cls):
+                    subcls_name = cls.__name__
+                    raise TypeError(
+                        f"Cannot subclass an instance of NewType. "
+                        f"Perhaps you were looking for: "
+                        f"`{subcls_name} = NewType({subcls_name!r}, {supercls_name})`"
+                    )
+
+            return (Dummy,)
+
+        def __repr__(self):
+            return f'{self.__module__}.{self.__qualname__}'
+
+        def __reduce__(self):
+            return self.__qualname__
+
+        # Breakpoint: https://github.com/python/cpython/pull/21515
+        if sys.version_info >= (3, 10):
+            # PEP 604 methods
+            # It doesn't make sense to have these methods on Python <3.10
+
+            def __or__(self, other):
+                return typing.Union[self, other]
+
+            def __ror__(self, other):
+                return typing.Union[other, self]
+
+
+# Breakpoint: https://github.com/python/cpython/pull/149172
+if sys.version_info >= (3, 15):
+    TypeAliasType = typing.TypeAliasType
+# <=3.14
+else:
+    # Breakpoint: https://github.com/python/cpython/pull/103764
+    if sys.version_info >= (3, 12):
+        # 3.12-3.14
+        def _is_unionable(obj):
+            """Corresponds to is_unionable() in unionobject.c in CPython."""
+            return obj is None or isinstance(obj, (
+                type,
+                _types.GenericAlias,
+                _types.UnionType,
+                typing.TypeAliasType,
+                TypeAliasType,
+            ))
+    else:
+        # <=3.11
+        def _is_unionable(obj):
+            """Corresponds to is_unionable() in unionobject.c in CPython."""
+            return obj is None or isinstance(obj, (
+                type,
+                _types.GenericAlias,
+                _types.UnionType,
+                TypeAliasType,
+            ))
+
+    if sys.version_info < (3, 10):
+        # Copied and pasted from https://github.com/python/cpython/blob/986a4e1b6fcae7fe7a1d0a26aea446107dd58dd2/Objects/genericaliasobject.c#L568-L582,
+        # so that we emulate the behaviour of `types.GenericAlias`
+        # on the latest versions of CPython
+        _ATTRIBUTE_DELEGATION_EXCLUSIONS = frozenset({
+            "__class__",
+            "__bases__",
+            "__origin__",
+            "__args__",
+            "__unpacked__",
+            "__parameters__",
+            "__typing_unpacked_tuple_args__",
+            "__mro_entries__",
+            "__reduce_ex__",
+            "__reduce__",
+            "__copy__",
+            "__deepcopy__",
+        })
+
+        class _TypeAliasGenericAlias(typing._GenericAlias, _root=True):
+            def __getattr__(self, attr):
+                if attr in _ATTRIBUTE_DELEGATION_EXCLUSIONS:
+                    return object.__getattr__(self, attr)
+                return getattr(self.__origin__, attr)
+
+
+    class TypeAliasType:
+        """Create named, parameterized type aliases.
+
+        This provides a backport of the new `type` statement in Python 3.12:
+
+            type ListOrSet[T] = list[T] | set[T]
+
+        is equivalent to:
+
+            T = TypeVar("T")
+            ListOrSet = TypeAliasType("ListOrSet", list[T] | set[T], type_params=(T,))
+
+        The name ListOrSet can then be used as an alias for the type it refers to.
+
+        The type_params argument should contain all the type parameters used
+        in the value of the type alias. If the alias is not generic, this
+        argument is omitted.
+
+        Static type checkers should only support type aliases declared using
+        TypeAliasType that follow these rules:
+
+        - The first argument (the name) must be a string literal.
+        - The TypeAliasType instance must be immediately assigned to a variable
+          of the same name. (For example, 'X = TypeAliasType("Y", int)' is invalid,
+          as is 'X, Y = TypeAliasType("X", int), TypeAliasType("Y", int)').
+
+        """
+
+        def __init__(self, name: str, value, *, type_params=()):
+            if not isinstance(name, str):
+                raise TypeError("TypeAliasType name must be a string")
+            if not isinstance(type_params, tuple):
+                raise TypeError("type_params must be a tuple")
+            self.__value__ = value
+            self.__type_params__ = type_params
+
+            default_value_encountered = False
+            parameters = []
+            for type_param in type_params:
+                if (
+                    not isinstance(type_param, (TypeVar, TypeVarTuple, ParamSpec))
+                    # <=3.11
+                    # Unpack Backport passes isinstance(type_param, TypeVar)
+                    or _is_unpack(type_param)
+                ):
+                    raise TypeError(f"Expected a type param, got {type_param!r}")
+                has_default = (
+                    getattr(type_param, '__default__', NoDefault) is not NoDefault
+                )
+                if default_value_encountered and not has_default:
+                    raise TypeError(f"non-default type parameter '{type_param!r}'"
+                                    " follows default type parameter")
+                if has_default:
+                    default_value_encountered = True
+                if isinstance(type_param, TypeVarTuple):
+                    parameters.extend(type_param)
+                else:
+                    parameters.append(type_param)
+            self.__parameters__ = tuple(parameters)
+            def_mod = _caller()
+            if def_mod != 'typing_extensions':
+                self.__module__ = def_mod
+            # Setting this attribute closes the TypeAliasType from further modification
+            self.__name__ = name
+
+        def __setattr__(self, name: str, value: object, /) -> None:
+            if hasattr(self, "__name__") and name != "__module__":
+                self._raise_attribute_error(name)
+            super().__setattr__(name, value)
+
+        def __delattr__(self, name: str, /) -> Never:
+            self._raise_attribute_error(name)
+
+        def _raise_attribute_error(self, name: str) -> Never:
+            # Match the Python 3.12 error messages exactly
+            if name == "__name__":
+                raise AttributeError("readonly attribute")
+            elif name in {"__value__", "__type_params__", "__parameters__"}:
+                raise AttributeError(
+                    f"attribute '{name}' of 'typing.TypeAliasType' objects "
+                    "is not writable"
+                )
+            else:
+                raise AttributeError(
+                    f"'typing.TypeAliasType' object has no attribute '{name}'"
+                )
+
+        def __repr__(self) -> str:
+            return self.__name__
+
+        if sys.version_info < (3, 11):
+            def _check_single_param(self, param, recursion=0):
+                # Allow [], [int], [int, str], [int, ...], [int, T]
+                if param is ...:
+                    return ...
+                if param is None:
+                    return None
+                # Note in <= 3.9 _ConcatenateGenericAlias inherits from list
+                if isinstance(param, list) and recursion == 0:
+                    return [self._check_single_param(arg, recursion+1)
+                            for arg in param]
+                return typing._type_check(
+                        param, f'Subscripting {self.__name__} requires a type.'
+                    )
+
+        def _check_parameters(self, parameters):
+            if sys.version_info < (3, 11):
+                return tuple(
+                    self._check_single_param(item)
+                    for item in parameters
+                )
+            return tuple(typing._type_check(
+                        item, f'Subscripting {self.__name__} requires a type.'
+                    )
+                    for item in parameters
+            )
+
+        def __getitem__(self, parameters):
+            if not self.__type_params__:
+                raise TypeError("Only generic type aliases are subscriptable")
+            if not isinstance(parameters, tuple):
+                parameters = (parameters,)
+            # Using 3.9 here will create problems with Concatenate
+            if sys.version_info >= (3, 10):
+                return _types.GenericAlias(self, parameters)
+            type_vars = _collect_type_vars(parameters)
+            parameters = self._check_parameters(parameters)
+            alias = _TypeAliasGenericAlias(self, parameters)
+            # alias.__parameters__ is not complete if Concatenate is present
+            # as it is converted to a list from which no parameters are extracted.
+            if alias.__parameters__ != type_vars:
+                alias.__parameters__ = type_vars
+            return alias
+
+        def __reduce__(self):
+            return self.__name__
+
+        def __init_subclass__(cls, *args, **kwargs):
+            raise TypeError(
+                "type 'typing_extensions.TypeAliasType' is not an acceptable base type"
+            )
+
+        # The presence of this method convinces typing._type_check
+        # that TypeAliasTypes are types.
+        def __call__(self):
+            raise TypeError("Type alias is not callable")
+
+        # Breakpoint: https://github.com/python/cpython/pull/21515
+        if sys.version_info >= (3, 10):
+            def __or__(self, right):
+                # For forward compatibility with 3.12, reject Unions
+                # that are not accepted by the built-in Union.
+                if not _is_unionable(right):
+                    return NotImplemented
+                return typing.Union[self, right]
+
+            def __ror__(self, left):
+                if not _is_unionable(left):
+                    return NotImplemented
+                return typing.Union[left, self]
+
+
+if hasattr(typing, "is_protocol"):
+    is_protocol = typing.is_protocol
+    get_protocol_members = typing.get_protocol_members
+else:
+    def is_protocol(tp: type, /) -> bool:
+        """Return True if the given type is a Protocol.
+
+        Example::
+
+            >>> from typing_extensions import Protocol, is_protocol
+            >>> class P(Protocol):
+            ...     def a(self) -> str: ...
+            ...     b: int
+            >>> is_protocol(P)
+            True
+            >>> is_protocol(int)
+            False
+        """
+        return (
+            isinstance(tp, type)
+            and getattr(tp, '_is_protocol', False)
+            and tp is not Protocol
+            and tp is not typing.Protocol
+        )
+
+    def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]:
+        """Return the set of members defined in a Protocol.
+
+        Example::
+
+            >>> from typing_extensions import Protocol, get_protocol_members
+            >>> class P(Protocol):
+            ...     def a(self) -> str: ...
+            ...     b: int
+            >>> get_protocol_members(P) == frozenset({'a', 'b'})
+            True
+
+        Raise a TypeError for arguments that are not Protocols.
+        """
+        if not is_protocol(tp):
+            raise TypeError(f'{tp!r} is not a Protocol')
+        if hasattr(tp, '__protocol_attrs__'):
+            return frozenset(tp.__protocol_attrs__)
+        return frozenset(_get_protocol_attrs(tp))
+
+
+if hasattr(typing, "Doc"):
+    Doc = typing.Doc
+else:
+    class Doc:
+        """Define the documentation of a type annotation using ``Annotated``, to be
+         used in class attributes, function and method parameters, return values,
+         and variables.
+
+        The value should be a positional-only string literal to allow static tools
+        like editors and documentation generators to use it.
+
+        This complements docstrings.
+
+        The string value passed is available in the attribute ``documentation``.
+
+        Example::
+
+            >>> from typing_extensions import Annotated, Doc
+            >>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ...
+        """
+        def __init__(self, documentation: str, /) -> None:
+            self.documentation = documentation
+
+        def __repr__(self) -> str:
+            return f"Doc({self.documentation!r})"
+
+        def __hash__(self) -> int:
+            return hash(self.documentation)
+
+        def __eq__(self, other: object) -> bool:
+            if not isinstance(other, Doc):
+                return NotImplemented
+            return self.documentation == other.documentation
+
+
+_CapsuleType = getattr(_types, "CapsuleType", None)
+
+if _CapsuleType is None:
+    try:
+        import _socket
+    except ImportError:
+        pass
+    else:
+        _CAPI = getattr(_socket, "CAPI", None)
+        if _CAPI is not None:
+            _CapsuleType = type(_CAPI)
+
+if _CapsuleType is not None:
+    CapsuleType = _CapsuleType
+    __all__.append("CapsuleType")
+
+
+if sys.version_info >= (3, 14):
+    from annotationlib import Format, get_annotations
+else:
+    # Available since Python 3.14.0a3
+    # PR: https://github.com/python/cpython/pull/124415
+    class Format(enum.IntEnum):
+        VALUE = 1
+        VALUE_WITH_FAKE_GLOBALS = 2
+        FORWARDREF = 3
+        STRING = 4
+
+    # Available since Python 3.14.0a1
+    # PR: https://github.com/python/cpython/pull/119891
+    def get_annotations(obj, *, globals=None, locals=None, eval_str=False,
+                        format=Format.VALUE):
+        """Compute the annotations dict for an object.
+
+        obj may be a callable, class, or module.
+        Passing in an object of any other type raises TypeError.
+
+        Returns a dict.  get_annotations() returns a new dict every time
+        it's called; calling it twice on the same object will return two
+        different but equivalent dicts.
+
+        This is a backport of `inspect.get_annotations`, which has been
+        in the standard library since Python 3.10. See the standard library
+        documentation for more:
+
+            https://docs.python.org/3/library/inspect.html#inspect.get_annotations
+
+        This backport adds the *format* argument introduced by PEP 649. The
+        three formats supported are:
+        * VALUE: the annotations are returned as-is. This is the default and
+          it is compatible with the behavior on previous Python versions.
+        * FORWARDREF: return annotations as-is if possible, but replace any
+          undefined names with ForwardRef objects. The implementation proposed by
+          PEP 649 relies on language changes that cannot be backported; the
+          typing-extensions implementation simply returns the same result as VALUE.
+        * STRING: return annotations as strings, in a format close to the original
+          source. Again, this behavior cannot be replicated directly in a backport.
+          As an approximation, typing-extensions retrieves the annotations under
+          VALUE semantics and then stringifies them.
+
+        The purpose of this backport is to allow users who would like to use
+        FORWARDREF or STRING semantics once PEP 649 is implemented, but who also
+        want to support earlier Python versions, to simply write:
+
+            typing_extensions.get_annotations(obj, format=Format.FORWARDREF)
+
+        """
+        format = Format(format)
+        if format is Format.VALUE_WITH_FAKE_GLOBALS:
+            raise ValueError(
+                "The VALUE_WITH_FAKE_GLOBALS format is for internal use only"
+            )
+
+        if eval_str and format is not Format.VALUE:
+            raise ValueError("eval_str=True is only supported with format=Format.VALUE")
+
+        if isinstance(obj, type):
+            # class
+            obj_dict = getattr(obj, '__dict__', None)
+            if obj_dict and hasattr(obj_dict, 'get'):
+                ann = obj_dict.get('__annotations__', None)
+                if isinstance(ann, _types.GetSetDescriptorType):
+                    ann = None
+            else:
+                ann = None
+
+            obj_globals = None
+            module_name = getattr(obj, '__module__', None)
+            if module_name:
+                module = sys.modules.get(module_name, None)
+                if module:
+                    obj_globals = getattr(module, '__dict__', None)
+            obj_locals = dict(vars(obj))
+            unwrap = obj
+        elif isinstance(obj, _types.ModuleType):
+            # module
+            ann = getattr(obj, '__annotations__', None)
+            obj_globals = obj.__dict__
+            obj_locals = None
+            unwrap = None
+        elif callable(obj):
+            # this includes types.Function, types.BuiltinFunctionType,
+            # types.BuiltinMethodType, functools.partial, functools.singledispatch,
+            # "class funclike" from Lib/test/test_inspect... on and on it goes.
+            ann = getattr(obj, '__annotations__', None)
+            obj_globals = getattr(obj, '__globals__', None)
+            obj_locals = None
+            unwrap = obj
+        elif hasattr(obj, '__annotations__'):
+            ann = obj.__annotations__
+            obj_globals = obj_locals = unwrap = None
+        else:
+            raise TypeError(f"{obj!r} is not a module, class, or callable.")
+
+        if ann is None:
+            return {}
+
+        if not isinstance(ann, dict):
+            raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")
+
+        if not ann:
+            return {}
+
+        if not eval_str:
+            if format is Format.STRING:
+                return {
+                    key: value if isinstance(value, str) else typing._type_repr(value)
+                    for key, value in ann.items()
+                }
+            return dict(ann)
+
+        if unwrap is not None:
+            while True:
+                if hasattr(unwrap, '__wrapped__'):
+                    unwrap = unwrap.__wrapped__
+                    continue
+                if isinstance(unwrap, functools.partial):
+                    unwrap = unwrap.func
+                    continue
+                break
+            if hasattr(unwrap, "__globals__"):
+                obj_globals = unwrap.__globals__
+
+        if globals is None:
+            globals = obj_globals
+        if locals is None:
+            locals = obj_locals or {}
+
+        # "Inject" type parameters into the local namespace
+        # (unless they are shadowed by assignments *in* the local namespace),
+        # as a way of emulating annotation scopes when calling `eval()`
+        if type_params := getattr(obj, "__type_params__", ()):
+            locals = {param.__name__: param for param in type_params} | locals
+
+        return_value = {key:
+            value if not isinstance(value, str) else eval(value, globals, locals)
+            for key, value in ann.items() }
+        return return_value
+
+
+if hasattr(typing, "evaluate_forward_ref"):
+    evaluate_forward_ref = typing.evaluate_forward_ref
+else:
+    # Implements annotationlib.ForwardRef.evaluate
+    def _eval_with_owner(
+        forward_ref, *, owner=None, globals=None, locals=None, type_params=None
+    ):
+        if forward_ref.__forward_evaluated__:
+            return forward_ref.__forward_value__
+        if getattr(forward_ref, "__cell__", None) is not None:
+            try:
+                value = forward_ref.__cell__.cell_contents
+            except ValueError:
+                pass
+            else:
+                forward_ref.__forward_evaluated__ = True
+                forward_ref.__forward_value__ = value
+                return value
+        if owner is None:
+            owner = getattr(forward_ref, "__owner__", None)
+
+        if (
+            globals is None
+            and getattr(forward_ref, "__forward_module__", None) is not None
+        ):
+            globals = getattr(
+                sys.modules.get(forward_ref.__forward_module__, None), "__dict__", None
+            )
+        if globals is None:
+            globals = getattr(forward_ref, "__globals__", None)
+        if globals is None:
+            if isinstance(owner, type):
+                module_name = getattr(owner, "__module__", None)
+                if module_name:
+                    module = sys.modules.get(module_name, None)
+                    if module:
+                        globals = getattr(module, "__dict__", None)
+            elif isinstance(owner, _types.ModuleType):
+                globals = getattr(owner, "__dict__", None)
+            elif callable(owner):
+                globals = getattr(owner, "__globals__", None)
+
+        # If we pass None to eval() below, the globals of this module are used.
+        if globals is None:
+            globals = {}
+
+        if locals is None:
+            locals = {}
+            if isinstance(owner, type):
+                locals.update(vars(owner))
+
+        if type_params is None and owner is not None:
+            # "Inject" type parameters into the local namespace
+            # (unless they are shadowed by assignments *in* the local namespace),
+            # as a way of emulating annotation scopes when calling `eval()`
+            type_params = getattr(owner, "__type_params__", None)
+
+        # Type parameters exist in their own scope, which is logically
+        # between the locals and the globals. We simulate this by adding
+        # them to the globals.
+        if type_params is not None:
+            globals = dict(globals)
+            for param in type_params:
+                globals[param.__name__] = param
+
+        arg = forward_ref.__forward_arg__
+        if arg.isidentifier() and not keyword.iskeyword(arg):
+            if arg in locals:
+                value = locals[arg]
+            elif arg in globals:
+                value = globals[arg]
+            elif hasattr(builtins, arg):
+                return getattr(builtins, arg)
+            else:
+                raise NameError(arg)
+        else:
+            code = forward_ref.__forward_code__
+            value = eval(code, globals, locals)
+        forward_ref.__forward_evaluated__ = True
+        forward_ref.__forward_value__ = value
+        return value
+
+    def evaluate_forward_ref(
+        forward_ref,
+        *,
+        owner=None,
+        globals=None,
+        locals=None,
+        type_params=None,
+        format=None,
+        _recursive_guard=frozenset(),
+    ):
+        """Evaluate a forward reference as a type hint.
+
+        This is similar to calling the ForwardRef.evaluate() method,
+        but unlike that method, evaluate_forward_ref() also:
+
+        * Recursively evaluates forward references nested within the type hint.
+        * Rejects certain objects that are not valid type hints.
+        * Replaces type hints that evaluate to None with types.NoneType.
+        * Supports the *FORWARDREF* and *STRING* formats.
+
+        *forward_ref* must be an instance of ForwardRef. *owner*, if given,
+        should be the object that holds the annotations that the forward reference
+        derived from, such as a module, class object, or function. It is used to
+        infer the namespaces to use for looking up names. *globals* and *locals*
+        can also be explicitly given to provide the global and local namespaces.
+        *type_params* is a tuple of type parameters that are in scope when
+        evaluating the forward reference. This parameter must be provided (though
+        it may be an empty tuple) if *owner* is not given and the forward reference
+        does not already have an owner set. *format* specifies the format of the
+        annotation and is a member of the annotationlib.Format enum.
+
+        """
+        if format == Format.STRING:
+            return forward_ref.__forward_arg__
+        if forward_ref.__forward_arg__ in _recursive_guard:
+            return forward_ref
+
+        # Evaluate the forward reference
+        try:
+            value = _eval_with_owner(
+                forward_ref,
+                owner=owner,
+                globals=globals,
+                locals=locals,
+                type_params=type_params,
+            )
+        except NameError:
+            if format == Format.FORWARDREF:
+                return forward_ref
+            else:
+                raise
+
+        if isinstance(value, str):
+            value = ForwardRef(value)
+
+        # Recursively evaluate the type
+        if isinstance(value, ForwardRef):
+            if getattr(value, "__forward_module__", True) is not None:
+                globals = None
+            return evaluate_forward_ref(
+                value,
+                globals=globals,
+                locals=locals,
+                 type_params=type_params, owner=owner,
+                _recursive_guard=_recursive_guard, format=format
+            )
+        if sys.version_info < (3, 12, 5) and type_params:
+            # Make use of type_params
+            locals = dict(locals) if locals else {}
+            for tvar in type_params:
+                if tvar.__name__ not in locals:  # lets not overwrite something present
+                    locals[tvar.__name__] = tvar
+        if sys.version_info < (3, 12, 5):
+            return typing._eval_type(
+                value,
+                globals,
+                locals,
+                recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
+            )
+        else:
+            return typing._eval_type(
+                value,
+                globals,
+                locals,
+                type_params,
+                recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
+            )
+
+
+if sys.version_info >= (3, 14, 0, "beta"):
+    type_repr = annotationlib.type_repr
+else:
+    def type_repr(value):
+        """Convert a Python value to a format suitable for use with the STRING format.
+
+        This is intended as a helper for tools that support the STRING format but do
+        not have access to the code that originally produced the annotations. It uses
+        repr() for most objects.
+
+        """
+        if isinstance(value, (type, _types.FunctionType, _types.BuiltinFunctionType)):
+            if value.__module__ == "builtins":
+                return value.__qualname__
+            return f"{value.__module__}.{value.__qualname__}"
+        if value is ...:
+            return "..."
+        return repr(value)
+
+
+# Aliases for items that are in typing in all supported versions.
+# We use hasattr() checks so this library will continue to import on
+# future versions of Python that may remove these names.
+_typing_names = [
+    "AbstractSet",
+    "AnyStr",
+    "BinaryIO",
+    "Callable",
+    "Collection",
+    "Container",
+    "Dict",
+    "FrozenSet",
+    "Hashable",
+    "IO",
+    "ItemsView",
+    "Iterable",
+    "Iterator",
+    "KeysView",
+    "List",
+    "Mapping",
+    "MappingView",
+    "Match",
+    "MutableMapping",
+    "MutableSequence",
+    "MutableSet",
+    "Optional",
+    "Pattern",
+    "Reversible",
+    "Sequence",
+    "Set",
+    "Sized",
+    "TextIO",
+    "Tuple",
+    "Union",
+    "ValuesView",
+    "cast",
+    "no_type_check",
+    # This is private, but it was defined by typing_extensions for a long time
+    # and some users rely on it.
+    "_AnnotatedAlias",
+]
+
+# Breakpoint: https://github.com/python/cpython/pull/133602
+if sys.version_info < (3, 15, 0):
+    _typing_names.append("no_type_check_decorator")
+    __all__.append("no_type_check_decorator")
+
+globals().update(
+    {name: getattr(typing, name) for name in _typing_names if hasattr(typing, name)}
+)
+# These are defined unconditionally because they are used in
+# typing-extensions itself.
+Generic = typing.Generic
+ForwardRef = typing.ForwardRef
+Annotated = typing.Annotated
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt
new file mode 100644
index 00000000000..e6183d0276b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2008-2020 Andrey Petrov and contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py
new file mode 100644
index 00000000000..3fe782c8a45
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py
@@ -0,0 +1,211 @@
+"""
+Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
+"""
+
+from __future__ import annotations
+
+# Set default logging handler to avoid "No handler found" warnings.
+import logging
+import sys
+import typing
+import warnings
+from logging import NullHandler
+
+from . import exceptions
+from ._base_connection import _TYPE_BODY
+from ._collections import HTTPHeaderDict
+from ._version import __version__
+from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url
+from .filepost import _TYPE_FIELDS, encode_multipart_formdata
+from .poolmanager import PoolManager, ProxyManager, proxy_from_url
+from .response import BaseHTTPResponse, HTTPResponse
+from .util.request import make_headers
+from .util.retry import Retry
+from .util.timeout import Timeout
+
+# Ensure that Python is compiled with OpenSSL 1.1.1+
+# If the 'ssl' module isn't available at all that's
+# fine, we only care if the module is available.
+try:
+    import ssl
+except ImportError:
+    pass
+else:
+    if not ssl.OPENSSL_VERSION.startswith("OpenSSL "):  # Defensive:
+        warnings.warn(
+            "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
+            f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
+            "See: https://github.com/urllib3/urllib3/issues/3020",
+            exceptions.NotOpenSSLWarning,
+        )
+    elif ssl.OPENSSL_VERSION_INFO < (1, 1, 1):  # Defensive:
+        raise ImportError(
+            "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
+            f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
+            "See: https://github.com/urllib3/urllib3/issues/2168"
+        )
+
+__author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
+__license__ = "MIT"
+__version__ = __version__
+
+__all__ = (
+    "HTTPConnectionPool",
+    "HTTPHeaderDict",
+    "HTTPSConnectionPool",
+    "PoolManager",
+    "ProxyManager",
+    "HTTPResponse",
+    "Retry",
+    "Timeout",
+    "add_stderr_logger",
+    "connection_from_url",
+    "disable_warnings",
+    "encode_multipart_formdata",
+    "make_headers",
+    "proxy_from_url",
+    "request",
+    "BaseHTTPResponse",
+)
+
+logging.getLogger(__name__).addHandler(NullHandler())
+
+
+def add_stderr_logger(
+    level: int = logging.DEBUG,
+) -> logging.StreamHandler[typing.TextIO]:
+    """
+    Helper for quickly adding a StreamHandler to the logger. Useful for
+    debugging.
+
+    Returns the handler after adding it.
+    """
+    # This method needs to be in this __init__.py to get the __name__ correct
+    # even if urllib3 is vendored within another package.
+    logger = logging.getLogger(__name__)
+    handler = logging.StreamHandler()
+    handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
+    logger.addHandler(handler)
+    logger.setLevel(level)
+    logger.debug("Added a stderr logging handler to logger: %s", __name__)
+    return handler
+
+
+# ... Clean up.
+del NullHandler
+
+
+# All warning filters *must* be appended unless you're really certain that they
+# shouldn't be: otherwise, it's very hard for users to use most Python
+# mechanisms to silence them.
+# SecurityWarning's always go off by default.
+warnings.simplefilter("always", exceptions.SecurityWarning, append=True)
+# InsecurePlatformWarning's don't vary between requests, so we keep it default.
+warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True)
+
+
+def disable_warnings(category: type[Warning] = exceptions.HTTPWarning) -> None:
+    """
+    Helper for quickly disabling all urllib3 warnings.
+    """
+    warnings.simplefilter("ignore", category)
+
+
+_DEFAULT_POOL = PoolManager()
+
+
+def request(
+    method: str,
+    url: str,
+    *,
+    body: _TYPE_BODY | None = None,
+    fields: _TYPE_FIELDS | None = None,
+    headers: typing.Mapping[str, str] | None = None,
+    preload_content: bool | None = True,
+    decode_content: bool | None = True,
+    redirect: bool | None = True,
+    retries: Retry | bool | int | None = None,
+    timeout: Timeout | float | int | None = 3,
+    json: typing.Any | None = None,
+) -> BaseHTTPResponse:
+    """
+    A convenience, top-level request method. It uses a module-global ``PoolManager`` instance.
+    Therefore, its side effects could be shared across dependencies relying on it.
+    To avoid side effects create a new ``PoolManager`` instance and use it instead.
+    The method does not accept low-level ``**urlopen_kw`` keyword arguments.
+
+    :param method:
+        HTTP request method (such as GET, POST, PUT, etc.)
+
+    :param url:
+        The URL to perform the request on.
+
+    :param body:
+        Data to send in the request body, either :class:`str`, :class:`bytes`,
+        an iterable of :class:`str`/:class:`bytes`, or a file-like object.
+
+    :param fields:
+        Data to encode and send in the request body.
+
+    :param headers:
+        Dictionary of custom headers to send, such as User-Agent,
+        If-None-Match, etc.
+
+    :param bool preload_content:
+        If True, the response's body will be preloaded into memory.
+
+    :param bool decode_content:
+        If True, will attempt to decode the body based on the
+        'content-encoding' header.
+
+    :param redirect:
+        If True, automatically handle redirects (status codes 301, 302,
+        303, 307, 308). Each redirect counts as a retry. Disabling retries
+        will disable redirect, too.
+
+    :param retries:
+        Configure the number of retries to allow before raising a
+        :class:`~urllib3.exceptions.MaxRetryError` exception.
+
+        If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a
+        :class:`~urllib3.util.retry.Retry` object for fine-grained control
+        over different types of retries.
+        Pass an integer number to retry connection errors that many times,
+        but no other types of errors. Pass zero to never retry.
+
+        If ``False``, then retries are disabled and any exception is raised
+        immediately. Also, instead of raising a MaxRetryError on redirects,
+        the redirect response will be returned.
+
+    :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
+
+    :param timeout:
+        If specified, overrides the default timeout for this one
+        request. It may be a float (in seconds) or an instance of
+        :class:`urllib3.util.Timeout`.
+
+    :param json:
+        Data to encode and send as JSON with UTF-encoded in the request body.
+        The ``"Content-Type"`` header will be set to ``"application/json"``
+        unless specified otherwise.
+    """
+
+    return _DEFAULT_POOL.request(
+        method,
+        url,
+        body=body,
+        fields=fields,
+        headers=headers,
+        preload_content=preload_content,
+        decode_content=decode_content,
+        redirect=redirect,
+        retries=retries,
+        timeout=timeout,
+        json=json,
+    )
+
+
+if sys.platform == "emscripten":
+    from .contrib.emscripten import inject_into_urllib3  # noqa: 401
+
+    inject_into_urllib3()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py
new file mode 100644
index 00000000000..992ec1657a9
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py
@@ -0,0 +1,167 @@
+from __future__ import annotations
+
+import typing
+
+from .util.connection import _TYPE_SOCKET_OPTIONS
+from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT
+from .util.url import Url
+
+_TYPE_BODY = typing.Union[
+    bytes, typing.IO[typing.Any], typing.Iterable[bytes | str], str
+]
+
+
+class ProxyConfig(typing.NamedTuple):
+    ssl_context: ssl.SSLContext | None
+    use_forwarding_for_https: bool
+    assert_hostname: None | str | typing.Literal[False]
+    assert_fingerprint: str | None
+
+
+class _ResponseOptions(typing.NamedTuple):
+    # TODO: Remove this in favor of a better
+    # HTTP request/response lifecycle tracking.
+    request_method: str
+    request_url: str
+    preload_content: bool
+    decode_content: bool
+    enforce_content_length: bool
+
+
+if typing.TYPE_CHECKING:
+    import ssl
+    from typing import Protocol
+
+    from .response import BaseHTTPResponse
+
+    class BaseHTTPConnection(Protocol):
+        default_port: typing.ClassVar[int]
+        default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
+
+        host: str
+        port: int
+        timeout: None | (
+            float
+        )  # Instance doesn't store _DEFAULT_TIMEOUT, must be resolved.
+        blocksize: int
+        source_address: tuple[str, int] | None
+        socket_options: _TYPE_SOCKET_OPTIONS | None
+
+        proxy: Url | None
+        proxy_config: ProxyConfig | None
+
+        is_verified: bool
+        proxy_is_verified: bool | None
+
+        def __init__(
+            self,
+            host: str,
+            port: int | None = None,
+            *,
+            timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+            source_address: tuple[str, int] | None = None,
+            blocksize: int = 8192,
+            socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
+            proxy: Url | None = None,
+            proxy_config: ProxyConfig | None = None,
+        ) -> None: ...
+
+        def set_tunnel(
+            self,
+            host: str,
+            port: int | None = None,
+            headers: typing.Mapping[str, str] | None = None,
+            scheme: str = "http",
+        ) -> None: ...
+
+        def connect(self) -> None: ...
+
+        def request(
+            self,
+            method: str,
+            url: str,
+            body: _TYPE_BODY | None = None,
+            headers: typing.Mapping[str, str] | None = None,
+            # We know *at least* botocore is depending on the order of the
+            # first 3 parameters so to be safe we only mark the later ones
+            # as keyword-only to ensure we have space to extend.
+            *,
+            chunked: bool = False,
+            preload_content: bool = True,
+            decode_content: bool = True,
+            enforce_content_length: bool = True,
+        ) -> None: ...
+
+        def getresponse(self) -> BaseHTTPResponse: ...
+
+        def close(self) -> None: ...
+
+        @property
+        def is_closed(self) -> bool:
+            """Whether the connection either is brand new or has been previously closed.
+            If this property is True then both ``is_connected`` and ``has_connected_to_proxy``
+            properties must be False.
+            """
+
+        @property
+        def is_connected(self) -> bool:
+            """Whether the connection is actively connected to any origin (proxy or target)"""
+
+        @property
+        def has_connected_to_proxy(self) -> bool:
+            """Whether the connection has successfully connected to its proxy.
+            This returns False if no proxy is in use. Used to determine whether
+            errors are coming from the proxy layer or from tunnelling to the target origin.
+            """
+
+    class BaseHTTPSConnection(BaseHTTPConnection, Protocol):
+        default_port: typing.ClassVar[int]
+        default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
+
+        # Certificate verification methods
+        cert_reqs: int | str | None
+        assert_hostname: None | str | typing.Literal[False]
+        assert_fingerprint: str | None
+        ssl_context: ssl.SSLContext | None
+
+        # Trusted CAs
+        ca_certs: str | None
+        ca_cert_dir: str | None
+        ca_cert_data: None | str | bytes
+
+        # TLS version
+        ssl_minimum_version: int | None
+        ssl_maximum_version: int | None
+        ssl_version: int | str | None  # Deprecated
+
+        # Client certificates
+        cert_file: str | None
+        key_file: str | None
+        key_password: str | None
+
+        def __init__(
+            self,
+            host: str,
+            port: int | None = None,
+            *,
+            timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+            source_address: tuple[str, int] | None = None,
+            blocksize: int = 16384,
+            socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
+            proxy: Url | None = None,
+            proxy_config: ProxyConfig | None = None,
+            cert_reqs: int | str | None = None,
+            assert_hostname: None | str | typing.Literal[False] = None,
+            assert_fingerprint: str | None = None,
+            server_hostname: str | None = None,
+            ssl_context: ssl.SSLContext | None = None,
+            ca_certs: str | None = None,
+            ca_cert_dir: str | None = None,
+            ca_cert_data: None | str | bytes = None,
+            ssl_minimum_version: int | None = None,
+            ssl_maximum_version: int | None = None,
+            ssl_version: int | str | None = None,  # Deprecated
+            cert_file: str | None = None,
+            key_file: str | None = None,
+            key_password: str | None = None,
+        ) -> None: ...
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py
new file mode 100644
index 00000000000..b62abb5ffcd
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py
@@ -0,0 +1,490 @@
+from __future__ import annotations
+
+import typing
+from collections import OrderedDict
+from enum import Enum, auto
+from threading import RLock
+
+if typing.TYPE_CHECKING:
+    # We can only import Protocol if TYPE_CHECKING because it's a development
+    # dependency, and is not available at runtime.
+    from typing import Protocol
+
+    from opentelemetry.agent._vendor.typing_extensions import Self
+
+    class HasGettableStringKeys(Protocol):
+        def keys(self) -> typing.Iterator[str]: ...
+
+        def __getitem__(self, key: str) -> str: ...
+
+
+__all__ = ["RecentlyUsedContainer", "HTTPHeaderDict"]
+
+
+# Key type
+_KT = typing.TypeVar("_KT")
+# Value type
+_VT = typing.TypeVar("_VT")
+# Default type
+_DT = typing.TypeVar("_DT")
+
+ValidHTTPHeaderSource = typing.Union[
+    "HTTPHeaderDict",
+    typing.Mapping[str, str],
+    typing.Iterable[tuple[str, str]],
+    "HasGettableStringKeys",
+]
+
+
+class _Sentinel(Enum):
+    not_passed = auto()
+
+
+def ensure_can_construct_http_header_dict(
+    potential: object,
+) -> ValidHTTPHeaderSource | None:
+    if isinstance(potential, HTTPHeaderDict):
+        return potential
+    elif isinstance(potential, typing.Mapping):
+        # Full runtime checking of the contents of a Mapping is expensive, so for the
+        # purposes of typechecking, we assume that any Mapping is the right shape.
+        return typing.cast(typing.Mapping[str, str], potential)
+    elif isinstance(potential, typing.Iterable):
+        # Similarly to Mapping, full runtime checking of the contents of an Iterable is
+        # expensive, so for the purposes of typechecking, we assume that any Iterable
+        # is the right shape.
+        return typing.cast(typing.Iterable[tuple[str, str]], potential)
+    elif hasattr(potential, "keys") and hasattr(potential, "__getitem__"):
+        return typing.cast("HasGettableStringKeys", potential)
+    else:
+        return None
+
+
+class RecentlyUsedContainer(typing.Generic[_KT, _VT], typing.MutableMapping[_KT, _VT]):
+    """
+    Provides a thread-safe dict-like container which maintains up to
+    ``maxsize`` keys while throwing away the least-recently-used keys beyond
+    ``maxsize``.
+
+    :param maxsize:
+        Maximum number of recent elements to retain.
+
+    :param dispose_func:
+        Every time an item is evicted from the container,
+        ``dispose_func(value)`` is called.  Callback which will get called
+    """
+
+    _container: typing.OrderedDict[_KT, _VT]
+    _maxsize: int
+    dispose_func: typing.Callable[[_VT], None] | None
+    lock: RLock
+
+    def __init__(
+        self,
+        maxsize: int = 10,
+        dispose_func: typing.Callable[[_VT], None] | None = None,
+    ) -> None:
+        super().__init__()
+        self._maxsize = maxsize
+        self.dispose_func = dispose_func
+        self._container = OrderedDict()
+        self.lock = RLock()
+
+    def __getitem__(self, key: _KT) -> _VT:
+        # Re-insert the item, moving it to the end of the eviction line.
+        with self.lock:
+            item = self._container.pop(key)
+            self._container[key] = item
+            return item
+
+    def __setitem__(self, key: _KT, value: _VT) -> None:
+        evicted_item = None
+        with self.lock:
+            # Possibly evict the existing value of 'key'
+            try:
+                # If the key exists, we'll overwrite it, which won't change the
+                # size of the pool. Because accessing a key should move it to
+                # the end of the eviction line, we pop it out first.
+                evicted_item = key, self._container.pop(key)
+                self._container[key] = value
+            except KeyError:
+                # When the key does not exist, we insert the value first so that
+                # evicting works in all cases, including when self._maxsize is 0
+                self._container[key] = value
+                if len(self._container) > self._maxsize:
+                    # If we didn't evict an existing value, and we've hit our maximum
+                    # size, then we have to evict the least recently used item from
+                    # the beginning of the container.
+                    evicted_item = self._container.popitem(last=False)
+
+        # After releasing the lock on the pool, dispose of any evicted value.
+        if evicted_item is not None and self.dispose_func:
+            _, evicted_value = evicted_item
+            self.dispose_func(evicted_value)
+
+    def __delitem__(self, key: _KT) -> None:
+        with self.lock:
+            value = self._container.pop(key)
+
+        if self.dispose_func:
+            self.dispose_func(value)
+
+    def __len__(self) -> int:
+        with self.lock:
+            return len(self._container)
+
+    def __iter__(self) -> typing.NoReturn:
+        raise NotImplementedError(
+            "Iteration over this class is unlikely to be threadsafe."
+        )
+
+    def clear(self) -> None:
+        with self.lock:
+            # Copy pointers to all values, then wipe the mapping
+            values = list(self._container.values())
+            self._container.clear()
+
+        if self.dispose_func:
+            for value in values:
+                self.dispose_func(value)
+
+    def keys(self) -> set[_KT]:  # type: ignore[override]
+        with self.lock:
+            return set(self._container.keys())
+
+
+class HTTPHeaderDictItemView(set[tuple[str, str]]):
+    """
+    HTTPHeaderDict is unusual for a Mapping[str, str] in that it has two modes of
+    address.
+
+    If we directly try to get an item with a particular name, we will get a string
+    back that is the concatenated version of all the values:
+
+    >>> d['X-Header-Name']
+    'Value1, Value2, Value3'
+
+    However, if we iterate over an HTTPHeaderDict's items, we will optionally combine
+    these values based on whether combine=True was called when building up the dictionary
+
+    >>> d = HTTPHeaderDict({"A": "1", "B": "foo"})
+    >>> d.add("A", "2", combine=True)
+    >>> d.add("B", "bar")
+    >>> list(d.items())
+    [
+        ('A', '1, 2'),
+        ('B', 'foo'),
+        ('B', 'bar'),
+    ]
+
+    This class conforms to the interface required by the MutableMapping ABC while
+    also giving us the nonstandard iteration behavior we want; items with duplicate
+    keys, ordered by time of first insertion.
+    """
+
+    _headers: HTTPHeaderDict
+
+    def __init__(self, headers: HTTPHeaderDict) -> None:
+        self._headers = headers
+
+    def __len__(self) -> int:
+        return len(list(self._headers.iteritems()))
+
+    def __iter__(self) -> typing.Iterator[tuple[str, str]]:
+        return self._headers.iteritems()
+
+    def __contains__(self, item: object) -> bool:
+        if isinstance(item, tuple) and len(item) == 2:
+            passed_key, passed_val = item
+            if isinstance(passed_key, str) and isinstance(passed_val, str):
+                return self._headers._has_value_for_header(passed_key, passed_val)
+        return False
+
+
+class HTTPHeaderDict(typing.MutableMapping[str, str]):
+    """
+    :param headers:
+        An iterable of field-value pairs. Must not contain multiple field names
+        when compared case-insensitively.
+
+    :param kwargs:
+        Additional field-value pairs to pass in to ``dict.update``.
+
+    A ``dict`` like container for storing HTTP Headers.
+
+    Field names are stored and compared case-insensitively in compliance with
+    RFC 7230. Iteration provides the first case-sensitive key seen for each
+    case-insensitive pair.
+
+    Using ``__setitem__`` syntax overwrites fields that compare equal
+    case-insensitively in order to maintain ``dict``'s api. For fields that
+    compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
+    in a loop.
+
+    If multiple fields that are equal case-insensitively are passed to the
+    constructor or ``.update``, the behavior is undefined and some will be
+    lost.
+
+    >>> headers = HTTPHeaderDict()
+    >>> headers.add('Set-Cookie', 'foo=bar')
+    >>> headers.add('set-cookie', 'baz=quxx')
+    >>> headers['content-length'] = '7'
+    >>> headers['SET-cookie']
+    'foo=bar, baz=quxx'
+    >>> headers['Content-Length']
+    '7'
+    """
+
+    _container: typing.MutableMapping[str, list[str]]
+
+    def __init__(self, headers: ValidHTTPHeaderSource | None = None, **kwargs: str):
+        super().__init__()
+        self._container = {}  # 'dict' is insert-ordered
+        if headers is not None:
+            if isinstance(headers, HTTPHeaderDict):
+                self._copy_from(headers)
+            else:
+                self.extend(headers)
+        if kwargs:
+            self.extend(kwargs)
+
+    def __setitem__(self, key: str, val: str) -> None:
+        # avoid a bytes/str comparison by decoding before httplib
+        if isinstance(key, bytes):
+            key = key.decode("latin-1")
+        self._container[key.lower()] = [key, val]
+
+    def __getitem__(self, key: str) -> str:
+        if isinstance(key, bytes):
+            key = key.decode("latin-1")
+        val = self._container[key.lower()]
+        return ", ".join(val[1:])
+
+    def __delitem__(self, key: str) -> None:
+        if isinstance(key, bytes):
+            key = key.decode("latin-1")
+        del self._container[key.lower()]
+
+    def __contains__(self, key: object) -> bool:
+        if isinstance(key, bytes):
+            key = key.decode("latin-1")
+        if isinstance(key, str):
+            return key.lower() in self._container
+        return False
+
+    def setdefault(self, key: str, default: str = "") -> str:
+        return super().setdefault(key, default)
+
+    def __eq__(self, other: object) -> bool:
+        maybe_constructable = ensure_can_construct_http_header_dict(other)
+        if maybe_constructable is None:
+            return False
+        else:
+            other_as_http_header_dict = type(self)(maybe_constructable)
+
+        return {k.lower(): v for k, v in self.itermerged()} == {
+            k.lower(): v for k, v in other_as_http_header_dict.itermerged()
+        }
+
+    def __ne__(self, other: object) -> bool:
+        return not self.__eq__(other)
+
+    def __len__(self) -> int:
+        return len(self._container)
+
+    def __iter__(self) -> typing.Iterator[str]:
+        # Only provide the originally cased names
+        for vals in self._container.values():
+            yield vals[0]
+
+    def discard(self, key: str) -> None:
+        try:
+            del self[key]
+        except KeyError:
+            pass
+
+    def add(self, key: str, val: str, *, combine: bool = False) -> None:
+        """Adds a (name, value) pair, doesn't overwrite the value if it already
+        exists.
+
+        If this is called with combine=True, instead of adding a new header value
+        as a distinct item during iteration, this will instead append the value to
+        any existing header value with a comma. If no existing header value exists
+        for the key, then the value will simply be added, ignoring the combine parameter.
+
+        >>> headers = HTTPHeaderDict(foo='bar')
+        >>> headers.add('Foo', 'baz')
+        >>> headers['foo']
+        'bar, baz'
+        >>> list(headers.items())
+        [('foo', 'bar'), ('foo', 'baz')]
+        >>> headers.add('foo', 'quz', combine=True)
+        >>> list(headers.items())
+        [('foo', 'bar, baz, quz')]
+        """
+        # avoid a bytes/str comparison by decoding before httplib
+        if isinstance(key, bytes):
+            key = key.decode("latin-1")
+        key_lower = key.lower()
+        new_vals = [key, val]
+        # Keep the common case aka no item present as fast as possible
+        vals = self._container.setdefault(key_lower, new_vals)
+        if new_vals is not vals:
+            # if there are values here, then there is at least the initial
+            # key/value pair
+            assert len(vals) >= 2
+            if combine:
+                vals[-1] = vals[-1] + ", " + val
+            else:
+                vals.append(val)
+
+    def extend(self, *args: ValidHTTPHeaderSource, **kwargs: str) -> None:
+        """Generic import function for any type of header-like object.
+        Adapted version of MutableMapping.update in order to insert items
+        with self.add instead of self.__setitem__
+        """
+        if len(args) > 1:
+            raise TypeError(
+                f"extend() takes at most 1 positional arguments ({len(args)} given)"
+            )
+        other = args[0] if len(args) >= 1 else ()
+
+        if isinstance(other, HTTPHeaderDict):
+            for key, val in other.iteritems():
+                self.add(key, val)
+        elif isinstance(other, typing.Mapping):
+            for key, val in other.items():
+                self.add(key, val)
+        elif isinstance(other, typing.Iterable):
+            for key, value in other:
+                self.add(key, value)
+        elif hasattr(other, "keys") and hasattr(other, "__getitem__"):
+            # THIS IS NOT A TYPESAFE BRANCH
+            # In this branch, the object has a `keys` attr but is not a Mapping or any of
+            # the other types indicated in the method signature. We do some stuff with
+            # it as though it partially implements the Mapping interface, but we're not
+            # doing that stuff safely AT ALL.
+            for key in other.keys():
+                self.add(key, other[key])
+
+        for key, value in kwargs.items():
+            self.add(key, value)
+
+    @typing.overload
+    def getlist(self, key: str) -> list[str]: ...
+
+    @typing.overload
+    def getlist(self, key: str, default: _DT) -> list[str] | _DT: ...
+
+    def getlist(
+        self, key: str, default: _Sentinel | _DT = _Sentinel.not_passed
+    ) -> list[str] | _DT:
+        """Returns a list of all the values for the named field. Returns an
+        empty list if the key doesn't exist."""
+        if isinstance(key, bytes):
+            key = key.decode("latin-1")
+        try:
+            vals = self._container[key.lower()]
+        except KeyError:
+            if default is _Sentinel.not_passed:
+                # _DT is unbound; empty list is instance of List[str]
+                return []
+            # _DT is bound; default is instance of _DT
+            return default
+        else:
+            # _DT may or may not be bound; vals[1:] is instance of List[str], which
+            # meets our external interface requirement of `Union[List[str], _DT]`.
+            return vals[1:]
+
+    def _prepare_for_method_change(self) -> Self:
+        """
+        Remove content-specific header fields before changing the request
+        method to GET or HEAD according to RFC 9110, Section 15.4.
+
+        ``Transfer-Encoding`` goes as well: it frames a request body that is
+        no longer going to be sent.
+        """
+        content_specific_headers = [
+            "Content-Encoding",
+            "Content-Language",
+            "Content-Location",
+            "Content-Type",
+            "Content-Length",
+            "Digest",
+            "Last-Modified",
+            "Transfer-Encoding",
+        ]
+        for header in content_specific_headers:
+            self.discard(header)
+        return self
+
+    # Backwards compatibility for httplib
+    getheaders = getlist
+    getallmatchingheaders = getlist
+    iget = getlist
+
+    # Backwards compatibility for http.cookiejar
+    get_all = getlist
+
+    def __repr__(self) -> str:
+        return f"{type(self).__name__}({dict(self.itermerged())})"
+
+    def _copy_from(self, other: HTTPHeaderDict) -> None:
+        for key in other:
+            val = other.getlist(key)
+            self._container[key.lower()] = [key, *val]
+
+    def copy(self) -> Self:
+        clone = type(self)()
+        clone._copy_from(self)
+        return clone
+
+    def iteritems(self) -> typing.Iterator[tuple[str, str]]:
+        """Iterate over all header lines, including duplicate ones."""
+        for key in self:
+            vals = self._container[key.lower()]
+            for val in vals[1:]:
+                yield vals[0], val
+
+    def itermerged(self) -> typing.Iterator[tuple[str, str]]:
+        """Iterate over all headers, merging duplicate ones together."""
+        for key in self:
+            val = self._container[key.lower()]
+            yield val[0], ", ".join(val[1:])
+
+    def items(self) -> HTTPHeaderDictItemView:  # type: ignore[override]
+        return HTTPHeaderDictItemView(self)
+
+    def _has_value_for_header(self, header_name: str, potential_value: str) -> bool:
+        if header_name in self:
+            return potential_value in self._container[header_name.lower()][1:]
+        return False
+
+    def __ior__(self, other: object) -> HTTPHeaderDict:
+        # Supports extending a header dict in-place using operator |=
+        # combining items with add instead of __setitem__
+        maybe_constructable = ensure_can_construct_http_header_dict(other)
+        if maybe_constructable is None:
+            return NotImplemented
+        self.extend(maybe_constructable)
+        return self
+
+    def __or__(self, other: object) -> Self:
+        # Supports merging header dicts using operator |
+        # combining items with add instead of __setitem__
+        maybe_constructable = ensure_can_construct_http_header_dict(other)
+        if maybe_constructable is None:
+            return NotImplemented
+        result = self.copy()
+        result.extend(maybe_constructable)
+        return result
+
+    def __ror__(self, other: object) -> Self:
+        # Supports merging header dicts using operator | when other is on left side
+        # combining items with add instead of __setitem__
+        maybe_constructable = ensure_can_construct_http_header_dict(other)
+        if maybe_constructable is None:
+            return NotImplemented
+        result = type(self)(maybe_constructable)
+        result.extend(self)
+        return result
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py
new file mode 100644
index 00000000000..297c271bf40
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py
@@ -0,0 +1,278 @@
+from __future__ import annotations
+
+import json as _json
+import typing
+from urllib.parse import urlencode
+
+from ._base_connection import _TYPE_BODY
+from ._collections import HTTPHeaderDict
+from .filepost import _TYPE_FIELDS, encode_multipart_formdata
+from .response import BaseHTTPResponse
+
+__all__ = ["RequestMethods"]
+
+_TYPE_ENCODE_URL_FIELDS = typing.Union[
+    typing.Sequence[tuple[str, typing.Union[str, bytes]]],
+    typing.Mapping[str, typing.Union[str, bytes]],
+]
+
+
+class RequestMethods:
+    """
+    Convenience mixin for classes who implement a :meth:`urlopen` method, such
+    as :class:`urllib3.HTTPConnectionPool` and
+    :class:`urllib3.PoolManager`.
+
+    Provides behavior for making common types of HTTP request methods and
+    decides which type of request field encoding to use.
+
+    Specifically,
+
+    :meth:`.request_encode_url` is for sending requests whose fields are
+    encoded in the URL (such as GET, HEAD, DELETE).
+
+    :meth:`.request_encode_body` is for sending requests whose fields are
+    encoded in the *body* of the request using multipart or www-form-urlencoded
+    (such as for POST, PUT, PATCH).
+
+    :meth:`.request` is for making any kind of request, it will look up the
+    appropriate encoding format and use one of the above two methods to make
+    the request.
+
+    Initializer parameters:
+
+    :param headers:
+        Headers to include with all requests, unless other headers are given
+        explicitly.
+    """
+
+    _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"}
+
+    def __init__(self, headers: typing.Mapping[str, str] | None = None) -> None:
+        self.headers = headers or {}
+
+    def urlopen(
+        self,
+        method: str,
+        url: str,
+        body: _TYPE_BODY | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        encode_multipart: bool = True,
+        multipart_boundary: str | None = None,
+        **kw: typing.Any,
+    ) -> BaseHTTPResponse:  # Abstract
+        raise NotImplementedError(
+            "Classes extending RequestMethods must implement "
+            "their own ``urlopen`` method."
+        )
+
+    def request(
+        self,
+        method: str,
+        url: str,
+        body: _TYPE_BODY | None = None,
+        fields: _TYPE_FIELDS | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        json: typing.Any | None = None,
+        **urlopen_kw: typing.Any,
+    ) -> BaseHTTPResponse:
+        """
+        Make a request using :meth:`urlopen` with the appropriate encoding of
+        ``fields`` based on the ``method`` used.
+
+        This is a convenience method that requires the least amount of manual
+        effort. It can be used in most situations, while still having the
+        option to drop down to more specific methods when necessary, such as
+        :meth:`request_encode_url`, :meth:`request_encode_body`,
+        or even the lowest level :meth:`urlopen`.
+
+        :param method:
+            HTTP request method (such as GET, POST, PUT, etc.)
+
+        :param url:
+            The URL to perform the request on.
+
+        :param body:
+            Data to send in the request body, either :class:`str`, :class:`bytes`,
+            an iterable of :class:`str`/:class:`bytes`, or a file-like object.
+
+        :param fields:
+            Data to encode and send in the URL or request body, depending on ``method``.
+
+        :param headers:
+            Dictionary of custom headers to send, such as User-Agent,
+            If-None-Match, etc. If None, pool headers are used. If provided,
+            these headers completely replace any pool-specific headers.
+
+        :param json:
+            Data to encode and send as JSON with UTF-encoded in the request body.
+            The ``"Content-Type"`` header will be set to ``"application/json"``
+            unless specified otherwise.
+        """
+        method = method.upper()
+
+        if json is not None and body is not None:
+            raise TypeError(
+                "request got values for both 'body' and 'json' parameters which are mutually exclusive"
+            )
+
+        if json is not None:
+            if headers is None:
+                headers = self.headers
+
+            if not ("content-type" in map(str.lower, headers.keys())):
+                headers = HTTPHeaderDict(headers)
+                headers["Content-Type"] = "application/json"
+
+            body = _json.dumps(json, separators=(",", ":"), ensure_ascii=False).encode(
+                "utf-8"
+            )
+
+        if body is not None:
+            urlopen_kw["body"] = body
+
+        if method in self._encode_url_methods:
+            return self.request_encode_url(
+                method,
+                url,
+                fields=fields,  # type: ignore[arg-type]
+                headers=headers,
+                **urlopen_kw,
+            )
+        else:
+            return self.request_encode_body(
+                method, url, fields=fields, headers=headers, **urlopen_kw
+            )
+
+    def request_encode_url(
+        self,
+        method: str,
+        url: str,
+        fields: _TYPE_ENCODE_URL_FIELDS | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        **urlopen_kw: str,
+    ) -> BaseHTTPResponse:
+        """
+        Make a request using :meth:`urlopen` with the ``fields`` encoded in
+        the url. This is useful for request methods like GET, HEAD, DELETE, etc.
+
+        :param method:
+            HTTP request method (such as GET, POST, PUT, etc.)
+
+        :param url:
+            The URL to perform the request on.
+
+        :param fields:
+            Data to encode and send in the URL.
+
+        :param headers:
+            Dictionary of custom headers to send, such as User-Agent,
+            If-None-Match, etc. If None, pool headers are used. If provided,
+            these headers completely replace any pool-specific headers.
+        """
+        if headers is None:
+            headers = self.headers
+
+        extra_kw: dict[str, typing.Any] = {"headers": headers}
+        extra_kw.update(urlopen_kw)
+
+        if fields:
+            url += "?" + urlencode(fields)
+
+        return self.urlopen(method, url, **extra_kw)
+
+    def request_encode_body(
+        self,
+        method: str,
+        url: str,
+        fields: _TYPE_FIELDS | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        encode_multipart: bool = True,
+        multipart_boundary: str | None = None,
+        **urlopen_kw: str,
+    ) -> BaseHTTPResponse:
+        """
+        Make a request using :meth:`urlopen` with the ``fields`` encoded in
+        the body. This is useful for request methods like POST, PUT, PATCH, etc.
+
+        When ``encode_multipart=True`` (default), then
+        :func:`urllib3.encode_multipart_formdata` is used to encode
+        the payload with the appropriate content type. Otherwise
+        :func:`urllib.parse.urlencode` is used with the
+        'application/x-www-form-urlencoded' content type.
+
+        Multipart encoding must be used when posting files, and it's reasonably
+        safe to use it in other times too. However, it may break request
+        signing, such as with OAuth.
+
+        Supports an optional ``fields`` parameter of key/value strings AND
+        key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
+        the MIME type is optional. For example::
+
+            fields = {
+                'foo': 'bar',
+                'fakefile': ('foofile.txt', 'contents of foofile'),
+                'realfile': ('barfile.txt', open('realfile').read()),
+                'typedfile': ('bazfile.bin', open('bazfile').read(),
+                              'image/jpeg'),
+                'nonamefile': 'contents of nonamefile field',
+            }
+
+        When uploading a file, providing a filename (the first parameter of the
+        tuple) is optional but recommended to best mimic behavior of browsers.
+
+        Note that if ``headers`` are supplied, the 'Content-Type' header will
+        be overwritten because it depends on the dynamic random boundary string
+        which is used to compose the body of the request. The random boundary
+        string can be explicitly set with the ``multipart_boundary`` parameter.
+
+        :param method:
+            HTTP request method (such as GET, POST, PUT, etc.)
+
+        :param url:
+            The URL to perform the request on.
+
+        :param fields:
+            Data to encode and send in the request body.
+
+        :param headers:
+            Dictionary of custom headers to send, such as User-Agent,
+            If-None-Match, etc. If None, pool headers are used. If provided,
+            these headers completely replace any pool-specific headers.
+
+        :param encode_multipart:
+            If True, encode the ``fields`` using the multipart/form-data MIME
+            format.
+
+        :param multipart_boundary:
+            If not specified, then a random boundary will be generated using
+            :func:`urllib3.filepost.choose_boundary`.
+        """
+        if headers is None:
+            headers = self.headers
+
+        extra_kw: dict[str, typing.Any] = {"headers": HTTPHeaderDict(headers)}
+        body: bytes | str
+
+        if fields:
+            if "body" in urlopen_kw:
+                raise TypeError(
+                    "request got values for both 'fields' and 'body', can only specify one."
+                )
+
+            if encode_multipart:
+                body, content_type = encode_multipart_formdata(
+                    fields, boundary=multipart_boundary
+                )
+            else:
+                body, content_type = (
+                    urlencode(fields),  # type: ignore[arg-type]
+                    "application/x-www-form-urlencoded",
+                )
+
+            extra_kw["body"] = body
+            extra_kw["headers"].setdefault("Content-Type", content_type)
+
+        extra_kw.update(urlopen_kw)
+
+        return self.urlopen(method, url, **extra_kw)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py
new file mode 100644
index 00000000000..319b966f20a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py
@@ -0,0 +1,24 @@
+# file generated by vcs-versioning
+# don't change, don't track in version control
+from __future__ import annotations
+
+__all__ = [
+    "__version__",
+    "__version_tuple__",
+    "version",
+    "version_tuple",
+    "__commit_id__",
+    "commit_id",
+]
+
+version: str
+__version__: str
+__version_tuple__: tuple[int | str, ...]
+version_tuple: tuple[int | str, ...]
+commit_id: str | None
+__commit_id__: str | None
+
+__version__ = version = '2.8.0'
+__version_tuple__ = version_tuple = (2, 8, 0)
+
+__commit_id__ = commit_id = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py
new file mode 100644
index 00000000000..3bf3f57ac77
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py
@@ -0,0 +1,1204 @@
+from __future__ import annotations
+
+import datetime
+import http.client
+import logging
+import os
+import re
+import socket
+import sys
+import threading
+import typing
+import warnings
+from http.client import HTTPConnection as _HTTPConnection
+from http.client import HTTPException as HTTPException  # noqa: F401
+from http.client import ResponseNotReady
+from socket import timeout as SocketTimeout
+
+if typing.TYPE_CHECKING:
+    from .response import HTTPResponse
+    from .util.ssl_ import _TYPE_PEER_CERT_RET_DICT
+    from .util.ssltransport import SSLTransport
+
+from ._collections import HTTPHeaderDict
+from .http2 import probe as http2_probe
+from .util.response import assert_header_parsing
+from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT, Timeout
+from .util.util import to_str
+from .util.wait import wait_for_read
+
+try:  # Compiled with SSL?
+    import ssl
+
+    BaseSSLError = ssl.SSLError
+except (ImportError, AttributeError):
+    ssl = None  # type: ignore[assignment]
+
+    class BaseSSLError(BaseException):  # type: ignore[no-redef]
+        pass
+
+
+from ._base_connection import _TYPE_BODY
+from ._base_connection import ProxyConfig as ProxyConfig
+from ._base_connection import _ResponseOptions as _ResponseOptions
+from ._version import __version__
+from .exceptions import (
+    ConnectTimeoutError,
+    HeaderParsingError,
+    NameResolutionError,
+    NewConnectionError,
+    ProxyError,
+    SystemTimeWarning,
+)
+from .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection, ssl_
+from .util.request import body_to_chunks
+from .util.ssl_ import assert_fingerprint as _assert_fingerprint
+from .util.ssl_ import (
+    create_urllib3_context,
+    is_ipaddress,
+    resolve_cert_reqs,
+    resolve_ssl_version,
+    ssl_wrap_socket,
+)
+from .util.ssl_match_hostname import CertificateError, match_hostname
+from .util.url import Url
+
+# Not a no-op, we're adding this to the namespace so it can be imported.
+ConnectionError = ConnectionError
+BrokenPipeError = BrokenPipeError
+
+
+log = logging.getLogger(__name__)
+
+port_by_scheme = {"http": 80, "https": 443}
+
+# When it comes time to update this value as a part of regular maintenance
+# (ie test_recent_date is failing) update it to ~6 months before the current date.
+RECENT_DATE = datetime.date(2025, 1, 1)
+
+_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")
+# Starting the optional OWS match at the beginning of a whitespace run avoids
+# quadratic backtracking for long header values.
+_OBSOLETE_FOLD_RE = re.compile(r"(?:(? str:
+    if "\r\n" not in value:
+        return value
+    return _OBSOLETE_FOLD_RE.sub(" ", value)
+
+
+def _normalize_header_values(
+    message: http.client.HTTPMessage,
+) -> list[tuple[str, str]]:
+    header_items = message.items()
+    headers_changed = False
+    for index, (name, value) in enumerate(header_items):
+        normalized_value = _normalize_header_value(value)
+        if normalized_value != value:
+            header_items[index] = (name, normalized_value)
+            headers_changed = True
+
+    if headers_changed:
+        # Keep the original message in sync for downstream consumers such as
+        # cookie jars while preserving its identity and header ordering.
+        for name, _ in header_items:
+            del message[name]
+        for name, value in header_items:
+            message[name] = value
+
+    return header_items
+
+
+class HTTPConnection(_HTTPConnection):
+    """
+    Based on :class:`http.client.HTTPConnection` but provides an extra constructor
+    backwards-compatibility layer between older and newer Pythons.
+
+    Additional keyword parameters are used to configure attributes of the connection.
+    Accepted parameters include:
+
+    - ``source_address``: Set the source address for the current connection.
+    - ``socket_options``: Set specific options on the underlying socket. If not specified, then
+      defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
+      Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
+
+      For example, if you wish to enable TCP Keep Alive in addition to the defaults,
+      you might pass:
+
+      .. code-block:: python
+
+         HTTPConnection.default_socket_options + [
+             (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
+         ]
+
+      Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).
+    """
+
+    default_port: typing.ClassVar[int] = port_by_scheme["http"]  # type: ignore[misc]
+
+    #: Disable Nagle's algorithm by default.
+    #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]``
+    #:
+    #: Use the ``socket_options`` parameter of :class:`~urllib3.PoolManager`,
+    #: :class:`~urllib3.ProxyManager`, or :class:`~urllib3.HTTPConnectionPool`
+    #: to change this behavior.
+    default_socket_options: typing.ClassVar[
+        typing.Final[connection._TYPE_SOCKET_OPTIONS]
+    ] = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
+
+    #: Whether this connection verifies the host's certificate.
+    is_verified: bool = False
+
+    #: Whether this proxy connection verified the proxy host's certificate.
+    # If no proxy is currently connected to the value will be ``None``.
+    proxy_is_verified: bool | None = None
+
+    blocksize: int
+    source_address: tuple[str, int] | None
+    socket_options: connection._TYPE_SOCKET_OPTIONS | None
+
+    _has_connected_to_proxy: bool
+    _response_options: _ResponseOptions | None
+    _tunnel_host: str | None
+    _tunnel_port: int | None
+    _tunnel_scheme: str | None
+
+    def __init__(
+        self,
+        host: str,
+        port: int | None = None,
+        *,
+        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+        source_address: tuple[str, int] | None = None,
+        blocksize: int = 16384,
+        socket_options: None | (
+            connection._TYPE_SOCKET_OPTIONS
+        ) = default_socket_options,
+        proxy: Url | None = None,
+        proxy_config: ProxyConfig | None = None,
+    ) -> None:
+        super().__init__(
+            host=host,
+            port=port,
+            timeout=Timeout.resolve_default_timeout(timeout),
+            source_address=source_address,
+            blocksize=blocksize,
+        )
+        self.socket_options = socket_options
+        self.proxy = proxy
+        self.proxy_config = proxy_config
+
+        self._has_connected_to_proxy = False
+        self._response_options = None
+        self._tunnel_host: str | None = None
+        self._tunnel_port: int | None = None
+        self._tunnel_scheme: str | None = None
+
+    def __str__(self) -> str:
+        return f"{type(self).__name__}(host={self.host!r}, port={self.port!r})"
+
+    def __repr__(self) -> str:
+        return f"<{self} at {id(self):#x}>"
+
+    @property
+    def host(self) -> str:
+        """
+        Getter method to remove any trailing dots that indicate the hostname is an FQDN.
+
+        In general, SSL certificates don't include the trailing dot indicating a
+        fully-qualified domain name, and thus, they don't validate properly when
+        checked against a domain name that includes the dot. In addition, some
+        servers may not expect to receive the trailing dot when provided.
+
+        However, the hostname with trailing dot is critical to DNS resolution; doing a
+        lookup with the trailing dot will properly only resolve the appropriate FQDN,
+        whereas a lookup without a trailing dot will search the system's search domain
+        list. Thus, it's important to keep the original host around for use only in
+        those cases where it's appropriate (i.e., when doing DNS lookup to establish the
+        actual TCP connection across which we're going to send HTTP requests).
+        """
+        return self._dns_host.rstrip(".")
+
+    @host.setter
+    def host(self, value: str) -> None:
+        """
+        Setter for the `host` property.
+
+        We assume that only urllib3 uses the _dns_host attribute; httplib itself
+        only uses `host`, and it seems reasonable that other libraries follow suit.
+        """
+        self._dns_host = value
+
+    def _new_conn(self) -> socket.socket:
+        """Establish a socket connection and set nodelay settings on it.
+
+        :return: New socket connection.
+        """
+        try:
+            sock = connection.create_connection(
+                (self._dns_host, self.port),
+                self.timeout,
+                source_address=self.source_address,
+                socket_options=self.socket_options,
+            )
+        except socket.gaierror as e:
+            raise NameResolutionError(self.host, self, e) from e
+        except SocketTimeout as e:
+            raise ConnectTimeoutError(
+                self,
+                f"Connection to {self.host} timed out. (connect timeout={self.timeout})",
+            ) from e
+
+        except OSError as e:
+            raise NewConnectionError(
+                self, f"Failed to establish a new connection: {e}"
+            ) from e
+
+        sys.audit("http.client.connect", self, self.host, self.port)
+
+        return sock
+
+    def set_tunnel(
+        self,
+        host: str,
+        port: int | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        scheme: str = "http",
+    ) -> None:
+        if scheme not in ("http", "https"):
+            raise ValueError(
+                f"Invalid proxy scheme for tunneling: {scheme!r}, must be either 'http' or 'https'"
+            )
+        super().set_tunnel(host, port=port, headers=headers)
+        self._tunnel_scheme = scheme
+
+    if sys.version_info < (3, 11, 16) or ((3, 12) <= sys.version_info < (3, 12, 14)):
+        # Taken from python/cpython#100986 which was backported in 3.11.9 and 3.12.3.
+        # When using connection_from_host, host will come without brackets.
+        # With a security patch from python/cpython#146211.
+        def _wrap_ipv6(self, ip: bytes) -> bytes:
+            if b":" in ip and ip[0] != b"["[0]:
+                return b"[" + ip + b"]"
+            return ip
+
+        # Copied from CPython 3.12.13 Lib/http/client.py
+        _is_legal_header_name = staticmethod(re.compile(rb"[^:\s][^:\r\n]*").fullmatch)
+        _is_illegal_header_value = staticmethod(
+            re.compile(rb"\n(?![ \t])|\r(?![ \t\n])").search
+        )
+        _contains_disallowed_url_pchar_re = re.compile("[\x00-\x20\x7f]")
+
+        if sys.version_info < (3, 11, 16):
+            # `_tunnel` copied from 3.11.15 backporting
+            # https://github.com/python/cpython/commit/0d4026432591d43185568dd31cef6a034c4b9261
+            # and https://github.com/python/cpython/commit/6fbc61070fda2ffb8889e77e3b24bca4249ab4d1
+            # plus a fix from https://github.com/python/cpython/commit/56b7100b04e44ea27989242b176beb8f016b2c53
+            def _tunnel(self) -> None:
+                if self._contains_disallowed_url_pchar_re.search(self._tunnel_host):  # type: ignore[arg-type]
+                    raise ValueError(
+                        "Tunnel host can't contain control characters %r"
+                        % (self._tunnel_host,)
+                    )
+                _MAXLINE = http.client._MAXLINE  # type: ignore[attr-defined]
+                connect = b"CONNECT %s:%d HTTP/1.0\r\n" % (  # type: ignore[str-format]
+                    self._wrap_ipv6(self._tunnel_host.encode("ascii")),  # type: ignore[union-attr]
+                    self._tunnel_port,
+                )
+                headers = [connect]
+                for header, value in self._tunnel_headers.items():  # type: ignore[attr-defined]
+                    header_bytes = header.encode("latin-1")
+                    value_bytes = value.encode("latin-1")
+                    if not self._is_legal_header_name(header_bytes):
+                        raise ValueError(f"Invalid header name {header_bytes!r}")
+                    if self._is_illegal_header_value(value_bytes):
+                        raise ValueError(f"Invalid header value {value_bytes!r}")
+                    headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes))
+                headers.append(b"\r\n")
+                # Making a single send() call instead of one per line encourages
+                # the host OS to use a more optimal packet size instead of
+                # potentially emitting a series of small packets.
+                self.send(b"".join(headers))
+                del headers
+
+                response = self.response_class(self.sock, method=self._method)  # type: ignore[attr-defined]
+                try:
+                    version, code, message = response._read_status()  # type: ignore[attr-defined]
+
+                    if code != http.HTTPStatus.OK:
+                        self.close()
+                        raise OSError(
+                            f"Tunnel connection failed: {code} {message.strip()}"
+                        )
+                    while True:
+                        line = response.fp.readline(_MAXLINE + 1)
+                        if len(line) > _MAXLINE:
+                            raise http.client.LineTooLong("header line")
+                        if not line:
+                            # for sites which EOF without sending a trailer
+                            break
+                        if line in (b"\r\n", b"\n", b""):
+                            break
+
+                        if self.debuglevel > 0:
+                            print("header:", line.decode())
+                finally:
+                    response.close()
+
+        elif (3, 12) <= sys.version_info < (3, 12, 14):
+            # `_tunnel` copied from 3.12.13 backporting
+            # https://github.com/python/cpython/commit/23aef575c7629abcd4aaf028ebd226fb41a4b3c8
+            # plus a fix from https://github.com/python/cpython/commit/c00c386faa579ad71196d33408644478488e43ec
+            def _tunnel(self) -> None:  # noqa: F811
+                if self._contains_disallowed_url_pchar_re.search(self._tunnel_host):  # type: ignore[arg-type]
+                    raise ValueError(
+                        "Tunnel host can't contain control characters %r"
+                        % (self._tunnel_host,)
+                    )
+                connect = b"CONNECT %s:%d HTTP/1.1\r\n" % (  # type: ignore[str-format]
+                    self._wrap_ipv6(self._tunnel_host.encode("idna")),  # type: ignore[union-attr]
+                    self._tunnel_port,
+                )
+                headers = [connect]
+                for header, value in self._tunnel_headers.items():  # type: ignore[attr-defined]
+                    header_bytes = header.encode("latin-1")
+                    value_bytes = value.encode("latin-1")
+                    if not self._is_legal_header_name(header_bytes):
+                        raise ValueError(f"Invalid header name {header_bytes!r}")
+                    if self._is_illegal_header_value(value_bytes):
+                        raise ValueError(f"Invalid header value {value_bytes!r}")
+                    headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes))
+                headers.append(b"\r\n")
+                # Making a single send() call instead of one per line encourages
+                # the host OS to use a more optimal packet size instead of
+                # potentially emitting a series of small packets.
+                self.send(b"".join(headers))
+                del headers
+
+                response = self.response_class(self.sock, method=self._method)  # type: ignore[attr-defined]
+                try:
+                    version, code, message = response._read_status()  # type: ignore[attr-defined]
+
+                    self._raw_proxy_headers = http.client._read_headers(response.fp)  # type: ignore[attr-defined]
+
+                    if self.debuglevel > 0:
+                        for header in self._raw_proxy_headers:
+                            print("header:", header.decode())
+
+                    if code != http.HTTPStatus.OK:
+                        self.close()
+                        raise OSError(
+                            f"Tunnel connection failed: {code} {message.strip()}"
+                        )
+
+                finally:
+                    response.close()
+
+    def connect(self) -> None:
+        self.sock = self._new_conn()
+        if self._tunnel_host:
+            # If we're tunneling it means we're connected to our proxy.
+            self._has_connected_to_proxy = True
+
+            # TODO: Fix tunnel so it doesn't depend on self.sock state.
+            self._tunnel()
+
+        # If there's a proxy to be connected to we are fully connected.
+        # This is set twice (once above and here) due to forwarding proxies
+        # not using tunnelling.
+        self._has_connected_to_proxy = bool(self.proxy)
+
+        if self._has_connected_to_proxy:
+            self.proxy_is_verified = False
+
+    @property
+    def is_closed(self) -> bool:
+        return self.sock is None
+
+    @property
+    def is_connected(self) -> bool:
+        if self.sock is None:
+            return False
+        return not wait_for_read(self.sock, timeout=0.0)
+
+    @property
+    def has_connected_to_proxy(self) -> bool:
+        return self._has_connected_to_proxy
+
+    @property
+    def proxy_is_forwarding(self) -> bool:
+        """
+        Return True if a forwarding proxy is configured, else return False
+        """
+        return bool(self.proxy) and self._tunnel_host is None
+
+    @property
+    def proxy_is_tunneling(self) -> bool:
+        """
+        Return True if a tunneling proxy is configured, else return False
+        """
+        return self._tunnel_host is not None
+
+    def close(self) -> None:
+        try:
+            super().close()
+        finally:
+            # Reset all stateful properties so connection
+            # can be re-used without leaking prior configs.
+            self.sock = None
+            self.is_verified = False
+            self.proxy_is_verified = None
+            self._has_connected_to_proxy = False
+            self._response_options = None
+            self._tunnel_host = None
+            self._tunnel_port = None
+            self._tunnel_scheme = None
+
+    def putrequest(
+        self,
+        method: str,
+        url: str,
+        skip_host: bool = False,
+        skip_accept_encoding: bool = False,
+    ) -> None:
+        """"""
+        # Empty docstring because the indentation of CPython's implementation
+        # is broken but we don't want this method in our documentation.
+        match = _CONTAINS_CONTROL_CHAR_RE.search(method)
+        if match:
+            raise ValueError(
+                f"Method cannot contain non-token characters {method!r} (found at least {match.group()!r})"
+            )
+
+        return super().putrequest(
+            method, url, skip_host=skip_host, skip_accept_encoding=skip_accept_encoding
+        )
+
+    def putheader(self, header: str, *values: str) -> None:  # type: ignore[override]
+        """"""
+        if not any(isinstance(v, str) and v == SKIP_HEADER for v in values):
+            super().putheader(header, *values)
+        elif to_str(header.lower()) not in SKIPPABLE_HEADERS:
+            skippable_headers = "', '".join(
+                [str.title(header) for header in sorted(SKIPPABLE_HEADERS)]
+            )
+            raise ValueError(
+                f"urllib3.util.SKIP_HEADER only supports '{skippable_headers}'"
+            )
+
+    # `request` method's signature intentionally violates LSP.
+    # urllib3's API is different from `http.client.HTTPConnection` and the subclassing is only incidental.
+    def request(  # type: ignore[override]
+        self,
+        method: str,
+        url: str,
+        body: _TYPE_BODY | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        *,
+        chunked: bool = False,
+        preload_content: bool = True,
+        decode_content: bool = True,
+        enforce_content_length: bool = True,
+    ) -> None:
+        # Update the inner socket's timeout value to send the request.
+        # This only triggers if the connection is re-used.
+        if self.sock is not None:
+            self.sock.settimeout(self.timeout)
+
+        # Store these values to be fed into the HTTPResponse
+        # object later. TODO: Remove this in favor of a real
+        # HTTP lifecycle mechanism.
+
+        # We have to store these before we call .request()
+        # because sometimes we can still salvage a response
+        # off the wire even if we aren't able to completely
+        # send the request body.
+        self._response_options = _ResponseOptions(
+            request_method=method,
+            request_url=url,
+            preload_content=preload_content,
+            decode_content=decode_content,
+            enforce_content_length=enforce_content_length,
+        )
+
+        if headers is None:
+            headers = {}
+        header_keys = frozenset(to_str(k.lower()) for k in headers)
+        skip_accept_encoding = "accept-encoding" in header_keys
+        skip_host = "host" in header_keys
+        self.putrequest(
+            method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host
+        )
+
+        # Transform the body into an iterable of sendall()-able chunks
+        # and detect if an explicit Content-Length is doable.
+        chunks_and_cl = body_to_chunks(body, method=method, blocksize=self.blocksize)
+        chunks = chunks_and_cl.chunks
+        content_length = chunks_and_cl.content_length
+
+        # When chunked is explicit set to 'True' we respect that.
+        if chunked:
+            if "transfer-encoding" not in header_keys:
+                self.putheader("Transfer-Encoding", "chunked")
+        else:
+            # Detect whether a framing mechanism is already in use. If so
+            # we respect that value, otherwise we pick chunked vs content-length
+            # depending on the type of 'body'.
+            if "content-length" in header_keys:
+                chunked = False
+            elif "transfer-encoding" in header_keys:
+                chunked = True
+
+            # Otherwise we go off the recommendation of 'body_to_chunks()'.
+            else:
+                chunked = False
+                if content_length is None:
+                    if chunks is not None:
+                        chunked = True
+                        self.putheader("Transfer-Encoding", "chunked")
+                else:
+                    self.putheader("Content-Length", str(content_length))
+
+        # Now that framing headers are out of the way we send all the other headers.
+        if "user-agent" not in header_keys:
+            self.putheader("User-Agent", _get_default_user_agent())
+        for header, value in headers.items():
+            self.putheader(header, value)
+        self.endheaders()
+
+        # If we're given a body we start sending that in chunks.
+        if chunks is not None:
+            for chunk in chunks:
+                # Sending empty chunks isn't allowed for TE: chunked
+                # as it indicates the end of the body.
+                if not chunk:
+                    continue
+                if isinstance(chunk, str):
+                    chunk = chunk.encode("utf-8")
+                if chunked:
+                    self.send(b"%x\r\n%b\r\n" % (len(chunk), chunk))
+                else:
+                    self.send(chunk)
+
+        # Regardless of whether we have a body or not, if we're in
+        # chunked mode we want to send an explicit empty chunk.
+        if chunked:
+            self.send(b"0\r\n\r\n")
+
+    def request_chunked(
+        self,
+        method: str,
+        url: str,
+        body: _TYPE_BODY | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+    ) -> None:
+        """
+        Alternative to the common request method, which sends the
+        body with chunked encoding and not as one block
+        """
+        warnings.warn(
+            "HTTPConnection.request_chunked() is deprecated and will be removed "
+            "in urllib3 v3.0. Instead use HTTPConnection.request(..., chunked=True).",
+            category=FutureWarning,
+            stacklevel=2,
+        )
+        self.request(method, url, body=body, headers=headers, chunked=True)
+
+    def getresponse(  # type: ignore[override]
+        self,
+    ) -> HTTPResponse:
+        """
+        Get the response from the server.
+
+        If the HTTPConnection is in the correct state, returns an instance of HTTPResponse or of whatever object is returned by the response_class variable.
+
+        If a request has not been sent or if a previous response has not be handled, ResponseNotReady is raised. If the HTTP response indicates that the connection should be closed, then it will be closed before the response is returned. When the connection is closed, the underlying socket is closed.
+        """
+        # Raise the same error as http.client.HTTPConnection
+        if self._response_options is None:
+            raise ResponseNotReady()
+
+        # Reset this attribute for being used again.
+        resp_options = self._response_options
+        self._response_options = None
+
+        # Since the connection's timeout value may have been updated
+        # we need to set the timeout on the socket.
+        self.sock.settimeout(self.timeout)
+
+        # This is needed here to avoid circular import errors
+        from .response import HTTPResponse
+
+        # Save a reference to the shutdown function before ownership is passed
+        # to httplib_response
+        # TODO should we implement it everywhere?
+        _shutdown = getattr(self.sock, "shutdown", None)
+
+        # Get the response from http.client.HTTPConnection
+        httplib_response = super().getresponse()
+
+        try:
+            assert_header_parsing(httplib_response.msg)
+        except (HeaderParsingError, TypeError) as hpe:
+            log.warning(
+                "Failed to parse headers (url=%s): %s",
+                _url_from_connection(self, resp_options.request_url),
+                hpe,
+                exc_info=True,
+            )
+
+        header_items = _normalize_header_values(httplib_response.msg)
+        headers = HTTPHeaderDict(header_items)
+
+        response = HTTPResponse(
+            body=httplib_response,
+            headers=headers,
+            status=httplib_response.status,
+            version=httplib_response.version,
+            version_string=getattr(self, "_http_vsn_str", "HTTP/?"),
+            reason=httplib_response.reason,
+            preload_content=resp_options.preload_content,
+            decode_content=resp_options.decode_content,
+            original_response=httplib_response,
+            enforce_content_length=resp_options.enforce_content_length,
+            request_method=resp_options.request_method,
+            request_url=resp_options.request_url,
+            sock_shutdown=_shutdown,
+        )
+        return response
+
+
+class HTTPSConnection(HTTPConnection):
+    """
+    Many of the parameters to this constructor are passed to the underlying SSL
+    socket by means of :py:func:`urllib3.util.ssl_wrap_socket`.
+    """
+
+    default_port = port_by_scheme["https"]  # type: ignore[misc]
+
+    cert_reqs: int | str | None = None
+    ca_certs: str | None = None
+    ca_cert_dir: str | None = None
+    ca_cert_data: None | str | bytes = None
+    ssl_version: int | str | None = None
+    ssl_minimum_version: int | None = None
+    ssl_maximum_version: int | None = None
+    assert_fingerprint: str | None = None
+    _connect_callback: typing.Callable[..., None] | None = None
+
+    def __init__(
+        self,
+        host: str,
+        port: int | None = None,
+        *,
+        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+        source_address: tuple[str, int] | None = None,
+        blocksize: int = 16384,
+        socket_options: None | (
+            connection._TYPE_SOCKET_OPTIONS
+        ) = HTTPConnection.default_socket_options,
+        proxy: Url | None = None,
+        proxy_config: ProxyConfig | None = None,
+        cert_reqs: int | str | None = None,
+        assert_hostname: None | str | typing.Literal[False] = None,
+        assert_fingerprint: str | None = None,
+        server_hostname: str | None = None,
+        ssl_context: ssl.SSLContext | None = None,
+        ca_certs: str | None = None,
+        ca_cert_dir: str | None = None,
+        ca_cert_data: None | str | bytes = None,
+        ssl_minimum_version: int | None = None,
+        ssl_maximum_version: int | None = None,
+        ssl_version: int | str | None = None,  # Deprecated
+        cert_file: str | None = None,
+        key_file: str | None = None,
+        key_password: str | None = None,
+    ) -> None:
+        super().__init__(
+            host,
+            port=port,
+            timeout=timeout,
+            source_address=source_address,
+            blocksize=blocksize,
+            socket_options=socket_options,
+            proxy=proxy,
+            proxy_config=proxy_config,
+        )
+
+        self.key_file = key_file
+        self.cert_file = cert_file
+        self.key_password = key_password
+        self.ssl_context = ssl_context
+        self.server_hostname = server_hostname
+        self.assert_hostname = assert_hostname
+        self.assert_fingerprint = assert_fingerprint
+        self.ssl_version = ssl_version
+        self.ssl_minimum_version = ssl_minimum_version
+        self.ssl_maximum_version = ssl_maximum_version
+        self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
+        self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
+        self.ca_cert_data = ca_cert_data
+
+        # cert_reqs depends on ssl_context so calculate last.
+        if cert_reqs is None:
+            if self.ssl_context is not None:
+                cert_reqs = self.ssl_context.verify_mode
+            else:
+                cert_reqs = resolve_cert_reqs(None)
+        self.cert_reqs = cert_reqs
+        self._connect_callback = None
+
+    def set_cert(
+        self,
+        key_file: str | None = None,
+        cert_file: str | None = None,
+        cert_reqs: int | str | None = None,
+        key_password: str | None = None,
+        ca_certs: str | None = None,
+        assert_hostname: None | str | typing.Literal[False] = None,
+        assert_fingerprint: str | None = None,
+        ca_cert_dir: str | None = None,
+        ca_cert_data: None | str | bytes = None,
+    ) -> None:
+        """
+        This method should only be called once, before the connection is used.
+        """
+        warnings.warn(
+            "HTTPSConnection.set_cert() is deprecated and will be removed "
+            "in urllib3 v3.0. Instead provide the parameters to the "
+            "HTTPSConnection constructor.",
+            category=FutureWarning,
+            stacklevel=2,
+        )
+
+        # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also
+        # have an SSLContext object in which case we'll use its verify_mode.
+        if cert_reqs is None:
+            if self.ssl_context is not None:
+                cert_reqs = self.ssl_context.verify_mode
+            else:
+                cert_reqs = resolve_cert_reqs(None)
+
+        self.key_file = key_file
+        self.cert_file = cert_file
+        self.cert_reqs = cert_reqs
+        self.key_password = key_password
+        self.assert_hostname = assert_hostname
+        self.assert_fingerprint = assert_fingerprint
+        self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
+        self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
+        self.ca_cert_data = ca_cert_data
+
+    def connect(self) -> None:
+        # Today we don't need to be doing this step before the /actual/ socket
+        # connection, however in the future we'll need to decide whether to
+        # create a new socket or re-use an existing "shared" socket as a part
+        # of the HTTP/2 handshake dance.
+        if self._tunnel_host is not None and self._tunnel_port is not None:
+            probe_http2_host = self._tunnel_host
+            probe_http2_port = self._tunnel_port
+        else:
+            probe_http2_host = self.host
+            probe_http2_port = self.port
+
+        # Check if the target origin supports HTTP/2.
+        # If the value comes back as 'None' it means that the current thread
+        # is probing for HTTP/2 support. Otherwise, we're waiting for another
+        # probe to complete, or we get a value right away.
+        target_supports_http2: bool | None
+        if "h2" in ssl_.ALPN_PROTOCOLS:
+            target_supports_http2 = http2_probe.acquire_and_get(
+                host=probe_http2_host, port=probe_http2_port
+            )
+        else:
+            # If HTTP/2 isn't going to be offered it doesn't matter if
+            # the target supports HTTP/2. Don't want to make a probe.
+            target_supports_http2 = False
+
+        if self._connect_callback is not None:
+            self._connect_callback(
+                "before connect",
+                thread_id=threading.get_ident(),
+                target_supports_http2=target_supports_http2,
+            )
+
+        try:
+            sock: socket.socket | ssl.SSLSocket
+            self.sock = sock = self._new_conn()
+            server_hostname: str = self.host
+            tls_in_tls = False
+
+            # Do we need to establish a tunnel?
+            if self.proxy_is_tunneling:
+                # We're tunneling to an HTTPS origin so need to do TLS-in-TLS.
+                if self._tunnel_scheme == "https":
+                    # _connect_tls_proxy will verify and assign proxy_is_verified
+                    self.sock = sock = self._connect_tls_proxy(self.host, sock)
+                    tls_in_tls = True
+                elif self._tunnel_scheme == "http":
+                    self.proxy_is_verified = False
+
+                # If we're tunneling it means we're connected to our proxy.
+                self._has_connected_to_proxy = True
+
+                self._tunnel()
+                # Override the host with the one we're requesting data from.
+                server_hostname = typing.cast(str, self._tunnel_host)
+
+            if self.server_hostname is not None:
+                server_hostname = self.server_hostname
+
+            is_time_off = datetime.date.today() < RECENT_DATE
+            if is_time_off:
+                warnings.warn(
+                    (
+                        f"System time is way off (before {RECENT_DATE}). This will probably "
+                        "lead to SSL verification errors"
+                    ),
+                    SystemTimeWarning,
+                )
+
+            # Remove trailing '.' from fqdn hostnames to allow certificate validation
+            server_hostname_rm_dot = server_hostname.rstrip(".")
+
+            # Forwarding proxies should use proxy SSL context for
+            # wrapping since that's the connection being established,
+            # whereas tunneling proxies should use the connection's SSL
+            # context.
+            # However, for backwards compatibility reasons, if the proxy
+            # is forwarding but no proxy SSL context is provided, we
+            # fall back to using the connection's SSL context until
+            # urllib3 v3.0. Appropriate warning is emitted in
+            # ``ProxyManager.__init__``.
+            wrapped_socket: ssl.SSLSocket | SSLTransport
+            if self.proxy_is_forwarding and self.proxy_config is not None:
+                wrapped_socket = self._connect_tls_proxy(self.host, sock)
+                is_verified = self.proxy_is_verified is True
+            else:
+                wrapped_socket, is_verified = _ssl_wrap_socket_and_match_hostname(
+                    sock=sock,
+                    cert_reqs=self.cert_reqs,
+                    ssl_version=self.ssl_version,
+                    ssl_minimum_version=self.ssl_minimum_version,
+                    ssl_maximum_version=self.ssl_maximum_version,
+                    ca_certs=self.ca_certs,
+                    ca_cert_dir=self.ca_cert_dir,
+                    ca_cert_data=self.ca_cert_data,
+                    cert_file=self.cert_file,
+                    key_file=self.key_file,
+                    key_password=self.key_password,
+                    server_hostname=server_hostname_rm_dot,
+                    ssl_context=self.ssl_context,
+                    tls_in_tls=tls_in_tls,
+                    assert_hostname=self.assert_hostname,
+                    assert_fingerprint=self.assert_fingerprint,
+                )
+            self.sock = wrapped_socket
+
+        # If an error occurs during connection/handshake we may need to release
+        # our lock so another connection can probe the origin.
+        except BaseException:
+            if self._connect_callback is not None:
+                self._connect_callback(
+                    "after connect failure",
+                    thread_id=threading.get_ident(),
+                    target_supports_http2=target_supports_http2,
+                )
+
+            if target_supports_http2 is None:
+                http2_probe.set_and_release(
+                    host=probe_http2_host, port=probe_http2_port, supports_http2=None
+                )
+            raise
+
+        # If this connection doesn't know if the origin supports HTTP/2
+        # we report back to the HTTP/2 probe our result.
+        if target_supports_http2 is None:
+            supports_http2 = wrapped_socket.selected_alpn_protocol() == "h2"
+            http2_probe.set_and_release(
+                host=probe_http2_host,
+                port=probe_http2_port,
+                supports_http2=supports_http2,
+            )
+
+        # Forwarding proxies can never have a verified target since
+        # the proxy is the one doing the verification. Should instead
+        # use a CONNECT tunnel in order to verify the target.
+        # See: https://github.com/urllib3/urllib3/issues/3267.
+        if self.proxy_is_forwarding:
+            self.is_verified = False
+        else:
+            self.is_verified = is_verified
+
+        # If there's a proxy to be connected to we are fully connected.
+        # This is set twice (once above and here) due to forwarding proxies
+        # not using tunnelling.
+        self._has_connected_to_proxy = bool(self.proxy)
+
+        # Set `self.proxy_is_verified` unless it's already set while
+        # establishing a tunnel.
+        if self._has_connected_to_proxy and self.proxy_is_verified is None:
+            self.proxy_is_verified = is_verified
+
+    def _connect_tls_proxy(self, hostname: str, sock: socket.socket) -> ssl.SSLSocket:
+        """
+        Establish a TLS connection to the proxy using proxy-specific policy.
+        """
+        proxy_config = typing.cast(ProxyConfig, self.proxy_config)
+        proxy_ssl_context = proxy_config.ssl_context
+
+        ssl_context: ssl.SSLContext | None
+        cert_reqs: int | str | None
+        if proxy_ssl_context is not None:
+            # Prefer the proxy's cert policy for the proxy connection
+            ssl_context = proxy_ssl_context
+            cert_reqs = proxy_ssl_context.verify_mode
+            ca_certs = None
+            ca_cert_dir = None
+            ca_cert_data = None
+            ssl_version = None
+            ssl_minimum_version = None
+            ssl_maximum_version = None
+        else:
+            # Otherwise we inherit the pool's cert policies
+            ssl_context = self.ssl_context if self.proxy_is_forwarding else None
+            cert_reqs = self.cert_reqs
+            ca_certs = self.ca_certs
+            ca_cert_dir = self.ca_cert_dir
+            ca_cert_data = self.ca_cert_data
+            ssl_version = self.ssl_version
+            ssl_minimum_version = self.ssl_minimum_version
+            ssl_maximum_version = self.ssl_maximum_version
+
+        sock_and_verified = _ssl_wrap_socket_and_match_hostname(
+            sock,
+            cert_reqs=cert_reqs,
+            ssl_version=ssl_version,
+            ssl_minimum_version=ssl_minimum_version,
+            ssl_maximum_version=ssl_maximum_version,
+            ca_certs=ca_certs,
+            ca_cert_dir=ca_cert_dir,
+            ca_cert_data=ca_cert_data,
+            server_hostname=hostname,
+            ssl_context=ssl_context,
+            assert_hostname=proxy_config.assert_hostname,
+            assert_fingerprint=proxy_config.assert_fingerprint,
+            # Features that aren't implemented for proxies yet:
+            cert_file=None,
+            key_file=None,
+            key_password=None,
+            tls_in_tls=False,
+        )
+        self.proxy_is_verified = sock_and_verified.is_verified
+        return sock_and_verified.socket  # type: ignore[return-value]
+
+
+class _WrappedAndVerifiedSocket(typing.NamedTuple):
+    """
+    Wrapped socket and whether the connection is
+    verified after the TLS handshake
+    """
+
+    socket: ssl.SSLSocket | SSLTransport
+    is_verified: bool
+
+
+def _ssl_wrap_socket_and_match_hostname(
+    sock: socket.socket,
+    *,
+    cert_reqs: None | str | int,
+    ssl_version: None | str | int,
+    ssl_minimum_version: int | None,
+    ssl_maximum_version: int | None,
+    cert_file: str | None,
+    key_file: str | None,
+    key_password: str | None,
+    ca_certs: str | None,
+    ca_cert_dir: str | None,
+    ca_cert_data: None | str | bytes,
+    assert_hostname: None | str | typing.Literal[False],
+    assert_fingerprint: str | None,
+    server_hostname: str | None,
+    ssl_context: ssl.SSLContext | None,
+    tls_in_tls: bool = False,
+) -> _WrappedAndVerifiedSocket:
+    """Logic for constructing an SSLContext from all TLS parameters, passing
+    that down into ssl_wrap_socket, and then doing certificate verification
+    either via hostname or fingerprint. This function exists to guarantee
+    that both proxies and targets have the same behavior when connecting via TLS.
+    """
+    default_ssl_context = False
+    if ssl_context is None:
+        default_ssl_context = True
+        context = create_urllib3_context(
+            ssl_version=resolve_ssl_version(ssl_version),
+            ssl_minimum_version=ssl_minimum_version,
+            ssl_maximum_version=ssl_maximum_version,
+            cert_reqs=resolve_cert_reqs(cert_reqs),
+        )
+    else:
+        context = ssl_context
+
+    context.verify_mode = resolve_cert_reqs(cert_reqs)
+
+    # In some cases, we want to verify hostnames ourselves
+    if (
+        # `ssl` can't verify fingerprints or alternate hostnames
+        assert_fingerprint
+        or assert_hostname
+        # assert_hostname can be set to False to disable hostname checking
+        or assert_hostname is False
+        # We still support OpenSSL 1.0.2, which prevents us from verifying
+        # hostnames easily: https://github.com/pyca/pyopenssl/pull/933
+        or ssl_.IS_PYOPENSSL
+        or not ssl_.HAS_NEVER_CHECK_COMMON_NAME
+    ):
+        context.check_hostname = False
+
+    # Try to load OS default certs if none are given. We need to do the hasattr() check
+    # for custom pyOpenSSL SSLContext objects because they don't support
+    # load_default_certs().
+    if (
+        not ca_certs
+        and not ca_cert_dir
+        and not ca_cert_data
+        and default_ssl_context
+        and hasattr(context, "load_default_certs")
+    ):
+        context.load_default_certs()
+
+    # Ensure that IPv6 addresses are in the proper format and don't have a
+    # scope ID. Python's SSL module fails to recognize scoped IPv6 addresses
+    # and interprets them as DNS hostnames.
+    if server_hostname is not None:
+        normalized = server_hostname.strip("[]")
+        if "%" in normalized:
+            normalized = normalized[: normalized.rfind("%")]
+        if is_ipaddress(normalized):
+            server_hostname = normalized
+
+    ssl_sock = ssl_wrap_socket(
+        sock=sock,
+        keyfile=key_file,
+        certfile=cert_file,
+        key_password=key_password,
+        ca_certs=ca_certs,
+        ca_cert_dir=ca_cert_dir,
+        ca_cert_data=ca_cert_data,
+        server_hostname=server_hostname,
+        ssl_context=context,
+        tls_in_tls=tls_in_tls,
+    )
+
+    try:
+        if assert_fingerprint:
+            _assert_fingerprint(
+                ssl_sock.getpeercert(binary_form=True), assert_fingerprint
+            )
+        elif (
+            context.verify_mode != ssl.CERT_NONE
+            and not context.check_hostname
+            and assert_hostname is not False
+        ):
+            cert: _TYPE_PEER_CERT_RET_DICT = ssl_sock.getpeercert()  # type: ignore[assignment]
+
+            # Need to signal to our match_hostname whether to use 'commonName' or not.
+            # If we're using our own constructed SSLContext we explicitly set 'False'
+            # because PyPy hard-codes 'True' from SSLContext.hostname_checks_common_name.
+            if default_ssl_context:
+                hostname_checks_common_name = False
+            else:
+                hostname_checks_common_name = (
+                    getattr(context, "hostname_checks_common_name", False) or False
+                )
+
+            _match_hostname(
+                cert,
+                assert_hostname or server_hostname,  # type: ignore[arg-type]
+                hostname_checks_common_name,
+            )
+
+        return _WrappedAndVerifiedSocket(
+            socket=ssl_sock,
+            is_verified=context.verify_mode == ssl.CERT_REQUIRED
+            or bool(assert_fingerprint),
+        )
+    except BaseException:
+        ssl_sock.close()
+        raise
+
+
+def _match_hostname(
+    cert: _TYPE_PEER_CERT_RET_DICT | None,
+    asserted_hostname: str,
+    hostname_checks_common_name: bool = False,
+) -> None:
+    # Our upstream implementation of ssl.match_hostname()
+    # only applies this normalization to IP addresses so it doesn't
+    # match DNS SANs so we do the same thing!
+    stripped_hostname = asserted_hostname.strip("[]")
+    if is_ipaddress(stripped_hostname):
+        asserted_hostname = stripped_hostname
+
+    try:
+        match_hostname(cert, asserted_hostname, hostname_checks_common_name)
+    except CertificateError as e:
+        log.warning(
+            "Certificate did not match expected hostname: %s. Certificate: %s",
+            asserted_hostname,
+            cert,
+        )
+        # Add cert to exception and reraise so client code can inspect
+        # the cert when catching the exception, if they want to
+        e._peer_cert = cert  # type: ignore[attr-defined]
+        raise
+
+
+def _wrap_proxy_error(err: Exception, proxy_scheme: str | None) -> ProxyError:
+    # Look for the phrase 'wrong version number', if found
+    # then we should warn the user that we're very sure that
+    # this proxy is HTTP-only and they have a configuration issue.
+    error_normalized = " ".join(re.split("[^a-z]", str(err).lower()))
+    is_likely_http_proxy = (
+        "wrong version number" in error_normalized
+        or "unknown protocol" in error_normalized
+        or "record layer failure" in error_normalized
+    )
+    http_proxy_warning = (
+        ". Your proxy appears to only use HTTP and not HTTPS, "
+        "try changing your proxy URL to be HTTP. See: "
+        "https://urllib3.readthedocs.io/en/latest/advanced-usage.html"
+        "#https-proxy-error-http-proxy"
+    )
+    new_err = ProxyError(
+        f"Unable to connect to proxy"
+        f"{http_proxy_warning if is_likely_http_proxy and proxy_scheme == 'https' else ''}",
+        err,
+    )
+    new_err.__cause__ = err
+    return new_err
+
+
+def _get_default_user_agent() -> str:
+    return f"python-urllib3/{__version__}"
+
+
+class DummyConnection:
+    """Used to detect a failed ConnectionCls import."""
+
+
+if not ssl:
+    HTTPSConnection = DummyConnection  # type: ignore[misc, assignment] # noqa: F811
+
+
+VerifiedHTTPSConnection = HTTPSConnection
+
+
+def _url_from_connection(
+    conn: HTTPConnection | HTTPSConnection, path: str | None = None
+) -> str:
+    """Returns the URL from a given connection. This is mainly used for testing and logging."""
+
+    scheme = "https" if isinstance(conn, HTTPSConnection) else "http"
+
+    return Url(scheme=scheme, host=conn.host, port=conn.port, path=path).url
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py
new file mode 100644
index 00000000000..dd1a1e05c55
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py
@@ -0,0 +1,1211 @@
+from __future__ import annotations
+
+import errno
+import logging
+import queue
+import sys
+import typing
+import warnings
+import weakref
+from socket import timeout as SocketTimeout
+from types import TracebackType
+
+from ._base_connection import _TYPE_BODY
+from ._collections import HTTPHeaderDict
+from ._request_methods import RequestMethods
+from .connection import (
+    BaseSSLError,
+    BrokenPipeError,
+    DummyConnection,
+    HTTPConnection,
+    HTTPException,
+    HTTPSConnection,
+    ProxyConfig,
+    _wrap_proxy_error,
+)
+from .connection import port_by_scheme as port_by_scheme
+from .exceptions import (
+    ClosedPoolError,
+    EmptyPoolError,
+    FullPoolError,
+    HostChangedError,
+    InsecureRequestWarning,
+    LocationValueError,
+    MaxRetryError,
+    NewConnectionError,
+    ProtocolError,
+    ProxyError,
+    ReadTimeoutError,
+    SSLError,
+    TimeoutError,
+)
+from .response import BaseHTTPResponse
+from .util.connection import is_connection_dropped
+from .util.proxy import connection_requires_http_tunnel
+from .util.request import _TYPE_BODY_POSITION, set_file_position
+from .util.retry import Retry
+from .util.ssl_match_hostname import CertificateError
+from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_DEFAULT, Timeout
+from .util.url import Url, _encode_target
+from .util.url import _normalize_host as normalize_host
+from .util.url import parse_url
+from .util.util import to_str
+
+if typing.TYPE_CHECKING:
+    import ssl
+
+    from opentelemetry.agent._vendor.typing_extensions import Self
+
+    from ._base_connection import BaseHTTPConnection, BaseHTTPSConnection
+
+log = logging.getLogger(__name__)
+
+_TYPE_TIMEOUT = typing.Union[Timeout, float, _TYPE_DEFAULT, None]
+_DEFAULT_QUEUE_CLASS = queue.LifoQueue
+
+
+# Pool objects
+class ConnectionPool:
+    """
+    Base class for all connection pools, such as
+    :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`.
+
+    .. note::
+       ConnectionPool.urlopen() does not normalize or percent-encode target URIs
+       which is useful if your target server doesn't support percent-encoded
+       target URIs.
+    """
+
+    scheme: str | None = None
+    QueueCls = _DEFAULT_QUEUE_CLASS
+
+    def __init__(self, host: str, port: int | None = None) -> None:
+        if not host:
+            raise LocationValueError("No host specified.")
+
+        self.host = _normalize_host(host, scheme=self.scheme)
+        self.port = port
+
+        # This property uses 'normalize_host()' (not '_normalize_host()')
+        # to avoid removing square braces around IPv6 addresses.
+        # This value is sent to `HTTPConnection.set_tunnel()` if called
+        # because square braces are required for HTTP CONNECT tunneling.
+        self._tunnel_host = normalize_host(host, scheme=self.scheme).lower()
+
+    def __str__(self) -> str:
+        return f"{type(self).__name__}(host={self.host!r}, port={self.port!r})"
+
+    def __enter__(self) -> Self:
+        return self
+
+    def __exit__(
+        self,
+        exc_type: type[BaseException] | None,
+        exc_val: BaseException | None,
+        exc_tb: TracebackType | None,
+    ) -> typing.Literal[False]:
+        self.close()
+        # Return False to re-raise any potential exceptions
+        return False
+
+    def close(self) -> None:
+        """
+        Close all pooled connections and disable the pool.
+        """
+
+    def _new_pool_queue(self, maxsize: int) -> queue.LifoQueue[typing.Any]:
+        if self.QueueCls is _DEFAULT_QUEUE_CLASS:
+            return queue.LifoQueue(maxsize)
+        return self.QueueCls(maxsize)
+
+
+# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
+_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}
+
+
+class HTTPConnectionPool(ConnectionPool, RequestMethods):
+    """
+    Thread-safe connection pool for one host.
+
+    :param host:
+        Host used for this HTTP Connection (e.g. "localhost"), passed into
+        :class:`http.client.HTTPConnection`.
+
+    :param port:
+        Port used for this HTTP Connection (None is equivalent to 80), passed
+        into :class:`http.client.HTTPConnection`.
+
+    :param timeout:
+        Socket timeout in seconds for each individual connection. This can
+        be a float or integer, which sets the timeout for the HTTP request,
+        or an instance of :class:`urllib3.util.Timeout` which gives you more
+        fine-grained control over request timeouts. After the constructor has
+        been parsed, this is always a `urllib3.util.Timeout` object.
+
+    :param maxsize:
+        Number of connections to save that can be reused. More than 1 is useful
+        in multithreaded situations. If ``block`` is set to False, more
+        connections will be created but they will not be saved once they've
+        been used.
+
+    :param block:
+        If set to True, no more than ``maxsize`` connections will be used at
+        a time. When no free connections are available, the call will block
+        until a connection has been released. This is a useful side effect for
+        particular multithreaded situations where one does not want to use more
+        than maxsize connections per host to prevent flooding.
+
+    :param headers:
+        Headers to include with all requests, unless other headers are given
+        explicitly.
+
+    :param retries:
+        Retry configuration to use by default with requests in this pool.
+
+    :param _proxy:
+        Parsed proxy URL, should not be used directly, instead, see
+        :class:`urllib3.ProxyManager`
+
+    :param _proxy_headers:
+        A dictionary with proxy headers, should not be used directly,
+        instead, see :class:`urllib3.ProxyManager`
+
+    :param \\**conn_kw:
+        Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`,
+        :class:`urllib3.connection.HTTPSConnection` instances.
+    """
+
+    scheme = "http"
+    ConnectionCls: type[BaseHTTPConnection] | type[BaseHTTPSConnection] = HTTPConnection
+
+    def __init__(
+        self,
+        host: str,
+        port: int | None = None,
+        timeout: _TYPE_TIMEOUT | None = _DEFAULT_TIMEOUT,
+        maxsize: int = 1,
+        block: bool = False,
+        headers: typing.Mapping[str, str] | None = None,
+        retries: Retry | bool | int | None = None,
+        _proxy: Url | None = None,
+        _proxy_headers: typing.Mapping[str, str] | None = None,
+        _proxy_config: ProxyConfig | None = None,
+        **conn_kw: typing.Any,
+    ):
+        ConnectionPool.__init__(self, host, port)
+        RequestMethods.__init__(self, headers)
+
+        if not isinstance(timeout, Timeout):
+            timeout = Timeout.from_float(timeout)
+
+        if retries is None:
+            retries = Retry.DEFAULT
+
+        self.timeout = timeout
+        self.retries = retries
+
+        self.pool: queue.LifoQueue[typing.Any] | None = self._new_pool_queue(maxsize)
+        self.block = block
+
+        self.proxy = _proxy
+        self.proxy_headers = _proxy_headers or {}
+        self.proxy_config = _proxy_config
+
+        # Fill the queue up so that doing get() on it will block properly
+        for _ in range(maxsize):
+            self.pool.put(None)
+
+        # These are mostly for testing and debugging purposes.
+        self.num_connections = 0
+        self.num_requests = 0
+        self.conn_kw = conn_kw
+
+        if self.proxy:
+            # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.
+            # Defaulting `socket_options` to an empty list avoids it defaulting to
+            # ``HTTPConnection.default_socket_options``.
+            self.conn_kw.setdefault("socket_options", [])
+
+            self.conn_kw["proxy"] = self.proxy
+            self.conn_kw["proxy_config"] = self.proxy_config
+
+        # Do not pass 'self' as callback to 'finalize'.
+        # Then the 'finalize' would keep an endless living (leak) to self.
+        # By just passing a reference to the pool allows the garbage collector
+        # to free self if nobody else has a reference to it.
+        pool = self.pool
+
+        # Close all the HTTPConnections in the pool before the
+        # HTTPConnectionPool object is garbage collected.
+        weakref.finalize(self, _close_pool_connections, pool)
+
+    def _new_conn(self) -> BaseHTTPConnection:
+        """
+        Return a fresh :class:`HTTPConnection`.
+        """
+        self.num_connections += 1
+        log.debug(
+            "Starting new HTTP connection (%d): %s:%s",
+            self.num_connections,
+            self.host,
+            self.port or "80",
+        )
+
+        conn = self.ConnectionCls(
+            host=self.host,
+            port=self.port,
+            timeout=self.timeout.connect_timeout,
+            **self.conn_kw,
+        )
+        return conn
+
+    def _get_conn(self, timeout: float | None = None) -> BaseHTTPConnection:
+        """
+        Get a connection. Will return a pooled connection if one is available.
+
+        If no connections are available and :prop:`.block` is ``False``, then a
+        fresh connection is returned.
+
+        :param timeout:
+            Seconds to wait before giving up and raising
+            :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and
+            :prop:`.block` is ``True``.
+        """
+        conn = None
+
+        if self.pool is None:
+            raise ClosedPoolError(self, "Pool is closed.")
+
+        try:
+            conn = self.pool.get(block=self.block, timeout=timeout)
+
+        except AttributeError:  # self.pool is None
+            raise ClosedPoolError(self, "Pool is closed.") from None  # Defensive:
+
+        except queue.Empty:
+            if self.block:
+                raise EmptyPoolError(
+                    self,
+                    "Pool is empty and a new connection can't be opened due to blocking mode.",
+                ) from None
+            pass  # Oh well, we'll create a new connection then
+
+        # If this is a persistent connection, check if it got disconnected
+        if conn and is_connection_dropped(conn):
+            log.debug("Resetting dropped connection: %s", self.host)
+            conn.close()
+
+        return conn or self._new_conn()
+
+    def _put_conn(self, conn: BaseHTTPConnection | None) -> None:
+        """
+        Put a connection back into the pool.
+
+        :param conn:
+            Connection object for the current host and port as returned by
+            :meth:`._new_conn` or :meth:`._get_conn`.
+
+        If the pool is already full, the connection is closed and discarded
+        because we exceeded maxsize. If connections are discarded frequently,
+        then maxsize should be increased.
+
+        If the pool is closed, then the connection will be closed and discarded.
+        """
+        if self.pool is not None:
+            try:
+                self.pool.put(conn, block=False)
+                return  # Everything is dandy, done.
+            except AttributeError:
+                # self.pool is None.
+                pass
+            except queue.Full:
+                # Connection never got put back into the pool, close it.
+                if conn:
+                    conn.close()
+
+                if self.block:
+                    # This should never happen if you got the conn from self._get_conn
+                    raise FullPoolError(
+                        self,
+                        "Pool reached maximum size and no more connections are allowed.",
+                    ) from None
+
+                log.warning(
+                    "Connection pool is full, discarding connection: %s. Connection pool size: %s",
+                    self.host,
+                    self.pool.qsize(),
+                )
+
+        # Connection never got put back into the pool, close it.
+        if conn:
+            conn.close()
+
+    def _validate_conn(self, conn: BaseHTTPConnection) -> None:
+        """
+        Called right before a request is made, after the socket is created.
+        """
+
+    def _prepare_proxy(self, conn: BaseHTTPConnection) -> None:
+        # Nothing to do for HTTP connections.
+        pass
+
+    def _get_timeout(self, timeout: _TYPE_TIMEOUT) -> Timeout:
+        """Helper that always returns a :class:`urllib3.util.Timeout`"""
+        if timeout is _DEFAULT_TIMEOUT:
+            return self.timeout.clone()
+
+        if isinstance(timeout, Timeout):
+            return timeout.clone()
+        else:
+            # User passed us an int/float. This is for backwards compatibility,
+            # can be removed later
+            return Timeout.from_float(timeout)
+
+    def _raise_timeout(
+        self,
+        err: BaseSSLError | OSError | SocketTimeout,
+        url: str,
+        timeout_value: _TYPE_TIMEOUT | None,
+    ) -> None:
+        """Is the error actually a timeout? Will raise a ReadTimeout or pass"""
+
+        if isinstance(err, SocketTimeout):
+            raise ReadTimeoutError(
+                self, url, f"Read timed out. (read timeout={timeout_value})"
+            ) from err
+
+        # See the above comment about EAGAIN in Python 3.
+        if hasattr(err, "errno") and err.errno in _blocking_errnos:
+            raise ReadTimeoutError(
+                self, url, f"Read timed out. (read timeout={timeout_value})"
+            ) from err
+
+    def _make_request(
+        self,
+        conn: BaseHTTPConnection,
+        method: str,
+        url: str,
+        body: _TYPE_BODY | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        retries: Retry | None = None,
+        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+        chunked: bool = False,
+        response_conn: BaseHTTPConnection | None = None,
+        preload_content: bool = True,
+        decode_content: bool = True,
+        enforce_content_length: bool = True,
+    ) -> BaseHTTPResponse:
+        """
+        Perform a request on a given urllib connection object taken from our
+        pool.
+
+        :param conn:
+            a connection from one of our connection pools
+
+        :param method:
+            HTTP request method (such as GET, POST, PUT, etc.)
+
+        :param url:
+            The URL to perform the request on.
+
+        :param body:
+            Data to send in the request body, either :class:`str`, :class:`bytes`,
+            an iterable of :class:`str`/:class:`bytes`, or a file-like object.
+
+        :param headers:
+            Dictionary of custom headers to send, such as User-Agent,
+            If-None-Match, etc. If None, pool headers are used. If provided,
+            these headers completely replace any pool-specific headers.
+
+        :param retries:
+            Configure the number of retries to allow before raising a
+            :class:`~urllib3.exceptions.MaxRetryError` exception.
+
+            Pass ``None`` to retry until you receive a response. Pass a
+            :class:`~urllib3.util.retry.Retry` object for fine-grained control
+            over different types of retries.
+            Pass an integer number to retry connection errors that many times,
+            but no other types of errors. Pass zero to never retry.
+
+            If ``False``, then retries are disabled and any exception is raised
+            immediately. Also, instead of raising a MaxRetryError on redirects,
+            the redirect response will be returned.
+
+        :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
+
+        :param timeout:
+            If specified, overrides the default timeout for this one
+            request. It may be a float (in seconds) or an instance of
+            :class:`urllib3.util.Timeout`.
+
+        :param chunked:
+            If True, urllib3 will send the body using chunked transfer
+            encoding. Otherwise, urllib3 will send the body using the standard
+            content-length form. Defaults to False.
+
+        :param response_conn:
+            Set this to ``None`` if you will handle releasing the connection or
+            set the connection to have the response release it.
+
+        :param preload_content:
+          If True, the response's body will be preloaded during construction.
+
+        :param decode_content:
+            If True, will attempt to decode the body based on the
+            'content-encoding' header.
+
+        :param enforce_content_length:
+            Enforce content length checking. Body returned by server must match
+            value of Content-Length header, if present. Otherwise, raise error.
+        """
+        self.num_requests += 1
+
+        timeout_obj = self._get_timeout(timeout)
+        timeout_obj.start_connect()
+        conn.timeout = Timeout.resolve_default_timeout(timeout_obj.connect_timeout)
+
+        try:
+            # Trigger any extra validation we need to do.
+            try:
+                self._validate_conn(conn)
+            except (SocketTimeout, BaseSSLError) as e:
+                self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
+                raise
+
+        # _validate_conn() starts the connection to an HTTPS proxy
+        # so we need to wrap errors with 'ProxyError' here too.
+        except (
+            OSError,
+            NewConnectionError,
+            TimeoutError,
+            BaseSSLError,
+            CertificateError,
+            SSLError,
+        ) as e:
+            new_e: Exception = e
+            if isinstance(e, (BaseSSLError, CertificateError)):
+                new_e = SSLError(e)
+            # If the connection didn't successfully connect to it's proxy
+            # then there
+            if isinstance(
+                new_e, (OSError, NewConnectionError, TimeoutError, SSLError)
+            ) and (conn and conn.proxy and not conn.has_connected_to_proxy):
+                new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
+            raise new_e
+
+        # conn.request() calls http.client.*.request, not the method in
+        # urllib3.request. It also calls makefile (recv) on the socket.
+        try:
+            conn.request(
+                method,
+                url,
+                body=body,
+                headers=headers,
+                chunked=chunked,
+                preload_content=preload_content,
+                decode_content=decode_content,
+                enforce_content_length=enforce_content_length,
+            )
+
+        # We are swallowing BrokenPipeError (errno.EPIPE) since the server is
+        # legitimately able to close the connection after sending a valid response.
+        # With this behaviour, the received response is still readable.
+        except BrokenPipeError:
+            pass
+        except OSError as e:
+            # MacOS/Linux
+            # EPROTOTYPE and ECONNRESET are needed on macOS
+            # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/
+            # Condition changed later to emit ECONNRESET instead of only EPROTOTYPE.
+            if e.errno != errno.EPROTOTYPE and e.errno != errno.ECONNRESET:
+                raise
+
+        # Reset the timeout for the recv() on the socket
+        read_timeout = timeout_obj.read_timeout
+
+        if not conn.is_closed:
+            # In Python 3 socket.py will catch EAGAIN and return None when you
+            # try and read into the file pointer created by http.client, which
+            # instead raises a BadStatusLine exception. Instead of catching
+            # the exception and assuming all BadStatusLine exceptions are read
+            # timeouts, check for a zero timeout before making the request.
+            if read_timeout == 0:
+                raise ReadTimeoutError(
+                    self, url, f"Read timed out. (read timeout={read_timeout})"
+                )
+            conn.timeout = read_timeout
+
+        # Receive the response from the server
+        try:
+            response = conn.getresponse()
+        except (BaseSSLError, OSError) as e:
+            self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
+            raise
+
+        # Set properties that are used by the pooling layer.
+        response.retries = retries
+        response._connection = response_conn  # type: ignore[attr-defined]
+        response._pool = self  # type: ignore[attr-defined]
+
+        log.debug(
+            '%s://%s:%s "%s %s %s" %s %s',
+            self.scheme,
+            self.host,
+            self.port,
+            method,
+            url,
+            response.version_string,
+            response.status,
+            response.length_remaining,
+        )
+
+        return response
+
+    def close(self) -> None:
+        """
+        Close all pooled connections and disable the pool.
+        """
+        if self.pool is None:
+            return
+        # Disable access to the pool
+        old_pool, self.pool = self.pool, None
+
+        # Close all the HTTPConnections in the pool.
+        _close_pool_connections(old_pool)
+
+    def is_same_host(self, url: str) -> bool:
+        """
+        Check if the given ``url`` is a member of the same host as this
+        connection pool.
+        """
+        if url.startswith("/"):
+            return True
+
+        # TODO: Add optional support for socket.gethostbyname checking.
+        scheme, _, host, port, *_ = parse_url(url)
+        scheme = scheme or "http"
+        if host is not None:
+            host = _normalize_host(host, scheme=scheme)
+
+        # Use explicit default port for comparison when none is given
+        if self.port is not None and port is None:
+            port = port_by_scheme.get(scheme)
+        elif self.port is None and port == port_by_scheme.get(scheme):
+            port = None
+
+        return (scheme, host, port) == (self.scheme, self.host, self.port)
+
+    def urlopen(  # type: ignore[override]
+        self,
+        method: str,
+        url: str,
+        body: _TYPE_BODY | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        retries: Retry | bool | int | None = None,
+        redirect: bool = True,
+        assert_same_host: bool = True,
+        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+        pool_timeout: int | None = None,
+        release_conn: bool | None = None,
+        chunked: bool = False,
+        body_pos: _TYPE_BODY_POSITION | None = None,
+        preload_content: bool = True,
+        decode_content: bool = True,
+        **response_kw: typing.Any,
+    ) -> BaseHTTPResponse:
+        """
+        Get a connection from the pool and perform an HTTP request. This is the
+        lowest level call for making a request, so you'll need to specify all
+        the raw details.
+
+        .. note::
+
+           More commonly, it's appropriate to use a convenience method
+           such as :meth:`request`.
+
+        .. note::
+
+           `release_conn` will only behave as expected if
+           `preload_content=False` because we want to make
+           `preload_content=False` the default behaviour someday soon without
+           breaking backwards compatibility.
+
+        :param method:
+            HTTP request method (such as GET, POST, PUT, etc.)
+
+        :param url:
+            The URL to perform the request on.
+
+        :param body:
+            Data to send in the request body, either :class:`str`, :class:`bytes`,
+            an iterable of :class:`str`/:class:`bytes`, or a file-like object.
+
+        :param headers:
+            Dictionary of custom headers to send, such as User-Agent,
+            If-None-Match, etc. If None, pool headers are used. If provided,
+            these headers completely replace any pool-specific headers.
+
+        :param retries:
+            Configure the number of retries to allow before raising a
+            :class:`~urllib3.exceptions.MaxRetryError` exception.
+
+            If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a
+            :class:`~urllib3.util.retry.Retry` object for fine-grained control
+            over different types of retries.
+            Pass an integer number to retry connection errors that many times,
+            but no other types of errors. Pass zero to never retry.
+
+            If ``False``, then retries are disabled and any exception is raised
+            immediately. Also, instead of raising a MaxRetryError on redirects,
+            the redirect response will be returned.
+
+        :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
+
+        :param redirect:
+            If True, automatically handle redirects (status codes 301, 302,
+            303, 307, 308). Each redirect counts as a retry. Disabling retries
+            will disable redirect, too.
+
+        :param assert_same_host:
+            If ``True``, will make sure that the host of the pool requests is
+            consistent else will raise HostChangedError. When ``False``, you can
+            use the pool on an HTTP proxy and request foreign hosts.
+
+        :param timeout:
+            If specified, overrides the default timeout for this one
+            request. It may be a float (in seconds) or an instance of
+            :class:`urllib3.util.Timeout`.
+
+        :param pool_timeout:
+            If set and the pool is set to block=True, then this method will
+            block for ``pool_timeout`` seconds and raise EmptyPoolError if no
+            connection is available within the time period.
+
+        :param bool preload_content:
+            If True, the response's body will be preloaded into memory.
+
+        :param bool decode_content:
+            If True, will attempt to decode the body based on the
+            'content-encoding' header.
+
+        :param release_conn:
+            If False, then the urlopen call will not release the connection
+            back into the pool once a response is received (but will release if
+            you read the entire contents of the response such as when
+            `preload_content=True`). This is useful if you're not preloading
+            the response's content immediately. You will need to call
+            ``r.release_conn()`` on the response ``r`` to return the connection
+            back into the pool. If None, it takes the value of ``preload_content``
+            which defaults to ``True``.
+
+        :param bool chunked:
+            If True, urllib3 will send the body using chunked transfer
+            encoding. Otherwise, urllib3 will send the body using the standard
+            content-length form. Defaults to False.
+
+        :param int body_pos:
+            Position to seek to in file-like body in the event of a retry or
+            redirect. Typically this won't need to be set because urllib3 will
+            auto-populate the value when needed.
+        """
+        # Ensure that the URL we're connecting to is properly encoded
+        if url.startswith("/"):
+            # URLs starting with / are inherently schemeless.
+            url = to_str(_encode_target(url))
+            destination_scheme = None
+        else:
+            parsed_url = parse_url(url)
+            destination_scheme = parsed_url.scheme
+            url = to_str(parsed_url._replace(fragment=None).url)
+
+        if headers is None:
+            headers = self.headers
+
+        if not isinstance(retries, Retry):
+            retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
+
+        if release_conn is None:
+            release_conn = preload_content
+
+        # Check host
+        if assert_same_host and not self.is_same_host(url):
+            raise HostChangedError(self, url, retries)
+
+        conn = None
+
+        # Track whether `conn` needs to be released before
+        # returning/raising/recursing. Update this variable if necessary, and
+        # leave `release_conn` constant throughout the function. That way, if
+        # the function recurses, the original value of `release_conn` will be
+        # passed down into the recursive call, and its value will be respected.
+        #
+        # See issue #651 [1] for details.
+        #
+        # [1] 
+        release_this_conn = release_conn
+
+        http_tunnel_required = connection_requires_http_tunnel(
+            self.proxy, self.proxy_config, destination_scheme
+        )
+
+        # Merge the proxy headers. Only done when not using HTTP CONNECT. We
+        # have to copy the headers dict so we can safely change it without those
+        # changes being reflected in anyone else's copy.
+        if not http_tunnel_required:
+            headers = headers.copy()  # type: ignore[attr-defined]
+            headers.update(self.proxy_headers)  # type: ignore[union-attr]
+
+        # Must keep the exception bound to a separate variable or else Python 3
+        # complains about UnboundLocalError.
+        err = None
+
+        # Keep track of whether we cleanly exited the except block. This
+        # ensures we do proper cleanup in finally.
+        clean_exit = False
+
+        # Rewind body position, if needed. Record current position
+        # for future rewinds in the event of a redirect/retry.
+        body_pos = set_file_position(body, body_pos)
+
+        timeout_obj = self._get_timeout(timeout)
+        try:
+            # Request a connection from the queue.
+            conn = self._get_conn(timeout=pool_timeout)
+            conn.timeout = timeout_obj.connect_timeout  # type: ignore[assignment]
+
+            # Is this a closed/new connection that requires CONNECT tunnelling?
+            if self.proxy is not None and http_tunnel_required and conn.is_closed:
+                try:
+                    self._prepare_proxy(conn)
+                except (BaseSSLError, OSError, SocketTimeout) as e:
+                    self._raise_timeout(
+                        err=e, url=self.proxy.url, timeout_value=conn.timeout
+                    )
+                    raise
+
+            # If we're going to release the connection in ``finally:``, then
+            # the response doesn't need to know about the connection. Otherwise
+            # it will also try to release it and we'll have a double-release
+            # mess.
+            response_conn = conn if not release_conn else None
+
+            # Make the request on the HTTPConnection object
+            response = self._make_request(
+                conn,
+                method,
+                url,
+                timeout=timeout_obj,
+                body=body,
+                headers=headers,
+                chunked=chunked,
+                retries=retries,
+                response_conn=response_conn,
+                preload_content=preload_content,
+                decode_content=decode_content,
+                **response_kw,
+            )
+
+            # Everything went great!
+            clean_exit = True
+
+        except EmptyPoolError:
+            # Didn't get a connection from the pool, no need to clean up
+            clean_exit = True
+            release_this_conn = False
+            raise
+
+        except (
+            TimeoutError,
+            HTTPException,
+            OSError,
+            ProtocolError,
+            BaseSSLError,
+            SSLError,
+            CertificateError,
+            ProxyError,
+        ) as e:
+            # Discard the connection for these exceptions. It will be
+            # replaced during the next _get_conn() call.
+            clean_exit = False
+            new_e: Exception = e
+            if isinstance(e, (BaseSSLError, CertificateError)):
+                new_e = SSLError(e)
+            if isinstance(
+                new_e,
+                (
+                    OSError,
+                    NewConnectionError,
+                    TimeoutError,
+                    SSLError,
+                    HTTPException,
+                ),
+            ) and (conn and conn.proxy and not conn.has_connected_to_proxy):
+                new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
+            elif isinstance(new_e, (OSError, HTTPException)):
+                new_e = ProtocolError("Connection aborted.", new_e)
+
+            retries = retries.increment(
+                method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]
+            )
+            retries.sleep()
+
+            # Keep track of the error for the retry warning.
+            err = e
+
+        finally:
+            if not clean_exit:
+                # We hit some kind of exception, handled or otherwise. We need
+                # to throw the connection away unless explicitly told not to.
+                # Close the connection, set the variable to None, and make sure
+                # we put the None back in the pool to avoid leaking it.
+                if conn:
+                    conn.close()
+                    conn = None
+                release_this_conn = True
+
+            if release_this_conn:
+                # Put the connection back to be reused. If the connection is
+                # expired then it will be None, which will get replaced with a
+                # fresh connection during _get_conn.
+                self._put_conn(conn)
+
+        if not conn:
+            # Try again
+            log.warning(
+                "Retrying (%r) after connection broken by '%r': %s",
+                retries,
+                err,
+                url,
+                # Provide an unique attribute with the host needed by pip to
+                # rewrite this warning. Ideally, we'd go with a better solution,
+                # but backwards compatibility and other constraints make those
+                # unfeasible, so this is the least bad option.
+                # See also: https://github.com/urllib3/urllib3/issues/2580.
+                extra={"__urllib3-retry-warning": {"host": self.host}},
+            )
+            return self.urlopen(
+                method,
+                url,
+                body,
+                headers,
+                retries,
+                redirect,
+                assert_same_host,
+                timeout=timeout,
+                pool_timeout=pool_timeout,
+                release_conn=release_conn,
+                chunked=chunked,
+                body_pos=body_pos,
+                preload_content=preload_content,
+                decode_content=decode_content,
+                **response_kw,
+            )
+
+        # Handle redirect?
+        redirect_location = redirect and response.get_redirect_location()
+        if redirect_location:
+            if response.status == 303:
+                # Change the method according to RFC 9110, Section 15.4.4.
+                method = "GET"
+                # And lose the body not to transfer anything sensitive.
+                body = None
+                # The body is gone, so the state that describes it has to go
+                # too: there is nothing left to frame with chunked transfer
+                # encoding, and nothing left to rewind.
+                chunked = False
+                body_pos = None
+                headers = HTTPHeaderDict(headers)._prepare_for_method_change()
+
+            # Strip headers marked as unsafe to forward to the redirected location.
+            # Check remove_headers_on_redirect to avoid a potential network call within
+            # self.is_same_host() which may use socket.gethostbyname() in the future.
+            if retries.remove_headers_on_redirect and not self.is_same_host(
+                redirect_location
+            ):
+                new_headers = headers.copy()  # type: ignore[union-attr]
+                for header in headers:
+                    if header.lower() in retries.remove_headers_on_redirect:
+                        new_headers.pop(header, None)
+                headers = new_headers
+
+            try:
+                retries = retries.increment(method, url, response=response, _pool=self)
+            except MaxRetryError:
+                if retries.raise_on_redirect:
+                    response.drain_conn()
+                    raise
+                return response
+
+            response.drain_conn()
+            retries.sleep_for_retry(response)
+            log.debug("Redirecting %s -> %s", url, redirect_location)
+            return self.urlopen(
+                method,
+                redirect_location,
+                body,
+                headers,
+                retries=retries,
+                redirect=redirect,
+                assert_same_host=assert_same_host,
+                timeout=timeout,
+                pool_timeout=pool_timeout,
+                release_conn=release_conn,
+                chunked=chunked,
+                body_pos=body_pos,
+                preload_content=preload_content,
+                decode_content=decode_content,
+                **response_kw,
+            )
+
+        # Check if we should retry the HTTP response.
+        has_retry_after = bool(response.headers.get("Retry-After"))
+        if retries.is_retry(method, response.status, has_retry_after):
+            try:
+                retries = retries.increment(method, url, response=response, _pool=self)
+            except MaxRetryError:
+                if retries.raise_on_status:
+                    response.drain_conn()
+                    raise
+                return response
+
+            response.drain_conn()
+            retries.sleep(response)
+            log.debug("Retry: %s", url)
+            return self.urlopen(
+                method,
+                url,
+                body,
+                headers,
+                retries=retries,
+                redirect=redirect,
+                assert_same_host=assert_same_host,
+                timeout=timeout,
+                pool_timeout=pool_timeout,
+                release_conn=release_conn,
+                chunked=chunked,
+                body_pos=body_pos,
+                preload_content=preload_content,
+                decode_content=decode_content,
+                **response_kw,
+            )
+
+        return response
+
+
+class HTTPSConnectionPool(HTTPConnectionPool):
+    """
+    Same as :class:`.HTTPConnectionPool`, but HTTPS.
+
+    :class:`.HTTPSConnection` uses one of ``assert_fingerprint``,
+    ``assert_hostname`` and ``host`` in this order to verify connections.
+    If ``assert_hostname`` is False, no verification is done.
+
+    The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``,
+    ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl`
+    is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade
+    the connection socket into an SSL socket.
+    """
+
+    scheme = "https"
+    ConnectionCls: type[BaseHTTPSConnection] = HTTPSConnection
+
+    def __init__(
+        self,
+        host: str,
+        port: int | None = None,
+        timeout: _TYPE_TIMEOUT | None = _DEFAULT_TIMEOUT,
+        maxsize: int = 1,
+        block: bool = False,
+        headers: typing.Mapping[str, str] | None = None,
+        retries: Retry | bool | int | None = None,
+        _proxy: Url | None = None,
+        _proxy_headers: typing.Mapping[str, str] | None = None,
+        key_file: str | None = None,
+        cert_file: str | None = None,
+        cert_reqs: int | str | None = None,
+        key_password: str | None = None,
+        ca_certs: str | None = None,
+        ssl_version: int | str | None = None,
+        ssl_minimum_version: ssl.TLSVersion | None = None,
+        ssl_maximum_version: ssl.TLSVersion | None = None,
+        assert_hostname: str | typing.Literal[False] | None = None,
+        assert_fingerprint: str | None = None,
+        ca_cert_dir: str | None = None,
+        **conn_kw: typing.Any,
+    ) -> None:
+        super().__init__(
+            host,
+            port,
+            timeout,
+            maxsize,
+            block,
+            headers,
+            retries,
+            _proxy,
+            _proxy_headers,
+            **conn_kw,
+        )
+
+        self.key_file = key_file
+        self.cert_file = cert_file
+        self.cert_reqs = cert_reqs
+        self.key_password = key_password
+        self.ca_certs = ca_certs
+        self.ca_cert_dir = ca_cert_dir
+        self.ssl_version = ssl_version
+        self.ssl_minimum_version = ssl_minimum_version
+        self.ssl_maximum_version = ssl_maximum_version
+        self.assert_hostname = assert_hostname
+        self.assert_fingerprint = assert_fingerprint
+
+    def _prepare_proxy(self, conn: HTTPSConnection) -> None:  # type: ignore[override]
+        """Establishes a tunnel connection through HTTP CONNECT."""
+        if self.proxy and self.proxy.scheme == "https":
+            tunnel_scheme = "https"
+        else:
+            tunnel_scheme = "http"
+
+        conn.set_tunnel(
+            scheme=tunnel_scheme,
+            host=self._tunnel_host,
+            port=self.port,
+            headers=self.proxy_headers,
+        )
+        conn.connect()
+
+    def _new_conn(self) -> BaseHTTPSConnection:
+        """
+        Return a fresh :class:`urllib3.connection.HTTPConnection`.
+        """
+        self.num_connections += 1
+        log.debug(
+            "Starting new HTTPS connection (%d): %s:%s",
+            self.num_connections,
+            self.host,
+            self.port or "443",
+        )
+
+        if not self.ConnectionCls or self.ConnectionCls is DummyConnection:  # type: ignore[comparison-overlap]
+            raise ImportError(
+                "Can't connect to HTTPS URL because the SSL module is not available."
+            )
+
+        actual_host: str = self.host
+        actual_port = self.port
+        if self.proxy is not None and self.proxy.host is not None:
+            actual_host = self.proxy.host
+            actual_port = self.proxy.port
+
+        return self.ConnectionCls(
+            host=actual_host,
+            port=actual_port,
+            timeout=self.timeout.connect_timeout,
+            cert_file=self.cert_file,
+            key_file=self.key_file,
+            key_password=self.key_password,
+            cert_reqs=self.cert_reqs,
+            ca_certs=self.ca_certs,
+            ca_cert_dir=self.ca_cert_dir,
+            assert_hostname=self.assert_hostname,
+            assert_fingerprint=self.assert_fingerprint,
+            ssl_version=self.ssl_version,
+            ssl_minimum_version=self.ssl_minimum_version,
+            ssl_maximum_version=self.ssl_maximum_version,
+            **self.conn_kw,
+        )
+
+    def _validate_conn(self, conn: BaseHTTPConnection) -> None:
+        """
+        Called right before a request is made, after the socket is created.
+        """
+        super()._validate_conn(conn)
+
+        # Force connect early to allow us to validate the connection.
+        if conn.is_closed:
+            conn.connect()
+
+        # TODO revise this, see https://github.com/urllib3/urllib3/issues/2791
+        if not conn.is_verified and not conn.proxy_is_verified:
+            warnings.warn(
+                (
+                    f"Unverified HTTPS request is being made to host '{conn.host}'. "
+                    "Adding certificate verification is strongly advised. See: "
+                    "https://urllib3.readthedocs.io/en/latest/advanced-usage.html"
+                    "#tls-warnings"
+                ),
+                InsecureRequestWarning,
+            )
+
+
+def connection_from_url(url: str, **kw: typing.Any) -> HTTPConnectionPool:
+    """
+    Given a url, return an :class:`.ConnectionPool` instance of its host.
+
+    This is a shortcut for not having to parse out the scheme, host, and port
+    of the url before creating an :class:`.ConnectionPool` instance.
+
+    :param url:
+        Absolute URL string that must include the scheme. Port is optional.
+
+    :param \\**kw:
+        Passes additional parameters to the constructor of the appropriate
+        :class:`.ConnectionPool`. Useful for specifying things like
+        timeout, maxsize, headers, etc.
+
+    Example::
+
+        >>> conn = connection_from_url('http://google.com/')
+        >>> r = conn.request('GET', '/')
+    """
+    scheme, _, host, port, *_ = parse_url(url)
+    scheme = scheme or "http"
+    if port is None:
+        port = port_by_scheme.get(scheme, 80)
+    if scheme == "https":
+        return HTTPSConnectionPool(host, port=port, **kw)  # type: ignore[arg-type]
+    else:
+        return HTTPConnectionPool(host, port=port, **kw)  # type: ignore[arg-type]
+
+
+@typing.overload
+def _normalize_host(host: None, scheme: str | None) -> None: ...
+
+
+@typing.overload
+def _normalize_host(host: str, scheme: str | None) -> str: ...
+
+
+def _normalize_host(host: str | None, scheme: str | None) -> str | None:
+    """
+    Normalize hosts for comparisons and use with sockets.
+    """
+
+    host = normalize_host(host, scheme)
+
+    # httplib doesn't like it when we include brackets in IPv6 addresses
+    # Specifically, if we include brackets but also pass the port then
+    # httplib crazily doubles up the square brackets on the Host header.
+    # Instead, we need to make sure we never pass ``None`` as the port.
+    # However, for backward compatibility reasons we can't actually
+    # *assert* that.  See http://bugs.python.org/issue28539
+    if host and host.startswith("[") and host.endswith("]"):
+        host = host[1:-1]
+    return host
+
+
+def _url_from_pool(
+    pool: HTTPConnectionPool | HTTPSConnectionPool, path: str | None = None
+) -> str:
+    """Returns the URL from a given connection pool. This is mainly used for testing and logging."""
+    return Url(scheme=pool.scheme, host=pool.host, port=pool.port, path=path).url
+
+
+def _close_pool_connections(pool: queue.LifoQueue[typing.Any]) -> None:
+    """Drains a queue of connections and closes each one."""
+    try:
+        while True:
+            conn = pool.get(block=False)
+            if conn:
+                conn.close()
+    except queue.Empty:
+        pass  # Done.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/contrib/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/contrib/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py
new file mode 100644
index 00000000000..3d7e9b93d30
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py
@@ -0,0 +1,335 @@
+from __future__ import annotations
+
+import socket
+import typing
+import warnings
+from email.errors import MessageDefect
+from http.client import IncompleteRead as httplib_IncompleteRead
+
+if typing.TYPE_CHECKING:
+    from .connection import HTTPConnection
+    from .connectionpool import ConnectionPool
+    from .response import HTTPResponse
+    from .util.retry import Retry
+
+# Base Exceptions
+
+
+class HTTPError(Exception):
+    """Base exception used by this module."""
+
+
+class HTTPWarning(Warning):
+    """Base warning used by this module."""
+
+
+_TYPE_REDUCE_RESULT = tuple[typing.Callable[..., object], tuple[object, ...]]
+
+
+class PoolError(HTTPError):
+    """Base exception for errors caused within a pool."""
+
+    def __init__(self, pool: ConnectionPool, message: str) -> None:
+        self.pool = pool
+        self._message = message
+        super().__init__(f"{pool}: {message}")
+
+    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
+        # For pickling purposes.
+        return self.__class__, (None, self._message)
+
+
+class RequestError(PoolError):
+    """Base exception for PoolErrors that have associated URLs."""
+
+    def __init__(self, pool: ConnectionPool, url: str | None, message: str) -> None:
+        self.url = url
+        super().__init__(pool, message)
+
+    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
+        # For pickling purposes.
+        return self.__class__, (None, self.url, self._message)
+
+
+class SSLError(HTTPError):
+    """Raised when SSL certificate fails in an HTTPS connection."""
+
+
+class ProxyError(HTTPError):
+    """Raised when the connection to a proxy fails."""
+
+    # The original error is also available as __cause__.
+    original_error: Exception
+
+    def __init__(self, message: str, error: Exception) -> None:
+        super().__init__(message, error)
+        self.original_error = error
+
+
+class DecodeError(HTTPError):
+    """Raised when automatic decoding based on Content-Type fails."""
+
+
+class ProtocolError(HTTPError):
+    """Raised when something unexpected happens mid-request/response."""
+
+
+#: Renamed to ProtocolError but aliased for backwards compatibility.
+ConnectionError = ProtocolError
+
+
+# Leaf Exceptions
+
+
+class MaxRetryError(RequestError):
+    """Raised when the maximum number of retries is exceeded.
+
+    :param pool: The connection pool
+    :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool`
+    :param str url: The requested Url
+    :param reason: The underlying error
+    :type reason: :class:`Exception`
+
+    """
+
+    def __init__(
+        self, pool: ConnectionPool, url: str | None, reason: Exception | None = None
+    ) -> None:
+        self.reason = reason
+
+        message = f"Max retries exceeded with url: {url} (Caused by {reason!r})"
+
+        super().__init__(pool, url, message)
+
+    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
+        # For pickling purposes.
+        return self.__class__, (None, self.url, self.reason)
+
+
+class HostChangedError(RequestError):
+    """Raised when an existing pool gets a request for a foreign host."""
+
+    def __init__(
+        self, pool: ConnectionPool, url: str, retries: Retry | int = 3
+    ) -> None:
+        message = f"Tried to open a foreign host with url: {url}"
+        super().__init__(pool, url, message)
+        self.retries = retries
+
+
+class TimeoutStateError(HTTPError):
+    """Raised when passing an invalid state to a timeout"""
+
+
+class TimeoutError(HTTPError):
+    """Raised when a socket timeout error occurs.
+
+    Catching this error will catch both :exc:`ReadTimeoutErrors
+    ` and :exc:`ConnectTimeoutErrors `.
+    """
+
+
+class ReadTimeoutError(TimeoutError, RequestError):
+    """Raised when a socket timeout occurs while receiving data from a server"""
+
+
+# This timeout error does not have a URL attached and needs to inherit from the
+# base HTTPError
+class ConnectTimeoutError(TimeoutError):
+    """Raised when a socket timeout occurs while connecting to a server"""
+
+
+class NewConnectionError(ConnectTimeoutError, HTTPError):
+    """Raised when we fail to establish a new connection. Usually ECONNREFUSED."""
+
+    def __init__(self, conn: HTTPConnection, message: str) -> None:
+        self.conn = conn
+        self._message = message
+        super().__init__(f"{conn}: {message}")
+
+    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
+        # For pickling purposes.
+        return self.__class__, (None, self._message)
+
+    @property
+    def pool(self) -> HTTPConnection:
+        warnings.warn(
+            "The 'pool' property is deprecated and will be removed "
+            "in urllib3 v3.0. Use 'conn' instead.",
+            FutureWarning,
+            stacklevel=2,
+        )
+
+        return self.conn
+
+
+class NameResolutionError(NewConnectionError):
+    """Raised when host name resolution fails."""
+
+    def __init__(self, host: str, conn: HTTPConnection, reason: socket.gaierror):
+        message = f"Failed to resolve '{host}' ({reason})"
+        self._host = host
+        self._reason = reason
+        super().__init__(conn, message)
+
+    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
+        # For pickling purposes.
+        return self.__class__, (self._host, None, self._reason)
+
+
+class EmptyPoolError(PoolError):
+    """Raised when a pool runs out of connections and no more are allowed."""
+
+
+class FullPoolError(PoolError):
+    """Raised when we try to add a connection to a full pool in blocking mode."""
+
+
+class ClosedPoolError(PoolError):
+    """Raised when a request enters a pool after the pool has been closed."""
+
+
+class LocationValueError(ValueError, HTTPError):
+    """Raised when there is something wrong with a given URL input."""
+
+
+class LocationParseError(LocationValueError):
+    """Raised when get_host or similar fails to parse the URL input."""
+
+    def __init__(self, location: str) -> None:
+        message = f"Failed to parse: {location}"
+        super().__init__(message)
+
+        self.location = location
+
+
+class URLSchemeUnknown(LocationValueError):
+    """Raised when a URL input has an unsupported scheme."""
+
+    def __init__(self, scheme: str):
+        message = f"Not supported URL scheme {scheme}"
+        super().__init__(message)
+
+        self.scheme = scheme
+
+
+class ResponseError(HTTPError):
+    """Used as a container for an error reason supplied in a MaxRetryError."""
+
+    GENERIC_ERROR = "too many error responses"
+    SPECIFIC_ERROR = "too many {status_code} error responses"
+
+
+class SecurityWarning(HTTPWarning):
+    """Warned when performing security reducing actions"""
+
+
+class InsecureRequestWarning(SecurityWarning):
+    """Warned when making an unverified HTTPS request."""
+
+
+class NotOpenSSLWarning(SecurityWarning):
+    """Warned when using unsupported SSL library"""
+
+
+class SystemTimeWarning(SecurityWarning):
+    """Warned when system time is suspected to be wrong"""
+
+
+class InsecurePlatformWarning(SecurityWarning):
+    """Warned when certain TLS/SSL configuration is not available on a platform."""
+
+
+class DependencyWarning(HTTPWarning):
+    """
+    Warned when an attempt is made to import a module with missing optional
+    dependencies.
+    """
+
+
+class ResponseNotChunked(ProtocolError, ValueError):
+    """Response needs to be chunked in order to read it as chunks."""
+
+
+class BodyNotHttplibCompatible(HTTPError):
+    """
+    Body should be :class:`http.client.HTTPResponse` like
+    (have an fp attribute which returns raw chunks) for read_chunked().
+    """
+
+
+class IncompleteRead(HTTPError, httplib_IncompleteRead):
+    """
+    Response length doesn't match expected Content-Length
+
+    Subclass of :class:`http.client.IncompleteRead` to allow int value
+    for ``partial`` to avoid creating large objects on streamed reads.
+    """
+
+    partial: int  # type: ignore[assignment]
+    expected: int
+
+    def __init__(self, partial: int, expected: int) -> None:
+        self.partial = partial
+        self.expected = expected
+
+    def __repr__(self) -> str:
+        return "IncompleteRead(%i bytes read, %i more expected)" % (
+            self.partial,
+            self.expected,
+        )
+
+
+class InvalidChunkLength(HTTPError, httplib_IncompleteRead):
+    """Invalid chunk length in a chunked response."""
+
+    def __init__(self, response: HTTPResponse, length: bytes) -> None:
+        self.partial: int = response.tell()  # type: ignore[assignment]
+        self.expected: int | None = response.length_remaining
+        self.response = response
+        self.length = length
+
+    def __repr__(self) -> str:
+        return "InvalidChunkLength(got length %r, %i bytes read)" % (
+            self.length,
+            self.partial,
+        )
+
+
+class InvalidHeader(HTTPError):
+    """The header provided was somehow invalid."""
+
+
+class ProxySchemeUnknown(AssertionError, URLSchemeUnknown):
+    """ProxyManager does not support the supplied scheme"""
+
+    # TODO(t-8ch): Stop inheriting from AssertionError in v2.0.
+
+    def __init__(self, scheme: str | None) -> None:
+        # 'localhost' is here because our URL parser parses
+        # localhost:8080 -> scheme=localhost, remove if we fix this.
+        if scheme == "localhost":
+            scheme = None
+        if scheme is None:
+            message = "Proxy URL had no scheme, should start with http:// or https://"
+        else:
+            message = f"Proxy URL had unsupported scheme {scheme}, should use http:// or https://"
+        super().__init__(message)
+
+
+class ProxySchemeUnsupported(ValueError):
+    """Fetching HTTPS resources through HTTPS proxies is unsupported"""
+
+
+class HeaderParsingError(HTTPError):
+    """Raised by assert_header_parsing, but we convert it to a log.warning statement."""
+
+    def __init__(
+        self, defects: list[MessageDefect], unparsed_data: bytes | str | None
+    ) -> None:
+        message = f"{defects or 'Unknown'}, unparsed data: {unparsed_data!r}"
+        super().__init__(message)
+
+
+class UnrewindableBodyError(HTTPError):
+    """urllib3 encountered an error when trying to rewind a body"""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py
new file mode 100644
index 00000000000..fe68e177324
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py
@@ -0,0 +1,341 @@
+from __future__ import annotations
+
+import email.utils
+import mimetypes
+import typing
+
+_TYPE_FIELD_VALUE = typing.Union[str, bytes]
+_TYPE_FIELD_VALUE_TUPLE = typing.Union[
+    _TYPE_FIELD_VALUE,
+    tuple[str, _TYPE_FIELD_VALUE],
+    tuple[str, _TYPE_FIELD_VALUE, str],
+]
+
+
+def guess_content_type(
+    filename: str | None, default: str = "application/octet-stream"
+) -> str:
+    """
+    Guess the "Content-Type" of a file.
+
+    :param filename:
+        The filename to guess the "Content-Type" of using :mod:`mimetypes`.
+    :param default:
+        If no "Content-Type" can be guessed, default to `default`.
+    """
+    if filename:
+        return mimetypes.guess_type(filename)[0] or default
+    return default
+
+
+def format_header_param_rfc2231(name: str, value: _TYPE_FIELD_VALUE) -> str:
+    """
+    Helper function to format and quote a single header parameter using the
+    strategy defined in RFC 2231.
+
+    Particularly useful for header parameters which might contain
+    non-ASCII values, like file names. This follows
+    `RFC 2388 Section 4.4 `_.
+
+    :param name:
+        The name of the parameter, a string expected to be ASCII only.
+    :param value:
+        The value of the parameter, provided as ``bytes`` or `str``.
+    :returns:
+        An RFC-2231-formatted unicode string.
+
+    .. deprecated:: 2.0.0
+        Will be removed in urllib3 v3.0. This is not valid for
+        ``multipart/form-data`` header parameters.
+    """
+    import warnings
+
+    warnings.warn(
+        "'format_header_param_rfc2231' is insecure, deprecated and will be "
+        "removed in urllib3 v3.0. This is not valid for "
+        "multipart/form-data header parameters.",
+        FutureWarning,
+        stacklevel=2,
+    )
+
+    if isinstance(value, bytes):
+        value = value.decode("utf-8")
+
+    if not any(ch in value for ch in '"\\\r\n'):
+        result = f'{name}="{value}"'
+        try:
+            result.encode("ascii")
+        except (UnicodeEncodeError, UnicodeDecodeError):
+            pass
+        else:
+            return result
+
+    value = email.utils.encode_rfc2231(value, "utf-8")
+    value = f"{name}*={value}"
+
+    return value
+
+
+def format_multipart_header_param(name: str, value: _TYPE_FIELD_VALUE) -> str:
+    """
+    Format and quote a single multipart header parameter.
+
+    This follows the `WHATWG HTML Standard`_ as of 2021/06/10, matching
+    the behavior of current browser and curl versions. Values are
+    assumed to be UTF-8. The ``\\n``, ``\\r``, and ``"`` characters are
+    percent encoded.
+
+    .. _WHATWG HTML Standard:
+        https://html.spec.whatwg.org/multipage/
+        form-control-infrastructure.html#multipart-form-data
+
+    :param name:
+        The name of the parameter, an ASCII-only ``str``.
+    :param value:
+        The value of the parameter, a ``str`` or UTF-8 encoded
+        ``bytes``.
+    :returns:
+        A string ``name="value"`` with the escaped value.
+
+    .. versionchanged:: 2.0.0
+        Matches the WHATWG HTML Standard as of 2021/06/10. Control
+        characters are no longer percent encoded.
+
+    .. versionchanged:: 2.0.0
+        Renamed from ``format_header_param_html5`` and
+        ``format_header_param``. The old names will be removed in
+        urllib3 v3.0.
+    """
+    if isinstance(value, bytes):
+        value = value.decode("utf-8")
+
+    # percent encode \n \r "
+    value = value.translate({10: "%0A", 13: "%0D", 34: "%22"})
+    return f'{name}="{value}"'
+
+
+def format_header_param_html5(name: str, value: _TYPE_FIELD_VALUE) -> str:
+    """
+    .. deprecated:: 2.0.0
+        Renamed to :func:`format_multipart_header_param`. Will be
+        removed in urllib3 v3.0.
+    """
+    import warnings
+
+    warnings.warn(
+        "'format_header_param_html5' has been renamed to "
+        "'format_multipart_header_param'. The old name will be "
+        "removed in urllib3 v3.0.",
+        FutureWarning,
+        stacklevel=2,
+    )
+    return format_multipart_header_param(name, value)
+
+
+def format_header_param(name: str, value: _TYPE_FIELD_VALUE) -> str:
+    """
+    .. deprecated:: 2.0.0
+        Renamed to :func:`format_multipart_header_param`. Will be
+        removed in urllib3 v3.0.
+    """
+    import warnings
+
+    warnings.warn(
+        "'format_header_param' has been renamed to "
+        "'format_multipart_header_param'. The old name will be "
+        "removed in urllib3 v3.0.",
+        FutureWarning,
+        stacklevel=2,
+    )
+    return format_multipart_header_param(name, value)
+
+
+class RequestField:
+    """
+    A data container for request body parameters.
+
+    :param name:
+        The name of this request field. Must be unicode.
+    :param data:
+        The data/value body.
+    :param filename:
+        An optional filename of the request field. Must be unicode.
+    :param headers:
+        An optional dict-like object of headers to initially use for the field.
+
+    .. versionchanged:: 2.0.0
+        The ``header_formatter`` parameter is deprecated and will
+        be removed in urllib3 v3.0.
+    """
+
+    def __init__(
+        self,
+        name: str,
+        data: _TYPE_FIELD_VALUE,
+        filename: str | None = None,
+        headers: typing.Mapping[str, str] | None = None,
+        header_formatter: typing.Callable[[str, _TYPE_FIELD_VALUE], str] | None = None,
+    ):
+        self._name = name
+        self._filename = filename
+        self.data = data
+        self.headers: dict[str, str | None] = {}
+        if headers:
+            self.headers = dict(headers)
+
+        if header_formatter is not None:
+            import warnings
+
+            warnings.warn(
+                "The 'header_formatter' parameter is deprecated and "
+                "will be removed in urllib3 v3.0.",
+                FutureWarning,
+                stacklevel=2,
+            )
+            self.header_formatter = header_formatter
+        else:
+            self.header_formatter = format_multipart_header_param
+
+    @classmethod
+    def from_tuples(
+        cls,
+        fieldname: str,
+        value: _TYPE_FIELD_VALUE_TUPLE,
+        header_formatter: typing.Callable[[str, _TYPE_FIELD_VALUE], str] | None = None,
+    ) -> RequestField:
+        """
+        A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters.
+
+        Supports constructing :class:`~urllib3.fields.RequestField` from
+        parameter of key/value strings AND key/filetuple. A filetuple is a
+        (filename, data, MIME type) tuple where the MIME type is optional.
+        For example::
+
+            'foo': 'bar',
+            'fakefile': ('foofile.txt', 'contents of foofile'),
+            'realfile': ('barfile.txt', open('realfile').read()),
+            'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'),
+            'nonamefile': 'contents of nonamefile field',
+
+        Field names and filenames must be unicode.
+        """
+        filename: str | None
+        content_type: str | None
+        data: _TYPE_FIELD_VALUE
+
+        if isinstance(value, tuple):
+            if len(value) == 3:
+                filename, data, content_type = value
+            else:
+                filename, data = value
+                content_type = guess_content_type(filename)
+        else:
+            filename = None
+            content_type = None
+            data = value
+
+        request_param = cls(
+            fieldname, data, filename=filename, header_formatter=header_formatter
+        )
+        request_param.make_multipart(content_type=content_type)
+
+        return request_param
+
+    def _render_part(self, name: str, value: _TYPE_FIELD_VALUE) -> str:
+        """
+        Override this method to change how each multipart header
+        parameter is formatted. By default, this calls
+        :func:`format_multipart_header_param`.
+
+        :param name:
+            The name of the parameter, an ASCII-only ``str``.
+        :param value:
+            The value of the parameter, a ``str`` or UTF-8 encoded
+            ``bytes``.
+
+        :meta public:
+        """
+        return self.header_formatter(name, value)
+
+    def _render_parts(
+        self,
+        header_parts: (
+            dict[str, _TYPE_FIELD_VALUE | None]
+            | typing.Sequence[tuple[str, _TYPE_FIELD_VALUE | None]]
+        ),
+    ) -> str:
+        """
+        Helper function to format and quote a single header.
+
+        Useful for single headers that are composed of multiple items. E.g.,
+        'Content-Disposition' fields.
+
+        :param header_parts:
+            A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format
+            as `k1="v1"; k2="v2"; ...`.
+        """
+        iterable: typing.Iterable[tuple[str, _TYPE_FIELD_VALUE | None]]
+
+        parts = []
+        if isinstance(header_parts, dict):
+            iterable = header_parts.items()
+        else:
+            iterable = header_parts
+
+        for name, value in iterable:
+            if value is not None:
+                parts.append(self._render_part(name, value))
+
+        return "; ".join(parts)
+
+    def render_headers(self) -> str:
+        """
+        Renders the headers for this request field.
+        """
+        lines = []
+
+        sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"]
+        for sort_key in sort_keys:
+            if self.headers.get(sort_key, False):
+                lines.append(f"{sort_key}: {self.headers[sort_key]}")
+
+        for header_name, header_value in self.headers.items():
+            if header_name not in sort_keys:
+                if header_value:
+                    lines.append(f"{header_name}: {header_value}")
+
+        lines.append("\r\n")
+        return "\r\n".join(lines)
+
+    def make_multipart(
+        self,
+        content_disposition: str | None = None,
+        content_type: str | None = None,
+        content_location: str | None = None,
+    ) -> None:
+        """
+        Makes this request field into a multipart request field.
+
+        This method overrides "Content-Disposition", "Content-Type" and
+        "Content-Location" headers to the request parameter.
+
+        :param content_disposition:
+            The 'Content-Disposition' of the request body. Defaults to 'form-data'
+        :param content_type:
+            The 'Content-Type' of the request body.
+        :param content_location:
+            The 'Content-Location' of the request body.
+
+        """
+        content_disposition = (content_disposition or "form-data") + "; ".join(
+            [
+                "",
+                self._render_parts(
+                    (("name", self._name), ("filename", self._filename))
+                ),
+            ]
+        )
+
+        self.headers["Content-Disposition"] = content_disposition
+        self.headers["Content-Type"] = content_type
+        self.headers["Content-Location"] = content_location
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py
new file mode 100644
index 00000000000..14f70b05b47
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py
@@ -0,0 +1,89 @@
+from __future__ import annotations
+
+import binascii
+import codecs
+import os
+import typing
+from io import BytesIO
+
+from .fields import _TYPE_FIELD_VALUE_TUPLE, RequestField
+
+writer = codecs.lookup("utf-8")[3]
+
+_TYPE_FIELDS_SEQUENCE = typing.Sequence[
+    typing.Union[tuple[str, _TYPE_FIELD_VALUE_TUPLE], RequestField]
+]
+_TYPE_FIELDS = typing.Union[
+    _TYPE_FIELDS_SEQUENCE,
+    typing.Mapping[str, _TYPE_FIELD_VALUE_TUPLE],
+]
+
+
+def choose_boundary() -> str:
+    """
+    Our embarrassingly-simple replacement for mimetools.choose_boundary.
+    """
+    return binascii.hexlify(os.urandom(16)).decode()
+
+
+def iter_field_objects(fields: _TYPE_FIELDS) -> typing.Iterable[RequestField]:
+    """
+    Iterate over fields.
+
+    Supports list of (k, v) tuples and dicts, and lists of
+    :class:`~urllib3.fields.RequestField`.
+
+    """
+    iterable: typing.Iterable[RequestField | tuple[str, _TYPE_FIELD_VALUE_TUPLE]]
+
+    if isinstance(fields, typing.Mapping):
+        iterable = fields.items()
+    else:
+        iterable = fields
+
+    for field in iterable:
+        if isinstance(field, RequestField):
+            yield field
+        else:
+            yield RequestField.from_tuples(*field)
+
+
+def encode_multipart_formdata(
+    fields: _TYPE_FIELDS, boundary: str | None = None
+) -> tuple[bytes, str]:
+    """
+    Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
+
+    :param fields:
+        Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
+        Values are processed by :func:`urllib3.fields.RequestField.from_tuples`.
+
+    :param boundary:
+        If not specified, then a random boundary will be generated using
+        :func:`urllib3.filepost.choose_boundary`.
+    """
+    body = BytesIO()
+    if boundary is None:
+        boundary = choose_boundary()
+
+    for field in iter_field_objects(fields):
+        body.write(f"--{boundary}\r\n".encode("latin-1"))
+
+        writer(body).write(field.render_headers())
+        data = field.data
+
+        if isinstance(data, int):
+            data = str(data)  # Backwards compatibility
+
+        if isinstance(data, str):
+            writer(body).write(data)
+        else:
+            body.write(data)
+
+        body.write(b"\r\n")
+
+    body.write(f"--{boundary}--\r\n".encode("latin-1"))
+
+    content_type = f"multipart/form-data; boundary={boundary}"
+
+    return body.getvalue(), content_type
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py
new file mode 100644
index 00000000000..133e1d8f237
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py
@@ -0,0 +1,53 @@
+from __future__ import annotations
+
+from importlib.metadata import version
+
+__all__ = [
+    "inject_into_urllib3",
+    "extract_from_urllib3",
+]
+
+import typing
+
+orig_HTTPSConnection: typing.Any = None
+
+
+def inject_into_urllib3() -> None:
+    # First check if h2 version is valid
+    h2_version = version("h2")
+    if not h2_version.startswith("4."):
+        raise ImportError(
+            "urllib3 v2 supports h2 version 4.x.x, currently "
+            f"the 'h2' module is compiled with {h2_version!r}. "
+            "See: https://github.com/urllib3/urllib3/issues/3290"
+        )
+
+    # Import here to avoid circular dependencies.
+    from .. import connection as urllib3_connection
+    from .. import util as urllib3_util
+    from ..connectionpool import HTTPSConnectionPool
+    from ..util import ssl_ as urllib3_util_ssl
+    from .connection import HTTP2Connection
+
+    global orig_HTTPSConnection
+    orig_HTTPSConnection = urllib3_connection.HTTPSConnection
+
+    HTTPSConnectionPool.ConnectionCls = HTTP2Connection
+    urllib3_connection.HTTPSConnection = HTTP2Connection  # type: ignore[misc]
+
+    # TODO: Offer 'http/1.1' as well, but for testing purposes this is handy.
+    urllib3_util.ALPN_PROTOCOLS = ["h2"]
+    urllib3_util_ssl.ALPN_PROTOCOLS = ["h2"]
+
+
+def extract_from_urllib3() -> None:
+    from .. import connection as urllib3_connection
+    from .. import util as urllib3_util
+    from ..connectionpool import HTTPSConnectionPool
+    from ..util import ssl_ as urllib3_util_ssl
+
+    HTTPSConnectionPool.ConnectionCls = orig_HTTPSConnection
+    urllib3_connection.HTTPSConnection = orig_HTTPSConnection  # type: ignore[misc]
+
+    urllib3_util.ALPN_PROTOCOLS = ["http/1.1"]
+    urllib3_util_ssl.ALPN_PROTOCOLS = ["http/1.1"]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py
new file mode 100644
index 00000000000..9ea900764f0
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py
@@ -0,0 +1,87 @@
+from __future__ import annotations
+
+import threading
+
+
+class _HTTP2ProbeCache:
+    __slots__ = (
+        "_lock",
+        "_cache_locks",
+        "_cache_values",
+    )
+
+    def __init__(self) -> None:
+        self._lock = threading.Lock()
+        self._cache_locks: dict[tuple[str, int], threading.RLock] = {}
+        self._cache_values: dict[tuple[str, int], bool | None] = {}
+
+    def acquire_and_get(self, host: str, port: int) -> bool | None:
+        # By the end of this block we know that
+        # _cache_[values,locks] is available.
+        value = None
+        with self._lock:
+            key = (host, port)
+            try:
+                value = self._cache_values[key]
+                # If it's a known value we return right away.
+                if value is not None:
+                    return value
+            except KeyError:
+                self._cache_locks[key] = threading.RLock()
+                self._cache_values[key] = None
+
+        # If the value is unknown, we acquire the lock to signal
+        # to the requesting thread that the probe is in progress
+        # or that the current thread needs to return their findings.
+        key_lock = self._cache_locks[key]
+        key_lock.acquire()
+        try:
+            # If the by the time we get the lock the value has been
+            # updated we want to return the updated value.
+            value = self._cache_values[key]
+
+        # In case an exception like KeyboardInterrupt is raised here.
+        except BaseException as e:  # Defensive:
+            assert not isinstance(e, KeyError)  # KeyError shouldn't be possible.
+            key_lock.release()
+            raise
+
+        return value
+
+    def set_and_release(
+        self, host: str, port: int, supports_http2: bool | None
+    ) -> None:
+        key = (host, port)
+        key_lock = self._cache_locks[key]
+        with key_lock:  # Uses an RLock, so can be locked again from same thread.
+            if supports_http2 is None and self._cache_values[key] is not None:
+                raise ValueError(
+                    "Cannot reset HTTP/2 support for origin after value has been set."
+                )  # Defensive: not expected in normal usage
+
+        self._cache_values[key] = supports_http2
+        key_lock.release()
+
+    def _values(self) -> dict[tuple[str, int], bool | None]:
+        """This function is for testing purposes only. Gets the current state of the probe cache"""
+        with self._lock:
+            return {k: v for k, v in self._cache_values.items()}
+
+    def _reset(self) -> None:
+        """This function is for testing purposes only. Reset the cache values"""
+        with self._lock:
+            self._cache_locks = {}
+            self._cache_values = {}
+
+
+_HTTP2_PROBE_CACHE = _HTTP2ProbeCache()
+
+set_and_release = _HTTP2_PROBE_CACHE.set_and_release
+acquire_and_get = _HTTP2_PROBE_CACHE.acquire_and_get
+_values = _HTTP2_PROBE_CACHE._values
+_reset = _HTTP2_PROBE_CACHE._reset
+
+__all__ = [
+    "set_and_release",
+    "acquire_and_get",
+]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py
new file mode 100644
index 00000000000..83157e8d66a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py
@@ -0,0 +1,677 @@
+from __future__ import annotations
+
+import functools
+import logging
+import typing
+import warnings
+from types import TracebackType
+from urllib.parse import urljoin
+
+from ._collections import HTTPHeaderDict, RecentlyUsedContainer
+from ._request_methods import RequestMethods
+from .connection import ProxyConfig
+from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
+from .exceptions import (
+    LocationValueError,
+    MaxRetryError,
+    ProxySchemeUnknown,
+    URLSchemeUnknown,
+)
+from .response import BaseHTTPResponse
+from .util.connection import _TYPE_SOCKET_OPTIONS
+from .util.proxy import connection_requires_http_tunnel
+from .util.retry import Retry
+from .util.timeout import Timeout
+from .util.url import Url, parse_url
+
+if typing.TYPE_CHECKING:
+    import ssl
+
+    from opentelemetry.agent._vendor.typing_extensions import Self
+
+__all__ = ["PoolManager", "ProxyManager", "proxy_from_url"]
+
+
+log = logging.getLogger(__name__)
+
+SSL_KEYWORDS = (
+    "key_file",
+    "cert_file",
+    "cert_reqs",
+    "ca_certs",
+    "ca_cert_data",
+    "ssl_version",
+    "ssl_minimum_version",
+    "ssl_maximum_version",
+    "ca_cert_dir",
+    "ssl_context",
+    "key_password",
+    "server_hostname",
+    "assert_hostname",
+    "assert_fingerprint",
+)
+# Default value for `blocksize` - a new parameter introduced to
+# http.client.HTTPConnection & http.client.HTTPSConnection in Python 3.7
+_DEFAULT_BLOCKSIZE = 16384
+
+
+class PoolKey(typing.NamedTuple):
+    """
+    All known keyword arguments that could be provided to the pool manager, its
+    pools, or the underlying connections.
+
+    All custom key schemes should include the fields in this key at a minimum.
+    """
+
+    key_scheme: str
+    key_host: str
+    key_port: int | None
+    key_timeout: Timeout | float | int | None
+    key_retries: Retry | bool | int | None
+    key_block: bool | None
+    key_source_address: tuple[str, int] | None
+    key_key_file: str | None
+    key_key_password: str | None
+    key_cert_file: str | None
+    key_cert_reqs: str | None
+    key_ca_certs: str | None
+    key_ca_cert_data: str | bytes | None
+    key_ssl_version: int | str | None
+    key_ssl_minimum_version: ssl.TLSVersion | None
+    key_ssl_maximum_version: ssl.TLSVersion | None
+    key_ca_cert_dir: str | None
+    key_ssl_context: ssl.SSLContext | None
+    key_maxsize: int | None
+    key_headers: frozenset[tuple[str, str]] | None
+    key__proxy: Url | None
+    key__proxy_headers: frozenset[tuple[str, str]] | None
+    key__proxy_config: ProxyConfig | None
+    key_socket_options: _TYPE_SOCKET_OPTIONS | None
+    key__socks_options: frozenset[tuple[str, str]] | None
+    key_assert_hostname: bool | str | None
+    key_assert_fingerprint: str | None
+    key_server_hostname: str | None
+    key_blocksize: int | None
+
+
+def _default_key_normalizer(
+    key_class: type[PoolKey], request_context: dict[str, typing.Any]
+) -> PoolKey:
+    """
+    Create a pool key out of a request context dictionary.
+
+    According to RFC 3986, both the scheme and host are case-insensitive.
+    Therefore, this function normalizes both before constructing the pool
+    key for an HTTPS request. If you wish to change this behaviour, provide
+    alternate callables to ``key_fn_by_scheme``.
+
+    :param key_class:
+        The class to use when constructing the key. This should be a namedtuple
+        with the ``scheme`` and ``host`` keys at a minimum.
+    :type  key_class: namedtuple
+    :param request_context:
+        A dictionary-like object that contain the context for a request.
+    :type  request_context: dict
+
+    :return: A namedtuple that can be used as a connection pool key.
+    :rtype:  PoolKey
+    """
+    # Since we mutate the dictionary, make a copy first
+    context = request_context.copy()
+    context["scheme"] = context["scheme"].lower()
+    context["host"] = context["host"].lower()
+
+    # These are both dictionaries and need to be transformed into frozensets
+    for key in ("headers", "_proxy_headers", "_socks_options"):
+        if key in context and context[key] is not None:
+            context[key] = frozenset(context[key].items())
+
+    # The socket_options key may be a list and needs to be transformed into a
+    # tuple.
+    socket_opts = context.get("socket_options")
+    if socket_opts is not None:
+        context["socket_options"] = tuple(socket_opts)
+
+    # Map the kwargs to the names in the namedtuple - this is necessary since
+    # namedtuples can't have fields starting with '_'.
+    for key in list(context.keys()):
+        context["key_" + key] = context.pop(key)
+
+    # Default to ``None`` for keys missing from the context
+    for field in key_class._fields:
+        if field not in context:
+            context[field] = None
+
+    # Default key_blocksize to _DEFAULT_BLOCKSIZE if missing from the context
+    if context.get("key_blocksize") is None:
+        context["key_blocksize"] = _DEFAULT_BLOCKSIZE
+
+    return key_class(**context)
+
+
+#: A dictionary that maps a scheme to a callable that creates a pool key.
+#: This can be used to alter the way pool keys are constructed, if desired.
+#: Each PoolManager makes a copy of this dictionary so they can be configured
+#: globally here, or individually on the instance.
+key_fn_by_scheme = {
+    "http": functools.partial(_default_key_normalizer, PoolKey),
+    "https": functools.partial(_default_key_normalizer, PoolKey),
+}
+
+pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool}
+
+
+class PoolManager(RequestMethods):
+    """
+    Allows for arbitrary requests while transparently keeping track of
+    necessary connection pools for you.
+
+    :param num_pools:
+        Number of connection pools to cache before discarding the least
+        recently used pool.
+
+    :param headers:
+        Headers to include with all requests, unless other headers are given
+        explicitly.
+
+    :param \\**connection_pool_kw:
+        Additional parameters are used to create fresh
+        :class:`urllib3.connectionpool.ConnectionPool` instances.
+
+    Example:
+
+    .. code-block:: python
+
+        import urllib3
+
+        http = urllib3.PoolManager(num_pools=2)
+
+        resp1 = http.request("GET", "https://google.com/")
+        resp2 = http.request("GET", "https://google.com/mail")
+        resp3 = http.request("GET", "https://yahoo.com/")
+
+        print(len(http.pools))
+        # 2
+
+    """
+
+    proxy: Url | None = None
+    proxy_config: ProxyConfig | None = None
+
+    def __init__(
+        self,
+        num_pools: int = 10,
+        headers: typing.Mapping[str, str] | None = None,
+        **connection_pool_kw: typing.Any,
+    ) -> None:
+        super().__init__(headers)
+        # PoolManager handles redirects itself in PoolManager.urlopen().
+        # It always passes redirect=False to the underlying connection pool to
+        # suppress per-pool redirect handling. If the user supplied a non-Retry
+        # value (int/bool/etc) for retries and we let the pool normalize it
+        # while redirect=False, the resulting Retry object would have redirect
+        # handling disabled, which can interfere with PoolManager's own
+        # redirect logic. Normalize here so redirects remain governed solely by
+        # PoolManager logic.
+        if "retries" in connection_pool_kw:
+            retries = connection_pool_kw["retries"]
+            if not isinstance(retries, Retry):
+                retries = Retry.from_int(retries)
+                connection_pool_kw = connection_pool_kw.copy()
+                connection_pool_kw["retries"] = retries
+        self.connection_pool_kw = connection_pool_kw
+
+        self.pools: RecentlyUsedContainer[PoolKey, HTTPConnectionPool]
+        self.pools = RecentlyUsedContainer(num_pools)
+
+        # Locally set the pool classes and keys so other PoolManagers can
+        # override them.
+        self.pool_classes_by_scheme = pool_classes_by_scheme
+        self.key_fn_by_scheme = key_fn_by_scheme.copy()
+
+    def __enter__(self) -> Self:
+        return self
+
+    def __exit__(
+        self,
+        exc_type: type[BaseException] | None,
+        exc_val: BaseException | None,
+        exc_tb: TracebackType | None,
+    ) -> typing.Literal[False]:
+        self.clear()
+        # Return False to re-raise any potential exceptions
+        return False
+
+    def _new_pool(
+        self,
+        scheme: str,
+        host: str,
+        port: int,
+        request_context: dict[str, typing.Any] | None = None,
+    ) -> HTTPConnectionPool:
+        """
+        Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and
+        any additional pool keyword arguments.
+
+        If ``request_context`` is provided, it is provided as keyword arguments
+        to the pool class used. This method is used to actually create the
+        connection pools handed out by :meth:`connection_from_url` and
+        companion methods. It is intended to be overridden for customization.
+        """
+        pool_cls: type[HTTPConnectionPool] = self.pool_classes_by_scheme[scheme]
+        if request_context is None:
+            request_context = self.connection_pool_kw.copy()
+
+        # Default blocksize to _DEFAULT_BLOCKSIZE if missing or explicitly
+        # set to 'None' in the request_context.
+        if request_context.get("blocksize") is None:
+            request_context["blocksize"] = _DEFAULT_BLOCKSIZE
+
+        # Although the context has everything necessary to create the pool,
+        # this function has historically only used the scheme, host, and port
+        # in the positional args. When an API change is acceptable these can
+        # be removed.
+        for key in ("scheme", "host", "port"):
+            request_context.pop(key, None)
+
+        if scheme == "http":
+            for kw in SSL_KEYWORDS:
+                request_context.pop(kw, None)
+
+        return pool_cls(host, port, **request_context)
+
+    def clear(self) -> None:
+        """
+        Empty our store of pools and direct them all to close.
+
+        This will not affect in-flight connections, but they will not be
+        re-used after completion.
+        """
+        self.pools.clear()
+
+    def connection_from_host(
+        self,
+        host: str | None,
+        port: int | None = None,
+        scheme: str | None = "http",
+        pool_kwargs: dict[str, typing.Any] | None = None,
+    ) -> HTTPConnectionPool:
+        """
+        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
+
+        If ``port`` isn't given, it will be derived from the ``scheme`` using
+        ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
+        provided, it is merged with the instance's ``connection_pool_kw``
+        variable and used to create the new connection pool, if one is
+        needed.
+        """
+
+        if not host:
+            raise LocationValueError("No host specified.")
+
+        request_context = self._merge_pool_kwargs(pool_kwargs)
+        request_context["scheme"] = scheme or "http"
+        if port is None:
+            port = port_by_scheme.get(request_context["scheme"].lower(), 80)
+        request_context["port"] = port
+        request_context["host"] = host
+
+        return self.connection_from_context(request_context)
+
+    def connection_from_context(
+        self, request_context: dict[str, typing.Any]
+    ) -> HTTPConnectionPool:
+        """
+        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context.
+
+        ``request_context`` must at least contain the ``scheme`` key and its
+        value must be a key in ``key_fn_by_scheme`` instance variable.
+        """
+        if "strict" in request_context:
+            warnings.warn(
+                "The 'strict' parameter is no longer needed on Python 3+. "
+                "This will raise an error in urllib3 v3.0.",
+                FutureWarning,
+            )
+            request_context.pop("strict")
+
+        scheme = request_context["scheme"].lower()
+        pool_key_constructor = self.key_fn_by_scheme.get(scheme)
+        if not pool_key_constructor:
+            raise URLSchemeUnknown(scheme)
+        pool_key = pool_key_constructor(request_context)
+
+        return self.connection_from_pool_key(pool_key, request_context=request_context)
+
+    def connection_from_pool_key(
+        self, pool_key: PoolKey, request_context: dict[str, typing.Any]
+    ) -> HTTPConnectionPool:
+        """
+        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key.
+
+        ``pool_key`` should be a namedtuple that only contains immutable
+        objects. At a minimum it must have the ``scheme``, ``host``, and
+        ``port`` fields.
+        """
+        with self.pools.lock:
+            # If the scheme, host, or port doesn't match existing open
+            # connections, open a new ConnectionPool.
+            pool = self.pools.get(pool_key)
+            if pool:
+                return pool
+
+            # Make a fresh ConnectionPool of the desired type
+            scheme = request_context["scheme"]
+            host = request_context["host"]
+            port = request_context["port"]
+            pool = self._new_pool(scheme, host, port, request_context=request_context)
+            self.pools[pool_key] = pool
+
+        return pool
+
+    def connection_from_url(
+        self, url: str, pool_kwargs: dict[str, typing.Any] | None = None
+    ) -> HTTPConnectionPool:
+        """
+        Similar to :func:`urllib3.connectionpool.connection_from_url`.
+
+        If ``pool_kwargs`` is not provided and a new pool needs to be
+        constructed, ``self.connection_pool_kw`` is used to initialize
+        the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
+        is provided, it is used instead. Note that if a new pool does not
+        need to be created for the request, the provided ``pool_kwargs`` are
+        not used.
+        """
+        u = parse_url(url)
+        return self.connection_from_host(
+            u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs
+        )
+
+    def _merge_pool_kwargs(
+        self, override: dict[str, typing.Any] | None
+    ) -> dict[str, typing.Any]:
+        """
+        Merge a dictionary of override values for self.connection_pool_kw.
+
+        This does not modify self.connection_pool_kw and returns a new dict.
+        Any keys in the override dictionary with a value of ``None`` are
+        removed from the merged dictionary.
+        """
+        base_pool_kwargs = self.connection_pool_kw.copy()
+        if override:
+            for key, value in override.items():
+                if value is None:
+                    try:
+                        del base_pool_kwargs[key]
+                    except KeyError:
+                        pass
+                else:
+                    base_pool_kwargs[key] = value
+        return base_pool_kwargs
+
+    def _proxy_requires_url_absolute_form(self, parsed_url: Url) -> bool:
+        """
+        Indicates if the proxy requires the complete destination URL in the
+        request.  Normally this is only needed when not using an HTTP CONNECT
+        tunnel.
+        """
+        if self.proxy is None:
+            return False
+
+        return not connection_requires_http_tunnel(
+            self.proxy, self.proxy_config, parsed_url.scheme
+        )
+
+    def urlopen(  # type: ignore[override]
+        self, method: str, url: str, redirect: bool = True, **kw: typing.Any
+    ) -> BaseHTTPResponse:
+        """
+        Same as :meth:`urllib3.HTTPConnectionPool.urlopen`
+        with custom cross-host redirect logic and only sends the request-uri
+        portion of the ``url``.
+
+        The given ``url`` parameter must be absolute, such that an appropriate
+        :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
+        """
+        u = parse_url(url)
+
+        if u.scheme is None:
+            warnings.warn(
+                "URLs without a scheme (ie 'https://') are deprecated and will raise an error "
+                "in urllib3 v3.0. To avoid this FutureWarning ensure all URLs "
+                "start with 'https://' or 'http://'. Read more in this issue: "
+                "https://github.com/urllib3/urllib3/issues/2920",
+                category=FutureWarning,
+                stacklevel=2,
+            )
+
+        conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
+
+        kw["assert_same_host"] = False
+        kw["redirect"] = False
+
+        if "headers" not in kw:
+            kw["headers"] = self.headers
+
+        if self._proxy_requires_url_absolute_form(u):
+            response = conn.urlopen(method, u._replace(fragment=None).url, **kw)
+        else:
+            response = conn.urlopen(method, u.request_uri, **kw)
+
+        redirect_location = redirect and response.get_redirect_location()
+        if not redirect_location:
+            return response
+
+        # Support relative URLs for redirecting.
+        redirect_location = urljoin(url, redirect_location)
+
+        if response.status == 303:
+            # Change the method according to RFC 9110, Section 15.4.4.
+            method = "GET"
+            # And lose the body not to transfer anything sensitive.
+            kw["body"] = None
+            # The body is gone, so the state that describes it has to go too:
+            # there is nothing left to frame with chunked transfer encoding,
+            # and nothing left to rewind.
+            kw["chunked"] = False
+            kw["body_pos"] = None
+            kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()
+
+        retries = kw.get("retries", response.retries)
+        if not isinstance(retries, Retry):
+            retries = Retry.from_int(retries, redirect=redirect)
+
+        # Strip headers marked as unsafe to forward to the redirected location.
+        # Check remove_headers_on_redirect to avoid a potential network call within
+        # conn.is_same_host() which may use socket.gethostbyname() in the future.
+        if retries.remove_headers_on_redirect and not conn.is_same_host(
+            redirect_location
+        ):
+            new_headers = kw["headers"].copy()
+            for header in kw["headers"]:
+                if header.lower() in retries.remove_headers_on_redirect:
+                    new_headers.pop(header, None)
+            kw["headers"] = new_headers
+
+        try:
+            retries = retries.increment(method, url, response=response, _pool=conn)
+        except MaxRetryError:
+            if retries.raise_on_redirect:
+                response.drain_conn()
+                raise
+            return response
+
+        kw["retries"] = retries
+        kw["redirect"] = redirect
+
+        log.info("Redirecting %s -> %s", url, redirect_location)
+
+        response.drain_conn()
+        return self.urlopen(method, redirect_location, **kw)
+
+
+class ProxyManager(PoolManager):
+    """
+    Behaves just like :class:`PoolManager`, but sends all requests through
+    the defined proxy, using the CONNECT method for HTTPS URLs.
+
+    :param proxy_url:
+        The URL of the proxy to be used.
+
+    :param proxy_headers:
+        A dictionary containing headers that will be sent to the proxy. In case
+        of HTTP they are being sent with each request, while in the
+        HTTPS/CONNECT case they are sent only once. Could be used for proxy
+        authentication.
+
+    :param proxy_ssl_context:
+        The proxy SSL context is used to establish the TLS connection to the
+        proxy when using HTTPS proxies.
+
+    :param use_forwarding_for_https:
+        (Defaults to False) If set to True will forward requests to the HTTPS
+        proxy to be made on behalf of the client instead of creating a TLS
+        tunnel via the CONNECT method. **Enabling this flag means that request
+        and response headers and content will be visible from the HTTPS proxy**
+        whereas tunneling keeps request and response headers and content
+        private.  IP address, target hostname, SNI, and port are always visible
+        to an HTTPS proxy even when this flag is disabled.
+
+    :param proxy_assert_hostname:
+        The hostname of the certificate to verify against.
+
+    :param proxy_assert_fingerprint:
+        The fingerprint of the certificate to verify against.
+
+    Example:
+
+    .. code-block:: python
+
+        import urllib3
+
+        proxy = urllib3.ProxyManager("https://localhost:3128/")
+
+        resp1 = proxy.request("GET", "http://google.com/")
+        resp2 = proxy.request("GET", "http://httpbin.org/")
+
+        # One pool was shared by both plain HTTP requests.
+        print(len(proxy.pools))
+        # 1
+
+        resp3 = proxy.request("GET", "https://httpbin.org/")
+        resp4 = proxy.request("GET", "https://twitter.com/")
+
+        # A separate pool was added for each HTTPS target.
+        print(len(proxy.pools))
+        # 3
+
+    """
+
+    def __init__(
+        self,
+        proxy_url: str,
+        num_pools: int = 10,
+        headers: typing.Mapping[str, str] | None = None,
+        proxy_headers: typing.Mapping[str, str] | None = None,
+        proxy_ssl_context: ssl.SSLContext | None = None,
+        use_forwarding_for_https: bool = False,
+        proxy_assert_hostname: None | str | typing.Literal[False] = None,
+        proxy_assert_fingerprint: str | None = None,
+        **connection_pool_kw: typing.Any,
+    ) -> None:
+        if isinstance(proxy_url, HTTPConnectionPool):
+            str_proxy_url = f"{proxy_url.scheme}://{proxy_url.host}:{proxy_url.port}"
+        else:
+            str_proxy_url = proxy_url
+        proxy = parse_url(str_proxy_url)
+
+        if proxy.scheme not in ("http", "https"):
+            raise ProxySchemeUnknown(proxy.scheme)
+
+        # Keep the deprecated ssl_context fallback on the manager for
+        # compatibility, while passing only explicit proxy policy to connections.
+        self.proxy_ssl_context = proxy_ssl_context
+        if (
+            use_forwarding_for_https
+            and proxy.scheme == "https"
+            and connection_pool_kw.get("ssl_context") is not None
+        ):
+            warnings.warn(
+                "Passing ssl_context when use_forwarding_for_https=True is deprecated "
+                "and will raise an error in urllib3 v3.0. "
+                "Use proxy_ssl_context to configure the TLS connection to the proxy.",
+                FutureWarning,
+                stacklevel=2,
+            )
+            if self.proxy_ssl_context is None:
+                self.proxy_ssl_context = connection_pool_kw.get("ssl_context")
+
+        if proxy.port is None:
+            port = port_by_scheme.get(proxy.scheme, 80)
+            proxy = proxy._replace(port=port)
+
+        self.proxy = proxy
+        self.proxy_headers = proxy_headers or {}
+        self.proxy_config = ProxyConfig(
+            proxy_ssl_context,
+            use_forwarding_for_https,
+            proxy_assert_hostname,
+            proxy_assert_fingerprint,
+        )
+
+        connection_pool_kw["_proxy"] = self.proxy
+        connection_pool_kw["_proxy_headers"] = self.proxy_headers
+        connection_pool_kw["_proxy_config"] = self.proxy_config
+
+        super().__init__(num_pools, headers, **connection_pool_kw)
+
+    def connection_from_host(
+        self,
+        host: str | None,
+        port: int | None = None,
+        scheme: str | None = "http",
+        pool_kwargs: dict[str, typing.Any] | None = None,
+    ) -> HTTPConnectionPool:
+        if scheme == "https":
+            return super().connection_from_host(
+                host, port, scheme, pool_kwargs=pool_kwargs
+            )
+
+        return super().connection_from_host(
+            self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs  # type: ignore[union-attr]
+        )
+
+    def _set_proxy_headers(
+        self, url: str, headers: typing.Mapping[str, str] | None = None
+    ) -> typing.Mapping[str, str]:
+        """
+        Sets headers needed by proxies: specifically, the Accept and Host
+        headers. Only sets headers not provided by the user.
+        """
+        headers_ = {"Accept": "*/*"}
+
+        netloc = parse_url(url).netloc
+        if netloc:
+            headers_["Host"] = netloc
+
+        if headers:
+            headers_.update(headers)
+        return headers_
+
+    def urlopen(  # type: ignore[override]
+        self, method: str, url: str, redirect: bool = True, **kw: typing.Any
+    ) -> BaseHTTPResponse:
+        "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
+        u = parse_url(url)
+        if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme):
+            # For connections using HTTP CONNECT, httplib sets the necessary
+            # headers on the CONNECT to the proxy. If we're not using CONNECT,
+            # we'll definitely need to set 'Host' at the very least.
+            headers = kw.get("headers", self.headers)
+            kw["headers"] = self._set_proxy_headers(url, headers)
+
+        return super().urlopen(method, url, redirect=redirect, **kw)
+
+
+def proxy_from_url(url: str, **kw: typing.Any) -> ProxyManager:
+    return ProxyManager(proxy_url=url, **kw)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py
new file mode 100644
index 00000000000..ec7d3083307
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py
@@ -0,0 +1,1526 @@
+from __future__ import annotations
+
+import collections
+import io
+import json as _json
+import logging
+import socket
+import sys
+import typing
+import warnings
+import zlib
+from contextlib import contextmanager
+from http.client import HTTPMessage as _HttplibHTTPMessage
+from http.client import HTTPResponse as _HttplibHTTPResponse
+from socket import timeout as SocketTimeout
+
+if typing.TYPE_CHECKING:
+    from ._base_connection import BaseHTTPConnection
+
+try:
+    try:
+        import brotlicffi as brotli  # type: ignore[import-not-found]
+    except ImportError:
+        import brotli  # type: ignore[import-not-found]
+except ImportError:
+    brotli = None
+
+from . import util
+from ._base_connection import _TYPE_BODY
+from ._collections import HTTPHeaderDict
+from .connection import BaseSSLError, HTTPConnection, HTTPException
+from .exceptions import (
+    BodyNotHttplibCompatible,
+    DecodeError,
+    DependencyWarning,
+    HTTPError,
+    IncompleteRead,
+    InvalidChunkLength,
+    InvalidHeader,
+    ProtocolError,
+    ReadTimeoutError,
+    ResponseNotChunked,
+    SSLError,
+)
+from .util.response import is_fp_closed, is_response_to_head
+from .util.retry import Retry
+
+if typing.TYPE_CHECKING:
+    from .connectionpool import HTTPConnectionPool
+
+log = logging.getLogger(__name__)
+
+# Read in 64 KiB chunks
+_READ_CHUNK_SIZE = 2**16
+
+# Maximum length of a chunk-size line (and the trailing CRLF line) when reading a
+# chunked-transfer-encoded response. Matches ``http.client._MAXLINE`` so urllib3's
+# streaming path bounds these reads exactly like the stdlib ``.read()`` path does,
+# preventing a malicious server from forcing unbounded buffering (memory exhaustion)
+# via an unterminated chunk-size line.
+_MAX_CHUNK_LINE_LENGTH = 2**16
+
+
+class ContentDecoder:
+    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
+        raise NotImplementedError()
+
+    @property
+    def has_unconsumed_tail(self) -> bool:
+        raise NotImplementedError()
+
+    def flush(self) -> bytes:
+        raise NotImplementedError()
+
+
+class DeflateDecoder(ContentDecoder):
+    def __init__(self) -> None:
+        self._first_try = True
+        self._first_try_data = b""
+        self._unfed_data = b""
+        self._obj = zlib.decompressobj()
+
+    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
+        data = self._unfed_data + data
+        self._unfed_data = b""
+        # Data received after EOF cannot produce more output from this
+        # Deflate stream.
+        if self._obj.eof:
+            return b""
+        if not data and not self._obj.unconsumed_tail:
+            return data
+        original_max_length = max_length
+        if original_max_length < 0:
+            max_length = 0
+        elif original_max_length == 0:
+            # We should not pass 0 to the zlib decompressor because 0 is
+            # the default value that will make zlib decompress without a
+            # length limit.
+            # Data should be stored for subsequent calls.
+            self._unfed_data = data
+            return b""
+
+        # Subsequent calls always reuse `self._obj`. zlib requires
+        # passing the unconsumed tail if decompression is to continue.
+        if not self._first_try:
+            return self._obj.decompress(
+                self._obj.unconsumed_tail + data, max_length=max_length
+            )
+
+        # First call tries with RFC 1950 ZLIB format.
+        self._first_try_data += data
+        try:
+            decompressed = self._obj.decompress(data, max_length=max_length)
+            if decompressed:
+                self._first_try = False
+                self._first_try_data = b""
+            return decompressed
+        # On failure, it falls back to RFC 1951 DEFLATE format.
+        except zlib.error:
+            self._first_try = False
+            self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
+            try:
+                return self.decompress(
+                    self._first_try_data, max_length=original_max_length
+                )
+            finally:
+                self._first_try_data = b""
+
+    @property
+    def has_unconsumed_tail(self) -> bool:
+        return bool(self._unfed_data) or (
+            bool(self._obj.unconsumed_tail)
+            and not self._first_try
+            and not self._obj.eof
+        )
+
+    def flush(self) -> bytes:
+        return self._obj.flush()
+
+
+class GzipDecoderState:
+    FIRST_MEMBER = 0
+    OTHER_MEMBERS = 1
+    SWALLOW_DATA = 2
+
+
+class GzipDecoder(ContentDecoder):
+    def __init__(self) -> None:
+        self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
+        self._state = GzipDecoderState.FIRST_MEMBER
+        self._unconsumed_tail = b""
+
+    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
+        ret = bytearray()
+        if self._state == GzipDecoderState.SWALLOW_DATA:
+            return bytes(ret)
+
+        if max_length == 0:
+            # We should not pass 0 to the zlib decompressor because 0 is
+            # the default value that will make zlib decompress without a
+            # length limit.
+            # Data should be stored for subsequent calls.
+            self._unconsumed_tail += data
+            return b""
+
+        # zlib requires passing the unconsumed tail to the subsequent
+        # call if decompression is to continue.
+        data = self._unconsumed_tail + data
+        if not data and self._obj.eof:
+            return bytes(ret)
+
+        while True:
+            try:
+                ret += self._obj.decompress(
+                    data, max_length=max(max_length - len(ret), 0)
+                )
+            except zlib.error:
+                previous_state = self._state
+                # Ignore data after the first error
+                self._state = GzipDecoderState.SWALLOW_DATA
+                self._unconsumed_tail = b""
+                if previous_state == GzipDecoderState.OTHER_MEMBERS:
+                    # Allow trailing garbage acceptable in other gzip clients
+                    return bytes(ret)
+                raise
+
+            self._unconsumed_tail = data = (
+                self._obj.unconsumed_tail or self._obj.unused_data
+            )
+            if max_length > 0 and len(ret) >= max_length:
+                break
+
+            if not data:
+                return bytes(ret)
+            # When the end of a gzip member is reached, a new decompressor
+            # must be created for unused (possibly future) data.
+            if self._obj.eof:
+                self._state = GzipDecoderState.OTHER_MEMBERS
+                self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
+
+        return bytes(ret)
+
+    @property
+    def has_unconsumed_tail(self) -> bool:
+        return bool(self._unconsumed_tail)
+
+    def flush(self) -> bytes:
+        return self._obj.flush()
+
+
+if brotli is not None:
+
+    class BrotliDecoder(ContentDecoder):
+        # Supports both 'brotlipy' and 'Brotli' packages
+        # since they share an import name. The top branches
+        # are for 'brotlipy' and bottom branches for 'Brotli'
+        def __init__(self) -> None:
+            self._obj = brotli.Decompressor()
+            if hasattr(self._obj, "decompress"):
+                setattr(self, "_decompress", self._obj.decompress)
+            else:
+                setattr(self, "_decompress", self._obj.process)
+
+        # Requires Brotli >= 1.2.0 for `output_buffer_limit`.
+        def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes:
+            raise NotImplementedError()
+
+        def decompress(self, data: bytes, max_length: int = -1) -> bytes:
+            try:
+                if max_length > 0:
+                    return self._decompress(data, output_buffer_limit=max_length)
+                else:
+                    return self._decompress(data)
+            except TypeError:
+                # Fallback for Brotli/brotlicffi/brotlipy versions without
+                # the `output_buffer_limit` parameter.
+                warnings.warn(
+                    "Brotli >= 1.2.0 is required to prevent decompression bombs.",
+                    DependencyWarning,
+                )
+                return self._decompress(data)
+
+        @property
+        def has_unconsumed_tail(self) -> bool:
+            try:
+                return not self._obj.can_accept_more_data()
+            except AttributeError:
+                return False
+
+        def flush(self) -> bytes:
+            if hasattr(self._obj, "flush"):
+                return self._obj.flush()  # type: ignore[no-any-return]
+            return b""
+
+
+try:
+    if sys.version_info >= (3, 14):
+        from compression import zstd
+    else:
+        from backports import zstd
+except ImportError:
+    HAS_ZSTD = False
+else:
+    HAS_ZSTD = True
+
+    class ZstdDecoder(ContentDecoder):
+        def __init__(self) -> None:
+            self._obj = zstd.ZstdDecompressor()
+
+        def decompress(self, data: bytes, max_length: int = -1) -> bytes:
+            if not data and not self.has_unconsumed_tail:
+                return b""
+            if self._obj.eof:
+                data = self._obj.unused_data + data
+                self._obj = zstd.ZstdDecompressor()
+            part = self._obj.decompress(data, max_length=max_length)
+            length = len(part)
+            data_parts = [part]
+            # Every loop iteration is supposed to read data from a separate frame.
+            # The loop breaks when:
+            #   - enough data is read;
+            #   - no more unused data is available;
+            #   - end of the last read frame has not been reached (i.e.,
+            #     more data has to be fed).
+            while (
+                self._obj.eof
+                and self._obj.unused_data
+                and (max_length < 0 or length < max_length)
+            ):
+                unused_data = self._obj.unused_data
+                if not self._obj.needs_input:
+                    self._obj = zstd.ZstdDecompressor()
+                part = self._obj.decompress(
+                    unused_data,
+                    max_length=(max_length - length) if max_length > 0 else -1,
+                )
+                if part_length := len(part):
+                    data_parts.append(part)
+                    length += part_length
+                elif self._obj.needs_input:
+                    break
+            return b"".join(data_parts)
+
+        @property
+        def has_unconsumed_tail(self) -> bool:
+            return not (self._obj.needs_input or self._obj.eof) or bool(
+                self._obj.unused_data
+            )
+
+        def flush(self) -> bytes:
+            if not self._obj.eof:
+                raise DecodeError("Zstandard data is incomplete")
+            return b""
+
+
+class MultiDecoder(ContentDecoder):
+    """
+    From RFC7231:
+        If one or more encodings have been applied to a representation, the
+        sender that applied the encodings MUST generate a Content-Encoding
+        header field that lists the content codings in the order in which
+        they were applied.
+    """
+
+    # Maximum allowed number of chained HTTP encodings in the
+    # Content-Encoding header.
+    max_decode_links = 5
+
+    def __init__(self, modes: str) -> None:
+        encodings = [m.strip() for m in modes.split(",")]
+        if len(encodings) > self.max_decode_links:
+            raise DecodeError(
+                "Too many content encodings in the chain: "
+                f"{len(encodings)} > {self.max_decode_links}"
+            )
+        self._decoders = [_get_decoder(e) for e in encodings]
+
+    def flush(self) -> bytes:
+        return self._decoders[0].flush()
+
+    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
+        if max_length <= 0:
+            for d in reversed(self._decoders):
+                data = d.decompress(data)
+            return data
+
+        ret = bytearray()
+        # Every while loop iteration goes through all decoders once.
+        # It exits when enough data is read or no more data can be read.
+        # It is possible that the while loop iteration does not produce
+        # any data because we retrieve up to `max_length` from every
+        # decoder, and the amount of bytes may be insufficient for the
+        # next decoder to produce enough/any output.
+        while True:
+            any_data = False
+            for d in reversed(self._decoders):
+                data = d.decompress(data, max_length=max_length - len(ret))
+                if data:
+                    any_data = True
+                # We should not break when no data is returned because
+                # next decoders may produce data even with empty input.
+            ret += data
+            if not any_data or len(ret) >= max_length:
+                return bytes(ret)
+            data = b""
+
+    @property
+    def has_unconsumed_tail(self) -> bool:
+        return any(d.has_unconsumed_tail for d in self._decoders)
+
+
+def _get_decoder(mode: str) -> ContentDecoder:
+    if "," in mode:
+        return MultiDecoder(mode)
+
+    # According to RFC 9110 section 8.4.1.3, recipients should
+    # consider x-gzip equivalent to gzip
+    if mode in ("gzip", "x-gzip"):
+        return GzipDecoder()
+
+    if brotli is not None and mode == "br":
+        return BrotliDecoder()
+
+    if HAS_ZSTD and mode == "zstd":
+        return ZstdDecoder()
+
+    return DeflateDecoder()
+
+
+class BytesQueueBuffer:
+    """Memory-efficient bytes buffer
+
+    To return decoded data in read() and still follow the BufferedIOBase API, we need a
+    buffer to always return the correct amount of bytes.
+
+    This buffer should be filled using calls to put()
+
+    Our maximum memory usage is determined by the sum of the size of:
+
+     * self.buffer, which contains the full data
+     * the largest chunk that we will copy in get()
+    """
+
+    def __init__(self) -> None:
+        self.buffer: typing.Deque[bytes | memoryview[bytes]] = collections.deque()
+        self._size: int = 0
+
+    def __len__(self) -> int:
+        return self._size
+
+    def put(self, data: bytes) -> None:
+        self.buffer.append(data)
+        self._size += len(data)
+
+    def get(self, n: int) -> bytes:
+        if n == 0:
+            return b""
+        elif not self.buffer:
+            raise RuntimeError("buffer is empty")
+        elif n < 0:
+            raise ValueError("n should be > 0")
+
+        if len(self.buffer[0]) == n and isinstance(self.buffer[0], bytes):
+            self._size -= n
+            return self.buffer.popleft()
+
+        fetched = 0
+        ret = io.BytesIO()
+        while fetched < n:
+            remaining = n - fetched
+            chunk = self.buffer.popleft()
+            chunk_length = len(chunk)
+            if remaining < chunk_length:
+                chunk = memoryview(chunk)
+                left_chunk, right_chunk = chunk[:remaining], chunk[remaining:]
+                ret.write(left_chunk)
+                self.buffer.appendleft(right_chunk)
+                self._size -= remaining
+                break
+            else:
+                ret.write(chunk)
+                self._size -= chunk_length
+            fetched += chunk_length
+
+            if not self.buffer:
+                break
+
+        return ret.getvalue()
+
+    def get_all(self) -> bytes:
+        buffer = self.buffer
+        if not buffer:
+            assert self._size == 0
+            return b""
+        if len(buffer) == 1:
+            result = buffer.pop()
+            if isinstance(result, memoryview):
+                result = result.tobytes()
+        else:
+            ret = io.BytesIO()
+            ret.writelines(buffer.popleft() for _ in range(len(buffer)))
+            result = ret.getvalue()
+        self._size = 0
+        return result
+
+
+class BaseHTTPResponse(io.IOBase):
+    CONTENT_DECODERS = ["gzip", "x-gzip", "deflate"]
+    if brotli is not None:
+        CONTENT_DECODERS += ["br"]
+    if HAS_ZSTD:
+        CONTENT_DECODERS += ["zstd"]
+    REDIRECT_STATUSES = [301, 302, 303, 307, 308]
+
+    DECODER_ERROR_CLASSES: tuple[type[Exception], ...] = (IOError, zlib.error)
+    if brotli is not None:
+        DECODER_ERROR_CLASSES += (brotli.error,)
+
+    if HAS_ZSTD:
+        DECODER_ERROR_CLASSES += (zstd.ZstdError,)
+
+    def __init__(
+        self,
+        *,
+        headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None,
+        status: int,
+        version: int,
+        version_string: str,
+        reason: str | None,
+        decode_content: bool,
+        request_url: str | None,
+        retries: Retry | None = None,
+    ) -> None:
+        if isinstance(headers, HTTPHeaderDict):
+            self.headers = headers
+        else:
+            self.headers = HTTPHeaderDict(headers)  # type: ignore[arg-type]
+        self.status = status
+        self.version = version
+        self.version_string = version_string
+        self.reason = reason
+        self.decode_content = decode_content
+        self._has_decoded_content = False
+        self._request_url: str | None = request_url
+        self.retries = retries
+
+        self.chunked = False
+        tr_enc = self.headers.get("transfer-encoding", "").lower()
+        # Don't incur the penalty of creating a list and then discarding it
+        encodings = (enc.strip() for enc in tr_enc.split(","))
+        if "chunked" in encodings:
+            self.chunked = True
+
+        self._decoder: ContentDecoder | None = None
+        # Distinguish an uninitialized decoder from a response needing no decoder.
+        self._decoder_initialized = False
+        self.length_remaining: int | None
+
+    def get_redirect_location(self) -> str | None | typing.Literal[False]:
+        """
+        Should we redirect and where to?
+
+        :returns: Truthy redirect location string if we got a redirect status
+            code and valid location. ``None`` if redirect status and no
+            location. ``False`` if not a redirect status code.
+        """
+        if self.status in self.REDIRECT_STATUSES:
+            return self.headers.get("location")
+        return False
+
+    @property
+    def data(self) -> bytes:
+        raise NotImplementedError()
+
+    def json(self) -> typing.Any:
+        """
+        Deserializes the body of the HTTP response as a Python object.
+
+        The body of the HTTP response must be encoded using UTF-8, as per
+        `RFC 8529 Section 8.1 `_.
+
+        To use a custom JSON decoder pass the result of :attr:`HTTPResponse.data` to
+        your custom decoder instead.
+
+        If the body of the HTTP response is not decodable to UTF-8, a
+        `UnicodeDecodeError` will be raised. If the body of the HTTP response is not a
+        valid JSON document, a `json.JSONDecodeError` will be raised.
+
+        Read more :ref:`here `.
+
+        :returns: The body of the HTTP response as a Python object.
+        """
+        data = self.data.decode("utf-8")
+        return _json.loads(data)
+
+    @property
+    def url(self) -> str | None:
+        raise NotImplementedError()
+
+    @url.setter
+    def url(self, url: str | None) -> None:
+        raise NotImplementedError()
+
+    @property
+    def connection(self) -> BaseHTTPConnection | None:
+        raise NotImplementedError()
+
+    @property
+    def retries(self) -> Retry | None:
+        return self._retries
+
+    @retries.setter
+    def retries(self, retries: Retry | None) -> None:
+        # Override the request_url if retries has a redirect location.
+        if retries is not None and retries.history:
+            self.url = retries.history[-1].redirect_location
+        self._retries = retries
+
+    def stream(
+        self, amt: int | None = _READ_CHUNK_SIZE, decode_content: bool | None = None
+    ) -> typing.Iterator[bytes]:
+        raise NotImplementedError()
+
+    def read(
+        self,
+        amt: int | None = None,
+        decode_content: bool | None = None,
+        cache_content: bool = False,
+    ) -> bytes:
+        raise NotImplementedError()
+
+    def read1(
+        self,
+        amt: int | None = None,
+        decode_content: bool | None = None,
+    ) -> bytes:
+        raise NotImplementedError()
+
+    def read_chunked(
+        self,
+        amt: int | None = None,
+        decode_content: bool | None = None,
+    ) -> typing.Iterator[bytes]:
+        raise NotImplementedError()
+
+    def release_conn(self) -> None:
+        raise NotImplementedError()
+
+    def drain_conn(self) -> None:
+        raise NotImplementedError()
+
+    def shutdown(self) -> None:
+        raise NotImplementedError()
+
+    def close(self) -> None:
+        raise NotImplementedError()
+
+    def _init_decoder(self) -> None:
+        """
+        Set-up the _decoder attribute if necessary.
+        """
+        if self._decoder_initialized:
+            return
+
+        if self._decoder is None:
+            # Note: content-encoding value should be case-insensitive, per RFC 7230
+            # Section 3.2
+            content_encoding = self.headers.get("content-encoding", "").lower()
+            if content_encoding in self.CONTENT_DECODERS:
+                self._decoder = _get_decoder(content_encoding)
+            elif "," in content_encoding:
+                encodings = [
+                    e.strip()
+                    for e in content_encoding.split(",")
+                    if e.strip() in self.CONTENT_DECODERS
+                ]
+                if encodings:
+                    self._decoder = _get_decoder(content_encoding)
+
+        self._decoder_initialized = True
+
+    def _decode(
+        self,
+        data: bytes,
+        decode_content: bool | None,
+        flush_decoder: bool,
+        max_length: int | None = None,
+    ) -> bytes:
+        """
+        Decode the data passed in and potentially flush the decoder.
+        """
+        if not decode_content:
+            if self._has_decoded_content:
+                raise RuntimeError(
+                    "Calling read(decode_content=False) is not supported after "
+                    "read(decode_content=True) was called."
+                )
+            return data
+
+        if max_length is None or flush_decoder:
+            max_length = -1
+
+        try:
+            if self._decoder:
+                data = self._decoder.decompress(data, max_length=max_length)
+                self._has_decoded_content = True
+        except self.DECODER_ERROR_CLASSES as e:
+            content_encoding = self.headers.get("content-encoding", "").lower()
+            raise DecodeError(
+                "Received response with content-encoding: %s, but "
+                "failed to decode it." % content_encoding,
+                e,
+            ) from e
+        if flush_decoder:
+            data += self._flush_decoder()
+
+        return data
+
+    def _flush_decoder(self) -> bytes:
+        """
+        Flushes the decoder. Should only be called if the decoder is actually
+        being used.
+        """
+        if self._decoder:
+            return self._decoder.decompress(b"") + self._decoder.flush()
+        return b""
+
+    # Compatibility methods for `io` module
+    def readinto(self, b: bytearray | memoryview[int]) -> int:
+        temp = self.read(len(b))
+        if len(temp) == 0:
+            return 0
+        else:
+            b[: len(temp)] = temp
+            return len(temp)
+
+    # Methods used by dependent libraries
+    def getheaders(self) -> HTTPHeaderDict:
+        return self.headers
+
+    def getheader(self, name: str, default: str | None = None) -> str | None:
+        return self.headers.get(name, default)
+
+    # Compatibility method for http.cookiejar
+    def info(self) -> HTTPHeaderDict:
+        return self.headers
+
+    def geturl(self) -> str | None:
+        return self.url
+
+
+class HTTPResponse(BaseHTTPResponse):
+    """
+    HTTP Response container.
+
+    Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is
+    loaded and decoded on-demand when the ``data`` property is accessed.  This
+    class is also compatible with the Python standard library's :mod:`io`
+    module, and can hence be treated as a readable object in the context of that
+    framework.
+
+    Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`:
+
+    :param preload_content:
+        If True, the response's body will be preloaded during construction.
+
+    :param decode_content:
+        If True, will attempt to decode the body based on the
+        'content-encoding' header.
+
+    :param original_response:
+        When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse`
+        object, it's convenient to include the original for debug purposes. It's
+        otherwise unused.
+
+    :param retries:
+        The retries contains the last :class:`~urllib3.util.retry.Retry` that
+        was used during the request.
+
+    :param enforce_content_length:
+        Enforce content length checking. Body returned by server must match
+        value of Content-Length header, if present. Otherwise, raise error.
+    """
+
+    def __init__(
+        self,
+        body: _TYPE_BODY = "",
+        headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None,
+        status: int = 0,
+        version: int = 0,
+        version_string: str = "HTTP/?",
+        reason: str | None = None,
+        preload_content: bool = True,
+        decode_content: bool = True,
+        original_response: _HttplibHTTPResponse | None = None,
+        pool: HTTPConnectionPool | None = None,
+        connection: HTTPConnection | None = None,
+        msg: _HttplibHTTPMessage | None = None,
+        retries: Retry | None = None,
+        enforce_content_length: bool = True,
+        request_method: str | None = None,
+        request_url: str | None = None,
+        auto_close: bool = True,
+        sock_shutdown: typing.Callable[[int], None] | None = None,
+    ) -> None:
+        super().__init__(
+            headers=headers,
+            status=status,
+            version=version,
+            version_string=version_string,
+            reason=reason,
+            decode_content=decode_content,
+            request_url=request_url,
+            retries=retries,
+        )
+
+        self.enforce_content_length = enforce_content_length
+        self.auto_close = auto_close
+
+        self._body = None
+        self._uncached_read_occurred = False
+        self._fp: _HttplibHTTPResponse | None = None
+        self._original_response = original_response
+        self._fp_bytes_read = 0
+        self.msg = msg
+
+        if body and isinstance(body, (str, bytes)):
+            self._body = body
+
+        self._pool = pool
+        self._connection = connection
+
+        if hasattr(body, "read"):
+            self._fp = body  # type: ignore[assignment]
+        self._sock_shutdown = sock_shutdown
+
+        # Are we using the chunked-style of transfer encoding?
+        self.chunk_left: int | None = None
+
+        # Determine length of response
+        self.length_remaining = self._init_length(request_method)
+
+        # Used to return the correct amount of bytes for partial read()s
+        self._decoded_buffer = BytesQueueBuffer()
+
+        # If requested, preload the body.
+        if preload_content and not self._body:
+            self._body = self.read(decode_content=decode_content)
+
+    def release_conn(self) -> None:
+        if not self._pool or not self._connection:
+            return None
+
+        self._pool._put_conn(self._connection)
+        self._connection = None
+
+    def drain_conn(self) -> None:
+        """
+        Read and discard any remaining HTTP response data in the response connection.
+
+        Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
+        """
+        try:
+            while self._raw_read(_READ_CHUNK_SIZE):
+                pass
+        except (HTTPError, OSError, BaseSSLError, HTTPException):
+            pass
+        if self._has_decoded_content:
+            # `_raw_read` skips decompression, so we should clean up the
+            # decoder to avoid keeping unnecessary data in memory.
+            self._decoded_buffer = BytesQueueBuffer()
+            self._decoder = None
+
+    @property
+    def data(self) -> bytes:
+        # For backwards-compat with earlier urllib3 0.4 and earlier.
+        if self._body:
+            return self._body  # type: ignore[return-value]
+
+        if self._fp:
+            return self.read(cache_content=True)
+
+        return None  # type: ignore[return-value]
+
+    @property
+    def connection(self) -> HTTPConnection | None:
+        return self._connection
+
+    def isclosed(self) -> bool:
+        return is_fp_closed(self._fp)
+
+    def tell(self) -> int:
+        """
+        Obtain the number of bytes pulled over the wire so far. May differ from
+        the amount of content returned by :meth:`HTTPResponse.read`
+        if bytes are encoded on the wire (e.g, compressed).
+        """
+        return self._fp_bytes_read
+
+    def _init_length(self, request_method: str | None) -> int | None:
+        """
+        Set initial length value for Response content if available.
+        """
+        length: int | None
+        content_length: str | None = self.headers.get("content-length")
+
+        if content_length is not None:
+            if self.chunked:
+                # This Response will fail with an IncompleteRead if it can't be
+                # received as chunked. This method falls back to attempt reading
+                # the response before raising an exception.
+                log.warning(
+                    "Received response with both Content-Length and "
+                    "Transfer-Encoding set. This is expressly forbidden "
+                    "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
+                    "attempting to process response as Transfer-Encoding: "
+                    "chunked."
+                )
+                return None
+
+            try:
+                # RFC 7230 section 3.3.2 specifies multiple content lengths can
+                # be sent in a single Content-Length header
+                # (e.g. Content-Length: 42, 42). This line ensures the values
+                # are all valid ints and that as long as the `set` length is 1,
+                # all values are the same. Otherwise, the header is invalid.
+                lengths = {int(val) for val in content_length.split(",")}
+                if len(lengths) > 1:
+                    raise InvalidHeader(
+                        "Content-Length contained multiple "
+                        "unmatching values (%s)" % content_length
+                    )
+                length = lengths.pop()
+            except ValueError:
+                length = None
+            else:
+                if length < 0:
+                    length = None
+
+        else:  # if content_length is None
+            length = None
+
+        # Convert status to int for comparison
+        # In some cases, httplib returns a status of "_UNKNOWN"
+        try:
+            status = int(self.status)
+        except ValueError:
+            status = 0
+
+        # Check for responses that shouldn't include a body
+        if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD":
+            length = 0
+
+        return length
+
+    @contextmanager
+    def _error_catcher(self) -> typing.Generator[None]:
+        """
+        Catch low-level python exceptions, instead re-raising urllib3
+        variants, so that low-level exceptions are not leaked in the
+        high-level api.
+
+        On exit, release the connection back to the pool.
+        """
+        clean_exit = False
+
+        try:
+            try:
+                yield
+
+            except SocketTimeout as e:
+                # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
+                # there is yet no clean way to get at it from this context.
+                raise ReadTimeoutError(self._pool, None, "Read timed out.") from e  # type: ignore[arg-type]
+
+            except BaseSSLError as e:
+                # SSL errors related to framing/MAC get wrapped and reraised here
+                raise SSLError(e) from e
+
+            except IncompleteRead as e:
+                if (
+                    e.expected is not None
+                    and e.partial is not None
+                    and e.expected == -e.partial
+                ):
+                    arg = "Response may not contain content."
+                else:
+                    arg = f"Connection broken: {e!r}"
+                raise ProtocolError(arg, e) from e
+
+            except (HTTPException, OSError) as e:
+                raise ProtocolError(f"Connection broken: {e!r}", e) from e
+
+            # If no exception is thrown, we should avoid cleaning up
+            # unnecessarily.
+            clean_exit = True
+        finally:
+            # If we didn't terminate cleanly, we need to throw away our
+            # connection.
+            if not clean_exit:
+                # The response may not be closed but we're not going to use it
+                # anymore so close it now to ensure that the connection is
+                # released back to the pool.
+                if self._original_response:
+                    self._original_response.close()
+
+                # Closing the response may not actually be sufficient to close
+                # everything, so if we have a hold of the connection close that
+                # too.
+                if self._connection:
+                    self._connection.close()
+
+            # If we hold the original response but it's closed now, we should
+            # return the connection back to the pool.
+            if self._original_response and self._original_response.isclosed():
+                self.release_conn()
+
+    def _fp_read(
+        self,
+        amt: int | None = None,
+        *,
+        read1: bool = False,
+    ) -> bytes:
+        """
+        Read a response with the thought that reading the number of bytes
+        larger than can fit in a 32-bit int at a time via SSL in some
+        known cases leads to an overflow error that has to be prevented
+        if `amt` or `self.length_remaining` indicate that a problem may
+        happen.
+
+        This happens to urllib3 injected with pyOpenSSL-backed SSL-support.
+        """
+        assert self._fp
+        c_int_max = 2**31 - 1
+        if (
+            (amt and amt > c_int_max)
+            or (
+                amt is None
+                and self.length_remaining
+                and self.length_remaining > c_int_max
+            )
+        ) and util.IS_PYOPENSSL:
+            if read1:
+                return self._fp.read1(c_int_max)
+            buffer = io.BytesIO()
+            # Besides `max_chunk_amt` being a maximum chunk size, it
+            # affects memory overhead of reading a response by this
+            # method in CPython.
+            # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum
+            # chunk size that does not lead to an overflow error, but
+            # 256 MiB is a compromise.
+            max_chunk_amt = 2**28
+            while amt is None or amt != 0:
+                if amt is not None:
+                    chunk_amt = min(amt, max_chunk_amt)
+                    amt -= chunk_amt
+                else:
+                    chunk_amt = max_chunk_amt
+                data = self._fp.read(chunk_amt)
+                if not data:
+                    break
+                buffer.write(data)
+                del data  # to reduce peak memory usage by `max_chunk_amt`.
+            return buffer.getvalue()
+        elif read1:
+            return self._fp.read1(amt) if amt is not None else self._fp.read1()
+        else:
+            # StringIO doesn't like amt=None
+            return self._fp.read(amt) if amt is not None else self._fp.read()
+
+    def _raw_read(
+        self,
+        amt: int | None = None,
+        *,
+        read1: bool = False,
+    ) -> bytes:
+        """
+        Reads `amt` of bytes from the socket.
+        """
+        if self._fp is None:
+            return None  # type: ignore[return-value]
+
+        fp_closed = getattr(self._fp, "closed", False)
+
+        with self._error_catcher():
+            data = self._fp_read(amt, read1=read1) if not fp_closed else b""
+            if amt is not None and amt != 0 and not data:
+                # Platform-specific: Buggy versions of Python.
+                # Close the connection when no data is returned
+                #
+                # This is redundant to what httplib/http.client _should_
+                # already do.  However, versions of python released before
+                # December 15, 2012 (http://bugs.python.org/issue16298) do
+                # not properly close the connection in all cases. There is
+                # no harm in redundantly calling close.
+                self._fp.close()
+                if (
+                    self.enforce_content_length
+                    and self.length_remaining is not None
+                    and self.length_remaining != 0
+                ):
+                    # This is an edge case that httplib failed to cover due
+                    # to concerns of backward compatibility. We're
+                    # addressing it here to make sure IncompleteRead is
+                    # raised during streaming, so all calls with incorrect
+                    # Content-Length are caught.
+                    raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
+            elif read1 and (
+                (amt != 0 and not data) or self.length_remaining == len(data)
+            ):
+                # All data has been read, but `self._fp.read1` in
+                # CPython 3.12 and older doesn't always close
+                # `http.client.HTTPResponse`, so we close it here.
+                # See https://github.com/python/cpython/issues/113199
+                self._fp.close()
+
+        if data:
+            self._fp_bytes_read += len(data)
+            if self.length_remaining is not None:
+                self.length_remaining -= len(data)
+        return data
+
+    def read(
+        self,
+        amt: int | None = None,
+        decode_content: bool | None = None,
+        cache_content: bool = False,
+    ) -> bytes:
+        """
+        Similar to :meth:`http.client.HTTPResponse.read`, but with two additional
+        parameters: ``decode_content`` and ``cache_content``.
+
+        :param amt:
+            How much of the content to read. If specified, caching is skipped
+            because it doesn't make sense to cache partial content as the full
+            response.
+
+        :param decode_content:
+            If True, will attempt to decode the body based on the
+            'content-encoding' header.
+
+        :param cache_content:
+            If True, will save the returned data such that the same result is
+            returned despite of the state of the underlying file object. This
+            is useful if you want the ``.data`` property to continue working
+            after having ``.read()`` the file object. (Overridden if ``amt`` is
+            set.)
+        """
+        self._init_decoder()
+        if decode_content is None:
+            decode_content = self.decode_content
+
+        if amt and amt < 0:
+            # Negative numbers and `None` should be treated the same.
+            amt = None
+        elif amt is not None:
+            cache_content = False
+
+            if (
+                self._decoder
+                and self._decoder.has_unconsumed_tail
+                and len(self._decoded_buffer) < amt
+            ):
+                decoded_data = self._decode(
+                    b"",
+                    decode_content,
+                    flush_decoder=False,
+                    max_length=amt - len(self._decoded_buffer),
+                )
+                self._decoded_buffer.put(decoded_data)
+            if len(self._decoded_buffer) >= amt:
+                return self._decoded_buffer.get(amt)
+
+        data = self._raw_read(amt)
+        if not cache_content:
+            self._uncached_read_occurred = True
+
+        flush_decoder = amt is None or (amt != 0 and not data)
+
+        if (
+            not data
+            and len(self._decoded_buffer) == 0
+            and not (self._decoder and self._decoder.has_unconsumed_tail)
+        ):
+            return data
+
+        if amt is None:
+            data = self._decode(data, decode_content, flush_decoder)
+            # It's possible that there is buffered decoded data after a
+            # partial read.
+            if decode_content and len(self._decoded_buffer) > 0:
+                self._decoded_buffer.put(data)
+                data = self._decoded_buffer.get_all()
+
+            if cache_content and not self._uncached_read_occurred:
+                self._body = data
+        else:
+            # do not waste memory on buffer when not decoding
+            if not decode_content:
+                if self._has_decoded_content:
+                    raise RuntimeError(
+                        "Calling read(decode_content=False) is not supported after "
+                        "read(decode_content=True) was called."
+                    )
+                return data
+
+            decoded_data = self._decode(
+                data,
+                decode_content,
+                flush_decoder,
+                max_length=amt - len(self._decoded_buffer),
+            )
+            self._decoded_buffer.put(decoded_data)
+
+            while len(self._decoded_buffer) < amt and data:
+                # TODO make sure to initially read enough data to get past the headers
+                # For example, the GZ file header takes 10 bytes, we don't want to read
+                # it one byte at a time
+                data = self._raw_read(amt)
+                decoded_data = self._decode(
+                    data,
+                    decode_content,
+                    flush_decoder,
+                    max_length=amt - len(self._decoded_buffer),
+                )
+                self._decoded_buffer.put(decoded_data)
+            data = self._decoded_buffer.get(amt)
+
+        return data
+
+    def read1(
+        self,
+        amt: int | None = None,
+        decode_content: bool | None = None,
+    ) -> bytes:
+        """
+        Similar to ``http.client.HTTPResponse.read1`` and documented
+        in :meth:`io.BufferedReader.read1`, but with an additional parameter:
+        ``decode_content``.
+
+        :param amt:
+            How much of the content to read.
+
+        :param decode_content:
+            If True, will attempt to decode the body based on the
+            'content-encoding' header.
+        """
+        if decode_content is None:
+            decode_content = self.decode_content
+        if amt and amt < 0:
+            # Negative numbers and `None` should be treated the same.
+            amt = None
+        # try and respond without going to the network
+        if self._has_decoded_content:
+            if not decode_content:
+                raise RuntimeError(
+                    "Calling read1(decode_content=False) is not supported after "
+                    "read1(decode_content=True) was called."
+                )
+            if (
+                self._decoder
+                and self._decoder.has_unconsumed_tail
+                and (amt is None or len(self._decoded_buffer) < amt)
+            ):
+                decoded_data = self._decode(
+                    b"",
+                    decode_content,
+                    flush_decoder=False,
+                    max_length=(
+                        amt - len(self._decoded_buffer) if amt is not None else None
+                    ),
+                )
+                self._decoded_buffer.put(decoded_data)
+            if len(self._decoded_buffer) > 0:
+                if amt is None:
+                    return self._decoded_buffer.get_all()
+                return self._decoded_buffer.get(amt)
+        if amt == 0:
+            return b""
+
+        # FIXME, this method's type doesn't say returning None is possible
+        data = self._raw_read(amt, read1=True)
+        self._uncached_read_occurred = True
+        if not decode_content or data is None:
+            return data
+
+        self._init_decoder()
+        while True:
+            flush_decoder = not data
+            decoded_data = self._decode(
+                data, decode_content, flush_decoder, max_length=amt
+            )
+            self._decoded_buffer.put(decoded_data)
+            if decoded_data or flush_decoder:
+                break
+            data = self._raw_read(8192, read1=True)
+
+        if amt is None:
+            return self._decoded_buffer.get_all()
+        return self._decoded_buffer.get(amt)
+
+    def stream(
+        self, amt: int | None = _READ_CHUNK_SIZE, decode_content: bool | None = None
+    ) -> typing.Generator[bytes]:
+        """
+        A generator wrapper for the read() method. A call will block until
+        ``amt`` bytes have been read from the connection or until the
+        connection is closed.
+
+        :param amt:
+            How much of the content to read. The generator will return up to
+            much data per iteration, but may return less. This is particularly
+            likely when using compressed data. However, the empty string will
+            never be returned.
+
+        :param decode_content:
+            If True, will attempt to decode the body based on the
+            'content-encoding' header.
+        """
+        if amt == 0:
+            return
+
+        if self.chunked and self.supports_chunked_reads():
+            yield from self.read_chunked(amt, decode_content=decode_content)
+        else:
+            while (
+                not is_fp_closed(self._fp)
+                or len(self._decoded_buffer) > 0
+                or (self._decoder and self._decoder.has_unconsumed_tail)
+            ):
+                data = self.read(amt=amt, decode_content=decode_content)
+
+                if data:
+                    yield data
+
+    # Overrides from io.IOBase
+    def readable(self) -> bool:
+        return True
+
+    def shutdown(self) -> None:
+        if not self._sock_shutdown:
+            raise ValueError("Cannot shutdown socket as self._sock_shutdown is not set")
+        if self._connection is None:
+            raise RuntimeError(
+                "Cannot shutdown as connection has already been released to the pool"
+            )
+        self._sock_shutdown(socket.SHUT_RD)
+
+    def close(self) -> None:
+        self._sock_shutdown = None
+
+        if not self.closed and self._fp:
+            self._fp.close()
+
+        if self._connection:
+            self._connection.close()
+
+        if not self.auto_close:
+            io.IOBase.close(self)
+
+    @property
+    def closed(self) -> bool:
+        if not self.auto_close:
+            return io.IOBase.closed.__get__(self)  # type: ignore[no-any-return]
+        elif self._fp is None:
+            return True
+        elif hasattr(self._fp, "isclosed"):
+            return self._fp.isclosed()
+        elif hasattr(self._fp, "closed"):
+            return self._fp.closed
+        else:
+            return True
+
+    def fileno(self) -> int:
+        if self._fp is None:
+            raise OSError("HTTPResponse has no file to get a fileno from")
+        elif hasattr(self._fp, "fileno"):
+            return self._fp.fileno()
+        else:
+            raise OSError(
+                "The file-like object this HTTPResponse is wrapped "
+                "around has no file descriptor"
+            )
+
+    def flush(self) -> None:
+        if (
+            self._fp is not None
+            and hasattr(self._fp, "flush")
+            and not getattr(self._fp, "closed", False)
+        ):
+            return self._fp.flush()
+
+    def supports_chunked_reads(self) -> bool:
+        """
+        Checks if the underlying file-like object looks like a
+        :class:`http.client.HTTPResponse` object. We do this by testing for
+        the fp attribute. If it is present we assume it returns raw chunks as
+        processed by read_chunked().
+        """
+        return hasattr(self._fp, "fp")
+
+    def _update_chunk_length(self) -> None:
+        # First, we'll figure out length of a chunk and then
+        # we'll try to read it from socket.
+        if self.chunk_left is not None:
+            return None
+        line = self._fp.fp.readline(_MAX_CHUNK_LINE_LENGTH + 1)  # type: ignore[union-attr]
+        if len(line) > _MAX_CHUNK_LINE_LENGTH:
+            self.close()
+            raise ProtocolError(
+                "Response chunk size line exceeded maximum allowed length"
+            ) from None
+        line = line.split(b";", 1)[0]
+        try:
+            self.chunk_left = int(line, 16)
+        except ValueError:
+            self.close()
+            if line:
+                # Invalid chunked protocol response, abort.
+                raise InvalidChunkLength(self, line) from None
+            else:
+                # Truncated at start of next chunk
+                raise ProtocolError("Response ended prematurely") from None
+
+    def _handle_chunk(self, amt: int | None) -> bytes:
+        returned_chunk = None
+        if amt is None:
+            chunk = self._fp._safe_read(self.chunk_left)  # type: ignore[union-attr]
+            returned_chunk = chunk
+            self._fp._safe_read(2)  # type: ignore[union-attr] # Toss the CRLF at the end of the chunk.
+            self.chunk_left = None
+        elif self.chunk_left is not None and amt < self.chunk_left:
+            value = self._fp._safe_read(amt)  # type: ignore[union-attr]
+            self.chunk_left = self.chunk_left - amt
+            returned_chunk = value
+        elif amt == self.chunk_left:
+            value = self._fp._safe_read(amt)  # type: ignore[union-attr]
+            self._fp._safe_read(2)  # type: ignore[union-attr] # Toss the CRLF at the end of the chunk.
+            self.chunk_left = None
+            returned_chunk = value
+        else:  # amt > self.chunk_left
+            returned_chunk = self._fp._safe_read(self.chunk_left)  # type: ignore[union-attr]
+            self._fp._safe_read(2)  # type: ignore[union-attr] # Toss the CRLF at the end of the chunk.
+            self.chunk_left = None
+        return returned_chunk  # type: ignore[no-any-return]
+
+    def read_chunked(
+        self, amt: int | None = None, decode_content: bool | None = None
+    ) -> typing.Generator[bytes]:
+        """
+        Similar to :meth:`HTTPResponse.read`, but with an additional
+        parameter: ``decode_content``.
+
+        :param amt:
+            How much of the content to read. If specified, caching is skipped
+            because it doesn't make sense to cache partial content as the full
+            response.
+
+        :param decode_content:
+            If True, will attempt to decode the body based on the
+            'content-encoding' header.
+        """
+        self._init_decoder()
+        # FIXME: Rewrite this method and make it a class with a better structured logic.
+        if not self.chunked:
+            raise ResponseNotChunked(
+                "Response is not chunked. "
+                "Header 'transfer-encoding: chunked' is missing."
+            )
+        if not self.supports_chunked_reads():
+            raise BodyNotHttplibCompatible(
+                "Body should be http.client.HTTPResponse like. "
+                "It should have have an fp attribute which returns raw chunks."
+            )
+
+        with self._error_catcher():
+            # Don't bother reading the body of a HEAD request.
+            if self._original_response and is_response_to_head(self._original_response):
+                self._original_response.close()
+                return None
+
+            # If a response is already read and closed
+            # then return immediately.
+            if self._fp.fp is None:  # type: ignore[union-attr]
+                return None
+
+            if amt == 0:
+                return
+            elif amt and amt < 0:
+                # Negative numbers and `None` should be treated the same,
+                # but httplib handles only `None` correctly.
+                amt = None
+
+            while True:
+                # First, check if any data is left in the decoder's buffer.
+                if self._decoder and self._decoder.has_unconsumed_tail:
+                    chunk = b""
+                else:
+                    self._update_chunk_length()
+                    self._uncached_read_occurred = True
+                    if self.chunk_left == 0:
+                        break
+                    chunk = self._handle_chunk(amt)
+                decoded = self._decode(
+                    chunk,
+                    decode_content=decode_content,
+                    flush_decoder=False,
+                    max_length=amt,
+                )
+                if decoded:
+                    yield decoded
+
+            if decode_content:
+                # On CPython and PyPy, we should never need to flush the
+                # decoder. However, on Jython we *might* need to, so
+                # lets defensively do it anyway.
+                decoded = self._flush_decoder()
+                if decoded:  # Platform-specific: Jython.
+                    yield decoded
+
+            # Chunk content ends with \r\n: discard it.
+            while self._fp is not None:
+                line = self._fp.fp.readline(_MAX_CHUNK_LINE_LENGTH + 1)
+                if len(line) > _MAX_CHUNK_LINE_LENGTH:
+                    raise ProtocolError(
+                        "Response chunk trailer line exceeded maximum allowed length"
+                    )
+                if not line:
+                    # Some sites may not end with '\r\n'.
+                    break
+                if line == b"\r\n":
+                    break
+
+            # We read everything; close the "file".
+            if self._original_response:
+                self._original_response.close()
+
+    @property
+    def url(self) -> str | None:
+        """
+        Returns the URL that was the source of this response.
+        If the request that generated this response redirected, this method
+        will return the final redirect location.
+        """
+        return self._request_url
+
+    @url.setter
+    def url(self, url: str | None) -> None:
+        self._request_url = url
+
+    def __iter__(self) -> typing.Iterator[bytes]:
+        buffer: list[bytes] = []
+        for chunk in self.stream(decode_content=True):
+            if b"\n" in chunk:
+                chunks = chunk.split(b"\n")
+                yield b"".join(buffer) + chunks[0] + b"\n"
+                for x in chunks[1:-1]:
+                    yield x + b"\n"
+                if chunks[-1]:
+                    buffer = [chunks[-1]]
+                else:
+                    buffer = []
+            else:
+                buffer.append(chunk)
+        if buffer:
+            yield b"".join(buffer)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py
new file mode 100644
index 00000000000..534126033c0
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py
@@ -0,0 +1,42 @@
+# For backwards compatibility, provide imports that used to be here.
+from __future__ import annotations
+
+from .connection import is_connection_dropped
+from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers
+from .response import is_fp_closed
+from .retry import Retry
+from .ssl_ import (
+    ALPN_PROTOCOLS,
+    IS_PYOPENSSL,
+    SSLContext,
+    assert_fingerprint,
+    create_urllib3_context,
+    resolve_cert_reqs,
+    resolve_ssl_version,
+    ssl_wrap_socket,
+)
+from .timeout import Timeout
+from .url import Url, parse_url
+from .wait import wait_for_read, wait_for_write
+
+__all__ = (
+    "IS_PYOPENSSL",
+    "SSLContext",
+    "ALPN_PROTOCOLS",
+    "Retry",
+    "Timeout",
+    "Url",
+    "assert_fingerprint",
+    "create_urllib3_context",
+    "is_connection_dropped",
+    "is_fp_closed",
+    "parse_url",
+    "make_headers",
+    "resolve_cert_reqs",
+    "resolve_ssl_version",
+    "ssl_wrap_socket",
+    "wait_for_read",
+    "wait_for_write",
+    "SKIP_HEADER",
+    "SKIPPABLE_HEADERS",
+)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py
new file mode 100644
index 00000000000..f92519ee912
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py
@@ -0,0 +1,137 @@
+from __future__ import annotations
+
+import socket
+import typing
+
+from ..exceptions import LocationParseError
+from .timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT
+
+_TYPE_SOCKET_OPTIONS = list[tuple[int, int, typing.Union[int, bytes]]]
+
+if typing.TYPE_CHECKING:
+    from .._base_connection import BaseHTTPConnection
+
+
+def is_connection_dropped(conn: BaseHTTPConnection) -> bool:  # Platform-specific
+    """
+    Returns True if the connection is dropped and should be closed.
+    :param conn: :class:`urllib3.connection.HTTPConnection` object.
+    """
+    return not conn.is_connected
+
+
+# This function is copied from socket.py in the Python 2.7 standard
+# library test suite. Added to its signature is only `socket_options`.
+# One additional modification is that we avoid binding to IPv6 servers
+# discovered in DNS if the system doesn't have IPv6 functionality.
+def create_connection(
+    address: tuple[str, int],
+    timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+    source_address: tuple[str, int] | None = None,
+    socket_options: _TYPE_SOCKET_OPTIONS | None = None,
+) -> socket.socket:
+    """Connect to *address* and return the socket object.
+
+    Convenience function.  Connect to *address* (a 2-tuple ``(host,
+    port)``) and return the socket object.  Passing the optional
+    *timeout* parameter will set the timeout on the socket instance
+    before attempting to connect.  If no *timeout* is supplied, the
+    global default timeout setting returned by :func:`socket.getdefaulttimeout`
+    is used.  If *source_address* is set it must be a tuple of (host, port)
+    for the socket to bind as a source address before making the connection.
+    An host of '' or port 0 tells the OS to use the default.
+    """
+
+    host, port = address
+    if host.startswith("["):
+        host = host.strip("[]")
+    err = None
+
+    # Using the value from allowed_gai_family() in the context of getaddrinfo lets
+    # us select whether to work with IPv4 DNS records, IPv6 records, or both.
+    # The original create_connection function always returns all records.
+    family = allowed_gai_family()
+
+    try:
+        host.encode("idna")
+    except UnicodeError:
+        raise LocationParseError(f"'{host}', label empty or too long") from None
+
+    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
+        af, socktype, proto, canonname, sa = res
+        sock = None
+        try:
+            sock = socket.socket(af, socktype, proto)
+
+            # If provided, set socket level options before connecting.
+            _set_socket_options(sock, socket_options)
+
+            if timeout is not _DEFAULT_TIMEOUT:
+                sock.settimeout(timeout)
+            if source_address:
+                sock.bind(source_address)
+            sock.connect(sa)
+            # Break explicitly a reference cycle
+            err = None
+            return sock
+
+        except OSError as _:
+            err = _
+            if sock is not None:
+                sock.close()
+
+    if err is not None:
+        try:
+            raise err
+        finally:
+            # Break explicitly a reference cycle
+            err = None
+    else:
+        raise OSError("getaddrinfo returns an empty list")
+
+
+def _set_socket_options(
+    sock: socket.socket, options: _TYPE_SOCKET_OPTIONS | None
+) -> None:
+    if options is None:
+        return
+
+    for opt in options:
+        sock.setsockopt(*opt)
+
+
+def allowed_gai_family() -> socket.AddressFamily:
+    """This function is designed to work in the context of
+    getaddrinfo, where family=socket.AF_UNSPEC is the default and
+    will perform a DNS search for both IPv6 and IPv4 records."""
+
+    family = socket.AF_INET
+    if HAS_IPV6:
+        family = socket.AF_UNSPEC
+    return family
+
+
+def _has_ipv6(host: str) -> bool:
+    """Returns True if the system can bind an IPv6 address."""
+    sock = None
+    has_ipv6 = False
+
+    if socket.has_ipv6:
+        # has_ipv6 returns true if cPython was compiled with IPv6 support.
+        # It does not tell us if the system has IPv6 support enabled. To
+        # determine that we must bind to an IPv6 address.
+        # https://github.com/urllib3/urllib3/pull/611
+        # https://bugs.python.org/issue658327
+        try:
+            sock = socket.socket(socket.AF_INET6)
+            sock.bind((host, 0))
+            has_ipv6 = True
+        except Exception:
+            pass
+
+    if sock:
+        sock.close()
+    return has_ipv6
+
+
+HAS_IPV6 = _has_ipv6("::1")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py
new file mode 100644
index 00000000000..908fc6621d0
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py
@@ -0,0 +1,43 @@
+from __future__ import annotations
+
+import typing
+
+from .url import Url
+
+if typing.TYPE_CHECKING:
+    from ..connection import ProxyConfig
+
+
+def connection_requires_http_tunnel(
+    proxy_url: Url | None = None,
+    proxy_config: ProxyConfig | None = None,
+    destination_scheme: str | None = None,
+) -> bool:
+    """
+    Returns True if the connection requires an HTTP CONNECT through the proxy.
+
+    :param URL proxy_url:
+        URL of the proxy.
+    :param ProxyConfig proxy_config:
+        Proxy configuration from poolmanager.py
+    :param str destination_scheme:
+        The scheme of the destination. (i.e https, http, etc)
+    """
+    # If we're not using a proxy, no way to use a tunnel.
+    if proxy_url is None:
+        return False
+
+    # HTTP destinations never require tunneling, we always forward.
+    if destination_scheme == "http":
+        return False
+
+    # Support for forwarding with HTTPS proxies and HTTPS destinations.
+    if (
+        proxy_url.scheme == "https"
+        and proxy_config
+        and proxy_config.use_forwarding_for_https
+    ):
+        return False
+
+    # Otherwise always use a tunnel.
+    return True
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py
new file mode 100644
index 00000000000..8c6c7fbdcfd
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py
@@ -0,0 +1,299 @@
+from __future__ import annotations
+
+import io
+import sys
+import typing
+from base64 import b64encode
+from enum import Enum
+
+from ..exceptions import UnrewindableBodyError
+from .util import to_bytes
+
+if typing.TYPE_CHECKING:
+    from typing import Final
+
+# Pass as a value within ``headers`` to skip
+# emitting some HTTP headers that are added automatically.
+# The only headers that are supported are ``Accept-Encoding``,
+# ``Host``, and ``User-Agent``.
+SKIP_HEADER = "@@@SKIP_HEADER@@@"
+SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"])
+
+ACCEPT_ENCODING = "gzip,deflate"
+try:
+    try:
+        import brotlicffi as _unused_module_brotli  # type: ignore[import-not-found] # noqa: F401
+    except ImportError:
+        import brotli as _unused_module_brotli  # type: ignore[import-not-found] # noqa: F401
+except ImportError:
+    pass
+else:
+    ACCEPT_ENCODING += ",br"
+
+try:
+    if sys.version_info >= (3, 14):
+        from compression import zstd as _unused_module_zstd  # noqa: F401
+    else:
+        from backports import zstd as _unused_module_zstd  # noqa: F401
+except ImportError:
+    pass
+else:
+    ACCEPT_ENCODING += ",zstd"
+
+
+class _TYPE_FAILEDTELL(Enum):
+    token = 0
+
+
+_FAILEDTELL: Final[_TYPE_FAILEDTELL] = _TYPE_FAILEDTELL.token
+
+_TYPE_BODY_POSITION = typing.Union[int, _TYPE_FAILEDTELL]
+
+# When sending a request with these methods we aren't expecting
+# a body so don't need to set an explicit 'Content-Length: 0'
+# The reason we do this in the negative instead of tracking methods
+# which 'should' have a body is because unknown methods should be
+# treated as if they were 'POST' which *does* expect a body.
+_METHODS_NOT_EXPECTING_BODY = {"GET", "HEAD", "DELETE", "TRACE", "OPTIONS", "CONNECT"}
+
+
+def make_headers(
+    keep_alive: bool | None = None,
+    accept_encoding: bool | list[str] | str | None = None,
+    user_agent: str | None = None,
+    basic_auth: str | None = None,
+    proxy_basic_auth: str | None = None,
+    disable_cache: bool | None = None,
+    *,
+    basic_auth_encoding: str = "latin-1",
+    proxy_basic_auth_encoding: str = "latin-1",
+) -> dict[str, str]:
+    """
+    Shortcuts for generating request headers.
+
+    :param keep_alive:
+        If ``True``, adds 'connection: keep-alive' header.
+
+    :param accept_encoding:
+        Can be a boolean, list, or string.
+        ``True`` translates to 'gzip,deflate'.  If the dependencies for
+        Brotli (either the ``brotli`` or ``brotlicffi`` package) and/or
+        Zstandard (the ``backports.zstd`` package for Python before 3.14)
+        algorithms are installed, then their encodings are
+        included in the string ('br' and 'zstd', respectively).
+        List will get joined by comma.
+        String will be used as provided.
+
+    :param user_agent:
+        String representing the user-agent you want, such as
+        "python-urllib3/0.6"
+
+    :param basic_auth:
+        Colon-separated username:password string for 'authorization: basic ...'
+        auth header. Basic authentication transmits Base64-encoded bytes, not
+        Unicode text, so the string is encoded with ``basic_auth_encoding``
+        before Base64 encoding.
+
+        Must contain decoded credentials (not percent-encoded).
+        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
+        to get the properly formatted string.
+
+    :param basic_auth_encoding:
+        Text encoding used to encode ``basic_auth`` before Base64 encoding.
+        Defaults to "latin-1" for backward compatibility. Use "utf-8" only
+        when the peer expects UTF-8 Basic authentication credentials.
+
+        Must contain decoded credentials (not percent-encoded).
+        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
+        to get the properly formatted string.
+
+    :param proxy_basic_auth:
+        Colon-separated username:password string for 'proxy-authorization: basic ...'
+        auth header. Basic authentication transmits Base64-encoded bytes, not
+        Unicode text, so the string is encoded with ``proxy_basic_auth_encoding``
+        before Base64 encoding.
+
+        Must contain decoded credentials (not percent-encoded).
+        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
+        to get the properly formatted string.
+
+    :param proxy_basic_auth_encoding:
+        Text encoding used to encode ``proxy_basic_auth`` before Base64
+        encoding. Defaults to "latin-1" for backward compatibility. Use
+        "utf-8" only when the proxy expects UTF-8 Basic authentication
+        credentials.
+
+        Must contain decoded credentials (not percent-encoded).
+        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
+        to get the properly formatted string.
+
+    :param disable_cache:
+        If ``True``, adds 'cache-control: no-cache' header.
+
+    Example:
+
+    .. code-block:: python
+
+        import urllib3
+
+        print(urllib3.util.make_headers(keep_alive=True, user_agent="Batman/1.0"))
+        # {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'}
+        print(urllib3.util.make_headers(accept_encoding=True))
+        # {'accept-encoding': 'gzip,deflate'}
+    """
+    headers: dict[str, str] = {}
+    if accept_encoding:
+        if isinstance(accept_encoding, str):
+            pass
+        elif isinstance(accept_encoding, list):
+            accept_encoding = ",".join(accept_encoding)
+        else:
+            accept_encoding = ACCEPT_ENCODING
+        headers["accept-encoding"] = accept_encoding
+
+    if user_agent:
+        headers["user-agent"] = user_agent
+
+    if keep_alive:
+        headers["connection"] = "keep-alive"
+
+    if basic_auth:
+        headers["authorization"] = (
+            f"Basic {b64encode(basic_auth.encode(basic_auth_encoding)).decode()}"
+        )
+
+    if proxy_basic_auth:
+        headers["proxy-authorization"] = (
+            f"Basic {b64encode(proxy_basic_auth.encode(proxy_basic_auth_encoding)).decode()}"
+        )
+
+    if disable_cache:
+        headers["cache-control"] = "no-cache"
+
+    return headers
+
+
+def set_file_position(
+    body: typing.Any, pos: _TYPE_BODY_POSITION | None
+) -> _TYPE_BODY_POSITION | None:
+    """
+    If a position is provided, move file to that point.
+    Otherwise, we'll attempt to record a position for future use.
+    """
+    if pos is not None:
+        rewind_body(body, pos)
+    elif getattr(body, "tell", None) is not None:
+        try:
+            pos = body.tell()
+        except OSError:
+            # This differentiates from None, allowing us to catch
+            # a failed `tell()` later when trying to rewind the body.
+            pos = _FAILEDTELL
+
+    return pos
+
+
+def rewind_body(body: typing.IO[typing.AnyStr], body_pos: _TYPE_BODY_POSITION) -> None:
+    """
+    Attempt to rewind body to a certain position.
+    Primarily used for request redirects and retries.
+
+    :param body:
+        File-like object that supports seek.
+
+    :param int pos:
+        Position to seek to in file.
+    """
+    body_seek = getattr(body, "seek", None)
+    if body_seek is not None and isinstance(body_pos, int):
+        try:
+            body_seek(body_pos)
+        except OSError as e:
+            raise UnrewindableBodyError(
+                "An error occurred when rewinding request body for redirect/retry."
+            ) from e
+    elif body_pos is _FAILEDTELL:
+        raise UnrewindableBodyError(
+            "Unable to record file position for rewinding "
+            "request body during a redirect/retry."
+        )
+    elif body_seek is None:
+        raise UnrewindableBodyError("body does not implement seek.")
+    else:
+        raise ValueError(
+            f"body_pos must be of type integer, instead it was {type(body_pos)}."
+        )
+
+
+class ChunksAndContentLength(typing.NamedTuple):
+    chunks: typing.Iterable[bytes] | None
+    content_length: int | None
+
+
+def body_to_chunks(
+    body: typing.Any | None, method: str, blocksize: int
+) -> ChunksAndContentLength:
+    """Takes the HTTP request method, body, and blocksize and
+    transforms them into an iterable of chunks to pass to
+    socket.sendall() and an optional 'Content-Length' header.
+
+    A 'Content-Length' of 'None' indicates the length of the body
+    can't be determined so should use 'Transfer-Encoding: chunked'
+    for framing instead.
+    """
+
+    chunks: typing.Iterable[bytes] | None
+    content_length: int | None
+
+    # No body, we need to make a recommendation on 'Content-Length'
+    # based on whether that request method is expected to have
+    # a body or not.
+    if body is None:
+        chunks = None
+        if method.upper() not in _METHODS_NOT_EXPECTING_BODY:
+            content_length = 0
+        else:
+            content_length = None
+
+    # Bytes or strings become bytes
+    elif isinstance(body, (str, bytes)):
+        chunks = (to_bytes(body),)
+        content_length = len(chunks[0])
+
+    # File-like object, TODO: use seek() and tell() for length?
+    elif hasattr(body, "read"):
+
+        def chunk_readable() -> typing.Iterable[bytes]:
+            encode = isinstance(body, io.TextIOBase)
+            while True:
+                datablock = body.read(blocksize)
+                if not datablock:
+                    break
+                if encode:
+                    datablock = datablock.encode("utf-8")
+                yield datablock
+
+        chunks = chunk_readable()
+        content_length = None
+
+    # Otherwise we need to start checking via duck-typing.
+    else:
+        try:
+            # Check if the body implements the buffer API.
+            mv = memoryview(body)
+        except TypeError:
+            try:
+                # Check if the body is an iterable
+                chunks = iter(body)
+                content_length = None
+            except TypeError:
+                raise TypeError(
+                    f"'body' must be a bytes-like object, file-like "
+                    f"object, or iterable. Instead was {body!r}"
+                ) from None
+        else:
+            # Since it implements the buffer API can be passed directly to socket.sendall()
+            chunks = (body,)
+            content_length = mv.nbytes
+
+    return ChunksAndContentLength(chunks=chunks, content_length=content_length)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py
new file mode 100644
index 00000000000..0f4578696fa
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py
@@ -0,0 +1,101 @@
+from __future__ import annotations
+
+import http.client as httplib
+from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect
+
+from ..exceptions import HeaderParsingError
+
+
+def is_fp_closed(obj: object) -> bool:
+    """
+    Checks whether a given file-like object is closed.
+
+    :param obj:
+        The file-like object to check.
+    """
+
+    try:
+        # Check `isclosed()` first, in case Python3 doesn't set `closed`.
+        # GH Issue #928
+        return obj.isclosed()  # type: ignore[no-any-return, attr-defined]
+    except AttributeError:
+        pass
+
+    try:
+        # Check via the official file-like-object way.
+        return obj.closed  # type: ignore[no-any-return, attr-defined]
+    except AttributeError:
+        pass
+
+    try:
+        # Check if the object is a container for another file-like object that
+        # gets released on exhaustion (e.g. HTTPResponse).
+        return obj.fp is None  # type: ignore[attr-defined]
+    except AttributeError:
+        pass
+
+    raise ValueError("Unable to determine whether fp is closed.")
+
+
+def assert_header_parsing(headers: httplib.HTTPMessage) -> None:
+    """
+    Asserts whether all headers have been successfully parsed.
+    Extracts encountered errors from the result of parsing headers.
+
+    Only works on Python 3.
+
+    :param http.client.HTTPMessage headers: Headers to verify.
+
+    :raises urllib3.exceptions.HeaderParsingError:
+        If parsing errors are found.
+    """
+
+    # This will fail silently if we pass in the wrong kind of parameter.
+    # To make debugging easier add an explicit check.
+    if not isinstance(headers, httplib.HTTPMessage):
+        raise TypeError(f"expected httplib.Message, got {type(headers)}.")
+
+    unparsed_data = None
+
+    # get_payload is actually email.message.Message.get_payload;
+    # we're only interested in the result if it's not a multipart message
+    if not headers.is_multipart():
+        payload = headers.get_payload()
+
+        if isinstance(payload, (bytes, str)):
+            unparsed_data = payload
+
+    # httplib is assuming a response body is available
+    # when parsing headers even when httplib only sends
+    # header data to parse_headers() This results in
+    # defects on multipart responses in particular.
+    # See: https://github.com/urllib3/urllib3/issues/800
+
+    # So we ignore the following defects:
+    # - StartBoundaryNotFoundDefect:
+    #     The claimed start boundary was never found.
+    # - MultipartInvariantViolationDefect:
+    #     A message claimed to be a multipart but no subparts were found.
+    defects = [
+        defect
+        for defect in headers.defects
+        if not isinstance(
+            defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect)
+        )
+    ]
+
+    if defects or unparsed_data:
+        raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
+
+
+def is_response_to_head(response: httplib.HTTPResponse) -> bool:
+    """
+    Checks whether the request of a response has been a HEAD-request.
+
+    :param http.client.HTTPResponse response:
+        Response to check if the originating request
+        used 'HEAD' as a method.
+    """
+    # FIXME: Can we do this somehow without accessing private httplib _method?
+    method_str = response._method  # type: str  # type: ignore[attr-defined]
+    return method_str.upper() == "HEAD"
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py
new file mode 100644
index 00000000000..42fa6fdd9c1
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py
@@ -0,0 +1,569 @@
+from __future__ import annotations
+
+import email
+import logging
+import random
+import re
+import time
+import typing
+import warnings
+from collections.abc import Collection
+from itertools import takewhile
+from types import TracebackType
+
+from ..exceptions import (
+    ConnectTimeoutError,
+    InvalidHeader,
+    MaxRetryError,
+    ProtocolError,
+    ProxyError,
+    ReadTimeoutError,
+    ResponseError,
+)
+from .util import reraise
+
+if typing.TYPE_CHECKING:
+    from opentelemetry.agent._vendor.typing_extensions import Self
+
+    from ..connectionpool import ConnectionPool
+    from ..response import BaseHTTPResponse
+
+log = logging.getLogger(__name__)
+
+
+# Data structure for representing the metadata of requests that result in a retry.
+class RequestHistory(typing.NamedTuple):
+    method: str | None
+    url: str | None
+    error: Exception | None
+    status: int | None
+    redirect_location: str | None
+
+
+class Retry:
+    """Retry configuration.
+
+    Each retry attempt will create a new Retry object with updated values, so
+    they can be safely reused.
+
+    Retries can be defined as a default for a pool:
+
+    .. code-block:: python
+
+        retries = Retry(connect=5, read=2, redirect=5)
+        http = PoolManager(retries=retries)
+        response = http.request("GET", "https://example.com/")
+
+    Or per-request (which overrides the default for the pool):
+
+    .. code-block:: python
+
+        response = http.request("GET", "https://example.com/", retries=Retry(10))
+
+    Retries can be disabled by passing ``False``:
+
+    .. code-block:: python
+
+        response = http.request("GET", "https://example.com/", retries=False)
+
+    Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless
+    retries are disabled, in which case the causing exception will be raised.
+
+    :param int total:
+        Total number of retries to allow. Takes precedence over other counts.
+
+        Set to ``None`` to remove this constraint and fall back on other
+        counts.
+
+        Set to ``0`` to fail on the first retry.
+
+        Set to ``False`` to disable and imply ``raise_on_redirect=False``.
+
+    :param int connect:
+        How many connection-related errors to retry on.
+
+        These are errors raised before the request is sent to the remote server,
+        which we assume has not triggered the server to process the request.
+
+        Set to ``0`` to fail on the first retry of this type.
+
+    :param int read:
+        How many times to retry on read errors.
+
+        These errors are raised after the request was sent to the server, so the
+        request may have side-effects.
+
+        Set to ``0`` to fail on the first retry of this type.
+
+    :param int redirect:
+        How many redirects to perform. Limit this to avoid infinite redirect
+        loops.
+
+        A redirect is a HTTP response with a status code 301, 302, 303, 307 or
+        308.
+
+        Set to ``0`` to fail on the first retry of this type.
+
+        Set to ``False`` to disable and imply ``raise_on_redirect=False``.
+
+    :param int status:
+        How many times to retry on bad status codes.
+
+        These are retries made on responses, where status code matches
+        ``status_forcelist``.
+
+        Set to ``0`` to fail on the first retry of this type.
+
+    :param int other:
+        How many times to retry on other errors.
+
+        Other errors are errors that are not connect, read, redirect or status errors.
+        These errors might be raised after the request was sent to the server, so the
+        request might have side-effects.
+
+        Set to ``0`` to fail on the first retry of this type.
+
+        If ``total`` is not set, it's a good idea to set this to 0 to account
+        for unexpected edge cases and avoid infinite retry loops.
+
+    :param Collection allowed_methods:
+        Set of uppercased HTTP method verbs that we should retry on.
+
+        By default, we only retry on methods which are considered to be
+        idempotent (multiple requests with the same parameters end with the
+        same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`.
+
+        Set to a ``None`` value to retry on any verb.
+
+    :param Collection status_forcelist:
+        A set of integer HTTP status codes that we should force a retry on.
+        A retry is initiated if the request method is in ``allowed_methods``
+        and the response status code is in ``status_forcelist``.
+
+        By default, this is disabled with ``None``.
+
+    :param float backoff_factor:
+        A backoff factor to apply between attempts after the second try
+        (most errors are resolved immediately by a second try without a
+        delay). urllib3 will sleep for::
+
+            {backoff factor} * (2 ** ({number of previous retries}))
+
+        seconds. If `backoff_jitter` is non-zero, this sleep is extended by::
+
+            random.uniform(0, {backoff jitter})
+
+        seconds. For example, if the backoff_factor is 0.1, then :func:`Retry.sleep` will
+        sleep for [0.0s, 0.2s, 0.4s, 0.8s, ...] between retries. No backoff will ever
+        be longer than `backoff_max`.
+
+        By default, backoff is disabled (factor set to 0).
+
+    :param float backoff_max:
+        The maximum backoff time (in seconds) between retry attempts.
+        This value caps the computed backoff from `backoff_factor`.
+
+    :param float backoff_jitter:
+        Random jitter amount (in seconds) added to the computed backoff.
+        Jitter is sampled uniformly from `0` to `backoff_jitter`.
+
+    :param bool raise_on_redirect: Whether, if the number of redirects is
+        exhausted, to raise a MaxRetryError, or to return a response with a
+        response code in the 3xx range.
+
+    :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
+        whether we should raise an exception, or return a response,
+        if status falls in ``status_forcelist`` range and retries have
+        been exhausted.
+
+    :param tuple history: The history of the request encountered during
+        each call to :meth:`~Retry.increment`. The list is in the order
+        the requests occurred. Each list item is of class :class:`RequestHistory`.
+
+    :param bool respect_retry_after_header:
+        Whether to respect Retry-After header on status codes defined as
+        :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
+
+    :param Collection remove_headers_on_redirect:
+        Sequence of headers to remove from the request when a response
+        indicating a redirect is returned before firing off the redirected
+        request.
+
+    :param int retry_after_max: Number of seconds to allow as the maximum for
+        Retry-After headers. Defaults to :attr:`Retry.DEFAULT_RETRY_AFTER_MAX`.
+        Any Retry-After headers larger than this value will be limited to this
+        value.
+    """
+
+    #: Default methods to be used for ``allowed_methods``
+    DEFAULT_ALLOWED_METHODS = frozenset(
+        ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"]
+    )
+
+    #: Default status codes that trigger a retry when a Retry-After header is
+    #: present and ``respect_retry_after_header`` is enabled.
+    RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
+
+    #: Default headers to be used for ``remove_headers_on_redirect``
+    DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(
+        ["Cookie", "Authorization", "Proxy-Authorization"]
+    )
+
+    #: Default maximum backoff time.
+    DEFAULT_BACKOFF_MAX = 120
+
+    # This is undocumented in the RFC. Setting to 6 hours matches other popular libraries.
+    #: Default maximum allowed value for Retry-After headers in seconds
+    DEFAULT_RETRY_AFTER_MAX: typing.Final[int] = 21600
+
+    # Backward compatibility; assigned outside of the class.
+    DEFAULT: typing.ClassVar[Retry]
+
+    def __init__(
+        self,
+        total: bool | int | None = 10,
+        connect: int | None = None,
+        read: int | None = None,
+        redirect: bool | int | None = None,
+        status: int | None = None,
+        other: int | None = None,
+        allowed_methods: typing.Collection[str] | None = DEFAULT_ALLOWED_METHODS,
+        status_forcelist: typing.Collection[int] | None = None,
+        backoff_factor: float = 0,
+        backoff_max: float = DEFAULT_BACKOFF_MAX,
+        raise_on_redirect: bool = True,
+        raise_on_status: bool = True,
+        history: tuple[RequestHistory, ...] | None = None,
+        respect_retry_after_header: bool = True,
+        remove_headers_on_redirect: typing.Collection[
+            str
+        ] = DEFAULT_REMOVE_HEADERS_ON_REDIRECT,
+        backoff_jitter: float = 0.0,
+        retry_after_max: int = DEFAULT_RETRY_AFTER_MAX,
+    ) -> None:
+        self.total = total
+        self.connect = connect
+        self.read = read
+        self.status = status
+        self.other = other
+
+        if redirect is False or total is False:
+            redirect = 0
+            raise_on_redirect = False
+
+        self.redirect = redirect
+        self.status_forcelist = status_forcelist or set()
+        if not allowed_methods and isinstance(allowed_methods, Collection):
+            warnings.warn(
+                "Using an empty collection for 'allowed_methods' option to "
+                "retry on any verb is deprecated and will skip retries for "
+                "all verbs in urllib3 v3.0. Instead use "
+                "Retry(..., allowed_methods=None).",
+                FutureWarning,
+                stacklevel=2,
+            )
+        self.allowed_methods = allowed_methods
+        self.backoff_factor = backoff_factor
+        self.backoff_max = backoff_max
+        self.retry_after_max = retry_after_max
+        self.raise_on_redirect = raise_on_redirect
+        self.raise_on_status = raise_on_status
+        self.history = history or ()
+        self.respect_retry_after_header = respect_retry_after_header
+        self.remove_headers_on_redirect = frozenset(
+            h.lower() for h in remove_headers_on_redirect
+        )
+        self.backoff_jitter = backoff_jitter
+
+    def new(self, **kw: typing.Any) -> Self:
+        params = dict(
+            total=self.total,
+            connect=self.connect,
+            read=self.read,
+            redirect=self.redirect,
+            status=self.status,
+            other=self.other,
+            allowed_methods=self.allowed_methods,
+            status_forcelist=self.status_forcelist,
+            backoff_factor=self.backoff_factor,
+            backoff_max=self.backoff_max,
+            retry_after_max=self.retry_after_max,
+            raise_on_redirect=self.raise_on_redirect,
+            raise_on_status=self.raise_on_status,
+            history=self.history,
+            remove_headers_on_redirect=self.remove_headers_on_redirect,
+            respect_retry_after_header=self.respect_retry_after_header,
+            backoff_jitter=self.backoff_jitter,
+        )
+
+        params.update(kw)
+        return type(self)(**params)  # type: ignore[arg-type]
+
+    @classmethod
+    def from_int(
+        cls,
+        retries: Retry | bool | int | None,
+        redirect: bool | int | None = True,
+        default: Retry | bool | int | None = None,
+    ) -> Retry:
+        """Backwards-compatibility for the old retries format."""
+        if retries is None:
+            retries = default if default is not None else cls.DEFAULT
+
+        if isinstance(retries, Retry):
+            return retries
+
+        redirect = bool(redirect) and None
+        new_retries = cls(retries, redirect=redirect)
+        log.debug("Converted retries value: %r -> %r", retries, new_retries)
+        return new_retries
+
+    def get_backoff_time(self) -> float:
+        """Formula for computing the current backoff
+
+        :rtype: float
+        """
+        # We want to consider only the last consecutive errors sequence (Ignore redirects).
+        consecutive_errors_len = len(
+            list(
+                takewhile(lambda x: x.redirect_location is None, reversed(self.history))
+            )
+        )
+        if consecutive_errors_len <= 1:
+            return 0
+
+        backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
+        if self.backoff_jitter != 0.0:
+            backoff_value += random.random() * self.backoff_jitter
+        return float(max(0, min(self.backoff_max, backoff_value)))
+
+    def parse_retry_after(self, retry_after: str) -> float:
+        seconds: float
+        # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4
+        if re.match(r"^\s*[0-9]+\s*$", retry_after):
+            seconds = int(retry_after)
+        else:
+            retry_date_tuple = email.utils.parsedate_tz(retry_after)
+            if retry_date_tuple is None:
+                raise InvalidHeader(f"Invalid Retry-After header: {retry_after}")
+
+            retry_date = email.utils.mktime_tz(retry_date_tuple)
+            seconds = retry_date - time.time()
+
+        seconds = max(seconds, 0)
+
+        # Check the seconds do not exceed the specified maximum
+        if seconds > self.retry_after_max:
+            seconds = self.retry_after_max
+
+        return seconds
+
+    def get_retry_after(self, response: BaseHTTPResponse) -> float | None:
+        """Get the value of Retry-After in seconds."""
+
+        retry_after = response.headers.get("Retry-After")
+
+        if retry_after is None:
+            return None
+
+        return self.parse_retry_after(retry_after)
+
+    def sleep_for_retry(self, response: BaseHTTPResponse) -> bool:
+        retry_after = self.get_retry_after(response)
+        if retry_after:
+            time.sleep(retry_after)
+            return True
+
+        return False
+
+    def _sleep_backoff(self) -> None:
+        backoff = self.get_backoff_time()
+        if backoff <= 0:
+            return
+        time.sleep(backoff)
+
+    def sleep(self, response: BaseHTTPResponse | None = None) -> None:
+        """Sleep between retry attempts.
+
+        This method will respect a server's ``Retry-After`` response header
+        and sleep the duration of the time requested. If that is not present, it
+        will use an exponential backoff. By default, the backoff factor is 0 and
+        this method will return immediately.
+        """
+
+        if self.respect_retry_after_header and response:
+            slept = self.sleep_for_retry(response)
+            if slept:
+                return
+
+        self._sleep_backoff()
+
+    def _is_connection_error(self, err: Exception) -> bool:
+        """Errors when we're fairly sure that the server did not receive the
+        request, so it should be safe to retry.
+        """
+        if isinstance(err, ProxyError):
+            err = err.original_error
+        return isinstance(err, ConnectTimeoutError)
+
+    def _is_read_error(self, err: Exception) -> bool:
+        """Errors that occur after the request has been started, so we should
+        assume that the server began processing it.
+        """
+        return isinstance(err, (ReadTimeoutError, ProtocolError))
+
+    def _is_method_retryable(self, method: str) -> bool:
+        """Checks if a given HTTP method should be retried upon, depending if
+        it is included in the allowed_methods
+        """
+        if self.allowed_methods and method.upper() not in self.allowed_methods:
+            return False
+        return True
+
+    def is_retry(
+        self, method: str, status_code: int, has_retry_after: bool = False
+    ) -> bool:
+        """Is this method/status code retryable? (Based on allowlists and control
+        variables such as the number of total retries to allow, whether to
+        respect the Retry-After header, whether this header is present, and
+        whether the returned status code is on the list of status codes to
+        be retried upon on the presence of the aforementioned header)
+        """
+        if not self._is_method_retryable(method):
+            return False
+
+        if self.status_forcelist and status_code in self.status_forcelist:
+            return True
+
+        return bool(
+            self.total
+            and self.respect_retry_after_header
+            and has_retry_after
+            and (status_code in self.RETRY_AFTER_STATUS_CODES)
+        )
+
+    def is_exhausted(self) -> bool:
+        """Are we out of retries?"""
+        retry_counts = [
+            x
+            for x in (
+                self.total,
+                self.connect,
+                self.read,
+                self.redirect,
+                self.status,
+                self.other,
+            )
+            if x
+        ]
+        if not retry_counts:
+            return False
+
+        return min(retry_counts) < 0
+
+    def increment(
+        self,
+        method: str | None = None,
+        url: str | None = None,
+        response: BaseHTTPResponse | None = None,
+        error: Exception | None = None,
+        _pool: ConnectionPool | None = None,
+        _stacktrace: TracebackType | None = None,
+    ) -> Self:
+        """Return a new Retry object with incremented retry counters.
+
+        :param response: A response object, or None, if the server did not
+            return a response.
+        :type response: :class:`~urllib3.response.BaseHTTPResponse`
+        :param Exception error: An error encountered during the request, or
+            None if the response was received successfully.
+
+        :return: A new ``Retry`` object.
+        """
+        if self.total is False and error:
+            # Disabled, indicate to re-raise the error.
+            raise reraise(type(error), error, _stacktrace)
+
+        total = self.total
+        if total is not None:
+            total -= 1
+
+        connect = self.connect
+        read = self.read
+        redirect = self.redirect
+        status_count = self.status
+        other = self.other
+        cause = "unknown"
+        status = None
+        redirect_location = None
+
+        if error and self._is_connection_error(error):
+            # Connect retry?
+            if connect is False:
+                raise reraise(type(error), error, _stacktrace)
+            elif connect is not None:
+                connect -= 1
+
+        elif error and self._is_read_error(error):
+            # Read retry?
+            if read is False or method is None or not self._is_method_retryable(method):
+                raise reraise(type(error), error, _stacktrace)
+            elif read is not None:
+                read -= 1
+
+        elif error:
+            # Other retry?
+            if other is not None:
+                other -= 1
+
+        elif response and response.get_redirect_location():
+            # Redirect retry?
+            if redirect is not None:
+                redirect -= 1
+            cause = "too many redirects"
+            response_redirect_location = response.get_redirect_location()
+            if response_redirect_location:
+                redirect_location = response_redirect_location
+            status = response.status
+
+        else:
+            # Incrementing because of a server error like a 500 in
+            # status_forcelist and the given method is in the allowed_methods
+            cause = ResponseError.GENERIC_ERROR
+            if response and response.status:
+                if status_count is not None:
+                    status_count -= 1
+                cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status)
+                status = response.status
+
+        history = self.history + (
+            RequestHistory(method, url, error, status, redirect_location),
+        )
+
+        new_retry = self.new(
+            total=total,
+            connect=connect,
+            read=read,
+            redirect=redirect,
+            status=status_count,
+            other=other,
+            history=history,
+        )
+
+        if new_retry.is_exhausted():
+            reason = error or ResponseError(cause)
+            raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
+
+        log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
+
+        return new_retry
+
+    def __repr__(self) -> str:
+        return (
+            f"{type(self).__name__}(total={self.total}, connect={self.connect}, "
+            f"read={self.read}, redirect={self.redirect}, status={self.status})"
+        )
+
+
+# For backwards compatibility (equivalent to pre-v1.9):
+Retry.DEFAULT = Retry(3)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py
new file mode 100644
index 00000000000..f6445a41dae
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py
@@ -0,0 +1,481 @@
+from __future__ import annotations
+
+import hashlib
+import hmac
+import os
+import socket
+import sys
+import typing
+import warnings
+from binascii import Error as BinasciiError
+from binascii import unhexlify
+
+from ..exceptions import ProxySchemeUnsupported, SSLError
+from .url import _BRACELESS_IPV6_ADDRZ_RE, _IPV4_RE
+
+SSLContext = None
+SSLTransport = None
+HAS_NEVER_CHECK_COMMON_NAME = False
+IS_PYOPENSSL = False
+ALPN_PROTOCOLS = ["http/1.1"]
+
+_TYPE_VERSION_INFO = tuple[int, int, int, str, int]
+
+# Maps the length of a digest to a possible hash function producing this digest
+HASHFUNC_MAP = {
+    length: getattr(hashlib, algorithm, None)
+    for length, algorithm in ((32, "md5"), (40, "sha1"), (64, "sha256"))
+}
+
+
+def _is_has_never_check_common_name_reliable(
+    openssl_version: str,
+) -> bool:
+    # As of May 2023, all released versions of LibreSSL fail to reject certificates with
+    # only common names, see https://github.com/urllib3/urllib3/pull/3024
+    is_openssl = openssl_version.startswith("OpenSSL ")
+
+    return is_openssl
+
+
+if typing.TYPE_CHECKING:
+    from ssl import VerifyMode
+    from typing import TypedDict
+
+    from .ssltransport import SSLTransport as SSLTransportType
+
+    class _TYPE_PEER_CERT_RET_DICT(TypedDict, total=False):
+        subjectAltName: tuple[tuple[str, str], ...]
+        subject: tuple[tuple[tuple[str, str], ...], ...]
+        serialNumber: str
+
+
+# Mapping from 'ssl.PROTOCOL_TLSX' to 'TLSVersion.X'
+_SSL_VERSION_TO_TLS_VERSION: dict[int, int] = {}
+
+try:  # Do we have ssl at all?
+    import ssl
+    from ssl import (  # type: ignore[assignment]
+        CERT_REQUIRED,
+        HAS_NEVER_CHECK_COMMON_NAME,
+        OP_NO_COMPRESSION,
+        OP_NO_TICKET,
+        OPENSSL_VERSION,
+        PROTOCOL_TLS,
+        PROTOCOL_TLS_CLIENT,
+        VERIFY_X509_PARTIAL_CHAIN,
+        VERIFY_X509_STRICT,
+        OP_NO_SSLv2,
+        OP_NO_SSLv3,
+        SSLContext,
+        TLSVersion,
+    )
+
+    PROTOCOL_SSLv23 = PROTOCOL_TLS
+
+    # Setting SSLContext.hostname_checks_common_name = False didn't work with
+    # LibreSSL, check details in the used function.
+    if HAS_NEVER_CHECK_COMMON_NAME and not _is_has_never_check_common_name_reliable(
+        OPENSSL_VERSION,
+    ):  # Defensive:
+        HAS_NEVER_CHECK_COMMON_NAME = False
+
+    # Need to be careful here in case old TLS versions get
+    # removed in future 'ssl' module implementations.
+    for attr in ("TLSv1", "TLSv1_1", "TLSv1_2"):
+        try:
+            _SSL_VERSION_TO_TLS_VERSION[getattr(ssl, f"PROTOCOL_{attr}")] = getattr(
+                TLSVersion, attr
+            )
+        except AttributeError:  # Defensive:
+            continue
+
+    from .ssltransport import SSLTransport  # type: ignore[assignment]
+except ImportError:
+    OP_NO_COMPRESSION = 0x20000  # type: ignore[assignment,misc]
+    OP_NO_TICKET = 0x4000  # type: ignore[assignment,misc]
+    OP_NO_SSLv2 = 0x1000000  # type: ignore[assignment,misc]
+    OP_NO_SSLv3 = 0x2000000  # type: ignore[assignment,misc]
+    PROTOCOL_SSLv23 = PROTOCOL_TLS = 2  # type: ignore[assignment,misc]
+    PROTOCOL_TLS_CLIENT = 16  # type: ignore[assignment,misc]
+    VERIFY_X509_PARTIAL_CHAIN = 0x80000  # type: ignore[assignment,misc]
+    VERIFY_X509_STRICT = 0x20  # type: ignore[assignment,misc]
+
+
+_TYPE_PEER_CERT_RET = typing.Union["_TYPE_PEER_CERT_RET_DICT", bytes, None]
+
+
+def assert_fingerprint(cert: bytes | None, fingerprint: str) -> None:
+    """
+    Checks if given fingerprint matches the supplied certificate.
+
+    :param cert:
+        Certificate as bytes object.
+    :param fingerprint:
+        Fingerprint as string of hexdigits, can be interspersed by colons.
+    """
+
+    if cert is None:
+        raise SSLError("No certificate for the peer.")
+
+    fingerprint = fingerprint.replace(":", "").lower()
+    digest_length = len(fingerprint)
+    if digest_length not in HASHFUNC_MAP:
+        raise SSLError(f"Fingerprint of invalid length: {fingerprint}")
+    hashfunc = HASHFUNC_MAP.get(digest_length)
+    if hashfunc is None:
+        raise SSLError(
+            f"Hash function implementation unavailable for fingerprint length: {digest_length}"
+        )
+
+    # We need encode() here for py32; works on py2 and p33.
+    try:
+        fingerprint_bytes = unhexlify(fingerprint.encode())
+    except BinasciiError as e:
+        raise SSLError(e) from e
+
+    cert_digest = hashfunc(cert).digest()
+
+    if not hmac.compare_digest(cert_digest, fingerprint_bytes):
+        raise SSLError(
+            f'Fingerprints did not match. Expected "{fingerprint}", got "{cert_digest.hex()}"'
+        )
+
+
+def resolve_cert_reqs(candidate: None | int | str) -> VerifyMode:
+    """
+    Resolves the argument to a numeric constant, which can be passed to
+    the wrap_socket function/method from the ssl module.
+    Defaults to :data:`ssl.CERT_REQUIRED`.
+    If given a string it is assumed to be the name of the constant in the
+    :mod:`ssl` module or its abbreviation.
+    (So you can specify `REQUIRED` instead of `CERT_REQUIRED`.
+    If it's neither `None` nor a string we assume it is already the numeric
+    constant which can directly be passed to wrap_socket.
+    """
+    if candidate is None:
+        return CERT_REQUIRED
+
+    if isinstance(candidate, str):
+        res = getattr(ssl, candidate, None)
+        if res is None:
+            res = getattr(ssl, "CERT_" + candidate)
+        return res  # type: ignore[no-any-return]
+
+    return candidate  # type: ignore[return-value]
+
+
+def resolve_ssl_version(candidate: None | int | str) -> int:
+    """
+    like resolve_cert_reqs
+    """
+    if candidate is None:
+        return PROTOCOL_TLS
+
+    if isinstance(candidate, str):
+        res = getattr(ssl, candidate, None)
+        if res is None:
+            res = getattr(ssl, "PROTOCOL_" + candidate)
+        return typing.cast(int, res)
+
+    return candidate
+
+
+def create_urllib3_context(
+    ssl_version: int | None = None,
+    cert_reqs: int | None = None,
+    options: int | None = None,
+    ciphers: str | None = None,
+    ssl_minimum_version: int | None = None,
+    ssl_maximum_version: int | None = None,
+    verify_flags: int | None = None,
+) -> ssl.SSLContext:
+    """Creates and configures an :class:`ssl.SSLContext` instance for use with urllib3.
+
+    :param ssl_version:
+        The desired protocol version to use. This will default to
+        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
+        the server and your installation of OpenSSL support.
+
+        This parameter is deprecated instead use 'ssl_minimum_version'.
+    :param ssl_minimum_version:
+        The minimum version of TLS to be used. Use the 'ssl.TLSVersion' enum for specifying the value.
+    :param ssl_maximum_version:
+        The maximum version of TLS to be used. Use the 'ssl.TLSVersion' enum for specifying the value.
+        Not recommended to set to anything other than 'ssl.TLSVersion.MAXIMUM_SUPPORTED' which is the
+        default value.
+    :param cert_reqs:
+        Whether to require the certificate verification. This defaults to
+        ``ssl.CERT_REQUIRED``.
+    :param options:
+        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
+        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
+    :param ciphers:
+        Which cipher suites to allow the server to select. Defaults to either system configured
+        ciphers if OpenSSL 1.1.1+, otherwise uses a secure default set of ciphers.
+    :param verify_flags:
+        The flags for certificate verification operations. These default to
+        ``ssl.VERIFY_X509_PARTIAL_CHAIN`` and ``ssl.VERIFY_X509_STRICT`` for Python 3.13+.
+    :returns:
+        Constructed SSLContext object with specified options
+    :rtype: SSLContext
+    """
+    if SSLContext is None:
+        raise TypeError("Can't create an SSLContext object without an ssl module")
+
+    # This means 'ssl_version' was specified as an exact value.
+    if ssl_version not in (None, PROTOCOL_TLS, PROTOCOL_TLS_CLIENT):
+        # Disallow setting 'ssl_version' and 'ssl_minimum|maximum_version'
+        # to avoid conflicts.
+        if ssl_minimum_version is not None or ssl_maximum_version is not None:
+            raise ValueError(
+                "Can't specify both 'ssl_version' and either "
+                "'ssl_minimum_version' or 'ssl_maximum_version'"
+            )
+
+        # 'ssl_version' is deprecated and will be removed in the future.
+        else:
+            # Use 'ssl_minimum_version' and 'ssl_maximum_version' instead.
+            ssl_minimum_version = _SSL_VERSION_TO_TLS_VERSION.get(
+                ssl_version, TLSVersion.MINIMUM_SUPPORTED
+            )
+            ssl_maximum_version = _SSL_VERSION_TO_TLS_VERSION.get(
+                ssl_version, TLSVersion.MAXIMUM_SUPPORTED
+            )
+
+            # This warning message is pushing users to use 'ssl_minimum_version'
+            # instead of both min/max. Best practice is to only set the minimum version and
+            # keep the maximum version to be it's default value: 'TLSVersion.MAXIMUM_SUPPORTED'
+            warnings.warn(
+                "'ssl_version' option is deprecated and will be "
+                "removed in urllib3 v3.0. Instead use 'ssl_minimum_version'",
+                category=FutureWarning,
+                stacklevel=2,
+            )
+
+    context = SSLContext(PROTOCOL_TLS_CLIENT)
+    if ssl_minimum_version is not None:
+        context.minimum_version = ssl_minimum_version
+    else:  # pyOpenSSL defaults to 'MINIMUM_SUPPORTED' so explicitly set TLSv1.2 here
+        context.minimum_version = TLSVersion.TLSv1_2
+
+    if ssl_maximum_version is not None:
+        context.maximum_version = ssl_maximum_version
+
+    # Unless we're given ciphers defer to either system ciphers in
+    # the case of OpenSSL 1.1.1+ or use our own secure default ciphers.
+    if ciphers:
+        context.set_ciphers(ciphers)
+
+    # Setting the default here, as we may have no ssl module on import
+    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
+
+    if options is None:
+        options = 0
+        # SSLv2 is easily broken and is considered harmful and dangerous
+        options |= OP_NO_SSLv2
+        # SSLv3 has several problems and is now dangerous
+        options |= OP_NO_SSLv3
+        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
+        # (issue #309)
+        options |= OP_NO_COMPRESSION
+        # TLSv1.2 only. Unless set explicitly, do not request tickets.
+        # This may save some bandwidth on wire, and although the ticket is encrypted,
+        # there is a risk associated with it being on wire,
+        # if the server is not rotating its ticketing keys properly.
+        options |= OP_NO_TICKET
+
+    context.options |= options
+
+    if verify_flags is None:
+        verify_flags = 0
+        # In Python 3.13+ ssl.create_default_context() sets VERIFY_X509_PARTIAL_CHAIN
+        # and VERIFY_X509_STRICT so we do the same
+        if sys.version_info >= (3, 13):
+            verify_flags |= VERIFY_X509_PARTIAL_CHAIN
+            verify_flags |= VERIFY_X509_STRICT
+
+    context.verify_flags |= verify_flags
+
+    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
+    # necessary for conditional client cert authentication with TLS 1.3.
+    # The attribute is None for OpenSSL <= 1.1.0 or does not exist when using
+    # an SSLContext created by pyOpenSSL.
+    if getattr(context, "post_handshake_auth", None) is not None:
+        context.post_handshake_auth = True
+
+    # The order of the below lines setting verify_mode and check_hostname
+    # matter due to safe-guards SSLContext has to prevent an SSLContext with
+    # check_hostname=True, verify_mode=NONE/OPTIONAL.
+    # We always set 'check_hostname=False' for pyOpenSSL so we rely on our own
+    # 'ssl.match_hostname()' implementation.
+    if cert_reqs == ssl.CERT_REQUIRED and not IS_PYOPENSSL:
+        context.verify_mode = cert_reqs
+        context.check_hostname = True
+    else:
+        context.check_hostname = False
+        context.verify_mode = cert_reqs
+
+    context.hostname_checks_common_name = False
+
+    if "SSLKEYLOGFILE" in os.environ:
+        sslkeylogfile = os.path.expandvars(os.environ.get("SSLKEYLOGFILE"))
+    else:
+        sslkeylogfile = None
+    if sslkeylogfile:
+        context.keylog_filename = sslkeylogfile
+
+    return context
+
+
+@typing.overload
+def ssl_wrap_socket(
+    sock: socket.socket,
+    keyfile: str | None = ...,
+    certfile: str | None = ...,
+    cert_reqs: int | None = ...,
+    ca_certs: str | None = ...,
+    server_hostname: str | None = ...,
+    ssl_version: int | None = ...,
+    ciphers: str | None = ...,
+    ssl_context: ssl.SSLContext | None = ...,
+    ca_cert_dir: str | None = ...,
+    key_password: str | None = ...,
+    ca_cert_data: None | str | bytes = ...,
+    tls_in_tls: typing.Literal[False] = ...,
+) -> ssl.SSLSocket: ...
+
+
+@typing.overload
+def ssl_wrap_socket(
+    sock: socket.socket,
+    keyfile: str | None = ...,
+    certfile: str | None = ...,
+    cert_reqs: int | None = ...,
+    ca_certs: str | None = ...,
+    server_hostname: str | None = ...,
+    ssl_version: int | None = ...,
+    ciphers: str | None = ...,
+    ssl_context: ssl.SSLContext | None = ...,
+    ca_cert_dir: str | None = ...,
+    key_password: str | None = ...,
+    ca_cert_data: None | str | bytes = ...,
+    tls_in_tls: bool = ...,
+) -> ssl.SSLSocket | SSLTransportType: ...
+
+
+def ssl_wrap_socket(
+    sock: socket.socket,
+    keyfile: str | None = None,
+    certfile: str | None = None,
+    cert_reqs: int | None = None,
+    ca_certs: str | None = None,
+    server_hostname: str | None = None,
+    ssl_version: int | None = None,
+    ciphers: str | None = None,
+    ssl_context: ssl.SSLContext | None = None,
+    ca_cert_dir: str | None = None,
+    key_password: str | None = None,
+    ca_cert_data: None | str | bytes = None,
+    tls_in_tls: bool = False,
+) -> ssl.SSLSocket | SSLTransportType:
+    """
+    All arguments except for server_hostname, ssl_context, tls_in_tls, ca_cert_data and
+    ca_cert_dir have the same meaning as they do when using
+    :func:`ssl.create_default_context`, :meth:`ssl.SSLContext.load_cert_chain`,
+    :meth:`ssl.SSLContext.set_ciphers` and :meth:`ssl.SSLContext.wrap_socket`.
+
+    :param server_hostname:
+        When SNI is supported, the expected hostname of the certificate
+    :param ssl_context:
+        A pre-made :class:`SSLContext` object. If none is provided, one will
+        be created using :func:`create_urllib3_context`.
+    :param ciphers:
+        A string of ciphers we wish the client to support.
+    :param ca_cert_dir:
+        A directory containing CA certificates in multiple separate files, as
+        supported by OpenSSL's -CApath flag or the capath argument to
+        SSLContext.load_verify_locations().
+    :param key_password:
+        Optional password if the keyfile is encrypted.
+    :param ca_cert_data:
+        Optional string containing CA certificates in PEM format suitable for
+        passing as the cadata parameter to SSLContext.load_verify_locations()
+    :param tls_in_tls:
+        Use SSLTransport to wrap the existing socket.
+    """
+    context = ssl_context
+    if context is None:
+        # Note: This branch of code and all the variables in it are only used in tests.
+        # We should consider deprecating and removing this code.
+        context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers)
+
+    if ca_certs or ca_cert_dir or ca_cert_data:
+        try:
+            context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data)
+        except OSError as e:
+            raise SSLError(e) from e
+
+    elif ssl_context is None and hasattr(context, "load_default_certs"):
+        # try to load OS default certs; works well on Windows.
+        context.load_default_certs()
+
+    # Attempt to detect if we get the goofy behavior of the
+    # keyfile being encrypted and OpenSSL asking for the
+    # passphrase via the terminal and instead error out.
+    if keyfile and key_password is None and _is_key_file_encrypted(keyfile):
+        raise SSLError("Client private key is encrypted, password is required")
+
+    if certfile:
+        if key_password is None:
+            context.load_cert_chain(certfile, keyfile)
+        else:
+            context.load_cert_chain(certfile, keyfile, key_password)
+
+    context.set_alpn_protocols(ALPN_PROTOCOLS)
+
+    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
+    return ssl_sock
+
+
+def is_ipaddress(hostname: str | bytes) -> bool:
+    """Detects whether the hostname given is an IPv4 or IPv6 address.
+    Also detects IPv6 addresses with Zone IDs.
+
+    :param str hostname: Hostname to examine.
+    :return: True if the hostname is an IP address, False otherwise.
+    """
+    if isinstance(hostname, bytes):
+        # IDN A-label bytes are ASCII compatible.
+        hostname = hostname.decode("ascii")
+    return bool(_IPV4_RE.match(hostname) or _BRACELESS_IPV6_ADDRZ_RE.match(hostname))
+
+
+def _is_key_file_encrypted(key_file: str) -> bool:
+    """Detects if a key file is encrypted or not."""
+    with open(key_file) as f:
+        for line in f:
+            # Look for Proc-Type: 4,ENCRYPTED
+            if "ENCRYPTED" in line:
+                return True
+
+    return False
+
+
+def _ssl_wrap_socket_impl(
+    sock: socket.socket,
+    ssl_context: ssl.SSLContext,
+    tls_in_tls: bool,
+    server_hostname: str | None = None,
+) -> ssl.SSLSocket | SSLTransportType:
+    if tls_in_tls:
+        if not SSLTransport:
+            # Import error, ssl is not available.
+            raise ProxySchemeUnsupported(
+                "TLS in TLS requires support for the 'ssl' module"
+            )
+
+        SSLTransport._validate_ssl_context_for_tls_in_tls(ssl_context)
+        return SSLTransport(sock, ssl_context, server_hostname)
+
+    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py
new file mode 100644
index 00000000000..94994f25ae1
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py
@@ -0,0 +1,153 @@
+"""The match_hostname() function from Python 3.5, essential when using SSL."""
+
+# Note: This file is under the PSF license as the code comes from the python
+# stdlib.   http://docs.python.org/3/license.html
+# It is modified to remove commonName support.
+
+from __future__ import annotations
+
+import ipaddress
+import re
+import typing
+from ipaddress import IPv4Address, IPv6Address
+
+if typing.TYPE_CHECKING:
+    from .ssl_ import _TYPE_PEER_CERT_RET_DICT
+
+__version__ = "3.5.0.1"
+
+
+class CertificateError(ValueError):
+    pass
+
+
+def _dnsname_match(
+    dn: typing.Any, hostname: str, max_wildcards: int = 1
+) -> typing.Match[str] | None | bool:
+    """Matching according to RFC 6125, section 6.4.3
+
+    http://tools.ietf.org/html/rfc6125#section-6.4.3
+    """
+    pats = []
+    if not dn:
+        return False
+
+    # Ported from python3-syntax:
+    # leftmost, *remainder = dn.split(r'.')
+    parts = dn.split(r".")
+    leftmost = parts[0]
+    remainder = parts[1:]
+
+    wildcards = leftmost.count("*")
+    if wildcards > max_wildcards:
+        # Issue #17980: avoid denials of service by refusing more
+        # than one wildcard per fragment.  A survey of established
+        # policy among SSL implementations showed it to be a
+        # reasonable choice.
+        raise CertificateError(
+            "too many wildcards in certificate DNS name: " + repr(dn)
+        )
+
+    # speed up common case w/o wildcards
+    if not wildcards:
+        return bool(dn.lower() == hostname.lower())
+
+    # RFC 6125, section 6.4.3, subitem 1.
+    # The client SHOULD NOT attempt to match a presented identifier in which
+    # the wildcard character comprises a label other than the left-most label.
+    if leftmost == "*":
+        # When '*' is a fragment by itself, it matches a non-empty dotless
+        # fragment.
+        pats.append("[^.]+")
+    elif leftmost.startswith("xn--") or hostname.startswith("xn--"):
+        # RFC 6125, section 6.4.3, subitem 3.
+        # The client SHOULD NOT attempt to match a presented identifier
+        # where the wildcard character is embedded within an A-label or
+        # U-label of an internationalized domain name.
+        pats.append(re.escape(leftmost))
+    else:
+        # Otherwise, '*' matches any dotless string, e.g. www*
+        pats.append(re.escape(leftmost).replace(r"\*", "[^.]*"))
+
+    # add the remaining fragments, ignore any wildcards
+    for frag in remainder:
+        pats.append(re.escape(frag))
+
+    pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE)
+    return pat.match(hostname)
+
+
+def _ipaddress_match(ipname: str, host_ip: IPv4Address | IPv6Address) -> bool:
+    """Exact matching of IP addresses.
+
+    RFC 9110 section 4.3.5: "A reference identity of IP-ID contains the decoded
+    bytes of the IP address. An IP version 4 address is 4 octets, and an IP
+    version 6 address is 16 octets. [...] A reference identity of type IP-ID
+    matches if the address is identical to an iPAddress value of the
+    subjectAltName extension of the certificate."
+    """
+    # OpenSSL may add a trailing newline to a subjectAltName's IP address
+    # Divergence from upstream: ipaddress can't handle byte str
+    ip = ipaddress.ip_address(ipname.rstrip())
+    return bool(ip.packed == host_ip.packed)
+
+
+def match_hostname(
+    cert: _TYPE_PEER_CERT_RET_DICT | None,
+    hostname: str,
+    hostname_checks_common_name: bool = False,
+) -> None:
+    """Verify that *cert* (in decoded format as returned by
+    SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 and RFC 6125
+    rules are followed, but IP addresses are not accepted for *hostname*.
+
+    CertificateError is raised on failure. On success, the function
+    returns nothing.
+    """
+    if not cert:
+        raise ValueError(
+            "empty or no certificate, match_hostname needs a "
+            "SSL socket or SSL context with either "
+            "CERT_OPTIONAL or CERT_REQUIRED"
+        )
+
+    try:
+        host_ip = ipaddress.ip_address(hostname)
+    except ValueError:
+        # Not an IP address (common case)
+        host_ip = None
+    dnsnames = []
+    san: tuple[tuple[str, str], ...] = cert.get("subjectAltName", ())
+    key: str
+    value: str
+    for key, value in san:
+        if key == "DNS":
+            if host_ip is None and _dnsname_match(value, hostname):
+                return
+            dnsnames.append(value)
+        elif key == "IP Address":
+            if host_ip is not None and _ipaddress_match(value, host_ip):
+                return
+            dnsnames.append(value)
+
+    # We only check 'commonName' if it's enabled and we're not verifying
+    # an IP address. IP addresses aren't valid within 'commonName'.
+    if hostname_checks_common_name and host_ip is None and not dnsnames:
+        for sub in cert.get("subject", ()):
+            for key, value in sub:
+                if key == "commonName":
+                    if _dnsname_match(value, hostname):
+                        return
+                    dnsnames.append(
+                        value
+                    )  # Defensive: for older PyPy and OpenSSL versions
+
+    if len(dnsnames) > 1:
+        raise CertificateError(
+            "hostname %r "
+            "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames)))
+        )
+    elif len(dnsnames) == 1:
+        raise CertificateError(f"hostname {hostname!r} doesn't match {dnsnames[0]!r}")
+    else:
+        raise CertificateError("no appropriate subjectAltName fields were found")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py
new file mode 100644
index 00000000000..3e3132f8ca0
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py
@@ -0,0 +1,271 @@
+from __future__ import annotations
+
+import io
+import socket
+import ssl
+import typing
+
+from ..exceptions import ProxySchemeUnsupported
+
+if typing.TYPE_CHECKING:
+    from opentelemetry.agent._vendor.typing_extensions import Self
+
+    from .ssl_ import _TYPE_PEER_CERT_RET, _TYPE_PEER_CERT_RET_DICT
+
+
+_WriteBuffer = typing.Union[bytearray, memoryview]
+_ReturnValue = typing.TypeVar("_ReturnValue")
+
+SSL_BLOCKSIZE = 16384
+
+
+class SSLTransport:
+    """
+    The SSLTransport wraps an existing socket and establishes an SSL connection.
+
+    Contrary to Python's implementation of SSLSocket, it allows you to chain
+    multiple TLS connections together. It's particularly useful if you need to
+    implement TLS within TLS.
+
+    The class supports most of the socket API operations.
+    """
+
+    @staticmethod
+    def _validate_ssl_context_for_tls_in_tls(ssl_context: ssl.SSLContext) -> None:
+        """
+        Raises a ProxySchemeUnsupported if the provided ssl_context can't be used
+        for TLS in TLS.
+
+        The only requirement is that the ssl_context provides the 'wrap_bio'
+        methods.
+        """
+
+        if not hasattr(ssl_context, "wrap_bio"):
+            raise ProxySchemeUnsupported(
+                "TLS in TLS requires SSLContext.wrap_bio() which isn't "
+                "available on non-native SSLContext"
+            )
+
+    def __init__(
+        self,
+        socket: socket.socket,
+        ssl_context: ssl.SSLContext,
+        server_hostname: str | None = None,
+        suppress_ragged_eofs: bool = True,
+    ) -> None:
+        """
+        Create an SSLTransport around socket using the provided ssl_context.
+        """
+        self.incoming = ssl.MemoryBIO()
+        self.outgoing = ssl.MemoryBIO()
+
+        self.suppress_ragged_eofs = suppress_ragged_eofs
+        self.socket = socket
+
+        self.sslobj = ssl_context.wrap_bio(
+            self.incoming, self.outgoing, server_hostname=server_hostname
+        )
+
+        # Perform initial handshake.
+        self._ssl_io_loop(self.sslobj.do_handshake)
+
+    def __enter__(self) -> Self:
+        return self
+
+    def __exit__(self, *_: typing.Any) -> None:
+        self.close()
+
+    def fileno(self) -> int:
+        return self.socket.fileno()
+
+    def read(self, len: int = 1024, buffer: typing.Any | None = None) -> int | bytes:
+        return self._wrap_ssl_read(len, buffer)
+
+    def recv(self, buflen: int = 1024, flags: int = 0) -> int | bytes:
+        if flags != 0:
+            raise ValueError("non-zero flags not allowed in calls to recv")
+        return self._wrap_ssl_read(buflen)
+
+    def recv_into(
+        self,
+        buffer: _WriteBuffer,
+        nbytes: int | None = None,
+        flags: int = 0,
+    ) -> None | int | bytes:
+        if flags != 0:
+            raise ValueError("non-zero flags not allowed in calls to recv_into")
+        if nbytes is None:
+            nbytes = len(buffer)
+        return self.read(nbytes, buffer)
+
+    def sendall(self, data: bytes, flags: int = 0) -> None:
+        if flags != 0:
+            raise ValueError("non-zero flags not allowed in calls to sendall")
+        count = 0
+        with memoryview(data) as view, view.cast("B") as byte_view:
+            amount = len(byte_view)
+            while count < amount:
+                v = self.send(byte_view[count:])
+                count += v
+
+    def send(self, data: bytes, flags: int = 0) -> int:
+        if flags != 0:
+            raise ValueError("non-zero flags not allowed in calls to send")
+        return self._ssl_io_loop(self.sslobj.write, data)
+
+    def makefile(
+        self,
+        mode: str,
+        buffering: int | None = None,
+        *,
+        encoding: str | None = None,
+        errors: str | None = None,
+        newline: str | None = None,
+    ) -> typing.BinaryIO | typing.TextIO | socket.SocketIO:
+        """
+        Python's httpclient uses makefile and buffered io when reading HTTP
+        messages and we need to support it.
+
+        This is unfortunately a copy and paste of socket.py makefile with small
+        changes to point to the socket directly.
+        """
+        if not set(mode) <= {"r", "w", "b"}:
+            raise ValueError(f"invalid mode {mode!r} (only r, w, b allowed)")
+
+        writing = "w" in mode
+        reading = "r" in mode or not writing
+        assert reading or writing
+        binary = "b" in mode
+        rawmode = ""
+        if reading:
+            rawmode += "r"
+        if writing:
+            rawmode += "w"
+        raw = socket.SocketIO(self, rawmode)  # type: ignore[arg-type]
+        self.socket._io_refs += 1  # type: ignore[attr-defined]
+        if buffering is None:
+            buffering = -1
+        if buffering < 0:
+            buffering = io.DEFAULT_BUFFER_SIZE
+        if buffering == 0:
+            if not binary:
+                raise ValueError("unbuffered streams must be binary")
+            return raw
+        buffer: typing.BinaryIO
+        if reading and writing:
+            buffer = io.BufferedRWPair(raw, raw, buffering)  # type: ignore[assignment]
+        elif reading:
+            buffer = io.BufferedReader(raw, buffering)
+        else:
+            assert writing
+            buffer = io.BufferedWriter(raw, buffering)
+        if binary:
+            return buffer
+        text = io.TextIOWrapper(buffer, encoding, errors, newline)
+        text.mode = mode  # type: ignore[misc]
+        return text
+
+    def unwrap(self) -> None:
+        self._ssl_io_loop(self.sslobj.unwrap)
+
+    def close(self) -> None:
+        self.socket.close()
+
+    @typing.overload
+    def getpeercert(
+        self, binary_form: typing.Literal[False] = ...
+    ) -> _TYPE_PEER_CERT_RET_DICT | None: ...
+
+    @typing.overload
+    def getpeercert(self, binary_form: typing.Literal[True]) -> bytes | None: ...
+
+    def getpeercert(self, binary_form: bool = False) -> _TYPE_PEER_CERT_RET:
+        return self.sslobj.getpeercert(binary_form)  # type: ignore[return-value]
+
+    def version(self) -> str | None:
+        return self.sslobj.version()
+
+    def cipher(self) -> tuple[str, str, int] | None:
+        return self.sslobj.cipher()
+
+    def selected_alpn_protocol(self) -> str | None:
+        return self.sslobj.selected_alpn_protocol()
+
+    def shared_ciphers(self) -> list[tuple[str, str, int]] | None:
+        return self.sslobj.shared_ciphers()
+
+    def compression(self) -> str | None:
+        return self.sslobj.compression()
+
+    def settimeout(self, value: float | None) -> None:
+        self.socket.settimeout(value)
+
+    def gettimeout(self) -> float | None:
+        return self.socket.gettimeout()
+
+    def _decref_socketios(self) -> None:
+        self.socket._decref_socketios()  # type: ignore[attr-defined]
+
+    def _wrap_ssl_read(self, len: int, buffer: bytearray | None = None) -> int | bytes:
+        try:
+            return self._ssl_io_loop(self.sslobj.read, len, buffer)
+        except ssl.SSLError as e:
+            if e.errno == ssl.SSL_ERROR_EOF and self.suppress_ragged_eofs:
+                return 0  # eof, return 0.
+            else:
+                raise
+
+    # func is sslobj.do_handshake or sslobj.unwrap
+    @typing.overload
+    def _ssl_io_loop(self, func: typing.Callable[[], None]) -> None: ...
+
+    # func is sslobj.write, arg1 is data
+    @typing.overload
+    def _ssl_io_loop(self, func: typing.Callable[[bytes], int], arg1: bytes) -> int: ...
+
+    # func is sslobj.read, arg1 is len, arg2 is buffer
+    @typing.overload
+    def _ssl_io_loop(
+        self,
+        func: typing.Callable[[int, bytearray | None], bytes],
+        arg1: int,
+        arg2: bytearray | None,
+    ) -> bytes: ...
+
+    def _ssl_io_loop(
+        self,
+        func: typing.Callable[..., _ReturnValue],
+        arg1: None | bytes | int = None,
+        arg2: bytearray | None = None,
+    ) -> _ReturnValue:
+        """Performs an I/O loop between incoming/outgoing and the socket."""
+        should_loop = True
+        ret = None
+
+        while should_loop:
+            errno = None
+            try:
+                if arg1 is None and arg2 is None:
+                    ret = func()
+                elif arg2 is None:
+                    ret = func(arg1)
+                else:
+                    ret = func(arg1, arg2)
+            except ssl.SSLError as e:
+                if e.errno not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
+                    # WANT_READ, and WANT_WRITE are expected, others are not.
+                    raise e
+                errno = e.errno
+
+            buf = self.outgoing.read()
+            self.socket.sendall(buf)
+
+            if errno is None:
+                should_loop = False
+            elif errno == ssl.SSL_ERROR_WANT_READ:
+                buf = self.socket.recv(SSL_BLOCKSIZE)
+                if buf:
+                    self.incoming.write(buf)
+                else:
+                    self.incoming.write_eof()
+        return typing.cast(_ReturnValue, ret)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py
new file mode 100644
index 00000000000..4bb1be11d9c
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py
@@ -0,0 +1,275 @@
+from __future__ import annotations
+
+import time
+import typing
+from enum import Enum
+from socket import getdefaulttimeout
+
+from ..exceptions import TimeoutStateError
+
+if typing.TYPE_CHECKING:
+    from typing import Final
+
+
+class _TYPE_DEFAULT(Enum):
+    # This value should never be passed to socket.settimeout() so for safety we use a -1.
+    # socket.settimout() raises a ValueError for negative values.
+    token = -1
+
+
+_DEFAULT_TIMEOUT: Final[_TYPE_DEFAULT] = _TYPE_DEFAULT.token
+
+_TYPE_TIMEOUT = typing.Optional[typing.Union[float, _TYPE_DEFAULT]]
+
+
+class Timeout:
+    """Timeout configuration.
+
+    Timeouts can be defined as a default for a pool:
+
+    .. code-block:: python
+
+        import urllib3
+
+        timeout = urllib3.util.Timeout(connect=2.0, read=7.0)
+
+        http = urllib3.PoolManager(timeout=timeout)
+
+        resp = http.request("GET", "https://example.com/")
+
+        print(resp.status)
+
+    Or per-request (which overrides the default for the pool):
+
+    .. code-block:: python
+
+       response = http.request("GET", "https://example.com/", timeout=Timeout(10))
+
+    Timeouts can be disabled by setting all the parameters to ``None``:
+
+    .. code-block:: python
+
+       no_timeout = Timeout(connect=None, read=None)
+       response = http.request("GET", "https://example.com/", timeout=no_timeout)
+
+
+    :param total:
+        This combines the connect and read timeouts into one; the read timeout
+        will be set to the time leftover from the connect attempt. In the
+        event that both a connect timeout and a total are specified, or a read
+        timeout and a total are specified, the shorter timeout will be applied.
+
+        Defaults to None.
+
+    :type total: int, float, or None
+
+    :param connect:
+        The maximum amount of time (in seconds) to wait for a connection
+        attempt to a server to succeed. Omitting the parameter will default the
+        connect timeout to the system default, probably `the global default
+        timeout in socket.py
+        `_.
+        None will set an infinite timeout for connection attempts.
+
+    :type connect: int, float, or None
+
+    :param read:
+        The maximum amount of time (in seconds) to wait between consecutive
+        read operations for a response from the server. Omitting the parameter
+        will default the read timeout to the system default, probably `the
+        global default timeout in socket.py
+        `_.
+        None will set an infinite timeout.
+
+    :type read: int, float, or None
+
+    .. note::
+
+        Many factors can affect the total amount of time for urllib3 to return
+        an HTTP response.
+
+        For example, Python's DNS resolver does not obey the timeout specified
+        on the socket. Other factors that can affect total request time include
+        high CPU load, high swap, the program running at a low priority level,
+        or other behaviors.
+
+        In addition, the read and total timeouts only measure the time between
+        read operations on the socket connecting the client and the server,
+        not the total amount of time for the request to return a complete
+        response. For most requests, the timeout is raised because the server
+        has not sent the first byte in the specified time. This is not always
+        the case; if a server streams one byte every fifteen seconds, a timeout
+        of 20 seconds will not trigger, even though the request will take
+        several minutes to complete.
+    """
+
+    #: A sentinel object representing the default timeout value
+    DEFAULT_TIMEOUT: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT
+
+    def __init__(
+        self,
+        total: _TYPE_TIMEOUT = None,
+        connect: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+        read: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
+    ) -> None:
+        self._connect = self._validate_timeout(connect, "connect")
+        self._read = self._validate_timeout(read, "read")
+        self.total = self._validate_timeout(total, "total")
+        self._start_connect: float | None = None
+
+    def __repr__(self) -> str:
+        return f"{type(self).__name__}(connect={self._connect!r}, read={self._read!r}, total={self.total!r})"
+
+    # __str__ provided for backwards compatibility
+    __str__ = __repr__
+
+    @staticmethod
+    def resolve_default_timeout(timeout: _TYPE_TIMEOUT) -> float | None:
+        return getdefaulttimeout() if timeout is _DEFAULT_TIMEOUT else timeout
+
+    @classmethod
+    def _validate_timeout(cls, value: _TYPE_TIMEOUT, name: str) -> _TYPE_TIMEOUT:
+        """Check that a timeout attribute is valid.
+
+        :param value: The timeout value to validate
+        :param name: The name of the timeout attribute to validate. This is
+            used to specify in error messages.
+        :return: The validated and casted version of the given value.
+        :raises ValueError: If it is a numeric value less than or equal to
+            zero, or the type is not an integer, float, or None.
+        """
+        if value is None or value is _DEFAULT_TIMEOUT:
+            return value
+
+        if isinstance(value, bool):
+            raise ValueError(
+                "Timeout cannot be a boolean value. It must "
+                "be an int, float or None."
+            )
+        try:
+            float(value)
+        except (TypeError, ValueError):
+            raise ValueError(
+                "Timeout value %s was %s, but it must be an "
+                "int, float or None." % (name, value)
+            ) from None
+
+        try:
+            if value <= 0:
+                raise ValueError(
+                    "Attempted to set %s timeout to %s, but the "
+                    "timeout cannot be set to a value less "
+                    "than or equal to 0." % (name, value)
+                )
+        except TypeError:
+            raise ValueError(
+                "Timeout value %s was %s, but it must be an "
+                "int, float or None." % (name, value)
+            ) from None
+
+        return value
+
+    @classmethod
+    def from_float(cls, timeout: _TYPE_TIMEOUT) -> Timeout:
+        """Create a new Timeout from a legacy timeout value.
+
+        The timeout value used by httplib.py sets the same timeout on the
+        connect(), and recv() socket requests. This creates a :class:`Timeout`
+        object that sets the individual timeouts to the ``timeout`` value
+        passed to this function.
+
+        :param timeout: The legacy timeout value.
+        :type timeout: integer, float, :attr:`urllib3.util.Timeout.DEFAULT_TIMEOUT`, or None
+        :return: Timeout object
+        :rtype: :class:`Timeout`
+        """
+        return Timeout(read=timeout, connect=timeout)
+
+    def clone(self) -> Timeout:
+        """Create a copy of the timeout object
+
+        Timeout properties are stored per-pool but each request needs a fresh
+        Timeout object to ensure each one has its own start/stop configured.
+
+        :return: a copy of the timeout object
+        :rtype: :class:`Timeout`
+        """
+        # We can't use copy.deepcopy because that will also create a new object
+        # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to
+        # detect the user default.
+        return Timeout(connect=self._connect, read=self._read, total=self.total)
+
+    def start_connect(self) -> float:
+        """Start the timeout clock, used during a connect() attempt
+
+        :raises urllib3.exceptions.TimeoutStateError: if you attempt
+            to start a timer that has been started already.
+        """
+        if self._start_connect is not None:
+            raise TimeoutStateError("Timeout timer has already been started.")
+        self._start_connect = time.monotonic()
+        return self._start_connect
+
+    def get_connect_duration(self) -> float:
+        """Gets the time elapsed since the call to :meth:`start_connect`.
+
+        :return: Elapsed time in seconds.
+        :rtype: float
+        :raises urllib3.exceptions.TimeoutStateError: if you attempt
+            to get duration for a timer that hasn't been started.
+        """
+        if self._start_connect is None:
+            raise TimeoutStateError(
+                "Can't get connect duration for timer that has not started."
+            )
+        return time.monotonic() - self._start_connect
+
+    @property
+    def connect_timeout(self) -> _TYPE_TIMEOUT:
+        """Get the value to use when setting a connection timeout.
+
+        This will be a positive float or integer, the value None
+        (never timeout), or the default system timeout.
+
+        :return: Connect timeout.
+        :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
+        """
+        if self.total is None:
+            return self._connect
+
+        if self._connect is None or self._connect is _DEFAULT_TIMEOUT:
+            return self.total
+
+        return min(self._connect, self.total)  # type: ignore[type-var]
+
+    @property
+    def read_timeout(self) -> float | None:
+        """Get the value for the read timeout.
+
+        This assumes some time has elapsed in the connection timeout and
+        computes the read timeout appropriately.
+
+        If self.total is set, the read timeout is dependent on the amount of
+        time taken by the connect timeout. If the connection time has not been
+        established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be
+        raised.
+
+        :return: Value to use for the read timeout.
+        :rtype: int, float or None
+        :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect`
+            has not yet been called on this object.
+        """
+        if (
+            self.total is not None
+            and self.total is not _DEFAULT_TIMEOUT
+            and self._read is not None
+            and self._read is not _DEFAULT_TIMEOUT
+        ):
+            # In case the connect timeout has not yet been established.
+            if self._start_connect is None:
+                return self._read
+            return max(0, min(self.total - self.get_connect_duration(), self._read))
+        elif self.total is not None and self.total is not _DEFAULT_TIMEOUT:
+            return max(0, self.total - self.get_connect_duration())
+        else:
+            return self.resolve_default_timeout(self._read)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py
new file mode 100644
index 00000000000..c635cddc9d0
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py
@@ -0,0 +1,577 @@
+from __future__ import annotations
+
+import re
+import typing
+from functools import partial
+from urllib.parse import unquote as _unquote
+
+from ..exceptions import LocationParseError
+from .util import to_str
+
+# We only want to normalize urls with an HTTP(S) scheme.
+# urllib3 infers URLs without a scheme (None) to be http.
+_NORMALIZABLE_SCHEMES = ("http", "https", None)
+
+# Almost all of these patterns were derived from the
+# 'rfc3986' module: https://github.com/python-hyper/rfc3986
+_PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}")
+_HOST_PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}|%")
+_SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)")
+_HOST_INVALID_CHAR_RE = re.compile(r"[\x00-\x20\x7f]")
+_URI_RE = re.compile(
+    r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?"
+    r"(?://([^\\/?#]*))?"
+    r"([^?#]*)"
+    r"(?:\?([^#]*))?"
+    r"(?:#(.*))?$",
+    re.UNICODE | re.DOTALL,
+)
+
+_IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}"
+_HEX_PAT = "[0-9A-Fa-f]{1,4}"
+_LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=_HEX_PAT, ipv4=_IPV4_PAT)
+_subs = {"hex": _HEX_PAT, "ls32": _LS32_PAT}
+_variations = [
+    #                            6( h16 ":" ) ls32
+    "(?:%(hex)s:){6}%(ls32)s",
+    #                       "::" 5( h16 ":" ) ls32
+    "::(?:%(hex)s:){5}%(ls32)s",
+    # [               h16 ] "::" 4( h16 ":" ) ls32
+    "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s",
+    # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
+    "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s",
+    # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
+    "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s",
+    # [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
+    "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s",
+    # [ *4( h16 ":" ) h16 ] "::"              ls32
+    "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s",
+    # [ *5( h16 ":" ) h16 ] "::"              h16
+    "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s",
+    # [ *6( h16 ":" ) h16 ] "::"
+    "(?:(?:%(hex)s:){0,6}%(hex)s)?::",
+]
+
+_UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._\-~"
+_IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")"
+_ZONE_ID_PAT = "(?:%25|%)(?:[" + _UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+"
+_IPV6_ADDRZ_PAT = r"\[" + _IPV6_PAT + r"(?:" + _ZONE_ID_PAT + r")?\]"
+_REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*"
+_TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$")
+
+_IPV4_RE = re.compile(
+    r"^(?:0[xX][0-9a-fA-F]+|[0-9]+)(?:\.(?:0[xX][0-9a-fA-F]+|[0-9]+)){0,3}$"
+)
+_IPV6_RE = re.compile("^" + _IPV6_PAT + "$")
+_IPV6_ADDRZ_RE = re.compile("^" + _IPV6_ADDRZ_PAT + "$")
+_BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + _IPV6_ADDRZ_PAT[2:-2] + "$")
+_ZONE_ID_RE = re.compile("(" + _ZONE_ID_PAT + r")\]$")
+
+_HOST_PORT_PAT = ("^(%s|%s|%s)(?::0*?(|0|[1-9][0-9]{0,4}))?$") % (
+    _REG_NAME_PAT,
+    _IPV4_PAT,
+    _IPV6_ADDRZ_PAT,
+)
+_HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL)
+
+_UNRESERVED_CHARS = set(
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~"
+)
+_SUB_DELIM_CHARS = set("!$&'()*+,;=")
+_USERINFO_CHARS = _UNRESERVED_CHARS | _SUB_DELIM_CHARS | {":"}
+_PATH_CHARS = _USERINFO_CHARS | {"@", "/"}
+_QUERY_CHARS = _FRAGMENT_CHARS = _PATH_CHARS | {"?"}
+
+
+class Url(
+    typing.NamedTuple(
+        "Url",
+        [
+            ("scheme", typing.Optional[str]),
+            ("auth", typing.Optional[str]),
+            ("host", typing.Optional[str]),
+            ("port", typing.Optional[int]),
+            ("path", typing.Optional[str]),
+            ("query", typing.Optional[str]),
+            ("fragment", typing.Optional[str]),
+        ],
+    )
+):
+    """
+    Data structure for representing an HTTP URL. Used as a return value for
+    :func:`parse_url`. Both the scheme and host are normalized as they are
+    both case-insensitive according to RFC 3986.
+
+    :param auth: User information as defined in RFC 3986 3.2.1. This
+        component is kept percent-encoded. Use :attr:`auth_decoded` or
+        :attr:`auth_decoded_joined` to get the decoded form.
+    """
+
+    def __new__(  # type: ignore[no-untyped-def]
+        cls,
+        scheme: str | None = None,
+        auth: str | None = None,
+        host: str | None = None,
+        port: int | None = None,
+        path: str | None = None,
+        query: str | None = None,
+        fragment: str | None = None,
+    ):
+        if path and not path.startswith("/"):
+            path = "/" + path
+        if scheme is not None:
+            scheme = scheme.lower()
+        return super().__new__(cls, scheme, auth, host, port, path, query, fragment)
+
+    @property
+    def auth_decoded(self) -> tuple[None, None] | tuple[str, str | None]:
+        """
+        User information with %-escapes decoded as UTF-8, returned as a
+        ``(username, password)`` tuple.
+
+        Both values are ``None`` if ``auth`` is ``None``.
+        ``password`` is ``None`` if not present in the auth component.
+        """
+        if self.auth is None:
+            return None, None
+        username, sep, password = self.auth.partition(":")
+        return (
+            _unquote(username, encoding="utf-8"),
+            _unquote(password, encoding="utf-8") if sep else None,
+        )
+
+    @property
+    def auth_decoded_joined(self) -> str | None:
+        """
+        User information with %-escapes decoded as UTF-8, as a string
+        prepared for encoding into an 'authorization: basic ...' header.
+
+        This property does not choose the encoding used for an
+        'authorization: basic ...' header. Use the ``basic_auth_encoding`` or
+        ``proxy_basic_auth_encoding`` parameters of
+        :func:`urllib3.util.make_headers` when converting the returned string
+        into Basic authentication bytes.
+
+        This is a convenience property that joins the username and
+        password with a colon, if both are present.
+        If only the username is present, a trailing colon is still
+        appended.
+        If ``auth`` is ``None``, this returns ``None``.
+        """
+        username, password = self.auth_decoded
+        if username is None:
+            return None
+        return f"{username}:{password or ''}"
+
+    @property
+    def hostname(self) -> str | None:
+        """For backwards-compatibility with urlparse. We're nice like that."""
+        return self.host
+
+    @property
+    def request_uri(self) -> str:
+        """Absolute path including the query string."""
+        uri = self.path or "/"
+
+        if self.query is not None:
+            uri += "?" + self.query
+
+        return uri
+
+    @property
+    def authority(self) -> str | None:
+        """
+        Authority component as defined in RFC 3986 3.2.
+        This includes userinfo (auth), host and port.
+
+        i.e.
+            userinfo@host:port
+        """
+        userinfo = self.auth
+        netloc = self.netloc
+        if netloc is None or userinfo is None:
+            return netloc
+        else:
+            return f"{userinfo}@{netloc}"
+
+    @property
+    def netloc(self) -> str | None:
+        """
+        Network location including host and port.
+
+        If you need the equivalent of urllib.parse's ``netloc``,
+        use the ``authority`` property instead.
+        """
+        if self.host is None:
+            return None
+        if self.port is not None:
+            return f"{self.host}:{self.port}"
+        return self.host
+
+    @property
+    def url(self) -> str:
+        """
+        Convert self into a url
+
+        This function should more or less round-trip with :func:`.parse_url`. The
+        returned url may not be exactly the same as the url inputted to
+        :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls
+        with a blank port will have : removed).
+
+        Example:
+
+        .. code-block:: python
+
+            import urllib3
+
+            U = urllib3.util.parse_url("https://google.com/mail/")
+
+            print(U.url)
+            # "https://google.com/mail/"
+
+            print( urllib3.util.Url("https", "username:password",
+                                    "host.com", 80, "/path", "query", "fragment"
+                                    ).url
+                )
+            # "https://username:password@host.com:80/path?query#fragment"
+        """
+        scheme, auth, host, port, path, query, fragment = self
+        url = ""
+
+        # We use "is not None" we want things to happen with empty strings (or 0 port)
+        if scheme is not None:
+            url += scheme + "://"
+        if auth is not None:
+            url += auth + "@"
+        if host is not None:
+            url += host
+        if port is not None:
+            url += ":" + str(port)
+        if path is not None:
+            url += path
+        if query is not None:
+            url += "?" + query
+        if fragment is not None:
+            url += "#" + fragment
+
+        return url
+
+    def __str__(self) -> str:
+        return self.url
+
+
+@typing.overload
+def _encode_invalid_chars(
+    component: str, allowed_chars: typing.Container[str]
+) -> str:  # Abstract
+    ...
+
+
+@typing.overload
+def _encode_invalid_chars(
+    component: None, allowed_chars: typing.Container[str]
+) -> None:  # Abstract
+    ...
+
+
+def _encode_invalid_chars(
+    component: str | None, allowed_chars: typing.Container[str]
+) -> str | None:
+    """Percent-encodes a URI component without reapplying
+    onto an already percent-encoded component.
+    """
+    if component is None:
+        return component
+
+    component = to_str(component)
+
+    # Fast path: an ASCII component that consists only of allowed characters
+    # and contains no '%' needs neither encoding nor percent-normalization.
+    # Components containing '%' always take the general path below because
+    # how '%' is treated depends on whether the whole component is already
+    # percent-encoded.
+    if (
+        "%" not in component
+        and component.isascii()
+        and all(map(allowed_chars.__contains__, component))
+    ):
+        return component
+
+    # Normalize existing percent-encoded bytes.
+    # Try to see if the component we're encoding is already percent-encoded
+    # so we can skip all '%' characters but still encode all others.
+    component, percent_encodings = _PERCENT_RE.subn(
+        lambda match: match.group(0).upper(), component
+    )
+
+    uri_bytes = component.encode("utf-8", "surrogatepass")
+    is_percent_encoded = percent_encodings == uri_bytes.count(b"%")
+    encoded_component = bytearray()
+
+    # Iterating over bytes yields integers; 0x25 is '%'.
+    for byte_ord in uri_bytes:
+        if (is_percent_encoded and byte_ord == 0x25) or (
+            byte_ord < 128 and chr(byte_ord) in allowed_chars
+        ):
+            encoded_component.append(byte_ord)
+        else:
+            encoded_component += b"%%%02X" % byte_ord
+
+    return encoded_component.decode()
+
+
+def _remove_path_dot_segments(path: str) -> str:
+    # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
+    segments = path.split("/")  # Turn the path into a list of segments
+    output = []  # Initialize the variable to use to store output
+
+    for segment in segments:
+        # '.' is the current directory, so ignore it, it is superfluous
+        if segment == ".":
+            continue
+        # Anything other than '..', should be appended to the output
+        if segment != "..":
+            output.append(segment)
+        # In this case segment == '..', if we can, we should pop the last
+        # element
+        elif output:
+            output.pop()
+
+    # If the path starts with '/' and the output is empty or the first string
+    # is non-empty
+    if path.startswith("/") and (not output or output[0]):
+        output.insert(0, "")
+
+    # If the path starts with '/.' or '/..' ensure we add one more empty
+    # string to add a trailing '/'
+    if path.endswith(("/.", "/..")):
+        output.append("")
+
+    return "/".join(output)
+
+
+@typing.overload
+def _normalize_host(host: None, scheme: str | None) -> None: ...
+
+
+@typing.overload
+def _normalize_host(host: str, scheme: str | None) -> str: ...
+
+
+def _normalize_host(host: str | None, scheme: str | None) -> str | None:
+    if host:
+        invalid_host_char = _HOST_INVALID_CHAR_RE.search(host)
+        if invalid_host_char:
+            raise LocationParseError(
+                f"Host {host!r} contains invalid character "
+                f"{invalid_host_char.group()!r}"
+            )
+        if scheme in _NORMALIZABLE_SCHEMES:
+            is_ipv6 = _IPV6_ADDRZ_RE.match(host)
+            if is_ipv6:
+                # IPv6 hosts of the form 'a::b%zone' are encoded in a URL as
+                # such per RFC 6874: 'a::b%25zone'. Unquote the ZoneID
+                # separator as necessary to return a valid RFC 4007 scoped IP.
+                match = _ZONE_ID_RE.search(host)
+                if match:
+                    start, end = match.span(1)
+                    zone_id = host[start:end]
+
+                    if zone_id.startswith("%25") and zone_id != "%25":
+                        zone_id = zone_id[3:]
+                    else:
+                        zone_id = zone_id[1:]
+                    zone_id = _PERCENT_RE.sub(
+                        partial(_normalize_zone_id_percent_encoding, error_host=host),
+                        zone_id,
+                    )
+                    zone_id = _encode_invalid_chars(zone_id, _UNRESERVED_CHARS)
+                    return f"{host[:start].lower()}%{zone_id}{host[end:]}"
+                else:
+                    return host.lower()
+            elif not _IPV4_RE.match(host):
+                if "%" in host:
+                    host = _HOST_PERCENT_RE.sub(_normalize_host_percent_encoding, host)
+                return to_str(
+                    b".".join([_idna_encode(label) for label in host.split(".")]),
+                    "ascii",
+                )
+    return host
+
+
+def _decode_percent_encoding(match: re.Match[str], *, error_host: str) -> str:
+    percent_encoded_octet = match.group(0)
+    decoded_octet = chr(int(percent_encoded_octet[1:], 16))
+    # Keep this narrower than _HOST_INVALID_CHAR_RE because "%20" is valid
+    # percent-encoding and remains encoded.
+    if decoded_octet < "\x20" or decoded_octet == "\x7f":
+        raise LocationParseError(
+            f"Host {error_host!r} contains invalid percent-encoded "
+            f"control character {percent_encoded_octet!r}"
+        )
+    return decoded_octet
+
+
+def _normalize_host_percent_encoding(match: re.Match[str]) -> str:
+    # Reject invalid percent encodings
+    if match.group(0) == "%":
+        raise LocationParseError(f"{match.string!r} is not a valid host")
+    decoded_octet = _decode_percent_encoding(match, error_host=match.string)
+    if decoded_octet in _UNRESERVED_CHARS:
+        return decoded_octet
+    return match.group(0).upper()
+
+
+def _normalize_zone_id_percent_encoding(
+    match: re.Match[str], *, error_host: str
+) -> str:
+    _decode_percent_encoding(match, error_host=error_host)
+    return match.group(0).upper()
+
+
+def _idna_encode(name: str) -> bytes:
+    if not name.isascii():
+        try:
+            from opentelemetry.agent._vendor import idna
+        except ImportError:
+            raise LocationParseError(
+                "Unable to parse URL without the 'idna' module"
+            ) from None
+
+        try:
+            return idna.encode(name.lower(), strict=True, std3_rules=True)
+        except idna.IDNAError:
+            raise LocationParseError(
+                f"Name '{name}' is not a valid IDNA label"
+            ) from None
+
+    return _PERCENT_RE.sub(lambda match: match.group(0).upper(), name.lower()).encode(
+        "ascii"
+    )
+
+
+def _encode_target(target: str) -> str:
+    """Percent-encodes a request target so that there are no invalid characters
+
+    Pre-condition for this function is that 'target' must start with '/'.
+    If that is the case then _TARGET_RE will always produce a match.
+    """
+    match = _TARGET_RE.match(target)
+    if not match:  # Defensive:
+        raise LocationParseError(f"{target!r} is not a valid request URI")
+
+    path, query = match.groups()
+    encoded_target = _encode_invalid_chars(path, _PATH_CHARS)
+    if query is not None:
+        query = _encode_invalid_chars(query, _QUERY_CHARS)
+        encoded_target += "?" + query
+    return encoded_target
+
+
+def parse_url(url: str) -> Url:
+    """
+    Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
+    performed to parse incomplete urls. Fields not provided will be None.
+    This parser is RFC 3986 and RFC 6874 compliant.
+
+    The parser logic and helper functions are based heavily on
+    work done in the ``rfc3986`` module.
+
+    :param str url: URL to parse into a :class:`.Url` namedtuple.
+
+    Partly backwards-compatible with :mod:`urllib.parse`.
+
+    Example:
+
+    .. code-block:: python
+
+        import urllib3
+
+        print( urllib3.util.parse_url('http://google.com/mail/'))
+        # Url(scheme='http', host='google.com', port=None, path='/mail/', ...)
+
+        print( urllib3.util.parse_url('google.com:80'))
+        # Url(scheme=None, host='google.com', port=80, path=None, ...)
+
+        print( urllib3.util.parse_url('/foo?bar'))
+        # Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
+    """
+    if not url:
+        # Empty
+        return Url()
+
+    if not _SCHEME_RE.search(url):
+        url = "//" + url
+
+    scheme: str | None
+    authority: str | None
+    auth: str | None
+    host: str | None
+    port: str | None
+    port_int: int | None
+    path: str | None
+    query: str | None
+    fragment: str | None
+
+    scheme, authority, path, query, fragment = _URI_RE.match(url).groups()  # type: ignore[union-attr]
+    normalize_uri = scheme is None or scheme.lower() in _NORMALIZABLE_SCHEMES
+
+    if scheme:
+        scheme = scheme.lower()
+
+    if authority:
+        auth, _, host_port = authority.rpartition("@")
+        auth = auth or None
+        host_port_match = _HOST_PORT_RE.fullmatch(host_port)
+        if not host_port_match:
+            invalid_host_char = _HOST_INVALID_CHAR_RE.search(host_port)
+            if invalid_host_char:
+                raise LocationParseError(
+                    f"Host {host_port!r} contains invalid character "
+                    f"{invalid_host_char.group()!r}"
+                )
+            raise LocationParseError(f"{host_port!r} is not a valid host or port")
+        host, port = host_port_match.groups()
+        if auth and normalize_uri:
+            auth = _encode_invalid_chars(auth, _USERINFO_CHARS)
+        if port == "":
+            port = None
+    else:
+        auth, host, port = None, None, None
+
+    if port is not None:
+        port_int = int(port)
+        if not (0 <= port_int <= 65535):
+            raise LocationParseError(url)
+    else:
+        port_int = None
+
+    host = _normalize_host(host, scheme)
+
+    if normalize_uri and path:
+        path = _remove_path_dot_segments(path)
+        path = _encode_invalid_chars(path, _PATH_CHARS)
+    if normalize_uri and query:
+        query = _encode_invalid_chars(query, _QUERY_CHARS)
+    if normalize_uri and fragment:
+        fragment = _encode_invalid_chars(fragment, _FRAGMENT_CHARS)
+
+    # For the sake of backwards compatibility we put empty
+    # string values for path if there are any defined values
+    # beyond the path in the URL.
+    # TODO: Remove this when we break backwards compatibility.
+    if not path:
+        if query is not None or fragment is not None:
+            path = ""
+        else:
+            path = None
+
+    return Url(
+        scheme=scheme,
+        auth=auth,
+        host=host,
+        port=port_int,
+        path=path,
+        query=query,
+        fragment=fragment,
+    )
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py
new file mode 100644
index 00000000000..35c77e40258
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py
@@ -0,0 +1,42 @@
+from __future__ import annotations
+
+import typing
+from types import TracebackType
+
+
+def to_bytes(
+    x: str | bytes, encoding: str | None = None, errors: str | None = None
+) -> bytes:
+    if isinstance(x, bytes):
+        return x
+    elif not isinstance(x, str):
+        raise TypeError(f"not expecting type {type(x).__name__}")
+    if encoding or errors:
+        return x.encode(encoding or "utf-8", errors=errors or "strict")
+    return x.encode()
+
+
+def to_str(
+    x: str | bytes, encoding: str | None = None, errors: str | None = None
+) -> str:
+    if isinstance(x, str):
+        return x
+    elif not isinstance(x, bytes):
+        raise TypeError(f"not expecting type {type(x).__name__}")
+    if encoding or errors:
+        return x.decode(encoding or "utf-8", errors=errors or "strict")
+    return x.decode()
+
+
+def reraise(
+    tp: type[BaseException] | None,
+    value: BaseException,
+    tb: TracebackType | None = None,
+) -> typing.NoReturn:
+    try:
+        if value.__traceback__ is not tb:
+            raise value.with_traceback(tb)
+        raise value
+    finally:
+        value = None  # type: ignore[assignment]
+        tb = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py
new file mode 100644
index 00000000000..aeca0c7ad5b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py
@@ -0,0 +1,124 @@
+from __future__ import annotations
+
+import select
+import socket
+from functools import partial
+
+__all__ = ["wait_for_read", "wait_for_write"]
+
+
+# How should we wait on sockets?
+#
+# There are two types of APIs you can use for waiting on sockets: the fancy
+# modern stateful APIs like epoll/kqueue, and the older stateless APIs like
+# select/poll. The stateful APIs are more efficient when you have a lots of
+# sockets to keep track of, because you can set them up once and then use them
+# lots of times. But we only ever want to wait on a single socket at a time
+# and don't want to keep track of state, so the stateless APIs are actually
+# more efficient. So we want to use select() or poll().
+#
+# Now, how do we choose between select() and poll()? On traditional Unixes,
+# select() has a strange calling convention that makes it slow, or fail
+# altogether, for high-numbered file descriptors. The point of poll() is to fix
+# that, so on Unixes, we prefer poll().
+#
+# On Windows, there is no poll() (or at least Python doesn't provide a wrapper
+# for it), but that's OK, because on Windows, select() doesn't have this
+# strange calling convention; plain select() works fine.
+#
+# So: on Windows we use select(), and everywhere else we use poll(). We also
+# fall back to select() in case poll() is somehow broken or missing.
+
+
+def select_wait_for_socket(
+    sock: socket.socket,
+    read: bool = False,
+    write: bool = False,
+    timeout: float | None = None,
+) -> bool:
+    if not read and not write:
+        raise RuntimeError("must specify at least one of read=True, write=True")
+    rcheck = []
+    wcheck = []
+    if read:
+        rcheck.append(sock)
+    if write:
+        wcheck.append(sock)
+    # When doing a non-blocking connect, most systems signal success by
+    # marking the socket writable. Windows, though, signals success by marked
+    # it as "exceptional". We paper over the difference by checking the write
+    # sockets for both conditions. (The stdlib selectors module does the same
+    # thing.)
+    fn = partial(select.select, rcheck, wcheck, wcheck)
+    rready, wready, xready = fn(timeout)
+    return bool(rready or wready or xready)
+
+
+def poll_wait_for_socket(
+    sock: socket.socket,
+    read: bool = False,
+    write: bool = False,
+    timeout: float | None = None,
+) -> bool:
+    if not read and not write:
+        raise RuntimeError("must specify at least one of read=True, write=True")
+    mask = 0
+    if read:
+        mask |= select.POLLIN
+    if write:
+        mask |= select.POLLOUT
+    poll_obj = select.poll()
+    poll_obj.register(sock, mask)
+
+    # For some reason, poll() takes timeout in milliseconds
+    def do_poll(t: float | None) -> list[tuple[int, int]]:
+        if t is not None:
+            t *= 1000
+        return poll_obj.poll(t)
+
+    return bool(do_poll(timeout))
+
+
+def _have_working_poll() -> bool:
+    # Apparently some systems have a select.poll that fails as soon as you try
+    # to use it, either due to strange configuration or broken monkeypatching
+    # from libraries like eventlet/greenlet.
+    try:
+        poll_obj = select.poll()
+        poll_obj.poll(0)
+    except (AttributeError, OSError):
+        return False
+    else:
+        return True
+
+
+def wait_for_socket(
+    sock: socket.socket,
+    read: bool = False,
+    write: bool = False,
+    timeout: float | None = None,
+) -> bool:
+    # We delay choosing which implementation to use until the first time we're
+    # called. We could do it at import time, but then we might make the wrong
+    # decision if someone goes wild with monkeypatching select.poll after
+    # we're imported.
+    global wait_for_socket
+    if _have_working_poll():
+        wait_for_socket = poll_wait_for_socket
+    elif hasattr(select, "select"):
+        wait_for_socket = select_wait_for_socket
+    return wait_for_socket(sock, read, write, timeout)
+
+
+def wait_for_read(sock: socket.socket, timeout: float | None = None) -> bool:
+    """Waits for reading to be available on a given socket.
+    Returns True if the socket is readable, or False if the timeout expired.
+    """
+    return wait_for_socket(sock, read=True, timeout=timeout)
+
+
+def wait_for_write(sock: socket.socket, timeout: float | None = None) -> bool:
+    """Waits for writing to be available on a given socket.
+    Returns True if the socket is readable, or False if the timeout expired.
+    """
+    return wait_for_socket(sock, write=True, timeout=timeout)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi
new file mode 100644
index 00000000000..75febda8309
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi
@@ -0,0 +1,841 @@
+import sys
+
+if sys.version_info >= (3, 10):
+    from contextlib import AbstractContextManager
+    from inspect import FullArgSpec, Signature
+    from types import GenericAlias, ModuleType, TracebackType
+    from typing import (
+        Any,
+        AsyncIterator,
+        Callable,
+        Concatenate,
+        Final,
+        Generator,
+        Generic,
+        Iterator,
+        ParamSpec,
+        Protocol,
+        TypeVar,
+        final,
+        overload,
+    )
+
+    # Self is only in typing from Python 3.11 and the stubs support 3.10.
+    from typing_extensions import Self
+
+    # Mirrors wrapt.__all__ at runtime (src/wrapt/__init__.py). Anything not
+    # listed here is a private stub-internal helper (TypeVar, Protocol,
+    # type alias) and is prefixed with a leading underscore.
+    __all__ = (
+        "AutoObjectProxy",
+        "BaseObjectProxy",
+        "BoundFunctionWrapper",
+        "CallableObjectProxy",
+        "FunctionWrapper",
+        "LazyObjectProxy",
+        "ObjectProxy",
+        "PartialCallableObjectProxy",
+        "PathResolutionError",
+        "TargetModuleNotFoundError",
+        "WrapperChainTooDeepError",
+        "WrapperNotFoundError",
+        "WrapperNotInitializedError",
+        "WrapperNotOutermostError",
+        "partial",
+        "AdapterFactory",
+        "adapter_factory",
+        "bind_state_to_wrapper",
+        "async_to_sync",
+        "decorator",
+        "lru_cache",
+        "mark_as_async",
+        "mark_as_sync",
+        "sync_to_async",
+        "synchronized",
+        "with_doc",
+        "with_signature",
+        "discover_post_import_hooks",
+        "notify_module_loaded",
+        "register_post_import_hook",
+        "when_imported",
+        "MISSING",
+        "AttributeWrapper",
+        "apply_patch",
+        "find_wrapper",
+        "function_wrapper",
+        "is_wrapped_by",
+        "lazy_import",
+        "patch_function_wrapper",
+        "resolve_owner",
+        "resolve_path",
+        "scoped_function_wrapper",
+        "transient_function_wrapper",
+        "unwrap_object",
+        "unwrapped",
+        "wrap_function_wrapper",
+        "wrap_object",
+        "wrap_object_attribute",
+        "wrapper_chain",
+        "WeakFunctionProxy",
+    )
+
+    _P = ParamSpec("_P")
+    _R = TypeVar("_R", covariant=True)
+
+    _T = TypeVar("_T", bound=Any)
+
+    # Need two sets of ParamSpec/TypeVar for generics in some cases to ensure
+    # that mypy, pyrefly and ty all work correctly. More specifically need a
+    # separate set for cases where extracting the type or instance from the
+    # first argument of a callable where binding is involved.
+
+    _P1 = ParamSpec("_P1")
+    _R1 = TypeVar("_R1", covariant=True)
+
+    _T1 = TypeVar("_T1", bound=Any)
+
+    _P2 = ParamSpec("_P2")
+    _R2 = TypeVar("_R2", covariant=True)
+
+    _T2 = TypeVar("_T2", bound=Any)
+
+    class _Boolean(Protocol):
+        def __bool__(self) -> bool: ...
+
+    # ObjectProxy
+    #
+    # BaseObjectProxy mirrors the dunder surface of the runtime class
+    # (wrappers.ObjectProxy / _wrappers.ObjectProxy). Every protocol/operator
+    # dunder that the runtime defines unconditionally is declared here so
+    # static type checkers accept `len(proxy)`, `with proxy: ...`,
+    # `proxy + x`, etc. without complaint. Dunders that the runtime only
+    # attaches dynamically per wrapped object (__iter__ lives on
+    # ObjectProxy for backward compatibility; __next__, __aiter__,
+    # __anext__, __await__ and __length_hint__ are added per-instance by
+    # AutoObjectProxy based on the wrapped interface) are intentionally
+    # NOT claimed statically on BaseObjectProxy.
+    #
+    # `__enter__`/`__aenter__` return `Any` because the runtime forwards to
+    # the wrapped object's `__enter__`, which may return a value of any type
+    # (for example, `threading.Lock.__enter__` returns `bool`, not the lock
+    # itself). Returning `_T` would be a false claim that the value bound by
+    # `with proxy as x` is the wrapped type, which is only sometimes true.
+    # Other operator dunders return `Any` for the same reason: the result
+    # depends on the wrapped type.
+
+    class BaseObjectProxy(Generic[_T]):
+        __wrapped__: _T
+
+        __name__: str
+        __qualname__: str
+
+        # __new__ accepts and ignores any arguments, so a subclass may add
+        # arguments to __init__ or pass its own arguments through from an
+        # overridden __new__. Returns Self so such an override type checks.
+        def __new__(cls, *args: Any, **kwargs: Any) -> Self: ...
+        def __init__(self, wrapped: _T) -> None: ...
+        def __getattr__(self, name: str) -> Any: ...
+        def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
+        def __mro_entries__(self, bases: tuple[type, ...]) -> tuple[type, ...]: ...
+
+        # Context managers.
+        def __enter__(self) -> Any: ...
+        def __exit__(
+            self,
+            exc_type: type[BaseException] | None,
+            exc_value: BaseException | None,
+            traceback: TracebackType | None,
+        ) -> bool | None: ...
+        async def __aenter__(self) -> Any: ...
+        async def __aexit__(
+            self,
+            exc_type: type[BaseException] | None,
+            exc_value: BaseException | None,
+            traceback: TracebackType | None,
+        ) -> bool | None: ...
+
+        # Container protocol.
+        def __len__(self) -> int: ...
+        def __contains__(self, key: object, /) -> bool: ...
+        def __getitem__(self, key: Any, /) -> Any: ...
+        def __setitem__(self, key: Any, value: Any, /) -> None: ...
+        def __delitem__(self, key: Any, /) -> None: ...
+        def __reversed__(self) -> Iterator[Any]: ...
+
+        # Rich comparisons.
+        def __lt__(self, other: object, /) -> bool: ...
+        def __le__(self, other: object, /) -> bool: ...
+        def __gt__(self, other: object, /) -> bool: ...
+        def __ge__(self, other: object, /) -> bool: ...
+
+        # Numeric conversions.
+        def __bool__(self) -> bool: ...
+        def __int__(self) -> int: ...
+        def __float__(self) -> float: ...
+        def __complex__(self) -> complex: ...
+        def __bytes__(self) -> bytes: ...
+        def __index__(self) -> int: ...
+        def __round__(self, ndigits: int | None = ..., /) -> Any: ...
+        def __trunc__(self) -> Any: ...
+        def __floor__(self) -> Any: ...
+        def __ceil__(self) -> Any: ...
+
+        # Unary arithmetic.
+        def __neg__(self) -> Any: ...
+        def __pos__(self) -> Any: ...
+        def __abs__(self) -> Any: ...
+        def __invert__(self) -> Any: ...
+
+        # Binary arithmetic.
+        def __add__(self, other: Any, /) -> Any: ...
+        def __sub__(self, other: Any, /) -> Any: ...
+        def __mul__(self, other: Any, /) -> Any: ...
+        def __matmul__(self, other: Any, /) -> Any: ...
+        def __truediv__(self, other: Any, /) -> Any: ...
+        def __floordiv__(self, other: Any, /) -> Any: ...
+        def __mod__(self, other: Any, /) -> Any: ...
+        def __divmod__(self, other: Any, /) -> Any: ...
+        def __pow__(self, other: Any, modulo: Any = ..., /) -> Any: ...
+        def __lshift__(self, other: Any, /) -> Any: ...
+        def __rshift__(self, other: Any, /) -> Any: ...
+        def __and__(self, other: Any, /) -> Any: ...
+        def __or__(self, other: Any, /) -> Any: ...
+        def __xor__(self, other: Any, /) -> Any: ...
+
+        # Reflected binary arithmetic.
+        def __radd__(self, other: Any, /) -> Any: ...
+        def __rsub__(self, other: Any, /) -> Any: ...
+        def __rmul__(self, other: Any, /) -> Any: ...
+        def __rmatmul__(self, other: Any, /) -> Any: ...
+        def __rtruediv__(self, other: Any, /) -> Any: ...
+        def __rfloordiv__(self, other: Any, /) -> Any: ...
+        def __rmod__(self, other: Any, /) -> Any: ...
+        def __rdivmod__(self, other: Any, /) -> Any: ...
+        def __rpow__(self, other: Any, modulo: Any = ..., /) -> Any: ...
+        def __rlshift__(self, other: Any, /) -> Any: ...
+        def __rrshift__(self, other: Any, /) -> Any: ...
+        def __rand__(self, other: Any, /) -> Any: ...
+        def __ror__(self, other: Any, /) -> Any: ...
+        def __rxor__(self, other: Any, /) -> Any: ...
+
+        # In-place arithmetic.
+        def __iadd__(self, other: Any, /) -> Any: ...
+        def __isub__(self, other: Any, /) -> Any: ...
+        def __imul__(self, other: Any, /) -> Any: ...
+        def __imatmul__(self, other: Any, /) -> Any: ...
+        def __itruediv__(self, other: Any, /) -> Any: ...
+        def __ifloordiv__(self, other: Any, /) -> Any: ...
+        def __imod__(self, other: Any, /) -> Any: ...
+        def __ipow__(self, other: Any, /) -> Any: ...  # type: ignore[misc]
+        def __ilshift__(self, other: Any, /) -> Any: ...
+        def __irshift__(self, other: Any, /) -> Any: ...
+        def __iand__(self, other: Any, /) -> Any: ...
+        def __ior__(self, other: Any, /) -> Any: ...
+        def __ixor__(self, other: Any, /) -> Any: ...
+
+        # Copy / pickle.
+        def __copy__(self) -> Any: ...
+        def __deepcopy__(self, memo: dict[int, Any], /) -> Any: ...
+        def __reduce__(self) -> Any: ...
+
+        # wrapt-specific escape hatches (not Python-language dunders despite
+        # the dunder-shaped names). Ordinary attribute access, __setattr__
+        # and arithmetic operations all forward to the wrapped object; these
+        # hooks let subclasses and wrapt-aware callers reach around the
+        # forwarding layer when they need to.
+        #
+        # __self_dict__: the proxy's own instance dict (since __dict__ is
+        # overridden to delegate to the wrapped object).
+        #
+        # __self_setattr__: set an attribute directly on the proxy, bypassing
+        # the forwarding __setattr__. Used for stashing state onto a wrapper.
+        #
+        # __object_proxy__: the class used to re-wrap results of arithmetic
+        # and bitwise operations (e.g. __add__ returns
+        # ``self.__object_proxy__(self.__wrapped__ + other)``). Subclasses
+        # override it to control the type of proxy produced from operations.
+        @property
+        def __self_dict__(self) -> dict[str, Any]: ...
+        @property
+        def __object_proxy__(self) -> type[BaseObjectProxy[Any]]: ...
+        def __self_setattr__(self, name: str, value: Any) -> None: ...
+
+    class ObjectProxy(BaseObjectProxy[_T]):
+        def __init__(self, wrapped: _T) -> None: ...
+        def __iter__(self) -> Iterator[Any]: ...
+
+    class AutoObjectProxy(BaseObjectProxy[_T]):
+        # AutoObjectProxy attaches the dunders below to a per-instance
+        # subclass at construction time, based on what the wrapped object
+        # exposes (see proxies.AutoObjectProxy.__new__). We statically
+        # claim all of them here so type checkers accept code that uses
+        # them -- AutoObjectProxy's contract is "take on the interface
+        # of the wrapped object", so the stub reflects that intent at
+        # the cost of being permissive for proxies whose wrapped value
+        # doesn't actually support a given dunder (a runtime
+        # AttributeError, which mirrors the wrapt design).
+
+        def __new__(cls, wrapped: _T, *args: Any, **kwargs: Any) -> Self: ...
+        def __init__(self, wrapped: _T) -> None: ...
+
+        # Hook called by BaseObjectProxy.__setattr__ whenever __wrapped__
+        # is reassigned. AutoObjectProxy's implementation re-wires the
+        # interface-conditional dunders below to match the new wrapped
+        # object; subclasses may override it to run additional fixup logic
+        # when the wrapped object changes.
+        def __wrapped_setattr_fixups__(self) -> None: ...
+        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
+        def __iter__(self) -> Iterator[Any]: ...
+        def __next__(self) -> Any: ...
+        def __aiter__(self) -> AsyncIterator[Any]: ...
+        async def __anext__(self) -> Any: ...
+        def __length_hint__(self) -> int: ...
+        def __fspath__(self) -> str | bytes: ...
+        def __await__(self) -> Generator[Any, Any, Any]: ...
+
+    # LazyObjectProxy
+
+    class LazyObjectProxy(AutoObjectProxy[_T]):
+        def __new__(
+            cls,
+            callback: Callable[[], _T] | None = None,
+            *args: Any,
+            interface: Any = ...,
+            **kwargs: Any,
+        ) -> Self: ...
+        def __init__(
+            self,
+            callback: Callable[[], _T] | None = None,
+            *,
+            interface: Any = ...,
+        ) -> None: ...
+
+    @overload
+    def lazy_import(name: str) -> LazyObjectProxy[ModuleType]: ...
+    @overload
+    def lazy_import(
+        name: str, attribute: str, *, interface: Any = ...
+    ) -> LazyObjectProxy[Any]: ...
+
+    # CallableObjectProxy
+
+    class CallableObjectProxy(BaseObjectProxy[_T]):
+        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
+
+    # PartialCallableObjectProxy
+
+    class PartialCallableObjectProxy(BaseObjectProxy[Callable[..., Any]]):
+        _self_args: tuple[Any, ...]
+        _self_kwargs: dict[str, Any]
+        @property
+        def __signature__(self) -> Signature: ...
+        def __init__(
+            self, func: Callable[..., Any], *args: Any, **kwargs: Any
+        ) -> None: ...
+        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
+
+    def partial(
+        func: Callable[..., Any], /, *args: Any, **kwargs: Any
+    ) -> Callable[..., Any]: ...
+
+    # WeakFunctionProxy
+
+    class WeakFunctionProxy(BaseObjectProxy[Callable[..., Any]]):
+        def __init__(
+            self,
+            wrapped: Callable[..., Any],
+            callback: Callable[..., Any] | None = None,
+        ) -> None: ...
+        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
+
+    # FunctionWrapper
+
+    _WrappedFunction = Callable[_P, _R]
+
+    _GenericCallableWrapperFunction = Callable[
+        [_WrappedFunction[_P, _R], Any, tuple[Any, ...], dict[str, Any]], _R
+    ]
+
+    _ClassMethodWrapperFunction = Callable[
+        [type[Any], _WrappedFunction[_P, _R], Any, tuple[Any, ...], dict[str, Any]], _R
+    ]
+
+    _InstanceMethodWrapperFunction = Callable[
+        [Any, _WrappedFunction[_P, _R], Any, tuple[Any, ...], dict[str, Any]], _R
+    ]
+
+    _WrapperFunction = (
+        _GenericCallableWrapperFunction[_P, _R]
+        | _ClassMethodWrapperFunction[_P, _R]
+        | _InstanceMethodWrapperFunction[_P, _R]
+    )
+
+    class _FunctionWrapperBase(BaseObjectProxy[_WrappedFunction[_P, _R]]):
+        _self_instance: Any
+        _self_wrapper: _WrapperFunction[_P, _R]
+        _self_enabled: bool | _Boolean | Callable[[], bool] | None
+        _self_binding: str
+        _self_parent: Any
+        _self_owner: Any
+
+    class BoundFunctionWrapper(_FunctionWrapperBase[_P1, _R1]):
+        def __call__(self, *args: _P1.args, **kwargs: _P1.kwargs) -> _R1: ...
+
+        # Note that for following overloads, testing with mypy and ty they still do
+        # not handle static methods being decorated but to best knowledge this is
+        # a limitation in those type checkers. Testing with pyrefly fails on any
+        # type of bound method. Testing with pyright handles case correctly.
+        #
+        # Also, note that use of _T2, _P2 and _R2 in first two cases is also required
+        # to ensure correct handling by mypy and ty, so do not change to use of _T1,
+        # _P1 and _R1.
+
+        @overload
+        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
+            self: BoundFunctionWrapper[Concatenate[_T2, _P2], _R2],
+            instance: _T2,
+            owner: type[_T2] | None = None,
+            /,
+        ) -> BoundFunctionWrapper[_P2, _R2]: ...
+        @overload
+        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
+            self: BoundFunctionWrapper[Concatenate[_T2, _P2], _R2],
+            instance: _T2,
+            owner: type[Any] | None = None,
+            /,
+        ) -> BoundFunctionWrapper[_P2, _R2]: ...
+        @overload
+        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
+            self, instance: None, owner: type[_T1] | None = None, /
+        ) -> BoundFunctionWrapper[_P1, _R1]: ...
+        @overload
+        def __get__(  # Required to ensure pyright works correctly
+            self, instance: _T1, owner: type[_T1] | None = None, /
+        ) -> BoundFunctionWrapper[_P1, _R1]: ...
+
+    class FunctionWrapper(_FunctionWrapperBase[_P1, _R1]):
+        # The class used to construct the bound wrapper when the function
+        # wrapper is bound to an instance via the descriptor protocol.
+        # Subclasses override it to control the type of bound wrapper
+        # produced.
+        __bound_function_wrapper__: type[BoundFunctionWrapper[_P1, _R1]]
+
+        def __init__(
+            self,
+            wrapped: _WrappedFunction[_P1, _R1],
+            wrapper: _WrapperFunction[_P1, _R1],
+            enabled: bool | _Boolean | Callable[[], bool] | None = None,
+        ) -> None: ...
+        def __call__(self, *args: _P1.args, **kwargs: _P1.kwargs) -> _R1: ...
+
+        # Note that for following overloads, testing with mypy and ty they still do
+        # not handle static methods being decorated but to best knowledge this is
+        # a limitation in those type checkers. Testing with pyrefly fails on any
+        # type of bound method. Testing with pyright handles case correctly.
+        #
+        # Also, note that use of _T2, _P2 and _R2 in first two cases is also required
+        # to ensure correct handling by mypy and ty, so do not change to use of _T1,
+        # _P1 and _R1.
+
+        @overload
+        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
+            self: FunctionWrapper[Concatenate[_T2, _P2], _R2],
+            instance: _T2,
+            owner: type[Any] | None = None,
+            /,
+        ) -> BoundFunctionWrapper[_P2, _R2]: ...
+        @overload
+        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
+            self: FunctionWrapper[Concatenate[_T2, _P2], _R2],
+            instance: _T2,
+            owner: type[_T2] | None = None,
+            /,
+        ) -> BoundFunctionWrapper[_P2, _R2]: ...
+        @overload
+        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
+            self, instance: None, owner: type[_T1] | None = None, /
+        ) -> BoundFunctionWrapper[_P1, _R1]: ...
+        @overload
+        def __get__(  # Required to ensure pyright works correctly
+            self, instance: _T1, owner: type[_T1] | None = None, /
+        ) -> BoundFunctionWrapper[_P1, _R1]: ...
+
+    # AdapterFactory/adapter_factory()
+
+    class AdapterFactory:
+        def __call__(
+            self, wrapped: Callable[..., Any]
+        ) -> str | FullArgSpec | Callable[..., Any]: ...
+
+    class _DelegatedAdapterFactory(AdapterFactory):
+        def __init__(self, factory: Callable[..., Any]) -> None: ...
+
+    adapter_factory = _DelegatedAdapterFactory
+
+    # decorator()
+
+    class _Descriptor(Protocol):
+        def __get__(self, instance: Any, owner: type[Any] | None = None) -> Any: ...
+
+    class _FunctionDecorator:
+        @overload
+        def __call__(
+            self,
+            callable: (
+                Callable[_P, _R]
+                | Callable[Concatenate[type[_T], _P], _R]  # Required for pylance
+                # | Callable[Concatenate[Any, _P], _R]  # Breaks mypy, pyrefly and ty
+                | Callable[[type[_T]], _R]  # Required for pylance
+            ),
+        ) -> FunctionWrapper[_P, _R]: ...
+        @overload
+        def __call__(self, callable: _Descriptor) -> FunctionWrapper[_P, Any]: ...
+
+    class _PartialFunctionDecorator:
+        @overload
+        def __call__(
+            self, wrapper: _GenericCallableWrapperFunction[_P, _R], /
+        ) -> _FunctionDecorator: ...
+        @overload
+        def __call__(
+            self, wrapper: _ClassMethodWrapperFunction[_P, _R], /
+        ) -> _FunctionDecorator: ...
+        @overload
+        def __call__(
+            self, wrapper: _InstanceMethodWrapperFunction[_P, _R], /
+        ) -> _FunctionDecorator: ...
+
+    # ... Decorator applied to class type.
+
+    @overload
+    def decorator(wrapper: type[_T], /) -> _FunctionDecorator: ...
+
+    # ... Decorator applied to function or method.
+
+    @overload
+    def decorator(
+        wrapper: _GenericCallableWrapperFunction[_P, _R], /
+    ) -> _FunctionDecorator: ...
+    @overload
+    def decorator(
+        wrapper: _ClassMethodWrapperFunction[_P, _R], /
+    ) -> _FunctionDecorator: ...
+    @overload
+    def decorator(
+        wrapper: _InstanceMethodWrapperFunction[_P, _R], /
+    ) -> _FunctionDecorator: ...
+
+    # ... Positional arguments.
+
+    @overload
+    def decorator(
+        *,
+        enabled: bool | _Boolean | Callable[[], bool] | None = None,
+        adapter: str | FullArgSpec | AdapterFactory | Callable[..., Any] | None = None,
+        proxy: type[FunctionWrapper[Any, Any]] | None = None,
+    ) -> _PartialFunctionDecorator: ...
+
+    # function_wrapper()
+
+    @overload
+    def function_wrapper(wrapper: type[Any]) -> _FunctionDecorator: ...
+    @overload
+    def function_wrapper(
+        wrapper: _GenericCallableWrapperFunction[_P, _R],
+    ) -> _FunctionDecorator: ...
+    @overload
+    def function_wrapper(
+        wrapper: _ClassMethodWrapperFunction[_P, _R],
+    ) -> _FunctionDecorator: ...
+    @overload
+    def function_wrapper(
+        wrapper: _InstanceMethodWrapperFunction[_P, _R],
+    ) -> _FunctionDecorator: ...
+    # @overload
+    # def function_wrapper(wrapper: Any) -> _FunctionDecorator: ... # Don't use, breaks stuff.
+
+    # wrap_function_wrapper()
+
+    def wrap_function_wrapper(
+        target: ModuleType | type[Any] | Any | str,
+        name: str,
+        wrapper: _WrapperFunction[_P, _R],
+    ) -> FunctionWrapper[_P, _R]: ...
+
+    # patch_function_wrapper()
+
+    class _WrapperDecorator:
+        def __call__(
+            self, wrapper: _WrapperFunction[_P, _R]
+        ) -> FunctionWrapper[_P, _R]: ...
+
+    def patch_function_wrapper(
+        target: ModuleType | type[Any] | Any | str,
+        name: str,
+        *,
+        enabled: bool | _Boolean | Callable[[], bool] | None | _MissingType = ...,
+    ) -> _WrapperDecorator: ...
+
+    # transient_function_wrapper()
+
+    class _TransientDecorator:
+        def __call__(self, wrapper: _WrapperFunction[_P, _R]) -> _FunctionDecorator: ...
+
+    def transient_function_wrapper(
+        target: ModuleType | type[Any] | Any | str, name: str
+    ) -> _TransientDecorator: ...
+
+    # scoped_function_wrapper()
+
+    def scoped_function_wrapper(
+        target: ModuleType | type[Any] | Any | str,
+        name: str,
+        wrapper: _WrapperFunction[_P, _R],
+    ) -> AbstractContextManager[None]: ...
+
+    # Exceptions.
+
+    class WrapperNotInitializedError(ValueError): ...
+
+    class PathResolutionError(AttributeError): ...
+
+    class TargetModuleNotFoundError(ModuleNotFoundError): ...
+
+    class WrapperChainTooDeepError(RuntimeError): ...
+
+    class WrapperNotFoundError(ValueError): ...
+
+    class WrapperNotOutermostError(ValueError): ...
+
+    # MISSING sentinel. The class stays private, matching the runtime
+    # (the dataclasses.MISSING/_MISSING_TYPE arrangement): signatures
+    # reference _MissingType while callers only ever write wrapt.MISSING.
+
+    @final
+    class _MissingType: ...
+
+    MISSING: Final[_MissingType]
+
+    # resolve_path()
+
+    def resolve_path(
+        target: ModuleType | type[Any] | Any | str, name: str
+    ) -> tuple[ModuleType | type[Any] | Any, str, Callable[..., Any]]: ...
+
+    # resolve_owner()
+
+    def resolve_owner(
+        target: ModuleType | type[Any] | Any | str, name: str
+    ) -> tuple[ModuleType | type[Any] | Any, str, Callable[..., Any]]: ...
+
+    # apply_patch()
+
+    def apply_patch(
+        parent: ModuleType | type[Any] | Any,
+        attribute: str,
+        replacement: Any,
+    ) -> None: ...
+
+    # wrap_object()
+
+    _WrapperFactory = Callable[
+        [Callable[..., Any], tuple[Any, ...], dict[str, Any]],
+        BaseObjectProxy[Any],
+    ]
+
+    def wrap_object(
+        target: ModuleType | type[Any] | Any | str,
+        name: str,
+        factory: _WrapperFactory | type[BaseObjectProxy[Any]],
+        args: tuple[Any, ...] = (),
+        kwargs: dict[str, Any] | None = None,
+    ) -> Any: ...
+
+    # wrap_object_attribute()
+
+    class AttributeWrapper(BaseObjectProxy[Any]):
+        _self_attribute: str
+        _self_factory: Callable[..., Any]
+        _self_args: tuple[Any, ...]
+        _self_kwargs: dict[str, Any]
+        def __init__(
+            self,
+            wrapped: Any,
+            attribute: str,
+            factory: Callable[..., Any],
+            args: tuple[Any, ...] = (),
+            kwargs: dict[str, Any] | None = None,
+        ) -> None: ...
+        def __get__(self, instance: Any, owner: type[Any] | None = None) -> Any: ...
+        def __set__(self, instance: Any, value: Any) -> None: ...
+        def __delete__(self, instance: Any) -> None: ...
+
+    def wrap_object_attribute(
+        module: ModuleType | type[Any] | Any | str,
+        name: str,
+        factory: _WrapperFactory | type[BaseObjectProxy[Any]],
+        args: tuple[Any, ...] = (),
+        kwargs: dict[str, Any] | None = None,
+    ) -> AttributeWrapper: ...
+
+    # wrapper_chain()
+
+    def wrapper_chain(obj: Any, *, limit: int = 64) -> Iterator[Any]: ...
+
+    # unwrapped()
+
+    def unwrapped(obj: Any, *, limit: int = 64) -> Any: ...
+
+    # find_wrapper()
+
+    def find_wrapper(
+        obj: Any,
+        handle: Any | None = None,
+        *,
+        predicate: Callable[[Any], bool] | None = None,
+        limit: int = 64,
+    ) -> Any | None: ...
+
+    # is_wrapped_by()
+
+    def is_wrapped_by(
+        obj: Any,
+        handle: Any | None = None,
+        *,
+        predicate: Callable[[Any], bool] | None = None,
+        limit: int = 64,
+    ) -> bool: ...
+
+    # unwrap_object()
+
+    def unwrap_object(
+        target: ModuleType | type[Any] | Any | str,
+        name: str,
+        handle: Any,
+        *,
+        missing_ok: bool = False,
+    ) -> Any | None: ...
+
+    # register_post_import_hook()
+
+    def register_post_import_hook(
+        hook: Callable[[ModuleType], Any] | str, name: str
+    ) -> None: ...
+
+    # discover_post_import_hooks()
+
+    def discover_post_import_hooks(group: str) -> None: ...
+
+    # notify_module_loaded()
+
+    def notify_module_loaded(module: ModuleType) -> None: ...
+
+    # when_imported()
+
+    class _ImportHookDecorator:
+        def __call__(self, hook: Callable[[ModuleType], Any]) -> Callable[..., Any]: ...
+
+    def when_imported(name: str) -> _ImportHookDecorator: ...
+
+    # synchronized()
+
+    class _SynchronizedObject:
+        def __call__(self, wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
+        def __enter__(self) -> Any: ...
+        def __exit__(
+            self,
+            exc_type: type[BaseException] | None,
+            exc_value: BaseException | None,
+            traceback: TracebackType | None,
+        ) -> bool | None: ...
+        async def __aenter__(self) -> Any: ...
+        async def __aexit__(
+            self,
+            exc_type: type[BaseException] | None,
+            exc_value: BaseException | None,
+            traceback: TracebackType | None,
+        ) -> bool | None: ...
+
+    @overload
+    def synchronized(wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
+    @overload
+    def synchronized(wrapped: Any) -> _SynchronizedObject: ...
+
+    # mark_as_sync(), mark_as_async(), async_to_sync(), sync_to_async()
+
+    @overload
+    def mark_as_sync(wrapped: Callable[_P, _R], /) -> Callable[_P, _R]: ...
+    @overload
+    def mark_as_sync(
+        *, generator: bool | None = None
+    ) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
+    @overload
+    def mark_as_async(wrapped: Callable[_P, _R], /) -> Callable[_P, _R]: ...
+    @overload
+    def mark_as_async(
+        *, generator: bool | None = None
+    ) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
+    def async_to_sync(wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
+    def sync_to_async(wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
+
+    # bind_state_to_wrapper()
+
+    class _StateBindingWrapper(BaseObjectProxy[Any]):
+        name: str
+        wrapper_factory: _Descriptor | None
+        def __init__(self, *, name: str = "state") -> None: ...
+        def __call__(self, wrapper_factory: _Descriptor) -> _StateBindingWrapper: ...
+        def __get__(
+            self, instance: Any, owner: type[Any]
+        ) -> (
+            _StateBindingWrapper
+            | Callable[[Callable[..., Any]], FunctionWrapper[..., Any]]
+        ): ...
+
+    bind_state_to_wrapper = _StateBindingWrapper
+
+    # lru_cache()
+
+    class _BoundLRUCacheFunctionWrapper(BoundFunctionWrapper[_P1, _R1]):
+        def cache_info(self) -> Any | None: ...
+        def cache_clear(self) -> None: ...
+        def cache_parameters(self) -> dict[str, Any] | None: ...
+
+    class _LRUCacheFunctionWrapper(FunctionWrapper[_P1, _R1]):
+        __bound_function_wrapper__: type[_BoundLRUCacheFunctionWrapper[_P1, _R1]]
+        def cache_info(self) -> Any | None: ...
+        def cache_clear(self) -> None: ...
+        def cache_parameters(self) -> dict[str, Any] | None: ...
+
+    @overload
+    def lru_cache(func: Callable[_P, _R], /) -> _LRUCacheFunctionWrapper[_P, _R]: ...
+    @overload
+    def lru_cache(
+        func: None = None, /, **kwargs: Any
+    ) -> Callable[[Callable[_P, _R]], _LRUCacheFunctionWrapper[_P, _R]]: ...
+
+    # with_signature()
+
+    def with_signature(
+        *,
+        prototype: Callable[..., Any] | None = None,
+        signature: Signature | None = None,
+        factory: (
+            Callable[
+                [Callable[..., Any]],
+                Signature
+                | Callable[..., Any]
+                | tuple[Signature | Callable[..., Any], str | None],
+            ]
+            | None
+        ) = None,
+        doc: str | None = None,
+    ) -> Callable[[Callable[_P, _R]], FunctionWrapper[_P, _R]]: ...
+
+    # with_doc()
+
+    def with_doc(
+        *,
+        doc: str | None = None,
+        factory: Callable[[Callable[..., Any]], str | None] | None = None,
+    ) -> Callable[[Callable[_P, _R]], FunctionWrapper[_P, _R]]: ...
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE
new file mode 100644
index 00000000000..58dfb5c737e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE
@@ -0,0 +1,24 @@
+Copyright (c) 2013-2026, Graham Dumpleton
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py
new file mode 100644
index 00000000000..5a91a9120e6
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py
@@ -0,0 +1,130 @@
+"""
+Wrapt is a library for decorators, wrappers and monkey patching.
+"""
+
+
+def _format_version(parts):
+    base = ".".join(parts[:3])
+    if len(parts) == 3:
+        return base
+    suffix = parts[3]
+    return (
+        f"{base}.{suffix}" if suffix.startswith(("dev", "post")) else f"{base}{suffix}"
+    )
+
+
+__version_info__ = ("2", "5", "2")
+__version__ = _format_version(__version_info__)
+
+from .__wrapt__ import (
+    BaseObjectProxy,
+    BoundFunctionWrapper,
+    CallableObjectProxy,
+    FunctionWrapper,
+    PartialCallableObjectProxy,
+    partial,
+)
+from .caching import lru_cache
+from .decorators import (
+    AdapterFactory,
+    adapter_factory,
+    bind_state_to_wrapper,
+    decorator,
+)
+from .doc import with_doc
+from .exceptions import (
+    PathResolutionError,
+    TargetModuleNotFoundError,
+    WrapperChainTooDeepError,
+    WrapperNotFoundError,
+    WrapperNotInitializedError,
+    WrapperNotOutermostError,
+)
+from .importer import (
+    discover_post_import_hooks,
+    notify_module_loaded,
+    register_post_import_hook,
+    when_imported,
+)
+from .patches import (
+    MISSING,
+    AttributeWrapper,
+    apply_patch,
+    find_wrapper,
+    function_wrapper,
+    is_wrapped_by,
+    patch_function_wrapper,
+    resolve_owner,
+    resolve_path,
+    scoped_function_wrapper,
+    transient_function_wrapper,
+    unwrap_object,
+    unwrapped,
+    wrap_function_wrapper,
+    wrap_object,
+    wrap_object_attribute,
+    wrapper_chain,
+)
+from .proxies import AutoObjectProxy, LazyObjectProxy, ObjectProxy, lazy_import
+from .signature import with_signature
+from .synchronization import (
+    async_to_sync,
+    mark_as_async,
+    mark_as_sync,
+    sync_to_async,
+    synchronized,
+)
+from .weakrefs import WeakFunctionProxy
+
+__all__ = (
+    "AutoObjectProxy",
+    "BaseObjectProxy",
+    "BoundFunctionWrapper",
+    "CallableObjectProxy",
+    "FunctionWrapper",
+    "LazyObjectProxy",
+    "ObjectProxy",
+    "PartialCallableObjectProxy",
+    "PathResolutionError",
+    "TargetModuleNotFoundError",
+    "WrapperChainTooDeepError",
+    "WrapperNotFoundError",
+    "WrapperNotInitializedError",
+    "WrapperNotOutermostError",
+    "partial",
+    "AdapterFactory",
+    "adapter_factory",
+    "bind_state_to_wrapper",
+    "async_to_sync",
+    "decorator",
+    "lru_cache",
+    "mark_as_async",
+    "mark_as_sync",
+    "sync_to_async",
+    "synchronized",
+    "with_doc",
+    "with_signature",
+    "discover_post_import_hooks",
+    "notify_module_loaded",
+    "register_post_import_hook",
+    "when_imported",
+    "MISSING",
+    "AttributeWrapper",
+    "apply_patch",
+    "find_wrapper",
+    "function_wrapper",
+    "is_wrapped_by",
+    "lazy_import",
+    "patch_function_wrapper",
+    "resolve_owner",
+    "resolve_path",
+    "scoped_function_wrapper",
+    "transient_function_wrapper",
+    "unwrap_object",
+    "unwrapped",
+    "wrap_function_wrapper",
+    "wrap_object",
+    "wrap_object_attribute",
+    "wrapper_chain",
+    "WeakFunctionProxy",
+)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py
new file mode 100644
index 00000000000..f633aa98558
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py
@@ -0,0 +1,42 @@
+"""This module is used to switch between C and Python implementations of the
+wrappers.
+"""
+
+import os
+
+from .wrappers import BoundFunctionWrapper, CallableObjectProxy, FunctionWrapper
+from .wrappers import ObjectProxy as BaseObjectProxy
+from .wrappers import PartialCallableObjectProxy, _FunctionWrapperBase
+
+# Try to use C extensions if not disabled.
+
+_using_c_extension = False
+
+_use_extensions = not os.environ.get("WRAPT_DISABLE_EXTENSIONS")
+
+if _use_extensions:
+    try:
+        from ._wrappers import (  # type: ignore[no-redef,import-not-found,import-untyped]
+            BoundFunctionWrapper,
+            CallableObjectProxy,
+            FunctionWrapper,
+        )
+        from ._wrappers import ObjectProxy as BaseObjectProxy  # type: ignore[no-redef,import-untyped]
+        from ._wrappers import (  # type: ignore[no-redef,import-not-found,import-untyped]
+            PartialCallableObjectProxy,
+            _FunctionWrapperBase,
+        )
+
+        _using_c_extension = True
+    except ImportError:
+        # C extensions not available, using Python implementations
+        pass
+
+
+def partial(*args, **kwargs):
+    """Create a callable object proxy with partial application of the given
+    arguments and keywords. This behaves the same as `functools.partial`, but
+    implemented using the `ObjectProxy` class to provide better support for
+    introspection.
+    """
+    return PartialCallableObjectProxy(*args, **kwargs)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c
new file mode 100644
index 00000000000..af1868de6e0
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c
@@ -0,0 +1,5892 @@
+/* ------------------------------------------------------------------------- */
+
+#include "Python.h"
+
+#include "structmember.h"
+
+/* ------------------------------------------------------------------------- */
+
+typedef struct
+{
+  PyObject_HEAD
+
+      PyObject *dict;
+  PyObject *wrapped;
+  PyObject *weakreflist;
+  int init_called;
+} WraptObjectProxyObject;
+
+typedef struct
+{
+  WraptObjectProxyObject object_proxy;
+
+  PyObject *args;
+  PyObject *kwargs;
+} WraptPartialCallableObjectProxyObject;
+
+typedef struct
+{
+  WraptObjectProxyObject object_proxy;
+
+  PyObject *instance;
+  PyObject *wrapper;
+  PyObject *enabled;
+  PyObject *binding;
+  PyObject *parent;
+  PyObject *owner;
+} WraptFunctionWrapperObject;
+
+/* ------------------------------------------------------------------------- */
+
+/* Forward declaration of moduledef so module-state helpers can reference it. */
+
+static struct PyModuleDef moduledef;
+
+/* Per-interpreter module state. Holds the heap type objects so that methods
+ * can reach them via PyType_GetModuleByDef without using static globals,
+ * along with the cached interned strings and exception type below. */
+
+typedef struct
+{
+  PyTypeObject *ObjectProxy_Type;
+  PyTypeObject *CallableObjectProxy_Type;
+  PyTypeObject *PartialCallableObjectProxy_Type;
+  PyTypeObject *FunctionWrapperBase_Type;
+  PyTypeObject *BoundFunctionWrapper_Type;
+  PyTypeObject *FunctionWrapper_Type;
+
+  /* Cached interned attribute / argument names. Initialized eagerly in
+   * wrapt_exec, released in wrapt_clear. Per-interpreter so they remain
+   * sub-interpreter safe; eager init makes them free-threading safe by
+   * eliminating the lazy-init data race that the previous static-local
+   * string pattern had. */
+
+  PyObject *str_wrapped;                /* "__wrapped__" */
+  PyObject *str_wrapped_factory;        /* "__wrapped_factory__" */
+  PyObject *str_wrapped_get;            /* "__wrapped_get__" */
+  PyObject *str_module;                 /* "__module__" */
+  PyObject *str_doc;                    /* "__doc__" */
+  PyObject *str_setattr_fixups;         /* "__wrapped_setattr_fixups__" */
+  PyObject *str_getattr;                /* "__getattr__" */
+  PyObject *str_self_;                  /* "_self_" */
+  PyObject *str_callable;               /* "callable" */
+  PyObject *str_bound_function_wrapper; /* "__bound_function_wrapper__" */
+  PyObject *str_function;               /* "function" */
+  PyObject *str_classmethod;            /* "classmethod" */
+  PyObject *str_staticmethod;           /* "staticmethod" */
+  PyObject *str_builtin;                /* "builtin" */
+  PyObject *str_class;                  /* "class" */
+  PyObject *str_instancemethod;         /* "instancemethod" */
+  PyObject *str_object_proxy;           /* "__object_proxy__" */
+  PyObject *str_enter;                  /* "__enter__" */
+  PyObject *str_exit;                   /* "__exit__" */
+  PyObject *str_aenter;                 /* "__aenter__" */
+  PyObject *str_aexit;                  /* "__aexit__" */
+  PyObject *str_mro_entries;            /* "__mro_entries__" */
+  PyObject *str_name;                   /* "__name__" */
+  PyObject *str_qualname;               /* "__qualname__" */
+  PyObject *str_annotations;            /* "__annotations__" */
+  PyObject *str_dunder_class;           /* "__class__" */
+  PyObject *str_self;                   /* "__self__" */
+  PyObject *str_set_name;               /* "__set_name__" */
+  PyObject *str_self_binding;           /* "_self_binding" */
+  PyObject *str_dict;                   /* "__dict__" */
+  PyObject *str_signature;              /* "__signature__" */
+
+  /* Cached exception type from wrapt.wrappers. Initialized eagerly in
+   * wrapt_exec after type creation. The wrapt.wrappers module is guaranteed
+   * to be imported before _wrappers because __wrapt__.py imports it first. */
+
+  PyObject *WrapperNotInitializedError;
+} wrapt_module_state;
+
+static inline wrapt_module_state *wrapt_get_state(PyObject *module)
+{
+  return (wrapt_module_state *)PyModule_GetState(module);
+}
+
+/* Polyfill PyType_GetModuleByDef for Python < 3.11. The borrowed-reference
+ * contract matches the real API so callers are version-agnostic. */
+
+#if PY_VERSION_HEX < 0x030B0000
+static PyObject *PyType_GetModuleByDef(PyTypeObject *type,
+                                       struct PyModuleDef *def)
+{
+  PyObject *mro = type->tp_mro;
+  Py_ssize_t i, n;
+
+  if (mro == NULL)
+    return NULL;
+
+  n = PyTuple_GET_SIZE(mro);
+
+  for (i = 0; i < n; i++)
+  {
+    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
+    PyObject *m;
+
+    if (!PyType_HasFeature(t, Py_TPFLAGS_HEAPTYPE))
+      continue;
+
+    m = PyType_GetModule(t);
+
+    if (m != NULL && PyModule_GetDef(m) == def)
+      return m;
+
+    if (m == NULL)
+    {
+      /* PyType_GetModule only raises TypeError here (no module
+       * association on heap type); no other failure mode is expected.
+       * Guard with WriteUnraisable for completeness. */
+      if (!PyErr_ExceptionMatches(PyExc_TypeError))
+        PyErr_WriteUnraisable((PyObject *)t);
+      PyErr_Clear();
+    }
+  }
+
+  PyErr_Format(PyExc_TypeError,
+               "PyType_GetModuleByDef: No superclass of '%s' has the given "
+               "module",
+               type->tp_name);
+  return NULL;
+}
+#endif
+
+/* Polyfill the critical section API for Python < 3.13. Free-threaded
+ * builds only exist on 3.13+, where the real macros are provided (and are
+ * no-ops on GIL builds), so expanding to plain blocks here is safe. */
+
+#if PY_VERSION_HEX < 0x030D0000
+#define Py_BEGIN_CRITICAL_SECTION(op) {
+#define Py_END_CRITICAL_SECTION() }
+#endif
+
+/* Polyfill PyObject_GetOptionalAttrString for Python < 3.13. Matches the
+ * 3.13+ semantics: returns 1 if found, 0 if not found (AttributeError
+ * only), -1 on other errors with exception set. */
+
+#if PY_VERSION_HEX < 0x030d0000
+static inline int
+PyObject_GetOptionalAttrString(PyObject *obj, const char *name, PyObject **result)
+{
+  *result = PyObject_GetAttrString(obj, name);
+  if (*result)
+    return 1;
+  if (PyErr_ExceptionMatches(PyExc_AttributeError))
+  {
+    PyErr_Clear();
+    return 0;
+  }
+  return -1;
+}
+#endif
+
+/* Atomically read a PyObject field of an instance and return a new
+ * reference to it, or NULL if the field is NULL (no exception is set).
+ * The read and the incref are performed together inside the owning
+ * object's critical section so the incref cannot race a writer which
+ * has swapped in a new value and is releasing the old one. On builds
+ * with the GIL the critical section is a no-op and this reduces to a
+ * plain load and incref. This is deliberately used on all builds rather
+ * than only free-threaded ones, so that both build variants exercise
+ * the same reference lifetimes, and so that a field value can never be
+ * freed while still in use when code invoked while operating on the
+ * field mutates the instance. */
+
+static inline PyObject *wrapt_acquire_field(PyObject *owner, PyObject **field)
+{
+  PyObject *value = NULL;
+
+  Py_BEGIN_CRITICAL_SECTION(owner);
+  value = *field;
+  Py_XINCREF(value);
+  Py_END_CRITICAL_SECTION();
+
+  return value;
+}
+
+/* Test whether an attribute name matches one of the interned strings held
+ * in module state. Attribute names arriving from Python code are interned
+ * by the compiler, so a pointer comparison against the interned string is
+ * nearly always sufficient and is the fast path. A name constructed at
+ * runtime, for example by string concatenation or decoding, is not
+ * interned and would never match by pointer, so fall back to a value
+ * comparison. That comparison is guarded by a length check so that the
+ * cost for the overwhelming majority of non matching names is a single
+ * integer comparison. This mirrors the pattern used by CPython itself in
+ * super_getattro() for __class__.
+ *
+ * The name must be a str. This holds for the attribute get and set slots
+ * where this is used, since PyObject_GetAttr() and PyObject_SetAttr()
+ * reject any other type before the slot is reached. */
+
+static inline int wrapt_name_equals(PyObject *name, PyObject *interned)
+{
+  if (name == interned)
+    return 1;
+
+  if (!PyUnicode_Check(name))
+    return 0;
+
+  if (PyUnicode_GET_LENGTH(name) != PyUnicode_GET_LENGTH(interned))
+    return 0;
+
+  return PyUnicode_Compare(name, interned) == 0;
+}
+
+/* Convenience form for the common case of the wrapped object field. */
+
+static inline PyObject *wrapt_acquire_wrapped(WraptObjectProxyObject *self)
+{
+  return wrapt_acquire_field((PyObject *)self, &self->wrapped);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Get module state for the wrapt module given any type whose MRO includes
+ * one of our heap types. Returns NULL and sets an exception on miss. */
+
+static wrapt_module_state *wrapt_state_from_type(PyTypeObject *type)
+{
+  PyObject *m = PyType_GetModuleByDef(type, &moduledef);
+  return m ? wrapt_get_state(m) : NULL;
+}
+
+/* Walk type's MRO checking each tp_dict directly for the named attribute.
+ * Does not invoke type's tp_getattro, so it does NOT trigger Python's lazy
+ * creation of class-level attributes such as __annotations__. Used by
+ * setattro to decide "is this a local attribute on the proxy type" without
+ * shadowing our getset descriptors via lazy class-dict mutation. */
+
+static int wrapt_type_has_attr(PyTypeObject *type, PyObject *name)
+{
+  PyObject *mro = type->tp_mro;
+  Py_ssize_t i, n;
+
+  if (mro == NULL)
+    return 0;
+
+  n = PyTuple_GET_SIZE(mro);
+
+  for (i = 0; i < n; i++)
+  {
+    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
+    PyObject *dict = t->tp_dict;
+    int contains;
+
+    if (dict == NULL)
+      continue;
+
+    contains = PyDict_Contains(dict, name);
+    if (contains < 0)
+    {
+      /* PyDict_Contains cannot fail with string keys against a
+       * string-keyed tp_dict; no failure is expected here. Guard
+       * with WriteUnraisable for completeness. */
+      PyErr_WriteUnraisable((PyObject *)t);
+      PyErr_Clear();
+      continue;
+    }
+    if (contains > 0)
+      return 1;
+  }
+
+  return 0;
+}
+
+/* Look for a __doc__ descriptor defined by a derived class. Walks the MRO
+ * of the type checking each tp_dict directly for __doc__, skipping the
+ * plain docstring entries which every class carries, being a string or
+ * None for a class without a docstring. The proxy base types hold a plain
+ * string docstring, so any descriptor found must come from a derived
+ * class, which is taken to mean it wants to control what __doc__ reports
+ * for its instances in place of the default delegation to the wrapped
+ * object. Only __doc__ is treated this way, __module__ always delegates.
+ * The descriptor is invoked directly rather than falling back to the
+ * generic attribute lookup, since that would stop at the None or docstring
+ * entry of a derived class which inherits the descriptor from its base.
+ * Returns a new reference, or NULL without an exception set if there is
+ * no such descriptor. */
+
+static PyObject *wrapt_lookup_doc_descriptor(PyTypeObject *type,
+                                             PyObject *name)
+{
+  PyObject *mro = type->tp_mro;
+  Py_ssize_t i, n;
+
+  if (mro == NULL)
+    return NULL;
+
+  n = PyTuple_GET_SIZE(mro);
+
+  for (i = 0; i < n; i++)
+  {
+    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
+    PyObject *dict = t->tp_dict;
+    PyObject *entry = NULL;
+
+    if (dict == NULL)
+      continue;
+
+#if PY_VERSION_HEX >= 0x030D0000
+    if (PyDict_GetItemRef(dict, name, &entry) < 0)
+    {
+      PyErr_WriteUnraisable((PyObject *)t);
+      PyErr_Clear();
+      continue;
+    }
+#else
+    entry = PyDict_GetItemWithError(dict, name);
+    if (entry == NULL && PyErr_Occurred())
+    {
+      PyErr_WriteUnraisable((PyObject *)t);
+      PyErr_Clear();
+      continue;
+    }
+    Py_XINCREF(entry);
+#endif
+
+    if (entry == NULL)
+      continue;
+
+    if (entry == Py_None || PyUnicode_Check(entry))
+    {
+      Py_DECREF(entry);
+      continue;
+    }
+
+    if (Py_TYPE(entry)->tp_descr_get)
+      return entry;
+
+    Py_DECREF(entry);
+    return NULL;
+  }
+
+  return NULL;
+}
+
+/* Non-error-setting predicate: is this object an instance of any wrapt
+ * proxy type? Walks the MRO directly. PyType_GetModule sets an exception
+ * for heap types that lack a module association (e.g. pure-Python user
+ * subclasses), so we save/restore exception state to keep this predicate
+ * side-effect-free for the caller. */
+
+static int wrapt_is_proxy(PyObject *o)
+{
+  PyTypeObject *type = Py_TYPE(o);
+  PyObject *mro = type->tp_mro;
+  Py_ssize_t i, n;
+  PyObject *saved_type = NULL, *saved_value = NULL, *saved_tb = NULL;
+  int had_error = PyErr_Occurred() != NULL;
+  int result = 0;
+
+  if (had_error)
+    PyErr_Fetch(&saved_type, &saved_value, &saved_tb);
+
+  if (mro == NULL)
+    goto done;
+
+  n = PyTuple_GET_SIZE(mro);
+
+  for (i = 0; i < n; i++)
+  {
+    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
+    PyObject *m;
+
+    if (!PyType_HasFeature(t, Py_TPFLAGS_HEAPTYPE))
+      continue;
+
+    m = PyType_GetModule(t);
+
+    if (m == NULL)
+    {
+      /* PyType_GetModule only raises TypeError here (no module
+       * association on heap type); no other failure mode is expected.
+       * Guard with WriteUnraisable for completeness. */
+      if (!PyErr_ExceptionMatches(PyExc_TypeError))
+        PyErr_WriteUnraisable((PyObject *)t);
+      PyErr_Clear();
+      continue;
+    }
+
+    if (PyModule_GetDef(m) == &moduledef)
+    {
+      result = 1;
+      break;
+    }
+  }
+
+done:
+  if (had_error)
+    PyErr_Restore(saved_type, saved_value, saved_tb);
+  else
+    PyErr_Clear();
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int raise_uninitialized_wrapper_error(WraptObjectProxyObject *object)
+{
+  // Before raising an exception we need to first check whether this is a lazy
+  // proxy object and attempt to intialize the wrapped object using the supplied
+  // callback if so. If the callback is not present then we can proceed to raise
+  // the exception, but if the callback is present and returns a value, we set
+  // that as the wrapped object and continue and return without raising an error.
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(object));
+  if (!state)
+    return -1;
+
+  PyObject *wrapped_str = state->str_wrapped;
+  PyObject *wrapped_factory_str = state->str_wrapped_factory;
+  PyObject *wrapped_get_str = state->str_wrapped_get;
+
+  PyObject *callback = NULL;
+  PyObject *value = NULL;
+
+  // Note that we use existance of __wrapped_factory__ to gate whether we can
+  // attempt to initialize the wrapped object lazily, but it is __wrapped_get__
+  // that we actually call to do the initialization. This is so that we can
+  // handle multithreading correctly by having __wrapped_get__ use a lock to
+  // protect against multiple threads trying to initialize the wrapped object
+  // at the same time.
+
+  callback = PyObject_GenericGetAttr((PyObject *)object, wrapped_factory_str);
+
+  if (callback)
+  {
+    if (callback != Py_None)
+    {
+      Py_DECREF(callback);
+
+      callback = PyObject_GenericGetAttr((PyObject *)object, wrapped_get_str);
+
+      if (!callback)
+        return -1;
+
+      value = PyObject_CallObject(callback, NULL);
+
+      Py_DECREF(callback);
+
+      if (value)
+      {
+        // We use setattr so that special dunder methods will be properly set.
+
+        if (PyObject_SetAttr((PyObject *)object, wrapped_str, value) == -1)
+        {
+          Py_DECREF(value);
+          return -1;
+        }
+
+        Py_DECREF(value);
+
+        return 0;
+      }
+      else
+      {
+        return -1;
+      }
+    }
+    else
+    {
+      Py_DECREF(callback);
+    }
+  }
+  else
+  {
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+      return -1;
+    PyErr_Clear();
+  }
+
+  if (object->init_called)
+  {
+    PyErr_SetString(state->WrapperNotInitializedError,
+                    "wrapper is in an inconsistent state: __wrapped__ is not set");
+  }
+  else
+  {
+    PyErr_Format(PyExc_AttributeError,
+                 "'%.100s' object has no attribute '__wrapped__'",
+                 Py_TYPE(object)->tp_name);
+  }
+
+  return -1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Check that a wrapper specific field, as acquired by the caller, is not
+ * NULL, raising an error if it is. The additional fields of a partial or
+ * function wrapper are only ever set by __init__(), and together, so one
+ * being NULL means __init__() was never called, or did not complete. That
+ * is possible where a derived class overrides __init__() without calling
+ * that of the base class, or where an instance is created using __new__()
+ * alone, and __wrapped__ is then assigned directly such that the check for
+ * an uninitialized wrapper passes. An AttributeError naming the attribute
+ * by which the field is exposed is raised, that being what the pure Python
+ * implementation yields, since it holds the same state as instance
+ * attributes, which in this situation do not exist. */
+
+static inline int wrapt_require_field(PyObject *object, PyObject *value,
+                                      const char *name)
+{
+  if (value)
+    return 0;
+
+  PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%s'",
+               Py_TYPE(object)->tp_name, name);
+
+  return -1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Replace *op with a strong reference to the value to actually operate
+ * on: the wrapped object if *op is a wrapt proxy, else *op itself. On
+ * success the caller owns a reference to the replacement value and must
+ * release it after use. Returns -1 with an exception set, and *op
+ * unchanged, if *op is an uninitialized proxy which could not be
+ * lazily initialized. */
+
+static int wrapt_unwrap_operand(PyObject **op)
+{
+  WraptObjectProxyObject *proxy;
+  PyObject *wrapped;
+
+  if (!wrapt_is_proxy(*op))
+  {
+    Py_INCREF(*op);
+    return 0;
+  }
+
+  proxy = (WraptObjectProxyObject *)*op;
+
+  if (!proxy->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(proxy) == -1)
+      return -1;
+  }
+
+  wrapped = wrapt_acquire_wrapped(proxy);
+
+  if (!wrapped)
+  {
+    PyErr_Format(PyExc_AttributeError,
+                 "'%.100s' object has no attribute '__wrapped__'",
+                 Py_TYPE(proxy)->tp_name);
+    return -1;
+  }
+
+  *op = wrapped;
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_new(PyTypeObject *type, PyObject *args,
+                                      PyObject *kwds)
+{
+  WraptObjectProxyObject *self;
+
+  self = (WraptObjectProxyObject *)type->tp_alloc(type, 0);
+
+  if (!self)
+    return NULL;
+
+  self->dict = PyDict_New();
+
+  if (!self->dict)
+  {
+    Py_DECREF(self);
+    return NULL;
+  }
+
+  self->wrapped = NULL;
+  self->weakreflist = NULL;
+  self->init_called = 0;
+
+  return (PyObject *)self;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_raw_init(WraptObjectProxyObject *self,
+                                     PyObject *wrapped)
+{
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *module_str = state->str_module;
+  PyObject *doc_str = state->str_doc;
+  PyObject *wrapped_factory_str = state->str_wrapped_factory;
+
+  PyObject *object = NULL;
+
+  // If wrapped is Py_None and we have a __wrapped_factory__ attribute
+  // then we defer initialization of the wrapped object until it is first needed.
+
+  if (wrapped == Py_None)
+  {
+    PyObject *callback = NULL;
+
+    callback = PyObject_GenericGetAttr((PyObject *)self, wrapped_factory_str);
+
+    if (callback)
+    {
+      if (callback != Py_None)
+      {
+        Py_DECREF(callback);
+        self->init_called = 1;
+        return 0;
+      }
+      else
+      {
+        Py_DECREF(callback);
+      }
+    }
+    else
+    {
+      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+        return -1;
+      PyErr_Clear();
+    }
+  }
+
+  /* Serialise the swap for the same reason as in the __wrapped__ setter.
+   * Normally __init__ runs before the proxy is shared, but it can be
+   * re-invoked on an already published proxy, in which case concurrent
+   * callers on a free-threaded build could otherwise decref the same old
+   * wrapped object twice. */
+
+  Py_INCREF(wrapped);
+  Py_BEGIN_CRITICAL_SECTION(self);
+  Py_XSETREF(self->wrapped, wrapped);
+  Py_END_CRITICAL_SECTION();
+
+  self->init_called = 1;
+
+  object = PyObject_GetAttr(wrapped, module_str);
+
+  if (object)
+  {
+    if (PyDict_SetItem(self->dict, module_str, object) == -1)
+    {
+      Py_DECREF(object);
+      return -1;
+    }
+    Py_DECREF(object);
+  }
+  else
+  {
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+      return -1;
+    PyErr_Clear();
+  }
+
+  object = PyObject_GetAttr(wrapped, doc_str);
+
+  if (object)
+  {
+    if (PyDict_SetItem(self->dict, doc_str, object) == -1)
+    {
+      Py_DECREF(object);
+      return -1;
+    }
+    Py_DECREF(object);
+  }
+  else
+  {
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+      return -1;
+    PyErr_Clear();
+  }
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_init(WraptObjectProxyObject *self, PyObject *args,
+                                 PyObject *kwds)
+{
+  PyObject *wrapped = NULL;
+
+  char *const kwlist[] = {"wrapped", NULL};
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:ObjectProxy", kwlist,
+                                   &wrapped))
+  {
+    return -1;
+  }
+
+  return WraptObjectProxy_raw_init(self, wrapped);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_traverse(WraptObjectProxyObject *self,
+                                     visitproc visit, void *arg)
+{
+  Py_VISIT(Py_TYPE(self));
+  Py_VISIT(self->dict);
+  Py_VISIT(self->wrapped);
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_clear(WraptObjectProxyObject *self)
+{
+  Py_CLEAR(self->dict);
+  Py_CLEAR(self->wrapped);
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void WraptObjectProxy_dealloc(WraptObjectProxyObject *self)
+{
+  PyTypeObject *tp = Py_TYPE(self);
+
+  PyObject_GC_UnTrack(self);
+
+  if (self->weakreflist != NULL)
+    PyObject_ClearWeakRefs((PyObject *)self);
+
+  WraptObjectProxy_clear(self);
+
+  tp->tp_free(self);
+
+#if PY_VERSION_HEX >= 0x030C0000
+  PyObject *exc = PyErr_GetRaisedException();
+  Py_DECREF(tp);
+  PyErr_SetRaisedException(exc);
+#else
+  PyObject *exc_type, *exc_value, *exc_tb;
+  PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
+  Py_DECREF(tp);
+  PyErr_Restore(exc_type, exc_value, exc_tb);
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_repr(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  char self_addr[24], wrapped_addr[24];
+  snprintf(self_addr, sizeof(self_addr), "0x%zx", (Py_uintptr_t)self);
+  snprintf(wrapped_addr, sizeof(wrapped_addr), "0x%zx",
+           (Py_uintptr_t)wrapped);
+  PyObject *result = PyUnicode_FromFormat("<%s at %s for %s at %s>",
+                                          Py_TYPE(self)->tp_name, self_addr,
+                                          Py_TYPE(wrapped)->tp_name,
+                                          wrapped_addr);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static Py_hash_t WraptObjectProxy_hash(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  Py_hash_t result = PyObject_Hash(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_str(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_Str(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_add(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Add(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_subtract(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Subtract(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_multiply(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Multiply(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_remainder(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Remainder(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_divmod(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Divmod(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_power(PyObject *o1, PyObject *o2,
+                                        PyObject *modulo)
+{
+  /*
+   * If modulo is a proxy we cannot call PyNumber_Power with it, otherwise
+   * we would recurse back into this slot via CPython's ternary_op fallback
+   * and blow the C stack. Return NotImplemented so a TypeError is raised,
+   * matching the pure Python implementation which does not unwrap modulo.
+   */
+
+  if (wrapt_is_proxy(modulo))
+  {
+    Py_RETURN_NOTIMPLEMENTED;
+  }
+
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Power(o1, o2, modulo);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_negative(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyNumber_Negative(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_positive(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyNumber_Positive(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_absolute(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyNumber_Absolute(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_bool(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result = PyObject_IsTrue(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_invert(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyNumber_Invert(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_lshift(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Lshift(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_rshift(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Rshift(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_and(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_And(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_xor(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Xor(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_or(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_Or(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_long(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyNumber_Long(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_float(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyNumber_Float(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_add(WraptObjectProxyObject *self,
+                                              PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__iadd__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceAdd(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    /* As in the __wrapped__ setter, serialise the swap so that concurrent
+     * in-place operations on the same proxy cannot decref the same old
+     * wrapped object twice on a free-threaded build. The wrapped object
+     * was read before the operation ran, so a concurrent mutation can
+     * still be lost, matching pure Python semantics. The same applies to
+     * all of the in-place operators which follow. */
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Add(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_subtract(WraptObjectProxyObject *self,
+                                                   PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__isub__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceSubtract(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Subtract(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_multiply(WraptObjectProxyObject *self,
+                                                   PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__imul__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceMultiply(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Multiply(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptObjectProxy_inplace_remainder(WraptObjectProxyObject *self,
+                                   PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__imod__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceRemainder(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Remainder(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_power(WraptObjectProxyObject *self,
+                                                PyObject *other,
+                                                PyObject *modulo)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__ipow__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlacePower(wrapped, other, modulo);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Power(wrapped, other, modulo);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_lshift(WraptObjectProxyObject *self,
+                                                 PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__ilshift__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceLshift(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Lshift(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_rshift(WraptObjectProxyObject *self,
+                                                 PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__irshift__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceRshift(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Rshift(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_and(WraptObjectProxyObject *self,
+                                              PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__iand__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceAnd(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_And(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_xor(WraptObjectProxyObject *self,
+                                              PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__ixor__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceXor(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Xor(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_or(WraptObjectProxyObject *self,
+                                             PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__ior__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceOr(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_Or(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_floor_divide(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_FloorDivide(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_true_divide(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_TrueDivide(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptObjectProxy_inplace_floor_divide(WraptObjectProxyObject *self,
+                                      PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__ifloordiv__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceFloorDivide(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_FloorDivide(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptObjectProxy_inplace_true_divide(WraptObjectProxyObject *self,
+                                     PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__itruediv__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceTrueDivide(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_TrueDivide(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_index(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyNumber_Index(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_matrix_multiply(PyObject *o1, PyObject *o2)
+{
+  if (wrapt_unwrap_operand(&o1) == -1)
+    return NULL;
+
+  if (wrapt_unwrap_operand(&o2) == -1)
+  {
+    Py_DECREF(o1);
+    return NULL;
+  }
+
+  PyObject *result = PyNumber_MatrixMultiply(o1, o2);
+
+  Py_DECREF(o1);
+  Py_DECREF(o2);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_inplace_matrix_multiply(
+    WraptObjectProxyObject *self, PyObject *other)
+{
+  PyObject *object = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (wrapt_unwrap_operand(&other) == -1)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *attr;
+  int rc = PyObject_GetOptionalAttrString(wrapped, "__imatmul__", &attr);
+  Py_XDECREF(attr);
+  if (rc < 0)
+  {
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+    return NULL;
+  }
+  if (rc)
+  {
+    object = PyNumber_InPlaceMatrixMultiply(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!object)
+      return NULL;
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_SETREF(self->wrapped, object);
+    Py_END_CRITICAL_SECTION();
+
+    Py_INCREF(self);
+    return (PyObject *)self;
+  }
+  else
+  {
+    PyObject *result = PyNumber_MatrixMultiply(wrapped, other);
+
+    Py_DECREF(wrapped);
+    Py_DECREF(other);
+
+    if (!result)
+      return NULL;
+
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
+
+    if (!proxy_type)
+    {
+      Py_DECREF(result);
+      return NULL;
+    }
+
+    PyObject *proxy_args = PyTuple_Pack(1, result);
+
+    Py_DECREF(result);
+
+    if (!proxy_args)
+    {
+      Py_DECREF(proxy_type);
+      return NULL;
+    }
+
+    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
+
+    Py_DECREF(proxy_type);
+    Py_DECREF(proxy_args);
+
+    return proxy_instance;
+  }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static Py_ssize_t WraptObjectProxy_length(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  Py_ssize_t result = PyObject_Length(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_contains(WraptObjectProxyObject *self,
+                                     PyObject *value)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result = PySequence_Contains(wrapped, value);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_getitem(WraptObjectProxyObject *self,
+                                          PyObject *key)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetItem(wrapped, key);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_setitem(WraptObjectProxyObject *self, PyObject *key,
+                                    PyObject *value)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result;
+
+  if (value == NULL)
+    result = PyObject_DelItem(wrapped, key);
+  else
+    result = PyObject_SetItem(wrapped, key, value);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_self_setattr(WraptObjectProxyObject *self,
+                                               PyObject *args)
+{
+  PyObject *name = NULL;
+  PyObject *value = NULL;
+
+  if (!PyArg_ParseTuple(args, "UO:__self_setattr__", &name, &value))
+    return NULL;
+
+  if (PyObject_GenericSetAttr((PyObject *)self, name, value) != 0)
+  {
+    return NULL;
+  }
+
+  Py_RETURN_NONE;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_dir(WraptObjectProxyObject *self,
+                                      PyObject *args)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_Dir(wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_enter(WraptObjectProxyObject *self,
+                                        PyObject *args, PyObject *kwds)
+{
+  PyObject *method = NULL;
+  PyObject *result = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  method = PyObject_GetAttr(wrapped, state->str_enter);
+
+  Py_DECREF(wrapped);
+
+  if (!method)
+    return NULL;
+
+  result = PyObject_Call(method, args, kwds);
+
+  Py_DECREF(method);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_exit(WraptObjectProxyObject *self,
+                                       PyObject *args, PyObject *kwds)
+{
+  PyObject *method = NULL;
+  PyObject *result = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  method = PyObject_GetAttr(wrapped, state->str_exit);
+
+  Py_DECREF(wrapped);
+
+  if (!method)
+    return NULL;
+
+  result = PyObject_Call(method, args, kwds);
+
+  Py_DECREF(method);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_aenter(WraptObjectProxyObject *self,
+                                         PyObject *args, PyObject *kwds)
+{
+  PyObject *method = NULL;
+  PyObject *result = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  method = PyObject_GetAttr(wrapped, state->str_aenter);
+
+  Py_DECREF(wrapped);
+
+  if (!method)
+    return NULL;
+
+  result = PyObject_Call(method, args, kwds);
+
+  Py_DECREF(method);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_aexit(WraptObjectProxyObject *self,
+                                        PyObject *args, PyObject *kwds)
+{
+  PyObject *method = NULL;
+  PyObject *result = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  method = PyObject_GetAttr(wrapped, state->str_aexit);
+
+  Py_DECREF(wrapped);
+
+  if (!method)
+    return NULL;
+
+  result = PyObject_Call(method, args, kwds);
+
+  Py_DECREF(method);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_copy(WraptObjectProxyObject *self,
+                                       PyObject *Py_UNUSED(ignored))
+{
+  PyErr_SetString(PyExc_NotImplementedError,
+                  "object proxy must define __copy__()");
+
+  return NULL;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_deepcopy(WraptObjectProxyObject *self,
+                                           PyObject *args, PyObject *kwds)
+{
+  PyErr_SetString(PyExc_NotImplementedError,
+                  "object proxy must define __deepcopy__()");
+
+  return NULL;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_reduce(WraptObjectProxyObject *self,
+                                         PyObject *Py_UNUSED(ignored))
+{
+  PyErr_SetString(PyExc_NotImplementedError,
+                  "object proxy must define __reduce__()");
+
+  return NULL;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_bytes(WraptObjectProxyObject *self,
+                                        PyObject *args)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_CallFunctionObjArgs((PyObject *)&PyBytes_Type,
+                                                  wrapped, NULL);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_format(WraptObjectProxyObject *self,
+                                         PyObject *args)
+{
+  PyObject *format_spec = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (!PyArg_ParseTuple(args, "O:format", &format_spec))
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_Format(wrapped, format_spec);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_reversed(WraptObjectProxyObject *self,
+                                           PyObject *args)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_CallFunctionObjArgs((PyObject *)&PyReversed_Type,
+                                                  wrapped, NULL);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_round(WraptObjectProxyObject *self,
+                                        PyObject *args, PyObject *kwds)
+{
+  PyObject *ndigits = NULL;
+
+  PyObject *module = NULL;
+  PyObject *round = NULL;
+
+  PyObject *result = NULL;
+
+  char *const kwlist[] = {"ndigits", NULL};
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:ObjectProxy", kwlist,
+                                   &ndigits))
+  {
+    return NULL;
+  }
+
+  module = PyImport_ImportModule("builtins");
+
+  if (!module)
+    return NULL;
+
+  round = PyObject_GetAttrString(module, "round");
+
+  if (!round)
+  {
+    Py_DECREF(module);
+    return NULL;
+  }
+
+  Py_DECREF(module);
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  result = PyObject_CallFunctionObjArgs(round, wrapped, ndigits, NULL);
+
+  Py_DECREF(wrapped);
+  Py_DECREF(round);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *wrapt_call_math_unary(WraptObjectProxyObject *self,
+                                       const char *name)
+{
+  PyObject *module = NULL;
+  PyObject *function = NULL;
+  PyObject *result = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  module = PyImport_ImportModule("math");
+
+  if (!module)
+    return NULL;
+
+  function = PyObject_GetAttrString(module, name);
+
+  if (!function)
+  {
+    Py_DECREF(module);
+    return NULL;
+  }
+
+  Py_DECREF(module);
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  result = PyObject_CallFunctionObjArgs(function, wrapped, NULL);
+
+  Py_DECREF(wrapped);
+  Py_DECREF(function);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_trunc(WraptObjectProxyObject *self,
+                                        PyObject *Py_UNUSED(ignored))
+{
+  return wrapt_call_math_unary(self, "trunc");
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_floor(WraptObjectProxyObject *self,
+                                        PyObject *Py_UNUSED(ignored))
+{
+  return wrapt_call_math_unary(self, "floor");
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_ceil(WraptObjectProxyObject *self,
+                                       PyObject *Py_UNUSED(ignored))
+{
+  return wrapt_call_math_unary(self, "ceil");
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_complex(WraptObjectProxyObject *self,
+                                          PyObject *args)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_CallFunctionObjArgs((PyObject *)&PyComplex_Type,
+                                                  wrapped, NULL);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_mro_entries(WraptObjectProxyObject *self,
+                                              PyObject *args, PyObject *kwds)
+{
+  PyObject *wrapped = NULL;
+  PyObject *mro_entries_method = NULL;
+  PyObject *result = NULL;
+  int is_type = 0;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapped = wrapt_acquire_wrapped(self);
+
+  // Check if wrapped is a type (class).
+
+  is_type = PyType_Check(wrapped);
+
+  // If wrapped is not a type and has __mro_entries__, forward to it.
+
+  if (!is_type)
+  {
+    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+    if (!state)
+    {
+      Py_DECREF(wrapped);
+      return NULL;
+    }
+
+    mro_entries_method = PyObject_GetAttr(wrapped, state->str_mro_entries);
+
+    if (mro_entries_method)
+    {
+      // Call wrapped.__mro_entries__(bases).
+
+      result = PyObject_Call(mro_entries_method, args, kwds);
+
+      Py_DECREF(mro_entries_method);
+      Py_DECREF(wrapped);
+
+      return result;
+    }
+    else
+    {
+      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+      {
+        Py_DECREF(wrapped);
+        return NULL;
+      }
+      PyErr_Clear();
+    }
+  }
+
+  result = Py_BuildValue("(O)", wrapped);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_name(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetAttr(wrapped, state->str_name);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_set_name(WraptObjectProxyObject *self,
+                                     PyObject *value)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result = PyObject_SetAttr(wrapped, state->str_name, value);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_qualname(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetAttr(wrapped, state->str_qualname);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_set_qualname(WraptObjectProxyObject *self,
+                                         PyObject *value)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result = PyObject_SetAttr(wrapped, state->str_qualname, value);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_module(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetAttr(wrapped, state->str_module);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Refresh the copy of __module__ or __doc__ held in the proxy's own dict
+ * after the attribute has been deleted from the wrapped object. Deleting
+ * __doc__ from a function, for example, leaves the attribute present with
+ * a value of None, whereas on other objects it may be gone entirely. Record
+ * what __init__ would have for a fresh proxy over the wrapped object in its
+ * current state: the value if the attribute still exists, otherwise no
+ * entry at all. */
+
+static int WraptObjectProxy_refresh_cached_attr(WraptObjectProxyObject *self,
+                                                PyObject *wrapped,
+                                                PyObject *name)
+{
+  PyObject *object = PyObject_GetAttr(wrapped, name);
+
+  if (object)
+  {
+    int result = PyDict_SetItem(self->dict, name, object);
+    Py_DECREF(object);
+    return result;
+  }
+
+  if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+    return -1;
+
+  PyErr_Clear();
+
+  if (PyDict_DelItem(self->dict, name) == -1)
+  {
+    if (!PyErr_ExceptionMatches(PyExc_KeyError))
+      return -1;
+    PyErr_Clear();
+  }
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* The setters for __module__ and __doc__ are called with a NULL value when
+ * the attribute is being deleted. PyObject_SetAttr() forwards a deletion to
+ * the wrapped object, but the copy held in the proxy's own dict must then be
+ * refreshed rather than stored, as the dict API rejects a NULL value. */
+
+static int WraptObjectProxy_set_module(WraptObjectProxyObject *self,
+                                       PyObject *value)
+{
+  int result;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  if (PyObject_SetAttr(wrapped, state->str_module, value) == -1)
+    result = -1;
+  else if (value)
+    result = PyDict_SetItem(self->dict, state->str_module, value);
+  else
+    result = WraptObjectProxy_refresh_cached_attr(self, wrapped,
+                                                  state->str_module);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_doc(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetAttr(wrapped, state->str_doc);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_set_doc(WraptObjectProxyObject *self,
+                                    PyObject *value)
+{
+  int result;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  if (PyObject_SetAttr(wrapped, state->str_doc, value) == -1)
+    result = -1;
+  else if (value)
+    result = PyDict_SetItem(self->dict, state->str_doc, value);
+  else
+    result = WraptObjectProxy_refresh_cached_attr(self, wrapped,
+                                                  state->str_doc);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_class(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetAttr(wrapped, state->str_dunder_class);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_set_class(WraptObjectProxyObject *self,
+                                      PyObject *value)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result = PyObject_SetAttr(wrapped, state->str_dunder_class, value);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptObjectProxy_get_annotations(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetAttr(wrapped, state->str_annotations);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_set_annotations(WraptObjectProxyObject *self,
+                                            PyObject *value)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result = PyObject_SetAttr(wrapped, state->str_annotations, value);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_dict(WraptObjectProxyObject *self)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_GetAttr(wrapped, state->str_dict);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_set_dict(WraptObjectProxyObject *self,
+                                     PyObject *value)
+{
+  if (!value)
+  {
+    PyErr_SetString(PyExc_AttributeError,
+                    "property '__dict__' of 'ObjectProxy' object has no deleter");
+    return -1;
+  }
+
+  PyErr_SetString(PyExc_AttributeError,
+                  "property '__dict__' of 'ObjectProxy' object has no setter");
+  return -1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_self_dict(WraptObjectProxyObject *self)
+{
+  PyObject *result = NULL;
+
+  /* self->dict is only NULL after tp_clear has run. Perform the lazy
+   * recreation and the reference acquisition inside a critical section
+   * so that two threads racing here on a free-threaded build cannot both
+   * create a dict, leaking one of them, or return a dict which the other
+   * thread has already replaced. */
+
+  Py_BEGIN_CRITICAL_SECTION(self);
+  if (!self->dict)
+    self->dict = PyDict_New();
+  result = self->dict;
+  Py_XINCREF(result);
+  Py_END_CRITICAL_SECTION();
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_wrapped(WraptObjectProxyObject *self)
+{
+  PyObject *value = NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  value = wrapt_acquire_wrapped(self);
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_get_object_proxy(WraptObjectProxyObject *self)
+{
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+  Py_INCREF(state->ObjectProxy_Type);
+  return (PyObject *)state->ObjectProxy_Type;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_set_wrapped(WraptObjectProxyObject *self,
+                                        PyObject *value)
+{
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *fixups = NULL;
+
+  if (!value)
+  {
+    PyErr_SetString(PyExc_TypeError, "can't delete __wrapped__ attribute");
+    return -1;
+  }
+
+  /* On free-threaded builds the swap must be serialised, otherwise two
+   * threads assigning __wrapped__ on the same proxy can both read the same
+   * old value and both decref it, releasing it twice. The critical section
+   * covers only the swap; __wrapped_setattr_fixups__ below runs arbitrary
+   * Python code and must stay outside it. */
+
+  Py_INCREF(value);
+  Py_BEGIN_CRITICAL_SECTION(self);
+  Py_XSETREF(self->wrapped, value);
+  Py_END_CRITICAL_SECTION();
+
+  fixups = PyObject_GetAttr((PyObject *)self, state->str_setattr_fixups);
+
+  if (fixups)
+  {
+    PyObject *result = NULL;
+
+    result = PyObject_CallObject(fixups, NULL);
+    Py_DECREF(fixups);
+
+    if (!result)
+      return -1;
+
+    Py_DECREF(result);
+  }
+  else
+  {
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+      return -1;
+    PyErr_Clear();
+  }
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_getattro(WraptObjectProxyObject *self,
+                                           PyObject *name)
+{
+  PyObject *object = NULL;
+  PyObject *result = NULL;
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  /* Intercept __module__ and __doc__ so they proxy to the wrapped object.
+   * These cannot be getset descriptors on heap types because that would
+   * place a descriptor object in tp_dict, shadowing the type-level
+   * __module__/__doc__ strings that type.__module__ reads via raw dict
+   * lookup. */
+
+  if (wrapt_name_equals(name, state->str_module))
+    return WraptObjectProxy_get_module(self);
+  if (wrapt_name_equals(name, state->str_doc))
+  {
+    /* A derived class may define its own __doc__ descriptor, in which
+     * case that is consulted in place of the wrapped object. */
+
+    PyObject *descriptor = wrapt_lookup_doc_descriptor(Py_TYPE(self), name);
+
+    if (descriptor)
+    {
+      result = (Py_TYPE(descriptor)->tp_descr_get)(
+          descriptor, (PyObject *)self, (PyObject *)Py_TYPE(self));
+      Py_DECREF(descriptor);
+      return result;
+    }
+
+    return WraptObjectProxy_get_doc(self);
+  }
+
+  object = PyObject_GenericGetAttr((PyObject *)self, name);
+
+  if (object)
+    return object;
+
+  if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+    return NULL;
+
+  PyErr_Clear();
+
+  object = PyObject_GenericGetAttr((PyObject *)self, state->str_getattr);
+
+  if (!object)
+    return NULL;
+
+  result = PyObject_CallFunctionObjArgs(object, name, NULL);
+
+  Py_DECREF(object);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_getattr(WraptObjectProxyObject *self,
+                                          PyObject *args)
+{
+  PyObject *name = NULL;
+  PyObject *wrapped = NULL;
+  PyObject *result = NULL;
+
+  if (!PyArg_ParseTuple(args, "U:__getattr__", &name))
+    return NULL;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  /* Hold a strong reference across the attribute lookup so a concurrent
+   * swap of the wrapped object cannot release it mid lookup. Note this
+   * path is reached from the __wrapped__ setter itself via the lookup
+   * of __wrapped_setattr_fixups__, so even a workload consisting purely
+   * of writers performs this read. */
+
+  wrapped = wrapt_acquire_wrapped(self);
+
+  result = PyObject_GetAttr(wrapped, name);
+
+  Py_XDECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptObjectProxy_setattro(WraptObjectProxyObject *self,
+                                     PyObject *name, PyObject *value)
+{
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  int match = PyUnicode_Tailmatch(name, state->str_self_, 0, PY_SSIZE_T_MAX, -1);
+
+  if (match < 0)
+    return -1;
+
+  if (match)
+    return PyObject_GenericSetAttr((PyObject *)self, name, value);
+
+  /* Intercept __module__ and __doc__ so they forward to the wrapped
+   * object rather than being stored locally. Without this, the string
+   * values in the type dict (from PyType_FromModuleAndSpec) would cause
+   * wrapt_type_has_attr to match and GenericSetAttr to store locally. */
+
+  if (wrapt_name_equals(name, state->str_module))
+    return WraptObjectProxy_set_module(self, value);
+  if (wrapt_name_equals(name, state->str_doc))
+  {
+    /* A derived class may define its own __doc__ descriptor, in which
+     * case assignment and deletion go to it rather than being forwarded
+     * to the wrapped object. A descriptor without __set__ is stored
+     * against the instance as generic attribute assignment would. */
+
+    PyObject *descriptor = wrapt_lookup_doc_descriptor(Py_TYPE(self), name);
+
+    if (descriptor)
+    {
+      int result;
+
+      if (Py_TYPE(descriptor)->tp_descr_set)
+        result = (Py_TYPE(descriptor)->tp_descr_set)(descriptor,
+                                                     (PyObject *)self, value);
+      else
+        result = PyObject_GenericSetAttr((PyObject *)self, name, value);
+
+      Py_DECREF(descriptor);
+      return result;
+    }
+
+    return WraptObjectProxy_set_doc(self, value);
+  }
+
+  if (wrapt_type_has_attr(Py_TYPE(self), name))
+    return PyObject_GenericSetAttr((PyObject *)self, name, value);
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return -1;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  int result = PyObject_SetAttr(wrapped, name, value);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptObjectProxy_richcompare(WraptObjectProxyObject *self,
+                                              PyObject *other, int opcode)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_RichCompare(wrapped, other, opcode);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptObjectProxy_instancecheck(WraptObjectProxyObject *self,
+                               PyObject *instance)
+{
+  int check = 0;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  check = PyObject_IsInstance(instance, wrapped);
+
+  Py_DECREF(wrapped);
+
+  if (check < 0)
+  {
+    return NULL;
+  }
+
+  return PyBool_FromLong(check);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptObjectProxy_subclasscheck(WraptObjectProxyObject *self,
+                               PyObject *args)
+{
+  PyObject *subclass = NULL;
+  PyObject *object = NULL;
+
+  int check = 0;
+
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  if (!PyArg_ParseTuple(args, "O", &subclass))
+    return NULL;
+
+  wrapt_module_state *state =
+      wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  object = PyObject_GetAttr(subclass, state->str_wrapped);
+
+  if (!object)
+  {
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+      return NULL;
+    PyErr_Clear();
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  check = PyObject_IsSubclass(object ? object : subclass, wrapped);
+
+  Py_DECREF(wrapped);
+  Py_XDECREF(object);
+
+  if (check == -1)
+    return NULL;
+
+  return PyBool_FromLong(check);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyMethodDef WraptObjectProxy_methods[] = {
+    {"__self_setattr__", (PyCFunction)WraptObjectProxy_self_setattr,
+     METH_VARARGS, 0},
+    {"__dir__", (PyCFunction)WraptObjectProxy_dir, METH_NOARGS, 0},
+    {"__enter__", (PyCFunction)WraptObjectProxy_enter,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {"__exit__", (PyCFunction)WraptObjectProxy_exit,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {"__aenter__", (PyCFunction)WraptObjectProxy_aenter,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {"__aexit__", (PyCFunction)WraptObjectProxy_aexit,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {"__copy__", (PyCFunction)WraptObjectProxy_copy, METH_NOARGS, 0},
+    {"__deepcopy__", (PyCFunction)WraptObjectProxy_deepcopy,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {"__reduce__", (PyCFunction)WraptObjectProxy_reduce, METH_NOARGS, 0},
+    {"__getattr__", (PyCFunction)WraptObjectProxy_getattr, METH_VARARGS, 0},
+    {"__bytes__", (PyCFunction)WraptObjectProxy_bytes, METH_NOARGS, 0},
+    {"__format__", (PyCFunction)WraptObjectProxy_format, METH_VARARGS, 0},
+    {"__reversed__", (PyCFunction)WraptObjectProxy_reversed, METH_NOARGS, 0},
+    {"__round__", (PyCFunction)WraptObjectProxy_round,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {"__trunc__", (PyCFunction)WraptObjectProxy_trunc, METH_NOARGS, 0},
+    {"__floor__", (PyCFunction)WraptObjectProxy_floor, METH_NOARGS, 0},
+    {"__ceil__", (PyCFunction)WraptObjectProxy_ceil, METH_NOARGS, 0},
+    {"__complex__", (PyCFunction)WraptObjectProxy_complex, METH_NOARGS, 0},
+    {"__mro_entries__", (PyCFunction)WraptObjectProxy_mro_entries,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {"__instancecheck__", (PyCFunction)WraptObjectProxy_instancecheck,
+     METH_O, 0},
+    {"__subclasscheck__", (PyCFunction)WraptObjectProxy_subclasscheck,
+     METH_VARARGS, 0},
+    {"__class_getitem__", Py_GenericAlias, METH_O | METH_CLASS, 0},
+    {NULL, NULL},
+};
+
+static PyGetSetDef WraptObjectProxy_getset[] = {
+    {"__name__", (getter)WraptObjectProxy_get_name,
+     (setter)WraptObjectProxy_set_name, 0},
+    {"__qualname__", (getter)WraptObjectProxy_get_qualname,
+     (setter)WraptObjectProxy_set_qualname, 0},
+    {"__class__", (getter)WraptObjectProxy_get_class,
+     (setter)WraptObjectProxy_set_class, 0},
+    {"__annotations__", (getter)WraptObjectProxy_get_annotations,
+     (setter)WraptObjectProxy_set_annotations, 0},
+    {"__dict__", (getter)WraptObjectProxy_get_dict,
+     (setter)WraptObjectProxy_set_dict, 0},
+    {"__self_dict__", (getter)WraptObjectProxy_get_self_dict, 0, 0},
+    {"__wrapped__", (getter)WraptObjectProxy_get_wrapped,
+     (setter)WraptObjectProxy_set_wrapped, 0},
+    {"__object_proxy__", (getter)WraptObjectProxy_get_object_proxy, 0, 0},
+    {NULL},
+};
+
+static PyMemberDef WraptObjectProxy_members[] = {
+    {"__dictoffset__", T_PYSSIZET,
+     offsetof(WraptObjectProxyObject, dict), READONLY, NULL},
+    {"__weaklistoffset__", T_PYSSIZET,
+     offsetof(WraptObjectProxyObject, weakreflist), READONLY, NULL},
+    {NULL},
+};
+
+static PyType_Slot WraptObjectProxy_slots[] = {
+    {Py_tp_dealloc, WraptObjectProxy_dealloc},
+    {Py_tp_repr, WraptObjectProxy_repr},
+    {Py_tp_hash, WraptObjectProxy_hash},
+    {Py_tp_str, WraptObjectProxy_str},
+    {Py_tp_getattro, WraptObjectProxy_getattro},
+    {Py_tp_setattro, WraptObjectProxy_setattro},
+    {Py_tp_traverse, WraptObjectProxy_traverse},
+    {Py_tp_clear, WraptObjectProxy_clear},
+    {Py_tp_richcompare, WraptObjectProxy_richcompare},
+    {Py_tp_methods, WraptObjectProxy_methods},
+    {Py_tp_members, WraptObjectProxy_members},
+    {Py_tp_getset, WraptObjectProxy_getset},
+    {Py_tp_init, WraptObjectProxy_init},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_new, WraptObjectProxy_new},
+    {Py_tp_free, PyObject_GC_Del},
+    /* PyNumberMethods */
+    {Py_nb_add, WraptObjectProxy_add},
+    {Py_nb_subtract, WraptObjectProxy_subtract},
+    {Py_nb_multiply, WraptObjectProxy_multiply},
+    {Py_nb_remainder, WraptObjectProxy_remainder},
+    {Py_nb_divmod, WraptObjectProxy_divmod},
+    {Py_nb_power, WraptObjectProxy_power},
+    {Py_nb_negative, WraptObjectProxy_negative},
+    {Py_nb_positive, WraptObjectProxy_positive},
+    {Py_nb_absolute, WraptObjectProxy_absolute},
+    {Py_nb_bool, WraptObjectProxy_bool},
+    {Py_nb_invert, WraptObjectProxy_invert},
+    {Py_nb_lshift, WraptObjectProxy_lshift},
+    {Py_nb_rshift, WraptObjectProxy_rshift},
+    {Py_nb_and, WraptObjectProxy_and},
+    {Py_nb_xor, WraptObjectProxy_xor},
+    {Py_nb_or, WraptObjectProxy_or},
+    {Py_nb_int, WraptObjectProxy_long},
+    {Py_nb_float, WraptObjectProxy_float},
+    {Py_nb_inplace_add, WraptObjectProxy_inplace_add},
+    {Py_nb_inplace_subtract, WraptObjectProxy_inplace_subtract},
+    {Py_nb_inplace_multiply, WraptObjectProxy_inplace_multiply},
+    {Py_nb_inplace_remainder, WraptObjectProxy_inplace_remainder},
+    {Py_nb_inplace_power, WraptObjectProxy_inplace_power},
+    {Py_nb_inplace_lshift, WraptObjectProxy_inplace_lshift},
+    {Py_nb_inplace_rshift, WraptObjectProxy_inplace_rshift},
+    {Py_nb_inplace_and, WraptObjectProxy_inplace_and},
+    {Py_nb_inplace_xor, WraptObjectProxy_inplace_xor},
+    {Py_nb_inplace_or, WraptObjectProxy_inplace_or},
+    {Py_nb_floor_divide, WraptObjectProxy_floor_divide},
+    {Py_nb_true_divide, WraptObjectProxy_true_divide},
+    {Py_nb_inplace_floor_divide, WraptObjectProxy_inplace_floor_divide},
+    {Py_nb_inplace_true_divide, WraptObjectProxy_inplace_true_divide},
+    {Py_nb_index, WraptObjectProxy_index},
+    {Py_nb_matrix_multiply, WraptObjectProxy_matrix_multiply},
+    {Py_nb_inplace_matrix_multiply, WraptObjectProxy_inplace_matrix_multiply},
+    /* PySequenceMethods */
+    {Py_sq_length, WraptObjectProxy_length},
+    {Py_sq_contains, WraptObjectProxy_contains},
+    /* PyMappingMethods */
+    {Py_mp_length, WraptObjectProxy_length},
+    {Py_mp_subscript, WraptObjectProxy_getitem},
+    {Py_mp_ass_subscript, WraptObjectProxy_setitem},
+    {0, NULL},
+};
+
+static PyType_Spec WraptObjectProxy_spec = {
+    .name = "_wrappers.ObjectProxy",
+    .basicsize = sizeof(WraptObjectProxyObject),
+    .itemsize = 0,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = WraptObjectProxy_slots,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptCallableObjectProxy_call(WraptObjectProxyObject *self,
+                                               PyObject *args, PyObject *kwds)
+{
+  if (!self->wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(self) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(self);
+
+  PyObject *result = PyObject_Call(wrapped, args, kwds);
+
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */;
+
+static PyType_Slot WraptCallableObjectProxy_slots[] = {
+    {Py_tp_dealloc, WraptObjectProxy_dealloc},
+    {Py_tp_traverse, WraptObjectProxy_traverse},
+    {Py_tp_clear, WraptObjectProxy_clear},
+    {Py_tp_call, WraptCallableObjectProxy_call},
+    {Py_tp_init, WraptObjectProxy_init},
+    {0, NULL},
+};
+
+static PyType_Spec WraptCallableObjectProxy_spec = {
+    .name = "_wrappers.CallableObjectProxy",
+    .basicsize = sizeof(WraptObjectProxyObject),
+    .itemsize = 0,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = WraptCallableObjectProxy_slots,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptPartialCallableObjectProxy_new(PyTypeObject *type,
+                                                     PyObject *args,
+                                                     PyObject *kwds)
+{
+  WraptPartialCallableObjectProxyObject *self;
+
+  self = (WraptPartialCallableObjectProxyObject *)WraptObjectProxy_new(
+      type, args, kwds);
+
+  if (!self)
+    return NULL;
+
+  self->args = NULL;
+  self->kwargs = NULL;
+
+  return (PyObject *)self;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptPartialCallableObjectProxy_raw_init(
+    WraptPartialCallableObjectProxyObject *self, PyObject *wrapped,
+    PyObject *args, PyObject *kwargs)
+{
+  int result = 0;
+
+  result = WraptObjectProxy_raw_init((WraptObjectProxyObject *)self, wrapped);
+
+  if (result == 0)
+  {
+    /* Serialise the swaps for the same reason as in the __wrapped__
+     * setter. Initialisation normally happens before the proxy is shared,
+     * but __init__ can be re-invoked on an already published proxy, in
+     * which case concurrent callers on a free-threaded build could
+     * otherwise decref the same old args or kwargs twice. */
+
+    Py_INCREF(args);
+    Py_XINCREF(kwargs);
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_XSETREF(self->args, args);
+    Py_XSETREF(self->kwargs, kwargs);
+    Py_END_CRITICAL_SECTION();
+  }
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptPartialCallableObjectProxy_init(
+    WraptPartialCallableObjectProxyObject *self, PyObject *args,
+    PyObject *kwds)
+{
+  PyObject *wrapped = NULL;
+  PyObject *fnargs = NULL;
+
+  int result = 0;
+
+  if (PyTuple_GET_SIZE(args) < 1)
+  {
+    PyErr_SetString(PyExc_TypeError, "__init__ of partial needs an argument");
+    return -1;
+  }
+
+  wrapped = PyTuple_GetItem(args, 0);
+
+  if (!PyCallable_Check(wrapped))
+  {
+    PyErr_SetString(PyExc_TypeError, "the first argument must be callable");
+    return -1;
+  }
+
+  fnargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
+
+  if (!fnargs)
+    return -1;
+
+  result =
+      WraptPartialCallableObjectProxy_raw_init(self, wrapped, fnargs, kwds);
+
+  Py_DECREF(fnargs);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptPartialCallableObjectProxy_traverse(
+    WraptPartialCallableObjectProxyObject *self, visitproc visit, void *arg)
+{
+  int err = WraptObjectProxy_traverse((WraptObjectProxyObject *)self, visit, arg);
+  if (err)
+    return err;
+
+  Py_VISIT(self->args);
+  Py_VISIT(self->kwargs);
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptPartialCallableObjectProxy_clear(
+    WraptPartialCallableObjectProxyObject *self)
+{
+  WraptObjectProxy_clear((WraptObjectProxyObject *)self);
+
+  Py_CLEAR(self->args);
+  Py_CLEAR(self->kwargs);
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void WraptPartialCallableObjectProxy_dealloc(
+    WraptPartialCallableObjectProxyObject *self)
+{
+  PyTypeObject *tp = Py_TYPE(self);
+
+  PyObject_GC_UnTrack(self);
+
+  if (self->object_proxy.weakreflist != NULL)
+    PyObject_ClearWeakRefs((PyObject *)self);
+
+  WraptPartialCallableObjectProxy_clear(self);
+
+  tp->tp_free(self);
+
+#if PY_VERSION_HEX >= 0x030C0000
+  PyObject *exc = PyErr_GetRaisedException();
+  Py_DECREF(tp);
+  PyErr_SetRaisedException(exc);
+#else
+  PyObject *exc_type, *exc_value, *exc_tb;
+  PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
+  Py_DECREF(tp);
+  PyErr_Restore(exc_type, exc_value, exc_tb);
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptPartialCallableObjectProxy_call(
+    WraptPartialCallableObjectProxyObject *self, PyObject *args,
+    PyObject *kwds)
+{
+  PyObject *fnargs = NULL;
+  PyObject *fnkwargs = NULL;
+
+  PyObject *result = NULL;
+
+  long i;
+  long offset;
+
+  if (!self->object_proxy.wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
+      return NULL;
+  }
+
+  /* Hold strong references to the wrapped object and the captured
+   * arguments across the call so a concurrent re-initialization of the
+   * partial cannot release them while they are in use. */
+
+  PyObject *wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+  PyObject *cargs = wrapt_acquire_field((PyObject *)self, &self->args);
+  PyObject *ckwargs = wrapt_acquire_field((PyObject *)self, &self->kwargs);
+
+  /* The captured keyword arguments are legitimately NULL when none were
+   * supplied, so only the captured positional arguments are required. */
+
+  if (wrapt_require_field((PyObject *)self, cargs, "_self_args") == -1)
+    goto finally;
+
+  fnargs = PyTuple_New(PyTuple_GET_SIZE(cargs) + PyTuple_GET_SIZE(args));
+
+  if (!fnargs)
+    goto finally;
+
+  for (i = 0; i < PyTuple_GET_SIZE(cargs); i++)
+  {
+    PyObject *item;
+    item = PyTuple_GetItem(cargs, i);
+    Py_INCREF(item);
+    PyTuple_SetItem(fnargs, i, item);
+  }
+
+  offset = PyTuple_GET_SIZE(cargs);
+
+  for (i = 0; i < PyTuple_GET_SIZE(args); i++)
+  {
+    PyObject *item;
+    item = PyTuple_GetItem(args, i);
+    Py_INCREF(item);
+    PyTuple_SetItem(fnargs, offset + i, item);
+  }
+
+  fnkwargs = PyDict_New();
+
+  if (!fnkwargs)
+    goto finally;
+
+  if (ckwargs && PyDict_Update(fnkwargs, ckwargs) == -1)
+    goto finally;
+
+  if (kwds && PyDict_Update(fnkwargs, kwds) == -1)
+    goto finally;
+
+  result = PyObject_Call(wrapped, fnargs, fnkwargs);
+
+finally:
+  Py_XDECREF(fnargs);
+  Py_XDECREF(fnkwargs);
+
+  Py_DECREF(wrapped);
+  Py_XDECREF(cargs);
+  Py_XDECREF(ckwargs);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */;
+
+static PyObject *WraptPartialCallableObjectProxy_get_self_args(
+    WraptPartialCallableObjectProxyObject *self, void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->args);
+
+  /* See the comment for the equivalent getters of the function wrapper
+   * as to why this fails rather than substituting an empty tuple. */
+
+  if (wrapt_require_field((PyObject *)self, value, "_self_args") == -1)
+    return NULL;
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptPartialCallableObjectProxy_get_self_kwargs(
+    WraptPartialCallableObjectProxyObject *self, void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->kwargs);
+
+  if (!value)
+  {
+    /* The captured keyword arguments are legitimately NULL when none were
+     * supplied, in which case an empty dictionary stands in for them. That
+     * must be distinguished from __init__() never having been called, for
+     * which the captured positional arguments, which are always set by
+     * __init__(), will be NULL as well. */
+
+    PyObject *args = wrapt_acquire_field((PyObject *)self, &self->args);
+
+    if (wrapt_require_field((PyObject *)self, args, "_self_kwargs") == -1)
+      return NULL;
+
+    Py_DECREF(args);
+
+    return PyDict_New();
+  }
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Report the signature of the wrapped callable with the bound positional
+ * and keyword arguments removed, matching what inspect.signature() reports
+ * for functools.partial. This is done by constructing an equivalent
+ * functools.partial and asking inspect for its signature, so that the
+ * result, including any ValueError for excess bound arguments, is exactly
+ * what functools.partial would give. */
+
+static PyObject *WraptPartialCallableObjectProxy_get_signature(
+    WraptPartialCallableObjectProxyObject *self)
+{
+  PyObject *module = NULL;
+  PyObject *function = NULL;
+  PyObject *fnargs = NULL;
+  PyObject *partial = NULL;
+  PyObject *result = NULL;
+
+  Py_ssize_t nargs = 0;
+  Py_ssize_t i;
+
+  if (!self->object_proxy.wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
+      return NULL;
+  }
+
+  PyObject *wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+  PyObject *cargs = wrapt_acquire_field((PyObject *)self, &self->args);
+  PyObject *ckwargs = wrapt_acquire_field((PyObject *)self, &self->kwargs);
+
+  if (cargs)
+    nargs = PyTuple_GET_SIZE(cargs);
+
+  /* Build the tuple (wrapped, *args) to pass to functools.partial(). */
+
+  fnargs = PyTuple_New(nargs + 1);
+
+  if (!fnargs)
+    goto finally;
+
+  Py_INCREF(wrapped);
+  PyTuple_SET_ITEM(fnargs, 0, wrapped);
+
+  for (i = 0; i < nargs; i++)
+  {
+    PyObject *item = PyTuple_GET_ITEM(cargs, i);
+    Py_INCREF(item);
+    PyTuple_SET_ITEM(fnargs, i + 1, item);
+  }
+
+  module = PyImport_ImportModule("functools");
+
+  if (!module)
+    goto finally;
+
+  function = PyObject_GetAttrString(module, "partial");
+
+  Py_CLEAR(module);
+
+  if (!function)
+    goto finally;
+
+  partial = PyObject_Call(function, fnargs, ckwargs);
+
+  Py_CLEAR(function);
+
+  if (!partial)
+    goto finally;
+
+  module = PyImport_ImportModule("inspect");
+
+  if (!module)
+    goto finally;
+
+  function = PyObject_GetAttrString(module, "signature");
+
+  Py_CLEAR(module);
+
+  if (!function)
+    goto finally;
+
+  result = PyObject_CallFunctionObjArgs(function, partial, NULL);
+
+finally:
+  Py_XDECREF(function);
+  Py_XDECREF(partial);
+  Py_XDECREF(fnargs);
+
+  Py_XDECREF(ckwargs);
+  Py_XDECREF(cargs);
+  Py_DECREF(wrapped);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* The __signature__ attribute is intercepted here rather than being a
+ * getset descriptor for the same reason as __module__ and __doc__ on the
+ * base object proxy. A descriptor would be visible on the type itself and
+ * inspect.signature() applied to the type would then fail on finding a
+ * descriptor object where it expects a Signature. Handling it in getattro
+ * makes it visible on instances only, which is all that inspect needs. */
+
+static PyObject *WraptPartialCallableObjectProxy_getattro(
+    WraptPartialCallableObjectProxyObject *self, PyObject *name)
+{
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  if (wrapt_name_equals(name, state->str_signature))
+    return WraptPartialCallableObjectProxy_get_signature(self);
+
+  return WraptObjectProxy_getattro((WraptObjectProxyObject *)self, name);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyGetSetDef WraptPartialCallableObjectProxy_getset[] = {
+    {"_self_args", (getter)WraptPartialCallableObjectProxy_get_self_args, NULL,
+     0},
+    {"_self_kwargs", (getter)WraptPartialCallableObjectProxy_get_self_kwargs,
+     NULL, 0},
+    {NULL},
+};
+
+static PyType_Slot WraptPartialCallableObjectProxy_slots[] = {
+    {Py_tp_dealloc, WraptPartialCallableObjectProxy_dealloc},
+    {Py_tp_call, WraptPartialCallableObjectProxy_call},
+    {Py_tp_traverse, WraptPartialCallableObjectProxy_traverse},
+    {Py_tp_clear, WraptPartialCallableObjectProxy_clear},
+    {Py_tp_getset, WraptPartialCallableObjectProxy_getset},
+    {Py_tp_getattro, WraptPartialCallableObjectProxy_getattro},
+    {Py_tp_init, WraptPartialCallableObjectProxy_init},
+    {Py_tp_new, WraptPartialCallableObjectProxy_new},
+    {0, NULL},
+};
+
+static PyType_Spec WraptPartialCallableObjectProxy_spec = {
+    .name = "_wrappers.PartialCallableObjectProxy",
+    .basicsize = sizeof(WraptPartialCallableObjectProxyObject),
+    .itemsize = 0,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = WraptPartialCallableObjectProxy_slots,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptFunctionWrapperBase_new(PyTypeObject *type,
+                                              PyObject *args, PyObject *kwds)
+{
+  WraptFunctionWrapperObject *self;
+
+  self = (WraptFunctionWrapperObject *)WraptObjectProxy_new(type, args, kwds);
+
+  if (!self)
+    return NULL;
+
+  self->instance = NULL;
+  self->wrapper = NULL;
+  self->enabled = NULL;
+  self->binding = NULL;
+  self->parent = NULL;
+  self->owner = NULL;
+
+  return (PyObject *)self;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptFunctionWrapperBase_raw_init(
+    WraptFunctionWrapperObject *self, PyObject *wrapped, PyObject *instance,
+    PyObject *wrapper, PyObject *enabled, PyObject *binding, PyObject *parent,
+    PyObject *owner)
+{
+  int result = 0;
+
+  result = WraptObjectProxy_raw_init((WraptObjectProxyObject *)self, wrapped);
+
+  if (result == 0)
+  {
+    /* Serialise the swaps for the same reason as in the __wrapped__
+     * setter. These fields have no setters, so re-invocation of __init__
+     * on an already published wrapper is the only path by which
+     * concurrent callers on a free-threaded build could otherwise decref
+     * the same old field values twice. */
+
+    Py_INCREF(instance);
+    Py_INCREF(wrapper);
+    Py_INCREF(enabled);
+    Py_INCREF(binding);
+    Py_INCREF(parent);
+    Py_INCREF(owner);
+
+    Py_BEGIN_CRITICAL_SECTION(self);
+    Py_XSETREF(self->instance, instance);
+    Py_XSETREF(self->wrapper, wrapper);
+    Py_XSETREF(self->enabled, enabled);
+    Py_XSETREF(self->binding, binding);
+    Py_XSETREF(self->parent, parent);
+    Py_XSETREF(self->owner, owner);
+    Py_END_CRITICAL_SECTION();
+  }
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptFunctionWrapperBase_init(WraptFunctionWrapperObject *self,
+                                         PyObject *args, PyObject *kwds)
+{
+  PyObject *wrapped = NULL;
+  PyObject *instance = NULL;
+  PyObject *wrapper = NULL;
+  PyObject *enabled = Py_None;
+  PyObject *binding = NULL;
+  PyObject *parent = Py_None;
+  PyObject *owner = Py_None;
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  char *const kwlist[] = {"wrapped", "instance", "wrapper", "enabled",
+                          "binding", "parent", "owner", NULL};
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|OOOO:FunctionWrapperBase",
+                                   kwlist, &wrapped, &instance, &wrapper,
+                                   &enabled, &binding, &parent, &owner))
+  {
+    return -1;
+  }
+
+  if (!binding)
+    binding = state->str_callable;
+
+  return WraptFunctionWrapperBase_raw_init(self, wrapped, instance, wrapper,
+                                           enabled, binding, parent, owner);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptFunctionWrapperBase_traverse(WraptFunctionWrapperObject *self,
+                                             visitproc visit, void *arg)
+{
+  int err = WraptObjectProxy_traverse((WraptObjectProxyObject *)self, visit, arg);
+  if (err)
+    return err;
+
+  Py_VISIT(self->instance);
+  Py_VISIT(self->wrapper);
+  Py_VISIT(self->enabled);
+  Py_VISIT(self->binding);
+  Py_VISIT(self->parent);
+  Py_VISIT(self->owner);
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptFunctionWrapperBase_clear(WraptFunctionWrapperObject *self)
+{
+  WraptObjectProxy_clear((WraptObjectProxyObject *)self);
+
+  Py_CLEAR(self->instance);
+  Py_CLEAR(self->wrapper);
+  Py_CLEAR(self->enabled);
+  Py_CLEAR(self->binding);
+  Py_CLEAR(self->parent);
+  Py_CLEAR(self->owner);
+
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void WraptFunctionWrapperBase_dealloc(WraptFunctionWrapperObject *self)
+{
+  PyTypeObject *tp = Py_TYPE(self);
+
+  PyObject_GC_UnTrack(self);
+
+  if (self->object_proxy.weakreflist != NULL)
+    PyObject_ClearWeakRefs((PyObject *)self);
+
+  WraptFunctionWrapperBase_clear(self);
+
+  tp->tp_free(self);
+
+#if PY_VERSION_HEX >= 0x030C0000
+  PyObject *exc = PyErr_GetRaisedException();
+  Py_DECREF(tp);
+  PyErr_SetRaisedException(exc);
+#else
+  PyObject *exc_type, *exc_value, *exc_tb;
+  PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
+  Py_DECREF(tp);
+  PyErr_Restore(exc_type, exc_value, exc_tb);
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptFunctionWrapperBase_call(WraptFunctionWrapperObject *self,
+                                               PyObject *args, PyObject *kwds)
+{
+  PyObject *param_kwds = NULL;
+
+  PyObject *wrapped = NULL;
+  PyObject *instance = NULL;
+  PyObject *wrapper = NULL;
+  PyObject *enabled = NULL;
+  PyObject *binding = NULL;
+
+  PyObject *result = NULL;
+
+  if (!self->object_proxy.wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  /* Hold strong references to the fields used across the call so a
+   * concurrent re-initialization of the wrapper cannot release them
+   * while in use. Fields are acquired independently, so a consistent
+   * snapshot across all of them is not guaranteed, as documented. */
+
+  wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+  instance = wrapt_acquire_field((PyObject *)self, &self->instance);
+  wrapper = wrapt_acquire_field((PyObject *)self, &self->wrapper);
+  enabled = wrapt_acquire_field((PyObject *)self, &self->enabled);
+  binding = wrapt_acquire_field((PyObject *)self, &self->binding);
+
+  if (wrapt_require_field((PyObject *)self, instance, "_self_instance") == -1 ||
+      wrapt_require_field((PyObject *)self, wrapper, "_self_wrapper") == -1 ||
+      wrapt_require_field((PyObject *)self, enabled, "_self_enabled") == -1 ||
+      wrapt_require_field((PyObject *)self, binding, "_self_binding") == -1)
+    goto finally;
+
+  if (enabled != Py_None)
+  {
+    if (PyCallable_Check(enabled))
+    {
+      PyObject *object = NULL;
+      int is_false;
+
+      object = PyObject_CallFunctionObjArgs(enabled, NULL);
+
+      if (!object)
+        goto finally;
+
+      is_false = PyObject_Not(object);
+      Py_DECREF(object);
+
+      if (is_false < 0)
+        goto finally;
+
+      if (is_false)
+      {
+        result = PyObject_Call(wrapped, args, kwds);
+        goto finally;
+      }
+    }
+    else
+    {
+      int is_false = PyObject_Not(enabled);
+
+      if (is_false < 0)
+        goto finally;
+
+      if (is_false)
+      {
+        result = PyObject_Call(wrapped, args, kwds);
+        goto finally;
+      }
+    }
+  }
+
+  if (!kwds)
+  {
+    param_kwds = PyDict_New();
+    if (!param_kwds)
+      goto finally;
+    kwds = param_kwds;
+  }
+
+  if (instance == Py_None)
+  {
+    int matched =
+        PyUnicode_CompareWithASCIIString(binding, "function") == 0 ||
+        PyUnicode_CompareWithASCIIString(binding, "instancemethod") == 0 ||
+        PyUnicode_CompareWithASCIIString(binding, "callable") == 0 ||
+        PyUnicode_CompareWithASCIIString(binding, "classmethod") == 0;
+
+    if (matched)
+    {
+      PyObject *bound_instance = NULL;
+
+      bound_instance = PyObject_GetAttr(wrapped, state->str_self);
+
+      if (bound_instance)
+      {
+        result = PyObject_CallFunctionObjArgs(wrapper, wrapped, bound_instance,
+                                              args, kwds, NULL);
+
+        Py_DECREF(bound_instance);
+
+        goto finally;
+      }
+      else
+      {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+          goto finally;
+        PyErr_Clear();
+      }
+    }
+  }
+
+  result = PyObject_CallFunctionObjArgs(wrapper, wrapped, instance, args, kwds,
+                                        NULL);
+
+finally:
+  Py_XDECREF(param_kwds);
+
+  Py_DECREF(wrapped);
+  Py_XDECREF(instance);
+  Py_XDECREF(wrapper);
+  Py_XDECREF(enabled);
+  Py_XDECREF(binding);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptFunctionWrapperBase_descr_get(WraptFunctionWrapperObject *self,
+                                   PyObject *obj, PyObject *type)
+{
+  PyObject *bound_type = NULL;
+  PyObject *descriptor = NULL;
+
+  PyObject *wrapped = NULL;
+  PyObject *instance = NULL;
+  PyObject *wrapper = NULL;
+  PyObject *enabled = NULL;
+  PyObject *binding = NULL;
+  PyObject *parent = NULL;
+
+  PyObject *result = NULL;
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *bound_type_str = state->str_bound_function_wrapper;
+
+  if (!self->object_proxy.wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
+      return NULL;
+  }
+
+  /* Hold strong references to the fields used across the binding so a
+   * concurrent re-initialization of the wrapper cannot release them
+   * while in use. Fields are acquired independently, so a consistent
+   * snapshot across all of them is not guaranteed, as documented. */
+
+  wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+  instance = wrapt_acquire_field((PyObject *)self, &self->instance);
+  wrapper = wrapt_acquire_field((PyObject *)self, &self->wrapper);
+  enabled = wrapt_acquire_field((PyObject *)self, &self->enabled);
+  binding = wrapt_acquire_field((PyObject *)self, &self->binding);
+  parent = wrapt_acquire_field((PyObject *)self, &self->parent);
+
+  if (wrapt_require_field((PyObject *)self, instance, "_self_instance") == -1 ||
+      wrapt_require_field((PyObject *)self, wrapper, "_self_wrapper") == -1 ||
+      wrapt_require_field((PyObject *)self, enabled, "_self_enabled") == -1 ||
+      wrapt_require_field((PyObject *)self, binding, "_self_binding") == -1 ||
+      wrapt_require_field((PyObject *)self, parent, "_self_parent") == -1)
+    goto finally;
+
+  if (parent == Py_None)
+  {
+    if (PyUnicode_CompareWithASCIIString(binding, "builtin") == 0)
+    {
+      Py_INCREF(self);
+      result = (PyObject *)self;
+      goto finally;
+    }
+
+    if (PyUnicode_CompareWithASCIIString(binding, "class") == 0)
+    {
+      Py_INCREF(self);
+      result = (PyObject *)self;
+      goto finally;
+    }
+
+    if (Py_TYPE(wrapped)->tp_descr_get == NULL)
+    {
+      Py_INCREF(self);
+      result = (PyObject *)self;
+      goto finally;
+    }
+
+    descriptor = (Py_TYPE(wrapped)->tp_descr_get)(wrapped, obj, type);
+
+    if (!descriptor)
+      goto finally;
+
+    if (Py_TYPE(self) != state->FunctionWrapper_Type)
+    {
+      bound_type = PyObject_GenericGetAttr((PyObject *)self, bound_type_str);
+
+      if (!bound_type)
+      {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+          goto finally;
+        PyErr_Clear();
+      }
+    }
+
+    if (obj == NULL)
+      obj = Py_None;
+
+    result = PyObject_CallFunctionObjArgs(
+        bound_type ? bound_type : (PyObject *)state->BoundFunctionWrapper_Type,
+        descriptor, obj, wrapper, enabled, binding, self, type, NULL);
+
+    goto finally;
+  }
+
+  if (instance == Py_None)
+  {
+    int matched =
+        PyUnicode_CompareWithASCIIString(binding, "function") == 0 ||
+        PyUnicode_CompareWithASCIIString(binding, "instancemethod") == 0 ||
+        PyUnicode_CompareWithASCIIString(binding, "callable") == 0;
+
+    if (matched)
+    {
+      PyObject *parent_wrapped = NULL;
+
+      if (PyObject_TypeCheck(parent, state->ObjectProxy_Type))
+      {
+        WraptObjectProxyObject *parent_proxy = (WraptObjectProxyObject *)parent;
+
+        if (!parent_proxy->wrapped)
+        {
+          if (raise_uninitialized_wrapper_error(parent_proxy) == -1)
+            goto finally;
+        }
+
+        parent_wrapped = wrapt_acquire_wrapped(parent_proxy);
+      }
+      else
+      {
+        /* Fallback for the unusual case where parent is not a wrapt proxy. */
+        parent_wrapped = PyObject_GetAttr(parent, state->str_wrapped);
+
+        if (!parent_wrapped)
+          goto finally;
+      }
+
+      if (Py_TYPE(parent_wrapped)->tp_descr_get == NULL)
+      {
+        PyErr_Format(PyExc_AttributeError,
+                     "'%s' object has no attribute '__get__'",
+                     Py_TYPE(parent_wrapped)->tp_name);
+        Py_DECREF(parent_wrapped);
+        goto finally;
+      }
+
+      descriptor =
+          (Py_TYPE(parent_wrapped)->tp_descr_get)(parent_wrapped, obj, type);
+
+      Py_DECREF(parent_wrapped);
+
+      if (!descriptor)
+        goto finally;
+
+      if (Py_TYPE(parent) != state->FunctionWrapper_Type)
+      {
+        bound_type = PyObject_GenericGetAttr(parent, bound_type_str);
+
+        if (!bound_type)
+        {
+          if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+            goto finally;
+          PyErr_Clear();
+        }
+      }
+
+      if (obj == NULL)
+        obj = Py_None;
+
+      result = PyObject_CallFunctionObjArgs(
+          bound_type ? bound_type : (PyObject *)state->BoundFunctionWrapper_Type,
+          descriptor, obj, wrapper, enabled, binding, parent, type, NULL);
+
+      goto finally;
+    }
+  }
+
+  Py_INCREF(self);
+  result = (PyObject *)self;
+
+finally:
+  Py_XDECREF(bound_type);
+  Py_XDECREF(descriptor);
+
+  Py_DECREF(wrapped);
+  Py_XDECREF(instance);
+  Py_XDECREF(wrapper);
+  Py_XDECREF(enabled);
+  Py_XDECREF(binding);
+  Py_XDECREF(parent);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptFunctionWrapperBase_set_name(WraptFunctionWrapperObject *self,
+                                  PyObject *args, PyObject *kwds)
+{
+  PyObject *method = NULL;
+  PyObject *result = NULL;
+
+  if (!self->object_proxy.wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state =
+      wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  PyObject *wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+
+  method = PyObject_GetAttr(wrapped, state->str_set_name);
+
+  Py_DECREF(wrapped);
+
+  if (!method)
+  {
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+      return NULL;
+    PyErr_Clear();
+    Py_RETURN_NONE;
+  }
+
+  result = PyObject_Call(method, args, kwds);
+
+  Py_DECREF(method);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* The getters for the wrapper specific fields fail with AttributeError if
+ * the field was never set, which means __init__() was not called. The
+ * attribute lookup then falls through to __getattr__() and so on to the
+ * wrapped object, which is the same outcome as for the pure Python
+ * implementation, where these are instance attributes which in that case
+ * do not exist. A value of None is not substituted, as that is a valid
+ * value for most of these fields and so would be indistinguishable from
+ * the state of a wrapper which had been initialized. */
+
+static PyObject *
+WraptFunctionWrapperBase_get_self_instance(WraptFunctionWrapperObject *self,
+                                           void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->instance);
+
+  if (wrapt_require_field((PyObject *)self, value, "_self_instance") == -1)
+    return NULL;
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptFunctionWrapperBase_get_self_wrapper(WraptFunctionWrapperObject *self,
+                                          void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->wrapper);
+
+  if (wrapt_require_field((PyObject *)self, value, "_self_wrapper") == -1)
+    return NULL;
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptFunctionWrapperBase_get_self_enabled(WraptFunctionWrapperObject *self,
+                                          void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->enabled);
+
+  if (wrapt_require_field((PyObject *)self, value, "_self_enabled") == -1)
+    return NULL;
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptFunctionWrapperBase_get_self_binding(WraptFunctionWrapperObject *self,
+                                          void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->binding);
+
+  if (wrapt_require_field((PyObject *)self, value, "_self_binding") == -1)
+    return NULL;
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptFunctionWrapperBase_get_self_parent(WraptFunctionWrapperObject *self,
+                                         void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->parent);
+
+  if (wrapt_require_field((PyObject *)self, value, "_self_parent") == -1)
+    return NULL;
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptFunctionWrapperBase_get_self_owner(WraptFunctionWrapperObject *self,
+                                        void *closure)
+{
+  PyObject *value = NULL;
+
+  value = wrapt_acquire_field((PyObject *)self, &self->owner);
+
+  if (wrapt_require_field((PyObject *)self, value, "_self_owner") == -1)
+    return NULL;
+
+  return value;
+}
+
+/* ------------------------------------------------------------------------- */;
+
+static PyMethodDef WraptFunctionWrapperBase_methods[] = {
+    {"__set_name__", (PyCFunction)WraptFunctionWrapperBase_set_name,
+     METH_VARARGS | METH_KEYWORDS, 0},
+    {NULL, NULL},
+};
+
+/* ------------------------------------------------------------------------- */;
+
+static PyGetSetDef WraptFunctionWrapperBase_getset[] = {
+    {"_self_instance", (getter)WraptFunctionWrapperBase_get_self_instance, NULL,
+     0},
+    {"_self_wrapper", (getter)WraptFunctionWrapperBase_get_self_wrapper, NULL,
+     0},
+    {"_self_enabled", (getter)WraptFunctionWrapperBase_get_self_enabled, NULL,
+     0},
+    {"_self_binding", (getter)WraptFunctionWrapperBase_get_self_binding, NULL,
+     0},
+    {"_self_parent", (getter)WraptFunctionWrapperBase_get_self_parent, NULL, 0},
+    {"_self_owner", (getter)WraptFunctionWrapperBase_get_self_owner, NULL, 0},
+    {NULL},
+};
+
+static PyType_Slot WraptFunctionWrapperBase_slots[] = {
+    {Py_tp_dealloc, WraptFunctionWrapperBase_dealloc},
+    {Py_tp_call, WraptFunctionWrapperBase_call},
+    {Py_tp_traverse, WraptFunctionWrapperBase_traverse},
+    {Py_tp_clear, WraptFunctionWrapperBase_clear},
+    {Py_tp_methods, WraptFunctionWrapperBase_methods},
+    {Py_tp_getset, WraptFunctionWrapperBase_getset},
+    {Py_tp_descr_get, WraptFunctionWrapperBase_descr_get},
+    {Py_tp_init, WraptFunctionWrapperBase_init},
+    {Py_tp_new, WraptFunctionWrapperBase_new},
+    {0, NULL},
+};
+
+static PyType_Spec WraptFunctionWrapperBase_spec = {
+    .name = "_wrappers._FunctionWrapperBase",
+    .basicsize = sizeof(WraptFunctionWrapperObject),
+    .itemsize = 0,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = WraptFunctionWrapperBase_slots,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *
+WraptBoundFunctionWrapper_call(WraptFunctionWrapperObject *self, PyObject *args,
+                               PyObject *kwds)
+{
+  PyObject *param_args = NULL;
+  PyObject *param_kwds = NULL;
+
+  PyObject *wrapped = NULL;
+  PyObject *instance = NULL;
+  PyObject *wrapper = NULL;
+  PyObject *enabled = NULL;
+  PyObject *binding = NULL;
+  PyObject *owner = NULL;
+
+  PyObject *call_instance = NULL;
+
+  PyObject *result = NULL;
+
+  int matched;
+
+  if (!self->object_proxy.wrapped)
+  {
+    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
+      return NULL;
+  }
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return NULL;
+
+  /* Hold strong references to the fields used across the call so a
+   * concurrent re-initialization of the wrapper cannot release them
+   * while in use. Fields are acquired independently, so a consistent
+   * snapshot across all of them is not guaranteed, as documented. The
+   * call_instance local always holds an owned reference to whichever
+   * instance value is passed through to the wrapper. */
+
+  instance = wrapt_acquire_field((PyObject *)self, &self->instance);
+  wrapper = wrapt_acquire_field((PyObject *)self, &self->wrapper);
+  enabled = wrapt_acquire_field((PyObject *)self, &self->enabled);
+  binding = wrapt_acquire_field((PyObject *)self, &self->binding);
+  owner = wrapt_acquire_field((PyObject *)self, &self->owner);
+
+  if (wrapt_require_field((PyObject *)self, instance, "_self_instance") == -1 ||
+      wrapt_require_field((PyObject *)self, wrapper, "_self_wrapper") == -1 ||
+      wrapt_require_field((PyObject *)self, enabled, "_self_enabled") == -1 ||
+      wrapt_require_field((PyObject *)self, binding, "_self_binding") == -1 ||
+      wrapt_require_field((PyObject *)self, owner, "_self_owner") == -1)
+    goto finally;
+
+  if (enabled != Py_None)
+  {
+    if (PyCallable_Check(enabled))
+    {
+      PyObject *object = NULL;
+      int is_false;
+
+      object = PyObject_CallFunctionObjArgs(enabled, NULL);
+
+      if (!object)
+        goto finally;
+
+      is_false = PyObject_Not(object);
+      Py_DECREF(object);
+
+      if (is_false < 0)
+        goto finally;
+
+      if (is_false)
+      {
+        wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+        result = PyObject_Call(wrapped, args, kwds);
+        goto finally;
+      }
+    }
+    else
+    {
+      int is_false = PyObject_Not(enabled);
+
+      if (is_false < 0)
+        goto finally;
+
+      if (is_false)
+      {
+        wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+        result = PyObject_Call(wrapped, args, kwds);
+        goto finally;
+      }
+    }
+  }
+
+  /*
+   * We need to do things different depending on whether we are likely
+   * wrapping an instance method vs a static method or class method.
+   */
+
+  matched =
+      PyUnicode_CompareWithASCIIString(binding, "function") == 0 ||
+      PyUnicode_CompareWithASCIIString(binding, "callable") == 0;
+
+  if (matched)
+  {
+
+    if (instance == Py_None && PyTuple_GET_SIZE(args) != 0)
+    {
+      /*
+       * This situation can occur where someone is calling the
+       * instancemethod via the class type and passing the
+       * instance as the first argument. We need to shift the args
+       * before making the call to the wrapper and effectively
+       * bind the instance to the wrapped function using a partial
+       * so the wrapper doesn't see anything as being different.
+       */
+
+      call_instance = PyTuple_GetItem(args, 0);
+
+      if (!call_instance)
+        goto finally;
+
+      Py_INCREF(call_instance);
+
+      int check = PyObject_IsInstance(call_instance, owner);
+
+      if (check < 0)
+        goto finally;
+
+      if (check)
+      {
+        PyObject *inner_wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+
+        wrapped = PyObject_CallFunctionObjArgs(
+            (PyObject *)state->PartialCallableObjectProxy_Type,
+            inner_wrapped, call_instance, NULL);
+
+        Py_DECREF(inner_wrapped);
+
+        if (!wrapped)
+          goto finally;
+
+        param_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
+
+        if (!param_args)
+          goto finally;
+
+        args = param_args;
+      }
+      else
+      {
+        Py_DECREF(call_instance);
+        call_instance = instance;
+        Py_XINCREF(call_instance);
+      }
+    }
+    else
+    {
+      call_instance = instance;
+      Py_XINCREF(call_instance);
+    }
+
+    if (!wrapped)
+    {
+      wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+    }
+
+    if (!kwds)
+    {
+      param_kwds = PyDict_New();
+      if (!param_kwds)
+        goto finally;
+      kwds = param_kwds;
+    }
+
+    result = PyObject_CallFunctionObjArgs(wrapper, wrapped, call_instance,
+                                          args, kwds, NULL);
+  }
+  else
+  {
+    /*
+     * As in this case we would be dealing with a classmethod or
+     * staticmethod, then _self_instance will only tell us whether
+     * when calling the classmethod or staticmethod they did it via
+     * an instance of the class it is bound to and not the case
+     * where done by the class type itself. We thus ignore
+     * _self_instance and use the __self__ attribute of the bound
+     * function instead. For a classmethod, this means instance will
+     * be the class type and for a staticmethod it will be None.
+     * This is probably the more useful thing we can pass through
+     * even though we loose knowledge of whether they were called on
+     * the instance vs the class type, as it reflects what they have
+     * available in the decoratored function.
+     */
+
+    wrapped = wrapt_acquire_wrapped(&self->object_proxy);
+
+    call_instance = PyObject_GetAttr(wrapped, state->str_self);
+
+    if (!call_instance)
+    {
+      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+        goto finally;
+      PyErr_Clear();
+      Py_INCREF(Py_None);
+      call_instance = Py_None;
+    }
+
+    if (!kwds)
+    {
+      param_kwds = PyDict_New();
+      if (!param_kwds)
+        goto finally;
+      kwds = param_kwds;
+    }
+
+    result = PyObject_CallFunctionObjArgs(wrapper, wrapped, call_instance,
+                                          args, kwds, NULL);
+  }
+
+finally:
+  Py_XDECREF(param_args);
+  Py_XDECREF(param_kwds);
+
+  Py_XDECREF(call_instance);
+
+  Py_XDECREF(wrapped);
+  Py_XDECREF(instance);
+  Py_XDECREF(wrapper);
+  Py_XDECREF(enabled);
+  Py_XDECREF(binding);
+  Py_XDECREF(owner);
+
+  return result;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyObject *WraptBoundFunctionWrapper_getattr(
+    WraptFunctionWrapperObject *self, PyObject *args)
+{
+  PyObject *name = NULL;
+
+  if (!PyArg_ParseTuple(args, "U:__getattr__", &name))
+    return NULL;
+
+  PyObject *parent = wrapt_acquire_field((PyObject *)self, &self->parent);
+
+  if (parent && parent != Py_None)
+  {
+    PyObject *result = PyObject_GetAttr(parent, name);
+
+    if (result)
+    {
+      Py_DECREF(parent);
+      return result;
+    }
+
+    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+    {
+      Py_DECREF(parent);
+      return NULL;
+    }
+
+    PyErr_Clear();
+  }
+
+  Py_XDECREF(parent);
+
+  return WraptObjectProxy_getattr((WraptObjectProxyObject *)self, args);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptBoundFunctionWrapper_setattro(
+    WraptFunctionWrapperObject *self, PyObject *name, PyObject *value)
+{
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  int match = PyUnicode_Tailmatch(name, state->str_self_, 0, PY_SSIZE_T_MAX, -1);
+
+  if (match < 0)
+    return -1;
+
+  if (match)
+  {
+    /* Check if this is an internal slot (has a getset descriptor on the type) */
+    if (wrapt_type_has_attr(Py_TYPE(self), name))
+      return PyObject_GenericSetAttr((PyObject *)self, name, value);
+
+    /* User-defined _self_ attribute — delegate to parent */
+    PyObject *parent = wrapt_acquire_field((PyObject *)self, &self->parent);
+
+    if (parent && parent != Py_None)
+    {
+      int result = PyObject_GenericSetAttr(parent, name, value);
+
+      Py_DECREF(parent);
+
+      return result;
+    }
+
+    Py_XDECREF(parent);
+  }
+
+  /* Fall through to base ObjectProxy setattro for everything else */
+  return WraptObjectProxy_setattro((WraptObjectProxyObject *)self, name, value);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyMethodDef WraptBoundFunctionWrapper_methods[] = {
+    {"__getattr__", (PyCFunction)WraptBoundFunctionWrapper_getattr, METH_VARARGS,
+     0},
+    {NULL, NULL},
+};
+
+/* ------------------------------------------------------------------------- */
+
+static PyType_Slot WraptBoundFunctionWrapper_slots[] = {
+    {Py_tp_dealloc, WraptFunctionWrapperBase_dealloc},
+    {Py_tp_traverse, WraptFunctionWrapperBase_traverse},
+    {Py_tp_clear, WraptFunctionWrapperBase_clear},
+    {Py_tp_call, WraptBoundFunctionWrapper_call},
+    {Py_tp_setattro, WraptBoundFunctionWrapper_setattro},
+    {Py_tp_methods, WraptBoundFunctionWrapper_methods},
+    {0, NULL},
+};
+
+static PyType_Spec WraptBoundFunctionWrapper_spec = {
+    .name = "_wrappers.BoundFunctionWrapper",
+    .basicsize = sizeof(WraptFunctionWrapperObject),
+    .itemsize = 0,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = WraptBoundFunctionWrapper_slots,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
+                                     PyObject *args, PyObject *kwds)
+{
+  PyObject *wrapped = NULL;
+  PyObject *wrapper = NULL;
+  PyObject *enabled = Py_None;
+  PyObject *binding = NULL;
+  PyObject *binding_owned = NULL;
+  PyObject *instance = NULL;
+
+  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
+  if (!state)
+    return -1;
+
+  PyObject *function_str = state->str_function;
+  PyObject *classmethod_str = state->str_classmethod;
+  PyObject *staticmethod_str = state->str_staticmethod;
+  PyObject *callable_str = state->str_callable;
+  PyObject *builtin_str = state->str_builtin;
+  PyObject *class_str = state->str_class;
+  PyObject *instancemethod_str = state->str_instancemethod;
+
+  int result = 0;
+
+  char *const kwlist[] = {"wrapped", "wrapper", "enabled", NULL};
+
+  if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:FunctionWrapper", kwlist,
+                                   &wrapped, &wrapper, &enabled))
+  {
+    return -1;
+  }
+
+  if (PyObject_TypeCheck(wrapped, state->FunctionWrapperBase_Type))
+  {
+    binding_owned = PyObject_GetAttr(wrapped, state->str_self_binding);
+    if (!binding_owned)
+    {
+      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+        return -1;
+      PyErr_Clear();
+    }
+    else
+    {
+      binding = binding_owned;
+    }
+  }
+
+  if (!binding)
+  {
+    int check;
+
+    if (PyCFunction_Check(wrapped))
+    {
+      binding = builtin_str;
+    }
+    else
+    {
+      check = PyObject_IsInstance(wrapped, (PyObject *)&PyFunction_Type);
+      if (check < 0)
+        goto error;
+      if (check)
+        binding = function_str;
+    }
+
+    if (!binding)
+    {
+      check = PyObject_IsInstance(wrapped, (PyObject *)&PyType_Type);
+      if (check < 0)
+        goto error;
+      if (check)
+        binding = class_str;
+    }
+
+    if (!binding)
+    {
+      check = PyObject_IsInstance(wrapped, (PyObject *)&PyClassMethod_Type);
+      if (check < 0)
+        goto error;
+      if (check)
+        binding = classmethod_str;
+    }
+
+    if (!binding)
+    {
+      check = PyObject_IsInstance(wrapped, (PyObject *)&PyStaticMethod_Type);
+      if (check < 0)
+        goto error;
+      if (check)
+        binding = staticmethod_str;
+    }
+
+    if (!binding)
+    {
+      instance = PyObject_GetAttr(wrapped, state->str_self);
+      if (instance != NULL)
+      {
+        check = PyObject_IsInstance(instance, (PyObject *)&PyType_Type);
+        if (check < 0)
+        {
+          Py_DECREF(instance);
+          goto error;
+        }
+        if (check)
+        {
+          binding = classmethod_str;
+        }
+        else
+        {
+          check = PyObject_IsInstance(wrapped, (PyObject *)&PyMethod_Type);
+          if (check < 0)
+          {
+            Py_DECREF(instance);
+            goto error;
+          }
+          if (check)
+            binding = instancemethod_str;
+          else
+            binding = callable_str;
+        }
+
+        Py_DECREF(instance);
+      }
+      else
+      {
+        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+          goto error;
+        PyErr_Clear();
+
+        binding = callable_str;
+      }
+    }
+  }
+
+  result = WraptFunctionWrapperBase_raw_init(
+      self, wrapped, Py_None, wrapper, enabled, binding, Py_None, Py_None);
+
+  Py_XDECREF(binding_owned);
+
+  return result;
+
+error:
+  Py_XDECREF(binding_owned);
+  return -1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static PyType_Slot WraptFunctionWrapper_slots[] = {
+    {Py_tp_dealloc, WraptFunctionWrapperBase_dealloc},
+    {Py_tp_traverse, WraptFunctionWrapperBase_traverse},
+    {Py_tp_clear, WraptFunctionWrapperBase_clear},
+    {Py_tp_init, WraptFunctionWrapper_init},
+    {0, NULL},
+};
+
+static PyType_Spec WraptFunctionWrapper_spec = {
+    .name = "_wrappers.FunctionWrapper",
+    .basicsize = sizeof(WraptFunctionWrapperObject),
+    .itemsize = 0,
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = WraptFunctionWrapper_slots,
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* PyModule_AddObjectRef polyfill for Python 3.9. */
+#if PY_VERSION_HEX >= 0x030A0000
+#define WRAPT_ADD_TYPE(mod, name, type)                               \
+  do                                                                  \
+  {                                                                   \
+    if (PyModule_AddObjectRef((mod), (name), (PyObject *)(type)) < 0) \
+      return -1;                                                      \
+  } while (0)
+#else
+#define WRAPT_ADD_TYPE(mod, name, type)                            \
+  do                                                               \
+  {                                                                \
+    Py_INCREF((PyObject *)(type));                                 \
+    if (PyModule_AddObject((mod), (name), (PyObject *)(type)) < 0) \
+    {                                                              \
+      Py_DECREF((PyObject *)(type));                               \
+      return -1;                                                   \
+    }                                                              \
+  } while (0)
+#endif
+
+/* Helper to create a heap type via PyType_FromModuleAndSpecWithBases and
+ * store it on the module. Returns 0 on success, -1 on failure. */
+
+static int wrapt_create_type(PyObject *module, PyTypeObject **out,
+                             PyType_Spec *spec, PyObject *bases,
+                             const char *name)
+{
+  PyObject *type;
+
+  type = PyType_FromModuleAndSpec(module, spec, bases);
+  if (type == NULL)
+    return -1;
+
+  /* PyType_FromModuleAndSpec returns a new reference. Add the type to
+   * the module dict first (WRAPT_ADD_TYPE adds another ref via
+   * PyModule_AddObjectRef on 3.10+, or via manual incref +
+   * PyModule_AddObject on 3.9). Only then store the owned reference
+   * in module state so that *out is never populated on failure. */
+
+  WRAPT_ADD_TYPE(module, name, type);
+
+  *out = (PyTypeObject *)type;
+
+  return 0;
+}
+
+/* Helper: intern a C string into the given module-state slot. Returns 0
+ * on success, -1 on failure (with PyErr set). */
+
+static int wrapt_intern_string(PyObject **slot, const char *s)
+{
+  PyObject *o = PyUnicode_InternFromString(s);
+  if (o == NULL)
+    return -1;
+  *slot = o;
+  return 0;
+}
+
+static int wrapt_init_strings(wrapt_module_state *state)
+{
+  if (wrapt_intern_string(&state->str_wrapped, "__wrapped__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_wrapped_factory,
+                          "__wrapped_factory__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_wrapped_get, "__wrapped_get__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_module, "__module__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_doc, "__doc__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_setattr_fixups,
+                          "__wrapped_setattr_fixups__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_getattr, "__getattr__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_self_, "_self_") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_callable, "callable") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_bound_function_wrapper,
+                          "__bound_function_wrapper__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_function, "function") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_classmethod, "classmethod") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_staticmethod, "staticmethod") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_builtin, "builtin") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_class, "class") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_instancemethod, "instancemethod") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_object_proxy, "__object_proxy__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_enter, "__enter__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_exit, "__exit__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_aenter, "__aenter__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_aexit, "__aexit__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_mro_entries, "__mro_entries__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_name, "__name__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_qualname, "__qualname__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_annotations, "__annotations__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_dunder_class, "__class__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_self, "__self__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_set_name, "__set_name__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_signature, "__signature__") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_self_binding, "_self_binding") < 0)
+    return -1;
+  if (wrapt_intern_string(&state->str_dict, "__dict__") < 0)
+    return -1;
+  return 0;
+}
+
+static int wrapt_exec(PyObject *module)
+{
+  wrapt_module_state *state = wrapt_get_state(module);
+  PyObject *bases = NULL;
+
+  /* Eagerly intern all cached strings. m_clear releases anything that
+   * was set before a failure, so we can return -1 on the first error. */
+  if (wrapt_init_strings(state) < 0)
+    return -1;
+
+  /* ObjectProxy: base = object (default). */
+  if (wrapt_create_type(module, &state->ObjectProxy_Type,
+                        &WraptObjectProxy_spec, NULL, "ObjectProxy") < 0)
+    return -1;
+
+  /* CallableObjectProxy: base = ObjectProxy. */
+  bases = PyTuple_Pack(1, (PyObject *)state->ObjectProxy_Type);
+  if (!bases)
+    return -1;
+  if (wrapt_create_type(module, &state->CallableObjectProxy_Type,
+                        &WraptCallableObjectProxy_spec, bases,
+                        "CallableObjectProxy") < 0)
+  {
+    Py_DECREF(bases);
+    return -1;
+  }
+  Py_DECREF(bases);
+
+  /* PartialCallableObjectProxy: base = ObjectProxy. */
+  bases = PyTuple_Pack(1, (PyObject *)state->ObjectProxy_Type);
+  if (!bases)
+    return -1;
+  if (wrapt_create_type(module, &state->PartialCallableObjectProxy_Type,
+                        &WraptPartialCallableObjectProxy_spec, bases,
+                        "PartialCallableObjectProxy") < 0)
+  {
+    Py_DECREF(bases);
+    return -1;
+  }
+  Py_DECREF(bases);
+
+  /* _FunctionWrapperBase: base = ObjectProxy. */
+  bases = PyTuple_Pack(1, (PyObject *)state->ObjectProxy_Type);
+  if (!bases)
+    return -1;
+  if (wrapt_create_type(module, &state->FunctionWrapperBase_Type,
+                        &WraptFunctionWrapperBase_spec, bases,
+                        "_FunctionWrapperBase") < 0)
+  {
+    Py_DECREF(bases);
+    return -1;
+  }
+  Py_DECREF(bases);
+
+  /* BoundFunctionWrapper: base = _FunctionWrapperBase. */
+  bases = PyTuple_Pack(1, (PyObject *)state->FunctionWrapperBase_Type);
+  if (!bases)
+    return -1;
+  if (wrapt_create_type(module, &state->BoundFunctionWrapper_Type,
+                        &WraptBoundFunctionWrapper_spec, bases,
+                        "BoundFunctionWrapper") < 0)
+  {
+    Py_DECREF(bases);
+    return -1;
+  }
+  Py_DECREF(bases);
+
+  /* FunctionWrapper: base = _FunctionWrapperBase. */
+  bases = PyTuple_Pack(1, (PyObject *)state->FunctionWrapperBase_Type);
+  if (!bases)
+    return -1;
+  if (wrapt_create_type(module, &state->FunctionWrapper_Type,
+                        &WraptFunctionWrapper_spec, bases,
+                        "FunctionWrapper") < 0)
+  {
+    Py_DECREF(bases);
+    return -1;
+  }
+  Py_DECREF(bases);
+
+  /* Cache WrapperNotInitializedError from wrapt.exceptions. The module is
+   * already in sys.modules because wrapt.wrappers imports it before
+   * __wrapt__.py imports us. */
+
+  {
+    PyObject *wrapt_exceptions_module =
+        PyImport_ImportModule("wrapt.exceptions");
+    if (!wrapt_exceptions_module)
+      return -1;
+
+    state->WrapperNotInitializedError = PyObject_GetAttrString(
+        wrapt_exceptions_module, "WrapperNotInitializedError");
+
+    Py_DECREF(wrapt_exceptions_module);
+
+    if (!state->WrapperNotInitializedError)
+      return -1;
+  }
+
+  return 0;
+}
+
+static int wrapt_traverse(PyObject *module, visitproc visit, void *arg)
+{
+  wrapt_module_state *state = wrapt_get_state(module);
+  if (state == NULL)
+    return 0;
+  Py_VISIT(state->ObjectProxy_Type);
+  Py_VISIT(state->CallableObjectProxy_Type);
+  Py_VISIT(state->PartialCallableObjectProxy_Type);
+  Py_VISIT(state->FunctionWrapperBase_Type);
+  Py_VISIT(state->BoundFunctionWrapper_Type);
+  Py_VISIT(state->FunctionWrapper_Type);
+  Py_VISIT(state->str_wrapped);
+  Py_VISIT(state->str_wrapped_factory);
+  Py_VISIT(state->str_wrapped_get);
+  Py_VISIT(state->str_module);
+  Py_VISIT(state->str_doc);
+  Py_VISIT(state->str_setattr_fixups);
+  Py_VISIT(state->str_getattr);
+  Py_VISIT(state->str_self_);
+  Py_VISIT(state->str_callable);
+  Py_VISIT(state->str_bound_function_wrapper);
+  Py_VISIT(state->str_function);
+  Py_VISIT(state->str_classmethod);
+  Py_VISIT(state->str_staticmethod);
+  Py_VISIT(state->str_builtin);
+  Py_VISIT(state->str_class);
+  Py_VISIT(state->str_instancemethod);
+  Py_VISIT(state->str_object_proxy);
+  Py_VISIT(state->str_enter);
+  Py_VISIT(state->str_exit);
+  Py_VISIT(state->str_aenter);
+  Py_VISIT(state->str_aexit);
+  Py_VISIT(state->str_mro_entries);
+  Py_VISIT(state->str_name);
+  Py_VISIT(state->str_qualname);
+  Py_VISIT(state->str_annotations);
+  Py_VISIT(state->str_dunder_class);
+  Py_VISIT(state->str_self);
+  Py_VISIT(state->str_set_name);
+  Py_VISIT(state->str_self_binding);
+  Py_VISIT(state->str_signature);
+  Py_VISIT(state->str_dict);
+  Py_VISIT(state->WrapperNotInitializedError);
+  return 0;
+}
+
+static int wrapt_clear(PyObject *module)
+{
+  wrapt_module_state *state = wrapt_get_state(module);
+  if (state == NULL)
+    return 0;
+  Py_CLEAR(state->ObjectProxy_Type);
+  Py_CLEAR(state->CallableObjectProxy_Type);
+  Py_CLEAR(state->PartialCallableObjectProxy_Type);
+  Py_CLEAR(state->FunctionWrapperBase_Type);
+  Py_CLEAR(state->BoundFunctionWrapper_Type);
+  Py_CLEAR(state->FunctionWrapper_Type);
+  Py_CLEAR(state->str_wrapped);
+  Py_CLEAR(state->str_wrapped_factory);
+  Py_CLEAR(state->str_wrapped_get);
+  Py_CLEAR(state->str_module);
+  Py_CLEAR(state->str_doc);
+  Py_CLEAR(state->str_setattr_fixups);
+  Py_CLEAR(state->str_getattr);
+  Py_CLEAR(state->str_self_);
+  Py_CLEAR(state->str_callable);
+  Py_CLEAR(state->str_bound_function_wrapper);
+  Py_CLEAR(state->str_function);
+  Py_CLEAR(state->str_classmethod);
+  Py_CLEAR(state->str_staticmethod);
+  Py_CLEAR(state->str_builtin);
+  Py_CLEAR(state->str_class);
+  Py_CLEAR(state->str_instancemethod);
+  Py_CLEAR(state->str_object_proxy);
+  Py_CLEAR(state->str_enter);
+  Py_CLEAR(state->str_exit);
+  Py_CLEAR(state->str_aenter);
+  Py_CLEAR(state->str_aexit);
+  Py_CLEAR(state->str_mro_entries);
+  Py_CLEAR(state->str_name);
+  Py_CLEAR(state->str_qualname);
+  Py_CLEAR(state->str_annotations);
+  Py_CLEAR(state->str_dunder_class);
+  Py_CLEAR(state->str_self);
+  Py_CLEAR(state->str_set_name);
+  Py_CLEAR(state->str_self_binding);
+  Py_CLEAR(state->str_signature);
+  Py_CLEAR(state->str_dict);
+  Py_CLEAR(state->WrapperNotInitializedError);
+  return 0;
+}
+
+static void wrapt_free(void *module)
+{
+  (void)wrapt_clear((PyObject *)module);
+}
+
+static PyModuleDef_Slot wrapt_slots[] = {
+    {Py_mod_exec, wrapt_exec},
+#if PY_VERSION_HEX >= 0x030C0000
+    /* Per-interpreter GIL support (PEP 684, 3.12+). All process-wide
+     * mutable state has been removed: types are heap types created per
+     * interpreter via PyType_FromModuleAndSpec, cached strings live in
+     * per-interpreter module state, and there are no static PyObject *
+     * globals. */
+    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
+#endif
+#if PY_VERSION_HEX >= 0x030D0000
+    /* Free-threading support (3.13+). The previous Py_MOD_GIL_NOT_USED
+     * declaration via PyUnstable_Module_SetGIL was unsound because the
+     * 19 cached interned strings were lazily initialized via racy
+     * static locals. With eager init in wrapt_exec the declaration is
+     * now actually correct. */
+    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
+#endif
+    {0, NULL},
+};
+
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    .m_name = "_wrappers",
+    .m_doc = NULL,
+    .m_size = sizeof(wrapt_module_state),
+    .m_methods = NULL,
+    .m_slots = wrapt_slots,
+    .m_traverse = wrapt_traverse,
+    .m_clear = wrapt_clear,
+    .m_free = wrapt_free,
+};
+
+PyMODINIT_FUNC PyInit__wrappers(void)
+{
+  return PyModuleDef_Init(&moduledef);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py
new file mode 100644
index 00000000000..2ded470d25f
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py
@@ -0,0 +1,55 @@
+"""The inspect.formatargspec() function was dropped in Python 3.11 but we need
+it for when constructing signature changing decorators based on result of
+inspect.getfullargspec(). The code here implements inspect.formatargspec() based
+on Parameter and Signature from inspect module, which were added in Python 3.6.
+Thanks to Cyril Jouve for the implementation.
+"""
+
+from inspect import Parameter, Signature
+from typing import Any, Callable, List, Mapping, Optional, Sequence, Tuple
+
+
+def formatargspec(
+    args: List[str],
+    varargs: Optional[str] = None,
+    varkw: Optional[str] = None,
+    defaults: Optional[Tuple[Any, ...]] = None,
+    kwonlyargs: Optional[Sequence[str]] = None,
+    kwonlydefaults: Optional[Mapping[str, Any]] = None,
+    annotations: Mapping[str, Any] = {},
+    formatarg: Callable[[str], str] = str,
+    formatvarargs: Callable[[str], str] = lambda name: "*" + name,
+    formatvarkw: Callable[[str], str] = lambda name: "**" + name,
+    formatvalue: Callable[[Any], str] = lambda value: "=" + repr(value),
+    formatreturns: Callable[[Any], str] = lambda text: " -> " + text,
+    formatannotation: Callable[[Any], str] = lambda annot: " -> " + repr(annot),
+) -> str:
+    if kwonlyargs is None:
+        kwonlyargs = ()
+    if kwonlydefaults is None:
+        kwonlydefaults = {}
+    ndefaults = len(defaults) if defaults else 0
+    parameters = [
+        Parameter(
+            arg,
+            Parameter.POSITIONAL_OR_KEYWORD,
+            default=defaults[i] if defaults and i >= 0 else Parameter.empty,
+            annotation=annotations.get(arg, Parameter.empty),
+        )
+        for i, arg in enumerate(args, ndefaults - len(args))
+    ]
+    if varargs:
+        parameters.append(Parameter(varargs, Parameter.VAR_POSITIONAL))
+    parameters.extend(
+        Parameter(
+            kwonlyarg,
+            Parameter.KEYWORD_ONLY,
+            default=kwonlydefaults.get(kwonlyarg, Parameter.empty),
+            annotation=annotations.get(kwonlyarg, Parameter.empty),
+        )
+        for kwonlyarg in kwonlyargs
+    )
+    if varkw:
+        parameters.append(Parameter(varkw, Parameter.VAR_KEYWORD))
+    return_annotation = annotations.get("return", Signature.empty)
+    return str(Signature(parameters, return_annotation=return_annotation))
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py
new file mode 100644
index 00000000000..4ef0e19be49
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py
@@ -0,0 +1,234 @@
+"""Caching decorators. Currently provides ``lru_cache``, a drop-in
+replacement for ``functools.lru_cache`` with correct handling of instance
+methods: a separate cache is maintained per instance, stored as an
+attribute on the instance itself so it is cleaned up with the instance
+by the garbage collector. For plain functions, class methods, and static
+methods a single shared cache is used, matching ``functools.lru_cache``.
+"""
+
+from functools import lru_cache as _functools_lru_cache
+from functools import partial
+
+from .__wrapt__ import BaseObjectProxy, BoundFunctionWrapper, FunctionWrapper
+from .decorators import decorator
+from .synchronization import synchronized
+
+# Decorator that applies functools.lru_cache to the wrapped function.
+# Unlike using functools.lru_cache directly, this works correctly with
+# instance methods and class methods by maintaining a separate cache
+# per instance or class. Each per-instance cache is stored as an
+# attribute on the instance itself, so it is automatically cleaned up
+# when the instance is garbage collected. For plain functions and
+# static methods, a single cache is stored on the wrapper itself.
+# The underlying caches are created lazily on first call, with
+# double-checked locking via synchronized to avoid races in
+# multi-threaded code.
+#
+# Custom FunctionWrapper and BoundFunctionWrapper subclasses are used
+# so that cache_info() and cache_clear() are available directly on
+# the decorated function. For bound methods, the BoundFunctionWrapper
+# uses _self_instance to locate the per-instance cache.
+
+
+class _BoundLRUCacheFunctionWrapper(BoundFunctionWrapper):
+
+    def _is_instance_method(self):
+        return self._self_binding == "function"
+
+    def __call__(self, *args, **kwargs):
+        parent = self._self_parent
+
+        # For class methods and static methods, use a single shared
+        # cache stored on the parent wrapper. The cache is created
+        # from the bound __wrapped__ since the parent's __wrapped__
+        # is the raw classmethod/staticmethod descriptor.
+
+        if not self._is_instance_method():
+            if parent._self_cache is None:
+                with synchronized(parent):
+                    if parent._self_cache is None:
+                        parent._self_cache = _functools_lru_cache(
+                            **parent._self_lru_kwargs
+                        )(self.__wrapped__)
+
+            return parent._self_cache(*args, **kwargs)
+
+        # Instance method — per-instance cache stored as an attribute
+        # on the instance so it is cleaned up with the instance by the
+        # garbage collector.
+
+        instance = self._self_instance
+        cache_attr = parent._self_cache_attr
+
+        cache = getattr(instance, cache_attr, None)
+
+        if cache is None:
+            with synchronized(parent):
+                cache = getattr(instance, cache_attr, None)
+
+                if cache is None:
+                    cache = _functools_lru_cache(**parent._self_lru_kwargs)(
+                        self.__wrapped__
+                    )
+
+                    # If the instance the method is bound to is a wrapt
+                    # object proxy, a plain setattr() would fall through and
+                    # store the cache on the wrapped object rather than the
+                    # proxy. Use type() rather than isinstance() so the check
+                    # sees the real proxy type and is not fooled by the proxy
+                    # overriding __class__ to report the wrapped object's
+                    # type. Proxies expose __self_setattr__() which stores the
+                    # attribute on the proxy itself.
+
+                    if issubclass(type(instance), BaseObjectProxy):
+                        instance.__self_setattr__(cache_attr, cache)
+                    else:
+                        setattr(instance, cache_attr, cache)
+
+        return cache(*args, **kwargs)
+
+    def cache_info(self):
+        """Return the cache statistics for this binding's cache, or
+        ``None`` if the cache has not yet been created.
+        """
+
+        if not self._is_instance_method():
+            return self._self_parent.cache_info()
+
+        cache = getattr(self._self_instance, self._self_parent._self_cache_attr, None)
+
+        if cache is not None:
+            return cache.cache_info()
+
+        return None
+
+    def cache_clear(self):
+        """Clear this binding's cache."""
+
+        if not self._is_instance_method():
+            self._self_parent.cache_clear()
+            return
+
+        cache = getattr(self._self_instance, self._self_parent._self_cache_attr, None)
+
+        if cache is not None:
+            cache.cache_clear()
+
+    def cache_parameters(self):
+        """Return the parameters used to create the cache."""
+
+        if not self._is_instance_method():
+            return self._self_parent.cache_parameters()
+
+        cache = getattr(self._self_instance, self._self_parent._self_cache_attr, None)
+
+        if cache is not None:
+            return cache.cache_parameters()
+
+        return None
+
+
+class _LRUCacheFunctionWrapper(FunctionWrapper):
+
+    __bound_function_wrapper__ = _BoundLRUCacheFunctionWrapper
+
+    def __init__(self, wrapped, wrapper, **kwargs):
+        super().__init__(wrapped, wrapper, **kwargs)
+
+        # Extract the LRU cache configuration that was attached to the
+        # wrapper function before it was passed to the decorator.
+
+        self._self_lru_kwargs = wrapper._self_lru_kwargs
+        self._self_cache = None
+
+        # Use __func__ to get the name for classmethod/staticmethod
+        # descriptors which lack __name__ on Python < 3.10.
+
+        name = getattr(wrapped, "__name__", None)
+
+        if name is None:
+            name = wrapped.__func__.__name__
+
+        # The cache attribute name must be unique per decorated method so
+        # that a method overridden in a subclass does not share the same
+        # per-instance cache slot as the method it overrides. If they shared
+        # a slot, a subclass method calling super() would find the subclass
+        # cache and re-enter its own body, recursing forever. The owning
+        # class is not known here, since the decorator runs on the raw
+        # function before the class exists, but each decorated method has its
+        # own wrapper instance, so id(self) is a stable discriminator unique
+        # to this method definition.
+
+        self._self_cache_attr = "_lru_cache_" + name + "_" + str(id(self))
+
+    def __call__(self, *args, **kwargs):
+        # Plain function or static method — single cache stored
+        # on the wrapper itself.
+
+        if self._self_cache is None:
+            with synchronized(self):
+                if self._self_cache is None:
+                    self._self_cache = _functools_lru_cache(**self._self_lru_kwargs)(
+                        self.__wrapped__
+                    )
+
+        return self._self_cache(*args, **kwargs)
+
+    def cache_info(self):
+        """Return the cache statistics, or ``None`` if the cache has
+        not yet been created.
+        """
+
+        if self._self_cache is not None:
+            return self._self_cache.cache_info()
+
+        return None
+
+    def cache_clear(self):
+        """Clear the cache and reset the statistics."""
+
+        if self._self_cache is not None:
+            self._self_cache.cache_clear()
+
+    def cache_parameters(self):
+        """Return the parameters used to create the cache, or ``None``
+        if the cache has not yet been created.
+        """
+
+        if self._self_cache is not None:
+            return self._self_cache.cache_parameters()
+
+        return None
+
+
+def lru_cache(func=None, /, **kwargs):
+    """A decorator that applies ``functools.lru_cache`` to the wrapped
+    function, with correct handling for instance methods, class methods,
+    and static methods.
+
+    For instance methods, a separate ``functools.lru_cache`` is
+    maintained per instance. The cache is stored as an attribute on the
+    instance itself, so it is automatically cleaned up when the instance
+    is garbage collected. This means instances do not need to be
+    hashable, each instance gets its own full ``maxsize`` budget, and
+    no external mapping prevents garbage collection.
+
+    For plain functions, class methods, and static methods, a single
+    shared cache is used.
+
+    All keyword arguments are passed through to ``functools.lru_cache``.
+
+    Cache management methods ``cache_info()`` and ``cache_clear()`` are
+    available directly on the decorated function. For bound methods,
+    these operate on the per-instance cache for the bound instance.
+    """
+
+    if func is None:
+        return partial(lru_cache, **kwargs)
+
+    def _wrapper(wrapped, instance, args, _kwargs):
+        return wrapped(*args, **_kwargs)
+
+    _wrapper._self_lru_kwargs = kwargs
+
+    return decorator(_wrapper, proxy=_LRUCacheFunctionWrapper)(func)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py
new file mode 100644
index 00000000000..4c52b5d294b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py
@@ -0,0 +1,488 @@
+"""This module implements decorators for implementing other decorators
+as well as some commonly used decorators.
+
+"""
+
+from functools import partial
+from inspect import isclass, signature
+
+from .__wrapt__ import (
+    BaseObjectProxy,
+    BoundFunctionWrapper,
+    CallableObjectProxy,
+    FunctionWrapper,
+)
+from .arguments import formatargspec
+
+# Adapter wrapper for the wrapped function which will overlay certain
+# properties from the adapter function onto the wrapped function so that
+# functions such as inspect.getfullargspec(), inspect.signature() and
+# inspect.getsource() return the correct results one would expect.
+
+
+class _AdapterFunctionCode(CallableObjectProxy):
+
+    def __init__(self, wrapped_code, adapter_code):
+        # Explicit class in super() is used because the proxy overrides
+        # __class__ and MRO-related methods to delegate to the wrapped
+        # object, which can interfere with bare super().
+        super(_AdapterFunctionCode, self).__init__(wrapped_code)
+        self._self_adapter_code = adapter_code
+
+    @property
+    def co_argcount(self):
+        return self._self_adapter_code.co_argcount
+
+    @property
+    def co_code(self):
+        return self._self_adapter_code.co_code
+
+    @property
+    def co_flags(self):
+        return self._self_adapter_code.co_flags
+
+    @property
+    def co_kwonlyargcount(self):
+        return self._self_adapter_code.co_kwonlyargcount
+
+    @property
+    def co_varnames(self):
+        return self._self_adapter_code.co_varnames
+
+
+class _AdapterFunctionSurrogate(CallableObjectProxy):
+
+    def __init__(self, wrapped, adapter):
+        # Explicit class in super() is used because the proxy overrides
+        # __class__ and MRO-related methods to delegate to the wrapped
+        # object, which can interfere with bare super().
+        super(_AdapterFunctionSurrogate, self).__init__(wrapped)
+        self._self_adapter = adapter
+
+    @property
+    def __code__(self):
+        return _AdapterFunctionCode(
+            self.__wrapped__.__code__, self._self_adapter.__code__
+        )
+
+    @property
+    def __defaults__(self):
+        return self._self_adapter.__defaults__
+
+    @property
+    def __kwdefaults__(self):
+        return self._self_adapter.__kwdefaults__
+
+    @property
+    def __signature__(self):
+        return signature(self._self_adapter)
+
+
+class _BoundAdapterFunctionWrapper(BoundFunctionWrapper):
+
+    @property
+    def __func__(self):
+        return _AdapterFunctionSurrogate(
+            self.__wrapped__.__func__, self._self_parent._self_adapter
+        )
+
+    @property
+    def __signature__(self):
+        return signature(self._self_parent._self_adapter)
+
+
+class _AdapterFunctionWrapper(FunctionWrapper):
+
+    __bound_function_wrapper__ = _BoundAdapterFunctionWrapper
+
+    def __init__(self, *args, **kwargs):
+        adapter = kwargs.pop("adapter")
+        # Explicit class in super() is used because the proxy overrides
+        # __class__ and MRO-related methods to delegate to the wrapped
+        # object, which can interfere with bare super().
+        super(_AdapterFunctionWrapper, self).__init__(*args, **kwargs)
+        self._self_surrogate = _AdapterFunctionSurrogate(self.__wrapped__, adapter)
+        self._self_adapter = adapter
+
+    @property
+    def __code__(self):
+        return self._self_surrogate.__code__
+
+    @property
+    def __defaults__(self):
+        return self._self_surrogate.__defaults__
+
+    @property
+    def __kwdefaults__(self):
+        return self._self_surrogate.__kwdefaults__
+
+    @property
+    def __signature__(self):
+        return self._self_surrogate.__signature__
+
+
+class AdapterFactory:
+    def __call__(self, wrapped):
+        raise NotImplementedError()
+
+
+class _DelegatedAdapterFactory(AdapterFactory):
+    def __init__(self, factory):
+        # Explicit class in super() for consistency with proxy subclasses.
+        super(_DelegatedAdapterFactory, self).__init__()
+        self.factory = factory
+
+    def __call__(self, wrapped):
+        return self.factory(wrapped)
+
+
+adapter_factory = _DelegatedAdapterFactory
+
+# Decorator for creating other decorators. This decorator and the
+# wrappers which they use are designed to properly preserve any name
+# attributes, function signatures etc, in addition to the wrappers
+# themselves acting like a transparent proxy for the original wrapped
+# function so the wrapper is effectively indistinguishable from the
+# original wrapped function.
+
+
+def decorator(wrapper=None, /, *, enabled=None, adapter=None, proxy=FunctionWrapper):
+    """
+    The decorator should be supplied with a single positional argument
+    which is the `wrapper` function to be used to implement the
+    decorator. This may be preceded by a step whereby the keyword
+    arguments are supplied to customise the behaviour of the
+    decorator. The `adapter` argument is used to optionally denote a
+    separate function which is notionally used by an adapter
+    decorator. In that case parts of the function `__code__` and
+    `__defaults__` attributes are used from the adapter function
+    rather than those of the wrapped function. This allows for the
+    argument specification from `inspect.getfullargspec()` and similar
+    functions to be overridden with a prototype for a different
+    function than what was wrapped. The `enabled` argument provides a
+    way to enable/disable the use of the decorator. If the type of
+    `enabled` is a boolean, then it is evaluated immediately and the
+    wrapper not even applied if it is `False`. If not a boolean, it will
+    be evaluated when the wrapper is called for an unbound wrapper,
+    and when binding occurs for a bound wrapper. When being evaluated,
+    if `enabled` is callable it will be called to obtain the value to
+    be checked. If `False`, the wrapper will not be called and instead
+    the original wrapped function will be called directly instead.
+    The `proxy` argument provides a way of passing a custom version of
+    the `FunctionWrapper` class used in decorating the function.
+    """
+
+    if wrapper is not None:
+        # Helper function for creating wrapper of the appropriate
+        # time when we need it down below.
+
+        def _build(wrapped, wrapper, enabled=None, adapter=None):
+            # Where the adapter is a factory, call it to obtain the actual
+            # adapter before testing whether an adapter was supplied at
+            # all. The factory check is done first and by type, rather
+            # than relying on the truth value of the adapter, as a factory
+            # instance may evaluate as false if it defines `__bool__()` or
+            # `__len__()`. A factory which returns `None` or some other
+            # false value is treated as there being no adapter.
+
+            if isinstance(adapter, AdapterFactory):
+                adapter = adapter(wrapped)
+
+            if adapter:
+                if not callable(adapter):
+                    ns = {}
+
+                    # Check if the signature argument specification has
+                    # annotations. If it does then we need to remember
+                    # it but also drop it when attempting to manufacture
+                    # a standin adapter function. This is necessary else
+                    # it will try and look up any types referenced in
+                    # the annotations in the empty namespace we use,
+                    # which will fail.
+
+                    annotations = {}
+
+                    if not isinstance(adapter, str):
+                        if len(adapter) == 7:
+                            annotations = adapter[-1]
+                            adapter = adapter[:-1]
+                        adapter = formatargspec(*adapter)
+
+                    exec(f"def adapter{adapter}: pass", ns, ns)
+                    adapter = ns["adapter"]
+
+                    # Override the annotations for the manufactured
+                    # adapter function so they match the original
+                    # adapter signature argument specification.
+
+                    if annotations:
+                        adapter.__annotations__ = annotations
+
+                return _AdapterFunctionWrapper(
+                    wrapped=wrapped, wrapper=wrapper, enabled=enabled, adapter=adapter
+                )
+
+            return proxy(wrapped=wrapped, wrapper=wrapper, enabled=enabled)
+
+        # The wrapper has been provided so return the final decorator.
+        # The decorator is itself one of our function wrappers so we
+        # can determine when it is applied to functions, instance methods
+        # or class methods. This allows us to bind the instance or class
+        # method so the appropriate self or cls attribute is supplied
+        # when it is finally called.
+
+        def _wrapper(wrapped, instance, args, kwargs):
+            # We first check for the case where the decorator was applied
+            # to a class type.
+            #
+            #     @decorator
+            #     class mydecoratorclass:
+            #         def __init__(self, arg=None):
+            #             self.arg = arg
+            #         def __call__(self, wrapped, instance, args, kwargs):
+            #             return wrapped(*args, **kwargs)
+            #
+            #     @mydecoratorclass(arg=1)
+            #     def function():
+            #         pass
+            #
+            # In this case an instance of the class is to be used as the
+            # decorator wrapper function. If args was empty at this point,
+            # then it means that there were optional keyword arguments
+            # supplied to be used when creating an instance of the class
+            # to be used as the wrapper function.
+
+            if instance is None and isclass(wrapped) and not args:
+                # We still need to be passed the target function to be
+                # wrapped as yet, so we need to return a further function
+                # to be able to capture it.
+
+                def _capture(target_wrapped):
+                    # Now have the target function to be wrapped and need
+                    # to create an instance of the class which is to act
+                    # as the decorator wrapper function. Before we do that,
+                    # we need to first check that use of the decorator
+                    # hadn't been disabled by a simple boolean. If it was,
+                    # the target function to be wrapped is returned instead.
+
+                    _enabled = enabled
+                    if type(_enabled) is bool:
+                        if not _enabled:
+                            return target_wrapped
+                        _enabled = None
+
+                    # Now create an instance of the class which is to act
+                    # as the decorator wrapper function. Any arguments had
+                    # to be supplied as keyword only arguments so that is
+                    # all we pass when creating it.
+
+                    target_wrapper = wrapped(**kwargs)
+
+                    # Finally build the wrapper itself and return it.
+
+                    return _build(target_wrapped, target_wrapper, _enabled, adapter)
+
+                return _capture
+
+            # We should always have the target function to be wrapped at
+            # this point as the first (and only) value in args.
+
+            target_wrapped = args[0]
+
+            # Need to now check that use of the decorator hadn't been
+            # disabled by a simple boolean. If it was, then target
+            # function to be wrapped is returned instead.
+
+            _enabled = enabled
+            if type(_enabled) is bool:
+                if not _enabled:
+                    return target_wrapped
+                _enabled = None
+
+            # We now need to build the wrapper, but there are a couple of
+            # different cases we need to consider.
+
+            if instance is None:
+                if isclass(wrapped):
+                    # In this case the decorator was applied to a class
+                    # type but optional keyword arguments were not supplied
+                    # for initialising an instance of the class to be used
+                    # as the decorator wrapper function.
+                    #
+                    #     @decorator
+                    #     class mydecoratorclass:
+                    #         def __init__(self, arg=None):
+                    #             self.arg = arg
+                    #         def __call__(self, wrapped, instance,
+                    #                 args, kwargs):
+                    #             return wrapped(*args, **kwargs)
+                    #
+                    #     @mydecoratorclass
+                    #     def function():
+                    #         pass
+                    #
+                    # We still need to create an instance of the class to
+                    # be used as the decorator wrapper function, but no
+                    # arguments are pass.
+
+                    target_wrapper = wrapped()
+
+                else:
+                    # In this case the decorator was applied to a normal
+                    # function, or possibly a static method of a class.
+                    #
+                    #     @decorator
+                    #     def mydecoratorfuntion(wrapped, instance,
+                    #             args, kwargs):
+                    #         return wrapped(*args, **kwargs)
+                    #
+                    #     @mydecoratorfunction
+                    #     def function():
+                    #         pass
+                    #
+                    # That normal function becomes the decorator wrapper
+                    # function.
+
+                    target_wrapper = wrapper
+
+            else:
+                if isclass(instance):
+                    # In this case the decorator was applied to a class
+                    # method.
+                    #
+                    #     class myclass:
+                    #         @decorator
+                    #         @classmethod
+                    #         def decoratorclassmethod(cls, wrapped,
+                    #                 instance, args, kwargs):
+                    #             return wrapped(*args, **kwargs)
+                    #
+                    #     instance = myclass()
+                    #
+                    #     @instance.decoratorclassmethod
+                    #     def function():
+                    #         pass
+                    #
+                    # This one is a bit strange because binding was actually
+                    # performed on the wrapper created by our decorator
+                    # factory. We need to apply that binding to the decorator
+                    # wrapper function that the decorator factory
+                    # was applied to.
+
+                    target_wrapper = wrapper.__get__(None, instance)
+
+                else:
+                    # In this case the decorator was applied to an instance
+                    # method.
+                    #
+                    #     class myclass:
+                    #         @decorator
+                    #         def decoratorclassmethod(self, wrapped,
+                    #                 instance, args, kwargs):
+                    #             return wrapped(*args, **kwargs)
+                    #
+                    #     instance = myclass()
+                    #
+                    #     @instance.decoratorclassmethod
+                    #     def function():
+                    #         pass
+                    #
+                    # This one is a bit strange because binding was actually
+                    # performed on the wrapper created by our decorator
+                    # factory. We need to apply that binding to the decorator
+                    # wrapper function that the decorator factory
+                    # was applied to.
+
+                    target_wrapper = wrapper.__get__(instance, type(instance))
+
+            # Finally build the wrapper itself and return it.
+
+            return _build(target_wrapped, target_wrapper, _enabled, adapter)
+
+        # We first return our magic function wrapper here so we can
+        # determine in what context the decorator factory was used. In
+        # other words, it is itself a universal decorator. The decorator
+        # function is used as the adapter so that linters see a signature
+        # corresponding to the decorator and not the wrapper it is being
+        # applied to.
+
+        return _build(wrapper, _wrapper, adapter=decorator)
+
+    else:
+        # The wrapper still has not been provided, so we are just
+        # collecting the optional keyword arguments. Return the
+        # decorator again wrapped in a partial using the collected
+        # arguments.
+
+        return partial(decorator, enabled=enabled, adapter=adapter, proxy=proxy)
+
+
+# Descriptor decorator for automatically binding state to a wrapper.
+# When applied to a method decorated with function_wrapper or decorator,
+# it intercepts descriptor access so that when the method is accessed
+# via an instance, the instance is automatically attached to the
+# resulting wrapper using __self_setattr__. This is useful when you
+# want the wrapper to carry a reference back to the object that owns
+# the wrapper factory method, making state accessible through the
+# decorated function without manual setup.
+
+
+class _StateBindingWrapper(BaseObjectProxy):
+    """A descriptor decorator that binds the owner instance to wrappers
+    produced by a wrapper factory method.
+
+    When applied on top of a method decorated with ``function_wrapper``
+    or ``decorator``, it intercepts the descriptor ``__get__`` so that
+    when the method is accessed through an instance, the owner instance
+    is automatically attached as an attribute on the resulting wrapper
+    via ``__self_setattr__``.
+
+    The *name* keyword argument controls the attribute name under which
+    the owner instance is stored on the wrapper (default ``"state"``).
+    """
+
+    def __init__(self, *, name="state"):
+        # Initialise the proxy with a placeholder. The actual wrapper
+        # factory is set later when __call__ is invoked as a decorator.
+
+        super().__init__(None)
+
+        self._self_attr_name = name
+
+    def __call__(self, wrapper_factory):
+        # Called when used as a decorator, receiving the wrapper factory
+        # (the function_wrapper or decorator-decorated method) to wrap.
+
+        self.__wrapped__ = wrapper_factory
+
+        return self
+
+    def __get__(self, instance, owner):
+        # When accessed via the class rather than an instance, return
+        # the descriptor itself unchanged. This preserves introspection
+        # of the underlying wrapper factory via the object proxy.
+
+        if instance is None:
+            return self
+
+        # Bind the underlying wrapper factory to the instance so it
+        # receives the correct self/cls when called.
+
+        wrapper_factory = self.__wrapped__.__get__(instance, owner)
+
+        name = self._self_attr_name
+
+        def _bind(func):
+            wrapper = wrapper_factory(func)
+
+            # Attach the owner instance to the wrapper so it can be
+            # accessed as an attribute of the decorated function.
+
+            wrapper.__self_setattr__(name, instance)
+
+            return wrapper
+
+        return _bind
+
+
+bind_state_to_wrapper = _StateBindingWrapper
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py
new file mode 100644
index 00000000000..9dc24065c5b
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py
@@ -0,0 +1,128 @@
+"""The `with_doc` decorator: override the docstring that introspection tools
+see for a wrapped callable without mutating the wrapped function itself.
+Accepts the docstring directly, or a factory that derives it from the
+wrapped function at decoration time.
+
+This is the companion of `with_signature`, which overrides the signature in
+the same way. Assigning to `__doc__` on an ordinary wrapt wrapper writes
+through to the wrapped function, because `__doc__` on every proxy delegates
+to the wrapped object, so a wrapper carrying its own docstring is the only
+way to change what is reported without touching the wrapped function.
+"""
+
+from .__wrapt__ import BoundFunctionWrapper, FunctionWrapper
+
+# Marker for a wrapper which carries no docstring override, so that `__doc__`
+# keeps delegating to the wrapped function. Distinct from None, which is a
+# legitimate docstring override.
+
+_NO_DOC_OVERRIDE = object()
+
+# The `__doc__` property for a function wrapper which may carry a docstring
+# override in its `_self_doc` slot. The wrapper class must assign this to
+# `__doc__` in its own class body, rather than inherit it from a mixin, and
+# set `_self_doc` in its `__init__()`, to `_NO_DOC_OVERRIDE` when there is
+# none.
+#
+# Both the pure Python metaclass and the C extension attribute hooks
+# recognise a `__doc__` descriptor defined by a derived class and consult it
+# in place of the default delegation to the wrapped object. It has to be in
+# the class dictionary of the wrapper class itself though, because `pydoc`
+# reads `__doc__` using `object.__getattribute__()` to avoid inherited
+# docstrings, and with the C extension that bypasses the attribute hooks and
+# would otherwise find the copy of the wrapped function's docstring which is
+# held in the instance dictionary.
+#
+# Without an override, assignment and deletion write through to the wrapped
+# function as they do for any other wrapt wrapper. With one, assignment
+# replaces the override and deletion removes it, restoring delegation to the
+# wrapped function.
+
+
+def _get_doc(self):
+    doc = self._self_doc
+    if doc is _NO_DOC_OVERRIDE:
+        return self.__wrapped__.__doc__
+    return doc
+
+
+def _set_doc(self, value):
+    if self._self_doc is _NO_DOC_OVERRIDE:
+        self.__wrapped__.__doc__ = value
+    else:
+        self._self_doc = value
+
+
+def _del_doc(self):
+    if self._self_doc is _NO_DOC_OVERRIDE:
+        del self.__wrapped__.__doc__
+    else:
+        self._self_doc = _NO_DOC_OVERRIDE
+
+
+_DOC_PROPERTY = property(_get_doc, _set_doc, _del_doc)
+
+# The `__doc__` property for the bound wrapper of a function wrapper which
+# may carry a docstring override, reading it from the parent. A bound
+# wrapper is read only, as `__doc__` of a bound method is.
+
+
+def _get_bound_doc(self):
+    doc = self._self_parent._self_doc
+    if doc is _NO_DOC_OVERRIDE:
+        return self.__wrapped__.__doc__
+    return doc
+
+
+_BOUND_DOC_PROPERTY = property(_get_bound_doc)
+
+
+class _BoundDocFunctionWrapper(BoundFunctionWrapper):
+    __doc__ = _BOUND_DOC_PROPERTY
+
+
+class _DocFunctionWrapper(FunctionWrapper):
+    __doc__ = _DOC_PROPERTY
+
+    __bound_function_wrapper__ = _BoundDocFunctionWrapper
+
+    def __init__(self, wrapped, wrapper, doc):
+        super().__init__(wrapped, wrapper)
+        self._self_doc = doc
+
+
+def with_doc(wrapped=None, /, *, doc=None, factory=None):
+    """Override the docstring of a wrapped callable.
+
+    Exactly one of `doc` or `factory` must be supplied:
+
+    - `doc`: the docstring to report.
+    - `factory`: a callable `factory(wrapped)` invoked at decoration time
+      that returns the docstring to report.
+
+    The resulting wrapper reports the override as its `__doc__`, and so it
+    is what `help()` and `pydoc` display. The wrapped function is not
+    mutated, and assigning to `__doc__` on the wrapper replaces the override
+    rather than writing through to the wrapped function. Calling behaviour
+    is unchanged.
+    """
+
+    if doc is None and factory is None:
+        raise TypeError("with_doc requires one of doc= or factory=")
+    if doc is not None and factory is not None:
+        raise TypeError("with_doc accepts only one of doc= or factory=")
+
+    def _decorator(wrapped):
+        def _wrapper(wrapped, instance, args, kwargs):
+            return wrapped(*args, **kwargs)
+
+        if factory is not None:
+            resolved = factory(wrapped)
+        else:
+            resolved = doc
+
+        return _DocFunctionWrapper(wrapped, _wrapper, resolved)
+
+    if wrapped is None:
+        return _decorator
+    return _decorator(wrapped)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py
new file mode 100644
index 00000000000..35efecebdd7
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py
@@ -0,0 +1,69 @@
+"""Exception types raised by wrapt."""
+
+
+class WrapperNotInitializedError(ValueError):
+    """
+    Exception raised when a wrapper is in an inconsistent state: __init__ was
+    called but __wrapped__ is not set. Inherits from ValueError only, so it is
+    not silently swallowed by hasattr/getattr/except AttributeError patterns.
+    """
+
+    pass
+
+
+class PathResolutionError(AttributeError):
+    """
+    Exception raised when the dotted attribute path supplied for a patch
+    target could not be resolved. Inherits from AttributeError so existing
+    code catching that continues to work, while the message carries the
+    target, the full dotted path, and the failing segment, and the low-level
+    error is preserved as __cause__.
+    """
+
+    pass
+
+
+class TargetModuleNotFoundError(ModuleNotFoundError):
+    """
+    Exception raised when a patch target supplied as a string named a module
+    that could not be imported. Inherits from ModuleNotFoundError so existing
+    code catching that, or ImportError, continues to work, while the message
+    names the module and the attribute path being resolved, and the low-level
+    error is preserved as __cause__.
+    """
+
+    pass
+
+
+class WrapperChainTooDeepError(RuntimeError):
+    """
+    Exception raised when a scan of a chain of wrappers reached the traversal
+    limit with a further link still pending, so the result of the scan would
+    be indeterminate. Inherits from RuntimeError, following the precedent of
+    RecursionError for exhaustion of a depth limit, as it reports an
+    execution limit rather than a contract violation.
+    """
+
+    pass
+
+
+class WrapperNotFoundError(ValueError):
+    """
+    Exception raised when the wrapper to be removed was not found in the
+    chain of wrappers of the attribute, meaning nothing of the caller's is
+    installed there: it was never wrapped, was already removed, or the
+    attribute was replaced wholesale by a third party.
+    """
+
+    pass
+
+
+class WrapperNotOutermostError(ValueError):
+    """
+    Exception raised when the wrapper to be removed was found but cannot be
+    removed, because what sits directly above it in the chain is not a wrapt
+    wrapper whose link to it can be updated in place, or because the
+    attribute is served dynamically and has no owning location to restore.
+    """
+
+    pass
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py
new file mode 100644
index 00000000000..4c1ea5f629a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py
@@ -0,0 +1,314 @@
+"""This module implements a post import hook mechanism styled after what is
+described in PEP-369. Note that it doesn't cope with modules being reloaded.
+
+"""
+
+import importlib.metadata
+import sys
+import threading
+from collections.abc import Callable
+from importlib.util import find_spec
+
+from .__wrapt__ import BaseObjectProxy
+
+# The dictionary registering any post import hooks to be triggered once
+# the target module has been imported. Once a module has been imported
+# and the hooks fired, the list of hooks recorded against the target
+# module will be truncated but the list left in the dictionary. This
+# acts as a flag to indicate that the module had already been imported.
+
+_post_import_hooks: dict[str, list[Callable]] = {}
+_post_import_hooks_init = False
+_post_import_hooks_lock = threading.RLock()
+
+# Register a new post import hook for the target module name. This
+# differs from the PEP-369 implementation in that it also allows the
+# hook function to be specified as a string consisting of the name of
+# the callback in the form 'module:function'. This will result in a
+# proxy callback being registered which will defer loading of the
+# specified module containing the callback function until required.
+
+
+def _create_import_hook_from_string(name):
+    def import_hook(module):
+        module_name, function = name.split(":")
+        attrs = function.split(".")
+
+        # Use importlib.import_module() rather than __import__() as the
+        # latter fails for a module registered in sys.modules whose parent
+        # package is not importable. See resolve_path() in patches.py.
+
+        callback = importlib.import_module(module_name)
+        for attr in attrs:
+            callback = getattr(callback, attr)
+        return callback(module)
+
+    return import_hook
+
+
+def register_post_import_hook(hook, name):
+    """
+    Register a post import hook for the target module `name`. The `hook`
+    function will be called once the module is imported and will be passed the
+    module as argument. If the module is already imported, the `hook` will be
+    called immediately. If you also want to defer loading of the module containing
+    the `hook` function until required, you can specify the `hook` as a string in
+    the form 'module:function'. This will result in a proxy hook function being
+    registered which will defer loading of the specified module containing the
+    callback function until required.
+    """
+
+    # Create a deferred import hook if hook is a string name rather than
+    # a callable function.
+
+    if isinstance(hook, str):
+        hook = _create_import_hook_from_string(hook)
+
+    with _post_import_hooks_lock:
+        # Automatically install the import hook finder if it has not already
+        # been installed.
+
+        global _post_import_hooks_init
+
+        if not _post_import_hooks_init:
+            _post_import_hooks_init = True
+            sys.meta_path.insert(0, ImportHookFinder())
+
+        # Check if the module is already imported. If not, register the hook
+        # to be called after import.
+
+        module = sys.modules.get(name, None)
+
+        if module is None:
+            _post_import_hooks.setdefault(name, []).append(hook)
+
+    # If the module is already imported, we fire the hook right away. Note that
+    # the hook is called outside of the lock to avoid deadlocks if code run as a
+    # consequence of calling the module import hook in turn triggers a separate
+    # thread which tries to register an import hook.
+
+    if module is not None:
+        hook(module)
+
+
+# Register post import hooks defined as package entry points.
+
+
+def discover_post_import_hooks(group):
+    """
+    Discover and register post import hooks defined as package entry points
+    in the specified `group`. The group should be a string that matches the
+    entry point group name used in the package metadata.
+    """
+
+    try:
+        # Python 3.10+ style with select parameter
+        entrypoints = importlib.metadata.entry_points(group=group)
+    except TypeError:
+        # Python 3.8-3.9 style that returns a dict
+        entrypoints = importlib.metadata.entry_points().get(group, ())
+
+    for entrypoint in entrypoints:
+        callback = entrypoint.load()  # Use the loaded callback directly
+        register_post_import_hook(callback, entrypoint.name)
+
+
+# Indicate that a module has been loaded. Any post import hooks which
+# were registered against the target module will be invoked. If an
+# exception is raised in any of the post import hooks, that will cause
+# the import of the target module to fail.
+
+
+def notify_module_loaded(module):
+    """
+    Notify that a `module` has been loaded and invoke any post import hooks
+    registered against the module. If the module is not registered, this
+    function does nothing.
+    """
+
+    name = getattr(module, "__name__", None)
+
+    with _post_import_hooks_lock:
+        hooks = _post_import_hooks.pop(name, ())
+
+    # Note that the hook is called outside of the lock to avoid deadlocks if
+    # code run as a consequence of calling the module import hook in turn
+    # triggers a separate thread which tries to register an import hook.
+
+    for hook in hooks:
+        hook(module)
+
+
+# A custom module import finder. This intercepts attempts to import
+# modules and watches out for attempts to import target modules of
+# interest. When a module of interest is imported, then any post import
+# hooks which are registered will be invoked.
+
+
+class _ImportHookChainedLoader(BaseObjectProxy):
+
+    def __init__(self, loader):
+        # Explicit class in super() is used because the proxy overrides
+        # __class__ and MRO-related methods to delegate to the wrapped
+        # object, which can interfere with bare super().
+        super(_ImportHookChainedLoader, self).__init__(loader)
+
+        if hasattr(loader, "load_module"):
+            self.__self_setattr__("load_module", self._self_load_module)
+        if hasattr(loader, "create_module"):
+            self.__self_setattr__("create_module", self._self_create_module)
+        if hasattr(loader, "exec_module"):
+            self.__self_setattr__("exec_module", self._self_exec_module)
+
+    def _self_set_loader(self, module):
+        # Set module's loader to self.__wrapped__ unless it's already set to
+        # something else. Import machinery will set it to spec.loader if it is
+        # None, so handle None as well. The module may not support attribute
+        # assignment, in which case we simply skip it. Note that we also deal
+        # with __loader__ not existing at all. This is to future proof things
+        # due to proposal to remove the attribute as described in the GitHub
+        # issue at https://github.com/python/cpython/issues/77458. Also prior
+        # to Python 3.3, the __loader__ attribute was only set if a custom
+        # module loader was used. It isn't clear whether the attribute still
+        # existed in that case or was set to None.
+
+        class UNDEFINED:
+            pass
+
+        if getattr(module, "__loader__", UNDEFINED) in (None, self):
+            try:
+                module.__loader__ = self.__wrapped__
+            except AttributeError:
+                pass
+
+        if (
+            getattr(module, "__spec__", None) is not None
+            and getattr(module.__spec__, "loader", None) is self
+        ):
+            module.__spec__.loader = self.__wrapped__
+
+    def _self_load_module(self, fullname):
+        module = self.__wrapped__.load_module(fullname)
+        self._self_set_loader(module)
+        notify_module_loaded(module)
+
+        return module
+
+    # Python 3.4 introduced create_module() and exec_module() instead of
+    # load_module() alone. Splitting the two steps.
+
+    def _self_create_module(self, spec):
+        return self.__wrapped__.create_module(spec)
+
+    def _self_exec_module(self, module):
+        self._self_set_loader(module)
+        self.__wrapped__.exec_module(module)
+        notify_module_loaded(module)
+
+
+class ImportHookFinder:
+
+    def __init__(self):
+        self.in_progress = {}
+
+    def find_module(self, fullname, path=None):
+        with _post_import_hooks_lock:
+            # If the module being imported is not one we have registered
+            # post import hooks for, we can return immediately. We will
+            # take no further part in the importing of this module.
+
+            if fullname not in _post_import_hooks:
+                return None
+
+            # When we are interested in a specific module, we will call back
+            # into the import system a second time to defer to the import
+            # finder that is supposed to handle the importing of the module.
+            # We set an in progress flag for the target module so that on
+            # the second time through we don't trigger another call back
+            # into the import system and cause a infinite loop.
+
+            if fullname in self.in_progress:
+                return None
+
+            self.in_progress[fullname] = True
+
+        # Now call back into the import system again.
+
+        try:
+            # For Python 3 we need to use find_spec().loader
+            # from the importlib.util module. It doesn't actually
+            # import the target module and only finds the
+            # loader. If a loader is found, we need to return
+            # our own loader which will then in turn call the
+            # real loader to import the module and invoke the
+            # post import hooks.
+
+            loader = getattr(find_spec(fullname), "loader", None)
+
+            if loader and not isinstance(loader, _ImportHookChainedLoader):
+                return _ImportHookChainedLoader(loader)
+
+        finally:
+            del self.in_progress[fullname]
+
+    def find_spec(self, fullname, path=None, target=None):
+        # Since Python 3.4, you are meant to implement find_spec() method
+        # instead of find_module() and since Python 3.10 you get deprecation
+        # warnings if you don't define find_spec().
+
+        with _post_import_hooks_lock:
+            # If the module being imported is not one we have registered
+            # post import hooks for, we can return immediately. We will
+            # take no further part in the importing of this module.
+
+            if fullname not in _post_import_hooks:
+                return None
+
+            # When we are interested in a specific module, we will call back
+            # into the import system a second time to defer to the import
+            # finder that is supposed to handle the importing of the module.
+            # We set an in progress flag for the target module so that on
+            # the second time through we don't trigger another call back
+            # into the import system and cause a infinite loop.
+
+            if fullname in self.in_progress:
+                return None
+
+            self.in_progress[fullname] = True
+
+        # Now call back into the import system again.
+
+        try:
+            # This should only be Python 3 so find_spec() should always
+            # exist so don't need to check.
+
+            spec = find_spec(fullname)
+            loader = getattr(spec, "loader", None)
+
+            if loader and not isinstance(loader, _ImportHookChainedLoader):
+                spec.loader = _ImportHookChainedLoader(loader)
+
+            return spec
+
+        finally:
+            del self.in_progress[fullname]
+
+
+# Decorator for marking that a function should be called as a post
+# import hook when the target module is imported.
+
+
+def when_imported(name):
+    """
+    Returns a decorator that registers the decorated function as a post import
+    hook for the module specified by `name`. The function will be called once
+    the module with the specified name is imported, and will be passed the
+    module as argument. If the module is already imported, the function will
+    be called immediately.
+    """
+
+    def register(hook):
+        register_post_import_hook(hook, name)
+        return hook
+
+    return register
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py
new file mode 100644
index 00000000000..aa8727de580
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py
@@ -0,0 +1,851 @@
+"""Utilities for monkey patching and wrapping object attributes."""
+
+import contextlib
+import importlib
+import inspect
+import sys
+import warnings
+
+from .__wrapt__ import BaseObjectProxy, FunctionWrapper
+from .exceptions import (
+    PathResolutionError,
+    TargetModuleNotFoundError,
+    WrapperChainTooDeepError,
+    WrapperNotFoundError,
+    WrapperNotOutermostError,
+)
+from .importer import register_post_import_hook
+
+# Sentinel used where the absence of a value must be distinguishable from
+# None being supplied, or where an attribute having had no prior definition
+# must be represented as a value. Exposed as public API since code walking
+# wrapper chains needs to be able to test for it by identity, but only
+# meaningful where wrapt itself checks for it.
+
+
+class _MissingType:
+    """The type of the MISSING sentinel, which marks the absence of a value
+    or attribute definition where None is itself meaningful."""
+
+    _instance = None
+
+    def __new__(cls):
+        if cls._instance is None:
+            cls._instance = super().__new__(cls)
+        return cls._instance
+
+    def __repr__(self):
+        return ""
+
+    def __reduce__(self):
+        # Pickle and copy resolve back to the singleton so identity
+        # comparison against MISSING survives a round trip.
+        return (_MissingType, ())
+
+
+MISSING = _MissingType()
+
+# Helper functions for applying wrappers to existing functions.
+
+
+def resolve_path(target, name):
+    """
+    Resolves the dotted path supplied as `name` to an attribute on a target
+    object. The `target` can be a module, class, or instance of a class. If the
+    `target` argument is a string, it is assumed to be the name of a module,
+    which will be imported if necessary and then used as the target object.
+    Returns a tuple containing the parent object holding the attribute lookup
+    resolved to, the attribute name (path prefix removed if present), and the
+    original attribute value. If the module cannot be imported, raises
+    `TargetModuleNotFoundError`, and if the attribute path cannot be resolved,
+    raises `PathResolutionError`, in both cases with the original exception
+    preserved as the `__cause__` attribute.
+    """
+
+    if isinstance(target, str):
+        # Use importlib.import_module() rather than __import__() as the
+        # latter, even though it imports a dotted module name successfully
+        # from the sys.modules cache, computes its return value by importing
+        # the top level package, which fails for a module registered in
+        # sys.modules whose parent package is not importable.
+
+        try:
+            target = importlib.import_module(target)
+        except ModuleNotFoundError as exc:
+            raise TargetModuleNotFoundError(
+                f"unable to import module {target!r} while resolving "
+                f"the target for {name!r}"
+            ) from exc
+
+    parent = target
+
+    path = name.split(".")
+    attribute = path[0]
+
+    # We can't just always use getattr() because in doing
+    # that on a class it will cause binding to occur which
+    # will complicate things later and cause some things not
+    # to work. For the case of a class we therefore access
+    # the __dict__ directly. To cope though with the wrong
+    # class being given to us, or a method being moved into
+    # a base class, we need to walk the class hierarchy to
+    # work out exactly which __dict__ the method was defined
+    # in, as accessing it from __dict__ will fail if it was
+    # not actually on the class given. Fallback to using
+    # getattr() if we can't find it. If it truly doesn't
+    # exist, then that will fail.
+
+    def lookup_attribute(parent, attribute):
+        try:
+            if inspect.isclass(parent):
+                for cls in inspect.getmro(parent):
+                    if attribute in vars(cls):
+                        return vars(cls)[attribute]
+                else:
+                    return getattr(parent, attribute)
+            else:
+                return getattr(parent, attribute)
+        except AttributeError as exc:
+            raise PathResolutionError(
+                f"unable to resolve attribute {attribute!r} in path "
+                f"{name!r} on {target!r}"
+            ) from exc
+
+    original = lookup_attribute(parent, attribute)
+
+    for attribute in path[1:]:
+        parent = original
+        original = lookup_attribute(parent, attribute)
+
+    return (parent, attribute, original)
+
+
+def resolve_owner(target, name):
+    """
+    Sibling of the `resolve_path()` function, resolving the dotted path
+    supplied as `name` on a target object in the same way and returning a
+    tuple of the same shape, with one difference: the first element is the
+    object whose `__dict__` actually defines the attribute, rather than
+    the object the path resolved to. The two answer different questions.
+    `resolve_path()` answers where to write so that lookups through the
+    named object are affected, which is the correct location for
+    installing a wrapper, and shadowing an inherited definition is
+    legitimate there. `resolve_owner()` answers where the attribute
+    physically lives, which is the correct location for removing a
+    wrapper, since restoring anywhere other than the defining location
+    would leave a shadowing copy behind. For a class target the owner is
+    the defining class found by walking the MRO, for an instance target
+    it is the instance itself if the attribute is in its `__dict__` and
+    otherwise the defining class, and for a module target it is the
+    module. For dotted paths the owner logic applies to the final segment
+    only. An attribute served dynamically, such as by a module level or
+    metaclass `__getattr__`, exists in no `__dict__`, and rather than
+    guess, `PathResolutionError` is raised, where `resolve_path()` would
+    return the value happily. Failures resolving the path itself raise
+    exactly as for `resolve_path()`.
+    """
+
+    parent, attribute, original = resolve_path(target, name)
+
+    if inspect.isclass(parent):
+        candidates = inspect.getmro(parent)
+    elif inspect.ismodule(parent):
+        candidates = (parent,)
+    else:
+        candidates = (parent,) + tuple(inspect.getmro(type(parent)))
+
+    for candidate in candidates:
+        try:
+            if attribute in vars(candidate):
+                return (candidate, attribute, original)
+        except TypeError:
+            continue
+
+    raise PathResolutionError(
+        f"attribute {attribute!r} of {parent!r} is not defined in any "
+        f"__dict__; it is served dynamically, so there is no owning "
+        f"location to patch"
+    )
+
+
+def apply_patch(parent, attribute, replacement):
+    """
+    Convenience function for applying a patch to an attribute. This maps to
+    the standard setattr() function.
+    """
+
+    setattr(parent, attribute, replacement)
+
+
+def wrap_object(target, name, factory, args=(), kwargs=None):
+    """
+    Wraps an object which is the attribute of a target object with a wrapper
+    object created by the `factory` function. The `target` can be a module,
+    class, or instance of a class. In the special case of `target` being a
+    string, it is assumed to be the name of a module, with the module being
+    imported if necessary and then used as the target object. The `name` is a
+    string representing the dotted path to the attribute. The `factory` function
+    should accept the original object and may accept additional positional and
+    keyword arguments which will be set by unpacking input arguments using
+    `*args` and `**kwargs` calling conventions. The factory function should
+    return a new object that will replace the original object, and should
+    ordinarily be a `BaseObjectProxy` subclass or return an instance of
+    one, so that the replacement can carry the installation details which
+    `unwrap_object()` later relies upon to restore things faithfully.
+    """
+
+    if kwargs is None:
+        kwargs = {}
+
+    parent, attribute, original = resolve_path(target, name)
+
+    # Record whether applying the patch creates the attribute slot on the
+    # parent, or overwrites one which already existed. When the value was
+    # being served from somewhere else, such as a base class via the MRO,
+    # the class of an instance, or a dynamic __getattr__, the patch
+    # creates a shadowing slot, and faithful removal is deleting that
+    # slot again rather than assigning the original into it. This fact
+    # only exists at installation time, so it is stashed on the wrapper
+    # itself, in the local state of the proxy where lookups cannot be
+    # confused with anything of the wrapped object's, for
+    # unwrap_object() to consult. A factory result which is not a wrapt
+    # proxy cannot carry it and unwrap_object() falls back to what can
+    # be determined at removal time.
+
+    try:
+        created = attribute not in vars(parent)
+    except TypeError:
+        created = False
+
+    wrapper = factory(original, *args, **kwargs)
+
+    try:
+        wrapper.__self_setattr__("__wrapt_wrap_object_created_slot__", created)
+    except AttributeError:
+        pass
+
+    apply_patch(parent, attribute, wrapper)
+
+    return wrapper
+
+
+# Function for applying a proxy object to an attribute of a class
+# instance. The wrapper works by defining an attribute of the same name
+# on the class which is a descriptor and which intercepts access to the
+# instance attribute. The descriptor is itself an object proxy wrapping
+# whatever previously occupied the class attribute, be that another
+# AttributeWrapper, some other descriptor such as a property, a plain
+# class default, or the MISSING sentinel when nothing was defined, so
+# stacked applications compose rather than replace one another and the
+# prior definition keeps working beneath the interception.
+
+
+class AttributeWrapper(BaseObjectProxy):
+    """A descriptor that intercepts access to an instance attribute to apply
+    a wrapper factory. The descriptor is an object proxy whose wrapped object
+    is whatever previously occupied the class attribute, or the MISSING
+    sentinel when nothing did, so stacked applications compose and a prior
+    descriptor keeps executing its own logic beneath the interception."""
+
+    def __init__(self, wrapped, attribute, factory, args=(), kwargs=None):
+        super(AttributeWrapper, self).__init__(wrapped)
+        self._self_attribute = attribute
+        self._self_factory = factory
+        self._self_args = args
+        self._self_kwargs = kwargs if kwargs is not None else {}
+
+    def __get__(self, instance, owner=None):
+        # Class level access returns the descriptor itself. Being a
+        # transparent proxy, introspection of the prior definition then
+        # works through delegation.
+
+        if instance is None:
+            return self
+
+        # Reads follow the standard attribute lookup precedence: a data
+        # descriptor prior takes precedence over the instance
+        # dictionary, a non-data descriptor prior yields to it, and a
+        # plain class default is the fallback when no instance value
+        # exists. Only when the prior is the MISSING sentinel, meaning
+        # no definition of any sort existed, is AttributeError raised.
+
+        prior = self.__wrapped__
+        prior_type = type(prior)
+
+        if hasattr(prior_type, "__get__") and (
+            hasattr(prior_type, "__set__") or hasattr(prior_type, "__delete__")
+        ):
+            value = prior.__get__(instance, owner)
+        elif self._self_attribute in instance.__dict__:
+            value = instance.__dict__[self._self_attribute]
+        elif hasattr(prior_type, "__get__"):
+            value = prior.__get__(instance, owner)
+        elif prior is not MISSING:
+            value = prior
+        else:
+            raise AttributeError(
+                f"{type(instance).__name__!r} object has no attribute "
+                f"{self._self_attribute!r}"
+            )
+
+        return self._self_factory(value, *self._self_args, **self._self_kwargs)
+
+    def __set__(self, instance, value):
+        # Writes delegate to a prior descriptor which implements
+        # __set__, so its validation and storage are honoured, and
+        # otherwise store into the instance dictionary.
+
+        prior = self.__wrapped__
+
+        if hasattr(type(prior), "__set__"):
+            prior.__set__(instance, value)
+        else:
+            instance.__dict__[self._self_attribute] = value
+
+    def __delete__(self, instance):
+        prior = self.__wrapped__
+
+        if hasattr(type(prior), "__delete__"):
+            prior.__delete__(instance)
+        else:
+            # Match the exception deleting the attribute would raise if
+            # the wrapper had not been applied, which is AttributeError
+            # rather than the KeyError of the raw dictionary lookup.
+
+            try:
+                del instance.__dict__[self._self_attribute]
+            except KeyError:
+                raise AttributeError(
+                    f"{type(instance).__name__!r} object has no attribute "
+                    f"{self._self_attribute!r}"
+                ) from None
+
+
+def wrap_object_attribute(module, name, factory, args=(), kwargs=None):
+    """
+    Wraps an object which is the attribute of a class instance with a wrapper
+    object created by the `factory` function. It does this by patching the
+    class, not the instance, with a descriptor that intercepts access to the
+    instance attribute. The `module` can be a module, class, or instance of a
+    class. In the special case of `module` being a string, it is assumed to be
+    the name of a module, with the module being imported if necessary and then
+    used as the target object. The `name` is a string representing the dotted
+    path to the attribute. The `factory` function should accept the original
+    object and may accept additional positional and keyword arguments which will
+    be set by unpacking input arguments using `*args` and `**kwargs` calling
+    conventions. The factory function should return a new object that will
+    replace the original object. Returns the `AttributeWrapper` descriptor
+    installed on the class, which wraps whatever previously occupied the
+    class attribute, or the `MISSING` sentinel when nothing did, so repeated
+    applications compose rather than replace one another.
+    """
+
+    if kwargs is None:
+        kwargs = {}
+
+    path, attribute = name.rsplit(".", 1)
+    parent = resolve_path(module, path)[2]
+    prior = vars(parent).get(attribute, MISSING)
+    wrapper = AttributeWrapper(prior, attribute, factory, args, kwargs)
+    apply_patch(parent, attribute, wrapper)
+    return wrapper
+
+
+# Functions for creating a simple decorator using a FunctionWrapper,
+# plus short cut functions for applying wrappers to functions. These are
+# for use when doing monkey patching. For a more featured way of
+# creating decorators see the decorator decorator instead.
+
+
+def function_wrapper(wrapper):
+    """
+    Creates a decorator for wrapping a function with a `wrapper` function.
+    The decorator which is returned may also be applied to any other callable
+    objects such as lambda functions, methods, classmethods, and staticmethods,
+    or objects which implement the `__call__()` method. The `wrapper` function
+    should accept the `wrapped` function, `instance`, `args`, and `kwargs`,
+    arguments and return the result of calling the wrapped function or some
+    other appropriate value.
+    """
+
+    def _wrapper(wrapped, instance, args, kwargs):
+        target_wrapped = args[0]
+        if instance is None:
+            target_wrapper = wrapper
+        elif inspect.isclass(instance):
+            target_wrapper = wrapper.__get__(None, instance)
+        else:
+            target_wrapper = wrapper.__get__(instance, type(instance))
+        return FunctionWrapper(target_wrapped, target_wrapper)
+
+    return FunctionWrapper(wrapper, _wrapper)
+
+
+def wrap_function_wrapper(target, name, wrapper):
+    """
+    Wraps a function which is the attribute of a target object with a `wrapper`
+    function. The `target` can be a module, class, or instance of a class. In
+    the special case of `target` being a string, it is assumed to be the name
+    of a module, with the module being imported if necessary. If the `target`
+    is a string with a trailing ``?``, the wrapping will be deferred until the
+    module is imported. If the module is already imported, the wrapping will be
+    applied immediately. The `name` is a string representing the dotted path to
+    the attribute. The `wrapper` function should accept the `wrapped` function,
+    `instance`, `args`, and `kwargs` arguments, and would return the result of
+    calling the wrapped attribute or some other appropriate value. Returns the
+    wrapped target function if the wrapping was applied immediately, or ``None``
+    if the wrapping was deferred.
+    """
+
+    if isinstance(target, str) and target.endswith("?"):
+        target = target[:-1]
+
+        if target in sys.modules:
+            return wrap_object(sys.modules[target], name, FunctionWrapper, (wrapper,))
+
+        def callback(module):
+            wrap_object(module, name, FunctionWrapper, (wrapper,))
+
+        register_post_import_hook(callback, target)
+        return None
+
+    return wrap_object(target, name, FunctionWrapper, (wrapper,))
+
+
+def patch_function_wrapper(target, name, _enabled=MISSING, *, enabled=MISSING):
+    """
+    Creates a decorator which can be applied to a wrapper function, where the
+    wrapper function will be used to wrap a function which is the attribute of
+    a target object. The decorator returns the original wrapper function. The
+    `target` can be a module, class, or instance of a class. In the special case
+    of `target` being a string, it is assumed to be the name of a module, with
+    the module being imported if necessary. If the `target` is a string with a
+    trailing ``?``, the wrapping will be deferred until the module is imported.
+    If the module is already imported, the wrapping will be applied immediately.
+    The `name` is a string representing the dotted path to the attribute. The
+    `enabled` argument is keyword only and can be a boolean or a callable that
+    returns a boolean. When a callable is provided, it will be called each time
+    the wrapper is invoked to determine if the wrapper function should be
+    executed or whether the wrapped function should be called directly. If
+    `enabled` is not provided, or an explicit value of `None` is supplied,
+    the wrapper is enabled by default.
+    """
+
+    if _enabled is not MISSING:
+        if enabled is not MISSING:
+            raise TypeError(
+                "patch_function_wrapper() got multiple values for " "argument 'enabled'"
+            )
+        warnings.warn(
+            "Passing 'enabled' positionally to patch_function_wrapper() is "
+            "deprecated and will be an error in a future version of wrapt; "
+            "pass it as a keyword argument.",
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        enabled = _enabled
+
+    if enabled is MISSING:
+        enabled = None
+
+    def _wrapper(wrapper):
+        if isinstance(target, str) and target.endswith("?"):
+            _target = target[:-1]
+
+            if _target in sys.modules:
+                wrap_object(
+                    sys.modules[_target], name, FunctionWrapper, (wrapper, enabled)
+                )
+                return wrapper
+
+            def callback(module):
+                wrap_object(module, name, FunctionWrapper, (wrapper, enabled))
+
+            register_post_import_hook(callback, _target)
+            return wrapper
+
+        wrap_object(target, name, FunctionWrapper, (wrapper, enabled))
+        return wrapper
+
+    return _wrapper
+
+
+def transient_function_wrapper(target, name):
+    """Creates a decorator that patches a target function with a wrapper
+    function, but only for the duration of the call that the decorator was
+    applied to. The `target` can be a module, class, or instance of a class.
+    In the special case of `target` being a string, it is assumed to be the name
+    of a module, with the module being imported if necessary. The `name` is a
+    string representing the dotted path to the attribute. The patch is applied
+    to the object the path resolves to, so patching an attribute reached
+    through inheritance, or through an instance, only affects lookups made
+    through that object and not the class where the attribute is defined. In
+    that case the temporary attribute which shadowed the inherited definition
+    is removed again when the call exits, restoring the original lookup.
+
+    The temporary wrapper is removed using `unwrap_object()`, so if code
+    called within the scope of the patch wrapped over the top of the
+    temporary wrapper with a wrapt wrapper and left it there, the temporary
+    wrapper is spliced out beneath it, with the other wrapper left in
+    place. If something removed or replaced the temporary wrapper during
+    the call, `WrapperNotFoundError` is raised, and if what was applied on
+    top of it is not a wrapt wrapper and so cannot be spliced past,
+    `WrapperNotOutermostError` is raised. Both are loud deliberately, as
+    they indicate the surrounding code, typically a test harness, is not
+    managing its own patches properly, and the leaked patch state would
+    otherwise surface as hard to diagnose failures later.
+    """
+
+    def _decorator(wrapper):
+        def _wrapper(wrapped, instance, args, kwargs):
+            target_wrapped = args[0]
+            if instance is None:
+                target_wrapper = wrapper
+            elif inspect.isclass(instance):
+                target_wrapper = wrapper.__get__(None, instance)
+            else:
+                target_wrapper = wrapper.__get__(instance, type(instance))
+
+            def _execute(wrapped, instance, args, kwargs):
+                # The wrap and unwrap functions handle all the details:
+                # wrap_object() records whether applying the patch created
+                # a shadowing attribute slot, and unwrap_object() consults
+                # that record to restore or remove the attribute
+                # faithfully, splices the temporary wrapper out from
+                # beneath any wrapt wrapper left applied on top of it, and
+                # raises if the temporary wrapper was removed, replaced,
+                # or pinned beneath a non wrapt wrapper. An exception
+                # raised on exit supersedes any in-flight exception from
+                # the wrapped call, which remains visible as the chained
+                # __context__.
+
+                replacement = wrap_object(
+                    target, name, FunctionWrapper, (target_wrapper,)
+                )
+
+                try:
+                    return wrapped(*args, **kwargs)
+                finally:
+                    unwrap_object(target, name, replacement)
+
+            return FunctionWrapper(target_wrapped, _execute)
+
+        return FunctionWrapper(wrapper, _wrapper)
+
+    return _decorator
+
+
+@contextlib.contextmanager
+def scoped_function_wrapper(target, name, wrapper):
+    """Returns a context manager which patches a target function with a
+    wrapper function for the duration of a with statement, the block scoped
+    counterpart of the `transient_function_wrapper()` decorator. The
+    arguments take the same form as for `wrap_function_wrapper()`: the
+    `target` can be a module, class, or instance of a class, or the name of
+    a module as a string, the `name` is a string representing the dotted
+    path to the attribute, and the `wrapper` function should accept the
+    `wrapped`, `instance`, `args`, and `kwargs` arguments. The deferred
+    form of the `target` with a trailing ``?`` is not supported, since the
+    patch must be applied at the point the with statement is entered. The
+    context manager yields nothing, is single use, and removes the wrapper
+    using `unwrap_object()` when the block exits, with the same behaviour
+    as `transient_function_wrapper()` when something interfered with the
+    patch during the block: a wrapt wrapper applied on top of the temporary
+    wrapper and left there is tolerated, with the temporary wrapper spliced
+    out beneath it, while the temporary wrapper having been removed or
+    replaced raises `WrapperNotFoundError`, and a non wrapt wrapper left
+    applied on top raises `WrapperNotOutermostError`.
+    """
+
+    if isinstance(target, str) and target.endswith("?"):
+        raise ValueError(
+            "deferred wrapping using a target with a trailing '?' cannot "
+            "be used with scoped_function_wrapper()"
+        )
+
+    handle = wrap_function_wrapper(target, name, wrapper)
+
+    try:
+        yield
+    finally:
+        unwrap_object(target, name, handle)
+
+
+# Functions for introspecting chains of wrappers, linked by each wrapper
+# holding the object it wraps as the __wrapped__ attribute. The chain
+# protocol is shared by wrapt proxies and wrappers, functions decorated
+# using functools.wraps(), and anything else honouring the convention.
+
+
+def wrapper_chain(obj, *, limit=64):
+    """
+    Returns an iterator yielding `obj`, then each successive object found
+    by following the `__wrapped__` attribute, outermost wrapper first. The
+    final item yielded is the innermost object of the chain, which is not
+    itself a wrapper. Traversal ends cleanly at an object with no
+    `__wrapped__` attribute, or upon returning to an object already seen.
+    If the `limit` on the number of items yielded is reached with a further
+    chain link still pending, `WrapperChainTooDeepError` is raised, as a
+    truncated scan would otherwise be indistinguishable from a complete
+    one. A chain of exactly `limit` items which ends naturally is not an
+    error. Note that reading `__wrapped__` from a lazy object proxy will
+    cause it to materialize, and an exception raised by a broken proxy or
+    a lazy object factory will propagate to the caller.
+    """
+
+    # Cycle detection must use identity, not equality or a set of the
+    # objects themselves, since proxies delegate __eq__ and __hash__ to
+    # the wrapped object. Objects seen are therefore tracked by id(),
+    # with strong references also held so no visited object can be
+    # garbage collected and have its id reused while the scan runs, ids
+    # being unique among simultaneously live objects.
+
+    seen = []
+    seen_ids = set()
+
+    current = obj
+
+    while True:
+        if id(current) in seen_ids:
+            return
+
+        if len(seen) >= limit:
+            raise WrapperChainTooDeepError(
+                f"wrapper chain of {obj!r} exceeded {limit} levels"
+            )
+
+        seen.append(current)
+        seen_ids.add(id(current))
+
+        yield current
+
+        try:
+            current = current.__wrapped__
+        except AttributeError:
+            return
+
+
+def unwrapped(obj, *, limit=64):
+    """
+    Returns the innermost object of the chain of wrappers followed from
+    `obj` by the `wrapper_chain()` function, or `obj` itself when it is not
+    wrapped. Shares the full contract of `wrapper_chain()`, including
+    raising `WrapperChainTooDeepError` when the scan is indeterminate,
+    rather than returning a mid chain wrapper as if it were the innermost
+    object.
+    """
+
+    result = obj
+
+    for result in wrapper_chain(obj, limit=limit):
+        pass
+
+    return result
+
+
+def find_wrapper(obj, handle=None, *, predicate=None, limit=64):
+    """
+    Scans the chain of wrappers followed from `obj` by the
+    `wrapper_chain()` function for a specific wrapper and returns it, or
+    `None` when it is not present. The `handle` argument is the wrapper
+    object to look for, as returned by the wrap functions when the wrapper
+    was installed, and is matched by object identity only, never equality,
+    which proxies delegate to the wrapped object. Alternatively a
+    `predicate` function may be supplied, in which case the first chain
+    entry for which it returns true is returned, and is itself usable as a
+    handle thereafter. When both are supplied, both must match. At least
+    one of the two must be supplied, since testing for the mere presence
+    of any wrapper is fragile: were the target library to adopt wrapt for
+    its own purposes, such a test would wrongly conclude a wrapper of
+    yours was installed. Shares the full contract of `wrapper_chain()`,
+    including raising `WrapperChainTooDeepError` when the scan is
+    indeterminate, rather than returning `None` as a false negative.
+    """
+
+    if handle is None and predicate is None:
+        raise TypeError(
+            "find_wrapper() requires a wrapper handle or a predicate"
+        )
+
+    for entry in wrapper_chain(obj, limit=limit):
+        if handle is not None and entry is not handle:
+            continue
+        if predicate is not None and not predicate(entry):
+            continue
+        return entry
+
+    return None
+
+
+def is_wrapped_by(obj, handle=None, *, predicate=None, limit=64):
+    """
+    Boolean convenience form of the `find_wrapper()` function, returning
+    whether the wrapper is present in the chain of wrappers followed from
+    `obj`. With a `handle`, this answers whether the wrapper it was
+    returned for when installed is still in place, which is the check to
+    run when a third party may have replaced the attribute wholesale.
+    Shares the full contract of `find_wrapper()`, including raising
+    `WrapperChainTooDeepError` when the scan is indeterminate, rather
+    than returning `False` as a false negative.
+    """
+
+    return find_wrapper(obj, handle, predicate=predicate, limit=limit) is not None
+
+
+def unwrap_object(target, name, handle, *, missing_ok=False):
+    """
+    Removes a wrapper which was installed on an attribute of a target
+    object, the inverse of the `wrap_object()` function and the removal
+    call for every wrap form, `wrap_function_wrapper()` and
+    `wrap_object_attribute()` included. The `target` and `name` arguments
+    take the same form as for `resolve_path()`. The `handle` argument is
+    the wrapper object which was returned when the wrapper was installed,
+    and is matched by object identity only. Note that it is not the
+    wrapper function: passing the wrapper function surfaces immediately
+    as `WrapperNotFoundError`, since a function is never a chain entry.
+
+    When the wrapper is found and is outermost, the attribute is restored
+    to the object the wrapper wrapped, at the location where the attribute
+    is actually defined per `resolve_owner()`, so removal through a
+    subclass restores the defining base class rather than leaving a
+    shadowing copy. If restoring would merely shadow the identical object
+    already reachable through the MRO, or the wrapper was installed where
+    no prior definition existed (a `MISSING` terminal), the attribute is
+    instead removed so no residue is left behind. When the wrapper is
+    found buried beneath other wrapt wrappers, it is spliced out of the
+    chain in place, without touching the attribute or disturbing the
+    wrappers above it. When what sits directly above it is not a wrapt
+    wrapper, such as a plain `functools.wraps()` closure whose
+    `__wrapped__` is only metadata, `WrapperNotOutermostError` is raised
+    naming what is above, since splicing there would silently not take
+    effect.
+
+    When the wrapper is not found, because the attribute was never
+    wrapped, the wrapper was already removed, or a third party replaced
+    the attribute wholesale, `WrapperNotFoundError` is raised by default.
+    Passing `missing_ok=True` returns `None` instead, for shutdown paths
+    which must tolerate third party interference. In either case nothing
+    is mutated. The wrapper which was removed is returned. Note that
+    `missing_ok` does not suppress `WrapperChainTooDeepError` from the
+    underlying scan, since an indeterminate scan is not the same thing as
+    the wrapper being gone.
+    """
+
+    try:
+        owner, attribute, current = resolve_owner(target, name)
+    except PathResolutionError as exc:
+        # The attribute is either wholly absent or served dynamically
+        # with no owning location. In neither case is anything of the
+        # caller's statically installed, so both are the not-found
+        # case, except when the wrapper is present in the dynamically
+        # served value, where removal is simply not possible.
+
+        try:
+            current = resolve_path(target, name)[2]
+        except PathResolutionError:
+            current = None
+
+        if current is not None and find_wrapper(current, handle) is not None:
+            raise WrapperNotOutermostError(
+                f"cannot remove {type(handle).__name__} from "
+                f"{target!r}.{name}: the attribute is served dynamically "
+                f"and has no owning location to restore"
+            ) from exc
+
+        if missing_ok:
+            return None
+
+        raise WrapperNotFoundError(
+            f"handle {handle!r} not found on {target!r}.{name}"
+        ) from exc
+
+    found = find_wrapper(current, handle)
+
+    if found is not None:
+        try:
+            restored = found.__wrapped__
+        except AttributeError:
+            # The terminal original object was matched, which the chain
+            # also yields; not being a wrapper, it is not a legitimate
+            # handle.
+            found = None
+
+    if found is None:
+        if missing_ok:
+            return None
+        raise WrapperNotFoundError(
+            f"handle {handle!r} not found on {target!r}.{name}"
+        )
+
+    if found is not current:
+        chain = list(wrapper_chain(current))
+
+        # The scan must use identity, since list.index() would use
+        # __eq__, which proxies delegate to the wrapped object.
+
+        position = next(
+            index for index, entry in enumerate(chain) if entry is found
+        )
+        neighbour = chain[position - 1]
+
+        if not issubclass(type(neighbour), BaseObjectProxy):
+            above = [type(entry).__name__ for entry in chain[:position]]
+            raise WrapperNotOutermostError(
+                f"cannot remove {type(found).__name__} from "
+                f"{target!r}.{name}: wrapped by {above}"
+            )
+
+        neighbour.__wrapped__ = restored
+        return found
+
+    if restored is MISSING:
+        # The wrapper was installed where no prior definition existed.
+        delattr(owner, attribute)
+        return found
+
+    # When wrap_object() installed the wrapper, it recorded on the
+    # wrapper itself whether applying the patch created the attribute
+    # slot. That fact is authoritative: since the wrapper is still
+    # installed and outermost here, the slot cannot have been touched
+    # since it was recorded. It must be read from the proxy's own local
+    # state only, since ordinary attribute access would delegate a
+    # missing entry to the wrapped object and could answer with an
+    # inner wrapper's record instead.
+
+    try:
+        created = found.__self_dict__.get("__wrapt_wrap_object_created_slot__")
+    except AttributeError:
+        created = None
+
+    if created is not None:
+        if created:
+            # Installing the wrapper created a shadowing slot, so
+            # removing the attribute reinstates the original lookup,
+            # be that through the MRO, the class of an instance, or a
+            # dynamic __getattr__, rather than leaving a permanent
+            # copy of the original behind.
+            delattr(owner, attribute)
+        else:
+            apply_patch(owner, attribute, restored)
+        return found
+
+    # The wrapper does not carry the installation record, so fall back
+    # to what can be determined at removal time: if removing the
+    # attribute from a class would re-expose the identical restored
+    # object through the MRO, the wrap must have created a shadow.
+
+    if inspect.isclass(owner):
+        inherited = next(
+            (
+                vars(cls)[attribute]
+                for cls in inspect.getmro(owner)[1:]
+                if attribute in vars(cls)
+            ),
+            None,
+        )
+        if inherited is restored:
+            delattr(owner, attribute)
+            return found
+
+    apply_patch(owner, attribute, restored)
+    return found
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py
new file mode 100644
index 00000000000..18c80e0523e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py
@@ -0,0 +1,386 @@
+"""Variants of ObjectProxy for different use cases."""
+
+from collections.abc import Callable
+from types import ModuleType
+
+from .__wrapt__ import BaseObjectProxy
+from .synchronization import synchronized
+
+# Define ObjectProxy which for compatibility adds `__iter__()` support which
+# has been removed from `BaseObjectProxy`.
+
+
+class ObjectProxy(BaseObjectProxy):
+    """A generic object proxy which forwards special methods as needed.
+    For backwards compatibility this class adds support for `__iter__()`. If
+    you don't need backward compatibility for `__iter__()` support then it is
+    preferable to use `BaseObjectProxy` directly. If you want automatic
+    support for special dunder methods for callables, iterators, and async,
+    then use `AutoObjectProxy`."""
+
+    @property
+    def __object_proxy__(self):
+        return ObjectProxy
+
+    def __iter__(self):
+        return iter(self.__wrapped__)
+
+
+# Define variant of ObjectProxy which can automatically adjust to the wrapped
+# object and add special dunder methods.
+
+
+def __wrapper_call__(*args, **kwargs):
+    def _unpack_self(self, *args):
+        return self, args
+
+    self, args = _unpack_self(*args)
+
+    return self.__wrapped__(*args, **kwargs)
+
+
+def __wrapper_iter__(self):
+    return iter(self.__wrapped__)
+
+
+def __wrapper_next__(self):
+    return self.__wrapped__.__next__()
+
+
+def __wrapper_aiter__(self):
+    return self.__wrapped__.__aiter__()
+
+
+async def __wrapper_anext__(self):
+    return await self.__wrapped__.__anext__()
+
+
+def __wrapper_length_hint__(self):
+    return self.__wrapped__.__length_hint__()
+
+
+def __wrapper_fspath__(self):
+    return self.__wrapped__.__fspath__()
+
+
+def __wrapper_await__(self):
+    return (yield from self.__wrapped__.__await__())
+
+
+def __wrapper_get__(self, instance, owner=None):
+    return self.__wrapped__.__get__(instance, owner)
+
+
+def __wrapper_set__(self, instance, value):
+    return self.__wrapped__.__set__(instance, value)
+
+
+def __wrapper_delete__(self, instance):
+    return self.__wrapped__.__delete__(instance)
+
+
+def __wrapper_set_name__(self, owner, name):
+    return self.__wrapped__.__set_name__(owner, name)
+
+
+class AutoObjectProxy(BaseObjectProxy):
+    """An object proxy which can automatically adjust to the wrapped object
+    and add special dunder methods as needed. Note that this creates a new
+    class for each instance, so it has much higher memory overhead than using
+    `BaseObjectProxy` directly. If you know what special dunder methods you need
+    then it is preferable to use `BaseObjectProxy` directly and add them to a
+    subclass as needed. If you only need `__iter__()` support for backwards
+    compatibility then use `ObjectProxy` instead.
+    """
+
+    def __new__(cls, wrapped, *args, **kwargs):
+        """Injects special dunder methods into a dynamically created subclass
+        as needed based on the wrapped object. Any further arguments are
+        those a derived class has added to `__init__()` and are ignored.
+        """
+
+        namespace = {}
+
+        # Special methods are only ever looked up on the type of the wrapped
+        # object, never on the instance itself, so the special methods to add
+        # are determined from dir() of the type of the wrapped object. For a
+        # class the type is its metaclass, as the special methods a class
+        # defines in its body apply to its instances, not to the class
+        # itself.
+
+        wrapped_attrs = dir(type(wrapped))
+        class_attrs = set(dir(cls))
+
+        if callable(wrapped) and "__call__" not in class_attrs:
+            namespace["__call__"] = __wrapper_call__
+
+        if "__iter__" in wrapped_attrs and "__iter__" not in class_attrs:
+            namespace["__iter__"] = __wrapper_iter__
+
+        if "__next__" in wrapped_attrs and "__next__" not in class_attrs:
+            namespace["__next__"] = __wrapper_next__
+
+        if "__aiter__" in wrapped_attrs and "__aiter__" not in class_attrs:
+            namespace["__aiter__"] = __wrapper_aiter__
+
+        if "__anext__" in wrapped_attrs and "__anext__" not in class_attrs:
+            namespace["__anext__"] = __wrapper_anext__
+
+        if "__length_hint__" in wrapped_attrs and "__length_hint__" not in class_attrs:
+            namespace["__length_hint__"] = __wrapper_length_hint__
+
+        if "__fspath__" in wrapped_attrs and "__fspath__" not in class_attrs:
+            namespace["__fspath__"] = __wrapper_fspath__
+
+        # Note that not providing compatibility with generator-based coroutines
+        # (PEP 342) here as they are removed in Python 3.11+ and were deprecated
+        # in 3.8.
+
+        if "__await__" in wrapped_attrs and "__await__" not in class_attrs:
+            namespace["__await__"] = __wrapper_await__
+
+        if "__get__" in wrapped_attrs and "__get__" not in class_attrs:
+            namespace["__get__"] = __wrapper_get__
+
+        if "__set__" in wrapped_attrs and "__set__" not in class_attrs:
+            namespace["__set__"] = __wrapper_set__
+
+        if "__delete__" in wrapped_attrs and "__delete__" not in class_attrs:
+            namespace["__delete__"] = __wrapper_delete__
+
+        if "__set_name__" in wrapped_attrs and "__set_name__" not in class_attrs:
+            namespace["__set_name__"] = __wrapper_set_name__
+
+        name = cls.__name__
+
+        if cls is AutoObjectProxy:
+            name = BaseObjectProxy.__name__
+
+        # Explicit class in super() is required here to ensure __new__
+        # is called on the parent of AutoObjectProxy, not the dynamically
+        # created subclass.
+        return super(AutoObjectProxy, cls).__new__(type(name, (cls,), namespace))
+
+    def __wrapped_setattr_fixups__(self):
+        """Adjusts special dunder methods on the class as needed based on the
+        wrapped object, when `__wrapped__` is changed.
+        """
+
+        cls = type(self)
+        class_attrs = set(dir(cls))
+
+        # As for __new__() above, special methods are only ever looked up on
+        # the type of the wrapped object, never on the instance itself, so
+        # check for them on the type of the wrapped object.
+
+        wrapped_type = type(self.__wrapped__)
+
+        if callable(self.__wrapped__):
+            if "__call__" not in class_attrs:
+                cls.__call__ = __wrapper_call__
+        elif getattr(cls, "__call__", None) is __wrapper_call__:
+            delattr(cls, "__call__")
+
+        if hasattr(wrapped_type, "__iter__"):
+            if "__iter__" not in class_attrs:
+                cls.__iter__ = __wrapper_iter__
+        elif getattr(cls, "__iter__", None) is __wrapper_iter__:
+            delattr(cls, "__iter__")
+
+        if hasattr(wrapped_type, "__next__"):
+            if "__next__" not in class_attrs:
+                cls.__next__ = __wrapper_next__
+        elif getattr(cls, "__next__", None) is __wrapper_next__:
+            delattr(cls, "__next__")
+
+        if hasattr(wrapped_type, "__aiter__"):
+            if "__aiter__" not in class_attrs:
+                cls.__aiter__ = __wrapper_aiter__
+        elif getattr(cls, "__aiter__", None) is __wrapper_aiter__:
+            delattr(cls, "__aiter__")
+
+        if hasattr(wrapped_type, "__anext__"):
+            if "__anext__" not in class_attrs:
+                cls.__anext__ = __wrapper_anext__
+        elif getattr(cls, "__anext__", None) is __wrapper_anext__:
+            delattr(cls, "__anext__")
+
+        if hasattr(wrapped_type, "__length_hint__"):
+            if "__length_hint__" not in class_attrs:
+                cls.__length_hint__ = __wrapper_length_hint__
+        elif getattr(cls, "__length_hint__", None) is __wrapper_length_hint__:
+            delattr(cls, "__length_hint__")
+
+        if hasattr(wrapped_type, "__fspath__"):
+            if "__fspath__" not in class_attrs:
+                cls.__fspath__ = __wrapper_fspath__
+        elif getattr(cls, "__fspath__", None) is __wrapper_fspath__:
+            delattr(cls, "__fspath__")
+
+        if hasattr(wrapped_type, "__await__"):
+            if "__await__" not in class_attrs:
+                cls.__await__ = __wrapper_await__
+        elif getattr(cls, "__await__", None) is __wrapper_await__:
+            delattr(cls, "__await__")
+
+        if hasattr(wrapped_type, "__get__"):
+            if "__get__" not in class_attrs:
+                cls.__get__ = __wrapper_get__
+        elif getattr(cls, "__get__", None) is __wrapper_get__:
+            delattr(cls, "__get__")
+
+        if hasattr(wrapped_type, "__set__"):
+            if "__set__" not in class_attrs:
+                cls.__set__ = __wrapper_set__
+        elif getattr(cls, "__set__", None) is __wrapper_set__:
+            delattr(cls, "__set__")
+
+        if hasattr(wrapped_type, "__delete__"):
+            if "__delete__" not in class_attrs:
+                cls.__delete__ = __wrapper_delete__
+        elif getattr(cls, "__delete__", None) is __wrapper_delete__:
+            delattr(cls, "__delete__")
+
+        if hasattr(wrapped_type, "__set_name__"):
+            if "__set_name__" not in class_attrs:
+                cls.__set_name__ = __wrapper_set_name__
+        elif getattr(cls, "__set_name__", None) is __wrapper_set_name__:
+            delattr(cls, "__set_name__")
+
+
+class LazyObjectProxy(AutoObjectProxy):
+    """An object proxy which can generate/create the wrapped object on demand
+    when it is first needed.
+    """
+
+    def __new__(cls, callback=None, *args, interface=..., **kwargs):
+        """Injects special dunder methods into a dynamically created subclass
+        as needed based on the declared interface of the wrapped object. Any
+        further arguments are those a derived class has added to `__init__()`
+        and are ignored.
+        """
+
+        if interface is ...:
+            interface = type(None)
+
+        namespace = {}
+
+        interface_attrs = dir(interface)
+        class_attrs = set(dir(cls))
+
+        if "__call__" in interface_attrs and "__call__" not in class_attrs:
+            namespace["__call__"] = __wrapper_call__
+
+        if "__iter__" in interface_attrs and "__iter__" not in class_attrs:
+            namespace["__iter__"] = __wrapper_iter__
+
+        if "__next__" in interface_attrs and "__next__" not in class_attrs:
+            namespace["__next__"] = __wrapper_next__
+
+        if "__aiter__" in interface_attrs and "__aiter__" not in class_attrs:
+            namespace["__aiter__"] = __wrapper_aiter__
+
+        if "__anext__" in interface_attrs and "__anext__" not in class_attrs:
+            namespace["__anext__"] = __wrapper_anext__
+
+        if (
+            "__length_hint__" in interface_attrs
+            and "__length_hint__" not in class_attrs
+        ):
+            namespace["__length_hint__"] = __wrapper_length_hint__
+
+        if "__fspath__" in interface_attrs and "__fspath__" not in class_attrs:
+            namespace["__fspath__"] = __wrapper_fspath__
+
+        # Note that not providing compatibility with generator-based coroutines
+        # (PEP 342) here as they are removed in Python 3.11+ and were deprecated
+        # in 3.8.
+
+        if "__await__" in interface_attrs and "__await__" not in class_attrs:
+            namespace["__await__"] = __wrapper_await__
+
+        if "__get__" in interface_attrs and "__get__" not in class_attrs:
+            namespace["__get__"] = __wrapper_get__
+
+        if "__set__" in interface_attrs and "__set__" not in class_attrs:
+            namespace["__set__"] = __wrapper_set__
+
+        if "__delete__" in interface_attrs and "__delete__" not in class_attrs:
+            namespace["__delete__"] = __wrapper_delete__
+
+        if "__set_name__" in interface_attrs and "__set_name__" not in class_attrs:
+            namespace["__set_name__"] = __wrapper_set_name__
+
+        name = cls.__name__
+
+        # Explicit class in super() is required here to ensure __new__
+        # is called on the parent of AutoObjectProxy, not the dynamically
+        # created subclass.
+        return super(AutoObjectProxy, cls).__new__(type(name, (cls,), namespace))
+
+    def __init__(self, callback=None, *, interface=...):
+        """Initialize the object proxy with wrapped object as `None` but due
+        to presence of special `__wrapped_factory__` attribute addded first,
+        this will actually trigger the deferred creation of the wrapped object
+        when first needed.
+        """
+
+        if callback is not None:
+            self.__wrapped_factory__ = callback
+
+        super().__init__(None)
+
+    __wrapped_get_called__ = False
+
+    def __wrapped_factory__(self):
+        return None
+
+    def __wrapped_get__(self):
+        """Gets the wrapped object, creating it if necessary."""
+
+        # We synchronize on the class type, which will be unique to this instance
+        # since we inherit from `AutoObjectProxy` which creates a new class
+        # for each instance. If we synchronize on `self` or the method then
+        # we can end up in infinite recursion via `__getattr__()`.
+
+        with synchronized(type(self)):
+            # We were called because `__wrapped__` was not set, but because of
+            # multiple threads we may find that it has been set by the time
+            # we get the lock. So check again now whether `__wrapped__` is set.
+            # If it is then just return it, otherwise call the factory to
+            # create it.
+
+            if self.__wrapped_get_called__:
+                return self.__wrapped__
+
+            self.__wrapped__ = self.__wrapped_factory__()
+
+            self.__wrapped_get_called__ = True
+
+            return self.__wrapped__
+
+
+def lazy_import(name, attribute=None, *, interface=...):
+    """Lazily imports the module `name`, returning a `LazyObjectProxy` which
+    will import the module when it is first needed. When `name is a dotted name,
+    then the full dotted name is imported and the last module is taken as the
+    target. If `attribute` is provided then it is used to retrieve an attribute
+    from the module.
+    """
+
+    if attribute is not None:
+        if interface is ...:
+            interface = Callable
+    else:
+        if interface is ...:
+            interface = ModuleType
+
+    def _import():
+        module = __import__(name, fromlist=[""])
+
+        if attribute is not None:
+            return getattr(module, attribute)
+
+        return module
+
+    return LazyObjectProxy(_import, interface=interface)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py
new file mode 100644
index 00000000000..a0a7e6e4ce8
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py
@@ -0,0 +1,270 @@
+"""The `with_signature` decorator: override the signature (and related
+introspection attributes) of a wrapped callable without mutating the wrapped
+function itself. Accepts a prototype callable, a prebuilt `inspect.Signature`,
+or a factory that derives a signature from the wrapped function at decoration
+time.
+
+This replaces the need for the `adapter=` argument of `wrapt.decorator`,
+which is planned for deprecation.
+"""
+
+from inspect import CO_VARARGS, CO_VARKEYWORDS, Parameter, Signature
+from inspect import signature as _inspect_signature
+
+from .__wrapt__ import (
+    BaseObjectProxy,
+    BoundFunctionWrapper,
+    CallableObjectProxy,
+    FunctionWrapper,
+)
+from .doc import _BOUND_DOC_PROPERTY, _DOC_PROPERTY, _NO_DOC_OVERRIDE
+
+_MISSING = object()
+
+
+def _cached(attr):
+    """Read-only property that memoizes its derivation in a `_self_*` slot.
+
+    `functools.cached_property` is unusable on ObjectProxy subclasses: wrapt
+    overrides `__dict__` with a property returning the wrapped object's dict,
+    so cached_property's `instance.__dict__[name] = value` would mutate the
+    wrapped function. Storing under a `_self_*` name routes through wrapt's
+    own setattr handling and lands in the proxy's real instance dict. Using
+    a `@property` (data descriptor) also ensures we win over any value
+    copied into the instance dict by `FunctionWrapper.__init__`.
+    """
+    slot = f"_self_cached_{attr.lstrip('_')}"
+
+    def getter(self):
+        value = getattr(self, slot, _MISSING)
+        if value is _MISSING:
+            value = self._derive(attr)
+            self.__self_setattr__(slot, value)
+        return value
+
+    return property(getter)
+
+
+def _derive_annotations(sig):
+    ann = {
+        p.name: p.annotation
+        for p in sig.parameters.values()
+        if p.annotation is not Parameter.empty
+    }
+    if sig.return_annotation is not Signature.empty:
+        ann["return"] = sig.return_annotation
+    return ann
+
+
+def _derive_defaults(sig):
+    defaults = tuple(
+        p.default
+        for p in sig.parameters.values()
+        if p.kind in (Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD)
+        and p.default is not Parameter.empty
+    )
+    return defaults or None
+
+
+def _derive_kwdefaults(sig):
+    kwdefaults = {
+        p.name: p.default
+        for p in sig.parameters.values()
+        if p.kind is Parameter.KEYWORD_ONLY and p.default is not Parameter.empty
+    }
+    return kwdefaults or None
+
+
+def _derive_varnames(sig):
+    pos_only, pos_or_kw, kw_only = [], [], []
+    var_pos = var_kw = None
+    for p in sig.parameters.values():
+        if p.kind is Parameter.POSITIONAL_ONLY:
+            pos_only.append(p.name)
+        elif p.kind is Parameter.POSITIONAL_OR_KEYWORD:
+            pos_or_kw.append(p.name)
+        elif p.kind is Parameter.VAR_POSITIONAL:
+            var_pos = p.name
+        elif p.kind is Parameter.KEYWORD_ONLY:
+            kw_only.append(p.name)
+        elif p.kind is Parameter.VAR_KEYWORD:
+            var_kw = p.name
+    names = pos_only + pos_or_kw + kw_only
+    if var_pos:
+        names.append(var_pos)
+    if var_kw:
+        names.append(var_kw)
+    return tuple(names)
+
+
+class _SignatureCode(BaseObjectProxy):
+    """Code-object proxy deriving argument-related co_* attrs from a Signature.
+
+    Non-argument bits (co_flags for coroutine/generator, co_filename, etc.)
+    fall through to the wrapped function's real __code__.
+    """
+
+    def __init__(self, wrapped, signature):
+        super().__init__(wrapped)
+        self._self_signature = signature
+
+    def _derive(self, attr):
+        sig = self._self_signature
+        if attr == "co_argcount":
+            kinds = (Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD)
+            return sum(p.kind in kinds for p in sig.parameters.values())
+        if attr == "co_posonlyargcount":
+            return sum(
+                p.kind is Parameter.POSITIONAL_ONLY for p in sig.parameters.values()
+            )
+        if attr == "co_kwonlyargcount":
+            return sum(
+                p.kind is Parameter.KEYWORD_ONLY for p in sig.parameters.values()
+            )
+        if attr == "co_varnames":
+            return _derive_varnames(sig)
+        if attr == "co_flags":
+            kinds = {p.kind for p in sig.parameters.values()}
+            flags = self.__wrapped__.co_flags & ~(CO_VARARGS | CO_VARKEYWORDS)
+            if Parameter.VAR_POSITIONAL in kinds:
+                flags |= CO_VARARGS
+            if Parameter.VAR_KEYWORD in kinds:
+                flags |= CO_VARKEYWORDS
+            return flags
+        raise AttributeError(attr)
+
+    co_argcount = _cached("co_argcount")
+    co_posonlyargcount = _cached("co_posonlyargcount")
+    co_kwonlyargcount = _cached("co_kwonlyargcount")
+    co_varnames = _cached("co_varnames")
+    co_flags = _cached("co_flags")
+
+
+class _SignatureMixin:
+    """Shared Signature-derived introspection attrs for wrapper + surrogate."""
+
+    def _derive(self, attr):
+        sig = self._self_signature
+        if attr == "__annotations__":
+            return _derive_annotations(sig)
+        if attr == "__defaults__":
+            return _derive_defaults(sig)
+        if attr == "__kwdefaults__":
+            return _derive_kwdefaults(sig)
+        if attr == "__code__":
+            return _SignatureCode(self.__wrapped__.__code__, sig)
+        raise AttributeError(attr)
+
+    @property
+    def __signature__(self):
+        return self._self_signature
+
+    __annotations__ = _cached("__annotations__")
+    __defaults__ = _cached("__defaults__")
+    __kwdefaults__ = _cached("__kwdefaults__")
+    __code__ = _cached("__code__")
+
+
+class _SignatureFunctionSurrogate(_SignatureMixin, CallableObjectProxy):
+    """Function surrogate exposing Signature-derived introspection attrs.
+
+    Used as __func__ of a bound wrapper so that inspect.signature -- which
+    treats the bound wrapper as a MethodType and consults __func__ -- sees
+    our override and strips self/cls correctly.
+    """
+
+    def __init__(self, wrapped, signature):
+        super().__init__(wrapped)
+        self._self_signature = signature
+
+
+class _BoundSignatureFunctionWrapper(BoundFunctionWrapper):
+    __doc__ = _BOUND_DOC_PROPERTY
+
+    @property
+    def __func__(self):
+        return _SignatureFunctionSurrogate(
+            self.__wrapped__.__func__, self._self_parent._self_signature
+        )
+
+    @property
+    def __signature__(self):
+        return self._self_parent._self_signature
+
+
+class _SignatureFunctionWrapper(_SignatureMixin, FunctionWrapper):
+    __doc__ = _DOC_PROPERTY
+
+    __bound_function_wrapper__ = _BoundSignatureFunctionWrapper
+
+    def __init__(self, wrapped, wrapper, signature, doc=_NO_DOC_OVERRIDE):
+        super().__init__(wrapped, wrapper)
+        self._self_signature = signature
+        self._self_doc = doc
+
+    @property
+    def __func__(self):
+        return _SignatureFunctionSurrogate(self.__wrapped__, self._self_signature)
+
+
+def with_signature(
+    wrapped=None, /, *, prototype=None, signature=None, factory=None, doc=None
+):
+    """Override the signature of a wrapped callable.
+
+    Exactly one of `prototype`, `signature`, or `factory` must be supplied:
+
+    - `prototype`: a callable whose signature will be used.
+    - `signature`: a prebuilt `inspect.Signature` object.
+    - `factory`: a callable `factory(wrapped)` invoked at decoration time
+      that returns either a `Signature` or a prototype callable, or a
+      tuple of `(signature_or_prototype, docstring)` to override the
+      docstring at the same time.
+
+    The docstring may also be overridden by supplying `doc`, in which case
+    a docstring from the factory is ignored. When neither is supplied the
+    wrapper reports the docstring of the wrapped function as normal.
+
+    The resulting wrapper exposes the override via `__signature__`, and
+    derives `__annotations__`, `__defaults__`, `__kwdefaults__`, and the
+    argument-related attributes of `__code__` from the same source. The
+    wrapped function is not mutated. Calling behaviour is unchanged.
+    """
+
+    specified = sum(x is not None for x in (prototype, signature, factory))
+    if specified == 0:
+        raise TypeError(
+            "with_signature requires one of prototype=, signature=, or factory="
+        )
+    if specified > 1:
+        raise TypeError(
+            "with_signature accepts only one of prototype=, signature=, or factory="
+        )
+
+    def _decorator(wrapped):
+        def _wrapper(wrapped, instance, args, kwargs):
+            return wrapped(*args, **kwargs)
+
+        resolved_doc = _NO_DOC_OVERRIDE if doc is None else doc
+
+        if signature is not None:
+            resolved = signature
+        elif prototype is not None:
+            resolved = _inspect_signature(prototype)
+        else:
+            produced = factory(wrapped)
+            if isinstance(produced, tuple):
+                produced, produced_doc = produced
+                if doc is None:
+                    resolved_doc = produced_doc
+            resolved = (
+                produced
+                if isinstance(produced, Signature)
+                else _inspect_signature(produced)
+            )
+
+        return _SignatureFunctionWrapper(wrapped, _wrapper, resolved, resolved_doc)
+
+    if wrapped is None:
+        return _decorator
+    return _decorator(wrapped)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py
new file mode 100644
index 00000000000..d51704b494e
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py
@@ -0,0 +1,540 @@
+"""Synchronization decorators and calling-convention markers/bridges.
+
+Provides ``synchronized`` for thread and async locking, ``mark_as_sync``
+and ``mark_as_async`` for declaring the effective calling convention of a
+wrapped callable (without converting it), and ``async_to_sync`` /
+``sync_to_async`` for bridging between the two.
+"""
+
+import asyncio
+import sys
+import warnings
+from functools import partial
+from inspect import (
+    CO_ASYNC_GENERATOR,
+    CO_COROUTINE,
+    CO_GENERATOR,
+    CO_ITERABLE_COROUTINE,
+    isasyncgenfunction,
+    iscoroutinefunction,
+    isgeneratorfunction,
+)
+from threading import Lock, RLock
+
+from .__wrapt__ import BoundFunctionWrapper, CallableObjectProxy, FunctionWrapper
+from .decorators import decorator
+
+# Calling-convention marker wrappers. These manipulate __code__.co_flags
+# so that inspect.iscoroutinefunction() reports the intended calling
+# convention, which lets stdlib code and the synchronized() decorator
+# auto-select the correct sync or async wrapping behaviour even when
+# stacked decorators change the effective convention (for example an
+# inner decorator that invokes an async def via asyncio.run()).
+
+
+class _SyncCodeProxy(CallableObjectProxy):
+
+    def __init__(self, wrapped, generator=None):
+        super().__init__(wrapped)
+        self._self_generator = generator
+
+    @property
+    def co_flags(self):
+        original = self.__wrapped__.co_flags
+        # Strip async-axis and iterable-coroutine bits; sync means neither
+        # coroutine function nor async generator nor types.coroutine-style.
+        flags = original & ~(CO_COROUTINE | CO_ASYNC_GENERATOR | CO_ITERABLE_COROUTINE)
+        if self._self_generator is True:
+            flags |= CO_GENERATOR
+        elif self._self_generator is False:
+            flags &= ~CO_GENERATOR
+        else:
+            # Auto: if input was an async generator, preserve generator-ness
+            # on the sync side by setting CO_GENERATOR. Otherwise leave
+            # CO_GENERATOR as-is (already copied from the wrapped flags).
+            if original & CO_ASYNC_GENERATOR:
+                flags |= CO_GENERATOR
+        return flags
+
+
+class _SyncFunctionSurrogate(CallableObjectProxy):
+
+    def __init__(self, wrapped, generator=None):
+        super().__init__(wrapped)
+        self._self_generator = generator
+
+    @property
+    def __code__(self):
+        return _SyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
+
+
+class _BoundSyncFunctionWrapper(BoundFunctionWrapper):
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self._self_is_not_coroutine = True
+
+    @property
+    def __func__(self):
+        return _SyncFunctionSurrogate(
+            self.__wrapped__.__func__, self._self_parent._self_generator
+        )
+
+
+class _SyncFunctionWrapper(FunctionWrapper):
+
+    __bound_function_wrapper__ = _BoundSyncFunctionWrapper
+
+    def __init__(self, wrapped, wrapper, generator=None):
+        super().__init__(wrapped, wrapper)
+        self._self_is_not_coroutine = True
+        self._self_generator = generator
+
+    @property
+    def __code__(self):
+        return _SyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
+
+
+class _AsyncCodeProxy(CallableObjectProxy):
+
+    def __init__(self, wrapped, generator=None):
+        super().__init__(wrapped)
+        self._self_generator = generator
+
+    @property
+    def co_flags(self):
+        original = self.__wrapped__.co_flags
+        # Strip all four convention bits; we reassert the right ones below.
+        flags = original & ~(
+            CO_GENERATOR | CO_COROUTINE | CO_ITERABLE_COROUTINE | CO_ASYNC_GENERATOR
+        )
+        if self._self_generator is True:
+            flags |= CO_ASYNC_GENERATOR
+        elif self._self_generator is False:
+            flags |= CO_COROUTINE
+        else:
+            # Auto: if input was a generator (sync or async), produce an
+            # async generator; otherwise produce a coroutine function.
+            if original & (CO_GENERATOR | CO_ASYNC_GENERATOR):
+                flags |= CO_ASYNC_GENERATOR
+            else:
+                flags |= CO_COROUTINE
+        return flags
+
+
+class _AsyncFunctionSurrogate(CallableObjectProxy):
+
+    def __init__(self, wrapped, generator=None):
+        super().__init__(wrapped)
+        self._self_generator = generator
+
+    @property
+    def __code__(self):
+        return _AsyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
+
+
+class _BoundAsyncFunctionWrapper(BoundFunctionWrapper):
+
+    @property
+    def __func__(self):
+        return _AsyncFunctionSurrogate(
+            self.__wrapped__.__func__, self._self_parent._self_generator
+        )
+
+
+class _AsyncFunctionWrapper(FunctionWrapper):
+
+    __bound_function_wrapper__ = _BoundAsyncFunctionWrapper
+
+    def __init__(self, wrapped, wrapper, generator=None):
+        super().__init__(wrapped, wrapper)
+        self._self_generator = generator
+
+    @property
+    def __code__(self):
+        return _AsyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
+
+
+def mark_as_sync(wrapped=None, /, *, generator=None):
+    """Mark a callable as synchronous from the perspective of calling
+    convention detection. The returned wrapper is a pass-through that
+    reports `inspect.iscoroutinefunction()` as False regardless of
+    whether the underlying callable is declared `async def`. Useful
+    when a stacked decorator has already collapsed an async function
+    into a synchronous one (for example by using `asyncio.run()`).
+
+    The `generator` keyword toggles the sync generator bit
+    (`CO_GENERATOR`) on the resulting wrapper. Tri-state:
+
+    - `None` (default): auto. Preserve generator-ness from the input --
+      if the input was an async generator, the wrapper reports as a sync
+      generator; otherwise CO_GENERATOR is copied through unchanged.
+    - `True`: force CO_GENERATOR on. Wrapper reports as a sync generator.
+    - `False`: force CO_GENERATOR off. Wrapper reports as a plain sync
+      function even if the input had CO_GENERATOR set.
+
+    Regardless of `generator`, CO_COROUTINE, CO_ASYNC_GENERATOR, and
+    CO_ITERABLE_COROUTINE are all cleared (sync means none of those).
+    """
+
+    def _decorator(wrapped):
+        def _wrapper(wrapped, instance, args, kwargs):
+            return wrapped(*args, **kwargs)
+
+        return _SyncFunctionWrapper(wrapped, _wrapper, generator=generator)
+
+    if wrapped is None:
+        return _decorator
+    return _decorator(wrapped)
+
+
+def mark_as_async(wrapped=None, /, *, generator=None):
+    """Mark a callable as asynchronous from the perspective of calling
+    convention detection. The returned wrapper reports
+    `inspect.iscoroutinefunction()` as True regardless of whether the
+    underlying callable is declared `async def`. Useful when a stacked
+    decorator returns a coroutine from a plain `def` wrapper.
+
+    The `generator` keyword chooses between coroutine function and
+    async generator reporting. Tri-state:
+
+    - `None` (default): auto. If the input was a sync or async
+      generator, the wrapper reports as an async generator
+      (`CO_ASYNC_GENERATOR`); otherwise it reports as a coroutine
+      function (`CO_COROUTINE`).
+    - `True`: force async generator reporting (`CO_ASYNC_GENERATOR` set,
+      `CO_COROUTINE` cleared). These two flags are mutually exclusive at
+      the CPython code-object level.
+    - `False`: force coroutine function reporting (`CO_COROUTINE` set,
+      `CO_ASYNC_GENERATOR` cleared).
+
+    CO_GENERATOR and CO_ITERABLE_COROUTINE are always cleared (the
+    async path does not use either).
+    """
+
+    def _decorator(wrapped):
+        def _wrapper(wrapped, instance, args, kwargs):
+            return wrapped(*args, **kwargs)
+
+        return _AsyncFunctionWrapper(wrapped, _wrapper, generator=generator)
+
+    if wrapped is None:
+        return _decorator
+    return _decorator(wrapped)
+
+
+def async_to_sync(wrapped):
+    """Adapt an async callable so it can be called synchronously. Each
+    call runs the coroutine to completion via `asyncio.run()`. The
+    returned wrapper reports as synchronous under
+    `inspect.iscoroutinefunction()`. Naming follows the asgiref
+    convention.
+
+    Generator functions of either convention are rejected with a
+    `TypeError`: `asyncio.run()` cannot run an async generator, and a
+    sync generator has nothing to run to completion. A callable not
+    reporting as a coroutine function produces a `UserWarning` rather
+    than an error, since convention detection has false negatives such
+    as a plain function wrapper which returns a coroutine; if the
+    callable really is asynchronous in behaviour, apply
+    `mark_as_async` to it first so it reports as such."""
+
+    if isasyncgenfunction(wrapped):
+        raise TypeError(
+            "async_to_sync cannot be applied to an async generator "
+            "function; asyncio.run() cannot run an async generator."
+        )
+
+    if isgeneratorfunction(wrapped):
+        raise TypeError(
+            "async_to_sync cannot be applied to a generator function; "
+            "there is no coroutine to run to completion. If the callable "
+            "is misreported and actually asynchronous in behaviour, apply "
+            "mark_as_async to it first."
+        )
+
+    if not iscoroutinefunction(wrapped):
+        # Detection has false negatives, such as a plain def wrapper
+        # which returns a coroutine, so this cannot be an error. Such a
+        # callable works here regardless, but marking it first also
+        # corrects what introspection reports elsewhere.
+        warnings.warn(
+            "async_to_sync was applied to a callable not reporting as a "
+            "coroutine function. If it is asynchronous in behaviour, "
+            "apply mark_as_async to it first so it reports as such.",
+            UserWarning,
+            stacklevel=2,
+        )
+
+    def wrapper(wrapped, instance, args, kwargs):
+        return asyncio.run(wrapped(*args, **kwargs))
+
+    return _SyncFunctionWrapper(wrapped, wrapper, generator=False)
+
+
+def sync_to_async(wrapped):
+    """Adapt a sync callable so it can be awaited. Each call dispatches
+    the synchronous work to the default executor via
+    `loop.run_in_executor()`. The returned wrapper reports as
+    asynchronous under `inspect.iscoroutinefunction()`. Naming follows
+    the asgiref convention.
+
+    Callables reporting as coroutine functions or generator functions
+    of either convention are rejected with a `TypeError`. For a
+    generator function the adaptation would be an illusion: only
+    creation of the generator would be dispatched to the executor,
+    which executes no body code, while each iteration would still block
+    the event loop. A callable misreported as asynchronous but
+    synchronous in behaviour can have `mark_as_sync` applied to it
+    first so it reports as such."""
+
+    if iscoroutinefunction(wrapped) or isasyncgenfunction(wrapped):
+        # Mirrors the equivalent check in asgiref. A callable which is
+        # misreported, such as a wrapper which runs an inner async def
+        # to completion, can be corrected with mark_as_sync first.
+        raise TypeError(
+            "sync_to_async can only be applied to a synchronous "
+            "callable. If the callable is misreported and actually "
+            "synchronous in behaviour, apply mark_as_sync to it first."
+        )
+
+    if isgeneratorfunction(wrapped):
+        raise TypeError(
+            "sync_to_async cannot be applied to a generator function; "
+            "creating the generator executes no code, and iterating it "
+            "would still block the event loop."
+        )
+
+    async def wrapper(wrapped, instance, args, kwargs):
+        loop = asyncio.get_running_loop()
+        return await loop.run_in_executor(None, partial(wrapped, *args, **kwargs))
+
+    return _AsyncFunctionWrapper(wrapped, wrapper, generator=False)
+
+
+def _synchronized_is_async_lock(obj):
+    return iscoroutinefunction(getattr(obj, "acquire", None))
+
+
+def _synchronized_is_async_callable(obj):
+    # Walk the __wrapped__ chain, returning True as soon as any layer
+    # declares itself a coroutine function. A sync marker wrapper can
+    # carry an authoritative `_self_is_not_coroutine` attribute that
+    # short-circuits the walk before it descends into a genuinely
+    # async inner layer. Cycle / runaway-chain protection modelled on
+    # inspect.unwrap().
+
+    memo = {id(obj): obj}
+    recursion_limit = sys.getrecursionlimit()
+    target = obj
+
+    while True:
+        if isinstance(target, (classmethod, staticmethod)):
+            inner = getattr(target, "__wrapped__", None)
+            if inner is None:
+                inner = target.__func__
+            target = inner
+            id_target = id(target)
+            if id_target in memo or len(memo) >= recursion_limit:
+                raise ValueError("wrapper loop when unwrapping {!r}".format(obj))
+            memo[id_target] = target
+            continue
+
+        if getattr(target, "_self_is_not_coroutine", False):
+            return False
+
+        if iscoroutinefunction(target):
+            return True
+
+        next_target = getattr(target, "__wrapped__", None)
+        if next_target is None or next_target is target:
+            return False
+        target = next_target
+        id_target = id(target)
+        if id_target in memo or len(memo) >= recursion_limit:
+            raise ValueError("wrapper loop when unwrapping {!r}".format(obj))
+        memo[id_target] = target
+
+
+# Decorator for implementing thread synchronization. It can be used as a
+# decorator, in which case the synchronization context is determined by
+# what type of function is wrapped, or it can also be used as a context
+# manager, where the user needs to supply the correct synchronization
+# context. It is also possible to supply an object which appears to be a
+# synchronization primitive of some sort, by virtue of having release()
+# and acquire() methods. In that case that will be used directly as the
+# synchronization primitive without creating a separate lock against the
+# derived or supplied context.
+
+
+def synchronized(wrapped):
+    """Depending on the nature of the `wrapped` object, will either return a
+    decorator which can be used to wrap a function or method, or a context
+    manager, both of which will act accordingly depending on how used, to
+    synchronize access to calling of the wrapped function, or the block of
+    code within the context manager. If it is an object which is a
+    synchronization primitive, such as a threading Lock, RLock, Semaphore,
+    Condition, or Event, then it is assumed that the object is to be used
+    directly as the synchronization primitive, otherwise a lock is created
+    automatically and attached to the wrapped object and used as the
+    synchronization primitive.
+
+    Async functions are supported: if the wrapped callable is an async
+    function, an `asyncio.Lock` is created for the context and the wrapper
+    awaits the lock. The returned object also exposes `__aenter__` and
+    `__aexit__` so it can be used with `async with` to synchronise a block
+    of code using an independent per-context `asyncio.Lock`. If an object
+    with coroutine `acquire`/`release` methods (such as an `asyncio.Lock`)
+    is supplied directly, the returned decorator and context manager will
+    use it via the async protocol.
+    """
+
+    # Determine if being passed an object which is a synchronization
+    # primitive. We can't check by type for Lock, RLock, Semaphore etc,
+    # as the means of creating them isn't the type. Therefore use the
+    # existence of acquire() and release() methods. This is more
+    # extensible anyway as it allows custom synchronization mechanisms.
+
+    if hasattr(wrapped, "acquire") and hasattr(wrapped, "release"):
+        # We remember what the original lock is and then return a new
+        # decorator which accesses and locks it. When returning the new
+        # decorator we wrap it with an object proxy so we can override
+        # the context manager methods in case it is being used to wrap
+        # synchronized statements with a 'with' statement.
+
+        lock = wrapped
+
+        if _synchronized_is_async_lock(lock):
+
+            @decorator
+            async def _synchronized(wrapped, instance, args, kwargs):
+                async with lock:
+                    return await wrapped(*args, **kwargs)
+
+            class _AsyncSynchronizedLockProxy(CallableObjectProxy):
+
+                async def __aenter__(self):
+                    await lock.acquire()
+                    return lock
+
+                async def __aexit__(self, *args):
+                    lock.release()
+
+            return _AsyncSynchronizedLockProxy(wrapped=_synchronized)
+
+        @decorator
+        def _synchronized(wrapped, instance, args, kwargs):
+            # Execute the wrapped function while the original supplied
+            # lock is held.
+
+            with lock:
+                return wrapped(*args, **kwargs)
+
+        class _SynchronizedLockProxy(CallableObjectProxy):
+
+            def __enter__(self):
+                lock.acquire()
+                return lock
+
+            def __exit__(self, *args):
+                lock.release()
+
+        return _SynchronizedLockProxy(wrapped=_synchronized)
+
+    # Following only apply when the lock is being created automatically
+    # based on the context of what was supplied. In this case we supply
+    # a final decorator, but need to use FunctionWrapper directly as we
+    # want to derive from it to add context manager methods in case it is
+    # being used to wrap synchronized statements with a 'with' statement.
+
+    def _synchronized_lock(context):
+        # Attempt to retrieve the lock for the specific context.
+
+        lock = vars(context).get("_synchronized_lock", None)
+
+        if lock is None:
+            # There is no existing lock defined for the context we
+            # are dealing with so we need to create one. This needs
+            # to be done in a way to guarantee there is only one
+            # created, even if multiple threads try and create it at
+            # the same time. We can't always use the setdefault()
+            # method on the __dict__ for the context. This is the
+            # case where the context is a class, as __dict__ is
+            # actually a dictproxy. What we therefore do is use a
+            # meta lock on this wrapper itself, to control the
+            # creation and assignment of the lock attribute against
+            # the context.
+
+            with synchronized._synchronized_meta_lock:
+                # We need to check again for whether the lock we want
+                # exists in case two threads were trying to create it
+                # at the same time and were competing to create the
+                # meta lock.
+
+                lock = vars(context).get("_synchronized_lock", None)
+
+                if lock is None:
+                    lock = RLock()
+                    setattr(context, "_synchronized_lock", lock)
+
+        return lock
+
+    def _synchronized_async_lock(context):
+        # Per-context asyncio.Lock, created lazily on first use. Created
+        # under the shared meta lock so creation is safe across threads;
+        # the meta lock is never held across an await. asyncio.Lock is
+        # not reentrant.
+
+        lock = vars(context).get("_synchronized_async_lock", None)
+
+        if lock is None:
+            with synchronized._synchronized_meta_lock:
+                lock = vars(context).get("_synchronized_async_lock", None)
+
+                if lock is None:
+                    lock = asyncio.Lock()
+                    setattr(context, "_synchronized_async_lock", lock)
+
+        return lock
+
+    def _synchronized_wrapper(wrapped, instance, args, kwargs):
+        # Execute the wrapped function while the lock for the
+        # desired context is held. If instance is None then the
+        # wrapped function is used as the context.
+
+        with _synchronized_lock(instance if instance is not None else wrapped):
+            return wrapped(*args, **kwargs)
+
+    async def _synchronized_async_wrapper(wrapped, instance, args, kwargs):
+        async with _synchronized_async_lock(
+            instance if instance is not None else wrapped
+        ):
+            return await wrapped(*args, **kwargs)
+
+    class _SynchronizedFunctionWrapper(FunctionWrapper):
+
+        def __enter__(self):
+            self._self_lock = _synchronized_lock(self.__wrapped__)
+            self._self_lock.acquire()
+            return self._self_lock
+
+        def __exit__(self, *args):
+            self._self_lock.release()
+
+        async def __aenter__(self):
+            self._self_async_lock = _synchronized_async_lock(self.__wrapped__)
+            await self._self_async_lock.acquire()
+            return self._self_async_lock
+
+        async def __aexit__(self, *args):
+            self._self_async_lock.release()
+
+    if _synchronized_is_async_callable(wrapped):
+        return _SynchronizedFunctionWrapper(
+            wrapped=wrapped, wrapper=_synchronized_async_wrapper
+        )
+
+    return _SynchronizedFunctionWrapper(wrapped=wrapped, wrapper=_synchronized_wrapper)
+
+
+synchronized._synchronized_meta_lock = Lock()  # type: ignore[attr-defined]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py
new file mode 100644
index 00000000000..a4ae1f5503a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py
@@ -0,0 +1,170 @@
+"""Weak reference proxy for functions and bound methods."""
+
+import functools
+import weakref
+
+from .__wrapt__ import BaseObjectProxy, _FunctionWrapperBase
+
+# A weak function proxy. This will work on instance methods, class
+# methods, static methods and regular functions. Special treatment is
+# needed for the method types because the bound method is effectively a
+# transient object and applying a weak reference to one will immediately
+# result in it being destroyed and the weakref callback called. The weak
+# reference is therefore applied to the instance the method is bound to
+# and the original function. The function is then rebound at the point
+# of a call via the weak function proxy.
+#
+# Where the function is a wrapt function wrapper, such as results from
+# applying a decorator, the same applies but there may be no instance,
+# either because the wrapper was never bound, as for a decorated free
+# function, or because the method was accessed via the class rather
+# than an instance. In that case a weak reference to the class the
+# wrapper was accessed through, the owner, is retained as well so that
+# the function can still be rebound correctly at the point of a call.
+
+
+def _weak_function_proxy_callback(ref, proxy, callback):
+    if proxy._self_expired:
+        return
+
+    proxy._self_expired = True
+
+    # This could raise an exception. We let it propagate back and let
+    # the weakref.proxy() deal with it, at which point it generally
+    # prints out a short error message direct to stderr and keeps going.
+    # Note that the callback can never actually be None here, as the
+    # partial which invokes this function is only created when a
+    # callback was supplied, but check anyway as a safeguard.
+
+    if callback is not None:
+        callback(proxy)
+
+
+class WeakFunctionProxy(BaseObjectProxy):
+    """A weak function proxy."""
+
+    def __init__(self, wrapped, callback=None):
+        """Create a proxy to object which uses a weak reference. This is
+        similar to the `weakref.proxy` but is designed to work with functions
+        and methods. It will automatically rebind the function to the instance
+        when called if the function was originally a bound method. This is
+        necessary because bound methods are transient objects and applying a
+        weak reference to one will immediately result in it being destroyed
+        and the weakref callback called. The weak reference is therefore
+        applied to the instance the method is bound to and the original
+        function. The function is then rebound at the point of a call via the
+        weak function proxy.
+        """
+
+        # We need to determine if the wrapped function is actually a
+        # bound method. In the case of a bound method, we need to keep a
+        # reference to the original unbound function and the instance.
+        # This is necessary because if we hold a reference to the bound
+        # function, it will be the only reference and given it is a
+        # temporary object, it will almost immediately expire and
+        # the weakref callback triggered. So what is done is that we
+        # hold a reference to the instance and unbound function and
+        # when called bind the function to the instance once again and
+        # then call it. Note that we avoid using a nested function for
+        # the callback here so as not to cause any odd reference cycles.
+
+        _callback = None
+        if callback is not None:
+            _callback = functools.partial(
+                _weak_function_proxy_callback, proxy=self, callback=callback
+            )
+
+        self._self_expired = False
+        self._self_owner = None
+
+        if isinstance(wrapped, _FunctionWrapperBase):
+            # A function wrapper may have no instance, either because it
+            # was never bound, as for a decorated free function, or
+            # because the method was accessed via the class rather than
+            # an instance. Only take a weak reference to the instance
+            # where there is one. The owner is the class the wrapper was
+            # accessed through, and is retained so the function can be
+            # rebound with it when called. Without it a classmethod
+            # accessed via the class could not be rebound at all, and an
+            # instance method accessed via the class would not be able
+            # to identify an instance passed as the first argument.
+
+            instance = wrapped._self_instance
+            self._self_instance = (
+                weakref.ref(instance, _callback) if instance is not None else None
+            )
+            owner = wrapped._self_owner
+            if owner is not None:
+                self._self_owner = weakref.ref(owner, _callback)
+
+            if wrapped._self_parent is not None:
+                # Explicit class in super() is used because the proxy
+                # overrides __class__ and MRO-related methods to delegate
+                # to the wrapped object, which can interfere with bare
+                # super().
+                super(WeakFunctionProxy, self).__init__(
+                    weakref.proxy(wrapped._self_parent, _callback)
+                )
+
+            else:
+                super(WeakFunctionProxy, self).__init__(
+                    weakref.proxy(wrapped, _callback)
+                )
+
+            return
+
+        try:
+            self._self_instance = weakref.ref(wrapped.__self__, _callback)
+
+            super(WeakFunctionProxy, self).__init__(
+                weakref.proxy(wrapped.__func__, _callback)
+            )
+
+        except AttributeError:
+            self._self_instance = None
+
+            super(WeakFunctionProxy, self).__init__(weakref.proxy(wrapped, _callback))
+
+    def __call__(*args, **kwargs):
+        def _unpack_self(self, *args):
+            return self, args
+
+        self, args = _unpack_self(*args)
+
+        # We perform a boolean check here on the instance and wrapped
+        # function as that will trigger the reference error prior to
+        # calling if the reference had expired.
+
+        instance = self._self_instance and self._self_instance()
+        function = self.__wrapped__ and self.__wrapped__
+
+        # If the wrapped function was originally a bound method but the
+        # instance it was bound to has been garbage collected, raise a
+        # ReferenceError rather than silently calling it as unbound.
+
+        if self._self_instance is not None and instance is None:
+            raise ReferenceError("weakly-referenced object no longer exists")
+
+        # If the wrapped function was a function wrapper for which the
+        # owner was retained, rebind the function against the instance,
+        # which may be None, and that owner. This is what a classmethod
+        # accessed via the class needs to be rebound at all, and what an
+        # instance method accessed via the class needs to recognise an
+        # instance passed as the first argument. If the owner has been
+        # garbage collected, raise a ReferenceError as for the instance.
+
+        if self._self_owner is not None:
+            owner = self._self_owner()
+            if owner is None:
+                raise ReferenceError("weakly-referenced object no longer exists")
+            return function.__get__(instance, owner)(*args, **kwargs)
+
+        # Otherwise, if the wrapped function was originally a bound
+        # function, for which we retained a reference to the instance and
+        # the unbound function, we need to rebind the function and then
+        # call it. If not just call the wrapped function.
+
+        if instance is None:
+            return self.__wrapped__(*args, **kwargs)
+
+        return function.__get__(instance, type(instance))(*args, **kwargs)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py
new file mode 100644
index 00000000000..83d3bc25022
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py
@@ -0,0 +1,1287 @@
+"""Core object proxy and function wrapper implementations."""
+
+import functools
+import inspect
+import math
+import operator
+import sys
+import types
+
+from .exceptions import WrapperNotInitializedError
+
+
+class _ObjectProxyMethods:
+
+    # We use properties to override the values of __module__ and
+    # __doc__. If we add these in ObjectProxy, the derived class
+    # __dict__ will still be setup to have string variants of these
+    # attributes and the rules of descriptors means that they appear to
+    # take precedence over the properties in the base class. To avoid
+    # that, we copy the properties into the derived class type itself
+    # via a meta class. In that way the properties will always take
+    # precedence.
+    #
+    # Note that because these properties end up in the class __dict__,
+    # type-level access (e.g. ObjectProxy.__module__) would return the
+    # property object rather than a string, since CPython's
+    # type.__module__ getter does a raw dict lookup without invoking the
+    # descriptor protocol. The metaclass has its own __module__ and
+    # __doc__ properties to handle type-level access correctly.
+
+    @property
+    def __module__(self):
+        return self.__wrapped__.__module__
+
+    @__module__.setter
+    def __module__(self, value):
+        self.__wrapped__.__module__ = value
+
+    @__module__.deleter
+    def __module__(self):
+        del self.__wrapped__.__module__
+
+    @property
+    def __doc__(self):
+        return self.__wrapped__.__doc__
+
+    @__doc__.setter
+    def __doc__(self, value):
+        self.__wrapped__.__doc__ = value
+
+    @__doc__.deleter
+    def __doc__(self):
+        del self.__wrapped__.__doc__
+
+    # We similar use a property for __dict__. We need __dict__ to be
+    # explicit to ensure that vars() works as expected.
+
+    @property
+    def __dict__(self):
+        return self.__wrapped__.__dict__
+
+    # Need to also propagate the special __weakref__ attribute for case
+    # where decorating classes which will define this. If do not define
+    # it and use a function like inspect.getmembers() on a decorator
+    # class it will fail. This can't be in the derived classes.
+
+    @property
+    def __weakref__(self):
+        return self.__wrapped__.__weakref__
+
+
+class _ObjectProxyDictBase:
+    """Base class whose sole purpose is to provide a ``getset_descriptor``
+    for ``__dict__`` that is valid for all ``ObjectProxy`` subclasses.
+    The metaclass installs this descriptor as ``__self_dict__`` so that
+    the real instance dictionary of the proxy can always be accessed,
+    even though ``ObjectProxy`` replaces ``__dict__`` with a property
+    that delegates to the wrapped object."""
+
+    pass
+
+
+_REAL_DICT_DESCRIPTOR = type.__dict__["__dict__"].__get__(_ObjectProxyDictBase)[
+    "__dict__"
+]
+
+
+def _get_self_dict(self):
+    return _REAL_DICT_DESCRIPTOR.__get__(self)
+
+
+# Wrapping the descriptor in a read-only property ensures that
+# ``proxy.__self_dict__ = value`` raises AttributeError rather than
+# replacing the real instance dictionary (which would break the proxy).
+
+_SELF_DICT_PROPERTY = property(_get_self_dict)
+
+# The default __doc__ property which delegates to the wrapped object. A
+# derived class may define its own __doc__ descriptor in its class body
+# to take control of what __doc__ reports for its instances, and that is
+# preserved by the metaclass in place of this default.
+
+_DEFAULT_DOC_PROPERTY = vars(_ObjectProxyMethods)["__doc__"]
+
+
+def _is_doc_descriptor(entry):
+    # Every class carries a __doc__ entry in its dict, being the docstring
+    # or None when there is none. Only a descriptor is taken to be a
+    # deliberate override of the instance level __doc__ property.
+
+    if entry is None or isinstance(entry, str):
+        return False
+    return hasattr(type(entry), "__get__")
+
+
+def _inherited_doc_descriptor(bases):
+    # Find a custom __doc__ descriptor inherited from a base class. The
+    # search stops at the first class which holds the default delegating
+    # property, since a derived class of that should delegate as well. The
+    # C extension performs the equivalent walk of the MRO at the time
+    # __doc__ is accessed.
+
+    for base in bases:
+        for klass in base.__mro__:
+            entry = vars(klass).get("__doc__")
+            if entry is _DEFAULT_DOC_PROPERTY:
+                return None
+            if _is_doc_descriptor(entry):
+                return entry
+    return None
+
+
+class _ObjectProxyMetaType(type):
+    # Properties on the metaclass control type-level access to __module__
+    # and __doc__ (e.g. ObjectProxy.__module__). Without these, the
+    # instance-level properties copied from _ObjectProxyMethods into each
+    # class dict would shadow the string values that type.__new__ sets,
+    # causing type.__module__ to return a property object instead of a
+    # string. The metaclass properties read from internal keys where the
+    # real values are saved.
+
+    @property
+    def __module__(cls):
+        return cls.__dict__.get("_cls_real_module", "builtins")
+
+    @__module__.setter
+    def __module__(cls, value):
+        type.__setattr__(cls, "_cls_real_module", value)
+
+    @property
+    def __doc__(cls):
+        return cls.__dict__.get("_cls_real_doc")
+
+    @__doc__.setter
+    def __doc__(cls, value):
+        type.__setattr__(cls, "_cls_real_doc", value)
+
+    def __new__(cls, name, bases, dictionary):
+        # Copy our special properties into the class so that they
+        # always take precedence over attributes of the same name added
+        # during construction of a derived class. This is to save
+        # duplicating the implementation for them in all derived classes.
+        #
+        # Because this overwrites the __module__ and __doc__ strings
+        # that would normally be in the class dict with property objects,
+        # we save the original values first and store them under internal
+        # keys. The metaclass properties above read from these keys to
+        # ensure type-level access (e.g. MyProxy.__module__) returns a
+        # string rather than a property object.
+
+        real_module = dictionary.get("__module__")
+        real_doc = dictionary.get("__doc__")
+
+        # If the subclass defines its own __dict__ property, preserve it
+        # rather than overwriting it with the default delegating property
+        # from _ObjectProxyMethods. When __dict__ is not explicitly
+        # defined in the class body, it will not be present in the
+        # dictionary at this point.
+
+        custom_dict = dictionary.get("__dict__")
+
+        # Similarly, if the subclass defines __doc__ as a descriptor rather
+        # than as a docstring, preserve it so the subclass controls what
+        # __doc__ reports for its instances. Such a descriptor is not the
+        # class docstring, so it is not recorded as one. A descriptor
+        # defined by a base class is inherited, as it would be for any
+        # class not using this metaclass, by copying it into the class
+        # dictionary where it takes precedence over the None or docstring
+        # entry the class body provides.
+
+        if _is_doc_descriptor(real_doc):
+            custom_doc = real_doc
+            real_doc = None
+        else:
+            custom_doc = _inherited_doc_descriptor(bases)
+
+        dictionary.update(vars(_ObjectProxyMethods))
+
+        if custom_dict is not None:
+            dictionary["__dict__"] = custom_dict
+
+        if custom_doc is not None:
+            dictionary["__doc__"] = custom_doc
+
+        dictionary.setdefault("__self_dict__", _SELF_DICT_PROPERTY)
+
+        klass = type.__new__(cls, name, bases, dictionary)
+
+        if real_module is not None:
+            type.__setattr__(klass, "_cls_real_module", real_module)
+        if real_doc is not None:
+            type.__setattr__(klass, "_cls_real_doc", real_doc)
+
+        return klass
+
+
+def _unwrap_operand(other):
+    # When the other operand of a binary operator is itself a proxy, apply
+    # the operator to the two wrapped objects rather than passing the proxy
+    # through to the wrapped object's own operator method. This mirrors
+    # wrapt_unwrap_operand() in the C extension. Without it, a wrapped
+    # type which raises TypeError for an unrecognised operand, rather
+    # than returning NotImplemented, would never give the proxy on the
+    # right hand side the chance to unwrap itself via the reflected
+    # method, and Python would not see the real types of the operands
+    # when deciding whether the reflected method of a subclass on the
+    # right hand side takes priority. The real type is checked, and not
+    # __class__, which the proxy reports as that of the wrapped object.
+
+    if issubclass(type(other), ObjectProxy):
+        return other.__wrapped__
+    return other
+
+
+class ObjectProxy(_ObjectProxyDictBase, metaclass=_ObjectProxyMetaType):
+    """A transparent object proxy that delegates attribute access to a
+    wrapped object."""
+
+    @classmethod
+    def __class_getitem__(cls, item, /):
+        return types.GenericAlias(cls, item)
+
+    def __new__(cls, *args, **kwargs):
+        # Accept and ignore any arguments. A derived class which adds
+        # arguments to __init__() has the same arguments passed to
+        # __new__(), and a derived class which overrides __new__() may
+        # pass through whatever it was given, as it must when deriving
+        # from AutoObjectProxy which needs the wrapped object in __new__().
+        # Without this, once __new__() is overridden anywhere in the class
+        # hierarchy, the call falls through to object.__new__() which
+        # rejects extra arguments. The C extension already ignores the
+        # arguments in its tp_new slot, so this keeps the two consistent.
+
+        return super().__new__(cls)
+
+    def __init__(self, wrapped):
+        """Create an object proxy around the given object."""
+
+        if wrapped is None:
+            try:
+                callback = object.__getattribute__(self, "__wrapped_factory__")
+            except AttributeError:
+                callback = None
+
+            if callback is not None:
+                # If wrapped is none and class has a __wrapped_factory__
+                # method, then we don't set __wrapped__ yet and instead will
+                # defer creation of the wrapped object until it is first
+                # needed.
+
+                pass
+
+            else:
+                object.__setattr__(self, "__wrapped__", wrapped)
+        else:
+            object.__setattr__(self, "__wrapped__", wrapped)
+
+        object.__setattr__(self, "__init_called__", True)
+
+        # Python 3.2+ has the __qualname__ attribute, but it does not
+        # allow it to be overridden using a property and it must instead
+        # be an actual string object instead.
+
+        try:
+            object.__setattr__(self, "__qualname__", wrapped.__qualname__)
+        except AttributeError:
+            pass
+
+        # Python 3.10 onwards also does not allow itself to be overridden
+        # using a property and it must instead be set explicitly. Python
+        # 3.14 onwards uses deferred evaluation of annotations via the
+        # __annotate__ attribute, so we copy that instead to avoid
+        # triggering eager evaluation which can fail if names referenced
+        # in annotations have been shadowed.
+
+        if sys.version_info >= (3, 14):
+            try:
+                object.__setattr__(self, "__annotate__", wrapped.__annotate__)
+            except AttributeError:
+                pass
+        else:
+            try:
+                object.__setattr__(self, "__annotations__", wrapped.__annotations__)
+            except AttributeError:
+                pass
+
+    @property
+    def __object_proxy__(self):
+        return ObjectProxy
+
+    def __self_setattr__(self, name, value):
+        object.__setattr__(self, name, value)
+
+    @property
+    def __name__(self):
+        return self.__wrapped__.__name__
+
+    @__name__.setter
+    def __name__(self, value):
+        self.__wrapped__.__name__ = value
+
+    @property
+    def __class__(self):
+        return self.__wrapped__.__class__
+
+    @__class__.setter
+    def __class__(self, value):
+        self.__wrapped__.__class__ = value
+
+    def __dir__(self):
+        return dir(self.__wrapped__)
+
+    def __str__(self):
+        return str(self.__wrapped__)
+
+    def __bytes__(self):
+        return bytes(self.__wrapped__)
+
+    def __repr__(self):
+        return f"<{type(self).__name__} at 0x{id(self):x} for {type(self.__wrapped__).__name__} at 0x{id(self.__wrapped__):x}>"
+
+    def __format__(self, format_spec):
+        return format(self.__wrapped__, format_spec)
+
+    def __reversed__(self):
+        return reversed(self.__wrapped__)
+
+    def __round__(self, ndigits=None):
+        return round(self.__wrapped__, ndigits)
+
+    def __trunc__(self):
+        return math.trunc(self.__wrapped__)
+
+    def __floor__(self):
+        return math.floor(self.__wrapped__)
+
+    def __ceil__(self):
+        return math.ceil(self.__wrapped__)
+
+    def __mro_entries__(self, bases):
+        if not isinstance(self.__wrapped__, type) and hasattr(
+            self.__wrapped__, "__mro_entries__"
+        ):
+            return self.__wrapped__.__mro_entries__(bases)
+        return (self.__wrapped__,)
+
+    def __lt__(self, other):
+        return self.__wrapped__ < other
+
+    def __le__(self, other):
+        return self.__wrapped__ <= other
+
+    def __eq__(self, other):
+        return self.__wrapped__ == other
+
+    def __ne__(self, other):
+        return self.__wrapped__ != other
+
+    def __gt__(self, other):
+        return self.__wrapped__ > other
+
+    def __ge__(self, other):
+        return self.__wrapped__ >= other
+
+    def __hash__(self):
+        return hash(self.__wrapped__)
+
+    def __bool__(self):
+        return bool(self.__wrapped__)
+
+    def __setattr__(self, name, value):
+        if name.startswith("_self_"):
+            object.__setattr__(self, name, value)
+
+        elif name == "__wrapped__":
+            object.__setattr__(self, name, value)
+
+            try:
+                object.__delattr__(self, "__qualname__")
+            except AttributeError:
+                pass
+            try:
+                object.__setattr__(self, "__qualname__", value.__qualname__)
+            except AttributeError:
+                pass
+            if sys.version_info >= (3, 14):
+                try:
+                    object.__delattr__(self, "__annotate__")
+                except AttributeError:
+                    pass
+                try:
+                    object.__setattr__(self, "__annotate__", value.__annotate__)
+                except AttributeError:
+                    pass
+            else:
+                try:
+                    object.__delattr__(self, "__annotations__")
+                except AttributeError:
+                    pass
+                try:
+                    object.__setattr__(self, "__annotations__", value.__annotations__)
+                except AttributeError:
+                    pass
+
+            __wrapped_setattr_fixups__ = getattr(
+                self, "__wrapped_setattr_fixups__", None
+            )
+
+            if __wrapped_setattr_fixups__ is not None:
+                __wrapped_setattr_fixups__()
+
+        elif name == "__qualname__":
+            setattr(self.__wrapped__, name, value)
+            object.__setattr__(self, name, value)
+
+        elif name == "__annotations__":
+            setattr(self.__wrapped__, name, value)
+            object.__setattr__(self, name, value)
+
+        elif name == "__annotate__":
+            setattr(self.__wrapped__, name, value)
+            object.__setattr__(self, name, value)
+
+        elif hasattr(type(self), name):
+            object.__setattr__(self, name, value)
+
+        else:
+            setattr(self.__wrapped__, name, value)
+
+    def __getattr__(self, name):
+        # If we need to lookup `__wrapped__` then the `__init__()` method
+        # cannot have been called, or this is a lazy object proxy which is
+        # deferring creation of the wrapped object until it is first needed.
+
+        if name == "__wrapped__":
+            # Note that we use existance of `__wrapped_factory__` to gate whether
+            # we can attempt to initialize the wrapped object lazily, but it is
+            # `__wrapped_get__` that we actually call to do the initialization.
+            # This is so that we can handle multithreading correctly by having
+            # `__wrapped_get__` use a lock to protect against multiple threads
+            # trying to initialize the wrapped object at the same time.
+
+            try:
+                object.__getattribute__(self, "__wrapped_factory__")
+            except AttributeError:
+                pass
+            else:
+                return object.__getattribute__(self, "__wrapped_get__")()
+
+            # If __init__ was called but __wrapped__ is not set, the wrapper
+            # is in an inconsistent state. Raise WrapperNotInitializedError
+            # (a ValueError, not AttributeError) so it is not silently
+            # swallowed by hasattr/getattr patterns.
+
+            try:
+                object.__getattribute__(self, "__init_called__")
+            except AttributeError:
+                raise AttributeError(
+                    f"'{type(self).__name__}' object has no attribute " f"'__wrapped__'"
+                )
+
+            raise WrapperNotInitializedError(
+                "wrapper is in an inconsistent state: __wrapped__ is not set"
+            )
+
+        return getattr(self.__wrapped__, name)
+
+    def __delattr__(self, name):
+        if name.startswith("_self_"):
+            object.__delattr__(self, name)
+
+        elif name == "__wrapped__":
+            raise TypeError("can't delete __wrapped__ attribute")
+
+        elif name == "__qualname__":
+            object.__delattr__(self, name)
+            delattr(self.__wrapped__, name)
+
+        elif name == "__annotations__":
+            try:
+                object.__delattr__(self, name)
+            except AttributeError:
+                pass
+            delattr(self.__wrapped__, name)
+
+        elif name == "__annotate__":
+            try:
+                object.__delattr__(self, name)
+            except AttributeError:
+                pass
+            delattr(self.__wrapped__, name)
+
+        elif hasattr(type(self), name):
+            object.__delattr__(self, name)
+
+        else:
+            delattr(self.__wrapped__, name)
+
+    def __add__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ + other
+
+    def __sub__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ - other
+
+    def __mul__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ * other
+
+    def __truediv__(self, other):
+        other = _unwrap_operand(other)
+        return operator.truediv(self.__wrapped__, other)
+
+    def __floordiv__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ // other
+
+    def __mod__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ % other
+
+    def __divmod__(self, other):
+        other = _unwrap_operand(other)
+        return divmod(self.__wrapped__, other)
+
+    def __pow__(self, other, *args):
+        other = _unwrap_operand(other)
+        return pow(self.__wrapped__, other, *args)
+
+    def __lshift__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ << other
+
+    def __rshift__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ >> other
+
+    def __and__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ & other
+
+    def __xor__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ ^ other
+
+    def __or__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ | other
+
+    def __radd__(self, other):
+        other = _unwrap_operand(other)
+        return other + self.__wrapped__
+
+    def __rsub__(self, other):
+        other = _unwrap_operand(other)
+        return other - self.__wrapped__
+
+    def __rmul__(self, other):
+        other = _unwrap_operand(other)
+        return other * self.__wrapped__
+
+    def __rtruediv__(self, other):
+        other = _unwrap_operand(other)
+        return operator.truediv(other, self.__wrapped__)
+
+    def __rfloordiv__(self, other):
+        other = _unwrap_operand(other)
+        return other // self.__wrapped__
+
+    def __rmod__(self, other):
+        other = _unwrap_operand(other)
+        return other % self.__wrapped__
+
+    def __rdivmod__(self, other):
+        other = _unwrap_operand(other)
+        return divmod(other, self.__wrapped__)
+
+    def __rpow__(self, other, *args):
+        other = _unwrap_operand(other)
+        return pow(other, self.__wrapped__, *args)
+
+    def __rlshift__(self, other):
+        other = _unwrap_operand(other)
+        return other << self.__wrapped__
+
+    def __rrshift__(self, other):
+        other = _unwrap_operand(other)
+        return other >> self.__wrapped__
+
+    def __rand__(self, other):
+        other = _unwrap_operand(other)
+        return other & self.__wrapped__
+
+    def __rxor__(self, other):
+        other = _unwrap_operand(other)
+        return other ^ self.__wrapped__
+
+    def __ror__(self, other):
+        other = _unwrap_operand(other)
+        return other | self.__wrapped__
+
+    def __iadd__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__iadd__"):
+            self.__wrapped__ += other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ + other)
+
+    def __isub__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__isub__"):
+            self.__wrapped__ -= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ - other)
+
+    def __imul__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__imul__"):
+            self.__wrapped__ *= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ * other)
+
+    def __itruediv__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__itruediv__"):
+            self.__wrapped__ /= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ / other)
+
+    def __ifloordiv__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__ifloordiv__"):
+            self.__wrapped__ //= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ // other)
+
+    def __imod__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__imod__"):
+            self.__wrapped__ %= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ % other)
+
+    def __ipow__(self, other):  # type: ignore[misc]
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__ipow__"):
+            self.__wrapped__ **= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__**other)
+
+    def __ilshift__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__ilshift__"):
+            self.__wrapped__ <<= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ << other)
+
+    def __irshift__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__irshift__"):
+            self.__wrapped__ >>= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ >> other)
+
+    def __iand__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__iand__"):
+            self.__wrapped__ &= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ & other)
+
+    def __ixor__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__ixor__"):
+            self.__wrapped__ ^= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ ^ other)
+
+    def __ior__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__ior__"):
+            self.__wrapped__ |= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ | other)
+
+    def __neg__(self):
+        return -self.__wrapped__
+
+    def __pos__(self):
+        return +self.__wrapped__
+
+    def __abs__(self):
+        return abs(self.__wrapped__)
+
+    def __invert__(self):
+        return ~self.__wrapped__
+
+    def __int__(self):
+        return int(self.__wrapped__)
+
+    def __float__(self):
+        return float(self.__wrapped__)
+
+    def __complex__(self):
+        return complex(self.__wrapped__)
+
+    def __index__(self):
+        return operator.index(self.__wrapped__)
+
+    def __matmul__(self, other):
+        other = _unwrap_operand(other)
+        return self.__wrapped__ @ other
+
+    def __rmatmul__(self, other):
+        other = _unwrap_operand(other)
+        return other @ self.__wrapped__
+
+    def __imatmul__(self, other):
+        other = _unwrap_operand(other)
+        if hasattr(self.__wrapped__, "__imatmul__"):
+            self.__wrapped__ @= other
+            return self
+        else:
+            return self.__object_proxy__(self.__wrapped__ @ other)
+
+    def __len__(self):
+        return len(self.__wrapped__)
+
+    def __contains__(self, value):
+        return value in self.__wrapped__
+
+    def __getitem__(self, key):
+        return self.__wrapped__[key]
+
+    def __setitem__(self, key, value):
+        self.__wrapped__[key] = value
+
+    def __delitem__(self, key):
+        del self.__wrapped__[key]
+
+    def __enter__(self):
+        return self.__wrapped__.__enter__()
+
+    def __exit__(self, *args, **kwargs):
+        return self.__wrapped__.__exit__(*args, **kwargs)
+
+    def __aenter__(self):
+        return self.__wrapped__.__aenter__()
+
+    def __aexit__(self, *args, **kwargs):
+        return self.__wrapped__.__aexit__(*args, **kwargs)
+
+    def __copy__(self):
+        raise NotImplementedError("object proxy must define __copy__()")
+
+    def __deepcopy__(self, memo):
+        raise NotImplementedError("object proxy must define __deepcopy__()")
+
+    def __reduce__(self):
+        raise NotImplementedError("object proxy must define __reduce__()")
+
+    def __instancecheck__(self, instance):
+        return isinstance(instance, self.__wrapped__)
+
+    def __subclasscheck__(self, subclass):
+        if hasattr(subclass, "__wrapped__"):
+            return issubclass(subclass.__wrapped__, self.__wrapped__)
+        else:
+            return issubclass(subclass, self.__wrapped__)
+
+
+class CallableObjectProxy(ObjectProxy):
+    """An object proxy for callable objects that also forwards calls."""
+
+    def __call__(*args, **kwargs):
+        def _unpack_self(self, *args):
+            return self, args
+
+        self, args = _unpack_self(*args)
+
+        return self.__wrapped__(*args, **kwargs)
+
+
+class _PartialSignatureDescriptor:
+    """Descriptor providing the ``__signature__`` attribute of instances of
+    ``PartialCallableObjectProxy``.
+
+    The signature reported is that of the wrapped callable with the bound
+    positional and keyword arguments removed, matching what ``inspect``
+    reports for ``functools.partial``. It must be defined on the proxy type
+    itself, since attribute lookup on the proxy would otherwise be forwarded
+    to the wrapped callable, and ``inspect.signature()`` stops following
+    ``__wrapped__`` at the first object which has a ``__signature__``
+    attribute.
+
+    A plain property cannot be used because it would also be visible when
+    accessed on the class, and ``inspect.signature()`` applied to the class
+    itself would then fail on finding a property object rather than a
+    ``Signature``. Raising ``AttributeError`` on class access leaves the
+    signature of the class unchanged.
+    """
+
+    def __get__(self, instance, owner=None):
+        if instance is None:
+            raise AttributeError("__signature__")
+
+        partial = functools.partial(
+            instance.__wrapped__, *instance._self_args, **instance._self_kwargs
+        )
+
+        return inspect.signature(partial)
+
+
+class PartialCallableObjectProxy(ObjectProxy):
+    """A callable object proxy that supports partial application of arguments
+    and keywords.
+    """
+
+    __signature__ = _PartialSignatureDescriptor()
+
+    def __init__(*args, **kwargs):
+        """Create a callable object proxy with partial application of the given
+        arguments and keywords. This behaves the same as `functools.partial`, but
+        implemented using the `ObjectProxy` class to provide better support for
+        introspection.
+        """
+
+        def _unpack_self(self, *args):
+            return self, args
+
+        self, args = _unpack_self(*args)
+
+        if len(args) < 1:
+            raise TypeError("partial type takes at least one argument")
+
+        wrapped, args = args[0], args[1:]
+
+        if not callable(wrapped):
+            raise TypeError("the first argument must be callable")
+
+        # Explicit class in super() is used because the proxy overrides
+        # __class__ and MRO-related methods to delegate to the wrapped
+        # object, which can interfere with bare super().
+        super(PartialCallableObjectProxy, self).__init__(wrapped)
+
+        self._self_args = args
+        self._self_kwargs = kwargs
+
+    def __call__(*args, **kwargs):
+        def _unpack_self(self, *args):
+            return self, args
+
+        self, args = _unpack_self(*args)
+
+        _args = self._self_args + args
+
+        _kwargs = dict(self._self_kwargs)
+        _kwargs.update(kwargs)
+
+        return self.__wrapped__(*_args, **_kwargs)
+
+
+class _FunctionWrapperBase(ObjectProxy):
+
+    def __init__(
+        self,
+        wrapped,
+        instance,
+        wrapper,
+        enabled=None,
+        binding="callable",
+        parent=None,
+        owner=None,
+    ):
+
+        # Explicit class in super() is used because the proxy overrides
+        # __class__ and MRO-related methods to delegate to the wrapped
+        # object, which can interfere with bare super().
+        super(_FunctionWrapperBase, self).__init__(wrapped)
+
+        object.__setattr__(self, "_self_instance", instance)
+        object.__setattr__(self, "_self_wrapper", wrapper)
+        object.__setattr__(self, "_self_enabled", enabled)
+        object.__setattr__(self, "_self_binding", binding)
+        object.__setattr__(self, "_self_parent", parent)
+        object.__setattr__(self, "_self_owner", owner)
+
+    def __get__(self, instance, owner=None):
+        # This method handles both unbound and bound derived wrapper classes.
+        # It is kept in the base class as the amount of common code makes it
+        # impractical to split into the derived classes.
+        #
+        # The distinguishing attribute which determines whether we are being
+        # called in an unbound or bound wrapper is the parent attribute. If
+        # binding has never occurred, then the parent will be None.
+        #
+        # First therefore, is if we are called in an unbound wrapper. In this
+        # case we perform the binding.
+        #
+        # We have two special cases to worry about here. These are where we are
+        # decorating a class or builtin function as neither provide a __get__()
+        # method to call. In this case we simply return self.
+        #
+        # Note that we otherwise still do binding even if instance is None and
+        # accessing an unbound instance method from a class. This is because we
+        # need to be able to later detect that specific case as we will need to
+        # extract the instance from the first argument of those passed in.
+
+        if self._self_parent is None:
+            # Technically can probably just check for existence of __get__ on
+            # the wrapped object, but this is more explicit.
+
+            if self._self_binding == "builtin":
+                return self
+
+            if self._self_binding == "class":
+                return self
+
+            binder = getattr(self.__wrapped__, "__get__", None)
+
+            if binder is None:
+                return self
+
+            descriptor = binder(instance, owner)
+
+            return self.__bound_function_wrapper__(
+                descriptor,
+                instance,
+                self._self_wrapper,
+                self._self_enabled,
+                self._self_binding,
+                self,
+                owner,
+            )
+
+        # Now we have the case of binding occurring a second time on what was
+        # already a bound function. In this case we would usually return
+        # ourselves again. This mirrors what Python does.
+        #
+        # The special case this time is where we were originally bound with an
+        # instance of None and we were likely an instance method. In that case
+        # we rebind against the original wrapped function from the parent again.
+
+        if self._self_instance is None and self._self_binding in (
+            "function",
+            "instancemethod",
+            "callable",
+        ):
+            descriptor = self._self_parent.__wrapped__.__get__(instance, owner)
+
+            return self._self_parent.__bound_function_wrapper__(
+                descriptor,
+                instance,
+                self._self_wrapper,
+                self._self_enabled,
+                self._self_binding,
+                self._self_parent,
+                owner,
+            )
+
+        return self
+
+    def __call__(*args, **kwargs):
+        def _unpack_self(self, *args):
+            return self, args
+
+        self, args = _unpack_self(*args)
+
+        # If enabled has been specified, then evaluate it at this point
+        # and if the wrapper is not to be executed, then simply return
+        # the bound function rather than a bound wrapper for the bound
+        # function. When evaluating enabled, if it is callable we call
+        # it, otherwise we evaluate it as a boolean.
+
+        if self._self_enabled is not None:
+            if callable(self._self_enabled):
+                if not self._self_enabled():
+                    return self.__wrapped__(*args, **kwargs)
+            elif not self._self_enabled:
+                return self.__wrapped__(*args, **kwargs)
+
+        # This can occur where initial function wrapper was applied to
+        # a function that was already bound to an instance. In that case
+        # we want to extract the instance from the function and use it.
+
+        if self._self_binding in (
+            "function",
+            "instancemethod",
+            "classmethod",
+            "callable",
+        ):
+            if self._self_instance is None:
+                instance = getattr(self.__wrapped__, "__self__", None)
+                if instance is not None:
+                    return self._self_wrapper(self.__wrapped__, instance, args, kwargs)
+
+        # This is generally invoked when the wrapped function is being
+        # called as a normal function and is not bound to a class as an
+        # instance method. This is also invoked in the case where the
+        # wrapped function was a method, but this wrapper was in turn
+        # wrapped using the staticmethod decorator.
+
+        return self._self_wrapper(self.__wrapped__, self._self_instance, args, kwargs)
+
+    def __set_name__(self, owner, name):
+        # This is a special method use to supply information to
+        # descriptors about what the name of variable in a class
+        # definition is. Not wanting to add this to ObjectProxy as not
+        # sure of broader implications of doing that. Thus restrict to
+        # FunctionWrapper used by decorators.
+
+        if hasattr(self.__wrapped__, "__set_name__"):
+            self.__wrapped__.__set_name__(owner, name)
+
+
+_FUNCTION_WRAPPER_SLOTS = frozenset(
+    (
+        "_self_instance",
+        "_self_wrapper",
+        "_self_enabled",
+        "_self_binding",
+        "_self_parent",
+        "_self_owner",
+    )
+)
+
+
+class BoundFunctionWrapper(_FunctionWrapperBase):
+    """A wrapper for bound methods, classmethods, and staticmethods."""
+
+    def __setattr__(self, name, value):
+        if name.startswith("_self_") and name not in _FUNCTION_WRAPPER_SLOTS:
+            if self._self_parent is not None:
+                object.__setattr__(self._self_parent, name, value)
+                return
+        super().__setattr__(name, value)
+
+    def __getattr__(self, name):
+        # This is only reached for _self_parent when that attribute was
+        # never set, which means __init__() was not called. It has to fail
+        # here, as the lookup of it below would otherwise come straight
+        # back in and recurse without end.
+
+        if name == "_self_parent":
+            raise AttributeError(
+                f"'{type(self).__name__}' object has no attribute '{name}'"
+            )
+
+        if self._self_parent is not None:
+            try:
+                return getattr(self._self_parent, name)
+            except AttributeError:
+                pass
+        return super().__getattr__(name)
+
+    def __call__(*args, **kwargs):
+        def _unpack_self(self, *args):
+            return self, args
+
+        self, args = _unpack_self(*args)
+
+        # If enabled has been specified, then evaluate it at this point and if
+        # the wrapper is not to be executed, then simply return the bound
+        # function rather than a bound wrapper for the bound function. When
+        # evaluating enabled, if it is callable we call it, otherwise we
+        # evaluate it as a boolean.
+
+        if self._self_enabled is not None:
+            if callable(self._self_enabled):
+                if not self._self_enabled():
+                    return self.__wrapped__(*args, **kwargs)
+            elif not self._self_enabled:
+                return self.__wrapped__(*args, **kwargs)
+
+        # We need to do things different depending on whether we are likely
+        # wrapping an instance method vs a static method or class method.
+
+        if self._self_binding == "function":
+            if self._self_instance is None and args:
+                instance, newargs = args[0], args[1:]
+                if isinstance(instance, self._self_owner):
+                    wrapped = PartialCallableObjectProxy(self.__wrapped__, instance)
+                    return self._self_wrapper(wrapped, instance, newargs, kwargs)
+
+            return self._self_wrapper(
+                self.__wrapped__, self._self_instance, args, kwargs
+            )
+
+        elif self._self_binding == "callable":
+            if self._self_instance is None and args:
+                # This situation can occur where someone is calling the
+                # instancemethod via the class type and passing the instance as
+                # the first argument. We need to shift the args before making
+                # the call to the wrapper and effectively bind the instance to
+                # the wrapped function using a partial so the wrapper doesn't
+                # see anything as being different.
+
+                instance, newargs = args[0], args[1:]
+                if isinstance(instance, self._self_owner):
+                    wrapped = PartialCallableObjectProxy(self.__wrapped__, instance)
+                    return self._self_wrapper(wrapped, instance, newargs, kwargs)
+
+            return self._self_wrapper(
+                self.__wrapped__, self._self_instance, args, kwargs
+            )
+
+        else:
+            # As in this case we would be dealing with a classmethod or
+            # staticmethod, then _self_instance will only tell us whether
+            # when calling the classmethod or staticmethod they did it via an
+            # instance of the class it is bound to and not the case where
+            # done by the class type itself. We thus ignore _self_instance
+            # and use the __self__ attribute of the bound function instead.
+            # For a classmethod, this means instance will be the class type
+            # and for a staticmethod it will be None. This is probably the
+            # more useful thing we can pass through even though we loose
+            # knowledge of whether they were called on the instance vs the
+            # class type, as it reflects what they have available in the
+            # decoratored function.
+
+            instance = getattr(self.__wrapped__, "__self__", None)
+
+            return self._self_wrapper(self.__wrapped__, instance, args, kwargs)
+
+
+class FunctionWrapper(_FunctionWrapperBase):
+    """
+    A wrapper for callable objects that can be used to apply decorators to
+    functions, methods, classmethods, and staticmethods, or any other callable.
+    It handles binding and unbinding of methods, and allows for the wrapper to
+    be enabled or disabled.
+    """
+
+    __bound_function_wrapper__ = BoundFunctionWrapper
+
+    def __init__(self, wrapped, wrapper, enabled=None):
+        """
+        Initialize the `FunctionWrapper` with the `wrapped` callable, the
+        `wrapper` function, and an optional `enabled` argument. The `enabled`
+        argument can be a boolean or a callable that returns a boolean. When a
+        callable is provided, it will be called each time the wrapper is
+        invoked to determine if the wrapper function should be executed or
+        whether the wrapped function should be called directly. If `enabled`
+        is not provided, the wrapper is enabled by default.
+        """
+
+        # What it is we are wrapping here could be anything. We need to
+        # try and detect specific cases though. In particular, we need
+        # to detect when we are given something that is a method of a
+        # class. Further, we need to know when it is likely an instance
+        # method, as opposed to a class or static method. This can
+        # become problematic though as there isn't strictly a fool proof
+        # method of knowing.
+        #
+        # The situations we could encounter when wrapping a method are:
+        #
+        # 1. The wrapper is being applied as part of a decorator which
+        # is a part of the class definition. In this case what we are
+        # given is the raw unbound function, classmethod or staticmethod
+        # wrapper objects.
+        #
+        # The problem here is that we will not know we are being applied
+        # in the context of the class being set up. This becomes
+        # important later for the case of an instance method, because in
+        # that case we just see it as a raw function and can't
+        # distinguish it from wrapping a normal function outside of
+        # a class context.
+        #
+        # 2. The wrapper is being applied when performing monkey
+        # patching of the class type afterwards and the method to be
+        # wrapped was retrieved direct from the __dict__ of the class
+        # type. This is effectively the same as (1) above.
+        #
+        # 3. The wrapper is being applied when performing monkey
+        # patching of the class type afterwards and the method to be
+        # wrapped was retrieved from the class type. In this case
+        # binding will have been performed where the instance against
+        # which the method is bound will be None at that point.
+        #
+        # This case is a problem because we can no longer tell if the
+        # method was a static method, plus if using Python3, we cannot
+        # tell if it was an instance method as the concept of an
+        # unnbound method no longer exists.
+        #
+        # 4. The wrapper is being applied when performing monkey
+        # patching of an instance of a class. In this case binding will
+        # have been performed where the instance was not None.
+        #
+        # This case is a problem because we can no longer tell if the
+        # method was a static method.
+        #
+        # Overall, the best we can do is look at the original type of the
+        # object which was wrapped prior to any binding being done and
+        # see if it is an instance of classmethod or staticmethod. In
+        # the case where other decorators are between us and them, if
+        # they do not propagate the __class__  attribute so that the
+        # isinstance() checks works, then likely this will do the wrong
+        # thing where classmethod and staticmethod are used.
+        #
+        # Since it is likely to be very rare that anyone even puts
+        # decorators around classmethod and staticmethod, likelihood of
+        # that being an issue is very small, so we accept it and suggest
+        # that those other decorators be fixed. It is also only an issue
+        # if a decorator wants to actually do things with the arguments.
+        #
+        # As to not being able to identify static methods properly, we
+        # just hope that that isn't something people are going to want
+        # to wrap, or if they do suggest they do it the correct way by
+        # ensuring that it is decorated in the class definition itself,
+        # or patch it in the __dict__ of the class type.
+        #
+        # So to get the best outcome we can, whenever we aren't sure what
+        # it is, we label it as a 'callable'. If it was already bound and
+        # that is rebound later, we assume that it will be an instance
+        # method and try and cope with the possibility that the 'self'
+        # argument it being passed as an explicit argument and shuffle
+        # the arguments around to extract 'self' for use as the instance.
+
+        binding = None
+
+        if isinstance(wrapped, _FunctionWrapperBase):
+            binding = wrapped._self_binding
+
+        if not binding:
+            if inspect.isbuiltin(wrapped):
+                binding = "builtin"
+
+            elif inspect.isfunction(wrapped):
+                binding = "function"
+
+            elif inspect.isclass(wrapped):
+                binding = "class"
+
+            elif isinstance(wrapped, classmethod):
+                binding = "classmethod"
+
+            elif isinstance(wrapped, staticmethod):
+                binding = "staticmethod"
+
+            elif hasattr(wrapped, "__self__"):
+                if inspect.isclass(wrapped.__self__):
+                    binding = "classmethod"
+                elif inspect.ismethod(wrapped):
+                    binding = "instancemethod"
+                else:
+                    binding = "callable"
+
+            else:
+                binding = "callable"
+
+        # Explicit class in super() is used because the proxy overrides
+        # __class__ and MRO-related methods to delegate to the wrapped
+        # object, which can interfere with bare super().
+        super(FunctionWrapper, self).__init__(wrapped, None, wrapper, enabled, binding)
diff --git a/agent/opentelemetry-agent/tests/test_hatch_build.py b/agent/opentelemetry-agent/tests/test_hatch_build.py
new file mode 100644
index 00000000000..6cbd31c2c91
--- /dev/null
+++ b/agent/opentelemetry-agent/tests/test_hatch_build.py
@@ -0,0 +1,63 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+from __future__ import annotations
+
+import importlib.util
+import sysconfig
+from pathlib import Path
+from typing import Any
+
+import pytest
+
+pytest.importorskip("hatchling")
+
+_SPEC = importlib.util.spec_from_file_location("hatch_build", Path(__file__).parents[1] / "hatch_build.py")
+assert _SPEC is not None and _SPEC.loader is not None
+hatch_build = importlib.util.module_from_spec(_SPEC)
+_SPEC.loader.exec_module(hatch_build)
+
+
+def _initialize(root: Path, target_name: str = "wheel") -> dict[str, Any]:
+    hook = hatch_build.CustomBuildHook(str(root), {"abi3-tag": "cp310"}, None, None, str(root), target_name)
+    build_data: dict[str, Any] = {"artifacts": [], "pure_python": True}
+    hook.initialize("1.0", build_data)
+    return build_data
+
+
+def _vendor_file(root: Path, relative: str) -> None:
+    path = root / "src/opentelemetry/agent/_vendor" / relative
+    path.parent.mkdir(parents=True, exist_ok=True)
+    path.write_bytes(b"")
+
+
+def test_pure_without_extensions(tmp_path: Path) -> None:
+    _vendor_file(tmp_path, "google/protobuf/message.py")
+
+    assert _initialize(tmp_path) == {"artifacts": [], "pure_python": True}
+
+
+def test_abi3_extension_makes_platform_wheel(tmp_path: Path) -> None:
+    _vendor_file(tmp_path, "google/_upb/_message.abi3.so")
+
+    build_data = _initialize(tmp_path)
+
+    platform = sysconfig.get_platform().replace("-", "_").replace(".", "_")
+    assert build_data == {
+        "artifacts": ["src/opentelemetry/agent/_vendor/google/_upb/_message.abi3.so"],
+        "pure_python": False,
+        "tag": f"cp310-abi3-{platform}",
+    }
+
+
+def test_non_abi3_extension_is_rejected(tmp_path: Path) -> None:
+    _vendor_file(tmp_path, "google/_upb/_message.cpython-312-darwin.so")
+
+    with pytest.raises(ValueError, match="must use the stable ABI"):
+        _initialize(tmp_path)
+
+
+def test_sdist_target_is_untouched(tmp_path: Path) -> None:
+    _vendor_file(tmp_path, "google/_upb/_message.abi3.so")
+
+    assert _initialize(tmp_path, "sdist") == {"artifacts": [], "pure_python": True}
diff --git a/agent/opentelemetry-agent/tests/test_vendored_otel.py b/agent/opentelemetry-agent/tests/test_vendored_otel.py
new file mode 100644
index 00000000000..95850463841
--- /dev/null
+++ b/agent/opentelemetry-agent/tests/test_vendored_otel.py
@@ -0,0 +1,148 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""Checks of the vendored OpenTelemetry packages and the patches that make them work under the agent's namespace."""
+
+from __future__ import annotations
+
+import json
+import os
+import subprocess
+import sys
+from pathlib import Path
+
+import pytest
+
+from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ConfigurationError
+from opentelemetry.agent._vendor.opentelemetry.configuration.file._loader import load_config_file
+from opentelemetry.agent._vendor.opentelemetry.distro import OpenTelemetryDistro
+from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_TRACES_EXPORTER
+from opentelemetry.agent._vendor.opentelemetry.sdk._configuration import _get_exporter_names, _import_exporters
+from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_PROTOCOL
+from opentelemetry.agent._vendor.opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope
+from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import distributions, entry_points
+
+NAMESPACE = "opentelemetry.agent._vendor"
+
+
+def test_entry_points_are_vendored() -> None:
+    eps = entry_points()
+
+    assert eps
+    assert all(entry_point.module.startswith(f"{NAMESPACE}.") for entry_point in eps)
+    assert {dist.metadata["Name"] for dist in distributions()} >= {"opentelemetry-sdk", "opentelemetry-distro"}
+
+
+def test_instrumentor_entry_point_has_dist_requires() -> None:
+    [entry_point] = entry_points(group="opentelemetry_instrumentor")
+
+    assert entry_point.name == "aiohttp-client"
+    assert entry_point.value == f"{NAMESPACE}.opentelemetry.instrumentation.aiohttp_client:AioHttpClientInstrumentor"
+    assert entry_point.dist is not None
+    # The dependency check of auto-instrumentation reads the "instruments" extra.
+    assert any(
+        "extra ==" in requirement and "aiohttp" in requirement for requirement in entry_point.dist.requires or []
+    )
+
+
+def test_otlp_exporter_defaults_to_http(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv(OTEL_TRACES_EXPORTER, "otlp")
+    monkeypatch.delenv(OTEL_EXPORTER_OTLP_PROTOCOL, raising=False)
+
+    OpenTelemetryDistro().configure()
+    names = _get_exporter_names("traces")
+    trace_exporters, _, _ = _import_exporters(names, [], [])
+
+    assert os.environ[OTEL_EXPORTER_OTLP_PROTOCOL] == "http/protobuf"
+    assert names == ["otlp_proto_http"]
+    assert trace_exporters["otlp_proto_http"].__module__ == (
+        f"{NAMESPACE}.opentelemetry.exporter.otlp.proto.http.trace_exporter"
+    )
+
+
+@pytest.mark.parametrize(
+    ("name", "expected"),
+    [
+        pytest.param(
+            f"{NAMESPACE}.opentelemetry.instrumentation.aiohttp_client",
+            "opentelemetry.instrumentation.aiohttp_client",
+            id="vendored",
+        ),
+        pytest.param("my.app", "my.app", id="application"),
+    ],
+)
+def test_instrumentation_scope_name(name: str, expected: str) -> None:
+    tracer = TracerProvider().get_tracer(name)
+
+    assert InstrumentationScope(name).name == expected
+    assert tracer._instrumentation_scope.name == expected  # pylint: disable=protected-access
+
+
+def test_load_config_file_yaml(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setenv("SERVICE", "checkout")
+    config_file = tmp_path / "otel.yaml"
+    config_file.write_text(
+        'file_format: "1.0"\n'
+        "disabled: off\n"  # a string in YAML 1.2, not a boolean
+        "resource:\n"
+        "  attributes:\n"
+        "    - name: service.name\n"
+        "      value: ${SERVICE}\n"
+    )
+
+    with pytest.raises(ConfigurationError, match=r"Configuration does not match schema: .*disabled.* must be boolean"):
+        load_config_file(config_file)
+
+    config_file.write_text(config_file.read_text().replace("disabled: off", "disabled: false"))
+    config = load_config_file(config_file)
+
+    assert config.disabled is False
+    assert config.resource is not None and config.resource.attributes is not None
+    [attribute] = config.resource.attributes
+    assert (attribute.name, attribute.value) == ("service.name", "checkout")
+
+
+def test_load_config_file_invalid_yaml(tmp_path: Path) -> None:
+    config_file = tmp_path / "otel.yaml"
+    config_file.write_text("file_format: [\n")
+
+    with pytest.raises(ConfigurationError, match="Failed to parse YAML"):
+        load_config_file(config_file)
+
+
+def test_imports_stay_in_namespace() -> None:
+    # In a fresh interpreter: importing the vendored packages must not import the application's copies.
+    modules = [
+        "opentelemetry.sdk._configuration",
+        "opentelemetry.distro",
+        "opentelemetry.instrumentation.auto_instrumentation",
+        "opentelemetry.configuration.file._loader",
+        "opentelemetry.exporter.otlp.proto.http.trace_exporter",
+        "opentelemetry.exporter.otlp.json.http.trace_exporter",
+        "opentelemetry.exporter.otlp.json.file.trace_exporter",
+        "opentelemetry.exporter.prometheus",
+        "opentelemetry.propagators.b3",
+    ]
+    # Modules loaded at startup (e.g. by *-nspkg.pth files of the environment) don't count.
+    code = (
+        "import json, sys\n"
+        "startup = set(sys.modules)\n"
+        f"for module in {modules!r}:\n"
+        f"    __import__({NAMESPACE!r} + '.' + module)\n"
+        "print(json.dumps(sorted(set(sys.modules) - startup)))\n"
+    )
+    loaded = json.loads(subprocess.run([sys.executable, "-c", code], check=True, capture_output=True, text=True).stdout)
+
+    vendored = {"google", "ruamel", "fastjsonschema", "wrapt", "packaging", "requests", "urllib3", "typing_extensions"}
+    leaked = [
+        module
+        for module in loaded
+        if module.split(".", 1)[0] in vendored
+        or (
+            module.startswith("opentelemetry.")
+            and module not in ("opentelemetry.agent", NAMESPACE)
+            and not module.startswith(f"{NAMESPACE}.")
+        )
+    ]
+    assert leaked == []
diff --git a/agent/opentelemetry-agent/vendor-excludes.txt b/agent/opentelemetry-agent/vendor-excludes.txt
new file mode 100644
index 00000000000..3bc5529e751
--- /dev/null
+++ b/agent/opentelemetry-agent/vendor-excludes.txt
@@ -0,0 +1,5 @@
+# Dependencies left out of the vendored tree (passed to uv pip compile --excludes).
+# opentelemetry-configuration: no pure-Python wheels (jsonschema needs rpds-py); replaced by
+# ruamel.yaml and fastjsonschema, see patches/otel-configuration-loader.patch.
+pyyaml
+jsonschema
diff --git a/agent/opentelemetry-agent/vendor.in b/agent/opentelemetry-agent/vendor.in
index ddde19a7e46..feeef174f1b 100644
--- a/agent/opentelemetry-agent/vendor.in
+++ b/agent/opentelemetry-agent/vendor.in
@@ -1,3 +1,25 @@
 requests
 typing-extensions>=4.6.0
 protobuf<8.0
+opentelemetry-api
+opentelemetry-sdk
+opentelemetry-semantic-conventions
+opentelemetry-proto
+opentelemetry-proto-json
+opentelemetry-configuration
+opentelemetry-exporter-http-transport
+opentelemetry-exporter-otlp-common
+opentelemetry-exporter-otlp-json-common
+opentelemetry-exporter-otlp-json-file
+opentelemetry-exporter-otlp-json-http
+opentelemetry-exporter-otlp-proto-common
+opentelemetry-exporter-otlp-proto-http
+opentelemetry-exporter-prometheus
+opentelemetry-propagator-b3
+opentelemetry-instrumentation
+opentelemetry-distro
+opentelemetry-instrumentation-aiohttp-client
+# Replace pyyaml and jsonschema (excluded in vendor-excludes.txt) in opentelemetry-configuration;
+# see patches/otel-configuration-loader.patch.
+ruamel.yaml
+fastjsonschema
diff --git a/agent/opentelemetry-vendor/README.rst b/agent/opentelemetry-vendor/README.rst
index e785696f593..d2534f758ca 100644
--- a/agent/opentelemetry-vendor/README.rst
+++ b/agent/opentelemetry-vendor/README.rst
@@ -33,10 +33,14 @@ namespace and fails on findings that haven't been reviewed:
 * ``module-names``: vendored module names left in protobuf builder calls of generated ``*_pb2`` code
   (``BuildTopDescriptorsAndMessages(DESCRIPTOR, "", ...)``), which set the classes' ``__module__``.
 * ``side-effects``: changes to process-global state: warning filters and environment variables.
+* ``external-imports``: absolute imports of modules that are neither vendored nor in the standard library,
+  which load the application's copy. Expected where vendored code patches the application's libraries
+  (instrumentations), or for optional, guarded integrations.
 
 Fix a finding with a patch, or, once reviewed, add its file (relative to ``destination``) under the
-finding's kind in ``[tool.opentelemetry-vendor.allow]`` with a comment explaining why it's safe. An entry
-that no longer matches anything is an error, so the list stays current.
+finding's kind in ``[tool.opentelemetry-vendor.allow]`` with a comment explaining why it's safe. Entries are
+``fnmatch`` patterns (``*`` also matches ``/``), e.g. ``opentelemetry/instrumentation/*``. An entry that no
+longer matches anything is an error, so the list stays current.
 
 Requirements must be pinned with hashes (``--generate-hashes``); ``pip`` then verifies every downloaded
 wheel.
@@ -46,11 +50,53 @@ code, ``*.dist-info`` directories) is never left behind. The ``*.dist-info`` dir
 their license files and metadata are captured in the copied license files and the SBOM, their ``RECORD`` no
 longer matches the rewritten code, and ``importlib.metadata`` can't find them inside a package anyway.
 
+Entry points
+------------
+
+The ``*.dist-info`` directories are removed, but vendored code can discover plugins through
+``importlib.metadata`` entry points (OpenTelemetry does). With ``metadata-dir`` (relative to
+``destination``), ``sync`` keeps each vendored distribution's ``METADATA`` and ``entry_points.txt`` in
+``/-.dist-info/``, with entry point modules moved under the vendor namespace
+and the ``console_scripts``/``gui_scripts`` groups dropped. An entry point whose module isn't in the vendored
+tree (dropped, or its distribution excluded) is an error. The directory isn't on ``sys.path``: vendored code
+finds it only through an explicit ``importlib.metadata.distributions(path=[...])``, set up by a patch.
+
+License files
+-------------
+
+Every vendored wheel must ship a license file. For a wheel that doesn't, map its distribution to a license
+file of the project under ``[tool.opentelemetry-vendor.license-files]``; the entry becomes an error once the
+wheel ships its own.
+
+Native extensions
+-----------------
+
+``sync`` vendors pure-Python wheels only; that tree is committed and makes the pure (``py3-none-any``) agent
+wheel. For platform wheels, ``opentelemetry-vendor build-native PROJECT_DIR`` builds the native extensions of
+the distributions configured under ``[tool.opentelemetry-vendor.native.]`` into the vendor tree:
+
+1. It downloads the distribution's hash-pinned sdist (from the requirements file) and extracts it.
+2. It applies the entry's ``patches`` (paths inside are relative to the sdist root). They must move the
+   extension, and every module name compiled into it (its own and those it imports by absolute name), under
+   the vendor namespace, and build it with the stable ABI (``abi3``).
+3. It builds a wheel with PEP 517 in a temporary virtual environment holding the hash-pinned
+   ``build-requirements``, and copies the namespaced ``abi3`` extensions into the vendor tree.
+4. It checks the binaries for un-namespaced vendored module names (``native-module-names``; reviewed
+   exceptions go in ``[tool.opentelemetry-vendor.allow]``) and records the native build in the SBOM.
+
+It must run on CPython at ``python-version`` (abi3 extensions are compiled against the oldest supported
+Python) and refuses free-threaded interpreters, which use the pure wheel. Then build the wheel from the
+source tree (not from the sdist, which doesn't contain the compiled extensions); the agent's build hook tags
+it ``cp310-abi3-``. ``opentelemetry-vendor build-native --clean PROJECT_DIR`` removes the extensions
+and restores the committed SBOM. A failed build cleans up after itself.
+
 Upgrading vendored packages
 ---------------------------
 
 1. Edit ``vendor.in``, then re-run the ``uv pip compile ... --generate-hashes`` command recorded at the top
-   of the requirements file to update the pins and hashes.
+   of the requirements file to update the pins and hashes. Dependencies that must not be vendored (e.g.
+   without a pure-Python wheel) are left out of the resolution with ``--excludes ``; ``sync`` downloads
+   exactly the pinned wheels (``pip download --no-deps``).
 2. Run ``opentelemetry-vendor sync PROJECT_DIR``.
 3. If a patch no longer applies, re-create it with the patch workflow above against the new version (or
    remove it if upstream fixed the issue).
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py
index 2f1fc46d908..9fa34695bde 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/checks.py
@@ -17,16 +17,22 @@
   would point at the application's package.
 * ``side-effects``: changes to process-global state shared with the application:
   warning filters and environment variables.
+* ``external-imports``: absolute imports of modules that are neither vendored nor in the
+  standard library, which load the application's copy (or fail). Expected in instrumentation
+  code, which patches the application's libraries.
 
-Findings of every kind except ``imports`` can be allowed per file after review.
+Findings of every kind except ``imports`` can be allowed per file (or ``fnmatch`` pattern) after review.
 Names are resolved through imports, so aliases such as ``import sys as _sys`` are
 recognized.
 """
 
 from __future__ import annotations
 
+import re
+import sys
 from collections.abc import Collection, Mapping
 from dataclasses import dataclass
+from fnmatch import fnmatchcase
 from pathlib import Path
 
 import libcst as cst
@@ -41,9 +47,16 @@
 LOGGER_NAMES = "logger-names"
 MODULE_NAMES = "module-names"
 SIDE_EFFECTS = "side-effects"
-ALLOWABLE_KINDS = (DYNAMIC_IMPORTS, LOGGER_NAMES, MODULE_NAMES, SIDE_EFFECTS)
+NATIVE_MODULE_NAMES = "native-module-names"
+EXTERNAL_IMPORTS = "external-imports"
+ALLOWABLE_KINDS = (DYNAMIC_IMPORTS, LOGGER_NAMES, MODULE_NAMES, SIDE_EFFECTS, EXTERNAL_IMPORTS, NATIVE_MODULE_NAMES)
 """Finding kinds that can be allowed per file in ``[tool.opentelemetry-vendor.allow]``."""
 _KINDS = (IMPORTS, *ALLOWABLE_KINDS)
+SOURCE_KINDS = (IMPORTS, DYNAMIC_IMPORTS, LOGGER_NAMES, MODULE_NAMES, SIDE_EFFECTS, EXTERNAL_IMPORTS)
+"""Kinds found by ``find_issues`` in Python sources (checked by ``sync``)."""
+EXTENSION_SUFFIXES = (".so", ".pyd")
+# Dotted names in a binary: module names in native code are NUL-terminated C string literals.
+_DOTTED_NAME_BYTES = re.compile(rb"[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)+")
 ALLOW_TABLE = "[tool.opentelemetry-vendor.allow]"
 
 _IMPORT_FUNCTIONS = frozenset({"builtins.__import__", "importlib.import_module"})
@@ -59,6 +72,41 @@
 _SYS_MODULES_MUTATORS = frozenset(f"{_SYS_MODULES}.{method}" for method in _MAPPING_MUTATORS)
 _GET_LOGGER = "logging.getLogger"
 _OS_ENVIRON = "os.environ"
+# Standard library modules of Python 3.10+ missing from some versions' sys.stdlib_module_names:
+# added after 3.10 or removed since (PEP 594), so the check doesn't depend on the running Python.
+_VERSIONED_STDLIB_MODULES = frozenset(
+    {
+        "annotationlib",
+        "compression",
+        "tomllib",
+        "aifc",
+        "asynchat",
+        "asyncore",
+        "audioop",
+        "cgi",
+        "cgitb",
+        "chunk",
+        "crypt",
+        "distutils",
+        "imghdr",
+        "imp",
+        "lib2to3",
+        "mailcap",
+        "msilib",
+        "nis",
+        "nntplib",
+        "ossaudiodev",
+        "pipes",
+        "smtpd",
+        "sndhdr",
+        "spwd",
+        "sunau",
+        "telnetlib",
+        "uu",
+        "xdrlib",
+    }
+)
+_STDLIB_MODULES = sys.stdlib_module_names | _VERSIONED_STDLIB_MODULES
 _SIDE_EFFECT_FUNCTIONS = frozenset(
     {
         "warnings.simplefilter",
@@ -86,23 +134,39 @@ def __str__(self) -> str:
 class _TreeChecker(cst.CSTVisitor):
     METADATA_DEPENDENCIES = (PositionProvider, QualifiedNameProvider)
 
-    def __init__(self, module: cst.Module, path: str, names: Collection[str]) -> None:
+    def __init__(self, module: cst.Module, path: str, names: Collection[str], namespace: str) -> None:
         super().__init__()
         self.module = module
         self.path = path
         self.names = names
+        self.namespace = namespace
         self.found: list[Finding] = []
 
     def visit_Import(self, node: cst.Import) -> None:
-        if any(is_vendored(alias_name(alias), self.names) for alias in node.names):
+        modules = [alias_name(alias) for alias in node.names]
+        if any(is_vendored(module, self.names, self.namespace) for module in modules):
             self._add(IMPORTS, node)
+        if any(self._is_external(module) for module in modules):
+            self._add(EXTERNAL_IMPORTS, node)
 
     def visit_ImportFrom(self, node: cst.ImportFrom) -> None:
         if node.relative or node.module is None:
             return
         module = get_full_name_for_node(node.module)
-        if module is not None and is_vendored(module, self.names):
+        if module is not None and is_vendored(module, self.names, self.namespace):
             self._add(IMPORTS, node)
+        if module is not None and self._is_external(module):
+            self._add(EXTERNAL_IMPORTS, node)
+
+    def _is_external(self, module: str) -> bool:
+        top_level = module.split(".", 1)[0]
+        return not (
+            top_level in self.names
+            or top_level in _STDLIB_MODULES
+            or top_level == "__future__"
+            or module == self.namespace
+            or module.startswith(f"{self.namespace}.")
+        )
 
     def visit_Call(self, node: cst.Call) -> None:
         functions = self._qualified_names(node.func)
@@ -159,7 +223,7 @@ def _is_safe_literal(self, node: cst.Call) -> bool:
         module = argument.evaluated_value
         if not isinstance(module, str):
             return False
-        return module.startswith(".") or not is_vendored(module, self.names)
+        return module.startswith(".") or not is_vendored(module, self.names, self.namespace)
 
     def _is_vendored_literal(self, node: cst.Call, position: int) -> bool:
         """Whether the positional argument at ``position`` is a string literal naming a vendored module."""
@@ -169,7 +233,7 @@ def _is_vendored_literal(self, node: cst.Call, position: int) -> bool:
         if not isinstance(argument, cst.SimpleString):
             return False
         value = argument.evaluated_value
-        return isinstance(value, str) and not value.startswith(".") and is_vendored(value, self.names)
+        return isinstance(value, str) and not value.startswith(".") and is_vendored(value, self.names, self.namespace)
 
     def _is_safe_resource_anchor(self, node: cst.Call) -> bool:
         """Whether the anchor is omitted, the calling module, or a non-vendored string literal."""
@@ -186,28 +250,77 @@ def _add(self, kind: str, node: cst.CSTNode) -> None:
         self.found.append(Finding(kind=kind, path=self.path, line=line, code=code))
 
 
-def find_issues(destination: Path, names: Collection[str]) -> list[Finding]:
-    """Find code escaping the vendor namespace in every ``.py`` file under ``destination``."""
+def find_issues(destination: Path, names: Collection[str], namespace: str) -> list[Finding]:
+    """Find code escaping the vendor ``namespace`` in every ``.py`` file under ``destination``."""
     found: list[Finding] = []
     for path in sorted(destination.rglob("*.py")):
         wrapper = MetadataWrapper(parse_file(path))
-        checker = _TreeChecker(wrapper.module, path.relative_to(destination).as_posix(), names)
+        checker = _TreeChecker(wrapper.module, path.relative_to(destination).as_posix(), names, namespace)
         wrapper.visit(checker)
         found.extend(checker.found)
     return found
 
 
+def find_native_issues(
+    destination: Path, names: Collection[str], namespace: str, extensions: Collection[Path]
+) -> list[Finding]:
+    """Find un-namespaced vendored module names compiled into native ``extensions``.
+
+    A string is flagged when it is a vendored *leaf* module path (e.g. ``google.protobuf.message``,
+    ``google._upb._message``), or starts with one followed by ``.`` (e.g. the type name
+    ``google._upb._message.Message``). Names under ``namespace`` are namespaced already. Package paths alone (``google.protobuf``) aren't flagged:
+    they also occur as protobuf package names in embedded descriptors. Findings report the
+    byte offset as their line.
+    """
+    leaves = _leaf_module_paths(destination, names)
+    found: list[Finding] = []
+    for extension in sorted(extensions):
+        relative = extension.relative_to(destination).as_posix()
+        for match in _DOTTED_NAME_BYTES.finditer(extension.read_bytes()):
+            name = match.group().decode()
+            if name.startswith(f"{namespace}."):
+                continue
+            parts = name.split(".")
+            if any(".".join(parts[:end]) in leaves for end in range(2, len(parts) + 1)):
+                found.append(Finding(kind=NATIVE_MODULE_NAMES, path=relative, line=match.start(), code=name))
+    return found
+
+
+def _leaf_module_paths(destination: Path, names: Collection[str]) -> set[str]:
+    """Dotted paths of the (un-namespaced) vendored modules that aren't packages."""
+    leaves = set()
+    for path in destination.rglob("*"):
+        if path.suffix not in (".py", *EXTENSION_SUFFIXES) or path.name.startswith("__init__."):
+            continue
+        parts = path.relative_to(destination).parts
+        if parts[0] not in names and parts[0].split(".", 1)[0] not in names:
+            continue
+        module = path.name.split(".", 1)[0]
+        leaves.add(".".join((*parts[:-1], module)))
+    return leaves
+
+
 def check_vendored_tree(
-    destination: Path, names: Collection[str], allow: Mapping[str, Collection[str]]
+    destination: Path, names: Collection[str], namespace: str, allow: Mapping[str, Collection[str]]
+) -> list[Finding]:
+    """Check the Python sources; see ``check_findings``."""
+    return check_findings(find_issues(destination, names, namespace), allow, SOURCE_KINDS)
+
+
+def check_findings(
+    found: Collection[Finding], allow: Mapping[str, Collection[str]], kinds: Collection[str]
 ) -> list[Finding]:
     """Raise ``VendorError`` for findings outside the ``allow``-ed files of their kind, or for unused entries.
 
-    ``allow`` maps a kind from ``ALLOWABLE_KINDS`` to destination-relative file paths.
-    Returns the allowed findings.
+    ``allow`` maps a kind from ``ALLOWABLE_KINDS`` to destination-relative file paths or ``fnmatch``
+    patterns (``*`` also matches ``/``); only
+    entries of the checked ``kinds`` must match something. Returns the allowed findings.
     """
-    found = find_issues(destination, names)
     allowed = [
-        finding for finding in found if finding.kind in ALLOWABLE_KINDS and finding.path in allow.get(finding.kind, ())
+        finding
+        for finding in found
+        if finding.kind in ALLOWABLE_KINDS
+        and any(fnmatchcase(finding.path, entry) for entry in allow.get(finding.kind, ()))
     ]
     unallowed = [finding for finding in found if finding not in allowed]
     if unallowed:
@@ -224,8 +337,10 @@ def check_vendored_tree(
             sections.append(f"  {kind} ({hint}):\n" + "\n".join(lines))
         raise VendorError("vendored code escapes the vendor namespace:\n" + "\n".join(sections))
     for kind, entries in allow.items():
+        if kind not in kinds:
+            continue
         paths = {finding.path for finding in found if finding.kind == kind}
         for entry in entries:
-            if entry not in paths:
+            if not any(fnmatchcase(path, entry) for path in paths):
                 raise VendorError(f"{ALLOW_TABLE} {kind} entry {entry!r} matched nothing")
     return allowed
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py
index 626cae3baf1..5e7de979509 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/cli.py
@@ -8,6 +8,7 @@
 
 import typer
 
+from opentelemetry.vendor import native as _native
 from opentelemetry.vendor import output
 from opentelemetry.vendor import sync as _sync
 from opentelemetry.vendor.config import load_config
@@ -67,6 +68,27 @@ def clean(project_dir: ProjectDir, quiet: Quiet = False, verbose: Verbose = Fals
         _fail(exc)
 
 
+@app.command("build-native")
+def build_native(
+    project_dir: ProjectDir,
+    clean: Annotated[
+        bool, typer.Option("--clean", help="Remove built extensions and restore the committed SBOM instead.")
+    ] = False,
+    quiet: Quiet = False,
+    verbose: Verbose = False,
+) -> None:
+    """Build PROJECT_DIR's native extensions from their sdists into the vendor tree (for platform wheels)."""
+    _configure_output(quiet, verbose)
+    try:
+        config = load_config(project_dir)
+        if clean:
+            _native.clean_native(config)
+        else:
+            _native.build_native(config)
+    except VendorError as exc:
+        _fail(exc)
+
+
 def _configure_output(quiet: bool, verbose: bool) -> None:
     if quiet and verbose:
         raise typer.BadParameter("--quiet and --verbose cannot be used together")
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py
index fcd2f8f5ef3..d212589fc33 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/config.py
@@ -7,12 +7,13 @@
 
 import sys
 from collections.abc import Collection, Mapping
-from dataclasses import dataclass
+from dataclasses import dataclass, field
 from pathlib import Path, PurePosixPath
 from typing import Any
 
 from opentelemetry.vendor.checks import ALLOW_TABLE, ALLOWABLE_KINDS, DYNAMIC_IMPORTS
 from opentelemetry.vendor.errors import VendorError
+from opentelemetry.vendor.metadata import canonicalize_name
 
 if sys.version_info >= (3, 11):
     import tomllib
@@ -27,6 +28,16 @@ class ConfigError(VendorError):
     """Raised when the vendoring configuration is missing or invalid."""
 
 
+@dataclass(frozen=True)
+class NativeConfig:
+    """How to build a vendored distribution's native extensions from its sdist."""
+
+    patches: Collection[Path]
+    """Patches applied, in order, to the extracted sdist (paths inside are relative to its root)."""
+    build_requirements: Path
+    """Hash-pinned requirements file of the build-time dependencies (e.g. setuptools)."""
+
+
 @dataclass(frozen=True)
 class VendorConfig:
     project_dir: Path
@@ -41,6 +52,12 @@ class VendorConfig:
     patches: Collection[Path]
     """Patch files, applied in order after imports are rewritten."""
     sbom_file: Path | None
+    license_files: Mapping[str, Path] = field(default_factory=dict)
+    """Canonical distribution name -> license file for wheels that don't ship one."""
+    metadata_dir: Path | None = None
+    """Where ``sync`` keeps the vendored distributions' ``METADATA`` and namespaced entry points."""
+    native: Mapping[str, NativeConfig] = field(default_factory=dict)
+    """Canonical distribution name -> native build, from ``[tool.opentelemetry-vendor.native.]``."""
 
 
 def load_config(project_dir: Path) -> VendorConfig:
@@ -64,6 +81,9 @@ def load_config(project_dir: Path) -> VendorConfig:
         raise ConfigError(f"'destination' must be a directory inside {project_dir}, got {destination}")
 
     sbom_file = _optional_str(table, "sbom-file")
+    metadata_dir = _optional_str(table, "metadata-dir")
+    if metadata_dir is not None:
+        _relative_paths({"metadata-dir": [metadata_dir]}, "metadata-dir")
     return VendorConfig(
         project_dir=project_dir,
         destination=destination,
@@ -75,9 +95,34 @@ def load_config(project_dir: Path) -> VendorConfig:
         allow=_allow(table),
         patches=tuple(project_dir / patch for patch in _str_list(table, "patches")),
         sbom_file=project_dir / sbom_file if sbom_file else None,
+        metadata_dir=destination / metadata_dir if metadata_dir else None,
+        license_files=_license_file_overrides(table, project_dir),
+        native=_native(table, project_dir),
     )
 
 
+def _native(table: Mapping[str, Any], project_dir: Path) -> dict[str, NativeConfig]:
+    native = table.get("native", {})
+    if not isinstance(native, dict):
+        raise ConfigError("'native' must be a table ([tool.opentelemetry-vendor.native.])")
+    configs = {}
+    for name, entry in native.items():
+        if not isinstance(entry, dict):
+            raise ConfigError(f"'native.{name}' must be a table")
+        configs[canonicalize_name(name)] = NativeConfig(
+            patches=tuple(project_dir / patch for patch in _str_list(entry, "patches")),
+            build_requirements=project_dir / _require_str(entry, "build-requirements"),
+        )
+    return configs
+
+
+def _license_file_overrides(table: Mapping[str, Any], project_dir: Path) -> dict[str, Path]:
+    overrides = table.get("license-files", {})
+    if not isinstance(overrides, dict) or not all(isinstance(value, str) and value for value in overrides.values()):
+        raise ConfigError("'license-files' must be a table of distribution names to file paths")
+    return {canonicalize_name(name): project_dir / path for name, path in overrides.items()}
+
+
 def _allow(table: Mapping[str, Any]) -> dict[str, tuple[str, ...]]:
     if "allow-dynamic-imports" in table:
         raise ConfigError(f"'allow-dynamic-imports' moved to {ALLOW_TABLE} {DYNAMIC_IMPORTS}")
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py
index ea8a923e075..e31ae4d33af 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/download.py
@@ -65,6 +65,42 @@ def download_wheels(requirements: Path, python_version: str, dest: Path) -> list
     return wheels
 
 
+def download_sdist(requirement: str, dest: Path) -> Path:
+    """Download the source distribution of a single hash-pinned ``requirement`` line."""
+    dest.mkdir(parents=True, exist_ok=True)
+    requirements = dest / "requirement.txt"
+    requirements.write_text(requirement + "\n")
+    result = subprocess.run(
+        [
+            sys.executable,
+            "-m",
+            "pip",
+            "download",
+            "--no-deps",
+            "--no-binary=:all:",
+            "--disable-pip-version-check",
+            "--dest",
+            str(dest),
+            "-r",
+            str(requirements),
+        ],
+        capture_output=True,
+        text=True,
+        check=False,
+    )
+    if result.returncode != 0:
+        raise DownloadError(
+            f"pip download of the sdist failed (exit code {result.returncode}).\n{result.stderr.strip()}"
+        )
+    output.detail(result.stdout.strip())
+    sdists = [path for path in dest.iterdir() if path.name.endswith((".tar.gz", ".zip"))]
+    if len(sdists) != 1:
+        raise DownloadError(
+            f"expected one sdist for {requirement.split(maxsplit=1)[0]!r}, got {sorted(p.name for p in sdists)}"
+        )
+    return sdists[0]
+
+
 def _check_pure_python(wheel: Path) -> None:
     # Wheel filenames end in {python tag}-{abi tag}-{platform tag}.whl
     _, abi_tag, platform_tag = wheel.stem.rsplit("-", 3)[-3:]
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/entry_points.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/entry_points.py
new file mode 100644
index 00000000000..fe0e5f9c1ea
--- /dev/null
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/entry_points.py
@@ -0,0 +1,110 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""Keep a trimmed, namespaced copy of the vendored distributions' metadata.
+
+Vendored code that discovers plugins through ``importlib.metadata`` entry points needs the
+metadata of the vendored distributions, but not that of the application's (which point at
+un-vendored modules). The copy lives in a directory that isn't on ``sys.path``, so only code
+that passes it explicitly (``importlib.metadata.distributions(path=[...])``) sees it.
+"""
+
+from __future__ import annotations
+
+import configparser
+import re
+import shutil
+from collections.abc import Collection
+from pathlib import Path
+
+from opentelemetry.vendor.errors import VendorError
+from opentelemetry.vendor.metadata import VendoredPackage
+from opentelemetry.vendor.rewrite import is_vendored
+
+_METADATA = "METADATA"
+_ENTRY_POINTS = "entry_points.txt"
+_DROPPED_GROUPS = frozenset({"console_scripts", "gui_scripts"})
+"""Script wrappers are generated at install time from the vendoring project's own metadata."""
+# Same grammar as importlib.metadata.EntryPoint: ``module[:attr] [extras]``.
+_ENTRY_POINT_VALUE = re.compile(r"(?P[\w.]+)(?P\s*(?::\s*[\w.]+\s*)?(?:\[.*\]\s*)?)$")
+
+
+def write_metadata(
+    packages: Collection[VendoredPackage],
+    destination: Path,
+    metadata_dir: Path,
+    namespace: str,
+    names: Collection[str],
+) -> int:
+    """Write each package's ``METADATA`` and namespaced ``entry_points.txt`` to ``metadata_dir``.
+
+    Raises ``VendorError`` for an entry point whose module isn't in the vendored tree (dropped,
+    excluded or never vendored). Returns the number of entry points written.
+    """
+    metadata_dir.mkdir(parents=True, exist_ok=True)
+    count = 0
+    for package in sorted(packages, key=lambda package: package.name):
+        target = metadata_dir / package.dist_info.name
+        target.mkdir()
+        shutil.copyfile(package.dist_info / _METADATA, target / _METADATA)
+        source = package.dist_info / _ENTRY_POINTS
+        if not source.is_file():
+            continue
+        groups = rewrite_entry_points(source.read_text(), namespace, names)
+        for group, entries in groups.items():
+            for name, value in entries.items():
+                module = value.split(":", 1)[0].strip()
+                if not _module_exists(destination, module.removeprefix(f"{namespace}.")):
+                    raise VendorError(
+                        f"entry point {group}:{name} of {package.name} references {module}, "
+                        "which isn't in the vendored tree"
+                    )
+                count += 1
+        if groups:
+            (target / _ENTRY_POINTS).write_text(_format(groups))
+    return count
+
+
+def rewrite_entry_points(text: str, namespace: str, names: Collection[str]) -> dict[str, dict[str, str]]:
+    """Parse ``entry_points.txt`` ``text`` and move vendored modules under ``namespace``.
+
+    Script groups are dropped. Values of non-vendored modules are kept, so ``write_metadata``
+    reports them.
+    """
+    parser = _CaseSensitiveParser(delimiters=("=",), interpolation=None, strict=False)
+    parser.read_string(text)
+    groups: dict[str, dict[str, str]] = {}
+    for group in parser.sections():
+        if group in _DROPPED_GROUPS:
+            continue
+        entries = {}
+        for name, value in parser.items(group):
+            match = _ENTRY_POINT_VALUE.match(value.strip())
+            if match is None:
+                raise VendorError(f"invalid entry point {group}:{name} = {value!r}")
+            module = match.group("module")
+            if is_vendored(module, names, namespace):
+                module = f"{namespace}.{module}"
+            entries[name] = f"{module}{match.group('rest')}".strip()
+        if entries:
+            groups[group] = entries
+    return groups
+
+
+class _CaseSensitiveParser(configparser.ConfigParser):
+    def optionxform(self, optionstr: str) -> str:
+        # Entry point names are case-sensitive; ConfigParser lowercases keys by default.
+        return optionstr
+
+
+def _module_exists(destination: Path, module: str) -> bool:
+    path = destination.joinpath(*module.split("."))
+    return path.with_suffix(".py").is_file() or (path / "__init__.py").is_file() or path.is_dir()
+
+
+def _format(groups: dict[str, dict[str, str]]) -> str:
+    sections = [
+        f"[{group}]\n" + "".join(f"{name} = {value}\n" for name, value in entries.items())
+        for group, entries in groups.items()
+    ]
+    return "\n".join(sections)
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py
index 3450a08da58..fde9c895d1e 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/metadata.py
@@ -34,11 +34,14 @@ class VendoredPackage:
     dist_info: Path
 
 
-def read_package(wheel: Path, dist_info: Path) -> VendoredPackage:
-    """Read the metadata needed for vendoring from an unpacked dist-info."""
+def read_package(wheel: Path, dist_info: Path, license_file: Path | None = None) -> VendoredPackage:
+    """Read the metadata needed for vendoring from an unpacked dist-info.
+
+    ``license_file`` stands in for a wheel that ships no license file of its own.
+    """
     distribution = PathDistribution(dist_info)
     metadata = distribution.metadata
-    name = _canonicalize_name(metadata["Name"])
+    name = canonicalize_name(metadata["Name"])
     return VendoredPackage(
         name=name,
         version=metadata["Version"],
@@ -49,7 +52,7 @@ def read_package(wheel: Path, dist_info: Path) -> VendoredPackage:
             metadata.get_all("Classifier") or [],
         ),
         top_level_names=_top_level_names(distribution, dist_info),
-        license_files=_license_files(name, dist_info, metadata.get_all("License-File") or []),
+        license_files=_license_files(name, dist_info, metadata.get_all("License-File") or [], license_file),
         dist_info=dist_info,
     )
 
@@ -69,7 +72,8 @@ def remove_dist_info(packages: Collection[VendoredPackage]) -> None:
         shutil.rmtree(package.dist_info)
 
 
-def _canonicalize_name(name: str) -> str:
+def canonicalize_name(name: str) -> str:
+    """Normalize a distribution name as specified by PEP 503."""
     return re.sub(r"[-_.]+", "-", name).lower()
 
 
@@ -107,7 +111,7 @@ def _top_level_names(distribution: PathDistribution, dist_info: Path) -> tuple[s
     return tuple(sorted(names))
 
 
-def _license_files(name: str, dist_info: Path, declared: Collection[str]) -> dict[str, Path]:
+def _license_files(name: str, dist_info: Path, declared: Collection[str], license_file: Path | None) -> dict[str, Path]:
     sources: dict[str, Path] = {}
     if declared:
         # PEP 639 puts License-File paths under .dist-info/licenses/; older
@@ -126,6 +130,14 @@ def _license_files(name: str, dist_info: Path, declared: Collection[str]) -> dic
                 if not path.is_relative_to(base):
                     base = dist_info
                 sources[path.relative_to(base).as_posix()] = path
+    if sources and license_file is not None:
+        raise VendorError(f"{dist_info.name} contains a license file; remove its license-files entry")
+    if not sources and license_file is not None:
+        if not license_file.is_file():
+            raise VendorError(f"license file {license_file} for {name} does not exist")
+        sources[license_file.name] = license_file
     if not sources:
-        raise VendorError(f"{dist_info.name} does not contain a license file")
+        raise VendorError(
+            f"{dist_info.name} does not contain a license file; add one under [tool.opentelemetry-vendor.license-files]"
+        )
     return {f"{name}.{relative.replace('/', '.')}": path for relative, path in sources.items()}
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/native.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/native.py
new file mode 100644
index 00000000000..be6fbd82741
--- /dev/null
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/native.py
@@ -0,0 +1,265 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""The ``build-native`` command: build vendored packages' native extensions from their sdists.
+
+The pure-Python vendor tree (from ``sync``) is committed. For platform-specific wheels,
+``build-native`` downloads each configured distribution's hash-pinned sdist, applies its native
+patches (which move the extension and the module names compiled into it under the vendor
+namespace), builds it with PEP 517 in a temporary virtual environment and copies the resulting
+stable-ABI (``abi3``) extensions into the vendor tree. ``build-native --clean`` restores the
+committed state.
+"""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import platform
+import shutil
+import subprocess
+import sys
+import sysconfig
+import tarfile
+import tempfile
+import zipfile
+from collections.abc import Collection
+from pathlib import Path, PurePosixPath
+
+from opentelemetry.vendor import output
+from opentelemetry.vendor.checks import EXTENSION_SUFFIXES, NATIVE_MODULE_NAMES, check_findings, find_native_issues
+from opentelemetry.vendor.config import NativeConfig, VendorConfig
+from opentelemetry.vendor.download import download_sdist
+from opentelemetry.vendor.errors import VendorError
+from opentelemetry.vendor.metadata import canonicalize_name
+from opentelemetry.vendor.patches import VendorPatch, apply_patches, read_patches
+from opentelemetry.vendor.sbom import add_native_build
+from opentelemetry.vendor.sync import read_requirements
+
+_STATE_DIR = Path("build", "opentelemetry-vendor")
+_MANIFEST = "native.json"
+_SBOM_BACKUP = "sbom.cdx.json"
+
+
+def build_native(config: VendorConfig) -> list[Path]:
+    """Build the native extensions of every ``config.native`` distribution into the vendor tree.
+
+    Returns the extension files written. On failure, the tree is restored with ``clean_native``.
+    """
+    _check_interpreter(config.python_version)
+    clean_native(config, quiet=True)
+    if not config.native:
+        raise VendorError("no native builds configured ([tool.opentelemetry-vendor.native.])")
+    names = _vendored_names(config)
+    requirements = {_requirement_name(line): line for line in read_requirements(config.requirements)}
+    state = config.project_dir / _STATE_DIR
+    manifest: dict[str, object] = {"extensions": [], "sbom_backup": None}
+    try:
+        state.mkdir(parents=True, exist_ok=True)
+        if config.sbom_file is not None and config.sbom_file.exists():
+            shutil.copy2(config.sbom_file, state / _SBOM_BACKUP)
+            manifest["sbom_backup"] = _SBOM_BACKUP
+        _write_manifest(state, manifest)
+
+        written: list[Path] = []
+        for name, native in sorted(config.native.items()):
+            if name not in requirements:
+                raise VendorError(f"native build {name!r} is not pinned in {config.requirements}")
+            extensions, sdist_sha256, patches = _build(config, name, native, requirements[name])
+            written += extensions
+            manifest["extensions"] = sorted(path.relative_to(config.destination).as_posix() for path in written)
+            _write_manifest(state, manifest)
+            if config.sbom_file is not None:
+                relative = [path.relative_to(config.destination).as_posix() for path in extensions]
+                add_native_build(config.sbom_file, name, sdist_sha256, relative, patches)
+
+        for finding in check_findings(
+            find_native_issues(config.destination, names, config.namespace, written),
+            config.allow,
+            (NATIVE_MODULE_NAMES,),
+        ):
+            output.detail(f"allowed {finding.kind} {finding.path}@{finding.line}: {finding.code}")
+        output.step(f"Checked {output.plural(len(written), 'native extension')}")
+        if config.sbom_file is not None:
+            output.step("Updated SBOM with the native builds")
+        return written
+    except BaseException:
+        clean_native(config, quiet=True)
+        raise
+
+
+def clean_native(config: VendorConfig, *, quiet: bool = False) -> None:
+    """Remove the extensions written by ``build_native`` and restore the committed SBOM."""
+    state = config.project_dir / _STATE_DIR
+    manifest_path = state / _MANIFEST
+    if not manifest_path.exists():
+        if not quiet:
+            output.step("No native build to clean")
+        return
+    manifest = json.loads(manifest_path.read_text())
+    for relative in manifest["extensions"]:
+        extension = config.destination / relative
+        extension.unlink(missing_ok=True)
+        output.detail(f"removed {relative}")
+        # Remove directories that only existed for the extension.
+        for parent in extension.parents:
+            if parent == config.destination or any(parent.iterdir()):
+                break
+            parent.rmdir()
+    if manifest["sbom_backup"] and config.sbom_file is not None:
+        shutil.copy2(state / manifest["sbom_backup"], config.sbom_file)
+        (state / manifest["sbom_backup"]).unlink()
+    manifest_path.unlink()
+    if not any(state.iterdir()):
+        state.rmdir()
+    if not quiet:
+        count = output.plural(len(manifest["extensions"]), "native extension")
+        output.step(f"Cleaned {count} and restored the SBOM")
+
+
+def _build(
+    config: VendorConfig, name: str, native: NativeConfig, requirement: str
+) -> tuple[list[Path], str, list[VendorPatch]]:
+    with tempfile.TemporaryDirectory() as tmp:
+        root = Path(tmp)
+        with output.status(f"Downloading the {name} sdist…"):
+            sdist = download_sdist(requirement, root / "sdist")
+        sdist_sha256 = hashlib.sha256(sdist.read_bytes()).hexdigest()
+        output.step(f"Downloaded sdist {sdist.name}")
+
+        source = _extract(sdist, root / "src")
+        patches = read_patches(native.patches)
+        if patches:
+            apply_patches(source, patches)
+            output.step(f"Applied {output.plural(len(patches), 'native patch', 'native patches')} to {name}")
+
+        with output.status(f"Building {name}…"):
+            wheel = _build_wheel(source, native.build_requirements, root / "build")
+        extensions = _install_extensions(wheel, config)
+        for extension in extensions:
+            output.detail(f"built {extension.relative_to(config.destination).as_posix()}")
+        output.step(f"Built {output.plural(len(extensions), 'extension')} for {name}")
+        return extensions, sdist_sha256, patches
+
+
+def _check_interpreter(python_version: str) -> None:
+    current = f"{sys.version_info.major}.{sys.version_info.minor}"
+    if platform.python_implementation() != "CPython" or current != python_version:
+        raise VendorError(
+            f"build-native must run on CPython {python_version} (running {platform.python_implementation()} "
+            f"{current}): stable-ABI (abi3) extensions are compiled against the oldest supported Python"
+        )
+    if sysconfig.get_config_var("Py_GIL_DISABLED"):
+        raise VendorError(
+            "build-native can't run on a free-threaded interpreter: abi3 extensions don't support it, "
+            "and free-threaded Pythons use the pure-Python agent wheel"
+        )
+
+
+def _vendored_names(config: VendorConfig) -> set[str]:
+    """Top-level vendored module and package names, from the synced tree."""
+    names = set()
+    for child in config.destination.iterdir():
+        if child.name in config.protected_files or child.name.startswith((".", "__")):
+            continue
+        if child.is_dir() and any(child.rglob("*.py")):
+            names.add(child.name)
+        elif child.suffix == ".py":
+            names.add(child.stem)
+    if not names:
+        raise VendorError(f"{config.destination} has no vendored packages; run opentelemetry-vendor sync first")
+    return names
+
+
+def _requirement_name(line: str) -> str:
+    name = line.split(maxsplit=1)[0]
+    for separator in "=<>!~;[@ ":
+        name = name.split(separator, 1)[0]
+    return canonicalize_name(name)
+
+
+def _extract(sdist: Path, dest: Path) -> Path:
+    """Safely extract ``sdist`` into ``dest`` and return its single top-level directory."""
+    dest.mkdir(parents=True)
+    if sdist.name.endswith(".zip"):
+        with zipfile.ZipFile(sdist) as archive:
+            members = archive.namelist()
+            _check_members(sdist, members)
+            archive.extractall(dest)
+    else:
+        with tarfile.open(sdist) as archive:
+            members = archive.getmembers()
+            _check_members(sdist, [member.name for member in members])
+            for member in members:
+                if not (member.isfile() or member.isdir()):
+                    raise VendorError(f"{sdist.name} contains a link or special file: {member.name}")
+            if hasattr(tarfile, "data_filter"):
+                archive.extractall(dest, filter="data")
+            else:
+                archive.extractall(dest)  # members checked above
+    tops = list(dest.iterdir())
+    if len(tops) != 1 or not tops[0].is_dir():
+        raise VendorError(f"{sdist.name} must contain a single top-level directory")
+    return tops[0]
+
+
+def _check_members(sdist: Path, names: Collection[str]) -> None:
+    for name in names:
+        path = PurePosixPath(name)
+        if path.is_absolute() or ".." in path.parts:
+            raise VendorError(f"{sdist.name} contains an unsafe path: {name}")
+
+
+def _build_wheel(source: Path, build_requirements: Path, work: Path) -> Path:
+    """Build ``source`` into a wheel with PEP 517, in a venv with the hash-pinned build requirements."""
+    venv = work / "venv"
+    _run([sys.executable, "-m", "venv", str(venv)], "creating the build environment")
+    python = venv / ("Scripts/python.exe" if sys.platform == "win32" else "bin/python")
+    pip = [str(python), "-m", "pip", "--disable-pip-version-check"]
+    _run(
+        [*pip, "install", "--no-deps", "--require-hashes", "-r", str(build_requirements)],
+        "installing the build requirements",
+    )
+    wheels = work / "wheels"
+    _run(
+        [*pip, "wheel", "--no-deps", "--no-build-isolation", "--wheel-dir", str(wheels), str(source)],
+        f"building {source.name}",
+    )
+    built = sorted(wheels.glob("*.whl"))
+    if len(built) != 1:
+        raise VendorError(f"building {source.name} produced {len(built)} wheels")
+    return built[0]
+
+
+def _install_extensions(wheel: Path, config: VendorConfig) -> list[Path]:
+    """Copy the namespaced extensions from ``wheel`` into the vendor tree."""
+    prefix = config.namespace.replace(".", "/") + "/"
+    written = []
+    with zipfile.ZipFile(wheel) as archive:
+        for member in sorted(archive.namelist()):
+            if not member.startswith(prefix) or not member.endswith(EXTENSION_SUFFIXES):
+                continue
+            relative = member[len(prefix) :]
+            if not (".abi3." in PurePosixPath(relative).name or relative.endswith(".pyd")):
+                raise VendorError(f"{wheel.name}: {member} isn't a stable-ABI (abi3) extension")
+            target = config.destination / relative
+            # e.g. google/_upb only holds the extension: an implicit namespace package.
+            target.parent.mkdir(parents=True, exist_ok=True)
+            target.write_bytes(archive.read(member))
+            target.chmod(0o755)
+            written.append(target)
+    if not written:
+        raise VendorError(f"{wheel.name} contains no extension under {prefix} (check the native patches)")
+    return written
+
+
+def _run(command: list[str], action: str) -> None:
+    result = subprocess.run(command, capture_output=True, text=True, check=False)
+    output.detail(result.stdout.strip())
+    if result.returncode != 0:
+        tail = "\n".join((result.stdout + result.stderr).strip().splitlines()[-30:])
+        raise VendorError(f"{action} failed (exit code {result.returncode}):\n{tail}")
+
+
+def _write_manifest(state: Path, manifest: dict[str, object]) -> None:
+    (state / _MANIFEST).write_text(json.dumps(manifest, indent=2) + "\n")
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py
index 9afccd18c1b..65166d09cf9 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/rewrite.py
@@ -42,8 +42,8 @@ class _ImportTransformer(cst.CSTTransformer):
     ``from X import Y`` becomes ``from namespace.X import Y``. Plain imports keep
     binding the same local name: ``import X`` becomes ``from namespace import X``,
     ``import X.Y as Z`` becomes ``from namespace.X import Y as Z`` and ``import X.Y``
-    becomes ``from namespace import X`` plus ``import namespace.X.Y`` to load the
-    submodule. A line containing an expanded import is split into one statement per line.
+    becomes ``import namespace.X.Y`` (to load the submodule) plus ``from namespace import X``.
+    A line containing an expanded import is split into one statement per line.
 
     Logger names are namespaced too, so vendored code doesn't log to (or configure) the
     application's loggers: a vendored-name string literal passed to ``logging.getLogger``
@@ -91,7 +91,11 @@ def leave_Param(self, original_node: cst.Param, updated_node: cst.Param) -> cst.
 
     def _namespaced_module_name(self, node: cst.SimpleString) -> cst.SimpleString | None:
         value = node.evaluated_value
-        if not isinstance(value, str) or not _DOTTED_NAME.fullmatch(value) or not is_vendored(value, self.names):
+        if (
+            not isinstance(value, str)
+            or not _DOTTED_NAME.fullmatch(value)
+            or not is_vendored(value, self.names, self.namespace)
+        ):
             return None
         return node.with_changes(value=f"{node.prefix}{node.quote}{self.namespace}.{value}{node.quote}")
 
@@ -99,7 +103,7 @@ def leave_ImportFrom(self, original_node: cst.ImportFrom, updated_node: cst.Impo
         if updated_node.relative or updated_node.module is None:
             return updated_node
         module = get_full_name_for_node(updated_node.module)
-        if module is None or not is_vendored(module, self.names):
+        if module is None or not is_vendored(module, self.names, self.namespace):
             return updated_node
         self.count += 1
         return updated_node.with_changes(module=_dotted_name(f"{self.namespace}.{module}"))
@@ -107,12 +111,12 @@ def leave_ImportFrom(self, original_node: cst.ImportFrom, updated_node: cst.Impo
     def leave_Import(
         self, original_node: cst.Import, updated_node: cst.Import
     ) -> cst.BaseSmallStatement | cst.FlattenSentinel[cst.BaseSmallStatement]:
-        if not any(is_vendored(alias_name(alias), self.names) for alias in updated_node.names):
+        if not any(is_vendored(alias_name(alias), self.names, self.namespace) for alias in updated_node.names):
             return updated_node
         statements: list[cst.BaseSmallStatement] = []
         for alias in updated_node.names:
             name = alias_name(alias)
-            if is_vendored(name, self.names):
+            if is_vendored(name, self.names, self.namespace):
                 statements.extend(self._rewrite_alias(name, alias.asname))
                 self.count += 1
             else:
@@ -146,10 +150,18 @@ def _rewrite_alias(self, name: str, asname: cst.AsName | None) -> list[cst.BaseS
             module = f"{self.namespace}.{package}" if package else self.namespace
             return [_import_from(module, attribute, asname)]
         top_level = name.split(".", 1)[0]
-        statements: list[cst.BaseSmallStatement] = [_import_from(self.namespace, top_level, None)]
-        if package:
-            # Binding X alone does not load the X.Y submodule.
-            statements.append(cst.Import(names=[cst.ImportAlias(name=_dotted_name(f"{self.namespace}.{name}"))]))
+        if not package:
+            return [_import_from(self.namespace, top_level, None)]
+        # Binding X alone does not load the X.Y submodule, so import namespace.X.Y first. That statement
+        # also binds the namespace's top-level name (``opentelemetry`` for ``opentelemetry.agent._vendor``),
+        # so bind X afterwards, and re-bind the top-level name if it is itself vendored.
+        statements: list[cst.BaseSmallStatement] = [
+            cst.Import(names=[cst.ImportAlias(name=_dotted_name(f"{self.namespace}.{name}"))]),
+            _import_from(self.namespace, top_level, None),
+        ]
+        namespace_top_level = self.namespace.split(".", 1)[0]
+        if namespace_top_level in self.names and namespace_top_level != top_level:
+            statements.append(_import_from(self.namespace, namespace_top_level, None))
         return statements
 
 
@@ -187,8 +199,14 @@ def parse_file(path: Path) -> cst.Module:
         raise VendorError(f"cannot parse {path}: {exc}") from exc
 
 
-def is_vendored(name: str, names: Collection[str]) -> bool:
-    """Whether dotted module ``name`` belongs to one of the vendored top-level ``names``."""
+def is_vendored(name: str, names: Collection[str], namespace: str) -> bool:
+    """Whether dotted module ``name`` belongs to one of the vendored top-level ``names``.
+
+    Names already under ``namespace`` aren't: the namespace may start with a vendored
+    top-level name (``opentelemetry.agent._vendor`` vendoring ``opentelemetry``).
+    """
+    if name == namespace or name.startswith(f"{namespace}."):
+        return False
     return name.split(".", 1)[0] in names
 
 
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py
index 2674773d2e1..fe2864528b2 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sbom.py
@@ -10,6 +10,7 @@
 import uuid
 from collections.abc import Collection, Mapping
 from pathlib import Path
+from typing import Any
 
 from cyclonedx.contrib.license.factories import LicenseFactory
 from cyclonedx.model import AttachedText, HashAlgorithm, HashType
@@ -57,13 +58,7 @@ def write_sbom(
     document = json.loads(JsonV1Dot6(bom).output_as_string())
     # The timestamp is optional; dropping it keeps re-syncs diff-free.
     document["metadata"].pop("timestamp", None)
-    output = json.dumps(document, indent=2) + "\n"
-
-    error = JsonStrictValidator(SchemaVersion.V1_6).validate_str(output)
-    if error is not None:
-        raise VendorError(f"generated SBOM is invalid: {error}")
-    path.parent.mkdir(parents=True, exist_ok=True)
-    path.write_text(output)
+    _write(document, path)
 
 
 def _component(
@@ -87,3 +82,56 @@ def _component(
         if patches
         else None,
     )
+
+
+NATIVE_SDIST_PROPERTY = "opentelemetry-vendor:native-sdist-sha256"
+NATIVE_EXTENSION_PROPERTY = "opentelemetry-vendor:native-extension"
+
+
+def add_native_build(
+    path: Path,
+    package: str,
+    sdist_sha256: str,
+    extensions: Collection[str],
+    patches: Collection[VendorPatch],
+) -> None:
+    """Record in the SBOM at ``path`` that ``package``'s native ``extensions`` were built from its sdist.
+
+    The native ``patches`` are added to the component's pedigree, and the sdist hash and
+    extension paths (relative to the vendor destination) as properties. The serial number
+    changes accordingly.
+    """
+    document = json.loads(path.read_text())
+    components = [component for component in document.get("components", []) if component.get("name") == package]
+    if len(components) != 1:
+        raise VendorError(f"SBOM {path} has no component {package!r}")
+    component = components[0]
+    pedigree = component.setdefault("pedigree", {})
+    pedigree.setdefault("patches", []).extend(
+        {"type": "unofficial", "diff": {"text": {"content": patch.text, "contentType": "text/plain"}}}
+        for patch in patches
+    )
+    component.setdefault("properties", []).extend(
+        [
+            {"name": NATIVE_SDIST_PROPERTY, "value": sdist_sha256},
+            *({"name": NATIVE_EXTENSION_PROPERTY, "value": extension} for extension in sorted(extensions)),
+        ]
+    )
+    identity = "\n".join(
+        [
+            document["serialNumber"],
+            sdist_sha256,
+            *(hashlib.sha256(patch.text.encode()).hexdigest() for patch in patches),
+        ]
+    )
+    document["serialNumber"] = uuid.uuid5(uuid.NAMESPACE_URL, identity).urn
+    _write(document, path)
+
+
+def _write(document: dict[str, Any], path: Path) -> None:
+    output = json.dumps(document, indent=2) + "\n"
+    error = JsonStrictValidator(SchemaVersion.V1_6).validate_str(output)
+    if error is not None:
+        raise VendorError(f"generated SBOM is invalid: {error}")
+    path.parent.mkdir(parents=True, exist_ok=True)
+    path.write_text(output)
diff --git a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py
index 2a8fc91706a..16ce639c482 100644
--- a/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py
+++ b/agent/opentelemetry-vendor/src/opentelemetry/vendor/sync.py
@@ -16,9 +16,11 @@
 from opentelemetry.vendor.checks import check_vendored_tree
 from opentelemetry.vendor.config import VendorConfig
 from opentelemetry.vendor.download import download_wheels, unpack_wheels
+from opentelemetry.vendor.entry_points import write_metadata
 from opentelemetry.vendor.errors import VendorError
 from opentelemetry.vendor.metadata import (
     VendoredPackage,
+    canonicalize_name,
     copy_license_files,
     read_package,
     remove_dist_info,
@@ -99,7 +101,13 @@ def _populate(config: VendorConfig, requirements: Collection[str]) -> list[Vendo
         output.step(f"Downloaded {output.plural(len(wheels), 'wheel')}")
 
         dist_infos = unpack_wheels(wheels, destination)
-        packages = [read_package(wheel, dist_info) for wheel, dist_info in dist_infos.items()]
+        packages = [
+            read_package(wheel, dist_info, config.license_files.get(_wheel_name(wheel)))
+            for wheel, dist_info in dist_infos.items()
+        ]
+        unused = sorted(set(config.license_files) - {package.name for package in packages})
+        if unused:
+            raise VendorError(f"license-files entries {unused} match no vendored distribution")
         output.step(f"Unpacked {output.plural(len(packages), 'wheel')}")
 
     if config.drop:
@@ -116,9 +124,15 @@ def _populate(config: VendorConfig, requirements: Collection[str]) -> list[Vendo
             output.detail(f"applied {_display(patch.path, config)}")
         output.step(f"Applied {output.plural(len(patches), 'patch', 'patches')}")
 
-    for finding in check_vendored_tree(destination, names, config.allow):
+    for finding in check_vendored_tree(destination, names, config.namespace, config.allow):
         output.detail(f"allowed {finding.kind} {finding}")
 
+    if config.metadata_dir is not None:
+        entry_points = write_metadata(packages, destination, config.metadata_dir, config.namespace, names)
+        output.step(
+            f"Wrote metadata to {_display(config.metadata_dir, config)} ({output.plural(entry_points, 'entry point')})"
+        )
+
     copy_license_files(packages, destination)
     license_count = sum(len(package.license_files) for package in packages)
     output.step(f"Copied {output.plural(license_count, 'license file')}")
@@ -132,6 +146,11 @@ def _populate(config: VendorConfig, requirements: Collection[str]) -> list[Vendo
     return packages
 
 
+def _wheel_name(wheel: Path) -> str:
+    """Canonical distribution name from a wheel file name (``{name}-{version}-...whl``)."""
+    return canonicalize_name(wheel.name.split("-", 1)[0])
+
+
 _REQUIREMENT_NAME = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]*")
 
 
@@ -168,7 +187,10 @@ def check(config: VendorConfig) -> None:
                 if sbom_outside
                 else expected / config.sbom_file.relative_to(config.destination)
             )
-        sync(dataclasses.replace(config, destination=expected, sbom_file=sbom_file))
+        metadata_dir = (
+            expected / config.metadata_dir.relative_to(config.destination) if config.metadata_dir is not None else None
+        )
+        sync(dataclasses.replace(config, destination=expected, sbom_file=sbom_file, metadata_dir=metadata_dir))
 
         differences = _diff_trees(config.destination, expected, config.protected_files)
         if sbom_outside and config.sbom_file is not None and sbom_file is not None:
diff --git a/agent/opentelemetry-vendor/tests/helpers.py b/agent/opentelemetry-vendor/tests/helpers.py
index 4bf6e1b02b9..2feca75645e 100644
--- a/agent/opentelemetry-vendor/tests/helpers.py
+++ b/agent/opentelemetry-vendor/tests/helpers.py
@@ -27,15 +27,19 @@ def make_wheel(
     metadata: str = "",
     licenses: Mapping[str, str] = DEFAULT_LICENSES,
     tag: str = "py3-none-any",
+    entry_points: str | None = None,
 ) -> Path:
     """Create a minimal but valid wheel with METADATA, RECORD and licenses.
 
     ``metadata`` is appended to the METADATA headers; ``licenses`` maps paths
-    relative to the dist-info directory to their contents.
+    relative to the dist-info directory to their contents; ``entry_points`` is the content of
+    ``entry_points.txt``.
     """
     dist_info = f"{name.replace('-', '_')}-{version}.dist-info"
     files = {member: "" for member in members}
     files[f"{dist_info}/METADATA"] = f"Metadata-Version: 2.4\nName: {name}\nVersion: {version}\n{metadata}"
+    if entry_points is not None:
+        files[f"{dist_info}/entry_points.txt"] = entry_points
     for relative, content in licenses.items():
         files[f"{dist_info}/{relative}"] = content
     record = f"{dist_info}/RECORD"
diff --git a/agent/opentelemetry-vendor/tests/test_checks.py b/agent/opentelemetry-vendor/tests/test_checks.py
index a8172aea55c..f0fb145417b 100644
--- a/agent/opentelemetry-vendor/tests/test_checks.py
+++ b/agent/opentelemetry-vendor/tests/test_checks.py
@@ -9,16 +9,20 @@
 
 from opentelemetry.vendor.checks import (
     DYNAMIC_IMPORTS,
+    EXTERNAL_IMPORTS,
     IMPORTS,
     LOGGER_NAMES,
     MODULE_NAMES,
+    NATIVE_MODULE_NAMES,
     SIDE_EFFECTS,
     Finding,
     check_vendored_tree,
     find_issues,
+    find_native_issues,
 )
 from opentelemetry.vendor.errors import VendorError
 
+NAMESPACE = "opentelemetry.agent._vendor"
 NAMES = frozenset({"idna", "urllib3"})
 
 # Imports used by the test sources; names are resolved through them.
@@ -109,7 +113,7 @@ def test_find_issues_dynamic_imports(tmp_path: Path, source: str, code: str) ->
     (tmp_path / "pkg").mkdir()
     (tmp_path / "pkg" / "mod.py").write_text(f"{HEADER}{source}\n")
 
-    [finding] = find_issues(tmp_path, NAMES)
+    [finding] = find_issues(tmp_path, NAMES, NAMESPACE)
 
     assert finding.kind == DYNAMIC_IMPORTS
     assert finding.path == "pkg/mod.py"
@@ -142,7 +146,9 @@ def test_find_issues_dynamic_imports(tmp_path: Path, source: str, code: str) ->
         pytest.param("value = os.environ['x']", id="environ-read"),
         pytest.param("os.environ.get('x')", id="environ-get"),
         pytest.param("env = dict(os.environ)\nenv['x'] = '1'", id="environ-copy"),
-        pytest.param("import urllib3x\nfrom . import urllib3\nfrom .urllib3 import a", id="non-vendored-imports"),
+        pytest.param("from . import urllib3\nfrom .urllib3 import a", id="relative-imports"),
+        pytest.param("import os.path, json\nfrom __future__ import annotations", id="stdlib-imports"),
+        pytest.param("import annotationlib, tomllib, distutils", id="stdlib-imports-other-versions"),
         pytest.param("from opentelemetry.agent._vendor import urllib3", id="namespaced-import"),
         pytest.param("logging.getLogger(__name__)", id="logger-dunder-name"),
         pytest.param("logging.getLogger(name)", id="logger-variable"),
@@ -152,7 +158,7 @@ def test_find_issues_dynamic_imports(tmp_path: Path, source: str, code: str) ->
 def test_find_issues_ignores(tmp_path: Path, source: str) -> None:
     (tmp_path / "mod.py").write_text(f"{HEADER}{source}\n")
 
-    assert find_issues(tmp_path, NAMES) == []
+    assert find_issues(tmp_path, NAMES, NAMESPACE) == []
 
 
 @pytest.mark.parametrize(
@@ -166,13 +172,21 @@ def test_find_issues_ignores(tmp_path: Path, source: str) -> None:
 def test_find_issues_ignores_unresolved_names(tmp_path: Path, source: str) -> None:
     (tmp_path / "mod.py").write_text(f"{source}\n")
 
-    assert find_issues(tmp_path, NAMES) == []
+    assert find_issues(tmp_path, NAMES, NAMESPACE) == []
 
 
 @pytest.mark.parametrize(
     ("source", "kind", "code"),
     [
         pytest.param("import urllib3", IMPORTS, "import urllib3", id="import"),
+        pytest.param("import urllib3x", EXTERNAL_IMPORTS, "import urllib3x", id="external-prefix-collision"),
+        pytest.param("import os, yaml.nodes", EXTERNAL_IMPORTS, "import os, yaml.nodes", id="external-import"),
+        pytest.param(
+            "from aiohttp.client import ClientSession",
+            EXTERNAL_IMPORTS,
+            "from aiohttp.client import ClientSession",
+            id="external-import-from",
+        ),
         pytest.param("import os, urllib3.util as u", IMPORTS, "import os, urllib3.util as u", id="import-multiple"),
         pytest.param("from idna import core", IMPORTS, "from idna import core", id="from-import"),
         pytest.param(
@@ -204,7 +218,7 @@ def test_find_issues_ignores_unresolved_names(tmp_path: Path, source: str) -> No
 def test_find_issues(tmp_path: Path, source: str, kind: str, code: str) -> None:
     (tmp_path / "mod.py").write_text(f"{HEADER}{source}\n")
 
-    assert find_issues(tmp_path, NAMES) == [Finding(kind=kind, path="mod.py", line=SOURCE_LINE, code=code)]
+    assert find_issues(tmp_path, NAMES, NAMESPACE) == [Finding(kind=kind, path="mod.py", line=SOURCE_LINE, code=code)]
 
 
 def test_check_vendored_tree_allowed(tmp_path: Path) -> None:
@@ -215,7 +229,7 @@ def test_check_vendored_tree_allowed(tmp_path: Path) -> None:
     (tmp_path / "clean.py").write_text("import os\n")
 
     allowed = check_vendored_tree(
-        tmp_path, NAMES, {DYNAMIC_IMPORTS: ["pkg/packages.py"], SIDE_EFFECTS: ["pkg/packages.py"]}
+        tmp_path, NAMES, NAMESPACE, {DYNAMIC_IMPORTS: ["pkg/packages.py"], SIDE_EFFECTS: ["pkg/packages.py"]}
     )
 
     assert [(finding.kind, str(finding)) for finding in allowed] == [
@@ -229,7 +243,7 @@ def test_check_vendored_tree_allow_is_per_kind(tmp_path: Path) -> None:
     (tmp_path / "a.py").write_text("import os, sys\nsys.modules['x'] = m\nos.environ['x'] = '1'\n")
 
     with pytest.raises(VendorError) as exc_info:
-        check_vendored_tree(tmp_path, NAMES, {DYNAMIC_IMPORTS: ["a.py"]})
+        check_vendored_tree(tmp_path, NAMES, NAMESPACE, {DYNAMIC_IMPORTS: ["a.py"]})
 
     assert str(exc_info.value) == (
         "vendored code escapes the vendor namespace:\n"
@@ -243,7 +257,7 @@ def test_check_vendored_tree_unallowed(tmp_path: Path) -> None:
     (tmp_path / "b.py").write_text("import importlib\nimportlib.import_module(name)\n")
 
     with pytest.raises(VendorError) as exc_info:
-        check_vendored_tree(tmp_path, NAMES, {IMPORTS: ["a.py"]})
+        check_vendored_tree(tmp_path, NAMES, NAMESPACE, {IMPORTS: ["a.py"]})
 
     assert str(exc_info.value) == (
         "vendored code escapes the vendor namespace:\n"
@@ -261,14 +275,28 @@ def test_check_vendored_tree_unused_entry(tmp_path: Path) -> None:
     with pytest.raises(
         VendorError, match=r"\[tool.opentelemetry-vendor.allow\] side-effects entry 'a.py' matched nothing"
     ):
-        check_vendored_tree(tmp_path, NAMES, {DYNAMIC_IMPORTS: ["a.py"], SIDE_EFFECTS: ["a.py"]})
+        check_vendored_tree(tmp_path, NAMES, NAMESPACE, {DYNAMIC_IMPORTS: ["a.py"], SIDE_EFFECTS: ["a.py"]})
+
+
+def test_check_vendored_tree_allow_patterns(tmp_path: Path) -> None:
+    (tmp_path / "pkg/instrumentation/aiohttp").mkdir(parents=True)
+    (tmp_path / "pkg/instrumentation/aiohttp/__init__.py").write_text("import aiohttp\n")
+    (tmp_path / "pkg/instrumentation/utils.py").write_text("from gevent import monkey\n")
+    (tmp_path / "pkg/loader.py").write_text("import yaml\n")
+
+    with pytest.raises(VendorError) as exc_info:
+        check_vendored_tree(tmp_path, NAMES, NAMESPACE, {EXTERNAL_IMPORTS: ["pkg/instrumentation/*"]})
+    assert str(exc_info.value).endswith("    pkg/loader.py:1: import yaml")
+
+    with pytest.raises(VendorError, match=r"external-imports entry 'other/\*' matched nothing"):
+        check_vendored_tree(tmp_path, NAMES, NAMESPACE, {EXTERNAL_IMPORTS: ["pkg/*", "other/*"]})
 
 
 def test_check_vendored_tree_unparsable_file(tmp_path: Path) -> None:
     (tmp_path / "broken.py").write_text("__import__(\n")
 
     with pytest.raises(VendorError, match=r"cannot parse .*broken\.py"):
-        check_vendored_tree(tmp_path, NAMES, {})
+        check_vendored_tree(tmp_path, NAMES, NAMESPACE, {})
 
 
 @pytest.mark.parametrize(
@@ -295,6 +323,60 @@ def test_find_issues_protobuf_module_names(
     call = f"builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, {module_name!r}, _globals)"
     (tmp_path / "x_pb2.py").write_text(f"{builder_import}\n{call}\n")
 
-    findings = [finding for finding in find_issues(tmp_path, NAMES | {"google"}) if finding.kind != IMPORTS]
+    findings = [finding for finding in find_issues(tmp_path, NAMES | {"google"}, NAMESPACE) if finding.kind != IMPORTS]
 
     assert findings == ([Finding(kind=MODULE_NAMES, path="x_pb2.py", line=2, code=call)] if flagged else [])
+
+
+def test_find_native_issues(tmp_path: Path) -> None:
+    for file in ("google/protobuf/__init__.py", "google/protobuf/message.py", "google/protobuf/internal/wkt.py"):
+        (tmp_path / file).parent.mkdir(parents=True, exist_ok=True)
+        (tmp_path / file).write_text("")
+    (tmp_path / "google/_upb").mkdir()
+    extension = tmp_path / "google/_upb/_message.abi3.so"
+    extension.write_bytes(
+        b"\x00google._upb._message\x00"  # the extension's own (leaf) module name
+        b"google._upb._message.Message\x00"  # a type name under it
+        b"google.protobuf.message\x00"  # a C-level import of a vendored module
+        b"\x0fgoogle.protobufB\x07"  # a protobuf package name in an embedded descriptor
+        b"google.protobuf.Any\x00"  # a protobuf type name
+        b"google.protobuf.internal\x00"  # a package path alone
+        b"opentelemetry.agent._vendor.google.protobuf.message\x00"  # namespaced
+        b"other.module\x00"
+    )
+
+    findings = find_native_issues(tmp_path, {"google"}, NAMESPACE, [extension])
+
+    assert [(finding.kind, finding.path, finding.code) for finding in findings] == [
+        (NATIVE_MODULE_NAMES, "google/_upb/_message.abi3.so", "google._upb._message"),
+        (NATIVE_MODULE_NAMES, "google/_upb/_message.abi3.so", "google._upb._message.Message"),
+        (NATIVE_MODULE_NAMES, "google/_upb/_message.abi3.so", "google.protobuf.message"),
+    ]
+    assert findings[0].line == 1  # byte offset
+
+
+def test_find_issues_namespace_shares_top_level_name(tmp_path: Path) -> None:
+    # Vendoring ``opentelemetry`` into ``opentelemetry.agent._vendor``: rewritten names aren't leftovers.
+    (tmp_path / "mod.py").write_text(
+        "import logging\n"
+        "import opentelemetry.agent._vendor.opentelemetry.trace\n"
+        "from opentelemetry.agent._vendor.opentelemetry import trace\n"
+        "logging.getLogger('opentelemetry.agent._vendor.opentelemetry.sdk')\n"
+        "import opentelemetry.trace\n"
+    )
+
+    findings = find_issues(tmp_path, NAMES | {"opentelemetry"}, NAMESPACE)
+
+    assert findings == [Finding(kind=IMPORTS, path="mod.py", line=5, code="import opentelemetry.trace")]
+
+
+def test_find_native_issues_namespace_shares_top_level_name(tmp_path: Path) -> None:
+    for file in ("opentelemetry/trace/__init__.py", "opentelemetry/trace/span.py"):
+        (tmp_path / file).parent.mkdir(parents=True, exist_ok=True)
+        (tmp_path / file).write_text("")
+    extension = tmp_path / "opentelemetry/_ext.abi3.so"
+    extension.write_bytes(b"\x00opentelemetry.agent._vendor.opentelemetry.trace.span\x00opentelemetry.trace.span\x00")
+
+    findings = find_native_issues(tmp_path, {"opentelemetry"}, NAMESPACE, [extension])
+
+    assert [finding.code for finding in findings] == ["opentelemetry.trace.span"]
diff --git a/agent/opentelemetry-vendor/tests/test_cli.py b/agent/opentelemetry-vendor/tests/test_cli.py
index b72c86fd616..ab0ba600d8a 100644
--- a/agent/opentelemetry-vendor/tests/test_cli.py
+++ b/agent/opentelemetry-vendor/tests/test_cli.py
@@ -10,6 +10,7 @@
 import pytest
 from typer.testing import CliRunner
 
+from opentelemetry.vendor import native as native_module
 from opentelemetry.vendor import sync as sync_module
 from opentelemetry.vendor.cli import app
 from opentelemetry.vendor.download import DownloadError
@@ -292,6 +293,51 @@ def test_sync_check_out_of_date(project_dir: Path, monkeypatch: pytest.MonkeyPat
     assert not (destination / "six.LICENSE").exists()
 
 
+def test_sync_unused_license_files_entry(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(pyproject.read_text() + '[tool.opentelemetry-vendor.license-files]\nother = "LICENSE"\n')
+    _fake_download(monkeypatch)
+
+    result = runner.invoke(app, ["sync", str(project_dir)])
+
+    assert result.exit_code == 1
+    assert "license-files entries ['other'] match no vendored distribution" in result.output
+
+
+def test_sync_metadata_dir(project_dir: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(pyproject.read_text() + 'metadata-dir = "_metadata"\n')
+    cache = tmp_path / "wheel-cache"
+    cache.mkdir()
+    wheel = make_wheel(
+        cache,
+        "six",
+        "1.0",
+        ["six/__init__.py", "six/plugin.py"],
+        metadata="License-Expression: MIT\n",
+        entry_points="[console_scripts]\nsix = six:main\n\n[six_plugins]\nplugin = six.plugin:Plugin\n",
+    )
+
+    def fake_download_wheels(requirements: Path, python_version: str, dest: Path) -> list[Path]:
+        return [Path(shutil.copy(wheel, dest))]
+
+    monkeypatch.setattr(sync_module, "download_wheels", fake_download_wheels)
+
+    result = runner.invoke(app, ["sync", str(project_dir)])
+
+    assert result.exit_code == 0, result.output
+    assert "✔ Wrote metadata to src/pkg/_vendor/_metadata (1 entry point)" in result.output.splitlines()
+    dist_info = project_dir / "src/pkg/_vendor/_metadata/six-1.0.dist-info"
+    assert (dist_info / "entry_points.txt").read_text() == "[six_plugins]\nplugin = pkg._vendor.six.plugin:Plugin\n"
+    assert not (project_dir / "src/pkg/_vendor/six-1.0.dist-info").exists()
+
+    assert runner.invoke(app, ["sync", "--check", str(project_dir)]).exit_code == 0
+    (dist_info / "entry_points.txt").write_text("")
+    result = runner.invoke(app, ["sync", "--check", str(project_dir)])
+    assert result.exit_code == 1
+    assert result.output.endswith("  ~ _metadata/six-1.0.dist-info/entry_points.txt\n")
+
+
 def test_sync_check_sbom_outside_destination(
     project_dir: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path
 ) -> None:
@@ -323,3 +369,21 @@ def test_sync_failure_cleans_destination(project_dir: Path, monkeypatch: pytest.
     assert "does not apply" in result.output
     # Neither the unpacked package nor its *.dist-info is left behind.
     assert sorted(p.name for p in (project_dir / "src/pkg/_vendor").iterdir()) == ["requirements.txt"]
+
+
+def test_build_native_cli(project_dir: Path, monkeypatch: pytest.MonkeyPatch) -> None:
+    calls = []
+    monkeypatch.setattr(native_module, "build_native", lambda config: calls.append(("build", config.project_dir)))
+    monkeypatch.setattr(native_module, "clean_native", lambda config: calls.append(("clean", config.project_dir)))
+
+    assert runner.invoke(app, ["build-native", str(project_dir)]).exit_code == 0
+    assert runner.invoke(app, ["build-native", "--clean", str(project_dir)]).exit_code == 0
+
+    assert calls == [("build", project_dir.resolve()), ("clean", project_dir.resolve())]
+
+
+def test_build_native_cli_error(project_dir: Path) -> None:
+    result = runner.invoke(app, ["build-native", str(project_dir)])
+
+    assert result.exit_code == 1
+    assert result.output.startswith("error: ")
diff --git a/agent/opentelemetry-vendor/tests/test_config.py b/agent/opentelemetry-vendor/tests/test_config.py
index 5e80e86d1c1..60906eaae52 100644
--- a/agent/opentelemetry-vendor/tests/test_config.py
+++ b/agent/opentelemetry-vendor/tests/test_config.py
@@ -22,6 +22,45 @@ def test_load_config(project_dir: Path) -> None:
     assert config.python_version == "3.10"
     assert tuple(config.protected_files) == ("__init__.py", "requirements.txt")
     assert config.sbom_file == root / "src/pkg/_vendor/bom.cdx.json"
+    assert config.metadata_dir is None
+
+
+def test_load_config_license_files(project_dir: Path) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(
+        pyproject.read_text() + '[tool.opentelemetry-vendor.license-files]\nOpenTelemetry_Distro = "../LICENSE"\n'
+    )
+
+    config = load_config(project_dir)
+
+    assert config.license_files == {"opentelemetry-distro": project_dir.resolve() / "../LICENSE"}
+
+
+@pytest.mark.parametrize("content", ['license-files = ["LICENSE"]\n', 'license-files = { pkg = "" }\n'])
+def test_load_config_invalid_license_files(project_dir: Path, content: str) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(pyproject.read_text() + content)
+
+    with pytest.raises(ConfigError, match="'license-files' must be a table"):
+        load_config(project_dir)
+
+
+def test_load_config_metadata_dir(project_dir: Path) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(pyproject.read_text() + 'metadata-dir = "_metadata"\n')
+
+    config = load_config(project_dir)
+
+    assert config.metadata_dir == project_dir.resolve() / "src/pkg/_vendor/_metadata"
+
+
+@pytest.mark.parametrize("entry", ["/abs", "../outside", ""])
+def test_load_config_invalid_metadata_dir(project_dir: Path, entry: str) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(pyproject.read_text() + f"metadata-dir = {entry!r}\n")
+
+    with pytest.raises(ConfigError, match="metadata-dir"):
+        load_config(project_dir)
 
 
 def test_load_config_optional_keys(tmp_path: Path) -> None:
@@ -157,3 +196,42 @@ def test_load_config_moved_allow_dynamic_imports(project_dir: Path) -> None:
         ConfigError, match=r"'allow-dynamic-imports' moved to \[tool.opentelemetry-vendor.allow\] dynamic-imports"
     ):
         load_config(project_dir)
+
+
+def test_load_config_native(project_dir: Path) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(
+        pyproject.read_text()
+        + '[tool.opentelemetry-vendor.native.Google_Protobuf]\npatches = ["patches/native/a.patch"]\n'
+        'build-requirements = "native-build-requirements.txt"\n'
+    )
+
+    config = load_config(project_dir)
+
+    root = project_dir.resolve()
+    assert list(config.native) == ["google-protobuf"]
+    assert tuple(config.native["google-protobuf"].patches) == (root / "patches/native/a.patch",)
+    assert config.native["google-protobuf"].build_requirements == root / "native-build-requirements.txt"
+    assert load_config(project_dir).allow == {}
+
+
+@pytest.mark.parametrize(
+    ("content", "message"),
+    [
+        pytest.param('native = ["protobuf"]\n', r"'native' must be a table", id="not-a-table"),
+        pytest.param(
+            "[tool.opentelemetry-vendor.native]\nprotobuf = 1\n", r"'native.protobuf' must be a table", id="entry"
+        ),
+        pytest.param(
+            "[tool.opentelemetry-vendor.native.protobuf]\npatches = []\n",
+            "missing required key 'build-requirements'",
+            id="missing-build-requirements",
+        ),
+    ],
+)
+def test_load_config_invalid_native(project_dir: Path, content: str, message: str) -> None:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(pyproject.read_text() + content)
+
+    with pytest.raises(ConfigError, match=message):
+        load_config(project_dir)
diff --git a/agent/opentelemetry-vendor/tests/test_entry_points.py b/agent/opentelemetry-vendor/tests/test_entry_points.py
new file mode 100644
index 00000000000..06393cb973a
--- /dev/null
+++ b/agent/opentelemetry-vendor/tests/test_entry_points.py
@@ -0,0 +1,152 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+from __future__ import annotations
+
+from importlib.metadata import distributions
+from pathlib import Path
+
+import pytest
+
+from opentelemetry.vendor.entry_points import rewrite_entry_points, write_metadata
+from opentelemetry.vendor.errors import VendorError
+from opentelemetry.vendor.metadata import VendoredPackage
+
+NAMESPACE = "opentelemetry.agent._vendor"
+NAMES = frozenset({"opentelemetry", "wrapt"})
+
+
+def _package(tmp_path: Path, entry_points: str | None) -> VendoredPackage:
+    dist_info = tmp_path / "unpacked" / "opentelemetry_sdk-1.0.dist-info"
+    dist_info.mkdir(parents=True)
+    (dist_info / "METADATA").write_text(
+        'Metadata-Version: 2.4\nName: opentelemetry-sdk\nVersion: 1.0\nRequires-Dist: wrapt; extra == "instruments"\n'
+    )
+    (dist_info / "RECORD").write_text("")
+    if entry_points is not None:
+        (dist_info / "entry_points.txt").write_text(entry_points)
+    return VendoredPackage(
+        name="opentelemetry-sdk",
+        version="1.0",
+        sha256="0" * 64,
+        license_expression=None,
+        top_level_names=("opentelemetry",),
+        license_files={},
+        dist_info=dist_info,
+    )
+
+
+def _vendored_tree(tmp_path: Path, *modules: str) -> Path:
+    destination = tmp_path / "_vendor"
+    for module in modules:
+        path = destination / module
+        path.parent.mkdir(parents=True, exist_ok=True)
+        path.write_text("")
+    return destination
+
+
+def test_rewrite_entry_points() -> None:
+    text = (
+        "[console_scripts]\n"
+        "opentelemetry-instrument = opentelemetry.instrumentation.auto_instrumentation:run\n"
+        "\n"
+        "[opentelemetry_traces_exporter]\n"
+        "Console = opentelemetry.sdk.trace.export:ConsoleSpanExporter\n"
+        "extras = opentelemetry.sdk.trace : Tracer [grpc]\n"
+        "module-only = opentelemetry.sdk.environment_variables\n"
+        "already = opentelemetry.agent._vendor.opentelemetry.sdk:X\n"
+        "external = aiohttp.client:ClientSession\n"
+        "\n"
+        "[gui_scripts]\n"
+        "gui = opentelemetry.gui:main\n"
+    )
+
+    assert rewrite_entry_points(text, NAMESPACE, NAMES) == {
+        "opentelemetry_traces_exporter": {
+            "Console": "opentelemetry.agent._vendor.opentelemetry.sdk.trace.export:ConsoleSpanExporter",
+            "extras": "opentelemetry.agent._vendor.opentelemetry.sdk.trace : Tracer [grpc]",
+            "module-only": "opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables",
+            "already": "opentelemetry.agent._vendor.opentelemetry.sdk:X",
+            "external": "aiohttp.client:ClientSession",
+        }
+    }
+
+
+def test_rewrite_entry_points_invalid_value() -> None:
+    with pytest.raises(VendorError, match=r"invalid entry point group:name = 'not a module'"):
+        rewrite_entry_points("[group]\nname = not a module\n", NAMESPACE, NAMES)
+
+
+def test_write_metadata(tmp_path: Path) -> None:
+    destination = _vendored_tree(
+        tmp_path, "opentelemetry/sdk/trace/export/__init__.py", "opentelemetry/sdk/environment_variables.py"
+    )
+    package = _package(
+        tmp_path,
+        "[console_scripts]\nscript = opentelemetry.sdk:main\n\n"
+        "[opentelemetry_traces_exporter]\nconsole = opentelemetry.sdk.trace.export:ConsoleSpanExporter\n\n"
+        "[opentelemetry_environment_variables]\nsdk = opentelemetry.sdk.environment_variables\n",
+    )
+    metadata_dir = destination / "_metadata"
+
+    count = write_metadata([package], destination, metadata_dir, NAMESPACE, NAMES)
+
+    assert count == 2
+    dist_info = metadata_dir / "opentelemetry_sdk-1.0.dist-info"
+    assert sorted(path.name for path in dist_info.iterdir()) == ["METADATA", "entry_points.txt"]
+    assert (dist_info / "entry_points.txt").read_text() == (
+        "[opentelemetry_traces_exporter]\n"
+        "console = opentelemetry.agent._vendor.opentelemetry.sdk.trace.export:ConsoleSpanExporter\n"
+        "\n"
+        "[opentelemetry_environment_variables]\n"
+        "sdk = opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables\n"
+    )
+    # importlib.metadata finds the copy only through an explicit path.
+    [distribution] = distributions(path=[str(metadata_dir)])
+    assert distribution.metadata["Name"] == "opentelemetry-sdk"
+    assert distribution.requires == ['wrapt; extra == "instruments"']
+    [entry_point] = distribution.entry_points.select(group="opentelemetry_traces_exporter")
+    assert entry_point.module == "opentelemetry.agent._vendor.opentelemetry.sdk.trace.export"
+    assert entry_point.dist is not None
+
+
+def test_write_metadata_without_entry_points(tmp_path: Path) -> None:
+    destination = _vendored_tree(tmp_path)
+
+    assert write_metadata([_package(tmp_path, None)], destination, destination / "_metadata", NAMESPACE, NAMES) == 0
+
+    dist_info = destination / "_metadata" / "opentelemetry_sdk-1.0.dist-info"
+    assert [path.name for path in dist_info.iterdir()] == ["METADATA"]
+
+
+def test_write_metadata_only_script_entry_points(tmp_path: Path) -> None:
+    destination = _vendored_tree(tmp_path)
+    package = _package(tmp_path, "[console_scripts]\nscript = opentelemetry.sdk:main\n")
+
+    write_metadata([package], destination, destination / "_metadata", NAMESPACE, NAMES)
+
+    assert not (destination / "_metadata" / "opentelemetry_sdk-1.0.dist-info" / "entry_points.txt").exists()
+
+
+@pytest.mark.parametrize(
+    ("value", "module"),
+    [
+        pytest.param(
+            "opentelemetry.exporter.otlp.proto.grpc:OTLPSpanExporter",
+            "opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.grpc",
+            id="missing-vendored-module",
+        ),
+        pytest.param("aiohttp.client:ClientSession", "aiohttp.client", id="non-vendored-module"),
+    ],
+)
+def test_write_metadata_missing_module(tmp_path: Path, value: str, module: str) -> None:
+    destination = _vendored_tree(tmp_path, "opentelemetry/sdk/__init__.py")
+    package = _package(tmp_path, f"[opentelemetry_traces_exporter]\notlp = {value}\n")
+
+    with pytest.raises(VendorError) as exc_info:
+        write_metadata([package], destination, destination / "_metadata", NAMESPACE, NAMES)
+
+    assert str(exc_info.value) == (
+        f"entry point opentelemetry_traces_exporter:otlp of opentelemetry-sdk references {module}, "
+        "which isn't in the vendored tree"
+    )
diff --git a/agent/opentelemetry-vendor/tests/test_metadata.py b/agent/opentelemetry-vendor/tests/test_metadata.py
index 61125531303..ce7eb42117a 100644
--- a/agent/opentelemetry-vendor/tests/test_metadata.py
+++ b/agent/opentelemetry-vendor/tests/test_metadata.py
@@ -131,6 +131,35 @@ def test_read_package_without_license_file(tmp_path: Path) -> None:
         _read(tmp_path, wheel)
 
 
+def test_read_package_license_file_override(tmp_path: Path) -> None:
+    license_file = tmp_path / "LICENSE"
+    license_file.write_text("Apache License")
+    wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"], licenses={})
+    ((wheel, dist_info),) = unpack_wheels([wheel], tmp_path / "_vendor").items()
+
+    package = read_package(wheel, dist_info, license_file)
+
+    assert package.license_files == {"pkg.LICENSE": license_file}
+
+
+def test_read_package_license_file_override_unneeded(tmp_path: Path) -> None:
+    license_file = tmp_path / "LICENSE"
+    license_file.write_text("Apache License")
+    wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"])
+    ((wheel, dist_info),) = unpack_wheels([wheel], tmp_path / "_vendor").items()
+
+    with pytest.raises(VendorError, match="contains a license file; remove its license-files entry"):
+        read_package(wheel, dist_info, license_file)
+
+
+def test_read_package_license_file_override_missing(tmp_path: Path) -> None:
+    wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"], licenses={})
+    ((wheel, dist_info),) = unpack_wheels([wheel], tmp_path / "_vendor").items()
+
+    with pytest.raises(VendorError, match="license file .*LICENSE for pkg does not exist"):
+        read_package(wheel, dist_info, tmp_path / "LICENSE")
+
+
 def test_copy_license_files_and_remove_dist_info(tmp_path: Path) -> None:
     destination = tmp_path / "_vendor"
     wheel = make_wheel(tmp_path, "pkg", "1.0", ["pkg.py"], licenses={"licenses/LICENSE": "text"})
diff --git a/agent/opentelemetry-vendor/tests/test_native.py b/agent/opentelemetry-vendor/tests/test_native.py
new file mode 100644
index 00000000000..523b173624e
--- /dev/null
+++ b/agent/opentelemetry-vendor/tests/test_native.py
@@ -0,0 +1,234 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+from __future__ import annotations
+
+import hashlib
+import io
+import json
+import sys
+import tarfile
+import zipfile
+from collections.abc import Mapping
+from pathlib import Path
+
+import pytest
+
+from opentelemetry.vendor import native
+from opentelemetry.vendor.config import load_config
+from opentelemetry.vendor.errors import VendorError
+from opentelemetry.vendor.metadata import VendoredPackage
+from opentelemetry.vendor.sbom import write_sbom
+
+CURRENT_PYTHON = f"{sys.version_info.major}.{sys.version_info.minor}"
+NATIVE_PATCH = """\
+Rename the module.
+
+diff --git a/setup.py b/setup.py
+--- a/setup.py
++++ b/setup.py
+@@ -1 +1 @@
+-NAME = 'six._ext'
++NAME = 'pkg._vendor.six._ext'
+"""
+EXTENSION = "pkg/_vendor/six/_ext.abi3.so"
+
+
+def _sdist(directory: Path, files: Mapping[str, str] | None = None) -> Path:
+    path = directory / "six-1.0.tar.gz"
+    with tarfile.open(path, "w:gz") as archive:
+        for name, content in (files or {"six-1.0/setup.py": "NAME = 'six._ext'\n"}).items():
+            data = content.encode()
+            info = tarfile.TarInfo(name)
+            info.size = len(data)
+            archive.addfile(info, io.BytesIO(data))
+    return path
+
+
+def _wheel(directory: Path, members: Mapping[str, bytes]) -> Path:
+    path = directory / "six-1.0-cp310-abi3-plat.whl"
+    with zipfile.ZipFile(path, "w") as archive:
+        for name, data in members.items():
+            archive.writestr(name, data)
+    return path
+
+
+@pytest.fixture(name="native_project")
+def fixture_native_project(project_dir: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> Path:
+    pyproject = project_dir / "pyproject.toml"
+    pyproject.write_text(
+        pyproject.read_text().replace('python-version = "3.10"', f'python-version = "{CURRENT_PYTHON}"')
+        + '\n[tool.opentelemetry-vendor.native.six]\npatches = ["patches/native/six.patch"]\n'
+        'build-requirements = "native-build-requirements.txt"\n'
+    )
+    (project_dir / "patches/native").mkdir(parents=True)
+    (project_dir / "patches/native/six.patch").write_text(NATIVE_PATCH)
+    (project_dir / "native-build-requirements.txt").write_text("setuptools==1.0 --hash=sha256:00\n")
+    destination = project_dir / "src/pkg/_vendor"
+    (destination / "six").mkdir()
+    (destination / "six/__init__.py").write_text("")
+    (destination / "six/moves.py").write_text("")
+    package = VendoredPackage(
+        name="six",
+        version="1.0",
+        sha256=hashlib.sha256(b"six").hexdigest(),
+        license_expression="MIT",
+        top_level_names=("six",),
+        license_files={},
+        dist_info=Path("six-1.0.dist-info"),
+    )
+    write_sbom([package], destination / "bom.cdx.json")
+
+    sdists = tmp_path / "sdists"
+    sdists.mkdir()
+    monkeypatch.setattr(native, "download_sdist", lambda requirement, dest: _sdist(sdists))
+    set_built_wheel(monkeypatch, tmp_path, {EXTENSION: b"\x00pkg._vendor.six._ext\x00google.protobuf.Any\x00"})
+    return project_dir
+
+
+def set_built_wheel(monkeypatch: pytest.MonkeyPatch, tmp_path: Path, members: Mapping[str, bytes]) -> None:
+    wheels = tmp_path / "wheels"
+    wheels.mkdir(exist_ok=True)
+
+    def fake_build_wheel(source: Path, build_requirements: Path, work: Path) -> Path:
+        # The native patch was applied to the extracted sdist before building.
+        assert (source / "setup.py").read_text() == "NAME = 'pkg._vendor.six._ext'\n"
+        assert build_requirements.name == "native-build-requirements.txt"
+        return _wheel(wheels, members)
+
+    monkeypatch.setattr(native, "_build_wheel", fake_build_wheel)
+
+
+def test_build_native_and_clean(native_project: Path) -> None:
+    config = load_config(native_project)
+    sbom = config.destination / "bom.cdx.json"
+    committed_sbom = sbom.read_bytes()
+
+    written = native.build_native(config)
+
+    extension = config.destination / "six/_ext.abi3.so"
+    assert written == [extension]
+    assert extension.read_bytes().startswith(b"\x00pkg._vendor.six._ext")
+    [component] = json.loads(sbom.read_text())["components"]
+    assert [patch["diff"]["text"]["content"] for patch in component["pedigree"]["patches"]] == [NATIVE_PATCH]
+    assert component["properties"] == [
+        {
+            "name": "opentelemetry-vendor:native-sdist-sha256",
+            "value": hashlib.sha256((native_project / "sdists/six-1.0.tar.gz").read_bytes()).hexdigest(),
+        },
+        {"name": "opentelemetry-vendor:native-extension", "value": "six/_ext.abi3.so"},
+    ]
+    assert json.loads(sbom.read_text())["serialNumber"] != json.loads(committed_sbom)["serialNumber"]
+
+    native.clean_native(config)
+
+    assert not extension.exists()
+    assert sbom.read_bytes() == committed_sbom
+    assert not (native_project / "build/opentelemetry-vendor").exists()
+
+
+def test_build_native_creates_namespace_package_directories(
+    native_project: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path
+) -> None:
+    set_built_wheel(monkeypatch, tmp_path, {"pkg/_vendor/six/_native/_ext.abi3.so": b""})
+    config = load_config(native_project)
+
+    native.build_native(config)
+    assert (config.destination / "six/_native/_ext.abi3.so").exists()
+    native.clean_native(config)
+
+    assert not (config.destination / "six/_native").exists()
+    assert (config.destination / "six/__init__.py").exists()
+
+
+@pytest.mark.parametrize(
+    ("members", "message"),
+    [
+        pytest.param({"pkg/_vendor/six/__init__.py": b""}, r"contains no extension under pkg/_vendor/", id="none"),
+        pytest.param(
+            {"pkg/_vendor/six/_ext.cpython-310-darwin.so": b""}, r"isn't a stable-ABI \(abi3\) extension", id="not-abi3"
+        ),
+        pytest.param(
+            {EXTENSION: b"\x00six.moves\x00six.moves.urllib\x00"},
+            r"native-module-names.*\n.*six/_ext\.abi3\.so:1: six\.moves",
+            id="un-namespaced-module-name",
+        ),
+    ],
+)
+def test_build_native_errors_restore_tree(
+    native_project: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path, members: Mapping[str, bytes], message: str
+) -> None:
+    set_built_wheel(monkeypatch, tmp_path, members)
+    config = load_config(native_project)
+    committed_sbom = (config.destination / "bom.cdx.json").read_bytes()
+
+    with pytest.raises(VendorError, match=message):
+        native.build_native(config)
+
+    assert not list(config.destination.rglob("*.so"))
+    assert (config.destination / "bom.cdx.json").read_bytes() == committed_sbom
+    assert not (native_project / "build/opentelemetry-vendor").exists()
+
+
+def test_build_native_allowed_native_finding(
+    native_project: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path
+) -> None:
+    set_built_wheel(monkeypatch, tmp_path, {EXTENSION: b"\x00six.moves\x00"})
+    pyproject = native_project / "pyproject.toml"
+    pyproject.write_text(
+        pyproject.read_text() + '\n[tool.opentelemetry-vendor.allow]\nnative-module-names = ["six/_ext.abi3.so"]\n'
+    )
+
+    assert native.build_native(load_config(native_project))
+
+
+def test_build_native_patch_does_not_apply(native_project: Path) -> None:
+    (native_project / "patches/native/six.patch").write_text(NATIVE_PATCH.replace("-NAME = 'six._ext'", "-NAME = 'x'"))
+
+    with pytest.raises(VendorError, match=r"six\.patch does not apply"):
+        native.build_native(load_config(native_project))
+
+
+def test_build_native_requirement_not_pinned(native_project: Path) -> None:
+    pyproject = native_project / "pyproject.toml"
+    pyproject.write_text(pyproject.read_text().replace("native.six]", "native.Other_Pkg]"))
+
+    with pytest.raises(VendorError, match=r"native build 'other-pkg' is not pinned in"):
+        native.build_native(load_config(native_project))
+
+
+def test_build_native_requires_synced_tree(native_project: Path) -> None:
+    config = load_config(native_project)
+    for path in sorted(config.destination.rglob("*"), reverse=True):
+        if path.name not in ("requirements.txt", "bom.cdx.json"):
+            path.unlink() if path.is_file() else path.rmdir()
+
+    with pytest.raises(VendorError, match="has no vendored packages; run opentelemetry-vendor sync first"):
+        native.build_native(config)
+
+
+def test_build_native_unsafe_sdist(native_project: Path, monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
+    unsafe = tmp_path / "unsafe"
+    unsafe.mkdir()
+    monkeypatch.setattr(
+        native, "download_sdist", lambda requirement, dest: _sdist(unsafe, {"six-1.0/../../evil.py": "x"})
+    )
+
+    with pytest.raises(VendorError, match=r"contains an unsafe path: six-1\.0/\.\./\.\./evil\.py"):
+        native.build_native(load_config(native_project))
+
+
+def test_check_interpreter_version() -> None:
+    with pytest.raises(VendorError, match=r"must run on CPython 2\.7 \(running CPython"):
+        native._check_interpreter("2.7")
+
+
+def test_check_interpreter_free_threaded(monkeypatch: pytest.MonkeyPatch) -> None:
+    monkeypatch.setattr(native.sysconfig, "get_config_var", lambda name: 1 if name == "Py_GIL_DISABLED" else None)
+
+    with pytest.raises(VendorError, match="can't run on a free-threaded interpreter"):
+        native._check_interpreter(CURRENT_PYTHON)
+
+
+def test_clean_native_without_build(native_project: Path) -> None:
+    native.clean_native(load_config(native_project))
diff --git a/agent/opentelemetry-vendor/tests/test_rewrite.py b/agent/opentelemetry-vendor/tests/test_rewrite.py
index 79842d7657a..e0b5bd421c2 100644
--- a/agent/opentelemetry-vendor/tests/test_rewrite.py
+++ b/agent/opentelemetry-vendor/tests/test_rewrite.py
@@ -3,6 +3,7 @@
 
 from __future__ import annotations
 
+import sys
 from pathlib import Path
 
 import pytest
@@ -74,7 +75,7 @@
         ),
         pytest.param(
             "import urllib3.contrib.socks\n",
-            "from opentelemetry.agent._vendor import urllib3\nimport opentelemetry.agent._vendor.urllib3.contrib.socks\n",
+            "import opentelemetry.agent._vendor.urllib3.contrib.socks\nfrom opentelemetry.agent._vendor import urllib3\n",
             id="import-submodule",
         ),
         pytest.param(
@@ -89,10 +90,10 @@
         ),
         pytest.param(
             "import urllib3.util\nimport urllib3.exceptions\n",
-            "from opentelemetry.agent._vendor import urllib3\n"
             "import opentelemetry.agent._vendor.urllib3.util\n"
             "from opentelemetry.agent._vendor import urllib3\n"
-            "import opentelemetry.agent._vendor.urllib3.exceptions\n",
+            "import opentelemetry.agent._vendor.urllib3.exceptions\n"
+            "from opentelemetry.agent._vendor import urllib3\n",
             id="import-submodules-repeat-binding",
         ),
         pytest.param(
@@ -107,13 +108,13 @@
         ),
         pytest.param(
             "try: import idna, urllib3.util\nexcept ImportError: pass\n",
-            "try: from opentelemetry.agent._vendor import idna; from opentelemetry.agent._vendor import urllib3; "
-            "import opentelemetry.agent._vendor.urllib3.util\nexcept ImportError: pass\n",
+            "try: from opentelemetry.agent._vendor import idna; import opentelemetry.agent._vendor.urllib3.util; "
+            "from opentelemetry.agent._vendor import urllib3\nexcept ImportError: pass\n",
             id="import-one-line-suite",
         ),
         pytest.param(
             "import urllib3.util; x = 1\n",
-            "from opentelemetry.agent._vendor import urllib3\nimport opentelemetry.agent._vendor.urllib3.util\nx = 1\n",
+            "import opentelemetry.agent._vendor.urllib3.util\nfrom opentelemetry.agent._vendor import urllib3\nx = 1\n",
             id="import-semicolon-line-split",
         ),
         pytest.param(
@@ -123,8 +124,8 @@
         ),
         pytest.param(
             "if True:\n    import urllib3.util  # trailing\n    y = 2\n",
-            "if True:\n    from opentelemetry.agent._vendor import urllib3\n"
-            "    import opentelemetry.agent._vendor.urllib3.util  # trailing\n    y = 2\n",
+            "if True:\n    import opentelemetry.agent._vendor.urllib3.util\n"
+            "    from opentelemetry.agent._vendor import urllib3  # trailing\n    y = 2\n",
             id="import-indented-split",
         ),
     ],
@@ -153,6 +154,67 @@ def test_rewrite_source_unchanged(source: str) -> None:
     assert rewrite_source(source, NAMESPACE, NAMES) == source
 
 
+@pytest.mark.parametrize(
+    ("source", "expected"),
+    [
+        pytest.param(
+            "from opentelemetry import trace\n",
+            "from opentelemetry.agent._vendor.opentelemetry import trace\n",
+            id="from-import",
+        ),
+        pytest.param(
+            "import opentelemetry.trace\n",
+            "import opentelemetry.agent._vendor.opentelemetry.trace\n"
+            "from opentelemetry.agent._vendor import opentelemetry\n",
+            id="import-submodule",
+        ),
+        pytest.param(
+            # ``import opentelemetry.agent._vendor.urllib3.util`` re-binds ``opentelemetry`` to the real package.
+            "import urllib3.util\n",
+            "import opentelemetry.agent._vendor.urllib3.util\n"
+            "from opentelemetry.agent._vendor import urllib3\n"
+            "from opentelemetry.agent._vendor import opentelemetry\n",
+            id="import-other-submodule-rebinds-top-level",
+        ),
+        pytest.param(
+            "from opentelemetry.agent._vendor.opentelemetry import trace\n",
+            "from opentelemetry.agent._vendor.opentelemetry import trace\n",
+            id="already-vendored",
+        ),
+        pytest.param(
+            "import logging\nlogging.getLogger('opentelemetry.agent._vendor.opentelemetry.sdk')\n",
+            "import logging\nlogging.getLogger('opentelemetry.agent._vendor.opentelemetry.sdk')\n",
+            id="logger-already-vendored",
+        ),
+    ],
+)
+def test_rewrite_source_namespace_shares_top_level_name(source: str, expected: str) -> None:
+    # The namespace starts with the vendored top-level name ``opentelemetry``.
+    assert rewrite_source(source, NAMESPACE, NAMES | {"opentelemetry"}) == expected
+
+
+def test_rewritten_submodule_import_binds_vendored_package(tmp_path: Path) -> None:
+    # A vendored tree whose namespace starts with the vendored top-level name, as for the agent.
+    for file in ("ns/__init__.py", "ns/_vendor/__init__.py", "ns/_vendor/ns/__init__.py", "ns/_vendor/ns/sub.py"):
+        (tmp_path / file).parent.mkdir(parents=True, exist_ok=True)
+        (tmp_path / file).write_text("")
+    (tmp_path / "ns/_vendor/ns/sub.py").write_text("VALUE = 1\n")
+    source = rewrite_source("import ns.sub\nresult = ns.sub.VALUE\n", "ns._vendor", {"ns"})
+    (tmp_path / "mod.py").write_text(source)
+
+    namespace: dict[str, object] = {}
+    sys.path.insert(0, str(tmp_path))
+    try:
+        exec(compile(source, str(tmp_path / "mod.py"), "exec"), namespace)
+    finally:
+        sys.path.remove(str(tmp_path))
+        for module in [name for name in sys.modules if name == "ns" or name.startswith("ns.")]:
+            del sys.modules[module]
+
+    assert namespace["result"] == 1
+    assert getattr(namespace["ns"], "__name__", None) == "ns._vendor.ns"
+
+
 def test_rewrite_imports(tmp_path: Path) -> None:
     (tmp_path / "urllib3" / "util").mkdir(parents=True)
     (tmp_path / "__init__.py").write_text("")

From 25984d27651164e16f4b10c76a3dbde1b59c925b Mon Sep 17 00:00:00 2001
From: Lukas Hering 
Date: Tue, 10 Nov 2026 15:54:58 -0500
Subject: [PATCH 5/5] stash

---
 .github/workflows/core_contrib_test.yml       |    70 +
 .github/workflows/test.yml                    |   246 +
 agent/opentelemetry-agent/README.rst          |     9 +-
 .../patches/otel-api-bridge.patch             |    97 +
 agent/opentelemetry-agent/pyproject.toml      |    12 +
 .../opentelemetry/agent/_bridge/__init__.py   |    36 +
 .../opentelemetry/agent/_bridge/context.py    |   159 +
 .../src/opentelemetry/agent/_bridge/span.py   |   145 +
 .../src/opentelemetry/agent/_bridge/trace.py  |   126 +
 .../certifi-2026.10.23.dist-info/METADATA     |    79 -
 .../METADATA                                  |   892 -
 .../fastjsonschema-2.22.3.dist-info/METADATA  |    60 -
 .../METADATA                                  |   215 -
 .../_metadata/idna-3.20.dist-info/METADATA    |   176 -
 .../METADATA                                  |    43 -
 .../entry_points.txt                          |    15 -
 .../METADATA                                  |    73 -
 .../METADATA                                  |    50 -
 .../entry_points.txt                          |     5 -
 .../METADATA                                  |    64 -
 .../entry_points.txt                          |     3 -
 .../METADATA                                  |    52 -
 .../METADATA                                  |    48 -
 .../METADATA                                  |    56 -
 .../entry_points.txt                          |     8 -
 .../METADATA                                  |    85 -
 .../entry_points.txt                          |     8 -
 .../METADATA                                  |    51 -
 .../METADATA                                  |    71 -
 .../entry_points.txt                          |     8 -
 .../METADATA                                  |    54 -
 .../entry_points.txt                          |     2 -
 .../METADATA                                  |   183 -
 .../entry_points.txt                          |     2 -
 .../METADATA                                  |    54 -
 .../entry_points.txt                          |     2 -
 .../METADATA                                  |    48 -
 .../entry_points.txt                          |     3 -
 .../METADATA                                  |    63 -
 .../METADATA                                  |    61 -
 .../METADATA                                  |    47 -
 .../entry_points.txt                          |    38 -
 .../METADATA                                  |    61 -
 .../METADATA                                  |    93 -
 .../packaging-26.3.dist-info/METADATA         |   112 -
 .../METADATA                                  |    56 -
 .../protobuf-7.36.2.dist-info/METADATA        |    17 -
 .../requests-2.34.2.dist-info/METADATA        |   120 -
 .../ruamel_yaml-0.19.1.dist-info/METADATA     |   317 -
 .../METADATA                                  |    73 -
 .../urllib3-2.8.0.dist-info/METADATA          |   175 -
 .../_metadata/wrapt-2.5.2.dist-info/METADATA  |   193 -
 .../opentelemetry/agent/_vendor/bom.cdx.json  |   845 -
 .../agent/_vendor/certifi.LICENSE             |    20 -
 .../agent/_vendor/certifi/__init__.py         |     4 -
 .../agent/_vendor/certifi/cacert.pem          |  3885 ----
 .../agent/_vendor/certifi/core.py             |    83 -
 .../agent/_vendor/charset-normalizer.LICENSE  |    21 -
 .../_vendor/charset_normalizer/__init__.py    |    48 -
 .../agent/_vendor/charset_normalizer/api.py   |   934 -
 .../agent/_vendor/charset_normalizer/cd.py    |   467 -
 .../_vendor/charset_normalizer/constant.py    |  2497 ---
 .../_vendor/charset_normalizer/legacy.py      |    79 -
 .../agent/_vendor/charset_normalizer/md.py    |  1065 -
 .../_vendor/charset_normalizer/models.py      |   387 -
 .../agent/_vendor/charset_normalizer/utils.py |   452 -
 .../_vendor/charset_normalizer/version.py     |     8 -
 .../agent/_vendor/fastjsonschema.AUTHORS      |    11 -
 .../agent/_vendor/fastjsonschema.LICENSE      |    27 -
 .../agent/_vendor/fastjsonschema/__init__.py  |   386 -
 .../agent/_vendor/fastjsonschema/draft04.py   |   686 -
 .../agent/_vendor/fastjsonschema/draft06.py   |   222 -
 .../agent/_vendor/fastjsonschema/draft07.py   |   138 -
 .../agent/_vendor/fastjsonschema/draft2019.py |    15 -
 .../_vendor/fastjsonschema/exceptions.py      |    75 -
 .../agent/_vendor/fastjsonschema/generator.py |   429 -
 .../agent/_vendor/fastjsonschema/indent.py    |    42 -
 .../_vendor/fastjsonschema/ref_resolver.py    |   219 -
 .../agent/_vendor/fastjsonschema/version.py   |     1 -
 .../_vendor/google/api/annotations.proto      |    31 -
 .../_vendor/google/api/annotations_pb2.py     |    55 -
 .../_vendor/google/api/annotations_pb2.pyi    |    24 -
 .../agent/_vendor/google/api/auth.proto       |   238 -
 .../agent/_vendor/google/api/auth_pb2.py      |    61 -
 .../agent/_vendor/google/api/auth_pb2.pyi     |   120 -
 .../agent/_vendor/google/api/backend.proto    |   196 -
 .../agent/_vendor/google/api/backend_pb2.py   |    65 -
 .../agent/_vendor/google/api/backend_pb2.pyi  |   106 -
 .../agent/_vendor/google/api/billing.proto    |    77 -
 .../agent/_vendor/google/api/billing_pb2.py   |    53 -
 .../agent/_vendor/google/api/billing_pb2.pyi  |    50 -
 .../agent/_vendor/google/api/client.proto     |   598 -
 .../agent/_vendor/google/api/client_pb2.py    |   118 -
 .../agent/_vendor/google/api/client_pb2.pyi   |   498 -
 .../_vendor/google/api/config_change.proto    |    84 -
 .../_vendor/google/api/config_change_pb2.py   |    57 -
 .../_vendor/google/api/config_change_pb2.pyi  |    65 -
 .../agent/_vendor/google/api/consumer.proto   |    82 -
 .../agent/_vendor/google/api/consumer_pb2.py  |    55 -
 .../agent/_vendor/google/api/consumer_pb2.pyi |    62 -
 .../agent/_vendor/google/api/context.proto    |    92 -
 .../agent/_vendor/google/api/context_pb2.py   |    53 -
 .../agent/_vendor/google/api/context_pb2.pyi  |    60 -
 .../agent/_vendor/google/api/control.proto    |    41 -
 .../agent/_vendor/google/api/control_pb2.py   |    53 -
 .../agent/_vendor/google/api/control_pb2.pyi  |    43 -
 .../_vendor/google/api/distribution.proto     |   213 -
 .../_vendor/google/api/distribution_pb2.py    |    68 -
 .../_vendor/google/api/distribution_pb2.pyi   |   147 -
 .../_vendor/google/api/documentation.proto    |   168 -
 .../_vendor/google/api/documentation_pb2.py   |    57 -
 .../_vendor/google/api/documentation_pb2.pyi  |    86 -
 .../agent/_vendor/google/api/endpoint.proto   |    69 -
 .../agent/_vendor/google/api/endpoint_pb2.py  |    51 -
 .../agent/_vendor/google/api/endpoint_pb2.pyi |    41 -
 .../_vendor/google/api/error_reason.proto     |   807 -
 .../_vendor/google/api/error_reason_pb2.py    |    53 -
 .../_vendor/google/api/error_reason_pb2.pyi   |   112 -
 .../_vendor/google/api/field_behavior.proto   |   104 -
 .../_vendor/google/api/field_behavior_pb2.py  |    55 -
 .../_vendor/google/api/field_behavior_pb2.pyi |    45 -
 .../agent/_vendor/google/api/field_info.proto |   106 -
 .../_vendor/google/api/field_info_pb2.py      |    59 -
 .../_vendor/google/api/field_info_pb2.pyi     |    60 -
 .../agent/_vendor/google/api/http.proto       |   370 -
 .../agent/_vendor/google/api/http_pb2.py      |    55 -
 .../agent/_vendor/google/api/http_pb2.pyi     |    94 -
 .../agent/_vendor/google/api/httpbody.proto   |    80 -
 .../agent/_vendor/google/api/httpbody_pb2.py  |    53 -
 .../agent/_vendor/google/api/httpbody_pb2.pyi |    41 -
 .../agent/_vendor/google/api/label.proto      |    47 -
 .../agent/_vendor/google/api/label_pb2.py     |    53 -
 .../agent/_vendor/google/api/label_pb2.pyi    |    47 -
 .../_vendor/google/api/launch_stage.proto     |    72 -
 .../_vendor/google/api/launch_stage_pb2.py    |    53 -
 .../_vendor/google/api/launch_stage_pb2.pyi   |    40 -
 .../agent/_vendor/google/api/log.proto        |    54 -
 .../agent/_vendor/google/api/log_pb2.py       |    53 -
 .../agent/_vendor/google/api/log_pb2.pyi      |    47 -
 .../agent/_vendor/google/api/logging.proto    |    81 -
 .../agent/_vendor/google/api/logging_pb2.py   |    53 -
 .../agent/_vendor/google/api/logging_pb2.pyi  |    57 -
 .../agent/_vendor/google/api/metric.proto     |   287 -
 .../agent/_vendor/google/api/metric_pb2.py    |    80 -
 .../agent/_vendor/google/api/metric_pb2.pyi   |   199 -
 .../google/api/monitored_resource.proto       |   129 -
 .../google/api/monitored_resource_pb2.py      |    72 -
 .../google/api/monitored_resource_pb2.pyi     |   104 -
 .../agent/_vendor/google/api/monitoring.proto |   107 -
 .../_vendor/google/api/monitoring_pb2.py      |    55 -
 .../_vendor/google/api/monitoring_pb2.pyi     |    57 -
 .../agent/_vendor/google/api/policy.proto     |    82 -
 .../agent/_vendor/google/api/policy_pb2.py    |    55 -
 .../agent/_vendor/google/api/policy_pb2.pyi   |    57 -
 .../agent/_vendor/google/api/quota.proto      |   184 -
 .../agent/_vendor/google/api/quota_pb2.py     |    63 -
 .../agent/_vendor/google/api/quota_pb2.pyi    |   116 -
 .../agent/_vendor/google/api/resource.proto   |   242 -
 .../agent/_vendor/google/api/resource_pb2.py  |    59 -
 .../agent/_vendor/google/api/resource_pb2.pyi |    93 -
 .../agent/_vendor/google/api/routing.proto    |   465 -
 .../agent/_vendor/google/api/routing_pb2.py   |    55 -
 .../agent/_vendor/google/api/routing_pb2.pyi  |    49 -
 .../agent/_vendor/google/api/service.proto    |   190 -
 .../agent/_vendor/google/api/service_pb2.py   |    76 -
 .../agent/_vendor/google/api/service_pb2.pyi  |   170 -
 .../_vendor/google/api/source_info.proto      |    31 -
 .../_vendor/google/api/source_info_pb2.py     |    55 -
 .../_vendor/google/api/source_info_pb2.pyi    |    34 -
 .../_vendor/google/api/system_parameter.proto |    96 -
 .../google/api/system_parameter_pb2.py        |    57 -
 .../google/api/system_parameter_pb2.pyi       |    60 -
 .../agent/_vendor/google/api/usage.proto      |    76 -
 .../agent/_vendor/google/api/usage_pb2.py     |    53 -
 .../agent/_vendor/google/api/usage_pb2.pyi    |    55 -
 .../agent/_vendor/google/api/visibility.proto |   112 -
 .../_vendor/google/api/visibility_pb2.py      |    57 -
 .../_vendor/google/api/visibility_pb2.pyi     |    56 -
 .../google/cloud/common_resources.proto       |    52 -
 .../google/cloud/common_resources_pb2.py      |    53 -
 .../google/cloud/common_resources_pb2.pyi     |    21 -
 .../google/cloud/extended_operations.proto    |   150 -
 .../google/cloud/extended_operations_pb2.py   |    60 -
 .../google/cloud/extended_operations_pb2.pyi  |    45 -
 .../google/cloud/location/locations.proto     |   108 -
 .../google/cloud/location/locations_pb2.py    |    87 -
 .../google/cloud/location/locations_pb2.pyi   |    96 -
 .../gapic/metadata/gapic_metadata.proto       |    98 -
 .../gapic/metadata/gapic_metadata_pb2.py      |    78 -
 .../gapic/metadata/gapic_metadata_pb2.pyi     |   122 -
 .../google/logging/type/http_request.proto    |    95 -
 .../google/logging/type/http_request_pb2.py   |    60 -
 .../google/logging/type/http_request_pb2.pyi  |    94 -
 .../google/logging/type/log_severity.proto    |    71 -
 .../google/logging/type/log_severity_pb2.py   |    58 -
 .../google/logging/type/log_severity_pb2.pyi  |    42 -
 .../google/longrunning/operations_grpc.py     |    20 -
 .../google/longrunning/operations_grpc_pb2.py |    16 -
 .../google/longrunning/operations_pb2.py      |    45 -
 .../google/longrunning/operations_proto.proto |   265 -
 .../google/longrunning/operations_proto.py    |     6 -
 .../longrunning/operations_proto_pb2.py       |   111 -
 .../longrunning/operations_proto_pb2.pyi      |   136 -
 .../agent/_vendor/google/protobuf/__init__.py |    10 -
 .../agent/_vendor/google/protobuf/any.py      |    52 -
 .../agent/_vendor/google/protobuf/any_pb2.py  |    37 -
 .../agent/_vendor/google/protobuf/api_pb2.py  |    47 -
 .../_vendor/google/protobuf/descriptor.py     |  1669 --
 .../google/protobuf/descriptor_database.py    |   186 -
 .../_vendor/google/protobuf/descriptor_pb2.py |  3465 ----
 .../google/protobuf/descriptor_pool.py        |  1468 --
 .../agent/_vendor/google/protobuf/duration.py |   100 -
 .../_vendor/google/protobuf/duration_pb2.py   |    37 -
 .../_vendor/google/protobuf/empty_pb2.py      |    37 -
 .../_vendor/google/protobuf/field_mask_pb2.py |    37 -
 .../google/protobuf/internal/__init__.py      |     6 -
 .../protobuf/internal/api_implementation.py   |    72 -
 .../google/protobuf/internal/builder.py       |   123 -
 .../google/protobuf/internal/containers.py    |   826 -
 .../google/protobuf/internal/decoder.py       |  1127 -
 .../google/protobuf/internal/encoder.py       |   931 -
 .../protobuf/internal/enum_type_wrapper.py    |   128 -
 .../protobuf/internal/extension_dict.py       |   209 -
 .../google/protobuf/internal/field_mask.py    |   352 -
 .../protobuf/internal/message_listener.py     |    56 -
 .../internal/python_edition_defaults.py       |     5 -
 .../protobuf/internal/python_message.py       |  1778 --
 .../google/protobuf/internal/type_checkers.py |   465 -
 .../protobuf/internal/well_known_types.py     |   707 -
 .../google/protobuf/internal/wire_format.py   |   255 -
 .../protobuf/json_enumvalue_options_pb2.py    |    40 -
 .../_vendor/google/protobuf/json_format.py    |  1247 --
 .../google/protobuf/json_options_pb2.py       |    37 -
 .../agent/_vendor/google/protobuf/message.py  |   467 -
 .../google/protobuf/message_factory.py        |   188 -
 .../agent/_vendor/google/protobuf/proto.py    |   153 -
 .../_vendor/google/protobuf/proto_builder.py  |   117 -
 .../_vendor/google/protobuf/proto_json.py     |    81 -
 .../_vendor/google/protobuf/proto_text.py     |   118 -
 .../_vendor/google/protobuf/pyext/__init__.py |     0
 .../google/protobuf/pyext/cpp_message.py      |    46 -
 .../_vendor/google/protobuf/reflection.py     |    36 -
 .../google/protobuf/runtime_version.py        |   105 -
 .../google/protobuf/service_reflection.py     |   284 -
 .../google/protobuf/source_context_pb2.py     |    37 -
 .../_vendor/google/protobuf/struct_pb2.py     |    47 -
 .../google/protobuf/symbol_database.py        |   178 -
 .../_vendor/google/protobuf/text_encoding.py  |   111 -
 .../_vendor/google/protobuf/text_format.py    |  2089 --
 .../_vendor/google/protobuf/timestamp.py      |   112 -
 .../_vendor/google/protobuf/timestamp_pb2.py  |    37 -
 .../agent/_vendor/google/protobuf/type_pb2.py |    53 -
 .../_vendor/google/protobuf/unknown_fields.py |    93 -
 .../_vendor/google/protobuf/util/__init__.py  |     0
 .../_vendor/google/protobuf/wrappers_pb2.py   |    53 -
 .../agent/_vendor/google/rpc/code.proto       |   186 -
 .../agent/_vendor/google/rpc/code_pb2.py      |    51 -
 .../agent/_vendor/google/rpc/code_pb2.pyi     |    58 -
 .../rpc/context/attribute_context.proto       |   350 -
 .../rpc/context/attribute_context_pb2.py      |    97 -
 .../rpc/context/attribute_context_pb2.pyi     |   326 -
 .../google/rpc/context/audit_context.proto    |    48 -
 .../google/rpc/context/audit_context_pb2.py   |    60 -
 .../google/rpc/context/audit_context_pb2.pyi  |    51 -
 .../_vendor/google/rpc/error_details.proto    |   363 -
 .../_vendor/google/rpc/error_details_pb2.py   |    91 -
 .../_vendor/google/rpc/error_details_pb2.pyi  |   250 -
 .../agent/_vendor/google/rpc/http.proto       |    64 -
 .../agent/_vendor/google/rpc/http_pb2.py      |    55 -
 .../agent/_vendor/google/rpc/http_pb2.pyi     |    71 -
 .../agent/_vendor/google/rpc/status.proto     |    48 -
 .../agent/_vendor/google/rpc/status_pb2.py    |    53 -
 .../agent/_vendor/google/rpc/status_pb2.pyi   |    41 -
 .../_vendor/google/type/calendar_period.proto |    56 -
 .../google/type/calendar_period_pb2.py        |    53 -
 .../google/type/calendar_period_pb2.pyi       |    40 -
 .../agent/_vendor/google/type/color.proto     |   173 -
 .../agent/_vendor/google/type/color_pb2.py    |    53 -
 .../agent/_vendor/google/type/color_pb2.pyi   |    42 -
 .../agent/_vendor/google/type/date.proto      |    54 -
 .../agent/_vendor/google/type/date_pb2.py     |    51 -
 .../agent/_vendor/google/type/date_pb2.pyi    |    36 -
 .../agent/_vendor/google/type/datetime.proto  |   104 -
 .../agent/_vendor/google/type/datetime_pb2.py |    57 -
 .../_vendor/google/type/datetime_pb2.pyi      |    80 -
 .../agent/_vendor/google/type/dayofweek.proto |    50 -
 .../_vendor/google/type/dayofweek_pb2.py      |    53 -
 .../_vendor/google/type/dayofweek_pb2.pyi     |    40 -
 .../agent/_vendor/google/type/decimal.proto   |    93 -
 .../agent/_vendor/google/type/decimal_pb2.py  |    51 -
 .../agent/_vendor/google/type/decimal_pb2.pyi |    27 -
 .../agent/_vendor/google/type/expr.proto      |    73 -
 .../agent/_vendor/google/type/expr_pb2.py     |    51 -
 .../agent/_vendor/google/type/expr_pb2.pyi    |    39 -
 .../agent/_vendor/google/type/fraction.proto  |    33 -
 .../agent/_vendor/google/type/fraction_pb2.py |    53 -
 .../_vendor/google/type/fraction_pb2.pyi      |    31 -
 .../agent/_vendor/google/type/interval.proto  |    45 -
 .../agent/_vendor/google/type/interval_pb2.py |    55 -
 .../_vendor/google/type/interval_pb2.pyi      |    41 -
 .../agent/_vendor/google/type/latlng.proto    |    36 -
 .../agent/_vendor/google/type/latlng_pb2.py   |    51 -
 .../agent/_vendor/google/type/latlng_pb2.pyi  |    31 -
 .../_vendor/google/type/localized_text.proto  |    36 -
 .../_vendor/google/type/localized_text_pb2.py |    53 -
 .../google/type/localized_text_pb2.pyi        |    31 -
 .../agent/_vendor/google/type/money.proto     |    41 -
 .../agent/_vendor/google/type/money_pb2.py    |    51 -
 .../agent/_vendor/google/type/money_pb2.pyi   |    36 -
 .../agent/_vendor/google/type/month.proto     |    65 -
 .../agent/_vendor/google/type/month_pb2.py    |    51 -
 .../agent/_vendor/google/type/month_pb2.pyi   |    50 -
 .../_vendor/google/type/phone_number.proto    |   118 -
 .../_vendor/google/type/phone_number_pb2.py   |    55 -
 .../_vendor/google/type/phone_number_pb2.pyi  |    48 -
 .../_vendor/google/type/postal_address.proto  |   134 -
 .../_vendor/google/type/postal_address_pb2.py |    53 -
 .../google/type/postal_address_pb2.pyi        |    74 -
 .../_vendor/google/type/quaternion.proto      |    94 -
 .../_vendor/google/type/quaternion_pb2.py     |    53 -
 .../_vendor/google/type/quaternion_pb2.pyi    |    39 -
 .../agent/_vendor/google/type/timeofday.proto |    47 -
 .../_vendor/google/type/timeofday_pb2.py      |    53 -
 .../_vendor/google/type/timeofday_pb2.pyi     |    39 -
 .../_vendor/googleapis-common-protos.LICENSE  |   202 -
 .../agent/_vendor/idna.LICENSE.md             |    31 -
 .../agent/_vendor/idna/__init__.py            |    47 -
 .../opentelemetry/agent/_vendor/idna/codec.py |   225 -
 .../agent/_vendor/idna/compat.py              |    43 -
 .../opentelemetry/agent/_vendor/idna/core.py  |   863 -
 .../agent/_vendor/idna/idnadata.py            |  1933 --
 .../agent/_vendor/idna/intranges.py           |    55 -
 .../agent/_vendor/idna/package_data.py        |     1 -
 .../agent/_vendor/idna/uts46data.py           | 17117 ----------------
 .../agent/_vendor/opentelemetry-api.LICENSE   |   201 -
 .../opentelemetry-configuration.LICENSE       |   201 -
 .../_vendor/opentelemetry-distro.LICENSE      |   201 -
 ...ntelemetry-exporter-http-transport.LICENSE |   201 -
 ...opentelemetry-exporter-otlp-common.LICENSE |   201 -
 ...elemetry-exporter-otlp-json-common.LICENSE |   201 -
 ...ntelemetry-exporter-otlp-json-file.LICENSE |   201 -
 ...ntelemetry-exporter-otlp-json-http.LICENSE |   201 -
 ...lemetry-exporter-otlp-proto-common.LICENSE |   201 -
 ...telemetry-exporter-otlp-proto-http.LICENSE |   201 -
 .../opentelemetry-exporter-prometheus.LICENSE |   201 -
 ...try-instrumentation-aiohttp-client.LICENSE |   201 -
 .../opentelemetry-instrumentation.LICENSE     |   201 -
 .../opentelemetry-propagator-b3.LICENSE       |   201 -
 .../_vendor/opentelemetry-proto-json.LICENSE  |   201 -
 .../agent/_vendor/opentelemetry-proto.LICENSE |   201 -
 .../agent/_vendor/opentelemetry-sdk.LICENSE   |   201 -
 ...opentelemetry-semantic-conventions.LICENSE |   201 -
 .../_vendor/opentelemetry-util-http.LICENSE   |   201 -
 .../_vendor/opentelemetry/_logs/__init__.py   |    47 -
 .../opentelemetry/_logs/_internal/__init__.py |   484 -
 .../opentelemetry/_logs/severity/__init__.py  |    44 -
 .../opentelemetry/attributes/__init__.py      |   243 -
 .../_vendor/opentelemetry/baggage/__init__.py |   122 -
 .../baggage/propagation/__init__.py           |   179 -
 .../opentelemetry/configuration/README.md     |    30 -
 .../opentelemetry/configuration/__init__.py   |    44 -
 .../opentelemetry/configuration/_common.py    |   228 -
 .../configuration/_conversion.py              |   137 -
 .../configuration/_exceptions.py              |    53 -
 .../configuration/_logger_provider.py         |   386 -
 .../configuration/_meter_provider.py          |   656 -
 .../configuration/_propagator.py              |   102 -
 .../opentelemetry/configuration/_resource.py  |   219 -
 .../opentelemetry/configuration/_sdk.py       |   108 -
 .../configuration/_tracer_provider.py         |   524 -
 .../configuration/file/__init__.py            |    58 -
 .../configuration/file/_env_substitution.py   |    82 -
 .../configuration/file/_loader.py             |   376 -
 .../configuration/instrumentation.py          |    73 -
 .../opentelemetry/configuration/models.py     |   803 -
 .../opentelemetry/configuration/schema.json   |  2576 ---
 .../configuration/version/__init__.py         |     4 -
 .../_vendor/opentelemetry/context/__init__.py |   147 -
 .../_vendor/opentelemetry/context/context.py  |    65 -
 .../context/contextvars_context.py            |    43 -
 .../_vendor/opentelemetry/distro/__init__.py  |    32 -
 .../_vendor/opentelemetry/distro/version.py   |     4 -
 .../environment_variables/__init__.py         |    72 -
 .../exporter/http/transport/__init__.py       |    73 -
 .../exporter/http/transport/_base.py          |    91 -
 .../exporter/http/transport/_requests.py      |   118 -
 .../exporter/http/transport/_urllib3.py       |   133 -
 .../http/transport/version/__init__.py        |     4 -
 .../exporter/otlp/common/__init__.py          |     2 -
 .../exporter/otlp/common/_aggregation.py      |   112 -
 .../exporter/otlp/common/_exporter_metrics.py |   152 -
 .../exporter/otlp/common/http.py              |   248 -
 .../exporter/otlp/common/version/__init__.py  |     4 -
 .../exporter/otlp/json/common/__init__.py     |     2 -
 .../otlp/json/common/_internal/__init__.py    |    98 -
 .../common/_internal/_log_encoder/__init__.py |    89 -
 .../_internal/metrics_encoder/__init__.py     |   372 -
 .../_internal/trace_encoder/__init__.py       |   159 -
 .../exporter/otlp/json/common/_log_encoder.py |     8 -
 .../otlp/json/common/metrics_encoder.py       |     8 -
 .../otlp/json/common/trace_encoder.py         |     8 -
 .../otlp/json/common/version/__init__.py      |     4 -
 .../exporter/otlp/json/file/__init__.py       |    73 -
 .../exporter/otlp/json/file/_internal.py      |    80 -
 .../exporter/otlp/json/file/_log_exporter.py  |    70 -
 .../otlp/json/file/metric_exporter.py         |    94 -
 .../exporter/otlp/json/file/trace_exporter.py |    64 -
 .../otlp/json/file/version/__init__.py        |     4 -
 .../exporter/otlp/json/http/__init__.py       |    79 -
 .../exporter/otlp/json/http/_internal.py      |   137 -
 .../exporter/otlp/json/http/_log_exporter.py  |   134 -
 .../otlp/json/http/metric_exporter.py         |   165 -
 .../exporter/otlp/json/http/trace_exporter.py |   128 -
 .../otlp/json/http/version/__init__.py        |     4 -
 .../exporter/otlp/proto/common/__init__.py    |     7 -
 .../otlp/proto/common/_internal/__init__.py   |   121 -
 .../common/_internal/_log_encoder/__init__.py |    87 -
 .../_internal/metrics_encoder/__init__.py     |   348 -
 .../_internal/trace_encoder/__init__.py       |   175 -
 .../otlp/proto/common/_log_encoder.py         |     9 -
 .../otlp/proto/common/metrics_encoder.py      |     9 -
 .../otlp/proto/common/trace_encoder.py        |     9 -
 .../otlp/proto/common/version/__init__.py     |     4 -
 .../exporter/otlp/proto/http/__init__.py      |    75 -
 .../otlp/proto/http/_common/__init__.py       |   211 -
 .../otlp/proto/http/_log_exporter/__init__.py |   223 -
 .../proto/http/metric_exporter/__init__.py    |   611 -
 .../proto/http/trace_exporter/__init__.py     |   219 -
 .../http/trace_exporter/encoder/__init__.py   |    55 -
 .../otlp/proto/http/version/__init__.py       |     4 -
 .../exporter/prometheus/__init__.py           |   523 -
 .../exporter/prometheus/_mapping.py           |   126 -
 .../exporter/prometheus/version/__init__.py   |     4 -
 .../instrumentation/_labeler/__init__.py      |    88 -
 .../_labeler/_internal/__init__.py            |   250 -
 .../opentelemetry/instrumentation/_semconv.py |   725 -
 .../aiohttp_client/__init__.py                |   721 -
 .../instrumentation/aiohttp_client/package.py |     9 -
 .../instrumentation/aiohttp_client/version.py |     4 -
 .../auto_instrumentation/__init__.py          |   168 -
 .../auto_instrumentation/_load.py             |   153 -
 .../auto_instrumentation/sitecustomize.py     |     6 -
 .../instrumentation/bootstrap.py              |   166 -
 .../instrumentation/bootstrap_gen.py          |    70 -
 .../opentelemetry/instrumentation/cidict.py   |    71 -
 .../instrumentation/dependencies.py           |   209 -
 .../opentelemetry/instrumentation/distro.py   |    59 -
 .../instrumentation/environment_variables.py  |    32 -
 .../instrumentation/instrumentor.py           |   136 -
 .../instrumentation/log_utils.py              |    65 -
 .../instrumentation/propagators.py            |   113 -
 .../instrumentation/sqlcommenter_utils.py     |    92 -
 .../opentelemetry/instrumentation/utils.py    |   214 -
 .../opentelemetry/instrumentation/version.py  |     4 -
 .../_vendor/opentelemetry/metrics/__init__.py |   121 -
 .../metrics/_internal/__init__.py             |   892 -
 .../metrics/_internal/instrument.py           |   540 -
 .../metrics/_internal/observation.py          |    51 -
 .../opentelemetry/propagate/__init__.py       |   171 -
 .../opentelemetry/propagators/_envcarrier.py  |    94 -
 .../opentelemetry/propagators/b3/__init__.py  |   182 -
 .../propagators/b3/version/__init__.py        |     4 -
 .../opentelemetry/propagators/composite.py    |    78 -
 .../opentelemetry/propagators/textmap.py      |   181 -
 .../_vendor/opentelemetry/proto/__init__.py   |     0
 .../opentelemetry/proto/collector/__init__.py |     0
 .../collector/logs/v1/logs_service_pb2.py     |    34 -
 .../collector/logs/v1/logs_service_pb2.pyi    |   117 -
 .../proto/collector/metrics/__init__.py       |     0
 .../proto/collector/metrics/v1/__init__.py    |     0
 .../metrics/v1/metrics_service_pb2.py         |    34 -
 .../metrics/v1/metrics_service_pb2.pyi        |   117 -
 .../v1development/profiles_service_pb2.py     |    34 -
 .../v1development/profiles_service_pb2.pyi    |   123 -
 .../proto/collector/trace/__init__.py         |     0
 .../proto/collector/trace/v1/__init__.py      |     0
 .../collector/trace/v1/trace_service_pb2.py   |    34 -
 .../collector/trace/v1/trace_service_pb2.pyi  |   117 -
 .../opentelemetry/proto/common/__init__.py    |     0
 .../opentelemetry/proto/common/v1/__init__.py |     0
 .../proto/common/v1/common_pb2.py             |    37 -
 .../proto/common/v1/common_pb2.pyi            |   280 -
 .../opentelemetry/proto/logs/v1/logs_pb2.py   |    39 -
 .../opentelemetry/proto/logs/v1/logs_pb2.pyi  |   365 -
 .../opentelemetry/proto/metrics/__init__.py   |     0
 .../proto/metrics/v1/__init__.py              |     0
 .../proto/metrics/v1/metrics_pb2.py           |    63 -
 .../proto/metrics/v1/metrics_pb2.pyi          |  1177 --
 .../profiles/v1development/profiles_pb2.py    |    55 -
 .../profiles/v1development/profiles_pb2.pyi   |   800 -
 .../opentelemetry/proto/resource/__init__.py  |     0
 .../proto/resource/v1/__init__.py             |     0
 .../proto/resource/v1/resource_pb2.py         |    28 -
 .../proto/resource/v1/resource_pb2.pyi        |    70 -
 .../opentelemetry/proto/trace/__init__.py     |     0
 .../opentelemetry/proto/trace/v1/__init__.py  |     0
 .../opentelemetry/proto/trace/v1/trace_pb2.py |    47 -
 .../proto/trace/v1/trace_pb2.pyi              |   586 -
 .../opentelemetry/proto/version/__init__.py   |     4 -
 .../opentelemetry/proto_json/__init__.py      |     0
 .../opentelemetry/proto_json/_json_codec.py   |   250 -
 .../proto_json/collector/__init__.py          |     0
 .../proto_json/collector/logs/__init__.py     |     0
 .../proto_json/collector/logs/v1/__init__.py  |     0
 .../collector/logs/v1/logs_service.py         |   148 -
 .../proto_json/collector/metrics/__init__.py  |     0
 .../collector/metrics/v1/__init__.py          |     0
 .../collector/metrics/v1/metrics_service.py   |   148 -
 .../proto_json/collector/profiles/__init__.py |     0
 .../profiles/v1development/__init__.py        |     0
 .../v1development/profiles_service.py         |   153 -
 .../proto_json/collector/trace/__init__.py    |     0
 .../proto_json/collector/trace/v1/__init__.py |     0
 .../collector/trace/v1/trace_service.py       |   148 -
 .../proto_json/common/__init__.py             |     0
 .../proto_json/common/v1/__init__.py          |     0
 .../proto_json/common/v1/common.py            |   348 -
 .../opentelemetry/proto_json/logs/__init__.py |     0
 .../proto_json/logs/v1/__init__.py            |     0
 .../opentelemetry/proto_json/logs/v1/logs.py  |   304 -
 .../proto_json/metrics/__init__.py            |     0
 .../proto_json/metrics/v1/__init__.py         |     0
 .../proto_json/metrics/v1/metrics.py          |  1000 -
 .../proto_json/profiles/__init__.py           |     0
 .../profiles/v1development/__init__.py        |     0
 .../profiles/v1development/profiles.py        |   816 -
 .../proto_json/resource/__init__.py           |     0
 .../proto_json/resource/v1/__init__.py        |     0
 .../proto_json/resource/v1/resource.py        |    71 -
 .../proto_json/trace/__init__.py              |     0
 .../proto_json/trace/v1/__init__.py           |     0
 .../proto_json/trace/v1/trace.py              |   497 -
 .../proto_json/version/__init__.py            |     4 -
 .../_vendor/opentelemetry/sdk/__init__.pyi    |    18 -
 .../sdk/_configuration/__init__.py            |   676 -
 .../opentelemetry/sdk/_logs/__init__.py       |    32 -
 .../sdk/_logs/_internal/__init__.py           |  1092 -
 .../sdk/_logs/_internal/_exceptions.py        |   114 -
 .../sdk/_logs/_internal/_logger_metrics.py    |    37 -
 .../sdk/_logs/_internal/export/__init__.py    |   392 -
 .../export/in_memory_log_exporter.py          |    53 -
 .../sdk/_logs/export/__init__.py              |    32 -
 .../sdk/_shared_internal/__init__.py          |   237 -
 .../_shared_internal/_processor_metrics.py    |   140 -
 .../sdk/environment_variables/__init__.py     |   863 -
 .../sdk/environment_variables/_internal.py    |    26 -
 .../sdk/error_handler/__init__.py             |   128 -
 .../opentelemetry/sdk/metrics/__init__.py     |    49 -
 .../sdk/metrics/_internal/__init__.py         |   660 -
 .../_internal/_view_instrument_match.py       |   217 -
 .../sdk/metrics/_internal/aggregation.py      |  1354 --
 .../sdk/metrics/_internal/exceptions.py       |     6 -
 .../metrics/_internal/exemplar/__init__.py    |    28 -
 .../metrics/_internal/exemplar/exemplar.py    |    33 -
 .../_internal/exemplar/exemplar_filter.py     |   120 -
 .../_internal/exemplar/exemplar_reservoir.py  |   291 -
 .../exponential_histogram/__init__.py         |     0
 .../exponential_histogram/buckets.py          |   177 -
 .../exponential_histogram/mapping/__init__.py |    94 -
 .../exponential_histogram/mapping/errors.py   |    15 -
 .../mapping/exponent_mapping.py               |   145 -
 .../exponential_histogram/mapping/ieee_754.md |   175 -
 .../exponential_histogram/mapping/ieee_754.py |   106 -
 .../mapping/logarithm_mapping.py              |   123 -
 .../sdk/metrics/_internal/export/__init__.py  |   608 -
 .../export/_metric_reader_metrics.py          |    54 -
 .../sdk/metrics/_internal/instrument.py       |   400 -
 .../sdk/metrics/_internal/measurement.py      |    54 -
 .../metrics/_internal/measurement_consumer.py |   145 -
 .../_internal/metric_reader_storage.py        |   285 -
 .../sdk/metrics/_internal/point.py            |   240 -
 .../metrics/_internal/sdk_configuration.py    |    20 -
 .../sdk/metrics/_internal/view.py             |   194 -
 .../sdk/metrics/export/__init__.py            |    61 -
 .../sdk/metrics/view/__init__.py              |    24 -
 .../opentelemetry/sdk/resources/__init__.py   |   776 -
 .../opentelemetry/sdk/trace/__init__.py       |  1426 --
 .../trace/_sampling_experimental/__init__.py  |    22 -
 .../_sampling_experimental/_always_off.py     |    44 -
 .../_sampling_experimental/_always_on.py      |    44 -
 .../_sampling_experimental/_composable.py     |    49 -
 .../_parent_threshold.py                      |    72 -
 .../_sampling_experimental/_rule_based.py     |   271 -
 .../trace/_sampling_experimental/_sampler.py  |    88 -
 .../_sampling_experimental/_trace_state.py    |   121 -
 .../_sampling_experimental/_traceid_ratio.py  |    67 -
 .../sdk/trace/_sampling_experimental/_util.py |    23 -
 .../sdk/trace/_tracer_metrics.py              |   103 -
 .../sdk/trace/export/__init__.py              |   316 -
 .../trace/export/in_memory_span_exporter.py   |    56 -
 .../opentelemetry/sdk/trace/id_generator.py   |    72 -
 .../opentelemetry/sdk/trace/sampling.py       |   488 -
 .../opentelemetry/sdk/util/__init__.py        |   140 -
 .../opentelemetry/sdk/util/__init__.pyi       |    76 -
 .../opentelemetry/sdk/util/_configurator.py   |    28 -
 .../opentelemetry/sdk/util/instrumentation.py |   191 -
 .../opentelemetry/sdk/version/__init__.py     |     4 -
 .../_vendor/opentelemetry/semconv/__init__.py |     0
 .../_incubating/attributes/app_attributes.py  |    90 -
 .../attributes/artifact_attributes.py         |    51 -
 .../_incubating/attributes/aws_attributes.py  |   316 -
 .../_incubating/attributes/az_attributes.py   |    14 -
 .../attributes/azure_attributes.py            |    76 -
 .../attributes/browser_attributes.py          |   104 -
 .../attributes/cassandra_attributes.py        |    60 -
 .../_incubating/attributes/cicd_attributes.py |   152 -
 .../attributes/client_attributes.py           |    14 -
 .../attributes/cloud_attributes.py            |   156 -
 .../attributes/cloudevents_attributes.py      |    29 -
 .../attributes/cloudfoundry_attributes.py     |   107 -
 .../_incubating/attributes/code_attributes.py |    54 -
 .../attributes/container_attributes.py        |   114 -
 .../_incubating/attributes/cpu_attributes.py  |    34 -
 .../attributes/cpython_attributes.py          |    19 -
 .../_incubating/attributes/db_attributes.py   |   574 -
 .../attributes/deployment_attributes.py       |    53 -
 .../attributes/destination_attributes.py      |    15 -
 .../attributes/device_attributes.py           |    43 -
 .../_incubating/attributes/disk_attributes.py |    17 -
 .../_incubating/attributes/dns_attributes.py  |    15 -
 .../attributes/elasticsearch_attributes.py    |     9 -
 .../attributes/enduser_attributes.py          |    32 -
 .../attributes/error_attributes.py            |    25 -
 .../attributes/event_attributes.py            |     9 -
 .../attributes/exception_attributes.py        |    24 -
 .../_incubating/attributes/faas_attributes.py |   150 -
 .../attributes/feature_flag_attributes.py     |   119 -
 .../_incubating/attributes/file_attributes.py |   125 -
 .../_incubating/attributes/gcp_attributes.py  |   234 -
 .../attributes/gen_ai_attributes.py           |   459 -
 .../_incubating/attributes/geo_attributes.py  |    57 -
 .../attributes/graphql_attributes.py          |    30 -
 .../attributes/heroku_attributes.py           |    19 -
 .../_incubating/attributes/host_attributes.py |   102 -
 .../_incubating/attributes/http_attributes.py |   190 -
 .../_incubating/attributes/hw_attributes.py   |   243 -
 .../attributes/jsonrpc_attributes.py          |    16 -
 .../_incubating/attributes/k8s_attributes.py  |   721 -
 .../attributes/linux_attributes.py            |    20 -
 .../_incubating/attributes/log_attributes.py  |    50 -
 .../attributes/mainframe_attributes.py        |     9 -
 .../_incubating/attributes/mcp_attributes.py  |    83 -
 .../attributes/message_attributes.py          |    35 -
 .../attributes/messaging_attributes.py        |   327 -
 .../_incubating/attributes/net_attributes.py  |   106 -
 .../attributes/network_attributes.py          |   209 -
 .../_incubating/attributes/nfs_attributes.py  |    14 -
 .../_incubating/attributes/oci_attributes.py  |    11 -
 .../attributes/onc_rpc_attributes.py          |    24 -
 .../attributes/openai_attributes.py           |    47 -
 .../attributes/openshift_attributes.py        |    14 -
 .../attributes/opentracing_attributes.py      |    18 -
 .../attributes/oracle_attributes.py           |    47 -
 .../attributes/oracle_cloud_attributes.py     |    10 -
 .../_incubating/attributes/os_attributes.py   |    57 -
 .../_incubating/attributes/otel_attributes.py |   145 -
 .../attributes/other_attributes.py            |    20 -
 .../_incubating/attributes/peer_attributes.py |     9 -
 .../_incubating/attributes/pool_attributes.py |     9 -
 .../attributes/pprof_attributes.py            |    62 -
 .../attributes/process_attributes.py          |   253 -
 .../attributes/profile_attributes.py          |    39 -
 .../_incubating/attributes/rpc_attributes.py  |   264 -
 .../attributes/security_rule_attributes.py    |    45 -
 .../attributes/server_attributes.py           |    14 -
 .../attributes/service_attributes.py          |    52 -
 .../attributes/session_attributes.py          |    14 -
 .../attributes/source_attributes.py           |    15 -
 .../attributes/system_attributes.py           |   242 -
 .../attributes/telemetry_attributes.py        |    64 -
 .../_incubating/attributes/test_attributes.py |    47 -
 .../attributes/thread_attributes.py           |    33 -
 .../_incubating/attributes/tls_attributes.py  |   158 -
 .../_incubating/attributes/url_attributes.py  |    76 -
 .../attributes/user_agent_attributes.py       |    47 -
 .../_incubating/attributes/user_attributes.py |    35 -
 .../_incubating/attributes/vcs_attributes.py  |   218 -
 .../attributes/webengine_attributes.py        |    19 -
 .../_incubating/attributes/zos_attributes.py  |    14 -
 .../_incubating/metrics/azure_metrics.py      |    40 -
 .../_incubating/metrics/cicd_metrics.py       |    94 -
 .../_incubating/metrics/container_metrics.py  |   281 -
 .../_incubating/metrics/cpu_metrics.py        |    58 -
 .../_incubating/metrics/cpython_metrics.py    |    60 -
 .../semconv/_incubating/metrics/db_metrics.py |   356 -
 .../_incubating/metrics/dns_metrics.py        |    23 -
 .../_incubating/metrics/faas_metrics.py       |   159 -
 .../_incubating/metrics/gen_ai_metrics.py     |   111 -
 .../_incubating/metrics/http_metrics.py       |   176 -
 .../semconv/_incubating/metrics/hw_metrics.py |   755 -
 .../_incubating/metrics/k8s_metrics.py        |  2952 ---
 .../_incubating/metrics/mcp_metrics.py        |    66 -
 .../_incubating/metrics/messaging_metrics.py  |   169 -
 .../_incubating/metrics/nfs_metrics.py        |   290 -
 .../_incubating/metrics/openshift_metrics.py  |   442 -
 .../_incubating/metrics/otel_metrics.py       |   443 -
 .../_incubating/metrics/process_metrics.py    |   286 -
 .../_incubating/metrics/rpc_metrics.py        |   194 -
 .../_incubating/metrics/system_metrics.py     |   835 -
 .../_incubating/metrics/vcs_metrics.py        |   193 -
 .../semconv/attributes/__init__.py            |     0
 .../semconv/attributes/client_attributes.py   |    16 -
 .../semconv/attributes/code_attributes.py     |    44 -
 .../attributes/container_attributes.py        |    25 -
 .../semconv/attributes/db_attributes.py       |   134 -
 .../attributes/deployment_attributes.py       |    28 -
 .../semconv/attributes/error_attributes.py    |    40 -
 .../attributes/exception_attributes.py        |    32 -
 .../semconv/attributes/http_attributes.py     |   127 -
 .../semconv/attributes/k8s_attributes.py      |   362 -
 .../semconv/attributes/network_attributes.py  |    73 -
 .../semconv/attributes/otel_attributes.py     |    38 -
 .../semconv/attributes/server_attributes.py   |    16 -
 .../semconv/attributes/service_attributes.py  |    53 -
 .../attributes/telemetry_attributes.py        |    67 -
 .../semconv/attributes/url_attributes.py      |    88 -
 .../attributes/user_agent_attributes.py       |     9 -
 .../opentelemetry/semconv/metrics/__init__.py |   191 -
 .../semconv/metrics/db_metrics.py             |    13 -
 .../semconv/metrics/http_metrics.py           |    20 -
 .../semconv/resource/__init__.py              |   875 -
 .../_vendor/opentelemetry/semconv/schemas.py  |   118 -
 .../opentelemetry/semconv/trace/__init__.py   |  2164 --
 .../opentelemetry/semconv/version/__init__.py |     4 -
 .../_vendor/opentelemetry/trace/__init__.py   |   661 -
 .../trace/propagation/__init__.py             |    37 -
 .../trace/propagation/tracecontext.py         |   126 -
 .../agent/_vendor/opentelemetry/trace/span.py |   616 -
 .../_vendor/opentelemetry/trace/status.py     |    68 -
 .../_vendor/opentelemetry/util/_decorator.py  |    75 -
 .../opentelemetry/util/_importlib_metadata.py |    58 -
 .../agent/_vendor/opentelemetry/util/_once.py |    36 -
 .../_vendor/opentelemetry/util/_providers.py  |    42 -
 .../opentelemetry/util/http/__init__.py       |   351 -
 .../opentelemetry/util/http/constants.py      |    23 -
 .../opentelemetry/util/http/httplib.py        |   186 -
 .../opentelemetry/util/http/version.py        |     4 -
 .../agent/_vendor/opentelemetry/util/re.py    |    93 -
 .../agent/_vendor/opentelemetry/util/types.py |    28 -
 .../_vendor/opentelemetry/version/__init__.py |     4 -
 .../agent/_vendor/packaging.LICENSE           |     3 -
 .../agent/_vendor/packaging.LICENSE.APACHE    |   177 -
 .../agent/_vendor/packaging.LICENSE.BSD       |    23 -
 .../agent/_vendor/packaging/__init__.py       |    15 -
 .../agent/_vendor/packaging/_elffile.py       |   108 -
 .../agent/_vendor/packaging/_manylinux.py     |   278 -
 .../agent/_vendor/packaging/_musllinux.py     |    88 -
 .../agent/_vendor/packaging/_parser.py        |   418 -
 .../agent/_vendor/packaging/_ranges.py        |   836 -
 .../agent/_vendor/packaging/_structures.py    |    33 -
 .../agent/_vendor/packaging/_tokenizer.py     |   200 -
 .../_vendor/packaging/dependency_groups.py    |   335 -
 .../agent/_vendor/packaging/direct_url.py     |   349 -
 .../agent/_vendor/packaging/errors.py         |    94 -
 .../_vendor/packaging/licenses/__init__.py    |   198 -
 .../agent/_vendor/packaging/licenses/_spdx.py |   799 -
 .../agent/_vendor/packaging/markers.py        |   576 -
 .../agent/_vendor/packaging/metadata.py       |  1054 -
 .../agent/_vendor/packaging/pylock.py         |   943 -
 .../agent/_vendor/packaging/ranges.py         |  2067 --
 .../agent/_vendor/packaging/requirements.py   |   192 -
 .../agent/_vendor/packaging/specifiers.py     |  1457 --
 .../agent/_vendor/packaging/tags.py           |  1053 -
 .../agent/_vendor/packaging/utils.py          |   370 -
 .../agent/_vendor/packaging/version.py        |  1252 --
 .../agent/_vendor/prometheus-client.LICENSE   |   201 -
 .../agent/_vendor/prometheus-client.NOTICE    |     5 -
 .../_vendor/prometheus_client/__init__.py     |    75 -
 .../agent/_vendor/prometheus_client/asgi.py   |    40 -
 .../prometheus_client/bridge/__init__.py      |     0
 .../prometheus_client/bridge/graphite.py      |    94 -
 .../prometheus_client/context_managers.py     |    83 -
 .../agent/_vendor/prometheus_client/core.py   |    35 -
 .../_vendor/prometheus_client/decorator.py    |   427 -
 .../_vendor/prometheus_client/exposition.py   |   828 -
 .../_vendor/prometheus_client/gc_collector.py |    45 -
 .../_vendor/prometheus_client/metrics.py      |   804 -
 .../_vendor/prometheus_client/metrics_core.py |   415 -
 .../_vendor/prometheus_client/mmap_dict.py    |   145 -
 .../_vendor/prometheus_client/multiprocess.py |   183 -
 .../prometheus_client/openmetrics/__init__.py |     0
 .../openmetrics/exposition.py                 |   287 -
 .../prometheus_client/openmetrics/parser.py   |   653 -
 .../agent/_vendor/prometheus_client/parser.py |   370 -
 .../prometheus_client/platform_collector.py   |    59 -
 .../prometheus_client/process_collector.py    |   101 -
 .../_vendor/prometheus_client/registry.py     |   178 -
 .../_vendor/prometheus_client/samples.py      |    74 -
 .../agent/_vendor/prometheus_client/utils.py  |    36 -
 .../_vendor/prometheus_client/validation.py   |   124 -
 .../agent/_vendor/prometheus_client/values.py |   163 -
 .../agent/_vendor/protobuf.LICENSE            |    32 -
 .../agent/_vendor/requests.LICENSE            |   175 -
 .../agent/_vendor/requests.NOTICE             |     2 -
 .../agent/_vendor/requests/__init__.py        |   217 -
 .../agent/_vendor/requests/__version__.py     |    14 -
 .../agent/_vendor/requests/_internal_utils.py |    51 -
 .../agent/_vendor/requests/_types.py          |   183 -
 .../agent/_vendor/requests/adapters.py        |   748 -
 .../agent/_vendor/requests/api.py             |   180 -
 .../agent/_vendor/requests/auth.py            |   354 -
 .../agent/_vendor/requests/certs.py           |    18 -
 .../agent/_vendor/requests/compat.py          |   102 -
 .../agent/_vendor/requests/cookies.py         |   625 -
 .../agent/_vendor/requests/exceptions.py      |   162 -
 .../agent/_vendor/requests/hooks.py           |    48 -
 .../agent/_vendor/requests/models.py          |  1180 --
 .../agent/_vendor/requests/packages.py        |     4 -
 .../agent/_vendor/requests/sessions.py        |   920 -
 .../agent/_vendor/requests/status_codes.py    |   128 -
 .../agent/_vendor/requests/structures.py      |   130 -
 .../agent/_vendor/requests/utils.py           |  1155 --
 .../agent/_vendor/ruamel-yaml.LICENSE         |    21 -
 .../agent/_vendor/ruamel/yaml/__init__.py     |    51 -
 .../agent/_vendor/ruamel/yaml/anchor.py       |    20 -
 .../agent/_vendor/ruamel/yaml/comments.py     |  1208 --
 .../agent/_vendor/ruamel/yaml/compat.py       |   236 -
 .../agent/_vendor/ruamel/yaml/composer.py     |   246 -
 .../_vendor/ruamel/yaml/configobjwalker.py    |    17 -
 .../agent/_vendor/ruamel/yaml/constructor.py  |  1724 --
 .../agent/_vendor/ruamel/yaml/docinfo.py      |   130 -
 .../agent/_vendor/ruamel/yaml/dumper.py       |   220 -
 .../agent/_vendor/ruamel/yaml/emitter.py      |  1802 --
 .../agent/_vendor/ruamel/yaml/error.py        |   328 -
 .../agent/_vendor/ruamel/yaml/events.py       |   266 -
 .../agent/_vendor/ruamel/yaml/loader.py       |    92 -
 .../agent/_vendor/ruamel/yaml/main.py         |  1519 --
 .../agent/_vendor/ruamel/yaml/mergevalue.py   |    39 -
 .../agent/_vendor/ruamel/yaml/nodes.py        |   149 -
 .../agent/_vendor/ruamel/yaml/parser.py       |   862 -
 .../agent/_vendor/ruamel/yaml/reader.py       |   277 -
 .../agent/_vendor/ruamel/yaml/representer.py  |  1139 -
 .../agent/_vendor/ruamel/yaml/resolver.py     |   392 -
 .../agent/_vendor/ruamel/yaml/scalarbool.py   |    43 -
 .../agent/_vendor/ruamel/yaml/scalarfloat.py  |   105 -
 .../agent/_vendor/ruamel/yaml/scalarint.py    |   124 -
 .../agent/_vendor/ruamel/yaml/scalarstring.py |   142 -
 .../agent/_vendor/ruamel/yaml/scanner.py      |  2390 ---
 .../agent/_vendor/ruamel/yaml/serializer.py   |   233 -
 .../agent/_vendor/ruamel/yaml/tag.py          |   126 -
 .../agent/_vendor/ruamel/yaml/timestamp.py    |    63 -
 .../agent/_vendor/ruamel/yaml/tokens.py       |   384 -
 .../agent/_vendor/ruamel/yaml/util.py         |   264 -
 .../agent/_vendor/typing-extensions.LICENSE   |   279 -
 .../agent/_vendor/typing_extensions.py        |  4422 ----
 .../agent/_vendor/urllib3.LICENSE.txt         |    21 -
 .../agent/_vendor/urllib3/__init__.py         |   211 -
 .../agent/_vendor/urllib3/_base_connection.py |   167 -
 .../agent/_vendor/urllib3/_collections.py     |   490 -
 .../agent/_vendor/urllib3/_request_methods.py |   278 -
 .../agent/_vendor/urllib3/_version.py         |    24 -
 .../agent/_vendor/urllib3/connection.py       |  1204 --
 .../agent/_vendor/urllib3/connectionpool.py   |  1211 --
 .../agent/_vendor/urllib3/contrib/__init__.py |     0
 .../agent/_vendor/urllib3/exceptions.py       |   335 -
 .../agent/_vendor/urllib3/fields.py           |   341 -
 .../agent/_vendor/urllib3/filepost.py         |    89 -
 .../agent/_vendor/urllib3/http2/__init__.py   |    53 -
 .../agent/_vendor/urllib3/http2/probe.py      |    87 -
 .../agent/_vendor/urllib3/poolmanager.py      |   677 -
 .../agent/_vendor/urllib3/response.py         |  1526 --
 .../agent/_vendor/urllib3/util/__init__.py    |    42 -
 .../agent/_vendor/urllib3/util/connection.py  |   137 -
 .../agent/_vendor/urllib3/util/proxy.py       |    43 -
 .../agent/_vendor/urllib3/util/request.py     |   299 -
 .../agent/_vendor/urllib3/util/response.py    |   101 -
 .../agent/_vendor/urllib3/util/retry.py       |   569 -
 .../agent/_vendor/urllib3/util/ssl_.py        |   481 -
 .../urllib3/util/ssl_match_hostname.py        |   153 -
 .../_vendor/urllib3/util/ssltransport.py      |   271 -
 .../agent/_vendor/urllib3/util/timeout.py     |   275 -
 .../agent/_vendor/urllib3/util/url.py         |   577 -
 .../agent/_vendor/urllib3/util/util.py        |    42 -
 .../agent/_vendor/urllib3/util/wait.py        |   124 -
 .../agent/_vendor/wrapt-stubs/__init__.pyi    |   841 -
 .../opentelemetry/agent/_vendor/wrapt.LICENSE |    24 -
 .../agent/_vendor/wrapt/__init__.py           |   130 -
 .../agent/_vendor/wrapt/__wrapt__.py          |    42 -
 .../agent/_vendor/wrapt/_wrappers.c           |  5892 ------
 .../agent/_vendor/wrapt/arguments.py          |    55 -
 .../agent/_vendor/wrapt/caching.py            |   234 -
 .../agent/_vendor/wrapt/decorators.py         |   488 -
 .../opentelemetry/agent/_vendor/wrapt/doc.py  |   128 -
 .../agent/_vendor/wrapt/exceptions.py         |    69 -
 .../agent/_vendor/wrapt/importer.py           |   314 -
 .../agent/_vendor/wrapt/patches.py            |   851 -
 .../agent/_vendor/wrapt/proxies.py            |   386 -
 .../agent/_vendor/wrapt/signature.py          |   270 -
 .../agent/_vendor/wrapt/synchronization.py    |   540 -
 .../agent/_vendor/wrapt/weakrefs.py           |   170 -
 .../agent/_vendor/wrapt/wrappers.py           |  1287 --
 .../tests/requirements.latest.txt             |     5 +
 .../tests/requirements.oldest.txt             |     7 +
 .../opentelemetry-agent/tests/test_bridge.py  |   337 +
 tox.ini                                       |    11 +
 895 files changed, 1258 insertions(+), 208132 deletions(-)
 create mode 100644 agent/opentelemetry-agent/patches/otel-api-bridge.patch
 create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/__init__.py
 create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/context.py
 create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/span.py
 create mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/trace.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/enum_type_wrapper.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/util/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/contrib/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py
 delete mode 100644 agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py
 create mode 100644 agent/opentelemetry-agent/tests/requirements.latest.txt
 create mode 100644 agent/opentelemetry-agent/tests/requirements.oldest.txt
 create mode 100644 agent/opentelemetry-agent/tests/test_bridge.py

diff --git a/.github/workflows/core_contrib_test.yml b/.github/workflows/core_contrib_test.yml
index 54d6e978c64..961a0b4e761 100644
--- a/.github/workflows/core_contrib_test.yml
+++ b/.github/workflows/core_contrib_test.yml
@@ -3632,6 +3632,76 @@ jobs:
       - name: Run tests
         run: uv run --no-sync tox -e py310-test-util-http -- -ra
 
+  py310-test-agent-oldest:
+    name: agent-oldest 
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    steps:
+      - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          repository: open-telemetry/opentelemetry-python-contrib
+          ref: ${{ env.CONTRIB_REPO_SHA }}
+          persist-credentials: false
+
+      - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          repository: open-telemetry/opentelemetry-python
+          ref: ${{ env.CORE_REPO_SHA }}
+          path: opentelemetry-python
+          persist-credentials: false
+
+      - name: Set up Python 3.10
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.10"
+          architecture: "x64"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py310-test-agent-oldest -- -ra
+
+  py310-test-agent-latest:
+    name: agent-latest 
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    steps:
+      - name: Checkout contrib repo @ SHA - ${{ env.CONTRIB_REPO_SHA }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          repository: open-telemetry/opentelemetry-python-contrib
+          ref: ${{ env.CONTRIB_REPO_SHA }}
+          persist-credentials: false
+
+      - name: Checkout core repo @ SHA - ${{ env.CORE_REPO_SHA }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          repository: open-telemetry/opentelemetry-python
+          ref: ${{ env.CORE_REPO_SHA }}
+          path: opentelemetry-python
+          persist-credentials: false
+
+      - name: Set up Python 3.10
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.10"
+          architecture: "x64"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py310-test-agent-latest -- -ra
+
   py310-test-exporter-credential-provider-gcp:
     name: exporter-credential-provider-gcp 
     runs-on: ubuntu-latest
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ff037f3c3c9..e6e42d76e12 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -13921,6 +13921,252 @@ jobs:
       - name: Run tests
         run: uv run --no-sync tox -e pypy3-test-util-http -- -ra
 
+  py310-test-agent-oldest_ubuntu-latest:
+    name: agent-oldest 3.10 Ubuntu
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.10
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.10"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py310-test-agent-oldest -- -ra
+
+  py310-test-agent-latest_ubuntu-latest:
+    name: agent-latest 3.10 Ubuntu
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.10
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.10"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py310-test-agent-latest -- -ra
+
+  py311-test-agent-oldest_ubuntu-latest:
+    name: agent-oldest 3.11 Ubuntu
+    runs-on: ubuntu-latest
+    if: ${{ github.event_name != 'pull_request' }}
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.11
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.11"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py311-test-agent-oldest -- -ra
+
+  py311-test-agent-latest_ubuntu-latest:
+    name: agent-latest 3.11 Ubuntu
+    runs-on: ubuntu-latest
+    if: ${{ github.event_name != 'pull_request' }}
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.11
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.11"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py311-test-agent-latest -- -ra
+
+  py312-test-agent-oldest_ubuntu-latest:
+    name: agent-oldest 3.12 Ubuntu
+    runs-on: ubuntu-latest
+    if: ${{ github.event_name != 'pull_request' }}
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.12
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.12"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py312-test-agent-oldest -- -ra
+
+  py312-test-agent-latest_ubuntu-latest:
+    name: agent-latest 3.12 Ubuntu
+    runs-on: ubuntu-latest
+    if: ${{ github.event_name != 'pull_request' }}
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.12
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.12"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py312-test-agent-latest -- -ra
+
+  py313-test-agent-oldest_ubuntu-latest:
+    name: agent-oldest 3.13 Ubuntu
+    runs-on: ubuntu-latest
+    if: ${{ github.event_name != 'pull_request' }}
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.13
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.13"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py313-test-agent-oldest -- -ra
+
+  py313-test-agent-latest_ubuntu-latest:
+    name: agent-latest 3.13 Ubuntu
+    runs-on: ubuntu-latest
+    if: ${{ github.event_name != 'pull_request' }}
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.13
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.13"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py313-test-agent-latest -- -ra
+
+  py314-test-agent-oldest_ubuntu-latest:
+    name: agent-oldest 3.14 Ubuntu
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.14
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.14"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py314-test-agent-oldest -- -ra
+
+  py314-test-agent-latest_ubuntu-latest:
+    name: agent-latest 3.14 Ubuntu
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    steps:
+      - name: Checkout repo @ SHA - ${{ github.sha }}
+        uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
+        with:
+          persist-credentials: false
+
+      - name: Set up Python 3.14
+        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
+        with:
+          python-version: "3.14"
+
+      - name: Set up uv
+        uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
+
+      - name: Install tox
+        run: uv sync --locked --only-group tox
+
+      - name: Run tests
+        run: uv run --no-sync tox -e py314-test-agent-latest -- -ra
+
   py310-test-exporter-credential-provider-gcp_ubuntu-latest:
     name: exporter-credential-provider-gcp 3.10 Ubuntu
     runs-on: ubuntu-latest
diff --git a/agent/opentelemetry-agent/README.rst b/agent/opentelemetry-agent/README.rst
index e118657a81a..4873e865d5d 100644
--- a/agent/opentelemetry-agent/README.rst
+++ b/agent/opentelemetry-agent/README.rst
@@ -23,7 +23,12 @@ Isolation
 
 * Only the vendored plugins (exporters, propagators, samplers, resource detectors) and instrumentations are
   discovered; OpenTelemetry packages installed in the application's environment aren't used.
-* The application's own ``opentelemetry-api`` (if any) is a separate copy: spans and metrics it records
-  don't reach the agent's providers.
+* The application's own ``opentelemetry-api`` (if any) is a separate copy, bridged to the agent: spans it
+  records are exported by the agent's SDK, and they parent (and are parented by) the agent's
+  instrumentation spans. ``opentelemetry-instrument`` selects the bridge by setting ``OTEL_PYTHON_CONTEXT``
+  and ``OTEL_PYTHON_TRACER_PROVIDER`` to ``opentelemetry_agent``, unless they're already set; a tracer
+  provider set by the application before its first ``get_tracer_provider()`` call is kept. Metrics and
+  logs recorded with the application's API don't reach the agent's providers yet. Tested with
+  ``opentelemetry-api`` 1.16 and later.
 * ``opentelemetry-instrumentation`` installs an ``opentelemetry-instrument`` script as well; when both are
   installed, the package installed last owns it.
diff --git a/agent/opentelemetry-agent/patches/otel-api-bridge.patch b/agent/opentelemetry-agent/patches/otel-api-bridge.patch
new file mode 100644
index 00000000000..24a62346bbb
--- /dev/null
+++ b/agent/opentelemetry-agent/patches/otel-api-bridge.patch
@@ -0,0 +1,97 @@
+Select the agent's bridge for the application's opentelemetry-api.
+
+The application's opentelemetry-api is a separate copy from the vendored one. It loads its runtime
+context (OTEL_PYTHON_CONTEXT) and tracer provider (OTEL_PYTHON_TRACER_PROVIDER) from entry points,
+and the opentelemetry-agent distribution registers the bridge (opentelemetry.agent._bridge) under the
+name _AGENT_BRIDGE. The bridge shares the vendored context and delegates to the vendored tracer
+provider. sitecustomize sets both variables unless they're already set.
+
+The vendored API reads the same variables but only sees the vendored distributions' entry points
+(see otel-importlib-metadata.patch), so it treats _AGENT_BRIDGE as unset: it uses its default runtime
+context, which the bridge is built on, and its global tracer provider, which the bridge delegates to.
+
+diff --git a/opentelemetry/context/__init__.py b/opentelemetry/context/__init__.py
+index 7e96f7105..360da46b9 100644
+--- a/opentelemetry/context/__init__.py
++++ b/opentelemetry/context/__init__.py
+@@ -11,7 +11,7 @@ from uuid import uuid4
+ # pylint: disable=wrong-import-position
+ from opentelemetry.agent._vendor.opentelemetry.context.context import Context, _RuntimeContext
+ from opentelemetry.agent._vendor.opentelemetry.context.contextvars_context import ContextVarsRuntimeContext
+-from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_CONTEXT
++from opentelemetry.agent._vendor.opentelemetry.environment_variables import _AGENT_BRIDGE, OTEL_PYTHON_CONTEXT
+ 
+ logger = logging.getLogger(__name__)
+ 
+@@ -23,7 +23,9 @@ def _load_runtime_context() -> _RuntimeContext:
+         An instance of RuntimeContext.
+     """
+     configured_context = os.environ.get(OTEL_PYTHON_CONTEXT)
+-    if not configured_context:
++    # opentelemetry-agent: the agent's bridge (selected for the application's opentelemetry-api) stores
++    # the application's context in this runtime context.
++    if not configured_context or configured_context == _AGENT_BRIDGE:
+         return ContextVarsRuntimeContext()
+ 
+     # pylint: disable=import-outside-toplevel,no-name-in-module
+diff --git a/opentelemetry/environment_variables/__init__.py b/opentelemetry/environment_variables/__init__.py
+index b335c8263..cf913396d 100644
+--- a/opentelemetry/environment_variables/__init__.py
++++ b/opentelemetry/environment_variables/__init__.py
+@@ -70,3 +70,8 @@ _OTEL_PYTHON_LOGGER_PROVIDER = "OTEL_PYTHON_LOGGER_PROVIDER"
+ """
+ .. envvar:: OTEL_PYTHON_LOGGER_PROVIDER
+ """
++
++# opentelemetry-agent: the value of OTEL_PYTHON_CONTEXT and OTEL_PYTHON_TRACER_PROVIDER that selects the
++# agent's bridge in the application's opentelemetry-api: the name of the opentelemetry-agent
++# distribution's opentelemetry_context and opentelemetry_tracer_provider entry points.
++_AGENT_BRIDGE = "opentelemetry_agent"
+diff --git a/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py b/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py
+index 46407e298..0e3284434 100644
+--- a/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py
++++ b/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py
+@@ -1,6 +1,19 @@
+ # Copyright The OpenTelemetry Authors
+ # SPDX-License-Identifier: Apache-2.0
+ 
++from os import environ
++
++from opentelemetry.agent._vendor.opentelemetry.environment_variables import (
++    _AGENT_BRIDGE,
++    OTEL_PYTHON_CONTEXT,
++    OTEL_PYTHON_TRACER_PROVIDER,
++)
+ from opentelemetry.agent._vendor.opentelemetry.instrumentation.auto_instrumentation import initialize
+ 
++# opentelemetry-agent: make the application's opentelemetry-api load the agent's bridge (entry points of
++# the opentelemetry-agent distribution), which shares the vendored API's context and tracer provider.
++# Explicitly configured implementations are kept.
++for _variable in (OTEL_PYTHON_CONTEXT, OTEL_PYTHON_TRACER_PROVIDER):
++    environ.setdefault(_variable, _AGENT_BRIDGE)
++
+ initialize()
+diff --git a/opentelemetry/trace/__init__.py b/opentelemetry/trace/__init__.py
+index 9e0fac92e..b36a85c8f 100644
+--- a/opentelemetry/trace/__init__.py
++++ b/opentelemetry/trace/__init__.py
+@@ -74,7 +74,7 @@ from opentelemetry.agent._vendor.typing_extensions import deprecated
+ from opentelemetry.agent._vendor.opentelemetry import context as context_api
+ from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes
+ from opentelemetry.agent._vendor.opentelemetry.context.context import Context
+-from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER
++from opentelemetry.agent._vendor.opentelemetry.environment_variables import _AGENT_BRIDGE, OTEL_PYTHON_TRACER_PROVIDER
+ from opentelemetry.agent._vendor.opentelemetry.trace.propagation import (
+     _SPAN_KEY,
+     get_current_span,
+@@ -566,7 +566,9 @@ def get_tracer_provider() -> TracerProvider:
+     if _TRACER_PROVIDER is None:
+         # if a global tracer provider has not been set either via code or env
+         # vars, return a proxy tracer provider
+-        if OTEL_PYTHON_TRACER_PROVIDER not in os.environ:
++        # opentelemetry-agent: the agent's bridge (selected for the application's opentelemetry-api)
++        # delegates to this global provider.
++        if os.environ.get(OTEL_PYTHON_TRACER_PROVIDER, _AGENT_BRIDGE) == _AGENT_BRIDGE:
+             return _PROXY_TRACER_PROVIDER
+ 
+         tracer_provider: TracerProvider = _load_provider(OTEL_PYTHON_TRACER_PROVIDER, "tracer_provider")
diff --git a/agent/opentelemetry-agent/pyproject.toml b/agent/opentelemetry-agent/pyproject.toml
index 68f7fdaaa5b..d4a6c59f9d4 100644
--- a/agent/opentelemetry-agent/pyproject.toml
+++ b/agent/opentelemetry-agent/pyproject.toml
@@ -30,6 +30,14 @@ dependencies = []
 # The vendored opentelemetry-instrument: its sitecustomize hook imports the vendored auto-instrumentation.
 opentelemetry-instrument = "opentelemetry.agent._vendor.opentelemetry.instrumentation.auto_instrumentation:run"
 
+# The bridge for the application's opentelemetry-api, selected by the vendored sitecustomize (see
+# patches/otel-api-bridge.patch). The names must match _AGENT_BRIDGE.
+[project.entry-points.opentelemetry_context]
+opentelemetry_agent = "opentelemetry.agent._bridge.context:BridgeRuntimeContext"
+
+[project.entry-points.opentelemetry_tracer_provider]
+opentelemetry_agent = "opentelemetry.agent._bridge.trace:BridgeTracerProvider"
+
 [project.urls]
 Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/agent/opentelemetry-agent"
 Repository = "https://github.com/open-telemetry/opentelemetry-python-contrib"
@@ -86,6 +94,7 @@ patches = [
   "patches/otel-distro-http-protocol.patch",
   "patches/otel-configuration-loader.patch",
   "patches/ruamel-yaml-pure.patch",
+  "patches/otel-api-bridge.patch",
 ]
 sbom-file = "src/opentelemetry/agent/_vendor/bom.cdx.json"
 # Scoped METADATA and namespaced entry points for the vendored importlib.metadata lookups; see
@@ -128,6 +137,9 @@ side-effects = [
   # sitecustomize hook) is what the distro and opentelemetry-instrument are for.
   "opentelemetry/distro/__init__.py",
   "opentelemetry/instrumentation/auto_instrumentation/__init__.py",
+  # Selects the agent's bridge for the application's opentelemetry-api (OTEL_PYTHON_CONTEXT and
+  # OTEL_PYTHON_TRACER_PROVIDER); see patches/otel-api-bridge.patch.
+  "opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py",
   # Copies the deprecated prometheus_multiproc_dir variable to PROMETHEUS_MULTIPROC_DIR when set.
   "prometheus_client/multiprocess.py",
   "prometheus_client/values.py",
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/__init__.py
new file mode 100644
index 00000000000..952adae2496
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/__init__.py
@@ -0,0 +1,36 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""Bridge from the application's ``opentelemetry-api`` to the agent's vendored API and SDK.
+
+The application's API is a separate copy, with its own globals and types. The vendored sitecustomize
+selects the bridge through ``OTEL_PYTHON_CONTEXT`` and ``OTEL_PYTHON_TRACER_PROVIDER``. The application's
+API then loads it from this distribution's entry points:
+
+* `context.BridgeRuntimeContext` stores the application's context in the vendored runtime context,
+  translating the keys of the current span, baggage and instrumentation suppression, so spans of the
+  application and of the vendored instrumentations parent each other.
+* `trace.BridgeTracerProvider` creates spans with the vendored tracer provider, wrapped as the
+  application's span type.
+
+Only the application's API modules imported by then are imported here: the bridge must not import the
+application's ``opentelemetry.trace`` (or any module that does) while its ``opentelemetry.context`` is
+still being imported.
+"""
+
+from __future__ import annotations
+
+from os import environ
+
+from opentelemetry.agent._vendor.opentelemetry.environment_variables import _AGENT_BRIDGE
+
+
+def release_environment_variable(name: str) -> None:
+    """Unset ``name`` once the application's API has loaded the bridge it selects.
+
+    Child processes inherit the environment. Ones that don't run the agent (another virtual environment,
+    or ``PYTHONPATH`` removed) would fail to load the bridge: ``get_tracer_provider()`` raises. Ones
+    that run the agent set it again in sitecustomize.
+    """
+    if environ.get(name) == _AGENT_BRIDGE:
+        del environ[name]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/context.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/context.py
new file mode 100644
index 00000000000..1d530b97d15
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/context.py
@@ -0,0 +1,159 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""The application's runtime context, stored in the vendored one.
+
+The application's ``opentelemetry.context`` loads `BridgeRuntimeContext` while it's being imported
+(``OTEL_PYTHON_CONTEXT``), so only its ``opentelemetry.context.context`` module is imported here.
+
+Both APIs create their context keys with ``create_key()``, which makes them unique: the application's
+keys of the current span, baggage and instrumentation suppression are translated to the vendored
+ones. They're looked up in the application's modules once those have defined them; other keys are
+kept as they are.
+"""
+
+from __future__ import annotations
+
+import sys
+from collections.abc import Callable, Mapping
+from contextvars import Token
+from dataclasses import dataclass
+from typing import cast
+
+from opentelemetry.agent._bridge import release_environment_variable
+from opentelemetry.agent._vendor.opentelemetry import baggage as agent_baggage
+from opentelemetry.agent._vendor.opentelemetry import context as agent_context
+from opentelemetry.agent._vendor.opentelemetry.context.context import Context as AgentContext
+from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_CONTEXT
+from opentelemetry.agent._vendor.opentelemetry.trace import propagation as agent_trace_propagation
+from opentelemetry.context.context import Context, _RuntimeContext
+
+_Convert = Callable[[object], object]
+
+
+def _identity(value: object) -> object:
+    return value
+
+
+def _span_converters() -> tuple[_Convert, _Convert]:
+    # Imports the application's opentelemetry.trace.span, loaded by the time it defines the span key.
+    from opentelemetry.agent._bridge import span  # noqa: PLC0415  # pylint: disable=import-outside-toplevel
+
+    return span.to_app_span, span.to_agent_span
+
+
+def _no_converters() -> tuple[_Convert, _Convert]:
+    return _identity, _identity
+
+
+@dataclass(frozen=True)
+class _KeyBridge:
+    module: str
+    """The application's module that defines the key."""
+    attribute: str
+    agent_key: str
+    converters: Callable[[], tuple[_Convert, _Convert]]
+    """Return the value converters to the application's and the vendored API; called once the key is found."""
+
+
+_KEY_BRIDGES = (
+    _KeyBridge("opentelemetry.trace.propagation", "_SPAN_KEY", agent_trace_propagation._SPAN_KEY, _span_converters),
+    _KeyBridge("opentelemetry.baggage", "_BAGGAGE_KEY", agent_baggage._BAGGAGE_KEY, _no_converters),
+    _KeyBridge(
+        "opentelemetry.context",
+        "_SUPPRESS_INSTRUMENTATION_KEY",
+        agent_context._SUPPRESS_INSTRUMENTATION_KEY,
+        _no_converters,
+    ),
+    # Not defined by opentelemetry-api versions before 1.22.
+    _KeyBridge(
+        "opentelemetry.context",
+        "_SUPPRESS_HTTP_INSTRUMENTATION_KEY",
+        agent_context._SUPPRESS_HTTP_INSTRUMENTATION_KEY,
+        _no_converters,
+    ),
+)
+
+
+@dataclass(frozen=True)
+class _KeyTable:
+    pending: tuple[_KeyBridge, ...]
+    """Keys the application's API hasn't defined yet."""
+    to_app: Mapping[str, tuple[str, _Convert]]
+    """Vendored key → the application's key and the value converter."""
+    to_agent: Mapping[str, tuple[str, _Convert]]
+    """The application's key → vendored key and the value converter."""
+
+
+_key_table = _KeyTable(pending=_KEY_BRIDGES, to_app={}, to_agent={})
+
+
+def _keys() -> _KeyTable:
+    """The current key table, after looking up the pending keys.
+
+    Updates replace the table as a whole; concurrent ones compute the same table.
+    """
+    global _key_table  # pylint: disable=global-statement
+    table = _key_table
+    if not table.pending:
+        return table
+    found: list[tuple[_KeyBridge, str]] = []
+    for bridge in table.pending:
+        app_key = getattr(sys.modules.get(bridge.module), bridge.attribute, None)
+        if isinstance(app_key, str):
+            found.append((bridge, app_key))
+    if not found:
+        return table
+    to_app = dict(table.to_app)
+    to_agent = dict(table.to_agent)
+    for bridge, app_key in found:
+        to_app_value, to_agent_value = bridge.converters()
+        to_app[bridge.agent_key] = (app_key, to_app_value)
+        to_agent[app_key] = (bridge.agent_key, to_agent_value)
+    found_bridges = {bridge for bridge, _ in found}
+    table = _KeyTable(
+        pending=tuple(bridge for bridge in table.pending if bridge not in found_bridges),
+        to_app=to_app,
+        to_agent=to_agent,
+    )
+    _key_table = table
+    return table
+
+
+def _translate(context: Mapping[str, object], keys: Mapping[str, tuple[str, _Convert]]) -> dict[str, object]:
+    values: dict[str, object] = {}
+    for key, value in context.items():
+        translation = keys.get(key)
+        if translation is None:
+            values[key] = value
+        else:
+            translated_key, convert = translation
+            values[translated_key] = convert(value)
+    return values
+
+
+def to_app_context(context: Mapping[str, object]) -> Context:
+    """The application's `Context` with the values of a vendored context."""
+    return Context(_translate(context, _keys().to_app))
+
+
+def to_agent_context(context: Mapping[str, object]) -> AgentContext:
+    """The vendored `Context` with the values of an application's context."""
+    return AgentContext(_translate(context, _keys().to_agent))
+
+
+class BridgeRuntimeContext(_RuntimeContext):
+    """The application's runtime context: the vendored runtime context, with translated keys."""
+
+    def __init__(self) -> None:
+        release_environment_variable(OTEL_PYTHON_CONTEXT)
+
+    def attach(self, context: Context) -> Token[Context]:
+        # The token is opaque to the application's API: it's only passed back to detach().
+        return cast("Token[Context]", agent_context._RUNTIME_CONTEXT.attach(to_agent_context(context)))
+
+    def get_current(self) -> Context:
+        return to_app_context(agent_context._RUNTIME_CONTEXT.get_current())
+
+    def detach(self, token: Token[Context]) -> None:
+        agent_context._RUNTIME_CONTEXT.detach(cast("Token[AgentContext]", token))
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/span.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/span.py
new file mode 100644
index 00000000000..f7672d33e1a
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/span.py
@@ -0,0 +1,145 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""Conversions between the application's and the vendored spans, span contexts and statuses.
+
+Only the application's ``opentelemetry.trace.span`` and ``opentelemetry.trace.status`` are imported:
+the context bridge imports this module as soon as the application's ``opentelemetry.trace.propagation``
+defines its span key, before its ``opentelemetry.trace`` has finished importing.
+"""
+
+from __future__ import annotations
+
+import types
+import weakref
+from collections.abc import Mapping
+
+from opentelemetry.agent._vendor.opentelemetry.trace import span as agent_span
+from opentelemetry.agent._vendor.opentelemetry.trace import status as agent_status
+from opentelemetry.trace.span import INVALID_SPAN, Span, SpanContext, TraceFlags, TraceState
+from opentelemetry.trace.status import Status, StatusCode
+from opentelemetry.util import types as app_types
+
+# The application's spans that aren't bridge spans (e.g. extracted by its propagators) are stored as vendored
+# non-recording spans: map those back to the original span.
+_APP_SPANS: weakref.WeakKeyDictionary[agent_span.Span, Span] = weakref.WeakKeyDictionary()
+
+
+def to_agent_span_context(span_context: SpanContext) -> agent_span.SpanContext:
+    return agent_span.SpanContext(
+        trace_id=span_context.trace_id,
+        span_id=span_context.span_id,
+        is_remote=span_context.is_remote,
+        trace_flags=agent_span.TraceFlags(span_context.trace_flags),
+        trace_state=agent_span.TraceState(list(span_context.trace_state.items())),
+    )
+
+
+def to_app_span_context(span_context: agent_span.SpanContext) -> SpanContext:
+    return SpanContext(
+        trace_id=span_context.trace_id,
+        span_id=span_context.span_id,
+        is_remote=span_context.is_remote,
+        trace_flags=TraceFlags(span_context.trace_flags),
+        trace_state=TraceState(list(span_context.trace_state.items())),
+    )
+
+
+def to_agent_status_code(status_code: StatusCode) -> agent_status.StatusCode:
+    return agent_status.StatusCode[status_code.name]
+
+
+def to_agent_status(status: Status) -> agent_status.Status:
+    return agent_status.Status(to_agent_status_code(status.status_code), status.description)
+
+
+class BridgeSpan(Span):
+    """The application's span type, wrapping a vendored span.
+
+    Bridge spans are created for each lookup of the current span; they're equal when they wrap the same span.
+    """
+
+    def __init__(self, span: agent_span.Span) -> None:
+        self._span = span
+
+    def end(self, end_time: int | None = None) -> None:
+        self._span.end(end_time)
+
+    def get_span_context(self) -> SpanContext:
+        return to_app_span_context(self._span.get_span_context())
+
+    def set_attributes(self, attributes: Mapping[str, app_types.AttributeValue]) -> None:
+        self._span.set_attributes(attributes)
+
+    def set_attribute(self, key: str, value: app_types.AttributeValue) -> None:
+        self._span.set_attribute(key, value)
+
+    def add_event(self, name: str, attributes: app_types.Attributes = None, timestamp: int | None = None) -> None:
+        self._span.add_event(name, attributes, timestamp)
+
+    def add_link(self, context: SpanContext, attributes: app_types.Attributes = None) -> None:
+        self._span.add_link(to_agent_span_context(context), attributes)
+
+    def update_name(self, name: str) -> None:
+        self._span.update_name(name)
+
+    def is_recording(self) -> bool:
+        return self._span.is_recording()
+
+    def set_status(self, status: Status | StatusCode, description: str | None = None) -> None:
+        if isinstance(status, Status):
+            self._span.set_status(to_agent_status(status), description)
+        else:
+            self._span.set_status(to_agent_status_code(status), description)
+
+    def record_exception(
+        self,
+        exception: BaseException,
+        attributes: app_types.Attributes = None,
+        timestamp: int | None = None,
+        escaped: bool = False,
+    ) -> None:
+        self._span.record_exception(exception, attributes, timestamp, escaped)
+
+    def __exit__(
+        self,
+        exc_type: type[BaseException] | None,
+        exc_val: BaseException | None,
+        exc_tb: types.TracebackType | None,
+    ) -> None:
+        # The SDK's span records the exception and sets the error status (as configured at its start).
+        self._span.__exit__(exc_type, exc_val, exc_tb)
+
+    def __eq__(self, other: object) -> bool:
+        return isinstance(other, BridgeSpan) and other._span is self._span
+
+    def __hash__(self) -> int:
+        return hash(self._span)
+
+    def __repr__(self) -> str:
+        return f"BridgeSpan({self._span!r})"
+
+
+def to_app_span(span: object) -> object:
+    """The application's span for a vendored span (in the vendored context)."""
+    if span is agent_span.INVALID_SPAN:
+        return INVALID_SPAN
+    if not isinstance(span, agent_span.Span):
+        return span
+    app_span = _APP_SPANS.get(span)
+    if app_span is not None:
+        return app_span
+    return BridgeSpan(span)
+
+
+def to_agent_span(span: object) -> object:
+    """The vendored span for an application's span (in the application's context)."""
+    if isinstance(span, BridgeSpan):
+        return span._span
+    if span is INVALID_SPAN:
+        return agent_span.INVALID_SPAN
+    if not isinstance(span, Span):
+        return span
+    agent = agent_span.NonRecordingSpan(to_agent_span_context(span.get_span_context()))
+    _APP_SPANS[agent] = span
+    return agent
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/trace.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/trace.py
new file mode 100644
index 00000000000..90892b74281
--- /dev/null
+++ b/agent/opentelemetry-agent/src/opentelemetry/agent/_bridge/trace.py
@@ -0,0 +1,126 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""The application's tracer provider, creating spans with the vendored one.
+
+The application's ``get_tracer_provider()`` loads `BridgeTracerProvider` (``OTEL_PYTHON_TRACER_PROVIDER``)
+unless the application set its own provider first.
+"""
+
+from __future__ import annotations
+
+from collections.abc import Iterator, Sequence
+from typing import TYPE_CHECKING
+
+from opentelemetry import context as app_context
+from opentelemetry import trace as app_trace
+from opentelemetry.agent._bridge import release_environment_variable
+from opentelemetry.agent._bridge.context import BridgeRuntimeContext, to_agent_context
+from opentelemetry.agent._bridge.span import BridgeSpan, to_agent_span_context
+from opentelemetry.agent._vendor.opentelemetry import trace as agent_trace
+from opentelemetry.agent._vendor.opentelemetry.context.context import Context as AgentContext
+from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER
+from opentelemetry.context import Context
+from opentelemetry.util import types as app_types
+
+if TYPE_CHECKING:
+    from opentelemetry.util._decorator import _agnosticcontextmanager
+else:
+    try:
+        from opentelemetry.util._decorator import _agnosticcontextmanager
+    except ImportError:  # opentelemetry-api < 1.24: start_as_current_span isn't usable as a decorator.
+        from contextlib import contextmanager as _agnosticcontextmanager
+
+
+class BridgeTracerProvider(app_trace.TracerProvider):
+    """Gets tracers from the vendored global tracer provider (set when the agent configures the SDK)."""
+
+    def __init__(self) -> None:
+        release_environment_variable(OTEL_PYTHON_TRACER_PROVIDER)
+
+    def get_tracer(
+        self,
+        instrumenting_module_name: str,
+        instrumenting_library_version: str | None = None,
+        schema_url: str | None = None,
+        attributes: app_types.Attributes = None,
+    ) -> app_trace.Tracer:
+        return BridgeTracer(
+            agent_trace.get_tracer_provider().get_tracer(
+                instrumenting_module_name, instrumenting_library_version, schema_url, attributes
+            )
+        )
+
+    def force_flush(self, timeout_millis: int = 30000) -> bool:
+        """Flush the vendored SDK's span processors, like the SDK's ``TracerProvider.force_flush()``."""
+        force_flush = getattr(agent_trace.get_tracer_provider(), "force_flush", None)
+        return force_flush(timeout_millis) if force_flush is not None else True
+
+
+def _agent_parent_context(context: Context | None) -> AgentContext | None:
+    if context is not None:
+        return to_agent_context(context)
+    if isinstance(app_context._RUNTIME_CONTEXT, BridgeRuntimeContext):
+        # The vendored SDK reads the same current context.
+        return None
+    # The application selected another runtime context: its current span isn't the vendored one.
+    return to_agent_context(app_context.get_current())
+
+
+def _to_agent_links(links: Sequence[app_trace.Link] | None) -> list[agent_trace.Link] | None:
+    if links is None:
+        return None
+    return [agent_trace.Link(to_agent_span_context(link.context), link.attributes) for link in links]
+
+
+class BridgeTracer(app_trace.Tracer):
+    def __init__(self, tracer: agent_trace.Tracer) -> None:
+        self._tracer = tracer
+
+    def start_span(
+        self,
+        name: str,
+        context: Context | None = None,
+        kind: app_trace.SpanKind = app_trace.SpanKind.INTERNAL,
+        attributes: app_types.Attributes = None,
+        links: Sequence[app_trace.Link] | None = None,
+        start_time: int | None = None,
+        record_exception: bool = True,
+        set_status_on_exception: bool = True,
+    ) -> app_trace.Span:
+        span = self._tracer.start_span(
+            name,
+            context=_agent_parent_context(context),
+            kind=agent_trace.SpanKind[kind.name],
+            attributes=attributes,
+            links=_to_agent_links(links),
+            start_time=start_time,
+            record_exception=record_exception,
+            set_status_on_exception=set_status_on_exception,
+        )
+        return BridgeSpan(span)
+
+    @_agnosticcontextmanager
+    def start_as_current_span(
+        self,
+        name: str,
+        context: Context | None = None,
+        kind: app_trace.SpanKind = app_trace.SpanKind.INTERNAL,
+        attributes: app_types.Attributes = None,
+        links: Sequence[app_trace.Link] | None = None,
+        start_time: int | None = None,
+        record_exception: bool = True,
+        set_status_on_exception: bool = True,
+        end_on_exit: bool = True,
+    ) -> Iterator[app_trace.Span]:
+        # Same as the SDK's Tracer.start_as_current_span; use_span sets the span in the application's context.
+        span = self.start_span(
+            name, context, kind, attributes, links, start_time, record_exception, set_status_on_exception
+        )
+        with app_trace.use_span(
+            span,
+            end_on_exit=end_on_exit,
+            record_exception=record_exception,
+            set_status_on_exception=set_status_on_exception,
+        ) as current_span:
+            yield current_span
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA
deleted file mode 100644
index fce48f0bc79..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/certifi-2026.10.23.dist-info/METADATA
+++ /dev/null
@@ -1,79 +0,0 @@
-Metadata-Version: 2.4
-Name: certifi
-Version: 2026.10.23
-Summary: Python package for providing Mozilla's CA Bundle.
-Home-page: https://github.com/certifi/python-certifi
-Author: Kenneth Reitz
-Author-email: me@kennethreitz.com
-License: MPL-2.0
-Project-URL: Source, https://github.com/certifi/python-certifi
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
-Classifier: Natural Language :: English
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
-Classifier: Programming Language :: Python :: 3.10
-Classifier: Programming Language :: Python :: 3.11
-Classifier: Programming Language :: Python :: 3.12
-Classifier: Programming Language :: Python :: 3.13
-Classifier: Programming Language :: Python :: 3.14
-Classifier: Programming Language :: Python :: 3.15
-Requires-Python: >=3.7
-License-File: LICENSE
-Dynamic: author
-Dynamic: author-email
-Dynamic: classifier
-Dynamic: description
-Dynamic: home-page
-Dynamic: license
-Dynamic: license-file
-Dynamic: project-url
-Dynamic: requires-python
-Dynamic: summary
-
-Certifi: Python SSL Certificates
-================================
-
-Certifi provides Mozilla's carefully curated collection of Root Certificates for
-validating the trustworthiness of SSL certificates while verifying the identity
-of TLS hosts. It has been extracted from the `Requests`_ project.
-
-Installation
-------------
-
-``certifi`` is available on PyPI. Simply install it with ``pip``::
-
-    $ pip install certifi
-
-Usage
------
-
-To reference the installed certificate authority (CA) bundle, you can use the
-built-in function::
-
-    >>> import certifi
-
-    >>> certifi.where()
-    '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem'
-
-Or from the command line::
-
-    $ python -m certifi
-    /usr/local/lib/python3.7/site-packages/certifi/cacert.pem
-
-Enjoy!
-
-.. _`Requests`: https://requests.readthedocs.io/en/latest/
-
-Addition/Removal of Certificates
---------------------------------
-
-Certifi does not support any addition/removal or other modification of the
-CA trust store content. This project is intended to provide a reliable and
-highly portable root of trust to python deployments. Look to upstream projects
-for methods to use alternate trust.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA
deleted file mode 100644
index d15b68acb1e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/charset_normalizer-3.5.2.dist-info/METADATA
+++ /dev/null
@@ -1,892 +0,0 @@
-Metadata-Version: 2.4
-Name: charset-normalizer
-Version: 3.5.2
-Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
-Author-email: "Ahmed R. TAHRI" 
-Maintainer-email: "Ahmed R. TAHRI" 
-License: MIT
-Project-URL: Changelog, https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md
-Project-URL: Documentation, https://charset-normalizer.readthedocs.io/
-Project-URL: Code, https://github.com/jawah/charset_normalizer
-Project-URL: Issue tracker, https://github.com/jawah/charset_normalizer/issues
-Keywords: encoding,charset,charset-detector,detector,normalization,unicode,chardet,detect
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
-Classifier: Programming Language :: Python :: 3.10
-Classifier: Programming Language :: Python :: 3.11
-Classifier: Programming Language :: Python :: 3.12
-Classifier: Programming Language :: Python :: 3.13
-Classifier: Programming Language :: Python :: 3.14
-Classifier: Programming Language :: Python :: 3.15
-Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: Implementation :: CPython
-Classifier: Programming Language :: Python :: Implementation :: PyPy
-Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient
-Classifier: Environment :: WebAssembly
-Classifier: Environment :: WebAssembly :: Emscripten
-Classifier: Topic :: Text Processing :: Linguistic
-Classifier: Topic :: Utilities
-Classifier: Typing :: Typed
-Requires-Python: >=3.7
-Description-Content-Type: text/markdown
-License-File: LICENSE
-Provides-Extra: unicode-backport
-Dynamic: license-file
-
-

Charset Detection, for Everyone 👋

- -

- The Real First Universal Charset Detector
- - - - - Download Count Total - - - - -

-

- Featured Packages
- - Static Badge - - - Static Badge - -

-

- In other language (unofficial port - by the community)
- - Static Badge - -

- -> A library that helps you read text from an unknown charset encoding.
Motivated by `chardet`, -> I'm trying to resolve the issue by taking a new approach. -> All IANA character set names for which the Python core library provides codecs are supported. -> You can also register your own set of codecs, and yes, it would work as-is. - -This project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**. - -| Feature | [Chardet](https://github.com/chardet/chardet) | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) | -|--------------------------------------------------|:---------------------------------------------:|:-----------------------------------------------------------------------------------------------:|:-----------------------------------------------:| -| `Fast` | ✅ | ✅ | ✅ | -| `Fast on large content (uncapped)` | ❌ | ✅ | ❌ | -| `Universal`[^1] | ❌ | ✅ | ❌ | -| `Reliable` **without** distinguishable standards | ✅ | ✅ | ✅ | -| `Reliable` **with** distinguishable standards | ✅ | ✅ | ✅ | -| `License` | _0BSD_[^2]
_disputed_ | MIT | MPL-1.1
_restrictive_ | -| `Native Python` | ✅ | ✅ | ❌ | -| `Detect spoken language` | ✅ | ✅ | N/A | -| `UnicodeDecodeError Safety` | ❌ | ✅ | ❌ | -| `Whl Size` | ~1200 kB | ~250 kB | ~200 kB | -| `Supported Encoding` | 99 | [99](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings) | 40 | -| `Can register custom encoding` | ❌ | ✅ | ❌ | - -

-Reading Normalized TextCat Reading Text -

- -[^1]: They are clearly using specific code for a specific encoding even if covering most of them. -[^2]: Chardet 7 replaced the historical LGPL-licensed implementation with an AI-assisted rewrite, initially distributed under MIT and later under 0BSD. The original author [contests](https://github.com/chardet/chardet/issues/327) that the rewrite was sufficiently independent to permit relicensing, while Chardet's maintainer maintains that it is a new, non-derivative implementation. A separate [discussion](https://github.com/chardet/chardet/issues/334) raises questions about copyright ownership and licensing of substantially AI-generated code. Neither unresolved question is presented here as settled law. The concern is broader than whether ideas, APIs, or observable behavior are copyrightable. Independent implementations are essential to open-source competition. The ethical question is whether a maintainer with extensive access to a reciprocal project's source, architecture, tests, behavior, community, and reputation can use an LLM to recreate the same product under the same package identity, then treat the generated implementation as a provenance reset that extinguishes the project's reciprocal licensing obligations and contributor expectations. Responsible AI use in open source requires more than producing text that differs from the historical source: it requires transparent provenance, respect for project lineage, meaningful attribution, accountable human review, and consideration for the social agreement under which earlier contributors participated. If automated rewriting becomes an accepted way to retain a project's name, users, and accumulated reputation while discarding its reciprocal license, it risks weakening the trust and incentives on which FOSS depends. Early Chardet 7.x development and evaluation also incorporated files originating from charset-normalizer's test corpus. Results measured on data that influenced implementation or model development are not independent validation. Charset-normalizer has been MIT-licensed since inception and originates from a continuous human-designed, encoding-agnostic project history. AI assistance may be used, but every proposed change remains subject to maintainer review, adjustment, testing, and accountability; AI is an engineering aid, not a mechanism for erasing provenance or project lineage. An attentive eye will see that some aspects lead by us are magically found in Chardet. - -## ⚡ Performance - -This package offer similar performances in general against Chardet. Expect 10X faster with large contents when you uncap Chardet max_bytes default assumption. - -| Package | Accuracy | Mean per file (ms) | -|--------------------|:--------:|:---------------------:| -| Chardet | 99 % | 0.4 ms[^4] 0.6 ms[^5] | -| charset-normalizer | 98 % | 0.4 ms | -| cchardet[^3] | 94 % | 0.6 ms | - -_Well, sub-ms detectors made them extremely discrete in the overall runtime. -Competitors can still win individual measurements, especially capped Chardet on -small-file median latency. But when performance, accuracy, binary handling, validation -strength, portability, and maintainability are considered together, charset-normalizer -is the stronger package._ - -| Package | 99th percentile | 95th percentile | 50th percentile | -|--------------------|:--------------------:|:---------------:|:---------------:| -| Chardet | 2.5 ms[^4] 4.2ms[^5] | 1 ms | 0.2 ms | -| charset-normalizer | 2.7 ms | 1.5 ms | 0.2 ms | -| cchardet | 2.7 ms | 2 ms | 0.3 ms | - -_updated as of August 2026 using CPython 3.12, Charset-Normalizer 3.5.1, and Chardet 7.5 inside a (libc Debian) container. The host CPU is a 13th gen Intel mobile CPU. We'll no longer update regularly those since the sub-ms changes aren't meaningful to anyone anymore._ - -> Stats are generated using 477 files using default parameters. More details on used files, see GHA workflows. -> And yes, these results might change at any time. The dataset can be updated to include more files. -> The actual delays heavily depends on your CPU capabilities. The factors should remain the same. -> Chardet claims on his documentation to have a greater accuracy than us based on the dataset they trained Chardet on(...) -> Whereas charset-normalizer don't train on anything, our solution is based on a completely different algorithm, still heuristic -> through, it does not need weights across every encoding tables. - -[^3]: cchardet main repository/package was discontinued. we're relying on a known fork namely faust-cchardet. the idea remained the same: uchardet bindings. -[^4]: Chardet does not feed the complete body but rather a limited part of it, because the algorithm doesn't scale properly with larger samples. Feeding the whole content slow things to 0.8 ms (from the 0.5ms avg). While we do not skip content in order for us to guarantee a usable result each and every time. We attempted to feed a 272 MiB UTF-8 (Reddit archive on comments/posts) file in Chardet uncapped and waited 3.4s while Charset-Normalizer took 0.3s, this is a 10-fold speedup. -[^5]: Uncapped max_bytes (no truncating of content) - -## ✨ Installation - -Using pip: - -```sh -pip install charset-normalizer -U -``` - -## 🚀 Basic Usage - -### CLI -This package comes with a CLI. - -``` -usage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD] - file [file ...] - -The Real First Universal Charset Detector. Discover originating encoding used -on text file. Normalize text to unicode. - -positional arguments: - files File(s) to be analysed - -optional arguments: - -h, --help show this help message and exit - -v, --verbose Display complementary information about file if any. - Stdout will contain logs about the detection process. - -a, --with-alternative - Output complementary possibilities if any. Top-level - JSON WILL be a list. - -n, --normalize Permit to normalize input file. If not set, program - does not write anything. - -m, --minimal Only output the charset detected to STDOUT. Disabling - JSON output. - -r, --replace Replace file when trying to normalize it instead of - creating a new one. - -f, --force Replace file without asking if you are sure, use this - flag with caution. - -t THRESHOLD, --threshold THRESHOLD - Define a custom maximum amount of chaos allowed in - decoded content. 0. <= chaos <= 1. - --version Show version information and exit. -``` - -```bash -normalizer ./data/sample.1.fr.srt -``` - -or - -```bash -python -m charset_normalizer ./data/sample.1.fr.srt -``` - -🎉 Since version 1.4.0 the CLI produce easily usable stdout result in JSON format. - -```json -{ - "path": "/home/default/projects/charset_normalizer/data/sample.1.fr.srt", - "encoding": "cp1252", - "encoding_aliases": [ - "1252", - "windows_1252" - ], - "alternative_encodings": [ - "cp1254", - "cp1256", - "cp1258", - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_9", - "latin_1", - "mbcs" - ], - "language": "French", - "alphabets": [ - "Basic Latin", - "Latin-1 Supplement" - ], - "has_sig_or_bom": false, - "chaos": 0.149, - "coherence": 97.152, - "unicode_path": null, - "is_preferred": true -} -``` - -### Python -*Just print out normalized text* -```python -from charset_normalizer import from_path - -results = from_path('./my_subtitle.srt') - -print(str(results.best())) -``` - -*Upgrade your code without effort* -```python -from charset_normalizer import detect -``` - -The above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible. - -See the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/) - -## 😇 Why - -When I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a -reliable alternative using a completely different method. Also! I never back down on a good challenge! - -I **don't care** about the **originating charset** encoding, because **two different tables** can -produce **two identical rendered string.** -What I want is to get readable text, the best I can. - -In a way, **I'm brute forcing text decoding.** How cool is that ? 😎 - -Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair Unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode. - -## 🍰 How - - - Discard all charset encoding table that could not fit the binary content. - - Measure noise, or the mess once opened (by chunks) with a corresponding charset encoding. - - Extract matches with the lowest mess detected. - - Additionally, we measure coherence / probe for a language. - -**Wait a minute**, what is noise/mess and coherence according to **YOU ?** - -*Noise :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then -**I established** some ground rules about **what is obvious** when **it seems like** a mess (aka. defining noise in rendered text). - I know that my interpretation of what is noise is probably incomplete, feel free to contribute in order to - improve or rewrite it. - -*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought -that intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design. - -## ⚡ Known limitations - - - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters)) - - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content. - -## ⚠️ About Python EOLs - -**If you are running:** - -- Python >=2.7,<3.5: Unsupported -- Python 3.5: charset-normalizer < 2.1 -- Python 3.6: charset-normalizer < 3.1 - -Upgrade your Python interpreter as soon as possible. - -## 👤 Contributing - -Contributions, issues and feature requests are very much welcome.
-Feel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute. - -## 📝 License - -Copyright © [Ahmed TAHRI @Ousret](https://github.com/Ousret).
-This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed. - -Characters frequencies used in this project © 2012 [Denny Vrandečić](http://simia.net/letters/) - -## 💼 For Enterprise - -Professional support for charset-normalizer is available as part of the [Tidelift -Subscription][1]. Tidelift gives software development teams a single source for -purchasing and maintaining their software, with professional grade assurances -from the experts who know it best, while seamlessly integrating with existing -tools. - -[1]: https://tidelift.com/subscription/pkg/pypi-charset-normalizer?utm_source=pypi-charset-normalizer&utm_medium=readme - -[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7297/badge)](https://www.bestpractices.dev/projects/7297) - -# Changelog -All notable changes to charset-normalizer will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -## [3.5.2](https://github.com/Ousret/charset_normalizer/compare/3.5.1...3.5.2) (2026-09-29) - -### Changed - -- Raised the Cython upper bound to `<3.4` for native builds. The bound remains `<3.3` for - `abi3` builds to preserve compatibility with the Python 3.7 Limited API. - -### Fixed - -- Valid UTF-8 Chinese JSON incorrectly detected as PTCP154 due to excessive noise penalties - for uncommon CJK characters. (#796) -- Supported encodings without aliases failing name resolution or being ignored in charset - declarations. (#800) - -## [3.5.1](https://github.com/Ousret/charset_normalizer/compare/3.5.0...3.5.1) (2026-08-15) - -### Changed -- Raised upper bound of setuptools to v84 (#794) -- Cache performance access optimization for our CharInfo struct (prebuilt only). - -### Fixed -- No longer decoding large content when the noise detector output give a high entropy. - Only impacted large content input >1M bytes. - -## [3.5.0](https://github.com/Ousret/charset_normalizer/compare/3.4.9...3.5.0) (2026-08-12) - -### Added -- Explicit support for Python 3.15 - -### Fixed -- Comparing a CharsetMatch to a non-alias encoding strings (#773) -- Return 0.0 CharsetMatch.multi_byte_usage for empty payloads instead of crashing (#774) -- A file with both a charset declaration and BOM/SIG did not verify first the BOM/SIG charset. -- iso2022* cases misdetected due to a flaw in our multibyte chunking logic. - -### Changed -- Replaced the optional mypyc build with Cython extensions while retaining the - pure Python fallback. The previous engine (mypyc) started to hit rough limit around - the optimization of our noise/coherence detector while Cython allows us to - steer the engine toward the right generated optimized sources. - This change SHOULD not impact bundler (e.g. Pyinstaller) as the module are - immediately discoverable (i.e. not hidden import like mypyc did). - Moreover, a long wished distribution is the abi3 wheels, this will allow us - to no longer rush each year when a new Python interpreter is released. - We still distribute the interpreter specific wheels for faster performance. -- Applied micro-optimization on several utils. -- CharsetMatches no longer sort on each match insertion. - -### Misc -- Removed an old performance optimization attempt in apy.py (success_fast_tracked+payload_result_cache). - -## [3.4.9](https://github.com/Ousret/charset_normalizer/compare/3.4.8...3.4.9) (2026-07-07) - -### Fixed -- Regression in our fallback path leading to a decode error. (#771) - We've yanked 3.4.8 as a result of that bug. - -## [3.4.8](https://github.com/Ousret/charset_normalizer/compare/3.4.7...3.4.8) (2026-07-06) - -### Fixed -- Wall import time due to cascade codec imports for our multibyte first sort of iana supported codecs (#742) -- Unnecessary json import at runtime (#753) -- Inverse capitalization not seen by noise detector (#731) - -### Changed -- No longer holding a global cache for our noise / coherence measurements. Relax RSS memory usage. -- Micro-optimizations in our noise / coherence measurements. -- No longer using regex search by default for our preemptive charset mark algorithm. -- Raised upperbound of setuptools to v83. -- Raised upperbound of mypy(c) to v2.1. - -### Removed -- Redundant UTF7 BOM marker (#730) - -## [3.4.7](https://github.com/Ousret/charset_normalizer/compare/3.4.6...3.4.7) (2026-04-02) - -### Changed -- Pre-built optimized version using mypy[c] v1.20. -- Relax `setuptools` constraint to `setuptools>=68,<82.1`. - -### Fixed -- Correctly remove SIG remnant in utf-7 decoded string. (#718) (#716) - -## [3.4.6](https://github.com/Ousret/charset_normalizer/compare/3.4.5...3.4.6) (2026-03-15) - -### Changed -- Flattened the logic in `charset_normalizer.md` for higher performance. Removed `eligible(..)` and `feed(...)` - in favor of `feed_info(...)`. -- Raised upper bound for mypy[c] to 1.20, for our optimized version. -- Updated `UNICODE_RANGES_COMBINED` using Unicode blocks v17. - -### Fixed -- Edge case where noise difference between two candidates can be almost insignificant. (#672) -- CLI `--normalize` writing to wrong path when passing multiple files in. (#702) - -### Misc -- Freethreaded pre-built wheels now shipped in PyPI starting with 3.14t. (#616) - -## [3.4.5](https://github.com/Ousret/charset_normalizer/compare/3.4.4...3.4.5) (2026-03-06) - -### Changed -- Update `setuptools` constraint to `setuptools>=68,<=82`. -- Raised upper bound of mypyc for the optional pre-built extension to v1.19.1 - -### Fixed -- Add explicit link to lib math in our optimized build. (#692) -- Logger level not restored correctly for empty byte sequences. (#701) -- TypeError when passing bytearray to from_bytes. (#703) - -### Misc -- Applied safe micro-optimizations in both our noise detector and language detector. -- Rewrote the `query_yes_no` function (inside CLI) to avoid using ambiguous licensed code. -- Added `cd.py` submodule into mypyc optional compilation to reduce further the performance impact. - -## [3.4.4](https://github.com/Ousret/charset_normalizer/compare/3.4.2...3.4.4) (2025-10-13) - -### Changed -- Bound `setuptools` to a specific constraint `setuptools>=68,<=81`. -- Raised upper bound of mypyc for the optional pre-built extension to v1.18.2 - -### Removed -- `setuptools-scm` as a build dependency. - -### Misc -- Enforced hashes in `dev-requirements.txt` and created `ci-requirements.txt` for security purposes. -- Additional pre-built wheels for riscv64, s390x, and armv7l architectures. -- Restore ` multiple.intoto.jsonl` in GitHub releases in addition to individual attestation file per wheel. - -## [3.4.3](https://github.com/Ousret/charset_normalizer/compare/3.4.2...3.4.3) (2025-08-09) - -### Changed -- mypy(c) is no longer a required dependency at build time if `CHARSET_NORMALIZER_USE_MYPYC` isn't set to `1`. (#595) (#583) -- automatically lower confidence on small bytes samples that are not Unicode in `detect` output legacy function. (#391) - -### Added -- Custom build backend to overcome inability to mark mypy as an optional dependency in the build phase. -- Support for Python 3.14 - -### Fixed -- sdist archive contained useless directories. -- automatically fallback on valid UTF-16 or UTF-32 even if the md says it's noisy. (#633) - -### Misc -- SBOM are automatically published to the relevant GitHub release to comply with regulatory changes. - Each published wheel comes with its SBOM. We choose CycloneDX as the format. -- Prebuilt optimized wheel are no longer distributed by default for CPython 3.7 due to a change in cibuildwheel. - -## [3.4.2](https://github.com/Ousret/charset_normalizer/compare/3.4.1...3.4.2) (2025-05-02) - -### Fixed -- Addressed the DeprecationWarning in our CLI regarding `argparse.FileType` by backporting the target class into the package. (#591) -- Improved the overall reliability of the detector with CJK Ideographs. (#605) (#587) - -### Changed -- Optional mypyc compilation upgraded to version 1.15 for Python >= 3.8 - -## [3.4.1](https://github.com/Ousret/charset_normalizer/compare/3.4.0...3.4.1) (2024-12-24) - -### Changed -- Project metadata are now stored using `pyproject.toml` instead of `setup.cfg` using setuptools as the build backend. -- Enforce annotation delayed loading for a simpler and consistent types in the project. -- Optional mypyc compilation upgraded to version 1.14 for Python >= 3.8 - -### Added -- pre-commit configuration. -- noxfile. - -### Removed -- `build-requirements.txt` as per using `pyproject.toml` native build configuration. -- `bin/integration.py` and `bin/serve.py` in favor of downstream integration test (see noxfile). -- `setup.cfg` in favor of `pyproject.toml` metadata configuration. -- Unused `utils.range_scan` function. - -### Fixed -- Converting content to Unicode bytes may insert `utf_8` instead of preferred `utf-8`. (#572) -- Deprecation warning "'count' is passed as positional argument" when converting to Unicode bytes on Python 3.13+ - -## [3.4.0](https://github.com/Ousret/charset_normalizer/compare/3.3.2...3.4.0) (2024-10-08) - -### Added -- Argument `--no-preemptive` in the CLI to prevent the detector to search for hints. -- Support for Python 3.13 (#512) - -### Fixed -- Relax the TypeError exception thrown when trying to compare a CharsetMatch with anything else than a CharsetMatch. -- Improved the general reliability of the detector based on user feedbacks. (#520) (#509) (#498) (#407) (#537) -- Declared charset in content (preemptive detection) not changed when converting to utf-8 bytes. (#381) - -## [3.3.2](https://github.com/Ousret/charset_normalizer/compare/3.3.1...3.3.2) (2023-10-31) - -### Fixed -- Unintentional memory usage regression when using large payload that match several encoding (#376) -- Regression on some detection case showcased in the documentation (#371) - -### Added -- Noise (md) probe that identify malformed arabic representation due to the presence of letters in isolated form (credit to my wife) - -## [3.3.1](https://github.com/Ousret/charset_normalizer/compare/3.3.0...3.3.1) (2023-10-22) - -### Changed -- Optional mypyc compilation upgraded to version 1.6.1 for Python >= 3.8 -- Improved the general detection reliability based on reports from the community - -## [3.3.0](https://github.com/Ousret/charset_normalizer/compare/3.2.0...3.3.0) (2023-09-30) - -### Added -- Allow to execute the CLI (e.g. normalizer) through `python -m charset_normalizer.cli` or `python -m charset_normalizer` -- Support for 9 forgotten encoding that are supported by Python but unlisted in `encoding.aliases` as they have no alias (#323) - -### Removed -- (internal) Redundant utils.is_ascii function and unused function is_private_use_only -- (internal) charset_normalizer.assets is moved inside charset_normalizer.constant - -### Changed -- (internal) Unicode code blocks in constants are updated using the latest v15.0.0 definition to improve detection -- Optional mypyc compilation upgraded to version 1.5.1 for Python >= 3.8 - -### Fixed -- Unable to properly sort CharsetMatch when both chaos/noise and coherence were close due to an unreachable condition in \_\_lt\_\_ (#350) - -## [3.2.0](https://github.com/Ousret/charset_normalizer/compare/3.1.0...3.2.0) (2023-06-07) - -### Changed -- Typehint for function `from_path` no longer enforce `PathLike` as its first argument -- Minor improvement over the global detection reliability - -### Added -- Introduce function `is_binary` that relies on main capabilities, and optimized to detect binaries -- Propagate `enable_fallback` argument throughout `from_bytes`, `from_path`, and `from_fp` that allow a deeper control over the detection (default True) -- Explicit support for Python 3.12 - -### Fixed -- Edge case detection failure where a file would contain 'very-long' camel cased word (Issue #289) - -## [3.1.0](https://github.com/Ousret/charset_normalizer/compare/3.0.1...3.1.0) (2023-03-06) - -### Added -- Argument `should_rename_legacy` for legacy function `detect` and disregard any new arguments without errors (PR #262) - -### Removed -- Support for Python 3.6 (PR #260) - -### Changed -- Optional speedup provided by mypy/c 1.0.1 - -## [3.0.1](https://github.com/Ousret/charset_normalizer/compare/3.0.0...3.0.1) (2022-11-18) - -### Fixed -- Multi-bytes cutter/chunk generator did not always cut correctly (PR #233) - -### Changed -- Speedup provided by mypy/c 0.990 on Python >= 3.7 - -## [3.0.0](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.0) (2022-10-20) - -### Added -- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results -- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES -- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio -- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) - -### Changed -- Build with static metadata using 'build' frontend -- Make the language detection stricter -- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 - -### Fixed -- CLI with opt --normalize fail when using full path for files -- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it -- Sphinx warnings when generating the documentation - -### Removed -- Coherence detector no longer return 'Simple English' instead return 'English' -- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' -- Breaking: Method `first()` and `best()` from CharsetMatch -- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) -- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches -- Breaking: Top-level function `normalize` -- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch -- Support for the backport `unicodedata2` - -## [3.0.0rc1](https://github.com/Ousret/charset_normalizer/compare/3.0.0b2...3.0.0rc1) (2022-10-18) - -### Added -- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results -- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES -- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio - -### Changed -- Build with static metadata using 'build' frontend -- Make the language detection stricter - -### Fixed -- CLI with opt --normalize fail when using full path for files -- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it - -### Removed -- Coherence detector no longer return 'Simple English' instead return 'English' -- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' - -## [3.0.0b2](https://github.com/Ousret/charset_normalizer/compare/3.0.0b1...3.0.0b2) (2022-08-21) - -### Added -- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) - -### Removed -- Breaking: Method `first()` and `best()` from CharsetMatch -- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) - -### Fixed -- Sphinx warnings when generating the documentation - -## [3.0.0b1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...3.0.0b1) (2022-08-15) - -### Changed -- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 - -### Removed -- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches -- Breaking: Top-level function `normalize` -- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch -- Support for the backport `unicodedata2` - -## [2.1.1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...2.1.1) (2022-08-19) - -### Deprecated -- Function `normalize` scheduled for removal in 3.0 - -### Changed -- Removed useless call to decode in fn is_unprintable (#206) - -### Fixed -- Third-party library (i18n xgettext) crashing not recognizing utf_8 (PEP 263) with underscore from [@aleksandernovikov](https://github.com/aleksandernovikov) (#204) - -## [2.1.0](https://github.com/Ousret/charset_normalizer/compare/2.0.12...2.1.0) (2022-06-19) - -### Added -- Output the Unicode table version when running the CLI with `--version` (PR #194) - -### Changed -- Reuse decoded buffer for single byte character sets from [@nijel](https://github.com/nijel) (PR #175) -- Fixing some performance bottlenecks from [@deedy5](https://github.com/deedy5) (PR #183) - -### Fixed -- Workaround potential bug in cpython with Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space (PR #175) -- CLI default threshold aligned with the API threshold from [@oleksandr-kuzmenko](https://github.com/oleksandr-kuzmenko) (PR #181) - -### Removed -- Support for Python 3.5 (PR #192) - -### Deprecated -- Use of backport unicodedata from `unicodedata2` as Python is quickly catching up, scheduled for removal in 3.0 (PR #194) - -## [2.0.12](https://github.com/Ousret/charset_normalizer/compare/2.0.11...2.0.12) (2022-02-12) - -### Fixed -- ASCII miss-detection on rare cases (PR #170) - -## [2.0.11](https://github.com/Ousret/charset_normalizer/compare/2.0.10...2.0.11) (2022-01-30) - -### Added -- Explicit support for Python 3.11 (PR #164) - -### Changed -- The logging behavior have been completely reviewed, now using only TRACE and DEBUG levels (PR #163 #165) - -## [2.0.10](https://github.com/Ousret/charset_normalizer/compare/2.0.9...2.0.10) (2022-01-04) - -### Fixed -- Fallback match entries might lead to UnicodeDecodeError for large bytes sequence (PR #154) - -### Changed -- Skipping the language-detection (CD) on ASCII (PR #155) - -## [2.0.9](https://github.com/Ousret/charset_normalizer/compare/2.0.8...2.0.9) (2021-12-03) - -### Changed -- Moderating the logging impact (since 2.0.8) for specific environments (PR #147) - -### Fixed -- Wrong logging level applied when setting kwarg `explain` to True (PR #146) - -## [2.0.8](https://github.com/Ousret/charset_normalizer/compare/2.0.7...2.0.8) (2021-11-24) -### Changed -- Improvement over Vietnamese detection (PR #126) -- MD improvement on trailing data and long foreign (non-pure latin) data (PR #124) -- Efficiency improvements in cd/alphabet_languages from [@adbar](https://github.com/adbar) (PR #122) -- call sum() without an intermediary list following PEP 289 recommendations from [@adbar](https://github.com/adbar) (PR #129) -- Code style as refactored by Sourcery-AI (PR #131) -- Minor adjustment on the MD around european words (PR #133) -- Remove and replace SRTs from assets / tests (PR #139) -- Initialize the library logger with a `NullHandler` by default from [@nmaynes](https://github.com/nmaynes) (PR #135) -- Setting kwarg `explain` to True will add provisionally (bounded to function lifespan) a specific stream handler (PR #135) - -### Fixed -- Fix large (misleading) sequence giving UnicodeDecodeError (PR #137) -- Avoid using too insignificant chunk (PR #137) - -### Added -- Add and expose function `set_logging_handler` to configure a specific StreamHandler from [@nmaynes](https://github.com/nmaynes) (PR #135) -- Add `CHANGELOG.md` entries, format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) (PR #141) - -## [2.0.7](https://github.com/Ousret/charset_normalizer/compare/2.0.6...2.0.7) (2021-10-11) -### Added -- Add support for Kazakh (Cyrillic) language detection (PR #109) - -### Changed -- Further, improve inferring the language from a given single-byte code page (PR #112) -- Vainly trying to leverage PEP263 when PEP3120 is not supported (PR #116) -- Refactoring for potential performance improvements in loops from [@adbar](https://github.com/adbar) (PR #113) -- Various detection improvement (MD+CD) (PR #117) - -### Removed -- Remove redundant logging entry about detected language(s) (PR #115) - -### Fixed -- Fix a minor inconsistency between Python 3.5 and other versions regarding language detection (PR #117 #102) - -## [2.0.6](https://github.com/Ousret/charset_normalizer/compare/2.0.5...2.0.6) (2021-09-18) -### Fixed -- Unforeseen regression with the loss of the backward-compatibility with some older minor of Python 3.5.x (PR #100) -- Fix CLI crash when using --minimal output in certain cases (PR #103) - -### Changed -- Minor improvement to the detection efficiency (less than 1%) (PR #106 #101) - -## [2.0.5](https://github.com/Ousret/charset_normalizer/compare/2.0.4...2.0.5) (2021-09-14) -### Changed -- The project now comply with: flake8, mypy, isort and black to ensure a better overall quality (PR #81) -- The BC-support with v1.x was improved, the old staticmethods are restored (PR #82) -- The Unicode detection is slightly improved (PR #93) -- Add syntax sugar \_\_bool\_\_ for results CharsetMatches list-container (PR #91) - -### Removed -- The project no longer raise warning on tiny content given for detection, will be simply logged as warning instead (PR #92) - -### Fixed -- In some rare case, the chunks extractor could cut in the middle of a multi-byte character and could mislead the mess detection (PR #95) -- Some rare 'space' characters could trip up the UnprintablePlugin/Mess detection (PR #96) -- The MANIFEST.in was not exhaustive (PR #78) - -## [2.0.4](https://github.com/Ousret/charset_normalizer/compare/2.0.3...2.0.4) (2021-07-30) -### Fixed -- The CLI no longer raise an unexpected exception when no encoding has been found (PR #70) -- Fix accessing the 'alphabets' property when the payload contains surrogate characters (PR #68) -- The logger could mislead (explain=True) on detected languages and the impact of one MBCS match (PR #72) -- Submatch factoring could be wrong in rare edge cases (PR #72) -- Multiple files given to the CLI were ignored when publishing results to STDOUT. (After the first path) (PR #72) -- Fix line endings from CRLF to LF for certain project files (PR #67) - -### Changed -- Adjust the MD to lower the sensitivity, thus improving the global detection reliability (PR #69 #76) -- Allow fallback on specified encoding if any (PR #71) - -## [2.0.3](https://github.com/Ousret/charset_normalizer/compare/2.0.2...2.0.3) (2021-07-16) -### Changed -- Part of the detection mechanism has been improved to be less sensitive, resulting in more accurate detection results. Especially ASCII. (PR #63) -- According to the community wishes, the detection will fall back on ASCII or UTF-8 in a last-resort case. (PR #64) - -## [2.0.2](https://github.com/Ousret/charset_normalizer/compare/2.0.1...2.0.2) (2021-07-15) -### Fixed -- Empty/Too small JSON payload miss-detection fixed. Report from [@tseaver](https://github.com/tseaver) (PR #59) - -### Changed -- Don't inject unicodedata2 into sys.modules from [@akx](https://github.com/akx) (PR #57) - -## [2.0.1](https://github.com/Ousret/charset_normalizer/compare/2.0.0...2.0.1) (2021-07-13) -### Fixed -- Make it work where there isn't a filesystem available, dropping assets frequencies.json. Report from [@sethmlarson](https://github.com/sethmlarson). (PR #55) -- Using explain=False permanently disable the verbose output in the current runtime (PR #47) -- One log entry (language target preemptive) was not show in logs when using explain=True (PR #47) -- Fix undesired exception (ValueError) on getitem of instance CharsetMatches (PR #52) - -### Changed -- Public function normalize default args values were not aligned with from_bytes (PR #53) - -### Added -- You may now use charset aliases in cp_isolation and cp_exclusion arguments (PR #47) - -## [2.0.0](https://github.com/Ousret/charset_normalizer/compare/1.4.1...2.0.0) (2021-07-02) -### Changed -- 4x to 5 times faster than the previous 1.4.0 release. At least 2x faster than Chardet. -- Accent has been made on UTF-8 detection, should perform rather instantaneous. -- The backward compatibility with Chardet has been greatly improved. The legacy detect function returns an identical charset name whenever possible. -- The detection mechanism has been slightly improved, now Turkish content is detected correctly (most of the time) -- The program has been rewritten to ease the readability and maintainability. (+Using static typing)+ -- utf_7 detection has been reinstated. - -### Removed -- This package no longer require anything when used with Python 3.5 (Dropped cached_property) -- Removed support for these languages: Catalan, Esperanto, Kazakh, Baque, Volapük, Azeri, Galician, Nynorsk, Macedonian, and Serbocroatian. -- The exception hook on UnicodeDecodeError has been removed. - -### Deprecated -- Methods coherence_non_latin, w_counter, chaos_secondary_pass of the class CharsetMatch are now deprecated and scheduled for removal in v3.0 - -### Fixed -- The CLI output used the relative path of the file(s). Should be absolute. - -## [1.4.1](https://github.com/Ousret/charset_normalizer/compare/1.4.0...1.4.1) (2021-05-28) -### Fixed -- Logger configuration/usage no longer conflict with others (PR #44) - -## [1.4.0](https://github.com/Ousret/charset_normalizer/compare/1.3.9...1.4.0) (2021-05-21) -### Removed -- Using standard logging instead of using the package loguru. -- Dropping nose test framework in favor of the maintained pytest. -- Choose to not use dragonmapper package to help with gibberish Chinese/CJK text. -- Require cached_property only for Python 3.5 due to constraint. Dropping for every other interpreter version. -- Stop support for UTF-7 that does not contain a SIG. -- Dropping PrettyTable, replaced with pure JSON output in CLI. - -### Fixed -- BOM marker in a CharsetNormalizerMatch instance could be False in rare cases even if obviously present. Due to the sub-match factoring process. -- Not searching properly for the BOM when trying utf32/16 parent codec. - -### Changed -- Improving the package final size by compressing frequencies.json. -- Huge improvement over the larges payload. - -### Added -- CLI now produces JSON consumable output. -- Return ASCII if given sequences fit. Given reasonable confidence. - -## [1.3.9](https://github.com/Ousret/charset_normalizer/compare/1.3.8...1.3.9) (2021-05-13) - -### Fixed -- In some very rare cases, you may end up getting encode/decode errors due to a bad bytes payload (PR #40) - -## [1.3.8](https://github.com/Ousret/charset_normalizer/compare/1.3.7...1.3.8) (2021-05-12) - -### Fixed -- Empty given payload for detection may cause an exception if trying to access the `alphabets` property. (PR #39) - -## [1.3.7](https://github.com/Ousret/charset_normalizer/compare/1.3.6...1.3.7) (2021-05-12) - -### Fixed -- The legacy detect function should return UTF-8-SIG if sig is present in the payload. (PR #38) - -## [1.3.6](https://github.com/Ousret/charset_normalizer/compare/1.3.5...1.3.6) (2021-02-09) - -### Changed -- Amend the previous release to allow prettytable 2.0 (PR #35) - -## [1.3.5](https://github.com/Ousret/charset_normalizer/compare/1.3.4...1.3.5) (2021-02-08) - -### Fixed -- Fix error while using the package with a python pre-release interpreter (PR #33) - -### Changed -- Dependencies refactoring, constraints revised. - -### Added -- Add python 3.9 and 3.10 to the supported interpreters - -MIT License - -Copyright (c) 2025 TAHRI Ahmed R. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA deleted file mode 100644 index c77e94b778f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/fastjsonschema-2.22.3.dist-info/METADATA +++ /dev/null @@ -1,60 +0,0 @@ -Metadata-Version: 2.4 -Name: fastjsonschema -Version: 2.22.3 -Summary: Fastest Python implementation of JSON schema -Home-page: https://github.com/horejsek/python-fastjsonschema -Author: Michal Horejsek -Author-email: fastjsonschema@horejsek.com -License: BSD-3-Clause -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Typing :: Typed -Requires-Python: >=3.10 -License-File: LICENSE -License-File: AUTHORS -Provides-Extra: devel -Requires-Dist: colorama; extra == "devel" -Requires-Dist: jsonschema; extra == "devel" -Requires-Dist: json-spec; extra == "devel" -Requires-Dist: pylint; extra == "devel" -Requires-Dist: pytest; extra == "devel" -Requires-Dist: pytest-benchmark; extra == "devel" -Requires-Dist: pytest-cache; extra == "devel" -Requires-Dist: validictory; extra == "devel" -Dynamic: author -Dynamic: author-email -Dynamic: classifier -Dynamic: description -Dynamic: home-page -Dynamic: license -Dynamic: license-file -Dynamic: provides-extra -Dynamic: requires-python -Dynamic: summary - -=========================== -Fast JSON schema for Python -=========================== - -|PyPI| |Pythons| - -.. |PyPI| image:: https://img.shields.io/pypi/v/fastjsonschema.svg - :alt: PyPI version - :target: https://pypi.python.org/pypi/fastjsonschema - -.. |Pythons| image:: https://img.shields.io/pypi/pyversions/fastjsonschema.svg - :alt: Supported Python versions - :target: https://pypi.python.org/pypi/fastjsonschema - -See `documentation `_. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA deleted file mode 100644 index 28e5ebb3a1a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/googleapis_common_protos-1.76.0.dist-info/METADATA +++ /dev/null @@ -1,215 +0,0 @@ -Metadata-Version: 2.4 -Name: googleapis-common-protos -Version: 1.76.0 -Summary: Common protobufs used in Google APIs -Author-email: Google LLC -License-Expression: Apache-2.0 -Project-URL: Repository, https://github.com/googleapis/google-cloud-python/tree/main/packages/googleapis-common-protos -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: 3.15 -Classifier: Operating System :: OS Independent -Classifier: Topic :: Internet -Requires-Python: >=3.10 -Description-Content-Type: text/x-rst -License-File: LICENSE -Requires-Dist: protobuf<8.0.0,>=6.33.5 -Provides-Extra: grpc -Requires-Dist: grpcio<2.0.0,>=1.59.0; extra == "grpc" -Dynamic: license-file - -Python Client for Service Config -================================ - -|stable| |pypi| |versions| - -- `Client Library Documentation`_ - -.. |stable| image:: https://img.shields.io/badge/support-stable-gold.svg - :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#stability-levels -.. |pypi| image:: https://img.shields.io/pypi/v/googleapis-common-protos.svg - :target: https://pypi.org/project/googleapis-common-protos/ -.. |versions| image:: https://img.shields.io/pypi/pyversions/googleapis-common-protos.svg - :target: https://pypi.org/project/googleapis-common-protos/ -.. _Client Library Documentation: https://github.com/googleapis/google-cloud-python/tree/main/packages/googleapis-common-protos/summary_overview - -Quick Start ------------ - -In order to use this library, you first need to go through the following steps: - -1. `Select or create a Cloud Platform project.`_ -2. `Enable billing for your project.`_ -3. `Set up Authentication.`_ - -.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project -.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project -.. _Set up Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html - -Installation -~~~~~~~~~~~~ - -Install this library in a virtual environment using `venv`_. `venv`_ is a tool that -creates isolated Python environments. These isolated environments can have separate -versions of Python packages, which allows you to isolate one project's dependencies -from the dependencies of other projects. - -With `venv`_, it's possible to install this library without needing system -install permissions, and without clashing with the installed system -dependencies. - -.. _`venv`: https://docs.python.org/3/library/venv.html - - -Code samples and snippets -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Code samples and snippets live in the `samples/`_ folder. - -.. _samples/: https://github.com/googleapis/google-cloud-python/tree/main/packages/googleapis-common-protos/samples - - -Supported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^ -Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of -Python. - -Python >= 3.10, including 3.14 - -.. _active: https://devguide.python.org/devcycle/#in-development-main-branch -.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches - -Unsupported Python Versions -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Python <= 3.9 - - -If you are using an `end-of-life`_ -version of Python, we recommend that you update as soon as possible to an actively supported version. - -.. _end-of-life: https://devguide.python.org/devcycle/#end-of-life-branches - -Mac/Linux -^^^^^^^^^ - -.. code-block:: console - - python3 -m venv - source /bin/activate - pip install googleapis-common-protos - - -Windows -^^^^^^^ - -.. code-block:: console - - py -m venv - .\\Scripts\activate - pip install googleapis-common-protos - -Next Steps -~~~~~~~~~~ - -- Read the `Client Library Documentation`_ for Service Config - to see other available methods on the client. -- View this `README`_ to see the full list of Cloud - APIs that we cover. - -.. _README: https://github.com/googleapis/google-cloud-python/blob/main/README.rst - -Logging -------- - -This library uses the standard Python :code:`logging` functionality to log some RPC events that could be of interest for debugging and monitoring purposes. -Note the following: - -#. Logs may contain sensitive information. Take care to **restrict access to the logs** if they are saved, whether it be on local storage or on Google Cloud Logging. -#. Google may refine the occurrence, level, and content of various log messages in this library without flagging such changes as breaking. **Do not depend on immutability of the logging events**. -#. By default, the logging events from this library are not handled. You must **explicitly configure log handling** using one of the mechanisms below. - -Simple, environment-based configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To enable logging for this library without any changes in your code, set the :code:`GOOGLE_SDK_PYTHON_LOGGING_SCOPE` environment variable to a valid Google -logging scope. This configures handling of logging events (at level :code:`logging.DEBUG` or higher) from this library in a default manner, emitting the logged -messages in a structured format. It does not currently allow customizing the logging levels captured nor the handlers, formatters, etc. used for any logging -event. - -A logging scope is a period-separated namespace that begins with :code:`google`, identifying the Python module or package to log. - -- Valid logging scopes: :code:`google`, :code:`google.cloud.asset.v1`, :code:`google.api`, :code:`google.auth`, etc. -- Invalid logging scopes: :code:`foo`, :code:`123`, etc. - -**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers. - -Environment-Based Examples -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Enabling the default handler for all Google-based loggers - -.. code-block:: console - - export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google - -- Enabling the default handler for a specific Google module (for a client library called :code:`library_v1`): - -.. code-block:: console - - export GOOGLE_SDK_PYTHON_LOGGING_SCOPE=google.cloud.library_v1 - - -Advanced, code-based configuration -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can also configure a valid logging scope using Python's standard `logging` mechanism. - -Code-Based Examples -^^^^^^^^^^^^^^^^^^^ - -- Configuring a handler for all Google-based loggers - -.. code-block:: python - - import logging - - from google.cloud import library_v1 - - base_logger = logging.getLogger("google") - base_logger.addHandler(logging.StreamHandler()) - base_logger.setLevel(logging.DEBUG) - -- Configuring a handler for a specific Google module (for a client library called :code:`library_v1`): - -.. code-block:: python - - import logging - - from google.cloud import library_v1 - - base_logger = logging.getLogger("google.cloud.library_v1") - base_logger.addHandler(logging.StreamHandler()) - base_logger.setLevel(logging.DEBUG) - -Logging details -~~~~~~~~~~~~~~~ - -#. Regardless of which of the mechanisms above you use to configure logging for this library, by default logging events are not propagated up to the root - logger from the `google`-level logger. If you need the events to be propagated to the root logger, you must explicitly set - :code:`logging.getLogger("google").propagate = True` in your code. -#. You can mix the different logging configurations above for different Google modules. For example, you may want use a code-based logging configuration for - one library, but decide you need to also set up environment-based logging configuration for another library. - - #. If you attempt to use both code-based and environment-based configuration for the same module, the environment-based configuration will be ineffectual - if the code -based configuration gets applied first. - -#. The Google-specific logging configurations (default handlers for environment-based configuration; not propagating logging events to the root logger) get - executed the first time *any* client library is instantiated in your application, and only if the affected loggers have not been previously configured. - (This is the reason for 2.i. above.) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA deleted file mode 100644 index edbc446bb4e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/idna-3.20.dist-info/METADATA +++ /dev/null @@ -1,176 +0,0 @@ -Metadata-Version: 2.5 -Name: idna -Version: 3.20 -Summary: Internationalized Domain Names in Applications (IDNA) -Author-email: Kim Davies -Requires-Python: >=3.9 -Description-Content-Type: text/markdown -License-Expression: BSD-3-Clause -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: System Administrators -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: 3.15 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Internet :: Name Service (DNS) -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Utilities -License-File: LICENSE.md -Requires-Dist: ruff >= 0.16.0 ; extra == "all" -Requires-Dist: mypy >= 1.11.2 ; extra == "all" -Requires-Dist: ty >= 0.0.37 ; extra == "all" -Requires-Dist: pytest >= 8.3.2 ; extra == "all" -Requires-Dist: hypothesis >= 6.141.1 ; extra == "all" -Requires-Dist: coverage >= 7.10.0 ; extra == "all" -Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.md -Project-URL: Issue tracker, https://github.com/kjd/idna/issues -Project-URL: Source, https://github.com/kjd/idna -Provides-Extra: all -Import-Name: idna - -# Internationalized Domain Names in Applications (IDNA) - -Support for [Internationalized Domain Names in Applications -(IDNA)](https://tools.ietf.org/html/rfc5891) and [Unicode IDNA -Compatibility Processing](https://unicode.org/reports/tr46/). It -supersedes the standard library's `encodings.idna`, which only -implements the 2003 specification, offering broader script coverage and -limiting domains with known security vulnerabilities. - -## Usage - -Package may be installed from [PyPI](https://pypi.org/project/idna/) via -the typical methods (e.g. `python3 -m pip install idna`) - -For typical usage, the `encode` and `decode` functions will take a -domain name argument and perform a conversion to ASCII-compatible encoding -(known as A-labels), or to Unicode strings (known as U-labels) -respectively. - -```pycon ->>> import idna ->>> idna.encode('ドメイン.テスト') -b'xn--eckwd4c7c.xn--zckzah' ->>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) -ドメイン.テスト -``` - -Conversions can be applied at a per-label basis using the `ulabel` or -`alabel` functions for specialized use cases. - - -### Compatibility Mapping (UTS #46) - -This library provides support for [Unicode IDNA Compatibility -Processing](https://unicode.org/reports/tr46/) which normalizes input from -different potential ways a user may input a domain prior to performing the IDNA -conversion operations. This functionality, known as a -[mapping](https://tools.ietf.org/html/rfc5895), is considered by the -specification to be a local user-interface issue distinct from IDNA -conversion functionality. - -For example, "Königsgäßchen" is not a permissible label as capital letters -are not allowed. UTS #46 will convert this into lower case prior to applying -the IDNA conversion. - -```pycon ->>> import idna ->>> idna.encode('Königsgäßchen') -... -idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed ->>> idna.encode('Königsgäßchen', uts46=True) -b'xn--knigsgchen-b4a3dun' ->>> idna.decode('xn--knigsgchen-b4a3dun') -'königsgäßchen' -``` - -When performing a decode operation for display purposes, `decode()` -accepts a `display=True` argument that leaves any `xn--` label that -fails to decode unchanged. This is useful for user interface display -where a domain is in use, the A-label form can be presented when it -is not a valid IDN. - - -## Exceptions - -All errors raised during conversion derive from the `idna.IDNAError` -base class. The more specific exceptions are: - -* `idna.IDNABidiError` — raised when a label contains an illegal - combination of left-to-right and right-to-left characters. -* `idna.InvalidCodepoint` — raised when a label contains a codepoint - that is INVALID for IDNA. -* `idna.InvalidCodepointContext` — raised when a CONTEXTO or CONTEXTJ - codepoint appears in a position whose contextual requirements are - not satisfied. - -Exceptions carry machine-readable attributes so that applications do -not need to parse the message: `code` is a short, stable identifier -for the rule that failed (such as `disallowed_codepoint` or -`label_too_long`); and, when the failure can be attributed to a -particular character, `text` (the label or domain being validated), -`codepoint` (the offending codepoint as an integer) and `position` -are set. - - -## Command-line tool - -The package supports command-line usage to convert domain names -between their Unicode and ASCII-compatible forms. It can be run either -as a module (`python3 -m idna`) or, once installed (such as with `uv -tool` or `pipx`), via the `idna` script: - -```bash -$ uv tool install idna -$ idna xn--e1afmkfd.xn--p1ai -пример.рф -$ idna пример.рф -xn--e1afmkfd.xn--p1ai -``` - -Mode can be specified with `-e`/`--encode` or `-d`/`--decode`, otherwise -it will be chosen automatically based on the first input. Multiple -domains can be supplied either as arguments or through standard input. -UTS #46 mapping is applied by default, which lets the tool accept -inputs that aren't strictly valid IDNA 2008 by normalising them first, -pass `--strict` to disable UTS #46. - -Conversion failures are reported on stderr together with the -offending input; processing continues with the remaining domains and -the tool exits with a non-zero status if any conversion failed. - - -## Additional Notes - -* **Python version support**. This library supports Python 3.9 and higher. - As this library serves as a low-level toolkit for a variety of - applications, we strive to support all versions of Python that are - not beyond end-of-life. Free-threaded Python is also supported, - as the library holds no mutable global state the functions can be - called concurrently from multiple threads. - -* **Unicode version**. The IDNA and UTS #46 lookup tables are generated - from a specific Unicode release. Some Unicode data depends on the - running Python's `unicodedata` module, so on an older Python a - character new to Unicode may be rejected as unknown even if this - library knows about it. - -* **Emoji**. It is an occasional request to support emoji domains in - this library. Encoding of symbols like emoji is expressly prohibited by - the IDNA technical standard, and emoji domains are broadly phased - out across the domain industry due to associated security risks. - -* **Regenerating lookup tables**. The IDNA and UTS #46 functionality - relies upon pre-calculated lookup tables, generated using the - `idna-data` script in [`tools/`](tools/README.md). - diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA deleted file mode 100644 index b4fbdfc3362..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/METADATA +++ /dev/null @@ -1,43 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-api -Version: 1.45.2 -Summary: OpenTelemetry Python API -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-api -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 5 - Production/Stable -Classifier: Framework :: OpenTelemetry -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Typing :: Typed -Requires-Python: >=3.10 -Requires-Dist: typing-extensions>=4.5.0 -Description-Content-Type: text/x-rst - -OpenTelemetry Python API -============================================================================ - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-api.svg - :target: https://pypi.org/project/opentelemetry-api/ - -Installation ------------- - -:: - - pip install opentelemetry-api - -References ----------- - -* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt deleted file mode 100644 index cbeb844d96f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_api-1.45.2.dist-info/entry_points.txt +++ /dev/null @@ -1,15 +0,0 @@ -[opentelemetry_context] -contextvars_context = opentelemetry.agent._vendor.opentelemetry.context.contextvars_context:ContextVarsRuntimeContext - -[opentelemetry_environment_variables] -api = opentelemetry.agent._vendor.opentelemetry.environment_variables - -[opentelemetry_meter_provider] -default_meter_provider = opentelemetry.agent._vendor.opentelemetry.metrics:NoOpMeterProvider - -[opentelemetry_propagator] -baggage = opentelemetry.agent._vendor.opentelemetry.baggage.propagation:W3CBaggagePropagator -tracecontext = opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext:TraceContextTextMapPropagator - -[opentelemetry_tracer_provider] -default_tracer_provider = opentelemetry.agent._vendor.opentelemetry.trace:NoOpTracerProvider diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA deleted file mode 100644 index f994cf53667..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_configuration-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,73 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-configuration -Version: 0.66b2 -Summary: OpenTelemetry Python Declarative Configuration (experimental) -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-configuration -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -Classifier: Development Status :: 3 - Alpha -Classifier: Framework :: OpenTelemetry -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Typing :: Typed -Requires-Python: >=3.10 -Requires-Dist: jsonschema>=4.0 -Requires-Dist: opentelemetry-api==1.45.2 -Requires-Dist: opentelemetry-sdk==1.45.2 -Requires-Dist: pyyaml>=5.4 -Description-Content-Type: text/x-rst - -OpenTelemetry Python SDK Declarative Configuration -=================================================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-configuration.svg - :target: https://pypi.org/project/opentelemetry-configuration/ - -.. warning:: - - This package is **experimental**. The API surface, type names, and behaviour - may change between minor versions. Pin a specific version in production. - -This package implements the `OpenTelemetry declarative configuration -specification `_ for -the Python SDK. It parses a YAML or JSON configuration file (or -programmatically-constructed configuration model) into typed dataclasses and -applies the result to the global SDK providers. - -The standard activation path is the ``OTEL_CONFIG_FILE`` environment variable, -which the SDK's configurator picks up automatically. Set the variable and run -your app under ``opentelemetry-instrument``; no code change is required. - -For programmatic use: - -.. code-block:: python - - from opentelemetry.configuration import configure_sdk, load_config_file - - config = load_config_file("otel-config.yaml") - configure_sdk(config) - -Installation ------------- - -:: - - pip install opentelemetry-configuration - -References ----------- - -* `OpenTelemetry declarative configuration specification - `_ -* `Language support status matrix - `_ -* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA deleted file mode 100644 index 8d5e3a7a367..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,50 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-distro -Version: 0.66b2 -Summary: OpenTelemetry Python Distro -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-distro -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Typing :: Typed -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api~=1.12 -Requires-Dist: opentelemetry-instrumentation==0.66b2 -Requires-Dist: opentelemetry-sdk~=1.13 -Provides-Extra: otlp -Requires-Dist: opentelemetry-exporter-otlp==1.45.2; extra == 'otlp' -Description-Content-Type: text/x-rst - -OpenTelemetry Distro -==================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-distro.svg - :target: https://pypi.org/project/opentelemetry-distro/ - -Installation ------------- - -:: - - pip install opentelemetry-distro - - -This package provides entrypoints to configure OpenTelemetry. - -References ----------- - -* `OpenTelemetry Project `_ -* `Example using opentelemetry-distro `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt deleted file mode 100644 index fe9f6356a4e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_distro-0.66b2.dist-info/entry_points.txt +++ /dev/null @@ -1,5 +0,0 @@ -[opentelemetry_configurator] -configurator = opentelemetry.agent._vendor.opentelemetry.distro:OpenTelemetryConfigurator - -[opentelemetry_distro] -distro = opentelemetry.agent._vendor.opentelemetry.distro:OpenTelemetryDistro diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA deleted file mode 100644 index c997785745a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,64 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-http-transport -Version: 0.66b2 -Summary: OpenTelemetry Exporters HTTP transport -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-http-transport -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api~=1.15 -Provides-Extra: requests -Requires-Dist: requests~=2.25; extra == 'requests' -Provides-Extra: urllib3 -Requires-Dist: urllib3>=1.26; extra == 'urllib3' -Description-Content-Type: text/x-rst - -OpenTelemetry Exporters HTTP Transport -====================================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-http-transport.svg - :target: https://pypi.org/project/opentelemetry-exporter-http-transport/ - -This package provides shared HTTP transport abstractions used by OpenTelemetry exporters. - -The package has **no required dependencies**. The ``requests`` and ``urllib3`` -transports are available as optional extras. - -Installation ------------- - -Core package (no HTTP backend included):: - - pip install opentelemetry-exporter-http-transport - -With the ``requests`` backend:: - - pip install opentelemetry-exporter-http-transport[requests] - -With the ``urllib3`` backend:: - - pip install opentelemetry-exporter-http-transport[urllib3] - - -References ----------- - -* `OpenTelemetry `_ -* `OpenTelemetry Protocol Specification `_ -* `requests `_ -* `urllib3 `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt deleted file mode 100644 index db7882341ec..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_http_transport-0.66b2.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[opentelemetry_http_transport] -requests = opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._requests:RequestsHTTPTransport -urllib3 = opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._urllib3:Urllib3HTTPTransport diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA deleted file mode 100644 index 968b0660afc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_common-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,52 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-otlp-common -Version: 0.66b2 -Summary: OpenTelemetry OTLP HTTP export utilities -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-common -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-sdk~=1.45.2 -Provides-Extra: http -Requires-Dist: opentelemetry-exporter-http-transport==0.66b2; extra == 'http' -Description-Content-Type: text/x-rst - -OpenTelemetry OTLP Utilities -=============================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-common.svg - :target: https://pypi.org/project/opentelemetry-exporter-otlp-common/ - -OpenTelemetry OTLP export utilities. - -This package is intended to be used by OpenTelemetry signal exporters (traces, metrics, -logs) that send telemetry with OTLP. Currently, all functionality in this package -is marked as internal and is not intended for use directly by application developers. - -Installation ------------- - -:: - - pip install opentelemetry-exporter-otlp-common - -References ----------- - -* `OpenTelemetry `_ -* `OTLP Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA deleted file mode 100644 index f8cefaafa0a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_common-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,48 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-otlp-json-common -Version: 0.66b2 -Summary: OpenTelemetry JSON encoding -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-json-common -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-proto-json==0.66b2 -Requires-Dist: opentelemetry-sdk~=1.45.2 -Description-Content-Type: text/x-rst - -OpenTelemetry JSON Encoding -=============================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-json-common.svg - :target: https://pypi.org/project/opentelemetry-exporter-otlp-json-common/ - -This library is provided as a convenience to encode to OTLP JSON. - -Installation ------------- - -:: - - pip install opentelemetry-exporter-otlp-json-common - - -References ----------- - -* `OpenTelemetry `_ -* `OpenTelemetry Protocol Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA deleted file mode 100644 index 96439e059d4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,56 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-otlp-json-file -Version: 0.66b2 -Summary: OpenTelemetry JSON File Exporter -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-json-file -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-exporter-otlp-common==0.66b2 -Requires-Dist: opentelemetry-exporter-otlp-json-common==0.66b2 -Requires-Dist: opentelemetry-sdk~=1.45.2 -Description-Content-Type: text/x-rst - -OpenTelemetry JSON File Exporter -================================ - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-json-file.svg - :target: https://pypi.org/project/opentelemetry-exporter-otlp-json-file/ - -This library exports telemetry as OTLP JSON to a file-like text stream, such -as a file or stdout. - -The exporter writes newline delimited OTLP JSON records for file-based -collection workflows. - -Installation ------------- - -:: - - pip install opentelemetry-exporter-otlp-json-file - - -References ----------- - -* `OpenTelemetry Project `_ -* `OpenTelemetry Protocol File Exporter `_ -* `OTLP Specification `_ -* `OTLP JSON Encoding Specification `_ -* `JSON Lines `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt deleted file mode 100644 index e4216b3db77..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_file-0.66b2.dist-info/entry_points.txt +++ /dev/null @@ -1,8 +0,0 @@ -[opentelemetry_logs_exporter] -otlp_json_file = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._log_exporter:FileLogExporter - -[opentelemetry_metrics_exporter] -otlp_json_file = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.metric_exporter:FileMetricExporter - -[opentelemetry_traces_exporter] -otlp_json_file = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.trace_exporter:FileSpanExporter diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA deleted file mode 100644 index 243c38d1f7a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,85 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-otlp-json-http -Version: 0.66b2 -Summary: OpenTelemetry OTLP JSON Exporter -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-json-http -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-exporter-http-transport[urllib3]==0.66b2 -Requires-Dist: opentelemetry-exporter-otlp-common==0.66b2 -Requires-Dist: opentelemetry-exporter-otlp-json-common==0.66b2 -Requires-Dist: opentelemetry-proto-json==0.66b2 -Requires-Dist: opentelemetry-sdk~=1.45.2 -Description-Content-Type: text/x-rst - -OpenTelemetry Collector JSON over HTTP Exporter -================================================ - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-json-http.svg - :target: https://pypi.org/project/opentelemetry-exporter-otlp-json-http/ - -This library exports OpenTelemetry traces, metrics and logs using the -OpenTelemetry Protocol (OTLP) JSON encoding over HTTP. It can be used to -send data to any backend that accepts OTLP JSON such as the OpenTelemetry -Collector. - -Installation ------------- - -:: - - pip install opentelemetry-exporter-otlp-json-http - - -Usage ------ - -.. code:: python - - from opentelemetry import trace - from opentelemetry.exporter.otlp.json.http import OTLPSpanExporter - from opentelemetry.sdk.resources import Resource - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import BatchSpanProcessor - - resource = Resource.create({ - "service.name": "service" - }) - - trace.set_tracer_provider(TracerProvider(resource=resource)) - tracer = trace.get_tracer(__name__) - - otlp_exporter = OTLPSpanExporter() - - span_processor = BatchSpanProcessor(otlp_exporter) - - trace.get_tracer_provider().add_span_processor(span_processor) - - with tracer.start_as_current_span("foo"): - print("Hello world!") - - -References ----------- - -* `OpenTelemetry OTLP Exporters `_ -* `OpenTelemetry Collector `_ -* `OpenTelemetry `_ -* `OpenTelemetry Protocol Specification `_ -* `OTLP JSON Encoding Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt deleted file mode 100644 index 7b536dbd717..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_json_http-0.66b2.dist-info/entry_points.txt +++ /dev/null @@ -1,8 +0,0 @@ -[opentelemetry_logs_exporter] -otlp_json_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._log_exporter:OTLPLogExporter - -[opentelemetry_metrics_exporter] -otlp_json_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.metric_exporter:OTLPMetricExporter - -[opentelemetry_traces_exporter] -otlp_json_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.trace_exporter:OTLPSpanExporter diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA deleted file mode 100644 index fccb1c28a26..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_common-1.45.2.dist-info/METADATA +++ /dev/null @@ -1,51 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-otlp-proto-common -Version: 1.45.2 -Summary: OpenTelemetry Protobuf encoding -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-common -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 5 - Production/Stable -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-proto==1.45.2 -Description-Content-Type: text/x-rst - -OpenTelemetry Protobuf Encoding -=============================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-proto-common.svg - :target: https://pypi.org/project/opentelemetry-exporter-otlp-proto-common/ - -This library is provided as a convenience to encode to Protobuf. Currently used by: - -* opentelemetry-exporter-otlp-proto-grpc -* opentelemetry-exporter-otlp-proto-http - - -Installation ------------- - -:: - - pip install opentelemetry-exporter-otlp-proto-common - - -References ----------- - -* `OpenTelemetry `_ -* `OpenTelemetry Protocol Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA deleted file mode 100644 index f954db2a7de..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/METADATA +++ /dev/null @@ -1,71 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-otlp-proto-http -Version: 1.45.2 -Summary: OpenTelemetry Collector Protobuf over HTTP Exporter -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-otlp-proto-http -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 5 - Production/Stable -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: googleapis-common-protos~=1.52 -Requires-Dist: opentelemetry-api~=1.15 -Requires-Dist: opentelemetry-exporter-http-transport[requests]==0.66b2 -Requires-Dist: opentelemetry-exporter-otlp-common==0.66b2 -Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.45.2 -Requires-Dist: opentelemetry-proto==1.45.2 -Requires-Dist: opentelemetry-sdk~=1.45.2 -Requires-Dist: requests~=2.7 -Requires-Dist: typing-extensions>=4.5.0 -Provides-Extra: gcp-auth -Requires-Dist: opentelemetry-exporter-credential-provider-gcp>=0.59b0; extra == 'gcp-auth' -Provides-Extra: requests -Requires-Dist: opentelemetry-exporter-http-transport[requests]==0.66b2; extra == 'requests' -Requires-Dist: requests~=2.7; extra == 'requests' -Description-Content-Type: text/x-rst - -OpenTelemetry Collector Protobuf over HTTP Exporter -=================================================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-otlp-proto-http.svg - :target: https://pypi.org/project/opentelemetry-exporter-otlp-proto-http/ - -This library allows to export data to the OpenTelemetry Collector using the OpenTelemetry Protocol using Protobuf over HTTP. - -Installation ------------- - -:: - - pip install opentelemetry-exporter-otlp-proto-http - -To use a custom ``requests.Session`` (for example to configure authentication), pass it to the exporter: - -.. code-block:: python - - import requests - from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter - - exporter = OTLPSpanExporter(session=requests.Session()) - - -References ----------- - -* `OpenTelemetry Collector Exporter `_ -* `OpenTelemetry Collector `_ -* `OpenTelemetry `_ -* `OpenTelemetry Protocol Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt deleted file mode 100644 index 90e636b44ff..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_otlp_proto_http-1.45.2.dist-info/entry_points.txt +++ /dev/null @@ -1,8 +0,0 @@ -[opentelemetry_logs_exporter] -otlp_proto_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._log_exporter:OTLPLogExporter - -[opentelemetry_metrics_exporter] -otlp_proto_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.metric_exporter:OTLPMetricExporter - -[opentelemetry_traces_exporter] -otlp_proto_http = opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.trace_exporter:OTLPSpanExporter diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA deleted file mode 100644 index 0f52dc8a6d5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,54 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-exporter-prometheus -Version: 0.66b2 -Summary: Prometheus Metric Exporter for OpenTelemetry -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/exporter/opentelemetry-exporter-prometheus -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Framework :: OpenTelemetry -Classifier: Framework :: OpenTelemetry :: Exporters -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api~=1.12 -Requires-Dist: opentelemetry-sdk~=1.45.2 -Requires-Dist: prometheus-client<1.0.0,>=0.5.0 -Description-Content-Type: text/x-rst - -OpenTelemetry Prometheus Exporter -================================= - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-exporter-prometheus.svg - :target: https://pypi.org/project/opentelemetry-exporter-prometheus/ - -This library allows to export metrics data to `Prometheus `_. - -Installation ------------- - -:: - - pip install opentelemetry-exporter-prometheus - -Limitations ------------ - -* No multiprocessing support: The Prometheus exporter is not designed to operate in multiprocessing environments (see `#3747 `_). - -References ----------- - -* `OpenTelemetry Prometheus Exporter `_ -* `Prometheus `_ -* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt deleted file mode 100644 index 8c6d2fe3079..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_exporter_prometheus-0.66b2.dist-info/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -[opentelemetry_metrics_exporter] -prometheus = opentelemetry.agent._vendor.opentelemetry.exporter.prometheus:_AutoPrometheusMetricReader diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA deleted file mode 100644 index ed292af545f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,183 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-instrumentation -Version: 0.66b2 -Summary: Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/opentelemetry-instrumentation -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api~=1.4 -Requires-Dist: opentelemetry-semantic-conventions==0.66b2 -Requires-Dist: packaging>=18.0 -Requires-Dist: wrapt<3.0.0,>=1.0.0 -Description-Content-Type: text/x-rst - -OpenTelemetry Instrumentation -============================= - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation.svg - :target: https://pypi.org/project/opentelemetry-instrumentation/ - -Installation ------------- - -:: - - pip install opentelemetry-instrumentation - - -This package provides commands that help automatically instrument a program: - -.. note:: - You need to install a distro package to get auto instrumentation working. The ``opentelemetry-distro`` - package contains the default distro and configurator and automatically configures some of the common options for users. - For more info about ``opentelemetry-distro`` check `here `__ - :: - - pip install "opentelemetry-distro[otlp]" - - When creating a custom distro and/or configurator, be sure to add entry points for each under ``opentelemetry_distro`` and ``opentelemetry_configurator`` respectfully. - If you have entry points for multiple distros or configurators present in your environment, you should specify the entry point name of the distro and configurator you want to be used via the ``OTEL_PYTHON_DISTRO`` and ``OTEL_PYTHON_CONFIGURATOR`` environment variables. - - -opentelemetry-bootstrap ------------------------ - -:: - - opentelemetry-bootstrap [-a |--action=][install|requirements] - -This command install default instrumentation packages and detects active Python site-packages -to figure out which instrumentation packages the user might want to install. By default, it -prints out a list of the default and detected instrumentation packages that can be added to a -requirements.txt file. It also supports installing the packages when run with -:code:`--action=install` or :code:`-a install` flag. All default and detectable -instrumentation packages are defined `here `__. - - -opentelemetry-instrument ------------------------- - -:: - - opentelemetry-instrument python program.py - -The instrument command will try to automatically detect packages used by your python program -and when possible, apply automatic tracing instrumentation on them. This means your program -will get automatic distributed tracing without having to make any code changes. This will -also configure a global tracer and tracing exporter as well as a meter and meter exporter. -By default, the instrument command will use the OTLP exporter but this can be overridden. - -The command supports the following configuration options as CLI arguments and environment -variables: - - -* ``--traces_exporter`` or ``OTEL_TRACES_EXPORTER`` -* ``--metrics_exporter`` or ``OTEL_METRICS_EXPORTER`` -* ``--distro`` or ``OTEL_PYTHON_DISTRO`` -* ``--configurator`` or ``OTEL_PYTHON_CONFIGURATOR`` - -The exporter options define what exporter destination to use and can be set to one or more -exporter names (see below). You can pass multiple values to configure multiple exporters -(e.g., ``zipkin_json,otlp``). - - - Defaults to ``otlp``. - - Can be set to ``none`` to disable automatic tracer initialization. - - Can be set to ``console`` to display JSON results locally. - -Trace exporter names: - - - jaeger_proto - - jaeger_thrift - - opencensus - - otlp - - otlp_proto_grpc (``deprecated``) - - otlp_proto_http (``deprecated``) - - zipkin_json - - zipkin_proto - -Metric exporter names: - - - otlp - - otlp_proto_grpc (``deprecated``) - - prometheus - -Note: The default transport protocol for ``otlp`` is gRPC. - -* ``--id-generator`` or ``OTEL_PYTHON_ID_GENERATOR`` - -Used to specify which IDs Generator to use for the global Tracer Provider. By default, it -will use the random IDs generator. - -The code in ``program.py`` needs to use one of the packages for which there is -an OpenTelemetry integration. For a list of the available integrations please -check `here `_ - -* ``OTEL_PYTHON_DISABLED_INSTRUMENTATIONS`` - -If set by the user, opentelemetry-instrument will read this environment variable to disable specific instrumentations. -e.g OTEL_PYTHON_DISABLED_INSTRUMENTATIONS="requests,django" - -If the variables contains ``*`` as member no instrumentation will be enabled. - -* ``OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH`` - -If set by the user to ``patch_all`` , opentelemetry instrument will call the gevent monkeypatching method ``patch_all``. -This is considered experimental but can be useful to instrument gevent applications. -e.g OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH=patch_all - - -Examples -^^^^^^^^ - -:: - - opentelemetry-instrument --traces_exporter console flask run --port=3000 - -The above command will pass ``--traces_exporter console`` to the instrument command and ``--port=3000`` to ``flask run``. - -:: - - opentelemetry-instrument --traces_exporter zipkin_json,otlp celery -A tasks worker --loglevel=info - -The above command will configure global trace provider, attach zipkin and otlp exporters to it and then -start celery with the rest of the arguments. - -:: - - opentelemetry-instrument --id_generator random flask run --port=3000 - -The above command will configure the global trace provider to use the Random IDs Generator, and then -pass ``--port=3000`` to ``flask run``. - -Programmatic Auto-instrumentation ---------------------------------- - -:: - - from opentelemetry.instrumentation import auto_instrumentation - auto_instrumentation.initialize() - - -If you are in an environment where you cannot use opentelemetry-instrument to inject auto-instrumentation you can do so programmatically with -the code above. Please note that some instrumentations may require the ``initialize()`` method to be called before the library they -instrument is imported. - -References ----------- - -* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt deleted file mode 100644 index bc231f53300..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation-0.66b2.dist-info/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -[opentelemetry_environment_variables] -instrumentation = opentelemetry.agent._vendor.opentelemetry.instrumentation.environment_variables diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA deleted file mode 100644 index c8a15ebe07c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,54 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-instrumentation-aiohttp-client -Version: 0.66b2 -Summary: OpenTelemetry aiohttp client instrumentation -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-aiohttp-client -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api~=1.12 -Requires-Dist: opentelemetry-instrumentation==0.66b2 -Requires-Dist: opentelemetry-semantic-conventions==0.66b2 -Requires-Dist: opentelemetry-util-http==0.66b2 -Requires-Dist: wrapt<3.0.0,>=1.0.0 -Provides-Extra: instruments -Requires-Dist: aiohttp~=3.0; extra == 'instruments' -Description-Content-Type: text/x-rst - -OpenTelemetry aiohttp client Integration -======================================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-aiohttp-client.svg - :target: https://pypi.org/project/opentelemetry-instrumentation-aiohttp-client/ - -This library allows tracing HTTP requests made by the -`aiohttp client `_ library. - -Installation ------------- - -:: - - pip install opentelemetry-instrumentation-aiohttp-client - -References ----------- - -* `OpenTelemetry aiohttp client Instrumentation `_ -* `aiohttp Tracing Reference `_ -* `OpenTelemetry Project `_ -* `OpenTelemetry Python Examples `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt deleted file mode 100644 index 36da1631192..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_instrumentation_aiohttp_client-0.66b2.dist-info/entry_points.txt +++ /dev/null @@ -1,2 +0,0 @@ -[opentelemetry_instrumentor] -aiohttp-client = opentelemetry.agent._vendor.opentelemetry.instrumentation.aiohttp_client:AioHttpClientInstrumentor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA deleted file mode 100644 index 33116e71c92..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/METADATA +++ /dev/null @@ -1,48 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-propagator-b3 -Version: 1.45.2 -Summary: OpenTelemetry B3 Propagator -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/propagator/opentelemetry-propagator-b3 -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 5 - Production/Stable -Classifier: Framework :: OpenTelemetry -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Typing :: Typed -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api~=1.3 -Requires-Dist: typing-extensions>=4.5.0 -Description-Content-Type: text/x-rst - -OpenTelemetry B3 Propagator -=========================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-propagator-b3.svg - :target: https://pypi.org/project/opentelemetry-propagator-b3/ - -This library provides a propagator for the B3 format - -Installation ------------- - -:: - - pip install opentelemetry-propagator-b3 - - -References ----------- - -* `OpenTelemetry `_ -* `B3 format `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt deleted file mode 100644 index c3eb07abc06..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_propagator_b3-1.45.2.dist-info/entry_points.txt +++ /dev/null @@ -1,3 +0,0 @@ -[opentelemetry_propagator] -b3 = opentelemetry.agent._vendor.opentelemetry.propagators.b3:B3SingleFormat -b3multi = opentelemetry.agent._vendor.opentelemetry.propagators.b3:B3MultiFormat diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA deleted file mode 100644 index 9c4992f10ba..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto-1.45.2.dist-info/METADATA +++ /dev/null @@ -1,63 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-proto -Version: 1.45.2 -Summary: OpenTelemetry Python Proto -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-proto -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 5 - Production/Stable -Classifier: Framework :: OpenTelemetry -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: protobuf<8.0,>=5.0 -Description-Content-Type: text/x-rst - -OpenTelemetry Python Proto -========================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-proto.svg - :target: https://pypi.org/project/opentelemetry-proto/ - -This library contains the generated code for OpenTelemetry protobuf data model. The code in the current -package was generated using the v1.10.0 release_ of opentelemetry-proto. - -.. _release: https://github.com/open-telemetry/opentelemetry-proto/releases/tag/v1.10.0 - -Installation ------------- - -:: - - pip install opentelemetry-proto - -Code Generation ---------------- - -These files were generated automatically from code in opentelemetry-proto_. -To regenerate the code, run ``../scripts/proto_codegen.sh``. - -To build against a new release or specific commit of opentelemetry-proto_, -update the ``PROTO_REPO_BRANCH_OR_COMMIT`` variable in -``../scripts/proto_codegen.sh``. Then run the script and commit the changes -as well as any fixes needed in the OTLP exporter. - -.. _opentelemetry-proto: https://github.com/open-telemetry/opentelemetry-proto - - -References ----------- - -* `OpenTelemetry Project `_ -* `OpenTelemetry Proto `_ -* `proto_codegen.sh script `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA deleted file mode 100644 index 6ed6c74c2e0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_proto_json-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,61 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-proto-json -Version: 0.66b2 -Summary: OpenTelemetry Python Json Proto -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-proto-json -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 4 - Beta -Classifier: Framework :: OpenTelemetry -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Description-Content-Type: text/x-rst - -OpenTelemetry Python Proto JSON -================================ - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-proto-json.svg - :target: https://pypi.org/project/opentelemetry-proto-json/ - -This library contains the generated code for OpenTelemetry protobuf data model with JSON encoding support. The code in the current package was generated using the v1.10.0 release_ of opentelemetry-proto and includes definitions for the OpenTelemetry JSON Protobuf encoding specification. - -.. _release: https://github.com/open-telemetry/opentelemetry-proto/releases/tag/v1.10.0 - -Installation ------------- - -:: - - pip install opentelemetry-proto-json - -Code Generation ---------------- - -These files were generated automatically using the custom protoc plugin opentelemetry-codegen-json_ from code in opentelemetry-proto_. -To regenerate the code, run ``../scripts/proto_codegen_json.sh``. - -To build against a new release or specific commit of opentelemetry-proto_, -update the ``PROTO_REPO_BRANCH_OR_COMMIT`` variable in -``../scripts/proto_codegen_json.sh``. Then run the script and commit the changes -as well as any fixes needed in the OTLP exporter. - -.. _opentelemetry-codegen-json: https://github.com/open-telemetry/opentelemetry-python/tree/main/codegen/opentelemetry-codegen-json -.. _opentelemetry-proto: https://github.com/open-telemetry/opentelemetry-proto - -References ----------- - -* `OpenTelemetry Project `_ -* `OpenTelemetry Proto `_ -* `OTLP JSON Encoding Specification `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA deleted file mode 100644 index 1d729d35c7f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/METADATA +++ /dev/null @@ -1,47 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-sdk -Version: 1.45.2 -Summary: OpenTelemetry Python SDK -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-sdk -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 5 - Production/Stable -Classifier: Framework :: OpenTelemetry -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Typing :: Typed -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api==1.45.2 -Requires-Dist: opentelemetry-semantic-conventions==0.66b2 -Requires-Dist: typing-extensions>=4.5.0 -Provides-Extra: file-configuration -Requires-Dist: opentelemetry-configuration==0.66b2; extra == 'file-configuration' -Description-Content-Type: text/x-rst - -OpenTelemetry Python SDK -============================================================================ - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-sdk.svg - :target: https://pypi.org/project/opentelemetry-sdk/ - -Installation ------------- - -:: - - pip install opentelemetry-sdk - -References ----------- - -* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt deleted file mode 100644 index cd7169588ba..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_sdk-1.45.2.dist-info/entry_points.txt +++ /dev/null @@ -1,38 +0,0 @@ -[opentelemetry_environment_variables] -sdk = opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables - -[opentelemetry_id_generator] -random = opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator:RandomIdGenerator - -[opentelemetry_logger_provider] -sdk_logger_provider = opentelemetry.agent._vendor.opentelemetry.sdk._logs:LoggerProvider - -[opentelemetry_logs_exporter] -console = opentelemetry.agent._vendor.opentelemetry.sdk._logs.export:ConsoleLogRecordExporter - -[opentelemetry_meter_provider] -sdk_meter_provider = opentelemetry.agent._vendor.opentelemetry.sdk.metrics:MeterProvider - -[opentelemetry_metrics_exporter] -console = opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export:ConsoleMetricExporter - -[opentelemetry_resource_detector] -host = opentelemetry.agent._vendor.opentelemetry.sdk.resources:_HostResourceDetector -os = opentelemetry.agent._vendor.opentelemetry.sdk.resources:OsResourceDetector -otel = opentelemetry.agent._vendor.opentelemetry.sdk.resources:OTELResourceDetector -process = opentelemetry.agent._vendor.opentelemetry.sdk.resources:ProcessResourceDetector -service_instance = opentelemetry.agent._vendor.opentelemetry.sdk.resources:ServiceInstanceIdResourceDetector - -[opentelemetry_tracer_provider] -sdk_tracer_provider = opentelemetry.agent._vendor.opentelemetry.sdk.trace:TracerProvider - -[opentelemetry_traces_exporter] -console = opentelemetry.agent._vendor.opentelemetry.sdk.trace.export:ConsoleSpanExporter - -[opentelemetry_traces_sampler] -always_off = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_AlwaysOff -always_on = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_AlwaysOn -parentbased_always_off = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_ParentBasedAlwaysOff -parentbased_always_on = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:_ParentBasedAlwaysOn -parentbased_traceidratio = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:ParentBasedTraceIdRatio -traceidratio = opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling:TraceIdRatioBased diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA deleted file mode 100644 index 86aaf5fd11f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_semantic_conventions-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,61 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-semantic-conventions -Version: 0.66b2 -Summary: OpenTelemetry Semantic Conventions -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python/tree/main/opentelemetry-semantic-conventions -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -License-File: LICENSE -Classifier: Development Status :: 5 - Production/Stable -Classifier: Framework :: OpenTelemetry -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Requires-Dist: opentelemetry-api==1.45.2 -Requires-Dist: typing-extensions>=4.5.0 -Description-Content-Type: text/x-rst - -OpenTelemetry Semantic Conventions -================================== - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-semantic-conventions.svg - :target: https://pypi.org/project/opentelemetry-semantic-conventions/ - -This library contains generated code for the semantic conventions defined by the OpenTelemetry specification. - -Installation ------------- - -:: - - pip install opentelemetry-semantic-conventions - -Code Generation ---------------- - -These files were generated automatically from code in semconv_. -To regenerate the code, run ``../scripts/semconv/generate.sh``. - -To build against a new release or specific commit of opentelemetry-specification_, -update the ``SPEC_VERSION`` variable in -``../scripts/semconv/generate.sh``. Then run the script and commit the changes. - -.. _opentelemetry-specification: https://github.com/open-telemetry/opentelemetry-specification -.. _semconv: https://github.com/open-telemetry/opentelemetry-python/tree/main/scripts/semconv - - -References ----------- - -* `OpenTelemetry Project `_ -* `OpenTelemetry Semantic Conventions Definitions `_ -* `generate.sh script `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA deleted file mode 100644 index 4daea2c52c7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/opentelemetry_util_http-0.66b2.dist-info/METADATA +++ /dev/null @@ -1,93 +0,0 @@ -Metadata-Version: 2.5 -Name: opentelemetry-util-http -Version: 0.66b2 -Summary: Web util for OpenTelemetry -Project-URL: Homepage, https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/util/opentelemetry-util-http -Project-URL: Repository, https://github.com/open-telemetry/opentelemetry-python-contrib -Author-email: OpenTelemetry Authors -License-Expression: Apache-2.0 -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Description-Content-Type: text/x-rst - -OpenTelemetry Util HTTP -======================= - -|pypi| - -.. |pypi| image:: https://badge.fury.io/py/opentelemetry-util-http.svg - :target: https://pypi.org/project/opentelemetry-util-http/ - - -This library provides ASGI, WSGI middleware and other HTTP-related -functionality that is common to instrumented web frameworks (such as Django, -Starlette, FastAPI, etc.) to track requests timing through OpenTelemetry. - -Installation ------------- - -:: - - pip install opentelemetry-util-http - - -Usage (Quart) -------------- - -.. code-block:: python - - from quart import Quart - from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware - - app = Quart(__name__) - app.asgi_app = OpenTelemetryMiddleware(app.asgi_app) - - @app.route("/") - async def hello(): - return "Hello!" - - if __name__ == "__main__": - app.run(debug=True) - - -Usage (Django 3.0) ------------------- - -Modify the application's ``asgi.py`` file as shown below. - -.. code-block:: python - - import os - from django.core.asgi import get_asgi_application - from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware - - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'asgi_example.settings') - - application = get_asgi_application() - application = OpenTelemetryMiddleware(application) - - -Usage (Raw ASGI) ----------------- - -.. code-block:: python - - from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware - - app = ... # An ASGI application. - app = OpenTelemetryMiddleware(app) - - -References ----------- - -* `OpenTelemetry Project `_ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA deleted file mode 100644 index 9a85a75b1f5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/packaging-26.3.dist-info/METADATA +++ /dev/null @@ -1,112 +0,0 @@ -Metadata-Version: 2.4 -Name: packaging -Version: 26.3 -Summary: Core utilities for Python packages -Author-email: Donald Stufft -Requires-Python: >=3.9 -Description-Content-Type: text/x-rst -License-Expression: Apache-2.0 OR BSD-2-Clause -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: 3.15 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient -Classifier: Typing :: Typed -License-File: LICENSE -License-File: LICENSE.APACHE -License-File: LICENSE.BSD -Project-URL: Documentation, https://packaging.pypa.io/ -Project-URL: Source, https://github.com/pypa/packaging - -packaging -========= - -.. start-intro - -Reusable core utilities for various Python Packaging -`interoperability specifications `_. - -This library provides utilities that implement the interoperability -specifications which have clearly one correct behaviour (eg: :pep:`440`) -or benefit greatly from having a single shared implementation (eg: :pep:`425`). - -.. end-intro - -The ``packaging`` project includes the following: version handling, specifiers, -markers, requirements, tags, metadata, lockfiles, utilities. - -Documentation -------------- - -The `documentation`_ provides information and the API for the following: - -- Version Handling -- Specifiers -- Markers -- Licenses -- Requirements -- Metadata -- Tags -- Lockfiles (pylock) -- Direct URL helpers -- Dependency groups -- Errors -- Utilities - -Installation ------------- - -Use ``pip`` to install these utilities:: - - pip install packaging - -The ``packaging`` library uses calendar-based versioning (``YY.N``). - -Discussion ----------- - -If you run into bugs, you can file them in our `issue tracker`_. - -You can also join discussions on `GitHub Discussions`_ to ask questions or get involved. - -.. _`documentation`: https://packaging.pypa.io/ -.. _`issue tracker`: https://github.com/pypa/packaging/issues -.. _`GitHub Discussions`: https://github.com/pypa/packaging/discussions - - -Code of Conduct ---------------- - -Everyone interacting in the packaging project's codebases, issue trackers, chat -rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_. - -.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md - -Contributing ------------- - -The ``CONTRIBUTING.rst`` file outlines how to contribute to this project as -well as how to report a potential security issue. The documentation for this -project also covers information about `project development`_ and `security`_. - -.. _`project development`: https://packaging.pypa.io/en/latest/development/ -.. _`security`: https://packaging.pypa.io/en/latest/security/ - -Project History ---------------- - -Please review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for -recent changes and project history. - -.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/ - diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA deleted file mode 100644 index 83c1c59e321..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/prometheus_client-0.26.0.dist-info/METADATA +++ /dev/null @@ -1,56 +0,0 @@ -Metadata-Version: 2.4 -Name: prometheus_client -Version: 0.26.0 -Summary: Python client for the Prometheus monitoring system. -Author-email: The Prometheus Authors -License-Expression: Apache-2.0 AND BSD-2-Clause -Project-URL: Homepage, https://github.com/prometheus/client_python -Project-URL: Documentation, https://prometheus.github.io/client_python/ -Keywords: prometheus,monitoring,instrumentation,client -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: Information Technology -Classifier: Intended Audience :: System Administrators -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: System :: Monitoring -Requires-Python: >=3.9 -Description-Content-Type: text/markdown -License-File: LICENSE -License-File: NOTICE -Provides-Extra: twisted -Requires-Dist: twisted; extra == "twisted" -Provides-Extra: aiohttp -Requires-Dist: aiohttp; extra == "aiohttp" -Provides-Extra: django -Requires-Dist: django; extra == "django" -Dynamic: license-file - -# Prometheus Python Client - -The official Python client for [Prometheus](https://prometheus.io). - -## Installation - -``` -pip install prometheus-client -``` - -This package can be found on [PyPI](https://pypi.python.org/pypi/prometheus_client). - -## Documentation - -Documentation is available on https://prometheus.github.io/client_python - -## Links - -* [Releases](https://github.com/prometheus/client_python/releases): The releases page shows the history of the project and acts as a changelog. -* [PyPI](https://pypi.python.org/pypi/prometheus_client) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA deleted file mode 100644 index ee1cbed7414..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/protobuf-7.36.2.dist-info/METADATA +++ /dev/null @@ -1,17 +0,0 @@ -Metadata-Version: 2.1 -Name: protobuf -Author: protobuf@googlegroups.com -Author-email: protobuf@googlegroups.com -Home-page: https://developers.google.com/protocol-buffers/ -License: 3-Clause BSD License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Requires-Python: >=3.10 -Version: 7.36.2 - -UNKNOWN diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA deleted file mode 100644 index cfc3f948ea8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/requests-2.34.2.dist-info/METADATA +++ /dev/null @@ -1,120 +0,0 @@ -Metadata-Version: 2.4 -Name: requests -Version: 2.34.2 -Summary: Python HTTP for Humans. -Author-email: Kenneth Reitz -Maintainer-email: Ian Stapleton Cordasco , Nate Prewitt -License: Apache-2.0 -Project-URL: Documentation, https://requests.readthedocs.io -Project-URL: Source, https://github.com/psf/requests -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Natural Language :: English -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: 3.15 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta -Classifier: Topic :: Internet :: WWW/HTTP -Classifier: Topic :: Software Development :: Libraries -Requires-Python: >=3.10 -Description-Content-Type: text/markdown -License-File: LICENSE -License-File: NOTICE -Requires-Dist: charset_normalizer<4,>=2 -Requires-Dist: idna<4,>=2.5 -Requires-Dist: urllib3<3,>=1.26 -Requires-Dist: certifi>=2023.5.7 -Provides-Extra: security -Provides-Extra: socks -Requires-Dist: PySocks!=1.5.7,>=1.5.6; extra == "socks" -Provides-Extra: use-chardet-on-py3 -Requires-Dist: chardet<8,>=3.0.2; extra == "use-chardet-on-py3" -Dynamic: license-file - -# Requests - -[![Version](https://img.shields.io/pypi/v/requests.svg?maxAge=86400)](https://pypi.org/project/requests/) -[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests) -[![Downloads](https://static.pepy.tech/badge/requests/month)](https://pepy.tech/project/requests) -[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors) -[![Documentation](https://readthedocs.org/projects/requests/badge/?version=latest)](https://requests.readthedocs.io) - -**Requests** is a simple, yet elegant, HTTP library. - -```python ->>> import requests ->>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass')) ->>> r.status_code -200 ->>> r.headers['content-type'] -'application/json; charset=utf8' ->>> r.encoding -'utf-8' ->>> r.text -'{"authenticated": true, ...' ->>> r.json() -{'authenticated': True, ...} -``` - -Requests allows you to send HTTP/1.1 requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data — but nowadays, just use the `json` method! - -Requests is one of the most downloaded Python packages today, pulling in around `300M downloads / week` — according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `4,000,000+` repositories. - -## Installing Requests and Supported Versions - -Requests is available on PyPI: - -```console -$ python -m pip install requests -``` - -Requests officially supports Python 3.10+. - -## Supported Features & Best–Practices - -Requests is ready for the demands of building robust and reliable HTTP–speaking applications, for the needs of today. - -- Keep-Alive & Connection Pooling -- International Domains and URLs -- Sessions with Cookie Persistence -- Browser-style TLS/SSL Verification -- Basic & Digest Authentication -- Familiar `dict`–like Cookies -- Automatic Content Decompression and Decoding -- Multi-part File Uploads -- SOCKS Proxy Support -- Connection Timeouts -- Streaming Downloads -- Automatic honoring of `.netrc` -- Chunked HTTP Requests - -## Cloning the repository - -When cloning the Requests repository, you may need to add the `-c -fetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit timestamp (see -[this issue](https://github.com/psf/requests/issues/2690) for more background): - -```shell -git clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git -``` - -You can also apply this setting to your global Git config: - -```shell -git config --global fetch.fsck.badTimezone ignore -``` - ---- - -[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/main/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/main/ext/psf.png)](https://www.python.org/psf) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA deleted file mode 100644 index 1340d3623fa..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/ruamel_yaml-0.19.1.dist-info/METADATA +++ /dev/null @@ -1,317 +0,0 @@ -Metadata-Version: 2.4 -Name: ruamel.yaml -Version: 0.19.1 -Summary: ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order -Author: Anthon van der Neut -Author-email: a.van.der.neut@ruamel.eu -License: MIT -Project-URL: Home, https://sourceforge.net/p/ruamel-yaml/ -Project-URL: Source, https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/ -Project-URL: Tracker, https://sourceforge.net/p/ruamel-yaml/tickets/ -Project-URL: Documentation, https://yaml.dev/doc/ruamel.yaml -Keywords: yaml 1.2 parser round-trip preserve quotes order config -Classifier: Development Status :: 4 - Beta -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Markup -Classifier: Typing :: Typed -Requires-Python: >=3.9 -Description-Content-Type: text/markdown; charset=UTF-8; variant=CommonMark -License-File: LICENSE -Provides-Extra: oldlibyaml -Requires-Dist: ruamel.yaml.clib; platform_python_implementation == "CPython" and extra == "oldlibyaml" -Provides-Extra: libyaml -Requires-Dist: ruamel.yaml.clibz>=0.3.7; platform_python_implementation == "CPython" and extra == "libyaml" -Provides-Extra: jinja2 -Requires-Dist: ruamel.yaml.jinja2>=0.2; extra == "jinja2" -Provides-Extra: docs -Requires-Dist: ryd; extra == "docs" -Requires-Dist: mercurial>5.7; extra == "docs" -Dynamic: author -Dynamic: author-email -Dynamic: classifier -Dynamic: description -Dynamic: description-content-type -Dynamic: keywords -Dynamic: license -Dynamic: license-file -Dynamic: project-url -Dynamic: provides-extra -Dynamic: requires-python -Dynamic: summary - -# ruamel.yaml - -`ruamel.yaml` is a YAML 1.2 loader/dumper package for Python. - -| | | -| - | - | -| version |0.19.0 | -| updated |2025-01-02 | -| documentation |https://yaml.dev/doc/ruamel.yaml | -| repository |https://sourceforge.net/projects/ruamel-yaml | -| pypi |https://pypi.org/project/ruamel.yaml | - - -## breaking changes, that may make future uploads to PyPI impossible - -*If you are interested in future upgrades of `ruamel.yaml` -please check the [documentation on installing](https://yaml.dev/doc/ruamel.yaml/install/), -since at some point I might not be able to upload a new version to PyPI with updated information.* - -`ruamel.yaml` was intentionally named as `yaml` in a namespace `ruamel`. The namespace allows the installation -name to correspond unchanged to how the package is imported, reduces the number of links I have to create -in site-packages of a Python install during development, as well as providing a recognisable set of packages -my company releases to the public. - -However, after uploading version 0.18.7, I got an email from PyPI, about having to change the project name -to `ruamel_yaml` to comply with PEP 625, sometime in the future. The email doesn't say if namespace packages are -no longer allowed, or how to deal with the very real clash with the pre-existing package `ruamel_yaml`. - -I might not be able to adapt `ruamel.yaml`, in -a way that does not negatively affect the 0.5 million daily downloads (and my own usage of the package) in time. -My experience with other such service downgrades (Bitbucket, Readthedocs), has not been entirely positive. - ------ - - - -Starting with 0.19.1 `ruamel.yaml` no longer has a dependency on `ruamel.yaml.clibz` -nor on the old `ruamel.yaml.clib`. - -Some deployment issues were reported on 0.19.0, due to the lack of proper pinning of the -`ruamel.yaml` version used. Most of these issues had to do with -the environment not having updated `setuptools` installed and the build -dependency `setuptools-zig` for `ruamel.yaml.clibz` not being invoked, with -Python falling back to invoking gcc (which was even less likely to be installed). - -The already indicated simple solution of using: - -``` - python -m pip install --no-deps ruamel.yaml ruamel.yaml.clib - -``` -turned out not to work for at least one setup. - -As I am not aware that you can create an install requirement that removes -a dependency, the default (Cython) dependency is removed and you should -use `ruamel.yaml[libyaml]` resp. `ruamel.yaml[oldlibyaml]` as your requirements. -(this is the preferred way over using `ruamel.yaml.clibz` and `ruamel.yaml.clib` -directly). -If you are using `ruamel.yaml` in its default (round-trip, `YAML(typ='rt')`) mode, -there is currently no advantage of installing either optional extension. - - -The C sources are functionally unchanged, -but they are now always compiled (using `setuptools-zig` and `ziglang`) on your system, -instead of being downloaded as pre-compiled wheels (if available). -For this to function properly your Python (virtual) environment needs to have -an up-to-date version of `setuptools` and `wheels` pre-installed. - -The code to load `ruamel.yaml.clib` has priority over `ruamel.yaml.clibz` -if both are installed. -This compatibility will at least be available during the 0.19 `ruamel.yaml` series -(so pin your usage of `ruamel.yaml` if necessary and report any problems). - -The motivitation for this change is the availability, -and easy of use, of Zig as the toolchain -(in the form of `ziglang` on PyPi), so lenghty, non-optimized, -pre-compilation and uploading to PyPI, -is no longer necessary. -The time spent on creating ~60 wheels -and even more time wasted on dealing with CI providers (Appveyor -not being updated to support 3.14, Github CI being slow, -and charging for the use of your own computer, -etc). - -The split out of `ruamel.yaml.clib` after the 0.15.100 release, -was also motivated by the time spent -on generating .whl files even if only Python code was changed. -The use of `ziglang` and `setuptools-zig` does make re-integration of the C sources -into `ruamel.yaml` feasable, but there are no plans yet to make this happen. - -The test matrix for `ruamel.yaml.clibz`, of course still has many dimensions: -``` - Python versions: 3.9 - 3.14 - OS-es: Linux, Alpine (musl), macOS, Windows - Architectures: Intel/AMD, Arm (and others), in 64 and some also in 32 bit versions - Zig version: ziglang < 0.16 is taken from PyPI -``` - -I try to test as much of the combinations as possible, -trying at least all supported Python versions, -including freethreading, -on macOS-arm64, -Linux arm64 (via docker containers), -Ubuntu Linux-Intel, -Linux musl intel (docker). -And at least one Python version along each of the indicated positions of the -dimensions above (e.g. Windows10 64bit was tested with Python 3.14, but I -could not test the RISC-V architecture). -As with generating .whl files previously -(which I could not all test myself) -I partly have to rely on the process of compilation/generation being likely correct, -and feedback from actual users, -of exotic (for me) platforms, is of course welcome. - -There is new section, -in the documentation, -on the security of processing unchecked input. - -------- - -The potentially breaking change announced for the 0.18 series, in that `YAML(typ='unsafe')` -was going to be deprecated (now pending), has not yet been implemented, but is still considered. -If you only use `unsafe` to dump, please use the new `YAML(typ='full')`, the result of that can be *safely* -loaded with a default instance `YAML()`, as that will get you inspectable, tagged, scalars, instead of -executed Python functions/classes. (You should probably add constructors for what you actually need, -but I do consider adding a `ruamel.yaml.unsafe` package that will re-add the `typ='unsafe'` option. -*Please adjust/pin your dependencies accordingly if necessary.* - -------- - -Version 0.18.16 was the last one tested to be working with Python 3.8. -Version 0.18.9 was the last one tested to be working with Python 3.7. -Version 0.17.21 was the last one tested to be working on Python 3.5 and 3.6. -The 0.16.13 release was the last that was tested to be working on Python 2.7. - - -There are two extra plug-in packages -(`ruamel.yaml.bytes` and `ruamel.yaml.string`) -for those not wanting to do the streaming to a -`io.BytesIO/StringIO` buffer themselves. - -If your package uses `ruamel.yaml` and is not listed on PyPI, drop me an -email, preferably with some information on how you use the package (or a -link to the repository) and I'll keep you informed when the status of -the API is stable enough to make the transition. - -For packaging purposes you can use a download of the [tar balls of tagged source](https://yaml.dev/ruamel-dl-tagged-releases) - - - - - - - - - -0.19.0 (2025-01-02): - -- removed dependency on `ruamel.yaml.clibz` - -0.19.0 (2025-12-31): - -- changed dependency on `ruamel.yaml.clib` to `ruamel.yaml.clibz` which includes support for free-threading (revisited after a bug report by [Ahmed Moustafa](https://sourceforge.net/u/aemous/profile/) and some insistance by [Nathan Goldbaum](https://sourceforge.net/u/ngoldbaum/profile/) -- added `.max_depth` to `YAML()` instance. If set to a (positive) number this limits the recursion, so loading does throw a `MaxDepthExceededError`. Based on comments by Benjamin Oberdorfer via email. This also triggered the new documenation section on processing unchecked input. - -0.18.17 (2025-12-17): - -- try to load C functions from `_ruamel_yaml_clibz` first. - -0.18.16 (2025-10-22): - -- root level block style scalars that started with a directives-end marker or a document-end marker, are now indented 2 spaces. -- merged fix for accessing end_marks on Tokens provided by [Toknak](https://sourceforge.net/u/taknok/) - -0.18.15 (2025-08-19): - -- duplicate merge keys are never allowed (not even with .allow_duplicate_keys = True -- merge keys now keep there position if a key before the merge key gets deleted (previously a key after the merge key would move before it) - -0.18.14 (2025-06-09): - -- Fix issue with constructing dataclasses that have a default factoryi attribute, but were missing a mapping value for that attribute. Reported by [Victor Prieto](https://sourceforge.net/u/vsprieto/profile/) -- the tagged release tar files can now also be downloaded from https://yaml.dev/ruamel-dl-tagged-releases/ please adjust if you use https://sourceforge.net/projects/ruamel-dl-tagged-releases/files/ as that repository in sourceforge will no longer be updated from some later date. - -0.18.13 (2025-06-06): - -- Fix line wrapping on plain scalars not observing width correctly. Issue 529, reported by [Sebastien Vermeille](https://sourceforge.net/u/svermeille/profile/) -- Fix sha256 and length in RECORD files. Reported by [Evan](https://sourceforge.net/u/bempelise/profile/) - -0.18.12 (2025-05-30): - -- fix additional issue with extra space in double quoted string. Reported by [Saugat Pachhai](https://sourceforge.net/u/skshetry/profile/) -- fix duplicate key url, now pointing to yaml.dev. Reported by [Hugo](https://sourceforge.net/u/hugovk/profile/) -- fix broken RECORD file, which was a problem for uv, not pip. Reported by [konstin](https://sourceforge.net/u/konstin/profile/) - -0.18.11 (2025-05-19): - -- function `load_yaml_guess_indent` now takes an option `yaml` argument so you can provide an already created/configured `YAML` instance -- Sequence item indicator with both comment/empty line before indicator **and** comment before sequence item, could not move comment and raise `NotImplementedError`. Reported by [Karsten Tessarzik](https://sourceforge.net/u/kars10/profile/). -- missing f for f-string (reported by π, via email) -- fixed issue with extra space in double quoted dump (reported by [Jan Möller](https://sourceforge.net/u/redfiredragon/profile/)) - -0.18.10 (2025-01-06): - -- implemented changes to the setup.py for Python 3.14 as suggested by [Miro Hrončok](https://sourceforge.net/u/hroncok/profile/) in merge requests (MR not merged as those files are copied in from `develop` config) - -0.18.9 (2025-01-05): - -- fix issue with roundtripping 0 in YAML 1.1 reported by [Peter Law](https://sourceforge.net/u/peterjclaw/profile/) - -0.18.8 (2025-01-02): - -- added warning to README.md that PyPI might block updates due to breaking changes - -0.18.7 (2024-12-30): - -- fixes for README (reported by [Kees Bakker](https://sourceforge.net/u/keesb/profile/)) -- fixes preserving anchor on scalar integer `0` (issue reported by (Mor Peled)[https://sourceforge.net/u/morp/profile/] and also in a question by [Ravi](https://stackoverflow.com/users/6550398/ravi) on [Stackoverflow](https://stackoverflow.com/a/79306830/1307905)) -- fix for formatting of README suggested by [Michael R. Crusoe](https://sourceforge.net/u/crusoe/profile/) - -0.18.6 (2024-02-07): - -- fixed an issue with dataclass loading when the fields were collections (bug found as a result of a question by [FibroMyAlgebra](https://stackoverflow.com/users/6855070/fibromyalgebra) on [StackOverflow](https://stackoverflow.com/a/77485786/1307905)) -- fixed an issue loading dataclasses with `InitVar` fields when `from __future__ import annotations` was used to delay evaluation of typing. - -0.18.5 (2023-11-03): - -- there is some indication that dependent packages have been pinned to use specific (tested) and just install the latest even in Python versions that have end-of-life - -0.18.4 (2023-11-01): - -- YAML() instance has a `doc_infos` attribute which is a cumulative list of DocInfo instances (one for `load()`, one per document for `load_all()`). DocInfo instances contain version information (requested, directive) and tag directive information -- fix issue that the YAML instance tags attribute was not reset between documents, resulting in mixing of tag directives of multiple documents. Now only provides tag directive information on latest document after loading. This means tags for dumping must be set **again** after a document is loaded with the same instance. (because of this tags will be removed in a favour of a different mechanism in the future) -- fix issue with multiple document intermixing YAML 1.2 and YAML 1.1, the VersionedResolver now resets -- fix issue with disappearing comment when next token was Tag (still can't have both a comment before a tag and after a tag, before node) - -0.18.3 (2023-10-29): - -- fix issue with spurious newline on first item after comment + nested block sequence -- additional links in the metadata on PyPI (Reported, with pointers how to fix, by [Sorin](https://sourceforge.net/u/ssbarnea/profile/)). - -0.18.2 (2023-10-24): - -- calling the deprecated functions now raises an `AttributeError` with the, somewhat more informative, orginal warning message. Instead of calling `sys.exit(1)` - -0.18.1 (2023-10-24): - -- calling the deprecated functions now always displays the warning message. (reported by [Trend Lloyd](https://sourceforge.net/u/lathiat2/profile/)) - -0.18.0 (2023-10-23): - -- the **functions** `scan`, `parse`, `compose`, `load`, `emit`, `serialize`, `dump` and their variants (`_all`, `safe_`, `round_trip_`, etc) have been deprecated (the same named **methods** on `YAML()` instances are, of course, still there. -- `YAML(typ='unsafe')` now issues a `PendingDeprecationWarning`. This will become deprecated in the 0.18 series -(probably before the end of 2023). -You can use `YAML(typ='full')` to dump unregistered Python classes/functions. -For loading you'll have to register your classes/functions -if you want the old, unsafe, functionality. You can still load any tag, like `!!python/name:posix.system', **safely** -with the (default) round-trip parser. -- fix for `bytes-like object is required not 'str' while dumping binary streams`. This was reported, analysed and a fix provided by [Vit Zikmund](https://sourceforge.net/u/tlwhitec/profile/) - - ------------------------------------------------------------------------- - -For older changes see the file -[CHANGES](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/CHANGES) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA deleted file mode 100644 index 97fd818b909..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/typing_extensions-4.16.0.dist-info/METADATA +++ /dev/null @@ -1,73 +0,0 @@ -Metadata-Version: 2.4 -Name: typing_extensions -Version: 4.16.0 -Summary: Backported and Experimental Type Hints for Python 3.9+ -Keywords: annotations,backport,checker,checking,function,hinting,hints,type,typechecking,typehinting,typehints,typing -Author-email: "Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee" -Requires-Python: >=3.9 -Description-Content-Type: text/markdown -License-Expression: PSF-2.0 -Classifier: Development Status :: 5 - Production/Stable -Classifier: Environment :: Console -Classifier: Intended Audience :: Developers -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: 3.15 -Classifier: Topic :: Software Development -License-File: LICENSE -Project-URL: Bug Tracker, https://github.com/python/typing_extensions/issues -Project-URL: Changes, https://github.com/python/typing_extensions/blob/main/CHANGELOG.md -Project-URL: Documentation, https://typing-extensions.readthedocs.io/ -Project-URL: Home, https://github.com/python/typing_extensions -Project-URL: Q & A, https://github.com/python/typing/discussions -Project-URL: Repository, https://github.com/python/typing_extensions - -# Typing Extensions - -[![Chat at https://gitter.im/python/typing](https://badges.gitter.im/python/typing.svg)](https://gitter.im/python/typing) - -[Documentation](https://typing-extensions.readthedocs.io/en/latest/#) – -[PyPI](https://pypi.org/project/typing-extensions/) - -## Overview - -The `typing_extensions` module serves two related purposes: - -- Enable use of new type system features on older Python versions. For example, - `typing.TypeGuard` is new in Python 3.10, but `typing_extensions` allows - users on previous Python versions to use it too. -- Enable experimentation with new type system PEPs before they are accepted and - added to the `typing` module. - -`typing_extensions` is treated specially by static type checkers such as -mypy and pyright. Objects defined in `typing_extensions` are treated the same -way as equivalent forms in `typing`. - -`typing_extensions` uses -[Semantic Versioning](https://semver.org/). The -major version will be incremented only for backwards-incompatible changes. -Therefore, it's safe to depend -on `typing_extensions` like this: `typing_extensions ~=x.y`, -where `x.y` is the first version that includes all features you need. -[This](https://packaging.python.org/en/latest/specifications/version-specifiers/#compatible-release) -is equivalent to `typing_extensions >=x.y, <(x+1)`. Do not depend on `~= x.y.z` -unless you really know what you're doing; that defeats the purpose of -semantic versioning. - -## Included items - -See [the documentation](https://typing-extensions.readthedocs.io/en/latest/#) for a -complete listing of module contents. - -## Contributing - -See [CONTRIBUTING.md](https://github.com/python/typing_extensions/blob/main/CONTRIBUTING.md) -for how to contribute to `typing_extensions`. - diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA deleted file mode 100644 index 88f02623b28..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/urllib3-2.8.0.dist-info/METADATA +++ /dev/null @@ -1,175 +0,0 @@ -Metadata-Version: 2.5 -Name: urllib3 -Version: 2.8.0 -Summary: HTTP library with thread-safe connection pooling, file post, and more. -Project-URL: Changelog, https://github.com/urllib3/urllib3/blob/main/CHANGES.rst -Project-URL: Documentation, https://urllib3.readthedocs.io -Project-URL: Code, https://github.com/urllib3/urllib3 -Project-URL: Issue tracker, https://github.com/urllib3/urllib3/issues -Project-URL: Security policy, https://urllib3.readthedocs.io/en/latest/security.html -Author-email: Andrey Petrov -Maintainer-email: Seth Michael Larson , Quentin Pradet , Illia Volochii -License-Expression: MIT -License-File: LICENSE.txt -Keywords: filepost,http,httplib,https,pooling,ssl,threadsafe,urllib -Classifier: Environment :: Web Environment -Classifier: Intended Audience :: Developers -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: 3.15 -Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Internet :: WWW/HTTP -Classifier: Topic :: Software Development :: Libraries -Requires-Python: >=3.10 -Provides-Extra: brotli -Requires-Dist: brotli>=1.2.0; (platform_python_implementation == 'CPython') and extra == 'brotli' -Requires-Dist: brotlicffi>=1.2.0.0; (platform_python_implementation != 'CPython') and extra == 'brotli' -Provides-Extra: h2 -Requires-Dist: h2<5,>=4; extra == 'h2' -Provides-Extra: socks -Requires-Dist: pysocks!=1.5.7,<2.0,>=1.5.6; extra == 'socks' -Provides-Extra: zstd -Requires-Dist: backports-zstd>=1.0.0; (python_version < '3.14') and extra == 'zstd' -Description-Content-Type: text/markdown - -

- -![urllib3](https://github.com/urllib3/urllib3/raw/main/docs/_static/banner_github.svg) - -

- -

- PyPI Version - Python Versions - Join our Discord - Coverage Status - Build Status on GitHub - Documentation Status
- OpenSSF Scorecard - SLSA 3 - CII Best Practices -

- -urllib3 is a powerful, *user-friendly* HTTP client for Python. -urllib3 brings many critical features that are missing from the Python -standard libraries: - -- Thread safety. -- Connection pooling. -- Client-side SSL/TLS verification. -- File uploads with multipart encoding. -- Helpers for retrying requests and dealing with HTTP redirects. -- Support for gzip, deflate, brotli, and zstd encoding. -- Proxy support for HTTP and SOCKS. -- 100% test coverage. - -... and many more features, but most importantly: Our maintainers have a 15+ -year track record of maintaining urllib3 with the highest code standards and -attention to security and safety. - -[Much of the Python ecosystem already uses urllib3](https://urllib3.readthedocs.io/en/stable/#who-uses) -and you should too. - - -## Installing - -urllib3 can be installed with [pip](https://pip.pypa.io): - -```bash -$ python -m pip install urllib3 -``` - -Alternatively, you can grab the latest source code from [GitHub](https://github.com/urllib3/urllib3): - -```bash -$ git clone https://github.com/urllib3/urllib3.git -$ cd urllib3 -$ pip install . -``` - -## Getting Started - -urllib3 is easy to use: - -```python3 ->>> import urllib3 ->>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt") ->>> resp.status -200 ->>> resp.data -b"User-agent: *\nDisallow: /deny\n" -``` - -urllib3 has usage and reference documentation at [urllib3.readthedocs.io](https://urllib3.readthedocs.io). - - -## Community - -urllib3 has a [community Discord channel](https://discord.gg/urllib3) for asking questions and -collaborating with other contributors. Drop by and say hello 👋 - - -## Contributing - -urllib3 welcomes contributions. Please read our -[contributing documentation](https://urllib3.readthedocs.io/en/latest/contributing.html) -before starting work. - -Check for existing pull requests addressing the same issue, and share feedback -and suggestions in the existing pull request and issue. Duplicate pull -requests, including alternative solutions, will be rejected without review -unless a maintainer has approved opening an alternative pull request in -advance. - - -## Security Disclosures - -To report a security vulnerability, please use the -[Tidelift security contact](https://tidelift.com/security). -Tidelift will coordinate the fix and disclosure with maintainers. - -See the repository -[Security Policy](https://urllib3.readthedocs.io/en/latest/security.html) -for more details. - - -## Maintainers - -Meet our maintainers since 2008: - -- Current Lead: [@illia-v](https://github.com/illia-v) (Illia Volochii) -- [@sethmlarson](https://github.com/sethmlarson) (Seth M. Larson) -- [@pquentin](https://github.com/pquentin) (Quentin Pradet) -- [@theacodes](https://github.com/theacodes) (Thea Flowers) -- [@haikuginger](https://github.com/haikuginger) (Jess Shapiro) -- [@lukasa](https://github.com/lukasa) (Cory Benfield) -- [@sigmavirus24](https://github.com/sigmavirus24) (Ian Stapleton Cordasco) -- [@shazow](https://github.com/shazow) (Andrey Petrov) - -👋 - - -## Sponsorship - -If your company benefits from this library, please consider [sponsoring its -development](https://urllib3.readthedocs.io/en/latest/sponsors.html). - - -## For Enterprise - -Professional support for urllib3 is available as part of the [Tidelift -Subscription][1]. Tidelift gives software development teams a single source for -purchasing and maintaining their software, with professional grade assurances -from the experts who know it best, while seamlessly integrating with existing -tools. - -[1]: https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=readme diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA deleted file mode 100644 index 8a0c2cbc88b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/_metadata/wrapt-2.5.2.dist-info/METADATA +++ /dev/null @@ -1,193 +0,0 @@ -Metadata-Version: 2.4 -Name: wrapt -Version: 2.5.2 -Summary: Module for decorators, wrappers and monkey patching. -Author-email: Graham Dumpleton -License-Expression: BSD-2-Clause -Project-URL: Homepage, https://github.com/GrahamDumpleton/wrapt -Project-URL: Bug Tracker, https://github.com/GrahamDumpleton/wrapt/issues/ -Project-URL: Changelog, https://wrapt.readthedocs.io/en/latest/changes.html -Project-URL: Documentation, https://wrapt.readthedocs.io/ -Keywords: wrapper,proxy,decorator -Classifier: Development Status :: 5 - Production/Stable -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Programming Language :: Python :: 3.15 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Requires-Python: >=3.9 -Description-Content-Type: text/x-rst -License-File: LICENSE -Provides-Extra: dev -Requires-Dist: pytest; extra == "dev" -Requires-Dist: setuptools; extra == "dev" -Dynamic: license-file - -.. image:: https://raw.githubusercontent.com/GrahamDumpleton/wrapt/develop/docs/_static/wrapt-logo.svg - :alt: wrapt - :width: 182px - -wrapt -===== - -|PyPI| |Documentation| - -A Python module for decorators, wrappers and monkey patching. - -Overview --------- - -The **wrapt** module provides a transparent object proxy for Python, which can be used as the basis for the construction of function wrappers and decorator functions. - -The **wrapt** module focuses very much on correctness. It goes way beyond existing mechanisms such as ``functools.wraps()`` to ensure that decorators preserve introspectability, signatures, type checking abilities etc. The decorators that can be constructed using this module will work in far more scenarios than typical decorators and provide more predictable and consistent behaviour. - -To ensure that the overhead is as minimal as possible, a C extension module is used for performance critical components. An automatic fallback to a pure Python implementation is also provided where a target system does not have a compiler to allow the C extension to be compiled. - -Key Features ------------- - -* **Universal decorators** that work with functions, methods, classmethods, staticmethods, and classes -* **Transparent object proxies** for advanced wrapping scenarios -* **Monkey patching utilities** for safe runtime modifications -* **C extension** for optimal performance with Python fallback -* **Comprehensive introspection preservation** (signatures, annotations, etc.) -* **Thread-safe decorator implementations** - -Installation ------------- - -Install from PyPI using pip:: - - pip install wrapt - -Supported Python Versions --------------------------- - -* Python 3.9+ -* CPython and PyPy implementations - -Documentation -------------- - -For comprehensive documentation, examples, and advanced usage patterns, visit: - -* https://wrapt.readthedocs.io/ - -Quick Start ------------ - -To implement your decorator you need to first define a wrapper function. -This will be called each time a decorated function is called. The wrapper -function needs to take four positional arguments: - -* ``wrapped`` - The wrapped function which in turns needs to be called by your wrapper function. -* ``instance`` - The object to which the wrapped function was bound when it was called. -* ``args`` - The list of positional arguments supplied when the decorated function was called. -* ``kwargs`` - The dictionary of keyword arguments supplied when the decorated function was called. - -The wrapper function would do whatever it needs to, but would usually in -turn call the wrapped function that is passed in via the ``wrapped`` -argument. - -The decorator ``@wrapt.decorator`` then needs to be applied to the wrapper -function to convert it into a decorator which can in turn be applied to -other functions. - -.. code-block:: python - - import wrapt - - @wrapt.decorator - def pass_through(wrapped, instance, args, kwargs): - return wrapped(*args, **kwargs) - - @pass_through - def function(): - pass - -If you wish to implement a decorator which accepts arguments, then wrap the -definition of the decorator in a function closure. Any arguments supplied -to the outer function when the decorator is applied, will be available to -the inner wrapper when the wrapped function is called. - -.. code-block:: python - - import wrapt - - def with_arguments(myarg1, myarg2): - @wrapt.decorator - def wrapper(wrapped, instance, args, kwargs): - return wrapped(*args, **kwargs) - return wrapper - - @with_arguments(1, 2) - def function(): - pass - -When applied to a normal function or static method, the wrapper function -when called will be passed ``None`` as the ``instance`` argument. - -When applied to an instance method, the wrapper function when called will -be passed the instance of the class the method is being called on as the -``instance`` argument. This will be the case even when the instance method -was called explicitly via the class and the instance passed as the first -argument. That is, the instance will never be passed as part of ``args``. - -When applied to a class method, the wrapper function when called will be -passed the class type as the ``instance`` argument. - -When applied to a class, the wrapper function when called will be passed -``None`` as the ``instance`` argument. The ``wrapped`` argument in this -case will be the class. - -The above rules can be summarised with the following example. - -.. code-block:: python - - import inspect - - @wrapt.decorator - def universal(wrapped, instance, args, kwargs): - if instance is None: - if inspect.isclass(wrapped): - # Decorator was applied to a class. - return wrapped(*args, **kwargs) - else: - # Decorator was applied to a function or staticmethod. - return wrapped(*args, **kwargs) - else: - if inspect.isclass(instance): - # Decorator was applied to a classmethod. - return wrapped(*args, **kwargs) - else: - # Decorator was applied to an instancemethod. - return wrapped(*args, **kwargs) - -Using these checks it is therefore possible to create a universal decorator -that can be applied in all situations. It is no longer necessary to create -different variants of decorators for normal functions and instance methods, -or use additional wrappers to convert a function decorator into one that -will work for instance methods. - -In all cases, the wrapped function passed to the wrapper function is called -in the same way, with ``args`` and ``kwargs`` being passed. The -``instance`` argument doesn't need to be used in calling the wrapped -function. - -Links ------ - -* **Documentation**: https://wrapt.readthedocs.io/ -* **Source Code**: https://github.com/GrahamDumpleton/wrapt -* **Bug Reports**: https://github.com/GrahamDumpleton/wrapt/issues/ -* **Changelog**: https://wrapt.readthedocs.io/en/latest/changes.html - -.. |PyPI| image:: https://img.shields.io/pypi/v/wrapt.svg?logo=python&cacheSeconds=3600 - :target: https://pypi.python.org/pypi/wrapt -.. |Documentation| image:: https://img.shields.io/badge/docs-wrapt.readthedocs.io-blue.svg - :target: https://wrapt.readthedocs.io/ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json deleted file mode 100644 index c3dec118ec2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/bom.cdx.json +++ /dev/null @@ -1,845 +0,0 @@ -{ - "components": [ - { - "bom-ref": "pkg:pypi/certifi@2026.10.23", - "hashes": [ - { - "alg": "SHA-256", - "content": "e9b54de76e530bb6cf0ccd036787103acb58fd42ba930ea8bf948ddbaa2f61d1" - } - ], - "licenses": [ - { - "license": { - "id": "MPL-2.0" - } - } - ], - "name": "certifi", - "pedigree": { - "patches": [ - { - "diff": { - "text": { - "content": "Look up the CA bundle in the vendored certifi package.\n\nUpstream passes the top-level name \"certifi\" to importlib.resources, which would import\nthe application's certifi (or fail if it isn't installed). __package__ resolves to the\nvendored package.\n\ndiff --git a/certifi/core.py b/certifi/core.py\n--- a/certifi/core.py\n+++ b/certifi/core.py\n@@ -37,14 +37,14 @@ if sys.version_info >= (3, 11):\n # We also have to hold onto the actual context manager, because\n # it will do the cleanup whenever it gets garbage collected, so\n # we will also store that at the global level as well.\n- _CACERT_CTX = as_file(files(\"certifi\").joinpath(\"cacert.pem\"))\n+ _CACERT_CTX = as_file(files(__package__).joinpath(\"cacert.pem\"))\n _CACERT_PATH = str(_CACERT_CTX.__enter__())\n atexit.register(exit_cacert_ctx)\n \n return _CACERT_PATH\n \n def contents() -> str:\n- return files(\"certifi\").joinpath(\"cacert.pem\").read_text(encoding=\"ascii\")\n+ return files(__package__).joinpath(\"cacert.pem\").read_text(encoding=\"ascii\")\n \n else:\n \n@@ -73,11 +73,11 @@ else:\n # We also have to hold onto the actual context manager, because\n # it will do the cleanup whenever it gets garbage collected, so\n # we will also store that at the global level as well.\n- _CACERT_CTX = get_path(\"certifi\", \"cacert.pem\")\n+ _CACERT_CTX = get_path(__package__, \"cacert.pem\")\n _CACERT_PATH = str(_CACERT_CTX.__enter__())\n atexit.register(exit_cacert_ctx)\n \n return _CACERT_PATH\n \n def contents() -> str:\n- return read_text(\"certifi\", \"cacert.pem\", encoding=\"ascii\")\n+ return read_text(__package__, \"cacert.pem\", encoding=\"ascii\")\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - } - ] - }, - "purl": "pkg:pypi/certifi@2026.10.23", - "type": "library", - "version": "2026.10.23" - }, - { - "bom-ref": "pkg:pypi/charset-normalizer@3.5.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "b6b751274acb69d77b3323d6b7dbaa3c7fdfc1eb829b7eb61d262f32e1af9685" - } - ], - "licenses": [ - { - "license": { - "id": "MIT" - } - } - ], - "name": "charset-normalizer", - "purl": "pkg:pypi/charset-normalizer@3.5.2", - "type": "library", - "version": "3.5.2" - }, - { - "bom-ref": "pkg:pypi/fastjsonschema@2.22.3", - "hashes": [ - { - "alg": "SHA-256", - "content": "f670b443830b75aca3f00b75949efa20f4b2a80302ec7a21505c28dd54cffd43" - } - ], - "licenses": [ - { - "license": { - "id": "BSD-3-Clause" - } - } - ], - "name": "fastjsonschema", - "purl": "pkg:pypi/fastjsonschema@2.22.3", - "type": "library", - "version": "2.22.3" - }, - { - "bom-ref": "pkg:pypi/googleapis-common-protos@1.76.0", - "hashes": [ - { - "alg": "SHA-256", - "content": "59e13344a9f3651aa201a03e2bee815a3bf43a4baf1f9ff8a9b62a840ce25fac" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "googleapis-common-protos", - "purl": "pkg:pypi/googleapis-common-protos@1.76.0", - "type": "library", - "version": "1.76.0" - }, - { - "bom-ref": "pkg:pypi/idna@3.20", - "hashes": [ - { - "alg": "SHA-256", - "content": "ab7ae7122974553370f0bdb919e1a960b2cd1bc1ef0276416d896db81c14582c" - } - ], - "licenses": [ - { - "license": { - "id": "BSD-3-Clause" - } - } - ], - "name": "idna", - "purl": "pkg:pypi/idna@3.20", - "type": "library", - "version": "3.20" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-api@1.45.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "2cbd737377e710ee740d261c94e93fa0f08e6d037c18f17513cc0a2d94479a34" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-api", - "purl": "pkg:pypi/opentelemetry-api@1.45.2", - "type": "library", - "version": "1.45.2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-configuration@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "de7f1b5682cab12d35f22330f025ed5a54d2a8151515eede5b0a3ed9629dcc61" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-configuration", - "purl": "pkg:pypi/opentelemetry-configuration@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-distro@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "a488231479bbc17f5c34d4ef740e9285fa8f8cd1114f73078cac9d8520eacfbd" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-distro", - "purl": "pkg:pypi/opentelemetry-distro@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-http-transport@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "fd5f5b490c099acda1cd7b909d5e8981436bf18cc8c6098d302d114c271720e9" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-http-transport", - "purl": "pkg:pypi/opentelemetry-exporter-http-transport@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-common@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "ace86efb75489f925f1ef809856ae5f0c7db534e4afdc624530222228b1236a5" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-otlp-common", - "purl": "pkg:pypi/opentelemetry-exporter-otlp-common@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-json-common@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "6e83ba9312edb60fc1d4929b73457e8cca7579db4b4492b32cb71a1a8ddecdc7" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-otlp-json-common", - "purl": "pkg:pypi/opentelemetry-exporter-otlp-json-common@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-json-file@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "a500f13bcc7760a74b5db7ece7d72ec8a78e0b515539fec81705970cb2efd7ca" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-otlp-json-file", - "purl": "pkg:pypi/opentelemetry-exporter-otlp-json-file@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-json-http@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "56a91c92e09c83c01d07380f48df6f649f3ce89fd47aa8c4862ef84de8e47ddb" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-otlp-json-http", - "purl": "pkg:pypi/opentelemetry-exporter-otlp-json-http@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-common@1.45.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "af483b24217028892f017096731b794b196b785025d2e6808874720fd0b05a80" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-otlp-proto-common", - "purl": "pkg:pypi/opentelemetry-exporter-otlp-proto-common@1.45.2", - "type": "library", - "version": "1.45.2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-http@1.45.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "6e4d025138829d0ee57946930c2ccad6491ad4d92a958e9c7eea69278fe60cfc" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-otlp-proto-http", - "purl": "pkg:pypi/opentelemetry-exporter-otlp-proto-http@1.45.2", - "type": "library", - "version": "1.45.2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-exporter-prometheus@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "b73998788aa30bec3bfe20fae312650878adb59f6563ed8bf37c188cb450a189" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-exporter-prometheus", - "purl": "pkg:pypi/opentelemetry-exporter-prometheus@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-instrumentation@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "fa9ccfdab147a14af8107d19ef0a7b5015675273c5adced7a1fc38f28b42ec4c" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-instrumentation", - "purl": "pkg:pypi/opentelemetry-instrumentation@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-instrumentation-aiohttp-client@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "33c51743ca225c2405b81b40ac744697804aef44b530f64d1f524c9a9cd3dca2" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-instrumentation-aiohttp-client", - "purl": "pkg:pypi/opentelemetry-instrumentation-aiohttp-client@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-propagator-b3@1.45.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "86c7f921a8390c0f7d88a27450765b6d075a3579f2592baa623723e9e527a1b8" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-propagator-b3", - "purl": "pkg:pypi/opentelemetry-propagator-b3@1.45.2", - "type": "library", - "version": "1.45.2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-proto@1.45.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "03a7ca1b43f89fd5b965d5975902bb2515c0c86e2428b456836e9a6149c6235a" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-proto", - "purl": "pkg:pypi/opentelemetry-proto@1.45.2", - "type": "library", - "version": "1.45.2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-proto-json@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "4da45dc527e68bc00fd4d16773c58b6a9a229ebb7a8dce997403414eaa03b3bb" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-proto-json", - "purl": "pkg:pypi/opentelemetry-proto-json@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-sdk@1.45.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "ff974ea70ee4f1d51e2ec152db37c2b626c7bf82bb3f7d86114fd8704e7199c6" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-sdk", - "purl": "pkg:pypi/opentelemetry-sdk@1.45.2", - "type": "library", - "version": "1.45.2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-semantic-conventions@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "4cbe61e5f9275d57ab31708446e7938ef4291ebbe6a7fca6f7a629c5acae87d8" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-semantic-conventions", - "purl": "pkg:pypi/opentelemetry-semantic-conventions@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/opentelemetry-util-http@0.66b2", - "hashes": [ - { - "alg": "SHA-256", - "content": "c4bb5d6744e60353bcaa3e325bc529a1515346b51cb4d9c8e5b730579337e06d" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "opentelemetry-util-http", - "pedigree": { - "patches": [ - { - "diff": { - "text": { - "content": "Default the distro's OTLP protocol to http/protobuf.\n\nThe distro defaults OTEL_EXPORTER_OTLP_PROTOCOL to grpc, but the gRPC exporters aren't vendored\n(grpcio has no pure-Python wheel). With http/protobuf the SDK resolves the \"otlp\" exporter to the\nvendored otlp_proto_http one. An explicitly set OTEL_EXPORTER_OTLP_PROTOCOL still wins.\n\ndiff --git a/opentelemetry/distro/__init__.py b/opentelemetry/distro/__init__.py\nindex 4d00198..6165e7a 100644\n--- a/opentelemetry/distro/__init__.py\n+++ b/opentelemetry/distro/__init__.py\n@@ -28,4 +28,5 @@ class OpenTelemetryDistro(BaseDistro):\n os.environ.setdefault(OTEL_TRACES_EXPORTER, \"otlp\")\n os.environ.setdefault(OTEL_METRICS_EXPORTER, \"otlp\")\n os.environ.setdefault(OTEL_LOGS_EXPORTER, \"otlp\")\n- os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, \"grpc\")\n+ # opentelemetry-agent: the gRPC exporters aren't vendored (grpcio has no pure-Python wheel).\n+ os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, \"http/protobuf\")\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - }, - { - "diff": { - "text": { - "content": "Parse and validate configuration files with ruamel.yaml and fastjsonschema.\n\nopentelemetry-configuration uses pyyaml and jsonschema, which have no pure-Python wheels (jsonschema needs\nrpds-py), so they are excluded (vendor-excludes.txt) and the vendored, pure-Python ruamel.yaml and\nfastjsonschema stand in for them:\n\n* YAML: ruamel.yaml's PyYAML-style SafeLoader (with the same Node classes, resolve() and\n construct_document()). It resolves scalars with the YAML 1.2 core schema, which the configuration\n spec requires (PyYAML implements YAML 1.1, where e.g. \"on\" and \"no\" are booleans).\n* Schema: a fastjsonschema validator compiled once. Its draft 2019-09 generator, used for the 2020-12\n $schema, covers every keyword the schema uses ($ref into $defs, oneOf, exclusiveMinimum, ...).\n Errors map to the same ConfigurationError messages.\n\nThe schema is also read relative to this file rather than with importlib.resources.files(\n\"opentelemetry.configuration\"), which would resolve the application's package.\n\ndiff --git a/opentelemetry/configuration/file/_loader.py b/opentelemetry/configuration/file/_loader.py\nindex dfa0037..44029a9 100644\n--- a/opentelemetry/configuration/file/_loader.py\n+++ b/opentelemetry/configuration/file/_loader.py\n@@ -3,7 +3,6 @@\n \n \"\"\"Configuration file loading and parsing.\"\"\"\n \n-import importlib.resources\n import json\n import logging\n import os\n@@ -14,32 +13,23 @@ from typing import Any\n from opentelemetry.agent._vendor.opentelemetry.configuration._conversion import _dict_to_dataclass\n from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import (\n ConfigurationError,\n- MissingDependencyError,\n )\n from opentelemetry.agent._vendor.opentelemetry.configuration.file._env_substitution import (\n substitute_env_vars,\n )\n from opentelemetry.agent._vendor.opentelemetry.configuration.models import OpenTelemetryConfiguration\n \n-try:\n- import yaml\n-except ImportError as exc:\n- raise MissingDependencyError(\n- package=\"pyyaml\",\n- feature=\"File configuration\",\n- install_name=\"opentelemetry-sdk\",\n- extras=\"file-configuration\",\n- ) from exc\n-\n-try:\n- import jsonschema\n-except ImportError as exc:\n- raise MissingDependencyError(\n- package=\"jsonschema\",\n- feature=\"File configuration\",\n- install_name=\"opentelemetry-sdk\",\n- extras=\"file-configuration\",\n- ) from exc\n+# opentelemetry-agent: pyyaml and jsonschema have no pure-Python wheels (jsonschema needs rpds-py),\n+# so the vendored ruamel.yaml (its pure-Python, PyYAML-style loader API) and fastjsonschema stand in.\n+from opentelemetry.agent._vendor import fastjsonschema\n+from opentelemetry.agent._vendor.ruamel.yaml import nodes as _yaml_nodes\n+from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError\n+from opentelemetry.agent._vendor.ruamel.yaml.loader import SafeLoader as _RuamelSafeLoader\n+\n+\n+class SafeLoader(_RuamelSafeLoader):\n+ # Only ruamel.yaml's YAML class sets the composer's nesting limit; 0 means none, like PyYAML.\n+ max_depth = 0\n \n # Schema version vendored in schema.json. ``file_format`` values are accepted\n # per the configuration spec's versioning rules: the major version must match,\n@@ -50,15 +40,24 @@ _SUPPORTED_SCHEMA_MAJOR = 1\n _SUPPORTED_SCHEMA_MINOR = 1\n \n _schema_cache: list[dict] = []\n+_validator_cache: list[Any] = []\n \n \n def _get_schema() -> dict:\n if not _schema_cache:\n- schema_path = importlib.resources.files(\"opentelemetry.configuration\") / \"schema.json\"\n+ # opentelemetry-agent: resolve the schema relative to this (vendored) package, not by name.\n+ schema_path = Path(__file__).resolve().parent.parent / \"schema.json\"\n _schema_cache.append(json.loads(schema_path.read_text(encoding=\"utf-8\")))\n return _schema_cache[0]\n \n \n+def _get_validator() -> Any:\n+ # Compiling the schema generates and executes Python code; do it once.\n+ if not _validator_cache:\n+ _validator_cache.append(fastjsonschema.compile(_get_schema()))\n+ return _validator_cache[0]\n+\n+\n _logger = logging.getLogger(__name__)\n \n _YAML_STR_TAG = \"tag:yaml.org,2002:str\"\n@@ -73,8 +72,8 @@ _STANDALONE_ENV_REF = re.compile(r\"\\A\\$\\{[A-Za-z_][A-Za-z0-9_]*(?::-[^}]*)?\\}\\Z\"\n \n \n def _substitute_env_in_yaml_node(\n- node: yaml.Node,\n- loader: yaml.SafeLoader,\n+ node: _yaml_nodes.Node,\n+ loader: SafeLoader,\n visited: set[int] | None = None,\n ):\n \"\"\"Apply env-var substitution to string configuration values in a node tree.\n@@ -120,7 +119,7 @@ def _substitute_env_in_yaml_node(\n # The parser hands this function the value node of attribute_count_limit,\n # which has value=\"${LIMIT}\", tag=str, style=None (plain/unquoted). Then:\n #\n- # 1. isinstance(node, yaml.ScalarNode) -> True: it is a leaf value.\n+ # 1. isinstance(node, ScalarNode) -> True: it is a leaf value.\n # 2. node.tag == _YAML_STR_TAG -> True: \"${LIMIT}\" is not a number or\n # bool, so the parser tagged it str. We substitute in place, giving\n # node.value = \"100\".\n@@ -131,7 +130,7 @@ def _substitute_env_in_yaml_node(\n #\n # Counter-cases that reach check 3 but stop there: \"${LIMIT}\" quoted fails\n # the style test; x${LIMIT} fails the regex. Both keep the str tag.\n- if isinstance(node, yaml.ScalarNode):\n+ if isinstance(node, _yaml_nodes.ScalarNode):\n # A ``ScalarNode`` is a leaf -- one configuration value. Only a\n # ``str``-tagged one can hold a ``${VAR}`` reference (nodes the parser\n # already typed as int, float, bool or null cannot), so those are the\n@@ -153,12 +152,12 @@ def _substitute_env_in_yaml_node(\n # str) YAML would assign to ``node.value``; the ``(True, False)``\n # implicit-flag pair marks it as a plain scalar so that\n # type-guessing applies, exactly as during normal parsing.\n- node.tag = loader.resolve(yaml.ScalarNode, node.value, (True, False))\n- elif isinstance(node, yaml.SequenceNode):\n+ node.tag = loader.resolve(_yaml_nodes.ScalarNode, node.value, (True, False))\n+ elif isinstance(node, _yaml_nodes.SequenceNode):\n # A sequence (list): each item is itself a value node -- recurse.\n for item in node.value:\n _substitute_env_in_yaml_node(item, loader, visited)\n- elif isinstance(node, yaml.MappingNode):\n+ elif isinstance(node, _yaml_nodes.MappingNode):\n # A mapping (dict): recurse into values only; keys are not\n # substitution candidates per the spec. A merge key (``<<: *base``)\n # appears here as an ordinary pair whose value node is the anchored\n@@ -197,7 +196,8 @@ def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLik\n try:\n if suffix == \".json\":\n return _substitute_env_in_json_value(json.loads(content))\n- yaml_loader = yaml.SafeLoader(content)\n+ # YAML 1.2 core schema, as the configuration spec requires (PyYAML implements YAML 1.1).\n+ yaml_loader = SafeLoader(content)\n try:\n root_node = yaml_loader.get_single_node()\n if root_node is None:\n@@ -206,7 +206,7 @@ def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLik\n return yaml_loader.construct_document(root_node)\n finally:\n yaml_loader.dispose()\n- except yaml.YAMLError as exc:\n+ except YAMLError as exc:\n _logger.exception(\"Failed to parse YAML from %s\", file_path)\n raise ConfigurationError(f\"Failed to parse YAML: {exc}\") from exc\n except json.JSONDecodeError as exc:\n@@ -294,19 +294,17 @@ def _validate_schema(data: dict) -> None:\n ConfigurationError: If the data does not conform to the schema.\n \"\"\"\n try:\n- jsonschema.validate(\n- instance=data,\n- schema=_get_schema(),\n- cls=jsonschema.Draft202012Validator,\n- )\n- except jsonschema.ValidationError as exc:\n+ _get_validator()(data)\n+ except fastjsonschema.JsonSchemaValueException as exc:\n+ # The path starts with the root's name (\"data\").\n+ path = exc.path[1:]\n raise ConfigurationError(\n- f\"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in exc.absolute_path)})\"\n- if exc.absolute_path\n+ f\"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in path)})\"\n+ if path\n else f\"Configuration does not match schema: {exc.message}\"\n ) from exc\n- except jsonschema.SchemaError as exc:\n- raise ConfigurationError(f\"Invalid configuration schema: {exc.message}\") from exc\n+ except fastjsonschema.JsonSchemaDefinitionException as exc:\n+ raise ConfigurationError(f\"Invalid configuration schema: {exc}\") from exc\n \n \n def _validate_file_format(data: dict) -> None:\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - }, - { - "diff": { - "text": { - "content": "Report upstream module names from the vendored SDK.\n\nInstrumentations name their tracers, meters and loggers after their module (get_tracer(__name__)),\nwhich is opentelemetry.agent._vendor.opentelemetry... once vendored. InstrumentationScope (and the\ndeprecated InstrumentationInfo) strip the vendor prefix, so telemetry reports the same scope names as\nthe upstream packages, e.g. opentelemetry.instrumentation.aiohttp_client.\n\nThe TracerProvider's warning filter for its own InstrumentationInfo deprecation names its module by\nstring; use __name__ so it matches the vendored module rather than the application's SDK.\n\ndiff --git a/opentelemetry/sdk/trace/__init__.py b/opentelemetry/sdk/trace/__init__.py\nindex 06fd2b3..1f7ab18 100644\n--- a/opentelemetry/sdk/trace/__init__.py\n+++ b/opentelemetry/sdk/trace/__init__.py\n@@ -1351,7 +1351,8 @@ class TracerProvider(trace_api.TracerProvider):\n \"ignore\",\n message=(r\"You should use InstrumentationScope. Deprecated since version 1.11.1.\"),\n category=DeprecationWarning,\n- module=\"opentelemetry.sdk.trace\",\n+ # opentelemetry-agent: match this (vendored) module, not the application's SDK.\n+ module=__name__,\n )\n \n instrumentation_info = InstrumentationInfo(\ndiff --git a/opentelemetry/sdk/util/instrumentation.py b/opentelemetry/sdk/util/instrumentation.py\nindex ac64c2d..9cf8491 100644\n--- a/opentelemetry/sdk/util/instrumentation.py\n+++ b/opentelemetry/sdk/util/instrumentation.py\n@@ -13,6 +13,18 @@ from opentelemetry.agent._vendor.opentelemetry.util.types import ( # TODO: see\n )\n \n \n+# opentelemetry-agent: instrumentations vendored under the agent's namespace name their scope after\n+# their module (get_tracer(__name__)); report the upstream module name instead, e.g.\n+# \"opentelemetry.instrumentation.aiohttp_client\" rather than \"opentelemetry.agent._vendor.opentelemetry...\".\n+_VENDOR_PREFIX = __name__.removesuffix(\"opentelemetry.sdk.util.instrumentation\")\n+\n+\n+def _unvendored_name(name: str) -> str:\n+ if isinstance(name, str) and name.startswith(_VENDOR_PREFIX):\n+ return name[len(_VENDOR_PREFIX) :]\n+ return name\n+\n+\n class InstrumentationInfo:\n \"\"\"Immutable information about an instrumentation library module.\n \n@@ -29,7 +41,7 @@ class InstrumentationInfo:\n version: str | None = None,\n schema_url: str | None = None,\n ):\n- self._name = name\n+ self._name = _unvendored_name(name)\n self._version = version\n if schema_url is None:\n schema_url = \"\"\n@@ -92,7 +104,7 @@ class InstrumentationScope:\n schema_url: str | None = None,\n attributes: Attributes = None,\n ) -> None:\n- self._name = name\n+ self._name = _unvendored_name(name)\n self._version = version\n if schema_url is None:\n schema_url = \"\"\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - }, - { - "diff": { - "text": { - "content": "Scope OpenTelemetry's entry point lookups to the vendored distributions.\n\nAll OpenTelemetry plugin discovery (distro, configurator, instrumentors, exporters, samplers,\npropagators, resource detectors, HTTP transports) goes through opentelemetry.util._importlib_metadata.\nUpstream it reads every installed distribution's entry points: the vendored copies have no\ndist-info on sys.path, and the application's OpenTelemetry plugins point at un-vendored modules.\nopentelemetry-vendor sync keeps the vendored distributions' METADATA and namespaced entry points in\n_vendor/_metadata (metadata-dir); entry_points() and distributions() only search there.\n\nversion() and requires() keep looking at the application's distributions: instrumentors check that the\ninstalled version of the library they patch matches their \"instruments\" requirements.\n\ndiff --git a/opentelemetry/util/_importlib_metadata.py b/opentelemetry/util/_importlib_metadata.py\nindex 656afbb..c7c5399 100644\n--- a/opentelemetry/util/_importlib_metadata.py\n+++ b/opentelemetry/util/_importlib_metadata.py\n@@ -11,38 +11,35 @@ It also normalizes minor differences across python versions 3.10+. References to\n - https://github.com/open-telemetry/opentelemetry-python/pull/5203\n \"\"\"\n \n-import itertools\n+import os\n from functools import cache\n from importlib.metadata import (\n Distribution,\n EntryPoint,\n EntryPoints,\n PackageNotFoundError,\n- distributions,\n requires,\n version,\n )\n-from importlib.metadata import entry_points as original_entry_points\n-from typing import Any\n+from importlib.metadata import distributions as _all_distributions\n+from typing import Any, Iterable\n+\n+# opentelemetry-agent: entry points are only looked up in the vendored distributions' metadata\n+# (written to _vendor/_metadata by opentelemetry-vendor sync), never in the application's, whose\n+# OpenTelemetry plugins point at un-vendored modules. version() and requires() still see the\n+# application's distributions: instrumentors check the installed versions of the libraries they patch.\n+_VENDORED_METADATA_PATH = [\n+ os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), \"_metadata\")\n+]\n \n \n-def _as_entry_points(eps: Any) -> EntryPoints:\n- # Python versions greater than 3.11 return EntryPoints.\n- if isinstance(eps, EntryPoints):\n- return eps\n- # In Python 3.10 and 3.11 entry_points() returns\n- # a dict-like SelectableGroups object.\n- # Use dict.values() instead of eps.values() to avoid the DeprecationWarning\n- # that SelectableGroups raises when calling .values().\n- if isinstance(eps, dict):\n- return EntryPoints(itertools.chain.from_iterable(dict.values(eps)))\n- # This case should be unreachable, but is included as a fallback.\n- return EntryPoints(ep for group in eps.groups for ep in eps.select(group=group))\n+def distributions(**kwargs: Any) -> Iterable[Distribution]:\n+ return _all_distributions(path=_VENDORED_METADATA_PATH, **kwargs)\n \n \n @cache\n def _original_entry_points_cached() -> EntryPoints:\n- return _as_entry_points(original_entry_points())\n+ return EntryPoints(entry_point for dist in distributions() for entry_point in dist.entry_points)\n \n \n def entry_points(**params) -> EntryPoints:\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - } - ] - }, - "purl": "pkg:pypi/opentelemetry-util-http@0.66b2", - "type": "library", - "version": "0.66b2" - }, - { - "bom-ref": "pkg:pypi/packaging@26.3", - "hashes": [ - { - "alg": "SHA-256", - "content": "d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c" - } - ], - "licenses": [ - { - "expression": "Apache-2.0 OR BSD-2-Clause" - } - ], - "name": "packaging", - "purl": "pkg:pypi/packaging@26.3", - "type": "library", - "version": "26.3" - }, - { - "bom-ref": "pkg:pypi/prometheus-client@0.26.0", - "hashes": [ - { - "alg": "SHA-256", - "content": "fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6" - } - ], - "licenses": [ - { - "expression": "Apache-2.0 AND BSD-2-Clause" - } - ], - "name": "prometheus-client", - "purl": "pkg:pypi/prometheus-client@0.26.0", - "type": "library", - "version": "0.26.0" - }, - { - "bom-ref": "pkg:pypi/protobuf@7.36.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "bdb3a345d48db958e6ce1f18e508beb0cc981d64f24088427549c866cd039f1e" - } - ], - "licenses": [ - { - "license": { - "name": "3-Clause BSD License" - } - } - ], - "name": "protobuf", - "pedigree": { - "patches": [ - { - "diff": { - "text": { - "content": "Select the vendored protobuf implementation: upb when built, else pure Python.\n\nUpstream probes for the upb/cpp C extensions with importlib.import_module(\"google._upb._message\")\nand friends, which imports the application's protobuf by its top-level name, and honours\nPROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which is meant for the application's protobuf: \"cpp\" makes\ndescriptor.py import the missing vendored pyext and crash. Only the vendored upb extension (included in\nplatform builds of the agent, see patches/native/protobuf-upb.patch) is considered; otherwise the\npure-Python implementation is used.\n\ndiff --git a/google/protobuf/internal/api_implementation.py b/google/protobuf/internal/api_implementation.py\n--- a/google/protobuf/internal/api_implementation.py\n+++ b/google/protobuf/internal/api_implementation.py\n@@ -6,7 +6,6 @@\n # https://developers.google.com/open-source/licenses/bsd\n \"\"\"Determine which implementation of the protobuf API is used in this process.\"\"\"\n \n-import importlib\n import os\n import sys\n import warnings\n@@ -24,89 +23,19 @@ def _ApiVersionToImplementationType(api_version):\n return None\n \n \n-_implementation_type = None\n+# Only the vendored upb extension is considered (platform builds of the agent include it;\n+# the pure-Python build doesn't). Never probe for the application's google._upb /\n+# google.protobuf.pyext by their top-level names, and don't follow\n+# PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which configures the application's protobuf\n+# (e.g. \"cpp\" would make descriptor.py import the missing vendored pyext._message).\n try:\n # pylint: disable=g-import-not-at-top\n- from opentelemetry.agent._vendor.google.protobuf.internal import _api_implementation\n- # The compile-time constants in the _api_implementation module can be used to\n- # switch to a certain implementation of the Python API at build time.\n- _implementation_type = _ApiVersionToImplementationType(\n- _api_implementation.api_version\n- )\n-except ImportError:\n- pass # Unspecified by compiler flags.\n-\n-\n-def _CanImport(mod_name):\n- try:\n- mod = importlib.import_module(mod_name)\n- # Work around a known issue in the classic bootstrap .par import hook.\n- if not mod:\n- raise ImportError(mod_name + ' import succeeded but was None')\n- return True\n- except ImportError:\n- return False\n-\n-\n-if _implementation_type is None:\n- if _CanImport('google._upb._message'):\n- _implementation_type = 'upb'\n- elif _CanImport('google.protobuf.pyext._message'):\n- _implementation_type = 'cpp'\n- else:\n- _implementation_type = 'python'\n-\n-# This environment variable can be used to switch to a certain implementation\n-# of the Python API, overriding the compile-time constants in the\n-# _api_implementation module. Right now only 'python', 'cpp' and 'upb' are\n-# valid values. Any other value will raise error.\n-_implementation_type = os.getenv(\n- 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', _implementation_type\n-)\n-\n-if _implementation_type not in ('python', 'cpp', 'upb'):\n- raise ValueError(\n- 'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION {0} is not '\n- \"supported. Please set to 'python', 'cpp' or \"\n- \"'upb'.\".format(_implementation_type)\n- )\n+ from opentelemetry.agent._vendor.google._upb import _message as _c_module\n \n-if 'PyPy' in sys.version and _implementation_type == 'cpp':\n- warnings.warn(\n- 'PyPy does not work yet with cpp protocol buffers. '\n- 'Falling back to the python implementation.'\n- )\n+ _implementation_type = 'upb'\n+except ImportError:\n _implementation_type = 'python'\n-\n-_c_module = None\n-\n-if _implementation_type == 'cpp':\n- try:\n- # pylint: disable=g-import-not-at-top\n- from opentelemetry.agent._vendor.google.protobuf.pyext import _message\n-\n- sys.modules['google3.net.proto2.python.internal.cpp._message'] = _message\n- _c_module = _message\n- del _message\n- except ImportError:\n- # TODO: fail back to python\n- warnings.warn('Selected implementation cpp is not available.')\n- pass\n-\n-if _implementation_type == 'upb':\n- try:\n- # pylint: disable=g-import-not-at-top\n- from opentelemetry.agent._vendor.google._upb import _message\n-\n- _c_module = _message\n- del _message\n- except ImportError:\n- warnings.warn(\n- 'Selected implementation upb is not available. '\n- 'Falling back to the python implementation.'\n- )\n- _implementation_type = 'python'\n- pass\n+ _c_module = None\n \n # Detect if serialization should be deterministic by default\n try:\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - } - ] - }, - "purl": "pkg:pypi/protobuf@7.36.2", - "type": "library", - "version": "7.36.2" - }, - { - "bom-ref": "pkg:pypi/requests@2.34.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" - } - ], - "licenses": [ - { - "license": { - "id": "Apache-2.0" - } - } - ], - "name": "requests", - "pedigree": { - "patches": [ - { - "diff": { - "text": { - "content": "Disable the requests.packages compatibility aliases.\n\nUpstream imports urllib3/idna/chardet by their top-level names and registers them as\n`requests.packages.*` in the global sys.modules, which would load and alias the\napplication's own packages.\n\ndiff --git a/requests/packages.py b/requests/packages.py\n--- a/requests/packages.py\n+++ b/requests/packages.py\n@@ -1,23 +1,4 @@\n-import sys\n-\n-from .compat import chardet\n-\n-# This code exists for backwards compatibility reasons.\n-# I don't like it either. Just look the other way. :)\n-\n-for package in (\"urllib3\", \"idna\"):\n- locals()[package] = __import__(package)\n- # This traversal is apparently necessary such that the identities are\n- # preserved (requests.packages.urllib3.* is urllib3.*)\n- for mod in list(sys.modules):\n- if mod == package or mod.startswith(f\"{package}.\"):\n- sys.modules[f\"requests.packages.{mod}\"] = sys.modules[mod]\n-\n-if chardet is not None:\n- target = chardet.__name__\n- for mod in list(sys.modules):\n- if mod == target or mod.startswith(f\"{target}.\"):\n- imported_mod = sys.modules[mod]\n- sys.modules[f\"requests.packages.{mod}\"] = imported_mod\n- mod = mod.replace(target, \"chardet\")\n- sys.modules[f\"requests.packages.{mod}\"] = imported_mod\n+# The upstream module imports urllib3, idna and chardet by their top-level names and\n+# registers them as `requests.packages.*` in the global sys.modules. In the vendored copy\n+# that would load (and alias) the application's own packages, so the backwards\n+# compatibility aliases are disabled.\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - }, - { - "diff": { - "text": { - "content": "Use the vendored charset_normalizer instead of looking up chardet.\n\nUpstream prefers an installed chardet (via importlib.import_module and a version\nimport), which would load the application's package.\n\ndiff --git a/requests/__init__.py b/requests/__init__.py\n--- a/requests/__init__.py\n+++ b/requests/__init__.py\n@@ -51,10 +51,8 @@ try:\n except ImportError:\n charset_normalizer_version = None\n \n-try:\n- from chardet import __version__ as chardet_version # type: ignore[import-not-found]\n-except ImportError:\n- chardet_version = None\n+# Only the vendored charset_normalizer is used, never the application's chardet.\n+chardet_version = None\n \n \n def check_compatibility(\ndiff --git a/requests/compat.py b/requests/compat.py\n--- a/requests/compat.py\n+++ b/requests/compat.py\n@@ -34,19 +34,8 @@ except (TypeError, AttributeError):\n # -------------------\n \n \n-def _resolve_char_detection() -> ModuleType | None:\n- \"\"\"Find supported character detection libraries.\"\"\"\n- chardet = None\n- for lib in (\"chardet\", \"charset_normalizer\"):\n- if chardet is None:\n- try:\n- chardet = importlib.import_module(lib)\n- except ImportError:\n- pass\n- return chardet\n-\n-\n-chardet = _resolve_char_detection()\n+# Always use the vendored charset_normalizer, never the application's chardet.\n+from opentelemetry.agent._vendor import charset_normalizer as chardet\n \n # -------\n # Pythons\n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - } - ] - }, - "purl": "pkg:pypi/requests@2.34.2", - "type": "library", - "version": "2.34.2" - }, - { - "bom-ref": "pkg:pypi/ruamel-yaml@0.19.1", - "hashes": [ - { - "alg": "SHA-256", - "content": "27592957fedf6e0b62f281e96effd28043345e0e66001f97683aa9a40c667c93" - } - ], - "licenses": [ - { - "license": { - "id": "MIT" - } - } - ], - "name": "ruamel-yaml", - "pedigree": { - "patches": [ - { - "diff": { - "text": { - "content": "Never load the libyaml binding in the vendored ruamel.yaml.\n\nruamel.yaml imports the optional C parser and emitter from the _ruamel_yaml extension module\n(ruamel.yaml.clib), which would be the application's, not vendored. ruamel/yaml/cyaml.py is dropped; this\npatch makes main.py fall back to the pure-Python implementation unconditionally.\n\ndiff --git a/ruamel/yaml/main.py b/ruamel/yaml/main.py\nindex fdf7c72..5e23910 100644\n--- a/ruamel/yaml/main.py\n+++ b/ruamel/yaml/main.py\n@@ -42,10 +42,9 @@ if False: # MYPY\n from types import TracebackType\n from pathlib import Path\n \n-try:\n- from _ruamel_yaml import CParser, CEmitter # type: ignore\n-except: # NOQA\n- CParser = CEmitter = None\n+# opentelemetry-agent: always use the pure-Python parser and emitter; the libyaml binding\n+# (_ruamel_yaml) would be the application's, not vendored.\n+CParser = CEmitter = None\n \n # import io\n \n", - "contentType": "text/plain" - } - }, - "type": "unofficial" - } - ] - }, - "purl": "pkg:pypi/ruamel-yaml@0.19.1", - "type": "library", - "version": "0.19.1" - }, - { - "bom-ref": "pkg:pypi/typing-extensions@4.16.0", - "hashes": [ - { - "alg": "SHA-256", - "content": "481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8" - } - ], - "licenses": [ - { - "license": { - "id": "PSF-2.0" - } - } - ], - "name": "typing-extensions", - "purl": "pkg:pypi/typing-extensions@4.16.0", - "type": "library", - "version": "4.16.0" - }, - { - "bom-ref": "pkg:pypi/urllib3@2.8.0", - "hashes": [ - { - "alg": "SHA-256", - "content": "0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3" - } - ], - "licenses": [ - { - "license": { - "id": "MIT" - } - } - ], - "name": "urllib3", - "purl": "pkg:pypi/urllib3@2.8.0", - "type": "library", - "version": "2.8.0" - }, - { - "bom-ref": "pkg:pypi/wrapt@2.5.2", - "hashes": [ - { - "alg": "SHA-256", - "content": "61eb54e9540ea522c2c4752a57549a83d3c67e6704ed708403d28e067aaf90f0" - } - ], - "licenses": [ - { - "license": { - "id": "BSD-2-Clause" - } - } - ], - "name": "wrapt", - "purl": "pkg:pypi/wrapt@2.5.2", - "type": "library", - "version": "2.5.2" - } - ], - "dependencies": [ - { - "ref": "pkg:pypi/certifi@2026.10.23" - }, - { - "ref": "pkg:pypi/charset-normalizer@3.5.2" - }, - { - "ref": "pkg:pypi/fastjsonschema@2.22.3" - }, - { - "ref": "pkg:pypi/googleapis-common-protos@1.76.0" - }, - { - "ref": "pkg:pypi/idna@3.20" - }, - { - "ref": "pkg:pypi/opentelemetry-api@1.45.2" - }, - { - "ref": "pkg:pypi/opentelemetry-configuration@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-distro@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-http-transport@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-otlp-common@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-otlp-json-common@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-otlp-json-file@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-otlp-json-http@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-common@1.45.2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-otlp-proto-http@1.45.2" - }, - { - "ref": "pkg:pypi/opentelemetry-exporter-prometheus@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-instrumentation-aiohttp-client@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-instrumentation@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-propagator-b3@1.45.2" - }, - { - "ref": "pkg:pypi/opentelemetry-proto-json@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-proto@1.45.2" - }, - { - "ref": "pkg:pypi/opentelemetry-sdk@1.45.2" - }, - { - "ref": "pkg:pypi/opentelemetry-semantic-conventions@0.66b2" - }, - { - "ref": "pkg:pypi/opentelemetry-util-http@0.66b2" - }, - { - "ref": "pkg:pypi/packaging@26.3" - }, - { - "ref": "pkg:pypi/prometheus-client@0.26.0" - }, - { - "ref": "pkg:pypi/protobuf@7.36.2" - }, - { - "ref": "pkg:pypi/requests@2.34.2" - }, - { - "ref": "pkg:pypi/ruamel-yaml@0.19.1" - }, - { - "ref": "pkg:pypi/typing-extensions@4.16.0" - }, - { - "ref": "pkg:pypi/urllib3@2.8.0" - }, - { - "ref": "pkg:pypi/wrapt@2.5.2" - } - ], - "metadata": {}, - "serialNumber": "urn:uuid:68c0eaa7-7e90-530a-b51b-92b28a55e1b4", - "version": 1, - "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", - "bomFormat": "CycloneDX", - "specVersion": "1.6" -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE deleted file mode 100644 index 62b076cdee5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi.LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -This package contains a modified version of ca-bundle.crt: - -ca-bundle.crt -- Bundle of CA Root Certificates - -This is a bundle of X.509 certificates of public Certificate Authorities -(CA). These were automatically extracted from Mozilla's root certificates -file (certdata.txt). This file can be found in the mozilla source tree: -https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt -It contains the certificates in PEM format and therefore -can be directly used with curl / libcurl / php_curl, or with -an Apache+mod_ssl webserver for SSL client authentication. -Just configure this file as the SSLCACertificateFile.# - -***** BEGIN LICENSE BLOCK ***** -This Source Code Form is subject to the terms of the Mozilla Public License, -v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain -one at http://mozilla.org/MPL/2.0/. - -***** END LICENSE BLOCK ***** -@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py deleted file mode 100644 index 1a9a755b6b6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .core import contents, where - -__all__ = ["contents", "where"] -__version__ = "2026.10.23" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem deleted file mode 100644 index 7b1cc2d81b6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/cacert.pem +++ /dev/null @@ -1,3885 +0,0 @@ - -# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited -# Label: "COMODO ECC Certification Authority" -# Serial: 41578283867086692638256921589707938090 -# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 -# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 -# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL -MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE -BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT -IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw -MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy -ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N -T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR -FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J -cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW -BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm -fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv -GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) -# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) -# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" -# Serial: 80544274841616 -# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 -# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 -# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG -EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 -MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl -cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR -dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB -pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM -b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm -aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz -IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT -lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz -AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 -VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG -ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 -BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG -AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M -U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh -bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C -+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F -uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 -XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. -# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. -# Label: "Microsec e-Szigno Root CA 2009" -# Serial: 14014712776195784473 -# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 -# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e -# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G -CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y -OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx -FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp -Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP -kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc -cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U -fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 -N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC -xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 -+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM -Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG -SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h -mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk -ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c -2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t -HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 -# Label: "GlobalSign Root CA - R3" -# Serial: 4835703278459759426209954 -# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 -# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad -# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G -A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp -Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 -MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG -A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 -RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT -gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm -KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd -QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ -XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o -LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU -RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp -jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK -6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX -mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs -Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH -WD9f ------END CERTIFICATE----- - -# Issuer: CN=Izenpe.com O=IZENPE S.A. -# Subject: CN=Izenpe.com O=IZENPE S.A. -# Label: "Izenpe.com" -# Serial: 917563065490389241595536686991402621 -# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 -# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 -# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f ------BEGIN CERTIFICATE----- -MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 -MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 -ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD -VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j -b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq -scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO -xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H -LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX -uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD -yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ -JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q -rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN -BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L -hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB -QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ -HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu -Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg -QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB -BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx -MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA -A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb -laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 -awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo -JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw -LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT -VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk -LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb -UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ -QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ -naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls -QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== ------END CERTIFICATE----- - -# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. -# Label: "Go Daddy Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 -# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b -# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz -NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE -AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD -E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH -/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy -DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh -GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR -tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA -AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX -WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu -9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr -gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo -2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI -4uJEvlz36hz1 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 -# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e -# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw -MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp -Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg -nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 -HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N -Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN -dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 -HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G -CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU -sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 -4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg -8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 -mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. -# Label: "Starfield Services Root Certificate Authority - G2" -# Serial: 0 -# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 -# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f -# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs -ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy -dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p -OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 -8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K -Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe -hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk -6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q -AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI -bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB -ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z -qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn -0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN -sSi6 ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Network CA" -# Serial: 279744 -# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 -# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e -# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM -MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D -ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU -cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 -WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg -Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw -IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH -UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM -TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU -BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM -kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x -AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV -HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y -sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL -I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 -J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY -VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA -# Label: "TWCA Root Certification Authority" -# Serial: 1 -# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 -# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 -# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES -MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU -V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz -WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO -LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE -AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH -K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX -RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z -rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx -3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq -hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC -MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls -XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D -lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn -aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ -YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 -# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 -# Label: "Security Communication RootCA2" -# Serial: 0 -# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 -# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 -# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl -MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe -U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX -DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy -dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj -YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV -OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr -zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM -VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ -hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO -ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw -awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs -OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 -DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF -coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc -okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 -t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy -1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ -SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 -# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 -# Label: "Actalis Authentication Root CA" -# Serial: 6271844772424770508 -# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 -# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac -# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE -BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w -MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC -SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 -ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv -UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX -4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 -KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ -gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb -rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ -51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F -be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe -KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F -v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn -fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 -jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz -ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL -e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 -jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz -WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V -SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j -pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX -X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok -fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R -K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU -ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU -LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT -LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- - -# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 -# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 -# Label: "Buypass Class 2 Root CA" -# Serial: 2 -# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 -# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 -# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr -6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV -L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 -1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx -MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ -QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB -arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr -Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi -FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS -P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN -9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz -uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h -9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t -OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo -+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 -KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 -DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us -H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ -I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 -5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h -3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz -Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= ------END CERTIFICATE----- - -# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 -# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 -# Label: "Buypass Class 3 Root CA" -# Serial: 2 -# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec -# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 -# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg -Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow -TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw -HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y -ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E -N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 -tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX -0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c -/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X -KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY -zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS -O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D -34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP -K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 -AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv -Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj -QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS -IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 -HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa -O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv -033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u -dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE -kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 -3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD -u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq -4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= ------END CERTIFICATE----- - -# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Label: "T-TeleSec GlobalRoot Class 3" -# Serial: 1 -# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef -# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 -# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN -8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ -RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 -hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 -ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM -EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 -A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy -WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ -1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 -6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT -91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p -TpPDpFQUWw== ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH -# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH -# Label: "D-TRUST Root Class 3 CA 2 2009" -# Serial: 623603 -# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f -# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 -# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha -ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM -HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB -BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 -UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 -tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R -ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM -lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp -/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G -A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy -MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl -cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js -L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL -BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni -acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K -zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 -PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y -Johw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH -# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH -# Label: "D-TRUST Root Class 3 CA 2 EV 2009" -# Serial: 623604 -# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 -# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 -# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF -MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD -bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw -NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV -BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn -ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 -3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z -qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR -p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 -HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw -ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea -HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw -Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh -c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E -RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt -dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku -Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp -3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF -CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na -xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX -KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 ------END CERTIFICATE----- - -# Issuer: CN=CA Disig Root R2 O=Disig a.s. -# Subject: CN=CA Disig Root R2 O=Disig a.s. -# Label: "CA Disig Root R2" -# Serial: 10572350602393338211 -# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 -# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 -# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV -BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu -MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy -MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx -EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe -NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH -PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I -x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe -QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR -yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO -QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 -H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ -QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD -i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs -nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 -rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI -hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf -GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb -lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka -+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal -TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i -nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 -gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr -G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os -zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x -L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- - -# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV -# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV -# Label: "ACCVRAIZ1" -# Serial: 6828503384748696800 -# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 -# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 -# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE -AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw -CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ -BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND -VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb -qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY -HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo -G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA -lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr -IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ -0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH -k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 -4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO -m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa -cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl -uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI -KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls -ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG -AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT -VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG -CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA -cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA -QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA -7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA -cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA -QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA -czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu -aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt -aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud -DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF -BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp -D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU -JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m -AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD -vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms -tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH -7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA -h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF -d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H -pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- - -# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA -# Label: "TWCA Global Root CA" -# Serial: 3262 -# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 -# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 -# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx -EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT -VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 -NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT -B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF -10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz -0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh -MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH -zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc -46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 -yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi -laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP -oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA -BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE -qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm -4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL -1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF -H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo -RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ -nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh -15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW -6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW -nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j -wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz -aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy -KwbQBM0= ------END CERTIFICATE----- - -# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center -# Label: "T-TeleSec GlobalRoot Class 2" -# Serial: 1 -# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a -# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 -# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx -KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd -BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl -YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 -OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy -aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 -ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd -AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC -FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi -1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq -jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ -wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ -WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy -NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC -uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw -IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 -g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP -BSeOE6Fuwg== ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 1 G3" -# Serial: 687049649626669250736271037606554624078720034195 -# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab -# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 -# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 -MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV -wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe -rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 -68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh -4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp -UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o -abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc -3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G -KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt -hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO -Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt -zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD -ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 -cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN -qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 -YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv -b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 -8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k -NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj -ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp -q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt -nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 2 G3" -# Serial: 390156079458959257446133169266079962026824725800 -# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 -# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 -# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 -MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf -qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW -n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym -c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ -O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 -o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j -IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq -IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz -8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh -vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l -7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG -cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD -ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC -roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga -W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n -lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE -+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV -csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd -dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg -KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM -HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 -WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M ------END CERTIFICATE----- - -# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited -# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited -# Label: "QuoVadis Root CA 3 G3" -# Serial: 268090761170461462463995952157327242137089239581 -# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 -# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d -# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL -BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc -BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 -MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM -aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR -/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu -FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR -U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c -ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR -FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k -A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw -eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl -sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp -VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q -A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ -ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD -ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI -FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv -oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg -u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP -0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf -3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl -8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ -DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN -PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ -ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root G2" -# Serial: 15385348160840213938643033620894905419 -# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d -# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f -# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv -b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl -cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA -n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc -biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp -EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA -bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu -YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB -AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW -BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI -QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I -0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni -lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 -B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv -ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Assured ID Root G3" -# Serial: 15459312981008553731928384953135426796 -# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb -# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 -# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg -RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf -Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q -RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ -BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD -AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY -JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv -6pZjamVFkpUBtA== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root G2" -# Serial: 4293743540046975378534879503202253541 -# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 -# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 -# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH -MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI -2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx -1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ -q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz -tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ -vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV -5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY -1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 -NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG -Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 -8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe -pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Global Root G3" -# Serial: 7089244469030293291760083333884364146 -# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca -# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e -# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw -CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu -ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe -Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw -EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG -fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO -Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd -BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx -AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ -oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 -sycX ------END CERTIFICATE----- - -# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com -# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com -# Label: "DigiCert Trusted Root G4" -# Serial: 7451500558977370777930084869016614236 -# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 -# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 -# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg -RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu -Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y -ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If -xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV -ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO -DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ -jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ -CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi -EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM -fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY -uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK -chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t -9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB -hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 -SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd -+SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc -fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa -sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N -cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N -0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie -4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI -r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 -/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm -gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ ------END CERTIFICATE----- - -# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited -# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited -# Label: "COMODO RSA Certification Authority" -# Serial: 101909084537582093308941363524873193117 -# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 -# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 -# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 ------BEGIN CERTIFICATE----- -MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB -hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV -BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT -EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR -6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X -pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC -9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV -/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf -Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z -+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w -qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah -SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC -u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf -Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq -crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E -FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB -/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl -wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM -4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV -2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna -FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ -CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK -boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke -jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL -S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb -QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl -0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB -NVOFBkpdn627G190 ------END CERTIFICATE----- - -# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network -# Label: "USERTrust RSA Certification Authority" -# Serial: 2645093764781058787591871645665788717 -# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 -# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e -# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- - -# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network -# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network -# Label: "USERTrust ECC Certification Authority" -# Serial: 123013823720199481456569720443997572134 -# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 -# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 -# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl -eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT -JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx -MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT -Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg -VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm -aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo -I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng -o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G -A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB -zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW -RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 -# Label: "GlobalSign ECC Root CA - R5" -# Serial: 32785792099990507226680698011560947931244 -# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 -# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa -# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc -8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke -hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI -KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg -515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO -xwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- - -# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust -# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust -# Label: "IdenTrust Commercial Root CA 1" -# Serial: 13298821034946342390520003877796839426 -# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 -# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 -# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu -VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw -MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw -JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT -3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU -+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp -S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 -bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi -T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL -vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK -Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK -dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT -c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv -l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N -iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD -ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt -LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 -nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 -+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK -W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT -AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq -l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG -4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ -mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A -7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H ------END CERTIFICATE----- - -# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust -# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust -# Label: "IdenTrust Public Sector Root CA 1" -# Serial: 13298821034946342390521976156843933698 -# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba -# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd -# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu -VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN -MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 -MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 -ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy -RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS -bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF -/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R -3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw -EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy -9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V -GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ -2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV -WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD -W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN -AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV -DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 -TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G -lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW -mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df -WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 -+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ -tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA -GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv -8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- - -# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority -# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority -# Label: "CFCA EV ROOT" -# Serial: 407555286 -# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 -# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 -# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD -TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y -aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx -MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j -aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP -T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 -sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL -TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 -/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp -7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz -EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt -hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP -a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot -aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg -TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV -PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv -cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL -tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd -BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT -ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL -jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS -ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy -P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 -xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d -Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN -5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe -/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z -AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ -5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- - -# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GB CA" -# Serial: 157768595616588414422159278966750757568 -# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d -# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed -# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt -MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg -Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i -YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x -CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG -b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 -HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx -WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX -1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk -u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P -99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r -M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB -BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh -cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 -gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO -ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf -aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- - -# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. -# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. -# Label: "SZAFIR ROOT CA2" -# Serial: 357043034767186914217277344587386743377558296292 -# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 -# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de -# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 -ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw -NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L -cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg -Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN -QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT -3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw -3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 -3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 -BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN -XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF -AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw -8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG -nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP -oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy -d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg -LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Network CA 2" -# Serial: 44979900017204383099463764357512596969 -# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 -# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 -# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB -gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu -QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG -A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz -OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ -VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 -b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA -DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn -0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB -OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE -fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E -Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m -o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i -sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW -OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez -Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS -adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n -3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ -F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf -CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 -XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm -djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ -WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb -AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq -P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko -b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj -XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P -5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi -DrW5viSP ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions RootCA 2015" -# Serial: 0 -# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce -# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 -# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix -DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k -IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT -N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v -dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG -A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh -ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx -QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 -dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC -AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA -4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 -AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 -4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C -ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV -9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD -gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 -Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq -NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko -LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd -ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I -XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI -M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot -9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V -Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea -j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh -X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ -l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf -bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 -pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK -e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 -vm9qp/UsQu0yrbYhnr68 ------END CERTIFICATE----- - -# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority -# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" -# Serial: 0 -# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef -# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 -# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN -BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl -bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv -b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ -BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj -YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 -MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 -dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg -QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa -jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi -C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep -lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof -TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- - -# Issuer: CN=ISRG Root X1 O=Internet Security Research Group -# Subject: CN=ISRG Root X1 O=Internet Security Research Group -# Label: "ISRG Root X1" -# Serial: 172886928669790476064670243504169061120 -# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e -# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 -# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- - -# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM -# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM -# Label: "AC RAIZ FNMT-RCM" -# Serial: 485876308206448804701554682760554759 -# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d -# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 -# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ -WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ -BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG -Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ -yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf -BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz -WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF -tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z -374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC -IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL -mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 -wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS -MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 -ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet -UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H -YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 -LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 -RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM -LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf -77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N -JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm -fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp -6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp -1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B -9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok -RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv -uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 1 O=Amazon -# Subject: CN=Amazon Root CA 1 O=Amazon -# Label: "Amazon Root CA 1" -# Serial: 143266978916655856878034712317230054538369994 -# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 -# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 -# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj -ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM -9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw -IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 -VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L -93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm -jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA -A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI -U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs -N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv -o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU -5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy -rqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 2 O=Amazon -# Subject: CN=Amazon Root CA 2 O=Amazon -# Label: "Amazon Root CA 2" -# Serial: 143266982885963551818349160658925006970653239 -# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 -# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a -# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF -ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 -b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL -MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv -b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK -gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ -W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg -1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K -8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r -2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me -z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR -8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj -mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz -7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 -+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI -0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm -UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 -LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS -k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl -7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm -btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl -urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ -fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 -n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE -76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H -9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT -4PsJYGw= ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 3 O=Amazon -# Subject: CN=Amazon Root CA 3 O=Amazon -# Label: "Amazon Root CA 3" -# Serial: 143266986699090766294700635381230934788665930 -# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 -# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e -# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl -ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j -QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr -ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr -BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM -YyRIHN8wfdVoOw== ------END CERTIFICATE----- - -# Issuer: CN=Amazon Root CA 4 O=Amazon -# Subject: CN=Amazon Root CA 4 O=Amazon -# Label: "Amazon Root CA 4" -# Serial: 143266989758080763974105200630763877849284878 -# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd -# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be -# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 -MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g -Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG -A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg -Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi -9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk -M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB -MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw -CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW -1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- - -# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM -# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM -# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" -# Serial: 1 -# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 -# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca -# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx -GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp -bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w -KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 -BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy -dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG -EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll -IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU -QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT -TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg -LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 -a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr -LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr -N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X -YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ -iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f -AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH -V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf -IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 -lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c -8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf -lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- - -# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. -# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. -# Label: "GDCA TrustAUTH R5 ROOT" -# Serial: 9009899650740120186 -# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 -# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 -# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE -BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 -MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV -BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w -HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF -AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj -Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj -TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u -KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj -qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm -MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 -ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP -zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk -L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC -jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA -HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC -AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm -DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 -COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry -L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf -JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg -IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io -2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV -09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ -XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq -T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe -MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- - -# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation -# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation -# Label: "SSL.com Root Certification Authority RSA" -# Serial: 8875640296558310041 -# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 -# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb -# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE -BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK -DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz -OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R -xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX -qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC -C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 -6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh -/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF -YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E -JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc -US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 -ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm -+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi -M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G -A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV -cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc -Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs -PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ -q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 -cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr -a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I -H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y -K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu -nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf -oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY -Ic2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- - -# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation -# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation -# Label: "SSL.com Root Certification Authority ECC" -# Serial: 8495723813297216424 -# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e -# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a -# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz -WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 -b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS -b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI -7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg -CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD -VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T -kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ -gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- - -# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation -# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation -# Label: "SSL.com EV Root Certification Authority RSA R2" -# Serial: 6248227494352943350 -# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 -# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a -# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV -BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE -CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy -MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G -A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD -DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq -M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf -OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa -4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 -HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR -aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA -b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ -Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV -PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO -pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu -UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY -MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 -9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW -s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 -Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg -cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM -79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz -/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt -ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm -Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK -QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ -w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi -S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 -mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- - -# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation -# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation -# Label: "SSL.com EV Root Certification Authority ECC" -# Serial: 3182246526754555285 -# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 -# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d -# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC -VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T -U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx -NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv -dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv -bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA -VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku -WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX -5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ -ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg -h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 -# Label: "GlobalSign Root CA - R6" -# Serial: 1417766617973444989252670301619537 -# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae -# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 -# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg -MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx -MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET -MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI -xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k -ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD -aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw -LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw -1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX -k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 -SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h -bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n -WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY -rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce -MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu -bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt -Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 -55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj -vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf -cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz -oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp -nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs -pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v -JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R -8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 -5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- - -# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed -# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed -# Label: "OISTE WISeKey Global Root GC CA" -# Serial: 44084345621038548146064804565436152554 -# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 -# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 -# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw -CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 -bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg -Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ -BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu -ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS -b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni -eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W -p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T -rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV -57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg -Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- - -# Issuer: CN=UCA Global G2 Root O=UniTrust -# Subject: CN=UCA Global G2 Root O=UniTrust -# Label: "UCA Global G2 Root" -# Serial: 124779693093741543919145257850076631279 -# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 -# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a -# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH -bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x -CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds -b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr -b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 -kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm -VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R -VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc -C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj -tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY -D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv -j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl -NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 -iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP -O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV -ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj -L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl -1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU -b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV -PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj -y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb -EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg -DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI -+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy -YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX -UB+K+wb1whnw0A== ------END CERTIFICATE----- - -# Issuer: CN=UCA Extended Validation Root O=UniTrust -# Subject: CN=UCA Extended Validation Root O=UniTrust -# Label: "UCA Extended Validation Root" -# Serial: 106100277556486529736699587978573607008 -# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 -# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a -# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH -MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF -eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx -MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV -BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog -D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS -sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop -O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk -sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi -c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj -VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz -KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ -TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G -sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs -1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD -fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T -AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN -l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ -VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 -c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp -4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s -t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj -2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO -vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C -xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx -cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM -fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax ------END CERTIFICATE----- - -# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 -# Label: "Certigna Root CA" -# Serial: 269714418870597844693661054334862075617 -# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 -# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 -# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw -WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw -MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x -MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD -VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX -BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO -ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M -CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu -I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm -TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh -C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf -ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz -IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT -Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k -JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 -hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB -GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov -L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo -dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr -aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq -hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L -6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG -HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 -0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB -lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi -o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 -gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v -faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 -Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh -jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw -3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- - -# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI -# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI -# Label: "emSign Root CA - G1" -# Serial: 235931866688319308814040 -# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac -# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c -# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD -VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU -ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH -MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO -MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv -Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz -f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO -8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq -d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM -tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt -Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB -o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x -PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM -wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d -GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH -6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby -RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- - -# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post -# Label: "Hongkong Post Root CA 3" -# Serial: 46170865288971385588281144162979347873371282084 -# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 -# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 -# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 ------BEGIN CERTIFICATE----- -MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL -BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ -SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n -a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 -NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT -CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u -Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO -dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI -VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV -9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY -2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY -vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt -bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb -x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ -l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK -TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj -Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e -i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw -DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG -7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk -MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr -gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk -GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS -3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm -Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ -l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c -JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP -L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa -LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG -mpv0 ------END CERTIFICATE----- - -# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation -# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation -# Label: "Microsoft ECC Root Certificate Authority 2017" -# Serial: 136839042543790627607696632466672567020 -# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 -# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 -# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw -CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD -VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw -MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy -b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR -ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb -hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E -BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 -FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV -L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB -iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- - -# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation -# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation -# Label: "Microsoft RSA Root Certificate Authority 2017" -# Serial: 40975477897264996090493496164228220339 -# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 -# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 -# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl -MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 -IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N -aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ -Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 -ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 -HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm -gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ -jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc -aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG -YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 -W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K -UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH -+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q -W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC -LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC -gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 -tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh -SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 -TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 -pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR -xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp -GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 -dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN -AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB -RA+GsCyRxj3qrg+E ------END CERTIFICATE----- - -# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. -# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. -# Label: "e-Szigno Root CA 2017" -# Serial: 411379200276854331539784714 -# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 -# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 -# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV -BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk -LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv -b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ -BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg -THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v -IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv -xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H -Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G -A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB -eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo -jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ -+efcMQ== ------END CERTIFICATE----- - -# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 -# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 -# Label: "certSIGN Root CA G2" -# Serial: 313609486401300475190 -# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 -# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 -# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV -BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g -Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ -BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ -R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF -dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw -vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ -uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp -n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs -cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW -xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P -rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF -DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx -DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy -LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C -eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ -d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq -kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl -qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 -OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c -NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk -ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO -pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj -03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk -PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE -1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX -QRBdJ3NghVdJIgc= ------END CERTIFICATE----- - -# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. -# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. -# Label: "NAVER Global Root Certification Authority" -# Serial: 9013692873798656336226253319739695165984492813 -# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b -# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 -# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM -BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG -T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 -aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx -CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD -b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA -iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH -38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE -HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz -kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP -szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq -vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf -nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG -YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo -0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a -CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K -AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I -36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN -qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj -cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm -+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL -hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe -lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 -p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 -piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR -LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX -5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO -dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul -9XXeifdy ------END CERTIFICATE----- - -# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres -# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres -# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" -# Serial: 131542671362353147877283741781055151509 -# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb -# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a -# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb ------BEGIN CERTIFICATE----- -MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw -CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw -FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S -Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 -MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL -DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS -QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH -sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK -Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu -SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC -MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy -v+c= ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa -# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa -# Label: "GlobalSign Root R46" -# Serial: 1552617688466950547958867513931858518042577 -# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef -# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 -# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA -MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD -VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy -MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt -c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ -OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG -vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud -316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo -0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE -y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF -zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE -+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN -I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs -x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa -ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC -4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 -7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg -JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti -2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk -pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF -FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt -rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk -ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 -u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP -4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 -N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 -vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa -# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa -# Label: "GlobalSign Root E46" -# Serial: 1552617690338932563915843282459653771421763 -# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f -# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 -# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 ------BEGIN CERTIFICATE----- -MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx -CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD -ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw -MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex -HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq -R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd -yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ -7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 -+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= ------END CERTIFICATE----- - -# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz -# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz -# Label: "ANF Secure Server Root CA" -# Serial: 996390341000653745 -# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 -# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 -# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 ------BEGIN CERTIFICATE----- -MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV -BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk -YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV -BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN -MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF -UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD -VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v -dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj -cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q -yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH -2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX -H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL -zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR -p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz -W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ -SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn -LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 -n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B -u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj -o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC -AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L -9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej -rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK -pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 -vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq -OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ -/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 -2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI -+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 -MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo -tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= ------END CERTIFICATE----- - -# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Label: "Certum EC-384 CA" -# Serial: 160250656287871593594747141429395092468 -# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 -# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed -# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 ------BEGIN CERTIFICATE----- -MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw -CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw -JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT -EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 -WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT -LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX -BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE -KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm -Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj -QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 -EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J -UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn -nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= ------END CERTIFICATE----- - -# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority -# Label: "Certum Trusted Root CA" -# Serial: 40870380103424195783807378461123655149 -# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 -# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 -# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd ------BEGIN CERTIFICATE----- -MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6 -MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu -MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV -BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw -MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg -U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ -n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q -p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq -NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF -8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3 -HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa -mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi -7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF -ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P -qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ -v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6 -Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 -vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD -ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4 -WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo -zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR -5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ -GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf -5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq -0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D -P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM -qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP -0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf -E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb ------END CERTIFICATE----- - -# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique -# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique -# Label: "TunTrust Root CA" -# Serial: 108534058042236574382096126452369648152337120275 -# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 -# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb -# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL -BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg -Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv -b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG -EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u -IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ -n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd -2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF -VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ -GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF -li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU -r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 -eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb -MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg -jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB -7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW -5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE -ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 -90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z -xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu -QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 -FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH -22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP -xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn -dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 -Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b -nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ -CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH -u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj -d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= ------END CERTIFICATE----- - -# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Label: "HARICA TLS RSA Root CA 2021" -# Serial: 76817823531813593706434026085292783742 -# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 -# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d -# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl -c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg -Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL -MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl -YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv -b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l -mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE -4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv -a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M -pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw -Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b -LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY -AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB -AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq -E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr -W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ -CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF -MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU -X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 -f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja -H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP -JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P -zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt -jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 -/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT -BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 -aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW -xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU -63ZTGI0RmLo= ------END CERTIFICATE----- - -# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA -# Label: "HARICA TLS ECC Root CA 2021" -# Serial: 137515985548005187474074462014555733966 -# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 -# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 -# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 ------BEGIN CERTIFICATE----- -MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw -CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh -cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v -dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG -A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj -aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg -Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 -KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y -STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD -AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw -SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN -nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps ------END CERTIFICATE----- - -# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 -# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" -# Serial: 1977337328857672817 -# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 -# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe -# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 -MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 -thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM -cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG -L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i -NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h -X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b -m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy -Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja -EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T -KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF -6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh -OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc -tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd -IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j -b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC -AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw -ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m -iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF -Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ -hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P -Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE -EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV -1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t -CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR -5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw -f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 -ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK -GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV ------END CERTIFICATE----- - -# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. -# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. -# Label: "vTrus ECC Root CA" -# Serial: 630369271402956006249506845124680065938238527194 -# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 -# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 -# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 ------BEGIN CERTIFICATE----- -MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw -RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY -BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz -MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u -LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF -K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 -v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd -e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD -VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw -V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA -AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG -GJTO ------END CERTIFICATE----- - -# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. -# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. -# Label: "vTrus Root CA" -# Serial: 387574501246983434957692974888460947164905180485 -# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc -# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 -# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 ------BEGIN CERTIFICATE----- -MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL -BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x -FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx -MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s -THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc -IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU -AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ -GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 -8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH -flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt -J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim -0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN -pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ -UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW -OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB -AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E -BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet -8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd -nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j -bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM -Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv -TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS -S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr -I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 -b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB -UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P -Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven -sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= ------END CERTIFICATE----- - -# Issuer: CN=ISRG Root X2 O=Internet Security Research Group -# Subject: CN=ISRG Root X2 O=Internet Security Research Group -# Label: "ISRG Root X2" -# Serial: 87493402998870891108772069816698636114 -# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 -# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af -# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 ------BEGIN CERTIFICATE----- -MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw -CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg -R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 -MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT -ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw -EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW -+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 -ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI -zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW -tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 -/q4AaOeMSQ+2b1tbFfLn ------END CERTIFICATE----- - -# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. -# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. -# Label: "HiPKI Root CA - G1" -# Serial: 60966262342023497858655262305426234976 -# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 -# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 -# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc ------BEGIN CERTIFICATE----- -MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP -MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 -ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa -Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 -YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw -qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv -Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 -lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz -Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ -KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK -FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj -HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr -y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ -/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM -a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 -fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG -SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi -7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc -SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza -ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc -XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg -iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho -L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF -Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr -kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ -vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU -YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== ------END CERTIFICATE----- - -# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 -# Label: "GlobalSign ECC Root CA - R4" -# Serial: 159662223612894884239637590694 -# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc -# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 -# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 ------BEGIN CERTIFICATE----- -MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD -VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh -bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw -MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g -UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT -BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx -uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV -HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ -+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 -bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R1 O=Google Trust Services LLC -# Subject: CN=GTS Root R1 O=Google Trust Services LLC -# Label: "GTS Root R1" -# Serial: 159662320309726417404178440727 -# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 -# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a -# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw -CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU -MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw -MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp -Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo -27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w -Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw -TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl -qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH -szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 -Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk -MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 -wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p -aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN -VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID -AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E -FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb -C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe -QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy -h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 -7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J -ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef -MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ -Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT -6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ -0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm -2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb -bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R3 O=Google Trust Services LLC -# Subject: CN=GTS Root R3 O=Google Trust Services LLC -# Label: "GTS Root R3" -# Serial: 159662495401136852707857743206 -# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 -# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 -# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD -VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG -A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw -WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz -IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G -jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 -4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 -VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm -ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X ------END CERTIFICATE----- - -# Issuer: CN=GTS Root R4 O=Google Trust Services LLC -# Subject: CN=GTS Root R4 O=Google Trust Services LLC -# Label: "GTS Root R4" -# Serial: 159662532700760215368942768210 -# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 -# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 -# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD -VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG -A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw -WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz -IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi -QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR -HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW -BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D -9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 -p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD ------END CERTIFICATE----- - -# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj -# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj -# Label: "Telia Root CA v2" -# Serial: 7288924052977061235122729490515358 -# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 -# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd -# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx -CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE -AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 -NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ -MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq -AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 -vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 -lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD -n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT -7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o -6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC -TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 -WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R -DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI -pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj -YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy -rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw -AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ -8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi -0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM -A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS -SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K -TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF -6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er -3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt -Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT -VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW -ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA -rBPuUBQemMc= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH -# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH -# Label: "D-TRUST BR Root CA 1 2020" -# Serial: 165870826978392376648679885835942448534 -# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed -# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 -# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw -CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS -VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 -NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG -A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB -BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS -zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 -QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ -VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g -PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf -Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l -dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 -c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO -PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW -wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV -dWNbFJWcHwHP2NVypw87 ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH -# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH -# Label: "D-TRUST EV Root CA 1 2020" -# Serial: 126288379621884218666039612629459926992 -# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e -# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 -# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw -CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS -VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 -NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG -A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB -BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC -/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD -wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 -OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g -PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf -Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l -dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 -c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO -PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA -y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb -gfM0agPnIjhQW+0ZT0MW ------END CERTIFICATE----- - -# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. -# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. -# Label: "DigiCert TLS ECC P384 Root G5" -# Serial: 13129116028163249804115411775095713523 -# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed -# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee -# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 ------BEGIN CERTIFICATE----- -MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp -Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 -MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ -bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS -7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp -0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS -B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 -BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ -LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 -DXZDjC5Ty3zfDBeWUA== ------END CERTIFICATE----- - -# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. -# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. -# Label: "DigiCert TLS RSA4096 Root G5" -# Serial: 11930366277458970227240571539258396554 -# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 -# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 -# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN -MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT -HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN -NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs -IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ -ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 -2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp -wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM -pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD -nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po -sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx -Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd -Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX -KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe -XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL -tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv -TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN -AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw -GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H -PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF -O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ -REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik -AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv -/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ -p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw -MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF -qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK -ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ ------END CERTIFICATE----- - -# Issuer: CN=Certainly Root R1 O=Certainly -# Subject: CN=Certainly Root R1 O=Certainly -# Label: "Certainly Root R1" -# Serial: 188833316161142517227353805653483829216 -# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 -# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af -# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw -PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy -dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 -MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 -YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 -1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT -vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed -aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 -1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 -r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 -cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ -wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ -6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA -2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH -Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR -eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB -/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u -d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr -PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d -8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi -1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd -rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di -taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 -lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj -yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn -Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy -yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n -wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 -OV+KmalBWQewLK8= ------END CERTIFICATE----- - -# Issuer: CN=Certainly Root E1 O=Certainly -# Subject: CN=Certainly Root E1 O=Certainly -# Label: "Certainly Root E1" -# Serial: 8168531406727139161245376702891150584 -# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 -# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b -# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 ------BEGIN CERTIFICATE----- -MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw -CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu -bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ -BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s -eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK -+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 -QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 -hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm -ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG -BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR ------END CERTIFICATE----- - -# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. -# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. -# Label: "Security Communication ECC RootCA1" -# Serial: 15446673492073852651 -# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 -# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 -# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 ------BEGIN CERTIFICATE----- -MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT -AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD -VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx -NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT -HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 -IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl -dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK -ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu -9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O -be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= ------END CERTIFICATE----- - -# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY -# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY -# Label: "BJCA Global Root CA1" -# Serial: 113562791157148395269083148143378328608 -# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 -# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a -# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU -MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI -T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz -MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF -SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh -bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z -xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ -spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 -58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR -at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll -5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq -nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK -V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ -pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO -z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn -jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ -WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF -7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE -AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 -YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli -awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u -+2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 -X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN -SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo -P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI -+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz -znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 -eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 -YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy -r/6zcCwupvI= ------END CERTIFICATE----- - -# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY -# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY -# Label: "BJCA Global Root CA2" -# Serial: 58605626836079930195615843123109055211 -# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c -# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 -# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 ------BEGIN CERTIFICATE----- -MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw -CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ -VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy -MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ -TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS -b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B -IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ -+kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK -sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA -94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B -43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== ------END CERTIFICATE----- - -# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited -# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited -# Label: "Sectigo Public Server Authentication Root E46" -# Serial: 88989738453351742415770396670917916916 -# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 -# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a -# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 ------BEGIN CERTIFICATE----- -MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw -CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T -ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN -MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG -A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT -ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC -WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ -6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B -Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa -qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q -4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== ------END CERTIFICATE----- - -# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited -# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited -# Label: "Sectigo Public Server Authentication Root R46" -# Serial: 156256931880233212765902055439220583700 -# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 -# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 -# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 ------BEGIN CERTIFICATE----- -MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf -MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD -Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw -HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY -MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp -YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa -ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz -SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf -iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X -ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 -IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS -VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE -SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu -+Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt -8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L -HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt -zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P -AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c -mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ -YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 -gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA -Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB -JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX -DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui -TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 -dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 -LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp -0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY -QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL ------END CERTIFICATE----- - -# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation -# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation -# Label: "SSL.com TLS RSA Root CA 2022" -# Serial: 148535279242832292258835760425842727825 -# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da -# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca -# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed ------BEGIN CERTIFICATE----- -MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO -MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD -DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX -DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw -b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP -L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY -t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins -S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 -PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO -L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 -R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w -dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS -+YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS -d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG -AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f -gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j -BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z -NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt -hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM -QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf -R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ -DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW -P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy -lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq -bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w -AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q -r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji -Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU -98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= ------END CERTIFICATE----- - -# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation -# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation -# Label: "SSL.com TLS ECC Root CA 2022" -# Serial: 26605119622390491762507526719404364228 -# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 -# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 -# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 ------BEGIN CERTIFICATE----- -MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw -CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT -U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 -MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh -dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm -acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN -SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME -GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW -uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp -15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN -b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== ------END CERTIFICATE----- - -# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos -# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos -# Label: "Atos TrustedRoot Root CA ECC TLS 2021" -# Serial: 81873346711060652204712539181482831616 -# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 -# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd -# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 ------BEGIN CERTIFICATE----- -MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w -LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w -CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 -MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF -Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI -zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X -tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 -AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 -KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD -aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu -CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo -9H1/IISpQuQo ------END CERTIFICATE----- - -# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos -# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos -# Label: "Atos TrustedRoot Root CA RSA TLS 2021" -# Serial: 111436099570196163832749341232207667876 -# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 -# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 -# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f ------BEGIN CERTIFICATE----- -MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM -MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx -MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 -MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD -QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z -4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv -Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ -kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs -GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln -nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh -3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD -0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy -geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 -ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB -c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI -pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU -dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB -DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS -4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs -o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ -qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw -xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM -rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 -AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR -0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY -o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 -dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE -oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. -# Label: "TrustAsia Global Root CA G3" -# Serial: 576386314500428537169965010905813481816650257167 -# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04 -# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7 -# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08 ------BEGIN CERTIFICATE----- -MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM -BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp -ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe -Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw -IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU -cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS -T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK -AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 -nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep -qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA -yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs -hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX -zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv -kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT -f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA -uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB -o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih -MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E -BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 -wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 -XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 -JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j -ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV -VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx -xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on -AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d -7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj -gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV -+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo -FGWsJwt0ivKH ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. -# Label: "TrustAsia Global Root CA G4" -# Serial: 451799571007117016466790293371524403291602933463 -# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb -# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a -# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c ------BEGIN CERTIFICATE----- -MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw -WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs -IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y -MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD -VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz -dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx -s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw -LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij -YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD -pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE -AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR -UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj -/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== ------END CERTIFICATE----- - -# Issuer: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH -# Subject: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH -# Label: "Telekom Security TLS ECC Root 2020" -# Serial: 72082518505882327255703894282316633856 -# MD5 Fingerprint: c1:ab:fe:6a:10:2c:03:8d:bc:1c:22:32:c0:85:a7:fd -# SHA1 Fingerprint: c0:f8:96:c5:a9:3b:01:06:21:07:da:18:42:48:bc:e9:9d:88:d5:ec -# SHA256 Fingerprint: 57:8a:f4:de:d0:85:3f:4e:59:98:db:4a:ea:f9:cb:ea:8d:94:5f:60:b6:20:a3:8d:1a:3c:13:b2:bc:7b:a8:e1 ------BEGIN CERTIFICATE----- -MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw -CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH -bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw -MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx -JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE -AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O -tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP -f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA -MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di -z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn -27iQ7t0l ------END CERTIFICATE----- - -# Issuer: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH -# Subject: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH -# Label: "Telekom Security TLS RSA Root 2023" -# Serial: 44676229530606711399881795178081572759 -# MD5 Fingerprint: bf:5b:eb:54:40:cd:48:71:c4:20:8d:7d:de:0a:42:f2 -# SHA1 Fingerprint: 54:d3:ac:b3:bd:57:56:f6:85:9d:ce:e5:c3:21:e2:d4:ad:83:d0:93 -# SHA256 Fingerprint: ef:c6:5c:ad:bb:59:ad:b6:ef:e8:4d:a2:23:11:b3:56:24:b7:1b:3b:1e:a0:da:8b:66:55:17:4e:c8:97:86:46 ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj -MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0 -eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy -MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC -REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG -A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9 -cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV -cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA -U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6 -Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug -BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy -8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J -co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg -8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8 -rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12 -mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg -+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX -gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 -p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ -pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm -9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw -M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd -GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+ -CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t -xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+ -w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK -L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj -X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q -ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm -dTdmQRCsu/WU48IxK63nI1bMNSWSs1A= ------END CERTIFICATE----- - -# Issuer: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA -# Subject: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA -# Label: "TWCA CYBER Root CA" -# Serial: 85076849864375384482682434040119489222 -# MD5 Fingerprint: 0b:33:a0:97:52:95:d4:a9:fd:bb:db:6e:a3:55:5b:51 -# SHA1 Fingerprint: f6:b1:1c:1a:83:38:e9:7b:db:b3:a8:c8:33:24:e0:2d:9c:7f:26:66 -# SHA256 Fingerprint: 3f:63:bb:28:14:be:17:4e:c8:b6:43:9c:f0:8d:6d:56:f0:b7:c4:05:88:3a:56:48:a3:34:42:4d:6b:3e:c5:58 ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ -MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290 -IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5 -WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO -LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg -Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P -40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF -avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/ -34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i -JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu -j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf -Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP -2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA -S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA -oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC -kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW -5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd -BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB -AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t -tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn -68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn -TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t -RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx -f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI -Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz -8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4 -NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX -xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6 -t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X ------END CERTIFICATE----- - -# Issuer: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. -# Subject: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. -# Label: "SecureSign Root CA14" -# Serial: 575790784512929437950770173562378038616896959179 -# MD5 Fingerprint: 71:0d:72:fa:92:19:65:5e:89:04:ac:16:33:f0:bc:d5 -# SHA1 Fingerprint: dd:50:c0:f7:79:b3:64:2e:74:a2:b8:9d:9f:d3:40:dd:bb:f0:f2:4f -# SHA256 Fingerprint: 4b:00:9c:10:34:49:4f:9a:b5:6b:ba:3b:a1:d6:27:31:fc:4d:20:d8:95:5a:dc:ec:10:a9:25:60:72:61:e3:38 ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM -BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u -LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw -NzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD -eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS -b290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh1oq/ -FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOg -vlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy -6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo -/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9J -kdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ -0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXib -y8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac -18izju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs -0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIAB -SMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVL -ApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk -86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E -rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ib -ed87hwriZLoAymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopT -zfFP7ELyk+OZpDc8h7hi2/DsHzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHS -DCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPGFrojutzdfhrGe0K22VoF3Jpf1d+4 -2kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6qnsb58Nn4DSEC5MUo -FlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/OfVy -K4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6 -dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl -Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB -365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c -JRNItX+S ------END CERTIFICATE----- - -# Issuer: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. -# Subject: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. -# Label: "SecureSign Root CA15" -# Serial: 126083514594751269499665114766174399806381178503 -# MD5 Fingerprint: 13:30:fc:c4:62:a6:a9:de:b5:c1:68:af:b5:d2:31:47 -# SHA1 Fingerprint: cb:ba:83:c8:c1:5a:5d:f1:f9:73:6f:ca:d7:ef:28:13:06:4a:07:7d -# SHA256 Fingerprint: e7:78:f0:f0:95:fe:84:37:29:cd:1a:00:82:17:9e:53:14:a9:c2:91:44:28:05:e1:fb:1d:8f:b6:b8:88:6c:3a ------BEGIN CERTIFICATE----- -MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw -UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM -dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy -NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl -cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290 -IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4 -wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR -ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB -Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT -9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp -4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6 -bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH -# Subject: CN=D-TRUST BR Root CA 2 2023 O=D-Trust GmbH -# Label: "D-TRUST BR Root CA 2 2023" -# Serial: 153168538924886464690566649552453098598 -# MD5 Fingerprint: e1:09:ed:d3:60:d4:56:1b:47:1f:b7:0c:5f:1b:5f:85 -# SHA1 Fingerprint: 2d:b0:70:ee:71:94:af:69:68:17:db:79:ce:58:9f:a0:6b:96:f7:87 -# SHA256 Fingerprint: 05:52:e6:f8:3f:df:65:e8:fa:96:70:e6:66:df:28:a4:e2:13:40:b5:10:cb:e5:25:66:f9:7c:4f:b9:4b:2b:d1 ------BEGIN CERTIFICATE----- -MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI -MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE -LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw -OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi -MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr -i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE -gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8 -k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT -Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl -2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U -cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP -/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS -uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+ -0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N -DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+ -XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61 -GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG -OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y -XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI -FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n -riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR -VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc -LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn -4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD -hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG -koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46 -ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS -Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80 -knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ -hJ65bvspmZDogNOfJA== ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia TLS ECC Root CA O=TrustAsia Technologies, Inc. -# Label: "TrustAsia TLS ECC Root CA" -# Serial: 310892014698942880364840003424242768478804666567 -# MD5 Fingerprint: 09:48:04:77:d2:fc:65:93:71:66:b1:11:95:4f:06:8c -# SHA1 Fingerprint: b5:ec:39:f3:a1:66:37:ae:c3:05:94:57:e2:be:11:be:b7:a1:7f:36 -# SHA256 Fingerprint: c0:07:6b:9e:f0:53:1f:b1:a6:56:d6:7c:4e:be:97:cd:5d:ba:a4:1e:f4:45:98:ac:c2:48:98:78:c9:2d:87:11 ------BEGIN CERTIFICATE----- -MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMw -WDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs -IEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQw -NTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBYMQswCQYDVQQGEwJDTjElMCMGA1UE -ChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1c3RB -c2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/pVs/ -AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDp -guMqWzJ8S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAw -DgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01 -L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15KeAIxAKORh/IRM4PDwYqR -OkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ== ------END CERTIFICATE----- - -# Issuer: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. -# Subject: CN=TrustAsia TLS RSA Root CA O=TrustAsia Technologies, Inc. -# Label: "TrustAsia TLS RSA Root CA" -# Serial: 160405846464868906657516898462547310235378010780 -# MD5 Fingerprint: 3b:9e:c3:86:0f:34:3c:6b:c5:46:c4:8e:1d:e7:19:12 -# SHA1 Fingerprint: a5:46:50:c5:62:ea:95:9a:1a:a7:04:6f:17:58:c7:29:53:3d:03:fa -# SHA256 Fingerprint: 06:c0:8d:7d:af:d8:76:97:1e:b1:12:4f:e6:7f:84:7e:c0:c7:a1:58:d3:ea:53:cb:e9:40:e2:ea:97:91:f4:c3 ------BEGIN CERTIFICATE----- -MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEM -BQAwWDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp -ZXMsIEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcN -MjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2WjBYMQswCQYDVQQGEwJDTjElMCMG -A1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1 -c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC -AgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+ -NmDQDIPNlOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJ -Q1DNDX3eRA5gEk9bNb2/mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561 -HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fkzv93uMltrOXVmPGZLmzjyUT5tUMnCE32 -ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYozza/+lcK7Fs/6TAWe8Tb -xNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyrz2I8sMeX -i9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQ -UNoyIBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+j -TnhMmCWr8n4uIF6CFabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DT -bE3txci3OE9kxJRMT6DNrqXGJyV1J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8 -S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnTq1mt1tve1CuBAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZylomkadFK/hT -MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3 -Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4 -iqME3mmL5Dw8veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt -7DlK9RME7I10nYEKqG/odv6LTytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp -2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHxtlotJnMnlvm5P1vQiJ3koP26TpUJ -g3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp27RIGAAtvKLEiUUj -pQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87qqA8M -pugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongP -XvPKnbwbPKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIwe -SsCI3zWQzj8C9GRh3sfIB5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0 -ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNzFrwFuHnYWa8G5z9nODmxfKuU4CkUpijy -323imttUQ/hHWKNddBWcwauwxzQ= ------END CERTIFICATE----- - -# Issuer: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH -# Subject: CN=D-TRUST EV Root CA 2 2023 O=D-Trust GmbH -# Label: "D-TRUST EV Root CA 2 2023" -# Serial: 139766439402180512324132425437959641711 -# MD5 Fingerprint: 96:b4:78:09:f0:09:cb:77:eb:bb:1b:4d:6f:36:bc:b6 -# SHA1 Fingerprint: a5:5b:d8:47:6c:8f:19:f7:4c:f4:6d:6b:b6:c2:79:82:22:df:54:8b -# SHA256 Fingerprint: 8e:82:21:b2:e7:d4:00:78:36:a1:67:2f:0d:cc:29:9c:33:bc:07:d3:16:f1:32:fa:1a:20:6d:58:71:50:f1:ce ------BEGIN CERTIFICATE----- -MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI -MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE -LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw -OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi -MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN -AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK -F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE -7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe -EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6 -lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb -RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV -jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc -jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx -TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ -ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk -hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF -NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH -kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG -OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y -XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14 -QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4 -pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q -3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU -t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX -cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8 -ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT -2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs -7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP -gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst -Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh -XBxvWHZks/wCuPWdCg== ------END CERTIFICATE----- - -# Issuer: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG -# Subject: CN=SwissSign RSA TLS Root CA 2022 - 1 O=SwissSign AG -# Label: "SwissSign RSA TLS Root CA 2022 - 1" -# Serial: 388078645722908516278762308316089881486363258315 -# MD5 Fingerprint: 16:2e:e4:19:76:81:85:ba:8e:91:58:f1:15:ef:72:39 -# SHA1 Fingerprint: 81:34:0a:be:4c:cd:ce:cc:e7:7d:cc:8a:d4:57:e2:45:a0:77:5d:ce -# SHA256 Fingerprint: 19:31:44:f4:31:e0:fd:db:74:07:17:d4:de:92:6a:57:11:33:88:4b:43:60:d3:0e:27:29:13:cb:e6:60:ce:41 ------BEGIN CERTIFICATE----- -MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL -BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE -AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx -MTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxT -d2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0EgVExTIFJvb3QgQ0Eg -MjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmjiC8NX -vDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7 -LCTLf5ImgKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX -5XH8irCRIFucdFJtrhUnWXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyE -EPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlfGUEGjw5NBuBwQCMBauTLE5tzrE0USJIt -/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36qOTw7D59Ke4LKa2/KIj4x -0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLOEGrOyvi5 -KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM -0ZPlEuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shd -OxtYk8EXlFXIC+OCeYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrta -clXvyFu1cvh43zcgTFeRc5JzrBh3Q4IgaezprClG5QtO+DdziZaKHG29777YtvTK -wP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow4UD2p8P98Q+4 -DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL -BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO3 -10aewCoSPY6WlkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgz -Hqp41eZUBDqyggmNzhYzWUUo8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQ -iJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zpy1FVCypM9fJkT6lc/2cyjlUtMoIc -gC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3CjlvrzG4ngRhZi0Rjn9UM -ZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6MOuhF -LhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJp -zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td -Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0 -rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO -gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ ------END CERTIFICATE----- - -# Issuer: CN=OISTE Server Root ECC G1 O=OISTE Foundation -# Subject: CN=OISTE Server Root ECC G1 O=OISTE Foundation -# Label: "OISTE Server Root ECC G1" -# Serial: 47819833811561661340092227008453318557 -# MD5 Fingerprint: 42:a7:d2:35:ae:02:92:db:19:76:08:de:2f:05:b4:d4 -# SHA1 Fingerprint: 3b:f6:8b:09:ae:2a:92:7b:ba:e3:8d:3f:11:95:d9:e6:44:0c:45:e2 -# SHA256 Fingerprint: ee:c9:97:c0:c3:0f:21:6f:7e:3b:8b:30:7d:2b:ae:42:41:2d:75:3f:c8:21:9d:af:d1:52:0b:25:72:85:0f:49 ------BEGIN CERTIFICATE----- -MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQsw -CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY -T0lTVEUgU2VydmVyIFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUy -NDE0NDIyN1owSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRp -b24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IEVDQyBHMTB2MBAGByqGSM49 -AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPoH7d5qVi2+GXROiFPqOujvqQy -cvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4LrQ95SjeHIC6XG4N -2xml4z+cKrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQ3 -TYhlz/w9itWj8UnATgwQb0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9C -tJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCpKjAd0MKfkFFR -QD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxgZzFDJe0CMQCSia7pXGKD -YmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c= ------END CERTIFICATE----- - -# Issuer: CN=OISTE Server Root RSA G1 O=OISTE Foundation -# Subject: CN=OISTE Server Root RSA G1 O=OISTE Foundation -# Label: "OISTE Server Root RSA G1" -# Serial: 113845518112613905024960613408179309848 -# MD5 Fingerprint: 23:a7:9e:d4:70:b8:b9:14:57:41:8a:7e:44:59:e2:68 -# SHA1 Fingerprint: f7:00:34:25:94:88:68:31:e4:34:87:3f:70:fe:86:b3:86:9f:f0:6e -# SHA256 Fingerprint: 9a:e3:62:32:a5:18:9f:fd:db:35:3d:fd:26:52:0c:01:53:95:d2:27:77:da:c5:9d:b5:7b:98:c0:89:a6:51:e6 ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBL -MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE -AwwYT0lTVEUgU2VydmVyIFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4 -MDUyNDE0MzcxNVowSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5k -YXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IFJTQSBHMTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuCz/vlNwvn1ZatkOhLKdxVYOPM -vLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnwYx4M0rH/1ow00O7b -rEi56rAUjtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8JnduodgsIUzk -ik/HEzxux9UTl7Ko2yRpg1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4z -O8vbUZeUapU8zhhabkvG/AePLhq5SvdkNCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8R -tOpXaZ+0AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY+m0o/DjH40ytas7ZTpOS -jswMZ78LS5bOZmdTaMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+lKXHiHUh -sd4JJCpM4rzsTGdHwimIuQq6+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+Ho -mnqT8eDI278n5mUpezbgMxVz8p1rhAhoKzYHKyfMeNhqhw5HdPSqoBNdZH702xSu -+zrkL8Fl47l6QGzwBrd7KJvX4V84c5Ss2XCTLdyEr0YconosP4EmQufU2MVshGYR -i3drVByjtdgQ8K4p92cIiBdcuJd5z+orKu5YM+Vt6SmqZQENghPsJQtdLEByFSnT -kCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU -8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC77EUOSh+1sbM2 -zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33 -I3K5Ce+SrScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG -5D1rd9QhEOP28yBOqb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8 -qyiWXmFcuCIzGEgWUOrKL+mlSdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dP -AGav9LEDOr4SfEE15fSmG0eLy3n31r8Xbk5l8PjaV8GUgeV6Vg27Rn9vkf195hfk -gSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2abtNUOshD+FKrDgHGdPY3ofRRs -YWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNqqYY1 -9tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7ph6N/Ome -/msVuduCmsuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3 -J8tRd/iWkx7P8nd9H0aTolkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2 -wq1yVAb+axj5d9spLFKebXd7Yv0PTY6YMjAwcRLWJTXjn/hvnLXrahut6hDTlhZy -BiElxky8j3C7DOReIoMt0r7+hVu05L0= ------END CERTIFICATE----- - -# Issuer: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. -# Subject: CN=e-Szigno TLS Root CA 2023 O=Microsec Ltd. -# Label: "e-Szigno TLS Root CA 2023" -# Serial: 71934828665710877219916191754 -# MD5 Fingerprint: 6a:e9:99:74:a5:da:5e:f1:d9:2e:f2:c8:d1:86:8b:71 -# SHA1 Fingerprint: 6f:9a:d5:d5:df:e8:2c:eb:be:37:07:ee:4f:4f:52:58:29:41:d1:fe -# SHA256 Fingerprint: b4:91:41:50:2d:00:66:3d:74:0f:2e:7e:c3:40:c5:28:00:96:26:66:12:1a:36:d0:9c:f7:dd:2b:90:38:4f:b4 ------BEGIN CERTIFICATE----- -MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYD -VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 -ZC4xFzAVBgNVBGEMDlZBVEhVLTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBU -TFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0MDAwMFoXDTM4MDcxNzE0MDAwMFow -dTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYwFAYDVQQKDA1NaWNy -b3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZZS1T -emlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAE -AGgP36J8PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFS -AL/fjO1ZrTJlqwlZULUZwmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/v -SzUaQ49CE0y5LBqcvjC2xN7cS53kpDzLLtmt3999Cd8ukv+ho2MwYTAPBgNVHRMB -Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUWYQCYlpGePVd3I8K -ECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0UwCgYIKoZI -zj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpt -y7Ve7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZl -C9p2x1L/Cx6AcCIwwzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6 -uWWL ------END CERTIFICATE----- - -# Issuer: CN=SECOM TLS RSA Root CA 2024 O=SECOM Trust Systems Co., Ltd. -# Subject: CN=SECOM TLS RSA Root CA 2024 O=SECOM Trust Systems Co., Ltd. -# Label: "SECOM TLS RSA Root CA 2024" -# Serial: 17188327524208271538 -# MD5 Fingerprint: d0:a4:db:32:eb:44:98:d2:62:0b:3e:bc:4d:7c:5c:e9 -# SHA1 Fingerprint: fb:97:96:7c:ef:8d:98:63:06:c0:3b:b6:11:f8:e0:13:97:a2:98:d3 -# SHA256 Fingerprint: 14:35:f2:25:c5:d2:52:d7:a2:19:48:cc:3c:e6:2a:ec:fa:88:00:1e:3d:d7:2d:1c:c3:55:51:00:eb:37:2f:93 ------BEGIN CERTIFICATE----- -MIIFmjCCA4KgAwIBAgIJAO6JNNDLgOCyMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNV -BAYTAkpQMSYwJAYDVQQKEx1TRUNPTSBUcnVzdCBTeXN0ZW1zIENvLiwgTHRkLjEj -MCEGA1UEAxMaU0VDT00gVExTIFJTQSBSb290IENBIDIwMjQwHhcNMjQwMTMxMDUx -MTU1WhcNNDkwMTE0MDUxMTU1WjBaMQswCQYDVQQGEwJKUDEmMCQGA1UEChMdU0VD -T00gVHJ1c3QgU3lzdGVtcyBDby4sIEx0ZC4xIzAhBgNVBAMTGlNFQ09NIFRMUyBS -U0EgUm9vdCBDQSAyMDI0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA -4TjizUwzxbInq8Tx11gaFYNk5fO+34y7TyM4neh0UgL5JIZbJNLTz2x//L/B71+5 -m6X6nGIr7d4lFJBGtjO677hXOz93zkcWaUTm3VbOAjBlt4YWxlcccBHXuZ7o3Q+4 -R+ormrBdHeJ1CTUEG8ttQbKIl3G7OZYbnH8/pP8cjPub/0kDVNuMzp7xsVRROOis -Qt53fMoJLlYgoebbuMphOqMCtjkJ7R6efEMfLp8UAVi9ZaLRn76ET/CJkk925ndu -uufC4BatS4mnXFmxN0vUXb0ij9B8O/D8gixQEsVSD4GK8FWRPh3bVd/6bzdkHGJj -y21XI0yejVomZUbRrOfNuz0boPGV1pt18fFC39IHQEth3OFqb5NDO3L+A9bNqTgA -yUgRmIn4ucgDc/Ri/Km3V51ueZjy1/yk0qwJVadAVVrCt56iNeXOyEvzJADGgDQ8 -E1Pdaqct8Cynz/47ReQM62vFYO08wcQkrjmX/tesiko1V1yyaf6EfPzUFzmaGy9x -vkCwdbm15EdTolOjE0H2Vb5/APDOyCFEokiYGmXTLdAUl0wKZ4IyjkHGzy0jhpaX -EXE/GJcEvI6VzEchjaBL03EJ0h9pG4OqeIOycKvAo3A+TbetyfsrgYyHzU0a7/qU -jGat1AAq1nVljMpKqpinPTsf/d9H39FTUeJL7TpzzjUCAwEAAaNjMGEwHQYDVR0O -BBYEFCzrchKOWHdkNRVWNQFXB6l9DTbmMB8GA1UdIwQYMBaAFCzrchKOWHdkNRVW -NQFXB6l9DTbmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG -SIb3DQEBDAUAA4ICAQAVwsvluSafaez5tFPR/hRTBzRxEyMMQF3XJXCVi3yegZyK -oec7hmE6jx2ZM8KgM1kn2yJRwFXHX8zUW9nBLEDWc4wuE8LrlZqhGZM9pJQXGmGz -ResDJV6JgRBna+j4sA1M7yIdlvL0sAfFXFCTRaWTD4E1V99RLrFzWfTcC+e180hD -uNMpqOEo46+lMeW/Wvh7ifOQs+kiK0O2gHxQDNxslSavnCs4V7l8HRDJ2La10o70 -Bo7VLzf1W8MBvv0VTnxB+NjT5qTAbhGFh9Gvp4BaJpmdUf0C5CEP6dbQlfgxWfzY -r69yVT6dPQB+GFEaY03IMY+AcBCs+om1fNxrQXt9zoofMBNFbLhvpNH/JsXWdGUz -fNbO12uswTa5wah8LB18FTQN2/zPHYmvBEoLuyUgZ09VNLJo5YA0kXItVYkLjMe2 -SixzK4scUHv81IK99I91DWx7FwMVKw2xgFp+ZLYB2dnpQQrqwlW64glHUcK2N9BD -snjLSxeZ+UPECh9RxH4WAcKiZW+cqaKMmhP2WBfR4IcR7NOL32ml11ds87hhV1CZ -WWFCJAcCidYZz6CZa8exzHojP9SB5RH0/v1KdHAisqhSjtJl/UIAHIQ48elOn8wr -TdFap4Yb5aHglmMeNx+fAIhDluWVfxTO7H4dTPU+SFVRMLAh+wwKZfqb94nMeQ== ------END CERTIFICATE----- - -# Issuer: CN=SECOM TLS ECC Root CA 2024 O=SECOM Trust Systems Co., Ltd. -# Subject: CN=SECOM TLS ECC Root CA 2024 O=SECOM Trust Systems Co., Ltd. -# Label: "SECOM TLS ECC Root CA 2024" -# Serial: 9329818985461676612 -# MD5 Fingerprint: 99:d3:9d:e4:d2:b1:2d:f0:2a:04:67:85:f3:df:46:d6 -# SHA1 Fingerprint: 7a:1f:22:2d:72:b2:c3:19:87:44:db:61:69:e8:a6:4b:d7:0d:44:0e -# SHA256 Fingerprint: 6a:b2:ab:75:f5:1c:b4:f4:f0:15:62:03:fb:f6:f6:46:23:2f:51:4b:e0:59:f6:28:33:30:8b:82:b4:d7:2d:b1 ------BEGIN CERTIFICATE----- -MIICTDCCAdGgAwIBAgIJAIF6LO+PI3pEMAoGCCqGSM49BAMDMFoxCzAJBgNVBAYT -AkpQMSYwJAYDVQQKEx1TRUNPTSBUcnVzdCBTeXN0ZW1zIENvLiwgTHRkLjEjMCEG -A1UEAxMaU0VDT00gVExTIEVDQyBSb290IENBIDIwMjQwHhcNMjQwMTMxMDU1MjM0 -WhcNNDkwMTE0MDU1MjM0WjBaMQswCQYDVQQGEwJKUDEmMCQGA1UEChMdU0VDT00g -VHJ1c3QgU3lzdGVtcyBDby4sIEx0ZC4xIzAhBgNVBAMTGlNFQ09NIFRMUyBFQ0Mg -Um9vdCBDQSAyMDI0MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7NzFMtu9dzQXSNC1 -2fabk0+GlC5finB3R7XaZonRUd20aFiWObtuNBCLUZSfk6QXAE55BjEXsXQ/NG8y -UqicXjsu9ksDK3JZBgCwLOVh6+nwJXTvso/dEj/GUYH5mBdoo2MwYTAdBgNVHQ4E -FgQUO3YReyl04k4GTFaCQNAhL3qzydUwHwYDVR0jBBgwFoAUO3YReyl04k4GTFaC -QNAhL3qzydUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZI -zj0EAwMDaQAwZgIxAN3ib8fi1pMYtAPjMilB5e5/H+t5CL0xPL+cZ5oTTZuSCjpA -n1v7F/VAr8bFxQXAowIxAKsBVO1ACFp7skwzPvdv1EUY5a897WGLT4lb+bjxFAWy -l8wDcZJdwGZ/pAHxt1AJ1g== ------END CERTIFICATE----- - -# Issuer: CN=Telia EC TLS Root CA v3 O=Telia Company AB -# Subject: CN=Telia EC TLS Root CA v3 O=Telia Company AB -# Label: "Telia EC TLS Root CA v3" -# Serial: 8028200332079443110287896228123317 -# MD5 Fingerprint: b6:fa:6a:5c:42:fb:c5:67:72:c0:e0:2f:72:fb:5a:44 -# SHA1 Fingerprint: b4:d6:07:c2:a5:95:bc:5b:f4:67:4d:c9:dc:6f:6f:0a:00:7a:a5:35 -# SHA256 Fingerprint: 09:8e:08:a9:1d:bb:f7:74:78:b9:6c:ce:b8:9b:14:13:a5:da:37:b7:c8:62:60:6a:95:5d:eb:07:17:9f:43:26 ------BEGIN CERTIFICATE----- -MIICMjCCAbegAwIBAgIPAYvSIlRjTQSLbOVHH9K1MAoGCCqGSM49BAMDMEoxCzAJ -BgNVBAYTAlNFMRkwFwYDVQQKDBBUZWxpYSBDb21wYW55IEFCMSAwHgYDVQQDDBdU -ZWxpYSBFQyBUTFMgUm9vdCBDQSB2MzAeFw0yMzExMTUwODU1MjZaFw00ODA1MjMx -MTAwMDBaMEoxCzAJBgNVBAYTAlNFMRkwFwYDVQQKDBBUZWxpYSBDb21wYW55IEFC -MSAwHgYDVQQDDBdUZWxpYSBFQyBUTFMgUm9vdCBDQSB2MzB2MBAGByqGSM49AgEG -BSuBBAAiA2IABMHIlhVDLbmFKUpW0iK4dpryT6emYOeS31JPwWnWPmkWRrAkTbPX -40sQfHI9mpR7Rbktu3ngg6W+BBSXSechtMCnBmWXj/EaVlmV5cY1jD2HoTfhBQ3A -acpCNMLJK4NpZaNjMGEwHwYDVR0jBBgwFoAU1GToQ4g6cy/QGnGCNgtehd7H3kMw -HQYDVR0OBBYEFNRk6EOIOnMv0BpxgjYLXoXex95DMA4GA1UdDwEB/wQEAwIBBjAP -BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2kAMGYCMQCXAUdS/9bbJ8A1JYaG -f/bWt/s7Ta0ot5Ulno8OjSNYRWQIlS4tVWldvTAVA7heOFgCMQCvKr8+Z2Rn+OBr -5UHzlgBObpad1LuwNTRcdNgUJxIWadcki+UBLEi1/AURKV5md2M= ------END CERTIFICATE----- - -# Issuer: CN=Telia RSA TLS Root CA v3 O=Telia Company AB -# Subject: CN=Telia RSA TLS Root CA v3 O=Telia Company AB -# Label: "Telia RSA TLS Root CA v3" -# Serial: 8028214673410753541795188766939845 -# MD5 Fingerprint: f4:8b:9c:f3:f8:63:cf:dc:25:8f:b4:bb:a2:e9:9d:e2 -# SHA1 Fingerprint: b5:2e:88:4e:40:c1:11:fb:50:c7:e2:4f:ac:18:2b:bd:68:15:d2:34 -# SHA256 Fingerprint: d1:3d:b1:29:4c:45:eb:c6:fc:86:c6:bb:f6:9f:a2:9b:df:e6:92:df:f7:c7:13:c2:43:c7:a9:56:c6:a2:28:4c ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgIPAYvSUKtCVSxHWr2h3BrFMA0GCSqGSIb3DQEBDAUAMEsx -CzAJBgNVBAYTAlNFMRkwFwYDVQQKDBBUZWxpYSBDb21wYW55IEFCMSEwHwYDVQQD -DBhUZWxpYSBSU0EgVExTIFJvb3QgQ0EgdjMwHhcNMjMxMTE1MDk0NzQyWhcNNDgw -NTIzMTEwMDAwWjBLMQswCQYDVQQGEwJTRTEZMBcGA1UECgwQVGVsaWEgQ29tcGFu -eSBBQjEhMB8GA1UEAwwYVGVsaWEgUlNBIFRMUyBSb290IENBIHYzMIICIjANBgkq -hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsV89KG19hCf4S1Fvk8D3TyDERhmcvx8F -7Kmb4WATx3ije1id3KHxRE0TKmcNCbAQ57bvHFEYa4hR2l20VjVadExqOW+2ld99 -MbEiO+jRVOz+BbxLxJnmGwCqI+BfuTjjVReDxsxjQvjgBsClaO/sm5i70nlZcWGR -tIkvWDK3NNkT5RtwXc/O8NTFVpbUqT6cRjIj3olAblR+lRf4Ffy5o+Q9fabjYn9Z -9S4itruElcEFf9Ljk7fwdTycT/rvJW9w/B3G2a3r0f/zXNOVruIBcqE6pkSospAC -U2bG42fYKrbM/GWnp7u+p9Frz4jaNwpb4YHuEeS8BratNcP8X62jXIvvKHxlsMDJ -Cnb4U8JzFOLsU6mohVY58BdZrvi0Gk9UOuqmgoG6dskHoksjZTlK61D/InzmEoA1 -yAYJFDVysjRxDUOu9cAwANbqmq77WIFL6BpnZgVqPtMfG6wN8BrTKdapvilVsYR5 -9BFgIsAVBMxrGh+W+QcvmJafUpASvlArKvVG2FI4i6PiLjSBT0+6F6EQLrYqefOQ -F/fBNEXb+njUQ0SUVrAqtH4Y+OjCI/a4/JJQppxeemZcQ0SUShgiI5AM5xHO5iya -UrTjYH4zxUz9j+1FEbDH/xpstr1gXBykspup+hRTaJcbA+UbpJqtWZndAPddJmt6 -YJQ+dU3pDu8CAwEAAaNjMGEwHwYDVR0jBBgwFoAUsMep0t2yKFZzBJSMFFxIbzdS -kqgwHQYDVR0OBBYEFLDHqdLdsihWcwSUjBRcSG83UpKoMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQBdYzFsNGDRk7bR -/AgRKq+5637YuOW+w6uhpoS0VnKMUpyHCwku86hEvqivakPtfmlm4bFwt++sb/8O -XsWBqtfbXMaBNDTZl8XRMJuLWOW2JrbKkRzgG0eBUcvsadG1rrhbmZqYvFXaAZO7 -o4TdOZzxhBB5GOAWWXB3IeraNP4J63zyo9n8Gqw3sJBG44em5hoYjBffP+npibys -lnslRi4L6xHsCYj/Pab+OlqbMCB6v+sTCLeEIukRVzoR9aQ45pEK7Z1QBnSsbAKQ -tss0JKD9d/mX143H1xePjPhTXlv5JCkhrcj+SShz0P9+EHoWe6m9lyUEOIVn0rp+ -yVJWNbmyDv3VkwFxHC1ApSQsgSimjGQ4wtr6cSmordYxkV+Ro8lOIIhRksXPyDk2 -7gW6IjUXCkZKpxFjkL3jiBSc8SkxnwCWtXg8xwNwdFVNBGLCCuJnsneYXjJNqzRq -UcoGwzsvF3Qi/ZnHUNvISdevlgIAXL4Wvrxaqvoa01wB+GCfs57RTGE4TvAGhKNK -us8K3hRT1BSpigzMIRzSxtAOrqPN6j//QSmW9f8Jcncri4j2ihSpVrFU0NdNkMhZ -eAKidTFPsxCVFuW4Aniz7jqiw5sWtjbQrlW035izIEU4sYwQoC1Nx0Svy+mMTRai -50LqFQ+A1/Hq6xHHDNx7CI83d23Erw== ------END CERTIFICATE----- diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py deleted file mode 100644 index 79132e4501c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/certifi/core.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -certifi.py -~~~~~~~~~~ - -This module returns the installation location of cacert.pem or its contents. -""" -import sys -import atexit - -def exit_cacert_ctx() -> None: - _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr] - - -if sys.version_info >= (3, 11): - - from importlib.resources import as_file, files - - _CACERT_CTX = None - _CACERT_PATH = None - - def where() -> str: - # This is slightly terrible, but we want to delay extracting the file - # in cases where we're inside of a zipimport situation until someone - # actually calls where(), but we don't want to re-extract the file - # on every call of where(), so we'll do it once then store it in a - # global variable. - global _CACERT_CTX - global _CACERT_PATH - if _CACERT_PATH is None: - # This is slightly janky, the importlib.resources API wants you to - # manage the cleanup of this file, so it doesn't actually return a - # path, it returns a context manager that will give you the path - # when you enter it and will do any cleanup when you leave it. In - # the common case of not needing a temporary file, it will just - # return the file system location and the __exit__() is a no-op. - # - # We also have to hold onto the actual context manager, because - # it will do the cleanup whenever it gets garbage collected, so - # we will also store that at the global level as well. - _CACERT_CTX = as_file(files(__package__).joinpath("cacert.pem")) - _CACERT_PATH = str(_CACERT_CTX.__enter__()) - atexit.register(exit_cacert_ctx) - - return _CACERT_PATH - - def contents() -> str: - return files(__package__).joinpath("cacert.pem").read_text(encoding="ascii") - -else: - - from importlib.resources import path as get_path, read_text - - _CACERT_CTX = None - _CACERT_PATH = None - - def where() -> str: - # This is slightly terrible, but we want to delay extracting the - # file in cases where we're inside of a zipimport situation until - # someone actually calls where(), but we don't want to re-extract - # the file on every call of where(), so we'll do it once then store - # it in a global variable. - global _CACERT_CTX - global _CACERT_PATH - if _CACERT_PATH is None: - # This is slightly janky, the importlib.resources API wants you - # to manage the cleanup of this file, so it doesn't actually - # return a path, it returns a context manager that will give - # you the path when you enter it and will do any cleanup when - # you leave it. In the common case of not needing a temporary - # file, it will just return the file system location and the - # __exit__() is a no-op. - # - # We also have to hold onto the actual context manager, because - # it will do the cleanup whenever it gets garbage collected, so - # we will also store that at the global level as well. - _CACERT_CTX = get_path(__package__, "cacert.pem") - _CACERT_PATH = str(_CACERT_CTX.__enter__()) - atexit.register(exit_cacert_ctx) - - return _CACERT_PATH - - def contents() -> str: - return read_text(__package__, "cacert.pem", encoding="ascii") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE deleted file mode 100644 index 9725772c796..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset-normalizer.LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 TAHRI Ahmed R. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py deleted file mode 100644 index 73dcff44460..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/__init__.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -Charset-Normalizer -~~~~~~~~~~~~~~ -The Real First Universal Charset Detector. -A library that helps you read text from an unknown charset encoding. -Motivated by chardet, This package is trying to resolve the issue by taking a new approach. -All IANA character set names for which the Python core library provides codecs are supported. - -Basic usage: - >>> from charset_normalizer import from_bytes - >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8')) - >>> best_guess = results.best() - >>> str(best_guess) - 'Bсеки човек има право на образование. Oбразованието!' - -Others methods and usages are available - see the full documentation -at . -:copyright: (c) Ahmed TAHRI -:license: MIT, see LICENSE for more details. -""" - -from __future__ import annotations - -import logging - -from .api import from_bytes, from_fp, from_path, is_binary -from .legacy import detect -from .models import CharsetMatch, CharsetMatches -from .utils import set_logging_handler -from .version import VERSION, __version__ - -__all__ = ( - "from_fp", - "from_path", - "from_bytes", - "is_binary", - "detect", - "CharsetMatch", - "CharsetMatches", - "__version__", - "VERSION", - "set_logging_handler", -) - -# Attach a NullHandler to the top level logger by default -# https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library - -logging.getLogger("opentelemetry.agent._vendor.charset_normalizer").addHandler(logging.NullHandler()) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py deleted file mode 100644 index 40366a5807c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/api.py +++ /dev/null @@ -1,934 +0,0 @@ -from __future__ import annotations - -import logging -from functools import lru_cache -from os import PathLike -from typing import BinaryIO - -from .cd import ( - coherence_ratio, - encoding_languages, - mb_encoding_languages, - merge_coherence_ratios, -) -from .constant import ( - IANA_SUPPORTED, - IANA_SUPPORTED_SIMILAR, - TOO_BIG_SEQUENCE, - TOO_SMALL_SEQUENCE, - TRACE, -) -from .md import mess_ratio -from .models import CharsetMatch, CharsetMatches -from .utils import ( - any_specified_encoding, - cut_sequence_chunks, - iana_name, - identify_sig_or_bom, - is_multi_byte_encoding, - should_strip_sig_or_bom, -) - -logger = logging.getLogger("opentelemetry.agent._vendor.charset_normalizer") -explain_handler = logging.StreamHandler() -explain_handler.setFormatter( - logging.Formatter("%(asctime)s | %(levelname)s | %(message)s") -) - -# Pre-compute a reordered encoding list: multibyte first, then single-byte. -# This allows the mb_definitive_match optimization to fire earlier, skipping -# all single-byte encodings for genuine CJK content. Multibyte codecs -# hard-fail (UnicodeDecodeError) on single-byte data almost instantly, so -# testing them first costs negligible time for non-CJK files. -# Stable sort on a boolean key: multibyte (False) first, IANA order kept -# within each group. -IANA_SUPPORTED_MB_FIRST: list[str] = sorted( - IANA_SUPPORTED, key=lambda encoding: not is_multi_byte_encoding(encoding) -) - - -def from_bytes( - sequences: bytes | bytearray, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.2, - cp_isolation: list[str] | None = None, - cp_exclusion: list[str] | None = None, - preemptive_behaviour: bool = True, - explain: bool = False, - language_threshold: float = 0.1, - enable_fallback: bool = True, -) -> CharsetMatches: - """ - Given a raw bytes sequence, return the best possibles charset usable to render str objects. - If there is no results, it is a strong indicator that the source is binary/not text. - By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence. - And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. - - The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page - but never take it for granted. Can improve the performance. - - You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that - purpose. - - This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. - By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' - toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. - Custom logging format and handler can be set manually. - """ - - if not isinstance(sequences, (bytearray, bytes)): - raise TypeError( - "Expected object of type bytes or bytearray, got: {}".format( - type(sequences) - ) - ) - - if explain: - previous_logger_level: int = logger.level - logger.addHandler(explain_handler) - logger.setLevel(TRACE) - - length: int = len(sequences) - - if length == 0: - logger.debug("Encoding detection on empty bytes, assuming utf_8 intention.") - if explain: # Defensive: ensure exit path clean handler - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")]) - - if cp_isolation is not None: - logger.log( - TRACE, - "cp_isolation is set. use this flag for debugging purpose. " - "limited list of encoding allowed : %s.", - ", ".join(cp_isolation), - ) - cp_isolation = [iana_name(cp, False) for cp in cp_isolation] - else: - cp_isolation = [] - - if cp_exclusion is not None: - logger.log( - TRACE, - "cp_exclusion is set. use this flag for debugging purpose. " - "limited list of encoding excluded : %s.", - ", ".join(cp_exclusion), - ) - cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion] - else: - cp_exclusion = [] - - if length <= (chunk_size * steps): - logger.log( - TRACE, - "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.", - steps, - chunk_size, - length, - ) - steps = 1 - chunk_size = length - - if steps > 1 and length / steps < chunk_size: - chunk_size = int(length / steps) - - is_too_small_sequence: bool = len(sequences) < TOO_SMALL_SEQUENCE - is_too_large_sequence: bool = len(sequences) >= TOO_BIG_SEQUENCE - - if is_too_small_sequence: - logger.log( - TRACE, - "Trying to detect encoding from a tiny portion of (%i) byte(s).", - length, - ) - elif is_too_large_sequence: - logger.log( - TRACE, - "Using lazy str decoding because the payload is quite large, (%i) byte(s).", - length, - ) - - prioritized_encodings: list[str] = [] - - specified_encoding: str | None = ( - any_specified_encoding(sequences) if preemptive_behaviour else None - ) - - if specified_encoding is not None: - prioritized_encodings.append(specified_encoding) - logger.log( - TRACE, - "Detected declarative mark in sequence. Priority +1 given for %s.", - specified_encoding, - ) - - tested: set[str] = set() - tested_but_hard_failure: list[str] = [] - tested_but_soft_failure: list[str] = [] - soft_failure_skip: set[str] = set() - - # Avoid unoptimized RSS usage. - # this cache is mostly interesting for - # local usage. Garbage collected at the - # end. Like it should. - cached_mess_ratio = lru_cache(maxsize=None)(mess_ratio) - cached_coherence_ratio = lru_cache(maxsize=None)(coherence_ratio) - - # When a definitive result (chaos=0.0 and good coherence) is found after testing - # the prioritized encodings (ascii, utf_8), we can significantly reduce the remaining - # work. Encodings that target completely different language families (e.g., Cyrillic - # when the definitive match is Latin) are skipped entirely. - # Additionally, for same-family encodings that pass chaos probing, we reuse the - # definitive match's coherence ratios instead of recomputing them — a major savings - # since coherence_ratio accounts for ~30% of total time on slow Latin files. - definitive_match_found: bool = False - definitive_target_languages: set[str] = set() - # After the definitive match fires, we cap the number of additional same-family - # single-byte encodings that pass chaos probing. Once we've accumulated enough - # good candidates (N), further same-family SB encodings are unlikely to produce - # a better best() result and just waste mess_ratio + coherence_ratio time. - # The first encoding to trigger the definitive match is NOT counted (it's already in). - post_definitive_sb_success_count: int = 0 - POST_DEFINITIVE_SB_CAP: int = 7 - - # When a non-UTF multibyte encoding passes chaos probing with significant multibyte - # content (decoded length < 98% of raw length), skip all remaining single-byte encodings. - # Rationale: multi-byte decoders (CJK) have strict byte-sequence validation — if they - # decode without error AND pass chaos probing with substantial multibyte content, the - # data is genuinely multibyte encoded. Single-byte encodings will always decode (every - # byte maps to something) but waste time on mess_ratio before failing. - # The 98% threshold prevents false triggers on files that happen to have a few valid - # multibyte pairs (e.g., cp424/_ude_1.txt where big5 decodes with 99% ratio). - mb_definitive_match_found: bool = False - - fallback_ascii: CharsetMatch | None = None - fallback_u8: CharsetMatch | None = None - fallback_specified: CharsetMatch | None = None - - results: CharsetMatches = CharsetMatches() - - early_stop_results: CharsetMatches = CharsetMatches() - - sig_encoding, sig_payload = identify_sig_or_bom(sequences) - - if sig_encoding is not None: - prioritized_encodings.insert(0, sig_encoding) - logger.log( - TRACE, - "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.", - len(sig_payload), - sig_encoding, - ) - - prioritized_encodings.append("ascii") - - if "utf_8" not in prioritized_encodings: - prioritized_encodings.append("utf_8") - - for encoding_iana in prioritized_encodings + IANA_SUPPORTED_MB_FIRST: - if cp_isolation and encoding_iana not in cp_isolation: - continue - - if cp_exclusion and encoding_iana in cp_exclusion: - continue - - if encoding_iana in tested: - continue - - tested.add(encoding_iana) - - decoded_payload: str | None = None - bom_or_sig_available: bool = sig_encoding == encoding_iana - strip_sig_or_bom: bool = bom_or_sig_available and should_strip_sig_or_bom( - encoding_iana - ) - - if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available: - logger.log( - TRACE, - "Encoding %s won't be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", - encoding_iana, - ) - continue - if encoding_iana in {"utf_7"} and not bom_or_sig_available: - logger.log( - TRACE, - "Encoding %s won't be tested as-is because detection is unreliable without BOM/SIG.", - encoding_iana, - ) - continue - - # Skip encodings similar to ones that already soft-failed (high mess ratio). - # Checked BEFORE the expensive decode attempt. - if encoding_iana in soft_failure_skip: - logger.log( - TRACE, - "%s is deemed too similar to a code page that was already considered unsuited. Continuing!", - encoding_iana, - ) - continue - - try: - is_multi_byte_decoder: bool = is_multi_byte_encoding(encoding_iana) - except (ModuleNotFoundError, ImportError): # Defensive: - logger.log( - TRACE, - "Encoding %s does not provide an IncrementalDecoder", - encoding_iana, - ) - continue - - # When we've already found a definitive match (chaos=0.0 with good coherence) - # after testing the prioritized encodings, skip encodings that target - # completely different language families. This avoids running expensive - # mess_ratio + coherence_ratio on clearly unrelated candidates (e.g., Cyrillic - # when the definitive match is Latin-based). - if definitive_match_found: - if not is_multi_byte_decoder: - enc_languages = set(encoding_languages(encoding_iana)) - else: - enc_languages = set(mb_encoding_languages(encoding_iana)) - if not enc_languages.intersection(definitive_target_languages): - logger.log( - TRACE, - "Skipping %s: definitive match already found, this encoding targets different languages (%s vs %s).", - encoding_iana, - enc_languages, - definitive_target_languages, - ) - continue - - # After the definitive match, cap the number of additional same-family - # single-byte encodings that pass chaos probing. This avoids testing the - # tail of rare, low-value same-family encodings (mac_iceland, cp860, etc.) - # that almost never change best() but each cost ~1-2ms of mess_ratio + coherence. - if ( - definitive_match_found - and not is_multi_byte_decoder - and post_definitive_sb_success_count >= POST_DEFINITIVE_SB_CAP - ): - logger.log( - TRACE, - "Skipping %s: already accumulated %d same-family results after definitive match (cap=%d).", - encoding_iana, - post_definitive_sb_success_count, - POST_DEFINITIVE_SB_CAP, - ) - continue - - # When a multibyte encoding with significant multibyte content has already - # passed chaos probing, skip all single-byte encodings. They will either fail - # chaos probing (wasting mess_ratio time) or produce inferior results. - if mb_definitive_match_found and not is_multi_byte_decoder: - logger.log( - TRACE, - "Skipping single-byte %s: multi-byte definitive match already found.", - encoding_iana, - ) - continue - - # Single-byte candidates of regular size defer the expensive whole - # payload decode until after chunk probing: single-byte codecs are - # stateless (1 byte == 1 char) so decoding chunk slices is provably - # identical to slicing the decoded payload, and candidates rejected - # by chaos probing (the common case) never pay the full decode nor - # the payload hash. - deferred_decoding: bool = ( - not is_multi_byte_decoder and not is_too_large_sequence - ) - - try: - if is_too_large_sequence and not is_multi_byte_decoder: - str( - ( - sequences[: int(50e4)] - if not strip_sig_or_bom - else sequences[len(sig_payload) : int(50e4)] - ), - encoding=encoding_iana, - ) - elif not deferred_decoding: - # UTF-7 BOM is encoded in modified Base64 whose byte boundary - # can overlap with the next character. Stripping raw SIG bytes - # before decoding may leave stray bytes that decode as garbage. - # Decode the full sequence and remove the leading BOM char instead. - # see https://github.com/jawah/charset_normalizer/issues/718 - # and https://github.com/jawah/charset_normalizer/issues/716 - if encoding_iana == "utf_7" and bom_or_sig_available: - decoded_payload = str( - sequences, - encoding=encoding_iana, - ) - if decoded_payload and decoded_payload[0] == "\ufeff": - decoded_payload = decoded_payload[1:] - else: - decoded_payload = str( - ( - sequences - if not strip_sig_or_bom - else sequences[len(sig_payload) :] - ), - encoding=encoding_iana, - ) - except (UnicodeDecodeError, LookupError) as e: - if not isinstance(e, LookupError): - logger.log( - TRACE, - "Code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - tested_but_hard_failure.append(encoding_iana) - continue - - r_ = range( - 0 if not bom_or_sig_available else len(sig_payload), - length, - int(length / steps), - ) - - multi_byte_bonus: bool = ( - is_multi_byte_decoder - and decoded_payload is not None - and len(decoded_payload) < length - ) - - if multi_byte_bonus: - logger.log( - TRACE, - "Code page %s is a multi byte encoding table and it appear that at least one character " - "was encoded using n-bytes.", - encoding_iana, - ) - - max_chunk_gave_up: int = int(len(r_) / 4) - - max_chunk_gave_up = max(max_chunk_gave_up, 2) - early_stop_count: int = 0 - lazy_str_hard_failure = False - - md_chunks: list[str] = [] - md_ratios = [] - - try: - for chunk in cut_sequence_chunks( - sequences, - encoding_iana, - r_, - chunk_size, - bom_or_sig_available, - strip_sig_or_bom, - sig_payload, - is_multi_byte_decoder, - decoded_payload, - deferred_decoding, - ): - md_chunks.append(chunk) - - md_ratios.append( - cached_mess_ratio( - chunk, - threshold, - explain and 1 <= len(cp_isolation) <= 2, - ) - ) - - if md_ratios[-1] >= threshold: - early_stop_count += 1 - - if (early_stop_count >= max_chunk_gave_up) or ( - bom_or_sig_available and not strip_sig_or_bom - ): - break - except ( - UnicodeDecodeError, - LookupError, - ) as e: # Lazy str loading may have missed something there - if deferred_decoding: - # Deferred single-byte validation failed on a chunk (or the - # codec is unavailable on this interpreter build): identical - # outcome and bookkeeping to the eager full-decode failure. - logger.log( - TRACE, - "Code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - tested_but_hard_failure.append(encoding_iana) - continue - logger.log( - TRACE, - "LazyStr Loading: After MD chunk decode, code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - early_stop_count = max_chunk_gave_up - lazy_str_hard_failure = True - - mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0 - - # We might want to check the sequence again with the whole content, - # but only if initial MD tests passed. - if ( - not lazy_str_hard_failure - and is_too_large_sequence - and not is_multi_byte_decoder - and mean_mess_ratio < threshold - and early_stop_count < max_chunk_gave_up - ): - try: - sequences[int(50e3) :].decode(encoding_iana, errors="strict") - except UnicodeDecodeError as e: - logger.log( - TRACE, - "LazyStr Loading: After final lookup, code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - tested_but_hard_failure.append(encoding_iana) - continue - - if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up: - tested_but_soft_failure.append(encoding_iana) - if encoding_iana in IANA_SUPPORTED_SIMILAR: - soft_failure_skip.update(IANA_SUPPORTED_SIMILAR[encoding_iana]) - logger.log( - TRACE, - "%s was excluded because of initial chaos probing. Gave up %i time(s). " - "Computed mean chaos is %f %%.", - encoding_iana, - early_stop_count, - round(mean_mess_ratio * 100, ndigits=3), - ) - # Preparing those fallbacks in case we got nothing. - if ( - enable_fallback - and encoding_iana - in ["ascii", "utf_8", specified_encoding, "utf_16", "utf_32"] - and not lazy_str_hard_failure - ): - # Always fully decode payload before. - # We've missed a UnicodeDecodeError proof - # while issuing release 3.4.8 - # see https://github.com/jawah/charset_normalizer/issues/771 - if decoded_payload is None: - try: - decoded_payload = str( - ( - sequences - if not strip_sig_or_bom - else sequences[len(sig_payload) :] - ), - encoding=encoding_iana, - ) - except (UnicodeDecodeError, LookupError): - logger.log( - TRACE, - "%s does not decode the whole payload: fallback entry withheld.", - encoding_iana, - ) - continue - if is_too_large_sequence: - # Don't retain huge payload in RAM. - decoded_payload = None - - fallback_entry = CharsetMatch( - sequences, - encoding_iana, - threshold, - bom_or_sig_available, - [], - decoded_payload, - preemptive_declaration=specified_encoding, - ) - if encoding_iana == specified_encoding: - fallback_specified = fallback_entry - elif encoding_iana == "ascii": - fallback_ascii = fallback_entry - else: - fallback_u8 = fallback_entry - continue - - if deferred_decoding: - # The candidate passed chaos probing: perform the whole payload - # decode (validation + payload reuse) that was deferred earlier. - try: - decoded_payload = str( - ( - sequences - if not strip_sig_or_bom - else sequences[len(sig_payload) :] - ), - encoding=encoding_iana, - ) - except (UnicodeDecodeError, LookupError) as e: - logger.log( - TRACE, - "Code page %s does not fit given bytes sequence at ALL. %s", - encoding_iana, - str(e), - ) - tested_but_hard_failure.append(encoding_iana) - continue - - logger.log( - TRACE, - "%s passed initial chaos probing. Mean measured chaos is %f %%", - encoding_iana, - round(mean_mess_ratio * 100, ndigits=3), - ) - - if not is_multi_byte_decoder: - target_languages: list[str] = encoding_languages(encoding_iana) - else: - target_languages = mb_encoding_languages(encoding_iana) - - if target_languages: - logger.log( - TRACE, - "%s should target any language(s) of %s", - encoding_iana, - target_languages, - ) - - cd_ratios = [] - - # Run coherence detection on all chunks. We previously tried limiting to - # 1-2 chunks for post-definitive encodings to save time, but this caused - # coverage regressions by producing unrepresentative coherence scores. - # The SB cap and language-family skip optimizations provide sufficient - # speedup without sacrificing coherence accuracy. - if encoding_iana != "ascii": - # We shall skip the CD when its about ASCII - # Most of the time its not relevant to run "language-detection" on it. - lg_inclusion: str | None = ( - ",".join(target_languages) if target_languages else None - ) - - for chunk in md_chunks: - chunk_languages = cached_coherence_ratio( - chunk, - language_threshold, - lg_inclusion, - ) - - cd_ratios.append(chunk_languages) - - cd_ratios_merged = merge_coherence_ratios(cd_ratios) - - if cd_ratios_merged: - logger.log( - TRACE, - "We detected language %s using %s", - cd_ratios_merged, - encoding_iana, - ) - - current_match = CharsetMatch( - sequences, - encoding_iana, - mean_mess_ratio, - bom_or_sig_available, - cd_ratios_merged, - ( - decoded_payload - if ( - not is_too_large_sequence - or encoding_iana in [specified_encoding, "ascii", "utf_8"] - ) - else None - ), - preemptive_declaration=specified_encoding, - ) - - results.append(current_match) - - # Count post-definitive same-family SB successes for the early termination cap. - # Only count low-mess encodings (< 2%) toward the cap. High-mess encodings are - # marginal results that shouldn't prevent better-quality candidates from being - # tested. For example, iso8859_4 (mess=0%) should not be skipped just because - # 7 high-mess Latin encodings (cp1252 at 8%, etc.) were tried first. - if ( - definitive_match_found - and not is_multi_byte_decoder - and mean_mess_ratio < 0.02 - ): - post_definitive_sb_success_count += 1 - - if ( - encoding_iana in [specified_encoding, "ascii", "utf_8"] - and mean_mess_ratio < 0.1 - ): - # If md says nothing to worry about, then... stop immediately! - if mean_mess_ratio == 0.0: - logger.debug( - "Encoding detection: %s is most likely the one.", - current_match.encoding, - ) - if explain: # Defensive: ensure exit path clean handler - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - return CharsetMatches([current_match]) - - early_stop_results.append(current_match) - - if ( - len(early_stop_results) - and (specified_encoding is None or specified_encoding in tested) - and "ascii" in tested - and "utf_8" in tested - ): - probable_result = early_stop_results.best() - assert probable_result is not None - logger.debug( - "Encoding detection: %s is most likely the one.", - probable_result.encoding, - ) - if explain: # Defensive: ensure exit path clean handler - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - - return CharsetMatches([probable_result]) - - # Once we find a result with good coherence (>= 0.5) after testing the - # prioritized encodings (ascii, utf_8), activate "definitive mode": skip - # encodings that target completely different language families. This avoids - # running expensive mess_ratio + coherence_ratio on clearly unrelated - # candidates (e.g., Cyrillic encodings when the match is Latin-based). - # We require coherence >= 0.5 to avoid false positives (e.g., cp1251 decoding - # Hebrew text with 0.0 chaos but wrong language detection at coherence 0.33). - if not definitive_match_found and not is_multi_byte_decoder: - best_coherence = ( - max((v for _, v in cd_ratios_merged), default=0.0) - if cd_ratios_merged - else 0.0 - ) - if best_coherence >= 0.5 and "ascii" in tested and "utf_8" in tested: - definitive_match_found = True - definitive_target_languages.update(target_languages) - logger.log( - TRACE, - "Definitive match found: %s (chaos=%.3f, coherence=%.2f). Encodings targeting different language families will be skipped.", - encoding_iana, - mean_mess_ratio, - best_coherence, - ) - - # When a non-UTF multibyte encoding passes chaos probing with significant - # multibyte content (decoded < 98% of raw), activate mb_definitive_match. - # This skips all remaining single-byte encodings which would either soft-fail - # (running expensive mess_ratio for nothing) or produce inferior results. - if ( - not mb_definitive_match_found - and is_multi_byte_decoder - and multi_byte_bonus - and decoded_payload is not None - and len(decoded_payload) < length * 0.98 - and encoding_iana - not in { - "utf_8", - "utf_8_sig", - "utf_16", - "utf_16_be", - "utf_16_le", - "utf_32", - "utf_32_be", - "utf_32_le", - "utf_7", - } - and "ascii" in tested - and "utf_8" in tested - ): - mb_definitive_match_found = True - logger.log( - TRACE, - "Multi-byte definitive match: %s (chaos=%.3f, decoded=%d/%d=%.1f%%). Single-byte encodings will be skipped.", - encoding_iana, - mean_mess_ratio, - len(decoded_payload), - length, - len(decoded_payload) / length * 100, - ) - - if encoding_iana == sig_encoding: - logger.debug( - "Encoding detection: %s is most likely the one as we detected a BOM or SIG within " - "the beginning of the sequence.", - encoding_iana, - ) - if explain: # Defensive: ensure exit path clean handler - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - return CharsetMatches([results[encoding_iana]]) - - if len(results) == 0: - if fallback_u8 or fallback_ascii or fallback_specified: - logger.log( - TRACE, - "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.", - ) - - if fallback_specified: - logger.debug( - "Encoding detection: %s will be used as a fallback match", - fallback_specified.encoding, - ) - results.append(fallback_specified) - elif ( - (fallback_u8 and fallback_ascii is None) - or ( - fallback_u8 - and fallback_ascii - and fallback_u8.fingerprint != fallback_ascii.fingerprint - ) - or (fallback_u8 is not None) - ): - logger.debug("Encoding detection: utf_8 will be used as a fallback match") - results.append(fallback_u8) - elif fallback_ascii: - logger.debug("Encoding detection: ascii will be used as a fallback match") - results.append(fallback_ascii) - - if results: - logger.debug( - "Encoding detection: Found %s as plausible (best-candidate) for content. With %i alternatives.", - results.best().encoding, # type: ignore - len(results) - 1, - ) - else: - logger.debug("Encoding detection: Unable to determine any suitable charset.") - - if explain: - logger.removeHandler(explain_handler) - logger.setLevel(previous_logger_level) - - return results - - -def from_fp( - fp: BinaryIO, - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: list[str] | None = None, - cp_exclusion: list[str] | None = None, - preemptive_behaviour: bool = True, - explain: bool = False, - language_threshold: float = 0.1, - enable_fallback: bool = True, -) -> CharsetMatches: - """ - Same thing than the function from_bytes but using a file pointer that is already ready. - Will not close the file pointer. - """ - return from_bytes( - fp.read(), - steps, - chunk_size, - threshold, - cp_isolation, - cp_exclusion, - preemptive_behaviour, - explain, - language_threshold, - enable_fallback, - ) - - -def from_path( - path: str | bytes | PathLike, # type: ignore[type-arg] - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: list[str] | None = None, - cp_exclusion: list[str] | None = None, - preemptive_behaviour: bool = True, - explain: bool = False, - language_threshold: float = 0.1, - enable_fallback: bool = True, -) -> CharsetMatches: - """ - Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. - Can raise IOError. - """ - with open(path, "rb") as fp: - return from_fp( - fp, - steps, - chunk_size, - threshold, - cp_isolation, - cp_exclusion, - preemptive_behaviour, - explain, - language_threshold, - enable_fallback, - ) - - -def is_binary( - fp_or_path_or_payload: PathLike | str | BinaryIO | bytes, # type: ignore[type-arg] - steps: int = 5, - chunk_size: int = 512, - threshold: float = 0.20, - cp_isolation: list[str] | None = None, - cp_exclusion: list[str] | None = None, - preemptive_behaviour: bool = True, - explain: bool = False, - language_threshold: float = 0.1, - enable_fallback: bool = False, -) -> bool: - """ - Detect if the given input (file, bytes, or path) points to a binary file. aka. not a string. - Based on the same main heuristic algorithms and default kwargs at the sole exception that fallbacks match - are disabled to be stricter around ASCII-compatible but unlikely to be a string. - """ - if isinstance(fp_or_path_or_payload, (str, PathLike)): - guesses = from_path( - fp_or_path_or_payload, - steps=steps, - chunk_size=chunk_size, - threshold=threshold, - cp_isolation=cp_isolation, - cp_exclusion=cp_exclusion, - preemptive_behaviour=preemptive_behaviour, - explain=explain, - language_threshold=language_threshold, - enable_fallback=enable_fallback, - ) - elif isinstance( - fp_or_path_or_payload, - ( - bytes, - bytearray, - ), - ): - guesses = from_bytes( - fp_or_path_or_payload, - steps=steps, - chunk_size=chunk_size, - threshold=threshold, - cp_isolation=cp_isolation, - cp_exclusion=cp_exclusion, - preemptive_behaviour=preemptive_behaviour, - explain=explain, - language_threshold=language_threshold, - enable_fallback=enable_fallback, - ) - else: - guesses = from_fp( - fp_or_path_or_payload, - steps=steps, - chunk_size=chunk_size, - threshold=threshold, - cp_isolation=cp_isolation, - cp_exclusion=cp_exclusion, - preemptive_behaviour=preemptive_behaviour, - explain=explain, - language_threshold=language_threshold, - enable_fallback=enable_fallback, - ) - - return not guesses diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py deleted file mode 100644 index 7a9344f1e5a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/cd.py +++ /dev/null @@ -1,467 +0,0 @@ -from __future__ import annotations - -import importlib -from codecs import IncrementalDecoder -from functools import lru_cache - -from .constant import ( - FREQUENCIES, - KO_NAMES, - LANGUAGE_SUPPORTED_COUNT, - TOO_SMALL_SEQUENCE, - ZH_NAMES, - _FREQUENCIES_SET, - _FREQUENCIES_RANK, -) -from .md import _ASCII_CHAR_INFO, _char_info, is_suspiciously_successive_range -from .models import CoherenceMatches -from .utils import ( - is_multi_byte_encoding, - is_unicode_range_secondary, -) - - -def encoding_unicode_range(iana_name: str) -> list[str]: - """ - Return associated unicode ranges in a single byte code page. - """ - if is_multi_byte_encoding(iana_name): - raise OSError( # Defensive: - "Function not supported on multi-byte code page" - ) - - decoder = importlib.import_module(f"encodings.{iana_name}").IncrementalDecoder - - p: IncrementalDecoder = decoder(errors="ignore") - seen_ranges: dict[str, int] = {} - character_count: int = 0 - - for i in range(0x40, 0xFF): - chunk: str = p.decode(bytes([i])) - - if chunk: - chunk_codepoint = ord(chunk) - character_range: str | None = ( - _ASCII_CHAR_INFO[chunk_codepoint].range - if chunk_codepoint < 128 - else _char_info(chunk).range - ) - - if character_range is None: - continue - - if not is_unicode_range_secondary(character_range): - if character_range not in seen_ranges: - seen_ranges[character_range] = 0 - seen_ranges[character_range] += 1 - character_count += 1 - - return sorted( - [ - character_range - for character_range in seen_ranges - if seen_ranges[character_range] / character_count >= 0.15 - ] - ) - - -def unicode_range_languages(primary_range: str) -> list[str]: - """ - Return inferred languages used with a unicode range. - """ - languages: list[str] = [] - - for language, characters in FREQUENCIES.items(): - for character in characters: - codepoint = ord(character) - info = ( - _ASCII_CHAR_INFO[codepoint] - if codepoint < 128 - else _char_info(character) - ) - if info.range == primary_range: - languages.append(language) - break - - return languages - - -@lru_cache() -def encoding_languages(iana_name: str) -> list[str]: - """ - Single-byte encoding language association. Some code page are heavily linked to particular language(s). - This function does the correspondence. - """ - try: - unicode_ranges: list[str] = encoding_unicode_range(iana_name) - except ImportError: # Defensive: encoding unavailable on this build. - return [] - - primary_range: str | None = None - - for specified_range in unicode_ranges: - if "Latin" not in specified_range: - primary_range = specified_range - break - - if primary_range is None: - return ["Latin Based"] - - return unicode_range_languages(primary_range) - - -@lru_cache() -def mb_encoding_languages(iana_name: str) -> list[str]: - """ - Multi-byte encoding language association. Some code page are heavily linked to particular language(s). - This function does the correspondence. - """ - if ( - iana_name.startswith("shift_") - or iana_name.startswith("iso2022_jp") - or iana_name.startswith("euc_j") - or iana_name == "cp932" - ): - return ["Japanese"] - if iana_name.startswith("gb") or iana_name in ZH_NAMES: - return ["Chinese"] - if iana_name.startswith("iso2022_kr") or iana_name in KO_NAMES: - return ["Korean"] - - return [] - - -@lru_cache(maxsize=LANGUAGE_SUPPORTED_COUNT) -def get_target_features(language: str) -> tuple[bool, bool]: - """ - Determine main aspects from a supported language if it contains accents and if is pure Latin. - """ - target_have_accents: bool = False - target_pure_latin: bool = True - - for character in FREQUENCIES[language]: - codepoint = ord(character) - info = _ASCII_CHAR_INFO[codepoint] if codepoint < 128 else _char_info(character) - if not target_have_accents and info.accentuated: - target_have_accents = True - if target_pure_latin and not info.latin: - target_pure_latin = False - - return target_have_accents, target_pure_latin - - -def alphabet_languages( - characters: list[str], ignore_non_latin: bool = False -) -> list[str]: - """ - Return associated languages associated to given characters. - """ - languages: list[tuple[str, float]] = [] - - characters_set: frozenset[str] = frozenset(characters) - source_have_accents = False - for character in characters: - codepoint = ord(character) - info = _ASCII_CHAR_INFO[codepoint] if codepoint < 128 else _char_info(character) - if info.accentuated: - source_have_accents = True - break - - for language, language_characters in FREQUENCIES.items(): - target_have_accents, target_pure_latin = get_target_features(language) - - if ignore_non_latin and not target_pure_latin: - continue - - if not target_have_accents and source_have_accents: - continue - - character_count: int = len(language_characters) - - character_match_count: int = len(_FREQUENCIES_SET[language] & characters_set) - - ratio: float = character_match_count / character_count - - if ratio >= 0.2: - languages.append((language, ratio)) - - languages = sorted(languages, key=lambda x: x[1], reverse=True) - - return [compatible_language[0] for compatible_language in languages] - - -def characters_popularity_compare( - language: str, ordered_characters: list[str] -) -> float: - """ - Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language. - The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit). - Beware that is function is not strict on the match in order to ease the detection. (Meaning close match is 1.) - """ - if language not in FREQUENCIES: - raise ValueError(f"{language} not available") # Defensive: - - character_approved_count: int = 0 - lang_rank: dict[str, int] = _FREQUENCIES_RANK[language] - - ordered_characters_count: int = len(ordered_characters) - target_language_characters_count: int = len(FREQUENCIES[language]) - - large_alphabet: bool = target_language_characters_count > 26 - large_alphabet_threshold: float = target_language_characters_count / 3 - - expected_projection_ratio: float = ( - target_language_characters_count / ordered_characters_count - ) - - # Single pass: characters present in the language vocabulary, as - # (language rank, popularity rank) pairs. The scoring below only ever - # needs ranks, never the characters themselves. - common_lr: list[int] = [] - common_orr: list[int] = [] - for popularity_rank, character in enumerate(ordered_characters): - language_rank = lang_rank.get(character) - if language_rank is not None: - common_lr.append(language_rank) - common_orr.append(popularity_rank) - - for character_rank_in_language, character_rank in zip(common_lr, common_orr): - character_rank_projection: int = int(character_rank * expected_projection_ratio) - - if ( - not large_alphabet - and abs(character_rank_projection - character_rank_in_language) > 4 - ): - continue - - if ( - large_alphabet - and abs(character_rank_projection - character_rank_in_language) - < large_alphabet_threshold - ): - character_approved_count += 1 - continue - - if character_rank_in_language == 0: - # before_match_count is structurally 0 here (no pair can have a - # smaller language rank): the historic "before <= 4" acceptance - # always holds. (The symmetric "after_len == 0" case is - # impossible: language ranks are strictly below the language - # character count, hence after_len >= 1.) - character_approved_count += 1 - continue - - after_len: int = target_language_characters_count - character_rank_in_language - - # Count how many characters appear "before" in both orderings, and - # how many appear "at or after" in both orderings. Both counts grow - # monotonically and the approval thresholds - # (before / rank >= 0.4 or after / after_len >= 0.4) are known - # upfront, expressed below as exact integer comparisons: exit as - # soon as one is crossed. - before_match_count: int = 0 - after_match_count: int = 0 - - for lr_i, orr_i in zip(common_lr, common_orr): - if lr_i < character_rank_in_language: - if orr_i < character_rank: - before_match_count += 1 - if 5 * before_match_count >= 2 * character_rank_in_language: - character_approved_count += 1 - break - else: - if orr_i >= character_rank: - after_match_count += 1 - if 5 * after_match_count >= 2 * after_len: - character_approved_count += 1 - break - - return character_approved_count / len(ordered_characters) - - -def alpha_unicode_split(decoded_sequence: str) -> list[str]: - """ - Given a decoded text sequence, return a list of str. Unicode range / alphabet separation. - Ex. a text containing English/Latin with a bit a Hebrew will return two items in the resulting list; - One containing the latin letters and the other hebrew. - """ - layers: dict[str, list[str]] = {} - - # Fast path: track single-layer key to skip dict iteration for single-script text. - single_layer_key: str | None = None - multi_layer: bool = False - - # Cache the last character_range and its resolved layer to avoid repeated - # is_suspiciously_successive_range calls for consecutive same-range chars. - prev_character_range: str | None = None - prev_layer_target: str | None = None - - for character in decoded_sequence: - # Reuse the per-codepoint CharInfo cache: info.alpha and info.range - # are computed with the very same str.isalpha() / unicode_range() - # calls this loop historically made per character occurrence. - codepoint: int = ord(character) - if codepoint < 128: - info = _ASCII_CHAR_INFO[codepoint] - else: - info = _char_info(character) - - if not info.alpha: - continue - - character_range: str | None = info.range - - if character_range is None: - continue - - # Fast path: same range as previous character → reuse cached layer target. - if character_range == prev_character_range: - if prev_layer_target is not None: - layers[prev_layer_target].append(character) - continue - - layer_target_range: str | None = None - - if multi_layer: - for discovered_range in layers: - if not is_suspiciously_successive_range( - discovered_range, character_range - ): - layer_target_range = discovered_range - break - elif single_layer_key is not None: - if not is_suspiciously_successive_range(single_layer_key, character_range): - layer_target_range = single_layer_key - - if layer_target_range is None: - layer_target_range = character_range - - if layer_target_range not in layers: - layers[layer_target_range] = [] - if single_layer_key is None: - single_layer_key = layer_target_range - else: - multi_layer = True - - layers[layer_target_range].append(character) - - # Cache for next iteration - prev_character_range = character_range - prev_layer_target = layer_target_range - - return ["".join(chars).lower() for chars in layers.values()] - - -def merge_coherence_ratios(results: list[CoherenceMatches]) -> CoherenceMatches: - """ - This function merge results previously given by the function coherence_ratio. - The return type is the same as coherence_ratio. - """ - per_language_ratios: dict[str, list[float]] = {} - for result in results: - for sub_result in result: - language, ratio = sub_result - if language not in per_language_ratios: - per_language_ratios[language] = [ratio] - continue - per_language_ratios[language].append(ratio) - - merge = [ - ( - language, - round( - sum(per_language_ratios[language]) / len(per_language_ratios[language]), - 4, - ), - ) - for language in per_language_ratios - ] - - return sorted(merge, key=lambda x: x[1], reverse=True) - - -def filter_alt_coherence_matches(results: CoherenceMatches) -> CoherenceMatches: - """ - We shall NOT return "English—" in CoherenceMatches because it is an alternative - of "English". This function only keeps the best match and remove the em-dash in it. - """ - index_results: dict[str, list[float]] = dict() - - for result in results: - language, ratio = result - no_em_name: str = language.replace("—", "") - - if no_em_name not in index_results: - index_results[no_em_name] = [] - - index_results[no_em_name].append(ratio) - - if any(len(index_results[e]) > 1 for e in index_results): - filtered_results: CoherenceMatches = [] - - for language in index_results: - filtered_results.append((language, max(index_results[language]))) - - return filtered_results - - return results - - -def coherence_ratio( - decoded_sequence: str, threshold: float = 0.1, lg_inclusion: str | None = None -) -> CoherenceMatches: - """ - Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers. - A layer = Character extraction by alphabets/ranges. - """ - - results: list[tuple[str, float]] = [] - ignore_non_latin: bool = False - - sufficient_match_count: int = 0 - - lg_inclusion_list = lg_inclusion.split(",") if lg_inclusion is not None else [] - if "Latin Based" in lg_inclusion_list: - ignore_non_latin = True - lg_inclusion_list.remove("Latin Based") - - for layer in alpha_unicode_split(decoded_sequence): - # Native counting + stable sort reproduce Counter.most_common() - # ordering exactly (ties keep first-appearance order) without the - # interpreted Counter machinery in the compiled hot path. - char_counts: dict[str, int] = {} - for layer_character in layer: - char_counts[layer_character] = char_counts.get(layer_character, 0) + 1 - - character_count: int = len(layer) - - if character_count <= TOO_SMALL_SEQUENCE: - continue - - popular_character_ordered: list[str] = [ - item[0] - for item in sorted( - char_counts.items(), key=lambda item: item[1], reverse=True - ) - ] - - for language in lg_inclusion_list or alphabet_languages( - popular_character_ordered, ignore_non_latin - ): - ratio: float = characters_popularity_compare( - language, popular_character_ordered - ) - - if ratio < threshold: - continue - elif ratio >= 0.8: - sufficient_match_count += 1 - - results.append((language, round(ratio, 4))) - - if sufficient_match_count >= 3: - break - - return sorted( - filter_alt_coherence_matches(results), key=lambda x: x[1], reverse=True - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py deleted file mode 100644 index f038336cbf6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/constant.py +++ /dev/null @@ -1,2497 +0,0 @@ -from __future__ import annotations - -from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE -from encodings.aliases import aliases -from re import IGNORECASE -from re import compile as re_compile - -# Contain for each eligible encoding a list of/item bytes SIG/BOM -ENCODING_MARKS: dict[str, bytes | list[bytes]] = { - "utf_8": BOM_UTF8, - "utf_7": [ - b"\x2b\x2f\x76\x38", - b"\x2b\x2f\x76\x39", - b"\x2b\x2f\x76\x2b", - b"\x2b\x2f\x76\x2f", - ], - "gb18030": b"\x84\x31\x95\x33", - "utf_32": [BOM_UTF32_BE, BOM_UTF32_LE], - "utf_16": [BOM_UTF16_BE, BOM_UTF16_LE], -} - -TOO_SMALL_SEQUENCE: int = 32 -TOO_BIG_SEQUENCE: int = int(10e6) - -UTF8_MAXIMAL_ALLOCATION: int = 1_112_064 - -# Up-to-date Unicode ucd/17.0.0 -UNICODE_RANGES_COMBINED: dict[str, range] = { - "Control character": range(32), - "Basic Latin": range(32, 128), - "Latin-1 Supplement": range(128, 256), - "Latin Extended-A": range(256, 384), - "Latin Extended-B": range(384, 592), - "IPA Extensions": range(592, 688), - "Spacing Modifier Letters": range(688, 768), - "Combining Diacritical Marks": range(768, 880), - "Greek and Coptic": range(880, 1024), - "Cyrillic": range(1024, 1280), - "Cyrillic Supplement": range(1280, 1328), - "Armenian": range(1328, 1424), - "Hebrew": range(1424, 1536), - "Arabic": range(1536, 1792), - "Syriac": range(1792, 1872), - "Arabic Supplement": range(1872, 1920), - "Thaana": range(1920, 1984), - "NKo": range(1984, 2048), - "Samaritan": range(2048, 2112), - "Mandaic": range(2112, 2144), - "Syriac Supplement": range(2144, 2160), - "Arabic Extended-B": range(2160, 2208), - "Arabic Extended-A": range(2208, 2304), - "Devanagari": range(2304, 2432), - "Bengali": range(2432, 2560), - "Gurmukhi": range(2560, 2688), - "Gujarati": range(2688, 2816), - "Oriya": range(2816, 2944), - "Tamil": range(2944, 3072), - "Telugu": range(3072, 3200), - "Kannada": range(3200, 3328), - "Malayalam": range(3328, 3456), - "Sinhala": range(3456, 3584), - "Thai": range(3584, 3712), - "Lao": range(3712, 3840), - "Tibetan": range(3840, 4096), - "Myanmar": range(4096, 4256), - "Georgian": range(4256, 4352), - "Hangul Jamo": range(4352, 4608), - "Ethiopic": range(4608, 4992), - "Ethiopic Supplement": range(4992, 5024), - "Cherokee": range(5024, 5120), - "Unified Canadian Aboriginal Syllabics": range(5120, 5760), - "Ogham": range(5760, 5792), - "Runic": range(5792, 5888), - "Tagalog": range(5888, 5920), - "Hanunoo": range(5920, 5952), - "Buhid": range(5952, 5984), - "Tagbanwa": range(5984, 6016), - "Khmer": range(6016, 6144), - "Mongolian": range(6144, 6320), - "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6400), - "Limbu": range(6400, 6480), - "Tai Le": range(6480, 6528), - "New Tai Lue": range(6528, 6624), - "Khmer Symbols": range(6624, 6656), - "Buginese": range(6656, 6688), - "Tai Tham": range(6688, 6832), - "Combining Diacritical Marks Extended": range(6832, 6912), - "Balinese": range(6912, 7040), - "Sundanese": range(7040, 7104), - "Batak": range(7104, 7168), - "Lepcha": range(7168, 7248), - "Ol Chiki": range(7248, 7296), - "Cyrillic Extended-C": range(7296, 7312), - "Georgian Extended": range(7312, 7360), - "Sundanese Supplement": range(7360, 7376), - "Vedic Extensions": range(7376, 7424), - "Phonetic Extensions": range(7424, 7552), - "Phonetic Extensions Supplement": range(7552, 7616), - "Combining Diacritical Marks Supplement": range(7616, 7680), - "Latin Extended Additional": range(7680, 7936), - "Greek Extended": range(7936, 8192), - "General Punctuation": range(8192, 8304), - "Superscripts and Subscripts": range(8304, 8352), - "Currency Symbols": range(8352, 8400), - "Combining Diacritical Marks for Symbols": range(8400, 8448), - "Letterlike Symbols": range(8448, 8528), - "Number Forms": range(8528, 8592), - "Arrows": range(8592, 8704), - "Mathematical Operators": range(8704, 8960), - "Miscellaneous Technical": range(8960, 9216), - "Control Pictures": range(9216, 9280), - "Optical Character Recognition": range(9280, 9312), - "Enclosed Alphanumerics": range(9312, 9472), - "Box Drawing": range(9472, 9600), - "Block Elements": range(9600, 9632), - "Geometric Shapes": range(9632, 9728), - "Miscellaneous Symbols": range(9728, 9984), - "Dingbats": range(9984, 10176), - "Miscellaneous Mathematical Symbols-A": range(10176, 10224), - "Supplemental Arrows-A": range(10224, 10240), - "Braille Patterns": range(10240, 10496), - "Supplemental Arrows-B": range(10496, 10624), - "Miscellaneous Mathematical Symbols-B": range(10624, 10752), - "Supplemental Mathematical Operators": range(10752, 11008), - "Miscellaneous Symbols and Arrows": range(11008, 11264), - "Glagolitic": range(11264, 11360), - "Latin Extended-C": range(11360, 11392), - "Coptic": range(11392, 11520), - "Georgian Supplement": range(11520, 11568), - "Tifinagh": range(11568, 11648), - "Ethiopic Extended": range(11648, 11744), - "Cyrillic Extended-A": range(11744, 11776), - "Supplemental Punctuation": range(11776, 11904), - "CJK Radicals Supplement": range(11904, 12032), - "Kangxi Radicals": range(12032, 12256), - "Ideographic Description Characters": range(12272, 12288), - "CJK Symbols and Punctuation": range(12288, 12352), - "Hiragana": range(12352, 12448), - "Katakana": range(12448, 12544), - "Bopomofo": range(12544, 12592), - "Hangul Compatibility Jamo": range(12592, 12688), - "Kanbun": range(12688, 12704), - "Bopomofo Extended": range(12704, 12736), - "CJK Strokes": range(12736, 12784), - "Katakana Phonetic Extensions": range(12784, 12800), - "Enclosed CJK Letters and Months": range(12800, 13056), - "CJK Compatibility": range(13056, 13312), - "CJK Unified Ideographs Extension A": range(13312, 19904), - "Yijing Hexagram Symbols": range(19904, 19968), - "CJK Unified Ideographs": range(19968, 40960), - "Yi Syllables": range(40960, 42128), - "Yi Radicals": range(42128, 42192), - "Lisu": range(42192, 42240), - "Vai": range(42240, 42560), - "Cyrillic Extended-B": range(42560, 42656), - "Bamum": range(42656, 42752), - "Modifier Tone Letters": range(42752, 42784), - "Latin Extended-D": range(42784, 43008), - "Syloti Nagri": range(43008, 43056), - "Common Indic Number Forms": range(43056, 43072), - "Phags-pa": range(43072, 43136), - "Saurashtra": range(43136, 43232), - "Devanagari Extended": range(43232, 43264), - "Kayah Li": range(43264, 43312), - "Rejang": range(43312, 43360), - "Hangul Jamo Extended-A": range(43360, 43392), - "Javanese": range(43392, 43488), - "Myanmar Extended-B": range(43488, 43520), - "Cham": range(43520, 43616), - "Myanmar Extended-A": range(43616, 43648), - "Tai Viet": range(43648, 43744), - "Meetei Mayek Extensions": range(43744, 43776), - "Ethiopic Extended-A": range(43776, 43824), - "Latin Extended-E": range(43824, 43888), - "Cherokee Supplement": range(43888, 43968), - "Meetei Mayek": range(43968, 44032), - "Hangul Syllables": range(44032, 55216), - "Hangul Jamo Extended-B": range(55216, 55296), - "High Surrogates": range(55296, 56192), - "High Private Use Surrogates": range(56192, 56320), - "Low Surrogates": range(56320, 57344), - "Private Use Area": range(57344, 63744), - "CJK Compatibility Ideographs": range(63744, 64256), - "Alphabetic Presentation Forms": range(64256, 64336), - "Arabic Presentation Forms-A": range(64336, 65024), - "Variation Selectors": range(65024, 65040), - "Vertical Forms": range(65040, 65056), - "Combining Half Marks": range(65056, 65072), - "CJK Compatibility Forms": range(65072, 65104), - "Small Form Variants": range(65104, 65136), - "Arabic Presentation Forms-B": range(65136, 65280), - "Halfwidth and Fullwidth Forms": range(65280, 65520), - "Specials": range(65520, 65536), - "Linear B Syllabary": range(65536, 65664), - "Linear B Ideograms": range(65664, 65792), - "Aegean Numbers": range(65792, 65856), - "Ancient Greek Numbers": range(65856, 65936), - "Ancient Symbols": range(65936, 66000), - "Phaistos Disc": range(66000, 66048), - "Lycian": range(66176, 66208), - "Carian": range(66208, 66272), - "Coptic Epact Numbers": range(66272, 66304), - "Old Italic": range(66304, 66352), - "Gothic": range(66352, 66384), - "Old Permic": range(66384, 66432), - "Ugaritic": range(66432, 66464), - "Old Persian": range(66464, 66528), - "Deseret": range(66560, 66640), - "Shavian": range(66640, 66688), - "Osmanya": range(66688, 66736), - "Osage": range(66736, 66816), - "Elbasan": range(66816, 66864), - "Caucasian Albanian": range(66864, 66928), - "Vithkuqi": range(66928, 67008), - "Todhri": range(67008, 67072), - "Linear A": range(67072, 67456), - "Latin Extended-F": range(67456, 67520), - "Cypriot Syllabary": range(67584, 67648), - "Imperial Aramaic": range(67648, 67680), - "Palmyrene": range(67680, 67712), - "Nabataean": range(67712, 67760), - "Hatran": range(67808, 67840), - "Phoenician": range(67840, 67872), - "Lydian": range(67872, 67904), - "Sidetic": range(67904, 67936), - "Meroitic Hieroglyphs": range(67968, 68000), - "Meroitic Cursive": range(68000, 68096), - "Kharoshthi": range(68096, 68192), - "Old South Arabian": range(68192, 68224), - "Old North Arabian": range(68224, 68256), - "Manichaean": range(68288, 68352), - "Avestan": range(68352, 68416), - "Inscriptional Parthian": range(68416, 68448), - "Inscriptional Pahlavi": range(68448, 68480), - "Psalter Pahlavi": range(68480, 68528), - "Old Turkic": range(68608, 68688), - "Old Hungarian": range(68736, 68864), - "Hanifi Rohingya": range(68864, 68928), - "Garay": range(68928, 69008), - "Rumi Numeral Symbols": range(69216, 69248), - "Yezidi": range(69248, 69312), - "Arabic Extended-C": range(69312, 69376), - "Old Sogdian": range(69376, 69424), - "Sogdian": range(69424, 69488), - "Old Uyghur": range(69488, 69552), - "Chorasmian": range(69552, 69600), - "Elymaic": range(69600, 69632), - "Brahmi": range(69632, 69760), - "Kaithi": range(69760, 69840), - "Sora Sompeng": range(69840, 69888), - "Chakma": range(69888, 69968), - "Mahajani": range(69968, 70016), - "Sharada": range(70016, 70112), - "Sinhala Archaic Numbers": range(70112, 70144), - "Khojki": range(70144, 70224), - "Multani": range(70272, 70320), - "Khudawadi": range(70320, 70400), - "Grantha": range(70400, 70528), - "Tulu-Tigalari": range(70528, 70656), - "Newa": range(70656, 70784), - "Tirhuta": range(70784, 70880), - "Siddham": range(71040, 71168), - "Modi": range(71168, 71264), - "Mongolian Supplement": range(71264, 71296), - "Takri": range(71296, 71376), - "Myanmar Extended-C": range(71376, 71424), - "Ahom": range(71424, 71504), - "Dogra": range(71680, 71760), - "Warang Citi": range(71840, 71936), - "Dives Akuru": range(71936, 72032), - "Nandinagari": range(72096, 72192), - "Zanabazar Square": range(72192, 72272), - "Soyombo": range(72272, 72368), - "Unified Canadian Aboriginal Syllabics Extended-A": range(72368, 72384), - "Pau Cin Hau": range(72384, 72448), - "Devanagari Extended-A": range(72448, 72544), - "Sharada Supplement": range(72544, 72576), - "Sunuwar": range(72640, 72704), - "Bhaiksuki": range(72704, 72816), - "Marchen": range(72816, 72896), - "Masaram Gondi": range(72960, 73056), - "Gunjala Gondi": range(73056, 73136), - "Tolong Siki": range(73136, 73200), - "Makasar": range(73440, 73472), - "Kawi": range(73472, 73568), - "Lisu Supplement": range(73648, 73664), - "Tamil Supplement": range(73664, 73728), - "Cuneiform": range(73728, 74752), - "Cuneiform Numbers and Punctuation": range(74752, 74880), - "Early Dynastic Cuneiform": range(74880, 75088), - "Cypro-Minoan": range(77712, 77824), - "Egyptian Hieroglyphs": range(77824, 78896), - "Egyptian Hieroglyph Format Controls": range(78896, 78944), - "Egyptian Hieroglyphs Extended-A": range(78944, 82944), - "Anatolian Hieroglyphs": range(82944, 83584), - "Gurung Khema": range(90368, 90432), - "Bamum Supplement": range(92160, 92736), - "Mro": range(92736, 92784), - "Tangsa": range(92784, 92880), - "Bassa Vah": range(92880, 92928), - "Pahawh Hmong": range(92928, 93072), - "Kirat Rai": range(93504, 93568), - "Medefaidrin": range(93760, 93856), - "Beria Erfe": range(93856, 93920), - "Miao": range(93952, 94112), - "Ideographic Symbols and Punctuation": range(94176, 94208), - "Tangut": range(94208, 100352), - "Tangut Components": range(100352, 101120), - "Khitan Small Script": range(101120, 101632), - "Tangut Supplement": range(101632, 101760), - "Tangut Components Supplement": range(101760, 101888), - "Kana Extended-B": range(110576, 110592), - "Kana Supplement": range(110592, 110848), - "Kana Extended-A": range(110848, 110896), - "Small Kana Extension": range(110896, 110960), - "Nushu": range(110960, 111360), - "Duployan": range(113664, 113824), - "Shorthand Format Controls": range(113824, 113840), - "Symbols for Legacy Computing Supplement": range(117760, 118464), - "Miscellaneous Symbols Supplement": range(118464, 118528), - "Znamenny Musical Notation": range(118528, 118736), - "Byzantine Musical Symbols": range(118784, 119040), - "Musical Symbols": range(119040, 119296), - "Ancient Greek Musical Notation": range(119296, 119376), - "Kaktovik Numerals": range(119488, 119520), - "Mayan Numerals": range(119520, 119552), - "Tai Xuan Jing Symbols": range(119552, 119648), - "Counting Rod Numerals": range(119648, 119680), - "Mathematical Alphanumeric Symbols": range(119808, 120832), - "Sutton SignWriting": range(120832, 121520), - "Latin Extended-G": range(122624, 122880), - "Glagolitic Supplement": range(122880, 122928), - "Cyrillic Extended-D": range(122928, 123024), - "Nyiakeng Puachue Hmong": range(123136, 123216), - "Toto": range(123536, 123584), - "Wancho": range(123584, 123648), - "Nag Mundari": range(124112, 124160), - "Ol Onal": range(124368, 124416), - "Tai Yo": range(124608, 124672), - "Ethiopic Extended-B": range(124896, 124928), - "Mende Kikakui": range(124928, 125152), - "Adlam": range(125184, 125280), - "Indic Siyaq Numbers": range(126064, 126144), - "Ottoman Siyaq Numbers": range(126208, 126288), - "Arabic Mathematical Alphabetic Symbols": range(126464, 126720), - "Mahjong Tiles": range(126976, 127024), - "Domino Tiles": range(127024, 127136), - "Playing Cards": range(127136, 127232), - "Enclosed Alphanumeric Supplement": range(127232, 127488), - "Enclosed Ideographic Supplement": range(127488, 127744), - "Miscellaneous Symbols and Pictographs": range(127744, 128512), - "Emoticons": range(128512, 128592), - "Ornamental Dingbats": range(128592, 128640), - "Transport and Map Symbols": range(128640, 128768), - "Alchemical Symbols": range(128768, 128896), - "Geometric Shapes Extended": range(128896, 129024), - "Supplemental Arrows-C": range(129024, 129280), - "Supplemental Symbols and Pictographs": range(129280, 129536), - "Chess Symbols": range(129536, 129648), - "Symbols and Pictographs Extended-A": range(129648, 129792), - "Symbols for Legacy Computing": range(129792, 130048), - "CJK Unified Ideographs Extension B": range(131072, 173792), - "CJK Unified Ideographs Extension C": range(173824, 177984), - "CJK Unified Ideographs Extension D": range(177984, 178208), - "CJK Unified Ideographs Extension E": range(178208, 183984), - "CJK Unified Ideographs Extension F": range(183984, 191472), - "CJK Unified Ideographs Extension I": range(191472, 192096), - "CJK Compatibility Ideographs Supplement": range(194560, 195104), - "CJK Unified Ideographs Extension G": range(196608, 201552), - "CJK Unified Ideographs Extension H": range(201552, 205744), - "CJK Unified Ideographs Extension J": range(205744, 210048), - "Tags": range(917504, 917632), - "Variation Selectors Supplement": range(917760, 918000), - "Supplementary Private Use Area-A": range(983040, 1048576), - "Supplementary Private Use Area-B": range(1048576, 1114112), -} - -# Canonical family for every Unicode range above. Keep this exhaustive and -# explicit: official block names are labels, not a grammar we should parse. -_RANGE_FAMILIES: dict[str, str] = { - "Control character": "Control character", - "Basic Latin": "Latin", - "Latin-1 Supplement": "Latin", - "Latin Extended-A": "Latin", - "Latin Extended-B": "Latin", - "IPA Extensions": "IPA", - "Spacing Modifier Letters": "Spacing Modifier Letters", - "Combining Diacritical Marks": "Combining", - "Greek and Coptic": "Greek", - "Cyrillic": "Cyrillic", - "Cyrillic Supplement": "Cyrillic", - "Armenian": "Armenian", - "Hebrew": "Hebrew", - "Arabic": "Arabic", - "Syriac": "Syriac", - "Arabic Supplement": "Arabic", - "Thaana": "Thaana", - "NKo": "NKo", - "Samaritan": "Samaritan", - "Mandaic": "Mandaic", - "Syriac Supplement": "Syriac", - "Arabic Extended-B": "Arabic", - "Arabic Extended-A": "Arabic", - "Devanagari": "Devanagari", - "Bengali": "Bengali", - "Gurmukhi": "Gurmukhi", - "Gujarati": "Gujarati", - "Oriya": "Oriya", - "Tamil": "Tamil", - "Telugu": "Telugu", - "Kannada": "Kannada", - "Malayalam": "Malayalam", - "Sinhala": "Sinhala", - "Thai": "Thai", - "Lao": "Lao", - "Tibetan": "Tibetan", - "Myanmar": "Myanmar", - "Georgian": "Georgian", - "Hangul Jamo": "Hangul", - "Ethiopic": "Ethiopic", - "Ethiopic Supplement": "Ethiopic", - "Cherokee": "Cherokee", - "Unified Canadian Aboriginal Syllabics": "Unified Canadian Aboriginal Syllabics", - "Ogham": "Ogham", - "Runic": "Runic", - "Tagalog": "Tagalog", - "Hanunoo": "Hanunoo", - "Buhid": "Buhid", - "Tagbanwa": "Tagbanwa", - "Khmer": "Khmer", - "Mongolian": "Mongolian", - "Unified Canadian Aboriginal Syllabics Extended": "Unified Canadian Aboriginal Syllabics", - "Limbu": "Limbu", - "Tai Le": "Tai Le", - "New Tai Lue": "New Tai Lue", - "Khmer Symbols": "Khmer", - "Buginese": "Buginese", - "Tai Tham": "Tai Tham", - "Combining Diacritical Marks Extended": "Combining", - "Balinese": "Balinese", - "Sundanese": "Sundanese", - "Batak": "Batak", - "Lepcha": "Lepcha", - "Ol Chiki": "Ol Chiki", - "Cyrillic Extended-C": "Cyrillic", - "Georgian Extended": "Georgian", - "Sundanese Supplement": "Sundanese", - "Vedic Extensions": "Vedic", - "Phonetic Extensions": "Phonetic", - "Phonetic Extensions Supplement": "Phonetic", - "Combining Diacritical Marks Supplement": "Combining", - "Latin Extended Additional": "Latin", - "Greek Extended": "Greek", - "General Punctuation": "Punctuation", - "Superscripts and Subscripts": "Superscripts and Subscripts", - "Currency Symbols": "Currency Symbols", - "Combining Diacritical Marks for Symbols": "Combining", - "Letterlike Symbols": "Letterlike Symbols", - "Number Forms": "Number Forms", - "Arrows": "Arrows", - "Mathematical Operators": "Mathematical", - "Miscellaneous Technical": "Miscellaneous Technical", - "Control Pictures": "Control Pictures", - "Optical Character Recognition": "Optical Character Recognition", - "Enclosed Alphanumerics": "Enclosed Alphanumerics", - "Box Drawing": "Box Drawing", - "Block Elements": "Block Elements", - "Geometric Shapes": "Geometric Shapes", - "Miscellaneous Symbols": "Miscellaneous Symbols", - "Dingbats": "Dingbats", - "Miscellaneous Mathematical Symbols-A": "Mathematical", - "Supplemental Arrows-A": "Arrows", - "Braille Patterns": "Braille", - "Supplemental Arrows-B": "Arrows", - "Miscellaneous Mathematical Symbols-B": "Mathematical", - "Supplemental Mathematical Operators": "Mathematical", - "Miscellaneous Symbols and Arrows": "Miscellaneous Symbols and Arrows", - "Glagolitic": "Glagolitic", - "Latin Extended-C": "Latin", - "Coptic": "Coptic", - "Georgian Supplement": "Georgian", - "Tifinagh": "Tifinagh", - "Ethiopic Extended": "Ethiopic", - "Cyrillic Extended-A": "Cyrillic", - "Supplemental Punctuation": "Punctuation", - "CJK Radicals Supplement": "CJK", - "Kangxi Radicals": "CJK", - "Ideographic Description Characters": "CJK", - "CJK Symbols and Punctuation": "CJK", - "Hiragana": "Hiragana", - "Katakana": "Katakana", - "Bopomofo": "Bopomofo", - "Hangul Compatibility Jamo": "Hangul", - "Kanbun": "Kanbun", - "Bopomofo Extended": "Bopomofo", - "CJK Strokes": "CJK", - "Katakana Phonetic Extensions": "Katakana", - "Enclosed CJK Letters and Months": "CJK", - "CJK Compatibility": "CJK", - "CJK Unified Ideographs Extension A": "CJK", - "Yijing Hexagram Symbols": "Yijing Hexagram Symbols", - "CJK Unified Ideographs": "CJK", - "Yi Syllables": "Yi", - "Yi Radicals": "Yi", - "Lisu": "Lisu", - "Vai": "Vai", - "Cyrillic Extended-B": "Cyrillic", - "Bamum": "Bamum", - "Modifier Tone Letters": "Phonetic", - "Latin Extended-D": "Latin", - "Syloti Nagri": "Syloti Nagri", - "Common Indic Number Forms": "Common Indic Number Forms", - "Phags-pa": "Phags-pa", - "Saurashtra": "Saurashtra", - "Devanagari Extended": "Devanagari", - "Kayah Li": "Kayah Li", - "Rejang": "Rejang", - "Hangul Jamo Extended-A": "Hangul", - "Javanese": "Javanese", - "Myanmar Extended-B": "Myanmar", - "Cham": "Cham", - "Myanmar Extended-A": "Myanmar", - "Tai Viet": "Tai Viet", - "Meetei Mayek Extensions": "Meetei Mayek", - "Ethiopic Extended-A": "Ethiopic", - "Latin Extended-E": "Latin", - "Cherokee Supplement": "Cherokee", - "Meetei Mayek": "Meetei Mayek", - "Hangul Syllables": "Hangul", - "Hangul Jamo Extended-B": "Hangul", - "High Surrogates": "Surrogates", - "High Private Use Surrogates": "Surrogates", - "Low Surrogates": "Surrogates", - "Private Use Area": "Private Use", - "CJK Compatibility Ideographs": "CJK", - "Alphabetic Presentation Forms": "Alphabetic Presentation Forms", - "Arabic Presentation Forms-A": "Arabic", - "Variation Selectors": "Variation Selectors", - "Vertical Forms": "CJK", - "Combining Half Marks": "Combining", - "CJK Compatibility Forms": "CJK", - "Small Form Variants": "CJK", - "Arabic Presentation Forms-B": "Arabic", - "Halfwidth and Fullwidth Forms": "Halfwidth and Fullwidth Forms", - "Specials": "Specials", - "Linear B Syllabary": "Linear B", - "Linear B Ideograms": "Linear B", - "Aegean Numbers": "Aegean Numbers", - "Ancient Greek Numbers": "Greek", - "Ancient Symbols": "Ancient Symbols", - "Phaistos Disc": "Phaistos Disc", - "Lycian": "Lycian", - "Carian": "Carian", - "Coptic Epact Numbers": "Coptic", - "Old Italic": "Old Italic", - "Gothic": "Gothic", - "Old Permic": "Old Permic", - "Ugaritic": "Ugaritic", - "Old Persian": "Old Persian", - "Deseret": "Deseret", - "Shavian": "Shavian", - "Osmanya": "Osmanya", - "Osage": "Osage", - "Elbasan": "Elbasan", - "Caucasian Albanian": "Caucasian Albanian", - "Vithkuqi": "Vithkuqi", - "Todhri": "Todhri", - "Linear A": "Linear A", - "Latin Extended-F": "Latin", - "Cypriot Syllabary": "Cypriot", - "Imperial Aramaic": "Imperial Aramaic", - "Palmyrene": "Palmyrene", - "Nabataean": "Nabataean", - "Hatran": "Hatran", - "Phoenician": "Phoenician", - "Lydian": "Lydian", - "Sidetic": "Sidetic", - "Meroitic Hieroglyphs": "Meroitic", - "Meroitic Cursive": "Meroitic", - "Kharoshthi": "Kharoshthi", - "Old South Arabian": "Old South Arabian", - "Old North Arabian": "Old North Arabian", - "Manichaean": "Manichaean", - "Avestan": "Avestan", - "Inscriptional Parthian": "Parthian", - "Inscriptional Pahlavi": "Pahlavi", - "Psalter Pahlavi": "Pahlavi", - "Old Turkic": "Old Turkic", - "Old Hungarian": "Old Hungarian", - "Hanifi Rohingya": "Hanifi Rohingya", - "Garay": "Garay", - "Rumi Numeral Symbols": "Arabic", - "Yezidi": "Yezidi", - "Arabic Extended-C": "Arabic", - "Old Sogdian": "Sogdian", - "Sogdian": "Sogdian", - "Old Uyghur": "Old Uyghur", - "Chorasmian": "Chorasmian", - "Elymaic": "Elymaic", - "Brahmi": "Brahmi", - "Kaithi": "Kaithi", - "Sora Sompeng": "Sora Sompeng", - "Chakma": "Chakma", - "Mahajani": "Mahajani", - "Sharada": "Sharada", - "Sinhala Archaic Numbers": "Sinhala", - "Khojki": "Khojki", - "Multani": "Multani", - "Khudawadi": "Khudawadi", - "Grantha": "Grantha", - "Tulu-Tigalari": "Tulu-Tigalari", - "Newa": "Newa", - "Tirhuta": "Tirhuta", - "Siddham": "Siddham", - "Modi": "Modi", - "Mongolian Supplement": "Mongolian", - "Takri": "Takri", - "Myanmar Extended-C": "Myanmar", - "Ahom": "Ahom", - "Dogra": "Dogra", - "Warang Citi": "Warang Citi", - "Dives Akuru": "Dives Akuru", - "Nandinagari": "Nandinagari", - "Zanabazar Square": "Zanabazar Square", - "Soyombo": "Soyombo", - "Unified Canadian Aboriginal Syllabics Extended-A": "Unified Canadian Aboriginal Syllabics", - "Pau Cin Hau": "Pau Cin Hau", - "Devanagari Extended-A": "Devanagari", - "Sharada Supplement": "Sharada", - "Sunuwar": "Sunuwar", - "Bhaiksuki": "Bhaiksuki", - "Marchen": "Marchen", - "Masaram Gondi": "Masaram Gondi", - "Gunjala Gondi": "Gunjala Gondi", - "Tolong Siki": "Tolong Siki", - "Makasar": "Makasar", - "Kawi": "Kawi", - "Lisu Supplement": "Lisu", - "Tamil Supplement": "Tamil", - "Cuneiform": "Cuneiform", - "Cuneiform Numbers and Punctuation": "Cuneiform", - "Early Dynastic Cuneiform": "Cuneiform", - "Cypro-Minoan": "Cypro-Minoan", - "Egyptian Hieroglyphs": "Egyptian Hieroglyphs", - "Egyptian Hieroglyph Format Controls": "Egyptian Hieroglyphs", - "Egyptian Hieroglyphs Extended-A": "Egyptian Hieroglyphs", - "Anatolian Hieroglyphs": "Anatolian Hieroglyphs", - "Gurung Khema": "Gurung Khema", - "Bamum Supplement": "Bamum", - "Mro": "Mro", - "Tangsa": "Tangsa", - "Bassa Vah": "Bassa Vah", - "Pahawh Hmong": "Pahawh Hmong", - "Kirat Rai": "Kirat Rai", - "Medefaidrin": "Medefaidrin", - "Beria Erfe": "Beria Erfe", - "Miao": "Miao", - "Ideographic Symbols and Punctuation": "CJK", - "Tangut": "Tangut", - "Tangut Components": "Tangut", - "Khitan Small Script": "Khitan Small Script", - "Tangut Supplement": "Tangut", - "Tangut Components Supplement": "Tangut", - "Kana Extended-B": "Kana", - "Kana Supplement": "Kana", - "Kana Extended-A": "Kana", - "Small Kana Extension": "Kana", - "Nushu": "Nushu", - "Duployan": "Duployan", - "Shorthand Format Controls": "Shorthand Format Controls", - "Symbols for Legacy Computing Supplement": "Symbols for Legacy Computing", - "Miscellaneous Symbols Supplement": "Miscellaneous Symbols", - "Znamenny Musical Notation": "Znamenny Musical Notation", - "Byzantine Musical Symbols": "Byzantine Musical Symbols", - "Musical Symbols": "Musical Symbols", - "Ancient Greek Musical Notation": "Greek", - "Kaktovik Numerals": "Kaktovik Numerals", - "Mayan Numerals": "Mayan Numerals", - "Tai Xuan Jing Symbols": "Tai Xuan Jing Symbols", - "Counting Rod Numerals": "Counting Rod Numerals", - "Mathematical Alphanumeric Symbols": "Mathematical", - "Sutton SignWriting": "Sutton SignWriting", - "Latin Extended-G": "Latin", - "Glagolitic Supplement": "Glagolitic", - "Cyrillic Extended-D": "Cyrillic", - "Nyiakeng Puachue Hmong": "Nyiakeng Puachue Hmong", - "Toto": "Toto", - "Wancho": "Wancho", - "Nag Mundari": "Nag Mundari", - "Ol Onal": "Ol Onal", - "Tai Yo": "Tai Yo", - "Ethiopic Extended-B": "Ethiopic", - "Mende Kikakui": "Mende Kikakui", - "Adlam": "Adlam", - "Indic Siyaq Numbers": "Indic Siyaq Numbers", - "Ottoman Siyaq Numbers": "Ottoman Siyaq Numbers", - "Arabic Mathematical Alphabetic Symbols": "Arabic", - "Mahjong Tiles": "Mahjong Tiles", - "Domino Tiles": "Domino Tiles", - "Playing Cards": "Playing Cards", - "Enclosed Alphanumeric Supplement": "Enclosed Alphanumerics", - "Enclosed Ideographic Supplement": "CJK", - "Miscellaneous Symbols and Pictographs": "Pictographs", - "Emoticons": "Emoticons", - "Ornamental Dingbats": "Dingbats", - "Transport and Map Symbols": "Pictographs", - "Alchemical Symbols": "Alchemical Symbols", - "Geometric Shapes Extended": "Geometric Shapes", - "Supplemental Arrows-C": "Arrows", - "Supplemental Symbols and Pictographs": "Pictographs", - "Chess Symbols": "Chess Symbols", - "Symbols and Pictographs Extended-A": "Pictographs", - "Symbols for Legacy Computing": "Symbols for Legacy Computing", - "CJK Unified Ideographs Extension B": "CJK", - "CJK Unified Ideographs Extension C": "CJK", - "CJK Unified Ideographs Extension D": "CJK", - "CJK Unified Ideographs Extension E": "CJK", - "CJK Unified Ideographs Extension F": "CJK", - "CJK Unified Ideographs Extension I": "CJK", - "CJK Compatibility Ideographs Supplement": "CJK", - "CJK Unified Ideographs Extension G": "CJK", - "CJK Unified Ideographs Extension H": "CJK", - "CJK Unified Ideographs Extension J": "CJK", - "Tags": "Tags", - "Variation Selectors Supplement": "Variation Selectors", - "Supplementary Private Use Area-A": "Private Use", - "Supplementary Private Use Area-B": "Private Use", -} - - -class CompatibleFamillyRange: - __slots__ = ("_families",) - - def __init__(self, familly_a: str, familly_b: str) -> None: - self._families: frozenset[str] = frozenset((familly_a, familly_b)) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, CompatibleFamillyRange): - return NotImplemented - - return self._families == other._families - - def __hash__(self) -> int: - return hash(self._families) - - -_COMPATIBLE_RANGE_FAMILIES: frozenset[CompatibleFamillyRange] = frozenset( - { - CompatibleFamillyRange("CJK", "Hiragana"), - CompatibleFamillyRange("CJK", "Katakana"), - CompatibleFamillyRange("CJK", "Kana"), - CompatibleFamillyRange("CJK", "Bopomofo"), - CompatibleFamillyRange("CJK", "Kanbun"), - CompatibleFamillyRange("Hiragana", "Katakana"), - CompatibleFamillyRange("Hiragana", "Kana"), - CompatibleFamillyRange("Katakana", "Kana"), - CompatibleFamillyRange("CJK", "Hangul"), - CompatibleFamillyRange("Latin", "IPA"), - CompatibleFamillyRange("Latin", "Phonetic"), - CompatibleFamillyRange("IPA", "Phonetic"), - CompatibleFamillyRange("Latin", "Spacing Modifier Letters"), - CompatibleFamillyRange("IPA", "Spacing Modifier Letters"), - CompatibleFamillyRange("Phonetic", "Spacing Modifier Letters"), - CompatibleFamillyRange("Alphabetic Presentation Forms", "Latin"), - CompatibleFamillyRange("Alphabetic Presentation Forms", "Armenian"), - CompatibleFamillyRange("Alphabetic Presentation Forms", "Hebrew"), - CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Latin"), - CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "CJK"), - CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Hiragana"), - CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Katakana"), - CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Kana"), - CompatibleFamillyRange("Halfwidth and Fullwidth Forms", "Hangul"), - } -) - -_COMPATIBLE_WITH_ANY_RANGE_FAMILIES: frozenset[str] = frozenset( - {"Combining", "Variation Selectors", "Emoticons", "Pictographs"} -) - -_BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES: frozenset[str] = frozenset( - {"CJK", "Hangul", "Hiragana", "Katakana", "Kana", "Bopomofo", "Kanbun"} -) - - -UNICODE_SECONDARY_RANGE_KEYWORD: list[str] = [ - "Supplement", - "Extended", - "Extensions", - "Modifier", - "Marks", - "Punctuation", - "Symbols", - "Forms", - "Operators", - "Miscellaneous", - "Drawing", - "Block", - "Shapes", - "Supplemental", - "Tags", -] - -RE_POSSIBLE_ENCODING_INDICATION = re_compile( - r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", - IGNORECASE, -) - -IANA_NO_ALIASES = [ - "cp720", - "cp737", - "cp856", - "cp874", - "cp875", - "cp1006", - "koi8_r", - "koi8_t", - "koi8_u", -] - -IANA_SUPPORTED: list[str] = sorted( - filter( - lambda x: not x.endswith("_codec") and x not in {"rot_13", "tactis", "mbcs"}, - list(set(aliases.values())) + IANA_NO_ALIASES, - ) -) - -IANA_SUPPORTED_COUNT: int = len(IANA_SUPPORTED) - -# pre-computed code page that are similar using the function cp_similarity. -IANA_SUPPORTED_SIMILAR: dict[str, list[str]] = { - "cp037": ["cp1026", "cp1140", "cp273", "cp500"], - "cp1026": ["cp037", "cp1140", "cp273", "cp500"], - "cp1125": ["cp866"], - "cp1140": ["cp037", "cp1026", "cp273", "cp500"], - "cp1250": ["iso8859_2"], - "cp1251": ["kz1048", "ptcp154"], - "cp1252": ["iso8859_15", "iso8859_9", "latin_1"], - "cp1253": ["iso8859_7"], - "cp1254": ["iso8859_15", "iso8859_9", "latin_1"], - "cp1257": ["iso8859_13"], - "cp273": ["cp037", "cp1026", "cp1140", "cp500"], - "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"], - "cp500": ["cp037", "cp1026", "cp1140", "cp273"], - "cp850": ["cp437", "cp857", "cp858", "cp865"], - "cp857": ["cp850", "cp858", "cp865"], - "cp858": ["cp437", "cp850", "cp857", "cp865"], - "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"], - "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"], - "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"], - "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"], - "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"], - "cp866": ["cp1125"], - "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"], - "iso8859_11": ["tis_620"], - "iso8859_13": ["cp1257"], - "iso8859_14": [ - "iso8859_10", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_9", - "latin_1", - ], - "iso8859_15": [ - "cp1252", - "cp1254", - "iso8859_10", - "iso8859_14", - "iso8859_16", - "iso8859_3", - "iso8859_9", - "latin_1", - ], - "iso8859_16": [ - "iso8859_14", - "iso8859_15", - "iso8859_2", - "iso8859_3", - "iso8859_9", - "latin_1", - ], - "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"], - "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"], - "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"], - "iso8859_7": ["cp1253"], - "iso8859_9": [ - "cp1252", - "cp1254", - "cp1258", - "iso8859_10", - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_4", - "latin_1", - ], - "kz1048": ["cp1251", "ptcp154"], - "latin_1": [ - "cp1252", - "cp1254", - "cp1258", - "iso8859_10", - "iso8859_14", - "iso8859_15", - "iso8859_16", - "iso8859_3", - "iso8859_4", - "iso8859_9", - ], - "mac_iceland": ["mac_roman", "mac_turkish"], - "mac_roman": ["mac_iceland", "mac_turkish"], - "mac_turkish": ["mac_iceland", "mac_roman"], - "ptcp154": ["cp1251", "kz1048"], - "tis_620": ["iso8859_11"], -} - - -CHARDET_CORRESPONDENCE: dict[str, str] = { - "iso2022_kr": "ISO-2022-KR", - "iso2022_jp": "ISO-2022-JP", - "euc_kr": "EUC-KR", - "tis_620": "TIS-620", - "utf_32": "UTF-32", - "euc_jp": "EUC-JP", - "koi8_r": "KOI8-R", - "iso8859_1": "ISO-8859-1", - "iso8859_2": "ISO-8859-2", - "iso8859_5": "ISO-8859-5", - "iso8859_6": "ISO-8859-6", - "iso8859_7": "ISO-8859-7", - "iso8859_8": "ISO-8859-8", - "utf_16": "UTF-16", - "cp855": "IBM855", - "mac_cyrillic": "MacCyrillic", - "gb2312": "GB2312", - "gb18030": "GB18030", - "cp932": "CP932", - "cp866": "IBM866", - "utf_8": "utf-8", - "utf_8_sig": "UTF-8-SIG", - "shift_jis": "SHIFT_JIS", - "big5": "Big5", - "cp1250": "windows-1250", - "cp1251": "windows-1251", - "cp1252": "Windows-1252", - "cp1253": "windows-1253", - "cp1255": "windows-1255", - "cp1256": "windows-1256", - "cp1254": "Windows-1254", - "cp949": "CP949", -} - - -COMMON_SAFE_ASCII_CHARACTERS: frozenset[str] = frozenset( - { - "<", - ">", - "=", - ":", - "/", - "&", - ";", - "{", - "}", - "[", - "]", - ",", - "|", - '"', - "-", - "(", - ")", - } -) - -# Sample character sets — replace with full lists if needed -COMMON_CHINESE_CHARACTERS = "的一是在不了有和人这中大为上个国我以要他时来用们生到作地于出就分对成会可主发年动同工也能下过子说产种面而方后多定行学法所民得经十三之进着等部度家电力里如水化高自二理起小物现实加量都两体制机当使点从业本去把性好应开它合还因由其些然前外天政四日那社义事平形相全表间样与关各重新线内数正心反你明看原又么利比或但质气第向道命此变条只没结解问意建月公无系军很情者最立代想已通并提直题党程展五果料象员革位入常文总次品式活设及管特件长求老头基资边流路级少图山统接知较将组见计别她手角期根论运农指几九区强放决西被干做必战先回则任取据处队南给色光门即保治北造百规热领七海口东导器压志世金增争济阶油思术极交受联什认六共权收证改清己美再采转更单风切打白教速花带安场身车例真务具万每目至达走积示议声报斗完类八离华名确才科张信马节话米整空元况今集温传土许步群广石记需段研界拉林律叫且究观越织装影算低持音众书布复容儿须际商非验连断深难近矿千周委素技备半办青省列习响约支般史感劳便团往酸历市克何除消构府太准精值号率族维划选标写存候毛亲快效斯院查江型眼王按格养易置派层片始却专状育厂京识适属圆包火住调满县局照参红细引听该铁价严龙飞" - -COMMON_JAPANESE_CHARACTERS = "日一国年大十二本中長出三時行見月分後前生五間上東四今金九入学高円子外八六下来気小七山話女北午百書先名川千水半男西電校語土木聞食車何南万毎白天母火右読友左休父雨" - -COMMON_KOREAN_CHARACTERS = "一二三四五六七八九十百千萬上下左右中人女子大小山川日月火水木金土父母天地國名年時文校學生" - -# Combine all into a frozenset -COMMON_CJK_CHARACTERS = frozenset( - "".join( - [ - COMMON_CHINESE_CHARACTERS, - COMMON_JAPANESE_CHARACTERS, - COMMON_KOREAN_CHARACTERS, - ] - ) -) - -KO_NAMES: frozenset[str] = frozenset({"johab", "cp949", "euc_kr"}) -ZH_NAMES: frozenset[str] = frozenset({"big5", "cp950", "big5hkscs", "hz"}) - -# Logging LEVEL below DEBUG -TRACE: int = 5 - - -# Language label that contain the em dash "—" -# character are to be considered alternative seq to origin -FREQUENCIES: dict[str, list[str]] = { - "English": [ - "e", - "a", - "t", - "i", - "o", - "n", - "s", - "r", - "h", - "l", - "d", - "c", - "u", - "m", - "f", - "p", - "g", - "w", - "y", - "b", - "v", - "k", - "x", - "j", - "z", - "q", - ], - "English—": [ - "e", - "a", - "t", - "i", - "o", - "n", - "s", - "r", - "h", - "l", - "d", - "c", - "m", - "u", - "f", - "p", - "g", - "w", - "b", - "y", - "v", - "k", - "j", - "x", - "z", - "q", - ], - "German": [ - "e", - "n", - "i", - "r", - "s", - "t", - "a", - "d", - "h", - "u", - "l", - "g", - "o", - "c", - "m", - "b", - "f", - "k", - "w", - "z", - "p", - "v", - "ü", - "ä", - "ö", - "j", - ], - "French": [ - "e", - "a", - "s", - "n", - "i", - "t", - "r", - "l", - "u", - "o", - "d", - "c", - "p", - "m", - "é", - "v", - "g", - "f", - "b", - "h", - "q", - "à", - "x", - "è", - "y", - "j", - ], - "Dutch": [ - "e", - "n", - "a", - "i", - "r", - "t", - "o", - "d", - "s", - "l", - "g", - "h", - "v", - "m", - "u", - "k", - "c", - "p", - "b", - "w", - "j", - "z", - "f", - "y", - "x", - "ë", - ], - "Italian": [ - "e", - "i", - "a", - "o", - "n", - "l", - "t", - "r", - "s", - "c", - "d", - "u", - "p", - "m", - "g", - "v", - "f", - "b", - "z", - "h", - "q", - "è", - "à", - "k", - "y", - "ò", - ], - "Polish": [ - "a", - "i", - "o", - "e", - "n", - "r", - "z", - "w", - "s", - "c", - "t", - "k", - "y", - "d", - "p", - "m", - "u", - "l", - "j", - "ł", - "g", - "b", - "h", - "ą", - "ę", - "ó", - ], - "Spanish": [ - "e", - "a", - "o", - "n", - "s", - "r", - "i", - "l", - "d", - "t", - "c", - "u", - "m", - "p", - "b", - "g", - "v", - "f", - "y", - "ó", - "h", - "q", - "í", - "j", - "z", - "á", - ], - "Russian": [ - "о", - "е", - "а", - "и", - "н", - "т", - "с", - "р", - "в", - "л", - "к", - "м", - "д", - "п", - "у", - "г", - "я", - "ы", - "з", - "б", - "й", - "ь", - "ч", - "х", - "ж", - "ц", - ], - # Jap-Kanji - "Japanese": [ - "日", - "一", - "人", - "年", - "大", - "十", - "二", - "本", - "中", - "長", - "出", - "三", - "時", - "行", - "見", - "月", - "分", - "後", - "前", - "生", - "五", - "間", - "上", - "東", - "四", - "今", - "金", - "九", - "入", - "学", - "高", - "円", - "子", - "外", - "八", - "六", - "下", - "来", - "気", - "小", - "七", - "山", - "話", - "女", - "北", - "午", - "百", - "書", - "先", - "名", - "川", - "千", - "水", - "半", - "男", - "西", - "電", - "校", - "語", - "土", - "木", - "聞", - "食", - "車", - "何", - "南", - "万", - "毎", - "白", - "天", - "母", - "火", - "右", - "読", - "友", - "左", - "休", - "父", - "雨", - ], - # Jap-Katakana - "Japanese—": [ - "ー", - "ン", - "ス", - "・", - "ル", - "ト", - "リ", - "イ", - "ア", - "ラ", - "ッ", - "ク", - "ド", - "シ", - "レ", - "ジ", - "タ", - "フ", - "ロ", - "カ", - "テ", - "マ", - "ィ", - "グ", - "バ", - "ム", - "プ", - "オ", - "コ", - "デ", - "ニ", - "ウ", - "メ", - "サ", - "ビ", - "ナ", - "ブ", - "ャ", - "エ", - "ュ", - "チ", - "キ", - "ズ", - "ダ", - "パ", - "ミ", - "ェ", - "ョ", - "ハ", - "セ", - "ベ", - "ガ", - "モ", - "ツ", - "ネ", - "ボ", - "ソ", - "ノ", - "ァ", - "ヴ", - "ワ", - "ポ", - "ペ", - "ピ", - "ケ", - "ゴ", - "ギ", - "ザ", - "ホ", - "ゲ", - "ォ", - "ヤ", - "ヒ", - "ユ", - "ヨ", - "ヘ", - "ゼ", - "ヌ", - "ゥ", - "ゾ", - "ヶ", - "ヂ", - "ヲ", - "ヅ", - "ヵ", - "ヱ", - "ヰ", - "ヮ", - "ヽ", - "゠", - "ヾ", - "ヷ", - "ヿ", - "ヸ", - "ヹ", - "ヺ", - ], - # Jap-Hiragana - "Japanese——": [ - "の", - "に", - "る", - "た", - "と", - "は", - "し", - "い", - "を", - "で", - "て", - "が", - "な", - "れ", - "か", - "ら", - "さ", - "っ", - "り", - "す", - "あ", - "も", - "こ", - "ま", - "う", - "く", - "よ", - "き", - "ん", - "め", - "お", - "け", - "そ", - "つ", - "だ", - "や", - "え", - "ど", - "わ", - "ち", - "み", - "せ", - "じ", - "ば", - "へ", - "び", - "ず", - "ろ", - "ほ", - "げ", - "む", - "べ", - "ひ", - "ょ", - "ゆ", - "ぶ", - "ご", - "ゃ", - "ね", - "ふ", - "ぐ", - "ぎ", - "ぼ", - "ゅ", - "づ", - "ざ", - "ぞ", - "ぬ", - "ぜ", - "ぱ", - "ぽ", - "ぷ", - "ぴ", - "ぃ", - "ぁ", - "ぇ", - "ぺ", - "ゞ", - "ぢ", - "ぉ", - "ぅ", - "ゐ", - "ゝ", - "ゑ", - "゛", - "゜", - "ゎ", - "ゔ", - "゚", - "ゟ", - "゙", - "ゕ", - "ゖ", - ], - "Portuguese": [ - "a", - "e", - "o", - "s", - "i", - "r", - "d", - "n", - "t", - "m", - "u", - "c", - "l", - "p", - "g", - "v", - "b", - "f", - "h", - "ã", - "q", - "é", - "ç", - "á", - "z", - "í", - ], - "Swedish": [ - "e", - "a", - "n", - "r", - "t", - "s", - "i", - "l", - "d", - "o", - "m", - "k", - "g", - "v", - "h", - "f", - "u", - "p", - "ä", - "c", - "b", - "ö", - "å", - "y", - "j", - "x", - ], - "Chinese": [ - "的", - "一", - "是", - "不", - "了", - "在", - "人", - "有", - "我", - "他", - "这", - "个", - "们", - "中", - "来", - "上", - "大", - "为", - "和", - "国", - "地", - "到", - "以", - "说", - "时", - "要", - "就", - "出", - "会", - "可", - "也", - "你", - "对", - "生", - "能", - "而", - "子", - "那", - "得", - "于", - "着", - "下", - "自", - "之", - "年", - "过", - "发", - "后", - "作", - "里", - "用", - "道", - "行", - "所", - "然", - "家", - "种", - "事", - "成", - "方", - "多", - "经", - "么", - "去", - "法", - "学", - "如", - "都", - "同", - "现", - "当", - "没", - "动", - "面", - "起", - "看", - "定", - "天", - "分", - "还", - "进", - "好", - "小", - "部", - "其", - "些", - "主", - "样", - "理", - "心", - "她", - "本", - "前", - "开", - "但", - "因", - "只", - "从", - "想", - "实", - ], - "Ukrainian": [ - "о", - "а", - "н", - "і", - "и", - "р", - "в", - "т", - "е", - "с", - "к", - "л", - "у", - "д", - "м", - "п", - "з", - "я", - "ь", - "б", - "г", - "й", - "ч", - "х", - "ц", - "ї", - ], - "Norwegian": [ - "e", - "r", - "n", - "t", - "a", - "s", - "i", - "o", - "l", - "d", - "g", - "k", - "m", - "v", - "f", - "p", - "u", - "b", - "h", - "å", - "y", - "j", - "ø", - "c", - "æ", - "w", - ], - "Finnish": [ - "a", - "i", - "n", - "t", - "e", - "s", - "l", - "o", - "u", - "k", - "ä", - "m", - "r", - "v", - "j", - "h", - "p", - "y", - "d", - "ö", - "g", - "c", - "b", - "f", - "w", - "z", - ], - "Vietnamese": [ - "n", - "h", - "t", - "i", - "c", - "g", - "a", - "o", - "u", - "m", - "l", - "r", - "à", - "đ", - "s", - "e", - "v", - "p", - "b", - "y", - "ư", - "d", - "á", - "k", - "ộ", - "ế", - ], - "Czech": [ - "o", - "e", - "a", - "n", - "t", - "s", - "i", - "l", - "v", - "r", - "k", - "d", - "u", - "m", - "p", - "í", - "c", - "h", - "z", - "á", - "y", - "j", - "b", - "ě", - "é", - "ř", - ], - "Hungarian": [ - "e", - "a", - "t", - "l", - "s", - "n", - "k", - "r", - "i", - "o", - "z", - "á", - "é", - "g", - "m", - "b", - "y", - "v", - "d", - "h", - "u", - "p", - "j", - "ö", - "f", - "c", - ], - "Korean": [ - "이", - "다", - "에", - "의", - "는", - "로", - "하", - "을", - "가", - "고", - "지", - "서", - "한", - "은", - "기", - "으", - "년", - "대", - "사", - "시", - "를", - "리", - "도", - "인", - "스", - "일", - ], - "Indonesian": [ - "a", - "n", - "e", - "i", - "r", - "t", - "u", - "s", - "d", - "k", - "m", - "l", - "g", - "p", - "b", - "o", - "h", - "y", - "j", - "c", - "w", - "f", - "v", - "z", - "x", - "q", - ], - "Turkish": [ - "a", - "e", - "i", - "n", - "r", - "l", - "ı", - "k", - "d", - "t", - "s", - "m", - "y", - "u", - "o", - "b", - "ü", - "ş", - "v", - "g", - "z", - "h", - "c", - "p", - "ç", - "ğ", - ], - "Romanian": [ - "e", - "i", - "a", - "r", - "n", - "t", - "u", - "l", - "o", - "c", - "s", - "d", - "p", - "m", - "ă", - "f", - "v", - "î", - "g", - "b", - "ș", - "ț", - "z", - "h", - "â", - "j", - ], - "Farsi": [ - "ا", - "ی", - "ر", - "د", - "ن", - "ه", - "و", - "م", - "ت", - "ب", - "س", - "ل", - "ک", - "ش", - "ز", - "ف", - "گ", - "ع", - "خ", - "ق", - "ج", - "آ", - "پ", - "ح", - "ط", - "ص", - ], - "Arabic": [ - "ا", - "ل", - "ي", - "م", - "و", - "ن", - "ر", - "ت", - "ب", - "ة", - "ع", - "د", - "س", - "ف", - "ه", - "ك", - "ق", - "أ", - "ح", - "ج", - "ش", - "ط", - "ص", - "ى", - "خ", - "إ", - ], - "Danish": [ - "e", - "r", - "n", - "t", - "a", - "i", - "s", - "d", - "l", - "o", - "g", - "m", - "k", - "f", - "v", - "u", - "b", - "h", - "p", - "å", - "y", - "ø", - "æ", - "c", - "j", - "w", - ], - "Serbian": [ - "а", - "и", - "о", - "е", - "н", - "р", - "с", - "у", - "т", - "к", - "ј", - "в", - "д", - "м", - "п", - "л", - "г", - "з", - "б", - "a", - "i", - "e", - "o", - "n", - "ц", - "ш", - ], - "Lithuanian": [ - "i", - "a", - "s", - "o", - "r", - "e", - "t", - "n", - "u", - "k", - "m", - "l", - "p", - "v", - "d", - "j", - "g", - "ė", - "b", - "y", - "ų", - "š", - "ž", - "c", - "ą", - "į", - ], - "Slovene": [ - "e", - "a", - "i", - "o", - "n", - "r", - "s", - "l", - "t", - "j", - "v", - "k", - "d", - "p", - "m", - "u", - "z", - "b", - "g", - "h", - "č", - "c", - "š", - "ž", - "f", - "y", - ], - "Slovak": [ - "o", - "a", - "e", - "n", - "i", - "r", - "v", - "t", - "s", - "l", - "k", - "d", - "m", - "p", - "u", - "c", - "h", - "j", - "b", - "z", - "á", - "y", - "ý", - "í", - "č", - "é", - ], - "Hebrew": [ - "י", - "ו", - "ה", - "ל", - "ר", - "ב", - "ת", - "מ", - "א", - "ש", - "נ", - "ע", - "ם", - "ד", - "ק", - "ח", - "פ", - "ס", - "כ", - "ג", - "ט", - "צ", - "ן", - "ז", - "ך", - ], - "Bulgarian": [ - "а", - "и", - "о", - "е", - "н", - "т", - "р", - "с", - "в", - "л", - "к", - "д", - "п", - "м", - "з", - "г", - "я", - "ъ", - "у", - "б", - "ч", - "ц", - "й", - "ж", - "щ", - "х", - ], - "Croatian": [ - "a", - "i", - "o", - "e", - "n", - "r", - "j", - "s", - "t", - "u", - "k", - "l", - "v", - "d", - "m", - "p", - "g", - "z", - "b", - "c", - "č", - "h", - "š", - "ž", - "ć", - "f", - ], - "Hindi": [ - "क", - "र", - "स", - "न", - "त", - "म", - "ह", - "प", - "य", - "ल", - "व", - "ज", - "द", - "ग", - "ब", - "श", - "ट", - "अ", - "ए", - "थ", - "भ", - "ड", - "च", - "ध", - "ष", - "इ", - ], - "Estonian": [ - "a", - "i", - "e", - "s", - "t", - "l", - "u", - "n", - "o", - "k", - "r", - "d", - "m", - "v", - "g", - "p", - "j", - "h", - "ä", - "b", - "õ", - "ü", - "f", - "c", - "ö", - "y", - ], - "Thai": [ - "า", - "น", - "ร", - "อ", - "ก", - "เ", - "ง", - "ม", - "ย", - "ล", - "ว", - "ด", - "ท", - "ส", - "ต", - "ะ", - "ป", - "บ", - "ค", - "ห", - "แ", - "จ", - "พ", - "ช", - "ข", - "ใ", - ], - "Greek": [ - "α", - "τ", - "ο", - "ι", - "ε", - "ν", - "ρ", - "σ", - "κ", - "η", - "π", - "ς", - "υ", - "μ", - "λ", - "ί", - "ό", - "ά", - "γ", - "έ", - "δ", - "ή", - "ω", - "χ", - "θ", - "ύ", - ], - "Tamil": [ - "க", - "த", - "ப", - "ட", - "ர", - "ம", - "ல", - "ன", - "வ", - "ற", - "ய", - "ள", - "ச", - "ந", - "இ", - "ண", - "அ", - "ஆ", - "ழ", - "ங", - "எ", - "உ", - "ஒ", - "ஸ", - ], - "Kazakh": [ - "а", - "ы", - "е", - "н", - "т", - "р", - "л", - "і", - "д", - "с", - "м", - "қ", - "к", - "о", - "б", - "и", - "у", - "ғ", - "ж", - "ң", - "з", - "ш", - "й", - "п", - "г", - "ө", - ], -} - -LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES) - -# Bit flags for unified character classification. -# A single unicodedata.name() call sets all relevant flags at once. -_LATIN: int = 1 -_ACCENTUATED: int = 1 << 1 -_CJK: int = 1 << 2 -_HANGUL: int = 1 << 3 -_KATAKANA: int = 1 << 4 -_HIRAGANA: int = 1 << 5 -_THAI: int = 1 << 6 -_ARABIC: int = 1 << 7 -_ARABIC_ISOLATED_FORM: int = 1 << 8 -_HALFWIDTH_KATAKANA: int = 1 << 9 -_LIGATURE: int = 1 << 10 -_SUPERSCRIPT: int = 1 << 11 -_SENTENCE_OPEN_PUNCTUATION: int = 1 << 12 - -_ACCENT_KEYWORDS: tuple[str, ...] = ( - "WITH GRAVE", - "WITH ACUTE", - "WITH CEDILLA", - "WITH DIAERESIS", - "WITH CIRCUMFLEX", - "WITH TILDE", - "WITH MACRON", - "WITH RING ABOVE", -) - -# Pre-built lookup structures for FREQUENCIES (computed once at import time). -# character -> rank mapping per language (replaces list .index() calls). -_FREQUENCIES_RANK: dict[str, dict[str, int]] = { - lang: {char: rank for rank, char in enumerate(chars)} - for lang, chars in FREQUENCIES.items() -} - -# frozenset per language (avoids rebuilding set() per call). -_FREQUENCIES_SET: dict[str, frozenset[str]] = { - lang: frozenset(chars) for lang, chars in FREQUENCIES.items() -} - -# prebuilt list of secondary range names. -_SECONDARY_RANGE_NAMES: frozenset[str] = frozenset( - range_name - for range_name in UNICODE_RANGES_COMBINED - if any(keyword in range_name for keyword in UNICODE_SECONDARY_RANGE_KEYWORD) -) - -_KNOWN_MB_DECODERS: frozenset[str] = frozenset( - { - "utf_8", - "utf_8_sig", - "utf_16", - "utf_16_be", - "utf_16_le", - "utf_32", - "utf_32_le", - "utf_32_be", - "utf_7", - } -) - -_KNOWN_MB_CLASSES: frozenset[str] = frozenset( - { - "_codecs_cn", - "_codecs_hk", - "_codecs_iso2022", - "_codecs_jp", - "_codecs_kr", - "_codecs_tw", - } -) - -_IANA_NAMES: dict[str, str] = { - **aliases, - **{iana_name: iana_name for iana_name in aliases.values()}, - **{iana_name: iana_name for iana_name in IANA_NO_ALIASES}, -} -_MULTIBYTE_SEARCH_RADIUS: int = 32768 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py deleted file mode 100644 index 4f17e8577f3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/legacy.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING, Any -from warnings import warn - -from .api import from_bytes -from .constant import CHARDET_CORRESPONDENCE, TOO_SMALL_SEQUENCE - -if TYPE_CHECKING: - from typing import TypedDict - - class ResultDict(TypedDict): - encoding: str | None - language: str - confidence: float | None - - -def detect( - byte_str: bytes, should_rename_legacy: bool = False, **kwargs: Any -) -> ResultDict: - """ - chardet legacy method - Detect the encoding of the given byte string. It should be mostly backward-compatible. - Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it) - This function is deprecated and should be used to migrate your project easily, consult the documentation for - further information. Not planned for removal. - - :param byte_str: The byte sequence to examine. - :param should_rename_legacy: Should we rename legacy encodings - to their more modern equivalents? - """ - if len(kwargs): - warn( - f"charset-normalizer disregard arguments '{','.join(list(kwargs.keys()))}' in legacy function detect()" - ) - - if not isinstance(byte_str, (bytearray, bytes)): - raise TypeError( # pragma: nocover - f"Expected object of type bytes or bytearray, got: {type(byte_str)}" - ) - - if isinstance(byte_str, bytearray): - byte_str = bytes(byte_str) - - r = from_bytes(byte_str).best() - - encoding = r.encoding if r is not None else None - language = r.language if r is not None and r.language != "Unknown" else "" - confidence = 1.0 - r.chaos if r is not None else None - - # automatically lower confidence - # on small bytes samples. - # https://github.com/jawah/charset_normalizer/issues/391 - if ( - confidence is not None - and confidence >= 0.9 - and encoding - not in { - "utf_8", - "ascii", - } - and not r.bom # type: ignore[union-attr] - and len(byte_str) < TOO_SMALL_SEQUENCE - ): - confidence -= 0.2 - - # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process - # but chardet does return 'utf-8-sig' and it is a valid codec name. - if r is not None and encoding == "utf_8" and r.bom: - encoding += "_sig" - - if not should_rename_legacy and encoding in CHARDET_CORRESPONDENCE: - encoding = CHARDET_CORRESPONDENCE[encoding] - - return { - "encoding": encoding, - "language": language, - "confidence": confidence, - } diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py deleted file mode 100644 index 6bd214f51d8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/md.py +++ /dev/null @@ -1,1065 +0,0 @@ -from __future__ import annotations - -from functools import lru_cache -from logging import getLogger - - -from .constant import ( - COMMON_CJK_CHARACTERS, - COMMON_SAFE_ASCII_CHARACTERS, - TRACE, - CompatibleFamillyRange, - _ACCENTUATED, - _ARABIC, - _ARABIC_ISOLATED_FORM, - _BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES, - _CJK, - _COMPATIBLE_RANGE_FAMILIES, - _COMPATIBLE_WITH_ANY_RANGE_FAMILIES, - _HANGUL, - _HALFWIDTH_KATAKANA, - _HIRAGANA, - _KATAKANA, - _LATIN, - _LIGATURE, - _RANGE_FAMILIES, - _SENTENCE_OPEN_PUNCTUATION, - _SUPERSCRIPT, - _THAI, -) -from .utils import ( - _character_flags, - is_emoticon, - is_punctuation, - is_separator, - is_symbol, - remove_accent, - unicode_range, -) - -# Combined bitmask for CJK/Hangul/Katakana/Hiragana/Thai glyph detection. -_GLYPH_MASK: int = _CJK | _HANGUL | _KATAKANA | _HIRAGANA | _THAI - - -class CharInfo: - """Pre-computed character properties shared across all detectors.""" - - __slots__ = ( - "character", - "printable", - "alpha", - "upper", - "lower", - "space", - "digit", - "is_ascii", - "case_variable", - "flags", - "accentuated", - "latin", - "is_cjk", - "is_katakana", - "is_halfwidth_katakana", - "is_arabic", - "is_ligature", - "is_superscript", - "is_sentence_open_punctuation", - "is_glyph", - "punct", - "sym", - "range", - "sep", - "emoticon", - "safe", - "common_cjk", - "unaccented", - ) - - character: str - printable: bool - alpha: bool - upper: bool - lower: bool - space: bool - digit: bool - is_ascii: bool - case_variable: bool - flags: int - accentuated: bool - latin: bool - is_cjk: bool - is_katakana: bool - is_halfwidth_katakana: bool - is_arabic: bool - is_ligature: bool - is_superscript: bool - is_sentence_open_punctuation: bool - is_glyph: bool - punct: bool - sym: bool - range: str | None - sep: bool - emoticon: bool - safe: bool - common_cjk: bool - unaccented: str - - def __init__(self, character: str) -> None: - """Compute all properties for *character* (built once per codepoint, - every branch assigns every slot).""" - self.character = character - - # ASCII fast-path: for characters with ord < 128, we can skip - # _character_flags() entirely and derive most properties from ord. - o: int = ord(character) - if o < 128: - self.is_ascii = True - self.accentuated = False - self.unaccented = character - self.emoticon = False - self.common_cjk = False - self.safe = character in COMMON_SAFE_ASCII_CHARACTERS - self.is_cjk = False - self.is_katakana = False - self.is_halfwidth_katakana = False - self.is_arabic = False - self.is_ligature = False - self.is_superscript = False - self.is_sentence_open_punctuation = False - self.is_glyph = False - # ASCII alpha: a-z (97-122) or A-Z (65-90) - if 65 <= o <= 90: - # Uppercase ASCII letter - self.alpha = True - self.upper = True - self.lower = False - self.space = False - self.digit = False - self.printable = True - self.case_variable = True - self.flags = _LATIN - self.latin = True - self.punct = False - self.sym = False - elif 97 <= o <= 122: - # Lowercase ASCII letter - self.alpha = True - self.upper = False - self.lower = True - self.space = False - self.digit = False - self.printable = True - self.case_variable = True - self.flags = _LATIN - self.latin = True - self.punct = False - self.sym = False - elif 48 <= o <= 57: - # ASCII digit 0-9 - self.alpha = False - self.upper = False - self.lower = False - self.space = False - self.digit = True - self.printable = True - self.case_variable = False - self.flags = 0 - self.latin = False - self.punct = False - self.sym = False - elif o == 32 or (9 <= o <= 13): - # Space, tab, newline, etc. - self.alpha = False - self.upper = False - self.lower = False - self.space = True - self.digit = False - self.printable = o == 32 - self.case_variable = False - self.flags = 0 - self.latin = False - self.punct = False - self.sym = False - else: - # Other ASCII (punctuation, symbols, control chars) - self.printable = character.isprintable() - self.alpha = False - self.upper = False - self.lower = False - self.space = False - self.digit = False - self.case_variable = False - self.flags = 0 - self.latin = False - self.punct = is_punctuation(character) if self.printable else False - self.sym = is_symbol(character) if self.printable else False - else: - # Non-ASCII path - self.is_ascii = False - self.safe = False - self.printable = character.isprintable() - self.alpha = character.isalpha() - self.upper = character.isupper() - self.lower = character.islower() - self.space = character.isspace() - self.digit = character.isdigit() - self.case_variable = self.lower != self.upper - - # Flag-based classification (single unicodedata.name() call, lru-cached) - flags: int = _character_flags(character) - if self.alpha: - self.emoticon = False - else: - self.emoticon = is_emoticon(character) - self.flags = flags - self.accentuated = bool(flags & _ACCENTUATED) - self.latin = bool(flags & _LATIN) - self.is_cjk = bool(flags & _CJK) - self.is_katakana = bool(flags & _KATAKANA) - self.is_halfwidth_katakana = bool(flags & _HALFWIDTH_KATAKANA) - self.is_arabic = bool(flags & _ARABIC) - self.is_ligature = bool(flags & _LIGATURE) - self.is_superscript = bool(flags & _SUPERSCRIPT) - self.is_sentence_open_punctuation = bool(flags & _SENTENCE_OPEN_PUNCTUATION) - self.is_glyph = bool(flags & _GLYPH_MASK) - - if self.latin and self.accentuated: - self.unaccented = remove_accent(character) - else: - self.unaccented = character - - self.common_cjk = self.is_cjk and character in COMMON_CJK_CHARACTERS - - # Eagerly compute punct and sym (avoids property dispatch overhead - # on 300K+ accesses in the hot loop). - if self.printable: - self.punct = is_punctuation(character) - self.sym = is_symbol(character) - else: - self.punct = False - self.sym = False - - self.range = unicode_range(character) - self.sep = is_separator(character) - - -# Per-codepoint cache of CharInfo instances -# At most UTF-8 size allocated. -@lru_cache(maxsize=None) -def _char_info(character: str) -> CharInfo: - """Build (once per codepoint) and cache the CharInfo for *character*.""" - return CharInfo(character) - - -# ASCII table indexed by codepoint. -_ASCII_CHAR_INFO: list[CharInfo] = [ - CharInfo(chr(_codepoint)) for _codepoint in range(128) -] - - -class MessDetectorPlugin: - """ - Base abstract class used for mess detection plugins. - All detectors MUST extend and implement given methods. - """ - - __slots__ = () - - def feed_info(self, character: str, info: CharInfo) -> None: - """ - The main routine to be executed upon character. - Insert the logic in witch the text would be considered chaotic. - """ - raise NotImplementedError # Defensive: - - def reset(self) -> None: # Defensive: - """ - Permit to reset the plugin to the initial state. - """ - raise NotImplementedError - - @property - def ratio(self) -> float: - """ - Compute the chaos ratio based on what your feed() has seen. - Must NOT be lower than 0.; No restriction gt 0. - """ - raise NotImplementedError # Defensive: - - -class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): - __slots__ = ( - "_punctuation_count", - "_symbol_count", - "_character_count", - "_last_printable_char", - ) - - def __init__(self) -> None: - self._punctuation_count: int = 0 - self._symbol_count: int = 0 - self._character_count: int = 0 - - self._last_printable_char: str | None = None - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - self._character_count += 1 - - if character != self._last_printable_char and not info.safe: - if info.punct: - self._punctuation_count += 1 - elif not info.digit and info.sym and not info.emoticon: - self._symbol_count += 2 - - self._last_printable_char = character - - def reset(self) -> None: # Abstract - self._punctuation_count = 0 - self._character_count = 0 - self._symbol_count = 0 - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - - ratio_of_punctuation: float = ( - self._punctuation_count + self._symbol_count - ) / self._character_count - - return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 - - -class TooManyAccentuatedPlugin(MessDetectorPlugin): - __slots__ = ("_character_count", "_accentuated_count") - - def __init__(self) -> None: - self._character_count: int = 0 - self._accentuated_count: int = 0 - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - self._character_count += 1 - - if info.accentuated: - self._accentuated_count += 1 - - def reset(self) -> None: # Abstract - self._character_count = 0 - self._accentuated_count = 0 - - @property - def ratio(self) -> float: - if self._character_count < 8: - return 0.0 - - ratio_of_accentuation: float = self._accentuated_count / self._character_count - return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 - - -class UnprintablePlugin(MessDetectorPlugin): - __slots__ = ("_unprintable_count", "_character_count", "_has_escape") - - def __init__(self) -> None: - self._unprintable_count: int = 0 - self._character_count: int = 0 - self._has_escape: bool = False - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - if character == "\x1b": - self._has_escape = True - - if ( - not info.printable - and not info.space - and character != "\x1a" - and character != "\ufeff" - ): - self._unprintable_count += 1 - self._character_count += 1 - - def reset(self) -> None: # Abstract - self._unprintable_count = 0 - self._has_escape = False - - @property - def ratio(self) -> float: - if self._character_count == 0: # Defensive: - return 0.0 - - if self._has_escape: - return 1.0 - - return (self._unprintable_count * 8) / self._character_count - - -class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): - __slots__ = ( - "_successive_count", - "_character_count", - "_last_latin_character", - "_last_was_accentuated", - ) - - def __init__(self) -> None: - self._successive_count: int = 0 - self._character_count: int = 0 - - self._last_latin_character: CharInfo | None = None - self._last_was_accentuated: bool = False - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - self._character_count += 1 - if ( - self._last_latin_character is not None - and info.accentuated - and self._last_was_accentuated - ): - if info.upper and self._last_latin_character.upper: - self._successive_count += 1 - if info.unaccented == self._last_latin_character.unaccented: - self._successive_count += 1 - self._last_latin_character = info - self._last_was_accentuated = info.accentuated - - def reset(self) -> None: # Abstract - self._successive_count = 0 - self._character_count = 0 - self._last_latin_character = None - self._last_was_accentuated = False - - @property - def ratio(self) -> float: - if self._character_count == 0: - return 0.0 - - return (self._successive_count * 2) / self._character_count - - -class SuspiciousRange(MessDetectorPlugin): - __slots__ = ( - "_suspicious_successive_range_count", - "_character_count", - "_last_printable_seen", - "_last_printable_range", - ) - - def __init__(self) -> None: - self._suspicious_successive_range_count: int = 0 - self._character_count: int = 0 - self._last_printable_seen: str | None = None - self._last_printable_range: str | None = None - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - self._character_count += 1 - - if info.space or info.punct or info.safe: - self._last_printable_seen = None - self._last_printable_range = None - return - - if self._last_printable_seen is None: - self._last_printable_seen = character - self._last_printable_range = info.range - return - - unicode_range_a: str | None = self._last_printable_range - unicode_range_b: str | None = info.range - - # Identical non-None ranges can never be suspicious. - if unicode_range_a != unicode_range_b or unicode_range_a is None: - if is_suspiciously_successive_range(unicode_range_a, unicode_range_b): - self._suspicious_successive_range_count += 1 - - self._last_printable_seen = character - self._last_printable_range = unicode_range_b - - def reset(self) -> None: # Abstract - self._character_count = 0 - self._suspicious_successive_range_count = 0 - self._last_printable_seen = None - self._last_printable_range = None - - @property - def ratio(self) -> float: - if self._character_count <= 13: - return 0.0 - - ratio_of_suspicious_range_usage: float = ( - self._suspicious_successive_range_count * 2 - ) / self._character_count - - return ratio_of_suspicious_range_usage - - -class SuperWeirdWordPlugin(MessDetectorPlugin): - __slots__ = ( - "_word_count", - "_bad_word_count", - "_foreign_long_count", - "_is_current_word_bad", - "_foreign_long_watch", - "_character_count", - "_bad_character_count", - "_buffer_length", - "_buffer_last_char", - "_buffer_last_char_accentuated", - "_buffer_accent_count", - "_buffer_glyph_count", - "_buffer_upper_count", - "_buffer_first_lower", - "_buffer_has_non_ascii", - "_buffer_last_char_ligature", - "_buffer_has_internal_ligature", - "_is_current_word_invalid", - "_invalid_word_count", - ) - - def __init__(self) -> None: - self._word_count: int = 0 - self._bad_word_count: int = 0 - self._foreign_long_count: int = 0 - - self._is_current_word_bad: bool = False - self._foreign_long_watch: bool = False - - self._character_count: int = 0 - self._bad_character_count: int = 0 - - self._buffer_length: int = 0 - self._buffer_last_char: str | None = None - self._buffer_last_char_accentuated: bool = False - self._buffer_accent_count: int = 0 - self._buffer_glyph_count: int = 0 - self._buffer_upper_count: int = 0 - self._buffer_first_lower: bool = False - self._buffer_has_non_ascii: bool = False - self._buffer_last_char_ligature: bool = False - self._buffer_has_internal_ligature: bool = False - self._is_current_word_invalid: bool = False - self._invalid_word_count: int = 0 - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - if info.alpha: - if self._buffer_last_char_ligature: - self._buffer_has_internal_ligature = True - self._buffer_last_char_ligature = info.is_ligature - if self._buffer_length == 0: - self._buffer_first_lower = info.lower - self._buffer_length += 1 - self._buffer_last_char = character - - if info.upper: - self._buffer_upper_count += 1 - if not info.is_ascii: - self._buffer_has_non_ascii = True - - self._buffer_last_char_accentuated = info.accentuated - - if info.accentuated: - self._buffer_accent_count += 1 - if info.is_glyph: - self._buffer_glyph_count += 1 - elif not self._foreign_long_watch and (not info.latin or info.accentuated): - self._foreign_long_watch = True - return - if not self._buffer_length: - return - if info.is_sentence_open_punctuation or ( - info.is_superscript and self._buffer_has_internal_ligature - ): - self._is_current_word_bad = True - self._is_current_word_invalid = True - if info.space or info.punct or info.sep: - self._word_count += 1 - buffer_length: int = self._buffer_length - - self._character_count += buffer_length - - if buffer_length >= 4: - if self._buffer_accent_count / buffer_length >= 0.5: - self._is_current_word_bad = True - elif ( - self._buffer_last_char_accentuated - and self._buffer_last_char.isupper() # type: ignore[union-attr] - and self._buffer_upper_count != buffer_length - ): - self._foreign_long_count += 1 - self._is_current_word_bad = True - elif self._buffer_glyph_count == 1: - self._is_current_word_bad = True - self._foreign_long_count += 1 - elif ( - self._buffer_has_non_ascii - and self._buffer_first_lower - and self._buffer_upper_count == buffer_length - 1 - ): - # Inverse capitalization detector. - # No natural writing produces such words. - # see https://github.com/jawah/charset_normalizer/issues/731 - self._foreign_long_count += 1 - self._is_current_word_bad = True - if buffer_length >= 24 and self._foreign_long_watch: - probable_camel_cased: bool = ( - self._buffer_upper_count > 0 - and self._buffer_upper_count / buffer_length <= 0.3 - ) - - if not probable_camel_cased: - self._foreign_long_count += 1 - self._is_current_word_bad = True - - if self._is_current_word_bad: - self._bad_word_count += 1 - self._bad_character_count += buffer_length - self._is_current_word_bad = False - if self._is_current_word_invalid: - self._invalid_word_count += 1 - self._is_current_word_invalid = False - - self._foreign_long_watch = False - self._buffer_length = 0 - self._buffer_last_char = None - self._buffer_last_char_accentuated = False - self._buffer_accent_count = 0 - self._buffer_glyph_count = 0 - self._buffer_upper_count = 0 - self._buffer_first_lower = False - self._buffer_has_non_ascii = False - self._buffer_last_char_ligature = False - self._buffer_has_internal_ligature = False - elif ( - character not in {"<", ">", "-", "=", "~", "|", "_"} - and not info.digit - and info.sym - ): - self._is_current_word_bad = True - self._buffer_length += 1 - self._buffer_last_char = character - self._buffer_last_char_accentuated = False - - def reset(self) -> None: # Abstract - self._buffer_length = 0 - self._buffer_last_char = None - self._buffer_last_char_accentuated = False - self._is_current_word_bad = False - self._foreign_long_watch = False - self._bad_word_count = 0 - self._word_count = 0 - self._character_count = 0 - self._bad_character_count = 0 - self._foreign_long_count = 0 - self._buffer_accent_count = 0 - self._buffer_glyph_count = 0 - self._buffer_upper_count = 0 - self._buffer_first_lower = False - self._buffer_has_non_ascii = False - self._buffer_last_char_ligature = False - self._buffer_has_internal_ligature = False - self._is_current_word_invalid = False - self._invalid_word_count = 0 - - @property - def ratio(self) -> float: - if self._invalid_word_count: - return 1.0 - - if self._word_count <= 10 and self._foreign_long_count == 0: - return 0.0 - - return self._bad_character_count / self._character_count - - -class CjkUncommonPlugin(MessDetectorPlugin): - """ - Detect messy CJK text that probably means nothing. - """ - - __slots__ = ("_character_count", "_uncommon_count") - - def __init__(self) -> None: - self._character_count: int = 0 - self._uncommon_count: int = 0 - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - self._character_count += 1 - - if not info.common_cjk: - self._uncommon_count += 1 - - def reset(self) -> None: # Abstract - self._character_count = 0 - self._uncommon_count = 0 - - @property - def ratio(self) -> float: - if self._character_count < 4: - return 0.0 - - uncommon_form_usage: float = ( - 2 * self._uncommon_count - self._character_count - ) / (5 * max(self._character_count, 16)) - - # we can be pretty sure it's garbage when uncommon characters are widely - # used. otherwise it could just be traditional chinese for example. - return max(0.0, uncommon_form_usage) - - -class SuspiciousKatakanaPlugin(MessDetectorPlugin): - """Detect implausible halfwidth Katakana and uncommon CJK combinations.""" - - __slots__ = ( - "_katakana_count", - "_halfwidth_katakana_count", - "_cjk_count", - "_uncommon_cjk_count", - ) - - def __init__(self) -> None: - self._katakana_count: int = 0 - self._halfwidth_katakana_count: int = 0 - self._cjk_count: int = 0 - self._uncommon_cjk_count: int = 0 - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - if info.is_katakana: - self._katakana_count += 1 - if info.is_halfwidth_katakana: - self._halfwidth_katakana_count += 1 - return - - self._cjk_count += 1 - if not info.common_cjk: - self._uncommon_cjk_count += 1 - - def reset(self) -> None: # Abstract - self._katakana_count = 0 - self._halfwidth_katakana_count = 0 - self._cjk_count = 0 - self._uncommon_cjk_count = 0 - - @property - def ratio(self) -> float: - if ( - self._halfwidth_katakana_count >= 4 - and self._halfwidth_katakana_count == self._katakana_count - and 3 <= self._cjk_count == self._uncommon_cjk_count - ): - return 1.0 - - return 0.0 - - -class ArchaicUpperLowerPlugin(MessDetectorPlugin): - __slots__ = ( - "_buf", - "_character_count_since_last_sep", - "_successive_upper_lower_count", - "_successive_upper_lower_count_final", - "_character_count", - "_last_alpha_seen_upper", - "_last_alpha_seen_lower", - "_current_ascii_only", - ) - - def __init__(self) -> None: - self._buf: bool = False - - self._character_count_since_last_sep: int = 0 - - self._successive_upper_lower_count: int = 0 - self._successive_upper_lower_count_final: int = 0 - - self._character_count: int = 0 - - self._last_alpha_seen_upper: bool = False - self._last_alpha_seen_lower: bool = False - self._current_ascii_only: bool = True - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - is_concerned: bool = info.alpha and info.case_variable - chunk_sep: bool = not is_concerned - - if chunk_sep and self._character_count_since_last_sep > 0: - if ( - self._character_count_since_last_sep <= 64 - and not info.digit - and not self._current_ascii_only - ): - self._successive_upper_lower_count_final += ( - self._successive_upper_lower_count - ) - - self._successive_upper_lower_count = 0 - self._character_count_since_last_sep = 0 - self._buf = False - self._character_count += 1 - self._current_ascii_only = True - - return - - if self._current_ascii_only and not info.is_ascii: - self._current_ascii_only = False - - if self._character_count_since_last_sep > 0: - if (info.upper and self._last_alpha_seen_lower) or ( - info.lower and self._last_alpha_seen_upper - ): - if self._buf: - self._successive_upper_lower_count += 2 - self._buf = False - else: - self._buf = True - else: - self._buf = False - - self._character_count += 1 - self._character_count_since_last_sep += 1 - self._last_alpha_seen_upper = info.upper - self._last_alpha_seen_lower = info.lower - - def reset(self) -> None: # Abstract - self._character_count = 0 - self._character_count_since_last_sep = 0 - self._successive_upper_lower_count = 0 - self._successive_upper_lower_count_final = 0 - self._last_alpha_seen_upper = False - self._last_alpha_seen_lower = False - self._buf = False - self._current_ascii_only = True - - @property - def ratio(self) -> float: - if self._character_count == 0: # Defensive: - return 0.0 - - return self._successive_upper_lower_count_final / self._character_count - - -class ArabicIsolatedFormPlugin(MessDetectorPlugin): - __slots__ = ("_character_count", "_isolated_form_count") - - def __init__(self) -> None: - self._character_count: int = 0 - self._isolated_form_count: int = 0 - - def reset(self) -> None: # Abstract - self._character_count = 0 - self._isolated_form_count = 0 - - def feed_info(self, character: str, info: CharInfo) -> None: - """Optimized feed using pre-computed character info.""" - self._character_count += 1 - - if info.flags & _ARABIC_ISOLATED_FORM: - self._isolated_form_count += 1 - - @property - def ratio(self) -> float: - if self._character_count < 8: - return 0.0 - - isolated_form_usage: float = self._isolated_form_count / self._character_count - - return isolated_form_usage - - -@lru_cache(maxsize=None) -def is_suspiciously_successive_range( - unicode_range_a: str | None, unicode_range_b: str | None -) -> bool: - """ - Determine if two Unicode ranges seen next to each other can be considered suspicious. - """ - if unicode_range_a is None or unicode_range_b is None: - return True - - familly_a: str = _RANGE_FAMILIES[unicode_range_a] - familly_b: str = _RANGE_FAMILIES[unicode_range_b] - - if familly_a == familly_b: - return False - - if ( - familly_a in _COMPATIBLE_WITH_ANY_RANGE_FAMILIES - or familly_b in _COMPATIBLE_WITH_ANY_RANGE_FAMILIES - ): - return False - - if CompatibleFamillyRange(familly_a, familly_b) in _COMPATIBLE_RANGE_FAMILIES: - return False - - # Basic Latin is commonly interspersed with East Asian scripts, but the - # compatibility must not extend to every range in the Latin family. - if unicode_range_a == "Basic Latin": - return familly_b not in _BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES - - if unicode_range_b == "Basic Latin": - return familly_a not in _BASIC_LATIN_COMPATIBLE_RANGE_FAMILIES - - return True - - -def mess_ratio( - decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False -) -> float: - """ - Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier. - """ - - seq_len: int = len(decoded_sequence) - - if seq_len < 511: - step: int = 32 - elif seq_len < 1024: - step = 64 - else: - step = 128 - - # str.isascii() is O(1) (the flag lives in the str header). Seven of the - # ten detectors provably keep a 0.0 ratio on ASCII-only input and are - # therefore not fed at all. - is_pure_ascii: bool = decoded_sequence.isascii() - - # Cached per-codepoint character properties (see CharInfo). ASCII - # characters resolve through the immutable import-time table; anything - # else goes through the lru_cache-backed slow path. - ascii_info = _ASCII_CHAR_INFO - char_info = _char_info - - mean_mess_ratio: float - info: CharInfo - - # Create each detector as a named local variable (unrolled from the generic loop). - # This eliminates per-character iteration over the detector list and - # per-character eligible() virtual dispatch, while keeping every plugin class - # intact and fully readable. - d_sp: TooManySymbolOrPunctuationPlugin = TooManySymbolOrPunctuationPlugin() - d_ta: TooManyAccentuatedPlugin = TooManyAccentuatedPlugin() - d_up: UnprintablePlugin = UnprintablePlugin() - d_sda: SuspiciousDuplicateAccentPlugin = SuspiciousDuplicateAccentPlugin() - d_sr: SuspiciousRange = SuspiciousRange() - d_sw: SuperWeirdWordPlugin = SuperWeirdWordPlugin() - d_cu: CjkUncommonPlugin = CjkUncommonPlugin() - d_sk: SuspiciousKatakanaPlugin = SuspiciousKatakanaPlugin() - d_au: ArchaicUpperLowerPlugin = ArchaicUpperLowerPlugin() - d_ai: ArabicIsolatedFormPlugin = ArabicIsolatedFormPlugin() - - # Local references avoid repeated bound-method creation in the hot loop. - d_sp_feed = d_sp.feed_info - d_ta_feed = d_ta.feed_info - d_up_feed = d_up.feed_info - d_sda_feed = d_sda.feed_info - d_sr_feed = d_sr.feed_info - d_sw_feed = d_sw.feed_info - d_cu_feed = d_cu.feed_info - d_sk_feed = d_sk.feed_info - d_au_feed = d_au.feed_info - d_ai_feed = d_ai.feed_info - - for block_start in range(0, seq_len, step): - for character in decoded_sequence[block_start : block_start + step]: - # Character properties computed once per distinct codepoint - # (shared across all plugins and all mess_ratio calls). - # ord() doubles as the ASCII table index. - codepoint: int = ord(character) - if codepoint < 128: - info = ascii_info[codepoint] - else: - info = char_info(character) - - # Detectors with eligible() == always True - d_up_feed(character, info) - d_sw_feed(character, info) - - if is_pure_ascii: - # The seven remaining detectors provably stay at 0.0 (see above). - if info.printable: - d_sp_feed(character, info) - continue - - d_au_feed(character, info) - - # Detectors with eligible() == isprintable - if info.printable: - d_sp_feed(character, info) - d_sr_feed(character, info) - - # Detectors with eligible() == isalpha - if info.alpha: - d_ta_feed(character, info) - # SuspiciousDuplicateAccent: isalpha() and is_latin() - if info.latin: - d_sda_feed(character, info) - # CjkUncommon and SuspiciousKatakana: is_cjk() - if info.is_cjk: - d_cu_feed(character, info) - d_sk_feed(character, info) - elif info.is_katakana: - d_sk_feed(character, info) - # ArabicIsolatedForm: is_arabic() - if info.is_arabic: - d_ai_feed(character, info) - - mean_mess_ratio = ( - d_sp.ratio - + d_ta.ratio - + d_up.ratio - + d_sda.ratio - + d_sr.ratio - + d_sw.ratio - + d_cu.ratio - + d_sk.ratio - + d_au.ratio - + d_ai.ratio - ) - - if mean_mess_ratio >= maximum_threshold: - break - else: - # Flush last word buffer in SuperWeirdWordPlugin via trailing newline. - nl_info = ascii_info[10] # "\n" - d_sw_feed("\n", nl_info) - if not is_pure_ascii: - d_au_feed("\n", nl_info) - d_up_feed("\n", nl_info) - - mean_mess_ratio = ( - d_sp.ratio - + d_ta.ratio - + d_up.ratio - + d_sda.ratio - + d_sr.ratio - + d_sw.ratio - + d_cu.ratio - + d_sk.ratio - + d_au.ratio - + d_ai.ratio - ) - - if debug: # Defensive: - logger = getLogger("opentelemetry.agent._vendor.charset_normalizer") - - logger.log( - TRACE, - "Mess-detector extended-analysis start. " - f"intermediary_mean_mess_ratio_calc={step} mean_mess_ratio={mean_mess_ratio} " - f"maximum_threshold={maximum_threshold}", - ) - - if seq_len > 16: - logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}") - logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}") - - for dt in [d_sp, d_ta, d_up, d_sda, d_sr, d_sw, d_cu, d_sk, d_au, d_ai]: - logger.log(TRACE, f"{dt.__class__}: {dt.ratio}") - - return round(mean_mess_ratio, 3) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py deleted file mode 100644 index 9b081a66b91..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/models.py +++ /dev/null @@ -1,387 +0,0 @@ -from __future__ import annotations - -from encodings.aliases import aliases -from re import sub -from typing import Any, Iterator, List, Tuple - -from .constant import RE_POSSIBLE_ENCODING_INDICATION, TOO_BIG_SEQUENCE -from .utils import iana_name, is_multi_byte_encoding, unicode_range - - -class CharsetMatch: - def __init__( - self, - payload: bytes | bytearray, - guessed_encoding: str, - mean_mess_ratio: float, - has_sig_or_bom: bool, - languages: CoherenceMatches, - decoded_payload: str | None = None, - preemptive_declaration: str | None = None, - ): - self._payload: bytes | bytearray = payload - - self._encoding: str = guessed_encoding - self._mean_mess_ratio: float = mean_mess_ratio - self._languages: CoherenceMatches = languages - self._has_sig_or_bom: bool = has_sig_or_bom - self._unicode_ranges: list[str] | None = None - - self._leaves: list[CharsetMatch] = [] - self._mean_coherence_ratio: float = 0.0 - - self._output_payload: bytes | None = None - self._output_encoding: str | None = None - - self._string: str | None = decoded_payload - - self._preemptive_declaration: str | None = preemptive_declaration - - def __eq__(self, other: object) -> bool: - if not isinstance(other, CharsetMatch): - if isinstance(other, str): - # Use non-strict iana_name so an operand that is not a known - # encoding alias compares unequal instead of raising, keeping - # __eq__ total as the data model requires (mirrors the lookup - # in CharsetMatches.__getitem__). - return iana_name(other, False) == self.encoding - return False - return self.encoding == other.encoding and self.fingerprint == other.fingerprint - - def __lt__(self, other: object) -> bool: - """ - Implemented to make sorted available upon CharsetMatches items. - """ - if not isinstance(other, CharsetMatch): - raise ValueError - - chaos_difference: float = abs(self.chaos - other.chaos) - coherence_difference: float = abs(self.coherence - other.coherence) - - # Below 0.5% difference --> Use Coherence - if chaos_difference < 0.005 and coherence_difference > 0.02: - return self.coherence > other.coherence - elif chaos_difference < 0.005 and coherence_difference <= 0.02: - # When having a difficult decision, use the result that decoded as many multi-byte as possible. - # preserve RAM usage! - if len(self._payload) >= TOO_BIG_SEQUENCE: - return self.chaos < other.chaos - return self.multi_byte_usage > other.multi_byte_usage - - return self.chaos < other.chaos - - @property - def multi_byte_usage(self) -> float: - # Empty payloads are valid (from_bytes(b"") returns a match); avoid /0. - raw_len = len(self.raw) - if raw_len == 0: - return 0.0 - return 1.0 - (len(str(self)) / raw_len) - - def __str__(self) -> str: - # Lazy Str Loading - if self._string is None: - self._string = str(self._payload, self._encoding, "strict") - # UTF-7 BOM is encoded in modified Base64 whose byte boundary - # can overlap with the next character, so raw-byte stripping - # is unreliable. Strip the decoded BOM character instead. - if ( - self._has_sig_or_bom - and self._encoding == "utf_7" - and self._string - and self._string[0] == "\ufeff" - ): - self._string = self._string[1:] - return self._string - - def __repr__(self) -> str: - return f"" - - def add_submatch(self, other: CharsetMatch) -> None: - if not isinstance(other, CharsetMatch) or other == self: - raise ValueError( - "Unable to add instance <{}> as a submatch of a CharsetMatch".format( - other.__class__ - ) - ) - - other._string = None # Unload RAM usage; dirty trick. - self._leaves.append(other) - - @property - def encoding(self) -> str: - return self._encoding - - @property - def encoding_aliases(self) -> list[str]: - """ - Encoding name are known by many name, using this could help when searching for IBM855 when it's listed as CP855. - """ - also_known_as: list[str] = [] - for u, p in aliases.items(): - if self.encoding == u: - also_known_as.append(p) - elif self.encoding == p: - also_known_as.append(u) - return also_known_as - - @property - def bom(self) -> bool: - return self._has_sig_or_bom - - @property - def byte_order_mark(self) -> bool: - return self._has_sig_or_bom - - @property - def languages(self) -> list[str]: - """ - Return the complete list of possible languages found in decoded sequence. - Usually not really useful. Returned list may be empty even if 'language' property return something != 'Unknown'. - """ - return [e[0] for e in self._languages] - - @property - def language(self) -> str: - """ - Most probable language found in decoded sequence. If none were detected or inferred, the property will return - "Unknown". - """ - if not self._languages: - # Trying to infer the language based on the given encoding - # Its either English or we should not pronounce ourselves in certain cases. - if "ascii" in self.could_be_from_charset: - return "English" - - # doing it there to avoid circular import - from opentelemetry.agent._vendor.charset_normalizer.cd import encoding_languages, mb_encoding_languages - - languages = ( - mb_encoding_languages(self.encoding) - if is_multi_byte_encoding(self.encoding) - else encoding_languages(self.encoding) - ) - - if len(languages) == 0 or "Latin Based" in languages: - return "Unknown" - - return languages[0] - - return self._languages[0][0] - - @property - def chaos(self) -> float: - return self._mean_mess_ratio - - @property - def coherence(self) -> float: - if not self._languages: - return 0.0 - return self._languages[0][1] - - @property - def percent_chaos(self) -> float: - return round(self.chaos * 100, ndigits=3) - - @property - def percent_coherence(self) -> float: - return round(self.coherence * 100, ndigits=3) - - @property - def raw(self) -> bytes | bytearray: - """ - Original untouched bytes. - """ - return self._payload - - @property - def submatch(self) -> list[CharsetMatch]: - return self._leaves - - @property - def has_submatch(self) -> bool: - return len(self._leaves) > 0 - - @property - def alphabets(self) -> list[str]: - if self._unicode_ranges is not None: - return self._unicode_ranges - # list detected ranges - detected_ranges: list[str | None] = [unicode_range(char) for char in str(self)] - # filter and sort - self._unicode_ranges = sorted(list({r for r in detected_ranges if r})) - return self._unicode_ranges - - @property - def could_be_from_charset(self) -> list[str]: - """ - The complete list of encoding that output the exact SAME str result and therefore could be the originating - encoding. - This list does include the encoding available in property 'encoding'. - """ - return [self._encoding] + [m.encoding for m in self._leaves] - - def output(self, encoding: str = "utf_8") -> bytes: - """ - Method to get re-encoded bytes payload using given target encoding. Default to UTF-8. - Any errors will be simply ignored by the encoder NOT replaced. - """ - if self._output_encoding is None or self._output_encoding != encoding: - self._output_encoding = encoding - decoded_string = str(self) - if ( - self._preemptive_declaration is not None - and self._preemptive_declaration.lower() - not in ["utf-8", "utf8", "utf_8"] - ): - patched_header = sub( - RE_POSSIBLE_ENCODING_INDICATION, - lambda m: m.string[m.span()[0] : m.span()[1]].replace( - m.groups()[0], - iana_name(self._output_encoding).replace("_", "-"), # type: ignore[arg-type] - ), - decoded_string[:8192], - count=1, - ) - - decoded_string = patched_header + decoded_string[8192:] - - self._output_payload = decoded_string.encode(encoding, "replace") - - return self._output_payload # type: ignore - - @property - def fingerprint(self) -> int: - """ - Retrieve a hash fingerprint of the decoded payload, used for deduplication. - """ - return hash(str(self)) - - -class CharsetMatches: - """ - Container with every CharsetMatch items ordered by default from most probable to the less one. - Act like a list(iterable) but does not implements all related methods. - """ - - def __init__(self, results: list[CharsetMatch] | None = None): - self._results: list[CharsetMatch] = sorted(results) if results else [] - self._is_sorted: bool = True - - def _ensure_sorted(self) -> None: - if not self._is_sorted: - self._results.sort() - self._is_sorted = True - - def __iter__(self) -> Iterator[CharsetMatch]: - self._ensure_sorted() - yield from self._results - - def __getitem__(self, item: int | str) -> CharsetMatch: - """ - Retrieve a single item either by its position or encoding name (alias may be used here). - Raise KeyError upon invalid index or encoding not present in results. - """ - if isinstance(item, int): - self._ensure_sorted() - return self._results[item] - if isinstance(item, str): - item = iana_name(item, False) - for result in self._results: - if item in result.could_be_from_charset: - return result - raise KeyError - - def __len__(self) -> int: - return len(self._results) - - def __bool__(self) -> bool: - return len(self._results) > 0 - - def append(self, item: CharsetMatch) -> None: - """ - Insert a single match. Will be inserted accordingly to preserve sort. - Can be inserted as a submatch. - """ - if not isinstance(item, CharsetMatch): - raise ValueError( - "Cannot append instance '{}' to CharsetMatches".format( - str(item.__class__) - ) - ) - # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) - if len(item.raw) < TOO_BIG_SEQUENCE: - for match in self._results: - if match.fingerprint == item.fingerprint and match.chaos == item.chaos: - match.add_submatch(item) - return - self._results.append(item) - self._is_sorted = False - - def best(self) -> CharsetMatch | None: - """ - Simply return the first match. Strict equivalent to matches[0]. - """ - if not self._results: - return None - self._ensure_sorted() - return self._results[0] - - def first(self) -> CharsetMatch | None: - """ - Redundant method, call the method best(). Kept for BC reasons. - """ - return self.best() - - -CoherenceMatch = Tuple[str, float] -CoherenceMatches = List[CoherenceMatch] - - -class CliDetectionResult: - def __init__( - self, - path: str, - encoding: str | None, - encoding_aliases: list[str], - alternative_encodings: list[str], - language: str, - alphabets: list[str], - has_sig_or_bom: bool, - chaos: float, - coherence: float, - unicode_path: str | None, - is_preferred: bool, - ): - self.path: str = path - self.unicode_path: str | None = unicode_path - self.encoding: str | None = encoding - self.encoding_aliases: list[str] = encoding_aliases - self.alternative_encodings: list[str] = alternative_encodings - self.language: str = language - self.alphabets: list[str] = alphabets - self.has_sig_or_bom: bool = has_sig_or_bom - self.chaos: float = chaos - self.coherence: float = coherence - self.is_preferred: bool = is_preferred - - @property - def __dict__(self) -> dict[str, Any]: # type: ignore - return { - "path": self.path, - "encoding": self.encoding, - "encoding_aliases": self.encoding_aliases, - "alternative_encodings": self.alternative_encodings, - "language": self.language, - "alphabets": self.alphabets, - "has_sig_or_bom": self.has_sig_or_bom, - "chaos": self.chaos, - "coherence": self.coherence, - "unicode_path": self.unicode_path, - "is_preferred": self.is_preferred, - } - - def to_json(self) -> str: - from json import dumps - - return dumps(self.__dict__, ensure_ascii=True, indent=4) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py deleted file mode 100644 index 34d3f8fc3db..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/utils.py +++ /dev/null @@ -1,452 +0,0 @@ -from __future__ import annotations - -import importlib -import logging -import unicodedata -from bisect import bisect_right -from codecs import IncrementalDecoder -from functools import lru_cache -from typing import Generator - -from .constant import ( - ENCODING_MARKS, - IANA_SUPPORTED_SIMILAR, - RE_POSSIBLE_ENCODING_INDICATION, - UNICODE_RANGES_COMBINED, - _SECONDARY_RANGE_NAMES, - COMMON_CJK_CHARACTERS, - _LATIN, - _CJK, - _HANGUL, - _KATAKANA, - _HIRAGANA, - _HALFWIDTH_KATAKANA, - _THAI, - _ARABIC, - _ARABIC_ISOLATED_FORM, - _LIGATURE, - _SUPERSCRIPT, - _SENTENCE_OPEN_PUNCTUATION, - _ACCENT_KEYWORDS, - _ACCENTUATED, - _KNOWN_MB_DECODERS, - _KNOWN_MB_CLASSES, - _IANA_NAMES, - _MULTIBYTE_SEARCH_RADIUS, -) - - -def _character_flags(character: str) -> int: - """Compute all name-based classification flags with a single unicodedata.name() call.""" - try: - desc: str = unicodedata.name(character) - except ValueError: - return 0 - - flags: int = 0 - - if "LATIN" in desc: - flags |= _LATIN - if "CJK" in desc: - flags |= _CJK - if "HANGUL" in desc: - flags |= _HANGUL - if "KATAKANA" in desc: - flags |= _KATAKANA - if "HALFWIDTH" in desc: - flags |= _HALFWIDTH_KATAKANA - if "HIRAGANA" in desc: - flags |= _HIRAGANA - if "THAI" in desc: - flags |= _THAI - if "ARABIC" in desc: - flags |= _ARABIC - if "ISOLATED FORM" in desc: - flags |= _ARABIC_ISOLATED_FORM - if "LIGATURE" in desc or desc.endswith("LETTER AE"): - flags |= _LIGATURE - if "SUPERSCRIPT" in desc: - flags |= _SUPERSCRIPT - if desc in {"INVERTED QUESTION MARK", "INVERTED EXCLAMATION MARK"}: - flags |= _SENTENCE_OPEN_PUNCTUATION - - for kw in _ACCENT_KEYWORDS: - if kw in desc: - flags |= _ACCENTUATED - break - - return flags - - -def is_accentuated(character: str) -> bool: - return bool(_character_flags(character) & _ACCENTUATED) - - -def remove_accent(character: str) -> str: - decomposed: str = unicodedata.decomposition(character) - if not decomposed: - return character - - codes: list[str] = decomposed.split(" ") - - return chr(int(codes[0], 16)) - - -# Pre-built sorted lookup table for O(log n) binary search in unicode_range(). -# Each entry is (range_start, range_end_exclusive, range_name). -_UNICODE_RANGES_SORTED: list[tuple[int, int, str]] = sorted( - (ord_range.start, ord_range.stop, name) - for name, ord_range in UNICODE_RANGES_COMBINED.items() -) -_UNICODE_RANGE_STARTS: list[int] = [e[0] for e in _UNICODE_RANGES_SORTED] - - -def unicode_range(character: str) -> str | None: - """ - Retrieve the Unicode range official name from a single character. - """ - character_ord: int = ord(character) - - if character_ord < 32: - return "Control character" - if character_ord < 128: - return "Basic Latin" - - # Binary search: find the rightmost range whose start <= character_ord - idx = bisect_right(_UNICODE_RANGE_STARTS, character_ord) - 1 - if idx >= 0: - start, stop, name = _UNICODE_RANGES_SORTED[idx] - if character_ord < stop: - return name - - return None - - -def is_latin(character: str) -> bool: - return bool(_character_flags(character) & _LATIN) - - -def is_punctuation(character: str) -> bool: - character_category: str = unicodedata.category(character) - - if "P" in character_category: - return True - - character_range: str | None = unicode_range(character) - - if character_range is None: - return False - - return "Punctuation" in character_range - - -def is_symbol(character: str) -> bool: - character_category: str = unicodedata.category(character) - - if "S" in character_category or "N" in character_category: - return True - - character_range: str | None = unicode_range(character) - - if character_range is None: - return False - - return "Forms" in character_range and character_category != "Lo" - - -def is_emoticon(character: str) -> bool: - character_range: str | None = unicode_range(character) - - if character_range is None: - return False - - return "Emoticons" in character_range or "Pictographs" in character_range - - -def is_separator(character: str) -> bool: - if character.isspace() or character in {"|", "+", "<", ">"}: - return True - - character_category: str = unicodedata.category(character) - - return "Z" in character_category or character_category in {"Po", "Pd", "Pc"} - - -def is_case_variable(character: str) -> bool: - return character.islower() != character.isupper() - - -def is_cjk(character: str) -> bool: - return bool(_character_flags(character) & _CJK) - - -def is_hiragana(character: str) -> bool: - return bool(_character_flags(character) & _HIRAGANA) - - -def is_katakana(character: str) -> bool: - return bool(_character_flags(character) & _KATAKANA) - - -def is_hangul(character: str) -> bool: - return bool(_character_flags(character) & _HANGUL) - - -def is_thai(character: str) -> bool: - return bool(_character_flags(character) & _THAI) - - -def is_arabic(character: str) -> bool: - return bool(_character_flags(character) & _ARABIC) - - -def is_arabic_isolated_form(character: str) -> bool: - return bool(_character_flags(character) & _ARABIC_ISOLATED_FORM) - - -def is_cjk_uncommon(character: str) -> bool: - return character not in COMMON_CJK_CHARACTERS - - -def is_unicode_range_secondary(range_name: str) -> bool: - return range_name in _SECONDARY_RANGE_NAMES - - -def is_unprintable(character: str) -> bool: - return ( - not character.isspace() # includes \n \t \r \v - and not character.isprintable() - and character != "\x1a" # Why? Its the ASCII substitute character. - and character != "\ufeff" # bug discovered in Python, - # Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space. - ) - - -def any_specified_encoding( - sequence: bytes | bytearray, search_zone: int = 8192 -) -> str | None: - """ - Extract using ASCII-only decoder any specified encoding in the first n-bytes. - """ - if not isinstance(sequence, (bytes, bytearray)): - raise TypeError - - seq_len: int = len(sequence) - - # Cheap literal pre-filter. - search_bytes = sequence[: min(seq_len, search_zone)] - lowered_bytes = search_bytes.lower() - if b"coding" not in lowered_bytes and b"charset" not in lowered_bytes: - return None - - decoded_zone: str = search_bytes.decode("ascii", errors="ignore") - - for match in RE_POSSIBLE_ENCODING_INDICATION.finditer(decoded_zone): - specified_encoding = match.group(1).lower().replace("-", "_") - encoding_iana = _IANA_NAMES.get(specified_encoding) - if encoding_iana is not None: - return encoding_iana - - return None - - -@lru_cache(maxsize=None) -def is_multi_byte_encoding(name: str) -> bool: - """ - Verify is a specific encoding is a multi byte one based on it IANA name - """ - if name in _KNOWN_MB_DECODERS: - return True - - # Besides the Unicode family above, every multibyte codec shipped with - # Python is implemented by _multibytecodec through exactly one of the six - # cjkcodecs providers below. Probing those providers directly (getcodec) - # classifies a name without importing its "encodings." module: - # classifying the whole IANA_SUPPORTED list would otherwise import many - # modules and dominate "import charset_normalizer" wall time. - # see https://github.com/jawah/charset_normalizer/issues/742 - for provider in _KNOWN_MB_CLASSES: - try: - importlib.import_module(provider).getcodec(name) # type: ignore[attr-defined] - except (ImportError, AttributeError, LookupError): # Defensive: edge cases - continue - return True - - return False - - -def identify_sig_or_bom(sequence: bytes | bytearray) -> tuple[str | None, bytes]: - """ - Identify and extract SIG/BOM in given sequence. - """ - - for iana_encoding in ENCODING_MARKS: - marks: bytes | list[bytes] = ENCODING_MARKS[iana_encoding] - - if isinstance(marks, bytes): - marks = [marks] - - for mark in marks: - if sequence.startswith(mark): - return iana_encoding, mark - - return None, b"" - - -def should_strip_sig_or_bom(iana_encoding: str) -> bool: - return iana_encoding not in {"utf_16", "utf_32"} - - -def iana_name(cp_name: str, strict: bool = True) -> str: - """Returns the Python normalized encoding name (Not the IANA official name).""" - cp_name = cp_name.lower().replace("-", "_") - - encoding_iana = _IANA_NAMES.get(cp_name) - if encoding_iana is not None: - return encoding_iana - - if strict: - raise ValueError(f"Unable to retrieve IANA for '{cp_name}'") - - return cp_name - - -def cp_similarity(iana_name_a: str, iana_name_b: str) -> float: - if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b): - return 0.0 - - decoder_a = importlib.import_module(f"encodings.{iana_name_a}").IncrementalDecoder - decoder_b = importlib.import_module(f"encodings.{iana_name_b}").IncrementalDecoder - - id_a: IncrementalDecoder = decoder_a(errors="ignore") - id_b: IncrementalDecoder = decoder_b(errors="ignore") - - character_match_count: int = 0 - - for i in range(256): - to_be_decoded: bytes = bytes([i]) - if id_a.decode(to_be_decoded) == id_b.decode(to_be_decoded): - character_match_count += 1 - - return character_match_count / 256 - - -def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool: - """ - Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using - the function cp_similarity. - """ - return ( - iana_name_a in IANA_SUPPORTED_SIMILAR - and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] - ) - - -def set_logging_handler( - name: str = "opentelemetry.agent._vendor.charset_normalizer", - level: int = logging.INFO, - format_string: str = "%(asctime)s | %(levelname)s | %(message)s", -) -> None: - logger = logging.getLogger(name) - logger.setLevel(level) - - handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter(format_string)) - logger.addHandler(handler) - - -def cut_sequence_chunks( - sequences: bytes | bytearray, - encoding_iana: str, - offsets: range, - chunk_size: int, - bom_or_sig_available: bool, - strip_sig_or_bom: bool, - sig_payload: bytes, - is_multi_byte_decoder: bool, - decoded_payload: str | None = None, - deferred_decoding: bool = False, -) -> Generator[str, None, None]: - # iso2022 codec is stateful, generic mb cuter isn't going to cut it! - if decoded_payload and encoding_iana.startswith("iso2022_"): - decoded_length = len(decoded_payload) - sequence_length = len(sequences) - for i in offsets: - decoded_offset = i * decoded_length // sequence_length - chunk = decoded_payload[decoded_offset : decoded_offset + chunk_size] - if not chunk: - break - yield chunk - elif decoded_payload and not is_multi_byte_decoder: - for i in offsets: - chunk = decoded_payload[i : i + chunk_size] - if not chunk: - break - yield chunk - elif deferred_decoding: - # Deferred single-byte probing: the whole payload is not decoded - # yet. Single-byte codecs are stateless (1 byte == 1 char), hence - # decode(base)[i:j] == decode(base[i:j]): slicing the raw bytes - # yields exactly the chunks the branch above would have produced, - # short trailing chunks included, and raises UnicodeDecodeError on - # invalid bytes just like the whole-payload decode would. - base_bytes = ( - sequences if not strip_sig_or_bom else sequences[len(sig_payload) :] - ) - for i in offsets: - cut_sequence = base_bytes[i : i + chunk_size] - if not cut_sequence: - break - yield str(cut_sequence, encoding_iana) - else: - for i in offsets: - chunk_end = i + chunk_size - if chunk_end > len(sequences) + 8: - continue - - cut_sequence = sequences[i : i + chunk_size] - - if bom_or_sig_available and not strip_sig_or_bom: - cut_sequence = sig_payload + cut_sequence - - chunk = cut_sequence.decode( - encoding_iana, - errors="ignore" if is_multi_byte_decoder else "strict", - ) - - # multi-byte bad cutting detector and adjustment - # not the cleanest way to perform that fix but clever enough for now. - if is_multi_byte_decoder and i > 0: - chunk_partial_size_chk: int = min(chunk_size, 16) - chunk_prefix = chunk[:chunk_partial_size_chk] - found_nearby = False - - if decoded_payload: - decoded_length = len(decoded_payload) - expected_offset = i * decoded_length // len(sequences) - search_start = max(0, expected_offset - _MULTIBYTE_SEARCH_RADIUS) - search_end = min( - decoded_length, expected_offset + _MULTIBYTE_SEARCH_RADIUS - ) - found_nearby = ( - decoded_payload.find(chunk_prefix, search_start, search_end) - >= 0 - ) - - if ( - decoded_payload - and not found_nearby - and chunk_prefix not in decoded_payload - ): - for j in range(i, i - 4, -1): - cut_sequence = sequences[j:chunk_end] - - if bom_or_sig_available and not strip_sig_or_bom: - cut_sequence = sig_payload + cut_sequence - - chunk = cut_sequence.decode(encoding_iana, errors="ignore") - - if chunk[:chunk_partial_size_chk] in decoded_payload: - break - - yield chunk diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py deleted file mode 100644 index c362b2c0fe2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/charset_normalizer/version.py +++ /dev/null @@ -1,8 +0,0 @@ -""" -Expose version -""" - -from __future__ import annotations - -__version__ = "3.5.2" -VERSION = __version__.split(".") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS deleted file mode 100644 index c26fdd231d6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.AUTHORS +++ /dev/null @@ -1,11 +0,0 @@ -MAINTAINER -Michal Hořejšek - -CONTRIBUTORS -anentropic -Antti Jokipii -bcaller -Frederik Petersen -Guillaume Desvé -Kris Molendyke -David Majda diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE deleted file mode 100644 index 1d77bbf99f3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema.LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2018, Michal Horejsek -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py deleted file mode 100644 index 87215ffd003..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/__init__.py +++ /dev/null @@ -1,386 +0,0 @@ -# ___ -# \./ DANGER: This project implements some code generation -# .--.O.--. techniques involving string concatenation. -# \/ \/ If you look at it, you might die. -# - -r""" -Installation -************ - -.. code-block:: bash - - pip install fastjsonschema - -Support only for Python 3.3 and higher. - -About -***** - -``fastjsonschema`` implements validation of JSON documents by JSON schema. -The library implements JSON schema drafts 04, 06, and 07. The main purpose is -to have a really fast implementation. See some numbers: - - * Probably the most popular, ``jsonschema``, can take up to 5 seconds for valid - inputs and 1.2 seconds for invalid inputs. - * Second most popular, ``json-spec``, is even worse with up to 7.2 and 1.7 seconds. - * Last ``validictory``, now deprecated, is much better with 370 or 23 milliseconds, - but it does not follow all standards, and it can be still slow for some purposes. - -With this library you can gain big improvements as ``fastjsonschema`` takes -only about 25 milliseconds for valid inputs and 2 milliseconds for invalid ones. -Pretty amazing, right? :-) - -Technically it works by generating the most stupid code on the fly, which is fast but -is hard to write by hand. The best efficiency is achieved when a validator is compiled -once and used many times, of course. It works similarly like regular expressions. But -you can also generate the code to a file, which is even slightly faster. - -You can run the performance benchmarks on your computer or server with the included -script: - -.. code-block:: bash - - $ make performance - fast_compiled valid ==> 0.0993900 - fast_compiled invalid ==> 0.0041089 - fast_compiled_without_exc valid ==> 0.0465258 - fast_compiled_without_exc invalid ==> 0.0023688 - fast_file valid ==> 0.0989483 - fast_file invalid ==> 0.0041104 - fast_not_compiled valid ==> 11.9572681 - fast_not_compiled invalid ==> 2.9512092 - jsonschema valid ==> 5.2233240 - jsonschema invalid ==> 1.3227916 - jsonschema_compiled valid ==> 0.4447982 - jsonschema_compiled invalid ==> 0.0231333 - jsonspec valid ==> 4.1450569 - jsonspec invalid ==> 1.0485777 - validictory valid ==> 0.2730411 - validictory invalid ==> 0.0183669 - -This library follows and implements `JSON schema draft-04, draft-06, and draft-07 -`_. Sometimes it's not perfectly clear, so I recommend also -check out this `understanding JSON schema `_. - -Note that there are some differences compared to JSON schema standard: - - * Regular expressions are full Python ones, not only what JSON schema allows. It's easier - to allow everything, and also it's faster to compile without limits. So keep in mind that when - you will use a more advanced regular expression, it may not work with other libraries or in - other languages. - * Because Python matches new line for a dollar in regular expressions (``a$`` matches ``a`` and ``a\\n``), - instead of ``$`` is used ``\Z`` and all dollars in your regular expression are changed to ``\\Z`` - as well. When you want to use dollar as regular character, you have to escape it (``\$``). - * JSON schema says you can use keyword ``default`` for providing default values. This implementation - uses that and always returns transformed input data. - -Usage -***** - -.. code-block:: python - - import fastjsonschema - - point_schema = { - "type": "object", - "properties": { - "x": { - "type": "number", - }, - "y": { - "type": "number", - }, - }, - "required": ["x", "y"], - "additionalProperties": False, - } - - point_validator = fastjsonschema.compile(point_schema) - try: - point_validator({"x": 1.0, "y": 2.0}) - except fastjsonschema.JsonSchemaException as e: - print(f"Data failed validation: {e}") - -API -*** -""" -from collections.abc import Callable, Mapping -from functools import partial, update_wrapper -from typing import Any - -from .draft04 import CodeGeneratorDraft04 -from .draft06 import CodeGeneratorDraft06 -from .draft07 import CodeGeneratorDraft07 -from .draft2019 import CodeGeneratorDraft2019 -from .exceptions import ( - JsonSchemaException, - JsonSchemaValueException, - JsonSchemaValuesException, - JsonSchemaDefinitionException, -) -from .ref_resolver import RefResolver -from .version import VERSION - -__all__ = ( - 'VERSION', - 'JsonSchemaException', - 'JsonSchemaValueException', - 'JsonSchemaValuesException', - 'JsonSchemaDefinitionException', - 'validate', - 'compile', - 'compile_to_code', -) - - -Definition = dict[str, Any] | bool -Handlers = Mapping[str, Callable[[str], Any]] -Formats = Mapping[str, str | Callable[[Any], bool]] -Validator = Callable[..., Any] - - -def validate( - definition: Definition, - data: Any, - handlers: Handlers = {}, - formats: Formats = {}, - use_default: bool = True, - use_formats: bool = True, - detailed_exceptions: bool = True, - fast_fail: bool = True, -) -> Any: - """ - Validation function for lazy programmers or for use cases when you need - to call validation only once, so you do not have to compile it first. - Use it only when you do not care about performance (even though it will - be still faster than alternative implementations). - - .. code-block:: python - - import fastjsonschema - - fastjsonschema.validate({'type': 'string'}, 'hello') - # same as: compile({'type': 'string'})('hello') - - Preferred is to use :any:`compile` function. - - The ``handlers`` parameter controls resolution of remote ``$ref`` URIs; see - :any:`compile` for details and security considerations when schemas are not - fully trusted. - """ - return compile(definition, handlers, formats, use_default, use_formats, detailed_exceptions, fast_fail)(data) - - -#TODO: Change use_default to False when upgrading to version 3. -# pylint: disable=redefined-builtin,dangerous-default-value,exec-used -def compile( - definition: Definition, - handlers: Handlers = {}, - formats: Formats = {}, - use_default: bool = True, - use_formats: bool = True, - detailed_exceptions: bool = True, - fast_fail: bool = True, -) -> Validator: - """ - Generates validation function for validating JSON schema passed in ``definition``. - Example: - - .. code-block:: python - - import fastjsonschema - - validate = fastjsonschema.compile({'type': 'string'}) - validate('hello') - - This implementation supports keyword ``default`` (can be turned off - by passing `use_default=False`): - - .. code-block:: python - - validate = fastjsonschema.compile({ - 'type': 'object', - 'properties': { - 'a': {'type': 'number', 'default': 42}, - }, - }) - - data = validate({}) - assert data == {'a': 42} - - Supported implementations are draft-04, draft-06 and draft-07. Which version - should be used is determined by `$draft` in your ``definition``. When not - specified, the latest implementation is used (draft-07). - - .. code-block:: python - - validate = fastjsonschema.compile({ - '$schema': 'http://json-schema.org/draft-04/schema', - 'type': 'number', - }) - - You can pass mapping from URI scheme to function that should be used to - retrieve remote references used in your ``definition`` in parameter - ``handlers``. When no handler is registered for a scheme, the URI is - fetched automatically via :mod:`urllib` (for example ``http``, ``https``, - or ``file`` URLs). - - .. warning:: - - Do not compile or validate untrusted schemas without custom - ``handlers``. A schema containing ``$ref`` can trigger outbound HTTP - requests to arbitrary URLs, including internal or loopback addresses - (server-side request forgery). Provide ``handlers`` to restrict which - URIs are resolved, or pre-resolve references before passing the schema - to this library. - - .. code-block:: python - - def http_handler(uri): - if not uri.startswith('https://schemas.example.com/'): - raise ValueError('ref not allowed') - import urllib.request - with urllib.request.urlopen(uri) as response: - return json.loads(response.read()) - - validate = fastjsonschema.compile(definition, handlers={ - 'http': http_handler, - 'https': http_handler, - }) - - Also, you can pass mapping for custom formats. Key is the name of your - formatter and value can be regular expression, which will be compiled or - callback returning `bool` (or you can raise your own exception). - - .. code-block:: python - - validate = fastjsonschema.compile(definition, formats={ - 'foo': r'foo|bar', - 'bar': lambda value: value in ('foo', 'bar'), - }) - - Note that formats are automatically used as assertions. It can be turned - off by passing `use_formats=False`. When disabled, custom formats are - disabled as well. (Added in 2.19.0.) - - If you don't need detailed exceptions, you can turn the details off and gain - additional performance by passing `detailed_exceptions=False`. - - By default, the execution stops with the first validation error. If you need - to collect all the errors, turn this off by passing `fast_fail=False`. - - Exception :any:`JsonSchemaDefinitionException` is raised when generating the - code fails (bad definition). - - Exception :any:`JsonSchemaValueException` is raised from generated function when - validation fails (data do not follow the definition). - - Exception :any:`JsonSchemaValuesException` is raised from generated function when - validation fails (data do not follow the definition) contatining all the errors - (when fast_fail is set to `False`). - """ - resolver, code_generator = _factory( - definition, - handlers, - formats, - use_default, - use_formats, - detailed_exceptions, - fast_fail, - ) - global_state = code_generator.global_state - # Do not pass local state so it can recursively call itself. - exec(code_generator.func_code, global_state) - func = global_state[resolver.get_scope_name()] - if formats: - return update_wrapper(partial(func, custom_formats=formats), func) - return func - - -# pylint: disable=dangerous-default-value -def compile_to_code( - definition: Definition, - handlers: Handlers = {}, - formats: Formats = {}, - use_default: bool = True, - use_formats: bool = True, - detailed_exceptions: bool = True, - fast_fail: bool = True, -) -> str: - """ - Generates validation code for validating JSON schema passed in ``definition``. - Example: - - .. code-block:: python - - import fastjsonschema - - code = fastjsonschema.compile_to_code({'type': 'string'}) - with open('your_file.py', 'w') as f: - f.write(code) - - You can also use it as a script: - - .. code-block:: bash - - echo "{'type': 'string'}" | python3 -m fastjsonschema > your_file.py - python3 -m fastjsonschema "{'type': 'string'}" > your_file.py - - Exception :any:`JsonSchemaDefinitionException` is raised when generating the - code fails (bad definition). - - Remote ``$ref`` URIs are resolved the same way as in :any:`compile`; see its - documentation for ``handlers`` and security considerations. - """ - _, code_generator = _factory( - definition, - handlers, - formats, - use_default, - use_formats, - detailed_exceptions, - fast_fail, - ) - return ( - 'VERSION = "' + VERSION + '"\n' + - code_generator.global_state_code + '\n' + - code_generator.func_code - ) - - -def _factory( - definition: Definition, - handlers: Handlers, - formats: Formats = {}, - use_default: bool = True, - use_formats: bool = True, - detailed_exceptions: bool = True, - fast_fail: bool = True, -) -> tuple[RefResolver, CodeGeneratorDraft04]: - resolver = RefResolver.from_schema(definition, handlers=handlers, store={}) - code_generator = _get_code_generator_class(definition)( - definition, - resolver=resolver, - formats=formats, - use_default=use_default, - use_formats=use_formats, - detailed_exceptions=detailed_exceptions, - fast_fail=fast_fail, - ) - return resolver, code_generator - - -def _get_code_generator_class(schema: Definition) -> type[CodeGeneratorDraft04]: - # Schema in from draft-06 can be just the boolean value. - if isinstance(schema, dict): - schema_version = schema.get('$schema', '') - if 'draft-04' in schema_version: - return CodeGeneratorDraft04 - if 'draft-06' in schema_version: - return CodeGeneratorDraft06 - if 'draft-07' in schema_version: - return CodeGeneratorDraft07 - if 'draft/2019' in schema_version or 'draft-2019' in schema_version: - return CodeGeneratorDraft2019 - return CodeGeneratorDraft2019 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py deleted file mode 100644 index 9d8eca36f5e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft04.py +++ /dev/null @@ -1,686 +0,0 @@ -import decimal -import re - -from .exceptions import JsonSchemaDefinitionException -from .generator import VALIDATION_EXCEPTIONS, CodeGenerator, enforce_list, repr_default - - -JSON_TYPE_TO_PYTHON_TYPE = { - 'null': 'NoneType', - 'boolean': 'bool', - 'number': 'int, float, Decimal', - 'integer': 'int', - 'string': 'str', - 'array': 'list, tuple', - 'object': 'dict', -} - -DOLLAR_FINDER = re.compile(r"(? {maxLength}:'): - self.exc('{name} must be shorter than or equal to {maxLength} characters', rule='maxLength') - - def generate_pattern(self): - with self.l('if isinstance({variable}, str):'): - pattern = self._definition['pattern'] - safe_pattern = self.e(pattern) - end_of_string_fixed_pattern = DOLLAR_FINDER.sub(r'\\Z', pattern) - self._compile_regexps[pattern] = re.compile(end_of_string_fixed_pattern) - with self.l('if not REGEX_PATTERNS[{}].search({variable}):', repr(pattern)): - self.exc('{name} must match pattern {}', safe_pattern, rule='pattern') - - def generate_format(self): - """ - Means that value have to be in specified format. For example date, email or other. - - .. code-block:: python - - {'format': 'email'} - - Valid value for this definition is user@example.com but not @username - """ - if not self._use_formats: - return - format_ = self._definition['format'] - if format_ not in self._custom_formats and format_ not in self.FORMAT_REGEXS and format_ != 'regex': - return - with self.l('if isinstance({variable}, str):'): - # Checking custom formats - user is allowed to override default formats. - if format_ in self._custom_formats: - custom_format = self._custom_formats[format_] - if isinstance(custom_format, str): - self._generate_format(format_, format_ + '_re_pattern', custom_format) - else: - with self.l('if not custom_formats["{}"]({variable}):', format_): - self.exc('{name} must be {}', format_, rule='format') - elif format_ in self.FORMAT_REGEXS: - format_regex = self.FORMAT_REGEXS[format_] - self._generate_format(format_, format_ + '_re_pattern', format_regex) - # Format regex is used only in meta schemas. - elif format_ == 'regex': - self._extra_imports_lines = ['import re'] - with self.l('try:', optimize=False): - self.l('re.compile({variable})') - with self.l('except Exception:'): - self.exc('{name} must be a valid regex', rule='format') - - - def _generate_format(self, format_name, regexp_name, regexp): - if self._definition['format'] == format_name: - if not regexp_name in self._compile_regexps: - self._compile_regexps[regexp_name] = re.compile(regexp) - with self.l('if not REGEX_PATTERNS["{}"].match({variable}):', regexp_name): - self.exc('{name} must be {}', format_name, rule='format') - - def generate_minimum(self): - with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): - if not isinstance(self._definition['minimum'], (int, float, decimal.Decimal)): - raise JsonSchemaDefinitionException('minimum must be a number') - if self._definition.get('exclusiveMinimum', False): - with self.l('if {variable} <= {minimum}:'): - self.exc('{name} must be bigger than {minimum}', rule='minimum') - else: - with self.l('if {variable} < {minimum}:'): - self.exc('{name} must be bigger than or equal to {minimum}', rule='minimum') - - def generate_maximum(self): - with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): - if not isinstance(self._definition['maximum'], (int, float, decimal.Decimal)): - raise JsonSchemaDefinitionException('maximum must be a number') - if self._definition.get('exclusiveMaximum', False): - with self.l('if {variable} >= {maximum}:'): - self.exc('{name} must be smaller than {maximum}', rule='maximum') - else: - with self.l('if {variable} > {maximum}:'): - self.exc('{name} must be smaller than or equal to {maximum}', rule='maximum') - - def generate_multiple_of(self): - with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): - if not isinstance(self._definition['multipleOf'], (int, float, decimal.Decimal)): - raise JsonSchemaDefinitionException('multipleOf must be a number') - # Integer division through a float loses precision or can overflow. - with self.l('if isinstance({variable}, int) and isinstance({multipleOf}, int):'): - with self.l('if {variable} % {multipleOf} != 0:'): - self.exc('{name} must be multiple of {multipleOf}', rule='multipleOf') - with self.l('else:'): - # For proper multiplication check of floats we need to use decimals, - # because for example 19.01 / 0.01 = 1901.0000000000002. - if isinstance(self._definition['multipleOf'], float): - self.l('quotient = Decimal(repr({variable})) / Decimal(repr({multipleOf}))') - else: - self.l('quotient = {variable} / {multipleOf}') - with self.l('if int(quotient) != quotient:'): - self.exc('{name} must be multiple of {multipleOf}', rule='multipleOf') - # For example, 1e308 / 0.123456789 - with self.l('if {variable} / {multipleOf} == float("inf"):'): - self.exc('inifinity reached', rule='multipleOf') - - def generate_min_items(self): - self.create_variable_is_list() - with self.l('if {variable}_is_list:'): - if not isinstance(self._definition['minItems'], (int, float)): - raise JsonSchemaDefinitionException('minItems must be a number') - self.create_variable_with_length() - with self.l('if {variable}_len < {minItems}:'): - self.exc('{name} must contain at least {minItems} items', rule='minItems') - - def generate_max_items(self): - self.create_variable_is_list() - with self.l('if {variable}_is_list:'): - if not isinstance(self._definition['maxItems'], (int, float)): - raise JsonSchemaDefinitionException('maxItems must be a number') - self.create_variable_with_length() - with self.l('if {variable}_len > {maxItems}:'): - self.exc('{name} must contain less than or equal to {maxItems} items', rule='maxItems') - - def generate_unique_items(self): - """ - With Python 3.4 module ``timeit`` recommended this solutions: - - .. code-block:: python - - >>> timeit.timeit("len(x) > len(set(x))", "x=range(100)+range(100)", number=100000) - 0.5839540958404541 - >>> timeit.timeit("len({}.fromkeys(x)) == len(x)", "x=range(100)+range(100)", number=100000) - 0.7094449996948242 - >>> timeit.timeit("seen = set(); any(i in seen or seen.add(i) for i in x)", "x=range(100)+range(100)", number=100000) - 2.0819358825683594 - >>> timeit.timeit("np.unique(x).size == len(x)", "x=range(100)+range(100); import numpy as np", number=100000) - 2.1439831256866455 - """ - unique_definition = self._definition['uniqueItems'] - if not unique_definition: - return - - self.create_variable_is_list() - with self.l('if {variable}_is_list:'): - self.l( - 'def fn(var): ' - 'return frozenset(dict((k, fn(v)) ' - 'for k, v in var.items()).items()) ' - 'if hasattr(var, "items") else tuple(fn(v) ' - 'for v in var) ' - 'if isinstance(var, (dict, list)) else (bool, var) ' - 'if isinstance(var, bool) else var') - self.create_variable_with_length() - with self.l('if {variable}_len > len(set(fn({variable}_x) for {variable}_x in {variable})):'): - self.exc('{name} must contain unique items', rule='uniqueItems') - - def generate_items(self): - """ - Means array is valid only when all items are valid by this definition. - - .. code-block:: python - - { - 'items': [ - {'type': 'integer'}, - {'type': 'string'}, - ], - } - - Valid arrays are those with integers or strings, nothing else. - - Since draft 06 definition can be also boolean. True means nothing, False - means everything is invalid. - """ - items_definition = self._definition['items'] - if items_definition is True: - return - - self.create_variable_is_list() - with self.l('if {variable}_is_list:'): - self.create_variable_with_length() - if items_definition is False: - with self.l('if {variable}:'): - self.exc('{name} must not be there', rule='items') - elif isinstance(items_definition, list): - for idx, item_definition in enumerate(items_definition): - with self.l('if {variable}_len > {}:', idx): - self.l('{variable}__{0} = {variable}[{0}]', idx) - self.generate_func_code_block( - item_definition, - '{}__{}'.format(self._variable, idx), - '{}[{}]'.format(self._variable_name, idx), - ) - if self._use_default and isinstance(item_definition, dict) and 'default' in item_definition: - self.l('else: {variable}.append({})', repr_default(item_definition['default'])) - - if 'additionalItems' in self._definition: - if self._definition['additionalItems'] is False: - with self.l('if {variable}_len > {}:', len(items_definition)): - self.exc('{name} must contain only specified items', rule='items') - else: - with self.l('for {variable}_x, {variable}_item in enumerate({variable}[{0}:], {0}):', len(items_definition)): - code_len = len(self._code) - self.generate_func_code_block( - self._definition['additionalItems'], - '{}_item'.format(self._variable), - '{}[{{{}_x}}]'.format(self._variable_name, self._variable), - ) - if len(self._code) == code_len: - self.l('pass') - else: - if items_definition: - with self.l('for {variable}_x, {variable}_item in enumerate({variable}):'): - code_len = len(self._code) - self.generate_func_code_block( - items_definition, - '{}_item'.format(self._variable), - '{}[{{{}_x}}]'.format(self._variable_name, self._variable), - ) - if len(self._code) == code_len: - self.l('pass') - - def generate_min_properties(self): - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - if not isinstance(self._definition['minProperties'], (int, float)): - raise JsonSchemaDefinitionException('minProperties must be a number') - self.create_variable_with_length() - with self.l('if {variable}_len < {minProperties}:'): - self.exc('{name} must contain at least {minProperties} properties', rule='minProperties') - - def generate_max_properties(self): - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - if not isinstance(self._definition['maxProperties'], (int, float)): - raise JsonSchemaDefinitionException('maxProperties must be a number') - self.create_variable_with_length() - with self.l('if {variable}_len > {maxProperties}:'): - self.exc('{name} must contain less than or equal to {maxProperties} properties', rule='maxProperties') - - def generate_required(self): - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - if not isinstance(self._definition['required'], (list, tuple)): - raise JsonSchemaDefinitionException('required must be an array') - if len(self._definition['required']) != len(set(self._definition['required'])): - raise JsonSchemaDefinitionException('required must contain unique elements') - if not self._definition.get('additionalProperties', True): - not_possible = [ - prop - for prop in self._definition['required'] - if - prop not in self._definition.get('properties', {}) - and not any(re.search(regex, prop) for regex in self._definition.get('patternProperties', {})) - ] - if not_possible: - raise JsonSchemaDefinitionException('{}: items {} are required but not allowed'.format(self._variable, not_possible)) - self.l('{variable}__missing_keys = set({required}) - {variable}.keys()') - with self.l('if {variable}__missing_keys:'): - dynamic = 'str(sorted({variable}__missing_keys)) + " properties"' - self.exc('{name} must contain ', self.e(self._definition['required']), rule='required', append_to_msg=dynamic) - - def generate_properties(self): - """ - Means object with defined keys. - - .. code-block:: python - - { - 'properties': { - 'key': {'type': 'number'}, - }, - } - - Valid object is containing key called 'key' and value any number. - """ - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - self.create_variable_keys() - for key, prop_definition in self._definition['properties'].items(): - key_name = re.sub(r'($[^a-zA-Z]|[^a-zA-Z0-9])', '', key) - if not isinstance(prop_definition, (dict, bool)): - raise JsonSchemaDefinitionException('{}[{}] must be object'.format(self._variable, key_name)) - with self.l('if "{}" in {variable}_keys:', self.e(key)): - self.l('{variable}_keys.remove("{}")', self.e(key)) - self.l('{variable}__{0} = {variable}["{1}"]', key_name, self.e(key)) - self.generate_func_code_block( - prop_definition, - '{}__{}'.format(self._variable, key_name), - '{}.{}'.format(self._variable_name, self.e(key).replace('{', '{{').replace('}', '}}')), - clear_variables=True, - ) - if self._use_default and isinstance(prop_definition, dict) and 'default' in prop_definition: - self.l('else: {variable}["{}"] = {}', self.e(key), repr_default(prop_definition['default'])) - - def generate_pattern_properties(self): - """ - Means object with defined keys as patterns. - - .. code-block:: python - - { - 'patternProperties': { - '^x': {'type': 'number'}, - }, - } - - Valid object is containing key starting with a 'x' and value any number. - """ - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - self.create_variable_keys() - pattern_prop_definition = self._definition['patternProperties'] - if pattern_prop_definition == {}: - return - for pattern, definition in pattern_prop_definition.items(): - self._compile_regexps[pattern] = re.compile(pattern) - with self.l('for {variable}_key, {variable}_val in {variable}.items():'): - for pattern, definition in self._definition['patternProperties'].items(): - with self.l('if REGEX_PATTERNS[{}].search({variable}_key):', repr(pattern)): - with self.l('if {variable}_key in {variable}_keys:'): - self.l('{variable}_keys.remove({variable}_key)') - self.generate_func_code_block( - definition, - '{}_val'.format(self._variable), - '{}.{{{}_key}}'.format(self._variable_name, self._variable), - clear_variables=True, - ) - - def generate_additional_properties(self): - """ - Means object with keys with values defined by definition. - - .. code-block:: python - - { - 'properties': { - 'key': {'type': 'number'}, - } - 'additionalProperties': {'type': 'string'}, - } - - Valid object is containing key called 'key' and it's value any number and - any other key with any string. - """ - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - self.create_variable_keys() - add_prop_definition = self._definition["additionalProperties"] - if add_prop_definition is True or add_prop_definition == {}: - return - if add_prop_definition: - properties_keys = list(self._definition.get("properties", {}).keys()) - with self.l('for {variable}_key in {variable}_keys:'): - with self.l('if {variable}_key not in {}:', properties_keys): - self.l('{variable}_value = {variable}.get({variable}_key)') - self.generate_func_code_block( - add_prop_definition, - '{}_value'.format(self._variable), - '{}.{{{}_key}}'.format(self._variable_name, self._variable), - ) - else: - with self.l('if {variable}_keys:'): - self.exc('{name} must not contain "+str({variable}_keys)+" properties', rule='additionalProperties') - - def generate_dependencies(self): - """ - Means when object has property, it needs to have also other property. - - .. code-block:: python - - { - 'dependencies': { - 'bar': ['foo'], - }, - } - - Valid object is containing only foo, both bar and foo or none of them, but not - object with only bar. - - Since draft 06 definition can be boolean or empty array. True and empty array - means nothing, False means that key cannot be there at all. - """ - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - is_empty = True - for key, values in self._definition["dependencies"].items(): - if values == [] or values is True: - continue - is_empty = False - with self.l('if "{}" in {variable}:', self.e(key)): - if values is False: - self.exc('{} in {name} must not be there', self.e(key), rule='dependencies') - elif isinstance(values, list): - for value in values: - with self.l('if "{}" not in {variable}:', self.e(value)): - self.exc('{name} missing dependency {} for {}', self.e(value), self.e(key), rule='dependencies') - else: - code_len = len(self._code) - self.generate_func_code_block(values, self._variable, self._variable_name, clear_variables=True) - if len(self._code) == code_len: - self.l('pass') - if is_empty: - self.l('pass') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py deleted file mode 100644 index 30eb517ad43..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft06.py +++ /dev/null @@ -1,222 +0,0 @@ -import decimal -from .draft04 import CodeGeneratorDraft04, JSON_TYPE_TO_PYTHON_TYPE -from .exceptions import JsonSchemaDefinitionException -from .generator import VALIDATION_EXCEPTIONS, enforce_list - - -class CodeGeneratorDraft06(CodeGeneratorDraft04): - FORMAT_REGEXS = dict(CodeGeneratorDraft04.FORMAT_REGEXS, **{ - 'json-pointer': r'^(/(([^/~])|(~[01]))*)*\Z', - 'uri-reference': r'^(\w+:(\/?\/?))?[^#\\\s]*(#[^\\\s]*)?\Z', - 'uri-template': ( - r'^(?:(?:[^\x00-\x20\"\'<>%\\^`{|}]|%[0-9a-f]{2})|' - r'\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+' - r'(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+' - r'(?::[1-9][0-9]{0,3}|\*)?)*\})*\Z' - ), - }) - - def __init__( - self, - definition, - resolver=None, - formats={}, - use_default=True, - use_formats=True, - detailed_exceptions=True, - fast_fail=True, - ): - super().__init__(definition, resolver, formats, use_default, use_formats, detailed_exceptions, fast_fail) - self._json_keywords_to_function.update(( - ('exclusiveMinimum', self.generate_exclusive_minimum), - ('exclusiveMaximum', self.generate_exclusive_maximum), - ('propertyNames', self.generate_property_names), - ('contains', self.generate_contains), - ('const', self.generate_const), - )) - - def _generate_func_code_block(self, definition): - if isinstance(definition, bool): - return self.generate_boolean_schema() - elif '$ref' in definition: - # needed because ref overrides any sibling keywords - return self.generate_ref() - return self.run_generate_functions(definition) - - def generate_boolean_schema(self): - """ - Means that schema can be specified by boolean. - True means everything is valid, False everything is invalid. - """ - if self._definition is True: - self.l('pass') - if self._definition is False: - self.exc('{name} must not be there') - - def generate_type(self): - """ - Validation of type. Can be one type or list of types. - - Since draft 06 a float without fractional part is an integer. - - .. code-block:: python - - {'type': 'string'} - {'type': ['string', 'number']} - """ - types = enforce_list(self._definition['type']) - try: - python_types = ', '.join(JSON_TYPE_TO_PYTHON_TYPE[t] for t in types) - except KeyError as exc: - raise JsonSchemaDefinitionException('Unknown type') from exc - - extra = '' - - if 'integer' in types: - extra += ' and not (isinstance({variable}, float) and {variable}.is_integer())'.format( - variable=self._variable, - ) - - if ('number' in types or 'integer' in types) and 'boolean' not in types: - extra += ' or isinstance({variable}, bool)'.format(variable=self._variable) - - with self.l('if not isinstance({variable}, ({})){}:', python_types, extra): - self.exc('{name} must be {}', ' or '.join(types), rule='type') - - def generate_minimum(self): - """ - Since draft 06 exclusiveMinimum is a number validated on its own, - so minimum is always inclusive. - """ - with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): - if not isinstance(self._definition['minimum'], (int, float, decimal.Decimal)): - raise JsonSchemaDefinitionException('minimum must be a number') - with self.l('if {variable} < {minimum}:'): - self.exc('{name} must be bigger than or equal to {minimum}', rule='minimum') - - def generate_maximum(self): - """ - Since draft 06 exclusiveMaximum is a number validated on its own, - so maximum is always inclusive. - """ - with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): - if not isinstance(self._definition['maximum'], (int, float, decimal.Decimal)): - raise JsonSchemaDefinitionException('maximum must be a number') - with self.l('if {variable} > {maximum}:'): - self.exc('{name} must be smaller than or equal to {maximum}', rule='maximum') - - def generate_exclusive_minimum(self): - with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): - if not isinstance(self._definition['exclusiveMinimum'], (int, float, decimal.Decimal)): - raise JsonSchemaDefinitionException('exclusiveMinimum must be an integer, a float or a decimal') - with self.l('if {variable} <= {exclusiveMinimum}:'): - self.exc('{name} must be bigger than {exclusiveMinimum}', rule='exclusiveMinimum') - - def generate_exclusive_maximum(self): - with self.l('if isinstance({variable}, (int, float, Decimal)) and not isinstance({variable}, bool):'): - if not isinstance(self._definition['exclusiveMaximum'], (int, float, decimal.Decimal)): - raise JsonSchemaDefinitionException('exclusiveMaximum must be an integer, a float or a decimal') - with self.l('if {variable} >= {exclusiveMaximum}:'): - self.exc('{name} must be smaller than {exclusiveMaximum}', rule='exclusiveMaximum') - - def generate_property_names(self): - """ - Means that keys of object must to follow this definition. - - .. code-block:: python - - { - 'propertyNames': { - 'maxLength': 3, - }, - } - - Valid keys of object for this definition are foo, bar, ... but not foobar for example. - """ - property_names_definition = self._definition.get('propertyNames', {}) - if property_names_definition is True: - pass - elif property_names_definition is False: - self.create_variable_is_dict() - with self.l('if {variable}_is_dict and {variable}:'): - self.exc('{name} must not be there', rule='propertyNames') - else: - self.create_variable_is_dict() - with self.l('if {variable}_is_dict:'): - self.create_variable_with_length() - with self.l('if {variable}_len != 0:'): - self.l('{variable}_property_names = True') - with self.l('for {variable}_key in {variable}:'): - with self.l('try:'): - code_len = len(self._code) - with self.trial_validation(): - self.generate_func_code_block( - property_names_definition, - '{}_key'.format(self._variable), - self._variable_name, - clear_variables=True, - ) - if len(self._code) == code_len: - self.l('pass') - with self.l('except {}:', VALIDATION_EXCEPTIONS): - self.l('{variable}_property_names = False') - with self.l('if not {variable}_property_names:'): - self.exc('{name} must be named by propertyName definition', rule='propertyNames') - - def generate_contains(self): - """ - Means that array must contain at least one defined item. - - .. code-block:: python - - { - 'contains': { - 'type': 'number', - }, - } - - Valid array is any with at least one number. - """ - self.create_variable_is_list() - with self.l('if {variable}_is_list:'): - contains_definition = self._definition['contains'] - - if contains_definition is False: - self.exc('{name} is always invalid', rule='contains') - elif contains_definition is True: - with self.l('if not {variable}:'): - self.exc('{name} must not be empty', rule='contains') - else: - self.l('{variable}_contains = False') - with self.l('for {variable}_key in {variable}:'): - with self.l('try:'): - with self.trial_validation(): - self.generate_func_code_block( - contains_definition, - '{}_key'.format(self._variable), - self._variable_name, - clear_variables=True, - ) - self.l('{variable}_contains = True') - self.l('break') - self.l('except {}: pass', VALIDATION_EXCEPTIONS) - - with self.l('if not {variable}_contains:'): - self.exc('{name} must contain one of contains definition', rule='contains') - - def generate_const(self): - """ - Means that value is valid when is equeal to const definition. - - .. code-block:: python - - { - 'const': 42, - } - - Only valid value is 42 in this example. - """ - const = self._definition['const'] - match = self._enum_value_matches(self._variable, const) - with self.l('if not ({}):', match): - self.exc('{name} must be same as const definition: {definition_rule}', rule='const') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py deleted file mode 100644 index 86476e7cdb9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft07.py +++ /dev/null @@ -1,138 +0,0 @@ -from .draft04 import DATE_REGEX -from .draft06 import CodeGeneratorDraft06 -from .generator import VALIDATION_EXCEPTIONS - - -class CodeGeneratorDraft07(CodeGeneratorDraft06): - FORMAT_REGEXS = dict(CodeGeneratorDraft06.FORMAT_REGEXS, **{ - 'date': r'^(?:' + DATE_REGEX + r')\Z', - 'iri': r'^\w+:(\/?\/?)[^\s]+\Z', - 'iri-reference': r'^(\w+:(\/?\/?))?[^#\\\s]*(#[^\\\s]*)?\Z', - 'idn-email': r'^[^@]+@[^@]+\.[^@]+\Z', - # pylint: disable=line-too-long - 'idn-hostname': r'^(?!-)(xn--)?[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.(?!-)(xn--)?([a-zA-Z0-9\-]{1,50}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,})$', - 'relative-json-pointer': r'^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)\Z', - #'regex': r'', - 'time': ( - r'^(?P[01]?\d|2[0-3]):(?P[0-5]?\d)' - r'(?::(?P[0-5]?\d|60)(?:\.(?P\d{1,6}))?' - r'([zZ]|[+-](?:[01]\d|2[0-3]):[0-5]\d)?)?\Z' - ), - }) - - def __init__( - self, - definition, - resolver=None, - formats={}, - use_default=True, - use_formats=True, - detailed_exceptions=True, - fast_fail=True - ): - super().__init__(definition, resolver, formats, use_default, use_formats, detailed_exceptions, fast_fail) - # pylint: disable=duplicate-code - self._json_keywords_to_function.update(( - ('if', self.generate_if_then_else), - ('contentEncoding', self.generate_content_encoding), - ('contentMediaType', self.generate_content_media_type), - )) - - def generate_if_then_else(self): - """ - Implementation of if-then-else. - - .. code-block:: python - - { - 'if': { - 'exclusiveMaximum': 0, - }, - 'then': { - 'minimum': -10, - }, - 'else': { - 'multipleOf': 2, - }, - } - - Valid values are any between -10 and 0 or any multiplication of two. - """ - with self.l('try:', optimize=False): - code_len = len(self._code) - with self.trial_validation(): - self.generate_func_code_block( - self._definition['if'], - self._variable, - self._variable_name, - clear_variables=True - ) - if len(self._code) == code_len: - self.l('pass') - with self.l('except {}:', VALIDATION_EXCEPTIONS): - if 'else' in self._definition: - code_len = len(self._code) - self.generate_func_code_block( - self._definition['else'], - self._variable, - self._variable_name, - clear_variables=True - ) - if len(self._code) == code_len: - self.l('pass') - else: - self.l('pass') - if 'then' in self._definition: - with self.l('else:'): - code_len = len(self._code) - self.generate_func_code_block( - self._definition['then'], - self._variable, - self._variable_name, - clear_variables=True - ) - if len(self._code) == code_len: - self.l('pass') - - def generate_content_encoding(self): - """ - Means decoding value when it's encoded by base64. - - .. code-block:: python - - { - 'contentEncoding': 'base64', - } - """ - if self._definition['contentEncoding'] == 'base64': - with self.l('if isinstance({variable}, str):'): - with self.l('try:'): - self.l('import base64') - self.l('{variable} = base64.b64decode({variable})') - with self.l('except Exception:'): - self.exc('{name} must be encoded by base64') - with self.l('if {variable} == "":'): - self.exc('contentEncoding must be base64') - - def generate_content_media_type(self): - """ - Means loading value when it's specified as JSON. - - .. code-block:: python - - { - 'contentMediaType': 'application/json', - } - """ - if self._definition['contentMediaType'] == 'application/json': - with self.l('if isinstance({variable}, bytes):'): - with self.l('try:'): - self.l('{variable} = {variable}.decode("utf-8")') - with self.l('except Exception:'): - self.exc('{name} must encoded by utf8') - with self.l('if isinstance({variable}, str):'): - with self.l('try:'): - self.l('import json') - self.l('{variable} = json.loads({variable})') - with self.l('except Exception:'): - self.exc('{name} must be valid JSON') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py deleted file mode 100644 index 85c9c128dc2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/draft2019.py +++ /dev/null @@ -1,15 +0,0 @@ -from .draft07 import CodeGeneratorDraft07 - - -class CodeGeneratorDraft2019(CodeGeneratorDraft07): - FORMAT_REGEXS = dict(CodeGeneratorDraft07.FORMAT_REGEXS, **{ - 'uuid': r'^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\Z', - # ISO 8601 duration from RFC 3339 Appendix A - 'duration': ( - r'^P(?!$)' - r'(?:' - r'[0-9]+W' - r'|(?:[0-9]+Y)?(?:[0-9]+M)?(?:[0-9]+D)?(?:T(?=[0-9])(?:[0-9]+H)?(?:[0-9]+M)?(?:[0-9]+S)?)?' - r')\Z' - ), - }) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py deleted file mode 100644 index 1d0d448566b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/exceptions.py +++ /dev/null @@ -1,75 +0,0 @@ -import re -from typing import Any - - -SPLIT_RE = re.compile(r'[\.\[\]]+') - - -class JsonSchemaException(ValueError): - """ - Base exception of ``fastjsonschema`` library. - """ - - -class JsonSchemaValueException(JsonSchemaException): - """ - Exception raised by validation function. Available properties: - - * ``message`` containing human-readable information what is wrong - (e.g. ``data.property[index] must be smaller than or equal to 42``), - * invalid ``value`` (e.g. ``60``), - * ``name`` of a path in the data structure (e.g. ``data.property[index]``), - * ``path`` as an array in the data structure (e.g. ``['data', 'property', 'index']``), - * the whole ``definition`` which the ``value`` has to fulfil (e.g. ``{'type': 'number', 'maximum': 42}``), - * ``rule`` which the ``value`` is breaking (e.g. ``maximum``) - * and ``rule_definition`` (e.g. ``42``). - - .. versionchanged:: 2.14.0 - Added all extra properties. - """ - - def __init__( - self, - message: str, - value: Any = None, - name: str | None = None, - definition: Any = None, - rule: str | None = None, - ) -> None: - super().__init__(message) - self.message = message - self.value = value - self.name = name - self.definition = definition - self.rule = rule - - @property - def path(self) -> list[str]: - return [item for item in SPLIT_RE.split(self.name or '') if item != ''] - - @property - def rule_definition(self) -> Any: - if not self.rule or not self.definition: - return None - return self.definition.get(self.rule) - - -class JsonSchemaValuesException(JsonSchemaException): - """ - Exception raised by validation function when ``fast_fail`` is turned off. - Available properties: - - * ``errors`` containing all :any:`JsonSchemaValueException` found in the data - * and ``message`` joining messages of all the errors. - """ - - def __init__(self, errors: list[JsonSchemaValueException]) -> None: - self.message = '; '.join(error.message for error in errors) - super().__init__(self.message) - self.errors = errors - - -class JsonSchemaDefinitionException(JsonSchemaException): - """ - Exception raised by generator of validation function. - """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py deleted file mode 100644 index 951eddad485..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/generator.py +++ /dev/null @@ -1,429 +0,0 @@ -from collections import OrderedDict -from contextlib import contextmanager -from decimal import Decimal -import re - -from .exceptions import JsonSchemaValueException, JsonSchemaValuesException, JsonSchemaDefinitionException -from .indent import indent -from .ref_resolver import RefResolver - -# Both mean "this subschema did not match": a subschema behind a $ref becomes its own -# function, which reports through JsonSchemaValuesException while errors are collected. -VALIDATION_EXCEPTIONS = '(JsonSchemaValueException, JsonSchemaValuesException)' - - -def enforce_list(variable): - if isinstance(variable, list): - return variable - return [variable] - - -# pylint: disable=too-many-instance-attributes,too-many-public-methods -class CodeGenerator: - """ - This class is not supposed to be used directly. Anything - inside of this class can be changed without noticing. - - This class generates code of validation function from JSON - schema object as string. Example: - - .. code-block:: python - - CodeGenerator(json_schema_definition).func_code - """ - - INDENT = 4 # spaces - - def __init__(self, definition, resolver=None, detailed_exceptions=True, fast_fail=True): - self._code = [] - self._compile_regexps = {} - self._custom_formats = {} - self._detailed_exceptions = detailed_exceptions - self._fast_fail = fast_fail - - # Any extra library should be here to be imported only once. - # Lines are imports to be printed in the file and objects - # key-value pair to pass to compile function directly. - self._extra_imports_lines = [ - "from decimal import Decimal", - ] - self._extra_imports_objects = { - "Decimal": Decimal, - } - - self._variables = {} - self._scope_stack = [] - self._scope_counter = 0 - self._last_closed_scope = None - self._indent = 0 - self._indent_last_line = None - self._variable = None - self._variable_name = None - self._root_definition = definition - self._definition = None - - # map schema URIs to validation function names for functions - # that are not yet generated, but need to be generated - self._needed_validation_functions = {} - # validation function names that are already done - self._validation_functions_done = set() - - if resolver is None: - resolver = RefResolver.from_schema(definition, store={}) - self._resolver = resolver - - # add main function to `self._needed_validation_functions` - self._needed_validation_functions[self._resolver.get_uri()] = self._resolver.get_scope_name() - - self._json_keywords_to_function = OrderedDict() - - @property - def func_code(self): - """ - Returns generated code of whole validation function as string. - """ - self._generate_func_code() - - return '\n'.join(self._code) - - @property - def global_state(self): - """ - Returns global variables for generating function from ``func_code``. Includes - compiled regular expressions and imports, so it does not have to do it every - time when validation function is called. - """ - self._generate_func_code() - - return dict( - **self._extra_imports_objects, - REGEX_PATTERNS=self._compile_regexps, - re=re, - JsonSchemaValueException=JsonSchemaValueException, - JsonSchemaValuesException=JsonSchemaValuesException, - ) - - @property - def global_state_code(self): - """ - Returns global variables for generating function from ``func_code`` as code. - Includes compiled regular expressions and imports. - """ - self._generate_func_code() - - if not self._compile_regexps: - return '\n'.join(self._extra_imports_lines + [ - 'from fastjsonschema import JsonSchemaValueException, JsonSchemaValuesException', - '', - '', - ]) - return '\n'.join(self._extra_imports_lines + [ - 'import re', - 'from fastjsonschema import JsonSchemaValueException, JsonSchemaValuesException', - '', - '', - 'REGEX_PATTERNS = ' + serialize_regexes(self._compile_regexps), - '', - ]) - - - def _generate_func_code(self): - if not self._code: - self.generate_func_code() - - def generate_func_code(self): - """ - Creates base code of validation function and calls helper - for creating code by definition. - """ - self.l('NoneType = type(None)') - # Generate parts that are referenced and not yet generated - while self._needed_validation_functions: - # During generation of validation function, could be needed to generate - # new one that is added again to `_needed_validation_functions`. - # Therefore usage of while instead of for loop. - uri, name = self._needed_validation_functions.popitem() - self.generate_validation_function(uri, name) - - def generate_validation_function(self, uri, name): - """ - Generate validation function for given uri with given name - """ - self._validation_functions_done.add(uri) - self.l('') - with self._resolver.resolving(uri) as definition: - with self.l('def {}(data, custom_formats={{}}, name_prefix=None):', name): - if not self._fast_fail: - self.l('errors = []') - self.generate_func_code_block(definition, 'data', 'data', clear_variables=True) - if not self._fast_fail: - self.l('if errors: raise JsonSchemaValuesException(errors)') - self.l('return data') - - def generate_func_code_block(self, definition, variable, variable_name, clear_variables=False): - """ - Creates validation rules for current definition. - - Returns the number of validation rules generated as code. - """ - backup = self._definition, self._variable, self._variable_name - self._definition, self._variable, self._variable_name = definition, variable, variable_name - if clear_variables: - backup_variables = self._variables - self._variables = {} - - count = self._generate_func_code_block(definition) - - self._definition, self._variable, self._variable_name = backup - if clear_variables: - self._variables = backup_variables - - return count - - @contextmanager - def trial_validation(self): - """ - Subschemas of anyOf, oneOf, not, if, contains and propertyNames are only tried out. - Their failure is control flow for the surrounding ``try``, not an error to report, - so they have to raise even when ``fast_fail`` is off. - """ - fast_fail, self._fast_fail = self._fast_fail, True - try: - yield - finally: - self._fast_fail = fast_fail - - def _generate_func_code_block(self, definition): - if not isinstance(definition, dict): - raise JsonSchemaDefinitionException("definition must be an object") - if '$ref' in definition: - # needed because ref overrides any sibling keywords - return self.generate_ref() - return self.run_generate_functions(definition) - - def run_generate_functions(self, definition): - """Returns the number of generate functions that were executed.""" - count = 0 - for key, func in self._json_keywords_to_function.items(): - if key in definition: - func() - count += 1 - return count - - def generate_ref(self): - """ - Ref can be link to remote or local definition. - - .. code-block:: python - - {'$ref': 'http://json-schema.org/draft-04/schema#'} - { - 'properties': { - 'foo': {'type': 'integer'}, - 'bar': {'$ref': '#/properties/foo'} - } - } - """ - with self._resolver.in_scope(self._definition['$ref']): - name = self._resolver.get_scope_name() - uri = self._resolver.get_uri() - if uri not in self._validation_functions_done: - self._needed_validation_functions[uri] = name - # call validation function - assert self._variable_name.startswith("data") - path = self._variable_name[4:] - name_arg = '(name_prefix or "data") + "{}"'.format(path) - if '{' in name_arg or '}' in name_arg: - name_arg = name_arg + '.format(**locals())' - if self._fast_fail: - self.l('{}({variable}, custom_formats, {name_arg})', name, name_arg=name_arg) - else: - # The referenced function collects into its own list, so merge it into ours - # instead of letting it abort the validation of the rest of the document. - with self.l('try:', optimize=False): - self.l('{}({variable}, custom_formats, {name_arg})', name, name_arg=name_arg) - with self.l('except JsonSchemaValuesException as e:'): - self.l('errors.extend(e.errors)') - - - # pylint: disable=invalid-name - @indent - def l(self, line, *args, **kwds): - """ - Short-cut of line. Used for inserting line. It's formated with parameters - ``variable``, ``variable_name`` (as ``name`` for short-cut), all keys from - current JSON schema ``definition`` and also passed arguments in ``args`` - and named ``kwds``. - - .. code-block:: python - - self.l('if {variable} not in {enum}: raise JsonSchemaValueException("Wrong!")') - - When you want to indent block, use it as context manager. For example: - - .. code-block:: python - - with self.l('if {variable} not in {enum}:'): - self.l('raise JsonSchemaValueException("Wrong!")') - """ - spaces = ' ' * self.INDENT * self._indent - - name = self._variable_name - if name: - # Add name_prefix to the name when it is being outputted. - assert name.startswith('data') - name = '" + (name_prefix or "data") + "' + name[4:] - if '{' in name or '}' in name: - name = name + '".format(**locals()) + "' - - context = dict( - self._definition if self._definition and self._definition is not True else {}, - variable=self._variable, - name=name, - **kwds - ) - line = line.format(*args, **context) - line = line.replace('\n', '\\n').replace('\r', '\\r') - self._code.append(spaces + line) - return line - - def e(self, string): - """ - Short-cut of escape. Used for inserting user values into a string message. - - .. code-block:: python - - self.l('raise JsonSchemaValueException("Variable: {}")', self.e(variable)) - """ - if isinstance(string, str): - return string.encode('unicode_escape').decode('ascii').replace('"', '\\"') - return str(string).replace('"', '\\"') - - def exc(self, msg, *args, append_to_msg=None, rule=None): - """ - Short-cut for creating raising exception in the code. - """ - if not self._detailed_exceptions: - if self._fast_fail: - self.l('raise JsonSchemaValueException("'+msg+'")', *args) - else: - self.l('errors.append(JsonSchemaValueException("'+msg+'"))', *args) - return - - arg = '"'+msg+'"' - if append_to_msg: - arg += ' + (' + append_to_msg + ')' - # pylint: disable=line-too-long - msg = ( - 'raise JsonSchemaValueException('+arg+', value={variable}, name="{name}", definition={definition}, rule={rule})' - if self._fast_fail else - 'errors.append(JsonSchemaValueException('+arg+', value={variable}, name="{name}", definition={definition}, rule={rule}))' - ) - definition = self._expand_refs(self._definition) - definition_rule = self.e(definition.get(rule) if isinstance(definition, dict) else None) - self.l(msg, *args, definition=repr_default(definition), rule=repr(rule), definition_rule=definition_rule) - - def _expand_refs(self, definition): - if isinstance(definition, list): - return [self._expand_refs(v) for v in definition] - if not isinstance(definition, dict): - return definition - if "$ref" in definition and isinstance(definition["$ref"], str): - with self._resolver.resolving(definition["$ref"]) as schema: - return schema - return {k: self._expand_refs(v) for k, v in definition.items()} - - def _is_variable_in_scope(self, variable_name): - """ - Whether ``variable_name`` was already defined in a block enclosing the - current one, and is therefore still bound here. A variable defined in a - sibling block is not, because that block may not have been entered. - """ - scope = self._variables.get(variable_name) - if scope is None: - return False - return tuple(self._scope_stack[:len(scope)]) == scope - - def create_variable_with_length(self): - """ - Append code for creating variable with length of that variable - (for example length of list or dictionary) with name ``{variable}_len``. - It can be called several times and always it's done only when that variable - still does not exists. - """ - variable_name = '{}_len'.format(self._variable) - if self._is_variable_in_scope(variable_name): - return - self._variables[variable_name] = tuple(self._scope_stack) - self.l('{variable}_len = len({variable})') - - def create_variable_keys(self): - """ - Append code for creating variable with keys of that variable (dictionary) - with a name ``{variable}_keys``. Similar to `create_variable_with_length`. - """ - variable_name = '{}_keys'.format(self._variable) - if self._is_variable_in_scope(variable_name): - return - self._variables[variable_name] = tuple(self._scope_stack) - self.l('{variable}_keys = set({variable}.keys())') - - def create_variable_is_list(self): - """ - Append code for creating variable with bool if it's instance of list - with a name ``{variable}_is_list``. Similar to `create_variable_with_length`. - """ - variable_name = '{}_is_list'.format(self._variable) - if self._is_variable_in_scope(variable_name): - return - self._variables[variable_name] = tuple(self._scope_stack) - self.l('{variable}_is_list = isinstance({variable}, (list, tuple))') - - def create_variable_is_dict(self): - """ - Append code for creating variable with bool if it's instance of list - with a name ``{variable}_is_dict``. Similar to `create_variable_with_length`. - """ - variable_name = '{}_is_dict'.format(self._variable) - if self._is_variable_in_scope(variable_name): - return - self._variables[variable_name] = tuple(self._scope_stack) - self.l('{variable}_is_dict = isinstance({variable}, dict)') - - -def serialize_regexes(patterns_dict): - # Unfortunately using `pprint.pformat` is causing errors - # specially with big regexes - regex_patterns = ( - repr(k) + ": " + repr_regex(v) - for k, v in patterns_dict.items() - ) - return '{\n ' + ",\n ".join(regex_patterns) + "\n}" - - -def repr_default(value): - """ - Like ``repr``, but renders non-finite floats as valid Python source. - - ``repr(float('nan'))`` is ``'nan'``, which is not a name available in the - generated code, so a schema default of NaN or infinity has to be written - out as a ``float(...)`` call instead. - """ - if isinstance(value, float) and (value != value or value in (float('inf'), float('-inf'))): - return "float({!r})".format(str(value)) - if isinstance(value, list): - return '[' + ', '.join(repr_default(item) for item in value) + ']' - if isinstance(value, tuple): - return '(' + ''.join(repr_default(item) + ', ' for item in value) + ')' - if isinstance(value, dict): - return '{' + ', '.join( - '{}: {}'.format(repr_default(k), repr_default(v)) for k, v in value.items() - ) + '}' - return repr(value) - - -def repr_regex(regex): - all_flags = ("A", "I", "DEBUG", "L", "M", "S", "X") - flags = " | ".join(f"re.{f}" for f in all_flags if regex.flags & getattr(re, f)) - flags = ", " + flags if flags else "" - return "re.compile({!r}{})".format(regex.pattern, flags) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py deleted file mode 100644 index 9cc011aa805..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/indent.py +++ /dev/null @@ -1,42 +0,0 @@ -# pylint: disable=protected-access - -def indent(func): - """ - Decorator for allowing to use method as normal method or with - context manager for auto-indenting code blocks. - """ - def wrapper(self, line, *args, optimize=True, **kwds): - last_line = self._indent_last_line - line = func(self, line, *args, **kwds) - # When two blocks have the same condition (such as value has to be dict), - # do the check only once and keep it under one block. - merged = optimize and last_line == line - if merged: - self._code.pop() - self._indent_last_line = line - return Indent(self, line, merged=merged) - return wrapper - - -class Indent: - def __init__(self, instance, line, merged=False): - self.instance = instance - self.line = line - self.merged = merged - - def __enter__(self): - self.instance._indent += 1 - # A merged block is a continuation of the block just closed, so it keeps - # its scope; otherwise this is a new scope and variables defined in it - # are not visible to sibling blocks. - if self.merged and self.instance._last_closed_scope is not None: - scope = self.instance._last_closed_scope - else: - self.instance._scope_counter += 1 - scope = self.instance._scope_counter - self.instance._scope_stack.append(scope) - - def __exit__(self, type_, value, traceback): - self.instance._indent -= 1 - self.instance._last_closed_scope = self.instance._scope_stack.pop() - self.instance._indent_last_line = self.line diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py deleted file mode 100644 index 67fcbdd541d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/ref_resolver.py +++ /dev/null @@ -1,219 +0,0 @@ -# pylint: disable=import-outside-toplevel - -""" -JSON Schema URI resolution scopes and dereferencing - -https://tools.ietf.org/id/draft-zyp-json-schema-04.html#rfc.section.7 - -Code adapted from https://github.com/Julian/jsonschema -""" - -import contextlib -import json -import re -import sys -from collections.abc import Callable, Iterator, Mapping -from typing import Any -from urllib import parse as urlparse -from urllib.parse import unquote - -from .exceptions import JsonSchemaDefinitionException - -MAX_SCHEMA_WALK_DEPTH = min(500, sys.getrecursionlimit() // 2) - - -def get_id(schema: dict[str, Any]) -> str: - """ - Originally ID was `id` and since v7 it's `$id`. - """ - return schema.get('$id', schema.get('id', '')) - - -def resolve_path(schema: Any, fragment: str) -> Any: - """ - Return definition from path. - - Path is unescaped according https://tools.ietf.org/html/rfc6901 - """ - fragment = fragment.lstrip('/') - parts = unquote(fragment).split('/') if fragment else [] - for part in parts: - part = part.replace('~1', '/').replace('~0', '~') - if isinstance(schema, list): - schema = schema[int(part)] - elif part in schema: - schema = schema[part] - else: - raise JsonSchemaDefinitionException('Unresolvable ref: {}'.format(part)) - return schema - - -def normalize(uri: str) -> str: - return urlparse.urlsplit(uri).geturl() - - -def resolve_remote(uri: str, handlers: Mapping[str, Callable[[str], Any]]) -> Any: - """ - Resolve a remote ``uri``. - - .. note:: - - urllib library is used to fetch requests from the remote ``uri`` - if handlers does notdefine otherwise. - """ - scheme = urlparse.urlsplit(uri).scheme - if scheme in handlers: - result = handlers[scheme](uri) - else: - from urllib.request import urlopen - - with urlopen(uri) as response: - encoding = response.info().get_content_charset() or 'utf-8' - try: - result = json.loads(response.read().decode(encoding),) - except ValueError as exc: - raise JsonSchemaDefinitionException('{} failed to decode'.format(uri)) from exc - return result - - -class RefResolver: - """ - Resolve JSON References. - """ - - # pylint: disable=dangerous-default-value,too-many-arguments - def __init__( - self, - base_uri: str, - schema: dict[str, Any] | bool, - store: dict[str, Any] = {}, - cache: bool = True, - handlers: Mapping[str, Callable[[str], Any]] = {}, - ) -> None: - """ - `base_uri` is URI of the referring document from the `schema`. - `store` is an dictionary that will be used to cache the fetched schemas - (if `cache=True`). - - Please notice that you can have caching problems when compiling schemas - with colliding `$ref`. To force overwriting use `cache=False` or - explicitly pass the `store` argument (with a brand new dictionary) - """ - self.base_uri = base_uri - self.resolution_scope = base_uri - self.schema = schema - self.store = store - self.cache = cache - self.handlers = handlers - self._walked_uris: set[str] = set() - self.walk(schema) - self._walked_uris.add(normalize(base_uri) if base_uri else '') - - @classmethod - def from_schema( - cls, - schema: dict[str, Any] | bool, - handlers: Mapping[str, Callable[[str], Any]] = {}, - **kwargs: Any, - ) -> 'RefResolver': - """ - Construct a resolver from a JSON schema object. - """ - return cls( - get_id(schema) if isinstance(schema, dict) else '', - schema, - handlers=handlers, - **kwargs - ) - - @contextlib.contextmanager - def in_scope(self, scope: str) -> Iterator[None]: - """ - Context manager to handle current scope. - """ - old_scope = self.resolution_scope - self.resolution_scope = urlparse.urljoin(old_scope, scope) - try: - yield - finally: - self.resolution_scope = old_scope - - @contextlib.contextmanager - def resolving(self, ref: str) -> Iterator[Any]: - """ - Context manager which resolves a JSON ``ref`` and enters the - resolution scope of this ref. - """ - new_uri = urlparse.urljoin(self.resolution_scope, ref) - uri, fragment = urlparse.urldefrag(new_uri) - - document_uri = uri or self.base_uri - - if uri and normalize(uri) in self.store: - schema = self.store[normalize(uri)] - elif not uri or uri == self.base_uri: - schema = self.schema - else: - schema = resolve_remote(uri, self.handlers) - if self.cache: - self.store[normalize(uri)] = schema - - old_base_uri, old_schema = self.base_uri, self.schema - self.base_uri, self.schema = document_uri, schema - try: - with self.in_scope(document_uri): - self._ensure_walked(document_uri, schema) - if fragment and not fragment.startswith('/'): - plain_name = normalize(urlparse.urljoin(document_uri, '#' + fragment)) - if plain_name in self.store: - yield self.store[plain_name] - return - raise JsonSchemaDefinitionException('Unresolvable ref: {}'.format(fragment)) - yield resolve_path(schema, fragment) - finally: - self.base_uri, self.schema = old_base_uri, old_schema - - def _ensure_walked(self, uri: str, schema: Any) -> None: - normalized = normalize(uri) if uri else '' - if normalized in self._walked_uris: - return - self.walk(schema, rewrite_refs=False) - self._walked_uris.add(normalized) - - def get_uri(self) -> str: - return normalize(self.resolution_scope) - - def get_scope_name(self) -> str: - """ - Get current scope and return it as a valid function name. - """ - name = 'validate_' + unquote(self.resolution_scope).replace('~1', '_').replace('~0', '_').replace('"', '') - name = re.sub(r'($[^a-zA-Z]|[^a-zA-Z0-9])', '_', name) - name = name.lower().rstrip('_') - return name - - def walk(self, node: dict[str, Any] | bool, depth: int = 0, rewrite_refs: bool = True) -> None: - """ - Walk thru schema and dereferencing ``id`` and ``$ref`` instances - """ - if depth >= MAX_SCHEMA_WALK_DEPTH: - raise JsonSchemaDefinitionException( - 'Schema is too deeply nested (maximum depth is {})'.format(MAX_SCHEMA_WALK_DEPTH) - ) - - if isinstance(node, bool): - pass - elif '$ref' in node and isinstance(node['$ref'], str): - if rewrite_refs: - ref = node['$ref'] - node['$ref'] = urlparse.urljoin(self.resolution_scope, ref) - elif ('$id' in node or 'id' in node) and isinstance(get_id(node), str): - with self.in_scope(get_id(node)): - self.store[normalize(self.resolution_scope)] = node - for _, item in node.items(): - if isinstance(item, dict): - self.walk(item, depth + 1, rewrite_refs) - else: - for _, item in node.items(): - if isinstance(item, dict): - self.walk(item, depth + 1, rewrite_refs) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py deleted file mode 100644 index 9cb373a2fc9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/fastjsonschema/version.py +++ /dev/null @@ -1 +0,0 @@ -VERSION = '2.22.3' diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto deleted file mode 100644 index 417edd8fa19..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/http.proto"; -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "AnnotationsProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.MethodOptions { - // See `HttpRule`. - HttpRule http = 72295728; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py deleted file mode 100644 index 615b761fbf2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/annotations.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/annotations.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -from opentelemetry.agent._vendor.google.api import http_pb2 as google_dot_api_dot_http__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1cgoogle/api/annotations.proto\x12\ngoogle.api\x1a\x15google/api/http.proto\x1a google/protobuf/descriptor.proto:E\n\x04http\x12\x1e.google.protobuf.MethodOptions\x18\xb0\xca\xbc" \x01(\x0b\x32\x14.google.api.HttpRuleBn\n\x0e\x63om.google.apiB\x10\x41nnotationsProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.annotations_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\020AnnotationsProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi deleted file mode 100644 index 4c4afeb9545..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/annotations_pb2.pyi +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 - -from google.api import http_pb2 as _http_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor -HTTP_FIELD_NUMBER: _ClassVar[int] -http: _descriptor.FieldDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto deleted file mode 100644 index 9b025bac156..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth.proto +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "AuthProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// `Authentication` defines the authentication configuration for API methods -// provided by an API service. -// -// Example: -// -// name: calendar.googleapis.com -// authentication: -// providers: -// - id: google_calendar_auth -// jwks_uri: https://www.googleapis.com/oauth2/v1/certs -// issuer: https://securetoken.google.com -// rules: -// - selector: "*" -// requirements: -// provider_id: google_calendar_auth -// - selector: google.calendar.Delegate -// oauth: -// canonical_scopes: https://www.googleapis.com/auth/calendar.read -message Authentication { - // A list of authentication rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated AuthenticationRule rules = 3; - - // Defines a set of authentication providers that a service supports. - repeated AuthProvider providers = 4; -} - -// Authentication rules for the service. -// -// By default, if a method has any authentication requirements, every request -// must include a valid credential matching one of the requirements. -// It's an error to include more than one kind of credential in a single -// request. -// -// If a method doesn't have any auth requirements, request credentials will be -// ignored. -message AuthenticationRule { - // Selects the methods to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // The requirements for OAuth credentials. - OAuthRequirements oauth = 2; - - // If true, the service accepts API keys without any other credential. - // This flag only applies to HTTP and gRPC requests. - bool allow_without_credential = 5; - - // Requirements for additional authentication providers. - repeated AuthRequirement requirements = 7; -} - -// Specifies a location to extract JWT from an API request. -message JwtLocation { - oneof in { - // Specifies HTTP header name to extract JWT token. - string header = 1; - - // Specifies URL query parameter name to extract JWT token. - string query = 2; - - // Specifies cookie name to extract JWT token. - string cookie = 4; - } - - // The value prefix. The value format is "value_prefix{token}" - // Only applies to "in" header type. Must be empty for "in" query type. - // If not empty, the header value has to match (case sensitive) this prefix. - // If not matched, JWT will not be extracted. If matched, JWT will be - // extracted after the prefix is removed. - // - // For example, for "Authorization: Bearer {JWT}", - // value_prefix="Bearer " with a space at the end. - string value_prefix = 3; -} - -// Configuration for an authentication provider, including support for -// [JSON Web Token -// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32). -message AuthProvider { - // The unique identifier of the auth provider. It will be referred to by - // `AuthRequirement.provider_id`. - // - // Example: "bookstore_auth". - string id = 1; - - // Identifies the principal that issued the JWT. See - // https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.1 - // Usually a URL or an email address. - // - // Example: https://securetoken.google.com - // Example: 1234567-compute@developer.gserviceaccount.com - string issuer = 2; - - // URL of the provider's public key set to validate signature of the JWT. See - // [OpenID - // Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). - // Optional if the key set document: - // - can be retrieved from - // [OpenID - // Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) - // of the issuer. - // - can be inferred from the email domain of the issuer (e.g. a Google - // service account). - // - // Example: https://www.googleapis.com/oauth2/v1/certs - string jwks_uri = 3; - - // The list of JWT - // [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). - // that are allowed to access. A JWT containing any of these audiences will - // be accepted. When this setting is absent, JWTs with audiences: - // - "https://[service.name]/[google.protobuf.Api.name]" - // - "https://[service.name]/" - // will be accepted. - // For example, if no audiences are in the setting, LibraryService API will - // accept JWTs with the following audiences: - // - - // https://library-example.googleapis.com/google.example.library.v1.LibraryService - // - https://library-example.googleapis.com/ - // - // Example: - // - // audiences: bookstore_android.apps.googleusercontent.com, - // bookstore_web.apps.googleusercontent.com - string audiences = 4; - - // Redirect URL if JWT token is required but not present or is expired. - // Implement authorizationUrl of securityDefinitions in OpenAPI spec. - string authorization_url = 5; - - // Defines the locations to extract the JWT. For now it is only used by the - // Cloud Endpoints to store the OpenAPI extension [x-google-jwt-locations] - // (https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#x-google-jwt-locations) - // - // JWT locations can be one of HTTP headers, URL query parameters or - // cookies. The rule is that the first match wins. - // - // If not specified, default to use following 3 locations: - // 1) Authorization: Bearer - // 2) x-goog-iap-jwt-assertion - // 3) access_token query parameter - // - // Default locations can be specified as followings: - // jwt_locations: - // - header: Authorization - // value_prefix: "Bearer " - // - header: x-goog-iap-jwt-assertion - // - query: access_token - repeated JwtLocation jwt_locations = 6; -} - -// OAuth scopes are a way to define data and permissions on data. For example, -// there are scopes defined for "Read-only access to Google Calendar" and -// "Access to Cloud Platform". Users can consent to a scope for an application, -// giving it permission to access that data on their behalf. -// -// OAuth scope specifications should be fairly coarse grained; a user will need -// to see and understand the text description of what your scope means. -// -// In most cases: use one or at most two OAuth scopes for an entire family of -// products. If your product has multiple APIs, you should probably be sharing -// the OAuth scope across all of those APIs. -// -// When you need finer grained OAuth consent screens: talk with your product -// management about how developers will use them in practice. -// -// Please note that even though each of the canonical scopes is enough for a -// request to be accepted and passed to the backend, a request can still fail -// due to the backend requiring additional scopes or permissions. -message OAuthRequirements { - // The list of publicly documented OAuth scopes that are allowed access. An - // OAuth token containing any of these scopes will be accepted. - // - // - // Example: - // - // canonical_scopes: https://www.googleapis.com/auth/calendar, - // https://www.googleapis.com/auth/calendar.read - string canonical_scopes = 1; -} - -// User-defined authentication requirements, including support for -// [JSON Web Token -// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32). -message AuthRequirement { - // [id][google.api.AuthProvider.id] from authentication provider. - // - // Example: - // - // provider_id: bookstore_auth - string provider_id = 1; - - // NOTE: This will be deprecated soon, once AuthProvider.audiences is - // implemented and accepted in all the runtime components. - // - // The list of JWT - // [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). - // that are allowed to access. A JWT containing any of these audiences will - // be accepted. When this setting is absent, only JWTs with audience - // "https://[Service_name][google.api.Service.name]/[API_name][google.protobuf.Api.name]" - // will be accepted. For example, if no audiences are in the setting, - // LibraryService API will only accept JWTs with the following audience - // "https://library-example.googleapis.com/google.example.library.v1.LibraryService". - // - // Example: - // - // audiences: bookstore_android.apps.googleusercontent.com, - // bookstore_web.apps.googleusercontent.com - string audiences = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py deleted file mode 100644 index c183866907c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/auth.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/auth.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x15google/api/auth.proto\x12\ngoogle.api"l\n\x0e\x41uthentication\x12-\n\x05rules\x18\x03 \x03(\x0b\x32\x1e.google.api.AuthenticationRule\x12+\n\tproviders\x18\x04 \x03(\x0b\x32\x18.google.api.AuthProvider"\xa9\x01\n\x12\x41uthenticationRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12,\n\x05oauth\x18\x02 \x01(\x0b\x32\x1d.google.api.OAuthRequirements\x12 \n\x18\x61llow_without_credential\x18\x05 \x01(\x08\x12\x31\n\x0crequirements\x18\x07 \x03(\x0b\x32\x1b.google.api.AuthRequirement"^\n\x0bJwtLocation\x12\x10\n\x06header\x18\x01 \x01(\tH\x00\x12\x0f\n\x05query\x18\x02 \x01(\tH\x00\x12\x10\n\x06\x63ookie\x18\x04 \x01(\tH\x00\x12\x14\n\x0cvalue_prefix\x18\x03 \x01(\tB\x04\n\x02in"\x9a\x01\n\x0c\x41uthProvider\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06issuer\x18\x02 \x01(\t\x12\x10\n\x08jwks_uri\x18\x03 \x01(\t\x12\x11\n\taudiences\x18\x04 \x01(\t\x12\x19\n\x11\x61uthorization_url\x18\x05 \x01(\t\x12.\n\rjwt_locations\x18\x06 \x03(\x0b\x32\x17.google.api.JwtLocation"-\n\x11OAuthRequirements\x12\x18\n\x10\x63\x61nonical_scopes\x18\x01 \x01(\t"9\n\x0f\x41uthRequirement\x12\x13\n\x0bprovider_id\x18\x01 \x01(\t\x12\x11\n\taudiences\x18\x02 \x01(\tBk\n\x0e\x63om.google.apiB\tAuthProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.auth_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\tAuthProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_AUTHENTICATION"]._serialized_start = 37 - _globals["_AUTHENTICATION"]._serialized_end = 145 - _globals["_AUTHENTICATIONRULE"]._serialized_start = 148 - _globals["_AUTHENTICATIONRULE"]._serialized_end = 317 - _globals["_JWTLOCATION"]._serialized_start = 319 - _globals["_JWTLOCATION"]._serialized_end = 413 - _globals["_AUTHPROVIDER"]._serialized_start = 416 - _globals["_AUTHPROVIDER"]._serialized_end = 570 - _globals["_OAUTHREQUIREMENTS"]._serialized_start = 572 - _globals["_OAUTHREQUIREMENTS"]._serialized_end = 617 - _globals["_AUTHREQUIREMENT"]._serialized_start = 619 - _globals["_AUTHREQUIREMENT"]._serialized_end = 676 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi deleted file mode 100644 index 421473a3972..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/auth_pb2.pyi +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Authentication(_message.Message): - __slots__ = ("rules", "providers") - RULES_FIELD_NUMBER: _ClassVar[int] - PROVIDERS_FIELD_NUMBER: _ClassVar[int] - rules: _containers.RepeatedCompositeFieldContainer[AuthenticationRule] - providers: _containers.RepeatedCompositeFieldContainer[AuthProvider] - def __init__( - self, - rules: _Optional[_Iterable[_Union[AuthenticationRule, _Mapping]]] = ..., - providers: _Optional[_Iterable[_Union[AuthProvider, _Mapping]]] = ..., - ) -> None: ... - -class AuthenticationRule(_message.Message): - __slots__ = ("selector", "oauth", "allow_without_credential", "requirements") - SELECTOR_FIELD_NUMBER: _ClassVar[int] - OAUTH_FIELD_NUMBER: _ClassVar[int] - ALLOW_WITHOUT_CREDENTIAL_FIELD_NUMBER: _ClassVar[int] - REQUIREMENTS_FIELD_NUMBER: _ClassVar[int] - selector: str - oauth: OAuthRequirements - allow_without_credential: bool - requirements: _containers.RepeatedCompositeFieldContainer[AuthRequirement] - def __init__( - self, - selector: _Optional[str] = ..., - oauth: _Optional[_Union[OAuthRequirements, _Mapping]] = ..., - allow_without_credential: _Optional[bool] = ..., - requirements: _Optional[_Iterable[_Union[AuthRequirement, _Mapping]]] = ..., - ) -> None: ... - -class JwtLocation(_message.Message): - __slots__ = ("header", "query", "cookie", "value_prefix") - HEADER_FIELD_NUMBER: _ClassVar[int] - QUERY_FIELD_NUMBER: _ClassVar[int] - COOKIE_FIELD_NUMBER: _ClassVar[int] - VALUE_PREFIX_FIELD_NUMBER: _ClassVar[int] - header: str - query: str - cookie: str - value_prefix: str - def __init__( - self, - header: _Optional[str] = ..., - query: _Optional[str] = ..., - cookie: _Optional[str] = ..., - value_prefix: _Optional[str] = ..., - ) -> None: ... - -class AuthProvider(_message.Message): - __slots__ = ( - "id", - "issuer", - "jwks_uri", - "audiences", - "authorization_url", - "jwt_locations", - ) - ID_FIELD_NUMBER: _ClassVar[int] - ISSUER_FIELD_NUMBER: _ClassVar[int] - JWKS_URI_FIELD_NUMBER: _ClassVar[int] - AUDIENCES_FIELD_NUMBER: _ClassVar[int] - AUTHORIZATION_URL_FIELD_NUMBER: _ClassVar[int] - JWT_LOCATIONS_FIELD_NUMBER: _ClassVar[int] - id: str - issuer: str - jwks_uri: str - audiences: str - authorization_url: str - jwt_locations: _containers.RepeatedCompositeFieldContainer[JwtLocation] - def __init__( - self, - id: _Optional[str] = ..., - issuer: _Optional[str] = ..., - jwks_uri: _Optional[str] = ..., - audiences: _Optional[str] = ..., - authorization_url: _Optional[str] = ..., - jwt_locations: _Optional[_Iterable[_Union[JwtLocation, _Mapping]]] = ..., - ) -> None: ... - -class OAuthRequirements(_message.Message): - __slots__ = ("canonical_scopes",) - CANONICAL_SCOPES_FIELD_NUMBER: _ClassVar[int] - canonical_scopes: str - def __init__(self, canonical_scopes: _Optional[str] = ...) -> None: ... - -class AuthRequirement(_message.Message): - __slots__ = ("provider_id", "audiences") - PROVIDER_ID_FIELD_NUMBER: _ClassVar[int] - AUDIENCES_FIELD_NUMBER: _ClassVar[int] - provider_id: str - audiences: str - def __init__( - self, provider_id: _Optional[str] = ..., audiences: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto deleted file mode 100644 index 7bff445a341..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend.proto +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "BackendProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// `Backend` defines the backend configuration for a service. -message Backend { - // A list of API backend rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated BackendRule rules = 1; -} - -// A backend rule provides configuration for an individual API element. -message BackendRule { - // Path Translation specifies how to combine the backend address with the - // request path in order to produce the appropriate forwarding URL for the - // request. - // - // Path Translation is applicable only to HTTP-based backends. Backends which - // do not accept requests over HTTP/HTTPS should leave `path_translation` - // unspecified. - enum PathTranslation { - PATH_TRANSLATION_UNSPECIFIED = 0; - - // Use the backend address as-is, with no modification to the path. If the - // URL pattern contains variables, the variable names and values will be - // appended to the query string. If a query string parameter and a URL - // pattern variable have the same name, this may result in duplicate keys in - // the query string. - // - // # Examples - // - // Given the following operation config: - // - // Method path: /api/company/{cid}/user/{uid} - // Backend address: https://example.cloudfunctions.net/getUser - // - // Requests to the following request paths will call the backend at the - // translated path: - // - // Request path: /api/company/widgetworks/user/johndoe - // Translated: - // https://example.cloudfunctions.net/getUser?cid=widgetworks&uid=johndoe - // - // Request path: /api/company/widgetworks/user/johndoe?timezone=EST - // Translated: - // https://example.cloudfunctions.net/getUser?timezone=EST&cid=widgetworks&uid=johndoe - CONSTANT_ADDRESS = 1; - - // The request path will be appended to the backend address. - // - // # Examples - // - // Given the following operation config: - // - // Method path: /api/company/{cid}/user/{uid} - // Backend address: https://example.appspot.com - // - // Requests to the following request paths will call the backend at the - // translated path: - // - // Request path: /api/company/widgetworks/user/johndoe - // Translated: - // https://example.appspot.com/api/company/widgetworks/user/johndoe - // - // Request path: /api/company/widgetworks/user/johndoe?timezone=EST - // Translated: - // https://example.appspot.com/api/company/widgetworks/user/johndoe?timezone=EST - APPEND_PATH_TO_ADDRESS = 2; - } - - // Selects the methods to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // The address of the API backend. - // - // The scheme is used to determine the backend protocol and security. - // The following schemes are accepted: - // - // SCHEME PROTOCOL SECURITY - // http:// HTTP None - // https:// HTTP TLS - // grpc:// gRPC None - // grpcs:// gRPC TLS - // - // It is recommended to explicitly include a scheme. Leaving out the scheme - // may cause constrasting behaviors across platforms. - // - // If the port is unspecified, the default is: - // - 80 for schemes without TLS - // - 443 for schemes with TLS - // - // For HTTP backends, use [protocol][google.api.BackendRule.protocol] - // to specify the protocol version. - string address = 2; - - // The number of seconds to wait for a response from a request. The default - // varies based on the request protocol and deployment environment. - double deadline = 3; - - // Deprecated, do not use. - double min_deadline = 4 [deprecated = true]; - - // The number of seconds to wait for the completion of a long running - // operation. The default is no deadline. - double operation_deadline = 5; - - // Path translation specifies how to combine the backend address with the - // request path in order to produce the appropriate forwarding URL for the - // request. See [PathTranslation][google.api.BackendRule.PathTranslation] for - // more details. - PathTranslation path_translation = 6; - - // Authentication settings used by the backend. - // - // These are typically used to provide service management functionality to - // a backend served on a publicly-routable URL. The `authentication` - // details should match the authentication behavior used by the backend. - // - // For example, specifying `jwt_audience` implies that the backend expects - // authentication via a JWT. - // - // When authentication is unspecified, the resulting behavior is the same - // as `disable_auth` set to `true`. - // - // Refer to https://developers.google.com/identity/protocols/OpenIDConnect for - // JWT ID token. - oneof authentication { - // The JWT audience is used when generating a JWT ID token for the backend. - // This ID token will be added in the HTTP "authorization" header, and sent - // to the backend. - string jwt_audience = 7; - - // When disable_auth is true, a JWT ID token won't be generated and the - // original "Authorization" HTTP header will be preserved. If the header is - // used to carry the original token and is expected by the backend, this - // field must be set to true to preserve the header. - bool disable_auth = 8; - } - - // The protocol used for sending a request to the backend. - // The supported values are "http/1.1" and "h2". - // - // The default value is inferred from the scheme in the - // [address][google.api.BackendRule.address] field: - // - // SCHEME PROTOCOL - // http:// http/1.1 - // https:// http/1.1 - // grpc:// h2 - // grpcs:// h2 - // - // For secure HTTP backends (https://) that support HTTP/2, set this field - // to "h2" for improved performance. - // - // Configuring this field to non-default values is only supported for secure - // HTTP backends. This field will be ignored for all other backends. - // - // See - // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids - // for more details on the supported values. - string protocol = 9; - - // The map between request protocol and the backend address. - map overrides_by_request_protocol = 10; - - // The load balancing policy used for connection to the application backend. - // - // Defined as an arbitrary string to accomondate custom load balancing - // policies supported by the underlying channel, but suggest most users use - // one of the standard policies, such as the default, "RoundRobin". - string load_balancing_policy = 11; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py deleted file mode 100644 index 454d236c79a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/backend.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/backend.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x18google/api/backend.proto\x12\ngoogle.api"1\n\x07\x42\x61\x63kend\x12&\n\x05rules\x18\x01 \x03(\x0b\x32\x17.google.api.BackendRule"\xd1\x04\n\x0b\x42\x61\x63kendRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08\x64\x65\x61\x64line\x18\x03 \x01(\x01\x12\x18\n\x0cmin_deadline\x18\x04 \x01(\x01\x42\x02\x18\x01\x12\x1a\n\x12operation_deadline\x18\x05 \x01(\x01\x12\x41\n\x10path_translation\x18\x06 \x01(\x0e\x32\'.google.api.BackendRule.PathTranslation\x12\x16\n\x0cjwt_audience\x18\x07 \x01(\tH\x00\x12\x16\n\x0c\x64isable_auth\x18\x08 \x01(\x08H\x00\x12\x10\n\x08protocol\x18\t \x01(\t\x12^\n\x1doverrides_by_request_protocol\x18\n \x03(\x0b\x32\x37.google.api.BackendRule.OverridesByRequestProtocolEntry\x12\x1d\n\x15load_balancing_policy\x18\x0b \x01(\t\x1aZ\n\x1fOverridesByRequestProtocolEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.google.api.BackendRule:\x02\x38\x01"e\n\x0fPathTranslation\x12 \n\x1cPATH_TRANSLATION_UNSPECIFIED\x10\x00\x12\x14\n\x10\x43ONSTANT_ADDRESS\x10\x01\x12\x1a\n\x16\x41PPEND_PATH_TO_ADDRESS\x10\x02\x42\x10\n\x0e\x61uthenticationBn\n\x0e\x63om.google.apiB\x0c\x42\x61\x63kendProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.backend_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\014BackendProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY"]._loaded_options = None - _globals[ - "_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY" - ]._serialized_options = b"8\001" - _globals["_BACKENDRULE"].fields_by_name["min_deadline"]._loaded_options = None - _globals["_BACKENDRULE"].fields_by_name[ - "min_deadline" - ]._serialized_options = b"\030\001" - _globals["_BACKEND"]._serialized_start = 40 - _globals["_BACKEND"]._serialized_end = 89 - _globals["_BACKENDRULE"]._serialized_start = 92 - _globals["_BACKENDRULE"]._serialized_end = 685 - _globals["_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY"]._serialized_start = 474 - _globals["_BACKENDRULE_OVERRIDESBYREQUESTPROTOCOLENTRY"]._serialized_end = 564 - _globals["_BACKENDRULE_PATHTRANSLATION"]._serialized_start = 566 - _globals["_BACKENDRULE_PATHTRANSLATION"]._serialized_end = 667 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi deleted file mode 100644 index 162a4bd8761..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/backend_pb2.pyi +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class Backend(_message.Message): - __slots__ = ("rules",) - RULES_FIELD_NUMBER: _ClassVar[int] - rules: _containers.RepeatedCompositeFieldContainer[BackendRule] - def __init__( - self, rules: _Optional[_Iterable[_Union[BackendRule, _Mapping]]] = ... - ) -> None: ... - -class BackendRule(_message.Message): - __slots__ = ( - "selector", - "address", - "deadline", - "min_deadline", - "operation_deadline", - "path_translation", - "jwt_audience", - "disable_auth", - "protocol", - "overrides_by_request_protocol", - "load_balancing_policy", - ) - class PathTranslation(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - PATH_TRANSLATION_UNSPECIFIED: _ClassVar[BackendRule.PathTranslation] - CONSTANT_ADDRESS: _ClassVar[BackendRule.PathTranslation] - APPEND_PATH_TO_ADDRESS: _ClassVar[BackendRule.PathTranslation] - - PATH_TRANSLATION_UNSPECIFIED: BackendRule.PathTranslation - CONSTANT_ADDRESS: BackendRule.PathTranslation - APPEND_PATH_TO_ADDRESS: BackendRule.PathTranslation - class OverridesByRequestProtocolEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: BackendRule - def __init__( - self, - key: _Optional[str] = ..., - value: _Optional[_Union[BackendRule, _Mapping]] = ..., - ) -> None: ... - - SELECTOR_FIELD_NUMBER: _ClassVar[int] - ADDRESS_FIELD_NUMBER: _ClassVar[int] - DEADLINE_FIELD_NUMBER: _ClassVar[int] - MIN_DEADLINE_FIELD_NUMBER: _ClassVar[int] - OPERATION_DEADLINE_FIELD_NUMBER: _ClassVar[int] - PATH_TRANSLATION_FIELD_NUMBER: _ClassVar[int] - JWT_AUDIENCE_FIELD_NUMBER: _ClassVar[int] - DISABLE_AUTH_FIELD_NUMBER: _ClassVar[int] - PROTOCOL_FIELD_NUMBER: _ClassVar[int] - OVERRIDES_BY_REQUEST_PROTOCOL_FIELD_NUMBER: _ClassVar[int] - LOAD_BALANCING_POLICY_FIELD_NUMBER: _ClassVar[int] - selector: str - address: str - deadline: float - min_deadline: float - operation_deadline: float - path_translation: BackendRule.PathTranslation - jwt_audience: str - disable_auth: bool - protocol: str - overrides_by_request_protocol: _containers.MessageMap[str, BackendRule] - load_balancing_policy: str - def __init__( - self, - selector: _Optional[str] = ..., - address: _Optional[str] = ..., - deadline: _Optional[float] = ..., - min_deadline: _Optional[float] = ..., - operation_deadline: _Optional[float] = ..., - path_translation: _Optional[_Union[BackendRule.PathTranslation, str]] = ..., - jwt_audience: _Optional[str] = ..., - disable_auth: _Optional[bool] = ..., - protocol: _Optional[str] = ..., - overrides_by_request_protocol: _Optional[_Mapping[str, BackendRule]] = ..., - load_balancing_policy: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto deleted file mode 100644 index 2b86bb61e42..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing.proto +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "BillingProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Billing related configuration of the service. -// -// The following example shows how to configure monitored resources and metrics -// for billing, `consumer_destinations` is the only supported destination and -// the monitored resources need at least one label key -// `cloud.googleapis.com/location` to indicate the location of the billing -// usage, using different monitored resources between monitoring and billing is -// recommended so they can be evolved independently: -// -// -// monitored_resources: -// - type: library.googleapis.com/billing_branch -// labels: -// - key: cloud.googleapis.com/location -// description: | -// Predefined label to support billing location restriction. -// - key: city -// description: | -// Custom label to define the city where the library branch is located -// in. -// - key: name -// description: Custom label to define the name of the library branch. -// metrics: -// - name: library.googleapis.com/book/borrowed_count -// metric_kind: DELTA -// value_type: INT64 -// unit: "1" -// billing: -// consumer_destinations: -// - monitored_resource: library.googleapis.com/billing_branch -// metrics: -// - library.googleapis.com/book/borrowed_count -message Billing { - // Configuration of a specific billing destination (Currently only support - // bill against consumer project). - message BillingDestination { - // The monitored resource type. The type must be defined in - // [Service.monitored_resources][google.api.Service.monitored_resources] - // section. - string monitored_resource = 1; - - // Names of the metrics to report to this billing destination. - // Each name must be defined in - // [Service.metrics][google.api.Service.metrics] section. - repeated string metrics = 2; - } - - // Billing configurations for sending metrics to the consumer project. - // There can be multiple consumer destinations per service, each one must have - // a different monitored resource type. A metric can be used in at most - // one consumer destination. - repeated BillingDestination consumer_destinations = 8; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py deleted file mode 100644 index d70bf097b3b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/billing.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/billing.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x18google/api/billing.proto\x12\ngoogle.api"\x93\x01\n\x07\x42illing\x12\x45\n\x15\x63onsumer_destinations\x18\x08 \x03(\x0b\x32&.google.api.Billing.BillingDestination\x1a\x41\n\x12\x42illingDestination\x12\x1a\n\x12monitored_resource\x18\x01 \x01(\t\x12\x0f\n\x07metrics\x18\x02 \x03(\tBn\n\x0e\x63om.google.apiB\x0c\x42illingProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.billing_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\014BillingProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_BILLING"]._serialized_start = 41 - _globals["_BILLING"]._serialized_end = 188 - _globals["_BILLING_BILLINGDESTINATION"]._serialized_start = 123 - _globals["_BILLING_BILLINGDESTINATION"]._serialized_end = 188 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi deleted file mode 100644 index f50e8794e18..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/billing_pb2.pyi +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Billing(_message.Message): - __slots__ = ("consumer_destinations",) - class BillingDestination(_message.Message): - __slots__ = ("monitored_resource", "metrics") - MONITORED_RESOURCE_FIELD_NUMBER: _ClassVar[int] - METRICS_FIELD_NUMBER: _ClassVar[int] - monitored_resource: str - metrics: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - monitored_resource: _Optional[str] = ..., - metrics: _Optional[_Iterable[str]] = ..., - ) -> None: ... - - CONSUMER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] - consumer_destinations: _containers.RepeatedCompositeFieldContainer[ - Billing.BillingDestination - ] - def __init__( - self, - consumer_destinations: _Optional[ - _Iterable[_Union[Billing.BillingDestination, _Mapping]] - ] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto deleted file mode 100644 index 332e0d086dc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client.proto +++ /dev/null @@ -1,598 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/launch_stage.proto"; -import "google/protobuf/descriptor.proto"; -import "google/protobuf/duration.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "ClientProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.MethodOptions { - // A definition of a client library method signature. - // - // In client libraries, each proto RPC corresponds to one or more methods - // which the end user is able to call, and calls the underlying RPC. - // Normally, this method receives a single argument (a struct or instance - // corresponding to the RPC request object). Defining this field will - // add one or more overloads providing flattened or simpler method signatures - // in some languages. - // - // The fields on the method signature are provided as a comma-separated - // string. - // - // For example, the proto RPC and annotation: - // - // rpc CreateSubscription(CreateSubscriptionRequest) - // returns (Subscription) { - // option (google.api.method_signature) = "name,topic"; - // } - // - // Would add the following Java overload (in addition to the method accepting - // the request object): - // - // public final Subscription createSubscription(String name, String topic) - // - // The following backwards-compatibility guidelines apply: - // - // * Adding this annotation to an unannotated method is backwards - // compatible. - // * Adding this annotation to a method which already has existing - // method signature annotations is backwards compatible if and only if - // the new method signature annotation is last in the sequence. - // * Modifying or removing an existing method signature annotation is - // a breaking change. - // * Re-ordering existing method signature annotations is a breaking - // change. - repeated string method_signature = 1051; -} - -extend google.protobuf.ServiceOptions { - // The hostname for this service. - // This should be specified with no prefix or protocol. - // - // Example: - // - // service Foo { - // option (google.api.default_host) = "foo.googleapi.com"; - // ... - // } - string default_host = 1049; - - // OAuth scopes needed for the client. - // - // Example: - // - // service Foo { - // option (google.api.oauth_scopes) = \ - // "https://www.googleapis.com/auth/cloud-platform"; - // ... - // } - // - // If there is more than one scope, use a comma-separated string: - // - // Example: - // - // service Foo { - // option (google.api.oauth_scopes) = \ - // "https://www.googleapis.com/auth/cloud-platform," - // "https://www.googleapis.com/auth/monitoring"; - // ... - // } - string oauth_scopes = 1050; - - // The API version of this service, which should be sent by version-aware - // clients to the service. This allows services to abide by the schema and - // behavior of the service at the time this API version was deployed. - // The format of the API version must be treated as opaque by clients. - // Services may use a format with an apparent structure, but clients must - // not rely on this to determine components within an API version, or attempt - // to construct other valid API versions. Note that this is for upcoming - // functionality and may not be implemented for all services. - // - // Example: - // - // service Foo { - // option (google.api.api_version) = "v1_20230821_preview"; - // } - string api_version = 525000001; -} - -// Required information for every language. -message CommonLanguageSettings { - // Link to automatically generated reference documentation. Example: - // https://cloud.google.com/nodejs/docs/reference/asset/latest - string reference_docs_uri = 1 [deprecated = true]; - - // The destination where API teams want this client library to be published. - repeated ClientLibraryDestination destinations = 2; - - // Configuration for which RPCs should be generated in the GAPIC client. - // - // Note: This field should not be used in most cases. - SelectiveGapicGeneration selective_gapic_generation = 3; -} - -// Details about how and where to publish client libraries. -message ClientLibrarySettings { - // Version of the API to apply these settings to. This is the full protobuf - // package for the API, ending in the version element. - // Examples: "google.cloud.speech.v1" and "google.spanner.admin.database.v1". - string version = 1; - - // Launch stage of this version of the API. - LaunchStage launch_stage = 2; - - // When using transport=rest, the client request will encode enums as - // numbers rather than strings. - bool rest_numeric_enums = 3; - - // Settings for legacy Java features, supported in the Service YAML. - JavaSettings java_settings = 21; - - // Settings for C++ client libraries. - CppSettings cpp_settings = 22; - - // Settings for PHP client libraries. - PhpSettings php_settings = 23; - - // Settings for Python client libraries. - PythonSettings python_settings = 24; - - // Settings for Node client libraries. - NodeSettings node_settings = 25; - - // Settings for .NET client libraries. - DotnetSettings dotnet_settings = 26; - - // Settings for Ruby client libraries. - RubySettings ruby_settings = 27; - - // Settings for Go client libraries. - GoSettings go_settings = 28; -} - -// This message configures the settings for publishing [Google Cloud Client -// libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) -// generated from the service config. -message Publishing { - // A list of API method settings, e.g. the behavior for methods that use the - // long-running operation pattern. - repeated MethodSettings method_settings = 2; - - // Link to a *public* URI where users can report issues. Example: - // https://issuetracker.google.com/issues/new?component=190865&template=1161103 - string new_issue_uri = 101; - - // Link to product home page. Example: - // https://cloud.google.com/asset-inventory/docs/overview - string documentation_uri = 102; - - // Used as a tracking tag when collecting data about the APIs developer - // relations artifacts like docs, packages delivered to package managers, - // etc. Example: "speech". - string api_short_name = 103; - - // GitHub label to apply to issues and pull requests opened for this API. - string github_label = 104; - - // GitHub teams to be added to CODEOWNERS in the directory in GitHub - // containing source code for the client libraries for this API. - repeated string codeowner_github_teams = 105; - - // A prefix used in sample code when demarking regions to be included in - // documentation. - string doc_tag_prefix = 106; - - // For whom the client library is being published. - ClientLibraryOrganization organization = 107; - - // Client library settings. If the same version string appears multiple - // times in this list, then the last one wins. Settings from earlier - // settings with the same version string are discarded. - repeated ClientLibrarySettings library_settings = 109; - - // Optional link to proto reference documentation. Example: - // https://cloud.google.com/pubsub/lite/docs/reference/rpc - string proto_reference_documentation_uri = 110; - - // Optional link to REST reference documentation. Example: - // https://cloud.google.com/pubsub/lite/docs/reference/rest - string rest_reference_documentation_uri = 111; -} - -// Settings for Java client libraries. -message JavaSettings { - // The package name to use in Java. Clobbers the java_package option - // set in the protobuf. This should be used **only** by APIs - // who have already set the language_settings.java.package_name" field - // in gapic.yaml. API teams should use the protobuf java_package option - // where possible. - // - // Example of a YAML configuration:: - // - // publishing: - // library_settings: - // java_settings: - // library_package: com.google.cloud.pubsub.v1 - string library_package = 1; - - // Configure the Java class name to use instead of the service's for its - // corresponding generated GAPIC client. Keys are fully-qualified - // service names as they appear in the protobuf (including the full - // the language_settings.java.interface_names" field in gapic.yaml. API - // teams should otherwise use the service name as it appears in the - // protobuf. - // - // Example of a YAML configuration:: - // - // publishing: - // java_settings: - // service_class_names: - // - google.pubsub.v1.Publisher: TopicAdmin - // - google.pubsub.v1.Subscriber: SubscriptionAdmin - map service_class_names = 2; - - // Some settings. - CommonLanguageSettings common = 3; -} - -// Settings for C++ client libraries. -message CppSettings { - // Some settings. - CommonLanguageSettings common = 1; -} - -// Settings for Php client libraries. -message PhpSettings { - // Some settings. - CommonLanguageSettings common = 1; - - // The package name to use in Php. Clobbers the php_namespace option - // set in the protobuf. This should be used **only** by APIs - // who have already set the language_settings.php.package_name" field - // in gapic.yaml. API teams should use the protobuf php_namespace option - // where possible. - // - // Example of a YAML configuration:: - // - // publishing: - // library_settings: - // php_settings: - // library_package: Google\Cloud\PubSub\V1 - string library_package = 2; -} - -// Settings for Python client libraries. -message PythonSettings { - // Experimental features to be included during client library generation. - // These fields will be deprecated once the feature graduates and is enabled - // by default. - message ExperimentalFeatures { - // Enables generation of asynchronous REST clients if `rest` transport is - // enabled. By default, asynchronous REST clients will not be generated. - // This feature will be enabled by default 1 month after launching the - // feature in preview packages. - bool rest_async_io_enabled = 1; - - // Enables generation of protobuf code using new types that are more - // Pythonic which are included in `protobuf>=5.29.x`. This feature will be - // enabled by default 1 month after launching the feature in preview - // packages. - bool protobuf_pythonic_types_enabled = 2; - - // Disables generation of an unversioned Python package for this client - // library. This means that the module names will need to be versioned in - // import statements. For example `import google.cloud.library_v2` instead - // of `import google.cloud.library`. - bool unversioned_package_disabled = 3; - } - - // Some settings. - CommonLanguageSettings common = 1; - - // Experimental features to be included during client library generation. - ExperimentalFeatures experimental_features = 2; -} - -// Settings for Node client libraries. -message NodeSettings { - // Some settings. - CommonLanguageSettings common = 1; -} - -// Settings for Dotnet client libraries. -message DotnetSettings { - // Some settings. - CommonLanguageSettings common = 1; - - // Map from original service names to renamed versions. - // This is used when the default generated types - // would cause a naming conflict. (Neither name is - // fully-qualified.) - // Example: Subscriber to SubscriberServiceApi. - map renamed_services = 2; - - // Map from full resource types to the effective short name - // for the resource. This is used when otherwise resource - // named from different services would cause naming collisions. - // Example entry: - // "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" - map renamed_resources = 3; - - // List of full resource types to ignore during generation. - // This is typically used for API-specific Location resources, - // which should be handled by the generator as if they were actually - // the common Location resources. - // Example entry: "documentai.googleapis.com/Location" - repeated string ignored_resources = 4; - - // Namespaces which must be aliased in snippets due to - // a known (but non-generator-predictable) naming collision - repeated string forced_namespace_aliases = 5; - - // Method signatures (in the form "service.method(signature)") - // which are provided separately, so shouldn't be generated. - // Snippets *calling* these methods are still generated, however. - repeated string handwritten_signatures = 6; -} - -// Settings for Ruby client libraries. -message RubySettings { - // Some settings. - CommonLanguageSettings common = 1; -} - -// Settings for Go client libraries. -message GoSettings { - // Some settings. - CommonLanguageSettings common = 1; - - // Map of service names to renamed services. Keys are the package relative - // service names and values are the name to be used for the service client - // and call options. - // - // Example: - // - // publishing: - // go_settings: - // renamed_services: - // Publisher: TopicAdmin - map renamed_services = 2; -} - -// Describes the generator configuration for a method. -message MethodSettings { - // Describes settings to use when generating API methods that use the - // long-running operation pattern. - // All default values below are from those used in the client library - // generators (e.g. - // [Java](https://github.com/googleapis/gapic-generator-java/blob/04c2faa191a9b5a10b92392fe8482279c4404803/src/main/java/com/google/api/generator/gapic/composer/common/RetrySettingsComposer.java)). - message LongRunning { - // Initial delay after which the first poll request will be made. - // Default value: 5 seconds. - google.protobuf.Duration initial_poll_delay = 1; - - // Multiplier to gradually increase delay between subsequent polls until it - // reaches max_poll_delay. - // Default value: 1.5. - float poll_delay_multiplier = 2; - - // Maximum time between two subsequent poll requests. - // Default value: 45 seconds. - google.protobuf.Duration max_poll_delay = 3; - - // Total polling timeout. - // Default value: 5 minutes. - google.protobuf.Duration total_poll_timeout = 4; - } - - // The fully qualified name of the method, for which the options below apply. - // This is used to find the method to apply the options. - // - // Example: - // - // publishing: - // method_settings: - // - selector: google.storage.control.v2.StorageControl.CreateFolder - // # method settings for CreateFolder... - string selector = 1; - - // Describes settings to use for long-running operations when generating - // API methods for RPCs. Complements RPCs that use the annotations in - // google/longrunning/operations.proto. - // - // Example of a YAML configuration:: - // - // publishing: - // method_settings: - // - selector: google.cloud.speech.v2.Speech.BatchRecognize - // long_running: - // initial_poll_delay: 60s # 1 minute - // poll_delay_multiplier: 1.5 - // max_poll_delay: 360s # 6 minutes - // total_poll_timeout: 54000s # 90 minutes - LongRunning long_running = 2; - - // List of top-level fields of the request message, that should be - // automatically populated by the client libraries based on their - // (google.api.field_info).format. Currently supported format: UUID4. - // - // Example of a YAML configuration: - // - // publishing: - // method_settings: - // - selector: google.example.v1.ExampleService.CreateExample - // auto_populated_fields: - // - request_id - repeated string auto_populated_fields = 3; - - // Batching configuration for an API method in client libraries. - // - // Example of a YAML configuration: - // - // publishing: - // method_settings: - // - selector: google.example.v1.ExampleService.BatchCreateExample - // batching: - // element_count_threshold: 1000 - // request_byte_threshold: 100000000 - // delay_threshold_millis: 10 - BatchingConfigProto batching = 4; -} - -// The organization for which the client libraries are being published. -// Affects the url where generated docs are published, etc. -enum ClientLibraryOrganization { - // Not useful. - CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED = 0; - - // Google Cloud Platform Org. - CLOUD = 1; - - // Ads (Advertising) Org. - ADS = 2; - - // Photos Org. - PHOTOS = 3; - - // Street View Org. - STREET_VIEW = 4; - - // Shopping Org. - SHOPPING = 5; - - // Geo Org. - GEO = 6; - - // Generative AI - https://developers.generativeai.google - GENERATIVE_AI = 7; -} - -// To where should client libraries be published? -enum ClientLibraryDestination { - // Client libraries will neither be generated nor published to package - // managers. - CLIENT_LIBRARY_DESTINATION_UNSPECIFIED = 0; - - // Generate the client library in a repo under github.com/googleapis, - // but don't publish it to package managers. - GITHUB = 10; - - // Publish the library to package managers like nuget.org and npmjs.com. - PACKAGE_MANAGER = 20; -} - -// This message is used to configure the generation of a subset of the RPCs in -// a service for client libraries. -// -// Note: This feature should not be used in most cases. -message SelectiveGapicGeneration { - // An allowlist of the fully qualified names of RPCs that should be included - // on public client surfaces. - repeated string methods = 1; - - // Setting this to true indicates to the client generators that methods - // that would be excluded from the generation should instead be generated - // in a way that indicates these methods should not be consumed by - // end users. How this is expressed is up to individual language - // implementations to decide. Some examples may be: added annotations, - // obfuscated identifiers, or other language idiomatic patterns. - bool generate_omitted_as_internal = 2; -} - -// `BatchingConfigProto` defines the batching configuration for an API method. -message BatchingConfigProto { - // The thresholds which trigger a batched request to be sent. - BatchingSettingsProto thresholds = 1; - - // The request and response fields used in batching. - BatchingDescriptorProto batch_descriptor = 2; -} - -// `BatchingSettingsProto` specifies a set of batching thresholds, each of -// which acts as a trigger to send a batch of messages as a request. At least -// one threshold must be positive nonzero. -message BatchingSettingsProto { - // The number of elements of a field collected into a batch which, if - // exceeded, causes the batch to be sent. - int32 element_count_threshold = 1; - - // The aggregated size of the batched field which, if exceeded, causes the - // batch to be sent. This size is computed by aggregating the sizes of the - // request field to be batched, not of the entire request message. - int64 request_byte_threshold = 2; - - // The duration after which a batch should be sent, starting from the addition - // of the first message to that batch. - google.protobuf.Duration delay_threshold = 3; - - // The maximum number of elements collected in a batch that could be accepted - // by server. - int32 element_count_limit = 4; - - // The maximum size of the request that could be accepted by server. - int32 request_byte_limit = 5; - - // The maximum number of elements allowed by flow control. - int32 flow_control_element_limit = 6; - - // The maximum size of data allowed by flow control. - int32 flow_control_byte_limit = 7; - - // The behavior to take when the flow control limit is exceeded. - FlowControlLimitExceededBehaviorProto flow_control_limit_exceeded_behavior = - 8; -} - -// The behavior to take when the flow control limit is exceeded. -enum FlowControlLimitExceededBehaviorProto { - // Default behavior, system-defined. - UNSET_BEHAVIOR = 0; - - // Stop operation, raise error. - THROW_EXCEPTION = 1; - - // Pause operation until limit clears. - BLOCK = 2; - - // Continue operation, disregard limit. - IGNORE = 3; -} - -// `BatchingDescriptorProto` specifies the fields of the request message to be -// used for batching, and, optionally, the fields of the response message to be -// used for demultiplexing. -message BatchingDescriptorProto { - // The repeated field in the request message to be aggregated by batching. - string batched_field = 1; - - // A list of the fields in the request message. Two requests will be batched - // together only if the values of every field specified in - // `request_discriminator_fields` is equal between the two requests. - repeated string discriminator_fields = 2; - - // Optional. When present, indicates the field in the response message to be - // used to demultiplex the response into multiple response messages, in - // correspondence with the multiple request messages originally batched - // together. - string subresponse_field = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py deleted file mode 100644 index 363109cbf50..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/client.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/client.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 -from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 - -from opentelemetry.agent._vendor.google.api import launch_stage_pb2 as google_dot_api_dot_launch__stage__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x17google/api/client.proto\x12\ngoogle.api\x1a\x1dgoogle/api/launch_stage.proto\x1a google/protobuf/descriptor.proto\x1a\x1egoogle/protobuf/duration.proto"\xbe\x01\n\x16\x43ommonLanguageSettings\x12\x1e\n\x12reference_docs_uri\x18\x01 \x01(\tB\x02\x18\x01\x12:\n\x0c\x64\x65stinations\x18\x02 \x03(\x0e\x32$.google.api.ClientLibraryDestination\x12H\n\x1aselective_gapic_generation\x18\x03 \x01(\x0b\x32$.google.api.SelectiveGapicGeneration"\xfb\x03\n\x15\x43lientLibrarySettings\x12\x0f\n\x07version\x18\x01 \x01(\t\x12-\n\x0claunch_stage\x18\x02 \x01(\x0e\x32\x17.google.api.LaunchStage\x12\x1a\n\x12rest_numeric_enums\x18\x03 \x01(\x08\x12/\n\rjava_settings\x18\x15 \x01(\x0b\x32\x18.google.api.JavaSettings\x12-\n\x0c\x63pp_settings\x18\x16 \x01(\x0b\x32\x17.google.api.CppSettings\x12-\n\x0cphp_settings\x18\x17 \x01(\x0b\x32\x17.google.api.PhpSettings\x12\x33\n\x0fpython_settings\x18\x18 \x01(\x0b\x32\x1a.google.api.PythonSettings\x12/\n\rnode_settings\x18\x19 \x01(\x0b\x32\x18.google.api.NodeSettings\x12\x33\n\x0f\x64otnet_settings\x18\x1a \x01(\x0b\x32\x1a.google.api.DotnetSettings\x12/\n\rruby_settings\x18\x1b \x01(\x0b\x32\x18.google.api.RubySettings\x12+\n\x0bgo_settings\x18\x1c \x01(\x0b\x32\x16.google.api.GoSettings"\xa8\x03\n\nPublishing\x12\x33\n\x0fmethod_settings\x18\x02 \x03(\x0b\x32\x1a.google.api.MethodSettings\x12\x15\n\rnew_issue_uri\x18\x65 \x01(\t\x12\x19\n\x11\x64ocumentation_uri\x18\x66 \x01(\t\x12\x16\n\x0e\x61pi_short_name\x18g \x01(\t\x12\x14\n\x0cgithub_label\x18h \x01(\t\x12\x1e\n\x16\x63odeowner_github_teams\x18i \x03(\t\x12\x16\n\x0e\x64oc_tag_prefix\x18j \x01(\t\x12;\n\x0corganization\x18k \x01(\x0e\x32%.google.api.ClientLibraryOrganization\x12;\n\x10library_settings\x18m \x03(\x0b\x32!.google.api.ClientLibrarySettings\x12)\n!proto_reference_documentation_uri\x18n \x01(\t\x12(\n rest_reference_documentation_uri\x18o \x01(\t"\xe3\x01\n\x0cJavaSettings\x12\x17\n\x0flibrary_package\x18\x01 \x01(\t\x12L\n\x13service_class_names\x18\x02 \x03(\x0b\x32/.google.api.JavaSettings.ServiceClassNamesEntry\x12\x32\n\x06\x63ommon\x18\x03 \x01(\x0b\x32".google.api.CommonLanguageSettings\x1a\x38\n\x16ServiceClassNamesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"A\n\x0b\x43ppSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings"Z\n\x0bPhpSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12\x17\n\x0flibrary_package\x18\x02 \x01(\t"\x9b\x02\n\x0ePythonSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12N\n\x15\x65xperimental_features\x18\x02 \x01(\x0b\x32/.google.api.PythonSettings.ExperimentalFeatures\x1a\x84\x01\n\x14\x45xperimentalFeatures\x12\x1d\n\x15rest_async_io_enabled\x18\x01 \x01(\x08\x12\'\n\x1fprotobuf_pythonic_types_enabled\x18\x02 \x01(\x08\x12$\n\x1cunversioned_package_disabled\x18\x03 \x01(\x08"B\n\x0cNodeSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings"\xaa\x03\n\x0e\x44otnetSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12I\n\x10renamed_services\x18\x02 \x03(\x0b\x32/.google.api.DotnetSettings.RenamedServicesEntry\x12K\n\x11renamed_resources\x18\x03 \x03(\x0b\x32\x30.google.api.DotnetSettings.RenamedResourcesEntry\x12\x19\n\x11ignored_resources\x18\x04 \x03(\t\x12 \n\x18\x66orced_namespace_aliases\x18\x05 \x03(\t\x12\x1e\n\x16handwritten_signatures\x18\x06 \x03(\t\x1a\x36\n\x14RenamedServicesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x37\n\x15RenamedResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"B\n\x0cRubySettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings"\xbf\x01\n\nGoSettings\x12\x32\n\x06\x63ommon\x18\x01 \x01(\x0b\x32".google.api.CommonLanguageSettings\x12\x45\n\x10renamed_services\x18\x02 \x03(\x0b\x32+.google.api.GoSettings.RenamedServicesEntry\x1a\x36\n\x14RenamedServicesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\x82\x03\n\x0eMethodSettings\x12\x10\n\x08selector\x18\x01 \x01(\t\x12<\n\x0clong_running\x18\x02 \x01(\x0b\x32&.google.api.MethodSettings.LongRunning\x12\x1d\n\x15\x61uto_populated_fields\x18\x03 \x03(\t\x12\x31\n\x08\x62\x61tching\x18\x04 \x01(\x0b\x32\x1f.google.api.BatchingConfigProto\x1a\xcd\x01\n\x0bLongRunning\x12\x35\n\x12initial_poll_delay\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x1d\n\x15poll_delay_multiplier\x18\x02 \x01(\x02\x12\x31\n\x0emax_poll_delay\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x35\n\x12total_poll_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration"Q\n\x18SelectiveGapicGeneration\x12\x0f\n\x07methods\x18\x01 \x03(\t\x12$\n\x1cgenerate_omitted_as_internal\x18\x02 \x01(\x08"\x8b\x01\n\x13\x42\x61tchingConfigProto\x12\x35\n\nthresholds\x18\x01 \x01(\x0b\x32!.google.api.BatchingSettingsProto\x12=\n\x10\x62\x61tch_descriptor\x18\x02 \x01(\x0b\x32#.google.api.BatchingDescriptorProto"\xeb\x02\n\x15\x42\x61tchingSettingsProto\x12\x1f\n\x17\x65lement_count_threshold\x18\x01 \x01(\x05\x12\x1e\n\x16request_byte_threshold\x18\x02 \x01(\x03\x12\x32\n\x0f\x64\x65lay_threshold\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x1b\n\x13\x65lement_count_limit\x18\x04 \x01(\x05\x12\x1a\n\x12request_byte_limit\x18\x05 \x01(\x05\x12"\n\x1a\x66low_control_element_limit\x18\x06 \x01(\x05\x12\x1f\n\x17\x66low_control_byte_limit\x18\x07 \x01(\x05\x12_\n$flow_control_limit_exceeded_behavior\x18\x08 \x01(\x0e\x32\x31.google.api.FlowControlLimitExceededBehaviorProto"i\n\x17\x42\x61tchingDescriptorProto\x12\x15\n\rbatched_field\x18\x01 \x01(\t\x12\x1c\n\x14\x64iscriminator_fields\x18\x02 \x03(\t\x12\x19\n\x11subresponse_field\x18\x03 \x01(\t*\xa3\x01\n\x19\x43lientLibraryOrganization\x12+\n\'CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED\x10\x00\x12\t\n\x05\x43LOUD\x10\x01\x12\x07\n\x03\x41\x44S\x10\x02\x12\n\n\x06PHOTOS\x10\x03\x12\x0f\n\x0bSTREET_VIEW\x10\x04\x12\x0c\n\x08SHOPPING\x10\x05\x12\x07\n\x03GEO\x10\x06\x12\x11\n\rGENERATIVE_AI\x10\x07*g\n\x18\x43lientLibraryDestination\x12*\n&CLIENT_LIBRARY_DESTINATION_UNSPECIFIED\x10\x00\x12\n\n\x06GITHUB\x10\n\x12\x13\n\x0fPACKAGE_MANAGER\x10\x14*g\n%FlowControlLimitExceededBehaviorProto\x12\x12\n\x0eUNSET_BEHAVIOR\x10\x00\x12\x13\n\x0fTHROW_EXCEPTION\x10\x01\x12\t\n\x05\x42LOCK\x10\x02\x12\n\n\x06IGNORE\x10\x03:9\n\x10method_signature\x12\x1e.google.protobuf.MethodOptions\x18\x9b\x08 \x03(\t:6\n\x0c\x64\x65\x66\x61ult_host\x12\x1f.google.protobuf.ServiceOptions\x18\x99\x08 \x01(\t:6\n\x0coauth_scopes\x12\x1f.google.protobuf.ServiceOptions\x18\x9a\x08 \x01(\t:8\n\x0b\x61pi_version\x12\x1f.google.protobuf.ServiceOptions\x18\xc1\xba\xab\xfa\x01 \x01(\tBi\n\x0e\x63om.google.apiB\x0b\x43lientProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.client_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\013ClientProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" - _globals["_COMMONLANGUAGESETTINGS"].fields_by_name[ - "reference_docs_uri" - ]._loaded_options = None - _globals["_COMMONLANGUAGESETTINGS"].fields_by_name[ - "reference_docs_uri" - ]._serialized_options = b"\030\001" - _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._loaded_options = None - _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._serialized_options = b"8\001" - _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._loaded_options = None - _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._serialized_options = b"8\001" - _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._loaded_options = None - _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._serialized_options = b"8\001" - _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._loaded_options = None - _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._serialized_options = b"8\001" - _globals["_CLIENTLIBRARYORGANIZATION"]._serialized_start = 3788 - _globals["_CLIENTLIBRARYORGANIZATION"]._serialized_end = 3951 - _globals["_CLIENTLIBRARYDESTINATION"]._serialized_start = 3953 - _globals["_CLIENTLIBRARYDESTINATION"]._serialized_end = 4056 - _globals["_FLOWCONTROLLIMITEXCEEDEDBEHAVIORPROTO"]._serialized_start = 4058 - _globals["_FLOWCONTROLLIMITEXCEEDEDBEHAVIORPROTO"]._serialized_end = 4161 - _globals["_COMMONLANGUAGESETTINGS"]._serialized_start = 137 - _globals["_COMMONLANGUAGESETTINGS"]._serialized_end = 327 - _globals["_CLIENTLIBRARYSETTINGS"]._serialized_start = 330 - _globals["_CLIENTLIBRARYSETTINGS"]._serialized_end = 837 - _globals["_PUBLISHING"]._serialized_start = 840 - _globals["_PUBLISHING"]._serialized_end = 1264 - _globals["_JAVASETTINGS"]._serialized_start = 1267 - _globals["_JAVASETTINGS"]._serialized_end = 1494 - _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._serialized_start = 1438 - _globals["_JAVASETTINGS_SERVICECLASSNAMESENTRY"]._serialized_end = 1494 - _globals["_CPPSETTINGS"]._serialized_start = 1496 - _globals["_CPPSETTINGS"]._serialized_end = 1561 - _globals["_PHPSETTINGS"]._serialized_start = 1563 - _globals["_PHPSETTINGS"]._serialized_end = 1653 - _globals["_PYTHONSETTINGS"]._serialized_start = 1656 - _globals["_PYTHONSETTINGS"]._serialized_end = 1939 - _globals["_PYTHONSETTINGS_EXPERIMENTALFEATURES"]._serialized_start = 1807 - _globals["_PYTHONSETTINGS_EXPERIMENTALFEATURES"]._serialized_end = 1939 - _globals["_NODESETTINGS"]._serialized_start = 1941 - _globals["_NODESETTINGS"]._serialized_end = 2007 - _globals["_DOTNETSETTINGS"]._serialized_start = 2010 - _globals["_DOTNETSETTINGS"]._serialized_end = 2436 - _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._serialized_start = 2325 - _globals["_DOTNETSETTINGS_RENAMEDSERVICESENTRY"]._serialized_end = 2379 - _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._serialized_start = 2381 - _globals["_DOTNETSETTINGS_RENAMEDRESOURCESENTRY"]._serialized_end = 2436 - _globals["_RUBYSETTINGS"]._serialized_start = 2438 - _globals["_RUBYSETTINGS"]._serialized_end = 2504 - _globals["_GOSETTINGS"]._serialized_start = 2507 - _globals["_GOSETTINGS"]._serialized_end = 2698 - _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._serialized_start = 2325 - _globals["_GOSETTINGS_RENAMEDSERVICESENTRY"]._serialized_end = 2379 - _globals["_METHODSETTINGS"]._serialized_start = 2701 - _globals["_METHODSETTINGS"]._serialized_end = 3087 - _globals["_METHODSETTINGS_LONGRUNNING"]._serialized_start = 2882 - _globals["_METHODSETTINGS_LONGRUNNING"]._serialized_end = 3087 - _globals["_SELECTIVEGAPICGENERATION"]._serialized_start = 3089 - _globals["_SELECTIVEGAPICGENERATION"]._serialized_end = 3170 - _globals["_BATCHINGCONFIGPROTO"]._serialized_start = 3173 - _globals["_BATCHINGCONFIGPROTO"]._serialized_end = 3312 - _globals["_BATCHINGSETTINGSPROTO"]._serialized_start = 3315 - _globals["_BATCHINGSETTINGSPROTO"]._serialized_end = 3678 - _globals["_BATCHINGDESCRIPTORPROTO"]._serialized_start = 3680 - _globals["_BATCHINGDESCRIPTORPROTO"]._serialized_end = 3785 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi deleted file mode 100644 index c25654fb9a2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/client_pb2.pyi +++ /dev/null @@ -1,498 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf import duration_pb2 as _duration_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -from google.api import launch_stage_pb2 as _launch_stage_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class ClientLibraryOrganization(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED: _ClassVar[ClientLibraryOrganization] - CLOUD: _ClassVar[ClientLibraryOrganization] - ADS: _ClassVar[ClientLibraryOrganization] - PHOTOS: _ClassVar[ClientLibraryOrganization] - STREET_VIEW: _ClassVar[ClientLibraryOrganization] - SHOPPING: _ClassVar[ClientLibraryOrganization] - GEO: _ClassVar[ClientLibraryOrganization] - GENERATIVE_AI: _ClassVar[ClientLibraryOrganization] - -class ClientLibraryDestination(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - CLIENT_LIBRARY_DESTINATION_UNSPECIFIED: _ClassVar[ClientLibraryDestination] - GITHUB: _ClassVar[ClientLibraryDestination] - PACKAGE_MANAGER: _ClassVar[ClientLibraryDestination] - -class FlowControlLimitExceededBehaviorProto( - int, metaclass=_enum_type_wrapper.EnumTypeWrapper -): - __slots__ = () - UNSET_BEHAVIOR: _ClassVar[FlowControlLimitExceededBehaviorProto] - THROW_EXCEPTION: _ClassVar[FlowControlLimitExceededBehaviorProto] - BLOCK: _ClassVar[FlowControlLimitExceededBehaviorProto] - IGNORE: _ClassVar[FlowControlLimitExceededBehaviorProto] - -CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED: ClientLibraryOrganization -CLOUD: ClientLibraryOrganization -ADS: ClientLibraryOrganization -PHOTOS: ClientLibraryOrganization -STREET_VIEW: ClientLibraryOrganization -SHOPPING: ClientLibraryOrganization -GEO: ClientLibraryOrganization -GENERATIVE_AI: ClientLibraryOrganization -CLIENT_LIBRARY_DESTINATION_UNSPECIFIED: ClientLibraryDestination -GITHUB: ClientLibraryDestination -PACKAGE_MANAGER: ClientLibraryDestination -UNSET_BEHAVIOR: FlowControlLimitExceededBehaviorProto -THROW_EXCEPTION: FlowControlLimitExceededBehaviorProto -BLOCK: FlowControlLimitExceededBehaviorProto -IGNORE: FlowControlLimitExceededBehaviorProto -METHOD_SIGNATURE_FIELD_NUMBER: _ClassVar[int] -method_signature: _descriptor.FieldDescriptor -DEFAULT_HOST_FIELD_NUMBER: _ClassVar[int] -default_host: _descriptor.FieldDescriptor -OAUTH_SCOPES_FIELD_NUMBER: _ClassVar[int] -oauth_scopes: _descriptor.FieldDescriptor -API_VERSION_FIELD_NUMBER: _ClassVar[int] -api_version: _descriptor.FieldDescriptor - -class CommonLanguageSettings(_message.Message): - __slots__ = ("reference_docs_uri", "destinations", "selective_gapic_generation") - REFERENCE_DOCS_URI_FIELD_NUMBER: _ClassVar[int] - DESTINATIONS_FIELD_NUMBER: _ClassVar[int] - SELECTIVE_GAPIC_GENERATION_FIELD_NUMBER: _ClassVar[int] - reference_docs_uri: str - destinations: _containers.RepeatedScalarFieldContainer[ClientLibraryDestination] - selective_gapic_generation: SelectiveGapicGeneration - def __init__( - self, - reference_docs_uri: _Optional[str] = ..., - destinations: _Optional[_Iterable[_Union[ClientLibraryDestination, str]]] = ..., - selective_gapic_generation: _Optional[ - _Union[SelectiveGapicGeneration, _Mapping] - ] = ..., - ) -> None: ... - -class ClientLibrarySettings(_message.Message): - __slots__ = ( - "version", - "launch_stage", - "rest_numeric_enums", - "java_settings", - "cpp_settings", - "php_settings", - "python_settings", - "node_settings", - "dotnet_settings", - "ruby_settings", - "go_settings", - ) - VERSION_FIELD_NUMBER: _ClassVar[int] - LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] - REST_NUMERIC_ENUMS_FIELD_NUMBER: _ClassVar[int] - JAVA_SETTINGS_FIELD_NUMBER: _ClassVar[int] - CPP_SETTINGS_FIELD_NUMBER: _ClassVar[int] - PHP_SETTINGS_FIELD_NUMBER: _ClassVar[int] - PYTHON_SETTINGS_FIELD_NUMBER: _ClassVar[int] - NODE_SETTINGS_FIELD_NUMBER: _ClassVar[int] - DOTNET_SETTINGS_FIELD_NUMBER: _ClassVar[int] - RUBY_SETTINGS_FIELD_NUMBER: _ClassVar[int] - GO_SETTINGS_FIELD_NUMBER: _ClassVar[int] - version: str - launch_stage: _launch_stage_pb2.LaunchStage - rest_numeric_enums: bool - java_settings: JavaSettings - cpp_settings: CppSettings - php_settings: PhpSettings - python_settings: PythonSettings - node_settings: NodeSettings - dotnet_settings: DotnetSettings - ruby_settings: RubySettings - go_settings: GoSettings - def __init__( - self, - version: _Optional[str] = ..., - launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., - rest_numeric_enums: _Optional[bool] = ..., - java_settings: _Optional[_Union[JavaSettings, _Mapping]] = ..., - cpp_settings: _Optional[_Union[CppSettings, _Mapping]] = ..., - php_settings: _Optional[_Union[PhpSettings, _Mapping]] = ..., - python_settings: _Optional[_Union[PythonSettings, _Mapping]] = ..., - node_settings: _Optional[_Union[NodeSettings, _Mapping]] = ..., - dotnet_settings: _Optional[_Union[DotnetSettings, _Mapping]] = ..., - ruby_settings: _Optional[_Union[RubySettings, _Mapping]] = ..., - go_settings: _Optional[_Union[GoSettings, _Mapping]] = ..., - ) -> None: ... - -class Publishing(_message.Message): - __slots__ = ( - "method_settings", - "new_issue_uri", - "documentation_uri", - "api_short_name", - "github_label", - "codeowner_github_teams", - "doc_tag_prefix", - "organization", - "library_settings", - "proto_reference_documentation_uri", - "rest_reference_documentation_uri", - ) - METHOD_SETTINGS_FIELD_NUMBER: _ClassVar[int] - NEW_ISSUE_URI_FIELD_NUMBER: _ClassVar[int] - DOCUMENTATION_URI_FIELD_NUMBER: _ClassVar[int] - API_SHORT_NAME_FIELD_NUMBER: _ClassVar[int] - GITHUB_LABEL_FIELD_NUMBER: _ClassVar[int] - CODEOWNER_GITHUB_TEAMS_FIELD_NUMBER: _ClassVar[int] - DOC_TAG_PREFIX_FIELD_NUMBER: _ClassVar[int] - ORGANIZATION_FIELD_NUMBER: _ClassVar[int] - LIBRARY_SETTINGS_FIELD_NUMBER: _ClassVar[int] - PROTO_REFERENCE_DOCUMENTATION_URI_FIELD_NUMBER: _ClassVar[int] - REST_REFERENCE_DOCUMENTATION_URI_FIELD_NUMBER: _ClassVar[int] - method_settings: _containers.RepeatedCompositeFieldContainer[MethodSettings] - new_issue_uri: str - documentation_uri: str - api_short_name: str - github_label: str - codeowner_github_teams: _containers.RepeatedScalarFieldContainer[str] - doc_tag_prefix: str - organization: ClientLibraryOrganization - library_settings: _containers.RepeatedCompositeFieldContainer[ClientLibrarySettings] - proto_reference_documentation_uri: str - rest_reference_documentation_uri: str - def __init__( - self, - method_settings: _Optional[_Iterable[_Union[MethodSettings, _Mapping]]] = ..., - new_issue_uri: _Optional[str] = ..., - documentation_uri: _Optional[str] = ..., - api_short_name: _Optional[str] = ..., - github_label: _Optional[str] = ..., - codeowner_github_teams: _Optional[_Iterable[str]] = ..., - doc_tag_prefix: _Optional[str] = ..., - organization: _Optional[_Union[ClientLibraryOrganization, str]] = ..., - library_settings: _Optional[ - _Iterable[_Union[ClientLibrarySettings, _Mapping]] - ] = ..., - proto_reference_documentation_uri: _Optional[str] = ..., - rest_reference_documentation_uri: _Optional[str] = ..., - ) -> None: ... - -class JavaSettings(_message.Message): - __slots__ = ("library_package", "service_class_names", "common") - class ServiceClassNamesEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - LIBRARY_PACKAGE_FIELD_NUMBER: _ClassVar[int] - SERVICE_CLASS_NAMES_FIELD_NUMBER: _ClassVar[int] - COMMON_FIELD_NUMBER: _ClassVar[int] - library_package: str - service_class_names: _containers.ScalarMap[str, str] - common: CommonLanguageSettings - def __init__( - self, - library_package: _Optional[str] = ..., - service_class_names: _Optional[_Mapping[str, str]] = ..., - common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., - ) -> None: ... - -class CppSettings(_message.Message): - __slots__ = ("common",) - COMMON_FIELD_NUMBER: _ClassVar[int] - common: CommonLanguageSettings - def __init__( - self, common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ... - ) -> None: ... - -class PhpSettings(_message.Message): - __slots__ = ("common", "library_package") - COMMON_FIELD_NUMBER: _ClassVar[int] - LIBRARY_PACKAGE_FIELD_NUMBER: _ClassVar[int] - common: CommonLanguageSettings - library_package: str - def __init__( - self, - common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., - library_package: _Optional[str] = ..., - ) -> None: ... - -class PythonSettings(_message.Message): - __slots__ = ("common", "experimental_features") - class ExperimentalFeatures(_message.Message): - __slots__ = ( - "rest_async_io_enabled", - "protobuf_pythonic_types_enabled", - "unversioned_package_disabled", - ) - REST_ASYNC_IO_ENABLED_FIELD_NUMBER: _ClassVar[int] - PROTOBUF_PYTHONIC_TYPES_ENABLED_FIELD_NUMBER: _ClassVar[int] - UNVERSIONED_PACKAGE_DISABLED_FIELD_NUMBER: _ClassVar[int] - rest_async_io_enabled: bool - protobuf_pythonic_types_enabled: bool - unversioned_package_disabled: bool - def __init__( - self, - rest_async_io_enabled: _Optional[bool] = ..., - protobuf_pythonic_types_enabled: _Optional[bool] = ..., - unversioned_package_disabled: _Optional[bool] = ..., - ) -> None: ... - - COMMON_FIELD_NUMBER: _ClassVar[int] - EXPERIMENTAL_FEATURES_FIELD_NUMBER: _ClassVar[int] - common: CommonLanguageSettings - experimental_features: PythonSettings.ExperimentalFeatures - def __init__( - self, - common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., - experimental_features: _Optional[ - _Union[PythonSettings.ExperimentalFeatures, _Mapping] - ] = ..., - ) -> None: ... - -class NodeSettings(_message.Message): - __slots__ = ("common",) - COMMON_FIELD_NUMBER: _ClassVar[int] - common: CommonLanguageSettings - def __init__( - self, common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ... - ) -> None: ... - -class DotnetSettings(_message.Message): - __slots__ = ( - "common", - "renamed_services", - "renamed_resources", - "ignored_resources", - "forced_namespace_aliases", - "handwritten_signatures", - ) - class RenamedServicesEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - class RenamedResourcesEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - COMMON_FIELD_NUMBER: _ClassVar[int] - RENAMED_SERVICES_FIELD_NUMBER: _ClassVar[int] - RENAMED_RESOURCES_FIELD_NUMBER: _ClassVar[int] - IGNORED_RESOURCES_FIELD_NUMBER: _ClassVar[int] - FORCED_NAMESPACE_ALIASES_FIELD_NUMBER: _ClassVar[int] - HANDWRITTEN_SIGNATURES_FIELD_NUMBER: _ClassVar[int] - common: CommonLanguageSettings - renamed_services: _containers.ScalarMap[str, str] - renamed_resources: _containers.ScalarMap[str, str] - ignored_resources: _containers.RepeatedScalarFieldContainer[str] - forced_namespace_aliases: _containers.RepeatedScalarFieldContainer[str] - handwritten_signatures: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., - renamed_services: _Optional[_Mapping[str, str]] = ..., - renamed_resources: _Optional[_Mapping[str, str]] = ..., - ignored_resources: _Optional[_Iterable[str]] = ..., - forced_namespace_aliases: _Optional[_Iterable[str]] = ..., - handwritten_signatures: _Optional[_Iterable[str]] = ..., - ) -> None: ... - -class RubySettings(_message.Message): - __slots__ = ("common",) - COMMON_FIELD_NUMBER: _ClassVar[int] - common: CommonLanguageSettings - def __init__( - self, common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ... - ) -> None: ... - -class GoSettings(_message.Message): - __slots__ = ("common", "renamed_services") - class RenamedServicesEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - COMMON_FIELD_NUMBER: _ClassVar[int] - RENAMED_SERVICES_FIELD_NUMBER: _ClassVar[int] - common: CommonLanguageSettings - renamed_services: _containers.ScalarMap[str, str] - def __init__( - self, - common: _Optional[_Union[CommonLanguageSettings, _Mapping]] = ..., - renamed_services: _Optional[_Mapping[str, str]] = ..., - ) -> None: ... - -class MethodSettings(_message.Message): - __slots__ = ("selector", "long_running", "auto_populated_fields", "batching") - class LongRunning(_message.Message): - __slots__ = ( - "initial_poll_delay", - "poll_delay_multiplier", - "max_poll_delay", - "total_poll_timeout", - ) - INITIAL_POLL_DELAY_FIELD_NUMBER: _ClassVar[int] - POLL_DELAY_MULTIPLIER_FIELD_NUMBER: _ClassVar[int] - MAX_POLL_DELAY_FIELD_NUMBER: _ClassVar[int] - TOTAL_POLL_TIMEOUT_FIELD_NUMBER: _ClassVar[int] - initial_poll_delay: _duration_pb2.Duration - poll_delay_multiplier: float - max_poll_delay: _duration_pb2.Duration - total_poll_timeout: _duration_pb2.Duration - def __init__( - self, - initial_poll_delay: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - poll_delay_multiplier: _Optional[float] = ..., - max_poll_delay: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - total_poll_timeout: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - ) -> None: ... - - SELECTOR_FIELD_NUMBER: _ClassVar[int] - LONG_RUNNING_FIELD_NUMBER: _ClassVar[int] - AUTO_POPULATED_FIELDS_FIELD_NUMBER: _ClassVar[int] - BATCHING_FIELD_NUMBER: _ClassVar[int] - selector: str - long_running: MethodSettings.LongRunning - auto_populated_fields: _containers.RepeatedScalarFieldContainer[str] - batching: BatchingConfigProto - def __init__( - self, - selector: _Optional[str] = ..., - long_running: _Optional[_Union[MethodSettings.LongRunning, _Mapping]] = ..., - auto_populated_fields: _Optional[_Iterable[str]] = ..., - batching: _Optional[_Union[BatchingConfigProto, _Mapping]] = ..., - ) -> None: ... - -class SelectiveGapicGeneration(_message.Message): - __slots__ = ("methods", "generate_omitted_as_internal") - METHODS_FIELD_NUMBER: _ClassVar[int] - GENERATE_OMITTED_AS_INTERNAL_FIELD_NUMBER: _ClassVar[int] - methods: _containers.RepeatedScalarFieldContainer[str] - generate_omitted_as_internal: bool - def __init__( - self, - methods: _Optional[_Iterable[str]] = ..., - generate_omitted_as_internal: _Optional[bool] = ..., - ) -> None: ... - -class BatchingConfigProto(_message.Message): - __slots__ = ("thresholds", "batch_descriptor") - THRESHOLDS_FIELD_NUMBER: _ClassVar[int] - BATCH_DESCRIPTOR_FIELD_NUMBER: _ClassVar[int] - thresholds: BatchingSettingsProto - batch_descriptor: BatchingDescriptorProto - def __init__( - self, - thresholds: _Optional[_Union[BatchingSettingsProto, _Mapping]] = ..., - batch_descriptor: _Optional[_Union[BatchingDescriptorProto, _Mapping]] = ..., - ) -> None: ... - -class BatchingSettingsProto(_message.Message): - __slots__ = ( - "element_count_threshold", - "request_byte_threshold", - "delay_threshold", - "element_count_limit", - "request_byte_limit", - "flow_control_element_limit", - "flow_control_byte_limit", - "flow_control_limit_exceeded_behavior", - ) - ELEMENT_COUNT_THRESHOLD_FIELD_NUMBER: _ClassVar[int] - REQUEST_BYTE_THRESHOLD_FIELD_NUMBER: _ClassVar[int] - DELAY_THRESHOLD_FIELD_NUMBER: _ClassVar[int] - ELEMENT_COUNT_LIMIT_FIELD_NUMBER: _ClassVar[int] - REQUEST_BYTE_LIMIT_FIELD_NUMBER: _ClassVar[int] - FLOW_CONTROL_ELEMENT_LIMIT_FIELD_NUMBER: _ClassVar[int] - FLOW_CONTROL_BYTE_LIMIT_FIELD_NUMBER: _ClassVar[int] - FLOW_CONTROL_LIMIT_EXCEEDED_BEHAVIOR_FIELD_NUMBER: _ClassVar[int] - element_count_threshold: int - request_byte_threshold: int - delay_threshold: _duration_pb2.Duration - element_count_limit: int - request_byte_limit: int - flow_control_element_limit: int - flow_control_byte_limit: int - flow_control_limit_exceeded_behavior: FlowControlLimitExceededBehaviorProto - def __init__( - self, - element_count_threshold: _Optional[int] = ..., - request_byte_threshold: _Optional[int] = ..., - delay_threshold: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - element_count_limit: _Optional[int] = ..., - request_byte_limit: _Optional[int] = ..., - flow_control_element_limit: _Optional[int] = ..., - flow_control_byte_limit: _Optional[int] = ..., - flow_control_limit_exceeded_behavior: _Optional[ - _Union[FlowControlLimitExceededBehaviorProto, str] - ] = ..., - ) -> None: ... - -class BatchingDescriptorProto(_message.Message): - __slots__ = ("batched_field", "discriminator_fields", "subresponse_field") - BATCHED_FIELD_FIELD_NUMBER: _ClassVar[int] - DISCRIMINATOR_FIELDS_FIELD_NUMBER: _ClassVar[int] - SUBRESPONSE_FIELD_FIELD_NUMBER: _ClassVar[int] - batched_field: str - discriminator_fields: _containers.RepeatedScalarFieldContainer[str] - subresponse_field: str - def __init__( - self, - batched_field: _Optional[str] = ..., - discriminator_fields: _Optional[_Iterable[str]] = ..., - subresponse_field: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto deleted file mode 100644 index b6792b9a50a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change.proto +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/configchange;configchange"; -option java_multiple_files = true; -option java_outer_classname = "ConfigChangeProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Output generated from semantically comparing two versions of a service -// configuration. -// -// Includes detailed information about a field that have changed with -// applicable advice about potential consequences for the change, such as -// backwards-incompatibility. -message ConfigChange { - // Object hierarchy path to the change, with levels separated by a '.' - // character. For repeated fields, an applicable unique identifier field is - // used for the index (usually selector, name, or id). For maps, the term - // 'key' is used. If the field has no unique identifier, the numeric index - // is used. - // Examples: - // - visibility.rules[selector=="google.LibraryService.ListBooks"].restriction - // - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value - // - logging.producer_destinations[0] - string element = 1; - - // Value of the changed object in the old Service configuration, - // in JSON format. This field will not be populated if ChangeType == ADDED. - string old_value = 2; - - // Value of the changed object in the new Service configuration, - // in JSON format. This field will not be populated if ChangeType == REMOVED. - string new_value = 3; - - // The type for this change, either ADDED, REMOVED, or MODIFIED. - ChangeType change_type = 4; - - // Collection of advice provided for this change, useful for determining the - // possible impact of this change. - repeated Advice advices = 5; -} - -// Generated advice about this change, used for providing more -// information about how a change will affect the existing service. -message Advice { - // Useful description for why this advice was applied and what actions should - // be taken to mitigate any implied risks. - string description = 2; -} - -// Classifies set of possible modifications to an object in the service -// configuration. -enum ChangeType { - // No value was provided. - CHANGE_TYPE_UNSPECIFIED = 0; - - // The changed object exists in the 'new' service configuration, but not - // in the 'old' service configuration. - ADDED = 1; - - // The changed object exists in the 'old' service configuration, but not - // in the 'new' service configuration. - REMOVED = 2; - - // The changed object exists in both service configurations, but its value - // is different. - MODIFIED = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py deleted file mode 100644 index 4214edfa424..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/config_change.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/config_change.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1egoogle/api/config_change.proto\x12\ngoogle.api"\x97\x01\n\x0c\x43onfigChange\x12\x0f\n\x07\x65lement\x18\x01 \x01(\t\x12\x11\n\told_value\x18\x02 \x01(\t\x12\x11\n\tnew_value\x18\x03 \x01(\t\x12+\n\x0b\x63hange_type\x18\x04 \x01(\x0e\x32\x16.google.api.ChangeType\x12#\n\x07\x61\x64vices\x18\x05 \x03(\x0b\x32\x12.google.api.Advice"\x1d\n\x06\x41\x64vice\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t*O\n\nChangeType\x12\x1b\n\x17\x43HANGE_TYPE_UNSPECIFIED\x10\x00\x12\t\n\x05\x41\x44\x44\x45\x44\x10\x01\x12\x0b\n\x07REMOVED\x10\x02\x12\x0c\n\x08MODIFIED\x10\x03\x42q\n\x0e\x63om.google.apiB\x11\x43onfigChangeProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/configchange;configchange\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.config_change_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\021ConfigChangeProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/configchange;configchange\242\002\004GAPI" - _globals["_CHANGETYPE"]._serialized_start = 231 - _globals["_CHANGETYPE"]._serialized_end = 310 - _globals["_CONFIGCHANGE"]._serialized_start = 47 - _globals["_CONFIGCHANGE"]._serialized_end = 198 - _globals["_ADVICE"]._serialized_start = 200 - _globals["_ADVICE"]._serialized_end = 229 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi deleted file mode 100644 index 3c7f2c3d27f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/config_change_pb2.pyi +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class ChangeType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - CHANGE_TYPE_UNSPECIFIED: _ClassVar[ChangeType] - ADDED: _ClassVar[ChangeType] - REMOVED: _ClassVar[ChangeType] - MODIFIED: _ClassVar[ChangeType] - -CHANGE_TYPE_UNSPECIFIED: ChangeType -ADDED: ChangeType -REMOVED: ChangeType -MODIFIED: ChangeType - -class ConfigChange(_message.Message): - __slots__ = ("element", "old_value", "new_value", "change_type", "advices") - ELEMENT_FIELD_NUMBER: _ClassVar[int] - OLD_VALUE_FIELD_NUMBER: _ClassVar[int] - NEW_VALUE_FIELD_NUMBER: _ClassVar[int] - CHANGE_TYPE_FIELD_NUMBER: _ClassVar[int] - ADVICES_FIELD_NUMBER: _ClassVar[int] - element: str - old_value: str - new_value: str - change_type: ChangeType - advices: _containers.RepeatedCompositeFieldContainer[Advice] - def __init__( - self, - element: _Optional[str] = ..., - old_value: _Optional[str] = ..., - new_value: _Optional[str] = ..., - change_type: _Optional[_Union[ChangeType, str]] = ..., - advices: _Optional[_Iterable[_Union[Advice, _Mapping]]] = ..., - ) -> None: ... - -class Advice(_message.Message): - __slots__ = ("description",) - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - description: str - def __init__(self, description: _Optional[str] = ...) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto deleted file mode 100644 index 303604900b9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer.proto +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "ConsumerProto"; -option java_package = "com.google.api"; - -// A descriptor for defining project properties for a service. One service may -// have many consumer projects, and the service may want to behave differently -// depending on some properties on the project. For example, a project may be -// associated with a school, or a business, or a government agency, a business -// type property on the project may affect how a service responds to the client. -// This descriptor defines which properties are allowed to be set on a project. -// -// Example: -// -// project_properties: -// properties: -// - name: NO_WATERMARK -// type: BOOL -// description: Allows usage of the API without watermarks. -// - name: EXTENDED_TILE_CACHE_PERIOD -// type: INT64 -message ProjectProperties { - // List of per consumer project-specific properties. - repeated Property properties = 1; -} - -// Defines project properties. -// -// API services can define properties that can be assigned to consumer projects -// so that backends can perform response customization without having to make -// additional calls or maintain additional storage. For example, Maps API -// defines properties that controls map tile cache period, or whether to embed a -// watermark in a result. -// -// These values can be set via API producer console. Only API providers can -// define and set these properties. -message Property { - // Supported data type of the property values - enum PropertyType { - // The type is unspecified, and will result in an error. - UNSPECIFIED = 0; - - // The type is `int64`. - INT64 = 1; - - // The type is `bool`. - BOOL = 2; - - // The type is `string`. - STRING = 3; - - // The type is 'double'. - DOUBLE = 4; - } - - // The name of the property (a.k.a key). - string name = 1; - - // The type of this property. - PropertyType type = 2; - - // The description of the property - string description = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py deleted file mode 100644 index 05fc69243e5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/consumer.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/consumer.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x19google/api/consumer.proto\x12\ngoogle.api"=\n\x11ProjectProperties\x12(\n\nproperties\x18\x01 \x03(\x0b\x32\x14.google.api.Property"\xac\x01\n\x08Property\x12\x0c\n\x04name\x18\x01 \x01(\t\x12/\n\x04type\x18\x02 \x01(\x0e\x32!.google.api.Property.PropertyType\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"L\n\x0cPropertyType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\t\n\x05INT64\x10\x01\x12\x08\n\x04\x42OOL\x10\x02\x12\n\n\x06STRING\x10\x03\x12\n\n\x06\x44OUBLE\x10\x04\x42h\n\x0e\x63om.google.apiB\rConsumerProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.consumer_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\rConsumerProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig" - _globals["_PROJECTPROPERTIES"]._serialized_start = 41 - _globals["_PROJECTPROPERTIES"]._serialized_end = 102 - _globals["_PROPERTY"]._serialized_start = 105 - _globals["_PROPERTY"]._serialized_end = 277 - _globals["_PROPERTY_PROPERTYTYPE"]._serialized_start = 201 - _globals["_PROPERTY_PROPERTYTYPE"]._serialized_end = 277 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi deleted file mode 100644 index 4e990bff7bf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/consumer_pb2.pyi +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class ProjectProperties(_message.Message): - __slots__ = ("properties",) - PROPERTIES_FIELD_NUMBER: _ClassVar[int] - properties: _containers.RepeatedCompositeFieldContainer[Property] - def __init__( - self, properties: _Optional[_Iterable[_Union[Property, _Mapping]]] = ... - ) -> None: ... - -class Property(_message.Message): - __slots__ = ("name", "type", "description") - class PropertyType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - UNSPECIFIED: _ClassVar[Property.PropertyType] - INT64: _ClassVar[Property.PropertyType] - BOOL: _ClassVar[Property.PropertyType] - STRING: _ClassVar[Property.PropertyType] - DOUBLE: _ClassVar[Property.PropertyType] - - UNSPECIFIED: Property.PropertyType - INT64: Property.PropertyType - BOOL: Property.PropertyType - STRING: Property.PropertyType - DOUBLE: Property.PropertyType - NAME_FIELD_NUMBER: _ClassVar[int] - TYPE_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - name: str - type: Property.PropertyType - description: str - def __init__( - self, - name: _Optional[str] = ..., - type: _Optional[_Union[Property.PropertyType, str]] = ..., - description: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto deleted file mode 100644 index c1704f1e999..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context.proto +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "ContextProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// `Context` defines which contexts an API requests. -// -// Example: -// -// context: -// rules: -// - selector: "*" -// requested: -// - google.rpc.context.ProjectContext -// - google.rpc.context.OriginContext -// -// The above specifies that all methods in the API request -// `google.rpc.context.ProjectContext` and -// `google.rpc.context.OriginContext`. -// -// Available context types are defined in package -// `google.rpc.context`. -// -// This also provides mechanism to allowlist any protobuf message extension that -// can be sent in grpc metadata using “x-goog-ext--bin” and -// “x-goog-ext--jspb” format. For example, list any service -// specific protobuf types that can appear in grpc metadata as follows in your -// yaml file: -// -// Example: -// -// context: -// rules: -// - selector: "google.example.library.v1.LibraryService.CreateBook" -// allowed_request_extensions: -// - google.foo.v1.NewExtension -// allowed_response_extensions: -// - google.foo.v1.NewExtension -// -// You can also specify extension ID instead of fully qualified extension name -// here. -message Context { - // A list of RPC context rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated ContextRule rules = 1; -} - -// A context rule provides information about the context for an individual API -// element. -message ContextRule { - // Selects the methods to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // A list of full type names of requested contexts, only the requested context - // will be made available to the backend. - repeated string requested = 2; - - // A list of full type names of provided contexts. It is used to support - // propagating HTTP headers and ETags from the response extension. - repeated string provided = 3; - - // A list of full type names or extension IDs of extensions allowed in grpc - // side channel from client to backend. - repeated string allowed_request_extensions = 4; - - // A list of full type names or extension IDs of extensions allowed in grpc - // side channel from backend to client. - repeated string allowed_response_extensions = 5; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py deleted file mode 100644 index d69b6772f76..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/context.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/context.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x18google/api/context.proto\x12\ngoogle.api"1\n\x07\x43ontext\x12&\n\x05rules\x18\x01 \x03(\x0b\x32\x17.google.api.ContextRule"\x8d\x01\n\x0b\x43ontextRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x11\n\trequested\x18\x02 \x03(\t\x12\x10\n\x08provided\x18\x03 \x03(\t\x12"\n\x1a\x61llowed_request_extensions\x18\x04 \x03(\t\x12#\n\x1b\x61llowed_response_extensions\x18\x05 \x03(\tBn\n\x0e\x63om.google.apiB\x0c\x43ontextProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.context_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\014ContextProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_CONTEXT"]._serialized_start = 40 - _globals["_CONTEXT"]._serialized_end = 89 - _globals["_CONTEXTRULE"]._serialized_start = 92 - _globals["_CONTEXTRULE"]._serialized_end = 233 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi deleted file mode 100644 index 65612dbd1ae..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/context_pb2.pyi +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Context(_message.Message): - __slots__ = ("rules",) - RULES_FIELD_NUMBER: _ClassVar[int] - rules: _containers.RepeatedCompositeFieldContainer[ContextRule] - def __init__( - self, rules: _Optional[_Iterable[_Union[ContextRule, _Mapping]]] = ... - ) -> None: ... - -class ContextRule(_message.Message): - __slots__ = ( - "selector", - "requested", - "provided", - "allowed_request_extensions", - "allowed_response_extensions", - ) - SELECTOR_FIELD_NUMBER: _ClassVar[int] - REQUESTED_FIELD_NUMBER: _ClassVar[int] - PROVIDED_FIELD_NUMBER: _ClassVar[int] - ALLOWED_REQUEST_EXTENSIONS_FIELD_NUMBER: _ClassVar[int] - ALLOWED_RESPONSE_EXTENSIONS_FIELD_NUMBER: _ClassVar[int] - selector: str - requested: _containers.RepeatedScalarFieldContainer[str] - provided: _containers.RepeatedScalarFieldContainer[str] - allowed_request_extensions: _containers.RepeatedScalarFieldContainer[str] - allowed_response_extensions: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - selector: _Optional[str] = ..., - requested: _Optional[_Iterable[str]] = ..., - provided: _Optional[_Iterable[str]] = ..., - allowed_request_extensions: _Optional[_Iterable[str]] = ..., - allowed_response_extensions: _Optional[_Iterable[str]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto deleted file mode 100644 index c0dc0cdc3d2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/policy.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "ControlProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Selects and configures the service controller used by the service. -// -// Example: -// -// control: -// environment: servicecontrol.googleapis.com -message Control { - // The service controller environment to use. If empty, no control plane - // features (like quota and billing) will be enabled. The recommended value - // for most services is servicecontrol.googleapis.com. - string environment = 1; - - // Defines policies applying to the API methods of the service. - repeated MethodPolicy method_policies = 4; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py deleted file mode 100644 index d9780a126b1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/control.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/control.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.api import policy_pb2 as google_dot_api_dot_policy__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x18google/api/control.proto\x12\ngoogle.api\x1a\x17google/api/policy.proto"Q\n\x07\x43ontrol\x12\x13\n\x0b\x65nvironment\x18\x01 \x01(\t\x12\x31\n\x0fmethod_policies\x18\x04 \x03(\x0b\x32\x18.google.api.MethodPolicyBn\n\x0e\x63om.google.apiB\x0c\x43ontrolProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.control_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\014ControlProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_CONTROL"]._serialized_start = 65 - _globals["_CONTROL"]._serialized_end = 146 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi deleted file mode 100644 index 789dc6c0536..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/control_pb2.pyi +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -from google.api import policy_pb2 as _policy_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class Control(_message.Message): - __slots__ = ("environment", "method_policies") - ENVIRONMENT_FIELD_NUMBER: _ClassVar[int] - METHOD_POLICIES_FIELD_NUMBER: _ClassVar[int] - environment: str - method_policies: _containers.RepeatedCompositeFieldContainer[ - _policy_pb2.MethodPolicy - ] - def __init__( - self, - environment: _Optional[str] = ..., - method_policies: _Optional[ - _Iterable[_Union[_policy_pb2.MethodPolicy, _Mapping]] - ] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto deleted file mode 100644 index 51cf36ef4f9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution.proto +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/distribution;distribution"; -option java_multiple_files = true; -option java_outer_classname = "DistributionProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// `Distribution` contains summary statistics for a population of values. It -// optionally contains a histogram representing the distribution of those values -// across a set of buckets. -// -// The summary statistics are the count, mean, sum of the squared deviation from -// the mean, the minimum, and the maximum of the set of population of values. -// The histogram is based on a sequence of buckets and gives a count of values -// that fall into each bucket. The boundaries of the buckets are given either -// explicitly or by formulas for buckets of fixed or exponentially increasing -// widths. -// -// Although it is not forbidden, it is generally a bad idea to include -// non-finite values (infinities or NaNs) in the population of values, as this -// will render the `mean` and `sum_of_squared_deviation` fields meaningless. -message Distribution { - // The range of the population values. - message Range { - // The minimum of the population values. - double min = 1; - - // The maximum of the population values. - double max = 2; - } - - // `BucketOptions` describes the bucket boundaries used to create a histogram - // for the distribution. The buckets can be in a linear sequence, an - // exponential sequence, or each bucket can be specified explicitly. - // `BucketOptions` does not include the number of values in each bucket. - // - // A bucket has an inclusive lower bound and exclusive upper bound for the - // values that are counted for that bucket. The upper bound of a bucket must - // be strictly greater than the lower bound. The sequence of N buckets for a - // distribution consists of an underflow bucket (number 0), zero or more - // finite buckets (number 1 through N - 2) and an overflow bucket (number N - - // 1). The buckets are contiguous: the lower bound of bucket i (i > 0) is the - // same as the upper bound of bucket i - 1. The buckets span the whole range - // of finite values: lower bound of the underflow bucket is -infinity and the - // upper bound of the overflow bucket is +infinity. The finite buckets are - // so-called because both bounds are finite. - message BucketOptions { - // Specifies a linear sequence of buckets that all have the same width - // (except overflow and underflow). Each bucket represents a constant - // absolute uncertainty on the specific value in the bucket. - // - // There are `num_finite_buckets + 2` (= N) buckets. Bucket `i` has the - // following boundaries: - // - // Upper bound (0 <= i < N-1): offset + (width * i). - // - // Lower bound (1 <= i < N): offset + (width * (i - 1)). - message Linear { - // Must be greater than 0. - int32 num_finite_buckets = 1; - - // Must be greater than 0. - double width = 2; - - // Lower bound of the first bucket. - double offset = 3; - } - - // Specifies an exponential sequence of buckets that have a width that is - // proportional to the value of the lower bound. Each bucket represents a - // constant relative uncertainty on a specific value in the bucket. - // - // There are `num_finite_buckets + 2` (= N) buckets. Bucket `i` has the - // following boundaries: - // - // Upper bound (0 <= i < N-1): scale * (growth_factor ^ i). - // - // Lower bound (1 <= i < N): scale * (growth_factor ^ (i - 1)). - message Exponential { - // Must be greater than 0. - int32 num_finite_buckets = 1; - - // Must be greater than 1. - double growth_factor = 2; - - // Must be greater than 0. - double scale = 3; - } - - // Specifies a set of buckets with arbitrary widths. - // - // There are `size(bounds) + 1` (= N) buckets. Bucket `i` has the following - // boundaries: - // - // Upper bound (0 <= i < N-1): bounds[i] - // Lower bound (1 <= i < N); bounds[i - 1] - // - // The `bounds` field must contain at least one element. If `bounds` has - // only one element, then there are no finite buckets, and that single - // element is the common boundary of the overflow and underflow buckets. - message Explicit { - // The values must be monotonically increasing. - repeated double bounds = 1; - } - - // Exactly one of these three fields must be set. - oneof options { - // The linear bucket. - Linear linear_buckets = 1; - - // The exponential buckets. - Exponential exponential_buckets = 2; - - // The explicit buckets. - Explicit explicit_buckets = 3; - } - } - - // Exemplars are example points that may be used to annotate aggregated - // distribution values. They are metadata that gives information about a - // particular value added to a Distribution bucket, such as a trace ID that - // was active when a value was added. They may contain further information, - // such as a example values and timestamps, origin, etc. - message Exemplar { - // Value of the exemplar point. This value determines to which bucket the - // exemplar belongs. - double value = 1; - - // The observation (sampling) time of the above value. - google.protobuf.Timestamp timestamp = 2; - - // Contextual information about the example value. Examples are: - // - // Trace: type.googleapis.com/google.monitoring.v3.SpanContext - // - // Literal string: type.googleapis.com/google.protobuf.StringValue - // - // Labels dropped during aggregation: - // type.googleapis.com/google.monitoring.v3.DroppedLabels - // - // There may be only a single attachment of any given message type in a - // single exemplar, and this is enforced by the system. - repeated google.protobuf.Any attachments = 3; - } - - // The number of values in the population. Must be non-negative. This value - // must equal the sum of the values in `bucket_counts` if a histogram is - // provided. - int64 count = 1; - - // The arithmetic mean of the values in the population. If `count` is zero - // then this field must be zero. - double mean = 2; - - // The sum of squared deviations from the mean of the values in the - // population. For values x_i this is: - // - // Sum[i=1..n]((x_i - mean)^2) - // - // Knuth, "The Art of Computer Programming", Vol. 2, page 232, 3rd edition - // describes Welford's method for accumulating this sum in one pass. - // - // If `count` is zero then this field must be zero. - double sum_of_squared_deviation = 3; - - // If specified, contains the range of the population values. The field - // must not be present if the `count` is zero. - Range range = 4; - - // Defines the histogram bucket boundaries. If the distribution does not - // contain a histogram, then omit this field. - BucketOptions bucket_options = 6; - - // The number of values in each bucket of the histogram, as described in - // `bucket_options`. If the distribution does not have a histogram, then omit - // this field. If there is a histogram, then the sum of the values in - // `bucket_counts` must equal the value in the `count` field of the - // distribution. - // - // If present, `bucket_counts` should contain N values, where N is the number - // of buckets specified in `bucket_options`. If you supply fewer than N - // values, the remaining values are assumed to be 0. - // - // The order of the values in `bucket_counts` follows the bucket numbering - // schemes described for the three bucket types. The first value must be the - // count for the underflow bucket (number 0). The next N-2 values are the - // counts for the finite buckets (number 1 through N-2). The N'th value in - // `bucket_counts` is the count for the overflow bucket (number N-1). - repeated int64 bucket_counts = 7; - - // Must be in increasing order of `value` field. - repeated Exemplar exemplars = 10; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py deleted file mode 100644 index a1aa7aad0ce..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/distribution.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/distribution.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from opentelemetry.agent._vendor.google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1dgoogle/api/distribution.proto\x12\ngoogle.api\x1a\x19google/protobuf/any.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\xd9\x06\n\x0c\x44istribution\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12\x0c\n\x04mean\x18\x02 \x01(\x01\x12 \n\x18sum_of_squared_deviation\x18\x03 \x01(\x01\x12-\n\x05range\x18\x04 \x01(\x0b\x32\x1e.google.api.Distribution.Range\x12>\n\x0e\x62ucket_options\x18\x06 \x01(\x0b\x32&.google.api.Distribution.BucketOptions\x12\x15\n\rbucket_counts\x18\x07 \x03(\x03\x12\x34\n\texemplars\x18\n \x03(\x0b\x32!.google.api.Distribution.Exemplar\x1a!\n\x05Range\x12\x0b\n\x03min\x18\x01 \x01(\x01\x12\x0b\n\x03max\x18\x02 \x01(\x01\x1a\xb5\x03\n\rBucketOptions\x12G\n\x0elinear_buckets\x18\x01 \x01(\x0b\x32-.google.api.Distribution.BucketOptions.LinearH\x00\x12Q\n\x13\x65xponential_buckets\x18\x02 \x01(\x0b\x32\x32.google.api.Distribution.BucketOptions.ExponentialH\x00\x12K\n\x10\x65xplicit_buckets\x18\x03 \x01(\x0b\x32/.google.api.Distribution.BucketOptions.ExplicitH\x00\x1a\x43\n\x06Linear\x12\x1a\n\x12num_finite_buckets\x18\x01 \x01(\x05\x12\r\n\x05width\x18\x02 \x01(\x01\x12\x0e\n\x06offset\x18\x03 \x01(\x01\x1aO\n\x0b\x45xponential\x12\x1a\n\x12num_finite_buckets\x18\x01 \x01(\x05\x12\x15\n\rgrowth_factor\x18\x02 \x01(\x01\x12\r\n\x05scale\x18\x03 \x01(\x01\x1a\x1a\n\x08\x45xplicit\x12\x0e\n\x06\x62ounds\x18\x01 \x03(\x01\x42\t\n\x07options\x1as\n\x08\x45xemplar\x12\r\n\x05value\x18\x01 \x01(\x01\x12-\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x0b\x61ttachments\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyBq\n\x0e\x63om.google.apiB\x11\x44istributionProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/distribution;distribution\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.distribution_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\021DistributionProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/distribution;distribution\242\002\004GAPI" - _globals["_DISTRIBUTION"]._serialized_start = 106 - _globals["_DISTRIBUTION"]._serialized_end = 963 - _globals["_DISTRIBUTION_RANGE"]._serialized_start = 373 - _globals["_DISTRIBUTION_RANGE"]._serialized_end = 406 - _globals["_DISTRIBUTION_BUCKETOPTIONS"]._serialized_start = 409 - _globals["_DISTRIBUTION_BUCKETOPTIONS"]._serialized_end = 846 - _globals["_DISTRIBUTION_BUCKETOPTIONS_LINEAR"]._serialized_start = 659 - _globals["_DISTRIBUTION_BUCKETOPTIONS_LINEAR"]._serialized_end = 726 - _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPONENTIAL"]._serialized_start = 728 - _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPONENTIAL"]._serialized_end = 807 - _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPLICIT"]._serialized_start = 809 - _globals["_DISTRIBUTION_BUCKETOPTIONS_EXPLICIT"]._serialized_end = 835 - _globals["_DISTRIBUTION_EXEMPLAR"]._serialized_start = 848 - _globals["_DISTRIBUTION_EXEMPLAR"]._serialized_end = 963 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi deleted file mode 100644 index 5b3ca23e142..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/distribution_pb2.pyi +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import any_pb2 as _any_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import timestamp_pb2 as _timestamp_pb2 -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Distribution(_message.Message): - __slots__ = ( - "count", - "mean", - "sum_of_squared_deviation", - "range", - "bucket_options", - "bucket_counts", - "exemplars", - ) - class Range(_message.Message): - __slots__ = ("min", "max") - MIN_FIELD_NUMBER: _ClassVar[int] - MAX_FIELD_NUMBER: _ClassVar[int] - min: float - max: float - def __init__( - self, min: _Optional[float] = ..., max: _Optional[float] = ... - ) -> None: ... - - class BucketOptions(_message.Message): - __slots__ = ("linear_buckets", "exponential_buckets", "explicit_buckets") - class Linear(_message.Message): - __slots__ = ("num_finite_buckets", "width", "offset") - NUM_FINITE_BUCKETS_FIELD_NUMBER: _ClassVar[int] - WIDTH_FIELD_NUMBER: _ClassVar[int] - OFFSET_FIELD_NUMBER: _ClassVar[int] - num_finite_buckets: int - width: float - offset: float - def __init__( - self, - num_finite_buckets: _Optional[int] = ..., - width: _Optional[float] = ..., - offset: _Optional[float] = ..., - ) -> None: ... - - class Exponential(_message.Message): - __slots__ = ("num_finite_buckets", "growth_factor", "scale") - NUM_FINITE_BUCKETS_FIELD_NUMBER: _ClassVar[int] - GROWTH_FACTOR_FIELD_NUMBER: _ClassVar[int] - SCALE_FIELD_NUMBER: _ClassVar[int] - num_finite_buckets: int - growth_factor: float - scale: float - def __init__( - self, - num_finite_buckets: _Optional[int] = ..., - growth_factor: _Optional[float] = ..., - scale: _Optional[float] = ..., - ) -> None: ... - - class Explicit(_message.Message): - __slots__ = ("bounds",) - BOUNDS_FIELD_NUMBER: _ClassVar[int] - bounds: _containers.RepeatedScalarFieldContainer[float] - def __init__(self, bounds: _Optional[_Iterable[float]] = ...) -> None: ... - - LINEAR_BUCKETS_FIELD_NUMBER: _ClassVar[int] - EXPONENTIAL_BUCKETS_FIELD_NUMBER: _ClassVar[int] - EXPLICIT_BUCKETS_FIELD_NUMBER: _ClassVar[int] - linear_buckets: Distribution.BucketOptions.Linear - exponential_buckets: Distribution.BucketOptions.Exponential - explicit_buckets: Distribution.BucketOptions.Explicit - def __init__( - self, - linear_buckets: _Optional[ - _Union[Distribution.BucketOptions.Linear, _Mapping] - ] = ..., - exponential_buckets: _Optional[ - _Union[Distribution.BucketOptions.Exponential, _Mapping] - ] = ..., - explicit_buckets: _Optional[ - _Union[Distribution.BucketOptions.Explicit, _Mapping] - ] = ..., - ) -> None: ... - - class Exemplar(_message.Message): - __slots__ = ("value", "timestamp", "attachments") - VALUE_FIELD_NUMBER: _ClassVar[int] - TIMESTAMP_FIELD_NUMBER: _ClassVar[int] - ATTACHMENTS_FIELD_NUMBER: _ClassVar[int] - value: float - timestamp: _timestamp_pb2.Timestamp - attachments: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] - def __init__( - self, - value: _Optional[float] = ..., - timestamp: _Optional[ - _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] - ] = ..., - attachments: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., - ) -> None: ... - - COUNT_FIELD_NUMBER: _ClassVar[int] - MEAN_FIELD_NUMBER: _ClassVar[int] - SUM_OF_SQUARED_DEVIATION_FIELD_NUMBER: _ClassVar[int] - RANGE_FIELD_NUMBER: _ClassVar[int] - BUCKET_OPTIONS_FIELD_NUMBER: _ClassVar[int] - BUCKET_COUNTS_FIELD_NUMBER: _ClassVar[int] - EXEMPLARS_FIELD_NUMBER: _ClassVar[int] - count: int - mean: float - sum_of_squared_deviation: float - range: Distribution.Range - bucket_options: Distribution.BucketOptions - bucket_counts: _containers.RepeatedScalarFieldContainer[int] - exemplars: _containers.RepeatedCompositeFieldContainer[Distribution.Exemplar] - def __init__( - self, - count: _Optional[int] = ..., - mean: _Optional[float] = ..., - sum_of_squared_deviation: _Optional[float] = ..., - range: _Optional[_Union[Distribution.Range, _Mapping]] = ..., - bucket_options: _Optional[_Union[Distribution.BucketOptions, _Mapping]] = ..., - bucket_counts: _Optional[_Iterable[int]] = ..., - exemplars: _Optional[_Iterable[_Union[Distribution.Exemplar, _Mapping]]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto deleted file mode 100644 index a730ab89a5f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation.proto +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "DocumentationProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// `Documentation` provides the information for describing a service. -// -// Example: -//
documentation:
-//   summary: >
-//     The Google Calendar API gives access
-//     to most calendar features.
-//   pages:
-//   - name: Overview
-//     content: (== include google/foo/overview.md ==)
-//   - name: Tutorial
-//     content: (== include google/foo/tutorial.md ==)
-//     subpages:
-//     - name: Java
-//       content: (== include google/foo/tutorial_java.md ==)
-//   rules:
-//   - selector: google.calendar.Calendar.Get
-//     description: >
-//       ...
-//   - selector: google.calendar.Calendar.Put
-//     description: >
-//       ...
-// 
-// Documentation is provided in markdown syntax. In addition to -// standard markdown features, definition lists, tables and fenced -// code blocks are supported. Section headers can be provided and are -// interpreted relative to the section nesting of the context where -// a documentation fragment is embedded. -// -// Documentation from the IDL is merged with documentation defined -// via the config at normalization time, where documentation provided -// by config rules overrides IDL provided. -// -// A number of constructs specific to the API platform are supported -// in documentation text. -// -// In order to reference a proto element, the following -// notation can be used: -//
[fully.qualified.proto.name][]
-// To override the display text used for the link, this can be used: -//
[display text][fully.qualified.proto.name]
-// Text can be excluded from doc using the following notation: -//
(-- internal comment --)
-// -// A few directives are available in documentation. Note that -// directives must appear on a single line to be properly -// identified. The `include` directive includes a markdown file from -// an external source: -//
(== include path/to/file ==)
-// The `resource_for` directive marks a message to be the resource of -// a collection in REST view. If it is not specified, tools attempt -// to infer the resource from the operations in a collection: -//
(== resource_for v1.shelves.books ==)
-// The directive `suppress_warning` does not directly affect documentation -// and is documented together with service config validation. -message Documentation { - // A short description of what the service does. The summary must be plain - // text. It becomes the overview of the service displayed in Google Cloud - // Console. - // NOTE: This field is equivalent to the standard field `description`. - string summary = 1; - - // The top level pages for the documentation set. - repeated Page pages = 5; - - // A list of documentation rules that apply to individual API elements. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated DocumentationRule rules = 3; - - // The URL to the root of documentation. - string documentation_root_url = 4; - - // Specifies the service root url if the default one (the service name - // from the yaml file) is not suitable. This can be seen in any fully - // specified service urls as well as sections that show a base that other - // urls are relative to. - string service_root_url = 6; - - // Declares a single overview page. For example: - //
documentation:
-  //   summary: ...
-  //   overview: (== include overview.md ==)
-  // 
- // This is a shortcut for the following declaration (using pages style): - //
documentation:
-  //   summary: ...
-  //   pages:
-  //   - name: Overview
-  //     content: (== include overview.md ==)
-  // 
- // Note: you cannot specify both `overview` field and `pages` field. - string overview = 2; -} - -// A documentation rule provides information about individual API elements. -message DocumentationRule { - // The selector is a comma-separated list of patterns for any element such as - // a method, a field, an enum value. Each pattern is a qualified name of the - // element which may end in "*", indicating a wildcard. Wildcards are only - // allowed at the end and for a whole component of the qualified name, - // i.e. "foo.*" is ok, but not "foo.b*" or "foo.*.bar". A wildcard will match - // one or more components. To specify a default for all applicable elements, - // the whole pattern "*" is used. - string selector = 1; - - // Description of the selected proto element (e.g. a message, a method, a - // 'service' definition, or a field). Defaults to leading & trailing comments - // taken from the proto source definition of the proto element. - string description = 2; - - // Deprecation description of the selected element(s). It can be provided if - // an element is marked as `deprecated`. - string deprecation_description = 3; -} - -// Represents a documentation page. A page can contain subpages to represent -// nested documentation set structure. -message Page { - // The name of the page. It will be used as an identity of the page to - // generate URI of the page, text of the link to this page in navigation, - // etc. The full page name (start from the root page name to this page - // concatenated with `.`) can be used as reference to the page in your - // documentation. For example: - //
pages:
-  // - name: Tutorial
-  //   content: (== include tutorial.md ==)
-  //   subpages:
-  //   - name: Java
-  //     content: (== include tutorial_java.md ==)
-  // 
- // You can reference `Java` page using Markdown reference link syntax: - // `[Java][Tutorial.Java]`. - string name = 1; - - // The Markdown content of the page. You can use ```(== include {path} - // ==)``` to include content from a Markdown file. The content can be used - // to produce the documentation page such as HTML format page. - string content = 2; - - // Subpages of this page. The order of subpages specified here will be - // honored in the generated docset. - repeated Page subpages = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py deleted file mode 100644 index 29ce1122a95..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/documentation.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/documentation.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1egoogle/api/documentation.proto\x12\ngoogle.api"\xbb\x01\n\rDocumentation\x12\x0f\n\x07summary\x18\x01 \x01(\t\x12\x1f\n\x05pages\x18\x05 \x03(\x0b\x32\x10.google.api.Page\x12,\n\x05rules\x18\x03 \x03(\x0b\x32\x1d.google.api.DocumentationRule\x12\x1e\n\x16\x64ocumentation_root_url\x18\x04 \x01(\t\x12\x18\n\x10service_root_url\x18\x06 \x01(\t\x12\x10\n\x08overview\x18\x02 \x01(\t"[\n\x11\x44ocumentationRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x1f\n\x17\x64\x65precation_description\x18\x03 \x01(\t"I\n\x04Page\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\t\x12"\n\x08subpages\x18\x03 \x03(\x0b\x32\x10.google.api.PageBt\n\x0e\x63om.google.apiB\x12\x44ocumentationProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.documentation_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\022DocumentationProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_DOCUMENTATION"]._serialized_start = 47 - _globals["_DOCUMENTATION"]._serialized_end = 234 - _globals["_DOCUMENTATIONRULE"]._serialized_start = 236 - _globals["_DOCUMENTATIONRULE"]._serialized_end = 327 - _globals["_PAGE"]._serialized_start = 329 - _globals["_PAGE"]._serialized_end = 402 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi deleted file mode 100644 index f5e066d5c0b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/documentation_pb2.pyi +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Documentation(_message.Message): - __slots__ = ( - "summary", - "pages", - "rules", - "documentation_root_url", - "service_root_url", - "overview", - ) - SUMMARY_FIELD_NUMBER: _ClassVar[int] - PAGES_FIELD_NUMBER: _ClassVar[int] - RULES_FIELD_NUMBER: _ClassVar[int] - DOCUMENTATION_ROOT_URL_FIELD_NUMBER: _ClassVar[int] - SERVICE_ROOT_URL_FIELD_NUMBER: _ClassVar[int] - OVERVIEW_FIELD_NUMBER: _ClassVar[int] - summary: str - pages: _containers.RepeatedCompositeFieldContainer[Page] - rules: _containers.RepeatedCompositeFieldContainer[DocumentationRule] - documentation_root_url: str - service_root_url: str - overview: str - def __init__( - self, - summary: _Optional[str] = ..., - pages: _Optional[_Iterable[_Union[Page, _Mapping]]] = ..., - rules: _Optional[_Iterable[_Union[DocumentationRule, _Mapping]]] = ..., - documentation_root_url: _Optional[str] = ..., - service_root_url: _Optional[str] = ..., - overview: _Optional[str] = ..., - ) -> None: ... - -class DocumentationRule(_message.Message): - __slots__ = ("selector", "description", "deprecation_description") - SELECTOR_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - DEPRECATION_DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - selector: str - description: str - deprecation_description: str - def __init__( - self, - selector: _Optional[str] = ..., - description: _Optional[str] = ..., - deprecation_description: _Optional[str] = ..., - ) -> None: ... - -class Page(_message.Message): - __slots__ = ("name", "content", "subpages") - NAME_FIELD_NUMBER: _ClassVar[int] - CONTENT_FIELD_NUMBER: _ClassVar[int] - SUBPAGES_FIELD_NUMBER: _ClassVar[int] - name: str - content: str - subpages: _containers.RepeatedCompositeFieldContainer[Page] - def __init__( - self, - name: _Optional[str] = ..., - content: _Optional[str] = ..., - subpages: _Optional[_Iterable[_Union[Page, _Mapping]]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto deleted file mode 100644 index 047cf54d515..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint.proto +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "EndpointProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// `Endpoint` describes a network address of a service that serves a set of -// APIs. It is commonly known as a service endpoint. A service may expose -// any number of service endpoints, and all service endpoints share the same -// service definition, such as quota limits and monitoring metrics. -// -// Example: -// -// type: google.api.Service -// name: library-example.googleapis.com -// endpoints: -// # Declares network address `https://library-example.googleapis.com` -// # for service `library-example.googleapis.com`. The `https` scheme -// # is implicit for all service endpoints. Other schemes may be -// # supported in the future. -// - name: library-example.googleapis.com -// allow_cors: false -// - name: content-staging-library-example.googleapis.com -// # Allows HTTP OPTIONS calls to be passed to the API frontend, for it -// # to decide whether the subsequent cross-origin request is allowed -// # to proceed. -// allow_cors: true -message Endpoint { - // The canonical name of this endpoint. - string name = 1; - - // Aliases for this endpoint, these will be served by the same UrlMap as the - // parent endpoint, and will be provisioned in the GCP stack for the Regional - // Endpoints. - repeated string aliases = 2; - - // The specification of an Internet routable address of API frontend that will - // handle requests to this [API - // Endpoint](https://cloud.google.com/apis/design/glossary). It should be - // either a valid IPv4 address or a fully-qualified domain name. For example, - // "8.8.8.8" or "myservice.appspot.com". - string target = 101; - - // Allowing - // [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka - // cross-domain traffic, would allow the backends served from this endpoint to - // receive and respond to HTTP OPTIONS requests. The response will be used by - // the browser to determine whether the subsequent cross-origin request is - // allowed to proceed. - bool allow_cors = 5; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py deleted file mode 100644 index 7785d9750af..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/endpoint.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/endpoint.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x19google/api/endpoint.proto\x12\ngoogle.api"M\n\x08\x45ndpoint\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x61liases\x18\x02 \x03(\t\x12\x0e\n\x06target\x18\x65 \x01(\t\x12\x12\n\nallow_cors\x18\x05 \x01(\x08\x42o\n\x0e\x63om.google.apiB\rEndpointProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.endpoint_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\rEndpointProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_ENDPOINT"]._serialized_start = 41 - _globals["_ENDPOINT"]._serialized_end = 118 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi deleted file mode 100644 index 8141e33c1f9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/endpoint_pb2.pyi +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Endpoint(_message.Message): - __slots__ = ("name", "aliases", "target", "allow_cors") - NAME_FIELD_NUMBER: _ClassVar[int] - ALIASES_FIELD_NUMBER: _ClassVar[int] - TARGET_FIELD_NUMBER: _ClassVar[int] - ALLOW_CORS_FIELD_NUMBER: _ClassVar[int] - name: str - aliases: _containers.RepeatedScalarFieldContainer[str] - target: str - allow_cors: bool - def __init__( - self, - name: _Optional[str] = ..., - aliases: _Optional[_Iterable[str]] = ..., - target: _Optional[str] = ..., - allow_cors: _Optional[bool] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto deleted file mode 100644 index 3b4826e5f74..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason.proto +++ /dev/null @@ -1,807 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/error_reason;error_reason"; -option java_multiple_files = true; -option java_outer_classname = "ErrorReasonProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Defines the supported values for `google.rpc.ErrorInfo.reason` for the -// `googleapis.com` error domain. This error domain is reserved for [Service -// Infrastructure](https://cloud.google.com/service-infrastructure/docs/overview). -// For each error info of this domain, the metadata key "service" refers to the -// logical identifier of an API service, such as "pubsub.googleapis.com". The -// "consumer" refers to the entity that consumes an API Service. It typically is -// a Google project that owns the client application or the server resource, -// such as "projects/123". Other metadata keys are specific to each error -// reason. For more information, see the definition of the specific error -// reason. -enum ErrorReason { - // Do not use this default value. - ERROR_REASON_UNSPECIFIED = 0; - - // The request is calling a disabled service for a consumer. - // - // Example of an ErrorInfo when the consumer "projects/123" contacting - // "pubsub.googleapis.com" service which is disabled: - // - // { "reason": "SERVICE_DISABLED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "pubsub.googleapis.com" - // } - // } - // - // This response indicates the "pubsub.googleapis.com" has been disabled in - // "projects/123". - SERVICE_DISABLED = 1; - - // The request whose associated billing account is disabled. - // - // Example of an ErrorInfo when the consumer "projects/123" fails to contact - // "pubsub.googleapis.com" service because the associated billing account is - // disabled: - // - // { "reason": "BILLING_DISABLED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "pubsub.googleapis.com" - // } - // } - // - // This response indicates the billing account associated has been disabled. - BILLING_DISABLED = 2; - - // The request is denied because the provided [API - // key](https://cloud.google.com/docs/authentication/api-keys) is invalid. It - // may be in a bad format, cannot be found, or has been expired). - // - // Example of an ErrorInfo when the request is contacting - // "storage.googleapis.com" service with an invalid API key: - // - // { "reason": "API_KEY_INVALID", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // } - // } - API_KEY_INVALID = 3; - - // The request is denied because it violates [API key API - // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_api_restrictions). - // - // Example of an ErrorInfo when the consumer "projects/123" fails to call the - // "storage.googleapis.com" service because this service is restricted in the - // API key: - // - // { "reason": "API_KEY_SERVICE_BLOCKED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com" - // } - // } - API_KEY_SERVICE_BLOCKED = 4; - - // The request is denied because it violates [API key HTTP - // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_http_restrictions). - // - // Example of an ErrorInfo when the consumer "projects/123" fails to call - // "storage.googleapis.com" service because the http referrer of the request - // violates API key HTTP restrictions: - // - // { "reason": "API_KEY_HTTP_REFERRER_BLOCKED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com", - // } - // } - API_KEY_HTTP_REFERRER_BLOCKED = 7; - - // The request is denied because it violates [API key IP address - // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). - // - // Example of an ErrorInfo when the consumer "projects/123" fails to call - // "storage.googleapis.com" service because the caller IP of the request - // violates API key IP address restrictions: - // - // { "reason": "API_KEY_IP_ADDRESS_BLOCKED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com", - // } - // } - API_KEY_IP_ADDRESS_BLOCKED = 8; - - // The request is denied because it violates [API key Android application - // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). - // - // Example of an ErrorInfo when the consumer "projects/123" fails to call - // "storage.googleapis.com" service because the request from the Android apps - // violates the API key Android application restrictions: - // - // { "reason": "API_KEY_ANDROID_APP_BLOCKED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com" - // } - // } - API_KEY_ANDROID_APP_BLOCKED = 9; - - // The request is denied because it violates [API key iOS application - // restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). - // - // Example of an ErrorInfo when the consumer "projects/123" fails to call - // "storage.googleapis.com" service because the request from the iOS apps - // violates the API key iOS application restrictions: - // - // { "reason": "API_KEY_IOS_APP_BLOCKED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com" - // } - // } - API_KEY_IOS_APP_BLOCKED = 13; - - // The request is denied because there is not enough rate quota for the - // consumer. - // - // Example of an ErrorInfo when the consumer "projects/123" fails to contact - // "pubsub.googleapis.com" service because consumer's rate quota usage has - // reached the maximum value set for the quota limit - // "ReadsPerMinutePerProject" on the quota metric - // "pubsub.googleapis.com/read_requests": - // - // { "reason": "RATE_LIMIT_EXCEEDED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "pubsub.googleapis.com", - // "quota_metric": "pubsub.googleapis.com/read_requests", - // "quota_limit": "ReadsPerMinutePerProject" - // } - // } - // - // Example of an ErrorInfo when the consumer "projects/123" checks quota on - // the service "dataflow.googleapis.com" and hits the organization quota - // limit "DefaultRequestsPerMinutePerOrganization" on the metric - // "dataflow.googleapis.com/default_requests". - // - // { "reason": "RATE_LIMIT_EXCEEDED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "dataflow.googleapis.com", - // "quota_metric": "dataflow.googleapis.com/default_requests", - // "quota_limit": "DefaultRequestsPerMinutePerOrganization" - // } - // } - RATE_LIMIT_EXCEEDED = 5; - - // The request is denied because there is not enough resource quota for the - // consumer. - // - // Example of an ErrorInfo when the consumer "projects/123" fails to contact - // "compute.googleapis.com" service because consumer's resource quota usage - // has reached the maximum value set for the quota limit "VMsPerProject" - // on the quota metric "compute.googleapis.com/vms": - // - // { "reason": "RESOURCE_QUOTA_EXCEEDED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "compute.googleapis.com", - // "quota_metric": "compute.googleapis.com/vms", - // "quota_limit": "VMsPerProject" - // } - // } - // - // Example of an ErrorInfo when the consumer "projects/123" checks resource - // quota on the service "dataflow.googleapis.com" and hits the organization - // quota limit "jobs-per-organization" on the metric - // "dataflow.googleapis.com/job_count". - // - // { "reason": "RESOURCE_QUOTA_EXCEEDED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "dataflow.googleapis.com", - // "quota_metric": "dataflow.googleapis.com/job_count", - // "quota_limit": "jobs-per-organization" - // } - // } - RESOURCE_QUOTA_EXCEEDED = 6; - - // The request whose associated billing account address is in a tax restricted - // location, violates the local tax restrictions when creating resources in - // the restricted region. - // - // Example of an ErrorInfo when creating the Cloud Storage Bucket in the - // container "projects/123" under a tax restricted region - // "locations/asia-northeast3": - // - // { "reason": "LOCATION_TAX_POLICY_VIOLATED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com", - // "location": "locations/asia-northeast3" - // } - // } - // - // This response indicates creating the Cloud Storage Bucket in - // "locations/asia-northeast3" violates the location tax restriction. - LOCATION_TAX_POLICY_VIOLATED = 10; - - // The request is denied because the caller does not have required permission - // on the user project "projects/123" or the user project is invalid. For more - // information, check the [userProject System - // Parameters](https://cloud.google.com/apis/docs/system-parameters). - // - // Example of an ErrorInfo when the caller is calling Cloud Storage service - // with insufficient permissions on the user project: - // - // { "reason": "USER_PROJECT_DENIED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com" - // } - // } - USER_PROJECT_DENIED = 11; - - // The request is denied because the consumer "projects/123" is suspended due - // to Terms of Service(Tos) violations. Check [Project suspension - // guidelines](https://cloud.google.com/resource-manager/docs/project-suspension-guidelines) - // for more information. - // - // Example of an ErrorInfo when calling Cloud Storage service with the - // suspended consumer "projects/123": - // - // { "reason": "CONSUMER_SUSPENDED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com" - // } - // } - CONSUMER_SUSPENDED = 12; - - // The request is denied because the associated consumer is invalid. It may be - // in a bad format, cannot be found, or have been deleted. - // - // Example of an ErrorInfo when calling Cloud Storage service with the - // invalid consumer "projects/123": - // - // { "reason": "CONSUMER_INVALID", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com" - // } - // } - CONSUMER_INVALID = 14; - - // The request is denied because it violates [VPC Service - // Controls](https://cloud.google.com/vpc-service-controls/docs/overview). - // The 'uid' field is a random generated identifier that customer can use it - // to search the audit log for a request rejected by VPC Service Controls. For - // more information, please refer [VPC Service Controls - // Troubleshooting](https://cloud.google.com/vpc-service-controls/docs/troubleshooting#unique-id) - // - // Example of an ErrorInfo when the consumer "projects/123" fails to call - // Cloud Storage service because the request is prohibited by the VPC Service - // Controls. - // - // { "reason": "SECURITY_POLICY_VIOLATED", - // "domain": "googleapis.com", - // "metadata": { - // "uid": "123456789abcde", - // "consumer": "projects/123", - // "service": "storage.googleapis.com" - // } - // } - SECURITY_POLICY_VIOLATED = 15; - - // The request is denied because the provided access token has expired. - // - // Example of an ErrorInfo when the request is calling Cloud Storage service - // with an expired access token: - // - // { "reason": "ACCESS_TOKEN_EXPIRED", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // "method": "google.storage.v1.Storage.GetObject" - // } - // } - ACCESS_TOKEN_EXPIRED = 16; - - // The request is denied because the provided access token doesn't have at - // least one of the acceptable scopes required for the API. Please check - // [OAuth 2.0 Scopes for Google - // APIs](https://developers.google.com/identity/protocols/oauth2/scopes) for - // the list of the OAuth 2.0 scopes that you might need to request to access - // the API. - // - // Example of an ErrorInfo when the request is calling Cloud Storage service - // with an access token that is missing required scopes: - // - // { "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // "method": "google.storage.v1.Storage.GetObject" - // } - // } - ACCESS_TOKEN_SCOPE_INSUFFICIENT = 17; - - // The request is denied because the account associated with the provided - // access token is in an invalid state, such as disabled or deleted. - // For more information, see https://cloud.google.com/docs/authentication. - // - // Warning: For privacy reasons, the server may not be able to disclose the - // email address for some accounts. The client MUST NOT depend on the - // availability of the `email` attribute. - // - // Example of an ErrorInfo when the request is to the Cloud Storage API with - // an access token that is associated with a disabled or deleted [service - // account](http://cloud/iam/docs/service-accounts): - // - // { "reason": "ACCOUNT_STATE_INVALID", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // "method": "google.storage.v1.Storage.GetObject", - // "email": "user@123.iam.gserviceaccount.com" - // } - // } - ACCOUNT_STATE_INVALID = 18; - - // The request is denied because the type of the provided access token is not - // supported by the API being called. - // - // Example of an ErrorInfo when the request is to the Cloud Storage API with - // an unsupported token type. - // - // { "reason": "ACCESS_TOKEN_TYPE_UNSUPPORTED", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // "method": "google.storage.v1.Storage.GetObject" - // } - // } - ACCESS_TOKEN_TYPE_UNSUPPORTED = 19; - - // The request is denied because the request doesn't have any authentication - // credentials. For more information regarding the supported authentication - // strategies for Google Cloud APIs, see - // https://cloud.google.com/docs/authentication. - // - // Example of an ErrorInfo when the request is to the Cloud Storage API - // without any authentication credentials. - // - // { "reason": "CREDENTIALS_MISSING", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // "method": "google.storage.v1.Storage.GetObject" - // } - // } - CREDENTIALS_MISSING = 20; - - // The request is denied because the provided project owning the resource - // which acts as the [API - // consumer](https://cloud.google.com/apis/design/glossary#api_consumer) is - // invalid. It may be in a bad format or empty. - // - // Example of an ErrorInfo when the request is to the Cloud Functions API, - // but the offered resource project in the request in a bad format which can't - // perform the ListFunctions method. - // - // { "reason": "RESOURCE_PROJECT_INVALID", - // "domain": "googleapis.com", - // "metadata": { - // "service": "cloudfunctions.googleapis.com", - // "method": - // "google.cloud.functions.v1.CloudFunctionsService.ListFunctions" - // } - // } - RESOURCE_PROJECT_INVALID = 21; - - // The request is denied because the provided session cookie is missing, - // invalid or failed to decode. - // - // Example of an ErrorInfo when the request is calling Cloud Storage service - // with a SID cookie which can't be decoded. - // - // { "reason": "SESSION_COOKIE_INVALID", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // "method": "google.storage.v1.Storage.GetObject", - // "cookie": "SID" - // } - // } - SESSION_COOKIE_INVALID = 23; - - // The request is denied because the user is from a Google Workspace customer - // that blocks their users from accessing a particular service. - // - // Example scenario: https://support.google.com/a/answer/9197205?hl=en - // - // Example of an ErrorInfo when access to Google Cloud Storage service is - // blocked by the Google Workspace administrator: - // - // { "reason": "USER_BLOCKED_BY_ADMIN", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com", - // "method": "google.storage.v1.Storage.GetObject", - // } - // } - USER_BLOCKED_BY_ADMIN = 24; - - // The request is denied because the resource service usage is restricted - // by administrators according to the organization policy constraint. - // For more information see - // https://cloud.google.com/resource-manager/docs/organization-policy/restricting-services. - // - // Example of an ErrorInfo when access to Google Cloud Storage service is - // restricted by Resource Usage Restriction policy: - // - // { "reason": "RESOURCE_USAGE_RESTRICTION_VIOLATED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/project-123", - // "service": "storage.googleapis.com" - // } - // } - RESOURCE_USAGE_RESTRICTION_VIOLATED = 25; - - // Unimplemented. Do not use. - // - // The request is denied because it contains unsupported system parameters in - // URL query parameters or HTTP headers. For more information, - // see https://cloud.google.com/apis/docs/system-parameters - // - // Example of an ErrorInfo when access "pubsub.googleapis.com" service with - // a request header of "x-goog-user-ip": - // - // { "reason": "SYSTEM_PARAMETER_UNSUPPORTED", - // "domain": "googleapis.com", - // "metadata": { - // "service": "pubsub.googleapis.com" - // "parameter": "x-goog-user-ip" - // } - // } - SYSTEM_PARAMETER_UNSUPPORTED = 26; - - // The request is denied because it violates Org Restriction: the requested - // resource does not belong to allowed organizations specified in - // "X-Goog-Allowed-Resources" header. - // - // Example of an ErrorInfo when accessing a GCP resource that is restricted by - // Org Restriction for "pubsub.googleapis.com" service. - // - // { - // reason: "ORG_RESTRICTION_VIOLATION" - // domain: "googleapis.com" - // metadata { - // "consumer":"projects/123456" - // "service": "pubsub.googleapis.com" - // } - // } - ORG_RESTRICTION_VIOLATION = 27; - - // The request is denied because "X-Goog-Allowed-Resources" header is in a bad - // format. - // - // Example of an ErrorInfo when - // accessing "pubsub.googleapis.com" service with an invalid - // "X-Goog-Allowed-Resources" request header. - // - // { - // reason: "ORG_RESTRICTION_HEADER_INVALID" - // domain: "googleapis.com" - // metadata { - // "consumer":"projects/123456" - // "service": "pubsub.googleapis.com" - // } - // } - ORG_RESTRICTION_HEADER_INVALID = 28; - - // Unimplemented. Do not use. - // - // The request is calling a service that is not visible to the consumer. - // - // Example of an ErrorInfo when the consumer "projects/123" contacting - // "pubsub.googleapis.com" service which is not visible to the consumer. - // - // { "reason": "SERVICE_NOT_VISIBLE", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "pubsub.googleapis.com" - // } - // } - // - // This response indicates the "pubsub.googleapis.com" is not visible to - // "projects/123" (or it may not exist). - SERVICE_NOT_VISIBLE = 29; - - // The request is related to a project for which GCP access is suspended. - // - // Example of an ErrorInfo when the consumer "projects/123" fails to contact - // "pubsub.googleapis.com" service because GCP access is suspended: - // - // { "reason": "GCP_SUSPENDED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "pubsub.googleapis.com" - // } - // } - // - // This response indicates the associated GCP account has been suspended. - GCP_SUSPENDED = 30; - - // The request violates the location policies when creating resources in - // the restricted region. - // - // Example of an ErrorInfo when creating the Cloud Storage Bucket by - // "projects/123" for service storage.googleapis.com: - // - // { "reason": "LOCATION_POLICY_VIOLATED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "storage.googleapis.com", - // } - // } - // - // This response indicates creating the Cloud Storage Bucket in - // "locations/asia-northeast3" violates at least one location policy. - // The troubleshooting guidance is provided in the Help links. - LOCATION_POLICY_VIOLATED = 31; - - // The request is denied because origin request header is missing. - // - // Example of an ErrorInfo when - // accessing "pubsub.googleapis.com" service with an empty "Origin" request - // header. - // - // { - // reason: "MISSING_ORIGIN" - // domain: "googleapis.com" - // metadata { - // "consumer":"projects/123456" - // "service": "pubsub.googleapis.com" - // } - // } - MISSING_ORIGIN = 33; - - // The request is denied because the request contains more than one credential - // type that are individually acceptable, but not together. The customer - // should retry their request with only one set of credentials. - // - // Example of an ErrorInfo when - // accessing "pubsub.googleapis.com" service with overloaded credentials. - // - // { - // reason: "OVERLOADED_CREDENTIALS" - // domain: "googleapis.com" - // metadata { - // "consumer":"projects/123456" - // "service": "pubsub.googleapis.com" - // } - // } - OVERLOADED_CREDENTIALS = 34; - - // The request whose associated location violates the location org policy - // restrictions when creating resources in the restricted region. - // - // Example of an ErrorInfo when creating the Cloud Storage Bucket in the - // container "projects/123" under a restricted region - // "locations/asia-northeast3": - // - // { - // "reason": "LOCATION_ORG_POLICY_VIOLATED", - // "domain": "googleapis.com", - // "metadata": { - // "resource": "projects/123", - // "location": "locations/asia-northeast3" - // } - // } - // - // This response indicates creating the Cloud Storage Bucket in - // "locations/asia-northeast3" violates the location org policy restriction. - LOCATION_ORG_POLICY_VIOLATED = 35; - - // The request is denied because it access data of regulated customers using - // TLS 1.0 and 1.1. - // - // Example of an ErrorInfo when accessing a GCP resource "projects/123" that - // is restricted by TLS Version Restriction for "pubsub.googleapis.com" - // service. - // - // { - // "reason": "TLS_ORG_POLICY_VIOLATED", - // "domain": "googleapis.com", - // "metadata": { - // "service": "pubsub.googleapis.com" - // "resource": "projects/123", - // "policyName": "constraints/gcp.restrictTLSVersion", - // "tlsVersion": "TLS_VERSION_1" - // } - // } - TLS_ORG_POLICY_VIOLATED = 36; - - // The request is denied because the associated project has exceeded the - // emulator quota limit. - // - // Example of an ErrorInfo when the associated "projects/123" has exceeded the - // emulator quota limit. - // - // { - // "reason": "EMULATOR_QUOTA_EXCEEDED", - // "domain": "googleapis.com", - // "metadata": { - // "service": "pubsub.googleapis.com" - // "consumer": "projects/123" - // } - // } - EMULATOR_QUOTA_EXCEEDED = 38; - - // The request is denied because the associated application credential header - // is invalid for an Android applications. - // - // Example of an ErrorInfo when the request from an Android application to the - // "pubsub.googleapis.com" with an invalid application credential header. - // - // { - // "reason": "CREDENTIAL_ANDROID_APP_INVALID", - // "domain": "googleapis.com", - // "metadata": { - // "service": "pubsub.googleapis.com" - // } - // } - CREDENTIAL_ANDROID_APP_INVALID = 39; - - // The request is denied because IAM permission on resource is denied. - // - // Example of an ErrorInfo when the IAM permission `aiplatform.datasets.list` - // is denied on resource `projects/123`. - // - // { - // "reason": "IAM_PERMISSION_DENIED", - // "domain": "googleapis.com", - // "metadata": { - // "resource": "projects/123" - // "permission": "aiplatform.datasets.list" - // } - // } - IAM_PERMISSION_DENIED = 41; - - // The request is denied because it contains the invalid JWT token. - // - // Example of an ErrorInfo when the request contains an invalid JWT token for - // service `storage.googleapis.com`. - // - // { - // "reason": "JWT_TOKEN_INVALID", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com" - // } - // } - JWT_TOKEN_INVALID = 42; - - // The request is denied because it contains credential with type that is - // unsupported. - // - // Example of an ErrorInfo when the request contains an unsupported credential - // type for service `storage.googleapis.com`. - // - // { - // "reason": "CREDENTIAL_TYPE_UNSUPPORTED", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com" - // } - // } - CREDENTIAL_TYPE_UNSUPPORTED = 43; - - // The request is denied because it contains unsupported account type. - // - // Example of an ErrorInfo when the request contains an unsupported account - // type for service `storage.googleapis.com`. - // - // { - // "reason": "ACCOUNT_TYPE_UNSUPPORTED", - // "domain": "googleapis.com", - // "metadata": { - // "service": "storage.googleapis.com" - // } - // } - ACCOUNT_TYPE_UNSUPPORTED = 44; - - // The request is denied because the API endpoint is restricted by - // administrators according to the organization policy constraint. - // For more information see - // https://cloud.google.com/assured-workloads/docs/restrict-endpoint-usage. - // - // Example of an ErrorInfo when access to Google Cloud Storage service is - // restricted by Restrict Endpoint Usage policy: - // - // { - // "reason": "ENDPOINT_USAGE_RESTRICTION_VIOLATED", - // "domain": "googleapis.com/policies/endpointUsageRestriction", - // "metadata": { - // "policy_name": "constraints/gcp.restrictEndpointUsage", - // "checked_value": "storage.googleapis.com" - // "consumer": "organization/123" - // "service": "storage.googleapis.com" - // } - // } - ENDPOINT_USAGE_RESTRICTION_VIOLATED = 45; - - // The request is denied because the TLS Cipher Suite is restricted by - // administrators according to the organization policy constraint. - // For more information see - // https://cloud.google.com/assured-workloads/docs/restrict-tls-cipher-suites - // - // Example of an ErrorInfo when access to Google Cloud BigQuery service is - // restricted by Restrict TLS Cipher Suites policy: - // - // { - // "reason": "TLS_CIPHER_RESTRICTION_VIOLATED", - // "domain": "googleapis.com/policies/tlsCipherRestriction", - // "metadata": { - // "policy_name": "constraints/gcp.restrictTLSCipherSuites", - // "checked_value": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - // "consumer": "organization/123" - // "service": "bigquery.googleapis.com" - // } - // } - TLS_CIPHER_RESTRICTION_VIOLATED = 46; - - // The request is denied because the MCP activation check fails. - // - // Example of an ErrorInfo when the container "projects/123" contacting - // "pubsub.googleapis.com" service which is disabled by MCP: - // - // { "reason": "MCP_SERVER_DISABLED", - // "domain": "googleapis.com", - // "metadata": { - // "consumer": "projects/123", - // "service": "pubsub.googleapis.com" - // } - // } - // - // This response indicates the "pubsub.googleapis.com" has been disabled in - // "projects/123" for MCP. - MCP_SERVER_DISABLED = 47; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py deleted file mode 100644 index 59874ac81e7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/error_reason.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/error_reason.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n\x1dgoogle/api/error_reason.proto\x12\ngoogle.api*\x92\n\n\x0b\x45rrorReason\x12\x1c\n\x18\x45RROR_REASON_UNSPECIFIED\x10\x00\x12\x14\n\x10SERVICE_DISABLED\x10\x01\x12\x14\n\x10\x42ILLING_DISABLED\x10\x02\x12\x13\n\x0f\x41PI_KEY_INVALID\x10\x03\x12\x1b\n\x17\x41PI_KEY_SERVICE_BLOCKED\x10\x04\x12!\n\x1d\x41PI_KEY_HTTP_REFERRER_BLOCKED\x10\x07\x12\x1e\n\x1a\x41PI_KEY_IP_ADDRESS_BLOCKED\x10\x08\x12\x1f\n\x1b\x41PI_KEY_ANDROID_APP_BLOCKED\x10\t\x12\x1b\n\x17\x41PI_KEY_IOS_APP_BLOCKED\x10\r\x12\x17\n\x13RATE_LIMIT_EXCEEDED\x10\x05\x12\x1b\n\x17RESOURCE_QUOTA_EXCEEDED\x10\x06\x12 \n\x1cLOCATION_TAX_POLICY_VIOLATED\x10\n\x12\x17\n\x13USER_PROJECT_DENIED\x10\x0b\x12\x16\n\x12\x43ONSUMER_SUSPENDED\x10\x0c\x12\x14\n\x10\x43ONSUMER_INVALID\x10\x0e\x12\x1c\n\x18SECURITY_POLICY_VIOLATED\x10\x0f\x12\x18\n\x14\x41\x43\x43\x45SS_TOKEN_EXPIRED\x10\x10\x12#\n\x1f\x41\x43\x43\x45SS_TOKEN_SCOPE_INSUFFICIENT\x10\x11\x12\x19\n\x15\x41\x43\x43OUNT_STATE_INVALID\x10\x12\x12!\n\x1d\x41\x43\x43\x45SS_TOKEN_TYPE_UNSUPPORTED\x10\x13\x12\x17\n\x13\x43REDENTIALS_MISSING\x10\x14\x12\x1c\n\x18RESOURCE_PROJECT_INVALID\x10\x15\x12\x1a\n\x16SESSION_COOKIE_INVALID\x10\x17\x12\x19\n\x15USER_BLOCKED_BY_ADMIN\x10\x18\x12'\n#RESOURCE_USAGE_RESTRICTION_VIOLATED\x10\x19\x12 \n\x1cSYSTEM_PARAMETER_UNSUPPORTED\x10\x1a\x12\x1d\n\x19ORG_RESTRICTION_VIOLATION\x10\x1b\x12\"\n\x1eORG_RESTRICTION_HEADER_INVALID\x10\x1c\x12\x17\n\x13SERVICE_NOT_VISIBLE\x10\x1d\x12\x11\n\rGCP_SUSPENDED\x10\x1e\x12\x1c\n\x18LOCATION_POLICY_VIOLATED\x10\x1f\x12\x12\n\x0eMISSING_ORIGIN\x10!\x12\x1a\n\x16OVERLOADED_CREDENTIALS\x10\"\x12 \n\x1cLOCATION_ORG_POLICY_VIOLATED\x10#\x12\x1b\n\x17TLS_ORG_POLICY_VIOLATED\x10$\x12\x1b\n\x17\x45MULATOR_QUOTA_EXCEEDED\x10&\x12\"\n\x1e\x43REDENTIAL_ANDROID_APP_INVALID\x10'\x12\x19\n\x15IAM_PERMISSION_DENIED\x10)\x12\x15\n\x11JWT_TOKEN_INVALID\x10*\x12\x1f\n\x1b\x43REDENTIAL_TYPE_UNSUPPORTED\x10+\x12\x1c\n\x18\x41\x43\x43OUNT_TYPE_UNSUPPORTED\x10,\x12'\n#ENDPOINT_USAGE_RESTRICTION_VIOLATED\x10-\x12#\n\x1fTLS_CIPHER_RESTRICTION_VIOLATED\x10.\x12\x17\n\x13MCP_SERVER_DISABLED\x10/Bp\n\x0e\x63om.google.apiB\x10\x45rrorReasonProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/error_reason;error_reason\xa2\x02\x04GAPIb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.error_reason_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\020ErrorReasonProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/error_reason;error_reason\242\002\004GAPI" - _globals["_ERRORREASON"]._serialized_start = 46 - _globals["_ERRORREASON"]._serialized_end = 1344 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi deleted file mode 100644 index 9450370e6a9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/error_reason_pb2.pyi +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class ErrorReason(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - ERROR_REASON_UNSPECIFIED: _ClassVar[ErrorReason] - SERVICE_DISABLED: _ClassVar[ErrorReason] - BILLING_DISABLED: _ClassVar[ErrorReason] - API_KEY_INVALID: _ClassVar[ErrorReason] - API_KEY_SERVICE_BLOCKED: _ClassVar[ErrorReason] - API_KEY_HTTP_REFERRER_BLOCKED: _ClassVar[ErrorReason] - API_KEY_IP_ADDRESS_BLOCKED: _ClassVar[ErrorReason] - API_KEY_ANDROID_APP_BLOCKED: _ClassVar[ErrorReason] - API_KEY_IOS_APP_BLOCKED: _ClassVar[ErrorReason] - RATE_LIMIT_EXCEEDED: _ClassVar[ErrorReason] - RESOURCE_QUOTA_EXCEEDED: _ClassVar[ErrorReason] - LOCATION_TAX_POLICY_VIOLATED: _ClassVar[ErrorReason] - USER_PROJECT_DENIED: _ClassVar[ErrorReason] - CONSUMER_SUSPENDED: _ClassVar[ErrorReason] - CONSUMER_INVALID: _ClassVar[ErrorReason] - SECURITY_POLICY_VIOLATED: _ClassVar[ErrorReason] - ACCESS_TOKEN_EXPIRED: _ClassVar[ErrorReason] - ACCESS_TOKEN_SCOPE_INSUFFICIENT: _ClassVar[ErrorReason] - ACCOUNT_STATE_INVALID: _ClassVar[ErrorReason] - ACCESS_TOKEN_TYPE_UNSUPPORTED: _ClassVar[ErrorReason] - CREDENTIALS_MISSING: _ClassVar[ErrorReason] - RESOURCE_PROJECT_INVALID: _ClassVar[ErrorReason] - SESSION_COOKIE_INVALID: _ClassVar[ErrorReason] - USER_BLOCKED_BY_ADMIN: _ClassVar[ErrorReason] - RESOURCE_USAGE_RESTRICTION_VIOLATED: _ClassVar[ErrorReason] - SYSTEM_PARAMETER_UNSUPPORTED: _ClassVar[ErrorReason] - ORG_RESTRICTION_VIOLATION: _ClassVar[ErrorReason] - ORG_RESTRICTION_HEADER_INVALID: _ClassVar[ErrorReason] - SERVICE_NOT_VISIBLE: _ClassVar[ErrorReason] - GCP_SUSPENDED: _ClassVar[ErrorReason] - LOCATION_POLICY_VIOLATED: _ClassVar[ErrorReason] - MISSING_ORIGIN: _ClassVar[ErrorReason] - OVERLOADED_CREDENTIALS: _ClassVar[ErrorReason] - LOCATION_ORG_POLICY_VIOLATED: _ClassVar[ErrorReason] - TLS_ORG_POLICY_VIOLATED: _ClassVar[ErrorReason] - EMULATOR_QUOTA_EXCEEDED: _ClassVar[ErrorReason] - CREDENTIAL_ANDROID_APP_INVALID: _ClassVar[ErrorReason] - IAM_PERMISSION_DENIED: _ClassVar[ErrorReason] - JWT_TOKEN_INVALID: _ClassVar[ErrorReason] - CREDENTIAL_TYPE_UNSUPPORTED: _ClassVar[ErrorReason] - ACCOUNT_TYPE_UNSUPPORTED: _ClassVar[ErrorReason] - ENDPOINT_USAGE_RESTRICTION_VIOLATED: _ClassVar[ErrorReason] - TLS_CIPHER_RESTRICTION_VIOLATED: _ClassVar[ErrorReason] - MCP_SERVER_DISABLED: _ClassVar[ErrorReason] - -ERROR_REASON_UNSPECIFIED: ErrorReason -SERVICE_DISABLED: ErrorReason -BILLING_DISABLED: ErrorReason -API_KEY_INVALID: ErrorReason -API_KEY_SERVICE_BLOCKED: ErrorReason -API_KEY_HTTP_REFERRER_BLOCKED: ErrorReason -API_KEY_IP_ADDRESS_BLOCKED: ErrorReason -API_KEY_ANDROID_APP_BLOCKED: ErrorReason -API_KEY_IOS_APP_BLOCKED: ErrorReason -RATE_LIMIT_EXCEEDED: ErrorReason -RESOURCE_QUOTA_EXCEEDED: ErrorReason -LOCATION_TAX_POLICY_VIOLATED: ErrorReason -USER_PROJECT_DENIED: ErrorReason -CONSUMER_SUSPENDED: ErrorReason -CONSUMER_INVALID: ErrorReason -SECURITY_POLICY_VIOLATED: ErrorReason -ACCESS_TOKEN_EXPIRED: ErrorReason -ACCESS_TOKEN_SCOPE_INSUFFICIENT: ErrorReason -ACCOUNT_STATE_INVALID: ErrorReason -ACCESS_TOKEN_TYPE_UNSUPPORTED: ErrorReason -CREDENTIALS_MISSING: ErrorReason -RESOURCE_PROJECT_INVALID: ErrorReason -SESSION_COOKIE_INVALID: ErrorReason -USER_BLOCKED_BY_ADMIN: ErrorReason -RESOURCE_USAGE_RESTRICTION_VIOLATED: ErrorReason -SYSTEM_PARAMETER_UNSUPPORTED: ErrorReason -ORG_RESTRICTION_VIOLATION: ErrorReason -ORG_RESTRICTION_HEADER_INVALID: ErrorReason -SERVICE_NOT_VISIBLE: ErrorReason -GCP_SUSPENDED: ErrorReason -LOCATION_POLICY_VIOLATED: ErrorReason -MISSING_ORIGIN: ErrorReason -OVERLOADED_CREDENTIALS: ErrorReason -LOCATION_ORG_POLICY_VIOLATED: ErrorReason -TLS_ORG_POLICY_VIOLATED: ErrorReason -EMULATOR_QUOTA_EXCEEDED: ErrorReason -CREDENTIAL_ANDROID_APP_INVALID: ErrorReason -IAM_PERMISSION_DENIED: ErrorReason -JWT_TOKEN_INVALID: ErrorReason -CREDENTIAL_TYPE_UNSUPPORTED: ErrorReason -ACCOUNT_TYPE_UNSUPPORTED: ErrorReason -ENDPOINT_USAGE_RESTRICTION_VIOLATED: ErrorReason -TLS_CIPHER_RESTRICTION_VIOLATED: ErrorReason -MCP_SERVER_DISABLED: ErrorReason diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto deleted file mode 100644 index 51f4c7d447c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior.proto +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "FieldBehaviorProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.FieldOptions { - // A designation of a specific field behavior (required, output only, etc.) - // in protobuf messages. - // - // Examples: - // - // string name = 1 [(google.api.field_behavior) = REQUIRED]; - // State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; - // google.protobuf.Duration ttl = 1 - // [(google.api.field_behavior) = INPUT_ONLY]; - // google.protobuf.Timestamp expire_time = 1 - // [(google.api.field_behavior) = OUTPUT_ONLY, - // (google.api.field_behavior) = IMMUTABLE]; - repeated google.api.FieldBehavior field_behavior = 1052; -} - -// An indicator of the behavior of a given field (for example, that a field -// is required in requests, or given as output but ignored as input). -// This **does not** change the behavior in protocol buffers itself; it only -// denotes the behavior and may affect how API tooling handles the field. -// -// Note: This enum **may** receive new values in the future. -enum FieldBehavior { - // Conventional default for enums. Do not use this. - FIELD_BEHAVIOR_UNSPECIFIED = 0; - - // Specifically denotes a field as optional. - // While all fields in protocol buffers are optional, this may be specified - // for emphasis if appropriate. - OPTIONAL = 1; - - // Denotes a field as required. - // This indicates that the field **must** be provided as part of the request, - // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). - REQUIRED = 2; - - // Denotes a field as output only. - // This indicates that the field is provided in responses, but including the - // field in a request does nothing (the server *must* ignore it and - // *must not* throw an error as a result of the field's presence). - OUTPUT_ONLY = 3; - - // Denotes a field as input only. - // This indicates that the field is provided in requests, and the - // corresponding field is not included in output. - INPUT_ONLY = 4; - - // Denotes a field as immutable. - // This indicates that the field may be set once in a request to create a - // resource, but may not be changed thereafter. - IMMUTABLE = 5; - - // Denotes that a (repeated) field is an unordered list. - // This indicates that the service may provide the elements of the list - // in any arbitrary order, rather than the order the user originally - // provided. Additionally, the list's order may or may not be stable. - UNORDERED_LIST = 6; - - // Denotes that this field returns a non-empty default value if not set. - // This indicates that if the user provides the empty value in a request, - // a non-empty value will be returned. The user will not be aware of what - // non-empty value to expect. - NON_EMPTY_DEFAULT = 7; - - // Denotes that the field in a resource (a message annotated with - // google.api.resource) is used in the resource name to uniquely identify the - // resource. For AIP-compliant APIs, this should only be applied to the - // `name` field on the resource. - // - // This behavior should not be applied to references to other resources within - // the message. - // - // The identifier field of resources often have different field behavior - // depending on the request it is embedded in (e.g. for Create methods name - // is optional and unused, while for Update methods it is required). Instead - // of method-specific annotations, only `IDENTIFIER` is required. - IDENTIFIER = 8; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py deleted file mode 100644 index 25b1acee045..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/field_behavior.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/field_behavior.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n\x1fgoogle/api/field_behavior.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto*\xb6\x01\n\rFieldBehavior\x12\x1e\n\x1a\x46IELD_BEHAVIOR_UNSPECIFIED\x10\x00\x12\x0c\n\x08OPTIONAL\x10\x01\x12\x0c\n\x08REQUIRED\x10\x02\x12\x0f\n\x0bOUTPUT_ONLY\x10\x03\x12\x0e\n\nINPUT_ONLY\x10\x04\x12\r\n\tIMMUTABLE\x10\x05\x12\x12\n\x0eUNORDERED_LIST\x10\x06\x12\x15\n\x11NON_EMPTY_DEFAULT\x10\x07\x12\x0e\n\nIDENTIFIER\x10\x08:Q\n\x0e\x66ield_behavior\x12\x1d.google.protobuf.FieldOptions\x18\x9c\x08 \x03(\x0e\x32\x19.google.api.FieldBehaviorBp\n\x0e\x63om.google.apiB\x12\x46ieldBehaviorProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.field_behavior_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\022FieldBehaviorProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" - _globals["_FIELDBEHAVIOR"]._serialized_start = 82 - _globals["_FIELDBEHAVIOR"]._serialized_end = 264 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi deleted file mode 100644 index c67ed0382d3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_behavior_pb2.pyi +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class FieldBehavior(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - FIELD_BEHAVIOR_UNSPECIFIED: _ClassVar[FieldBehavior] - OPTIONAL: _ClassVar[FieldBehavior] - REQUIRED: _ClassVar[FieldBehavior] - OUTPUT_ONLY: _ClassVar[FieldBehavior] - INPUT_ONLY: _ClassVar[FieldBehavior] - IMMUTABLE: _ClassVar[FieldBehavior] - UNORDERED_LIST: _ClassVar[FieldBehavior] - NON_EMPTY_DEFAULT: _ClassVar[FieldBehavior] - IDENTIFIER: _ClassVar[FieldBehavior] - -FIELD_BEHAVIOR_UNSPECIFIED: FieldBehavior -OPTIONAL: FieldBehavior -REQUIRED: FieldBehavior -OUTPUT_ONLY: FieldBehavior -INPUT_ONLY: FieldBehavior -IMMUTABLE: FieldBehavior -UNORDERED_LIST: FieldBehavior -NON_EMPTY_DEFAULT: FieldBehavior -IDENTIFIER: FieldBehavior -FIELD_BEHAVIOR_FIELD_NUMBER: _ClassVar[int] -field_behavior: _descriptor.FieldDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto deleted file mode 100644 index 64387fde139..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info.proto +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "FieldInfoProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.FieldOptions { - // Rich semantic descriptor of an API field beyond the basic typing. - // - // Examples: - // - // string request_id = 1 [(google.api.field_info).format = UUID4]; - // string old_ip_address = 2 [(google.api.field_info).format = IPV4]; - // string new_ip_address = 3 [(google.api.field_info).format = IPV6]; - // string actual_ip_address = 4 [ - // (google.api.field_info).format = IPV4_OR_IPV6 - // ]; - // google.protobuf.Any generic_field = 5 [ - // (google.api.field_info).referenced_types = {type_name: "ActualType"}, - // (google.api.field_info).referenced_types = {type_name: "OtherType"}, - // ]; - // google.protobuf.Any generic_user_input = 5 [ - // (google.api.field_info).referenced_types = {type_name: "*"}, - // ]; - google.api.FieldInfo field_info = 291403980; -} - -// Rich semantic information of an API field beyond basic typing. -message FieldInfo { - // The standard format of a field value. The supported formats are all backed - // by either an RFC defined by the IETF or a Google-defined AIP. - enum Format { - // Default, unspecified value. - FORMAT_UNSPECIFIED = 0; - - // Universally Unique Identifier, version 4, value as defined by - // https://datatracker.ietf.org/doc/html/rfc4122. The value may be - // normalized to entirely lowercase letters. For example, the value - // `F47AC10B-58CC-0372-8567-0E02B2C3D479` would be normalized to - // `f47ac10b-58cc-0372-8567-0e02b2c3d479`. - UUID4 = 1; - - // Internet Protocol v4 value as defined by [RFC - // 791](https://datatracker.ietf.org/doc/html/rfc791). The value may be - // condensed, with leading zeros in each octet stripped. For example, - // `001.022.233.040` would be condensed to `1.22.233.40`. - IPV4 = 2; - - // Internet Protocol v6 value as defined by [RFC - // 2460](https://datatracker.ietf.org/doc/html/rfc2460). The value may be - // normalized to entirely lowercase letters with zeros compressed, following - // [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952). For example, - // the value `2001:0DB8:0::0` would be normalized to `2001:db8::`. - IPV6 = 3; - - // An IP address in either v4 or v6 format as described by the individual - // values defined herein. See the comments on the IPV4 and IPV6 types for - // allowed normalizations of each. - IPV4_OR_IPV6 = 4; - } - - // The standard format of a field value. This does not explicitly configure - // any API consumer, just documents the API's format for the field it is - // applied to. - Format format = 1; - - // The type(s) that the annotated, generic field may represent. - // - // Currently, this must only be used on fields of type `google.protobuf.Any`. - // Supporting other generic types may be considered in the future. - repeated TypeReference referenced_types = 2; -} - -// A reference to a message type, for use in [FieldInfo][google.api.FieldInfo]. -message TypeReference { - // The name of the type that the annotated, generic field may represent. - // If the type is in the same protobuf package, the value can be the simple - // message name e.g., `"MyMessage"`. Otherwise, the value must be the - // fully-qualified message name e.g., `"google.library.v1.Book"`. - // - // If the type(s) are unknown to the service (e.g. the field accepts generic - // user input), use the wildcard `"*"` to denote this behavior. - // - // See [AIP-202](https://google.aip.dev/202#type-references) for more details. - string type_name = 1; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py deleted file mode 100644 index 98b495ae3b5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/field_info.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/field_info.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1bgoogle/api/field_info.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"\xc1\x01\n\tFieldInfo\x12,\n\x06\x66ormat\x18\x01 \x01(\x0e\x32\x1c.google.api.FieldInfo.Format\x12\x33\n\x10referenced_types\x18\x02 \x03(\x0b\x32\x19.google.api.TypeReference"Q\n\x06\x46ormat\x12\x16\n\x12\x46ORMAT_UNSPECIFIED\x10\x00\x12\t\n\x05UUID4\x10\x01\x12\x08\n\x04IPV4\x10\x02\x12\x08\n\x04IPV6\x10\x03\x12\x10\n\x0cIPV4_OR_IPV6\x10\x04""\n\rTypeReference\x12\x11\n\ttype_name\x18\x01 \x01(\t:L\n\nfield_info\x12\x1d.google.protobuf.FieldOptions\x18\xcc\xf1\xf9\x8a\x01 \x01(\x0b\x32\x15.google.api.FieldInfoBl\n\x0e\x63om.google.apiB\x0e\x46ieldInfoProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.field_info_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\016FieldInfoProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" - _globals["_FIELDINFO"]._serialized_start = 78 - _globals["_FIELDINFO"]._serialized_end = 271 - _globals["_FIELDINFO_FORMAT"]._serialized_start = 190 - _globals["_FIELDINFO_FORMAT"]._serialized_end = 271 - _globals["_TYPEREFERENCE"]._serialized_start = 273 - _globals["_TYPEREFERENCE"]._serialized_end = 307 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi deleted file mode 100644 index 4ccc4744a7e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/field_info_pb2.pyi +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor -FIELD_INFO_FIELD_NUMBER: _ClassVar[int] -field_info: _descriptor.FieldDescriptor - -class FieldInfo(_message.Message): - __slots__ = ("format", "referenced_types") - class Format(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - FORMAT_UNSPECIFIED: _ClassVar[FieldInfo.Format] - UUID4: _ClassVar[FieldInfo.Format] - IPV4: _ClassVar[FieldInfo.Format] - IPV6: _ClassVar[FieldInfo.Format] - IPV4_OR_IPV6: _ClassVar[FieldInfo.Format] - - FORMAT_UNSPECIFIED: FieldInfo.Format - UUID4: FieldInfo.Format - IPV4: FieldInfo.Format - IPV6: FieldInfo.Format - IPV4_OR_IPV6: FieldInfo.Format - FORMAT_FIELD_NUMBER: _ClassVar[int] - REFERENCED_TYPES_FIELD_NUMBER: _ClassVar[int] - format: FieldInfo.Format - referenced_types: _containers.RepeatedCompositeFieldContainer[TypeReference] - def __init__( - self, - format: _Optional[_Union[FieldInfo.Format, str]] = ..., - referenced_types: _Optional[_Iterable[_Union[TypeReference, _Mapping]]] = ..., - ) -> None: ... - -class TypeReference(_message.Message): - __slots__ = ("type_name",) - TYPE_NAME_FIELD_NUMBER: _ClassVar[int] - type_name: str - def __init__(self, type_name: _Optional[str] = ...) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto deleted file mode 100644 index bb3af8e56a0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http.proto +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "HttpProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Defines the HTTP configuration for an API service. It contains a list of -// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method -// to one or more HTTP REST API methods. -message Http { - // A list of HTTP configuration rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated HttpRule rules = 1; - - // When set to true, URL path parameters will be fully URI-decoded except in - // cases of single segment matches in reserved expansion, where "%2F" will be - // left encoded. - // - // The default behavior is to not decode RFC 6570 reserved characters in multi - // segment matches. - bool fully_decode_reserved_expansion = 2; -} - -// gRPC Transcoding -// -// gRPC Transcoding is a feature for mapping between a gRPC method and one or -// more HTTP REST endpoints. It allows developers to build a single API service -// that supports both gRPC APIs and REST APIs. Many systems, including [Google -// APIs](https://github.com/googleapis/googleapis), -// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC -// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), -// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature -// and use it for large scale production services. -// -// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies -// how different portions of the gRPC request message are mapped to the URL -// path, URL query parameters, and HTTP request body. It also controls how the -// gRPC response message is mapped to the HTTP response body. `HttpRule` is -// typically specified as an `google.api.http` annotation on the gRPC method. -// -// Each mapping specifies a URL path template and an HTTP method. The path -// template may refer to one or more fields in the gRPC request message, as long -// as each field is a non-repeated field with a primitive (non-message) type. -// The path template controls how fields of the request message are mapped to -// the URL path. -// -// Example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get: "/v1/{name=messages/*}" -// }; -// } -// } -// message GetMessageRequest { -// string name = 1; // Mapped to URL path. -// } -// message Message { -// string text = 1; // The resource content. -// } -// -// This enables an HTTP REST to gRPC mapping as below: -// -// - HTTP: `GET /v1/messages/123456` -// - gRPC: `GetMessage(name: "messages/123456")` -// -// Any fields in the request message which are not bound by the path template -// automatically become HTTP query parameters if there is no HTTP request body. -// For example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get:"/v1/messages/{message_id}" -// }; -// } -// } -// message GetMessageRequest { -// message SubMessage { -// string subfield = 1; -// } -// string message_id = 1; // Mapped to URL path. -// int64 revision = 2; // Mapped to URL query parameter `revision`. -// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. -// } -// -// This enables a HTTP JSON to RPC mapping as below: -// -// - HTTP: `GET /v1/messages/123456?revision=2&sub.subfield=foo` -// - gRPC: `GetMessage(message_id: "123456" revision: 2 sub: -// SubMessage(subfield: "foo"))` -// -// Note that fields which are mapped to URL query parameters must have a -// primitive type or a repeated primitive type or a non-repeated message type. -// In the case of a repeated type, the parameter can be repeated in the URL -// as `...?param=A¶m=B`. In the case of a message type, each field of the -// message is mapped to a separate parameter, such as -// `...?foo.a=A&foo.b=B&foo.c=C`. -// -// For HTTP methods that allow a request body, the `body` field -// specifies the mapping. Consider a REST update method on the -// message resource collection: -// -// service Messaging { -// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { -// option (google.api.http) = { -// patch: "/v1/messages/{message_id}" -// body: "message" -// }; -// } -// } -// message UpdateMessageRequest { -// string message_id = 1; // mapped to the URL -// Message message = 2; // mapped to the body -// } -// -// The following HTTP JSON to RPC mapping is enabled, where the -// representation of the JSON in the request body is determined by -// protos JSON encoding: -// -// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` -// - gRPC: `UpdateMessage(message_id: "123456" message { text: "Hi!" })` -// -// The special name `*` can be used in the body mapping to define that -// every field not bound by the path template should be mapped to the -// request body. This enables the following alternative definition of -// the update method: -// -// service Messaging { -// rpc UpdateMessage(Message) returns (Message) { -// option (google.api.http) = { -// patch: "/v1/messages/{message_id}" -// body: "*" -// }; -// } -// } -// message Message { -// string message_id = 1; -// string text = 2; -// } -// -// -// The following HTTP JSON to RPC mapping is enabled: -// -// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` -// - gRPC: `UpdateMessage(message_id: "123456" text: "Hi!")` -// -// Note that when using `*` in the body mapping, it is not possible to -// have HTTP parameters, as all fields not bound by the path end in -// the body. This makes this option more rarely used in practice when -// defining REST APIs. The common usage of `*` is in custom methods -// which don't use the URL at all for transferring data. -// -// It is possible to define multiple HTTP methods for one RPC by using -// the `additional_bindings` option. Example: -// -// service Messaging { -// rpc GetMessage(GetMessageRequest) returns (Message) { -// option (google.api.http) = { -// get: "/v1/messages/{message_id}" -// additional_bindings { -// get: "/v1/users/{user_id}/messages/{message_id}" -// } -// }; -// } -// } -// message GetMessageRequest { -// string message_id = 1; -// string user_id = 2; -// } -// -// This enables the following two alternative HTTP JSON to RPC mappings: -// -// - HTTP: `GET /v1/messages/123456` -// - gRPC: `GetMessage(message_id: "123456")` -// -// - HTTP: `GET /v1/users/me/messages/123456` -// - gRPC: `GetMessage(user_id: "me" message_id: "123456")` -// -// Rules for HTTP mapping -// -// 1. Leaf request fields (recursive expansion nested messages in the request -// message) are classified into three categories: -// - Fields referred by the path template. They are passed via the URL path. -// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They -// are passed via the HTTP -// request body. -// - All other fields are passed via the URL query parameters, and the -// parameter name is the field path in the request message. A repeated -// field can be represented as multiple query parameters under the same -// name. -// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL -// query parameter, all fields -// are passed via URL path and HTTP request body. -// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP -// request body, all -// fields are passed via URL path and URL query parameters. -// -// Path template syntax -// -// Template = "/" Segments [ Verb ] ; -// Segments = Segment { "/" Segment } ; -// Segment = "*" | "**" | LITERAL | Variable ; -// Variable = "{" FieldPath [ "=" Segments ] "}" ; -// FieldPath = IDENT { "." IDENT } ; -// Verb = ":" LITERAL ; -// -// The syntax `*` matches a single URL path segment. The syntax `**` matches -// zero or more URL path segments, which must be the last part of the URL path -// except the `Verb`. -// -// The syntax `Variable` matches part of the URL path as specified by its -// template. A variable template must not contain other variables. If a variable -// matches a single path segment, its template may be omitted, e.g. `{var}` -// is equivalent to `{var=*}`. -// -// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` -// contains any reserved character, such characters should be percent-encoded -// before the matching. -// -// If a variable contains exactly one path segment, such as `"{var}"` or -// `"{var=*}"`, when such a variable is expanded into a URL path on the client -// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The -// server side does the reverse decoding. Such variables show up in the -// [Discovery -// Document](https://developers.google.com/discovery/v1/reference/apis) as -// `{var}`. -// -// If a variable contains multiple path segments, such as `"{var=foo/*}"` -// or `"{var=**}"`, when such a variable is expanded into a URL path on the -// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. -// The server side does the reverse decoding, except "%2F" and "%2f" are left -// unchanged. Such variables show up in the -// [Discovery -// Document](https://developers.google.com/discovery/v1/reference/apis) as -// `{+var}`. -// -// Using gRPC API Service Configuration -// -// gRPC API Service Configuration (service config) is a configuration language -// for configuring a gRPC service to become a user-facing product. The -// service config is simply the YAML representation of the `google.api.Service` -// proto message. -// -// As an alternative to annotating your proto file, you can configure gRPC -// transcoding in your service config YAML files. You do this by specifying a -// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same -// effect as the proto annotation. This can be particularly useful if you -// have a proto that is reused in multiple services. Note that any transcoding -// specified in the service config will override any matching transcoding -// configuration in the proto. -// -// The following example selects a gRPC method and applies an `HttpRule` to it: -// -// http: -// rules: -// - selector: example.v1.Messaging.GetMessage -// get: /v1/messages/{message_id}/{sub.subfield} -// -// Special notes -// -// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the -// proto to JSON conversion must follow the [proto3 -// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). -// -// While the single segment variable follows the semantics of -// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String -// Expansion, the multi segment variable **does not** follow RFC 6570 Section -// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion -// does not expand special characters like `?` and `#`, which would lead -// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding -// for multi segment variables. -// -// The path variables **must not** refer to any repeated or mapped field, -// because client libraries are not capable of handling such variable expansion. -// -// The path variables **must not** capture the leading "/" character. The reason -// is that the most common use case "{var}" does not capture the leading "/" -// character. For consistency, all path variables must share the same behavior. -// -// Repeated message fields must not be mapped to URL query parameters, because -// no client library can support such complicated mapping. -// -// If an API needs to use a JSON array for request or response body, it can map -// the request or response body to a repeated field. However, some gRPC -// Transcoding implementations may not support this feature. -message HttpRule { - // Selects a method to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // Determines the URL pattern is matched by this rules. This pattern can be - // used with any of the {get|put|post|delete|patch} methods. A custom method - // can be defined using the 'custom' field. - oneof pattern { - // Maps to HTTP GET. Used for listing and getting information about - // resources. - string get = 2; - - // Maps to HTTP PUT. Used for replacing a resource. - string put = 3; - - // Maps to HTTP POST. Used for creating a resource or performing an action. - string post = 4; - - // Maps to HTTP DELETE. Used for deleting a resource. - string delete = 5; - - // Maps to HTTP PATCH. Used for updating a resource. - string patch = 6; - - // The custom pattern is used for specifying an HTTP method that is not - // included in the `pattern` field, such as HEAD, or "*" to leave the - // HTTP method unspecified for this rule. The wild-card rule is useful - // for services that provide content to Web (HTML) clients. - CustomHttpPattern custom = 8; - } - - // The name of the request field whose value is mapped to the HTTP request - // body, or `*` for mapping all request fields not captured by the path - // pattern to the HTTP body, or omitted for not having any HTTP request body. - // - // NOTE: the referred field must be present at the top-level of the request - // message type. - string body = 7; - - // Optional. The name of the response field whose value is mapped to the HTTP - // response body. When omitted, the entire response message will be used - // as the HTTP response body. - // - // NOTE: The referred field must be present at the top-level of the response - // message type. - string response_body = 12; - - // Additional HTTP bindings for the selector. Nested bindings must - // not contain an `additional_bindings` field themselves (that is, - // the nesting may only be one level deep). - repeated HttpRule additional_bindings = 11; -} - -// A custom pattern is used for defining custom HTTP verb. -message CustomHttpPattern { - // The name of this custom HTTP verb. - string kind = 1; - - // The path matched by this custom verb. - string path = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py deleted file mode 100644 index baed2dbed8c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/http.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/http.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x15google/api/http.proto\x12\ngoogle.api"T\n\x04Http\x12#\n\x05rules\x18\x01 \x03(\x0b\x32\x14.google.api.HttpRule\x12\'\n\x1f\x66ully_decode_reserved_expansion\x18\x02 \x01(\x08"\x81\x02\n\x08HttpRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\r\n\x03get\x18\x02 \x01(\tH\x00\x12\r\n\x03put\x18\x03 \x01(\tH\x00\x12\x0e\n\x04post\x18\x04 \x01(\tH\x00\x12\x10\n\x06\x64\x65lete\x18\x05 \x01(\tH\x00\x12\x0f\n\x05patch\x18\x06 \x01(\tH\x00\x12/\n\x06\x63ustom\x18\x08 \x01(\x0b\x32\x1d.google.api.CustomHttpPatternH\x00\x12\x0c\n\x04\x62ody\x18\x07 \x01(\t\x12\x15\n\rresponse_body\x18\x0c \x01(\t\x12\x31\n\x13\x61\x64\x64itional_bindings\x18\x0b \x03(\x0b\x32\x14.google.api.HttpRuleB\t\n\x07pattern"/\n\x11\x43ustomHttpPattern\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\tBg\n\x0e\x63om.google.apiB\tHttpProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.http_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\tHttpProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" - _globals["_HTTP"]._serialized_start = 37 - _globals["_HTTP"]._serialized_end = 121 - _globals["_HTTPRULE"]._serialized_start = 124 - _globals["_HTTPRULE"]._serialized_end = 381 - _globals["_CUSTOMHTTPPATTERN"]._serialized_start = 383 - _globals["_CUSTOMHTTPPATTERN"]._serialized_end = 430 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi deleted file mode 100644 index 2dafa8fc029..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/http_pb2.pyi +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Http(_message.Message): - __slots__ = ("rules", "fully_decode_reserved_expansion") - RULES_FIELD_NUMBER: _ClassVar[int] - FULLY_DECODE_RESERVED_EXPANSION_FIELD_NUMBER: _ClassVar[int] - rules: _containers.RepeatedCompositeFieldContainer[HttpRule] - fully_decode_reserved_expansion: bool - def __init__( - self, - rules: _Optional[_Iterable[_Union[HttpRule, _Mapping]]] = ..., - fully_decode_reserved_expansion: _Optional[bool] = ..., - ) -> None: ... - -class HttpRule(_message.Message): - __slots__ = ( - "selector", - "get", - "put", - "post", - "delete", - "patch", - "custom", - "body", - "response_body", - "additional_bindings", - ) - SELECTOR_FIELD_NUMBER: _ClassVar[int] - GET_FIELD_NUMBER: _ClassVar[int] - PUT_FIELD_NUMBER: _ClassVar[int] - POST_FIELD_NUMBER: _ClassVar[int] - DELETE_FIELD_NUMBER: _ClassVar[int] - PATCH_FIELD_NUMBER: _ClassVar[int] - CUSTOM_FIELD_NUMBER: _ClassVar[int] - BODY_FIELD_NUMBER: _ClassVar[int] - RESPONSE_BODY_FIELD_NUMBER: _ClassVar[int] - ADDITIONAL_BINDINGS_FIELD_NUMBER: _ClassVar[int] - selector: str - get: str - put: str - post: str - delete: str - patch: str - custom: CustomHttpPattern - body: str - response_body: str - additional_bindings: _containers.RepeatedCompositeFieldContainer[HttpRule] - def __init__( - self, - selector: _Optional[str] = ..., - get: _Optional[str] = ..., - put: _Optional[str] = ..., - post: _Optional[str] = ..., - delete: _Optional[str] = ..., - patch: _Optional[str] = ..., - custom: _Optional[_Union[CustomHttpPattern, _Mapping]] = ..., - body: _Optional[str] = ..., - response_body: _Optional[str] = ..., - additional_bindings: _Optional[_Iterable[_Union[HttpRule, _Mapping]]] = ..., - ) -> None: ... - -class CustomHttpPattern(_message.Message): - __slots__ = ("kind", "path") - KIND_FIELD_NUMBER: _ClassVar[int] - PATH_FIELD_NUMBER: _ClassVar[int] - kind: str - path: str - def __init__( - self, kind: _Optional[str] = ..., path: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto deleted file mode 100644 index 3fd226a987f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody.proto +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/any.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; -option java_multiple_files = true; -option java_outer_classname = "HttpBodyProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Message that represents an arbitrary HTTP body. It should only be used for -// payload formats that can't be represented as JSON, such as raw binary or -// an HTML page. -// -// -// This message can be used both in streaming and non-streaming API methods in -// the request as well as the response. -// -// It can be used as a top-level request field, which is convenient if one -// wants to extract parameters from either the URL or HTTP template into the -// request fields and also want access to the raw HTTP body. -// -// Example: -// -// message GetResourceRequest { -// // A unique request id. -// string request_id = 1; -// -// // The raw HTTP body is bound to this field. -// google.api.HttpBody http_body = 2; -// -// } -// -// service ResourceService { -// rpc GetResource(GetResourceRequest) -// returns (google.api.HttpBody); -// rpc UpdateResource(google.api.HttpBody) -// returns (google.protobuf.Empty); -// -// } -// -// Example with streaming methods: -// -// service CaldavService { -// rpc GetCalendar(stream google.api.HttpBody) -// returns (stream google.api.HttpBody); -// rpc UpdateCalendar(stream google.api.HttpBody) -// returns (stream google.api.HttpBody); -// -// } -// -// Use of this type only changes how the request and response bodies are -// handled, all other features will continue to work unchanged. -message HttpBody { - // The HTTP Content-Type header value specifying the content type of the body. - string content_type = 1; - - // The HTTP request/response body as raw binary. - bytes data = 2; - - // Application specific response metadata. Must be set in the first response - // for streaming APIs. - repeated google.protobuf.Any extensions = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py deleted file mode 100644 index 78e7ba6030e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/httpbody.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/httpbody.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x19google/api/httpbody.proto\x12\ngoogle.api\x1a\x19google/protobuf/any.proto"X\n\x08HttpBody\x12\x14\n\x0c\x63ontent_type\x18\x01 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x12(\n\nextensions\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyBe\n\x0e\x63om.google.apiB\rHttpBodyProtoP\x01Z;google.golang.org/genproto/googleapis/api/httpbody;httpbody\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.httpbody_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\rHttpBodyProtoP\001Z;google.golang.org/genproto/googleapis/api/httpbody;httpbody\242\002\004GAPI" - _globals["_HTTPBODY"]._serialized_start = 68 - _globals["_HTTPBODY"]._serialized_end = 156 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi deleted file mode 100644 index eed5062fd19..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/httpbody_pb2.pyi +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import any_pb2 as _any_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class HttpBody(_message.Message): - __slots__ = ("content_type", "data", "extensions") - CONTENT_TYPE_FIELD_NUMBER: _ClassVar[int] - DATA_FIELD_NUMBER: _ClassVar[int] - EXTENSIONS_FIELD_NUMBER: _ClassVar[int] - content_type: str - data: bytes - extensions: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] - def __init__( - self, - content_type: _Optional[str] = ..., - data: _Optional[bytes] = ..., - extensions: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto deleted file mode 100644 index 5d77c708824..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label.proto +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/label;label"; -option java_multiple_files = true; -option java_outer_classname = "LabelProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// A description of a label. -message LabelDescriptor { - // Value types that can be used as label values. - enum ValueType { - // A variable-length string. This is the default. - STRING = 0; - - // Boolean; true or false. - BOOL = 1; - - // A 64-bit signed integer. - INT64 = 2; - } - - // The label key. - string key = 1; - - // The type of data that can be assigned to the label. - ValueType value_type = 2; - - // A human-readable description for the label. - string description = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py deleted file mode 100644 index cb3a441a503..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/label.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/label.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x16google/api/label.proto\x12\ngoogle.api"\x9c\x01\n\x0fLabelDescriptor\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x39\n\nvalue_type\x18\x02 \x01(\x0e\x32%.google.api.LabelDescriptor.ValueType\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t",\n\tValueType\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x42OOL\x10\x01\x12\t\n\x05INT64\x10\x02\x42\\\n\x0e\x63om.google.apiB\nLabelProtoP\x01Z5google.golang.org/genproto/googleapis/api/label;label\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.label_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\nLabelProtoP\001Z5google.golang.org/genproto/googleapis/api/label;label\242\002\004GAPI" - _globals["_LABELDESCRIPTOR"]._serialized_start = 39 - _globals["_LABELDESCRIPTOR"]._serialized_end = 195 - _globals["_LABELDESCRIPTOR_VALUETYPE"]._serialized_start = 151 - _globals["_LABELDESCRIPTOR_VALUETYPE"]._serialized_end = 195 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi deleted file mode 100644 index ca9a0b71406..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/label_pb2.pyi +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class LabelDescriptor(_message.Message): - __slots__ = ("key", "value_type", "description") - class ValueType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - STRING: _ClassVar[LabelDescriptor.ValueType] - BOOL: _ClassVar[LabelDescriptor.ValueType] - INT64: _ClassVar[LabelDescriptor.ValueType] - - STRING: LabelDescriptor.ValueType - BOOL: LabelDescriptor.ValueType - INT64: LabelDescriptor.ValueType - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_TYPE_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - key: str - value_type: LabelDescriptor.ValueType - description: str - def __init__( - self, - key: _Optional[str] = ..., - value_type: _Optional[_Union[LabelDescriptor.ValueType, str]] = ..., - description: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto deleted file mode 100644 index 0fff247bd8f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage.proto +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api;api"; -option java_multiple_files = true; -option java_outer_classname = "LaunchStageProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// The launch stage as defined by [Google Cloud Platform -// Launch Stages](https://cloud.google.com/terms/launch-stages). -enum LaunchStage { - // Do not use this default value. - LAUNCH_STAGE_UNSPECIFIED = 0; - - // The feature is not yet implemented. Users can not use it. - UNIMPLEMENTED = 6; - - // Prelaunch features are hidden from users and are only visible internally. - PRELAUNCH = 7; - - // Early Access features are limited to a closed group of testers. To use - // these features, you must sign up in advance and sign a Trusted Tester - // agreement (which includes confidentiality provisions). These features may - // be unstable, changed in backward-incompatible ways, and are not - // guaranteed to be released. - EARLY_ACCESS = 1; - - // Alpha is a limited availability test for releases before they are cleared - // for widespread use. By Alpha, all significant design issues are resolved - // and we are in the process of verifying functionality. Alpha customers - // need to apply for access, agree to applicable terms, and have their - // projects allowlisted. Alpha releases don't have to be feature complete, - // no SLAs are provided, and there are no technical support obligations, but - // they will be far enough along that customers can actually use them in - // test environments or for limited-use tests -- just like they would in - // normal production cases. - ALPHA = 2; - - // Beta is the point at which we are ready to open a release for any - // customer to use. There are no SLA or technical support obligations in a - // Beta release. Products will be complete from a feature perspective, but - // may have some open outstanding issues. Beta releases are suitable for - // limited production use cases. - BETA = 3; - - // GA features are open to all developers and are considered stable and - // fully qualified for production use. - GA = 4; - - // Deprecated features are scheduled to be shut down and removed. For more - // information, see the "Deprecation Policy" section of our [Terms of - // Service](https://cloud.google.com/terms/) - // and the [Google Cloud Platform Subject to the Deprecation - // Policy](https://cloud.google.com/terms/deprecation) documentation. - DEPRECATED = 5; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py deleted file mode 100644 index 7e0bc0586a9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/launch_stage.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/launch_stage.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n\x1dgoogle/api/launch_stage.proto\x12\ngoogle.api*\x8c\x01\n\x0bLaunchStage\x12\x1c\n\x18LAUNCH_STAGE_UNSPECIFIED\x10\x00\x12\x11\n\rUNIMPLEMENTED\x10\x06\x12\r\n\tPRELAUNCH\x10\x07\x12\x10\n\x0c\x45\x41RLY_ACCESS\x10\x01\x12\t\n\x05\x41LPHA\x10\x02\x12\x08\n\x04\x42\x45TA\x10\x03\x12\x06\n\x02GA\x10\x04\x12\x0e\n\nDEPRECATED\x10\x05\x42Z\n\x0e\x63om.google.apiB\x10LaunchStageProtoP\x01Z-google.golang.org/genproto/googleapis/api;api\xa2\x02\x04GAPIb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.launch_stage_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\020LaunchStageProtoP\001Z-google.golang.org/genproto/googleapis/api;api\242\002\004GAPI" - _globals["_LAUNCHSTAGE"]._serialized_start = 46 - _globals["_LAUNCHSTAGE"]._serialized_end = 186 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi deleted file mode 100644 index bdbe119a889..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/launch_stage_pb2.pyi +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class LaunchStage(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - LAUNCH_STAGE_UNSPECIFIED: _ClassVar[LaunchStage] - UNIMPLEMENTED: _ClassVar[LaunchStage] - PRELAUNCH: _ClassVar[LaunchStage] - EARLY_ACCESS: _ClassVar[LaunchStage] - ALPHA: _ClassVar[LaunchStage] - BETA: _ClassVar[LaunchStage] - GA: _ClassVar[LaunchStage] - DEPRECATED: _ClassVar[LaunchStage] - -LAUNCH_STAGE_UNSPECIFIED: LaunchStage -UNIMPLEMENTED: LaunchStage -PRELAUNCH: LaunchStage -EARLY_ACCESS: LaunchStage -ALPHA: LaunchStage -BETA: LaunchStage -GA: LaunchStage -DEPRECATED: LaunchStage diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto deleted file mode 100644 index 2f13e72750b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log.proto +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/label.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "LogProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// A description of a log type. Example in YAML format: -// -// - name: library.googleapis.com/activity_history -// description: The history of borrowing and returning library items. -// display_name: Activity -// labels: -// - key: /customer_id -// description: Identifier of a library customer -message LogDescriptor { - // The name of the log. It must be less than 512 characters long and can - // include the following characters: upper- and lower-case alphanumeric - // characters [A-Za-z0-9], and punctuation characters including - // slash, underscore, hyphen, period [/_-.]. - string name = 1; - - // The set of labels that are available to describe a specific log entry. - // Runtime requests that contain labels not specified here are - // considered invalid. - repeated LabelDescriptor labels = 2; - - // A human-readable description of this log. This information appears in - // the documentation and can contain details. - string description = 3; - - // The human-readable name for this log. This information appears on - // the user interface and should be concise. - string display_name = 4; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py deleted file mode 100644 index ef3f554be63..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/log.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/log.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.api import label_pb2 as google_dot_api_dot_label__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x14google/api/log.proto\x12\ngoogle.api\x1a\x16google/api/label.proto"u\n\rLogDescriptor\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x06labels\x18\x02 \x03(\x0b\x32\x1b.google.api.LabelDescriptor\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\tBj\n\x0e\x63om.google.apiB\x08LogProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.log_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\010LogProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_LOGDESCRIPTOR"]._serialized_start = 60 - _globals["_LOGDESCRIPTOR"]._serialized_end = 177 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi deleted file mode 100644 index 76948cac3d3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/log_pb2.pyi +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -from google.api import label_pb2 as _label_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class LogDescriptor(_message.Message): - __slots__ = ("name", "labels", "description", "display_name") - NAME_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] - name: str - labels: _containers.RepeatedCompositeFieldContainer[_label_pb2.LabelDescriptor] - description: str - display_name: str - def __init__( - self, - name: _Optional[str] = ..., - labels: _Optional[ - _Iterable[_Union[_label_pb2.LabelDescriptor, _Mapping]] - ] = ..., - description: _Optional[str] = ..., - display_name: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto deleted file mode 100644 index 7a82de9acb6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging.proto +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "LoggingProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Logging configuration of the service. -// -// The following example shows how to configure logs to be sent to the -// producer and consumer projects. In the example, the `activity_history` -// log is sent to both the producer and consumer projects, whereas the -// `purchase_history` log is only sent to the producer project. -// -// monitored_resources: -// - type: library.googleapis.com/branch -// labels: -// - key: /city -// description: The city where the library branch is located in. -// - key: /name -// description: The name of the branch. -// logs: -// - name: activity_history -// labels: -// - key: /customer_id -// - name: purchase_history -// logging: -// producer_destinations: -// - monitored_resource: library.googleapis.com/branch -// logs: -// - activity_history -// - purchase_history -// consumer_destinations: -// - monitored_resource: library.googleapis.com/branch -// logs: -// - activity_history -message Logging { - // Configuration of a specific logging destination (the producer project - // or the consumer project). - message LoggingDestination { - // The monitored resource type. The type must be defined in the - // [Service.monitored_resources][google.api.Service.monitored_resources] - // section. - string monitored_resource = 3; - - // Names of the logs to be sent to this destination. Each name must - // be defined in the [Service.logs][google.api.Service.logs] section. If the - // log name is not a domain scoped name, it will be automatically prefixed - // with the service name followed by "/". - repeated string logs = 1; - } - - // Logging configurations for sending logs to the producer project. - // There can be multiple producer destinations, each one must have a - // different monitored resource type. A log can be used in at most - // one producer destination. - repeated LoggingDestination producer_destinations = 1; - - // Logging configurations for sending logs to the consumer project. - // There can be multiple consumer destinations, each one must have a - // different monitored resource type. A log can be used in at most - // one consumer destination. - repeated LoggingDestination consumer_destinations = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py deleted file mode 100644 index 22bcad2bf73..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/logging.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/logging.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x18google/api/logging.proto\x12\ngoogle.api"\xd7\x01\n\x07Logging\x12\x45\n\x15producer_destinations\x18\x01 \x03(\x0b\x32&.google.api.Logging.LoggingDestination\x12\x45\n\x15\x63onsumer_destinations\x18\x02 \x03(\x0b\x32&.google.api.Logging.LoggingDestination\x1a>\n\x12LoggingDestination\x12\x1a\n\x12monitored_resource\x18\x03 \x01(\t\x12\x0c\n\x04logs\x18\x01 \x03(\tBn\n\x0e\x63om.google.apiB\x0cLoggingProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.logging_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\014LoggingProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_LOGGING"]._serialized_start = 41 - _globals["_LOGGING"]._serialized_end = 256 - _globals["_LOGGING_LOGGINGDESTINATION"]._serialized_start = 194 - _globals["_LOGGING_LOGGINGDESTINATION"]._serialized_end = 256 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi deleted file mode 100644 index aa29c856c97..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/logging_pb2.pyi +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Logging(_message.Message): - __slots__ = ("producer_destinations", "consumer_destinations") - class LoggingDestination(_message.Message): - __slots__ = ("monitored_resource", "logs") - MONITORED_RESOURCE_FIELD_NUMBER: _ClassVar[int] - LOGS_FIELD_NUMBER: _ClassVar[int] - monitored_resource: str - logs: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - monitored_resource: _Optional[str] = ..., - logs: _Optional[_Iterable[str]] = ..., - ) -> None: ... - - PRODUCER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] - CONSUMER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] - producer_destinations: _containers.RepeatedCompositeFieldContainer[ - Logging.LoggingDestination - ] - consumer_destinations: _containers.RepeatedCompositeFieldContainer[ - Logging.LoggingDestination - ] - def __init__( - self, - producer_destinations: _Optional[ - _Iterable[_Union[Logging.LoggingDestination, _Mapping]] - ] = ..., - consumer_destinations: _Optional[ - _Iterable[_Union[Logging.LoggingDestination, _Mapping]] - ] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto deleted file mode 100644 index b7fb82a9bb6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric.proto +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/label.proto"; -import "google/api/launch_stage.proto"; -import "google/protobuf/duration.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/metric;metric"; -option java_multiple_files = true; -option java_outer_classname = "MetricProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Defines a metric type and its schema. Once a metric descriptor is created, -// deleting or altering it stops data collection and makes the metric type's -// existing data unusable. -// -message MetricDescriptor { - // The kind of measurement. It describes how the data is reported. - // For information on setting the start time and end time based on - // the MetricKind, see [TimeInterval][google.monitoring.v3.TimeInterval]. - enum MetricKind { - // Do not use this default value. - METRIC_KIND_UNSPECIFIED = 0; - - // An instantaneous measurement of a value. - GAUGE = 1; - - // The change in a value during a time interval. - DELTA = 2; - - // A value accumulated over a time interval. Cumulative - // measurements in a time series should have the same start time - // and increasing end times, until an event resets the cumulative - // value to zero and sets a new start time for the following - // points. - CUMULATIVE = 3; - } - - // The value type of a metric. - enum ValueType { - // Do not use this default value. - VALUE_TYPE_UNSPECIFIED = 0; - - // The value is a boolean. - // This value type can be used only if the metric kind is `GAUGE`. - BOOL = 1; - - // The value is a signed 64-bit integer. - INT64 = 2; - - // The value is a double precision floating point number. - DOUBLE = 3; - - // The value is a text string. - // This value type can be used only if the metric kind is `GAUGE`. - STRING = 4; - - // The value is a [`Distribution`][google.api.Distribution]. - DISTRIBUTION = 5; - - // The value is money. - MONEY = 6; - } - - // Additional annotations that can be used to guide the usage of a metric. - message MetricDescriptorMetadata { - // The resource hierarchy level of the timeseries data of a metric. - enum TimeSeriesResourceHierarchyLevel { - // Do not use this default value. - TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED = 0; - - // Scopes a metric to a project. - PROJECT = 1; - - // Scopes a metric to an organization. - ORGANIZATION = 2; - - // Scopes a metric to a folder. - FOLDER = 3; - } - - // Deprecated. Must use the - // [MetricDescriptor.launch_stage][google.api.MetricDescriptor.launch_stage] - // instead. - LaunchStage launch_stage = 1 [deprecated = true]; - - // The sampling period of metric data points. For metrics which are written - // periodically, consecutive data points are stored at this time interval, - // excluding data loss due to errors. Metrics with a higher granularity have - // a smaller sampling period. - google.protobuf.Duration sample_period = 2; - - // The delay of data points caused by ingestion. Data points older than this - // age are guaranteed to be ingested and available to be read, excluding - // data loss due to errors. - google.protobuf.Duration ingest_delay = 3; - - // The scope of the timeseries data of the metric. - repeated TimeSeriesResourceHierarchyLevel - time_series_resource_hierarchy_level = 4; - } - - // The resource name of the metric descriptor. - string name = 1; - - // The metric type, including its DNS name prefix. The type is not - // URL-encoded. All user-defined metric types have the DNS name - // `custom.googleapis.com` or `external.googleapis.com`. Metric types should - // use a natural hierarchical grouping. For example: - // - // "custom.googleapis.com/invoice/paid/amount" - // "external.googleapis.com/prometheus/up" - // "appengine.googleapis.com/http/server/response_latencies" - string type = 8; - - // The set of labels that can be used to describe a specific - // instance of this metric type. For example, the - // `appengine.googleapis.com/http/server/response_latencies` metric - // type has a label for the HTTP response code, `response_code`, so - // you can look at latencies for successful responses or just - // for responses that failed. - repeated LabelDescriptor labels = 2; - - // Whether the metric records instantaneous values, changes to a value, etc. - // Some combinations of `metric_kind` and `value_type` might not be supported. - MetricKind metric_kind = 3; - - // Whether the measurement is an integer, a floating-point number, etc. - // Some combinations of `metric_kind` and `value_type` might not be supported. - ValueType value_type = 4; - - // The units in which the metric value is reported. It is only applicable - // if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` - // defines the representation of the stored metric values. - // - // Different systems might scale the values to be more easily displayed (so a - // value of `0.02kBy` _might_ be displayed as `20By`, and a value of - // `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is - // `kBy`, then the value of the metric is always in thousands of bytes, no - // matter how it might be displayed. - // - // If you want a custom metric to record the exact number of CPU-seconds used - // by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is - // `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 - // CPU-seconds, then the value is written as `12005`. - // - // Alternatively, if you want a custom metric to record data in a more - // granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is - // `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), - // or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). - // - // The supported units are a subset of [The Unified Code for Units of - // Measure](https://unitsofmeasure.org/ucum.html) standard: - // - // **Basic units (UNIT)** - // - // * `bit` bit - // * `By` byte - // * `s` second - // * `min` minute - // * `h` hour - // * `d` day - // * `1` dimensionless - // - // **Prefixes (PREFIX)** - // - // * `k` kilo (10^3) - // * `M` mega (10^6) - // * `G` giga (10^9) - // * `T` tera (10^12) - // * `P` peta (10^15) - // * `E` exa (10^18) - // * `Z` zetta (10^21) - // * `Y` yotta (10^24) - // - // * `m` milli (10^-3) - // * `u` micro (10^-6) - // * `n` nano (10^-9) - // * `p` pico (10^-12) - // * `f` femto (10^-15) - // * `a` atto (10^-18) - // * `z` zepto (10^-21) - // * `y` yocto (10^-24) - // - // * `Ki` kibi (2^10) - // * `Mi` mebi (2^20) - // * `Gi` gibi (2^30) - // * `Ti` tebi (2^40) - // * `Pi` pebi (2^50) - // - // **Grammar** - // - // The grammar also includes these connectors: - // - // * `/` division or ratio (as an infix operator). For examples, - // `kBy/{email}` or `MiBy/10ms` (although you should almost never - // have `/s` in a metric `unit`; rates should always be computed at - // query time from the underlying cumulative or delta value). - // * `.` multiplication or composition (as an infix operator). For - // examples, `GBy.d` or `k{watt}.h`. - // - // The grammar for a unit is as follows: - // - // Expression = Component { "." Component } { "/" Component } ; - // - // Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] - // | Annotation - // | "1" - // ; - // - // Annotation = "{" NAME "}" ; - // - // Notes: - // - // * `Annotation` is just a comment if it follows a `UNIT`. If the annotation - // is used alone, then the unit is equivalent to `1`. For examples, - // `{request}/s == 1/s`, `By{transmitted}/s == By/s`. - // * `NAME` is a sequence of non-blank printable ASCII characters not - // containing `{` or `}`. - // * `1` represents a unitary [dimensionless - // unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such - // as in `1/s`. It is typically used when none of the basic units are - // appropriate. For example, "new users per day" can be represented as - // `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new - // users). Alternatively, "thousands of page views per day" would be - // represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric - // value of `5.3` would mean "5300 page views per day"). - // * `%` represents dimensionless value of 1/100, and annotates values giving - // a percentage (so the metric values are typically in the range of 0..100, - // and a metric value `3` means "3 percent"). - // * `10^2.%` indicates a metric contains a ratio, typically in the range - // 0..1, that will be multiplied by 100 and displayed as a percentage - // (so a metric value `0.03` means "3 percent"). - string unit = 5; - - // A detailed description of the metric, which can be used in documentation. - string description = 6; - - // A concise name for the metric, which can be displayed in user interfaces. - // Use sentence case without an ending period, for example "Request count". - // This field is optional but it is recommended to be set for any metrics - // associated with user-visible concepts, such as Quota. - string display_name = 7; - - // Optional. Metadata which can be used to guide usage of the metric. - MetricDescriptorMetadata metadata = 10; - - // Optional. The launch stage of the metric definition. - LaunchStage launch_stage = 12; - - // Read-only. If present, then a [time - // series][google.monitoring.v3.TimeSeries], which is identified partially by - // a metric type and a - // [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that - // is associated with this metric type can only be associated with one of the - // monitored resource types listed here. - repeated string monitored_resource_types = 13; -} - -// A specific metric, identified by specifying values for all of the -// labels of a [`MetricDescriptor`][google.api.MetricDescriptor]. -message Metric { - // An existing metric type, see - // [google.api.MetricDescriptor][google.api.MetricDescriptor]. For example, - // `custom.googleapis.com/invoice/paid/amount`. - string type = 3; - - // The set of label values that uniquely identify this metric. All - // labels listed in the `MetricDescriptor` must be assigned values. - map labels = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py deleted file mode 100644 index 97d2225df82..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/metric.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/metric.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 - -from opentelemetry.agent._vendor.google.api import label_pb2 as google_dot_api_dot_label__pb2 -from opentelemetry.agent._vendor.google.api import launch_stage_pb2 as google_dot_api_dot_launch__stage__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x17google/api/metric.proto\x12\ngoogle.api\x1a\x16google/api/label.proto\x1a\x1dgoogle/api/launch_stage.proto\x1a\x1egoogle/protobuf/duration.proto"\xac\x08\n\x10MetricDescriptor\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x08 \x01(\t\x12+\n\x06labels\x18\x02 \x03(\x0b\x32\x1b.google.api.LabelDescriptor\x12<\n\x0bmetric_kind\x18\x03 \x01(\x0e\x32\'.google.api.MetricDescriptor.MetricKind\x12:\n\nvalue_type\x18\x04 \x01(\x0e\x32&.google.api.MetricDescriptor.ValueType\x12\x0c\n\x04unit\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x07 \x01(\t\x12G\n\x08metadata\x18\n \x01(\x0b\x32\x35.google.api.MetricDescriptor.MetricDescriptorMetadata\x12-\n\x0claunch_stage\x18\x0c \x01(\x0e\x32\x17.google.api.LaunchStage\x12 \n\x18monitored_resource_types\x18\r \x03(\t\x1a\xbd\x03\n\x18MetricDescriptorMetadata\x12\x31\n\x0claunch_stage\x18\x01 \x01(\x0e\x32\x17.google.api.LaunchStageB\x02\x18\x01\x12\x30\n\rsample_period\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12/\n\x0cingest_delay\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x84\x01\n$time_series_resource_hierarchy_level\x18\x04 \x03(\x0e\x32V.google.api.MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel"\x83\x01\n TimeSeriesResourceHierarchyLevel\x12\x34\n0TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED\x10\x00\x12\x0b\n\x07PROJECT\x10\x01\x12\x10\n\x0cORGANIZATION\x10\x02\x12\n\n\x06\x46OLDER\x10\x03"O\n\nMetricKind\x12\x1b\n\x17METRIC_KIND_UNSPECIFIED\x10\x00\x12\t\n\x05GAUGE\x10\x01\x12\t\n\x05\x44\x45LTA\x10\x02\x12\x0e\n\nCUMULATIVE\x10\x03"q\n\tValueType\x12\x1a\n\x16VALUE_TYPE_UNSPECIFIED\x10\x00\x12\x08\n\x04\x42OOL\x10\x01\x12\t\n\x05INT64\x10\x02\x12\n\n\x06\x44OUBLE\x10\x03\x12\n\n\x06STRING\x10\x04\x12\x10\n\x0c\x44ISTRIBUTION\x10\x05\x12\t\n\x05MONEY\x10\x06"u\n\x06Metric\x12\x0c\n\x04type\x18\x03 \x01(\t\x12.\n\x06labels\x18\x02 \x03(\x0b\x32\x1e.google.api.Metric.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42_\n\x0e\x63om.google.apiB\x0bMetricProtoP\x01Z7google.golang.org/genproto/googleapis/api/metric;metric\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.metric_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\013MetricProtoP\001Z7google.golang.org/genproto/googleapis/api/metric;metric\242\002\004GAPI" - _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"].fields_by_name[ - "launch_stage" - ]._loaded_options = None - _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"].fields_by_name[ - "launch_stage" - ]._serialized_options = b"\030\001" - _globals["_METRIC_LABELSENTRY"]._loaded_options = None - _globals["_METRIC_LABELSENTRY"]._serialized_options = b"8\001" - _globals["_METRICDESCRIPTOR"]._serialized_start = 127 - _globals["_METRICDESCRIPTOR"]._serialized_end = 1195 - _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"]._serialized_start = 554 - _globals["_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA"]._serialized_end = 999 - _globals[ - "_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA_TIMESERIESRESOURCEHIERARCHYLEVEL" - ]._serialized_start = 868 - _globals[ - "_METRICDESCRIPTOR_METRICDESCRIPTORMETADATA_TIMESERIESRESOURCEHIERARCHYLEVEL" - ]._serialized_end = 999 - _globals["_METRICDESCRIPTOR_METRICKIND"]._serialized_start = 1001 - _globals["_METRICDESCRIPTOR_METRICKIND"]._serialized_end = 1080 - _globals["_METRICDESCRIPTOR_VALUETYPE"]._serialized_start = 1082 - _globals["_METRICDESCRIPTOR_VALUETYPE"]._serialized_end = 1195 - _globals["_METRIC"]._serialized_start = 1197 - _globals["_METRIC"]._serialized_end = 1314 - _globals["_METRIC_LABELSENTRY"]._serialized_start = 1269 - _globals["_METRIC_LABELSENTRY"]._serialized_end = 1314 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi deleted file mode 100644 index 6da69754a09..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/metric_pb2.pyi +++ /dev/null @@ -1,199 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import duration_pb2 as _duration_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -from google.api import label_pb2 as _label_pb2 -from google.api import launch_stage_pb2 as _launch_stage_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class MetricDescriptor(_message.Message): - __slots__ = ( - "name", - "type", - "labels", - "metric_kind", - "value_type", - "unit", - "description", - "display_name", - "metadata", - "launch_stage", - "monitored_resource_types", - ) - class MetricKind(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - METRIC_KIND_UNSPECIFIED: _ClassVar[MetricDescriptor.MetricKind] - GAUGE: _ClassVar[MetricDescriptor.MetricKind] - DELTA: _ClassVar[MetricDescriptor.MetricKind] - CUMULATIVE: _ClassVar[MetricDescriptor.MetricKind] - - METRIC_KIND_UNSPECIFIED: MetricDescriptor.MetricKind - GAUGE: MetricDescriptor.MetricKind - DELTA: MetricDescriptor.MetricKind - CUMULATIVE: MetricDescriptor.MetricKind - class ValueType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - VALUE_TYPE_UNSPECIFIED: _ClassVar[MetricDescriptor.ValueType] - BOOL: _ClassVar[MetricDescriptor.ValueType] - INT64: _ClassVar[MetricDescriptor.ValueType] - DOUBLE: _ClassVar[MetricDescriptor.ValueType] - STRING: _ClassVar[MetricDescriptor.ValueType] - DISTRIBUTION: _ClassVar[MetricDescriptor.ValueType] - MONEY: _ClassVar[MetricDescriptor.ValueType] - - VALUE_TYPE_UNSPECIFIED: MetricDescriptor.ValueType - BOOL: MetricDescriptor.ValueType - INT64: MetricDescriptor.ValueType - DOUBLE: MetricDescriptor.ValueType - STRING: MetricDescriptor.ValueType - DISTRIBUTION: MetricDescriptor.ValueType - MONEY: MetricDescriptor.ValueType - class MetricDescriptorMetadata(_message.Message): - __slots__ = ( - "launch_stage", - "sample_period", - "ingest_delay", - "time_series_resource_hierarchy_level", - ) - class TimeSeriesResourceHierarchyLevel( - int, metaclass=_enum_type_wrapper.EnumTypeWrapper - ): - __slots__ = () - TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED: _ClassVar[ - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ] - PROJECT: _ClassVar[ - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ] - ORGANIZATION: _ClassVar[ - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ] - FOLDER: _ClassVar[ - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ] - - TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED: ( - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ) - PROJECT: ( - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ) - ORGANIZATION: ( - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ) - FOLDER: ( - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ) - LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] - SAMPLE_PERIOD_FIELD_NUMBER: _ClassVar[int] - INGEST_DELAY_FIELD_NUMBER: _ClassVar[int] - TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_FIELD_NUMBER: _ClassVar[int] - launch_stage: _launch_stage_pb2.LaunchStage - sample_period: _duration_pb2.Duration - ingest_delay: _duration_pb2.Duration - time_series_resource_hierarchy_level: _containers.RepeatedScalarFieldContainer[ - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel - ] - def __init__( - self, - launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., - sample_period: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - ingest_delay: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - time_series_resource_hierarchy_level: _Optional[ - _Iterable[ - _Union[ - MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel, - str, - ] - ] - ] = ..., - ) -> None: ... - - NAME_FIELD_NUMBER: _ClassVar[int] - TYPE_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - METRIC_KIND_FIELD_NUMBER: _ClassVar[int] - VALUE_TYPE_FIELD_NUMBER: _ClassVar[int] - UNIT_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] - METADATA_FIELD_NUMBER: _ClassVar[int] - LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] - MONITORED_RESOURCE_TYPES_FIELD_NUMBER: _ClassVar[int] - name: str - type: str - labels: _containers.RepeatedCompositeFieldContainer[_label_pb2.LabelDescriptor] - metric_kind: MetricDescriptor.MetricKind - value_type: MetricDescriptor.ValueType - unit: str - description: str - display_name: str - metadata: MetricDescriptor.MetricDescriptorMetadata - launch_stage: _launch_stage_pb2.LaunchStage - monitored_resource_types: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - name: _Optional[str] = ..., - type: _Optional[str] = ..., - labels: _Optional[ - _Iterable[_Union[_label_pb2.LabelDescriptor, _Mapping]] - ] = ..., - metric_kind: _Optional[_Union[MetricDescriptor.MetricKind, str]] = ..., - value_type: _Optional[_Union[MetricDescriptor.ValueType, str]] = ..., - unit: _Optional[str] = ..., - description: _Optional[str] = ..., - display_name: _Optional[str] = ..., - metadata: _Optional[ - _Union[MetricDescriptor.MetricDescriptorMetadata, _Mapping] - ] = ..., - launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., - monitored_resource_types: _Optional[_Iterable[str]] = ..., - ) -> None: ... - -class Metric(_message.Message): - __slots__ = ("type", "labels") - class LabelsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - TYPE_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - type: str - labels: _containers.ScalarMap[str, str] - def __init__( - self, type: _Optional[str] = ..., labels: _Optional[_Mapping[str, str]] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto deleted file mode 100644 index eaf1f1280be..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource.proto +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/label.proto"; -import "google/api/launch_stage.proto"; -import "google/protobuf/struct.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/monitoredres;monitoredres"; -option java_multiple_files = true; -option java_outer_classname = "MonitoredResourceProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// An object that describes the schema of a -// [MonitoredResource][google.api.MonitoredResource] object using a type name -// and a set of labels. For example, the monitored resource descriptor for -// Google Compute Engine VM instances has a type of -// `"gce_instance"` and specifies the use of the labels `"instance_id"` and -// `"zone"` to identify particular VM instances. -// -// Different APIs can support different monitored resource types. APIs generally -// provide a `list` method that returns the monitored resource descriptors used -// by the API. -// -message MonitoredResourceDescriptor { - // Optional. The resource name of the monitored resource descriptor: - // `"projects/{project_id}/monitoredResourceDescriptors/{type}"` where - // {type} is the value of the `type` field in this object and - // {project_id} is a project ID that provides API-specific context for - // accessing the type. APIs that do not use project information can use the - // resource name format `"monitoredResourceDescriptors/{type}"`. - string name = 5; - - // Required. The monitored resource type. For example, the type - // `"cloudsql_database"` represents databases in Google Cloud SQL. - // For a list of types, see [Monitored resource - // types](https://cloud.google.com/monitoring/api/resources) - // and [Logging resource - // types](https://cloud.google.com/logging/docs/api/v2/resource-list). - string type = 1; - - // Optional. A concise name for the monitored resource type that might be - // displayed in user interfaces. It should be a Title Cased Noun Phrase, - // without any article or other determiners. For example, - // `"Google Cloud SQL Database"`. - string display_name = 2; - - // Optional. A detailed description of the monitored resource type that might - // be used in documentation. - string description = 3; - - // Required. A set of labels used to describe instances of this monitored - // resource type. For example, an individual Google Cloud SQL database is - // identified by values for the labels `"database_id"` and `"zone"`. - repeated LabelDescriptor labels = 4; - - // Optional. The launch stage of the monitored resource definition. - LaunchStage launch_stage = 7; -} - -// An object representing a resource that can be used for monitoring, logging, -// billing, or other purposes. Examples include virtual machine instances, -// databases, and storage devices such as disks. The `type` field identifies a -// [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] object -// that describes the resource's schema. Information in the `labels` field -// identifies the actual resource and its attributes according to the schema. -// For example, a particular Compute Engine VM instance could be represented by -// the following object, because the -// [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] for -// `"gce_instance"` has labels -// `"project_id"`, `"instance_id"` and `"zone"`: -// -// { "type": "gce_instance", -// "labels": { "project_id": "my-project", -// "instance_id": "12345678901234", -// "zone": "us-central1-a" }} -message MonitoredResource { - // Required. The monitored resource type. This field must match - // the `type` field of a - // [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] - // object. For example, the type of a Compute Engine VM instance is - // `gce_instance`. Some descriptors include the service name in the type; for - // example, the type of a Datastream stream is - // `datastream.googleapis.com/Stream`. - string type = 1; - - // Required. Values for all of the labels listed in the associated monitored - // resource descriptor. For example, Compute Engine VM instances use the - // labels `"project_id"`, `"instance_id"`, and `"zone"`. - map labels = 2; -} - -// Auxiliary metadata for a [MonitoredResource][google.api.MonitoredResource] -// object. [MonitoredResource][google.api.MonitoredResource] objects contain the -// minimum set of information to uniquely identify a monitored resource -// instance. There is some other useful auxiliary metadata. Monitoring and -// Logging use an ingestion pipeline to extract metadata for cloud resources of -// all types, and store the metadata in this message. -message MonitoredResourceMetadata { - // Output only. Values for predefined system metadata labels. - // System labels are a kind of metadata extracted by Google, including - // "machine_image", "vpc", "subnet_id", - // "security_group", "name", etc. - // System label values can be only strings, Boolean values, or a list of - // strings. For example: - // - // { "name": "my-test-instance", - // "security_group": ["a", "b", "c"], - // "spot_instance": false } - google.protobuf.Struct system_labels = 1; - - // Output only. A map of user-defined metadata labels. - map user_labels = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py deleted file mode 100644 index 2268a4cb7d7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/monitored_resource.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/monitored_resource.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 - -from opentelemetry.agent._vendor.google.api import label_pb2 as google_dot_api_dot_label__pb2 -from opentelemetry.agent._vendor.google.api import launch_stage_pb2 as google_dot_api_dot_launch__stage__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n#google/api/monitored_resource.proto\x12\ngoogle.api\x1a\x16google/api/label.proto\x1a\x1dgoogle/api/launch_stage.proto\x1a\x1cgoogle/protobuf/struct.proto"\xc0\x01\n\x1bMonitoredResourceDescriptor\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12+\n\x06labels\x18\x04 \x03(\x0b\x32\x1b.google.api.LabelDescriptor\x12-\n\x0claunch_stage\x18\x07 \x01(\x0e\x32\x17.google.api.LaunchStage"\x8b\x01\n\x11MonitoredResource\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x39\n\x06labels\x18\x02 \x03(\x0b\x32).google.api.MonitoredResource.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01"\xca\x01\n\x19MonitoredResourceMetadata\x12.\n\rsystem_labels\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12J\n\x0buser_labels\x18\x02 \x03(\x0b\x32\x35.google.api.MonitoredResourceMetadata.UserLabelsEntry\x1a\x31\n\x0fUserLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42v\n\x0e\x63om.google.apiB\x16MonitoredResourceProtoP\x01ZCgoogle.golang.org/genproto/googleapis/api/monitoredres;monitoredres\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.monitored_resource_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\026MonitoredResourceProtoP\001ZCgoogle.golang.org/genproto/googleapis/api/monitoredres;monitoredres\242\002\004GAPI" - _globals["_MONITOREDRESOURCE_LABELSENTRY"]._loaded_options = None - _globals["_MONITOREDRESOURCE_LABELSENTRY"]._serialized_options = b"8\001" - _globals["_MONITOREDRESOURCEMETADATA_USERLABELSENTRY"]._loaded_options = None - _globals[ - "_MONITOREDRESOURCEMETADATA_USERLABELSENTRY" - ]._serialized_options = b"8\001" - _globals["_MONITOREDRESOURCEDESCRIPTOR"]._serialized_start = 137 - _globals["_MONITOREDRESOURCEDESCRIPTOR"]._serialized_end = 329 - _globals["_MONITOREDRESOURCE"]._serialized_start = 332 - _globals["_MONITOREDRESOURCE"]._serialized_end = 471 - _globals["_MONITOREDRESOURCE_LABELSENTRY"]._serialized_start = 426 - _globals["_MONITOREDRESOURCE_LABELSENTRY"]._serialized_end = 471 - _globals["_MONITOREDRESOURCEMETADATA"]._serialized_start = 474 - _globals["_MONITOREDRESOURCEMETADATA"]._serialized_end = 676 - _globals["_MONITOREDRESOURCEMETADATA_USERLABELSENTRY"]._serialized_start = 627 - _globals["_MONITOREDRESOURCEMETADATA_USERLABELSENTRY"]._serialized_end = 676 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi deleted file mode 100644 index 5e125018a18..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitored_resource_pb2.pyi +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import struct_pb2 as _struct_pb2 -from google.protobuf.internal import containers as _containers - -from google.api import label_pb2 as _label_pb2 -from google.api import launch_stage_pb2 as _launch_stage_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class MonitoredResourceDescriptor(_message.Message): - __slots__ = ( - "name", - "type", - "display_name", - "description", - "labels", - "launch_stage", - ) - NAME_FIELD_NUMBER: _ClassVar[int] - TYPE_FIELD_NUMBER: _ClassVar[int] - DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - LAUNCH_STAGE_FIELD_NUMBER: _ClassVar[int] - name: str - type: str - display_name: str - description: str - labels: _containers.RepeatedCompositeFieldContainer[_label_pb2.LabelDescriptor] - launch_stage: _launch_stage_pb2.LaunchStage - def __init__( - self, - name: _Optional[str] = ..., - type: _Optional[str] = ..., - display_name: _Optional[str] = ..., - description: _Optional[str] = ..., - labels: _Optional[ - _Iterable[_Union[_label_pb2.LabelDescriptor, _Mapping]] - ] = ..., - launch_stage: _Optional[_Union[_launch_stage_pb2.LaunchStage, str]] = ..., - ) -> None: ... - -class MonitoredResource(_message.Message): - __slots__ = ("type", "labels") - class LabelsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - TYPE_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - type: str - labels: _containers.ScalarMap[str, str] - def __init__( - self, type: _Optional[str] = ..., labels: _Optional[_Mapping[str, str]] = ... - ) -> None: ... - -class MonitoredResourceMetadata(_message.Message): - __slots__ = ("system_labels", "user_labels") - class UserLabelsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - SYSTEM_LABELS_FIELD_NUMBER: _ClassVar[int] - USER_LABELS_FIELD_NUMBER: _ClassVar[int] - system_labels: _struct_pb2.Struct - user_labels: _containers.ScalarMap[str, str] - def __init__( - self, - system_labels: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., - user_labels: _Optional[_Mapping[str, str]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto deleted file mode 100644 index b939a0ca2a5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring.proto +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "MonitoringProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Monitoring configuration of the service. -// -// The example below shows how to configure monitored resources and metrics -// for monitoring. In the example, a monitored resource and two metrics are -// defined. The `library.googleapis.com/book/returned_count` metric is sent -// to both producer and consumer projects, whereas the -// `library.googleapis.com/book/num_overdue` metric is only sent to the -// consumer project. -// -// monitored_resources: -// - type: library.googleapis.com/Branch -// display_name: "Library Branch" -// description: "A branch of a library." -// launch_stage: GA -// labels: -// - key: resource_container -// description: "The Cloud container (ie. project id) for the Branch." -// - key: location -// description: "The location of the library branch." -// - key: branch_id -// description: "The id of the branch." -// metrics: -// - name: library.googleapis.com/book/returned_count -// display_name: "Books Returned" -// description: "The count of books that have been returned." -// launch_stage: GA -// metric_kind: DELTA -// value_type: INT64 -// unit: "1" -// labels: -// - key: customer_id -// description: "The id of the customer." -// - name: library.googleapis.com/book/num_overdue -// display_name: "Books Overdue" -// description: "The current number of overdue books." -// launch_stage: GA -// metric_kind: GAUGE -// value_type: INT64 -// unit: "1" -// labels: -// - key: customer_id -// description: "The id of the customer." -// monitoring: -// producer_destinations: -// - monitored_resource: library.googleapis.com/Branch -// metrics: -// - library.googleapis.com/book/returned_count -// consumer_destinations: -// - monitored_resource: library.googleapis.com/Branch -// metrics: -// - library.googleapis.com/book/returned_count -// - library.googleapis.com/book/num_overdue -message Monitoring { - // Configuration of a specific monitoring destination (the producer project - // or the consumer project). - message MonitoringDestination { - // The monitored resource type. The type must be defined in - // [Service.monitored_resources][google.api.Service.monitored_resources] - // section. - string monitored_resource = 1; - - // Types of the metrics to report to this monitoring destination. - // Each type must be defined in - // [Service.metrics][google.api.Service.metrics] section. - repeated string metrics = 2; - } - - // Monitoring configurations for sending metrics to the producer project. - // There can be multiple producer destinations. A monitored resource type may - // appear in multiple monitoring destinations if different aggregations are - // needed for different sets of metrics associated with that monitored - // resource type. A monitored resource and metric pair may only be used once - // in the Monitoring configuration. - repeated MonitoringDestination producer_destinations = 1; - - // Monitoring configurations for sending metrics to the consumer project. - // There can be multiple consumer destinations. A monitored resource type may - // appear in multiple monitoring destinations if different aggregations are - // needed for different sets of metrics associated with that monitored - // resource type. A monitored resource and metric pair may only be used once - // in the Monitoring configuration. - repeated MonitoringDestination consumer_destinations = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py deleted file mode 100644 index 35ace5a6670..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/monitoring.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/monitoring.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1bgoogle/api/monitoring.proto\x12\ngoogle.api"\xec\x01\n\nMonitoring\x12K\n\x15producer_destinations\x18\x01 \x03(\x0b\x32,.google.api.Monitoring.MonitoringDestination\x12K\n\x15\x63onsumer_destinations\x18\x02 \x03(\x0b\x32,.google.api.Monitoring.MonitoringDestination\x1a\x44\n\x15MonitoringDestination\x12\x1a\n\x12monitored_resource\x18\x01 \x01(\t\x12\x0f\n\x07metrics\x18\x02 \x03(\tBq\n\x0e\x63om.google.apiB\x0fMonitoringProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.monitoring_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\017MonitoringProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_MONITORING"]._serialized_start = 44 - _globals["_MONITORING"]._serialized_end = 280 - _globals["_MONITORING_MONITORINGDESTINATION"]._serialized_start = 212 - _globals["_MONITORING_MONITORINGDESTINATION"]._serialized_end = 280 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi deleted file mode 100644 index b6eade82800..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/monitoring_pb2.pyi +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Monitoring(_message.Message): - __slots__ = ("producer_destinations", "consumer_destinations") - class MonitoringDestination(_message.Message): - __slots__ = ("monitored_resource", "metrics") - MONITORED_RESOURCE_FIELD_NUMBER: _ClassVar[int] - METRICS_FIELD_NUMBER: _ClassVar[int] - monitored_resource: str - metrics: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - monitored_resource: _Optional[str] = ..., - metrics: _Optional[_Iterable[str]] = ..., - ) -> None: ... - - PRODUCER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] - CONSUMER_DESTINATIONS_FIELD_NUMBER: _ClassVar[int] - producer_destinations: _containers.RepeatedCompositeFieldContainer[ - Monitoring.MonitoringDestination - ] - consumer_destinations: _containers.RepeatedCompositeFieldContainer[ - Monitoring.MonitoringDestination - ] - def __init__( - self, - producer_destinations: _Optional[ - _Iterable[_Union[Monitoring.MonitoringDestination, _Mapping]] - ] = ..., - consumer_destinations: _Optional[ - _Iterable[_Union[Monitoring.MonitoringDestination, _Mapping]] - ] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto deleted file mode 100644 index c925fdc4272..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy.proto +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "PolicyProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.FieldOptions { - // See [FieldPolicy][]. - google.api.FieldPolicy field_policy = 158361448; -} - -extend google.protobuf.MethodOptions { - // See [MethodPolicy][]. - google.api.MethodPolicy method_policy = 161893301; -} - -// Google API Policy Annotation -// -// This message defines a simple API policy annotation that can be used to -// annotate API request and response message fields with applicable policies. -// One field may have multiple applicable policies that must all be satisfied -// before a request can be processed. This policy annotation is used to -// generate the overall policy that will be used for automatic runtime -// policy enforcement and documentation generation. -message FieldPolicy { - // Selects one or more request or response message fields to apply this - // `FieldPolicy`. - // - // When a `FieldPolicy` is used in proto annotation, the selector must - // be left as empty. The service config generator will automatically fill - // the correct value. - // - // When a `FieldPolicy` is used in service config, the selector must be a - // comma-separated string with valid request or response field paths, - // such as "foo.bar" or "foo.bar,foo.baz". - string selector = 1; - - // Specifies the required permission(s) for the resource referred to by the - // field. It requires the field contains a valid resource reference, and - // the request must pass the permission checks to proceed. For example, - // "resourcemanager.projects.get". - string resource_permission = 2; - - // Specifies the resource type for the resource referred to by the field. - string resource_type = 3; -} - -// Defines policies applying to an RPC method. -message MethodPolicy { - // Selects a method to which these policies should be enforced, for example, - // "google.pubsub.v1.Subscriber.CreateSubscription". - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - // - // NOTE: This field must not be set in the proto annotation. It will be - // automatically filled by the service config compiler . - string selector = 9; - - // Policies that are applicable to the request message. - repeated FieldPolicy request_policies = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py deleted file mode 100644 index f974f4fa200..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/policy.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/policy.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x17google/api/policy.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"S\n\x0b\x46ieldPolicy\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x1b\n\x13resource_permission\x18\x02 \x01(\t\x12\x15\n\rresource_type\x18\x03 \x01(\t"S\n\x0cMethodPolicy\x12\x10\n\x08selector\x18\t \x01(\t\x12\x31\n\x10request_policies\x18\x02 \x03(\x0b\x32\x17.google.api.FieldPolicy:O\n\x0c\x66ield_policy\x12\x1d.google.protobuf.FieldOptions\x18\xe8\xce\xc1K \x01(\x0b\x32\x17.google.api.FieldPolicy:R\n\rmethod_policy\x12\x1e.google.protobuf.MethodOptions\x18\xb5\x97\x99M \x01(\x0b\x32\x18.google.api.MethodPolicyBm\n\x0e\x63om.google.apiB\x0bPolicyProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.policy_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\013PolicyProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_FIELDPOLICY"]._serialized_start = 73 - _globals["_FIELDPOLICY"]._serialized_end = 156 - _globals["_METHODPOLICY"]._serialized_start = 158 - _globals["_METHODPOLICY"]._serialized_end = 241 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi deleted file mode 100644 index 2c5fe960d98..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/policy_pb2.pyi +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor -FIELD_POLICY_FIELD_NUMBER: _ClassVar[int] -field_policy: _descriptor.FieldDescriptor -METHOD_POLICY_FIELD_NUMBER: _ClassVar[int] -method_policy: _descriptor.FieldDescriptor - -class FieldPolicy(_message.Message): - __slots__ = ("selector", "resource_permission", "resource_type") - SELECTOR_FIELD_NUMBER: _ClassVar[int] - RESOURCE_PERMISSION_FIELD_NUMBER: _ClassVar[int] - RESOURCE_TYPE_FIELD_NUMBER: _ClassVar[int] - selector: str - resource_permission: str - resource_type: str - def __init__( - self, - selector: _Optional[str] = ..., - resource_permission: _Optional[str] = ..., - resource_type: _Optional[str] = ..., - ) -> None: ... - -class MethodPolicy(_message.Message): - __slots__ = ("selector", "request_policies") - SELECTOR_FIELD_NUMBER: _ClassVar[int] - REQUEST_POLICIES_FIELD_NUMBER: _ClassVar[int] - selector: str - request_policies: _containers.RepeatedCompositeFieldContainer[FieldPolicy] - def __init__( - self, - selector: _Optional[str] = ..., - request_policies: _Optional[_Iterable[_Union[FieldPolicy, _Mapping]]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto deleted file mode 100644 index 29ae86ed467..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota.proto +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "QuotaProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Quota configuration helps to achieve fairness and budgeting in service -// usage. -// -// The metric based quota configuration works this way: -// - The service configuration defines a set of metrics. -// - For API calls, the quota.metric_rules maps methods to metrics with -// corresponding costs. -// - The quota.limits defines limits on the metrics, which will be used for -// quota checks at runtime. -// -// An example quota configuration in yaml format: -// -// quota: -// limits: -// -// - name: apiWriteQpsPerProject -// metric: library.googleapis.com/write_calls -// unit: "1/min/{project}" # rate limit for consumer projects -// values: -// STANDARD: 10000 -// -// -// (The metric rules bind all methods to the read_calls metric, -// except for the UpdateBook and DeleteBook methods. These two methods -// are mapped to the write_calls metric, with the UpdateBook method -// consuming at twice rate as the DeleteBook method.) -// metric_rules: -// - selector: "*" -// metric_costs: -// library.googleapis.com/read_calls: 1 -// - selector: google.example.library.v1.LibraryService.UpdateBook -// metric_costs: -// library.googleapis.com/write_calls: 2 -// - selector: google.example.library.v1.LibraryService.DeleteBook -// metric_costs: -// library.googleapis.com/write_calls: 1 -// -// Corresponding Metric definition: -// -// metrics: -// - name: library.googleapis.com/read_calls -// display_name: Read requests -// metric_kind: DELTA -// value_type: INT64 -// -// - name: library.googleapis.com/write_calls -// display_name: Write requests -// metric_kind: DELTA -// value_type: INT64 -// -// -message Quota { - // List of QuotaLimit definitions for the service. - repeated QuotaLimit limits = 3; - - // List of MetricRule definitions, each one mapping a selected method to one - // or more metrics. - repeated MetricRule metric_rules = 4; -} - -// Bind API methods to metrics. Binding a method to a metric causes that -// metric's configured quota behaviors to apply to the method call. -message MetricRule { - // Selects the methods to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // Metrics to update when the selected methods are called, and the associated - // cost applied to each metric. - // - // The key of the map is the metric name, and the values are the amount - // increased for the metric against which the quota limits are defined. - // The value must not be negative. - map metric_costs = 2; -} - -// `QuotaLimit` defines a specific limit that applies over a specified duration -// for a limit type. There can be at most one limit for a duration and limit -// type combination defined within a `QuotaGroup`. -message QuotaLimit { - // Name of the quota limit. - // - // The name must be provided, and it must be unique within the service. The - // name can only include alphanumeric characters as well as '-'. - // - // The maximum length of the limit name is 64 characters. - string name = 6; - - // Optional. User-visible, extended description for this quota limit. - // Should be used only when more context is needed to understand this limit - // than provided by the limit's display name (see: `display_name`). - string description = 2; - - // Default number of tokens that can be consumed during the specified - // duration. This is the number of tokens assigned when a client - // application developer activates the service for his/her project. - // - // Specifying a value of 0 will block all requests. This can be used if you - // are provisioning quota to selected consumers and blocking others. - // Similarly, a value of -1 will indicate an unlimited quota. No other - // negative values are allowed. - // - // Used by group-based quotas only. - int64 default_limit = 3; - - // Maximum number of tokens that can be consumed during the specified - // duration. Client application developers can override the default limit up - // to this maximum. If specified, this value cannot be set to a value less - // than the default limit. If not specified, it is set to the default limit. - // - // To allow clients to apply overrides with no upper bound, set this to -1, - // indicating unlimited maximum quota. - // - // Used by group-based quotas only. - int64 max_limit = 4; - - // Free tier value displayed in the Developers Console for this limit. - // The free tier is the number of tokens that will be subtracted from the - // billed amount when billing is enabled. - // This field can only be set on a limit with duration "1d", in a billable - // group; it is invalid on any other limit. If this field is not set, it - // defaults to 0, indicating that there is no free tier for this service. - // - // Used by group-based quotas only. - int64 free_tier = 7; - - // Duration of this limit in textual notation. Must be "100s" or "1d". - // - // Used by group-based quotas only. - string duration = 5; - - // The name of the metric this quota limit applies to. The quota limits with - // the same metric will be checked together during runtime. The metric must be - // defined within the service config. - string metric = 8; - - // Specify the unit of the quota limit. It uses the same syntax as - // [MetricDescriptor.unit][google.api.MetricDescriptor.unit]. The supported - // unit kinds are determined by the quota backend system. - // - // Here are some examples: - // * "1/min/{project}" for quota per minute per project. - // - // Note: the order of unit components is insignificant. - // The "1" at the beginning is required to follow the metric unit syntax. - string unit = 9; - - // Tiered limit values. You must specify this as a key:value pair, with an - // integer value that is the maximum number of requests allowed for the - // specified unit. Currently only STANDARD is supported. - map values = 10; - - // User-visible display name for this limit. - // Optional. If not set, the UI will provide a default display name based on - // the quota configuration. This field can be used to override the default - // display name generated from the configuration. - string display_name = 12; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py deleted file mode 100644 index 237f7a5cfd7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/quota.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/quota.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x16google/api/quota.proto\x12\ngoogle.api"]\n\x05Quota\x12&\n\x06limits\x18\x03 \x03(\x0b\x32\x16.google.api.QuotaLimit\x12,\n\x0cmetric_rules\x18\x04 \x03(\x0b\x32\x16.google.api.MetricRule"\x91\x01\n\nMetricRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12=\n\x0cmetric_costs\x18\x02 \x03(\x0b\x32\'.google.api.MetricRule.MetricCostsEntry\x1a\x32\n\x10MetricCostsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01"\x95\x02\n\nQuotaLimit\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x15\n\rdefault_limit\x18\x03 \x01(\x03\x12\x11\n\tmax_limit\x18\x04 \x01(\x03\x12\x11\n\tfree_tier\x18\x07 \x01(\x03\x12\x10\n\x08\x64uration\x18\x05 \x01(\t\x12\x0e\n\x06metric\x18\x08 \x01(\t\x12\x0c\n\x04unit\x18\t \x01(\t\x12\x32\n\x06values\x18\n \x03(\x0b\x32".google.api.QuotaLimit.ValuesEntry\x12\x14\n\x0c\x64isplay_name\x18\x0c \x01(\t\x1a-\n\x0bValuesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03:\x02\x38\x01\x42l\n\x0e\x63om.google.apiB\nQuotaProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.quota_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\nQuotaProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_METRICRULE_METRICCOSTSENTRY"]._loaded_options = None - _globals["_METRICRULE_METRICCOSTSENTRY"]._serialized_options = b"8\001" - _globals["_QUOTALIMIT_VALUESENTRY"]._loaded_options = None - _globals["_QUOTALIMIT_VALUESENTRY"]._serialized_options = b"8\001" - _globals["_QUOTA"]._serialized_start = 38 - _globals["_QUOTA"]._serialized_end = 131 - _globals["_METRICRULE"]._serialized_start = 134 - _globals["_METRICRULE"]._serialized_end = 279 - _globals["_METRICRULE_METRICCOSTSENTRY"]._serialized_start = 229 - _globals["_METRICRULE_METRICCOSTSENTRY"]._serialized_end = 279 - _globals["_QUOTALIMIT"]._serialized_start = 282 - _globals["_QUOTALIMIT"]._serialized_end = 559 - _globals["_QUOTALIMIT_VALUESENTRY"]._serialized_start = 514 - _globals["_QUOTALIMIT_VALUESENTRY"]._serialized_end = 559 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi deleted file mode 100644 index 2c70590ab90..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/quota_pb2.pyi +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Quota(_message.Message): - __slots__ = ("limits", "metric_rules") - LIMITS_FIELD_NUMBER: _ClassVar[int] - METRIC_RULES_FIELD_NUMBER: _ClassVar[int] - limits: _containers.RepeatedCompositeFieldContainer[QuotaLimit] - metric_rules: _containers.RepeatedCompositeFieldContainer[MetricRule] - def __init__( - self, - limits: _Optional[_Iterable[_Union[QuotaLimit, _Mapping]]] = ..., - metric_rules: _Optional[_Iterable[_Union[MetricRule, _Mapping]]] = ..., - ) -> None: ... - -class MetricRule(_message.Message): - __slots__ = ("selector", "metric_costs") - class MetricCostsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: int - def __init__( - self, key: _Optional[str] = ..., value: _Optional[int] = ... - ) -> None: ... - - SELECTOR_FIELD_NUMBER: _ClassVar[int] - METRIC_COSTS_FIELD_NUMBER: _ClassVar[int] - selector: str - metric_costs: _containers.ScalarMap[str, int] - def __init__( - self, - selector: _Optional[str] = ..., - metric_costs: _Optional[_Mapping[str, int]] = ..., - ) -> None: ... - -class QuotaLimit(_message.Message): - __slots__ = ( - "name", - "description", - "default_limit", - "max_limit", - "free_tier", - "duration", - "metric", - "unit", - "values", - "display_name", - ) - class ValuesEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: int - def __init__( - self, key: _Optional[str] = ..., value: _Optional[int] = ... - ) -> None: ... - - NAME_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - DEFAULT_LIMIT_FIELD_NUMBER: _ClassVar[int] - MAX_LIMIT_FIELD_NUMBER: _ClassVar[int] - FREE_TIER_FIELD_NUMBER: _ClassVar[int] - DURATION_FIELD_NUMBER: _ClassVar[int] - METRIC_FIELD_NUMBER: _ClassVar[int] - UNIT_FIELD_NUMBER: _ClassVar[int] - VALUES_FIELD_NUMBER: _ClassVar[int] - DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] - name: str - description: str - default_limit: int - max_limit: int - free_tier: int - duration: str - metric: str - unit: str - values: _containers.ScalarMap[str, int] - display_name: str - def __init__( - self, - name: _Optional[str] = ..., - description: _Optional[str] = ..., - default_limit: _Optional[int] = ..., - max_limit: _Optional[int] = ..., - free_tier: _Optional[int] = ..., - duration: _Optional[str] = ..., - metric: _Optional[str] = ..., - unit: _Optional[str] = ..., - values: _Optional[_Mapping[str, int]] = ..., - display_name: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto deleted file mode 100644 index 2a5213bb08a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource.proto +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "ResourceProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.FieldOptions { - // An annotation that describes a resource reference, see - // [ResourceReference][]. - google.api.ResourceReference resource_reference = 1055; -} - -extend google.protobuf.FileOptions { - // An annotation that describes a resource definition without a corresponding - // message; see [ResourceDescriptor][]. - repeated google.api.ResourceDescriptor resource_definition = 1053; -} - -extend google.protobuf.MessageOptions { - // An annotation that describes a resource definition, see - // [ResourceDescriptor][]. - google.api.ResourceDescriptor resource = 1053; -} - -// A simple descriptor of a resource type. -// -// ResourceDescriptor annotates a resource message (either by means of a -// protobuf annotation or use in the service config), and associates the -// resource's schema, the resource type, and the pattern of the resource name. -// -// Example: -// -// message Topic { -// // Indicates this message defines a resource schema. -// // Declares the resource type in the format of {service}/{kind}. -// // For Kubernetes resources, the format is {api group}/{kind}. -// option (google.api.resource) = { -// type: "pubsub.googleapis.com/Topic" -// pattern: "projects/{project}/topics/{topic}" -// }; -// } -// -// The ResourceDescriptor Yaml config will look like: -// -// resources: -// - type: "pubsub.googleapis.com/Topic" -// pattern: "projects/{project}/topics/{topic}" -// -// Sometimes, resources have multiple patterns, typically because they can -// live under multiple parents. -// -// Example: -// -// message LogEntry { -// option (google.api.resource) = { -// type: "logging.googleapis.com/LogEntry" -// pattern: "projects/{project}/logs/{log}" -// pattern: "folders/{folder}/logs/{log}" -// pattern: "organizations/{organization}/logs/{log}" -// pattern: "billingAccounts/{billing_account}/logs/{log}" -// }; -// } -// -// The ResourceDescriptor Yaml config will look like: -// -// resources: -// - type: 'logging.googleapis.com/LogEntry' -// pattern: "projects/{project}/logs/{log}" -// pattern: "folders/{folder}/logs/{log}" -// pattern: "organizations/{organization}/logs/{log}" -// pattern: "billingAccounts/{billing_account}/logs/{log}" -message ResourceDescriptor { - // A description of the historical or future-looking state of the - // resource pattern. - enum History { - // The "unset" value. - HISTORY_UNSPECIFIED = 0; - - // The resource originally had one pattern and launched as such, and - // additional patterns were added later. - ORIGINALLY_SINGLE_PATTERN = 1; - - // The resource has one pattern, but the API owner expects to add more - // later. (This is the inverse of ORIGINALLY_SINGLE_PATTERN, and prevents - // that from being necessary once there are multiple patterns.) - FUTURE_MULTI_PATTERN = 2; - } - - // A flag representing a specific style that a resource claims to conform to. - enum Style { - // The unspecified value. Do not use. - STYLE_UNSPECIFIED = 0; - - // This resource is intended to be "declarative-friendly". - // - // Declarative-friendly resources must be more strictly consistent, and - // setting this to true communicates to tools that this resource should - // adhere to declarative-friendly expectations. - // - // Note: This is used by the API linter (linter.aip.dev) to enable - // additional checks. - DECLARATIVE_FRIENDLY = 1; - } - - // The resource type. It must be in the format of - // {service_name}/{resource_type_kind}. The `resource_type_kind` must be - // singular and must not include version numbers. - // - // Example: `storage.googleapis.com/Bucket` - // - // The value of the resource_type_kind must follow the regular expression - // /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and - // should use PascalCase (UpperCamelCase). The maximum number of - // characters allowed for the `resource_type_kind` is 100. - string type = 1; - - // Optional. The relative resource name pattern associated with this resource - // type. The DNS prefix of the full resource name shouldn't be specified here. - // - // The path pattern must follow the syntax, which aligns with HTTP binding - // syntax: - // - // Template = Segment { "/" Segment } ; - // Segment = LITERAL | Variable ; - // Variable = "{" LITERAL "}" ; - // - // Examples: - // - // - "projects/{project}/topics/{topic}" - // - "projects/{project}/knowledgeBases/{knowledge_base}" - // - // The components in braces correspond to the IDs for each resource in the - // hierarchy. It is expected that, if multiple patterns are provided, - // the same component name (e.g. "project") refers to IDs of the same - // type of resource. - repeated string pattern = 2; - - // Optional. The field on the resource that designates the resource name - // field. If omitted, this is assumed to be "name". - string name_field = 3; - - // Optional. The historical or future-looking state of the resource pattern. - // - // Example: - // - // // The InspectTemplate message originally only supported resource - // // names with organization, and project was added later. - // message InspectTemplate { - // option (google.api.resource) = { - // type: "dlp.googleapis.com/InspectTemplate" - // pattern: - // "organizations/{organization}/inspectTemplates/{inspect_template}" - // pattern: "projects/{project}/inspectTemplates/{inspect_template}" - // history: ORIGINALLY_SINGLE_PATTERN - // }; - // } - History history = 4; - - // The plural name used in the resource name and permission names, such as - // 'projects' for the resource name of 'projects/{project}' and the permission - // name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception - // to this is for Nested Collections that have stuttering names, as defined - // in [AIP-122](https://google.aip.dev/122#nested-collections), where the - // collection ID in the resource name pattern does not necessarily directly - // match the `plural` value. - // - // It is the same concept of the `plural` field in k8s CRD spec - // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ - // - // Note: The plural form is required even for singleton resources. See - // https://aip.dev/156 - string plural = 5; - - // The same concept of the `singular` field in k8s CRD spec - // https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ - // Such as "project" for the `resourcemanager.googleapis.com/Project` type. - string singular = 6; - - // Style flag(s) for this resource. - // These indicate that a resource is expected to conform to a given - // style. See the specific style flags for additional information. - repeated Style style = 10; -} - -// Defines a proto annotation that describes a string field that refers to -// an API resource. -message ResourceReference { - // The resource type that the annotated field references. - // - // Example: - // - // message Subscription { - // string topic = 2 [(google.api.resource_reference) = { - // type: "pubsub.googleapis.com/Topic" - // }]; - // } - // - // Occasionally, a field may reference an arbitrary resource. In this case, - // APIs use the special value * in their resource reference. - // - // Example: - // - // message GetIamPolicyRequest { - // string resource = 2 [(google.api.resource_reference) = { - // type: "*" - // }]; - // } - string type = 1; - - // The resource type of a child collection that the annotated field - // references. This is useful for annotating the `parent` field that - // doesn't have a fixed resource type. - // - // Example: - // - // message ListLogEntriesRequest { - // string parent = 1 [(google.api.resource_reference) = { - // child_type: "logging.googleapis.com/LogEntry" - // }; - // } - string child_type = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py deleted file mode 100644 index a11f17a44ad..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/resource.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/resource.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x19google/api/resource.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"\xee\x02\n\x12ResourceDescriptor\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07pattern\x18\x02 \x03(\t\x12\x12\n\nname_field\x18\x03 \x01(\t\x12\x37\n\x07history\x18\x04 \x01(\x0e\x32&.google.api.ResourceDescriptor.History\x12\x0e\n\x06plural\x18\x05 \x01(\t\x12\x10\n\x08singular\x18\x06 \x01(\t\x12\x33\n\x05style\x18\n \x03(\x0e\x32$.google.api.ResourceDescriptor.Style"[\n\x07History\x12\x17\n\x13HISTORY_UNSPECIFIED\x10\x00\x12\x1d\n\x19ORIGINALLY_SINGLE_PATTERN\x10\x01\x12\x18\n\x14\x46UTURE_MULTI_PATTERN\x10\x02"8\n\x05Style\x12\x15\n\x11STYLE_UNSPECIFIED\x10\x00\x12\x18\n\x14\x44\x45\x43LARATIVE_FRIENDLY\x10\x01"5\n\x11ResourceReference\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x12\n\nchild_type\x18\x02 \x01(\t:Y\n\x12resource_reference\x12\x1d.google.protobuf.FieldOptions\x18\x9f\x08 \x01(\x0b\x32\x1d.google.api.ResourceReference:Z\n\x13resource_definition\x12\x1c.google.protobuf.FileOptions\x18\x9d\x08 \x03(\x0b\x32\x1e.google.api.ResourceDescriptor:R\n\x08resource\x12\x1f.google.protobuf.MessageOptions\x18\x9d\x08 \x01(\x0b\x32\x1e.google.api.ResourceDescriptorBk\n\x0e\x63om.google.apiB\rResourceProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.resource_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\rResourceProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" - _globals["_RESOURCEDESCRIPTOR"]._serialized_start = 76 - _globals["_RESOURCEDESCRIPTOR"]._serialized_end = 442 - _globals["_RESOURCEDESCRIPTOR_HISTORY"]._serialized_start = 293 - _globals["_RESOURCEDESCRIPTOR_HISTORY"]._serialized_end = 384 - _globals["_RESOURCEDESCRIPTOR_STYLE"]._serialized_start = 386 - _globals["_RESOURCEDESCRIPTOR_STYLE"]._serialized_end = 442 - _globals["_RESOURCEREFERENCE"]._serialized_start = 444 - _globals["_RESOURCEREFERENCE"]._serialized_end = 497 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi deleted file mode 100644 index 806682cdb3d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/resource_pb2.pyi +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor -RESOURCE_REFERENCE_FIELD_NUMBER: _ClassVar[int] -resource_reference: _descriptor.FieldDescriptor -RESOURCE_DEFINITION_FIELD_NUMBER: _ClassVar[int] -resource_definition: _descriptor.FieldDescriptor -RESOURCE_FIELD_NUMBER: _ClassVar[int] -resource: _descriptor.FieldDescriptor - -class ResourceDescriptor(_message.Message): - __slots__ = ( - "type", - "pattern", - "name_field", - "history", - "plural", - "singular", - "style", - ) - class History(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - HISTORY_UNSPECIFIED: _ClassVar[ResourceDescriptor.History] - ORIGINALLY_SINGLE_PATTERN: _ClassVar[ResourceDescriptor.History] - FUTURE_MULTI_PATTERN: _ClassVar[ResourceDescriptor.History] - - HISTORY_UNSPECIFIED: ResourceDescriptor.History - ORIGINALLY_SINGLE_PATTERN: ResourceDescriptor.History - FUTURE_MULTI_PATTERN: ResourceDescriptor.History - class Style(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - STYLE_UNSPECIFIED: _ClassVar[ResourceDescriptor.Style] - DECLARATIVE_FRIENDLY: _ClassVar[ResourceDescriptor.Style] - - STYLE_UNSPECIFIED: ResourceDescriptor.Style - DECLARATIVE_FRIENDLY: ResourceDescriptor.Style - TYPE_FIELD_NUMBER: _ClassVar[int] - PATTERN_FIELD_NUMBER: _ClassVar[int] - NAME_FIELD_FIELD_NUMBER: _ClassVar[int] - HISTORY_FIELD_NUMBER: _ClassVar[int] - PLURAL_FIELD_NUMBER: _ClassVar[int] - SINGULAR_FIELD_NUMBER: _ClassVar[int] - STYLE_FIELD_NUMBER: _ClassVar[int] - type: str - pattern: _containers.RepeatedScalarFieldContainer[str] - name_field: str - history: ResourceDescriptor.History - plural: str - singular: str - style: _containers.RepeatedScalarFieldContainer[ResourceDescriptor.Style] - def __init__( - self, - type: _Optional[str] = ..., - pattern: _Optional[_Iterable[str]] = ..., - name_field: _Optional[str] = ..., - history: _Optional[_Union[ResourceDescriptor.History, str]] = ..., - plural: _Optional[str] = ..., - singular: _Optional[str] = ..., - style: _Optional[_Iterable[_Union[ResourceDescriptor.Style, str]]] = ..., - ) -> None: ... - -class ResourceReference(_message.Message): - __slots__ = ("type", "child_type") - TYPE_FIELD_NUMBER: _ClassVar[int] - CHILD_TYPE_FIELD_NUMBER: _ClassVar[int] - type: str - child_type: str - def __init__( - self, type: _Optional[str] = ..., child_type: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto deleted file mode 100644 index 020d32f7b71..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing.proto +++ /dev/null @@ -1,465 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; -option java_multiple_files = true; -option java_outer_classname = "RoutingProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.MethodOptions { - // See RoutingRule. - google.api.RoutingRule routing = 72295729; -} - -// Specifies the routing information that should be sent along with the request -// in the form of routing header. -// **NOTE:** All service configuration rules follow the "last one wins" order. -// -// The examples below will apply to an RPC which has the following request type: -// -// Message Definition: -// -// message Request { -// // The name of the Table -// // Values can be of the following formats: -// // - `projects//tables/
` -// // - `projects//instances//tables/
` -// // - `region//zones//tables/
` -// string table_name = 1; -// -// // This value specifies routing for replication. -// // It can be in the following formats: -// // - `profiles/` -// // - a legacy `profile_id` that can be any string -// string app_profile_id = 2; -// } -// -// Example message: -// -// { -// table_name: projects/proj_foo/instances/instance_bar/table/table_baz, -// app_profile_id: profiles/prof_qux -// } -// -// The routing header consists of one or multiple key-value pairs. The order of -// the key-value pairs is undefined, the order of the `routing_parameters` in -// the `RoutingRule` only matters for the evaluation order of the path -// templates when `field` is the same. See the examples below for more details. -// -// Every key and value in the routing header must be percent-encoded, -// and joined together in the following format: `key1=value1&key2=value2`. -// The examples below skip the percent-encoding for readability. -// -// Example 1 -// -// Extracting a field from the request to put into the routing header -// unchanged, with the key equal to the field name. -// -// annotation: -// -// option (google.api.routing) = { -// // Take the `app_profile_id`. -// routing_parameters { -// field: "app_profile_id" -// } -// }; -// -// result: -// -// x-goog-request-params: app_profile_id=profiles/prof_qux -// -// Example 2 -// -// Extracting a field from the request to put into the routing header -// unchanged, with the key different from the field name. -// -// annotation: -// -// option (google.api.routing) = { -// // Take the `app_profile_id`, but name it `routing_id` in the header. -// routing_parameters { -// field: "app_profile_id" -// path_template: "{routing_id=**}" -// } -// }; -// -// result: -// -// x-goog-request-params: routing_id=profiles/prof_qux -// -// Example 3 -// -// Extracting a field from the request to put into the routing -// header, while matching a path template syntax on the field's value. -// -// NB: it is more useful to send nothing than to send garbage for the purpose -// of dynamic routing, since garbage pollutes cache. Thus the matching. -// -// Sub-example 3a -// -// The field matches the template. -// -// annotation: -// -// option (google.api.routing) = { -// // Take the `table_name`, if it's well-formed (with project-based -// // syntax). -// routing_parameters { -// field: "table_name" -// path_template: "{table_name=projects/*/instances/*/**}" -// } -// }; -// -// result: -// -// x-goog-request-params: -// table_name=projects/proj_foo/instances/instance_bar/table/table_baz -// -// Sub-example 3b -// -// The field does not match the template. -// -// annotation: -// -// option (google.api.routing) = { -// // Take the `table_name`, if it's well-formed (with region-based -// // syntax). -// routing_parameters { -// field: "table_name" -// path_template: "{table_name=regions/*/zones/*/**}" -// } -// }; -// -// result: -// -// -// -// Sub-example 3c -// -// Multiple alternative conflictingly named path templates are -// specified. The one that matches is used to construct the header. -// -// annotation: -// -// option (google.api.routing) = { -// // Take the `table_name`, if it's well-formed, whether -// // using the region- or projects-based syntax. -// -// routing_parameters { -// field: "table_name" -// path_template: "{table_name=regions/*/zones/*/**}" -// } -// routing_parameters { -// field: "table_name" -// path_template: "{table_name=projects/*/instances/*/**}" -// } -// }; -// -// result: -// -// x-goog-request-params: -// table_name=projects/proj_foo/instances/instance_bar/table/table_baz -// -// Example 4 -// -// Extracting a single routing header key-value pair by matching a -// template syntax on (a part of) a single request field. -// -// annotation: -// -// option (google.api.routing) = { -// // Take just the project id from the `table_name` field. -// routing_parameters { -// field: "table_name" -// path_template: "{routing_id=projects/*}/**" -// } -// }; -// -// result: -// -// x-goog-request-params: routing_id=projects/proj_foo -// -// Example 5 -// -// Extracting a single routing header key-value pair by matching -// several conflictingly named path templates on (parts of) a single request -// field. The last template to match "wins" the conflict. -// -// annotation: -// -// option (google.api.routing) = { -// // If the `table_name` does not have instances information, -// // take just the project id for routing. -// // Otherwise take project + instance. -// -// routing_parameters { -// field: "table_name" -// path_template: "{routing_id=projects/*}/**" -// } -// routing_parameters { -// field: "table_name" -// path_template: "{routing_id=projects/*/instances/*}/**" -// } -// }; -// -// result: -// -// x-goog-request-params: -// routing_id=projects/proj_foo/instances/instance_bar -// -// Example 6 -// -// Extracting multiple routing header key-value pairs by matching -// several non-conflicting path templates on (parts of) a single request field. -// -// Sub-example 6a -// -// Make the templates strict, so that if the `table_name` does not -// have an instance information, nothing is sent. -// -// annotation: -// -// option (google.api.routing) = { -// // The routing code needs two keys instead of one composite -// // but works only for the tables with the "project-instance" name -// // syntax. -// -// routing_parameters { -// field: "table_name" -// path_template: "{project_id=projects/*}/instances/*/**" -// } -// routing_parameters { -// field: "table_name" -// path_template: "projects/*/{instance_id=instances/*}/**" -// } -// }; -// -// result: -// -// x-goog-request-params: -// project_id=projects/proj_foo&instance_id=instances/instance_bar -// -// Sub-example 6b -// -// Make the templates loose, so that if the `table_name` does not -// have an instance information, just the project id part is sent. -// -// annotation: -// -// option (google.api.routing) = { -// // The routing code wants two keys instead of one composite -// // but will work with just the `project_id` for tables without -// // an instance in the `table_name`. -// -// routing_parameters { -// field: "table_name" -// path_template: "{project_id=projects/*}/**" -// } -// routing_parameters { -// field: "table_name" -// path_template: "projects/*/{instance_id=instances/*}/**" -// } -// }; -// -// result (is the same as 6a for our example message because it has the instance -// information): -// -// x-goog-request-params: -// project_id=projects/proj_foo&instance_id=instances/instance_bar -// -// Example 7 -// -// Extracting multiple routing header key-value pairs by matching -// several path templates on multiple request fields. -// -// NB: note that here there is no way to specify sending nothing if one of the -// fields does not match its template. E.g. if the `table_name` is in the wrong -// format, the `project_id` will not be sent, but the `routing_id` will be. -// The backend routing code has to be aware of that and be prepared to not -// receive a full complement of keys if it expects multiple. -// -// annotation: -// -// option (google.api.routing) = { -// // The routing needs both `project_id` and `routing_id` -// // (from the `app_profile_id` field) for routing. -// -// routing_parameters { -// field: "table_name" -// path_template: "{project_id=projects/*}/**" -// } -// routing_parameters { -// field: "app_profile_id" -// path_template: "{routing_id=**}" -// } -// }; -// -// result: -// -// x-goog-request-params: -// project_id=projects/proj_foo&routing_id=profiles/prof_qux -// -// Example 8 -// -// Extracting a single routing header key-value pair by matching -// several conflictingly named path templates on several request fields. The -// last template to match "wins" the conflict. -// -// annotation: -// -// option (google.api.routing) = { -// // The `routing_id` can be a project id or a region id depending on -// // the table name format, but only if the `app_profile_id` is not set. -// // If `app_profile_id` is set it should be used instead. -// -// routing_parameters { -// field: "table_name" -// path_template: "{routing_id=projects/*}/**" -// } -// routing_parameters { -// field: "table_name" -// path_template: "{routing_id=regions/*}/**" -// } -// routing_parameters { -// field: "app_profile_id" -// path_template: "{routing_id=**}" -// } -// }; -// -// result: -// -// x-goog-request-params: routing_id=profiles/prof_qux -// -// Example 9 -// -// Bringing it all together. -// -// annotation: -// -// option (google.api.routing) = { -// // For routing both `table_location` and a `routing_id` are needed. -// // -// // table_location can be either an instance id or a region+zone id. -// // -// // For `routing_id`, take the value of `app_profile_id` -// // - If it's in the format `profiles/`, send -// // just the `` part. -// // - If it's any other literal, send it as is. -// // If the `app_profile_id` is empty, and the `table_name` starts with -// // the project_id, send that instead. -// -// routing_parameters { -// field: "table_name" -// path_template: "projects/*/{table_location=instances/*}/tables/*" -// } -// routing_parameters { -// field: "table_name" -// path_template: "{table_location=regions/*/zones/*}/tables/*" -// } -// routing_parameters { -// field: "table_name" -// path_template: "{routing_id=projects/*}/**" -// } -// routing_parameters { -// field: "app_profile_id" -// path_template: "{routing_id=**}" -// } -// routing_parameters { -// field: "app_profile_id" -// path_template: "profiles/{routing_id=*}" -// } -// }; -// -// result: -// -// x-goog-request-params: -// table_location=instances/instance_bar&routing_id=prof_qux -message RoutingRule { - // A collection of Routing Parameter specifications. - // **NOTE:** If multiple Routing Parameters describe the same key - // (via the `path_template` field or via the `field` field when - // `path_template` is not provided), "last one wins" rule - // determines which Parameter gets used. - // See the examples for more details. - repeated RoutingParameter routing_parameters = 2; -} - -// A projection from an input message to the GRPC or REST header. -message RoutingParameter { - // A request field to extract the header key-value pair from. - string field = 1; - - // A pattern matching the key-value field. Optional. - // If not specified, the whole field specified in the `field` field will be - // taken as value, and its name used as key. If specified, it MUST contain - // exactly one named segment (along with any number of unnamed segments) The - // pattern will be matched over the field specified in the `field` field, then - // if the match is successful: - // - the name of the single named segment will be used as a header name, - // - the match value of the segment will be used as a header value; - // if the match is NOT successful, nothing will be sent. - // - // Example: - // - // -- This is a field in the request message - // | that the header value will be extracted from. - // | - // | -- This is the key name in the - // | | routing header. - // V | - // field: "table_name" v - // path_template: "projects/*/{table_location=instances/*}/tables/*" - // ^ ^ - // | | - // In the {} brackets is the pattern that -- | - // specifies what to extract from the | - // field as a value to be sent. | - // | - // The string in the field must match the whole pattern -- - // before brackets, inside brackets, after brackets. - // - // When looking at this specific example, we can see that: - // - A key-value pair with the key `table_location` - // and the value matching `instances/*` should be added - // to the x-goog-request-params routing header. - // - The value is extracted from the request message's `table_name` field - // if it matches the full pattern specified: - // `projects/*/instances/*/tables/*`. - // - // **NB:** If the `path_template` field is not provided, the key name is - // equal to the field name, and the whole field should be sent as a value. - // This makes the pattern for the field and the value functionally equivalent - // to `**`, and the configuration - // - // { - // field: "table_name" - // } - // - // is a functionally equivalent shorthand to: - // - // { - // field: "table_name" - // path_template: "{table_name=**}" - // } - // - // See Example 1 for more details. - string path_template = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py deleted file mode 100644 index 0356b505025..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/routing.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/routing.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x18google/api/routing.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"G\n\x0bRoutingRule\x12\x38\n\x12routing_parameters\x18\x02 \x03(\x0b\x32\x1c.google.api.RoutingParameter"8\n\x10RoutingParameter\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x15\n\rpath_template\x18\x02 \x01(\t:K\n\x07routing\x12\x1e.google.protobuf.MethodOptions\x18\xb1\xca\xbc" \x01(\x0b\x32\x17.google.api.RoutingRuleBj\n\x0e\x63om.google.apiB\x0cRoutingProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.routing_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\014RoutingProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI" - _globals["_ROUTINGRULE"]._serialized_start = 74 - _globals["_ROUTINGRULE"]._serialized_end = 145 - _globals["_ROUTINGPARAMETER"]._serialized_start = 147 - _globals["_ROUTINGPARAMETER"]._serialized_end = 203 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi deleted file mode 100644 index 39fe16e5659..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/routing_pb2.pyi +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor -ROUTING_FIELD_NUMBER: _ClassVar[int] -routing: _descriptor.FieldDescriptor - -class RoutingRule(_message.Message): - __slots__ = ("routing_parameters",) - ROUTING_PARAMETERS_FIELD_NUMBER: _ClassVar[int] - routing_parameters: _containers.RepeatedCompositeFieldContainer[RoutingParameter] - def __init__( - self, - routing_parameters: _Optional[ - _Iterable[_Union[RoutingParameter, _Mapping]] - ] = ..., - ) -> None: ... - -class RoutingParameter(_message.Message): - __slots__ = ("field", "path_template") - FIELD_FIELD_NUMBER: _ClassVar[int] - PATH_TEMPLATE_FIELD_NUMBER: _ClassVar[int] - field: str - path_template: str - def __init__( - self, field: _Optional[str] = ..., path_template: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto deleted file mode 100644 index 9952ca0e8d5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service.proto +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/api/auth.proto"; -import "google/api/backend.proto"; -import "google/api/billing.proto"; -import "google/api/client.proto"; -import "google/api/context.proto"; -import "google/api/control.proto"; -import "google/api/documentation.proto"; -import "google/api/endpoint.proto"; -import "google/api/http.proto"; -import "google/api/log.proto"; -import "google/api/logging.proto"; -import "google/api/metric.proto"; -import "google/api/monitored_resource.proto"; -import "google/api/monitoring.proto"; -import "google/api/quota.proto"; -import "google/api/source_info.proto"; -import "google/api/system_parameter.proto"; -import "google/api/usage.proto"; -import "google/protobuf/api.proto"; -import "google/protobuf/type.proto"; -import "google/protobuf/wrappers.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "ServiceProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// `Service` is the root object of Google API service configuration (service -// config). It describes the basic information about a logical service, -// such as the service name and the user-facing title, and delegates other -// aspects to sub-sections. Each sub-section is either a proto message or a -// repeated proto message that configures a specific aspect, such as auth. -// For more information, see each proto message definition. -// -// Example: -// -// type: google.api.Service -// name: calendar.googleapis.com -// title: Google Calendar API -// apis: -// - name: google.calendar.v3.Calendar -// -// visibility: -// rules: -// - selector: "google.calendar.v3.*" -// restriction: PREVIEW -// backend: -// rules: -// - selector: "google.calendar.v3.*" -// address: calendar.example.com -// -// authentication: -// providers: -// - id: google_calendar_auth -// jwks_uri: https://www.googleapis.com/oauth2/v1/certs -// issuer: https://securetoken.google.com -// rules: -// - selector: "*" -// requirements: -// provider_id: google_calendar_auth -message Service { - // The service name, which is a DNS-like logical identifier for the - // service, such as `calendar.googleapis.com`. The service name - // typically goes through DNS verification to make sure the owner - // of the service also owns the DNS name. - string name = 1; - - // The product title for this service, it is the name displayed in Google - // Cloud Console. - string title = 2; - - // The Google project that owns this service. - string producer_project_id = 22; - - // A unique ID for a specific instance of this message, typically assigned - // by the client for tracking purpose. Must be no longer than 63 characters - // and only lower case letters, digits, '.', '_' and '-' are allowed. If - // empty, the server may choose to generate one instead. - string id = 33; - - // A list of API interfaces exported by this service. Only the `name` field - // of the [google.protobuf.Api][google.protobuf.Api] needs to be provided by - // the configuration author, as the remaining fields will be derived from the - // IDL during the normalization process. It is an error to specify an API - // interface here which cannot be resolved against the associated IDL files. - repeated google.protobuf.Api apis = 3; - - // A list of all proto message types included in this API service. - // Types referenced directly or indirectly by the `apis` are automatically - // included. Messages which are not referenced but shall be included, such as - // types used by the `google.protobuf.Any` type, should be listed here by - // name by the configuration author. Example: - // - // types: - // - name: google.protobuf.Int32 - repeated google.protobuf.Type types = 4; - - // A list of all enum types included in this API service. Enums referenced - // directly or indirectly by the `apis` are automatically included. Enums - // which are not referenced but shall be included should be listed here by - // name by the configuration author. Example: - // - // enums: - // - name: google.someapi.v1.SomeEnum - repeated google.protobuf.Enum enums = 5; - - // Additional API documentation. - Documentation documentation = 6; - - // API backend configuration. - Backend backend = 8; - - // HTTP configuration. - Http http = 9; - - // Quota configuration. - Quota quota = 10; - - // Auth configuration. - Authentication authentication = 11; - - // Context configuration. - Context context = 12; - - // Configuration controlling usage of this service. - Usage usage = 15; - - // Configuration for network endpoints. If this is empty, then an endpoint - // with the same name as the service is automatically generated to service all - // defined APIs. - repeated Endpoint endpoints = 18; - - // Configuration for the service control plane. - Control control = 21; - - // Defines the logs used by this service. - repeated LogDescriptor logs = 23; - - // Defines the metrics used by this service. - repeated MetricDescriptor metrics = 24; - - // Defines the monitored resources used by this service. This is required - // by the `Service.monitoring` and `Service.logging` configurations. - repeated MonitoredResourceDescriptor monitored_resources = 25; - - // Billing configuration. - Billing billing = 26; - - // Logging configuration. - Logging logging = 27; - - // Monitoring configuration. - Monitoring monitoring = 28; - - // System parameter configuration. - SystemParameters system_parameters = 29; - - // Output only. The source information for this configuration if available. - SourceInfo source_info = 37; - - // Settings for [Google Cloud Client - // libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) - // generated from APIs defined as protocol buffers. - Publishing publishing = 45; - - // Obsolete. Do not use. - // - // This field has no semantic meaning. The service config compiler always - // sets this field to `3`. - google.protobuf.UInt32Value config_version = 20; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py deleted file mode 100644 index ac0c1db283c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/service.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/service.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import api_pb2 as google_dot_protobuf_dot_api__pb2 -from opentelemetry.agent._vendor.google.protobuf import type_pb2 as google_dot_protobuf_dot_type__pb2 -from opentelemetry.agent._vendor.google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 - -from opentelemetry.agent._vendor.google.api import auth_pb2 as google_dot_api_dot_auth__pb2 -from opentelemetry.agent._vendor.google.api import backend_pb2 as google_dot_api_dot_backend__pb2 -from opentelemetry.agent._vendor.google.api import billing_pb2 as google_dot_api_dot_billing__pb2 -from opentelemetry.agent._vendor.google.api import client_pb2 as google_dot_api_dot_client__pb2 -from opentelemetry.agent._vendor.google.api import context_pb2 as google_dot_api_dot_context__pb2 -from opentelemetry.agent._vendor.google.api import control_pb2 as google_dot_api_dot_control__pb2 -from opentelemetry.agent._vendor.google.api import documentation_pb2 as google_dot_api_dot_documentation__pb2 -from opentelemetry.agent._vendor.google.api import endpoint_pb2 as google_dot_api_dot_endpoint__pb2 -from opentelemetry.agent._vendor.google.api import http_pb2 as google_dot_api_dot_http__pb2 -from opentelemetry.agent._vendor.google.api import log_pb2 as google_dot_api_dot_log__pb2 -from opentelemetry.agent._vendor.google.api import logging_pb2 as google_dot_api_dot_logging__pb2 -from opentelemetry.agent._vendor.google.api import metric_pb2 as google_dot_api_dot_metric__pb2 -from opentelemetry.agent._vendor.google.api import ( - monitored_resource_pb2 as google_dot_api_dot_monitored__resource__pb2, -) -from opentelemetry.agent._vendor.google.api import monitoring_pb2 as google_dot_api_dot_monitoring__pb2 -from opentelemetry.agent._vendor.google.api import quota_pb2 as google_dot_api_dot_quota__pb2 -from opentelemetry.agent._vendor.google.api import source_info_pb2 as google_dot_api_dot_source__info__pb2 -from opentelemetry.agent._vendor.google.api import system_parameter_pb2 as google_dot_api_dot_system__parameter__pb2 -from opentelemetry.agent._vendor.google.api import usage_pb2 as google_dot_api_dot_usage__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n\x18google/api/service.proto\x12\ngoogle.api\x1a\x15google/api/auth.proto\x1a\x18google/api/backend.proto\x1a\x18google/api/billing.proto\x1a\x17google/api/client.proto\x1a\x18google/api/context.proto\x1a\x18google/api/control.proto\x1a\x1egoogle/api/documentation.proto\x1a\x19google/api/endpoint.proto\x1a\x15google/api/http.proto\x1a\x14google/api/log.proto\x1a\x18google/api/logging.proto\x1a\x17google/api/metric.proto\x1a#google/api/monitored_resource.proto\x1a\x1bgoogle/api/monitoring.proto\x1a\x16google/api/quota.proto\x1a\x1cgoogle/api/source_info.proto\x1a!google/api/system_parameter.proto\x1a\x16google/api/usage.proto\x1a\x19google/protobuf/api.proto\x1a\x1agoogle/protobuf/type.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\x82\x08\n\x07Service\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x1b\n\x13producer_project_id\x18\x16 \x01(\t\x12\n\n\x02id\x18! \x01(\t\x12\"\n\x04\x61pis\x18\x03 \x03(\x0b\x32\x14.google.protobuf.Api\x12$\n\x05types\x18\x04 \x03(\x0b\x32\x15.google.protobuf.Type\x12$\n\x05\x65nums\x18\x05 \x03(\x0b\x32\x15.google.protobuf.Enum\x12\x30\n\rdocumentation\x18\x06 \x01(\x0b\x32\x19.google.api.Documentation\x12$\n\x07\x62\x61\x63kend\x18\x08 \x01(\x0b\x32\x13.google.api.Backend\x12\x1e\n\x04http\x18\t \x01(\x0b\x32\x10.google.api.Http\x12 \n\x05quota\x18\n \x01(\x0b\x32\x11.google.api.Quota\x12\x32\n\x0e\x61uthentication\x18\x0b \x01(\x0b\x32\x1a.google.api.Authentication\x12$\n\x07\x63ontext\x18\x0c \x01(\x0b\x32\x13.google.api.Context\x12 \n\x05usage\x18\x0f \x01(\x0b\x32\x11.google.api.Usage\x12'\n\tendpoints\x18\x12 \x03(\x0b\x32\x14.google.api.Endpoint\x12$\n\x07\x63ontrol\x18\x15 \x01(\x0b\x32\x13.google.api.Control\x12'\n\x04logs\x18\x17 \x03(\x0b\x32\x19.google.api.LogDescriptor\x12-\n\x07metrics\x18\x18 \x03(\x0b\x32\x1c.google.api.MetricDescriptor\x12\x44\n\x13monitored_resources\x18\x19 \x03(\x0b\x32'.google.api.MonitoredResourceDescriptor\x12$\n\x07\x62illing\x18\x1a \x01(\x0b\x32\x13.google.api.Billing\x12$\n\x07logging\x18\x1b \x01(\x0b\x32\x13.google.api.Logging\x12*\n\nmonitoring\x18\x1c \x01(\x0b\x32\x16.google.api.Monitoring\x12\x37\n\x11system_parameters\x18\x1d \x01(\x0b\x32\x1c.google.api.SystemParameters\x12+\n\x0bsource_info\x18% \x01(\x0b\x32\x16.google.api.SourceInfo\x12*\n\npublishing\x18- \x01(\x0b\x32\x16.google.api.Publishing\x12\x34\n\x0e\x63onfig_version\x18\x14 \x01(\x0b\x32\x1c.google.protobuf.UInt32ValueBn\n\x0e\x63om.google.apiB\x0cServiceProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.service_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\014ServiceProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_SERVICE"]._serialized_start = 614 - _globals["_SERVICE"]._serialized_end = 1640 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi deleted file mode 100644 index 93b393abfb7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/service_pb2.pyi +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import api_pb2 as _api_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import type_pb2 as _type_pb2 -from google.protobuf import wrappers_pb2 as _wrappers_pb2 -from google.protobuf.internal import containers as _containers - -from google.api import auth_pb2 as _auth_pb2 -from google.api import backend_pb2 as _backend_pb2 -from google.api import billing_pb2 as _billing_pb2 -from google.api import client_pb2 as _client_pb2 -from google.api import context_pb2 as _context_pb2 -from google.api import control_pb2 as _control_pb2 -from google.api import documentation_pb2 as _documentation_pb2 -from google.api import endpoint_pb2 as _endpoint_pb2 -from google.api import http_pb2 as _http_pb2 -from google.api import log_pb2 as _log_pb2 -from google.api import logging_pb2 as _logging_pb2 -from google.api import metric_pb2 as _metric_pb2 -from google.api import monitored_resource_pb2 as _monitored_resource_pb2 -from google.api import monitoring_pb2 as _monitoring_pb2 -from google.api import quota_pb2 as _quota_pb2 -from google.api import source_info_pb2 as _source_info_pb2 -from google.api import system_parameter_pb2 as _system_parameter_pb2 -from google.api import usage_pb2 as _usage_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class Service(_message.Message): - __slots__ = ( - "name", - "title", - "producer_project_id", - "id", - "apis", - "types", - "enums", - "documentation", - "backend", - "http", - "quota", - "authentication", - "context", - "usage", - "endpoints", - "control", - "logs", - "metrics", - "monitored_resources", - "billing", - "logging", - "monitoring", - "system_parameters", - "source_info", - "publishing", - "config_version", - ) - NAME_FIELD_NUMBER: _ClassVar[int] - TITLE_FIELD_NUMBER: _ClassVar[int] - PRODUCER_PROJECT_ID_FIELD_NUMBER: _ClassVar[int] - ID_FIELD_NUMBER: _ClassVar[int] - APIS_FIELD_NUMBER: _ClassVar[int] - TYPES_FIELD_NUMBER: _ClassVar[int] - ENUMS_FIELD_NUMBER: _ClassVar[int] - DOCUMENTATION_FIELD_NUMBER: _ClassVar[int] - BACKEND_FIELD_NUMBER: _ClassVar[int] - HTTP_FIELD_NUMBER: _ClassVar[int] - QUOTA_FIELD_NUMBER: _ClassVar[int] - AUTHENTICATION_FIELD_NUMBER: _ClassVar[int] - CONTEXT_FIELD_NUMBER: _ClassVar[int] - USAGE_FIELD_NUMBER: _ClassVar[int] - ENDPOINTS_FIELD_NUMBER: _ClassVar[int] - CONTROL_FIELD_NUMBER: _ClassVar[int] - LOGS_FIELD_NUMBER: _ClassVar[int] - METRICS_FIELD_NUMBER: _ClassVar[int] - MONITORED_RESOURCES_FIELD_NUMBER: _ClassVar[int] - BILLING_FIELD_NUMBER: _ClassVar[int] - LOGGING_FIELD_NUMBER: _ClassVar[int] - MONITORING_FIELD_NUMBER: _ClassVar[int] - SYSTEM_PARAMETERS_FIELD_NUMBER: _ClassVar[int] - SOURCE_INFO_FIELD_NUMBER: _ClassVar[int] - PUBLISHING_FIELD_NUMBER: _ClassVar[int] - CONFIG_VERSION_FIELD_NUMBER: _ClassVar[int] - name: str - title: str - producer_project_id: str - id: str - apis: _containers.RepeatedCompositeFieldContainer[_api_pb2.Api] - types: _containers.RepeatedCompositeFieldContainer[_type_pb2.Type] - enums: _containers.RepeatedCompositeFieldContainer[_type_pb2.Enum] - documentation: _documentation_pb2.Documentation - backend: _backend_pb2.Backend - http: _http_pb2.Http - quota: _quota_pb2.Quota - authentication: _auth_pb2.Authentication - context: _context_pb2.Context - usage: _usage_pb2.Usage - endpoints: _containers.RepeatedCompositeFieldContainer[_endpoint_pb2.Endpoint] - control: _control_pb2.Control - logs: _containers.RepeatedCompositeFieldContainer[_log_pb2.LogDescriptor] - metrics: _containers.RepeatedCompositeFieldContainer[_metric_pb2.MetricDescriptor] - monitored_resources: _containers.RepeatedCompositeFieldContainer[ - _monitored_resource_pb2.MonitoredResourceDescriptor - ] - billing: _billing_pb2.Billing - logging: _logging_pb2.Logging - monitoring: _monitoring_pb2.Monitoring - system_parameters: _system_parameter_pb2.SystemParameters - source_info: _source_info_pb2.SourceInfo - publishing: _client_pb2.Publishing - config_version: _wrappers_pb2.UInt32Value - def __init__( - self, - name: _Optional[str] = ..., - title: _Optional[str] = ..., - producer_project_id: _Optional[str] = ..., - id: _Optional[str] = ..., - apis: _Optional[_Iterable[_Union[_api_pb2.Api, _Mapping]]] = ..., - types: _Optional[_Iterable[_Union[_type_pb2.Type, _Mapping]]] = ..., - enums: _Optional[_Iterable[_Union[_type_pb2.Enum, _Mapping]]] = ..., - documentation: _Optional[ - _Union[_documentation_pb2.Documentation, _Mapping] - ] = ..., - backend: _Optional[_Union[_backend_pb2.Backend, _Mapping]] = ..., - http: _Optional[_Union[_http_pb2.Http, _Mapping]] = ..., - quota: _Optional[_Union[_quota_pb2.Quota, _Mapping]] = ..., - authentication: _Optional[_Union[_auth_pb2.Authentication, _Mapping]] = ..., - context: _Optional[_Union[_context_pb2.Context, _Mapping]] = ..., - usage: _Optional[_Union[_usage_pb2.Usage, _Mapping]] = ..., - endpoints: _Optional[_Iterable[_Union[_endpoint_pb2.Endpoint, _Mapping]]] = ..., - control: _Optional[_Union[_control_pb2.Control, _Mapping]] = ..., - logs: _Optional[_Iterable[_Union[_log_pb2.LogDescriptor, _Mapping]]] = ..., - metrics: _Optional[ - _Iterable[_Union[_metric_pb2.MetricDescriptor, _Mapping]] - ] = ..., - monitored_resources: _Optional[ - _Iterable[ - _Union[_monitored_resource_pb2.MonitoredResourceDescriptor, _Mapping] - ] - ] = ..., - billing: _Optional[_Union[_billing_pb2.Billing, _Mapping]] = ..., - logging: _Optional[_Union[_logging_pb2.Logging, _Mapping]] = ..., - monitoring: _Optional[_Union[_monitoring_pb2.Monitoring, _Mapping]] = ..., - system_parameters: _Optional[ - _Union[_system_parameter_pb2.SystemParameters, _Mapping] - ] = ..., - source_info: _Optional[_Union[_source_info_pb2.SourceInfo, _Mapping]] = ..., - publishing: _Optional[_Union[_client_pb2.Publishing, _Mapping]] = ..., - config_version: _Optional[_Union[_wrappers_pb2.UInt32Value, _Mapping]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto deleted file mode 100644 index 1d4094e13d5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info.proto +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/any.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "SourceInfoProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Source information used to create a Service Config -message SourceInfo { - // All files used during config generation. - repeated google.protobuf.Any source_files = 1; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py deleted file mode 100644 index a25eebdf54d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/source_info.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/source_info.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1cgoogle/api/source_info.proto\x12\ngoogle.api\x1a\x19google/protobuf/any.proto"8\n\nSourceInfo\x12*\n\x0csource_files\x18\x01 \x03(\x0b\x32\x14.google.protobuf.AnyBq\n\x0e\x63om.google.apiB\x0fSourceInfoProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.source_info_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\017SourceInfoProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_SOURCEINFO"]._serialized_start = 71 - _globals["_SOURCEINFO"]._serialized_end = 127 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi deleted file mode 100644 index f21bfe427d0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/source_info_pb2.pyi +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import any_pb2 as _any_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class SourceInfo(_message.Message): - __slots__ = ("source_files",) - SOURCE_FILES_FIELD_NUMBER: _ClassVar[int] - source_files: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] - def __init__( - self, source_files: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto deleted file mode 100644 index 5ab1f37e1b6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter.proto +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "SystemParameterProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// ### System parameter configuration -// -// A system parameter is a special kind of parameter defined by the API -// system, not by an individual API. It is typically mapped to an HTTP header -// and/or a URL query parameter. This configuration specifies which methods -// change the names of the system parameters. -message SystemParameters { - // Define system parameters. - // - // The parameters defined here will override the default parameters - // implemented by the system. If this field is missing from the service - // config, default system parameters will be used. Default system parameters - // and names is implementation-dependent. - // - // Example: define api key for all methods - // - // system_parameters - // rules: - // - selector: "*" - // parameters: - // - name: api_key - // url_query_parameter: api_key - // - // - // Example: define 2 api key names for a specific method. - // - // system_parameters - // rules: - // - selector: "/ListShelves" - // parameters: - // - name: api_key - // http_header: Api-Key1 - // - name: api_key - // http_header: Api-Key2 - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated SystemParameterRule rules = 1; -} - -// Define a system parameter rule mapping system parameter definitions to -// methods. -message SystemParameterRule { - // Selects the methods to which this rule applies. Use '*' to indicate all - // methods in all APIs. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // Define parameters. Multiple names may be defined for a parameter. - // For a given method call, only one of them should be used. If multiple - // names are used the behavior is implementation-dependent. - // If none of the specified names are present the behavior is - // parameter-dependent. - repeated SystemParameter parameters = 2; -} - -// Define a parameter's name and location. The parameter may be passed as either -// an HTTP header or a URL query parameter, and if both are passed the behavior -// is implementation-dependent. -message SystemParameter { - // Define the name of the parameter, such as "api_key" . It is case sensitive. - string name = 1; - - // Define the HTTP header name to use for the parameter. It is case - // insensitive. - string http_header = 2; - - // Define the URL query parameter name to use for the parameter. It is case - // sensitive. - string url_query_parameter = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py deleted file mode 100644 index 550fd972fa2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/system_parameter.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/system_parameter.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n!google/api/system_parameter.proto\x12\ngoogle.api"B\n\x10SystemParameters\x12.\n\x05rules\x18\x01 \x03(\x0b\x32\x1f.google.api.SystemParameterRule"X\n\x13SystemParameterRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12/\n\nparameters\x18\x02 \x03(\x0b\x32\x1b.google.api.SystemParameter"Q\n\x0fSystemParameter\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0bhttp_header\x18\x02 \x01(\t\x12\x1b\n\x13url_query_parameter\x18\x03 \x01(\tBv\n\x0e\x63om.google.apiB\x14SystemParameterProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.system_parameter_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\024SystemParameterProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_SYSTEMPARAMETERS"]._serialized_start = 49 - _globals["_SYSTEMPARAMETERS"]._serialized_end = 115 - _globals["_SYSTEMPARAMETERRULE"]._serialized_start = 117 - _globals["_SYSTEMPARAMETERRULE"]._serialized_end = 205 - _globals["_SYSTEMPARAMETER"]._serialized_start = 207 - _globals["_SYSTEMPARAMETER"]._serialized_end = 288 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi deleted file mode 100644 index 14b7b286b96..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/system_parameter_pb2.pyi +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class SystemParameters(_message.Message): - __slots__ = ("rules",) - RULES_FIELD_NUMBER: _ClassVar[int] - rules: _containers.RepeatedCompositeFieldContainer[SystemParameterRule] - def __init__( - self, rules: _Optional[_Iterable[_Union[SystemParameterRule, _Mapping]]] = ... - ) -> None: ... - -class SystemParameterRule(_message.Message): - __slots__ = ("selector", "parameters") - SELECTOR_FIELD_NUMBER: _ClassVar[int] - PARAMETERS_FIELD_NUMBER: _ClassVar[int] - selector: str - parameters: _containers.RepeatedCompositeFieldContainer[SystemParameter] - def __init__( - self, - selector: _Optional[str] = ..., - parameters: _Optional[_Iterable[_Union[SystemParameter, _Mapping]]] = ..., - ) -> None: ... - -class SystemParameter(_message.Message): - __slots__ = ("name", "http_header", "url_query_parameter") - NAME_FIELD_NUMBER: _ClassVar[int] - HTTP_HEADER_FIELD_NUMBER: _ClassVar[int] - URL_QUERY_PARAMETER_FIELD_NUMBER: _ClassVar[int] - name: str - http_header: str - url_query_parameter: str - def __init__( - self, - name: _Optional[str] = ..., - http_header: _Optional[str] = ..., - url_query_parameter: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto deleted file mode 100644 index df1b93b39fd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage.proto +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; -option java_multiple_files = true; -option java_outer_classname = "UsageProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -// Configuration controlling usage of a service. -message Usage { - // Requirements that must be satisfied before a consumer project can use the - // service. Each requirement is of the form /; - // for example 'serviceusage.googleapis.com/billing-enabled'. - // - // For Google APIs, a Terms of Service requirement must be included here. - // Google Cloud APIs must include "serviceusage.googleapis.com/tos/cloud". - // Other Google APIs should include - // "serviceusage.googleapis.com/tos/universal". Additional ToS can be - // included based on the business needs. - repeated string requirements = 1; - - // A list of usage rules that apply to individual API methods. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated UsageRule rules = 6; - - // The full resource name of a channel used for sending notifications to the - // service producer. - // - // Google Service Management currently only supports - // [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) as a notification - // channel. To use Google Cloud Pub/Sub as the channel, this must be the name - // of a Cloud Pub/Sub topic that uses the Cloud Pub/Sub topic name format - // documented in https://cloud.google.com/pubsub/docs/overview. - string producer_notification_channel = 7; -} - -// Usage configuration rules for the service. -message UsageRule { - // Selects the methods to which this rule applies. Use '*' to indicate all - // methods in all APIs. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // Use this rule to configure unregistered calls for the service. Unregistered - // calls are calls that do not contain consumer project identity. - // (Example: calls that do not contain an API key). - // - // WARNING: By default, API methods do not allow unregistered calls, and each - // method call must be identified by a consumer project identity. - bool allow_unregistered_calls = 2; - - // If true, the selected method should skip service control and the control - // plane features, such as quota and billing, will not be available. - // This flag is used by Google Cloud Endpoints to bypass checks for internal - // methods, such as service health check methods. - bool skip_service_control = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py deleted file mode 100644 index c718660a19c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/usage.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/usage.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x16google/api/usage.proto\x12\ngoogle.api"j\n\x05Usage\x12\x14\n\x0crequirements\x18\x01 \x03(\t\x12$\n\x05rules\x18\x06 \x03(\x0b\x32\x15.google.api.UsageRule\x12%\n\x1dproducer_notification_channel\x18\x07 \x01(\t"]\n\tUsageRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12 \n\x18\x61llow_unregistered_calls\x18\x02 \x01(\x08\x12\x1c\n\x14skip_service_control\x18\x03 \x01(\x08\x42l\n\x0e\x63om.google.apiB\nUsageProtoP\x01ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.api.usage_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\nUsageProtoP\001ZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig\242\002\004GAPI" - _globals["_USAGE"]._serialized_start = 38 - _globals["_USAGE"]._serialized_end = 144 - _globals["_USAGERULE"]._serialized_start = 146 - _globals["_USAGERULE"]._serialized_end = 239 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi deleted file mode 100644 index 444b29e10bb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/usage_pb2.pyi +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Usage(_message.Message): - __slots__ = ("requirements", "rules", "producer_notification_channel") - REQUIREMENTS_FIELD_NUMBER: _ClassVar[int] - RULES_FIELD_NUMBER: _ClassVar[int] - PRODUCER_NOTIFICATION_CHANNEL_FIELD_NUMBER: _ClassVar[int] - requirements: _containers.RepeatedScalarFieldContainer[str] - rules: _containers.RepeatedCompositeFieldContainer[UsageRule] - producer_notification_channel: str - def __init__( - self, - requirements: _Optional[_Iterable[str]] = ..., - rules: _Optional[_Iterable[_Union[UsageRule, _Mapping]]] = ..., - producer_notification_channel: _Optional[str] = ..., - ) -> None: ... - -class UsageRule(_message.Message): - __slots__ = ("selector", "allow_unregistered_calls", "skip_service_control") - SELECTOR_FIELD_NUMBER: _ClassVar[int] - ALLOW_UNREGISTERED_CALLS_FIELD_NUMBER: _ClassVar[int] - SKIP_SERVICE_CONTROL_FIELD_NUMBER: _ClassVar[int] - selector: str - allow_unregistered_calls: bool - skip_service_control: bool - def __init__( - self, - selector: _Optional[str] = ..., - allow_unregistered_calls: _Optional[bool] = ..., - skip_service_control: _Optional[bool] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto deleted file mode 100644 index fb5cac6f266..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility.proto +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.api; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/api/visibility;visibility"; -option java_multiple_files = true; -option java_outer_classname = "VisibilityProto"; -option java_package = "com.google.api"; -option objc_class_prefix = "GAPI"; - -extend google.protobuf.EnumOptions { - // See `VisibilityRule`. - google.api.VisibilityRule enum_visibility = 72295727; -} - -extend google.protobuf.EnumValueOptions { - // See `VisibilityRule`. - google.api.VisibilityRule value_visibility = 72295727; -} - -extend google.protobuf.FieldOptions { - // See `VisibilityRule`. - google.api.VisibilityRule field_visibility = 72295727; -} - -extend google.protobuf.MessageOptions { - // See `VisibilityRule`. - google.api.VisibilityRule message_visibility = 72295727; -} - -extend google.protobuf.MethodOptions { - // See `VisibilityRule`. - google.api.VisibilityRule method_visibility = 72295727; -} - -extend google.protobuf.ServiceOptions { - // See `VisibilityRule`. - google.api.VisibilityRule api_visibility = 72295727; -} - -// `Visibility` restricts service consumer's access to service elements, -// such as whether an application can call a visibility-restricted method. -// The restriction is expressed by applying visibility labels on service -// elements. The visibility labels are elsewhere linked to service consumers. -// -// A service can define multiple visibility labels, but a service consumer -// should be granted at most one visibility label. Multiple visibility -// labels for a single service consumer are not supported. -// -// If an element and all its parents have no visibility label, its visibility -// is unconditionally granted. -// -// Example: -// -// visibility: -// rules: -// - selector: google.calendar.Calendar.EnhancedSearch -// restriction: PREVIEW -// - selector: google.calendar.Calendar.Delegate -// restriction: INTERNAL -// -// Here, all methods are publicly visible except for the restricted methods -// EnhancedSearch and Delegate. -message Visibility { - // A list of visibility rules that apply to individual API elements. - // - // **NOTE:** All service configuration rules follow "last one wins" order. - repeated VisibilityRule rules = 1; -} - -// A visibility rule provides visibility configuration for an individual API -// element. -message VisibilityRule { - // Selects methods, messages, fields, enums, etc. to which this rule applies. - // - // Refer to [selector][google.api.DocumentationRule.selector] for syntax - // details. - string selector = 1; - - // A comma-separated list of visibility labels that apply to the `selector`. - // Any of the listed labels can be used to grant the visibility. - // - // If a rule has multiple labels, removing one of the labels but not all of - // them can break clients. - // - // Example: - // - // visibility: - // rules: - // - selector: google.calendar.Calendar.EnhancedSearch - // restriction: INTERNAL, PREVIEW - // - // Removing INTERNAL from this restriction will break clients that rely on - // this method and only had access to it through INTERNAL. - string restriction = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py deleted file mode 100644 index 317306612cf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/api/visibility.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/api/visibility.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1bgoogle/api/visibility.proto\x12\ngoogle.api\x1a google/protobuf/descriptor.proto"7\n\nVisibility\x12)\n\x05rules\x18\x01 \x03(\x0b\x32\x1a.google.api.VisibilityRule"7\n\x0eVisibilityRule\x12\x10\n\x08selector\x18\x01 \x01(\t\x12\x13\n\x0brestriction\x18\x02 \x01(\t:T\n\x0f\x65num_visibility\x12\x1c.google.protobuf.EnumOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:Z\n\x10value_visibility\x12!.google.protobuf.EnumValueOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:V\n\x10\x66ield_visibility\x12\x1d.google.protobuf.FieldOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:Z\n\x12message_visibility\x12\x1f.google.protobuf.MessageOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:X\n\x11method_visibility\x12\x1e.google.protobuf.MethodOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRule:V\n\x0e\x61pi_visibility\x12\x1f.google.protobuf.ServiceOptions\x18\xaf\xca\xbc" \x01(\x0b\x32\x1a.google.api.VisibilityRuleBk\n\x0e\x63om.google.apiB\x0fVisibilityProtoP\x01Z?google.golang.org/genproto/googleapis/api/visibility;visibility\xa2\x02\x04GAPIb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.api.visibility_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.apiB\017VisibilityProtoP\001Z?google.golang.org/genproto/googleapis/api/visibility;visibility\242\002\004GAPI" - _globals["_VISIBILITY"]._serialized_start = 77 - _globals["_VISIBILITY"]._serialized_end = 132 - _globals["_VISIBILITYRULE"]._serialized_start = 134 - _globals["_VISIBILITYRULE"]._serialized_end = 189 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi deleted file mode 100644 index c4d32773bd7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/api/visibility_pb2.pyi +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor -ENUM_VISIBILITY_FIELD_NUMBER: _ClassVar[int] -enum_visibility: _descriptor.FieldDescriptor -VALUE_VISIBILITY_FIELD_NUMBER: _ClassVar[int] -value_visibility: _descriptor.FieldDescriptor -FIELD_VISIBILITY_FIELD_NUMBER: _ClassVar[int] -field_visibility: _descriptor.FieldDescriptor -MESSAGE_VISIBILITY_FIELD_NUMBER: _ClassVar[int] -message_visibility: _descriptor.FieldDescriptor -METHOD_VISIBILITY_FIELD_NUMBER: _ClassVar[int] -method_visibility: _descriptor.FieldDescriptor -API_VISIBILITY_FIELD_NUMBER: _ClassVar[int] -api_visibility: _descriptor.FieldDescriptor - -class Visibility(_message.Message): - __slots__ = ("rules",) - RULES_FIELD_NUMBER: _ClassVar[int] - rules: _containers.RepeatedCompositeFieldContainer[VisibilityRule] - def __init__( - self, rules: _Optional[_Iterable[_Union[VisibilityRule, _Mapping]]] = ... - ) -> None: ... - -class VisibilityRule(_message.Message): - __slots__ = ("selector", "restriction") - SELECTOR_FIELD_NUMBER: _ClassVar[int] - RESTRICTION_FIELD_NUMBER: _ClassVar[int] - selector: str - restriction: str - def __init__( - self, selector: _Optional[str] = ..., restriction: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto deleted file mode 100644 index cd44c547460..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources.proto +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file contains stub messages for common resources in GCP. -// It is not intended to be directly generated, and is instead used by -// other tooling to be able to match common resource patterns. -syntax = "proto3"; - -package google.cloud; - -import "google/api/resource.proto"; - - -option (google.api.resource_definition) = { - type: "cloudresourcemanager.googleapis.com/Project" - pattern: "projects/{project}" -}; - - -option (google.api.resource_definition) = { - type: "cloudresourcemanager.googleapis.com/Organization" - pattern: "organizations/{organization}" -}; - - -option (google.api.resource_definition) = { - type: "cloudresourcemanager.googleapis.com/Folder" - pattern: "folders/{folder}" -}; - - -option (google.api.resource_definition) = { - type: "cloudbilling.googleapis.com/BillingAccount" - pattern: "billingAccounts/{billing_account}" -}; - -option (google.api.resource_definition) = { - type: "locations.googleapis.com/Location" - pattern: "projects/{project}/locations/{location}" -}; - diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py deleted file mode 100644 index fdae0c85efa..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/cloud/common_resources.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/cloud/common_resources.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.api import resource_pb2 as google_dot_api_dot_resource__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n#google/cloud/common_resources.proto\x12\x0cgoogle.cloud\x1a\x19google/api/resource.protoB\xf9\x02\xea\x41\x41\n+cloudresourcemanager.googleapis.com/Project\x12\x12projects/{project}\xea\x41P\n0cloudresourcemanager.googleapis.com/Organization\x12\x1corganizations/{organization}\xea\x41>\n*cloudresourcemanager.googleapis.com/Folder\x12\x10\x66olders/{folder}\xea\x41O\n*cloudbilling.googleapis.com/BillingAccount\x12!billingAccounts/{billing_account}\xea\x41L\n!locations.googleapis.com/Location\x12'projects/{project}/locations/{location}b\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.cloud.common_resources_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\352AA\n+cloudresourcemanager.googleapis.com/Project\022\022projects/{project}\352AP\n0cloudresourcemanager.googleapis.com/Organization\022\034organizations/{organization}\352A>\n*cloudresourcemanager.googleapis.com/Folder\022\020folders/{folder}\352AO\n*cloudbilling.googleapis.com/BillingAccount\022!billingAccounts/{billing_account}\352AL\n!locations.googleapis.com/Location\022'projects/{project}/locations/{location}" -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi deleted file mode 100644 index 524a461dc1f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/common_resources_pb2.pyi +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor - -from google.api import resource_pb2 as _resource_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto deleted file mode 100644 index 69f44ddac85..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations.proto +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file contains custom annotations that are used by GAPIC generators to -// handle Long Running Operation methods (LRO) that are NOT compliant with -// https://google.aip.dev/151. These annotations are public for technical -// reasons only. Please DO NOT USE them in your protos. -syntax = "proto3"; - -package google.cloud; - -import "google/protobuf/descriptor.proto"; - -option go_package = "google.golang.org/genproto/googleapis/cloud/extendedops;extendedops"; -option java_multiple_files = true; -option java_outer_classname = "ExtendedOperationsProto"; -option java_package = "com.google.cloud"; -option objc_class_prefix = "GAPI"; - -// FieldOptions to match corresponding fields in the initial request, -// polling request and operation response messages. -// -// Example: -// -// In an API-specific operation message: -// -// message MyOperation { -// string http_error_message = 1 [(operation_field) = ERROR_MESSAGE]; -// int32 http_error_status_code = 2 [(operation_field) = ERROR_CODE]; -// string id = 3 [(operation_field) = NAME]; -// Status status = 4 [(operation_field) = STATUS]; -// } -// -// In a polling request message (the one which is used to poll for an LRO -// status): -// -// message MyPollingRequest { -// string operation = 1 [(operation_response_field) = "id"]; -// string project = 2; -// string region = 3; -// } -// -// In an initial request message (the one which starts an LRO): -// -// message MyInitialRequest { -// string my_project = 2 [(operation_request_field) = "project"]; -// string my_region = 3 [(operation_request_field) = "region"]; -// } -// -extend google.protobuf.FieldOptions { - // A field annotation that maps fields in an API-specific Operation object to - // their standard counterparts in google.longrunning.Operation. See - // OperationResponseMapping enum definition. - OperationResponseMapping operation_field = 1149; - - // A field annotation that maps fields in the initial request message - // (the one which started the LRO) to their counterparts in the polling - // request message. For non-standard LRO, the polling response may be missing - // some of the information needed to make a subsequent polling request. The - // missing information (for example, project or region ID) is contained in the - // fields of the initial request message that this annotation must be applied - // to. The string value of the annotation corresponds to the name of the - // counterpart field in the polling request message that the annotated field's - // value will be copied to. - string operation_request_field = 1150; - - // A field annotation that maps fields in the polling request message to their - // counterparts in the initial and/or polling response message. The initial - // and the polling methods return an API-specific Operation object. Some of - // the fields from that response object must be reused in the subsequent - // request (like operation name/ID) to fully identify the polled operation. - // This annotation must be applied to the fields in the polling request - // message, the string value of the annotation must correspond to the name of - // the counterpart field in the Operation response object whose value will be - // copied to the annotated field. - string operation_response_field = 1151; -} - -// MethodOptions to identify the actual service and method used for operation -// status polling. -// -// Example: -// -// In a method, which starts an LRO: -// -// service MyService { -// rpc Foo(MyInitialRequest) returns (MyOperation) { -// option (operation_service) = "MyPollingService"; -// } -// } -// -// In a polling method: -// -// service MyPollingService { -// rpc Get(MyPollingRequest) returns (MyOperation) { -// option (operation_polling_method) = true; -// } -// } -extend google.protobuf.MethodOptions { - // A method annotation that maps an LRO method (the one which starts an LRO) - // to the service, which will be used to poll for the operation status. The - // annotation must be applied to the method which starts an LRO, the string - // value of the annotation must correspond to the name of the service used to - // poll for the operation status. - string operation_service = 1249; - - // A method annotation that marks methods that can be used for polling - // operation status (e.g. the MyPollingService.Get(MyPollingRequest) method). - bool operation_polling_method = 1250; -} - -// An enum to be used to mark the essential (for polling) fields in an -// API-specific Operation object. A custom Operation object may contain many -// different fields, but only few of them are essential to conduct a successful -// polling process. -enum OperationResponseMapping { - // Do not use. - UNDEFINED = 0; - - // A field in an API-specific (custom) Operation object which carries the same - // meaning as google.longrunning.Operation.name. - NAME = 1; - - // A field in an API-specific (custom) Operation object which carries the same - // meaning as google.longrunning.Operation.done. If the annotated field is of - // an enum type, `annotated_field_name == EnumType.DONE` semantics should be - // equivalent to `Operation.done == true`. If the annotated field is of type - // boolean, then it should follow the same semantics as Operation.done. - // Otherwise, a non-empty value should be treated as `Operation.done == true`. - STATUS = 2; - - // A field in an API-specific (custom) Operation object which carries the same - // meaning as google.longrunning.Operation.error.code. - ERROR_CODE = 3; - - // A field in an API-specific (custom) Operation object which carries the same - // meaning as google.longrunning.Operation.error.message. - ERROR_MESSAGE = 4; -} \ No newline at end of file diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py deleted file mode 100644 index bf2c7eb3fa8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/cloud/extended_operations.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 33, - 5, - "", - "google/cloud/extended_operations.proto", -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n&google/cloud/extended_operations.proto\x12\x0cgoogle.cloud\x1a google/protobuf/descriptor.proto*b\n\x18OperationResponseMapping\x12\r\n\tUNDEFINED\x10\x00\x12\x08\n\x04NAME\x10\x01\x12\n\n\x06STATUS\x10\x02\x12\x0e\n\nERROR_CODE\x10\x03\x12\x11\n\rERROR_MESSAGE\x10\x04:_\n\x0foperation_field\x12\x1d.google.protobuf.FieldOptions\x18\xfd\x08 \x01(\x0e\x32&.google.cloud.OperationResponseMapping:?\n\x17operation_request_field\x12\x1d.google.protobuf.FieldOptions\x18\xfe\x08 \x01(\t:@\n\x18operation_response_field\x12\x1d.google.protobuf.FieldOptions\x18\xff\x08 \x01(\t::\n\x11operation_service\x12\x1e.google.protobuf.MethodOptions\x18\xe1\t \x01(\t:A\n\x18operation_polling_method\x12\x1e.google.protobuf.MethodOptions\x18\xe2\t \x01(\x08\x42y\n\x10\x63om.google.cloudB\x17\x45xtendedOperationsProtoP\x01ZCgoogle.golang.org/genproto/googleapis/cloud/extendedops;extendedops\xa2\x02\x04GAPIb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.cloud.extended_operations_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\020com.google.cloudB\027ExtendedOperationsProtoP\001ZCgoogle.golang.org/genproto/googleapis/cloud/extendedops;extendedops\242\002\004GAPI" - _globals["_OPERATIONRESPONSEMAPPING"]._serialized_start = 90 - _globals["_OPERATIONRESPONSEMAPPING"]._serialized_end = 188 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi deleted file mode 100644 index 8f29d450773..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/extended_operations_pb2.pyi +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class OperationResponseMapping(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - UNDEFINED: _ClassVar[OperationResponseMapping] - NAME: _ClassVar[OperationResponseMapping] - STATUS: _ClassVar[OperationResponseMapping] - ERROR_CODE: _ClassVar[OperationResponseMapping] - ERROR_MESSAGE: _ClassVar[OperationResponseMapping] - -UNDEFINED: OperationResponseMapping -NAME: OperationResponseMapping -STATUS: OperationResponseMapping -ERROR_CODE: OperationResponseMapping -ERROR_MESSAGE: OperationResponseMapping -OPERATION_FIELD_FIELD_NUMBER: _ClassVar[int] -operation_field: _descriptor.FieldDescriptor -OPERATION_REQUEST_FIELD_FIELD_NUMBER: _ClassVar[int] -operation_request_field: _descriptor.FieldDescriptor -OPERATION_RESPONSE_FIELD_FIELD_NUMBER: _ClassVar[int] -operation_response_field: _descriptor.FieldDescriptor -OPERATION_SERVICE_FIELD_NUMBER: _ClassVar[int] -operation_service: _descriptor.FieldDescriptor -OPERATION_POLLING_METHOD_FIELD_NUMBER: _ClassVar[int] -operation_polling_method: _descriptor.FieldDescriptor diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto deleted file mode 100644 index 36a0b0e89dd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations.proto +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.cloud.location; - -import "google/api/annotations.proto"; -import "google/protobuf/any.proto"; -import "google/api/client.proto"; - -option cc_enable_arenas = true; -option go_package = "google.golang.org/genproto/googleapis/cloud/location;location"; -option java_multiple_files = true; -option java_outer_classname = "LocationsProto"; -option java_package = "com.google.cloud.location"; - -// An abstract interface that provides location-related information for -// a service. Service-specific metadata is provided through the -// [Location.metadata][google.cloud.location.Location.metadata] field. -service Locations { - option (google.api.default_host) = "cloud.googleapis.com"; - option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; - - // Lists information about the supported locations for this service. - rpc ListLocations(ListLocationsRequest) returns (ListLocationsResponse) { - option (google.api.http) = { - get: "/v1/{name=locations}" - additional_bindings { - get: "/v1/{name=projects/*}/locations" - } - }; - } - - // Gets information about a location. - rpc GetLocation(GetLocationRequest) returns (Location) { - option (google.api.http) = { - get: "/v1/{name=locations/*}" - additional_bindings { - get: "/v1/{name=projects/*/locations/*}" - } - }; - } -} - -// The request message for [Locations.ListLocations][google.cloud.location.Locations.ListLocations]. -message ListLocationsRequest { - // The resource that owns the locations collection, if applicable. - string name = 1; - - // The standard list filter. - string filter = 2; - - // The standard list page size. - int32 page_size = 3; - - // The standard list page token. - string page_token = 4; -} - -// The response message for [Locations.ListLocations][google.cloud.location.Locations.ListLocations]. -message ListLocationsResponse { - // A list of locations that matches the specified filter in the request. - repeated Location locations = 1; - - // The standard List next-page token. - string next_page_token = 2; -} - -// The request message for [Locations.GetLocation][google.cloud.location.Locations.GetLocation]. -message GetLocationRequest { - // Resource name for the location. - string name = 1; -} - -// A resource that represents Google Cloud Platform location. -message Location { - // Resource name for the location, which may vary between implementations. - // For example: `"projects/example-project/locations/us-east1"` - string name = 1; - - // The canonical id for this location. For example: `"us-east1"`. - string location_id = 4; - - // The friendly name for this location, typically a nearby city name. - // For example, "Tokyo". - string display_name = 5; - - // Cross-service attributes for the location. For example - // - // {"cloud.googleapis.com/region": "us-east1"} - map labels = 2; - - // Service-specific metadata. For example the available capacity at the given - // location. - google.protobuf.Any metadata = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py deleted file mode 100644 index b7de50539ba..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/cloud/location/locations.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 33, - 5, - "", - "google/cloud/location/locations.proto", -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 - -from opentelemetry.agent._vendor.google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -from opentelemetry.agent._vendor.google.api import client_pb2 as google_dot_api_dot_client__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n%google/cloud/location/locations.proto\x12\x15google.cloud.location\x1a\x1cgoogle/api/annotations.proto\x1a\x19google/protobuf/any.proto\x1a\x17google/api/client.proto"[\n\x14ListLocationsRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\x12\x11\n\tpage_size\x18\x03 \x01(\x05\x12\x12\n\npage_token\x18\x04 \x01(\t"d\n\x15ListLocationsResponse\x12\x32\n\tlocations\x18\x01 \x03(\x0b\x32\x1f.google.cloud.location.Location\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t""\n\x12GetLocationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"\xd7\x01\n\x08Location\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0blocation_id\x18\x04 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x05 \x01(\t\x12;\n\x06labels\x18\x02 \x03(\x0b\x32+.google.cloud.location.Location.LabelsEntry\x12&\n\x08metadata\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x32\xa4\x03\n\tLocations\x12\xab\x01\n\rListLocations\x12+.google.cloud.location.ListLocationsRequest\x1a,.google.cloud.location.ListLocationsResponse"?\x82\xd3\xe4\x93\x02\x39\x12\x14/v1/{name=locations}Z!\x12\x1f/v1/{name=projects/*}/locations\x12\x9e\x01\n\x0bGetLocation\x12).google.cloud.location.GetLocationRequest\x1a\x1f.google.cloud.location.Location"C\x82\xd3\xe4\x93\x02=\x12\x16/v1/{name=locations/*}Z#\x12!/v1/{name=projects/*/locations/*}\x1aH\xca\x41\x14\x63loud.googleapis.com\xd2\x41.https://www.googleapis.com/auth/cloud-platformBo\n\x19\x63om.google.cloud.locationB\x0eLocationsProtoP\x01Z=google.golang.org/genproto/googleapis/cloud/location;location\xf8\x01\x01\x62\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.cloud.location.locations_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\031com.google.cloud.locationB\016LocationsProtoP\001Z=google.golang.org/genproto/googleapis/cloud/location;location\370\001\001" - _globals["_LOCATION_LABELSENTRY"]._loaded_options = None - _globals["_LOCATION_LABELSENTRY"]._serialized_options = b"8\001" - _globals["_LOCATIONS"]._loaded_options = None - _globals[ - "_LOCATIONS" - ]._serialized_options = b"\312A\024cloud.googleapis.com\322A.https://www.googleapis.com/auth/cloud-platform" - _globals["_LOCATIONS"].methods_by_name["ListLocations"]._loaded_options = None - _globals["_LOCATIONS"].methods_by_name[ - "ListLocations" - ]._serialized_options = b"\202\323\344\223\0029\022\024/v1/{name=locations}Z!\022\037/v1/{name=projects/*}/locations" - _globals["_LOCATIONS"].methods_by_name["GetLocation"]._loaded_options = None - _globals["_LOCATIONS"].methods_by_name[ - "GetLocation" - ]._serialized_options = b"\202\323\344\223\002=\022\026/v1/{name=locations/*}Z#\022!/v1/{name=projects/*/locations/*}" - _globals["_LISTLOCATIONSREQUEST"]._serialized_start = 146 - _globals["_LISTLOCATIONSREQUEST"]._serialized_end = 237 - _globals["_LISTLOCATIONSRESPONSE"]._serialized_start = 239 - _globals["_LISTLOCATIONSRESPONSE"]._serialized_end = 339 - _globals["_GETLOCATIONREQUEST"]._serialized_start = 341 - _globals["_GETLOCATIONREQUEST"]._serialized_end = 375 - _globals["_LOCATION"]._serialized_start = 378 - _globals["_LOCATION"]._serialized_end = 593 - _globals["_LOCATION_LABELSENTRY"]._serialized_start = 548 - _globals["_LOCATION_LABELSENTRY"]._serialized_end = 593 - _globals["_LOCATIONS"]._serialized_start = 596 - _globals["_LOCATIONS"]._serialized_end = 1016 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi deleted file mode 100644 index 7454a9da707..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/cloud/location/locations_pb2.pyi +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import any_pb2 as _any_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -from google.api import annotations_pb2 as _annotations_pb2 -from google.api import client_pb2 as _client_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class ListLocationsRequest(_message.Message): - __slots__ = ("name", "filter", "page_size", "page_token") - NAME_FIELD_NUMBER: _ClassVar[int] - FILTER_FIELD_NUMBER: _ClassVar[int] - PAGE_SIZE_FIELD_NUMBER: _ClassVar[int] - PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] - name: str - filter: str - page_size: int - page_token: str - def __init__( - self, - name: _Optional[str] = ..., - filter: _Optional[str] = ..., - page_size: _Optional[int] = ..., - page_token: _Optional[str] = ..., - ) -> None: ... - -class ListLocationsResponse(_message.Message): - __slots__ = ("locations", "next_page_token") - LOCATIONS_FIELD_NUMBER: _ClassVar[int] - NEXT_PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] - locations: _containers.RepeatedCompositeFieldContainer[Location] - next_page_token: str - def __init__( - self, - locations: _Optional[_Iterable[_Union[Location, _Mapping]]] = ..., - next_page_token: _Optional[str] = ..., - ) -> None: ... - -class GetLocationRequest(_message.Message): - __slots__ = ("name",) - NAME_FIELD_NUMBER: _ClassVar[int] - name: str - def __init__(self, name: _Optional[str] = ...) -> None: ... - -class Location(_message.Message): - __slots__ = ("name", "location_id", "display_name", "labels", "metadata") - class LabelsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - NAME_FIELD_NUMBER: _ClassVar[int] - LOCATION_ID_FIELD_NUMBER: _ClassVar[int] - DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - METADATA_FIELD_NUMBER: _ClassVar[int] - name: str - location_id: str - display_name: str - labels: _containers.ScalarMap[str, str] - metadata: _any_pb2.Any - def __init__( - self, - name: _Optional[str] = ..., - location_id: _Optional[str] = ..., - display_name: _Optional[str] = ..., - labels: _Optional[_Mapping[str, str]] = ..., - metadata: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto deleted file mode 100644 index 0f2855c15a6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata.proto +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2020 Google LLC. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -syntax = "proto3"; - -package google.gapic.metadata; - -option csharp_namespace = "Google.Gapic.Metadata"; -option go_package = "google.golang.org/genproto/googleapis/gapic/metadata;metadata"; -option java_multiple_files = true; -option java_outer_classname = "GapicMetadataProto"; -option java_package = "com.google.gapic.metadata"; -option php_namespace = "Google\\Gapic\\Metadata"; -option ruby_package = "Google::Gapic::Metadata"; - -// Metadata about a GAPIC library service for a specific combination of API, -// version, and computer language. -message GapicMetadata { - // Schema version of this proto. Current value: 1.0 - string schema = 1; - - // Any human-readable comments to be included in this file. - string comment = 2; - - // Computer language of this generated language. This must be - // spelled out as it spoken in English, with no capitalization or - // separators (e.g. "csharp", "nodejs"). - string language = 3; - - // The proto package containing the API definition for which this - // GAPIC library was generated. - string proto_package = 4; - - // The language-specific library package for this GAPIC library. - string library_package = 5; - - // A map from each proto-defined service to ServiceForTransports, - // which allows listing information about transport-specific - // implementations of the service. - // - // The key is the name of the service as it appears in the .proto - // file. - map services = 6; - - // A map from a transport name to ServiceAsClient, which allows - // listing information about the client objects that implement the - // parent RPC service for the specified transport. - message ServiceForTransport { - // Map of transport name to ServiceAsClient. The key name is the transport, - // lower-cased with no separators (e.g. "grpc", "rest"). - map clients = 1; - - // The API version for the interface definition found in the - // `google.api.api_version` annotation of this proto-defined service during - // code generation. - // This is the value populated by the client in the API version request - // parameter as per - // [AIP-4236](https://google.aip.dev/client-libraries/4236). - string api_version = 2; - } - - // Information about a specific client implementing a proto-defined service. - message ServiceAsClient { - // The name of the library client formatted as it appears in the source code - string library_client = 1; - - // A mapping from each proto-defined RPC name to the the list of - // methods in library_client that implement it. There can be more - // than one library_client method for each RPC. RPCs with no - // library_client methods need not be included. - // - // The key name is the name of the RPC as defined and formatted in - // the proto file. - map rpcs = 2; - } - - // List of GAPIC client methods implementing the proto-defined RPC - // for the transport and service specified in the containing - // structures. - message MethodList { - // List of methods for a specific proto-service client in the - // GAPIC. These names should be formatted as they appear in the - // source code. - repeated string methods = 1; - } -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py deleted file mode 100644 index f269f536cd7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.py +++ /dev/null @@ -1,78 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/gapic/metadata/gapic_metadata.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 33, - 5, - "", - "google/gapic/metadata/gapic_metadata.proto", -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n*google/gapic/metadata/gapic_metadata.proto\x12\x15google.gapic.metadata"\x85\x06\n\rGapicMetadata\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12\x0f\n\x07\x63omment\x18\x02 \x01(\t\x12\x10\n\x08language\x18\x03 \x01(\t\x12\x15\n\rproto_package\x18\x04 \x01(\t\x12\x17\n\x0flibrary_package\x18\x05 \x01(\t\x12\x44\n\x08services\x18\x06 \x03(\x0b\x32\x32.google.gapic.metadata.GapicMetadata.ServicesEntry\x1ai\n\rServicesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.google.gapic.metadata.GapicMetadata.ServiceForTransport:\x02\x38\x01\x1a\xe8\x01\n\x13ServiceForTransport\x12V\n\x07\x63lients\x18\x01 \x03(\x0b\x32\x45.google.gapic.metadata.GapicMetadata.ServiceForTransport.ClientsEntry\x12\x13\n\x0b\x61pi_version\x18\x02 \x01(\t\x1a\x64\n\x0c\x43lientsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x43\n\x05value\x18\x02 \x01(\x0b\x32\x34.google.gapic.metadata.GapicMetadata.ServiceAsClient:\x02\x38\x01\x1a\xd5\x01\n\x0fServiceAsClient\x12\x16\n\x0elibrary_client\x18\x01 \x01(\t\x12L\n\x04rpcs\x18\x02 \x03(\x0b\x32>.google.gapic.metadata.GapicMetadata.ServiceAsClient.RpcsEntry\x1a\\\n\tRpcsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12>\n\x05value\x18\x02 \x01(\x0b\x32/.google.gapic.metadata.GapicMetadata.MethodList:\x02\x38\x01\x1a\x1d\n\nMethodList\x12\x0f\n\x07methods\x18\x01 \x03(\tB\xba\x01\n\x19\x63om.google.gapic.metadataB\x12GapicMetadataProtoP\x01Z=google.golang.org/genproto/googleapis/gapic/metadata;metadata\xaa\x02\x15Google.Gapic.Metadata\xca\x02\x15Google\\Gapic\\Metadata\xea\x02\x17Google::Gapic::Metadatab\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.gapic.metadata.gapic_metadata_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\031com.google.gapic.metadataB\022GapicMetadataProtoP\001Z=google.golang.org/genproto/googleapis/gapic/metadata;metadata\252\002\025Google.Gapic.Metadata\312\002\025Google\\Gapic\\Metadata\352\002\027Google::Gapic::Metadata" - _globals["_GAPICMETADATA_SERVICESENTRY"]._loaded_options = None - _globals["_GAPICMETADATA_SERVICESENTRY"]._serialized_options = b"8\001" - _globals["_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY"]._loaded_options = None - _globals[ - "_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY" - ]._serialized_options = b"8\001" - _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._loaded_options = None - _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._serialized_options = b"8\001" - _globals["_GAPICMETADATA"]._serialized_start = 70 - _globals["_GAPICMETADATA"]._serialized_end = 843 - _globals["_GAPICMETADATA_SERVICESENTRY"]._serialized_start = 256 - _globals["_GAPICMETADATA_SERVICESENTRY"]._serialized_end = 361 - _globals["_GAPICMETADATA_SERVICEFORTRANSPORT"]._serialized_start = 364 - _globals["_GAPICMETADATA_SERVICEFORTRANSPORT"]._serialized_end = 596 - _globals["_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY"]._serialized_start = 496 - _globals["_GAPICMETADATA_SERVICEFORTRANSPORT_CLIENTSENTRY"]._serialized_end = 596 - _globals["_GAPICMETADATA_SERVICEASCLIENT"]._serialized_start = 599 - _globals["_GAPICMETADATA_SERVICEASCLIENT"]._serialized_end = 812 - _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._serialized_start = 720 - _globals["_GAPICMETADATA_SERVICEASCLIENT_RPCSENTRY"]._serialized_end = 812 - _globals["_GAPICMETADATA_METHODLIST"]._serialized_start = 814 - _globals["_GAPICMETADATA_METHODLIST"]._serialized_end = 843 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi deleted file mode 100644 index 85b594cbc02..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/gapic/metadata/gapic_metadata_pb2.pyi +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class GapicMetadata(_message.Message): - __slots__ = ( - "schema", - "comment", - "language", - "proto_package", - "library_package", - "services", - ) - class ServicesEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: GapicMetadata.ServiceForTransport - def __init__( - self, - key: _Optional[str] = ..., - value: _Optional[_Union[GapicMetadata.ServiceForTransport, _Mapping]] = ..., - ) -> None: ... - - class ServiceForTransport(_message.Message): - __slots__ = ("clients", "api_version") - class ClientsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: GapicMetadata.ServiceAsClient - def __init__( - self, - key: _Optional[str] = ..., - value: _Optional[_Union[GapicMetadata.ServiceAsClient, _Mapping]] = ..., - ) -> None: ... - - CLIENTS_FIELD_NUMBER: _ClassVar[int] - API_VERSION_FIELD_NUMBER: _ClassVar[int] - clients: _containers.MessageMap[str, GapicMetadata.ServiceAsClient] - api_version: str - def __init__( - self, - clients: _Optional[_Mapping[str, GapicMetadata.ServiceAsClient]] = ..., - api_version: _Optional[str] = ..., - ) -> None: ... - - class ServiceAsClient(_message.Message): - __slots__ = ("library_client", "rpcs") - class RpcsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: GapicMetadata.MethodList - def __init__( - self, - key: _Optional[str] = ..., - value: _Optional[_Union[GapicMetadata.MethodList, _Mapping]] = ..., - ) -> None: ... - - LIBRARY_CLIENT_FIELD_NUMBER: _ClassVar[int] - RPCS_FIELD_NUMBER: _ClassVar[int] - library_client: str - rpcs: _containers.MessageMap[str, GapicMetadata.MethodList] - def __init__( - self, - library_client: _Optional[str] = ..., - rpcs: _Optional[_Mapping[str, GapicMetadata.MethodList]] = ..., - ) -> None: ... - - class MethodList(_message.Message): - __slots__ = ("methods",) - METHODS_FIELD_NUMBER: _ClassVar[int] - methods: _containers.RepeatedScalarFieldContainer[str] - def __init__(self, methods: _Optional[_Iterable[str]] = ...) -> None: ... - - SCHEMA_FIELD_NUMBER: _ClassVar[int] - COMMENT_FIELD_NUMBER: _ClassVar[int] - LANGUAGE_FIELD_NUMBER: _ClassVar[int] - PROTO_PACKAGE_FIELD_NUMBER: _ClassVar[int] - LIBRARY_PACKAGE_FIELD_NUMBER: _ClassVar[int] - SERVICES_FIELD_NUMBER: _ClassVar[int] - schema: str - comment: str - language: str - proto_package: str - library_package: str - services: _containers.MessageMap[str, GapicMetadata.ServiceForTransport] - def __init__( - self, - schema: _Optional[str] = ..., - comment: _Optional[str] = ..., - language: _Optional[str] = ..., - proto_package: _Optional[str] = ..., - library_package: _Optional[str] = ..., - services: _Optional[_Mapping[str, GapicMetadata.ServiceForTransport]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto deleted file mode 100644 index b31522b69c7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request.proto +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.logging.type; - -import "google/protobuf/duration.proto"; - -option csharp_namespace = "Google.Cloud.Logging.Type"; -option go_package = "google.golang.org/genproto/googleapis/logging/type;ltype"; -option java_multiple_files = true; -option java_outer_classname = "HttpRequestProto"; -option java_package = "com.google.logging.type"; -option php_namespace = "Google\\Cloud\\Logging\\Type"; -option ruby_package = "Google::Cloud::Logging::Type"; - -// A common proto for logging HTTP requests. Only contains semantics -// defined by the HTTP specification. Product-specific logging -// information MUST be defined in a separate message. -message HttpRequest { - // The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`. - string request_method = 1; - - // The scheme (http, https), the host name, the path and the query - // portion of the URL that was requested. - // Example: `"http://example.com/some/info?color=red"`. - string request_url = 2; - - // The size of the HTTP request message in bytes, including the request - // headers and the request body. - int64 request_size = 3; - - // The response code indicating the status of response. - // Examples: 200, 404. - int32 status = 4; - - // The size of the HTTP response message sent back to the client, in bytes, - // including the response headers and the response body. - int64 response_size = 5; - - // The user agent sent by the client. Example: - // `"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET - // CLR 1.0.3705)"`. - string user_agent = 6; - - // The IP address (IPv4 or IPv6) of the client that issued the HTTP - // request. This field can include port information. Examples: - // `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. - string remote_ip = 7; - - // The IP address (IPv4 or IPv6) of the origin server that the request was - // sent to. This field can include port information. Examples: - // `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. - string server_ip = 13; - - // The referer URL of the request, as defined in - // [HTTP/1.1 Header Field - // Definitions](https://datatracker.ietf.org/doc/html/rfc2616#section-14.36). - string referer = 8; - - // The request processing latency on the server, from the time the request was - // received until the response was sent. - google.protobuf.Duration latency = 14; - - // Whether or not a cache lookup was attempted. - bool cache_lookup = 11; - - // Whether or not an entity was served from cache - // (with or without validation). - bool cache_hit = 9; - - // Whether or not the response was validated with the origin server before - // being served from cache. This field is only meaningful if `cache_hit` is - // True. - bool cache_validated_with_origin_server = 10; - - // The number of HTTP response bytes inserted into cache. Set only when a - // cache fill was attempted. - int64 cache_fill_bytes = 12; - - // Protocol used for the request. Examples: "HTTP/1.1", "HTTP/2", "websocket" - string protocol = 15; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py deleted file mode 100644 index 560ae78b3cd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/logging/type/http_request.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 33, - 5, - "", - "google/logging/type/http_request.proto", -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n&google/logging/type/http_request.proto\x12\x13google.logging.type\x1a\x1egoogle/protobuf/duration.proto"\xef\x02\n\x0bHttpRequest\x12\x16\n\x0erequest_method\x18\x01 \x01(\t\x12\x13\n\x0brequest_url\x18\x02 \x01(\t\x12\x14\n\x0crequest_size\x18\x03 \x01(\x03\x12\x0e\n\x06status\x18\x04 \x01(\x05\x12\x15\n\rresponse_size\x18\x05 \x01(\x03\x12\x12\n\nuser_agent\x18\x06 \x01(\t\x12\x11\n\tremote_ip\x18\x07 \x01(\t\x12\x11\n\tserver_ip\x18\r \x01(\t\x12\x0f\n\x07referer\x18\x08 \x01(\t\x12*\n\x07latency\x18\x0e \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x14\n\x0c\x63\x61\x63he_lookup\x18\x0b \x01(\x08\x12\x11\n\tcache_hit\x18\t \x01(\x08\x12*\n"cache_validated_with_origin_server\x18\n \x01(\x08\x12\x18\n\x10\x63\x61\x63he_fill_bytes\x18\x0c \x01(\x03\x12\x10\n\x08protocol\x18\x0f \x01(\tB\xbe\x01\n\x17\x63om.google.logging.typeB\x10HttpRequestProtoP\x01Z8google.golang.org/genproto/googleapis/logging/type;ltype\xaa\x02\x19Google.Cloud.Logging.Type\xca\x02\x19Google\\Cloud\\Logging\\Type\xea\x02\x1cGoogle::Cloud::Logging::Typeb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.logging.type.http_request_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\027com.google.logging.typeB\020HttpRequestProtoP\001Z8google.golang.org/genproto/googleapis/logging/type;ltype\252\002\031Google.Cloud.Logging.Type\312\002\031Google\\Cloud\\Logging\\Type\352\002\034Google::Cloud::Logging::Type" - _globals["_HTTPREQUEST"]._serialized_start = 96 - _globals["_HTTPREQUEST"]._serialized_end = 463 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi deleted file mode 100644 index 5a05ecfb46a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/http_request_pb2.pyi +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import duration_pb2 as _duration_pb2 -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class HttpRequest(_message.Message): - __slots__ = ( - "request_method", - "request_url", - "request_size", - "status", - "response_size", - "user_agent", - "remote_ip", - "server_ip", - "referer", - "latency", - "cache_lookup", - "cache_hit", - "cache_validated_with_origin_server", - "cache_fill_bytes", - "protocol", - ) - REQUEST_METHOD_FIELD_NUMBER: _ClassVar[int] - REQUEST_URL_FIELD_NUMBER: _ClassVar[int] - REQUEST_SIZE_FIELD_NUMBER: _ClassVar[int] - STATUS_FIELD_NUMBER: _ClassVar[int] - RESPONSE_SIZE_FIELD_NUMBER: _ClassVar[int] - USER_AGENT_FIELD_NUMBER: _ClassVar[int] - REMOTE_IP_FIELD_NUMBER: _ClassVar[int] - SERVER_IP_FIELD_NUMBER: _ClassVar[int] - REFERER_FIELD_NUMBER: _ClassVar[int] - LATENCY_FIELD_NUMBER: _ClassVar[int] - CACHE_LOOKUP_FIELD_NUMBER: _ClassVar[int] - CACHE_HIT_FIELD_NUMBER: _ClassVar[int] - CACHE_VALIDATED_WITH_ORIGIN_SERVER_FIELD_NUMBER: _ClassVar[int] - CACHE_FILL_BYTES_FIELD_NUMBER: _ClassVar[int] - PROTOCOL_FIELD_NUMBER: _ClassVar[int] - request_method: str - request_url: str - request_size: int - status: int - response_size: int - user_agent: str - remote_ip: str - server_ip: str - referer: str - latency: _duration_pb2.Duration - cache_lookup: bool - cache_hit: bool - cache_validated_with_origin_server: bool - cache_fill_bytes: int - protocol: str - def __init__( - self, - request_method: _Optional[str] = ..., - request_url: _Optional[str] = ..., - request_size: _Optional[int] = ..., - status: _Optional[int] = ..., - response_size: _Optional[int] = ..., - user_agent: _Optional[str] = ..., - remote_ip: _Optional[str] = ..., - server_ip: _Optional[str] = ..., - referer: _Optional[str] = ..., - latency: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - cache_lookup: _Optional[bool] = ..., - cache_hit: _Optional[bool] = ..., - cache_validated_with_origin_server: _Optional[bool] = ..., - cache_fill_bytes: _Optional[int] = ..., - protocol: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto deleted file mode 100644 index 406b8173a3a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity.proto +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.logging.type; - -option csharp_namespace = "Google.Cloud.Logging.Type"; -option go_package = "google.golang.org/genproto/googleapis/logging/type;ltype"; -option java_multiple_files = true; -option java_outer_classname = "LogSeverityProto"; -option java_package = "com.google.logging.type"; -option objc_class_prefix = "GLOG"; -option php_namespace = "Google\\Cloud\\Logging\\Type"; -option ruby_package = "Google::Cloud::Logging::Type"; - -// The severity of the event described in a log entry, expressed as one of the -// standard severity levels listed below. For your reference, the levels are -// assigned the listed numeric values. The effect of using numeric values other -// than those listed is undefined. -// -// You can filter for log entries by severity. For example, the following -// filter expression will match log entries with severities `INFO`, `NOTICE`, -// and `WARNING`: -// -// severity > DEBUG AND severity <= WARNING -// -// If you are writing log entries, you should map other severity encodings to -// one of these standard levels. For example, you might map all of Java's FINE, -// FINER, and FINEST levels to `LogSeverity.DEBUG`. You can preserve the -// original severity level in the log entry payload if you wish. -enum LogSeverity { - // (0) The log entry has no assigned severity level. - DEFAULT = 0; - - // (100) Debug or trace information. - DEBUG = 100; - - // (200) Routine information, such as ongoing status or performance. - INFO = 200; - - // (300) Normal but significant events, such as start up, shut down, or - // a configuration change. - NOTICE = 300; - - // (400) Warning events might cause problems. - WARNING = 400; - - // (500) Error events are likely to cause problems. - ERROR = 500; - - // (600) Critical events cause more severe problems or outages. - CRITICAL = 600; - - // (700) A person must take an action immediately. - ALERT = 700; - - // (800) One or more systems are unusable. - EMERGENCY = 800; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py deleted file mode 100644 index 009b1602e3e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/logging/type/log_severity.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 33, - 5, - "", - "google/logging/type/log_severity.proto", -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n&google/logging/type/log_severity.proto\x12\x13google.logging.type*\x82\x01\n\x0bLogSeverity\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\t\n\x05\x44\x45\x42UG\x10\x64\x12\t\n\x04INFO\x10\xc8\x01\x12\x0b\n\x06NOTICE\x10\xac\x02\x12\x0c\n\x07WARNING\x10\x90\x03\x12\n\n\x05\x45RROR\x10\xf4\x03\x12\r\n\x08\x43RITICAL\x10\xd8\x04\x12\n\n\x05\x41LERT\x10\xbc\x05\x12\x0e\n\tEMERGENCY\x10\xa0\x06\x42\xc5\x01\n\x17\x63om.google.logging.typeB\x10LogSeverityProtoP\x01Z8google.golang.org/genproto/googleapis/logging/type;ltype\xa2\x02\x04GLOG\xaa\x02\x19Google.Cloud.Logging.Type\xca\x02\x19Google\\Cloud\\Logging\\Type\xea\x02\x1cGoogle::Cloud::Logging::Typeb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.logging.type.log_severity_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\027com.google.logging.typeB\020LogSeverityProtoP\001Z8google.golang.org/genproto/googleapis/logging/type;ltype\242\002\004GLOG\252\002\031Google.Cloud.Logging.Type\312\002\031Google\\Cloud\\Logging\\Type\352\002\034Google::Cloud::Logging::Type" - _globals["_LOGSEVERITY"]._serialized_start = 64 - _globals["_LOGSEVERITY"]._serialized_end = 194 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi deleted file mode 100644 index eeafb8ed88d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/logging/type/log_severity_pb2.pyi +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class LogSeverity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - DEFAULT: _ClassVar[LogSeverity] - DEBUG: _ClassVar[LogSeverity] - INFO: _ClassVar[LogSeverity] - NOTICE: _ClassVar[LogSeverity] - WARNING: _ClassVar[LogSeverity] - ERROR: _ClassVar[LogSeverity] - CRITICAL: _ClassVar[LogSeverity] - ALERT: _ClassVar[LogSeverity] - EMERGENCY: _ClassVar[LogSeverity] - -DEFAULT: LogSeverity -DEBUG: LogSeverity -INFO: LogSeverity -NOTICE: LogSeverity -WARNING: LogSeverity -ERROR: LogSeverity -CRITICAL: LogSeverity -ALERT: LogSeverity -EMERGENCY: LogSeverity diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py deleted file mode 100644 index 7daa5f84590..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# This module is provided for backwards compatibility with -# googleapis-common-protos <= 1.5.0, where this was the import path. - -from __future__ import absolute_import - -from opentelemetry.agent._vendor.google.longrunning.operations_grpc_pb2 import * # noqa: F401, F403 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py deleted file mode 100644 index 51bf99d5a26..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_grpc_pb2.py +++ /dev/null @@ -1,16 +0,0 @@ -# This module is provided for backwards compatibility with -# googleapis-common-protos <= 1.52.0, where this import path contained -# all of the message and gRPC definitions. - -from opentelemetry.agent._vendor.google.longrunning.operations_pb2_grpc import * -from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import * -from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import ( - _CANCELOPERATIONREQUEST, - _DELETEOPERATIONREQUEST, - _GETOPERATIONREQUEST, - _LISTOPERATIONSREQUEST, - _LISTOPERATIONSRESPONSE, - _OPERATION, - _OPERATIONINFO, - _OPERATIONS, -) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py deleted file mode 100644 index 81758b841a7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_pb2.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright 2016 Google Inc. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Safe implementation of long-running operations with and without gRPC. - -Multiplexes between versions of long-running operations with and without gRPC. -The former is preferred, but not possible in all environments (such as Google -AppEngine Standard). -""" - -try: - from opentelemetry.agent._vendor.google.longrunning.operations_grpc_pb2 import * - from opentelemetry.agent._vendor.google.longrunning.operations_grpc_pb2 import ( - _CANCELOPERATIONREQUEST, - _DELETEOPERATIONREQUEST, - _GETOPERATIONREQUEST, - _LISTOPERATIONSREQUEST, - _LISTOPERATIONSRESPONSE, - _OPERATION, - _OPERATIONINFO, - _OPERATIONS, - ) -except ImportError: - from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import * - from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import ( - _CANCELOPERATIONREQUEST, - _DELETEOPERATIONREQUEST, - _GETOPERATIONREQUEST, - _LISTOPERATIONSREQUEST, - _LISTOPERATIONSRESPONSE, - _OPERATION, - _OPERATIONINFO, - _OPERATIONS, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto deleted file mode 100644 index 63df207d258..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.proto +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.longrunning; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/api/field_behavior.proto"; -import "google/protobuf/any.proto"; -import "google/protobuf/descriptor.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/empty.proto"; -import "google/rpc/status.proto"; - -option csharp_namespace = "Google.LongRunning"; -option go_package = "cloud.google.com/go/longrunning/autogen/longrunningpb;longrunningpb"; -option java_multiple_files = true; -option java_outer_classname = "OperationsProto"; -option java_package = "com.google.longrunning"; -option objc_class_prefix = "GLRUN"; -option php_namespace = "Google\\LongRunning"; - -extend google.protobuf.MethodOptions { - // Additional information regarding long-running operations. - // In particular, this specifies the types that are returned from - // long-running operations. - // - // Required for methods that return `google.longrunning.Operation`; invalid - // otherwise. - google.longrunning.OperationInfo operation_info = 1049; -} - -// Manages long-running operations with an API service. -// -// When an API method normally takes long time to complete, it can be designed -// to return [Operation][google.longrunning.Operation] to the client, and the -// client can use this interface to receive the real response asynchronously by -// polling the operation resource, or pass the operation resource to another API -// (such as Pub/Sub API) to receive the response. Any API service that returns -// long-running operations should implement the `Operations` interface so -// developers can have a consistent client experience. -service Operations { - option (google.api.default_host) = "longrunning.googleapis.com"; - - // Lists operations that match the specified filter in the request. If the - // server doesn't support this method, it returns `UNIMPLEMENTED`. - rpc ListOperations(ListOperationsRequest) returns (ListOperationsResponse) { - option (google.api.http) = { - get: "/v1/{name=operations}" - }; - option (google.api.method_signature) = "name,filter"; - } - - // Gets the latest state of a long-running operation. Clients can use this - // method to poll the operation result at intervals as recommended by the API - // service. - rpc GetOperation(GetOperationRequest) returns (Operation) { - option (google.api.http) = { - get: "/v1/{name=operations/**}" - }; - option (google.api.method_signature) = "name"; - } - - // Deletes a long-running operation. This method indicates that the client is - // no longer interested in the operation result. It does not cancel the - // operation. If the server doesn't support this method, it returns - // `google.rpc.Code.UNIMPLEMENTED`. - rpc DeleteOperation(DeleteOperationRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - delete: "/v1/{name=operations/**}" - }; - option (google.api.method_signature) = "name"; - } - - // Starts asynchronous cancellation on a long-running operation. The server - // makes a best effort to cancel the operation, but success is not - // guaranteed. If the server doesn't support this method, it returns - // `google.rpc.Code.UNIMPLEMENTED`. Clients can use - // [Operations.GetOperation][google.longrunning.Operations.GetOperation] or - // other methods to check whether the cancellation succeeded or whether the - // operation completed despite cancellation. On successful cancellation, - // the operation is not deleted; instead, it becomes an operation with - // an [Operation.error][google.longrunning.Operation.error] value with a - // [google.rpc.Status.code][google.rpc.Status.code] of `1`, corresponding to - // `Code.CANCELLED`. - rpc CancelOperation(CancelOperationRequest) returns (google.protobuf.Empty) { - option (google.api.http) = { - post: "/v1/{name=operations/**}:cancel" - body: "*" - }; - option (google.api.method_signature) = "name"; - } - - // Waits until the specified long-running operation is done or reaches at most - // a specified timeout, returning the latest state. If the operation is - // already done, the latest state is immediately returned. If the timeout - // specified is greater than the default HTTP/RPC timeout, the HTTP/RPC - // timeout is used. If the server does not support this method, it returns - // `google.rpc.Code.UNIMPLEMENTED`. - // Note that this method is on a best-effort basis. It may return the latest - // state before the specified timeout (including immediately), meaning even an - // immediate response is no guarantee that the operation is done. - rpc WaitOperation(WaitOperationRequest) returns (Operation) {} -} - -// This resource represents a long-running operation that is the result of a -// network API call. -message Operation { - // The server-assigned name, which is only unique within the same service that - // originally returns it. If you use the default HTTP mapping, the - // `name` should be a resource name ending with `operations/{unique_id}`. - string name = 1; - - // Service-specific metadata associated with the operation. It typically - // contains progress information and common metadata such as create time. - // Some services might not provide such metadata. Any method that returns a - // long-running operation should document the metadata type, if any. - google.protobuf.Any metadata = 2; - - // If the value is `false`, it means the operation is still in progress. - // If `true`, the operation is completed, and either `error` or `response` is - // available. - bool done = 3; - - // The operation result, which can be either an `error` or a valid `response`. - // If `done` == `false`, neither `error` nor `response` is set. - // If `done` == `true`, exactly one of `error` or `response` can be set. - // Some services might not provide the result. - oneof result { - // The error result of the operation in case of failure or cancellation. - google.rpc.Status error = 4; - - // The normal, successful response of the operation. If the original - // method returns no data on success, such as `Delete`, the response is - // `google.protobuf.Empty`. If the original method is standard - // `Get`/`Create`/`Update`, the response should be the resource. For other - // methods, the response should have the type `XxxResponse`, where `Xxx` - // is the original method name. For example, if the original method name - // is `TakeSnapshot()`, the inferred response type is - // `TakeSnapshotResponse`. - google.protobuf.Any response = 5; - } -} - -// The request message for -// [Operations.GetOperation][google.longrunning.Operations.GetOperation]. -message GetOperationRequest { - // The name of the operation resource. - string name = 1; -} - -// The request message for -// [Operations.ListOperations][google.longrunning.Operations.ListOperations]. -message ListOperationsRequest { - // The name of the operation's parent resource. - string name = 4; - - // The standard list filter. - string filter = 1; - - // The standard list page size. - int32 page_size = 2; - - // The standard list page token. - string page_token = 3; - - // When set to `true`, operations that are reachable are returned as normal, - // and those that are unreachable are returned in the - // [ListOperationsResponse.unreachable] field. - // - // This can only be `true` when reading across collections e.g. when `parent` - // is set to `"projects/example/locations/-"`. - // - // This field is not by default supported and will result in an - // `UNIMPLEMENTED` error if set unless explicitly documented otherwise in - // service or product specific documentation. - bool return_partial_success = 5; -} - -// The response message for -// [Operations.ListOperations][google.longrunning.Operations.ListOperations]. -message ListOperationsResponse { - // A list of operations that matches the specified filter in the request. - repeated Operation operations = 1; - - // The standard List next-page token. - string next_page_token = 2; - - // Unordered list. Unreachable resources. Populated when the request sets - // `ListOperationsRequest.return_partial_success` and reads across - // collections e.g. when attempting to list all resources across all supported - // locations. - repeated string unreachable = 3 - [(google.api.field_behavior) = UNORDERED_LIST]; -} - -// The request message for -// [Operations.CancelOperation][google.longrunning.Operations.CancelOperation]. -message CancelOperationRequest { - // The name of the operation resource to be cancelled. - string name = 1; -} - -// The request message for -// [Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation]. -message DeleteOperationRequest { - // The name of the operation resource to be deleted. - string name = 1; -} - -// The request message for -// [Operations.WaitOperation][google.longrunning.Operations.WaitOperation]. -message WaitOperationRequest { - // The name of the operation resource to wait on. - string name = 1; - - // The maximum duration to wait before timing out. If left blank, the wait - // will be at most the time permitted by the underlying HTTP/RPC protocol. - // If RPC context deadline is also specified, the shorter one will be used. - google.protobuf.Duration timeout = 2; -} - -// A message representing the message types used by a long-running operation. -// -// Example: -// -// rpc Export(ExportRequest) returns (google.longrunning.Operation) { -// option (google.longrunning.operation_info) = { -// response_type: "ExportResponse" -// metadata_type: "ExportMetadata" -// }; -// } -message OperationInfo { - // Required. The message name of the primary return type for this - // long-running operation. - // This type will be used to deserialize the LRO's response. - // - // If the response is in a different package from the rpc, a fully-qualified - // message name must be used (e.g. `google.protobuf.Struct`). - // - // Note: Altering this value constitutes a breaking change. - string response_type = 1; - - // Required. The message name of the metadata type for this long-running - // operation. - // - // If the response is in a different package from the rpc, a fully-qualified - // message name must be used (e.g. `google.protobuf.Struct`). - // - // Note: Altering this value constitutes a breaking change. - string metadata_type = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py deleted file mode 100644 index cd708839d89..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto.py +++ /dev/null @@ -1,6 +0,0 @@ -# This module is provided for backwards compatibility with -# googleapis-common-protos <= 1.5.0, where this was the import path. - -from __future__ import absolute_import - -from opentelemetry.agent._vendor.google.longrunning.operations_proto_pb2 import * # noqa: F401, F403 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py deleted file mode 100644 index f83b1977393..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/longrunning/operations.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/longrunning/operations.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 -from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 -from opentelemetry.agent._vendor.google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - -from opentelemetry.agent._vendor.google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 -from opentelemetry.agent._vendor.google.api import client_pb2 as google_dot_api_dot_client__pb2 -from opentelemetry.agent._vendor.google.api import field_behavior_pb2 as google_dot_api_dot_field__behavior__pb2 -from opentelemetry.agent._vendor.google.rpc import status_pb2 as google_dot_rpc_dot_status__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n#google/longrunning/operations.proto\x12\x12google.longrunning\x1a\x1cgoogle/api/annotations.proto\x1a\x17google/api/client.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a\x19google/protobuf/any.proto\x1a google/protobuf/descriptor.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x17google/rpc/status.proto"\xa8\x01\n\tOperation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x08metadata\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any\x12\x0c\n\x04\x64one\x18\x03 \x01(\x08\x12#\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x12.google.rpc.StatusH\x00\x12(\n\x08response\x18\x05 \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x42\x08\n\x06result"#\n\x13GetOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"|\n\x15ListOperationsRequest\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x01 \x01(\t\x12\x11\n\tpage_size\x18\x02 \x01(\x05\x12\x12\n\npage_token\x18\x03 \x01(\t\x12\x1e\n\x16return_partial_success\x18\x05 \x01(\x08"~\n\x16ListOperationsResponse\x12\x31\n\noperations\x18\x01 \x03(\x0b\x32\x1d.google.longrunning.Operation\x12\x17\n\x0fnext_page_token\x18\x02 \x01(\t\x12\x18\n\x0bunreachable\x18\x03 \x03(\tB\x03\xe0\x41\x06"&\n\x16\x43\x61ncelOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"&\n\x16\x44\x65leteOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t"P\n\x14WaitOperationRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12*\n\x07timeout\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration"=\n\rOperationInfo\x12\x15\n\rresponse_type\x18\x01 \x01(\t\x12\x15\n\rmetadata_type\x18\x02 \x01(\t2\xaa\x05\n\nOperations\x12\x94\x01\n\x0eListOperations\x12).google.longrunning.ListOperationsRequest\x1a*.google.longrunning.ListOperationsResponse"+\xda\x41\x0bname,filter\x82\xd3\xe4\x93\x02\x17\x12\x15/v1/{name=operations}\x12\x7f\n\x0cGetOperation\x12\'.google.longrunning.GetOperationRequest\x1a\x1d.google.longrunning.Operation"\'\xda\x41\x04name\x82\xd3\xe4\x93\x02\x1a\x12\x18/v1/{name=operations/**}\x12~\n\x0f\x44\x65leteOperation\x12*.google.longrunning.DeleteOperationRequest\x1a\x16.google.protobuf.Empty"\'\xda\x41\x04name\x82\xd3\xe4\x93\x02\x1a*\x18/v1/{name=operations/**}\x12\x88\x01\n\x0f\x43\x61ncelOperation\x12*.google.longrunning.CancelOperationRequest\x1a\x16.google.protobuf.Empty"1\xda\x41\x04name\x82\xd3\xe4\x93\x02$"\x1f/v1/{name=operations/**}:cancel:\x01*\x12Z\n\rWaitOperation\x12(.google.longrunning.WaitOperationRequest\x1a\x1d.google.longrunning.Operation"\x00\x1a\x1d\xca\x41\x1alongrunning.googleapis.com:Z\n\x0eoperation_info\x12\x1e.google.protobuf.MethodOptions\x18\x99\x08 \x01(\x0b\x32!.google.longrunning.OperationInfoB\xa2\x01\n\x16\x63om.google.longrunningB\x0fOperationsProtoP\x01ZCcloud.google.com/go/longrunning/autogen/longrunningpb;longrunningpb\xa2\x02\x05GLRUN\xaa\x02\x12Google.LongRunning\xca\x02\x12Google\\LongRunningb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.longrunning.operations_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\026com.google.longrunningB\017OperationsProtoP\001ZCcloud.google.com/go/longrunning/autogen/longrunningpb;longrunningpb\242\002\005GLRUN\252\002\022Google.LongRunning\312\002\022Google\\LongRunning" - _globals["_LISTOPERATIONSRESPONSE"].fields_by_name[ - "unreachable" - ]._loaded_options = None - _globals["_LISTOPERATIONSRESPONSE"].fields_by_name[ - "unreachable" - ]._serialized_options = b"\340A\006" - _globals["_OPERATIONS"]._loaded_options = None - _globals["_OPERATIONS"]._serialized_options = b"\312A\032longrunning.googleapis.com" - _globals["_OPERATIONS"].methods_by_name["ListOperations"]._loaded_options = None - _globals["_OPERATIONS"].methods_by_name[ - "ListOperations" - ]._serialized_options = ( - b"\332A\013name,filter\202\323\344\223\002\027\022\025/v1/{name=operations}" - ) - _globals["_OPERATIONS"].methods_by_name["GetOperation"]._loaded_options = None - _globals["_OPERATIONS"].methods_by_name[ - "GetOperation" - ]._serialized_options = ( - b"\332A\004name\202\323\344\223\002\032\022\030/v1/{name=operations/**}" - ) - _globals["_OPERATIONS"].methods_by_name["DeleteOperation"]._loaded_options = None - _globals["_OPERATIONS"].methods_by_name[ - "DeleteOperation" - ]._serialized_options = ( - b"\332A\004name\202\323\344\223\002\032*\030/v1/{name=operations/**}" - ) - _globals["_OPERATIONS"].methods_by_name["CancelOperation"]._loaded_options = None - _globals["_OPERATIONS"].methods_by_name[ - "CancelOperation" - ]._serialized_options = ( - b'\332A\004name\202\323\344\223\002$"\037/v1/{name=operations/**}:cancel:\001*' - ) - _globals["_OPERATION"]._serialized_start = 295 - _globals["_OPERATION"]._serialized_end = 463 - _globals["_GETOPERATIONREQUEST"]._serialized_start = 465 - _globals["_GETOPERATIONREQUEST"]._serialized_end = 500 - _globals["_LISTOPERATIONSREQUEST"]._serialized_start = 502 - _globals["_LISTOPERATIONSREQUEST"]._serialized_end = 626 - _globals["_LISTOPERATIONSRESPONSE"]._serialized_start = 628 - _globals["_LISTOPERATIONSRESPONSE"]._serialized_end = 754 - _globals["_CANCELOPERATIONREQUEST"]._serialized_start = 756 - _globals["_CANCELOPERATIONREQUEST"]._serialized_end = 794 - _globals["_DELETEOPERATIONREQUEST"]._serialized_start = 796 - _globals["_DELETEOPERATIONREQUEST"]._serialized_end = 834 - _globals["_WAITOPERATIONREQUEST"]._serialized_start = 836 - _globals["_WAITOPERATIONREQUEST"]._serialized_end = 916 - _globals["_OPERATIONINFO"]._serialized_start = 918 - _globals["_OPERATIONINFO"]._serialized_end = 979 - _globals["_OPERATIONS"]._serialized_start = 982 - _globals["_OPERATIONS"]._serialized_end = 1664 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi deleted file mode 100644 index e56b84a361d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/longrunning/operations_proto_pb2.pyi +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import any_pb2 as _any_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pb2 as _descriptor_pb2 -from google.protobuf import duration_pb2 as _duration_pb2 -from google.protobuf import empty_pb2 as _empty_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -from google.api import annotations_pb2 as _annotations_pb2 -from google.api import client_pb2 as _client_pb2 -from google.api import field_behavior_pb2 as _field_behavior_pb2 -from google.rpc import status_pb2 as _status_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor -OPERATION_INFO_FIELD_NUMBER: _ClassVar[int] -operation_info: _descriptor.FieldDescriptor - -class Operation(_message.Message): - __slots__ = ("name", "metadata", "done", "error", "response") - NAME_FIELD_NUMBER: _ClassVar[int] - METADATA_FIELD_NUMBER: _ClassVar[int] - DONE_FIELD_NUMBER: _ClassVar[int] - ERROR_FIELD_NUMBER: _ClassVar[int] - RESPONSE_FIELD_NUMBER: _ClassVar[int] - name: str - metadata: _any_pb2.Any - done: bool - error: _status_pb2.Status - response: _any_pb2.Any - def __init__( - self, - name: _Optional[str] = ..., - metadata: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., - done: _Optional[bool] = ..., - error: _Optional[_Union[_status_pb2.Status, _Mapping]] = ..., - response: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., - ) -> None: ... - -class GetOperationRequest(_message.Message): - __slots__ = ("name",) - NAME_FIELD_NUMBER: _ClassVar[int] - name: str - def __init__(self, name: _Optional[str] = ...) -> None: ... - -class ListOperationsRequest(_message.Message): - __slots__ = ("name", "filter", "page_size", "page_token", "return_partial_success") - NAME_FIELD_NUMBER: _ClassVar[int] - FILTER_FIELD_NUMBER: _ClassVar[int] - PAGE_SIZE_FIELD_NUMBER: _ClassVar[int] - PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] - RETURN_PARTIAL_SUCCESS_FIELD_NUMBER: _ClassVar[int] - name: str - filter: str - page_size: int - page_token: str - return_partial_success: bool - def __init__( - self, - name: _Optional[str] = ..., - filter: _Optional[str] = ..., - page_size: _Optional[int] = ..., - page_token: _Optional[str] = ..., - return_partial_success: _Optional[bool] = ..., - ) -> None: ... - -class ListOperationsResponse(_message.Message): - __slots__ = ("operations", "next_page_token", "unreachable") - OPERATIONS_FIELD_NUMBER: _ClassVar[int] - NEXT_PAGE_TOKEN_FIELD_NUMBER: _ClassVar[int] - UNREACHABLE_FIELD_NUMBER: _ClassVar[int] - operations: _containers.RepeatedCompositeFieldContainer[Operation] - next_page_token: str - unreachable: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - operations: _Optional[_Iterable[_Union[Operation, _Mapping]]] = ..., - next_page_token: _Optional[str] = ..., - unreachable: _Optional[_Iterable[str]] = ..., - ) -> None: ... - -class CancelOperationRequest(_message.Message): - __slots__ = ("name",) - NAME_FIELD_NUMBER: _ClassVar[int] - name: str - def __init__(self, name: _Optional[str] = ...) -> None: ... - -class DeleteOperationRequest(_message.Message): - __slots__ = ("name",) - NAME_FIELD_NUMBER: _ClassVar[int] - name: str - def __init__(self, name: _Optional[str] = ...) -> None: ... - -class WaitOperationRequest(_message.Message): - __slots__ = ("name", "timeout") - NAME_FIELD_NUMBER: _ClassVar[int] - TIMEOUT_FIELD_NUMBER: _ClassVar[int] - name: str - timeout: _duration_pb2.Duration - def __init__( - self, - name: _Optional[str] = ..., - timeout: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - ) -> None: ... - -class OperationInfo(_message.Message): - __slots__ = ("response_type", "metadata_type") - RESPONSE_TYPE_FIELD_NUMBER: _ClassVar[int] - METADATA_TYPE_FIELD_NUMBER: _ClassVar[int] - response_type: str - metadata_type: str - def __init__( - self, response_type: _Optional[str] = ..., metadata_type: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py deleted file mode 100644 index 2273ed8da80..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -# Copyright 2007 Google Inc. All Rights Reserved. - -__version__ = '7.36.2' diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py deleted file mode 100644 index 19c09e2079f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any.py +++ /dev/null @@ -1,52 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -"""Contains the Any helper APIs.""" - -from typing import Optional, TypeVar - -from opentelemetry.agent._vendor.google.protobuf import descriptor -from opentelemetry.agent._vendor.google.protobuf.message import Message - -from opentelemetry.agent._vendor.google.protobuf.any_pb2 import Any - -_MessageT = TypeVar('_MessageT', bound=Message) - - -def pack( - msg: Message, - type_url_prefix: Optional[str] = 'type.googleapis.com/', - deterministic: Optional[bool] = None, -) -> Any: - any_msg = Any() - any_msg.Pack( - msg=msg, type_url_prefix=type_url_prefix, deterministic=deterministic - ) - return any_msg - - -def unpack(any_msg: Any, msg: Message) -> bool: - return any_msg.Unpack(msg=msg) - - -def unpack_as(any_msg: Any, message_type: type[_MessageT]) -> _MessageT: - unpacked = message_type() - if unpack(any_msg, unpacked): - return unpacked - else: - raise TypeError( - f'Attempted to unpack {type_name(any_msg)} to' - f' {message_type.__qualname__}' - ) - - -def type_name(any_msg: Any) -> str: - return any_msg.TypeName() - - -def is_type(any_msg: Any, des: descriptor.Descriptor) -> bool: - return any_msg.Is(des) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py deleted file mode 100644 index 1b31d6dc7b7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/any_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/any.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/any.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/any.proto\x12\x0fgoogle.protobuf\"6\n\x03\x41ny\x12\x19\n\x08type_url\x18\x01 \x01(\tR\x07typeUrl\x12\x14\n\x05value\x18\x02 \x01(\x0cR\x05valueBv\n\x13\x63om.google.protobufB\x08\x41nyProtoP\x01Z,google.golang.org/protobuf/types/known/anypb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.any_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\010AnyProtoP\001Z,google.golang.org/protobuf/types/known/anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_ANY']._serialized_start=46 - _globals['_ANY']._serialized_end=100 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py deleted file mode 100644 index 492256f31d1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/api_pb2.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/api.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/api.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 -from opentelemetry.agent._vendor.google.protobuf import type_pb2 as google_dot_protobuf_dot_type__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/api.proto\x12\x0fgoogle.protobuf\x1a$google/protobuf/source_context.proto\x1a\x1agoogle/protobuf/type.proto\"\xdb\x02\n\x03\x41pi\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x31\n\x07methods\x18\x02 \x03(\x0b\x32\x17.google.protobuf.MethodR\x07methods\x12\x31\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x18\n\x07version\x18\x04 \x01(\tR\x07version\x12\x45\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContextR\rsourceContext\x12.\n\x06mixins\x18\x06 \x03(\x0b\x32\x16.google.protobuf.MixinR\x06mixins\x12/\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.SyntaxR\x06syntax\x12\x18\n\x07\x65\x64ition\x18\x08 \x01(\tR\x07\x65\x64ition\"\xd4\x02\n\x06Method\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12(\n\x10request_type_url\x18\x02 \x01(\tR\x0erequestTypeUrl\x12+\n\x11request_streaming\x18\x03 \x01(\x08R\x10requestStreaming\x12*\n\x11response_type_url\x18\x04 \x01(\tR\x0fresponseTypeUrl\x12-\n\x12response_streaming\x18\x05 \x01(\x08R\x11responseStreaming\x12\x31\n\x07options\x18\x06 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x33\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.SyntaxB\x02\x18\x01R\x06syntax\x12\x1c\n\x07\x65\x64ition\x18\x08 \x01(\tB\x02\x18\x01R\x07\x65\x64ition\"/\n\x05Mixin\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n\x04root\x18\x02 \x01(\tR\x04rootBv\n\x13\x63om.google.protobufB\x08\x41piProtoP\x01Z,google.golang.org/protobuf/types/known/apipb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.api_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\010ApiProtoP\001Z,google.golang.org/protobuf/types/known/apipb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_METHOD'].fields_by_name['syntax']._loaded_options = None - _globals['_METHOD'].fields_by_name['syntax']._serialized_options = b'\030\001' - _globals['_METHOD'].fields_by_name['edition']._loaded_options = None - _globals['_METHOD'].fields_by_name['edition']._serialized_options = b'\030\001' - _globals['_API']._serialized_start=113 - _globals['_API']._serialized_end=460 - _globals['_METHOD']._serialized_start=463 - _globals['_METHOD']._serialized_end=803 - _globals['_MIXIN']._serialized_start=805 - _globals['_MIXIN']._serialized_end=852 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py deleted file mode 100644 index 436de6d1293..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor.py +++ /dev/null @@ -1,1669 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Descriptors essentially contain exactly the information found in a .proto - -file, in types that make this information accessible in Python. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import abc -import binascii -import os -import threading -import warnings - -from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation - -_USE_C_DESCRIPTORS = False -if api_implementation.Type() != 'python': - # pylint: disable=protected-access - _message = api_implementation._c_module - # TODO: Remove this import after fix api_implementation - if _message is None: - from opentelemetry.agent._vendor.google.protobuf.pyext import _message - _USE_C_DESCRIPTORS = True - - -class Error(Exception): - """Base error for this module.""" - - -class TypeTransformationError(Error): - """Error transforming between python proto type and corresponding C++ type.""" - - -if _USE_C_DESCRIPTORS: - # This metaclass allows to override the behavior of code like - # isinstance(my_descriptor, FieldDescriptor) - # and make it return True when the descriptor is an instance of the extension - # type written in C++. - class DescriptorMetaclass(type): - - def __instancecheck__(cls, obj): - if super(DescriptorMetaclass, cls).__instancecheck__(obj): - return True - if isinstance(obj, cls._C_DESCRIPTOR_CLASS): - return True - return False - -else: - # The standard metaclass; nothing changes. - DescriptorMetaclass = abc.ABCMeta - - -class _Lock(object): - """Wrapper class of threading.Lock(), which is allowed by 'with'.""" - - def __new__(cls): - self = object.__new__(cls) - self._lock = threading.Lock() # pylint: disable=protected-access - return self - - def __enter__(self): - self._lock.acquire() - - def __exit__(self, exc_type, exc_value, exc_tb): - self._lock.release() - - -_lock = threading.Lock() - - -def _Deprecated( - name, - alternative='get/find descriptors from generated code or query the descriptor_pool', -): - if _Deprecated.count > 0: - _Deprecated.count -= 1 - warnings.warn( - 'Call to deprecated %s, use %s instead.' % (name, alternative), - category=DeprecationWarning, - stacklevel=3, - ) - - -# These must match the values in descriptor.proto, but we can't use them -# directly because we sometimes need to reference them in feature helpers -# below *during* the build of descriptor.proto. -_FEATURESET_MESSAGE_ENCODING_DELIMITED = 2 -_FEATURESET_FIELD_PRESENCE_IMPLICIT = 2 -_FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED = 3 -_FEATURESET_REPEATED_FIELD_ENCODING_PACKED = 1 -_FEATURESET_ENUM_TYPE_CLOSED = 2 - -# Deprecated warnings will print 100 times at most which should be enough for -# users to notice and do not cause timeout. -_Deprecated.count = 100 - -_internal_create_key = object() - - -class DescriptorBase(metaclass=DescriptorMetaclass): - """Descriptors base class. - - This class is the base of all descriptor classes. It provides common options - related functionality. - - Attributes: - has_options: True if the descriptor has non-default options. Usually it is - not necessary to read this -- just call GetOptions() which will happily - return the default instance. However, it's sometimes useful for - efficiency, and also useful inside the protobuf implementation to avoid - some bootstrapping issues. - file (FileDescriptor): Reference to file info. - """ - - if _USE_C_DESCRIPTORS: - # The class, or tuple of classes, that are considered as "virtual - # subclasses" of this descriptor class. - _C_DESCRIPTOR_CLASS = () - - def __init__(self, file, options, serialized_options, options_class_name): - """Initialize the descriptor given its options message and the name of the - - class of the options message. The name of the class is required in case - the options message is None and has to be created. - """ - self._features = None - self.file = file - self._original_options = options - # These two fields are duplicated as a compatibility shim for old gencode - # that resets them. In 26.x (cl/580304039) we renamed _options to, - # _loaded_options breaking backwards compatibility. - self._options = self._loaded_options = None - self._options_class_name = options_class_name - self._serialized_options = serialized_options - - # Does this descriptor have non-default options? - self.has_options = (self._original_options is not None) or ( - self._serialized_options is not None - ) - - @property - @abc.abstractmethod - def _parent(self): - pass - - def _InferLegacyFeatures(self, edition, options, features): - """Infers features from proto2/proto3 syntax so that editions logic can be used everywhere. - - Args: - edition: The edition to infer features for. - options: The options for this descriptor that are being processed. - features: The feature set object to modify with inferred features. - """ - pass - - def _GetFeatures(self): - if not self._features: - self._LazyLoadOptions() - return self._features - - def _ResolveFeatures(self, edition, raw_options): - """Resolves features from the raw options of this descriptor. - - Args: - edition: The edition to use for feature defaults. - raw_options: The options for this descriptor that are being processed. - - Returns: - A fully resolved feature set for making runtime decisions. - """ - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - if self._parent: - features = descriptor_pb2.FeatureSet() - features.CopyFrom(self._parent._GetFeatures()) - else: - features = self.file.pool._CreateDefaultFeatures(edition) - unresolved = descriptor_pb2.FeatureSet() - unresolved.CopyFrom(raw_options.features) - self._InferLegacyFeatures(edition, raw_options, unresolved) - features.MergeFrom(unresolved) - - # Use the feature cache to reduce memory bloat. - return self.file.pool._InternFeatures(features) - - def _LazyLoadOptions(self): - """Lazily initializes descriptor options towards the end of the build.""" - if self._options and self._loaded_options == self._options: - # If neither has been reset by gencode, use the cache. - return - - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - if not hasattr(descriptor_pb2, self._options_class_name): - raise RuntimeError( - 'Unknown options class name %s!' % self._options_class_name - ) - options_class = getattr(descriptor_pb2, self._options_class_name) - features = None - edition = self.file._edition - - if not self.has_options: - if not self._features: - features = self._ResolveFeatures( - descriptor_pb2.Edition.Value(edition), options_class() - ) - with _lock: - self._options = self._loaded_options = options_class() - if not self._features: - self._features = features - else: - if not self._serialized_options: - options = self._original_options - else: - options = _ParseOptions(options_class(), self._serialized_options) - - if not self._features: - features = self._ResolveFeatures( - descriptor_pb2.Edition.Value(edition), options - ) - with _lock: - self._options = self._loaded_options = options - if not self._features: - self._features = features - if options.HasField('features'): - options.ClearField('features') - if not options.SerializeToString(): - self._options = self._loaded_options = options_class() - self.has_options = False - - def GetOptions(self): - """Retrieves descriptor options. - - Returns: - The options set on this descriptor. - """ - # If either has been reset by gencode, reload options. - if not self._options or not self._loaded_options: - self._LazyLoadOptions() - if ( - self._options - and hasattr(self._options, '_SetFrozen') - and not getattr(self._options, '_frozen', False) - ): - self._options._SetFrozen() - return self._options - - -class _NestedDescriptorBase(DescriptorBase): - """Common class for descriptors that can be nested.""" - - def __init__( - self, - options, - options_class_name, - name, - full_name, - file, - containing_type, - serialized_start=None, - serialized_end=None, - serialized_options=None, - ): - """Constructor. - - Args: - options: Protocol message options or None to use default message options. - options_class_name (str): The class name of the above options. - name (str): Name of this protocol message type. - full_name (str): Fully-qualified name of this protocol message type, which - will include protocol "package" name and the name of any enclosing - types. - containing_type: if provided, this is a nested descriptor, with this - descriptor as parent, otherwise None. - serialized_start: The start index (inclusive) in block in the - file.serialized_pb that describes this descriptor. - serialized_end: The end index (exclusive) in block in the - file.serialized_pb that describes this descriptor. - serialized_options: Protocol message serialized options or None. - """ - super(_NestedDescriptorBase, self).__init__( - file, options, serialized_options, options_class_name - ) - - self.name = name - # TODO: Add function to calculate full_name instead of having it in - # memory? - self.full_name = full_name - self.containing_type = containing_type - - self._serialized_start = serialized_start - self._serialized_end = serialized_end - - def CopyToProto(self, proto): - """Copies this to the matching proto in descriptor_pb2. - - Args: - proto: An empty proto instance from descriptor_pb2. - - Raises: - Error: If self couldn't be serialized, due to to few constructor - arguments. - """ - if ( - self.file is not None - and self._serialized_start is not None - and self._serialized_end is not None - ): - proto.ParseFromString( - self.file.serialized_pb[self._serialized_start : self._serialized_end] - ) - else: - raise Error('Descriptor does not contain serialization.') - - -class Descriptor(_NestedDescriptorBase): - """Descriptor for a protocol message type. - - Attributes: - name (str): Name of this protocol message type. - full_name (str): Fully-qualified name of this protocol message type, which - will include protocol "package" name and the name of any enclosing - types. - containing_type (Descriptor): Reference to the descriptor of the type - containing us, or None if this is top-level. - fields (list[FieldDescriptor]): Field descriptors for all fields in this - type. - fields_by_number (dict(int, FieldDescriptor)): Same - :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by - "number" attribute in each FieldDescriptor. - fields_by_name (dict(str, FieldDescriptor)): Same :class:`FieldDescriptor` - objects as in :attr:`fields`, but indexed by "name" attribute in each - :class:`FieldDescriptor`. - nested_types (list[Descriptor]): Descriptor references for all protocol - message types nested within this one. - nested_types_by_name (dict(str, Descriptor)): Same Descriptor objects as - in :attr:`nested_types`, but indexed by "name" attribute in each - Descriptor. - enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references for - all enums contained within this type. - enum_types_by_name (dict(str, EnumDescriptor)): Same - :class:`EnumDescriptor` objects as in :attr:`enum_types`, but indexed by - "name" attribute in each EnumDescriptor. - enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping from - enum value name to :class:`EnumValueDescriptor` for that value. - extensions (list[FieldDescriptor]): All extensions defined directly within - this message type (NOT within a nested type). - extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor - objects as :attr:`extensions`, but indexed by "name" attribute of each - FieldDescriptor. - is_extendable (bool): Does this type define any extension ranges? - oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields - in this message. - oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in - :attr:`oneofs`, but indexed by "name" attribute. - file (FileDescriptor): Reference to file descriptor. - is_map_entry: If the message type is a map entry. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.Descriptor - - def __new__( - cls, - name=None, - full_name=None, - filename=None, - containing_type=None, - fields=None, - nested_types=None, - enum_types=None, - extensions=None, - options=None, - serialized_options=None, - is_extendable=True, - extension_ranges=None, - oneofs=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - syntax=None, - is_map_entry=False, - create_key=None, - ): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindMessageTypeByName(full_name) - - # NOTE: The file argument redefining a builtin is nothing we can - # fix right now since we don't know how many clients already rely on the - # name of the argument. - def __init__( - self, - name, - full_name, - filename, - containing_type, - fields, - nested_types, - enum_types, - extensions, - options=None, - serialized_options=None, - is_extendable=True, - extension_ranges=None, - oneofs=None, - file=None, - serialized_start=None, - serialized_end=None, # pylint: disable=redefined-builtin - syntax=None, - is_map_entry=False, - create_key=None, - ): - """Arguments to __init__() are as described in the description - - of Descriptor fields above. - - Note that filename is an obsolete argument, that is not used anymore. - Please use file.name to access this as an attribute. - """ - if create_key is not _internal_create_key: - _Deprecated('create function Descriptor()') - - super(Descriptor, self).__init__( - options, - 'MessageOptions', - name, - full_name, - file, - containing_type, - serialized_start=serialized_start, - serialized_end=serialized_end, - serialized_options=serialized_options, - ) - - # We have fields in addition to fields_by_name and fields_by_number, - # so that: - # 1. Clients can index fields by "order in which they're listed." - # 2. Clients can easily iterate over all fields with the terse - # syntax: for f in descriptor.fields: ... - self.fields = fields - for field in self.fields: - field.containing_type = self - field.file = file - self.fields_by_number = dict((f.number, f) for f in fields) - self.fields_by_name = dict((f.name, f) for f in fields) - self._fields_by_camelcase_name = None - - self.nested_types = nested_types - for nested_type in nested_types: - nested_type.containing_type = self - self.nested_types_by_name = dict((t.name, t) for t in nested_types) - - self.enum_types = enum_types - for enum_type in self.enum_types: - enum_type.containing_type = self - self.enum_types_by_name = dict((t.name, t) for t in enum_types) - self.enum_values_by_name = dict( - (v.name, v) for t in enum_types for v in t.values - ) - - self.extensions = extensions - for extension in self.extensions: - extension.extension_scope = self - self.extensions_by_name = dict((f.name, f) for f in extensions) - self.is_extendable = is_extendable - self.extension_ranges = extension_ranges - self.oneofs = oneofs if oneofs is not None else [] - self.oneofs_by_name = dict((o.name, o) for o in self.oneofs) - for oneof in self.oneofs: - oneof.containing_type = self - oneof.file = file - self._is_map_entry = is_map_entry - - @property - def _parent(self): - return self.containing_type or self.file - - @property - def fields_by_camelcase_name(self): - """Same FieldDescriptor objects as in :attr:`fields`, but indexed by - - :attr:`FieldDescriptor.camelcase_name`. - """ - if self._fields_by_camelcase_name is None: - self._fields_by_camelcase_name = dict( - (f.camelcase_name, f) for f in self.fields - ) - return self._fields_by_camelcase_name - - def EnumValueName(self, enum, value): - """Returns the string name of an enum value. - - This is just a small helper method to simplify a common operation. - - Args: - enum: string name of the Enum. - value: int, value of the enum. - - Returns: - string name of the enum value. - - Raises: - KeyError if either the Enum doesn't exist or the value is not a valid - value for the enum. - """ - return self.enum_types_by_name[enum].values_by_number[value].name - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.DescriptorProto. - - Args: - proto: An empty descriptor_pb2.DescriptorProto. - """ - # This function is overridden to give a better doc comment. - super(Descriptor, self).CopyToProto(proto) - - -# TODO: We should have aggressive checking here, -# for example: -# * If you specify a repeated field, you should not be allowed -# to specify a default value. -# * [Other examples here as needed]. -# -# TODO: for this and other *Descriptor classes, we -# might also want to lock things down aggressively (e.g., -# prevent clients from setting the attributes). Having -# stronger invariants here in general will reduce the number -# of runtime checks we must do in reflection.py... -class FieldDescriptor(DescriptorBase): - """Descriptor for a single field in a .proto file. - - Attributes: - name (str): Name of this field, exactly as it appears in .proto. - full_name (str): Name of this field, including containing scope. This is - particularly relevant for extensions. - index (int): Dense, 0-indexed index giving the order that this field - textually appears within its message in the .proto file. - number (int): Tag number declared for this field in the .proto file. - type (int): (One of the TYPE_* constants below) Declared type. - cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to - represent this field. - label (int): (One of the LABEL_* constants below) Tells whether this field - is optional, required, or repeated. - has_default_value (bool): True if this field has a default value defined, - otherwise false. - default_value (Varies): Default value of this field. Only meaningful for - non-repeated scalar fields. Repeated fields should always set this to [], - and non-repeated composite fields should always set this to None. - containing_type (Descriptor): Descriptor of the protocol message type that - contains this field. Set by the Descriptor constructor if we're passed - into one. Somewhat confusingly, for extension fields, this is the - descriptor of the EXTENDED message, not the descriptor of the message - containing this field. (See is_extension and extension_scope below). - message_type (Descriptor): If a composite field, a descriptor of the message - type contained in this field. Otherwise, this is None. - enum_type (EnumDescriptor): If this field contains an enum, a descriptor of - that enum. Otherwise, this is None. - is_extension: True iff this describes an extension field. - extension_scope (Descriptor): Only meaningful if is_extension is True. Gives - the message that immediately contains this extension field. Will be None - iff we're a top-level (file-level) extension field. - options (descriptor_pb2.FieldOptions): Protocol message field options or - None to use default field options. - containing_oneof (OneofDescriptor): If the field is a member of a oneof - union, contains its descriptor. Otherwise, None. - file (FileDescriptor): Reference to file descriptor. - """ - - # Must be consistent with C++ FieldDescriptor::Type enum in - # descriptor.h. - # - # TODO: Find a way to eliminate this repetition. - TYPE_DOUBLE = 1 - TYPE_FLOAT = 2 - TYPE_INT64 = 3 - TYPE_UINT64 = 4 - TYPE_INT32 = 5 - TYPE_FIXED64 = 6 - TYPE_FIXED32 = 7 - TYPE_BOOL = 8 - TYPE_STRING = 9 - TYPE_GROUP = 10 - TYPE_MESSAGE = 11 - TYPE_BYTES = 12 - TYPE_UINT32 = 13 - TYPE_ENUM = 14 - TYPE_SFIXED32 = 15 - TYPE_SFIXED64 = 16 - TYPE_SINT32 = 17 - TYPE_SINT64 = 18 - MAX_TYPE = 18 - - # Must be consistent with C++ FieldDescriptor::CppType enum in - # descriptor.h. - # - # TODO: Find a way to eliminate this repetition. - CPPTYPE_INT32 = 1 - CPPTYPE_INT64 = 2 - CPPTYPE_UINT32 = 3 - CPPTYPE_UINT64 = 4 - CPPTYPE_DOUBLE = 5 - CPPTYPE_FLOAT = 6 - CPPTYPE_BOOL = 7 - CPPTYPE_ENUM = 8 - CPPTYPE_STRING = 9 - CPPTYPE_MESSAGE = 10 - MAX_CPPTYPE = 10 - - _PYTHON_TO_CPP_PROTO_TYPE_MAP = { - TYPE_DOUBLE: CPPTYPE_DOUBLE, - TYPE_FLOAT: CPPTYPE_FLOAT, - TYPE_ENUM: CPPTYPE_ENUM, - TYPE_INT64: CPPTYPE_INT64, - TYPE_SINT64: CPPTYPE_INT64, - TYPE_SFIXED64: CPPTYPE_INT64, - TYPE_UINT64: CPPTYPE_UINT64, - TYPE_FIXED64: CPPTYPE_UINT64, - TYPE_INT32: CPPTYPE_INT32, - TYPE_SFIXED32: CPPTYPE_INT32, - TYPE_SINT32: CPPTYPE_INT32, - TYPE_UINT32: CPPTYPE_UINT32, - TYPE_FIXED32: CPPTYPE_UINT32, - TYPE_BYTES: CPPTYPE_STRING, - TYPE_STRING: CPPTYPE_STRING, - TYPE_BOOL: CPPTYPE_BOOL, - TYPE_MESSAGE: CPPTYPE_MESSAGE, - TYPE_GROUP: CPPTYPE_MESSAGE, - } - - # Must be consistent with C++ FieldDescriptor::Label enum in - # descriptor.h. - # - # TODO: Find a way to eliminate this repetition. - LABEL_OPTIONAL = 1 - LABEL_REQUIRED = 2 - LABEL_REPEATED = 3 - MAX_LABEL = 3 - - # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber, - # and kLastReservedNumber in descriptor.h - MAX_FIELD_NUMBER = (1 << 29) - 1 - FIRST_RESERVED_FIELD_NUMBER = 19000 - LAST_RESERVED_FIELD_NUMBER = 19999 - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.FieldDescriptor - - def __new__( - cls, - name, - full_name, - index, - number, - type, - cpp_type, - label, - default_value, - message_type, - enum_type, - containing_type, - is_extension, - extension_scope, - options=None, - serialized_options=None, - has_default_value=True, - containing_oneof=None, - json_name=None, - file=None, - create_key=None, - ): # pylint: disable=redefined-builtin - _message.Message._CheckCalledFromGeneratedFile() - if is_extension: - return _message.default_pool.FindExtensionByName(full_name) - else: - return _message.default_pool.FindFieldByName(full_name) - - def __init__( - self, - name, - full_name, - index, - number, - type, - cpp_type, - label, - default_value, - message_type, - enum_type, - containing_type, - is_extension, - extension_scope, - options=None, - serialized_options=None, - has_default_value=True, - containing_oneof=None, - json_name=None, - file=None, - create_key=None, - ): # pylint: disable=redefined-builtin - """The arguments are as described in the description of FieldDescriptor - - attributes above. - - Note that containing_type may be None, and may be set later if necessary - (to deal with circular references between message types, for example). - Likewise for extension_scope. - """ - if create_key is not _internal_create_key: - _Deprecated('create function FieldDescriptor()') - - super(FieldDescriptor, self).__init__( - file, options, serialized_options, 'FieldOptions' - ) - self.name = name - self.full_name = full_name - self._camelcase_name = None - if json_name is None: - self.json_name = _ToJsonName(name) - else: - self.json_name = json_name - self.index = index - self.number = number - self._type = type - self.cpp_type = cpp_type - self._label = label - self.has_default_value = has_default_value - self.default_value = default_value - self.containing_type = containing_type - self.message_type = message_type - self.enum_type = enum_type - self.is_extension = is_extension - self.extension_scope = extension_scope - self.containing_oneof = containing_oneof - if api_implementation.Type() == 'python': - self._cdescriptor = None - else: - if is_extension: - self._cdescriptor = _message.default_pool.FindExtensionByName(full_name) - else: - self._cdescriptor = _message.default_pool.FindFieldByName(full_name) - - @property - def _parent(self): - if self.containing_oneof: - return self.containing_oneof - if self.is_extension: - return self.extension_scope or self.file - return self.containing_type - - def _InferLegacyFeatures(self, edition, options, features): - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - if edition >= descriptor_pb2.Edition.EDITION_2023: - return - - if self._label == FieldDescriptor.LABEL_REQUIRED: - features.field_presence = ( - descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED - ) - - if self._type == FieldDescriptor.TYPE_GROUP: - features.message_encoding = ( - descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED - ) - - if options.HasField('packed'): - features.repeated_field_encoding = ( - descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED - if options.packed - else descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED - ) - - @property - def type(self): - if ( - self._GetFeatures().message_encoding - == _FEATURESET_MESSAGE_ENCODING_DELIMITED - and self.message_type - and not self.message_type.GetOptions().map_entry - and not self.containing_type.GetOptions().map_entry - ): - return FieldDescriptor.TYPE_GROUP - return self._type - - @type.setter - def type(self, val): - self._type = val - - @property - def is_required(self): - """Returns if the field is required.""" - return ( - self._GetFeatures().field_presence - == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED - ) - - @property - def is_repeated(self): - """Returns if the field is repeated.""" - return self._label == FieldDescriptor.LABEL_REPEATED - - @property - def camelcase_name(self): - """Camelcase name of this field. - - Returns: - str: the name in CamelCase. - """ - if self._camelcase_name is None: - self._camelcase_name = _ToCamelCase(self.name) - return self._camelcase_name - - @property - def has_presence(self): - """Whether the field distinguishes between unpopulated and default values. - - Raises: - RuntimeError: singular field that is not linked with message nor file. - """ - if self.is_repeated: - return False - if ( - self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE - or self.is_extension - or self.containing_oneof - ): - return True - - return ( - self._GetFeatures().field_presence - != _FEATURESET_FIELD_PRESENCE_IMPLICIT - ) - - @property - def is_packed(self): - """Returns if the field is packed.""" - if not self.is_repeated: - return False - field_type = self.type - if ( - field_type == FieldDescriptor.TYPE_STRING - or field_type == FieldDescriptor.TYPE_GROUP - or field_type == FieldDescriptor.TYPE_MESSAGE - or field_type == FieldDescriptor.TYPE_BYTES - ): - return False - - return ( - self._GetFeatures().repeated_field_encoding - == _FEATURESET_REPEATED_FIELD_ENCODING_PACKED - ) - - @staticmethod - def ProtoTypeToCppProtoType(proto_type): - """Converts from a Python proto type to a C++ Proto Type. - - The Python ProtocolBuffer classes specify both the 'Python' datatype and the - 'C++' datatype - and they're not the same. This helper method should - translate from one to another. - - Args: - proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) - - Returns: - int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. - Raises: - TypeTransformationError: when the Python proto type isn't known. - """ - try: - return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] - except KeyError: - raise TypeTransformationError('Unknown proto_type: %s' % proto_type) - - -class EnumDescriptor(_NestedDescriptorBase): - """Descriptor for an enum defined in a .proto file. - - Attributes: - name (str): Name of the enum type. - full_name (str): Full name of the type, including package name and any - enclosing type(s). - values (list[EnumValueDescriptor]): List of the values in this enum. - values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, but - indexed by the "name" field of each EnumValueDescriptor. - values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`, - but indexed by the "number" field of each EnumValueDescriptor. - containing_type (Descriptor): Descriptor of the immediate containing type of - this enum, or None if this is an enum defined at the top level in a .proto - file. Set by Descriptor's constructor if we're passed into one. - file (FileDescriptor): Reference to file descriptor. - options (descriptor_pb2.EnumOptions): Enum options message or None to use - default enum options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.EnumDescriptor - - def __new__( - cls, - name, - full_name, - filename, - values, - containing_type=None, - options=None, - serialized_options=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - create_key=None, - ): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindEnumTypeByName(full_name) - - def __init__( - self, - name, - full_name, - filename, - values, - containing_type=None, - options=None, - serialized_options=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - create_key=None, - ): - """Arguments are as described in the attribute description above. - - Note that filename is an obsolete argument, that is not used anymore. - Please use file.name to access this as an attribute. - """ - if create_key is not _internal_create_key: - _Deprecated('create function EnumDescriptor()') - - super(EnumDescriptor, self).__init__( - options, - 'EnumOptions', - name, - full_name, - file, - containing_type, - serialized_start=serialized_start, - serialized_end=serialized_end, - serialized_options=serialized_options, - ) - - self.values = values - for value in self.values: - value.file = file - value.type = self - self.values_by_name = dict((v.name, v) for v in values) - # Values are reversed to ensure that the first alias is retained. - self.values_by_number = dict((v.number, v) for v in reversed(values)) - - @property - def _parent(self): - return self.containing_type or self.file - - @property - def is_closed(self): - """Returns true whether this is a "closed" enum. - - This means that it: - - Has a fixed set of values, rather than being equivalent to an int32. - - Encountering values not in this set causes them to be treated as unknown - fields. - - The first value (i.e., the default) may be nonzero. - - WARNING: Some runtimes currently have a quirk where non-closed enums are - treated as closed when used as the type of fields defined in a - `syntax = proto2;` file. This quirk is not present in all runtimes; as of - writing, we know that: - - - C++, Java, and C++-based Python share this quirk. - - UPB and UPB-based Python do not. - - PHP and Ruby treat all enums as open regardless of declaration. - - Care should be taken when using this function to respect the target - runtime's enum handling quirks. - """ - return self._GetFeatures().enum_type == _FEATURESET_ENUM_TYPE_CLOSED - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.EnumDescriptorProto. - - Args: - proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. - """ - # This function is overridden to give a better doc comment. - super(EnumDescriptor, self).CopyToProto(proto) - - -class EnumValueDescriptor(DescriptorBase): - """Descriptor for a single value within an enum. - - Attributes: - name (str): Name of this value. - index (int): Dense, 0-indexed index giving the order that this value appears - textually within its enum in the .proto file. - number (int): Actual number assigned to this enum value. - type (EnumDescriptor): :class:`EnumDescriptor` to which this value belongs. - Set by :class:`EnumDescriptor`'s constructor if we're passed into one. - options (descriptor_pb2.EnumValueOptions): Enum value options message or - None to use default enum value options options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor - - def __new__( - cls, - name, - index, - number, - type=None, # pylint: disable=redefined-builtin - options=None, - serialized_options=None, - create_key=None, - ): - _message.Message._CheckCalledFromGeneratedFile() - # There is no way we can build a complete EnumValueDescriptor with the - # given parameters (the name of the Enum is not known, for example). - # Fortunately generated files just pass it to the EnumDescriptor() - # constructor, which will ignore it, so returning None is good enough. - return None - - def __init__( - self, - name, - index, - number, - type=None, # pylint: disable=redefined-builtin - options=None, - serialized_options=None, - create_key=None, - ): - """Arguments are as described in the attribute description above.""" - if create_key is not _internal_create_key: - _Deprecated('create function EnumValueDescriptor()') - - super(EnumValueDescriptor, self).__init__( - type.file if type else None, - options, - serialized_options, - 'EnumValueOptions', - ) - self.name = name - self.index = index - self.number = number - self.type = type - - @property - def _parent(self): - return self.type - - -class OneofDescriptor(DescriptorBase): - """Descriptor for a oneof field. - - Attributes: - name (str): Name of the oneof field. - full_name (str): Full name of the oneof field, including package name. - index (int): 0-based index giving the order of the oneof field inside its - containing type. - containing_type (Descriptor): :class:`Descriptor` of the protocol message - type that contains this field. Set by the :class:`Descriptor` constructor - if we're passed into one. - fields (list[FieldDescriptor]): The list of field descriptors this oneof can - contain. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.OneofDescriptor - - def __new__( - cls, - name, - full_name, - index, - containing_type, - fields, - options=None, - serialized_options=None, - create_key=None, - ): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindOneofByName(full_name) - - def __init__( - self, - name, - full_name, - index, - containing_type, - fields, - options=None, - serialized_options=None, - create_key=None, - ): - """Arguments are as described in the attribute description above.""" - if create_key is not _internal_create_key: - _Deprecated('create function OneofDescriptor()') - - super(OneofDescriptor, self).__init__( - containing_type.file if containing_type else None, - options, - serialized_options, - 'OneofOptions', - ) - self.name = name - self.full_name = full_name - self.index = index - self.containing_type = containing_type - self.fields = fields - - @property - def _parent(self): - return self.containing_type - - -class ServiceDescriptor(_NestedDescriptorBase): - """Descriptor for a service. - - Attributes: - name (str): Name of the service. - full_name (str): Full name of the service, including package name. - index (int): 0-indexed index giving the order that this services definition - appears within the .proto file. - methods (list[MethodDescriptor]): List of methods provided by this service. - methods_by_name (dict(str, MethodDescriptor)): Same - :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but - indexed by "name" attribute in each :class:`MethodDescriptor`. - options (descriptor_pb2.ServiceOptions): Service options message or None to - use default service options. - file (FileDescriptor): Reference to file info. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor - - def __new__( - cls, - name=None, - full_name=None, - index=None, - methods=None, - options=None, - serialized_options=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - create_key=None, - ): - _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access - return _message.default_pool.FindServiceByName(full_name) - - def __init__( - self, - name, - full_name, - index, - methods, - options=None, - serialized_options=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - create_key=None, - ): - if create_key is not _internal_create_key: - _Deprecated('create function ServiceDescriptor()') - - super(ServiceDescriptor, self).__init__( - options, - 'ServiceOptions', - name, - full_name, - file, - None, - serialized_start=serialized_start, - serialized_end=serialized_end, - serialized_options=serialized_options, - ) - self.index = index - self.methods = methods - self.methods_by_name = dict((m.name, m) for m in methods) - # Set the containing service for each method in this service. - for method in self.methods: - method.file = self.file - method.containing_service = self - - @property - def _parent(self): - return self.file - - def FindMethodByName(self, name): - """Searches for the specified method, and returns its descriptor. - - Args: - name (str): Name of the method. - - Returns: - MethodDescriptor: The descriptor for the requested method. - - Raises: - KeyError: if the method cannot be found in the service. - """ - return self.methods_by_name[name] - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.ServiceDescriptorProto. - - Args: - proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. - """ - # This function is overridden to give a better doc comment. - super(ServiceDescriptor, self).CopyToProto(proto) - - -class MethodDescriptor(DescriptorBase): - """Descriptor for a method in a service. - - Attributes: - name (str): Name of the method within the service. - full_name (str): Full name of method. - index (int): 0-indexed index of the method inside the service. - containing_service (ServiceDescriptor): The service that contains this - method. - input_type (Descriptor): The descriptor of the message that this method - accepts. - output_type (Descriptor): The descriptor of the message that this method - returns. - client_streaming (bool): Whether this method uses client streaming. - server_streaming (bool): Whether this method uses server streaming. - options (descriptor_pb2.MethodOptions or None): Method options message, or - None to use default method options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.MethodDescriptor - - def __new__( - cls, - name, - full_name, - index, - containing_service, - input_type, - output_type, - client_streaming=False, - server_streaming=False, - options=None, - serialized_options=None, - create_key=None, - ): - _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access - return _message.default_pool.FindMethodByName(full_name) - - def __init__( - self, - name, - full_name, - index, - containing_service, - input_type, - output_type, - client_streaming=False, - server_streaming=False, - options=None, - serialized_options=None, - create_key=None, - ): - """The arguments are as described in the description of MethodDescriptor - - attributes above. - - Note that containing_service may be None, and may be set later if necessary. - """ - if create_key is not _internal_create_key: - _Deprecated('create function MethodDescriptor()') - - super(MethodDescriptor, self).__init__( - containing_service.file if containing_service else None, - options, - serialized_options, - 'MethodOptions', - ) - self.name = name - self.full_name = full_name - self.index = index - self.containing_service = containing_service - self.input_type = input_type - self.output_type = output_type - self.client_streaming = client_streaming - self.server_streaming = server_streaming - - @property - def _parent(self): - return self.containing_service - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.MethodDescriptorProto. - - Args: - proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto. - - Raises: - Error: If self couldn't be serialized, due to too few constructor - arguments. - """ - if self.containing_service is not None: - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - service_proto = descriptor_pb2.ServiceDescriptorProto() - self.containing_service.CopyToProto(service_proto) - proto.CopyFrom(service_proto.method[self.index]) - else: - raise Error('Descriptor does not contain a service.') - - -class FileDescriptor(DescriptorBase): - """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. - - Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and - :attr:`dependencies` fields are only set by the - :py:mod:`google.protobuf.message_factory` module, and not by the generated - proto code. - - Attributes: - name (str): Name of file, relative to root of source tree. - package (str): Name of the package - edition (Edition): Enum value indicating edition of the file - serialized_pb (bytes): Byte string of serialized - :class:`descriptor_pb2.FileDescriptorProto`. - dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` - objects this :class:`FileDescriptor` depends on. - public_dependencies (list[FileDescriptor]): A subset of - :attr:`dependencies`, which were declared as "public". - message_types_by_name (dict(str, Descriptor)): Mapping from message names to - their :class:`Descriptor`. - enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to - their :class:`EnumDescriptor`. - extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension - names declared at file scope to their :class:`FieldDescriptor`. - services_by_name (dict(str, ServiceDescriptor)): Mapping from services' - names to their :class:`ServiceDescriptor`. - pool (DescriptorPool): The pool this descriptor belongs to. When not passed - to the constructor, the global default pool is used. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.FileDescriptor - - def __new__( - cls, - name, - package, - options=None, - serialized_options=None, - serialized_pb=None, - dependencies=None, - public_dependencies=None, - syntax=None, - edition=None, - pool=None, - create_key=None, - ): - # FileDescriptor() is called from various places, not only from generated - # files, to register dynamic proto files and messages. - # pylint: disable=g-explicit-bool-comparison - if serialized_pb: - return _message.default_pool.AddSerializedFile(serialized_pb) - else: - return super(FileDescriptor, cls).__new__(cls) - - def __init__( - self, - name, - package, - options=None, - serialized_options=None, - serialized_pb=None, - dependencies=None, - public_dependencies=None, - syntax=None, - edition=None, - pool=None, - create_key=None, - ): - """Constructor.""" - if create_key is not _internal_create_key: - _Deprecated('create function FileDescriptor()') - - super(FileDescriptor, self).__init__( - self, options, serialized_options, 'FileOptions' - ) - - if edition and edition != 'EDITION_UNKNOWN': - self._edition = edition - elif syntax == 'proto3': - self._edition = 'EDITION_PROTO3' - else: - self._edition = 'EDITION_PROTO2' - - if pool is None: - from opentelemetry.agent._vendor.google.protobuf import descriptor_pool - - pool = descriptor_pool.Default() - self.pool = pool - self.message_types_by_name = {} - self.name = name - self.package = package - self.serialized_pb = serialized_pb - - self.enum_types_by_name = {} - self.extensions_by_name = {} - self.services_by_name = {} - self.dependencies = dependencies or [] - self.public_dependencies = public_dependencies or [] - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.FileDescriptorProto. - - Args: - proto: An empty descriptor_pb2.FileDescriptorProto. - """ - proto.ParseFromString(self.serialized_pb) - - @property - def _parent(self): - return None - - -def _ParseOptions(message, string): - """Parses serialized options. - - This helper function is used to parse serialized options in generated - proto2 files. It must not be used outside proto2. - """ - message.ParseFromString(string) - return message - - -def _ToCamelCase(name): - """Converts name to camel-case and returns it.""" - capitalize_next = False - result = [] - - for c in name: - if c == '_': - if result: - capitalize_next = True - elif capitalize_next: - result.append(c.upper()) - capitalize_next = False - else: - result += c - - # Lower-case the first letter. - if result and result[0].isupper(): - result[0] = result[0].lower() - return ''.join(result) - - -def _OptionsOrNone(descriptor_proto): - """Returns the value of the field `options`, or None if it is not set.""" - if descriptor_proto.HasField('options'): - return descriptor_proto.options - else: - return None - - -def _ToJsonName(name): - """Converts name to Json name and returns it.""" - capitalize_next = False - result = [] - - for c in name: - if c == '_': - capitalize_next = True - elif capitalize_next: - result.append(c.upper()) - capitalize_next = False - else: - result += c - - return ''.join(result) - - -def MakeDescriptor( - desc_proto, - package='', - build_file_if_cpp=True, - syntax=None, - edition=None, - file_desc=None, -): - """Make a protobuf Descriptor given a DescriptorProto protobuf. - - Handles nested descriptors. Note that this is limited to the scope of defining - a message inside of another message. Composite fields can currently only be - resolved if the message is defined in the same scope as the field. - - Args: - desc_proto: The descriptor_pb2.DescriptorProto protobuf message. - package: Optional package name for the new message Descriptor (string). - build_file_if_cpp: Update the C++ descriptor pool if api matches. Set to - False on recursion, so no duplicates are created. - syntax: The syntax/semantics that should be used. Set to "proto3" to get - proto3 field presence semantics. - edition: The edition that should be used if syntax is "edition". - file_desc: A FileDescriptor to place this descriptor into. - - Returns: - A Descriptor for protobuf messages. - """ - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - # Generate a random name for this proto file to prevent conflicts with any - # imported ones. We need to specify a file name so the descriptor pool - # accepts our FileDescriptorProto, but it is not important what that file - # name is actually set to. - proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') - - if package: - file_name = os.path.join(package.replace('.', '/'), proto_name + '.proto') - else: - file_name = proto_name + '.proto' - - if api_implementation.Type() != 'python' and build_file_if_cpp: - # The C++ implementation requires all descriptors to be backed by the same - # definition in the C++ descriptor pool. To do this, we build a - # FileDescriptorProto with the same definition as this descriptor and build - # it into the pool. - file_descriptor_proto = descriptor_pb2.FileDescriptorProto() - file_descriptor_proto.message_type.add().MergeFrom(desc_proto) - - if package: - file_descriptor_proto.package = package - file_descriptor_proto.name = file_name - - _message.default_pool.Add(file_descriptor_proto) - result = _message.default_pool.FindFileByName(file_descriptor_proto.name) - - if _USE_C_DESCRIPTORS: - return result.message_types_by_name[desc_proto.name] - - if file_desc is None: - file_desc = FileDescriptor( - pool=None, - name=file_name, - package=package, - syntax=syntax, - edition=edition, - options=None, - serialized_pb='', - dependencies=[], - public_dependencies=[], - create_key=_internal_create_key, - ) - full_message_name = [desc_proto.name] - if package: - full_message_name.insert(0, package) - - # Create Descriptors for enum types - enum_types = {} - for enum_proto in desc_proto.enum_type: - full_name = '.'.join(full_message_name + [enum_proto.name]) - enum_desc = EnumDescriptor( - enum_proto.name, - full_name, - None, - [ - EnumValueDescriptor( - enum_val.name, - ii, - enum_val.number, - create_key=_internal_create_key, - ) - for ii, enum_val in enumerate(enum_proto.value) - ], - file=file_desc, - create_key=_internal_create_key, - ) - enum_types[full_name] = enum_desc - - # Create Descriptors for nested types - nested_types = {} - for nested_proto in desc_proto.nested_type: - full_name = '.'.join(full_message_name + [nested_proto.name]) - # Nested types are just those defined inside of the message, not all types - # used by fields in the message, so no loops are possible here. - nested_desc = MakeDescriptor( - nested_proto, - package='.'.join(full_message_name), - build_file_if_cpp=False, - syntax=syntax, - edition=edition, - file_desc=file_desc, - ) - nested_types[full_name] = nested_desc - - fields = [] - for field_proto in desc_proto.field: - full_name = '.'.join(full_message_name + [field_proto.name]) - enum_desc = None - nested_desc = None - if field_proto.json_name: - json_name = field_proto.json_name - else: - json_name = None - if field_proto.HasField('type_name'): - type_name = field_proto.type_name - full_type_name = '.'.join( - full_message_name + [type_name[type_name.rfind('.') + 1 :]] - ) - if full_type_name in nested_types: - nested_desc = nested_types[full_type_name] - elif full_type_name in enum_types: - enum_desc = enum_types[full_type_name] - # Else type_name references a non-local type, which isn't implemented - field = FieldDescriptor( - field_proto.name, - full_name, - field_proto.number - 1, - field_proto.number, - field_proto.type, - FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), - field_proto.label, - None, - nested_desc, - enum_desc, - None, - False, - None, - options=_OptionsOrNone(field_proto), - has_default_value=False, - json_name=json_name, - file=file_desc, - create_key=_internal_create_key, - ) - fields.append(field) - - desc_name = '.'.join(full_message_name) - return Descriptor( - desc_proto.name, - desc_name, - None, - None, - fields, - list(nested_types.values()), - list(enum_types.values()), - [], - options=_OptionsOrNone(desc_proto), - file=file_desc, - create_key=_internal_create_key, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py deleted file mode 100644 index ce0033efedb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_database.py +++ /dev/null @@ -1,186 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Provides a container for DescriptorProtos.""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -from typing import Dict, Iterator, Optional -import warnings - - -class Error(Exception): - pass - - -class DescriptorDatabaseConflictingDefinitionError(Error): - """Raised when a proto is added with the same name & different descriptor.""" - - -class DescriptorDatabase(object): - """A container accepting FileDescriptorProtos and maps DescriptorProtos.""" - - def __init__(self) -> None: - self._file_desc_protos_by_file: Dict[ - str, 'descriptor_pb2.FileDescriptorProto' - ] = {} - self._file_desc_protos_by_symbol: Dict[ - str, 'descriptor_pb2.FileDescriptorProto' - ] = {} - - def Add(self, file_desc_proto: 'descriptor_pb2.FileDescriptorProto') -> None: - """Adds the FileDescriptorProto and its types to this database. - - Args: - file_desc_proto: The FileDescriptorProto to add. - - Raises: - DescriptorDatabaseConflictingDefinitionError: if an attempt is made to - add a proto with the same name but different definition than an - existing proto in the database. - """ - proto_name = file_desc_proto.name - if proto_name not in self._file_desc_protos_by_file: - self._file_desc_protos_by_file[proto_name] = file_desc_proto - elif self._file_desc_protos_by_file[proto_name] != file_desc_proto: - raise DescriptorDatabaseConflictingDefinitionError( - '%s already added, but with different descriptor.' % proto_name - ) - else: - return - - # Add all the top-level descriptors to the index. - package = file_desc_proto.package - for message in file_desc_proto.message_type: - for name in _ExtractSymbols(message, package): - self._AddSymbol(name, file_desc_proto) - for enum in file_desc_proto.enum_type: - self._AddSymbol( - ('.'.join((package, enum.name)) if package else enum.name), - file_desc_proto, - ) - for enum_value in enum.value: - self._file_desc_protos_by_symbol[ - '.'.join((package, enum_value.name)) if package else enum_value.name - ] = file_desc_proto - for extension in file_desc_proto.extension: - self._AddSymbol( - ('.'.join((package, extension.name)) if package else extension.name), - file_desc_proto, - ) - for service in file_desc_proto.service: - self._AddSymbol( - ('.'.join((package, service.name)) if package else service.name), - file_desc_proto, - ) - - def FindFileByName(self, name: str) -> 'descriptor_pb2.FileDescriptorProto': - """Finds the file descriptor proto by file name. - - Typically the file name is a relative path ending to a .proto file. The - proto with the given name will have to have been added to this database - using the Add method or else an error will be raised. - - Args: - name: The file name to find. - - Returns: - The file descriptor proto matching the name. - - Raises: - KeyError if no file by the given name was added. - """ - - return self._file_desc_protos_by_file[name] - - def FindFileContainingSymbol( - self, symbol: str - ) -> 'descriptor_pb2.FileDescriptorProto': - """Finds the file descriptor proto containing the specified symbol. - - The symbol should be a fully qualified name including the file descriptor's - package and any containing messages. Some examples: - - 'some.package.name.Message' - 'some.package.name.Message.NestedEnum' - 'some.package.name.Message.some_field' - - The file descriptor proto containing the specified symbol must be added to - this database using the Add method or else an error will be raised. - - Args: - symbol: The fully qualified symbol name. - - Returns: - The file descriptor proto containing the symbol. - - Raises: - KeyError if no file contains the specified symbol. - """ - symbol = symbol.lstrip('.') - try: - return self._file_desc_protos_by_symbol[symbol] - except KeyError: - # Fields, enum values, and nested extensions are not in - # _file_desc_protos_by_symbol. Try to find the top level - # descriptor. Non-existent nested symbol under a valid top level - # descriptor can also be found. The behavior is the same with - # protobuf C++. - top_level, _, _ = symbol.rpartition('.') - try: - return self._file_desc_protos_by_symbol[top_level] - except KeyError: - # Raise the original symbol as a KeyError for better diagnostics. - raise KeyError(symbol) - - def FindFileContainingExtension( - self, - extendee_name: str, - extension_number: int, # pylint: disable=unused-argument - ) -> Optional['descriptor_pb2.FileDescriptorProto']: - # TODO: implement this API. - return None - - def FindAllExtensionNumbers(self, extendee_name: str) -> list[int]: # pylint: disable=unused-argument - # TODO: implement this API. - return [] - - def _AddSymbol( - self, name: str, file_desc_proto: 'descriptor_pb2.FileDescriptorProto' - ) -> None: - if name in self._file_desc_protos_by_symbol: - warn_msg = ( - 'Conflict register for file "' - + file_desc_proto.name - + '": ' - + name - + ' is already defined in file "' - + self._file_desc_protos_by_symbol[name].name - + '"' - ) - warnings.warn(warn_msg, RuntimeWarning) - self._file_desc_protos_by_symbol[name] = file_desc_proto - - -def _ExtractSymbols( - desc_proto: 'descriptor_pb2.DescriptorProto', package: str -) -> Iterator[str]: - """Pulls out all the symbols from a descriptor proto. - - Args: - desc_proto: The proto to extract symbols from. - package: The package containing the descriptor type. - - Yields: - The fully qualified name found in the descriptor. - """ - message_name = package + '.' + desc_proto.name if package else desc_proto.name - yield message_name - for nested_type in desc_proto.nested_type: - for symbol in _ExtractSymbols(nested_type, message_name): - yield symbol - for enum_type in desc_proto.enum_type: - yield '.'.join((message_name, enum_type.name)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py deleted file mode 100644 index 31ed13939da..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pb2.py +++ /dev/null @@ -1,3465 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/descriptor.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/descriptor.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -if not _descriptor._USE_C_DESCRIPTORS: - DESCRIPTOR = _descriptor.FileDescriptor( - name='google/protobuf/descriptor.proto', - package='google.protobuf', - syntax='proto2', - edition='EDITION_PROTO2', - serialized_options=b'\n\023com.google.protobufB\020DescriptorProtosH\001Z-google.golang.org/protobuf/types/descriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Reflection', - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"[\n\x11\x46ileDescriptorSet\x12\x38\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProtoR\x04\x66ile*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xc5\x05\n\x13\x46ileDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n\x07package\x18\x02 \x01(\tR\x07package\x12\x1e\n\ndependency\x18\x03 \x03(\tR\ndependency\x12+\n\x11public_dependency\x18\n \x03(\x05R\x10publicDependency\x12\'\n\x0fweak_dependency\x18\x0b \x03(\x05R\x0eweakDependency\x12+\n\x11option_dependency\x18\x0f \x03(\tR\x10optionDependency\x12\x43\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\x0bmessageType\x12\x41\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12\x41\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProtoR\x07service\x12\x43\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x36\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptionsR\x07options\x12I\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfoR\x0esourceCodeInfo\x12\x16\n\x06syntax\x18\x0c \x01(\tR\x06syntax\x12\x32\n\x07\x65\x64ition\x18\x0e \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\"\xfc\x06\n\x0f\x44\x65scriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12;\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\x05\x66ield\x12\x43\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x41\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\nnestedType\x12\x41\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12X\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRangeR\x0e\x65xtensionRange\x12\x44\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProtoR\toneofDecl\x12\x39\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptionsR\x07options\x12U\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\n \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x0b \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1az\n\x0e\x45xtensionRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\x12@\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptionsR\x07options\x1a\x37\n\rReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\xd4\x04\n\x15\x45xtensionRangeOptions\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x12Y\n\x0b\x64\x65\x63laration\x18\x02 \x03(\x0b\x32\x32.google.protobuf.ExtensionRangeOptions.DeclarationB\x03\x88\x01\x02R\x0b\x64\x65\x63laration\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12m\n\x0cverification\x18\x03 \x01(\x0e\x32\x38.google.protobuf.ExtensionRangeOptions.VerificationState:\nUNVERIFIEDB\x03\x88\x01\x02R\x0cverification\x1a\x94\x01\n\x0b\x44\x65\x63laration\x12\x16\n\x06number\x18\x01 \x01(\x05R\x06number\x12\x1b\n\tfull_name\x18\x02 \x01(\tR\x08\x66ullName\x12\x12\n\x04type\x18\x03 \x01(\tR\x04type\x12\x1a\n\x08reserved\x18\x05 \x01(\x08R\x08reserved\x12\x1a\n\x08repeated\x18\x06 \x01(\x08R\x08repeatedJ\x04\x08\x04\x10\x05\"4\n\x11VerificationState\x12\x0f\n\x0b\x44\x45\x43LARATION\x10\x00\x12\x0e\n\nUNVERIFIED\x10\x01*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xc1\x06\n\x14\x46ieldDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x03 \x01(\x05R\x06number\x12\x41\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.LabelR\x05label\x12>\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.TypeR\x04type\x12\x1b\n\ttype_name\x18\x06 \x01(\tR\x08typeName\x12\x1a\n\x08\x65xtendee\x18\x02 \x01(\tR\x08\x65xtendee\x12#\n\rdefault_value\x18\x07 \x01(\tR\x0c\x64\x65\x66\x61ultValue\x12\x1f\n\x0boneof_index\x18\t \x01(\x05R\noneofIndex\x12\x1b\n\tjson_name\x18\n \x01(\tR\x08jsonName\x12\x37\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptionsR\x07options\x12\'\n\x0fproto3_optional\x18\x11 \x01(\x08R\x0eproto3Optional\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REPEATED\x10\x03\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\"c\n\x14OneofDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x37\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptionsR\x07options\"\xa6\x03\n\x13\x45numDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12?\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProtoR\x05value\x12\x36\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptionsR\x07options\x12]\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\x05 \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x06 \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1a;\n\x11\x45numReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\x83\x01\n\x18\x45numValueDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x02 \x01(\x05R\x06number\x12;\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptionsR\x07options\"\xb5\x01\n\x16ServiceDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12>\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProtoR\x06method\x12\x39\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptionsR\x07optionsJ\x04\x08\x04\x10\x05R\x06stream\"\x89\x02\n\x15MethodDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1d\n\ninput_type\x18\x02 \x01(\tR\tinputType\x12\x1f\n\x0boutput_type\x18\x03 \x01(\tR\noutputType\x12\x38\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptionsR\x07options\x12\x30\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lseR\x0f\x63lientStreaming\x12\x30\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lseR\x0fserverStreaming\"\x8c\x0c\n\x0b\x46ileOptions\x12!\n\x0cjava_package\x18\x01 \x01(\tR\x0bjavaPackage\x12\x30\n\x14java_outer_classname\x18\x08 \x01(\tR\x12javaOuterClassname\x12\xf9\x01\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lseB\xc1\x01\xb2\x01\xbd\x01\x08\xe6\x07 \xe9\x07*\xb4\x01This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.R\x11javaMultipleFiles\x12\x44\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01R\x19javaGenerateEqualsAndHash\x12:\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lseR\x13javaStringCheckUtf8\x12S\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEEDR\x0boptimizeFor\x12\x1d\n\ngo_package\x18\x0b \x01(\tR\tgoPackage\x12\x35\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lseR\x11\x63\x63GenericServices\x12\x39\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lseR\x13javaGenericServices\x12\x35\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lseR\x11pyGenericServices\x12%\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\xbf\x01\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04trueB\x8e\x01\xb2\x01\x8a\x01 \xea\x07*\x84\x01\x63\x63_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.R\x0e\x63\x63\x45nableArenas\x12*\n\x11objc_class_prefix\x18$ \x01(\tR\x0fobjcClassPrefix\x12)\n\x10\x63sharp_namespace\x18% \x01(\tR\x0f\x63sharpNamespace\x12!\n\x0cswift_prefix\x18\' \x01(\tR\x0bswiftPrefix\x12(\n\x10php_class_prefix\x18( \x01(\tR\x0ephpClassPrefix\x12#\n\rphp_namespace\x18) \x01(\tR\x0cphpNamespace\x12\x34\n\x16php_metadata_namespace\x18, \x01(\tR\x14phpMetadataNamespace\x12!\n\x0cruby_package\x18- \x01(\tR\x0brubyPackage\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08*\x10+J\x04\x08&\x10\'R\x14php_generic_services\"\xfc\x03\n\x0eMessageOptions\x12<\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lseR\x14messageSetWireFormat\x12L\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lseR\x1cnoStandardDescriptorAccessor\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1b\n\tmap_entry\x18\x07 \x01(\x08R\x08mapEntry\x12V\n&deprecated_legacy_json_field_conflicts\x18\x0b \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xce\r\n\x0c\x46ieldOptions\x12\x41\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRINGR\x05\x63type\x12\x16\n\x06packed\x18\x02 \x01(\x08R\x06packed\x12G\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMALR\x06jstype\x12\x19\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lseR\x04lazy\x12.\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lseR\x0eunverifiedLazy\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1d\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lseB\x02\x18\x01R\x04weak\x12(\n\x0c\x64\x65\x62ug_redact\x18\x10 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12K\n\tretention\x18\x11 \x01(\x0e\x32-.google.protobuf.FieldOptions.OptionRetentionR\tretention\x12H\n\x07targets\x18\x13 \x03(\x0e\x32..google.protobuf.FieldOptions.OptionTargetTypeR\x07targets\x12W\n\x10\x65\x64ition_defaults\x18\x14 \x03(\x0b\x32,.google.protobuf.FieldOptions.EditionDefaultR\x0f\x65\x64itionDefaults\x12\x37\n\x08\x66\x65\x61tures\x18\x15 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12U\n\x0f\x66\x65\x61ture_support\x18\x16 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x1aZ\n\x0e\x45\x64itionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value\x1a\xbb\x02\n\x0e\x46\x65\x61tureSupport\x12G\n\x12\x65\x64ition_introduced\x18\x01 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionIntroduced\x12G\n\x12\x65\x64ition_deprecated\x18\x02 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionDeprecated\x12/\n\x13\x64\x65precation_warning\x18\x03 \x01(\tR\x12\x64\x65precationWarning\x12\x41\n\x0f\x65\x64ition_removed\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0e\x65\x64itionRemoved\x12#\n\rremoval_error\x18\x05 \x01(\tR\x0cremovalError\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02\"U\n\x0fOptionRetention\x12\x15\n\x11RETENTION_UNKNOWN\x10\x00\x12\x15\n\x11RETENTION_RUNTIME\x10\x01\x12\x14\n\x10RETENTION_SOURCE\x10\x02\"\x8c\x02\n\x10OptionTargetType\x12\x17\n\x13TARGET_TYPE_UNKNOWN\x10\x00\x12\x14\n\x10TARGET_TYPE_FILE\x10\x01\x12\x1f\n\x1bTARGET_TYPE_EXTENSION_RANGE\x10\x02\x12\x17\n\x13TARGET_TYPE_MESSAGE\x10\x03\x12\x15\n\x11TARGET_TYPE_FIELD\x10\x04\x12\x15\n\x11TARGET_TYPE_ONEOF\x10\x05\x12\x14\n\x10TARGET_TYPE_ENUM\x10\x06\x12\x1a\n\x16TARGET_TYPE_ENUM_ENTRY\x10\x07\x12\x17\n\x13TARGET_TYPE_SERVICE\x10\x08\x12\x16\n\x12TARGET_TYPE_METHOD\x10\t*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x12\x10\x13\"\xb4\x01\n\x0cOneofOptions\x12\x37\n\x08\x66\x65\x61tures\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd9\x02\n\x0b\x45numOptions\x12\x1f\n\x0b\x61llow_alias\x18\x02 \x01(\x08R\nallowAlias\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12V\n&deprecated_legacy_json_field_conflicts\x18\x06 \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x07 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"\xe0\x02\n\x10\x45numValueOptions\x12%\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x37\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12(\n\x0c\x64\x65\x62ug_redact\x18\x03 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12U\n\x0f\x66\x65\x61ture_support\x18\x04 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xdd\x01\n\x0eServiceOptions\x12\x37\n\x08\x66\x65\x61tures\x18\" \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xa1\x03\n\rMethodOptions\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12q\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWNR\x10idempotencyLevel\x12\x37\n\x08\x66\x65\x61tures\x18# \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9a\x03\n\x13UninterpretedOption\x12\x41\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePartR\x04name\x12)\n\x10identifier_value\x18\x03 \x01(\tR\x0fidentifierValue\x12,\n\x12positive_int_value\x18\x04 \x01(\x04R\x10positiveIntValue\x12,\n\x12negative_int_value\x18\x05 \x01(\x03R\x10negativeIntValue\x12!\n\x0c\x64ouble_value\x18\x06 \x01(\x01R\x0b\x64oubleValue\x12!\n\x0cstring_value\x18\x07 \x01(\x0cR\x0bstringValue\x12\'\n\x0f\x61ggregate_value\x18\x08 \x01(\tR\x0e\x61ggregateValue\x1aJ\n\x08NamePart\x12\x1b\n\tname_part\x18\x01 \x02(\tR\x08namePart\x12!\n\x0cis_extension\x18\x02 \x02(\x08R\x0bisExtension\"\xfd\x11\n\nFeatureSet\x12\x91\x01\n\x0e\x66ield_presence\x18\x01 \x01(\x0e\x32).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPLICIT\x18\x84\x07\xa2\x01\r\x12\x08IMPLICIT\x18\xe7\x07\xa2\x01\r\x12\x08\x45XPLICIT\x18\xe8\x07\xb2\x01\x03\x08\xe8\x07R\rfieldPresence\x12l\n\tenum_type\x18\x02 \x01(\x0e\x32$.google.protobuf.FeatureSet.EnumTypeB)\x88\x01\x01\x98\x01\x06\x98\x01\x01\xa2\x01\x0b\x12\x06\x43LOSED\x18\x84\x07\xa2\x01\t\x12\x04OPEN\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x08\x65numType\x12\x98\x01\n\x17repeated_field_encoding\x18\x03 \x01(\x0e\x32\x31.google.protobuf.FeatureSet.RepeatedFieldEncodingB-\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPANDED\x18\x84\x07\xa2\x01\x0b\x12\x06PACKED\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x15repeatedFieldEncoding\x12~\n\x0futf8_validation\x18\x04 \x01(\x0e\x32*.google.protobuf.FeatureSet.Utf8ValidationB)\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\t\x12\x04NONE\x18\x84\x07\xa2\x01\x0b\x12\x06VERIFY\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x0eutf8Validation\x12~\n\x10message_encoding\x18\x05 \x01(\x0e\x32+.google.protobuf.FeatureSet.MessageEncodingB&\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\x14\x12\x0fLENGTH_PREFIXED\x18\x84\x07\xb2\x01\x03\x08\xe8\x07R\x0fmessageEncoding\x12\x82\x01\n\x0bjson_format\x18\x06 \x01(\x0e\x32&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\x07\xa2\x01\n\x12\x05\x41LLOW\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\njsonFormat\x12\xbc\x01\n\x14\x65nforce_naming_style\x18\x07 \x01(\x0e\x32..google.protobuf.FeatureSet.EnforceNamingStyleBZ\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\x07\x98\x01\x08\x98\x01\t\xa2\x01\x11\x12\x0cSTYLE_LEGACY\x18\x84\x07\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\x07\xa2\x01\x0e\x12\tSTYLE2026\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x12\x65nforceNamingStyle\x12\xc7\x01\n\x19\x64\x65\x66\x61ult_symbol_visibility\x18\x08 \x01(\x0e\x32\x45.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityBD\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\nEXPORT_ALL\x18\x84\x07\xa2\x01\x15\x12\x10\x45XPORT_TOP_LEVEL\x18\xe9\x07\xa2\x01\x0b\x12\x06STRICT\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x17\x64\x65\x66\x61ultSymbolVisibility\x12\xc3\x01\n\x14\x65nforce_proto_limits\x18\t \x01(\x0e\x32\x41.google.protobuf.FeatureSet.ProtoLimitsFeature.EnforceProtoLimitsBN\x88\x01\x02\x98\x01\x06\x98\x01\x03\x98\x01\x04\x98\x01\x05\xa2\x01\x1e\x12\x19LEGACY_NO_EXPLICIT_LIMITS\x18\x84\x07\xa2\x01\x15\x12\x10PROTO_LIMITS2026\x18\xea\x07\xb2\x01\x03\x08\xea\x07R\x12\x65nforceProtoLimits\x1a\xa1\x01\n\x11VisibilityFeature\"\x81\x01\n\x17\x44\x65\x66\x61ultSymbolVisibility\x12%\n!DEFAULT_SYMBOL_VISIBILITY_UNKNOWN\x10\x00\x12\x0e\n\nEXPORT_ALL\x10\x01\x12\x14\n\x10\x45XPORT_TOP_LEVEL\x10\x02\x12\r\n\tLOCAL_ALL\x10\x03\x12\n\n\x06STRICT\x10\x04J\x08\x08\x01\x10\x80\x80\x80\x80\x02\x1ay\n\x12ProtoLimitsFeature\"c\n\x12\x45nforceProtoLimits\x12\x18\n\x14PROTO_LIMITS_UNKNOWN\x10\x00\x12\x1d\n\x19LEGACY_NO_EXPLICIT_LIMITS\x10\x01\x12\x14\n\x10PROTO_LIMITS2026\x10\x02\"\\\n\rFieldPresence\x12\x1a\n\x16\x46IELD_PRESENCE_UNKNOWN\x10\x00\x12\x0c\n\x08\x45XPLICIT\x10\x01\x12\x0c\n\x08IMPLICIT\x10\x02\x12\x13\n\x0fLEGACY_REQUIRED\x10\x03\"7\n\x08\x45numType\x12\x15\n\x11\x45NUM_TYPE_UNKNOWN\x10\x00\x12\x08\n\x04OPEN\x10\x01\x12\n\n\x06\x43LOSED\x10\x02\"V\n\x15RepeatedFieldEncoding\x12#\n\x1fREPEATED_FIELD_ENCODING_UNKNOWN\x10\x00\x12\n\n\x06PACKED\x10\x01\x12\x0c\n\x08\x45XPANDED\x10\x02\"I\n\x0eUtf8Validation\x12\x1b\n\x17UTF8_VALIDATION_UNKNOWN\x10\x00\x12\n\n\x06VERIFY\x10\x02\x12\x08\n\x04NONE\x10\x03\"\x04\x08\x01\x10\x01\"S\n\x0fMessageEncoding\x12\x1c\n\x18MESSAGE_ENCODING_UNKNOWN\x10\x00\x12\x13\n\x0fLENGTH_PREFIXED\x10\x01\x12\r\n\tDELIMITED\x10\x02\"H\n\nJsonFormat\x12\x17\n\x13JSON_FORMAT_UNKNOWN\x10\x00\x12\t\n\x05\x41LLOW\x10\x01\x12\x16\n\x12LEGACY_BEST_EFFORT\x10\x02\"f\n\x12\x45nforceNamingStyle\x12 \n\x1c\x45NFORCE_NAMING_STYLE_UNKNOWN\x10\x00\x12\r\n\tSTYLE2024\x10\x01\x12\x10\n\x0cSTYLE_LEGACY\x10\x02\x12\r\n\tSTYLE2026\x10\x03*\x06\x08\xe8\x07\x10\x8bN*\x06\x08\x8bN\x10\x90N*\x06\x08\x90N\x10\x91NJ\x06\x08\xe7\x07\x10\xe8\x07\"\xef\x03\n\x12\x46\x65\x61tureSetDefaults\x12X\n\x08\x64\x65\x66\x61ults\x18\x01 \x03(\x0b\x32<.google.protobuf.FeatureSetDefaults.FeatureSetEditionDefaultR\x08\x64\x65\x66\x61ults\x12\x41\n\x0fminimum_edition\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0eminimumEdition\x12\x41\n\x0fmaximum_edition\x18\x05 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0emaximumEdition\x1a\xf8\x01\n\x18\x46\x65\x61tureSetEditionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12N\n\x14overridable_features\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x13overridableFeatures\x12\x42\n\x0e\x66ixed_features\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\rfixedFeaturesJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03R\x08\x66\x65\x61tures\"\xb5\x02\n\x0eSourceCodeInfo\x12\x44\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.LocationR\x08location\x1a\xce\x01\n\x08Location\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x16\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01R\x04span\x12)\n\x10leading_comments\x18\x03 \x01(\tR\x0fleadingComments\x12+\n\x11trailing_comments\x18\x04 \x01(\tR\x10trailingComments\x12:\n\x19leading_detached_comments\x18\x06 \x03(\tR\x17leadingDetachedComments*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xd0\x02\n\x11GeneratedCodeInfo\x12M\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.AnnotationR\nannotation\x1a\xeb\x01\n\nAnnotation\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x1f\n\x0bsource_file\x18\x02 \x01(\tR\nsourceFile\x12\x14\n\x05\x62\x65gin\x18\x03 \x01(\x05R\x05\x62\x65gin\x12\x10\n\x03\x65nd\x18\x04 \x01(\x05R\x03\x65nd\x12R\n\x08semantic\x18\x05 \x01(\x0e\x32\x36.google.protobuf.GeneratedCodeInfo.Annotation.SemanticR\x08semantic\"(\n\x08Semantic\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03SET\x10\x01\x12\t\n\x05\x41LIAS\x10\x02*\xd1\x02\n\x07\x45\x64ition\x12\x13\n\x0f\x45\x44ITION_UNKNOWN\x10\x00\x12\x13\n\x0e\x45\x44ITION_LEGACY\x10\x84\x07\x12\x13\n\x0e\x45\x44ITION_PROTO2\x10\xe6\x07\x12\x13\n\x0e\x45\x44ITION_PROTO3\x10\xe7\x07\x12\x11\n\x0c\x45\x44ITION_2023\x10\xe8\x07\x12\x11\n\x0c\x45\x44ITION_2024\x10\xe9\x07\x12\x11\n\x0c\x45\x44ITION_2026\x10\xea\x07\x12\x15\n\x10\x45\x44ITION_UNSTABLE\x10\x8fN\x12\x17\n\x13\x45\x44ITION_1_TEST_ONLY\x10\x01\x12\x17\n\x13\x45\x44ITION_2_TEST_ONLY\x10\x02\x12\x1d\n\x17\x45\x44ITION_99997_TEST_ONLY\x10\x9d\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99998_TEST_ONLY\x10\x9e\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99999_TEST_ONLY\x10\x9f\x8d\x06\x12\x13\n\x0b\x45\x44ITION_MAX\x10\xff\xff\xff\xff\x07*U\n\x10SymbolVisibility\x12\x14\n\x10VISIBILITY_UNSET\x10\x00\x12\x14\n\x10VISIBILITY_LOCAL\x10\x01\x12\x15\n\x11VISIBILITY_EXPORT\x10\x02\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection' - ) -else: - DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"[\n\x11\x46ileDescriptorSet\x12\x38\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProtoR\x04\x66ile*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xc5\x05\n\x13\x46ileDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n\x07package\x18\x02 \x01(\tR\x07package\x12\x1e\n\ndependency\x18\x03 \x03(\tR\ndependency\x12+\n\x11public_dependency\x18\n \x03(\x05R\x10publicDependency\x12\'\n\x0fweak_dependency\x18\x0b \x03(\x05R\x0eweakDependency\x12+\n\x11option_dependency\x18\x0f \x03(\tR\x10optionDependency\x12\x43\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\x0bmessageType\x12\x41\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12\x41\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProtoR\x07service\x12\x43\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x36\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptionsR\x07options\x12I\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfoR\x0esourceCodeInfo\x12\x16\n\x06syntax\x18\x0c \x01(\tR\x06syntax\x12\x32\n\x07\x65\x64ition\x18\x0e \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\"\xfc\x06\n\x0f\x44\x65scriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12;\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\x05\x66ield\x12\x43\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProtoR\textension\x12\x41\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProtoR\nnestedType\x12\x41\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProtoR\x08\x65numType\x12X\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRangeR\x0e\x65xtensionRange\x12\x44\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProtoR\toneofDecl\x12\x39\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptionsR\x07options\x12U\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\n \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x0b \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1az\n\x0e\x45xtensionRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\x12@\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptionsR\x07options\x1a\x37\n\rReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\xd4\x04\n\x15\x45xtensionRangeOptions\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x12Y\n\x0b\x64\x65\x63laration\x18\x02 \x03(\x0b\x32\x32.google.protobuf.ExtensionRangeOptions.DeclarationB\x03\x88\x01\x02R\x0b\x64\x65\x63laration\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12m\n\x0cverification\x18\x03 \x01(\x0e\x32\x38.google.protobuf.ExtensionRangeOptions.VerificationState:\nUNVERIFIEDB\x03\x88\x01\x02R\x0cverification\x1a\x94\x01\n\x0b\x44\x65\x63laration\x12\x16\n\x06number\x18\x01 \x01(\x05R\x06number\x12\x1b\n\tfull_name\x18\x02 \x01(\tR\x08\x66ullName\x12\x12\n\x04type\x18\x03 \x01(\tR\x04type\x12\x1a\n\x08reserved\x18\x05 \x01(\x08R\x08reserved\x12\x1a\n\x08repeated\x18\x06 \x01(\x08R\x08repeatedJ\x04\x08\x04\x10\x05\"4\n\x11VerificationState\x12\x0f\n\x0b\x44\x45\x43LARATION\x10\x00\x12\x0e\n\nUNVERIFIED\x10\x01*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xc1\x06\n\x14\x46ieldDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x03 \x01(\x05R\x06number\x12\x41\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.LabelR\x05label\x12>\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.TypeR\x04type\x12\x1b\n\ttype_name\x18\x06 \x01(\tR\x08typeName\x12\x1a\n\x08\x65xtendee\x18\x02 \x01(\tR\x08\x65xtendee\x12#\n\rdefault_value\x18\x07 \x01(\tR\x0c\x64\x65\x66\x61ultValue\x12\x1f\n\x0boneof_index\x18\t \x01(\x05R\noneofIndex\x12\x1b\n\tjson_name\x18\n \x01(\tR\x08jsonName\x12\x37\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptionsR\x07options\x12\'\n\x0fproto3_optional\x18\x11 \x01(\x08R\x0eproto3Optional\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REPEATED\x10\x03\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\"c\n\x14OneofDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x37\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptionsR\x07options\"\xa6\x03\n\x13\x45numDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12?\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProtoR\x05value\x12\x36\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptionsR\x07options\x12]\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRangeR\rreservedRange\x12#\n\rreserved_name\x18\x05 \x03(\tR\x0creservedName\x12\x41\n\nvisibility\x18\x06 \x01(\x0e\x32!.google.protobuf.SymbolVisibilityR\nvisibility\x1a;\n\x11\x45numReservedRange\x12\x14\n\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n\x03\x65nd\x18\x02 \x01(\x05R\x03\x65nd\"\x83\x01\n\x18\x45numValueDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x02 \x01(\x05R\x06number\x12;\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptionsR\x07options\"\xb5\x01\n\x16ServiceDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12>\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProtoR\x06method\x12\x39\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptionsR\x07optionsJ\x04\x08\x04\x10\x05R\x06stream\"\x89\x02\n\x15MethodDescriptorProto\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x1d\n\ninput_type\x18\x02 \x01(\tR\tinputType\x12\x1f\n\x0boutput_type\x18\x03 \x01(\tR\noutputType\x12\x38\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptionsR\x07options\x12\x30\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lseR\x0f\x63lientStreaming\x12\x30\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lseR\x0fserverStreaming\"\x8c\x0c\n\x0b\x46ileOptions\x12!\n\x0cjava_package\x18\x01 \x01(\tR\x0bjavaPackage\x12\x30\n\x14java_outer_classname\x18\x08 \x01(\tR\x12javaOuterClassname\x12\xf9\x01\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lseB\xc1\x01\xb2\x01\xbd\x01\x08\xe6\x07 \xe9\x07*\xb4\x01This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.R\x11javaMultipleFiles\x12\x44\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01R\x19javaGenerateEqualsAndHash\x12:\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lseR\x13javaStringCheckUtf8\x12S\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEEDR\x0boptimizeFor\x12\x1d\n\ngo_package\x18\x0b \x01(\tR\tgoPackage\x12\x35\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lseR\x11\x63\x63GenericServices\x12\x39\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lseR\x13javaGenericServices\x12\x35\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lseR\x11pyGenericServices\x12%\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\xbf\x01\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04trueB\x8e\x01\xb2\x01\x8a\x01 \xea\x07*\x84\x01\x63\x63_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.R\x0e\x63\x63\x45nableArenas\x12*\n\x11objc_class_prefix\x18$ \x01(\tR\x0fobjcClassPrefix\x12)\n\x10\x63sharp_namespace\x18% \x01(\tR\x0f\x63sharpNamespace\x12!\n\x0cswift_prefix\x18\' \x01(\tR\x0bswiftPrefix\x12(\n\x10php_class_prefix\x18( \x01(\tR\x0ephpClassPrefix\x12#\n\rphp_namespace\x18) \x01(\tR\x0cphpNamespace\x12\x34\n\x16php_metadata_namespace\x18, \x01(\tR\x14phpMetadataNamespace\x12!\n\x0cruby_package\x18- \x01(\tR\x0brubyPackage\x12\x37\n\x08\x66\x65\x61tures\x18\x32 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08*\x10+J\x04\x08&\x10\'R\x14php_generic_services\"\xfc\x03\n\x0eMessageOptions\x12<\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lseR\x14messageSetWireFormat\x12L\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lseR\x1cnoStandardDescriptorAccessor\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1b\n\tmap_entry\x18\x07 \x01(\x08R\x08mapEntry\x12V\n&deprecated_legacy_json_field_conflicts\x18\x0b \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x0c \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xce\r\n\x0c\x46ieldOptions\x12\x41\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRINGR\x05\x63type\x12\x16\n\x06packed\x18\x02 \x01(\x08R\x06packed\x12G\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMALR\x06jstype\x12\x19\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lseR\x04lazy\x12.\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lseR\x0eunverifiedLazy\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x1d\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lseB\x02\x18\x01R\x04weak\x12(\n\x0c\x64\x65\x62ug_redact\x18\x10 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12K\n\tretention\x18\x11 \x01(\x0e\x32-.google.protobuf.FieldOptions.OptionRetentionR\tretention\x12H\n\x07targets\x18\x13 \x03(\x0e\x32..google.protobuf.FieldOptions.OptionTargetTypeR\x07targets\x12W\n\x10\x65\x64ition_defaults\x18\x14 \x03(\x0b\x32,.google.protobuf.FieldOptions.EditionDefaultR\x0f\x65\x64itionDefaults\x12\x37\n\x08\x66\x65\x61tures\x18\x15 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12U\n\x0f\x66\x65\x61ture_support\x18\x16 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\x1aZ\n\x0e\x45\x64itionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value\x1a\xbb\x02\n\x0e\x46\x65\x61tureSupport\x12G\n\x12\x65\x64ition_introduced\x18\x01 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionIntroduced\x12G\n\x12\x65\x64ition_deprecated\x18\x02 \x01(\x0e\x32\x18.google.protobuf.EditionR\x11\x65\x64itionDeprecated\x12/\n\x13\x64\x65precation_warning\x18\x03 \x01(\tR\x12\x64\x65precationWarning\x12\x41\n\x0f\x65\x64ition_removed\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0e\x65\x64itionRemoved\x12#\n\rremoval_error\x18\x05 \x01(\tR\x0cremovalError\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02\"U\n\x0fOptionRetention\x12\x15\n\x11RETENTION_UNKNOWN\x10\x00\x12\x15\n\x11RETENTION_RUNTIME\x10\x01\x12\x14\n\x10RETENTION_SOURCE\x10\x02\"\x8c\x02\n\x10OptionTargetType\x12\x17\n\x13TARGET_TYPE_UNKNOWN\x10\x00\x12\x14\n\x10TARGET_TYPE_FILE\x10\x01\x12\x1f\n\x1bTARGET_TYPE_EXTENSION_RANGE\x10\x02\x12\x17\n\x13TARGET_TYPE_MESSAGE\x10\x03\x12\x15\n\x11TARGET_TYPE_FIELD\x10\x04\x12\x15\n\x11TARGET_TYPE_ONEOF\x10\x05\x12\x14\n\x10TARGET_TYPE_ENUM\x10\x06\x12\x1a\n\x16TARGET_TYPE_ENUM_ENTRY\x10\x07\x12\x17\n\x13TARGET_TYPE_SERVICE\x10\x08\x12\x16\n\x12TARGET_TYPE_METHOD\x10\t*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x12\x10\x13\"\xb4\x01\n\x0cOneofOptions\x12\x37\n\x08\x66\x65\x61tures\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd9\x02\n\x0b\x45numOptions\x12\x1f\n\x0b\x61llow_alias\x18\x02 \x01(\x08R\nallowAlias\x12%\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12V\n&deprecated_legacy_json_field_conflicts\x18\x06 \x01(\x08\x42\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x12\x37\n\x08\x66\x65\x61tures\x18\x07 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"\xe0\x02\n\x10\x45numValueOptions\x12%\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12\x37\n\x08\x66\x65\x61tures\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12(\n\x0c\x64\x65\x62ug_redact\x18\x03 \x01(\x08:\x05\x66\x61lseR\x0b\x64\x65\x62ugRedact\x12U\n\x0f\x66\x65\x61ture_support\x18\x04 \x01(\x0b\x32,.google.protobuf.FieldOptions.FeatureSupportR\x0e\x66\x65\x61tureSupport\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xdd\x01\n\x0eServiceOptions\x12\x37\n\x08\x66\x65\x61tures\x18\" \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xa1\x03\n\rMethodOptions\x12%\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lseR\ndeprecated\x12q\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWNR\x10idempotencyLevel\x12\x37\n\x08\x66\x65\x61tures\x18# \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x08\x66\x65\x61tures\x12X\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\x06\x08\xde\x07\x10\xe7\x07*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9a\x03\n\x13UninterpretedOption\x12\x41\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePartR\x04name\x12)\n\x10identifier_value\x18\x03 \x01(\tR\x0fidentifierValue\x12,\n\x12positive_int_value\x18\x04 \x01(\x04R\x10positiveIntValue\x12,\n\x12negative_int_value\x18\x05 \x01(\x03R\x10negativeIntValue\x12!\n\x0c\x64ouble_value\x18\x06 \x01(\x01R\x0b\x64oubleValue\x12!\n\x0cstring_value\x18\x07 \x01(\x0cR\x0bstringValue\x12\'\n\x0f\x61ggregate_value\x18\x08 \x01(\tR\x0e\x61ggregateValue\x1aJ\n\x08NamePart\x12\x1b\n\tname_part\x18\x01 \x02(\tR\x08namePart\x12!\n\x0cis_extension\x18\x02 \x02(\x08R\x0bisExtension\"\xfd\x11\n\nFeatureSet\x12\x91\x01\n\x0e\x66ield_presence\x18\x01 \x01(\x0e\x32).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPLICIT\x18\x84\x07\xa2\x01\r\x12\x08IMPLICIT\x18\xe7\x07\xa2\x01\r\x12\x08\x45XPLICIT\x18\xe8\x07\xb2\x01\x03\x08\xe8\x07R\rfieldPresence\x12l\n\tenum_type\x18\x02 \x01(\x0e\x32$.google.protobuf.FeatureSet.EnumTypeB)\x88\x01\x01\x98\x01\x06\x98\x01\x01\xa2\x01\x0b\x12\x06\x43LOSED\x18\x84\x07\xa2\x01\t\x12\x04OPEN\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x08\x65numType\x12\x98\x01\n\x17repeated_field_encoding\x18\x03 \x01(\x0e\x32\x31.google.protobuf.FeatureSet.RepeatedFieldEncodingB-\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\x08\x45XPANDED\x18\x84\x07\xa2\x01\x0b\x12\x06PACKED\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x15repeatedFieldEncoding\x12~\n\x0futf8_validation\x18\x04 \x01(\x0e\x32*.google.protobuf.FeatureSet.Utf8ValidationB)\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\t\x12\x04NONE\x18\x84\x07\xa2\x01\x0b\x12\x06VERIFY\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\x0eutf8Validation\x12~\n\x10message_encoding\x18\x05 \x01(\x0e\x32+.google.protobuf.FeatureSet.MessageEncodingB&\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\x14\x12\x0fLENGTH_PREFIXED\x18\x84\x07\xb2\x01\x03\x08\xe8\x07R\x0fmessageEncoding\x12\x82\x01\n\x0bjson_format\x18\x06 \x01(\x0e\x32&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\x07\xa2\x01\n\x12\x05\x41LLOW\x18\xe7\x07\xb2\x01\x03\x08\xe8\x07R\njsonFormat\x12\xbc\x01\n\x14\x65nforce_naming_style\x18\x07 \x01(\x0e\x32..google.protobuf.FeatureSet.EnforceNamingStyleBZ\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\x07\x98\x01\x08\x98\x01\t\xa2\x01\x11\x12\x0cSTYLE_LEGACY\x18\x84\x07\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\x07\xa2\x01\x0e\x12\tSTYLE2026\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x12\x65nforceNamingStyle\x12\xc7\x01\n\x19\x64\x65\x66\x61ult_symbol_visibility\x18\x08 \x01(\x0e\x32\x45.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityBD\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\nEXPORT_ALL\x18\x84\x07\xa2\x01\x15\x12\x10\x45XPORT_TOP_LEVEL\x18\xe9\x07\xa2\x01\x0b\x12\x06STRICT\x18\xea\x07\xb2\x01\x03\x08\xe9\x07R\x17\x64\x65\x66\x61ultSymbolVisibility\x12\xc3\x01\n\x14\x65nforce_proto_limits\x18\t \x01(\x0e\x32\x41.google.protobuf.FeatureSet.ProtoLimitsFeature.EnforceProtoLimitsBN\x88\x01\x02\x98\x01\x06\x98\x01\x03\x98\x01\x04\x98\x01\x05\xa2\x01\x1e\x12\x19LEGACY_NO_EXPLICIT_LIMITS\x18\x84\x07\xa2\x01\x15\x12\x10PROTO_LIMITS2026\x18\xea\x07\xb2\x01\x03\x08\xea\x07R\x12\x65nforceProtoLimits\x1a\xa1\x01\n\x11VisibilityFeature\"\x81\x01\n\x17\x44\x65\x66\x61ultSymbolVisibility\x12%\n!DEFAULT_SYMBOL_VISIBILITY_UNKNOWN\x10\x00\x12\x0e\n\nEXPORT_ALL\x10\x01\x12\x14\n\x10\x45XPORT_TOP_LEVEL\x10\x02\x12\r\n\tLOCAL_ALL\x10\x03\x12\n\n\x06STRICT\x10\x04J\x08\x08\x01\x10\x80\x80\x80\x80\x02\x1ay\n\x12ProtoLimitsFeature\"c\n\x12\x45nforceProtoLimits\x12\x18\n\x14PROTO_LIMITS_UNKNOWN\x10\x00\x12\x1d\n\x19LEGACY_NO_EXPLICIT_LIMITS\x10\x01\x12\x14\n\x10PROTO_LIMITS2026\x10\x02\"\\\n\rFieldPresence\x12\x1a\n\x16\x46IELD_PRESENCE_UNKNOWN\x10\x00\x12\x0c\n\x08\x45XPLICIT\x10\x01\x12\x0c\n\x08IMPLICIT\x10\x02\x12\x13\n\x0fLEGACY_REQUIRED\x10\x03\"7\n\x08\x45numType\x12\x15\n\x11\x45NUM_TYPE_UNKNOWN\x10\x00\x12\x08\n\x04OPEN\x10\x01\x12\n\n\x06\x43LOSED\x10\x02\"V\n\x15RepeatedFieldEncoding\x12#\n\x1fREPEATED_FIELD_ENCODING_UNKNOWN\x10\x00\x12\n\n\x06PACKED\x10\x01\x12\x0c\n\x08\x45XPANDED\x10\x02\"I\n\x0eUtf8Validation\x12\x1b\n\x17UTF8_VALIDATION_UNKNOWN\x10\x00\x12\n\n\x06VERIFY\x10\x02\x12\x08\n\x04NONE\x10\x03\"\x04\x08\x01\x10\x01\"S\n\x0fMessageEncoding\x12\x1c\n\x18MESSAGE_ENCODING_UNKNOWN\x10\x00\x12\x13\n\x0fLENGTH_PREFIXED\x10\x01\x12\r\n\tDELIMITED\x10\x02\"H\n\nJsonFormat\x12\x17\n\x13JSON_FORMAT_UNKNOWN\x10\x00\x12\t\n\x05\x41LLOW\x10\x01\x12\x16\n\x12LEGACY_BEST_EFFORT\x10\x02\"f\n\x12\x45nforceNamingStyle\x12 \n\x1c\x45NFORCE_NAMING_STYLE_UNKNOWN\x10\x00\x12\r\n\tSTYLE2024\x10\x01\x12\x10\n\x0cSTYLE_LEGACY\x10\x02\x12\r\n\tSTYLE2026\x10\x03*\x06\x08\xe8\x07\x10\x8bN*\x06\x08\x8bN\x10\x90N*\x06\x08\x90N\x10\x91NJ\x06\x08\xe7\x07\x10\xe8\x07\"\xef\x03\n\x12\x46\x65\x61tureSetDefaults\x12X\n\x08\x64\x65\x66\x61ults\x18\x01 \x03(\x0b\x32<.google.protobuf.FeatureSetDefaults.FeatureSetEditionDefaultR\x08\x64\x65\x66\x61ults\x12\x41\n\x0fminimum_edition\x18\x04 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0eminimumEdition\x12\x41\n\x0fmaximum_edition\x18\x05 \x01(\x0e\x32\x18.google.protobuf.EditionR\x0emaximumEdition\x1a\xf8\x01\n\x18\x46\x65\x61tureSetEditionDefault\x12\x32\n\x07\x65\x64ition\x18\x03 \x01(\x0e\x32\x18.google.protobuf.EditionR\x07\x65\x64ition\x12N\n\x14overridable_features\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\x13overridableFeatures\x12\x42\n\x0e\x66ixed_features\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.FeatureSetR\rfixedFeaturesJ\x04\x08\x01\x10\x02J\x04\x08\x02\x10\x03R\x08\x66\x65\x61tures\"\xb5\x02\n\x0eSourceCodeInfo\x12\x44\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.LocationR\x08location\x1a\xce\x01\n\x08Location\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x16\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01R\x04span\x12)\n\x10leading_comments\x18\x03 \x01(\tR\x0fleadingComments\x12+\n\x11trailing_comments\x18\x04 \x01(\tR\x10trailingComments\x12:\n\x19leading_detached_comments\x18\x06 \x03(\tR\x17leadingDetachedComments*\x0c\x08\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xd0\x02\n\x11GeneratedCodeInfo\x12M\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.AnnotationR\nannotation\x1a\xeb\x01\n\nAnnotation\x12\x16\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01R\x04path\x12\x1f\n\x0bsource_file\x18\x02 \x01(\tR\nsourceFile\x12\x14\n\x05\x62\x65gin\x18\x03 \x01(\x05R\x05\x62\x65gin\x12\x10\n\x03\x65nd\x18\x04 \x01(\x05R\x03\x65nd\x12R\n\x08semantic\x18\x05 \x01(\x0e\x32\x36.google.protobuf.GeneratedCodeInfo.Annotation.SemanticR\x08semantic\"(\n\x08Semantic\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03SET\x10\x01\x12\t\n\x05\x41LIAS\x10\x02*\xd1\x02\n\x07\x45\x64ition\x12\x13\n\x0f\x45\x44ITION_UNKNOWN\x10\x00\x12\x13\n\x0e\x45\x44ITION_LEGACY\x10\x84\x07\x12\x13\n\x0e\x45\x44ITION_PROTO2\x10\xe6\x07\x12\x13\n\x0e\x45\x44ITION_PROTO3\x10\xe7\x07\x12\x11\n\x0c\x45\x44ITION_2023\x10\xe8\x07\x12\x11\n\x0c\x45\x44ITION_2024\x10\xe9\x07\x12\x11\n\x0c\x45\x44ITION_2026\x10\xea\x07\x12\x15\n\x10\x45\x44ITION_UNSTABLE\x10\x8fN\x12\x17\n\x13\x45\x44ITION_1_TEST_ONLY\x10\x01\x12\x17\n\x13\x45\x44ITION_2_TEST_ONLY\x10\x02\x12\x1d\n\x17\x45\x44ITION_99997_TEST_ONLY\x10\x9d\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99998_TEST_ONLY\x10\x9e\x8d\x06\x12\x1d\n\x17\x45\x44ITION_99999_TEST_ONLY\x10\x9f\x8d\x06\x12\x13\n\x0b\x45\x44ITION_MAX\x10\xff\xff\xff\xff\x07*U\n\x10SymbolVisibility\x12\x14\n\x10VISIBILITY_UNSET\x10\x00\x12\x14\n\x10VISIBILITY_LOCAL\x10\x01\x12\x15\n\x11VISIBILITY_EXPORT\x10\x02\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection') - -_globals = globals() -if not _descriptor._USE_C_DESCRIPTORS: - _EDITION = _descriptor.EnumDescriptor( - name='Edition', - full_name='google.protobuf.Edition', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='EDITION_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_LEGACY', index=1, number=900, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_PROTO2', index=2, number=998, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_PROTO3', index=3, number=999, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_2023', index=4, number=1000, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_2024', index=5, number=1001, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_2026', index=6, number=1002, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_UNSTABLE', index=7, number=9999, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_1_TEST_ONLY', index=8, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_2_TEST_ONLY', index=9, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_99997_TEST_ONLY', index=10, number=99997, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_99998_TEST_ONLY', index=11, number=99998, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_99999_TEST_ONLY', index=12, number=99999, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EDITION_MAX', index=13, number=2147483647, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_EDITION) - - _SYMBOLVISIBILITY = _descriptor.EnumDescriptor( - name='SymbolVisibility', - full_name='google.protobuf.SymbolVisibility', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='VISIBILITY_UNSET', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='VISIBILITY_LOCAL', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='VISIBILITY_EXPORT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_SYMBOLVISIBILITY) - - _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE = _descriptor.EnumDescriptor( - name='VerificationState', - full_name='google.protobuf.ExtensionRangeOptions.VerificationState', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='DECLARATION', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='UNVERIFIED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE) - - _FIELDDESCRIPTORPROTO_TYPE = _descriptor.EnumDescriptor( - name='Type', - full_name='google.protobuf.FieldDescriptorProto.Type', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='TYPE_DOUBLE', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FLOAT', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_INT64', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_UINT64', index=3, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_INT32', index=4, number=5, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FIXED64', index=5, number=6, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FIXED32', index=6, number=7, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_BOOL', index=7, number=8, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_STRING', index=8, number=9, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_GROUP', index=9, number=10, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_MESSAGE', index=10, number=11, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_BYTES', index=11, number=12, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_UINT32', index=12, number=13, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_ENUM', index=13, number=14, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SFIXED32', index=14, number=15, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SFIXED64', index=15, number=16, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SINT32', index=16, number=17, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SINT64', index=17, number=18, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_TYPE) - - _FIELDDESCRIPTORPROTO_LABEL = _descriptor.EnumDescriptor( - name='Label', - full_name='google.protobuf.FieldDescriptorProto.Label', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='LABEL_OPTIONAL', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LABEL_REPEATED', index=1, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LABEL_REQUIRED', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_LABEL) - - _FILEOPTIONS_OPTIMIZEMODE = _descriptor.EnumDescriptor( - name='OptimizeMode', - full_name='google.protobuf.FileOptions.OptimizeMode', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SPEED', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CODE_SIZE', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LITE_RUNTIME', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FILEOPTIONS_OPTIMIZEMODE) - - _FIELDOPTIONS_CTYPE = _descriptor.EnumDescriptor( - name='CType', - full_name='google.protobuf.FieldOptions.CType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='STRING', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CORD', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='STRING_PIECE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_CTYPE) - - _FIELDOPTIONS_JSTYPE = _descriptor.EnumDescriptor( - name='JSType', - full_name='google.protobuf.FieldOptions.JSType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='JS_NORMAL', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='JS_STRING', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='JS_NUMBER', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_JSTYPE) - - _FIELDOPTIONS_OPTIONRETENTION = _descriptor.EnumDescriptor( - name='OptionRetention', - full_name='google.protobuf.FieldOptions.OptionRetention', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='RETENTION_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='RETENTION_RUNTIME', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='RETENTION_SOURCE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_OPTIONRETENTION) - - _FIELDOPTIONS_OPTIONTARGETTYPE = _descriptor.EnumDescriptor( - name='OptionTargetType', - full_name='google.protobuf.FieldOptions.OptionTargetType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_FILE', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_EXTENSION_RANGE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_MESSAGE', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_FIELD', index=4, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_ONEOF', index=5, number=5, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_ENUM', index=6, number=6, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_ENUM_ENTRY', index=7, number=7, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_SERVICE', index=8, number=8, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TARGET_TYPE_METHOD', index=9, number=9, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_OPTIONTARGETTYPE) - - _METHODOPTIONS_IDEMPOTENCYLEVEL = _descriptor.EnumDescriptor( - name='IdempotencyLevel', - full_name='google.protobuf.MethodOptions.IdempotencyLevel', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='IDEMPOTENCY_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='NO_SIDE_EFFECTS', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='IDEMPOTENT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_IDEMPOTENCYLEVEL) - - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY = _descriptor.EnumDescriptor( - name='DefaultSymbolVisibility', - full_name='google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='DEFAULT_SYMBOL_VISIBILITY_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EXPORT_ALL', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EXPORT_TOP_LEVEL', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LOCAL_ALL', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='STRICT', index=4, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY) - - _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS = _descriptor.EnumDescriptor( - name='EnforceProtoLimits', - full_name='google.protobuf.FeatureSet.ProtoLimitsFeature.EnforceProtoLimits', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='PROTO_LIMITS_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LEGACY_NO_EXPLICIT_LIMITS', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='PROTO_LIMITS2026', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS) - - _FEATURESET_FIELDPRESENCE = _descriptor.EnumDescriptor( - name='FieldPresence', - full_name='google.protobuf.FeatureSet.FieldPresence', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='FIELD_PRESENCE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EXPLICIT', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='IMPLICIT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LEGACY_REQUIRED', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_FIELDPRESENCE) - - _FEATURESET_ENUMTYPE = _descriptor.EnumDescriptor( - name='EnumType', - full_name='google.protobuf.FeatureSet.EnumType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='ENUM_TYPE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='OPEN', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CLOSED', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_ENUMTYPE) - - _FEATURESET_REPEATEDFIELDENCODING = _descriptor.EnumDescriptor( - name='RepeatedFieldEncoding', - full_name='google.protobuf.FeatureSet.RepeatedFieldEncoding', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='REPEATED_FIELD_ENCODING_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='PACKED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='EXPANDED', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_REPEATEDFIELDENCODING) - - _FEATURESET_UTF8VALIDATION = _descriptor.EnumDescriptor( - name='Utf8Validation', - full_name='google.protobuf.FeatureSet.Utf8Validation', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='UTF8_VALIDATION_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='VERIFY', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='NONE', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_UTF8VALIDATION) - - _FEATURESET_MESSAGEENCODING = _descriptor.EnumDescriptor( - name='MessageEncoding', - full_name='google.protobuf.FeatureSet.MessageEncoding', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='MESSAGE_ENCODING_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LENGTH_PREFIXED', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='DELIMITED', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_MESSAGEENCODING) - - _FEATURESET_JSONFORMAT = _descriptor.EnumDescriptor( - name='JsonFormat', - full_name='google.protobuf.FeatureSet.JsonFormat', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='JSON_FORMAT_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='ALLOW', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LEGACY_BEST_EFFORT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_JSONFORMAT) - - _FEATURESET_ENFORCENAMINGSTYLE = _descriptor.EnumDescriptor( - name='EnforceNamingStyle', - full_name='google.protobuf.FeatureSet.EnforceNamingStyle', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='ENFORCE_NAMING_STYLE_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='STYLE2024', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='STYLE_LEGACY', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='STYLE2026', index=3, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FEATURESET_ENFORCENAMINGSTYLE) - - _GENERATEDCODEINFO_ANNOTATION_SEMANTIC = _descriptor.EnumDescriptor( - name='Semantic', - full_name='google.protobuf.GeneratedCodeInfo.Annotation.Semantic', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='NONE', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='SET', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='ALIAS', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_GENERATEDCODEINFO_ANNOTATION_SEMANTIC) - - - _FILEDESCRIPTORSET = _descriptor.Descriptor( - name='FileDescriptorSet', - full_name='google.protobuf.FileDescriptorSet', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='file', full_name='google.protobuf.FileDescriptorSet.file', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='file', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(536000000, 536000001), ], - oneofs=[ - ], - ) - - - _FILEDESCRIPTORPROTO = _descriptor.Descriptor( - name='FileDescriptorProto', - full_name='google.protobuf.FileDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.FileDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='package', full_name='google.protobuf.FileDescriptorProto.package', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='package', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='dependency', full_name='google.protobuf.FileDescriptorProto.dependency', index=2, - number=3, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='dependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='public_dependency', full_name='google.protobuf.FileDescriptorProto.public_dependency', index=3, - number=10, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='publicDependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='weak_dependency', full_name='google.protobuf.FileDescriptorProto.weak_dependency', index=4, - number=11, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='weakDependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='option_dependency', full_name='google.protobuf.FileDescriptorProto.option_dependency', index=5, - number=15, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='optionDependency', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='message_type', full_name='google.protobuf.FileDescriptorProto.message_type', index=6, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='messageType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enum_type', full_name='google.protobuf.FileDescriptorProto.enum_type', index=7, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='enumType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service', full_name='google.protobuf.FileDescriptorProto.service', index=8, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='service', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension', full_name='google.protobuf.FileDescriptorProto.extension', index=9, - number=7, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='extension', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.FileDescriptorProto.options', index=10, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='source_code_info', full_name='google.protobuf.FileDescriptorProto.source_code_info', index=11, - number=9, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='sourceCodeInfo', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='syntax', full_name='google.protobuf.FileDescriptorProto.syntax', index=12, - number=12, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='syntax', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='edition', full_name='google.protobuf.FileDescriptorProto.edition', index=13, - number=14, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='edition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _DESCRIPTORPROTO_EXTENSIONRANGE = _descriptor.Descriptor( - name='ExtensionRange', - full_name='google.protobuf.DescriptorProto.ExtensionRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.DescriptorProto.ExtensionRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='start', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.DescriptorProto.ExtensionRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.DescriptorProto.ExtensionRange.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _DESCRIPTORPROTO_RESERVEDRANGE = _descriptor.Descriptor( - name='ReservedRange', - full_name='google.protobuf.DescriptorProto.ReservedRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.DescriptorProto.ReservedRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='start', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.DescriptorProto.ReservedRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _DESCRIPTORPROTO = _descriptor.Descriptor( - name='DescriptorProto', - full_name='google.protobuf.DescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.DescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='field', full_name='google.protobuf.DescriptorProto.field', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='field', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension', full_name='google.protobuf.DescriptorProto.extension', index=2, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='extension', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='nested_type', full_name='google.protobuf.DescriptorProto.nested_type', index=3, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='nestedType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enum_type', full_name='google.protobuf.DescriptorProto.enum_type', index=4, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='enumType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension_range', full_name='google.protobuf.DescriptorProto.extension_range', index=5, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='extensionRange', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='oneof_decl', full_name='google.protobuf.DescriptorProto.oneof_decl', index=6, - number=8, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='oneofDecl', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.DescriptorProto.options', index=7, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_range', full_name='google.protobuf.DescriptorProto.reserved_range', index=8, - number=9, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='reservedRange', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_name', full_name='google.protobuf.DescriptorProto.reserved_name', index=9, - number=10, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='reservedName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='visibility', full_name='google.protobuf.DescriptorProto.visibility', index=10, - number=11, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='visibility', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, _DESCRIPTORPROTO_RESERVEDRANGE, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _EXTENSIONRANGEOPTIONS_DECLARATION = _descriptor.Descriptor( - name='Declaration', - full_name='google.protobuf.ExtensionRangeOptions.Declaration', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='number', full_name='google.protobuf.ExtensionRangeOptions.Declaration.number', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='number', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='full_name', full_name='google.protobuf.ExtensionRangeOptions.Declaration.full_name', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='fullName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='type', full_name='google.protobuf.ExtensionRangeOptions.Declaration.type', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='type', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved', full_name='google.protobuf.ExtensionRangeOptions.Declaration.reserved', index=3, - number=5, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='reserved', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='repeated', full_name='google.protobuf.ExtensionRangeOptions.Declaration.repeated', index=4, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='repeated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _EXTENSIONRANGEOPTIONS = _descriptor.Descriptor( - name='ExtensionRangeOptions', - full_name='google.protobuf.ExtensionRangeOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.ExtensionRangeOptions.uninterpreted_option', index=0, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='declaration', full_name='google.protobuf.ExtensionRangeOptions.declaration', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\002', json_name='declaration', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.ExtensionRangeOptions.features', index=2, - number=50, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='verification', full_name='google.protobuf.ExtensionRangeOptions.verification', index=3, - number=3, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\002', json_name='verification', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_EXTENSIONRANGEOPTIONS_DECLARATION, ], - enum_types=[ - _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE, - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _FIELDDESCRIPTORPROTO = _descriptor.Descriptor( - name='FieldDescriptorProto', - full_name='google.protobuf.FieldDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.FieldDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='number', full_name='google.protobuf.FieldDescriptorProto.number', index=1, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='number', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='label', full_name='google.protobuf.FieldDescriptorProto.label', index=2, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='label', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='type', full_name='google.protobuf.FieldDescriptorProto.type', index=3, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='type', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='type_name', full_name='google.protobuf.FieldDescriptorProto.type_name', index=4, - number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='typeName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extendee', full_name='google.protobuf.FieldDescriptorProto.extendee', index=5, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='extendee', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='default_value', full_name='google.protobuf.FieldDescriptorProto.default_value', index=6, - number=7, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='defaultValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='oneof_index', full_name='google.protobuf.FieldDescriptorProto.oneof_index', index=7, - number=9, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='oneofIndex', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='json_name', full_name='google.protobuf.FieldDescriptorProto.json_name', index=8, - number=10, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='jsonName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=9, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='proto3_optional', full_name='google.protobuf.FieldDescriptorProto.proto3_optional', index=10, - number=17, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='proto3Optional', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FIELDDESCRIPTORPROTO_TYPE, - _FIELDDESCRIPTORPROTO_LABEL, - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _ONEOFDESCRIPTORPROTO = _descriptor.Descriptor( - name='OneofDescriptorProto', - full_name='google.protobuf.OneofDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.OneofDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.OneofDescriptorProto.options', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE = _descriptor.Descriptor( - name='EnumReservedRange', - full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='start', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _ENUMDESCRIPTORPROTO = _descriptor.Descriptor( - name='EnumDescriptorProto', - full_name='google.protobuf.EnumDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.EnumDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='value', full_name='google.protobuf.EnumDescriptorProto.value', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='value', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.EnumDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_range', full_name='google.protobuf.EnumDescriptorProto.reserved_range', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='reservedRange', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_name', full_name='google.protobuf.EnumDescriptorProto.reserved_name', index=4, - number=5, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='reservedName', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='visibility', full_name='google.protobuf.EnumDescriptorProto.visibility', index=5, - number=6, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='visibility', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _ENUMVALUEDESCRIPTORPROTO = _descriptor.Descriptor( - name='EnumValueDescriptorProto', - full_name='google.protobuf.EnumValueDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.EnumValueDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='number', full_name='google.protobuf.EnumValueDescriptorProto.number', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='number', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.EnumValueDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _SERVICEDESCRIPTORPROTO = _descriptor.Descriptor( - name='ServiceDescriptorProto', - full_name='google.protobuf.ServiceDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.ServiceDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='method', full_name='google.protobuf.ServiceDescriptorProto.method', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='method', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.ServiceDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _METHODDESCRIPTORPROTO = _descriptor.Descriptor( - name='MethodDescriptorProto', - full_name='google.protobuf.MethodDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.MethodDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='input_type', full_name='google.protobuf.MethodDescriptorProto.input_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='inputType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='output_type', full_name='google.protobuf.MethodDescriptorProto.output_type', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='outputType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.MethodDescriptorProto.options', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='options', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='client_streaming', full_name='google.protobuf.MethodDescriptorProto.client_streaming', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='clientStreaming', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='server_streaming', full_name='google.protobuf.MethodDescriptorProto.server_streaming', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='serverStreaming', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _FILEOPTIONS = _descriptor.Descriptor( - name='FileOptions', - full_name='google.protobuf.FileOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='java_package', full_name='google.protobuf.FileOptions.java_package', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='javaPackage', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_outer_classname', full_name='google.protobuf.FileOptions.java_outer_classname', index=1, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='javaOuterClassname', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_multiple_files', full_name='google.protobuf.FileOptions.java_multiple_files', index=2, - number=10, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\262\001\275\001\010\346\007 \351\007*\264\001This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.', json_name='javaMultipleFiles', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_generate_equals_and_hash', full_name='google.protobuf.FileOptions.java_generate_equals_and_hash', index=3, - number=20, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\030\001', json_name='javaGenerateEqualsAndHash', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_string_check_utf8', full_name='google.protobuf.FileOptions.java_string_check_utf8', index=4, - number=27, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='javaStringCheckUtf8', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=5, - number=9, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='optimizeFor', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='go_package', full_name='google.protobuf.FileOptions.go_package', index=6, - number=11, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='goPackage', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=7, - number=16, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='ccGenericServices', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=8, - number=17, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='javaGenericServices', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=9, - number=18, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='pyGenericServices', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.FileOptions.deprecated', index=10, - number=23, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='cc_enable_arenas', full_name='google.protobuf.FileOptions.cc_enable_arenas', index=11, - number=31, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=True, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\262\001\212\001 \352\007*\204\001cc_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.', json_name='ccEnableArenas', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='objc_class_prefix', full_name='google.protobuf.FileOptions.objc_class_prefix', index=12, - number=36, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='objcClassPrefix', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='csharp_namespace', full_name='google.protobuf.FileOptions.csharp_namespace', index=13, - number=37, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='csharpNamespace', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='swift_prefix', full_name='google.protobuf.FileOptions.swift_prefix', index=14, - number=39, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='swiftPrefix', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_class_prefix', full_name='google.protobuf.FileOptions.php_class_prefix', index=15, - number=40, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='phpClassPrefix', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_namespace', full_name='google.protobuf.FileOptions.php_namespace', index=16, - number=41, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='phpNamespace', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_metadata_namespace', full_name='google.protobuf.FileOptions.php_metadata_namespace', index=17, - number=44, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='phpMetadataNamespace', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='ruby_package', full_name='google.protobuf.FileOptions.ruby_package', index=18, - number=45, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='rubyPackage', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.FileOptions.features', index=19, - number=50, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=20, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FILEOPTIONS_OPTIMIZEMODE, - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _MESSAGEOPTIONS = _descriptor.Descriptor( - name='MessageOptions', - full_name='google.protobuf.MessageOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='message_set_wire_format', full_name='google.protobuf.MessageOptions.message_set_wire_format', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='messageSetWireFormat', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='no_standard_descriptor_accessor', full_name='google.protobuf.MessageOptions.no_standard_descriptor_accessor', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='noStandardDescriptorAccessor', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.MessageOptions.deprecated', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='map_entry', full_name='google.protobuf.MessageOptions.map_entry', index=3, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='mapEntry', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated_legacy_json_field_conflicts', full_name='google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts', index=4, - number=11, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\030\001', json_name='deprecatedLegacyJsonFieldConflicts', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.MessageOptions.features', index=5, - number=12, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=6, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _FIELDOPTIONS_EDITIONDEFAULT = _descriptor.Descriptor( - name='EditionDefault', - full_name='google.protobuf.FieldOptions.EditionDefault', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='edition', full_name='google.protobuf.FieldOptions.EditionDefault.edition', index=0, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='edition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='value', full_name='google.protobuf.FieldOptions.EditionDefault.value', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='value', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _FIELDOPTIONS_FEATURESUPPORT = _descriptor.Descriptor( - name='FeatureSupport', - full_name='google.protobuf.FieldOptions.FeatureSupport', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='edition_introduced', full_name='google.protobuf.FieldOptions.FeatureSupport.edition_introduced', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='editionIntroduced', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='edition_deprecated', full_name='google.protobuf.FieldOptions.FeatureSupport.edition_deprecated', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='editionDeprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecation_warning', full_name='google.protobuf.FieldOptions.FeatureSupport.deprecation_warning', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecationWarning', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='edition_removed', full_name='google.protobuf.FieldOptions.FeatureSupport.edition_removed', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='editionRemoved', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='removal_error', full_name='google.protobuf.FieldOptions.FeatureSupport.removal_error', index=4, - number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='removalError', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _FIELDOPTIONS = _descriptor.Descriptor( - name='FieldOptions', - full_name='google.protobuf.FieldOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='ctype', full_name='google.protobuf.FieldOptions.ctype', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='ctype', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='packed', full_name='google.protobuf.FieldOptions.packed', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='packed', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='jstype', full_name='google.protobuf.FieldOptions.jstype', index=2, - number=6, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='jstype', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='lazy', full_name='google.protobuf.FieldOptions.lazy', index=3, - number=5, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='lazy', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='unverified_lazy', full_name='google.protobuf.FieldOptions.unverified_lazy', index=4, - number=15, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='unverifiedLazy', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=5, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='weak', full_name='google.protobuf.FieldOptions.weak', index=6, - number=10, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\030\001', json_name='weak', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='debug_redact', full_name='google.protobuf.FieldOptions.debug_redact', index=7, - number=16, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='debugRedact', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='retention', full_name='google.protobuf.FieldOptions.retention', index=8, - number=17, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='retention', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='targets', full_name='google.protobuf.FieldOptions.targets', index=9, - number=19, type=14, cpp_type=8, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='targets', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='edition_defaults', full_name='google.protobuf.FieldOptions.edition_defaults', index=10, - number=20, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='editionDefaults', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.FieldOptions.features', index=11, - number=21, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='feature_support', full_name='google.protobuf.FieldOptions.feature_support', index=12, - number=22, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='featureSupport', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.FieldOptions.uninterpreted_option', index=13, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_FIELDOPTIONS_EDITIONDEFAULT, _FIELDOPTIONS_FEATURESUPPORT, ], - enum_types=[ - _FIELDOPTIONS_CTYPE, - _FIELDOPTIONS_JSTYPE, - _FIELDOPTIONS_OPTIONRETENTION, - _FIELDOPTIONS_OPTIONTARGETTYPE, - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _ONEOFOPTIONS = _descriptor.Descriptor( - name='OneofOptions', - full_name='google.protobuf.OneofOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.OneofOptions.features', index=0, - number=1, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.OneofOptions.uninterpreted_option', index=1, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _ENUMOPTIONS = _descriptor.Descriptor( - name='EnumOptions', - full_name='google.protobuf.EnumOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='allow_alias', full_name='google.protobuf.EnumOptions.allow_alias', index=0, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='allowAlias', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.EnumOptions.deprecated', index=1, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated_legacy_json_field_conflicts', full_name='google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts', index=2, - number=6, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\030\001', json_name='deprecatedLegacyJsonFieldConflicts', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.EnumOptions.features', index=3, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=4, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _ENUMVALUEOPTIONS = _descriptor.Descriptor( - name='EnumValueOptions', - full_name='google.protobuf.EnumValueOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.EnumValueOptions.deprecated', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.EnumValueOptions.features', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='debug_redact', full_name='google.protobuf.EnumValueOptions.debug_redact', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='debugRedact', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='feature_support', full_name='google.protobuf.EnumValueOptions.feature_support', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='featureSupport', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=4, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _SERVICEOPTIONS = _descriptor.Descriptor( - name='ServiceOptions', - full_name='google.protobuf.ServiceOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.ServiceOptions.features', index=0, - number=34, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.ServiceOptions.deprecated', index=1, - number=33, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=2, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _METHODOPTIONS = _descriptor.Descriptor( - name='MethodOptions', - full_name='google.protobuf.MethodOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.MethodOptions.deprecated', index=0, - number=33, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='deprecated', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='idempotency_level', full_name='google.protobuf.MethodOptions.idempotency_level', index=1, - number=34, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='idempotencyLevel', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='features', full_name='google.protobuf.MethodOptions.features', index=2, - number=35, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='features', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=3, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='uninterpretedOption', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _METHODOPTIONS_IDEMPOTENCYLEVEL, - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(990, 999), (1000, 536870912), ], - oneofs=[ - ], - ) - - - _UNINTERPRETEDOPTION_NAMEPART = _descriptor.Descriptor( - name='NamePart', - full_name='google.protobuf.UninterpretedOption.NamePart', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name_part', full_name='google.protobuf.UninterpretedOption.NamePart.name_part', index=0, - number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='namePart', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='is_extension', full_name='google.protobuf.UninterpretedOption.NamePart.is_extension', index=1, - number=2, type=8, cpp_type=7, label=2, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='isExtension', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _UNINTERPRETEDOPTION = _descriptor.Descriptor( - name='UninterpretedOption', - full_name='google.protobuf.UninterpretedOption', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.UninterpretedOption.name', index=0, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='name', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='identifier_value', full_name='google.protobuf.UninterpretedOption.identifier_value', index=1, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='identifierValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='positive_int_value', full_name='google.protobuf.UninterpretedOption.positive_int_value', index=2, - number=4, type=4, cpp_type=4, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='positiveIntValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='negative_int_value', full_name='google.protobuf.UninterpretedOption.negative_int_value', index=3, - number=5, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='negativeIntValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='double_value', full_name='google.protobuf.UninterpretedOption.double_value', index=4, - number=6, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='doubleValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='string_value', full_name='google.protobuf.UninterpretedOption.string_value', index=5, - number=7, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=b"", - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='stringValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='aggregate_value', full_name='google.protobuf.UninterpretedOption.aggregate_value', index=6, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='aggregateValue', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_UNINTERPRETEDOPTION_NAMEPART, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _FEATURESET_VISIBILITYFEATURE = _descriptor.Descriptor( - name='VisibilityFeature', - full_name='google.protobuf.FeatureSet.VisibilityFeature', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY, - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _FEATURESET_PROTOLIMITSFEATURE = _descriptor.Descriptor( - name='ProtoLimitsFeature', - full_name='google.protobuf.FeatureSet.ProtoLimitsFeature', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS, - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _FEATURESET = _descriptor.Descriptor( - name='FeatureSet', - full_name='google.protobuf.FeatureSet', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='field_presence', full_name='google.protobuf.FeatureSet.field_presence', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPLICIT\030\204\007\242\001\r\022\010IMPLICIT\030\347\007\242\001\r\022\010EXPLICIT\030\350\007\262\001\003\010\350\007', json_name='fieldPresence', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enum_type', full_name='google.protobuf.FeatureSet.enum_type', index=1, - number=2, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\001\230\001\006\230\001\001\242\001\013\022\006CLOSED\030\204\007\242\001\t\022\004OPEN\030\347\007\262\001\003\010\350\007', json_name='enumType', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='repeated_field_encoding', full_name='google.protobuf.FeatureSet.repeated_field_encoding', index=2, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPANDED\030\204\007\242\001\013\022\006PACKED\030\347\007\262\001\003\010\350\007', json_name='repeatedFieldEncoding', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='utf8_validation', full_name='google.protobuf.FeatureSet.utf8_validation', index=3, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\t\022\004NONE\030\204\007\242\001\013\022\006VERIFY\030\347\007\262\001\003\010\350\007', json_name='utf8Validation', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='message_encoding', full_name='google.protobuf.FeatureSet.message_encoding', index=4, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\001\230\001\004\230\001\001\242\001\024\022\017LENGTH_PREFIXED\030\204\007\262\001\003\010\350\007', json_name='messageEncoding', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='json_format', full_name='google.protobuf.FeatureSet.json_format', index=5, - number=6, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\001\230\001\003\230\001\006\230\001\001\242\001\027\022\022LEGACY_BEST_EFFORT\030\204\007\242\001\n\022\005ALLOW\030\347\007\262\001\003\010\350\007', json_name='jsonFormat', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enforce_naming_style', full_name='google.protobuf.FeatureSet.enforce_naming_style', index=6, - number=7, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\002\230\001\001\230\001\002\230\001\003\230\001\004\230\001\005\230\001\006\230\001\007\230\001\010\230\001\t\242\001\021\022\014STYLE_LEGACY\030\204\007\242\001\016\022\tSTYLE2024\030\351\007\242\001\016\022\tSTYLE2026\030\352\007\262\001\003\010\351\007', json_name='enforceNamingStyle', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='default_symbol_visibility', full_name='google.protobuf.FeatureSet.default_symbol_visibility', index=7, - number=8, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\002\230\001\001\242\001\017\022\nEXPORT_ALL\030\204\007\242\001\025\022\020EXPORT_TOP_LEVEL\030\351\007\242\001\013\022\006STRICT\030\352\007\262\001\003\010\351\007', json_name='defaultSymbolVisibility', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enforce_proto_limits', full_name='google.protobuf.FeatureSet.enforce_proto_limits', index=8, - number=9, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\210\001\002\230\001\006\230\001\003\230\001\004\230\001\005\242\001\036\022\031LEGACY_NO_EXPLICIT_LIMITS\030\204\007\242\001\025\022\020PROTO_LIMITS2026\030\352\007\262\001\003\010\352\007', json_name='enforceProtoLimits', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_FEATURESET_VISIBILITYFEATURE, _FEATURESET_PROTOLIMITSFEATURE, ], - enum_types=[ - _FEATURESET_FIELDPRESENCE, - _FEATURESET_ENUMTYPE, - _FEATURESET_REPEATEDFIELDENCODING, - _FEATURESET_UTF8VALIDATION, - _FEATURESET_MESSAGEENCODING, - _FEATURESET_JSONFORMAT, - _FEATURESET_ENFORCENAMINGSTYLE, - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(1000, 9995), (9995, 10000), (10000, 10001), ], - oneofs=[ - ], - ) - - - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT = _descriptor.Descriptor( - name='FeatureSetEditionDefault', - full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='edition', full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition', index=0, - number=3, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='edition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='overridable_features', full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features', index=1, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='overridableFeatures', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='fixed_features', full_name='google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features', index=2, - number=5, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='fixedFeatures', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _FEATURESETDEFAULTS = _descriptor.Descriptor( - name='FeatureSetDefaults', - full_name='google.protobuf.FeatureSetDefaults', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='defaults', full_name='google.protobuf.FeatureSetDefaults.defaults', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='defaults', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='minimum_edition', full_name='google.protobuf.FeatureSetDefaults.minimum_edition', index=1, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='minimumEdition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='maximum_edition', full_name='google.protobuf.FeatureSetDefaults.maximum_edition', index=2, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='maximumEdition', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - - _SOURCECODEINFO_LOCATION = _descriptor.Descriptor( - name='Location', - full_name='google.protobuf.SourceCodeInfo.Location', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='path', full_name='google.protobuf.SourceCodeInfo.Location.path', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\020\001', json_name='path', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='span', full_name='google.protobuf.SourceCodeInfo.Location.span', index=1, - number=2, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\020\001', json_name='span', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='leading_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_comments', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='leadingComments', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='trailing_comments', full_name='google.protobuf.SourceCodeInfo.Location.trailing_comments', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='trailingComments', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='leading_detached_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_detached_comments', index=4, - number=6, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='leadingDetachedComments', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _SOURCECODEINFO = _descriptor.Descriptor( - name='SourceCodeInfo', - full_name='google.protobuf.SourceCodeInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='location', full_name='google.protobuf.SourceCodeInfo.location', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='location', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_SOURCECODEINFO_LOCATION, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - extension_ranges=[(536000000, 536000001), ], - oneofs=[ - ], - ) - - - _GENERATEDCODEINFO_ANNOTATION = _descriptor.Descriptor( - name='Annotation', - full_name='google.protobuf.GeneratedCodeInfo.Annotation', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='path', full_name='google.protobuf.GeneratedCodeInfo.Annotation.path', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=b'\020\001', json_name='path', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='source_file', full_name='google.protobuf.GeneratedCodeInfo.Annotation.source_file', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='sourceFile', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='begin', full_name='google.protobuf.GeneratedCodeInfo.Annotation.begin', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='begin', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.GeneratedCodeInfo.Annotation.end', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='end', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='semantic', full_name='google.protobuf.GeneratedCodeInfo.Annotation.semantic', index=4, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='semantic', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _GENERATEDCODEINFO_ANNOTATION_SEMANTIC, - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _GENERATEDCODEINFO = _descriptor.Descriptor( - name='GeneratedCodeInfo', - full_name='google.protobuf.GeneratedCodeInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='annotation', full_name='google.protobuf.GeneratedCodeInfo.annotation', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, json_name='annotation', file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_GENERATEDCODEINFO_ANNOTATION, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - extension_ranges=[], - oneofs=[ - ], - ) - - _FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['message_type'].message_type = _DESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['service'].message_type = _SERVICEDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS - _FILEDESCRIPTORPROTO.fields_by_name['source_code_info'].message_type = _SOURCECODEINFO - _FILEDESCRIPTORPROTO.fields_by_name['edition'].enum_type = _EDITION - _DESCRIPTORPROTO_EXTENSIONRANGE.fields_by_name['options'].message_type = _EXTENSIONRANGEOPTIONS - _DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO_RESERVEDRANGE.containing_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE - _DESCRIPTORPROTO.fields_by_name['oneof_decl'].message_type = _ONEOFDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS - _DESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _DESCRIPTORPROTO_RESERVEDRANGE - _DESCRIPTORPROTO.fields_by_name['visibility'].enum_type = _SYMBOLVISIBILITY - _EXTENSIONRANGEOPTIONS_DECLARATION.containing_type = _EXTENSIONRANGEOPTIONS - _EXTENSIONRANGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _EXTENSIONRANGEOPTIONS.fields_by_name['declaration'].message_type = _EXTENSIONRANGEOPTIONS_DECLARATION - _EXTENSIONRANGEOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _EXTENSIONRANGEOPTIONS.fields_by_name['verification'].enum_type = _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE - _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE.containing_type = _EXTENSIONRANGEOPTIONS - _FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL - _FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE - _FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS - _FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO - _FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO - _ONEOFDESCRIPTORPROTO.fields_by_name['options'].message_type = _ONEOFOPTIONS - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.containing_type = _ENUMDESCRIPTORPROTO - _ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO - _ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS - _ENUMDESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE - _ENUMDESCRIPTORPROTO.fields_by_name['visibility'].enum_type = _SYMBOLVISIBILITY - _ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS - _SERVICEDESCRIPTORPROTO.fields_by_name['method'].message_type = _METHODDESCRIPTORPROTO - _SERVICEDESCRIPTORPROTO.fields_by_name['options'].message_type = _SERVICEOPTIONS - _METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS - _FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE - _FILEOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS - _MESSAGEOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDOPTIONS_EDITIONDEFAULT.fields_by_name['edition'].enum_type = _EDITION - _FIELDOPTIONS_EDITIONDEFAULT.containing_type = _FIELDOPTIONS - _FIELDOPTIONS_FEATURESUPPORT.fields_by_name['edition_introduced'].enum_type = _EDITION - _FIELDOPTIONS_FEATURESUPPORT.fields_by_name['edition_deprecated'].enum_type = _EDITION - _FIELDOPTIONS_FEATURESUPPORT.fields_by_name['edition_removed'].enum_type = _EDITION - _FIELDOPTIONS_FEATURESUPPORT.containing_type = _FIELDOPTIONS - _FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE - _FIELDOPTIONS.fields_by_name['jstype'].enum_type = _FIELDOPTIONS_JSTYPE - _FIELDOPTIONS.fields_by_name['retention'].enum_type = _FIELDOPTIONS_OPTIONRETENTION - _FIELDOPTIONS.fields_by_name['targets'].enum_type = _FIELDOPTIONS_OPTIONTARGETTYPE - _FIELDOPTIONS.fields_by_name['edition_defaults'].message_type = _FIELDOPTIONS_EDITIONDEFAULT - _FIELDOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _FIELDOPTIONS.fields_by_name['feature_support'].message_type = _FIELDOPTIONS_FEATURESUPPORT - _FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS - _FIELDOPTIONS_JSTYPE.containing_type = _FIELDOPTIONS - _FIELDOPTIONS_OPTIONRETENTION.containing_type = _FIELDOPTIONS - _FIELDOPTIONS_OPTIONTARGETTYPE.containing_type = _FIELDOPTIONS - _ONEOFOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _ONEOFOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _ENUMOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _ENUMVALUEOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _ENUMVALUEOPTIONS.fields_by_name['feature_support'].message_type = _FIELDOPTIONS_FEATURESUPPORT - _ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _SERVICEOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _METHODOPTIONS.fields_by_name['idempotency_level'].enum_type = _METHODOPTIONS_IDEMPOTENCYLEVEL - _METHODOPTIONS.fields_by_name['features'].message_type = _FEATURESET - _METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _METHODOPTIONS_IDEMPOTENCYLEVEL.containing_type = _METHODOPTIONS - _UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION - _UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART - _FEATURESET_VISIBILITYFEATURE.containing_type = _FEATURESET - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.containing_type = _FEATURESET_VISIBILITYFEATURE - _FEATURESET_PROTOLIMITSFEATURE.containing_type = _FEATURESET - _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.containing_type = _FEATURESET_PROTOLIMITSFEATURE - _FEATURESET.fields_by_name['field_presence'].enum_type = _FEATURESET_FIELDPRESENCE - _FEATURESET.fields_by_name['enum_type'].enum_type = _FEATURESET_ENUMTYPE - _FEATURESET.fields_by_name['repeated_field_encoding'].enum_type = _FEATURESET_REPEATEDFIELDENCODING - _FEATURESET.fields_by_name['utf8_validation'].enum_type = _FEATURESET_UTF8VALIDATION - _FEATURESET.fields_by_name['message_encoding'].enum_type = _FEATURESET_MESSAGEENCODING - _FEATURESET.fields_by_name['json_format'].enum_type = _FEATURESET_JSONFORMAT - _FEATURESET.fields_by_name['enforce_naming_style'].enum_type = _FEATURESET_ENFORCENAMINGSTYLE - _FEATURESET.fields_by_name['default_symbol_visibility'].enum_type = _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY - _FEATURESET.fields_by_name['enforce_proto_limits'].enum_type = _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS - _FEATURESET_FIELDPRESENCE.containing_type = _FEATURESET - _FEATURESET_ENUMTYPE.containing_type = _FEATURESET - _FEATURESET_REPEATEDFIELDENCODING.containing_type = _FEATURESET - _FEATURESET_UTF8VALIDATION.containing_type = _FEATURESET - _FEATURESET_MESSAGEENCODING.containing_type = _FEATURESET - _FEATURESET_JSONFORMAT.containing_type = _FEATURESET - _FEATURESET_ENFORCENAMINGSTYLE.containing_type = _FEATURESET - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields_by_name['edition'].enum_type = _EDITION - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields_by_name['overridable_features'].message_type = _FEATURESET - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields_by_name['fixed_features'].message_type = _FEATURESET - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.containing_type = _FEATURESETDEFAULTS - _FEATURESETDEFAULTS.fields_by_name['defaults'].message_type = _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT - _FEATURESETDEFAULTS.fields_by_name['minimum_edition'].enum_type = _EDITION - _FEATURESETDEFAULTS.fields_by_name['maximum_edition'].enum_type = _EDITION - _SOURCECODEINFO_LOCATION.containing_type = _SOURCECODEINFO - _SOURCECODEINFO.fields_by_name['location'].message_type = _SOURCECODEINFO_LOCATION - _GENERATEDCODEINFO_ANNOTATION.fields_by_name['semantic'].enum_type = _GENERATEDCODEINFO_ANNOTATION_SEMANTIC - _GENERATEDCODEINFO_ANNOTATION.containing_type = _GENERATEDCODEINFO - _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.containing_type = _GENERATEDCODEINFO_ANNOTATION - _GENERATEDCODEINFO.fields_by_name['annotation'].message_type = _GENERATEDCODEINFO_ANNOTATION - DESCRIPTOR.message_types_by_name['FileDescriptorSet'] = _FILEDESCRIPTORSET - DESCRIPTOR.message_types_by_name['FileDescriptorProto'] = _FILEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['DescriptorProto'] = _DESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['ExtensionRangeOptions'] = _EXTENSIONRANGEOPTIONS - DESCRIPTOR.message_types_by_name['FieldDescriptorProto'] = _FIELDDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['OneofDescriptorProto'] = _ONEOFDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['EnumDescriptorProto'] = _ENUMDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['EnumValueDescriptorProto'] = _ENUMVALUEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['ServiceDescriptorProto'] = _SERVICEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['MethodDescriptorProto'] = _METHODDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['FileOptions'] = _FILEOPTIONS - DESCRIPTOR.message_types_by_name['MessageOptions'] = _MESSAGEOPTIONS - DESCRIPTOR.message_types_by_name['FieldOptions'] = _FIELDOPTIONS - DESCRIPTOR.message_types_by_name['OneofOptions'] = _ONEOFOPTIONS - DESCRIPTOR.message_types_by_name['EnumOptions'] = _ENUMOPTIONS - DESCRIPTOR.message_types_by_name['EnumValueOptions'] = _ENUMVALUEOPTIONS - DESCRIPTOR.message_types_by_name['ServiceOptions'] = _SERVICEOPTIONS - DESCRIPTOR.message_types_by_name['MethodOptions'] = _METHODOPTIONS - DESCRIPTOR.message_types_by_name['UninterpretedOption'] = _UNINTERPRETEDOPTION - DESCRIPTOR.message_types_by_name['FeatureSet'] = _FEATURESET - DESCRIPTOR.message_types_by_name['FeatureSetDefaults'] = _FEATURESETDEFAULTS - DESCRIPTOR.message_types_by_name['SourceCodeInfo'] = _SOURCECODEINFO - DESCRIPTOR.message_types_by_name['GeneratedCodeInfo'] = _GENERATEDCODEINFO - DESCRIPTOR.enum_types_by_name['Edition'] = _EDITION - DESCRIPTOR.enum_types_by_name['SymbolVisibility'] = _SYMBOLVISIBILITY - _sym_db.RegisterFileDescriptor(DESCRIPTOR) - - class _ResolvedFeatures: - def __init__(self, features = None, **kwargs): - if features: - for k, v in features.FIELDS.items(): - setattr(self, k, getattr(features, k)) - else: - for k, v in kwargs.items(): - setattr(self, k, v) - DESCRIPTOR._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORSET._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORSET.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEDESCRIPTORPROTO.fields[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO_EXTENSIONRANGE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO_EXTENSIONRANGE.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO_EXTENSIONRANGE.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO_EXTENSIONRANGE.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO_RESERVEDRANGE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO_RESERVEDRANGE.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _DESCRIPTORPROTO_RESERVEDRANGE.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_DECLARATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_DECLARATION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_DECLARATION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_DECLARATION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_DECLARATION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_DECLARATION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ONEOFDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ONEOFDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ONEOFDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODDESCRIPTORPROTO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODDESCRIPTORPROTO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODDESCRIPTORPROTO.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODDESCRIPTORPROTO.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODDESCRIPTORPROTO.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODDESCRIPTORPROTO.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODDESCRIPTORPROTO.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[14]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[15]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[16]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[17]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[18]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[19]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS.fields[20]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _MESSAGEOPTIONS.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS.fields[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_EDITIONDEFAULT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_EDITIONDEFAULT.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_EDITIONDEFAULT.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_FEATURESUPPORT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_FEATURESUPPORT.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_FEATURESUPPORT.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_FEATURESUPPORT.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_FEATURESUPPORT.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_FEATURESUPPORT.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ONEOFOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ONEOFOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ONEOFOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _ENUMVALUEOPTIONS.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SERVICEOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION_NAMEPART._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION_NAMEPART.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["LEGACY_REQUIRED"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _UNINTERPRETEDOPTION_NAMEPART.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["LEGACY_REQUIRED"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET.fields[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_VISIBILITYFEATURE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_PROTOLIMITSFEATURE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO_LOCATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO_LOCATION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["PACKED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO_LOCATION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["PACKED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO_LOCATION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO_LOCATION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SOURCECODEINFO_LOCATION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION.fields[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["PACKED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION.fields[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION.fields[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION.fields[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION.fields[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[14]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[15]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[16]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_TYPE.values[17]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_LABEL._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_LABEL.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_LABEL.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDDESCRIPTORPROTO_LABEL.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS_OPTIMIZEMODE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS_OPTIMIZEMODE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS_OPTIMIZEMODE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FILEOPTIONS_OPTIMIZEMODE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_CTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_CTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_CTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_CTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_JSTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_JSTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_JSTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_JSTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONRETENTION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONRETENTION.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONRETENTION.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONRETENTION.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FIELDOPTIONS_OPTIONTARGETTYPE.values[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS_IDEMPOTENCYLEVEL._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS_IDEMPOTENCYLEVEL.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS_IDEMPOTENCYLEVEL.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _METHODOPTIONS_IDEMPOTENCYLEVEL.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_FIELDPRESENCE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_FIELDPRESENCE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_FIELDPRESENCE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_FIELDPRESENCE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_FIELDPRESENCE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENUMTYPE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENUMTYPE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENUMTYPE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENUMTYPE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_REPEATEDFIELDENCODING._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_REPEATEDFIELDENCODING.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_REPEATEDFIELDENCODING.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_REPEATEDFIELDENCODING.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_UTF8VALIDATION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_UTF8VALIDATION.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_UTF8VALIDATION.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_UTF8VALIDATION.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_MESSAGEENCODING._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_MESSAGEENCODING.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_MESSAGEENCODING.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_MESSAGEENCODING.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_JSONFORMAT._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_JSONFORMAT.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_JSONFORMAT.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_JSONFORMAT.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENFORCENAMINGSTYLE._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENFORCENAMINGSTYLE.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENFORCENAMINGSTYLE.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENFORCENAMINGSTYLE.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_ENFORCENAMINGSTYLE.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION_SEMANTIC._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _GENERATEDCODEINFO_ANNOTATION_SEMANTIC.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[3]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[4]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[5]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[6]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[7]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[8]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[9]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[10]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[11]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[12]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _EDITION.values[13]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SYMBOLVISIBILITY._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SYMBOLVISIBILITY.values[0]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SYMBOLVISIBILITY.values[1]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) - _SYMBOLVISIBILITY.values[2]._features = _ResolvedFeatures(field_presence=_FEATURESET_FIELDPRESENCE.values_by_name["EXPLICIT"].number,enum_type=_FEATURESET_ENUMTYPE.values_by_name["CLOSED"].number,repeated_field_encoding=_FEATURESET_REPEATEDFIELDENCODING.values_by_name["EXPANDED"].number,utf8_validation=_FEATURESET_UTF8VALIDATION.values_by_name["NONE"].number,message_encoding=_FEATURESET_MESSAGEENCODING.values_by_name["LENGTH_PREFIXED"].number,json_format=_FEATURESET_JSONFORMAT.values_by_name["LEGACY_BEST_EFFORT"].number) -else: - _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.descriptor_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\020DescriptorProtosH\001Z-google.golang.org/protobuf/types/descriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf.Reflection' - _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['declaration']._loaded_options = None - _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['declaration']._serialized_options = b'\210\001\002' - _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['verification']._loaded_options = None - _globals['_EXTENSIONRANGEOPTIONS'].fields_by_name['verification']._serialized_options = b'\210\001\002' - _globals['_FILEOPTIONS'].fields_by_name['java_multiple_files']._loaded_options = None - _globals['_FILEOPTIONS'].fields_by_name['java_multiple_files']._serialized_options = b'\262\001\275\001\010\346\007 \351\007*\264\001This behavior is enabled by default in editions 2024 and above. To disable it, you can set `features.(pb.java).nest_in_file_class = YES` on individual messages, enums, or services.' - _globals['_FILEOPTIONS'].fields_by_name['java_generate_equals_and_hash']._loaded_options = None - _globals['_FILEOPTIONS'].fields_by_name['java_generate_equals_and_hash']._serialized_options = b'\030\001' - _globals['_FILEOPTIONS'].fields_by_name['cc_enable_arenas']._loaded_options = None - _globals['_FILEOPTIONS'].fields_by_name['cc_enable_arenas']._serialized_options = b'\262\001\212\001 \352\007*\204\001cc_enable_arenas is enabled by default in every edition and overrides are ignored.This option is removed in editions 2026 and above.' - _globals['_MESSAGEOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._loaded_options = None - _globals['_MESSAGEOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._serialized_options = b'\030\001' - _globals['_FIELDOPTIONS'].fields_by_name['weak']._loaded_options = None - _globals['_FIELDOPTIONS'].fields_by_name['weak']._serialized_options = b'\030\001' - _globals['_ENUMOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._loaded_options = None - _globals['_ENUMOPTIONS'].fields_by_name['deprecated_legacy_json_field_conflicts']._serialized_options = b'\030\001' - _globals['_FEATURESET'].fields_by_name['field_presence']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['field_presence']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPLICIT\030\204\007\242\001\r\022\010IMPLICIT\030\347\007\242\001\r\022\010EXPLICIT\030\350\007\262\001\003\010\350\007' - _globals['_FEATURESET'].fields_by_name['enum_type']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['enum_type']._serialized_options = b'\210\001\001\230\001\006\230\001\001\242\001\013\022\006CLOSED\030\204\007\242\001\t\022\004OPEN\030\347\007\262\001\003\010\350\007' - _globals['_FEATURESET'].fields_by_name['repeated_field_encoding']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['repeated_field_encoding']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPANDED\030\204\007\242\001\013\022\006PACKED\030\347\007\262\001\003\010\350\007' - _globals['_FEATURESET'].fields_by_name['utf8_validation']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['utf8_validation']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\t\022\004NONE\030\204\007\242\001\013\022\006VERIFY\030\347\007\262\001\003\010\350\007' - _globals['_FEATURESET'].fields_by_name['message_encoding']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['message_encoding']._serialized_options = b'\210\001\001\230\001\004\230\001\001\242\001\024\022\017LENGTH_PREFIXED\030\204\007\262\001\003\010\350\007' - _globals['_FEATURESET'].fields_by_name['json_format']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['json_format']._serialized_options = b'\210\001\001\230\001\003\230\001\006\230\001\001\242\001\027\022\022LEGACY_BEST_EFFORT\030\204\007\242\001\n\022\005ALLOW\030\347\007\262\001\003\010\350\007' - _globals['_FEATURESET'].fields_by_name['enforce_naming_style']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['enforce_naming_style']._serialized_options = b'\210\001\002\230\001\001\230\001\002\230\001\003\230\001\004\230\001\005\230\001\006\230\001\007\230\001\010\230\001\t\242\001\021\022\014STYLE_LEGACY\030\204\007\242\001\016\022\tSTYLE2024\030\351\007\242\001\016\022\tSTYLE2026\030\352\007\262\001\003\010\351\007' - _globals['_FEATURESET'].fields_by_name['default_symbol_visibility']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['default_symbol_visibility']._serialized_options = b'\210\001\002\230\001\001\242\001\017\022\nEXPORT_ALL\030\204\007\242\001\025\022\020EXPORT_TOP_LEVEL\030\351\007\242\001\013\022\006STRICT\030\352\007\262\001\003\010\351\007' - _globals['_FEATURESET'].fields_by_name['enforce_proto_limits']._loaded_options = None - _globals['_FEATURESET'].fields_by_name['enforce_proto_limits']._serialized_options = b'\210\001\002\230\001\006\230\001\003\230\001\004\230\001\005\242\001\036\022\031LEGACY_NO_EXPLICIT_LIMITS\030\204\007\242\001\025\022\020PROTO_LIMITS2026\030\352\007\262\001\003\010\352\007' - _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['path']._loaded_options = None - _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['path']._serialized_options = b'\020\001' - _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['span']._loaded_options = None - _globals['_SOURCECODEINFO_LOCATION'].fields_by_name['span']._serialized_options = b'\020\001' - _globals['_GENERATEDCODEINFO_ANNOTATION'].fields_by_name['path']._loaded_options = None - _globals['_GENERATEDCODEINFO_ANNOTATION'].fields_by_name['path']._serialized_options = b'\020\001' - _globals['_EDITION']._serialized_start=13504 - _globals['_EDITION']._serialized_end=13841 - _globals['_SYMBOLVISIBILITY']._serialized_start=13843 - _globals['_SYMBOLVISIBILITY']._serialized_end=13928 - _globals['_FILEDESCRIPTORSET']._serialized_start=53 - _globals['_FILEDESCRIPTORSET']._serialized_end=144 - _globals['_FILEDESCRIPTORPROTO']._serialized_start=147 - _globals['_FILEDESCRIPTORPROTO']._serialized_end=856 - _globals['_DESCRIPTORPROTO']._serialized_start=859 - _globals['_DESCRIPTORPROTO']._serialized_end=1751 - _globals['_DESCRIPTORPROTO_EXTENSIONRANGE']._serialized_start=1572 - _globals['_DESCRIPTORPROTO_EXTENSIONRANGE']._serialized_end=1694 - _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_start=1696 - _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_end=1751 - _globals['_EXTENSIONRANGEOPTIONS']._serialized_start=1754 - _globals['_EXTENSIONRANGEOPTIONS']._serialized_end=2350 - _globals['_EXTENSIONRANGEOPTIONS_DECLARATION']._serialized_start=2129 - _globals['_EXTENSIONRANGEOPTIONS_DECLARATION']._serialized_end=2277 - _globals['_EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE']._serialized_start=2279 - _globals['_EXTENSIONRANGEOPTIONS_VERIFICATIONSTATE']._serialized_end=2331 - _globals['_FIELDDESCRIPTORPROTO']._serialized_start=2353 - _globals['_FIELDDESCRIPTORPROTO']._serialized_end=3186 - _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_start=2807 - _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_end=3117 - _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_start=3119 - _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_end=3186 - _globals['_ONEOFDESCRIPTORPROTO']._serialized_start=3188 - _globals['_ONEOFDESCRIPTORPROTO']._serialized_end=3287 - _globals['_ENUMDESCRIPTORPROTO']._serialized_start=3290 - _globals['_ENUMDESCRIPTORPROTO']._serialized_end=3712 - _globals['_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE']._serialized_start=3653 - _globals['_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE']._serialized_end=3712 - _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_start=3715 - _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_end=3846 - _globals['_SERVICEDESCRIPTORPROTO']._serialized_start=3849 - _globals['_SERVICEDESCRIPTORPROTO']._serialized_end=4030 - _globals['_METHODDESCRIPTORPROTO']._serialized_start=4033 - _globals['_METHODDESCRIPTORPROTO']._serialized_end=4298 - _globals['_FILEOPTIONS']._serialized_start=4301 - _globals['_FILEOPTIONS']._serialized_end=5849 - _globals['_FILEOPTIONS_OPTIMIZEMODE']._serialized_start=5738 - _globals['_FILEOPTIONS_OPTIMIZEMODE']._serialized_end=5796 - _globals['_MESSAGEOPTIONS']._serialized_start=5852 - _globals['_MESSAGEOPTIONS']._serialized_end=6360 - _globals['_FIELDOPTIONS']._serialized_start=6363 - _globals['_FIELDOPTIONS']._serialized_end=8105 - _globals['_FIELDOPTIONS_EDITIONDEFAULT']._serialized_start=7204 - _globals['_FIELDOPTIONS_EDITIONDEFAULT']._serialized_end=7294 - _globals['_FIELDOPTIONS_FEATURESUPPORT']._serialized_start=7297 - _globals['_FIELDOPTIONS_FEATURESUPPORT']._serialized_end=7612 - _globals['_FIELDOPTIONS_CTYPE']._serialized_start=7614 - _globals['_FIELDOPTIONS_CTYPE']._serialized_end=7661 - _globals['_FIELDOPTIONS_JSTYPE']._serialized_start=7663 - _globals['_FIELDOPTIONS_JSTYPE']._serialized_end=7716 - _globals['_FIELDOPTIONS_OPTIONRETENTION']._serialized_start=7718 - _globals['_FIELDOPTIONS_OPTIONRETENTION']._serialized_end=7803 - _globals['_FIELDOPTIONS_OPTIONTARGETTYPE']._serialized_start=7806 - _globals['_FIELDOPTIONS_OPTIONTARGETTYPE']._serialized_end=8074 - _globals['_ONEOFOPTIONS']._serialized_start=8108 - _globals['_ONEOFOPTIONS']._serialized_end=8288 - _globals['_ENUMOPTIONS']._serialized_start=8291 - _globals['_ENUMOPTIONS']._serialized_end=8636 - _globals['_ENUMVALUEOPTIONS']._serialized_start=8639 - _globals['_ENUMVALUEOPTIONS']._serialized_end=8991 - _globals['_SERVICEOPTIONS']._serialized_start=8994 - _globals['_SERVICEOPTIONS']._serialized_end=9215 - _globals['_METHODOPTIONS']._serialized_start=9218 - _globals['_METHODOPTIONS']._serialized_end=9635 - _globals['_METHODOPTIONS_IDEMPOTENCYLEVEL']._serialized_start=9536 - _globals['_METHODOPTIONS_IDEMPOTENCYLEVEL']._serialized_end=9616 - _globals['_UNINTERPRETEDOPTION']._serialized_start=9638 - _globals['_UNINTERPRETEDOPTION']._serialized_end=10048 - _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_start=9974 - _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_end=10048 - _globals['_FEATURESET']._serialized_start=10051 - _globals['_FEATURESET']._serialized_end=12352 - _globals['_FEATURESET_VISIBILITYFEATURE']._serialized_start=11459 - _globals['_FEATURESET_VISIBILITYFEATURE']._serialized_end=11620 - _globals['_FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY']._serialized_start=11481 - _globals['_FEATURESET_VISIBILITYFEATURE_DEFAULTSYMBOLVISIBILITY']._serialized_end=11610 - _globals['_FEATURESET_PROTOLIMITSFEATURE']._serialized_start=11622 - _globals['_FEATURESET_PROTOLIMITSFEATURE']._serialized_end=11743 - _globals['_FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS']._serialized_start=11644 - _globals['_FEATURESET_PROTOLIMITSFEATURE_ENFORCEPROTOLIMITS']._serialized_end=11743 - _globals['_FEATURESET_FIELDPRESENCE']._serialized_start=11745 - _globals['_FEATURESET_FIELDPRESENCE']._serialized_end=11837 - _globals['_FEATURESET_ENUMTYPE']._serialized_start=11839 - _globals['_FEATURESET_ENUMTYPE']._serialized_end=11894 - _globals['_FEATURESET_REPEATEDFIELDENCODING']._serialized_start=11896 - _globals['_FEATURESET_REPEATEDFIELDENCODING']._serialized_end=11982 - _globals['_FEATURESET_UTF8VALIDATION']._serialized_start=11984 - _globals['_FEATURESET_UTF8VALIDATION']._serialized_end=12057 - _globals['_FEATURESET_MESSAGEENCODING']._serialized_start=12059 - _globals['_FEATURESET_MESSAGEENCODING']._serialized_end=12142 - _globals['_FEATURESET_JSONFORMAT']._serialized_start=12144 - _globals['_FEATURESET_JSONFORMAT']._serialized_end=12216 - _globals['_FEATURESET_ENFORCENAMINGSTYLE']._serialized_start=12218 - _globals['_FEATURESET_ENFORCENAMINGSTYLE']._serialized_end=12320 - _globals['_FEATURESETDEFAULTS']._serialized_start=12355 - _globals['_FEATURESETDEFAULTS']._serialized_end=12850 - _globals['_FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT']._serialized_start=12602 - _globals['_FEATURESETDEFAULTS_FEATURESETEDITIONDEFAULT']._serialized_end=12850 - _globals['_SOURCECODEINFO']._serialized_start=12853 - _globals['_SOURCECODEINFO']._serialized_end=13162 - _globals['_SOURCECODEINFO_LOCATION']._serialized_start=12942 - _globals['_SOURCECODEINFO_LOCATION']._serialized_end=13148 - _globals['_GENERATEDCODEINFO']._serialized_start=13165 - _globals['_GENERATEDCODEINFO']._serialized_end=13501 - _globals['_GENERATEDCODEINFO_ANNOTATION']._serialized_start=13266 - _globals['_GENERATEDCODEINFO_ANNOTATION']._serialized_end=13501 - _globals['_GENERATEDCODEINFO_ANNOTATION_SEMANTIC']._serialized_start=13461 - _globals['_GENERATEDCODEINFO_ANNOTATION_SEMANTIC']._serialized_end=13501 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py deleted file mode 100644 index cd7092f7fd4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/descriptor_pool.py +++ /dev/null @@ -1,1468 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Provides DescriptorPool to use as a container for proto2 descriptors. - -The DescriptorPool is used in conjection with a DescriptorDatabase to maintain -a collection of protocol buffer descriptors for use when dynamically creating -message types at runtime. - -For most applications protocol buffers should be used via modules generated by -the protocol buffer compiler tool. This should only be used when the type of -protocol buffers used in an application or library cannot be predetermined. - -Below is a straightforward example on how to use this class:: - - pool = DescriptorPool() - file_descriptor_protos = [ ... ] - for file_descriptor_proto in file_descriptor_protos: - pool.Add(file_descriptor_proto) - my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType') - -The message descriptor can be used in conjunction with the message_factory -module in order to create a protocol buffer class that can be encoded and -decoded. - -If you want to get a Python class for the specified proto, use the -helper functions inside google.protobuf.message_factory -directly instead of this class. -""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -import collections -import threading -import warnings - -from opentelemetry.agent._vendor.google.protobuf import descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_database -from opentelemetry.agent._vendor.google.protobuf import text_encoding -from opentelemetry.agent._vendor.google.protobuf.internal import python_edition_defaults -from opentelemetry.agent._vendor.google.protobuf.internal import python_message - -_USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-access - - -def _NormalizeFullyQualifiedName(name): - """Remove leading period from fully-qualified type name. - - Due to b/13860351 in descriptor_database.py, types in the root namespace are - generated with a leading period. This function removes that prefix. - - Args: - name (str): The fully-qualified symbol name. - - Returns: - str: The normalized fully-qualified symbol name. - """ - return name.lstrip('.') - - -def _OptionsOrNone(descriptor_proto): - """Returns the value of the field `options`, or None if it is not set.""" - if descriptor_proto.HasField('options'): - return descriptor_proto.options - else: - return None - - -def _IsMessageSetExtension(field): - return ( - field.is_extension - and field.containing_type.has_options - and field.containing_type.GetOptions().message_set_wire_format - and field.type == descriptor.FieldDescriptor.TYPE_MESSAGE - and not field.is_required - and not field.is_repeated - ) - - -_edition_defaults_lock = threading.Lock() - - -class DescriptorPool(object): - """A collection of protobufs dynamically constructed by descriptor protos.""" - - if _USE_C_DESCRIPTORS: - - def __new__(cls, descriptor_db=None): - # pylint: disable=protected-access - return descriptor._message.DescriptorPool(descriptor_db) - - def __init__( - self, descriptor_db=None, use_deprecated_legacy_json_field_conflicts=False - ): - """Initializes a Pool of proto buffs. - - The descriptor_db argument to the constructor is provided to allow - specialized file descriptor proto lookup code to be triggered on demand. An - example would be an implementation which will read and compile a file - specified in a call to FindFileByName() and not require the call to Add() - at all. Results from this database will be cached internally here as well. - - Args: - descriptor_db: A secondary source of file descriptors. - use_deprecated_legacy_json_field_conflicts: Unused, for compatibility with - C++. - """ - - self._internal_db = descriptor_database.DescriptorDatabase() - self._descriptor_db = descriptor_db - self._descriptors = {} - self._enum_descriptors = {} - self._service_descriptors = {} - self._file_descriptors = {} - self._toplevel_extensions = {} - self._top_enum_values = {} - # We store extensions in two two-level mappings: The first key is the - # descriptor of the message being extended, the second key is the extension - # full name or its tag number. - self._extensions_by_name = collections.defaultdict(dict) - self._extensions_by_number = collections.defaultdict(dict) - self._serialized_edition_defaults = ( - python_edition_defaults._PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS - ) - self._edition_defaults = None - self._feature_cache = dict() - - def _CheckConflictRegister(self, desc, desc_name, file_name): - """Check if the descriptor name conflicts with another of the same name. - - Args: - desc: Descriptor of a message, enum, service, extension or enum value. - desc_name (str): the full name of desc. - file_name (str): The file name of descriptor. - """ - for register, descriptor_type in [ - (self._descriptors, descriptor.Descriptor), - (self._enum_descriptors, descriptor.EnumDescriptor), - (self._service_descriptors, descriptor.ServiceDescriptor), - (self._toplevel_extensions, descriptor.FieldDescriptor), - (self._top_enum_values, descriptor.EnumValueDescriptor), - ]: - if desc_name in register: - old_desc = register[desc_name] - if isinstance(old_desc, descriptor.EnumValueDescriptor): - old_file = old_desc.type.file.name - else: - old_file = old_desc.file.name - - if not isinstance(desc, descriptor_type) or (old_file != file_name): - error_msg = ( - 'Conflict register for file "' - + file_name - + '": ' - + desc_name - + ' is already defined in file "' - + old_file - + '". Please fix the conflict by adding ' - 'package name on the proto file, or use different ' - 'name for the duplication.' - ) - if isinstance(desc, descriptor.EnumValueDescriptor): - error_msg += ( - '\nNote: enum values appear as ' - 'siblings of the enum type instead of ' - 'children of it.' - ) - - raise TypeError(error_msg) - - return - - def Add(self, file_desc_proto): - """Adds the FileDescriptorProto and its types to this pool. - - Args: - file_desc_proto (FileDescriptorProto): The file descriptor to add. - """ - - self._internal_db.Add(file_desc_proto) - - def AddSerializedFile(self, serialized_file_desc_proto): - """Adds the FileDescriptorProto and its types to this pool. - - Args: - serialized_file_desc_proto (bytes): A bytes string, serialization of the - :class:`FileDescriptorProto` to add. - - Returns: - FileDescriptor: Descriptor for the added file. - """ - - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString( - serialized_file_desc_proto - ) - file_desc = self._ConvertFileProtoToFileDescriptor(file_desc_proto) - file_desc.serialized_pb = serialized_file_desc_proto - return file_desc - - # Never call this method. It is for internal usage only. - def _AddDescriptor(self, desc): - """Adds a Descriptor to the pool, non-recursively. - - If the Descriptor contains nested messages or enums, the caller must - explicitly register them. This method also registers the FileDescriptor - associated with the message. - - Args: - desc: A Descriptor. - """ - if not isinstance(desc, descriptor.Descriptor): - raise TypeError('Expected instance of descriptor.Descriptor.') - - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - - self._descriptors[desc.full_name] = desc - self._AddFileDescriptor(desc.file) - - # Never call this method. It is for internal usage only. - def _AddEnumDescriptor(self, enum_desc): - """Adds an EnumDescriptor to the pool. - - This method also registers the FileDescriptor associated with the enum. - - Args: - enum_desc: An EnumDescriptor. - """ - - if not isinstance(enum_desc, descriptor.EnumDescriptor): - raise TypeError('Expected instance of descriptor.EnumDescriptor.') - - file_name = enum_desc.file.name - self._CheckConflictRegister(enum_desc, enum_desc.full_name, file_name) - self._enum_descriptors[enum_desc.full_name] = enum_desc - - # Top enum values need to be indexed. - # Count the number of dots to see whether the enum is toplevel or nested - # in a message. We cannot use enum_desc.containing_type at this stage. - if enum_desc.file.package: - top_level = ( - enum_desc.full_name.count('.') - enum_desc.file.package.count('.') - == 1 - ) - else: - top_level = enum_desc.full_name.count('.') == 0 - if top_level: - file_name = enum_desc.file.name - package = enum_desc.file.package - for enum_value in enum_desc.values: - full_name = _NormalizeFullyQualifiedName( - '.'.join((package, enum_value.name)) - ) - self._CheckConflictRegister(enum_value, full_name, file_name) - self._top_enum_values[full_name] = enum_value - self._AddFileDescriptor(enum_desc.file) - - # Never call this method. It is for internal usage only. - def _AddServiceDescriptor(self, service_desc): - """Adds a ServiceDescriptor to the pool. - - Args: - service_desc: A ServiceDescriptor. - """ - - if not isinstance(service_desc, descriptor.ServiceDescriptor): - raise TypeError('Expected instance of descriptor.ServiceDescriptor.') - - self._CheckConflictRegister( - service_desc, service_desc.full_name, service_desc.file.name - ) - self._service_descriptors[service_desc.full_name] = service_desc - - # Never call this method. It is for internal usage only. - def _AddExtensionDescriptor(self, extension): - """Adds a FieldDescriptor describing an extension to the pool. - - Args: - extension: A FieldDescriptor. - - Raises: - AssertionError: when another extension with the same number extends the - same message. - TypeError: when the specified extension is not a - descriptor.FieldDescriptor. - """ - if not ( - isinstance(extension, descriptor.FieldDescriptor) - and extension.is_extension - ): - raise TypeError('Expected an extension descriptor.') - - if extension.extension_scope is None: - self._CheckConflictRegister( - extension, extension.full_name, extension.file.name - ) - self._toplevel_extensions[extension.full_name] = extension - - try: - existing_desc = self._extensions_by_number[extension.containing_type][ - extension.number - ] - except KeyError: - pass - else: - if extension is not existing_desc: - raise AssertionError( - 'Extensions "%s" and "%s" both try to extend message type "%s" ' - 'with field number %d.' - % ( - extension.full_name, - existing_desc.full_name, - extension.containing_type.full_name, - extension.number, - ) - ) - - self._extensions_by_number[extension.containing_type][ - extension.number - ] = extension - self._extensions_by_name[extension.containing_type][ - extension.full_name - ] = extension - - # Also register MessageSet extensions with the type name. - if _IsMessageSetExtension(extension): - self._extensions_by_name[extension.containing_type][ - extension.message_type.full_name - ] = extension - - if hasattr(extension.containing_type, '_concrete_class'): - python_message._AttachFieldHelpers( - extension.containing_type._concrete_class, extension - ) - - # Never call this method. It is for internal usage only. - def _InternalAddFileDescriptor(self, file_desc): - """Adds a FileDescriptor to the pool, non-recursively. - - If the FileDescriptor contains messages or enums, the caller must explicitly - register them. - - Args: - file_desc: A FileDescriptor. - """ - - self._AddFileDescriptor(file_desc) - - def _AddFileDescriptor(self, file_desc): - """Adds a FileDescriptor to the pool, non-recursively. - - If the FileDescriptor contains messages or enums, the caller must explicitly - register them. - - Args: - file_desc: A FileDescriptor. - """ - - if not isinstance(file_desc, descriptor.FileDescriptor): - raise TypeError('Expected instance of descriptor.FileDescriptor.') - self._file_descriptors[file_desc.name] = file_desc - - def FindFileByName(self, file_name): - """Gets a FileDescriptor by file name. - - Args: - file_name (str): The path to the file to get a descriptor for. - - Returns: - FileDescriptor: The descriptor for the named file. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - - try: - return self._file_descriptors[file_name] - except KeyError: - pass - - try: - file_proto = self._internal_db.FindFileByName(file_name) - except KeyError as error: - if self._descriptor_db: - file_proto = self._descriptor_db.FindFileByName(file_name) - else: - raise error - if not file_proto: - raise KeyError('Cannot find a file named %s' % file_name) - return self._ConvertFileProtoToFileDescriptor(file_proto) - - def FindFileContainingSymbol(self, symbol): - """Gets the FileDescriptor for the file containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: Descriptor for the file that contains the specified - symbol. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - - symbol = _NormalizeFullyQualifiedName(symbol) - try: - return self._InternalFindFileContainingSymbol(symbol) - except KeyError: - pass - - try: - # Try fallback database. Build and find again if possible. - self._FindFileContainingSymbolInDb(symbol) - return self._InternalFindFileContainingSymbol(symbol) - except KeyError: - raise KeyError('Cannot find a file containing %s' % symbol) - - def _InternalFindFileContainingSymbol(self, symbol): - """Gets the already built FileDescriptor containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: Descriptor for the file that contains the specified - symbol. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - try: - return self._descriptors[symbol].file - except KeyError: - pass - - try: - return self._enum_descriptors[symbol].file - except KeyError: - pass - - try: - return self._service_descriptors[symbol].file - except KeyError: - pass - - try: - return self._top_enum_values[symbol].type.file - except KeyError: - pass - - try: - return self._toplevel_extensions[symbol].file - except KeyError: - pass - - # Try fields, enum values and nested extensions inside a message. - top_name, _, sub_name = symbol.rpartition('.') - try: - message = self.FindMessageTypeByName(top_name) - assert ( - sub_name in message.extensions_by_name - or sub_name in message.fields_by_name - or sub_name in message.enum_values_by_name - ) - return message.file - except (KeyError, AssertionError): - raise KeyError('Cannot find a file containing %s' % symbol) - - def FindMessageTypeByName(self, full_name): - """Loads the named descriptor from the pool. - - Args: - full_name (str): The full name of the descriptor to load. - - Returns: - Descriptor: The descriptor for the named type. - - Raises: - KeyError: if the message cannot be found in the pool. - """ - - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._descriptors[full_name] - - def FindEnumTypeByName(self, full_name): - """Loads the named enum descriptor from the pool. - - Args: - full_name (str): The full name of the enum descriptor to load. - - Returns: - EnumDescriptor: The enum descriptor for the named type. - - Raises: - KeyError: if the enum cannot be found in the pool. - """ - - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._enum_descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._enum_descriptors[full_name] - - def FindFieldByName(self, full_name): - """Loads the named field descriptor from the pool. - - Args: - full_name (str): The full name of the field descriptor to load. - - Returns: - FieldDescriptor: The field descriptor for the named field. - - Raises: - KeyError: if the field cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - message_name, _, field_name = full_name.rpartition('.') - message_descriptor = self.FindMessageTypeByName(message_name) - return message_descriptor.fields_by_name[field_name] - - def FindOneofByName(self, full_name): - """Loads the named oneof descriptor from the pool. - - Args: - full_name (str): The full name of the oneof descriptor to load. - - Returns: - OneofDescriptor: The oneof descriptor for the named oneof. - - Raises: - KeyError: if the oneof cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - message_name, _, oneof_name = full_name.rpartition('.') - message_descriptor = self.FindMessageTypeByName(message_name) - return message_descriptor.oneofs_by_name[oneof_name] - - def FindExtensionByName(self, full_name): - """Loads the named extension descriptor from the pool. - - Args: - full_name (str): The full name of the extension descriptor to load. - - Returns: - FieldDescriptor: The field descriptor for the named extension. - - Raises: - KeyError: if the extension cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - try: - # The proto compiler does not give any link between the FileDescriptor - # and top-level extensions unless the FileDescriptorProto is added to - # the DescriptorDatabase, but this can impact memory usage. - # So we registered these extensions by name explicitly. - return self._toplevel_extensions[full_name] - except KeyError: - pass - message_name, _, extension_name = full_name.rpartition('.') - try: - # Most extensions are nested inside a message. - scope = self.FindMessageTypeByName(message_name) - except KeyError: - # Some extensions are defined at file scope. - scope = self._FindFileContainingSymbolInDb(full_name) - return scope.extensions_by_name[extension_name] - - def FindExtensionByNumber(self, message_descriptor, number): - """Gets the extension of the specified message with the specified number. - - Extensions have to be registered to this pool by calling :func:`Add` or - :func:`AddExtensionDescriptor`. - - Args: - message_descriptor (Descriptor): descriptor of the extended message. - number (int): Number of the extension field. - - Returns: - FieldDescriptor: The descriptor for the extension. - - Raises: - KeyError: when no extension with the given number is known for the - specified message. - """ - try: - return self._extensions_by_number[message_descriptor][number] - except KeyError: - self._TryLoadExtensionFromDB(message_descriptor, number) - return self._extensions_by_number[message_descriptor][number] - - def FindAllExtensions(self, message_descriptor): - """Gets all the known extensions of a given message. - - Extensions have to be registered to this pool by build related - :func:`Add` or :func:`AddExtensionDescriptor`. - - Args: - message_descriptor (Descriptor): Descriptor of the extended message. - - Returns: - list[FieldDescriptor]: Field descriptors describing the extensions. - """ - # Fallback to descriptor db if FindAllExtensionNumbers is provided. - if self._descriptor_db and hasattr( - self._descriptor_db, 'FindAllExtensionNumbers' - ): - full_name = message_descriptor.full_name - try: - all_numbers = self._descriptor_db.FindAllExtensionNumbers(full_name) - except: - pass - else: - if isinstance(all_numbers, list): - for number in all_numbers: - if number in self._extensions_by_number[message_descriptor]: - continue - self._TryLoadExtensionFromDB(message_descriptor, number) - else: - warnings.warn( - 'FindAllExtensionNumbers() on fall back DB must return a list,' - ' not {0}'.format(type(all_numbers)) - ) - - return list(self._extensions_by_number[message_descriptor].values()) - - def _TryLoadExtensionFromDB(self, message_descriptor, number): - """Try to Load extensions from descriptor db. - - Args: - message_descriptor: descriptor of the extended message. - number: the extension number that needs to be loaded. - """ - if not self._descriptor_db: - return - # Only supported when FindFileContainingExtension is provided. - if not hasattr(self._descriptor_db, 'FindFileContainingExtension'): - return - - full_name = message_descriptor.full_name - file_proto = None - try: - file_proto = self._descriptor_db.FindFileContainingExtension( - full_name, number - ) - except: - return - - if file_proto is None: - return - - try: - self._ConvertFileProtoToFileDescriptor(file_proto) - except: - warn_msg = 'Unable to load proto file %s for extension number %d.' % ( - file_proto.name, - number, - ) - warnings.warn(warn_msg, RuntimeWarning) - - def FindServiceByName(self, full_name): - """Loads the named service descriptor from the pool. - - Args: - full_name (str): The full name of the service descriptor to load. - - Returns: - ServiceDescriptor: The service descriptor for the named service. - - Raises: - KeyError: if the service cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._service_descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._service_descriptors[full_name] - - def FindMethodByName(self, full_name): - """Loads the named service method descriptor from the pool. - - Args: - full_name (str): The full name of the method descriptor to load. - - Returns: - MethodDescriptor: The method descriptor for the service method. - - Raises: - KeyError: if the method cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - service_name, _, method_name = full_name.rpartition('.') - service_descriptor = self.FindServiceByName(service_name) - return service_descriptor.methods_by_name[method_name] - - def SetFeatureSetDefaults(self, defaults): - """Sets the default feature mappings used during the build. - - Args: - defaults: a FeatureSetDefaults message containing the new mappings. - """ - if self._edition_defaults is not None: - raise ValueError( - "Feature set defaults can't be changed once the pool has started" - ' building!' - ) - - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - if not isinstance(defaults, descriptor_pb2.FeatureSetDefaults): - raise TypeError('SetFeatureSetDefaults called with invalid type') - - if defaults.minimum_edition > defaults.maximum_edition: - raise ValueError( - 'Invalid edition range %s to %s' - % ( - descriptor_pb2.Edition.Name(defaults.minimum_edition), - descriptor_pb2.Edition.Name(defaults.maximum_edition), - ) - ) - - prev_edition = descriptor_pb2.Edition.EDITION_UNKNOWN - for d in defaults.defaults: - if d.edition == descriptor_pb2.Edition.EDITION_UNKNOWN: - raise ValueError('Invalid edition EDITION_UNKNOWN specified') - if prev_edition >= d.edition: - raise ValueError( - 'Feature set defaults are not strictly increasing. %s is greater' - ' than or equal to %s' - % ( - descriptor_pb2.Edition.Name(prev_edition), - descriptor_pb2.Edition.Name(d.edition), - ) - ) - prev_edition = d.edition - self._edition_defaults = defaults - - def _CreateDefaultFeatures(self, edition): - """Creates a FeatureSet message with defaults for a specific edition. - - Args: - edition: the edition to generate defaults for. - - Returns: - A FeatureSet message with defaults for a specific edition. - """ - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - with _edition_defaults_lock: - if not self._edition_defaults: - self._edition_defaults = descriptor_pb2.FeatureSetDefaults() - self._edition_defaults.ParseFromString( - self._serialized_edition_defaults - ) - - if edition < self._edition_defaults.minimum_edition: - raise TypeError( - 'Edition %s is earlier than the minimum supported edition %s!' - % ( - descriptor_pb2.Edition.Name(edition), - descriptor_pb2.Edition.Name( - self._edition_defaults.minimum_edition - ), - ) - ) - if ( - edition > self._edition_defaults.maximum_edition - and edition != descriptor_pb2.EDITION_UNSTABLE - ): - raise TypeError( - 'Edition %s is later than the maximum supported edition %s!' - % ( - descriptor_pb2.Edition.Name(edition), - descriptor_pb2.Edition.Name( - self._edition_defaults.maximum_edition - ), - ) - ) - found = None - for d in self._edition_defaults.defaults: - if d.edition > edition: - break - found = d - if found is None: - raise TypeError( - 'No valid default found for edition %s!' - % descriptor_pb2.Edition.Name(edition) - ) - - defaults = descriptor_pb2.FeatureSet() - defaults.CopyFrom(found.fixed_features) - defaults.MergeFrom(found.overridable_features) - return defaults - - def _InternFeatures(self, features): - serialized = features.SerializeToString() - with _edition_defaults_lock: - cached = self._feature_cache.get(serialized) - if cached is None: - self._feature_cache[serialized] = features - cached = features - return cached - - def _FindFileContainingSymbolInDb(self, symbol): - """Finds the file in descriptor DB containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: The file that contains the specified symbol. - - Raises: - KeyError: if the file cannot be found in the descriptor database. - """ - try: - file_proto = self._internal_db.FindFileContainingSymbol(symbol) - except KeyError as error: - if self._descriptor_db: - file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) - else: - raise error - if not file_proto: - raise KeyError('Cannot find a file containing %s' % symbol) - return self._ConvertFileProtoToFileDescriptor(file_proto) - - def _ConvertFileProtoToFileDescriptor(self, file_proto): - """Creates a FileDescriptor from a proto or returns a cached copy. - - This method also has the side effect of loading all the symbols found in - the file into the appropriate dictionaries in the pool. - - Args: - file_proto: The proto to convert. - - Returns: - A FileDescriptor matching the passed in proto. - """ - if file_proto.name not in self._file_descriptors: - built_deps = list(self._GetDeps(file_proto.dependency)) - direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] - public_deps = [direct_deps[i] for i in file_proto.public_dependency] - - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 - - file_descriptor = descriptor.FileDescriptor( - pool=self, - name=file_proto.name, - package=file_proto.package, - syntax=file_proto.syntax, - edition=descriptor_pb2.Edition.Name(file_proto.edition), - options=_OptionsOrNone(file_proto), - serialized_pb=file_proto.SerializeToString(), - dependencies=direct_deps, - public_dependencies=public_deps, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - scope = {} - - # This loop extracts all the message and enum types from all the - # dependencies of the file_proto. This is necessary to create the - # scope of available message types when defining the passed in - # file proto. - for dependency in built_deps: - scope.update( - self._ExtractSymbols(dependency.message_types_by_name.values()) - ) - scope.update( - (_PrefixWithDot(enum.full_name), enum) - for enum in dependency.enum_types_by_name.values() - ) - - for message_type in file_proto.message_type: - message_desc = self._ConvertMessageDescriptor( - message_type, - file_proto.package, - file_descriptor, - scope, - file_proto.syntax, - ) - file_descriptor.message_types_by_name[message_desc.name] = message_desc - - for enum_type in file_proto.enum_type: - file_descriptor.enum_types_by_name[enum_type.name] = ( - self._ConvertEnumDescriptor( - enum_type, - file_proto.package, - file_descriptor, - None, - scope, - True, - ) - ) - - for index, extension_proto in enumerate(file_proto.extension): - extension_desc = self._MakeFieldDescriptor( - extension_proto, - file_proto.package, - index, - file_descriptor, - is_extension=True, - ) - extension_desc.containing_type = self._GetTypeFromScope( - file_descriptor.package, extension_proto.extendee, scope - ) - self._SetFieldType( - extension_proto, extension_desc, file_descriptor.package, scope - ) - file_descriptor.extensions_by_name[extension_desc.name] = extension_desc - - for desc_proto in file_proto.message_type: - self._SetAllFieldTypes(file_proto.package, desc_proto, scope) - - if file_proto.package: - desc_proto_prefix = _PrefixWithDot(file_proto.package) - else: - desc_proto_prefix = '' - - for desc_proto in file_proto.message_type: - desc = self._GetTypeFromScope(desc_proto_prefix, desc_proto.name, scope) - file_descriptor.message_types_by_name[desc_proto.name] = desc - - for index, service_proto in enumerate(file_proto.service): - file_descriptor.services_by_name[service_proto.name] = ( - self._MakeServiceDescriptor( - service_proto, index, scope, file_proto.package, file_descriptor - ) - ) - - self._file_descriptors[file_proto.name] = file_descriptor - - # Add extensions to the pool - def AddExtensionForNested(message_type): - for nested in message_type.nested_types: - AddExtensionForNested(nested) - for extension in message_type.extensions: - self._AddExtensionDescriptor(extension) - - file_desc = self._file_descriptors[file_proto.name] - for extension in file_desc.extensions_by_name.values(): - self._AddExtensionDescriptor(extension) - for message_type in file_desc.message_types_by_name.values(): - AddExtensionForNested(message_type) - - return file_desc - - def _ConvertMessageDescriptor( - self, desc_proto, package=None, file_desc=None, scope=None, syntax=None - ): - """Adds the proto to the pool in the specified package. - - Args: - desc_proto: The descriptor_pb2.DescriptorProto protobuf message. - package: The package the proto should be located in. - file_desc: The file containing this message. - scope: Dict mapping short and full symbols to message and enum types. - syntax: string indicating syntax of the file ("proto2" or "proto3") - - Returns: - The added descriptor. - """ - - if package: - desc_name = '.'.join((package, desc_proto.name)) - else: - desc_name = desc_proto.name - - if file_desc is None: - file_name = None - else: - file_name = file_desc.name - - if scope is None: - scope = {} - - nested = [ - self._ConvertMessageDescriptor( - nested, desc_name, file_desc, scope, syntax - ) - for nested in desc_proto.nested_type - ] - enums = [ - self._ConvertEnumDescriptor( - enum, desc_name, file_desc, None, scope, False - ) - for enum in desc_proto.enum_type - ] - fields = [ - self._MakeFieldDescriptor(field, desc_name, index, file_desc) - for index, field in enumerate(desc_proto.field) - ] - extensions = [ - self._MakeFieldDescriptor( - extension, desc_name, index, file_desc, is_extension=True - ) - for index, extension in enumerate(desc_proto.extension) - ] - oneofs = [ - # pylint: disable=g-complex-comprehension - descriptor.OneofDescriptor( - desc.name, - '.'.join((desc_name, desc.name)), - index, - None, - [], - _OptionsOrNone(desc), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - for index, desc in enumerate(desc_proto.oneof_decl) - ] - extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] - if extension_ranges: - is_extendable = True - else: - is_extendable = False - desc = descriptor.Descriptor( - name=desc_proto.name, - full_name=desc_name, - filename=file_name, - containing_type=None, - fields=fields, - oneofs=oneofs, - nested_types=nested, - enum_types=enums, - extensions=extensions, - options=_OptionsOrNone(desc_proto), - is_extendable=is_extendable, - extension_ranges=extension_ranges, - file=file_desc, - serialized_start=None, - serialized_end=None, - is_map_entry=desc_proto.options.map_entry, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - for nested in desc.nested_types: - nested.containing_type = desc - for enum in desc.enum_types: - enum.containing_type = desc - for field_index, field_desc in enumerate(desc_proto.field): - if field_desc.HasField('oneof_index'): - oneof_index = field_desc.oneof_index - oneofs[oneof_index].fields.append(fields[field_index]) - fields[field_index].containing_oneof = oneofs[oneof_index] - - scope[_PrefixWithDot(desc_name)] = desc - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._descriptors[desc_name] = desc - return desc - - def _ConvertEnumDescriptor( - self, - enum_proto, - package=None, - file_desc=None, - containing_type=None, - scope=None, - top_level=False, - ): - """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf. - - Args: - enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message. - package: Optional package name for the new message EnumDescriptor. - file_desc: The file containing the enum descriptor. - containing_type: The type containing this enum. - scope: Scope containing available types. - top_level: If True, the enum is a top level symbol. If False, the enum is - defined inside a message. - - Returns: - The added descriptor - """ - - if package: - enum_name = '.'.join((package, enum_proto.name)) - else: - enum_name = enum_proto.name - - if file_desc is None: - file_name = None - else: - file_name = file_desc.name - - values = [ - self._MakeEnumValueDescriptor(value, index) - for index, value in enumerate(enum_proto.value) - ] - desc = descriptor.EnumDescriptor( - name=enum_proto.name, - full_name=enum_name, - filename=file_name, - file=file_desc, - values=values, - containing_type=containing_type, - options=_OptionsOrNone(enum_proto), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - scope['.%s' % enum_name] = desc - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._enum_descriptors[enum_name] = desc - - # Add top level enum values. - if top_level: - for value in values: - full_name = _NormalizeFullyQualifiedName( - '.'.join((package, value.name)) - ) - self._CheckConflictRegister(value, full_name, file_name) - self._top_enum_values[full_name] = value - - return desc - - def _MakeFieldDescriptor( - self, field_proto, message_name, index, file_desc, is_extension=False - ): - """Creates a field descriptor from a FieldDescriptorProto. - - For message and enum type fields, this method will do a look up - in the pool for the appropriate descriptor for that type. If it - is unavailable, it will fall back to the _source function to - create it. If this type is still unavailable, construction will - fail. - - Args: - field_proto: The proto describing the field. - message_name: The name of the containing message. - index: Index of the field - file_desc: The file containing the field descriptor. - is_extension: Indication that this field is for an extension. - - Returns: - An initialized FieldDescriptor object - """ - - if message_name: - full_name = '.'.join((message_name, field_proto.name)) - else: - full_name = field_proto.name - - if field_proto.json_name: - json_name = field_proto.json_name - else: - json_name = None - - return descriptor.FieldDescriptor( - name=field_proto.name, - full_name=full_name, - index=index, - number=field_proto.number, - type=field_proto.type, - cpp_type=None, - message_type=None, - enum_type=None, - containing_type=None, - label=field_proto.label, - has_default_value=False, - default_value=None, - is_extension=is_extension, - extension_scope=None, - options=_OptionsOrNone(field_proto), - json_name=json_name, - file=file_desc, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - - def _SetAllFieldTypes(self, package, desc_proto, scope): - """Sets all the descriptor's fields's types. - - This method also sets the containing types on any extensions. - - Args: - package: The current package of desc_proto. - desc_proto: The message descriptor to update. - scope: Enclosing scope of available types. - """ - - package = _PrefixWithDot(package) - - main_desc = self._GetTypeFromScope(package, desc_proto.name, scope) - - if package == '.': - nested_package = _PrefixWithDot(desc_proto.name) - else: - nested_package = '.'.join([package, desc_proto.name]) - - for field_proto, field_desc in zip(desc_proto.field, main_desc.fields): - self._SetFieldType(field_proto, field_desc, nested_package, scope) - - for extension_proto, extension_desc in zip( - desc_proto.extension, main_desc.extensions - ): - extension_desc.containing_type = self._GetTypeFromScope( - nested_package, extension_proto.extendee, scope - ) - self._SetFieldType(extension_proto, extension_desc, nested_package, scope) - - for nested_type in desc_proto.nested_type: - self._SetAllFieldTypes(nested_package, nested_type, scope) - - def _SetFieldType(self, field_proto, field_desc, package, scope): - """Sets the field's type, cpp_type, message_type and enum_type. - - Args: - field_proto: Data about the field in proto format. - field_desc: The descriptor to modify. - package: The package the field's container is in. - scope: Enclosing scope of available types. - """ - if field_proto.type_name: - desc = self._GetTypeFromScope(package, field_proto.type_name, scope) - else: - desc = None - - if not field_proto.HasField('type'): - if isinstance(desc, descriptor.Descriptor): - field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE - else: - field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM - - field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType( - field_proto.type - ) - - if ( - field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE - or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP - ): - field_desc.message_type = desc - - if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.enum_type = desc - - if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED: - field_desc.has_default_value = False - field_desc.default_value = [] - elif field_proto.HasField('default_value'): - field_desc.has_default_value = True - if ( - field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE - or field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT - ): - field_desc.default_value = float(field_proto.default_value) - elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: - field_desc.default_value = field_proto.default_value - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: - field_desc.default_value = field_proto.default_value.lower() == 'true' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.default_value = field_desc.enum_type.values_by_name[ - field_proto.default_value - ].number - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: - field_desc.default_value = text_encoding.CUnescape( - field_proto.default_value - ) - elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: - field_desc.default_value = None - else: - # All other types are of the "int" type. - field_desc.default_value = int(field_proto.default_value) - else: - field_desc.has_default_value = False - if ( - field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE - or field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT - ): - field_desc.default_value = 0.0 - elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: - field_desc.default_value = '' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: - field_desc.default_value = False - elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.default_value = field_desc.enum_type.values[0].number - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: - field_desc.default_value = b'' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: - field_desc.default_value = None - elif field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP: - field_desc.default_value = None - else: - # All other types are of the "int" type. - field_desc.default_value = 0 - - field_desc.type = field_proto.type - - def _MakeEnumValueDescriptor(self, value_proto, index): - """Creates a enum value descriptor object from a enum value proto. - - Args: - value_proto: The proto describing the enum value. - index: The index of the enum value. - - Returns: - An initialized EnumValueDescriptor object. - """ - - return descriptor.EnumValueDescriptor( - name=value_proto.name, - index=index, - number=value_proto.number, - options=_OptionsOrNone(value_proto), - type=None, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - - def _MakeServiceDescriptor( - self, service_proto, service_index, scope, package, file_desc - ): - """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto. - - Args: - service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message. - service_index: The index of the service in the File. - scope: Dict mapping short and full symbols to message and enum types. - package: Optional package name for the new message EnumDescriptor. - file_desc: The file containing the service descriptor. - - Returns: - The added descriptor. - """ - - if package: - service_name = '.'.join((package, service_proto.name)) - else: - service_name = service_proto.name - - methods = [ - self._MakeMethodDescriptor( - method_proto, service_name, package, scope, index - ) - for index, method_proto in enumerate(service_proto.method) - ] - desc = descriptor.ServiceDescriptor( - name=service_proto.name, - full_name=service_name, - index=service_index, - methods=methods, - options=_OptionsOrNone(service_proto), - file=file_desc, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._service_descriptors[service_name] = desc - return desc - - def _MakeMethodDescriptor( - self, method_proto, service_name, package, scope, index - ): - """Creates a method descriptor from a MethodDescriptorProto. - - Args: - method_proto: The proto describing the method. - service_name: The name of the containing service. - package: Optional package name to look up for types. - scope: Scope containing available types. - index: Index of the method in the service. - - Returns: - An initialized MethodDescriptor object. - """ - full_name = '.'.join((service_name, method_proto.name)) - input_type = self._GetTypeFromScope(package, method_proto.input_type, scope) - output_type = self._GetTypeFromScope( - package, method_proto.output_type, scope - ) - return descriptor.MethodDescriptor( - name=method_proto.name, - full_name=full_name, - index=index, - containing_service=None, - input_type=input_type, - output_type=output_type, - client_streaming=method_proto.client_streaming, - server_streaming=method_proto.server_streaming, - options=_OptionsOrNone(method_proto), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key, - ) - - def _ExtractSymbols(self, descriptors): - """Pulls out all the symbols from descriptor protos. - - Args: - descriptors: The messages to extract descriptors from. - - Yields: - A two element tuple of the type name and descriptor object. - """ - - for desc in descriptors: - yield (_PrefixWithDot(desc.full_name), desc) - for symbol in self._ExtractSymbols(desc.nested_types): - yield symbol - for enum in desc.enum_types: - yield (_PrefixWithDot(enum.full_name), enum) - - def _GetDeps(self, dependencies, visited=None): - """Recursively finds dependencies for file protos. - - Args: - dependencies: The names of the files being depended on. - visited: The names of files already found. - - Yields: - Each direct and indirect dependency. - """ - - visited = visited or set() - for dependency in dependencies: - if dependency not in visited: - visited.add(dependency) - dep_desc = self.FindFileByName(dependency) - yield dep_desc - public_files = [d.name for d in dep_desc.public_dependencies] - yield from self._GetDeps(public_files, visited) - - def _GetTypeFromScope(self, package, type_name, scope): - """Finds a given type name in the current scope. - - Args: - package: The package the proto should be located in. - type_name: The name of the type to be found in the scope. - scope: Dict mapping short and full symbols to message and enum types. - - Returns: - The descriptor for the requested type. - """ - if type_name not in scope: - components = _PrefixWithDot(package).split('.') - while components: - possible_match = '.'.join(components + [type_name]) - if possible_match in scope: - type_name = possible_match - break - else: - components.pop(-1) - return scope[type_name] - - -def _PrefixWithDot(name): - return name if name.startswith('.') else '.%s' % name - - -if _USE_C_DESCRIPTORS: - # TODO: This pool could be constructed from Python code, when we - # support a flag like 'use_cpp_generated_pool=True'. - # pylint: disable=protected-access - _DEFAULT = descriptor._message.default_pool -else: - _DEFAULT = DescriptorPool() - - -def Default(): - return _DEFAULT diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py deleted file mode 100644 index da6d2f3187f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration.py +++ /dev/null @@ -1,100 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -"""Contains the Duration helper APIs.""" - -import datetime - -from opentelemetry.agent._vendor.google.protobuf.duration_pb2 import Duration - - -def from_json_string(value: str) -> Duration: - """Converts a string to Duration. - - Args: - value: A string to be converted. The string must end with 's'. Any - fractional digits (or none) are accepted as long as they fit into - precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s" - - Raises: - ValueError: On parsing problems. - """ - duration = Duration() - duration.FromJsonString(value) - return duration - - -def from_microseconds(micros: float) -> Duration: - """Converts microseconds to Duration.""" - duration = Duration() - duration.FromMicroseconds(micros) - return duration - - -def from_milliseconds(millis: float) -> Duration: - """Converts milliseconds to Duration.""" - duration = Duration() - duration.FromMilliseconds(millis) - return duration - - -def from_nanoseconds(nanos: float) -> Duration: - """Converts nanoseconds to Duration.""" - duration = Duration() - duration.FromNanoseconds(nanos) - return duration - - -def from_seconds(seconds: float) -> Duration: - """Converts seconds to Duration.""" - duration = Duration() - duration.FromSeconds(seconds) - return duration - - -def from_timedelta(td: datetime.timedelta) -> Duration: - """Converts timedelta to Duration.""" - duration = Duration() - duration.FromTimedelta(td) - return duration - - -def to_json_string(duration: Duration) -> str: - """Converts Duration to string format. - - Returns: - A string converted from self. The string format will contains - 3, 6, or 9 fractional digits depending on the precision required to - represent the exact Duration value. For example: "1s", "1.010s", - "1.000000100s", "-3.100s" - """ - return duration.ToJsonString() - - -def to_microseconds(duration: Duration) -> int: - """Converts a Duration to microseconds.""" - return duration.ToMicroseconds() - - -def to_milliseconds(duration: Duration) -> int: - """Converts a Duration to milliseconds.""" - return duration.ToMilliseconds() - - -def to_nanoseconds(duration: Duration) -> int: - """Converts a Duration to nanoseconds.""" - return duration.ToNanoseconds() - - -def to_seconds(duration: Duration) -> int: - """Converts a Duration to seconds.""" - return duration.ToSeconds() - - -def to_timedelta(duration: Duration) -> datetime.timedelta: - """Converts Duration to timedelta.""" - return duration.ToTimedelta() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py deleted file mode 100644 index 42bcce9c456..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/duration_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/duration.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/duration.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/duration.proto\x12\x0fgoogle.protobuf\":\n\x08\x44uration\x12\x18\n\x07seconds\x18\x01 \x01(\x03R\x07seconds\x12\x14\n\x05nanos\x18\x02 \x01(\x05R\x05nanosB\x83\x01\n\x13\x63om.google.protobufB\rDurationProtoP\x01Z1google.golang.org/protobuf/types/known/durationpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.duration_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\rDurationProtoP\001Z1google.golang.org/protobuf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_DURATION']._serialized_start=51 - _globals['_DURATION']._serialized_end=109 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py deleted file mode 100644 index 4c0ea6d2df6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/empty_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/empty.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/empty.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bgoogle/protobuf/empty.proto\x12\x0fgoogle.protobuf\"\x07\n\x05\x45mptyB}\n\x13\x63om.google.protobufB\nEmptyProtoP\x01Z.google.golang.org/protobuf/types/known/emptypb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.empty_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\nEmptyProtoP\001Z.google.golang.org/protobuf/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_EMPTY']._serialized_start=48 - _globals['_EMPTY']._serialized_end=55 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py deleted file mode 100644 index 5c7fd0002b1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/field_mask_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/field_mask.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/field_mask.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/field_mask.proto\x12\x0fgoogle.protobuf\"!\n\tFieldMask\x12\x14\n\x05paths\x18\x01 \x03(\tR\x05pathsB\x85\x01\n\x13\x63om.google.protobufB\x0e\x46ieldMaskProtoP\x01Z2google.golang.org/protobuf/types/known/fieldmaskpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.field_mask_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\016FieldMaskProtoP\001Z2google.golang.org/protobuf/types/known/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_FIELDMASK']._serialized_start=53 - _globals['_FIELDMASK']._serialized_end=86 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py deleted file mode 100644 index 80d99fe5b1f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py deleted file mode 100644 index ae716eea5d8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/api_implementation.py +++ /dev/null @@ -1,72 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Determine which implementation of the protobuf API is used in this process.""" - -import os -import sys -import warnings - -_GOOGLE3_PYTHON_UPB_DEFAULT = True - - -def _ApiVersionToImplementationType(api_version): - if api_version == 2: - return 'cpp' - if api_version == 1: - raise ValueError('api_version=1 is no longer supported.') - if api_version == 0: - return 'python' - return None - - -# Only the vendored upb extension is considered (platform builds of the agent include it; -# the pure-Python build doesn't). Never probe for the application's google._upb / -# google.protobuf.pyext by their top-level names, and don't follow -# PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION, which configures the application's protobuf -# (e.g. "cpp" would make descriptor.py import the missing vendored pyext._message). -try: - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google._upb import _message as _c_module - - _implementation_type = 'upb' -except ImportError: - _implementation_type = 'python' - _c_module = None - -# Detect if serialization should be deterministic by default -try: - # The presence of this module in a build allows the proto implementation to - # be upgraded merely via build deps. - # - # NOTE: Merely importing this automatically enables deterministic proto - # serialization for C++ code, but we still need to export it as a boolean so - # that we can do the same for `_implementation_type == 'python'`. - # - # NOTE2: It is possible for C++ code to enable deterministic serialization by - # default _without_ affecting Python code, if the C++ implementation is not in - # use by this module. That is intended behavior, so we don't actually expose - # this boolean outside of this module. - # - # pylint: disable=g-import-not-at-top,unused-import - from opentelemetry.agent._vendor.google.protobuf import enable_deterministic_proto_serialization - - _python_deterministic_proto_serialization = True -except ImportError: - _python_deterministic_proto_serialization = False - - -# Usage of this function is discouraged. Clients shouldn't care which -# implementation of the API is in use. Note that there is no guarantee -# that differences between APIs will be maintained. -# Please don't use this function if possible. -def Type(): - return _implementation_type - - -# For internal use only -def IsPythonDefaultSerializationDeterministic(): - return _python_deterministic_proto_serialization diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py deleted file mode 100644 index c8e81f9a218..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/builder.py +++ /dev/null @@ -1,123 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Builds descriptors, message classes and services for generated _pb2.py. - -This file is only called in python generated _pb2.py files. It builds -descriptors, message classes and services that users can directly use -in generated code. -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - -from opentelemetry.agent._vendor.google.protobuf import message as _message -from opentelemetry.agent._vendor.google.protobuf import reflection as _reflection -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import enum_type_wrapper -from opentelemetry.agent._vendor.google.protobuf.internal import python_message - -_sym_db = _symbol_database.Default() - - -def _BuildNestedDescriptors(module, msg_des, prefix): - for name, nested_msg in msg_des.nested_types_by_name.items(): - module_name = prefix + name.upper() - module[module_name] = nested_msg - _BuildNestedDescriptors(module, nested_msg, module_name + '_') - for enum_des in msg_des.enum_types: - module[prefix + enum_des.name.upper()] = enum_des - - -def BuildMessageAndEnumDescriptors(file_des, module): - """Builds message and enum descriptors. - - Args: - file_des: FileDescriptor of the .proto file - module: Generated _pb2 module - """ - for name, msg_des in file_des.message_types_by_name.items(): - module_name = '_' + name.upper() - module[module_name] = msg_des - _BuildNestedDescriptors(module, msg_des, module_name + '_') - - -def _BuildMessage(module_name, msg_des, prefix): - create_dict = {} - for name, nested_msg in msg_des.nested_types_by_name.items(): - create_dict[name] = _BuildMessage( - module_name, nested_msg, prefix + msg_des.name + '.' - ) - create_dict['DESCRIPTOR'] = msg_des - create_dict['__module__'] = module_name - create_dict['__qualname__'] = prefix + msg_des.name - message_class = _reflection.GeneratedProtocolMessageType( - msg_des.name, (_message.Message,), create_dict - ) - _sym_db.RegisterMessage(message_class) - return message_class - - -def BuildTopDescriptorsAndMessages(file_des, module_name, module): - """Builds top level descriptors and message classes. - - Args: - file_des: FileDescriptor of the .proto file - module_name: str, the name of generated _pb2 module - module: Generated _pb2 module - """ - - # top level enums - for name, enum_des in file_des.enum_types_by_name.items(): - module['_' + name.upper()] = enum_des - module[name] = enum_type_wrapper.EnumTypeWrapper(enum_des) - for enum_value in enum_des.values: - module[enum_value.name] = enum_value.number - - # top level extensions - for name, extension_des in file_des.extensions_by_name.items(): - module[name.upper() + '_FIELD_NUMBER'] = extension_des.number - module[name] = extension_des - - # services - for name, service in file_des.services_by_name.items(): - module['_' + name.upper()] = service - - # Build messages. - for name, msg_des in file_des.message_types_by_name.items(): - module[name] = _BuildMessage(module_name, msg_des, '') - - -def AddHelpersToExtensions(file_des): - """no-op to keep old generated code work with new runtime. - - Args: - file_des: FileDescriptor of the .proto file - """ - # TODO: Remove this on-op - return - - -def BuildServices(file_des, module_name, module): - """Builds services classes and services stub class. - - Args: - file_des: FileDescriptor of the .proto file - module_name: str, the name of generated _pb2 module - module: Generated _pb2 module - """ - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import service_reflection - # pylint: enable=g-import-not-at-top - for name, service in file_des.services_by_name.items(): - module[name] = service_reflection.GeneratedServiceType( - name, (), dict(DESCRIPTOR=service, __module__=module_name) - ) - stub_name = name + '_Stub' - module[stub_name] = service_reflection.GeneratedServiceStubType( - stub_name, - (module[name],), - dict(DESCRIPTOR=service, __module__=module_name), - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py deleted file mode 100644 index 18539ae1c2d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/containers.py +++ /dev/null @@ -1,826 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains container classes to represent different protocol buffer types. - -This file defines container classes which represent categories of protocol -buffer field types which need extra maintenance. Currently these categories -are: - -- Repeated scalar fields - These are all repeated fields which aren't - composite (e.g. they are of simple types like int32, string, etc). -- Repeated composite fields - Repeated fields which are composite. This - includes groups and nested messages. -""" - -import collections.abc -import copy -import pickle -import warnings -from typing import ( - Any, - Iterable, - Iterator, - List, - MutableMapping, - MutableSequence, - NoReturn, - Optional, - Sequence, - TypeVar, - Union, - overload, -) - -_T = TypeVar('_T') -_K = TypeVar('_K') -_V = TypeVar('_V') - -from opentelemetry.agent._vendor.google.protobuf.descriptor import FieldDescriptor -from opentelemetry.agent._vendor.google.protobuf import message - - -def _CheckFrozen(is_frozen: bool, msg: str) -> None: - if is_frozen: - warnings.warn( - 'Mutating messages or containers returned by GetOptions() is' - ' deprecated and will raise an exception in a future release.', - category=FutureWarning, - stacklevel=3, - ) - - -class BaseContainer(Sequence[_T]): - """Base container class.""" - - # Minimizes memory usage and disallows assignment to other attributes. - __slots__ = ['_message_listener', '_values', '_frozen'] - - def __init__(self, message_listener: Any) -> None: - """Args: - - message_listener: A MessageListener implementation. - The RepeatedScalarFieldContainer will call this object's - Modified() method when it is modified. - """ - self._message_listener = message_listener - self._values = [] - self._frozen = False - - @overload - def __getitem__(self, key: int) -> _T: - ... - - @overload - def __getitem__(self, key: slice) -> List[_T]: - ... - - def __getitem__(self, key): - """Retrieves item by the specified key.""" - return self._values[key] - - def __len__(self) -> int: - """Returns the number of elements in the container.""" - return len(self._values) - - def __ne__(self, other: Any) -> bool: - """Checks if another instance isn't equal to this one.""" - # The concrete classes should define __eq__. - return not self == other - - __hash__ = None - - def __repr__(self) -> str: - return repr(self._values) - - def _SetFrozen(self) -> None: - self._frozen = True - - def _AssureWritable(self) -> 'BaseContainer[_T]': - _CheckFrozen(self._frozen, 'Container is immutable') - return self - - def sort(self, *args, **kwargs) -> None: - self._AssureWritable() - # Continue to support the old sort_function keyword argument. - # This is expected to be a rare occurrence, so use LBYL to avoid - # the overhead of actually catching KeyError. - if 'sort_function' in kwargs: - kwargs['cmp'] = kwargs.pop('sort_function') - self._values.sort(*args, **kwargs) - - def reverse(self) -> None: - self._AssureWritable() - self._values.reverse() - - -# TODO: Remove this. BaseContainer does *not* conform to -# MutableSequence, only its subclasses do. -collections.abc.MutableSequence.register(BaseContainer) - - -class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]): - """Simple, type-checked, list-like container for holding repeated scalars.""" - - # Disallows assignment to other attributes. - __slots__ = ['_type_checker', '_field'] - - def __init__( - self, - message_listener: Any, - type_checker: Any, - field: Any = None, - ) -> None: - """Args: - - message_listener: A MessageListener implementation. The - RepeatedScalarFieldContainer will call this object's Modified() method - when it is modified. - type_checker: A type_checkers.ValueChecker instance to run on elements - inserted into this container. - """ - super().__init__(message_listener) - self._type_checker = type_checker - self._field = field - - def append(self, value: _T) -> None: - """Appends an item to the list. Similar to list.append().""" - self._AssureWritable() - self._values.append(self._type_checker.CheckValue(value)) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def insert(self, key: int, value: _T) -> None: - """Inserts the item at the specified position. Similar to list.insert().""" - self._AssureWritable() - self._values.insert(key, self._type_checker.CheckValue(value)) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def extend(self, elem_seq: Iterable[_T]) -> None: - """Extends by appending the given iterable. Similar to list.extend().""" - self._AssureWritable() - elem_seq_iter = iter(elem_seq) - new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter] - if new_values: - self._values.extend(new_values) - self._message_listener.Modified() - - def MergeFrom( - self, - other: Union['RepeatedScalarFieldContainer[_T]', Iterable[_T]], - ) -> None: - """Appends the contents of another repeated field of the same type to this - - one. We do not check the types of the individual fields. - """ - self._AssureWritable() - self._values.extend(other) - self._message_listener.Modified() - - def remove(self, elem: _T): - """Removes an item from the list. Similar to list.remove().""" - self._AssureWritable() - self._values.remove(elem) - self._message_listener.Modified() - - def pop(self, key: Optional[int] = -1) -> _T: - """Removes and returns an item at a given index. Similar to list.pop().""" - self._AssureWritable() - value = self._values[key] - self.__delitem__(key) - return value - - @overload - def __setitem__(self, key: int, value: _T) -> None: - ... - - @overload - def __setitem__(self, key: slice, value: Iterable[_T]) -> None: - ... - - def __setitem__(self, key, value) -> None: - """Sets the item on the specified position.""" - self._AssureWritable() - if isinstance(key, slice): - if key.step is not None: - raise ValueError('Extended slices not supported') - self._values[key] = map(self._type_checker.CheckValue, value) - self._message_listener.Modified() - else: - self._values[key] = self._type_checker.CheckValue(value) - self._message_listener.Modified() - - def __delitem__(self, key: Union[int, slice]) -> None: - """Deletes the item at the specified position.""" - self._AssureWritable() - del self._values[key] - self._message_listener.Modified() - - def __eq__(self, other: Any) -> bool: - """Compares the current instance with another one.""" - if self is other: - return True - # Special case for the same type which should be common and fast. - if isinstance(other, self.__class__): - return other._values == self._values - # We are presumably comparing against some other sequence type. - return other == self._values - - def __deepcopy__( - self, - unused_memo: Any = None, - ) -> 'RepeatedScalarFieldContainer[_T]': - clone = RepeatedScalarFieldContainer( - copy.deepcopy(self._message_listener), self._type_checker, self._field - ) - clone.MergeFrom(self) - return clone - - def __reduce__(self, **kwargs) -> NoReturn: - raise pickle.PickleError( - "Can't pickle repeated scalar fields, convert to list first" - ) - - def __array__(self, dtype=None, copy=None): - import numpy as np - - if dtype is None: - cpp_type = self._field.cpp_type - if cpp_type == FieldDescriptor.CPPTYPE_INT32: - dtype = np.int32 - elif cpp_type == FieldDescriptor.CPPTYPE_INT64: - dtype = np.int64 - elif cpp_type == FieldDescriptor.CPPTYPE_UINT32: - dtype = np.uint32 - elif cpp_type == FieldDescriptor.CPPTYPE_UINT64: - dtype = np.uint64 - elif cpp_type == FieldDescriptor.CPPTYPE_DOUBLE: - dtype = np.float64 - elif cpp_type == FieldDescriptor.CPPTYPE_FLOAT: - dtype = np.float32 - elif cpp_type == FieldDescriptor.CPPTYPE_BOOL: - dtype = np.bool - elif cpp_type == FieldDescriptor.CPPTYPE_ENUM: - dtype = np.int32 - elif self._field.type == FieldDescriptor.TYPE_BYTES: - dtype = 'S' - elif self._field.type == FieldDescriptor.TYPE_STRING: - dtype = str - else: - raise SystemError( - 'Code should never reach here: message type detected in' - ' RepeatedScalarFieldContainer' - ) - return np.array(self._values, dtype=dtype, copy=True) - - -# TODO: Constrain T to be a subtype of Message. -class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]): - """Simple, list-like container for holding repeated composite fields.""" - - # Disallows assignment to other attributes. - __slots__ = ['_message_descriptor'] - - def __init__(self, message_listener: Any, message_descriptor: Any) -> None: - """Note that we pass in a descriptor instead of the generated directly, - - since at the time we construct a _RepeatedCompositeFieldContainer we - haven't yet necessarily initialized the type that will be contained in the - container. - - Args: - message_listener: A MessageListener implementation. The - RepeatedCompositeFieldContainer will call this object's Modified() - method when it is modified. - message_descriptor: A Descriptor instance describing the protocol type - that should be present in this container. We'll use the _concrete_class - field of this descriptor when the client calls add(). - """ - super().__init__(message_listener) - self._message_descriptor = message_descriptor - - def _SetFrozen(self) -> None: - super()._SetFrozen() - for val in self._values: - val._SetFrozen() - - def add(self, **kwargs: Any) -> _T: - """Adds a new element at the end of the list and returns it. - - Keyword arguments may be used to initialize the element. - """ - self._AssureWritable() - new_element = self._message_descriptor._concrete_class(**kwargs) - new_element._SetListener(self._message_listener) - self._values.append(new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - return new_element - - def append(self, value: _T) -> None: - """Appends one element by copying the message.""" - self._AssureWritable() - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - new_element.CopyFrom(value) - self._values.append(new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def insert(self, key: int, value: _T) -> None: - """Inserts the item at the specified position by copying.""" - self._AssureWritable() - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - new_element.CopyFrom(value) - self._values.insert(key, new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def extend(self, elem_seq: Iterable[_T]) -> None: - """Extends by appending the given sequence of elements of the same type - - as this one, copying each individual message. - """ - self._AssureWritable() - message_class = self._message_descriptor._concrete_class - listener = self._message_listener - values = self._values - for message in elem_seq: - new_element = message_class() - new_element._SetListener(listener) - new_element.MergeFrom(message) - values.append(new_element) - listener.Modified() - - def MergeFrom( - self, - other: Union['RepeatedCompositeFieldContainer[_T]', Iterable[_T]], - ) -> None: - """Appends the contents of another repeated field of the same type to this - - one, copying each individual message. - """ - self._AssureWritable() - self.extend(other) - - def remove(self, elem: _T) -> None: - """Removes an item from the list. Similar to list.remove().""" - self._AssureWritable() - self._values.remove(elem) - self._message_listener.Modified() - - def pop(self, key: Optional[int] = -1) -> _T: - """Removes and returns an item at a given index. Similar to list.pop().""" - self._AssureWritable() - value = self._values[key] - self.__delitem__(key) - return value - - @overload - def __setitem__(self, key: int, value: _T) -> None: - ... - - @overload - def __setitem__(self, key: slice, value: Iterable[_T]) -> None: - ... - - def __setitem__(self, key, value): - # This method is implemented to make RepeatedCompositeFieldContainer - # structurally compatible with typing.MutableSequence. It is - # otherwise unsupported and will always raise an error. - raise TypeError( - f'{self.__class__.__name__} object does not support item assignment' - ) - - def __delitem__(self, key: Union[int, slice]) -> None: - """Deletes the item at the specified position.""" - self._AssureWritable() - del self._values[key] - self._message_listener.Modified() - - def __eq__(self, other: Any) -> bool: - """Compares the current instance with another one.""" - if self is other: - return True - if not isinstance(other, self.__class__): - raise TypeError( - 'Can only compare repeated composite fields against ' - 'other repeated composite fields.' - ) - return self._values == other._values - - -class ScalarMap(MutableMapping[_K, _V]): - """Simple, type-checked, dict-like container for holding repeated scalars.""" - - # Disallows assignment to other attributes. - __slots__ = [ - '_key_checker', - '_value_checker', - '_values', - '_message_listener', - '_entry_descriptor', - '_frozen', - ] - - def __init__( - self, - message_listener: Any, - key_checker: Any, - value_checker: Any, - entry_descriptor: Any, - ) -> None: - """Args: - - message_listener: A MessageListener implementation. - The ScalarMap will call this object's Modified() method when it - is modified. - key_checker: A type_checkers.ValueChecker instance to run on keys - inserted into this container. - value_checker: A type_checkers.ValueChecker instance to run on values - inserted into this container. - entry_descriptor: The MessageDescriptor of a map entry: key and value. - """ - self._message_listener = message_listener - self._key_checker = key_checker - self._value_checker = value_checker - self._entry_descriptor = entry_descriptor - self._values = {} - self._frozen = False - - def _SetFrozen(self) -> None: - self._frozen = True - - def _AssureWritable(self) -> 'ScalarMap[_K, _V]': - _CheckFrozen(self._frozen, 'Map is immutable') - return self - - def __getitem__(self, key: _K) -> _V: - key = self._key_checker.CheckValue(key) - try: - return self._values[key] - except KeyError: - self._AssureWritable() - val = self._value_checker.DefaultValue() - self._values[key] = val - return val - - def __contains__(self, item: _K) -> bool: - # We check the key's type to match the strong-typing flavor of the API. - # Also this makes it easier to match the behavior of the C++ implementation. - item = self._key_checker.CheckValue(item) - return item in self._values - - @overload - def get(self, key: _K) -> Optional[_V]: - ... - - @overload - def get(self, key: _K, default: _T) -> Union[_V, _T]: - ... - - # We need to override this explicitly, because our defaultdict-like behavior - # will make the default implementation (from our base class) always insert - # the key. - def get(self, key, default=None): - checked_key = self._key_checker.CheckValue(key) - if checked_key in self._values: - return self[checked_key] - else: - return default - - def __setitem__(self, key: _K, value: _V) -> _T: - self._AssureWritable() - checked_key = self._key_checker.CheckValue(key) - checked_value = self._value_checker.CheckValue(value) - self._values[checked_key] = checked_value - self._message_listener.Modified() - - def __delitem__(self, key: _K) -> None: - self._AssureWritable() - checked_key = self._key_checker.CheckValue(key) - del self._values[checked_key] - self._message_listener.Modified() - - def __len__(self) -> int: - return len(self._values) - - def __iter__(self) -> Iterator[_K]: - return iter(self._values) - - def __repr__(self) -> str: - return repr(self._values) - - def setdefault(self, key: _K, value: Optional[_V] = None) -> _V: - self._AssureWritable() - checked_key = self._key_checker.CheckValue(key) - if value == None: - raise ValueError('The value for scalar map setdefault must be set.') - if checked_key not in self._values: - self.__setitem__(checked_key, value) - return self[key] - - def MergeFrom(self, other: 'ScalarMap[_K, _V]') -> None: - self._AssureWritable() - self._values.update(other._values) - self._message_listener.Modified() - - def InvalidateIterators(self) -> None: - # It appears that the only way to reliably invalidate iterators to - # self._values is to ensure that its size changes. - original = self._values - self._values = original.copy() - original[None] = None - - # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self) -> None: - self._AssureWritable() - self._values.clear() - self._message_listener.Modified() - - def GetEntryClass(self) -> Any: - return self._entry_descriptor._concrete_class - - -class MessageMap(MutableMapping[_K, _V]): - """Simple, type-checked, dict-like container for with submessage values.""" - - # Disallows assignment to other attributes. - __slots__ = [ - '_key_checker', - '_values', - '_message_listener', - '_message_descriptor', - '_entry_descriptor', - '_frozen', - ] - - def __init__( - self, - message_listener: Any, - message_descriptor: Any, - key_checker: Any, - entry_descriptor: Any, - ) -> None: - """Args: - - message_listener: A MessageListener implementation. - The ScalarMap will call this object's Modified() method when it - is modified. - key_checker: A type_checkers.ValueChecker instance to run on keys - inserted into this container. - value_checker: A type_checkers.ValueChecker instance to run on values - inserted into this container. - entry_descriptor: The MessageDescriptor of a map entry: key and value. - """ - self._message_listener = message_listener - self._message_descriptor = message_descriptor - self._key_checker = key_checker - self._entry_descriptor = entry_descriptor - self._values = {} - self._frozen = False - - def _SetFrozen(self) -> None: - self._frozen = True - for val in self._values.values(): - val._SetFrozen() - - def _AssureWritable(self) -> 'MessageMap[_K, _V]': - _CheckFrozen(self._frozen, 'Map is immutable') - return self - - def __getitem__(self, key: _K) -> _V: - key = self._key_checker.CheckValue(key) - try: - return self._values[key] - except KeyError: - self._AssureWritable() - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - self._values[key] = new_element - self._message_listener.Modified() - return new_element - - def get_or_create(self, key: _K) -> _V: - """get_or_create() is an alias for getitem (ie. map[key]). - - Args: - key: The key to get or create in the map. - - This is useful in cases where you want to be explicit that the call is - mutating the map. This can avoid lint errors for statements like this - that otherwise would appear to be pointless statements: - - msg.my_map[key] - """ - return self[key] - - @overload - def get(self, key: _K) -> Optional[_V]: - ... - - @overload - def get(self, key: _K, default: _T) -> Union[_V, _T]: - ... - - # We need to override this explicitly, because our defaultdict-like behavior - # will make the default implementation (from our base class) always insert - # the key. - def get(self, key, default=None): - if key in self: - return self[key] - else: - return default - - def __contains__(self, item: _K) -> bool: - item = self._key_checker.CheckValue(item) - return item in self._values - - def __setitem__(self, key: _K, value: _V) -> NoReturn: - self._AssureWritable() - raise ValueError('May not set values directly, call my_map[key].foo = 5') - - def __delitem__(self, key: _K) -> None: - self._AssureWritable() - key = self._key_checker.CheckValue(key) - del self._values[key] - self._message_listener.Modified() - - def __len__(self) -> int: - return len(self._values) - - def __iter__(self) -> Iterator[_K]: - return iter(self._values) - - def __repr__(self) -> str: - return repr(self._values) - - def setdefault(self, key: _K, value: Optional[_V] = None) -> _V: - self._AssureWritable() - raise NotImplementedError( - 'Set message map value directly is not supported, call' - ' my_map[key].foo = 5' - ) - - def MergeFrom(self, other: 'MessageMap[_K, _V]') -> None: - self._AssureWritable() - # pylint: disable=protected-access - for key in other._values: - # According to documentation: "When parsing from the wire or when merging, - # if there are duplicate map keys the last key seen is used". - if key in self: - del self[key] - self[key].CopyFrom(other[key]) - # self._message_listener.Modified() not required here, because - # mutations to submessages already propagate. - - def InvalidateIterators(self) -> None: - # It appears that the only way to reliably invalidate iterators to - # self._values is to ensure that its size changes. - original = self._values - self._values = original.copy() - original[None] = None - - # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self) -> None: - self._AssureWritable() - self._values.clear() - self._message_listener.Modified() - - def GetEntryClass(self) -> Any: - return self._entry_descriptor._concrete_class - - -class _UnknownField: - """A parsed unknown field.""" - - # Disallows assignment to other attributes. - __slots__ = ['_field_number', '_wire_type', '_data'] - - def __init__(self, field_number, wire_type, data): - self._field_number = field_number - self._wire_type = wire_type - self._data = data - return - - def __lt__(self, other): - # pylint: disable=protected-access - return self._field_number < other._field_number - - def __eq__(self, other): - if self is other: - return True - # pylint: disable=protected-access - return ( - self._field_number == other._field_number - and self._wire_type == other._wire_type - and self._data == other._data - ) - - -class UnknownFieldRef: # pylint: disable=missing-class-docstring - - def __init__(self, parent, index): - self._parent = parent - self._index = index - - def _check_valid(self): - if not self._parent: - raise ValueError( - 'UnknownField does not exist. The parent message might be cleared.' - ) - if self._index >= len(self._parent): - raise ValueError( - 'UnknownField does not exist. The parent message might be cleared.' - ) - - @property - def field_number(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._field_number - - @property - def wire_type(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._wire_type - - @property - def data(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._data - - -class UnknownFieldSet: - """UnknownField container""" - - # Disallows assignment to other attributes. - __slots__ = ['_values'] - - def __init__(self): - self._values = [] - - def __getitem__(self, index): - if self._values is None: - raise ValueError( - 'UnknownFields does not exist. The parent message might be cleared.' - ) - size = len(self._values) - if index < 0: - index += size - if index < 0 or index >= size: - raise IndexError('index %d out of range'.index) - - return UnknownFieldRef(self, index) - - def _internal_get(self, index): - return self._values[index] - - def __len__(self): - if self._values is None: - raise ValueError( - 'UnknownFields does not exist. The parent message might be cleared.' - ) - return len(self._values) - - def _add(self, field_number, wire_type, data): - unknown_field = _UnknownField(field_number, wire_type, data) - self._values.append(unknown_field) - return unknown_field - - def __iter__(self): - for i in range(len(self)): - yield UnknownFieldRef(self, i) - - def _extend(self, other): - if other is None: - return - # pylint: disable=protected-access - self._values.extend(other._values) - - def __eq__(self, other): - if self is other: - return True - # Sort unknown fields because their order shouldn't - # affect equality test. - values = list(self._values) - if other is None: - return not values - values.sort() - # pylint: disable=protected-access - other_values = sorted(other._values) - return values == other_values - - def _clear(self): - for value in self._values: - # pylint: disable=protected-access - if isinstance(value._data, UnknownFieldSet): - value._data._clear() # pylint: disable=protected-access - self._values = None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py deleted file mode 100644 index a4a425a61b4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/decoder.py +++ /dev/null @@ -1,1127 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Code for decoding protocol buffer primitives. - -This code is very similar to encoder.py -- read the docs for that module first. - -A "decoder" is a function with the signature: - Decode(buffer, pos, end, message, field_dict) -The arguments are: - buffer: The string containing the encoded message. - pos: The current position in the string. - end: The position in the string where the current message ends. May be - less than len(buffer) if we're reading a sub-message. - message: The message object into which we're parsing. - field_dict: message._fields (avoids a hashtable lookup). -The decoder reads the field and stores it into field_dict, returning the new -buffer position. A decoder for a repeated field may proactively decode all of -the elements of that field, if they appear consecutively. - -Note that decoders may throw any of the following: - IndexError: Indicates a truncated message. - struct.error: Unpacking of a fixed-width field failed. - message.DecodeError: Other errors. - -Decoders are expected to raise an exception if they are called with pos > end. -This allows callers to be lax about bounds checking: it's fineto read past -"end" as long as you are sure that someone else will notice and throw an -exception later on. - -Something up the call stack is expected to catch IndexError and struct.error -and convert them to message.DecodeError. - -Decoders are constructed using decoder constructors with the signature: - MakeDecoder(field_number, is_repeated, is_packed, key, new_default) -The arguments are: - field_number: The field number of the field we want to decode. - is_repeated: Is the field a repeated field? (bool) - is_packed: Is the field a packed field? (bool) - key: The key to use when looking up the field within field_dict. - (This is actually the FieldDescriptor but nothing in this - file should depend on that.) - new_default: A function which takes a message object as a parameter and - returns a new instance of the default value for this field. - (This is called for repeated fields and sub-messages, when an - instance does not already exist.) - -As with encoders, we define a decoder constructor for every type of field. -Then, for every field of every message class we construct an actual decoder. -That decoder goes into a dict indexed by tag, so when we decode a message -we repeatedly read a tag, look up the corresponding decoder, and invoke it. -""" - -__author__ = 'kenton@google.com (Kenton Varda)' - -import math -import numbers -import struct - -from opentelemetry.agent._vendor.google.protobuf import message -from opentelemetry.agent._vendor.google.protobuf.internal import containers -from opentelemetry.agent._vendor.google.protobuf.internal import encoder -from opentelemetry.agent._vendor.google.protobuf.internal import wire_format - -# This is not for optimization, but rather to avoid conflicts with local -# variables named "message". -_DecodeError = message.DecodeError - - -def IsDefaultScalarValue(value): - """Returns whether or not a scalar value is the default value of its type. - - Specifically, this should be used to determine presence of implicit-presence - fields, where we disallow custom defaults. - - Args: - value: A scalar value to check. - - Returns: - True if the value is equivalent to a default value, False otherwise. - """ - if isinstance(value, numbers.Number) and math.copysign(1.0, value) < 0: - # Special case for negative zero, where "truthiness" fails to give the right - # answer. - return False - - # Normally, we can just use Python's boolean conversion. - return not value - - -def _VarintDecoder(mask, result_type): - """Return an encoder for a basic varint value (does not include tag). - - Decoded values will be bitwise-anded with the given mask before being - returned, e.g. to limit them to 32 bits. The returned decoder does not - take the usual "end" parameter -- the caller is expected to do bounds checking - after the fact (often the caller can defer such checking until later). The - decoder returns a (value, new_pos) pair. - """ - - def DecodeVarint(buffer, pos: int = None): - result = 0 - shift = 0 - while 1: - if pos is None: - # Read from BytesIO - try: - b = buffer.read(1)[0] - except IndexError as e: - if shift == 0: - # End of BytesIO. - return None - else: - raise ValueError('Fail to read varint %s' % str(e)) - else: - b = buffer[pos] - pos += 1 - result |= (b & 0x7F) << shift - if not (b & 0x80): - result &= mask - result = result_type(result) - return result if pos is None else (result, pos) - shift += 7 - if shift >= 64: - raise _DecodeError('Too many bytes when decoding varint.') - - return DecodeVarint - - -def _SignedVarintDecoder(bits, result_type): - """Like _VarintDecoder() but decodes signed values.""" - - signbit = 1 << (bits - 1) - mask = (1 << bits) - 1 - - def DecodeVarint(buffer, pos): - result = 0 - shift = 0 - while 1: - b = buffer[pos] - result |= (b & 0x7F) << shift - pos += 1 - if not (b & 0x80): - result &= mask - result = (result ^ signbit) - signbit - result = result_type(result) - return (result, pos) - shift += 7 - if shift >= 64: - raise _DecodeError('Too many bytes when decoding varint.') - - return DecodeVarint - - -# All 32-bit and 64-bit values are represented as int. -_DecodeVarint = _VarintDecoder((1 << 64) - 1, int) -_DecodeSignedVarint = _SignedVarintDecoder(64, int) - -# Use these versions for values which must be limited to 32 bits. -_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int) -_DecodeSignedVarint32 = _SignedVarintDecoder(32, int) - - -def ReadTag(buffer, pos): - """Read a tag from the memoryview, and return a (tag_bytes, new_pos) tuple. - - We return the raw bytes of the tag rather than decoding them. The raw - bytes can then be used to look up the proper decoder. This effectively allows - us to trade some work that would be done in pure-python (decoding a varint) - for work that is done in C (searching for a byte string in a hash table). - In a low-level language it would be much cheaper to decode the varint and - use that, but not in Python. - - Args: - buffer: memoryview object of the encoded bytes - pos: int of the current position to start from - - Returns: - Tuple[bytes, int] of the tag data and new position. - """ - start = pos - while buffer[pos] & 0x80: - pos += 1 - pos += 1 - - tag_bytes = buffer[start:pos].tobytes() - return tag_bytes, pos - - -def DecodeTag(tag_bytes): - """Decode a tag from the bytes. - - Args: - tag_bytes: the bytes of the tag - - Returns: - Tuple[int, int] of the tag field number and wire type. - """ - tag, _ = _DecodeVarint(tag_bytes, 0) - return wire_format.UnpackTag(tag) - - -# -------------------------------------------------------------------- - - -def _SimpleDecoder(wire_type, decode_value): - """Return a constructor for a decoder for fields of a particular type. - - Args: - wire_type: The field's wire type. - decode_value: A function which decodes an individual value, e.g. - _DecodeVarint() - """ - - def SpecificDecoder( - field_number, - is_repeated, - is_packed, - key, - new_default, - clear_if_default=False, - ): - if is_packed: - local_DecodeVarint = _DecodeVarint - - def DecodePackedField( - buffer, pos, end, message, field_dict, current_depth=0 - ): - del current_depth # unused - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - endpoint, pos = local_DecodeVarint(buffer, pos) - endpoint += pos - if endpoint > end: - raise _DecodeError('Truncated message.') - while pos < endpoint: - element, pos = decode_value(buffer, pos) - value.append(element) - if pos > endpoint: - del value[-1] # Discard corrupt value. - raise _DecodeError('Packed element was truncated.') - return pos - - return DecodePackedField - elif is_repeated: - tag_bytes = encoder.TagBytes(field_number, wire_type) - tag_len = len(tag_bytes) - - def DecodeRepeatedField( - buffer, pos, end, message, field_dict, current_depth=0 - ): - del current_depth # unused - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - element, new_pos = decode_value(buffer, pos) - value.append(element) - # Predict that the next tag is another copy of the same repeated - # field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos >= end: - # Prediction failed. Return. - if new_pos > end: - raise _DecodeError('Truncated message.') - return new_pos - - return DecodeRepeatedField - else: - - def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): - del current_depth # unused - new_value, pos = decode_value(buffer, pos) - if pos > end: - raise _DecodeError('Truncated message.') - if clear_if_default and IsDefaultScalarValue(new_value): - field_dict.pop(key, None) - else: - field_dict[key] = new_value - return pos - - return DecodeField - - return SpecificDecoder - - -def _ModifiedDecoder(wire_type, decode_value, modify_value): - """Like SimpleDecoder but additionally invokes modify_value on every value - - before storing it. Usually modify_value is ZigZagDecode. - """ - - # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but - # not enough to make a significant difference. - - def InnerDecode(buffer, pos): - result, new_pos = decode_value(buffer, pos) - return (modify_value(result), new_pos) - - return _SimpleDecoder(wire_type, InnerDecode) - - -def _StructPackDecoder(wire_type, format): - """Return a constructor for a decoder for a fixed-width field. - - Args: - wire_type: The field's wire type. - format: The format string to pass to struct.unpack(). - """ - - value_size = struct.calcsize(format) - local_unpack = struct.unpack - - # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but - # not enough to make a significant difference. - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - - def InnerDecode(buffer, pos): - new_pos = pos + value_size - result = local_unpack(format, buffer[pos:new_pos])[0] - return (result, new_pos) - - return _SimpleDecoder(wire_type, InnerDecode) - - -def _FloatDecoder(): - """Returns a decoder for a float field. - - This code works around a bug in struct.unpack for non-finite 32-bit - floating-point values. - """ - - local_unpack = struct.unpack - - def InnerDecode(buffer, pos): - """Decode serialized float to a float and new position. - - Args: - buffer: memoryview of the serialized bytes - pos: int, position in the memory view to start at. - - Returns: - Tuple[float, int] of the deserialized float value and new position - in the serialized data. - """ - # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign - # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand. - new_pos = pos + 4 - float_bytes = buffer[pos:new_pos].tobytes() - - # If this value has all its exponent bits set, then it's non-finite. - # In Python 2.4, struct.unpack will convert it to a finite 64-bit value. - # To avoid that, we parse it specially. - if float_bytes[3:4] in b'\x7F\xFF' and float_bytes[2:3] >= b'\x80': - # If at least one significand bit is set... - if float_bytes[0:3] != b'\x00\x00\x80': - return (math.nan, new_pos) - # If sign bit is set... - if float_bytes[3:4] == b'\xFF': - return (-math.inf, new_pos) - return (math.inf, new_pos) - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - result = local_unpack('= b'\xF0') - and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0') - ): - return (math.nan, new_pos) - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - result = local_unpack(' end: - raise _DecodeError('Truncated message.') - while pos < endpoint: - value_start_pos = pos - element, pos = _DecodeSignedVarint32(buffer, pos) - # pylint: disable=protected-access - if element in enum_type.values_by_number: - value.append(element) - else: - if not message._unknown_fields: - message._unknown_fields = [] - tag_bytes = encoder.TagBytes( - field_number, wire_format.WIRETYPE_VARINT - ) - - message._unknown_fields.append( - (tag_bytes, buffer[value_start_pos:pos].tobytes()) - ) - # pylint: enable=protected-access - if pos > endpoint: - if element in enum_type.values_by_number: - del value[-1] # Discard corrupt value. - else: - del message._unknown_fields[-1] - # pylint: enable=protected-access - raise _DecodeError('Packed element was truncated.') - return pos - - return DecodePackedField - elif is_repeated: - tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) - tag_len = len(tag_bytes) - - def DecodeRepeatedField( - buffer, pos, end, message, field_dict, current_depth=0 - ): - """Decode serialized repeated enum to its value and a new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - del current_depth # unused - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - element, new_pos = _DecodeSignedVarint32(buffer, pos) - # pylint: disable=protected-access - if element in enum_type.values_by_number: - value.append(element) - else: - if not message._unknown_fields: - message._unknown_fields = [] - message._unknown_fields.append( - (tag_bytes, buffer[pos:new_pos].tobytes()) - ) - # pylint: enable=protected-access - # Predict that the next tag is another copy of the same repeated - # field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos >= end: - # Prediction failed. Return. - if new_pos > end: - raise _DecodeError('Truncated message.') - return new_pos - - return DecodeRepeatedField - else: - - def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): - """Decode serialized repeated enum to its value and a new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - del current_depth # unused - value_start_pos = pos - enum_value, pos = _DecodeSignedVarint32(buffer, pos) - if pos > end: - raise _DecodeError('Truncated message.') - if clear_if_default and IsDefaultScalarValue(enum_value): - field_dict.pop(key, None) - return pos - # pylint: disable=protected-access - if enum_value in enum_type.values_by_number: - field_dict[key] = enum_value - else: - if not message._unknown_fields: - message._unknown_fields = [] - tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) - message._unknown_fields.append( - (tag_bytes, buffer[value_start_pos:pos].tobytes()) - ) - # pylint: enable=protected-access - return pos - - return DecodeField - - -# -------------------------------------------------------------------- - -Int32Decoder = _SimpleDecoder( - wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32 -) - -Int64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeSignedVarint) - -UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) -UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint) - -SInt32Decoder = _ModifiedDecoder( - wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode -) -SInt64Decoder = _ModifiedDecoder( - wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode -) - -# Note that Python conveniently guarantees that when using the '<' prefix on -# formats, they will also have the same size across all platforms (as opposed -# to without the prefix, where their sizes depend on the C compiler's basic -# type sizes). -Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, ' end: - raise _DecodeError('Truncated string.') - value.append(_ConvertToUnicode(buffer[pos:new_pos])) - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - - return DecodeRepeatedField - else: - - def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): - del current_depth # unused - size, pos = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - if clear_if_default and IsDefaultScalarValue(size): - field_dict.pop(key, None) - else: - field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) - return new_pos - - return DecodeField - - -def BytesDecoder( - field_number, - is_repeated, - is_packed, - key, - new_default, - clear_if_default=False, -): - """Returns a decoder for a bytes field.""" - - local_DecodeVarint = _DecodeVarint - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes( - field_number, wire_format.WIRETYPE_LENGTH_DELIMITED - ) - tag_len = len(tag_bytes) - - def DecodeRepeatedField( - buffer, pos, end, message, field_dict, current_depth=0 - ): - del current_depth # unused - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - size, pos = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - value.append(buffer[pos:new_pos].tobytes()) - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - - return DecodeRepeatedField - else: - - def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): - del current_depth # unused - size, pos = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - if clear_if_default and IsDefaultScalarValue(size): - field_dict.pop(key, None) - else: - field_dict[key] = buffer[pos:new_pos].tobytes() - return new_pos - - return DecodeField - - -def GroupDecoder(field_number, is_repeated, is_packed, key, new_default): - """Returns a decoder for a group field.""" - - end_tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_END_GROUP) - end_tag_len = len(end_tag_bytes) - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_START_GROUP) - tag_len = len(tag_bytes) - - def DecodeRepeatedField( - buffer, pos, end, message, field_dict, current_depth=0 - ): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read sub-message. - current_depth += 1 - if current_depth > _recursion_limit: - raise _DecodeError( - 'Error parsing message: too many levels of nesting.' - ) - pos = value.add()._InternalParse(buffer, pos, end, current_depth) - current_depth -= 1 - # Read end tag. - new_pos = pos + end_tag_len - if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: - raise _DecodeError('Missing group end tag.') - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - - return DecodeRepeatedField - else: - - def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read sub-message. - current_depth += 1 - if current_depth > _recursion_limit: - raise _DecodeError('Error parsing message: too many levels of nesting.') - pos = value._InternalParse(buffer, pos, end, current_depth) - current_depth -= 1 - # Read end tag. - new_pos = pos + end_tag_len - if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: - raise _DecodeError('Missing group end tag.') - return new_pos - - return DecodeField - - -def MessageDecoder(field_number, is_repeated, is_packed, key, new_default): - """Returns a decoder for a message field.""" - - local_DecodeVarint = _DecodeVarint - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes( - field_number, wire_format.WIRETYPE_LENGTH_DELIMITED - ) - tag_len = len(tag_bytes) - - def DecodeRepeatedField( - buffer, pos, end, message, field_dict, current_depth=0 - ): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - # Read length. - size, pos = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - current_depth += 1 - if current_depth > _recursion_limit: - raise _DecodeError( - 'Error parsing message: too many levels of nesting.' - ) - if ( - value.add()._InternalParse(buffer, pos, new_pos, current_depth) - != new_pos - ): - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - current_depth -= 1 - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - - return DecodeRepeatedField - else: - - def DecodeField(buffer, pos, end, message, field_dict, current_depth=0): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read length. - size, pos = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - current_depth += 1 - if current_depth > _recursion_limit: - raise _DecodeError('Error parsing message: too many levels of nesting.') - if value._InternalParse(buffer, pos, new_pos, current_depth) != new_pos: - # The only reason _InternalParse would return early is if it encountered - # an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - current_depth -= 1 - return new_pos - - return DecodeField - - -# -------------------------------------------------------------------- - -MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP) - - -def MessageSetItemDecoder(descriptor): - """Returns a decoder for a MessageSet item. - - The parameter is the message Descriptor. - - The message set message looks like this: - message MessageSet { - repeated group Item = 1 { - required int32 type_id = 2; - required string message = 3; - } - } - """ - - type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) - message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) - item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) - - local_ReadTag = ReadTag - local_DecodeVarint = _DecodeVarint - - def DecodeItem(buffer, pos, end, message, field_dict, current_depth=0): - """Decode serialized message set to its value and new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - message_set_item_start = pos - type_id = -1 - message_start = -1 - message_end = -1 - - # Technically, type_id and message can appear in any order, so we need - # a little loop here. - while 1: - tag_bytes, pos = local_ReadTag(buffer, pos) - if tag_bytes == type_id_tag_bytes: - type_id, pos = local_DecodeVarint(buffer, pos) - elif tag_bytes == message_tag_bytes: - size, message_start = local_DecodeVarint(buffer, pos) - pos = message_end = message_start + size - elif tag_bytes == item_end_tag_bytes: - break - else: - field_number, wire_type = DecodeTag(tag_bytes) - _, pos = _DecodeUnknownField(buffer, pos, end, field_number, wire_type) - if pos == -1: - raise _DecodeError('Unexpected end-group tag.') - - if pos > end: - raise _DecodeError('Truncated message.') - - if type_id == -1: - raise _DecodeError('MessageSet item missing type_id.') - if message_start == -1: - raise _DecodeError('MessageSet item missing message.') - - extension = message.Extensions._FindExtensionByNumber(type_id) - # pylint: disable=protected-access - if extension is not None: - value = field_dict.get(extension) - if value is None: - message_type = extension.message_type - if not hasattr(message_type, '_concrete_class'): - message_factory.GetMessageClass(message_type) - value = field_dict.setdefault(extension, message_type._concrete_class()) - current_depth += 1 - if current_depth > _recursion_limit: - raise _DecodeError('Error parsing message: too many levels of nesting.') - if ( - value._InternalParse( - buffer, message_start, message_end, current_depth - ) - != message_end - ): - # The only reason _InternalParse would return early is if it encountered - # an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - current_depth -= 1 - else: - if not message._unknown_fields: - message._unknown_fields = [] - message._unknown_fields.append( - (MESSAGE_SET_ITEM_TAG, buffer[message_set_item_start:pos].tobytes()) - ) - # pylint: enable=protected-access - - return pos - - return DecodeItem - - -def UnknownMessageSetItemDecoder(): - """Returns a decoder for a Unknown MessageSet item.""" - - type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) - message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) - item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) - - def DecodeUnknownItem(buffer): - pos = 0 - end = len(buffer) - message_start = -1 - message_end = -1 - while 1: - tag_bytes, pos = ReadTag(buffer, pos) - if tag_bytes == type_id_tag_bytes: - type_id, pos = _DecodeVarint(buffer, pos) - elif tag_bytes == message_tag_bytes: - size, message_start = _DecodeVarint(buffer, pos) - pos = message_end = message_start + size - elif tag_bytes == item_end_tag_bytes: - break - else: - field_number, wire_type = DecodeTag(tag_bytes) - _, pos = _DecodeUnknownField(buffer, pos, end, field_number, wire_type) - if pos == -1: - raise _DecodeError('Unexpected end-group tag.') - - if pos > end: - raise _DecodeError('Truncated message.') - - if type_id == -1: - raise _DecodeError('MessageSet item missing type_id.') - if message_start == -1: - raise _DecodeError('MessageSet item missing message.') - - return (type_id, buffer[message_start:message_end].tobytes()) - - return DecodeUnknownItem - - -# -------------------------------------------------------------------- - - -def MapDecoder(field_descriptor, new_default, is_message_map): - """Returns a decoder for a map field.""" - - key = field_descriptor - tag_bytes = encoder.TagBytes( - field_descriptor.number, wire_format.WIRETYPE_LENGTH_DELIMITED - ) - tag_len = len(tag_bytes) - local_DecodeVarint = _DecodeVarint - # Can't read _concrete_class yet; might not be initialized. - message_type = field_descriptor.message_type - - def DecodeMap(buffer, pos, end, message, field_dict, current_depth=0): - submsg = message_type._concrete_class() - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - # Read length. - size, pos = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - submsg.Clear() - current_depth += 1 - if current_depth > _recursion_limit: - raise _DecodeError('Error parsing message: too many levels of nesting.') - if submsg._InternalParse(buffer, pos, new_pos, current_depth) != new_pos: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - current_depth -= 1 - - if is_message_map: - value[submsg.key].CopyFrom(submsg.value) - else: - value[submsg.key] = submsg.value - - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - - return DecodeMap - - -def _DecodeFixed64(buffer, pos): - """Decode a fixed64.""" - new_pos = pos + 8 - return (struct.unpack('= _recursion_limit: - raise _DecodeError('Error parsing message: too many levels of nesting.') - data, pos = _DecodeUnknownFieldSet(buffer, pos, end_pos, current_depth) - current_depth -= 1 - # Check end tag. - if buffer[pos - len(end_tag_bytes) : pos] != end_tag_bytes: - raise _DecodeError('Missing group end tag.') - elif wire_type == wire_format.WIRETYPE_END_GROUP: - return (0, -1) - else: - raise _DecodeError('Wrong wire type in tag.') - - if pos > end_pos: - raise _DecodeError('Truncated message.') - - return (data, pos) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py deleted file mode 100644 index 6ae91bab46a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/encoder.py +++ /dev/null @@ -1,931 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Code for encoding protocol message primitives. - -Contains the logic for encoding every logical protocol field type -into one of the 5 physical wire types. - -This code is designed to push the Python interpreter's performance to the -limits. - -The basic idea is that at startup time, for every field (i.e. every -FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The -sizer takes a value of this field's type and computes its byte size. The -encoder takes a writer function and a value. It encodes the value into byte -strings and invokes the writer function to write those strings. Typically the -writer function is the write() method of a BytesIO. - -We try to do as much work as possible when constructing the writer and the -sizer rather than when calling them. In particular: -* We copy any needed global functions to local variables, so that we do not need - to do costly global table lookups at runtime. -* Similarly, we try to do any attribute lookups at startup time if possible. -* Every field's tag is encoded to bytes at startup, since it can't change at - runtime. -* Whatever component of the field size we can compute at startup, we do. -* We *avoid* sharing code if doing so would make the code slower and not sharing - does not burden us too much. For example, encoders for repeated fields do - not just call the encoders for singular fields in a loop because this would - add an extra function call overhead for every loop iteration; instead, we - manually inline the single-value encoder into the loop. -* If a Python function lacks a return statement, Python actually generates - instructions to pop the result of the last statement off the stack, push - None onto the stack, and then return that. If we really don't care what - value is returned, then we can save two instructions by returning the - result of the last statement. It looks funny but it helps. -* We assume that type and bounds checking has happened at a higher level. -""" - -__author__ = 'kenton@google.com (Kenton Varda)' - -import struct - -from opentelemetry.agent._vendor.google.protobuf.internal import wire_format - -# This will overflow and thus become IEEE-754 "infinity". We would use -# "float('inf')" but it doesn't work on Windows pre-Python-2.6. -_POS_INF = 1e10000 -_NEG_INF = -_POS_INF - - -def _VarintSize(value): - """Compute the size of a varint value.""" - if value <= 0x7F: - return 1 - if value <= 0x3FFF: - return 2 - if value <= 0x1FFFFF: - return 3 - if value <= 0xFFFFFFF: - return 4 - if value <= 0x7FFFFFFFF: - return 5 - if value <= 0x3FFFFFFFFFF: - return 6 - if value <= 0x1FFFFFFFFFFFF: - return 7 - if value <= 0xFFFFFFFFFFFFFF: - return 8 - if value <= 0x7FFFFFFFFFFFFFFF: - return 9 - return 10 - - -def _SignedVarintSize(value): - """Compute the size of a signed varint value.""" - if value < 0: - return 10 - if value <= 0x7F: - return 1 - if value <= 0x3FFF: - return 2 - if value <= 0x1FFFFF: - return 3 - if value <= 0xFFFFFFF: - return 4 - if value <= 0x7FFFFFFFF: - return 5 - if value <= 0x3FFFFFFFFFF: - return 6 - if value <= 0x1FFFFFFFFFFFF: - return 7 - if value <= 0xFFFFFFFFFFFFFF: - return 8 - if value <= 0x7FFFFFFFFFFFFFFF: - return 9 - return 10 - - -def _TagSize(field_number): - """Returns the number of bytes required to serialize a tag with this field - - number. - """ - # Just pass in type 0, since the type won't affect the tag+type size. - return _VarintSize(wire_format.PackTag(field_number, 0)) - - -# -------------------------------------------------------------------- -# In this section we define some generic sizers. Each of these functions -# takes parameters specific to a particular field type, e.g. int32 or fixed64. -# It returns another function which in turn takes parameters specific to a -# particular field, e.g. the field number and whether it is repeated or packed. -# Look at the next section to see how these are used. - - -def _SimpleSizer(compute_value_size): - """A sizer which uses the function compute_value_size to compute the size of - - each value. Typically compute_value_size is _VarintSize. - """ - - def SpecificSizer(field_number, is_repeated, is_packed): - tag_size = _TagSize(field_number) - if is_packed: - local_VarintSize = _VarintSize - - def PackedFieldSize(value): - result = 0 - for element in value: - result += compute_value_size(element) - return result + local_VarintSize(result) + tag_size - - return PackedFieldSize - elif is_repeated: - - def RepeatedFieldSize(value): - result = tag_size * len(value) - for element in value: - result += compute_value_size(element) - return result - - return RepeatedFieldSize - else: - - def FieldSize(value): - return tag_size + compute_value_size(value) - - return FieldSize - - return SpecificSizer - - -def _ModifiedSizer(compute_value_size, modify_value): - """Like SimpleSizer, but modify_value is invoked on each value before it is - - passed to compute_value_size. modify_value is typically ZigZagEncode. - """ - - def SpecificSizer(field_number, is_repeated, is_packed): - tag_size = _TagSize(field_number) - if is_packed: - local_VarintSize = _VarintSize - - def PackedFieldSize(value): - result = 0 - for element in value: - result += compute_value_size(modify_value(element)) - return result + local_VarintSize(result) + tag_size - - return PackedFieldSize - elif is_repeated: - - def RepeatedFieldSize(value): - result = tag_size * len(value) - for element in value: - result += compute_value_size(modify_value(element)) - return result - - return RepeatedFieldSize - else: - - def FieldSize(value): - return tag_size + compute_value_size(modify_value(value)) - - return FieldSize - - return SpecificSizer - - -def _FixedSizer(value_size): - """Like _SimpleSizer except for a fixed-size field. - - The input is the size of one value. - """ - - def SpecificSizer(field_number, is_repeated, is_packed): - tag_size = _TagSize(field_number) - if is_packed: - local_VarintSize = _VarintSize - - def PackedFieldSize(value): - result = len(value) * value_size - return result + local_VarintSize(result) + tag_size - - return PackedFieldSize - elif is_repeated: - element_size = value_size + tag_size - - def RepeatedFieldSize(value): - return len(value) * element_size - - return RepeatedFieldSize - else: - field_size = value_size + tag_size - - def FieldSize(value): - return field_size - - return FieldSize - - return SpecificSizer - - -# ==================================================================== -# Here we declare a sizer constructor for each field type. Each "sizer -# constructor" is a function that takes (field_number, is_repeated, is_packed) -# as parameters and returns a sizer, which in turn takes a field value as -# a parameter and returns its encoded size. - -Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize) - -UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize) - -SInt32Sizer = SInt64Sizer = _ModifiedSizer( - _SignedVarintSize, wire_format.ZigZagEncode -) - -Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4) -Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8) - -BoolSizer = _FixedSizer(1) - - -def StringSizer(field_number, is_repeated, is_packed): - """Returns a sizer for a string field.""" - - tag_size = _TagSize(field_number) - local_VarintSize = _VarintSize - local_len = len - assert not is_packed - if is_repeated: - - def RepeatedFieldSize(value): - result = tag_size * len(value) - for element in value: - l = local_len(element.encode('utf-8')) - result += local_VarintSize(l) + l - return result - - return RepeatedFieldSize - else: - - def FieldSize(value): - l = local_len(value.encode('utf-8')) - return tag_size + local_VarintSize(l) + l - - return FieldSize - - -def BytesSizer(field_number, is_repeated, is_packed): - """Returns a sizer for a bytes field.""" - - tag_size = _TagSize(field_number) - local_VarintSize = _VarintSize - local_len = len - assert not is_packed - if is_repeated: - - def RepeatedFieldSize(value): - result = tag_size * len(value) - for element in value: - l = local_len(element) - result += local_VarintSize(l) + l - return result - - return RepeatedFieldSize - else: - - def FieldSize(value): - l = local_len(value) - return tag_size + local_VarintSize(l) + l - - return FieldSize - - -def GroupSizer(field_number, is_repeated, is_packed): - """Returns a sizer for a group field.""" - - tag_size = _TagSize(field_number) * 2 - assert not is_packed - if is_repeated: - - def RepeatedFieldSize(value): - result = tag_size * len(value) - for element in value: - result += element.ByteSize() - return result - - return RepeatedFieldSize - else: - - def FieldSize(value): - return tag_size + value.ByteSize() - - return FieldSize - - -def MessageSizer(field_number, is_repeated, is_packed): - """Returns a sizer for a message field.""" - - tag_size = _TagSize(field_number) - local_VarintSize = _VarintSize - assert not is_packed - if is_repeated: - - def RepeatedFieldSize(value): - result = tag_size * len(value) - for element in value: - l = element.ByteSize() - result += local_VarintSize(l) + l - return result - - return RepeatedFieldSize - else: - - def FieldSize(value): - l = value.ByteSize() - return tag_size + local_VarintSize(l) + l - - return FieldSize - - -# -------------------------------------------------------------------- -# MessageSet is special: it needs custom logic to compute its size properly. - - -def MessageSetItemSizer(field_number): - """Returns a sizer for extensions of MessageSet. - - The message set message looks like this: - message MessageSet { - repeated group Item = 1 { - required int32 type_id = 2; - required string message = 3; - } - } - """ - static_size = ( - _TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) + _TagSize(3) - ) - local_VarintSize = _VarintSize - - def FieldSize(value): - l = value.ByteSize() - return static_size + local_VarintSize(l) + l - - return FieldSize - - -# -------------------------------------------------------------------- -# Map is special: it needs custom logic to compute its size properly. - - -def MapSizer(field_descriptor, key_sizer, value_sizer): - """Returns a sizer for a map field.""" - - def FieldSize(map_value): - tag_size = _TagSize(field_descriptor.number) - local_VarintSize = _VarintSize - - total = 0 - for key in map_value: - val = map_value[key] - entry_size = key_sizer(key) + value_sizer(val) - total += tag_size + local_VarintSize(entry_size) + entry_size - - return total - - return FieldSize - - -# ==================================================================== -# Encoders! - - -def _VarintEncoder(): - """Return an encoder for a basic varint value (does not include tag).""" - - local_int2byte = struct.Struct('>B').pack - - def EncodeVarint(write, value, unused_deterministic=None): - bits = value & 0x7F - value >>= 7 - while value: - write(local_int2byte(0x80 | bits)) - bits = value & 0x7F - value >>= 7 - return write(local_int2byte(bits)) - - return EncodeVarint - - -def _SignedVarintEncoder(): - """Return an encoder for a basic signed varint value (does not include - - tag). - """ - - local_int2byte = struct.Struct('>B').pack - - def EncodeSignedVarint(write, value, unused_deterministic=None): - if value < 0: - value += 1 << 64 - bits = value & 0x7F - value >>= 7 - while value: - write(local_int2byte(0x80 | bits)) - bits = value & 0x7F - value >>= 7 - return write(local_int2byte(bits)) - - return EncodeSignedVarint - - -_EncodeVarint = _VarintEncoder() -_EncodeSignedVarint = _SignedVarintEncoder() - - -def _VarintBytes(value): - """Encode the given integer as a varint and return the bytes. - - This is only called at startup time so it doesn't need to be fast. - """ - - pieces = [] - _EncodeVarint(pieces.append, value, True) - return b''.join(pieces) - - -def TagBytes(field_number, wire_type): - """Encode the given tag and return the bytes. Only called at startup.""" - - return bytes(_VarintBytes(wire_format.PackTag(field_number, wire_type))) - - -# -------------------------------------------------------------------- -# As with sizers (see above), we have a number of common encoder -# implementations. - - -def _SimpleEncoder(wire_type, encode_value, compute_value_size): - """Return a constructor for an encoder for fields of a particular type. - - Args: - wire_type: The field's wire type, for encoding tags. - encode_value: A function which encodes an individual value, e.g. - _EncodeVarint(). - compute_value_size: A function which computes the size of an individual - value, e.g. _VarintSize(). - """ - - def SpecificEncoder(field_number, is_repeated, is_packed): - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - size = 0 - for element in value: - size += compute_value_size(element) - local_EncodeVarint(write, size, deterministic) - for element in value: - encode_value(write, element, deterministic) - - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeRepeatedField(write, value, deterministic): - for element in value: - write(tag_bytes) - encode_value(write, element, deterministic) - - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeField(write, value, deterministic): - write(tag_bytes) - return encode_value(write, value, deterministic) - - return EncodeField - - return SpecificEncoder - - -def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): - """Like SimpleEncoder but additionally invokes modify_value on every value - - before passing it to encode_value. Usually modify_value is ZigZagEncode. - """ - - def SpecificEncoder(field_number, is_repeated, is_packed): - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - size = 0 - for element in value: - size += compute_value_size(modify_value(element)) - local_EncodeVarint(write, size, deterministic) - for element in value: - encode_value(write, modify_value(element), deterministic) - - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeRepeatedField(write, value, deterministic): - for element in value: - write(tag_bytes) - encode_value(write, modify_value(element), deterministic) - - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeField(write, value, deterministic): - write(tag_bytes) - return encode_value(write, modify_value(value), deterministic) - - return EncodeField - - return SpecificEncoder - - -def _StructPackEncoder(wire_type, format): - """Return a constructor for an encoder for a fixed-width field. - - Args: - wire_type: The field's wire type, for encoding tags. - format: The format string to pass to struct.pack(). - """ - - value_size = struct.calcsize(format) - - def SpecificEncoder(field_number, is_repeated, is_packed): - local_struct_pack = struct.pack - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size, deterministic) - for element in value: - write(local_struct_pack(format, element)) - - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeRepeatedField(write, value, unused_deterministic=None): - for element in value: - write(tag_bytes) - write(local_struct_pack(format, element)) - - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeField(write, value, unused_deterministic=None): - write(tag_bytes) - return write(local_struct_pack(format, value)) - - return EncodeField - - return SpecificEncoder - - -def _FloatingPointEncoder(wire_type, format): - """Return a constructor for an encoder for float fields. - - This is like StructPackEncoder, but catches errors that may be due to - passing non-finite floating-point values to struct.pack, and makes a - second attempt to encode those values. - - Args: - wire_type: The field's wire type, for encoding tags. - format: The format string to pass to struct.pack(). - """ - - value_size = struct.calcsize(format) - if value_size == 4: - - def EncodeNonFiniteOrRaise(write, value): - # Remember that the serialized form uses little-endian byte order. - if value == _POS_INF: - write(b'\x00\x00\x80\x7F') - elif value == _NEG_INF: - write(b'\x00\x00\x80\xFF') - elif value != value: # NaN - write(b'\x00\x00\xC0\x7F') - else: - raise - - elif value_size == 8: - - def EncodeNonFiniteOrRaise(write, value): - if value == _POS_INF: - write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F') - elif value == _NEG_INF: - write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF') - elif value != value: # NaN - write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F') - else: - raise - - else: - raise ValueError( - "Can't encode floating-point values that are " - '%d bytes long (only 4 or 8)' % value_size - ) - - def SpecificEncoder(field_number, is_repeated, is_packed): - local_struct_pack = struct.pack - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size, deterministic) - for element in value: - # This try/except block is going to be faster than any code that - # we could write to check whether element is finite. - try: - write(local_struct_pack(format, element)) - except SystemError: - EncodeNonFiniteOrRaise(write, element) - - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeRepeatedField(write, value, unused_deterministic=None): - for element in value: - write(tag_bytes) - try: - write(local_struct_pack(format, element)) - except SystemError: - EncodeNonFiniteOrRaise(write, element) - - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - - def EncodeField(write, value, unused_deterministic=None): - write(tag_bytes) - try: - write(local_struct_pack(format, value)) - except SystemError: - EncodeNonFiniteOrRaise(write, value) - - return EncodeField - - return SpecificEncoder - - -# ==================================================================== -# Here we declare an encoder constructor for each field type. These work -# very similarly to sizer constructors, described earlier. - -Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder( - wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize -) - -UInt32Encoder = UInt64Encoder = _SimpleEncoder( - wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize -) - -SInt32Encoder = SInt64Encoder = _ModifiedEncoder( - wire_format.WIRETYPE_VARINT, - _EncodeVarint, - _VarintSize, - wire_format.ZigZagEncode, -) - -# Note that Python conveniently guarantees that when using the '<' prefix on -# formats, they will also have the same size across all platforms (as opposed -# to without the prefix, where their sizes depend on the C compiler's basic -# type sizes). -Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, ' str - ValueType = int - - def __init__(self, enum_type): - """Inits EnumTypeWrapper with an EnumDescriptor.""" - self._enum_type = enum_type - self.DESCRIPTOR = enum_type # pylint: disable=invalid-name - - def Name(self, number): # pylint: disable=invalid-name - """Returns a string containing the name of an enum value.""" - try: - return self._enum_type.values_by_number[number].name - except KeyError: - pass # fall out to break exception chaining - - if not isinstance(number, int): - raise TypeError( - 'Enum value for {} must be an int, but got {} {!r}.'.format( - self._enum_type.name, type(number), number - ) - ) - else: - # repr here to handle the odd case when you pass in a boolean. - raise ValueError( - 'Enum {} has no name defined for value {!r}'.format( - self._enum_type.name, number - ) - ) - - def Value(self, name): # pylint: disable=invalid-name - """Returns the value corresponding to the given enum name.""" - try: - return self._enum_type.values_by_name[name].number - except KeyError: - pass # fall out to break exception chaining - raise ValueError( - 'Enum {} has no value defined for name {!r}'.format( - self._enum_type.name, name - ) - ) - - def keys(self): - """Return a list of the string names in the enum. - - Returns: - A list of strs, in the order they were defined in the .proto file. - """ - - return [ - value_descriptor.name for value_descriptor in self._enum_type.values - ] - - def values(self): - """Return a list of the integer values in the enum. - - Returns: - A list of ints, in the order they were defined in the .proto file. - """ - - return [ - value_descriptor.number for value_descriptor in self._enum_type.values - ] - - def items(self): - """Return a list of the (name, value) pairs of the enum. - - Returns: - A list of (str, int) pairs, in the order they were defined - in the .proto file. - """ - return [ - (value_descriptor.name, value_descriptor.number) - for value_descriptor in self._enum_type.values - ] - - def __getattr__(self, name): - """Returns the value corresponding to the given enum name.""" - try: - return ( - super(EnumTypeWrapper, self) - .__getattribute__('_enum_type') - .values_by_name[name] - .number - ) - except KeyError: - pass # fall out to break exception chaining - raise AttributeError( - 'Enum {} has no value defined for name {!r}'.format( - self._enum_type.name, name - ) - ) - - def __or__(self, other): - """Returns the union type of self and other.""" - if sys.version_info >= (3, 10): - return type(self) | other - else: - raise NotImplementedError( - 'You may not use | on EnumTypes (or classes) below python 3.10' - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py deleted file mode 100644 index 16613ea70ed..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/extension_dict.py +++ /dev/null @@ -1,209 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains _ExtensionDict class to represent extensions.""" - -from opentelemetry.agent._vendor.google.protobuf.descriptor import FieldDescriptor -from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers - - -def _VerifyExtensionHandle(message, extension_handle): - """Verify that the given extension handle is valid.""" - - if not isinstance(extension_handle, FieldDescriptor): - raise KeyError( - 'HasExtension() expects an extension handle, got: %s' % extension_handle - ) - - if not extension_handle.is_extension: - raise KeyError('"%s" is not an extension.' % extension_handle.full_name) - - if not extension_handle.containing_type: - raise KeyError( - '"%s" is missing a containing_type.' % extension_handle.full_name - ) - - if extension_handle.containing_type is not message.DESCRIPTOR: - raise KeyError( - 'Extension "%s" extends message type "%s", but this ' - 'message is of type "%s".' - % ( - extension_handle.full_name, - extension_handle.containing_type.full_name, - message.DESCRIPTOR.full_name, - ) - ) - - -# TODO: Unify error handling of "unknown extension" crap. -# TODO: Support iteritems()-style iteration over all -# extensions with the "has" bits turned on? -class _ExtensionDict(object): - """Dict-like container for Extension fields on proto instances. - - Note that in all cases we expect extension handles to be - FieldDescriptors. - """ - - def __init__(self, extended_message): - """Args: - - extended_message: Message instance for which we are the Extensions dict. - """ - self._extended_message = extended_message - - def __getitem__(self, extension_handle): - """Returns the current value of the given extension handle.""" - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - result = self._extended_message._fields.get(extension_handle) - if result is not None: - return result - - if extension_handle.is_repeated: - result = extension_handle._default_constructor(self._extended_message) - elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - message_type = extension_handle.message_type - if not hasattr(message_type, '_concrete_class'): - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import message_factory - - message_factory.GetMessageClass(message_type) - if not hasattr(extension_handle.message_type, '_concrete_class'): - from opentelemetry.agent._vendor.google.protobuf import message_factory - - message_factory.GetMessageClass(extension_handle.message_type) - result = extension_handle.message_type._concrete_class() - try: - result._SetListener(self._extended_message._listener_for_children) - except ReferenceError: - pass - else: - # Singular scalar -- just return the default without inserting into the - # dict. - return extension_handle.default_value - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - if self._extended_message._frozen: - result._SetFrozen() - result = self._extended_message._fields.setdefault(extension_handle, result) - - return result - - def __eq__(self, other): - if not isinstance(other, self.__class__): - return False - - my_fields = self._extended_message.ListFields() - other_fields = other._extended_message.ListFields() - - # Get rid of non-extension fields. - my_fields = [field for field in my_fields if field.is_extension] - other_fields = [field for field in other_fields if field.is_extension] - - return my_fields == other_fields - - def __ne__(self, other): - return not self == other - - def __len__(self): - fields = self._extended_message.ListFields() - # Get rid of non-extension fields. - extension_fields = [field for field in fields if field[0].is_extension] - return len(extension_fields) - - def __hash__(self): - raise TypeError('unhashable object') - - # Note that this is only meaningful for non-repeated, scalar extension - # fields. Note also that we may have to call _Modified() when we do - # successfully set a field this way, to set any necessary "has" bits in the - # ancestors of the extended message. - def __setitem__(self, extension_handle, value): - """If extension_handle specifies a non-repeated, scalar extension - - field, sets the value of that field. - """ - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - self._extended_message._AssureWritable() - - if ( - extension_handle.is_repeated - or extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE - ): - raise TypeError( - 'Cannot assign to extension "%s" because it is a repeated or ' - 'composite type.' - % extension_handle.full_name - ) - - # It's slightly wasteful to lookup the type checker each time, - # but we expect this to be a vanishingly uncommon case anyway. - type_checker = type_checkers.GetTypeChecker(extension_handle) - # pylint: disable=protected-access - self._extended_message._fields[extension_handle] = type_checker.CheckValue( - value - ) - self._extended_message._Modified() - - def __delitem__(self, extension_handle): - self._extended_message.ClearExtension(extension_handle) - - def _FindExtensionByName(self, name): - """Tries to find a known extension with the specified name. - - Args: - name: Extension full name. - - Returns: - Extension field descriptor. - """ - descriptor = self._extended_message.DESCRIPTOR - extensions = descriptor.file.pool._extensions_by_name[descriptor] - return extensions.get(name, None) - - def _FindExtensionByNumber(self, number): - """Tries to find a known extension with the field number. - - Args: - number: Extension field number. - - Returns: - Extension field descriptor. - """ - descriptor = self._extended_message.DESCRIPTOR - extensions = descriptor.file.pool._extensions_by_number[descriptor] - return extensions.get(number, None) - - def __iter__(self): - # Return a generator over the populated extension fields - return ( - f[0] for f in self._extended_message.ListFields() if f[0].is_extension - ) - - def __contains__(self, extension_handle): - _VerifyExtensionHandle(self._extended_message, extension_handle) - - if extension_handle not in self._extended_message._fields: - return False - - if extension_handle.is_repeated: - return bool(self._extended_message._fields.get(extension_handle)) - - if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - value = self._extended_message._fields.get(extension_handle) - # pylint: disable=protected-access - return value is not None and value._is_present_in_parent - - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py deleted file mode 100644 index 27b176e351c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/field_mask.py +++ /dev/null @@ -1,352 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains FieldMask class.""" - -from opentelemetry.agent._vendor.google.protobuf.descriptor import FieldDescriptor - - -class FieldMask(object): - """Class for FieldMask message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts FieldMask to string according to ProtoJSON spec.""" - camelcase_paths = [] - for path in self.paths: - camelcase_paths.append(_SnakeCaseToCamelCase(path)) - return ','.join(camelcase_paths) - - def FromJsonString(self, value): - """Converts string to FieldMask according to ProtoJSON spec.""" - if not isinstance(value, str): - raise ValueError('FieldMask JSON value not a string: {!r}'.format(value)) - self.Clear() - if value: - for path in value.split(','): - self.paths.append(_CamelCaseToSnakeCase(path)) - - def IsValidForDescriptor(self, message_descriptor): - """Checks whether the FieldMask is valid for Message Descriptor.""" - for path in self.paths: - if not _IsValidPath(message_descriptor, path): - return False - return True - - def AllFieldsFromDescriptor(self, message_descriptor): - """Gets all direct fields of Message Descriptor to FieldMask.""" - self.Clear() - for field in message_descriptor.fields: - self.paths.append(field.name) - - def CanonicalFormFromMask(self, mask): - """Converts a FieldMask to the canonical form. - - Removes paths that are covered by another path. For example, - "foo.bar" is covered by "foo" and will be removed if "foo" - is also in the FieldMask. Then sorts all paths in alphabetical order. - - Args: - mask: The original FieldMask to be converted. - """ - tree = _FieldMaskTree(mask) - tree.ToFieldMask(self) - - def Union(self, mask1, mask2): - """Merges mask1 and mask2 into this FieldMask.""" - _CheckFieldMaskMessage(mask1) - _CheckFieldMaskMessage(mask2) - tree = _FieldMaskTree(mask1) - tree.MergeFromFieldMask(mask2) - tree.ToFieldMask(self) - - def Intersect(self, mask1, mask2): - """Intersects mask1 and mask2 into this FieldMask.""" - _CheckFieldMaskMessage(mask1) - _CheckFieldMaskMessage(mask2) - tree = _FieldMaskTree(mask1) - intersection = _FieldMaskTree() - for path in mask2.paths: - tree.IntersectPath(path, intersection) - intersection.ToFieldMask(self) - - def MergeMessage( - self, - source, - destination, - replace_message_field=False, - replace_repeated_field=False, - ): - """Merges fields specified in FieldMask from source to destination. - - Args: - source: Source message. - destination: The destination message to be merged into. - replace_message_field: Replace message field if True. Merge message field - if False. - replace_repeated_field: Replace repeated field if True. Append elements of - repeated field if False. - """ - tree = _FieldMaskTree(self) - tree.MergeMessage( - source, destination, replace_message_field, replace_repeated_field - ) - - -def _IsValidPath(message_descriptor, path): - """Checks whether the path is valid for Message Descriptor.""" - parts = path.split('.') - last = parts.pop() - for name in parts: - field = message_descriptor.fields_by_name.get(name) - if ( - field is None - or field.is_repeated - or field.type != FieldDescriptor.TYPE_MESSAGE - ): - return False - message_descriptor = field.message_type - return last in message_descriptor.fields_by_name - - -def _CheckFieldMaskMessage(message): - """Raises ValueError if message is not a FieldMask.""" - message_descriptor = message.DESCRIPTOR - if ( - message_descriptor.name != 'FieldMask' - or message_descriptor.file.name != 'google/protobuf/field_mask.proto' - ): - raise ValueError( - 'Message {0} is not a FieldMask.'.format(message_descriptor.full_name) - ) - - -def _SnakeCaseToCamelCase(path_name): - """Converts a path name from snake_case to camelCase.""" - result = [] - after_underscore = False - for c in path_name: - if c.isupper(): - raise ValueError( - 'Fail to print FieldMask to Json string: Path name ' - '{0} must not contain uppercase letters.'.format(path_name) - ) - if after_underscore: - if c.islower(): - result.append(c.upper()) - after_underscore = False - else: - raise ValueError( - 'Fail to print FieldMask to Json string: The ' - 'character after a "_" must be a lowercase letter ' - 'in path name {0}.'.format(path_name) - ) - elif c == '_': - after_underscore = True - else: - result += c - - if after_underscore: - raise ValueError( - 'Fail to print FieldMask to Json string: Trailing "_" ' - 'in path name {0}.'.format(path_name) - ) - return ''.join(result) - - -def _CamelCaseToSnakeCase(path_name): - """Converts a field name from camelCase to snake_case.""" - result = [] - for c in path_name: - if c == '_': - raise ValueError( - 'Fail to parse FieldMask: Path name ' - '{0} must not contain "_"s.'.format(path_name) - ) - if c.isupper(): - result += '_' - result += c.lower() - else: - result += c - return ''.join(result) - - -class _FieldMaskTree(object): - """Represents a FieldMask in a tree structure. - - For example, given a FieldMask "foo.bar,foo.baz,bar.baz", - the FieldMaskTree will be: - [_root] -+- foo -+- bar - | | - | +- baz - | - +- bar --- baz - In the tree, each leaf node represents a field path. - """ - - __slots__ = ('_root',) - - def __init__(self, field_mask=None): - """Initializes the tree by FieldMask.""" - self._root = {} - if field_mask: - self.MergeFromFieldMask(field_mask) - - def MergeFromFieldMask(self, field_mask): - """Merges a FieldMask to the tree.""" - for path in field_mask.paths: - self.AddPath(path) - - def AddPath(self, path): - """Adds a field path into the tree. - - If the field path to add is a sub-path of an existing field path - in the tree (i.e., a leaf node), it means the tree already matches - the given path so nothing will be added to the tree. If the path - matches an existing non-leaf node in the tree, that non-leaf node - will be turned into a leaf node with all its children removed because - the path matches all the node's children. Otherwise, a new path will - be added. - - Args: - path: The field path to add. - """ - node = self._root - for name in path.split('.'): - if name not in node: - node[name] = {} - elif not node[name]: - # Pre-existing empty node implies we already have this entire tree. - return - node = node[name] - # Remove any sub-trees we might have had. - node.clear() - - def ToFieldMask(self, field_mask): - """Converts the tree to a FieldMask.""" - field_mask.Clear() - _AddFieldPaths(self._root, '', field_mask) - - def IntersectPath(self, path, intersection): - """Calculates the intersection part of a field path with this tree. - - Args: - path: The field path to calculates. - intersection: The out tree to record the intersection part. - """ - node = self._root - for name in path.split('.'): - if name not in node: - return - elif not node[name]: - intersection.AddPath(path) - return - node = node[name] - intersection.AddLeafNodes(path, node) - - def AddLeafNodes(self, prefix, node): - """Adds leaf nodes begin with prefix to this tree.""" - if not node: - self.AddPath(prefix) - return - stack = [(prefix, node)] - while stack: - current_prefix, current_node = stack.pop() - if not current_node: - self.AddPath(current_prefix) - continue - for name in current_node: - child_path = current_prefix + '.' + name - stack.append((child_path, current_node[name])) - - def MergeMessage( - self, source, destination, replace_message, replace_repeated - ): - """Merge all fields specified by this tree from source to destination.""" - _MergeMessage( - self._root, source, destination, replace_message, replace_repeated - ) - - -def _StrConvert(value): - """Converts value to str if it is not.""" - # This file is imported by c extension and some methods like ClearField - # requires string for the field name. py2/py3 has different text - # type and may use unicode. - if not isinstance(value, str): - return value.encode('utf-8') - return value - - -def _MergeMessage(node, source, destination, replace_message, replace_repeated): - """Merge all fields specified by a sub-tree from source to destination.""" - stack = [(node, source, destination)] - while stack: - current_node, current_source, current_destination = stack.pop() - source_descriptor = current_source.DESCRIPTOR - for name in current_node: - child = current_node[name] - field = source_descriptor.fields_by_name[name] - if field is None: - raise ValueError( - "Error: Can't find field {0} in message {1}.".format( - name, source_descriptor.full_name - ) - ) - if child: - # Sub-paths are only allowed for singular message fields. - if ( - field.is_repeated - or field.cpp_type != FieldDescriptor.CPPTYPE_MESSAGE - ): - raise ValueError( - 'Error: Field {0} in message {1} is not a singular ' - 'message field and cannot have sub-fields.'.format( - name, source_descriptor.full_name - ) - ) - if current_source.HasField(name): - stack.append(( - child, - getattr(current_source, name), - getattr(current_destination, name), - )) - continue - if field.is_repeated: - if replace_repeated: - current_destination.ClearField(_StrConvert(name)) - repeated_source = getattr(current_source, name) - repeated_destination = getattr(current_destination, name) - repeated_destination.MergeFrom(repeated_source) - else: - if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - if replace_message: - current_destination.ClearField(_StrConvert(name)) - if current_source.HasField(name): - getattr(current_destination, name).MergeFrom( - getattr(current_source, name) - ) - elif not field.has_presence or current_source.HasField(name): - setattr(current_destination, name, getattr(current_source, name)) - else: - current_destination.ClearField(_StrConvert(name)) - - -def _AddFieldPaths(node, prefix, field_mask): - """Adds the field paths descended from node to field_mask.""" - stack = [(node, prefix)] - while stack: - current_node, current_prefix = stack.pop() - if not current_node and current_prefix: - field_mask.paths.append(current_prefix) - continue - for name in sorted(current_node, reverse=True): - if current_prefix: - child_path = current_prefix + '.' + name - else: - child_path = name - stack.append((current_node[name], child_path)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py deleted file mode 100644 index 7abb851d7c2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/message_listener.py +++ /dev/null @@ -1,56 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -"""Defines a listener interface for observing certain - -state transitions on Message objects. - -Also defines a null implementation of this interface. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - - -class MessageListener(object): - """Listens for modifications made to a message. - - Meant to be registered via Message._SetListener(). - - Attributes: - dirty: If True, then calling Modified() would be a no-op. This can be used - to avoid these calls entirely in the common case. - """ - - def Modified(self): - """Called every time the message is modified in such a way that the parent - - message may need to be updated. This currently means either: - (a) The message was modified for the first time, so the parent message - should henceforth mark the message as present. - (b) The message's cached byte size became dirty -- i.e. the message was - modified for the first time after a previous call to ByteSize(). - Therefore the parent should also mark its byte size as dirty. - Note that (a) implies (b), since new objects start out with a client cached - size (zero). However, we document (a) explicitly because it is important. - - Modified() will *only* be called in response to one of these two events -- - not every time the sub-message is modified. - - Note that if the listener's |dirty| attribute is true, then calling - Modified at the moment would be a no-op, so it can be skipped. Performance- - sensitive callers should check this attribute directly before calling since - it will be true most of the time. - """ - - raise NotImplementedError - - -class NullMessageListener(object): - """No-op MessageListener implementation.""" - - def Modified(self): - pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py deleted file mode 100644 index a6b7741c58a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_edition_defaults.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -This file contains the serialized FeatureSetDefaults object corresponding to -the Pure Python runtime. This is used for feature resolution under Editions. -""" -_PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS = b"\n\031\030\204\007\"\000*\022\010\001\020\002\030\002 \003(\0010\0028\002@\001H\001\n\031\030\347\007\"\000*\022\010\002\020\001\030\001 \002(\0010\0018\002@\001H\001\n\031\030\350\007\"\014\010\001\020\001\030\001 \002(\0010\001*\0068\002@\001H\001\n\031\030\351\007\"\020\010\001\020\001\030\001 \002(\0010\0018\001@\002*\002H\001\n\031\030\352\007\"\022\010\001\020\001\030\001 \002(\0010\0018\003@\004H\002*\000 \346\007(\352\007" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py deleted file mode 100644 index 556e3f4ab0d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/python_message.py +++ /dev/null @@ -1,1778 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -# This code is meant to work on Python 2.4 and above only. -# -# TODO: Helpers for verbose, common checks like seeing if a -# descriptor's cpp_type is CPPTYPE_MESSAGE. -"""Contains a metaclass and helper functions used to create - -protocol message classes from Descriptor objects at runtime. - -Recall that a metaclass is the "type" of a class. -(A class is to a metaclass what an instance is to a class.) - -In this case, we use the GeneratedProtocolMessageType metaclass -to inject all the useful functionality into the classes -output by the protocol compiler at compile-time. - -The upshot of all this is that the real implementation -details for ALL pure-Python protocol buffers are *here in -this file*. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import datetime -from io import BytesIO -import math -import struct -import sys -import warnings -import weakref - -from opentelemetry.agent._vendor.google.protobuf import descriptor as descriptor_mod -from opentelemetry.agent._vendor.google.protobuf import message as message_mod -from opentelemetry.agent._vendor.google.protobuf import text_format - -# We use "as" to avoid name collisions with variables. -from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation -from opentelemetry.agent._vendor.google.protobuf.internal import containers -from opentelemetry.agent._vendor.google.protobuf.internal import decoder -from opentelemetry.agent._vendor.google.protobuf.internal import encoder -from opentelemetry.agent._vendor.google.protobuf.internal import enum_type_wrapper -from opentelemetry.agent._vendor.google.protobuf.internal import extension_dict -from opentelemetry.agent._vendor.google.protobuf.internal import message_listener as message_listener_mod -from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers -from opentelemetry.agent._vendor.google.protobuf.internal import well_known_types -from opentelemetry.agent._vendor.google.protobuf.internal import wire_format - -_FieldDescriptor = descriptor_mod.FieldDescriptor -_AnyFullTypeName = 'google.protobuf.Any' -_StructFullTypeName = 'google.protobuf.Struct' -_ListValueFullTypeName = 'google.protobuf.ListValue' -_ExtensionDict = extension_dict._ExtensionDict - - -class GeneratedProtocolMessageType(type): - """Metaclass for protocol message classes created at runtime from Descriptors. - - We add implementations for all methods described in the Message class. We - also create properties to allow getting/setting all fields in the protocol - message. Finally, we create slots to prevent users from accidentally - "setting" nonexistent fields in the protocol message, which then wouldn't get - serialized / deserialized properly. - - The protocol compiler currently uses this metaclass to create protocol - message classes at runtime. Clients can also manually create their own - classes at runtime, as in this example: - - mydescriptor = Descriptor(.....) - factory = symbol_database.Default() - factory.pool.AddDescriptor(mydescriptor) - MyProtoClass = message_factory.GetMessageClass(mydescriptor) - myproto_instance = MyProtoClass() - myproto.foo_field = 23 - ... - """ - - # Must be consistent with the protocol-compiler code in - # proto2/compiler/internal/generator.*. - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __new__(cls, name, bases, dictionary): - """Custom allocation for runtime-generated class types. - - We override __new__ because this is apparently the only place - where we can meaningfully set __slots__ on the class we're creating(?). - (The interplay between metaclasses and slots is not very well-documented). - - Args: - name: Name of the class (ignored, but required by the metaclass protocol). - bases: Base classes of the class we're constructing. (Should be - message.Message). We ignore this field, but it's required by the - metaclass protocol - dictionary: The class dictionary of the class we're constructing. - dictionary[_DESCRIPTOR_KEY] must contain a Descriptor object describing - this protocol message type. - - Returns: - Newly-allocated class. - - Raises: - RuntimeError: Generated code only work with python cpp extension. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - - if isinstance(descriptor, str): - raise RuntimeError( - 'The generated code only work with python cpp ' - 'extension, but it is using pure python runtime.' - ) - - # If a concrete class already exists for this descriptor, don't try to - # create another. Doing so will break any messages that already exist with - # the existing class. - # - # The C++ implementation appears to have its own internal `PyMessageFactory` - # to achieve similar results. - # - # This most commonly happens in `text_format.py` when using descriptors from - # a custom pool; it calls message_factory.GetMessageClass() on a - # descriptor which already has an existing concrete class. - new_class = getattr(descriptor, '_concrete_class', None) - if new_class: - return new_class - - if descriptor.full_name in well_known_types.WKTBASES: - bases += (well_known_types.WKTBASES[descriptor.full_name],) - _AddClassAttributesForNestedExtensions(descriptor, dictionary) - _AddSlots(descriptor, dictionary) - - superclass = super(GeneratedProtocolMessageType, cls) - new_class = superclass.__new__(cls, name, bases, dictionary) - return new_class - - def __init__(cls, name, bases, dictionary): - """Here we perform the majority of our work on the class. - - We add enum getters, an __init__ method, implementations of all Message - methods, and properties for all fields in the protocol type. - - Args: - name: Name of the class (ignored, but required by the metaclass protocol). - bases: Base classes of the class we're constructing. (Should be - message.Message). We ignore this field, but it's required by the - metaclass protocol - dictionary: The class dictionary of the class we're constructing. - dictionary[_DESCRIPTOR_KEY] must contain a Descriptor object describing - this protocol message type. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - - # If this is an _existing_ class looked up via `_concrete_class` in the - # __new__ method above, then we don't need to re-initialize anything. - existing_class = getattr(descriptor, '_concrete_class', None) - if existing_class: - assert existing_class is cls, ( - 'Duplicate `GeneratedProtocolMessageType` created for descriptor %r' - % (descriptor.full_name) - ) - return - - cls._message_set_decoders_by_tag = {} - cls._fields_by_tag = {} - if ( - descriptor.has_options - and descriptor.GetOptions().message_set_wire_format - ): - cls._message_set_decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( - decoder.MessageSetItemDecoder(descriptor), - None, - ) - - # Attach stuff to each FieldDescriptor for quick lookup later on. - for field in descriptor.fields: - _AttachFieldHelpers(cls, field) - - if descriptor.is_extendable and hasattr(descriptor.file, 'pool'): - extensions = descriptor.file.pool.FindAllExtensions(descriptor) - for ext in extensions: - _AttachFieldHelpers(cls, ext) - - descriptor._concrete_class = cls # pylint: disable=protected-access - _AddEnumValues(descriptor, cls) - _AddInitMethod(descriptor, cls) - _AddPropertiesForFields(descriptor, cls) - _AddPropertiesForExtensions(descriptor, cls) - _AddStaticMethods(cls) - _AddMessageMethods(descriptor, cls) - _AddPrivateHelperMethods(descriptor, cls) - - superclass = super(GeneratedProtocolMessageType, cls) - superclass.__init__(name, bases, dictionary) - - -# Stateless helpers for GeneratedProtocolMessageType below. -# Outside clients should not access these directly. -# -# I opted not to make any of these methods on the metaclass, to make it more -# clear that I'm not really using any state there and to keep clients from -# thinking that they have direct access to these construction helpers. - - -def _PropertyName(proto_field_name): - """Returns the name of the public property attribute which - - clients can use to get and (in some cases) set the value - of a protocol message field. - - Args: - proto_field_name: The protocol message field name, exactly as it appears (or - would appear) in a .proto file. - """ - # TODO: Escape Python keywords (e.g., yield), and test this support. - # nnorwitz makes my day by writing: - # """ - # FYI. See the keyword module in the stdlib. This could be as simple as: - # - # if keyword.iskeyword(proto_field_name): - # return proto_field_name + "_" - # return proto_field_name - # """ - # Kenton says: The above is a BAD IDEA. People rely on being able to use - # getattr() and setattr() to reflectively manipulate field values. If we - # rename the properties, then every such user has to also make sure to apply - # the same transformation. Note that currently if you name a field "yield", - # you can still access it just fine using getattr/setattr -- it's not even - # that cumbersome to do so. - # TODO: Remove this method entirely if/when everyone agrees with my - # position. - return proto_field_name - - -def _AddSlots(message_descriptor, dictionary): - """Adds a __slots__ entry to dictionary, containing the names of all valid - - attributes for this message type. - - Args: - message_descriptor: A Descriptor instance describing this message type. - dictionary: Class dictionary to which we'll add a '__slots__' entry. - """ - dictionary['__slots__'] = [ - '_cached_byte_size', - '_cached_byte_size_dirty', - '_fields', - '_unknown_fields', - '_is_present_in_parent', - '_listener', - '_listener_for_children', - '__weakref__', - '_oneofs', - '_frozen', - ] - - -def _IsMessageSetExtension(field): - return ( - field.is_extension - and field.containing_type.has_options - and field.containing_type.GetOptions().message_set_wire_format - and field.type == _FieldDescriptor.TYPE_MESSAGE - and not field.is_required - and not field.is_repeated - ) - - -def _IsMapField(field): - return ( - field.type == _FieldDescriptor.TYPE_MESSAGE - and field.message_type._is_map_entry - ) - - -def _IsMessageMapField(field): - value_type = field.message_type.fields_by_name['value'] - return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE - - -def _AttachFieldHelpers(cls, field_descriptor): - field_descriptor._default_constructor = _DefaultValueConstructorForField( - field_descriptor - ) - - def AddFieldByTag(wiretype, is_packed): - tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) - cls._fields_by_tag[tag_bytes] = (field_descriptor, is_packed) - - AddFieldByTag( - type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], False - ) - - if field_descriptor.is_repeated and wire_format.IsTypePackable( - field_descriptor.type - ): - # To support wire compatibility of adding packed = true, add a decoder for - # packed values regardless of the field's options. - AddFieldByTag(wire_format.WIRETYPE_LENGTH_DELIMITED, True) - - -def _MaybeAddEncoder(cls, field_descriptor): - if hasattr(field_descriptor, '_encoder'): - return - is_repeated = field_descriptor.is_repeated - is_map_entry = _IsMapField(field_descriptor) - is_packed = field_descriptor.is_packed - - if is_map_entry: - key_descriptor = field_descriptor.message_type.fields_by_name['key'] - value_descriptor = field_descriptor.message_type.fields_by_name['value'] - - key_sizer = type_checkers.TYPE_TO_SIZER[key_descriptor.type]( - key_descriptor.number, False, False - ) - value_sizer = type_checkers.TYPE_TO_SIZER[value_descriptor.type]( - value_descriptor.number, False, False - ) - - key_encoder = type_checkers.TYPE_TO_ENCODER[key_descriptor.type]( - key_descriptor.number, False, False - ) - value_encoder = type_checkers.TYPE_TO_ENCODER[value_descriptor.type]( - value_descriptor.number, False, False - ) - - field_encoder = encoder.MapEncoder( - field_descriptor, key_encoder, value_encoder, key_sizer, value_sizer - ) - sizer = encoder.MapSizer(field_descriptor, key_sizer, value_sizer) - elif _IsMessageSetExtension(field_descriptor): - field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) - sizer = encoder.MessageSetItemSizer(field_descriptor.number) - else: - field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed - ) - sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed - ) - - field_descriptor._sizer = sizer - field_descriptor._encoder = field_encoder - - -def _MaybeAddDecoder(cls, field_descriptor): - if hasattr(field_descriptor, '_decoders'): - return - - is_repeated = field_descriptor.is_repeated - is_map_entry = _IsMapField(field_descriptor) - helper_decoders = {} - - def AddDecoder(is_packed): - decode_type = field_descriptor.type - if ( - decode_type == _FieldDescriptor.TYPE_ENUM - and not field_descriptor.enum_type.is_closed - ): - decode_type = _FieldDescriptor.TYPE_INT32 - - oneof_descriptor = None - if field_descriptor.containing_oneof is not None: - oneof_descriptor = field_descriptor - - if is_map_entry: - is_message_map = _IsMessageMapField(field_descriptor) - - field_decoder = decoder.MapDecoder( - field_descriptor, - _GetInitializeDefaultForMap(field_descriptor), - is_message_map, - ) - elif decode_type == _FieldDescriptor.TYPE_STRING: - field_decoder = decoder.StringDecoder( - field_descriptor.number, - is_repeated, - is_packed, - field_descriptor, - field_descriptor._default_constructor, - not field_descriptor.has_presence, - ) - elif field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( - field_descriptor.number, - is_repeated, - is_packed, - field_descriptor, - field_descriptor._default_constructor, - ) - else: - field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( - field_descriptor.number, - is_repeated, - is_packed, - # pylint: disable=protected-access - field_descriptor, - field_descriptor._default_constructor, - not field_descriptor.has_presence, - ) - - helper_decoders[is_packed] = field_decoder - - AddDecoder(False) - - if is_repeated and wire_format.IsTypePackable(field_descriptor.type): - # To support wire compatibility of adding packed = true, add a decoder for - # packed values regardless of the field's options. - AddDecoder(True) - - field_descriptor._decoders = helper_decoders - - -def _AddClassAttributesForNestedExtensions(descriptor, dictionary): - extensions = descriptor.extensions_by_name - for extension_name, extension_field in extensions.items(): - assert extension_name not in dictionary - dictionary[extension_name] = extension_field - - -def _AddEnumValues(descriptor, cls): - """Sets class-level attributes for all enum fields defined in this message. - - Also exporting a class-level object that can name enum values. - - Args: - descriptor: Descriptor object for this message type. - cls: Class we're constructing for this message type. - """ - for enum_type in descriptor.enum_types: - setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type)) - for enum_value in enum_type.values: - setattr(cls, enum_value.name, enum_value.number) - - -def _GetInitializeDefaultForMap(field): - if not field.is_repeated: - raise ValueError('map_entry set on non-repeated field %s' % (field.name)) - fields_by_name = field.message_type.fields_by_name - key_checker = type_checkers.GetTypeChecker(fields_by_name['key']) - - value_field = fields_by_name['value'] - if _IsMessageMapField(field): - - def MakeMessageMapDefault(message): - return containers.MessageMap( - message._listener_for_children, - value_field.message_type, - key_checker, - field.message_type, - ) - - return MakeMessageMapDefault - else: - value_checker = type_checkers.GetTypeChecker(value_field) - - def MakePrimitiveMapDefault(message): - return containers.ScalarMap( - message._listener_for_children, - key_checker, - value_checker, - field.message_type, - ) - - return MakePrimitiveMapDefault - - -def _DefaultValueConstructorForField(field): - """Returns a function which returns a default value for a field. - - Args: - field: FieldDescriptor object for this field. - - The returned function has one argument: - message: Message instance containing this field, or a weakref proxy - of same. - - That function in turn returns a default value for this field. The default - value may refer back to |message| via a weak reference. - """ - - if _IsMapField(field): - return _GetInitializeDefaultForMap(field) - - if field.is_repeated: - if field.has_default_value and field.default_value != []: - raise ValueError( - 'Repeated field default value not empty list: %s' - % (field.default_value) - ) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - # We can't look at _concrete_class yet since it might not have - # been set. (Depends on order in which we initialize the classes). - message_type = field.message_type - - def MakeRepeatedMessageDefault(message): - return containers.RepeatedCompositeFieldContainer( - message._listener_for_children, field.message_type - ) - - return MakeRepeatedMessageDefault - else: - type_checker = type_checkers.GetTypeChecker(field) - - def MakeRepeatedScalarDefault(message): - return containers.RepeatedScalarFieldContainer( - message._listener_for_children, type_checker, field - ) - - return MakeRepeatedScalarDefault - - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - message_type = field.message_type - - def MakeSubMessageDefault(message): - # _concrete_class may not yet be initialized. - if not hasattr(message_type, '_concrete_class'): - from opentelemetry.agent._vendor.google.protobuf import message_factory - - message_factory.GetMessageClass(message_type) - result = message_type._concrete_class() - result._SetListener( - _OneofListener(message, field) - if field.containing_oneof is not None - else message._listener_for_children - ) - return result - - return MakeSubMessageDefault - - def MakeScalarDefault(message): - # TODO: This may be broken since there may not be - # default_value. Combine with has_default_value somehow. - return field.default_value - - return MakeScalarDefault - - -def _ReraiseTypeErrorWithFieldName(message_name, field_name): - """Re-raise the currently-handled TypeError with the field name added.""" - exc = sys.exc_info()[1] - if len(exc.args) == 1 and type(exc) is TypeError: - # simple TypeError; add field name to exception message - exc = TypeError('%s for field %s.%s' % (str(exc), message_name, field_name)) - - # re-raise possibly-amended exception with original traceback: - raise exc.with_traceback(sys.exc_info()[2]) - - -def _AddInitMethod(message_descriptor, cls): - """Adds an __init__ method to cls.""" - - def _GetIntegerEnumValue(enum_type, value): - """Convert a string or integer enum value to an integer. - - If the value is a string, it is converted to the enum value in - enum_type with the same name. If the value is not a string, it's - returned as-is. (No conversion or bounds-checking is done.) - """ - if isinstance(value, str): - try: - return enum_type.values_by_name[value].number - except KeyError: - raise ValueError( - 'Enum type %s: unknown label "%s"' % (enum_type.full_name, value) - ) - return value - - def init(self, **kwargs): - - def init_wkt_or_merge(field, msg, value): - if isinstance(value, message_mod.Message): - msg.MergeFrom(value) - elif ( - isinstance(value, dict) - and field.message_type.full_name == _StructFullTypeName - ): - msg.Clear() - if len(value) == 1 and 'fields' in value: - try: - msg.update(value) - except: - msg.Clear() - msg.__init__(**value) - else: - msg.update(value) - elif hasattr(msg, '_internal_assign'): - msg._internal_assign(value) - else: - raise TypeError( - 'Message field {0}.{1} must be initialized with a ' - 'dict or instance of same class, got {2}.'.format( - message_descriptor.name, - field.name, - type(value).__name__, - ) - ) - - self._cached_byte_size = 0 - self._cached_byte_size_dirty = len(kwargs) > 0 - self._fields = {} - # Contains a mapping from oneof field descriptors to the descriptor - # of the currently set field in that oneof field. - self._oneofs = {} - - # _unknown_fields is () when empty for efficiency, and will be turned into - # a list if fields are added. - self._unknown_fields = () - self._is_present_in_parent = False - self._listener = message_listener_mod.NullMessageListener() - self._listener_for_children = _Listener(self) - self._frozen = False - for field_name, field_value in kwargs.items(): - field = _GetFieldByName(message_descriptor, field_name) - if field is None: - raise TypeError( - '%s() got an unexpected keyword argument "%s"' - % (message_descriptor.name, field_name) - ) - if field_value is None: - # field=None is the same as no field at all. - continue - if field.is_repeated: - field_copy = field._default_constructor(self) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite - if _IsMapField(field): - if _IsMessageMapField(field): - for key in field_value: - item_value = field_value[key] - if isinstance(item_value, dict): - field_copy[key].__init__(**item_value) - else: - field_copy[key].MergeFrom(item_value) - else: - field_copy.update(field_value) - else: - for val in field_value: - if isinstance(val, dict) and ( - field.message_type.full_name != _StructFullTypeName - ): - field_copy.add(**val) - else: - new_msg = field_copy.add() - init_wkt_or_merge(field, new_msg, val) - else: # Scalar - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - field_value = [ - _GetIntegerEnumValue(field.enum_type, val) - for val in field_value - ] - field_copy.extend(field_value) - self._fields[field] = field_copy - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - field_copy = field._default_constructor(self) - if isinstance(field_value, dict) and ( - field.message_type.full_name != _StructFullTypeName - ): - new_val = field.message_type._concrete_class(**field_value) - field_copy.MergeFrom(new_val) - else: - try: - init_wkt_or_merge(field, field_copy, field_value) - except TypeError: - _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) - self._fields[field] = field_copy - else: - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - field_value = _GetIntegerEnumValue(field.enum_type, field_value) - try: - setattr(self, field_name, field_value) - except TypeError: - _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) - - init.__module__ = None - init.__doc__ = None - cls.__init__ = init - - -def _GetFieldByName(message_descriptor, field_name): - """Returns a field descriptor by field name. - - Args: - message_descriptor: A Descriptor describing all fields in message. - field_name: The name of the field to retrieve. - - Returns: - The field descriptor associated with the field name. - """ - try: - return message_descriptor.fields_by_name[field_name] - except KeyError: - raise ValueError( - 'Protocol message %s has no "%s" field.' - % (message_descriptor.name, field_name) - ) - - -def _AddPropertiesForFields(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - for field in descriptor.fields: - _AddPropertiesForField(field, cls) - - if descriptor.is_extendable: - # _ExtensionDict is just an adaptor with no state so we allocate a new one - # every time it is accessed. - cls.Extensions = property(lambda self: _ExtensionDict(self)) - - -def _AddPropertiesForField(field, cls): - """Adds a public property for a protocol message field. - - Clients can use this property to get and (in the case of non-repeated scalar - fields) directly set the value of a protocol message field. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # Catch it if we add other types that we should - # handle specially here. - assert _FieldDescriptor.MAX_CPPTYPE == 10 - - constant_name = field.name.upper() + '_FIELD_NUMBER' - setattr(cls, constant_name, field.number) - - if field.is_repeated: - _AddPropertiesForRepeatedField(field, cls) - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - _AddPropertiesForNonRepeatedCompositeField(field, cls) - else: - _AddPropertiesForNonRepeatedScalarField(field, cls) - - -class _FieldProperty(property): - __slots__ = ('DESCRIPTOR',) - - def __init__(self, descriptor, getter, setter, doc): - property.__init__(self, getter, setter, doc=doc) - self.DESCRIPTOR = descriptor - - -def _AddPropertiesForRepeatedField(field, cls): - """Adds a public property for a "repeated" protocol message field. - - Clients can use this property to get the value of the field, which will be - either a RepeatedScalarFieldContainer or RepeatedCompositeFieldContainer (see - below). - - Note that when clients add values to these containers, we perform - type-checking in the case of repeated scalar fields, and we also set any - necessary "has" bits as a side-effect. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - if self._frozen: - field_value._SetFrozen() - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - raise AttributeError( - 'Assignment not allowed to repeated field ' - '"%s" in protocol message object.' % proto_field_name - ) - - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedScalarField(field, cls): - """Adds a public property for a nonrepeated, scalar protocol message field. - - Clients can use this property to get and directly set the value of the field. - Note that when the client sets the value of a field by using this property, - all necessary "has" bits are set as a side-effect, and we also perform - type-checking. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - type_checker = type_checkers.GetTypeChecker(field) - default_value = field.default_value - - def getter(self): - # TODO: This may be broken since there may not be - # default_value. Combine with has_default_value somehow. - return self._fields.get(field, default_value) - - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - def field_setter(self, new_value): - self._AssureWritable() - # pylint: disable=protected-access - # Testing the value for truthiness captures all of the implicit presence - # defaults (0, 0.0, enum 0, and False), except for -0.0. - try: - new_value = type_checker.CheckValue(new_value) - except TypeError as e: - raise TypeError( - 'Cannot set %s to %.1024r: %s' % (field.full_name, new_value, e) - ) - if not field.has_presence and decoder.IsDefaultScalarValue(new_value): - self._fields.pop(field, None) - else: - self._fields[field] = new_value - # Check _cached_byte_size_dirty inline to improve performance, since scalar - # setters are called frequently. - if not self._cached_byte_size_dirty: - self._Modified() - - if field.containing_oneof: - - def setter(self, new_value): - field_setter(self, new_value) - self._UpdateOneofState(field) - - else: - setter = field_setter - - setter.__module__ = None - setter.__doc__ = 'Setter for %s.' % proto_field_name - - # Add a property to encapsulate the getter/setter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedCompositeField(field, cls): - """Adds a public property for a nonrepeated, composite protocol message field. - - A composite field is a "group" or "message" field. - - Clients can use this property to get the value of the field, but cannot - assign to the property directly. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # TODO: Remove duplication with similar method - # for non-repeated scalars. - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - if self._frozen: - field_value._SetFrozen() - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - self._AssureWritable() - if field.message_type.full_name == 'google.protobuf.Timestamp': - getter(self) - self._fields[field].FromDatetime(new_value) - elif field.message_type.full_name == 'google.protobuf.Duration': - getter(self) - self._fields[field].FromTimedelta(new_value) - elif field.message_type.full_name == _StructFullTypeName: - getter(self) - self._fields[field].Clear() - self._fields[field].update(new_value) - elif field.message_type.full_name == _ListValueFullTypeName: - getter(self) - self._fields[field].Clear() - self._fields[field].extend(new_value) - else: - raise AttributeError( - 'Assignment not allowed to composite field ' - '"%s" in protocol message object.' % proto_field_name - ) - - # Add a property to encapsulate the getter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForExtensions(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - extensions = descriptor.extensions_by_name - for extension_name, extension_field in extensions.items(): - constant_name = extension_name.upper() + '_FIELD_NUMBER' - setattr(cls, constant_name, extension_field.number) - - # TODO: Migrate all users of these attributes to functions like - # pool.FindExtensionByNumber(descriptor). - if descriptor.file is not None: - # TODO: Use cls.MESSAGE_FACTORY.pool when available. - pool = descriptor.file.pool - - -def _AddStaticMethods(cls): - - def RegisterExtension(_): - """no-op to keep generated code <=4.23 working with new runtimes.""" - # This was originally removed in 5.26 (cl/595989309). - pass - - cls.RegisterExtension = staticmethod(RegisterExtension) - - def FromString(s): - message = cls() - message.MergeFromString(s) - return message - - cls.FromString = staticmethod(FromString) - - -def _IsPresent(item): - """Given a (FieldDescriptor, value) tuple from _fields, return true if the - - value should be included in the list returned by ListFields(). - """ - - if item[0].is_repeated: - return bool(item[1]) - elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - return item[1]._is_present_in_parent - else: - return True - - -def _AddListFieldsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ListFields(self): - all_fields = [item for item in self._fields.items() if _IsPresent(item)] - all_fields.sort(key=lambda item: item[0].number) - return all_fields - - cls.ListFields = ListFields - - -def _AddHasFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - hassable_fields = {} - for field in message_descriptor.fields: - if field.is_repeated: - continue - # For proto3, only submessages and fields inside a oneof have presence. - if not field.has_presence: - continue - hassable_fields[field.name] = field - - # Has methods are supported for oneof descriptors. - for oneof in message_descriptor.oneofs: - hassable_fields[oneof.name] = oneof - - def HasField(self, field_name): - try: - field = hassable_fields[field_name] - except KeyError as exc: - raise ValueError( - 'Protocol message %s has no non-repeated field "%s" ' - 'nor has presence is not available for this field.' - % (message_descriptor.full_name, field_name) - ) from exc - - if isinstance(field, descriptor_mod.OneofDescriptor): - try: - return HasField(self, self._oneofs[field].name) - except KeyError: - return False - else: - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(field) - return value is not None and value._is_present_in_parent - else: - return field in self._fields - - cls.HasField = HasField - - -def _AddClearFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ClearField(self, field_name): - self._AssureWritable() - try: - field = message_descriptor.fields_by_name[field_name] - except KeyError: - try: - field = message_descriptor.oneofs_by_name[field_name] - if field in self._oneofs: - field = self._oneofs[field] - else: - return - except KeyError: - raise ValueError( - 'Protocol message %s has no "%s" field.' - % (message_descriptor.name, field_name) - ) - - if field in self._fields: - # To match the C++ implementation, we need to invalidate iterators - # for map fields when ClearField() happens. - if hasattr(self._fields[field], 'InvalidateIterators'): - self._fields[field].InvalidateIterators() - - # Note: If the field is a sub-message, its listener will still point - # at us. That's fine, because the worst than can happen is that it - # will call _Modified() and invalidate our byte size. Big deal. - del self._fields[field] - - if self._oneofs.get(field.containing_oneof, None) is field: - del self._oneofs[field.containing_oneof] - - # Always call _Modified() -- even if nothing was changed, this is - # a mutating method, and thus calling it should cause the field to become - # present in the parent message. - self._Modified() - - cls.ClearField = ClearField - - -def _AddClearExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - - def ClearExtension(self, field_descriptor): - self._AssureWritable() - extension_dict._VerifyExtensionHandle(self, field_descriptor) - - # Similar to ClearField(), above. - if field_descriptor in self._fields: - del self._fields[field_descriptor] - self._Modified() - - cls.ClearExtension = ClearExtension - - -def _AddHasExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - - def HasExtension(self, field_descriptor): - extension_dict._VerifyExtensionHandle(self, field_descriptor) - if field_descriptor.is_repeated: - raise KeyError('"%s" is repeated.' % field_descriptor.full_name) - - if field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(field_descriptor) - return value is not None and value._is_present_in_parent - else: - return field_descriptor in self._fields - - cls.HasExtension = HasExtension - - -def _InternalUnpackAny(msg): - """Unpacks Any message and returns the unpacked message. - - This internal method is different from public Any Unpack method which takes - the target message as argument. _InternalUnpackAny method does not have - target message type and need to find the message type in descriptor pool. - - Args: - msg: An Any message to be unpacked. - - Returns: - The unpacked message. - """ - # TODO: Don't use the factory of generated messages. - # To make Any work with custom factories, use the message factory of the - # parent message. - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import symbol_database - - factory = symbol_database.Default() - - type_url = msg.type_url - - if not type_url: - return None - - # TODO: For now we just strip the hostname. Better logic will be - # required. - type_name = type_url.split('/')[-1] - descriptor = factory.pool.FindMessageTypeByName(type_name) - - if descriptor is None: - return None - - # Unable to import message_factory at top because of circular import. - # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf import message_factory - - message_class = message_factory.GetMessageClass(descriptor) - message = message_class() - - message.ParseFromString(msg.value) - return message - - -def _AddEqualsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def __eq__(self, other): - if self.DESCRIPTOR.full_name == _ListValueFullTypeName and isinstance( - other, list - ): - return self._internal_compare(other) - if self.DESCRIPTOR.full_name == _StructFullTypeName and isinstance( - other, dict - ): - return self._internal_compare(other) - - if ( - not isinstance(other, message_mod.Message) - or other.DESCRIPTOR != self.DESCRIPTOR - ): - return NotImplemented - - if self is other: - return True - - if self.DESCRIPTOR.full_name == _AnyFullTypeName: - any_a = _InternalUnpackAny(self) - any_b = _InternalUnpackAny(other) - if any_a and any_b: - return any_a == any_b - - if not self.ListFields() == other.ListFields(): - return False - - # TODO: Fix UnknownFieldSet to consider MessageSet extensions, - # then use it for the comparison. - unknown_fields = list(self._unknown_fields) - unknown_fields.sort() - other_unknown_fields = list(other._unknown_fields) - other_unknown_fields.sort() - return unknown_fields == other_unknown_fields - - cls.__eq__ = __eq__ - - -def _AddStrMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def __str__(self): - return text_format.MessageToString(self) - - cls.__str__ = __str__ - - -def _AddReprMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def __repr__(self): - return text_format.MessageToString(self) - - cls.__repr__ = __repr__ - - -def _AddUnicodeMethod(unused_message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def __unicode__(self): - return text_format.MessageToString(self, as_utf8=True).decode('utf-8') - - cls.__unicode__ = __unicode__ - - -def _AddContainsMethod(message_descriptor, cls): - - if message_descriptor.full_name == 'google.protobuf.Struct': - - def __contains__(self, key): - return key in self.fields - - elif message_descriptor.full_name == 'google.protobuf.ListValue': - - def __contains__(self, value): - return value in self.items() - - else: - - def __contains__(self, field): - return self.HasField(field) - - cls.__contains__ = __contains__ - - -def _BytesForNonRepeatedElement(value, field_number, field_type): - """Returns the number of bytes needed to serialize a non-repeated element. - - The returned byte count includes space for tag information and any other - additional space associated with serializing value. - - Args: - value: Value we're serializing. - field_number: Field number of this value. (Since the field number is stored - as part of a varint-encoded tag, this has an impact on the total bytes - required to serialize the value). - field_type: The type of the field. One of the TYPE_* constants within - FieldDescriptor. - """ - try: - fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] - return fn(field_number, value) - except KeyError: - raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) - - -def _AddByteSizeMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ByteSize(self): - if not self._cached_byte_size_dirty: - return self._cached_byte_size - - size = 0 - descriptor = self.DESCRIPTOR - if descriptor._is_map_entry: - # Fields of map entry should always be serialized. - key_field = descriptor.fields_by_name['key'] - _MaybeAddEncoder(cls, key_field) - size = key_field._sizer(self.key) - value_field = descriptor.fields_by_name['value'] - _MaybeAddEncoder(cls, value_field) - size += value_field._sizer(self.value) - else: - for field_descriptor, field_value in self.ListFields(): - _MaybeAddEncoder(cls, field_descriptor) - size += field_descriptor._sizer(field_value) - for tag_bytes, value_bytes in self._unknown_fields: - size += len(tag_bytes) + len(value_bytes) - - self._cached_byte_size = size - self._cached_byte_size_dirty = False - self._listener_for_children.dirty = False - return size - - cls.ByteSize = ByteSize - - -def _AddSerializeToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializeToString(self, **kwargs): - # Check if the message has all of its required fields set. - if not self.IsInitialized(): - raise message_mod.EncodeError( - 'Message %s is missing required fields: %s' - % ( - self.DESCRIPTOR.full_name, - ','.join(self.FindInitializationErrors()), - ) - ) - return self.SerializePartialToString(**kwargs) - - cls.SerializeToString = SerializeToString - - -def _AddSerializePartialToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializePartialToString(self, **kwargs): - out = BytesIO() - self._InternalSerialize(out.write, **kwargs) - return out.getvalue() - - cls.SerializePartialToString = SerializePartialToString - - def InternalSerialize(self, write_bytes, deterministic=None): - if deterministic is None: - deterministic = ( - api_implementation.IsPythonDefaultSerializationDeterministic() - ) - else: - deterministic = bool(deterministic) - - descriptor = self.DESCRIPTOR - if descriptor._is_map_entry: - # Fields of map entry should always be serialized. - key_field = descriptor.fields_by_name['key'] - _MaybeAddEncoder(cls, key_field) - key_field._encoder(write_bytes, self.key, deterministic) - value_field = descriptor.fields_by_name['value'] - _MaybeAddEncoder(cls, value_field) - value_field._encoder(write_bytes, self.value, deterministic) - else: - for field_descriptor, field_value in self.ListFields(): - _MaybeAddEncoder(cls, field_descriptor) - field_descriptor._encoder(write_bytes, field_value, deterministic) - for tag_bytes, value_bytes in self._unknown_fields: - write_bytes(tag_bytes) - write_bytes(value_bytes) - - cls._InternalSerialize = InternalSerialize - - -def _AddMergeFromStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def MergeFromString(self, serialized): - self._AssureWritable() - serialized = memoryview(serialized) - length = len(serialized) - try: - if self._InternalParse(serialized, 0, length) != length: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise message_mod.DecodeError('Unexpected end-group tag.') - except (IndexError, TypeError): - # Now ord(buf[p:p+1]) == ord('') gets TypeError. - raise message_mod.DecodeError('Truncated message.') - except struct.error as e: - raise message_mod.DecodeError(e) - return length # Return this for legacy reasons. - - cls.MergeFromString = MergeFromString - - fields_by_tag = cls._fields_by_tag - message_set_decoders_by_tag = cls._message_set_decoders_by_tag - - def InternalParse(self, buffer, pos, end, current_depth=0): - """Create a message from serialized bytes. - - Args: - self: Message, instance of the proto message object. - buffer: memoryview of the serialized data. - pos: int, position to start in the serialized data. - end: int, end position of the serialized data. - - Returns: - Message object. - """ - # Guard against internal misuse, since this function is called internally - # quite extensively, and its easy to accidentally pass bytes. - assert isinstance(buffer, memoryview) - self._Modified() - field_dict = self._fields - while pos != end: - tag_bytes, new_pos = decoder.ReadTag(buffer, pos) - field_decoder, field_des = message_set_decoders_by_tag.get( - tag_bytes, (None, None) - ) - if field_decoder: - pos = field_decoder( - buffer, new_pos, end, self, field_dict, current_depth - ) - continue - field_des, is_packed = fields_by_tag.get(tag_bytes, (None, None)) - if field_des is None: - if not self._unknown_fields: # pylint: disable=protected-access - self._unknown_fields = [] # pylint: disable=protected-access - field_number, wire_type = decoder.DecodeTag(tag_bytes) - if field_number == 0: - raise message_mod.DecodeError('Field number 0 is illegal.') - data, new_pos = decoder._DecodeUnknownField( - buffer, new_pos, end, field_number, wire_type - ) # pylint: disable=protected-access - if new_pos == -1: - return pos - self._unknown_fields.append( - (tag_bytes, buffer[pos + len(tag_bytes) : new_pos].tobytes()) - ) - pos = new_pos - else: - _MaybeAddDecoder(cls, field_des) - field_decoder = field_des._decoders[is_packed] - pos = field_decoder( - buffer, new_pos, end, self, field_dict, current_depth - ) - if field_des.containing_oneof: - self._UpdateOneofState(field_des) - return pos - - cls._InternalParse = InternalParse - - -def _AddIsInitializedMethod(message_descriptor, cls): - """Adds the IsInitialized and FindInitializationError methods to the - - protocol message class. - """ - - required_fields = [ - field for field in message_descriptor.fields if field.is_required - ] - - def IsInitialized(self, errors=None): - """Checks if all required fields of a message are set. - - Args: - errors: A list which, if provided, will be populated with the field paths - of all missing required fields. - - Returns: - True iff the specified message has all required fields set. - """ - - # Performance is critical so we avoid HasField() and ListFields(). - - for field in required_fields: - if field not in self._fields or ( - field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE - and not self._fields[field]._is_present_in_parent - ): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - for field, value in list(self._fields.items()): # dict can change size! - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.is_repeated: - if field.message_type._is_map_entry: - continue - for element in value: - if not element.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - elif value._is_present_in_parent and not value.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - return True - - cls.IsInitialized = IsInitialized - - def FindInitializationErrors(self): - """Finds required fields which are not initialized. - - Returns: - A list of strings. Each string is a path to an uninitialized field from - the top-level message, e.g. "foo.bar[5].baz". - """ - - errors = [] # simplify things - - for field in required_fields: - if not self.HasField(field.name): - errors.append(field.name) - - for field, value in self.ListFields(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.is_extension: - name = '(%s)' % field.full_name - else: - name = field.name - - if _IsMapField(field): - if _IsMessageMapField(field): - for key in value: - element = value[key] - prefix = '%s[%s].' % (name, key) - sub_errors = element.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - else: - # ScalarMaps can't have any initialization errors. - pass - elif field.is_repeated: - for i in range(len(value)): - element = value[i] - prefix = '%s[%d].' % (name, i) - sub_errors = element.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - else: - prefix = name + '.' - sub_errors = value.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - - return errors - - cls.FindInitializationErrors = FindInitializationErrors - - -def _FullyQualifiedClassName(klass): - module = klass.__module__ - name = getattr(klass, '__qualname__', klass.__name__) - if module in (None, 'builtins', '__builtin__'): - return name - return module + '.' + name - - -def _AddMergeFromMethod(cls): - CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE - - def MergeFrom(self, msg): - self._AssureWritable() - if not isinstance(msg, cls): - raise TypeError( - 'Parameter to MergeFrom() must be instance of same class: ' - 'expected %s got %s.' - % ( - _FullyQualifiedClassName(cls), - _FullyQualifiedClassName(msg.__class__), - ) - ) - - assert msg is not self - self._Modified() - - fields = self._fields - - for field, value in msg._fields.items(): - if field.is_repeated: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - elif field.cpp_type == CPPTYPE_MESSAGE: - if value._is_present_in_parent: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - else: - self._fields[field] = value - if field.containing_oneof: - self._UpdateOneofState(field) - - if msg._unknown_fields: - if not self._unknown_fields: - self._unknown_fields = [] - self._unknown_fields.extend(msg._unknown_fields) - - cls.MergeFrom = MergeFrom - - -def _AddWhichOneofMethod(message_descriptor, cls): - - def WhichOneof(self, oneof_name): - """Returns the name of the currently set field inside a oneof, or None.""" - try: - field = message_descriptor.oneofs_by_name[oneof_name] - except KeyError: - raise ValueError('Protocol message has no oneof "%s" field.' % oneof_name) - - nested_field = self._oneofs.get(field, None) - if nested_field is not None and self.HasField(nested_field.name): - return nested_field.name - else: - return None - - cls.WhichOneof = WhichOneof - - -def _Clear(self): - self._AssureWritable() - # Clear fields. - self._fields = {} - self._unknown_fields = () - - self._oneofs = {} - self._Modified() - - -def _SetFrozen(self): - self._frozen = True - for value in self._fields.values(): - if hasattr(value, '_SetFrozen'): - value._SetFrozen() - - -def _AssureWritable(self): - if self._frozen: - warnings.warn( - 'Mutating messages or containers returned by GetOptions() is' - ' deprecated and will raise an exception in a future release.', - category=FutureWarning, - stacklevel=3, - ) - return self - - -def _UnknownFields(self): - raise NotImplementedError( - 'Please use the add-on feaure ' - 'unknown_fields.UnknownFieldSet(message) in ' - 'unknown_fields.py instead.' - ) - - -def _DiscardUnknownFields(self): - self._AssureWritable() - self._unknown_fields = [] - for field, value in self.ListFields(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if _IsMapField(field): - if _IsMessageMapField(field): - for key in value: - value[key].DiscardUnknownFields() - elif field.is_repeated: - for sub_message in value: - sub_message.DiscardUnknownFields() - else: - value.DiscardUnknownFields() - - -def _SetListener(self, listener): - if listener is None: - self._listener = message_listener_mod.NullMessageListener() - else: - self._listener = listener - - -def _AddMessageMethods(message_descriptor, cls): - """Adds implementations of all Message methods to cls.""" - _AddListFieldsMethod(message_descriptor, cls) - _AddHasFieldMethod(message_descriptor, cls) - _AddClearFieldMethod(message_descriptor, cls) - if message_descriptor.is_extendable: - _AddClearExtensionMethod(cls) - _AddHasExtensionMethod(cls) - _AddEqualsMethod(message_descriptor, cls) - _AddStrMethod(message_descriptor, cls) - _AddReprMethod(message_descriptor, cls) - _AddUnicodeMethod(message_descriptor, cls) - _AddContainsMethod(message_descriptor, cls) - _AddByteSizeMethod(message_descriptor, cls) - _AddSerializeToStringMethod(message_descriptor, cls) - _AddSerializePartialToStringMethod(message_descriptor, cls) - _AddMergeFromStringMethod(message_descriptor, cls) - _AddIsInitializedMethod(message_descriptor, cls) - _AddMergeFromMethod(cls) - _AddWhichOneofMethod(message_descriptor, cls) - # Adds methods which do not depend on cls. - cls.Clear = _Clear - cls.DiscardUnknownFields = _DiscardUnknownFields - cls._SetListener = _SetListener - cls._SetFrozen = _SetFrozen - cls._AssureWritable = _AssureWritable - - -def _AddPrivateHelperMethods(message_descriptor, cls): - """Adds implementation of private helper methods to cls.""" - - def Modified(self): - """Sets the _cached_byte_size_dirty bit to true, - - and propagates this to our listener iff this was a state change. - """ - - # Note: Some callers check _cached_byte_size_dirty before calling - # _Modified() as an extra optimization. So, if this method is ever - # changed such that it does stuff even when _cached_byte_size_dirty is - # already true, the callers need to be updated. - if not self._cached_byte_size_dirty: - self._cached_byte_size_dirty = True - self._listener_for_children.dirty = True - self._is_present_in_parent = True - self._listener.Modified() - - def _UpdateOneofState(self, field): - """Sets field as the active field in its containing oneof. - - Will also delete currently active field in the oneof, if it is different - from the argument. Does not mark the message as modified. - """ - other_field = self._oneofs.setdefault(field.containing_oneof, field) - if other_field is not field: - del self._fields[other_field] - self._oneofs[field.containing_oneof] = field - - cls._Modified = Modified - cls.SetInParent = Modified - cls._UpdateOneofState = _UpdateOneofState - - -class _Listener(object): - """MessageListener implementation that a parent message registers with its - - child message. - - In order to support semantics like: - - foo.bar.baz.moo = 23 - assert foo.HasField('bar') - - ...child objects must have back references to their parents. - This helper class is at the heart of this support. - """ - - def __init__(self, parent_message): - """Args: - - parent_message: The message whose _Modified() method we should call when - we receive Modified() messages. - """ - # This listener establishes a back reference from a child (contained) object - # to its parent (containing) object. We make this a weak reference to avoid - # creating cyclic garbage when the client finishes with the 'parent' object - # in the tree. - if isinstance(parent_message, weakref.ProxyType): - self._parent_message_weakref = parent_message - else: - self._parent_message_weakref = weakref.proxy(parent_message) - - # As an optimization, we also indicate directly on the listener whether - # or not the parent message is dirty. This way we can avoid traversing - # up the tree in the common case. - self.dirty = False - - def Modified(self): - if self.dirty: - return - try: - # Propagate the signal to our parents iff this is the first field set. - self._parent_message_weakref._Modified() - except ReferenceError: - # We can get here if a client has kept a reference to a child object, - # and is now setting a field on it, but the child's parent has been - # garbage-collected. This is not an error. - pass - - -class _OneofListener(_Listener): - """Special listener implementation for setting composite oneof fields.""" - - def __init__(self, parent_message, field): - """Args: - - parent_message: The message whose _Modified() method we should call when - we receive Modified() messages. - field: The descriptor of the field being set in the parent message. - """ - super(_OneofListener, self).__init__(parent_message) - self._field = field - - def Modified(self): - """Also updates the state of the containing oneof in the parent message.""" - try: - self._parent_message_weakref._UpdateOneofState(self._field) - super(_OneofListener, self).Modified() - except ReferenceError: - pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py deleted file mode 100644 index 375e7024984..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/type_checkers.py +++ /dev/null @@ -1,465 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Provides type checking routines. - -This module defines type checking utilities in the forms of dictionaries: - -VALUE_CHECKERS: A dictionary of field types and a value validation object. -TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing - function. -TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization - function. -FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their - corresponding wire types. -TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization - function. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import numbers -import struct -import warnings - -from opentelemetry.agent._vendor.google.protobuf import descriptor -from opentelemetry.agent._vendor.google.protobuf.internal import decoder -from opentelemetry.agent._vendor.google.protobuf.internal import encoder -from opentelemetry.agent._vendor.google.protobuf.internal import wire_format - -_FieldDescriptor = descriptor.FieldDescriptor - - -def TruncateToFourByteFloat(original): - return struct.unpack(' _FLOAT_MAX: - if converted_value <= _MAX_FLOAT_AS_DOUBLE_ROUNDED: - return _FLOAT_MAX - return _INF - if converted_value < _FLOAT_MIN: - if converted_value >= -_MAX_FLOAT_AS_DOUBLE_ROUNDED: - return _FLOAT_MIN - return _NEG_INF - - return TruncateToFourByteFloat(converted_value) - - -# Type-checkers for all scalar CPPTYPEs. -_VALUE_CHECKERS = { - _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), - _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), - _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), - _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), - _FieldDescriptor.CPPTYPE_DOUBLE: DoubleValueChecker(), - _FieldDescriptor.CPPTYPE_FLOAT: FloatValueChecker(), - _FieldDescriptor.CPPTYPE_BOOL: BoolValueChecker(), - _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes), -} - -# Map from field type to a function F, such that F(field_num, value) -# gives the total byte size for a value of the given type. This -# byte size includes tag information and any other additional space -# associated with serializing "value". -TYPE_TO_BYTE_SIZE_FN = { - _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, - _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, - _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, - _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, - _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, - _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, - _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, - _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, - _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, - _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, - _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, - _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, - _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, - _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, - _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, - _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, - _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, - _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize, -} - -# Maps from field types to encoder constructors. -TYPE_TO_ENCODER = { - _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder, - _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder, - _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder, - _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder, - _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder, - _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder, - _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder, - _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder, - _FieldDescriptor.TYPE_STRING: encoder.StringEncoder, - _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder, - _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder, - _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder, - _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder, - _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder, - _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder, - _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder, - _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder, - _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder, -} - -# Maps from field types to sizer constructors. -TYPE_TO_SIZER = { - _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer, - _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer, - _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer, - _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer, - _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer, - _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer, - _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer, - _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer, - _FieldDescriptor.TYPE_STRING: encoder.StringSizer, - _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer, - _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer, - _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer, - _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer, - _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer, - _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer, - _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer, - _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer, - _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer, -} - -# Maps from field type to a decoder constructor. -TYPE_TO_DECODER = { - _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder, - _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder, - _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder, - _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder, - _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder, - _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder, - _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder, - _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder, - _FieldDescriptor.TYPE_STRING: decoder.StringDecoder, - _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder, - _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder, - _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder, - _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder, - _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder, - _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder, - _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder, - _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder, - _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder, -} - -# Maps from field type to expected wiretype. -FIELD_TYPE_TO_WIRE_TYPE = { - _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_STRING: wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, - _FieldDescriptor.TYPE_MESSAGE: wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_BYTES: wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py deleted file mode 100644 index 2b5957c27b4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/well_known_types.py +++ /dev/null @@ -1,707 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains well known classes. - -This files defines well known classes which need extra maintenance including: - - Any - - Duration - - FieldMask - - Struct - - Timestamp -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - -import calendar -import collections.abc -import datetime -from typing import Union -import warnings -from opentelemetry.agent._vendor.google.protobuf.internal import field_mask - -FieldMask = field_mask.FieldMask - -_TIMESTAMPFORMAT = '%Y-%m-%dT%H:%M:%S' -_NANOS_PER_SECOND = 1000000000 -_NANOS_PER_MILLISECOND = 1000000 -_NANOS_PER_MICROSECOND = 1000 -_MILLIS_PER_SECOND = 1000 -_MICROS_PER_SECOND = 1000000 -_SECONDS_PER_DAY = 24 * 3600 -_DURATION_SECONDS_MAX = 315576000000 -_TIMESTAMP_SECONDS_MIN = -62135596800 -_TIMESTAMP_SECONDS_MAX = 253402300799 - -_EPOCH_DATETIME_NAIVE = datetime.datetime(1970, 1, 1, tzinfo=None) -_EPOCH_DATETIME_AWARE = _EPOCH_DATETIME_NAIVE.replace( - tzinfo=datetime.timezone.utc -) - - -class Any(object): - """Class for Any Message type.""" - - __slots__ = () - - def Pack( - self, msg, type_url_prefix='type.googleapis.com/', deterministic=None - ): - """Packs the specified message into current Any message.""" - if len(type_url_prefix) < 1 or type_url_prefix[-1] != '/': - self.type_url = '%s/%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) - else: - self.type_url = '%s%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) - self.value = msg.SerializeToString(deterministic=deterministic) - - def Unpack(self, msg): - """Unpacks the current Any message into specified message.""" - descriptor = msg.DESCRIPTOR - if not self.Is(descriptor): - return False - msg.ParseFromString(self.value) - return True - - def TypeName(self): - """Returns the protobuf type name of the inner message.""" - # Only last part is to be used: b/25630112 - return self.type_url.rpartition('/')[2] - - def Is(self, descriptor): - """Checks if this Any represents the given protobuf type.""" - return '/' in self.type_url and self.TypeName() == descriptor.full_name - - -class Timestamp(object): - """Class for Timestamp message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts Timestamp to RFC 3339 date string format. - - Returns: - A string converted from timestamp. The string is always Z-normalized - and uses 3, 6 or 9 fractional digits as required to represent the - exact time. Example of the return format: '1972-01-01T10:00:20.021Z' - """ - _CheckTimestampValid(self.seconds, self.nanos) - nanos = self.nanos - seconds = self.seconds % _SECONDS_PER_DAY - days = (self.seconds - seconds) // _SECONDS_PER_DAY - dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(days, seconds) - - result = dt.isoformat() - if (nanos % 1e9) == 0: - # If there are 0 fractional digits, the fractional - # point '.' should be omitted when serializing. - return result + 'Z' - if (nanos % 1e6) == 0: - # Serialize 3 fractional digits. - return result + '.%03dZ' % (nanos / 1e6) - if (nanos % 1e3) == 0: - # Serialize 6 fractional digits. - return result + '.%06dZ' % (nanos / 1e3) - # Serialize 9 fractional digits. - return result + '.%09dZ' % nanos - - def FromJsonString(self, value): - """Parse a RFC 3339 date string format to Timestamp. - - Args: - value: A date string. Any fractional digits (or none) and any offset are - accepted as long as they fit into nano-seconds precision. Example of - accepted format: '1972-01-01T10:00:20.021-05:00' - - Raises: - ValueError: On parsing problems. - """ - if not isinstance(value, str): - raise ValueError('Timestamp JSON value not a string: {!r}'.format(value)) - timezone_offset = value.find('Z') - if timezone_offset == -1: - timezone_offset = value.find('+') - if timezone_offset == -1: - timezone_offset = value.rfind('-') - if timezone_offset == -1: - raise ValueError( - 'Failed to parse timestamp: missing valid timezone offset.' - ) - time_value = value[0:timezone_offset] - # Parse datetime and nanos. - point_position = time_value.find('.') - if point_position == -1: - second_value = time_value - nano_value = '' - else: - second_value = time_value[:point_position] - nano_value = time_value[point_position + 1 :] - if 't' in second_value: - raise ValueError( - "time data '{0}' does not match format '%Y-%m-%dT%H:%M:%S', " - "lowercase 't' is not accepted".format(second_value) - ) - date_object = datetime.datetime.strptime(second_value, _TIMESTAMPFORMAT) - td = date_object - datetime.datetime(1970, 1, 1) - seconds = td.seconds + td.days * _SECONDS_PER_DAY - if len(nano_value) > 9: - raise ValueError( - 'Failed to parse Timestamp: nanos {0} more than ' - '9 fractional digits.'.format(nano_value) - ) - if nano_value: - nanos = round(float('0.' + nano_value) * 1e9) - else: - nanos = 0 - # Parse timezone offsets. - if value[timezone_offset] == 'Z': - if len(value) != timezone_offset + 1: - raise ValueError( - 'Failed to parse timestamp: invalid trailing data {0}.'.format( - value - ) - ) - else: - timezone = value[timezone_offset:] - pos = timezone.find(':') - if pos == -1: - raise ValueError('Invalid timezone offset value: {0}.'.format(timezone)) - if timezone[0] == '+': - seconds -= (int(timezone[1:pos]) * 60 + int(timezone[pos + 1 :])) * 60 - else: - seconds += (int(timezone[1:pos]) * 60 + int(timezone[pos + 1 :])) * 60 - # Set seconds and nanos - _CheckTimestampValid(seconds, nanos) - self.seconds = int(seconds) - self.nanos = int(nanos) - - def GetCurrentTime(self): - """Get the current UTC into Timestamp.""" - self.FromDatetime(datetime.datetime.now(tz=datetime.timezone.utc)) - - def ToNanoseconds(self): - """Converts Timestamp to nanoseconds since epoch.""" - _CheckTimestampValid(self.seconds, self.nanos) - return self.seconds * _NANOS_PER_SECOND + self.nanos - - def ToMicroseconds(self): - """Converts Timestamp to microseconds since epoch.""" - _CheckTimestampValid(self.seconds, self.nanos) - return ( - self.seconds * _MICROS_PER_SECOND + self.nanos // _NANOS_PER_MICROSECOND - ) - - def ToMilliseconds(self): - """Converts Timestamp to milliseconds since epoch.""" - _CheckTimestampValid(self.seconds, self.nanos) - return ( - self.seconds * _MILLIS_PER_SECOND + self.nanos // _NANOS_PER_MILLISECOND - ) - - def ToSeconds(self): - """Converts Timestamp to seconds since epoch.""" - _CheckTimestampValid(self.seconds, self.nanos) - return self.seconds - - def FromNanoseconds(self, nanos): - """Converts nanoseconds since epoch to Timestamp.""" - seconds = nanos // _NANOS_PER_SECOND - nanos = nanos % _NANOS_PER_SECOND - _CheckTimestampValid(seconds, nanos) - self.seconds = seconds - self.nanos = nanos - - def FromMicroseconds(self, micros): - """Converts microseconds since epoch to Timestamp.""" - seconds = micros // _MICROS_PER_SECOND - nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND - _CheckTimestampValid(seconds, nanos) - self.seconds = seconds - self.nanos = nanos - - def FromMilliseconds(self, millis): - """Converts milliseconds since epoch to Timestamp.""" - seconds = millis // _MILLIS_PER_SECOND - nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND - _CheckTimestampValid(seconds, nanos) - self.seconds = seconds - self.nanos = nanos - - def FromSeconds(self, seconds): - """Converts seconds since epoch to Timestamp.""" - _CheckTimestampValid(seconds, 0) - self.seconds = seconds - self.nanos = 0 - - def ToDatetime(self, tzinfo=None): - """Converts Timestamp to a datetime. - - Args: - tzinfo: A datetime.tzinfo subclass; defaults to None. - - Returns: - If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone - information, i.e. not aware that it's UTC). - - Otherwise, returns a timezone-aware datetime in the input timezone. - """ - # Using datetime.fromtimestamp for this would avoid constructing an extra - # timedelta object and possibly an extra datetime. Unfortunately, that has - # the disadvantage of not handling the full precision (on all platforms, see - # https://github.com/python/cpython/issues/109849) or full range (on some - # platforms, see https://github.com/python/cpython/issues/110042) of - # datetime. - _CheckTimestampValid(self.seconds, self.nanos) - delta = datetime.timedelta( - seconds=self.seconds, - microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND), - ) - if tzinfo is None: - return _EPOCH_DATETIME_NAIVE + delta - else: - # Note the tz conversion has to come after the timedelta arithmetic. - return (_EPOCH_DATETIME_AWARE + delta).astimezone(tzinfo) - - def FromDatetime(self, dt): - """Converts datetime to Timestamp. - - Args: - dt: A datetime. If it's timezone-naive, it's assumed to be in UTC. - """ - # Using this guide: http://wiki.python.org/moin/WorkingWithTime - # And this conversion guide: http://docs.python.org/library/time.html - - # Turn the date parameter into a tuple (struct_time) that can then be - # manipulated into a long value of seconds. During the conversion from - # struct_time to long, the source date in UTC, and so it follows that the - # correct transformation is calendar.timegm() - if type(dt).__name__ != 'datetime' and not isinstance( - dt, datetime.datetime - ): - raise TypeError( - 'Fail to convert to Timestamp. Expected a datetime object ' - 'got {0}'.format(type(dt).__name__) - ) - try: - seconds = calendar.timegm(dt.utctimetuple()) - nanos = dt.microsecond * _NANOS_PER_MICROSECOND - except AttributeError as e: - raise AttributeError( - 'Fail to convert to Timestamp. Expected a datetime like ' - 'object got {0} : {1}'.format(type(dt).__name__, e) - ) from e - _CheckTimestampValid(seconds, nanos) - self.seconds = seconds - self.nanos = nanos - - def _internal_assign(self, dt): - self.FromDatetime(dt) - - def __add__(self, value) -> datetime.datetime: - if isinstance(value, Duration): - return self.ToDatetime() + value.ToTimedelta() - return self.ToDatetime() + value - - __radd__ = __add__ - - def __sub__(self, value) -> Union[datetime.datetime, datetime.timedelta]: - if isinstance(value, Timestamp): - return self.ToDatetime() - value.ToDatetime() - elif isinstance(value, Duration): - return self.ToDatetime() - value.ToTimedelta() - return self.ToDatetime() - value - - def __rsub__(self, dt) -> datetime.timedelta: - return dt - self.ToDatetime() - - -def _CheckTimestampValid(seconds, nanos): - if seconds < _TIMESTAMP_SECONDS_MIN or seconds > _TIMESTAMP_SECONDS_MAX: - raise ValueError( - 'Timestamp is not valid: Seconds {0} must be in range ' - '[-62135596800, 253402300799].'.format(seconds)) - if nanos < 0 or nanos >= _NANOS_PER_SECOND: - raise ValueError( - 'Timestamp is not valid: Nanos {} must be in a range ' - '[0, 999999].'.format(nanos) - ) - - -class Duration(object): - """Class for Duration message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts Duration to string format. - - Returns: - A string converted from self. The string format will contains - 3, 6, or 9 fractional digits depending on the precision required to - represent the exact Duration value. For example: "1s", "1.010s", - "1.000000100s", "-3.100s" - """ - _CheckDurationValid(self.seconds, self.nanos) - if self.seconds < 0 or self.nanos < 0: - result = '-' - seconds = -self.seconds + int((0 - self.nanos) // 1e9) - nanos = (0 - self.nanos) % 1e9 - else: - result = '' - seconds = self.seconds + int(self.nanos // 1e9) - nanos = self.nanos % 1e9 - result += '%d' % seconds - if (nanos % 1e9) == 0: - # If there are 0 fractional digits, the fractional - # point '.' should be omitted when serializing. - return result + 's' - if (nanos % 1e6) == 0: - # Serialize 3 fractional digits. - return result + '.%03ds' % (nanos / 1e6) - if (nanos % 1e3) == 0: - # Serialize 6 fractional digits. - return result + '.%06ds' % (nanos / 1e3) - # Serialize 9 fractional digits. - return result + '.%09ds' % nanos - - def FromJsonString(self, value): - """Converts a string to Duration. - - Args: - value: A string to be converted. The string must end with 's'. Any - fractional digits (or none) are accepted as long as they fit into - precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s - - Raises: - ValueError: On parsing problems. - """ - if not isinstance(value, str): - raise ValueError('Duration JSON value not a string: {!r}'.format(value)) - if len(value) < 1 or value[-1] != 's': - raise ValueError('Duration must end with letter "s": {0}.'.format(value)) - try: - pos = value.find('.') - if pos == -1: - seconds = int(value[:-1]) - nanos = 0 - else: - seconds = int(value[:pos]) - if value[0] == '-': - nanos = int(round(float('-0{0}'.format(value[pos:-1])) * 1e9)) - else: - nanos = int(round(float('0{0}'.format(value[pos:-1])) * 1e9)) - _CheckDurationValid(seconds, nanos) - self.seconds = seconds - self.nanos = nanos - except ValueError as e: - raise ValueError("Couldn't parse duration: {0} : {1}.".format(value, e)) - - def ToNanoseconds(self): - """Converts a Duration to nanoseconds.""" - return self.seconds * _NANOS_PER_SECOND + self.nanos - - def ToMicroseconds(self): - """Converts a Duration to microseconds.""" - micros = _RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND) - return self.seconds * _MICROS_PER_SECOND + micros - - def ToMilliseconds(self): - """Converts a Duration to milliseconds.""" - millis = _RoundTowardZero(self.nanos, _NANOS_PER_MILLISECOND) - return self.seconds * _MILLIS_PER_SECOND + millis - - def ToSeconds(self): - """Converts a Duration to seconds.""" - return self.seconds - - def FromNanoseconds(self, nanos): - """Converts nanoseconds to Duration.""" - self._NormalizeDuration( - nanos // _NANOS_PER_SECOND, nanos % _NANOS_PER_SECOND - ) - - def FromMicroseconds(self, micros): - """Converts microseconds to Duration.""" - self._NormalizeDuration( - micros // _MICROS_PER_SECOND, - (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND, - ) - - def FromMilliseconds(self, millis): - """Converts milliseconds to Duration.""" - self._NormalizeDuration( - millis // _MILLIS_PER_SECOND, - (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND, - ) - - def FromSeconds(self, seconds): - """Converts seconds to Duration.""" - self.seconds = seconds - self.nanos = 0 - - def ToTimedelta(self) -> datetime.timedelta: - """Converts Duration to timedelta.""" - return datetime.timedelta( - seconds=self.seconds, - microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND), - ) - - def FromTimedelta(self, td): - """Converts timedelta to Duration.""" - if type(td).__name__ != 'timedelta' and not isinstance( - td, datetime.timedelta - ): - raise TypeError( - 'Fail to convert to Duration. Expected a timedelta object ' - 'got {0}'.format(type(td).__name__) - ) - try: - self._NormalizeDuration( - td.seconds + td.days * _SECONDS_PER_DAY, - td.microseconds * _NANOS_PER_MICROSECOND, - ) - except AttributeError as e: - raise AttributeError( - 'Fail to convert to Duration. Expected a timedelta like ' - 'object got {0}: {1}'.format(type(td).__name__, e) - ) from e - - def _internal_assign(self, td): - self.FromTimedelta(td) - - def _NormalizeDuration(self, seconds, nanos): - """Set Duration by seconds and nanos.""" - # Force nanos to be negative if the duration is negative. - if seconds < 0 and nanos > 0: - seconds += 1 - nanos -= _NANOS_PER_SECOND - self.seconds = seconds - self.nanos = nanos - - def __add__(self, value) -> Union[datetime.datetime, datetime.timedelta]: - if isinstance(value, Timestamp): - return self.ToTimedelta() + value.ToDatetime() - return self.ToTimedelta() + value - - __radd__ = __add__ - - def __sub__(self, value) -> datetime.timedelta: - return self.ToTimedelta() - value - - def __rsub__(self, value) -> Union[datetime.datetime, datetime.timedelta]: - return value - self.ToTimedelta() - - -def _CheckDurationValid(seconds, nanos): - if seconds < -_DURATION_SECONDS_MAX or seconds > _DURATION_SECONDS_MAX: - raise ValueError( - 'Duration is not valid: Seconds {0} must be in range ' - '[-315576000000, 315576000000].'.format(seconds) - ) - if nanos <= -_NANOS_PER_SECOND or nanos >= _NANOS_PER_SECOND: - raise ValueError( - 'Duration is not valid: Nanos {0} must be in range ' - '[-999999999, 999999999].'.format(nanos) - ) - if (nanos < 0 and seconds > 0) or (nanos > 0 and seconds < 0): - raise ValueError('Duration is not valid: Sign mismatch.') - - -def _RoundTowardZero(value, divider): - """Truncates the remainder part after division.""" - # For some languages, the sign of the remainder is implementation - # dependent if any of the operands is negative. Here we enforce - # "rounded toward zero" semantics. For example, for (-5) / 2 an - # implementation may give -3 as the result with the remainder being - # 1. This function ensures we always return -2 (closer to zero). - result = value // divider - remainder = value % divider - if result < 0 and remainder > 0: - return result + 1 - else: - return result - - -def _SetStructValue(struct_value, value): - if value is None: - struct_value.null_value = 0 - elif isinstance(value, bool): - # Note: this check must come before the number check because in Python - # True and False are also considered numbers. - struct_value.bool_value = value - elif isinstance(value, str): - struct_value.string_value = value - elif isinstance(value, (int, float)): - struct_value.number_value = value - elif isinstance(value, (dict, Struct)): - struct_value.struct_value.Clear() - struct_value.struct_value.update(value) - elif isinstance(value, (list, tuple, ListValue)): - struct_value.list_value.Clear() - struct_value.list_value.extend(value) - else: - raise ValueError('Unexpected type') - - -def _GetStructValue(struct_value): - which = struct_value.WhichOneof('kind') - if which == 'struct_value': - return struct_value.struct_value - elif which == 'null_value': - return None - elif which == 'number_value': - return struct_value.number_value - elif which == 'string_value': - return struct_value.string_value - elif which == 'bool_value': - return struct_value.bool_value - elif which == 'list_value': - return struct_value.list_value - elif which is None: - raise ValueError('Value not set') - - -class Struct(object): - """Class for Struct message type.""" - - __slots__ = () - - def __getitem__(self, key): - return _GetStructValue(self.fields[key]) - - def __setitem__(self, key, value): - _SetStructValue(self.fields[key], value) - - def __delitem__(self, key): - del self.fields[key] - - def __len__(self): - return len(self.fields) - - def __iter__(self): - return iter(self.fields) - - def _internal_assign(self, dictionary): - self.Clear() - self.update(dictionary) - - def _internal_compare(self, other): - size = len(self) - if size != len(other): - return False - for key, value in self.items(): - if key not in other: - return False - if isinstance(other[key], (dict, list)): - if not value._internal_compare(other[key]): - return False - elif value != other[key]: - return False - return True - - def keys(self): # pylint: disable=invalid-name - return self.fields.keys() - - def values(self): # pylint: disable=invalid-name - return [self[key] for key in self] - - def items(self): # pylint: disable=invalid-name - return [(key, self[key]) for key in self] - - def get_or_create_list(self, key): - """Returns a list for this key, creating if it didn't exist already.""" - if not self.fields[key].HasField('list_value'): - # Clear will mark list_value modified which will indeed create a list. - self.fields[key].list_value.Clear() - return self.fields[key].list_value - - def get_or_create_struct(self, key): - """Returns a struct for this key, creating if it didn't exist already.""" - if not self.fields[key].HasField('struct_value'): - # Clear will mark struct_value modified which will indeed create a struct. - self.fields[key].struct_value.Clear() - return self.fields[key].struct_value - - def update(self, dictionary): # pylint: disable=invalid-name - for key, value in dictionary.items(): - _SetStructValue(self.fields[key], value) - - -collections.abc.MutableMapping.register(Struct) - - -class ListValue(object): - """Class for ListValue message type.""" - - __slots__ = () - - def __len__(self): - return len(self.values) - - def append(self, value): - _SetStructValue(self.values.add(), value) - - def extend(self, elem_seq): - for value in elem_seq: - self.append(value) - - def __getitem__(self, index): - """Retrieves item by the specified index.""" - return _GetStructValue(self.values.__getitem__(index)) - - def __setitem__(self, index, value): - _SetStructValue(self.values.__getitem__(index), value) - - def __delitem__(self, key): - del self.values[key] - - def _internal_assign(self, elem_seq): - self.Clear() - self.extend(elem_seq) - - def _internal_compare(self, other): - size = len(self) - if size != len(other): - return False - for i in range(size): - if isinstance(other[i], (dict, list)): - if not self[i]._internal_compare(other[i]): - return False - elif self[i] != other[i]: - return False - return True - - def items(self): - for i in range(len(self)): - yield self[i] - - def add_struct(self): - """Appends and returns a struct value as the next value in the list.""" - struct_value = self.values.add().struct_value - # Clear will mark struct_value modified which will indeed create a struct. - struct_value.Clear() - return struct_value - - def add_list(self): - """Appends and returns a list value as the next value in the list.""" - list_value = self.values.add().list_value - # Clear will mark list_value modified which will indeed create a list. - list_value.Clear() - return list_value - - -collections.abc.MutableSequence.register(ListValue) - -# LINT.IfChange(wktbases) -WKTBASES = { - 'google.protobuf.Any': Any, - 'google.protobuf.Duration': Duration, - 'google.protobuf.FieldMask': FieldMask, - 'google.protobuf.ListValue': ListValue, - 'google.protobuf.Struct': Struct, - 'google.protobuf.Timestamp': Timestamp, -} -# LINT.ThenChange(//depot/google.protobuf/compiler/python/pyi_generator.cc:wktbases) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py deleted file mode 100644 index 4f177f45cb5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/internal/wire_format.py +++ /dev/null @@ -1,255 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Constants and static functions to support protocol buffer wire format.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import struct -from opentelemetry.agent._vendor.google.protobuf import descriptor -from opentelemetry.agent._vendor.google.protobuf import message - -TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. -TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 - -# These numbers identify the wire type of a protocol buffer value. -# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded -# tag-and-type to store one of these WIRETYPE_* constants. -# These values must match WireType enum in //google/protobuf/wire_format.h. -WIRETYPE_VARINT = 0 -WIRETYPE_FIXED64 = 1 -WIRETYPE_LENGTH_DELIMITED = 2 -WIRETYPE_START_GROUP = 3 -WIRETYPE_END_GROUP = 4 -WIRETYPE_FIXED32 = 5 -_WIRETYPE_MAX = 5 - -# Bounds for various integer types. -INT32_MAX = int((1 << 31) - 1) -INT32_MIN = int(-(1 << 31)) -UINT32_MAX = (1 << 32) - 1 - -INT64_MAX = (1 << 63) - 1 -INT64_MIN = -(1 << 63) -UINT64_MAX = (1 << 64) - 1 - -# "struct" format strings that will encode/decode the specified formats. -FORMAT_UINT32_LITTLE_ENDIAN = '> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK) - - -def ZigZagEncode(value): - """ZigZag Transform: Encodes signed integers so that they can be - - effectively used with varint encoding. See wire_format.h for - more details. - """ - if value >= 0: - return value << 1 - return (value << 1) ^ (~0) - - -def ZigZagDecode(value): - """Inverse of ZigZagEncode().""" - if not value & 0x1: - return value >> 1 - return (value >> 1) ^ (~0) - - -# The *ByteSize() functions below return the number of bytes required to -# serialize "field number + type" information and then serialize the value. - - -def Int32ByteSize(field_number, int32): - return Int64ByteSize(field_number, int32) - - -def Int32ByteSizeNoTag(int32): - return _VarUInt64ByteSizeNoTag(0xFFFFFFFFFFFFFFFF & int32) - - -def Int64ByteSize(field_number, int64): - # Have to convert to uint before calling UInt64ByteSize(). - return UInt64ByteSize(field_number, 0xFFFFFFFFFFFFFFFF & int64) - - -def UInt32ByteSize(field_number, uint32): - return UInt64ByteSize(field_number, uint32) - - -def UInt64ByteSize(field_number, uint64): - return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) - - -def SInt32ByteSize(field_number, int32): - return UInt32ByteSize(field_number, ZigZagEncode(int32)) - - -def SInt64ByteSize(field_number, int64): - return UInt64ByteSize(field_number, ZigZagEncode(int64)) - - -def Fixed32ByteSize(field_number, fixed32): - return TagByteSize(field_number) + 4 - - -def Fixed64ByteSize(field_number, fixed64): - return TagByteSize(field_number) + 8 - - -def SFixed32ByteSize(field_number, sfixed32): - return TagByteSize(field_number) + 4 - - -def SFixed64ByteSize(field_number, sfixed64): - return TagByteSize(field_number) + 8 - - -def FloatByteSize(field_number, flt): - return TagByteSize(field_number) + 4 - - -def DoubleByteSize(field_number, double): - return TagByteSize(field_number) + 8 - - -def BoolByteSize(field_number, b): - return TagByteSize(field_number) + 1 - - -def EnumByteSize(field_number, enum): - return UInt32ByteSize(field_number, enum) - - -def StringByteSize(field_number, string): - return BytesByteSize(field_number, string.encode('utf-8')) - - -def BytesByteSize(field_number, b): - return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(len(b)) + len(b) - - -def GroupByteSize(field_number, message): - return ( - 2 * TagByteSize(field_number) + message.ByteSize() # START and END group. - ) - - -def MessageByteSize(field_number, message): - return ( - TagByteSize(field_number) - + _VarUInt64ByteSizeNoTag(message.ByteSize()) - + message.ByteSize() - ) - - -def MessageSetItemByteSize(field_number, msg): - # First compute the sizes of the tags. - # There are 2 tags for the beginning and ending of the repeated group, that - # is field number 1, one with field number 2 (type_id) and one with field - # number 3 (message). - total_size = 2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3) - - # Add the number of bytes for type_id. - total_size += _VarUInt64ByteSizeNoTag(field_number) - - message_size = msg.ByteSize() - - # The number of bytes for encoding the length of the message. - total_size += _VarUInt64ByteSizeNoTag(message_size) - - # The size of the message. - total_size += message_size - return total_size - - -def TagByteSize(field_number): - """Returns the bytes required to serialize a tag with this field number.""" - # Just pass in type 0, since the type won't affect the tag+type size. - return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) - - -# Private helper function for the *ByteSize() functions above. - - -def _VarUInt64ByteSizeNoTag(uint64): - """Returns the number of bytes required to serialize a single varint - - using boundary value comparisons. (unrolled loop optimization -WPierce) - uint64 must be unsigned. - """ - if uint64 <= 0x7F: - return 1 - if uint64 <= 0x3FFF: - return 2 - if uint64 <= 0x1FFFFF: - return 3 - if uint64 <= 0xFFFFFFF: - return 4 - if uint64 <= 0x7FFFFFFFF: - return 5 - if uint64 <= 0x3FFFFFFFFFF: - return 6 - if uint64 <= 0x1FFFFFFFFFFFF: - return 7 - if uint64 <= 0xFFFFFFFFFFFFFF: - return 8 - if uint64 <= 0x7FFFFFFFFFFFFFFF: - return 9 - if uint64 > UINT64_MAX: - raise message.EncodeError('Value out of range: %d' % uint64) - return 10 - - -NON_PACKABLE_TYPES = ( - descriptor.FieldDescriptor.TYPE_STRING, - descriptor.FieldDescriptor.TYPE_GROUP, - descriptor.FieldDescriptor.TYPE_MESSAGE, - descriptor.FieldDescriptor.TYPE_BYTES, -) - - -def IsTypePackable(field_type): - """Return true iff packable = true is valid for fields of this type. - - Args: - field_type: a FieldDescriptor::Type value. - - Returns: - True iff fields of this type are packable. - """ - return field_type not in NON_PACKABLE_TYPES diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py deleted file mode 100644 index 83e5f6c94d4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_enumvalue_options_pb2.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/json_enumvalue_options.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/json_enumvalue_options.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,google/protobuf/json_enumvalue_options.proto\x12\x0cpb.enumvalue\x1a google/protobuf/descriptor.proto\"0\n\x14JsonEnumValueOptions\x12\x16\n\x06string\x18\x01 \x01(\tR\x06stringX\x01:b\n\x04json\x12!.google.protobuf.EnumValueOptions\x18\xe6\x07 \x01(\x0b\x32\".pb.enumvalue.JsonEnumValueOptionsB\x06\xb2\x01\x03\x08\xea\x07R\x04jsonB\x1a\n\x18\x63om.google.protobuf.utilb\x08\x65\x64itionsp\xe9\x07') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.json_enumvalue_options_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\030com.google.protobuf.util' - _globals['json']._loaded_options = None - _globals['json']._serialized_options = b'\262\001\003\010\352\007' - _globals['_JSONENUMVALUEOPTIONS']._serialized_start=96 - _globals['_JSONENUMVALUEOPTIONS']._serialized_end=144 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py deleted file mode 100644 index 72b112a9dde..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_format.py +++ /dev/null @@ -1,1247 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains routines for printing protocol messages in JSON format. - -Simple usage example: - - # Create a proto object and serialize it to a json format string. - message = my_proto_pb2.MyMessage(foo='bar') - json_string = json_format.MessageToJson(message) - - # Parse a json format string to proto object. - message = json_format.Parse(json_string, my_proto_pb2.MyMessage()) -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - -import base64 -from collections import OrderedDict -import json -import math -from operator import methodcaller -import re - -from opentelemetry.agent._vendor.google.protobuf import descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import message_factory -from opentelemetry.agent._vendor.google.protobuf import symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers - -_INT_TYPES = frozenset([ - descriptor.FieldDescriptor.CPPTYPE_INT32, - descriptor.FieldDescriptor.CPPTYPE_UINT32, - descriptor.FieldDescriptor.CPPTYPE_INT64, - descriptor.FieldDescriptor.CPPTYPE_UINT64, -]) -_INT64_TYPES = frozenset([ - descriptor.FieldDescriptor.CPPTYPE_INT64, - descriptor.FieldDescriptor.CPPTYPE_UINT64, -]) -_FLOAT_TYPES = frozenset([ - descriptor.FieldDescriptor.CPPTYPE_FLOAT, - descriptor.FieldDescriptor.CPPTYPE_DOUBLE, -]) -_INFINITY = 'Infinity' -_NEG_INFINITY = '-Infinity' -_NAN = 'NaN' - -_UNPAIRED_SURROGATE_PATTERN = re.compile( - '[\ud800-\udbff](?![\udc00-\udfff])|(? self.max_recursion_depth: - raise ParseError( - 'Message too deep. Max recursion depth is {0}'.format( - self.max_recursion_depth - ) - ) - message_descriptor = message.DESCRIPTOR - full_name = message_descriptor.full_name - if not path: - path = message_descriptor.name - if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value, message, path) - elif full_name in _WKTJSONMETHODS: - methodcaller(_WKTJSONMETHODS[full_name][1], value, message, path)(self) - else: - self._ConvertFieldValuePair(value, message, path) - self.recursion_depth -= 1 - - def _ConvertFieldValuePair(self, js, message, path): - """Convert field value pairs into regular message. - - Args: - js: A JSON object to convert the field value pairs. - message: A regular protocol message to record the data. - path: parent path to log parse error info. - - Raises: - ParseError: In case of problems converting. - """ - names = [] - message_descriptor = message.DESCRIPTOR - fields_by_json_name = dict( - (f.json_name, f) for f in message_descriptor.fields - ) - - def _ClearFieldOrExtension(message, field): - if field.is_extension: - message.ClearExtension(field) - else: - message.ClearField(field.name) - - def _GetFieldOrExtension(message, field): - if field.is_extension: - return message.Extensions[field] - else: - return getattr(message, field.name) - - def _SetFieldOrExtension(message, field, value): - if field.is_extension: - message.Extensions[field] = value - else: - setattr(message, field.name, value) - - for name in js: - try: - field = fields_by_json_name.get(name, None) - if not field: - field = message_descriptor.fields_by_name.get(name, None) - if not field and _VALID_EXTENSION_NAME.match(name): - if not message_descriptor.is_extendable: - raise ParseError( - 'Message type {0} does not have extensions at {1}'.format( - message_descriptor.full_name, path - ) - ) - identifier = name[1:-1] # strip [] brackets - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(identifier) - # pylint: enable=protected-access - if not field: - # Try looking for extension by the message type name, dropping the - # field name following the final . separator in full_name. - identifier = '.'.join(identifier.split('.')[:-1]) - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(identifier) - # pylint: enable=protected-access - if not field: - if self.ignore_unknown_fields: - continue - raise ParseError( - ( - 'Message type "{0}" has no field named "{1}" at "{2}".\n' - ' Available Fields(except extensions): "{3}"' - ).format( - message_descriptor.full_name, - name, - path, - [f.json_name for f in message_descriptor.fields], - ) - ) - if name in names: - raise ParseError( - 'Message type "{0}" should not have multiple ' - '"{1}" fields at "{2}".'.format( - message.DESCRIPTOR.full_name, name, path - ) - ) - names.append(name) - value = js[name] - # Check no other oneof field is parsed. - if field.containing_oneof is not None and value is not None: - oneof_name = field.containing_oneof.name - if oneof_name in names: - raise ParseError( - 'Message type "{0}" should not have multiple ' - '"{1}" oneof fields at "{2}".'.format( - message.DESCRIPTOR.full_name, oneof_name, path - ) - ) - names.append(oneof_name) - - if value is None: - if ( - field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE - and field.message_type.full_name == 'google.protobuf.Value' - ): - sub_message = _GetFieldOrExtension(message, field) - sub_message.null_value = 0 - elif ( - field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM - and field.enum_type.full_name == 'google.protobuf.NullValue' - ): - _SetFieldOrExtension(message, field, 0) - else: - _ClearFieldOrExtension(message, field) - continue - - # Parse field value. - if _IsMapEntry(field): - _ClearFieldOrExtension(message, field) - self._ConvertMapFieldValue( - value, message, field, '{0}.{1}'.format(path, name) - ) - elif field.is_repeated: - _ClearFieldOrExtension(message, field) - if not isinstance(value, _LIST_LIKE): - raise ParseError( - 'repeated field {0} must be in [] which is {1} at {2}'.format( - name, value, path - ) - ) - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - # Repeated message field. - for index, item in enumerate(value): - sub_message = _GetFieldOrExtension(message, field).add() - # None is a null_value in Value. - if ( - item is None - and sub_message.DESCRIPTOR.full_name - != 'google.protobuf.Value' - ): - raise ParseError( - 'null is not allowed to be used as an element' - ' in a repeated field at {0}.{1}[{2}]'.format( - path, name, index - ) - ) - self.ConvertMessage( - item, sub_message, '{0}.{1}[{2}]'.format(path, name, index) - ) - else: - # Repeated scalar field. - for index, item in enumerate(value): - if item is None: - raise ParseError( - 'null is not allowed to be used as an element' - ' in a repeated field at {0}.{1}[{2}]'.format( - path, name, index - ) - ) - self._ConvertAndAppendScalar( - message, field, item, '{0}.{1}[{2}]'.format(path, name, index) - ) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - sub_message = _GetFieldOrExtension(message, field) - sub_message.SetInParent() - self.ConvertMessage(value, sub_message, '{0}.{1}'.format(path, name)) - else: - self._ConvertAndSetScalar( - message, field, value, '{0}.{1}'.format(path, name) - ) - except ParseError as e: - if field and field.containing_oneof is None: - raise ParseError( - 'Failed to parse {0} field: {1}.'.format(name, e) - ) from e - else: - raise ParseError(str(e)) from e - except ValueError as e: - raise ParseError( - 'Failed to parse {0} field: {1}.'.format(name, e) - ) from e - except TypeError as e: - raise ParseError( - 'Failed to parse {0} field: {1}.'.format(name, e) - ) from e - - def _ConvertAnyMessage(self, value, message, path): - """Convert a JSON representation into Any message.""" - if isinstance(value, dict) and not value: - return - try: - type_url = value['@type'] - except KeyError as e: - raise ParseError( - '@type is missing when parsing any message at {0}'.format(path) - ) from e - - try: - sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) - except TypeError as e: - raise ParseError('{0} at {1}'.format(e, path)) from e - message_descriptor = sub_message.DESCRIPTOR - full_name = message_descriptor.full_name - if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage( - value['value'], sub_message, '{0}.value'.format(path) - ) - elif full_name in _WKTJSONMETHODS: - # For well-known types (including nested Any), use ConvertMessage - # to ensure recursion depth is properly tracked - self.ConvertMessage(value['value'], sub_message, '{0}.value'.format(path)) - else: - del value['@type'] - try: - self._ConvertFieldValuePair(value, sub_message, path) - finally: - value['@type'] = type_url - # Sets Any message - message.value = sub_message.SerializeToString() - message.type_url = type_url - - def _ConvertGenericMessage(self, value, message, path): - """Convert a JSON representation into message with FromJsonString.""" - # Duration, Timestamp, FieldMask have a FromJsonString method to do the - # conversion. Users can also call the method directly. - try: - message.FromJsonString(value) - except ValueError as e: - raise ParseError('{0} at {1}'.format(e, path)) from e - - def _ConvertValueMessage(self, value, message, path): - """Convert a JSON representation into Value message.""" - if isinstance(value, dict): - self.ConvertMessage(value, message.struct_value, path) - elif isinstance(value, _LIST_LIKE): - self.ConvertMessage(value, message.list_value, path) - elif value is None: - message.null_value = 0 - elif isinstance(value, bool): - message.bool_value = value - elif isinstance(value, str): - message.string_value = value - elif isinstance(value, _INT_OR_FLOAT): - message.number_value = value - else: - raise ParseError( - 'Value {0} has unexpected type {1} at {2}'.format( - value, type(value), path - ) - ) - - def _ConvertListOrTupleValueMessage(self, value, message, path): - """Convert a JSON representation into ListValue message.""" - if not isinstance(value, _LIST_LIKE): - raise ParseError( - 'ListValue must be in [] which is {0} at {1}'.format(value, path) - ) - message.ClearField('values') - for index, item in enumerate(value): - self.ConvertMessage( - item, message.values.add(), '{0}[{1}]'.format(path, index) - ) - - def _ConvertStructMessage(self, value, message, path): - """Convert a JSON representation into Struct message.""" - if not isinstance(value, dict): - raise ParseError( - 'Struct must be in a dict which is {0} at {1}'.format(value, path) - ) - # Clear will mark the struct as modified so it will be created even if - # there are no values. - message.Clear() - for key in value: - self.ConvertMessage( - value[key], message.fields[key], '{0}.{1}'.format(path, key) - ) - return - - def _ConvertWrapperMessage(self, value, message, path): - """Convert a JSON representation into Wrapper message.""" - field = message.DESCRIPTOR.fields_by_name['value'] - self._ConvertAndSetScalar( - message, field, value, path='{0}.value'.format(path) - ) - - def _ConvertMapFieldValue(self, value, message, field, path): - """Convert map field value for a message map field. - - Args: - value: A JSON object to convert the map field value. - message: A protocol message to record the converted data. - field: The descriptor of the map field to be converted. - path: parent path to log parse error info. - - Raises: - ParseError: In case of convert problems. - """ - if not isinstance(value, dict): - raise ParseError( - 'Map field {0} must be in a dict which is {1} at {2}'.format( - field.name, value, path - ) - ) - key_field = field.message_type.fields_by_name['key'] - value_field = field.message_type.fields_by_name['value'] - for key in value: - key_value = _ConvertScalarFieldValue( - key, - key_field, - '{0}.key'.format(path), - self._custom_enum_names_cache, - self._GetEnumValueJsonExtension(), - require_str=True, - ) - if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self.ConvertMessage( - value[key], - getattr(message, field.name)[key_value], - '{0}[{1}]'.format(path, key_value), - ) - else: - self._ConvertAndSetScalarToMapKey( - message, - field, - key_value, - value[key], - path='{0}[{1}]'.format(path, key_value), - ) - - def _ConvertAndSetScalar(self, message, field, js_value, path): - """Convert scalar from js_value and assign it to message.field.""" - try: - value = _ConvertScalarFieldValue( - js_value, - field, - path, - self._custom_enum_names_cache, - self._GetEnumValueJsonExtension(), - ) - if field.is_extension: - message.Extensions[field] = value - else: - setattr(message, field.name, value) - except EnumStringValueParseError: - if not self.ignore_unknown_fields: - raise - - def _ConvertAndAppendScalar(self, message, repeated_field, js_value, path): - """Convert scalar from js_value and append it to message.repeated_field.""" - try: - if repeated_field.is_extension: - repeated = message.Extensions[repeated_field] - else: - repeated = getattr(message, repeated_field.name) - value = _ConvertScalarFieldValue( - js_value, - repeated_field, - path, - self._custom_enum_names_cache, - self._GetEnumValueJsonExtension(), - ) - repeated.append(value) - except EnumStringValueParseError: - if not self.ignore_unknown_fields: - raise - - def _ConvertAndSetScalarToMapKey( - self, message, map_field, converted_key, js_value, path - ): - """Convert scalar from 'js_value' and add it to message.map_field[converted_key].""" - try: - getattr(message, map_field.name)[converted_key] = ( - _ConvertScalarFieldValue( - js_value, - map_field.message_type.fields_by_name['value'], - path, - self._custom_enum_names_cache, - self._GetEnumValueJsonExtension(), - ) - ) - except EnumStringValueParseError: - if not self.ignore_unknown_fields: - raise - - -def _GetJsonEnumValueOption(ev, extension_descriptor): - """Helper to get the JsonEnumValueOptions for an enum value. - - Args: - ev: The EnumValueDescriptor. - extension_descriptor: The extension descriptor for 'pb.enumvalue.json'. - - Returns: - The JsonEnumValueOptions message if the extension is present, - otherwise None. - """ - if ev.GetOptions().HasExtension(extension_descriptor): - return ev.GetOptions().Extensions[extension_descriptor] - return None - - -def _GetCustomJsonEnumNames( - enum_type, custom_enum_names_cache, enumvalue_json_extension=None -): - """Helper to get a mapping from custom JSON name to EnumValueDescriptor. - - Args: - enum_type: The EnumDescriptor. - custom_enum_names_cache: A dict to store/lookup the cached map. - enumvalue_json_extension: The extension descriptor for 'pb.enumvalue.json', - or None to look it up in the default descriptor pool. - - Returns: - A dict mapping custom JSON name strings to EnumValueDescriptors. - """ - if enum_type in custom_enum_names_cache: - return custom_enum_names_cache[enum_type] - - custom_names = {} - if enumvalue_json_extension is None: - # Options are always put on the default pool, so we only search the default pool. - try: - enumvalue_json_extension = descriptor_pool.Default().FindExtensionByName( - 'pb.enumvalue.json' - ) - except KeyError: - enumvalue_json_extension = None - - if enumvalue_json_extension is not None: - for ev in enum_type.values: - options = ev.GetOptions() - if options.HasExtension(enumvalue_json_extension): - option = options.Extensions[enumvalue_json_extension] - if option.HasField('string'): - custom_names[option.string] = ev - - custom_enum_names_cache[enum_type] = custom_names - return custom_names - - -def _ConvertScalarFieldValue( - value, - field, - path, - custom_enum_names_cache, - enumvalue_json_extension=None, - require_str=False, -): - """Convert a single scalar field value. - - Args: - value: A scalar value to convert the scalar field value. - field: The descriptor of the field to convert. - path: parent path to log parse error info. - custom_enum_names_cache: A dict to store/lookup custom enum names. - enumvalue_json_extension: The extension descriptor for 'pb.enumvalue.json', - or None if not loaded. - require_str: If True, the field value must be a str. - - Returns: - The converted scalar field value - - Raises: - ParseError: In case of convert problems. - EnumStringValueParseError: In case of unknown enum string value. - """ - try: - if field.cpp_type in _INT_TYPES: - return _ConvertInteger(value) - elif field.cpp_type in _FLOAT_TYPES: - return _ConvertFloat(value, field) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - return _ConvertBool(value, require_str) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - if isinstance(value, str): - encoded = value.encode('utf-8') - else: - encoded = value - # Add extra padding '=' - padded_value = encoded + b'=' * (4 - len(encoded) % 4) - return base64.urlsafe_b64decode(padded_value) - else: - # Checking for unpaired surrogates appears to be unreliable, - # depending on the specific Python version, so we check manually. - if _UNPAIRED_SURROGATE_PATTERN.search(value): - raise ParseError('Unpaired surrogate') - return value - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - # Convert an enum value. - enum_value = field.enum_type.values_by_name.get(value, None) - # First check to see if we have a custom enum string. - if ( - enum_value is None - and isinstance(value, str) - and enumvalue_json_extension is not None - ): - custom_names = _GetCustomJsonEnumNames( - field.enum_type, - custom_enum_names_cache, - enumvalue_json_extension, - ) - enum_value = custom_names.get(value, None) - # If not, try parsing it as an integer. - if enum_value is None: - try: - number = int(value) - enum_value = field.enum_type.values_by_number.get(number, None) - except ValueError as e: - # Since parsing to integer failed and lookup in values_by_name didn't - # find this name, we have an enum string value which is unknown. - raise EnumStringValueParseError( - 'Invalid enum value {0} for enum type {1}'.format( - value, field.enum_type.full_name - ) - ) from e - if enum_value is None: - if field.enum_type.is_closed: - raise ParseError( - 'Invalid enum value {0} for enum type {1}'.format( - value, field.enum_type.full_name - ) - ) - else: - return number - return enum_value.number - except EnumStringValueParseError as e: - raise EnumStringValueParseError('{0} at {1}'.format(e, path)) from e - except ParseError as e: - raise ParseError('{0} at {1}'.format(e, path)) from e - - -def _ConvertInteger(value): - """Convert an integer. - - Args: - value: A scalar value to convert. - - Returns: - The integer value. - - Raises: - ParseError: If an integer couldn't be consumed. - """ - if isinstance(value, float) and not value.is_integer(): - raise ParseError("Couldn't parse integer: {0}".format(value)) - - if isinstance(value, str) and value.find(' ') != -1: - raise ParseError('Couldn\'t parse integer: "{0}"'.format(value)) - - if isinstance(value, bool): - raise ParseError( - 'Bool value {0} is not acceptable for integer field'.format(value) - ) - - try: - return int(value) - except ValueError as e: - # Attempt to parse as an integer-valued float. - try: - f = float(value) - except ValueError: - # Raise the original exception for the int parse. - raise e # pylint: disable=raise-missing-from - if not f.is_integer(): - raise ParseError( - 'Couldn\'t parse non-integer string: "{0}"'.format(value) - ) from e - return int(f) - - -def _ConvertFloat(value, field): - """Convert an floating point number.""" - if isinstance(value, float): - if math.isnan(value): - raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead') - if math.isinf(value): - if value > 0: - raise ParseError( - "Couldn't parse Infinity or value too large, " - 'use quoted "Infinity" instead' - ) - else: - raise ParseError( - "Couldn't parse -Infinity or value too small, " - 'use quoted "-Infinity" instead' - ) - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: - # pylint: disable=protected-access - if value > type_checkers._FLOAT_MAX: - raise ParseError('Float value too large') - # pylint: disable=protected-access - if value < type_checkers._FLOAT_MIN: - raise ParseError('Float value too small') - if value == 'nan': - raise ParseError('Couldn\'t parse float "nan", use "NaN" instead') - try: - # Assume Python compatible syntax. - return float(value) - except ValueError as e: - # Check alternative spellings. - if value == _NEG_INFINITY: - return float('-inf') - elif value == _INFINITY: - return float('inf') - elif value == _NAN: - return float('nan') - else: - raise ParseError("Couldn't parse float: {0}".format(value)) from e - - -def _ConvertBool(value, require_str): - """Convert a boolean value. - - Args: - value: A scalar value to convert. - require_str: If True, value must be a str. - - Returns: - The bool parsed. - - Raises: - ParseError: If a boolean value couldn't be consumed. - """ - if require_str: - if value == 'true': - return True - elif value == 'false': - return False - else: - raise ParseError('Expected "true" or "false", not {0}'.format(value)) - - if not isinstance(value, bool): - raise ParseError('Expected true or false without quotes') - return value - - -_WKTJSONMETHODS = { - 'google.protobuf.Any': ['_AnyMessageToJsonObject', '_ConvertAnyMessage'], - 'google.protobuf.Duration': [ - '_GenericMessageToJsonObject', - '_ConvertGenericMessage', - ], - 'google.protobuf.FieldMask': [ - '_GenericMessageToJsonObject', - '_ConvertGenericMessage', - ], - 'google.protobuf.ListValue': [ - '_ListValueMessageToJsonObject', - '_ConvertListOrTupleValueMessage', - ], - 'google.protobuf.Struct': [ - '_StructMessageToJsonObject', - '_ConvertStructMessage', - ], - 'google.protobuf.Timestamp': [ - '_GenericMessageToJsonObject', - '_ConvertGenericMessage', - ], - 'google.protobuf.Value': [ - '_ValueMessageToJsonObject', - '_ConvertValueMessage', - ], -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py deleted file mode 100644 index 7e029843db7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/json_options_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/json_options.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/json_options.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import json_enumvalue_options_pb2 as google_dot_protobuf_dot_json__enumvalue__options__pb2 - -from opentelemetry.agent._vendor.google.protobuf.json_enumvalue_options_pb2 import * - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"google/protobuf/json_options.proto\x12\x02pb\x1a,google/protobuf/json_enumvalue_options.protoB\x1a\n\x18\x63om.google.protobuf.utilP\x00\x62\x08\x65\x64itionsp\xe9\x07') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.json_options_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\030com.google.protobuf.util' -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py deleted file mode 100644 index c0e8001069a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message.py +++ /dev/null @@ -1,467 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -# TODO: We should just make these methods all "pure-virtual" and move -# all implementation out, into reflection.py for now. -"""Contains an abstract base class for protocol messages.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -_INCONSISTENT_MESSAGE_ATTRIBUTES = ('Extensions',) - - -class Error(Exception): - """Base error type for this module.""" - - pass - - -class DecodeError(Error): - """Exception raised when deserializing messages.""" - - pass - - -class EncodeError(Error): - """Exception raised when serializing messages.""" - - pass - - -class FrozenInstanceError(AttributeError): - """Exception raised when mutating a frozen message.""" - - pass - - -class Message(object): - """Abstract base class for protocol messages. - - Protocol message classes are almost always generated by the protocol - compiler. These generated types subclass Message and implement the methods - shown below. - """ - - # TODO: Link to an HTML document here. - - # TODO: Document that instances of this class will also - # have an Extensions attribute with __getitem__ and __setitem__. - # Again, not sure how to best convey this. - - # TODO: Document these fields and methods. - - __slots__ = [] - - #: The :class:`google.protobuf.Descriptor` - # for this message type. - DESCRIPTOR = None - - def __deepcopy__(self, memo=None): - clone = type(self)() - clone.MergeFrom(self) - return clone - - def __dir__(self): - """Provides the list of all accessible Message attributes.""" - message_attributes = set(super().__dir__()) - - # TODO: Remove this once the UPB implementation is improved. - # The UPB proto implementation currently doesn't provide proto fields as - # attributes and they have to added. - if self.DESCRIPTOR is not None: - for field in self.DESCRIPTOR.fields: - message_attributes.add(field.name) - - # The Fast C++ proto implementation provides inaccessible attributes that - # have to be removed. - for attribute in _INCONSISTENT_MESSAGE_ATTRIBUTES: - if attribute not in message_attributes: - continue - try: - getattr(self, attribute) - except AttributeError: - message_attributes.remove(attribute) - - return sorted(message_attributes) - - def __eq__(self, other_msg): - """Recursively compares two messages by value and structure.""" - raise NotImplementedError - - def __ne__(self, other_msg): - # Can't just say self != other_msg, since that would infinitely recurse. :) - return not self == other_msg - - def __hash__(self): - raise TypeError('unhashable object') - - def __str__(self): - """Outputs a human-readable representation of the message.""" - raise NotImplementedError - - def __unicode__(self): - """Outputs a human-readable representation of the message.""" - raise NotImplementedError - - def __contains__(self, field_name_or_key): - """Checks if a certain field is set for the message. - - Has presence fields return true if the field is set, false if the field is - not set. Fields without presence do raise `ValueError` (this includes - repeated fields, map fields, and implicit presence fields). - - If field_name is not defined in the message descriptor, `ValueError` will - be raised. - Note: WKT Struct checks if the key is contained in fields. ListValue checks - if the item is contained in the list. - - Args: - field_name_or_key: For Struct, the key (str) of the fields map. For - ListValue, any type that may be contained in the list. For other - messages, name of the field (str) to check for presence. - - Returns: - bool: For Struct, whether the item is contained in fields. For ListValue, - whether the item is contained in the list. For other message, - whether a value has been set for the named field. - - Raises: - ValueError: For normal messages, if the `field_name_or_key` is not a - member of this message or `field_name_or_key` is not a string. - """ - raise NotImplementedError - - def MergeFrom(self, other_msg): - """Merges the contents of the specified message into current message. - - This method merges the contents of the specified message into the current - message. Singular fields that are set in the specified message overwrite - the corresponding fields in the current message. Repeated fields are - appended. Singular sub-messages and groups are recursively merged. - - Args: - other_msg (Message): A message to merge into the current message. - """ - raise NotImplementedError - - def CopyFrom(self, other_msg): - """Copies the content of the specified message into the current message. - - The method clears the current message and then merges the specified - message using MergeFrom. - - Args: - other_msg (Message): A message to copy into the current one. - """ - if self is other_msg: - return - self.Clear() - self.MergeFrom(other_msg) - - def Clear(self): - """Clears all data that was set in the message.""" - raise NotImplementedError - - def SetInParent(self): - """Mark this as present in the parent. - - This normally happens automatically when you assign a field of a - sub-message, but sometimes you want to make the sub-message - present while keeping it empty. If you find yourself using this, - you may want to reconsider your design. - """ - raise NotImplementedError - - def IsInitialized(self): - """Checks if the message is initialized. - - Returns: - bool: The method returns True if the message is initialized (i.e. all of - its required fields are set). - """ - raise NotImplementedError - - # TODO: MergeFromString() should probably return None and be - # implemented in terms of a helper that returns the # of bytes read. Our - # deserialization routines would use the helper when recursively - # deserializing, but the end user would almost always just want the no-return - # MergeFromString(). - - def MergeFromString(self, serialized): - """Merges serialized protocol buffer data into this message. - - When we find a field in `serialized` that is already present - in this message: - - - If it's a "repeated" field, we append to the end of our list. - - Else, if it's a scalar, we overwrite our field. - - Else, (it's a nonrepeated composite), we recursively merge - into the existing composite. - - Args: - serialized (bytes): Any object that allows us to call - ``memoryview(serialized)`` to access a string of bytes using the buffer - interface. - - Returns: - int: The number of bytes read from `serialized`. - For non-group messages, this will always be `len(serialized)`, - but for messages which are actually groups, this will - generally be less than `len(serialized)`, since we must - stop when we reach an ``END_GROUP`` tag. Note that if - we *do* stop because of an ``END_GROUP`` tag, the number - of bytes returned does not include the bytes - for the ``END_GROUP`` tag information. - - Raises: - DecodeError: if the input cannot be parsed. - """ - # TODO: Document handling of unknown fields. - # TODO: When we switch to a helper, this will return None. - raise NotImplementedError - - def ParseFromString(self, serialized): - """Parse serialized protocol buffer data in binary form into this message. - - Like :func:`MergeFromString()`, except we clear the object first. - - Raises: - message.DecodeError if the input cannot be parsed. - """ - self.Clear() - return self.MergeFromString(serialized) - - def SerializeToString(self, **kwargs): - """Serializes the protocol message to a binary string. - - Keyword Args: - deterministic (bool): If true, requests deterministic serialization - of the protobuf. Note that there is no canonical representation of - protobuf messages: deterministic serialization only means 'consistent - for current build, but not stable between rebuilds, and may not match - decisions made by other languages'. - See - https://protobuf.dev/programming-guides/serialization-not-canonical/. - - Returns: - A binary string representation of the message if all of the required - fields in the message are set (i.e. the message is initialized). - - Raises: - EncodeError: if the message isn't initialized (see :func:`IsInitialized`). - """ - raise NotImplementedError - - def SerializePartialToString(self, **kwargs): - """Serializes the protocol message to a binary string. - - This method is similar to SerializeToString but doesn't check if the - message is initialized. - - Keyword Args: - deterministic (bool): If true, requests deterministic serialization - of the protobuf. Note that 'deterministic' serialization only means - 'Consistent for current build, but still arbitary and not stable over - time'. There is no canonical representation of protobuf messages, - See - https://protobuf.dev/programming-guides/serialization-not-canonical/. - - Returns: - bytes: A serialized representation of the partial message. - """ - raise NotImplementedError - - # TODO: Decide whether we like these better - # than auto-generated has_foo() and clear_foo() methods - # on the instances themselves. This way is less consistent - # with C++, but it makes reflection-type access easier and - # reduces the number of magically autogenerated things. - # - # TODO: Be sure to document (and test) exactly - # which field names are accepted here. Are we case-sensitive? - # What do we do with fields that share names with Python keywords - # like 'lambda' and 'yield'? - # - # nnorwitz says: - # """ - # Typically (in python), an underscore is appended to names that are - # keywords. So they would become lambda_ or yield_. - # """ - def ListFields(self): - """Returns a list of (FieldDescriptor, value) tuples for present fields. - - A message field is non-empty if HasField() would return true. A singular - primitive field is non-empty if HasField() would return true in proto2 or it - is non zero in proto3. A repeated field is non-empty if it contains at least - one element. The fields are ordered by field number. - - Returns: - list[tuple(FieldDescriptor, value)]: field descriptors and values - for all fields in the message which are not empty. The values vary by - field type. - """ - raise NotImplementedError - - def HasField(self, field_name): - """Checks if a certain field is set for the message. - - For a oneof group, checks if any field inside is set. Note that if the - field_name is not defined in the message descriptor, :exc:`ValueError` will - be raised. - - Args: - field_name (str): The name of the field to check for presence. - - Returns: - bool: Whether a value has been set for the named field. - - Raises: - ValueError: if the `field_name` is not a member of this message. - """ - raise NotImplementedError - - def ClearField(self, field_name): - """Clears the contents of a given field. - - Inside a oneof group, clears the field set. If the name neither refers to a - defined field or oneof group, :exc:`ValueError` is raised. - - Args: - field_name (str): The name of the field to check for presence. - - Raises: - ValueError: if the `field_name` is not a member of this message. - """ - raise NotImplementedError - - def WhichOneof(self, oneof_group): - """Returns the name of the field that is set inside a oneof group. - - If no field is set, returns None. - - Args: - oneof_group (str): the name of the oneof group to check. - - Returns: - str or None: The name of the group that is set, or None. - - Raises: - ValueError: no group with the given name exists - """ - raise NotImplementedError - - def HasExtension(self, field_descriptor): - """Checks if a certain extension is present for this message. - - Extensions are retrieved using the :attr:`Extensions` mapping (if present). - - Args: - field_descriptor: The field descriptor for the extension to check. - - Returns: - bool: Whether the extension is present for this message. - - Raises: - KeyError: if the extension is repeated. Similar to repeated fields, - there is no separate notion of presence: a "not present" repeated - extension is an empty list. - """ - raise NotImplementedError - - def ClearExtension(self, field_descriptor): - """Clears the contents of a given extension. - - Args: - field_descriptor: The field descriptor for the extension to clear. - """ - raise NotImplementedError - - def UnknownFields(self): - """Returns the UnknownFieldSet. - - Returns: - UnknownFieldSet: The unknown fields stored in this message. - """ - raise NotImplementedError - - def DiscardUnknownFields(self): - """Clears all fields in the :class:`UnknownFieldSet`. - - This operation is recursive for nested message. - """ - raise NotImplementedError - - def ByteSize(self): - """Returns the serialized size of this message. - - Recursively calls ByteSize() on all contained messages. - - Returns: - int: The number of bytes required to serialize this message. - """ - raise NotImplementedError - - @classmethod - def FromString(cls, s): - raise NotImplementedError - - def _SetListener(self, message_listener): - """Internal method used by the protocol message implementation. - - Clients should not call this directly. - - Sets a listener that this message will call on certain state transitions. - - The purpose of this method is to register back-edges from children to - parents at runtime, for the purpose of setting "has" bits and - byte-size-dirty bits in the parent and ancestor objects whenever a child or - descendant object is modified. - - If the client wants to disconnect this Message from the object tree, she - explicitly sets callback to None. - - If message_listener is None, unregisters any existing listener. Otherwise, - message_listener must implement the MessageListener interface in - internal/message_listener.py, and we discard any listener registered - via a previous _SetListener() call. - """ - raise NotImplementedError - - def __getstate__(self): - """Support the pickle protocol.""" - return dict(serialized=self.SerializePartialToString()) - - def __setstate__(self, state): - """Support the pickle protocol.""" - self.__init__() - serialized = state['serialized'] - # On Python 3, using encoding='latin1' is required for unpickling - # protos pickled by Python 2. - if not isinstance(serialized, bytes): - serialized = serialized.encode('latin1') - self.ParseFromString(serialized) - - def __reduce__(self): - message_descriptor = self.DESCRIPTOR - if message_descriptor.containing_type is None: - return type(self), (), self.__getstate__() - # the message type must be nested. - # Python does not pickle nested classes; use the symbol_database on the - # receiving end. - container = message_descriptor - return ( - _InternalConstructMessage, - (container.full_name,), - self.__getstate__(), - ) - - -def _InternalConstructMessage(full_name): - """Constructs a nested message.""" - from opentelemetry.agent._vendor.google.protobuf import symbol_database # pylint:disable=g-import-not-at-top - - return symbol_database.Default().GetSymbol(full_name)() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py deleted file mode 100644 index 3858440b219..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/message_factory.py +++ /dev/null @@ -1,188 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Provides a factory class for generating dynamic messages. - -The easiest way to use this class is if you have access to the FileDescriptor -protos containing the messages you want to create you can just do the following: - -message_classes = message_factory.GetMessages(iterable_of_file_descriptors) -my_proto_instance = message_classes['some.proto.package.MessageName']() -""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -import warnings - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import message -from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation - -if api_implementation.Type() == 'python': - from opentelemetry.agent._vendor.google.protobuf.internal import python_message as message_impl -else: - from opentelemetry.agent._vendor.google.protobuf.pyext import cpp_message as message_impl # pylint: disable=g-import-not-at-top - -# The type of all Message classes. -_GENERATED_PROTOCOL_MESSAGE_TYPE = message_impl.GeneratedProtocolMessageType - - -def GetMessageClass(descriptor): - """Obtains a proto2 message class based on the passed in descriptor. - - Passing a descriptor with a fully qualified name matching a previous - invocation will cause the same class to be returned. - - Args: - descriptor: The descriptor to build from. - - Returns: - A class describing the passed in descriptor. - """ - concrete_class = getattr(descriptor, '_concrete_class', None) - if concrete_class: - return concrete_class - return _InternalCreateMessageClass(descriptor) - - -def GetMessageClassesForFiles(files, pool): - """Gets all the messages from specified files. - - This will find and resolve dependencies, failing if the descriptor - pool cannot satisfy them. - - This will not return the classes for nested types within those classes, for - those, use GetMessageClass() on the nested types within their containing - messages. - - For example, for the message: - - message NestedTypeMessage { - message NestedType { - string data = 1; - } - NestedType nested = 1; - } - - NestedTypeMessage will be in the result, but not - NestedTypeMessage.NestedType. - - Args: - files: The file names to extract messages from. - pool: The descriptor pool to find the files including the dependent files. - - Returns: - A dictionary mapping proto names to the message classes. - """ - result = {} - for file_name in files: - file_desc = pool.FindFileByName(file_name) - for desc in file_desc.message_types_by_name.values(): - result[desc.full_name] = GetMessageClass(desc) - - # While the extension FieldDescriptors are created by the descriptor pool, - # the python classes created in the factory need them to be registered - # explicitly, which is done below. - # - # The call to RegisterExtension will specifically check if the - # extension was already registered on the object and either - # ignore the registration if the original was the same, or raise - # an error if they were different. - - for extension in file_desc.extensions_by_name.values(): - _ = GetMessageClass(extension.containing_type) - if api_implementation.Type() != 'python': - # TODO: Remove this check here. Duplicate extension - # register check should be in descriptor_pool. - if extension is not pool.FindExtensionByNumber( - extension.containing_type, extension.number - ): - raise ValueError('Double registration of Extensions') - # Recursively load protos for extension field, in order to be able to - # fully represent the extension. This matches the behavior for regular - # fields too. - if extension.message_type: - GetMessageClass(extension.message_type) - return result - - -def _InternalCreateMessageClass(descriptor): - """Builds a proto2 message class based on the passed in descriptor. - - Args: - descriptor: The descriptor to build from. - - Returns: - A class describing the passed in descriptor. - """ - descriptor_name = descriptor.name - result_class = _GENERATED_PROTOCOL_MESSAGE_TYPE( - descriptor_name, - (message.Message,), - { - 'DESCRIPTOR': descriptor, - # If module not set, it wrongly points to message_factory module. - '__module__': None, - }, - ) - for field in descriptor.fields: - if field.message_type: - GetMessageClass(field.message_type) - - for extension in result_class.DESCRIPTOR.extensions: - extended_class = GetMessageClass(extension.containing_type) - if api_implementation.Type() != 'python': - # TODO: Remove this check here. Duplicate extension - # register check should be in descriptor_pool. - pool = extension.containing_type.file.pool - if extension is not pool.FindExtensionByNumber( - extension.containing_type, extension.number - ): - raise ValueError('Double registration of Extensions') - if extension.message_type: - GetMessageClass(extension.message_type) - return result_class - - -# Deprecated. Please use GetMessageClass() or GetMessageClassesForFiles() -# method above instead. -class MessageFactory(object): - """Factory for creating Proto2 messages from descriptors in a pool.""" - - def __init__(self, pool=None): - """Initializes a new factory.""" - self.pool = pool or descriptor_pool.DescriptorPool() - - -def GetMessages(file_protos, pool=None): - """Builds a dictionary of all the messages available in a set of files. - - Args: - file_protos: Iterable of FileDescriptorProto to build messages out of. - pool: The descriptor pool to add the file protos. - - Returns: - A dictionary mapping proto names to the message classes. This will include - any dependent messages as well as any messages defined in the same file as - a specified message. - """ - # The cpp implementation of the protocol buffer library requires to add the - # message in topological order of the dependency graph. - des_pool = pool or descriptor_pool.DescriptorPool() - file_by_name = {file_proto.name: file_proto for file_proto in file_protos} - - def _AddFile(file_proto): - for dependency in file_proto.dependency: - if dependency in file_by_name: - # Remove from elements to be visited, in order to cut cycles. - _AddFile(file_by_name.pop(dependency)) - des_pool.Add(file_proto) - - while file_by_name: - _AddFile(file_by_name.popitem()[1]) - return GetMessageClassesForFiles( - [file_proto.name for file_proto in file_protos], des_pool - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py deleted file mode 100644 index ee373e92cbf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto.py +++ /dev/null @@ -1,153 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains the Nextgen Pythonic protobuf APIs.""" - -import io -from typing import Text, Type, TypeVar - -from opentelemetry.agent._vendor.google.protobuf.internal import decoder -from opentelemetry.agent._vendor.google.protobuf.internal import encoder -from opentelemetry.agent._vendor.google.protobuf.message import Message - -_MESSAGE = TypeVar('_MESSAGE', bound='Message') - - -def serialize(message: _MESSAGE, deterministic: bool = None) -> bytes: - """Return the serialized proto. - - Args: - message: The proto message to be serialized. - deterministic: If true, requests deterministic serialization of the - protobuf, with predictable ordering of map keys. - - Returns: - A binary bytes representation of the message. - """ - return message.SerializeToString(deterministic=deterministic) - - -def parse(message_class: Type[_MESSAGE], payload: bytes) -> _MESSAGE: - """Given a serialized data in binary form, deserialize it into a Message. - - Args: - message_class: The message meta class. - payload: A serialized bytes in binary form. - - Returns: - A new message deserialized from payload. - """ - new_message = message_class() - new_message.ParseFromString(payload) - return new_message - - -def serialize_length_prefixed(message: _MESSAGE, output: io.BytesIO) -> None: - """Writes the size of the message as a varint and the serialized message. - - Writes the size of the message as a varint and then the serialized message. - This allows more data to be written to the output after the message. Use - parse_length_prefixed to parse messages written by this method. - - The output stream must be buffered, e.g. using - https://docs.python.org/3/library/io.html#buffered-streams. - - Example usage: - out = io.BytesIO() - for msg in message_list: - proto.serialize_length_prefixed(msg, out) - - Args: - message: The protocol buffer message that should be serialized. - output: BytesIO or custom buffered IO that data should be written to. - """ - payload = serialize(message) - size = len(payload) - encoder._VarintEncoder()(output.write, size) - out_size = output.write(payload) - - if out_size != size: - raise TypeError( - 'Failed to write complete message (wrote: %d, expected: %d)' - '. Ensure output is using buffered IO.' % (out_size, size) - ) - - -def parse_length_prefixed( - message_class: Type[_MESSAGE], input_bytes: io.BytesIO -) -> _MESSAGE: - """Parse a message from input_bytes. - - Args: - message_class: The protocol buffer message class that parser should parse. - input_bytes: A buffered input. - - Example usage: - while True: - msg = proto.parse_length_prefixed(message_class, input_bytes) - if msg is None: - break - ... - - Returns: - A parsed message if successful. None if input_bytes is at EOF. - """ - size = decoder._DecodeVarint(input_bytes) - if size is None: - # It is the end of buffered input. See example usage in the - # API description. - return None - - message = message_class() - - if size == 0: - return message - - parsed_size = message.ParseFromString(input_bytes.read(size)) - if parsed_size != size: - raise ValueError( - 'Truncated message or non-buffered input_bytes: ' - 'Expected {0} bytes but only {1} bytes parsed for ' - '{2}.'.format(size, parsed_size, message.DESCRIPTOR.name) - ) - return message - - -def byte_size(message: Message) -> int: - """Returns the serialized size of this message. - - Args: - message: A proto message. - - Returns: - int: The number of bytes required to serialize this message. - """ - return message.ByteSize() - - -def clear_message(message: Message) -> None: - """Clears all data that was set in the message. - - Args: - message: The proto message to be cleared. - """ - message.Clear() - - -def clear_field(message: Message, field_name: Text) -> None: - """Clears the contents of a given field. - - Inside a oneof group, clears the field set. If the name neither refers to a - defined field or oneof group, :exc:`ValueError` is raised. - - Args: - message: The proto message. - field_name (str): The name of the field to be cleared. - - Raises: - ValueError: if the `field_name` is not a member of this message. - """ - message.ClearField(field_name) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py deleted file mode 100644 index d98b4025cbf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_builder.py +++ /dev/null @@ -1,117 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Dynamic Protobuf class creator.""" - -from collections import OrderedDict -import hashlib -import os - -from opentelemetry.agent._vendor.google.protobuf import descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pb2 -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import message_factory - - -def _GetMessageFromFactory(pool, full_name): - """Get a proto class from the MessageFactory by name. - - Args: - pool: a descriptor pool. - full_name: str, the fully qualified name of the proto type. - - Returns: - A class, for the type identified by full_name. - Raises: - KeyError, if the proto is not found in the factory's descriptor pool. - """ - proto_descriptor = pool.FindMessageTypeByName(full_name) - proto_cls = message_factory.GetMessageClass(proto_descriptor) - return proto_cls - - -def MakeSimpleProtoClass(fields, full_name=None, pool=None): - """Create a Protobuf class whose fields are basic types. - - Note: this doesn't validate field names! - - Args: - fields: dict of {name: field_type} mappings for each field in the proto. If - this is an OrderedDict the order will be maintained, otherwise the fields - will be sorted by name. - full_name: optional str, the fully-qualified name of the proto type. - pool: optional DescriptorPool instance. - - Returns: - a class, the new protobuf class with a FileDescriptor. - """ - pool_instance = pool or descriptor_pool.DescriptorPool() - if full_name is not None: - try: - proto_cls = _GetMessageFromFactory(pool_instance, full_name) - return proto_cls - except KeyError: - # The factory's DescriptorPool doesn't know about this class yet. - pass - - # Get a list of (name, field_type) tuples from the fields dict. If fields was - # an OrderedDict we keep the order, but otherwise we sort the field to ensure - # consistent ordering. - field_items = fields.items() - if not isinstance(fields, OrderedDict): - field_items = sorted(field_items) - - # Use a consistent file name that is unlikely to conflict with any imported - # proto files. - fields_hash = hashlib.sha1(usedforsecurity=False) - for f_name, f_type in field_items: - fields_hash.update(f_name.encode('utf-8')) - fields_hash.update(str(f_type).encode('utf-8')) - proto_file_name = fields_hash.hexdigest() + '.proto' - - # If the proto is anonymous, use the same hash to name it. - if full_name is None: - full_name = ( - 'net.proto2.python.public.proto_builder.AnonymousProto_' - + fields_hash.hexdigest() - ) - try: - proto_cls = _GetMessageFromFactory(pool_instance, full_name) - return proto_cls - except KeyError: - # The factory's DescriptorPool doesn't know about this class yet. - pass - - # This is the first time we see this proto: add a new descriptor to the pool. - pool_instance.Add( - _MakeFileDescriptorProto(proto_file_name, full_name, field_items) - ) - return _GetMessageFromFactory(pool_instance, full_name) - - -def _MakeFileDescriptorProto(proto_file_name, full_name, field_items): - """Populate FileDescriptorProto for MessageFactory's DescriptorPool.""" - package, name = full_name.rsplit('.', 1) - file_proto = descriptor_pb2.FileDescriptorProto() - file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name) - file_proto.package = package - desc_proto = file_proto.message_type.add() - desc_proto.name = name - for f_number, (f_name, f_type) in enumerate(field_items, 1): - field_proto = desc_proto.field.add() - field_proto.name = f_name - # # If the number falls in the reserved range, reassign it to the correct - # # number after the range. - if f_number >= descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER: - f_number += ( - descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER - - descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER - + 1 - ) - field_proto.number = f_number - field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL - field_proto.type = f_type - return file_proto diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py deleted file mode 100644 index af95a43b4e2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_json.py +++ /dev/null @@ -1,81 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains the Nextgen Pythonic Protobuf JSON APIs.""" - -from typing import Optional, Type - -from opentelemetry.agent._vendor.google.protobuf import json_format -from opentelemetry.agent._vendor.google.protobuf.descriptor_pool import DescriptorPool -from opentelemetry.agent._vendor.google.protobuf.message import Message - - -def serialize( - message: Message, - always_print_fields_with_no_presence: bool = False, - preserving_proto_field_name: bool = False, - use_integers_for_enums: bool = False, - descriptor_pool: Optional[DescriptorPool] = None, -) -> dict: - """Converts protobuf message to a dictionary. - - When the dictionary is encoded to JSON, it conforms to ProtoJSON spec. - - Args: - message: The protocol buffers message instance to serialize. - always_print_fields_with_no_presence: If True, fields without presence - (implicit presence scalars, repeated fields, and map fields) will always - be serialized. Any field that supports presence is not affected by this - option (including singular message fields and oneof fields). - preserving_proto_field_name: If True, use the original proto field names as - defined in the .proto file. If False, convert the field names to - lowerCamelCase. - use_integers_for_enums: If true, print integers instead of enum names. - descriptor_pool: A Descriptor Pool for resolving types. If None use the - default. - - Returns: - A dict representation of the protocol buffer message. - """ - return json_format.MessageToDict( - message, - always_print_fields_with_no_presence=always_print_fields_with_no_presence, - preserving_proto_field_name=preserving_proto_field_name, - use_integers_for_enums=use_integers_for_enums, - ) - - -def parse( - message_class: Type[Message], - js_dict: dict, - ignore_unknown_fields: bool = False, - descriptor_pool: Optional[DescriptorPool] = None, - max_recursion_depth: int = 100, -) -> Message: - """Parses a JSON dictionary representation into a message. - - Args: - message_class: The message meta class. - js_dict: Dict representation of a JSON message. - ignore_unknown_fields: If True, do not raise errors for unknown fields. - descriptor_pool: A Descriptor Pool for resolving types. If None use the - default. - max_recursion_depth: max recursion depth of JSON message to be deserialized. - JSON messages over this depth will fail to be deserialized. Default value - is 100. - - Returns: - A new message passed from json_dict. - """ - new_message = message_class() - json_format.ParseDict( - js_dict=js_dict, - message=new_message, - ignore_unknown_fields=ignore_unknown_fields, - descriptor_pool=descriptor_pool, - max_recursion_depth=max_recursion_depth, - ) - return new_message diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py deleted file mode 100644 index 96a61f7bcd8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/proto_text.py +++ /dev/null @@ -1,118 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2025 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains the Nextgen Pythonic Protobuf Text Format APIs.""" - -from typing import AnyStr, Callable, Optional, Text, Type, Union - -from opentelemetry.agent._vendor.google.protobuf import text_format -from opentelemetry.agent._vendor.google.protobuf.descriptor_pool import DescriptorPool -from opentelemetry.agent._vendor.google.protobuf.message import Message - -_MsgFormatter = Callable[[Message, Union[int, bool], bool], Optional[Text]] - - -def serialize( - message: Message, - as_utf8: bool = True, - as_one_line: bool = False, - use_short_repeated_primitives: bool = False, - pointy_brackets: bool = False, - use_index_order: bool = False, - use_field_number: bool = False, - descriptor_pool: Optional[DescriptorPool] = None, - indent: int = 0, - message_formatter: Optional[_MsgFormatter] = None, - print_unknown_fields: bool = False, - force_colon: bool = False, -) -> str: - """Convert protobuf message to text format. - - Double values can be formatted compactly with 15 digits of - precision (which is the most that IEEE 754 "double" can guarantee) - using double_format='.15g'. To ensure that converting to text and back to a - proto will result in an identical value, double_format='.17g' should be used. - - Args: - message: The protocol buffers message. - as_utf8: Return unescaped Unicode for non-ASCII characters. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, fields of a proto message will be printed using - the order defined in source code instead of the field number, extensions - will be printed at the end of the message and their relative order is - determined by the extension number. By default, use the field number - order. - use_field_number: If True, print field numbers instead of names. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - indent (int): The initial indent level, in terms of spaces, for pretty - print. - message_formatter (function(message, indent, as_one_line) -> unicode|None): - Custom formatter for selected sub-messages (usually based on message - type). Use to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if the - field is a proto message. - - Returns: - str: A string of the text formatted protocol buffer message. - """ - return text_format.MessageToString( - message=message, - as_utf8=as_utf8, - as_one_line=as_one_line, - use_short_repeated_primitives=use_short_repeated_primitives, - pointy_brackets=pointy_brackets, - use_index_order=use_index_order, - use_field_number=use_field_number, - descriptor_pool=descriptor_pool, - indent=indent, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon, - ) - - -def parse( - message_class: Type[Message], - text: AnyStr, - allow_unknown_extension: bool = False, - allow_field_number: bool = False, - descriptor_pool: Optional[DescriptorPool] = None, - allow_unknown_field: bool = False, -) -> Message: - """Parses a text representation of a protocol message into a message. - - Args: - message_class: The message meta class. - text (str): Message text representation. - message (Message): A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep parsing. - Avoid to use this option if possible. It may hide some errors (e.g. - spelling error on field name) - - Returns: - Message: A new message passed from text. - - Raises: - ParseError: On text parsing problems. - """ - new_message = message_class() - text_format.Parse( - text=text, - message=new_message, - allow_unknown_extension=allow_unknown_extension, - allow_field_number=allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field, - ) - return new_message diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py deleted file mode 100644 index 03bf7da68a0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/pyext/cpp_message.py +++ /dev/null @@ -1,46 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Protocol message implementation hooks for C++ implementation. - -Contains helper functions used to create protocol message classes from -Descriptor objects at runtime backed by the protocol buffer C++ API. -""" - -__author__ = 'tibell@google.com (Johan Tibell)' - -from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation - -# pylint: disable=protected-access -_message = api_implementation._c_module -# TODO: Remove this import after fix api_implementation -if _message is None: - from opentelemetry.agent._vendor.google.protobuf.pyext import _message - - -class GeneratedProtocolMessageType(_message.MessageMeta): - """Metaclass for protocol message classes created at runtime from Descriptors. - - The protocol compiler currently uses this metaclass to create protocol - message classes at runtime. Clients can also manually create their own - classes at runtime, as in this example: - - mydescriptor = Descriptor(.....) - factory = symbol_database.Default() - factory.pool.AddDescriptor(mydescriptor) - MyProtoClass = message_factory.GetMessageClass(mydescriptor) - myproto_instance = MyProtoClass() - myproto.foo_field = 23 - ... - - The above example will not work for nested types. If you wish to include them, - use reflection.MakeClass() instead of manually instantiating the class in - order to create the appropriate class structure. - """ - - # Must be consistent with the protocol-compiler code in - # proto2/compiler/internal/generator.*. - _DESCRIPTOR_KEY = 'DESCRIPTOR' diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py deleted file mode 100644 index cf8014a141a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/reflection.py +++ /dev/null @@ -1,36 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -# This code is meant to work on Python 2.4 and above only. -"""Contains a metaclass and helper functions used to create - -protocol message classes from Descriptor objects at runtime. - -Recall that a metaclass is the "type" of a class. -(A class is to a metaclass what an instance is to a class.) - -In this case, we use the GeneratedProtocolMessageType metaclass -to inject all the useful functionality into the classes -output by the protocol compiler at compile-time. - -The upshot of all this is that the real implementation -details for ALL pure-Python protocol buffers are *here in -this file*. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import warnings - -from opentelemetry.agent._vendor.google.protobuf import message_factory -from opentelemetry.agent._vendor.google.protobuf import symbol_database - -# The type of all Message classes. -# Part of the public interface, but normally only used by message factories. -GeneratedProtocolMessageType = message_factory._GENERATED_PROTOCOL_MESSAGE_TYPE - -MESSAGE_CLASS_CACHE = {} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py deleted file mode 100644 index 857f373c38e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/runtime_version.py +++ /dev/null @@ -1,105 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Protobuf Runtime versions and validators. - -It should only be accessed by Protobuf gencodes and tests. DO NOT USE it -elsewhere. -""" - -__author__ = 'shaod@google.com (Dennis Shao)' - -from enum import Enum - -import os -import warnings - - -class Domain(Enum): - GOOGLE_INTERNAL = 1 - PUBLIC = 2 - - -# The versions of this Python Protobuf runtime to be changed automatically by -# the Protobuf release process. Do not edit them manually. -# These OSS versions are not stripped to avoid merging conflicts. -OSS_DOMAIN = Domain.PUBLIC -OSS_MAJOR = 7 -OSS_MINOR = 36 -OSS_PATCH = 2 -OSS_SUFFIX = '' - -DOMAIN = OSS_DOMAIN -MAJOR = OSS_MAJOR -MINOR = OSS_MINOR -PATCH = OSS_PATCH -SUFFIX = OSS_SUFFIX - -# Avoid flooding of warnings. -_MAX_WARNING_COUNT = 20 -_warning_count = 0 - - -class VersionError(Exception): - """Exception class for version violation.""" - - -def _ReportVersionError(msg): - raise VersionError(msg) - - -def ValidateProtobufRuntimeVersion( - gen_domain, gen_major, gen_minor, gen_patch, gen_suffix, location -): - """Function to validate versions. - - Args: - gen_domain: The domain where the code was generated from. - gen_major: The major version number of the gencode. - gen_minor: The minor version number of the gencode. - gen_patch: The patch version number of the gencode. - gen_suffix: The version suffix e.g. '-dev', '-rc1' of the gencode. - location: The proto location that causes the version violation. - - Raises: - VersionError: if gencode version is invalid or incompatible with the - runtime. - """ - - disable_flag = os.getenv('TEMPORARILY_DISABLE_PROTOBUF_VERSION_CHECK') - if disable_flag is not None and disable_flag.lower() == 'true': - return - - global _warning_count - - version = f'{MAJOR}.{MINOR}.{PATCH}{SUFFIX}' - gen_version = f'{gen_major}.{gen_minor}.{gen_patch}{gen_suffix}' - - if gen_major < 0 or gen_minor < 0 or gen_patch < 0: - raise VersionError(f'Invalid gencode version: {gen_version}') - - error_prompt = ( - 'See Protobuf version guarantees at' - ' https://protobuf.dev/support/cross-version-runtime-guarantee.' - ) - - if gen_domain != DOMAIN: - _ReportVersionError( - 'Detected mismatched Protobuf Gencode/Runtime domains when loading' - f' {location}: gencode {gen_domain.name} runtime {DOMAIN.name}.' - ' Cross-domain usage of Protobuf is not supported.' - ) - - if ( - MAJOR < gen_major - or (MAJOR == gen_major and MINOR < gen_minor) - or (MAJOR == gen_major and MINOR == gen_minor and PATCH < gen_patch) - ): - _ReportVersionError( - 'Detected incompatible Protobuf Gencode/Runtime versions when loading' - f' {location}: gencode {gen_version} runtime {version}. Runtime version' - f' cannot be older than the linked gencode version. {error_prompt}' - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py deleted file mode 100644 index 8760be50ce9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/service_reflection.py +++ /dev/null @@ -1,284 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -"""Contains metaclasses used to create protocol service and service stub - -classes from ServiceDescriptor objects at runtime. - -The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to -inject all useful functionality into the classes output by the protocol -compiler at compile-time. -""" - -__author__ = 'petar@google.com (Petar Petrov)' - - -class GeneratedServiceType(type): - """Metaclass for service classes created at runtime from ServiceDescriptors. - - Implementations for all methods described in the Service class are added here - by this class. We also create properties to allow getting/setting all fields - in the protocol message. - - The protocol compiler currently uses this metaclass to create protocol service - classes at runtime. Clients can also manually create their own classes at - runtime, as in this example:: - - mydescriptor = ServiceDescriptor(.....) - class MyProtoService(service.Service): - __metaclass__ = GeneratedServiceType - DESCRIPTOR = mydescriptor - myservice_instance = MyProtoService() - # ... - """ - - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __init__(cls, name, bases, dictionary): - """Creates a message service class. - - Args: - name: Name of the class (ignored, but required by the metaclass protocol). - bases: Base classes of the class being constructed. - dictionary: The class dictionary of the class being constructed. - dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object - describing this protocol service type. - """ - # Don't do anything if this class doesn't have a descriptor. This happens - # when a service class is subclassed. - if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary: - return - - descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY] - service_builder = _ServiceBuilder(descriptor) - service_builder.BuildService(cls) - cls.DESCRIPTOR = descriptor - - -class GeneratedServiceStubType(GeneratedServiceType): - """Metaclass for service stubs created at runtime from ServiceDescriptors. - - This class has similar responsibilities as GeneratedServiceType, except that - it creates the service stub classes. - """ - - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __init__(cls, name, bases, dictionary): - """Creates a message service stub class. - - Args: - name: Name of the class (ignored, here). - bases: Base classes of the class being constructed. - dictionary: The class dictionary of the class being constructed. - dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object - describing this protocol service type. - """ - super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary) - # Don't do anything if this class doesn't have a descriptor. This happens - # when a service stub is subclassed. - if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary: - return - - descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] - service_stub_builder = _ServiceStubBuilder(descriptor) - service_stub_builder.BuildServiceStub(cls) - - -class _ServiceBuilder(object): - """This class constructs a protocol service class using a service descriptor. - - Given a service descriptor, this class constructs a class that represents - the specified service descriptor. One service builder instance constructs - exactly one service class. That means all instances of that class share the - same builder. - """ - - def __init__(self, service_descriptor): - """Initializes an instance of the service class builder. - - Args: - service_descriptor: ServiceDescriptor to use when constructing the service - class. - """ - self.descriptor = service_descriptor - - def BuildService(builder, cls): - """Constructs the service class. - - Args: - cls: The class that will be constructed. - """ - - # CallMethod needs to operate with an instance of the Service class. This - # internal wrapper function exists only to be able to pass the service - # instance to the method that does the real CallMethod work. - # Making sure to use exact argument names from the abstract interface in - # service.py to match the type signature - def _WrapCallMethod(self, method_descriptor, rpc_controller, request, done): - return builder._CallMethod( - self, method_descriptor, rpc_controller, request, done - ) - - def _WrapGetRequestClass(self, method_descriptor): - return builder._GetRequestClass(method_descriptor) - - def _WrapGetResponseClass(self, method_descriptor): - return builder._GetResponseClass(method_descriptor) - - builder.cls = cls - cls.CallMethod = _WrapCallMethod - cls.GetDescriptor = staticmethod(lambda: builder.descriptor) - cls.GetDescriptor.__doc__ = 'Returns the service descriptor.' - cls.GetRequestClass = _WrapGetRequestClass - cls.GetResponseClass = _WrapGetResponseClass - for method in builder.descriptor.methods: - setattr(cls, method.name, builder._GenerateNonImplementedMethod(method)) - - def _CallMethod( - self, srvc, method_descriptor, rpc_controller, request, callback - ): - """Calls the method described by a given method descriptor. - - Args: - srvc: Instance of the service for which this method is called. - method_descriptor: Descriptor that represent the method to call. - rpc_controller: RPC controller to use for this method's execution. - request: Request protocol message. - callback: A callback to invoke after the method has completed. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'CallMethod() given method descriptor for wrong service type.' - ) - method = getattr(srvc, method_descriptor.name) - return method(rpc_controller, request, callback) - - def _GetRequestClass(self, method_descriptor): - """Returns the class of the request protocol message. - - Args: - method_descriptor: Descriptor of the method for which to return the - request protocol message class. - - Returns: - A class that represents the input protocol message of the specified - method. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'GetRequestClass() given method descriptor for wrong service type.' - ) - return method_descriptor.input_type._concrete_class - - def _GetResponseClass(self, method_descriptor): - """Returns the class of the response protocol message. - - Args: - method_descriptor: Descriptor of the method for which to return the - response protocol message class. - - Returns: - A class that represents the output protocol message of the specified - method. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'GetResponseClass() given method descriptor for wrong service type.' - ) - return method_descriptor.output_type._concrete_class - - def _GenerateNonImplementedMethod(self, method): - """Generates and returns a method that can be set for a service methods. - - Args: - method: Descriptor of the service method for which a method is to be - generated. - - Returns: - A method that can be added to the service class. - """ - return lambda inst, rpc_controller, request, callback: ( - self._NonImplementedMethod(method.name, rpc_controller, callback) - ) - - def _NonImplementedMethod(self, method_name, rpc_controller, callback): - """The body of all methods in the generated service class. - - Args: - method_name: Name of the method being executed. - rpc_controller: RPC controller used to execute this method. - callback: A callback which will be invoked when the method finishes. - """ - rpc_controller.SetFailed('Method %s not implemented.' % method_name) - callback(None) - - -class _ServiceStubBuilder(object): - """Constructs a protocol service stub class using a service descriptor. - - Given a service descriptor, this class constructs a suitable stub class. - A stub is just a type-safe wrapper around an RpcChannel which emulates a - local implementation of the service. - - One service stub builder instance constructs exactly one class. It means all - instances of that class share the same service stub builder. - """ - - def __init__(self, service_descriptor): - """Initializes an instance of the service stub class builder. - - Args: - service_descriptor: ServiceDescriptor to use when constructing the stub - class. - """ - self.descriptor = service_descriptor - - def BuildServiceStub(self, cls): - """Constructs the stub class. - - Args: - cls: The class that will be constructed. - """ - - def _ServiceStubInit(stub, rpc_channel): - stub.rpc_channel = rpc_channel - - self.cls = cls - cls.__init__ = _ServiceStubInit - for method in self.descriptor.methods: - setattr(cls, method.name, self._GenerateStubMethod(method)) - - def _GenerateStubMethod(self, method): - return ( - lambda inst, rpc_controller, request, callback=None: self._StubMethod( - inst, method, rpc_controller, request, callback - ) - ) - - def _StubMethod( - self, stub, method_descriptor, rpc_controller, request, callback - ): - """The body of all service methods in the generated stub class. - - Args: - stub: Stub instance. - method_descriptor: Descriptor of the invoked method. - rpc_controller: Rpc controller to execute the method. - request: Request protocol message. - callback: A callback to execute when the method finishes. - - Returns: - Response message (in case of blocking call). - """ - return stub.rpc_channel.CallMethod( - method_descriptor, - rpc_controller, - request, - method_descriptor.output_type._concrete_class, - callback, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py deleted file mode 100644 index 53baf277947..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/source_context_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/source_context.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/source_context.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$google/protobuf/source_context.proto\x12\x0fgoogle.protobuf\",\n\rSourceContext\x12\x1b\n\tfile_name\x18\x01 \x01(\tR\x08\x66ileNameB\x8a\x01\n\x13\x63om.google.protobufB\x12SourceContextProtoP\x01Z6google.golang.org/protobuf/types/known/sourcecontextpb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.source_context_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\022SourceContextProtoP\001Z6google.golang.org/protobuf/types/known/sourcecontextpb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_SOURCECONTEXT']._serialized_start=57 - _globals['_SOURCECONTEXT']._serialized_end=101 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py deleted file mode 100644 index 33ce4e37a47..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/struct_pb2.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/struct.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/struct.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cgoogle/protobuf/struct.proto\x12\x0fgoogle.protobuf\"\x98\x01\n\x06Struct\x12;\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.protobuf.Struct.FieldsEntryR\x06\x66ields\x1aQ\n\x0b\x46ieldsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.ValueR\x05value:\x02\x38\x01\"\xb2\x02\n\x05Value\x12;\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12#\n\x0cnumber_value\x18\x02 \x01(\x01H\x00R\x0bnumberValue\x12#\n\x0cstring_value\x18\x03 \x01(\tH\x00R\x0bstringValue\x12\x1f\n\nbool_value\x18\x04 \x01(\x08H\x00R\tboolValue\x12<\n\x0cstruct_value\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x00R\x0bstructValue\x12;\n\nlist_value\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.ListValueH\x00R\tlistValueB\x06\n\x04kind\";\n\tListValue\x12.\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.ValueR\x06values*\x1b\n\tNullValue\x12\x0e\n\nNULL_VALUE\x10\x00\x42\x7f\n\x13\x63om.google.protobufB\x0bStructProtoP\x01Z/google.golang.org/protobuf/types/known/structpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.struct_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\013StructProtoP\001Z/google.golang.org/protobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_STRUCT_FIELDSENTRY']._loaded_options = None - _globals['_STRUCT_FIELDSENTRY']._serialized_options = b'8\001' - _globals['_NULLVALUE']._serialized_start=574 - _globals['_NULLVALUE']._serialized_end=601 - _globals['_STRUCT']._serialized_start=50 - _globals['_STRUCT']._serialized_end=202 - _globals['_STRUCT_FIELDSENTRY']._serialized_start=121 - _globals['_STRUCT_FIELDSENTRY']._serialized_end=202 - _globals['_VALUE']._serialized_start=205 - _globals['_VALUE']._serialized_end=511 - _globals['_LISTVALUE']._serialized_start=513 - _globals['_LISTVALUE']._serialized_end=572 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py deleted file mode 100644 index 3055ddc27d4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/symbol_database.py +++ /dev/null @@ -1,178 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""A database of Python protocol buffer generated symbols. - -SymbolDatabase is the MessageFactory for messages generated at compile time, -and makes it easy to create new instances of a registered type, given only the -type's protocol buffer symbol name. - -Example usage:: - - db = symbol_database.SymbolDatabase() - - # Register symbols of interest, from one or multiple files. - db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR) - db.RegisterMessage(my_proto_pb2.MyMessage) - db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR) - - # The database can be used as a MessageFactory, to generate types based on - # their name: - types = db.GetMessages(['my_proto.proto']) - my_message_instance = types['MyMessage']() - - # The database's underlying descriptor pool can be queried, so it's not - # necessary to know a type's filename to be able to generate it: - filename = db.pool.FindFileContainingSymbol('MyMessage') - my_message_instance = db.GetMessages([filename])['MyMessage']() - - # This functionality is also provided directly via a convenience method: - my_message_instance = db.GetSymbol('MyMessage')() -""" - -import warnings - -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import message_factory -from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation - - -class SymbolDatabase: - """A database of Python generated symbols.""" - - # local cache of registered classes. - _classes = {} - - def __init__(self, pool=None): - """Initializes a new SymbolDatabase.""" - self.pool = pool or descriptor_pool.DescriptorPool() - - def RegisterMessage(self, message): - """Registers the given message type in the local database. - - Calls to GetSymbol() and GetMessages() will return messages registered here. - - Args: - message: A :class:`google.protobuf.message.Message` subclass (or - instance); its descriptor will be registered. - - Returns: - The provided message. - """ - - desc = message.DESCRIPTOR - self._classes[desc] = message - self.RegisterMessageDescriptor(desc) - return message - - def RegisterMessageDescriptor(self, message_descriptor): - """Registers the given message descriptor in the local database. - - Args: - message_descriptor (Descriptor): the message descriptor to add. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddDescriptor(message_descriptor) - - def RegisterEnumDescriptor(self, enum_descriptor): - """Registers the given enum descriptor in the local database. - - Args: - enum_descriptor (EnumDescriptor): The enum descriptor to register. - - Returns: - EnumDescriptor: The provided descriptor. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddEnumDescriptor(enum_descriptor) - return enum_descriptor - - def RegisterServiceDescriptor(self, service_descriptor): - """Registers the given service descriptor in the local database. - - Args: - service_descriptor (ServiceDescriptor): the service descriptor to - register. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddServiceDescriptor(service_descriptor) - - def RegisterFileDescriptor(self, file_descriptor): - """Registers the given file descriptor in the local database. - - Args: - file_descriptor (FileDescriptor): The file descriptor to register. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._InternalAddFileDescriptor(file_descriptor) - - def GetSymbol(self, symbol): - """Tries to find a symbol in the local database. - - Currently, this method only returns message.Message instances, however, if - may be extended in future to support other symbol types. - - Args: - symbol (str): a protocol buffer symbol. - - Returns: - A Python class corresponding to the symbol. - - Raises: - KeyError: if the symbol could not be found. - """ - - return self._classes[self.pool.FindMessageTypeByName(symbol)] - - def GetMessages(self, files): - # TODO: Fix the differences with MessageFactory. - """Gets all registered messages from a specified file. - - Only messages already created and registered will be returned; (this is the - case for imported _pb2 modules) - But unlike MessageFactory, this version also returns already defined nested - messages, but does not register any message extensions. - - Args: - files (list[str]): The file names to extract messages from. - - Returns: - A dictionary mapping proto names to the message classes. - - Raises: - KeyError: if a file could not be found. - """ - - def _GetAllMessages(desc): - """Walk a message Descriptor and recursively yields all message names.""" - yield desc - for msg_desc in desc.nested_types: - for nested_desc in _GetAllMessages(msg_desc): - yield nested_desc - - result = {} - for file_name in files: - file_desc = self.pool.FindFileByName(file_name) - for msg_desc in file_desc.message_types_by_name.values(): - for desc in _GetAllMessages(msg_desc): - try: - result[desc.full_name] = self._classes[desc] - except KeyError: - # This descriptor has no registered class, skip it. - pass - return result - - -_DEFAULT = SymbolDatabase(pool=descriptor_pool.Default()) - - -def Default(): - """Returns the default SymbolDatabase.""" - return _DEFAULT diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py deleted file mode 100644 index 294a4624200..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_encoding.py +++ /dev/null @@ -1,111 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Encoding related utilities.""" - -import re - - -def _AsciiIsPrint(i): - return i >= 32 and i < 127 - - -def _MakeStrEscapes(): - ret = {} - for i in range(0, 128): - if not _AsciiIsPrint(i): - ret[i] = r'\%03o' % i - ret[ord('\t')] = r'\t' # optional escape - ret[ord('\n')] = r'\n' # optional escape - ret[ord('\r')] = r'\r' # optional escape - ret[ord('"')] = r'\"' # necessary escape - ret[ord("'")] = r'\'' # optional escape - ret[ord('\\')] = r'\\' # necessary escape - return ret - - -# Maps int -> char, performing string escapes. -_str_escapes = _MakeStrEscapes() - -# Maps int -> char, performing byte escaping and string escapes -_byte_escapes = {i: chr(i) for i in range(0, 256)} -_byte_escapes.update(_str_escapes) -_byte_escapes.update({i: r'\%03o' % i for i in range(128, 256)}) - - -def _DecodeUtf8EscapeErrors(text_bytes): - ret = '' - while text_bytes: - try: - ret += text_bytes.decode('utf-8').translate(_str_escapes) - text_bytes = '' - except UnicodeDecodeError as e: - ret += text_bytes[: e.start].decode('utf-8').translate(_str_escapes) - ret += _byte_escapes[text_bytes[e.start]] - text_bytes = text_bytes[e.start + 1 :] - return ret - - -def CEscape(text, as_utf8) -> str: - """Escape a bytes string for use in an text protocol buffer. - - Args: - text: A byte string to be escaped. - as_utf8: Specifies if result may contain non-ASCII characters. In Python 3 - this allows unescaped non-ASCII Unicode characters. In Python 2 the return - value will be valid UTF-8 rather than only ASCII. - - Returns: - Escaped string (str). - """ - # Python's text.encode() 'string_escape' or 'unicode_escape' codecs do not - # satisfy our needs; they encodes unprintable characters using two-digit hex - # escapes whereas our C++ unescaping function allows hex escapes to be any - # length. So, "\0011".encode('string_escape') ends up being "\\x011", which - # will be decoded in C++ as a single-character string with char code 0x11. - text_is_unicode = isinstance(text, str) - if as_utf8: - if text_is_unicode: - return text.translate(_str_escapes) - else: - return _DecodeUtf8EscapeErrors(text) - else: - if text_is_unicode: - text = text.encode('utf-8') - return ''.join([_byte_escapes[c] for c in text]) - - -_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])') - - -def CUnescape(text: str) -> bytes: - """Unescape a text string with C-style escape sequences to UTF-8 bytes. - - Args: - text: The data to parse in a str. - - Returns: - A byte string. - """ - - def ReplaceHex(m): - # Only replace the match if the number of leading back slashes is odd. i.e. - # the slash itself is not escaped. - if len(m.group(1)) & 1: - return m.group(1) + 'x0' + m.group(2) - return m.group(0) - - # This is required because the 'string_escape' encoding doesn't - # allow single-digit hex escapes (like '\xf'). - result = _CUNESCAPE_HEX.sub(ReplaceHex, text) - - # Replaces Unicode escape sequences with their character equivalents. - result = result.encode('raw_unicode_escape').decode('raw_unicode_escape') - # Encode Unicode characters as UTF-8, then decode to Latin-1 escaping - # unprintable characters. - result = result.encode('utf-8').decode('unicode_escape') - # Convert Latin-1 text back to a byte string (latin-1 codec also works here). - return result.encode('latin-1') diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py deleted file mode 100644 index 947d72e6ff0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/text_format.py +++ /dev/null @@ -1,2089 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains routines for printing messages in Protobuf Text Format. - -Printing and parsing messages in Text Format is useful for debugging -and human editing of messages. - -Unlike the Binary and ProtoJSON formats, Text Format is not designed to be -used as a wire format; instead it is intended for human-in-the-loop -configuration use-cases. - -Systems processing untrusted inputs should strongly prefer to use Binary format -instead. If a textual format of untrusted inputs is required, consider using -ProtoJSON format instead. - -Simple usage example:: - - # Create a proto object and serialize it to a text proto string. - message = my_proto_pb2.MyMessage(foo='bar') - text_proto = text_format.MessageToString(message) - - # Parse a text proto string. - message = text_format.Parse(text_proto, my_proto_pb2.MyMessage()) -""" - -__author__ = 'kenton@google.com (Kenton Varda)' - -# TODO Import thread contention leads to test failures. -import encodings.raw_unicode_escape # pylint: disable=unused-import -import encodings.unicode_escape # pylint: disable=unused-import -import io -import math -import re -import warnings - -from opentelemetry.agent._vendor.google.protobuf.internal import decoder -from opentelemetry.agent._vendor.google.protobuf.internal import type_checkers -from opentelemetry.agent._vendor.google.protobuf import descriptor - -from opentelemetry.agent._vendor.google.protobuf import text_encoding -from opentelemetry.agent._vendor.google.protobuf import unknown_fields - -# pylint: disable=g-import-not-at-top -__all__ = [ - 'MessageToString', - 'Parse', - 'PrintMessage', - 'PrintField', - 'PrintFieldValue', - 'Merge', - 'MessageToBytes', -] - -_INTEGER_CHECKERS = ( - type_checkers.Uint32ValueChecker(), - type_checkers.Int32ValueChecker(), - type_checkers.Uint64ValueChecker(), - type_checkers.Int64ValueChecker(), -) -_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?$', re.IGNORECASE) -_FLOAT_NAN = re.compile('nanf?$', re.IGNORECASE) -_FLOAT_OCTAL_PREFIX = re.compile('-?0[0-9]+') -_PERCENT_ENCODING = re.compile(r'^%[\da-fA-F][\da-fA-F]$') -_TYPE_NAME = re.compile(r'^[^\d\W]\w*(\.[^\d\W]\w*)*$') -_QUOTES = frozenset(("'", '"')) -_ANY_FULL_TYPE_NAME = 'google.protobuf.Any' -_DEBUG_STRING_SILENT_MARKER = '\t ' - -_as_utf8_default = True - - -class Error(Exception): - """Top-level module error for text_format.""" - - -class ParseError(Error): - """Thrown in case of text parsing or tokenizing error.""" - - def __init__(self, message=None, line=None, column=None): - if message is not None and line is not None: - loc = str(line) - if column is not None: - loc += ':{0}'.format(column) - message = '{0} : {1}'.format(loc, message) - if message is not None: - super(ParseError, self).__init__(message) - else: - super(ParseError, self).__init__() - self._line = line - self._column = column - - def GetLine(self): - return self._line - - def GetColumn(self): - return self._column - - -class TextWriter(object): - - def __init__(self, as_utf8): - self._writer = io.StringIO() - - def write(self, val): - return self._writer.write(val) - - def close(self): - return self._writer.close() - - def getvalue(self): - return self._writer.getvalue() - - -def MessageToString( - message, - as_utf8=_as_utf8_default, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - use_field_number=False, - descriptor_pool=None, - indent=0, - message_formatter=None, - print_unknown_fields=False, - force_colon=False, -) -> str: - """Convert protobuf message to text format. - - Args: - message: The protocol buffers message. - as_utf8: Return unescaped Unicode for non-ASCII characters. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, fields of a proto message will be printed using - the order defined in source code instead of the field number, extensions - will be printed at the end of the message and their relative order is - determined by the extension number. By default, use the field number - order. - use_field_number: If True, print field numbers instead of names. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - indent (int): The initial indent level, in terms of spaces, for pretty - print. - message_formatter (function(message, indent, as_one_line) -> unicode|None): - Custom formatter for selected sub-messages (usually based on message - type). Use to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if the - field is a proto message. - - Returns: - str: A string of the text formatted protocol buffer message. - """ - out = TextWriter(as_utf8) - printer = _Printer( - out=out, - indent=indent, - as_utf8=as_utf8, - as_one_line=as_one_line, - use_short_repeated_primitives=use_short_repeated_primitives, - pointy_brackets=pointy_brackets, - use_index_order=use_index_order, - use_field_number=use_field_number, - descriptor_pool=descriptor_pool, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon, - ) - printer.PrintMessage(message) - result = out.getvalue() - out.close() - if as_one_line: - return result.rstrip() - return result - - -def MessageToBytes(message, **kwargs) -> bytes: - """Convert protobuf message to encoded text format. See MessageToString.""" - text = MessageToString(message, **kwargs) - if isinstance(text, bytes): - return text - codec = 'utf-8' if kwargs.get('as_utf8') else 'ascii' - return text.encode(codec) - - -def _IsMapEntry(field): - return ( - field.type == descriptor.FieldDescriptor.TYPE_MESSAGE - and field.message_type.has_options - and field.message_type.GetOptions().map_entry - ) - - -def _IsGroupLike(field): - """Determines if a field is consistent with a proto2 group. - - Args: - field: The field descriptor. - - Returns: - True if this field is group-like, false otherwise. - """ - # Groups are always tag-delimited. - if field.type != descriptor.FieldDescriptor.TYPE_GROUP: - return False - - # Group fields always are always the lowercase type name. - if field.name != field.message_type.name.lower(): - return False - - if field.message_type.file != field.file: - return False - - # Group messages are always defined in the same scope as the field. File - # level extensions will compare NULL == NULL here, which is why the file - # comparison above is necessary to ensure both come from the same file. - return ( - field.message_type.containing_type == field.extension_scope - if field.is_extension - else field.message_type.containing_type == field.containing_type - ) - - -def PrintMessage( - message, - out, - indent=0, - as_utf8=_as_utf8_default, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - use_field_number=False, - descriptor_pool=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False, -): - """Convert the message to text format and write it to the out stream. - - Args: - message: The Message object to convert to text format. - out: A file handle to write the message to. - indent: The initial indent level for pretty print. - as_utf8: Return unescaped Unicode for non-ASCII characters. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, print fields of a proto message using the order - defined in source code instead of the field number. By default, use the - field number order. - use_field_number: If True, print field numbers instead of names. - descriptor_pool: A DescriptorPool used to resolve Any types. - message_formatter: A function(message, indent, as_one_line): unicode|None to - custom format selected sub-messages (usually based on message type). Use - to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if the - field is a proto message. - """ - printer = _Printer( - out=out, - indent=indent, - as_utf8=as_utf8, - as_one_line=as_one_line, - use_short_repeated_primitives=use_short_repeated_primitives, - pointy_brackets=pointy_brackets, - use_index_order=use_index_order, - use_field_number=use_field_number, - descriptor_pool=descriptor_pool, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon, - ) - printer.PrintMessage(message) - - -def PrintField( - field, - value, - out, - indent=0, - as_utf8=_as_utf8_default, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - message_formatter=None, - print_unknown_fields=False, - force_colon=False, -): - """Print a single field name/value pair.""" - printer = _Printer( - out, - indent, - as_utf8, - as_one_line, - use_short_repeated_primitives, - pointy_brackets, - use_index_order, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon, - ) - printer.PrintField(field, value) - - -def PrintFieldValue( - field, - value, - out, - indent=0, - as_utf8=_as_utf8_default, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - message_formatter=None, - print_unknown_fields=False, - force_colon=False, -): - """Print a single field value (not including name).""" - printer = _Printer( - out, - indent, - as_utf8, - as_one_line, - use_short_repeated_primitives, - pointy_brackets, - use_index_order, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon, - ) - printer.PrintFieldValue(field, value) - - -def _BuildMessageFromTypeName(type_name, descriptor_pool): - """Returns a protobuf message instance. - - Args: - type_name: Fully-qualified protobuf message type name string. - descriptor_pool: DescriptorPool instance. - - Returns: - A Message instance of type matching type_name, or None if the a Descriptor - wasn't found matching type_name. - """ - # pylint: disable=g-import-not-at-top - if descriptor_pool is None: - from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as pool_mod - - descriptor_pool = pool_mod.Default() - from opentelemetry.agent._vendor.google.protobuf import message_factory - - try: - message_descriptor = descriptor_pool.FindMessageTypeByName(type_name) - except KeyError: - return None - message_type = message_factory.GetMessageClass(message_descriptor) - return message_type() - - -# These values must match WireType enum in //google/protobuf/wire_format.h. -WIRETYPE_LENGTH_DELIMITED = 2 -WIRETYPE_START_GROUP = 3 - - -class _Printer(object): - """Text format printer for protocol message.""" - - def __init__( - self, - out, - indent=0, - as_utf8=_as_utf8_default, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - use_field_number=False, - descriptor_pool=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False, - ): - """Initialize the Printer. - - Args: - out: To record the text format result. - indent: The initial indent level for pretty print. - as_utf8: Return unescaped Unicode for non-ASCII characters. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, print fields of a proto message using the order - defined in source code instead of the field number. By default, use the - field number order. - use_field_number: If True, print field numbers instead of names. - descriptor_pool: A DescriptorPool used to resolve Any types. - message_formatter: A function(message, indent, as_one_line): unicode|None - to custom format selected sub-messages (usually based on message type). - Use to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if - the field is a proto message. - """ - self.out = out - self.indent = indent - self.as_utf8 = as_utf8 - self.as_one_line = as_one_line - self.use_short_repeated_primitives = use_short_repeated_primitives - self.pointy_brackets = pointy_brackets - self.use_index_order = use_index_order - self.use_field_number = use_field_number - self.descriptor_pool = descriptor_pool - self.message_formatter = message_formatter - self.print_unknown_fields = print_unknown_fields - self.force_colon = force_colon - - def _TryPrintAsAnyMessage(self, message): - """Serializes if message is a google.protobuf.Any field.""" - if '/' not in message.type_url: - return False - packed_message = _BuildMessageFromTypeName( - message.TypeName(), self.descriptor_pool - ) - if packed_message is not None: - packed_message.MergeFromString(message.value) - colon = ':' if self.force_colon else '' - self.out.write('%s[%s]%s ' % (self.indent * ' ', message.type_url, colon)) - self._PrintMessageFieldValue(packed_message) - self.out.write(' ' if self.as_one_line else '\n') - return True - else: - return False - - def _TryCustomFormatMessage(self, message): - formatted = self.message_formatter(message, self.indent, self.as_one_line) - if formatted is None: - return False - - out = self.out - out.write(' ' * self.indent) - out.write(formatted) - out.write(' ' if self.as_one_line else '\n') - return True - - def PrintMessage(self, message): - """Convert protobuf message to text format. - - Args: - message: The protocol buffers message. - """ - if self.message_formatter and self._TryCustomFormatMessage(message): - return - if ( - message.DESCRIPTOR.full_name == _ANY_FULL_TYPE_NAME - and self._TryPrintAsAnyMessage(message) - ): - return - fields = message.ListFields() - if self.use_index_order: - fields.sort( - key=lambda x: x[0].number if x[0].is_extension else x[0].index - ) - for field, value in fields: - if _IsMapEntry(field): - for key in sorted(value): - # This is slow for maps with submessage entries because it copies the - # entire tree. Unfortunately this would take significant refactoring - # of this file to work around. - # - # TODO: refactor and optimize if this becomes an issue. - entry_submsg = value.GetEntryClass()(key=key, value=value[key]) - self.PrintField(field, entry_submsg) - elif field.is_repeated: - if ( - self.use_short_repeated_primitives - and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE - and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_STRING - ): - self._PrintShortRepeatedPrimitivesValue(field, value) - else: - for element in value: - self.PrintField(field, element) - else: - self.PrintField(field, value) - - if self.print_unknown_fields: - self._PrintUnknownFields(unknown_fields.UnknownFieldSet(message)) - - def _PrintUnknownFields(self, unknown_field_set): - """Print unknown fields.""" - out = self.out - for field in unknown_field_set: - out.write(' ' * self.indent) - out.write(str(field.field_number)) - if field.wire_type == WIRETYPE_START_GROUP: - if self.as_one_line: - out.write(' { ') - else: - out.write(' {\n') - self.indent += 2 - - self._PrintUnknownFields(field.data) - - if self.as_one_line: - out.write('} ') - else: - self.indent -= 2 - out.write(' ' * self.indent + '}\n') - elif field.wire_type == WIRETYPE_LENGTH_DELIMITED: - try: - # If this field is parseable as a Message, it is probably - # an embedded message. - # pylint: disable=protected-access - embedded_unknown_message, pos = decoder._DecodeUnknownFieldSet( - memoryview(field.data), 0, len(field.data) - ) - except Exception: # pylint: disable=broad-except - pos = 0 - - if pos == len(field.data): - if self.as_one_line: - out.write(' { ') - else: - out.write(' {\n') - self.indent += 2 - - self._PrintUnknownFields(embedded_unknown_message) - - if self.as_one_line: - out.write('} ') - else: - self.indent -= 2 - out.write(' ' * self.indent + '}\n') - else: - # A string or bytes field. self.as_utf8 may not work. - out.write(': "') - out.write(text_encoding.CEscape(field.data, False)) - out.write('" ' if self.as_one_line else '"\n') - else: - # varint, fixed32, fixed64 - out.write(': ') - out.write(str(field.data)) - out.write(' ' if self.as_one_line else '\n') - - def _PrintFieldName(self, field): - """Print field name.""" - out = self.out - out.write(' ' * self.indent) - if self.use_field_number: - out.write(str(field.number)) - else: - if field.is_extension: - out.write('[') - if ( - field.containing_type.GetOptions().message_set_wire_format - and field.type == descriptor.FieldDescriptor.TYPE_MESSAGE - and not field.is_required - and not field.is_repeated - ): - out.write(field.message_type.full_name) - else: - out.write(field.full_name) - out.write(']') - elif _IsGroupLike(field): - # For groups, use the capitalized name. - out.write(field.message_type.name) - else: - out.write(field.name) - - if ( - self.force_colon - or field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE - ): - # The colon is optional in this case, but our cross-language golden files - # don't include it. Here, the colon is only included if force_colon is - # set to True - out.write(':') - - def PrintField(self, field, value): - """Print a single field name/value pair.""" - self._PrintFieldName(field) - self.out.write(' ') - self.PrintFieldValue(field, value) - self.out.write(' ' if self.as_one_line else '\n') - - def _PrintShortRepeatedPrimitivesValue(self, field, value): - """ "Prints short repeated primitives value.""" - # Note: this is called only when value has at least one element. - self._PrintFieldName(field) - self.out.write(' [') - for i in range(len(value) - 1): - self.PrintFieldValue(field, value[i]) - self.out.write(', ') - self.PrintFieldValue(field, value[-1]) - self.out.write(']') - self.out.write(' ' if self.as_one_line else '\n') - - def _PrintMessageFieldValue(self, value): - if self.pointy_brackets: - openb = '<' - closeb = '>' - else: - openb = '{' - closeb = '}' - - if self.as_one_line: - self.out.write('%s ' % openb) - self.PrintMessage(value) - self.out.write(closeb) - else: - self.out.write('%s\n' % openb) - self.indent += 2 - self.PrintMessage(value) - self.indent -= 2 - self.out.write(' ' * self.indent + closeb) - - def PrintFieldValue(self, field, value): - """Print a single field value (not including name). - - For repeated fields, the value should be a single element. - - Args: - field: The descriptor of the field to be printed. - value: The value of the field. - """ - out = self.out - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self._PrintMessageFieldValue(value) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - enum_value = field.enum_type.values_by_number.get(value, None) - if enum_value is not None: - out.write(enum_value.name) - else: - out.write(str(value)) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - out.write('"') - if isinstance(value, str) and not self.as_utf8: - out_value = value.encode('utf-8') - else: - out_value = value - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - # We always need to escape all binary data in TYPE_BYTES fields. - out_as_utf8 = False - else: - out_as_utf8 = self.as_utf8 - out.write(text_encoding.CEscape(out_value, out_as_utf8)) - out.write('"') - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - if value: - out.write('true') - else: - out.write('false') - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: - if math.isnan(value): - out.write(str(value)) - else: - out.write(str(type_checkers.ToShortestFloat(value))) - else: - out.write(str(value)) - - -def Parse( - text, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False, - max_recursion_depth=None, -): - """Parses a text representation of a protocol message into a message. - - NOTE: for historical reasons this function does not clear the input - message. This is different from what the binary msg.ParseFrom(...) does. - If text contains a field already set in message, the value is appended if the - field is repeated. Otherwise, an error is raised. - - Example:: - - a = MyProto() - a.repeated_field.append('test') - b = MyProto() - - # Repeated fields are combined - text_format.Parse(repr(a), b) - text_format.Parse(repr(a), b) # repeated_field contains ["test", "test"] - - # Non-repeated fields cannot be overwritten - a.singular_field = 1 - b.singular_field = 2 - text_format.Parse(repr(a), b) # ParseError - - # Binary version: - b.ParseFromString(a.SerializeToString()) # repeated_field is now "test" - - Caller is responsible for clearing the message as needed. - - Args: - text (str): Message text representation. - message (Message): A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep parsing. - Avoid to use this option if possible. It may hide some errors (e.g. - spelling error on field name) - max_recursion_depth: Optional maximum recursion depth of the message to be - parsed: Text Format inputs over this depth will fail to parse. ``None`` - means no additional limit (the Python runtime will enforce some limit - due to call stack limits). As Text Format is primarily intended to be - used on trusted configuration inputs, and to maintain backwards - compatibility, the default of ``None`` (unbounded) is intentional. For - better consistency with what messages will successfully round trip - through binary wire format, or for the discouraged case of processing - untrusted Text Format inputs, setting a limit of 100 is recommended. - - Returns: - Message: The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - return ParseLines( - text.split(b'\n' if isinstance(text, bytes) else '\n'), - message, - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field, - max_recursion_depth=max_recursion_depth, - ) - - -def Merge( - text, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False, - max_recursion_depth=None, -): - """Parses a text representation of a protocol message into a message. - - Like Parse(), but allows repeated values for a non-repeated field, and uses - the last one. This means any non-repeated, top-level fields specified in text - replace those in the message. - - Args: - text (str): Message text representation. - message (Message): A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep parsing. - Avoid to use this option if possible. It may hide some errors (e.g. - spelling error on field name) - max_recursion_depth: Optional maximum recursion depth of the message to be - parsed: Text Format inputs over this depth will fail to parse. ``None`` - means no additional limit (the Python runtime will enforce some limit - due to call stack limits). As Text Format is primarily intended to be - used on trusted configuration inputs, and to maintain backwards - compatibility, the default of ``None`` (unbounded) is intentional. For - better consistency with what messages will successfully round trip - through binary wire format, or for the discouraged case of processing - untrusted Text Format inputs, setting a limit of 100 is recommended. - - Returns: - Message: The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - return MergeLines( - text.split(b'\n' if isinstance(text, bytes) else '\n'), - message, - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field, - max_recursion_depth=max_recursion_depth, - ) - - -def ParseLines( - lines, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False, - max_recursion_depth=None, -): - """Parses a text representation of a protocol message into a message. - - See Parse() for caveats. - - Args: - lines: An iterable of lines of a message's text representation. - message: A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep parsing. - Avoid to use this option if possible. It may hide some errors (e.g. - spelling error on field name) - max_recursion_depth: Optional maximum recursion depth of the message to be - parsed: Text Format inputs over this depth will fail to parse. ``None`` - means no additional limit (the Python runtime will enforce some limit - due to call stack limits). As Text Format is primarily intended to be - used on trusted configuration inputs, and to maintain backwards - compatibility, the default of ``None`` (unbounded) is intentional. For - better consistency with what messages will successfully round trip - through binary wire format, or for the discouraged case of processing - untrusted Text Format inputs, setting a limit of 100 is recommended. - - Returns: - The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - parser = _Parser( - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field, - max_recursion_depth=max_recursion_depth, - ) - return parser.ParseLines(lines, message) - - -def MergeLines( - lines, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False, - max_recursion_depth=None, -): - """Parses a text representation of a protocol message into a message. - - See Merge() for more details. - - Args: - lines: An iterable of lines of a message's text representation. - message: A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep parsing. - Avoid to use this option if possible. It may hide some errors (e.g. - spelling error on field name) - max_recursion_depth: Optional maximum recursion depth of the message to be - parsed: Text Format inputs over this depth will fail to parse. ``None`` - means no additional limit (the Python runtime will enforce some limit - due to call stack limits). As Text Format is primarily intended to be - used on trusted configuration inputs, and to maintain backwards - compatibility, the default of ``None`` (unbounded) is intentional. For - better consistency with what messages will successfully round trip - through binary wire format, or for the discouraged case of processing - untrusted Text Format inputs, setting a limit of 100 is recommended. - - Returns: - The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - parser = _Parser( - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field, - max_recursion_depth=max_recursion_depth, - ) - return parser.MergeLines(lines, message) - - -class _Parser(object): - """Text format parser for protocol message.""" - - def __init__( - self, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False, - max_recursion_depth=None, - ): - self.allow_unknown_extension = allow_unknown_extension - self.allow_field_number = allow_field_number - self.descriptor_pool = descriptor_pool - self.allow_unknown_field = allow_unknown_field - self.max_recursion_depth = max_recursion_depth - self.recursion_depth = 0 - - def ParseLines(self, lines, message): - """Parses a text representation of a protocol message into a message.""" - self._allow_multiple_scalars = False - self._ParseOrMerge(lines, message) - return message - - def MergeLines(self, lines, message): - """Merges a text representation of a protocol message into a message.""" - self._allow_multiple_scalars = True - self._ParseOrMerge(lines, message) - return message - - def _ParseOrMerge(self, lines, message): - """Converts a text representation of a protocol message into a message. - - Args: - lines: Lines of a message's text representation. - message: A protocol buffer message to merge into. - - Raises: - ParseError: On text parsing problems. - """ - # Tokenize expects native str lines. - try: - str_lines = ( - line if isinstance(line, str) else line.decode('utf-8') - for line in lines - ) - tokenizer = Tokenizer(str_lines) - except UnicodeDecodeError as e: - raise ParseError from e - if message: - self.root_type = message.DESCRIPTOR.full_name - self.recursion_depth += 1 - if ( - self.max_recursion_depth is not None - and self.recursion_depth > self.max_recursion_depth - ): - raise ParseError( - 'Message too deep. Max recursion depth is {0}'.format( - self.max_recursion_depth - ) - ) - while not tokenizer.AtEnd(): - self._MergeField(tokenizer, message) - self.recursion_depth -= 1 - - def _MergeMessage(self, tokenizer, message, end_token): - self.recursion_depth += 1 - if ( - self.max_recursion_depth is not None - and self.recursion_depth > self.max_recursion_depth - ): - raise ParseError( - 'Message too deep. Max recursion depth is {0}'.format( - self.max_recursion_depth - ) - ) - while not tokenizer.TryConsume(end_token): - if tokenizer.AtEnd(): - raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token,)) - self._MergeField(tokenizer, message) - self.recursion_depth -= 1 - - def _MergeField(self, tokenizer, message): - """Merges a single protocol message field into a message. - - Args: - tokenizer: A tokenizer to parse the field name and values. - message: A protocol message to record the data. - - Raises: - ParseError: In case of text parsing problems. - """ - message_descriptor = message.DESCRIPTOR - if ( - message_descriptor.full_name == _ANY_FULL_TYPE_NAME - and tokenizer.TryConsume('[') - ): - type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer) - tokenizer.TryConsume(':') - self._DetectSilentMarker( - tokenizer, - message_descriptor.full_name, - type_url_prefix + '/' + packed_type_name, - ) - if tokenizer.TryConsume('<'): - expanded_any_end_token = '>' - else: - tokenizer.Consume('{') - expanded_any_end_token = '}' - expanded_any_sub_message = _BuildMessageFromTypeName( - packed_type_name, self.descriptor_pool - ) - # Direct comparison with None is used instead of implicit bool conversion - # to avoid false positives with falsy initial values, e.g. for - # google.protobuf.ListValue. - if expanded_any_sub_message is None: - raise ParseError( - 'Type %s not found in descriptor pool' % packed_type_name - ) - self._MergeMessage( - tokenizer, expanded_any_sub_message, expanded_any_end_token - ) - deterministic = False - - message.Pack( - expanded_any_sub_message, - type_url_prefix=type_url_prefix + '/', - deterministic=deterministic, - ) - return - - if tokenizer.TryConsume('['): - name = [tokenizer.ConsumeIdentifier()] - while tokenizer.TryConsume('.'): - name.append(tokenizer.ConsumeIdentifier()) - name = '.'.join(name) - - if not message_descriptor.is_extendable: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" does not have extensions.' - % message_descriptor.full_name - ) - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(name) - # pylint: enable=protected-access - if not field: - if self.allow_unknown_extension: - field = None - else: - raise tokenizer.ParseErrorPreviousToken( - 'Extension "%s" not registered. ' - 'Did you import the _pb2 module which defines it? ' - 'If you are trying to place the extension in the MessageSet ' - 'field of another message that is in an Any or MessageSet field, ' - "that message's _pb2 module must be imported as well" % name - ) - elif message_descriptor != field.containing_type: - raise tokenizer.ParseErrorPreviousToken( - 'Extension "%s" does not extend message type "%s".' - % (name, message_descriptor.full_name) - ) - - tokenizer.Consume(']') - - else: - name = tokenizer.ConsumeIdentifierOrNumber() - if self.allow_field_number and name.isdigit(): - number = ParseInteger(name, True, True) - field = message_descriptor.fields_by_number.get(number, None) - if not field and message_descriptor.is_extendable: - field = message.Extensions._FindExtensionByNumber(number) - else: - field = message_descriptor.fields_by_name.get(name, None) - - # Group names are expected to be capitalized as they appear in the - # .proto file, which actually matches their type names, not their field - # names. - if not field: - field = message_descriptor.fields_by_name.get(name.lower(), None) - if field and not _IsGroupLike(field): - field = None - if field and field.message_type.name != name: - field = None - - if not field and not self.allow_unknown_field: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" has no field named "%s".' - % (message_descriptor.full_name, name) - ) - - if field: - if not self._allow_multiple_scalars and field.containing_oneof: - # Check if there's a different field set in this oneof. - # Note that we ignore the case if the same field was set before, and we - # apply _allow_multiple_scalars to non-scalar fields as well. - which_oneof = message.WhichOneof(field.containing_oneof.name) - if which_oneof is not None and which_oneof != field.name: - raise tokenizer.ParseErrorPreviousToken( - 'Field "%s" is specified along with field "%s", another member ' - 'of oneof "%s" for message type "%s".' - % ( - field.name, - which_oneof, - field.containing_oneof.name, - message_descriptor.full_name, - ) - ) - - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - tokenizer.TryConsume(':') - self._DetectSilentMarker( - tokenizer, message_descriptor.full_name, field.full_name - ) - merger = self._MergeMessageField - else: - tokenizer.Consume(':') - self._DetectSilentMarker( - tokenizer, message_descriptor.full_name, field.full_name - ) - merger = self._MergeScalarField - - if field.is_repeated and tokenizer.TryConsume('['): - # Short repeated format, e.g. "foo: [1, 2, 3]" - if not tokenizer.TryConsume(']'): - while True: - merger(tokenizer, message, field) - if tokenizer.TryConsume(']'): - break - tokenizer.Consume(',') - - else: - merger(tokenizer, message, field) - - else: # Proto field is unknown. - assert self.allow_unknown_extension or self.allow_unknown_field - self._SkipFieldContents(tokenizer, name, message_descriptor.full_name) - - # For historical reasons, fields may optionally be separated by commas or - # semicolons. - if not tokenizer.TryConsume(','): - tokenizer.TryConsume(';') - - def _LogSilentMarker(self, immediate_message_type, field_name): - pass - - def _DetectSilentMarker(self, tokenizer, immediate_message_type, field_name): - if tokenizer.contains_silent_marker_before_current_token: - self._LogSilentMarker(immediate_message_type, field_name) - - def _ConsumeAnyTypeUrl(self, tokenizer): - """Consumes a google.protobuf.Any type URL. - - Assumes the caller has already consumed the opening [ and consumes up to the - closing ]. - - Args: - tokenizer: A tokenizer to parse the type URL. - - Returns: - A tuple of type URL prefix (without trailing slash) and type name. - """ - # Consume all tokens with valid URL characters until ]. Whitespace and - # comments are ignored/skipped by the Tokenizer. - tokens = [] - last_slash = -1 - while True: - try: - tokens.append(tokenizer.ConsumeUrlChars()) - continue - except ParseError: - pass - if tokenizer.TryConsume('/'): - last_slash = len(tokens) - tokens.append('/') - else: - tokenizer.Consume(']') - break - - if last_slash == -1: - raise tokenizer.ParseError('Type URL does not contain "/".') - - prefix = ''.join(tokens[:last_slash]) - name = ''.join(tokens[last_slash + 1 :]) - - if not prefix: - raise tokenizer.ParseError('Type URL prefix is empty.') - if prefix.startswith('/'): - raise tokenizer.ParseError('Type URL prefix starts with "/".') - - # Check for invalid percent encodings. '%' needs to be followed by exactly - # two valid hexadecimal digits. - for i, char in enumerate(prefix): - if char == '%' and not _PERCENT_ENCODING.match(prefix[i : i + 3]): - raise tokenizer.ParseError( - f'Invalid percent escape, got "{prefix[i : i + 3]}".' - ) - - # After the last slash we expect a valid type name, not just any sequence of - # URL characters. - if not _TYPE_NAME.match(name): - raise tokenizer.ParseError('Expected type name, got "%s".' % name) - - return prefix, name - - def _MergeMessageField(self, tokenizer, message, field): - """Merges a single scalar field into a message. - - Args: - tokenizer: A tokenizer to parse the field value. - message: The message of which field is a member. - field: The descriptor of the field to be merged. - - Raises: - ParseError: In case of text parsing problems. - """ - is_map_entry = _IsMapEntry(field) - - if tokenizer.TryConsume('<'): - end_token = '>' - else: - tokenizer.Consume('{') - end_token = '}' - - if field.is_repeated: - if field.is_extension: - sub_message = message.Extensions[field].add() - elif is_map_entry: - sub_message = getattr(message, field.name).GetEntryClass()() - else: - sub_message = getattr(message, field.name).add() - else: - if field.is_extension: - if not self._allow_multiple_scalars and message.HasExtension(field): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" extensions.' - % (message.DESCRIPTOR.full_name, field.full_name) - ) - sub_message = message.Extensions[field] - else: - # Also apply _allow_multiple_scalars to message field. - # TODO: Change to _allow_singular_overwrites. - if not self._allow_multiple_scalars and message.HasField(field.name): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" fields.' - % (message.DESCRIPTOR.full_name, field.name) - ) - sub_message = getattr(message, field.name) - sub_message.SetInParent() - - self._MergeMessage(tokenizer, sub_message, end_token) - - if is_map_entry: - value_cpptype = field.message_type.fields_by_name['value'].cpp_type - if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - value = getattr(message, field.name)[sub_message.key] - value.CopyFrom(sub_message.value) - else: - getattr(message, field.name)[sub_message.key] = sub_message.value - - def _MergeScalarField(self, tokenizer, message, field): - """Merges a single scalar field into a message. - - Args: - tokenizer: A tokenizer to parse the field value. - message: A protocol message to record the data. - field: The descriptor of the field to be merged. - - Raises: - ParseError: In case of text parsing problems. - RuntimeError: On runtime errors. - """ - _ = self.allow_unknown_extension - value = None - - if field.type in ( - descriptor.FieldDescriptor.TYPE_INT32, - descriptor.FieldDescriptor.TYPE_SINT32, - descriptor.FieldDescriptor.TYPE_SFIXED32, - ): - value = _ConsumeInt32(tokenizer) - elif field.type in ( - descriptor.FieldDescriptor.TYPE_INT64, - descriptor.FieldDescriptor.TYPE_SINT64, - descriptor.FieldDescriptor.TYPE_SFIXED64, - ): - value = _ConsumeInt64(tokenizer) - elif field.type in ( - descriptor.FieldDescriptor.TYPE_UINT32, - descriptor.FieldDescriptor.TYPE_FIXED32, - ): - value = _ConsumeUint32(tokenizer) - elif field.type in ( - descriptor.FieldDescriptor.TYPE_UINT64, - descriptor.FieldDescriptor.TYPE_FIXED64, - ): - value = _ConsumeUint64(tokenizer) - elif field.type in ( - descriptor.FieldDescriptor.TYPE_FLOAT, - descriptor.FieldDescriptor.TYPE_DOUBLE, - ): - value = tokenizer.ConsumeFloat() - elif field.type == descriptor.FieldDescriptor.TYPE_BOOL: - value = tokenizer.ConsumeBool() - elif field.type == descriptor.FieldDescriptor.TYPE_STRING: - value = tokenizer.ConsumeString() - elif field.type == descriptor.FieldDescriptor.TYPE_BYTES: - value = tokenizer.ConsumeByteString() - elif field.type == descriptor.FieldDescriptor.TYPE_ENUM: - value = tokenizer.ConsumeEnum(field) - else: - raise RuntimeError('Unknown field type %d' % field.type) - - if field.is_repeated: - if field.is_extension: - message.Extensions[field].append(value) - else: - getattr(message, field.name).append(value) - else: - if field.is_extension: - if ( - not self._allow_multiple_scalars - and field.has_presence - and message.HasExtension(field) - ): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" extensions.' - % (message.DESCRIPTOR.full_name, field.full_name) - ) - else: - message.Extensions[field] = value - else: - duplicate_error = False - if not self._allow_multiple_scalars: - if field.has_presence: - duplicate_error = message.HasField(field.name) - else: - # For field that doesn't represent presence, try best effort to - # check multiple scalars by compare to default values. - duplicate_error = not decoder.IsDefaultScalarValue( - getattr(message, field.name) - ) - - if duplicate_error: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" fields.' - % (message.DESCRIPTOR.full_name, field.name) - ) - else: - setattr(message, field.name, value) - - def _SkipFieldContents(self, tokenizer, field_name, immediate_message_type): - """Skips over contents (value or message) of a field. - - Args: - tokenizer: A tokenizer to parse the field name and values. - field_name: The field name currently being parsed. - immediate_message_type: The type of the message immediately containing the - silent marker. - """ - # Try to guess the type of this field. - # If this field is not a message, there should be a ":" between the - # field name and the field value and also the field value should not - # start with "{" or "<" which indicates the beginning of a message body. - # If there is no ":" or there is a "{" or "<" after ":", this field has - # to be a message or the input is ill-formed. - if ( - tokenizer.TryConsume(':') - and not tokenizer.LookingAt('{') - and not tokenizer.LookingAt('<') - ): - self._DetectSilentMarker(tokenizer, immediate_message_type, field_name) - if tokenizer.LookingAt('['): - self._SkipRepeatedFieldValue(tokenizer, immediate_message_type) - else: - self._SkipFieldValue(tokenizer) - else: - self._DetectSilentMarker(tokenizer, immediate_message_type, field_name) - self._SkipFieldMessage(tokenizer, immediate_message_type) - - def _SkipField(self, tokenizer, immediate_message_type): - """Skips over a complete field (name and value/message). - - Args: - tokenizer: A tokenizer to parse the field name and values. - immediate_message_type: The type of the message immediately containing the - silent marker. - """ - field_name = '' - if tokenizer.TryConsume('['): - # Consume extension or google.protobuf.Any type URL - field_name += '[' + tokenizer.ConsumeIdentifier() - num_identifiers = 1 - while tokenizer.TryConsume('.'): - field_name += '.' + tokenizer.ConsumeIdentifier() - num_identifiers += 1 - # This is possibly a type URL for an Any message. - if num_identifiers == 3 and tokenizer.TryConsume('/'): - field_name += '/' + tokenizer.ConsumeIdentifier() - while tokenizer.TryConsume('.'): - field_name += '.' + tokenizer.ConsumeIdentifier() - tokenizer.Consume(']') - field_name += ']' - else: - field_name += tokenizer.ConsumeIdentifierOrNumber() - - self._SkipFieldContents(tokenizer, field_name, immediate_message_type) - - # For historical reasons, fields may optionally be separated by commas or - # semicolons. - if not tokenizer.TryConsume(','): - tokenizer.TryConsume(';') - - def _SkipFieldMessage(self, tokenizer, immediate_message_type): - """Skips over a field message. - - Args: - tokenizer: A tokenizer to parse the field name and values. - immediate_message_type: The type of the message immediately containing the - silent marker - """ - if tokenizer.TryConsume('<'): - delimiter = '>' - else: - tokenizer.Consume('{') - delimiter = '}' - - while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'): - self._SkipField(tokenizer, immediate_message_type) - - tokenizer.Consume(delimiter) - - def _SkipFieldValue(self, tokenizer): - """Skips over a field value. - - Args: - tokenizer: A tokenizer to parse the field name and values. - - Raises: - ParseError: In case an invalid field value is found. - """ - if ( - not tokenizer.TryConsumeByteString() - and not tokenizer.TryConsumeIdentifier() - and not _TryConsumeInt64(tokenizer) - and not _TryConsumeUint64(tokenizer) - and not tokenizer.TryConsumeFloat() - ): - raise ParseError('Invalid field value: ' + tokenizer.token) - - def _SkipRepeatedFieldValue(self, tokenizer, immediate_message_type): - """Skips over a repeated field value. - - Args: - tokenizer: A tokenizer to parse the field value. - """ - tokenizer.Consume('[') - if not tokenizer.TryConsume(']'): - while True: - if tokenizer.LookingAt('<') or tokenizer.LookingAt('{'): - self._SkipFieldMessage(tokenizer, immediate_message_type) - else: - self._SkipFieldValue(tokenizer) - if tokenizer.TryConsume(']'): - break - tokenizer.Consume(',') - - -class Tokenizer(object): - """Protocol buffer text representation tokenizer. - - This class handles the lower level string parsing by splitting it into - meaningful tokens. - - It was directly ported from the Java protocol buffer API. - """ - - _WHITESPACE = re.compile(r'\s+') - _COMMENT = re.compile(r'(\s*#.*$)', re.MULTILINE) - _WHITESPACE_OR_COMMENT = re.compile(r'(\s|(#.*$))+', re.MULTILINE) - _TOKEN = re.compile( - '|'.join( - [ - r'[a-zA-Z_][0-9a-zA-Z_+-]*', # an identifier - r'([0-9+-]|(\.[0-9]))[0-9a-zA-Z_.+-]*', # a number - ] - + [ # quoted str for each quote mark - # Avoid backtracking! https://stackoverflow.com/a/844267 - r'{qt}[^{qt}\n\\]*((\\.)+[^{qt}\n\\]*)*({qt}|\\?$)'.format( - qt=mark - ) - for mark in _QUOTES - ] - ) - ) - - _IDENTIFIER = re.compile(r'[^\d\W]\w*') - _IDENTIFIER_OR_NUMBER = re.compile(r'\w+') - # Accepted URL characters (excluding "/") - _URL_CHARS = re.compile(r'^[0-9a-zA-Z-.~_ !$&()*+,;=%]+$') - - def __init__(self, lines, skip_comments=True): - self._position = 0 - self._line = -1 - self._column = 0 - self._token_start = None - self.token = '' - self._lines = iter(lines) - self._current_line = '' - self._previous_line = 0 - self._previous_column = 0 - self._more_lines = True - self._skip_comments = skip_comments - self._whitespace_pattern = ( - skip_comments and self._WHITESPACE_OR_COMMENT or self._WHITESPACE - ) - self.contains_silent_marker_before_current_token = False - - self._SkipWhitespace() - self.NextToken() - - def LookingAt(self, token): - return self.token == token - - def AtEnd(self): - """Checks the end of the text was reached. - - Returns: - True iff the end was reached. - """ - return not self.token - - def _PopLine(self): - while len(self._current_line) <= self._column: - try: - self._current_line = next(self._lines) - except StopIteration: - self._current_line = '' - self._more_lines = False - return - else: - self._line += 1 - self._column = 0 - - def _SkipWhitespace(self): - while True: - self._PopLine() - match = self._whitespace_pattern.match(self._current_line, self._column) - if not match: - break - self.contains_silent_marker_before_current_token = match.group(0) == ( - ' ' + _DEBUG_STRING_SILENT_MARKER - ) - length = len(match.group(0)) - self._column += length - - def TryConsume(self, token): - """Tries to consume a given piece of text. - - Args: - token: Text to consume. - - Returns: - True iff the text was consumed. - """ - if self.token == token: - self.NextToken() - return True - return False - - def Consume(self, token): - """Consumes a piece of text. - - Args: - token: Text to consume. - - Raises: - ParseError: If the text couldn't be consumed. - """ - if not self.TryConsume(token): - raise self.ParseError('Expected "%s".' % token) - - def ConsumeComment(self): - result = self.token - if not self._COMMENT.match(result): - raise self.ParseError('Expected comment.') - self.NextToken() - return result - - def ConsumeCommentOrTrailingComment(self): - """Consumes a comment, returns a 2-tuple (trailing bool, comment str).""" - - # Tokenizer initializes _previous_line and _previous_column to 0. As the - # tokenizer starts, it looks like there is a previous token on the line. - just_started = self._line == 0 and self._column == 0 - - before_parsing = self._previous_line - comment = self.ConsumeComment() - - # A trailing comment is a comment on the same line than the previous token. - trailing = self._previous_line == before_parsing and not just_started - - return trailing, comment - - def TryConsumeIdentifier(self): - try: - self.ConsumeIdentifier() - return True - except ParseError: - return False - - def ConsumeIdentifier(self): - """Consumes protocol message field identifier. - - Returns: - Identifier string. - - Raises: - ParseError: If an identifier couldn't be consumed. - """ - result = self.token - if not self._IDENTIFIER.match(result): - raise self.ParseError('Expected identifier.') - self.NextToken() - return result - - def TryConsumeIdentifierOrNumber(self): - try: - self.ConsumeIdentifierOrNumber() - return True - except ParseError: - return False - - def ConsumeIdentifierOrNumber(self): - """Consumes protocol message field identifier. - - Returns: - Identifier string. - - Raises: - ParseError: If an identifier couldn't be consumed. - """ - result = self.token - if not self._IDENTIFIER_OR_NUMBER.match(result): - raise self.ParseError('Expected identifier or number, got %s.' % result) - self.NextToken() - return result - - def TryConsumeInteger(self): - try: - self.ConsumeInteger() - return True - except ParseError: - return False - - def ConsumeInteger(self): - """Consumes an integer number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an integer couldn't be consumed. - """ - try: - result = _ParseAbstractInteger(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def TryConsumeFloat(self): - try: - self.ConsumeFloat() - return True - except ParseError: - return False - - def ConsumeFloat(self): - """Consumes an floating point number. - - Returns: - The number parsed. - - Raises: - ParseError: If a floating point number couldn't be consumed. - """ - try: - result = ParseFloat(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ConsumeBool(self): - """Consumes a boolean value. - - Returns: - The bool parsed. - - Raises: - ParseError: If a boolean value couldn't be consumed. - """ - try: - result = ParseBool(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def TryConsumeByteString(self): - try: - self.ConsumeByteString() - return True - except ParseError: - return False - - def ConsumeString(self): - """Consumes a string value. - - Returns: - The string parsed. - - Raises: - ParseError: If a string value couldn't be consumed. - """ - the_bytes = self.ConsumeByteString() - try: - return str(the_bytes, 'utf-8') - except UnicodeDecodeError as e: - raise self._StringParseError(e) - - def ConsumeByteString(self): - """Consumes a byte array value. - - Returns: - The array parsed (as a string). - - Raises: - ParseError: If a byte array value couldn't be consumed. - """ - the_list = [self._ConsumeSingleByteString()] - while self.token and self.token[0] in _QUOTES: - the_list.append(self._ConsumeSingleByteString()) - return b''.join(the_list) - - def _ConsumeSingleByteString(self): - """Consume one token of a string literal. - - String literals (whether bytes or text) can come in multiple adjacent - tokens which are automatically concatenated, like in C or Python. This - method only consumes one token. - - Returns: - The token parsed. - Raises: - ParseError: When the wrong format data is found. - """ - text = self.token - if len(text) < 1 or text[0] not in _QUOTES: - raise self.ParseError('Expected string but found: %r' % (text,)) - - if len(text) < 2 or text[-1] != text[0]: - raise self.ParseError('String missing ending quote: %r' % (text,)) - - try: - result = text_encoding.CUnescape(text[1:-1]) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ConsumeEnum(self, field): - try: - result = ParseEnum(field, self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ConsumeUrlChars(self): - """Consumes a token containing valid URL characters. - - Excludes '/' so that it can be treated specially as a delimiter. - - Returns: - The next token containing one or more URL characters. - - Raises: - ParseError: If the next token contains unaccepted URL characters. - """ - if not self._URL_CHARS.match(self.token): - raise self.ParseError('Expected URL character(s), got "%s"' % self.token) - - result = self.token - self.NextToken() - return result - - def TryConsumeUrlChars(self): - try: - self.ConsumeUrlChars() - return True - except ParseError: - return False - - def ParseErrorPreviousToken(self, message): - """Creates and *returns* a ParseError for the previously read token. - - Args: - message: A message to set for the exception. - - Returns: - A ParseError instance. - """ - return ParseError( - message, self._previous_line + 1, self._previous_column + 1 - ) - - def ParseError(self, message): - """Creates and *returns* a ParseError for the current token.""" - return ParseError( - "'" + self._current_line + "': " + message, - self._line + 1, - self._column + 1, - ) - - def _StringParseError(self, e): - return self.ParseError("Couldn't parse string: " + str(e)) - - def NextToken(self): - """Reads the next meaningful token.""" - self._previous_line = self._line - self._previous_column = self._column - self.contains_silent_marker_before_current_token = False - - self._column += len(self.token) - self._SkipWhitespace() - - if not self._more_lines: - self.token = '' - return - - match = self._TOKEN.match(self._current_line, self._column) - if not match and not self._skip_comments: - match = self._COMMENT.match(self._current_line, self._column) - if match: - token = match.group(0) - self.token = token - else: - self.token = self._current_line[self._column] - - -# Aliased so it can still be accessed by current visibility violators. -# TODO: Migrate violators to textformat_tokenizer. -_Tokenizer = Tokenizer # pylint: disable=invalid-name - - -def _ConsumeInt32(tokenizer): - """Consumes a signed 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If a signed 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=True, is_long=False) - - -def _ConsumeUint32(tokenizer): - """Consumes an unsigned 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an unsigned 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=False, is_long=False) - - -def _TryConsumeInt64(tokenizer): - try: - _ConsumeInt64(tokenizer) - return True - except ParseError: - return False - - -def _ConsumeInt64(tokenizer): - """Consumes a signed 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If a signed 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=True, is_long=True) - - -def _TryConsumeUint64(tokenizer): - try: - _ConsumeUint64(tokenizer) - return True - except ParseError: - return False - - -def _ConsumeUint64(tokenizer): - """Consumes an unsigned 64bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an unsigned 64bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=False, is_long=True) - - -def _ConsumeInteger(tokenizer, is_signed=False, is_long=False): - """Consumes an integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - is_signed: True if a signed integer must be parsed. - is_long: True if a long integer must be parsed. - - Returns: - The integer parsed. - - Raises: - ParseError: If an integer with given characteristics couldn't be consumed. - """ - try: - result = ParseInteger(tokenizer.token, is_signed=is_signed, is_long=is_long) - except ValueError as e: - raise tokenizer.ParseError(str(e)) - tokenizer.NextToken() - return result - - -def ParseInteger(text, is_signed=False, is_long=False): - """Parses an integer. - - Args: - text: The text to parse. - is_signed: True if a signed integer must be parsed. - is_long: True if a long integer must be parsed. - - Returns: - The integer value. - - Raises: - ValueError: Thrown Iff the text is not a valid integer. - """ - # Do the actual parsing. Exception handling is propagated to caller. - result = _ParseAbstractInteger(text) - - # Check if the integer is sane. Exceptions handled by callers. - checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)] - checker.CheckValue(result) - return result - - -def _ParseAbstractInteger(text): - """Parses an integer without checking size/signedness. - - Args: - text: The text to parse. - - Returns: - The integer value. - - Raises: - ValueError: Thrown Iff the text is not a valid integer. - """ - # Do the actual parsing. Exception handling is propagated to caller. - orig_text = text - c_octal_match = re.match(r'(-?)0(\d+)$', text) - if c_octal_match: - # Python 3 no longer supports 0755 octal syntax without the 'o', so - # we always use the '0o' prefix for multi-digit numbers starting with 0. - text = c_octal_match.group(1) + '0o' + c_octal_match.group(2) - try: - return int(text, 0) - except ValueError: - raise ValueError("Couldn't parse integer: %s" % orig_text) - - -def ParseFloat(text): - """Parse a floating point number. - - Args: - text: Text to parse. - - Returns: - The number parsed. - - Raises: - ValueError: If a floating point number couldn't be parsed. - """ - if _FLOAT_OCTAL_PREFIX.match(text): - raise ValueError('Invalid octal float: %s' % text) - try: - # Assume Python compatible syntax. - return float(text) - except ValueError: - # Check alternative spellings. - if _FLOAT_INFINITY.match(text): - if text[0] == '-': - return float('-inf') - else: - return float('inf') - elif _FLOAT_NAN.match(text): - return float('nan') - else: - # assume '1.0f' format - try: - return float(text.rstrip('fF')) - except ValueError: - raise ValueError("Couldn't parse float: %s" % text) - - -def ParseBool(text): - """Parse a boolean value. - - Args: - text: Text to parse. - - Returns: - Boolean values parsed - - Raises: - ValueError: If text is not a valid boolean. - """ - if text in ('true', 't', '1', 'True'): - return True - elif text in ('false', 'f', '0', 'False'): - return False - else: - raise ValueError('Expected "true" or "false".') - - -def ParseEnum(field, value): - """Parse an enum value. - - The value can be specified by a number (the enum value), or by - a string literal (the enum name). - - Args: - field: Enum field descriptor. - value: String value. - - Returns: - Enum value number. - - Raises: - ValueError: If the enum value could not be parsed. - """ - enum_descriptor = field.enum_type - try: - number = int(value, 0) - except ValueError: - # Identifier. - enum_value = enum_descriptor.values_by_name.get(value, None) - if enum_value is None: - raise ValueError( - 'Enum type "%s" has no value named %s.' - % (enum_descriptor.full_name, value) - ) - else: - if not field.enum_type.is_closed: - return number - enum_value = enum_descriptor.values_by_number.get(number, None) - if enum_value is None: - raise ValueError( - 'Enum type "%s" has no value with number %d.' - % (enum_descriptor.full_name, number) - ) - return enum_value.number diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py deleted file mode 100644 index fb9c89143bb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp.py +++ /dev/null @@ -1,112 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd - -"""Contains the Timestamp helper APIs.""" - -import datetime -from typing import Optional - -from opentelemetry.agent._vendor.google.protobuf.timestamp_pb2 import Timestamp - - -def from_json_string(value: str) -> Timestamp: - """Parse a RFC 3339 date string format to Timestamp. - - Args: - value: A date string. Any fractional digits (or none) and any offset are - accepted as long as they fit into nano-seconds precision. Example of - accepted format: '1972-01-01T10:00:20.021-05:00' - - Raises: - ValueError: On parsing problems. - """ - timestamp = Timestamp() - timestamp.FromJsonString(value) - return timestamp - - -def from_microseconds(micros: float) -> Timestamp: - """Converts microseconds since epoch to Timestamp.""" - timestamp = Timestamp() - timestamp.FromMicroseconds(micros) - return timestamp - - -def from_milliseconds(millis: float) -> Timestamp: - """Converts milliseconds since epoch to Timestamp.""" - timestamp = Timestamp() - timestamp.FromMilliseconds(millis) - return timestamp - - -def from_nanoseconds(nanos: float) -> Timestamp: - """Converts nanoseconds since epoch to Timestamp.""" - timestamp = Timestamp() - timestamp.FromNanoseconds(nanos) - return timestamp - - -def from_seconds(seconds: float) -> Timestamp: - """Converts seconds since epoch to Timestamp.""" - timestamp = Timestamp() - timestamp.FromSeconds(seconds) - return timestamp - - -def from_current_time() -> Timestamp: - """Converts the current UTC to Timestamp.""" - timestamp = Timestamp() - timestamp.FromDatetime(datetime.datetime.now(tz=datetime.timezone.utc)) - return timestamp - - -def to_json_string(ts: Timestamp) -> str: - """Converts Timestamp to RFC 3339 date string format. - - Returns: - A string converted from timestamp. The string is always Z-normalized - and uses 3, 6 or 9 fractional digits as required to represent the - exact time. Example of the return format: '1972-01-01T10:00:20.021Z' - """ - return ts.ToJsonString() - - -def to_microseconds(ts: Timestamp) -> int: - """Converts Timestamp to microseconds since epoch.""" - return ts.ToMicroseconds() - - -def to_milliseconds(ts: Timestamp) -> int: - """Converts Timestamp to milliseconds since epoch.""" - return ts.ToMilliseconds() - - -def to_nanoseconds(ts: Timestamp) -> int: - """Converts Timestamp to nanoseconds since epoch.""" - return ts.ToNanoseconds() - - -def to_seconds(ts: Timestamp) -> int: - """Converts Timestamp to seconds since epoch.""" - return ts.ToSeconds() - - -def to_datetime( - ts: Timestamp, tz: Optional[datetime.tzinfo] = None -) -> datetime.datetime: - """Converts Timestamp to a datetime. - - Args: - tz: A datetime.tzinfo subclass; defaults to None. - - Returns: - If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone - information, i.e. not aware that it's UTC). - - Otherwise, returns a timezone-aware datetime in the input timezone. - """ - return ts.ToDatetime(tzinfo=tz) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py deleted file mode 100644 index 41c048c29ff..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/timestamp_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/timestamp.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/timestamp.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fgoogle/protobuf/timestamp.proto\x12\x0fgoogle.protobuf\";\n\tTimestamp\x12\x18\n\x07seconds\x18\x01 \x01(\x03R\x07seconds\x12\x14\n\x05nanos\x18\x02 \x01(\x05R\x05nanosB\x85\x01\n\x13\x63om.google.protobufB\x0eTimestampProtoP\x01Z2google.golang.org/protobuf/types/known/timestamppb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.timestamp_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\016TimestampProtoP\001Z2google.golang.org/protobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_TIMESTAMP']._serialized_start=52 - _globals['_TIMESTAMP']._serialized_end=111 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py deleted file mode 100644 index 67d136d7765..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/type_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/type.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/type.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from opentelemetry.agent._vendor.google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1agoogle/protobuf/type.proto\x12\x0fgoogle.protobuf\x1a\x19google/protobuf/any.proto\x1a$google/protobuf/source_context.proto\"\xa7\x02\n\x04Type\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12.\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x16.google.protobuf.FieldR\x06\x66ields\x12\x16\n\x06oneofs\x18\x03 \x03(\tR\x06oneofs\x12\x31\n\x07options\x18\x04 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x45\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContextR\rsourceContext\x12/\n\x06syntax\x18\x06 \x01(\x0e\x32\x17.google.protobuf.SyntaxR\x06syntax\x12\x18\n\x07\x65\x64ition\x18\x07 \x01(\tR\x07\x65\x64ition\"\xb4\x06\n\x05\x46ield\x12/\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.google.protobuf.Field.KindR\x04kind\x12\x44\n\x0b\x63\x61rdinality\x18\x02 \x01(\x0e\x32\".google.protobuf.Field.CardinalityR\x0b\x63\x61rdinality\x12\x16\n\x06number\x18\x03 \x01(\x05R\x06number\x12\x12\n\x04name\x18\x04 \x01(\tR\x04name\x12\x19\n\x08type_url\x18\x06 \x01(\tR\x07typeUrl\x12\x1f\n\x0boneof_index\x18\x07 \x01(\x05R\noneofIndex\x12\x16\n\x06packed\x18\x08 \x01(\x08R\x06packed\x12\x31\n\x07options\x18\t \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x1b\n\tjson_name\x18\n \x01(\tR\x08jsonName\x12#\n\rdefault_value\x18\x0b \x01(\tR\x0c\x64\x65\x66\x61ultValue\"\xc8\x02\n\x04Kind\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"t\n\x0b\x43\x61rdinality\x12\x17\n\x13\x43\x41RDINALITY_UNKNOWN\x10\x00\x12\x18\n\x14\x43\x41RDINALITY_OPTIONAL\x10\x01\x12\x18\n\x14\x43\x41RDINALITY_REQUIRED\x10\x02\x12\x18\n\x14\x43\x41RDINALITY_REPEATED\x10\x03\"\x99\x02\n\x04\x45num\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x38\n\tenumvalue\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.EnumValueR\tenumvalue\x12\x31\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\x12\x45\n\x0esource_context\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.SourceContextR\rsourceContext\x12/\n\x06syntax\x18\x05 \x01(\x0e\x32\x17.google.protobuf.SyntaxR\x06syntax\x12\x18\n\x07\x65\x64ition\x18\x06 \x01(\tR\x07\x65\x64ition\"j\n\tEnumValue\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n\x06number\x18\x02 \x01(\x05R\x06number\x12\x31\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.OptionR\x07options\"H\n\x06Option\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x14.google.protobuf.AnyR\x05value*C\n\x06Syntax\x12\x11\n\rSYNTAX_PROTO2\x10\x00\x12\x11\n\rSYNTAX_PROTO3\x10\x01\x12\x13\n\x0fSYNTAX_EDITIONS\x10\x02\x42{\n\x13\x63om.google.protobufB\tTypeProtoP\x01Z-google.golang.org/protobuf/types/known/typepb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.type_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\tTypeProtoP\001Z-google.golang.org/protobuf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_SYNTAX']._serialized_start=1699 - _globals['_SYNTAX']._serialized_end=1766 - _globals['_TYPE']._serialized_start=113 - _globals['_TYPE']._serialized_end=408 - _globals['_FIELD']._serialized_start=411 - _globals['_FIELD']._serialized_end=1231 - _globals['_FIELD_KIND']._serialized_start=785 - _globals['_FIELD_KIND']._serialized_end=1113 - _globals['_FIELD_CARDINALITY']._serialized_start=1115 - _globals['_FIELD_CARDINALITY']._serialized_end=1231 - _globals['_ENUM']._serialized_start=1234 - _globals['_ENUM']._serialized_end=1515 - _globals['_ENUMVALUE']._serialized_start=1517 - _globals['_ENUMVALUE']._serialized_end=1623 - _globals['_OPTION']._serialized_start=1625 - _globals['_OPTION']._serialized_end=1697 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py deleted file mode 100644 index 0845f428388..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/unknown_fields.py +++ /dev/null @@ -1,93 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file or at -# https://developers.google.com/open-source/licenses/bsd -"""Contains Unknown Fields APIs. - -Simple usage example: - unknown_field_set = UnknownFieldSet(message) - for unknown_field in unknown_field_set: - wire_type = unknown_field.wire_type - field_number = unknown_field.field_number - data = unknown_field.data -""" - -from opentelemetry.agent._vendor.google.protobuf.internal import api_implementation - -if api_implementation._c_module is not None: # pylint: disable=protected-access - UnknownFieldSet = api_implementation._c_module.UnknownFieldSet # pylint: disable=protected-access -else: - from opentelemetry.agent._vendor.google.protobuf.internal import decoder # pylint: disable=g-import-not-at-top - from opentelemetry.agent._vendor.google.protobuf.internal import wire_format # pylint: disable=g-import-not-at-top - - class UnknownField: - """A parsed unknown field.""" - - # Disallows assignment to other attributes. - __slots__ = ['_field_number', '_wire_type', '_data'] - - def __init__(self, field_number, wire_type, data): - self._field_number = field_number - self._wire_type = wire_type - self._data = data - return - - @property - def field_number(self): - return self._field_number - - @property - def wire_type(self): - return self._wire_type - - @property - def data(self): - return self._data - - class UnknownFieldSet: - """UnknownField container.""" - - # Disallows assignment to other attributes. - __slots__ = ['_values'] - - def __init__(self, msg): - - def InternalAdd(field_number, wire_type, data): - unknown_field = UnknownField(field_number, wire_type, data) - self._values.append(unknown_field) - - self._values = [] - msg_des = msg.DESCRIPTOR - # pylint: disable=protected-access - unknown_fields = msg._unknown_fields - if msg_des.has_options and msg_des.GetOptions().message_set_wire_format: - local_decoder = decoder.UnknownMessageSetItemDecoder() - for _, buffer in unknown_fields: - field_number, data = local_decoder(memoryview(buffer)) - InternalAdd(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED, data) - else: - for tag_bytes, buffer in unknown_fields: - field_number, wire_type = decoder.DecodeTag(tag_bytes) - if field_number == 0: - raise RuntimeError('Field number 0 is illegal.') - data, _ = decoder._DecodeUnknownField( - memoryview(buffer), 0, len(buffer), field_number, wire_type - ) - InternalAdd(field_number, wire_type, data) - - def __getitem__(self, index): - size = len(self._values) - if index < 0: - index += size - if index < 0 or index >= size: - raise IndexError('index %d out of range'.index) - - return self._values[index] - - def __len__(self): - return len(self._values) - - def __iter__(self): - return iter(self._values) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/util/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/util/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py deleted file mode 100644 index d6470414b00..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/protobuf/wrappers_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/protobuf/wrappers.proto -# Protobuf Python Version: 7.36.2 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 7, - 36, - 2, - '', - 'google/protobuf/wrappers.proto' -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/wrappers.proto\x12\x0fgoogle.protobuf\"#\n\x0b\x44oubleValue\x12\x14\n\x05value\x18\x01 \x01(\x01R\x05value\"\"\n\nFloatValue\x12\x14\n\x05value\x18\x01 \x01(\x02R\x05value\"\"\n\nInt64Value\x12\x14\n\x05value\x18\x01 \x01(\x03R\x05value\"#\n\x0bUInt64Value\x12\x14\n\x05value\x18\x01 \x01(\x04R\x05value\"\"\n\nInt32Value\x12\x14\n\x05value\x18\x01 \x01(\x05R\x05value\"#\n\x0bUInt32Value\x12\x14\n\x05value\x18\x01 \x01(\rR\x05value\"!\n\tBoolValue\x12\x14\n\x05value\x18\x01 \x01(\x08R\x05value\"#\n\x0bStringValue\x12\x14\n\x05value\x18\x01 \x01(\tR\x05value\"\"\n\nBytesValue\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05valueB\x83\x01\n\x13\x63om.google.protobufB\rWrappersProtoP\x01Z1google.golang.org/protobuf/types/known/wrapperspb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.google.protobuf.wrappers_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\023com.google.protobufB\rWrappersProtoP\001Z1google.golang.org/protobuf/types/known/wrapperspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _globals['_DOUBLEVALUE']._serialized_start=51 - _globals['_DOUBLEVALUE']._serialized_end=86 - _globals['_FLOATVALUE']._serialized_start=88 - _globals['_FLOATVALUE']._serialized_end=122 - _globals['_INT64VALUE']._serialized_start=124 - _globals['_INT64VALUE']._serialized_end=158 - _globals['_UINT64VALUE']._serialized_start=160 - _globals['_UINT64VALUE']._serialized_end=195 - _globals['_INT32VALUE']._serialized_start=197 - _globals['_INT32VALUE']._serialized_end=231 - _globals['_UINT32VALUE']._serialized_start=233 - _globals['_UINT32VALUE']._serialized_end=268 - _globals['_BOOLVALUE']._serialized_start=270 - _globals['_BOOLVALUE']._serialized_end=303 - _globals['_STRINGVALUE']._serialized_start=305 - _globals['_STRINGVALUE']._serialized_end=340 - _globals['_BYTESVALUE']._serialized_start=342 - _globals['_BYTESVALUE']._serialized_end=376 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto deleted file mode 100644 index 46b5d75a78a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code.proto +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.rpc; - -option go_package = "google.golang.org/genproto/googleapis/rpc/code;code"; -option java_multiple_files = true; -option java_outer_classname = "CodeProto"; -option java_package = "com.google.rpc"; -option objc_class_prefix = "RPC"; - -// The canonical error codes for gRPC APIs. -// -// -// Sometimes multiple error codes may apply. Services should return -// the most specific error code that applies. For example, prefer -// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply. -// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`. -enum Code { - // Not an error; returned on success. - // - // HTTP Mapping: 200 OK - OK = 0; - - // The operation was cancelled, typically by the caller. - // - // HTTP Mapping: 499 Client Closed Request - CANCELLED = 1; - - // Unknown error. For example, this error may be returned when - // a `Status` value received from another address space belongs to - // an error space that is not known in this address space. Also - // errors raised by APIs that do not return enough error information - // may be converted to this error. - // - // HTTP Mapping: 500 Internal Server Error - UNKNOWN = 2; - - // The client specified an invalid argument. Note that this differs - // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments - // that are problematic regardless of the state of the system - // (e.g., a malformed file name). - // - // HTTP Mapping: 400 Bad Request - INVALID_ARGUMENT = 3; - - // The deadline expired before the operation could complete. For operations - // that change the state of the system, this error may be returned - // even if the operation has completed successfully. For example, a - // successful response from a server could have been delayed long - // enough for the deadline to expire. - // - // HTTP Mapping: 504 Gateway Timeout - DEADLINE_EXCEEDED = 4; - - // Some requested entity (e.g., file or directory) was not found. - // - // Note to server developers: if a request is denied for an entire class - // of users, such as gradual feature rollout or undocumented allowlist, - // `NOT_FOUND` may be used. If a request is denied for some users within - // a class of users, such as user-based access control, `PERMISSION_DENIED` - // must be used. - // - // HTTP Mapping: 404 Not Found - NOT_FOUND = 5; - - // The entity that a client attempted to create (e.g., file or directory) - // already exists. - // - // HTTP Mapping: 409 Conflict - ALREADY_EXISTS = 6; - - // The caller does not have permission to execute the specified - // operation. `PERMISSION_DENIED` must not be used for rejections - // caused by exhausting some resource (use `RESOURCE_EXHAUSTED` - // instead for those errors). `PERMISSION_DENIED` must not be - // used if the caller can not be identified (use `UNAUTHENTICATED` - // instead for those errors). This error code does not imply the - // request is valid or the requested entity exists or satisfies - // other pre-conditions. - // - // HTTP Mapping: 403 Forbidden - PERMISSION_DENIED = 7; - - // The request does not have valid authentication credentials for the - // operation. - // - // HTTP Mapping: 401 Unauthorized - UNAUTHENTICATED = 16; - - // Some resource has been exhausted, perhaps a per-user quota, or - // perhaps the entire file system is out of space. - // - // HTTP Mapping: 429 Too Many Requests - RESOURCE_EXHAUSTED = 8; - - // The operation was rejected because the system is not in a state - // required for the operation's execution. For example, the directory - // to be deleted is non-empty, an rmdir operation is applied to - // a non-directory, etc. - // - // Service implementors can use the following guidelines to decide - // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: - // (a) Use `UNAVAILABLE` if the client can retry just the failing call. - // (b) Use `ABORTED` if the client should retry at a higher level. For - // example, when a client-specified test-and-set fails, indicating the - // client should restart a read-modify-write sequence. - // (c) Use `FAILED_PRECONDITION` if the client should not retry until - // the system state has been explicitly fixed. For example, if an "rmdir" - // fails because the directory is non-empty, `FAILED_PRECONDITION` - // should be returned since the client should not retry unless - // the files are deleted from the directory. - // - // HTTP Mapping: 400 Bad Request - FAILED_PRECONDITION = 9; - - // The operation was aborted, typically due to a concurrency issue such as - // a sequencer check failure or transaction abort. - // - // See the guidelines above for deciding between `FAILED_PRECONDITION`, - // `ABORTED`, and `UNAVAILABLE`. - // - // HTTP Mapping: 409 Conflict - ABORTED = 10; - - // The operation was attempted past the valid range. E.g., seeking or - // reading past end-of-file. - // - // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may - // be fixed if the system state changes. For example, a 32-bit file - // system will generate `INVALID_ARGUMENT` if asked to read at an - // offset that is not in the range [0,2^32-1], but it will generate - // `OUT_OF_RANGE` if asked to read from an offset past the current - // file size. - // - // There is a fair bit of overlap between `FAILED_PRECONDITION` and - // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific - // error) when it applies so that callers who are iterating through - // a space can easily look for an `OUT_OF_RANGE` error to detect when - // they are done. - // - // HTTP Mapping: 400 Bad Request - OUT_OF_RANGE = 11; - - // The operation is not implemented or is not supported/enabled in this - // service. - // - // HTTP Mapping: 501 Not Implemented - UNIMPLEMENTED = 12; - - // Internal errors. This means that some invariants expected by the - // underlying system have been broken. This error code is reserved - // for serious errors. - // - // HTTP Mapping: 500 Internal Server Error - INTERNAL = 13; - - // The service is currently unavailable. This is most likely a - // transient condition, which can be corrected by retrying with - // a backoff. Note that it is not always safe to retry - // non-idempotent operations. - // - // See the guidelines above for deciding between `FAILED_PRECONDITION`, - // `ABORTED`, and `UNAVAILABLE`. - // - // HTTP Mapping: 503 Service Unavailable - UNAVAILABLE = 14; - - // Unrecoverable data loss or corruption. - // - // HTTP Mapping: 500 Internal Server Error - DATA_LOSS = 15; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py deleted file mode 100644 index c79900e7978..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/rpc/code.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/code.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n\x15google/rpc/code.proto\x12\ngoogle.rpc*\xb7\x02\n\x04\x43ode\x12\x06\n\x02OK\x10\x00\x12\r\n\tCANCELLED\x10\x01\x12\x0b\n\x07UNKNOWN\x10\x02\x12\x14\n\x10INVALID_ARGUMENT\x10\x03\x12\x15\n\x11\x44\x45\x41\x44LINE_EXCEEDED\x10\x04\x12\r\n\tNOT_FOUND\x10\x05\x12\x12\n\x0e\x41LREADY_EXISTS\x10\x06\x12\x15\n\x11PERMISSION_DENIED\x10\x07\x12\x13\n\x0fUNAUTHENTICATED\x10\x10\x12\x16\n\x12RESOURCE_EXHAUSTED\x10\x08\x12\x17\n\x13\x46\x41ILED_PRECONDITION\x10\t\x12\x0b\n\x07\x41\x42ORTED\x10\n\x12\x10\n\x0cOUT_OF_RANGE\x10\x0b\x12\x11\n\rUNIMPLEMENTED\x10\x0c\x12\x0c\n\x08INTERNAL\x10\r\x12\x0f\n\x0bUNAVAILABLE\x10\x0e\x12\r\n\tDATA_LOSS\x10\x0f\x42X\n\x0e\x63om.google.rpcB\tCodeProtoP\x01Z3google.golang.org/genproto/googleapis/rpc/code;code\xa2\x02\x03RPCb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.code_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.rpcB\tCodeProtoP\001Z3google.golang.org/genproto/googleapis/rpc/code;code\242\002\003RPC" - _globals["_CODE"]._serialized_start = 38 - _globals["_CODE"]._serialized_end = 349 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi deleted file mode 100644 index 17acb5af980..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/code_pb2.pyi +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class Code(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - OK: _ClassVar[Code] - CANCELLED: _ClassVar[Code] - UNKNOWN: _ClassVar[Code] - INVALID_ARGUMENT: _ClassVar[Code] - DEADLINE_EXCEEDED: _ClassVar[Code] - NOT_FOUND: _ClassVar[Code] - ALREADY_EXISTS: _ClassVar[Code] - PERMISSION_DENIED: _ClassVar[Code] - UNAUTHENTICATED: _ClassVar[Code] - RESOURCE_EXHAUSTED: _ClassVar[Code] - FAILED_PRECONDITION: _ClassVar[Code] - ABORTED: _ClassVar[Code] - OUT_OF_RANGE: _ClassVar[Code] - UNIMPLEMENTED: _ClassVar[Code] - INTERNAL: _ClassVar[Code] - UNAVAILABLE: _ClassVar[Code] - DATA_LOSS: _ClassVar[Code] - -OK: Code -CANCELLED: Code -UNKNOWN: Code -INVALID_ARGUMENT: Code -DEADLINE_EXCEEDED: Code -NOT_FOUND: Code -ALREADY_EXISTS: Code -PERMISSION_DENIED: Code -UNAUTHENTICATED: Code -RESOURCE_EXHAUSTED: Code -FAILED_PRECONDITION: Code -ABORTED: Code -OUT_OF_RANGE: Code -UNIMPLEMENTED: Code -INTERNAL: Code -UNAVAILABLE: Code -DATA_LOSS: Code diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto deleted file mode 100644 index 55f95f844e7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context.proto +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.rpc.context; - -import "google/protobuf/any.proto"; -import "google/protobuf/duration.proto"; -import "google/protobuf/struct.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "google.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_context"; -option java_multiple_files = true; -option java_outer_classname = "AttributeContextProto"; -option java_package = "com.google.rpc.context"; - -// This message defines the standard attribute vocabulary for Google APIs. -// -// An attribute is a piece of metadata that describes an activity on a network -// service. For example, the size of an HTTP request, or the status code of -// an HTTP response. -// -// Each attribute has a type and a name, which is logically defined as -// a proto message field in `AttributeContext`. The field type becomes the -// attribute type, and the field path becomes the attribute name. For example, -// the attribute `source.ip` maps to field `AttributeContext.source.ip`. -// -// This message definition is guaranteed not to have any wire breaking change. -// So you can use it directly for passing attributes across different systems. -// -// NOTE: Different system may generate different subset of attributes. Please -// verify the system specification before relying on an attribute generated -// a system. -message AttributeContext { - // This message defines attributes for a node that handles a network request. - // The node can be either a service or an application that sends, forwards, - // or receives the request. Service peers should fill in - // `principal` and `labels` as appropriate. - message Peer { - // The IP address of the peer. - string ip = 1; - - // The network port of the peer. - int64 port = 2; - - // The labels associated with the peer. - map labels = 6; - - // The identity of this peer. Similar to `Request.auth.principal`, but - // relative to the peer instead of the request. For example, the - // identity associated with a load balancer that forwarded the request. - string principal = 7; - - // The CLDR country/region code associated with the above IP address. - // If the IP address is private, the `region_code` should reflect the - // physical location where this peer is running. - string region_code = 8; - } - - // This message defines attributes associated with API operations, such as - // a network API request. The terminology is based on the conventions used - // by Google APIs, Istio, and OpenAPI. - message Api { - // The API service name. It is a logical identifier for a networked API, - // such as "pubsub.googleapis.com". The naming syntax depends on the - // API management system being used for handling the request. - string service = 1; - - // The API operation name. For gRPC requests, it is the fully qualified API - // method name, such as "google.pubsub.v1.Publisher.Publish". For OpenAPI - // requests, it is the `operationId`, such as "getPet". - string operation = 2; - - // The API protocol used for sending the request, such as "http", "https", - // "grpc", or "internal". - string protocol = 3; - - // The API version associated with the API operation above, such as "v1" or - // "v1alpha1". - string version = 4; - } - - // This message defines request authentication attributes. Terminology is - // based on the JSON Web Token (JWT) standard, but the terms also - // correlate to concepts in other standards. - message Auth { - // The authenticated principal. Reflects the issuer (`iss`) and subject - // (`sub`) claims within a JWT. The issuer and subject should be `/` - // delimited, with `/` percent-encoded within the subject fragment. For - // Google accounts, the principal format is: - // "https://accounts.google.com/{id}" - string principal = 1; - - // The intended audience(s) for this authentication information. Reflects - // the audience (`aud`) claim within a JWT. The audience - // value(s) depends on the `issuer`, but typically include one or more of - // the following pieces of information: - // - // * The services intended to receive the credential. For example, - // ["https://pubsub.googleapis.com/", "https://storage.googleapis.com/"]. - // * A set of service-based scopes. For example, - // ["https://www.googleapis.com/auth/cloud-platform"]. - // * The client id of an app, such as the Firebase project id for JWTs - // from Firebase Auth. - // - // Consult the documentation for the credential issuer to determine the - // information provided. - repeated string audiences = 2; - - // The authorized presenter of the credential. Reflects the optional - // Authorized Presenter (`azp`) claim within a JWT or the - // OAuth client id. For example, a Google Cloud Platform client id looks - // as follows: "123456789012.apps.googleusercontent.com". - string presenter = 3; - - // Structured claims presented with the credential. JWTs include - // `{key: value}` pairs for standard and private claims. The following - // is a subset of the standard required and optional claims that would - // typically be presented for a Google-based JWT: - // - // {'iss': 'accounts.google.com', - // 'sub': '113289723416554971153', - // 'aud': ['123456789012', 'pubsub.googleapis.com'], - // 'azp': '123456789012.apps.googleusercontent.com', - // 'email': 'jsmith@example.com', - // 'iat': 1353601026, - // 'exp': 1353604926} - // - // SAML assertions are similarly specified, but with an identity provider - // dependent structure. - google.protobuf.Struct claims = 4; - - // A list of access level resource names that allow resources to be - // accessed by authenticated requester. It is part of Secure GCP processing - // for the incoming request. An access level string has the format: - // "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/{short_name}" - // - // Example: - // "//accesscontextmanager.googleapis.com/accessPolicies/MY_POLICY_ID/accessLevels/MY_LEVEL" - repeated string access_levels = 5; - } - - // This message defines attributes for an HTTP request. If the actual - // request is not an HTTP request, the runtime system should try to map - // the actual request to an equivalent HTTP request. - message Request { - // The unique ID for a request, which can be propagated to downstream - // systems. The ID should have low probability of collision - // within a single day for a specific service. - string id = 1; - - // The HTTP request method, such as `GET`, `POST`. - string method = 2; - - // The HTTP request headers. If multiple headers share the same key, they - // must be merged according to the HTTP spec. All header keys must be - // lowercased, because HTTP header keys are case-insensitive. - map headers = 3; - - // The HTTP URL path, excluding the query parameters. - string path = 4; - - // The HTTP request `Host` header value. - string host = 5; - - // The HTTP URL scheme, such as `http` and `https`. - string scheme = 6; - - // The HTTP URL query in the format of `name1=value1&name2=value2`, as it - // appears in the first line of the HTTP request. No decoding is performed. - string query = 7; - - // The timestamp when the `destination` service receives the last byte of - // the request. - google.protobuf.Timestamp time = 9; - - // The HTTP request size in bytes. If unknown, it must be -1. - int64 size = 10; - - // The network protocol used with the request, such as "http/1.1", - // "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See - // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids - // for details. - string protocol = 11; - - // A special parameter for request reason. It is used by security systems - // to associate auditing information with a request. - string reason = 12; - - // The request authentication. May be absent for unauthenticated requests. - // Derived from the HTTP request `Authorization` header or equivalent. - Auth auth = 13; - - // The values from Origin header from the HTTP request, such as - // "https://console.cloud.google.com". Modern browsers can only have one - // origin. Special browsers and/or HTTP clients may require multiple - // origins. - string origin = 14; - } - - // This message defines attributes for a typical network response. It - // generally models semantics of an HTTP response. - message Response { - // The HTTP response status code, such as `200` and `404`. - int64 code = 1; - - // The HTTP response size in bytes. If unknown, it must be -1. - int64 size = 2; - - // The HTTP response headers. If multiple headers share the same key, they - // must be merged according to HTTP spec. All header keys must be - // lowercased, because HTTP header keys are case-insensitive. - map headers = 3; - - // The timestamp when the `destination` service sends the last byte of - // the response. - google.protobuf.Timestamp time = 4; - - // The amount of time it takes the backend service to fully respond to a - // request. Measured from when the destination service starts to send the - // request to the backend until when the destination service receives the - // complete response from the backend. - google.protobuf.Duration backend_latency = 5; - } - - // This message defines core attributes for a resource. A resource is an - // addressable (named) entity provided by the destination service. For - // example, a file stored on a network storage service. - message Resource { - // The name of the service that this resource belongs to, such as - // `pubsub.googleapis.com`. The service may be different from the DNS - // hostname that actually serves the request. - string service = 1; - - // The stable identifier (name) of a resource on the `service`. A resource - // can be logically identified as "//{resource.service}/{resource.name}". - // The differences between a resource name and a URI are: - // - // * Resource name is a logical identifier, independent of network - // protocol and API version. For example, - // `//pubsub.googleapis.com/projects/123/topics/news-feed`. - // * URI often includes protocol and version information, so it can - // be used directly by applications. For example, - // `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`. - // - // See https://cloud.google.com/apis/design/resource_names for details. - string name = 2; - - // The type of the resource. The syntax is platform-specific because - // different platforms define their resources differently. - // - // For Google APIs, the type format must be "{service}/{kind}", such as - // "pubsub.googleapis.com/Topic". - string type = 3; - - // The labels or tags on the resource, such as AWS resource tags and - // Kubernetes resource labels. - map labels = 4; - - // The unique identifier of the resource. UID is unique in the time - // and space for this resource within the scope of the service. It is - // typically generated by the server on successful creation of a resource - // and must not be changed. UID is used to uniquely identify resources - // with resource name reuses. This should be a UUID4. - string uid = 5; - - // Annotations is an unstructured key-value map stored with a resource that - // may be set by external tools to store and retrieve arbitrary metadata. - // They are not queryable and should be preserved when modifying objects. - // - // More info: - // https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ - map annotations = 6; - - // Mutable. The display name set by clients. Must be <= 63 characters. - string display_name = 7; - - // Output only. The timestamp when the resource was created. This may - // be either the time creation was initiated or when it was completed. - google.protobuf.Timestamp create_time = 8; - - // Output only. The timestamp when the resource was last updated. Any - // change to the resource made by users must refresh this value. - // Changes to a resource made by the service should refresh this value. - google.protobuf.Timestamp update_time = 9; - - // Output only. The timestamp when the resource was deleted. - // If the resource is not deleted, this must be empty. - google.protobuf.Timestamp delete_time = 10; - - // Output only. An opaque value that uniquely identifies a version or - // generation of a resource. It can be used to confirm that the client - // and server agree on the ordering of a resource being written. - string etag = 11; - - // Immutable. The location of the resource. The location encoding is - // specific to the service provider, and new encoding may be introduced - // as the service evolves. - // - // For Google Cloud products, the encoding is what is used by Google Cloud - // APIs, such as `us-east1`, `aws-us-east-1`, and `azure-eastus2`. The - // semantics of `location` is identical to the - // `cloud.googleapis.com/location` label used by some Google Cloud APIs. - string location = 12; - } - - // The origin of a network activity. In a multi hop network activity, - // the origin represents the sender of the first hop. For the first hop, - // the `source` and the `origin` must have the same content. - Peer origin = 7; - - // The source of a network activity, such as starting a TCP connection. - // In a multi hop network activity, the source represents the sender of the - // last hop. - Peer source = 1; - - // The destination of a network activity, such as accepting a TCP connection. - // In a multi hop network activity, the destination represents the receiver of - // the last hop. - Peer destination = 2; - - // Represents a network request, such as an HTTP request. - Request request = 3; - - // Represents a network response, such as an HTTP response. - Response response = 4; - - // Represents a target resource that is involved with a network activity. - // If multiple resources are involved with an activity, this must be the - // primary one. - Resource resource = 5; - - // Represents an API operation that is involved to a network activity. - Api api = 6; - - // Supports extensions for advanced use cases, such as logs and metrics. - repeated google.protobuf.Any extensions = 8; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py deleted file mode 100644 index 8fe0b8631d7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.py +++ /dev/null @@ -1,97 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/rpc/context/attribute_context.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 33, - 5, - "", - "google/rpc/context/attribute_context.proto", -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 -from opentelemetry.agent._vendor.google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 -from opentelemetry.agent._vendor.google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n*google/rpc/context/attribute_context.proto\x12\x12google.rpc.context\x1a\x19google/protobuf/any.proto\x1a\x1egoogle/protobuf/duration.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x93\x10\n\x10\x41ttributeContext\x12\x39\n\x06origin\x18\x07 \x01(\x0b\x32).google.rpc.context.AttributeContext.Peer\x12\x39\n\x06source\x18\x01 \x01(\x0b\x32).google.rpc.context.AttributeContext.Peer\x12>\n\x0b\x64\x65stination\x18\x02 \x01(\x0b\x32).google.rpc.context.AttributeContext.Peer\x12=\n\x07request\x18\x03 \x01(\x0b\x32,.google.rpc.context.AttributeContext.Request\x12?\n\x08response\x18\x04 \x01(\x0b\x32-.google.rpc.context.AttributeContext.Response\x12?\n\x08resource\x18\x05 \x01(\x0b\x32-.google.rpc.context.AttributeContext.Resource\x12\x35\n\x03\x61pi\x18\x06 \x01(\x0b\x32(.google.rpc.context.AttributeContext.Api\x12(\n\nextensions\x18\x08 \x03(\x0b\x32\x14.google.protobuf.Any\x1a\xbe\x01\n\x04Peer\x12\n\n\x02ip\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x03\x12\x45\n\x06labels\x18\x06 \x03(\x0b\x32\x35.google.rpc.context.AttributeContext.Peer.LabelsEntry\x12\x11\n\tprincipal\x18\x07 \x01(\t\x12\x13\n\x0bregion_code\x18\x08 \x01(\t\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1aL\n\x03\x41pi\x12\x0f\n\x07service\x18\x01 \x01(\t\x12\x11\n\toperation\x18\x02 \x01(\t\x12\x10\n\x08protocol\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x1a\x7f\n\x04\x41uth\x12\x11\n\tprincipal\x18\x01 \x01(\t\x12\x11\n\taudiences\x18\x02 \x03(\t\x12\x11\n\tpresenter\x18\x03 \x01(\t\x12'\n\x06\x63laims\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x15\n\raccess_levels\x18\x05 \x03(\t\x1a\xff\x02\n\x07Request\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06method\x18\x02 \x01(\t\x12J\n\x07headers\x18\x03 \x03(\x0b\x32\x39.google.rpc.context.AttributeContext.Request.HeadersEntry\x12\x0c\n\x04path\x18\x04 \x01(\t\x12\x0c\n\x04host\x18\x05 \x01(\t\x12\x0e\n\x06scheme\x18\x06 \x01(\t\x12\r\n\x05query\x18\x07 \x01(\t\x12(\n\x04time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04size\x18\n \x01(\x03\x12\x10\n\x08protocol\x18\x0b \x01(\t\x12\x0e\n\x06reason\x18\x0c \x01(\t\x12\x37\n\x04\x61uth\x18\r \x01(\x0b\x32).google.rpc.context.AttributeContext.Auth\x12\x0e\n\x06origin\x18\x0e \x01(\t\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x81\x02\n\x08Response\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x03\x12\x0c\n\x04size\x18\x02 \x01(\x03\x12K\n\x07headers\x18\x03 \x03(\x0b\x32:.google.rpc.context.AttributeContext.Response.HeadersEntry\x12(\n\x04time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0f\x62\x61\x63kend_latency\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x90\x04\n\x08Resource\x12\x0f\n\x07service\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04type\x18\x03 \x01(\t\x12I\n\x06labels\x18\x04 \x03(\x0b\x32\x39.google.rpc.context.AttributeContext.Resource.LabelsEntry\x12\x0b\n\x03uid\x18\x05 \x01(\t\x12S\n\x0b\x61nnotations\x18\x06 \x03(\x0b\x32>.google.rpc.context.AttributeContext.Resource.AnnotationsEntry\x12\x14\n\x0c\x64isplay_name\x18\x07 \x01(\t\x12/\n\x0b\x63reate_time\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bupdate_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0b\x64\x65lete_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04\x65tag\x18\x0b \x01(\t\x12\x10\n\x08location\x18\x0c \x01(\t\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x32\n\x10\x41nnotationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x88\x01\n\x16\x63om.google.rpc.contextB\x15\x41ttributeContextProtoP\x01ZUgoogle.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_contextb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.context.attribute_context_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\026com.google.rpc.contextB\025AttributeContextProtoP\001ZUgoogle.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_context" - _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._loaded_options = None - _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._serialized_options = b"8\001" - _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._loaded_options = None - _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._serialized_options = b"8\001" - _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._loaded_options = None - _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._serialized_options = b"8\001" - _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._loaded_options = None - _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._serialized_options = b"8\001" - _globals["_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY"]._loaded_options = None - _globals[ - "_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY" - ]._serialized_options = b"8\001" - _globals["_ATTRIBUTECONTEXT"]._serialized_start = 189 - _globals["_ATTRIBUTECONTEXT"]._serialized_end = 2256 - _globals["_ATTRIBUTECONTEXT_PEER"]._serialized_start = 682 - _globals["_ATTRIBUTECONTEXT_PEER"]._serialized_end = 872 - _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._serialized_start = 827 - _globals["_ATTRIBUTECONTEXT_PEER_LABELSENTRY"]._serialized_end = 872 - _globals["_ATTRIBUTECONTEXT_API"]._serialized_start = 874 - _globals["_ATTRIBUTECONTEXT_API"]._serialized_end = 950 - _globals["_ATTRIBUTECONTEXT_AUTH"]._serialized_start = 952 - _globals["_ATTRIBUTECONTEXT_AUTH"]._serialized_end = 1079 - _globals["_ATTRIBUTECONTEXT_REQUEST"]._serialized_start = 1082 - _globals["_ATTRIBUTECONTEXT_REQUEST"]._serialized_end = 1465 - _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._serialized_start = 1419 - _globals["_ATTRIBUTECONTEXT_REQUEST_HEADERSENTRY"]._serialized_end = 1465 - _globals["_ATTRIBUTECONTEXT_RESPONSE"]._serialized_start = 1468 - _globals["_ATTRIBUTECONTEXT_RESPONSE"]._serialized_end = 1725 - _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._serialized_start = 1419 - _globals["_ATTRIBUTECONTEXT_RESPONSE_HEADERSENTRY"]._serialized_end = 1465 - _globals["_ATTRIBUTECONTEXT_RESOURCE"]._serialized_start = 1728 - _globals["_ATTRIBUTECONTEXT_RESOURCE"]._serialized_end = 2256 - _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._serialized_start = 827 - _globals["_ATTRIBUTECONTEXT_RESOURCE_LABELSENTRY"]._serialized_end = 872 - _globals["_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY"]._serialized_start = 2206 - _globals["_ATTRIBUTECONTEXT_RESOURCE_ANNOTATIONSENTRY"]._serialized_end = 2256 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi deleted file mode 100644 index feab1f6f623..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/attribute_context_pb2.pyi +++ /dev/null @@ -1,326 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import any_pb2 as _any_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import duration_pb2 as _duration_pb2 -from google.protobuf import message as _message -from google.protobuf import struct_pb2 as _struct_pb2 -from google.protobuf import timestamp_pb2 as _timestamp_pb2 -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class AttributeContext(_message.Message): - __slots__ = ( - "origin", - "source", - "destination", - "request", - "response", - "resource", - "api", - "extensions", - ) - class Peer(_message.Message): - __slots__ = ("ip", "port", "labels", "principal", "region_code") - class LabelsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - IP_FIELD_NUMBER: _ClassVar[int] - PORT_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - PRINCIPAL_FIELD_NUMBER: _ClassVar[int] - REGION_CODE_FIELD_NUMBER: _ClassVar[int] - ip: str - port: int - labels: _containers.ScalarMap[str, str] - principal: str - region_code: str - def __init__( - self, - ip: _Optional[str] = ..., - port: _Optional[int] = ..., - labels: _Optional[_Mapping[str, str]] = ..., - principal: _Optional[str] = ..., - region_code: _Optional[str] = ..., - ) -> None: ... - - class Api(_message.Message): - __slots__ = ("service", "operation", "protocol", "version") - SERVICE_FIELD_NUMBER: _ClassVar[int] - OPERATION_FIELD_NUMBER: _ClassVar[int] - PROTOCOL_FIELD_NUMBER: _ClassVar[int] - VERSION_FIELD_NUMBER: _ClassVar[int] - service: str - operation: str - protocol: str - version: str - def __init__( - self, - service: _Optional[str] = ..., - operation: _Optional[str] = ..., - protocol: _Optional[str] = ..., - version: _Optional[str] = ..., - ) -> None: ... - - class Auth(_message.Message): - __slots__ = ("principal", "audiences", "presenter", "claims", "access_levels") - PRINCIPAL_FIELD_NUMBER: _ClassVar[int] - AUDIENCES_FIELD_NUMBER: _ClassVar[int] - PRESENTER_FIELD_NUMBER: _ClassVar[int] - CLAIMS_FIELD_NUMBER: _ClassVar[int] - ACCESS_LEVELS_FIELD_NUMBER: _ClassVar[int] - principal: str - audiences: _containers.RepeatedScalarFieldContainer[str] - presenter: str - claims: _struct_pb2.Struct - access_levels: _containers.RepeatedScalarFieldContainer[str] - def __init__( - self, - principal: _Optional[str] = ..., - audiences: _Optional[_Iterable[str]] = ..., - presenter: _Optional[str] = ..., - claims: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., - access_levels: _Optional[_Iterable[str]] = ..., - ) -> None: ... - - class Request(_message.Message): - __slots__ = ( - "id", - "method", - "headers", - "path", - "host", - "scheme", - "query", - "time", - "size", - "protocol", - "reason", - "auth", - "origin", - ) - class HeadersEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - ID_FIELD_NUMBER: _ClassVar[int] - METHOD_FIELD_NUMBER: _ClassVar[int] - HEADERS_FIELD_NUMBER: _ClassVar[int] - PATH_FIELD_NUMBER: _ClassVar[int] - HOST_FIELD_NUMBER: _ClassVar[int] - SCHEME_FIELD_NUMBER: _ClassVar[int] - QUERY_FIELD_NUMBER: _ClassVar[int] - TIME_FIELD_NUMBER: _ClassVar[int] - SIZE_FIELD_NUMBER: _ClassVar[int] - PROTOCOL_FIELD_NUMBER: _ClassVar[int] - REASON_FIELD_NUMBER: _ClassVar[int] - AUTH_FIELD_NUMBER: _ClassVar[int] - ORIGIN_FIELD_NUMBER: _ClassVar[int] - id: str - method: str - headers: _containers.ScalarMap[str, str] - path: str - host: str - scheme: str - query: str - time: _timestamp_pb2.Timestamp - size: int - protocol: str - reason: str - auth: AttributeContext.Auth - origin: str - def __init__( - self, - id: _Optional[str] = ..., - method: _Optional[str] = ..., - headers: _Optional[_Mapping[str, str]] = ..., - path: _Optional[str] = ..., - host: _Optional[str] = ..., - scheme: _Optional[str] = ..., - query: _Optional[str] = ..., - time: _Optional[ - _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] - ] = ..., - size: _Optional[int] = ..., - protocol: _Optional[str] = ..., - reason: _Optional[str] = ..., - auth: _Optional[_Union[AttributeContext.Auth, _Mapping]] = ..., - origin: _Optional[str] = ..., - ) -> None: ... - - class Response(_message.Message): - __slots__ = ("code", "size", "headers", "time", "backend_latency") - class HeadersEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - CODE_FIELD_NUMBER: _ClassVar[int] - SIZE_FIELD_NUMBER: _ClassVar[int] - HEADERS_FIELD_NUMBER: _ClassVar[int] - TIME_FIELD_NUMBER: _ClassVar[int] - BACKEND_LATENCY_FIELD_NUMBER: _ClassVar[int] - code: int - size: int - headers: _containers.ScalarMap[str, str] - time: _timestamp_pb2.Timestamp - backend_latency: _duration_pb2.Duration - def __init__( - self, - code: _Optional[int] = ..., - size: _Optional[int] = ..., - headers: _Optional[_Mapping[str, str]] = ..., - time: _Optional[ - _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] - ] = ..., - backend_latency: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - ) -> None: ... - - class Resource(_message.Message): - __slots__ = ( - "service", - "name", - "type", - "labels", - "uid", - "annotations", - "display_name", - "create_time", - "update_time", - "delete_time", - "etag", - "location", - ) - class LabelsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - class AnnotationsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - SERVICE_FIELD_NUMBER: _ClassVar[int] - NAME_FIELD_NUMBER: _ClassVar[int] - TYPE_FIELD_NUMBER: _ClassVar[int] - LABELS_FIELD_NUMBER: _ClassVar[int] - UID_FIELD_NUMBER: _ClassVar[int] - ANNOTATIONS_FIELD_NUMBER: _ClassVar[int] - DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int] - CREATE_TIME_FIELD_NUMBER: _ClassVar[int] - UPDATE_TIME_FIELD_NUMBER: _ClassVar[int] - DELETE_TIME_FIELD_NUMBER: _ClassVar[int] - ETAG_FIELD_NUMBER: _ClassVar[int] - LOCATION_FIELD_NUMBER: _ClassVar[int] - service: str - name: str - type: str - labels: _containers.ScalarMap[str, str] - uid: str - annotations: _containers.ScalarMap[str, str] - display_name: str - create_time: _timestamp_pb2.Timestamp - update_time: _timestamp_pb2.Timestamp - delete_time: _timestamp_pb2.Timestamp - etag: str - location: str - def __init__( - self, - service: _Optional[str] = ..., - name: _Optional[str] = ..., - type: _Optional[str] = ..., - labels: _Optional[_Mapping[str, str]] = ..., - uid: _Optional[str] = ..., - annotations: _Optional[_Mapping[str, str]] = ..., - display_name: _Optional[str] = ..., - create_time: _Optional[ - _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] - ] = ..., - update_time: _Optional[ - _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] - ] = ..., - delete_time: _Optional[ - _Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping] - ] = ..., - etag: _Optional[str] = ..., - location: _Optional[str] = ..., - ) -> None: ... - - ORIGIN_FIELD_NUMBER: _ClassVar[int] - SOURCE_FIELD_NUMBER: _ClassVar[int] - DESTINATION_FIELD_NUMBER: _ClassVar[int] - REQUEST_FIELD_NUMBER: _ClassVar[int] - RESPONSE_FIELD_NUMBER: _ClassVar[int] - RESOURCE_FIELD_NUMBER: _ClassVar[int] - API_FIELD_NUMBER: _ClassVar[int] - EXTENSIONS_FIELD_NUMBER: _ClassVar[int] - origin: AttributeContext.Peer - source: AttributeContext.Peer - destination: AttributeContext.Peer - request: AttributeContext.Request - response: AttributeContext.Response - resource: AttributeContext.Resource - api: AttributeContext.Api - extensions: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] - def __init__( - self, - origin: _Optional[_Union[AttributeContext.Peer, _Mapping]] = ..., - source: _Optional[_Union[AttributeContext.Peer, _Mapping]] = ..., - destination: _Optional[_Union[AttributeContext.Peer, _Mapping]] = ..., - request: _Optional[_Union[AttributeContext.Request, _Mapping]] = ..., - response: _Optional[_Union[AttributeContext.Response, _Mapping]] = ..., - resource: _Optional[_Union[AttributeContext.Resource, _Mapping]] = ..., - api: _Optional[_Union[AttributeContext.Api, _Mapping]] = ..., - extensions: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto deleted file mode 100644 index 03c5ab9a508..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.rpc.context; - -import "google/protobuf/struct.proto"; - -option go_package = "google.golang.org/genproto/googleapis/rpc/context;context"; -option java_multiple_files = true; -option java_outer_classname = "AuditContextProto"; -option java_package = "com.google.rpc.context"; - -// `AuditContext` provides information that is needed for audit logging. -message AuditContext { - // Serialized audit log. - bytes audit_log = 1; - - // An API request message that is scrubbed based on the method annotation. - // This field should only be filled if audit_log field is present. - // Service Control will use this to assemble a complete log for Cloud Audit - // Logs and Google internal audit logs. - google.protobuf.Struct scrubbed_request = 2; - - // An API response message that is scrubbed based on the method annotation. - // This field should only be filled if audit_log field is present. - // Service Control will use this to assemble a complete log for Cloud Audit - // Logs and Google internal audit logs. - google.protobuf.Struct scrubbed_response = 3; - - // Number of scrubbed response items. - int32 scrubbed_response_item_count = 4; - - // Audit resource name which is scrubbed. - string target_resource = 5; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py deleted file mode 100644 index 41cacce0ac6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/rpc/context/audit_context.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 6, - 33, - 5, - "", - "google/rpc/context/audit_context.proto", -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n&google/rpc/context/audit_context.proto\x12\x12google.rpc.context\x1a\x1cgoogle/protobuf/struct.proto"\xc7\x01\n\x0c\x41uditContext\x12\x11\n\taudit_log\x18\x01 \x01(\x0c\x12\x31\n\x10scrubbed_request\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x32\n\x11scrubbed_response\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12$\n\x1cscrubbed_response_item_count\x18\x04 \x01(\x05\x12\x17\n\x0ftarget_resource\x18\x05 \x01(\tBh\n\x16\x63om.google.rpc.contextB\x11\x41uditContextProtoP\x01Z9google.golang.org/genproto/googleapis/rpc/context;contextb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.context.audit_context_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\026com.google.rpc.contextB\021AuditContextProtoP\001Z9google.golang.org/genproto/googleapis/rpc/context;context" - _globals["_AUDITCONTEXT"]._serialized_start = 93 - _globals["_AUDITCONTEXT"]._serialized_end = 292 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi deleted file mode 100644 index 720be02d377..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/context/audit_context_pb2.pyi +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import struct_pb2 as _struct_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class AuditContext(_message.Message): - __slots__ = ( - "audit_log", - "scrubbed_request", - "scrubbed_response", - "scrubbed_response_item_count", - "target_resource", - ) - AUDIT_LOG_FIELD_NUMBER: _ClassVar[int] - SCRUBBED_REQUEST_FIELD_NUMBER: _ClassVar[int] - SCRUBBED_RESPONSE_FIELD_NUMBER: _ClassVar[int] - SCRUBBED_RESPONSE_ITEM_COUNT_FIELD_NUMBER: _ClassVar[int] - TARGET_RESOURCE_FIELD_NUMBER: _ClassVar[int] - audit_log: bytes - scrubbed_request: _struct_pb2.Struct - scrubbed_response: _struct_pb2.Struct - scrubbed_response_item_count: int - target_resource: str - def __init__( - self, - audit_log: _Optional[bytes] = ..., - scrubbed_request: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., - scrubbed_response: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., - scrubbed_response_item_count: _Optional[int] = ..., - target_resource: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto deleted file mode 100644 index 43b7d04d2ba..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details.proto +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.rpc; - -import "google/protobuf/duration.proto"; - -option go_package = "google.golang.org/genproto/googleapis/rpc/errdetails;errdetails"; -option java_multiple_files = true; -option java_outer_classname = "ErrorDetailsProto"; -option java_package = "com.google.rpc"; -option objc_class_prefix = "RPC"; - -// Describes the cause of the error with structured details. -// -// Example of an error when contacting the "pubsub.googleapis.com" API when it -// is not enabled: -// -// { "reason": "API_DISABLED" -// "domain": "googleapis.com" -// "metadata": { -// "resource": "projects/123", -// "service": "pubsub.googleapis.com" -// } -// } -// -// This response indicates that the pubsub.googleapis.com API is not enabled. -// -// Example of an error that is returned when attempting to create a Spanner -// instance in a region that is out of stock: -// -// { "reason": "STOCKOUT" -// "domain": "spanner.googleapis.com", -// "metadata": { -// "availableRegions": "us-central1,us-east2" -// } -// } -message ErrorInfo { - // The reason of the error. This is a constant value that identifies the - // proximate cause of the error. Error reasons are unique within a particular - // domain of errors. This should be at most 63 characters and match a - // regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, which represents - // UPPER_SNAKE_CASE. - string reason = 1; - - // The logical grouping to which the "reason" belongs. The error domain - // is typically the registered service name of the tool or product that - // generates the error. Example: "pubsub.googleapis.com". If the error is - // generated by some common infrastructure, the error domain must be a - // globally unique value that identifies the infrastructure. For Google API - // infrastructure, the error domain is "googleapis.com". - string domain = 2; - - // Additional structured details about this error. - // - // Keys must match a regular expression of `[a-z][a-zA-Z0-9-_]+` but should - // ideally be lowerCamelCase. Also, they must be limited to 64 characters in - // length. When identifying the current value of an exceeded limit, the units - // should be contained in the key, not the value. For example, rather than - // `{"instanceLimit": "100/request"}`, should be returned as, - // `{"instanceLimitPerRequest": "100"}`, if the client exceeds the number of - // instances that can be created in a single (batch) request. - map metadata = 3; -} - -// Describes when the clients can retry a failed request. Clients could ignore -// the recommendation here or retry when this information is missing from error -// responses. -// -// It's always recommended that clients should use exponential backoff when -// retrying. -// -// Clients should wait until `retry_delay` amount of time has passed since -// receiving the error response before retrying. If retrying requests also -// fail, clients should use an exponential backoff scheme to gradually increase -// the delay between retries based on `retry_delay`, until either a maximum -// number of retries have been reached or a maximum retry delay cap has been -// reached. -message RetryInfo { - // Clients should wait at least this long between retrying the same request. - google.protobuf.Duration retry_delay = 1; -} - -// Describes additional debugging info. -message DebugInfo { - // The stack trace entries indicating where the error occurred. - repeated string stack_entries = 1; - - // Additional debugging information provided by the server. - string detail = 2; -} - -// Describes how a quota check failed. -// -// For example if a daily limit was exceeded for the calling project, -// a service could respond with a QuotaFailure detail containing the project -// id and the description of the quota limit that was exceeded. If the -// calling project hasn't enabled the service in the developer console, then -// a service could respond with the project id and set `service_disabled` -// to true. -// -// Also see RetryInfo and Help types for other details about handling a -// quota failure. -message QuotaFailure { - // A message type used to describe a single quota violation. For example, a - // daily quota or a custom quota that was exceeded. - message Violation { - // The subject on which the quota check failed. - // For example, "clientip:" or "project:". - string subject = 1; - - // A description of how the quota check failed. Clients can use this - // description to find more about the quota configuration in the service's - // public documentation, or find the relevant quota limit to adjust through - // developer console. - // - // For example: "Service disabled" or "Daily Limit for read operations - // exceeded". - string description = 2; - - // The API Service from which the `QuotaFailure.Violation` orginates. In - // some cases, Quota issues originate from an API Service other than the one - // that was called. In other words, a dependency of the called API Service - // could be the cause of the `QuotaFailure`, and this field would have the - // dependency API service name. - // - // For example, if the called API is Kubernetes Engine API - // (container.googleapis.com), and a quota violation occurs in the - // Kubernetes Engine API itself, this field would be - // "container.googleapis.com". On the other hand, if the quota violation - // occurs when the Kubernetes Engine API creates VMs in the Compute Engine - // API (compute.googleapis.com), this field would be - // "compute.googleapis.com". - string api_service = 3; - - // The metric of the violated quota. A quota metric is a named counter to - // measure usage, such as API requests or CPUs. When an activity occurs in a - // service, such as Virtual Machine allocation, one or more quota metrics - // may be affected. - // - // For example, "compute.googleapis.com/cpus_per_vm_family", - // "storage.googleapis.com/internet_egress_bandwidth". - string quota_metric = 4; - - // The id of the violated quota. Also know as "limit name", this is the - // unique identifier of a quota in the context of an API service. - // - // For example, "CPUS-PER-VM-FAMILY-per-project-region". - string quota_id = 5; - - // The dimensions of the violated quota. Every non-global quota is enforced - // on a set of dimensions. While quota metric defines what to count, the - // dimensions specify for what aspects the counter should be increased. - // - // For example, the quota "CPUs per region per VM family" enforces a limit - // on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions - // "region" and "vm_family". And if the violation occurred in region - // "us-central1" and for VM family "n1", the quota_dimensions would be, - // - // { - // "region": "us-central1", - // "vm_family": "n1", - // } - // - // When a quota is enforced globally, the quota_dimensions would always be - // empty. - map quota_dimensions = 6; - - // The enforced quota value at the time of the `QuotaFailure`. - // - // For example, if the enforced quota value at the time of the - // `QuotaFailure` on the number of CPUs is "10", then the value of this - // field would reflect this quantity. - int64 quota_value = 7; - - // The new quota value being rolled out at the time of the violation. At the - // completion of the rollout, this value will be enforced in place of - // quota_value. If no rollout is in progress at the time of the violation, - // this field is not set. - // - // For example, if at the time of the violation a rollout is in progress - // changing the number of CPUs quota from 10 to 20, 20 would be the value of - // this field. - optional int64 future_quota_value = 8; - } - - // Describes all quota violations. - repeated Violation violations = 1; -} - -// Describes what preconditions have failed. -// -// For example, if an RPC failed because it required the Terms of Service to be -// acknowledged, it could list the terms of service violation in the -// PreconditionFailure message. -message PreconditionFailure { - // A message type used to describe a single precondition failure. - message Violation { - // The type of PreconditionFailure. We recommend using a service-specific - // enum type to define the supported precondition violation subjects. For - // example, "TOS" for "Terms of Service violation". - string type = 1; - - // The subject, relative to the type, that failed. - // For example, "google.com/cloud" relative to the "TOS" type would indicate - // which terms of service is being referenced. - string subject = 2; - - // A description of how the precondition failed. Developers can use this - // description to understand how to fix the failure. - // - // For example: "Terms of service not accepted". - string description = 3; - } - - // Describes all precondition violations. - repeated Violation violations = 1; -} - -// Describes violations in a client request. This error type focuses on the -// syntactic aspects of the request. -message BadRequest { - // A message type used to describe a single bad request field. - message FieldViolation { - // A path that leads to a field in the request body. The value will be a - // sequence of dot-separated identifiers that identify a protocol buffer - // field. - // - // Consider the following: - // - // message CreateContactRequest { - // message EmailAddress { - // enum Type { - // TYPE_UNSPECIFIED = 0; - // HOME = 1; - // WORK = 2; - // } - // - // optional string email = 1; - // repeated EmailType type = 2; - // } - // - // string full_name = 1; - // repeated EmailAddress email_addresses = 2; - // } - // - // In this example, in proto `field` could take one of the following values: - // - // * `full_name` for a violation in the `full_name` value - // * `email_addresses[0].email` for a violation in the `email` field of the - // first `email_addresses` message - // * `email_addresses[2].type[1]` for a violation in the second `type` - // value in the third `email_addresses` message. - // - // In JSON, the same values are represented as: - // - // * `fullName` for a violation in the `fullName` value - // * `emailAddresses[0].email` for a violation in the `email` field of the - // first `emailAddresses` message - // * `emailAddresses[2].type[1]` for a violation in the second `type` - // value in the third `emailAddresses` message. - string field = 1; - - // A description of why the request element is bad. - string description = 2; - - // The reason of the field-level error. This is a constant value that - // identifies the proximate cause of the field-level error. It should - // uniquely identify the type of the FieldViolation within the scope of the - // google.rpc.ErrorInfo.domain. This should be at most 63 - // characters and match a regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, - // which represents UPPER_SNAKE_CASE. - string reason = 3; - - // Provides a localized error message for field-level errors that is safe to - // return to the API consumer. - LocalizedMessage localized_message = 4; - } - - // Describes all violations in a client request. - repeated FieldViolation field_violations = 1; -} - -// Contains metadata about the request that clients can attach when filing a bug -// or providing other forms of feedback. -message RequestInfo { - // An opaque string that should only be interpreted by the service generating - // it. For example, it can be used to identify requests in the service's logs. - string request_id = 1; - - // Any data that was used to serve this request. For example, an encrypted - // stack trace that can be sent back to the service provider for debugging. - string serving_data = 2; -} - -// Describes the resource that is being accessed. -message ResourceInfo { - // A name for the type of resource being accessed, e.g. "sql table", - // "cloud storage bucket", "file", "Google calendar"; or the type URL - // of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". - string resource_type = 1; - - // The name of the resource being accessed. For example, a shared calendar - // name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current - // error is - // [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. - string resource_name = 2; - - // The owner of the resource (optional). - // For example, "user:" or "project:". - string owner = 3; - - // Describes what error is encountered when accessing this resource. - // For example, updating a cloud project may require the `writer` permission - // on the developer console project. - string description = 4; -} - -// Provides links to documentation or for performing an out of band action. -// -// For example, if a quota check failed with an error indicating the calling -// project hasn't enabled the accessed service, this can contain a URL pointing -// directly to the right place in the developer console to flip the bit. -message Help { - // Describes a URL link. - message Link { - // Describes what the link offers. - string description = 1; - - // The URL of the link. - string url = 2; - } - - // URL(s) pointing to additional information on handling the current error. - repeated Link links = 1; -} - -// Provides a localized error message that is safe to return to the user -// which can be attached to an RPC error. -message LocalizedMessage { - // The locale used following the specification defined at - // https://www.rfc-editor.org/rfc/bcp/bcp47.txt. - // Examples are: "en-US", "fr-CH", "es-MX" - string locale = 1; - - // The localized error message in the above locale. - string message = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py deleted file mode 100644 index b53f087da55..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/rpc/error_details.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/error_details.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1egoogle/rpc/error_details.proto\x12\ngoogle.rpc\x1a\x1egoogle/protobuf/duration.proto"\x93\x01\n\tErrorInfo\x12\x0e\n\x06reason\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\x12\x35\n\x08metadata\x18\x03 \x03(\x0b\x32#.google.rpc.ErrorInfo.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01";\n\tRetryInfo\x12.\n\x0bretry_delay\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration"2\n\tDebugInfo\x12\x15\n\rstack_entries\x18\x01 \x03(\t\x12\x0e\n\x06\x64\x65tail\x18\x02 \x01(\t"\x8f\x03\n\x0cQuotaFailure\x12\x36\n\nviolations\x18\x01 \x03(\x0b\x32".google.rpc.QuotaFailure.Violation\x1a\xc6\x02\n\tViolation\x12\x0f\n\x07subject\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x13\n\x0b\x61pi_service\x18\x03 \x01(\t\x12\x14\n\x0cquota_metric\x18\x04 \x01(\t\x12\x10\n\x08quota_id\x18\x05 \x01(\t\x12Q\n\x10quota_dimensions\x18\x06 \x03(\x0b\x32\x37.google.rpc.QuotaFailure.Violation.QuotaDimensionsEntry\x12\x13\n\x0bquota_value\x18\x07 \x01(\x03\x12\x1f\n\x12\x66uture_quota_value\x18\x08 \x01(\x03H\x00\x88\x01\x01\x1a\x36\n\x14QuotaDimensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x15\n\x13_future_quota_value"\x95\x01\n\x13PreconditionFailure\x12=\n\nviolations\x18\x01 \x03(\x0b\x32).google.rpc.PreconditionFailure.Violation\x1a?\n\tViolation\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07subject\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"\xcc\x01\n\nBadRequest\x12?\n\x10\x66ield_violations\x18\x01 \x03(\x0b\x32%.google.rpc.BadRequest.FieldViolation\x1a}\n\x0e\x46ieldViolation\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x37\n\x11localized_message\x18\x04 \x01(\x0b\x32\x1c.google.rpc.LocalizedMessage"7\n\x0bRequestInfo\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x14\n\x0cserving_data\x18\x02 \x01(\t"`\n\x0cResourceInfo\x12\x15\n\rresource_type\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\r\n\x05owner\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t"V\n\x04Help\x12$\n\x05links\x18\x01 \x03(\x0b\x32\x15.google.rpc.Help.Link\x1a(\n\x04Link\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t"3\n\x10LocalizedMessage\x12\x0e\n\x06locale\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\tBl\n\x0e\x63om.google.rpcB\x11\x45rrorDetailsProtoP\x01Z?google.golang.org/genproto/googleapis/rpc/errdetails;errdetails\xa2\x02\x03RPCb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.error_details_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.rpcB\021ErrorDetailsProtoP\001Z?google.golang.org/genproto/googleapis/rpc/errdetails;errdetails\242\002\003RPC" - _globals["_ERRORINFO_METADATAENTRY"]._loaded_options = None - _globals["_ERRORINFO_METADATAENTRY"]._serialized_options = b"8\001" - _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._loaded_options = None - _globals[ - "_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY" - ]._serialized_options = b"8\001" - _globals["_ERRORINFO"]._serialized_start = 79 - _globals["_ERRORINFO"]._serialized_end = 226 - _globals["_ERRORINFO_METADATAENTRY"]._serialized_start = 179 - _globals["_ERRORINFO_METADATAENTRY"]._serialized_end = 226 - _globals["_RETRYINFO"]._serialized_start = 228 - _globals["_RETRYINFO"]._serialized_end = 287 - _globals["_DEBUGINFO"]._serialized_start = 289 - _globals["_DEBUGINFO"]._serialized_end = 339 - _globals["_QUOTAFAILURE"]._serialized_start = 342 - _globals["_QUOTAFAILURE"]._serialized_end = 741 - _globals["_QUOTAFAILURE_VIOLATION"]._serialized_start = 415 - _globals["_QUOTAFAILURE_VIOLATION"]._serialized_end = 741 - _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._serialized_start = 664 - _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._serialized_end = 718 - _globals["_PRECONDITIONFAILURE"]._serialized_start = 744 - _globals["_PRECONDITIONFAILURE"]._serialized_end = 893 - _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_start = 830 - _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_end = 893 - _globals["_BADREQUEST"]._serialized_start = 896 - _globals["_BADREQUEST"]._serialized_end = 1100 - _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_start = 975 - _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_end = 1100 - _globals["_REQUESTINFO"]._serialized_start = 1102 - _globals["_REQUESTINFO"]._serialized_end = 1157 - _globals["_RESOURCEINFO"]._serialized_start = 1159 - _globals["_RESOURCEINFO"]._serialized_end = 1255 - _globals["_HELP"]._serialized_start = 1257 - _globals["_HELP"]._serialized_end = 1343 - _globals["_HELP_LINK"]._serialized_start = 1303 - _globals["_HELP_LINK"]._serialized_end = 1343 - _globals["_LOCALIZEDMESSAGE"]._serialized_start = 1345 - _globals["_LOCALIZEDMESSAGE"]._serialized_end = 1396 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi deleted file mode 100644 index d581ac79152..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/error_details_pb2.pyi +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import datetime -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import duration_pb2 as _duration_pb2 -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class ErrorInfo(_message.Message): - __slots__ = ("reason", "domain", "metadata") - class MetadataEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - REASON_FIELD_NUMBER: _ClassVar[int] - DOMAIN_FIELD_NUMBER: _ClassVar[int] - METADATA_FIELD_NUMBER: _ClassVar[int] - reason: str - domain: str - metadata: _containers.ScalarMap[str, str] - def __init__( - self, - reason: _Optional[str] = ..., - domain: _Optional[str] = ..., - metadata: _Optional[_Mapping[str, str]] = ..., - ) -> None: ... - -class RetryInfo(_message.Message): - __slots__ = ("retry_delay",) - RETRY_DELAY_FIELD_NUMBER: _ClassVar[int] - retry_delay: _duration_pb2.Duration - def __init__( - self, - retry_delay: _Optional[ - _Union[datetime.timedelta, _duration_pb2.Duration, _Mapping] - ] = ..., - ) -> None: ... - -class DebugInfo(_message.Message): - __slots__ = ("stack_entries", "detail") - STACK_ENTRIES_FIELD_NUMBER: _ClassVar[int] - DETAIL_FIELD_NUMBER: _ClassVar[int] - stack_entries: _containers.RepeatedScalarFieldContainer[str] - detail: str - def __init__( - self, - stack_entries: _Optional[_Iterable[str]] = ..., - detail: _Optional[str] = ..., - ) -> None: ... - -class QuotaFailure(_message.Message): - __slots__ = ("violations",) - class Violation(_message.Message): - __slots__ = ( - "subject", - "description", - "api_service", - "quota_metric", - "quota_id", - "quota_dimensions", - "quota_value", - "future_quota_value", - ) - class QuotaDimensionsEntry(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... - - SUBJECT_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - API_SERVICE_FIELD_NUMBER: _ClassVar[int] - QUOTA_METRIC_FIELD_NUMBER: _ClassVar[int] - QUOTA_ID_FIELD_NUMBER: _ClassVar[int] - QUOTA_DIMENSIONS_FIELD_NUMBER: _ClassVar[int] - QUOTA_VALUE_FIELD_NUMBER: _ClassVar[int] - FUTURE_QUOTA_VALUE_FIELD_NUMBER: _ClassVar[int] - subject: str - description: str - api_service: str - quota_metric: str - quota_id: str - quota_dimensions: _containers.ScalarMap[str, str] - quota_value: int - future_quota_value: int - def __init__( - self, - subject: _Optional[str] = ..., - description: _Optional[str] = ..., - api_service: _Optional[str] = ..., - quota_metric: _Optional[str] = ..., - quota_id: _Optional[str] = ..., - quota_dimensions: _Optional[_Mapping[str, str]] = ..., - quota_value: _Optional[int] = ..., - future_quota_value: _Optional[int] = ..., - ) -> None: ... - - VIOLATIONS_FIELD_NUMBER: _ClassVar[int] - violations: _containers.RepeatedCompositeFieldContainer[QuotaFailure.Violation] - def __init__( - self, - violations: _Optional[ - _Iterable[_Union[QuotaFailure.Violation, _Mapping]] - ] = ..., - ) -> None: ... - -class PreconditionFailure(_message.Message): - __slots__ = ("violations",) - class Violation(_message.Message): - __slots__ = ("type", "subject", "description") - TYPE_FIELD_NUMBER: _ClassVar[int] - SUBJECT_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - type: str - subject: str - description: str - def __init__( - self, - type: _Optional[str] = ..., - subject: _Optional[str] = ..., - description: _Optional[str] = ..., - ) -> None: ... - - VIOLATIONS_FIELD_NUMBER: _ClassVar[int] - violations: _containers.RepeatedCompositeFieldContainer[ - PreconditionFailure.Violation - ] - def __init__( - self, - violations: _Optional[ - _Iterable[_Union[PreconditionFailure.Violation, _Mapping]] - ] = ..., - ) -> None: ... - -class BadRequest(_message.Message): - __slots__ = ("field_violations",) - class FieldViolation(_message.Message): - __slots__ = ("field", "description", "reason", "localized_message") - FIELD_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - REASON_FIELD_NUMBER: _ClassVar[int] - LOCALIZED_MESSAGE_FIELD_NUMBER: _ClassVar[int] - field: str - description: str - reason: str - localized_message: LocalizedMessage - def __init__( - self, - field: _Optional[str] = ..., - description: _Optional[str] = ..., - reason: _Optional[str] = ..., - localized_message: _Optional[_Union[LocalizedMessage, _Mapping]] = ..., - ) -> None: ... - - FIELD_VIOLATIONS_FIELD_NUMBER: _ClassVar[int] - field_violations: _containers.RepeatedCompositeFieldContainer[ - BadRequest.FieldViolation - ] - def __init__( - self, - field_violations: _Optional[ - _Iterable[_Union[BadRequest.FieldViolation, _Mapping]] - ] = ..., - ) -> None: ... - -class RequestInfo(_message.Message): - __slots__ = ("request_id", "serving_data") - REQUEST_ID_FIELD_NUMBER: _ClassVar[int] - SERVING_DATA_FIELD_NUMBER: _ClassVar[int] - request_id: str - serving_data: str - def __init__( - self, request_id: _Optional[str] = ..., serving_data: _Optional[str] = ... - ) -> None: ... - -class ResourceInfo(_message.Message): - __slots__ = ("resource_type", "resource_name", "owner", "description") - RESOURCE_TYPE_FIELD_NUMBER: _ClassVar[int] - RESOURCE_NAME_FIELD_NUMBER: _ClassVar[int] - OWNER_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - resource_type: str - resource_name: str - owner: str - description: str - def __init__( - self, - resource_type: _Optional[str] = ..., - resource_name: _Optional[str] = ..., - owner: _Optional[str] = ..., - description: _Optional[str] = ..., - ) -> None: ... - -class Help(_message.Message): - __slots__ = ("links",) - class Link(_message.Message): - __slots__ = ("description", "url") - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - URL_FIELD_NUMBER: _ClassVar[int] - description: str - url: str - def __init__( - self, description: _Optional[str] = ..., url: _Optional[str] = ... - ) -> None: ... - - LINKS_FIELD_NUMBER: _ClassVar[int] - links: _containers.RepeatedCompositeFieldContainer[Help.Link] - def __init__( - self, links: _Optional[_Iterable[_Union[Help.Link, _Mapping]]] = ... - ) -> None: ... - -class LocalizedMessage(_message.Message): - __slots__ = ("locale", "message") - LOCALE_FIELD_NUMBER: _ClassVar[int] - MESSAGE_FIELD_NUMBER: _ClassVar[int] - locale: str - message: str - def __init__( - self, locale: _Optional[str] = ..., message: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto deleted file mode 100644 index 9d97b601d9f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http.proto +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.rpc; - -option go_package = "google.golang.org/genproto/googleapis/rpc/http;http"; -option java_multiple_files = true; -option java_outer_classname = "HttpProto"; -option java_package = "com.google.rpc"; -option objc_class_prefix = "RPC"; - -// Represents an HTTP request. -message HttpRequest { - // The HTTP request method. - string method = 1; - - // The HTTP request URI. - string uri = 2; - - // The HTTP request headers. The ordering of the headers is significant. - // Multiple headers with the same key may present for the request. - repeated HttpHeader headers = 3; - - // The HTTP request body. If the body is not expected, it should be empty. - bytes body = 4; -} - -// Represents an HTTP response. -message HttpResponse { - // The HTTP status code, such as 200 or 404. - int32 status = 1; - - // The HTTP reason phrase, such as "OK" or "Not Found". - string reason = 2; - - // The HTTP response headers. The ordering of the headers is significant. - // Multiple headers with the same key may present for the response. - repeated HttpHeader headers = 3; - - // The HTTP response body. If the body is not expected, it should be empty. - bytes body = 4; -} - -// Represents an HTTP header. -message HttpHeader { - // The HTTP header key. It is case insensitive. - string key = 1; - - // The HTTP header value. - string value = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py deleted file mode 100644 index 57fd1ef8681..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/rpc/http.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/http.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x15google/rpc/http.proto\x12\ngoogle.rpc"a\n\x0bHttpRequest\x12\x0e\n\x06method\x18\x01 \x01(\t\x12\x0b\n\x03uri\x18\x02 \x01(\t\x12\'\n\x07headers\x18\x03 \x03(\x0b\x32\x16.google.rpc.HttpHeader\x12\x0c\n\x04\x62ody\x18\x04 \x01(\x0c"e\n\x0cHttpResponse\x12\x0e\n\x06status\x18\x01 \x01(\x05\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\'\n\x07headers\x18\x03 \x03(\x0b\x32\x16.google.rpc.HttpHeader\x12\x0c\n\x04\x62ody\x18\x04 \x01(\x0c"(\n\nHttpHeader\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\tBX\n\x0e\x63om.google.rpcB\tHttpProtoP\x01Z3google.golang.org/genproto/googleapis/rpc/http;http\xa2\x02\x03RPCb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.http_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.rpcB\tHttpProtoP\001Z3google.golang.org/genproto/googleapis/rpc/http;http\242\002\003RPC" - _globals["_HTTPREQUEST"]._serialized_start = 37 - _globals["_HTTPREQUEST"]._serialized_end = 134 - _globals["_HTTPRESPONSE"]._serialized_start = 136 - _globals["_HTTPRESPONSE"]._serialized_end = 237 - _globals["_HTTPHEADER"]._serialized_start = 239 - _globals["_HTTPHEADER"]._serialized_end = 279 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi deleted file mode 100644 index 69f680b03a4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/http_pb2.pyi +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class HttpRequest(_message.Message): - __slots__ = ("method", "uri", "headers", "body") - METHOD_FIELD_NUMBER: _ClassVar[int] - URI_FIELD_NUMBER: _ClassVar[int] - HEADERS_FIELD_NUMBER: _ClassVar[int] - BODY_FIELD_NUMBER: _ClassVar[int] - method: str - uri: str - headers: _containers.RepeatedCompositeFieldContainer[HttpHeader] - body: bytes - def __init__( - self, - method: _Optional[str] = ..., - uri: _Optional[str] = ..., - headers: _Optional[_Iterable[_Union[HttpHeader, _Mapping]]] = ..., - body: _Optional[bytes] = ..., - ) -> None: ... - -class HttpResponse(_message.Message): - __slots__ = ("status", "reason", "headers", "body") - STATUS_FIELD_NUMBER: _ClassVar[int] - REASON_FIELD_NUMBER: _ClassVar[int] - HEADERS_FIELD_NUMBER: _ClassVar[int] - BODY_FIELD_NUMBER: _ClassVar[int] - status: int - reason: str - headers: _containers.RepeatedCompositeFieldContainer[HttpHeader] - body: bytes - def __init__( - self, - status: _Optional[int] = ..., - reason: _Optional[str] = ..., - headers: _Optional[_Iterable[_Union[HttpHeader, _Mapping]]] = ..., - body: _Optional[bytes] = ..., - ) -> None: ... - -class HttpHeader(_message.Message): - __slots__ = ("key", "value") - KEY_FIELD_NUMBER: _ClassVar[int] - VALUE_FIELD_NUMBER: _ClassVar[int] - key: str - value: str - def __init__( - self, key: _Optional[str] = ..., value: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto deleted file mode 100644 index 97f50b9d890..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status.proto +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.rpc; - -import "google/protobuf/any.proto"; - -option go_package = "google.golang.org/genproto/googleapis/rpc/status;status"; -option java_multiple_files = true; -option java_outer_classname = "StatusProto"; -option java_package = "com.google.rpc"; -option objc_class_prefix = "RPC"; - -// The `Status` type defines a logical error model that is suitable for -// different programming environments, including REST APIs and RPC APIs. It is -// used by [gRPC](https://github.com/grpc). Each `Status` message contains -// three pieces of data: error code, error message, and error details. -// -// You can find out more about this error model and how to work with it in the -// [API Design Guide](https://cloud.google.com/apis/design/errors). -message Status { - // The status code, which should be an enum value of - // [google.rpc.Code][google.rpc.Code]. - int32 code = 1; - - // A developer-facing error message, which should be in English. Any - // user-facing error message should be localized and sent in the - // [google.rpc.Status.details][google.rpc.Status.details] field, or localized - // by the client. - string message = 2; - - // A list of messages that carry the error details. There is a common set of - // message types for APIs to use. - repeated google.protobuf.Any details = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py deleted file mode 100644 index 2d713790e3c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/rpc/status.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/rpc/status.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x17google/rpc/status.proto\x12\ngoogle.rpc\x1a\x19google/protobuf/any.proto"N\n\x06Status\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\x12%\n\x07\x64\x65tails\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyB^\n\x0e\x63om.google.rpcB\x0bStatusProtoP\x01Z7google.golang.org/genproto/googleapis/rpc/status;status\xa2\x02\x03RPCb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.rpc.status_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\016com.google.rpcB\013StatusProtoP\001Z7google.golang.org/genproto/googleapis/rpc/status;status\242\002\003RPC" - _globals["_STATUS"]._serialized_start = 66 - _globals["_STATUS"]._serialized_end = 144 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi deleted file mode 100644 index c24374a0eca..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/rpc/status_pb2.pyi +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import any_pb2 as _any_pb2 -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class Status(_message.Message): - __slots__ = ("code", "message", "details") - CODE_FIELD_NUMBER: _ClassVar[int] - MESSAGE_FIELD_NUMBER: _ClassVar[int] - DETAILS_FIELD_NUMBER: _ClassVar[int] - code: int - message: str - details: _containers.RepeatedCompositeFieldContainer[_any_pb2.Any] - def __init__( - self, - code: _Optional[int] = ..., - message: _Optional[str] = ..., - details: _Optional[_Iterable[_Union[_any_pb2.Any, _Mapping]]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto deleted file mode 100644 index ae08aebd677..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period.proto +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/calendarperiod;calendarperiod"; -option java_multiple_files = true; -option java_outer_classname = "CalendarPeriodProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// A `CalendarPeriod` represents the abstract concept of a time period that has -// a canonical start. Grammatically, "the start of the current -// `CalendarPeriod`." All calendar times begin at midnight UTC. -enum CalendarPeriod { - // Undefined period, raises an error. - CALENDAR_PERIOD_UNSPECIFIED = 0; - - // A day. - DAY = 1; - - // A week. Weeks begin on Monday, following - // [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). - WEEK = 2; - - // A fortnight. The first calendar fortnight of the year begins at the start - // of week 1 according to - // [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). - FORTNIGHT = 3; - - // A month. - MONTH = 4; - - // A quarter. Quarters start on dates 1-Jan, 1-Apr, 1-Jul, and 1-Oct of each - // year. - QUARTER = 5; - - // A half-year. Half-years start on dates 1-Jan and 1-Jul. - HALF = 6; - - // A year. - YEAR = 7; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py deleted file mode 100644 index 813bccfed09..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/calendar_period.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/calendar_period.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n!google/type/calendar_period.proto\x12\x0bgoogle.type*\x7f\n\x0e\x43\x61lendarPeriod\x12\x1f\n\x1b\x43\x41LENDAR_PERIOD_UNSPECIFIED\x10\x00\x12\x07\n\x03\x44\x41Y\x10\x01\x12\x08\n\x04WEEK\x10\x02\x12\r\n\tFORTNIGHT\x10\x03\x12\t\n\x05MONTH\x10\x04\x12\x0b\n\x07QUARTER\x10\x05\x12\x08\n\x04HALF\x10\x06\x12\x08\n\x04YEAR\x10\x07\x42x\n\x0f\x63om.google.typeB\x13\x43\x61lendarPeriodProtoP\x01ZHgoogle.golang.org/genproto/googleapis/type/calendarperiod;calendarperiod\xa2\x02\x03GTPb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.type.calendar_period_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\023CalendarPeriodProtoP\001ZHgoogle.golang.org/genproto/googleapis/type/calendarperiod;calendarperiod\242\002\003GTP" - _globals["_CALENDARPERIOD"]._serialized_start = 50 - _globals["_CALENDARPERIOD"]._serialized_end = 177 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi deleted file mode 100644 index 2e230b4ed08..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/calendar_period_pb2.pyi +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class CalendarPeriod(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - CALENDAR_PERIOD_UNSPECIFIED: _ClassVar[CalendarPeriod] - DAY: _ClassVar[CalendarPeriod] - WEEK: _ClassVar[CalendarPeriod] - FORTNIGHT: _ClassVar[CalendarPeriod] - MONTH: _ClassVar[CalendarPeriod] - QUARTER: _ClassVar[CalendarPeriod] - HALF: _ClassVar[CalendarPeriod] - YEAR: _ClassVar[CalendarPeriod] - -CALENDAR_PERIOD_UNSPECIFIED: CalendarPeriod -DAY: CalendarPeriod -WEEK: CalendarPeriod -FORTNIGHT: CalendarPeriod -MONTH: CalendarPeriod -QUARTER: CalendarPeriod -HALF: CalendarPeriod -YEAR: CalendarPeriod diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto deleted file mode 100644 index c48d0644a70..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color.proto +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -import "google/protobuf/wrappers.proto"; - -option go_package = "google.golang.org/genproto/googleapis/type/color;color"; -option java_multiple_files = true; -option java_outer_classname = "ColorProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a color in the RGBA color space. This representation is designed -// for simplicity of conversion to and from color representations in various -// languages over compactness. For example, the fields of this representation -// can be trivially provided to the constructor of `java.awt.Color` in Java; it -// can also be trivially provided to UIColor's `+colorWithRed:green:blue:alpha` -// method in iOS; and, with just a little work, it can be easily formatted into -// a CSS `rgba()` string in JavaScript. -// -// This reference page doesn't have information about the absolute color -// space that should be used to interpret the RGB value—for example, sRGB, -// Adobe RGB, -// DCI-P3, and BT.2020. By default, applications should assume the sRGB color -// space. -// -// When color equality needs to be decided, implementations, unless documented -// otherwise, treat two colors as equal if all their red, green, blue, and alpha -// values each differ by at most `1e-5`. -// -// Example (Java): -// -// import com.google.type.Color; -// -// // ... -// public static java.awt.Color fromProto(Color protocolor) { -// float alpha = protocolor.hasAlpha() -// ? protocolor.getAlpha().getValue() -// : 1.0; -// -// return new java.awt.Color( -// protocolor.getRed(), -// protocolor.getGreen(), -// protocolor.getBlue(), -// alpha); -// } -// -// public static Color toProto(java.awt.Color color) { -// float red = (float) color.getRed(); -// float green = (float) color.getGreen(); -// float blue = (float) color.getBlue(); -// float denominator = 255.0; -// Color.Builder resultBuilder = -// Color -// .newBuilder() -// .setRed(red / denominator) -// .setGreen(green / denominator) -// .setBlue(blue / denominator); -// int alpha = color.getAlpha(); -// if (alpha != 255) { -// result.setAlpha( -// FloatValue -// .newBuilder() -// .setValue(((float) alpha) / denominator) -// .build()); -// } -// return resultBuilder.build(); -// } -// // ... -// -// Example (iOS / Obj-C): -// -// // ... -// static UIColor* fromProto(Color* protocolor) { -// float red = [protocolor red]; -// float green = [protocolor green]; -// float blue = [protocolor blue]; -// FloatValue* alpha_wrapper = [protocolor alpha]; -// float alpha = 1.0; -// if (alpha_wrapper != nil) { -// alpha = [alpha_wrapper value]; -// } -// return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; -// } -// -// static Color* toProto(UIColor* color) { -// CGFloat red, green, blue, alpha; -// if (![color getRed:&red green:&green blue:&blue alpha:&alpha]) { -// return nil; -// } -// Color* result = [[Color alloc] init]; -// [result setRed:red]; -// [result setGreen:green]; -// [result setBlue:blue]; -// if (alpha <= 0.9999) { -// [result setAlpha:floatWrapperWithValue(alpha)]; -// } -// [result autorelease]; -// return result; -// } -// // ... -// -// Example (JavaScript): -// -// // ... -// -// var protoToCssColor = function(rgb_color) { -// var redFrac = rgb_color.red || 0.0; -// var greenFrac = rgb_color.green || 0.0; -// var blueFrac = rgb_color.blue || 0.0; -// var red = Math.floor(redFrac * 255); -// var green = Math.floor(greenFrac * 255); -// var blue = Math.floor(blueFrac * 255); -// -// if (!('alpha' in rgb_color)) { -// return rgbToCssColor(red, green, blue); -// } -// -// var alphaFrac = rgb_color.alpha.value || 0.0; -// var rgbParams = [red, green, blue].join(','); -// return ['rgba(', rgbParams, ',', alphaFrac, ')'].join(''); -// }; -// -// var rgbToCssColor = function(red, green, blue) { -// var rgbNumber = new Number((red << 16) | (green << 8) | blue); -// var hexString = rgbNumber.toString(16); -// var missingZeros = 6 - hexString.length; -// var resultBuilder = ['#']; -// for (var i = 0; i < missingZeros; i++) { -// resultBuilder.push('0'); -// } -// resultBuilder.push(hexString); -// return resultBuilder.join(''); -// }; -// -// // ... -message Color { - // The amount of red in the color as a value in the interval [0, 1]. - float red = 1; - - // The amount of green in the color as a value in the interval [0, 1]. - float green = 2; - - // The amount of blue in the color as a value in the interval [0, 1]. - float blue = 3; - - // The fraction of this color that should be applied to the pixel. That is, - // the final pixel color is defined by the equation: - // - // `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` - // - // This means that a value of 1.0 corresponds to a solid color, whereas - // a value of 0.0 corresponds to a completely transparent color. This - // uses a wrapper message rather than a simple float scalar so that it is - // possible to distinguish between a default value and the value being unset. - // If omitted, this color object is rendered as a solid color - // (as if the alpha value had been explicitly given a value of 1.0). - google.protobuf.FloatValue alpha = 4; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py deleted file mode 100644 index 5e4e0a27f69..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/color.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/color.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x17google/type/color.proto\x12\x0bgoogle.type\x1a\x1egoogle/protobuf/wrappers.proto"]\n\x05\x43olor\x12\x0b\n\x03red\x18\x01 \x01(\x02\x12\r\n\x05green\x18\x02 \x01(\x02\x12\x0c\n\x04\x62lue\x18\x03 \x01(\x02\x12*\n\x05\x61lpha\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.FloatValueB]\n\x0f\x63om.google.typeB\nColorProtoP\x01Z6google.golang.org/genproto/googleapis/type/color;color\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.color_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\nColorProtoP\001Z6google.golang.org/genproto/googleapis/type/color;color\242\002\003GTP" - _globals["_COLOR"]._serialized_start = 72 - _globals["_COLOR"]._serialized_end = 165 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi deleted file mode 100644 index c80242e79bb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/color_pb2.pyi +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import wrappers_pb2 as _wrappers_pb2 - -DESCRIPTOR: _descriptor.FileDescriptor - -class Color(_message.Message): - __slots__ = ("red", "green", "blue", "alpha") - RED_FIELD_NUMBER: _ClassVar[int] - GREEN_FIELD_NUMBER: _ClassVar[int] - BLUE_FIELD_NUMBER: _ClassVar[int] - ALPHA_FIELD_NUMBER: _ClassVar[int] - red: float - green: float - blue: float - alpha: _wrappers_pb2.FloatValue - def __init__( - self, - red: _Optional[float] = ..., - green: _Optional[float] = ..., - blue: _Optional[float] = ..., - alpha: _Optional[_Union[_wrappers_pb2.FloatValue, _Mapping]] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto deleted file mode 100644 index 12be7e16a48..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date.proto +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/date;date"; -option java_multiple_files = true; -option java_outer_classname = "DateProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a whole or partial calendar date, such as a birthday. The time of -// day and time zone are either specified elsewhere or are insignificant. The -// date is relative to the Gregorian Calendar. This can represent one of the -// following: -// -// * A full date, with non-zero year, month, and day values. -// * A month and day, with a zero year (for example, an anniversary). -// * A year on its own, with a zero month and a zero day. -// * A year and month, with a zero day (for example, a credit card expiration -// date). -// -// Related types: -// -// * [google.type.TimeOfDay][google.type.TimeOfDay] -// * [google.type.DateTime][google.type.DateTime] -// * [google.protobuf.Timestamp][google.protobuf.Timestamp] -message Date { - // Year of the date. Must be from 1 to 9999, or 0 to specify a date without - // a year. - int32 year = 1; - - // Month of a year. Must be from 1 to 12, or 0 to specify a year without a - // month and day. - int32 month = 2; - - // Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 - // to specify a year by itself or a year and month where the day isn't - // significant. - int32 day = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py deleted file mode 100644 index 11130adab1c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/date.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/date.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x16google/type/date.proto\x12\x0bgoogle.type"0\n\x04\x44\x61te\x12\x0c\n\x04year\x18\x01 \x01(\x05\x12\r\n\x05month\x18\x02 \x01(\x05\x12\x0b\n\x03\x64\x61y\x18\x03 \x01(\x05\x42Z\n\x0f\x63om.google.typeB\tDateProtoP\x01Z4google.golang.org/genproto/googleapis/type/date;date\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.date_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\tDateProtoP\001Z4google.golang.org/genproto/googleapis/type/date;date\242\002\003GTP" - _globals["_DATE"]._serialized_start = 39 - _globals["_DATE"]._serialized_end = 87 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi deleted file mode 100644 index fcaf2f9984a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/date_pb2.pyi +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class Date(_message.Message): - __slots__ = ("year", "month", "day") - YEAR_FIELD_NUMBER: _ClassVar[int] - MONTH_FIELD_NUMBER: _ClassVar[int] - DAY_FIELD_NUMBER: _ClassVar[int] - year: int - month: int - day: int - def __init__( - self, - year: _Optional[int] = ..., - month: _Optional[int] = ..., - day: _Optional[int] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto deleted file mode 100644 index b81e4f472f9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime.proto +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -import "google/protobuf/duration.proto"; - -option go_package = "google.golang.org/genproto/googleapis/type/datetime;datetime"; -option java_multiple_files = true; -option java_outer_classname = "DateTimeProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents civil time (or occasionally physical time). -// -// This type can represent a civil time in one of a few possible ways: -// -// * When utc_offset is set and time_zone is unset: a civil time on a calendar -// day with a particular offset from UTC. -// * When time_zone is set and utc_offset is unset: a civil time on a calendar -// day in a particular time zone. -// * When neither time_zone nor utc_offset is set: a civil time on a calendar -// day in local time. -// -// The date is relative to the Proleptic Gregorian Calendar. -// -// If year, month, or day are 0, the DateTime is considered not to have a -// specific year, month, or day respectively. -// -// This type may also be used to represent a physical time if all the date and -// time fields are set and either case of the `time_offset` oneof is set. -// Consider using `Timestamp` message for physical time instead. If your use -// case also would like to store the user's timezone, that can be done in -// another field. -// -// This type is more flexible than some applications may want. Make sure to -// document and validate your application's limitations. -message DateTime { - // Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a - // datetime without a year. - int32 year = 1; - - // Optional. Month of year. Must be from 1 to 12, or 0 if specifying a - // datetime without a month. - int32 month = 2; - - // Optional. Day of month. Must be from 1 to 31 and valid for the year and - // month, or 0 if specifying a datetime without a day. - int32 day = 3; - - // Optional. Hours of day in 24 hour format. Should be from 0 to 23, defaults - // to 0 (midnight). An API may choose to allow the value "24:00:00" for - // scenarios like business closing time. - int32 hours = 4; - - // Optional. Minutes of hour of day. Must be from 0 to 59, defaults to 0. - int32 minutes = 5; - - // Optional. Seconds of minutes of the time. Must normally be from 0 to 59, - // defaults to 0. An API may allow the value 60 if it allows leap-seconds. - int32 seconds = 6; - - // Optional. Fractions of seconds in nanoseconds. Must be from 0 to - // 999,999,999, defaults to 0. - int32 nanos = 7; - - // Optional. Specifies either the UTC offset or the time zone of the DateTime. - // Choose carefully between them, considering that time zone data may change - // in the future (for example, a country modifies their DST start/end dates, - // and future DateTimes in the affected range had already been stored). - // If omitted, the DateTime is considered to be in local time. - oneof time_offset { - // UTC offset. Must be whole seconds, between -18 hours and +18 hours. - // For example, a UTC offset of -4:00 would be represented as - // { seconds: -14400 }. - google.protobuf.Duration utc_offset = 8; - - // Time zone. - TimeZone time_zone = 9; - } -} - -// Represents a time zone from the -// [IANA Time Zone Database](https://www.iana.org/time-zones). -message TimeZone { - // IANA Time Zone Database time zone. For example "America/New_York". - string id = 1; - - // Optional. IANA Time Zone Database version number. For example "2019a". - string version = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py deleted file mode 100644 index 84bf4dabfd4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/datetime_pb2.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/datetime.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/datetime.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1agoogle/type/datetime.proto\x12\x0bgoogle.type\x1a\x1egoogle/protobuf/duration.proto"\xe0\x01\n\x08\x44\x61teTime\x12\x0c\n\x04year\x18\x01 \x01(\x05\x12\r\n\x05month\x18\x02 \x01(\x05\x12\x0b\n\x03\x64\x61y\x18\x03 \x01(\x05\x12\r\n\x05hours\x18\x04 \x01(\x05\x12\x0f\n\x07minutes\x18\x05 \x01(\x05\x12\x0f\n\x07seconds\x18\x06 \x01(\x05\x12\r\n\x05nanos\x18\x07 \x01(\x05\x12/\n\nutc_offset\x18\x08 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x12*\n\ttime_zone\x18\t \x01(\x0b\x32\x15.google.type.TimeZoneH\x00\x42\r\n\x0btime_offset"\'\n\x08TimeZone\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\tBf\n\x0f\x63om.google.typeB\rDateTimeProtoP\x01Z None: ... - -class TimeZone(_message.Message): - __slots__ = ("id", "version") - ID_FIELD_NUMBER: _ClassVar[int] - VERSION_FIELD_NUMBER: _ClassVar[int] - id: str - version: str - def __init__( - self, id: _Optional[str] = ..., version: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto deleted file mode 100644 index 669d89401c1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek.proto +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/dayofweek;dayofweek"; -option java_multiple_files = true; -option java_outer_classname = "DayOfWeekProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a day of the week. -enum DayOfWeek { - // The day of the week is unspecified. - DAY_OF_WEEK_UNSPECIFIED = 0; - - // Monday - MONDAY = 1; - - // Tuesday - TUESDAY = 2; - - // Wednesday - WEDNESDAY = 3; - - // Thursday - THURSDAY = 4; - - // Friday - FRIDAY = 5; - - // Saturday - SATURDAY = 6; - - // Sunday - SUNDAY = 7; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py deleted file mode 100644 index 18ceb9601c3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/dayofweek.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/dayofweek.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n\x1bgoogle/type/dayofweek.proto\x12\x0bgoogle.type*\x84\x01\n\tDayOfWeek\x12\x1b\n\x17\x44\x41Y_OF_WEEK_UNSPECIFIED\x10\x00\x12\n\n\x06MONDAY\x10\x01\x12\x0b\n\x07TUESDAY\x10\x02\x12\r\n\tWEDNESDAY\x10\x03\x12\x0c\n\x08THURSDAY\x10\x04\x12\n\n\x06\x46RIDAY\x10\x05\x12\x0c\n\x08SATURDAY\x10\x06\x12\n\n\x06SUNDAY\x10\x07\x42i\n\x0f\x63om.google.typeB\x0e\x44\x61yOfWeekProtoP\x01Z>google.golang.org/genproto/googleapis/type/dayofweek;dayofweek\xa2\x02\x03GTPb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.type.dayofweek_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\016DayOfWeekProtoP\001Z>google.golang.org/genproto/googleapis/type/dayofweek;dayofweek\242\002\003GTP" - _globals["_DAYOFWEEK"]._serialized_start = 45 - _globals["_DAYOFWEEK"]._serialized_end = 177 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi deleted file mode 100644 index 34c6770654e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/dayofweek_pb2.pyi +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class DayOfWeek(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - DAY_OF_WEEK_UNSPECIFIED: _ClassVar[DayOfWeek] - MONDAY: _ClassVar[DayOfWeek] - TUESDAY: _ClassVar[DayOfWeek] - WEDNESDAY: _ClassVar[DayOfWeek] - THURSDAY: _ClassVar[DayOfWeek] - FRIDAY: _ClassVar[DayOfWeek] - SATURDAY: _ClassVar[DayOfWeek] - SUNDAY: _ClassVar[DayOfWeek] - -DAY_OF_WEEK_UNSPECIFIED: DayOfWeek -MONDAY: DayOfWeek -TUESDAY: DayOfWeek -WEDNESDAY: DayOfWeek -THURSDAY: DayOfWeek -FRIDAY: DayOfWeek -SATURDAY: DayOfWeek -SUNDAY: DayOfWeek diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto deleted file mode 100644 index 353e14b477a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal.proto +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/decimal;decimal"; -option java_multiple_files = true; -option java_outer_classname = "DecimalProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// A representation of a decimal value, such as 2.5. Clients may convert values -// into language-native decimal formats, such as Java's -// [BigDecimal](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html) -// or Python's -// [decimal.Decimal](https://docs.python.org/3/library/decimal.html). -message Decimal { - // The decimal value, as a string. - // - // The string representation consists of an optional sign, `+` (`U+002B`) - // or `-` (`U+002D`), followed by a sequence of zero or more decimal digits - // ("the integer"), optionally followed by a fraction, optionally followed - // by an exponent. An empty string **should** be interpreted as `0`. - // - // The fraction consists of a decimal point followed by zero or more decimal - // digits. The string must contain at least one digit in either the integer - // or the fraction. The number formed by the sign, the integer and the - // fraction is referred to as the significand. - // - // The exponent consists of the character `e` (`U+0065`) or `E` (`U+0045`) - // followed by one or more decimal digits. - // - // Services **should** normalize decimal values before storing them by: - // - // - Removing an explicitly-provided `+` sign (`+2.5` -> `2.5`). - // - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). - // - Coercing the exponent character to upper-case, with explicit sign - // (`2.5e8` -> `2.5E+8`). - // - Removing an explicitly-provided zero exponent (`2.5E0` -> `2.5`). - // - // Services **may** perform additional normalization based on its own needs - // and the internal decimal implementation selected, such as shifting the - // decimal point and exponent value together (example: `2.5E-1` <-> `0.25`). - // Additionally, services **may** preserve trailing zeroes in the fraction - // to indicate increased precision, but are not required to do so. - // - // Note that only the `.` character is supported to divide the integer - // and the fraction; `,` **should not** be supported regardless of locale. - // Additionally, thousand separators **should not** be supported. If a - // service does support them, values **must** be normalized. - // - // The ENBF grammar is: - // - // DecimalString = - // '' | [Sign] Significand [Exponent]; - // - // Sign = '+' | '-'; - // - // Significand = - // Digits ['.'] [Digits] | [Digits] '.' Digits; - // - // Exponent = ('e' | 'E') [Sign] Digits; - // - // Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; - // - // Services **should** clearly document the range of supported values, the - // maximum supported precision (total number of digits), and, if applicable, - // the scale (number of digits after the decimal point), as well as how it - // behaves when receiving out-of-bounds values. - // - // Services **may** choose to accept values passed as input even when the - // value has a higher precision or scale than the service supports, and - // **should** round the value to fit the supported scale. Alternatively, the - // service **may** error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) - // if precision would be lost. - // - // Services **should** error with `400 Bad Request` (`INVALID_ARGUMENT` in - // gRPC) if the service receives a value outside of the supported range. - string value = 1; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py deleted file mode 100644 index 79a62771fa9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/decimal.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/decimal.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x19google/type/decimal.proto\x12\x0bgoogle.type"\x18\n\x07\x44\x65\x63imal\x12\r\n\x05value\x18\x01 \x01(\tBc\n\x0f\x63om.google.typeB\x0c\x44\x65\x63imalProtoP\x01Z:google.golang.org/genproto/googleapis/type/decimal;decimal\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.decimal_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\014DecimalProtoP\001Z:google.golang.org/genproto/googleapis/type/decimal;decimal\242\002\003GTP" - _globals["_DECIMAL"]._serialized_start = 42 - _globals["_DECIMAL"]._serialized_end = 66 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi deleted file mode 100644 index 95f43e305a7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/decimal_pb2.pyi +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class Decimal(_message.Message): - __slots__ = ("value",) - VALUE_FIELD_NUMBER: _ClassVar[int] - value: str - def __init__(self, value: _Optional[str] = ...) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto deleted file mode 100644 index 2fca5cda315..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr.proto +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/expr;expr"; -option java_multiple_files = true; -option java_outer_classname = "ExprProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a textual expression in the Common Expression Language (CEL) -// syntax. CEL is a C-like expression language. The syntax and semantics of CEL -// are documented at https://github.com/google/cel-spec. -// -// Example (Comparison): -// -// title: "Summary size limit" -// description: "Determines if a summary is less than 100 chars" -// expression: "document.summary.size() < 100" -// -// Example (Equality): -// -// title: "Requestor is owner" -// description: "Determines if requestor is the document owner" -// expression: "document.owner == request.auth.claims.email" -// -// Example (Logic): -// -// title: "Public documents" -// description: "Determine whether the document should be publicly visible" -// expression: "document.type != 'private' && document.type != 'internal'" -// -// Example (Data Manipulation): -// -// title: "Notification string" -// description: "Create a notification string with a timestamp." -// expression: "'New message received at ' + string(document.create_time)" -// -// The exact variables and functions that may be referenced within an expression -// are determined by the service that evaluates it. See the service -// documentation for additional information. -message Expr { - // Textual representation of an expression in Common Expression Language - // syntax. - string expression = 1; - - // Optional. Title for the expression, i.e. a short string describing - // its purpose. This can be used e.g. in UIs which allow to enter the - // expression. - string title = 2; - - // Optional. Description of the expression. This is a longer text which - // describes the expression, e.g. when hovered over it in a UI. - string description = 3; - - // Optional. String indicating the location of the expression for error - // reporting, e.g. a file name and a position in the file. - string location = 4; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py deleted file mode 100644 index 01af5242d6e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/expr.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/expr.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x16google/type/expr.proto\x12\x0bgoogle.type"P\n\x04\x45xpr\x12\x12\n\nexpression\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08location\x18\x04 \x01(\tBZ\n\x0f\x63om.google.typeB\tExprProtoP\x01Z4google.golang.org/genproto/googleapis/type/expr;expr\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.expr_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\tExprProtoP\001Z4google.golang.org/genproto/googleapis/type/expr;expr\242\002\003GTP" - _globals["_EXPR"]._serialized_start = 39 - _globals["_EXPR"]._serialized_end = 119 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi deleted file mode 100644 index a1a55662b92..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/expr_pb2.pyi +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class Expr(_message.Message): - __slots__ = ("expression", "title", "description", "location") - EXPRESSION_FIELD_NUMBER: _ClassVar[int] - TITLE_FIELD_NUMBER: _ClassVar[int] - DESCRIPTION_FIELD_NUMBER: _ClassVar[int] - LOCATION_FIELD_NUMBER: _ClassVar[int] - expression: str - title: str - description: str - location: str - def __init__( - self, - expression: _Optional[str] = ..., - title: _Optional[str] = ..., - description: _Optional[str] = ..., - location: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto deleted file mode 100644 index 72f90b3113e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction.proto +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/fraction;fraction"; -option java_multiple_files = true; -option java_outer_classname = "FractionProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a fraction in terms of a numerator divided by a denominator. -message Fraction { - // The numerator in the fraction, e.g. 2 in 2/3. - int64 numerator = 1; - - // The value by which the numerator is divided, e.g. 3 in 2/3. Must be - // positive. - int64 denominator = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py deleted file mode 100644 index a89d2c1d588..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/fraction_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/fraction.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/fraction.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1agoogle/type/fraction.proto\x12\x0bgoogle.type"2\n\x08\x46raction\x12\x11\n\tnumerator\x18\x01 \x01(\x03\x12\x13\n\x0b\x64\x65nominator\x18\x02 \x01(\x03\x42\x66\n\x0f\x63om.google.typeB\rFractionProtoP\x01Z None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto deleted file mode 100644 index 8e001282caa..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval.proto +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -import "google/protobuf/timestamp.proto"; - -option go_package = "google.golang.org/genproto/googleapis/type/interval;interval"; -option java_multiple_files = true; -option java_outer_classname = "IntervalProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a time interval, encoded as a Timestamp start (inclusive) and a -// Timestamp end (exclusive). -// -// The start must be less than or equal to the end. -// When the start equals the end, the interval is empty (matches no time). -// When both start and end are unspecified, the interval matches any time. -message Interval { - // Optional. Inclusive start of the interval. - // - // If specified, a Timestamp matching this interval will have to be the same - // or after the start. - google.protobuf.Timestamp start_time = 1; - - // Optional. Exclusive end of the interval. - // - // If specified, a Timestamp matching this interval will have to be before the - // end. - google.protobuf.Timestamp end_time = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py deleted file mode 100644 index a5da33d592a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/interval_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/interval.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/interval.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1agoogle/type/interval.proto\x12\x0bgoogle.type\x1a\x1fgoogle/protobuf/timestamp.proto"h\n\x08Interval\x12.\n\nstart_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampBf\n\x0f\x63om.google.typeB\rIntervalProtoP\x01Z None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto deleted file mode 100644 index 2866058ccf1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng.proto +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/latlng;latlng"; -option java_multiple_files = true; -option java_outer_classname = "LatLngProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// An object that represents a latitude/longitude pair. This is expressed as a -// pair of doubles to represent degrees latitude and degrees longitude. Unless -// specified otherwise, this object must conform to the -// -// WGS84 standard. Values must be within normalized ranges. -message LatLng { - // The latitude in degrees. It must be in the range [-90.0, +90.0]. - double latitude = 1; - - // The longitude in degrees. It must be in the range [-180.0, +180.0]. - double longitude = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py deleted file mode 100644 index 0f3911bde54..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/latlng.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/latlng.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x18google/type/latlng.proto\x12\x0bgoogle.type"-\n\x06LatLng\x12\x10\n\x08latitude\x18\x01 \x01(\x01\x12\x11\n\tlongitude\x18\x02 \x01(\x01\x42`\n\x0f\x63om.google.typeB\x0bLatLngProtoP\x01Z8google.golang.org/genproto/googleapis/type/latlng;latlng\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.latlng_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\013LatLngProtoP\001Z8google.golang.org/genproto/googleapis/type/latlng;latlng\242\002\003GTP" - _globals["_LATLNG"]._serialized_start = 41 - _globals["_LATLNG"]._serialized_end = 86 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi deleted file mode 100644 index 033dd881924..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/latlng_pb2.pyi +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class LatLng(_message.Message): - __slots__ = ("latitude", "longitude") - LATITUDE_FIELD_NUMBER: _ClassVar[int] - LONGITUDE_FIELD_NUMBER: _ClassVar[int] - latitude: float - longitude: float - def __init__( - self, latitude: _Optional[float] = ..., longitude: _Optional[float] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto deleted file mode 100644 index d3f2c2c1833..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text.proto +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/localized_text;localized_text"; -option java_multiple_files = true; -option java_outer_classname = "LocalizedTextProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Localized variant of a text in a particular language. -message LocalizedText { - // Localized string in the language corresponding to - // [language_code][google.type.LocalizedText.language_code] below. - string text = 1; - - // The text's BCP-47 language code, such as "en-US" or "sr-Latn". - // - // For more information, see - // http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. - string language_code = 2; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py deleted file mode 100644 index c6a9ac88f42..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/localized_text.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/localized_text.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n google/type/localized_text.proto\x12\x0bgoogle.type"4\n\rLocalizedText\x12\x0c\n\x04text\x18\x01 \x01(\t\x12\x15\n\rlanguage_code\x18\x02 \x01(\tBw\n\x0f\x63om.google.typeB\x12LocalizedTextProtoP\x01ZHgoogle.golang.org/genproto/googleapis/type/localized_text;localized_text\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.type.localized_text_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\022LocalizedTextProtoP\001ZHgoogle.golang.org/genproto/googleapis/type/localized_text;localized_text\242\002\003GTP" - _globals["_LOCALIZEDTEXT"]._serialized_start = 49 - _globals["_LOCALIZEDTEXT"]._serialized_end = 101 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi deleted file mode 100644 index f67aa6deb76..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/localized_text_pb2.pyi +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class LocalizedText(_message.Message): - __slots__ = ("text", "language_code") - TEXT_FIELD_NUMBER: _ClassVar[int] - LANGUAGE_CODE_FIELD_NUMBER: _ClassVar[int] - text: str - language_code: str - def __init__( - self, text: _Optional[str] = ..., language_code: _Optional[str] = ... - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto deleted file mode 100644 index ed0d790a334..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money.proto +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/money;money"; -option java_multiple_files = true; -option java_outer_classname = "MoneyProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents an amount of money with its currency type. -message Money { - // The three-letter currency code defined in ISO 4217. - string currency_code = 1; - - // The whole units of the amount. - // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. - int64 units = 2; - - // Number of nano (10^-9) units of the amount. - // The value must be between -999,999,999 and +999,999,999 inclusive. - // If `units` is positive, `nanos` must be positive or zero. - // If `units` is zero, `nanos` can be positive, zero, or negative. - // If `units` is negative, `nanos` must be negative or zero. - // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. - int32 nanos = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py deleted file mode 100644 index 332526e578e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/money.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/money.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x17google/type/money.proto\x12\x0bgoogle.type"<\n\x05Money\x12\x15\n\rcurrency_code\x18\x01 \x01(\t\x12\r\n\x05units\x18\x02 \x01(\x03\x12\r\n\x05nanos\x18\x03 \x01(\x05\x42]\n\x0f\x63om.google.typeB\nMoneyProtoP\x01Z6google.golang.org/genproto/googleapis/type/money;money\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.money_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\nMoneyProtoP\001Z6google.golang.org/genproto/googleapis/type/money;money\242\002\003GTP" - _globals["_MONEY"]._serialized_start = 40 - _globals["_MONEY"]._serialized_end = 100 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi deleted file mode 100644 index dd1c02b3212..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/money_pb2.pyi +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class Money(_message.Message): - __slots__ = ("currency_code", "units", "nanos") - CURRENCY_CODE_FIELD_NUMBER: _ClassVar[int] - UNITS_FIELD_NUMBER: _ClassVar[int] - NANOS_FIELD_NUMBER: _ClassVar[int] - currency_code: str - units: int - nanos: int - def __init__( - self, - currency_code: _Optional[str] = ..., - units: _Optional[int] = ..., - nanos: _Optional[int] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto deleted file mode 100644 index f8a66305f9b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month.proto +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/month;month"; -option java_multiple_files = true; -option java_outer_classname = "MonthProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a month in the Gregorian calendar. -enum Month { - // The unspecified month. - MONTH_UNSPECIFIED = 0; - - // The month of January. - JANUARY = 1; - - // The month of February. - FEBRUARY = 2; - - // The month of March. - MARCH = 3; - - // The month of April. - APRIL = 4; - - // The month of May. - MAY = 5; - - // The month of June. - JUNE = 6; - - // The month of July. - JULY = 7; - - // The month of August. - AUGUST = 8; - - // The month of September. - SEPTEMBER = 9; - - // The month of October. - OCTOBER = 10; - - // The month of November. - NOVEMBER = 11; - - // The month of December. - DECEMBER = 12; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py deleted file mode 100644 index 05d2498eedd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/month.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/month.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b"\n\x17google/type/month.proto\x12\x0bgoogle.type*\xb0\x01\n\x05Month\x12\x15\n\x11MONTH_UNSPECIFIED\x10\x00\x12\x0b\n\x07JANUARY\x10\x01\x12\x0c\n\x08\x46\x45\x42RUARY\x10\x02\x12\t\n\x05MARCH\x10\x03\x12\t\n\x05\x41PRIL\x10\x04\x12\x07\n\x03MAY\x10\x05\x12\x08\n\x04JUNE\x10\x06\x12\x08\n\x04JULY\x10\x07\x12\n\n\x06\x41UGUST\x10\x08\x12\r\n\tSEPTEMBER\x10\t\x12\x0b\n\x07OCTOBER\x10\n\x12\x0c\n\x08NOVEMBER\x10\x0b\x12\x0c\n\x08\x44\x45\x43\x45MBER\x10\x0c\x42]\n\x0f\x63om.google.typeB\nMonthProtoP\x01Z6google.golang.org/genproto/googleapis/type/month;month\xa2\x02\x03GTPb\x06proto3" -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "opentelemetry.agent._vendor.google.type.month_pb2", _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\nMonthProtoP\001Z6google.golang.org/genproto/googleapis/type/month;month\242\002\003GTP" - _globals["_MONTH"]._serialized_start = 41 - _globals["_MONTH"]._serialized_end = 217 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi deleted file mode 100644 index a5634ce2250..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/month_pb2.pyi +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar - -from google.protobuf import descriptor as _descriptor -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper - -DESCRIPTOR: _descriptor.FileDescriptor - -class Month(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): - __slots__ = () - MONTH_UNSPECIFIED: _ClassVar[Month] - JANUARY: _ClassVar[Month] - FEBRUARY: _ClassVar[Month] - MARCH: _ClassVar[Month] - APRIL: _ClassVar[Month] - MAY: _ClassVar[Month] - JUNE: _ClassVar[Month] - JULY: _ClassVar[Month] - AUGUST: _ClassVar[Month] - SEPTEMBER: _ClassVar[Month] - OCTOBER: _ClassVar[Month] - NOVEMBER: _ClassVar[Month] - DECEMBER: _ClassVar[Month] - -MONTH_UNSPECIFIED: Month -JANUARY: Month -FEBRUARY: Month -MARCH: Month -APRIL: Month -MAY: Month -JUNE: Month -JULY: Month -AUGUST: Month -SEPTEMBER: Month -OCTOBER: Month -NOVEMBER: Month -DECEMBER: Month diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto deleted file mode 100644 index 7c55be07688..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number.proto +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/phone_number;phone_number"; -option java_multiple_files = true; -option java_outer_classname = "PhoneNumberProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// An object representing a phone number, suitable as an API wire format. -// -// This representation: -// -// - should not be used for locale-specific formatting of a phone number, such -// as "+1 (650) 253-0000 ext. 123" -// -// - is not designed for efficient storage -// - may not be suitable for dialing - specialized libraries (see references) -// should be used to parse the number for that purpose -// -// To do something meaningful with this number, such as format it for various -// use-cases, convert it to an `i18n.phonenumbers.PhoneNumber` object first. -// -// For instance, in Java this would be: -// -// com.google.type.PhoneNumber wireProto = -// com.google.type.PhoneNumber.newBuilder().build(); -// com.google.i18n.phonenumbers.Phonenumber.PhoneNumber phoneNumber = -// PhoneNumberUtil.getInstance().parse(wireProto.getE164Number(), "ZZ"); -// if (!wireProto.getExtension().isEmpty()) { -// phoneNumber.setExtension(wireProto.getExtension()); -// } -// -// Reference(s): -// - https://github.com/google/libphonenumber -message PhoneNumber { - // An object representing a short code, which is a phone number that is - // typically much shorter than regular phone numbers and can be used to - // address messages in MMS and SMS systems, as well as for abbreviated dialing - // (For example "Text 611 to see how many minutes you have remaining on your - // plan."). - // - // Short codes are restricted to a region and are not internationally - // dialable, which means the same short code can exist in different regions, - // with different usage and pricing, even if those regions share the same - // country calling code (For example: US and CA). - message ShortCode { - // Required. The BCP-47 region code of the location where calls to this - // short code can be made, such as "US" and "BB". - // - // Reference(s): - // - http://www.unicode.org/reports/tr35/#unicode_region_subtag - string region_code = 1; - - // Required. The short code digits, without a leading plus ('+') or country - // calling code. For example "611". - string number = 2; - } - - // Required. Either a regular number, or a short code. New fields may be - // added to the oneof below in the future, so clients should ignore phone - // numbers for which none of the fields they coded against are set. - oneof kind { - // The phone number, represented as a leading plus sign ('+'), followed by a - // phone number that uses a relaxed ITU E.164 format consisting of the - // country calling code (1 to 3 digits) and the subscriber number, with no - // additional spaces or formatting. For example: - // - // - correct: "+15552220123" - // - // - incorrect: "+1 (555) 222-01234 x123" - // - // The ITU E.164 format limits the latter to 12 digits, but in practice not - // all countries respect that, so we relax that restriction here. - // National-only numbers are not allowed. - // - // References: - // - // - https://www.itu.int/rec/T-REC-E.164-201011-I - // - // - https://en.wikipedia.org/wiki/E.164. - // - // - https://en.wikipedia.org/wiki/List_of_country_calling_codes - string e164_number = 1; - - // A short code. - // - // Reference(s): - // - https://wikipedia.org/wiki/Short_code - ShortCode short_code = 2; - } - - // The phone number's extension. The extension is not standardized in ITU - // recommendations, except for being defined as a series of numbers with a - // maximum length of 40 digits. Other than digits, some other dialing - // characters such as ',' (indicating a wait) or '#' may be stored here. - // - // Note that no regions currently use extensions with short codes, so this - // field is normally only set in conjunction with an E.164 number. It is held - // separately from the E.164 number to allow for short code extensions in the - // future. - string extension = 3; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py deleted file mode 100644 index e87b2a13980..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/phone_number.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/phone_number.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1egoogle/type/phone_number.proto\x12\x0bgoogle.type"\xab\x01\n\x0bPhoneNumber\x12\x15\n\x0b\x65\x31\x36\x34_number\x18\x01 \x01(\tH\x00\x12\x38\n\nshort_code\x18\x02 \x01(\x0b\x32".google.type.PhoneNumber.ShortCodeH\x00\x12\x11\n\textension\x18\x03 \x01(\t\x1a\x30\n\tShortCode\x12\x13\n\x0bregion_code\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\tB\x06\n\x04kindBq\n\x0f\x63om.google.typeB\x10PhoneNumberProtoP\x01ZDgoogle.golang.org/genproto/googleapis/type/phone_number;phone_number\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.type.phone_number_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\020PhoneNumberProtoP\001ZDgoogle.golang.org/genproto/googleapis/type/phone_number;phone_number\242\002\003GTP" - _globals["_PHONENUMBER"]._serialized_start = 48 - _globals["_PHONENUMBER"]._serialized_end = 219 - _globals["_PHONENUMBER_SHORTCODE"]._serialized_start = 163 - _globals["_PHONENUMBER_SHORTCODE"]._serialized_end = 211 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi deleted file mode 100644 index aae75ceea08..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/phone_number_pb2.pyi +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Mapping as _Mapping -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional -from typing import Union as _Union - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class PhoneNumber(_message.Message): - __slots__ = ("e164_number", "short_code", "extension") - class ShortCode(_message.Message): - __slots__ = ("region_code", "number") - REGION_CODE_FIELD_NUMBER: _ClassVar[int] - NUMBER_FIELD_NUMBER: _ClassVar[int] - region_code: str - number: str - def __init__( - self, region_code: _Optional[str] = ..., number: _Optional[str] = ... - ) -> None: ... - - E164_NUMBER_FIELD_NUMBER: _ClassVar[int] - SHORT_CODE_FIELD_NUMBER: _ClassVar[int] - EXTENSION_FIELD_NUMBER: _ClassVar[int] - e164_number: str - short_code: PhoneNumber.ShortCode - extension: str - def __init__( - self, - e164_number: _Optional[str] = ..., - short_code: _Optional[_Union[PhoneNumber.ShortCode, _Mapping]] = ..., - extension: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto deleted file mode 100644 index 57059625235..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address.proto +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/postaladdress;postaladdress"; -option java_multiple_files = true; -option java_outer_classname = "PostalAddressProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a postal address, such as for postal delivery or payments -// addresses. With a postal address, a postal service can deliver items to a -// premise, P.O. box, or similar. A postal address is not intended to model -// geographical locations like roads, towns, or mountains. -// -// In typical usage, an address would be created by user input or from importing -// existing data, depending on the type of process. -// -// Advice on address input or editing: -// -// - Use an internationalization-ready address widget such as -// https://github.com/google/libaddressinput. -// - Users should not be presented with UI elements for input or editing of -// fields outside countries where that field is used. -// -// For more guidance on how to use this schema, see: -// https://support.google.com/business/answer/6397478. -message PostalAddress { - // The schema revision of the `PostalAddress`. This must be set to 0, which is - // the latest revision. - // - // All new revisions **must** be backward compatible with old revisions. - int32 revision = 1; - - // Required. CLDR region code of the country/region of the address. This - // is never inferred and it is up to the user to ensure the value is - // correct. See https://cldr.unicode.org/ and - // https://www.unicode.org/cldr/charts/30/supplemental/territory_information.html - // for details. Example: "CH" for Switzerland. - string region_code = 2; - - // Optional. BCP-47 language code of the contents of this address (if - // known). This is often the UI language of the input form or is expected - // to match one of the languages used in the address' country/region, or their - // transliterated equivalents. - // This can affect formatting in certain countries, but is not critical - // to the correctness of the data and will never affect any validation or - // other non-formatting related operations. - // - // If this value is not known, it should be omitted (rather than specifying a - // possibly incorrect default). - // - // Examples: "zh-Hant", "ja", "ja-Latn", "en". - string language_code = 3; - - // Optional. Postal code of the address. Not all countries use or require - // postal codes to be present, but where they are used, they may trigger - // additional validation with other parts of the address (for example, - // state or zip code validation in the United States). - string postal_code = 4; - - // Optional. Additional, country-specific, sorting code. This is not used - // in most regions. Where it is used, the value is either a string like - // "CEDEX", optionally followed by a number (for example, "CEDEX 7"), or just - // a number alone, representing the "sector code" (Jamaica), "delivery area - // indicator" (Malawi) or "post office indicator" (Côte d'Ivoire). - string sorting_code = 5; - - // Optional. Highest administrative subdivision which is used for postal - // addresses of a country or region. - // For example, this can be a state, a province, an oblast, or a prefecture. - // For Spain, this is the province and not the autonomous - // community (for example, "Barcelona" and not "Catalonia"). - // Many countries don't use an administrative area in postal addresses. For - // example, in Switzerland, this should be left unpopulated. - string administrative_area = 6; - - // Optional. Generally refers to the city or town portion of the address. - // Examples: US city, IT comune, UK post town. - // In regions of the world where localities are not well defined or do not fit - // into this structure well, leave `locality` empty and use `address_lines`. - string locality = 7; - - // Optional. Sublocality of the address. - // For example, this can be a neighborhood, borough, or district. - string sublocality = 8; - - // Unstructured address lines describing the lower levels of an address. - // - // Because values in `address_lines` do not have type information and may - // sometimes contain multiple values in a single field (for example, - // "Austin, TX"), it is important that the line order is clear. The order of - // address lines should be "envelope order" for the country or region of the - // address. In places where this can vary (for example, Japan), - // `address_language` is used to make it explicit (for example, "ja" for - // large-to-small ordering and "ja-Latn" or "en" for small-to-large). In this - // way, the most specific line of an address can be selected based on the - // language. - // - // The minimum permitted structural representation of an address consists - // of a `region_code` with all remaining information placed in the - // `address_lines`. It would be possible to format such an address very - // approximately without geocoding, but no semantic reasoning could be - // made about any of the address components until it was at least - // partially resolved. - // - // Creating an address only containing a `region_code` and `address_lines` and - // then geocoding is the recommended way to handle completely unstructured - // addresses (as opposed to guessing which parts of the address should be - // localities or administrative areas). - repeated string address_lines = 9; - - // Optional. The recipient at the address. - // This field may, under certain circumstances, contain multiline information. - // For example, it might contain "care of" information. - repeated string recipients = 10; - - // Optional. The name of the organization at the address. - string organization = 11; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py deleted file mode 100644 index ffd6b8c96bc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/postal_address.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/postal_address.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n google/type/postal_address.proto\x12\x0bgoogle.type"\xfd\x01\n\rPostalAddress\x12\x10\n\x08revision\x18\x01 \x01(\x05\x12\x13\n\x0bregion_code\x18\x02 \x01(\t\x12\x15\n\rlanguage_code\x18\x03 \x01(\t\x12\x13\n\x0bpostal_code\x18\x04 \x01(\t\x12\x14\n\x0csorting_code\x18\x05 \x01(\t\x12\x1b\n\x13\x61\x64ministrative_area\x18\x06 \x01(\t\x12\x10\n\x08locality\x18\x07 \x01(\t\x12\x13\n\x0bsublocality\x18\x08 \x01(\t\x12\x15\n\raddress_lines\x18\t \x03(\t\x12\x12\n\nrecipients\x18\n \x03(\t\x12\x14\n\x0corganization\x18\x0b \x01(\tBu\n\x0f\x63om.google.typeB\x12PostalAddressProtoP\x01ZFgoogle.golang.org/genproto/googleapis/type/postaladdress;postaladdress\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.type.postal_address_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\022PostalAddressProtoP\001ZFgoogle.golang.org/genproto/googleapis/type/postaladdress;postaladdress\242\002\003GTP" - _globals["_POSTALADDRESS"]._serialized_start = 50 - _globals["_POSTALADDRESS"]._serialized_end = 303 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi deleted file mode 100644 index 946cbf7c13c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/postal_address_pb2.pyi +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import Iterable as _Iterable -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers - -DESCRIPTOR: _descriptor.FileDescriptor - -class PostalAddress(_message.Message): - __slots__ = ( - "revision", - "region_code", - "language_code", - "postal_code", - "sorting_code", - "administrative_area", - "locality", - "sublocality", - "address_lines", - "recipients", - "organization", - ) - REVISION_FIELD_NUMBER: _ClassVar[int] - REGION_CODE_FIELD_NUMBER: _ClassVar[int] - LANGUAGE_CODE_FIELD_NUMBER: _ClassVar[int] - POSTAL_CODE_FIELD_NUMBER: _ClassVar[int] - SORTING_CODE_FIELD_NUMBER: _ClassVar[int] - ADMINISTRATIVE_AREA_FIELD_NUMBER: _ClassVar[int] - LOCALITY_FIELD_NUMBER: _ClassVar[int] - SUBLOCALITY_FIELD_NUMBER: _ClassVar[int] - ADDRESS_LINES_FIELD_NUMBER: _ClassVar[int] - RECIPIENTS_FIELD_NUMBER: _ClassVar[int] - ORGANIZATION_FIELD_NUMBER: _ClassVar[int] - revision: int - region_code: str - language_code: str - postal_code: str - sorting_code: str - administrative_area: str - locality: str - sublocality: str - address_lines: _containers.RepeatedScalarFieldContainer[str] - recipients: _containers.RepeatedScalarFieldContainer[str] - organization: str - def __init__( - self, - revision: _Optional[int] = ..., - region_code: _Optional[str] = ..., - language_code: _Optional[str] = ..., - postal_code: _Optional[str] = ..., - sorting_code: _Optional[str] = ..., - administrative_area: _Optional[str] = ..., - locality: _Optional[str] = ..., - sublocality: _Optional[str] = ..., - address_lines: _Optional[_Iterable[str]] = ..., - recipients: _Optional[_Iterable[str]] = ..., - organization: _Optional[str] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto deleted file mode 100644 index d24629821ff..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion.proto +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/quaternion;quaternion"; -option java_multiple_files = true; -option java_outer_classname = "QuaternionProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// A quaternion, represented by four 64-bit floating point values. -// -// A quaternion is defined as the quotient of two directed lines in a -// three-dimensional space or equivalently as the quotient of two Euclidean -// vectors (https://en.wikipedia.org/wiki/Quaternion). -// -// Quaternions are often used in calculations involving three-dimensional -// rotations (https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation), -// as they provide greater mathematical robustness by avoiding the gimbal lock -// problems that can be encountered when using Euler angles -// (https://en.wikipedia.org/wiki/Gimbal_lock). -// -// Quaternions are generally represented in this form: -// -// w + xi + yj + zk -// -// where x, y, z, and w are real numbers, and i, j, and k are three imaginary -// numbers. -// -// The naming choice `(x, y, z, w)` comes from the desire to avoid confusion for -// those interested in the geometric properties of the quaternion in the 3D -// Cartesian space. Other texts often use alternative names or subscripts, such -// as `(a, b, c, d)`, `(1, i, j, k)`, or `(0, 1, 2, 3)`, which are perhaps -// better suited for mathematical interpretations. -// -// To avoid any confusion, as well as to maintain compatibility with a large -// number of software libraries, the quaternions represented using the protocol -// buffer below *must* follow the Hamilton convention, which defines `ij = k` -// (i.e. a right-handed algebra), and therefore: -// -// i^2 = j^2 = k^2 = ijk = −1 -// ij = −ji = k -// jk = −kj = i -// ki = −ik = j -// -// Please DO NOT use this to represent quaternions that follow the JPL -// convention, or any of the other quaternion flavors out there. -// -// Definitions: -// -// - Quaternion norm (or magnitude): `sqrt(x^2 + y^2 + z^2 + w^2)`. -// - Unit (or normalized) quaternion: a quaternion whose norm is 1. -// - Pure quaternion: a quaternion whose scalar component (`w`) is 0. -// - Rotation quaternion: a unit quaternion used to represent rotation. -// - Orientation quaternion: a unit quaternion used to represent orientation. -// -// A quaternion can be normalized by dividing it by its norm. The resulting -// quaternion maintains the same direction, but has a norm of 1, i.e. it moves -// on the unit sphere. This is generally necessary for rotation and orientation -// quaternions, to avoid rounding errors: -// https://en.wikipedia.org/wiki/Rotation_formalisms_in_three_dimensions -// -// Note that `(x, y, z, w)` and `(-x, -y, -z, -w)` represent the same rotation, -// but normalization would be even more useful, e.g. for comparison purposes, if -// it would produce a unique representation. It is thus recommended that `w` be -// kept positive, which can be achieved by changing all the signs when `w` is -// negative. -message Quaternion { - // The x component. - double x = 1; - - // The y component. - double y = 2; - - // The z component. - double z = 3; - - // The scalar component. - double w = 4; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py deleted file mode 100644 index 92b0b7f79d3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/quaternion.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/quaternion.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1cgoogle/type/quaternion.proto\x12\x0bgoogle.type"8\n\nQuaternion\x12\t\n\x01x\x18\x01 \x01(\x01\x12\t\n\x01y\x18\x02 \x01(\x01\x12\t\n\x01z\x18\x03 \x01(\x01\x12\t\n\x01w\x18\x04 \x01(\x01\x42l\n\x0f\x63om.google.typeB\x0fQuaternionProtoP\x01Z@google.golang.org/genproto/googleapis/type/quaternion;quaternion\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.type.quaternion_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\017QuaternionProtoP\001Z@google.golang.org/genproto/googleapis/type/quaternion;quaternion\242\002\003GTP" - _globals["_QUATERNION"]._serialized_start = 45 - _globals["_QUATERNION"]._serialized_end = 101 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi deleted file mode 100644 index 8a7bfbe24c2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/quaternion_pb2.pyi +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class Quaternion(_message.Message): - __slots__ = ("x", "y", "z", "w") - X_FIELD_NUMBER: _ClassVar[int] - Y_FIELD_NUMBER: _ClassVar[int] - Z_FIELD_NUMBER: _ClassVar[int] - W_FIELD_NUMBER: _ClassVar[int] - x: float - y: float - z: float - w: float - def __init__( - self, - x: _Optional[float] = ..., - y: _Optional[float] = ..., - z: _Optional[float] = ..., - w: _Optional[float] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto deleted file mode 100644 index 94090bd085e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday.proto +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2026 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package google.type; - -option go_package = "google.golang.org/genproto/googleapis/type/timeofday;timeofday"; -option java_multiple_files = true; -option java_outer_classname = "TimeOfDayProto"; -option java_package = "com.google.type"; -option objc_class_prefix = "GTP"; - -// Represents a time of day. The date and time zone are either not significant -// or are specified elsewhere. An API may choose to allow leap seconds. Related -// types are [google.type.Date][google.type.Date] and -// `google.protobuf.Timestamp`. -message TimeOfDay { - // Hours of a day in 24 hour format. Must be greater than or equal to 0 and - // typically must be less than or equal to 23. An API may choose to allow the - // value "24:00:00" for scenarios like business closing time. - int32 hours = 1; - - // Minutes of an hour. Must be greater than or equal to 0 and less than or - // equal to 59. - int32 minutes = 2; - - // Seconds of a minute. Must be greater than or equal to 0 and typically must - // be less than or equal to 59. An API may allow the value 60 if it allows - // leap-seconds. - int32 seconds = 3; - - // Fractions of seconds, in nanoseconds. Must be greater than or equal to 0 - // and less than or equal to 999,999,999. - int32 nanos = 4; -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py deleted file mode 100644 index e76f2d45152..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Generated by the protocol buffer compiler. DO NOT EDIT! -# NO CHECKED-IN PROTOBUF GENCODE -# source: google/type/timeofday.proto -# Protobuf Python Version: 6.33.5 -"""Generated protocol buffer code.""" - -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import runtime_version as _runtime_version -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder - -_runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, 6, 33, 5, "", "google/type/timeofday.proto" -) -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1bgoogle/type/timeofday.proto\x12\x0bgoogle.type"K\n\tTimeOfDay\x12\r\n\x05hours\x18\x01 \x01(\x05\x12\x0f\n\x07minutes\x18\x02 \x01(\x05\x12\x0f\n\x07seconds\x18\x03 \x01(\x05\x12\r\n\x05nanos\x18\x04 \x01(\x05\x42i\n\x0f\x63om.google.typeB\x0eTimeOfDayProtoP\x01Z>google.golang.org/genproto/googleapis/type/timeofday;timeofday\xa2\x02\x03GTPb\x06proto3' -) - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages( - DESCRIPTOR, "opentelemetry.agent._vendor.google.type.timeofday_pb2", _globals -) -if not _descriptor._USE_C_DESCRIPTORS: - _globals["DESCRIPTOR"]._loaded_options = None - _globals[ - "DESCRIPTOR" - ]._serialized_options = b"\n\017com.google.typeB\016TimeOfDayProtoP\001Z>google.golang.org/genproto/googleapis/type/timeofday;timeofday\242\002\003GTP" - _globals["_TIMEOFDAY"]._serialized_start = 44 - _globals["_TIMEOFDAY"]._serialized_end = 119 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi deleted file mode 100644 index 1a5e2618956..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/google/type/timeofday_pb2.pyi +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2025 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import ClassVar as _ClassVar -from typing import Optional as _Optional - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message - -DESCRIPTOR: _descriptor.FileDescriptor - -class TimeOfDay(_message.Message): - __slots__ = ("hours", "minutes", "seconds", "nanos") - HOURS_FIELD_NUMBER: _ClassVar[int] - MINUTES_FIELD_NUMBER: _ClassVar[int] - SECONDS_FIELD_NUMBER: _ClassVar[int] - NANOS_FIELD_NUMBER: _ClassVar[int] - hours: int - minutes: int - seconds: int - nanos: int - def __init__( - self, - hours: _Optional[int] = ..., - minutes: _Optional[int] = ..., - seconds: _Optional[int] = ..., - nanos: _Optional[int] = ..., - ) -> None: ... diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/googleapis-common-protos.LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md deleted file mode 100644 index f706835ab3a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna.LICENSE.md +++ /dev/null @@ -1,31 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2013-2026, Kim Davies and contributors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py deleted file mode 100644 index d6c890a9a93..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/__init__.py +++ /dev/null @@ -1,47 +0,0 @@ -from .core import ( - IDNABidiError, - IDNAError, - InvalidCodepoint, - InvalidCodepointContext, - alabel, - check_bidi, - check_hyphen_ok, - check_initial_combiner, - check_label, - check_nfc, - decode, - encode, - ulabel, - uts46_remap, - valid_contextj, - valid_contexto, - valid_label_length, - valid_string_length, -) -from .idnadata import __version__ as unicode_version -from .intranges import intranges_contain -from .package_data import __version__ - -__all__ = [ - "__version__", - "unicode_version", - "IDNABidiError", - "IDNAError", - "InvalidCodepoint", - "InvalidCodepointContext", - "alabel", - "check_bidi", - "check_hyphen_ok", - "check_initial_combiner", - "check_label", - "check_nfc", - "decode", - "encode", - "intranges_contain", - "ulabel", - "uts46_remap", - "valid_contextj", - "valid_contexto", - "valid_label_length", - "valid_string_length", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py deleted file mode 100644 index 8efc1eed736..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/codec.py +++ /dev/null @@ -1,225 +0,0 @@ -from __future__ import annotations - -import codecs -from typing import Any - -from .core import IDNAError, _max_domain_length, _unicode_dots_re, alabel, decode, encode, ulabel - - -class Codec(codecs.Codec): - """Stateless IDNA 2008 codec. - - Implements the :class:`codecs.Codec` protocol so that the whole-domain - encoder (:func:`idna.encode`) and decoder (:func:`idna.decode`) are - accessible through the standard codec machinery as ``"idna2008"``. - - Only the ``"strict"`` error handler is supported; any other handler - raises :exc:`~idna.IDNAError`. - """ - - def encode(self, data: str, errors: str = "strict") -> tuple[bytes, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") - - if not data: - return b"", 0 - - return encode(data), len(data) - - def decode(self, data: bytes, errors: str = "strict") -> tuple[str, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") - - if not data: - return "", 0 - - return decode(data), len(data) - - -class IncrementalEncoder(codecs.BufferedIncrementalEncoder): - """Incremental IDNA 2008 encoder. - - Buffers a partial trailing label across calls until either the next - label separator is seen or ``final=True``, so that streamed input is - encoded one whole label at a time. Any of the four Unicode label - separators (``U+002E``, ``U+3002``, ``U+FF0E``, ``U+FF61``) ends a - label; the result always uses ``U+002E`` as the separator. - - The 253-octet domain length limit (254 with a trailing dot) that - :func:`idna.encode` enforces is applied to the accumulated output, so - that streaming a name and encoding it in one shot either both succeed - with the same result or both raise :exc:`~idna.IDNAError`. - - Only the ``"strict"`` error handler is supported. - """ - - def __init__(self, errors: str = "strict") -> None: - super().__init__(errors) - self._emitted = 0 # octets returned so far - self._trailing_dot = False # whether the output so far ends with "." - - def reset(self) -> None: - super().reset() - self._emitted = 0 - self._trailing_dot = False - - def getstate(self) -> Any: - if not self.buffer and not self._emitted: - return 0 - return (self.buffer, self._emitted, self._trailing_dot) - - def setstate(self, state: Any) -> None: - if state: - self.buffer, self._emitted, self._trailing_dot = state - else: - self.reset() - - def _buffer_encode(self, data: str, errors: str, final: bool) -> tuple[bytes, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") - - result_bytes = b"" - size = 0 - if data: - labels = _unicode_dots_re.split(data) - trailing_dot = b"" - if labels: - if not labels[-1]: - trailing_dot = b"." - del labels[-1] - elif not final: - # Keep potentially unfinished label until the next call - del labels[-1] - if labels: - trailing_dot = b"." - - result = [] - for label in labels: - result.append(alabel(label)) - if size: - size += 1 - size += len(label) - - result_bytes = b".".join(result) + trailing_dot - size += len(trailing_dot) - - # Mirror encode(): the whole name may not exceed 253 octets, or 254 - # when it ends with a dot. Until the input is final a trailing dot - # may still arrive, so only the 254-octet ceiling applies before then. - self._emitted += len(result_bytes) - if result_bytes: - self._trailing_dot = result_bytes.endswith(b".") - may_end_with_dot = self._trailing_dot or not final - if self._emitted > _max_domain_length + may_end_with_dot: - raise IDNAError("Domain too long", code="domain_too_long") - return result_bytes, size - - -class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - """Incremental IDNA 2008 decoder. - - Buffers a partial trailing label across calls until either the next - label separator is seen or ``final=True``, so that streamed input is - decoded one whole label at a time. - - The 254-octet input length limit that :func:`idna.decode` enforces is - applied to the accumulated input, so that streaming a name and decoding - it in one shot either both succeed with the same result or both raise - :exc:`~idna.IDNAError`. - - Only the ``"strict"`` error handler is supported. - """ - - def __init__(self, errors: str = "strict") -> None: - super().__init__(errors) - self._consumed = 0 # input octets consumed so far - - def reset(self) -> None: - super().reset() - self._consumed = 0 - - def getstate(self) -> tuple[bytes, int]: - return (self.buffer, self._consumed) - - def setstate(self, state: tuple[bytes, int]) -> None: - self.buffer, self._consumed = state - - def _buffer_decode(self, data: Any, errors: str, final: bool) -> tuple[str, int]: # ty: ignore[invalid-method-override] - if errors != "strict": - raise IDNAError(f'Unsupported error handling "{errors}"', code="unsupported_errors") - - if not data: - return ("", 0) - - if not isinstance(data, str): - try: - data = str(data, "ascii") - except UnicodeDecodeError as err: - raise IDNAError("Invalid ASCII in A-label", code="invalid_ascii") from err - - # Mirror decode(), which rejects input longer than 254 characters - # (253 plus a possible trailing dot) before looking at any label. - # ``data`` is the unconsumed buffer plus the new input, so this is - # the total seen so far. - if self._consumed + len(data) > _max_domain_length + 1: - raise IDNAError("Domain too long", code="domain_too_long") - - labels = _unicode_dots_re.split(data) - trailing_dot = "" - if labels: - if not labels[-1]: - trailing_dot = "." - del labels[-1] - elif not final: - # Keep potentially unfinished label until the next call - del labels[-1] - if labels: - trailing_dot = "." - - result = [] - size = 0 - for label in labels: - result.append(ulabel(label)) - if size: - size += 1 - size += len(label) - - result_str = ".".join(result) + trailing_dot - size += len(trailing_dot) - self._consumed += size - return (result_str, size) - - -class StreamWriter(Codec, codecs.StreamWriter): - pass - - -class StreamReader(Codec, codecs.StreamReader): - pass - - -def search_function(name: str) -> codecs.CodecInfo | None: - """Codec search function registered with :mod:`codecs`. - - Returns a :class:`codecs.CodecInfo` for the ``"idna2008"`` codec name - so that ``str.encode("idna2008")`` and ``bytes.decode("idna2008")`` - invoke the IDNA 2008 codec defined in this module. - - :param name: The codec name being looked up. - :returns: A :class:`codecs.CodecInfo` instance if ``name`` is - ``"idna2008"``, otherwise ``None``. - """ - if name != "idna2008": - return None - return codecs.CodecInfo( - name=name, - encode=Codec().encode, - decode=Codec().decode, # type: ignore - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) - - -codecs.register(search_function) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py deleted file mode 100644 index 5bedee9bad9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/compat.py +++ /dev/null @@ -1,43 +0,0 @@ -from __future__ import annotations - -from typing import Any - -from .core import decode, encode - - -def ToASCII(label: str) -> bytes: - """Compatibility shim for :rfc:`3490` ``ToASCII``. - - Delegates to :func:`idna.encode` (IDNA 2008). Provided to ease porting - of code written against the legacy :mod:`encodings.idna` API; new code - should call :func:`idna.encode` directly. - - :param label: The label or domain to encode. - :returns: The encoded form as ASCII :class:`bytes`. - """ - return encode(label) - - -def ToUnicode(label: bytes | bytearray) -> str: - """Compatibility shim for :rfc:`3490` ``ToUnicode``. - - Delegates to :func:`idna.decode` (IDNA 2008). Provided to ease porting - of code written against the legacy :mod:`encodings.idna` API; new code - should call :func:`idna.decode` directly. - - :param label: The label or domain to decode. - :returns: The decoded Unicode form. - """ - return decode(label) - - -def nameprep(s: Any) -> None: - """Stub for :rfc:`3491` Nameprep, which is not used by IDNA 2008. - - IDNA 2008 (:rfc:`5891`) replaces Nameprep with the per-codepoint - validity classes from :rfc:`5892`; this function exists only to - return a clear error if legacy code attempts to call it. - - :raises NotImplementedError: Always. - """ - raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py deleted file mode 100644 index d4a6f0e3a7d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/core.py +++ /dev/null @@ -1,863 +0,0 @@ -from __future__ import annotations - -import bisect -import re -import unicodedata -import warnings -from typing import Literal - -from . import idnadata -from .intranges import intranges_contain - -_virama_combining_class = 9 -_alabel_prefix = b"xn--" -_max_input_length = 1024 -_max_domain_length = 253 # RFC 1035 octets, excluding any trailing dot -_STATUS_VALID, _STATUS_MAPPED, _STATUS_DEVIATION, _STATUS_IGNORED = b"VMDI" -_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") -_std3_disallowed_re = re.compile("[\x00-\x2c\x2f\x3a-\x40A-Z\x5b-\x60\x7b-\x7f]") -_bidi_rtl_first = frozenset({"R", "AL"}) -_bidi_rtl_categories = frozenset({"R", "AL", "AN"}) -_bidi_rtl_allowed = frozenset({"R", "AL", "AN", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) -_bidi_rtl_valid_ending = frozenset({"R", "AL", "EN", "AN"}) -_bidi_rtl_numeric = frozenset({"AN", "EN"}) -_bidi_ltr_allowed = frozenset({"L", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"}) -_bidi_ltr_valid_ending = frozenset({"L", "EN"}) -_bidi_joiner_l_or_d = frozenset({"L", "D"}) -_bidi_joiner_r_or_d = frozenset({"R", "D"}) - - -def _joining_type(cp: int) -> str | None: - for jt, ranges in idnadata.joining_types.items(): - if intranges_contain(cp, ranges): - return jt - return None - - -# Machine-readable identifiers for the rule an :class:`IDNAError` reports. -# These strings are stable and documented; exception message wording is not. -_ErrorCode = Literal[ - "input_too_long", - "label_too_long", - "domain_too_long", - "empty_label", - "empty_domain", - "not_nfc", - "hyphen_3_4", - "hyphen_start_end", - "leading_combiner", - "disallowed_codepoint", - "contextj", - "contexto", - "unknown_codepoint", - "bidi_rule_1", - "bidi_rule_2", - "bidi_rule_3", - "bidi_rule_4", - "bidi_rule_5", - "bidi_rule_6", - "bidi_unknown_direction", - "invalid_alabel", - "non_canonical_alabel", - "invalid_ascii", - "invalid_utf8", - "uts46_disallowed", - "uts46_std3", - "unsupported_errors", -] - - -class IDNAError(UnicodeError): - """Base exception for all IDNA-encoding related problems. - - ``str(err)`` is a human-readable description of the failure. The - exception also carries machine-readable attributes so callers do not - need to parse the message: - - * ``code`` -- a short, stable identifier for the rule that failed, such - as ``"disallowed_codepoint"`` or ``"bidi_rule_2"``; the full list is - documented in the README. Message wording, by contrast, may change - between releases. - * ``text`` -- the label (or, for UTS #46 processing, the domain) that - was being validated; - * ``codepoint`` -- the offending codepoint, as an ``int``; - * ``position`` -- the 1-based index of the offending character within - ``text``, matching the position quoted in the message. - - Each is ``None`` when it does not apply. - """ - - code: str | None - text: str | None - codepoint: int | None - position: int | None - - def __init__( - self, - *args: object, - code: _ErrorCode | None = None, - text: str | None = None, - codepoint: int | None = None, - position: int | None = None, - ) -> None: - super().__init__(*args) - self.code = code - self.text = text - self.codepoint = codepoint - self.position = position - - -class IDNABidiError(IDNAError): - """Exception when bidirectional requirements are not satisfied""" - - -class InvalidCodepoint(IDNAError): - """Exception when a disallowed or unallocated codepoint is used""" - - -class InvalidCodepointContext(IDNAError): - """Exception when the codepoint is not valid in the context it is used""" - - -def _combining_class(cp: int) -> int: - v = unicodedata.combining(chr(cp)) - if v == 0 and not unicodedata.name(chr(cp)): - raise ValueError("Unknown character in unicodedata") - return v - - -def _is_script(cp: str, script: str) -> bool: - return intranges_contain(ord(cp), idnadata.scripts[script]) - - -def _punycode(s: str) -> bytes: - return s.encode("punycode") - - -def _unot(s: int) -> str: - return f"U+{s:04X}" - - -def valid_label_length(label: bytes | str) -> bool: - """Check that a label does not exceed the maximum permitted length. - - Per :rfc:`1035` (and :rfc:`5891` §4.2.4) a DNS label must not exceed - 63 octets. The argument may be either a :class:`str` (a U-label, where - length is measured in characters) or :class:`bytes` (an A-label, where - length is measured in octets). - - :param label: The label to check. - :returns: ``True`` if the label is within the length limit, otherwise - ``False``. - """ - return len(label) <= 63 - - -def valid_string_length(domain: bytes | str, trailing_dot: bool) -> bool: - """Check that a full domain name does not exceed the maximum length. - - Per :rfc:`1035`, a domain name is limited to 253 octets when no trailing - dot is present, or 254 octets when one is included. - - :param domain: The full (possibly multi-label) domain name. - :param trailing_dot: ``True`` if ``domain`` includes a trailing ``.``. - :returns: ``True`` if the domain is within the length limit, otherwise - ``False``. - """ - return len(domain) <= _max_domain_length + trailing_dot - - -def check_bidi(label: str, check_ltr: bool = False) -> bool: - """Validate the Bidi Rule from :rfc:`5893` for a single label. - - The Bidi Rule constrains how bidirectional characters (Hebrew, Arabic, - etc.) may appear within a label. By default the check is only applied - when the label contains at least one right-to-left character (Unicode - bidirectional categories ``R``, ``AL``, or ``AN``); set ``check_ltr`` - to ``True`` to apply it to LTR-only labels as well. - - :param label: The label to validate, as a Unicode string. - :param check_ltr: If ``True``, apply the rules even when the label - contains no RTL characters. - :returns: ``True`` if the label satisfies the Bidi Rule. - :raises IDNABidiError: If any of Bidi Rule conditions 1-6 are violated, - or if the directional category of a codepoint cannot be determined. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long", code="input_too_long") - # Bidi rules should only be applied if string contains RTL characters - bidi_label = False - for idx, cp in enumerate(label, 1): - direction = unicodedata.bidirectional(cp) - if direction == "": - # String likely comes from a newer version of Unicode - raise IDNABidiError( - f"Unknown directionality in label {label!r} at position {idx}", - code="bidi_unknown_direction", - text=label, - codepoint=ord(cp), - position=idx, - ) - if direction in _bidi_rtl_categories: - bidi_label = True - if not bidi_label and not check_ltr: - return True - - # Bidi rule 1 - direction = unicodedata.bidirectional(label[0]) - if direction in _bidi_rtl_first: - rtl = True - elif direction == "L": - rtl = False - else: - raise IDNABidiError( - f"First codepoint in label {label!r} must be directionality L, R or AL", - code="bidi_rule_1", - text=label, - codepoint=ord(label[0]), - position=1, - ) - - valid_ending = False - ending_idx = 1 - number_type: str | None = None - for idx, cp in enumerate(label, 1): - direction = unicodedata.bidirectional(cp) - - if rtl: - # Bidi rule 2 - if direction not in _bidi_rtl_allowed: - raise IDNABidiError( - f"Invalid direction for codepoint at position {idx} in a right-to-left label", - code="bidi_rule_2", - text=label, - codepoint=ord(cp), - position=idx, - ) - # Bidi rule 3 - if direction in _bidi_rtl_valid_ending: - valid_ending = True - ending_idx = idx - elif direction != "NSM": - valid_ending = False - ending_idx = idx - # Bidi rule 4 - if direction in _bidi_rtl_numeric: - if not number_type: - number_type = direction - elif number_type != direction: - raise IDNABidiError( - "Can not mix numeral types in a right-to-left label", - code="bidi_rule_4", - text=label, - codepoint=ord(cp), - position=idx, - ) - else: - # Bidi rule 5 - if direction not in _bidi_ltr_allowed: - raise IDNABidiError( - f"Invalid direction for codepoint at position {idx} in a left-to-right label", - code="bidi_rule_5", - text=label, - codepoint=ord(cp), - position=idx, - ) - # Bidi rule 6 - if direction in _bidi_ltr_valid_ending: - valid_ending = True - ending_idx = idx - elif direction != "NSM": - valid_ending = False - ending_idx = idx - - if not valid_ending: - # Rules 3 and 6 concern the last character that is not a - # non-spacing mark, which is what ``ending_idx`` tracks. - raise IDNABidiError( - "Label ends with illegal codepoint directionality", - code="bidi_rule_3" if rtl else "bidi_rule_6", - text=label, - codepoint=ord(label[ending_idx - 1]), - position=ending_idx, - ) - - return True - - -def check_initial_combiner(label: str) -> bool: - """Reject labels that begin with a combining mark. - - Per :rfc:`5891` §4.2.3.2 a label must not start with a character of - Unicode general category ``M`` (Mark). - - :param label: The label to check. - :returns: ``True`` if the first character is not a combining mark. - :raises IDNAError: If the label begins with a combining character. - """ - if label and unicodedata.category(label[0])[0] == "M": - raise IDNAError( - "Label begins with an illegal combining character", - code="leading_combiner", - text=label, - codepoint=ord(label[0]), - position=1, - ) - return True - - -def check_hyphen_ok(label: str) -> bool: - """Validate the hyphen restrictions for a label. - - Per :rfc:`5891` §4.2.3.1 a label must not start or end with a hyphen - (``U+002D``), and must not have hyphens in both the third and fourth - positions (the prefix reserved for A-labels). - - :param label: The label to check. - :returns: ``True`` if the hyphen restrictions are satisfied. - :raises IDNAError: If any of the hyphen restrictions are violated. - """ - if label[2:4] == "--": - raise IDNAError("Label has disallowed hyphens in 3rd and 4th position", code="hyphen_3_4") - if label.startswith("-") or label.endswith("-"): - raise IDNAError("Label must not start or end with a hyphen", code="hyphen_start_end") - return True - - -def check_nfc(label: str) -> None: - """Require that a label is in Unicode Normalization Form C. - - :param label: The label to check. - :raises IDNAError: If ``label`` differs from its NFC normalisation. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long", code="input_too_long") - if unicodedata.normalize("NFC", label) != label: - raise IDNAError("Label must be in Normalization Form C", code="not_nfc") - - -def valid_contextj(label: str, pos: int) -> bool: - """Validate the CONTEXTJ rules from :rfc:`5892` Appendix A. - - These rules govern the contextual use of the joiner codepoints - ``U+200C`` (ZERO WIDTH NON-JOINER, Appendix A.1) and ``U+200D`` - (ZERO WIDTH JOINER, Appendix A.2) within a label. - - :param label: The label containing the codepoint. - :param pos: Index of the joiner codepoint within ``label``. - :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTJ - rule, ``False`` otherwise (including when the codepoint at - ``pos`` is not a recognised joiner). - :raises ValueError: If an adjacent codepoint has no Unicode name when - determining its combining class. - :raises IDNAError: If ``label`` exceeds the defensive input length limit. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long", code="input_too_long") - cp_value = ord(label[pos]) - - if cp_value == 0x200C: - if pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class: - return True - - ok = False - for i in range(pos - 1, -1, -1): - joining_type = _joining_type(ord(label[i])) - if joining_type == "T": - continue - if joining_type in _bidi_joiner_l_or_d: - ok = True - break - break - - if not ok: - return False - - ok = False - for i in range(pos + 1, len(label)): - joining_type = _joining_type(ord(label[i])) - if joining_type == "T": - continue - if joining_type in _bidi_joiner_r_or_d: - ok = True - break - break - return ok - - if cp_value == 0x200D: - return pos > 0 and _combining_class(ord(label[pos - 1])) == _virama_combining_class - - return False - - -def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: - """Validate the CONTEXTO rules from :rfc:`5892` Appendix A. - - Covers the contextual rules for codepoints such as MIDDLE DOT - (``U+00B7``), Greek lower numeral sign, Hebrew punctuation, Katakana - middle dot, and the Arabic-Indic / Extended Arabic-Indic digit ranges. - - :param label: The label containing the codepoint. - :param pos: Index of the codepoint within ``label``. - :param exception: Reserved for forward compatibility; currently unused. - :returns: ``True`` if the codepoint at ``pos`` satisfies its CONTEXTO - rule, ``False`` otherwise (including when the codepoint is not a - recognised CONTEXTO codepoint). - :raises IDNAError: If ``label`` exceeds the defensive input length limit. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long", code="input_too_long") - cp_value = ord(label[pos]) - - if cp_value == 0x00B7: - return 0 < pos < len(label) - 1 and ord(label[pos - 1]) == 0x006C and ord(label[pos + 1]) == 0x006C - - if cp_value == 0x0375: - if pos < len(label) - 1 and len(label) > 1: - return _is_script(label[pos + 1], "Greek") - return False - - if cp_value in {0x05F3, 0x05F4}: - if pos > 0: - return _is_script(label[pos - 1], "Hebrew") - return False - - if cp_value == 0x30FB: - for cp in label: - if cp == "\u30fb": - continue - if _is_script(cp, "Hiragana") or _is_script(cp, "Katakana") or _is_script(cp, "Han"): - return True - return False - - if 0x660 <= cp_value <= 0x669: - return not any(0x6F0 <= ord(cp) <= 0x06F9 for cp in label) - - if 0x6F0 <= cp_value <= 0x6F9: - return not any(0x660 <= ord(cp) <= 0x0669 for cp in label) - - return False - - -def check_label(label: str | bytes | bytearray) -> None: - """Run the full set of IDNA 2008 validity checks on a single label. - - Applies, in order: NFC normalisation (:func:`check_nfc`), hyphen - restrictions (:func:`check_hyphen_ok`), the no-leading-combiner rule - (:func:`check_initial_combiner`), per-codepoint validity (PVALID, - CONTEXTJ, CONTEXTO classes from :rfc:`5892`), and the Bidi Rule - (:func:`check_bidi`). - - :param label: The label to validate. ``bytes`` or ``bytearray`` input - is decoded as UTF-8 first. - :raises IDNAError: If the label is empty or fails a structural rule. - :raises InvalidCodepoint: If the label contains a DISALLOWED or - UNASSIGNED codepoint. - :raises InvalidCodepointContext: If a CONTEXTJ or CONTEXTO codepoint - is not valid in its context. - :raises IDNABidiError: If the Bidi Rule is violated. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long", code="input_too_long") - if isinstance(label, (bytes, bytearray)): - try: - label = label.decode("utf-8") - except UnicodeDecodeError as err: - raise IDNAError("Invalid UTF-8 in label", code="invalid_utf8") from err - if len(label) == 0: - raise IDNAError("Empty Label", code="empty_label") - - # Check against the domain length rather than the label length to - # support some UTS #46 use cases, while still bounding the work done - # by the label contextual rules below. - if not valid_string_length(label, trailing_dot=True): - raise IDNAError("Label too long", code="label_too_long") - - check_nfc(label) - check_hyphen_ok(label) - check_initial_combiner(label) - - for pos, cp in enumerate(label): - cp_value = ord(cp) - if intranges_contain(cp_value, idnadata.codepoint_classes["PVALID"]): - continue - if intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]): - try: - contextj_ok = valid_contextj(label, pos) - except ValueError as err: - raise IDNAError( - f"Unknown codepoint adjacent to joiner {_unot(cp_value)} at position {pos + 1} in {label!r}", - code="unknown_codepoint", - text=label, - codepoint=cp_value, - position=pos + 1, - ) from err - if not contextj_ok: - raise InvalidCodepointContext( - f"Joiner {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}", - code="contextj", - text=label, - codepoint=cp_value, - position=pos + 1, - ) - elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTO"]): - if not valid_contexto(label, pos): - raise InvalidCodepointContext( - f"Codepoint {_unot(cp_value)} not allowed at position {pos + 1} in {label!r}", - code="contexto", - text=label, - codepoint=cp_value, - position=pos + 1, - ) - else: - raise InvalidCodepoint( - f"Codepoint {_unot(cp_value)} at position {pos + 1} of {label!r} not allowed", - code="disallowed_codepoint", - text=label, - codepoint=cp_value, - position=pos + 1, - ) - - check_bidi(label) - - -def alabel(label: str) -> bytes: - """Convert a single U-label into its A-label form. - - The result is the ASCII-Compatible Encoding (ACE) form per :rfc:`5891` - §4: the label is validated, Punycode-encoded, and prefixed with - ``xn--``. Pure ASCII labels that are already valid IDNA labels are - returned unchanged (as :class:`bytes`). - - :param label: The label to convert, as a Unicode string. - :returns: The A-label as ASCII-encoded :class:`bytes`. - :raises IDNAError: If the label is invalid or the resulting A-label - exceeds 63 octets. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long", code="input_too_long") - try: - label_bytes = label.encode("ascii") - except UnicodeEncodeError: - pass - else: - ulabel(label_bytes) - if not valid_label_length(label_bytes): - raise IDNAError("Label too long", code="label_too_long") - return label_bytes - - check_label(label) - label_bytes = _alabel_prefix + _punycode(label) - - if not valid_label_length(label_bytes): - raise IDNAError("Label too long", code="label_too_long") - - return label_bytes - - -def ulabel(label: str | bytes | bytearray) -> str: - """Convert a single A-label into its U-label form. - - Performs the inverse of :func:`alabel`: an ``xn--``-prefixed label is - Punycode-decoded and validated, and is rejected unless it is the - canonical A-label for the decoded U-label (:rfc:`5891` §5.3). Labels - that are already Unicode (or plain ASCII without the ACE prefix) are - validated and returned as a Unicode string. - - :param label: The label to convert. ``bytes`` or ``bytearray`` input - is treated as ASCII. - :returns: The U-label as a Unicode string. - :raises IDNAError: If the label is malformed or fails validation. - """ - if len(label) > _max_input_length: - raise IDNAError("Label too long", code="input_too_long") - if not isinstance(label, (bytes, bytearray)): - try: - label_bytes = label.encode("ascii") - except UnicodeEncodeError: - check_label(label) - return label - else: - label_bytes = bytes(label) - if not label_bytes.isascii(): - raise IDNAError("Invalid ASCII in A-label", code="invalid_ascii") - - label_bytes = label_bytes.lower() - if label_bytes.startswith(_alabel_prefix): - label_bytes = label_bytes[len(_alabel_prefix) :] - if not label_bytes: - raise IDNAError("Malformed A-label, no Punycode eligible content found", code="invalid_alabel") - if label_bytes.endswith(b"-"): - raise IDNAError("A-label must not end with a hyphen", code="invalid_alabel") - else: - check_label(label_bytes) - return label_bytes.decode("ascii") - - try: - label = label_bytes.decode("punycode") - except UnicodeError as err: - raise IDNAError("Invalid A-label", code="invalid_alabel") from err - # RFC 5891 §5.3: the label is rejected unless re-encoding the decoded - # form reproduces the (lowercased) input. This catches "fake A-labels" - # (RFC 5890 §2.3.2.1) such as ``xn---bbk``, a non-canonical Punycode - # spelling of ``xn--bbk`` that would otherwise decode to the same - # U-label and so display identically to a different wire-format name. - if _punycode(label) != label_bytes: - raise IDNAError("A-label is not the canonical Punycode encoding of its U-label", code="non_canonical_alabel") - check_label(label) - return label - - -def _check_std3(text: str, domain: str, offset: int) -> None: - """Raise if ``text``, a slice of ``domain`` starting at ``offset`` that - UTS #46 mapping left unchanged, contains an ASCII character disallowed - under ``UseSTD3ASCIIRules``.""" - match = _std3_disallowed_re.search(text) - if match: - codepoint = ord(match.group()) - position = offset + match.start() + 1 - raise InvalidCodepoint( - f"Codepoint {_unot(codepoint)} not allowed at position {position} in {domain!r}", - code="uts46_std3", - text=domain, - codepoint=codepoint, - position=position, - ) - - -def _warn_transitional() -> None: - warnings.warn( - "Transitional processing is deprecated in UTS #46 and has no effect. " - "The transitional argument will be removed in a future version.", - DeprecationWarning, - stacklevel=3, - ) - - -def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: - """Apply the UTS #46 character mapping to a domain string. - - Implements the mapping table from `UTS #46 §4 - `_: each character is kept, - replaced, or rejected based on its status (``V``, ``M``, ``D``, - ``I``, ``X``). The result is returned in Normalisation Form C. - - :param domain: The full domain name to remap. - :param std3_rules: If ``True``, apply UTS #46's ``UseSTD3ASCIIRules``: - after mapping, any ASCII character other than a lowercase letter, - digit, hyphen or the label separator ``.`` is rejected, whether it - appeared in the input or was produced by a mapping (e.g. U+FF01 - FULLWIDTH EXCLAMATION MARK maps to ``!``). If ``False``, such - characters are passed through. - :param transitional: Deprecated and ignored. UTS #46 deprecated - transitional processing in Unicode 15.1 and deviation (status - ``D``) codepoints are now always kept, so this has no effect - beyond emitting a :class:`DeprecationWarning`. It will be removed - in a future version. - :returns: The remapped domain, in Normalisation Form C. - :raises InvalidCodepoint: If the domain contains a disallowed - codepoint under the chosen rules. - :raises IDNAError: If ``domain`` exceeds the defensive input length limit. - """ - if transitional: - _warn_transitional() - if len(domain) > _max_input_length: - raise IDNAError("Domain too long", code="input_too_long") - if domain.isascii(): - # The only ASCII mapping in UTS #46 is upper- to lowercase, and - # ASCII is invariant under NFC, so lowercasing is the whole job. - result = domain.lower() - if std3_rules: - _check_std3(result, domain, 0) - return result - - from .uts46data import uts46_replacements, uts46_starts, uts46_statuses - - # ``start`` marks the run of unchanged input not yet copied; a run is - # only sliced out when a character must be replaced or dropped, so the - # common no-change case makes no copy. STD3 is checked per output piece - # to report a violation at its input position. - output: list[str] = [] - start = 0 - for pos, char in enumerate(domain): - code_point = ord(char) - i = code_point if code_point < 256 else bisect.bisect_right(uts46_starts, code_point) - 1 - status = uts46_statuses[i] - # UTS #46 §4: V valid, D deviation (kept), M mapped, I ignored, - # anything else disallowed. - if status == _STATUS_VALID: - continue - if status == _STATUS_MAPPED: - replacement = uts46_replacements[i] - elif status == _STATUS_DEVIATION: - continue - elif status == _STATUS_IGNORED: - replacement = None - else: - raise InvalidCodepoint( - f"Codepoint {_unot(code_point)} not allowed at position {pos + 1} in {domain!r}", - code="uts46_disallowed", - text=domain, - codepoint=code_point, - position=pos + 1, - ) - if start < pos: - run = domain[start:pos] - if std3_rules: - _check_std3(run, domain, start) - output.append(run) - if replacement: - if std3_rules and _std3_disallowed_re.search(replacement): - raise InvalidCodepoint( - f"Codepoint {_unot(code_point)} not allowed at position {pos + 1} in {domain!r}", - code="uts46_std3", - text=domain, - codepoint=code_point, - position=pos + 1, - ) - output.append(replacement) - start = pos + 1 - - if start == 0: - if std3_rules: - _check_std3(domain, domain, 0) - return unicodedata.normalize("NFC", domain) - tail = domain[start:] - if std3_rules: - _check_std3(tail, domain, start) - output.append(tail) - return unicodedata.normalize("NFC", "".join(output)) - - -def encode( - s: str | bytes | bytearray, - strict: bool = False, - uts46: bool = False, - std3_rules: bool = False, - transitional: bool = False, -) -> bytes: - """Encode a Unicode domain name into its ASCII (A-label) form. - - Splits the input on label separators (only ``U+002E`` if ``strict`` is - set; otherwise also IDEOGRAPHIC FULL STOP ``U+3002``, FULLWIDTH FULL - STOP ``U+FF0E``, and HALFWIDTH IDEOGRAPHIC FULL STOP ``U+FF61``), - encodes each label with :func:`alabel`, and rejoins them with ``.``. - Optionally pre-processes the input through :func:`uts46_remap`. - - :param s: The domain name to encode. - :param strict: If ``True``, only ``U+002E`` is recognised as a label - separator. - :param uts46: If ``True``, apply UTS #46 mapping before encoding. - :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is - ``True``. - :param transitional: Deprecated and ignored (see :func:`uts46_remap`): - emits a :class:`DeprecationWarning` and will be removed in a - future version. - :returns: The encoded domain as ASCII :class:`bytes`. - :raises IDNAError: If the domain is empty, contains an invalid label, - or exceeds the maximum domain length. - """ - if transitional: - _warn_transitional() - if not isinstance(s, str): - try: - s = str(s, "ascii") - except (UnicodeDecodeError, TypeError) as err: - raise IDNAError( - "should pass a unicode string to the function rather than a byte string.", code="invalid_ascii" - ) from err - if len(s) > _max_input_length: - raise IDNAError("Domain too long", code="input_too_long") - if uts46: - s = uts46_remap(s, std3_rules) - - if not valid_string_length(s, trailing_dot=True): - raise IDNAError("Domain too long", code="domain_too_long") - - trailing_dot = False - result = [] - labels = s.split(".") if strict else _unicode_dots_re.split(s) - if not labels or labels == [""]: - raise IDNAError("Empty domain", code="empty_domain") - if labels[-1] == "": - del labels[-1] - trailing_dot = True - for label in labels: - s = alabel(label) - if s: - result.append(s) - else: - raise IDNAError("Empty label", code="empty_label") - if trailing_dot: - result.append(b"") - s = b".".join(result) - if not valid_string_length(s, trailing_dot): - raise IDNAError("Domain too long", code="domain_too_long") - return s - - -def decode( - s: str | bytes | bytearray, - strict: bool = False, - uts46: bool = False, - std3_rules: bool = False, - display: bool = False, -) -> str: - """Decode an A-label-encoded domain name back to Unicode. - - Splits the input on label separators (see :func:`encode` for the - rules), decodes each label with :func:`ulabel`, and rejoins them - with ``.``. Optionally pre-processes the input through - :func:`uts46_remap`. - - :param s: The domain name to decode. - :param strict: If ``True``, only ``U+002E`` is recognised as a label - separator. - :param uts46: If ``True``, apply UTS #46 mapping before decoding. - :param std3_rules: Forwarded to :func:`uts46_remap` when ``uts46`` is - ``True``. - :param display: If ``True``, any ``xn--`` label that fails IDNA - validation is passed through unchanged (lowercased) rather than - aborting the whole call. Intended for "decode for display" - consumers (e.g. URL libraries, HTTP clients) that want to show - the user the label as it appears on the wire when it cannot be - rendered as Unicode. Matches the per-label recovery prescribed - by UTS #46 §4 and the WHATWG URL "domain to Unicode" algorithm. - :returns: The decoded domain as a Unicode string. - :raises IDNAError: If the input is not valid ASCII, contains an - invalid label, or is empty. - """ - if not isinstance(s, str): - try: - s = str(s, "ascii") - except (UnicodeDecodeError, TypeError) as err: - raise IDNAError("Invalid ASCII in A-label", code="invalid_ascii") from err - if len(s) > _max_input_length: - raise IDNAError("Domain too long", code="input_too_long") - if uts46: - s = uts46_remap(s, std3_rules, False) - if not valid_string_length(s, trailing_dot=True): - raise IDNAError("Domain too long", code="domain_too_long") - trailing_dot = False - result = [] - labels = s.split(".") if strict else _unicode_dots_re.split(s) - if not labels or labels == [""]: - raise IDNAError("Empty domain", code="empty_domain") - if not labels[-1]: - del labels[-1] - trailing_dot = True - for label in labels: - try: - u = ulabel(label) - except IDNAError: - if display and label[:4].lower() == "xn--": - u = label.lower() - else: - raise - if u: - result.append(u) - else: - raise IDNAError("Empty label", code="empty_label") - if trailing_dot: - result.append("") - return ".".join(result) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py deleted file mode 100644 index 471c047d1f2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/idnadata.py +++ /dev/null @@ -1,1933 +0,0 @@ -# This file is automatically generated by tools/idna-data - -__version__ = "18.0.0" - -scripts = { - "Greek": ( - 0x37000000374, - 0x37500000378, - 0x37A0000037E, - 0x37F00000380, - 0x38400000385, - 0x38600000387, - 0x3880000038B, - 0x38C0000038D, - 0x38E000003A2, - 0x3A3000003E2, - 0x3F000000400, - 0x1D2600001D2B, - 0x1D5D00001D62, - 0x1D6600001D6B, - 0x1DBF00001DC0, - 0x1F0000001F16, - 0x1F1800001F1E, - 0x1F2000001F46, - 0x1F4800001F4E, - 0x1F5000001F58, - 0x1F5900001F5A, - 0x1F5B00001F5C, - 0x1F5D00001F5E, - 0x1F5F00001F7E, - 0x1F8000001FB5, - 0x1FB600001FC5, - 0x1FC600001FD4, - 0x1FD600001FDC, - 0x1FDD00001FF0, - 0x1FF200001FF5, - 0x1FF600001FFF, - 0x212600002127, - 0xAB650000AB66, - 0x101400001018F, - 0x101A0000101A1, - 0x1D2000001D246, - 0x1DFF30001DFF5, - ), - "Han": ( - 0x2E8000002E9A, - 0x2E9B00002EF4, - 0x2F0000002FD6, - 0x300500003006, - 0x300700003008, - 0x30210000302A, - 0x30380000303C, - 0x340000004DC0, - 0x4E000000A000, - 0xF9000000FA6E, - 0xFA700000FADA, - 0x16FE200016FE4, - 0x16FF000016FF7, - 0x200000002A6E0, - 0x2A7000002B81F, - 0x2B8200002CEAE, - 0x2CEB00002EBE1, - 0x2EBF00002EE5E, - 0x2F8000002FA1E, - 0x300000003134B, - 0x313500003347A, - ), - "Hebrew": ( - 0x591000005CA, - 0x5D0000005EB, - 0x5EF000005F5, - 0xFB1D0000FB37, - 0xFB380000FB3D, - 0xFB3E0000FB3F, - 0xFB400000FB42, - 0xFB430000FB45, - 0xFB460000FB50, - ), - "Hiragana": ( - 0x304100003097, - 0x309D000030A0, - 0x1B0010001B120, - 0x1B1230001B124, - 0x1B1320001B133, - 0x1B1500001B153, - 0x1F2000001F201, - ), - "Katakana": ( - 0x30A1000030FB, - 0x30FD00003100, - 0x31F000003200, - 0x32D0000032FF, - 0x330000003358, - 0xFF660000FF70, - 0xFF710000FF9E, - 0x1AFF00001AFF4, - 0x1AFF50001AFFC, - 0x1AFFD0001AFFF, - 0x1B0000001B001, - 0x1B1200001B123, - 0x1B1240001B129, - 0x1B1550001B156, - 0x1B1640001B169, - ), -} - - -joining_types = { - "C": ( - 0x64000000641, - 0x7FA000007FB, - 0x88300000886, - 0x180A0000180B, - 0x200D0000200E, - ), - "D": ( - 0x62000000621, - 0x62600000627, - 0x62800000629, - 0x62A0000062F, - 0x63300000640, - 0x64100000648, - 0x6490000064B, - 0x66E00000670, - 0x67800000688, - 0x69A000006C0, - 0x6C1000006C3, - 0x6CC000006CD, - 0x6CE000006CF, - 0x6D0000006D2, - 0x6FA000006FD, - 0x6FF00000700, - 0x71200000715, - 0x71A0000071E, - 0x71F00000728, - 0x7290000072A, - 0x72B0000072C, - 0x72D0000072F, - 0x74E00000759, - 0x75C0000076B, - 0x76D00000771, - 0x77200000773, - 0x77500000778, - 0x77A00000780, - 0x7CA000007EB, - 0x84100000846, - 0x84800000849, - 0x84A00000854, - 0x85500000856, - 0x86000000861, - 0x86200000866, - 0x86800000869, - 0x88600000887, - 0x8890000088E, - 0x88F00000890, - 0x8A0000008AA, - 0x8AF000008B1, - 0x8B3000008B9, - 0x8BA000008C9, - 0x180700001808, - 0x182000001879, - 0x1887000018A9, - 0x18AA000018AB, - 0xA8400000A872, - 0x10AC000010AC5, - 0x10AD300010AD7, - 0x10AD800010ADD, - 0x10ADE00010AE1, - 0x10AEB00010AEF, - 0x10B8000010B81, - 0x10B8200010B83, - 0x10B8600010B89, - 0x10B8A00010B8C, - 0x10B8D00010B8E, - 0x10B9000010B91, - 0x10BAD00010BAF, - 0x10D0100010D22, - 0x10D2300010D24, - 0x10EC300010EC5, - 0x10EC600010EC8, - 0x10F3000010F33, - 0x10F3400010F45, - 0x10F5100010F54, - 0x10F7000010F74, - 0x10F7600010F82, - 0x10FB000010FB1, - 0x10FB200010FB4, - 0x10FB800010FB9, - 0x10FBB00010FBD, - 0x10FBE00010FC0, - 0x10FC100010FC2, - 0x10FC400010FC5, - 0x10FCA00010FCB, - 0x1E9000001E944, - ), - "L": ( - 0xA8720000A873, - 0x10ACD00010ACE, - 0x10AD700010AD8, - 0x10D0000010D01, - 0x10ED900010EEF, - 0x10FCB00010FCC, - ), - "R": ( - 0x62200000626, - 0x62700000628, - 0x6290000062A, - 0x62F00000633, - 0x64800000649, - 0x67100000674, - 0x67500000678, - 0x6880000069A, - 0x6C0000006C1, - 0x6C3000006CC, - 0x6CD000006CE, - 0x6CF000006D0, - 0x6D2000006D4, - 0x6D5000006D6, - 0x6EE000006F0, - 0x71000000711, - 0x7150000071A, - 0x71E0000071F, - 0x72800000729, - 0x72A0000072B, - 0x72C0000072D, - 0x72F00000730, - 0x74D0000074E, - 0x7590000075C, - 0x76B0000076D, - 0x77100000772, - 0x77300000775, - 0x7780000077A, - 0x84000000841, - 0x84600000848, - 0x8490000084A, - 0x85400000855, - 0x85600000859, - 0x86700000868, - 0x8690000086B, - 0x87000000883, - 0x88E0000088F, - 0x8AA000008AD, - 0x8AE000008AF, - 0x8B1000008B3, - 0x8B9000008BA, - 0x10AC500010AC6, - 0x10AC700010AC8, - 0x10AC900010ACB, - 0x10ACE00010AD3, - 0x10ADD00010ADE, - 0x10AE100010AE2, - 0x10AE400010AE5, - 0x10AEF00010AF0, - 0x10B8100010B82, - 0x10B8300010B86, - 0x10B8900010B8A, - 0x10B8C00010B8D, - 0x10B8E00010B90, - 0x10B9100010B92, - 0x10BA900010BAD, - 0x10D2200010D23, - 0x10EC200010EC3, - 0x10F3300010F34, - 0x10F5400010F55, - 0x10F7400010F76, - 0x10FB400010FB7, - 0x10FB900010FBB, - 0x10FBD00010FBE, - 0x10FC200010FC4, - 0x10FC900010FCA, - ), - "T": ( - 0xAD000000AE, - 0x30000000370, - 0x4830000048A, - 0x591000005BE, - 0x5BF000005C0, - 0x5C1000005C3, - 0x5C4000005C6, - 0x5C7000005CA, - 0x6100000061B, - 0x61C0000061D, - 0x64B00000660, - 0x67000000671, - 0x6D6000006DD, - 0x6DF000006E5, - 0x6E7000006E9, - 0x6EA000006EE, - 0x70F00000710, - 0x71100000712, - 0x7300000074B, - 0x7A6000007B1, - 0x7EB000007F4, - 0x7FD000007FE, - 0x8160000081A, - 0x81B00000824, - 0x82500000828, - 0x8290000082E, - 0x8590000085C, - 0x897000008A0, - 0x8CA000008E2, - 0x8E300000903, - 0x93A0000093B, - 0x93C0000093D, - 0x94100000949, - 0x94D0000094E, - 0x95100000958, - 0x96200000964, - 0x98100000982, - 0x9BC000009BD, - 0x9C1000009C5, - 0x9CD000009CE, - 0x9E2000009E4, - 0x9FE000009FF, - 0xA0100000A03, - 0xA3C00000A3D, - 0xA4100000A43, - 0xA4700000A49, - 0xA4B00000A4E, - 0xA5100000A52, - 0xA7000000A72, - 0xA7500000A76, - 0xA8100000A83, - 0xABC00000ABD, - 0xAC100000AC6, - 0xAC700000AC9, - 0xACD00000ACE, - 0xAE200000AE4, - 0xAFA00000B00, - 0xB0100000B02, - 0xB3C00000B3D, - 0xB3F00000B40, - 0xB4100000B45, - 0xB4D00000B4E, - 0xB5300000B57, - 0xB6200000B64, - 0xB8200000B83, - 0xBC000000BC1, - 0xBCD00000BCE, - 0xC0000000C01, - 0xC0400000C05, - 0xC3C00000C3D, - 0xC3E00000C41, - 0xC4600000C49, - 0xC4A00000C4E, - 0xC5500000C57, - 0xC6200000C64, - 0xC8100000C82, - 0xCBC00000CBD, - 0xCBF00000CC0, - 0xCC600000CC7, - 0xCCC00000CCE, - 0xCE200000CE4, - 0xD0000000D02, - 0xD3B00000D3D, - 0xD4100000D45, - 0xD4D00000D4E, - 0xD6200000D64, - 0xD8100000D82, - 0xDCA00000DCB, - 0xDD200000DD5, - 0xDD600000DD7, - 0xE3100000E32, - 0xE3400000E3B, - 0xE4700000E4F, - 0xEB100000EB2, - 0xEB400000EBD, - 0xEC800000ECF, - 0xF1800000F1A, - 0xF3500000F36, - 0xF3700000F38, - 0xF3900000F3A, - 0xF7100000F7F, - 0xF8000000F85, - 0xF8600000F88, - 0xF8D00000F98, - 0xF9900000FBD, - 0xFC600000FC7, - 0x102D00001031, - 0x103200001038, - 0x10390000103B, - 0x103D0000103F, - 0x10580000105A, - 0x105E00001061, - 0x107100001075, - 0x108200001083, - 0x108500001087, - 0x108D0000108E, - 0x109D0000109E, - 0x135D00001360, - 0x171200001715, - 0x173200001734, - 0x175200001754, - 0x177200001774, - 0x17B4000017B6, - 0x17B7000017BE, - 0x17C6000017C7, - 0x17C9000017D4, - 0x17DD000017DE, - 0x180B0000180E, - 0x180F00001810, - 0x188500001887, - 0x18A9000018AA, - 0x192000001923, - 0x192700001929, - 0x193200001933, - 0x19390000193C, - 0x1A1700001A19, - 0x1A1B00001A1C, - 0x1A5600001A57, - 0x1A5800001A5F, - 0x1A6000001A61, - 0x1A6200001A63, - 0x1A6500001A6D, - 0x1A7300001A7D, - 0x1A7F00001A80, - 0x1AB000001AF1, - 0x1B0000001B04, - 0x1B3400001B35, - 0x1B3600001B3B, - 0x1B3C00001B3D, - 0x1B4200001B43, - 0x1B6B00001B74, - 0x1B8000001B82, - 0x1BA200001BA6, - 0x1BA800001BAA, - 0x1BAB00001BAE, - 0x1BE600001BE7, - 0x1BE800001BEA, - 0x1BED00001BEE, - 0x1BEF00001BF2, - 0x1C2C00001C34, - 0x1C3600001C38, - 0x1CD000001CD3, - 0x1CD400001CE1, - 0x1CE200001CE9, - 0x1CED00001CEE, - 0x1CF400001CF5, - 0x1CF800001CFA, - 0x1DC000001E00, - 0x200B0000200C, - 0x200E00002010, - 0x202A0000202F, - 0x206000002065, - 0x206A00002070, - 0x20D0000020F1, - 0x2CEF00002CF2, - 0x2D7F00002D80, - 0x2DE000002E00, - 0x302A0000302E, - 0x30990000309B, - 0xA66F0000A673, - 0xA6740000A67E, - 0xA69E0000A6A0, - 0xA6F00000A6F2, - 0xA8020000A803, - 0xA8060000A807, - 0xA80B0000A80C, - 0xA8250000A827, - 0xA82C0000A82D, - 0xA8C40000A8C6, - 0xA8E00000A8F2, - 0xA8FF0000A900, - 0xA9260000A92E, - 0xA9470000A952, - 0xA9800000A983, - 0xA9B30000A9B4, - 0xA9B60000A9BA, - 0xA9BC0000A9BE, - 0xA9E50000A9E6, - 0xAA290000AA2F, - 0xAA310000AA33, - 0xAA350000AA37, - 0xAA430000AA44, - 0xAA4C0000AA4D, - 0xAA7C0000AA7D, - 0xAAB00000AAB1, - 0xAAB20000AAB5, - 0xAAB70000AAB9, - 0xAABE0000AAC0, - 0xAAC10000AAC2, - 0xAAEC0000AAEE, - 0xAAF60000AAF7, - 0xABE50000ABE6, - 0xABE80000ABE9, - 0xABED0000ABEE, - 0xFB1E0000FB1F, - 0xFE000000FE10, - 0xFE200000FE30, - 0xFEFF0000FF00, - 0xFFF90000FFFC, - 0x101FD000101FE, - 0x102E0000102E1, - 0x103760001037B, - 0x10A0100010A04, - 0x10A0500010A07, - 0x10A0C00010A10, - 0x10A3800010A3B, - 0x10A3F00010A40, - 0x10AE500010AE7, - 0x10D2400010D28, - 0x10D6900010D6E, - 0x10EAB00010EAD, - 0x10ECB00010ED0, - 0x10EF000010F00, - 0x10F4600010F51, - 0x10F8200010F86, - 0x1100100011002, - 0x1103800011047, - 0x1107000011071, - 0x1107300011075, - 0x1107F00011082, - 0x110B3000110B7, - 0x110B9000110BB, - 0x110C2000110C3, - 0x1110000011103, - 0x111270001112C, - 0x1112D00011135, - 0x1117300011174, - 0x1118000011182, - 0x111B6000111BF, - 0x111C9000111CD, - 0x111CF000111D0, - 0x1122F00011232, - 0x1123400011235, - 0x1123600011238, - 0x1123E0001123F, - 0x1124100011242, - 0x112DF000112E0, - 0x112E3000112EB, - 0x1130000011302, - 0x1133B0001133D, - 0x1134000011341, - 0x113660001136D, - 0x1137000011375, - 0x113BB000113C1, - 0x113CE000113CF, - 0x113D0000113D1, - 0x113D2000113D3, - 0x113E1000113E3, - 0x1143800011440, - 0x1144200011445, - 0x1144600011447, - 0x1145E0001145F, - 0x114B3000114B9, - 0x114BA000114BB, - 0x114BF000114C1, - 0x114C2000114C4, - 0x115B2000115B6, - 0x115BC000115BE, - 0x115BF000115C1, - 0x115DC000115DE, - 0x116330001163B, - 0x1163D0001163E, - 0x1163F00011641, - 0x116AB000116AC, - 0x116AD000116AE, - 0x116B0000116B6, - 0x116B7000116B8, - 0x1171D0001171E, - 0x1171F00011720, - 0x1172200011726, - 0x117270001172C, - 0x1182F00011838, - 0x118390001183B, - 0x1193B0001193D, - 0x1193E0001193F, - 0x1194300011944, - 0x119D4000119D8, - 0x119DA000119DC, - 0x119E0000119E1, - 0x11A0100011A0B, - 0x11A3300011A39, - 0x11A3B00011A3F, - 0x11A4700011A48, - 0x11A5100011A57, - 0x11A5900011A5C, - 0x11A8A00011A97, - 0x11A9800011A9A, - 0x11B6000011B61, - 0x11B6200011B65, - 0x11B6600011B67, - 0x11C3000011C37, - 0x11C3800011C3E, - 0x11C3F00011C40, - 0x11C9200011CA8, - 0x11CAA00011CB1, - 0x11CB200011CB4, - 0x11CB500011CB7, - 0x11D3100011D37, - 0x11D3A00011D3B, - 0x11D3C00011D3E, - 0x11D3F00011D46, - 0x11D4700011D48, - 0x11D9000011D92, - 0x11D9500011D96, - 0x11D9700011D98, - 0x11DF000011DF1, - 0x11EF300011EF5, - 0x11F0000011F02, - 0x11F3600011F3B, - 0x11F4000011F41, - 0x11F4200011F43, - 0x11F5A00011F5B, - 0x1343000013441, - 0x1344700013456, - 0x1611E0001612A, - 0x1612D00016130, - 0x16AF000016AF5, - 0x16B3000016B37, - 0x16F4F00016F50, - 0x16F8F00016F93, - 0x16FE400016FE5, - 0x1BC9D0001BC9F, - 0x1BCA00001BCA4, - 0x1CF000001CF2E, - 0x1CF300001CF47, - 0x1D1270001D129, - 0x1D1670001D16A, - 0x1D1730001D183, - 0x1D1850001D18C, - 0x1D1AA0001D1AE, - 0x1D2420001D245, - 0x1D25B0001D25D, - 0x1DA000001DA37, - 0x1DA3B0001DA6D, - 0x1DA750001DA76, - 0x1DA840001DA85, - 0x1DA9B0001DAA0, - 0x1DAA10001DAB0, - 0x1E0000001E007, - 0x1E0080001E019, - 0x1E01B0001E022, - 0x1E0230001E025, - 0x1E0260001E02B, - 0x1E08F0001E090, - 0x1E1300001E137, - 0x1E2AE0001E2AF, - 0x1E2EC0001E2F0, - 0x1E4EC0001E4F0, - 0x1E5EE0001E5F0, - 0x1E6E30001E6E4, - 0x1E6E60001E6E7, - 0x1E6EE0001E6F0, - 0x1E6F50001E6F6, - 0x1E8D00001E8D7, - 0x1E9440001E94C, - 0xE0001000E0002, - 0xE0020000E0080, - 0xE0100000E01F0, - ), -} - - -codepoint_classes = { - "PVALID": ( - 0x2D0000002E, - 0x300000003A, - 0x610000007B, - 0xDF000000F7, - 0xF800000100, - 0x10100000102, - 0x10300000104, - 0x10500000106, - 0x10700000108, - 0x1090000010A, - 0x10B0000010C, - 0x10D0000010E, - 0x10F00000110, - 0x11100000112, - 0x11300000114, - 0x11500000116, - 0x11700000118, - 0x1190000011A, - 0x11B0000011C, - 0x11D0000011E, - 0x11F00000120, - 0x12100000122, - 0x12300000124, - 0x12500000126, - 0x12700000128, - 0x1290000012A, - 0x12B0000012C, - 0x12D0000012E, - 0x12F00000130, - 0x13100000132, - 0x13500000136, - 0x13700000139, - 0x13A0000013B, - 0x13C0000013D, - 0x13E0000013F, - 0x14200000143, - 0x14400000145, - 0x14600000147, - 0x14800000149, - 0x14B0000014C, - 0x14D0000014E, - 0x14F00000150, - 0x15100000152, - 0x15300000154, - 0x15500000156, - 0x15700000158, - 0x1590000015A, - 0x15B0000015C, - 0x15D0000015E, - 0x15F00000160, - 0x16100000162, - 0x16300000164, - 0x16500000166, - 0x16700000168, - 0x1690000016A, - 0x16B0000016C, - 0x16D0000016E, - 0x16F00000170, - 0x17100000172, - 0x17300000174, - 0x17500000176, - 0x17700000178, - 0x17A0000017B, - 0x17C0000017D, - 0x17E0000017F, - 0x18000000181, - 0x18300000184, - 0x18500000186, - 0x18800000189, - 0x18C0000018E, - 0x19200000193, - 0x19500000196, - 0x1990000019C, - 0x19E0000019F, - 0x1A1000001A2, - 0x1A3000001A4, - 0x1A5000001A6, - 0x1A8000001A9, - 0x1AA000001AC, - 0x1AD000001AE, - 0x1B0000001B1, - 0x1B4000001B5, - 0x1B6000001B7, - 0x1B9000001BC, - 0x1BD000001C4, - 0x1CE000001CF, - 0x1D0000001D1, - 0x1D2000001D3, - 0x1D4000001D5, - 0x1D6000001D7, - 0x1D8000001D9, - 0x1DA000001DB, - 0x1DC000001DE, - 0x1DF000001E0, - 0x1E1000001E2, - 0x1E3000001E4, - 0x1E5000001E6, - 0x1E7000001E8, - 0x1E9000001EA, - 0x1EB000001EC, - 0x1ED000001EE, - 0x1EF000001F1, - 0x1F5000001F6, - 0x1F9000001FA, - 0x1FB000001FC, - 0x1FD000001FE, - 0x1FF00000200, - 0x20100000202, - 0x20300000204, - 0x20500000206, - 0x20700000208, - 0x2090000020A, - 0x20B0000020C, - 0x20D0000020E, - 0x20F00000210, - 0x21100000212, - 0x21300000214, - 0x21500000216, - 0x21700000218, - 0x2190000021A, - 0x21B0000021C, - 0x21D0000021E, - 0x21F00000220, - 0x22100000222, - 0x22300000224, - 0x22500000226, - 0x22700000228, - 0x2290000022A, - 0x22B0000022C, - 0x22D0000022E, - 0x22F00000230, - 0x23100000232, - 0x2330000023A, - 0x23C0000023D, - 0x23F00000241, - 0x24200000243, - 0x24700000248, - 0x2490000024A, - 0x24B0000024C, - 0x24D0000024E, - 0x24F000002B0, - 0x2B9000002C2, - 0x2C6000002D2, - 0x2EC000002ED, - 0x2EE000002EF, - 0x30000000340, - 0x34200000343, - 0x3460000034F, - 0x35000000370, - 0x37100000372, - 0x37300000374, - 0x37700000378, - 0x37B0000037E, - 0x39000000391, - 0x3AC000003CF, - 0x3D7000003D8, - 0x3D9000003DA, - 0x3DB000003DC, - 0x3DD000003DE, - 0x3DF000003E0, - 0x3E1000003E2, - 0x3E3000003E4, - 0x3E5000003E6, - 0x3E7000003E8, - 0x3E9000003EA, - 0x3EB000003EC, - 0x3ED000003EE, - 0x3EF000003F0, - 0x3F3000003F4, - 0x3F8000003F9, - 0x3FB000003FD, - 0x43000000460, - 0x46100000462, - 0x46300000464, - 0x46500000466, - 0x46700000468, - 0x4690000046A, - 0x46B0000046C, - 0x46D0000046E, - 0x46F00000470, - 0x47100000472, - 0x47300000474, - 0x47500000476, - 0x47700000478, - 0x4790000047A, - 0x47B0000047C, - 0x47D0000047E, - 0x47F00000480, - 0x48100000482, - 0x48300000488, - 0x48B0000048C, - 0x48D0000048E, - 0x48F00000490, - 0x49100000492, - 0x49300000494, - 0x49500000496, - 0x49700000498, - 0x4990000049A, - 0x49B0000049C, - 0x49D0000049E, - 0x49F000004A0, - 0x4A1000004A2, - 0x4A3000004A4, - 0x4A5000004A6, - 0x4A7000004A8, - 0x4A9000004AA, - 0x4AB000004AC, - 0x4AD000004AE, - 0x4AF000004B0, - 0x4B1000004B2, - 0x4B3000004B4, - 0x4B5000004B6, - 0x4B7000004B8, - 0x4B9000004BA, - 0x4BB000004BC, - 0x4BD000004BE, - 0x4BF000004C0, - 0x4C2000004C3, - 0x4C4000004C5, - 0x4C6000004C7, - 0x4C8000004C9, - 0x4CA000004CB, - 0x4CC000004CD, - 0x4CE000004D0, - 0x4D1000004D2, - 0x4D3000004D4, - 0x4D5000004D6, - 0x4D7000004D8, - 0x4D9000004DA, - 0x4DB000004DC, - 0x4DD000004DE, - 0x4DF000004E0, - 0x4E1000004E2, - 0x4E3000004E4, - 0x4E5000004E6, - 0x4E7000004E8, - 0x4E9000004EA, - 0x4EB000004EC, - 0x4ED000004EE, - 0x4EF000004F0, - 0x4F1000004F2, - 0x4F3000004F4, - 0x4F5000004F6, - 0x4F7000004F8, - 0x4F9000004FA, - 0x4FB000004FC, - 0x4FD000004FE, - 0x4FF00000500, - 0x50100000502, - 0x50300000504, - 0x50500000506, - 0x50700000508, - 0x5090000050A, - 0x50B0000050C, - 0x50D0000050E, - 0x50F00000510, - 0x51100000512, - 0x51300000514, - 0x51500000516, - 0x51700000518, - 0x5190000051A, - 0x51B0000051C, - 0x51D0000051E, - 0x51F00000520, - 0x52100000522, - 0x52300000524, - 0x52500000526, - 0x52700000528, - 0x5290000052A, - 0x52B0000052C, - 0x52D0000052E, - 0x52F00000530, - 0x5590000055A, - 0x56000000587, - 0x58800000589, - 0x591000005BE, - 0x5BF000005C0, - 0x5C1000005C3, - 0x5C4000005C6, - 0x5C7000005CA, - 0x5D0000005EB, - 0x5EF000005F3, - 0x6100000061B, - 0x62000000640, - 0x64100000660, - 0x66E00000675, - 0x679000006D4, - 0x6D5000006DD, - 0x6DF000006E9, - 0x6EA000006F0, - 0x6FA00000700, - 0x7100000074B, - 0x74D000007B2, - 0x7C0000007F6, - 0x7FD000007FE, - 0x8000000082E, - 0x8400000085C, - 0x8600000086B, - 0x87000000888, - 0x88900000890, - 0x897000008E2, - 0x8E300000958, - 0x96000000964, - 0x96600000970, - 0x97100000984, - 0x9850000098D, - 0x98F00000991, - 0x993000009A9, - 0x9AA000009B1, - 0x9B2000009B3, - 0x9B6000009BA, - 0x9BC000009C5, - 0x9C7000009C9, - 0x9CB000009CF, - 0x9D7000009D8, - 0x9E0000009E4, - 0x9E6000009F2, - 0x9FC000009FD, - 0x9FE000009FF, - 0xA0100000A04, - 0xA0500000A0B, - 0xA0F00000A11, - 0xA1300000A29, - 0xA2A00000A31, - 0xA3200000A33, - 0xA3500000A36, - 0xA3800000A3A, - 0xA3C00000A3D, - 0xA3E00000A43, - 0xA4700000A49, - 0xA4B00000A4E, - 0xA5100000A52, - 0xA5C00000A5D, - 0xA6600000A76, - 0xA8100000A84, - 0xA8500000A8E, - 0xA8F00000A92, - 0xA9300000AA9, - 0xAAA00000AB1, - 0xAB200000AB4, - 0xAB500000ABA, - 0xABC00000AC6, - 0xAC700000ACA, - 0xACB00000ACE, - 0xAD000000AD1, - 0xAE000000AE4, - 0xAE600000AF0, - 0xAF900000B00, - 0xB0100000B04, - 0xB0500000B0D, - 0xB0F00000B11, - 0xB1300000B29, - 0xB2A00000B31, - 0xB3200000B34, - 0xB3500000B3A, - 0xB3C00000B45, - 0xB4700000B49, - 0xB4B00000B4E, - 0xB5300000B58, - 0xB5F00000B64, - 0xB6600000B70, - 0xB7100000B72, - 0xB8200000B84, - 0xB8500000B8B, - 0xB8E00000B91, - 0xB9200000B96, - 0xB9900000B9B, - 0xB9C00000B9D, - 0xB9E00000BA0, - 0xBA300000BA5, - 0xBA800000BAB, - 0xBAE00000BBA, - 0xBBE00000BC3, - 0xBC600000BC9, - 0xBCA00000BCE, - 0xBD000000BD1, - 0xBD700000BD8, - 0xBE600000BF0, - 0xC0000000C0D, - 0xC0E00000C11, - 0xC1200000C29, - 0xC2A00000C3A, - 0xC3C00000C45, - 0xC4600000C49, - 0xC4A00000C4E, - 0xC5500000C57, - 0xC5800000C5B, - 0xC5C00000C5E, - 0xC6000000C64, - 0xC6600000C70, - 0xC8000000C84, - 0xC8500000C8D, - 0xC8E00000C91, - 0xC9200000CA9, - 0xCAA00000CB4, - 0xCB500000CBA, - 0xCBC00000CC5, - 0xCC600000CC9, - 0xCCA00000CCE, - 0xCD500000CD7, - 0xCDC00000CDF, - 0xCE000000CE4, - 0xCE600000CF0, - 0xCF100000CF4, - 0xD0000000D0D, - 0xD0E00000D11, - 0xD1200000D45, - 0xD4600000D49, - 0xD4A00000D4F, - 0xD5400000D58, - 0xD5F00000D64, - 0xD6600000D70, - 0xD7A00000D80, - 0xD8100000D84, - 0xD8500000D97, - 0xD9A00000DB2, - 0xDB300000DBC, - 0xDBD00000DBE, - 0xDC000000DC7, - 0xDCA00000DCB, - 0xDCF00000DD5, - 0xDD600000DD7, - 0xDD800000DE0, - 0xDE600000DF0, - 0xDF200000DF4, - 0xE0100000E33, - 0xE3400000E3B, - 0xE4000000E4F, - 0xE5000000E5A, - 0xE8100000E83, - 0xE8400000E85, - 0xE8600000E8B, - 0xE8C00000EA4, - 0xEA500000EA6, - 0xEA700000EB3, - 0xEB400000EBE, - 0xEC000000EC5, - 0xEC600000EC7, - 0xEC800000ECF, - 0xED000000EDA, - 0xEDE00000EE0, - 0xF0000000F01, - 0xF0B00000F0C, - 0xF1800000F1A, - 0xF2000000F2A, - 0xF3500000F36, - 0xF3700000F38, - 0xF3900000F3A, - 0xF3E00000F43, - 0xF4400000F48, - 0xF4900000F4D, - 0xF4E00000F52, - 0xF5300000F57, - 0xF5800000F5C, - 0xF5D00000F69, - 0xF6A00000F6D, - 0xF7100000F73, - 0xF7400000F75, - 0xF7A00000F81, - 0xF8200000F85, - 0xF8600000F93, - 0xF9400000F98, - 0xF9900000F9D, - 0xF9E00000FA2, - 0xFA300000FA7, - 0xFA800000FAC, - 0xFAD00000FB9, - 0xFBA00000FBD, - 0xFC600000FC7, - 0x10000000104A, - 0x10500000109E, - 0x10D0000010FB, - 0x10FD00001100, - 0x120000001249, - 0x124A0000124E, - 0x125000001257, - 0x125800001259, - 0x125A0000125E, - 0x126000001289, - 0x128A0000128E, - 0x1290000012B1, - 0x12B2000012B6, - 0x12B8000012BF, - 0x12C0000012C1, - 0x12C2000012C6, - 0x12C8000012D7, - 0x12D800001311, - 0x131200001316, - 0x13180000135B, - 0x135D00001360, - 0x138000001390, - 0x13A0000013F6, - 0x14010000166D, - 0x166F00001680, - 0x16810000169B, - 0x16A0000016EB, - 0x16F1000016F9, - 0x170000001716, - 0x171F00001735, - 0x174000001754, - 0x17600000176D, - 0x176E00001771, - 0x177200001774, - 0x1780000017B4, - 0x17B6000017D4, - 0x17D7000017D8, - 0x17DC000017DE, - 0x17E0000017EA, - 0x18100000181A, - 0x182000001879, - 0x1880000018AB, - 0x18B0000018F6, - 0x19000000191F, - 0x19200000192C, - 0x19300000193C, - 0x19460000196E, - 0x197000001975, - 0x1980000019AC, - 0x19B0000019CA, - 0x19D0000019DA, - 0x1A0000001A1C, - 0x1A2000001A5F, - 0x1A6000001A7D, - 0x1A7F00001A8A, - 0x1A9000001A9A, - 0x1AA700001AA8, - 0x1AB000001ABE, - 0x1ABF00001AF1, - 0x1B0000001B4D, - 0x1B5000001B5A, - 0x1B6B00001B74, - 0x1B8000001BF4, - 0x1C0000001C38, - 0x1C4000001C4A, - 0x1C4D00001C7E, - 0x1C8A00001C8B, - 0x1CD000001CD3, - 0x1CD400001CFB, - 0x1D0000001D2C, - 0x1D2F00001D30, - 0x1D3B00001D3C, - 0x1D4E00001D4F, - 0x1D6B00001D78, - 0x1D7900001D9B, - 0x1DC000001E00, - 0x1E0100001E02, - 0x1E0300001E04, - 0x1E0500001E06, - 0x1E0700001E08, - 0x1E0900001E0A, - 0x1E0B00001E0C, - 0x1E0D00001E0E, - 0x1E0F00001E10, - 0x1E1100001E12, - 0x1E1300001E14, - 0x1E1500001E16, - 0x1E1700001E18, - 0x1E1900001E1A, - 0x1E1B00001E1C, - 0x1E1D00001E1E, - 0x1E1F00001E20, - 0x1E2100001E22, - 0x1E2300001E24, - 0x1E2500001E26, - 0x1E2700001E28, - 0x1E2900001E2A, - 0x1E2B00001E2C, - 0x1E2D00001E2E, - 0x1E2F00001E30, - 0x1E3100001E32, - 0x1E3300001E34, - 0x1E3500001E36, - 0x1E3700001E38, - 0x1E3900001E3A, - 0x1E3B00001E3C, - 0x1E3D00001E3E, - 0x1E3F00001E40, - 0x1E4100001E42, - 0x1E4300001E44, - 0x1E4500001E46, - 0x1E4700001E48, - 0x1E4900001E4A, - 0x1E4B00001E4C, - 0x1E4D00001E4E, - 0x1E4F00001E50, - 0x1E5100001E52, - 0x1E5300001E54, - 0x1E5500001E56, - 0x1E5700001E58, - 0x1E5900001E5A, - 0x1E5B00001E5C, - 0x1E5D00001E5E, - 0x1E5F00001E60, - 0x1E6100001E62, - 0x1E6300001E64, - 0x1E6500001E66, - 0x1E6700001E68, - 0x1E6900001E6A, - 0x1E6B00001E6C, - 0x1E6D00001E6E, - 0x1E6F00001E70, - 0x1E7100001E72, - 0x1E7300001E74, - 0x1E7500001E76, - 0x1E7700001E78, - 0x1E7900001E7A, - 0x1E7B00001E7C, - 0x1E7D00001E7E, - 0x1E7F00001E80, - 0x1E8100001E82, - 0x1E8300001E84, - 0x1E8500001E86, - 0x1E8700001E88, - 0x1E8900001E8A, - 0x1E8B00001E8C, - 0x1E8D00001E8E, - 0x1E8F00001E90, - 0x1E9100001E92, - 0x1E9300001E94, - 0x1E9500001E9A, - 0x1E9C00001E9E, - 0x1E9F00001EA0, - 0x1EA100001EA2, - 0x1EA300001EA4, - 0x1EA500001EA6, - 0x1EA700001EA8, - 0x1EA900001EAA, - 0x1EAB00001EAC, - 0x1EAD00001EAE, - 0x1EAF00001EB0, - 0x1EB100001EB2, - 0x1EB300001EB4, - 0x1EB500001EB6, - 0x1EB700001EB8, - 0x1EB900001EBA, - 0x1EBB00001EBC, - 0x1EBD00001EBE, - 0x1EBF00001EC0, - 0x1EC100001EC2, - 0x1EC300001EC4, - 0x1EC500001EC6, - 0x1EC700001EC8, - 0x1EC900001ECA, - 0x1ECB00001ECC, - 0x1ECD00001ECE, - 0x1ECF00001ED0, - 0x1ED100001ED2, - 0x1ED300001ED4, - 0x1ED500001ED6, - 0x1ED700001ED8, - 0x1ED900001EDA, - 0x1EDB00001EDC, - 0x1EDD00001EDE, - 0x1EDF00001EE0, - 0x1EE100001EE2, - 0x1EE300001EE4, - 0x1EE500001EE6, - 0x1EE700001EE8, - 0x1EE900001EEA, - 0x1EEB00001EEC, - 0x1EED00001EEE, - 0x1EEF00001EF0, - 0x1EF100001EF2, - 0x1EF300001EF4, - 0x1EF500001EF6, - 0x1EF700001EF8, - 0x1EF900001EFA, - 0x1EFB00001EFC, - 0x1EFD00001EFE, - 0x1EFF00001F08, - 0x1F1000001F16, - 0x1F2000001F28, - 0x1F3000001F38, - 0x1F4000001F46, - 0x1F5000001F58, - 0x1F6000001F68, - 0x1F7000001F71, - 0x1F7200001F73, - 0x1F7400001F75, - 0x1F7600001F77, - 0x1F7800001F79, - 0x1F7A00001F7B, - 0x1F7C00001F7D, - 0x1FB000001FB2, - 0x1FB600001FB7, - 0x1FC600001FC7, - 0x1FD000001FD3, - 0x1FD600001FD8, - 0x1FE000001FE3, - 0x1FE400001FE8, - 0x1FF600001FF7, - 0x208F00002090, - 0x214E0000214F, - 0x218400002185, - 0x2C3000002C60, - 0x2C6100002C62, - 0x2C6500002C67, - 0x2C6800002C69, - 0x2C6A00002C6B, - 0x2C6C00002C6D, - 0x2C7100002C72, - 0x2C7300002C75, - 0x2C7600002C7C, - 0x2C8100002C82, - 0x2C8300002C84, - 0x2C8500002C86, - 0x2C8700002C88, - 0x2C8900002C8A, - 0x2C8B00002C8C, - 0x2C8D00002C8E, - 0x2C8F00002C90, - 0x2C9100002C92, - 0x2C9300002C94, - 0x2C9500002C96, - 0x2C9700002C98, - 0x2C9900002C9A, - 0x2C9B00002C9C, - 0x2C9D00002C9E, - 0x2C9F00002CA0, - 0x2CA100002CA2, - 0x2CA300002CA4, - 0x2CA500002CA6, - 0x2CA700002CA8, - 0x2CA900002CAA, - 0x2CAB00002CAC, - 0x2CAD00002CAE, - 0x2CAF00002CB0, - 0x2CB100002CB2, - 0x2CB300002CB4, - 0x2CB500002CB6, - 0x2CB700002CB8, - 0x2CB900002CBA, - 0x2CBB00002CBC, - 0x2CBD00002CBE, - 0x2CBF00002CC0, - 0x2CC100002CC2, - 0x2CC300002CC4, - 0x2CC500002CC6, - 0x2CC700002CC8, - 0x2CC900002CCA, - 0x2CCB00002CCC, - 0x2CCD00002CCE, - 0x2CCF00002CD0, - 0x2CD100002CD2, - 0x2CD300002CD4, - 0x2CD500002CD6, - 0x2CD700002CD8, - 0x2CD900002CDA, - 0x2CDB00002CDC, - 0x2CDD00002CDE, - 0x2CDF00002CE0, - 0x2CE100002CE2, - 0x2CE300002CE5, - 0x2CEC00002CED, - 0x2CEE00002CF2, - 0x2CF300002CF4, - 0x2D0000002D26, - 0x2D2700002D28, - 0x2D2D00002D2E, - 0x2D3000002D68, - 0x2D7F00002D97, - 0x2DA000002DA7, - 0x2DA800002DAF, - 0x2DB000002DB7, - 0x2DB800002DBF, - 0x2DC000002DC7, - 0x2DC800002DCF, - 0x2DD000002DD7, - 0x2DD800002DDF, - 0x2DE000002E00, - 0x2E2F00002E30, - 0x300500003008, - 0x302A0000302E, - 0x303C0000303D, - 0x304100003097, - 0x30990000309B, - 0x309D0000309F, - 0x30A1000030FB, - 0x30FC000030FF, - 0x310500003130, - 0x31A0000031C0, - 0x31F000003200, - 0x340000004DC0, - 0x4E000000A48D, - 0xA4D00000A4FE, - 0xA5000000A60D, - 0xA6100000A62C, - 0xA6410000A642, - 0xA6430000A644, - 0xA6450000A646, - 0xA6470000A648, - 0xA6490000A64A, - 0xA64B0000A64C, - 0xA64D0000A64E, - 0xA64F0000A650, - 0xA6510000A652, - 0xA6530000A654, - 0xA6550000A656, - 0xA6570000A658, - 0xA6590000A65A, - 0xA65B0000A65C, - 0xA65D0000A65E, - 0xA65F0000A660, - 0xA6610000A662, - 0xA6630000A664, - 0xA6650000A666, - 0xA6670000A668, - 0xA6690000A66A, - 0xA66B0000A66C, - 0xA66D0000A670, - 0xA6740000A67E, - 0xA67F0000A680, - 0xA6810000A682, - 0xA6830000A684, - 0xA6850000A686, - 0xA6870000A688, - 0xA6890000A68A, - 0xA68B0000A68C, - 0xA68D0000A68E, - 0xA68F0000A690, - 0xA6910000A692, - 0xA6930000A694, - 0xA6950000A696, - 0xA6970000A698, - 0xA6990000A69A, - 0xA69B0000A69C, - 0xA69E0000A6E6, - 0xA6F00000A6F2, - 0xA7170000A720, - 0xA7230000A724, - 0xA7250000A726, - 0xA7270000A728, - 0xA7290000A72A, - 0xA72B0000A72C, - 0xA72D0000A72E, - 0xA72F0000A732, - 0xA7330000A734, - 0xA7350000A736, - 0xA7370000A738, - 0xA7390000A73A, - 0xA73B0000A73C, - 0xA73D0000A73E, - 0xA73F0000A740, - 0xA7410000A742, - 0xA7430000A744, - 0xA7450000A746, - 0xA7470000A748, - 0xA7490000A74A, - 0xA74B0000A74C, - 0xA74D0000A74E, - 0xA74F0000A750, - 0xA7510000A752, - 0xA7530000A754, - 0xA7550000A756, - 0xA7570000A758, - 0xA7590000A75A, - 0xA75B0000A75C, - 0xA75D0000A75E, - 0xA75F0000A760, - 0xA7610000A762, - 0xA7630000A764, - 0xA7650000A766, - 0xA7670000A768, - 0xA7690000A76A, - 0xA76B0000A76C, - 0xA76D0000A76E, - 0xA76F0000A770, - 0xA7710000A779, - 0xA77A0000A77B, - 0xA77C0000A77D, - 0xA77F0000A780, - 0xA7810000A782, - 0xA7830000A784, - 0xA7850000A786, - 0xA7870000A789, - 0xA78C0000A78D, - 0xA78E0000A790, - 0xA7910000A792, - 0xA7930000A796, - 0xA7970000A798, - 0xA7990000A79A, - 0xA79B0000A79C, - 0xA79D0000A79E, - 0xA79F0000A7A0, - 0xA7A10000A7A2, - 0xA7A30000A7A4, - 0xA7A50000A7A6, - 0xA7A70000A7A8, - 0xA7A90000A7AA, - 0xA7AF0000A7B0, - 0xA7B50000A7B6, - 0xA7B70000A7B8, - 0xA7B90000A7BA, - 0xA7BB0000A7BC, - 0xA7BD0000A7BE, - 0xA7BF0000A7C0, - 0xA7C10000A7C2, - 0xA7C30000A7C4, - 0xA7C80000A7C9, - 0xA7CA0000A7CB, - 0xA7CD0000A7CE, - 0xA7CF0000A7D0, - 0xA7D10000A7D2, - 0xA7D30000A7D4, - 0xA7D50000A7D6, - 0xA7D70000A7D8, - 0xA7D90000A7DA, - 0xA7DB0000A7DC, - 0xA7F60000A7F8, - 0xA7FA0000A828, - 0xA82C0000A82D, - 0xA8400000A874, - 0xA8800000A8C6, - 0xA8D00000A8DA, - 0xA8E00000A8F8, - 0xA8FB0000A8FC, - 0xA8FD0000A92E, - 0xA9300000A954, - 0xA9800000A9C1, - 0xA9CF0000A9DA, - 0xA9E00000A9FF, - 0xAA000000AA37, - 0xAA400000AA4E, - 0xAA500000AA5A, - 0xAA600000AA77, - 0xAA7A0000AAC3, - 0xAADB0000AADE, - 0xAAE00000AAF0, - 0xAAF20000AAF7, - 0xAB010000AB07, - 0xAB090000AB0F, - 0xAB110000AB17, - 0xAB200000AB27, - 0xAB280000AB2F, - 0xAB300000AB5B, - 0xAB600000AB69, - 0xABC00000ABEB, - 0xABEC0000ABEE, - 0xABF00000ABFA, - 0xAC000000D7A4, - 0xFA0E0000FA10, - 0xFA110000FA12, - 0xFA130000FA15, - 0xFA1F0000FA20, - 0xFA210000FA22, - 0xFA230000FA25, - 0xFA270000FA2A, - 0xFB1E0000FB1F, - 0xFE200000FE30, - 0xFE730000FE74, - 0x100000001000C, - 0x1000D00010027, - 0x100280001003B, - 0x1003C0001003E, - 0x1003F0001004E, - 0x100500001005E, - 0x10080000100FB, - 0x101FD000101FE, - 0x102800001029D, - 0x102A0000102D1, - 0x102E0000102E1, - 0x1030000010320, - 0x1032D00010341, - 0x103420001034A, - 0x103500001037B, - 0x103800001039E, - 0x103A0000103C4, - 0x103C8000103D0, - 0x104280001049E, - 0x104A0000104AA, - 0x104D8000104FC, - 0x1050000010528, - 0x1053000010564, - 0x10597000105A2, - 0x105A3000105B2, - 0x105B3000105BA, - 0x105BB000105BD, - 0x105C0000105F4, - 0x1060000010737, - 0x1074000010756, - 0x1076000010768, - 0x1078000010781, - 0x1080000010806, - 0x1080800010809, - 0x1080A00010836, - 0x1083700010839, - 0x1083C0001083D, - 0x1083F00010856, - 0x1086000010877, - 0x108800001089F, - 0x108E0000108F3, - 0x108F4000108F6, - 0x1090000010916, - 0x109200001093A, - 0x109400001095A, - 0x10980000109B8, - 0x109BE000109C0, - 0x10A0000010A04, - 0x10A0500010A07, - 0x10A0C00010A14, - 0x10A1500010A18, - 0x10A1900010A36, - 0x10A3800010A3B, - 0x10A3F00010A40, - 0x10A6000010A7D, - 0x10A8000010A9D, - 0x10AC000010AC8, - 0x10AC900010AE7, - 0x10B0000010B36, - 0x10B4000010B56, - 0x10B6000010B73, - 0x10B8000010B92, - 0x10C0000010C49, - 0x10CC000010CF3, - 0x10D0000010D28, - 0x10D3000010D3A, - 0x10D4000010D50, - 0x10D6900010D6E, - 0x10D6F00010D86, - 0x10E8000010EAA, - 0x10EAB00010EAD, - 0x10EB000010EB2, - 0x10EC200010EC8, - 0x10ECB00010ED0, - 0x10ED900010EEF, - 0x10EF000010F1D, - 0x10F2700010F28, - 0x10F3000010F51, - 0x10F7000010F86, - 0x10FB000010FC5, - 0x10FE000010FF7, - 0x1100000011047, - 0x1106600011076, - 0x1107F000110BB, - 0x110C2000110C3, - 0x110D0000110E9, - 0x110F0000110FA, - 0x1110000011135, - 0x1113600011140, - 0x1114400011148, - 0x1115000011174, - 0x1117600011177, - 0x11180000111C5, - 0x111C9000111CD, - 0x111CE000111DB, - 0x111DC000111DD, - 0x1120000011212, - 0x1121300011238, - 0x1123E00011242, - 0x1128000011287, - 0x1128800011289, - 0x1128A0001128E, - 0x1128F0001129E, - 0x1129F000112A9, - 0x112B0000112EB, - 0x112F0000112FA, - 0x1130000011304, - 0x113050001130D, - 0x1130F00011311, - 0x1131300011329, - 0x1132A00011331, - 0x1133200011334, - 0x113350001133A, - 0x1133B00011345, - 0x1134700011349, - 0x1134B0001134E, - 0x1135000011351, - 0x1135700011358, - 0x1135D00011364, - 0x113660001136D, - 0x1137000011375, - 0x113800001138A, - 0x1138B0001138C, - 0x1138E0001138F, - 0x11390000113B6, - 0x113B7000113C1, - 0x113C2000113C3, - 0x113C5000113C6, - 0x113C7000113CB, - 0x113CC000113D4, - 0x113E1000113E3, - 0x114000001144B, - 0x114500001145A, - 0x1145E00011462, - 0x11480000114C6, - 0x114C7000114C8, - 0x114D0000114DA, - 0x11580000115B6, - 0x115B8000115C1, - 0x115D8000115DE, - 0x1160000011641, - 0x1164400011645, - 0x116500001165A, - 0x11680000116B9, - 0x116C0000116CA, - 0x116D0000116E4, - 0x117000001171B, - 0x1171D0001172C, - 0x117300001173A, - 0x1174000011747, - 0x118000001183B, - 0x118C0000118EA, - 0x118FF00011907, - 0x119090001190A, - 0x1190C00011914, - 0x1191500011917, - 0x1191800011936, - 0x1193700011939, - 0x1193B00011944, - 0x119500001195A, - 0x119A0000119A8, - 0x119AA000119D8, - 0x119DA000119E2, - 0x119E3000119E5, - 0x11A0000011A3F, - 0x11A4700011A48, - 0x11A5000011A9A, - 0x11A9D00011A9E, - 0x11AB000011AF9, - 0x11B0A00011B0B, - 0x11B6000011B68, - 0x11BC000011BE1, - 0x11BF000011BFA, - 0x11C0000011C09, - 0x11C0A00011C37, - 0x11C3800011C41, - 0x11C5000011C5A, - 0x11C7200011C90, - 0x11C9200011CA8, - 0x11CA900011CB7, - 0x11D0000011D07, - 0x11D0800011D0A, - 0x11D0B00011D37, - 0x11D3A00011D3B, - 0x11D3C00011D3E, - 0x11D3F00011D48, - 0x11D5000011D5A, - 0x11D6000011D66, - 0x11D6700011D69, - 0x11D6A00011D8F, - 0x11D9000011D92, - 0x11D9300011D99, - 0x11DA000011DAA, - 0x11DB000011DDC, - 0x11DE000011DEA, - 0x11DF000011DF2, - 0x11EE000011EF7, - 0x11F0000011F11, - 0x11F1200011F3B, - 0x11F3E00011F43, - 0x11F5000011F5B, - 0x11FB000011FB1, - 0x120000001239A, - 0x1248000012544, - 0x12F9000012FF1, - 0x1300000013430, - 0x1344000013456, - 0x13460000143FB, - 0x1440000014647, - 0x161000001613A, - 0x1680000016A39, - 0x16A4000016A5F, - 0x16A6000016A6A, - 0x16A7000016ABF, - 0x16AC000016ACA, - 0x16AD000016AEE, - 0x16AF000016AF5, - 0x16B0000016B37, - 0x16B4000016B44, - 0x16B5000016B5A, - 0x16B6300016B78, - 0x16B7D00016B90, - 0x16D4000016D6D, - 0x16D7000016D7A, - 0x16E6000016E80, - 0x16EBB00016ED4, - 0x16F0000016F4B, - 0x16F4F00016F88, - 0x16F8F00016FA0, - 0x16FE000016FE2, - 0x16FE300016FE5, - 0x16FF000016FF4, - 0x1700000018CDB, - 0x18CFF00018D21, - 0x18D8000018DF3, - 0x18E0000019192, - 0x191A0000191D3, - 0x1AFF00001AFF4, - 0x1AFF50001AFFC, - 0x1AFFD0001AFFF, - 0x1B0000001B123, - 0x1B1270001B129, - 0x1B1320001B133, - 0x1B1500001B153, - 0x1B1550001B156, - 0x1B1640001B169, - 0x1B1700001B2FC, - 0x1BC000001BC6B, - 0x1BC700001BC7D, - 0x1BC800001BC89, - 0x1BC900001BC9A, - 0x1BC9D0001BC9F, - 0x1CF000001CF2E, - 0x1CF300001CF47, - 0x1D2500001D253, - 0x1D25B0001D25D, - 0x1D25F0001D260, - 0x1D2800001D282, - 0x1DA000001DA37, - 0x1DA3B0001DA6D, - 0x1DA750001DA76, - 0x1DA840001DA85, - 0x1DA9B0001DAA0, - 0x1DAA10001DAB0, - 0x1DF000001DF40, - 0x1DF410001DF48, - 0x1DF490001DF4A, - 0x1DF4B0001DF4D, - 0x1DF4E0001DF51, - 0x1DF520001DF68, - 0x1DF690001DF6A, - 0x1DF6B0001DF6C, - 0x1DF6D0001DF6E, - 0x1DF6F0001DF72, - 0x1DF730001DF74, - 0x1DF750001DF76, - 0x1DF770001DF78, - 0x1DF790001DF7A, - 0x1DF7B0001DF7C, - 0x1DF7D0001DF7E, - 0x1DF7F0001DF82, - 0x1DF900001DF95, - 0x1DF960001DF97, - 0x1E0000001E007, - 0x1E0080001E019, - 0x1E01B0001E022, - 0x1E0230001E025, - 0x1E0260001E02B, - 0x1E08F0001E090, - 0x1E1000001E12D, - 0x1E1300001E13E, - 0x1E1400001E14A, - 0x1E14E0001E14F, - 0x1E2900001E2AF, - 0x1E2C00001E2FA, - 0x1E4D00001E4FA, - 0x1E5D00001E5FB, - 0x1E6C00001E6DF, - 0x1E6E00001E6F6, - 0x1E6FE0001E700, - 0x1E7E00001E7E7, - 0x1E7E80001E7EC, - 0x1E7ED0001E7EF, - 0x1E7F00001E7FF, - 0x1E8000001E8C5, - 0x1E8D00001E8D7, - 0x1E9220001E94C, - 0x1E9500001E95A, - 0x200000002A6E0, - 0x2A7000002B81F, - 0x2B8200002CEAE, - 0x2CEB00002EBE1, - 0x2EBF00002EE5E, - 0x300000003134B, - 0x313500003347A, - 0x3D0000003FC40, - ), - "CONTEXTJ": (0x200C0000200E,), - "CONTEXTO": ( - 0xB7000000B8, - 0x37500000376, - 0x5F3000005F5, - 0x6600000066A, - 0x6F0000006FA, - 0x30FB000030FC, - ), -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py deleted file mode 100644 index 19d77810caf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/intranges.py +++ /dev/null @@ -1,55 +0,0 @@ -""" -Given a list of integers, made up of (hopefully) a small number of long runs -of consecutive integers, compute a representation of the form -((start1, end1), (start2, end2) ...). Then answer the question "was x present -in the original list?" in time O(log(# runs)). -""" - -import bisect - - -def intranges_from_list(list_: list[int]) -> tuple[int, ...]: - """Represent a list of integers as a sequence of ranges: - ((start_0, end_0), (start_1, end_1), ...), such that the original - integers are exactly those x such that start_i <= x < end_i for some i. - - Ranges are encoded as single integers (start << 32 | end), not as tuples. - """ - - sorted_list = sorted(list_) - ranges = [] - last_write = -1 - for i in range(len(sorted_list)): - if i + 1 < len(sorted_list) and sorted_list[i] == sorted_list[i + 1] - 1: - continue - current_range = sorted_list[last_write + 1 : i + 1] - ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) - last_write = i - - return tuple(ranges) - - -def _encode_range(start: int, end: int) -> int: - return (start << 32) | end - - -def _decode_range(r: int) -> tuple[int, int]: - return (r >> 32), (r & ((1 << 32) - 1)) - - -def intranges_contain(int_: int, ranges: tuple[int, ...]) -> bool: - """Determine if `int_` falls into one of the ranges in `ranges`.""" - tuple_ = _encode_range(int_, 0) - pos = bisect.bisect_left(ranges, tuple_) - # we could be immediately ahead of a tuple (start, end) - # with start < int_ <= end - if pos > 0: - left, right = _decode_range(ranges[pos - 1]) - if left <= int_ < right: - return True - # or we could be immediately behind a tuple (int_, end) - if pos < len(ranges): - left, _ = _decode_range(ranges[pos]) - if left == int_: - return True - return False diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py deleted file mode 100644 index 2f9ff7e825c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/package_data.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "3.20" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py deleted file mode 100644 index dbfb60ff4b3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/idna/uts46data.py +++ /dev/null @@ -1,17117 +0,0 @@ -# This file is automatically generated by tools/idna-data - -from __future__ import annotations - -from array import array - -"""IDNA Mapping Table from UTS46.""" - - -__version__ = "18.0.0" - -uts46_starts: array[int] = array( - "I", - ( - 0x0, - 0x1, - 0x2, - 0x3, - 0x4, - 0x5, - 0x6, - 0x7, - 0x8, - 0x9, - 0xA, - 0xB, - 0xC, - 0xD, - 0xE, - 0xF, - 0x10, - 0x11, - 0x12, - 0x13, - 0x14, - 0x15, - 0x16, - 0x17, - 0x18, - 0x19, - 0x1A, - 0x1B, - 0x1C, - 0x1D, - 0x1E, - 0x1F, - 0x20, - 0x21, - 0x22, - 0x23, - 0x24, - 0x25, - 0x26, - 0x27, - 0x28, - 0x29, - 0x2A, - 0x2B, - 0x2C, - 0x2D, - 0x2E, - 0x2F, - 0x30, - 0x31, - 0x32, - 0x33, - 0x34, - 0x35, - 0x36, - 0x37, - 0x38, - 0x39, - 0x3A, - 0x3B, - 0x3C, - 0x3D, - 0x3E, - 0x3F, - 0x40, - 0x41, - 0x42, - 0x43, - 0x44, - 0x45, - 0x46, - 0x47, - 0x48, - 0x49, - 0x4A, - 0x4B, - 0x4C, - 0x4D, - 0x4E, - 0x4F, - 0x50, - 0x51, - 0x52, - 0x53, - 0x54, - 0x55, - 0x56, - 0x57, - 0x58, - 0x59, - 0x5A, - 0x5B, - 0x5C, - 0x5D, - 0x5E, - 0x5F, - 0x60, - 0x61, - 0x62, - 0x63, - 0x64, - 0x65, - 0x66, - 0x67, - 0x68, - 0x69, - 0x6A, - 0x6B, - 0x6C, - 0x6D, - 0x6E, - 0x6F, - 0x70, - 0x71, - 0x72, - 0x73, - 0x74, - 0x75, - 0x76, - 0x77, - 0x78, - 0x79, - 0x7A, - 0x7B, - 0x7C, - 0x7D, - 0x7E, - 0x7F, - 0x80, - 0x81, - 0x82, - 0x83, - 0x84, - 0x85, - 0x86, - 0x87, - 0x88, - 0x89, - 0x8A, - 0x8B, - 0x8C, - 0x8D, - 0x8E, - 0x8F, - 0x90, - 0x91, - 0x92, - 0x93, - 0x94, - 0x95, - 0x96, - 0x97, - 0x98, - 0x99, - 0x9A, - 0x9B, - 0x9C, - 0x9D, - 0x9E, - 0x9F, - 0xA0, - 0xA1, - 0xA2, - 0xA3, - 0xA4, - 0xA5, - 0xA6, - 0xA7, - 0xA8, - 0xA9, - 0xAA, - 0xAB, - 0xAC, - 0xAD, - 0xAE, - 0xAF, - 0xB0, - 0xB1, - 0xB2, - 0xB3, - 0xB4, - 0xB5, - 0xB6, - 0xB7, - 0xB8, - 0xB9, - 0xBA, - 0xBB, - 0xBC, - 0xBD, - 0xBE, - 0xBF, - 0xC0, - 0xC1, - 0xC2, - 0xC3, - 0xC4, - 0xC5, - 0xC6, - 0xC7, - 0xC8, - 0xC9, - 0xCA, - 0xCB, - 0xCC, - 0xCD, - 0xCE, - 0xCF, - 0xD0, - 0xD1, - 0xD2, - 0xD3, - 0xD4, - 0xD5, - 0xD6, - 0xD7, - 0xD8, - 0xD9, - 0xDA, - 0xDB, - 0xDC, - 0xDD, - 0xDE, - 0xDF, - 0xE0, - 0xE1, - 0xE2, - 0xE3, - 0xE4, - 0xE5, - 0xE6, - 0xE7, - 0xE8, - 0xE9, - 0xEA, - 0xEB, - 0xEC, - 0xED, - 0xEE, - 0xEF, - 0xF0, - 0xF1, - 0xF2, - 0xF3, - 0xF4, - 0xF5, - 0xF6, - 0xF7, - 0xF8, - 0xF9, - 0xFA, - 0xFB, - 0xFC, - 0xFD, - 0xFE, - 0xFF, - 0x100, - 0x101, - 0x102, - 0x103, - 0x104, - 0x105, - 0x106, - 0x107, - 0x108, - 0x109, - 0x10A, - 0x10B, - 0x10C, - 0x10D, - 0x10E, - 0x10F, - 0x110, - 0x111, - 0x112, - 0x113, - 0x114, - 0x115, - 0x116, - 0x117, - 0x118, - 0x119, - 0x11A, - 0x11B, - 0x11C, - 0x11D, - 0x11E, - 0x11F, - 0x120, - 0x121, - 0x122, - 0x123, - 0x124, - 0x125, - 0x126, - 0x127, - 0x128, - 0x129, - 0x12A, - 0x12B, - 0x12C, - 0x12D, - 0x12E, - 0x12F, - 0x130, - 0x131, - 0x132, - 0x134, - 0x135, - 0x136, - 0x137, - 0x139, - 0x13A, - 0x13B, - 0x13C, - 0x13D, - 0x13E, - 0x13F, - 0x141, - 0x142, - 0x143, - 0x144, - 0x145, - 0x146, - 0x147, - 0x148, - 0x149, - 0x14A, - 0x14B, - 0x14C, - 0x14D, - 0x14E, - 0x14F, - 0x150, - 0x151, - 0x152, - 0x153, - 0x154, - 0x155, - 0x156, - 0x157, - 0x158, - 0x159, - 0x15A, - 0x15B, - 0x15C, - 0x15D, - 0x15E, - 0x15F, - 0x160, - 0x161, - 0x162, - 0x163, - 0x164, - 0x165, - 0x166, - 0x167, - 0x168, - 0x169, - 0x16A, - 0x16B, - 0x16C, - 0x16D, - 0x16E, - 0x16F, - 0x170, - 0x171, - 0x172, - 0x173, - 0x174, - 0x175, - 0x176, - 0x177, - 0x178, - 0x179, - 0x17A, - 0x17B, - 0x17C, - 0x17D, - 0x17E, - 0x17F, - 0x180, - 0x181, - 0x182, - 0x183, - 0x184, - 0x185, - 0x186, - 0x187, - 0x188, - 0x189, - 0x18A, - 0x18B, - 0x18C, - 0x18E, - 0x18F, - 0x190, - 0x191, - 0x192, - 0x193, - 0x194, - 0x195, - 0x196, - 0x197, - 0x198, - 0x199, - 0x19C, - 0x19D, - 0x19E, - 0x19F, - 0x1A0, - 0x1A1, - 0x1A2, - 0x1A3, - 0x1A4, - 0x1A5, - 0x1A6, - 0x1A7, - 0x1A8, - 0x1A9, - 0x1AA, - 0x1AC, - 0x1AD, - 0x1AE, - 0x1AF, - 0x1B0, - 0x1B1, - 0x1B2, - 0x1B3, - 0x1B4, - 0x1B5, - 0x1B6, - 0x1B7, - 0x1B8, - 0x1B9, - 0x1BC, - 0x1BD, - 0x1C4, - 0x1C7, - 0x1CA, - 0x1CD, - 0x1CE, - 0x1CF, - 0x1D0, - 0x1D1, - 0x1D2, - 0x1D3, - 0x1D4, - 0x1D5, - 0x1D6, - 0x1D7, - 0x1D8, - 0x1D9, - 0x1DA, - 0x1DB, - 0x1DC, - 0x1DE, - 0x1DF, - 0x1E0, - 0x1E1, - 0x1E2, - 0x1E3, - 0x1E4, - 0x1E5, - 0x1E6, - 0x1E7, - 0x1E8, - 0x1E9, - 0x1EA, - 0x1EB, - 0x1EC, - 0x1ED, - 0x1EE, - 0x1EF, - 0x1F1, - 0x1F4, - 0x1F5, - 0x1F6, - 0x1F7, - 0x1F8, - 0x1F9, - 0x1FA, - 0x1FB, - 0x1FC, - 0x1FD, - 0x1FE, - 0x1FF, - 0x200, - 0x201, - 0x202, - 0x203, - 0x204, - 0x205, - 0x206, - 0x207, - 0x208, - 0x209, - 0x20A, - 0x20B, - 0x20C, - 0x20D, - 0x20E, - 0x20F, - 0x210, - 0x211, - 0x212, - 0x213, - 0x214, - 0x215, - 0x216, - 0x217, - 0x218, - 0x219, - 0x21A, - 0x21B, - 0x21C, - 0x21D, - 0x21E, - 0x21F, - 0x220, - 0x221, - 0x222, - 0x223, - 0x224, - 0x225, - 0x226, - 0x227, - 0x228, - 0x229, - 0x22A, - 0x22B, - 0x22C, - 0x22D, - 0x22E, - 0x22F, - 0x230, - 0x231, - 0x232, - 0x233, - 0x23A, - 0x23B, - 0x23C, - 0x23D, - 0x23E, - 0x23F, - 0x241, - 0x242, - 0x243, - 0x244, - 0x245, - 0x246, - 0x247, - 0x248, - 0x249, - 0x24A, - 0x24B, - 0x24C, - 0x24D, - 0x24E, - 0x24F, - 0x2B0, - 0x2B1, - 0x2B2, - 0x2B3, - 0x2B4, - 0x2B5, - 0x2B6, - 0x2B7, - 0x2B8, - 0x2B9, - 0x2D8, - 0x2D9, - 0x2DA, - 0x2DB, - 0x2DC, - 0x2DD, - 0x2DE, - 0x2E0, - 0x2E1, - 0x2E2, - 0x2E3, - 0x2E4, - 0x2E5, - 0x340, - 0x341, - 0x342, - 0x343, - 0x344, - 0x345, - 0x346, - 0x34F, - 0x350, - 0x370, - 0x371, - 0x372, - 0x373, - 0x374, - 0x375, - 0x376, - 0x377, - 0x378, - 0x37A, - 0x37B, - 0x37E, - 0x37F, - 0x380, - 0x384, - 0x385, - 0x386, - 0x387, - 0x388, - 0x389, - 0x38A, - 0x38B, - 0x38C, - 0x38D, - 0x38E, - 0x38F, - 0x390, - 0x391, - 0x392, - 0x393, - 0x394, - 0x395, - 0x396, - 0x397, - 0x398, - 0x399, - 0x39A, - 0x39B, - 0x39C, - 0x39D, - 0x39E, - 0x39F, - 0x3A0, - 0x3A1, - 0x3A2, - 0x3A3, - 0x3A4, - 0x3A5, - 0x3A6, - 0x3A7, - 0x3A8, - 0x3A9, - 0x3AA, - 0x3AB, - 0x3AC, - 0x3C2, - 0x3C3, - 0x3CF, - 0x3D0, - 0x3D1, - 0x3D2, - 0x3D3, - 0x3D4, - 0x3D5, - 0x3D6, - 0x3D7, - 0x3D8, - 0x3D9, - 0x3DA, - 0x3DB, - 0x3DC, - 0x3DD, - 0x3DE, - 0x3DF, - 0x3E0, - 0x3E1, - 0x3E2, - 0x3E3, - 0x3E4, - 0x3E5, - 0x3E6, - 0x3E7, - 0x3E8, - 0x3E9, - 0x3EA, - 0x3EB, - 0x3EC, - 0x3ED, - 0x3EE, - 0x3EF, - 0x3F0, - 0x3F1, - 0x3F2, - 0x3F3, - 0x3F4, - 0x3F5, - 0x3F6, - 0x3F7, - 0x3F8, - 0x3F9, - 0x3FA, - 0x3FB, - 0x3FD, - 0x3FE, - 0x3FF, - 0x400, - 0x401, - 0x402, - 0x403, - 0x404, - 0x405, - 0x406, - 0x407, - 0x408, - 0x409, - 0x40A, - 0x40B, - 0x40C, - 0x40D, - 0x40E, - 0x40F, - 0x410, - 0x411, - 0x412, - 0x413, - 0x414, - 0x415, - 0x416, - 0x417, - 0x418, - 0x419, - 0x41A, - 0x41B, - 0x41C, - 0x41D, - 0x41E, - 0x41F, - 0x420, - 0x421, - 0x422, - 0x423, - 0x424, - 0x425, - 0x426, - 0x427, - 0x428, - 0x429, - 0x42A, - 0x42B, - 0x42C, - 0x42D, - 0x42E, - 0x42F, - 0x430, - 0x460, - 0x461, - 0x462, - 0x463, - 0x464, - 0x465, - 0x466, - 0x467, - 0x468, - 0x469, - 0x46A, - 0x46B, - 0x46C, - 0x46D, - 0x46E, - 0x46F, - 0x470, - 0x471, - 0x472, - 0x473, - 0x474, - 0x475, - 0x476, - 0x477, - 0x478, - 0x479, - 0x47A, - 0x47B, - 0x47C, - 0x47D, - 0x47E, - 0x47F, - 0x480, - 0x481, - 0x48A, - 0x48B, - 0x48C, - 0x48D, - 0x48E, - 0x48F, - 0x490, - 0x491, - 0x492, - 0x493, - 0x494, - 0x495, - 0x496, - 0x497, - 0x498, - 0x499, - 0x49A, - 0x49B, - 0x49C, - 0x49D, - 0x49E, - 0x49F, - 0x4A0, - 0x4A1, - 0x4A2, - 0x4A3, - 0x4A4, - 0x4A5, - 0x4A6, - 0x4A7, - 0x4A8, - 0x4A9, - 0x4AA, - 0x4AB, - 0x4AC, - 0x4AD, - 0x4AE, - 0x4AF, - 0x4B0, - 0x4B1, - 0x4B2, - 0x4B3, - 0x4B4, - 0x4B5, - 0x4B6, - 0x4B7, - 0x4B8, - 0x4B9, - 0x4BA, - 0x4BB, - 0x4BC, - 0x4BD, - 0x4BE, - 0x4BF, - 0x4C0, - 0x4C1, - 0x4C2, - 0x4C3, - 0x4C4, - 0x4C5, - 0x4C6, - 0x4C7, - 0x4C8, - 0x4C9, - 0x4CA, - 0x4CB, - 0x4CC, - 0x4CD, - 0x4CE, - 0x4D0, - 0x4D1, - 0x4D2, - 0x4D3, - 0x4D4, - 0x4D5, - 0x4D6, - 0x4D7, - 0x4D8, - 0x4D9, - 0x4DA, - 0x4DB, - 0x4DC, - 0x4DD, - 0x4DE, - 0x4DF, - 0x4E0, - 0x4E1, - 0x4E2, - 0x4E3, - 0x4E4, - 0x4E5, - 0x4E6, - 0x4E7, - 0x4E8, - 0x4E9, - 0x4EA, - 0x4EB, - 0x4EC, - 0x4ED, - 0x4EE, - 0x4EF, - 0x4F0, - 0x4F1, - 0x4F2, - 0x4F3, - 0x4F4, - 0x4F5, - 0x4F6, - 0x4F7, - 0x4F8, - 0x4F9, - 0x4FA, - 0x4FB, - 0x4FC, - 0x4FD, - 0x4FE, - 0x4FF, - 0x500, - 0x501, - 0x502, - 0x503, - 0x504, - 0x505, - 0x506, - 0x507, - 0x508, - 0x509, - 0x50A, - 0x50B, - 0x50C, - 0x50D, - 0x50E, - 0x50F, - 0x510, - 0x511, - 0x512, - 0x513, - 0x514, - 0x515, - 0x516, - 0x517, - 0x518, - 0x519, - 0x51A, - 0x51B, - 0x51C, - 0x51D, - 0x51E, - 0x51F, - 0x520, - 0x521, - 0x522, - 0x523, - 0x524, - 0x525, - 0x526, - 0x527, - 0x528, - 0x529, - 0x52A, - 0x52B, - 0x52C, - 0x52D, - 0x52E, - 0x52F, - 0x530, - 0x531, - 0x532, - 0x533, - 0x534, - 0x535, - 0x536, - 0x537, - 0x538, - 0x539, - 0x53A, - 0x53B, - 0x53C, - 0x53D, - 0x53E, - 0x53F, - 0x540, - 0x541, - 0x542, - 0x543, - 0x544, - 0x545, - 0x546, - 0x547, - 0x548, - 0x549, - 0x54A, - 0x54B, - 0x54C, - 0x54D, - 0x54E, - 0x54F, - 0x550, - 0x551, - 0x552, - 0x553, - 0x554, - 0x555, - 0x556, - 0x557, - 0x558, - 0x559, - 0x587, - 0x588, - 0x58B, - 0x58C, - 0x58D, - 0x590, - 0x591, - 0x5CA, - 0x5D0, - 0x5EB, - 0x5EF, - 0x5F5, - 0x606, - 0x61C, - 0x61D, - 0x675, - 0x676, - 0x677, - 0x678, - 0x679, - 0x6DD, - 0x6DE, - 0x70E, - 0x710, - 0x74B, - 0x74D, - 0x7B2, - 0x7C0, - 0x7FB, - 0x7FD, - 0x82E, - 0x830, - 0x83F, - 0x840, - 0x85C, - 0x85E, - 0x85F, - 0x860, - 0x86B, - 0x870, - 0x890, - 0x897, - 0x8E2, - 0x8E3, - 0x958, - 0x959, - 0x95A, - 0x95B, - 0x95C, - 0x95D, - 0x95E, - 0x95F, - 0x960, - 0x984, - 0x985, - 0x98D, - 0x98F, - 0x991, - 0x993, - 0x9A9, - 0x9AA, - 0x9B1, - 0x9B2, - 0x9B3, - 0x9B6, - 0x9BA, - 0x9BC, - 0x9C5, - 0x9C7, - 0x9C9, - 0x9CB, - 0x9CF, - 0x9D7, - 0x9D8, - 0x9DC, - 0x9DD, - 0x9DE, - 0x9DF, - 0x9E0, - 0x9E4, - 0x9E6, - 0x9FF, - 0xA01, - 0xA04, - 0xA05, - 0xA0B, - 0xA0F, - 0xA11, - 0xA13, - 0xA29, - 0xA2A, - 0xA31, - 0xA32, - 0xA33, - 0xA34, - 0xA35, - 0xA36, - 0xA37, - 0xA38, - 0xA3A, - 0xA3C, - 0xA3D, - 0xA3E, - 0xA43, - 0xA47, - 0xA49, - 0xA4B, - 0xA4E, - 0xA51, - 0xA52, - 0xA59, - 0xA5A, - 0xA5B, - 0xA5C, - 0xA5D, - 0xA5E, - 0xA5F, - 0xA66, - 0xA77, - 0xA81, - 0xA84, - 0xA85, - 0xA8E, - 0xA8F, - 0xA92, - 0xA93, - 0xAA9, - 0xAAA, - 0xAB1, - 0xAB2, - 0xAB4, - 0xAB5, - 0xABA, - 0xABC, - 0xAC6, - 0xAC7, - 0xACA, - 0xACB, - 0xACE, - 0xAD0, - 0xAD1, - 0xAE0, - 0xAE4, - 0xAE6, - 0xAF2, - 0xAF9, - 0xB00, - 0xB01, - 0xB04, - 0xB05, - 0xB0D, - 0xB0F, - 0xB11, - 0xB13, - 0xB29, - 0xB2A, - 0xB31, - 0xB32, - 0xB34, - 0xB35, - 0xB3A, - 0xB3C, - 0xB45, - 0xB47, - 0xB49, - 0xB4B, - 0xB4E, - 0xB53, - 0xB58, - 0xB5C, - 0xB5D, - 0xB5E, - 0xB5F, - 0xB64, - 0xB66, - 0xB78, - 0xB82, - 0xB84, - 0xB85, - 0xB8B, - 0xB8E, - 0xB91, - 0xB92, - 0xB96, - 0xB99, - 0xB9B, - 0xB9C, - 0xB9D, - 0xB9E, - 0xBA0, - 0xBA3, - 0xBA5, - 0xBA8, - 0xBAB, - 0xBAE, - 0xBBA, - 0xBBE, - 0xBC3, - 0xBC6, - 0xBC9, - 0xBCA, - 0xBCE, - 0xBD0, - 0xBD1, - 0xBD7, - 0xBD8, - 0xBE6, - 0xBFB, - 0xC00, - 0xC0D, - 0xC0E, - 0xC11, - 0xC12, - 0xC29, - 0xC2A, - 0xC3A, - 0xC3C, - 0xC45, - 0xC46, - 0xC49, - 0xC4A, - 0xC4E, - 0xC55, - 0xC57, - 0xC58, - 0xC5B, - 0xC5C, - 0xC5E, - 0xC60, - 0xC64, - 0xC66, - 0xC70, - 0xC77, - 0xC8D, - 0xC8E, - 0xC91, - 0xC92, - 0xCA9, - 0xCAA, - 0xCB4, - 0xCB5, - 0xCBA, - 0xCBC, - 0xCC5, - 0xCC6, - 0xCC9, - 0xCCA, - 0xCCE, - 0xCD5, - 0xCD7, - 0xCDC, - 0xCDF, - 0xCE0, - 0xCE4, - 0xCE6, - 0xCF0, - 0xCF1, - 0xCF4, - 0xD00, - 0xD0D, - 0xD0E, - 0xD11, - 0xD12, - 0xD45, - 0xD46, - 0xD49, - 0xD4A, - 0xD50, - 0xD54, - 0xD64, - 0xD66, - 0xD80, - 0xD81, - 0xD84, - 0xD85, - 0xD97, - 0xD9A, - 0xDB2, - 0xDB3, - 0xDBC, - 0xDBD, - 0xDBE, - 0xDC0, - 0xDC7, - 0xDCA, - 0xDCB, - 0xDCF, - 0xDD5, - 0xDD6, - 0xDD7, - 0xDD8, - 0xDE0, - 0xDE6, - 0xDF0, - 0xDF2, - 0xDF5, - 0xE01, - 0xE33, - 0xE34, - 0xE3B, - 0xE3F, - 0xE5C, - 0xE81, - 0xE83, - 0xE84, - 0xE85, - 0xE86, - 0xE8B, - 0xE8C, - 0xEA4, - 0xEA5, - 0xEA6, - 0xEA7, - 0xEB3, - 0xEB4, - 0xEBE, - 0xEC0, - 0xEC5, - 0xEC6, - 0xEC7, - 0xEC8, - 0xECF, - 0xED0, - 0xEDA, - 0xEDC, - 0xEDD, - 0xEDE, - 0xEE0, - 0xF00, - 0xF0C, - 0xF0D, - 0xF43, - 0xF44, - 0xF48, - 0xF49, - 0xF4D, - 0xF4E, - 0xF52, - 0xF53, - 0xF57, - 0xF58, - 0xF5C, - 0xF5D, - 0xF69, - 0xF6A, - 0xF6D, - 0xF71, - 0xF73, - 0xF74, - 0xF75, - 0xF76, - 0xF77, - 0xF78, - 0xF79, - 0xF7A, - 0xF81, - 0xF82, - 0xF93, - 0xF94, - 0xF98, - 0xF99, - 0xF9D, - 0xF9E, - 0xFA2, - 0xFA3, - 0xFA7, - 0xFA8, - 0xFAC, - 0xFAD, - 0xFB9, - 0xFBA, - 0xFBD, - 0xFBE, - 0xFCD, - 0xFCE, - 0xFDB, - 0x1000, - 0x10A0, - 0x10A1, - 0x10A2, - 0x10A3, - 0x10A4, - 0x10A5, - 0x10A6, - 0x10A7, - 0x10A8, - 0x10A9, - 0x10AA, - 0x10AB, - 0x10AC, - 0x10AD, - 0x10AE, - 0x10AF, - 0x10B0, - 0x10B1, - 0x10B2, - 0x10B3, - 0x10B4, - 0x10B5, - 0x10B6, - 0x10B7, - 0x10B8, - 0x10B9, - 0x10BA, - 0x10BB, - 0x10BC, - 0x10BD, - 0x10BE, - 0x10BF, - 0x10C0, - 0x10C1, - 0x10C2, - 0x10C3, - 0x10C4, - 0x10C5, - 0x10C6, - 0x10C7, - 0x10C8, - 0x10CD, - 0x10CE, - 0x10D0, - 0x10FC, - 0x10FD, - 0x115F, - 0x1161, - 0x1249, - 0x124A, - 0x124E, - 0x1250, - 0x1257, - 0x1258, - 0x1259, - 0x125A, - 0x125E, - 0x1260, - 0x1289, - 0x128A, - 0x128E, - 0x1290, - 0x12B1, - 0x12B2, - 0x12B6, - 0x12B8, - 0x12BF, - 0x12C0, - 0x12C1, - 0x12C2, - 0x12C6, - 0x12C8, - 0x12D7, - 0x12D8, - 0x1311, - 0x1312, - 0x1316, - 0x1318, - 0x135B, - 0x135D, - 0x137D, - 0x1380, - 0x139A, - 0x13A0, - 0x13F6, - 0x13F8, - 0x13F9, - 0x13FA, - 0x13FB, - 0x13FC, - 0x13FD, - 0x13FE, - 0x1400, - 0x1680, - 0x1681, - 0x169D, - 0x16A0, - 0x16F9, - 0x1700, - 0x1716, - 0x171F, - 0x1737, - 0x1740, - 0x1754, - 0x1760, - 0x176D, - 0x176E, - 0x1771, - 0x1772, - 0x1774, - 0x1780, - 0x17B4, - 0x17B6, - 0x17DE, - 0x17E0, - 0x17EA, - 0x17F0, - 0x17FA, - 0x1800, - 0x180B, - 0x1810, - 0x181A, - 0x1820, - 0x1879, - 0x1880, - 0x18AB, - 0x18B0, - 0x18F6, - 0x1900, - 0x191F, - 0x1920, - 0x192C, - 0x1930, - 0x193C, - 0x1940, - 0x1941, - 0x1944, - 0x196E, - 0x1970, - 0x1975, - 0x1980, - 0x19AC, - 0x19B0, - 0x19CA, - 0x19D0, - 0x19DB, - 0x19DE, - 0x1A1C, - 0x1A1E, - 0x1A5F, - 0x1A60, - 0x1A7D, - 0x1A7F, - 0x1A8A, - 0x1A90, - 0x1A9A, - 0x1AA0, - 0x1AAE, - 0x1AB0, - 0x1AF1, - 0x1B00, - 0x1B4D, - 0x1B4E, - 0x1BF4, - 0x1BFC, - 0x1C38, - 0x1C3B, - 0x1C4A, - 0x1C4D, - 0x1C80, - 0x1C81, - 0x1C82, - 0x1C83, - 0x1C84, - 0x1C86, - 0x1C87, - 0x1C88, - 0x1C89, - 0x1C8A, - 0x1C8B, - 0x1C90, - 0x1C91, - 0x1C92, - 0x1C93, - 0x1C94, - 0x1C95, - 0x1C96, - 0x1C97, - 0x1C98, - 0x1C99, - 0x1C9A, - 0x1C9B, - 0x1C9C, - 0x1C9D, - 0x1C9E, - 0x1C9F, - 0x1CA0, - 0x1CA1, - 0x1CA2, - 0x1CA3, - 0x1CA4, - 0x1CA5, - 0x1CA6, - 0x1CA7, - 0x1CA8, - 0x1CA9, - 0x1CAA, - 0x1CAB, - 0x1CAC, - 0x1CAD, - 0x1CAE, - 0x1CAF, - 0x1CB0, - 0x1CB1, - 0x1CB2, - 0x1CB3, - 0x1CB4, - 0x1CB5, - 0x1CB6, - 0x1CB7, - 0x1CB8, - 0x1CB9, - 0x1CBA, - 0x1CBB, - 0x1CBD, - 0x1CBE, - 0x1CBF, - 0x1CC0, - 0x1CC8, - 0x1CD0, - 0x1CFB, - 0x1D00, - 0x1D2C, - 0x1D2D, - 0x1D2E, - 0x1D2F, - 0x1D30, - 0x1D31, - 0x1D32, - 0x1D33, - 0x1D34, - 0x1D35, - 0x1D36, - 0x1D37, - 0x1D38, - 0x1D39, - 0x1D3A, - 0x1D3B, - 0x1D3C, - 0x1D3D, - 0x1D3E, - 0x1D3F, - 0x1D40, - 0x1D41, - 0x1D42, - 0x1D43, - 0x1D44, - 0x1D45, - 0x1D46, - 0x1D47, - 0x1D48, - 0x1D49, - 0x1D4A, - 0x1D4B, - 0x1D4C, - 0x1D4D, - 0x1D4E, - 0x1D4F, - 0x1D50, - 0x1D51, - 0x1D52, - 0x1D53, - 0x1D54, - 0x1D55, - 0x1D56, - 0x1D57, - 0x1D58, - 0x1D59, - 0x1D5A, - 0x1D5B, - 0x1D5C, - 0x1D5D, - 0x1D5E, - 0x1D5F, - 0x1D60, - 0x1D61, - 0x1D62, - 0x1D63, - 0x1D64, - 0x1D65, - 0x1D66, - 0x1D67, - 0x1D68, - 0x1D69, - 0x1D6A, - 0x1D6B, - 0x1D78, - 0x1D79, - 0x1D9B, - 0x1D9C, - 0x1D9D, - 0x1D9E, - 0x1D9F, - 0x1DA0, - 0x1DA1, - 0x1DA2, - 0x1DA3, - 0x1DA4, - 0x1DA5, - 0x1DA6, - 0x1DA7, - 0x1DA8, - 0x1DA9, - 0x1DAA, - 0x1DAB, - 0x1DAC, - 0x1DAD, - 0x1DAE, - 0x1DAF, - 0x1DB0, - 0x1DB1, - 0x1DB2, - 0x1DB3, - 0x1DB4, - 0x1DB5, - 0x1DB6, - 0x1DB7, - 0x1DB8, - 0x1DB9, - 0x1DBA, - 0x1DBB, - 0x1DBC, - 0x1DBD, - 0x1DBE, - 0x1DBF, - 0x1DC0, - 0x1E00, - 0x1E01, - 0x1E02, - 0x1E03, - 0x1E04, - 0x1E05, - 0x1E06, - 0x1E07, - 0x1E08, - 0x1E09, - 0x1E0A, - 0x1E0B, - 0x1E0C, - 0x1E0D, - 0x1E0E, - 0x1E0F, - 0x1E10, - 0x1E11, - 0x1E12, - 0x1E13, - 0x1E14, - 0x1E15, - 0x1E16, - 0x1E17, - 0x1E18, - 0x1E19, - 0x1E1A, - 0x1E1B, - 0x1E1C, - 0x1E1D, - 0x1E1E, - 0x1E1F, - 0x1E20, - 0x1E21, - 0x1E22, - 0x1E23, - 0x1E24, - 0x1E25, - 0x1E26, - 0x1E27, - 0x1E28, - 0x1E29, - 0x1E2A, - 0x1E2B, - 0x1E2C, - 0x1E2D, - 0x1E2E, - 0x1E2F, - 0x1E30, - 0x1E31, - 0x1E32, - 0x1E33, - 0x1E34, - 0x1E35, - 0x1E36, - 0x1E37, - 0x1E38, - 0x1E39, - 0x1E3A, - 0x1E3B, - 0x1E3C, - 0x1E3D, - 0x1E3E, - 0x1E3F, - 0x1E40, - 0x1E41, - 0x1E42, - 0x1E43, - 0x1E44, - 0x1E45, - 0x1E46, - 0x1E47, - 0x1E48, - 0x1E49, - 0x1E4A, - 0x1E4B, - 0x1E4C, - 0x1E4D, - 0x1E4E, - 0x1E4F, - 0x1E50, - 0x1E51, - 0x1E52, - 0x1E53, - 0x1E54, - 0x1E55, - 0x1E56, - 0x1E57, - 0x1E58, - 0x1E59, - 0x1E5A, - 0x1E5B, - 0x1E5C, - 0x1E5D, - 0x1E5E, - 0x1E5F, - 0x1E60, - 0x1E61, - 0x1E62, - 0x1E63, - 0x1E64, - 0x1E65, - 0x1E66, - 0x1E67, - 0x1E68, - 0x1E69, - 0x1E6A, - 0x1E6B, - 0x1E6C, - 0x1E6D, - 0x1E6E, - 0x1E6F, - 0x1E70, - 0x1E71, - 0x1E72, - 0x1E73, - 0x1E74, - 0x1E75, - 0x1E76, - 0x1E77, - 0x1E78, - 0x1E79, - 0x1E7A, - 0x1E7B, - 0x1E7C, - 0x1E7D, - 0x1E7E, - 0x1E7F, - 0x1E80, - 0x1E81, - 0x1E82, - 0x1E83, - 0x1E84, - 0x1E85, - 0x1E86, - 0x1E87, - 0x1E88, - 0x1E89, - 0x1E8A, - 0x1E8B, - 0x1E8C, - 0x1E8D, - 0x1E8E, - 0x1E8F, - 0x1E90, - 0x1E91, - 0x1E92, - 0x1E93, - 0x1E94, - 0x1E95, - 0x1E9A, - 0x1E9B, - 0x1E9C, - 0x1E9E, - 0x1E9F, - 0x1EA0, - 0x1EA1, - 0x1EA2, - 0x1EA3, - 0x1EA4, - 0x1EA5, - 0x1EA6, - 0x1EA7, - 0x1EA8, - 0x1EA9, - 0x1EAA, - 0x1EAB, - 0x1EAC, - 0x1EAD, - 0x1EAE, - 0x1EAF, - 0x1EB0, - 0x1EB1, - 0x1EB2, - 0x1EB3, - 0x1EB4, - 0x1EB5, - 0x1EB6, - 0x1EB7, - 0x1EB8, - 0x1EB9, - 0x1EBA, - 0x1EBB, - 0x1EBC, - 0x1EBD, - 0x1EBE, - 0x1EBF, - 0x1EC0, - 0x1EC1, - 0x1EC2, - 0x1EC3, - 0x1EC4, - 0x1EC5, - 0x1EC6, - 0x1EC7, - 0x1EC8, - 0x1EC9, - 0x1ECA, - 0x1ECB, - 0x1ECC, - 0x1ECD, - 0x1ECE, - 0x1ECF, - 0x1ED0, - 0x1ED1, - 0x1ED2, - 0x1ED3, - 0x1ED4, - 0x1ED5, - 0x1ED6, - 0x1ED7, - 0x1ED8, - 0x1ED9, - 0x1EDA, - 0x1EDB, - 0x1EDC, - 0x1EDD, - 0x1EDE, - 0x1EDF, - 0x1EE0, - 0x1EE1, - 0x1EE2, - 0x1EE3, - 0x1EE4, - 0x1EE5, - 0x1EE6, - 0x1EE7, - 0x1EE8, - 0x1EE9, - 0x1EEA, - 0x1EEB, - 0x1EEC, - 0x1EED, - 0x1EEE, - 0x1EEF, - 0x1EF0, - 0x1EF1, - 0x1EF2, - 0x1EF3, - 0x1EF4, - 0x1EF5, - 0x1EF6, - 0x1EF7, - 0x1EF8, - 0x1EF9, - 0x1EFA, - 0x1EFB, - 0x1EFC, - 0x1EFD, - 0x1EFE, - 0x1EFF, - 0x1F08, - 0x1F09, - 0x1F0A, - 0x1F0B, - 0x1F0C, - 0x1F0D, - 0x1F0E, - 0x1F0F, - 0x1F10, - 0x1F16, - 0x1F18, - 0x1F19, - 0x1F1A, - 0x1F1B, - 0x1F1C, - 0x1F1D, - 0x1F1E, - 0x1F20, - 0x1F28, - 0x1F29, - 0x1F2A, - 0x1F2B, - 0x1F2C, - 0x1F2D, - 0x1F2E, - 0x1F2F, - 0x1F30, - 0x1F38, - 0x1F39, - 0x1F3A, - 0x1F3B, - 0x1F3C, - 0x1F3D, - 0x1F3E, - 0x1F3F, - 0x1F40, - 0x1F46, - 0x1F48, - 0x1F49, - 0x1F4A, - 0x1F4B, - 0x1F4C, - 0x1F4D, - 0x1F4E, - 0x1F50, - 0x1F58, - 0x1F59, - 0x1F5A, - 0x1F5B, - 0x1F5C, - 0x1F5D, - 0x1F5E, - 0x1F5F, - 0x1F60, - 0x1F68, - 0x1F69, - 0x1F6A, - 0x1F6B, - 0x1F6C, - 0x1F6D, - 0x1F6E, - 0x1F6F, - 0x1F70, - 0x1F71, - 0x1F72, - 0x1F73, - 0x1F74, - 0x1F75, - 0x1F76, - 0x1F77, - 0x1F78, - 0x1F79, - 0x1F7A, - 0x1F7B, - 0x1F7C, - 0x1F7D, - 0x1F7E, - 0x1F80, - 0x1F81, - 0x1F82, - 0x1F83, - 0x1F84, - 0x1F85, - 0x1F86, - 0x1F87, - 0x1F88, - 0x1F89, - 0x1F8A, - 0x1F8B, - 0x1F8C, - 0x1F8D, - 0x1F8E, - 0x1F8F, - 0x1F90, - 0x1F91, - 0x1F92, - 0x1F93, - 0x1F94, - 0x1F95, - 0x1F96, - 0x1F97, - 0x1F98, - 0x1F99, - 0x1F9A, - 0x1F9B, - 0x1F9C, - 0x1F9D, - 0x1F9E, - 0x1F9F, - 0x1FA0, - 0x1FA1, - 0x1FA2, - 0x1FA3, - 0x1FA4, - 0x1FA5, - 0x1FA6, - 0x1FA7, - 0x1FA8, - 0x1FA9, - 0x1FAA, - 0x1FAB, - 0x1FAC, - 0x1FAD, - 0x1FAE, - 0x1FAF, - 0x1FB0, - 0x1FB2, - 0x1FB3, - 0x1FB4, - 0x1FB5, - 0x1FB6, - 0x1FB7, - 0x1FB8, - 0x1FB9, - 0x1FBA, - 0x1FBB, - 0x1FBC, - 0x1FBD, - 0x1FBE, - 0x1FBF, - 0x1FC0, - 0x1FC1, - 0x1FC2, - 0x1FC3, - 0x1FC4, - 0x1FC5, - 0x1FC6, - 0x1FC7, - 0x1FC8, - 0x1FC9, - 0x1FCA, - 0x1FCB, - 0x1FCC, - 0x1FCD, - 0x1FCE, - 0x1FCF, - 0x1FD0, - 0x1FD3, - 0x1FD4, - 0x1FD6, - 0x1FD8, - 0x1FD9, - 0x1FDA, - 0x1FDB, - 0x1FDC, - 0x1FDD, - 0x1FDE, - 0x1FDF, - 0x1FE0, - 0x1FE3, - 0x1FE4, - 0x1FE8, - 0x1FE9, - 0x1FEA, - 0x1FEB, - 0x1FEC, - 0x1FED, - 0x1FEE, - 0x1FEF, - 0x1FF0, - 0x1FF2, - 0x1FF3, - 0x1FF4, - 0x1FF5, - 0x1FF6, - 0x1FF7, - 0x1FF8, - 0x1FF9, - 0x1FFA, - 0x1FFB, - 0x1FFC, - 0x1FFD, - 0x1FFE, - 0x1FFF, - 0x2000, - 0x200B, - 0x200C, - 0x200E, - 0x2010, - 0x2011, - 0x2012, - 0x2017, - 0x2018, - 0x2024, - 0x2027, - 0x2028, - 0x202F, - 0x2030, - 0x2033, - 0x2034, - 0x2035, - 0x2036, - 0x2037, - 0x2038, - 0x203C, - 0x203D, - 0x203E, - 0x203F, - 0x2047, - 0x2048, - 0x2049, - 0x204A, - 0x2057, - 0x2058, - 0x205F, - 0x2060, - 0x2065, - 0x206A, - 0x2070, - 0x2071, - 0x2072, - 0x2074, - 0x2075, - 0x2076, - 0x2077, - 0x2078, - 0x2079, - 0x207A, - 0x207B, - 0x207C, - 0x207D, - 0x207E, - 0x207F, - 0x2080, - 0x2081, - 0x2082, - 0x2083, - 0x2084, - 0x2085, - 0x2086, - 0x2087, - 0x2088, - 0x2089, - 0x208A, - 0x208B, - 0x208C, - 0x208D, - 0x208E, - 0x208F, - 0x2090, - 0x2091, - 0x2092, - 0x2093, - 0x2094, - 0x2095, - 0x2096, - 0x2097, - 0x2098, - 0x2099, - 0x209A, - 0x209B, - 0x209C, - 0x209D, - 0x209E, - 0x209F, - 0x20A0, - 0x20A8, - 0x20A9, - 0x20C5, - 0x20D0, - 0x20F1, - 0x2100, - 0x2101, - 0x2102, - 0x2103, - 0x2104, - 0x2105, - 0x2106, - 0x2107, - 0x2108, - 0x2109, - 0x210A, - 0x210B, - 0x210F, - 0x2110, - 0x2112, - 0x2114, - 0x2115, - 0x2116, - 0x2117, - 0x2119, - 0x211A, - 0x211B, - 0x211E, - 0x2120, - 0x2121, - 0x2122, - 0x2123, - 0x2124, - 0x2125, - 0x2126, - 0x2127, - 0x2128, - 0x2129, - 0x212A, - 0x212B, - 0x212C, - 0x212D, - 0x212E, - 0x212F, - 0x2131, - 0x2132, - 0x2133, - 0x2134, - 0x2135, - 0x2136, - 0x2137, - 0x2138, - 0x2139, - 0x213A, - 0x213B, - 0x213C, - 0x213D, - 0x213F, - 0x2140, - 0x2141, - 0x2145, - 0x2147, - 0x2148, - 0x2149, - 0x214A, - 0x2150, - 0x2151, - 0x2152, - 0x2153, - 0x2154, - 0x2155, - 0x2156, - 0x2157, - 0x2158, - 0x2159, - 0x215A, - 0x215B, - 0x215C, - 0x215D, - 0x215E, - 0x215F, - 0x2160, - 0x2161, - 0x2162, - 0x2163, - 0x2164, - 0x2165, - 0x2166, - 0x2167, - 0x2168, - 0x2169, - 0x216A, - 0x216B, - 0x216C, - 0x216D, - 0x216E, - 0x216F, - 0x2170, - 0x2171, - 0x2172, - 0x2173, - 0x2174, - 0x2175, - 0x2176, - 0x2177, - 0x2178, - 0x2179, - 0x217A, - 0x217B, - 0x217C, - 0x217D, - 0x217E, - 0x217F, - 0x2180, - 0x2183, - 0x2184, - 0x2189, - 0x218A, - 0x218C, - 0x2190, - 0x222C, - 0x222D, - 0x222E, - 0x222F, - 0x2230, - 0x2231, - 0x2329, - 0x232A, - 0x232B, - 0x242A, - 0x2440, - 0x244B, - 0x2460, - 0x2461, - 0x2462, - 0x2463, - 0x2464, - 0x2465, - 0x2466, - 0x2467, - 0x2468, - 0x2469, - 0x246A, - 0x246B, - 0x246C, - 0x246D, - 0x246E, - 0x246F, - 0x2470, - 0x2471, - 0x2472, - 0x2473, - 0x2474, - 0x2475, - 0x2476, - 0x2477, - 0x2478, - 0x2479, - 0x247A, - 0x247B, - 0x247C, - 0x247D, - 0x247E, - 0x247F, - 0x2480, - 0x2481, - 0x2482, - 0x2483, - 0x2484, - 0x2485, - 0x2486, - 0x2487, - 0x2488, - 0x249C, - 0x249D, - 0x249E, - 0x249F, - 0x24A0, - 0x24A1, - 0x24A2, - 0x24A3, - 0x24A4, - 0x24A5, - 0x24A6, - 0x24A7, - 0x24A8, - 0x24A9, - 0x24AA, - 0x24AB, - 0x24AC, - 0x24AD, - 0x24AE, - 0x24AF, - 0x24B0, - 0x24B1, - 0x24B2, - 0x24B3, - 0x24B4, - 0x24B5, - 0x24B6, - 0x24B7, - 0x24B8, - 0x24B9, - 0x24BA, - 0x24BB, - 0x24BC, - 0x24BD, - 0x24BE, - 0x24BF, - 0x24C0, - 0x24C1, - 0x24C2, - 0x24C3, - 0x24C4, - 0x24C5, - 0x24C6, - 0x24C7, - 0x24C8, - 0x24C9, - 0x24CA, - 0x24CB, - 0x24CC, - 0x24CD, - 0x24CE, - 0x24CF, - 0x24D0, - 0x24D1, - 0x24D2, - 0x24D3, - 0x24D4, - 0x24D5, - 0x24D6, - 0x24D7, - 0x24D8, - 0x24D9, - 0x24DA, - 0x24DB, - 0x24DC, - 0x24DD, - 0x24DE, - 0x24DF, - 0x24E0, - 0x24E1, - 0x24E2, - 0x24E3, - 0x24E4, - 0x24E5, - 0x24E6, - 0x24E7, - 0x24E8, - 0x24E9, - 0x24EA, - 0x24EB, - 0x2A0C, - 0x2A0D, - 0x2A74, - 0x2A75, - 0x2A76, - 0x2A77, - 0x2ADC, - 0x2ADD, - 0x2B74, - 0x2B76, - 0x2C00, - 0x2C01, - 0x2C02, - 0x2C03, - 0x2C04, - 0x2C05, - 0x2C06, - 0x2C07, - 0x2C08, - 0x2C09, - 0x2C0A, - 0x2C0B, - 0x2C0C, - 0x2C0D, - 0x2C0E, - 0x2C0F, - 0x2C10, - 0x2C11, - 0x2C12, - 0x2C13, - 0x2C14, - 0x2C15, - 0x2C16, - 0x2C17, - 0x2C18, - 0x2C19, - 0x2C1A, - 0x2C1B, - 0x2C1C, - 0x2C1D, - 0x2C1E, - 0x2C1F, - 0x2C20, - 0x2C21, - 0x2C22, - 0x2C23, - 0x2C24, - 0x2C25, - 0x2C26, - 0x2C27, - 0x2C28, - 0x2C29, - 0x2C2A, - 0x2C2B, - 0x2C2C, - 0x2C2D, - 0x2C2E, - 0x2C2F, - 0x2C30, - 0x2C60, - 0x2C61, - 0x2C62, - 0x2C63, - 0x2C64, - 0x2C65, - 0x2C67, - 0x2C68, - 0x2C69, - 0x2C6A, - 0x2C6B, - 0x2C6C, - 0x2C6D, - 0x2C6E, - 0x2C6F, - 0x2C70, - 0x2C71, - 0x2C72, - 0x2C73, - 0x2C75, - 0x2C76, - 0x2C7C, - 0x2C7D, - 0x2C7E, - 0x2C7F, - 0x2C80, - 0x2C81, - 0x2C82, - 0x2C83, - 0x2C84, - 0x2C85, - 0x2C86, - 0x2C87, - 0x2C88, - 0x2C89, - 0x2C8A, - 0x2C8B, - 0x2C8C, - 0x2C8D, - 0x2C8E, - 0x2C8F, - 0x2C90, - 0x2C91, - 0x2C92, - 0x2C93, - 0x2C94, - 0x2C95, - 0x2C96, - 0x2C97, - 0x2C98, - 0x2C99, - 0x2C9A, - 0x2C9B, - 0x2C9C, - 0x2C9D, - 0x2C9E, - 0x2C9F, - 0x2CA0, - 0x2CA1, - 0x2CA2, - 0x2CA3, - 0x2CA4, - 0x2CA5, - 0x2CA6, - 0x2CA7, - 0x2CA8, - 0x2CA9, - 0x2CAA, - 0x2CAB, - 0x2CAC, - 0x2CAD, - 0x2CAE, - 0x2CAF, - 0x2CB0, - 0x2CB1, - 0x2CB2, - 0x2CB3, - 0x2CB4, - 0x2CB5, - 0x2CB6, - 0x2CB7, - 0x2CB8, - 0x2CB9, - 0x2CBA, - 0x2CBB, - 0x2CBC, - 0x2CBD, - 0x2CBE, - 0x2CBF, - 0x2CC0, - 0x2CC1, - 0x2CC2, - 0x2CC3, - 0x2CC4, - 0x2CC5, - 0x2CC6, - 0x2CC7, - 0x2CC8, - 0x2CC9, - 0x2CCA, - 0x2CCB, - 0x2CCC, - 0x2CCD, - 0x2CCE, - 0x2CCF, - 0x2CD0, - 0x2CD1, - 0x2CD2, - 0x2CD3, - 0x2CD4, - 0x2CD5, - 0x2CD6, - 0x2CD7, - 0x2CD8, - 0x2CD9, - 0x2CDA, - 0x2CDB, - 0x2CDC, - 0x2CDD, - 0x2CDE, - 0x2CDF, - 0x2CE0, - 0x2CE1, - 0x2CE2, - 0x2CE3, - 0x2CEB, - 0x2CEC, - 0x2CED, - 0x2CEE, - 0x2CF2, - 0x2CF3, - 0x2CF4, - 0x2CF9, - 0x2D26, - 0x2D27, - 0x2D28, - 0x2D2D, - 0x2D2E, - 0x2D30, - 0x2D68, - 0x2D6F, - 0x2D70, - 0x2D71, - 0x2D7F, - 0x2D97, - 0x2DA0, - 0x2DA7, - 0x2DA8, - 0x2DAF, - 0x2DB0, - 0x2DB7, - 0x2DB8, - 0x2DBF, - 0x2DC0, - 0x2DC7, - 0x2DC8, - 0x2DCF, - 0x2DD0, - 0x2DD7, - 0x2DD8, - 0x2DDF, - 0x2DE0, - 0x2E5E, - 0x2E60, - 0x2E64, - 0x2E80, - 0x2E9A, - 0x2E9B, - 0x2E9F, - 0x2EA0, - 0x2EF3, - 0x2EF4, - 0x2F00, - 0x2F01, - 0x2F02, - 0x2F03, - 0x2F04, - 0x2F05, - 0x2F06, - 0x2F07, - 0x2F08, - 0x2F09, - 0x2F0A, - 0x2F0B, - 0x2F0C, - 0x2F0D, - 0x2F0E, - 0x2F0F, - 0x2F10, - 0x2F11, - 0x2F12, - 0x2F13, - 0x2F14, - 0x2F15, - 0x2F16, - 0x2F17, - 0x2F18, - 0x2F19, - 0x2F1A, - 0x2F1B, - 0x2F1C, - 0x2F1D, - 0x2F1E, - 0x2F1F, - 0x2F20, - 0x2F21, - 0x2F22, - 0x2F23, - 0x2F24, - 0x2F25, - 0x2F26, - 0x2F27, - 0x2F28, - 0x2F29, - 0x2F2A, - 0x2F2B, - 0x2F2C, - 0x2F2D, - 0x2F2E, - 0x2F2F, - 0x2F30, - 0x2F31, - 0x2F32, - 0x2F33, - 0x2F34, - 0x2F35, - 0x2F36, - 0x2F37, - 0x2F38, - 0x2F39, - 0x2F3A, - 0x2F3B, - 0x2F3C, - 0x2F3D, - 0x2F3E, - 0x2F3F, - 0x2F40, - 0x2F41, - 0x2F42, - 0x2F43, - 0x2F44, - 0x2F45, - 0x2F46, - 0x2F47, - 0x2F48, - 0x2F49, - 0x2F4A, - 0x2F4B, - 0x2F4C, - 0x2F4D, - 0x2F4E, - 0x2F4F, - 0x2F50, - 0x2F51, - 0x2F52, - 0x2F53, - 0x2F54, - 0x2F55, - 0x2F56, - 0x2F57, - 0x2F58, - 0x2F59, - 0x2F5A, - 0x2F5B, - 0x2F5C, - 0x2F5D, - 0x2F5E, - 0x2F5F, - 0x2F60, - 0x2F61, - 0x2F62, - 0x2F63, - 0x2F64, - 0x2F65, - 0x2F66, - 0x2F67, - 0x2F68, - 0x2F69, - 0x2F6A, - 0x2F6B, - 0x2F6C, - 0x2F6D, - 0x2F6E, - 0x2F6F, - 0x2F70, - 0x2F71, - 0x2F72, - 0x2F73, - 0x2F74, - 0x2F75, - 0x2F76, - 0x2F77, - 0x2F78, - 0x2F79, - 0x2F7A, - 0x2F7B, - 0x2F7C, - 0x2F7D, - 0x2F7E, - 0x2F7F, - 0x2F80, - 0x2F81, - 0x2F82, - 0x2F83, - 0x2F84, - 0x2F85, - 0x2F86, - 0x2F87, - 0x2F88, - 0x2F89, - 0x2F8A, - 0x2F8B, - 0x2F8C, - 0x2F8D, - 0x2F8E, - 0x2F8F, - 0x2F90, - 0x2F91, - 0x2F92, - 0x2F93, - 0x2F94, - 0x2F95, - 0x2F96, - 0x2F97, - 0x2F98, - 0x2F99, - 0x2F9A, - 0x2F9B, - 0x2F9C, - 0x2F9D, - 0x2F9E, - 0x2F9F, - 0x2FA0, - 0x2FA1, - 0x2FA2, - 0x2FA3, - 0x2FA4, - 0x2FA5, - 0x2FA6, - 0x2FA7, - 0x2FA8, - 0x2FA9, - 0x2FAA, - 0x2FAB, - 0x2FAC, - 0x2FAD, - 0x2FAE, - 0x2FAF, - 0x2FB0, - 0x2FB1, - 0x2FB2, - 0x2FB3, - 0x2FB4, - 0x2FB5, - 0x2FB6, - 0x2FB7, - 0x2FB8, - 0x2FB9, - 0x2FBA, - 0x2FBB, - 0x2FBC, - 0x2FBD, - 0x2FBE, - 0x2FBF, - 0x2FC0, - 0x2FC1, - 0x2FC2, - 0x2FC3, - 0x2FC4, - 0x2FC5, - 0x2FC6, - 0x2FC7, - 0x2FC8, - 0x2FC9, - 0x2FCA, - 0x2FCB, - 0x2FCC, - 0x2FCD, - 0x2FCE, - 0x2FCF, - 0x2FD0, - 0x2FD1, - 0x2FD2, - 0x2FD3, - 0x2FD4, - 0x2FD5, - 0x2FD6, - 0x3000, - 0x3001, - 0x3002, - 0x3003, - 0x3036, - 0x3037, - 0x3038, - 0x3039, - 0x303A, - 0x303B, - 0x3040, - 0x3041, - 0x3097, - 0x3099, - 0x309B, - 0x309C, - 0x309D, - 0x309F, - 0x30A0, - 0x30FF, - 0x3100, - 0x3105, - 0x3130, - 0x3131, - 0x3132, - 0x3133, - 0x3134, - 0x3135, - 0x3136, - 0x3137, - 0x3138, - 0x3139, - 0x313A, - 0x313B, - 0x313C, - 0x313D, - 0x313E, - 0x313F, - 0x3140, - 0x3141, - 0x3142, - 0x3143, - 0x3144, - 0x3145, - 0x3146, - 0x3147, - 0x3148, - 0x3149, - 0x314A, - 0x314B, - 0x314C, - 0x314D, - 0x314E, - 0x314F, - 0x3150, - 0x3151, - 0x3152, - 0x3153, - 0x3154, - 0x3155, - 0x3156, - 0x3157, - 0x3158, - 0x3159, - 0x315A, - 0x315B, - 0x315C, - 0x315D, - 0x315E, - 0x315F, - 0x3160, - 0x3161, - 0x3162, - 0x3163, - 0x3164, - 0x3165, - 0x3166, - 0x3167, - 0x3168, - 0x3169, - 0x316A, - 0x316B, - 0x316C, - 0x316D, - 0x316E, - 0x316F, - 0x3170, - 0x3171, - 0x3172, - 0x3173, - 0x3174, - 0x3175, - 0x3176, - 0x3177, - 0x3178, - 0x3179, - 0x317A, - 0x317B, - 0x317C, - 0x317D, - 0x317E, - 0x317F, - 0x3180, - 0x3181, - 0x3182, - 0x3183, - 0x3184, - 0x3185, - 0x3186, - 0x3187, - 0x3188, - 0x3189, - 0x318A, - 0x318B, - 0x318C, - 0x318D, - 0x318E, - 0x318F, - 0x3190, - 0x3192, - 0x3193, - 0x3194, - 0x3195, - 0x3196, - 0x3197, - 0x3198, - 0x3199, - 0x319A, - 0x319B, - 0x319C, - 0x319D, - 0x319E, - 0x319F, - 0x31A0, - 0x31E6, - 0x31F0, - 0x3200, - 0x3201, - 0x3202, - 0x3203, - 0x3204, - 0x3205, - 0x3206, - 0x3207, - 0x3208, - 0x3209, - 0x320A, - 0x320B, - 0x320C, - 0x320D, - 0x320E, - 0x320F, - 0x3210, - 0x3211, - 0x3212, - 0x3213, - 0x3214, - 0x3215, - 0x3216, - 0x3217, - 0x3218, - 0x3219, - 0x321A, - 0x321B, - 0x321C, - 0x321D, - 0x321E, - 0x321F, - 0x3220, - 0x3221, - 0x3222, - 0x3223, - 0x3224, - 0x3225, - 0x3226, - 0x3227, - 0x3228, - 0x3229, - 0x322A, - 0x322B, - 0x322C, - 0x322D, - 0x322E, - 0x322F, - 0x3230, - 0x3231, - 0x3232, - 0x3233, - 0x3234, - 0x3235, - 0x3236, - 0x3237, - 0x3238, - 0x3239, - 0x323A, - 0x323B, - 0x323C, - 0x323D, - 0x323E, - 0x323F, - 0x3240, - 0x3241, - 0x3242, - 0x3243, - 0x3244, - 0x3245, - 0x3246, - 0x3247, - 0x3248, - 0x3250, - 0x3251, - 0x3252, - 0x3253, - 0x3254, - 0x3255, - 0x3256, - 0x3257, - 0x3258, - 0x3259, - 0x325A, - 0x325B, - 0x325C, - 0x325D, - 0x325E, - 0x325F, - 0x3260, - 0x3261, - 0x3262, - 0x3263, - 0x3264, - 0x3265, - 0x3266, - 0x3267, - 0x3268, - 0x3269, - 0x326A, - 0x326B, - 0x326C, - 0x326D, - 0x326E, - 0x326F, - 0x3270, - 0x3271, - 0x3272, - 0x3273, - 0x3274, - 0x3275, - 0x3276, - 0x3277, - 0x3278, - 0x3279, - 0x327A, - 0x327B, - 0x327C, - 0x327D, - 0x327E, - 0x327F, - 0x3280, - 0x3281, - 0x3282, - 0x3283, - 0x3284, - 0x3285, - 0x3286, - 0x3287, - 0x3288, - 0x3289, - 0x328A, - 0x328B, - 0x328C, - 0x328D, - 0x328E, - 0x328F, - 0x3290, - 0x3291, - 0x3292, - 0x3293, - 0x3294, - 0x3295, - 0x3296, - 0x3297, - 0x3298, - 0x3299, - 0x329A, - 0x329B, - 0x329C, - 0x329D, - 0x329E, - 0x329F, - 0x32A0, - 0x32A1, - 0x32A2, - 0x32A3, - 0x32A4, - 0x32A5, - 0x32A6, - 0x32A7, - 0x32A8, - 0x32A9, - 0x32AA, - 0x32AB, - 0x32AC, - 0x32AD, - 0x32AE, - 0x32AF, - 0x32B0, - 0x32B1, - 0x32B2, - 0x32B3, - 0x32B4, - 0x32B5, - 0x32B6, - 0x32B7, - 0x32B8, - 0x32B9, - 0x32BA, - 0x32BB, - 0x32BC, - 0x32BD, - 0x32BE, - 0x32BF, - 0x32C0, - 0x32C1, - 0x32C2, - 0x32C3, - 0x32C4, - 0x32C5, - 0x32C6, - 0x32C7, - 0x32C8, - 0x32C9, - 0x32CA, - 0x32CB, - 0x32CC, - 0x32CD, - 0x32CE, - 0x32CF, - 0x32D0, - 0x32D1, - 0x32D2, - 0x32D3, - 0x32D4, - 0x32D5, - 0x32D6, - 0x32D7, - 0x32D8, - 0x32D9, - 0x32DA, - 0x32DB, - 0x32DC, - 0x32DD, - 0x32DE, - 0x32DF, - 0x32E0, - 0x32E1, - 0x32E2, - 0x32E3, - 0x32E4, - 0x32E5, - 0x32E6, - 0x32E7, - 0x32E8, - 0x32E9, - 0x32EA, - 0x32EB, - 0x32EC, - 0x32ED, - 0x32EE, - 0x32EF, - 0x32F0, - 0x32F1, - 0x32F2, - 0x32F3, - 0x32F4, - 0x32F5, - 0x32F6, - 0x32F7, - 0x32F8, - 0x32F9, - 0x32FA, - 0x32FB, - 0x32FC, - 0x32FD, - 0x32FE, - 0x32FF, - 0x3300, - 0x3301, - 0x3302, - 0x3303, - 0x3304, - 0x3305, - 0x3306, - 0x3307, - 0x3308, - 0x3309, - 0x330A, - 0x330B, - 0x330C, - 0x330D, - 0x330E, - 0x330F, - 0x3310, - 0x3311, - 0x3312, - 0x3313, - 0x3314, - 0x3315, - 0x3316, - 0x3317, - 0x3318, - 0x3319, - 0x331A, - 0x331B, - 0x331C, - 0x331D, - 0x331E, - 0x331F, - 0x3320, - 0x3321, - 0x3322, - 0x3323, - 0x3324, - 0x3325, - 0x3326, - 0x3327, - 0x3328, - 0x3329, - 0x332A, - 0x332B, - 0x332C, - 0x332D, - 0x332E, - 0x332F, - 0x3330, - 0x3331, - 0x3332, - 0x3333, - 0x3334, - 0x3335, - 0x3336, - 0x3337, - 0x3338, - 0x3339, - 0x333A, - 0x333B, - 0x333C, - 0x333D, - 0x333E, - 0x333F, - 0x3340, - 0x3341, - 0x3342, - 0x3343, - 0x3344, - 0x3345, - 0x3346, - 0x3347, - 0x3348, - 0x3349, - 0x334A, - 0x334B, - 0x334C, - 0x334D, - 0x334E, - 0x334F, - 0x3350, - 0x3351, - 0x3352, - 0x3353, - 0x3354, - 0x3355, - 0x3356, - 0x3357, - 0x3358, - 0x3359, - 0x335A, - 0x335B, - 0x335C, - 0x335D, - 0x335E, - 0x335F, - 0x3360, - 0x3361, - 0x3362, - 0x3363, - 0x3364, - 0x3365, - 0x3366, - 0x3367, - 0x3368, - 0x3369, - 0x336A, - 0x336B, - 0x336C, - 0x336D, - 0x336E, - 0x336F, - 0x3370, - 0x3371, - 0x3372, - 0x3373, - 0x3374, - 0x3375, - 0x3376, - 0x3377, - 0x3378, - 0x3379, - 0x337A, - 0x337B, - 0x337C, - 0x337D, - 0x337E, - 0x337F, - 0x3380, - 0x3381, - 0x3382, - 0x3383, - 0x3384, - 0x3385, - 0x3386, - 0x3387, - 0x3388, - 0x3389, - 0x338A, - 0x338B, - 0x338C, - 0x338D, - 0x338E, - 0x338F, - 0x3390, - 0x3391, - 0x3392, - 0x3393, - 0x3394, - 0x3395, - 0x3396, - 0x3397, - 0x3398, - 0x3399, - 0x339A, - 0x339B, - 0x339C, - 0x339D, - 0x339E, - 0x339F, - 0x33A0, - 0x33A1, - 0x33A2, - 0x33A3, - 0x33A4, - 0x33A5, - 0x33A6, - 0x33A7, - 0x33A8, - 0x33A9, - 0x33AA, - 0x33AB, - 0x33AC, - 0x33AD, - 0x33AE, - 0x33AF, - 0x33B0, - 0x33B1, - 0x33B2, - 0x33B3, - 0x33B4, - 0x33B5, - 0x33B6, - 0x33B7, - 0x33B8, - 0x33B9, - 0x33BA, - 0x33BB, - 0x33BC, - 0x33BD, - 0x33BE, - 0x33BF, - 0x33C0, - 0x33C1, - 0x33C2, - 0x33C3, - 0x33C4, - 0x33C5, - 0x33C6, - 0x33C7, - 0x33C8, - 0x33C9, - 0x33CA, - 0x33CB, - 0x33CC, - 0x33CD, - 0x33CE, - 0x33CF, - 0x33D0, - 0x33D1, - 0x33D2, - 0x33D3, - 0x33D4, - 0x33D5, - 0x33D6, - 0x33D7, - 0x33D8, - 0x33D9, - 0x33DA, - 0x33DB, - 0x33DC, - 0x33DD, - 0x33DE, - 0x33DF, - 0x33E0, - 0x33E1, - 0x33E2, - 0x33E3, - 0x33E4, - 0x33E5, - 0x33E6, - 0x33E7, - 0x33E8, - 0x33E9, - 0x33EA, - 0x33EB, - 0x33EC, - 0x33ED, - 0x33EE, - 0x33EF, - 0x33F0, - 0x33F1, - 0x33F2, - 0x33F3, - 0x33F4, - 0x33F5, - 0x33F6, - 0x33F7, - 0x33F8, - 0x33F9, - 0x33FA, - 0x33FB, - 0x33FC, - 0x33FD, - 0x33FE, - 0x33FF, - 0x3400, - 0xA48D, - 0xA490, - 0xA4C7, - 0xA4D0, - 0xA62C, - 0xA640, - 0xA641, - 0xA642, - 0xA643, - 0xA644, - 0xA645, - 0xA646, - 0xA647, - 0xA648, - 0xA649, - 0xA64A, - 0xA64B, - 0xA64C, - 0xA64D, - 0xA64E, - 0xA64F, - 0xA650, - 0xA651, - 0xA652, - 0xA653, - 0xA654, - 0xA655, - 0xA656, - 0xA657, - 0xA658, - 0xA659, - 0xA65A, - 0xA65B, - 0xA65C, - 0xA65D, - 0xA65E, - 0xA65F, - 0xA660, - 0xA661, - 0xA662, - 0xA663, - 0xA664, - 0xA665, - 0xA666, - 0xA667, - 0xA668, - 0xA669, - 0xA66A, - 0xA66B, - 0xA66C, - 0xA66D, - 0xA680, - 0xA681, - 0xA682, - 0xA683, - 0xA684, - 0xA685, - 0xA686, - 0xA687, - 0xA688, - 0xA689, - 0xA68A, - 0xA68B, - 0xA68C, - 0xA68D, - 0xA68E, - 0xA68F, - 0xA690, - 0xA691, - 0xA692, - 0xA693, - 0xA694, - 0xA695, - 0xA696, - 0xA697, - 0xA698, - 0xA699, - 0xA69A, - 0xA69B, - 0xA69C, - 0xA69D, - 0xA69E, - 0xA6F8, - 0xA700, - 0xA722, - 0xA723, - 0xA724, - 0xA725, - 0xA726, - 0xA727, - 0xA728, - 0xA729, - 0xA72A, - 0xA72B, - 0xA72C, - 0xA72D, - 0xA72E, - 0xA72F, - 0xA732, - 0xA733, - 0xA734, - 0xA735, - 0xA736, - 0xA737, - 0xA738, - 0xA739, - 0xA73A, - 0xA73B, - 0xA73C, - 0xA73D, - 0xA73E, - 0xA73F, - 0xA740, - 0xA741, - 0xA742, - 0xA743, - 0xA744, - 0xA745, - 0xA746, - 0xA747, - 0xA748, - 0xA749, - 0xA74A, - 0xA74B, - 0xA74C, - 0xA74D, - 0xA74E, - 0xA74F, - 0xA750, - 0xA751, - 0xA752, - 0xA753, - 0xA754, - 0xA755, - 0xA756, - 0xA757, - 0xA758, - 0xA759, - 0xA75A, - 0xA75B, - 0xA75C, - 0xA75D, - 0xA75E, - 0xA75F, - 0xA760, - 0xA761, - 0xA762, - 0xA763, - 0xA764, - 0xA765, - 0xA766, - 0xA767, - 0xA768, - 0xA769, - 0xA76A, - 0xA76B, - 0xA76C, - 0xA76D, - 0xA76E, - 0xA76F, - 0xA770, - 0xA771, - 0xA779, - 0xA77A, - 0xA77B, - 0xA77C, - 0xA77D, - 0xA77E, - 0xA77F, - 0xA780, - 0xA781, - 0xA782, - 0xA783, - 0xA784, - 0xA785, - 0xA786, - 0xA787, - 0xA78B, - 0xA78C, - 0xA78D, - 0xA78E, - 0xA790, - 0xA791, - 0xA792, - 0xA793, - 0xA796, - 0xA797, - 0xA798, - 0xA799, - 0xA79A, - 0xA79B, - 0xA79C, - 0xA79D, - 0xA79E, - 0xA79F, - 0xA7A0, - 0xA7A1, - 0xA7A2, - 0xA7A3, - 0xA7A4, - 0xA7A5, - 0xA7A6, - 0xA7A7, - 0xA7A8, - 0xA7A9, - 0xA7AA, - 0xA7AB, - 0xA7AC, - 0xA7AD, - 0xA7AE, - 0xA7AF, - 0xA7B0, - 0xA7B1, - 0xA7B2, - 0xA7B3, - 0xA7B4, - 0xA7B5, - 0xA7B6, - 0xA7B7, - 0xA7B8, - 0xA7B9, - 0xA7BA, - 0xA7BB, - 0xA7BC, - 0xA7BD, - 0xA7BE, - 0xA7BF, - 0xA7C0, - 0xA7C1, - 0xA7C2, - 0xA7C3, - 0xA7C4, - 0xA7C5, - 0xA7C6, - 0xA7C7, - 0xA7C8, - 0xA7C9, - 0xA7CA, - 0xA7CB, - 0xA7CC, - 0xA7CD, - 0xA7CE, - 0xA7CF, - 0xA7D0, - 0xA7D1, - 0xA7D2, - 0xA7D3, - 0xA7D4, - 0xA7D5, - 0xA7D6, - 0xA7D7, - 0xA7D8, - 0xA7D9, - 0xA7DA, - 0xA7DB, - 0xA7DC, - 0xA7DD, - 0xA7DE, - 0xA7E2, - 0xA7E3, - 0xA7F1, - 0xA7F2, - 0xA7F3, - 0xA7F4, - 0xA7F5, - 0xA7F6, - 0xA7F8, - 0xA7F9, - 0xA7FA, - 0xA82D, - 0xA830, - 0xA83A, - 0xA840, - 0xA878, - 0xA880, - 0xA8C6, - 0xA8CE, - 0xA8DA, - 0xA8E0, - 0xA954, - 0xA95F, - 0xA97D, - 0xA980, - 0xA9CE, - 0xA9CF, - 0xA9DA, - 0xA9DE, - 0xA9FF, - 0xAA00, - 0xAA37, - 0xAA40, - 0xAA4E, - 0xAA50, - 0xAA5A, - 0xAA5C, - 0xAAC3, - 0xAADB, - 0xAAF7, - 0xAB01, - 0xAB07, - 0xAB09, - 0xAB0F, - 0xAB11, - 0xAB17, - 0xAB20, - 0xAB27, - 0xAB28, - 0xAB2F, - 0xAB30, - 0xAB5C, - 0xAB5D, - 0xAB5E, - 0xAB5F, - 0xAB60, - 0xAB69, - 0xAB6A, - 0xAB6C, - 0xAB6D, - 0xAB6E, - 0xAB70, - 0xAB71, - 0xAB72, - 0xAB73, - 0xAB74, - 0xAB75, - 0xAB76, - 0xAB77, - 0xAB78, - 0xAB79, - 0xAB7A, - 0xAB7B, - 0xAB7C, - 0xAB7D, - 0xAB7E, - 0xAB7F, - 0xAB80, - 0xAB81, - 0xAB82, - 0xAB83, - 0xAB84, - 0xAB85, - 0xAB86, - 0xAB87, - 0xAB88, - 0xAB89, - 0xAB8A, - 0xAB8B, - 0xAB8C, - 0xAB8D, - 0xAB8E, - 0xAB8F, - 0xAB90, - 0xAB91, - 0xAB92, - 0xAB93, - 0xAB94, - 0xAB95, - 0xAB96, - 0xAB97, - 0xAB98, - 0xAB99, - 0xAB9A, - 0xAB9B, - 0xAB9C, - 0xAB9D, - 0xAB9E, - 0xAB9F, - 0xABA0, - 0xABA1, - 0xABA2, - 0xABA3, - 0xABA4, - 0xABA5, - 0xABA6, - 0xABA7, - 0xABA8, - 0xABA9, - 0xABAA, - 0xABAB, - 0xABAC, - 0xABAD, - 0xABAE, - 0xABAF, - 0xABB0, - 0xABB1, - 0xABB2, - 0xABB3, - 0xABB4, - 0xABB5, - 0xABB6, - 0xABB7, - 0xABB8, - 0xABB9, - 0xABBA, - 0xABBB, - 0xABBC, - 0xABBD, - 0xABBE, - 0xABBF, - 0xABC0, - 0xABEE, - 0xABF0, - 0xABFA, - 0xAC00, - 0xD7A4, - 0xD7B0, - 0xD7C7, - 0xD7CB, - 0xD7FC, - 0xF900, - 0xF901, - 0xF902, - 0xF903, - 0xF904, - 0xF905, - 0xF906, - 0xF907, - 0xF909, - 0xF90A, - 0xF90B, - 0xF90C, - 0xF90D, - 0xF90E, - 0xF90F, - 0xF910, - 0xF911, - 0xF912, - 0xF913, - 0xF914, - 0xF915, - 0xF916, - 0xF917, - 0xF918, - 0xF919, - 0xF91A, - 0xF91B, - 0xF91C, - 0xF91D, - 0xF91E, - 0xF91F, - 0xF920, - 0xF921, - 0xF922, - 0xF923, - 0xF924, - 0xF925, - 0xF926, - 0xF927, - 0xF928, - 0xF929, - 0xF92A, - 0xF92B, - 0xF92C, - 0xF92D, - 0xF92E, - 0xF92F, - 0xF930, - 0xF931, - 0xF932, - 0xF933, - 0xF934, - 0xF935, - 0xF936, - 0xF937, - 0xF938, - 0xF939, - 0xF93A, - 0xF93B, - 0xF93C, - 0xF93D, - 0xF93E, - 0xF93F, - 0xF940, - 0xF941, - 0xF942, - 0xF943, - 0xF944, - 0xF945, - 0xF946, - 0xF947, - 0xF948, - 0xF949, - 0xF94A, - 0xF94B, - 0xF94C, - 0xF94D, - 0xF94E, - 0xF94F, - 0xF950, - 0xF951, - 0xF952, - 0xF953, - 0xF954, - 0xF955, - 0xF956, - 0xF957, - 0xF958, - 0xF959, - 0xF95A, - 0xF95B, - 0xF95C, - 0xF95D, - 0xF95E, - 0xF95F, - 0xF960, - 0xF961, - 0xF962, - 0xF963, - 0xF964, - 0xF965, - 0xF966, - 0xF967, - 0xF968, - 0xF969, - 0xF96A, - 0xF96B, - 0xF96C, - 0xF96D, - 0xF96E, - 0xF96F, - 0xF970, - 0xF971, - 0xF972, - 0xF973, - 0xF974, - 0xF975, - 0xF976, - 0xF977, - 0xF978, - 0xF979, - 0xF97A, - 0xF97B, - 0xF97C, - 0xF97D, - 0xF97E, - 0xF97F, - 0xF980, - 0xF981, - 0xF982, - 0xF983, - 0xF984, - 0xF985, - 0xF986, - 0xF987, - 0xF988, - 0xF989, - 0xF98A, - 0xF98B, - 0xF98C, - 0xF98D, - 0xF98E, - 0xF98F, - 0xF990, - 0xF991, - 0xF992, - 0xF993, - 0xF994, - 0xF995, - 0xF996, - 0xF997, - 0xF998, - 0xF999, - 0xF99A, - 0xF99B, - 0xF99C, - 0xF99D, - 0xF99E, - 0xF99F, - 0xF9A0, - 0xF9A1, - 0xF9A2, - 0xF9A3, - 0xF9A4, - 0xF9A5, - 0xF9A6, - 0xF9A7, - 0xF9A8, - 0xF9A9, - 0xF9AA, - 0xF9AB, - 0xF9AC, - 0xF9AD, - 0xF9AE, - 0xF9AF, - 0xF9B0, - 0xF9B1, - 0xF9B2, - 0xF9B3, - 0xF9B4, - 0xF9B5, - 0xF9B6, - 0xF9B7, - 0xF9B8, - 0xF9B9, - 0xF9BA, - 0xF9BB, - 0xF9BC, - 0xF9BD, - 0xF9BE, - 0xF9BF, - 0xF9C0, - 0xF9C1, - 0xF9C2, - 0xF9C3, - 0xF9C4, - 0xF9C5, - 0xF9C6, - 0xF9C7, - 0xF9C8, - 0xF9C9, - 0xF9CA, - 0xF9CB, - 0xF9CC, - 0xF9CD, - 0xF9CE, - 0xF9CF, - 0xF9D0, - 0xF9D1, - 0xF9D2, - 0xF9D3, - 0xF9D4, - 0xF9D5, - 0xF9D6, - 0xF9D7, - 0xF9D8, - 0xF9D9, - 0xF9DA, - 0xF9DB, - 0xF9DC, - 0xF9DD, - 0xF9DE, - 0xF9DF, - 0xF9E0, - 0xF9E1, - 0xF9E2, - 0xF9E3, - 0xF9E4, - 0xF9E5, - 0xF9E6, - 0xF9E7, - 0xF9E8, - 0xF9E9, - 0xF9EA, - 0xF9EB, - 0xF9EC, - 0xF9ED, - 0xF9EE, - 0xF9EF, - 0xF9F0, - 0xF9F1, - 0xF9F2, - 0xF9F3, - 0xF9F4, - 0xF9F5, - 0xF9F6, - 0xF9F7, - 0xF9F8, - 0xF9F9, - 0xF9FA, - 0xF9FB, - 0xF9FC, - 0xF9FD, - 0xF9FE, - 0xF9FF, - 0xFA00, - 0xFA01, - 0xFA02, - 0xFA03, - 0xFA04, - 0xFA05, - 0xFA06, - 0xFA07, - 0xFA08, - 0xFA09, - 0xFA0A, - 0xFA0B, - 0xFA0C, - 0xFA0D, - 0xFA0E, - 0xFA10, - 0xFA11, - 0xFA12, - 0xFA13, - 0xFA15, - 0xFA16, - 0xFA17, - 0xFA18, - 0xFA19, - 0xFA1A, - 0xFA1B, - 0xFA1C, - 0xFA1D, - 0xFA1E, - 0xFA1F, - 0xFA20, - 0xFA21, - 0xFA22, - 0xFA23, - 0xFA25, - 0xFA26, - 0xFA27, - 0xFA2A, - 0xFA2B, - 0xFA2C, - 0xFA2D, - 0xFA2E, - 0xFA2F, - 0xFA30, - 0xFA31, - 0xFA32, - 0xFA33, - 0xFA34, - 0xFA35, - 0xFA36, - 0xFA37, - 0xFA38, - 0xFA39, - 0xFA3A, - 0xFA3B, - 0xFA3C, - 0xFA3D, - 0xFA3E, - 0xFA3F, - 0xFA40, - 0xFA41, - 0xFA42, - 0xFA43, - 0xFA44, - 0xFA45, - 0xFA46, - 0xFA47, - 0xFA48, - 0xFA49, - 0xFA4A, - 0xFA4B, - 0xFA4C, - 0xFA4D, - 0xFA4E, - 0xFA4F, - 0xFA50, - 0xFA51, - 0xFA52, - 0xFA53, - 0xFA54, - 0xFA55, - 0xFA56, - 0xFA57, - 0xFA58, - 0xFA59, - 0xFA5A, - 0xFA5B, - 0xFA5C, - 0xFA5D, - 0xFA5F, - 0xFA60, - 0xFA61, - 0xFA62, - 0xFA63, - 0xFA64, - 0xFA65, - 0xFA66, - 0xFA67, - 0xFA68, - 0xFA69, - 0xFA6A, - 0xFA6B, - 0xFA6C, - 0xFA6D, - 0xFA6E, - 0xFA70, - 0xFA71, - 0xFA72, - 0xFA73, - 0xFA74, - 0xFA75, - 0xFA76, - 0xFA77, - 0xFA78, - 0xFA79, - 0xFA7A, - 0xFA7B, - 0xFA7C, - 0xFA7D, - 0xFA7E, - 0xFA7F, - 0xFA80, - 0xFA81, - 0xFA82, - 0xFA83, - 0xFA84, - 0xFA85, - 0xFA86, - 0xFA87, - 0xFA88, - 0xFA89, - 0xFA8A, - 0xFA8B, - 0xFA8C, - 0xFA8D, - 0xFA8E, - 0xFA8F, - 0xFA90, - 0xFA91, - 0xFA92, - 0xFA93, - 0xFA94, - 0xFA95, - 0xFA96, - 0xFA97, - 0xFA98, - 0xFA99, - 0xFA9A, - 0xFA9B, - 0xFA9C, - 0xFA9D, - 0xFA9E, - 0xFA9F, - 0xFAA0, - 0xFAA1, - 0xFAA2, - 0xFAA3, - 0xFAA4, - 0xFAA5, - 0xFAA6, - 0xFAA7, - 0xFAA8, - 0xFAA9, - 0xFAAA, - 0xFAAB, - 0xFAAC, - 0xFAAD, - 0xFAAE, - 0xFAAF, - 0xFAB0, - 0xFAB1, - 0xFAB2, - 0xFAB3, - 0xFAB4, - 0xFAB5, - 0xFAB6, - 0xFAB7, - 0xFAB8, - 0xFAB9, - 0xFABA, - 0xFABB, - 0xFABC, - 0xFABD, - 0xFABE, - 0xFABF, - 0xFAC0, - 0xFAC1, - 0xFAC2, - 0xFAC3, - 0xFAC4, - 0xFAC5, - 0xFAC6, - 0xFAC7, - 0xFAC8, - 0xFAC9, - 0xFACA, - 0xFACB, - 0xFACC, - 0xFACD, - 0xFACE, - 0xFACF, - 0xFAD0, - 0xFAD1, - 0xFAD2, - 0xFAD3, - 0xFAD4, - 0xFAD5, - 0xFAD6, - 0xFAD7, - 0xFAD8, - 0xFAD9, - 0xFADA, - 0xFB00, - 0xFB01, - 0xFB02, - 0xFB03, - 0xFB04, - 0xFB05, - 0xFB07, - 0xFB13, - 0xFB14, - 0xFB15, - 0xFB16, - 0xFB17, - 0xFB18, - 0xFB1D, - 0xFB1E, - 0xFB1F, - 0xFB20, - 0xFB21, - 0xFB22, - 0xFB23, - 0xFB24, - 0xFB25, - 0xFB26, - 0xFB27, - 0xFB28, - 0xFB29, - 0xFB2A, - 0xFB2B, - 0xFB2C, - 0xFB2D, - 0xFB2E, - 0xFB2F, - 0xFB30, - 0xFB31, - 0xFB32, - 0xFB33, - 0xFB34, - 0xFB35, - 0xFB36, - 0xFB37, - 0xFB38, - 0xFB39, - 0xFB3A, - 0xFB3B, - 0xFB3C, - 0xFB3D, - 0xFB3E, - 0xFB3F, - 0xFB40, - 0xFB41, - 0xFB42, - 0xFB43, - 0xFB44, - 0xFB45, - 0xFB46, - 0xFB47, - 0xFB48, - 0xFB49, - 0xFB4A, - 0xFB4B, - 0xFB4C, - 0xFB4D, - 0xFB4E, - 0xFB4F, - 0xFB50, - 0xFB52, - 0xFB56, - 0xFB5A, - 0xFB5E, - 0xFB62, - 0xFB66, - 0xFB6A, - 0xFB6E, - 0xFB72, - 0xFB76, - 0xFB7A, - 0xFB7E, - 0xFB82, - 0xFB84, - 0xFB86, - 0xFB88, - 0xFB8A, - 0xFB8C, - 0xFB8E, - 0xFB92, - 0xFB96, - 0xFB9A, - 0xFB9E, - 0xFBA0, - 0xFBA4, - 0xFBA6, - 0xFBAA, - 0xFBAE, - 0xFBB0, - 0xFBB2, - 0xFBD3, - 0xFBD7, - 0xFBD9, - 0xFBDB, - 0xFBDD, - 0xFBDE, - 0xFBE0, - 0xFBE2, - 0xFBE4, - 0xFBE8, - 0xFBEA, - 0xFBEC, - 0xFBEE, - 0xFBF0, - 0xFBF2, - 0xFBF4, - 0xFBF6, - 0xFBF9, - 0xFBFC, - 0xFC00, - 0xFC01, - 0xFC02, - 0xFC03, - 0xFC04, - 0xFC05, - 0xFC06, - 0xFC07, - 0xFC08, - 0xFC09, - 0xFC0A, - 0xFC0B, - 0xFC0C, - 0xFC0D, - 0xFC0E, - 0xFC0F, - 0xFC10, - 0xFC11, - 0xFC12, - 0xFC13, - 0xFC14, - 0xFC15, - 0xFC16, - 0xFC17, - 0xFC18, - 0xFC19, - 0xFC1A, - 0xFC1B, - 0xFC1C, - 0xFC1D, - 0xFC1E, - 0xFC1F, - 0xFC20, - 0xFC21, - 0xFC22, - 0xFC23, - 0xFC24, - 0xFC25, - 0xFC26, - 0xFC27, - 0xFC28, - 0xFC29, - 0xFC2A, - 0xFC2B, - 0xFC2C, - 0xFC2D, - 0xFC2E, - 0xFC2F, - 0xFC30, - 0xFC31, - 0xFC32, - 0xFC33, - 0xFC34, - 0xFC35, - 0xFC36, - 0xFC37, - 0xFC38, - 0xFC39, - 0xFC3A, - 0xFC3B, - 0xFC3C, - 0xFC3D, - 0xFC3E, - 0xFC3F, - 0xFC40, - 0xFC41, - 0xFC42, - 0xFC43, - 0xFC44, - 0xFC45, - 0xFC46, - 0xFC47, - 0xFC48, - 0xFC49, - 0xFC4A, - 0xFC4B, - 0xFC4C, - 0xFC4D, - 0xFC4E, - 0xFC4F, - 0xFC50, - 0xFC51, - 0xFC52, - 0xFC53, - 0xFC54, - 0xFC55, - 0xFC56, - 0xFC57, - 0xFC58, - 0xFC59, - 0xFC5A, - 0xFC5B, - 0xFC5C, - 0xFC5D, - 0xFC5E, - 0xFC5F, - 0xFC60, - 0xFC61, - 0xFC62, - 0xFC63, - 0xFC64, - 0xFC65, - 0xFC66, - 0xFC67, - 0xFC68, - 0xFC69, - 0xFC6A, - 0xFC6B, - 0xFC6C, - 0xFC6D, - 0xFC6E, - 0xFC6F, - 0xFC70, - 0xFC71, - 0xFC72, - 0xFC73, - 0xFC74, - 0xFC75, - 0xFC76, - 0xFC77, - 0xFC78, - 0xFC79, - 0xFC7A, - 0xFC7B, - 0xFC7C, - 0xFC7D, - 0xFC7E, - 0xFC7F, - 0xFC80, - 0xFC81, - 0xFC82, - 0xFC83, - 0xFC84, - 0xFC85, - 0xFC86, - 0xFC87, - 0xFC88, - 0xFC89, - 0xFC8A, - 0xFC8B, - 0xFC8C, - 0xFC8D, - 0xFC8E, - 0xFC8F, - 0xFC90, - 0xFC91, - 0xFC92, - 0xFC93, - 0xFC94, - 0xFC95, - 0xFC96, - 0xFC97, - 0xFC98, - 0xFC99, - 0xFC9A, - 0xFC9B, - 0xFC9C, - 0xFC9D, - 0xFC9E, - 0xFC9F, - 0xFCA0, - 0xFCA1, - 0xFCA2, - 0xFCA3, - 0xFCA4, - 0xFCA5, - 0xFCA6, - 0xFCA7, - 0xFCA8, - 0xFCA9, - 0xFCAA, - 0xFCAB, - 0xFCAC, - 0xFCAD, - 0xFCAE, - 0xFCAF, - 0xFCB0, - 0xFCB1, - 0xFCB2, - 0xFCB3, - 0xFCB4, - 0xFCB5, - 0xFCB6, - 0xFCB7, - 0xFCB8, - 0xFCB9, - 0xFCBA, - 0xFCBB, - 0xFCBC, - 0xFCBD, - 0xFCBE, - 0xFCBF, - 0xFCC0, - 0xFCC1, - 0xFCC2, - 0xFCC3, - 0xFCC4, - 0xFCC5, - 0xFCC6, - 0xFCC7, - 0xFCC8, - 0xFCC9, - 0xFCCA, - 0xFCCB, - 0xFCCC, - 0xFCCD, - 0xFCCE, - 0xFCCF, - 0xFCD0, - 0xFCD1, - 0xFCD2, - 0xFCD3, - 0xFCD4, - 0xFCD5, - 0xFCD6, - 0xFCD7, - 0xFCD8, - 0xFCD9, - 0xFCDA, - 0xFCDB, - 0xFCDC, - 0xFCDD, - 0xFCDE, - 0xFCDF, - 0xFCE0, - 0xFCE1, - 0xFCE2, - 0xFCE3, - 0xFCE4, - 0xFCE5, - 0xFCE6, - 0xFCE7, - 0xFCE8, - 0xFCE9, - 0xFCEA, - 0xFCEB, - 0xFCEC, - 0xFCED, - 0xFCEE, - 0xFCEF, - 0xFCF0, - 0xFCF1, - 0xFCF2, - 0xFCF3, - 0xFCF4, - 0xFCF5, - 0xFCF6, - 0xFCF7, - 0xFCF8, - 0xFCF9, - 0xFCFA, - 0xFCFB, - 0xFCFC, - 0xFCFD, - 0xFCFE, - 0xFCFF, - 0xFD00, - 0xFD01, - 0xFD02, - 0xFD03, - 0xFD04, - 0xFD05, - 0xFD06, - 0xFD07, - 0xFD08, - 0xFD09, - 0xFD0A, - 0xFD0B, - 0xFD0C, - 0xFD0D, - 0xFD0E, - 0xFD0F, - 0xFD10, - 0xFD11, - 0xFD12, - 0xFD13, - 0xFD14, - 0xFD15, - 0xFD16, - 0xFD17, - 0xFD18, - 0xFD19, - 0xFD1A, - 0xFD1B, - 0xFD1C, - 0xFD1D, - 0xFD1E, - 0xFD1F, - 0xFD20, - 0xFD21, - 0xFD22, - 0xFD23, - 0xFD24, - 0xFD25, - 0xFD26, - 0xFD27, - 0xFD28, - 0xFD29, - 0xFD2A, - 0xFD2B, - 0xFD2C, - 0xFD2D, - 0xFD2E, - 0xFD2F, - 0xFD30, - 0xFD31, - 0xFD32, - 0xFD33, - 0xFD34, - 0xFD35, - 0xFD36, - 0xFD37, - 0xFD38, - 0xFD39, - 0xFD3A, - 0xFD3B, - 0xFD3C, - 0xFD3E, - 0xFD50, - 0xFD51, - 0xFD53, - 0xFD54, - 0xFD55, - 0xFD56, - 0xFD57, - 0xFD58, - 0xFD5A, - 0xFD5B, - 0xFD5C, - 0xFD5D, - 0xFD5E, - 0xFD5F, - 0xFD61, - 0xFD62, - 0xFD64, - 0xFD66, - 0xFD67, - 0xFD69, - 0xFD6A, - 0xFD6C, - 0xFD6E, - 0xFD6F, - 0xFD71, - 0xFD73, - 0xFD74, - 0xFD75, - 0xFD76, - 0xFD78, - 0xFD79, - 0xFD7A, - 0xFD7B, - 0xFD7C, - 0xFD7E, - 0xFD7F, - 0xFD80, - 0xFD81, - 0xFD82, - 0xFD83, - 0xFD85, - 0xFD87, - 0xFD89, - 0xFD8A, - 0xFD8B, - 0xFD8C, - 0xFD8D, - 0xFD8E, - 0xFD8F, - 0xFD90, - 0xFD92, - 0xFD93, - 0xFD94, - 0xFD95, - 0xFD96, - 0xFD97, - 0xFD99, - 0xFD9A, - 0xFD9B, - 0xFD9C, - 0xFD9E, - 0xFD9F, - 0xFDA0, - 0xFDA1, - 0xFDA2, - 0xFDA3, - 0xFDA4, - 0xFDA5, - 0xFDA6, - 0xFDA7, - 0xFDA8, - 0xFDA9, - 0xFDAA, - 0xFDAB, - 0xFDAC, - 0xFDAD, - 0xFDAE, - 0xFDAF, - 0xFDB0, - 0xFDB1, - 0xFDB2, - 0xFDB3, - 0xFDB4, - 0xFDB5, - 0xFDB6, - 0xFDB7, - 0xFDB8, - 0xFDB9, - 0xFDBA, - 0xFDBB, - 0xFDBC, - 0xFDBD, - 0xFDBE, - 0xFDBF, - 0xFDC0, - 0xFDC1, - 0xFDC2, - 0xFDC3, - 0xFDC4, - 0xFDC5, - 0xFDC6, - 0xFDC7, - 0xFDC8, - 0xFDD0, - 0xFDF0, - 0xFDF1, - 0xFDF2, - 0xFDF3, - 0xFDF4, - 0xFDF5, - 0xFDF6, - 0xFDF7, - 0xFDF8, - 0xFDF9, - 0xFDFA, - 0xFDFB, - 0xFDFC, - 0xFDFD, - 0xFE00, - 0xFE10, - 0xFE11, - 0xFE12, - 0xFE13, - 0xFE14, - 0xFE15, - 0xFE16, - 0xFE17, - 0xFE18, - 0xFE19, - 0xFE20, - 0xFE30, - 0xFE31, - 0xFE32, - 0xFE33, - 0xFE35, - 0xFE36, - 0xFE37, - 0xFE38, - 0xFE39, - 0xFE3A, - 0xFE3B, - 0xFE3C, - 0xFE3D, - 0xFE3E, - 0xFE3F, - 0xFE40, - 0xFE41, - 0xFE42, - 0xFE43, - 0xFE44, - 0xFE45, - 0xFE47, - 0xFE48, - 0xFE49, - 0xFE4D, - 0xFE50, - 0xFE51, - 0xFE52, - 0xFE54, - 0xFE55, - 0xFE56, - 0xFE57, - 0xFE58, - 0xFE59, - 0xFE5A, - 0xFE5B, - 0xFE5C, - 0xFE5D, - 0xFE5E, - 0xFE5F, - 0xFE60, - 0xFE61, - 0xFE62, - 0xFE63, - 0xFE64, - 0xFE65, - 0xFE66, - 0xFE67, - 0xFE68, - 0xFE69, - 0xFE6A, - 0xFE6B, - 0xFE6C, - 0xFE70, - 0xFE71, - 0xFE72, - 0xFE73, - 0xFE74, - 0xFE75, - 0xFE76, - 0xFE77, - 0xFE78, - 0xFE79, - 0xFE7A, - 0xFE7B, - 0xFE7C, - 0xFE7D, - 0xFE7E, - 0xFE7F, - 0xFE80, - 0xFE81, - 0xFE83, - 0xFE85, - 0xFE87, - 0xFE89, - 0xFE8D, - 0xFE8F, - 0xFE93, - 0xFE95, - 0xFE99, - 0xFE9D, - 0xFEA1, - 0xFEA5, - 0xFEA9, - 0xFEAB, - 0xFEAD, - 0xFEAF, - 0xFEB1, - 0xFEB5, - 0xFEB9, - 0xFEBD, - 0xFEC1, - 0xFEC5, - 0xFEC9, - 0xFECD, - 0xFED1, - 0xFED5, - 0xFED9, - 0xFEDD, - 0xFEE1, - 0xFEE5, - 0xFEE9, - 0xFEED, - 0xFEEF, - 0xFEF1, - 0xFEF5, - 0xFEF7, - 0xFEF9, - 0xFEFB, - 0xFEFD, - 0xFEFF, - 0xFF00, - 0xFF01, - 0xFF02, - 0xFF03, - 0xFF04, - 0xFF05, - 0xFF06, - 0xFF07, - 0xFF08, - 0xFF09, - 0xFF0A, - 0xFF0B, - 0xFF0C, - 0xFF0D, - 0xFF0E, - 0xFF0F, - 0xFF10, - 0xFF11, - 0xFF12, - 0xFF13, - 0xFF14, - 0xFF15, - 0xFF16, - 0xFF17, - 0xFF18, - 0xFF19, - 0xFF1A, - 0xFF1B, - 0xFF1C, - 0xFF1D, - 0xFF1E, - 0xFF1F, - 0xFF20, - 0xFF21, - 0xFF22, - 0xFF23, - 0xFF24, - 0xFF25, - 0xFF26, - 0xFF27, - 0xFF28, - 0xFF29, - 0xFF2A, - 0xFF2B, - 0xFF2C, - 0xFF2D, - 0xFF2E, - 0xFF2F, - 0xFF30, - 0xFF31, - 0xFF32, - 0xFF33, - 0xFF34, - 0xFF35, - 0xFF36, - 0xFF37, - 0xFF38, - 0xFF39, - 0xFF3A, - 0xFF3B, - 0xFF3C, - 0xFF3D, - 0xFF3E, - 0xFF3F, - 0xFF40, - 0xFF41, - 0xFF42, - 0xFF43, - 0xFF44, - 0xFF45, - 0xFF46, - 0xFF47, - 0xFF48, - 0xFF49, - 0xFF4A, - 0xFF4B, - 0xFF4C, - 0xFF4D, - 0xFF4E, - 0xFF4F, - 0xFF50, - 0xFF51, - 0xFF52, - 0xFF53, - 0xFF54, - 0xFF55, - 0xFF56, - 0xFF57, - 0xFF58, - 0xFF59, - 0xFF5A, - 0xFF5B, - 0xFF5C, - 0xFF5D, - 0xFF5E, - 0xFF5F, - 0xFF60, - 0xFF61, - 0xFF62, - 0xFF63, - 0xFF64, - 0xFF65, - 0xFF66, - 0xFF67, - 0xFF68, - 0xFF69, - 0xFF6A, - 0xFF6B, - 0xFF6C, - 0xFF6D, - 0xFF6E, - 0xFF6F, - 0xFF70, - 0xFF71, - 0xFF72, - 0xFF73, - 0xFF74, - 0xFF75, - 0xFF76, - 0xFF77, - 0xFF78, - 0xFF79, - 0xFF7A, - 0xFF7B, - 0xFF7C, - 0xFF7D, - 0xFF7E, - 0xFF7F, - 0xFF80, - 0xFF81, - 0xFF82, - 0xFF83, - 0xFF84, - 0xFF85, - 0xFF86, - 0xFF87, - 0xFF88, - 0xFF89, - 0xFF8A, - 0xFF8B, - 0xFF8C, - 0xFF8D, - 0xFF8E, - 0xFF8F, - 0xFF90, - 0xFF91, - 0xFF92, - 0xFF93, - 0xFF94, - 0xFF95, - 0xFF96, - 0xFF97, - 0xFF98, - 0xFF99, - 0xFF9A, - 0xFF9B, - 0xFF9C, - 0xFF9D, - 0xFF9E, - 0xFF9F, - 0xFFA0, - 0xFFA1, - 0xFFA2, - 0xFFA3, - 0xFFA4, - 0xFFA5, - 0xFFA6, - 0xFFA7, - 0xFFA8, - 0xFFA9, - 0xFFAA, - 0xFFAB, - 0xFFAC, - 0xFFAD, - 0xFFAE, - 0xFFAF, - 0xFFB0, - 0xFFB1, - 0xFFB2, - 0xFFB3, - 0xFFB4, - 0xFFB5, - 0xFFB6, - 0xFFB7, - 0xFFB8, - 0xFFB9, - 0xFFBA, - 0xFFBB, - 0xFFBC, - 0xFFBD, - 0xFFBE, - 0xFFBF, - 0xFFC2, - 0xFFC3, - 0xFFC4, - 0xFFC5, - 0xFFC6, - 0xFFC7, - 0xFFC8, - 0xFFCA, - 0xFFCB, - 0xFFCC, - 0xFFCD, - 0xFFCE, - 0xFFCF, - 0xFFD0, - 0xFFD2, - 0xFFD3, - 0xFFD4, - 0xFFD5, - 0xFFD6, - 0xFFD7, - 0xFFD8, - 0xFFDA, - 0xFFDB, - 0xFFDC, - 0xFFDD, - 0xFFE0, - 0xFFE1, - 0xFFE2, - 0xFFE3, - 0xFFE4, - 0xFFE5, - 0xFFE6, - 0xFFE7, - 0xFFE8, - 0xFFE9, - 0xFFEA, - 0xFFEB, - 0xFFEC, - 0xFFED, - 0xFFEE, - 0xFFEF, - 0x10000, - 0x1000C, - 0x1000D, - 0x10027, - 0x10028, - 0x1003B, - 0x1003C, - 0x1003E, - 0x1003F, - 0x1004E, - 0x10050, - 0x1005E, - 0x10080, - 0x100FB, - 0x10100, - 0x10103, - 0x10107, - 0x10134, - 0x10137, - 0x1018F, - 0x10190, - 0x1019D, - 0x101A0, - 0x101A1, - 0x101D0, - 0x101FE, - 0x10280, - 0x1029D, - 0x102A0, - 0x102D1, - 0x102E0, - 0x102FC, - 0x10300, - 0x10324, - 0x1032D, - 0x1034B, - 0x10350, - 0x1037B, - 0x10380, - 0x1039E, - 0x1039F, - 0x103C4, - 0x103C8, - 0x103D6, - 0x10400, - 0x10401, - 0x10402, - 0x10403, - 0x10404, - 0x10405, - 0x10406, - 0x10407, - 0x10408, - 0x10409, - 0x1040A, - 0x1040B, - 0x1040C, - 0x1040D, - 0x1040E, - 0x1040F, - 0x10410, - 0x10411, - 0x10412, - 0x10413, - 0x10414, - 0x10415, - 0x10416, - 0x10417, - 0x10418, - 0x10419, - 0x1041A, - 0x1041B, - 0x1041C, - 0x1041D, - 0x1041E, - 0x1041F, - 0x10420, - 0x10421, - 0x10422, - 0x10423, - 0x10424, - 0x10425, - 0x10426, - 0x10427, - 0x10428, - 0x1049E, - 0x104A0, - 0x104AA, - 0x104B0, - 0x104B1, - 0x104B2, - 0x104B3, - 0x104B4, - 0x104B5, - 0x104B6, - 0x104B7, - 0x104B8, - 0x104B9, - 0x104BA, - 0x104BB, - 0x104BC, - 0x104BD, - 0x104BE, - 0x104BF, - 0x104C0, - 0x104C1, - 0x104C2, - 0x104C3, - 0x104C4, - 0x104C5, - 0x104C6, - 0x104C7, - 0x104C8, - 0x104C9, - 0x104CA, - 0x104CB, - 0x104CC, - 0x104CD, - 0x104CE, - 0x104CF, - 0x104D0, - 0x104D1, - 0x104D2, - 0x104D3, - 0x104D4, - 0x104D8, - 0x104FC, - 0x10500, - 0x10528, - 0x10530, - 0x10564, - 0x1056F, - 0x10570, - 0x10571, - 0x10572, - 0x10573, - 0x10574, - 0x10575, - 0x10576, - 0x10577, - 0x10578, - 0x10579, - 0x1057A, - 0x1057B, - 0x1057C, - 0x1057D, - 0x1057E, - 0x1057F, - 0x10580, - 0x10581, - 0x10582, - 0x10583, - 0x10584, - 0x10585, - 0x10586, - 0x10587, - 0x10588, - 0x10589, - 0x1058A, - 0x1058B, - 0x1058C, - 0x1058D, - 0x1058E, - 0x1058F, - 0x10590, - 0x10591, - 0x10592, - 0x10593, - 0x10594, - 0x10595, - 0x10596, - 0x10597, - 0x105A2, - 0x105A3, - 0x105B2, - 0x105B3, - 0x105BA, - 0x105BB, - 0x105BD, - 0x105C0, - 0x105F4, - 0x10600, - 0x10737, - 0x10740, - 0x10756, - 0x10760, - 0x10768, - 0x10780, - 0x10781, - 0x10782, - 0x10783, - 0x10784, - 0x10785, - 0x10786, - 0x10787, - 0x10788, - 0x10789, - 0x1078A, - 0x1078B, - 0x1078C, - 0x1078D, - 0x1078E, - 0x1078F, - 0x10790, - 0x10791, - 0x10792, - 0x10793, - 0x10794, - 0x10795, - 0x10796, - 0x10797, - 0x10798, - 0x10799, - 0x1079A, - 0x1079B, - 0x1079C, - 0x1079D, - 0x1079E, - 0x1079F, - 0x107A0, - 0x107A1, - 0x107A2, - 0x107A3, - 0x107A4, - 0x107A5, - 0x107A6, - 0x107A7, - 0x107A8, - 0x107A9, - 0x107AA, - 0x107AB, - 0x107AC, - 0x107AD, - 0x107AE, - 0x107AF, - 0x107B0, - 0x107B1, - 0x107B2, - 0x107B3, - 0x107B4, - 0x107B5, - 0x107B6, - 0x107B7, - 0x107B8, - 0x107B9, - 0x107BA, - 0x107BB, - 0x107BC, - 0x107BD, - 0x107BE, - 0x107BF, - 0x107C0, - 0x10800, - 0x10806, - 0x10808, - 0x10809, - 0x1080A, - 0x10836, - 0x10837, - 0x10839, - 0x1083C, - 0x1083D, - 0x1083F, - 0x10856, - 0x10857, - 0x1089F, - 0x108A7, - 0x108B0, - 0x108E0, - 0x108F3, - 0x108F4, - 0x108F6, - 0x108FB, - 0x1091C, - 0x1091F, - 0x1093A, - 0x1093F, - 0x1095A, - 0x10980, - 0x109B8, - 0x109BC, - 0x109D0, - 0x109D2, - 0x10A04, - 0x10A05, - 0x10A07, - 0x10A0C, - 0x10A14, - 0x10A15, - 0x10A18, - 0x10A19, - 0x10A36, - 0x10A38, - 0x10A3B, - 0x10A3F, - 0x10A49, - 0x10A50, - 0x10A59, - 0x10A60, - 0x10AA0, - 0x10AC0, - 0x10AE7, - 0x10AEB, - 0x10AF7, - 0x10B00, - 0x10B36, - 0x10B39, - 0x10B56, - 0x10B58, - 0x10B73, - 0x10B78, - 0x10B92, - 0x10B99, - 0x10B9D, - 0x10BA9, - 0x10BB0, - 0x10C00, - 0x10C49, - 0x10C80, - 0x10C81, - 0x10C82, - 0x10C83, - 0x10C84, - 0x10C85, - 0x10C86, - 0x10C87, - 0x10C88, - 0x10C89, - 0x10C8A, - 0x10C8B, - 0x10C8C, - 0x10C8D, - 0x10C8E, - 0x10C8F, - 0x10C90, - 0x10C91, - 0x10C92, - 0x10C93, - 0x10C94, - 0x10C95, - 0x10C96, - 0x10C97, - 0x10C98, - 0x10C99, - 0x10C9A, - 0x10C9B, - 0x10C9C, - 0x10C9D, - 0x10C9E, - 0x10C9F, - 0x10CA0, - 0x10CA1, - 0x10CA2, - 0x10CA3, - 0x10CA4, - 0x10CA5, - 0x10CA6, - 0x10CA7, - 0x10CA8, - 0x10CA9, - 0x10CAA, - 0x10CAB, - 0x10CAC, - 0x10CAD, - 0x10CAE, - 0x10CAF, - 0x10CB0, - 0x10CB1, - 0x10CB2, - 0x10CB3, - 0x10CC0, - 0x10CF3, - 0x10CFA, - 0x10D28, - 0x10D30, - 0x10D3A, - 0x10D40, - 0x10D50, - 0x10D51, - 0x10D52, - 0x10D53, - 0x10D54, - 0x10D55, - 0x10D56, - 0x10D57, - 0x10D58, - 0x10D59, - 0x10D5A, - 0x10D5B, - 0x10D5C, - 0x10D5D, - 0x10D5E, - 0x10D5F, - 0x10D60, - 0x10D61, - 0x10D62, - 0x10D63, - 0x10D64, - 0x10D65, - 0x10D66, - 0x10D69, - 0x10D86, - 0x10D8E, - 0x10D90, - 0x10E60, - 0x10E7F, - 0x10E80, - 0x10EAA, - 0x10EAB, - 0x10EAE, - 0x10EB0, - 0x10EB2, - 0x10EC2, - 0x10EC8, - 0x10EC9, - 0x10EEF, - 0x10EF0, - 0x10F28, - 0x10F30, - 0x10F5A, - 0x10F70, - 0x10F8A, - 0x10FB0, - 0x10FCC, - 0x10FE0, - 0x10FF7, - 0x11000, - 0x1104E, - 0x11052, - 0x11076, - 0x1107F, - 0x110BD, - 0x110BE, - 0x110C3, - 0x110D0, - 0x110E9, - 0x110F0, - 0x110FA, - 0x11100, - 0x11135, - 0x11136, - 0x11148, - 0x11150, - 0x11177, - 0x11180, - 0x111E0, - 0x111E1, - 0x111F5, - 0x11200, - 0x11212, - 0x11213, - 0x11242, - 0x11280, - 0x11287, - 0x11288, - 0x11289, - 0x1128A, - 0x1128E, - 0x1128F, - 0x1129E, - 0x1129F, - 0x112AA, - 0x112B0, - 0x112EB, - 0x112F0, - 0x112FA, - 0x11300, - 0x11304, - 0x11305, - 0x1130D, - 0x1130F, - 0x11311, - 0x11313, - 0x11329, - 0x1132A, - 0x11331, - 0x11332, - 0x11334, - 0x11335, - 0x1133A, - 0x1133B, - 0x11345, - 0x11347, - 0x11349, - 0x1134B, - 0x1134E, - 0x11350, - 0x11351, - 0x11357, - 0x11358, - 0x1135D, - 0x11364, - 0x11366, - 0x1136D, - 0x11370, - 0x11375, - 0x11380, - 0x1138A, - 0x1138B, - 0x1138C, - 0x1138E, - 0x1138F, - 0x11390, - 0x113B6, - 0x113B7, - 0x113C1, - 0x113C2, - 0x113C3, - 0x113C5, - 0x113C6, - 0x113C7, - 0x113CB, - 0x113CC, - 0x113D6, - 0x113D7, - 0x113D9, - 0x113E1, - 0x113E3, - 0x11400, - 0x1145C, - 0x1145D, - 0x11462, - 0x11480, - 0x114C8, - 0x114D0, - 0x114DA, - 0x11580, - 0x115B6, - 0x115B8, - 0x115DE, - 0x11600, - 0x11645, - 0x11650, - 0x1165A, - 0x11660, - 0x1166D, - 0x11680, - 0x116BA, - 0x116C0, - 0x116CA, - 0x116D0, - 0x116E4, - 0x11700, - 0x1171B, - 0x1171D, - 0x1172C, - 0x11730, - 0x11747, - 0x11800, - 0x1183C, - 0x118A0, - 0x118A1, - 0x118A2, - 0x118A3, - 0x118A4, - 0x118A5, - 0x118A6, - 0x118A7, - 0x118A8, - 0x118A9, - 0x118AA, - 0x118AB, - 0x118AC, - 0x118AD, - 0x118AE, - 0x118AF, - 0x118B0, - 0x118B1, - 0x118B2, - 0x118B3, - 0x118B4, - 0x118B5, - 0x118B6, - 0x118B7, - 0x118B8, - 0x118B9, - 0x118BA, - 0x118BB, - 0x118BC, - 0x118BD, - 0x118BE, - 0x118BF, - 0x118C0, - 0x118F3, - 0x118FF, - 0x11907, - 0x11909, - 0x1190A, - 0x1190C, - 0x11914, - 0x11915, - 0x11917, - 0x11918, - 0x11936, - 0x11937, - 0x11939, - 0x1193B, - 0x11947, - 0x11950, - 0x1195A, - 0x119A0, - 0x119A8, - 0x119AA, - 0x119D8, - 0x119DA, - 0x119E5, - 0x11A00, - 0x11A48, - 0x11A50, - 0x11AA3, - 0x11AB0, - 0x11AF9, - 0x11B00, - 0x11B0B, - 0x11B60, - 0x11B68, - 0x11BC0, - 0x11BE2, - 0x11BF0, - 0x11BFA, - 0x11C00, - 0x11C09, - 0x11C0A, - 0x11C37, - 0x11C38, - 0x11C46, - 0x11C50, - 0x11C6D, - 0x11C70, - 0x11C90, - 0x11C92, - 0x11CA8, - 0x11CA9, - 0x11CB7, - 0x11D00, - 0x11D07, - 0x11D08, - 0x11D0A, - 0x11D0B, - 0x11D37, - 0x11D3A, - 0x11D3B, - 0x11D3C, - 0x11D3E, - 0x11D3F, - 0x11D48, - 0x11D50, - 0x11D5A, - 0x11D60, - 0x11D66, - 0x11D67, - 0x11D69, - 0x11D6A, - 0x11D8F, - 0x11D90, - 0x11D92, - 0x11D93, - 0x11D99, - 0x11DA0, - 0x11DAA, - 0x11DB0, - 0x11DDC, - 0x11DE0, - 0x11DEA, - 0x11DF0, - 0x11DF2, - 0x11EE0, - 0x11EF9, - 0x11F00, - 0x11F11, - 0x11F12, - 0x11F3B, - 0x11F3E, - 0x11F5B, - 0x11FB0, - 0x11FB1, - 0x11FC0, - 0x11FF2, - 0x11FFF, - 0x1239A, - 0x12400, - 0x12544, - 0x12550, - 0x12687, - 0x12F90, - 0x12FF3, - 0x13000, - 0x13430, - 0x13440, - 0x13456, - 0x13460, - 0x143FB, - 0x14400, - 0x14647, - 0x16100, - 0x1613A, - 0x16800, - 0x16A39, - 0x16A40, - 0x16A5F, - 0x16A60, - 0x16A6A, - 0x16A6E, - 0x16ABF, - 0x16AC0, - 0x16ACA, - 0x16AD0, - 0x16AEE, - 0x16AF0, - 0x16AF6, - 0x16B00, - 0x16B46, - 0x16B50, - 0x16B5A, - 0x16B5B, - 0x16B62, - 0x16B63, - 0x16B78, - 0x16B7D, - 0x16B90, - 0x16D40, - 0x16D7A, - 0x16E40, - 0x16E41, - 0x16E42, - 0x16E43, - 0x16E44, - 0x16E45, - 0x16E46, - 0x16E47, - 0x16E48, - 0x16E49, - 0x16E4A, - 0x16E4B, - 0x16E4C, - 0x16E4D, - 0x16E4E, - 0x16E4F, - 0x16E50, - 0x16E51, - 0x16E52, - 0x16E53, - 0x16E54, - 0x16E55, - 0x16E56, - 0x16E57, - 0x16E58, - 0x16E59, - 0x16E5A, - 0x16E5B, - 0x16E5C, - 0x16E5D, - 0x16E5E, - 0x16E5F, - 0x16E60, - 0x16E9B, - 0x16EA0, - 0x16EA1, - 0x16EA2, - 0x16EA3, - 0x16EA4, - 0x16EA5, - 0x16EA6, - 0x16EA7, - 0x16EA8, - 0x16EA9, - 0x16EAA, - 0x16EAB, - 0x16EAC, - 0x16EAD, - 0x16EAE, - 0x16EAF, - 0x16EB0, - 0x16EB1, - 0x16EB2, - 0x16EB3, - 0x16EB4, - 0x16EB5, - 0x16EB6, - 0x16EB7, - 0x16EB8, - 0x16EB9, - 0x16EBB, - 0x16ED4, - 0x16F00, - 0x16F4B, - 0x16F4F, - 0x16F88, - 0x16F8F, - 0x16FA0, - 0x16FE0, - 0x16FE5, - 0x16FF0, - 0x16FF7, - 0x17000, - 0x18CDB, - 0x18CFF, - 0x18D21, - 0x18D80, - 0x18DF3, - 0x18E00, - 0x19192, - 0x191A0, - 0x191D3, - 0x1AFF0, - 0x1AFF4, - 0x1AFF5, - 0x1AFFC, - 0x1AFFD, - 0x1AFFF, - 0x1B000, - 0x1B123, - 0x1B124, - 0x1B125, - 0x1B126, - 0x1B127, - 0x1B129, - 0x1B132, - 0x1B133, - 0x1B150, - 0x1B153, - 0x1B155, - 0x1B156, - 0x1B164, - 0x1B169, - 0x1B170, - 0x1B2FC, - 0x1BC00, - 0x1BC6B, - 0x1BC70, - 0x1BC7D, - 0x1BC80, - 0x1BC89, - 0x1BC90, - 0x1BC9A, - 0x1BC9C, - 0x1BCA0, - 0x1BCA4, - 0x1CC00, - 0x1CCD6, - 0x1CCD7, - 0x1CCD8, - 0x1CCD9, - 0x1CCDA, - 0x1CCDB, - 0x1CCDC, - 0x1CCDD, - 0x1CCDE, - 0x1CCDF, - 0x1CCE0, - 0x1CCE1, - 0x1CCE2, - 0x1CCE3, - 0x1CCE4, - 0x1CCE5, - 0x1CCE6, - 0x1CCE7, - 0x1CCE8, - 0x1CCE9, - 0x1CCEA, - 0x1CCEB, - 0x1CCEC, - 0x1CCED, - 0x1CCEE, - 0x1CCEF, - 0x1CCF0, - 0x1CCF1, - 0x1CCF2, - 0x1CCF3, - 0x1CCF4, - 0x1CCF5, - 0x1CCF6, - 0x1CCF7, - 0x1CCF8, - 0x1CCF9, - 0x1CCFA, - 0x1CCFD, - 0x1CD00, - 0x1CEB4, - 0x1CEBA, - 0x1CED1, - 0x1CED2, - 0x1CED5, - 0x1CEDD, - 0x1CEFE, - 0x1CF00, - 0x1CF2E, - 0x1CF30, - 0x1CF47, - 0x1CF50, - 0x1CFC4, - 0x1D000, - 0x1D0F6, - 0x1D100, - 0x1D15E, - 0x1D15F, - 0x1D160, - 0x1D161, - 0x1D162, - 0x1D163, - 0x1D164, - 0x1D165, - 0x1D173, - 0x1D17B, - 0x1D1BB, - 0x1D1BC, - 0x1D1BD, - 0x1D1BE, - 0x1D1BF, - 0x1D1C0, - 0x1D1C1, - 0x1D246, - 0x1D250, - 0x1D282, - 0x1D2C0, - 0x1D2D4, - 0x1D2E0, - 0x1D2F4, - 0x1D300, - 0x1D357, - 0x1D360, - 0x1D379, - 0x1D400, - 0x1D401, - 0x1D402, - 0x1D403, - 0x1D404, - 0x1D405, - 0x1D406, - 0x1D407, - 0x1D408, - 0x1D409, - 0x1D40A, - 0x1D40B, - 0x1D40C, - 0x1D40D, - 0x1D40E, - 0x1D40F, - 0x1D410, - 0x1D411, - 0x1D412, - 0x1D413, - 0x1D414, - 0x1D415, - 0x1D416, - 0x1D417, - 0x1D418, - 0x1D419, - 0x1D41A, - 0x1D41B, - 0x1D41C, - 0x1D41D, - 0x1D41E, - 0x1D41F, - 0x1D420, - 0x1D421, - 0x1D422, - 0x1D423, - 0x1D424, - 0x1D425, - 0x1D426, - 0x1D427, - 0x1D428, - 0x1D429, - 0x1D42A, - 0x1D42B, - 0x1D42C, - 0x1D42D, - 0x1D42E, - 0x1D42F, - 0x1D430, - 0x1D431, - 0x1D432, - 0x1D433, - 0x1D434, - 0x1D435, - 0x1D436, - 0x1D437, - 0x1D438, - 0x1D439, - 0x1D43A, - 0x1D43B, - 0x1D43C, - 0x1D43D, - 0x1D43E, - 0x1D43F, - 0x1D440, - 0x1D441, - 0x1D442, - 0x1D443, - 0x1D444, - 0x1D445, - 0x1D446, - 0x1D447, - 0x1D448, - 0x1D449, - 0x1D44A, - 0x1D44B, - 0x1D44C, - 0x1D44D, - 0x1D44E, - 0x1D44F, - 0x1D450, - 0x1D451, - 0x1D452, - 0x1D453, - 0x1D454, - 0x1D455, - 0x1D456, - 0x1D457, - 0x1D458, - 0x1D459, - 0x1D45A, - 0x1D45B, - 0x1D45C, - 0x1D45D, - 0x1D45E, - 0x1D45F, - 0x1D460, - 0x1D461, - 0x1D462, - 0x1D463, - 0x1D464, - 0x1D465, - 0x1D466, - 0x1D467, - 0x1D468, - 0x1D469, - 0x1D46A, - 0x1D46B, - 0x1D46C, - 0x1D46D, - 0x1D46E, - 0x1D46F, - 0x1D470, - 0x1D471, - 0x1D472, - 0x1D473, - 0x1D474, - 0x1D475, - 0x1D476, - 0x1D477, - 0x1D478, - 0x1D479, - 0x1D47A, - 0x1D47B, - 0x1D47C, - 0x1D47D, - 0x1D47E, - 0x1D47F, - 0x1D480, - 0x1D481, - 0x1D482, - 0x1D483, - 0x1D484, - 0x1D485, - 0x1D486, - 0x1D487, - 0x1D488, - 0x1D489, - 0x1D48A, - 0x1D48B, - 0x1D48C, - 0x1D48D, - 0x1D48E, - 0x1D48F, - 0x1D490, - 0x1D491, - 0x1D492, - 0x1D493, - 0x1D494, - 0x1D495, - 0x1D496, - 0x1D497, - 0x1D498, - 0x1D499, - 0x1D49A, - 0x1D49B, - 0x1D49C, - 0x1D49D, - 0x1D49E, - 0x1D49F, - 0x1D4A0, - 0x1D4A2, - 0x1D4A3, - 0x1D4A5, - 0x1D4A6, - 0x1D4A7, - 0x1D4A9, - 0x1D4AA, - 0x1D4AB, - 0x1D4AC, - 0x1D4AD, - 0x1D4AE, - 0x1D4AF, - 0x1D4B0, - 0x1D4B1, - 0x1D4B2, - 0x1D4B3, - 0x1D4B4, - 0x1D4B5, - 0x1D4B6, - 0x1D4B7, - 0x1D4B8, - 0x1D4B9, - 0x1D4BA, - 0x1D4BB, - 0x1D4BC, - 0x1D4BD, - 0x1D4BE, - 0x1D4BF, - 0x1D4C0, - 0x1D4C1, - 0x1D4C2, - 0x1D4C3, - 0x1D4C4, - 0x1D4C5, - 0x1D4C6, - 0x1D4C7, - 0x1D4C8, - 0x1D4C9, - 0x1D4CA, - 0x1D4CB, - 0x1D4CC, - 0x1D4CD, - 0x1D4CE, - 0x1D4CF, - 0x1D4D0, - 0x1D4D1, - 0x1D4D2, - 0x1D4D3, - 0x1D4D4, - 0x1D4D5, - 0x1D4D6, - 0x1D4D7, - 0x1D4D8, - 0x1D4D9, - 0x1D4DA, - 0x1D4DB, - 0x1D4DC, - 0x1D4DD, - 0x1D4DE, - 0x1D4DF, - 0x1D4E0, - 0x1D4E1, - 0x1D4E2, - 0x1D4E3, - 0x1D4E4, - 0x1D4E5, - 0x1D4E6, - 0x1D4E7, - 0x1D4E8, - 0x1D4E9, - 0x1D4EA, - 0x1D4EB, - 0x1D4EC, - 0x1D4ED, - 0x1D4EE, - 0x1D4EF, - 0x1D4F0, - 0x1D4F1, - 0x1D4F2, - 0x1D4F3, - 0x1D4F4, - 0x1D4F5, - 0x1D4F6, - 0x1D4F7, - 0x1D4F8, - 0x1D4F9, - 0x1D4FA, - 0x1D4FB, - 0x1D4FC, - 0x1D4FD, - 0x1D4FE, - 0x1D4FF, - 0x1D500, - 0x1D501, - 0x1D502, - 0x1D503, - 0x1D504, - 0x1D505, - 0x1D506, - 0x1D507, - 0x1D508, - 0x1D509, - 0x1D50A, - 0x1D50B, - 0x1D50D, - 0x1D50E, - 0x1D50F, - 0x1D510, - 0x1D511, - 0x1D512, - 0x1D513, - 0x1D514, - 0x1D515, - 0x1D516, - 0x1D517, - 0x1D518, - 0x1D519, - 0x1D51A, - 0x1D51B, - 0x1D51C, - 0x1D51D, - 0x1D51E, - 0x1D51F, - 0x1D520, - 0x1D521, - 0x1D522, - 0x1D523, - 0x1D524, - 0x1D525, - 0x1D526, - 0x1D527, - 0x1D528, - 0x1D529, - 0x1D52A, - 0x1D52B, - 0x1D52C, - 0x1D52D, - 0x1D52E, - 0x1D52F, - 0x1D530, - 0x1D531, - 0x1D532, - 0x1D533, - 0x1D534, - 0x1D535, - 0x1D536, - 0x1D537, - 0x1D538, - 0x1D539, - 0x1D53A, - 0x1D53B, - 0x1D53C, - 0x1D53D, - 0x1D53E, - 0x1D53F, - 0x1D540, - 0x1D541, - 0x1D542, - 0x1D543, - 0x1D544, - 0x1D545, - 0x1D546, - 0x1D547, - 0x1D54A, - 0x1D54B, - 0x1D54C, - 0x1D54D, - 0x1D54E, - 0x1D54F, - 0x1D550, - 0x1D551, - 0x1D552, - 0x1D553, - 0x1D554, - 0x1D555, - 0x1D556, - 0x1D557, - 0x1D558, - 0x1D559, - 0x1D55A, - 0x1D55B, - 0x1D55C, - 0x1D55D, - 0x1D55E, - 0x1D55F, - 0x1D560, - 0x1D561, - 0x1D562, - 0x1D563, - 0x1D564, - 0x1D565, - 0x1D566, - 0x1D567, - 0x1D568, - 0x1D569, - 0x1D56A, - 0x1D56B, - 0x1D56C, - 0x1D56D, - 0x1D56E, - 0x1D56F, - 0x1D570, - 0x1D571, - 0x1D572, - 0x1D573, - 0x1D574, - 0x1D575, - 0x1D576, - 0x1D577, - 0x1D578, - 0x1D579, - 0x1D57A, - 0x1D57B, - 0x1D57C, - 0x1D57D, - 0x1D57E, - 0x1D57F, - 0x1D580, - 0x1D581, - 0x1D582, - 0x1D583, - 0x1D584, - 0x1D585, - 0x1D586, - 0x1D587, - 0x1D588, - 0x1D589, - 0x1D58A, - 0x1D58B, - 0x1D58C, - 0x1D58D, - 0x1D58E, - 0x1D58F, - 0x1D590, - 0x1D591, - 0x1D592, - 0x1D593, - 0x1D594, - 0x1D595, - 0x1D596, - 0x1D597, - 0x1D598, - 0x1D599, - 0x1D59A, - 0x1D59B, - 0x1D59C, - 0x1D59D, - 0x1D59E, - 0x1D59F, - 0x1D5A0, - 0x1D5A1, - 0x1D5A2, - 0x1D5A3, - 0x1D5A4, - 0x1D5A5, - 0x1D5A6, - 0x1D5A7, - 0x1D5A8, - 0x1D5A9, - 0x1D5AA, - 0x1D5AB, - 0x1D5AC, - 0x1D5AD, - 0x1D5AE, - 0x1D5AF, - 0x1D5B0, - 0x1D5B1, - 0x1D5B2, - 0x1D5B3, - 0x1D5B4, - 0x1D5B5, - 0x1D5B6, - 0x1D5B7, - 0x1D5B8, - 0x1D5B9, - 0x1D5BA, - 0x1D5BB, - 0x1D5BC, - 0x1D5BD, - 0x1D5BE, - 0x1D5BF, - 0x1D5C0, - 0x1D5C1, - 0x1D5C2, - 0x1D5C3, - 0x1D5C4, - 0x1D5C5, - 0x1D5C6, - 0x1D5C7, - 0x1D5C8, - 0x1D5C9, - 0x1D5CA, - 0x1D5CB, - 0x1D5CC, - 0x1D5CD, - 0x1D5CE, - 0x1D5CF, - 0x1D5D0, - 0x1D5D1, - 0x1D5D2, - 0x1D5D3, - 0x1D5D4, - 0x1D5D5, - 0x1D5D6, - 0x1D5D7, - 0x1D5D8, - 0x1D5D9, - 0x1D5DA, - 0x1D5DB, - 0x1D5DC, - 0x1D5DD, - 0x1D5DE, - 0x1D5DF, - 0x1D5E0, - 0x1D5E1, - 0x1D5E2, - 0x1D5E3, - 0x1D5E4, - 0x1D5E5, - 0x1D5E6, - 0x1D5E7, - 0x1D5E8, - 0x1D5E9, - 0x1D5EA, - 0x1D5EB, - 0x1D5EC, - 0x1D5ED, - 0x1D5EE, - 0x1D5EF, - 0x1D5F0, - 0x1D5F1, - 0x1D5F2, - 0x1D5F3, - 0x1D5F4, - 0x1D5F5, - 0x1D5F6, - 0x1D5F7, - 0x1D5F8, - 0x1D5F9, - 0x1D5FA, - 0x1D5FB, - 0x1D5FC, - 0x1D5FD, - 0x1D5FE, - 0x1D5FF, - 0x1D600, - 0x1D601, - 0x1D602, - 0x1D603, - 0x1D604, - 0x1D605, - 0x1D606, - 0x1D607, - 0x1D608, - 0x1D609, - 0x1D60A, - 0x1D60B, - 0x1D60C, - 0x1D60D, - 0x1D60E, - 0x1D60F, - 0x1D610, - 0x1D611, - 0x1D612, - 0x1D613, - 0x1D614, - 0x1D615, - 0x1D616, - 0x1D617, - 0x1D618, - 0x1D619, - 0x1D61A, - 0x1D61B, - 0x1D61C, - 0x1D61D, - 0x1D61E, - 0x1D61F, - 0x1D620, - 0x1D621, - 0x1D622, - 0x1D623, - 0x1D624, - 0x1D625, - 0x1D626, - 0x1D627, - 0x1D628, - 0x1D629, - 0x1D62A, - 0x1D62B, - 0x1D62C, - 0x1D62D, - 0x1D62E, - 0x1D62F, - 0x1D630, - 0x1D631, - 0x1D632, - 0x1D633, - 0x1D634, - 0x1D635, - 0x1D636, - 0x1D637, - 0x1D638, - 0x1D639, - 0x1D63A, - 0x1D63B, - 0x1D63C, - 0x1D63D, - 0x1D63E, - 0x1D63F, - 0x1D640, - 0x1D641, - 0x1D642, - 0x1D643, - 0x1D644, - 0x1D645, - 0x1D646, - 0x1D647, - 0x1D648, - 0x1D649, - 0x1D64A, - 0x1D64B, - 0x1D64C, - 0x1D64D, - 0x1D64E, - 0x1D64F, - 0x1D650, - 0x1D651, - 0x1D652, - 0x1D653, - 0x1D654, - 0x1D655, - 0x1D656, - 0x1D657, - 0x1D658, - 0x1D659, - 0x1D65A, - 0x1D65B, - 0x1D65C, - 0x1D65D, - 0x1D65E, - 0x1D65F, - 0x1D660, - 0x1D661, - 0x1D662, - 0x1D663, - 0x1D664, - 0x1D665, - 0x1D666, - 0x1D667, - 0x1D668, - 0x1D669, - 0x1D66A, - 0x1D66B, - 0x1D66C, - 0x1D66D, - 0x1D66E, - 0x1D66F, - 0x1D670, - 0x1D671, - 0x1D672, - 0x1D673, - 0x1D674, - 0x1D675, - 0x1D676, - 0x1D677, - 0x1D678, - 0x1D679, - 0x1D67A, - 0x1D67B, - 0x1D67C, - 0x1D67D, - 0x1D67E, - 0x1D67F, - 0x1D680, - 0x1D681, - 0x1D682, - 0x1D683, - 0x1D684, - 0x1D685, - 0x1D686, - 0x1D687, - 0x1D688, - 0x1D689, - 0x1D68A, - 0x1D68B, - 0x1D68C, - 0x1D68D, - 0x1D68E, - 0x1D68F, - 0x1D690, - 0x1D691, - 0x1D692, - 0x1D693, - 0x1D694, - 0x1D695, - 0x1D696, - 0x1D697, - 0x1D698, - 0x1D699, - 0x1D69A, - 0x1D69B, - 0x1D69C, - 0x1D69D, - 0x1D69E, - 0x1D69F, - 0x1D6A0, - 0x1D6A1, - 0x1D6A2, - 0x1D6A3, - 0x1D6A4, - 0x1D6A5, - 0x1D6A6, - 0x1D6A7, - 0x1D6A8, - 0x1D6A9, - 0x1D6AA, - 0x1D6AB, - 0x1D6AC, - 0x1D6AD, - 0x1D6AE, - 0x1D6AF, - 0x1D6B0, - 0x1D6B1, - 0x1D6B2, - 0x1D6B3, - 0x1D6B4, - 0x1D6B5, - 0x1D6B6, - 0x1D6B7, - 0x1D6B8, - 0x1D6B9, - 0x1D6BA, - 0x1D6BB, - 0x1D6BC, - 0x1D6BD, - 0x1D6BE, - 0x1D6BF, - 0x1D6C0, - 0x1D6C1, - 0x1D6C2, - 0x1D6C3, - 0x1D6C4, - 0x1D6C5, - 0x1D6C6, - 0x1D6C7, - 0x1D6C8, - 0x1D6C9, - 0x1D6CA, - 0x1D6CB, - 0x1D6CC, - 0x1D6CD, - 0x1D6CE, - 0x1D6CF, - 0x1D6D0, - 0x1D6D1, - 0x1D6D2, - 0x1D6D3, - 0x1D6D5, - 0x1D6D6, - 0x1D6D7, - 0x1D6D8, - 0x1D6D9, - 0x1D6DA, - 0x1D6DB, - 0x1D6DC, - 0x1D6DD, - 0x1D6DE, - 0x1D6DF, - 0x1D6E0, - 0x1D6E1, - 0x1D6E2, - 0x1D6E3, - 0x1D6E4, - 0x1D6E5, - 0x1D6E6, - 0x1D6E7, - 0x1D6E8, - 0x1D6E9, - 0x1D6EA, - 0x1D6EB, - 0x1D6EC, - 0x1D6ED, - 0x1D6EE, - 0x1D6EF, - 0x1D6F0, - 0x1D6F1, - 0x1D6F2, - 0x1D6F3, - 0x1D6F4, - 0x1D6F5, - 0x1D6F6, - 0x1D6F7, - 0x1D6F8, - 0x1D6F9, - 0x1D6FA, - 0x1D6FB, - 0x1D6FC, - 0x1D6FD, - 0x1D6FE, - 0x1D6FF, - 0x1D700, - 0x1D701, - 0x1D702, - 0x1D703, - 0x1D704, - 0x1D705, - 0x1D706, - 0x1D707, - 0x1D708, - 0x1D709, - 0x1D70A, - 0x1D70B, - 0x1D70C, - 0x1D70D, - 0x1D70F, - 0x1D710, - 0x1D711, - 0x1D712, - 0x1D713, - 0x1D714, - 0x1D715, - 0x1D716, - 0x1D717, - 0x1D718, - 0x1D719, - 0x1D71A, - 0x1D71B, - 0x1D71C, - 0x1D71D, - 0x1D71E, - 0x1D71F, - 0x1D720, - 0x1D721, - 0x1D722, - 0x1D723, - 0x1D724, - 0x1D725, - 0x1D726, - 0x1D727, - 0x1D728, - 0x1D729, - 0x1D72A, - 0x1D72B, - 0x1D72C, - 0x1D72D, - 0x1D72E, - 0x1D72F, - 0x1D730, - 0x1D731, - 0x1D732, - 0x1D733, - 0x1D734, - 0x1D735, - 0x1D736, - 0x1D737, - 0x1D738, - 0x1D739, - 0x1D73A, - 0x1D73B, - 0x1D73C, - 0x1D73D, - 0x1D73E, - 0x1D73F, - 0x1D740, - 0x1D741, - 0x1D742, - 0x1D743, - 0x1D744, - 0x1D745, - 0x1D746, - 0x1D747, - 0x1D749, - 0x1D74A, - 0x1D74B, - 0x1D74C, - 0x1D74D, - 0x1D74E, - 0x1D74F, - 0x1D750, - 0x1D751, - 0x1D752, - 0x1D753, - 0x1D754, - 0x1D755, - 0x1D756, - 0x1D757, - 0x1D758, - 0x1D759, - 0x1D75A, - 0x1D75B, - 0x1D75C, - 0x1D75D, - 0x1D75E, - 0x1D75F, - 0x1D760, - 0x1D761, - 0x1D762, - 0x1D763, - 0x1D764, - 0x1D765, - 0x1D766, - 0x1D767, - 0x1D768, - 0x1D769, - 0x1D76A, - 0x1D76B, - 0x1D76C, - 0x1D76D, - 0x1D76E, - 0x1D76F, - 0x1D770, - 0x1D771, - 0x1D772, - 0x1D773, - 0x1D774, - 0x1D775, - 0x1D776, - 0x1D777, - 0x1D778, - 0x1D779, - 0x1D77A, - 0x1D77B, - 0x1D77C, - 0x1D77D, - 0x1D77E, - 0x1D77F, - 0x1D780, - 0x1D781, - 0x1D783, - 0x1D784, - 0x1D785, - 0x1D786, - 0x1D787, - 0x1D788, - 0x1D789, - 0x1D78A, - 0x1D78B, - 0x1D78C, - 0x1D78D, - 0x1D78E, - 0x1D78F, - 0x1D790, - 0x1D791, - 0x1D792, - 0x1D793, - 0x1D794, - 0x1D795, - 0x1D796, - 0x1D797, - 0x1D798, - 0x1D799, - 0x1D79A, - 0x1D79B, - 0x1D79C, - 0x1D79D, - 0x1D79E, - 0x1D79F, - 0x1D7A0, - 0x1D7A1, - 0x1D7A2, - 0x1D7A3, - 0x1D7A4, - 0x1D7A5, - 0x1D7A6, - 0x1D7A7, - 0x1D7A8, - 0x1D7A9, - 0x1D7AA, - 0x1D7AB, - 0x1D7AC, - 0x1D7AD, - 0x1D7AE, - 0x1D7AF, - 0x1D7B0, - 0x1D7B1, - 0x1D7B2, - 0x1D7B3, - 0x1D7B4, - 0x1D7B5, - 0x1D7B6, - 0x1D7B7, - 0x1D7B8, - 0x1D7B9, - 0x1D7BA, - 0x1D7BB, - 0x1D7BD, - 0x1D7BE, - 0x1D7BF, - 0x1D7C0, - 0x1D7C1, - 0x1D7C2, - 0x1D7C3, - 0x1D7C4, - 0x1D7C5, - 0x1D7C6, - 0x1D7C7, - 0x1D7C8, - 0x1D7C9, - 0x1D7CA, - 0x1D7CC, - 0x1D7CE, - 0x1D7CF, - 0x1D7D0, - 0x1D7D1, - 0x1D7D2, - 0x1D7D3, - 0x1D7D4, - 0x1D7D5, - 0x1D7D6, - 0x1D7D7, - 0x1D7D8, - 0x1D7D9, - 0x1D7DA, - 0x1D7DB, - 0x1D7DC, - 0x1D7DD, - 0x1D7DE, - 0x1D7DF, - 0x1D7E0, - 0x1D7E1, - 0x1D7E2, - 0x1D7E3, - 0x1D7E4, - 0x1D7E5, - 0x1D7E6, - 0x1D7E7, - 0x1D7E8, - 0x1D7E9, - 0x1D7EA, - 0x1D7EB, - 0x1D7EC, - 0x1D7ED, - 0x1D7EE, - 0x1D7EF, - 0x1D7F0, - 0x1D7F1, - 0x1D7F2, - 0x1D7F3, - 0x1D7F4, - 0x1D7F5, - 0x1D7F6, - 0x1D7F7, - 0x1D7F8, - 0x1D7F9, - 0x1D7FA, - 0x1D7FB, - 0x1D7FC, - 0x1D7FD, - 0x1D7FE, - 0x1D7FF, - 0x1D800, - 0x1DA8C, - 0x1DA9B, - 0x1DAA0, - 0x1DAA1, - 0x1DAB0, - 0x1DB00, - 0x1DB1D, - 0x1DF00, - 0x1DF40, - 0x1DF41, - 0x1DF48, - 0x1DF49, - 0x1DF4A, - 0x1DF4B, - 0x1DF4D, - 0x1DF4E, - 0x1DF51, - 0x1DF52, - 0x1DF68, - 0x1DF69, - 0x1DF6A, - 0x1DF6B, - 0x1DF6C, - 0x1DF6D, - 0x1DF6E, - 0x1DF6F, - 0x1DF72, - 0x1DF73, - 0x1DF74, - 0x1DF75, - 0x1DF76, - 0x1DF77, - 0x1DF78, - 0x1DF79, - 0x1DF7A, - 0x1DF7B, - 0x1DF7C, - 0x1DF7D, - 0x1DF7E, - 0x1DF7F, - 0x1DF82, - 0x1DF90, - 0x1DF95, - 0x1DF96, - 0x1DF97, - 0x1DFCD, - 0x1DFCE, - 0x1DFCF, - 0x1DFD0, - 0x1DFD1, - 0x1DFD2, - 0x1DFD3, - 0x1DFD4, - 0x1DFD5, - 0x1DFD6, - 0x1DFD7, - 0x1DFD8, - 0x1DFD9, - 0x1DFDA, - 0x1DFDB, - 0x1DFDC, - 0x1DFDD, - 0x1DFDE, - 0x1DFDF, - 0x1DFE0, - 0x1DFE1, - 0x1DFE2, - 0x1DFE3, - 0x1DFE4, - 0x1DFE5, - 0x1DFE6, - 0x1DFE7, - 0x1DFE8, - 0x1DFE9, - 0x1DFEA, - 0x1DFEB, - 0x1DFEC, - 0x1DFED, - 0x1DFEE, - 0x1DFEF, - 0x1DFF0, - 0x1DFF1, - 0x1DFF2, - 0x1DFF3, - 0x1DFF4, - 0x1DFF5, - 0x1DFF6, - 0x1DFF7, - 0x1DFF8, - 0x1DFF9, - 0x1DFFA, - 0x1DFFB, - 0x1DFFC, - 0x1DFFD, - 0x1DFFE, - 0x1DFFF, - 0x1E000, - 0x1E007, - 0x1E008, - 0x1E019, - 0x1E01B, - 0x1E022, - 0x1E023, - 0x1E025, - 0x1E026, - 0x1E02B, - 0x1E030, - 0x1E031, - 0x1E032, - 0x1E033, - 0x1E034, - 0x1E035, - 0x1E036, - 0x1E037, - 0x1E038, - 0x1E039, - 0x1E03A, - 0x1E03B, - 0x1E03C, - 0x1E03D, - 0x1E03E, - 0x1E03F, - 0x1E040, - 0x1E041, - 0x1E042, - 0x1E043, - 0x1E044, - 0x1E045, - 0x1E046, - 0x1E047, - 0x1E048, - 0x1E049, - 0x1E04A, - 0x1E04B, - 0x1E04C, - 0x1E04D, - 0x1E04E, - 0x1E04F, - 0x1E050, - 0x1E051, - 0x1E052, - 0x1E053, - 0x1E054, - 0x1E055, - 0x1E056, - 0x1E057, - 0x1E058, - 0x1E059, - 0x1E05A, - 0x1E05B, - 0x1E05C, - 0x1E05D, - 0x1E05E, - 0x1E05F, - 0x1E060, - 0x1E061, - 0x1E062, - 0x1E063, - 0x1E064, - 0x1E065, - 0x1E066, - 0x1E067, - 0x1E068, - 0x1E069, - 0x1E06A, - 0x1E06B, - 0x1E06C, - 0x1E06D, - 0x1E06E, - 0x1E08F, - 0x1E090, - 0x1E100, - 0x1E12D, - 0x1E130, - 0x1E13E, - 0x1E140, - 0x1E14A, - 0x1E14E, - 0x1E150, - 0x1E290, - 0x1E2AF, - 0x1E2C0, - 0x1E2FA, - 0x1E2FF, - 0x1E300, - 0x1E4D0, - 0x1E4FA, - 0x1E5D0, - 0x1E5FB, - 0x1E5FF, - 0x1E600, - 0x1E6C0, - 0x1E6DF, - 0x1E6E0, - 0x1E6F6, - 0x1E6FE, - 0x1E700, - 0x1E7E0, - 0x1E7E7, - 0x1E7E8, - 0x1E7EC, - 0x1E7ED, - 0x1E7EF, - 0x1E7F0, - 0x1E7FF, - 0x1E800, - 0x1E8C5, - 0x1E8C7, - 0x1E8D7, - 0x1E900, - 0x1E901, - 0x1E902, - 0x1E903, - 0x1E904, - 0x1E905, - 0x1E906, - 0x1E907, - 0x1E908, - 0x1E909, - 0x1E90A, - 0x1E90B, - 0x1E90C, - 0x1E90D, - 0x1E90E, - 0x1E90F, - 0x1E910, - 0x1E911, - 0x1E912, - 0x1E913, - 0x1E914, - 0x1E915, - 0x1E916, - 0x1E917, - 0x1E918, - 0x1E919, - 0x1E91A, - 0x1E91B, - 0x1E91C, - 0x1E91D, - 0x1E91E, - 0x1E91F, - 0x1E920, - 0x1E921, - 0x1E922, - 0x1E94C, - 0x1E950, - 0x1E95A, - 0x1E95E, - 0x1E960, - 0x1EC71, - 0x1ECB5, - 0x1ED01, - 0x1ED3E, - 0x1EE00, - 0x1EE01, - 0x1EE02, - 0x1EE03, - 0x1EE04, - 0x1EE05, - 0x1EE06, - 0x1EE07, - 0x1EE08, - 0x1EE09, - 0x1EE0A, - 0x1EE0B, - 0x1EE0C, - 0x1EE0D, - 0x1EE0E, - 0x1EE0F, - 0x1EE10, - 0x1EE11, - 0x1EE12, - 0x1EE13, - 0x1EE14, - 0x1EE15, - 0x1EE16, - 0x1EE17, - 0x1EE18, - 0x1EE19, - 0x1EE1A, - 0x1EE1B, - 0x1EE1C, - 0x1EE1D, - 0x1EE1E, - 0x1EE1F, - 0x1EE20, - 0x1EE21, - 0x1EE22, - 0x1EE23, - 0x1EE24, - 0x1EE25, - 0x1EE27, - 0x1EE28, - 0x1EE29, - 0x1EE2A, - 0x1EE2B, - 0x1EE2C, - 0x1EE2D, - 0x1EE2E, - 0x1EE2F, - 0x1EE30, - 0x1EE31, - 0x1EE32, - 0x1EE33, - 0x1EE34, - 0x1EE35, - 0x1EE36, - 0x1EE37, - 0x1EE38, - 0x1EE39, - 0x1EE3A, - 0x1EE3B, - 0x1EE3C, - 0x1EE42, - 0x1EE43, - 0x1EE47, - 0x1EE48, - 0x1EE49, - 0x1EE4A, - 0x1EE4B, - 0x1EE4C, - 0x1EE4D, - 0x1EE4E, - 0x1EE4F, - 0x1EE50, - 0x1EE51, - 0x1EE52, - 0x1EE53, - 0x1EE54, - 0x1EE55, - 0x1EE57, - 0x1EE58, - 0x1EE59, - 0x1EE5A, - 0x1EE5B, - 0x1EE5C, - 0x1EE5D, - 0x1EE5E, - 0x1EE5F, - 0x1EE60, - 0x1EE61, - 0x1EE62, - 0x1EE63, - 0x1EE64, - 0x1EE65, - 0x1EE67, - 0x1EE68, - 0x1EE69, - 0x1EE6A, - 0x1EE6B, - 0x1EE6C, - 0x1EE6D, - 0x1EE6E, - 0x1EE6F, - 0x1EE70, - 0x1EE71, - 0x1EE72, - 0x1EE73, - 0x1EE74, - 0x1EE75, - 0x1EE76, - 0x1EE77, - 0x1EE78, - 0x1EE79, - 0x1EE7A, - 0x1EE7B, - 0x1EE7C, - 0x1EE7D, - 0x1EE7E, - 0x1EE7F, - 0x1EE80, - 0x1EE81, - 0x1EE82, - 0x1EE83, - 0x1EE84, - 0x1EE85, - 0x1EE86, - 0x1EE87, - 0x1EE88, - 0x1EE89, - 0x1EE8A, - 0x1EE8B, - 0x1EE8C, - 0x1EE8D, - 0x1EE8E, - 0x1EE8F, - 0x1EE90, - 0x1EE91, - 0x1EE92, - 0x1EE93, - 0x1EE94, - 0x1EE95, - 0x1EE96, - 0x1EE97, - 0x1EE98, - 0x1EE99, - 0x1EE9A, - 0x1EE9B, - 0x1EE9C, - 0x1EEA1, - 0x1EEA2, - 0x1EEA3, - 0x1EEA4, - 0x1EEA5, - 0x1EEA6, - 0x1EEA7, - 0x1EEA8, - 0x1EEA9, - 0x1EEAA, - 0x1EEAB, - 0x1EEAC, - 0x1EEAD, - 0x1EEAE, - 0x1EEAF, - 0x1EEB0, - 0x1EEB1, - 0x1EEB2, - 0x1EEB3, - 0x1EEB4, - 0x1EEB5, - 0x1EEB6, - 0x1EEB7, - 0x1EEB8, - 0x1EEB9, - 0x1EEBA, - 0x1EEBB, - 0x1EEBC, - 0x1EEF0, - 0x1EEF2, - 0x1F000, - 0x1F02C, - 0x1F030, - 0x1F094, - 0x1F0A0, - 0x1F0AF, - 0x1F0B1, - 0x1F0C0, - 0x1F0C1, - 0x1F0D0, - 0x1F0D1, - 0x1F0F6, - 0x1F101, - 0x1F102, - 0x1F103, - 0x1F104, - 0x1F105, - 0x1F106, - 0x1F107, - 0x1F108, - 0x1F109, - 0x1F10A, - 0x1F10B, - 0x1F110, - 0x1F111, - 0x1F112, - 0x1F113, - 0x1F114, - 0x1F115, - 0x1F116, - 0x1F117, - 0x1F118, - 0x1F119, - 0x1F11A, - 0x1F11B, - 0x1F11C, - 0x1F11D, - 0x1F11E, - 0x1F11F, - 0x1F120, - 0x1F121, - 0x1F122, - 0x1F123, - 0x1F124, - 0x1F125, - 0x1F126, - 0x1F127, - 0x1F128, - 0x1F129, - 0x1F12A, - 0x1F12B, - 0x1F12C, - 0x1F12D, - 0x1F12E, - 0x1F12F, - 0x1F130, - 0x1F131, - 0x1F132, - 0x1F133, - 0x1F134, - 0x1F135, - 0x1F136, - 0x1F137, - 0x1F138, - 0x1F139, - 0x1F13A, - 0x1F13B, - 0x1F13C, - 0x1F13D, - 0x1F13E, - 0x1F13F, - 0x1F140, - 0x1F141, - 0x1F142, - 0x1F143, - 0x1F144, - 0x1F145, - 0x1F146, - 0x1F147, - 0x1F148, - 0x1F149, - 0x1F14A, - 0x1F14B, - 0x1F14C, - 0x1F14D, - 0x1F14E, - 0x1F14F, - 0x1F150, - 0x1F16A, - 0x1F16B, - 0x1F16C, - 0x1F16D, - 0x1F190, - 0x1F191, - 0x1F1AF, - 0x1F1E6, - 0x1F200, - 0x1F201, - 0x1F202, - 0x1F203, - 0x1F210, - 0x1F211, - 0x1F212, - 0x1F213, - 0x1F214, - 0x1F215, - 0x1F216, - 0x1F217, - 0x1F218, - 0x1F219, - 0x1F21A, - 0x1F21B, - 0x1F21C, - 0x1F21D, - 0x1F21E, - 0x1F21F, - 0x1F220, - 0x1F221, - 0x1F222, - 0x1F223, - 0x1F224, - 0x1F225, - 0x1F226, - 0x1F227, - 0x1F228, - 0x1F229, - 0x1F22A, - 0x1F22B, - 0x1F22C, - 0x1F22D, - 0x1F22E, - 0x1F22F, - 0x1F230, - 0x1F231, - 0x1F232, - 0x1F233, - 0x1F234, - 0x1F235, - 0x1F236, - 0x1F237, - 0x1F238, - 0x1F239, - 0x1F23A, - 0x1F23B, - 0x1F23C, - 0x1F240, - 0x1F241, - 0x1F242, - 0x1F243, - 0x1F244, - 0x1F245, - 0x1F246, - 0x1F247, - 0x1F248, - 0x1F249, - 0x1F250, - 0x1F251, - 0x1F252, - 0x1F260, - 0x1F266, - 0x1F300, - 0x1F6DA, - 0x1F6DC, - 0x1F6ED, - 0x1F6F0, - 0x1F6FD, - 0x1F700, - 0x1F7DC, - 0x1F7E0, - 0x1F7EC, - 0x1F7F0, - 0x1F80C, - 0x1F810, - 0x1F848, - 0x1F850, - 0x1F85A, - 0x1F860, - 0x1F888, - 0x1F890, - 0x1F8AE, - 0x1F8B0, - 0x1F8BC, - 0x1F8C0, - 0x1F8C2, - 0x1F8D0, - 0x1F8D9, - 0x1F900, - 0x1FA58, - 0x1FA60, - 0x1FA6E, - 0x1FA70, - 0x1FA7D, - 0x1FA80, - 0x1FAC7, - 0x1FAC8, - 0x1FAC9, - 0x1FACC, - 0x1FADE, - 0x1FADF, - 0x1FAEC, - 0x1FAEF, - 0x1FAFB, - 0x1FB00, - 0x1FB93, - 0x1FB94, - 0x1FBF0, - 0x1FBF1, - 0x1FBF2, - 0x1FBF3, - 0x1FBF4, - 0x1FBF5, - 0x1FBF6, - 0x1FBF7, - 0x1FBF8, - 0x1FBF9, - 0x1FBFA, - 0x1FBFB, - 0x20000, - 0x2A6E0, - 0x2A700, - 0x2B81F, - 0x2B820, - 0x2CEAE, - 0x2CEB0, - 0x2EBE1, - 0x2EBF0, - 0x2EE5E, - 0x2F800, - 0x2F801, - 0x2F802, - 0x2F803, - 0x2F804, - 0x2F805, - 0x2F806, - 0x2F807, - 0x2F808, - 0x2F809, - 0x2F80A, - 0x2F80B, - 0x2F80C, - 0x2F80D, - 0x2F80E, - 0x2F80F, - 0x2F810, - 0x2F811, - 0x2F812, - 0x2F813, - 0x2F814, - 0x2F815, - 0x2F816, - 0x2F817, - 0x2F818, - 0x2F819, - 0x2F81A, - 0x2F81B, - 0x2F81C, - 0x2F81D, - 0x2F81E, - 0x2F81F, - 0x2F820, - 0x2F821, - 0x2F822, - 0x2F823, - 0x2F824, - 0x2F825, - 0x2F826, - 0x2F827, - 0x2F828, - 0x2F829, - 0x2F82A, - 0x2F82B, - 0x2F82C, - 0x2F82D, - 0x2F82E, - 0x2F82F, - 0x2F830, - 0x2F831, - 0x2F834, - 0x2F835, - 0x2F836, - 0x2F837, - 0x2F838, - 0x2F839, - 0x2F83A, - 0x2F83B, - 0x2F83C, - 0x2F83D, - 0x2F83E, - 0x2F83F, - 0x2F840, - 0x2F841, - 0x2F842, - 0x2F843, - 0x2F844, - 0x2F845, - 0x2F847, - 0x2F848, - 0x2F849, - 0x2F84A, - 0x2F84B, - 0x2F84C, - 0x2F84D, - 0x2F84E, - 0x2F84F, - 0x2F850, - 0x2F851, - 0x2F852, - 0x2F853, - 0x2F854, - 0x2F855, - 0x2F856, - 0x2F857, - 0x2F858, - 0x2F859, - 0x2F85A, - 0x2F85B, - 0x2F85C, - 0x2F85D, - 0x2F85E, - 0x2F85F, - 0x2F860, - 0x2F861, - 0x2F862, - 0x2F863, - 0x2F864, - 0x2F865, - 0x2F866, - 0x2F867, - 0x2F868, - 0x2F869, - 0x2F86A, - 0x2F86C, - 0x2F86D, - 0x2F86E, - 0x2F86F, - 0x2F870, - 0x2F871, - 0x2F872, - 0x2F873, - 0x2F874, - 0x2F875, - 0x2F876, - 0x2F877, - 0x2F878, - 0x2F879, - 0x2F87A, - 0x2F87B, - 0x2F87C, - 0x2F87D, - 0x2F87E, - 0x2F87F, - 0x2F880, - 0x2F881, - 0x2F882, - 0x2F883, - 0x2F884, - 0x2F885, - 0x2F886, - 0x2F887, - 0x2F888, - 0x2F889, - 0x2F88A, - 0x2F88B, - 0x2F88C, - 0x2F88D, - 0x2F88E, - 0x2F88F, - 0x2F890, - 0x2F891, - 0x2F893, - 0x2F894, - 0x2F896, - 0x2F897, - 0x2F898, - 0x2F899, - 0x2F89A, - 0x2F89B, - 0x2F89C, - 0x2F89D, - 0x2F89E, - 0x2F89F, - 0x2F8A0, - 0x2F8A1, - 0x2F8A2, - 0x2F8A3, - 0x2F8A4, - 0x2F8A5, - 0x2F8A6, - 0x2F8A7, - 0x2F8A8, - 0x2F8A9, - 0x2F8AA, - 0x2F8AB, - 0x2F8AC, - 0x2F8AD, - 0x2F8AE, - 0x2F8AF, - 0x2F8B0, - 0x2F8B1, - 0x2F8B2, - 0x2F8B3, - 0x2F8B4, - 0x2F8B5, - 0x2F8B6, - 0x2F8B7, - 0x2F8B8, - 0x2F8B9, - 0x2F8BA, - 0x2F8BB, - 0x2F8BC, - 0x2F8BD, - 0x2F8BE, - 0x2F8BF, - 0x2F8C0, - 0x2F8C1, - 0x2F8C2, - 0x2F8C3, - 0x2F8C4, - 0x2F8C5, - 0x2F8C6, - 0x2F8C7, - 0x2F8C8, - 0x2F8C9, - 0x2F8CA, - 0x2F8CB, - 0x2F8CC, - 0x2F8CD, - 0x2F8CE, - 0x2F8CF, - 0x2F8D0, - 0x2F8D1, - 0x2F8D2, - 0x2F8D3, - 0x2F8D4, - 0x2F8D5, - 0x2F8D6, - 0x2F8D7, - 0x2F8D8, - 0x2F8D9, - 0x2F8DA, - 0x2F8DB, - 0x2F8DC, - 0x2F8DD, - 0x2F8DE, - 0x2F8DF, - 0x2F8E0, - 0x2F8E1, - 0x2F8E2, - 0x2F8E3, - 0x2F8E4, - 0x2F8E5, - 0x2F8E6, - 0x2F8E7, - 0x2F8E8, - 0x2F8E9, - 0x2F8EA, - 0x2F8EB, - 0x2F8EC, - 0x2F8ED, - 0x2F8EE, - 0x2F8EF, - 0x2F8F0, - 0x2F8F1, - 0x2F8F2, - 0x2F8F3, - 0x2F8F4, - 0x2F8F5, - 0x2F8F6, - 0x2F8F7, - 0x2F8F8, - 0x2F8F9, - 0x2F8FA, - 0x2F8FB, - 0x2F8FC, - 0x2F8FD, - 0x2F8FE, - 0x2F8FF, - 0x2F900, - 0x2F901, - 0x2F902, - 0x2F903, - 0x2F904, - 0x2F905, - 0x2F906, - 0x2F907, - 0x2F908, - 0x2F909, - 0x2F90A, - 0x2F90B, - 0x2F90C, - 0x2F90D, - 0x2F90E, - 0x2F90F, - 0x2F910, - 0x2F911, - 0x2F912, - 0x2F913, - 0x2F914, - 0x2F915, - 0x2F916, - 0x2F917, - 0x2F918, - 0x2F919, - 0x2F91A, - 0x2F91B, - 0x2F91C, - 0x2F91D, - 0x2F91E, - 0x2F91F, - 0x2F920, - 0x2F921, - 0x2F922, - 0x2F923, - 0x2F924, - 0x2F925, - 0x2F926, - 0x2F927, - 0x2F928, - 0x2F929, - 0x2F92A, - 0x2F92B, - 0x2F92C, - 0x2F92E, - 0x2F92F, - 0x2F930, - 0x2F931, - 0x2F932, - 0x2F933, - 0x2F934, - 0x2F935, - 0x2F936, - 0x2F937, - 0x2F938, - 0x2F939, - 0x2F93A, - 0x2F93B, - 0x2F93C, - 0x2F93D, - 0x2F93E, - 0x2F93F, - 0x2F940, - 0x2F941, - 0x2F942, - 0x2F943, - 0x2F944, - 0x2F945, - 0x2F946, - 0x2F948, - 0x2F949, - 0x2F94A, - 0x2F94B, - 0x2F94C, - 0x2F94D, - 0x2F94E, - 0x2F94F, - 0x2F950, - 0x2F951, - 0x2F952, - 0x2F953, - 0x2F954, - 0x2F955, - 0x2F956, - 0x2F957, - 0x2F958, - 0x2F959, - 0x2F95A, - 0x2F95B, - 0x2F95C, - 0x2F95D, - 0x2F95F, - 0x2F960, - 0x2F961, - 0x2F962, - 0x2F963, - 0x2F964, - 0x2F965, - 0x2F966, - 0x2F967, - 0x2F968, - 0x2F969, - 0x2F96A, - 0x2F96B, - 0x2F96C, - 0x2F96D, - 0x2F96E, - 0x2F96F, - 0x2F970, - 0x2F971, - 0x2F972, - 0x2F973, - 0x2F974, - 0x2F975, - 0x2F976, - 0x2F977, - 0x2F978, - 0x2F979, - 0x2F97A, - 0x2F97B, - 0x2F97C, - 0x2F97D, - 0x2F97E, - 0x2F97F, - 0x2F980, - 0x2F981, - 0x2F982, - 0x2F983, - 0x2F984, - 0x2F985, - 0x2F986, - 0x2F987, - 0x2F988, - 0x2F989, - 0x2F98A, - 0x2F98B, - 0x2F98C, - 0x2F98D, - 0x2F98E, - 0x2F98F, - 0x2F990, - 0x2F991, - 0x2F992, - 0x2F993, - 0x2F994, - 0x2F995, - 0x2F996, - 0x2F997, - 0x2F998, - 0x2F999, - 0x2F99A, - 0x2F99B, - 0x2F99C, - 0x2F99D, - 0x2F99E, - 0x2F99F, - 0x2F9A0, - 0x2F9A1, - 0x2F9A2, - 0x2F9A3, - 0x2F9A4, - 0x2F9A5, - 0x2F9A6, - 0x2F9A7, - 0x2F9A8, - 0x2F9A9, - 0x2F9AA, - 0x2F9AB, - 0x2F9AC, - 0x2F9AD, - 0x2F9AE, - 0x2F9AF, - 0x2F9B0, - 0x2F9B1, - 0x2F9B2, - 0x2F9B3, - 0x2F9B4, - 0x2F9B5, - 0x2F9B6, - 0x2F9B7, - 0x2F9B8, - 0x2F9B9, - 0x2F9BA, - 0x2F9BB, - 0x2F9BC, - 0x2F9BD, - 0x2F9BE, - 0x2F9BF, - 0x2F9C0, - 0x2F9C1, - 0x2F9C2, - 0x2F9C3, - 0x2F9C4, - 0x2F9C5, - 0x2F9C6, - 0x2F9C7, - 0x2F9C8, - 0x2F9C9, - 0x2F9CA, - 0x2F9CB, - 0x2F9CC, - 0x2F9CD, - 0x2F9CE, - 0x2F9CF, - 0x2F9D0, - 0x2F9D1, - 0x2F9D2, - 0x2F9D3, - 0x2F9D4, - 0x2F9D5, - 0x2F9D6, - 0x2F9D7, - 0x2F9D8, - 0x2F9D9, - 0x2F9DA, - 0x2F9DB, - 0x2F9DC, - 0x2F9DD, - 0x2F9DE, - 0x2F9DF, - 0x2F9E0, - 0x2F9E1, - 0x2F9E2, - 0x2F9E3, - 0x2F9E4, - 0x2F9E5, - 0x2F9E6, - 0x2F9E7, - 0x2F9E8, - 0x2F9E9, - 0x2F9EA, - 0x2F9EB, - 0x2F9EC, - 0x2F9ED, - 0x2F9EE, - 0x2F9EF, - 0x2F9F0, - 0x2F9F1, - 0x2F9F2, - 0x2F9F3, - 0x2F9F4, - 0x2F9F5, - 0x2F9F6, - 0x2F9F7, - 0x2F9F8, - 0x2F9F9, - 0x2F9FA, - 0x2F9FB, - 0x2F9FC, - 0x2F9FD, - 0x2F9FE, - 0x2FA00, - 0x2FA01, - 0x2FA02, - 0x2FA03, - 0x2FA04, - 0x2FA05, - 0x2FA06, - 0x2FA07, - 0x2FA08, - 0x2FA09, - 0x2FA0A, - 0x2FA0B, - 0x2FA0C, - 0x2FA0D, - 0x2FA0E, - 0x2FA0F, - 0x2FA10, - 0x2FA11, - 0x2FA12, - 0x2FA13, - 0x2FA14, - 0x2FA15, - 0x2FA16, - 0x2FA17, - 0x2FA18, - 0x2FA19, - 0x2FA1A, - 0x2FA1B, - 0x2FA1C, - 0x2FA1D, - 0x2FA1E, - 0x30000, - 0x3134B, - 0x31350, - 0x3347A, - 0x3D000, - 0x3FC40, - 0xE0100, - 0xE01F0, - ), -) - -uts46_statuses: bytes = ( - b"VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" - b"VMMMMMMMMMMMMMMMMMMMMMMMMMMVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" - b"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMVVVVVVVMVMVVIVMVVMMMMVVMMMVMMMV" - b"MMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMDVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMVMMV" - b"MVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMM" - b"VMVMMVMMMVMMMMVMMVMMMVMMVMMVMVMVMMVMVMVMMVMMMVMVMMVMVMMMMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMMVMVMMMMVMVMVMVMVMMMMMMMMMVMMMMMM" - b"VMMMMMVMMVMMMVIVMVMVMVMVXMVMMXMMMMMMMXMXMMVMMMMMMMMMMMMMMMMMXMMM" - b"MMMMMMVDVMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMMMVMMVMVMMVMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMXMVMVMMVXVXVXVXVXVMMMMVXVXVXVXVXVXVXVXVX" - b"VXVXVXVMMMMMMMMVXVXVXVXVXVXVXVXVXVXVXMMXMVXVXVXVXVXVXVXVMXVMXVXV" - b"XVXVXVXVXMMMVXMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" - b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" - b"XVXVMVXVXVXVXVXVXVXVMVXVXVXVXVXMMVXVMVMVXVMVMVMVMVMVXVMVMMMMMVMV" - b"MVXVMVMVMVMVMVXVXVXVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMXMXV" - b"MVIVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMXVXVXVXVXVXVXVXVX" - b"VXVIVXVXVXVIVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMM" - b"MMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMVXVXVMMMV" - b"MMMMMMMMMMMVMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMMMMMMMVXMMMMMMXVMMMMMMMMVMMMMMM" - b"MMVXMMMMMMXVXMXMXMXMVMMMMMMMMVMVMVMVMVMVMVMXMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMXVMMMMMMMMMMMMMMXVMMMMMMMMMVMXVM" - b"MMMXMMMVMVMMMMMMMMXMMMXVMMMMMMMMXMIDXVMVMVXVXMVMMVMMVMVMVMMMVMVM" - b"IXIMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMVMVXVXMMMMVMMM" - b"VMMMMMMVMMVMMMVMMMVMVMVMVMMMMVMMMMMMMMMMVMMMMMVMMMMVMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMVXVMMVMMVMMVXVXMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVXVMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMVMMMVMVMVMVMMMMVMVMV" - b"MMMMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVXVXVXVXVXMVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVMVMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMVMVMVMMMVXVXVMMVM" - b"VMXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVMMMMMMMMMMMMMMVXVMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMMMMMMM" - b"MMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXMVMVMVMVMVM" - b"VMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVM" - b"MVXVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMVMMM" - b"MMVMMMMMVMVMVMVMVMVMVMVMMMMVMVMMVMVMVMVMVMVMVMVMMXMXMMMMMVMMVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMMMVMVMMXMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMV" - b"XVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMVMVMVMMMMMMMMMMVMVMVMMVMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMXMMMMMXMVMMMMMMMMMMMMMMMMMMMMM" - b"MMMXMMMMMXMXMMXMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXMMMMMMMMMMMM" - b"MVIMMXMMMMMMXVXMMMMMMMMMMMMMMMMMMMVMMMMMMXMMMMMMMMMMMMMMMMMMMXMM" - b"MMXMMMVMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXIXMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMIMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMM" - b"MMMXMMMMMMXMMMMMMXMMMXMMMMMMMXMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVMMMMMMMMMMMXMMMMMMMMMM" - b"MMMMMXMMMMMMMXMMXVXVXVXVXVXVXVXVXVMMMMMXMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMVXMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVX" - b"VXVXVXVXVXVXVXVXVMMMMVXVXVXVXVXVXVXVXVXVXVIXVMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMVXVXVXVXVXVXVXVXVXVMMMMMMMVIVMMMMMMVXVXVXVXVXVX" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMXMXMMXMMMMXMMMMMMMMMMMMXMXMMMMMM" - b"MXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMXMMMMXMMMMMMMMXMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMXMMMM" - b"MXMXMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVMVMV" - b"MVMVMVMVMVMVMVMVMVMVMVMVMVMVXVMVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMVXVXVXVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXV" - b"XVXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVXVXVXVXVXMMMMXMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMXMMXMXMXMMMMMMMMMMXMMMMXMXMXMXMXMXMXMMMXMMXMXMX" - b"MXMXMXMXMMXMXMMMMXMMMMMMMXMMMMXMMMMXMXMMMMMMMMMMXMMMMMMMMMMMMMMM" - b"MMXMMMXMMMMMXMMMMMMMMMMMMMMMMMXVXVXVXVXVXVXVXMMMMMMMMMMVMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMVMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMVMMMVMVX" - b"VMMMXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXMMMMMMMMMXMMXV" - b"XVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVXVMMMMMMMMMMVXVXVXVX" - b"VXVXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" - b"MMMMMMMMMMMMMMMMMMMMMMMMXVXVXVXIX" -) - -uts46_replacements: tuple[str | None, ...] = ( - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - " ", - None, - None, - None, - None, - None, - None, - None, - " ̈", - None, - "a", - None, - None, - None, - None, - " ̄", - None, - None, - "2", - "3", - " ́", - "μ", - None, - None, - " ̧", - "1", - "o", - None, - "1⁄4", - "1⁄2", - "3⁄4", - None, - "à", - "á", - "â", - "ã", - "ä", - "å", - "æ", - "ç", - "è", - "é", - "ê", - "ë", - "ì", - "í", - "î", - "ï", - "ð", - "ñ", - "ò", - "ó", - "ô", - "õ", - "ö", - None, - "ø", - "ù", - "ú", - "û", - "ü", - "ý", - "þ", - "ss", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ā", - None, - "ă", - None, - "ą", - None, - "ć", - None, - "ĉ", - None, - "ċ", - None, - "č", - None, - "ď", - None, - "đ", - None, - "ē", - None, - "ĕ", - None, - "ė", - None, - "ę", - None, - "ě", - None, - "ĝ", - None, - "ğ", - None, - "ġ", - None, - "ģ", - None, - "ĥ", - None, - "ħ", - None, - "ĩ", - None, - "ī", - None, - "ĭ", - None, - "į", - None, - "i̇", - None, - "ij", - "ĵ", - None, - "ķ", - None, - "ĺ", - None, - "ļ", - None, - "ľ", - None, - "l·", - "ł", - None, - "ń", - None, - "ņ", - None, - "ň", - None, - "ʼn", - "ŋ", - None, - "ō", - None, - "ŏ", - None, - "ő", - None, - "œ", - None, - "ŕ", - None, - "ŗ", - None, - "ř", - None, - "ś", - None, - "ŝ", - None, - "ş", - None, - "š", - None, - "ţ", - None, - "ť", - None, - "ŧ", - None, - "ũ", - None, - "ū", - None, - "ŭ", - None, - "ů", - None, - "ű", - None, - "ų", - None, - "ŵ", - None, - "ŷ", - None, - "ÿ", - "ź", - None, - "ż", - None, - "ž", - None, - "s", - None, - "ɓ", - "ƃ", - None, - "ƅ", - None, - "ɔ", - "ƈ", - None, - "ɖ", - "ɗ", - "ƌ", - None, - "ǝ", - "ə", - "ɛ", - "ƒ", - None, - "ɠ", - "ɣ", - None, - "ɩ", - "ɨ", - "ƙ", - None, - "ɯ", - "ɲ", - None, - "ɵ", - "ơ", - None, - "ƣ", - None, - "ƥ", - None, - "ʀ", - "ƨ", - None, - "ʃ", - None, - "ƭ", - None, - "ʈ", - "ư", - None, - "ʊ", - "ʋ", - "ƴ", - None, - "ƶ", - None, - "ʒ", - "ƹ", - None, - "ƽ", - None, - "dž", - "lj", - "nj", - "ǎ", - None, - "ǐ", - None, - "ǒ", - None, - "ǔ", - None, - "ǖ", - None, - "ǘ", - None, - "ǚ", - None, - "ǜ", - None, - "ǟ", - None, - "ǡ", - None, - "ǣ", - None, - "ǥ", - None, - "ǧ", - None, - "ǩ", - None, - "ǫ", - None, - "ǭ", - None, - "ǯ", - None, - "dz", - "ǵ", - None, - "ƕ", - "ƿ", - "ǹ", - None, - "ǻ", - None, - "ǽ", - None, - "ǿ", - None, - "ȁ", - None, - "ȃ", - None, - "ȅ", - None, - "ȇ", - None, - "ȉ", - None, - "ȋ", - None, - "ȍ", - None, - "ȏ", - None, - "ȑ", - None, - "ȓ", - None, - "ȕ", - None, - "ȗ", - None, - "ș", - None, - "ț", - None, - "ȝ", - None, - "ȟ", - None, - "ƞ", - None, - "ȣ", - None, - "ȥ", - None, - "ȧ", - None, - "ȩ", - None, - "ȫ", - None, - "ȭ", - None, - "ȯ", - None, - "ȱ", - None, - "ȳ", - None, - "ⱥ", - "ȼ", - None, - "ƚ", - "ⱦ", - None, - "ɂ", - None, - "ƀ", - "ʉ", - "ʌ", - "ɇ", - None, - "ɉ", - None, - "ɋ", - None, - "ɍ", - None, - "ɏ", - None, - "h", - "ɦ", - "j", - "r", - "ɹ", - "ɻ", - "ʁ", - "w", - "y", - None, - " ̆", - " ̇", - " ̊", - " ̨", - " ̃", - " ̋", - None, - "ɣ", - "l", - "s", - "x", - "ʕ", - None, - "̀", - "́", - None, - "̓", - "̈́", - "ι", - None, - None, - None, - "ͱ", - None, - "ͳ", - None, - "ʹ", - None, - "ͷ", - None, - None, - " ι", - None, - ";", - "ϳ", - None, - " ́", - " ̈́", - "ά", - "·", - "έ", - "ή", - "ί", - None, - "ό", - None, - "ύ", - "ώ", - None, - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - None, - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "ϊ", - "ϋ", - None, - "σ", - None, - "ϗ", - "β", - "θ", - "υ", - "ύ", - "ϋ", - "φ", - "π", - None, - "ϙ", - None, - "ϛ", - None, - "ϝ", - None, - "ϟ", - None, - "ϡ", - None, - "ϣ", - None, - "ϥ", - None, - "ϧ", - None, - "ϩ", - None, - "ϫ", - None, - "ϭ", - None, - "ϯ", - None, - "κ", - "ρ", - "σ", - None, - "θ", - "ε", - None, - "ϸ", - None, - "σ", - "ϻ", - None, - "ͻ", - "ͼ", - "ͽ", - "ѐ", - "ё", - "ђ", - "ѓ", - "є", - "ѕ", - "і", - "ї", - "ј", - "љ", - "њ", - "ћ", - "ќ", - "ѝ", - "ў", - "џ", - "а", - "б", - "в", - "г", - "д", - "е", - "ж", - "з", - "и", - "й", - "к", - "л", - "м", - "н", - "о", - "п", - "р", - "с", - "т", - "у", - "ф", - "х", - "ц", - "ч", - "ш", - "щ", - "ъ", - "ы", - "ь", - "э", - "ю", - "я", - None, - "ѡ", - None, - "ѣ", - None, - "ѥ", - None, - "ѧ", - None, - "ѩ", - None, - "ѫ", - None, - "ѭ", - None, - "ѯ", - None, - "ѱ", - None, - "ѳ", - None, - "ѵ", - None, - "ѷ", - None, - "ѹ", - None, - "ѻ", - None, - "ѽ", - None, - "ѿ", - None, - "ҁ", - None, - "ҋ", - None, - "ҍ", - None, - "ҏ", - None, - "ґ", - None, - "ғ", - None, - "ҕ", - None, - "җ", - None, - "ҙ", - None, - "қ", - None, - "ҝ", - None, - "ҟ", - None, - "ҡ", - None, - "ң", - None, - "ҥ", - None, - "ҧ", - None, - "ҩ", - None, - "ҫ", - None, - "ҭ", - None, - "ү", - None, - "ұ", - None, - "ҳ", - None, - "ҵ", - None, - "ҷ", - None, - "ҹ", - None, - "һ", - None, - "ҽ", - None, - "ҿ", - None, - "ӏ", - "ӂ", - None, - "ӄ", - None, - "ӆ", - None, - "ӈ", - None, - "ӊ", - None, - "ӌ", - None, - "ӎ", - None, - "ӑ", - None, - "ӓ", - None, - "ӕ", - None, - "ӗ", - None, - "ә", - None, - "ӛ", - None, - "ӝ", - None, - "ӟ", - None, - "ӡ", - None, - "ӣ", - None, - "ӥ", - None, - "ӧ", - None, - "ө", - None, - "ӫ", - None, - "ӭ", - None, - "ӯ", - None, - "ӱ", - None, - "ӳ", - None, - "ӵ", - None, - "ӷ", - None, - "ӹ", - None, - "ӻ", - None, - "ӽ", - None, - "ӿ", - None, - "ԁ", - None, - "ԃ", - None, - "ԅ", - None, - "ԇ", - None, - "ԉ", - None, - "ԋ", - None, - "ԍ", - None, - "ԏ", - None, - "ԑ", - None, - "ԓ", - None, - "ԕ", - None, - "ԗ", - None, - "ԙ", - None, - "ԛ", - None, - "ԝ", - None, - "ԟ", - None, - "ԡ", - None, - "ԣ", - None, - "ԥ", - None, - "ԧ", - None, - "ԩ", - None, - "ԫ", - None, - "ԭ", - None, - "ԯ", - None, - None, - "ա", - "բ", - "գ", - "դ", - "ե", - "զ", - "է", - "ը", - "թ", - "ժ", - "ի", - "լ", - "խ", - "ծ", - "կ", - "հ", - "ձ", - "ղ", - "ճ", - "մ", - "յ", - "ն", - "շ", - "ո", - "չ", - "պ", - "ջ", - "ռ", - "ս", - "վ", - "տ", - "ր", - "ց", - "ւ", - "փ", - "ք", - "օ", - "ֆ", - None, - "է", - None, - "եւ", - None, - "ի", - "յ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "اٴ", - "وٴ", - "ۇٴ", - "يٴ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "क़", - "ख़", - "ग़", - "ज़", - "ड़", - "ढ़", - "फ़", - "य़", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ড়", - "ঢ়", - None, - "য়", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ਲ਼", - None, - None, - "ਸ਼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ਖ਼", - "ਗ਼", - "ਜ਼", - None, - None, - "ਫ਼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ଡ଼", - "ଢ଼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ํา", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ໍາ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ຫນ", - "ຫມ", - None, - None, - None, - "་", - None, - "གྷ", - None, - None, - None, - "ཌྷ", - None, - "དྷ", - None, - "བྷ", - None, - "ཛྷ", - None, - "ཀྵ", - None, - None, - None, - "ཱི", - None, - "ཱུ", - "ྲྀ", - "ྲཱྀ", - "ླྀ", - "ླཱྀ", - None, - "ཱྀ", - None, - "ྒྷ", - None, - None, - None, - "ྜྷ", - None, - "ྡྷ", - None, - "ྦྷ", - None, - "ྫྷ", - None, - "ྐྵ", - None, - None, - None, - None, - None, - None, - None, - "ⴀ", - "ⴁ", - "ⴂ", - "ⴃ", - "ⴄ", - "ⴅ", - "ⴆ", - "ⴇ", - "ⴈ", - "ⴉ", - "ⴊ", - "ⴋ", - "ⴌ", - "ⴍ", - "ⴎ", - "ⴏ", - "ⴐ", - "ⴑ", - "ⴒ", - "ⴓ", - "ⴔ", - "ⴕ", - "ⴖ", - "ⴗ", - "ⴘ", - "ⴙ", - "ⴚ", - "ⴛ", - "ⴜ", - "ⴝ", - "ⴞ", - "ⴟ", - "ⴠ", - "ⴡ", - "ⴢ", - "ⴣ", - "ⴤ", - "ⴥ", - None, - "ⴧ", - None, - "ⴭ", - None, - None, - "ნ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "Ᏸ", - "Ᏹ", - "Ᏺ", - "Ᏻ", - "Ᏼ", - "Ᏽ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "в", - "д", - "о", - "с", - "т", - "ъ", - "ѣ", - "ꙋ", - "ᲊ", - None, - None, - "ა", - "ბ", - "გ", - "დ", - "ე", - "ვ", - "ზ", - "თ", - "ი", - "კ", - "ლ", - "მ", - "ნ", - "ო", - "პ", - "ჟ", - "რ", - "ს", - "ტ", - "უ", - "ფ", - "ქ", - "ღ", - "ყ", - "შ", - "ჩ", - "ც", - "ძ", - "წ", - "ჭ", - "ხ", - "ჯ", - "ჰ", - "ჱ", - "ჲ", - "ჳ", - "ჴ", - "ჵ", - "ჶ", - "ჷ", - "ჸ", - "ჹ", - "ჺ", - None, - "ჽ", - "ჾ", - "ჿ", - None, - None, - None, - None, - None, - "a", - "æ", - "b", - None, - "d", - "e", - "ǝ", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - None, - "o", - "ȣ", - "p", - "r", - "t", - "u", - "w", - "a", - "ɐ", - "ɑ", - "ᴂ", - "b", - "d", - "e", - "ə", - "ɛ", - "ɜ", - "g", - None, - "k", - "m", - "ŋ", - "o", - "ɔ", - "ᴖ", - "ᴗ", - "p", - "t", - "u", - "ᴝ", - "ɯ", - "v", - "ᴥ", - "β", - "γ", - "δ", - "φ", - "χ", - "i", - "r", - "u", - "v", - "β", - "γ", - "ρ", - "φ", - "χ", - None, - "н", - None, - "ɒ", - "c", - "ɕ", - "ð", - "ɜ", - "f", - "ɟ", - "ɡ", - "ɥ", - "ɨ", - "ɩ", - "ɪ", - "ᵻ", - "ʝ", - "ɭ", - "ᶅ", - "ʟ", - "ɱ", - "ɰ", - "ɲ", - "ɳ", - "ɴ", - "ɵ", - "ɸ", - "ʂ", - "ʃ", - "ƫ", - "ʉ", - "ʊ", - "ᴜ", - "ʋ", - "ʌ", - "z", - "ʐ", - "ʑ", - "ʒ", - "θ", - None, - "ḁ", - None, - "ḃ", - None, - "ḅ", - None, - "ḇ", - None, - "ḉ", - None, - "ḋ", - None, - "ḍ", - None, - "ḏ", - None, - "ḑ", - None, - "ḓ", - None, - "ḕ", - None, - "ḗ", - None, - "ḙ", - None, - "ḛ", - None, - "ḝ", - None, - "ḟ", - None, - "ḡ", - None, - "ḣ", - None, - "ḥ", - None, - "ḧ", - None, - "ḩ", - None, - "ḫ", - None, - "ḭ", - None, - "ḯ", - None, - "ḱ", - None, - "ḳ", - None, - "ḵ", - None, - "ḷ", - None, - "ḹ", - None, - "ḻ", - None, - "ḽ", - None, - "ḿ", - None, - "ṁ", - None, - "ṃ", - None, - "ṅ", - None, - "ṇ", - None, - "ṉ", - None, - "ṋ", - None, - "ṍ", - None, - "ṏ", - None, - "ṑ", - None, - "ṓ", - None, - "ṕ", - None, - "ṗ", - None, - "ṙ", - None, - "ṛ", - None, - "ṝ", - None, - "ṟ", - None, - "ṡ", - None, - "ṣ", - None, - "ṥ", - None, - "ṧ", - None, - "ṩ", - None, - "ṫ", - None, - "ṭ", - None, - "ṯ", - None, - "ṱ", - None, - "ṳ", - None, - "ṵ", - None, - "ṷ", - None, - "ṹ", - None, - "ṻ", - None, - "ṽ", - None, - "ṿ", - None, - "ẁ", - None, - "ẃ", - None, - "ẅ", - None, - "ẇ", - None, - "ẉ", - None, - "ẋ", - None, - "ẍ", - None, - "ẏ", - None, - "ẑ", - None, - "ẓ", - None, - "ẕ", - None, - "aʾ", - "ṡ", - None, - "ß", - None, - "ạ", - None, - "ả", - None, - "ấ", - None, - "ầ", - None, - "ẩ", - None, - "ẫ", - None, - "ậ", - None, - "ắ", - None, - "ằ", - None, - "ẳ", - None, - "ẵ", - None, - "ặ", - None, - "ẹ", - None, - "ẻ", - None, - "ẽ", - None, - "ế", - None, - "ề", - None, - "ể", - None, - "ễ", - None, - "ệ", - None, - "ỉ", - None, - "ị", - None, - "ọ", - None, - "ỏ", - None, - "ố", - None, - "ồ", - None, - "ổ", - None, - "ỗ", - None, - "ộ", - None, - "ớ", - None, - "ờ", - None, - "ở", - None, - "ỡ", - None, - "ợ", - None, - "ụ", - None, - "ủ", - None, - "ứ", - None, - "ừ", - None, - "ử", - None, - "ữ", - None, - "ự", - None, - "ỳ", - None, - "ỵ", - None, - "ỷ", - None, - "ỹ", - None, - "ỻ", - None, - "ỽ", - None, - "ỿ", - None, - "ἀ", - "ἁ", - "ἂ", - "ἃ", - "ἄ", - "ἅ", - "ἆ", - "ἇ", - None, - None, - "ἐ", - "ἑ", - "ἒ", - "ἓ", - "ἔ", - "ἕ", - None, - None, - "ἠ", - "ἡ", - "ἢ", - "ἣ", - "ἤ", - "ἥ", - "ἦ", - "ἧ", - None, - "ἰ", - "ἱ", - "ἲ", - "ἳ", - "ἴ", - "ἵ", - "ἶ", - "ἷ", - None, - None, - "ὀ", - "ὁ", - "ὂ", - "ὃ", - "ὄ", - "ὅ", - None, - None, - None, - "ὑ", - None, - "ὓ", - None, - "ὕ", - None, - "ὗ", - None, - "ὠ", - "ὡ", - "ὢ", - "ὣ", - "ὤ", - "ὥ", - "ὦ", - "ὧ", - None, - "ά", - None, - "έ", - None, - "ή", - None, - "ί", - None, - "ό", - None, - "ύ", - None, - "ώ", - None, - "ἀι", - "ἁι", - "ἂι", - "ἃι", - "ἄι", - "ἅι", - "ἆι", - "ἇι", - "ἀι", - "ἁι", - "ἂι", - "ἃι", - "ἄι", - "ἅι", - "ἆι", - "ἇι", - "ἠι", - "ἡι", - "ἢι", - "ἣι", - "ἤι", - "ἥι", - "ἦι", - "ἧι", - "ἠι", - "ἡι", - "ἢι", - "ἣι", - "ἤι", - "ἥι", - "ἦι", - "ἧι", - "ὠι", - "ὡι", - "ὢι", - "ὣι", - "ὤι", - "ὥι", - "ὦι", - "ὧι", - "ὠι", - "ὡι", - "ὢι", - "ὣι", - "ὤι", - "ὥι", - "ὦι", - "ὧι", - None, - "ὰι", - "αι", - "άι", - None, - None, - "ᾶι", - "ᾰ", - "ᾱ", - "ὰ", - "ά", - "αι", - " ̓", - "ι", - " ̓", - " ͂", - " ̈͂", - "ὴι", - "ηι", - "ήι", - None, - None, - "ῆι", - "ὲ", - "έ", - "ὴ", - "ή", - "ηι", - " ̓̀", - " ̓́", - " ̓͂", - None, - "ΐ", - None, - None, - "ῐ", - "ῑ", - "ὶ", - "ί", - None, - " ̔̀", - " ̔́", - " ̔͂", - None, - "ΰ", - None, - "ῠ", - "ῡ", - "ὺ", - "ύ", - "ῥ", - " ̈̀", - " ̈́", - "`", - None, - "ὼι", - "ωι", - "ώι", - None, - None, - "ῶι", - "ὸ", - "ό", - "ὼ", - "ώ", - "ωι", - " ́", - " ̔", - None, - " ", - None, - "", - None, - None, - "‐", - None, - " ̳", - None, - None, - None, - None, - " ", - None, - "′′", - "′′′", - None, - "‵‵", - "‵‵‵", - None, - "!!", - None, - " ̅", - None, - "??", - "?!", - "!?", - None, - "′′′′", - None, - " ", - None, - None, - None, - "0", - "i", - None, - "4", - "5", - "6", - "7", - "8", - "9", - "+", - "−", - "=", - "(", - ")", - "n", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "+", - "−", - "=", - "(", - ")", - None, - "a", - "e", - "o", - "x", - "ə", - "h", - "k", - "l", - "m", - "n", - "p", - "s", - "t", - "w", - "y", - "z", - None, - "rs", - None, - None, - None, - None, - "a/c", - "a/s", - "c", - "°c", - None, - "c/o", - "c/u", - "ɛ", - None, - "°f", - "g", - "h", - "ħ", - "i", - "l", - None, - "n", - "no", - None, - "p", - "q", - "r", - None, - "sm", - "tel", - "tm", - None, - "z", - None, - "ω", - None, - "z", - None, - "k", - "å", - "b", - "c", - None, - "e", - "f", - "ⅎ", - "m", - "o", - "א", - "ב", - "ג", - "ד", - "i", - None, - "fax", - "π", - "γ", - "π", - "∑", - None, - "d", - "e", - "i", - "j", - None, - "1⁄7", - "1⁄9", - "1⁄10", - "1⁄3", - "2⁄3", - "1⁄5", - "2⁄5", - "3⁄5", - "4⁄5", - "1⁄6", - "5⁄6", - "1⁄8", - "3⁄8", - "5⁄8", - "7⁄8", - "1⁄", - "i", - "ii", - "iii", - "iv", - "v", - "vi", - "vii", - "viii", - "ix", - "x", - "xi", - "xii", - "l", - "c", - "d", - "m", - "i", - "ii", - "iii", - "iv", - "v", - "vi", - "vii", - "viii", - "ix", - "x", - "xi", - "xii", - "l", - "c", - "d", - "m", - None, - "ↄ", - None, - "0⁄3", - None, - None, - None, - "∫∫", - "∫∫∫", - None, - "∮∮", - "∮∮∮", - None, - "〈", - "〉", - None, - None, - None, - None, - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "(1)", - "(2)", - "(3)", - "(4)", - "(5)", - "(6)", - "(7)", - "(8)", - "(9)", - "(10)", - "(11)", - "(12)", - "(13)", - "(14)", - "(15)", - "(16)", - "(17)", - "(18)", - "(19)", - "(20)", - None, - "(a)", - "(b)", - "(c)", - "(d)", - "(e)", - "(f)", - "(g)", - "(h)", - "(i)", - "(j)", - "(k)", - "(l)", - "(m)", - "(n)", - "(o)", - "(p)", - "(q)", - "(r)", - "(s)", - "(t)", - "(u)", - "(v)", - "(w)", - "(x)", - "(y)", - "(z)", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "0", - None, - "∫∫∫∫", - None, - "::=", - "==", - "===", - None, - "⫝̸", - None, - None, - None, - "ⰰ", - "ⰱ", - "ⰲ", - "ⰳ", - "ⰴ", - "ⰵ", - "ⰶ", - "ⰷ", - "ⰸ", - "ⰹ", - "ⰺ", - "ⰻ", - "ⰼ", - "ⰽ", - "ⰾ", - "ⰿ", - "ⱀ", - "ⱁ", - "ⱂ", - "ⱃ", - "ⱄ", - "ⱅ", - "ⱆ", - "ⱇ", - "ⱈ", - "ⱉ", - "ⱊ", - "ⱋ", - "ⱌ", - "ⱍ", - "ⱎ", - "ⱏ", - "ⱐ", - "ⱑ", - "ⱒ", - "ⱓ", - "ⱔ", - "ⱕ", - "ⱖ", - "ⱗ", - "ⱘ", - "ⱙ", - "ⱚ", - "ⱛ", - "ⱜ", - "ⱝ", - "ⱞ", - "ⱟ", - None, - "ⱡ", - None, - "ɫ", - "ᵽ", - "ɽ", - None, - "ⱨ", - None, - "ⱪ", - None, - "ⱬ", - None, - "ɑ", - "ɱ", - "ɐ", - "ɒ", - None, - "ⱳ", - None, - "ⱶ", - None, - "j", - "v", - "ȿ", - "ɀ", - "ⲁ", - None, - "ⲃ", - None, - "ⲅ", - None, - "ⲇ", - None, - "ⲉ", - None, - "ⲋ", - None, - "ⲍ", - None, - "ⲏ", - None, - "ⲑ", - None, - "ⲓ", - None, - "ⲕ", - None, - "ⲗ", - None, - "ⲙ", - None, - "ⲛ", - None, - "ⲝ", - None, - "ⲟ", - None, - "ⲡ", - None, - "ⲣ", - None, - "ⲥ", - None, - "ⲧ", - None, - "ⲩ", - None, - "ⲫ", - None, - "ⲭ", - None, - "ⲯ", - None, - "ⲱ", - None, - "ⲳ", - None, - "ⲵ", - None, - "ⲷ", - None, - "ⲹ", - None, - "ⲻ", - None, - "ⲽ", - None, - "ⲿ", - None, - "ⳁ", - None, - "ⳃ", - None, - "ⳅ", - None, - "ⳇ", - None, - "ⳉ", - None, - "ⳋ", - None, - "ⳍ", - None, - "ⳏ", - None, - "ⳑ", - None, - "ⳓ", - None, - "ⳕ", - None, - "ⳗ", - None, - "ⳙ", - None, - "ⳛ", - None, - "ⳝ", - None, - "ⳟ", - None, - "ⳡ", - None, - "ⳣ", - None, - "ⳬ", - None, - "ⳮ", - None, - "ⳳ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ⵡ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "母", - None, - "龟", - None, - "一", - "丨", - "丶", - "丿", - "乙", - "亅", - "二", - "亠", - "人", - "儿", - "入", - "八", - "冂", - "冖", - "冫", - "几", - "凵", - "刀", - "力", - "勹", - "匕", - "匚", - "匸", - "十", - "卜", - "卩", - "厂", - "厶", - "又", - "口", - "囗", - "土", - "士", - "夂", - "夊", - "夕", - "大", - "女", - "子", - "宀", - "寸", - "小", - "尢", - "尸", - "屮", - "山", - "巛", - "工", - "己", - "巾", - "干", - "幺", - "广", - "廴", - "廾", - "弋", - "弓", - "彐", - "彡", - "彳", - "心", - "戈", - "戶", - "手", - "支", - "攴", - "文", - "斗", - "斤", - "方", - "无", - "日", - "曰", - "月", - "木", - "欠", - "止", - "歹", - "殳", - "毋", - "比", - "毛", - "氏", - "气", - "水", - "火", - "爪", - "父", - "爻", - "爿", - "片", - "牙", - "牛", - "犬", - "玄", - "玉", - "瓜", - "瓦", - "甘", - "生", - "用", - "田", - "疋", - "疒", - "癶", - "白", - "皮", - "皿", - "目", - "矛", - "矢", - "石", - "示", - "禸", - "禾", - "穴", - "立", - "竹", - "米", - "糸", - "缶", - "网", - "羊", - "羽", - "老", - "而", - "耒", - "耳", - "聿", - "肉", - "臣", - "自", - "至", - "臼", - "舌", - "舛", - "舟", - "艮", - "色", - "艸", - "虍", - "虫", - "血", - "行", - "衣", - "襾", - "見", - "角", - "言", - "谷", - "豆", - "豕", - "豸", - "貝", - "赤", - "走", - "足", - "身", - "車", - "辛", - "辰", - "辵", - "邑", - "酉", - "釆", - "里", - "金", - "長", - "門", - "阜", - "隶", - "隹", - "雨", - "靑", - "非", - "面", - "革", - "韋", - "韭", - "音", - "頁", - "風", - "飛", - "食", - "首", - "香", - "馬", - "骨", - "高", - "髟", - "鬥", - "鬯", - "鬲", - "鬼", - "魚", - "鳥", - "鹵", - "鹿", - "麥", - "麻", - "黃", - "黍", - "黑", - "黹", - "黽", - "鼎", - "鼓", - "鼠", - "鼻", - "齊", - "齒", - "龍", - "龜", - "龠", - None, - " ", - None, - ".", - None, - "〒", - None, - "十", - "卄", - "卅", - None, - None, - None, - None, - None, - " ゙", - " ゚", - None, - "より", - None, - "コト", - None, - None, - None, - "ᄀ", - "ᄁ", - "ᆪ", - "ᄂ", - "ᆬ", - "ᆭ", - "ᄃ", - "ᄄ", - "ᄅ", - "ᆰ", - "ᆱ", - "ᆲ", - "ᆳ", - "ᆴ", - "ᆵ", - "ᄚ", - "ᄆ", - "ᄇ", - "ᄈ", - "ᄡ", - "ᄉ", - "ᄊ", - "ᄋ", - "ᄌ", - "ᄍ", - "ᄎ", - "ᄏ", - "ᄐ", - "ᄑ", - "ᄒ", - "ᅡ", - "ᅢ", - "ᅣ", - "ᅤ", - "ᅥ", - "ᅦ", - "ᅧ", - "ᅨ", - "ᅩ", - "ᅪ", - "ᅫ", - "ᅬ", - "ᅭ", - "ᅮ", - "ᅯ", - "ᅰ", - "ᅱ", - "ᅲ", - "ᅳ", - "ᅴ", - "ᅵ", - None, - "ᄔ", - "ᄕ", - "ᇇ", - "ᇈ", - "ᇌ", - "ᇎ", - "ᇓ", - "ᇗ", - "ᇙ", - "ᄜ", - "ᇝ", - "ᇟ", - "ᄝ", - "ᄞ", - "ᄠ", - "ᄢ", - "ᄣ", - "ᄧ", - "ᄩ", - "ᄫ", - "ᄬ", - "ᄭ", - "ᄮ", - "ᄯ", - "ᄲ", - "ᄶ", - "ᅀ", - "ᅇ", - "ᅌ", - "ᇱ", - "ᇲ", - "ᅗ", - "ᅘ", - "ᅙ", - "ᆄ", - "ᆅ", - "ᆈ", - "ᆑ", - "ᆒ", - "ᆔ", - "ᆞ", - "ᆡ", - None, - None, - "一", - "二", - "三", - "四", - "上", - "中", - "下", - "甲", - "乙", - "丙", - "丁", - "天", - "地", - "人", - None, - None, - None, - "(ᄀ)", - "(ᄂ)", - "(ᄃ)", - "(ᄅ)", - "(ᄆ)", - "(ᄇ)", - "(ᄉ)", - "(ᄋ)", - "(ᄌ)", - "(ᄎ)", - "(ᄏ)", - "(ᄐ)", - "(ᄑ)", - "(ᄒ)", - "(가)", - "(나)", - "(다)", - "(라)", - "(마)", - "(바)", - "(사)", - "(아)", - "(자)", - "(차)", - "(카)", - "(타)", - "(파)", - "(하)", - "(주)", - "(오전)", - "(오후)", - None, - "(一)", - "(二)", - "(三)", - "(四)", - "(五)", - "(六)", - "(七)", - "(八)", - "(九)", - "(十)", - "(月)", - "(火)", - "(水)", - "(木)", - "(金)", - "(土)", - "(日)", - "(株)", - "(有)", - "(社)", - "(名)", - "(特)", - "(財)", - "(祝)", - "(労)", - "(代)", - "(呼)", - "(学)", - "(監)", - "(企)", - "(資)", - "(協)", - "(祭)", - "(休)", - "(自)", - "(至)", - "問", - "幼", - "文", - "箏", - None, - "pte", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - "29", - "30", - "31", - "32", - "33", - "34", - "35", - "ᄀ", - "ᄂ", - "ᄃ", - "ᄅ", - "ᄆ", - "ᄇ", - "ᄉ", - "ᄋ", - "ᄌ", - "ᄎ", - "ᄏ", - "ᄐ", - "ᄑ", - "ᄒ", - "가", - "나", - "다", - "라", - "마", - "바", - "사", - "아", - "자", - "차", - "카", - "타", - "파", - "하", - "참고", - "주의", - "우", - None, - "一", - "二", - "三", - "四", - "五", - "六", - "七", - "八", - "九", - "十", - "月", - "火", - "水", - "木", - "金", - "土", - "日", - "株", - "有", - "社", - "名", - "特", - "財", - "祝", - "労", - "秘", - "男", - "女", - "適", - "優", - "印", - "注", - "項", - "休", - "写", - "正", - "上", - "中", - "下", - "左", - "右", - "医", - "宗", - "学", - "監", - "企", - "資", - "協", - "夜", - "36", - "37", - "38", - "39", - "40", - "41", - "42", - "43", - "44", - "45", - "46", - "47", - "48", - "49", - "50", - "1月", - "2月", - "3月", - "4月", - "5月", - "6月", - "7月", - "8月", - "9月", - "10月", - "11月", - "12月", - "hg", - "erg", - "ev", - "ltd", - "ア", - "イ", - "ウ", - "エ", - "オ", - "カ", - "キ", - "ク", - "ケ", - "コ", - "サ", - "シ", - "ス", - "セ", - "ソ", - "タ", - "チ", - "ツ", - "テ", - "ト", - "ナ", - "ニ", - "ヌ", - "ネ", - "ノ", - "ハ", - "ヒ", - "フ", - "ヘ", - "ホ", - "マ", - "ミ", - "ム", - "メ", - "モ", - "ヤ", - "ユ", - "ヨ", - "ラ", - "リ", - "ル", - "レ", - "ロ", - "ワ", - "ヰ", - "ヱ", - "ヲ", - "令和", - "アパート", - "アルファ", - "アンペア", - "アール", - "イニング", - "インチ", - "ウォン", - "エスクード", - "エーカー", - "オンス", - "オーム", - "カイリ", - "カラット", - "カロリー", - "ガロン", - "ガンマ", - "ギガ", - "ギニー", - "キュリー", - "ギルダー", - "キロ", - "キログラム", - "キロメートル", - "キロワット", - "グラム", - "グラムトン", - "クルゼイロ", - "クローネ", - "ケース", - "コルナ", - "コーポ", - "サイクル", - "サンチーム", - "シリング", - "センチ", - "セント", - "ダース", - "デシ", - "ドル", - "トン", - "ナノ", - "ノット", - "ハイツ", - "パーセント", - "パーツ", - "バーレル", - "ピアストル", - "ピクル", - "ピコ", - "ビル", - "ファラッド", - "フィート", - "ブッシェル", - "フラン", - "ヘクタール", - "ペソ", - "ペニヒ", - "ヘルツ", - "ペンス", - "ページ", - "ベータ", - "ポイント", - "ボルト", - "ホン", - "ポンド", - "ホール", - "ホーン", - "マイクロ", - "マイル", - "マッハ", - "マルク", - "マンション", - "ミクロン", - "ミリ", - "ミリバール", - "メガ", - "メガトン", - "メートル", - "ヤード", - "ヤール", - "ユアン", - "リットル", - "リラ", - "ルピー", - "ルーブル", - "レム", - "レントゲン", - "ワット", - "0点", - "1点", - "2点", - "3点", - "4点", - "5点", - "6点", - "7点", - "8点", - "9点", - "10点", - "11点", - "12点", - "13点", - "14点", - "15点", - "16点", - "17点", - "18点", - "19点", - "20点", - "21点", - "22点", - "23点", - "24点", - "hpa", - "da", - "au", - "bar", - "ov", - "pc", - "dm", - "dm2", - "dm3", - "iu", - "平成", - "昭和", - "大正", - "明治", - "株式会社", - "pa", - "na", - "μa", - "ma", - "ka", - "kb", - "mb", - "gb", - "cal", - "kcal", - "pf", - "nf", - "μf", - "μg", - "mg", - "kg", - "hz", - "khz", - "mhz", - "ghz", - "thz", - "μl", - "ml", - "dl", - "kl", - "fm", - "nm", - "μm", - "mm", - "cm", - "km", - "mm2", - "cm2", - "m2", - "km2", - "mm3", - "cm3", - "m3", - "km3", - "m∕s", - "m∕s2", - "pa", - "kpa", - "mpa", - "gpa", - "rad", - "rad∕s", - "rad∕s2", - "ps", - "ns", - "μs", - "ms", - "pv", - "nv", - "μv", - "mv", - "kv", - "mv", - "pw", - "nw", - "μw", - "mw", - "kw", - "mw", - "kω", - "mω", - None, - "bq", - "cc", - "cd", - "c∕kg", - None, - "db", - "gy", - "ha", - "hp", - "in", - "kk", - "km", - "kt", - "lm", - "ln", - "log", - "lx", - "mb", - "mil", - "mol", - "ph", - None, - "ppm", - "pr", - "sr", - "sv", - "wb", - "v∕m", - "a∕m", - "1日", - "2日", - "3日", - "4日", - "5日", - "6日", - "7日", - "8日", - "9日", - "10日", - "11日", - "12日", - "13日", - "14日", - "15日", - "16日", - "17日", - "18日", - "19日", - "20日", - "21日", - "22日", - "23日", - "24日", - "25日", - "26日", - "27日", - "28日", - "29日", - "30日", - "31日", - "gal", - None, - None, - None, - None, - None, - None, - "ꙁ", - None, - "ꙃ", - None, - "ꙅ", - None, - "ꙇ", - None, - "ꙉ", - None, - "ꙋ", - None, - "ꙍ", - None, - "ꙏ", - None, - "ꙑ", - None, - "ꙓ", - None, - "ꙕ", - None, - "ꙗ", - None, - "ꙙ", - None, - "ꙛ", - None, - "ꙝ", - None, - "ꙟ", - None, - "ꙡ", - None, - "ꙣ", - None, - "ꙥ", - None, - "ꙧ", - None, - "ꙩ", - None, - "ꙫ", - None, - "ꙭ", - None, - "ꚁ", - None, - "ꚃ", - None, - "ꚅ", - None, - "ꚇ", - None, - "ꚉ", - None, - "ꚋ", - None, - "ꚍ", - None, - "ꚏ", - None, - "ꚑ", - None, - "ꚓ", - None, - "ꚕ", - None, - "ꚗ", - None, - "ꚙ", - None, - "ꚛ", - None, - "ъ", - "ь", - None, - None, - None, - "ꜣ", - None, - "ꜥ", - None, - "ꜧ", - None, - "ꜩ", - None, - "ꜫ", - None, - "ꜭ", - None, - "ꜯ", - None, - "ꜳ", - None, - "ꜵ", - None, - "ꜷ", - None, - "ꜹ", - None, - "ꜻ", - None, - "ꜽ", - None, - "ꜿ", - None, - "ꝁ", - None, - "ꝃ", - None, - "ꝅ", - None, - "ꝇ", - None, - "ꝉ", - None, - "ꝋ", - None, - "ꝍ", - None, - "ꝏ", - None, - "ꝑ", - None, - "ꝓ", - None, - "ꝕ", - None, - "ꝗ", - None, - "ꝙ", - None, - "ꝛ", - None, - "ꝝ", - None, - "ꝟ", - None, - "ꝡ", - None, - "ꝣ", - None, - "ꝥ", - None, - "ꝧ", - None, - "ꝩ", - None, - "ꝫ", - None, - "ꝭ", - None, - "ꝯ", - None, - "ꝯ", - None, - "ꝺ", - None, - "ꝼ", - None, - "ᵹ", - "ꝿ", - None, - "ꞁ", - None, - "ꞃ", - None, - "ꞅ", - None, - "ꞇ", - None, - "ꞌ", - None, - "ɥ", - None, - "ꞑ", - None, - "ꞓ", - None, - "ꞗ", - None, - "ꞙ", - None, - "ꞛ", - None, - "ꞝ", - None, - "ꞟ", - None, - "ꞡ", - None, - "ꞣ", - None, - "ꞥ", - None, - "ꞧ", - None, - "ꞩ", - None, - "ɦ", - "ɜ", - "ɡ", - "ɬ", - "ɪ", - None, - "ʞ", - "ʇ", - "ʝ", - "ꭓ", - "ꞵ", - None, - "ꞷ", - None, - "ꞹ", - None, - "ꞻ", - None, - "ꞽ", - None, - "ꞿ", - None, - "ꟁ", - None, - "ꟃ", - None, - "ꞔ", - "ʂ", - "ᶎ", - "ꟈ", - None, - "ꟊ", - None, - "ɤ", - "ꟍ", - None, - "꟏", - None, - "ꟑ", - None, - "ꟓ", - None, - "ꟕ", - None, - "ꟗ", - None, - "ꟙ", - None, - "ꟛ", - None, - "ƛ", - "ɷ", - None, - "ɼ", - None, - "s", - "c", - "f", - "q", - "ꟶ", - None, - "ħ", - "œ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ꜧ", - "ꬷ", - "ɫ", - "ꭒ", - None, - "ʍ", - None, - "ꭋ", - "ꭌ", - None, - "Ꭰ", - "Ꭱ", - "Ꭲ", - "Ꭳ", - "Ꭴ", - "Ꭵ", - "Ꭶ", - "Ꭷ", - "Ꭸ", - "Ꭹ", - "Ꭺ", - "Ꭻ", - "Ꭼ", - "Ꭽ", - "Ꭾ", - "Ꭿ", - "Ꮀ", - "Ꮁ", - "Ꮂ", - "Ꮃ", - "Ꮄ", - "Ꮅ", - "Ꮆ", - "Ꮇ", - "Ꮈ", - "Ꮉ", - "Ꮊ", - "Ꮋ", - "Ꮌ", - "Ꮍ", - "Ꮎ", - "Ꮏ", - "Ꮐ", - "Ꮑ", - "Ꮒ", - "Ꮓ", - "Ꮔ", - "Ꮕ", - "Ꮖ", - "Ꮗ", - "Ꮘ", - "Ꮙ", - "Ꮚ", - "Ꮛ", - "Ꮜ", - "Ꮝ", - "Ꮞ", - "Ꮟ", - "Ꮠ", - "Ꮡ", - "Ꮢ", - "Ꮣ", - "Ꮤ", - "Ꮥ", - "Ꮦ", - "Ꮧ", - "Ꮨ", - "Ꮩ", - "Ꮪ", - "Ꮫ", - "Ꮬ", - "Ꮭ", - "Ꮮ", - "Ꮯ", - "Ꮰ", - "Ꮱ", - "Ꮲ", - "Ꮳ", - "Ꮴ", - "Ꮵ", - "Ꮶ", - "Ꮷ", - "Ꮸ", - "Ꮹ", - "Ꮺ", - "Ꮻ", - "Ꮼ", - "Ꮽ", - "Ꮾ", - "Ꮿ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "豈", - "更", - "車", - "賈", - "滑", - "串", - "句", - "龜", - "契", - "金", - "喇", - "奈", - "懶", - "癩", - "羅", - "蘿", - "螺", - "裸", - "邏", - "樂", - "洛", - "烙", - "珞", - "落", - "酪", - "駱", - "亂", - "卵", - "欄", - "爛", - "蘭", - "鸞", - "嵐", - "濫", - "藍", - "襤", - "拉", - "臘", - "蠟", - "廊", - "朗", - "浪", - "狼", - "郎", - "來", - "冷", - "勞", - "擄", - "櫓", - "爐", - "盧", - "老", - "蘆", - "虜", - "路", - "露", - "魯", - "鷺", - "碌", - "祿", - "綠", - "菉", - "錄", - "鹿", - "論", - "壟", - "弄", - "籠", - "聾", - "牢", - "磊", - "賂", - "雷", - "壘", - "屢", - "樓", - "淚", - "漏", - "累", - "縷", - "陋", - "勒", - "肋", - "凜", - "凌", - "稜", - "綾", - "菱", - "陵", - "讀", - "拏", - "樂", - "諾", - "丹", - "寧", - "怒", - "率", - "異", - "北", - "磻", - "便", - "復", - "不", - "泌", - "數", - "索", - "參", - "塞", - "省", - "葉", - "說", - "殺", - "辰", - "沈", - "拾", - "若", - "掠", - "略", - "亮", - "兩", - "凉", - "梁", - "糧", - "良", - "諒", - "量", - "勵", - "呂", - "女", - "廬", - "旅", - "濾", - "礪", - "閭", - "驪", - "麗", - "黎", - "力", - "曆", - "歷", - "轢", - "年", - "憐", - "戀", - "撚", - "漣", - "煉", - "璉", - "秊", - "練", - "聯", - "輦", - "蓮", - "連", - "鍊", - "列", - "劣", - "咽", - "烈", - "裂", - "說", - "廉", - "念", - "捻", - "殮", - "簾", - "獵", - "令", - "囹", - "寧", - "嶺", - "怜", - "玲", - "瑩", - "羚", - "聆", - "鈴", - "零", - "靈", - "領", - "例", - "禮", - "醴", - "隸", - "惡", - "了", - "僚", - "寮", - "尿", - "料", - "樂", - "燎", - "療", - "蓼", - "遼", - "龍", - "暈", - "阮", - "劉", - "杻", - "柳", - "流", - "溜", - "琉", - "留", - "硫", - "紐", - "類", - "六", - "戮", - "陸", - "倫", - "崙", - "淪", - "輪", - "律", - "慄", - "栗", - "率", - "隆", - "利", - "吏", - "履", - "易", - "李", - "梨", - "泥", - "理", - "痢", - "罹", - "裏", - "裡", - "里", - "離", - "匿", - "溺", - "吝", - "燐", - "璘", - "藺", - "隣", - "鱗", - "麟", - "林", - "淋", - "臨", - "立", - "笠", - "粒", - "狀", - "炙", - "識", - "什", - "茶", - "刺", - "切", - "度", - "拓", - "糖", - "宅", - "洞", - "暴", - "輻", - "行", - "降", - "見", - "廓", - "兀", - "嗀", - None, - "塚", - None, - "晴", - None, - "凞", - "猪", - "益", - "礼", - "神", - "祥", - "福", - "靖", - "精", - "羽", - None, - "蘒", - None, - "諸", - None, - "逸", - "都", - None, - "飯", - "飼", - "館", - "鶴", - "郞", - "隷", - "侮", - "僧", - "免", - "勉", - "勤", - "卑", - "喝", - "嘆", - "器", - "塀", - "墨", - "層", - "屮", - "悔", - "慨", - "憎", - "懲", - "敏", - "既", - "暑", - "梅", - "海", - "渚", - "漢", - "煮", - "爫", - "琢", - "碑", - "社", - "祉", - "祈", - "祐", - "祖", - "祝", - "禍", - "禎", - "穀", - "突", - "節", - "練", - "縉", - "繁", - "署", - "者", - "臭", - "艹", - "著", - "褐", - "視", - "謁", - "謹", - "賓", - "贈", - "辶", - "逸", - "難", - "響", - "頻", - "恵", - "𤋮", - "舘", - None, - "並", - "况", - "全", - "侀", - "充", - "冀", - "勇", - "勺", - "喝", - "啕", - "喙", - "嗢", - "塚", - "墳", - "奄", - "奔", - "婢", - "嬨", - "廒", - "廙", - "彩", - "徭", - "惘", - "慎", - "愈", - "憎", - "慠", - "懲", - "戴", - "揄", - "搜", - "摒", - "敖", - "晴", - "朗", - "望", - "杖", - "歹", - "殺", - "流", - "滛", - "滋", - "漢", - "瀞", - "煮", - "瞧", - "爵", - "犯", - "猪", - "瑱", - "甆", - "画", - "瘝", - "瘟", - "益", - "盛", - "直", - "睊", - "着", - "磌", - "窱", - "節", - "类", - "絛", - "練", - "缾", - "者", - "荒", - "華", - "蝹", - "襁", - "覆", - "視", - "調", - "諸", - "請", - "謁", - "諾", - "諭", - "謹", - "變", - "贈", - "輸", - "遲", - "醙", - "鉶", - "陼", - "難", - "靖", - "韛", - "響", - "頋", - "頻", - "鬒", - "龜", - "𢡊", - "𢡄", - "𣏕", - "㮝", - "䀘", - "䀹", - "𥉉", - "𥳐", - "𧻓", - "齃", - "龎", - None, - "ff", - "fi", - "fl", - "ffi", - "ffl", - "st", - None, - "մն", - "մե", - "մի", - "վն", - "մխ", - None, - "יִ", - None, - "ײַ", - "ע", - "א", - "ד", - "ה", - "כ", - "ל", - "ם", - "ר", - "ת", - "+", - "שׁ", - "שׂ", - "שּׁ", - "שּׂ", - "אַ", - "אָ", - "אּ", - "בּ", - "גּ", - "דּ", - "הּ", - "וּ", - "זּ", - None, - "טּ", - "יּ", - "ךּ", - "כּ", - "לּ", - None, - "מּ", - None, - "נּ", - "סּ", - None, - "ףּ", - "פּ", - None, - "צּ", - "קּ", - "רּ", - "שּ", - "תּ", - "וֹ", - "בֿ", - "כֿ", - "פֿ", - "אל", - "ٱ", - "ٻ", - "پ", - "ڀ", - "ٺ", - "ٿ", - "ٹ", - "ڤ", - "ڦ", - "ڄ", - "ڃ", - "چ", - "ڇ", - "ڍ", - "ڌ", - "ڎ", - "ڈ", - "ژ", - "ڑ", - "ک", - "گ", - "ڳ", - "ڱ", - "ں", - "ڻ", - "ۀ", - "ہ", - "ھ", - "ے", - "ۓ", - None, - "ڭ", - "ۇ", - "ۆ", - "ۈ", - "ۇٴ", - "ۋ", - "ۅ", - "ۉ", - "ې", - "ى", - "ئا", - "ئە", - "ئو", - "ئۇ", - "ئۆ", - "ئۈ", - "ئې", - "ئى", - "ی", - "ئج", - "ئح", - "ئم", - "ئى", - "ئي", - "بج", - "بح", - "بخ", - "بم", - "بى", - "بي", - "تج", - "تح", - "تخ", - "تم", - "تى", - "تي", - "ثج", - "ثم", - "ثى", - "ثي", - "جح", - "جم", - "حج", - "حم", - "خج", - "خح", - "خم", - "سج", - "سح", - "سخ", - "سم", - "صح", - "صم", - "ضج", - "ضح", - "ضخ", - "ضم", - "طح", - "طم", - "ظم", - "عج", - "عم", - "غج", - "غم", - "فج", - "فح", - "فخ", - "فم", - "فى", - "في", - "قح", - "قم", - "قى", - "قي", - "كا", - "كج", - "كح", - "كخ", - "كل", - "كم", - "كى", - "كي", - "لج", - "لح", - "لخ", - "لم", - "لى", - "لي", - "مج", - "مح", - "مخ", - "مم", - "مى", - "مي", - "نج", - "نح", - "نخ", - "نم", - "نى", - "ني", - "هج", - "هم", - "هى", - "هي", - "يج", - "يح", - "يخ", - "يم", - "يى", - "يي", - "ذٰ", - "رٰ", - "ىٰ", - " ٌّ", - " ٍّ", - " َّ", - " ُّ", - " ِّ", - " ّٰ", - "ئر", - "ئز", - "ئم", - "ئن", - "ئى", - "ئي", - "بر", - "بز", - "بم", - "بن", - "بى", - "بي", - "تر", - "تز", - "تم", - "تن", - "تى", - "تي", - "ثر", - "ثز", - "ثم", - "ثن", - "ثى", - "ثي", - "فى", - "في", - "قى", - "قي", - "كا", - "كل", - "كم", - "كى", - "كي", - "لم", - "لى", - "لي", - "ما", - "مم", - "نر", - "نز", - "نم", - "نن", - "نى", - "ني", - "ىٰ", - "ير", - "يز", - "يم", - "ين", - "يى", - "يي", - "ئج", - "ئح", - "ئخ", - "ئم", - "ئه", - "بج", - "بح", - "بخ", - "بم", - "به", - "تج", - "تح", - "تخ", - "تم", - "ته", - "ثم", - "جح", - "جم", - "حج", - "حم", - "خج", - "خم", - "سج", - "سح", - "سخ", - "سم", - "صح", - "صخ", - "صم", - "ضج", - "ضح", - "ضخ", - "ضم", - "طح", - "ظم", - "عج", - "عم", - "غج", - "غم", - "فج", - "فح", - "فخ", - "فم", - "قح", - "قم", - "كج", - "كح", - "كخ", - "كل", - "كم", - "لج", - "لح", - "لخ", - "لم", - "له", - "مج", - "مح", - "مخ", - "مم", - "نج", - "نح", - "نخ", - "نم", - "نه", - "هج", - "هم", - "هٰ", - "يج", - "يح", - "يخ", - "يم", - "يه", - "ئم", - "ئه", - "بم", - "به", - "تم", - "ته", - "ثم", - "ثه", - "سم", - "سه", - "شم", - "شه", - "كل", - "كم", - "لم", - "نم", - "نه", - "يم", - "يه", - "ـَّ", - "ـُّ", - "ـِّ", - "طى", - "طي", - "عى", - "عي", - "غى", - "غي", - "سى", - "سي", - "شى", - "شي", - "حى", - "حي", - "جى", - "جي", - "خى", - "خي", - "صى", - "صي", - "ضى", - "ضي", - "شج", - "شح", - "شخ", - "شم", - "شر", - "سر", - "صر", - "ضر", - "طى", - "طي", - "عى", - "عي", - "غى", - "غي", - "سى", - "سي", - "شى", - "شي", - "حى", - "حي", - "جى", - "جي", - "خى", - "خي", - "صى", - "صي", - "ضى", - "ضي", - "شج", - "شح", - "شخ", - "شم", - "شر", - "سر", - "صر", - "ضر", - "شج", - "شح", - "شخ", - "شم", - "سه", - "شه", - "طم", - "سج", - "سح", - "سخ", - "شج", - "شح", - "شخ", - "طم", - "ظم", - "اً", - None, - "تجم", - "تحج", - "تحم", - "تخم", - "تمج", - "تمح", - "تمخ", - "جمح", - "حمي", - "حمى", - "سحج", - "سجح", - "سجى", - "سمح", - "سمج", - "سمم", - "صحح", - "صمم", - "شحم", - "شجي", - "شمخ", - "شمم", - "ضحى", - "ضخم", - "طمح", - "طمم", - "طمي", - "عجم", - "عمم", - "عمى", - "غمم", - "غمي", - "غمى", - "فخم", - "قمح", - "قمم", - "لحم", - "لحي", - "لحى", - "لجج", - "لخم", - "لمح", - "محج", - "محم", - "محي", - "مجح", - "مجم", - "مخج", - "مخم", - None, - "مجخ", - "همج", - "همم", - "نحم", - "نحى", - "نجم", - "نجى", - "نمي", - "نمى", - "يمم", - "بخي", - "تجي", - "تجى", - "تخي", - "تخى", - "تمي", - "تمى", - "جمي", - "جحى", - "جمى", - "سخى", - "صحي", - "شحي", - "ضحي", - "لجي", - "لمي", - "يحي", - "يجي", - "يمي", - "ممي", - "قمي", - "نحي", - "قمح", - "لحم", - "عمي", - "كمي", - "نجح", - "مخي", - "لجم", - "كمم", - "لجم", - "نجح", - "جحي", - "حجي", - "مجي", - "فمي", - "بحي", - "كمم", - "عجم", - "صمم", - "سخي", - "نجي", - None, - None, - "صلے", - "قلے", - "الله", - "اكبر", - "محمد", - "صلعم", - "رسول", - "عليه", - "وسلم", - "صلى", - "صلى الله عليه وسلم", - "جل جلاله", - "ریال", - None, - None, - ",", - "、", - None, - ":", - ";", - "!", - "?", - "〖", - "〗", - None, - None, - None, - "—", - "–", - "_", - "(", - ")", - "{", - "}", - "〔", - "〕", - "【", - "】", - "《", - "》", - "〈", - "〉", - "「", - "」", - "『", - "』", - None, - "[", - "]", - " ̅", - "_", - ",", - "、", - None, - ";", - ":", - "?", - "!", - "—", - "(", - ")", - "{", - "}", - "〔", - "〕", - "#", - "&", - "*", - "+", - "-", - "<", - ">", - "=", - None, - "\\", - "$", - "%", - "@", - None, - " ً", - "ـً", - " ٌ", - None, - " ٍ", - None, - " َ", - "ـَ", - " ُ", - "ـُ", - " ِ", - "ـِ", - " ّ", - "ـّ", - " ْ", - "ـْ", - "ء", - "آ", - "أ", - "ؤ", - "إ", - "ئ", - "ا", - "ب", - "ة", - "ت", - "ث", - "ج", - "ح", - "خ", - "د", - "ذ", - "ر", - "ز", - "س", - "ش", - "ص", - "ض", - "ط", - "ظ", - "ع", - "غ", - "ف", - "ق", - "ك", - "ل", - "م", - "ن", - "ه", - "و", - "ى", - "ي", - "لآ", - "لأ", - "لإ", - "لا", - None, - None, - None, - "!", - '"', - "#", - "$", - "%", - "&", - "'", - "(", - ")", - "*", - "+", - ",", - "-", - ".", - "/", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - ":", - ";", - "<", - "=", - ">", - "?", - "@", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "[", - "\\", - "]", - "^", - "_", - "`", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "{", - "|", - "}", - "~", - "⦅", - "⦆", - ".", - "「", - "」", - "、", - "・", - "ヲ", - "ァ", - "ィ", - "ゥ", - "ェ", - "ォ", - "ャ", - "ュ", - "ョ", - "ッ", - "ー", - "ア", - "イ", - "ウ", - "エ", - "オ", - "カ", - "キ", - "ク", - "ケ", - "コ", - "サ", - "シ", - "ス", - "セ", - "ソ", - "タ", - "チ", - "ツ", - "テ", - "ト", - "ナ", - "ニ", - "ヌ", - "ネ", - "ノ", - "ハ", - "ヒ", - "フ", - "ヘ", - "ホ", - "マ", - "ミ", - "ム", - "メ", - "モ", - "ヤ", - "ユ", - "ヨ", - "ラ", - "リ", - "ル", - "レ", - "ロ", - "ワ", - "ン", - "゙", - "゚", - None, - "ᄀ", - "ᄁ", - "ᆪ", - "ᄂ", - "ᆬ", - "ᆭ", - "ᄃ", - "ᄄ", - "ᄅ", - "ᆰ", - "ᆱ", - "ᆲ", - "ᆳ", - "ᆴ", - "ᆵ", - "ᄚ", - "ᄆ", - "ᄇ", - "ᄈ", - "ᄡ", - "ᄉ", - "ᄊ", - "ᄋ", - "ᄌ", - "ᄍ", - "ᄎ", - "ᄏ", - "ᄐ", - "ᄑ", - "ᄒ", - None, - "ᅡ", - "ᅢ", - "ᅣ", - "ᅤ", - "ᅥ", - "ᅦ", - None, - "ᅧ", - "ᅨ", - "ᅩ", - "ᅪ", - "ᅫ", - "ᅬ", - None, - "ᅭ", - "ᅮ", - "ᅯ", - "ᅰ", - "ᅱ", - "ᅲ", - None, - "ᅳ", - "ᅴ", - "ᅵ", - None, - "¢", - "£", - "¬", - " ̄", - "¦", - "¥", - "₩", - None, - "│", - "←", - "↑", - "→", - "↓", - "■", - "○", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𐐨", - "𐐩", - "𐐪", - "𐐫", - "𐐬", - "𐐭", - "𐐮", - "𐐯", - "𐐰", - "𐐱", - "𐐲", - "𐐳", - "𐐴", - "𐐵", - "𐐶", - "𐐷", - "𐐸", - "𐐹", - "𐐺", - "𐐻", - "𐐼", - "𐐽", - "𐐾", - "𐐿", - "𐑀", - "𐑁", - "𐑂", - "𐑃", - "𐑄", - "𐑅", - "𐑆", - "𐑇", - "𐑈", - "𐑉", - "𐑊", - "𐑋", - "𐑌", - "𐑍", - "𐑎", - "𐑏", - None, - None, - None, - None, - "𐓘", - "𐓙", - "𐓚", - "𐓛", - "𐓜", - "𐓝", - "𐓞", - "𐓟", - "𐓠", - "𐓡", - "𐓢", - "𐓣", - "𐓤", - "𐓥", - "𐓦", - "𐓧", - "𐓨", - "𐓩", - "𐓪", - "𐓫", - "𐓬", - "𐓭", - "𐓮", - "𐓯", - "𐓰", - "𐓱", - "𐓲", - "𐓳", - "𐓴", - "𐓵", - "𐓶", - "𐓷", - "𐓸", - "𐓹", - "𐓺", - "𐓻", - None, - None, - None, - None, - None, - None, - None, - None, - "𐖗", - "𐖘", - "𐖙", - "𐖚", - "𐖛", - "𐖜", - "𐖝", - "𐖞", - "𐖟", - "𐖠", - "𐖡", - None, - "𐖣", - "𐖤", - "𐖥", - "𐖦", - "𐖧", - "𐖨", - "𐖩", - "𐖪", - "𐖫", - "𐖬", - "𐖭", - "𐖮", - "𐖯", - "𐖰", - "𐖱", - None, - "𐖳", - "𐖴", - "𐖵", - "𐖶", - "𐖷", - "𐖸", - "𐖹", - None, - "𐖻", - "𐖼", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ː", - "ˑ", - "æ", - "ʙ", - "ɓ", - None, - "ʣ", - "ꭦ", - "ʥ", - "ʤ", - "ɖ", - "ɗ", - "ᶑ", - "ɘ", - "ɞ", - "ʩ", - "ɤ", - "ɢ", - "ɠ", - "ʛ", - "ħ", - "ʜ", - "ɧ", - "ʄ", - "ʪ", - "ʫ", - "ɬ", - "𝼄", - "ꞎ", - "ɮ", - "𝼅", - "ʎ", - "𝼆", - "ø", - "ɶ", - "ɷ", - "q", - "ɺ", - "𝼈", - "ɽ", - "ɾ", - "ʀ", - "ʨ", - "ʦ", - "ꭧ", - "ʧ", - "ʈ", - "ⱱ", - None, - "ʏ", - "ʡ", - "ʢ", - "ʘ", - "ǀ", - "ǁ", - "ǂ", - "𝼊", - "𝼞", - "ʇ", - "ʖ", - "ʗ", - "ʞ", - "𝼋", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𐳀", - "𐳁", - "𐳂", - "𐳃", - "𐳄", - "𐳅", - "𐳆", - "𐳇", - "𐳈", - "𐳉", - "𐳊", - "𐳋", - "𐳌", - "𐳍", - "𐳎", - "𐳏", - "𐳐", - "𐳑", - "𐳒", - "𐳓", - "𐳔", - "𐳕", - "𐳖", - "𐳗", - "𐳘", - "𐳙", - "𐳚", - "𐳛", - "𐳜", - "𐳝", - "𐳞", - "𐳟", - "𐳠", - "𐳡", - "𐳢", - "𐳣", - "𐳤", - "𐳥", - "𐳦", - "𐳧", - "𐳨", - "𐳩", - "𐳪", - "𐳫", - "𐳬", - "𐳭", - "𐳮", - "𐳯", - "𐳰", - "𐳱", - "𐳲", - None, - None, - None, - None, - None, - None, - None, - None, - "𐵰", - "𐵱", - "𐵲", - "𐵳", - "𐵴", - "𐵵", - "𐵶", - "𐵷", - "𐵸", - "𐵹", - "𐵺", - "𐵻", - "𐵼", - "𐵽", - "𐵾", - "𐵿", - "𐶀", - "𐶁", - "𐶂", - "𐶃", - "𐶄", - "𐶅", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𑣀", - "𑣁", - "𑣂", - "𑣃", - "𑣄", - "𑣅", - "𑣆", - "𑣇", - "𑣈", - "𑣉", - "𑣊", - "𑣋", - "𑣌", - "𑣍", - "𑣎", - "𑣏", - "𑣐", - "𑣑", - "𑣒", - "𑣓", - "𑣔", - "𑣕", - "𑣖", - "𑣗", - "𑣘", - "𑣙", - "𑣚", - "𑣛", - "𑣜", - "𑣝", - "𑣞", - "𑣟", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𖹠", - "𖹡", - "𖹢", - "𖹣", - "𖹤", - "𖹥", - "𖹦", - "𖹧", - "𖹨", - "𖹩", - "𖹪", - "𖹫", - "𖹬", - "𖹭", - "𖹮", - "𖹯", - "𖹰", - "𖹱", - "𖹲", - "𖹳", - "𖹴", - "𖹵", - "𖹶", - "𖹷", - "𖹸", - "𖹹", - "𖹺", - "𖹻", - "𖹼", - "𖹽", - "𖹾", - "𖹿", - None, - None, - "𖺻", - "𖺼", - "𖺽", - "𖺾", - "𖺿", - "𖻀", - "𖻁", - "𖻂", - "𖻃", - "𖻄", - "𖻅", - "𖻆", - "𖻇", - "𖻈", - "𖻉", - "𖻊", - "𖻋", - "𖻌", - "𖻍", - "𖻎", - "𖻏", - "𖻐", - "𖻑", - "𖻒", - "𖻓", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "こと", - "トキ", - "トテ", - "ヨリ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𝅗𝅥", - "𝅘𝅥", - "𝅘𝅥𝅮", - "𝅘𝅥𝅯", - "𝅘𝅥𝅰", - "𝅘𝅥𝅱", - "𝅘𝅥𝅲", - None, - None, - None, - "𝆹𝅥", - "𝆺𝅥", - "𝆹𝅥𝅮", - "𝆺𝅥𝅮", - "𝆹𝅥𝅯", - "𝆺𝅥𝅯", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - None, - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - None, - "c", - "d", - None, - "g", - None, - "j", - "k", - None, - "n", - "o", - "p", - "q", - None, - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - None, - "f", - None, - "h", - "i", - "j", - "k", - "l", - "m", - "n", - None, - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - None, - "d", - "e", - "f", - "g", - None, - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - None, - "s", - "t", - "u", - "v", - "w", - "x", - "y", - None, - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - None, - "d", - "e", - "f", - "g", - None, - "i", - "j", - "k", - "l", - "m", - None, - "o", - None, - "s", - "t", - "u", - "v", - "w", - "x", - "y", - None, - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "ı", - "ȷ", - "ss", - None, - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "θ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∇", - "α", - "β", - "γ", - "δ", - "ε", - "ζ", - "η", - "θ", - "ι", - "κ", - "λ", - "μ", - "ν", - "ξ", - "ο", - "π", - "ρ", - "σ", - "τ", - "υ", - "φ", - "χ", - "ψ", - "ω", - "∂", - "ε", - "θ", - "κ", - "φ", - "ρ", - "π", - "ϝ", - None, - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𝽁", - None, - "𝽉", - None, - "𝽋", - None, - "𝽎", - None, - "𝽒", - None, - "𝽩", - None, - "𝽫", - None, - "𝽭", - None, - "𝽯", - None, - "𝽳", - None, - "𝽵", - None, - "𝽷", - None, - "𝽹", - None, - "𝽻", - None, - "𝽽", - None, - "𝽿", - None, - None, - None, - "ss", - None, - None, - "𝽗", - "𝽘", - "𝽙", - "ɣ", - "ᴘ", - "ƀ", - "đ", - "ǥ", - "ł", - "ƚ", - "𝽐", - "𝼾", - "ɉ", - "ᵿ", - "𝼿", - "ƞ", - "ɼ", - "ȸ", - "ȹ", - "𝼫", - "𝼙", - "ʆ", - "ᶘ", - "𝼬", - "𝼜", - "ʓ", - "ᶚ", - "ᴅ", - "ᴀ", - "ᴇ", - "ɿ", - "ʅ", - "ʮ", - "ʯ", - "ȡ", - "ȴ", - "ȵ", - "ȶ", - "ψ", - "ω", - "ᶁ", - "ꞕ", - "ᶇ", - "ᶊ", - "ᶎ", - "ƈ", - "ƙ", - "ƥ", - "ʠ", - "ƭ", - "𝼉", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "а", - "б", - "в", - "г", - "д", - "е", - "ж", - "з", - "и", - "к", - "л", - "м", - "о", - "п", - "р", - "с", - "т", - "у", - "ф", - "х", - "ц", - "ч", - "ш", - "ы", - "э", - "ю", - "ꚉ", - "ә", - "і", - "ј", - "ө", - "ү", - "ӏ", - "а", - "б", - "в", - "г", - "д", - "е", - "ж", - "з", - "и", - "к", - "л", - "о", - "п", - "с", - "у", - "ф", - "х", - "ц", - "ч", - "ш", - "ъ", - "ы", - "ґ", - "і", - "ѕ", - "џ", - "ҫ", - "ꙑ", - "ұ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "𞤢", - "𞤣", - "𞤤", - "𞤥", - "𞤦", - "𞤧", - "𞤨", - "𞤩", - "𞤪", - "𞤫", - "𞤬", - "𞤭", - "𞤮", - "𞤯", - "𞤰", - "𞤱", - "𞤲", - "𞤳", - "𞤴", - "𞤵", - "𞤶", - "𞤷", - "𞤸", - "𞤹", - "𞤺", - "𞤻", - "𞤼", - "𞤽", - "𞤾", - "𞤿", - "𞥀", - "𞥁", - "𞥂", - "𞥃", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "ا", - "ب", - "ج", - "د", - None, - "و", - "ز", - "ح", - "ط", - "ي", - "ك", - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - "ر", - "ش", - "ت", - "ث", - "خ", - "ذ", - "ض", - "ظ", - "غ", - "ٮ", - "ں", - "ڡ", - "ٯ", - None, - "ب", - "ج", - None, - "ه", - None, - "ح", - None, - "ي", - "ك", - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - None, - "ش", - "ت", - "ث", - "خ", - None, - "ض", - None, - "غ", - None, - "ج", - None, - "ح", - None, - "ي", - None, - "ل", - None, - "ن", - "س", - "ع", - None, - "ص", - "ق", - None, - "ش", - None, - "خ", - None, - "ض", - None, - "غ", - None, - "ں", - None, - "ٯ", - None, - "ب", - "ج", - None, - "ه", - None, - "ح", - "ط", - "ي", - "ك", - None, - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - None, - "ش", - "ت", - "ث", - "خ", - None, - "ض", - "ظ", - "غ", - "ٮ", - None, - "ڡ", - None, - "ا", - "ب", - "ج", - "د", - "ه", - "و", - "ز", - "ح", - "ط", - "ي", - None, - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - "ر", - "ش", - "ت", - "ث", - "خ", - "ذ", - "ض", - "ظ", - "غ", - None, - "ب", - "ج", - "د", - None, - "و", - "ز", - "ح", - "ط", - "ي", - None, - "ل", - "م", - "ن", - "س", - "ع", - "ف", - "ص", - "ق", - "ر", - "ش", - "ت", - "ث", - "خ", - "ذ", - "ض", - "ظ", - "غ", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "0,", - "1,", - "2,", - "3,", - "4,", - "5,", - "6,", - "7,", - "8,", - "9,", - None, - "(a)", - "(b)", - "(c)", - "(d)", - "(e)", - "(f)", - "(g)", - "(h)", - "(i)", - "(j)", - "(k)", - "(l)", - "(m)", - "(n)", - "(o)", - "(p)", - "(q)", - "(r)", - "(s)", - "(t)", - "(u)", - "(v)", - "(w)", - "(x)", - "(y)", - "(z)", - "〔s〕", - "c", - "r", - "cd", - "wz", - None, - "a", - "b", - "c", - "d", - "e", - "f", - "g", - "h", - "i", - "j", - "k", - "l", - "m", - "n", - "o", - "p", - "q", - "r", - "s", - "t", - "u", - "v", - "w", - "x", - "y", - "z", - "hv", - "mv", - "sd", - "ss", - "ppv", - "wc", - None, - "mc", - "md", - "mr", - None, - "dj", - None, - None, - None, - "ほか", - "ココ", - "サ", - None, - "手", - "字", - "双", - "デ", - "二", - "多", - "解", - "天", - "交", - "映", - "無", - "料", - "前", - "後", - "再", - "新", - "初", - "終", - "生", - "販", - "声", - "吹", - "演", - "投", - "捕", - "一", - "三", - "遊", - "左", - "中", - "右", - "指", - "走", - "打", - "禁", - "空", - "合", - "満", - "有", - "月", - "申", - "割", - "営", - "配", - None, - "〔本〕", - "〔三〕", - "〔二〕", - "〔安〕", - "〔点〕", - "〔打〕", - "〔盗〕", - "〔勝〕", - "〔敗〕", - None, - "得", - "可", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - "丽", - "丸", - "乁", - "𠄢", - "你", - "侮", - "侻", - "倂", - "偺", - "備", - "僧", - "像", - "㒞", - "𠘺", - "免", - "兔", - "兤", - "具", - "𠔜", - "㒹", - "內", - "再", - "𠕋", - "冗", - "冤", - "仌", - "冬", - "况", - "𩇟", - "凵", - "刃", - "㓟", - "刻", - "剆", - "割", - "剷", - "㔕", - "勇", - "勉", - "勤", - "勺", - "包", - "匆", - "北", - "卉", - "卑", - "博", - "即", - "卽", - "卿", - "𠨬", - "灰", - "及", - "叟", - "𠭣", - "叫", - "叱", - "吆", - "咞", - "吸", - "呈", - "周", - "咢", - "哶", - "唐", - "啓", - "啣", - "善", - "喙", - "喫", - "喳", - "嗂", - "圖", - "嘆", - "圗", - "噑", - "噴", - "切", - "壮", - "城", - "埴", - "堍", - "型", - "堲", - "報", - "墬", - "𡓤", - "売", - "壷", - "夆", - "多", - "夢", - "奢", - "𡚨", - "𡛪", - "姬", - "娛", - "娧", - "姘", - "婦", - "㛮", - "㛼", - "嬈", - "嬾", - "𡧈", - "寃", - "寘", - "寧", - "寳", - "𡬘", - "寿", - "将", - "当", - "尢", - "㞁", - "屠", - "屮", - "峀", - "岍", - "𡷤", - "嵃", - "𡷦", - "嵮", - "嵫", - "嵼", - "巡", - "巢", - "㠯", - "巽", - "帨", - "帽", - "幩", - "㡢", - "𢆃", - "㡼", - "庰", - "庳", - "庶", - "廊", - "𪎒", - "廾", - "𢌱", - "舁", - "弢", - "㣇", - "𣊸", - "𦇚", - "形", - "彫", - "㣣", - "徚", - "忍", - "志", - "忹", - "悁", - "㤺", - "㤜", - "悔", - "𢛔", - "惇", - "慈", - "慌", - "慎", - "慌", - "慺", - "憎", - "憲", - "憤", - "憯", - "懞", - "懲", - "懶", - "成", - "戛", - "扝", - "抱", - "拔", - "捐", - "𢬌", - "挽", - "拼", - "捨", - "掃", - "揤", - "𢯱", - "搢", - "揅", - "掩", - "㨮", - "摩", - "摾", - "撝", - "摷", - "㩬", - "敏", - "敬", - "𣀊", - "旣", - "書", - "晉", - "㬙", - "暑", - "㬈", - "㫤", - "冒", - "冕", - "最", - "暜", - "肭", - "䏙", - "朗", - "望", - "朡", - "杞", - "杓", - "𣏃", - "㭉", - "柺", - "枅", - "桒", - "梅", - "𣑭", - "梎", - "栟", - "椔", - "㮝", - "楂", - "榣", - "槪", - "檨", - "𣚣", - "櫛", - "㰘", - "次", - "𣢧", - "歔", - "㱎", - "歲", - "殟", - "殺", - "殻", - "𣪍", - "𡴋", - "𣫺", - "汎", - "𣲼", - "沿", - "泍", - "汧", - "洖", - "派", - "海", - "流", - "浩", - "浸", - "涅", - "𣴞", - "洴", - "港", - "湮", - "㴳", - "滋", - "滇", - "𣻑", - "淹", - "潮", - "𣽞", - "𣾎", - "濆", - "瀹", - "瀞", - "瀛", - "㶖", - "灊", - "災", - "灷", - "炭", - "𠔥", - "煅", - "𤉣", - "熜", - "𤎫", - "爨", - "爵", - "牐", - "𤘈", - "犀", - "犕", - "𤜵", - "𤠔", - "獺", - "王", - "㺬", - "玥", - "㺸", - "瑇", - "瑜", - "瑱", - "璅", - "瓊", - "㼛", - "甤", - "𤰶", - "甾", - "𤲒", - "異", - "𢆟", - "瘐", - "𤾡", - "𤾸", - "𥁄", - "㿼", - "䀈", - "直", - "𥃳", - "𥃲", - "𥄙", - "𥄳", - "眞", - "真", - "睊", - "䀹", - "瞋", - "䁆", - "䂖", - "𥐝", - "硎", - "碌", - "磌", - "䃣", - "𥘦", - "祖", - "𥚚", - "𥛅", - "福", - "秫", - "䄯", - "穀", - "穊", - "穏", - "𥥼", - "𥪧", - "竮", - "䈂", - "𥮫", - "篆", - "築", - "䈧", - "𥲀", - "糒", - "䊠", - "糨", - "糣", - "紀", - "𥾆", - "絣", - "䌁", - "緇", - "縂", - "繅", - "䌴", - "𦈨", - "𦉇", - "䍙", - "𦋙", - "罺", - "𦌾", - "羕", - "翺", - "者", - "𦓚", - "𦔣", - "聠", - "𦖨", - "聰", - "𣍟", - "䏕", - "育", - "脃", - "䐋", - "脾", - "媵", - "𦞧", - "𦞵", - "𣎓", - "𣎜", - "舁", - "舄", - "辞", - "䑫", - "芑", - "芋", - "芝", - "劳", - "花", - "芳", - "芽", - "苦", - "𦬼", - "若", - "茝", - "荣", - "莭", - "茣", - "莽", - "菧", - "著", - "荓", - "菊", - "菌", - "菜", - "𦰶", - "𦵫", - "𦳕", - "䔫", - "蓱", - "蓳", - "蔖", - "𧏊", - "蕤", - "𦼬", - "䕝", - "䕡", - "𦾱", - "𧃒", - "䕫", - "虐", - "虜", - "虧", - "虩", - "蚩", - "蚈", - "蜎", - "蛢", - "蝹", - "蜨", - "蝫", - "螆", - "䗗", - "蟡", - "蠁", - "䗹", - "衠", - "衣", - "𧙧", - "裗", - "裞", - "䘵", - "裺", - "㒻", - "𧢮", - "𧥦", - "䚾", - "䛇", - "誠", - "諭", - "變", - "豕", - "𧲨", - "貫", - "賁", - "贛", - "起", - "𧼯", - "𠠄", - "跋", - "趼", - "跰", - "𠣞", - "軔", - "輸", - "𨗒", - "𨗭", - "邔", - "郱", - "鄑", - "𨜮", - "鄛", - "鈸", - "鋗", - "鋘", - "鉼", - "鏹", - "鐕", - "𨯺", - "開", - "䦕", - "閷", - "𨵷", - "䧦", - "雃", - "嶲", - "霣", - "𩅅", - "𩈚", - "䩮", - "䩶", - "韠", - "𩐊", - "䪲", - "𩒖", - "頋", - "頩", - "𩖶", - "飢", - "䬳", - "餩", - "馧", - "駂", - "駾", - "䯎", - "𩬰", - "鬒", - "鱀", - "鳽", - "䳎", - "䳭", - "鵧", - "𪃎", - "䳸", - "𪄅", - "𪈎", - "𪊑", - "麻", - "䵖", - "黹", - "黾", - "鼅", - "鼏", - "鼖", - "鼻", - "𪘀", - None, - None, - None, - None, - None, - None, - None, - None, - None, -) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-api.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-configuration.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-distro.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-http-transport.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-common.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-common.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-file.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-json-http.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-common.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-otlp-proto-http.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-exporter-prometheus.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation-aiohttp-client.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-instrumentation.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-propagator-b3.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto-json.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-proto.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-sdk.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-semantic-conventions.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry-util-http.LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py deleted file mode 100644 index 9bfc71644e8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/__init__.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -""" -The OpenTelemetry logging API describes the classes used to generate logs and events. - -The :class:`.LoggerProvider` provides users access to the :class:`.Logger`. - -This module provides abstract (i.e. unimplemented) classes required for -logging, and a concrete no-op implementation :class:`.NoOpLogger` that allows applications -to use the API package alone without a supporting implementation. - -To get a logger, you need to provide the package name from which you are -calling the logging APIs to OpenTelemetry by calling `LoggerProvider.get_logger` -with the calling module name and the version of your package. - -The following code shows how to obtain a logger using the global :class:`.LoggerProvider`:: - - from opentelemetry._logs import get_logger - - logger = get_logger("example-logger") - -.. versionadded:: 1.15.0 -""" - -from opentelemetry.agent._vendor.opentelemetry._logs._internal import ( - Logger, - LoggerProvider, - LogRecord, - NoOpLogger, - NoOpLoggerProvider, - get_logger, - get_logger_provider, - set_logger_provider, -) -from opentelemetry.agent._vendor.opentelemetry._logs.severity import SeverityNumber - -__all__ = [ - "LogRecord", - "Logger", - "LoggerProvider", - "NoOpLogger", - "NoOpLoggerProvider", - "SeverityNumber", - "get_logger", - "get_logger_provider", - "set_logger_provider", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py deleted file mode 100644 index da2c77dbfc6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/_internal/__init__.py +++ /dev/null @@ -1,484 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -""" -The OpenTelemetry logging API describes the classes used to generate logs and events. - -The :class:`.LoggerProvider` provides users access to the :class:`.Logger`. - -This module provides abstract (i.e. unimplemented) classes required for -logging, and a concrete no-op implementation :class:`.NoOpLogger` that allows applications -to use the API package alone without a supporting implementation. - -To get a logger, you need to provide the package name from which you are -calling the logging APIs to OpenTelemetry by calling `LoggerProvider.get_logger` -with the calling module name and the version of your package. - -The following code shows how to obtain a logger using the global :class:`.LoggerProvider`:: - - from opentelemetry._logs import get_logger - - logger = get_logger("example-logger") - -.. versionadded:: 1.15.0 -""" - -from __future__ import annotations - -from abc import ABC, abstractmethod -from logging import getLogger -from os import environ -from time import time_ns -from typing import cast, overload - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry._logs.severity import SeverityNumber -from opentelemetry.agent._vendor.opentelemetry.context import get_current -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.environment_variables import _OTEL_PYTHON_LOGGER_PROVIDER -from opentelemetry.agent._vendor.opentelemetry.trace import get_current_span -from opentelemetry.agent._vendor.opentelemetry.trace.span import TraceFlags -from opentelemetry.agent._vendor.opentelemetry.util._once import Once -from opentelemetry.agent._vendor.opentelemetry.util._providers import _load_provider -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes - -_logger = getLogger(__name__) - - -class LogRecord(ABC): - """A LogRecord instance represents an event being logged. - - LogRecord instances are created and emitted via `Logger` - every time something is logged. They contain all the information - pertinent to the event being logged. - """ - - @overload - def __init__( - self, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_text: str | None = None, - severity_number: SeverityNumber | None = None, - body: AnyValue = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: ... - - @overload - @deprecated( - "LogRecord init with `trace_id`, `span_id`, and/or `trace_flags` is deprecated since 1.35.0. Use `context` instead." - ) - def __init__( - self, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - trace_id: int | None = None, - span_id: int | None = None, - trace_flags: TraceFlags | None = None, - severity_text: str | None = None, - severity_number: SeverityNumber | None = None, - body: AnyValue = None, - attributes: Attributes = None, - ) -> None: ... - - def __init__( - self, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - trace_id: int | None = None, - span_id: int | None = None, - trace_flags: TraceFlags | None = None, - severity_text: str | None = None, - severity_number: SeverityNumber | None = None, - body: AnyValue = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: - if not context: - context = get_current() - span_context = get_current_span(context).get_span_context() - self.timestamp = timestamp - if observed_timestamp is None: - observed_timestamp = time_ns() - self.observed_timestamp = observed_timestamp - self.context = context - self.trace_id = trace_id or span_context.trace_id - self.span_id = span_id or span_context.span_id - self.trace_flags = trace_flags or span_context.trace_flags - self.severity_text = severity_text - self.severity_number = severity_number - self.body = body - self.attributes = attributes - self.event_name = event_name - self.exception = exception - - -class Logger(ABC): - """Handles emitting events and logs via `LogRecord`.""" - - def __init__( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> None: - super().__init__() - self._name = name - self._version = version - self._schema_url = schema_url - self._attributes = attributes - - @overload - def emit( - self, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: ... - - @overload - def emit( - self, - record: LogRecord, - ) -> None: ... - - @abstractmethod - def emit( - self, - record: LogRecord | None = None, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: - """Emits a :class:`LogRecord` representing a log to the processing pipeline.""" - - @abstractmethod - def enabled( - self, - *, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - event_name: str | None = None, - ) -> bool: - """Returns whether the logger is enabled for the given arguments. - - Instrumentation should call this before performing expensive work to - construct a log record, and skip that work if ``False`` is returned. - - The returned value may change over time and should be checked each time - before emitting a log record. - """ - - -class NoOpLogger(Logger): - """The default Logger used when no Logger implementation is available. - - All operations are no-op. - """ - - @overload - def emit( - self, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: ... - - @overload - def emit( # pylint:disable=arguments-differ - self, - record: LogRecord, - ) -> None: ... - - def emit( - self, - record: LogRecord | None = None, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: - pass - - def enabled( - self, - *, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - event_name: str | None = None, - ) -> bool: - return False - - -class ProxyLogger(Logger): - def __init__( # pylint: disable=super-init-not-called - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ): - self._name = name - self._version = version - self._schema_url = schema_url - self._attributes = attributes - self._real_logger: Logger | None = None - self._noop_logger = NoOpLogger(name) - - @property - def _logger(self) -> Logger: - if self._real_logger: - return self._real_logger - - if _LOGGER_PROVIDER: - self._real_logger = _LOGGER_PROVIDER.get_logger( - self._name, - self._version, - self._schema_url, - self._attributes, - ) - return self._real_logger - return self._noop_logger - - @overload - def emit( - self, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: ... - - @overload - def emit( # pylint:disable=arguments-differ - self, - record: LogRecord, - ) -> None: ... - - def emit( - self, - record: LogRecord | None = None, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: - if record: - self._logger.emit(record) - else: - self._logger.emit( - timestamp=timestamp, - observed_timestamp=observed_timestamp, - context=context, - severity_number=severity_number, - severity_text=severity_text, - body=body, - attributes=attributes, - event_name=event_name, - exception=exception, - ) - - def enabled( - self, - *, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - event_name: str | None = None, - ) -> bool: - return self._logger.enabled( - context=context, - severity_number=severity_number, - event_name=event_name, - ) - - -class LoggerProvider(ABC): - """ - LoggerProvider is the entry point of the API. It provides access to Logger instances. - """ - - @abstractmethod - def get_logger( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> Logger: - """Returns a `Logger` for use by the given instrumentation library. - - For any two calls with identical parameters, it is undefined whether the same - or different `Logger` instances are returned. - - This function may return different `Logger` types (e.g. a no-op logger - vs. a functional logger). - - Args: - name: The name of the instrumenting module, package or class. - This should *not* be the name of the module, package or class that is - instrumented but the name of the code doing the instrumentation. - E.g., instead of ``"requests"``, use - ``"opentelemetry.instrumentation.requests"``. - - For log sources which define a logger name (e.g. logging.Logger.name) - the Logger Name should be recorded as the instrumentation scope name. - - version: Optional. The version string of the - instrumenting library. Usually this should be the same as - ``importlib.metadata.version(instrumenting_library_name)``. - - schema_url: Optional. Specifies the Schema URL of the emitted telemetry. - - attributes: Optional. Specifies the instrumentation scope attributes to - associate with emitted telemetry. - """ - - -class NoOpLoggerProvider(LoggerProvider): - """The default LoggerProvider used when no LoggerProvider implementation is available.""" - - def get_logger( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> Logger: - """Returns a NoOpLogger.""" - return NoOpLogger(name, version=version, schema_url=schema_url, attributes=attributes) - - -class ProxyLoggerProvider(LoggerProvider): - def get_logger( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> Logger: - if _LOGGER_PROVIDER: - return _LOGGER_PROVIDER.get_logger( - name, - version=version, - schema_url=schema_url, - attributes=attributes, - ) - return ProxyLogger( - name, - version=version, - schema_url=schema_url, - attributes=attributes, - ) - - -_LOGGER_PROVIDER_SET_ONCE = Once() -_LOGGER_PROVIDER: LoggerProvider | None = None -_PROXY_LOGGER_PROVIDER = ProxyLoggerProvider() - - -def get_logger_provider() -> LoggerProvider: - """Gets the current global :class:`~.LoggerProvider` object.""" - global _LOGGER_PROVIDER # pylint: disable=global-variable-not-assigned - if _LOGGER_PROVIDER is None: - if _OTEL_PYTHON_LOGGER_PROVIDER not in environ: - return _PROXY_LOGGER_PROVIDER - - logger_provider: LoggerProvider = _load_provider( # type: ignore - _OTEL_PYTHON_LOGGER_PROVIDER, "logger_provider" - ) - _set_logger_provider(logger_provider, log=False) - - # _LOGGER_PROVIDER will have been set by one thread - return cast("LoggerProvider", _LOGGER_PROVIDER) - - -def _set_logger_provider(logger_provider: LoggerProvider, log: bool) -> None: - def set_lp() -> None: - global _LOGGER_PROVIDER # pylint: disable=global-statement - _LOGGER_PROVIDER = logger_provider - - did_set = _LOGGER_PROVIDER_SET_ONCE.do_once(set_lp) - - if log and not did_set: - _logger.warning("Overriding of current LoggerProvider is not allowed") - - -def set_logger_provider(logger_provider: LoggerProvider) -> None: - """Sets the current global :class:`~.LoggerProvider` object. - - This can only be done once, a warning will be logged if any further attempt - is made. - """ - _set_logger_provider(logger_provider, log=True) - - -def get_logger( - instrumenting_module_name: str, - instrumenting_library_version: str = "", - logger_provider: LoggerProvider | None = None, - schema_url: str | None = None, - attributes: Attributes = None, -) -> Logger: - """Returns a `Logger` for use within a python process. - - This function is a convenience wrapper for - opentelemetry.sdk._logs.LoggerProvider.get_logger. - - If logger_provider param is omitted the current configured one is used. - """ - if logger_provider is None: - logger_provider = get_logger_provider() - return logger_provider.get_logger( - instrumenting_module_name, - instrumenting_library_version, - schema_url, - attributes, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py deleted file mode 100644 index 96ffcc6229e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/_logs/severity/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import enum - - -class SeverityNumber(enum.Enum): - """Numerical value of severity. - - Smaller numerical values correspond to less severe events - (such as debug events), larger numerical values correspond - to more severe events (such as errors and critical events). - - See the `Log Data Model`_ spec for more info and how to map the - severity from source format to OTLP Model. - - .. _Log Data Model: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber - """ - - UNSPECIFIED = 0 - TRACE = 1 - TRACE2 = 2 - TRACE3 = 3 - TRACE4 = 4 - DEBUG = 5 - DEBUG2 = 6 - DEBUG3 = 7 - DEBUG4 = 8 - INFO = 9 - INFO2 = 10 - INFO3 = 11 - INFO4 = 12 - WARN = 13 - WARN2 = 14 - WARN3 = 15 - WARN4 = 16 - ERROR = 17 - ERROR2 = 18 - ERROR3 = 19 - ERROR4 = 20 - FATAL = 21 - FATAL2 = 22 - FATAL3 = 23 - FATAL4 = 24 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py deleted file mode 100644 index 2e5947c315f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/attributes/__init__.py +++ /dev/null @@ -1,243 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pyright: reportUnnecessaryIsInstance=false - -import copy -import logging -import threading -from collections.abc import Mapping, MutableMapping, Sequence -from types import NoneType -from typing import TYPE_CHECKING, Any, overload - -from opentelemetry.agent._vendor.typing_extensions import assert_never, deprecated - -from opentelemetry.agent._vendor.opentelemetry.util import types - -_logger = logging.getLogger(__name__) - - -# Calling str(x) will use an object's `__str__` method if it exists, otherwise it will use it's `__repr__` method. -# If neither is defined it uses the base class's `object.__repr__` method, which returns a string that is hard to understand. -# So in that case we drop the key/value pair. -def _is_non_custom_str(key: Any) -> bool: - return type(key).__str__ is not object.__str__ or type(key).__repr__ is not object.__repr__ - - -@overload -def _clean_attribute_value( - value: Mapping[str, types.AnyValue], - max_string_value_length: int | None, -) -> Mapping[str, types.AnyValue]: ... - - -@overload -def _clean_attribute_value( - value: types.AnyValue, - max_string_value_length: int | None, -) -> types.AnyValue: ... - - -def _clean_attribute_value( - value: types.AnyValue, - max_string_value_length: int | None, -) -> types.AnyValue: - """Recursively checks if an attribute value is valid and cleans it if required. - - String values are truncated to max_string_value_length if provided. - Anything that isn't of `types.AnyValue`, we attempt to cast to `str`. - If this fails, the value is replaced with None. Sequence's are converted to tuples and mappings - are copied into new dicts. - - Returns: - The recursively cleaned AnyValue. - """ - if isinstance(value, (NoneType, bool, int, float, bytes)): - return value - if isinstance(value, str): - if max_string_value_length is not None and len(value) > max_string_value_length: - _logger.warning( - "String attribute value exceeds max length of %d, truncating.", - max_string_value_length, - ) - value = value[:max_string_value_length] - return value - if isinstance(value, Sequence): - return tuple(_clean_attribute_value(v, max_string_value_length) for v in value) - if isinstance(value, Mapping): - cleaned_mapping: dict[str, types.AnyValue] = {} - for key, val in value.items(): - if not key: - _logger.warning( - "invalid attribute key `%s`. must be non-empty string. Dropping key from attributes.", - key, - ) - continue - # Spec says to convert unknown types to strings if possible (here and below too). - if not isinstance(key, str): - _logger.warning( - "Invalid type `%s` for attribute key `%s`, must be a str. Key's `__str__/__repr__` method will be called if it exists, otherwise the key/value pair will be dropped.", - type(key), - key, - ) - if _is_non_custom_str(key): - key = str(key) - else: - continue - cleaned_mapping[key] = _clean_attribute_value(val, max_string_value_length) - return cleaned_mapping - if TYPE_CHECKING: - assert_never(value) - _logger.warning( - "Invalid type `%s` for attribute value. Expected one of bool, str, None, bytes, int, float or a " - "Mapping or Sequence of those types. Value's __str__ method will be called if it exists, otherwise the value will be replaced with None.", - type(value), - ) - if _is_non_custom_str(value): - return str(value) - return None - - -class BoundedAttributes(MutableMapping[str, types.AnyValue]): - """A dict with a fixed max capacity which cleans and potentially drops values to ensure they are valid attribute values. - - Args: - maxlen: The maximum number of attributes to store, use None for no limit. - attributes: The initial attributes to store. - immutable: Defaults to true. Whether to allow adding/removing of attributes after the initialisation of the instance. - max_value_len: The maximum length of string values, use None for no limit. - extended_attributes: Deprecated. Kept for backwards compatibility. Extended attributes are now always used for attributes everywhere. - - When the dict is full and a new element is added, the oldest element is dropped. Attributes are made to be immutable when set in this container. - So passing a mutable list as an attribute value, and then mutating it after will not change it's value in this container. - """ - - @overload - def __init__( - self, - maxlen: int | None = None, - attributes: types.Attributes = None, - immutable: bool = True, - max_value_len: int | None = None, - ) -> None: ... - - @overload - @deprecated( - "Creating BoundedAttributes with `extended_attributes` set is deprecated. " - "The `extended_attributes` param is no longer used and will be removed " - "in a future release. Extended attributes are now always used for attributes everywhere." - ) - def __init__( - self, - maxlen: int | None = None, - attributes: types.Attributes = None, - immutable: bool = True, - max_value_len: int | None = None, - extended_attributes: bool = False, - ) -> None: ... - - def __init__( - self, - maxlen: int | None = None, - attributes: types.Attributes = None, - immutable: bool = True, - max_value_len: int | None = None, - extended_attributes: bool = False, - ) -> None: - if maxlen is not None and maxlen < 0: - raise ValueError("maxlen must be valid int greater or equal to 0") - if max_value_len is not None and max_value_len < 0: - raise ValueError("max_value_len must be valid int greater or equal to 0") - self._dict: dict[str, types.AnyValue] = {} - self.maxlen = maxlen - self.dropped = 0 - self.max_value_len = max_value_len - self._lock = threading.Lock() - # setting False before adding items - self._immutable = False - if attributes: - self._set_items(attributes) - self._immutable = immutable - - def __repr__(self) -> str: - return f"{dict(self._dict)}" - - def __getitem__(self, key: str) -> types.AnyValue: - return self._dict[key] - - def _raise_if_immutable(self) -> None: - if self._immutable: - raise TypeError("Cannot mutate immutable BoundedAttributes") - - def __setitem__(self, key: str, value: types.AnyValue) -> None: - self._raise_if_immutable() - if self.maxlen is not None and self.maxlen == 0: - with self._lock: - self.dropped += 1 - return - if not key or not isinstance(key, str): - _logger.warning( - "invalid key `%s`. must be non-empty string. Dropping key from attributes.", - key, - ) - with self._lock: - self.dropped += 1 - return - cleaned = _clean_attribute_value(value, self.max_value_len) - with self._lock: - self._setitem_locked(key, cleaned) - - def _set_items(self, attributes: Mapping[str, types.AnyValue]) -> None: - self._raise_if_immutable() - if self.maxlen is not None and self.maxlen == 0: - with self._lock: - self.dropped += len(attributes) - return - cleaned_attributes: Mapping[str, types.AnyValue] = _clean_attribute_value(attributes, self.max_value_len) - with self._lock: - self.dropped += len(attributes) - len(cleaned_attributes) - for key, value in cleaned_attributes.items(): - self._setitem_locked(key, value) - - def _setitem_locked(self, key: str, value: types.AnyValue) -> None: - if key in self._dict: - del self._dict[key] - if self.maxlen is not None and len(self._dict) >= self.maxlen: - _logger.warning( - "Attributes dict is full. Dropping the oldest key-value pair from attributes to make space for the new key-value pair.", - ) - # Dictionaries are insertion ordered in Python, this is the recommended way to get the oldest value. - del self._dict[next(iter(self._dict.keys()))] - self.dropped += 1 - - self._dict[key] = value - - def __delitem__(self, key: str) -> None: - self._raise_if_immutable() - del self._dict[key] - - def __iter__(self): - if self._immutable: - return iter(self._dict) - with self._lock: - return iter(list(self._dict)) - - def __len__(self) -> int: - return len(self._dict) - - def __deepcopy__(self, memo: dict[int, Any]) -> "BoundedAttributes": - copy_ = BoundedAttributes( - maxlen=self.maxlen, - immutable=self._immutable, - max_value_len=self.max_value_len, - ) - memo[id(self)] = copy_ - with self._lock: - # Assign _dict directly to avoid re-cleaning already clean values - # and to bypass the immutability guard in __setitem__ - copy_._dict = copy.deepcopy(self._dict, memo) - copy_.dropped = self.dropped - return copy_ - - def copy(self) -> MutableMapping[str, types.AnyValue]: - return self._dict.copy() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py deleted file mode 100644 index 7e72d68e514..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/__init__.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from collections.abc import Mapping -from logging import getLogger -from re import compile -from types import MappingProxyType - -from opentelemetry.agent._vendor.opentelemetry.context import create_key, get_value, set_value -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.util.re import ( - _BAGGAGE_PROPERTY_FORMAT, - _KEY_FORMAT, - _VALUE_FORMAT, -) - -_BAGGAGE_KEY = create_key("baggage") -_logger = getLogger(__name__) - -_KEY_PATTERN = compile(_KEY_FORMAT) -_VALUE_PATTERN = compile(_VALUE_FORMAT) -_PROPERT_PATTERN = compile(_BAGGAGE_PROPERTY_FORMAT) - - -def get_all( - context: Context | None = None, -) -> Mapping[str, object]: - """Returns the name/value pairs in the Baggage - - Args: - context: The Context to use. If not set, uses current Context - - Returns: - The name/value pairs in the Baggage - """ - return MappingProxyType(_get_baggage_value(context=context)) - - -def get_baggage(name: str, context: Context | None = None) -> object | None: - """Provides access to the value for a name/value pair in the - Baggage - - Args: - name: The name of the value to retrieve - context: The Context to use. If not set, uses current Context - - Returns: - The value associated with the given name, or null if the given name is - not present. - """ - return _get_baggage_value(context=context).get(name) - - -def set_baggage(name: str, value: object, context: Context | None = None) -> Context: - """Sets a value in the Baggage - - Args: - name: The name of the value to set - value: The value to set - context: The Context to use. If not set, uses current Context - - Returns: - A Context with the value updated - """ - baggage = _get_baggage_value(context=context).copy() - baggage[name] = value - return set_value(_BAGGAGE_KEY, baggage, context=context) - - -def remove_baggage(name: str, context: Context | None = None) -> Context: - """Removes a value from the Baggage - - Args: - name: The name of the value to remove - context: The Context to use. If not set, uses current Context - - Returns: - A Context with the name/value removed - """ - baggage = _get_baggage_value(context=context).copy() - baggage.pop(name, None) - - return set_value(_BAGGAGE_KEY, baggage, context=context) - - -def clear(context: Context | None = None) -> Context: - """Removes all values from the Baggage - - Args: - context: The Context to use. If not set, uses current Context - - Returns: - A Context with all baggage entries removed - """ - return set_value(_BAGGAGE_KEY, {}, context=context) - - -def _get_baggage_value(context: Context | None = None) -> dict[str, object]: - baggage = get_value(_BAGGAGE_KEY, context=context) - if isinstance(baggage, dict): - return baggage - return {} - - -def _is_valid_key(name: str) -> bool: - return _KEY_PATTERN.fullmatch(str(name)) is not None - - -def _is_valid_value(value: object) -> bool: - parts = str(value).split(";") - # W3C Baggage allows optional whitespace between the value and ";" - is_valid_value = _VALUE_PATTERN.fullmatch(parts[0].rstrip(" \t")) is not None - if len(parts) > 1: # one or more properties metadata - for property in parts[1:]: - if _PROPERT_PATTERN.fullmatch(property) is None: - is_valid_value = False - break - return is_valid_value - - -def _is_valid_pair(key: str, value: str) -> bool: - return _is_valid_key(key) and _is_valid_value(value) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py deleted file mode 100644 index a314415242c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/baggage/propagation/__init__.py +++ /dev/null @@ -1,179 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -# -from collections.abc import Iterable, Iterator, Mapping -from logging import getLogger -from re import split -from urllib.parse import quote_plus, unquote_plus - -from opentelemetry.agent._vendor.opentelemetry.baggage import _is_valid_pair, get_all, set_baggage -from opentelemetry.agent._vendor.opentelemetry.context import get_current -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.propagators import textmap -from opentelemetry.agent._vendor.opentelemetry.util.re import _DELIMITER_PATTERN - -_logger = getLogger(__name__) - - -def _filter_valid_entries( - entries: Iterable[str], - max_pair_length: int, -) -> Iterator[str]: - for entry in entries: - if not entry: - continue - if not entry.isascii(): - _logger.warning( - "Baggage entry with key `%s` contains non-ASCII characters", - entry.split("=", 1)[0], - ) - continue - if len(entry) > max_pair_length: - _logger.warning( - "Baggage entry with key `%s` exceeded the maximum number of bytes per list-member with length %d", - entry.split("=", 1)[0], - len(entry), - ) - continue - yield entry - - -def _apply_baggage_limits( - entries: Iterable[str], - max_pairs: int, - max_pair_length: int, - max_header_length: int, -) -> Iterator[str]: - """Apply W3C Baggage size limits to a sequence of baggage entries. - - Yields entries that fit within the W3C specification limits. - Logs warnings when entries are dropped. - """ - length = 0 - for index, entry in enumerate(_filter_valid_entries(entries, max_pair_length)): - if index >= max_pairs: - _logger.warning("Baggage exceeded the maximum number of list-members") - return - - length += (1 if index > 0 else 0) + len(entry) - if length > max_header_length: - _logger.warning("Baggage exceeded the maximum number of bytes per baggage-string") - return - yield entry - - -class W3CBaggagePropagator(textmap.TextMapPropagator): - """Extracts and injects Baggage which is used to annotate telemetry.""" - - _MAX_HEADER_LENGTH = 8192 - _MAX_PAIR_LENGTH = 4096 - _MAX_PAIRS = 180 - _BAGGAGE_HEADER_NAME = "baggage" - - def extract( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, - ) -> Context: - """Extract Baggage from the carrier. - - See - `opentelemetry.propagators.textmap.TextMapPropagator.extract` - """ - - if context is None: - context = get_current() - - header = _extract_first_element(getter.get(carrier, self._BAGGAGE_HEADER_NAME)) - - if not header: - return context - - if len(header.encode()) > self._MAX_HEADER_LENGTH: - _logger.warning( - "Baggage header `%s` exceeded the maximum number of bytes per baggage-string", - header, - ) - return context - - baggage_entries = split(_DELIMITER_PATTERN, header) - - for entry in _apply_baggage_limits( - baggage_entries, - max_pairs=self._MAX_PAIRS, - max_pair_length=self._MAX_PAIR_LENGTH, - max_header_length=self._MAX_HEADER_LENGTH, - ): - try: - name, value = entry.split("=", 1) - except Exception: # pylint: disable=broad-exception-caught - _logger.warning("Baggage list-member `%s` doesn't match the format", entry) - continue - - # W3C Baggage allows optional whitespace around "=" - name = name.strip(" \t") - value = value.strip(" \t") - - if not _is_valid_pair(name, value): - _logger.warning("Invalid baggage entry: `%s`", entry) - continue - - name = unquote_plus(name).strip() - value = unquote_plus(value).strip() - - context = set_baggage( - name, - value, - context=context, - ) - - return context - - def inject( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, - ) -> None: - """Injects Baggage into the carrier. - - See - `opentelemetry.propagators.textmap.TextMapPropagator.inject` - """ - baggage_entries = get_all(context=context) - if not baggage_entries: - return - - baggage_string = ",".join( - _apply_baggage_limits( - _encode_baggage_pairs(baggage_entries), - max_pairs=self._MAX_PAIRS, - max_pair_length=self._MAX_PAIR_LENGTH, - max_header_length=self._MAX_HEADER_LENGTH, - ) - ) - - if baggage_string: - setter.set(carrier, self._BAGGAGE_HEADER_NAME, baggage_string) - - @property - def fields(self) -> set[str]: - """Returns a set with the fields set in `inject`.""" - return {self._BAGGAGE_HEADER_NAME} - - -def _encode_baggage_pairs( - baggage_entries: Mapping[str, object], -) -> Iterator[str]: - """Yield URL-encoded 'key=value' pairs from baggage entries.""" - for key, value in baggage_entries.items(): - yield quote_plus(str(key)) + "=" + quote_plus(str(value)) - - -def _extract_first_element( - items: Iterable[textmap.CarrierT] | None, -) -> textmap.CarrierT | None: - if items is None: - return None - return next(iter(items), None) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md deleted file mode 100644 index b6c4ffb922f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# SDK Declarative Configuration - -This package implements [OpenTelemetry file-based configuration](https://opentelemetry.io/docs/specs/otel/configuration). - -## Files - -- `schema.json`: vendored copy of the [OpenTelemetry configuration JSON schema](https://github.com/open-telemetry/opentelemetry-configuration) -- `models.py`: Python dataclasses generated from `schema.json` by [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator), using a custom template from `opentelemetry-configuration/codegen/` (see that directory's README for details) - -## Spec conformance - -Which fields of the configuration schema the Python SDK actually applies at runtime is tracked in the shared [language support status matrix](https://github.com/open-telemetry/opentelemetry-configuration/blob/main/language-support-status.md#python) in the `opentelemetry-configuration` repository. The Python column is the source of truth; update [`schema/meta_schema_language_python.yaml`](https://github.com/open-telemetry/opentelemetry-configuration/blob/main/schema/meta_schema_language_python.yaml) there when wiring lands or changes, and the matrix regenerates. - -## Updating the schema - -1. Pick the desired release tag from the [opentelemetry-configuration releases](https://github.com/open-telemetry/opentelemetry-configuration/releases) and overwrite `opentelemetry-configuration/src/opentelemetry/configuration/schema.json` with the `opentelemetry_configuration.json` published on that release. - -2. Regenerate `models.py`: - - ```sh - tox -e generate-config-from-jsonschema - ``` - -3. Bump `_SUPPORTED_SCHEMA_MAJOR` / `_SUPPORTED_SCHEMA_MINOR` in `file/_loader.py` to the version of the vendored schema. - -4. Update any version string references in tests and source: - - ```sh - grep -r "OLD_VERSION" opentelemetry-configuration/ - ``` diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py deleted file mode 100644 index 320b8ad5d89..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -"""OpenTelemetry SDK Declarative Configuration. - -This package implements the OpenTelemetry declarative configuration -specification for the Python SDK. Load a YAML or JSON configuration file -(or build a configuration model programmatically) and apply it to the -process-global SDK providers. - -The standard activation path is the ``OTEL_CONFIG_FILE`` environment -variable, which the SDK's configurator picks up automatically. For -programmatic use: - ->>> from opentelemetry.configuration import ( -... load_config_file, -... configure_sdk, -... ) ->>> config = load_config_file("otel-config.yaml") ->>> configure_sdk(config) - -Construct a configuration programmatically and apply it: - ->>> from opentelemetry.configuration import ( -... OpenTelemetryConfiguration, -... configure_sdk, -... ) ->>> configure_sdk(OpenTelemetryConfiguration(file_format="1.0-rc.1")) - -This package is **experimental**. The API surface, type names, and -behaviour may change between minor versions. -""" - -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ConfigurationError -from opentelemetry.agent._vendor.opentelemetry.configuration._sdk import configure_sdk -from opentelemetry.agent._vendor.opentelemetry.configuration.file._loader import load_config_file -from opentelemetry.agent._vendor.opentelemetry.configuration.models import OpenTelemetryConfiguration - -__all__ = [ - "ConfigurationError", - "OpenTelemetryConfiguration", - "configure_sdk", - "load_config_file", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py deleted file mode 100644 index b5706dcc148..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_common.py +++ /dev/null @@ -1,228 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import dataclasses -import inspect -import logging -from collections.abc import Callable -from typing import Any, Protocol -from urllib.parse import urlparse - -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ConfigurationError -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points - -_logger = logging.getLogger(__name__) - - -def _additional_properties(cls): - """Decorator for dataclasses whose JSON Schema sets additionalProperties. - - Wraps the dataclass-generated ``__init__`` so that extra keyword - arguments are captured into an ``additional_properties`` instance - attribute instead of raising ``TypeError``. This lets user-defined - component names flow through the config pipeline without modifying - the codegen output for built-in fields. - - Applied automatically by the custom template in ``opentelemetry-sdk/codegen/`` - when ``additionalPropertiesType`` is present in the template context - (set by ``datamodel-codegen`` for schema types with ``additionalProperties``). - """ - original_init = cls.__init__ - original_sig = inspect.signature(original_init) - known_fields = frozenset(f.name for f in dataclasses.fields(cls)) - - def _init(self, **kwargs): - known = {k: v for k, v in kwargs.items() if k in known_fields} - extra = {k: v for k, v in kwargs.items() if k not in known_fields} - original_init(self, **known) - self.additional_properties = extra - - # Preserve the original parameter list for IDE autocompletion and - # inspect.signature(), adding **kwargs to signal extras are accepted. - # setattr used because pyright rejects direct __signature__ assignment. - params = list(original_sig.parameters.values()) - params.append(inspect.Parameter("kwargs", inspect.Parameter.VAR_KEYWORD)) - setattr(_init, "__signature__", original_sig.replace(parameters=params)) # noqa: B010 - - cls.__init__ = _init - return cls - - -def load_entry_point(group: str, name: str) -> type: - """Load a plugin class from an entry point group by name. - - Returns the loaded class — callers are responsible for instantiation - with whatever arguments their config requires. - - Raises: - ConfigurationError: If the entry point is not found or fails to load. - """ - try: - ep = next(iter(entry_points(group=group, name=name)), None) - if ep is None: - raise ConfigurationError( - f"Plugin '{name}' not found in group '{group}'. " - "Make sure the package providing this plugin is installed." - ) - return ep.load() - except ConfigurationError: - raise - except Exception as exc: - raise ConfigurationError(f"Failed to load plugin '{name}' from group '{group}': {exc}") from exc - - -class _ComponentConfig(Protocol): - """Protocol for config dataclasses decorated with @_additional_properties. - - Values in ``additional_properties`` are nested config dicts (suitable - for ``**kwargs`` splatting to the user-defined component class) or - ``None`` (when the YAML uses ``my_plugin:`` or ``my_plugin: null``). - - Note: the generated models declare ``additional_properties`` as a - ``ClassVar`` even though the decorator assigns it as an instance - attribute at runtime. This is tolerated by pyright in ``standard`` - mode but flagged in ``strict`` mode. See #5268. - """ - - additional_properties: dict[str, dict[str, Any] | None] - - -def _resolve_component( - config: _ComponentConfig, - registry: dict[str, Callable[[Any], Any]], - entry_point_group: str, - component_type: str, -) -> Any: - """Resolve a config dataclass to a component instance. - - Checks built-in factories in ``registry`` first (by matching typed - field names on ``config``), then falls back to entry point loading - for plugin components found in ``config.additional_properties``. - - The JSON schema enforces exactly one component per config block - (``minProperties: 1, maxProperties: 1``). If multiple typed fields or - ``additional_properties`` entries are set (e.g. when schema validation - is bypassed), the first registry match wins. - - Args: - config: A dataclass with ``additional_properties`` (from the - ``@_additional_properties`` decorator). - registry: Mapping of built-in component names to factory - callables. Each factory receives the field value from config. - entry_point_group: The entry point group name for plugin loading. - component_type: Human-readable name for error messages - (e.g. "span exporter"). - - Returns: - The resolved component instance. - - Raises: - ConfigurationError: If no component type is specified in config. - """ - for name, factory in registry.items(): - value = getattr(config, name, None) - if value is not None: - return factory(value) - if config.additional_properties: - name, plugin_config = next(iter(config.additional_properties.items())) - return load_entry_point(entry_point_group, name)(**(plugin_config or {})) - raise ConfigurationError(f"No {component_type} type specified in config.") - - -def _parse_headers( - headers: list | None, - headers_list: str | None, -) -> dict[str, str] | None: - """Merge headers struct and headers_list into a dict. - - Returns None if neither is set, letting the exporter read env vars. - headers struct takes priority over headers_list for the same key. - """ - if headers is None and headers_list is None: - return None - result: dict[str, str] = {} - if headers_list: - for item in headers_list.split(","): - item = item.strip() - if "=" in item: - key, value = item.split("=", 1) - result[key.strip()] = value.strip() - elif item: - _logger.warning( - "Invalid header pair in headers_list (missing '='): %s", - item, - ) - if headers: - for pair in headers: - if isinstance(pair, dict): - result[pair["name"]] = pair.get("value") or "" - else: - result[pair.name] = pair.value or "" - return result - - -def _map_compression( - value: str | None, - compression_enum: type, - *, - allow_deflate: bool = False, -) -> object | None: - """Map a compression string to the given Compression enum value.""" - if value is None: - return None - - value_lower = value.lower() - supports_deflate = hasattr(compression_enum, "Deflate") - - if value_lower == "none": - return None - if value_lower == "gzip": - return compression_enum.Gzip # type: ignore[attr-defined] - if value_lower == "deflate" and allow_deflate and supports_deflate: - return compression_enum.Deflate # type: ignore[attr-defined] - - supported_values = ["'gzip'", "'none'"] - if allow_deflate and supports_deflate: - supported_values.insert(1, "'deflate'") - - raise ConfigurationError( - f"Unsupported compression value '{value}'. Supported values: {', '.join(supported_values)}." - ) - - -def _parse_otlp_file_output_stream(output_stream: str | None) -> str | None: - """Resolve an output_stream value to a file path, or None for stdout. - - Per the OTel file exporter spec, output_stream is "stdout" (or - None, which means the same), or a "file://" URI giving a path. - """ - if output_stream is None or output_stream == "stdout": - return None - try: - parsed = urlparse(output_stream) - except ValueError as exc: - raise ConfigurationError( - f"Failed to parse output_stream '{output_stream}' for otlp_file_development exporter: {exc}" - ) from exc - is_local_file_uri = parsed.scheme == "file" and parsed.netloc in ("", "localhost") and bool(parsed.path) - has_extra_components = parsed.params or parsed.query or parsed.fragment - if is_local_file_uri and not has_extra_components: - path = parsed.path - if not path.startswith("/"): - raise ConfigurationError( - f"Unsupported output_stream '{output_stream}' for " - "otlp_file_development exporter. Path must be absolute." - ) - if path.endswith("/"): - raise ConfigurationError( - f"Unsupported output_stream '{output_stream}' for " - "otlp_file_development exporter. Path must be a file, " - "not a directory." - ) - return path - raise ConfigurationError( - f"Unsupported output_stream '{output_stream}' for otlp_file_development " - "exporter. Supported values: stdout, file://." - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py deleted file mode 100644 index dfb1a0f0209..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_conversion.py +++ /dev/null @@ -1,137 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -"""Recursive dict-to-dataclass conversion for parsed config data. - -The YAML/JSON loader produces nested dicts. Factory functions expect typed -dataclass instances (e.g. ``TracerProvider``, ``SpanProcessor``). This module -walks each field's type annotation and converts nested dicts into their -corresponding dataclass types. -""" - -from __future__ import annotations - -from collections.abc import Mapping -from dataclasses import MISSING, fields, is_dataclass -from enum import Enum -from types import UnionType -from typing import Any, TypeVar, Union, get_args, get_origin, get_type_hints - -_T = TypeVar("_T") - - -def _unwrap_optional(type_hint: Any) -> Any: - """Strip ``None`` from a ``X | None`` / ``Optional[X]`` annotation. - - Returns the unwrapped type, or the original hint if not a union with None. - """ - origin = get_origin(type_hint) - if origin is UnionType or origin is Union: - non_none = [t for t in get_args(type_hint) if t is not type(None)] - if len(non_none) == 1: - return non_none[0] - return type_hint - - -def _is_empty_constructible_dataclass(unwrapped: Any) -> bool: - """True if ``unwrapped`` is a dataclass type instantiable with no args. - - A dataclass with only optional fields (all have a default or - default_factory) can be built as ``cls()``; one with a required field - cannot, and coercing a present null into it would raise ``TypeError``. - """ - return ( - isinstance(unwrapped, type) - and is_dataclass(unwrapped) - and all(field.default is not MISSING or field.default_factory is not MISSING for field in fields(unwrapped)) - ) - - -def _convert_value(value: Any, type_hint: Any) -> Any: - """Convert a value according to its type hint. - - Recursively converts dicts to dataclasses and lists of dicts to lists of - dataclasses. Other values (primitives, enums, ``dict[str, Any]`` aliases) - pass through unchanged. - """ - unwrapped = _unwrap_optional(type_hint) - origin = get_origin(unwrapped) - - if value is None: - # A mapping key present with an empty (null) YAML value parses to - # ``None``, which is otherwise indistinguishable from an absent key. - # For object-typed nodes the declarative-config spec treats a present - # null as "select this with an empty config" — e.g. ``always_on:`` is - # equivalent to ``always_on: {}`` and a metric ``console:`` exporter to - # ``console: {}``. Substitute an empty mapping and let the dict/ - # dataclass handling below build it, so downstream ``is not None`` type - # dispatch selects it. Scalar fields — and dataclasses with required - # fields, which cannot be defaulted — keep ``None``, so an absent - # optional section stays unset. - if origin is dict or _is_empty_constructible_dataclass(unwrapped): - value = {} - else: - return None - - # list[X] — recurse on each element - if origin is list and isinstance(value, list): - args = get_args(unwrapped) - if args: - item_type = args[0] - return [_convert_value(item, item_type) for item in value] - return value - - # Direct dataclass type — recurse - if isinstance(unwrapped, type) and is_dataclass(unwrapped) and isinstance(value, dict): - return _dict_to_dataclass(value, unwrapped) - - # Enum type — coerce string/value to the Enum member - if isinstance(unwrapped, type) and issubclass(unwrapped, Enum) and not isinstance(value, unwrapped): - return unwrapped(value) - - return value - - -def _dict_to_dataclass(data: Mapping[str, Any], cls: type[_T]) -> _T: - """Recursively convert a mapping to a dataclass instance. - - For each key in ``data``: - - If it matches a known dataclass field, the value is converted according - to that field's type annotation (recursing for nested dataclasses). - - Unknown keys are passed through as kwargs; classes decorated with - ``@_additional_properties`` will capture them on the instance's - ``additional_properties`` attribute. - - ``ClassVar`` fields (e.g. the ``additional_properties`` annotation on - decorated dataclasses) are ignored as expected. - - Raises: - TypeError: If ``cls`` is not a dataclass type. - """ - if not is_dataclass(cls): - raise TypeError(f"{cls.__name__} is not a dataclass") - - # Annotated as ``dict[str, Any]`` so astroid stops tracing into - # ``get_type_hints`` — under pylint 3.x that path leads into - # Python 3.14's ``annotationlib`` (which uses t-strings) and crashes. - hints: dict[str, Any] = dict(get_type_hints(cls, include_extras=False)) - known_fields = {f.name for f in fields(cls)} - kwargs: dict[str, Any] = {} - - for key, value in data.items(): - # The OTel configuration schema uses "/" as a namespace separator for - # development/experimental features (e.g. "otlp_file/development", - # "instrumentation/development"). Python identifiers cannot contain - # "/", so the corresponding dataclass fields use "_" instead (e.g. - # "otlp_file_development"). Without this normalisation the key would - # not match any known field and would fall through to - # additional_properties, causing the factory lookup to fail silently. - field_key = key.replace("/", "_") - if field_key in known_fields: - type_hint = hints.get(field_key) - kwargs[field_key] = _convert_value(value, type_hint) - else: - # Unknown key — @_additional_properties decorator will capture it. - kwargs[key] = value - - return cls(**kwargs) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py deleted file mode 100644 index 85b73574c8e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_exceptions.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -class ConfigurationError(Exception): - """Raised when configuration loading, parsing, validation, or instantiation fails. - - This includes errors from: - - File not found or inaccessible - - Invalid YAML/JSON syntax - - Schema validation failures - - Environment variable substitution errors - - Missing required SDK extensions (e.g., propagator packages not installed) - """ - - -class MissingDependencyError(ConfigurationError, ImportError): - """Raised when an optional dependency is not installed. - - Inherits from both :class:`ConfigurationError` and :class:`ImportError` to - maintain backwards compatibility with callers that catch ``ImportError``. - - Args: - package: The name of the missing package. - feature: Optional description of the feature that requires the package. - install_name: Optional package name used in the pip install command - (defaults to ``package``). - extras: Optional extras string for the pip install command. - """ - - def __init__( - self, - package: str, - feature: str | None = None, - install_name: str | None = None, - extras: str | None = None, - ) -> None: - self.package = package - self.feature = feature - self.install_name = install_name or package - self.extras = extras - - if extras: - install_cmd = f'pip install "{self.install_name}[{extras}]"' - else: - install_cmd = f"pip install {self.install_name}" - - if feature: - message = f"{feature} requires '{package}'. Install it with: {install_cmd}" - else: - message = f"'{package}' is required but not installed. Install it with: {install_cmd}" - - super().__init__(message) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py deleted file mode 100644 index 8863f395f83..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_logger_provider.py +++ /dev/null @@ -1,386 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging - -from opentelemetry.agent._vendor.opentelemetry._logs import set_logger_provider -from opentelemetry.agent._vendor.opentelemetry.configuration._common import ( - _map_compression, - _parse_headers, - _parse_otlp_file_output_stream, - load_entry_point, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( - ConfigurationError, - MissingDependencyError, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - AttributeLimits, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - BatchLogRecordProcessor as BatchLogRecordProcessorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalLoggerConfig as LoggerConfigConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalLoggerConfigurator as LoggerConfiguratorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalOtlpFileExporter as ExperimentalOtlpFileExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - LoggerProvider as LoggerProviderConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - LogRecordExporter as LogRecordExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - LogRecordLimits as LogRecordLimitsConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - LogRecordProcessor as LogRecordProcessorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - OtlpGrpcExporter as OtlpGrpcExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - OtlpHttpExporter as OtlpHttpExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - SimpleLogRecordProcessor as SimpleLogRecordProcessorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import LoggerProvider -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal import ( - LogRecordLimits, - _LoggerConfig, - _RuleBasedLoggerConfigurator, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal.export import ( - BatchLogRecordProcessor, - ConsoleLogRecordExporter, - LogRecordExporter, - SimpleLogRecordProcessor, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob - -_logger = logging.getLogger(__name__) - -_DEFAULT_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT = 128 - -# BatchLogRecordProcessor defaults per OTel spec (milliseconds). -_DEFAULT_SCHEDULE_DELAY_MILLIS = 1000 -_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 -_DEFAULT_MAX_QUEUE_SIZE = 2048 -_DEFAULT_MAX_EXPORT_BATCH_SIZE = 512 - - -def _create_console_log_exporter() -> ConsoleLogRecordExporter: - """Create a ConsoleLogRecordExporter.""" - return ConsoleLogRecordExporter() - - -def _create_otlp_http_log_exporter( - config: OtlpHttpExporterConfig, -) -> LogRecordExporter: - """Create an OTLP HTTP log exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( # noqa: PLC0415 # type: ignore[import-untyped] - Compression, - ) - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._log_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - OTLPLogExporter, - ) - except ImportError as exc: - raise MissingDependencyError( - package="opentelemetry-exporter-otlp-proto-http", - feature="otlp_http log exporter", - ) from exc - - compression = _map_compression(config.compression, Compression, allow_deflate=True) - headers = _parse_headers(config.headers, config.headers_list) - timeout = (config.timeout / 1000.0) if config.timeout is not None else None - - return OTLPLogExporter( # type: ignore[return-value] - endpoint=config.endpoint, - headers=headers, - timeout=timeout, - compression=compression, # type: ignore[arg-type] - ) - - -def _create_otlp_grpc_log_exporter( - config: OtlpGrpcExporterConfig, -) -> LogRecordExporter: - """Create an OTLP gRPC log exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - import grpc # noqa: PLC0415 # type: ignore[import-untyped] - - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - OTLPLogExporter, - ) - except ImportError as exc: - raise MissingDependencyError( - package="opentelemetry-exporter-otlp-proto-grpc", - feature="otlp_grpc log exporter", - ) from exc - - compression = _map_compression(config.compression, grpc.Compression) - headers = _parse_headers(config.headers, config.headers_list) - timeout = (config.timeout / 1000.0) if config.timeout is not None else None - - return OTLPLogExporter( # type: ignore[return-value] - endpoint=config.endpoint, - headers=headers, - timeout=timeout, - compression=compression, # type: ignore[arg-type] - ) - - -def _create_otlp_file_development_log_exporter( - config: ExperimentalOtlpFileExporterConfig, -) -> LogRecordExporter: - """Create an OTLP file (JSON Lines) log exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._log_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - FileLogExporter, - ) - except ImportError as exc: - raise ConfigurationError( - "otlp_file_development log exporter requires 'opentelemetry-exporter-otlp-json-file'. " - "Install it with: pip install opentelemetry-exporter-otlp-json-file" - ) from exc - - path = _parse_otlp_file_output_stream(config.output_stream) - return FileLogExporter(path) if path is not None else FileLogExporter() - - -_LOG_EXPORTER_REGISTRY: dict = { - "otlp_http": _create_otlp_http_log_exporter, - "otlp_grpc": _create_otlp_grpc_log_exporter, - "console": lambda _: ConsoleLogRecordExporter(), - "otlp_file_development": _create_otlp_file_development_log_exporter, -} - - -def _create_log_record_exporter( - config: LogRecordExporterConfig, -) -> LogRecordExporter: - """Create a log record exporter from config. - - Known exporter types are checked via typed fields on the LogRecordExporter - dataclass. Unknown exporter names captured in additional_properties - by the @_additional_properties decorator are loaded via the - ``opentelemetry_logs_exporter`` entry point group. - """ - for name, factory in _LOG_EXPORTER_REGISTRY.items(): - value = getattr(config, name, None) - if value is not None: - return factory(value) - if config.additional_properties: - name, plugin_config = next(iter(config.additional_properties.items())) - return load_entry_point("opentelemetry_logs_exporter", name)(**(plugin_config or {})) - raise ConfigurationError( - "No exporter type specified in log record exporter config. " - "Supported types: console, otlp_http, otlp_grpc, otlp_file_development." - ) - - -def _create_batch_log_record_processor( - config: BatchLogRecordProcessorConfig, -) -> BatchLogRecordProcessor: - """Create a BatchLogRecordProcessor from config. - - Passes explicit defaults to suppress OTEL_BLRP_* env var reading. - """ - exporter = _create_log_record_exporter(config.exporter) - schedule_delay = config.schedule_delay if config.schedule_delay is not None else _DEFAULT_SCHEDULE_DELAY_MILLIS - export_timeout = config.export_timeout if config.export_timeout is not None else _DEFAULT_EXPORT_TIMEOUT_MILLIS - max_queue_size = config.max_queue_size if config.max_queue_size is not None else _DEFAULT_MAX_QUEUE_SIZE - max_export_batch_size = ( - config.max_export_batch_size if config.max_export_batch_size is not None else _DEFAULT_MAX_EXPORT_BATCH_SIZE - ) - return BatchLogRecordProcessor( - exporter=exporter, - schedule_delay_millis=float(schedule_delay), - export_timeout_millis=float(export_timeout), - max_queue_size=max_queue_size, - max_export_batch_size=max_export_batch_size, - ) - - -def _create_simple_log_record_processor( - config: SimpleLogRecordProcessorConfig, -) -> SimpleLogRecordProcessor: - """Create a SimpleLogRecordProcessor from config.""" - exporter = _create_log_record_exporter(config.exporter) - return SimpleLogRecordProcessor(exporter) - - -def _create_log_record_processor( - config: LogRecordProcessorConfig, -) -> BatchLogRecordProcessor | SimpleLogRecordProcessor: - """Create a log record processor from config.""" - if config.batch is not None: - return _create_batch_log_record_processor(config.batch) - if config.simple is not None: - return _create_simple_log_record_processor(config.simple) - raise ConfigurationError( - "No processor type specified in log record processor config. Supported types: batch, simple." - ) - - -def _to_logger_config(config: LoggerConfigConfig | None) -> _LoggerConfig: - """Map an experimental per-logger config to an SDK ``_LoggerConfig``. - - Only ``enabled`` is honored. ``minimum_severity`` and ``trace_based`` are - accepted by the config schema but not supported by the Python SDK - ``_LoggerConfig``; the ones that are set are ignored with a warning naming - them. An absent ``enabled`` leaves the logger enabled. - """ - if config is None: - return _LoggerConfig.default() - unsupported_fields = [ - field_name for field_name in ("minimum_severity", "trace_based") if getattr(config, field_name) is not None - ] - if unsupported_fields: - _logger.warning( - "Ignoring logger_configurator fields that are not supported by the Python SDK LoggerProvider: %s", - ", ".join(unsupported_fields), - ) - if config.enabled is None: - return _LoggerConfig.default() - return _LoggerConfig(is_enabled=config.enabled) - - -def _create_logger_configurator( - config: LoggerConfiguratorConfig, -) -> _RuleBasedLoggerConfigurator: - """Build a rule-based logger configurator from experimental config. - - Each entry in ``loggers`` maps an instrumentation-scope name glob to a - per-logger config; ``default_config`` applies to scopes matching no glob. - Rules are evaluated in order, so earlier entries take precedence. - """ - rules = [ - ( - _scope_name_matches_glob(matcher.name), - _to_logger_config(matcher.config), - ) - for matcher in (config.loggers or []) - ] - return _RuleBasedLoggerConfigurator( - rules=rules, - default_config=_to_logger_config(config.default_config), - ) - - -def _create_log_record_limits( - config: LogRecordLimitsConfig, - global_limits: AttributeLimits | None = None, -) -> LogRecordLimits: - """Create LogRecordLimits from config. - - Absent fields fall back to global_limits (if provided), then to OTel spec - defaults (128 for counts, unlimited for lengths). - Explicit values suppress env-var reading — matching Java SDK behavior. - """ - attribute_count_limit = config.attribute_count_limit - if attribute_count_limit is None and global_limits is not None: - attribute_count_limit = global_limits.attribute_count_limit - - attribute_value_length_limit = config.attribute_value_length_limit - if attribute_value_length_limit is None and global_limits is not None: - attribute_value_length_limit = global_limits.attribute_value_length_limit - - max_attributes = ( - attribute_count_limit if attribute_count_limit is not None else _DEFAULT_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT - ) - max_attribute_length = ( - attribute_value_length_limit if attribute_value_length_limit is not None else LogRecordLimits.UNSET - ) - - # The log-record-specific fields are the ones the SDK enforces, so they are - # set explicitly too. Leaving them absent would let OTEL_LOGRECORD_ATTRIBUTE_* - # override the configured values. - return LogRecordLimits( - max_attributes=max_attributes, - max_attribute_length=max_attribute_length, - max_log_record_attributes=max_attributes, - max_log_record_attribute_length=max_attribute_length, - ) - - -def create_logger_provider( - config: LoggerProviderConfig | None, - resource: Resource | None = None, - global_attribute_limits: AttributeLimits | None = None, -) -> LoggerProvider: - """Create an SDK LoggerProvider from declarative config. - - Does NOT read OTEL_BLRP_* or other env vars for values explicitly - controlled by the config. Absent config values use OTel spec defaults. - - Args: - config: LoggerProvider config from the parsed config file, or None. - resource: Resource to attach to the provider. - global_attribute_limits: Top-level attribute_limits from the root config, - used as a fallback when per-signal limits are not specified. - - Returns: - A configured LoggerProvider. - """ - logger_configurator = ( - _create_logger_configurator(config.logger_configurator_development) - if config is not None and config.logger_configurator_development is not None - else None - ) - - if config is not None and config.limits is not None: - limits = config.limits - - else: - limits = LogRecordLimitsConfig() - - log_record_limits = _create_log_record_limits(limits, global_attribute_limits) - - provider = LoggerProvider( - resource=resource, - log_record_limits=log_record_limits, - _logger_configurator=logger_configurator, - ) - - if config is None: - return provider - - for processor_config in config.processors: - provider.add_log_record_processor(_create_log_record_processor(processor_config)) - - return provider - - -def configure_logger_provider( - config: LoggerProviderConfig | None, - resource: Resource | None = None, - global_attribute_limits: AttributeLimits | None = None, -) -> None: - """Configure the global LoggerProvider from declarative config. - - When config is None (logger_provider section absent from config file), - the global is not set — matching Java/JS SDK behavior. - - Args: - config: LoggerProvider config from the parsed config file, or None. - resource: Resource to attach to the provider. - global_attribute_limits: Top-level attribute_limits from the root config, - used as a fallback when per-signal limits are not specified. - """ - if config is None: - return - set_logger_provider(create_logger_provider(config, resource, global_attribute_limits)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py deleted file mode 100644 index 30ae72cc01d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_meter_provider.py +++ /dev/null @@ -1,656 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging - -from opentelemetry.agent._vendor.opentelemetry import metrics -from opentelemetry.agent._vendor.opentelemetry.configuration._common import ( - _map_compression, - _parse_headers, - _parse_otlp_file_output_stream, - load_entry_point, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( - ConfigurationError, - MissingDependencyError, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - Aggregation as AggregationConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - CardinalityLimits as CardinalityLimitsConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ConsoleMetricExporter as ConsoleMetricExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExemplarFilter as ExemplarFilterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalMeterConfig as MeterConfigConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalMeterConfigurator as MeterConfiguratorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalOtlpFileMetricExporter as ExperimentalOtlpFileMetricExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalPrometheusMetricExporter as PrometheusMetricExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExporterDefaultHistogramAggregation, - ExporterTemporalityPreference, - InstrumentType, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - MeterProvider as MeterProviderConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - MetricReader as MetricReaderConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - OtlpGrpcMetricExporter as OtlpGrpcMetricExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - OtlpHttpMetricExporter as OtlpHttpMetricExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - PeriodicMetricReader as PeriodicMetricReaderConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - PullMetricExporter as PullMetricExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - PullMetricReader as PullMetricReaderConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - PushMetricExporter as PushMetricExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - View as ViewConfig, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( - AlwaysOffExemplarFilter, - AlwaysOnExemplarFilter, - Counter, - Histogram, - MeterProvider, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - TraceBasedExemplarFilter, - UpDownCounter, - _Gauge, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import ( - _MeterConfig, - _RuleBasedMeterConfigurator, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - AggregationTemporality, - CardinalityLimits, - ConsoleMetricExporter, - MetricExporter, - MetricReader, - PeriodicExportingMetricReader, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import ( - Aggregation, - DefaultAggregation, - DropAggregation, - ExplicitBucketHistogramAggregation, - ExponentialBucketHistogramAggregation, - LastValueAggregation, - SumAggregation, - View, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob - -_logger = logging.getLogger(__name__) - - -# Default interval/timeout per OTel spec (milliseconds). -_DEFAULT_EXPORT_INTERVAL_MILLIS = 60000 -_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 - -# Instrument type → SDK instrument class mapping (for View selectors). -_INSTRUMENT_TYPE_MAP: dict[InstrumentType, type] = { - InstrumentType.counter: Counter, - InstrumentType.up_down_counter: UpDownCounter, - InstrumentType.histogram: Histogram, - InstrumentType.gauge: _Gauge, - InstrumentType.observable_counter: ObservableCounter, - InstrumentType.observable_gauge: ObservableGauge, - InstrumentType.observable_up_down_counter: ObservableUpDownCounter, -} - - -def _map_temporality( - pref: ExporterTemporalityPreference | None, -) -> dict[type, AggregationTemporality]: - """Map a temporality preference to an explicit preferred_temporality dict. - - Always returns an explicit dict to suppress OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE. - Default (None or cumulative) → all instruments CUMULATIVE. - """ - if pref is None or pref == ExporterTemporalityPreference.cumulative: - return { - Counter: AggregationTemporality.CUMULATIVE, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.CUMULATIVE, - ObservableCounter: AggregationTemporality.CUMULATIVE, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - if pref == ExporterTemporalityPreference.delta: - return { - Counter: AggregationTemporality.DELTA, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.DELTA, - ObservableCounter: AggregationTemporality.DELTA, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - if pref == ExporterTemporalityPreference.low_memory: - return { - Counter: AggregationTemporality.DELTA, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.DELTA, - ObservableCounter: AggregationTemporality.CUMULATIVE, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - raise ConfigurationError( - f"Unsupported temporality preference '{pref}'. Supported values: cumulative, delta, low_memory." - ) - - -def _map_histogram_aggregation( - pref: ExporterDefaultHistogramAggregation | None, -) -> dict[type, Aggregation]: - """Map a histogram aggregation preference to an explicit preferred_aggregation dict. - - Always returns an explicit dict to suppress - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION. - Default (None or explicit_bucket_histogram) → ExplicitBucketHistogramAggregation. - """ - if pref is None or pref == ExporterDefaultHistogramAggregation.explicit_bucket_histogram: - return {Histogram: ExplicitBucketHistogramAggregation()} - if pref == ExporterDefaultHistogramAggregation.base2_exponential_bucket_histogram: - return {Histogram: ExponentialBucketHistogramAggregation()} - raise ConfigurationError( - f"Unsupported default histogram aggregation '{pref}'. " - "Supported values: explicit_bucket_histogram, base2_exponential_bucket_histogram." - ) - - -def _create_aggregation(config: AggregationConfig) -> Aggregation: - """Create an SDK Aggregation from config, passing through detail parameters.""" - if config.default is not None: - return DefaultAggregation() - if config.drop is not None: - return DropAggregation() - if config.explicit_bucket_histogram is not None: - return ExplicitBucketHistogramAggregation( - boundaries=config.explicit_bucket_histogram.boundaries, - record_min_max=( - config.explicit_bucket_histogram.record_min_max - if config.explicit_bucket_histogram.record_min_max is not None - else True - ), - ) - if config.base2_exponential_bucket_histogram is not None: - kwargs = {} - if config.base2_exponential_bucket_histogram.max_size is not None: - kwargs["max_size"] = config.base2_exponential_bucket_histogram.max_size - if config.base2_exponential_bucket_histogram.max_scale is not None: - kwargs["max_scale"] = config.base2_exponential_bucket_histogram.max_scale - if config.base2_exponential_bucket_histogram.record_min_max is not None: - kwargs["record_min_max"] = config.base2_exponential_bucket_histogram.record_min_max - return ExponentialBucketHistogramAggregation(**kwargs) - if config.last_value is not None: - return LastValueAggregation() - if config.sum is not None: - return SumAggregation() - raise ConfigurationError( - f"Unknown or unsupported aggregation type in config: {config!r}. " - "Supported types: default, drop, explicit_bucket_histogram, " - "base2_exponential_bucket_histogram, last_value, sum." - ) - - -def _create_view(config: ViewConfig) -> View: - """Create an SDK View from config.""" - selector = config.selector - stream = config.stream - - instrument_type = None - if selector.instrument_type is not None: - instrument_type = _INSTRUMENT_TYPE_MAP.get(selector.instrument_type) - if instrument_type is None: - raise ConfigurationError(f"Unknown instrument type: {selector.instrument_type!r}") - - attribute_keys: set[str] | None = None - if stream.attribute_keys is not None: - if stream.attribute_keys.excluded: - _logger.warning( - "attribute_keys.excluded is not supported by the Python SDK View; the exclusion list will be ignored." - ) - if stream.attribute_keys.included is not None: - attribute_keys = set(stream.attribute_keys.included) - - aggregation = None - if stream.aggregation is not None: - aggregation = _create_aggregation(stream.aggregation) - - return View( - instrument_type=instrument_type, - instrument_name=selector.instrument_name, - meter_name=selector.meter_name, - meter_version=selector.meter_version, - meter_schema_url=selector.meter_schema_url, - instrument_unit=selector.unit, - name=stream.name, - description=stream.description, - attribute_keys=attribute_keys, - aggregation=aggregation, - aggregation_cardinality_limit=stream.aggregation_cardinality_limit, - ) - - -def _create_console_metric_exporter( - config: ConsoleMetricExporterConfig, -) -> MetricExporter: - """Create a ConsoleMetricExporter from config.""" - preferred_temporality = _map_temporality(config.temporality_preference) - preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) - return ConsoleMetricExporter( - preferred_temporality=preferred_temporality, - preferred_aggregation=preferred_aggregation, - ) - - -def _create_otlp_http_metric_exporter( - config: OtlpHttpMetricExporterConfig, -) -> MetricExporter: - """Create an OTLP HTTP metric exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( # noqa: PLC0415 # type: ignore[import-untyped] - Compression, - ) - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.metric_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - OTLPMetricExporter, - ) - except ImportError as exc: - raise MissingDependencyError( - package="opentelemetry-exporter-otlp-proto-http", - feature="otlp_http metric exporter", - ) from exc - - compression = _map_compression(config.compression, Compression, allow_deflate=True) - headers = _parse_headers(config.headers, config.headers_list) - timeout = (config.timeout / 1000.0) if config.timeout is not None else None - preferred_temporality = _map_temporality(config.temporality_preference) - preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) - - return OTLPMetricExporter( # type: ignore[return-value] - endpoint=config.endpoint, - headers=headers, - timeout=timeout, - compression=compression, # type: ignore[arg-type] - preferred_temporality=preferred_temporality, - preferred_aggregation=preferred_aggregation, - ) - - -def _create_otlp_grpc_metric_exporter( - config: OtlpGrpcMetricExporterConfig, -) -> MetricExporter: - """Create an OTLP gRPC metric exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - import grpc # noqa: PLC0415 # type: ignore[import-untyped] - - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.grpc.metric_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - OTLPMetricExporter, - ) - except ImportError as exc: - raise MissingDependencyError( - package="opentelemetry-exporter-otlp-proto-grpc", - feature="otlp_grpc metric exporter", - ) from exc - - compression = _map_compression(config.compression, grpc.Compression) - headers = _parse_headers(config.headers, config.headers_list) - timeout = (config.timeout / 1000.0) if config.timeout is not None else None - preferred_temporality = _map_temporality(config.temporality_preference) - preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) - - return OTLPMetricExporter( # type: ignore[return-value] - endpoint=config.endpoint, - headers=headers, - timeout=timeout, - compression=compression, # type: ignore[arg-type] - preferred_temporality=preferred_temporality, - preferred_aggregation=preferred_aggregation, - ) - - -def _create_otlp_file_development_metric_exporter( - config: ExperimentalOtlpFileMetricExporterConfig, -) -> MetricExporter: - """Create an OTLP file (JSON Lines) metric exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.metric_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - FileMetricExporter, - ) - except ImportError as exc: - raise ConfigurationError( - "otlp_file_development metric exporter requires 'opentelemetry-exporter-otlp-json-file'. " - "Install it with: pip install opentelemetry-exporter-otlp-json-file" - ) from exc - - path = _parse_otlp_file_output_stream(config.output_stream) - preferred_temporality = _map_temporality(config.temporality_preference) - preferred_aggregation = _map_histogram_aggregation(config.default_histogram_aggregation) - return ( - FileMetricExporter( - path, - preferred_temporality=preferred_temporality, - preferred_aggregation=preferred_aggregation, - ) - if path is not None - else FileMetricExporter( - preferred_temporality=preferred_temporality, - preferred_aggregation=preferred_aggregation, - ) - ) - - -_METRIC_EXPORTER_REGISTRY: dict = { - "otlp_http": _create_otlp_http_metric_exporter, - "otlp_grpc": _create_otlp_grpc_metric_exporter, - "console": _create_console_metric_exporter, - "otlp_file_development": _create_otlp_file_development_metric_exporter, -} - - -def _create_push_metric_exporter( - config: PushMetricExporterConfig, -) -> MetricExporter: - """Create a push metric exporter from config. - - Known exporter types are checked via typed fields on the PushMetricExporter - dataclass. Unknown exporter names captured in additional_properties - by the @_additional_properties decorator are loaded via the - ``opentelemetry_metrics_exporter`` entry point group. - """ - for name, factory in _METRIC_EXPORTER_REGISTRY.items(): - value = getattr(config, name, None) - if value is not None: - return factory(value) - if config.additional_properties: - name, plugin_config = next(iter(config.additional_properties.items())) - return load_entry_point("opentelemetry_metrics_exporter", name)(**(plugin_config or {})) - raise ConfigurationError( - "No exporter type specified in push metric exporter config. " - "Supported types: console, otlp_http, otlp_grpc, otlp_file_development." - ) - - -def _create_cardinality_limits(config: CardinalityLimitsConfig | None) -> CardinalityLimits | None: - """Create the SDK per-instrument cardinality limits from config. - - Each instrument type uses its own limit and falls back to ``default``. - Instrument types left out of the result use the SDK default limit. - """ - if config is None: - return None - limits: CardinalityLimits = {} - for instrument_class, limit in ( - (Counter, config.counter), - (UpDownCounter, config.up_down_counter), - (Histogram, config.histogram), - (_Gauge, config.gauge), - (ObservableCounter, config.observable_counter), - (ObservableUpDownCounter, config.observable_up_down_counter), - (ObservableGauge, config.observable_gauge), - ): - limit = limit if limit is not None else config.default - if limit is not None: - limits[instrument_class] = limit - return limits - - -def _create_periodic_metric_reader( - config: PeriodicMetricReaderConfig, -) -> PeriodicExportingMetricReader: - """Create a PeriodicExportingMetricReader from config. - - Passes explicit interval/timeout defaults to suppress env var reading. - """ - exporter = _create_push_metric_exporter(config.exporter) - interval = config.interval if config.interval is not None else _DEFAULT_EXPORT_INTERVAL_MILLIS - timeout = config.timeout if config.timeout is not None else _DEFAULT_EXPORT_TIMEOUT_MILLIS - return PeriodicExportingMetricReader( - exporter=exporter, - export_interval_millis=float(interval), - export_timeout_millis=float(timeout), - cardinality_limits=_create_cardinality_limits(config.cardinality_limits), - ) - - -def _create_prometheus_metric_reader( - config: PrometheusMetricExporterConfig, - cardinality_limits: CardinalityLimits | None = None, -) -> MetricReader: - """Create a PrometheusMetricReader from config. - - Dynamically imports the prometheus exporter package to avoid a hard - dependency. Maps config fields to constructor parameters and starts - the HTTP server. - """ - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.exporter.prometheus import ( # noqa: PLC0415 # type: ignore[import-untyped] - PrometheusMetricReader, - start_http_server, - ) - except ImportError as exc: - raise MissingDependencyError( - package="opentelemetry-exporter-prometheus", - feature="prometheus pull metric exporter", - ) from exc - - disable_target_info = ( - config.target_info_enabled_development is not None and not config.target_info_enabled_development - ) - - if config.scope_info_enabled is not None: - _logger.warning("scope_info_enabled is not yet supported for Prometheus metric exporter and will be ignored.") - if config.resource_constant_labels is not None: - _logger.warning( - "resource_constant_labels is not yet supported for Prometheus metric exporter and will be ignored." - ) - - reader = PrometheusMetricReader( - disable_target_info=disable_target_info, - cardinality_limits=cardinality_limits, - ) - - port = config.port if config.port is not None else 9464 - host = config.host if config.host is not None else "localhost" - start_http_server(port=port, addr=host) - - return reader - - -def _create_pull_metric_exporter( - config: PullMetricExporterConfig, - cardinality_limits: CardinalityLimits | None = None, -) -> MetricReader: - """Create a pull metric exporter (which is itself a MetricReader) from config. - - Pull metric exporters like Prometheus are combined reader+exporter objects: - the "exporter" IS the reader. The config schema models them as separate - exporter configs, but the factory returns a MetricReader. - - Plugin pull exporters are loaded via the ``opentelemetry_pull_metric_exporter`` - entry point group. - """ - if config.prometheus_development is not None: - return _create_prometheus_metric_reader(config.prometheus_development, cardinality_limits) - if config.additional_properties: - name, plugin_config = next(iter(config.additional_properties.items())) - if cardinality_limits is not None: - _logger.warning( - "cardinality_limits is not yet supported for pull metric exporter plugins and will be ignored." - ) - return load_entry_point("opentelemetry_pull_metric_exporter", name)(**(plugin_config or {})) - raise ConfigurationError( - "No exporter type specified in pull metric exporter config. Supported types: prometheus_development." - ) - - -def _create_pull_metric_reader( - config: PullMetricReaderConfig, -) -> MetricReader: - """Create a pull MetricReader from config. - - The pull reader's exporter is itself a MetricReader (combined reader+exporter). - producers are not yet supported. - """ - if config.producers: - _logger.warning( - "MetricProducer configuration is not yet supported for pull metric readers and will be ignored." - ) - return _create_pull_metric_exporter(config.exporter, _create_cardinality_limits(config.cardinality_limits)) - - -def _create_metric_reader(config: MetricReaderConfig) -> MetricReader: - """Create a MetricReader from config.""" - if config.periodic is not None: - return _create_periodic_metric_reader(config.periodic) - if config.pull is not None: - return _create_pull_metric_reader(config.pull) - raise ConfigurationError("No reader type specified in metric reader config. Supported types: periodic, pull.") - - -def _create_exemplar_filter( - value: ExemplarFilterConfig, -) -> object: - """Create an SDK exemplar filter from config enum value.""" - if value == ExemplarFilterConfig.always_on: - return AlwaysOnExemplarFilter() - if value == ExemplarFilterConfig.always_off: - return AlwaysOffExemplarFilter() - if value == ExemplarFilterConfig.trace_based: - return TraceBasedExemplarFilter() - raise ConfigurationError( - f"Unknown exemplar filter value: {value!r}. Supported values: always_on, always_off, trace_based." - ) - - -def _to_meter_config(config: MeterConfigConfig | None) -> _MeterConfig: - """Map an experimental per-meter config to an SDK ``_MeterConfig``. - - Only ``enabled`` is honored — it is the sole field the SDK - ``_MeterConfig`` exposes. An absent ``enabled`` leaves the meter enabled. - """ - if config is None or config.enabled is None: - return _MeterConfig.default() - return _MeterConfig(is_enabled=config.enabled) - - -def _create_meter_configurator( - config: MeterConfiguratorConfig, -) -> _RuleBasedMeterConfigurator: - """Build a rule-based meter configurator from experimental config. - - Each entry in ``meters`` maps an instrumentation-scope name glob to a - per-meter config; ``default_config`` applies to scopes matching no glob. - Rules are evaluated in order, so earlier entries take precedence. - """ - rules = [ - ( - _scope_name_matches_glob(matcher.name), - _to_meter_config(matcher.config), - ) - for matcher in (config.meters or []) - ] - return _RuleBasedMeterConfigurator( - rules=rules, - default_config=_to_meter_config(config.default_config), - ) - - -def create_meter_provider( - config: MeterProviderConfig | None, - resource: Resource | None = None, -) -> MeterProvider: - """Create an SDK MeterProvider from declarative config. - - Does NOT read OTEL_METRIC_EXPORT_INTERVAL, OTEL_METRICS_EXEMPLAR_FILTER, - or any other env vars for values explicitly controlled by the config. - Absent config values use OTel spec defaults, matching Java SDK behavior. - - Args: - config: MeterProvider config from the parsed config file, or None. - resource: Resource to attach to the provider. - - Returns: - A configured MeterProvider. - """ - # Always pass an explicit exemplar filter to suppress env var reading. - # Spec default is trace_based. - exemplar_filter: object = TraceBasedExemplarFilter() - if config is not None and config.exemplar_filter is not None: - exemplar_filter = _create_exemplar_filter(config.exemplar_filter) - - readers: list[MetricReader] = [] - views: list[View] = [] - - if config is not None: - for reader_config in config.readers: - readers.append(_create_metric_reader(reader_config)) - if config.views: - for view_config in config.views: - views.append(_create_view(view_config)) - - meter_configurator = ( - _create_meter_configurator(config.meter_configurator_development) - if config is not None and config.meter_configurator_development is not None - else None - ) - - return MeterProvider( - resource=resource, - metric_readers=readers, - exemplar_filter=exemplar_filter, # type: ignore[arg-type] - views=views, - _meter_configurator=meter_configurator, - ) - - -def configure_meter_provider( - config: MeterProviderConfig | None, - resource: Resource | None = None, -) -> None: - """Configure the global MeterProvider from declarative config. - - When config is None (meter_provider section absent from config file), - the global is not set — matching Java/JS SDK behavior. - - Args: - config: MeterProvider config from the parsed config file, or None. - resource: Resource to attach to the provider. - """ - if config is None: - return - metrics.set_meter_provider(create_meter_provider(config, resource)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py deleted file mode 100644 index e78eec1a87a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_propagator.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from opentelemetry.agent._vendor.opentelemetry.baggage.propagation import W3CBaggagePropagator -from opentelemetry.agent._vendor.opentelemetry.configuration._common import load_entry_point -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - Propagator as PropagatorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - TextMapPropagator as TextMapPropagatorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.propagate import set_global_textmap -from opentelemetry.agent._vendor.opentelemetry.propagators.composite import CompositePropagator -from opentelemetry.agent._vendor.opentelemetry.propagators.textmap import TextMapPropagator -from opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext import ( - TraceContextTextMapPropagator, -) - -# Propagators bundled with the SDK — no entry point lookup needed. -_PROPAGATOR_REGISTRY: dict[str, type[TextMapPropagator]] = { - "tracecontext": TraceContextTextMapPropagator, - "baggage": W3CBaggagePropagator, -} - - -def _propagators_from_textmap_config( - config: TextMapPropagatorConfig, -) -> list[TextMapPropagator]: - """Resolve a TextMapPropagator config to a list of propagators. - - Known names (tracecontext, baggage) are bootstrapped directly via - _PROPAGATOR_REGISTRY. Known schema fields not in the registry (b3, b3multi) - and unknown plugin names from additional_properties are loaded via the - ``opentelemetry_propagator`` entry point group. - """ - result: list[TextMapPropagator] = [] - for name, cls in _PROPAGATOR_REGISTRY.items(): - if getattr(config, name, None) is not None: - result.append(cls()) - - # Known schema fields not in registry (b3, b3multi) — loaded via entry point - for name in ("b3", "b3multi"): - if getattr(config, name, None) is not None: - result.append(load_entry_point("opentelemetry_propagator", name)()) - - # Plugin propagators from additional_properties - for name, plugin_config in config.additional_properties.items(): - result.append(load_entry_point("opentelemetry_propagator", name)(**(plugin_config or {}))) - - return result - - -def create_propagator( - config: PropagatorConfig | None, -) -> CompositePropagator: - """Create a CompositePropagator from declarative config. - - If config is None or has no propagators defined, returns an empty - CompositePropagator (no-op), ensuring "what you see is what you get" - semantics — the env-var-based default propagators are not used. - - Args: - config: Propagator config from the parsed config file, or None. - - Returns: - A CompositePropagator wrapping all configured propagators. - """ - if config is None: - return CompositePropagator([]) - - propagators: dict[type[TextMapPropagator], TextMapPropagator] = {} - - # Process structured composite list - if config.composite: - for entry in config.composite: - for propagator in _propagators_from_textmap_config(entry): - propagators.setdefault(type(propagator), propagator) - - # Process composite_list (comma-separated propagator names via entry_points) - if config.composite_list: - for name in config.composite_list.split(","): - name = name.strip() - if not name or name.lower() == "none": - continue - propagator = load_entry_point("opentelemetry_propagator", name)() - propagators.setdefault(type(propagator), propagator) - - return CompositePropagator(list(propagators.values())) - - -def configure_propagator(config: PropagatorConfig | None) -> None: - """Configure the global text map propagator from declarative config. - - Always calls set_global_textmap to override any defaults (including the - env-var-based tracecontext+baggage default set by the SDK). - - Args: - config: Propagator config from the parsed config file, or None. - """ - set_global_textmap(create_propagator(config)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py deleted file mode 100644 index 7e9188d1511..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_resource.py +++ /dev/null @@ -1,219 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import dataclasses -import fnmatch -import logging -import os -import sys -from collections.abc import Callable -from typing import Any -from urllib import parse - -from opentelemetry.agent._vendor.opentelemetry.configuration._common import load_entry_point -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - AttributeNameValue, - AttributeType, - ExperimentalResourceDetector, - IncludeExclude, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import Resource as ResourceConfig -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import OTEL_SERVICE_NAME -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( - _DEFAULT_RESOURCE, - SERVICE_NAME, - ProcessResourceDetector, - Resource, - ServiceInstanceIdResourceDetector, - _HostResourceDetector, -) -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue - -_logger = logging.getLogger(__name__) - - -def _coerce_bool(value: object) -> bool: - if isinstance(value, str): - return value.lower() not in ("false", "0", "") - return bool(value) - - -def _array(coerce: Callable) -> Callable: - return lambda value: [coerce(item) for item in value] - - -# Dispatch table mapping AttributeType to its coercion callable -_COERCIONS = { - AttributeType.string: str, - AttributeType.int: int, - AttributeType.double: float, - AttributeType.bool: _coerce_bool, - AttributeType.string_array: _array(str), - AttributeType.int_array: _array(int), - AttributeType.double_array: _array(float), - AttributeType.bool_array: _array(_coerce_bool), -} - - -def _coerce_attribute_value(attr: AttributeNameValue) -> object: - """Coerce an attribute value to the correct Python type based on AttributeType.""" - coerce = _COERCIONS.get(attr.type) # type: ignore[arg-type] - return coerce(attr.value) if coerce is not None else attr.value # type: ignore[operator] - - -def _parse_attributes_list(attributes_list: str) -> dict[str, str]: - """Parse a comma-separated key=value string into a dict. - - Format is the same as OTEL_RESOURCE_ATTRIBUTES: key=value,key=value - Values are always strings (no type coercion). - """ - result: dict[str, str] = {} - for item in attributes_list.split(","): - item = item.strip() - if not item: - continue - if "=" not in item: - _logger.warning( - "Invalid resource attribute pair in attributes_list: %s", - item, - ) - continue - key, value = item.split("=", maxsplit=1) - result[key.strip()] = parse.unquote(value.strip()) - return result - - -def create_resource(config: ResourceConfig | None) -> Resource: - """Create an SDK Resource from declarative config. - - Does NOT read OTEL_RESOURCE_ATTRIBUTES. Resource detectors are only run - when explicitly listed under detection_development.detectors in the config. - Starts from SDK telemetry defaults (telemetry.sdk.*), merges any detected - attributes, then merges explicit config attributes on top (highest priority). - - Args: - config: Resource config from the parsed config file, or None. - - Returns: - A Resource with SDK defaults, optional detector attributes, and any - config-specified attributes merged in priority order. - """ - # Spec requires service.name to always be present; detectors and explicit - # config attributes can override this default. - executable_name = os.path.basename(sys.executable) if sys.executable else None - default_service_name = f"unknown_service:{executable_name}" if executable_name else "unknown_service" - base = _DEFAULT_RESOURCE.merge(Resource({SERVICE_NAME: default_service_name})) - - if config is None: - return base - - # attributes_list is lower priority; explicit attributes overwrite conflicts. - config_attrs: dict[str, object] = {} - if config.attributes_list: - config_attrs.update(_parse_attributes_list(config.attributes_list)) - - if config.attributes: - for attr in config.attributes: - # An unset ${VAR} with no default substitutes an empty value that - # the YAML parser reads as null. Skip such attributes rather than - # inserting a None (or coercing it into garbage like "None"/0). - if attr.value is None: - _logger.warning( - "Ignoring resource attribute '%s' with empty value", - attr.name, - ) - continue - config_attrs[attr.name] = _coerce_attribute_value(attr) - - schema_url = config.schema_url - - # Run detectors only if detection_development is configured. Collect all - # detected attributes, apply the include/exclude filter, then merge before - # config attributes so explicit values always win. - result = base - if config.detection_development: - detected_attrs: dict[str, object] = {} - if config.detection_development.detectors: - for detector_config in config.detection_development.detectors: - _run_detectors(detector_config, detected_attrs) - - filtered = _filter_attributes(detected_attrs, config.detection_development.attributes) - if filtered: - result = result.merge(Resource(filtered)) # type: ignore[arg-type] - - config_resource = Resource(config_attrs, schema_url) # type: ignore[arg-type] - return result.merge(config_resource) - - -def _detect_service(_config: Any) -> dict[str, AnyValue]: - """Service detector: generates instance ID and reads OTEL_SERVICE_NAME.""" - attrs: dict[str, AnyValue] = dict(ServiceInstanceIdResourceDetector().detect().attributes) - if service_name := os.environ.get(OTEL_SERVICE_NAME): - attrs[SERVICE_NAME] = service_name - return attrs - - -_RESOURCE_DETECTOR_REGISTRY: dict[str, Callable[[Any], dict[str, AnyValue]]] = { - "service": _detect_service, - "host": lambda _: dict(_HostResourceDetector().detect().attributes), - "process": lambda _: dict(ProcessResourceDetector().detect().attributes), -} - - -def _run_detectors( - detector_config: ExperimentalResourceDetector, - detected_attrs: dict[str, object], -) -> None: - """Run detectors present in a single detector config entry. - - Known detectors (service, host, process) are handled directly via - _RESOURCE_DETECTOR_REGISTRY. All other detectors — including known - schema fields like container that require contrib packages, and - unknown plugin detectors captured in additional_properties — are - loaded via the ``opentelemetry_resource_detector`` entry point group. - - The detected_attrs dict is updated in-place; later detectors overwrite - earlier ones for the same key. - """ - for name in dataclasses.fields(detector_config): - value = getattr(detector_config, name.name, None) - if value is None: - continue - if name.name in _RESOURCE_DETECTOR_REGISTRY: - detected_attrs.update(_RESOURCE_DETECTOR_REGISTRY[name.name](value)) - else: - cls = load_entry_point("opentelemetry_resource_detector", name.name) - detected_attrs.update(cls(**(value or {})).detect().attributes) - - for name, plugin_config in detector_config.additional_properties.items(): - cls = load_entry_point("opentelemetry_resource_detector", name) - detected_attrs.update(cls(**(plugin_config or {})).detect().attributes) - - -def _filter_attributes(attrs: dict[str, object], filter_config: IncludeExclude | None) -> dict[str, object]: - """Filter detected attribute keys using include/exclude glob patterns. - - Mirrors other SDK IncludeExcludePredicate.createPatternMatching behaviour: - - No filter config (attributes absent) → include all detected attributes. - - included patterns are checked first; excluded patterns are applied after. - - An empty included list is treated as "include everything". - """ - if filter_config is None: - return attrs - - included = filter_config.included - excluded = filter_config.excluded - - if not included and not excluded: - return attrs - - result: dict[str, object] = {} - for key, value in attrs.items(): - if included and not any(fnmatch.fnmatch(key, pat) for pat in included): - continue - if excluded and any(fnmatch.fnmatch(key, pat) for pat in excluded): - continue - result[key] = value - return result diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py deleted file mode 100644 index 99785b0426f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_sdk.py +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -"""Top-level orchestrator for declarative SDK configuration. - -Takes a parsed ``OpenTelemetryConfiguration`` and applies it by calling -each per-signal ``configure_*`` factory in order. This is the single -entry point for "apply this config" on the declarative path. -""" - -from __future__ import annotations - -from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING, getLogger - -from opentelemetry.agent._vendor.opentelemetry.configuration._logger_provider import ( - configure_logger_provider, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._meter_provider import ( - configure_meter_provider, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._propagator import configure_propagator -from opentelemetry.agent._vendor.opentelemetry.configuration._resource import create_resource -from opentelemetry.agent._vendor.opentelemetry.configuration._tracer_provider import ( - configure_tracer_provider, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.instrumentation import ( - configure_instrumentation, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - OpenTelemetryConfiguration, - SeverityNumber, -) - -_logger = getLogger(__name__) - -# Maps OTel SeverityNumber groups to Python logging levels. -# The numbered variants (debug2, info3, …) are sub-levels within the same -# Python tier, so they collapse to the same level constant. -_SEVERITY_TO_LOGGING_LEVEL: dict[SeverityNumber, int] = { - SeverityNumber.trace: DEBUG, - SeverityNumber.trace2: DEBUG, - SeverityNumber.trace3: DEBUG, - SeverityNumber.trace4: DEBUG, - SeverityNumber.debug: DEBUG, - SeverityNumber.debug2: DEBUG, - SeverityNumber.debug3: DEBUG, - SeverityNumber.debug4: DEBUG, - SeverityNumber.info: INFO, - SeverityNumber.info2: INFO, - SeverityNumber.info3: INFO, - SeverityNumber.info4: INFO, - SeverityNumber.warn: WARNING, - SeverityNumber.warn2: WARNING, - SeverityNumber.warn3: WARNING, - SeverityNumber.warn4: WARNING, - SeverityNumber.error: ERROR, - SeverityNumber.error2: ERROR, - SeverityNumber.error3: ERROR, - SeverityNumber.error4: ERROR, - SeverityNumber.fatal: CRITICAL, - SeverityNumber.fatal2: CRITICAL, - SeverityNumber.fatal3: CRITICAL, - SeverityNumber.fatal4: CRITICAL, -} - - -def configure_sdk(config: OpenTelemetryConfiguration) -> None: - """Configure the global SDK from a parsed declarative configuration. - - Builds a :class:`Resource` from ``config.resource`` and applies it to - each signal provider. Sets the global tracer provider, meter provider, - logger provider, and text map propagator from their respective config - sections. Sections absent from the config (``None``) leave the - corresponding global untouched — matching the spec's "noop default" - behavior. - - Honors the top-level ``disabled`` flag: when true, the function returns - early without setting any globals. The ``log_level`` field, when present - and not disabled, is applied to the internal ``opentelemetry`` logger to - control the verbosity of SDK self-diagnostics. - - Args: - config: Parsed ``OpenTelemetryConfiguration`` (typically from - ``load_config_file``). - - Example: - >>> from opentelemetry.configuration.file import ( - ... load_config_file, - ... configure_sdk, - ... ) - >>> config = load_config_file("otel-config.yaml") - >>> configure_sdk(config) - """ - if config.disabled: - _logger.warning("Declarative configuration has disabled=true; skipping SDK setup.") - return - - if config.log_level is not None: - level = _SEVERITY_TO_LOGGING_LEVEL.get(config.log_level, INFO) - getLogger("opentelemetry.agent._vendor.opentelemetry").setLevel(level) - - global_attribute_limits = config.attribute_limits - resource = create_resource(config.resource) - configure_tracer_provider(config.tracer_provider, resource, global_attribute_limits) - configure_meter_provider(config.meter_provider, resource) - configure_logger_provider(config.logger_provider, resource, global_attribute_limits) - configure_propagator(config.propagator) - configure_instrumentation(config.instrumentation_development) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py deleted file mode 100644 index d0b09349c51..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/_tracer_provider.py +++ /dev/null @@ -1,524 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging - -from opentelemetry.agent._vendor.opentelemetry import trace -from opentelemetry.agent._vendor.opentelemetry.configuration._common import ( - _map_compression, - _parse_headers, - _parse_otlp_file_output_stream, - load_entry_point, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( - ConfigurationError, - MissingDependencyError, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - AttributeLimits, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalComposableRuleBasedSampler as RuleBasedSamplerConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalComposableRuleBasedSamplerRule as RuleBasedSamplerRuleConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalComposableSampler as ComposableSamplerConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalOtlpFileExporter as ExperimentalOtlpFileExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalTracerConfig as TracerConfigConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ExperimentalTracerConfigurator as TracerConfiguratorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - IdGenerator as IdGeneratorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - OtlpGrpcExporter as OtlpGrpcExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - OtlpHttpExporter as OtlpHttpExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - ParentBasedSampler as ParentBasedSamplerConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - Sampler as SamplerConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - SpanExporter as SpanExporterConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - SpanLimits as SpanLimitsConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - SpanProcessor as SpanProcessorConfig, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ( - TracerProvider as TracerProviderConfig, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ( - _DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, - _DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, - _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, - _DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT, - _DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT, - SpanLimits, - TracerProvider, - _RuleBasedTracerConfigurator, - _TracerConfig, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace._sampling_experimental import ( - ComposableSampler, - composable_always_off, - composable_always_on, - composable_parent_threshold, - composable_rule_based, - composable_traceid_ratio_based, - composite_sampler, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace._sampling_experimental._rule_based import ( - AllPredicate, - AlwaysMatchPredicate, - AttributePatternsPredicate, - AttributeValuesPredicate, - ParentPredicate, - PredicateT, - RulesT, - SpanKindPredicate, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import ( - BatchSpanProcessor, - ConsoleSpanExporter, - SimpleSpanProcessor, - SpanExporter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import ( - ALWAYS_OFF, - ALWAYS_ON, - ParentBased, - Sampler, - TraceIdRatioBased, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import _scope_name_matches_glob -from opentelemetry.agent._vendor.opentelemetry.trace import SpanKind as TraceSpanKind - -_logger = logging.getLogger(__name__) - -# Default sampler per the OTel spec: parent_based with always_on root. -_DEFAULT_SAMPLER = ParentBased(root=ALWAYS_ON) - - -def _create_otlp_http_span_exporter( - config: OtlpHttpExporterConfig, -) -> SpanExporter: - """Create an OTLP HTTP span exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( # noqa: PLC0415 # type: ignore[import-untyped] - Compression, - ) - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http.trace_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - OTLPSpanExporter, - ) - except ImportError as exc: - raise MissingDependencyError( - package="opentelemetry-exporter-otlp-proto-http", - feature="otlp_http span exporter", - ) from exc - - compression = _map_compression(config.compression, Compression, allow_deflate=True) - headers = _parse_headers(config.headers, config.headers_list) - timeout = (config.timeout / 1000.0) if config.timeout is not None else None - - return OTLPSpanExporter( # type: ignore[return-value] - endpoint=config.endpoint, - headers=headers, - timeout=timeout, - compression=compression, # type: ignore[arg-type] - ) - - -def _create_otlp_grpc_span_exporter( - config: OtlpGrpcExporterConfig, -) -> SpanExporter: - """Create an OTLP gRPC span exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - import grpc # noqa: PLC0415 # type: ignore[import-untyped] - - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - OTLPSpanExporter, - ) - except ImportError as exc: - raise MissingDependencyError( - package="opentelemetry-exporter-otlp-proto-grpc", - feature="otlp_grpc span exporter", - ) from exc - - compression = _map_compression(config.compression, grpc.Compression) - headers = _parse_headers(config.headers, config.headers_list) - timeout = (config.timeout / 1000.0) if config.timeout is not None else None - - return OTLPSpanExporter( # type: ignore[return-value] - endpoint=config.endpoint, - headers=headers, - timeout=timeout, - compression=compression, # type: ignore[arg-type] - ) - - -def _create_otlp_file_development_span_exporter( - config: ExperimentalOtlpFileExporterConfig, -) -> SpanExporter: - """Create an OTLP file (JSON Lines) span exporter from config.""" - try: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.trace_exporter import ( # noqa: PLC0415 # type: ignore[import-untyped] - FileSpanExporter, - ) - except ImportError as exc: - raise ConfigurationError( - "otlp_file_development span exporter requires 'opentelemetry-exporter-otlp-json-file'. " - "Install it with: pip install opentelemetry-exporter-otlp-json-file" - ) from exc - - path = _parse_otlp_file_output_stream(config.output_stream) - return FileSpanExporter(path) if path is not None else FileSpanExporter() - - -_SPAN_EXPORTER_REGISTRY: dict = { - "otlp_http": _create_otlp_http_span_exporter, - "otlp_grpc": _create_otlp_grpc_span_exporter, - "console": lambda _: ConsoleSpanExporter(), - "otlp_file_development": _create_otlp_file_development_span_exporter, -} - - -def _create_span_exporter(config: SpanExporterConfig) -> SpanExporter: - """Create a span exporter from config. - - Known exporter types are checked via typed fields on the SpanExporter - dataclass. Unknown exporter names captured in additional_properties - by the @_additional_properties decorator are loaded via the - ``opentelemetry_traces_exporter`` entry point group. - """ - for name, factory in _SPAN_EXPORTER_REGISTRY.items(): - value = getattr(config, name, None) - if value is not None: - return factory(value) - if config.additional_properties: - name, plugin_config = next(iter(config.additional_properties.items())) - return load_entry_point("opentelemetry_traces_exporter", name)(**(plugin_config or {})) - raise ConfigurationError( - "No exporter type specified in span exporter config. " - "Supported types: otlp_http, otlp_grpc, console, otlp_file_development." - ) - - -def _create_span_processor( - config: SpanProcessorConfig, -) -> BatchSpanProcessor | SimpleSpanProcessor: - """Create a span processor from config.""" - if config.batch is not None: - exporter = _create_span_exporter(config.batch.exporter) - return BatchSpanProcessor( - exporter, - max_queue_size=config.batch.max_queue_size, - schedule_delay_millis=config.batch.schedule_delay, - max_export_batch_size=config.batch.max_export_batch_size, - export_timeout_millis=config.batch.export_timeout, - ) - if config.simple is not None: - return SimpleSpanProcessor(_create_span_exporter(config.simple.exporter)) - raise ConfigurationError("No processor type specified in span processor config. Supported types: batch, simple.") - - -def _create_experimental_composable_sampler( - config: ComposableSamplerConfig, -) -> ComposableSampler: - """Create an experimental composable sampler from config""" - if config.always_on is not None: - return composable_always_on() - if config.always_off is not None: - return composable_always_off() - if config.parent_threshold is not None: - return composable_parent_threshold(_create_experimental_composable_sampler(config.parent_threshold.root)) - if config.probability is not None: - ratio = config.probability.ratio - return composable_traceid_ratio_based(ratio if ratio is not None else 1.0) - if config.rule_based is not None: - return composable_rule_based(_create_rule_based_sampler_rules(config.rule_based)) - raise ConfigurationError( - f"Unknown or unsupported experimental composable sampler type in config: {config!r}. " - "Supported types: always_on, always_off, parent_threshold, probability, rule_based." - ) - - -def _create_rule_based_sampler_rules( - config: RuleBasedSamplerConfig, -) -> RulesT: - if config.rules is None: - return [] - return [ - ( - _create_rule_based_sampler_rule_predicate(rule), - _create_experimental_composable_sampler(rule.sampler), - ) - for rule in config.rules - ] - - -def _create_rule_based_sampler_rule_predicate( - config: RuleBasedSamplerRuleConfig, -) -> PredicateT: - predicates: list[PredicateT] = [] - if config.attribute_values is not None: - predicates.append( - AttributeValuesPredicate( - config.attribute_values.key, - config.attribute_values.values, - ) - ) - if config.attribute_patterns is not None: - predicates.append( - AttributePatternsPredicate( - config.attribute_patterns.key, - config.attribute_patterns.included, - config.attribute_patterns.excluded, - ) - ) - if config.span_kinds is not None: - predicates.append( - SpanKindPredicate([TraceSpanKind[span_kind.value.upper()] for span_kind in config.span_kinds]) - ) - if config.parent is not None: - predicates.append(ParentPredicate([parent.value for parent in config.parent])) - if not predicates: - return AlwaysMatchPredicate() - if len(predicates) == 1: - return predicates[0] - return AllPredicate(predicates) - - -def _create_sampler(config: SamplerConfig) -> Sampler: - """Create a sampler from config. - - Built-in sampler types are checked via typed fields on the Sampler - dataclass. User-defined sampler names captured in additional_properties - by the @_additional_properties decorator are loaded via the - ``opentelemetry_sampler`` entry point group. - """ - if config.always_on is not None: - return ALWAYS_ON - if config.always_off is not None: - return ALWAYS_OFF - if config.trace_id_ratio_based is not None: - ratio = config.trace_id_ratio_based.ratio - return TraceIdRatioBased(ratio if ratio is not None else 1.0) - if config.composite_development is not None: - return composite_sampler(_create_experimental_composable_sampler(config.composite_development)) - if config.parent_based is not None: - return _create_parent_based_sampler(config.parent_based) - if config.additional_properties: - name = next(iter(config.additional_properties)) - return load_entry_point("opentelemetry_sampler", name)() - raise ConfigurationError( - f"Unsupported sampler type in config: {config!r}. " - "Supported types: always_on, always_off, composite_development, " - "trace_id_ratio_based, parent_based." - ) - - -def _create_id_generator(config: IdGeneratorConfig) -> IdGenerator: - """Create an IdGenerator from config. - - Built-in ``random`` resolves to ``RandomIdGenerator``; unknown names - load from the ``opentelemetry_id_generator`` entry point group (the - same group ``OTEL_PYTHON_ID_GENERATOR`` uses today). - """ - if config.random is not None: - return RandomIdGenerator() - if config.additional_properties: - name, plugin_config = next(iter(config.additional_properties.items())) - return load_entry_point("opentelemetry_id_generator", name)(**(plugin_config or {})) - raise ConfigurationError("No id_generator type specified in config. Supported built-in types: random.") - - -def _create_parent_based_sampler(config: ParentBasedSamplerConfig) -> Sampler: - """Create a ParentBased sampler from config, applying SDK defaults for absent delegates.""" - root = _create_sampler(config.root) if config.root is not None else ALWAYS_ON - kwargs: dict = {"root": root} - if config.remote_parent_sampled is not None: - kwargs["remote_parent_sampled"] = _create_sampler(config.remote_parent_sampled) - if config.remote_parent_not_sampled is not None: - kwargs["remote_parent_not_sampled"] = _create_sampler(config.remote_parent_not_sampled) - if config.local_parent_sampled is not None: - kwargs["local_parent_sampled"] = _create_sampler(config.local_parent_sampled) - if config.local_parent_not_sampled is not None: - kwargs["local_parent_not_sampled"] = _create_sampler(config.local_parent_not_sampled) - return ParentBased(**kwargs) - - -def _create_span_limits( - config: SpanLimitsConfig, - global_limits: AttributeLimits | None = None, -) -> SpanLimits: - """Create SpanLimits from config. - - Absent fields fall back to global_limits (if provided), then to OTel spec - defaults (128 for counts, unlimited for lengths). - Explicit values suppress env-var reading — matching Java SDK behavior. - """ - attribute_count_limit = config.attribute_count_limit - if attribute_count_limit is None and global_limits is not None: - attribute_count_limit = global_limits.attribute_count_limit - - attribute_value_length_limit = config.attribute_value_length_limit - if attribute_value_length_limit is None and global_limits is not None: - attribute_value_length_limit = global_limits.attribute_value_length_limit - - return SpanLimits( - max_span_attributes=( - attribute_count_limit if attribute_count_limit is not None else _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT - ), - max_events=( - config.event_count_limit if config.event_count_limit is not None else _DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT - ), - max_links=( - config.link_count_limit if config.link_count_limit is not None else _DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT - ), - max_event_attributes=( - config.event_attribute_count_limit - if config.event_attribute_count_limit is not None - else _DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT - ), - max_link_attributes=( - config.link_attribute_count_limit - if config.link_attribute_count_limit is not None - else _DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT - ), - max_attribute_length=( - attribute_value_length_limit if attribute_value_length_limit is not None else SpanLimits.UNSET - ), - max_span_attribute_length=( - attribute_value_length_limit if attribute_value_length_limit is not None else SpanLimits.UNSET - ), - ) - - -def _to_tracer_config(config: TracerConfigConfig | None) -> _TracerConfig: - """Map an experimental per-tracer config to an SDK ``_TracerConfig``. - - Only ``enabled`` is honored — it is the sole field the SDK - ``_TracerConfig`` exposes. An absent ``enabled`` leaves the tracer enabled. - """ - if config is None or config.enabled is None: - return _TracerConfig.default() - return _TracerConfig(is_enabled=config.enabled) - - -def _create_tracer_configurator( - config: TracerConfiguratorConfig, -) -> _RuleBasedTracerConfigurator: - """Build a rule-based tracer configurator from experimental config. - - Each entry in ``tracers`` maps an instrumentation-scope name glob to a - per-tracer config; ``default_config`` applies to scopes matching no glob. - Rules are evaluated in order, so earlier entries take precedence. - """ - rules = [ - ( - _scope_name_matches_glob(matcher.name), - _to_tracer_config(matcher.config), - ) - for matcher in (config.tracers or []) - ] - return _RuleBasedTracerConfigurator( - rules=rules, - default_config=_to_tracer_config(config.default_config), - ) - - -def create_tracer_provider( - config: TracerProviderConfig | None, - resource: Resource | None = None, - global_attribute_limits: AttributeLimits | None = None, -) -> TracerProvider: - """Create an SDK TracerProvider from declarative config. - - Does NOT read OTEL_TRACES_SAMPLER, OTEL_SPAN_*_LIMIT, or any other env vars - for values that are explicitly controlled by the config. Absent config values - use OTel spec defaults (not env vars), matching Java SDK behavior. - - Args: - config: TracerProvider config from the parsed config file, or None. - resource: Resource to attach to the provider. - global_attribute_limits: Top-level attribute_limits from the root config, - used as a fallback when per-signal limits are not specified. - - Returns: - A configured TracerProvider. - """ - sampler = _create_sampler(config.sampler) if config is not None and config.sampler is not None else _DEFAULT_SAMPLER - id_generator = ( - _create_id_generator(config.id_generator) if config is not None and config.id_generator is not None else None - ) - if config is not None and config.limits is not None: - limits = config.limits - - else: - limits = SpanLimitsConfig() - - span_limits = _create_span_limits(limits, global_attribute_limits) - - tracer_configurator = ( - _create_tracer_configurator(config.tracer_configurator_development) - if config is not None and config.tracer_configurator_development is not None - else None - ) - - provider = TracerProvider( - resource=resource, - sampler=sampler, - span_limits=span_limits, - id_generator=id_generator, - _tracer_configurator=tracer_configurator, - ) - - if config is not None: - for proc_config in config.processors: - provider.add_span_processor(_create_span_processor(proc_config)) - - return provider - - -def configure_tracer_provider( - config: TracerProviderConfig | None, - resource: Resource | None = None, - global_attribute_limits: AttributeLimits | None = None, -) -> None: - """Configure the global TracerProvider from declarative config. - - When config is None (tracer_provider section absent from config file), - the global is not set — matching Java/JS SDK behavior and the spec's - "a noop tracer provider is used" default. - - Args: - config: TracerProvider config from the parsed config file, or None. - resource: Resource to attach to the provider. - global_attribute_limits: Top-level attribute_limits from the root config, - used as a fallback when per-signal limits are not specified. - """ - if config is None: - return - trace.set_tracer_provider(create_tracer_provider(config, resource, global_attribute_limits)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py deleted file mode 100644 index 17af64baee5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/__init__.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -"""OpenTelemetry SDK File Configuration. - -This module provides support for configuring the OpenTelemetry SDK -using declarative configuration files (YAML or JSON). - -Example: - >>> from opentelemetry.configuration.file import load_config_file - >>> config = load_config_file("otel-config.yaml") - >>> print(config.file_format) - '1.0' -""" - -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( - ConfigurationError, - MissingDependencyError, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._logger_provider import ( - configure_logger_provider, - create_logger_provider, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._meter_provider import ( - configure_meter_provider, - create_meter_provider, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._propagator import ( - configure_propagator, - create_propagator, -) -from opentelemetry.agent._vendor.opentelemetry.configuration._resource import create_resource -from opentelemetry.agent._vendor.opentelemetry.configuration._sdk import configure_sdk -from opentelemetry.agent._vendor.opentelemetry.configuration._tracer_provider import ( - configure_tracer_provider, - create_tracer_provider, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.file._env_substitution import ( - substitute_env_vars, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.file._loader import load_config_file - -__all__ = [ - "ConfigurationError", - "MissingDependencyError", - "configure_logger_provider", - "configure_meter_provider", - "configure_propagator", - "configure_sdk", - "configure_tracer_provider", - "create_logger_provider", - "create_meter_provider", - "create_propagator", - "create_resource", - "create_tracer_provider", - "load_config_file", - "substitute_env_vars", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py deleted file mode 100644 index 82327ce2db7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_env_substitution.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -"""Environment variable substitution for configuration files.""" - -import os -import re - - -def substitute_env_vars(text: str) -> str: - """Substitute environment variables within a configuration value. - - A configuration value is a single value from the parsed configuration file - (the value of one key or one list item), never a key, a comment, or a whole - mapping/list. Substitution is applied per configuration value after the - file has been parsed, so comments and mapping keys are never touched. - - For example, given the YAML:: - - service_name: ${SERVICE_NAME} - endpoint: http://${HOST}:${PORT} - - the configuration values are ``${SERVICE_NAME}`` and - ``http://${HOST}:${PORT}``; this function is called once with each, and - never with the keys ``service_name`` or ``endpoint``. - - Supports the following syntax: - - - ${VAR}: Substitute with environment variable VAR, or an empty value if - VAR is not set. - - ${VAR:-default}: Substitute with VAR if set, otherwise use default value. - - $$: Escape sequence for literal $. - - Per the declarative configuration specification, a referenced environment - variable that is not set and has no default is replaced with an empty - value (which the YAML parser then interprets as null). This matches the - behavior of the Java and Node.js implementations and lets configuration - files be shared across languages. - - Args: - text: A configuration value with potential ${VAR} placeholders. - - Returns: - The configuration value with environment variables substituted. - - Examples: - >>> os.environ["SERVICE_NAME"] = "my-service" - >>> substitute_env_vars("${SERVICE_NAME}") - 'my-service' - >>> substitute_env_vars("${MISSING:-default}") - 'default' - >>> substitute_env_vars("$$100") - '$100' - """ - # Pattern matches $$ (escape sequence) or ${VAR_NAME} / ${VAR_NAME:-default_value} - # Handling both in a single pass ensures $$ followed by ${VAR} works correctly - pattern = r"\$\$|\$\{([A-Za-z_][A-Za-z0-9_]*)(:-([^}]*))?\}" - - def replace_var(match) -> str: - if match.group(1) is None: - # Matched $$, return literal $ - return "$" - - var_name = match.group(1) - has_default = match.group(2) is not None - default_value = match.group(3) if has_default else None - - value = os.environ.get(var_name) - - if value is None: - # An unset variable is replaced with its default if one is - # provided, otherwise with an empty value, per the spec. - return default_value or "" - - # Substitution runs on an already-parsed configuration value, so the - # result cannot inject new YAML structure regardless of its contents - # (a newline in the value stays a literal character within this one - # value). Type interpretation for standalone references is handled by - # the loader, which re-resolves the node tag after substitution. - return value - - return re.sub(pattern, replace_var, text) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py deleted file mode 100644 index 44029a96def..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/file/_loader.py +++ /dev/null @@ -1,376 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -"""Configuration file loading and parsing.""" - -import json -import logging -import os -import re -from pathlib import Path -from typing import Any - -from opentelemetry.agent._vendor.opentelemetry.configuration._conversion import _dict_to_dataclass -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ( - ConfigurationError, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.file._env_substitution import ( - substitute_env_vars, -) -from opentelemetry.agent._vendor.opentelemetry.configuration.models import OpenTelemetryConfiguration - -# opentelemetry-agent: pyyaml and jsonschema have no pure-Python wheels (jsonschema needs rpds-py), -# so the vendored ruamel.yaml (its pure-Python, PyYAML-style loader API) and fastjsonschema stand in. -from opentelemetry.agent._vendor import fastjsonschema -from opentelemetry.agent._vendor.ruamel.yaml import nodes as _yaml_nodes -from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError -from opentelemetry.agent._vendor.ruamel.yaml.loader import SafeLoader as _RuamelSafeLoader - - -class SafeLoader(_RuamelSafeLoader): - # Only ruamel.yaml's YAML class sets the composer's nesting limit; 0 means none, like PyYAML. - max_depth = 0 - -# Schema version vendored in schema.json. ``file_format`` values are accepted -# per the configuration spec's versioning rules: the major version must match, -# and a minor version newer than the one this SDK targets is accepted with a -# warning. See -# https://github.com/open-telemetry/opentelemetry-configuration/blob/main/VERSIONING.md -_SUPPORTED_SCHEMA_MAJOR = 1 -_SUPPORTED_SCHEMA_MINOR = 1 - -_schema_cache: list[dict] = [] -_validator_cache: list[Any] = [] - - -def _get_schema() -> dict: - if not _schema_cache: - # opentelemetry-agent: resolve the schema relative to this (vendored) package, not by name. - schema_path = Path(__file__).resolve().parent.parent / "schema.json" - _schema_cache.append(json.loads(schema_path.read_text(encoding="utf-8"))) - return _schema_cache[0] - - -def _get_validator() -> Any: - # Compiling the schema generates and executes Python code; do it once. - if not _validator_cache: - _validator_cache.append(fastjsonschema.compile(_get_schema())) - return _validator_cache[0] - - -_logger = logging.getLogger(__name__) - -_YAML_STR_TAG = "tag:yaml.org,2002:str" - -# A configuration value whose entire content is a single ``${VAR}`` / -# ``${VAR:-default}`` reference. Only such standalone references (when -# unquoted) have their type re-interpreted after substitution; embedded or -# multiple references resolve to a string per the configuration spec. A -# leading ``$$`` escape does not match, so ``$${VAR}`` is treated as an -# embedded (string) value. -_STANDALONE_ENV_REF = re.compile(r"\A\$\{[A-Za-z_][A-Za-z0-9_]*(?::-[^}]*)?\}\Z") - - -def _substitute_env_in_yaml_node( - node: _yaml_nodes.Node, - loader: SafeLoader, - visited: set[int] | None = None, -): - """Apply env-var substitution to string configuration values in a node tree. - - Substitution runs after parsing on configuration values only, so comments - and mapping keys are never candidates (per the configuration spec). For an - unquoted standalone ``${VAR}`` reference the node's type tag is re-resolved - from the substituted value so YAML type coercion still applies (e.g. - ``${LIMIT}`` -> int); quoted or embedded references stay strings. - - Args: - node: Root of the node tree to walk. Substitution happens in place. - loader: The loader that composed ``node``; used to re-resolve tags. - visited: Ids of nodes already processed in this traversal. Callers pass - nothing; the walker creates and threads one set through the whole - tree. - """ - # Every anchor/alias pair shares one composed node, so the same node is - # reached once per reference to it. Each node must be substituted exactly - # once for two reasons: - # - # 1. Substituting twice re-reads the output of the first pass. An - # anchored ``$${TOKEN}`` becomes the escaped literal ``${TOKEN}`` on - # the first visit, which the second visit then resolves as a real - # variable -- silently defeating the ``$$`` escape. - # 2. A cyclic alias (``a: &anchor {self: *anchor}``) makes the node tree - # a graph with a loop, so an unguarded walk recurses until it raises - # ``RecursionError``. - # - # Tracking ``id(node)`` is safe here because ``root_node`` keeps every node - # in the tree alive for the whole traversal, so no id can be reused. - if visited is None: - visited = set() - if id(node) in visited: - return - visited.add(id(node)) - # Worked example: a node value that makes all three checks below true. - # - # YAML (with environment LIMIT=100): - # attribute_limits: - # attribute_count_limit: ${LIMIT} - # - # The parser hands this function the value node of attribute_count_limit, - # which has value="${LIMIT}", tag=str, style=None (plain/unquoted). Then: - # - # 1. isinstance(node, ScalarNode) -> True: it is a leaf value. - # 2. node.tag == _YAML_STR_TAG -> True: "${LIMIT}" is not a number or - # bool, so the parser tagged it str. We substitute in place, giving - # node.value = "100". - # 3. node.style is None and _STANDALONE_ENV_REF.match(raw) -> True: - # it was unquoted and the whole value is a single reference. We - # re-resolve the tag: resolve("100") -> int, and construct_document() - # later builds the integer 100 (not the string "100"). - # - # Counter-cases that reach check 3 but stop there: "${LIMIT}" quoted fails - # the style test; x${LIMIT} fails the regex. Both keep the str tag. - if isinstance(node, _yaml_nodes.ScalarNode): - # A ``ScalarNode`` is a leaf -- one configuration value. Only a - # ``str``-tagged one can hold a ``${VAR}`` reference (nodes the parser - # already typed as int, float, bool or null cannot), so those are the - # only substitution candidates. - if node.tag == _YAML_STR_TAG: - # ``node.value`` is the raw text of this one value (never a key or - # comment). Replace any ${VAR} / ${VAR:-default} / $$ in it. - raw = node.value - node.value = substitute_env_vars(raw) - # The spec says node types are interpreted *after* substitution, - # but only for a value that is exactly one reference and written - # unquoted (``style is None``). Example: ``count: ${N}`` with - # ``N=42`` must yield the int 42, not the string "42". In that case - # re-run YAML's implicit type resolution on the substituted text - # and retag the node. A quoted (``"${N}"``) or embedded - # (``foo-${N}``) value keeps its ``str`` tag and stays a string. - if node.style is None and _STANDALONE_ENV_REF.match(raw): - # ``resolve`` returns the implicit tag (int/float/bool/null/ - # str) YAML would assign to ``node.value``; the ``(True, False)`` - # implicit-flag pair marks it as a plain scalar so that - # type-guessing applies, exactly as during normal parsing. - node.tag = loader.resolve(_yaml_nodes.ScalarNode, node.value, (True, False)) - elif isinstance(node, _yaml_nodes.SequenceNode): - # A sequence (list): each item is itself a value node -- recurse. - for item in node.value: - _substitute_env_in_yaml_node(item, loader, visited) - elif isinstance(node, _yaml_nodes.MappingNode): - # A mapping (dict): recurse into values only; keys are not - # substitution candidates per the spec. A merge key (``<<: *base``) - # appears here as an ordinary pair whose value node is the anchored - # mapping itself, so ``visited`` also covers the merged-in values. - for _key_node, value_node in node.value: - _substitute_env_in_yaml_node(value_node, loader, visited) - - -def _substitute_env_in_json_value(value: Any) -> Any: - """Recursively apply env-var substitution to string values in JSON data. - - JSON has explicit types and no comments, so substitution applies only to - string values (the result stays a string) and mapping keys are left as-is. - """ - if isinstance(value, str): - return substitute_env_vars(value) - if isinstance(value, list): - return [_substitute_env_in_json_value(item) for item in value] - if isinstance(value, dict): - return {key: _substitute_env_in_json_value(val) for key, val in value.items()} - return value - - -def _parse_config_content(content: str, suffix: str, file_path: str | os.PathLike[str]) -> Any: - """Parse configuration text and substitute environment variables. - - Parsing happens first, so ``${VAR}`` references in comments and mapping - keys are never substitution candidates; substitution then runs on - configuration values, with YAML node types re-resolved for standalone - references. - - Raises: - ConfigurationError: If the content cannot be parsed or substitution of - a required environment variable fails. - """ - try: - if suffix == ".json": - return _substitute_env_in_json_value(json.loads(content)) - # YAML 1.2 core schema, as the configuration spec requires (PyYAML implements YAML 1.1). - yaml_loader = SafeLoader(content) - try: - root_node = yaml_loader.get_single_node() - if root_node is None: - return None - _substitute_env_in_yaml_node(root_node, yaml_loader) - return yaml_loader.construct_document(root_node) - finally: - yaml_loader.dispose() - except YAMLError as exc: - _logger.exception("Failed to parse YAML from %s", file_path) - raise ConfigurationError(f"Failed to parse YAML: {exc}") from exc - except json.JSONDecodeError as exc: - _logger.exception("Failed to parse JSON from %s", file_path) - raise ConfigurationError(f"Failed to parse JSON: {exc}") from exc - - -def load_config_file( - file_path: str | os.PathLike[str], -) -> OpenTelemetryConfiguration: - """Load and parse an OpenTelemetry configuration file. - - Supports YAML and JSON formats. Environment variable substitution is - performed after parsing, on configuration values only, so ``${VAR}`` - references in comments or mapping keys are left untouched. - - Args: - file_path: Path to the configuration file (.yaml, .yml, or .json). - - Returns: - Parsed OpenTelemetryConfiguration object. - - Raises: - ConfigurationError: If file cannot be read, parsed, or validated. - - Examples: - >>> config = load_config_file("otel-config.yaml") - >>> print(config.tracer_provider) - """ - path = Path(file_path) - - if not path.exists(): - _logger.error("Configuration file not found: %s", file_path) - raise ConfigurationError(f"Configuration file not found: {file_path}") - - if not path.is_file(): - _logger.error("Configuration path is not a file: %s", file_path) - raise ConfigurationError(f"Configuration path is not a file: {file_path}") - - try: - with open(path, encoding="utf-8") as config_file: - content = config_file.read() - except OSError as exc: - _logger.exception("Failed to read configuration file: %s", file_path) - raise ConfigurationError(f"Failed to read configuration file: {file_path}") from exc - - # Parse the file, then substitute env vars in configuration values only. - # Parsing first means comments and mapping keys are never substitution - # candidates, and node types are still resolved after substitution. - suffix = path.suffix.lower() - if suffix not in (".yaml", ".yml", ".json"): - _logger.error("Unsupported file format: %s", suffix) - raise ConfigurationError(f"Unsupported file format: {suffix}. Use .yaml, .yml, or .json") - - data = _parse_config_content(content, suffix, file_path) - - if data is None: - _logger.error("Configuration file is empty: %s", file_path) - raise ConfigurationError("Configuration file is empty") - - if not isinstance(data, dict): - _logger.error( - "Configuration must be a mapping/object, got %s", - type(data).__name__, - ) - raise ConfigurationError(f"Configuration must be a mapping/object, got {type(data).__name__}") - - _validate_schema(data) - _validate_file_format(data) - - # Convert to OpenTelemetryConfiguration model - try: - config = _dict_to_model(data) - except Exception as exc: - _logger.exception("Failed to validate configuration from %s", file_path) - raise ConfigurationError(f"Failed to validate configuration: {exc}") from exc - - return config - - -def _validate_schema(data: dict) -> None: - """Validate configuration dict against the OTel configuration JSON schema. - - Raises: - ConfigurationError: If the data does not conform to the schema. - """ - try: - _get_validator()(data) - except fastjsonschema.JsonSchemaValueException as exc: - # The path starts with the root's name ("data"). - path = exc.path[1:] - raise ConfigurationError( - f"Configuration does not match schema: {exc.message} (at {' -> '.join(str(p) for p in path)})" - if path - else f"Configuration does not match schema: {exc.message}" - ) from exc - except fastjsonschema.JsonSchemaDefinitionException as exc: - raise ConfigurationError(f"Invalid configuration schema: {exc}") from exc - - -def _validate_file_format(data: dict) -> None: - """Validate the ``file_format`` version per the configuration spec. - - The spec requires implementations to fail on an unsupported major version - (a breaking-change boundary) and to accept, with a warning, a minor version - newer than the one this SDK targets. See - https://github.com/open-telemetry/opentelemetry-configuration/blob/main/VERSIONING.md - - Raises: - ConfigurationError: If ``file_format`` is malformed or its major - version is not supported. - """ - file_format = data.get("file_format") - # file_format is required and typed as a string by the schema, which is - # validated before this runs; guard defensively regardless. - if not isinstance(file_format, str): - raise ConfigurationError(f"Invalid file_format: expected a version string, got {file_format!r}") - - # Drop any pre-release / meta tag, e.g. "1.0-rc.2" -> "1.0". - version = file_format.split("-", 1)[0] - parts = version.split(".") - try: - major = int(parts[0]) - minor = int(parts[1]) if len(parts) > 1 else 0 - except ValueError as exc: - raise ConfigurationError(f"Invalid file_format '{file_format}': expected MAJOR.MINOR version numbers") from exc - - if major != _SUPPORTED_SCHEMA_MAJOR: - raise ConfigurationError( - f"Unsupported file_format '{file_format}': this SDK supports schema version {_SUPPORTED_SCHEMA_MAJOR}.x" - ) - - if minor > _SUPPORTED_SCHEMA_MINOR: - _logger.warning( - "Configuration file_format '%s' has a newer minor version than " - "this SDK supports (%d.%d); some settings may be ignored.", - file_format, - _SUPPORTED_SCHEMA_MAJOR, - _SUPPORTED_SCHEMA_MINOR, - ) - - -def _dict_to_model(data: dict[str, Any]) -> OpenTelemetryConfiguration: - """Convert a parsed config dictionary to the full typed model tree. - - Walks each field's type annotation, recursively converting nested - dicts to their corresponding dataclass types. The resulting - ``OpenTelemetryConfiguration`` is fully typed end-to-end, so factory - functions can rely on typed attribute access (e.g. ``config.sampler``, - ``config.processors[0].batch.exporter``). - - Args: - data: Parsed configuration dictionary. - - Returns: - OpenTelemetryConfiguration instance. - - Raises: - TypeError: If data doesn't match expected structure. - ValueError: If values are invalid. - """ - try: - return _dict_to_dataclass(data, OpenTelemetryConfiguration) - except TypeError as exc: - raise TypeError( - f"Configuration structure is invalid. Check that all required fields are present and correctly typed: {exc}" - ) from exc diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py deleted file mode 100644 index 884ba470ea8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/instrumentation.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from dataclasses import fields, is_dataclass -from inspect import isclass -from logging import getLogger - -from opentelemetry.agent._vendor.opentelemetry.configuration._common import load_entry_point -from opentelemetry.agent._vendor.opentelemetry.configuration._conversion import _dict_to_dataclass -from opentelemetry.agent._vendor.opentelemetry.configuration._exceptions import ConfigurationError -from opentelemetry.agent._vendor.opentelemetry.configuration.models import ExperimentalInstrumentation - -_logger = getLogger(__name__) - - -def configure_instrumentation( - configuration: ExperimentalInstrumentation | None, -) -> None: - """Activate instrumentors listed under ``instrumentation/development.python``. - - For each entry in ``configuration.python`` the matching - ``opentelemetry_instrumentor`` entry point is loaded. If the instrumentor - class exposes a ``configuration`` attribute that is a dataclass type, the - raw options are validated through ``_dict_to_dataclass`` before being - forwarded to ``instrument()``. An ``enabled: false`` value suppresses - instrumentation without raising. - - If an instrumentor is already active (e.g. ``opentelemetry-instrument`` - ran before the SDK was configured from the file) its ``instrument()`` call - is skipped to avoid a double-instrumentation warning. - - Absent or unknown entry points are logged as warnings; runtime errors from - an instrumentor are logged as exceptions. Neither stops the remaining - instrumentors from being applied. - """ - if configuration is None or configuration.python is None: - return - - for name, options in configuration.python.items(): - options = dict(options) - if not options.pop("enabled", True): - _logger.debug( - "Instrumentation '%s' is disabled in declarative config; skipping", - name, - ) - continue - - try: - cls = load_entry_point("opentelemetry_instrumentor", name) - configuration_cls = getattr(cls, "configuration", None) - if isclass(configuration_cls) and is_dataclass(configuration_cls): - configuration_obj = _dict_to_dataclass(options, configuration_cls) - options = { - f.name: value - for f in fields(configuration_obj) - if (value := getattr(configuration_obj, f.name)) is not None - } - instance = cls() - if getattr(instance, "is_instrumented_by_opentelemetry", False): - _logger.debug("Skipping '%s': already instrumented", name) - else: - instance.instrument(**options) - _logger.debug("Instrumented '%s' via declarative config", name) - except ConfigurationError as exc: - _logger.warning( - "Skipping instrumentation '%s' in declarative config: %s", - name, - exc, - ) - except Exception: # pylint: disable=broad-except - _logger.exception("Failed to instrument '%s' via declarative config", name) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py deleted file mode 100644 index fc7cc2ae5a1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/models.py +++ /dev/null @@ -1,803 +0,0 @@ -# generated by datamodel-codegen: -# filename: schema.json -# timestamp: 2026-06-23T15:17:37+00:00 - -from __future__ import annotations - -from dataclasses import dataclass -from enum import Enum -from typing import Any, ClassVar, TypeAlias - -from opentelemetry.agent._vendor.opentelemetry.configuration._common import _additional_properties - -AlwaysOffSampler: TypeAlias = dict[str, Any] | None - - -AlwaysOnSampler: TypeAlias = dict[str, Any] | None - - -@dataclass -class AttributeLimits: - attribute_value_length_limit: int | None = None - attribute_count_limit: int | None = None - - -Value: TypeAlias = list[str] - - -Value1: TypeAlias = list[bool] - - -Value2: TypeAlias = list[float] - - -class AttributeType(Enum): - string = "string" - bool = "bool" - int = "int" - double = "double" - string_array = "string_array" - bool_array = "bool_array" - int_array = "int_array" - double_array = "double_array" - - -B3MultiPropagator: TypeAlias = dict[str, Any] | None - - -B3Propagator: TypeAlias = dict[str, Any] | None - - -BaggagePropagator: TypeAlias = dict[str, Any] | None - - -@dataclass -class Base2ExponentialBucketHistogramAggregation: - max_scale: int | None = None - max_size: int | None = None - record_min_max: bool | None = None - - -@dataclass -class CardinalityLimits: - default: int | None = None - counter: int | None = None - gauge: int | None = None - histogram: int | None = None - observable_counter: int | None = None - observable_gauge: int | None = None - observable_up_down_counter: int | None = None - up_down_counter: int | None = None - - -ConsoleExporter: TypeAlias = dict[str, Any] | None - - -DefaultAggregation: TypeAlias = dict[str, Any] | None - - -Distribution: TypeAlias = dict[str, dict[str, Any]] - - -DropAggregation: TypeAlias = dict[str, Any] | None - - -class ExemplarFilter(Enum): - always_on = "always_on" - always_off = "always_off" - trace_based = "trace_based" - - -ExperimentalComposableAlwaysOffSampler: TypeAlias = dict[str, Any] | None - - -ExperimentalComposableAlwaysOnSampler: TypeAlias = dict[str, Any] | None - - -@dataclass -class ExperimentalComposableProbabilitySampler: - ratio: float | None = None - - -@dataclass -class ExperimentalComposableRuleBasedSamplerRuleAttributePatterns: - key: str - included: list[str] | None = None - excluded: list[str] | None = None - - -@dataclass -class ExperimentalComposableRuleBasedSamplerRuleAttributeValues: - key: str - values: list[str] - - -ExperimentalContainerResourceDetector: TypeAlias = dict[str, Any] | None - - -ExperimentalEventToSpanEventBridgeLogRecordProcessor: TypeAlias = dict[str, Any] | None - - -ExperimentalHostResourceDetector: TypeAlias = dict[str, Any] | None - - -@dataclass -class ExperimentalHttpClientInstrumentation: - request_captured_headers: list[str] | None = None - response_captured_headers: list[str] | None = None - known_methods: list[str] | None = None - - -@dataclass -class ExperimentalHttpServerInstrumentation: - request_captured_headers: list[str] | None = None - response_captured_headers: list[str] | None = None - known_methods: list[str] | None = None - - -ExperimentalLanguageSpecificInstrumentation: TypeAlias = dict[str, dict[str, Any]] - - -@dataclass -class ExperimentalMeterConfig: - enabled: bool | None = None - - -@dataclass -class ExperimentalMeterMatcherAndConfig: - name: str - config: ExperimentalMeterConfig - - -@dataclass -class ExperimentalOtlpFileExporter: - output_stream: str | None = None - - -@dataclass -class ExperimentalProbabilitySampler: - ratio: float | None = None - - -ExperimentalProcessResourceDetector: TypeAlias = dict[str, Any] | None - - -class ExperimentalPrometheusTranslationStrategy(Enum): - underscore_escaping_with_suffixes = "underscore_escaping_with_suffixes" - underscore_escaping_without_suffixes_development = "underscore_escaping_without_suffixes/development" - no_utf8_escaping_with_suffixes_development = "no_utf8_escaping_with_suffixes/development" - no_translation_development = "no_translation/development" - - -@dataclass -class ExperimentalSemconvConfig: - version: int | None = None - experimental: bool | None = None - dual_emit: bool | None = None - - -ExperimentalServiceResourceDetector: TypeAlias = dict[str, Any] | None - - -class ExperimentalSpanParent(Enum): - none = "none" - remote = "remote" - local = "local" - - -@dataclass -class ExperimentalTracerConfig: - enabled: bool | None = None - - -@dataclass -class ExperimentalTracerMatcherAndConfig: - name: str - config: ExperimentalTracerConfig - - -@dataclass -class ExperimentalUrlSanitization: - sensitive_query_parameters: list[str] | None = None - - -@dataclass -class ExplicitBucketHistogramAggregation: - boundaries: list[float] | None = None - record_min_max: bool | None = None - - -class ExporterDefaultHistogramAggregation(Enum): - explicit_bucket_histogram = "explicit_bucket_histogram" - base2_exponential_bucket_histogram = "base2_exponential_bucket_histogram" - - -class ExporterTemporalityPreference(Enum): - cumulative = "cumulative" - delta = "delta" - low_memory = "low_memory" - - -@dataclass -class GrpcTls: - ca_file: str | None = None - key_file: str | None = None - cert_file: str | None = None - insecure: bool | None = None - - -@dataclass -class HttpTls: - ca_file: str | None = None - key_file: str | None = None - cert_file: str | None = None - - -@dataclass -class IncludeExclude: - included: list[str] | None = None - excluded: list[str] | None = None - - -class InstrumentType(Enum): - counter = "counter" - gauge = "gauge" - histogram = "histogram" - observable_counter = "observable_counter" - observable_gauge = "observable_gauge" - observable_up_down_counter = "observable_up_down_counter" - up_down_counter = "up_down_counter" - - -LastValueAggregation: TypeAlias = dict[str, Any] | None - - -@dataclass -class LogRecordLimits: - attribute_value_length_limit: int | None = None - attribute_count_limit: int | None = None - - -@dataclass -class NameStringValuePair: - name: str - value: str | None - - -OpenCensusMetricProducer: TypeAlias = dict[str, Any] | None - - -@dataclass -class OtlpGrpcExporter: - endpoint: str | None = None - tls: GrpcTls | None = None - headers: list[NameStringValuePair] | None = None - headers_list: str | None = None - compression: str | None = None - timeout: int | None = None - - -@dataclass -class OtlpGrpcMetricExporter: - endpoint: str | None = None - tls: GrpcTls | None = None - headers: list[NameStringValuePair] | None = None - headers_list: str | None = None - compression: str | None = None - timeout: int | None = None - temporality_preference: ExporterTemporalityPreference | None = None - default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None - - -class OtlpHttpEncoding(Enum): - protobuf = "protobuf" - json = "json" - - -@dataclass -class OtlpHttpExporter: - endpoint: str | None = None - tls: HttpTls | None = None - headers: list[NameStringValuePair] | None = None - headers_list: str | None = None - compression: str | None = None - timeout: int | None = None - encoding: OtlpHttpEncoding | None = None - - -@dataclass -class OtlpHttpMetricExporter: - endpoint: str | None = None - tls: HttpTls | None = None - headers: list[NameStringValuePair] | None = None - headers_list: str | None = None - compression: str | None = None - timeout: int | None = None - encoding: OtlpHttpEncoding | None = None - temporality_preference: ExporterTemporalityPreference | None = None - default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None - - -RandomIdGenerator: TypeAlias = dict[str, Any] | None - - -class SeverityNumber(Enum): - trace = "trace" - trace2 = "trace2" - trace3 = "trace3" - trace4 = "trace4" - debug = "debug" - debug2 = "debug2" - debug3 = "debug3" - debug4 = "debug4" - info = "info" - info2 = "info2" - info3 = "info3" - info4 = "info4" - warn = "warn" - warn2 = "warn2" - warn3 = "warn3" - warn4 = "warn4" - error = "error" - error2 = "error2" - error3 = "error3" - error4 = "error4" - fatal = "fatal" - fatal2 = "fatal2" - fatal3 = "fatal3" - fatal4 = "fatal4" - - -@_additional_properties -@dataclass -class SpanExporter: - otlp_http: OtlpHttpExporter | None = None - otlp_grpc: OtlpGrpcExporter | None = None - otlp_file_development: ExperimentalOtlpFileExporter | None = None - console: ConsoleExporter | None = None - additional_properties: ClassVar[dict[str, Any]] - - -class SpanKind(Enum): - internal = "internal" - server = "server" - client = "client" - producer = "producer" - consumer = "consumer" - - -@dataclass -class SpanLimits: - attribute_value_length_limit: int | None = None - attribute_count_limit: int | None = None - event_count_limit: int | None = None - link_count_limit: int | None = None - event_attribute_count_limit: int | None = None - link_attribute_count_limit: int | None = None - - -SumAggregation: TypeAlias = dict[str, Any] | None - - -TraceContextPropagator: TypeAlias = dict[str, Any] | None - - -@dataclass -class TraceIdRatioBasedSampler: - ratio: float | None = None - - -@dataclass -class ViewSelector: - instrument_name: str | None = None - instrument_type: InstrumentType | None = None - unit: str | None = None - meter_name: str | None = None - meter_version: str | None = None - meter_schema_url: str | None = None - - -@dataclass -class Aggregation: - default: DefaultAggregation | None = None - drop: DropAggregation | None = None - explicit_bucket_histogram: ExplicitBucketHistogramAggregation | None = None - base2_exponential_bucket_histogram: Base2ExponentialBucketHistogramAggregation | None = None - last_value: LastValueAggregation | None = None - sum: SumAggregation | None = None - - -@dataclass -class AttributeNameValue: - name: str - value: str | float | bool | Value | Value1 | Value2 | None - type: AttributeType | None = None - - -@dataclass -class BatchSpanProcessor: - exporter: SpanExporter - schedule_delay: int | None = None - export_timeout: int | None = None - max_queue_size: int | None = None - max_export_batch_size: int | None = None - - -@dataclass -class ConsoleMetricExporter: - temporality_preference: ExporterTemporalityPreference | None = None - default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None - - -@dataclass -class ExperimentalCodeInstrumentation: - semconv: ExperimentalSemconvConfig | None = None - - -@dataclass -class ExperimentalDbInstrumentation: - semconv: ExperimentalSemconvConfig | None = None - - -@dataclass -class ExperimentalGenAiInstrumentation: - semconv: ExperimentalSemconvConfig | None = None - - -@dataclass -class ExperimentalHttpInstrumentation: - semconv: ExperimentalSemconvConfig | None = None - client: ExperimentalHttpClientInstrumentation | None = None - server: ExperimentalHttpServerInstrumentation | None = None - - -@dataclass -class ExperimentalLoggerConfig: - enabled: bool | None = None - minimum_severity: SeverityNumber | None = None - trace_based: bool | None = None - - -@dataclass -class ExperimentalLoggerMatcherAndConfig: - name: str - config: ExperimentalLoggerConfig - - -@dataclass -class ExperimentalMessagingInstrumentation: - semconv: ExperimentalSemconvConfig | None = None - - -@dataclass -class ExperimentalMeterConfigurator: - default_config: ExperimentalMeterConfig | None = None - meters: list[ExperimentalMeterMatcherAndConfig] | None = None - - -@dataclass -class ExperimentalOtlpFileMetricExporter: - output_stream: str | None = None - temporality_preference: ExporterTemporalityPreference | None = None - default_histogram_aggregation: ExporterDefaultHistogramAggregation | None = None - - -@dataclass -class ExperimentalPrometheusMetricExporter: - host: str | None = None - port: int | None = None - scope_info_enabled: bool | None = None - target_info_enabled_development: bool | None = None - resource_constant_labels: IncludeExclude | None = None - translation_strategy: ExperimentalPrometheusTranslationStrategy | None = None - - -@_additional_properties -@dataclass -class ExperimentalResourceDetector: - container: ExperimentalContainerResourceDetector | None = None - host: ExperimentalHostResourceDetector | None = None - process: ExperimentalProcessResourceDetector | None = None - service: ExperimentalServiceResourceDetector | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class ExperimentalRpcInstrumentation: - semconv: ExperimentalSemconvConfig | None = None - - -@dataclass -class ExperimentalSanitization: - url: ExperimentalUrlSanitization | None = None - - -@dataclass -class ExperimentalTracerConfigurator: - default_config: ExperimentalTracerConfig | None = None - tracers: list[ExperimentalTracerMatcherAndConfig] | None = None - - -@_additional_properties -@dataclass -class IdGenerator: - random: RandomIdGenerator | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@_additional_properties -@dataclass -class LogRecordExporter: - otlp_http: OtlpHttpExporter | None = None - otlp_grpc: OtlpGrpcExporter | None = None - otlp_file_development: ExperimentalOtlpFileExporter | None = None - console: ConsoleExporter | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@_additional_properties -@dataclass -class MetricProducer: - opencensus: OpenCensusMetricProducer | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@_additional_properties -@dataclass -class PullMetricExporter: - prometheus_development: ExperimentalPrometheusMetricExporter | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class PullMetricReader: - exporter: PullMetricExporter - producers: list[MetricProducer] | None = None - cardinality_limits: CardinalityLimits | None = None - - -@_additional_properties -@dataclass -class PushMetricExporter: - otlp_http: OtlpHttpMetricExporter | None = None - otlp_grpc: OtlpGrpcMetricExporter | None = None - otlp_file_development: ExperimentalOtlpFileMetricExporter | None = None - console: ConsoleMetricExporter | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class SimpleLogRecordProcessor: - exporter: LogRecordExporter - - -@dataclass -class SimpleSpanProcessor: - exporter: SpanExporter - - -@_additional_properties -@dataclass -class SpanProcessor: - batch: BatchSpanProcessor | None = None - simple: SimpleSpanProcessor | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@_additional_properties -@dataclass -class TextMapPropagator: - tracecontext: TraceContextPropagator | None = None - baggage: BaggagePropagator | None = None - b3: B3Propagator | None = None - b3multi: B3MultiPropagator | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class ViewStream: - name: str | None = None - description: str | None = None - aggregation: Aggregation | None = None - aggregation_cardinality_limit: int | None = None - attribute_keys: IncludeExclude | None = None - - -@dataclass -class BatchLogRecordProcessor: - exporter: LogRecordExporter - schedule_delay: int | None = None - export_timeout: int | None = None - max_queue_size: int | None = None - max_export_batch_size: int | None = None - - -@dataclass -class ExperimentalGeneralInstrumentation: - http: ExperimentalHttpInstrumentation | None = None - code: ExperimentalCodeInstrumentation | None = None - db: ExperimentalDbInstrumentation | None = None - gen_ai: ExperimentalGenAiInstrumentation | None = None - messaging: ExperimentalMessagingInstrumentation | None = None - rpc: ExperimentalRpcInstrumentation | None = None - sanitization: ExperimentalSanitization | None = None - stability_opt_in_list: str | None = None - - -@dataclass -class ExperimentalInstrumentation: - general: ExperimentalGeneralInstrumentation | None = None - cpp: ExperimentalLanguageSpecificInstrumentation | None = None - dotnet: ExperimentalLanguageSpecificInstrumentation | None = None - erlang: ExperimentalLanguageSpecificInstrumentation | None = None - go: ExperimentalLanguageSpecificInstrumentation | None = None - java: ExperimentalLanguageSpecificInstrumentation | None = None - js: ExperimentalLanguageSpecificInstrumentation | None = None - php: ExperimentalLanguageSpecificInstrumentation | None = None - python: ExperimentalLanguageSpecificInstrumentation | None = None - ruby: ExperimentalLanguageSpecificInstrumentation | None = None - rust: ExperimentalLanguageSpecificInstrumentation | None = None - swift: ExperimentalLanguageSpecificInstrumentation | None = None - - -@dataclass -class ExperimentalLoggerConfigurator: - default_config: ExperimentalLoggerConfig | None = None - loggers: list[ExperimentalLoggerMatcherAndConfig] | None = None - - -@dataclass -class ExperimentalResourceDetection: - attributes: IncludeExclude | None = None - detectors: list[ExperimentalResourceDetector] | None = None - - -@_additional_properties -@dataclass -class LogRecordProcessor: - batch: BatchLogRecordProcessor | None = None - simple: SimpleLogRecordProcessor | None = None - event_to_span_event_bridge_development: ExperimentalEventToSpanEventBridgeLogRecordProcessor | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class PeriodicMetricReader: - exporter: PushMetricExporter - interval: int | None = None - timeout: int | None = None - max_export_batch_size_development: int | None = None - producers: list[MetricProducer] | None = None - cardinality_limits: CardinalityLimits | None = None - - -@dataclass -class Propagator: - composite: list[TextMapPropagator] | None = None - composite_list: str | None = None - - -@dataclass -class Resource: - attributes: list[AttributeNameValue] | None = None - detection_development: ExperimentalResourceDetection | None = None - schema_url: str | None = None - attributes_list: str | None = None - - -@dataclass -class View: - selector: ViewSelector - stream: ViewStream - - -@dataclass -class LoggerProvider: - processors: list[LogRecordProcessor] - limits: LogRecordLimits | None = None - logger_configurator_development: ExperimentalLoggerConfigurator | None = None - - -@dataclass -class MetricReader: - periodic: PeriodicMetricReader | None = None - pull: PullMetricReader | None = None - - -@dataclass -class MeterProvider: - readers: list[MetricReader] - views: list[View] | None = None - exemplar_filter: ExemplarFilter | None = None - meter_configurator_development: ExperimentalMeterConfigurator | None = None - - -@_additional_properties -@dataclass -class OpenTelemetryConfiguration: - file_format: str - disabled: bool | None = None - log_level: SeverityNumber | None = None - attribute_limits: AttributeLimits | None = None - logger_provider: LoggerProvider | None = None - meter_provider: MeterProvider | None = None - propagator: Propagator | None = None - tracer_provider: TracerProvider | None = None - resource: Resource | None = None - instrumentation_development: ExperimentalInstrumentation | None = None - distribution: Distribution | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class ExperimentalComposableParentThresholdSampler: - root: ExperimentalComposableSampler - - -@dataclass -class ExperimentalComposableRuleBasedSampler: - rules: list[ExperimentalComposableRuleBasedSamplerRule] | None = None - - -@dataclass -class ExperimentalComposableRuleBasedSamplerRule: - """ - A rule for ExperimentalComposableRuleBasedSampler. A rule can have multiple match conditions - the sampler will be applied if all match. - If no conditions are specified, the rule matches all spans that reach it. - - """ - - sampler: ExperimentalComposableSampler - attribute_values: ExperimentalComposableRuleBasedSamplerRuleAttributeValues | None = None - attribute_patterns: ExperimentalComposableRuleBasedSamplerRuleAttributePatterns | None = None - span_kinds: list[SpanKind] | None = None - parent: list[ExperimentalSpanParent] | None = None - - -@_additional_properties -@dataclass -class ExperimentalComposableSampler: - always_off: ExperimentalComposableAlwaysOffSampler | None = None - always_on: ExperimentalComposableAlwaysOnSampler | None = None - parent_threshold: ExperimentalComposableParentThresholdSampler | None = None - probability: ExperimentalComposableProbabilitySampler | None = None - rule_based: ExperimentalComposableRuleBasedSampler | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class ExperimentalJaegerRemoteSampler: - endpoint: str - initial_sampler: Sampler - interval: int | None = None - - -@dataclass -class ParentBasedSampler: - root: Sampler | None = None - remote_parent_sampled: Sampler | None = None - remote_parent_not_sampled: Sampler | None = None - local_parent_sampled: Sampler | None = None - local_parent_not_sampled: Sampler | None = None - - -@_additional_properties -@dataclass -class Sampler: - always_off: AlwaysOffSampler | None = None - always_on: AlwaysOnSampler | None = None - composite_development: ExperimentalComposableSampler | None = None - jaeger_remote_development: ExperimentalJaegerRemoteSampler | None = None - parent_based: ParentBasedSampler | None = None - probability_development: ExperimentalProbabilitySampler | None = None - trace_id_ratio_based: TraceIdRatioBasedSampler | None = None - additional_properties: ClassVar[dict[str, Any]] - - -@dataclass -class TracerProvider: - processors: list[SpanProcessor] - limits: SpanLimits | None = None - sampler: Sampler | None = None - id_generator: IdGenerator | None = None - tracer_configurator_development: ExperimentalTracerConfigurator | None = None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json deleted file mode 100644 index 1a30982ecb6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/schema.json +++ /dev/null @@ -1,2576 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "title": "OpenTelemetryConfiguration", - "type": "object", - "additionalProperties": true, - "properties": { - "file_format": { - "type": "string", - "description": "The file format version.\nRepresented as a string including the semver major, minor version numbers (and optionally the meta tag). For example: \"0.4\", \"1.0-rc.2\", \"1.0\" (after stable release).\nSee https://github.com/open-telemetry/opentelemetry-configuration/blob/main/VERSIONING.md for more details.\nThe yaml format is documented at https://github.com/open-telemetry/opentelemetry-configuration/tree/main/schema\nProperty is required and must be non-null.\n" - }, - "disabled": { - "type": [ - "boolean", - "null" - ], - "description": "Configure if the SDK is disabled or not.\nIf omitted or null, false is used.\n" - }, - "log_level": { - "$ref": "#/$defs/SeverityNumber", - "description": "Configure the log level of the internal logger used by the SDK.\nValues include:\n* debug: debug, severity number 5.\n* debug2: debug2, severity number 6.\n* debug3: debug3, severity number 7.\n* debug4: debug4, severity number 8.\n* error: error, severity number 17.\n* error2: error2, severity number 18.\n* error3: error3, severity number 19.\n* error4: error4, severity number 20.\n* fatal: fatal, severity number 21.\n* fatal2: fatal2, severity number 22.\n* fatal3: fatal3, severity number 23.\n* fatal4: fatal4, severity number 24.\n* info: info, severity number 9.\n* info2: info2, severity number 10.\n* info3: info3, severity number 11.\n* info4: info4, severity number 12.\n* trace: trace, severity number 1.\n* trace2: trace2, severity number 2.\n* trace3: trace3, severity number 3.\n* trace4: trace4, severity number 4.\n* warn: warn, severity number 13.\n* warn2: warn2, severity number 14.\n* warn3: warn3, severity number 15.\n* warn4: warn4, severity number 16.\nIf omitted, INFO is used.\n" - }, - "attribute_limits": { - "$ref": "#/$defs/AttributeLimits", - "description": "Configure general attribute limits. See also tracer_provider.limits, logger_provider.limits.\nIf omitted, default values as described in AttributeLimits are used.\n" - }, - "logger_provider": { - "$ref": "#/$defs/LoggerProvider", - "description": "Configure logger provider.\nIf omitted, a noop logger provider is used.\n" - }, - "meter_provider": { - "$ref": "#/$defs/MeterProvider", - "description": "Configure meter provider.\nIf omitted, a noop meter provider is used.\n" - }, - "propagator": { - "$ref": "#/$defs/Propagator", - "description": "Configure text map context propagators.\nIf omitted, a noop propagator is used.\n" - }, - "tracer_provider": { - "$ref": "#/$defs/TracerProvider", - "description": "Configure tracer provider.\nIf omitted, a noop tracer provider is used.\n" - }, - "resource": { - "$ref": "#/$defs/Resource", - "description": "Configure resource for all signals.\nIf omitted, the default resource is used.\n" - }, - "instrumentation/development": { - "$ref": "#/$defs/ExperimentalInstrumentation", - "description": "Configure instrumentation.\nIf omitted, instrumentation defaults are used.\n" - }, - "distribution": { - "$ref": "#/$defs/Distribution", - "description": "Defines configuration parameters specific to a particular OpenTelemetry distribution or vendor.\nThis section provides a standardized location for distribution-specific settings\nthat are not part of the OpenTelemetry configuration model.\nIt allows vendors to expose their own extensions and general configuration options.\nIf omitted, distribution defaults are used.\n" - } - }, - "required": [ - "file_format" - ], - "$defs": { - "Aggregation": { - "type": "object", - "additionalProperties": false, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "default": { - "$ref": "#/$defs/DefaultAggregation", - "description": "Configures the stream to use the instrument kind to select an aggregation and advisory parameters to influence aggregation configuration parameters. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#default-aggregation for details.\nIf omitted, ignore.\n" - }, - "drop": { - "$ref": "#/$defs/DropAggregation", - "description": "Configures the stream to ignore/drop all instrument measurements. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#drop-aggregation for details.\nIf omitted, ignore.\n" - }, - "explicit_bucket_histogram": { - "$ref": "#/$defs/ExplicitBucketHistogramAggregation", - "description": "Configures the stream to collect data for the histogram metric point using a set of explicit boundary values for histogram bucketing. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation for details\nIf omitted, ignore.\n" - }, - "base2_exponential_bucket_histogram": { - "$ref": "#/$defs/Base2ExponentialBucketHistogramAggregation", - "description": "Configures the stream to collect data for the exponential histogram metric point, which uses a base-2 exponential formula to determine bucket boundaries and an integer scale parameter to control resolution. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation for details.\nIf omitted, ignore.\n" - }, - "last_value": { - "$ref": "#/$defs/LastValueAggregation", - "description": "Configures the stream to collect data using the last measurement. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#last-value-aggregation for details.\nIf omitted, ignore.\n" - }, - "sum": { - "$ref": "#/$defs/SumAggregation", - "description": "Configures the stream to collect the arithmetic sum of measurement values. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#sum-aggregation for details.\nIf omitted, ignore.\n" - } - } - }, - "AlwaysOffSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "AlwaysOnSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "AttributeLimits": { - "type": "object", - "additionalProperties": false, - "properties": { - "attribute_value_length_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attribute value size. \nValue must be non-negative.\nIf omitted or null, there is no limit.\n" - }, - "attribute_count_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attribute count. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" - } - } - }, - "AttributeNameValue": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "The attribute name.\nProperty is required and must be non-null.\n" - }, - "value": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "null" - }, - { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1 - }, - { - "type": "array", - "items": { - "type": "boolean" - }, - "minItems": 1 - }, - { - "type": "array", - "items": { - "type": "number" - }, - "minItems": 1 - } - ], - "description": "The attribute value.\nThe type of value must match .type.\nProperty must be present, but if null the entry is ignored.\n" - }, - "type": { - "$ref": "#/$defs/AttributeType", - "description": "The attribute type.\nValues include:\n* bool: Boolean attribute value.\n* bool_array: Boolean array attribute value.\n* double: Double attribute value.\n* double_array: Double array attribute value.\n* int: Integer attribute value.\n* int_array: Integer array attribute value.\n* string: String attribute value.\n* string_array: String array attribute value.\nIf omitted, string is used.\n" - } - }, - "required": [ - "name", - "value" - ] - }, - "AttributeType": { - "type": [ - "string", - "null" - ], - "enum": [ - "string", - "bool", - "int", - "double", - "string_array", - "bool_array", - "int_array", - "double_array" - ] - }, - "B3MultiPropagator": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "B3Propagator": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "BaggagePropagator": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "Base2ExponentialBucketHistogramAggregation": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "max_scale": { - "type": [ - "integer", - "null" - ], - "minimum": -10, - "maximum": 20, - "description": "Configure the max scale factor.\nIf omitted or null, 20 is used.\n" - }, - "max_size": { - "type": [ - "integer", - "null" - ], - "minimum": 2, - "description": "Configure the maximum number of buckets in each of the positive and negative ranges, not counting the special zero bucket.\nIf omitted or null, 160 is used.\n" - }, - "record_min_max": { - "type": [ - "boolean", - "null" - ], - "description": "Configure whether or not to record min and max.\nIf omitted or null, true is used.\n" - } - } - }, - "BatchLogRecordProcessor": { - "type": "object", - "additionalProperties": false, - "properties": { - "schedule_delay": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure delay interval (in milliseconds) between two consecutive exports. \nValue must be non-negative.\nIf omitted or null, 1000 is used.\n" - }, - "export_timeout": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure maximum allowed time (in milliseconds) to export data. \nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 30000 is used.\n" - }, - "max_queue_size": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure maximum queue size. Value must be positive.\nIf omitted or null, 2048 is used.\n" - }, - "max_export_batch_size": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure maximum batch size. Value must be positive.\nIf omitted or null, 512 is used.\n" - }, - "exporter": { - "$ref": "#/$defs/LogRecordExporter", - "description": "Configure exporter.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "exporter" - ] - }, - "BatchSpanProcessor": { - "type": "object", - "additionalProperties": false, - "properties": { - "schedule_delay": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure delay interval (in milliseconds) between two consecutive exports. \nValue must be non-negative.\nIf omitted or null, 5000 is used.\n" - }, - "export_timeout": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure maximum allowed time (in milliseconds) to export data. \nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 30000 is used.\n" - }, - "max_queue_size": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure maximum queue size. Value must be positive.\nIf omitted or null, 2048 is used.\n" - }, - "max_export_batch_size": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure maximum batch size. Value must be positive.\nIf omitted or null, 512 is used.\n" - }, - "exporter": { - "$ref": "#/$defs/SpanExporter", - "description": "Configure exporter.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "exporter" - ] - }, - "CardinalityLimits": { - "type": "object", - "additionalProperties": false, - "properties": { - "default": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for all instrument types.\nInstrument-specific cardinality limits take priority.\nIf omitted or null, 2000 is used.\n" - }, - "counter": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for counter instruments.\nIf omitted or null, the value from .default is used.\n" - }, - "gauge": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for gauge instruments.\nIf omitted or null, the value from .default is used.\n" - }, - "histogram": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for histogram instruments.\nIf omitted or null, the value from .default is used.\n" - }, - "observable_counter": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for observable_counter instruments.\nIf omitted or null, the value from .default is used.\n" - }, - "observable_gauge": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for observable_gauge instruments.\nIf omitted or null, the value from .default is used.\n" - }, - "observable_up_down_counter": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for observable_up_down_counter instruments.\nIf omitted or null, the value from .default is used.\n" - }, - "up_down_counter": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure default cardinality limit for up_down_counter instruments.\nIf omitted or null, the value from .default is used.\n" - } - } - }, - "ConsoleExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ConsoleMetricExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "temporality_preference": { - "$ref": "#/$defs/ExporterTemporalityPreference", - "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" - }, - "default_histogram_aggregation": { - "$ref": "#/$defs/ExporterDefaultHistogramAggregation", - "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" - } - } - }, - "DefaultAggregation": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "Distribution": { - "type": "object", - "additionalProperties": { - "type": "object" - }, - "minProperties": 1 - }, - "DropAggregation": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExemplarFilter": { - "type": [ - "string", - "null" - ], - "enum": [ - "always_on", - "always_off", - "trace_based" - ] - }, - "ExperimentalCodeInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "semconv": { - "$ref": "#/$defs/ExperimentalSemconvConfig", - "description": "Configure code semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee code semantic conventions: https://opentelemetry.io/docs/specs/semconv/registry/attributes/code/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" - } - } - }, - "ExperimentalComposableAlwaysOffSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExperimentalComposableAlwaysOnSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExperimentalComposableParentThresholdSampler": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "root": { - "$ref": "#/$defs/ExperimentalComposableSampler", - "description": "Sampler to use when there is no parent.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "root" - ] - }, - "ExperimentalComposableProbabilitySampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "ratio": { - "type": [ - "number", - "null" - ], - "minimum": 0, - "maximum": 1, - "description": "Configure ratio.\nIf omitted or null, 1.0 is used.\n" - } - } - }, - "ExperimentalComposableRuleBasedSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "rules": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/ExperimentalComposableRuleBasedSamplerRule" - }, - "description": "The rules for the sampler, matched in order.\nEach rule can have multiple match conditions. All conditions must match for the rule to match.\nIf no conditions are specified, the rule matches all spans that reach it.\nIf no rules match, the span is not sampled.\nIf omitted, no span is sampled.\n" - } - } - }, - "ExperimentalComposableRuleBasedSamplerRule": { - "type": "object", - "description": "A rule for ExperimentalComposableRuleBasedSampler. A rule can have multiple match conditions - the sampler will be applied if all match. \nIf no conditions are specified, the rule matches all spans that reach it.\n", - "additionalProperties": false, - "properties": { - "attribute_values": { - "$ref": "#/$defs/ExperimentalComposableRuleBasedSamplerRuleAttributeValues", - "description": "Values to match against a single attribute. Non-string attributes are matched using their string representation:\nfor example, a value of \"404\" would match the http.response.status_code 404. For array attributes, if any\nitem matches, it is considered a match.\nIf omitted, ignore.\n" - }, - "attribute_patterns": { - "$ref": "#/$defs/ExperimentalComposableRuleBasedSamplerRuleAttributePatterns", - "description": "Patterns to match against a single attribute. Non-string attributes are matched using their string representation:\nfor example, a pattern of \"4*\" would match any http.response.status_code in 400-499. For array attributes, if any\nitem matches, it is considered a match.\nIf omitted, ignore.\n" - }, - "span_kinds": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/SpanKind" - }, - "description": "The span kinds to match. If the span's kind matches any of these, it matches.\nValues include:\n* client: client, a client span.\n* consumer: consumer, a consumer span.\n* internal: internal, an internal span.\n* producer: producer, a producer span.\n* server: server, a server span.\nIf omitted, ignore.\n" - }, - "parent": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/ExperimentalSpanParent" - }, - "description": "The parent span types to match.\nValues include:\n* local: local, a local parent.\n* none: none, no parent, i.e., the trace root.\n* remote: remote, a remote parent.\nIf omitted, ignore.\n" - }, - "sampler": { - "$ref": "#/$defs/ExperimentalComposableSampler", - "description": "The sampler to use for matching spans.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "sampler" - ] - }, - "ExperimentalComposableRuleBasedSamplerRuleAttributePatterns": { - "type": "object", - "additionalProperties": false, - "properties": { - "key": { - "type": "string", - "description": "The attribute key to match against.\nProperty is required and must be non-null.\n" - }, - "included": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure list of value patterns to include.\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, all values are included.\n" - }, - "excluded": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure list of value patterns to exclude. Applies after .included (i.e. excluded has higher priority than included).\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, .included attributes are included.\n" - } - }, - "required": [ - "key" - ] - }, - "ExperimentalComposableRuleBasedSamplerRuleAttributeValues": { - "type": "object", - "additionalProperties": false, - "properties": { - "key": { - "type": "string", - "description": "The attribute key to match against.\nProperty is required and must be non-null.\n" - }, - "values": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "The attribute values to match against. If the attribute's value matches any of these, it matches.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "key", - "values" - ] - }, - "ExperimentalComposableSampler": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "always_off": { - "$ref": "#/$defs/ExperimentalComposableAlwaysOffSampler", - "description": "Configure sampler to be always_off.\nIf omitted, ignore.\n" - }, - "always_on": { - "$ref": "#/$defs/ExperimentalComposableAlwaysOnSampler", - "description": "Configure sampler to be always_on.\nIf omitted, ignore.\n" - }, - "parent_threshold": { - "$ref": "#/$defs/ExperimentalComposableParentThresholdSampler", - "description": "Configure sampler to be parent_threshold.\nIf omitted, ignore.\n" - }, - "probability": { - "$ref": "#/$defs/ExperimentalComposableProbabilitySampler", - "description": "Configure sampler to be probability.\nIf omitted, ignore.\n" - }, - "rule_based": { - "$ref": "#/$defs/ExperimentalComposableRuleBasedSampler", - "description": "Configure sampler to be rule_based.\nIf omitted, ignore.\n" - } - } - }, - "ExperimentalContainerResourceDetector": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExperimentalDbInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "semconv": { - "$ref": "#/$defs/ExperimentalSemconvConfig", - "description": "Configure database semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee database migration: https://opentelemetry.io/docs/specs/semconv/database/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" - } - } - }, - "ExperimentalEventToSpanEventBridgeLogRecordProcessor": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExperimentalGenAiInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "semconv": { - "$ref": "#/$defs/ExperimentalSemconvConfig", - "description": "Configure GenAI semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee GenAI semantic conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" - } - } - }, - "ExperimentalGeneralInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "http": { - "$ref": "#/$defs/ExperimentalHttpInstrumentation", - "description": "Configure instrumentations following the http semantic conventions.\nSee http semantic conventions: https://opentelemetry.io/docs/specs/semconv/http/\nIf omitted, defaults as described in ExperimentalHttpInstrumentation are used.\n" - }, - "code": { - "$ref": "#/$defs/ExperimentalCodeInstrumentation", - "description": "Configure instrumentations following the code semantic conventions.\nSee code semantic conventions: https://opentelemetry.io/docs/specs/semconv/registry/attributes/code/\nIf omitted, defaults as described in ExperimentalCodeInstrumentation are used.\n" - }, - "db": { - "$ref": "#/$defs/ExperimentalDbInstrumentation", - "description": "Configure instrumentations following the database semantic conventions.\nSee database semantic conventions: https://opentelemetry.io/docs/specs/semconv/database/\nIf omitted, defaults as described in ExperimentalDbInstrumentation are used.\n" - }, - "gen_ai": { - "$ref": "#/$defs/ExperimentalGenAiInstrumentation", - "description": "Configure instrumentations following the GenAI semantic conventions.\nSee GenAI semantic conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/\nIf omitted, defaults as described in ExperimentalGenAiInstrumentation are used.\n" - }, - "messaging": { - "$ref": "#/$defs/ExperimentalMessagingInstrumentation", - "description": "Configure instrumentations following the messaging semantic conventions.\nSee messaging semantic conventions: https://opentelemetry.io/docs/specs/semconv/messaging/\nIf omitted, defaults as described in ExperimentalMessagingInstrumentation are used.\n" - }, - "rpc": { - "$ref": "#/$defs/ExperimentalRpcInstrumentation", - "description": "Configure instrumentations following the RPC semantic conventions.\nSee RPC semantic conventions: https://opentelemetry.io/docs/specs/semconv/rpc/\nIf omitted, defaults as described in ExperimentalRpcInstrumentation are used.\n" - }, - "sanitization": { - "$ref": "#/$defs/ExperimentalSanitization", - "description": "Configure general sanitization options.\nIf omitted, defaults as described in ExperimentalSanitization are used.\n" - }, - "stability_opt_in_list": { - "type": [ - "string", - "null" - ], - "description": "Configure semantic convention stability opt-in as a comma-separated list.\nThis property follows the format and semantics of the OTEL_SEMCONV_STABILITY_OPT_IN environment variable.\nControls the emission of stable vs. experimental semantic conventions for instrumentation.\nThis setting is only intended for migrating from experimental to stable semantic conventions.\n\nKnown values include:\n- http: Emit stable HTTP and networking conventions only\n- http/dup: Emit both old and stable HTTP and networking conventions (for phased migration)\n- database: Emit stable database conventions only\n- database/dup: Emit both old and stable database conventions (for phased migration)\n- rpc: Emit stable RPC conventions only\n- rpc/dup: Emit both experimental and stable RPC conventions (for phased migration)\n- messaging: Emit stable messaging conventions only\n- messaging/dup: Emit both old and stable messaging conventions (for phased migration)\n- code: Emit stable code conventions only\n- code/dup: Emit both old and stable code conventions (for phased migration)\n\nMultiple values can be specified as a comma-separated list (e.g., \"http,database/dup\").\nAdditional signal types may be supported in future versions.\n\nDomain-specific semconv properties (e.g., .instrumentation/development.general.db.semconv) take precedence over this general setting.\n\nSee:\n- HTTP migration: https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/\n- Database migration: https://opentelemetry.io/docs/specs/semconv/database/\n- RPC: https://opentelemetry.io/docs/specs/semconv/rpc/\n- Messaging: https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/\nIf omitted or null, no opt-in is configured and instrumentations continue emitting their default semantic convention version.\n" - } - } - }, - "ExperimentalHostResourceDetector": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExperimentalHttpClientInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "request_captured_headers": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure headers to capture for outbound http requests.\nIf omitted, no outbound request headers are captured.\n" - }, - "response_captured_headers": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure headers to capture for inbound http responses.\nIf omitted, no inbound response headers are captured.\n" - }, - "known_methods": { - "type": "array", - "minItems": 0, - "items": { - "type": "string" - }, - "description": "Override the default list of known HTTP methods.\nKnown methods are case-sensitive.\nThis is a full override of the default known methods, not a list of known methods in addition to the defaults.\nIf omitted, HTTP methods GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH are known.\n" - } - } - }, - "ExperimentalHttpInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "semconv": { - "$ref": "#/$defs/ExperimentalSemconvConfig", - "description": "Configure HTTP semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee HTTP migration: https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" - }, - "client": { - "$ref": "#/$defs/ExperimentalHttpClientInstrumentation", - "description": "Configure instrumentations following the http client semantic conventions.\nIf omitted, defaults as described in ExperimentalHttpClientInstrumentation are used.\n" - }, - "server": { - "$ref": "#/$defs/ExperimentalHttpServerInstrumentation", - "description": "Configure instrumentations following the http server semantic conventions.\nIf omitted, defaults as described in ExperimentalHttpServerInstrumentation are used.\n" - } - } - }, - "ExperimentalHttpServerInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "request_captured_headers": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure headers to capture for inbound http requests.\nIf omitted, no request headers are captured.\n" - }, - "response_captured_headers": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure headers to capture for outbound http responses.\nIf omitted, no response headers are captures.\n" - }, - "known_methods": { - "type": "array", - "minItems": 0, - "items": { - "type": "string" - }, - "description": "Override the default list of known HTTP methods.\nKnown methods are case-sensitive.\nThis is a full override of the default known methods, not a list of known methods in addition to the defaults.\nIf omitted, HTTP methods GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH are known.\n" - } - } - }, - "ExperimentalInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "general": { - "$ref": "#/$defs/ExperimentalGeneralInstrumentation", - "description": "Configure general SemConv options that may apply to multiple languages and instrumentations.\nInstrumenation may merge general config options with the language specific configuration at .instrumentation..\nIf omitted, default values as described in ExperimentalGeneralInstrumentation are used.\n" - }, - "cpp": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure C++ language-specific instrumentation libraries.\nIf omitted, instrumentation defaults are used.\n" - }, - "dotnet": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure .NET language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "erlang": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure Erlang language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "go": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure Go language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "java": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure Java language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "js": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure JavaScript language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "php": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure PHP language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "python": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure Python language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "ruby": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure Ruby language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "rust": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure Rust language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - }, - "swift": { - "$ref": "#/$defs/ExperimentalLanguageSpecificInstrumentation", - "description": "Configure Swift language-specific instrumentation libraries.\nEach entry's key identifies a particular instrumentation library. The corresponding value configures it.\nIf omitted, instrumentation defaults are used.\n" - } - } - }, - "ExperimentalJaegerRemoteSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "endpoint": { - "type": [ - "string" - ], - "description": "Configure the endpoint of the jaeger remote sampling service.\nProperty is required and must be non-null.\n" - }, - "interval": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure the polling interval (in milliseconds) to fetch from the remote sampling service.\nIf omitted or null, 60000 is used.\n" - }, - "initial_sampler": { - "$ref": "#/$defs/Sampler", - "description": "Configure the initial sampler used before first configuration is fetched.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "endpoint", - "initial_sampler" - ] - }, - "ExperimentalLanguageSpecificInstrumentation": { - "type": "object", - "additionalProperties": { - "type": "object" - } - }, - "ExperimentalLoggerConfig": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "enabled": { - "type": [ - "boolean", - "null" - ], - "description": "Configure if the logger is enabled or not.\nIf omitted or null, true is used.\n" - }, - "minimum_severity": { - "$ref": "#/$defs/SeverityNumber", - "description": "Configure severity filtering.\nLog records with an non-zero (i.e. unspecified) severity number which is less than minimum_severity are not processed.\nValues include:\n* debug: debug, severity number 5.\n* debug2: debug2, severity number 6.\n* debug3: debug3, severity number 7.\n* debug4: debug4, severity number 8.\n* error: error, severity number 17.\n* error2: error2, severity number 18.\n* error3: error3, severity number 19.\n* error4: error4, severity number 20.\n* fatal: fatal, severity number 21.\n* fatal2: fatal2, severity number 22.\n* fatal3: fatal3, severity number 23.\n* fatal4: fatal4, severity number 24.\n* info: info, severity number 9.\n* info2: info2, severity number 10.\n* info3: info3, severity number 11.\n* info4: info4, severity number 12.\n* trace: trace, severity number 1.\n* trace2: trace2, severity number 2.\n* trace3: trace3, severity number 3.\n* trace4: trace4, severity number 4.\n* warn: warn, severity number 13.\n* warn2: warn2, severity number 14.\n* warn3: warn3, severity number 15.\n* warn4: warn4, severity number 16.\nIf omitted, severity filtering is not applied.\n" - }, - "trace_based": { - "type": [ - "boolean", - "null" - ], - "description": "Configure trace based filtering.\nIf true, log records associated with unsampled trace contexts traces are not processed. If false, or if a log record is not associated with a trace context, trace based filtering is not applied.\nIf omitted or null, trace based filtering is not applied.\n" - } - } - }, - "ExperimentalLoggerConfigurator": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "default_config": { - "$ref": "#/$defs/ExperimentalLoggerConfig", - "description": "Configure the default logger config used there is no matching entry in .logger_configurator/development.loggers.\nIf omitted, unmatched .loggers use default values as described in ExperimentalLoggerConfig.\n" - }, - "loggers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/ExperimentalLoggerMatcherAndConfig" - }, - "description": "Configure loggers.\nIf omitted, all loggers use .default_config.\n" - } - } - }, - "ExperimentalLoggerMatcherAndConfig": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "name": { - "type": [ - "string" - ], - "description": "Configure logger names to match. Matching is case-sensitive, evaluated as follows:\n\n * If the logger name exactly matches.\n * If the logger name matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nProperty is required and must be non-null.\n" - }, - "config": { - "$ref": "#/$defs/ExperimentalLoggerConfig", - "description": "The logger config.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "name", - "config" - ] - }, - "ExperimentalMessagingInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "semconv": { - "$ref": "#/$defs/ExperimentalSemconvConfig", - "description": "Configure messaging semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee messaging semantic conventions: https://opentelemetry.io/docs/specs/semconv/messaging/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" - } - } - }, - "ExperimentalMeterConfig": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "enabled": { - "type": [ - "boolean" - ], - "description": "Configure if the meter is enabled or not.\nIf omitted, true is used.\n" - } - } - }, - "ExperimentalMeterConfigurator": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "default_config": { - "$ref": "#/$defs/ExperimentalMeterConfig", - "description": "Configure the default meter config used there is no matching entry in .meter_configurator/development.meters.\nIf omitted, unmatched .meters use default values as described in ExperimentalMeterConfig.\n" - }, - "meters": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/ExperimentalMeterMatcherAndConfig" - }, - "description": "Configure meters.\nIf omitted, all meters used .default_config.\n" - } - } - }, - "ExperimentalMeterMatcherAndConfig": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "name": { - "type": [ - "string" - ], - "description": "Configure meter names to match. Matching is case-sensitive, evaluated as follows:\n\n * If the meter name exactly matches.\n * If the meter name matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nProperty is required and must be non-null.\n" - }, - "config": { - "$ref": "#/$defs/ExperimentalMeterConfig", - "description": "The meter config.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "name", - "config" - ] - }, - "ExperimentalOtlpFileExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "output_stream": { - "type": [ - "string", - "null" - ], - "description": "Configure output stream. \nValues include stdout, or scheme+destination. For example: file:///path/to/file.jsonl.\nIf omitted or null, stdout is used.\n" - } - } - }, - "ExperimentalOtlpFileMetricExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "output_stream": { - "type": [ - "string", - "null" - ], - "description": "Configure output stream. \nValues include stdout, or scheme+destination. For example: file:///path/to/file.jsonl.\nIf omitted or null, stdout is used.\n" - }, - "temporality_preference": { - "$ref": "#/$defs/ExporterTemporalityPreference", - "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" - }, - "default_histogram_aggregation": { - "$ref": "#/$defs/ExporterDefaultHistogramAggregation", - "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" - } - } - }, - "ExperimentalProbabilitySampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "ratio": { - "type": [ - "number", - "null" - ], - "minimum": 0, - "maximum": 1, - "description": "Configure ratio.\nIf omitted or null, 1.0 is used.\n" - } - } - }, - "ExperimentalProcessResourceDetector": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExperimentalPrometheusMetricExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "host": { - "type": [ - "string", - "null" - ], - "description": "Configure host.\nIf omitted or null, localhost is used.\n" - }, - "port": { - "type": [ - "integer", - "null" - ], - "description": "Configure port.\nIf omitted or null, 9464 is used.\n" - }, - "scope_info_enabled": { - "type": [ - "boolean", - "null" - ], - "description": "Configure Prometheus Exporter to produce metrics with scope labels.\nIf omitted or null, true is used.\n" - }, - "target_info_enabled/development": { - "type": [ - "boolean", - "null" - ], - "description": "Configure Prometheus Exporter to produce metrics with a target info metric for the resource.\nIf omitted or null, true is used.\n" - }, - "resource_constant_labels": { - "$ref": "#/$defs/IncludeExclude", - "description": "Configure Prometheus Exporter to add resource attributes as metrics attributes, where the resource attribute keys match the patterns.\nIf omitted, no resource attributes are added.\n" - }, - "translation_strategy": { - "$ref": "#/$defs/ExperimentalPrometheusTranslationStrategy", - "description": "Configure how metric names are translated to Prometheus metric names.\nValues include:\n* no_translation/development: Special character escaping is disabled. Type and unit suffixes are disabled. Metric names are unaltered.\n* no_utf8_escaping_with_suffixes/development: Special character escaping is disabled. Type and unit suffixes are enabled.\n* underscore_escaping_with_suffixes: Special character escaping is enabled. Type and unit suffixes are enabled.\n* underscore_escaping_without_suffixes/development: Special character escaping is enabled. Type and unit suffixes are disabled. This represents classic Prometheus metric name compatibility.\nIf omitted, underscore_escaping_with_suffixes is used.\n" - } - } - }, - "ExperimentalPrometheusTranslationStrategy": { - "type": [ - "string", - "null" - ], - "enum": [ - "underscore_escaping_with_suffixes", - "underscore_escaping_without_suffixes/development", - "no_utf8_escaping_with_suffixes/development", - "no_translation/development" - ] - }, - "ExperimentalResourceDetection": { - "type": "object", - "additionalProperties": false, - "properties": { - "attributes": { - "$ref": "#/$defs/IncludeExclude", - "description": "Configure attributes provided by resource detectors.\nIf omitted, all attributes from resource detectors are added.\n" - }, - "detectors": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/ExperimentalResourceDetector" - }, - "description": "Configure resource detectors.\nResource detector names are dependent on the SDK language ecosystem. Please consult documentation for each respective language. \nIf omitted, no resource detectors are enabled.\n" - } - } - }, - "ExperimentalResourceDetector": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "container": { - "$ref": "#/$defs/ExperimentalContainerResourceDetector", - "description": "Enable the container resource detector, which populates container.* attributes.\nIf omitted, ignore.\n" - }, - "host": { - "$ref": "#/$defs/ExperimentalHostResourceDetector", - "description": "Enable the host resource detector, which populates host.* and os.* attributes.\nIf omitted, ignore.\n" - }, - "process": { - "$ref": "#/$defs/ExperimentalProcessResourceDetector", - "description": "Enable the process resource detector, which populates process.* attributes.\nIf omitted, ignore.\n" - }, - "service": { - "$ref": "#/$defs/ExperimentalServiceResourceDetector", - "description": "Enable the service detector, which populates service.name based on the OTEL_SERVICE_NAME environment variable and service.instance.id.\nIf omitted, ignore.\n" - } - } - }, - "ExperimentalRpcInstrumentation": { - "type": "object", - "additionalProperties": false, - "properties": { - "semconv": { - "$ref": "#/$defs/ExperimentalSemconvConfig", - "description": "Configure RPC semantic convention version and migration behavior.\n\nThis property takes precedence over the .instrumentation/development.general.stability_opt_in_list setting.\n\nSee RPC semantic conventions: https://opentelemetry.io/docs/specs/semconv/rpc/\nIf omitted, uses the general stability_opt_in_list setting, or instrumentations continue emitting their default semantic convention version if not set.\n" - } - } - }, - "ExperimentalSanitization": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "$ref": "#/$defs/ExperimentalUrlSanitization", - "description": "Configure URL sanitization options.\nIf omitted, defaults as described in ExperimentalUrlSanitization are used.\n" - } - } - }, - "ExperimentalSemconvConfig": { - "type": "object", - "additionalProperties": false, - "properties": { - "version": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "The target semantic convention version for this domain (e.g., 1).\nIf omitted or null, the latest stable version is used, or if no stable version is available and .experimental is true then the latest experimental version is used.\n" - }, - "experimental": { - "type": [ - "boolean", - "null" - ], - "description": "Use latest experimental semantic conventions (before stable is available or to enable experimental features on top of stable conventions).\nIf omitted or null, false is used.\n" - }, - "dual_emit": { - "type": [ - "boolean", - "null" - ], - "description": "When true, also emit the previous major version alongside the target version.\nFor version=1, the previous version refers to the pre-stable conventions that the instrumentation emitted before the first stable semantic convention version was defined.\nFor version=2 and above, the previous version is the prior stable major version (e.g., version=2, dual_emit=true emits both v2 and v1).\nEnables dual-emit for phased migration between versions.\nIf omitted or null, false is used.\n" - } - } - }, - "ExperimentalServiceResourceDetector": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "ExperimentalSpanParent": { - "type": [ - "string", - "null" - ], - "enum": [ - "none", - "remote", - "local" - ] - }, - "ExperimentalTracerConfig": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "enabled": { - "type": [ - "boolean" - ], - "description": "Configure if the tracer is enabled or not.\nIf omitted, true is used.\n" - } - } - }, - "ExperimentalTracerConfigurator": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "default_config": { - "$ref": "#/$defs/ExperimentalTracerConfig", - "description": "Configure the default tracer config used there is no matching entry in .tracer_configurator/development.tracers.\nIf omitted, unmatched .tracers use default values as described in ExperimentalTracerConfig.\n" - }, - "tracers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/ExperimentalTracerMatcherAndConfig" - }, - "description": "Configure tracers.\nIf omitted, all tracers use .default_config.\n" - } - } - }, - "ExperimentalTracerMatcherAndConfig": { - "type": [ - "object" - ], - "additionalProperties": false, - "properties": { - "name": { - "type": [ - "string" - ], - "description": "Configure tracer names to match. Matching is case-sensitive, evaluated as follows:\n\n * If the tracer name exactly matches.\n * If the tracer name matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nProperty is required and must be non-null.\n" - }, - "config": { - "$ref": "#/$defs/ExperimentalTracerConfig", - "description": "The tracer config.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "name", - "config" - ] - }, - "ExperimentalUrlSanitization": { - "type": "object", - "additionalProperties": false, - "properties": { - "sensitive_query_parameters": { - "type": "array", - "minItems": 0, - "items": { - "type": "string" - }, - "description": "List of query parameter names whose values should be redacted from URLs.\nQuery parameter names are case-sensitive.\nThis is a full override of the default sensitive query parameter keys, it is not a list of keys in addition to the defaults.\nSet to an empty array to disable query parameter redaction.\nIf omitted, the default sensitive query parameter list as defined by the url semantic conventions (https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/url.md) is used.\n" - } - } - }, - "ExplicitBucketHistogramAggregation": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "boundaries": { - "type": "array", - "minItems": 0, - "items": { - "type": "number" - }, - "description": "Configure bucket boundaries.\nIf omitted, [0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000] is used.\n" - }, - "record_min_max": { - "type": [ - "boolean", - "null" - ], - "description": "Configure record min and max.\nIf omitted or null, true is used.\n" - } - } - }, - "ExporterDefaultHistogramAggregation": { - "type": [ - "string", - "null" - ], - "enum": [ - "explicit_bucket_histogram", - "base2_exponential_bucket_histogram" - ] - }, - "ExporterTemporalityPreference": { - "type": [ - "string", - "null" - ], - "enum": [ - "cumulative", - "delta", - "low_memory" - ] - }, - "GrpcTls": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "ca_file": { - "type": [ - "string", - "null" - ], - "description": "Configure certificate used to verify a server's TLS credentials. \nAbsolute path to certificate file in PEM format.\nIf omitted or null, system default certificate verification is used for secure connections.\n" - }, - "key_file": { - "type": [ - "string", - "null" - ], - "description": "Configure mTLS private client key. \nAbsolute path to client key file in PEM format. If set, .client_certificate must also be set.\nIf omitted or null, mTLS is not used.\n" - }, - "cert_file": { - "type": [ - "string", - "null" - ], - "description": "Configure mTLS client certificate. \nAbsolute path to client certificate file in PEM format. If set, .client_key must also be set.\nIf omitted or null, mTLS is not used.\n" - }, - "insecure": { - "type": [ - "boolean", - "null" - ], - "description": "Configure client transport security for the exporter's connection. \nOnly applicable when .endpoint is provided without http or https scheme. Implementations may choose to ignore .insecure.\nIf omitted or null, false is used.\n" - } - } - }, - "HttpTls": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "ca_file": { - "type": [ - "string", - "null" - ], - "description": "Configure certificate used to verify a server's TLS credentials. \nAbsolute path to certificate file in PEM format.\nIf omitted or null, system default certificate verification is used for secure connections.\n" - }, - "key_file": { - "type": [ - "string", - "null" - ], - "description": "Configure mTLS private client key. \nAbsolute path to client key file in PEM format. If set, .client_certificate must also be set.\nIf omitted or null, mTLS is not used.\n" - }, - "cert_file": { - "type": [ - "string", - "null" - ], - "description": "Configure mTLS client certificate. \nAbsolute path to client certificate file in PEM format. If set, .client_key must also be set.\nIf omitted or null, mTLS is not used.\n" - } - } - }, - "IdGenerator": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "random": { - "$ref": "#/$defs/RandomIdGenerator", - "description": "Configure the ID generator to randomly generate TraceIds and SpanIds (spec default).\nIf omitted, ignore.\n" - } - } - }, - "IncludeExclude": { - "type": "object", - "additionalProperties": false, - "properties": { - "included": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure list of value patterns to include.\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, all values are included.\n" - }, - "excluded": { - "type": "array", - "minItems": 1, - "items": { - "type": "string" - }, - "description": "Configure list of value patterns to exclude. Applies after .included (i.e. excluded has higher priority than included).\nMatching is case-sensitive. Values are evaluated to match as follows:\n * If the value exactly matches.\n * If the value matches the wildcard pattern, where '?' matches any single character and '*' matches any number of characters including none.\nIf omitted, .included attributes are included.\n" - } - } - }, - "InstrumentType": { - "type": [ - "string", - "null" - ], - "enum": [ - "counter", - "gauge", - "histogram", - "observable_counter", - "observable_gauge", - "observable_up_down_counter", - "up_down_counter" - ] - }, - "LastValueAggregation": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "LoggerProvider": { - "type": "object", - "additionalProperties": false, - "properties": { - "processors": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/LogRecordProcessor" - }, - "description": "Configure log record processors.\nProperty is required and must be non-null.\n" - }, - "limits": { - "$ref": "#/$defs/LogRecordLimits", - "description": "Configure log record limits. See also attribute_limits.\nIf omitted, default values as described in LogRecordLimits are used.\n" - }, - "logger_configurator/development": { - "$ref": "#/$defs/ExperimentalLoggerConfigurator", - "description": "Configure loggers.\nIf omitted, all loggers use default values as described in ExperimentalLoggerConfig.\n" - } - }, - "required": [ - "processors" - ] - }, - "LogRecordExporter": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "otlp_http": { - "$ref": "#/$defs/OtlpHttpExporter", - "description": "Configure exporter to be OTLP with HTTP transport.\nIf omitted, ignore.\n" - }, - "otlp_grpc": { - "$ref": "#/$defs/OtlpGrpcExporter", - "description": "Configure exporter to be OTLP with gRPC transport.\nIf omitted, ignore.\n" - }, - "otlp_file/development": { - "$ref": "#/$defs/ExperimentalOtlpFileExporter", - "description": "Configure exporter to be OTLP with file transport.\nIf omitted, ignore.\n" - }, - "console": { - "$ref": "#/$defs/ConsoleExporter", - "description": "Configure exporter to be console.\nIf omitted, ignore.\n" - } - } - }, - "LogRecordLimits": { - "type": "object", - "additionalProperties": false, - "properties": { - "attribute_value_length_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attribute value size. Overrides .attribute_limits.attribute_value_length_limit. \nValue must be non-negative.\nIf omitted or null, there is no limit.\n" - }, - "attribute_count_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attribute count. Overrides .attribute_limits.attribute_count_limit. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" - } - } - }, - "LogRecordProcessor": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "batch": { - "$ref": "#/$defs/BatchLogRecordProcessor", - "description": "Configure a batch log record processor.\nIf omitted, ignore.\n" - }, - "simple": { - "$ref": "#/$defs/SimpleLogRecordProcessor", - "description": "Configure a simple log record processor.\nIf omitted, ignore.\n" - }, - "event_to_span_event_bridge/development": { - "$ref": "#/$defs/ExperimentalEventToSpanEventBridgeLogRecordProcessor", - "description": "Configure an event to span event bridge log record processor.\nIf omitted, ignore.\n" - } - } - }, - "MeterProvider": { - "type": "object", - "additionalProperties": false, - "properties": { - "readers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/MetricReader" - }, - "description": "Configure metric readers.\nProperty is required and must be non-null.\n" - }, - "views": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/View" - }, - "description": "Configure views. \nEach view has a selector which determines the instrument(s) it applies to, and a configuration for the resulting stream(s).\nIf omitted, no views are registered.\n" - }, - "exemplar_filter": { - "$ref": "#/$defs/ExemplarFilter", - "description": "Configure the exemplar filter.\nValues include:\n* always_off: ExemplarFilter which makes no measurements eligible for being an Exemplar.\n* always_on: ExemplarFilter which makes all measurements eligible for being an Exemplar.\n* trace_based: ExemplarFilter which makes measurements recorded in the context of a sampled parent span eligible for being an Exemplar.\nIf omitted, trace_based is used.\n" - }, - "meter_configurator/development": { - "$ref": "#/$defs/ExperimentalMeterConfigurator", - "description": "Configure meters.\nIf omitted, all meters use default values as described in ExperimentalMeterConfig.\n" - } - }, - "required": [ - "readers" - ] - }, - "MetricProducer": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "opencensus": { - "$ref": "#/$defs/OpenCensusMetricProducer", - "description": "Configure metric producer to be opencensus.\nIf omitted, ignore.\n" - } - } - }, - "MetricReader": { - "type": "object", - "additionalProperties": false, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "periodic": { - "$ref": "#/$defs/PeriodicMetricReader", - "description": "Configure a periodic metric reader.\nIf omitted, ignore.\n" - }, - "pull": { - "$ref": "#/$defs/PullMetricReader", - "description": "Configure a pull based metric reader.\nIf omitted, ignore.\n" - } - } - }, - "NameStringValuePair": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "The name of the pair.\nProperty is required and must be non-null.\n" - }, - "value": { - "type": [ - "string", - "null" - ], - "description": "The value of the pair.\nProperty must be present, but if null the behavior is dependent on usage context.\n" - } - }, - "required": [ - "name", - "value" - ] - }, - "OpenCensusMetricProducer": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "OtlpGrpcExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "endpoint": { - "type": [ - "string", - "null" - ], - "description": "Configure endpoint.\nIf omitted or null, http://localhost:4317 is used.\n" - }, - "tls": { - "$ref": "#/$defs/GrpcTls", - "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" - }, - "headers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/NameStringValuePair" - }, - "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" - }, - "headers_list": { - "type": [ - "string", - "null" - ], - "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" - }, - "compression": { - "type": [ - "string", - "null" - ], - "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" - } - } - }, - "OtlpGrpcMetricExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "endpoint": { - "type": [ - "string", - "null" - ], - "description": "Configure endpoint.\nIf omitted or null, http://localhost:4317 is used.\n" - }, - "tls": { - "$ref": "#/$defs/GrpcTls", - "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" - }, - "headers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/NameStringValuePair" - }, - "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" - }, - "headers_list": { - "type": [ - "string", - "null" - ], - "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" - }, - "compression": { - "type": [ - "string", - "null" - ], - "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" - }, - "temporality_preference": { - "$ref": "#/$defs/ExporterTemporalityPreference", - "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" - }, - "default_histogram_aggregation": { - "$ref": "#/$defs/ExporterDefaultHistogramAggregation", - "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" - } - } - }, - "OtlpHttpEncoding": { - "type": [ - "string", - "null" - ], - "enum": [ - "protobuf", - "json" - ] - }, - "OtlpHttpExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "endpoint": { - "type": [ - "string", - "null" - ], - "description": "Configure endpoint, including the signal specific path.\nIf omitted or null, the http://localhost:4318/v1/{signal} (where signal is 'traces', 'logs', or 'metrics') is used.\n" - }, - "tls": { - "$ref": "#/$defs/HttpTls", - "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" - }, - "headers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/NameStringValuePair" - }, - "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" - }, - "headers_list": { - "type": [ - "string", - "null" - ], - "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" - }, - "compression": { - "type": [ - "string", - "null" - ], - "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" - }, - "encoding": { - "$ref": "#/$defs/OtlpHttpEncoding", - "description": "Configure the encoding used for messages. \nImplementations may not support json.\nValues include:\n* json: Protobuf JSON encoding.\n* protobuf: Protobuf binary encoding.\nIf omitted, protobuf is used.\n" - } - } - }, - "OtlpHttpMetricExporter": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "endpoint": { - "type": [ - "string", - "null" - ], - "description": "Configure endpoint.\nIf omitted or null, http://localhost:4318/v1/metrics is used.\n" - }, - "tls": { - "$ref": "#/$defs/HttpTls", - "description": "Configure TLS settings for the exporter.\nIf omitted, system default TLS settings are used.\n" - }, - "headers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/NameStringValuePair" - }, - "description": "Configure headers. Entries have higher priority than entries from .headers_list.\nIf an entry's .value is null, the entry is ignored.\nIf omitted, no headers are added.\n" - }, - "headers_list": { - "type": [ - "string", - "null" - ], - "description": "Configure headers. Entries have lower priority than entries from .headers.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_EXPORTER_OTLP_HEADERS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options for details.\nIf omitted or null, no headers are added.\n" - }, - "compression": { - "type": [ - "string", - "null" - ], - "description": "Configure compression.\nKnown values include: gzip, none. Implementations may support other compression algorithms.\nIf omitted or null, none is used.\n" - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max time (in milliseconds) to wait for each export.\nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 10000 is used.\n" - }, - "encoding": { - "$ref": "#/$defs/OtlpHttpEncoding", - "description": "Configure the encoding used for messages. \nImplementations may not support json.\nValues include:\n* json: Protobuf JSON encoding.\n* protobuf: Protobuf binary encoding.\nIf omitted, protobuf is used.\n" - }, - "temporality_preference": { - "$ref": "#/$defs/ExporterTemporalityPreference", - "description": "Configure temporality preference.\nValues include:\n* cumulative: Use cumulative aggregation temporality for all instrument types.\n* delta: Use delta aggregation for all instrument types except up down counter and asynchronous up down counter.\n* low_memory: Use delta aggregation temporality for counter and histogram instrument types. Use cumulative aggregation temporality for all other instrument types.\nIf omitted, cumulative is used.\n" - }, - "default_histogram_aggregation": { - "$ref": "#/$defs/ExporterDefaultHistogramAggregation", - "description": "Configure default histogram aggregation.\nValues include:\n* base2_exponential_bucket_histogram: Use base2 exponential histogram as the default aggregation for histogram instruments.\n* explicit_bucket_histogram: Use explicit bucket histogram as the default aggregation for histogram instruments.\nIf omitted, explicit_bucket_histogram is used.\n" - } - } - }, - "ParentBasedSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "root": { - "$ref": "#/$defs/Sampler", - "description": "Configure root sampler.\nIf omitted, always_on is used.\n" - }, - "remote_parent_sampled": { - "$ref": "#/$defs/Sampler", - "description": "Configure remote_parent_sampled sampler.\nIf omitted, always_on is used.\n" - }, - "remote_parent_not_sampled": { - "$ref": "#/$defs/Sampler", - "description": "Configure remote_parent_not_sampled sampler.\nIf omitted, always_off is used.\n" - }, - "local_parent_sampled": { - "$ref": "#/$defs/Sampler", - "description": "Configure local_parent_sampled sampler.\nIf omitted, always_on is used.\n" - }, - "local_parent_not_sampled": { - "$ref": "#/$defs/Sampler", - "description": "Configure local_parent_not_sampled sampler.\nIf omitted, always_off is used.\n" - } - } - }, - "PeriodicMetricReader": { - "type": "object", - "additionalProperties": false, - "properties": { - "interval": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure delay interval (in milliseconds) between start of two consecutive exports. \nValue must be non-negative.\nIf omitted or null, 60000 is used.\n" - }, - "timeout": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure maximum allowed time (in milliseconds) to export data. \nValue must be non-negative. A value of 0 indicates no limit (infinity).\nIf omitted or null, 30000 is used.\n" - }, - "max_export_batch_size/development": { - "type": [ - "integer", - "null" - ], - "minimum": 1, - "description": "Configure maximum export batch size.\nIf omitted or null, no limit is used.\n" - }, - "exporter": { - "$ref": "#/$defs/PushMetricExporter", - "description": "Configure exporter.\nProperty is required and must be non-null.\n" - }, - "producers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/MetricProducer" - }, - "description": "Configure metric producers.\nIf omitted, no metric producers are added.\n" - }, - "cardinality_limits": { - "$ref": "#/$defs/CardinalityLimits", - "description": "Configure cardinality limits.\nIf omitted, default values as described in CardinalityLimits are used.\n" - } - }, - "required": [ - "exporter" - ] - }, - "Propagator": { - "type": "object", - "additionalProperties": false, - "properties": { - "composite": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/TextMapPropagator" - }, - "description": "Configure the propagators in the composite text map propagator. Entries from .composite_list are appended to the list here with duplicates filtered out.\nBuilt-in propagator keys include: tracecontext, baggage, b3, b3multi. Known third party keys include: xray.\nIf omitted, and .composite_list is omitted or null, a noop propagator is used.\n" - }, - "composite_list": { - "type": [ - "string", - "null" - ], - "description": "Configure the propagators in the composite text map propagator. Entries are appended to .composite with duplicates filtered out.\nThe value is a comma separated list of propagator identifiers matching the format of OTEL_PROPAGATORS. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details.\nBuilt-in propagator identifiers include: tracecontext, baggage, b3, b3multi. Known third party identifiers include: xray.\nIf omitted or null, and .composite is omitted or null, a noop propagator is used.\n" - } - } - }, - "PullMetricExporter": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "prometheus/development": { - "$ref": "#/$defs/ExperimentalPrometheusMetricExporter", - "description": "Configure exporter to be prometheus.\nIf omitted, ignore.\n" - } - } - }, - "PullMetricReader": { - "type": "object", - "additionalProperties": false, - "properties": { - "exporter": { - "$ref": "#/$defs/PullMetricExporter", - "description": "Configure exporter.\nProperty is required and must be non-null.\n" - }, - "producers": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/MetricProducer" - }, - "description": "Configure metric producers.\nIf omitted, no metric producers are added.\n" - }, - "cardinality_limits": { - "$ref": "#/$defs/CardinalityLimits", - "description": "Configure cardinality limits.\nIf omitted, default values as described in CardinalityLimits are used.\n" - } - }, - "required": [ - "exporter" - ] - }, - "PushMetricExporter": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "otlp_http": { - "$ref": "#/$defs/OtlpHttpMetricExporter", - "description": "Configure exporter to be OTLP with HTTP transport.\nIf omitted, ignore.\n" - }, - "otlp_grpc": { - "$ref": "#/$defs/OtlpGrpcMetricExporter", - "description": "Configure exporter to be OTLP with gRPC transport.\nIf omitted, ignore.\n" - }, - "otlp_file/development": { - "$ref": "#/$defs/ExperimentalOtlpFileMetricExporter", - "description": "Configure exporter to be OTLP with file transport.\nIf omitted, ignore.\n" - }, - "console": { - "$ref": "#/$defs/ConsoleMetricExporter", - "description": "Configure exporter to be console.\nIf omitted, ignore.\n" - } - } - }, - "RandomIdGenerator": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "Resource": { - "type": "object", - "additionalProperties": false, - "properties": { - "attributes": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/AttributeNameValue" - }, - "description": "Configure resource attributes. Entries have higher priority than entries from .resource.attributes_list.\nIf omitted, no resource attributes are added.\n" - }, - "detection/development": { - "$ref": "#/$defs/ExperimentalResourceDetection", - "description": "Configure resource detection.\nIf omitted, resource detection is disabled.\n" - }, - "schema_url": { - "type": [ - "string", - "null" - ], - "description": "Configure resource schema URL.\nIf omitted or null, no schema URL is used.\n" - }, - "attributes_list": { - "type": [ - "string", - "null" - ], - "description": "Configure resource attributes. Entries have lower priority than entries from .resource.attributes.\nThe value is a list of comma separated key-value pairs matching the format of OTEL_RESOURCE_ATTRIBUTES. See https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#general-sdk-configuration for details.\nIf omitted or null, no resource attributes are added.\n" - } - } - }, - "Sampler": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "always_off": { - "$ref": "#/$defs/AlwaysOffSampler", - "description": "Configure sampler to be always_off.\nIf omitted, ignore.\n" - }, - "always_on": { - "$ref": "#/$defs/AlwaysOnSampler", - "description": "Configure sampler to be always_on.\nIf omitted, ignore.\n" - }, - "composite/development": { - "$ref": "#/$defs/ExperimentalComposableSampler", - "description": "Configure sampler to be composite.\nIf omitted, ignore.\n" - }, - "jaeger_remote/development": { - "$ref": "#/$defs/ExperimentalJaegerRemoteSampler", - "description": "Configure sampler to be jaeger_remote.\nIf omitted, ignore.\n" - }, - "parent_based": { - "$ref": "#/$defs/ParentBasedSampler", - "description": "Configure sampler to be parent_based.\nIf omitted, ignore.\n" - }, - "probability/development": { - "$ref": "#/$defs/ExperimentalProbabilitySampler", - "description": "Configure sampler to be probability.\nIf omitted, ignore.\n" - }, - "trace_id_ratio_based": { - "$ref": "#/$defs/TraceIdRatioBasedSampler", - "description": "Configure sampler to be trace_id_ratio_based.\nIf omitted, ignore.\n" - } - } - }, - "SeverityNumber": { - "type": [ - "string", - "null" - ], - "enum": [ - "trace", - "trace2", - "trace3", - "trace4", - "debug", - "debug2", - "debug3", - "debug4", - "info", - "info2", - "info3", - "info4", - "warn", - "warn2", - "warn3", - "warn4", - "error", - "error2", - "error3", - "error4", - "fatal", - "fatal2", - "fatal3", - "fatal4" - ] - }, - "SimpleLogRecordProcessor": { - "type": "object", - "additionalProperties": false, - "properties": { - "exporter": { - "$ref": "#/$defs/LogRecordExporter", - "description": "Configure exporter.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "exporter" - ] - }, - "SimpleSpanProcessor": { - "type": "object", - "additionalProperties": false, - "properties": { - "exporter": { - "$ref": "#/$defs/SpanExporter", - "description": "Configure exporter.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "exporter" - ] - }, - "SpanExporter": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "otlp_http": { - "$ref": "#/$defs/OtlpHttpExporter", - "description": "Configure exporter to be OTLP with HTTP transport.\nIf omitted, ignore.\n" - }, - "otlp_grpc": { - "$ref": "#/$defs/OtlpGrpcExporter", - "description": "Configure exporter to be OTLP with gRPC transport.\nIf omitted, ignore.\n" - }, - "otlp_file/development": { - "$ref": "#/$defs/ExperimentalOtlpFileExporter", - "description": "Configure exporter to be OTLP with file transport.\nIf omitted, ignore.\n" - }, - "console": { - "$ref": "#/$defs/ConsoleExporter", - "description": "Configure exporter to be console.\nIf omitted, ignore.\n" - } - } - }, - "SpanKind": { - "type": [ - "string", - "null" - ], - "enum": [ - "internal", - "server", - "client", - "producer", - "consumer" - ] - }, - "SpanLimits": { - "type": "object", - "additionalProperties": false, - "properties": { - "attribute_value_length_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attribute value size. Overrides .attribute_limits.attribute_value_length_limit. \nValue must be non-negative.\nIf omitted or null, there is no limit.\n" - }, - "attribute_count_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attribute count. Overrides .attribute_limits.attribute_count_limit. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" - }, - "event_count_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max span event count. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" - }, - "link_count_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max span link count. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" - }, - "event_attribute_count_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attributes per span event. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" - }, - "link_attribute_count_limit": { - "type": [ - "integer", - "null" - ], - "minimum": 0, - "description": "Configure max attributes per span link. \nValue must be non-negative.\nIf omitted or null, 128 is used.\n" - } - } - }, - "SpanProcessor": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "batch": { - "$ref": "#/$defs/BatchSpanProcessor", - "description": "Configure a batch span processor.\nIf omitted, ignore.\n" - }, - "simple": { - "$ref": "#/$defs/SimpleSpanProcessor", - "description": "Configure a simple span processor.\nIf omitted, ignore.\n" - } - } - }, - "SumAggregation": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "TextMapPropagator": { - "type": "object", - "additionalProperties": { - "type": [ - "object", - "null" - ] - }, - "minProperties": 1, - "maxProperties": 1, - "properties": { - "tracecontext": { - "$ref": "#/$defs/TraceContextPropagator", - "description": "Include the w3c trace context propagator.\nIf omitted, ignore.\n" - }, - "baggage": { - "$ref": "#/$defs/BaggagePropagator", - "description": "Include the w3c baggage propagator.\nIf omitted, ignore.\n" - }, - "b3": { - "$ref": "#/$defs/B3Propagator", - "description": "Include the zipkin b3 propagator.\nIf omitted, ignore.\n" - }, - "b3multi": { - "$ref": "#/$defs/B3MultiPropagator", - "description": "Include the zipkin b3 multi propagator.\nIf omitted, ignore.\n" - } - } - }, - "TraceContextPropagator": { - "type": [ - "object", - "null" - ], - "additionalProperties": false - }, - "TraceIdRatioBasedSampler": { - "type": [ - "object", - "null" - ], - "additionalProperties": false, - "properties": { - "ratio": { - "type": [ - "number", - "null" - ], - "minimum": 0, - "maximum": 1, - "description": "Configure trace_id_ratio.\nIf omitted or null, 1.0 is used.\n" - } - } - }, - "TracerProvider": { - "type": "object", - "additionalProperties": false, - "properties": { - "processors": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/$defs/SpanProcessor" - }, - "description": "Configure span processors.\nProperty is required and must be non-null.\n" - }, - "limits": { - "$ref": "#/$defs/SpanLimits", - "description": "Configure span limits. See also attribute_limits.\nIf omitted, default values as described in SpanLimits are used.\n" - }, - "sampler": { - "$ref": "#/$defs/Sampler", - "description": "Configure the sampler.\nIf omitted, parent based sampler with a root of always_on is used.\n" - }, - "id_generator": { - "$ref": "#/$defs/IdGenerator", - "description": "Configure the trace and span ID generator.\nIf omitted, RandomIdGenerator is used.\n" - }, - "tracer_configurator/development": { - "$ref": "#/$defs/ExperimentalTracerConfigurator", - "description": "Configure tracers.\nIf omitted, all tracers use default values as described in ExperimentalTracerConfig.\n" - } - }, - "required": [ - "processors" - ] - }, - "View": { - "type": "object", - "additionalProperties": false, - "properties": { - "selector": { - "$ref": "#/$defs/ViewSelector", - "description": "Configure view selector. \nSelection criteria is additive as described in https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#instrument-selection-criteria.\nProperty is required and must be non-null.\n" - }, - "stream": { - "$ref": "#/$defs/ViewStream", - "description": "Configure view stream.\nProperty is required and must be non-null.\n" - } - }, - "required": [ - "selector", - "stream" - ] - }, - "ViewSelector": { - "type": "object", - "additionalProperties": false, - "properties": { - "instrument_name": { - "type": [ - "string", - "null" - ], - "description": "Configure instrument name selection criteria.\nIf omitted or null, all instrument names match.\n" - }, - "instrument_type": { - "$ref": "#/$defs/InstrumentType", - "description": "Configure instrument type selection criteria.\nValues include:\n* counter: Synchronous counter instruments.\n* gauge: Synchronous gauge instruments.\n* histogram: Synchronous histogram instruments.\n* observable_counter: Asynchronous counter instruments.\n* observable_gauge: Asynchronous gauge instruments.\n* observable_up_down_counter: Asynchronous up down counter instruments.\n* up_down_counter: Synchronous up down counter instruments.\nIf omitted, all instrument types match.\n" - }, - "unit": { - "type": [ - "string", - "null" - ], - "description": "Configure the instrument unit selection criteria.\nIf omitted or null, all instrument units match.\n" - }, - "meter_name": { - "type": [ - "string", - "null" - ], - "description": "Configure meter name selection criteria.\nIf omitted or null, all meter names match.\n" - }, - "meter_version": { - "type": [ - "string", - "null" - ], - "description": "Configure meter version selection criteria.\nIf omitted or null, all meter versions match.\n" - }, - "meter_schema_url": { - "type": [ - "string", - "null" - ], - "description": "Configure meter schema url selection criteria.\nIf omitted or null, all meter schema URLs match.\n" - } - } - }, - "ViewStream": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": [ - "string", - "null" - ], - "description": "Configure metric name of the resulting stream(s).\nIf omitted or null, the instrument's original name is used.\n" - }, - "description": { - "type": [ - "string", - "null" - ], - "description": "Configure metric description of the resulting stream(s).\nIf omitted or null, the instrument's origin description is used.\n" - }, - "aggregation": { - "$ref": "#/$defs/Aggregation", - "description": "Configure aggregation of the resulting stream(s).\nIf omitted, default is used.\n" - }, - "aggregation_cardinality_limit": { - "type": [ - "integer", - "null" - ], - "exclusiveMinimum": 0, - "description": "Configure the aggregation cardinality limit.\nIf omitted or null, the metric reader's default cardinality limit is used.\n" - }, - "attribute_keys": { - "$ref": "#/$defs/IncludeExclude", - "description": "Configure attribute keys retained in the resulting stream(s).\nIf omitted, all attribute keys are retained.\n" - } - } - } - } -} \ No newline at end of file diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/configuration/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py deleted file mode 100644 index 7e96f7105d1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/__init__.py +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -import os -from contextvars import Token -from uuid import uuid4 - -# pylint: disable=wrong-import-position -from opentelemetry.agent._vendor.opentelemetry.context.context import Context, _RuntimeContext -from opentelemetry.agent._vendor.opentelemetry.context.contextvars_context import ContextVarsRuntimeContext -from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_CONTEXT - -logger = logging.getLogger(__name__) - - -def _load_runtime_context() -> _RuntimeContext: - """Initialize the RuntimeContext - - Returns: - An instance of RuntimeContext. - """ - configured_context = os.environ.get(OTEL_PYTHON_CONTEXT) - if not configured_context: - return ContextVarsRuntimeContext() - - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 - entry_points, - ) - - try: - return next(iter(entry_points(group="opentelemetry_context", name=configured_context))).load()() - except Exception: # pylint: disable=broad-exception-caught - logger.exception( - "Failed to load context: %s, falling back to contextvars_context", - configured_context, - ) - return ContextVarsRuntimeContext() - - -_RUNTIME_CONTEXT = _load_runtime_context() - - -def create_key(keyname: str) -> str: - """To allow cross-cutting concern to control access to their local state, - the RuntimeContext API provides a function which takes a keyname as input, - and returns a unique key. - Args: - keyname: The key name is for debugging purposes and is not required to be unique. - Returns: - A unique string representing the newly created key. - """ - return keyname + "-" + str(uuid4()) - - -def get_value(key: str, context: Context | None = None) -> object: - """To access the local state of a concern, the RuntimeContext API - provides a function which takes a context and a key as input, - and returns a value. - - Args: - key: The key of the value to retrieve. - context: The context from which to retrieve the value, if None, the current context is used. - - Returns: - The value associated with the key. - """ - return context.get(key) if context is not None else get_current().get(key) - - -def set_value(key: str, value: object, context: Context | None = None) -> Context: - """To record the local state of a cross-cutting concern, the - RuntimeContext API provides a function which takes a context, a - key, and a value as input, and returns an updated context - which contains the new value. - - Args: - key: The key of the entry to set. - value: The value of the entry to set. - context: The context to copy, if None, the current context is used. - - Returns: - A new `Context` containing the value set. - """ - if context is None: - context = get_current() - new_values = context.copy() - new_values[key] = value - return Context(new_values) - - -def get_current() -> Context: - """To access the context associated with program execution, - the Context API provides a function which takes no arguments - and returns a Context. - - Returns: - The current `Context` object. - """ - return _RUNTIME_CONTEXT.get_current() - - -def attach(context: Context) -> Token[Context]: - """Associates a Context with the caller's current execution unit. Returns - a token that can be used to restore the previous Context. - - Args: - context: The Context to set as current. - - Returns: - A token that can be used with `detach` to reset the context. - """ - return _RUNTIME_CONTEXT.attach(context) - - -def detach(token: Token[Context]) -> None: - """Resets the Context associated with the caller's current execution unit - to the value it had before attaching a specified Context. - - Args: - token: The Token that was returned by a previous call to attach a Context. - """ - try: - _RUNTIME_CONTEXT.detach(token) - except Exception: # pylint: disable=broad-exception-caught - logger.exception("Failed to detach context") - - -# FIXME This is a temporary location for the suppress instrumentation key. -# Once the decision around how to suppress instrumentation is made in the -# spec, this key should be moved accordingly. -_ON_EMIT_RECURSION_COUNT_KEY = create_key("on_emit_recursion_count") -_SUPPRESS_INSTRUMENTATION_KEY = create_key("suppress_instrumentation") -_SUPPRESS_HTTP_INSTRUMENTATION_KEY = create_key("suppress_http_instrumentation") - -__all__ = [ - "Context", - "attach", - "create_key", - "detach", - "get_current", - "get_value", - "set_value", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py deleted file mode 100644 index 984bf424d84..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/context.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from abc import ABC, abstractmethod -from contextvars import Token - - -class Context(dict[str, object]): - def __setitem__(self, key: str, value: object) -> None: - raise ValueError - - def __delitem__(self, key: str) -> None: - raise ValueError - - def setdefault(self, key: str, default: object = None) -> object: - raise ValueError - - def pop(self, key: str, *args: object) -> object: - raise ValueError - - def popitem(self) -> tuple[str, object]: - raise ValueError - - def clear(self) -> None: - raise ValueError - - def update(self, *args: object, **kwargs: object) -> None: - raise ValueError - - def __ior__(self, other: object) -> Context: - raise ValueError - - -class _RuntimeContext(ABC): - """The RuntimeContext interface provides a wrapper for the different - mechanisms that are used to propagate context in Python. - Implementations can be made available via entry_points and - selected through environment variables. - """ - - @abstractmethod - def attach(self, context: Context) -> Token[Context]: - """Sets the current `Context` object. Returns a - token that can be used to reset to the previous `Context`. - - Args: - context: The Context to set. - """ - - @abstractmethod - def get_current(self) -> Context: - """Returns the current `Context` object.""" - - @abstractmethod - def detach(self, token: Token[Context]) -> None: - """Resets Context to a previous value - - Args: - token: A reference to a previous Context. - """ - - -__all__ = ["Context"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py deleted file mode 100644 index 923cc2dfc9e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/context/contextvars_context.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from contextvars import ContextVar, Token - -from opentelemetry.agent._vendor.opentelemetry.context.context import Context, _RuntimeContext - - -class ContextVarsRuntimeContext(_RuntimeContext): - """An implementation of the RuntimeContext interface which wraps ContextVar under - the hood. This is the preferred implementation for usage with Python 3.5+ - """ - - _CONTEXT_KEY = "current_context" - - def __init__(self) -> None: - self._current_context = ContextVar(self._CONTEXT_KEY, default=Context()) - - def attach(self, context: Context) -> Token[Context]: - """Sets the current `Context` object. Returns a - token that can be used to reset to the previous `Context`. - - Args: - context: The Context to set. - """ - return self._current_context.set(context) - - def get_current(self) -> Context: - """Returns the current `Context` object.""" - return self._current_context.get() - - def detach(self, token: Token[Context]) -> None: - """Resets Context to a previous value - - Args: - token: A reference to a previous Context. - """ - self._current_context.reset(token) - - -__all__ = ["ContextVarsRuntimeContext"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py deleted file mode 100644 index 6165e7a93da..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import os - -from opentelemetry.agent._vendor.opentelemetry.environment_variables import ( - OTEL_LOGS_EXPORTER, - OTEL_METRICS_EXPORTER, - OTEL_TRACES_EXPORTER, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.distro import BaseDistro -from opentelemetry.agent._vendor.opentelemetry.sdk._configuration import _OTelSDKConfigurator -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_PROTOCOL - - -class OpenTelemetryConfigurator(_OTelSDKConfigurator): - pass - - -class OpenTelemetryDistro(BaseDistro): - """ - The OpenTelemetry provided Distro configures a default set of - configuration out of the box. - """ - - # pylint: disable=no-self-use - def _configure(self, **kwargs): - os.environ.setdefault(OTEL_TRACES_EXPORTER, "otlp") - os.environ.setdefault(OTEL_METRICS_EXPORTER, "otlp") - os.environ.setdefault(OTEL_LOGS_EXPORTER, "otlp") - # opentelemetry-agent: the gRPC exporters aren't vendored (grpcio has no pure-Python wheel). - os.environ.setdefault(OTEL_EXPORTER_OTLP_PROTOCOL, "http/protobuf") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/distro/version.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py deleted file mode 100644 index b335c826380..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/environment_variables/__init__.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -OTEL_LOGS_EXPORTER = "OTEL_LOGS_EXPORTER" -""" -.. envvar:: OTEL_LOGS_EXPORTER - -""" - -OTEL_METRICS_EXPORTER = "OTEL_METRICS_EXPORTER" -""" -.. envvar:: OTEL_METRICS_EXPORTER - -Specifies which exporter is used for metrics. See `General SDK Configuration -`_. - -**Default value:** ``"otlp"`` - -**Example:** - -``export OTEL_METRICS_EXPORTER="prometheus"`` - -Accepted values for ``OTEL_METRICS_EXPORTER`` are: - -- ``"otlp"`` -- ``"prometheus"`` -- ``"none"``: No automatically configured exporter for metrics. - -.. note:: - - Exporter packages may add entry points for group ``opentelemetry_metrics_exporter`` which - can then be used with this environment variable by name. The entry point should point to - either a `opentelemetry.sdk.metrics.export.MetricExporter` (push exporter) or - `opentelemetry.sdk.metrics.export.MetricReader` (pull exporter) subclass; it must be - constructable without any required arguments. This mechanism is considered experimental and - may change in subsequent releases. -""" - -OTEL_PROPAGATORS = "OTEL_PROPAGATORS" -""" -.. envvar:: OTEL_PROPAGATORS -""" - -OTEL_PYTHON_CONTEXT = "OTEL_PYTHON_CONTEXT" -""" -.. envvar:: OTEL_PYTHON_CONTEXT -""" - -OTEL_PYTHON_ID_GENERATOR = "OTEL_PYTHON_ID_GENERATOR" -""" -.. envvar:: OTEL_PYTHON_ID_GENERATOR -""" - -OTEL_TRACES_EXPORTER = "OTEL_TRACES_EXPORTER" -""" -.. envvar:: OTEL_TRACES_EXPORTER -""" - -OTEL_PYTHON_TRACER_PROVIDER = "OTEL_PYTHON_TRACER_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_TRACER_PROVIDER -""" - -OTEL_PYTHON_METER_PROVIDER = "OTEL_PYTHON_METER_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_METER_PROVIDER -""" - -_OTEL_PYTHON_LOGGER_PROVIDER = "OTEL_PYTHON_LOGGER_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_LOGGER_PROVIDER -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py deleted file mode 100644 index 72af79e9752..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/__init__.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from typing import TYPE_CHECKING, cast - -# pylint: disable-next=import-error -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._requests import ( - RequestsHTTPTransport as _RequestsHTTPTransport, -) - -# pylint: disable-next=import-error -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._urllib3 import ( - Urllib3HTTPTransport as _Urllib3HTTPTransport, -) - -if TYPE_CHECKING: - from typing import Any, Protocol - - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport - - class BaseHTTPTransportFactory(Protocol): - def __call__( - self, - *, - verify: bool | str, - cert: str | tuple[str, str] | None, - **kwargs: Any, - ) -> BaseHTTPTransport: ... - - -_KNOWN_TRANSPORTS: dict[str, BaseHTTPTransportFactory] = { - "requests": _RequestsHTTPTransport, - "urllib3": _Urllib3HTTPTransport, -} - - -def _load_http_transport_factory(name: str) -> BaseHTTPTransportFactory: - """Return the transport factory registered under *name*. - - Checks the built-in transport registry first to avoid the overhead of an - entry-point scan for built-in transports. Falls back to standard entry-point - discovery for user supplied transports registered under the - ``opentelemetry_http_transport`` group. - - :param name: Entry point name, e.g. ``"requests"`` or ``"urllib3"``. - :returns: A callable with signature - ``(*, verify, cert, **kwargs) -> BaseHTTPTransport``. - :raises ValueError: If no transport is registered under *name*. - :raises TypeError: If the loaded entry point is not callable. - """ - if name in _KNOWN_TRANSPORTS: - return _KNOWN_TRANSPORTS[name] - # pylint: disable-next=import-outside-toplevel,import-error - from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 - entry_points, - ) - - ep = next( - iter(entry_points(group="opentelemetry_http_transport", name=name)), - None, - ) - if not ep: - raise ValueError( - f"No HTTP transport registered under name {name!r}. " - "Install the corresponding extra or register an entry point " - "under the 'opentelemetry_http_transport' group." - ) - factory = ep.load() - if not callable(factory): - raise TypeError(f"Transport {name!r} loaded from entry point is not callable (got {factory!r}).") - return cast("BaseHTTPTransportFactory", factory) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py deleted file mode 100644 index 74b7976a5d0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_base.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import json -from abc import ABC, abstractmethod -from dataclasses import dataclass -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from collections.abc import Mapping - from typing import Any - - -@dataclass(frozen=True, slots=True) -class BaseHTTPResult(ABC): - """Outcome of a single HTTP request made by a :class:`BaseHTTPTransport`. - - Either ``status_code`` and ``reason`` are populated (server responded), - or ``error`` is set (request failed before a response was received). - """ - - status_code: int | None = None - reason: str | None = None - error: Exception | None = None - - @abstractmethod - def content(self) -> bytes: - """Return the raw response body. - - Implementations may raise an exception if the returned content is malformed. - """ - - @abstractmethod - def headers(self) -> Mapping[str, str]: - """Return the response headers. - - The returned mapping MUST be case-insensitive with respect to header - keys. Headers with multiple values are represented as a single string - of comma separated values. - - Implementations may raise an exception if the returned headers are malformed. - """ - - def text(self) -> str: - """Return the response body decoded as UTF-8. - - Implementations may raise an exception if the returned string is malformed. - """ - return self.content().decode("utf-8") - - def json(self) -> Any: - """Return the response body parsed as JSON. - - Implementations may raise an exception if no response content - is available or the returned JSON is malformed. - """ - return json.loads(self.text()) - - -class BaseHTTPTransport(ABC): - """Abstract HTTP transport interface used by HTTP exporters.""" - - @abstractmethod - def request( - self, - method: str, - url: str, - *, - headers: dict[str, str] | None = None, - timeout: float | None = None, - data: bytes | None = None, - ) -> BaseHTTPResult: - """Send an HTTP request and return the result. - - :param method: HTTP method (e.g. ``"POST"``). - :param url: Target URL. - :param headers: Optional HTTP headers to include in the request. - :param timeout: Optional request timeout in seconds. - :param data: Optional request body. - :returns: A :class:`BaseHTTPResult` describing the outcome. - """ - - @abstractmethod - def close(self) -> None: - """Release any resources held by the transport.""" - - @abstractmethod - def is_connection_error(self, exception: Exception | None) -> bool: - """Return ``True`` if the exception is a transport-level connection error.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py deleted file mode 100644 index 90e6cb314df..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_requests.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import functools -from dataclasses import dataclass, field -from typing import TYPE_CHECKING - -# pylint: disable-next=import-error -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import ( - BaseHTTPResult, - BaseHTTPTransport, -) - -if TYPE_CHECKING: - from collections.abc import Mapping - from typing import Any - - from opentelemetry.agent._vendor import requests - from opentelemetry.agent._vendor.requests import Response - - -@functools.cache -def _get_connection_error_types() -> tuple[type[Exception], ...]: - # pylint: disable-next=import-outside-toplevel - import opentelemetry.agent._vendor.requests.exceptions - from opentelemetry.agent._vendor import requests - from opentelemetry.agent._vendor import opentelemetry # noqa: PLC0415 - - return ( - requests.exceptions.ConnectionError, - requests.exceptions.ConnectTimeout, - requests.exceptions.ReadTimeout, - requests.exceptions.Timeout, - requests.exceptions.SSLError, - requests.exceptions.ProxyError, - ) - - -@dataclass(frozen=True, slots=True) -class RequestsHTTPResult(BaseHTTPResult): - response: Response | None = field(default=None, hash=False, compare=False) - - def content(self) -> bytes: - if self.response is None: - return b"" - return self.response.content or b"" - - def text(self) -> str: - if self.response is None: - return "" - return self.response.text or "" - - def json(self) -> Any: - if self.response is None: - raise ValueError("No response available.") - return self.response.json() - - def headers(self) -> Mapping[str, str]: - if self.response is None: - return {} - return self.response.headers - - -class RequestsHTTPTransport(BaseHTTPTransport): - def __init__( - self, - *, - verify: bool | str = True, - cert: str | tuple[str, str] | None = None, - session: requests.Session | None = None, - **kwargs: Any, - ) -> None: - # pylint: disable-next=import-outside-toplevel - from opentelemetry.agent._vendor import requests # noqa: PLC0415 - - self._session = session if session is not None else requests.Session() - self._session.verify = verify - if cert is not None: - self._session.cert = cert - - def request( - self, - method: str, - url: str, - *, - headers: dict[str, str] | None = None, - timeout: float | None = None, - data: bytes | None = None, - ) -> BaseHTTPResult: - try: - response = self._session.request( - method=method, - url=url, - headers=headers, - data=data, - timeout=timeout, - allow_redirects=False, - ) - # pylint: disable-next=broad-exception-caught - except Exception as error: - # pylint: disable-next=unexpected-keyword-arg - return RequestsHTTPResult(error=error) - - # pylint: disable-next=unexpected-keyword-arg - return RequestsHTTPResult( - status_code=response.status_code, - reason=response.reason, - response=response, - ) - - # pylint: disable-next=no-self-use - def is_connection_error(self, exception: Exception | None) -> bool: - return isinstance(exception, _get_connection_error_types()) - - def close(self) -> None: - self._session.close() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py deleted file mode 100644 index 6213b653791..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/_urllib3.py +++ /dev/null @@ -1,133 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import functools -import json -from dataclasses import dataclass, field -from typing import TYPE_CHECKING - -# pylint: disable-next=import-error -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import ( - BaseHTTPResult, - BaseHTTPTransport, -) - -if TYPE_CHECKING: - from collections.abc import Mapping - from typing import Any - - from opentelemetry.agent._vendor.urllib3 import BaseHTTPResponse - - -@functools.cache -def _get_connection_error_types() -> tuple[type[Exception], ...]: - # pylint: disable-next=import-outside-toplevel - import opentelemetry.agent._vendor.urllib3.exceptions - from opentelemetry.agent._vendor import urllib3 - from opentelemetry.agent._vendor import opentelemetry # noqa: PLC0415 - - types: list[type[Exception]] = [ - urllib3.exceptions.ConnectionError, - urllib3.exceptions.NewConnectionError, - urllib3.exceptions.ConnectTimeoutError, - urllib3.exceptions.MaxRetryError, - urllib3.exceptions.ProtocolError, - ] - - # NameResolutionError was added in urllib3 2.0 - name_resolution_error = getattr(urllib3.exceptions, "NameResolutionError", None) - if name_resolution_error is not None: - types.append(name_resolution_error) - - return tuple(types) - - -@dataclass(frozen=True, slots=True) -class Urllib3HTTPResult(BaseHTTPResult): - response: BaseHTTPResponse | None = field(default=None, hash=False, compare=False) - - def content(self) -> bytes: - if self.response is None: - return b"" - return self.response.data or b"" - - def headers(self) -> Mapping[str, str]: - if self.response is None: - return {} - return self.response.headers - - def json(self) -> Any: - if self.response is None: - raise ValueError("No response available.") - return json.loads(self.content()) - - -class Urllib3HTTPTransport(BaseHTTPTransport): - def __init__( - self, - *, - verify: bool | str = True, - cert: str | tuple[str, str] | None = None, - **kwargs: Any, - ) -> None: - # pylint: disable-next=import-outside-toplevel - from opentelemetry.agent._vendor import urllib3 # noqa: PLC0415 - - pool_kwargs: dict[str, object] = { - "retries": urllib3.Retry(0, redirect=False), - } - if verify is False: - pool_kwargs["cert_reqs"] = "CERT_NONE" - else: - pool_kwargs["cert_reqs"] = "CERT_REQUIRED" - if isinstance(verify, str): - pool_kwargs["ca_certs"] = verify - if isinstance(cert, tuple): - pool_kwargs["cert_file"] = cert[0] - pool_kwargs["key_file"] = cert[1] - elif isinstance(cert, str): - pool_kwargs["cert_file"] = cert - - self._pool = urllib3.PoolManager(**pool_kwargs) # type: ignore - - def request( - self, - method: str, - url: str, - *, - headers: dict[str, str] | None = None, - timeout: float | None = None, - data: bytes | None = None, - ) -> BaseHTTPResult: - # pylint: disable-next=import-outside-toplevel - from opentelemetry.agent._vendor import urllib3 # noqa: PLC0415 - - try: - response = self._pool.request( - method=method, - url=url, - headers=headers, - body=data, - timeout=urllib3.Timeout(total=timeout) if timeout is not None else None, - preload_content=True, - ) - # pylint: disable-next=broad-exception-caught - except Exception as error: - # pylint: disable-next=unexpected-keyword-arg - return Urllib3HTTPResult(error=error) - - # pylint: disable-next=unexpected-keyword-arg - return Urllib3HTTPResult( - status_code=response.status, - reason=response.reason, - response=response, - ) - - # pylint: disable-next=no-self-use - def is_connection_error(self, exception: Exception | None) -> bool: - return isinstance(exception, _get_connection_error_types()) - - def close(self) -> None: - self._pool.clear() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/http/transport/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py deleted file mode 100644 index e57cf4aba95..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py deleted file mode 100644 index 74e52f456b8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_aggregation.py +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -import os - -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( - Counter, - Histogram, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - UpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import AggregationTemporality -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import ( - Aggregation, - ExplicitBucketHistogramAggregation, - ExponentialBucketHistogramAggregation, -) - -_logger = logging.getLogger(__name__) - - -def _get_temporality( - preferred_temporality: dict[type, AggregationTemporality] | None, -) -> dict[type, AggregationTemporality]: - temporality_preference = ( - os.environ.get( - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, - "CUMULATIVE", - ) - .upper() - .strip() - ) - - instrument_class_temporality: dict[type, AggregationTemporality] - match temporality_preference: - case "DELTA": - instrument_class_temporality = { - Counter: AggregationTemporality.DELTA, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.DELTA, - ObservableCounter: AggregationTemporality.DELTA, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - case "LOWMEMORY": - instrument_class_temporality = { - Counter: AggregationTemporality.DELTA, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.DELTA, - ObservableCounter: AggregationTemporality.CUMULATIVE, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - case _: - if temporality_preference != "CUMULATIVE": - _logger.warning( - ("Invalid value for %s: %s, using cumulative temporality aggregation"), - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, - temporality_preference, - ) - instrument_class_temporality = { - Counter: AggregationTemporality.CUMULATIVE, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.CUMULATIVE, - ObservableCounter: AggregationTemporality.CUMULATIVE, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - - return instrument_class_temporality | (preferred_temporality or {}) - - -def _get_aggregation( - preferred_aggregation: dict[type, Aggregation] | None, -) -> dict[type, Aggregation]: - default_histogram_aggregation = ( - os.environ.get( - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, - "explicit_bucket_histogram", - ) - .upper() - .strip() - ) - - instrument_class_aggregation: dict[type, Aggregation] - match default_histogram_aggregation: - case "BASE2_EXPONENTIAL_BUCKET_HISTOGRAM": - instrument_class_aggregation = { - Histogram: ExponentialBucketHistogramAggregation(), - } - case _: - if default_histogram_aggregation != "EXPLICIT_BUCKET_HISTOGRAM": - _logger.warning( - ("Invalid value for %s: %s, using explicit bucket histogram aggregation"), - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, - default_histogram_aggregation, - ) - - instrument_class_aggregation = { - Histogram: ExplicitBucketHistogramAggregation(), - } - - return instrument_class_aggregation | (preferred_aggregation or {}) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py deleted file mode 100644 index 8d4029b539d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/_exporter_metrics.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections import Counter -from collections.abc import Iterator -from contextlib import AbstractContextManager, contextmanager -from dataclasses import dataclass -from time import perf_counter -from typing import TYPE_CHECKING, Protocol -from urllib.parse import urlparse - -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OTEL_COMPONENT_NAME, - OTEL_COMPONENT_TYPE, - OtelComponentTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( - create_otel_sdk_exporter_log_exported, - create_otel_sdk_exporter_log_inflight, - create_otel_sdk_exporter_metric_data_point_exported, - create_otel_sdk_exporter_metric_data_point_inflight, - create_otel_sdk_exporter_operation_duration, - create_otel_sdk_exporter_span_exported, - create_otel_sdk_exporter_span_inflight, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.server_attributes import ( - SERVER_ADDRESS, - SERVER_PORT, -) - -if TYPE_CHECKING: - from typing import Literal - - from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes - -_component_counter = Counter() - -_GRPC_COMPONENT_TYPES = frozenset( - { - OtelComponentTypeValues.OTLP_GRPC_SPAN_EXPORTER, - OtelComponentTypeValues.OTLP_GRPC_LOG_EXPORTER, - OtelComponentTypeValues.OTLP_GRPC_METRIC_EXPORTER, - } -) - - -@dataclass -class ExportResult: - error: Exception | None = None - error_attrs: Attributes = None - - -class ExporterMetricsT(Protocol): - def export_operation(self, num_items: int) -> AbstractContextManager[ExportResult]: ... - - -class NoOpExporterMetrics: - @contextmanager - # pylint: disable-next=no-self-use - def export_operation(self, num_items: int) -> Iterator[ExportResult]: - yield ExportResult() - - -class ExporterMetrics: - def __init__( - self, - component_type: OtelComponentTypeValues | None, - signal: Literal["traces", "metrics", "logs"], - endpoint: str, - meter_provider: MeterProvider | None, - ) -> None: - if signal == "traces": - create_exported = create_otel_sdk_exporter_span_exported - create_inflight = create_otel_sdk_exporter_span_inflight - elif signal == "logs": - create_exported = create_otel_sdk_exporter_log_exported - create_inflight = create_otel_sdk_exporter_log_inflight - else: - create_exported = create_otel_sdk_exporter_metric_data_point_exported - create_inflight = create_otel_sdk_exporter_metric_data_point_inflight - - if not endpoint.startswith("//") and "://" not in endpoint: - endpoint = f"//{endpoint}" - parsed_endpoint = urlparse(endpoint) - - port = parsed_endpoint.port - if port is None: - if component_type in _GRPC_COMPONENT_TYPES or parsed_endpoint.scheme == "https": - port = 443 - elif parsed_endpoint.scheme == "http": - port = 80 - - component_type_value = component_type.value if component_type else "unknown_otlp_exporter" - count = _component_counter[component_type_value] - _component_counter[component_type_value] = count + 1 - self._standard_attrs: dict[str, AnyValue] = { - OTEL_COMPONENT_TYPE: component_type_value, - OTEL_COMPONENT_NAME: f"{component_type_value}/{count}", - } - if parsed_endpoint.hostname: - self._standard_attrs[SERVER_ADDRESS] = parsed_endpoint.hostname - if port is not None: - self._standard_attrs[SERVER_PORT] = port - - meter_provider = meter_provider or get_meter_provider() - meter = meter_provider.get_meter("opentelemetry-sdk") - self._inflight = create_inflight(meter) - self._exported = create_exported(meter) - self._duration = create_otel_sdk_exporter_operation_duration(meter) - - @contextmanager - def export_operation(self, num_items: int) -> Iterator[ExportResult]: - start_time = perf_counter() - self._inflight.add(num_items, self._standard_attrs) - - result = ExportResult() - try: - yield result - finally: - error = result.error - error_attrs = result.error_attrs - - end_time = perf_counter() - self._inflight.add(-num_items, self._standard_attrs) - exported_attrs = ( - {**self._standard_attrs, ERROR_TYPE: type(error).__qualname__} if error else self._standard_attrs - ) - self._exported.add(num_items, exported_attrs) - duration_attrs = {**exported_attrs, **error_attrs} if error_attrs else exported_attrs - self._duration.record(end_time - start_time, duration_attrs) - - -def create_exporter_metrics( - component_type: OtelComponentTypeValues | None, - signal: Literal["traces", "metrics", "logs"], - endpoint: str, - meter_provider: MeterProvider | None, - enabled: bool, -) -> ExporterMetricsT: - if not enabled: - return NoOpExporterMetrics() - - return ExporterMetrics( - component_type, - signal, - endpoint, - meter_provider, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py deleted file mode 100644 index 1904c22ba3c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/http.py +++ /dev/null @@ -1,248 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import enum -import gzip -import logging -import math -import random -import threading -import time -import zlib -from collections.abc import Mapping -from dataclasses import dataclass -from datetime import timezone -from email.utils import parsedate_to_datetime -from http import HTTPStatus -from io import BytesIO -from typing import TYPE_CHECKING, Final, Literal - -if TYPE_CHECKING: - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import ( - BaseHTTPResult, - BaseHTTPTransport, - ) - -_logger = logging.getLogger(__name__) - -_MAX_RETRIES: Final[int] = 6 -_DEFAULT_TIMEOUT: Final[float] = 10.0 -_DEFAULT_JITTER: Final[float] = 0.2 - - -_RETRYABLE_STATUS_CODES: Final[frozenset[int]] = frozenset( - { - HTTPStatus.TOO_MANY_REQUESTS.value, - HTTPStatus.BAD_GATEWAY.value, - HTTPStatus.SERVICE_UNAVAILABLE.value, - HTTPStatus.GATEWAY_TIMEOUT.value, - } -) - - -def _is_retryable(status_code: int | None) -> bool: - return status_code in _RETRYABLE_STATUS_CODES - - -def _extract_retry_after(result: BaseHTTPResult) -> float | None: - """Parse the ``Retry-After`` header (RFC 7231).""" - try: - value = result.headers().get("retry-after") - # pylint: disable-next=broad-exception-caught - except Exception: - return None - if value is None: - return None - value = value.strip() - - # delay-seconds: a non-negative decimal integer. - try: - seconds = float(value) - except ValueError: - pass - else: - return max(seconds, 0.0) if math.isfinite(seconds) else None - - # HTTP-date: wait until the indicated absolute time. - try: - retry_at = parsedate_to_datetime(value) - except (TypeError, ValueError): - return None - if retry_at.tzinfo is None: - retry_at = retry_at.replace(tzinfo=timezone.utc) - return max(retry_at.timestamp() - time.time(), 0.0) - - -class Compression(enum.Enum): - NONE = "none" - DEFLATE = "deflate" - GZIP = "gzip" - - @staticmethod - def from_str(value: str) -> Compression: - match value.strip().lower(): - case "none": - return Compression.NONE - case "deflate": - return Compression.DEFLATE - case "gzip": - return Compression.GZIP - case _: - raise ValueError(f"Invalid compression type: {value!r}. Expected one of: 'none', 'deflate', 'gzip'.") - - -@dataclass(slots=True, frozen=True) -class _ExportResult: - """Outcome of an OTLP export attempt, including retry exhaustion.""" - - success: bool - status_code: int | None - reason: str | None - error: Exception | None - - -class _OTLPHTTPClient: - """Sends serialized OTLP payloads over HTTP with retry logic. - - Compression, backoff, and connection-error recovery are handled internally. - Callers interact through the :meth:`export` and :meth:`close` methods. - """ - - def __init__( - self, - transport: BaseHTTPTransport, - endpoint: str, - kind: Literal["spans", "logs", "metrics"], - timeout: float = _DEFAULT_TIMEOUT, - compression: Compression = Compression.NONE, - headers: Mapping[str, str] | None = None, - jitter: float = _DEFAULT_JITTER, - logger: logging.Logger | None = None, - ) -> None: - self._transport = transport - self._endpoint = endpoint - self._timeout = timeout - self._compression = compression - self._headers = dict(headers) if headers is not None else {} - if self._compression is not Compression.NONE and not any( - key.lower() == "content-encoding" for key in self._headers - ): - self._headers["Content-Encoding"] = self._compression.value - self._kind = kind - self._jitter = min(max(jitter, 0.0), 1.0) - self._logger = logger if logger is not None else _logger - self._shutdown = False - self._shutdown_event = threading.Event() - - def _compute_backoff(self, retry: int) -> float: - return 2**retry * random.uniform(1 - self._jitter, 1 + self._jitter) - - def _compress(self, serialized_data: bytes) -> bytes: - if self._compression is Compression.GZIP: - buf = BytesIO() - with gzip.GzipFile(fileobj=buf, mode="w") as gz: - gz.write(serialized_data) - return buf.getvalue() - if self._compression is Compression.DEFLATE: - return zlib.compress(serialized_data) - return serialized_data - - def _submit(self, data: bytes, timeout: float) -> BaseHTTPResult: - deadline = time.time() + timeout - result = self._transport.request( - "POST", - self._endpoint, - headers=self._headers, - data=data, - timeout=timeout, - ) - if ( - result.error is not None - and self._transport.is_connection_error(result.error) - and (remaining := deadline - time.time()) > 0 - ): - # Immediately retry connection errors once without backoff. These - # usually indicate a stale pooled connection that the transport will - # reestablish on the next attempt. - result = self._transport.request( - "POST", - self._endpoint, - headers=self._headers, - data=data, - timeout=remaining, - ) - return result - - def export(self, data: bytes) -> _ExportResult: - """Export a serialized payload, retrying on transient failures. - - :param data: Serialized bytes to send. - :returns: An :class:`ExportResult` indicating success or the reason for failure. - """ - data = self._compress(data) - deadline = time.time() + self._timeout - - for retry in range(_MAX_RETRIES): - backoff = self._compute_backoff(retry) - status_code: int | None = None - reason: str | None = None - export_error: Exception | None - retryable: bool - - try: - result = self._submit(data, max(deadline - time.time(), 0.0)) - # pylint: disable-next=broad-exception-caught - except Exception as error: - export_error = error - retryable = False - else: - status_code = result.status_code - reason = result.reason - if status_code is not None and 200 <= status_code < 400: - return _ExportResult(True, status_code, reason, None) - export_error = result.error - retryable = ( - _is_retryable(status_code) if status_code else self._transport.is_connection_error(result.error) - ) - if retryable and status_code is not None and (retry_after := _extract_retry_after(result)) is not None: - backoff = retry_after - - if not retryable: - self._logger.error( - "Failed to export %s batch code: %s, reason: %s", - self._kind, - status_code, - reason or export_error or "unknown", - ) - return _ExportResult(False, status_code, reason, export_error) - - if retry + 1 == _MAX_RETRIES or backoff > (deadline - time.time()) or self._shutdown_event.is_set(): - self._logger.error( - "Failed to export %s batch due to timeout, max retries or shutdown.", - self._kind, - ) - return _ExportResult(False, status_code, reason, export_error) - - self._logger.warning( - "Transient error %s encountered while exporting %s batch, retrying in %.2fs.", - reason or export_error, - self._kind, - backoff, - ) - shutdown = self._shutdown_event.wait(backoff) - if shutdown: - self._logger.warning("Shutdown in progress, aborting retry.") - break - - return _ExportResult(False, None, None, None) - - def shutdown(self) -> None: - """Shutdown the client.""" - if self._shutdown: - self._logger.warning("OTLP client already shutdown, ignoring call") - return - self._shutdown = True - self._shutdown_event.set() - self._transport.close() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/common/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py deleted file mode 100644 index e57cf4aba95..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py deleted file mode 100644 index cf1ca13c262..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/__init__.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pyright: reportCallIssue=false - -from __future__ import annotations - -import logging -from collections.abc import Mapping, Sequence -from typing import Any - -from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import AnyValue as JSONAnyValue -from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import ( - ArrayValue as JSONArrayValue, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import ( - InstrumentationScope as JSONInstrumentationScope, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import KeyValue as JSONKeyValue -from opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common import ( - KeyValueList as JSONKeyValueList, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource import ( - Resource as JSONResource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -_logger = logging.getLogger(__name__) - - -def _encode_instrumentation_scope( - instrumentation_scope: InstrumentationScope | None, -) -> JSONInstrumentationScope: - return ( - JSONInstrumentationScope( - name=instrumentation_scope.name, - version=instrumentation_scope.version, - attributes=_encode_attributes(instrumentation_scope.attributes), - ) - if instrumentation_scope is not None - else JSONInstrumentationScope() - ) - - -def _encode_resource(resource: Resource) -> JSONResource: - return JSONResource(attributes=_encode_attributes(resource.attributes)) - - -# pylint: disable-next=too-many-return-statements -def _encode_value(value: Any) -> JSONAnyValue: - if value is None: - return JSONAnyValue() - if isinstance(value, bool): - return JSONAnyValue(bool_value=value) - if isinstance(value, str): - return JSONAnyValue(string_value=value) - if isinstance(value, int): - return JSONAnyValue(int_value=value) - if isinstance(value, float): - return JSONAnyValue(double_value=value) - if isinstance(value, bytes): - return JSONAnyValue(bytes_value=value) - if isinstance(value, Sequence): - return JSONAnyValue(array_value=JSONArrayValue(values=[_encode_value(v) for v in value])) - if isinstance(value, Mapping): - return JSONAnyValue( - kvlist_value=JSONKeyValueList(values=[_encode_key_value(str(k), v) for k, v in value.items()]) - ) - raise TypeError(f"Invalid type {type(value)} of value {value}") - - -def _encode_key_value(key: str, value: Any) -> JSONKeyValue: - return JSONKeyValue(key=key, value=_encode_value(value)) - - -def _encode_span_id(span_id: int) -> bytes: - return span_id.to_bytes(length=8, byteorder="big", signed=False) - - -def _encode_trace_id(trace_id: int) -> bytes: - return trace_id.to_bytes(length=16, byteorder="big", signed=False) - - -def _encode_attributes( - attributes: Attributes, -) -> list[JSONKeyValue]: - if not attributes: - return [] - json_attributes = [] - for key, value in attributes.items(): - # pylint: disable=broad-exception-caught - try: - json_attributes.append(_encode_key_value(key, value)) - except Exception as error: - _logger.exception("Failed to encode key %s: %s", key, error) - return json_attributes diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py deleted file mode 100644 index 5aa5f9a7d16..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pyright: reportCallIssue=false - -from __future__ import annotations - -from collections import defaultdict -from collections.abc import Collection -from typing import cast - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal import ( - _encode_attributes, - _encode_instrumentation_scope, - _encode_resource, - _encode_span_id, - _encode_trace_id, - _encode_value, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.collector.logs.v1.logs_service import ( - ExportLogsServiceRequest as JSONExportLogsServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs import LogRecord as JSONLogRecord -from opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs import ( - ResourceLogs as JSONResourceLogs, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs import ( - ScopeLogs as JSONScopeLogs, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - - -def encode_logs( - batch: Collection[ReadableLogRecord], -) -> JSONExportLogsServiceRequest: - return JSONExportLogsServiceRequest(resource_logs=_encode_resource_logs(batch)) - - -def _encode_log(readable_log_record: ReadableLogRecord) -> JSONLogRecord: - return JSONLogRecord( - time_unix_nano=readable_log_record.log_record.timestamp, - observed_time_unix_nano=readable_log_record.log_record.observed_timestamp, - span_id=_encode_span_id(readable_log_record.log_record.span_id) - if readable_log_record.log_record.span_id - else None, - trace_id=_encode_trace_id(readable_log_record.log_record.trace_id) - if readable_log_record.log_record.trace_id - else None, - flags=int(readable_log_record.log_record.trace_flags), - body=_encode_value(readable_log_record.log_record.body), - severity_text=readable_log_record.log_record.severity_text, - attributes=_encode_attributes(cast(Attributes, readable_log_record.log_record.attributes)), - dropped_attributes_count=readable_log_record.dropped_attributes, - severity_number=getattr(readable_log_record.log_record.severity_number, "value", None), - event_name=readable_log_record.log_record.event_name, - ) - - -def _encode_resource_logs( - batch: Collection[ReadableLogRecord], -) -> list[JSONResourceLogs]: - sdk_resource_logs = defaultdict(lambda: defaultdict(list)) - - for readable_log in batch: - sdk_resource = readable_log.resource - sdk_instrumentation = readable_log.instrumentation_scope or None - sdk_resource_logs[sdk_resource][sdk_instrumentation].append(_encode_log(readable_log)) - - json_resource_logs = [] - for sdk_resource, sdk_instrumentations in sdk_resource_logs.items(): - scope_logs = [] - for sdk_instrumentation, json_logs in sdk_instrumentations.items(): - scope_logs.append( - JSONScopeLogs( - scope=(_encode_instrumentation_scope(sdk_instrumentation)), - log_records=json_logs, - schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, - ) - ) - json_resource_logs.append( - JSONResourceLogs( - resource=_encode_resource(sdk_resource), - scope_logs=scope_logs, - schema_url=sdk_resource.schema_url, - ) - ) - - return json_resource_logs diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py deleted file mode 100644 index 2e718a53f6d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py +++ /dev/null @@ -1,372 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# type: ignore[reportArgumentType] -# pyright: reportCallIssue=false - -from __future__ import annotations - -import logging -from collections.abc import Collection, Iterable -from dataclasses import replace -from typing import TYPE_CHECKING - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal import ( - _encode_attributes, - _encode_instrumentation_scope, - _encode_span_id, - _encode_trace_id, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.collector.metrics.v1.metrics_service import ( - ExportMetricsServiceRequest as JSONExportMetricsServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - Exemplar as JSONExemplar, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - ExponentialHistogram as JSONExponentialHistogram, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - ExponentialHistogramDataPoint as JSONExponentialHistogramDataPoint, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import Gauge as JSONGauge -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - Histogram as JSONHistogram, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - HistogramDataPoint as JSONHistogramDataPoint, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import Metric as JSONMetric -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - NumberDataPoint as JSONNumberDataPoint, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - ResourceMetrics as JSONResourceMetrics, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import ( - ScopeMetrics as JSONScopeMetrics, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics import Sum as JSONSum -from opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource import ( - Resource as JSONResource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( - Exemplar, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( - ExponentialHistogramDataPoint, - HistogramDataPoint, - Metric, - NumberDataPoint, - ResourceMetrics, - ScopeMetrics, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - ExponentialHistogram, - Gauge, - Histogram, - MetricsData, - Sum, -) - -if TYPE_CHECKING: - from opentelemetry.agent._vendor.typing_extensions import assert_never - -_logger = logging.getLogger(__name__) - -_METRIC_DATA_FIELDS = ( - "gauge", - "sum", - "histogram", - "exponential_histogram", - "summary", -) - - -def encode_metrics(data: MetricsData) -> JSONExportMetricsServiceRequest: - return JSONExportMetricsServiceRequest( - resource_metrics=[_encode_resource_metrics(rm) for rm in data.resource_metrics] - ) - - -# pylint: disable-next=too-many-locals -def split_metrics_data( - metrics_data: JSONExportMetricsServiceRequest, - max_export_batch_size: int | None, -) -> Iterable[JSONExportMetricsServiceRequest]: - """Split an ExportMetricsServiceRequest into batches of at most - max_export_batch_size data points, preserving resource/scope hierarchy. - """ - if max_export_batch_size is None: - yield metrics_data - return - - batch_size: int = 0 - resource_metrics_batch: list[JSONResourceMetrics] = [] - scope_metrics_batch: list[JSONScopeMetrics] = [] - metrics_batch: list[JSONMetric] = [] - - for ( - resource_metrics, - scope_metrics, - metric, - field_name, - data_points, - ) in _iter_metric_data_points(metrics_data): - if not resource_metrics_batch or resource_metrics_batch[-1].resource is not resource_metrics.resource: - scope_metrics_batch = [] - resource_metrics_batch.append(replace(resource_metrics, scope_metrics=scope_metrics_batch)) - - if not scope_metrics_batch or scope_metrics_batch[-1].scope is not scope_metrics.scope: - metrics_batch = [] - scope_metrics_batch.append(replace(scope_metrics, metrics=metrics_batch)) - - data_points_batch: list = [] - metrics_batch.append(_build_metric_with_data_points(metric, field_name, data_points_batch)) - - for data_point in data_points: - data_points_batch.append(data_point) - batch_size += 1 - - if batch_size >= max_export_batch_size: - yield JSONExportMetricsServiceRequest(resource_metrics=resource_metrics_batch) - ( - resource_metrics_batch, - scope_metrics_batch, - metrics_batch, - data_points_batch, - ) = _build_empty_metric_batches(resource_metrics, scope_metrics, metric, field_name) - batch_size = 0 - - if not batch_size: - resource_metrics_batch = [] - scope_metrics_batch = [] - metrics_batch = [] - - if batch_size: - yield JSONExportMetricsServiceRequest(resource_metrics=resource_metrics_batch) - - -def _get_metric_data_field_name(metric: JSONMetric) -> str | None: - return next( - (f for f in _METRIC_DATA_FIELDS if getattr(metric, f) is not None), - None, - ) - - -def _iter_metric_data_points( - metrics_data: JSONExportMetricsServiceRequest, -) -> Iterable[tuple[JSONResourceMetrics, JSONScopeMetrics, JSONMetric, str, list]]: - for resource_metrics in metrics_data.resource_metrics: - for scope_metrics in resource_metrics.scope_metrics: - for metric in scope_metrics.metrics: - field_name = _get_metric_data_field_name(metric) - if field_name is None: - _logger.warning("Tried to split and export an unsupported metric type. Skipping.") - continue - dps = getattr(metric, field_name).data_points - if not dps: - _logger.warning("Unexpected empty metric datapoints. Skipping.") - continue - yield ( - resource_metrics, - scope_metrics, - metric, - field_name, - dps, - ) - - -def _build_metric_with_data_points( - metric: JSONMetric, - field_name: str, - data_points: list, -) -> JSONMetric: - new_data = replace(getattr(metric, field_name), data_points=data_points) - return replace(metric, **{field_name: new_data}) - - -def _build_empty_metric_batches( - resource_metrics: JSONResourceMetrics, - scope_metrics: JSONScopeMetrics, - metric: JSONMetric, - field_name: str, -) -> tuple[list[JSONResourceMetrics], list[JSONScopeMetrics], list[JSONMetric], list]: - data_points_batch = [] - metrics_batch = [_build_metric_with_data_points(metric, field_name, data_points_batch)] - scope_metrics_batch = [replace(scope_metrics, metrics=metrics_batch)] - resource_metrics_batch = [replace(resource_metrics, scope_metrics=scope_metrics_batch)] - return ( - resource_metrics_batch, - scope_metrics_batch, - metrics_batch, - data_points_batch, - ) - - -def _encode_resource_metrics( - rm: ResourceMetrics, -) -> JSONResourceMetrics: - return JSONResourceMetrics( - resource=JSONResource(attributes=_encode_attributes(rm.resource.attributes)), - scope_metrics=[_encode_scope_metrics(sm) for sm in rm.scope_metrics], - schema_url=rm.resource.schema_url, - ) - - -def _encode_scope_metrics( - sm: ScopeMetrics, -) -> JSONScopeMetrics: - return JSONScopeMetrics( - scope=_encode_instrumentation_scope(sm.scope), - schema_url=sm.scope.schema_url, - metrics=[_encode_metric(m) for m in sm.metrics], - ) - - -def _encode_metric(metric: Metric) -> JSONMetric: - json_metric = JSONMetric( - name=metric.name, - description=metric.description, - unit=metric.unit, - ) - if isinstance(metric.data, Gauge): - json_metric.gauge = JSONGauge(data_points=[_encode_gauge_data_point(pt) for pt in metric.data.data_points]) - elif isinstance(metric.data, Histogram): - json_metric.histogram = JSONHistogram( - data_points=[_encode_histogram_data_point(pt) for pt in metric.data.data_points], - aggregation_temporality=metric.data.aggregation_temporality, - ) - elif isinstance(metric.data, Sum): - json_metric.sum = JSONSum( - data_points=[_encode_sum_data_point(pt) for pt in metric.data.data_points], - aggregation_temporality=metric.data.aggregation_temporality, - is_monotonic=metric.data.is_monotonic, - ) - elif isinstance(metric.data, ExponentialHistogram): - json_metric.exponential_histogram = JSONExponentialHistogram( - data_points=[_encode_exponential_histogram_data_point(pt) for pt in metric.data.data_points], - aggregation_temporality=metric.data.aggregation_temporality, - ) - else: - if TYPE_CHECKING: - assert_never(metric.data) - _logger.warning( - "unsupported data type %s", - metric.data.__class__.__name__, - ) - return json_metric - - -def _encode_gauge_data_point( - data_point: NumberDataPoint, -) -> JSONNumberDataPoint: - pt = JSONNumberDataPoint( - attributes=_encode_attributes(data_point.attributes), - time_unix_nano=data_point.time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - ) - if isinstance(data_point.value, int): - pt.as_int = data_point.value - else: - pt.as_double = data_point.value - return pt - - -def _encode_sum_data_point( - data_point: NumberDataPoint, -) -> JSONNumberDataPoint: - pt = JSONNumberDataPoint( - attributes=_encode_attributes(data_point.attributes), - start_time_unix_nano=data_point.start_time_unix_nano, - time_unix_nano=data_point.time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - ) - if isinstance(data_point.value, int): - pt.as_int = data_point.value - else: - pt.as_double = data_point.value - return pt - - -def _encode_histogram_data_point( - data_point: HistogramDataPoint, -) -> JSONHistogramDataPoint: - return JSONHistogramDataPoint( - attributes=_encode_attributes(data_point.attributes), - time_unix_nano=data_point.time_unix_nano, - start_time_unix_nano=data_point.start_time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - count=data_point.count, - sum=data_point.sum, - bucket_counts=list(data_point.bucket_counts), - explicit_bounds=list(data_point.explicit_bounds), - max=data_point.max, - min=data_point.min, - ) - - -def _encode_exponential_histogram_data_point( - data_point: ExponentialHistogramDataPoint, -) -> JSONExponentialHistogramDataPoint: - return JSONExponentialHistogramDataPoint( - attributes=_encode_attributes(data_point.attributes), - time_unix_nano=data_point.time_unix_nano, - start_time_unix_nano=data_point.start_time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - count=data_point.count, - sum=data_point.sum, - scale=data_point.scale, - zero_count=data_point.zero_count, - positive=( - JSONExponentialHistogramDataPoint.Buckets( - offset=data_point.positive.offset, - bucket_counts=list(data_point.positive.bucket_counts), - ) - if data_point.positive.bucket_counts - else None - ), - negative=( - JSONExponentialHistogramDataPoint.Buckets( - offset=data_point.negative.offset, - bucket_counts=list(data_point.negative.bucket_counts), - ) - if data_point.negative.bucket_counts - else None - ), - flags=data_point.flags, - max=data_point.max, - min=data_point.min, - ) - - -def _encode_exemplars( - sdk_exemplars: Collection[Exemplar], -) -> list[JSONExemplar]: - json_exemplars = [] - for sdk_exemplar in sdk_exemplars: - if sdk_exemplar.span_id is not None and sdk_exemplar.trace_id is not None: - json_exemplar = JSONExemplar( - time_unix_nano=sdk_exemplar.time_unix_nano, - span_id=_encode_span_id(sdk_exemplar.span_id), - trace_id=_encode_trace_id(sdk_exemplar.trace_id), - filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), - ) - else: - json_exemplar = JSONExemplar( - time_unix_nano=sdk_exemplar.time_unix_nano, - filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), - ) - - # Assign the value based on its type in the SDK exemplar - if isinstance(sdk_exemplar.value, float): - json_exemplar.as_double = sdk_exemplar.value - elif isinstance(sdk_exemplar.value, int): - json_exemplar.as_int = sdk_exemplar.value - else: - if TYPE_CHECKING: - assert_never(sdk_exemplar.value) - raise ValueError("Exemplar value must be an int or float") - json_exemplars.append(json_exemplar) - - return json_exemplars diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py deleted file mode 100644 index 7e4b4d9550a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_internal/trace_encoder/__init__.py +++ /dev/null @@ -1,159 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pyright: reportCallIssue=false - -from __future__ import annotations - -import logging -from collections import defaultdict -from collections.abc import Collection - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal import ( - _encode_attributes, - _encode_instrumentation_scope, - _encode_resource, - _encode_span_id, - _encode_trace_id, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.collector.trace.v1.trace_service import ( - ExportTraceServiceRequest as JSONExportTraceServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import ( - ResourceSpans as JSONResourceSpans, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import ( - ScopeSpans as JSONScopeSpans, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import Span as JSONSpan -from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import ( - SpanFlags as JSONSpanFlags, -) -from opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace import Status as JSONStatus -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Event, ReadableSpan -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind -from opentelemetry.agent._vendor.opentelemetry.trace.span import SpanContext, Status, TraceState - -# pylint: disable=E1101 -_SPAN_KIND_MAP = { - SpanKind.INTERNAL: JSONSpan.SpanKind.SPAN_KIND_INTERNAL, - SpanKind.SERVER: JSONSpan.SpanKind.SPAN_KIND_SERVER, - SpanKind.CLIENT: JSONSpan.SpanKind.SPAN_KIND_CLIENT, - SpanKind.PRODUCER: JSONSpan.SpanKind.SPAN_KIND_PRODUCER, - SpanKind.CONSUMER: JSONSpan.SpanKind.SPAN_KIND_CONSUMER, -} - -_logger = logging.getLogger(__name__) - - -def encode_spans( - sdk_spans: Collection[ReadableSpan], -) -> JSONExportTraceServiceRequest: - return JSONExportTraceServiceRequest(resource_spans=_encode_resource_spans(sdk_spans)) - - -def _encode_resource_spans( - sdk_spans: Collection[ReadableSpan], -) -> list[JSONResourceSpans]: - sdk_resource_spans = defaultdict(lambda: defaultdict(list)) - - for sdk_span in sdk_spans: - sdk_resource = sdk_span.resource - sdk_instrumentation = sdk_span.instrumentation_scope or None - sdk_resource_spans[sdk_resource][sdk_instrumentation].append(_encode_span(sdk_span)) - - json_resource_spans = [] - for sdk_resource, sdk_instrumentations in sdk_resource_spans.items(): - scope_spans = [] - for sdk_instrumentation, json_spans in sdk_instrumentations.items(): - scope_spans.append( - JSONScopeSpans( - scope=(_encode_instrumentation_scope(sdk_instrumentation)), - spans=json_spans, - schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, - ) - ) - json_resource_spans.append( - JSONResourceSpans( - resource=_encode_resource(sdk_resource), - scope_spans=scope_spans, - schema_url=sdk_resource.schema_url, - ) - ) - - return json_resource_spans - - -def _span_flags(parent_span_context: SpanContext | None) -> int: - flags = JSONSpanFlags.SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK - if parent_span_context and parent_span_context.is_remote: - flags |= JSONSpanFlags.SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK - return int(flags) - - -def _encode_span(sdk_span: ReadableSpan) -> JSONSpan: - span_context = sdk_span.get_span_context() - return JSONSpan( - trace_id=_encode_trace_id(span_context.trace_id if span_context else 0), - span_id=_encode_span_id(span_context.span_id if span_context else 0), - trace_state=_encode_trace_state(span_context.trace_state if span_context else None), - parent_span_id=_encode_context_span_id(sdk_span.parent), - name=sdk_span.name, - kind=_SPAN_KIND_MAP[sdk_span.kind], - start_time_unix_nano=sdk_span.start_time, - end_time_unix_nano=sdk_span.end_time, - attributes=_encode_attributes(sdk_span.attributes), - events=_encode_events(sdk_span.events), - links=_encode_links(sdk_span.links), - status=_encode_status(sdk_span.status), - dropped_attributes_count=sdk_span.dropped_attributes, - dropped_events_count=sdk_span.dropped_events, - dropped_links_count=sdk_span.dropped_links, - flags=_span_flags(sdk_span.parent), - ) - - -def _encode_events( - events: Collection[Event], -) -> list[JSONSpan.Event]: - return [ - JSONSpan.Event( - name=event.name, - time_unix_nano=event.timestamp, - attributes=_encode_attributes(event.attributes), - dropped_attributes_count=event.dropped_attributes, - ) - for event in events - ] - - -def _encode_links(links: Collection[Link]) -> list[JSONSpan.Link]: - return [ - JSONSpan.Link( - trace_id=_encode_trace_id(link.context.trace_id), - span_id=_encode_span_id(link.context.span_id), - attributes=_encode_attributes(link.attributes), - dropped_attributes_count=link.dropped_attributes, - flags=_span_flags(link.context), - ) - for link in links - ] - - -def _encode_status(status: Status | None) -> JSONStatus | None: - return ( - JSONStatus( - code=JSONStatus.StatusCode(status.status_code.value), - message=status.description, - ) - if status is not None - else None - ) - - -def _encode_trace_state(trace_state: TraceState | None) -> str | None: - return ",".join([f"{key}={value}" for key, value in (trace_state.items())]) if trace_state is not None else None - - -def _encode_context_span_id(context: SpanContext | None) -> bytes | None: - return _encode_span_id(context.span_id) if context else None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py deleted file mode 100644 index f6fff4cf524..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/_log_encoder.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal._log_encoder import ( - encode_logs, -) - -__all__ = ["encode_logs"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py deleted file mode 100644 index b16f5d63353..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/metrics_encoder.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.metrics_encoder import ( - encode_metrics, -) - -__all__ = ["encode_metrics"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py deleted file mode 100644 index 4968e789f14..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/trace_encoder.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.trace_encoder import ( - encode_spans, -) - -__all__ = ["encode_spans"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/common/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py deleted file mode 100644 index 228853fab25..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/__init__.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -This library allows exporting OpenTelemetry telemetry to a file or stream -in OTLP JSON (JSON Lines) format. - -Usage ------ - -The **OTLP JSON File Exporter** writes `OpenTelemetry`_ traces, metrics, and -logs as compact JSON Lines to a file, an arbitrary ``IO[str]`` stream or -``sys.stdout``. - -Three exporters are provided: - -- :class:`~opentelemetry.exporter.otlp.json.file.trace_exporter.FileSpanExporter` - traces -- :class:`~opentelemetry.exporter.otlp.json.file.metric_exporter.FileMetricExporter` - metrics -- :class:`~opentelemetry.exporter.otlp.json.file._log_exporter.FileLogExporter` - logs - -Each exporter accepts a destination in one of three ways: - -- ``path`` - a file path opened in append mode (UTF-8) -- ``stream`` - any ``IO[str]`` text stream -- neither - defaults to ``sys.stdout`` - -.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ - -.. code:: python - - from opentelemetry import trace - from opentelemetry.exporter.otlp.json.file import FileSpanExporter - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import BatchSpanProcessor - - # Write traces to a file (append mode, UTF-8) - exporter = FileSpanExporter("/var/log/otel/traces.jsonl") - - # Alternatively, write to an explicit stream: - # exporter = FileSpanExporter(stream=open("traces.jsonl", "a")) - - # Or write to sys.stdout (default when no path or stream is given): - # exporter = FileSpanExporter() - - trace.set_tracer_provider(TracerProvider()) - trace.get_tracer_provider().add_span_processor( - BatchSpanProcessor(exporter) - ) - - tracer = trace.get_tracer(__name__) - with tracer.start_as_current_span("foo"): - print("Hello world!") - -The metric exporter supports the following environment variables: - -- :envvar:`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` -- :envvar:`OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` - -API ---- -""" - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.metric_exporter import ( - FileMetricExporter, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file.trace_exporter import ( - FileSpanExporter, -) - -__all__ = [ - "FileMetricExporter", - "FileSpanExporter", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py deleted file mode 100644 index 34222944cf1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_internal.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import json -import logging -import sys -import threading -from collections.abc import Callable -from os import PathLike -from typing import IO, Generic, Literal, TypeVar - -_logger = logging.getLogger(__name__) - -T = TypeVar("T") - - -class _FileExporter(Generic[T]): - def __init__( - self, - encode: Callable[[T], dict | None], - kind: Literal["spans", "logs", "metrics"], - logger: logging.Logger | None = None, - path: str | PathLike[str] | None = None, - stream: IO[str] | None = None, - ) -> None: - if path is not None and stream is not None: - raise ValueError("Cannot specify both 'path' and 'stream'") - if path is not None: - self._stream: IO[str] = open( # pylint: disable=consider-using-with - path, "a", encoding="utf-8" - ) - self._owns_stream = True - elif stream is not None: - self._stream = stream - self._owns_stream = False - else: - self._stream = sys.stdout - self._owns_stream = False - self._shutdown = False - self._encode = encode - self._kind = kind - self._logger = logger if logger is not None else _logger - self._lock = threading.Lock() - - def export(self, data: T) -> bool: - if self._shutdown: - self._logger.warning("Exporter already shutdown, ignoring call") - return False - try: - encoded = self._encode(data) - with self._lock: - if self._stream.closed: - self._logger.warning("Stream is closed, ignoring %s export call", self._kind) - return False - if encoded is not None: - self._stream.write(_format_line(encoded)) - self._stream.flush() - # pylint: disable-next=broad-exception-caught - except Exception as error: - self._logger.exception( - "Failed to write %s batch to stream: %s: %s", - self._kind, - type(error).__name__, - error, - ) - return False - return True - - def shutdown(self) -> None: - if self._shutdown: - self._logger.warning("Exporter already shutdown, ignoring call") - return - self._shutdown = True - if self._owns_stream: - with self._lock: - self._stream.close() - - -def _format_line(entry: dict) -> str: - return json.dumps(entry, separators=(",", ":")) + "\n" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py deleted file mode 100644 index 028a923ca77..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/_log_exporter.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -import os -from collections.abc import Sequence -from typing import IO, Any, overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._log_encoder import encode_logs -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._internal import _FileExporter -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord -from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( - LogRecordExporter, - LogRecordExportResult, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import DuplicateFilter - -_logger = logging.getLogger(__name__) -_logger.addFilter(DuplicateFilter()) - - -def _encode_logs_to_dict( - batch: Sequence[ReadableLogRecord], -) -> dict[str, Any] | None: - data = encode_logs(batch) - return data.to_dict() if data.resource_logs else None - - -class FileLogExporter(LogRecordExporter): - @overload - def __init__( - self, - path: str | os.PathLike[str], - ) -> None: ... - - @overload - def __init__( - self, - *, - stream: IO[str], - ) -> None: ... - - @overload - def __init__( - self, - ) -> None: ... - - def __init__( - self, - path: str | os.PathLike[str] | None = None, - *, - stream: IO[str] | None = None, - ) -> None: - self._exporter: _FileExporter[Sequence[ReadableLogRecord]] = _FileExporter( - encode=_encode_logs_to_dict, - kind="logs", - logger=_logger, - path=path, - stream=stream, - ) - - def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: - return LogRecordExportResult.SUCCESS if self._exporter.export(batch) else LogRecordExportResult.FAILURE - - def shutdown(self) -> None: - self._exporter.shutdown() - - # pylint: disable-next=no-self-use - def force_flush(self, timeout_millis: int = 10_000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py deleted file mode 100644 index 1ce97ace535..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/metric_exporter.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -import os -from typing import IO, Any, overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._aggregation import ( - _get_aggregation, - _get_temporality, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common.metrics_encoder import ( - encode_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._internal import _FileExporter -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - AggregationTemporality, - MetricExporter, - MetricExportResult, - MetricsData, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import Aggregation - -_logger = logging.getLogger(__name__) - - -def _encode_metrics_to_dict( - metrics_data: MetricsData, -) -> dict[str, Any] | None: - data = encode_metrics(metrics_data) - return data.to_dict() if data.resource_metrics else None - - -class FileMetricExporter(MetricExporter): - @overload - def __init__( - self, - path: str | os.PathLike[str], - *, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - ) -> None: ... - - @overload - def __init__( - self, - *, - stream: IO[str], - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - ) -> None: ... - - @overload - def __init__( - self, - *, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - ) -> None: ... - - def __init__( - self, - path: str | os.PathLike[str] | None = None, - *, - stream: IO[str] | None = None, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - ) -> None: - MetricExporter.__init__( - self, - preferred_temporality=_get_temporality(preferred_temporality), - preferred_aggregation=_get_aggregation(preferred_aggregation), - ) - self._exporter: _FileExporter[MetricsData] = _FileExporter( - encode=_encode_metrics_to_dict, - kind="metrics", - logger=_logger, - path=path, - stream=stream, - ) - - def export( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> MetricExportResult: - return MetricExportResult.SUCCESS if self._exporter.export(metrics_data) else MetricExportResult.FAILURE - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - self._exporter.shutdown() - - def force_flush(self, timeout_millis: float = 10_000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py deleted file mode 100644 index f3bcb567097..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/trace_exporter.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -import os -from collections.abc import Sequence -from typing import IO, Any, overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common.trace_encoder import encode_spans -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.file._internal import _FileExporter -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult - -_logger = logging.getLogger(__name__) - - -def _encode_spans_to_dict( - spans: Sequence[ReadableSpan], -) -> dict[str, Any] | None: - data = encode_spans(spans) - return data.to_dict() if data.resource_spans else None - - -class FileSpanExporter(SpanExporter): - @overload - def __init__( - self, - path: str | os.PathLike[str], - ) -> None: ... - - @overload - def __init__( - self, - *, - stream: IO[str], - ) -> None: ... - - @overload - def __init__( - self, - ) -> None: ... - - def __init__( - self, - path: str | os.PathLike[str] | None = None, - *, - stream: IO[str] | None = None, - ) -> None: - self._exporter: _FileExporter[Sequence[ReadableSpan]] = _FileExporter( - encode=_encode_spans_to_dict, - kind="spans", - logger=_logger, - path=path, - stream=stream, - ) - - def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: - return SpanExportResult.SUCCESS if self._exporter.export(spans) else SpanExportResult.FAILURE - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - self._exporter.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/file/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py deleted file mode 100644 index 3c2993f3b19..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/__init__.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -This library allows exporting OpenTelemetry telemetry using the OTLP JSON -over HTTP wire format to any backend that accepts OTLP JSON. - -Usage ------ - -The **OTLP JSON HTTP Exporter** exports `OpenTelemetry`_ traces, metrics, -and logs via HTTP to any `OTLP`_-compatible backend using OTLP JSON -encoding instead of protobuf. - -Three exporters are provided: - -- :class:`~opentelemetry.exporter.otlp.json.http.trace_exporter.OTLPSpanExporter` - traces -- :class:`~opentelemetry.exporter.otlp.json.http.metric_exporter.OTLPMetricExporter` - metrics -- :class:`~opentelemetry.exporter.otlp.json.http._log_exporter.OTLPLogExporter` - logs - -You can configure each exporter with the following environment variables, -using the appropriate per-signal prefix (``TRACES``, ``METRICS``, or -``LOGS``) or the generic variant that applies to all three: - -- :envvar:`OTEL_EXPORTER_OTLP_ENDPOINT` -- :envvar:`OTEL_EXPORTER_OTLP_HEADERS` -- :envvar:`OTEL_EXPORTER_OTLP_TIMEOUT` -- :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` -- :envvar:`OTEL_EXPORTER_OTLP_CERTIFICATE` -- :envvar:`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` -- :envvar:`OTEL_EXPORTER_OTLP_CLIENT_KEY` - -The metric exporter also supports the following environment variables: - -- :envvar:`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` -- :envvar:`OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` - -.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/ -.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ - -.. code:: python - - from opentelemetry import trace - from opentelemetry.exporter.otlp.json.http import OTLPSpanExporter - from opentelemetry.sdk.resources import Resource - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import BatchSpanProcessor - - resource = Resource.create({ - "service.name": "service" - }) - - trace.set_tracer_provider(TracerProvider(resource=resource)) - tracer = trace.get_tracer(__name__) - - otlp_exporter = OTLPSpanExporter() - - span_processor = BatchSpanProcessor(otlp_exporter) - - trace.get_tracer_provider().add_span_processor(span_processor) - - with tracer.start_as_current_span("foo"): - print("Hello world!") - -API ---- -""" - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.metric_exporter import ( - OTLPMetricExporter, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.trace_exporter import ( - OTLPSpanExporter, -) - -__all__ = [ - "OTLPMetricExporter", - "OTLPSpanExporter", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py deleted file mode 100644 index 942df502545..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_internal.py +++ /dev/null @@ -1,137 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -import os -from collections.abc import Mapping -from typing import TYPE_CHECKING, Literal - -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._urllib3 import Urllib3HTTPTransport -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import Compression -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http.version import __version__ -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_OTLP_CERTIFICATE, - OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_CLIENT_KEY, - OTEL_EXPORTER_OTLP_COMPRESSION, - OTEL_EXPORTER_OTLP_ENDPOINT, - OTEL_EXPORTER_OTLP_HEADERS, - OTEL_EXPORTER_OTLP_TIMEOUT, -) -from opentelemetry.agent._vendor.opentelemetry.util.re import parse_env_headers - -if TYPE_CHECKING: - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport import BaseHTTPTransportFactory - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport - -_DEFAULT_ENDPOINT = "http://localhost:4318" -_DEFAULT_TIMEOUT = 10 - -_logger = logging.getLogger(__name__) - - -def _resolve_endpoint( - endpoint_env_var: str, - default_path: Literal["v1/traces", "v1/metrics", "v1/logs"], -) -> str: - if endpoint := os.environ.get(endpoint_env_var): - return endpoint - - base_endpoint = os.environ.get(OTEL_EXPORTER_OTLP_ENDPOINT) or _DEFAULT_ENDPOINT - - return f"{base_endpoint.removesuffix('/')}/{default_path}" - - -def _resolve_headers( - headers: Mapping[str, str] | None, - headers_env_var: str, -) -> dict[str, str]: - headers_ = { - "content-type": "application/json", - "user-agent": "OTel-OTLP-JSON-Exporter-Python/" + __version__, - } - env_headers = parse_env_headers( - os.environ.get(headers_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), - liberal=True, - ) - headers_.update(env_headers) - if headers: - headers_.update({key.lower(): value for key, value in headers.items()}) - return headers_ - - -def _resolve_timeout( - timeout_env_var: str, -) -> float: - raw = os.environ.get(timeout_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_TIMEOUT) or _DEFAULT_TIMEOUT - - try: - return float(raw) - except ValueError: - _logger.warning( - "Invalid timeout value %r, using default of %s seconds", - raw, - _DEFAULT_TIMEOUT, - ) - return float(_DEFAULT_TIMEOUT) - - -def _resolve_compression(compression_env_var: str) -> Compression: - val = ( - ( - os.environ.get( - compression_env_var, - ) - or os.environ.get(OTEL_EXPORTER_OTLP_COMPRESSION) - or "none" - ) - .lower() - .strip() - ) - - try: - return Compression.from_str(val) - except ValueError: - _logger.warning("Unsupported compression type: %s", val) - return Compression.NONE - - -def _build_transport( - certificate_file: str | None, - client_key_file: str | None, - client_certificate_file: str | None, - certificate_env_var: str, - client_key_env_var: str, - client_certificate_env_var: str, - transport_factory: BaseHTTPTransportFactory = Urllib3HTTPTransport, -) -> BaseHTTPTransport: - verify: bool | str = ( - certificate_file - or os.environ.get( - certificate_env_var, - ) - or os.environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE) - or True - ) - client_key_file = ( - client_key_file - or os.environ.get( - client_key_env_var, - ) - or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_KEY) - ) - client_certificate_file = ( - client_certificate_file - or os.environ.get( - client_certificate_env_var, - ) - or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE) - ) - return transport_factory( - verify=verify, - cert=(client_certificate_file, client_key_file) - if client_certificate_file and client_key_file - else client_certificate_file, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py deleted file mode 100644 index 9c30db2074c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/_log_exporter.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -from collections.abc import Mapping, Sequence -from typing import overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import ( - Compression, - _OTLPHTTPClient, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal._log_encoder import ( - encode_logs, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._internal import ( - _build_transport, - _resolve_compression, - _resolve_endpoint, - _resolve_headers, - _resolve_timeout, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord -from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( - LogRecordExporter, - LogRecordExportResult, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import DuplicateFilter -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, - OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, - OTEL_EXPORTER_OTLP_LOGS_HEADERS, - OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, -) - -_DEFAULT_LOGS_EXPORT_PATH = "v1/logs" - -_logger = logging.getLogger(__name__) -_logger.addFilter(DuplicateFilter()) - - -class OTLPLogExporter(LogRecordExporter): - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - ) -> None: ... - - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: None = None, - client_key_file: None = None, - client_certificate_file: None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - *, - _transport: BaseHTTPTransport, - ) -> None: ... - - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - *, - _transport: BaseHTTPTransport | None = None, - ) -> None: - """OTLP HTTP JSON log exporter. - - Args: - endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal - path. Example: ``http://collector:4318/v1/logs``. For a base URL without a - signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. - """ - transport = _transport or _build_transport( - certificate_file, - client_key_file, - client_certificate_file, - OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, - ) - self._client = _OTLPHTTPClient( - transport=transport, - endpoint=endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, _DEFAULT_LOGS_EXPORT_PATH), - kind="logs", - timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT), - compression=compression - if compression is not None - else _resolve_compression(OTEL_EXPORTER_OTLP_LOGS_COMPRESSION), - headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_LOGS_HEADERS), - logger=_logger, - ) - self._shutdown = False - - def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring batch") - return LogRecordExportResult.FAILURE - try: - body = encode_logs(batch).to_json().encode() - # pylint: disable-next=broad-exception-caught - except Exception as error: - _logger.error("Failed to encode logs: %s", error) - return LogRecordExportResult.FAILURE - export_result = self._client.export(body) - return LogRecordExportResult.SUCCESS if export_result.success else LogRecordExportResult.FAILURE - - def shutdown(self) -> None: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring call") - return - self._shutdown = True - self._client.shutdown() - - # pylint: disable-next=no-self-use - def force_flush(self, timeout_millis: int = 10_000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py deleted file mode 100644 index f8de6408261..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/metric_exporter.py +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -from collections.abc import Mapping -from typing import overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._aggregation import ( - _get_aggregation, - _get_temporality, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import ( - Compression, - _OTLPHTTPClient, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.metrics_encoder import ( - encode_metrics, - split_metrics_data, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._internal import ( - _build_transport, - _resolve_compression, - _resolve_endpoint, - _resolve_headers, - _resolve_timeout, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, - OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, - OTEL_EXPORTER_OTLP_METRICS_HEADERS, - OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - AggregationTemporality, - MetricExporter, - MetricExportResult, - MetricsData, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import Aggregation - -_DEFAULT_METRICS_EXPORT_PATH = "v1/metrics" - -_logger = logging.getLogger(__name__) - - -class OTLPMetricExporter(MetricExporter): - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - max_export_batch_size: int | None = None, - ) -> None: ... - - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: None = None, - client_key_file: None = None, - client_certificate_file: None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - max_export_batch_size: int | None = None, - *, - _transport: BaseHTTPTransport, - ) -> None: ... - - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - max_export_batch_size: int | None = None, - *, - _transport: BaseHTTPTransport | None = None, - ) -> None: - """OTLP HTTP JSON metric exporter. - - Args: - endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal - path. Example: ``http://collector:4318/v1/metrics``. For a base URL without a - signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. - """ - MetricExporter.__init__( - self, - preferred_temporality=_get_temporality(preferred_temporality), - preferred_aggregation=_get_aggregation(preferred_aggregation), - ) - transport = _transport or _build_transport( - certificate_file, - client_key_file, - client_certificate_file, - OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, - ) - self._client = _OTLPHTTPClient( - transport=transport, - endpoint=endpoint - or _resolve_endpoint( - OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, - _DEFAULT_METRICS_EXPORT_PATH, - ), - kind="metrics", - timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_METRICS_TIMEOUT), - compression=compression - if compression is not None - else _resolve_compression(OTEL_EXPORTER_OTLP_METRICS_COMPRESSION), - headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_METRICS_HEADERS), - logger=_logger, - ) - self._max_export_batch_size = max_export_batch_size - self._shutdown = False - - def export( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> MetricExportResult: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring batch") - return MetricExportResult.FAILURE - try: - export_request = encode_metrics(metrics_data) - # pylint: disable-next=broad-exception-caught - except Exception as error: - _logger.error("Failed to encode metrics: %s", error) - return MetricExportResult.FAILURE - for request in split_metrics_data(export_request, self._max_export_batch_size): - export_result = self._client.export(request.to_json().encode()) - if not export_result.success: - return MetricExportResult.FAILURE - return MetricExportResult.SUCCESS - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring call") - return - self._shutdown = True - self._client.shutdown() - - def force_flush(self, timeout_millis: float = 10_000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py deleted file mode 100644 index 3477ba4b27c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/trace_exporter.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -from collections.abc import Mapping, Sequence -from typing import overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common.http import ( - Compression, - _OTLPHTTPClient, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.common._internal.trace_encoder import ( - encode_spans, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.json.http._internal import ( - _build_transport, - _resolve_compression, - _resolve_endpoint, - _resolve_headers, - _resolve_timeout, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, - OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, - OTEL_EXPORTER_OTLP_TRACES_HEADERS, - OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult - -_DEFAULT_TRACES_EXPORT_PATH = "v1/traces" - -_logger = logging.getLogger(__name__) - - -class OTLPSpanExporter(SpanExporter): - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - ) -> None: ... - - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: None = None, - client_key_file: None = None, - client_certificate_file: None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - *, - _transport: BaseHTTPTransport, - ) -> None: ... - - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | None = None, - *, - _transport: BaseHTTPTransport | None = None, - ) -> None: - """OTLP HTTP JSON span exporter. - - Args: - endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal - path. Example: ``http://collector:4318/v1/traces``. For a base URL without a - signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. - """ - transport = _transport or _build_transport( - certificate_file, - client_key_file, - client_certificate_file, - OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, - ) - self._client = _OTLPHTTPClient( - transport=transport, - endpoint=endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, _DEFAULT_TRACES_EXPORT_PATH), - kind="spans", - timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT), - compression=compression - if compression is not None - else _resolve_compression(OTEL_EXPORTER_OTLP_TRACES_COMPRESSION), - headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_TRACES_HEADERS), - logger=_logger, - ) - self._shutdown = False - - def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring batch") - return SpanExportResult.FAILURE - try: - body = encode_spans(spans).to_json().encode() - # pylint: disable-next=broad-exception-caught - except Exception as error: - _logger.error("Failed to encode spans: %s", error) - return SpanExportResult.FAILURE - export_result = self._client.export(body) - return SpanExportResult.SUCCESS if export_result.success else SpanExportResult.FAILURE - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring call") - return - self._shutdown = True - self._client.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/json/http/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py deleted file mode 100644 index ca87bc042d2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common.version import __version__ - -__all__ = ["__version__"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py deleted file mode 100644 index fdeeabddd2a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from __future__ import annotations - -import logging -from collections.abc import Callable, Mapping, Sequence -from typing import ( - Any, - TypeVar, -) - -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import AnyValue as PB2AnyValue -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( - ArrayValue as PB2ArrayValue, -) -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( - InstrumentationScope as PB2InstrumentationScope, -) -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import KeyValue as PB2KeyValue -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( - KeyValueList as PB2KeyValueList, -) -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( - Resource as PB2Resource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -_logger = logging.getLogger(__name__) - -_TypingResourceT = TypeVar("_TypingResourceT") -_ResourceDataT = TypeVar("_ResourceDataT") - - -def _encode_instrumentation_scope( - instrumentation_scope: InstrumentationScope, -) -> PB2InstrumentationScope: - if instrumentation_scope is None: - return PB2InstrumentationScope() - return PB2InstrumentationScope( - name=instrumentation_scope.name, - version=instrumentation_scope.version, - attributes=_encode_attributes(instrumentation_scope.attributes), - ) - - -def _encode_resource(resource: Resource) -> PB2Resource: - return PB2Resource(attributes=_encode_attributes(resource.attributes)) - - -def _encode_value(value: Any) -> PB2AnyValue: - if value is None: - return PB2AnyValue() - if isinstance(value, bool): - return PB2AnyValue(bool_value=value) - if isinstance(value, str): - return PB2AnyValue(string_value=value) - if isinstance(value, int): - return PB2AnyValue(int_value=value) - if isinstance(value, float): - return PB2AnyValue(double_value=value) - if isinstance(value, bytes): - return PB2AnyValue(bytes_value=value) - if isinstance(value, Sequence): - return PB2AnyValue(array_value=PB2ArrayValue(values=[_encode_value(v) for v in value])) - if isinstance(value, Mapping): - return PB2AnyValue( - kvlist_value=PB2KeyValueList(values=[_encode_key_value(str(k), v) for k, v in value.items()]) - ) - raise Exception(f"Invalid type {type(value)} of value {value}") - - -def _encode_key_value(key: str, value: Any) -> PB2KeyValue: - return PB2KeyValue(key=key, value=_encode_value(value)) - - -def _encode_span_id(span_id: int) -> bytes: - return span_id.to_bytes(length=8, byteorder="big", signed=False) - - -def _encode_trace_id(trace_id: int) -> bytes: - return trace_id.to_bytes(length=16, byteorder="big", signed=False) - - -def _encode_attributes(attributes: Attributes) -> list[PB2KeyValue]: - if not attributes: - return [] - pb2_attributes = [] - for key, value in attributes.items(): - # pylint: disable=broad-exception-caught - try: - pb2_attributes.append(_encode_key_value(key, value)) - except Exception as error: - _logger.exception("Failed to encode key %s: %s", key, error) - return pb2_attributes - - -def _get_resource_data( - sdk_resource_scope_data: dict[Resource, _ResourceDataT], - resource_class: Callable[..., _TypingResourceT], - name: str, -) -> list[_TypingResourceT]: - resource_data = [] - - for ( - sdk_resource, - scope_data, - ) in sdk_resource_scope_data.items(): - collector_resource = PB2Resource(attributes=_encode_attributes(sdk_resource.attributes)) - resource_data.append( - resource_class( - **{ - "resource": collector_resource, - f"scope_{name}": scope_data.values(), - } - ) - ) - return resource_data diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py deleted file mode 100644 index 3a8e30c78f6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from collections import defaultdict -from collections.abc import Sequence - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( - _encode_attributes, - _encode_instrumentation_scope, - _encode_resource, - _encode_span_id, - _encode_trace_id, - _encode_value, -) -from opentelemetry.agent._vendor.opentelemetry.proto.collector.logs.v1.logs_service_pb2 import ( - ExportLogsServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto.logs.v1.logs_pb2 import LogRecord as PB2LogRecord -from opentelemetry.agent._vendor.opentelemetry.proto.logs.v1.logs_pb2 import ( - ResourceLogs, - ScopeLogs, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord - - -def encode_logs( - batch: Sequence[ReadableLogRecord], -) -> ExportLogsServiceRequest: - return ExportLogsServiceRequest(resource_logs=_encode_resource_logs(batch)) - - -def _encode_log(readable_log_record: ReadableLogRecord) -> PB2LogRecord: - span_id = ( - None if readable_log_record.log_record.span_id == 0 else _encode_span_id(readable_log_record.log_record.span_id) - ) - trace_id = ( - None - if readable_log_record.log_record.trace_id == 0 - else _encode_trace_id(readable_log_record.log_record.trace_id) - ) - return PB2LogRecord( - time_unix_nano=readable_log_record.log_record.timestamp, - observed_time_unix_nano=readable_log_record.log_record.observed_timestamp, - span_id=span_id, - trace_id=trace_id, - flags=int(readable_log_record.log_record.trace_flags), - body=_encode_value(readable_log_record.log_record.body), - severity_text=readable_log_record.log_record.severity_text, - attributes=_encode_attributes(readable_log_record.log_record.attributes), - dropped_attributes_count=readable_log_record.dropped_attributes, - severity_number=getattr(readable_log_record.log_record.severity_number, "value", None), - event_name=readable_log_record.log_record.event_name, - ) - - -def _encode_resource_logs( - batch: Sequence[ReadableLogRecord], -) -> list[ResourceLogs]: - sdk_resource_logs = defaultdict(lambda: defaultdict(list)) - - for readable_log in batch: - sdk_resource = readable_log.resource - sdk_instrumentation = readable_log.instrumentation_scope or None - pb2_log = _encode_log(readable_log) - - sdk_resource_logs[sdk_resource][sdk_instrumentation].append(pb2_log) - - pb2_resource_logs = [] - - for sdk_resource, sdk_instrumentations in sdk_resource_logs.items(): - scope_logs = [] - for sdk_instrumentation, pb2_logs in sdk_instrumentations.items(): - scope_logs.append( - ScopeLogs( - scope=(_encode_instrumentation_scope(sdk_instrumentation)), - log_records=pb2_logs, - schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, - ) - ) - pb2_resource_logs.append( - ResourceLogs( - resource=_encode_resource(sdk_resource), - scope_logs=scope_logs, - schema_url=sdk_resource.schema_url, - ) - ) - - return pb2_resource_logs diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py deleted file mode 100644 index 378efb6d8b8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/metrics_encoder/__init__.py +++ /dev/null @@ -1,348 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import logging -from os import environ - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( - _encode_attributes, - _encode_instrumentation_scope, - _encode_span_id, - _encode_trace_id, -) -from opentelemetry.agent._vendor.opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( - ExportMetricsServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2 -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( - Resource as PB2Resource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( - Counter, - Exemplar, - Histogram, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - UpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - AggregationTemporality, - Gauge, - MetricExporter, - MetricsData, - Sum, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - ExponentialHistogram as ExponentialHistogramType, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - Histogram as HistogramType, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.view import ( - Aggregation, - ExplicitBucketHistogramAggregation, - ExponentialBucketHistogramAggregation, -) - -_logger = logging.getLogger(__name__) - - -class OTLPMetricExporterMixin: - def _common_configuration( - self, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - ) -> None: - MetricExporter.__init__( - self, - preferred_temporality=self._get_temporality(preferred_temporality), - preferred_aggregation=self._get_aggregation(preferred_aggregation), - ) - - def _get_temporality( - self, preferred_temporality: dict[type, AggregationTemporality] - ) -> dict[type, AggregationTemporality]: - otel_exporter_otlp_metrics_temporality_preference = ( - environ.get( - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE, - "CUMULATIVE", - ) - .upper() - .strip() - ) - - if otel_exporter_otlp_metrics_temporality_preference == "DELTA": - instrument_class_temporality = { - Counter: AggregationTemporality.DELTA, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.DELTA, - ObservableCounter: AggregationTemporality.DELTA, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - - elif otel_exporter_otlp_metrics_temporality_preference == "LOWMEMORY": - instrument_class_temporality = { - Counter: AggregationTemporality.DELTA, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.DELTA, - ObservableCounter: AggregationTemporality.CUMULATIVE, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - - else: - if otel_exporter_otlp_metrics_temporality_preference != ("CUMULATIVE"): - _logger.warning( - "Unrecognized OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE value found: %s, using CUMULATIVE", - otel_exporter_otlp_metrics_temporality_preference, - ) - instrument_class_temporality = { - Counter: AggregationTemporality.CUMULATIVE, - UpDownCounter: AggregationTemporality.CUMULATIVE, - Histogram: AggregationTemporality.CUMULATIVE, - ObservableCounter: AggregationTemporality.CUMULATIVE, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - } - - instrument_class_temporality.update(preferred_temporality or {}) - - return instrument_class_temporality - - def _get_aggregation( - self, - preferred_aggregation: dict[type, Aggregation], - ) -> dict[type, Aggregation]: - otel_exporter_otlp_metrics_default_histogram_aggregation = environ.get( - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, - "explicit_bucket_histogram", - ) - - if otel_exporter_otlp_metrics_default_histogram_aggregation == ("base2_exponential_bucket_histogram"): - instrument_class_aggregation = { - Histogram: ExponentialBucketHistogramAggregation(), - } - - else: - if otel_exporter_otlp_metrics_default_histogram_aggregation != ("explicit_bucket_histogram"): - _logger.warning( - ("Invalid value for %s: %s, using explicit bucket histogram aggregation"), - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, - otel_exporter_otlp_metrics_default_histogram_aggregation, - ) - - instrument_class_aggregation = { - Histogram: ExplicitBucketHistogramAggregation(), - } - - instrument_class_aggregation.update(preferred_aggregation or {}) - - return instrument_class_aggregation - - -class EncodingException(Exception): - """ - Raised by encode_metrics() when an exception is caught during encoding. Contains the problematic metric so - the misbehaving metric name and details can be logged during exception handling. - """ - - def __init__(self, original_exception, metric): - super().__init__() - self.original_exception = original_exception - self.metric = metric - - def __str__(self): - return f"{self.metric}\n{self.original_exception}" - - -def encode_metrics(data: MetricsData) -> ExportMetricsServiceRequest: - resource_metrics_dict = {} - - for resource_metrics in data.resource_metrics: - _encode_resource_metrics(resource_metrics, resource_metrics_dict) - - resource_data = [] - for ( - sdk_resource, - scope_data, - ) in resource_metrics_dict.items(): - resource_data.append( - pb2.ResourceMetrics( - resource=PB2Resource(attributes=_encode_attributes(sdk_resource.attributes)), - scope_metrics=scope_data.values(), - schema_url=sdk_resource.schema_url, - ) - ) - return ExportMetricsServiceRequest(resource_metrics=resource_data) - - -def _encode_resource_metrics(resource_metrics, resource_metrics_dict): - resource = resource_metrics.resource - # It is safe to assume that each entry in data.resource_metrics is - # associated with an unique resource. - scope_metrics_dict = {} - resource_metrics_dict[resource] = scope_metrics_dict - for scope_metrics in resource_metrics.scope_metrics: - instrumentation_scope = scope_metrics.scope - - # The SDK groups metrics in instrumentation scopes already so - # there is no need to check for existing instrumentation scopes - # here. - pb2_scope_metrics = pb2.ScopeMetrics( - scope=_encode_instrumentation_scope(instrumentation_scope), - schema_url=instrumentation_scope.schema_url, - ) - - scope_metrics_dict[instrumentation_scope] = pb2_scope_metrics - - for metric in scope_metrics.metrics: - pb2_metric = pb2.Metric( - name=metric.name, - description=metric.description, - unit=metric.unit, - ) - - try: - _encode_metric(metric, pb2_metric) - except Exception as ex: - # `from None` so we don't get "During handling of the above exception, another exception occurred:" - raise EncodingException(ex, metric) from None - - pb2_scope_metrics.metrics.append(pb2_metric) - - -def _encode_metric(metric, pb2_metric): - if isinstance(metric.data, Gauge): - for data_point in metric.data.data_points: - pt = pb2.NumberDataPoint( - attributes=_encode_attributes(data_point.attributes), - time_unix_nano=data_point.time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - ) - if isinstance(data_point.value, int): - pt.as_int = data_point.value - else: - pt.as_double = data_point.value - pb2_metric.gauge.data_points.append(pt) - - elif isinstance(metric.data, HistogramType): - for data_point in metric.data.data_points: - pt = pb2.HistogramDataPoint( - attributes=_encode_attributes(data_point.attributes), - time_unix_nano=data_point.time_unix_nano, - start_time_unix_nano=data_point.start_time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - count=data_point.count, - sum=data_point.sum, - bucket_counts=data_point.bucket_counts, - explicit_bounds=data_point.explicit_bounds, - max=data_point.max, - min=data_point.min, - ) - pb2_metric.histogram.aggregation_temporality = metric.data.aggregation_temporality - pb2_metric.histogram.data_points.append(pt) - - elif isinstance(metric.data, Sum): - for data_point in metric.data.data_points: - pt = pb2.NumberDataPoint( - attributes=_encode_attributes(data_point.attributes), - start_time_unix_nano=data_point.start_time_unix_nano, - time_unix_nano=data_point.time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - ) - if isinstance(data_point.value, int): - pt.as_int = data_point.value - else: - pt.as_double = data_point.value - # note that because sum is a message type, the - # fields must be set individually rather than - # instantiating a pb2.Sum and setting it once - pb2_metric.sum.aggregation_temporality = metric.data.aggregation_temporality - pb2_metric.sum.is_monotonic = metric.data.is_monotonic - pb2_metric.sum.data_points.append(pt) - - elif isinstance(metric.data, ExponentialHistogramType): - for data_point in metric.data.data_points: - if data_point.positive.bucket_counts: - positive = pb2.ExponentialHistogramDataPoint.Buckets( - offset=data_point.positive.offset, - bucket_counts=data_point.positive.bucket_counts, - ) - else: - positive = None - - if data_point.negative.bucket_counts: - negative = pb2.ExponentialHistogramDataPoint.Buckets( - offset=data_point.negative.offset, - bucket_counts=data_point.negative.bucket_counts, - ) - else: - negative = None - - pt = pb2.ExponentialHistogramDataPoint( - attributes=_encode_attributes(data_point.attributes), - time_unix_nano=data_point.time_unix_nano, - start_time_unix_nano=data_point.start_time_unix_nano, - exemplars=_encode_exemplars(data_point.exemplars), - count=data_point.count, - sum=data_point.sum, - scale=data_point.scale, - zero_count=data_point.zero_count, - positive=positive, - negative=negative, - flags=data_point.flags, - max=data_point.max, - min=data_point.min, - ) - pb2_metric.exponential_histogram.aggregation_temporality = metric.data.aggregation_temporality - pb2_metric.exponential_histogram.data_points.append(pt) - - else: - _logger.warning( - "unsupported data type %s", - metric.data.__class__.__name__, - ) - - -def _encode_exemplars(sdk_exemplars: list[Exemplar]) -> list[pb2.Exemplar]: - """ - Converts a list of SDK Exemplars into a list of protobuf Exemplars. - - Args: - sdk_exemplars (list): The list of exemplars from the OpenTelemetry SDK. - - Returns: - list: A list of protobuf exemplars. - """ - pb_exemplars = [] - for sdk_exemplar in sdk_exemplars: - if sdk_exemplar.span_id is not None and sdk_exemplar.trace_id is not None: - pb_exemplar = pb2.Exemplar( - time_unix_nano=sdk_exemplar.time_unix_nano, - span_id=_encode_span_id(sdk_exemplar.span_id), - trace_id=_encode_trace_id(sdk_exemplar.trace_id), - filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), - ) - else: - pb_exemplar = pb2.Exemplar( - time_unix_nano=sdk_exemplar.time_unix_nano, - filtered_attributes=_encode_attributes(sdk_exemplar.filtered_attributes), - ) - - # Assign the value based on its type in the SDK exemplar - if isinstance(sdk_exemplar.value, float): - pb_exemplar.as_double = sdk_exemplar.value - elif isinstance(sdk_exemplar.value, int): - pb_exemplar.as_int = sdk_exemplar.value - else: - raise ValueError("Exemplar value must be an int or float") - pb_exemplars.append(pb_exemplar) - - return pb_exemplars diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py deleted file mode 100644 index 48bdb23bf34..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_internal/trace_encoder/__init__.py +++ /dev/null @@ -1,175 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -from collections import defaultdict -from collections.abc import Sequence - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( - _encode_attributes, - _encode_instrumentation_scope, - _encode_resource, - _encode_span_id, - _encode_trace_id, -) -from opentelemetry.agent._vendor.opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ( - ExportTraceServiceRequest as PB2ExportTraceServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( - ResourceSpans as PB2ResourceSpans, -) -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ScopeSpans as PB2ScopeSpans -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import Span as PB2SPan -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import SpanFlags as PB2SpanFlags -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import Status as PB2Status -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Event, ReadableSpan -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind -from opentelemetry.agent._vendor.opentelemetry.trace.span import SpanContext, Status, TraceState - -# pylint: disable=E1101 -_SPAN_KIND_MAP = { - SpanKind.INTERNAL: PB2SPan.SpanKind.SPAN_KIND_INTERNAL, - SpanKind.SERVER: PB2SPan.SpanKind.SPAN_KIND_SERVER, - SpanKind.CLIENT: PB2SPan.SpanKind.SPAN_KIND_CLIENT, - SpanKind.PRODUCER: PB2SPan.SpanKind.SPAN_KIND_PRODUCER, - SpanKind.CONSUMER: PB2SPan.SpanKind.SPAN_KIND_CONSUMER, -} - -_logger = logging.getLogger(__name__) - - -def encode_spans( - sdk_spans: Sequence[ReadableSpan], -) -> PB2ExportTraceServiceRequest: - return PB2ExportTraceServiceRequest(resource_spans=_encode_resource_spans(sdk_spans)) - - -def _encode_resource_spans( - sdk_spans: Sequence[ReadableSpan], -) -> list[PB2ResourceSpans]: - # We need to inspect the spans and group + structure them as: - # - # Resource - # Instrumentation Library - # Spans - # - # First loop organizes the SDK spans in this structure. Protobuf messages - # are not hashable so we stick with SDK data in this phase. - # - # Second loop encodes the data into Protobuf format. - # - sdk_resource_spans = defaultdict(lambda: defaultdict(list)) - - for sdk_span in sdk_spans: - sdk_resource = sdk_span.resource - sdk_instrumentation = sdk_span.instrumentation_scope or None - pb2_span = _encode_span(sdk_span) - - sdk_resource_spans[sdk_resource][sdk_instrumentation].append(pb2_span) - - pb2_resource_spans = [] - - for sdk_resource, sdk_instrumentations in sdk_resource_spans.items(): - scope_spans = [] - for sdk_instrumentation, pb2_spans in sdk_instrumentations.items(): - scope_spans.append( - PB2ScopeSpans( - scope=(_encode_instrumentation_scope(sdk_instrumentation)), - spans=pb2_spans, - schema_url=sdk_instrumentation.schema_url if sdk_instrumentation else None, - ) - ) - pb2_resource_spans.append( - PB2ResourceSpans( - resource=_encode_resource(sdk_resource), - scope_spans=scope_spans, - schema_url=sdk_resource.schema_url, - ) - ) - - return pb2_resource_spans - - -def _span_flags(parent_span_context: SpanContext | None) -> int: - flags = PB2SpanFlags.SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK - if parent_span_context and parent_span_context.is_remote: - flags |= PB2SpanFlags.SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK - return flags - - -def _encode_span(sdk_span: ReadableSpan) -> PB2SPan: - span_context = sdk_span.get_span_context() - return PB2SPan( - trace_id=_encode_trace_id(span_context.trace_id), - span_id=_encode_span_id(span_context.span_id), - trace_state=_encode_trace_state(span_context.trace_state), - parent_span_id=_encode_parent_id(sdk_span.parent), - name=sdk_span.name, - kind=_SPAN_KIND_MAP[sdk_span.kind], - start_time_unix_nano=sdk_span.start_time, - end_time_unix_nano=sdk_span.end_time, - attributes=_encode_attributes(sdk_span.attributes), - events=_encode_events(sdk_span.events), - links=_encode_links(sdk_span.links), - status=_encode_status(sdk_span.status), - dropped_attributes_count=sdk_span.dropped_attributes, - dropped_events_count=sdk_span.dropped_events, - dropped_links_count=sdk_span.dropped_links, - flags=_span_flags(sdk_span.parent), - ) - - -def _encode_events( - events: Sequence[Event], -) -> list[PB2SPan.Event] | None: - pb2_events = None - if events: - pb2_events = [] - for event in events: - encoded_event = PB2SPan.Event( - name=event.name, - time_unix_nano=event.timestamp, - attributes=_encode_attributes(event.attributes), - dropped_attributes_count=event.dropped_attributes, - ) - pb2_events.append(encoded_event) - return pb2_events - - -def _encode_links(links: Sequence[Link]) -> Sequence[PB2SPan.Link]: - pb2_links = None - if links: - pb2_links = [] - for link in links: - encoded_link = PB2SPan.Link( - trace_id=_encode_trace_id(link.context.trace_id), - span_id=_encode_span_id(link.context.span_id), - attributes=_encode_attributes(link.attributes), - dropped_attributes_count=link.dropped_attributes, - flags=_span_flags(link.context), - ) - pb2_links.append(encoded_link) - return pb2_links - - -def _encode_status(status: Status) -> PB2Status | None: - pb2_status = None - if status is not None: - pb2_status = PB2Status( - code=status.status_code.value, - message=status.description, - ) - return pb2_status - - -def _encode_trace_state(trace_state: TraceState) -> str | None: - pb2_trace_state = None - if trace_state is not None: - pb2_trace_state = ",".join([f"{key}={value}" for key, value in (trace_state.items())]) - return pb2_trace_state - - -def _encode_parent_id(context: SpanContext | None) -> bytes | None: - if context: - return _encode_span_id(context.span_id) - return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py deleted file mode 100644 index 51463b90b19..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/_log_encoder.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal._log_encoder import ( - encode_logs, -) - -__all__ = ["encode_logs"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py deleted file mode 100644 index 79bd0d4d27a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/metrics_encoder.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal.metrics_encoder import ( - encode_metrics, -) - -__all__ = ["encode_metrics"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py deleted file mode 100644 index b8b5b90024d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/trace_encoder.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal.trace_encoder import ( - encode_spans, -) - -__all__ = ["encode_spans"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py deleted file mode 100644 index 0101c361616..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/common/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py deleted file mode 100644 index 69f51ec0557..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/__init__.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -""" -This library allows to export tracing data to an OTLP collector. - -Usage ------ - -The **OTLP Span Exporter** allows to export `OpenTelemetry`_ traces to the -`OTLP`_ collector. - -You can configure the exporter with the following environment variables: - -- :envvar:`OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` -- :envvar:`OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` -- :envvar:`OTEL_EXPORTER_OTLP_TRACES_HEADERS` -- :envvar:`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` -- :envvar:`OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` -- :envvar:`OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` -- :envvar:`OTEL_EXPORTER_OTLP_TIMEOUT` -- :envvar:`OTEL_EXPORTER_OTLP_PROTOCOL` -- :envvar:`OTEL_EXPORTER_OTLP_HEADERS` -- :envvar:`OTEL_EXPORTER_OTLP_ENDPOINT` -- :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` -- :envvar:`OTEL_EXPORTER_OTLP_CERTIFICATE` - -.. _OTLP: https://github.com/open-telemetry/opentelemetry-collector/ -.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ - -.. code:: python - - from opentelemetry import trace - from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter - from opentelemetry.sdk.resources import Resource - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import BatchSpanProcessor - - # Resource can be required for some backends, e.g. Jaeger - # If resource wouldn't be set - traces wouldn't appears in Jaeger - resource = Resource.create({ - "service.name": "service" - }) - - trace.set_tracer_provider(TracerProvider(resource=resource)) - tracer = trace.get_tracer(__name__) - - otlp_exporter = OTLPSpanExporter() - - span_processor = BatchSpanProcessor(otlp_exporter) - - trace.get_tracer_provider().add_span_processor(span_processor) - - with tracer.start_as_current_span("foo"): - print("Hello world!") - -API ---- -""" - -import enum - -from .version import __version__ - -_OTLP_HTTP_HEADERS = { - "Content-Type": "application/x-protobuf", - "User-Agent": "OTel-OTLP-Exporter-Python/" + __version__, -} - - -class Compression(enum.Enum): - NoCompression = "none" - Deflate = "deflate" - Gzip = "gzip" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py deleted file mode 100644 index a2e87b1a353..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_common/__init__.py +++ /dev/null @@ -1,211 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -import os -from collections.abc import Mapping -from os import environ -from typing import TYPE_CHECKING, Literal - -from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._requests import ( - RequestsHTTPTransport, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import ( - _OTLP_HTTP_HEADERS, - Compression, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - _OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER, - OTEL_EXPORTER_OTLP_CERTIFICATE, - OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_CLIENT_KEY, - OTEL_EXPORTER_OTLP_COMPRESSION, - OTEL_EXPORTER_OTLP_ENDPOINT, - OTEL_EXPORTER_OTLP_HEADERS, - OTEL_EXPORTER_OTLP_TIMEOUT, -) -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points -from opentelemetry.agent._vendor.opentelemetry.util.re import parse_env_headers - -if TYPE_CHECKING: - from opentelemetry.agent._vendor import requests - - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport - - _CredentialEnvVar = Literal[ - "OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER", - "OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER", - "OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER", - ] - -_logger = logging.getLogger(__name__) - -_DEFAULT_ENDPOINT = "http://localhost:4318" -_DEFAULT_TIMEOUT = 10 - -# 64 MiB, in bytes. -_DEFAULT_MAX_REQUEST_SIZE = 64 * 1024 * 1024 - - -class RequestPayloadTooLargeError(Exception): - """A serialized OTLP request exceeded the configured ``max_request_size``. - - The class name is emitted as the ``error.type`` attribute on the exporter's - failed-export metric, so renaming it changes observable telemetry. - """ - - -def _is_request_too_large(serialized_data: bytes, max_request_size: int) -> bool: - """Return True if the serialized request exceeds a positive size limit. - - The size is measured on the uncompressed serialized request, matching the - OTLP specification's "before compression" request-size limit. A - ``max_request_size`` of ``0`` (or any non-positive value) disables the - check. - """ - return 0 < max_request_size < len(serialized_data) - - -def _load_session_from_envvar( - cred_envvar: _CredentialEnvVar, -) -> requests.Session | None: - _credential_env = environ.get(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER) or environ.get(cred_envvar) - if _credential_env: - try: - # pylint: disable-next=import-outside-toplevel - from opentelemetry.agent._vendor import requests # noqa: PLC0415 - except ImportError as exc: - raise ImportError( - "The 'requests' package is required to load a credential " - "provider session but is not installed. Install it with " - "`pip install requests`." - ) from exc - - try: - maybe_session = next( - iter( - entry_points( - group="opentelemetry_otlp_credential_provider", - name=_credential_env, - ) - ) - ).load()() - except StopIteration: - raise RuntimeError( - f"Requested component '{_credential_env}' not found in " - f"entry point 'opentelemetry_otlp_credential_provider'" - ) - if isinstance(maybe_session, requests.Session): - return maybe_session - else: - raise RuntimeError( - f"Requested component '{_credential_env}' is of type {type(maybe_session)}" - f" must be of type `requests.Session`." - ) - return None - - -def _normalize_compression( - compression: Compression | _http.Compression | None, -) -> _http.Compression | None: - match compression: - case Compression.NoCompression: - return _http.Compression.NONE - case Compression.Deflate: - return _http.Compression.DEFLATE - case Compression.Gzip: - return _http.Compression.GZIP - case _: - return compression - - -def _resolve_endpoint( - endpoint_env_var: str, - default_path: Literal["v1/traces", "v1/metrics", "v1/logs"], -) -> str: - if endpoint := os.environ.get(endpoint_env_var): - return endpoint - - base_endpoint = os.environ.get(OTEL_EXPORTER_OTLP_ENDPOINT) or _DEFAULT_ENDPOINT - - return f"{base_endpoint.removesuffix('/')}/{default_path}" - - -def _resolve_headers( - headers: Mapping[str, str] | None, - headers_env_var: str, -) -> dict[str, str]: - headers_ = {k.lower(): v for k, v in _OTLP_HTTP_HEADERS.items()} - env_headers = parse_env_headers( - os.environ.get(headers_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), - liberal=True, - ) - headers_.update(env_headers) - if headers: - headers_.update({key.lower(): value for key, value in headers.items()}) - return headers_ - - -def _resolve_timeout( - timeout_env_var: str, -) -> float: - raw = os.environ.get(timeout_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_TIMEOUT) or _DEFAULT_TIMEOUT - - try: - return float(raw) - except ValueError: - _logger.warning( - "Invalid timeout value %r, using default of %s seconds", - raw, - _DEFAULT_TIMEOUT, - ) - return float(_DEFAULT_TIMEOUT) - - -def _resolve_compression(compression_env_var: str) -> _http.Compression: - value = ( - (os.environ.get(compression_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_COMPRESSION) or "none") - .lower() - .strip() - ) - - try: - return _http.Compression.from_str(value) - except ValueError: - _logger.warning("Unsupported compression type: %s", value) - return _http.Compression.NONE - - -def _build_transport( - certificate_file: str | None, - client_key_file: str | None, - client_certificate_file: str | None, - certificate_env_var: str, - client_key_env_var: str, - client_certificate_env_var: str, - session: requests.Session | None, -) -> BaseHTTPTransport: - verify: bool | str = ( - certificate_file - or os.environ.get(certificate_env_var) - or os.environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE) - or True - ) - client_key_file = ( - client_key_file or os.environ.get(client_key_env_var) or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_KEY) - ) - client_certificate_file = ( - client_certificate_file - or os.environ.get(client_certificate_env_var) - or os.environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE) - ) - cert = ( - (client_certificate_file, client_key_file) - if client_certificate_file and client_key_file - else client_certificate_file - ) - - return RequestsHTTPTransport(verify=verify, cert=cert, session=session) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py deleted file mode 100644 index bbc80a740a4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -import os -from collections.abc import Mapping, Sequence -from typing import TYPE_CHECKING, overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._exporter_metrics import ( - create_exporter_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._log_encoder import encode_logs -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import Compression -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._common import ( - _DEFAULT_MAX_REQUEST_SIZE, - RequestPayloadTooLargeError, - _build_transport, - _is_request_too_large, - _load_session_from_envvar, - _normalize_compression, - _resolve_compression, - _resolve_endpoint, - _resolve_headers, - _resolve_timeout, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord -from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( - LogRecordExporter, - LogRecordExportResult, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import DuplicateFilter -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - _OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER, - OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, - OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, - OTEL_EXPORTER_OTLP_LOGS_HEADERS, - OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OtelComponentTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( - HTTP_RESPONSE_STATUS_CODE, -) - -if TYPE_CHECKING: - from opentelemetry.agent._vendor import requests - - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport - -_logger = logging.getLogger(__name__) -# This prevents logs generated when a log fails to be written to generate another log which fails to be written etc. etc. -_logger.addFilter(DuplicateFilter()) - - -DEFAULT_COMPRESSION = Compression.NoCompression -DEFAULT_ENDPOINT = "http://localhost:4318/" -DEFAULT_LOGS_EXPORT_PATH = "v1/logs" -DEFAULT_TIMEOUT = 10 # in seconds - - -class OTLPLogExporter(LogRecordExporter): - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - ) -> None: ... - - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: None = None, - client_key_file: None = None, - client_certificate_file: None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - _transport: BaseHTTPTransport, - ) -> None: ... - - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - _transport: BaseHTTPTransport | None = None, - ) -> None: - """OTLP HTTP log exporter. - - Args: - endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal - path. Example: ``http://collector:4318/v1/logs``. For a base URL without a - signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. - certificate_file: Path to the CA certificate file for TLS. - client_key_file: Path to the client key file for mTLS. - client_certificate_file: Path to the client certificate file for mTLS. - headers: Headers to send with each export request. - timeout: Timeout in seconds for each export request. - compression: Compression to use; one of none, gzip, deflate. - session: Requests session to use at export. - max_request_size: Maximum size in bytes of a serialized request, - measured before compression. A request exceeding this size is - dropped before being sent. Defaults to 64 MiB; a value of 0 (or - any non-positive value) disables the limit. Batch processors - group log records by count rather than serialized size, so a - batch whose serialized request exceeds this limit is dropped as - a whole and recorded as a failed export; reduce the processor's - ``max_export_batch_size`` (or raise/disable this limit) if - batches may approach it. - meter_provider: MeterProvider used for the exporter's own metrics. - """ - self._endpoint = endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, DEFAULT_LOGS_EXPORT_PATH) - self._compression = _normalize_compression(compression) or _resolve_compression( - OTEL_EXPORTER_OTLP_LOGS_COMPRESSION - ) - transport = _transport or _build_transport( - certificate_file, - client_key_file, - client_certificate_file, - OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, - session=session or _load_session_from_envvar(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER), - ) - self._max_request_size = _DEFAULT_MAX_REQUEST_SIZE if max_request_size is None else max_request_size - self._client = _http._OTLPHTTPClient( - transport=transport, - endpoint=self._endpoint, - kind="logs", - timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT), - compression=self._compression, - headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_LOGS_HEADERS), - logger=_logger, - ) - self._shutdown = False - - self._metrics = create_exporter_metrics( - OtelComponentTypeValues.OTLP_HTTP_LOG_EXPORTER, - "logs", - self._endpoint, - meter_provider, - os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", - ) - - def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring batch") - return LogRecordExportResult.FAILURE - - with self._metrics.export_operation(len(batch)) as result: - try: - serialized_data = encode_logs(batch).SerializeToString() - # pylint: disable-next=broad-exception-caught - except Exception as error: - _logger.error("Failed to encode logs batch: %s", error) - result.error = error - return LogRecordExportResult.FAILURE - - if _is_request_too_large(serialized_data, self._max_request_size): - _logger.warning( - "Dropping logs batch: serialized size %d bytes exceeds max_request_size %d bytes.", - len(serialized_data), - self._max_request_size, - ) - result.error = RequestPayloadTooLargeError( - f"Serialized logs request size {len(serialized_data)} " - f"bytes exceeds max_request_size " - f"{self._max_request_size} bytes." - ) - return LogRecordExportResult.FAILURE - - export_result = self._client.export(serialized_data) - if not export_result.success: - result.error = export_result.error - result.error_attrs = ( - {HTTP_RESPONSE_STATUS_CODE: export_result.status_code} - if export_result.status_code is not None - else None - ) - return LogRecordExportResult.FAILURE - return LogRecordExportResult.SUCCESS - - def force_flush(self, timeout_millis: int = 10_000) -> bool: - """Nothing is buffered in this exporter, so this method does nothing.""" - return True - - def shutdown(self): - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring call") - return - self._shutdown = True - self._client.shutdown() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py deleted file mode 100644 index 2e8fa2c1ef0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py +++ /dev/null @@ -1,611 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import logging -import os -from collections.abc import Callable, Iterable, Mapping -from typing import ( # noqa: F401 - TYPE_CHECKING, - Any, - Optional, - overload, -) - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._aggregation import ( - _get_aggregation, - _get_temporality, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._exporter_metrics import ( - create_exporter_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common._internal import ( - _get_resource_data, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common.metrics_encoder import ( - encode_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import Compression -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._common import ( - _DEFAULT_MAX_REQUEST_SIZE, - RequestPayloadTooLargeError, - _build_transport, - _is_request_too_large, - _load_session_from_envvar, - _normalize_compression, - _resolve_compression, - _resolve_endpoint, - _resolve_headers, - _resolve_timeout, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider -from opentelemetry.agent._vendor.opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( - ExportMetricsServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 - AnyValue, - ArrayValue, - InstrumentationScope, - KeyValue, - KeyValueList, -) -from opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2 -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import Resource # noqa: F401 -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( - Resource as PB2Resource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - _OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER, - OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, - OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, - OTEL_EXPORTER_OTLP_METRICS_HEADERS, - OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import Aggregation -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( # noqa: F401 - AggregationTemporality, - Gauge, - MetricExporter, - MetricExportResult, - MetricsData, - Sum, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( # noqa: F401 - Histogram as HistogramType, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource as SDKResource -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OtelComponentTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( - HTTP_RESPONSE_STATUS_CODE, -) - -if TYPE_CHECKING: - from opentelemetry.agent._vendor import requests - - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport - -_logger = logging.getLogger(__name__) - - -DEFAULT_COMPRESSION = Compression.NoCompression -DEFAULT_ENDPOINT = "http://localhost:4318/" -DEFAULT_METRICS_EXPORT_PATH = "v1/metrics" -DEFAULT_TIMEOUT = 10 # in seconds - - -class OTLPMetricExporter(MetricExporter): - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - max_export_batch_size: int | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - ) -> None: ... - - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: None = None, - client_key_file: None = None, - client_certificate_file: None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - max_export_batch_size: int | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - _transport: BaseHTTPTransport, - ) -> None: ... - - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, Aggregation] | None = None, - max_export_batch_size: int | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - _transport: BaseHTTPTransport | None = None, - ) -> None: - """OTLP HTTP metrics exporter - - Args: - endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal - path. Example: ``http://collector:4318/v1/metrics``. For a base URL without a - signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. - certificate_file: Path to the certificate file to use for any TLS - client_key_file: Path to the client key file to use for any TLS - client_certificate_file: Path to the client certificate file to use for any TLS - headers: Headers to be sent with HTTP requests at export - timeout: Timeout in seconds for export - compression: Compression to use; one of none, gzip, deflate - session: Requests session to use at export - preferred_temporality: Map of preferred temporality for each metric type. - See `opentelemetry.sdk.metrics.export.MetricReader` for more details on what - preferred temporality is. - preferred_aggregation: Map of preferred aggregation for each metric type. - See `opentelemetry.sdk.metrics.export.MetricReader` for more details on what - preferred aggregation is. - max_export_batch_size: Maximum number of data points to export in a single request. - If not set there is no limit to the number of data points in a request. - If it is set and the number of data points exceeds the max, the request will be split. - max_request_size: Maximum size in bytes of a serialized request, measured before - compression. A request exceeding this size is dropped before being sent. Defaults - to 64 MiB; a value of 0 (or any non-positive value) disables the limit. Requests - are sized after any ``max_export_batch_size`` splitting; a batch whose serialized - request still exceeds this limit is dropped as a whole and recorded as a failed - export. Reduce ``max_export_batch_size`` (or raise/disable this limit) if batches - may approach it. - meter_provider: MeterProvider used for the exporter's own metrics. - """ - MetricExporter.__init__( - self, - preferred_temporality=_get_temporality(preferred_temporality), - preferred_aggregation=_get_aggregation(preferred_aggregation), - ) - self._endpoint = endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, DEFAULT_METRICS_EXPORT_PATH) - self._compression = _normalize_compression(compression) or _resolve_compression( - OTEL_EXPORTER_OTLP_METRICS_COMPRESSION - ) - transport = _transport or _build_transport( - certificate_file, - client_key_file, - client_certificate_file, - OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, - OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, - session=session or _load_session_from_envvar(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER), - ) - self._client = _http._OTLPHTTPClient( - transport=transport, - endpoint=self._endpoint, - kind="metrics", - timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_METRICS_TIMEOUT), - compression=self._compression, - headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_METRICS_HEADERS), - logger=_logger, - ) - self._max_export_batch_size: int | None = max_export_batch_size - self._max_request_size = _DEFAULT_MAX_REQUEST_SIZE if max_request_size is None else max_request_size - self._shutdown = False - - self._metrics = create_exporter_metrics( - OtelComponentTypeValues.OTLP_HTTP_METRIC_EXPORTER, - "metrics", - self._endpoint, - meter_provider, - os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", - ) - - def _export_batch( - self, - export_request: ExportMetricsServiceRequest, - ) -> MetricExportResult: - with self._metrics.export_operation(_count_data_points(export_request)) as result: - serialized_data = export_request.SerializeToString() - if _is_request_too_large(serialized_data, self._max_request_size): - _logger.warning( - "Dropping metrics batch: serialized size %d bytes exceeds max_request_size %d bytes.", - len(serialized_data), - self._max_request_size, - ) - result.error = RequestPayloadTooLargeError( - f"Serialized metrics request size {len(serialized_data)} " - f"bytes exceeds max_request_size " - f"{self._max_request_size} bytes." - ) - return MetricExportResult.FAILURE - export_result = self._client.export(serialized_data) - if not export_result.success: - result.error = export_result.error - result.error_attrs = ( - {HTTP_RESPONSE_STATUS_CODE: export_result.status_code} - if export_result.status_code is not None - else None - ) - return MetricExportResult.FAILURE - return MetricExportResult.SUCCESS - - def export( - self, - metrics_data: MetricsData, - timeout_millis: float | None = 10000, - **kwargs, - ) -> MetricExportResult: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring batch") - return MetricExportResult.FAILURE - - try: - export_request = encode_metrics(metrics_data) - # pylint: disable-next=broad-exception-caught - except Exception as error: - _logger.error("Failed to encode metrics batch: %s", error) - return MetricExportResult.FAILURE - - # If no batch size configured, export as single batch with retries as configured - if self._max_export_batch_size is None: - return self._export_batch(export_request) - - for batch in _split_metrics_data(export_request, self._max_export_batch_size): - export_result = self._export_batch(batch) - if export_result != MetricExportResult.SUCCESS: - return MetricExportResult.FAILURE - - # Only returns SUCCESS if all batches succeeded - return MetricExportResult.SUCCESS - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring call") - return - self._shutdown = True - self._client.shutdown() - - def force_flush(self, timeout_millis: float = 10_000) -> bool: - """Nothing is buffered in this exporter, so this method does nothing.""" - return True - - def set_meter_provider(self, meter_provider: MeterProvider) -> None: - self._metrics = create_exporter_metrics( - OtelComponentTypeValues.OTLP_HTTP_METRIC_EXPORTER, - "metrics", - self._endpoint, - meter_provider, - os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", - ) - - -def _count_data_points(export_request: ExportMetricsServiceRequest) -> int: - """Count the number of data points in an encoded metrics export request.""" - count = 0 - for resource_metrics in export_request.resource_metrics: - for scope_metrics in resource_metrics.scope_metrics: - for metric in scope_metrics.metrics: - field_name = metric.WhichOneof("data") - if field_name: - count += len(getattr(metric, field_name).data_points) - return count - - -def _split_metrics_data( - metrics_data: ExportMetricsServiceRequest, - max_export_batch_size: int | None = None, -) -> Iterable[ExportMetricsServiceRequest]: - """Splits metrics data into several ExportMetricsServiceRequest (copies protobuf originals), - based on configured data point max export batch size. - - Args: - metrics_data: metrics object based on HTTP protocol buffer definition - - Returns: - Iterable[ExportMetricsServiceRequest]: An iterable of ExportMetricsServiceRequest objects containing - ExportMetricsServiceRequest.ResourceMetrics, ExportMetricsServiceRequest.ScopeMetrics, ExportMetricsServiceRequest.Metrics, and data points - """ - if not max_export_batch_size: - return metrics_data - - batch_size: int = 0 - # Stores split metrics data as editable references - # used to write batched pb2 objects for export when finalized - split_resource_metrics = [] - - for resource_metrics in metrics_data.resource_metrics: - split_scope_metrics = [] - split_resource_metrics.append( - { - "resource": resource_metrics.resource, - "schema_url": resource_metrics.schema_url, - "scope_metrics": split_scope_metrics, - } - ) - - for scope_metrics in resource_metrics.scope_metrics: - split_metrics = [] - split_scope_metrics.append( - { - "scope": scope_metrics.scope, - "schema_url": scope_metrics.schema_url, - "metrics": split_metrics, - } - ) - - for metric in scope_metrics.metrics: - split_data_points = [] - field_name = metric.WhichOneof("data") - if not field_name: - _logger.warning("Tried to split and export an unsupported metric type. Skipping.") - continue - - # Get data container using field name - # and build metric dictionary dynamically for conciseness - data_container = getattr(metric, field_name) - metric_dict = { - "name": metric.name, - "description": metric.description, - "unit": metric.unit, - field_name: { - "data_points": split_data_points, - }, - } - if hasattr(data_container, "aggregation_temporality"): - metric_dict[field_name]["aggregation_temporality"] = data_container.aggregation_temporality - if hasattr(data_container, "is_monotonic"): - metric_dict[field_name]["is_monotonic"] = data_container.is_monotonic - split_metrics.append(metric_dict) - - current_data_points = data_container.data_points - for data_point in current_data_points: - split_data_points.append(data_point) - batch_size += 1 - - if batch_size >= max_export_batch_size: - yield ExportMetricsServiceRequest( - resource_metrics=_get_split_resource_metrics_pb2(split_resource_metrics) - ) - - # Reset all the reference variables with current metrics_data position - # minus yielded data_points. Need to clear data_points and keep metric - # to avoid duplicate data_point export - batch_size = 0 - split_data_points = [] - - # Rebuild metric dict generically using same approach as initial creation - field_name = metric.WhichOneof("data") - if field_name is None: - _logger.warning("Tried to split and export an unsupported metric type. Skipping.") - continue - data_container = getattr(metric, field_name) - metric_dict = { - "name": metric.name, - "description": metric.description, - "unit": metric.unit, - field_name: { - "data_points": split_data_points, - }, - } - if hasattr(data_container, "aggregation_temporality"): - metric_dict[field_name]["aggregation_temporality"] = data_container.aggregation_temporality - if hasattr(data_container, "is_monotonic"): - metric_dict[field_name]["is_monotonic"] = data_container.is_monotonic - - split_metrics = [metric_dict] - split_scope_metrics = [ - { - "scope": scope_metrics.scope, - "schema_url": scope_metrics.schema_url, - "metrics": split_metrics, - } - ] - split_resource_metrics = [ - { - "resource": resource_metrics.resource, - "schema_url": resource_metrics.schema_url, - "scope_metrics": split_scope_metrics, - } - ] - - if not split_data_points: - # If data_points is empty remove the whole metric - split_metrics.pop() - - if not split_metrics: - # If metrics is empty remove the whole scope_metrics - split_scope_metrics.pop() - - if not split_scope_metrics: - # If scope_metrics is empty remove the whole resource_metrics - split_resource_metrics.pop() - - if batch_size > 0: - yield ExportMetricsServiceRequest(resource_metrics=_get_split_resource_metrics_pb2(split_resource_metrics)) - - -def _get_split_resource_metrics_pb2( - split_resource_metrics: list[dict], -) -> list[pb2.ResourceMetrics]: - """Helper that returns a list of pb2.ResourceMetrics objects based on split_resource_metrics. - Example input: - - ```python - [ - { - "resource": , - "schema_url": "http://foo-bar", - "scope_metrics": [ - "scope": , - "schema_url": "http://foo-baz", - "metrics": [ - { - "name": "apples", - "description": "number of apples purchased", - "sum": { - "aggregation_temporality": 1, - "is_monotonic": "false", - "data_points": [ - { - start_time_unix_nano: 1000 - time_unix_nano: 1001 - exemplars { - time_unix_nano: 1002 - span_id: "foo-span" - trace_id: "foo-trace" - as_int: 5 - } - as_int: 5 - } - ] - } - }, - ], - ], - }, - ] - ``` - - Args: - split_resource_metrics: A list of dict representations of ResourceMetrics, - ScopeMetrics, Metrics, and data points. - - Returns: - List[pb2.ResourceMetrics]: A list of pb2.ResourceMetrics objects containing - pb2.ScopeMetrics, pb2.Metrics, and data points - """ - split_resource_metrics_pb = [] - for resource_metrics in split_resource_metrics: - new_resource_metrics = pb2.ResourceMetrics( - resource=resource_metrics.get("resource"), - scope_metrics=[], - schema_url=resource_metrics.get("schema_url") or "", - ) - for scope_metrics in resource_metrics.get("scope_metrics", []): - new_scope_metrics = pb2.ScopeMetrics( - scope=scope_metrics.get("scope"), - metrics=[], - schema_url=scope_metrics.get("schema_url") or "", - ) - - for metric in scope_metrics.get("metrics", []): - new_metric = None - data_points = [] - - if "sum" in metric: - new_metric = pb2.Metric( - name=metric.get("name"), - description=metric.get("description"), - unit=metric.get("unit"), - sum=pb2.Sum( - data_points=[], - aggregation_temporality=metric.get("sum").get("aggregation_temporality"), - is_monotonic=metric.get("sum").get("is_monotonic"), - ), - ) - data_points = metric.get("sum").get("data_points") - elif "histogram" in metric: - new_metric = pb2.Metric( - name=metric.get("name"), - description=metric.get("description"), - unit=metric.get("unit"), - histogram=pb2.Histogram( - data_points=[], - aggregation_temporality=metric.get("histogram").get("aggregation_temporality"), - ), - ) - data_points = metric.get("histogram").get("data_points") - elif "exponential_histogram" in metric: - new_metric = pb2.Metric( - name=metric.get("name"), - description=metric.get("description"), - unit=metric.get("unit"), - exponential_histogram=pb2.ExponentialHistogram( - data_points=[], - aggregation_temporality=metric.get("exponential_histogram").get("aggregation_temporality"), - ), - ) - data_points = metric.get("exponential_histogram").get("data_points") - elif "gauge" in metric: - new_metric = pb2.Metric( - name=metric.get("name"), - description=metric.get("description"), - unit=metric.get("unit"), - gauge=pb2.Gauge( - data_points=[], - ), - ) - data_points = metric.get("gauge").get("data_points") - elif "summary" in metric: - new_metric = pb2.Metric( - name=metric.get("name"), - description=metric.get("description"), - unit=metric.get("unit"), - summary=pb2.Summary( - data_points=[], - ), - ) - data_points = metric.get("summary").get("data_points") - else: - _logger.warning("Tried to split and export an unsupported metric type. Skipping.") - continue - - # Append data points generically using the field name from the metric dict - for field_name in [ - "sum", - "histogram", - "exponential_histogram", - "gauge", - "summary", - ]: - if field_name in metric: - metric_data_container = getattr(new_metric, field_name) - for data_point in data_points: - metric_data_container.data_points.append(data_point) - break - - new_scope_metrics.metrics.append(new_metric) - new_resource_metrics.scope_metrics.append(new_scope_metrics) - split_resource_metrics_pb.append(new_resource_metrics) - return split_resource_metrics_pb - - -@deprecated( - "Use one of the encoders from opentelemetry-exporter-otlp-proto-common instead. Deprecated since version 1.18.0.", -) -def get_resource_data( - sdk_resource_scope_data: dict[SDKResource, Any], # ResourceDataT? - resource_class: Callable[..., PB2Resource], - name: str, -) -> list[PB2Resource]: - return _get_resource_data(sdk_resource_scope_data, resource_class, name) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py deleted file mode 100644 index 0512e653120..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py +++ /dev/null @@ -1,219 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -import os -from collections.abc import Mapping, Sequence -from typing import TYPE_CHECKING, overload - -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common import http as _http -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.common._exporter_metrics import ( - create_exporter_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.common.trace_encoder import ( - encode_spans, -) -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http import Compression -from opentelemetry.agent._vendor.opentelemetry.exporter.otlp.proto.http._common import ( - _DEFAULT_MAX_REQUEST_SIZE, - RequestPayloadTooLargeError, - _build_transport, - _is_request_too_large, - _load_session_from_envvar, - _normalize_compression, - _resolve_compression, - _resolve_endpoint, - _resolve_headers, - _resolve_timeout, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - _OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER, - OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, - OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, - OTEL_EXPORTER_OTLP_TRACES_HEADERS, - OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OtelComponentTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( - HTTP_RESPONSE_STATUS_CODE, -) - -if TYPE_CHECKING: - from opentelemetry.agent._vendor import requests - - from opentelemetry.agent._vendor.opentelemetry.exporter.http.transport._base import BaseHTTPTransport - -_logger = logging.getLogger(__name__) - - -DEFAULT_COMPRESSION = Compression.NoCompression -DEFAULT_ENDPOINT = "http://localhost:4318/" -DEFAULT_TRACES_EXPORT_PATH = "v1/traces" -DEFAULT_TIMEOUT = 10 # in seconds - - -class OTLPSpanExporter(SpanExporter): - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - ) -> None: ... - - @overload - def __init__( - self, - endpoint: str | None = None, - certificate_file: None = None, - client_key_file: None = None, - client_certificate_file: None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - _transport: BaseHTTPTransport, - ) -> None: ... - - def __init__( - self, - endpoint: str | None = None, - certificate_file: str | None = None, - client_key_file: str | None = None, - client_certificate_file: str | None = None, - headers: Mapping[str, str] | None = None, - timeout: float | None = None, - compression: Compression | _http.Compression | None = None, - session: requests.Session | None = None, - *, - max_request_size: int | None = None, - meter_provider: MeterProvider | None = None, - _transport: BaseHTTPTransport | None = None, - ) -> None: - """OTLP HTTP span exporter. - - Args: - endpoint: Full URL of the OTLP/HTTP signal endpoint, including the signal - path. Example: ``http://collector:4318/v1/traces``. For a base URL without a - signal path, set the ``OTEL_EXPORTER_OTLP_ENDPOINT`` environment variable. - certificate_file: Path to the CA certificate file for TLS. - client_key_file: Path to the client key file for mTLS. - client_certificate_file: Path to the client certificate file for mTLS. - headers: Headers to send with each export request. - timeout: Timeout in seconds for each export request. - compression: Compression to use; one of none, gzip, deflate. - session: Requests session to use at export. - max_request_size: Maximum size in bytes of a serialized request, - measured before compression. A request exceeding this size is - dropped before being sent. Defaults to 64 MiB; a value of 0 (or - any non-positive value) disables the limit. Batch processors - group spans by count rather than serialized size, so a batch - whose serialized request exceeds this limit is dropped as a - whole and recorded as a failed export; reduce the processor's - ``max_export_batch_size`` (or raise/disable this limit) if - batches may approach it. - meter_provider: MeterProvider used for the exporter's own metrics. - """ - self._endpoint = endpoint or _resolve_endpoint(OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, DEFAULT_TRACES_EXPORT_PATH) - self._compression = _normalize_compression(compression) or _resolve_compression( - OTEL_EXPORTER_OTLP_TRACES_COMPRESSION - ) - transport = _transport or _build_transport( - certificate_file, - client_key_file, - client_certificate_file, - OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, - OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, - session=session or _load_session_from_envvar(_OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER), - ) - self._max_request_size = _DEFAULT_MAX_REQUEST_SIZE if max_request_size is None else max_request_size - self._client = _http._OTLPHTTPClient( - transport=transport, - endpoint=self._endpoint, - kind="spans", - timeout=timeout if timeout is not None else _resolve_timeout(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT), - compression=self._compression, - headers=_resolve_headers(headers, OTEL_EXPORTER_OTLP_TRACES_HEADERS), - logger=_logger, - ) - self._shutdown = False - - self._metrics = create_exporter_metrics( - OtelComponentTypeValues.OTLP_HTTP_SPAN_EXPORTER, - "traces", - self._endpoint, - meter_provider, - os.environ.get(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, "").strip().lower() == "true", - ) - - def export(self, spans: Sequence[ReadableSpan]) -> SpanExportResult: - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring batch") - return SpanExportResult.FAILURE - - with self._metrics.export_operation(len(spans)) as result: - try: - serialized_data = encode_spans(spans).SerializePartialToString() - # pylint: disable-next=broad-exception-caught - except Exception as error: - _logger.error("Failed to encode span batch: %s", error) - result.error = error - return SpanExportResult.FAILURE - - if _is_request_too_large(serialized_data, self._max_request_size): - _logger.warning( - "Dropping span batch: serialized size %d bytes exceeds max_request_size %d bytes.", - len(serialized_data), - self._max_request_size, - ) - result.error = RequestPayloadTooLargeError( - f"Serialized span request size {len(serialized_data)} " - f"bytes exceeds max_request_size " - f"{self._max_request_size} bytes." - ) - return SpanExportResult.FAILURE - - export_result = self._client.export(serialized_data) - if not export_result.success: - result.error = export_result.error - result.error_attrs = ( - {HTTP_RESPONSE_STATUS_CODE: export_result.status_code} - if export_result.status_code is not None - else None - ) - return SpanExportResult.FAILURE - return SpanExportResult.SUCCESS - - def shutdown(self): - if self._shutdown: - _logger.warning("Exporter already shutdown, ignoring call") - return - self._shutdown = True - self._client.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Nothing is buffered in this exporter, so this method does nothing.""" - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py deleted file mode 100644 index 6b9b95be1fc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/trace_exporter/encoder/__init__.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging # noqa: F401 -from collections import abc # noqa: F401 -from collections.abc import Sequence # noqa: F401 - -from opentelemetry.agent._vendor.opentelemetry.proto.collector.trace.v1.trace_service_pb2 import ( # noqa: F401 - ExportTraceServiceRequest as PB2ExportTraceServiceRequest, -) -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 - AnyValue as PB2AnyValue, -) -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 - ArrayValue as PB2ArrayValue, -) -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 - InstrumentationScope as PB2InstrumentationScope, -) -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401 - KeyValue as PB2KeyValue, -) -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2 import ( # noqa: F401 - Resource as PB2Resource, -) -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 - ResourceSpans as PB2ResourceSpans, -) -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 - ScopeSpans as PB2ScopeSpans, -) -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 - Span as PB2SPan, -) -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2 import ( # noqa: F401 - Status as PB2Status, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ( - Event, # noqa: F401 - Resource, # noqa: F401 -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import Span as SDKSpan # noqa: F401 -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( # noqa: F401 - InstrumentationScope, -) -from opentelemetry.agent._vendor.opentelemetry.trace import ( - Link, # noqa: F401 - SpanKind, # noqa: F401 -) -from opentelemetry.agent._vendor.opentelemetry.trace.span import ( # noqa: F401 - SpanContext, - Status, - TraceState, -) -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes # noqa: F401 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py deleted file mode 100644 index 0101c361616..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/otlp/proto/http/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py deleted file mode 100644 index 2c5a682a03b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/__init__.py +++ /dev/null @@ -1,523 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -This library allows export of metrics data to `Prometheus `_. - -Usage ------ - -The **OpenTelemetry Prometheus Exporter** allows export of `OpenTelemetry`_ -metrics to `Prometheus`_. - - -.. _Prometheus: https://prometheus.io/ -.. _OpenTelemetry: https://github.com/open-telemetry/opentelemetry-python/ - -.. code:: python - - from prometheus_client import start_http_server - - from opentelemetry.exporter.prometheus import PrometheusMetricReader - from opentelemetry.metrics import get_meter_provider, set_meter_provider - from opentelemetry.sdk.metrics import MeterProvider - - # Start Prometheus client - start_http_server(port=8000, addr="localhost") - - # Exporter to export metrics to Prometheus - prefix = "MyAppPrefix" - reader = PrometheusMetricReader(prefix=prefix) - - # Meter is responsible for creating and recording metrics - set_meter_provider(MeterProvider(metric_readers=[reader])) - meter = get_meter_provider().get_meter("myapp", "0.1.2") - - counter = meter.create_counter( - "requests", - "requests", - "number of requests", - ) - - # Labels are used to identify key-values that are associated with a specific - # metric that you want to record. These are useful for pre-aggregation and can - # be used to store custom dimensions pertaining to a metric - labels = {"environment": "staging"} - - counter.add(25, labels) - input("Press any key to exit...") - -API ---- -""" - -from collections import deque -from collections.abc import Callable, Iterable, Sequence -from itertools import chain -from json import dumps -from logging import getLogger -from os import environ -from typing import ( - Any, - TypeVar, -) - -from opentelemetry.agent._vendor.prometheus_client import CollectorRegistry, start_http_server -from opentelemetry.agent._vendor.prometheus_client.core import ( - REGISTRY, - CounterMetricFamily, - GaugeMetricFamily, - HistogramMetricFamily, - InfoMetricFamily, -) -from opentelemetry.agent._vendor.prometheus_client.core import Metric as PrometheusMetric - -from opentelemetry.agent._vendor.opentelemetry.exporter.prometheus._mapping import ( - map_unit, - sanitize_attribute, - sanitize_full_name, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPORTER_PROMETHEUS_HOST, - OTEL_EXPORTER_PROMETHEUS_PORT, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import ( - Counter, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - UpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import Histogram as HistogramInstrument -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - AggregationTemporality, - CardinalityLimits, - DataT, - Gauge, - Histogram, - HistogramDataPoint, - Metric, - MetricReader, - MetricsData, - Sum, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OtelComponentTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes - -_logger = getLogger(__name__) - -_TARGET_INFO_NAME = "target" -_TARGET_INFO_DESCRIPTION = "Target metadata" - -_OTEL_SCOPE_NAME_LABEL = "otel_scope_name" -_OTEL_SCOPE_VERSION_LABEL = "otel_scope_version" -_OTEL_SCOPE_SCHEMA_URL_LABEL = "otel_scope_schema_url" -_OTEL_SCOPE_ATTR_PREFIX = "otel_scope_" - - -def _convert_buckets(bucket_counts: Sequence[int], explicit_bounds: Sequence[float]) -> Sequence[tuple[str, int]]: - buckets = [] - total_count = 0 - for upper_bound, count in zip( - chain(explicit_bounds, ["+Inf"]), - bucket_counts, - ): - total_count += count - buckets.append((f"{upper_bound}", total_count)) - - return buckets - - -def _should_convert_sum_to_gauge(metric: Metric) -> bool: - # The Prometheus compatibility spec requires cumulative non-monotonic Sums - # to be exported as Gauges. - if not isinstance(metric.data, Sum): - return False - return not metric.data.is_monotonic and metric.data.aggregation_temporality == AggregationTemporality.CUMULATIVE - - -_FamilyT = TypeVar("_FamilyT", bound=PrometheusMetric) - - -def _get_or_create_family( - registry: dict[str, PrometheusMetric], - family_id: str, - factory: Callable[..., _FamilyT], - *, - name: str, - documentation: str, - labels: Sequence[str], - unit: str, -) -> _FamilyT: - if family_id not in registry: - registry[family_id] = factory( - name=name, - documentation=documentation, - labels=labels, - unit=unit, - ) - return registry[family_id] - - -def _populate_counter_family( - registry: dict[str, PrometheusMetric], - per_metric_family_id: str, - metric_name: str, - description: str, - unit: str, - label_keys: Sequence[str], - label_rows: Sequence[Sequence[str]], - values: Sequence[float], -) -> None: - family_id = "|".join([per_metric_family_id, CounterMetricFamily.__name__]) - family = _get_or_create_family( - registry, - family_id, - CounterMetricFamily, - name=metric_name, - documentation=description, - labels=label_keys, - unit=unit, - ) - for label_values, value in zip(label_rows, values): - family.add_metric(labels=label_values, value=value) - - -def _populate_gauge_family( - registry: dict[str, PrometheusMetric], - per_metric_family_id: str, - metric_name: str, - description: str, - unit: str, - label_keys: Sequence[str], - label_rows: Sequence[Sequence[str]], - values: Sequence[float], -) -> None: - family_id = "|".join([per_metric_family_id, GaugeMetricFamily.__name__]) - family = _get_or_create_family( - registry, - family_id, - GaugeMetricFamily, - name=metric_name, - documentation=description, - labels=label_keys, - unit=unit, - ) - for label_values, value in zip(label_rows, values): - family.add_metric(labels=label_values, value=value) - - -def _populate_histogram_family( - registry: dict[str, PrometheusMetric], - per_metric_family_id: str, - metric_name: str, - description: str, - unit: str, - label_keys: Sequence[str], - label_rows: Sequence[Sequence[str]], - values: Sequence[dict[str, Any]], -) -> None: - family_id = "|".join([per_metric_family_id, HistogramMetricFamily.__name__]) - family = _get_or_create_family( - registry, - family_id, - HistogramMetricFamily, - name=metric_name, - documentation=description, - labels=label_keys, - unit=unit, - ) - for label_values, value in zip(label_rows, values): - family.add_metric( - labels=label_values, - buckets=_convert_buckets(value["bucket_counts"], value["explicit_bounds"]), - sum_value=value["sum"], - ) - - -class PrometheusMetricReader(MetricReader): - """Prometheus metric exporter for OpenTelemetry. - - Args: - disable_target_info: Whether to disable the ``target_info`` metric. - prefix: Prefix added to exported Prometheus metric names. - scope_info_enabled: Whether to include instrumentation scope labels on - exported metrics. Scope labels are exported by default. - resource_attribute_filter: Optional callback to select resource attributes - that are copied as labels on exported metrics. The callback receives - the original resource attribute key. Selected keys are sanitized to - valid Prometheus label names. - cardinality_limits: A mapping between instrument classes and the - maximum number of metric points a metric stream of that class may - export per collection cycle. Classes not included in the mapping - use a limit of 2000. See - :class:`~opentelemetry.sdk.metrics.export.MetricReader` for details. - """ - - def __init__( - self, - disable_target_info: bool = False, - prefix: str = "", - scope_info_enabled: bool = True, - *, - resource_attribute_filter: Callable[[str], bool] | None = None, - registry: CollectorRegistry = REGISTRY, - cardinality_limits: CardinalityLimits | None = None, - ) -> None: - super().__init__( - preferred_temporality={ - Counter: AggregationTemporality.CUMULATIVE, - UpDownCounter: AggregationTemporality.CUMULATIVE, - HistogramInstrument: AggregationTemporality.CUMULATIVE, - ObservableCounter: AggregationTemporality.CUMULATIVE, - ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - ObservableGauge: AggregationTemporality.CUMULATIVE, - }, - cardinality_limits=cardinality_limits, - otel_component_type=OtelComponentTypeValues.PROMETHEUS_HTTP_TEXT_METRIC_EXPORTER, - ) - self._collector = _CustomCollector( - disable_target_info=disable_target_info, - prefix=prefix, - scope_info_enabled=scope_info_enabled, - resource_attribute_filter=resource_attribute_filter, - ) - self._registry = registry - self._registry.register(self._collector) - self._collector._callback = self.collect - self._prefix = prefix - - def _receive_metrics( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> None: - if metrics_data is None: - return - self._collector.add_metrics_data(metrics_data) - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - self._registry.unregister(self._collector) - - -class _CustomCollector: - """_CustomCollector represents the Prometheus Collector object - - See more: - https://github.com/prometheus/client_python#custom-collectors - """ - - def __init__( - self, - disable_target_info: bool = False, - prefix: str = "", - scope_info_enabled: bool = True, - resource_attribute_filter: Callable[[str], bool] | None = None, - ): - self._callback = None - self._metrics_datas: deque[MetricsData] = deque() - self._disable_target_info = disable_target_info - self._target_info = None - self._prefix = prefix - self._scope_info_enabled = scope_info_enabled - self._resource_attribute_filter = resource_attribute_filter - - def add_metrics_data(self, metrics_data: MetricsData) -> None: - """Add metrics to Prometheus data""" - self._metrics_datas.append(metrics_data) - - def collect(self) -> Iterable[PrometheusMetric]: - """Collect fetches the metrics from OpenTelemetry - and delivers them as Prometheus Metrics. - Collect is invoked every time a ``prometheus.Gatherer`` is run - for example when the HTTP endpoint is invoked by Prometheus. - """ - if self._callback is not None: - self._callback() - - metric_family_id_metric_family = {} - - if len(self._metrics_datas): - if not self._disable_target_info: - if self._target_info is None: - attributes: Attributes = {} - for res in self._metrics_datas[0].resource_metrics: - attributes = {**attributes, **res.resource.attributes} - - self._target_info = self._create_info_metric( - _TARGET_INFO_NAME, _TARGET_INFO_DESCRIPTION, attributes - ) - metric_family_id_metric_family[_TARGET_INFO_NAME] = self._target_info - - while self._metrics_datas: - self._translate_to_prometheus(self._metrics_datas.popleft(), metric_family_id_metric_family) - - if metric_family_id_metric_family: - yield from metric_family_id_metric_family.values() - - def _translate_to_prometheus( - self, - metrics_data: MetricsData, - metric_family_id_metric_family: dict[str, PrometheusMetric], - ): - for rm in metrics_data.resource_metrics: - resource_attrs = self._build_resource_attrs(rm.resource) - for sm in rm.scope_metrics: - scope_attrs = self._build_scope_attrs(sm.scope) - for metric in sm.metrics: - self._translate_metric( - metric=metric, - scope_attrs=scope_attrs, - resource_attrs=resource_attrs, - metric_family_id_metric_family=metric_family_id_metric_family, - ) - - def _translate_metric( - self, - metric: Metric, - scope_attrs: dict[str, AnyValue], - resource_attrs: dict[str, AnyValue], - metric_family_id_metric_family: dict[str, PrometheusMetric], - ) -> None: - metric_name = self._resolve_metric_name(metric.name) - description = metric.description or "" - unit = map_unit(metric.unit or "") - label_keys, label_rows, values = self._collect_data_points(metric.data, scope_attrs, resource_attrs) - per_metric_family_id = "|".join((metric_name, description, unit)) - - convert_sum_to_gauge = _should_convert_sum_to_gauge(metric) - - if isinstance(metric.data, Sum) and not convert_sum_to_gauge: - _populate_counter_family( - registry=metric_family_id_metric_family, - per_metric_family_id=per_metric_family_id, - metric_name=metric_name, - description=description, - unit=unit, - label_keys=label_keys, - label_rows=label_rows, - values=values, - ) - elif isinstance(metric.data, Gauge) or convert_sum_to_gauge: - _populate_gauge_family( - registry=metric_family_id_metric_family, - per_metric_family_id=per_metric_family_id, - metric_name=metric_name, - description=description, - unit=unit, - label_keys=label_keys, - label_rows=label_rows, - values=values, - ) - elif isinstance(metric.data, Histogram): - _populate_histogram_family( - registry=metric_family_id_metric_family, - per_metric_family_id=per_metric_family_id, - metric_name=metric_name, - description=description, - unit=unit, - label_keys=label_keys, - label_rows=label_rows, - values=values, - ) - else: - _logger.warning("Unsupported metric data. %s", type(metric.data)) - - def _build_scope_attrs(self, scope: InstrumentationScope) -> dict[str, AnyValue]: - if not self._scope_info_enabled: - return {} - attrs: dict[str, AnyValue] = {} - if scope.attributes: - for key, value in scope.attributes.items(): - attrs[_OTEL_SCOPE_ATTR_PREFIX + key] = value - attrs[_OTEL_SCOPE_NAME_LABEL] = scope.name or "" - attrs[_OTEL_SCOPE_VERSION_LABEL] = scope.version or "" - attrs[_OTEL_SCOPE_SCHEMA_URL_LABEL] = scope.schema_url or "" - return attrs - - def _build_resource_attrs(self, resource: Resource) -> dict[str, AnyValue]: - if not self._resource_attribute_filter: - return {} - return {key: value for key, value in resource.attributes.items() if self._resource_attribute_filter(key)} - - def _resolve_metric_name(self, name: str) -> str: - if self._prefix: - name = self._prefix + "_" + name - return sanitize_full_name(name) - - def _collect_data_points( - self, - metric_data: DataT, - scope_attrs: dict[str, AnyValue], - resource_attrs: dict[str, AnyValue], - ) -> tuple[list[str], list[list[str]], list[float | dict[str, Any]]]: - keys: set[str] = set() - rows: list[dict[str, str]] = [] - values: list[float | dict[str, Any]] = [] - - for point in metric_data.data_points: - labels: dict[str, str] = {} - for key, value in chain( - resource_attrs.items(), - scope_attrs.items(), - point.attributes.items(), - ): - label = sanitize_attribute(key) - keys.add(label) - labels[label] = self._check_value(value) - rows.append(labels) - - if isinstance(point, HistogramDataPoint): - values.append( - { - "bucket_counts": point.bucket_counts, - "explicit_bounds": point.explicit_bounds, - "sum": point.sum, - } - ) - else: - values.append(point.value) - - label_keys = sorted(keys) - # Backfill missing labels with "" so every data point exposes the - # full label set expected by the Prometheus family. - label_rows = [[labels.get(k, "") for k in label_keys] for labels in rows] - return label_keys, label_rows, values - - # pylint: disable=no-self-use - def _check_value(self, value: float | str | Sequence) -> str: - """Check the label value and return is appropriate representation""" - if not isinstance(value, str): - return dumps(value, default=str) - return str(value) - - def _create_info_metric(self, name: str, description: str, attributes: dict[str, str]) -> InfoMetricFamily: - """Create an Info Metric Family with list of attributes""" - # sanitize the attribute names according to Prometheus rule - attributes = {sanitize_attribute(key): self._check_value(value) for key, value in attributes.items()} - info = InfoMetricFamily(name, description, labels=attributes) - info.add_metric(labels=list(attributes.keys()), value=attributes) - return info - - -class _AutoPrometheusMetricReader(PrometheusMetricReader): - """Thin wrapper around PrometheusMetricReader used for the opentelemetry_metrics_exporter entry point. - - This allows users to use the prometheus exporter with opentelemetry-instrument. It handles - starting the Prometheus http server on the the correct port and host. - """ - - def __init__(self) -> None: - super().__init__() - - # Default values are specified in - # https://github.com/open-telemetry/opentelemetry-specification/blob/v1.24.0/specification/configuration/sdk-environment-variables.md#prometheus-exporter - start_http_server( - port=int(environ.get(OTEL_EXPORTER_PROMETHEUS_PORT, "9464")), - addr=environ.get(OTEL_EXPORTER_PROMETHEUS_HOST, "localhost"), - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py deleted file mode 100644 index 7822c69cc57..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/_mapping.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from re import UNICODE, compile - -_SANITIZE_NAME_RE = compile(r"[^a-zA-Z0-9:]+", UNICODE) -# Same as name, but doesn't allow ":" -_SANITIZE_ATTRIBUTE_KEY_RE = compile(r"[^a-zA-Z0-9]+", UNICODE) - -# UCUM style annotations which are text enclosed in curly braces https://ucum.org/ucum#para-6. -# This regex is more permissive than UCUM allows and matches any character within curly braces. -_UNIT_ANNOTATION = compile(r"{.*}") - -# Remaps common UCUM and SI units to prometheus conventions. Copied from -# https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/v0.101.0/pkg/translator/prometheus/normalize_name.go#L19 -# See specification: -# https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 -_UNIT_MAPPINGS = { - # Time - "d": "days", - "h": "hours", - "min": "minutes", - "s": "seconds", - "ms": "milliseconds", - "us": "microseconds", - "ns": "nanoseconds", - # Bytes - "By": "bytes", - "KiBy": "kibibytes", - "MiBy": "mebibytes", - "GiBy": "gibibytes", - "TiBy": "tibibytes", - "KBy": "kilobytes", - "MBy": "megabytes", - "GBy": "gigabytes", - "TBy": "terabytes", - # SI - "m": "meters", - "V": "volts", - "A": "amperes", - "J": "joules", - "W": "watts", - "g": "grams", - # Misc - "Cel": "celsius", - "Hz": "hertz", - # TODO(https://github.com/open-telemetry/opentelemetry-specification/issues/4058): the - # specification says to normalize "1" to ratio but that may change. Update this mapping or - # remove TODO once a decision is made. - "1": "", - "%": "percent", -} -# Similar to _UNIT_MAPPINGS, but for "per" unit denominator. -# Example: s => per second (singular) -# Copied from https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/80317ce83ed87a2dff0c316bb939afbfaa823d5e/pkg/translator/prometheus/normalize_name.go#L58 -_PER_UNIT_MAPPINGS = { - "s": "second", - "m": "minute", - "h": "hour", - "d": "day", - "w": "week", - "mo": "month", - "y": "year", -} - - -def sanitize_full_name(name: str) -> str: - """sanitize the given metric name according to Prometheus rule, including sanitizing - leading digits - - https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 - """ - # Leading number special case - if name and name[0].isdigit(): - name = "_" + name[1:] - return _sanitize_name(name) - - -def _sanitize_name(name: str) -> str: - """sanitize the given metric name according to Prometheus rule, but does not handle - sanitizing a leading digit.""" - return _SANITIZE_NAME_RE.sub("_", name) - - -def sanitize_attribute(key: str) -> str: - """sanitize the given metric attribute key according to Prometheus rule. - - https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-attributes - """ - # Leading number special case - if key and key[0].isdigit(): - key = "_" + key[1:] - return _SANITIZE_ATTRIBUTE_KEY_RE.sub("_", key) - - -def map_unit(unit: str) -> str: - """Maps unit to common prometheus metric names if available and sanitizes any invalid - characters - - See: - - https://github.com/open-telemetry/opentelemetry-specification/blob/v1.33.0/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 - - https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/v0.101.0/pkg/translator/prometheus/normalize_name.go#L108 - """ - # remove curly brace unit annotations - unit = _UNIT_ANNOTATION.sub("", unit) - - if unit in _UNIT_MAPPINGS: - return _UNIT_MAPPINGS[unit] - - # replace "/" with "per" units like m/s -> meters_per_second - ratio_unit_subparts = unit.split("/", maxsplit=1) - if len(ratio_unit_subparts) == 2: - bottom = _sanitize_name(ratio_unit_subparts[1]) - if bottom: - top = _sanitize_name(ratio_unit_subparts[0]) - top = _UNIT_MAPPINGS.get(top, top) - bottom = _PER_UNIT_MAPPINGS.get(bottom, bottom) - return f"{top}_per_{bottom}" if top else f"per_{bottom}" - - return ( - # since units end up as a metric name suffix, they must be sanitized - _sanitize_name(unit) - # strip surrounding "_" chars since it will lead to consecutive underscores in the - # metric name - .strip("_") - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/exporter/prometheus/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py deleted file mode 100644 index 7c9f8f20e01..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/__init__.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -OpenTelemetry Labeler -===================== - -The labeler utility provides a way to add custom attributes to metrics. - -This was inspired by OpenTelemetry Go's net/http instrumentation Labeler -https://github.com/open-telemetry/opentelemetry-go-contrib/pull/306 - -Usage ------ - -The labeler is typically used within the context of an instrumented request -or operation. Use ``get_labeler`` to obtain a labeler instance for the -current context, then add attributes using the ``add`` or -``add_attributes`` methods. - -Example -------- - -Here's a framework-agnostic example showing manual use of the labeler: - -.. code-block:: python - - from opentelemetry.instrumentation._labeler import ( - enrich_metric_attributes, - get_labeler, - ) - from opentelemetry.metrics import get_meter - - meter = get_meter("example.manual") - duration_histogram = meter.create_histogram( - name="http.server.request.duration", - unit="s", - description="Duration of HTTP server requests.", - ) - - - def record_request(user_id: str, duration_s: float) -> None: - labeler = get_labeler() - labeler.add("user_id", user_id) - labeler.add_attributes( - { - "has_premium": user_id in ["123", "456"], - "experiment_group": "control", - "feature_enabled": True, - "user_segment": "active", - } - ) - - base_attributes = { - "http.request.method": "GET", - "http.response.status_code": 200, - } - duration_histogram.record( - max(duration_s, 0), - enrich_metric_attributes(base_attributes), - ) - -This package introduces the shared Labeler API and helper utilities. -Framework-specific integration points that call -``enrich_metric_attributes`` (for example before ``Histogram.record``) -can be added by individual instrumentors. - -When instrumentors use ``enrich_metric_attributes``, it does not -overwrite base attributes that exist at the same keys. -""" - -from opentelemetry.agent._vendor.opentelemetry.instrumentation._labeler._internal import ( - Labeler, - clear_labeler, - enrich_metric_attributes, - get_labeler, - get_labeler_attributes, - set_labeler, -) - -__all__ = [ - "Labeler", - "clear_labeler", - "enrich_metric_attributes", - "get_labeler", - "get_labeler_attributes", - "set_labeler", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py deleted file mode 100644 index 63531f845e2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_labeler/_internal/__init__.py +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import logging -import threading -from collections.abc import Mapping -from types import MappingProxyType -from typing import Any - -from opentelemetry.agent._vendor.opentelemetry.context import attach, create_key, get_value, set_value -from opentelemetry.agent._vendor.opentelemetry.util.types import AttributeValue - -LABELER_CONTEXT_KEY = create_key("otel_labeler") - -_logger = logging.getLogger(__name__) - - -class Labeler: - """ - Stores custom attributes for the current OTel context. - - This feature is experimental and unstable. - """ - - def __init__(self, max_custom_attrs: int = 20, max_attr_value_length: int = 100): - """ - Initialize a new Labeler instance. - - Args: - max_custom_attrs: Maximum number of custom attributes to store. - When this limit is reached, new attributes will be ignored; - existing attributes can still be updated. - max_attr_value_length: Maximum length for string attribute values. - String values exceeding this length will be truncated. - """ - self._lock = threading.Lock() - self._attributes: dict[str, str | int | float | bool] = {} - self._max_custom_attrs = max_custom_attrs - self._max_attr_value_length = max_attr_value_length - - def add(self, key: str, value: Any) -> None: - """ - Add a single attribute to the labeler, subject to the labeler's limits: - - If max_custom_attrs limit is reached and this is a new key, the attribute is ignored - - String values exceeding max_attr_value_length are truncated - - Args: - key: attribute key - value: attribute value, must be a primitive type: str, int, float, or bool - """ - if not isinstance(value, (str, int, float, bool)): - _logger.warning( - "Skipping attribute '%s': value must be str, int, float, or bool, got %s", - key, - type(value).__name__, - ) - return - - with self._lock: - if len(self._attributes) >= self._max_custom_attrs and key not in self._attributes: - return - - if isinstance(value, str) and len(value) > self._max_attr_value_length: - value = value[: self._max_attr_value_length] - - self._attributes[key] = value - - def add_attributes(self, attributes: dict[str, Any]) -> None: - """ - Add multiple attributes to the labeler, subject to the labeler's limits: - - If max_custom_attrs limit is reached and this is a new key, the attribute is ignored - - Existing attributes can still be updated - - String values exceeding max_attr_value_length are truncated - - Args: - attributes: Dictionary of attributes to add. Values must be primitive types - (str, int, float, or bool) - """ - with self._lock: - for key, value in attributes.items(): - if not isinstance(value, (str, int, float, bool)): - _logger.warning( - "Skipping attribute '%s': value must be str, int, float, or bool, got %s", - key, - type(value).__name__, - ) - continue - - if len(self._attributes) >= self._max_custom_attrs and key not in self._attributes: - continue - - if isinstance(value, str) and len(value) > self._max_attr_value_length: - value = value[: self._max_attr_value_length] - - self._attributes[key] = value - - def get_attributes(self) -> Mapping[str, str | int | float | bool]: - """ - Return a read-only mapping view of attributes in this labeler. - """ - with self._lock: - return MappingProxyType(self._attributes) - - def clear(self) -> None: - with self._lock: - self._attributes.clear() - - def __len__(self) -> int: - with self._lock: - return len(self._attributes) - - -def _attach_context_value(value: Labeler | None) -> None: - """ - Attach a new OpenTelemetry context containing the given labeler value. - - This helper is fail-safe: context attach errors are suppressed and - logged at debug level. - - Args: - value: Labeler instance to store in context, or ``None`` to clear it. - """ - try: - updated_context = set_value(LABELER_CONTEXT_KEY, value) - attach(updated_context) - except Exception: # pylint: disable=broad-exception-caught - _logger.debug("Failed to attach labeler context", exc_info=True) - - -def get_labeler() -> Labeler: - """ - Get the Labeler instance for the current OTel context. - - If no Labeler exists in the current context, a new one is created - and stored in the context. - - Returns: - Labeler instance for the current OTel context, or a new empty Labeler - if no Labeler is currently stored in context. - """ - try: - current_value = get_value(LABELER_CONTEXT_KEY) - except Exception: # pylint: disable=broad-exception-caught - _logger.debug("Failed to read labeler from context", exc_info=True) - current_value = None - - if isinstance(current_value, Labeler): - return current_value - - labeler = Labeler() - _attach_context_value(labeler) - return labeler - - -def set_labeler(labeler: Any) -> None: - """ - Set the Labeler instance for the current OTel context. - - Args: - labeler: The Labeler instance to set - """ - if not isinstance(labeler, Labeler): - _logger.warning( - "Skipping set_labeler: value must be Labeler, got %s", - type(labeler).__name__, - ) - return - _attach_context_value(labeler) - - -def clear_labeler() -> None: - """ - Clear the Labeler instance from the current OTel context. - - This is primarily intended for test isolation or manual context-lifecycle - management. In typical framework-instrumented request handling, - applications generally should not need to call this directly. - """ - _attach_context_value(None) - - -def get_labeler_attributes() -> Mapping[str, str | int | float | bool]: - """ - Get attributes from the current labeler, if any. - - Returns: - Read-only mapping of custom attributes, or an empty read-only mapping - if no labeler exists. - """ - empty_attributes: dict[str, str | int | float | bool] = {} - try: - current_value = get_value(LABELER_CONTEXT_KEY) - except Exception: # pylint: disable=broad-exception-caught - _logger.debug("Failed to read labeler attributes from context", exc_info=True) - return MappingProxyType(empty_attributes) - - if not isinstance(current_value, Labeler): - return MappingProxyType(empty_attributes) - return current_value.get_attributes() - - -def enrich_metric_attributes( - base_attributes: dict[str, Any], - enrich_enabled: bool = True, -) -> dict[str, AttributeValue]: - """ - Combines base_attributes with custom attributes from the current labeler, - returning a new dictionary of attributes according to the labeler configuration: - - Attributes that would override base_attributes are skipped - - If max_custom_attrs limit is reached and this is a new key, the attribute is ignored - - String values exceeding max_attr_value_length are truncated - - Args: - base_attributes: The base attributes for the metric - enrich_enabled: Whether to include custom labeler attributes - - Returns: - Dictionary combining base and custom attributes. If no custom attributes, - returns a copy of the original base attributes. - """ - if not enrich_enabled: - return base_attributes.copy() - - labeler_attributes = get_labeler_attributes() - if not labeler_attributes: - return base_attributes.copy() - - try: - labeler = get_value(LABELER_CONTEXT_KEY) - except Exception: # pylint: disable=broad-exception-caught - labeler = None - - if not isinstance(labeler, Labeler): - return base_attributes.copy() - - enriched_attributes = base_attributes.copy() - added_count = 0 - for key, value in labeler_attributes.items(): - if added_count >= labeler._max_custom_attrs: - break - if key in base_attributes: - continue - - if isinstance(value, str) and len(value) > labeler._max_attr_value_length: - value = value[: labeler._max_attr_value_length] - - enriched_attributes[key] = value - added_count += 1 - - return enriched_attributes diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py deleted file mode 100644 index 37a7b36afe5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/_semconv.py +++ /dev/null @@ -1,725 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import os -import threading -from collections.abc import Container, Mapping, MutableMapping -from enum import Enum -from urllib.parse import urlparse - -from opentelemetry.agent._vendor.packaging import version as package_version - -from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import http_status_to_status_code -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.db_attributes import ( - DB_NAME, - DB_OPERATION, - DB_REDIS_DATABASE_INDEX, - DB_STATEMENT, - DB_SYSTEM, - DB_USER, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.http_attributes import ( - HTTP_FLAVOR, - HTTP_HOST, - HTTP_METHOD, - HTTP_SCHEME, - HTTP_SERVER_NAME, - HTTP_STATUS_CODE, - HTTP_TARGET, - HTTP_URL, - HTTP_USER_AGENT, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.net_attributes import ( - NET_HOST_NAME, - NET_HOST_PORT, - NET_PEER_IP, - NET_PEER_NAME, - NET_PEER_PORT, - NET_TRANSPORT, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.client_attributes import ( - CLIENT_ADDRESS, - CLIENT_PORT, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.db_attributes import ( - DB_NAMESPACE, - DB_OPERATION_NAME, - DB_QUERY_TEXT, - DB_SYSTEM_NAME, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.http_attributes import ( - HTTP_REQUEST_METHOD, - HTTP_REQUEST_METHOD_ORIGINAL, - HTTP_RESPONSE_STATUS_CODE, - HTTP_ROUTE, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.network_attributes import ( - NETWORK_PROTOCOL_VERSION, - NETWORK_TRANSPORT, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.server_attributes import ( - SERVER_ADDRESS, - SERVER_PORT, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.url_attributes import ( - URL_FULL, - URL_PATH, - URL_QUERY, - URL_SCHEME, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.user_agent_attributes import ( - USER_AGENT_ORIGINAL, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.schemas import Schemas -from opentelemetry.agent._vendor.opentelemetry.trace import Span -from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode -from opentelemetry.agent._vendor.opentelemetry.util.types import AttributeValue - -# Values defined in milliseconds -HTTP_DURATION_HISTOGRAM_BUCKETS_OLD = ( - 0.0, - 5.0, - 10.0, - 25.0, - 50.0, - 75.0, - 100.0, - 250.0, - 500.0, - 750.0, - 1000.0, - 2500.0, - 5000.0, - 7500.0, - 10000.0, -) - -# Values defined in seconds -HTTP_DURATION_HISTOGRAM_BUCKETS_NEW = ( - 0.005, - 0.01, - 0.025, - 0.05, - 0.075, - 0.1, - 0.25, - 0.5, - 0.75, - 1, - 2.5, - 5, - 7.5, - 10, -) - -# These lists represent attributes for metrics that are currently supported - -_client_duration_attrs_old = [ - HTTP_STATUS_CODE, - HTTP_HOST, - HTTP_METHOD, - HTTP_FLAVOR, - HTTP_SCHEME, - NET_PEER_PORT, - NET_PEER_NAME, -] - -_client_duration_attrs_new = [ - ERROR_TYPE, - HTTP_REQUEST_METHOD, - HTTP_RESPONSE_STATUS_CODE, - NETWORK_PROTOCOL_VERSION, - SERVER_ADDRESS, - SERVER_PORT, - # TODO: Support opt-in for scheme in new semconv - # URL_SCHEME, -] - -_server_duration_attrs_old = [ - HTTP_METHOD, - HTTP_HOST, - HTTP_SCHEME, - HTTP_STATUS_CODE, - HTTP_FLAVOR, - HTTP_SERVER_NAME, - NET_HOST_NAME, - NET_HOST_PORT, -] - -_server_duration_attrs_new = [ - ERROR_TYPE, - HTTP_REQUEST_METHOD, - HTTP_RESPONSE_STATUS_CODE, - HTTP_ROUTE, - NETWORK_PROTOCOL_VERSION, - URL_SCHEME, -] - -_server_active_requests_count_attrs_old = [ - HTTP_METHOD, - HTTP_HOST, - HTTP_SCHEME, - HTTP_FLAVOR, - HTTP_SERVER_NAME, -] - -_server_active_requests_count_attrs_new = [ - HTTP_REQUEST_METHOD, - URL_SCHEME, - # TODO: Support SERVER_ADDRESS AND SERVER_PORT -] - -OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" - -# Legacy/default schema version when schema_url was first introduced -_LEGACY_SCHEMA_VERSION = "1.11.0" - - -class _OpenTelemetryStabilitySignalType(Enum): - HTTP = "http" - DATABASE = "database" - GEN_AI = "gen_ai" - - -class _StabilityMode(Enum): - DEFAULT = "default" - HTTP = "http" - HTTP_DUP = "http/dup" - DATABASE = "database" - DATABASE_DUP = "database/dup" - GEN_AI_LATEST_EXPERIMENTAL = "gen_ai_latest_experimental" - - -def _report_new(mode: _StabilityMode): - return mode != _StabilityMode.DEFAULT - - -def _report_old(mode: _StabilityMode): - return mode not in (_StabilityMode.HTTP, _StabilityMode.DATABASE) - - -class _OpenTelemetrySemanticConventionStability: - _initialized = False - _lock = threading.Lock() - _OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = {} - - @classmethod - def _initialize(cls): - with cls._lock: - if cls._initialized: - return - - # Users can pass in comma delimited string for opt-in options - # Only values for http, gen ai, and database stability are supported for now - opt_in = os.environ.get(OTEL_SEMCONV_STABILITY_OPT_IN) - - if not opt_in: - # early return in case of default - cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING = { - _OpenTelemetryStabilitySignalType.HTTP: _StabilityMode.DEFAULT, - _OpenTelemetryStabilitySignalType.DATABASE: _StabilityMode.DEFAULT, - _OpenTelemetryStabilitySignalType.GEN_AI: _StabilityMode.DEFAULT, - } - cls._initialized = True - return - - opt_in_list = [s.strip() for s in opt_in.split(",")] - - cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[_OpenTelemetryStabilitySignalType.HTTP] = cls._filter_mode( - opt_in_list, _StabilityMode.HTTP, _StabilityMode.HTTP_DUP - ) - - cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[_OpenTelemetryStabilitySignalType.GEN_AI] = cls._filter_mode( - opt_in_list, - _StabilityMode.DEFAULT, - _StabilityMode.GEN_AI_LATEST_EXPERIMENTAL, - ) - - cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING[_OpenTelemetryStabilitySignalType.DATABASE] = cls._filter_mode( - opt_in_list, - _StabilityMode.DATABASE, - _StabilityMode.DATABASE_DUP, - ) - cls._initialized = True - - @staticmethod - def _filter_mode(opt_in_list, stable_mode, dup_mode): - # Process semconv stability opt-in - # http/dup,database/dup has higher precedence over http,database - if dup_mode.value in opt_in_list: - return dup_mode - - return stable_mode if stable_mode.value in opt_in_list else _StabilityMode.DEFAULT - - @classmethod - def _get_opentelemetry_stability_opt_in_mode(cls, signal_type: _OpenTelemetryStabilitySignalType) -> _StabilityMode: - # Get OpenTelemetry opt-in mode based off of signal type (http, messaging, etc.) - return cls._OTEL_SEMCONV_STABILITY_SIGNAL_MAPPING.get(signal_type, _StabilityMode.DEFAULT) - - -def _get_semconv_opt_in_modes( - signal_types: tuple[_OpenTelemetryStabilitySignalType, ...], -) -> dict[_OpenTelemetryStabilitySignalType, _StabilityMode]: - """Returns a mapping of signal type to mode for the provided - signal_types (one/more of DATABASE, HTTP, GEN_AI). - """ - _OpenTelemetrySemanticConventionStability._initialize() - return { - signal_type: _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(signal_type) - for signal_type in signal_types - } - - -def _filter_semconv_duration_attrs( - attrs: Mapping[str, AttributeValue], - old_attrs: Container[AttributeValue], - new_attrs: Container[AttributeValue], - sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, -) -> dict[str, AttributeValue]: - filtered_attrs = {} - # duration is two different metrics depending on sem_conv_opt_in_mode, so no DUP attributes - allowed_attributes = new_attrs if sem_conv_opt_in_mode == _StabilityMode.HTTP else old_attrs - for key, val in attrs.items(): - if key in allowed_attributes: - filtered_attrs[key] = val - return filtered_attrs - - -def _filter_semconv_active_request_count_attr( - attrs: Mapping[str, AttributeValue], - old_attrs: Container[AttributeValue], - new_attrs: Container[AttributeValue], - sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, -) -> dict[str, AttributeValue]: - filtered_attrs = {} - if _report_old(sem_conv_opt_in_mode): - for key, val in attrs.items(): - if key in old_attrs: - filtered_attrs[key] = val - if _report_new(sem_conv_opt_in_mode): - for key, val in attrs.items(): - if key in new_attrs: - filtered_attrs[key] = val - return filtered_attrs - - -def set_string_attribute( - result: MutableMapping[str, AttributeValue], - key: str, - value: AttributeValue, -) -> None: - if value: - result[key] = value - - -def set_int_attribute( - result: MutableMapping[str, AttributeValue], - key: str, - value: AttributeValue, -) -> None: - if value: - try: - result[key] = int(value) - except (ValueError, TypeError): - pass - - -def _set_http_method( - result: MutableMapping[str, AttributeValue], - original: str, - normalized: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - original = original.strip() - normalized = normalized.strip() - # See https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#common-attributes - # Method is case sensitive. "http.request.method_original" should not be sanitized or automatically capitalized. - if original != normalized and _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_REQUEST_METHOD_ORIGINAL, original) - - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_METHOD, normalized) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_REQUEST_METHOD, normalized) - - -def _set_http_status_code( - result: MutableMapping[str, AttributeValue], - code: str | int, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_int_attribute(result, HTTP_STATUS_CODE, code) - if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, HTTP_RESPONSE_STATUS_CODE, code) - - -def _set_http_url( - result: MutableMapping[str, AttributeValue], - url: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_URL, url) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, URL_FULL, url) - - -def _set_http_scheme( - result: MutableMapping[str, AttributeValue], - scheme: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_SCHEME, scheme) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, URL_SCHEME, scheme) - - -def _set_http_flavor_version( - result: MutableMapping[str, AttributeValue], - version: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_FLAVOR, version) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) - - -def _set_http_user_agent( - result: MutableMapping[str, AttributeValue], - user_agent: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_USER_AGENT, user_agent) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, USER_AGENT_ORIGINAL, user_agent) - - -# Client - - -def _set_http_host_client( - result: MutableMapping[str, AttributeValue], - host: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_HOST, host) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SERVER_ADDRESS, host) - - -def _set_http_net_peer_name_client( - result: MutableMapping[str, AttributeValue], - peer_name: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, NET_PEER_NAME, peer_name) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SERVER_ADDRESS, peer_name) - - -def _set_http_peer_port_client( - result: MutableMapping[str, AttributeValue], - port: str | int, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_int_attribute(result, NET_PEER_PORT, port) - if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, SERVER_PORT, port) - - -def _set_http_network_protocol_version( - result: MutableMapping[str, AttributeValue], - version: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_FLAVOR, version) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, NETWORK_PROTOCOL_VERSION, version) - - -# Server - - -def _set_http_net_host( - result: MutableMapping[str, AttributeValue], - host: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, NET_HOST_NAME, host) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, SERVER_ADDRESS, host) - - -def _set_http_net_host_port( - result: MutableMapping[str, AttributeValue], - port: str | int, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_int_attribute(result, NET_HOST_PORT, port) - if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, SERVER_PORT, port) - - -def _set_http_target( - result: MutableMapping[str, AttributeValue], - target: str, - path: str | None, - query: str | None, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_TARGET, target) - if _report_new(sem_conv_opt_in_mode): - if path: - set_string_attribute(result, URL_PATH, path) - if query: - set_string_attribute(result, URL_QUERY, query) - - -def _set_http_host_server( - result: MutableMapping[str, AttributeValue], - host: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, HTTP_HOST, host) - if _report_new(sem_conv_opt_in_mode): - if not result.get(SERVER_ADDRESS): - set_string_attribute(result, SERVER_ADDRESS, host) - - -# net.peer.ip -> net.sock.peer.addr -# https://github.com/open-telemetry/semantic-conventions/blob/40db676ca0e735aa84f242b5a0fb14e49438b69b/schemas/1.15.0#L18 -# net.sock.peer.addr -> client.socket.address for server spans (TODO) AND client.address if missing -# https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/CHANGELOG.md#v1210-2023-07-13 -# https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md#common-attributes-across-http-client-and-server-spans -def _set_http_peer_ip_server( - result: MutableMapping[str, AttributeValue], - ip: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, NET_PEER_IP, ip) - if _report_new(sem_conv_opt_in_mode): - # Only populate if not already populated - if not result.get(CLIENT_ADDRESS): - set_string_attribute(result, CLIENT_ADDRESS, ip) - - -def _set_http_peer_port_server( - result: MutableMapping[str, AttributeValue], - port: str | int, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_int_attribute(result, NET_PEER_PORT, port) - if _report_new(sem_conv_opt_in_mode): - set_int_attribute(result, CLIENT_PORT, port) - - -def _set_http_net_peer_name_server( - result: MutableMapping[str, AttributeValue], - name: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, NET_PEER_NAME, name) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, CLIENT_ADDRESS, name) - - -# Database - - -def _set_db_system( - result: MutableMapping[str, AttributeValue], - system: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, DB_SYSTEM, system) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, DB_SYSTEM_NAME, system) - - -def _set_db_name( - result: MutableMapping[str, AttributeValue], - name: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, DB_NAME, name) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, DB_NAMESPACE, name) - - -def _set_db_statement( - result: MutableMapping[str, AttributeValue], - statement: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - # skip the statement if it's None but set it if it's an empty string - if statement is None: - return - - if _report_old(sem_conv_opt_in_mode): - result[DB_STATEMENT] = statement - if _report_new(sem_conv_opt_in_mode): - result[DB_QUERY_TEXT] = statement - - -def _set_db_user( - result: MutableMapping[str, AttributeValue], - user: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, DB_USER, user) - # No new attribute - db.user was removed with no replacement - - -def _set_db_operation( - result: MutableMapping[str, AttributeValue], - operation: str, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, DB_OPERATION, operation) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, DB_OPERATION_NAME, operation) - - -def _set_db_redis_database_index( - result: MutableMapping[str, AttributeValue], - database_index: int, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - if database_index is not None: - result[DB_REDIS_DATABASE_INDEX] = int(database_index) - # No new attribute - db.redis.database_index was removed with no replacement in semconv 1.38.0 - - -def _set_net_transport( - result: MutableMapping[str, AttributeValue], - old_transport: AttributeValue, - new_transport: AttributeValue, - sem_conv_opt_in_mode: _StabilityMode, -) -> None: - if _report_old(sem_conv_opt_in_mode): - set_string_attribute(result, NET_TRANSPORT, old_transport) - if _report_new(sem_conv_opt_in_mode): - set_string_attribute(result, NETWORK_TRANSPORT, new_transport) - - -# General - - -def _set_status( - span: Span, - metrics_attributes: MutableMapping[str, AttributeValue], - status_code: int, - status_code_str: str, - server_span: bool = True, - sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, -) -> None: - if status_code < 0: - if _report_new(sem_conv_opt_in_mode): - metrics_attributes[ERROR_TYPE] = status_code_str - if span.is_recording(): - if _report_new(sem_conv_opt_in_mode): - span.set_attribute(ERROR_TYPE, status_code_str) - span.set_status( - Status( - StatusCode.ERROR, - "Non-integer HTTP status: " + status_code_str, - ) - ) - else: - status = http_status_to_status_code(status_code, server_span=server_span) - - if _report_old(sem_conv_opt_in_mode): - if span.is_recording(): - span.set_attribute(HTTP_STATUS_CODE, status_code) - metrics_attributes[HTTP_STATUS_CODE] = status_code - if _report_new(sem_conv_opt_in_mode): - if span.is_recording(): - span.set_attribute(HTTP_RESPONSE_STATUS_CODE, status_code) - metrics_attributes[HTTP_RESPONSE_STATUS_CODE] = status_code - if status == StatusCode.ERROR: - if span.is_recording(): - span.set_attribute(ERROR_TYPE, status_code_str) - metrics_attributes[ERROR_TYPE] = status_code_str - if span.is_recording(): - span.set_status(Status(status)) - - -def _get_schema_url(mode: _StabilityMode) -> str: - """Get schema version URL for a single signal type's opt-in mode (backwards compatible). - - For new instrumentations using multiple signal types, use - _get_schema_url_for_signal_types() - """ - if mode is _StabilityMode.DEFAULT: - return f"https://opentelemetry.io/schemas/{_LEGACY_SCHEMA_VERSION}" - return Schemas.V1_21_0.value - - -def _get_schema_version_for_opt_in_mode( - signal_type: _OpenTelemetryStabilitySignalType, - mode: _StabilityMode, -) -> str: - """Get the schema version for a specific signal type and opt-in mode.""" - if mode == _StabilityMode.DEFAULT: - return _LEGACY_SCHEMA_VERSION - - signal_versions = { - _OpenTelemetryStabilitySignalType.HTTP: Schemas.V1_21_0.value, - _OpenTelemetryStabilitySignalType.DATABASE: Schemas.V1_25_0.value, - _OpenTelemetryStabilitySignalType.GEN_AI: Schemas.V1_26_0.value, - } - schema_url = signal_versions.get(signal_type) - if not schema_url: - return _LEGACY_SCHEMA_VERSION - - path = urlparse(schema_url).path - schema_version = path.rstrip("/").split("/")[-1] - return schema_version or _LEGACY_SCHEMA_VERSION - - -def _get_schema_url_for_signal_types( - signal_types: list[_OpenTelemetryStabilitySignalType], -) -> str: - """Get the highest applicable schema URL for multiple signal types. - - Note: - Instrumentors should call _OpenTelemetrySemanticConventionStability._initialize() - before using this function to ensure proper initialization of stability modes. - - Args: - signal_types: List of signal types used by the instrumentation - - Returns: - Schema URL string representing the highest applicable semconv version - """ - highest_schema_version = _LEGACY_SCHEMA_VERSION - for signal_type in signal_types: - mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(signal_type) - schema_version = _get_schema_version_for_opt_in_mode(signal_type, mode) - # Keep the highest for all signals - if package_version.Version(schema_version) > package_version.Version(highest_schema_version): - highest_schema_version = schema_version - return f"https://opentelemetry.io/schemas/{highest_schema_version}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py deleted file mode 100644 index ac89a699b92..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/__init__.py +++ /dev/null @@ -1,721 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -The opentelemetry-instrumentation-aiohttp-client package allows tracing HTTP -requests made by the aiohttp client library. - -Usage ------ -Explicitly instrumenting a single client session: - -.. code:: python - - import asyncio - import aiohttp - from opentelemetry.instrumentation.aiohttp_client import create_trace_config - import yarl - - def strip_query_params(url: yarl.URL) -> str: - return str(url.with_query(None)) - - async def get(url): - async with aiohttp.ClientSession(trace_configs=[create_trace_config( - # Remove all query params from the URL attribute on the span. - url_filter=strip_query_params, - )]) as session: - async with session.get(url) as response: - await response.text() - - asyncio.run(get("https://example.com")) - -Instrumenting all client sessions: - -.. code:: python - - import asyncio - import aiohttp - from opentelemetry.instrumentation.aiohttp_client import ( - AioHttpClientInstrumentor - ) - - # Enable instrumentation - AioHttpClientInstrumentor().instrument() - - # Create a session and make an HTTP get request - async def get(url): - async with aiohttp.ClientSession() as session: - async with session.get(url) as response: - await response.text() - - asyncio.run(get("https://example.com")) - -Configuration -------------- - -Request/Response hooks -********************** - -Utilize request/response hooks to execute custom logic to be performed before/after performing a request. - -.. code-block:: python - - def request_hook(span: Span, params: aiohttp.TraceRequestStartParams): - if span and span.is_recording(): - span.set_attribute("custom_user_attribute_from_request_hook", "some-value") - - - def response_hook( - span: Span, - params: typing.Union[ - aiohttp.TraceRequestEndParams, - aiohttp.TraceRequestExceptionParams, - ], - ): - if span and span.is_recording(): - span.set_attribute("custom_user_attribute_from_response_hook", "some-value") - - - AioHttpClientInstrumentor().instrument(request_hook=request_hook, response_hook=response_hook) - -Exclude lists -************* -To exclude certain URLs from tracking, set the environment variable ``OTEL_PYTHON_AIOHTTP_CLIENT_EXCLUDED_URLS`` -(or ``OTEL_PYTHON_EXCLUDED_URLS`` to cover all instrumentations) to a string of comma delimited regexes that match the -URLs. - -For example, - -:: - - export OTEL_PYTHON_AIOHTTP_CLIENT_EXCLUDED_URLS="client/.*/info,healthcheck" - -will exclude requests such as ``https://site/client/123/info`` and ``https://site/xyz/healthcheck``. - -Capture HTTP request and response headers -***************************************** -You can configure the agent to capture specified HTTP headers as span attributes, according to the -`semantic conventions `_. - -Request headers -*************** -To capture HTTP request headers as span attributes, set the environment variable -``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST`` to a comma delimited list of HTTP header names. - -For example using the environment variable, -:: - - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST="content-type,custom_request_header" - -will extract ``content-type`` and ``custom_request_header`` from the request headers and add them as span attributes. - -Request header names in aiohttp are case-insensitive. So, giving the header name as ``CUStom-Header`` in the environment -variable will capture the header named ``custom-header``. - -Regular expressions may also be used to match multiple headers that correspond to the given pattern. For example: -:: - - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST="Accept.*,X-.*" - -Would match all request headers that start with ``Accept`` and ``X-``. - -To capture all request headers, set ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST`` to ``".*"``. -:: - - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST=".*" - -The name of the added span attribute will follow the format ``http.request.header.`` where ```` -is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a -single item list containing all the header values. - -For example: -``http.request.header.custom_request_header = ["", ""]`` - -Response headers -**************** -To capture HTTP response headers as span attributes, set the environment variable -``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE`` to a comma delimited list of HTTP header names. - -For example using the environment variable, -:: - - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE="content-type,custom_response_header" - -will extract ``content-type`` and ``custom_response_header`` from the response headers and add them as span attributes. - -Response header names in aiohttp are case-insensitive. So, giving the header name as ``CUStom-Header`` in the environment -variable will capture the header named ``custom-header``. - -Regular expressions may also be used to match multiple headers that correspond to the given pattern. For example: -:: - - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE="Content.*,X-.*" - -Would match all response headers that start with ``Content`` and ``X-``. - -To capture all response headers, set ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE`` to ``".*"``. -:: - - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE=".*" - -The name of the added span attribute will follow the format ``http.response.header.`` where ```` -is the normalized HTTP header name (lowercase, with ``-`` replaced by ``_``). The value of the attribute will be a -list containing the header values. - -For example: -``http.response.header.custom_response_header = ["", ""]`` - -Sanitizing headers -****************** -In order to prevent storing sensitive data such as personally identifiable information (PII), session keys, passwords, -etc, set the environment variable ``OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS`` -to a comma delimited list of HTTP header names to be sanitized. - -Regexes may be used, and all header names will be matched in a case-insensitive manner. - -For example using the environment variable, -:: - - export OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS=".*session.*,set-cookie" - -will replace the value of headers such as ``session-id`` and ``set-cookie`` with ``[REDACTED]`` in the span. - -Note: - The environment variable names used to capture HTTP headers are still experimental, and thus are subject to change. - -API ---- -""" - -from __future__ import annotations - -import types -import typing -from collections.abc import Callable, Collection -from timeit import default_timer -from typing import ( - TYPE_CHECKING, - Any, - TypedDict, - cast, -) -from urllib.parse import urlparse - -import aiohttp -from opentelemetry.agent._vendor import wrapt -import yarl - -from opentelemetry.agent._vendor.opentelemetry import context as context_api -from opentelemetry.agent._vendor.opentelemetry import trace -from opentelemetry.agent._vendor.opentelemetry.instrumentation._semconv import ( - HTTP_DURATION_HISTOGRAM_BUCKETS_NEW, - HTTP_DURATION_HISTOGRAM_BUCKETS_OLD, - _client_duration_attrs_new, - _client_duration_attrs_old, - _filter_semconv_duration_attrs, - _get_schema_url, - _OpenTelemetrySemanticConventionStability, - _OpenTelemetryStabilitySignalType, - _report_new, - _report_old, - _set_http_host_client, - _set_http_method, - _set_http_net_peer_name_client, - _set_http_peer_port_client, - _set_http_url, - _set_status, - _StabilityMode, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.aiohttp_client.package import _instruments -from opentelemetry.agent._vendor.opentelemetry.instrumentation.aiohttp_client.version import __version__ -from opentelemetry.agent._vendor.opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import ( - is_http_instrumentation_enabled, - unwrap, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter -from opentelemetry.agent._vendor.opentelemetry.propagate import inject -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE -from opentelemetry.agent._vendor.opentelemetry.semconv.metrics import ( - MetricInstruments, # type: ignore[reportDeprecated] -) -from opentelemetry.agent._vendor.opentelemetry.semconv.metrics.http_metrics import ( - HTTP_CLIENT_REQUEST_DURATION, -) -from opentelemetry.agent._vendor.opentelemetry.trace import Span, SpanKind, TracerProvider, get_tracer -from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode -from opentelemetry.agent._vendor.opentelemetry.util.http import ( - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST, - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE, - OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS, - get_custom_header_attributes, - get_custom_headers, - get_excluded_urls, - normalise_request_header_name, - normalise_response_header_name, - redact_url, - sanitize_method, -) - -if TYPE_CHECKING: - from opentelemetry.agent._vendor.typing_extensions import Unpack - - UrlFilterT = Callable[[yarl.URL], str] | None - RequestHookT = Callable[[Span, aiohttp.TraceRequestStartParams], None] | None - ResponseHookT = ( - Callable[ - [ - Span, - aiohttp.TraceRequestEndParams | aiohttp.TraceRequestExceptionParams, - ], - None, - ] - | None - ) - - class ClientSessionInitKwargs(TypedDict, total=False): - trace_configs: typing.Sequence[aiohttp.TraceConfig] - - class InstrumentKwargs(TypedDict, total=False): - tracer_provider: trace.TracerProvider - meter_provider: MeterProvider - url_filter: UrlFilterT - request_hook: RequestHookT - response_hook: ResponseHookT - trace_configs: typing.Sequence[aiohttp.TraceConfig] - - class UninstrumentKwargs(TypedDict, total=False): - pass - - -def _get_span_name(method: str) -> str: - method = sanitize_method(method.strip()) - if method == "_OTHER": - method = "HTTP" - return method - - -def _set_http_status_code_attribute( - span: Span, - status_code: int, - metric_attributes: dict[str, Any] | None = None, - sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, -): - status_code_str = str(status_code) - try: - status_code = int(status_code) - except ValueError: - status_code = -1 - if metric_attributes is None: - metric_attributes = {} - # When we have durations we should set metrics only once - # Also the decision to include status code on a histogram should - # not be dependent on tracing decisions. - _set_status( - span, - metric_attributes, - status_code, - status_code_str, - server_span=False, - sem_conv_opt_in_mode=sem_conv_opt_in_mode, - ) - - -# pylint: disable=too-many-locals -# pylint: disable=too-many-statements -def create_trace_config( - url_filter: UrlFilterT = None, - request_hook: RequestHookT = None, - response_hook: ResponseHookT = None, - tracer_provider: TracerProvider | None = None, - meter_provider: MeterProvider | None = None, - sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, - captured_request_headers: list[str] | None = None, - captured_response_headers: list[str] | None = None, - sensitive_headers: list[str] | None = None, -) -> aiohttp.TraceConfig: - """Create an aiohttp-compatible trace configuration. - - One span is created for the entire HTTP request, including initial - TCP/TLS setup if the connection doesn't exist. - - By default the span name is set to the HTTP request method. - - Example usage: - - .. code:: python - - import aiohttp - from opentelemetry.instrumentation.aiohttp_client import create_trace_config - - async with aiohttp.ClientSession(trace_configs=[create_trace_config()]) as session: - async with session.get(url) as response: - await response.text() - - - :param url_filter: A callback to process the requested URL prior to adding - it as a span attribute. This can be useful to remove sensitive data - such as API keys or user personal information. - - :param Callable request_hook: Optional callback that can modify span name and request params. - :param Callable response_hook: Optional callback that can modify span name and response params. - :param tracer_provider: optional TracerProvider from which to get a Tracer - :param meter_provider: optional Meter provider to use - :param captured_request_headers: List of HTTP request header regexes to capture as - span attributes. Header names matching these patterns will be added as span - attributes with the format ``http.request.header.``. - :param captured_response_headers: List of HTTP response header regexes to capture as - span attributes. Header names matching these patterns will be added as span - attributes with the format ``http.response.header.``. - :param sensitive_headers: List of HTTP header regexes whose values should be - sanitized (redacted) when captured. Header values matching these patterns - will be replaced with ``[REDACTED]``. - - :return: An object suitable for use with :py:class:`aiohttp.ClientSession`. - :rtype: :py:class:`aiohttp.TraceConfig` - """ - # `aiohttp.TraceRequestStartParams` resolves to `aiohttp.tracing.TraceRequestStartParams` - # which doesn't exist in the aiohttp intersphinx inventory. - # Explicitly specify the type for the `request_hook` and `response_hook` param and rtype to work - # around this issue. - - schema_url = _get_schema_url(sem_conv_opt_in_mode) - - tracer = get_tracer( - __name__, - __version__, - tracer_provider, - schema_url=schema_url, - ) - - meter = get_meter( - __name__, - __version__, - meter_provider, - schema_url, - ) - - duration_histogram_old = None - if _report_old(sem_conv_opt_in_mode): - duration_histogram_old = meter.create_histogram( - name=MetricInstruments.HTTP_CLIENT_DURATION, # type: ignore[reportDeprecated] - unit="ms", - description="measures the duration of the outbound HTTP request", - explicit_bucket_boundaries_advisory=HTTP_DURATION_HISTOGRAM_BUCKETS_OLD, - ) - duration_histogram_new = None - if _report_new(sem_conv_opt_in_mode): - duration_histogram_new = meter.create_histogram( - name=HTTP_CLIENT_REQUEST_DURATION, - unit="s", - description="Duration of HTTP client requests.", - explicit_bucket_boundaries_advisory=HTTP_DURATION_HISTOGRAM_BUCKETS_NEW, - ) - - excluded_urls = get_excluded_urls("AIOHTTP_CLIENT") - - def _end_trace(trace_config_ctx: types.SimpleNamespace): - elapsed_time = max(default_timer() - trace_config_ctx.start_time, 0) - if trace_config_ctx.token: - context_api.detach(trace_config_ctx.token) - if trace_config_ctx.span: - trace_config_ctx.span.end() - - if trace_config_ctx.duration_histogram_old is not None: - duration_attrs_old = cast( - dict[str, Any], - _filter_semconv_duration_attrs( - trace_config_ctx.metric_attributes, - _client_duration_attrs_old, - _client_duration_attrs_new, - _StabilityMode.DEFAULT, - ), - ) - trace_config_ctx.duration_histogram_old.record( - max(round(elapsed_time * 1000), 0), - attributes=duration_attrs_old, - ) - if trace_config_ctx.duration_histogram_new is not None: - duration_attrs_new = cast( - dict[str, Any], - _filter_semconv_duration_attrs( - trace_config_ctx.metric_attributes, - _client_duration_attrs_old, - _client_duration_attrs_new, - _StabilityMode.HTTP, - ), - ) - trace_config_ctx.duration_histogram_new.record(elapsed_time, attributes=duration_attrs_new) - - async def on_request_start( - _session: aiohttp.ClientSession, - trace_config_ctx: types.SimpleNamespace, - params: aiohttp.TraceRequestStartParams, - ): - if not is_http_instrumentation_enabled() or trace_config_ctx.excluded_urls.url_disabled(str(params.url)): - return - - trace_config_ctx.start_time = default_timer() - method = params.method - request_span_name = _get_span_name(method) - request_url = ( - redact_url(cast(Callable[[yarl.URL], str], trace_config_ctx.url_filter)(params.url)) - if callable(trace_config_ctx.url_filter) - else redact_url(str(params.url)) - ) - - span_attributes: dict[str, Any] = {} - _set_http_method( - span_attributes, - method, - sanitize_method(method), - sem_conv_opt_in_mode, - ) - _set_http_method( - trace_config_ctx.metric_attributes, - method, - sanitize_method(method), - sem_conv_opt_in_mode, - ) - _set_http_url(span_attributes, request_url, sem_conv_opt_in_mode) - - try: - parsed_url = urlparse(request_url) - if parsed_url.hostname: - _set_http_host_client( - trace_config_ctx.metric_attributes, - parsed_url.hostname, - sem_conv_opt_in_mode, - ) - _set_http_net_peer_name_client( - trace_config_ctx.metric_attributes, - parsed_url.hostname, - sem_conv_opt_in_mode, - ) - if _report_new(sem_conv_opt_in_mode): - _set_http_host_client( - span_attributes, - parsed_url.hostname, - sem_conv_opt_in_mode, - ) - if parsed_url.port: - _set_http_peer_port_client( - trace_config_ctx.metric_attributes, - parsed_url.port, - sem_conv_opt_in_mode, - ) - if _report_new(sem_conv_opt_in_mode): - _set_http_peer_port_client(span_attributes, parsed_url.port, sem_conv_opt_in_mode) - except ValueError: - pass - - span_attributes.update( - get_custom_header_attributes( - {key: params.headers.getall(key) for key in params.headers.keys()}, - captured_request_headers, - sensitive_headers, - normalise_request_header_name, - ) - ) - - trace_config_ctx.span = trace_config_ctx.tracer.start_span( - request_span_name, kind=SpanKind.CLIENT, attributes=span_attributes - ) - - if callable(request_hook): - request_hook(trace_config_ctx.span, params) - - trace_config_ctx.token = context_api.attach(trace.set_span_in_context(trace_config_ctx.span)) - - inject(params.headers) - - async def on_request_end( - _session: aiohttp.ClientSession, - trace_config_ctx: types.SimpleNamespace, - params: aiohttp.TraceRequestEndParams, - ): - if trace_config_ctx.span is None: - return - - if callable(response_hook): - response_hook(trace_config_ctx.span, params) - _set_http_status_code_attribute( - trace_config_ctx.span, - params.response.status, - trace_config_ctx.metric_attributes, - sem_conv_opt_in_mode, - ) - - trace_config_ctx.span.set_attributes( - get_custom_header_attributes( - {key: params.response.headers.getall(key) for key in params.response.headers.keys()}, - captured_response_headers, - sensitive_headers, - normalise_response_header_name, - ) - ) - - _end_trace(trace_config_ctx) - - async def on_request_exception( - _session: aiohttp.ClientSession, - trace_config_ctx: types.SimpleNamespace, - params: aiohttp.TraceRequestExceptionParams, - ): - if trace_config_ctx.span is None: - return - - if trace_config_ctx.span.is_recording() and params.exception: - exc_type = type(params.exception).__qualname__ - if _report_new(sem_conv_opt_in_mode): - trace_config_ctx.span.set_attribute(ERROR_TYPE, exc_type) - trace_config_ctx.metric_attributes[ERROR_TYPE] = exc_type - - trace_config_ctx.span.set_status(Status(StatusCode.ERROR, exc_type)) - trace_config_ctx.span.record_exception(params.exception) - - if callable(response_hook): - response_hook(trace_config_ctx.span, params) - - _end_trace(trace_config_ctx) - - def _trace_config_ctx_factory(**kwargs: Any) -> types.SimpleNamespace: - kwargs.setdefault("trace_request_ctx", {}) - return types.SimpleNamespace( - tracer=tracer, - span=None, - token=None, - duration_histogram_old=duration_histogram_old, - duration_histogram_new=duration_histogram_new, - metric_attributes={}, - url_filter=url_filter, - excluded_urls=excluded_urls, - start_time=0, - **kwargs, - ) - - trace_config = aiohttp.TraceConfig( - trace_config_ctx_factory=cast(type[types.SimpleNamespace], _trace_config_ctx_factory) - ) - - trace_config.on_request_start.append(on_request_start) - trace_config.on_request_end.append(on_request_end) - trace_config.on_request_exception.append(on_request_exception) - - return trace_config - - -def _instrument( - tracer_provider: TracerProvider | None = None, - meter_provider: MeterProvider | None = None, - url_filter: UrlFilterT = None, - request_hook: RequestHookT = None, - response_hook: ResponseHookT = None, - trace_configs: typing.Sequence[aiohttp.TraceConfig] | None = None, - sem_conv_opt_in_mode: _StabilityMode = _StabilityMode.DEFAULT, - captured_request_headers: list[str] | None = None, - captured_response_headers: list[str] | None = None, - sensitive_headers: list[str] | None = None, -): - """Enables tracing of all ClientSessions - - When a ClientSession gets created a TraceConfig is automatically added to - the session's trace_configs. - """ - - trace_configs = trace_configs or () - - # pylint:disable=unused-argument - def instrumented_init( - wrapped: Callable[..., None], - _instance: aiohttp.ClientSession, - args: tuple[Any, ...], - kwargs: ClientSessionInitKwargs, - ): - client_trace_configs = list(kwargs.get("trace_configs") or []) - client_trace_configs.extend(trace_configs) - - trace_config = create_trace_config( - url_filter=url_filter, - request_hook=request_hook, - response_hook=response_hook, - tracer_provider=tracer_provider, - meter_provider=meter_provider, - sem_conv_opt_in_mode=sem_conv_opt_in_mode, - captured_request_headers=captured_request_headers, - captured_response_headers=captured_response_headers, - sensitive_headers=sensitive_headers, - ) - setattr(trace_config, "_is_instrumented_by_opentelemetry", True) - client_trace_configs.append(trace_config) - - kwargs["trace_configs"] = client_trace_configs - return wrapped(*args, **kwargs) - - wrapt.wrap_function_wrapper( # type: ignore[reportUnknownVariableType] - aiohttp.ClientSession, "__init__", instrumented_init - ) - - -def _uninstrument(): - """Disables instrumenting for all newly created ClientSessions""" - unwrap(aiohttp.ClientSession, "__init__") - - -def _uninstrument_session(client_session: aiohttp.ClientSession): - """Disables instrumentation for the given ClientSession""" - # pylint: disable=protected-access - trace_configs = client_session._trace_configs - client_session._trace_configs = [ - trace_config for trace_config in trace_configs if not hasattr(trace_config, "_is_instrumented_by_opentelemetry") - ] - - -class AioHttpClientInstrumentor(BaseInstrumentor): - """An instrumentor for aiohttp client sessions - - See `BaseInstrumentor` - """ - - def instrumentation_dependencies(self) -> Collection[str]: - return _instruments - - def _instrument(self, **kwargs: Unpack[InstrumentKwargs]): - """Instruments aiohttp ClientSession - - Args: - **kwargs: Optional arguments - ``tracer_provider``: a TracerProvider, defaults to global - ``meter_provider``: a MeterProvider, defaults to global - ``url_filter``: A callback to process the requested URL prior to adding - it as a span attribute. This can be useful to remove sensitive data - such as API keys or user personal information. - ``request_hook``: An optional callback that is invoked right after a span is created. - ``response_hook``: An optional callback which is invoked right before the span is finished processing a response. - ``trace_configs``: An optional list of aiohttp.TraceConfig items, allowing customize enrichment of spans - based on aiohttp events (see specification: https://docs.aiohttp.org/en/stable/tracing_reference.html) - """ - _OpenTelemetrySemanticConventionStability._initialize() - _sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode( - _OpenTelemetryStabilitySignalType.HTTP, - ) - _instrument( - tracer_provider=kwargs.get("tracer_provider"), - meter_provider=kwargs.get("meter_provider"), - url_filter=kwargs.get("url_filter"), - request_hook=kwargs.get("request_hook"), - response_hook=kwargs.get("response_hook"), - trace_configs=kwargs.get("trace_configs"), - sem_conv_opt_in_mode=_sem_conv_opt_in_mode, - captured_request_headers=get_custom_headers(OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST), - captured_response_headers=get_custom_headers(OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE), - sensitive_headers=get_custom_headers(OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS), - ) - - def _uninstrument(self, **kwargs: Unpack[UninstrumentKwargs]): - _uninstrument() - - @staticmethod - def uninstrument_session(client_session: aiohttp.ClientSession): - """Disables instrumentation for the given session""" - _uninstrument_session(client_session) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py deleted file mode 100644 index 0e356f89fb4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/package.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -_instruments = ("aiohttp ~= 3.0",) - -_supports_metrics = True - -_semconv_status = "migration" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/aiohttp_client/version.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py deleted file mode 100644 index d5728026249..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/__init__.py +++ /dev/null @@ -1,168 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from argparse import REMAINDER, ArgumentParser -from logging import getLogger -from os import environ, execl, getcwd -from os.path import abspath, dirname, pathsep -from re import sub -from shutil import which - -from opentelemetry.agent._vendor.opentelemetry.instrumentation.auto_instrumentation._load import ( - _load_configurators, - _load_distro, - _load_instrumentors, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.environment_variables import ( - OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import _python_path_without_directory -from opentelemetry.agent._vendor.opentelemetry.instrumentation.version import __version__ -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points - -_logger = getLogger(__name__) - - -def run() -> None: - parser = ArgumentParser( - description=""" - opentelemetry-instrument automatically instruments a Python - program and its dependencies and then runs the program. - """, - epilog=""" - Optional arguments (except for --help and --version) for opentelemetry-instrument - directly correspond with OpenTelemetry environment variables. The - corresponding optional argument is formed by removing the OTEL_ or - OTEL_PYTHON_ prefix from the environment variable and lower casing the - rest. For example, the optional argument --attribute_value_length_limit - corresponds with the environment variable - OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT. - - These optional arguments will override the current value of the - corresponding environment variable during the execution of the command. - """, - ) - - argument_otel_environment_variable = {} - - for entry_point in entry_points(group="opentelemetry_environment_variables"): - environment_variable_module = entry_point.load() - - for attribute in dir(environment_variable_module): - if attribute.startswith("OTEL_"): - argument = sub(r"OTEL_(PYTHON_)?", "", attribute).lower() - - parser.add_argument( - f"--{argument}", - required=False, - ) - argument_otel_environment_variable[argument] = attribute - - parser.add_argument( - "--version", - help="print version information", - action="version", - version="%(prog)s " + __version__, - ) - parser.add_argument("command", help="Your Python application.") - parser.add_argument( - "command_args", - help="Arguments for your application.", - nargs=REMAINDER, - ) - - args = parser.parse_args() - - for argument, otel_environment_variable in (argument_otel_environment_variable).items(): - value = getattr(args, argument) - if value is not None: - environ[otel_environment_variable] = value - - python_path = environ.get("PYTHONPATH") - - if not python_path: - python_path = [] - - else: - python_path = python_path.split(pathsep) - - cwd_path = getcwd() - - # This is being added to support applications that are being run from their - # own executable, like Django. - # FIXME investigate if there is another way to achieve this - if cwd_path not in python_path: - python_path.insert(0, cwd_path) - - filedir_path = dirname(abspath(__file__)) - - python_path = [path for path in python_path if path != filedir_path] - - python_path.insert(0, filedir_path) - - environ["PYTHONPATH"] = pathsep.join(python_path) - - executable = which(args.command) - execl(executable, executable, *args.command_args) - - -def _initialize(*, swallow_exceptions: bool = True) -> None: - # handle optional gevent monkey patching. This is done via environment variables so it may be used from the - # opentelemetry operator - gevent_patch: str | None = environ.get(OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH) - if gevent_patch is not None: - if gevent_patch != "patch_all": - _logger.error( - "%s value must be `patch_all`", - OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH, - ) - else: - try: - # pylint: disable=import-outside-toplevel - from gevent import monkey # noqa: PLC0415 - - getattr(monkey, gevent_patch)() - except ImportError: - _logger.exception("Failed to monkey patch with gevent because gevent is not available") - if not swallow_exceptions: - raise - - try: - distro = _load_distro() - distro.configure() - _load_configurators() - _load_instrumentors(distro) - except Exception as exc: # pylint: disable=broad-except - _logger.exception("Failed to auto initialize OpenTelemetry") - if not swallow_exceptions: - raise exc - - -def initialize(*, swallow_exceptions: bool = True) -> None: - """ - Setup auto-instrumentation, called by the sitecustomize module - - :param swallow_exceptions: Whether or not to propagate instrumentation exceptions to the caller. Exceptions are logged and swallowed by default. - """ - filedir = dirname(abspath(__file__)) - - python_path = environ.get("PYTHONPATH") - auto_instrumentation_path_was_present = python_path is not None and filedir in python_path.split(pathsep) - - # Remove the auto-instrumentation path during initialization to prevent - # auto-instrumentation from executing in subprocesses spawned during this phase. - # This suppression is performed to avoid creating a recursive loop scenario - # where subprocesses spawned in the initialization phase execute the - # initialization phase again, spawning more subprocesses. - if python_path is not None: - environ["PYTHONPATH"] = _python_path_without_directory(python_path, filedir, pathsep) - - try: - _initialize(swallow_exceptions=swallow_exceptions) - finally: - if auto_instrumentation_path_was_present: - current = environ.get("PYTHONPATH", "") - if filedir not in current.split(pathsep): - environ["PYTHONPATH"] = filedir + pathsep + current if current else filedir diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py deleted file mode 100644 index 436f2ba88be..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/_load.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from functools import cached_property -from logging import getLogger -from os import environ - -from opentelemetry.agent._vendor.opentelemetry.instrumentation.dependencies import ( - DependencyConflictError, - get_dist_dependency_conflicts, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.distro import BaseDistro, DefaultDistro -from opentelemetry.agent._vendor.opentelemetry.instrumentation.environment_variables import ( - OTEL_PYTHON_CONFIGURATOR, - OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, - OTEL_PYTHON_DISTRO, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.version import __version__ -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( - EntryPoint, - distributions, - entry_points, -) - -_logger = getLogger(__name__) - -SKIPPED_INSTRUMENTATIONS_WILDCARD = "*" - - -class _EntryPointDistFinder: - @cached_property - def _mapping(self): - return {self._key_for(ep): dist for dist in distributions() for ep in dist.entry_points} - - def dist_for(self, entry_point: EntryPoint): - dist = getattr(entry_point, "dist", None) - if dist: - return dist - - return self._mapping.get(self._key_for(entry_point)) - - @staticmethod - def _key_for(entry_point: EntryPoint): - return f"{entry_point.group}:{entry_point.name}:{entry_point.value}" - - -def _load_distro() -> BaseDistro: - distro_name = environ.get(OTEL_PYTHON_DISTRO, None) - for entry_point in entry_points(group="opentelemetry_distro"): - try: - # If no distro is specified, use first to come up. - if distro_name is None or distro_name == entry_point.name: - distro = entry_point.load()() - if not isinstance(distro, BaseDistro): - _logger.debug( - "%s is not an OpenTelemetry Distro. Skipping", - entry_point.name, - ) - continue - _logger.debug("Distribution %s will be configured", entry_point.name) - return distro - except Exception as exc: # pylint: disable=broad-except - _logger.exception("Distribution %s configuration failed", entry_point.name) - raise exc - return DefaultDistro() - - -def _load_instrumentors(distro): - package_to_exclude = environ.get(OTEL_PYTHON_DISABLED_INSTRUMENTATIONS, []) - entry_point_finder = _EntryPointDistFinder() - if isinstance(package_to_exclude, str): - package_to_exclude = package_to_exclude.split(",") - # to handle users entering "requests , flask" or "requests, flask" with spaces - package_to_exclude = [x.strip() for x in package_to_exclude] - - for entry_point in entry_points(group="opentelemetry_pre_instrument"): - entry_point.load()() - - for entry_point in entry_points(group="opentelemetry_instrumentor"): - if SKIPPED_INSTRUMENTATIONS_WILDCARD in package_to_exclude: - break - - if entry_point.name in package_to_exclude: - _logger.debug("Instrumentation skipped for library %s", entry_point.name) - continue - - try: - entry_point_dist = entry_point_finder.dist_for(entry_point) - conflict = get_dist_dependency_conflicts(entry_point_dist) - if conflict: - conflict._log(_logger, entry_point.name) - continue - - # tell instrumentation to not run dep checks again as we already did it above - distro.load_instrumentor(entry_point, skip_dep_check=True) - _logger.debug("Instrumented %s", entry_point.name) - except DependencyConflictError as exc: - # Dependency conflicts are generally caught from get_dist_dependency_conflicts - # returning a DependencyConflict. Keeping this error handling in case custom - # distro and instrumentor behavior raises a DependencyConflictError later. - # See https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610 - exc.conflict._log(_logger, entry_point.name) - continue - except ModuleNotFoundError as exc: - # ModuleNotFoundError is raised when the library is not installed - # and the instrumentation is not required to be loaded. - # See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/3421 - _logger.debug("Skipping instrumentation %s: %s", entry_point.name, exc.msg) - continue - except ImportError: - # in scenarios using the kubernetes operator to do autoinstrumentation some - # instrumentors (usually requiring binary extensions) may fail to load - # because the injected autoinstrumentation code does not match the application - # environment regarding python version, libc, etc... In this case it's better - # to skip the single instrumentation rather than failing to load everything - # so treat differently ImportError than the rest of exceptions - _logger.exception("Importing of %s failed, skipping it", entry_point.name) - continue - except Exception as exc: # pylint: disable=broad-except - _logger.exception("Instrumenting of %s failed", entry_point.name) - raise exc - - for entry_point in entry_points(group="opentelemetry_post_instrument"): - entry_point.load()() - - -def _load_configurators(): - configurator_name = environ.get(OTEL_PYTHON_CONFIGURATOR, None) - configured = None - for entry_point in entry_points(group="opentelemetry_configurator"): - if configured is not None: - _logger.warning( - "Configuration of %s not loaded, %s already loaded", - entry_point.name, - configured, - ) - continue - try: - if configurator_name is None or configurator_name == entry_point.name: - entry_point.load()().configure(auto_instrumentation_version=__version__) # type: ignore - configured = entry_point.name - else: - _logger.warning( - "Configuration of %s not loaded because %s is set by %s", - entry_point.name, - configurator_name, - OTEL_PYTHON_CONFIGURATOR, - ) - except Exception as exc: # pylint: disable=broad-except - _logger.exception("Configuration of %s failed", entry_point.name) - raise exc diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py deleted file mode 100644 index 46407e2987f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation/sitecustomize.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.instrumentation.auto_instrumentation import initialize - -initialize() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py deleted file mode 100644 index 29c3c40e522..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import argparse -import logging -import sys -from subprocess import ( - PIPE, - CalledProcessError, - Popen, - SubprocessError, - check_call, -) - -from opentelemetry.agent._vendor.packaging.requirements import Requirement - -from opentelemetry.agent._vendor.opentelemetry.instrumentation.bootstrap_gen import ( - default_instrumentations as gen_default_instrumentations, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.bootstrap_gen import ( - libraries as gen_libraries, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.version import __version__ -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( - PackageNotFoundError, - version, -) - -logger = logging.getLogger(__name__) - - -def _syscall(func): - def wrapper(package=None): - try: - if package: - return func(package) - return func() - except SubprocessError as exp: - cmd = getattr(exp, "cmd", None) - if cmd: - msg = f'Error calling system command "{" ".join(cmd)}"' - if package: - msg = f'{msg} for package "{package}"' - raise RuntimeError(msg) - - return wrapper - - -@_syscall -def _sys_pip_install(package): - # explicit upgrade strategy to override potential pip config - try: - check_call( - [ - sys.executable, - "-m", - "pip", - "install", - "-U", - "--upgrade-strategy", - "only-if-needed", - package, - ] - ) - except CalledProcessError as error: - print(error) - - -def _pip_check(libraries): - """Ensures none of the instrumentations have dependency conflicts. - Clean check reported as: - 'No broken requirements found.' - Dependency conflicts are reported as: - 'opentelemetry-instrumentation-flask 1.0.1 has requirement opentelemetry-sdk<2.0,>=1.0, but you have opentelemetry-sdk 0.5.' - To not be too restrictive, we'll only check for relevant packages. - """ - with Popen([sys.executable, "-m", "pip", "check"], stdout=PIPE) as check_pipe: - pip_check = check_pipe.communicate()[0].decode() - pip_check_lower = pip_check.lower() - for package_tup in libraries: - for package in package_tup: - if package.lower() in pip_check_lower: - raise RuntimeError(f"Dependency conflict found: {pip_check}") - - -def _is_installed(req): - req = Requirement(req) - - try: - dist_version = version(req.name) - except PackageNotFoundError: - return False - - if not req.specifier.filter(dist_version): - logger.warning( - "instrumentation for package %s is available but version %s is installed. Skipping.", - req, - dist_version, - ) - return False - return True - - -def _find_installed_libraries(default_instrumentations, libraries): - yield from default_instrumentations - - for lib in libraries: - if _is_installed(lib["library"]): - yield lib["instrumentation"] - - -def _run_requirements(default_instrumentations, libraries): - logger.setLevel(logging.ERROR) - print("\n".join(_find_installed_libraries(default_instrumentations, libraries))) - - -def _run_install(default_instrumentations, libraries): - for lib in _find_installed_libraries(default_instrumentations, libraries): - _sys_pip_install(lib) - _pip_check(libraries) - - -def run( - default_instrumentations: list | None = None, - libraries: list | None = None, -) -> None: - action_install = "install" - action_requirements = "requirements" - - parser = argparse.ArgumentParser( - description=""" - opentelemetry-bootstrap detects installed libraries and automatically - installs the relevant instrumentation packages for them. - """ - ) - parser.add_argument( - "--version", - help="print version information", - action="version", - version="%(prog)s " + __version__, - ) - parser.add_argument( - "-a", - "--action", - choices=[action_install, action_requirements], - default=action_requirements, - help=""" - install - uses pip to install the new requirements using to the - currently active site-package. - requirements - prints out the new requirements to stdout. Action can - be piped and appended to a requirements.txt file. - """, - ) - args = parser.parse_args() - - if libraries is None: - libraries = gen_libraries - - if default_instrumentations is None: - default_instrumentations = gen_default_instrumentations - - cmd = { - action_install: _run_install, - action_requirements: _run_requirements, - }[args.action] - cmd(default_instrumentations, libraries) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py deleted file mode 100644 index 15959848204..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/bootstrap_gen.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# DO NOT EDIT. THIS FILE WAS AUTOGENERATED FROM INSTRUMENTATION PACKAGES. -# RUN `python scripts/generate_instrumentation_bootstrap.py` TO REGENERATE. - -libraries = [ - {"library": "openai >= 1.26.0", "instrumentation": "opentelemetry-instrumentation-openai-v2"}, - {"library": "google-cloud-aiplatform >= 1.64", "instrumentation": "opentelemetry-instrumentation-vertexai>=2.0b0"}, - {"library": "aio_pika >= 7.2.0, < 11.0.0", "instrumentation": "opentelemetry-instrumentation-aio-pika==0.66b2"}, - {"library": "aiohttp ~= 3.0", "instrumentation": "opentelemetry-instrumentation-aiohttp-client==0.66b2"}, - {"library": "aiohttp ~= 3.0", "instrumentation": "opentelemetry-instrumentation-aiohttp-server==0.66b2"}, - {"library": "aiokafka >= 0.8, < 1.0", "instrumentation": "opentelemetry-instrumentation-aiokafka==0.66b2"}, - {"library": "aiopg >= 0.13.0, < 2.0.0", "instrumentation": "opentelemetry-instrumentation-aiopg==0.66b2"}, - {"library": "asgiref ~= 3.0", "instrumentation": "opentelemetry-instrumentation-asgi==0.66b2"}, - {"library": "asyncclick ~= 8.0", "instrumentation": "opentelemetry-instrumentation-asyncclick==0.66b2"}, - {"library": "asyncpg >= 0.12.0", "instrumentation": "opentelemetry-instrumentation-asyncpg==0.66b2"}, - {"library": "boto3 ~= 1.0", "instrumentation": "opentelemetry-instrumentation-boto3sqs==0.66b2"}, - {"library": "botocore ~= 1.0", "instrumentation": "opentelemetry-instrumentation-botocore==0.66b2"}, - {"library": "aiobotocore >= 2.0, < 4.0", "instrumentation": "opentelemetry-instrumentation-botocore==0.66b2"}, - {"library": "cassandra-driver ~= 3.25", "instrumentation": "opentelemetry-instrumentation-cassandra==0.66b2"}, - {"library": "scylla-driver ~= 3.25", "instrumentation": "opentelemetry-instrumentation-cassandra==0.66b2"}, - {"library": "celery >= 4.0, < 6.0", "instrumentation": "opentelemetry-instrumentation-celery==0.66b2"}, - {"library": "click >= 8.1.3, < 9.0.0", "instrumentation": "opentelemetry-instrumentation-click==0.66b2"}, - { - "library": "confluent-kafka >= 1.8.2, < 3.0.0", - "instrumentation": "opentelemetry-instrumentation-confluent-kafka==0.66b2", - }, - {"library": "django >= 2.0", "instrumentation": "opentelemetry-instrumentation-django==0.66b2"}, - {"library": "falcon >= 1.4.1, < 5.0.0", "instrumentation": "opentelemetry-instrumentation-falcon==0.66b2"}, - {"library": "fastapi ~= 0.92", "instrumentation": "opentelemetry-instrumentation-fastapi==0.66b2"}, - {"library": "flask >= 1.0", "instrumentation": "opentelemetry-instrumentation-flask==0.66b2"}, - {"library": "grpcio >= 1.42.0", "instrumentation": "opentelemetry-instrumentation-grpc==0.66b2"}, - {"library": "httpx >= 0.18.0", "instrumentation": "opentelemetry-instrumentation-httpx==0.66b2"}, - {"library": "httpx2 >= 2.0.0", "instrumentation": "opentelemetry-instrumentation-httpx==0.66b2"}, - {"library": "jinja2 >= 2.7, < 4.0", "instrumentation": "opentelemetry-instrumentation-jinja2==0.66b2"}, - {"library": "kafka-python >= 2.0, < 4.0", "instrumentation": "opentelemetry-instrumentation-kafka-python==0.66b2"}, - {"library": "mysql-connector-python >= 8.0", "instrumentation": "opentelemetry-instrumentation-mysql==0.66b2"}, - {"library": "mysqlclient < 3", "instrumentation": "opentelemetry-instrumentation-mysqlclient==0.66b2"}, - {"library": "pika >= 0.12.0", "instrumentation": "opentelemetry-instrumentation-pika==0.66b2"}, - {"library": "psycopg >= 3.1.0", "instrumentation": "opentelemetry-instrumentation-psycopg==0.66b2"}, - {"library": "psycopg2 >= 2.7.3.1", "instrumentation": "opentelemetry-instrumentation-psycopg2==0.66b2"}, - {"library": "psycopg2-binary >= 2.7.3.1", "instrumentation": "opentelemetry-instrumentation-psycopg2==0.66b2"}, - {"library": "pymemcache >= 1.3.5, < 5", "instrumentation": "opentelemetry-instrumentation-pymemcache==0.66b2"}, - {"library": "pymongo >= 3.1, < 5.0", "instrumentation": "opentelemetry-instrumentation-pymongo==0.66b2"}, - {"library": "pymssql >= 2.1.5, < 3", "instrumentation": "opentelemetry-instrumentation-pymssql==0.66b2"}, - {"library": "PyMySQL < 2", "instrumentation": "opentelemetry-instrumentation-pymysql==0.66b2"}, - {"library": "pyramid >= 1.7", "instrumentation": "opentelemetry-instrumentation-pyramid==0.66b2"}, - {"library": "redis >= 2.6", "instrumentation": "opentelemetry-instrumentation-redis==0.66b2"}, - {"library": "remoulade >= 0.50", "instrumentation": "opentelemetry-instrumentation-remoulade==0.66b2"}, - {"library": "requests ~= 2.0", "instrumentation": "opentelemetry-instrumentation-requests==0.66b2"}, - {"library": "sqlalchemy >= 1.0.0, < 2.1.0", "instrumentation": "opentelemetry-instrumentation-sqlalchemy==0.66b2"}, - {"library": "starlette >= 0.13", "instrumentation": "opentelemetry-instrumentation-starlette==0.66b2"}, - {"library": "structlog >= 21.1", "instrumentation": "opentelemetry-instrumentation-structlog==0.66b2"}, - {"library": "psutil >= 5", "instrumentation": "opentelemetry-instrumentation-system-metrics==0.66b2"}, - {"library": "tornado >= 5.1.1", "instrumentation": "opentelemetry-instrumentation-tornado==0.66b2"}, - {"library": "tortoise-orm >= 0.17.0", "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.66b2"}, - {"library": "pydantic >= 1.10.2", "instrumentation": "opentelemetry-instrumentation-tortoiseorm==0.66b2"}, - {"library": "urllib3 >= 1.0.0, < 3.0.0", "instrumentation": "opentelemetry-instrumentation-urllib3==0.66b2"}, -] -default_instrumentations = [ - "opentelemetry-instrumentation-asyncio==0.66b2", - "opentelemetry-instrumentation-dbapi==0.66b2", - "opentelemetry-instrumentation-exceptions==0.66b2", - "opentelemetry-instrumentation-logging==0.66b2", - "opentelemetry-instrumentation-sqlite3==0.66b2", - "opentelemetry-instrumentation-threading==0.66b2", - "opentelemetry-instrumentation-urllib==0.66b2", - "opentelemetry-instrumentation-wsgi==0.66b2", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py deleted file mode 100644 index 86814840a72..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/cidict.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Iterable, Iterator, Mapping, MutableMapping -from typing import ( - Any, - TypeVar, -) - -KT = TypeVar("KT") -VT = TypeVar("VT") - - -class CIDict(MutableMapping[KT, VT]): - def __init__( - self, - data: Mapping[KT, VT] | Iterable[tuple[KT, VT]] | None = None, - ) -> None: - self._data: dict[KT, tuple[KT, VT]] = {} - if data is None: - data = {} - self.update(data) - - @staticmethod - def _normalize_key(key: KT) -> KT: - if isinstance(key, str): - return key.lower() # type: ignore - return key - - def _get_entry(self, key: KT) -> tuple[KT, VT]: - normalized_key = self._normalize_key(key) - if normalized_key in self._data: - return self._data[normalized_key] - raise KeyError(repr(key)) - - def original_key(self, key: KT) -> KT: - return self._get_entry(key)[0] - - def normalized_items(self) -> Iterable[tuple[KT, VT]]: - return ((key, value[1]) for key, value in self._data.items()) - - def __setitem__(self, key: KT, value: VT, /) -> None: - self._data[self._normalize_key(key)] = (key, value) - - def __delitem__(self, key: KT, /) -> None: - try: - del self._data[self._normalize_key(key)] - except KeyError: - raise KeyError(repr(key)) from None - - def __getitem__(self, key: KT, /) -> VT: - return self._get_entry(key)[1] - - def __len__(self) -> int: - return len(self._data) - - def __iter__(self) -> Iterator[KT]: - return (key for key, _ in self._data.values()) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({dict(self.items())!r})" - - def __eq__(self, other: object) -> bool: - if isinstance(other, CIDict): - return dict(self.normalized_items()) == dict(other.normalized_items()) - if not isinstance(other, Mapping): - return False - ciother: CIDict[Any, Any] = CIDict(other) - return dict(self.normalized_items()) == dict(ciother.normalized_items()) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py deleted file mode 100644 index 9620154134c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/dependencies.py +++ /dev/null @@ -1,209 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Collection -from logging import Logger, getLogger - -from opentelemetry.agent._vendor.packaging.requirements import InvalidRequirement, Requirement - -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( - Distribution, - PackageNotFoundError, - version, -) - -_logger = getLogger(__name__) - - -def _format_deps(deps: Collection[str]) -> str: - return ", ".join(str(dep) for dep in deps) - - -class DependencyConflict: - """Represents a dependency conflict in OpenTelemetry instrumentation. - - This class is used to track conflicts between required dependencies and the - actual installed packages. It supports two scenarios: - - 1. Standard conflicts where all dependencies are required - 2. Either/or conflicts where only one of a set of dependencies is required - - Attributes: - required: The required dependency specification that conflicts with what's installed. - found: The actual dependency that was found installed (if any). - required_any: Collection of dependency specifications where any one would satisfy - the requirement (for either/or scenarios). - found_any: Collection of actual dependencies found for either/or scenarios. - """ - - required: str | None = None - found: str | None = None - # The following fields are used when an instrumentation requires any of a set of dependencies rather than all. - required_any: Collection[str] = None - found_any: Collection[str] = None - - def __init__( - self, - required: str | None = None, - found: str | None = None, - required_any: Collection[str] = None, - found_any: Collection[str] = None, - ): - self.required = required - self.found = found - # The following fields are used when an instrumentation requires any of a set of dependencies rather than all. - self.required_any = required_any - self.found_any = found_any - - @property - def _is_version_conflict(self) -> bool: - """False when the dependency is not installed at all, rather than installed at an incompatible version.""" - return bool(self.found or self.found_any) - - def _log(self, logger: Logger, instrumentor_name: str) -> None: - """Log as an error for a version conflict, at debug level when the dependency is not installed.""" - log = logger.error if self._is_version_conflict else logger.debug - log(self._format_message(instrumentor_name)) - - def _format_message(self, instrumentor_name: str | None = None) -> str: - subject = instrumentor_name or "This instrumentation" - if self.required: - if self.found: - return ( - f'{subject} only instruments "{self.required}", ' - f'but currently installed version ("{self.found}") falls outside of that range, ' - f"so nothing can be instrumented." - ) - return ( - f'{subject} only instruments "{self.required}", ' - f"but no installed version was found, so nothing can be instrumented." - ) - if self.required_any: - if self.found_any: - return ( - f'{subject} instruments any of "{_format_deps(self.required_any)}", ' - f'but currently installed version(s) ("{_format_deps(self.found_any)}") fall outside of that range, ' - f"so nothing can be instrumented." - ) - return ( - f'{subject} requires any of "{_format_deps(self.required_any)}", ' - f"but none are installed, so nothing can be instrumented." - ) - return f"{subject} has an unknown dependency conflict, so nothing can be instrumented." - - def __str__(self): - return self._format_message() - - -class DependencyConflictError(Exception): - conflict: DependencyConflict - - def __init__(self, conflict: DependencyConflict): - self.conflict = conflict - - def __str__(self): - return str(self.conflict) - - -def get_dist_dependency_conflicts( - dist: Distribution, -) -> DependencyConflict | None: - instrumentation_deps = [] - instrumentation_any_deps = [] - extra = "extra" - instruments = "instruments" - instruments_marker = {extra: instruments} - instruments_any = "instruments-any" - instruments_any_marker = {extra: instruments_any} - if dist.requires: - for dep in dist.requires: - if extra not in dep: - continue - if instruments not in dep and instruments_any not in dep: - continue - - req = Requirement(dep) - if req.marker.evaluate(instruments_marker): # type: ignore - instrumentation_deps.append(req) # type: ignore - if req.marker.evaluate(instruments_any_marker): # type: ignore - instrumentation_any_deps.append(req) # type: ignore - return get_dependency_conflicts(instrumentation_deps, instrumentation_any_deps) # type: ignore - - -def get_dependency_conflicts( - deps: Collection[str | Requirement], # Dependencies all of which are required - deps_any: Collection[str | Requirement] | None = None, # Dependencies any of which are required -) -> DependencyConflict | None: - for dep in deps: - if isinstance(dep, Requirement): - req = dep - else: - try: - req = Requirement(dep) - except InvalidRequirement as exc: - _logger.warning( - 'error parsing dependency, reporting as a conflict: "%s" - %s', - dep, - exc, - ) - return DependencyConflict(dep) - - try: - dist_version = version(req.name) - except PackageNotFoundError: - return DependencyConflict(dep) - - if not req.specifier.contains(dist_version): - return DependencyConflict(dep, f"{req.name} {dist_version}") - - # If all the dependencies in "instruments" are present, check "instruments-any" for conflicts. - if deps_any: - return _get_dependency_conflicts_any(deps_any) - return None - - -# This is a helper functions designed to ease reading and meet linting requirements. -def _get_dependency_conflicts_any( - deps_any: Collection[str | Requirement], -) -> DependencyConflict | None: - if not deps_any: - return None - is_dependency_conflict = True - required_any: Collection[str] = [] - found_any: Collection[str] = [] - for dep in deps_any: - if isinstance(dep, Requirement): - req = dep - else: - try: - req = Requirement(dep) - except InvalidRequirement as exc: - _logger.warning( - 'error parsing dependency, reporting as a conflict: "%s" - %s', - dep, - exc, - ) - return DependencyConflict(dep) - - try: - dist_version = version(req.name) - except PackageNotFoundError: - required_any.append(str(dep)) - continue - - if req.specifier.contains(dist_version): - # Since only one of the instrumentation_any dependencies is required, there is no dependency conflict. - is_dependency_conflict = False - break - # If the version does not match, add it to the list of unfulfilled requirement options. - required_any.append(str(dep)) - found_any.append(f"{req.name} {dist_version}") - - if is_dependency_conflict: - return DependencyConflict( - required_any=required_any, - found_any=found_any, - ) - return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py deleted file mode 100644 index d9b259e9ca6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/distro.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -# type: ignore - -""" -OpenTelemetry Base Distribution (Distro) -""" - -from abc import ABC, abstractmethod -from logging import getLogger - -from opentelemetry.agent._vendor.opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import EntryPoint - -_LOG = getLogger(__name__) - - -class BaseDistro(ABC): - """An ABC for distro""" - - _instance = None - - def __new__(cls, *args, **kwargs): - if cls._instance is None: - cls._instance = object.__new__(cls, *args, **kwargs) - - return cls._instance - - @abstractmethod - def _configure(self, **kwargs): - """Configure the distribution""" - - def configure(self, **kwargs): - """Configure the distribution""" - self._configure(**kwargs) - - def load_instrumentor( # pylint: disable=no-self-use - self, entry_point: EntryPoint, **kwargs - ): - """Takes an instrumentation entry point and activates it by instantiating - and calling instrument() on it. - This is called for each opentelemetry_instrumentor entry point by auto - instrumentation. - - Distros can override this method to customize the behavior by - inspecting each entry point and configuring them in special ways, - passing additional arguments, load a replacement/fork instead, - skip loading entirely, etc. - """ - instrumentor: BaseInstrumentor = entry_point.load() - instrumentor().instrument(**kwargs) - - -class DefaultDistro(BaseDistro): - def _configure(self, **kwargs): - pass - - -__all__ = ["BaseDistro", "DefaultDistro"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py deleted file mode 100644 index 27773aadb7c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/environment_variables.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -OTEL_PYTHON_DISABLED_INSTRUMENTATIONS = "OTEL_PYTHON_DISABLED_INSTRUMENTATIONS" -""" -.. envvar:: OTEL_PYTHON_DISABLED_INSTRUMENTATIONS -""" - -OTEL_PYTHON_DISTRO = "OTEL_PYTHON_DISTRO" -""" -.. envvar:: OTEL_PYTHON_DISTRO -""" - -OTEL_PYTHON_CONFIGURATOR = "OTEL_PYTHON_CONFIGURATOR" -""" -.. envvar:: OTEL_PYTHON_CONFIGURATOR -""" - -OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH = ( - "OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH" -) -""" -.. envvar:: OTEL_PYTHON_AUTO_INSTRUMENTATION_EXPERIMENTAL_GEVENT_PATCH -""" - -OTEL_SEMCONV_STABILITY_OPT_IN = "OTEL_SEMCONV_STABILITY_OPT_IN" -""" -.. envvar:: OTEL_SEMCONV_STABILITY_OPT_IN - -Opt-in to stable semantic convention signals. -Comma-separated list of signals, e.g. ``http``, ``http/dup``. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py deleted file mode 100644 index e99d86f2e9b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/instrumentor.py +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -# type: ignore - -""" -OpenTelemetry Base Instrumentor -""" - -from __future__ import annotations - -from abc import ABC, abstractmethod -from collections.abc import Collection -from logging import getLogger -from typing import Any - -from opentelemetry.agent._vendor.opentelemetry.instrumentation._semconv import ( - _OpenTelemetrySemanticConventionStability, -) -from opentelemetry.agent._vendor.opentelemetry.instrumentation.dependencies import ( - DependencyConflict, - DependencyConflictError, - get_dependency_conflicts, -) - -_LOG = getLogger(__name__) - - -class BaseInstrumentor(ABC): - """An ABC for instrumentors. - - Child classes of this ABC should instrument specific third - party libraries or frameworks either by using the - ``opentelemetry-instrument`` command or by calling their methods - directly. - - Since every third party library or framework is different and has different - instrumentation needs, more methods can be added to the child classes as - needed to provide practical instrumentation to the end user. - """ - - _instance = None - _is_instrumented_by_opentelemetry = False - - def __new__(cls, *args, **kwargs): - if cls._instance is None: - cls._instance = object.__new__(cls) - - return cls._instance - - @property - def is_instrumented_by_opentelemetry(self): - return self._is_instrumented_by_opentelemetry - - @abstractmethod - def instrumentation_dependencies(self) -> Collection[str]: - """Return a list of python packages with versions that the will be instrumented. - - The format should be the same as used in requirements.txt or pyproject.toml. - - For example, if an instrumentation instruments requests 1.x, this method should look - like: - - def instrumentation_dependencies(self) -> Collection[str]: - return ['requests ~= 1.0'] - - This will ensure that the instrumentation will only be used when the specified library - is present in the environment. - """ - - def _instrument(self, **kwargs: Any): - """Instrument the library""" - - @abstractmethod - def _uninstrument(self, **kwargs: Any): - """Uninstrument the library""" - - def _check_dependency_conflicts(self) -> DependencyConflict | None: - dependencies = self.instrumentation_dependencies() - return get_dependency_conflicts(dependencies) - - def instrument(self, **kwargs: Any): - """Instrument the library - - This method will be called without any optional arguments by the - ``opentelemetry-instrument`` command. - - This means that calling this method directly without passing any - optional values should do the very same thing that the - ``opentelemetry-instrument`` command does. - """ - - if self._is_instrumented_by_opentelemetry: - _LOG.warning("Attempting to instrument while already instrumented") - return None - - # check if instrumentor has any missing or conflicting dependencies - skip_dep_check = kwargs.pop("skip_dep_check", False) - raise_exception_on_conflict = kwargs.pop("raise_exception_on_conflict", False) - if not skip_dep_check: - conflict = self._check_dependency_conflicts() - if conflict: - # auto-instrumentation path: don't log conflict as error, instead - # let _load_instrumentors handle the exception - if raise_exception_on_conflict: - raise DependencyConflictError(conflict) - # manual instrumentation path: log the conflict as error - _LOG.error(conflict._format_message(self.__class__.__name__)) - return None - - # initialize semantic conventions opt-in if needed - _OpenTelemetrySemanticConventionStability._initialize() - - result = self._instrument( # pylint: disable=assignment-from-no-return - **kwargs - ) - self._is_instrumented_by_opentelemetry = True - return result - - def uninstrument(self, **kwargs: Any): - """Uninstrument the library - - See ``BaseInstrumentor.instrument`` for more information regarding the - usage of ``kwargs``. - """ - - if self._is_instrumented_by_opentelemetry: - result = self._uninstrument(**kwargs) - self._is_instrumented_by_opentelemetry = False - return result - - _LOG.warning("Attempting to uninstrument while already uninstrumented") - - return None - - -__all__ = ["BaseInstrumentor"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py deleted file mode 100644 index df0bc280f69..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/log_utils.py +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry._logs import SeverityNumber - -_STD_TO_OTEL = { - 10: SeverityNumber.DEBUG, - 11: SeverityNumber.DEBUG2, - 12: SeverityNumber.DEBUG3, - 13: SeverityNumber.DEBUG4, - 14: SeverityNumber.DEBUG4, - 15: SeverityNumber.DEBUG4, - 16: SeverityNumber.DEBUG4, - 17: SeverityNumber.DEBUG4, - 18: SeverityNumber.DEBUG4, - 19: SeverityNumber.DEBUG4, - 20: SeverityNumber.INFO, - 21: SeverityNumber.INFO2, - 22: SeverityNumber.INFO3, - 23: SeverityNumber.INFO4, - 24: SeverityNumber.INFO4, - 25: SeverityNumber.INFO4, - 26: SeverityNumber.INFO4, - 27: SeverityNumber.INFO4, - 28: SeverityNumber.INFO4, - 29: SeverityNumber.INFO4, - 30: SeverityNumber.WARN, - 31: SeverityNumber.WARN2, - 32: SeverityNumber.WARN3, - 33: SeverityNumber.WARN4, - 34: SeverityNumber.WARN4, - 35: SeverityNumber.WARN4, - 36: SeverityNumber.WARN4, - 37: SeverityNumber.WARN4, - 38: SeverityNumber.WARN4, - 39: SeverityNumber.WARN4, - 40: SeverityNumber.ERROR, - 41: SeverityNumber.ERROR2, - 42: SeverityNumber.ERROR3, - 43: SeverityNumber.ERROR4, - 44: SeverityNumber.ERROR4, - 45: SeverityNumber.ERROR4, - 46: SeverityNumber.ERROR4, - 47: SeverityNumber.ERROR4, - 48: SeverityNumber.ERROR4, - 49: SeverityNumber.ERROR4, - 50: SeverityNumber.FATAL, - 51: SeverityNumber.FATAL2, - 52: SeverityNumber.FATAL3, - 53: SeverityNumber.FATAL4, -} - - -def std_to_otel(levelno: int) -> SeverityNumber: - """ - Map a Python log level number as defined in - https://docs.python.org/3/library/logging.html#logging-levels - to an OTel log severity number as defined in - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber - """ - if levelno < 10: - return SeverityNumber.UNSPECIFIED - if levelno > 53: - return SeverityNumber.FATAL4 - return _STD_TO_OTEL[levelno] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py deleted file mode 100644 index b405ae801e7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/propagators.py +++ /dev/null @@ -1,113 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -This module implements experimental propagators to inject trace context -into response carriers. This is useful for server side frameworks that start traces -when server requests and want to share the trace context with the client so the -client can add its spans to the same trace. - -This is part of an upcoming W3C spec and will eventually make it to the Otel spec. - -https://w3c.github.io/trace-context/#trace-context-http-response-headers-format -""" - -from abc import ABC, abstractmethod - -from opentelemetry.agent._vendor.opentelemetry import trace -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.propagators import textmap -from opentelemetry.agent._vendor.opentelemetry.trace import format_span_id, format_trace_id - -_HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers" -_RESPONSE_PROPAGATOR = None - - -def get_global_response_propagator(): - return _RESPONSE_PROPAGATOR - - -def set_global_response_propagator(propagator): - global _RESPONSE_PROPAGATOR # pylint:disable=global-statement - _RESPONSE_PROPAGATOR = propagator - - -class Setter(ABC): - @abstractmethod - def set(self, carrier, key, value): - """Inject the provided key value pair in carrier.""" - - -class DictHeaderSetter(Setter): - def set(self, carrier, key, value): # pylint: disable=no-self-use - old_value = carrier.get(key, "") - if old_value: - value = f"{old_value}, {value}" - carrier[key] = value - - -class FuncSetter(Setter): - """FuncSetter converts a function into a valid Setter. Any function that - can set values in a carrier can be converted into a Setter by using - FuncSetter. This is useful when injecting trace context into non-dict - objects such HTTP Response objects for different framework. - - For example, it can be used to create a setter for Falcon response object - as: - - setter = FuncSetter(falcon.api.Response.append_header) - - and then used with the propagator as: - - propagator.inject(falcon_response, setter=setter) - - This would essentially make the propagator call `falcon_response.append_header(key, value)` - """ - - def __init__(self, func): - self._func = func - - def set(self, carrier, key, value): - self._func(carrier, key, value) - - -default_setter = DictHeaderSetter() - - -class ResponsePropagator(ABC): - @abstractmethod - def inject( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - setter: textmap.Setter = default_setter, - ) -> None: - """Injects SpanContext into the HTTP response carrier.""" - - -class TraceResponsePropagator(ResponsePropagator): - """Experimental propagator that injects tracecontext into HTTP responses.""" - - def inject( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - setter: textmap.Setter = default_setter, - ) -> None: - """Injects SpanContext into the HTTP response carrier.""" - span = trace.get_current_span(context) - span_context = span.get_span_context() - if span_context == trace.INVALID_SPAN_CONTEXT: - return - - header_name = "traceresponse" - setter.set( - carrier, - header_name, - f"00-{format_trace_id(span_context.trace_id)}-{format_span_id(span_context.span_id)}-{span_context.trace_flags:02x}", - ) - setter.set( - carrier, - _HTTP_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, - header_name, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py deleted file mode 100644 index ad46f2c5925..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/sqlcommenter_utils.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import itertools -import sys -from typing import TYPE_CHECKING, Any - -from opentelemetry.agent._vendor.opentelemetry import context -from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import _url_quote - -if sys.version_info >= (3, 14): - from string.templatelib import Template as _Template -else: - _Template = () - -if TYPE_CHECKING: - if sys.version_info >= (3, 14): - from string.templatelib import Template - else: - from typing import Never - - Template = Never - from typing import overload - - @overload - def _add_sql_comment(sql: str, **meta: Any) -> str: ... - - @overload - def _add_sql_comment(sql: Template, **meta: Any) -> Template: ... - - -def _add_sql_comment(sql: str | Template, **meta: Any) -> str | Template: - """ - Appends comments to the sql statement and returns it - """ - meta.update(**_add_framework_tags()) - comment = _generate_sql_comment(**meta) - - if isinstance(sql, _Template): - last = sql.strings[-1].rstrip() - if last.endswith(";"): - last = last[:-1] + comment + ";" - else: - last += comment - args = [ - *itertools.chain.from_iterable(zip(sql.strings[:-1], sql.interpolations)), - last, - ] - return _Template(*args) - - sql = sql.rstrip() - if sql.endswith(";"): - sql = sql[:-1] + comment + ";" - else: - sql = sql + comment - return sql - - -def _generate_sql_comment(**meta) -> str: - """ - Return a SQL comment with comma delimited key=value pairs created from - **meta kwargs. - """ - key_value_delimiter = "," - - if not meta: # No entries added. - return "" - - # Sort the keywords to ensure that caching works and that testing is - # deterministic. It eases visual inspection as well. - return ( - " /*" - + key_value_delimiter.join( - f"{_url_quote(key)}={_url_quote(value)!r}" for key, value in sorted(meta.items()) if value is not None - ) - + "*/" - ) - - -def _add_framework_tags() -> dict: - """ - Returns orm related tags if any set by the context - """ - - sqlcommenter_framework_values = ( - context.get_value("SQLCOMMENTER_ORM_TAGS_AND_VALUES") - if context.get_value("SQLCOMMENTER_ORM_TAGS_AND_VALUES") - else {} - ) - return sqlcommenter_framework_values diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py deleted file mode 100644 index 73fa7dfb83a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/utils.py +++ /dev/null @@ -1,214 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import sys -import urllib.parse -from collections.abc import Generator, Sequence -from contextlib import contextmanager -from importlib import import_module -from re import escape, sub -from typing import Any - -try: - # wrapt 2.0.0+ - from opentelemetry.agent._vendor.wrapt import BaseObjectProxy # pylint: disable=no-name-in-module -except ImportError: - from opentelemetry.agent._vendor.wrapt import ObjectProxy as BaseObjectProxy - -from opentelemetry.agent._vendor.opentelemetry import context, trace - -# pylint: disable=E0611 -# FIXME: fix the importing of these private attributes when the location of the _SUPPRESS_HTTP_INSTRUMENTATION_KEY is defined.= -from opentelemetry.agent._vendor.opentelemetry.context import ( - _SUPPRESS_HTTP_INSTRUMENTATION_KEY, - _SUPPRESS_INSTRUMENTATION_KEY, -) - -# pylint: disable=E0611 -from opentelemetry.agent._vendor.opentelemetry.propagate import extract -from opentelemetry.agent._vendor.opentelemetry.trace import StatusCode -from opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext import ( - TraceContextTextMapPropagator, -) - -propagator = TraceContextTextMapPropagator() - -_SUPPRESS_INSTRUMENTATION_KEY_PLAIN = "suppress_instrumentation" # Set for backward compatibility - - -def extract_attributes_from_object( - obj: Any, attributes: Sequence[str], existing: dict[str, str] | None = None -) -> dict[str, str]: - extracted: dict[str, str] = {} - if existing: - extracted.update(existing) - for attr in attributes: - value = getattr(obj, attr, None) - if value is not None: - extracted[attr] = str(value) - return extracted - - -def http_status_to_status_code( - status: int, - allow_redirect: bool = True, - server_span: bool = False, -) -> StatusCode: - """Converts an HTTP status code to an OpenTelemetry canonical status code - - Args: - status (int): HTTP status code - """ - # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status - if not isinstance(status, int): - return StatusCode.UNSET - - if status < 100: - return StatusCode.ERROR - if status <= 299: - return StatusCode.UNSET - if status <= 399 and allow_redirect: - return StatusCode.UNSET - if status <= 499 and server_span: - return StatusCode.UNSET - return StatusCode.ERROR - - -def unwrap(obj: object, attr: str): - """Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it - - The object containing the function to unwrap may be passed as dotted module path string. - - Args: - obj: Object that holds a reference to the wrapped function or dotted import path as string - attr (str): Name of the wrapped function - """ - if isinstance(obj, str): - try: - module_path, class_name = obj.rsplit(".", 1) - except ValueError as exc: - raise ImportError(f"Cannot parse '{obj}' as dotted import path") from exc - if module_path not in sys.modules: - # Was never imported, meaning it could never have been wrapped - return - module = import_module(module_path) - try: - obj = getattr(module, class_name) - except AttributeError as exc: - raise ImportError(f"Cannot import '{class_name}' from '{module}'") from exc - - func = getattr(obj, attr, None) - if func and isinstance(func, BaseObjectProxy) and hasattr(func, "__wrapped__"): - setattr(obj, attr, func.__wrapped__) - - -def _start_internal_or_server_span( - tracer, - span_name, - start_time, - context_carrier, - context_getter, - attributes=None, -): - """Returns internal or server span along with the token which can be used by caller to reset context - - - Args: - tracer : tracer in use by given instrumentation library - span_name (string): name of the span - start_time : start time of the span - context_carrier : 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_getter : an object which contains a get function that can retrieve zero - or more values from the carrier and a keys function that can get all the keys - from carrier. - """ - - token = ctx = span_kind = None - if trace.get_current_span() is trace.INVALID_SPAN: - ctx = extract(context_carrier, getter=context_getter) - token = context.attach(ctx) - span_kind = trace.SpanKind.SERVER - else: - ctx = context.get_current() - span_kind = trace.SpanKind.INTERNAL - span = tracer.start_span( - name=span_name, - context=ctx, - kind=span_kind, - start_time=start_time, - attributes=attributes, - ) - return span, token - - -def _url_quote(s: Any) -> str: # pylint: disable=invalid-name - if not isinstance(s, (str, bytes)): - return s - quoted = urllib.parse.quote(s) - # Since SQL uses '%' as a keyword, '%' is a by-product of url quoting - # e.g. foo,bar --> foo%2Cbar - # thus in our quoting, we need to escape it too to finally give - # foo,bar --> foo%%2Cbar - return quoted.replace("%", "%%") - - -def _get_opentelemetry_values() -> dict[str, Any]: - """ - Return the OpenTelemetry Trace and Span IDs if Span ID is set in the - OpenTelemetry execution context. - """ - # Insert the W3C TraceContext generated - _headers: dict[str, Any] = {} - propagator.inject(_headers) - return _headers - - -def _python_path_without_directory(python_path, directory, path_separator): - return sub( - rf"{escape(directory)}{path_separator}(?!$)", - "", - python_path, - ) - - -def is_instrumentation_enabled() -> bool: - return not ( - context.get_value(_SUPPRESS_INSTRUMENTATION_KEY) or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY_PLAIN) - ) - - -def is_http_instrumentation_enabled() -> bool: - return is_instrumentation_enabled() and not context.get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY) - - -@contextmanager -def _suppress_instrumentation(*keys: str) -> Generator[None]: - """Suppress instrumentation within the context.""" - ctx = context.get_current() - for key in keys: - ctx = context.set_value(key, True, ctx) - token = context.attach(ctx) - try: - yield - finally: - if token: - context.detach(token) - - -@contextmanager -def suppress_instrumentation() -> Generator[None]: - """Suppress instrumentation within the context.""" - with _suppress_instrumentation(_SUPPRESS_INSTRUMENTATION_KEY, _SUPPRESS_INSTRUMENTATION_KEY_PLAIN): - yield - - -@contextmanager -def suppress_http_instrumentation() -> Generator[None]: - """Suppress instrumentation within the context.""" - with _suppress_instrumentation(_SUPPRESS_HTTP_INSTRUMENTATION_KEY): - yield diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/version.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py deleted file mode 100644 index c6660418e74..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/__init__.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -The OpenTelemetry metrics API describes the classes used to generate -metrics. - -The :class:`.MeterProvider` provides users access to the :class:`.Meter` which in -turn is used to create :class:`.Instrument` objects. The :class:`.Instrument` objects are -used to record measurements. - -This module provides abstract (i.e. unimplemented) classes required for -metrics, and a concrete no-op implementation :class:`.NoOpMeter` that allows applications -to use the API package alone without a supporting implementation. - -To get a meter, you need to provide the package name from which you are -calling the meter APIs to OpenTelemetry by calling `MeterProvider.get_meter` -with the calling instrumentation name and the version of your package. - -The following code shows how to obtain a meter using the global :class:`.MeterProvider`:: - - from opentelemetry.metrics import get_meter - - meter = get_meter("example-meter") - counter = meter.create_counter("example-counter") - -.. versionadded:: 1.10.0 -.. versionchanged:: 1.12.0rc -""" - -from opentelemetry.agent._vendor.opentelemetry.metrics._internal import ( - Meter, - MeterProvider, - NoOpMeter, - NoOpMeterProvider, - get_meter, - get_meter_provider, - set_meter_provider, -) -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import ( - Asynchronous, - CallbackOptions, - CallbackT, - Counter, - Histogram, - Instrument, - NoOpCounter, - NoOpHistogram, - NoOpObservableCounter, - NoOpObservableGauge, - NoOpObservableUpDownCounter, - NoOpUpDownCounter, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - Synchronous, - UpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import Gauge as _Gauge -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import NoOpGauge as _NoOpGauge -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.observation import Observation - -for obj in [ - Counter, - Synchronous, - Asynchronous, - CallbackOptions, - _Gauge, - _NoOpGauge, - get_meter_provider, - get_meter, - Histogram, - Meter, - MeterProvider, - Instrument, - NoOpCounter, - NoOpHistogram, - NoOpMeter, - NoOpMeterProvider, - NoOpObservableCounter, - NoOpObservableGauge, - NoOpObservableUpDownCounter, - NoOpUpDownCounter, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - Observation, - set_meter_provider, - UpDownCounter, -]: - obj.__module__ = __name__ - -__all__ = [ - "Asynchronous", - "CallbackOptions", - "CallbackT", - "Counter", - "Histogram", - "Instrument", - "Meter", - "MeterProvider", - "NoOpCounter", - "NoOpHistogram", - "NoOpMeter", - "NoOpMeterProvider", - "NoOpObservableCounter", - "NoOpObservableGauge", - "NoOpObservableUpDownCounter", - "NoOpUpDownCounter", - "ObservableCounter", - "ObservableGauge", - "ObservableUpDownCounter", - "Observation", - "Synchronous", - "UpDownCounter", - "_Gauge", - "_NoOpGauge", - "get_meter", - "get_meter_provider", - "set_meter_provider", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py deleted file mode 100644 index 4635d3bd412..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/__init__.py +++ /dev/null @@ -1,892 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=too-many-ancestors - -""" -The OpenTelemetry metrics API describes the classes used to generate -metrics. - -The :class:`.MeterProvider` provides users access to the :class:`.Meter` which in -turn is used to create :class:`.Instrument` objects. The :class:`.Instrument` objects are -used to record measurements. - -This module provides abstract (i.e. unimplemented) classes required for -metrics, and a concrete no-op implementation :class:`.NoOpMeter` that allows applications -to use the API package alone without a supporting implementation. - -To get a meter, you need to provide the package name from which you are -calling the meter APIs to OpenTelemetry by calling `MeterProvider.get_meter` -with the calling instrumentation name and the version of your package. - -The following code shows how to obtain a meter using the global :class:`.MeterProvider`:: - - from opentelemetry.metrics import get_meter - - meter = get_meter("example-meter") - counter = meter.create_counter("example-counter") - -.. versionadded:: 1.10.0 -""" - -import warnings -from abc import ABC, abstractmethod -from collections.abc import Sequence -from dataclasses import dataclass -from logging import getLogger -from os import environ -from threading import Lock -from typing import cast - -from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_METER_PROVIDER -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import ( - CallbackT, - Counter, - Gauge, - Histogram, - NoOpCounter, - NoOpGauge, - NoOpHistogram, - NoOpObservableCounter, - NoOpObservableGauge, - NoOpObservableUpDownCounter, - NoOpUpDownCounter, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - UpDownCounter, - _MetricsHistogramAdvisory, - _ProxyCounter, - _ProxyGauge, - _ProxyHistogram, - _ProxyObservableCounter, - _ProxyObservableGauge, - _ProxyObservableUpDownCounter, - _ProxyUpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.util._once import Once -from opentelemetry.agent._vendor.opentelemetry.util._providers import _load_provider -from opentelemetry.agent._vendor.opentelemetry.util.types import ( - Attributes, -) - -_logger = getLogger(__name__) - - -# pylint: disable=invalid-name -_ProxyInstrumentT = ( - _ProxyCounter - | _ProxyHistogram - | _ProxyGauge - | _ProxyObservableCounter - | _ProxyObservableGauge - | _ProxyObservableUpDownCounter - | _ProxyUpDownCounter -) - - -class MeterProvider(ABC): - """ - MeterProvider is the entry point of the API. It provides access to `Meter` instances. - """ - - @abstractmethod - def get_meter( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> "Meter": - """Returns a `Meter` for use by the given instrumentation library. - - For any two calls it is undefined whether the same or different - `Meter` instances are returned, even for different library names. - - This function may return different `Meter` types (e.g. a no-op meter - vs. a functional meter). - - Args: - name: The name of the instrumenting module. - ``__name__`` should be avoided as this can result in - different meter names if the meters are in different files. - It is better to use a fixed string that can be imported where - needed and used consistently as the name of the meter. - - This should *not* be the name of the module that is - instrumented but the name of the module doing the instrumentation. - E.g., instead of ``"requests"``, use - ``"opentelemetry.instrumentation.requests"``. - - version: Optional. The version string of the - instrumenting library. Usually this should be the same as - ``importlib.metadata.version(instrumenting_library_name)``. - - schema_url: Optional. Specifies the Schema URL of the emitted telemetry. - attributes: Optional. Attributes that are associated with the emitted telemetry. - """ - - -class NoOpMeterProvider(MeterProvider): - """The default MeterProvider used when no MeterProvider implementation is available.""" - - def get_meter( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> "Meter": - """Returns a NoOpMeter.""" - return NoOpMeter(name, version=version, schema_url=schema_url) - - -class _ProxyMeterProvider(MeterProvider): - def __init__(self) -> None: - self._lock = Lock() - self._meters: list[_ProxyMeter] = [] - self._real_meter_provider: MeterProvider | None = None - - def get_meter( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> "Meter": - with self._lock: - if self._real_meter_provider is not None: - return self._real_meter_provider.get_meter(name, version, schema_url) - - meter = _ProxyMeter(name, version=version, schema_url=schema_url) - self._meters.append(meter) - return meter - - def on_set_meter_provider(self, meter_provider: MeterProvider) -> None: - with self._lock: - self._real_meter_provider = meter_provider - for meter in self._meters: - meter.on_set_meter_provider(meter_provider) - - -@dataclass -class _InstrumentRegistrationStatus: - instrument_id: str - already_registered: bool - conflict: bool - current_advisory: _MetricsHistogramAdvisory | None - - -class Meter(ABC): - """Handles instrument creation. - - This class provides methods for creating instruments which are then - used to produce measurements. - """ - - def __init__( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - ) -> None: - super().__init__() - self._name = name - self._version = version - self._schema_url = schema_url - self._instrument_ids: dict[str, _MetricsHistogramAdvisory | None] = {} - self._instrument_ids_lock = Lock() - - @property - def name(self) -> str: - """ - The name of the instrumenting module. - """ - return self._name - - @property - def version(self) -> str | None: - """ - The version string of the instrumenting library. - """ - return self._version - - @property - def schema_url(self) -> str | None: - """ - Specifies the Schema URL of the emitted telemetry - """ - return self._schema_url - - def _register_instrument( - self, - name: str, - type_: type, - unit: str, - description: str, - advisory: _MetricsHistogramAdvisory | None = None, - ) -> _InstrumentRegistrationStatus: - """ - Register an instrument with the name, type, unit and description as - identifying keys and the advisory as value. - - Returns a tuple. The first value is the instrument id. - The second value is an `_InstrumentRegistrationStatus` where - `already_registered` is `True` if the instrument has been registered - already. - If `conflict` is set to True the `current_advisory` attribute contains - the registered instrument advisory. - """ - - instrument_id = ",".join([name.strip().lower(), type_.__name__, unit, description]) - - already_registered = False - conflict = False - current_advisory = None - - with self._instrument_ids_lock: - # we are not using get because None is a valid value - already_registered = instrument_id in self._instrument_ids - if already_registered: - current_advisory = self._instrument_ids[instrument_id] - conflict = current_advisory != advisory - else: - self._instrument_ids[instrument_id] = advisory - - return _InstrumentRegistrationStatus( - instrument_id=instrument_id, - already_registered=already_registered, - conflict=conflict, - current_advisory=current_advisory, - ) - - @staticmethod - def _log_instrument_registration_conflict( - name: str, - instrumentation_type: str, - unit: str, - description: str, - status: _InstrumentRegistrationStatus, - ) -> None: - _logger.warning( - "An instrument with name %s, type %s, unit %s and " - "description %s has been created already with a " - "different advisory value %s and will be used instead.", - name, - instrumentation_type, - unit, - description, - status.current_advisory, - ) - - @abstractmethod - def create_counter( - self, - name: str, - unit: str = "", - description: str = "", - ) -> Counter: - """Creates a `Counter` instrument - - Args: - name: The name of the instrument to be created - unit: The unit for observations this instrument reports. For - example, ``By`` for bytes. UCUM units are recommended. - description: A description for this instrument and what it measures. - """ - - @abstractmethod - def create_up_down_counter( - self, - name: str, - unit: str = "", - description: str = "", - ) -> UpDownCounter: - """Creates an `UpDownCounter` instrument - - Args: - name: The name of the instrument to be created - unit: The unit for observations this instrument reports. For - example, ``By`` for bytes. UCUM units are recommended. - description: A description for this instrument and what it measures. - """ - - @abstractmethod - def create_observable_counter( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableCounter: - """Creates an `ObservableCounter` instrument - - An observable counter observes a monotonically increasing count by calling provided - callbacks which accept a :class:`~opentelemetry.metrics.CallbackOptions` and return - multiple :class:`~opentelemetry.metrics.Observation`. - - For example, an observable counter could be used to report system CPU - time periodically. Here is a basic implementation:: - - def cpu_time_callback( - options: CallbackOptions, - ) -> Iterable[Observation]: - observations = [] - with open("/proc/stat") as procstat: - procstat.readline() # skip the first line - for line in procstat: - if not line.startswith("cpu"): - break - cpu, *states = line.split() - observations.append( - Observation( - int(states[0]) // 100, - {"cpu": cpu, "state": "user"}, - ) - ) - observations.append( - Observation( - int(states[1]) // 100, - {"cpu": cpu, "state": "nice"}, - ) - ) - observations.append( - Observation( - int(states[2]) // 100, - {"cpu": cpu, "state": "system"}, - ) - ) - # ... other states - return observations - - - meter.create_observable_counter( - "system.cpu.time", - callbacks=[cpu_time_callback], - unit="s", - description="CPU time", - ) - - To reduce memory usage, you can use generator callbacks instead of - building the full list:: - - def cpu_time_callback( - options: CallbackOptions, - ) -> Iterable[Observation]: - with open("/proc/stat") as procstat: - procstat.readline() # skip the first line - for line in procstat: - if not line.startswith("cpu"): - break - cpu, *states = line.split() - yield Observation( - int(states[0]) // 100, - {"cpu": cpu, "state": "user"}, - ) - yield Observation( - int(states[1]) // 100, - {"cpu": cpu, "state": "nice"}, - ) - # ... other states - - Alternatively, you can pass a sequence of generators directly instead of a sequence of - callbacks, which each should return iterables of :class:`~opentelemetry.metrics.Observation`:: - - def cpu_time_callback( - states_to_include: set[str], - ) -> Iterable[Iterable[Observation]]: - # accept options sent in from OpenTelemetry - options = yield - while True: - observations = [] - with open("/proc/stat") as procstat: - procstat.readline() # skip the first line - for line in procstat: - if not line.startswith("cpu"): - break - cpu, *states = line.split() - if "user" in states_to_include: - observations.append( - Observation( - int(states[0]) // 100, - {"cpu": cpu, "state": "user"}, - ) - ) - if "nice" in states_to_include: - observations.append( - Observation( - int(states[1]) // 100, - {"cpu": cpu, "state": "nice"}, - ) - ) - # ... other states - # yield the observations and receive the options for next iteration - options = yield observations - - - meter.create_observable_counter( - "system.cpu.time", - callbacks=[cpu_time_callback({"user", "system"})], - unit="s", - description="CPU time", - ) - - The :class:`~opentelemetry.metrics.CallbackOptions` contain a timeout which the - callback should respect. For example if the callback does asynchronous work, like - making HTTP requests, it should respect the timeout:: - - def scrape_http_callback( - options: CallbackOptions, - ) -> Iterable[Observation]: - r = requests.get( - "http://scrapethis.com", - timeout=options.timeout_millis / 10**3, - ) - for value in r.json(): - yield Observation(value) - - Args: - name: The name of the instrument to be created - callbacks: A sequence of callbacks that return an iterable of - :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a sequence of generators that each - yields iterables of :class:`~opentelemetry.metrics.Observation`. - unit: The unit for observations this instrument reports. For - example, ``By`` for bytes. UCUM units are recommended. - description: A description for this instrument and what it measures. - """ - - @abstractmethod - def create_histogram( - self, - name: str, - unit: str = "", - description: str = "", - *, - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - ) -> Histogram: - """Creates a :class:`~opentelemetry.metrics.Histogram` instrument - - Args: - name: The name of the instrument to be created - unit: The unit for observations this instrument reports. For - example, ``By`` for bytes. UCUM units are recommended. - description: A description for this instrument and what it measures. - """ - - def create_gauge( # type: ignore # pylint: disable=no-self-use - self, - name: str, - unit: str = "", - description: str = "", - ) -> Gauge: # pyright: ignore[reportReturnType] - """Creates a ``Gauge`` instrument - - Args: - name: The name of the instrument to be created - unit: The unit for observations this instrument reports. For - example, ``By`` for bytes. UCUM units are recommended. - description: A description for this instrument and what it measures. - """ - warnings.warn("create_gauge() is not implemented and will be a no-op") - - @abstractmethod - def create_observable_gauge( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableGauge: - """Creates an `ObservableGauge` instrument - - Args: - name: The name of the instrument to be created - callbacks: A sequence of callbacks that return an iterable of - :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a generator that yields iterables - of :class:`~opentelemetry.metrics.Observation`. - unit: The unit for observations this instrument reports. For - example, ``By`` for bytes. UCUM units are recommended. - description: A description for this instrument and what it measures. - """ - - @abstractmethod - def create_observable_up_down_counter( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableUpDownCounter: - """Creates an `ObservableUpDownCounter` instrument - - Args: - name: The name of the instrument to be created - callbacks: A sequence of callbacks that return an iterable of - :class:`~opentelemetry.metrics.Observation`. Alternatively, can be a generator that yields iterables - of :class:`~opentelemetry.metrics.Observation`. - unit: The unit for observations this instrument reports. For - example, ``By`` for bytes. UCUM units are recommended. - description: A description for this instrument and what it measures. - """ - - -class _ProxyMeter(Meter): - def __init__( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - ) -> None: - super().__init__(name, version=version, schema_url=schema_url) - self._lock = Lock() - self._instruments: list[_ProxyInstrumentT] = [] - self._real_meter: Meter | None = None - - def on_set_meter_provider(self, meter_provider: MeterProvider) -> None: - """Called when a real meter provider is set on the creating _ProxyMeterProvider - - Creates a real backing meter for this instance and notifies all created - instruments so they can create real backing instruments. - """ - real_meter = meter_provider.get_meter(self._name, self._version, self._schema_url) - - with self._lock: - self._real_meter = real_meter - # notify all proxy instruments of the new meter so they can create - # real instruments to back themselves - for instrument in self._instruments: - instrument.on_meter_set(real_meter) - - def create_counter( - self, - name: str, - unit: str = "", - description: str = "", - ) -> Counter: - with self._lock: - if self._real_meter: - return self._real_meter.create_counter(name, unit, description) - proxy = _ProxyCounter(name, unit, description) - self._instruments.append(proxy) - return proxy - - def create_up_down_counter( - self, - name: str, - unit: str = "", - description: str = "", - ) -> UpDownCounter: - with self._lock: - if self._real_meter: - return self._real_meter.create_up_down_counter(name, unit, description) - proxy = _ProxyUpDownCounter(name, unit, description) - self._instruments.append(proxy) - return proxy - - def create_observable_counter( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableCounter: - with self._lock: - if self._real_meter: - return self._real_meter.create_observable_counter(name, callbacks, unit, description) - proxy = _ProxyObservableCounter(name, callbacks, unit=unit, description=description) - self._instruments.append(proxy) - return proxy - - def create_histogram( - self, - name: str, - unit: str = "", - description: str = "", - *, - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - ) -> Histogram: - with self._lock: - if self._real_meter: - return self._real_meter.create_histogram( - name, - unit, - description, - explicit_bucket_boundaries_advisory=explicit_bucket_boundaries_advisory, - ) - proxy = _ProxyHistogram(name, unit, description, explicit_bucket_boundaries_advisory) - self._instruments.append(proxy) - return proxy - - def create_gauge( - self, - name: str, - unit: str = "", - description: str = "", - ) -> Gauge: - with self._lock: - if self._real_meter: - return self._real_meter.create_gauge(name, unit, description) - proxy = _ProxyGauge(name, unit, description) - self._instruments.append(proxy) - return proxy - - def create_observable_gauge( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableGauge: - with self._lock: - if self._real_meter: - return self._real_meter.create_observable_gauge(name, callbacks, unit, description) - proxy = _ProxyObservableGauge(name, callbacks, unit=unit, description=description) - self._instruments.append(proxy) - return proxy - - def create_observable_up_down_counter( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableUpDownCounter: - with self._lock: - if self._real_meter: - return self._real_meter.create_observable_up_down_counter( - name, - callbacks, - unit, - description, - ) - proxy = _ProxyObservableUpDownCounter(name, callbacks, unit=unit, description=description) - self._instruments.append(proxy) - return proxy - - -class NoOpMeter(Meter): - """The default Meter used when no Meter implementation is available. - - All operations are no-op. - """ - - def create_counter( - self, - name: str, - unit: str = "", - description: str = "", - ) -> Counter: - """Returns a no-op Counter.""" - status = self._register_instrument(name, NoOpCounter, unit, description) - if status.conflict: - self._log_instrument_registration_conflict( - name, - Counter.__name__, - unit, - description, - status, - ) - - return NoOpCounter(name, unit=unit, description=description) - - def create_gauge( - self, - name: str, - unit: str = "", - description: str = "", - ) -> Gauge: - """Returns a no-op Gauge.""" - status = self._register_instrument(name, NoOpGauge, unit, description) - if status.conflict: - self._log_instrument_registration_conflict( - name, - Gauge.__name__, - unit, - description, - status, - ) - return NoOpGauge(name, unit=unit, description=description) - - def create_up_down_counter( - self, - name: str, - unit: str = "", - description: str = "", - ) -> UpDownCounter: - """Returns a no-op UpDownCounter.""" - status = self._register_instrument(name, NoOpUpDownCounter, unit, description) - if status.conflict: - self._log_instrument_registration_conflict( - name, - UpDownCounter.__name__, - unit, - description, - status, - ) - return NoOpUpDownCounter(name, unit=unit, description=description) - - def create_observable_counter( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableCounter: - """Returns a no-op ObservableCounter.""" - status = self._register_instrument(name, NoOpObservableCounter, unit, description) - if status.conflict: - self._log_instrument_registration_conflict( - name, - ObservableCounter.__name__, - unit, - description, - status, - ) - return NoOpObservableCounter( - name, - callbacks, - unit=unit, - description=description, - ) - - def create_histogram( - self, - name: str, - unit: str = "", - description: str = "", - *, - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - ) -> Histogram: - """Returns a no-op Histogram.""" - status = self._register_instrument( - name, - NoOpHistogram, - unit, - description, - _MetricsHistogramAdvisory(explicit_bucket_boundaries=explicit_bucket_boundaries_advisory), - ) - if status.conflict: - self._log_instrument_registration_conflict( - name, - Histogram.__name__, - unit, - description, - status, - ) - return NoOpHistogram( - name, - unit=unit, - description=description, - explicit_bucket_boundaries_advisory=explicit_bucket_boundaries_advisory, - ) - - def create_observable_gauge( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableGauge: - """Returns a no-op ObservableGauge.""" - status = self._register_instrument(name, NoOpObservableGauge, unit, description) - if status.conflict: - self._log_instrument_registration_conflict( - name, - ObservableGauge.__name__, - unit, - description, - status, - ) - return NoOpObservableGauge( - name, - callbacks, - unit=unit, - description=description, - ) - - def create_observable_up_down_counter( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> ObservableUpDownCounter: - """Returns a no-op ObservableUpDownCounter.""" - status = self._register_instrument(name, NoOpObservableUpDownCounter, unit, description) - if status.conflict: - self._log_instrument_registration_conflict( - name, - ObservableUpDownCounter.__name__, - unit, - description, - status, - ) - return NoOpObservableUpDownCounter( - name, - callbacks, - unit=unit, - description=description, - ) - - -_METER_PROVIDER_SET_ONCE = Once() -_METER_PROVIDER: MeterProvider | None = None -_PROXY_METER_PROVIDER = _ProxyMeterProvider() - - -def get_meter( - name: str, - version: str = "", - meter_provider: MeterProvider | None = None, - schema_url: str | None = None, - attributes: Attributes = None, -) -> "Meter": - """Returns a `Meter` for use by the given instrumentation library. - - This function is a convenience wrapper for - `opentelemetry.metrics.MeterProvider.get_meter`. - - If meter_provider is omitted the current configured one is used. - """ - if meter_provider is None: - meter_provider = get_meter_provider() - return meter_provider.get_meter(name, version, schema_url, attributes) - - -def _set_meter_provider(meter_provider: MeterProvider, log: bool) -> None: - def set_mp() -> None: - global _METER_PROVIDER # pylint: disable=global-statement - _METER_PROVIDER = meter_provider - - # gives all proxies real instruments off the newly set meter provider - _PROXY_METER_PROVIDER.on_set_meter_provider(meter_provider) - - did_set = _METER_PROVIDER_SET_ONCE.do_once(set_mp) - - if log and not did_set: - _logger.warning("Overriding of current MeterProvider is not allowed") - - -def set_meter_provider(meter_provider: MeterProvider) -> None: - """Sets the current global :class:`~.MeterProvider` object. - - This can only be done once, a warning will be logged if any further attempt - is made. - """ - _set_meter_provider(meter_provider, log=True) - - -def get_meter_provider() -> MeterProvider: - """Gets the current global :class:`~.MeterProvider` object.""" - - if _METER_PROVIDER is None: - if OTEL_PYTHON_METER_PROVIDER not in environ: - return _PROXY_METER_PROVIDER - - meter_provider: MeterProvider = _load_provider( # type: ignore - OTEL_PYTHON_METER_PROVIDER, "meter_provider" - ) - _set_meter_provider(meter_provider, log=False) - - # _METER_PROVIDER will have been set by one thread - return cast("MeterProvider", _METER_PROVIDER) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py deleted file mode 100644 index 9dfa1057f4f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/instrument.py +++ /dev/null @@ -1,540 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=too-many-ancestors - - -from abc import ABC, abstractmethod -from collections.abc import Callable, Generator, Iterable, Sequence -from dataclasses import dataclass -from logging import getLogger -from re import compile as re_compile -from typing import ( - Generic, - TypeVar, -) - -# pylint: disable=unused-import; needed for typing and sphinx -from opentelemetry.agent._vendor.opentelemetry import metrics -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.observation import Observation -from opentelemetry.agent._vendor.opentelemetry.util.types import ( - Attributes, -) - -_logger = getLogger(__name__) - -_name_regex = re_compile(r"[a-zA-Z][-_./a-zA-Z0-9]{0,254}") -_unit_regex = re_compile(r"[\x00-\x7F]{0,63}") - - -@dataclass(frozen=True) -class _MetricsHistogramAdvisory: - explicit_bucket_boundaries: Sequence[float] | None = None - - -@dataclass(frozen=True) -class CallbackOptions: - """Options for the callback - - Args: - timeout_millis: Timeout for the callback's execution. If the callback does asynchronous - work (e.g. HTTP requests), it should respect this timeout. - """ - - timeout_millis: float = 10_000 - - -InstrumentT = TypeVar("InstrumentT", bound="Instrument") -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -class Instrument(ABC): - """Abstract class that serves as base for all instruments.""" - - @abstractmethod - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - ) -> None: - pass - - @staticmethod - def _check_name_unit_description(name: str, unit: str, description: str) -> dict[str, str | None]: - """ - Checks the following instrument name, unit and description for - compliance with the spec. - - Returns a dict with keys "name", "unit" and "description", the - corresponding values will be the checked strings or `None` if the value - is invalid. If valid, the checked strings should be used instead of the - original values. - """ - - result: dict[str, str | None] = {} - - if _name_regex.fullmatch(name) is not None: - result["name"] = name - else: - result["name"] = None - - if unit is None: - unit = "" - if _unit_regex.fullmatch(unit) is not None: - result["unit"] = unit - else: - result["unit"] = None - - if description is None: - result["description"] = "" - else: - result["description"] = description - - return result - - -class _ProxyInstrument(ABC, Generic[InstrumentT]): - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - ) -> None: - self._name = name - self._unit = unit - self._description = description - self._real_instrument: InstrumentT | None = None - - def on_meter_set(self, meter: "metrics.Meter") -> None: - """Called when a real meter is set on the creating _ProxyMeter""" - - # We don't need any locking on proxy instruments because it's OK if some - # measurements get dropped while a real backing instrument is being - # created. - self._real_instrument = self._create_real_instrument(meter) - - @abstractmethod - def _create_real_instrument(self, meter: "metrics.Meter") -> InstrumentT: - """Create an instance of the real instrument. Implement this.""" - - -class _ProxyAsynchronousInstrument(_ProxyInstrument[InstrumentT]): - def __init__( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> None: - super().__init__(name, unit, description) - self._callbacks = callbacks - - -class Synchronous(Instrument): - """Base class for all synchronous instruments""" - - -class Asynchronous(Instrument): - """Base class for all asynchronous instruments""" - - @abstractmethod - def __init__( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> None: - super().__init__(name, unit=unit, description=description) - - -class Counter(Synchronous): - """A Counter is a synchronous `Instrument` which supports non-negative increments.""" - - @abstractmethod - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - """Records an increment to the counter. - - Args: - amount: The amount to increment the counter by. Must be non-negative. - attributes: Optional set of attributes to associate with the measurement. - context: Optional context to associate with the measurement. If not - provided, the current context is used. - """ - - -class NoOpCounter(Counter): - """No-op implementation of `Counter`.""" - - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - ) -> None: - super().__init__(name, unit=unit, description=description) - - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - return super().add(amount, attributes=attributes, context=context) - - -class _ProxyCounter(_ProxyInstrument[Counter], Counter): - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - if self._real_instrument: - self._real_instrument.add(amount, attributes, context) - - def _create_real_instrument(self, meter: "metrics.Meter") -> Counter: - return meter.create_counter( - self._name, - self._unit, - self._description, - ) - - -class UpDownCounter(Synchronous): - """An UpDownCounter is a synchronous `Instrument` which supports increments and decrements.""" - - @abstractmethod - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - """Records an increment or decrement to the counter. - - Unlike `Counter`, the ``amount`` may be negative, allowing the - instrument to track values that go up and down (e.g. number of - active requests, queue depth). - - Args: - amount: The amount to add to the counter. May be positive or negative. - attributes: Optional set of attributes to associate with the measurement. - context: Optional context to associate with the measurement. If not - provided, the current context is used. - """ - - -class NoOpUpDownCounter(UpDownCounter): - """No-op implementation of `UpDownCounter`.""" - - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - ) -> None: - super().__init__(name, unit=unit, description=description) - - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - return super().add(amount, attributes=attributes, context=context) - - -class _ProxyUpDownCounter(_ProxyInstrument[UpDownCounter], UpDownCounter): - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - if self._real_instrument: - self._real_instrument.add(amount, attributes, context) - - def _create_real_instrument(self, meter: "metrics.Meter") -> UpDownCounter: - return meter.create_up_down_counter( - self._name, - self._unit, - self._description, - ) - - -class ObservableCounter(Asynchronous): - """An ObservableCounter is an asynchronous `Instrument` which reports monotonically - increasing value(s) when the instrument is being observed. - """ - - -class NoOpObservableCounter(ObservableCounter): - """No-op implementation of `ObservableCounter`.""" - - def __init__( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> None: - super().__init__( - name, - callbacks, - unit=unit, - description=description, - ) - - -class _ProxyObservableCounter(_ProxyAsynchronousInstrument[ObservableCounter], ObservableCounter): - def _create_real_instrument(self, meter: "metrics.Meter") -> ObservableCounter: - return meter.create_observable_counter( - self._name, - self._callbacks, - self._unit, - self._description, - ) - - -class ObservableUpDownCounter(Asynchronous): - """An ObservableUpDownCounter is an asynchronous `Instrument` which reports additive value(s) (e.g. - the process heap size - it makes sense to report the heap size from multiple processes and sum them - up, so we get the total heap usage) when the instrument is being observed. - """ - - -class NoOpObservableUpDownCounter(ObservableUpDownCounter): - """No-op implementation of `ObservableUpDownCounter`.""" - - def __init__( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> None: - super().__init__( - name, - callbacks, - unit=unit, - description=description, - ) - - -class _ProxyObservableUpDownCounter( - _ProxyAsynchronousInstrument[ObservableUpDownCounter], - ObservableUpDownCounter, -): - def _create_real_instrument(self, meter: "metrics.Meter") -> ObservableUpDownCounter: - return meter.create_observable_up_down_counter( - self._name, - self._callbacks, - self._unit, - self._description, - ) - - -class Histogram(Synchronous): - """Histogram is a synchronous `Instrument` which can be used to report arbitrary values - that are likely to be statistically meaningful. It is intended for statistics such as - histograms, summaries, and percentile. - """ - - @abstractmethod - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - ) -> None: - pass - - @abstractmethod - def record( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - """Records a measurement. - - Used to report measurements that are likely to be statistically - meaningful, such as request durations, payload sizes, or any value - for which a distribution (e.g. percentiles) is useful. - - Args: - amount: The measurement to record. Should be non-negative in most - cases; negative values are only meaningful when the histogram - is used to track signed deltas. - attributes: Optional set of attributes to associate with the measurement. - context: Optional context to associate with the measurement. If not - provided, the current context is used. - """ - - -class NoOpHistogram(Histogram): - """No-op implementation of `Histogram`.""" - - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - ) -> None: - super().__init__( - name, - unit=unit, - description=description, - explicit_bucket_boundaries_advisory=explicit_bucket_boundaries_advisory, - ) - - def record( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - return super().record(amount, attributes=attributes, context=context) - - -class _ProxyHistogram(_ProxyInstrument[Histogram], Histogram): - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - ) -> None: - super().__init__(name, unit=unit, description=description) - self._explicit_bucket_boundaries_advisory = explicit_bucket_boundaries_advisory - - def record( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - if self._real_instrument: - self._real_instrument.record(amount, attributes, context) - - def _create_real_instrument(self, meter: "metrics.Meter") -> Histogram: - return meter.create_histogram( - self._name, - self._unit, - self._description, - explicit_bucket_boundaries_advisory=self._explicit_bucket_boundaries_advisory, - ) - - -class ObservableGauge(Asynchronous): - """Asynchronous Gauge is an asynchronous `Instrument` which reports non-additive value(s) (e.g. - the room temperature - it makes no sense to report the temperature value from multiple rooms - and sum them up) when the instrument is being observed. - """ - - -class NoOpObservableGauge(ObservableGauge): - """No-op implementation of `ObservableGauge`.""" - - def __init__( - self, - name: str, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - ) -> None: - super().__init__( - name, - callbacks, - unit=unit, - description=description, - ) - - -class _ProxyObservableGauge( - _ProxyAsynchronousInstrument[ObservableGauge], - ObservableGauge, -): - def _create_real_instrument(self, meter: "metrics.Meter") -> ObservableGauge: - return meter.create_observable_gauge( - self._name, - self._callbacks, - self._unit, - self._description, - ) - - -class Gauge(Synchronous): - """A Gauge is a synchronous `Instrument` which can be used to record non-additive values as they occur.""" - - @abstractmethod - def set( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - """Records the current value of the gauge. - - The gauge reports the last recorded value when observed. It is - intended for non-additive measurements where only the current - value matters (e.g. CPU utilisation percentage, room temperature). - - Args: - amount: The current value to record. - attributes: Optional set of attributes to associate with the measurement. - context: Optional context to associate with the measurement. If not - provided, the current context is used. - """ - - -class NoOpGauge(Gauge): - """No-op implementation of ``Gauge``.""" - - def __init__( - self, - name: str, - unit: str = "", - description: str = "", - ) -> None: - super().__init__(name, unit=unit, description=description) - - def set( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - return super().set(amount, attributes=attributes, context=context) - - -class _ProxyGauge( - _ProxyInstrument[Gauge], - Gauge, -): - def set( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - if self._real_instrument: - self._real_instrument.set(amount, attributes, context) - - def _create_real_instrument(self, meter: "metrics.Meter") -> Gauge: - return meter.create_gauge( - self._name, - self._unit, - self._description, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py deleted file mode 100644 index 3248045e1ce..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/metrics/_internal/observation.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - - -class Observation: - """A measurement observed in an asynchronous instrument - - Return/yield instances of this class from asynchronous instrument callbacks. - - Args: - value: The float or int measured value - attributes: The measurement's attributes - context: The measurement's context - """ - - def __init__( - self, - value: float, - attributes: Attributes = None, - context: Context | None = None, - ) -> None: - self._value = value - self._attributes = attributes - self._context = context - - @property - def value(self) -> float | int: - return self._value - - @property - def attributes(self) -> Attributes: - return self._attributes - - @property - def context(self) -> Context | None: - return self._context - - def __eq__(self, other: object) -> bool: - return ( - isinstance(other, Observation) - and self.value == other.value - and self.attributes == other.attributes - and self.context == other.context - ) - - def __repr__(self) -> str: - return f"Observation(value={self.value}, attributes={self.attributes}, context={self.context})" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py deleted file mode 100644 index 6561217c51e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagate/__init__.py +++ /dev/null @@ -1,171 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -API for propagation of context. - -The propagators for the -``opentelemetry.propagators.composite.CompositePropagator`` can be defined -via configuration in the ``OTEL_PROPAGATORS`` environment variable. This -variable should be set to a comma-separated string of names of values for the -``opentelemetry_propagator`` entry point. For example, setting -``OTEL_PROPAGATORS`` to ``tracecontext,baggage`` (which is the default value) -would instantiate -``opentelemetry.propagators.composite.CompositePropagator`` with 2 -propagators, one of type -``opentelemetry.trace.propagation.tracecontext.TraceContextTextMapPropagator`` -and other of type ``opentelemetry.baggage.propagation.W3CBaggagePropagator``. -Notice that these propagator classes are defined as -``opentelemetry_propagator`` entry points in the ``pyproject.toml`` file of -``opentelemetry``. - -Example:: - - import flask - import requests - from opentelemetry import propagate - - - PROPAGATOR = propagate.get_global_textmap() - - - def get_header_from_flask_request(request, key): - return request.headers.get_all(key) - - - def set_header_into_requests_request(request: requests.Request, key: str, value: str): - request.headers[key] = value - - - def example_route(): - context = PROPAGATOR.extract(get_header_from_flask_request, flask.request) - request_to_downstream = requests.Request("GET", "http://httpbin.org/get") - PROPAGATOR.inject( - set_header_into_requests_request, - request_to_downstream, - context=context, - ) - session = requests.Session() - session.send(request_to_downstream.prepare()) - - -.. _Propagation API Specification: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md -""" - -from logging import getLogger -from os import environ - -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PROPAGATORS -from opentelemetry.agent._vendor.opentelemetry.propagators import composite, textmap - -logger = getLogger(__name__) - - -def extract( - carrier: textmap.CarrierT, - context: Context | None = None, - getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, -) -> Context: - """Uses the configured propagator to extract a Context from the carrier. - - Args: - getter: an object which contains a get function that can retrieve zero - or more values from the carrier and a keys function that can get all the keys - from carrier. - 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. - """ - return get_global_textmap().extract(carrier, context, getter=getter) - - -def inject( - carrier: textmap.CarrierT, - context: Context | None = None, - setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, -) -> None: - """Uses the configured propagator to inject a Context into the carrier. - - Args: - carrier: the medium used by Propagators to read - values from and write values to. - 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. - """ - get_global_textmap().inject(carrier, context=context, setter=setter) - - -def _load_propagators() -> textmap.TextMapPropagator: - configured = environ.get(OTEL_PROPAGATORS) - if not configured: - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.baggage.propagation import ( # noqa: PLC0415 - W3CBaggagePropagator, - ) - - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.trace.propagation.tracecontext import ( # noqa: PLC0415 - TraceContextTextMapPropagator, - ) - - return composite.CompositePropagator([TraceContextTextMapPropagator(), W3CBaggagePropagator()]) - - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.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([]) - 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 - 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") - -for propagator in environ_propagators.split(","): # type: ignore[assignment] - propagator = propagator.strip() - - -def get_global_textmap() -> textmap.TextMapPropagator: - return _HTTP_TEXT_FORMAT - - -def set_global_textmap( - http_text_format: textmap.TextMapPropagator, -) -> None: - global _HTTP_TEXT_FORMAT # pylint:disable=global-statement - _HTTP_TEXT_FORMAT = http_text_format diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py deleted file mode 100644 index 3d934f4a3f0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/_envcarrier.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -"""Environment variable carriers for text map propagators. - -Use :class:`EnvironmentGetter` with the environment mapping to extract from, -usually ``os.environ`` during application or child-process initialization. -Use :class:`EnvironmentSetter` with a mutable environment copy when preparing -the environment for a child process. -""" - -import re -from collections.abc import Mapping, MutableMapping - -from opentelemetry.agent._vendor.opentelemetry.propagators.textmap import Getter, Setter - - -def _normalize_key(key: str) -> str: - if not key: - return "_" - result = re.sub(r"[^A-Za-z0-9_]", "_", key).upper() - if result and result[0].isdigit(): - result = "_" + result - return result - - -def _is_normalized_key(key: str) -> bool: - if not key: - return False - if "0" <= key[0] <= "9": - return False - return all("A" <= char <= "Z" or "0" <= char <= "9" or char == "_" for char in key) - - -class EnvironmentGetter(Getter[Mapping[str, str]]): - """Getter implementation for extracting context and baggage from environment variables. - - EnvironmentGetter reads from the mapping provided as the carrier, normalizes - requested keys, and provides simple data access without validation. - - Example usage: - getter = EnvironmentGetter() - traceparent = getter.get(os.environ, "traceparent") - """ - - def get(self, carrier: Mapping[str, str], key: str) -> list[str] | None: - """Get a value from the environment carrier for the given key. - - Args: - carrier: Mapping to read environment variables from - key: The key to look up (will be normalized) - - Returns: - A list with a single string value if the key exists, None otherwise. - """ - val = carrier.get(_normalize_key(key)) - if val is None: - return None - return [val] - - def keys(self, carrier: Mapping[str, str]) -> list[str]: - """Get all keys from the environment carrier. - - Args: - carrier: Mapping to read environment variable keys from - - Returns: - List of all already-normalized environment variable keys. - """ - return [key for key in carrier.keys() if _is_normalized_key(key)] - - -class EnvironmentSetter(Setter[MutableMapping[str, str]]): - """Setter implementation for building environment variable dictionaries. - - EnvironmentSetter builds a dictionary of environment variables that - can be passed to utilities like subprocess.run() - - Example usage: - setter = EnvironmentSetter() - env_vars = {} - setter.set(env_vars, "traceparent", "00-trace-id-span-id-01") - subprocess.run(myCommand, env=env_vars) - """ - - def set(self, carrier: MutableMapping[str, str], key: str, value: str) -> None: - """Set a value in the carrier dictionary for the given key. - - Args: - carrier: Dictionary to store environment variables - key: The key to set (normalized) - value: The value to set - """ - carrier[_normalize_key(key)] = value diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py deleted file mode 100644 index ba9b04067dd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/__init__.py +++ /dev/null @@ -1,182 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import collections.abc -from re import compile as re_compile - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry import trace -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.propagators.textmap import ( - CarrierT, - Getter, - Setter, - TextMapPropagator, - default_getter, - default_setter, -) -from opentelemetry.agent._vendor.opentelemetry.trace import format_span_id, format_trace_id - - -class B3MultiFormat(TextMapPropagator): - """Propagator for the B3 HTTP multi-header format. - - See: https://github.com/openzipkin/b3-propagation - https://github.com/openzipkin/b3-propagation#multiple-headers - """ - - SINGLE_HEADER_KEY = "b3" - TRACE_ID_KEY = "x-b3-traceid" - SPAN_ID_KEY = "x-b3-spanid" - SAMPLED_KEY = "x-b3-sampled" - FLAGS_KEY = "x-b3-flags" - _SAMPLE_PROPAGATE_VALUES = {"1", "True", "true", "d"} - _trace_id_regex = re_compile(r"[\da-fA-F]{16}|[\da-fA-F]{32}") - _span_id_regex = re_compile(r"[\da-fA-F]{16}") - - def extract( - self, - carrier: CarrierT, - context: Context | None = None, - getter: Getter = default_getter, - ) -> Context: - if context is None: - context = Context() - trace_id = trace.INVALID_TRACE_ID - span_id = trace.INVALID_SPAN_ID - sampled = "0" - flags = None - - single_header = _extract_first_element(getter.get(carrier, self.SINGLE_HEADER_KEY)) - if single_header: - # The b3 spec calls for the sampling state to be - # "deferred", which is unspecified. This concept does not - # translate to SpanContext, so we set it as recorded. - sampled = "1" - fields = single_header.split("-", 4) - - if len(fields) == 1: - sampled = fields[0] - elif len(fields) == 2: - trace_id, span_id = fields - elif len(fields) == 3: - trace_id, span_id, sampled = fields - elif len(fields) == 4: - trace_id, span_id, sampled, _ = fields - else: - trace_id = _extract_first_element(getter.get(carrier, self.TRACE_ID_KEY)) or trace_id - span_id = _extract_first_element(getter.get(carrier, self.SPAN_ID_KEY)) or span_id - sampled = _extract_first_element(getter.get(carrier, self.SAMPLED_KEY)) or sampled - flags = _extract_first_element(getter.get(carrier, self.FLAGS_KEY)) or flags - - if ( - trace_id == trace.INVALID_TRACE_ID - or span_id == trace.INVALID_SPAN_ID - or self._trace_id_regex.fullmatch(trace_id) is None - or self._span_id_regex.fullmatch(span_id) is None - ): - return context - - trace_id = int(trace_id, 16) - span_id = int(span_id, 16) - options = 0 - # The b3 spec provides no defined behavior for both sample and - # flag values set. Since the setting of at least one implies - # the desire for some form of sampling, propagate if either - # header is set to allow. - if sampled in self._SAMPLE_PROPAGATE_VALUES or flags == "1": - options |= trace.TraceFlags.SAMPLED - - return trace.set_span_in_context( - trace.NonRecordingSpan( - trace.SpanContext( - # trace an span ids are encoded in hex, so must be converted - trace_id=trace_id, - span_id=span_id, - is_remote=True, - trace_flags=trace.TraceFlags(options), - trace_state=trace.TraceState(), - ) - ), - context, - ) - - def inject( - self, - carrier: CarrierT, - context: Context | None = None, - setter: Setter = default_setter, - ) -> None: - span = trace.get_current_span(context=context) - - span_context = span.get_span_context() - if span_context == trace.INVALID_SPAN_CONTEXT: - return - - sampled = (trace.TraceFlags.SAMPLED & span_context.trace_flags) != 0 - setter.set( - carrier, - self.TRACE_ID_KEY, - format_trace_id(span_context.trace_id), - ) - setter.set(carrier, self.SPAN_ID_KEY, format_span_id(span_context.span_id)) - setter.set(carrier, self.SAMPLED_KEY, "1" if sampled else "0") - - @property - def fields(self) -> set[str]: - return { - self.TRACE_ID_KEY, - self.SPAN_ID_KEY, - self.SAMPLED_KEY, - } - - -class B3SingleFormat(B3MultiFormat): - """Propagator for the B3 HTTP single-header format. - - See: https://github.com/openzipkin/b3-propagation - https://github.com/openzipkin/b3-propagation#single-header - """ - - def inject( - self, - carrier: CarrierT, - context: Context | None = None, - setter: Setter = default_setter, - ) -> None: - span = trace.get_current_span(context=context) - - span_context = span.get_span_context() - if span_context == trace.INVALID_SPAN_CONTEXT: - return - - sampled = (trace.TraceFlags.SAMPLED & span_context.trace_flags) != 0 - - fields = [ - format_trace_id(span_context.trace_id), - format_span_id(span_context.span_id), - "1" if sampled else "0", - ] - - setter.set(carrier, self.SINGLE_HEADER_KEY, "-".join(fields)) - - @property - def fields(self) -> set[str]: - return {self.SINGLE_HEADER_KEY} - - -class B3Format(B3MultiFormat): - @deprecated( - "B3Format is deprecated in favor of B3MultiFormat. Deprecated since version 1.2.0.", - ) - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - -def _extract_first_element( - items: collections.abc.Iterable[CarrierT], -) -> CarrierT | None: - if items is None: - return None - return next(iter(items), None) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py deleted file mode 100644 index 0101c361616..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/b3/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py deleted file mode 100644 index 801faa3d42a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/composite.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -import collections.abc -import logging - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.propagators import textmap - -logger = logging.getLogger(__name__) - - -class CompositePropagator(textmap.TextMapPropagator): - """CompositePropagator provides a mechanism for combining multiple - propagators into a single one. - - Args: - propagators: the list of propagators to use - """ - - def __init__(self, propagators: collections.abc.Sequence[textmap.TextMapPropagator]) -> None: - self._propagators = propagators - - def extract( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, - ) -> Context: - """Run each of the configured propagators with the given context and carrier. - Propagators are run in the order they are configured, if multiple - propagators write the same context key, the propagator later in the list - will override previous propagators. - - See `opentelemetry.propagators.textmap.TextMapPropagator.extract` - """ - for propagator in self._propagators: - context = propagator.extract(carrier, context, getter=getter) - return context # type: ignore - - def inject( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, - ) -> None: - """Run each of the configured propagators with the given context and carrier. - Propagators are run in the order they are configured, if multiple - propagators write the same carrier key, the propagator later in the list - will override previous propagators. - - See `opentelemetry.propagators.textmap.TextMapPropagator.inject` - """ - for propagator in self._propagators: - propagator.inject(carrier, context, setter=setter) - - @property - def fields(self) -> set[str]: - """Returns a set with the fields set in `inject`. - - See - `opentelemetry.propagators.textmap.TextMapPropagator.fields` - """ - composite_fields = set() - - for propagator in self._propagators: - for field in propagator.fields: - composite_fields.add(field) - - return composite_fields - - -@deprecated("You should use CompositePropagator. Deprecated since version 1.2.0.") -class CompositeHTTPPropagator(CompositePropagator): - """CompositeHTTPPropagator provides a mechanism for combining multiple - propagators into a single one. - """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py deleted file mode 100644 index 504124d54cf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/propagators/textmap.py +++ /dev/null @@ -1,181 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import abc -import typing -from collections.abc import Iterable, Mapping, MutableMapping - -from opentelemetry.agent._vendor.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`. - """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py deleted file mode 100644 index d3e9a32f978..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/collector/logs/v1/logs_service.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.logs.v1 import logs_pb2 as opentelemetry_dot_proto_dot_logs_dot_v1_dot_logs__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n8opentelemetry/proto/collector/logs/v1/logs_service.proto\x12%opentelemetry.proto.collector.logs.v1\x1a&opentelemetry/proto/logs/v1/logs.proto\"\\\n\x18\x45xportLogsServiceRequest\x12@\n\rresource_logs\x18\x01 \x03(\x0b\x32).opentelemetry.proto.logs.v1.ResourceLogs\"u\n\x19\x45xportLogsServiceResponse\x12X\n\x0fpartial_success\x18\x01 \x01(\x0b\x32?.opentelemetry.proto.collector.logs.v1.ExportLogsPartialSuccess\"O\n\x18\x45xportLogsPartialSuccess\x12\x1c\n\x14rejected_log_records\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\x9d\x01\n\x0bLogsService\x12\x8d\x01\n\x06\x45xport\x12?.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest\x1a@.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse\"\x00\x42\x98\x01\n(io.opentelemetry.proto.collector.logs.v1B\x10LogsServiceProtoP\x01Z0go.opentelemetry.io/proto/otlp/collector/logs/v1\xaa\x02%OpenTelemetry.Proto.Collector.Logs.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.logs.v1.logs_service_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n(io.opentelemetry.proto.collector.logs.v1B\020LogsServiceProtoP\001Z0go.opentelemetry.io/proto/otlp/collector/logs/v1\252\002%OpenTelemetry.Proto.Collector.Logs.V1' - _globals['_EXPORTLOGSSERVICEREQUEST']._serialized_start=139 - _globals['_EXPORTLOGSSERVICEREQUEST']._serialized_end=231 - _globals['_EXPORTLOGSSERVICERESPONSE']._serialized_start=233 - _globals['_EXPORTLOGSSERVICERESPONSE']._serialized_end=350 - _globals['_EXPORTLOGSPARTIALSUCCESS']._serialized_start=352 - _globals['_EXPORTLOGSPARTIALSUCCESS']._serialized_end=431 - _globals['_LOGSSERVICE']._serialized_start=434 - _globals['_LOGSSERVICE']._serialized_end=591 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi deleted file mode 100644 index 99e2a0ac101..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/logs/v1/logs_service_pb2.pyi +++ /dev/null @@ -1,117 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2020, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import opentelemetry.proto.logs.v1.logs_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class ExportLogsServiceRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_LOGS_FIELD_NUMBER: builtins.int - @property - def resource_logs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.logs.v1.logs_pb2.ResourceLogs]: - """An array of ResourceLogs. - For data coming from a single resource this array will typically contain one - element. Intermediary nodes (such as OpenTelemetry Collector) that receive - data from multiple origins typically batch the data before forwarding further and - in that case this array will contain multiple elements. - """ - def __init__( - self, - *, - resource_logs: collections.abc.Iterable[opentelemetry.proto.logs.v1.logs_pb2.ResourceLogs] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["resource_logs", b"resource_logs"]) -> None: ... - -global___ExportLogsServiceRequest = ExportLogsServiceRequest - -@typing_extensions.final -class ExportLogsServiceResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int - @property - def partial_success(self) -> global___ExportLogsPartialSuccess: - """The details of a partially successful export request. - - If the request is only partially accepted - (i.e. when the server accepts only parts of the data and rejects the rest) - the server MUST initialize the `partial_success` field and MUST - set the `rejected_` with the number of items it rejected. - - Servers MAY also make use of the `partial_success` field to convey - warnings/suggestions to senders even when the request was fully accepted. - In such cases, the `rejected_` MUST have a value of `0` and - the `error_message` MUST be non-empty. - - A `partial_success` message with an empty value (rejected_ = 0 and - `error_message` = "") is equivalent to it not being set/present. Senders - SHOULD interpret it the same way as in the full success case. - """ - def __init__( - self, - *, - partial_success: global___ExportLogsPartialSuccess | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... - -global___ExportLogsServiceResponse = ExportLogsServiceResponse - -@typing_extensions.final -class ExportLogsPartialSuccess(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - REJECTED_LOG_RECORDS_FIELD_NUMBER: builtins.int - ERROR_MESSAGE_FIELD_NUMBER: builtins.int - rejected_log_records: builtins.int - """The number of rejected log records. - - A `rejected_` field holding a `0` value indicates that the - request was fully accepted. - """ - error_message: builtins.str - """A developer-facing human-readable message in English. It should be used - either to explain why the server rejected parts of the data during a partial - success or to convey warnings/suggestions during a full success. The message - should offer guidance on how users can address such issues. - - error_message is an optional field. An error_message with an empty value - is equivalent to it not being set. - """ - def __init__( - self, - *, - rejected_log_records: builtins.int = ..., - error_message: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_log_records", b"rejected_log_records"]) -> None: ... - -global___ExportLogsPartialSuccess = ExportLogsPartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py deleted file mode 100644 index 603b072d9dc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/collector/metrics/v1/metrics_service.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1 import metrics_pb2 as opentelemetry_dot_proto_dot_metrics_dot_v1_dot_metrics__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n>opentelemetry/proto/collector/metrics/v1/metrics_service.proto\x12(opentelemetry.proto.collector.metrics.v1\x1a,opentelemetry/proto/metrics/v1/metrics.proto\"h\n\x1b\x45xportMetricsServiceRequest\x12I\n\x10resource_metrics\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.ResourceMetrics\"~\n\x1c\x45xportMetricsServiceResponse\x12^\n\x0fpartial_success\x18\x01 \x01(\x0b\x32\x45.opentelemetry.proto.collector.metrics.v1.ExportMetricsPartialSuccess\"R\n\x1b\x45xportMetricsPartialSuccess\x12\x1c\n\x14rejected_data_points\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\xac\x01\n\x0eMetricsService\x12\x99\x01\n\x06\x45xport\x12\x45.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest\x1a\x46.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse\"\x00\x42\xa4\x01\n+io.opentelemetry.proto.collector.metrics.v1B\x13MetricsServiceProtoP\x01Z3go.opentelemetry.io/proto/otlp/collector/metrics/v1\xaa\x02(OpenTelemetry.Proto.Collector.Metrics.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.metrics.v1.metrics_service_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n+io.opentelemetry.proto.collector.metrics.v1B\023MetricsServiceProtoP\001Z3go.opentelemetry.io/proto/otlp/collector/metrics/v1\252\002(OpenTelemetry.Proto.Collector.Metrics.V1' - _globals['_EXPORTMETRICSSERVICEREQUEST']._serialized_start=154 - _globals['_EXPORTMETRICSSERVICEREQUEST']._serialized_end=258 - _globals['_EXPORTMETRICSSERVICERESPONSE']._serialized_start=260 - _globals['_EXPORTMETRICSSERVICERESPONSE']._serialized_end=386 - _globals['_EXPORTMETRICSPARTIALSUCCESS']._serialized_start=388 - _globals['_EXPORTMETRICSPARTIALSUCCESS']._serialized_end=470 - _globals['_METRICSSERVICE']._serialized_start=473 - _globals['_METRICSSERVICE']._serialized_end=645 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi deleted file mode 100644 index fe3c44f3c37..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/metrics/v1/metrics_service_pb2.pyi +++ /dev/null @@ -1,117 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2019, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import opentelemetry.proto.metrics.v1.metrics_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class ExportMetricsServiceRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_METRICS_FIELD_NUMBER: builtins.int - @property - def resource_metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.metrics.v1.metrics_pb2.ResourceMetrics]: - """An array of ResourceMetrics. - For data coming from a single resource this array will typically contain one - element. Intermediary nodes (such as OpenTelemetry Collector) that receive - data from multiple origins typically batch the data before forwarding further and - in that case this array will contain multiple elements. - """ - def __init__( - self, - *, - resource_metrics: collections.abc.Iterable[opentelemetry.proto.metrics.v1.metrics_pb2.ResourceMetrics] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["resource_metrics", b"resource_metrics"]) -> None: ... - -global___ExportMetricsServiceRequest = ExportMetricsServiceRequest - -@typing_extensions.final -class ExportMetricsServiceResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int - @property - def partial_success(self) -> global___ExportMetricsPartialSuccess: - """The details of a partially successful export request. - - If the request is only partially accepted - (i.e. when the server accepts only parts of the data and rejects the rest) - the server MUST initialize the `partial_success` field and MUST - set the `rejected_` with the number of items it rejected. - - Servers MAY also make use of the `partial_success` field to convey - warnings/suggestions to senders even when the request was fully accepted. - In such cases, the `rejected_` MUST have a value of `0` and - the `error_message` MUST be non-empty. - - A `partial_success` message with an empty value (rejected_ = 0 and - `error_message` = "") is equivalent to it not being set/present. Senders - SHOULD interpret it the same way as in the full success case. - """ - def __init__( - self, - *, - partial_success: global___ExportMetricsPartialSuccess | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... - -global___ExportMetricsServiceResponse = ExportMetricsServiceResponse - -@typing_extensions.final -class ExportMetricsPartialSuccess(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - REJECTED_DATA_POINTS_FIELD_NUMBER: builtins.int - ERROR_MESSAGE_FIELD_NUMBER: builtins.int - rejected_data_points: builtins.int - """The number of rejected data points. - - A `rejected_` field holding a `0` value indicates that the - request was fully accepted. - """ - error_message: builtins.str - """A developer-facing human-readable message in English. It should be used - either to explain why the server rejected parts of the data during a partial - success or to convey warnings/suggestions during a full success. The message - should offer guidance on how users can address such issues. - - error_message is an optional field. An error_message with an empty value - is equivalent to it not being set. - """ - def __init__( - self, - *, - rejected_data_points: builtins.int = ..., - error_message: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_data_points", b"rejected_data_points"]) -> None: ... - -global___ExportMetricsPartialSuccess = ExportMetricsPartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py deleted file mode 100644 index 0fcb9d8b503..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/collector/profiles/v1development/profiles_service.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.profiles.v1development import profiles_pb2 as opentelemetry_dot_proto_dot_profiles_dot_v1development_dot_profiles__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\nKopentelemetry/proto/collector/profiles/v1development/profiles_service.proto\x12\x34opentelemetry.proto.collector.profiles.v1development\x1a\x39opentelemetry/proto/profiles/v1development/profiles.proto\"\xcb\x01\n\x1c\x45xportProfilesServiceRequest\x12W\n\x11resource_profiles\x18\x01 \x03(\x0b\x32<.opentelemetry.proto.profiles.v1development.ResourceProfiles\x12R\n\ndictionary\x18\x02 \x01(\x0b\x32>.opentelemetry.proto.profiles.v1development.ProfilesDictionary\"\x8c\x01\n\x1d\x45xportProfilesServiceResponse\x12k\n\x0fpartial_success\x18\x01 \x01(\x0b\x32R.opentelemetry.proto.collector.profiles.v1development.ExportProfilesPartialSuccess\"P\n\x1c\x45xportProfilesPartialSuccess\x12\x19\n\x11rejected_profiles\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\xc7\x01\n\x0fProfilesService\x12\xb3\x01\n\x06\x45xport\x12R.opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceRequest\x1aS.opentelemetry.proto.collector.profiles.v1development.ExportProfilesServiceResponse\"\x00\x42\xc9\x01\n7io.opentelemetry.proto.collector.profiles.v1developmentB\x14ProfilesServiceProtoP\x01Z?go.opentelemetry.io/proto/otlp/collector/profiles/v1development\xaa\x02\x34OpenTelemetry.Proto.Collector.Profiles.V1Developmentb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.profiles.v1development.profiles_service_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n7io.opentelemetry.proto.collector.profiles.v1developmentB\024ProfilesServiceProtoP\001Z?go.opentelemetry.io/proto/otlp/collector/profiles/v1development\252\0024OpenTelemetry.Proto.Collector.Profiles.V1Development' - _globals['_EXPORTPROFILESSERVICEREQUEST']._serialized_start=193 - _globals['_EXPORTPROFILESSERVICEREQUEST']._serialized_end=396 - _globals['_EXPORTPROFILESSERVICERESPONSE']._serialized_start=399 - _globals['_EXPORTPROFILESSERVICERESPONSE']._serialized_end=539 - _globals['_EXPORTPROFILESPARTIALSUCCESS']._serialized_start=541 - _globals['_EXPORTPROFILESPARTIALSUCCESS']._serialized_end=621 - _globals['_PROFILESSERVICE']._serialized_start=624 - _globals['_PROFILESSERVICE']._serialized_end=823 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi deleted file mode 100644 index e8b7a82095c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/profiles/v1development/profiles_service_pb2.pyi +++ /dev/null @@ -1,123 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2023, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import opentelemetry.proto.profiles.v1development.profiles_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class ExportProfilesServiceRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_PROFILES_FIELD_NUMBER: builtins.int - DICTIONARY_FIELD_NUMBER: builtins.int - @property - def resource_profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.profiles.v1development.profiles_pb2.ResourceProfiles]: - """An array of ResourceProfiles. - For data coming from a single resource this array will typically contain one - element. Intermediary nodes (such as OpenTelemetry Collector) that receive - data from multiple origins typically batch the data before forwarding further and - in that case this array will contain multiple elements. - """ - @property - def dictionary(self) -> opentelemetry.proto.profiles.v1development.profiles_pb2.ProfilesDictionary: - """The reference table containing all data shared by profiles across the message being sent.""" - def __init__( - self, - *, - resource_profiles: collections.abc.Iterable[opentelemetry.proto.profiles.v1development.profiles_pb2.ResourceProfiles] | None = ..., - dictionary: opentelemetry.proto.profiles.v1development.profiles_pb2.ProfilesDictionary | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary", "resource_profiles", b"resource_profiles"]) -> None: ... - -global___ExportProfilesServiceRequest = ExportProfilesServiceRequest - -@typing_extensions.final -class ExportProfilesServiceResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int - @property - def partial_success(self) -> global___ExportProfilesPartialSuccess: - """The details of a partially successful export request. - - If the request is only partially accepted - (i.e. when the server accepts only parts of the data and rejects the rest) - the server MUST initialize the `partial_success` field and MUST - set the `rejected_` with the number of items it rejected. - - Servers MAY also make use of the `partial_success` field to convey - warnings/suggestions to senders even when the request was fully accepted. - In such cases, the `rejected_` MUST have a value of `0` and - the `error_message` MUST be non-empty. - - A `partial_success` message with an empty value (rejected_ = 0 and - `error_message` = "") is equivalent to it not being set/present. Senders - SHOULD interpret it the same way as in the full success case. - """ - def __init__( - self, - *, - partial_success: global___ExportProfilesPartialSuccess | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... - -global___ExportProfilesServiceResponse = ExportProfilesServiceResponse - -@typing_extensions.final -class ExportProfilesPartialSuccess(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - REJECTED_PROFILES_FIELD_NUMBER: builtins.int - ERROR_MESSAGE_FIELD_NUMBER: builtins.int - rejected_profiles: builtins.int - """The number of rejected profiles. - - A `rejected_` field holding a `0` value indicates that the - request was fully accepted. - """ - error_message: builtins.str - """A developer-facing human-readable message in English. It should be used - either to explain why the server rejected parts of the data during a partial - success or to convey warnings/suggestions during a full success. The message - should offer guidance on how users can address such issues. - - error_message is an optional field. An error_message with an empty value - is equivalent to it not being set. - """ - def __init__( - self, - *, - rejected_profiles: builtins.int = ..., - error_message: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_profiles", b"rejected_profiles"]) -> None: ... - -global___ExportProfilesPartialSuccess = ExportProfilesPartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py deleted file mode 100644 index db09e3babf1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/collector/trace/v1/trace_service.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.trace.v1 import trace_pb2 as opentelemetry_dot_proto_dot_trace_dot_v1_dot_trace__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n:opentelemetry/proto/collector/trace/v1/trace_service.proto\x12&opentelemetry.proto.collector.trace.v1\x1a(opentelemetry/proto/trace/v1/trace.proto\"`\n\x19\x45xportTraceServiceRequest\x12\x43\n\x0eresource_spans\x18\x01 \x03(\x0b\x32+.opentelemetry.proto.trace.v1.ResourceSpans\"x\n\x1a\x45xportTraceServiceResponse\x12Z\n\x0fpartial_success\x18\x01 \x01(\x0b\x32\x41.opentelemetry.proto.collector.trace.v1.ExportTracePartialSuccess\"J\n\x19\x45xportTracePartialSuccess\x12\x16\n\x0erejected_spans\x18\x01 \x01(\x03\x12\x15\n\rerror_message\x18\x02 \x01(\t2\xa2\x01\n\x0cTraceService\x12\x91\x01\n\x06\x45xport\x12\x41.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest\x1a\x42.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse\"\x00\x42\x9c\x01\n)io.opentelemetry.proto.collector.trace.v1B\x11TraceServiceProtoP\x01Z1go.opentelemetry.io/proto/otlp/collector/trace/v1\xaa\x02&OpenTelemetry.Proto.Collector.Trace.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.collector.trace.v1.trace_service_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n)io.opentelemetry.proto.collector.trace.v1B\021TraceServiceProtoP\001Z1go.opentelemetry.io/proto/otlp/collector/trace/v1\252\002&OpenTelemetry.Proto.Collector.Trace.V1' - _globals['_EXPORTTRACESERVICEREQUEST']._serialized_start=144 - _globals['_EXPORTTRACESERVICEREQUEST']._serialized_end=240 - _globals['_EXPORTTRACESERVICERESPONSE']._serialized_start=242 - _globals['_EXPORTTRACESERVICERESPONSE']._serialized_end=362 - _globals['_EXPORTTRACEPARTIALSUCCESS']._serialized_start=364 - _globals['_EXPORTTRACEPARTIALSUCCESS']._serialized_end=438 - _globals['_TRACESERVICE']._serialized_start=441 - _globals['_TRACESERVICE']._serialized_end=603 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi deleted file mode 100644 index ceb4db5213f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/collector/trace/v1/trace_service_pb2.pyi +++ /dev/null @@ -1,117 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2019, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import opentelemetry.proto.trace.v1.trace_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class ExportTraceServiceRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_SPANS_FIELD_NUMBER: builtins.int - @property - def resource_spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.trace.v1.trace_pb2.ResourceSpans]: - """An array of ResourceSpans. - For data coming from a single resource this array will typically contain one - element. Intermediary nodes (such as OpenTelemetry Collector) that receive - data from multiple origins typically batch the data before forwarding further and - in that case this array will contain multiple elements. - """ - def __init__( - self, - *, - resource_spans: collections.abc.Iterable[opentelemetry.proto.trace.v1.trace_pb2.ResourceSpans] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["resource_spans", b"resource_spans"]) -> None: ... - -global___ExportTraceServiceRequest = ExportTraceServiceRequest - -@typing_extensions.final -class ExportTraceServiceResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PARTIAL_SUCCESS_FIELD_NUMBER: builtins.int - @property - def partial_success(self) -> global___ExportTracePartialSuccess: - """The details of a partially successful export request. - - If the request is only partially accepted - (i.e. when the server accepts only parts of the data and rejects the rest) - the server MUST initialize the `partial_success` field and MUST - set the `rejected_` with the number of items it rejected. - - Servers MAY also make use of the `partial_success` field to convey - warnings/suggestions to senders even when the request was fully accepted. - In such cases, the `rejected_` MUST have a value of `0` and - the `error_message` MUST be non-empty. - - A `partial_success` message with an empty value (rejected_ = 0 and - `error_message` = "") is equivalent to it not being set/present. Senders - SHOULD interpret it the same way as in the full success case. - """ - def __init__( - self, - *, - partial_success: global___ExportTracePartialSuccess | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["partial_success", b"partial_success"]) -> None: ... - -global___ExportTraceServiceResponse = ExportTraceServiceResponse - -@typing_extensions.final -class ExportTracePartialSuccess(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - REJECTED_SPANS_FIELD_NUMBER: builtins.int - ERROR_MESSAGE_FIELD_NUMBER: builtins.int - rejected_spans: builtins.int - """The number of rejected spans. - - A `rejected_` field holding a `0` value indicates that the - request was fully accepted. - """ - error_message: builtins.str - """A developer-facing human-readable message in English. It should be used - either to explain why the server rejected parts of the data during a partial - success or to convey warnings/suggestions during a full success. The message - should offer guidance on how users can address such issues. - - error_message is an optional field. An error_message with an empty value - is equivalent to it not being set. - """ - def __init__( - self, - *, - rejected_spans: builtins.int = ..., - error_message: builtins.str = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["error_message", b"error_message", "rejected_spans", b"rejected_spans"]) -> None: ... - -global___ExportTracePartialSuccess = ExportTracePartialSuccess diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py deleted file mode 100644 index 07d0de164fc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/common/v1/common.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*opentelemetry/proto/common/v1/common.proto\x12\x1dopentelemetry.proto.common.v1\"\xad\x02\n\x08\x41nyValue\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12@\n\x0b\x61rray_value\x18\x05 \x01(\x0b\x32).opentelemetry.proto.common.v1.ArrayValueH\x00\x12\x43\n\x0ckvlist_value\x18\x06 \x01(\x0b\x32+.opentelemetry.proto.common.v1.KeyValueListH\x00\x12\x15\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00\x12\x1f\n\x15string_value_strindex\x18\x08 \x01(\x05H\x00\x42\x07\n\x05value\"E\n\nArrayValue\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\"G\n\x0cKeyValueList\x12\x37\n\x06values\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\"e\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\x12\x14\n\x0ckey_strindex\x18\x03 \x01(\x05\"\x94\x01\n\x14InstrumentationScope\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12;\n\nattributes\x18\x03 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x04 \x01(\r\"X\n\tEntityRef\x12\x12\n\nschema_url\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0f\n\x07id_keys\x18\x03 \x03(\t\x12\x18\n\x10\x64\x65scription_keys\x18\x04 \x03(\tB{\n io.opentelemetry.proto.common.v1B\x0b\x43ommonProtoP\x01Z(go.opentelemetry.io/proto/otlp/common/v1\xaa\x02\x1dOpenTelemetry.Proto.Common.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.common.v1.common_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n io.opentelemetry.proto.common.v1B\013CommonProtoP\001Z(go.opentelemetry.io/proto/otlp/common/v1\252\002\035OpenTelemetry.Proto.Common.V1' - _globals['_ANYVALUE']._serialized_start=78 - _globals['_ANYVALUE']._serialized_end=379 - _globals['_ARRAYVALUE']._serialized_start=381 - _globals['_ARRAYVALUE']._serialized_end=450 - _globals['_KEYVALUELIST']._serialized_start=452 - _globals['_KEYVALUELIST']._serialized_end=523 - _globals['_KEYVALUE']._serialized_start=525 - _globals['_KEYVALUE']._serialized_end=626 - _globals['_INSTRUMENTATIONSCOPE']._serialized_start=629 - _globals['_INSTRUMENTATIONSCOPE']._serialized_end=777 - _globals['_ENTITYREF']._serialized_start=779 - _globals['_ENTITYREF']._serialized_end=867 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi deleted file mode 100644 index 205bba7510f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/common/v1/common_pb2.pyi +++ /dev/null @@ -1,280 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2019, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class AnyValue(google.protobuf.message.Message): - """Represents any type of attribute value. AnyValue may contain a - primitive value such as a string or integer or it may contain an arbitrary nested - object containing arrays, key-value lists and primitives. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - STRING_VALUE_FIELD_NUMBER: builtins.int - BOOL_VALUE_FIELD_NUMBER: builtins.int - INT_VALUE_FIELD_NUMBER: builtins.int - DOUBLE_VALUE_FIELD_NUMBER: builtins.int - ARRAY_VALUE_FIELD_NUMBER: builtins.int - KVLIST_VALUE_FIELD_NUMBER: builtins.int - BYTES_VALUE_FIELD_NUMBER: builtins.int - STRING_VALUE_STRINDEX_FIELD_NUMBER: builtins.int - string_value: builtins.str - bool_value: builtins.bool - int_value: builtins.int - double_value: builtins.float - @property - def array_value(self) -> global___ArrayValue: ... - @property - def kvlist_value(self) -> global___KeyValueList: ... - bytes_value: builtins.bytes - string_value_strindex: builtins.int - """Reference to the string value in ProfilesDictionary.string_table. - - Note: This is currently used exclusively in the Profiling signal. - Implementers of OTLP receivers for signals other than Profiling should - treat the presence of this value as a non-fatal issue. - Log an error or warning indicating an unexpected field intended for the - Profiling signal and process the data as if this value were absent or - empty, ignoring its semantic content for the non-Profiling signal. - - Status: [Development] - """ - def __init__( - self, - *, - string_value: builtins.str = ..., - bool_value: builtins.bool = ..., - int_value: builtins.int = ..., - double_value: builtins.float = ..., - array_value: global___ArrayValue | None = ..., - kvlist_value: global___KeyValueList | None = ..., - bytes_value: builtins.bytes = ..., - string_value_strindex: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["array_value", b"array_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "double_value", b"double_value", "int_value", b"int_value", "kvlist_value", b"kvlist_value", "string_value", b"string_value", "string_value_strindex", b"string_value_strindex", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["array_value", b"array_value", "bool_value", b"bool_value", "bytes_value", b"bytes_value", "double_value", b"double_value", "int_value", b"int_value", "kvlist_value", b"kvlist_value", "string_value", b"string_value", "string_value_strindex", b"string_value_strindex", "value", b"value"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["string_value", "bool_value", "int_value", "double_value", "array_value", "kvlist_value", "bytes_value", "string_value_strindex"] | None: ... - -global___AnyValue = AnyValue - -@typing_extensions.final -class ArrayValue(google.protobuf.message.Message): - """ArrayValue is a list of AnyValue messages. We need ArrayValue as a message - since oneof in AnyValue does not allow repeated fields. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - VALUES_FIELD_NUMBER: builtins.int - @property - def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___AnyValue]: - """Array of values. The array may be empty (contain 0 elements).""" - def __init__( - self, - *, - values: collections.abc.Iterable[global___AnyValue] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["values", b"values"]) -> None: ... - -global___ArrayValue = ArrayValue - -@typing_extensions.final -class KeyValueList(google.protobuf.message.Message): - """KeyValueList is a list of KeyValue messages. We need KeyValueList as a message - since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need - a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to - avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches - are semantically equivalent. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - VALUES_FIELD_NUMBER: builtins.int - @property - def values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___KeyValue]: - """A collection of key/value pairs of key-value pairs. The list may be empty (may - contain 0 elements). - - The keys MUST be unique (it is not allowed to have more than one - value with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - def __init__( - self, - *, - values: collections.abc.Iterable[global___KeyValue] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["values", b"values"]) -> None: ... - -global___KeyValueList = KeyValueList - -@typing_extensions.final -class KeyValue(google.protobuf.message.Message): - """Represents a key-value pair that is used to store Span attributes, Link - attributes, etc. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - KEY_FIELD_NUMBER: builtins.int - VALUE_FIELD_NUMBER: builtins.int - KEY_STRINDEX_FIELD_NUMBER: builtins.int - key: builtins.str - """The key name of the pair. - key_ref MUST NOT be set if key is used. - """ - @property - def value(self) -> global___AnyValue: - """The value of the pair.""" - key_strindex: builtins.int - """Reference to the string key in ProfilesDictionary.string_table. - key MUST NOT be set if key_strindex is used. - - Note: This is currently used exclusively in the Profiling signal. - Implementers of OTLP receivers for signals other than Profiling should - treat the presence of this key as a non-fatal issue. - Log an error or warning indicating an unexpected field intended for the - Profiling signal and process the data as if this value were absent or - empty, ignoring its semantic content for the non-Profiling signal. - - Status: [Development] - """ - def __init__( - self, - *, - key: builtins.str = ..., - value: global___AnyValue | None = ..., - key_strindex: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["key", b"key", "key_strindex", b"key_strindex", "value", b"value"]) -> None: ... - -global___KeyValue = KeyValue - -@typing_extensions.final -class InstrumentationScope(google.protobuf.message.Message): - """InstrumentationScope is a message representing the instrumentation scope information - such as the fully qualified name and version. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NAME_FIELD_NUMBER: builtins.int - VERSION_FIELD_NUMBER: builtins.int - ATTRIBUTES_FIELD_NUMBER: builtins.int - DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int - name: builtins.str - """A name denoting the Instrumentation scope. - An empty instrumentation scope name means the name is unknown. - """ - version: builtins.str - """Defines the version of the instrumentation scope. - An empty instrumentation scope version means the version is unknown. - """ - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___KeyValue]: - """Additional attributes that describe the scope. [Optional]. - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - dropped_attributes_count: builtins.int - """The number of attributes that were discarded. Attributes - can be discarded because their keys are too long or because there are too many - attributes. If this value is 0, then no attributes were dropped. - """ - def __init__( - self, - *, - name: builtins.str = ..., - version: builtins.str = ..., - attributes: collections.abc.Iterable[global___KeyValue] | None = ..., - dropped_attributes_count: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "name", b"name", "version", b"version"]) -> None: ... - -global___InstrumentationScope = InstrumentationScope - -@typing_extensions.final -class EntityRef(google.protobuf.message.Message): - """A reference to an Entity. - Entity represents an object of interest associated with produced telemetry: e.g spans, metrics, profiles, or logs. - - Status: [Development] - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - SCHEMA_URL_FIELD_NUMBER: builtins.int - TYPE_FIELD_NUMBER: builtins.int - ID_KEYS_FIELD_NUMBER: builtins.int - DESCRIPTION_KEYS_FIELD_NUMBER: builtins.int - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the entity data - is recorded in. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - - This schema_url applies to the data in this message and to the Resource attributes - referenced by id_keys and description_keys. - TODO: discuss if we are happy with this somewhat complicated definition of what - the schema_url applies to. - - This field obsoletes the schema_url field in ResourceMetrics/ResourceSpans/ResourceLogs. - """ - type: builtins.str - """Defines the type of the entity. MUST not change during the lifetime of the entity. - For example: "service" or "host". This field is required and MUST not be empty - for valid entities. - """ - @property - def id_keys(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: - """Attribute Keys that identify the entity. - MUST not change during the lifetime of the entity. The Id must contain at least one attribute. - These keys MUST exist in the containing {message}.attributes. - """ - @property - def description_keys(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: - """Descriptive (non-identifying) attribute keys of the entity. - MAY change over the lifetime of the entity. MAY be empty. - These attribute keys are not part of entity's identity. - These keys MUST exist in the containing {message}.attributes. - """ - def __init__( - self, - *, - schema_url: builtins.str = ..., - type: builtins.str = ..., - id_keys: collections.abc.Iterable[builtins.str] | None = ..., - description_keys: collections.abc.Iterable[builtins.str] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["description_keys", b"description_keys", "id_keys", b"id_keys", "schema_url", b"schema_url", "type", b"type"]) -> None: ... - -global___EntityRef = EntityRef diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py deleted file mode 100644 index e88e99462f0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/logs/v1/logs.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&opentelemetry/proto/logs/v1/logs.proto\x12\x1bopentelemetry.proto.logs.v1\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"L\n\x08LogsData\x12@\n\rresource_logs\x18\x01 \x03(\x0b\x32).opentelemetry.proto.logs.v1.ResourceLogs\"\xa3\x01\n\x0cResourceLogs\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12:\n\nscope_logs\x18\x02 \x03(\x0b\x32&.opentelemetry.proto.logs.v1.ScopeLogs\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\xa0\x01\n\tScopeLogs\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12;\n\x0blog_records\x18\x02 \x03(\x0b\x32&.opentelemetry.proto.logs.v1.LogRecord\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\x83\x03\n\tLogRecord\x12\x16\n\x0etime_unix_nano\x18\x01 \x01(\x06\x12\x1f\n\x17observed_time_unix_nano\x18\x0b \x01(\x06\x12\x44\n\x0fseverity_number\x18\x02 \x01(\x0e\x32+.opentelemetry.proto.logs.v1.SeverityNumber\x12\x15\n\rseverity_text\x18\x03 \x01(\t\x12\x35\n\x04\x62ody\x18\x05 \x01(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\x12;\n\nattributes\x18\x06 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x07 \x01(\r\x12\r\n\x05\x66lags\x18\x08 \x01(\x07\x12\x10\n\x08trace_id\x18\t \x01(\x0c\x12\x0f\n\x07span_id\x18\n \x01(\x0c\x12\x12\n\nevent_name\x18\x0c \x01(\tJ\x04\x08\x04\x10\x05*\xc3\x05\n\x0eSeverityNumber\x12\x1f\n\x1bSEVERITY_NUMBER_UNSPECIFIED\x10\x00\x12\x19\n\x15SEVERITY_NUMBER_TRACE\x10\x01\x12\x1a\n\x16SEVERITY_NUMBER_TRACE2\x10\x02\x12\x1a\n\x16SEVERITY_NUMBER_TRACE3\x10\x03\x12\x1a\n\x16SEVERITY_NUMBER_TRACE4\x10\x04\x12\x19\n\x15SEVERITY_NUMBER_DEBUG\x10\x05\x12\x1a\n\x16SEVERITY_NUMBER_DEBUG2\x10\x06\x12\x1a\n\x16SEVERITY_NUMBER_DEBUG3\x10\x07\x12\x1a\n\x16SEVERITY_NUMBER_DEBUG4\x10\x08\x12\x18\n\x14SEVERITY_NUMBER_INFO\x10\t\x12\x19\n\x15SEVERITY_NUMBER_INFO2\x10\n\x12\x19\n\x15SEVERITY_NUMBER_INFO3\x10\x0b\x12\x19\n\x15SEVERITY_NUMBER_INFO4\x10\x0c\x12\x18\n\x14SEVERITY_NUMBER_WARN\x10\r\x12\x19\n\x15SEVERITY_NUMBER_WARN2\x10\x0e\x12\x19\n\x15SEVERITY_NUMBER_WARN3\x10\x0f\x12\x19\n\x15SEVERITY_NUMBER_WARN4\x10\x10\x12\x19\n\x15SEVERITY_NUMBER_ERROR\x10\x11\x12\x1a\n\x16SEVERITY_NUMBER_ERROR2\x10\x12\x12\x1a\n\x16SEVERITY_NUMBER_ERROR3\x10\x13\x12\x1a\n\x16SEVERITY_NUMBER_ERROR4\x10\x14\x12\x19\n\x15SEVERITY_NUMBER_FATAL\x10\x15\x12\x1a\n\x16SEVERITY_NUMBER_FATAL2\x10\x16\x12\x1a\n\x16SEVERITY_NUMBER_FATAL3\x10\x17\x12\x1a\n\x16SEVERITY_NUMBER_FATAL4\x10\x18*Y\n\x0eLogRecordFlags\x12\x1f\n\x1bLOG_RECORD_FLAGS_DO_NOT_USE\x10\x00\x12&\n!LOG_RECORD_FLAGS_TRACE_FLAGS_MASK\x10\xff\x01\x42s\n\x1eio.opentelemetry.proto.logs.v1B\tLogsProtoP\x01Z&go.opentelemetry.io/proto/otlp/logs/v1\xaa\x02\x1bOpenTelemetry.Proto.Logs.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.logs.v1.logs_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\036io.opentelemetry.proto.logs.v1B\tLogsProtoP\001Z&go.opentelemetry.io/proto/otlp/logs/v1\252\002\033OpenTelemetry.Proto.Logs.V1' - _globals['_SEVERITYNUMBER']._serialized_start=961 - _globals['_SEVERITYNUMBER']._serialized_end=1668 - _globals['_LOGRECORDFLAGS']._serialized_start=1670 - _globals['_LOGRECORDFLAGS']._serialized_end=1759 - _globals['_LOGSDATA']._serialized_start=163 - _globals['_LOGSDATA']._serialized_end=239 - _globals['_RESOURCELOGS']._serialized_start=242 - _globals['_RESOURCELOGS']._serialized_end=405 - _globals['_SCOPELOGS']._serialized_start=408 - _globals['_SCOPELOGS']._serialized_end=568 - _globals['_LOGRECORD']._serialized_start=571 - _globals['_LOGRECORD']._serialized_end=958 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi deleted file mode 100644 index 03edd535b7c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/logs/v1/logs_pb2.pyi +++ /dev/null @@ -1,365 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2020, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message -import opentelemetry.proto.common.v1.common_pb2 -import opentelemetry.proto.resource.v1.resource_pb2 -import sys -import typing - -if sys.version_info >= (3, 10): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -class _SeverityNumber: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _SeverityNumberEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SeverityNumber.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - SEVERITY_NUMBER_UNSPECIFIED: _SeverityNumber.ValueType # 0 - SEVERITY_NUMBER_TRACE: _SeverityNumber.ValueType # 1 - SEVERITY_NUMBER_TRACE2: _SeverityNumber.ValueType # 2 - SEVERITY_NUMBER_TRACE3: _SeverityNumber.ValueType # 3 - SEVERITY_NUMBER_TRACE4: _SeverityNumber.ValueType # 4 - SEVERITY_NUMBER_DEBUG: _SeverityNumber.ValueType # 5 - SEVERITY_NUMBER_DEBUG2: _SeverityNumber.ValueType # 6 - SEVERITY_NUMBER_DEBUG3: _SeverityNumber.ValueType # 7 - SEVERITY_NUMBER_DEBUG4: _SeverityNumber.ValueType # 8 - SEVERITY_NUMBER_INFO: _SeverityNumber.ValueType # 9 - SEVERITY_NUMBER_INFO2: _SeverityNumber.ValueType # 10 - SEVERITY_NUMBER_INFO3: _SeverityNumber.ValueType # 11 - SEVERITY_NUMBER_INFO4: _SeverityNumber.ValueType # 12 - SEVERITY_NUMBER_WARN: _SeverityNumber.ValueType # 13 - SEVERITY_NUMBER_WARN2: _SeverityNumber.ValueType # 14 - SEVERITY_NUMBER_WARN3: _SeverityNumber.ValueType # 15 - SEVERITY_NUMBER_WARN4: _SeverityNumber.ValueType # 16 - SEVERITY_NUMBER_ERROR: _SeverityNumber.ValueType # 17 - SEVERITY_NUMBER_ERROR2: _SeverityNumber.ValueType # 18 - SEVERITY_NUMBER_ERROR3: _SeverityNumber.ValueType # 19 - SEVERITY_NUMBER_ERROR4: _SeverityNumber.ValueType # 20 - SEVERITY_NUMBER_FATAL: _SeverityNumber.ValueType # 21 - SEVERITY_NUMBER_FATAL2: _SeverityNumber.ValueType # 22 - SEVERITY_NUMBER_FATAL3: _SeverityNumber.ValueType # 23 - SEVERITY_NUMBER_FATAL4: _SeverityNumber.ValueType # 24 - -class SeverityNumber(_SeverityNumber, metaclass=_SeverityNumberEnumTypeWrapper): - """Possible values for LogRecord.SeverityNumber.""" - -SEVERITY_NUMBER_UNSPECIFIED: SeverityNumber.ValueType # 0 -SEVERITY_NUMBER_TRACE: SeverityNumber.ValueType # 1 -SEVERITY_NUMBER_TRACE2: SeverityNumber.ValueType # 2 -SEVERITY_NUMBER_TRACE3: SeverityNumber.ValueType # 3 -SEVERITY_NUMBER_TRACE4: SeverityNumber.ValueType # 4 -SEVERITY_NUMBER_DEBUG: SeverityNumber.ValueType # 5 -SEVERITY_NUMBER_DEBUG2: SeverityNumber.ValueType # 6 -SEVERITY_NUMBER_DEBUG3: SeverityNumber.ValueType # 7 -SEVERITY_NUMBER_DEBUG4: SeverityNumber.ValueType # 8 -SEVERITY_NUMBER_INFO: SeverityNumber.ValueType # 9 -SEVERITY_NUMBER_INFO2: SeverityNumber.ValueType # 10 -SEVERITY_NUMBER_INFO3: SeverityNumber.ValueType # 11 -SEVERITY_NUMBER_INFO4: SeverityNumber.ValueType # 12 -SEVERITY_NUMBER_WARN: SeverityNumber.ValueType # 13 -SEVERITY_NUMBER_WARN2: SeverityNumber.ValueType # 14 -SEVERITY_NUMBER_WARN3: SeverityNumber.ValueType # 15 -SEVERITY_NUMBER_WARN4: SeverityNumber.ValueType # 16 -SEVERITY_NUMBER_ERROR: SeverityNumber.ValueType # 17 -SEVERITY_NUMBER_ERROR2: SeverityNumber.ValueType # 18 -SEVERITY_NUMBER_ERROR3: SeverityNumber.ValueType # 19 -SEVERITY_NUMBER_ERROR4: SeverityNumber.ValueType # 20 -SEVERITY_NUMBER_FATAL: SeverityNumber.ValueType # 21 -SEVERITY_NUMBER_FATAL2: SeverityNumber.ValueType # 22 -SEVERITY_NUMBER_FATAL3: SeverityNumber.ValueType # 23 -SEVERITY_NUMBER_FATAL4: SeverityNumber.ValueType # 24 -global___SeverityNumber = SeverityNumber - -class _LogRecordFlags: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _LogRecordFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_LogRecordFlags.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - LOG_RECORD_FLAGS_DO_NOT_USE: _LogRecordFlags.ValueType # 0 - """The zero value for the enum. Should not be used for comparisons. - Instead use bitwise "and" with the appropriate mask as shown above. - """ - LOG_RECORD_FLAGS_TRACE_FLAGS_MASK: _LogRecordFlags.ValueType # 255 - """Bits 0-7 are used for trace flags.""" - -class LogRecordFlags(_LogRecordFlags, metaclass=_LogRecordFlagsEnumTypeWrapper): - """LogRecordFlags represents constants used to interpret the - LogRecord.flags field, which is protobuf 'fixed32' type and is to - be used as bit-fields. Each non-zero value defined in this enum is - a bit-mask. To extract the bit-field, for example, use an - expression like: - - (logRecord.flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK) - """ - -LOG_RECORD_FLAGS_DO_NOT_USE: LogRecordFlags.ValueType # 0 -"""The zero value for the enum. Should not be used for comparisons. -Instead use bitwise "and" with the appropriate mask as shown above. -""" -LOG_RECORD_FLAGS_TRACE_FLAGS_MASK: LogRecordFlags.ValueType # 255 -"""Bits 0-7 are used for trace flags.""" -global___LogRecordFlags = LogRecordFlags - -@typing_extensions.final -class LogsData(google.protobuf.message.Message): - """LogsData represents the logs data that can be stored in a persistent storage, - OR can be embedded by other protocols that transfer OTLP logs data but do not - implement the OTLP protocol. - - The main difference between this message and collector protocol is that - in this message there will not be any "control" or "metadata" specific to - OTLP protocol. - - When new fields are added into this message, the OTLP request MUST be updated - as well. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_LOGS_FIELD_NUMBER: builtins.int - @property - def resource_logs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceLogs]: - """An array of ResourceLogs. - For data coming from a single resource this array will typically contain - one element. Intermediary nodes that receive data from multiple origins - typically batch the data before forwarding further and in that case this - array will contain multiple elements. - """ - def __init__( - self, - *, - resource_logs: collections.abc.Iterable[global___ResourceLogs] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["resource_logs", b"resource_logs"]) -> None: ... - -global___LogsData = LogsData - -@typing_extensions.final -class ResourceLogs(google.protobuf.message.Message): - """A collection of ScopeLogs from a Resource.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_FIELD_NUMBER: builtins.int - SCOPE_LOGS_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: - """The resource for the logs in this message. - If this field is not set then resource info is unknown. - """ - @property - def scope_logs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeLogs]: - """A list of ScopeLogs that originate from a resource.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the resource data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "resource" field. It does not apply - to the data in the "scope_logs" field which have their own schema_url field. - """ - def __init__( - self, - *, - resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., - scope_logs: collections.abc.Iterable[global___ScopeLogs] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_logs", b"scope_logs"]) -> None: ... - -global___ResourceLogs = ResourceLogs - -@typing_extensions.final -class ScopeLogs(google.protobuf.message.Message): - """A collection of Logs produced by a Scope.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - SCOPE_FIELD_NUMBER: builtins.int - LOG_RECORDS_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: - """The instrumentation scope information for the logs in this message. - Semantically when InstrumentationScope isn't set, it is equivalent with - an empty instrumentation scope name (unknown). - """ - @property - def log_records(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___LogRecord]: - """A list of log records.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the log data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "scope" field and all logs in the - "log_records" field. - """ - def __init__( - self, - *, - scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., - log_records: collections.abc.Iterable[global___LogRecord] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["log_records", b"log_records", "schema_url", b"schema_url", "scope", b"scope"]) -> None: ... - -global___ScopeLogs = ScopeLogs - -@typing_extensions.final -class LogRecord(google.protobuf.message.Message): - """A log record according to OpenTelemetry Log Data Model: - https://github.com/open-telemetry/oteps/blob/main/text/logs/0097-log-data-model.md - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - OBSERVED_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - SEVERITY_NUMBER_FIELD_NUMBER: builtins.int - SEVERITY_TEXT_FIELD_NUMBER: builtins.int - BODY_FIELD_NUMBER: builtins.int - ATTRIBUTES_FIELD_NUMBER: builtins.int - DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int - FLAGS_FIELD_NUMBER: builtins.int - TRACE_ID_FIELD_NUMBER: builtins.int - SPAN_ID_FIELD_NUMBER: builtins.int - EVENT_NAME_FIELD_NUMBER: builtins.int - time_unix_nano: builtins.int - """time_unix_nano is the time when the event occurred. - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - Value of 0 indicates unknown or missing timestamp. - """ - observed_time_unix_nano: builtins.int - """Time when the event was observed by the collection system. - For events that originate in OpenTelemetry (e.g. using OpenTelemetry Logging SDK) - this timestamp is typically set at the generation time and is equal to Timestamp. - For events originating externally and collected by OpenTelemetry (e.g. using - Collector) this is the time when OpenTelemetry's code observed the event measured - by the clock of the OpenTelemetry code. This field MUST be set once the event is - observed by OpenTelemetry. - - For converting OpenTelemetry log data to formats that support only one timestamp or - when receiving OpenTelemetry log data by recipients that support only one timestamp - internally the following logic is recommended: - - Use time_unix_nano if it is present, otherwise use observed_time_unix_nano. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - Value of 0 indicates unknown or missing timestamp. - """ - severity_number: global___SeverityNumber.ValueType - """Numerical value of the severity, normalized to values described in Log Data Model. - [Optional]. - """ - severity_text: builtins.str - """The severity text (also known as log level). The original string representation as - it is known at the source. [Optional]. - """ - @property - def body(self) -> opentelemetry.proto.common.v1.common_pb2.AnyValue: - """A value containing the body of the log record. Can be for example a human-readable - string message (including multi-line) describing the event in a free form or it can - be a structured data composed of arrays and maps of other values. [Optional]. - """ - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """Additional attributes that describe the specific event occurrence. [Optional]. - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - dropped_attributes_count: builtins.int - flags: builtins.int - """Flags, a bit field. 8 least significant bits are the trace flags as - defined in W3C Trace Context specification. 24 most significant bits are reserved - and must be set to 0. Readers must not assume that 24 most significant bits - will be zero and must correctly mask the bits when reading 8-bit trace flag (use - flags & LOG_RECORD_FLAGS_TRACE_FLAGS_MASK). [Optional]. - """ - trace_id: builtins.bytes - """A unique identifier for a trace. All logs from the same trace share - the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR - of length other than 16 bytes is considered invalid (empty string in OTLP/JSON - is zero-length and thus is also invalid). - - This field is optional. - - The receivers SHOULD assume that the log record is not associated with a - trace if any of the following is true: - - the field is not present, - - the field contains an invalid value. - """ - span_id: builtins.bytes - """A unique identifier for a span within a trace, assigned when the span - is created. The ID is an 8-byte array. An ID with all zeroes OR of length - other than 8 bytes is considered invalid (empty string in OTLP/JSON - is zero-length and thus is also invalid). - - This field is optional. If the sender specifies a valid span_id then it SHOULD also - specify a valid trace_id. - - The receivers SHOULD assume that the log record is not associated with a - span if any of the following is true: - - the field is not present, - - the field contains an invalid value. - """ - event_name: builtins.str - """A unique identifier of event category/type. - All events with the same event_name are expected to conform to the same - schema for both their attributes and their body. - - Recommended to be fully qualified and short (no longer than 256 characters). - - Presence of event_name on the log record identifies this record - as an event. - - [Optional]. - """ - def __init__( - self, - *, - time_unix_nano: builtins.int = ..., - observed_time_unix_nano: builtins.int = ..., - severity_number: global___SeverityNumber.ValueType = ..., - severity_text: builtins.str = ..., - body: opentelemetry.proto.common.v1.common_pb2.AnyValue | None = ..., - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - dropped_attributes_count: builtins.int = ..., - flags: builtins.int = ..., - trace_id: builtins.bytes = ..., - span_id: builtins.bytes = ..., - event_name: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["body", b"body"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "body", b"body", "dropped_attributes_count", b"dropped_attributes_count", "event_name", b"event_name", "flags", b"flags", "observed_time_unix_nano", b"observed_time_unix_nano", "severity_number", b"severity_number", "severity_text", b"severity_text", "span_id", b"span_id", "time_unix_nano", b"time_unix_nano", "trace_id", b"trace_id"]) -> None: ... - -global___LogRecord = LogRecord diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py deleted file mode 100644 index 2a279a61ed7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/metrics/v1/metrics.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,opentelemetry/proto/metrics/v1/metrics.proto\x12\x1eopentelemetry.proto.metrics.v1\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"X\n\x0bMetricsData\x12I\n\x10resource_metrics\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.ResourceMetrics\"\xaf\x01\n\x0fResourceMetrics\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12\x43\n\rscope_metrics\x18\x02 \x03(\x0b\x32,.opentelemetry.proto.metrics.v1.ScopeMetrics\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\x9f\x01\n\x0cScopeMetrics\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12\x37\n\x07metrics\x18\x02 \x03(\x0b\x32&.opentelemetry.proto.metrics.v1.Metric\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\xcd\x03\n\x06Metric\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0c\n\x04unit\x18\x03 \x01(\t\x12\x36\n\x05gauge\x18\x05 \x01(\x0b\x32%.opentelemetry.proto.metrics.v1.GaugeH\x00\x12\x32\n\x03sum\x18\x07 \x01(\x0b\x32#.opentelemetry.proto.metrics.v1.SumH\x00\x12>\n\thistogram\x18\t \x01(\x0b\x32).opentelemetry.proto.metrics.v1.HistogramH\x00\x12U\n\x15\x65xponential_histogram\x18\n \x01(\x0b\x32\x34.opentelemetry.proto.metrics.v1.ExponentialHistogramH\x00\x12:\n\x07summary\x18\x0b \x01(\x0b\x32\'.opentelemetry.proto.metrics.v1.SummaryH\x00\x12\x39\n\x08metadata\x18\x0c \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValueB\x06\n\x04\x64\x61taJ\x04\x08\x04\x10\x05J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\t\"M\n\x05Gauge\x12\x44\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.NumberDataPoint\"\xba\x01\n\x03Sum\x12\x44\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32/.opentelemetry.proto.metrics.v1.NumberDataPoint\x12W\n\x17\x61ggregation_temporality\x18\x02 \x01(\x0e\x32\x36.opentelemetry.proto.metrics.v1.AggregationTemporality\x12\x14\n\x0cis_monotonic\x18\x03 \x01(\x08\"\xad\x01\n\tHistogram\x12G\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32\x32.opentelemetry.proto.metrics.v1.HistogramDataPoint\x12W\n\x17\x61ggregation_temporality\x18\x02 \x01(\x0e\x32\x36.opentelemetry.proto.metrics.v1.AggregationTemporality\"\xc3\x01\n\x14\x45xponentialHistogram\x12R\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32=.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint\x12W\n\x17\x61ggregation_temporality\x18\x02 \x01(\x0e\x32\x36.opentelemetry.proto.metrics.v1.AggregationTemporality\"P\n\x07Summary\x12\x45\n\x0b\x64\x61ta_points\x18\x01 \x03(\x0b\x32\x30.opentelemetry.proto.metrics.v1.SummaryDataPoint\"\x86\x02\n\x0fNumberDataPoint\x12;\n\nattributes\x18\x07 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\x13\n\tas_double\x18\x04 \x01(\x01H\x00\x12\x10\n\x06\x61s_int\x18\x06 \x01(\x10H\x00\x12;\n\texemplars\x18\x05 \x03(\x0b\x32(.opentelemetry.proto.metrics.v1.Exemplar\x12\r\n\x05\x66lags\x18\x08 \x01(\rB\x07\n\x05valueJ\x04\x08\x01\x10\x02\"\xe6\x02\n\x12HistogramDataPoint\x12;\n\nattributes\x18\t \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\r\n\x05\x63ount\x18\x04 \x01(\x06\x12\x10\n\x03sum\x18\x05 \x01(\x01H\x00\x88\x01\x01\x12\x15\n\rbucket_counts\x18\x06 \x03(\x06\x12\x17\n\x0f\x65xplicit_bounds\x18\x07 \x03(\x01\x12;\n\texemplars\x18\x08 \x03(\x0b\x32(.opentelemetry.proto.metrics.v1.Exemplar\x12\r\n\x05\x66lags\x18\n \x01(\r\x12\x10\n\x03min\x18\x0b \x01(\x01H\x01\x88\x01\x01\x12\x10\n\x03max\x18\x0c \x01(\x01H\x02\x88\x01\x01\x42\x06\n\x04_sumB\x06\n\x04_minB\x06\n\x04_maxJ\x04\x08\x01\x10\x02\"\xda\x04\n\x1d\x45xponentialHistogramDataPoint\x12;\n\nattributes\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\r\n\x05\x63ount\x18\x04 \x01(\x06\x12\x10\n\x03sum\x18\x05 \x01(\x01H\x00\x88\x01\x01\x12\r\n\x05scale\x18\x06 \x01(\x11\x12\x12\n\nzero_count\x18\x07 \x01(\x06\x12W\n\x08positive\x18\x08 \x01(\x0b\x32\x45.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint.Buckets\x12W\n\x08negative\x18\t \x01(\x0b\x32\x45.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint.Buckets\x12\r\n\x05\x66lags\x18\n \x01(\r\x12;\n\texemplars\x18\x0b \x03(\x0b\x32(.opentelemetry.proto.metrics.v1.Exemplar\x12\x10\n\x03min\x18\x0c \x01(\x01H\x01\x88\x01\x01\x12\x10\n\x03max\x18\r \x01(\x01H\x02\x88\x01\x01\x12\x16\n\x0ezero_threshold\x18\x0e \x01(\x01\x1a\x30\n\x07\x42uckets\x12\x0e\n\x06offset\x18\x01 \x01(\x11\x12\x15\n\rbucket_counts\x18\x02 \x03(\x04\x42\x06\n\x04_sumB\x06\n\x04_minB\x06\n\x04_max\"\xc5\x02\n\x10SummaryDataPoint\x12;\n\nattributes\x18\x07 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x1c\n\x14start_time_unix_nano\x18\x02 \x01(\x06\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\r\n\x05\x63ount\x18\x04 \x01(\x06\x12\x0b\n\x03sum\x18\x05 \x01(\x01\x12Y\n\x0fquantile_values\x18\x06 \x03(\x0b\x32@.opentelemetry.proto.metrics.v1.SummaryDataPoint.ValueAtQuantile\x12\r\n\x05\x66lags\x18\x08 \x01(\r\x1a\x32\n\x0fValueAtQuantile\x12\x10\n\x08quantile\x18\x01 \x01(\x01\x12\r\n\x05value\x18\x02 \x01(\x01J\x04\x08\x01\x10\x02\"\xc1\x01\n\x08\x45xemplar\x12\x44\n\x13\x66iltered_attributes\x18\x07 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12\x16\n\x0etime_unix_nano\x18\x02 \x01(\x06\x12\x13\n\tas_double\x18\x03 \x01(\x01H\x00\x12\x10\n\x06\x61s_int\x18\x06 \x01(\x10H\x00\x12\x0f\n\x07span_id\x18\x04 \x01(\x0c\x12\x10\n\x08trace_id\x18\x05 \x01(\x0c\x42\x07\n\x05valueJ\x04\x08\x01\x10\x02*\x8c\x01\n\x16\x41ggregationTemporality\x12\'\n#AGGREGATION_TEMPORALITY_UNSPECIFIED\x10\x00\x12!\n\x1d\x41GGREGATION_TEMPORALITY_DELTA\x10\x01\x12&\n\"AGGREGATION_TEMPORALITY_CUMULATIVE\x10\x02*^\n\x0e\x44\x61taPointFlags\x12\x1f\n\x1b\x44\x41TA_POINT_FLAGS_DO_NOT_USE\x10\x00\x12+\n\'DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK\x10\x01\x42\x7f\n!io.opentelemetry.proto.metrics.v1B\x0cMetricsProtoP\x01Z)go.opentelemetry.io/proto/otlp/metrics/v1\xaa\x02\x1eOpenTelemetry.Proto.Metrics.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.metrics.v1.metrics_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n!io.opentelemetry.proto.metrics.v1B\014MetricsProtoP\001Z)go.opentelemetry.io/proto/otlp/metrics/v1\252\002\036OpenTelemetry.Proto.Metrics.V1' - _globals['_AGGREGATIONTEMPORALITY']._serialized_start=3546 - _globals['_AGGREGATIONTEMPORALITY']._serialized_end=3686 - _globals['_DATAPOINTFLAGS']._serialized_start=3688 - _globals['_DATAPOINTFLAGS']._serialized_end=3782 - _globals['_METRICSDATA']._serialized_start=172 - _globals['_METRICSDATA']._serialized_end=260 - _globals['_RESOURCEMETRICS']._serialized_start=263 - _globals['_RESOURCEMETRICS']._serialized_end=438 - _globals['_SCOPEMETRICS']._serialized_start=441 - _globals['_SCOPEMETRICS']._serialized_end=600 - _globals['_METRIC']._serialized_start=603 - _globals['_METRIC']._serialized_end=1064 - _globals['_GAUGE']._serialized_start=1066 - _globals['_GAUGE']._serialized_end=1143 - _globals['_SUM']._serialized_start=1146 - _globals['_SUM']._serialized_end=1332 - _globals['_HISTOGRAM']._serialized_start=1335 - _globals['_HISTOGRAM']._serialized_end=1508 - _globals['_EXPONENTIALHISTOGRAM']._serialized_start=1511 - _globals['_EXPONENTIALHISTOGRAM']._serialized_end=1706 - _globals['_SUMMARY']._serialized_start=1708 - _globals['_SUMMARY']._serialized_end=1788 - _globals['_NUMBERDATAPOINT']._serialized_start=1791 - _globals['_NUMBERDATAPOINT']._serialized_end=2053 - _globals['_HISTOGRAMDATAPOINT']._serialized_start=2056 - _globals['_HISTOGRAMDATAPOINT']._serialized_end=2414 - _globals['_EXPONENTIALHISTOGRAMDATAPOINT']._serialized_start=2417 - _globals['_EXPONENTIALHISTOGRAMDATAPOINT']._serialized_end=3019 - _globals['_EXPONENTIALHISTOGRAMDATAPOINT_BUCKETS']._serialized_start=2947 - _globals['_EXPONENTIALHISTOGRAMDATAPOINT_BUCKETS']._serialized_end=2995 - _globals['_SUMMARYDATAPOINT']._serialized_start=3022 - _globals['_SUMMARYDATAPOINT']._serialized_end=3347 - _globals['_SUMMARYDATAPOINT_VALUEATQUANTILE']._serialized_start=3291 - _globals['_SUMMARYDATAPOINT_VALUEATQUANTILE']._serialized_end=3341 - _globals['_EXEMPLAR']._serialized_start=3350 - _globals['_EXEMPLAR']._serialized_end=3543 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi deleted file mode 100644 index 0f374be93ee..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/metrics/v1/metrics_pb2.pyi +++ /dev/null @@ -1,1177 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2019, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message -import opentelemetry.proto.common.v1.common_pb2 -import opentelemetry.proto.resource.v1.resource_pb2 -import sys -import typing - -if sys.version_info >= (3, 10): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -class _AggregationTemporality: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _AggregationTemporalityEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_AggregationTemporality.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - AGGREGATION_TEMPORALITY_UNSPECIFIED: _AggregationTemporality.ValueType # 0 - """UNSPECIFIED is the default AggregationTemporality, it MUST not be used.""" - AGGREGATION_TEMPORALITY_DELTA: _AggregationTemporality.ValueType # 1 - """DELTA is an AggregationTemporality for a metric aggregator which reports - changes since last report time. Successive metrics contain aggregation of - values from continuous and non-overlapping intervals. - - The values for a DELTA metric are based only on the time interval - associated with one measurement cycle. There is no dependency on - previous measurements like is the case for CUMULATIVE metrics. - - For example, consider a system measuring the number of requests that - it receives and reports the sum of these requests every second as a - DELTA metric: - - 1. The system starts receiving at time=t_0. - 2. A request is received, the system measures 1 request. - 3. A request is received, the system measures 1 request. - 4. A request is received, the system measures 1 request. - 5. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+1 with a value of 3. - 6. A request is received, the system measures 1 request. - 7. A request is received, the system measures 1 request. - 8. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0+1 to - t_0+2 with a value of 2. - """ - AGGREGATION_TEMPORALITY_CUMULATIVE: _AggregationTemporality.ValueType # 2 - """CUMULATIVE is an AggregationTemporality for a metric aggregator which - reports changes since a fixed start time. This means that current values - of a CUMULATIVE metric depend on all previous measurements since the - start time. Because of this, the sender is required to retain this state - in some form. If this state is lost or invalidated, the CUMULATIVE metric - values MUST be reset and a new fixed start time following the last - reported measurement time sent MUST be used. - - For example, consider a system measuring the number of requests that - it receives and reports the sum of these requests every second as a - CUMULATIVE metric: - - 1. The system starts receiving at time=t_0. - 2. A request is received, the system measures 1 request. - 3. A request is received, the system measures 1 request. - 4. A request is received, the system measures 1 request. - 5. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+1 with a value of 3. - 6. A request is received, the system measures 1 request. - 7. A request is received, the system measures 1 request. - 8. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+2 with a value of 5. - 9. The system experiences a fault and loses state. - 10. The system recovers and resumes receiving at time=t_1. - 11. A request is received, the system measures 1 request. - 12. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_1 to - t_0+1 with a value of 1. - - Note: Even though, when reporting changes since last report time, using - CUMULATIVE is valid, it is not recommended. This may cause problems for - systems that do not use start_time to determine when the aggregation - value was reset (e.g. Prometheus). - """ - -class AggregationTemporality(_AggregationTemporality, metaclass=_AggregationTemporalityEnumTypeWrapper): - """AggregationTemporality defines how a metric aggregator reports aggregated - values. It describes how those values relate to the time interval over - which they are aggregated. - """ - -AGGREGATION_TEMPORALITY_UNSPECIFIED: AggregationTemporality.ValueType # 0 -"""UNSPECIFIED is the default AggregationTemporality, it MUST not be used.""" -AGGREGATION_TEMPORALITY_DELTA: AggregationTemporality.ValueType # 1 -"""DELTA is an AggregationTemporality for a metric aggregator which reports -changes since last report time. Successive metrics contain aggregation of -values from continuous and non-overlapping intervals. - -The values for a DELTA metric are based only on the time interval -associated with one measurement cycle. There is no dependency on -previous measurements like is the case for CUMULATIVE metrics. - -For example, consider a system measuring the number of requests that -it receives and reports the sum of these requests every second as a -DELTA metric: - - 1. The system starts receiving at time=t_0. - 2. A request is received, the system measures 1 request. - 3. A request is received, the system measures 1 request. - 4. A request is received, the system measures 1 request. - 5. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+1 with a value of 3. - 6. A request is received, the system measures 1 request. - 7. A request is received, the system measures 1 request. - 8. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0+1 to - t_0+2 with a value of 2. -""" -AGGREGATION_TEMPORALITY_CUMULATIVE: AggregationTemporality.ValueType # 2 -"""CUMULATIVE is an AggregationTemporality for a metric aggregator which -reports changes since a fixed start time. This means that current values -of a CUMULATIVE metric depend on all previous measurements since the -start time. Because of this, the sender is required to retain this state -in some form. If this state is lost or invalidated, the CUMULATIVE metric -values MUST be reset and a new fixed start time following the last -reported measurement time sent MUST be used. - -For example, consider a system measuring the number of requests that -it receives and reports the sum of these requests every second as a -CUMULATIVE metric: - - 1. The system starts receiving at time=t_0. - 2. A request is received, the system measures 1 request. - 3. A request is received, the system measures 1 request. - 4. A request is received, the system measures 1 request. - 5. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+1 with a value of 3. - 6. A request is received, the system measures 1 request. - 7. A request is received, the system measures 1 request. - 8. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_0 to - t_0+2 with a value of 5. - 9. The system experiences a fault and loses state. - 10. The system recovers and resumes receiving at time=t_1. - 11. A request is received, the system measures 1 request. - 12. The 1 second collection cycle ends. A metric is exported for the - number of requests received over the interval of time t_1 to - t_0+1 with a value of 1. - -Note: Even though, when reporting changes since last report time, using -CUMULATIVE is valid, it is not recommended. This may cause problems for -systems that do not use start_time to determine when the aggregation -value was reset (e.g. Prometheus). -""" -global___AggregationTemporality = AggregationTemporality - -class _DataPointFlags: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _DataPointFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_DataPointFlags.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - DATA_POINT_FLAGS_DO_NOT_USE: _DataPointFlags.ValueType # 0 - """The zero value for the enum. Should not be used for comparisons. - Instead use bitwise "and" with the appropriate mask as shown above. - """ - DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK: _DataPointFlags.ValueType # 1 - """This DataPoint is valid but has no recorded value. This value - SHOULD be used to reflect explicitly missing data in a series, as - for an equivalent to the Prometheus "staleness marker". - """ - -class DataPointFlags(_DataPointFlags, metaclass=_DataPointFlagsEnumTypeWrapper): - """DataPointFlags is defined as a protobuf 'uint32' type and is to be used as a - bit-field representing 32 distinct boolean flags. Each flag defined in this - enum is a bit-mask. To test the presence of a single flag in the flags of - a data point, for example, use an expression like: - - (point.flags & DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK) == DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK - """ - -DATA_POINT_FLAGS_DO_NOT_USE: DataPointFlags.ValueType # 0 -"""The zero value for the enum. Should not be used for comparisons. -Instead use bitwise "and" with the appropriate mask as shown above. -""" -DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK: DataPointFlags.ValueType # 1 -"""This DataPoint is valid but has no recorded value. This value -SHOULD be used to reflect explicitly missing data in a series, as -for an equivalent to the Prometheus "staleness marker". -""" -global___DataPointFlags = DataPointFlags - -@typing_extensions.final -class MetricsData(google.protobuf.message.Message): - """MetricsData represents the metrics data that can be stored in a persistent - storage, OR can be embedded by other protocols that transfer OTLP metrics - data but do not implement the OTLP protocol. - - MetricsData - └─── ResourceMetrics - ├── Resource - ├── SchemaURL - └── ScopeMetrics - ├── Scope - ├── SchemaURL - └── Metric - ├── Name - ├── Description - ├── Unit - └── data - ├── Gauge - ├── Sum - ├── Histogram - ├── ExponentialHistogram - └── Summary - - The main difference between this message and collector protocol is that - in this message there will not be any "control" or "metadata" specific to - OTLP protocol. - - When new fields are added into this message, the OTLP request MUST be updated - as well. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_METRICS_FIELD_NUMBER: builtins.int - @property - def resource_metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceMetrics]: - """An array of ResourceMetrics. - For data coming from a single resource this array will typically contain - one element. Intermediary nodes that receive data from multiple origins - typically batch the data before forwarding further and in that case this - array will contain multiple elements. - """ - def __init__( - self, - *, - resource_metrics: collections.abc.Iterable[global___ResourceMetrics] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["resource_metrics", b"resource_metrics"]) -> None: ... - -global___MetricsData = MetricsData - -@typing_extensions.final -class ResourceMetrics(google.protobuf.message.Message): - """A collection of ScopeMetrics from a Resource.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_FIELD_NUMBER: builtins.int - SCOPE_METRICS_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: - """The resource for the metrics in this message. - If this field is not set then no resource info is known. - """ - @property - def scope_metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeMetrics]: - """A list of metrics that originate from a resource.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the resource data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "resource" field. It does not apply - to the data in the "scope_metrics" field which have their own schema_url field. - """ - def __init__( - self, - *, - resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., - scope_metrics: collections.abc.Iterable[global___ScopeMetrics] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_metrics", b"scope_metrics"]) -> None: ... - -global___ResourceMetrics = ResourceMetrics - -@typing_extensions.final -class ScopeMetrics(google.protobuf.message.Message): - """A collection of Metrics produced by an Scope.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - SCOPE_FIELD_NUMBER: builtins.int - METRICS_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: - """The instrumentation scope information for the metrics in this message. - Semantically when InstrumentationScope isn't set, it is equivalent with - an empty instrumentation scope name (unknown). - """ - @property - def metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Metric]: - """A list of metrics that originate from an instrumentation library.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the metric data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "scope" field and all metrics in the - "metrics" field. - """ - def __init__( - self, - *, - scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., - metrics: collections.abc.Iterable[global___Metric] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["metrics", b"metrics", "schema_url", b"schema_url", "scope", b"scope"]) -> None: ... - -global___ScopeMetrics = ScopeMetrics - -@typing_extensions.final -class Metric(google.protobuf.message.Message): - """Defines a Metric which has one or more timeseries. The following is a - brief summary of the Metric data model. For more details, see: - - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md - - The data model and relation between entities is shown in the - diagram below. Here, "DataPoint" is the term used to refer to any - one of the specific data point value types, and "points" is the term used - to refer to any one of the lists of points contained in the Metric. - - - Metric is composed of a metadata and data. - - Metadata part contains a name, description, unit. - - Data is one of the possible types (Sum, Gauge, Histogram, Summary). - - DataPoint contains timestamps, attributes, and one of the possible value type - fields. - - Metric - +------------+ - |name | - |description | - |unit | +------------------------------------+ - |data |---> |Gauge, Sum, Histogram, Summary, ... | - +------------+ +------------------------------------+ - - Data [One of Gauge, Sum, Histogram, Summary, ...] - +-----------+ - |... | // Metadata about the Data. - |points |--+ - +-----------+ | - | +---------------------------+ - | |DataPoint 1 | - v |+------+------+ +------+ | - +-----+ ||label |label |...|label | | - | 1 |-->||value1|value2|...|valueN| | - +-----+ |+------+------+ +------+ | - | . | |+-----+ | - | . | ||value| | - | . | |+-----+ | - | . | +---------------------------+ - | . | . - | . | . - | . | . - | . | +---------------------------+ - | . | |DataPoint M | - +-----+ |+------+------+ +------+ | - | M |-->||label |label |...|label | | - +-----+ ||value1|value2|...|valueN| | - |+------+------+ +------+ | - |+-----+ | - ||value| | - |+-----+ | - +---------------------------+ - - Each distinct type of DataPoint represents the output of a specific - aggregation function, the result of applying the DataPoint's - associated function of to one or more measurements. - - All DataPoint types have three common fields: - - Attributes includes key-value pairs associated with the data point - - TimeUnixNano is required, set to the end time of the aggregation - - StartTimeUnixNano is optional, but strongly encouraged for DataPoints - having an AggregationTemporality field, as discussed below. - - Both TimeUnixNano and StartTimeUnixNano values are expressed as - UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - - # TimeUnixNano - - This field is required, having consistent interpretation across - DataPoint types. TimeUnixNano is the moment corresponding to when - the data point's aggregate value was captured. - - Data points with the 0 value for TimeUnixNano SHOULD be rejected - by consumers. - - # StartTimeUnixNano - - StartTimeUnixNano in general allows detecting when a sequence of - observations is unbroken. This field indicates to consumers the - start time for points with cumulative and delta - AggregationTemporality, and it should be included whenever possible - to support correct rate calculation. Although it may be omitted - when the start time is truly unknown, setting StartTimeUnixNano is - strongly encouraged. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NAME_FIELD_NUMBER: builtins.int - DESCRIPTION_FIELD_NUMBER: builtins.int - UNIT_FIELD_NUMBER: builtins.int - GAUGE_FIELD_NUMBER: builtins.int - SUM_FIELD_NUMBER: builtins.int - HISTOGRAM_FIELD_NUMBER: builtins.int - EXPONENTIAL_HISTOGRAM_FIELD_NUMBER: builtins.int - SUMMARY_FIELD_NUMBER: builtins.int - METADATA_FIELD_NUMBER: builtins.int - name: builtins.str - """The name of the metric.""" - description: builtins.str - """A description of the metric, which can be used in documentation.""" - unit: builtins.str - """The unit in which the metric value is reported. Follows the format - described by https://unitsofmeasure.org/ucum.html. - """ - @property - def gauge(self) -> global___Gauge: ... - @property - def sum(self) -> global___Sum: ... - @property - def histogram(self) -> global___Histogram: ... - @property - def exponential_histogram(self) -> global___ExponentialHistogram: ... - @property - def summary(self) -> global___Summary: ... - @property - def metadata(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """Additional metadata attributes that describe the metric. [Optional]. - Attributes are non-identifying. - Consumers SHOULD NOT need to be aware of these attributes. - These attributes MAY be used to encode information allowing - for lossless roundtrip translation to / from another data model. - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - def __init__( - self, - *, - name: builtins.str = ..., - description: builtins.str = ..., - unit: builtins.str = ..., - gauge: global___Gauge | None = ..., - sum: global___Sum | None = ..., - histogram: global___Histogram | None = ..., - exponential_histogram: global___ExponentialHistogram | None = ..., - summary: global___Summary | None = ..., - metadata: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["data", b"data", "exponential_histogram", b"exponential_histogram", "gauge", b"gauge", "histogram", b"histogram", "sum", b"sum", "summary", b"summary"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["data", b"data", "description", b"description", "exponential_histogram", b"exponential_histogram", "gauge", b"gauge", "histogram", b"histogram", "metadata", b"metadata", "name", b"name", "sum", b"sum", "summary", b"summary", "unit", b"unit"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["data", b"data"]) -> typing_extensions.Literal["gauge", "sum", "histogram", "exponential_histogram", "summary"] | None: ... - -global___Metric = Metric - -@typing_extensions.final -class Gauge(google.protobuf.message.Message): - """Gauge represents the type of a scalar metric that always exports the - "current value" for every data point. It should be used for an "unknown" - aggregation. - - A Gauge does not support different aggregation temporalities. Given the - aggregation is unknown, points cannot be combined using the same - aggregation, regardless of aggregation temporalities. Therefore, - AggregationTemporality is not included. Consequently, this also means - "StartTimeUnixNano" is ignored for all data points. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - DATA_POINTS_FIELD_NUMBER: builtins.int - @property - def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NumberDataPoint]: - """The time series data points. - Note: Multiple time series may be included (same timestamp, different attributes). - """ - def __init__( - self, - *, - data_points: collections.abc.Iterable[global___NumberDataPoint] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["data_points", b"data_points"]) -> None: ... - -global___Gauge = Gauge - -@typing_extensions.final -class Sum(google.protobuf.message.Message): - """Sum represents the type of a scalar metric that is calculated as a sum of all - reported measurements over a time interval. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - DATA_POINTS_FIELD_NUMBER: builtins.int - AGGREGATION_TEMPORALITY_FIELD_NUMBER: builtins.int - IS_MONOTONIC_FIELD_NUMBER: builtins.int - @property - def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NumberDataPoint]: - """The time series data points. - Note: Multiple time series may be included (same timestamp, different attributes). - """ - aggregation_temporality: global___AggregationTemporality.ValueType - """aggregation_temporality describes if the aggregator reports delta changes - since last report time, or cumulative changes since a fixed start time. - """ - is_monotonic: builtins.bool - """Represents whether the sum is monotonic.""" - def __init__( - self, - *, - data_points: collections.abc.Iterable[global___NumberDataPoint] | None = ..., - aggregation_temporality: global___AggregationTemporality.ValueType = ..., - is_monotonic: builtins.bool = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["aggregation_temporality", b"aggregation_temporality", "data_points", b"data_points", "is_monotonic", b"is_monotonic"]) -> None: ... - -global___Sum = Sum - -@typing_extensions.final -class Histogram(google.protobuf.message.Message): - """Histogram represents the type of a metric that is calculated by aggregating - as a Histogram of all reported measurements over a time interval. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - DATA_POINTS_FIELD_NUMBER: builtins.int - AGGREGATION_TEMPORALITY_FIELD_NUMBER: builtins.int - @property - def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___HistogramDataPoint]: - """The time series data points. - Note: Multiple time series may be included (same timestamp, different attributes). - """ - aggregation_temporality: global___AggregationTemporality.ValueType - """aggregation_temporality describes if the aggregator reports delta changes - since last report time, or cumulative changes since a fixed start time. - """ - def __init__( - self, - *, - data_points: collections.abc.Iterable[global___HistogramDataPoint] | None = ..., - aggregation_temporality: global___AggregationTemporality.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["aggregation_temporality", b"aggregation_temporality", "data_points", b"data_points"]) -> None: ... - -global___Histogram = Histogram - -@typing_extensions.final -class ExponentialHistogram(google.protobuf.message.Message): - """ExponentialHistogram represents the type of a metric that is calculated by aggregating - as a ExponentialHistogram of all reported double measurements over a time interval. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - DATA_POINTS_FIELD_NUMBER: builtins.int - AGGREGATION_TEMPORALITY_FIELD_NUMBER: builtins.int - @property - def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ExponentialHistogramDataPoint]: - """The time series data points. - Note: Multiple time series may be included (same timestamp, different attributes). - """ - aggregation_temporality: global___AggregationTemporality.ValueType - """aggregation_temporality describes if the aggregator reports delta changes - since last report time, or cumulative changes since a fixed start time. - """ - def __init__( - self, - *, - data_points: collections.abc.Iterable[global___ExponentialHistogramDataPoint] | None = ..., - aggregation_temporality: global___AggregationTemporality.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["aggregation_temporality", b"aggregation_temporality", "data_points", b"data_points"]) -> None: ... - -global___ExponentialHistogram = ExponentialHistogram - -@typing_extensions.final -class Summary(google.protobuf.message.Message): - """Summary metric data are used to convey quantile summaries, - a Prometheus (see: https://prometheus.io/docs/concepts/metric_types/#summary) - and OpenMetrics (see: https://github.com/prometheus/OpenMetrics/blob/4dbf6075567ab43296eed941037c12951faafb92/protos/prometheus.proto#L45) - data type. These data points cannot always be merged in a meaningful way. - While they can be useful in some applications, histogram data points are - recommended for new applications. - Summary metrics do not have an aggregation temporality field. This is - because the count and sum fields of a SummaryDataPoint are assumed to be - cumulative values. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - DATA_POINTS_FIELD_NUMBER: builtins.int - @property - def data_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SummaryDataPoint]: - """The time series data points. - Note: Multiple time series may be included (same timestamp, different attributes). - """ - def __init__( - self, - *, - data_points: collections.abc.Iterable[global___SummaryDataPoint] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["data_points", b"data_points"]) -> None: ... - -global___Summary = Summary - -@typing_extensions.final -class NumberDataPoint(google.protobuf.message.Message): - """NumberDataPoint is a single data point in a timeseries that describes the - time-varying scalar value of a metric. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ATTRIBUTES_FIELD_NUMBER: builtins.int - START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - AS_DOUBLE_FIELD_NUMBER: builtins.int - AS_INT_FIELD_NUMBER: builtins.int - EXEMPLARS_FIELD_NUMBER: builtins.int - FLAGS_FIELD_NUMBER: builtins.int - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """The set of key/value pairs that uniquely identify the timeseries from - where this point belongs. The list may be empty (may contain 0 elements). - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - start_time_unix_nano: builtins.int - """StartTimeUnixNano is optional but strongly encouraged, see the - the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - time_unix_nano: builtins.int - """TimeUnixNano is required, see the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - as_double: builtins.float - as_int: builtins.int - @property - def exemplars(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Exemplar]: - """(Optional) List of exemplars collected from - measurements that were used to form the data point - """ - flags: builtins.int - """Flags that apply to this specific data point. See DataPointFlags - for the available flags and their meaning. - """ - def __init__( - self, - *, - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - start_time_unix_nano: builtins.int = ..., - time_unix_nano: builtins.int = ..., - as_double: builtins.float = ..., - as_int: builtins.int = ..., - exemplars: collections.abc.Iterable[global___Exemplar] | None = ..., - flags: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "attributes", b"attributes", "exemplars", b"exemplars", "flags", b"flags", "start_time_unix_nano", b"start_time_unix_nano", "time_unix_nano", b"time_unix_nano", "value", b"value"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["as_double", "as_int"] | None: ... - -global___NumberDataPoint = NumberDataPoint - -@typing_extensions.final -class HistogramDataPoint(google.protobuf.message.Message): - """HistogramDataPoint is a single data point in a timeseries that describes the - time-varying values of a Histogram. A Histogram contains summary statistics - for a population of values, it may optionally contain the distribution of - those values across a set of buckets. - - If the histogram contains the distribution of values, then both - "explicit_bounds" and "bucket counts" fields must be defined. - If the histogram does not contain the distribution of values, then both - "explicit_bounds" and "bucket_counts" must be omitted and only "count" and - "sum" are known. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ATTRIBUTES_FIELD_NUMBER: builtins.int - START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - COUNT_FIELD_NUMBER: builtins.int - SUM_FIELD_NUMBER: builtins.int - BUCKET_COUNTS_FIELD_NUMBER: builtins.int - EXPLICIT_BOUNDS_FIELD_NUMBER: builtins.int - EXEMPLARS_FIELD_NUMBER: builtins.int - FLAGS_FIELD_NUMBER: builtins.int - MIN_FIELD_NUMBER: builtins.int - MAX_FIELD_NUMBER: builtins.int - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """The set of key/value pairs that uniquely identify the timeseries from - where this point belongs. The list may be empty (may contain 0 elements). - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - start_time_unix_nano: builtins.int - """StartTimeUnixNano is optional but strongly encouraged, see the - the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - time_unix_nano: builtins.int - """TimeUnixNano is required, see the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - count: builtins.int - """count is the number of values in the population. Must be non-negative. This - value must be equal to the sum of the "count" fields in buckets if a - histogram is provided. - """ - sum: builtins.float - """sum of the values in the population. If count is zero then this field - must be zero. - - Note: Sum should only be filled out when measuring non-negative discrete - events, and is assumed to be monotonic over the values of these events. - Negative events *can* be recorded, but sum should not be filled out when - doing so. This is specifically to enforce compatibility w/ OpenMetrics, - see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram - """ - @property - def bucket_counts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """bucket_counts is an optional field contains the count values of histogram - for each bucket. - - The sum of the bucket_counts must equal the value in the count field. - - The number of elements in bucket_counts array must be by one greater than - the number of elements in explicit_bounds array. The exception to this rule - is when the length of bucket_counts is 0, then the length of explicit_bounds - must also be 0. - """ - @property - def explicit_bounds(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: - """explicit_bounds specifies buckets with explicitly defined bounds for values. - - The boundaries for bucket at index i are: - - (-infinity, explicit_bounds[i]] for i == 0 - (explicit_bounds[i-1], explicit_bounds[i]] for 0 < i < size(explicit_bounds) - (explicit_bounds[i-1], +infinity) for i == size(explicit_bounds) - - The values in the explicit_bounds array must be strictly increasing. - - Histogram buckets are inclusive of their upper boundary, except the last - bucket where the boundary is at infinity. This format is intentionally - compatible with the OpenMetrics histogram definition. - - If bucket_counts length is 0 then explicit_bounds length must also be 0, - otherwise the data point is invalid. - """ - @property - def exemplars(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Exemplar]: - """(Optional) List of exemplars collected from - measurements that were used to form the data point - """ - flags: builtins.int - """Flags that apply to this specific data point. See DataPointFlags - for the available flags and their meaning. - """ - min: builtins.float - """min is the minimum value over (start_time, end_time].""" - max: builtins.float - """max is the maximum value over (start_time, end_time].""" - def __init__( - self, - *, - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - start_time_unix_nano: builtins.int = ..., - time_unix_nano: builtins.int = ..., - count: builtins.int = ..., - sum: builtins.float | None = ..., - bucket_counts: collections.abc.Iterable[builtins.int] | None = ..., - explicit_bounds: collections.abc.Iterable[builtins.float] | None = ..., - exemplars: collections.abc.Iterable[global___Exemplar] | None = ..., - flags: builtins.int = ..., - min: builtins.float | None = ..., - max: builtins.float | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "max", b"max", "min", b"min", "sum", b"sum"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "attributes", b"attributes", "bucket_counts", b"bucket_counts", "count", b"count", "exemplars", b"exemplars", "explicit_bounds", b"explicit_bounds", "flags", b"flags", "max", b"max", "min", b"min", "start_time_unix_nano", b"start_time_unix_nano", "sum", b"sum", "time_unix_nano", b"time_unix_nano"]) -> None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_max", b"_max"]) -> typing_extensions.Literal["max"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_min", b"_min"]) -> typing_extensions.Literal["min"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_sum", b"_sum"]) -> typing_extensions.Literal["sum"] | None: ... - -global___HistogramDataPoint = HistogramDataPoint - -@typing_extensions.final -class ExponentialHistogramDataPoint(google.protobuf.message.Message): - """ExponentialHistogramDataPoint is a single data point in a timeseries that describes the - time-varying values of a ExponentialHistogram of double values. A ExponentialHistogram contains - summary statistics for a population of values, it may optionally contain the - distribution of those values across a set of buckets. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - @typing_extensions.final - class Buckets(google.protobuf.message.Message): - """Buckets are a set of bucket counts, encoded in a contiguous array - of counts. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - OFFSET_FIELD_NUMBER: builtins.int - BUCKET_COUNTS_FIELD_NUMBER: builtins.int - offset: builtins.int - """The bucket index of the first entry in the bucket_counts array. - - Note: This uses a varint encoding as a simple form of compression. - """ - @property - def bucket_counts(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """An array of count values, where bucket_counts[i] carries - the count of the bucket at index (offset+i). bucket_counts[i] is the count - of values greater than base^(offset+i) and less than or equal to - base^(offset+i+1). - - Note: By contrast, the explicit HistogramDataPoint uses - fixed64. This field is expected to have many buckets, - especially zeros, so uint64 has been selected to ensure - varint encoding. - """ - def __init__( - self, - *, - offset: builtins.int = ..., - bucket_counts: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["bucket_counts", b"bucket_counts", "offset", b"offset"]) -> None: ... - - ATTRIBUTES_FIELD_NUMBER: builtins.int - START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - COUNT_FIELD_NUMBER: builtins.int - SUM_FIELD_NUMBER: builtins.int - SCALE_FIELD_NUMBER: builtins.int - ZERO_COUNT_FIELD_NUMBER: builtins.int - POSITIVE_FIELD_NUMBER: builtins.int - NEGATIVE_FIELD_NUMBER: builtins.int - FLAGS_FIELD_NUMBER: builtins.int - EXEMPLARS_FIELD_NUMBER: builtins.int - MIN_FIELD_NUMBER: builtins.int - MAX_FIELD_NUMBER: builtins.int - ZERO_THRESHOLD_FIELD_NUMBER: builtins.int - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """The set of key/value pairs that uniquely identify the timeseries from - where this point belongs. The list may be empty (may contain 0 elements). - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - start_time_unix_nano: builtins.int - """StartTimeUnixNano is optional but strongly encouraged, see the - the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - time_unix_nano: builtins.int - """TimeUnixNano is required, see the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - count: builtins.int - """The number of values in the population. Must be - non-negative. This value must be equal to the sum of the "bucket_counts" - values in the positive and negative Buckets plus the "zero_count" field. - """ - sum: builtins.float - """The sum of the values in the population. If count is zero then this field - must be zero. - - Note: Sum should only be filled out when measuring non-negative discrete - events, and is assumed to be monotonic over the values of these events. - Negative events *can* be recorded, but sum should not be filled out when - doing so. This is specifically to enforce compatibility w/ OpenMetrics, - see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram - """ - scale: builtins.int - """scale describes the resolution of the histogram. Boundaries are - located at powers of the base, where: - - base = (2^(2^-scale)) - - The histogram bucket identified by `index`, a signed integer, - contains values that are greater than (base^index) and - less than or equal to (base^(index+1)). - - The positive and negative ranges of the histogram are expressed - separately. Negative values are mapped by their absolute value - into the negative range using the same scale as the positive range. - - scale is not restricted by the protocol, as the permissible - values depend on the range of the data. - """ - zero_count: builtins.int - """The count of values that are either exactly zero or - within the region considered zero by the instrumentation at the - tolerated degree of precision. This bucket stores values that - cannot be expressed using the standard exponential formula as - well as values that have been rounded to zero. - - Implementations MAY consider the zero bucket to have probability - mass equal to (zero_count / count). - """ - @property - def positive(self) -> global___ExponentialHistogramDataPoint.Buckets: - """positive carries the positive range of exponential bucket counts.""" - @property - def negative(self) -> global___ExponentialHistogramDataPoint.Buckets: - """negative carries the negative range of exponential bucket counts.""" - flags: builtins.int - """Flags that apply to this specific data point. See DataPointFlags - for the available flags and their meaning. - """ - @property - def exemplars(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Exemplar]: - """(Optional) List of exemplars collected from - measurements that were used to form the data point - """ - min: builtins.float - """The minimum value over (start_time, end_time].""" - max: builtins.float - """The maximum value over (start_time, end_time].""" - zero_threshold: builtins.float - """ZeroThreshold may be optionally set to convey the width of the zero - region. Where the zero region is defined as the closed interval - [-ZeroThreshold, ZeroThreshold]. - When ZeroThreshold is 0, zero count bucket stores values that cannot be - expressed using the standard exponential formula as well as values that - have been rounded to zero. - """ - def __init__( - self, - *, - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - start_time_unix_nano: builtins.int = ..., - time_unix_nano: builtins.int = ..., - count: builtins.int = ..., - sum: builtins.float | None = ..., - scale: builtins.int = ..., - zero_count: builtins.int = ..., - positive: global___ExponentialHistogramDataPoint.Buckets | None = ..., - negative: global___ExponentialHistogramDataPoint.Buckets | None = ..., - flags: builtins.int = ..., - exemplars: collections.abc.Iterable[global___Exemplar] | None = ..., - min: builtins.float | None = ..., - max: builtins.float | None = ..., - zero_threshold: builtins.float = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "max", b"max", "min", b"min", "negative", b"negative", "positive", b"positive", "sum", b"sum"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["_max", b"_max", "_min", b"_min", "_sum", b"_sum", "attributes", b"attributes", "count", b"count", "exemplars", b"exemplars", "flags", b"flags", "max", b"max", "min", b"min", "negative", b"negative", "positive", b"positive", "scale", b"scale", "start_time_unix_nano", b"start_time_unix_nano", "sum", b"sum", "time_unix_nano", b"time_unix_nano", "zero_count", b"zero_count", "zero_threshold", b"zero_threshold"]) -> None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_max", b"_max"]) -> typing_extensions.Literal["max"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_min", b"_min"]) -> typing_extensions.Literal["min"] | None: ... - @typing.overload - def WhichOneof(self, oneof_group: typing_extensions.Literal["_sum", b"_sum"]) -> typing_extensions.Literal["sum"] | None: ... - -global___ExponentialHistogramDataPoint = ExponentialHistogramDataPoint - -@typing_extensions.final -class SummaryDataPoint(google.protobuf.message.Message): - """SummaryDataPoint is a single data point in a timeseries that describes the - time-varying values of a Summary metric. The count and sum fields represent - cumulative values. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - @typing_extensions.final - class ValueAtQuantile(google.protobuf.message.Message): - """Represents the value at a given quantile of a distribution. - - To record Min and Max values following conventions are used: - - The 1.0 quantile is equivalent to the maximum value observed. - - The 0.0 quantile is equivalent to the minimum value observed. - - See the following issue for more context: - https://github.com/open-telemetry/opentelemetry-proto/issues/125 - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - QUANTILE_FIELD_NUMBER: builtins.int - VALUE_FIELD_NUMBER: builtins.int - quantile: builtins.float - """The quantile of a distribution. Must be in the interval - [0.0, 1.0]. - """ - value: builtins.float - """The value at the given quantile of a distribution. - - Quantile values must NOT be negative. - """ - def __init__( - self, - *, - quantile: builtins.float = ..., - value: builtins.float = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["quantile", b"quantile", "value", b"value"]) -> None: ... - - ATTRIBUTES_FIELD_NUMBER: builtins.int - START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - COUNT_FIELD_NUMBER: builtins.int - SUM_FIELD_NUMBER: builtins.int - QUANTILE_VALUES_FIELD_NUMBER: builtins.int - FLAGS_FIELD_NUMBER: builtins.int - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """The set of key/value pairs that uniquely identify the timeseries from - where this point belongs. The list may be empty (may contain 0 elements). - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - start_time_unix_nano: builtins.int - """StartTimeUnixNano is optional but strongly encouraged, see the - the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - time_unix_nano: builtins.int - """TimeUnixNano is required, see the detailed comments above Metric. - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - count: builtins.int - """count is the number of values in the population. Must be non-negative.""" - sum: builtins.float - """sum of the values in the population. If count is zero then this field - must be zero. - - Note: Sum should only be filled out when measuring non-negative discrete - events, and is assumed to be monotonic over the values of these events. - Negative events *can* be recorded, but sum should not be filled out when - doing so. This is specifically to enforce compatibility w/ OpenMetrics, - see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#summary - """ - @property - def quantile_values(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SummaryDataPoint.ValueAtQuantile]: - """(Optional) list of values at different quantiles of the distribution calculated - from the current snapshot. The quantiles must be strictly increasing. - """ - flags: builtins.int - """Flags that apply to this specific data point. See DataPointFlags - for the available flags and their meaning. - """ - def __init__( - self, - *, - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - start_time_unix_nano: builtins.int = ..., - time_unix_nano: builtins.int = ..., - count: builtins.int = ..., - sum: builtins.float = ..., - quantile_values: collections.abc.Iterable[global___SummaryDataPoint.ValueAtQuantile] | None = ..., - flags: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "count", b"count", "flags", b"flags", "quantile_values", b"quantile_values", "start_time_unix_nano", b"start_time_unix_nano", "sum", b"sum", "time_unix_nano", b"time_unix_nano"]) -> None: ... - -global___SummaryDataPoint = SummaryDataPoint - -@typing_extensions.final -class Exemplar(google.protobuf.message.Message): - """A representation of an exemplar, which is a sample input measurement. - Exemplars also hold information about the environment when the measurement - was recorded, for example the span and trace ID of the active span when the - exemplar was recorded. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - FILTERED_ATTRIBUTES_FIELD_NUMBER: builtins.int - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - AS_DOUBLE_FIELD_NUMBER: builtins.int - AS_INT_FIELD_NUMBER: builtins.int - SPAN_ID_FIELD_NUMBER: builtins.int - TRACE_ID_FIELD_NUMBER: builtins.int - @property - def filtered_attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """The set of key/value pairs that were filtered out by the aggregator, but - recorded alongside the original measurement. Only key/value pairs that were - filtered out by the aggregator should be included - """ - time_unix_nano: builtins.int - """time_unix_nano is the exact time when this exemplar was recorded - - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January - 1970. - """ - as_double: builtins.float - as_int: builtins.int - span_id: builtins.bytes - """(Optional) Span ID of the exemplar trace. - span_id may be missing if the measurement is not recorded inside a trace - or if the trace is not sampled. - """ - trace_id: builtins.bytes - """(Optional) Trace ID of the exemplar trace. - trace_id may be missing if the measurement is not recorded inside a trace - or if the trace is not sampled. - """ - def __init__( - self, - *, - filtered_attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - time_unix_nano: builtins.int = ..., - as_double: builtins.float = ..., - as_int: builtins.int = ..., - span_id: builtins.bytes = ..., - trace_id: builtins.bytes = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["as_double", b"as_double", "as_int", b"as_int", "filtered_attributes", b"filtered_attributes", "span_id", b"span_id", "time_unix_nano", b"time_unix_nano", "trace_id", b"trace_id", "value", b"value"]) -> None: ... - def WhichOneof(self, oneof_group: typing_extensions.Literal["value", b"value"]) -> typing_extensions.Literal["as_double", "as_int"] | None: ... - -global___Exemplar = Exemplar diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py deleted file mode 100644 index 5d8c241a36b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/profiles/v1development/profiles.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n9opentelemetry/proto/profiles/v1development/profiles.proto\x12*opentelemetry.proto.profiles.v1development\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"\xf6\x03\n\x12ProfilesDictionary\x12J\n\rmapping_table\x18\x01 \x03(\x0b\x32\x33.opentelemetry.proto.profiles.v1development.Mapping\x12L\n\x0elocation_table\x18\x02 \x03(\x0b\x32\x34.opentelemetry.proto.profiles.v1development.Location\x12L\n\x0e\x66unction_table\x18\x03 \x03(\x0b\x32\x34.opentelemetry.proto.profiles.v1development.Function\x12\x44\n\nlink_table\x18\x04 \x03(\x0b\x32\x30.opentelemetry.proto.profiles.v1development.Link\x12\x14\n\x0cstring_table\x18\x05 \x03(\t\x12T\n\x0f\x61ttribute_table\x18\x06 \x03(\x0b\x32;.opentelemetry.proto.profiles.v1development.KeyValueAndUnit\x12\x46\n\x0bstack_table\x18\x07 \x03(\x0b\x32\x31.opentelemetry.proto.profiles.v1development.Stack\"\xbb\x01\n\x0cProfilesData\x12W\n\x11resource_profiles\x18\x01 \x03(\x0b\x32<.opentelemetry.proto.profiles.v1development.ResourceProfiles\x12R\n\ndictionary\x18\x02 \x01(\x0b\x32>.opentelemetry.proto.profiles.v1development.ProfilesDictionary\"\xbe\x01\n\x10ResourceProfiles\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12Q\n\x0escope_profiles\x18\x02 \x03(\x0b\x32\x39.opentelemetry.proto.profiles.v1development.ScopeProfiles\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\xae\x01\n\rScopeProfiles\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12\x45\n\x08profiles\x18\x02 \x03(\x0b\x32\x33.opentelemetry.proto.profiles.v1development.Profile\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\xb1\x03\n\x07Profile\x12J\n\x0bsample_type\x18\x01 \x01(\x0b\x32\x35.opentelemetry.proto.profiles.v1development.ValueType\x12\x43\n\x07samples\x18\x02 \x03(\x0b\x32\x32.opentelemetry.proto.profiles.v1development.Sample\x12\x16\n\x0etime_unix_nano\x18\x03 \x01(\x06\x12\x15\n\rduration_nano\x18\x04 \x01(\x04\x12J\n\x0bperiod_type\x18\x05 \x01(\x0b\x32\x35.opentelemetry.proto.profiles.v1development.ValueType\x12\x0e\n\x06period\x18\x06 \x01(\x03\x12\x12\n\nprofile_id\x18\x07 \x01(\x0c\x12 \n\x18\x64ropped_attributes_count\x18\x08 \x01(\r\x12\x1f\n\x17original_payload_format\x18\t \x01(\t\x12\x18\n\x10original_payload\x18\n \x01(\x0c\x12\x19\n\x11\x61ttribute_indices\x18\x0b \x03(\x05\")\n\x04Link\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\"9\n\tValueType\x12\x15\n\rtype_strindex\x18\x01 \x01(\x05\x12\x15\n\runit_strindex\x18\x02 \x01(\x05\"z\n\x06Sample\x12\x13\n\x0bstack_index\x18\x01 \x01(\x05\x12\x19\n\x11\x61ttribute_indices\x18\x02 \x03(\x05\x12\x12\n\nlink_index\x18\x03 \x01(\x05\x12\x0e\n\x06values\x18\x04 \x03(\x03\x12\x1c\n\x14timestamps_unix_nano\x18\x05 \x03(\x06\"\x80\x01\n\x07Mapping\x12\x14\n\x0cmemory_start\x18\x01 \x01(\x04\x12\x14\n\x0cmemory_limit\x18\x02 \x01(\x04\x12\x13\n\x0b\x66ile_offset\x18\x03 \x01(\x04\x12\x19\n\x11\x66ilename_strindex\x18\x04 \x01(\x05\x12\x19\n\x11\x61ttribute_indices\x18\x05 \x03(\x05\"!\n\x05Stack\x12\x18\n\x10location_indices\x18\x01 \x03(\x05\"\x8e\x01\n\x08Location\x12\x15\n\rmapping_index\x18\x01 \x01(\x05\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\x04\x12?\n\x05lines\x18\x03 \x03(\x0b\x32\x30.opentelemetry.proto.profiles.v1development.Line\x12\x19\n\x11\x61ttribute_indices\x18\x04 \x03(\x05\"<\n\x04Line\x12\x16\n\x0e\x66unction_index\x18\x01 \x01(\x05\x12\x0c\n\x04line\x18\x02 \x01(\x03\x12\x0e\n\x06\x63olumn\x18\x03 \x01(\x03\"n\n\x08\x46unction\x12\x15\n\rname_strindex\x18\x01 \x01(\x05\x12\x1c\n\x14system_name_strindex\x18\x02 \x01(\x05\x12\x19\n\x11\x66ilename_strindex\x18\x03 \x01(\x05\x12\x12\n\nstart_line\x18\x04 \x01(\x03\"v\n\x0fKeyValueAndUnit\x12\x14\n\x0ckey_strindex\x18\x01 \x01(\x05\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.opentelemetry.proto.common.v1.AnyValue\x12\x15\n\runit_strindex\x18\x03 \x01(\x05\x42\xa4\x01\n-io.opentelemetry.proto.profiles.v1developmentB\rProfilesProtoP\x01Z5go.opentelemetry.io/proto/otlp/profiles/v1development\xaa\x02*OpenTelemetry.Proto.Profiles.V1Developmentb\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.profiles.v1development.profiles_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n-io.opentelemetry.proto.profiles.v1developmentB\rProfilesProtoP\001Z5go.opentelemetry.io/proto/otlp/profiles/v1development\252\002*OpenTelemetry.Proto.Profiles.V1Development' - _globals['_PROFILESDICTIONARY']._serialized_start=198 - _globals['_PROFILESDICTIONARY']._serialized_end=700 - _globals['_PROFILESDATA']._serialized_start=703 - _globals['_PROFILESDATA']._serialized_end=890 - _globals['_RESOURCEPROFILES']._serialized_start=893 - _globals['_RESOURCEPROFILES']._serialized_end=1083 - _globals['_SCOPEPROFILES']._serialized_start=1086 - _globals['_SCOPEPROFILES']._serialized_end=1260 - _globals['_PROFILE']._serialized_start=1263 - _globals['_PROFILE']._serialized_end=1696 - _globals['_LINK']._serialized_start=1698 - _globals['_LINK']._serialized_end=1739 - _globals['_VALUETYPE']._serialized_start=1741 - _globals['_VALUETYPE']._serialized_end=1798 - _globals['_SAMPLE']._serialized_start=1800 - _globals['_SAMPLE']._serialized_end=1922 - _globals['_MAPPING']._serialized_start=1925 - _globals['_MAPPING']._serialized_end=2053 - _globals['_STACK']._serialized_start=2055 - _globals['_STACK']._serialized_end=2088 - _globals['_LOCATION']._serialized_start=2091 - _globals['_LOCATION']._serialized_end=2233 - _globals['_LINE']._serialized_start=2235 - _globals['_LINE']._serialized_end=2295 - _globals['_FUNCTION']._serialized_start=2297 - _globals['_FUNCTION']._serialized_end=2407 - _globals['_KEYVALUEANDUNIT']._serialized_start=2409 - _globals['_KEYVALUEANDUNIT']._serialized_end=2527 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi deleted file mode 100644 index 01938eded00..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/profiles/v1development/profiles_pb2.pyi +++ /dev/null @@ -1,800 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2023, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -This file includes work covered by the following copyright and permission notices: - -Copyright 2016 Google Inc. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import opentelemetry.proto.common.v1.common_pb2 -import opentelemetry.proto.resource.v1.resource_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class ProfilesDictionary(google.protobuf.message.Message): - """ Relationships Diagram - - ┌──────────────────┐ LEGEND - │ ProfilesData │ ─────┐ - └──────────────────┘ │ ─────▶ embedded - │ │ - │ 1-n │ ─────▷ referenced by index - ▼ ▼ - ┌──────────────────┐ ┌────────────────────┐ - │ ResourceProfiles │ │ ProfilesDictionary │ - └──────────────────┘ └────────────────────┘ - │ - │ 1-n - ▼ - ┌──────────────────┐ - │ ScopeProfiles │ - └──────────────────┘ - │ - │ 1-n - ▼ - ┌──────────────────┐ - │ Profile │ - └──────────────────┘ - │ n-1 - │ 1-n ┌───────────────────────────────────────┐ - ▼ │ ▽ - ┌──────────────────┐ 1-n ┌─────────────────┐ ┌──────────┐ - │ Sample │ ──────▷ │ KeyValueAndUnit │ │ Link │ - └──────────────────┘ └─────────────────┘ └──────────┘ - │ △ △ - │ n-1 │ │ 1-n - ▽ │ │ - ┌──────────────────┐ │ │ - │ Stack │ │ │ - └──────────────────┘ │ │ - │ 1-n │ │ - │ 1-n ┌────────────────┘ │ - ▽ │ │ - ┌──────────────────┐ n-1 ┌─────────────┐ - │ Location │ ──────▷ │ Mapping │ - └──────────────────┘ └─────────────┘ - │ - │ 1-n - ▼ - ┌──────────────────┐ - │ Line │ - └──────────────────┘ - │ - │ 1-1 - ▽ - ┌──────────────────┐ - │ Function │ - └──────────────────┘ - - ProfilesDictionary represents the profiles data shared across the - entire message being sent. The following applies to all fields in this - message: - - - A dictionary is an array of dictionary items. Users of the dictionary - compactly reference the items using the index within the array. - - - A dictionary MUST have a zero value encoded as the first element. This - allows for _index fields pointing into the dictionary to use a 0 pointer - value to indicate 'null' / 'not set'. Unless otherwise defined, a 'zero - value' message value is one with all default field values, so as to - minimize wire encoded size. - - - There SHOULD NOT be dupes in a dictionary. The identity of dictionary - items is based on their value, recursively as needed. If a particular - implementation does emit duplicated items, it MUST NOT attempt to give them - meaning based on the index or order. A profile processor may remove - duplicate items and this MUST NOT have any observable effects for - consumers. - - - There SHOULD NOT be orphaned (unreferenced) items in a dictionary. A - profile processor may remove ("garbage-collect") orphaned items and this - MUST NOT have any observable effects for consumers. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MAPPING_TABLE_FIELD_NUMBER: builtins.int - LOCATION_TABLE_FIELD_NUMBER: builtins.int - FUNCTION_TABLE_FIELD_NUMBER: builtins.int - LINK_TABLE_FIELD_NUMBER: builtins.int - STRING_TABLE_FIELD_NUMBER: builtins.int - ATTRIBUTE_TABLE_FIELD_NUMBER: builtins.int - STACK_TABLE_FIELD_NUMBER: builtins.int - @property - def mapping_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Mapping]: - """Mappings from address ranges to the image/binary/library mapped - into that address range referenced by locations via Location.mapping_index. - - mapping_table[0] must always be zero value (Mapping{}) and present. - """ - @property - def location_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Location]: - """Locations referenced by samples via Stack.location_indices. - - location_table[0] must always be zero value (Location{}) and present. - """ - @property - def function_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Function]: - """Functions referenced by locations via Line.function_index. - - function_table[0] must always be zero value (Function{}) and present. - """ - @property - def link_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Link]: - """Links referenced by samples via Sample.link_index. - - link_table[0] must always be zero value (Link{}) and present. - """ - @property - def string_table(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: - """A common table for strings referenced by various messages. - - string_table[0] must always be "" and present. - """ - @property - def attribute_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___KeyValueAndUnit]: - """A common table for attributes referenced by the Profile, Sample, Mapping - and Location messages below through attribute_indices field. Each entry is - a key/value pair with an optional unit. Since this is a dictionary table, - multiple entries with the same key may be present, unlike direct attribute - tables like Resource.attributes. The referencing attribute_indices fields, - though, do maintain the key uniqueness requirement. - - It's recommended to use attributes for variables with bounded cardinality, - such as categorical variables - (https://en.wikipedia.org/wiki/Categorical_variable). Using an attribute of - a floating point type (e.g., CPU time) in a sample can quickly make every - attribute value unique, defeating the purpose of the dictionary and - impractically increasing the profile size. - - Examples of attributes: - "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" - "abc.com/myattribute": true - "allocation_size": 128 bytes - - attribute_table[0] must always be zero value (KeyValueAndUnit{}) and present. - """ - @property - def stack_table(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Stack]: - """Stacks referenced by samples via Sample.stack_index. - - stack_table[0] must always be zero value (Stack{}) and present. - """ - def __init__( - self, - *, - mapping_table: collections.abc.Iterable[global___Mapping] | None = ..., - location_table: collections.abc.Iterable[global___Location] | None = ..., - function_table: collections.abc.Iterable[global___Function] | None = ..., - link_table: collections.abc.Iterable[global___Link] | None = ..., - string_table: collections.abc.Iterable[builtins.str] | None = ..., - attribute_table: collections.abc.Iterable[global___KeyValueAndUnit] | None = ..., - stack_table: collections.abc.Iterable[global___Stack] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attribute_table", b"attribute_table", "function_table", b"function_table", "link_table", b"link_table", "location_table", b"location_table", "mapping_table", b"mapping_table", "stack_table", b"stack_table", "string_table", b"string_table"]) -> None: ... - -global___ProfilesDictionary = ProfilesDictionary - -@typing_extensions.final -class ProfilesData(google.protobuf.message.Message): - """ProfilesData represents the profiles data that can be stored in persistent storage, - OR can be embedded by other protocols that transfer OTLP profiles data but do not - implement the OTLP protocol. - - The main difference between this message and collector protocol is that - in this message there will not be any "control" or "metadata" specific to - OTLP protocol. - - When new fields are added into this message, the OTLP request MUST be updated - as well. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_PROFILES_FIELD_NUMBER: builtins.int - DICTIONARY_FIELD_NUMBER: builtins.int - @property - def resource_profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceProfiles]: - """An array of ResourceProfiles. - For data coming from an SDK profiler, this array will typically contain one - element. Host-level profilers will usually create one ResourceProfile per - container, as well as one additional ResourceProfile grouping all samples - from non-containerized processes. - Other resource groupings are possible as well and clarified via - Resource.attributes and semantic conventions. - Tools that visualize profiles should prefer displaying - resources_profiles[0].scope_profiles[0].profiles[0] by default. - """ - @property - def dictionary(self) -> global___ProfilesDictionary: - """One instance of ProfilesDictionary""" - def __init__( - self, - *, - resource_profiles: collections.abc.Iterable[global___ResourceProfiles] | None = ..., - dictionary: global___ProfilesDictionary | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["dictionary", b"dictionary", "resource_profiles", b"resource_profiles"]) -> None: ... - -global___ProfilesData = ProfilesData - -@typing_extensions.final -class ResourceProfiles(google.protobuf.message.Message): - """A collection of ScopeProfiles from a Resource.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_FIELD_NUMBER: builtins.int - SCOPE_PROFILES_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: - """The resource for the profiles in this message. - If this field is not set then no resource info is known. - """ - @property - def scope_profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeProfiles]: - """A list of ScopeProfiles that originate from a resource.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the resource data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "resource" field. It does not apply - to the data in the "scope_profiles" field which have their own schema_url field. - """ - def __init__( - self, - *, - resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., - scope_profiles: collections.abc.Iterable[global___ScopeProfiles] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_profiles", b"scope_profiles"]) -> None: ... - -global___ResourceProfiles = ResourceProfiles - -@typing_extensions.final -class ScopeProfiles(google.protobuf.message.Message): - """A collection of Profiles produced by an InstrumentationScope.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - SCOPE_FIELD_NUMBER: builtins.int - PROFILES_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: - """The instrumentation scope information for the profiles in this message. - Semantically when InstrumentationScope isn't set, it is equivalent with - an empty instrumentation scope name (unknown). - """ - @property - def profiles(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Profile]: - """A list of Profiles that originate from an instrumentation scope.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the profile data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "scope" field and all profiles in the - "profiles" field. - """ - def __init__( - self, - *, - scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., - profiles: collections.abc.Iterable[global___Profile] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["profiles", b"profiles", "schema_url", b"schema_url", "scope", b"scope"]) -> None: ... - -global___ScopeProfiles = ScopeProfiles - -@typing_extensions.final -class Profile(google.protobuf.message.Message): - """Profile is a common stacktrace profile format. - - Measurements represented with this format should follow the - following conventions: - - - Consumers should treat unset optional fields as if they had been - set with their default value. - - - When possible, measurements should be stored in "unsampled" form - that is most useful to humans. There should be enough - information present to determine the original sampled values. - - - The profile is represented as a set of samples, where each sample - references a stack trace which is a list of locations, each belonging - to a mapping. - - There is a N->1 relationship from Stack.location_indices entries to - locations. For every Stack.location_indices entry there must be a - unique Location with that index. - - There is an optional N->1 relationship from locations to - mappings. For every nonzero Location.mapping_id there must be a - unique Mapping with that index. - - Represents a complete profile, including sample types, samples, mappings to - binaries, stacks, locations, functions, string table, and additional - metadata. It modifies and annotates pprof Profile with OpenTelemetry - specific fields. - - Note that whilst fields in this message retain the name and field id from pprof in most cases - for ease of understanding data migration, it is not intended that pprof:Profile and - OpenTelemetry:Profile encoding be wire compatible. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - SAMPLE_TYPE_FIELD_NUMBER: builtins.int - SAMPLES_FIELD_NUMBER: builtins.int - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - DURATION_NANO_FIELD_NUMBER: builtins.int - PERIOD_TYPE_FIELD_NUMBER: builtins.int - PERIOD_FIELD_NUMBER: builtins.int - PROFILE_ID_FIELD_NUMBER: builtins.int - DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int - ORIGINAL_PAYLOAD_FORMAT_FIELD_NUMBER: builtins.int - ORIGINAL_PAYLOAD_FIELD_NUMBER: builtins.int - ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int - @property - def sample_type(self) -> global___ValueType: - """The type and unit of all Sample.values in this profile. - For a cpu or off-cpu profile this might be: - ["cpu","nanoseconds"] or ["off_cpu","nanoseconds"] - For a heap profile, this might be: - ["allocated_objects","count"] or ["allocated_space","bytes"], - """ - @property - def samples(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Sample]: - """The set of samples recorded in this profile.""" - time_unix_nano: builtins.int - """The following fields 3-12 are informational, do not affect - interpretation of results. - - Time of collection. Value is UNIX Epoch time in nanoseconds since 00:00:00 - UTC on 1 January 1970. - """ - duration_nano: builtins.int - """Duration of the profile. For instant profiles like live heap snapshot, the - duration can be zero but it may be preferable to set time_unix_nano to the - process start time and duration_nano to the relative time when the profile - was gathered. This ensures Sample.timestamps_unix_nano values such as - allocation timestamp fall into the profile time range. - """ - @property - def period_type(self) -> global___ValueType: - """The kind of events between sampled occurrences. - e.g [ "cpu","cycles" ] or [ "heap","bytes" ] - """ - period: builtins.int - """The number of events between sampled occurrences.""" - profile_id: builtins.bytes - """A globally unique identifier for a profile. The ID is a 16-byte array. An ID with - all zeroes is considered invalid. It may be used for deduplication and signal - correlation purposes. It is acceptable to treat two profiles with different values - in this field as not equal, even if they represented the same object at an earlier - time. - This field is optional; an ID may be assigned to an ID-less profile in a later step. - """ - dropped_attributes_count: builtins.int - """The number of attributes that were discarded. Attributes - can be discarded because their keys are too long or because there are too many - attributes. If this value is 0, then no attributes were dropped. - """ - original_payload_format: builtins.str - """The original payload format. See also original_payload. Optional, but the - format and the bytes must be set or unset together. - - The allowed values for the format string are defined by the OpenTelemetry - specification. Some examples are "jfr", "pprof", "linux_perf". - - The original payload may be optionally provided when the conversion to the - OLTP format was done from a different format with some loss of the fidelity - and the receiver may want to store the original payload to allow future - lossless export or reinterpretation. Some examples of the original format - are JFR (Java Flight Recorder), pprof, Linux perf. - - Even when the original payload is in a format that is semantically close to - OTLP, such as pprof, a conversion may still be lossy in some cases (e.g. if - the pprof file contains custom extensions or conventions). - - The original payload can be large in size, so including the original - payload should be configurable by the profiler or collector options. The - default behavior should be to not include the original payload. - """ - original_payload: builtins.bytes - """The original payload bytes. See also original_payload_format. Optional, but - format and the bytes must be set or unset together. - """ - @property - def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """References to attributes in attribute_table. [optional]""" - def __init__( - self, - *, - sample_type: global___ValueType | None = ..., - samples: collections.abc.Iterable[global___Sample] | None = ..., - time_unix_nano: builtins.int = ..., - duration_nano: builtins.int = ..., - period_type: global___ValueType | None = ..., - period: builtins.int = ..., - profile_id: builtins.bytes = ..., - dropped_attributes_count: builtins.int = ..., - original_payload_format: builtins.str = ..., - original_payload: builtins.bytes = ..., - attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["period_type", b"period_type", "sample_type", b"sample_type"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["attribute_indices", b"attribute_indices", "dropped_attributes_count", b"dropped_attributes_count", "duration_nano", b"duration_nano", "original_payload", b"original_payload", "original_payload_format", b"original_payload_format", "period", b"period", "period_type", b"period_type", "profile_id", b"profile_id", "sample_type", b"sample_type", "samples", b"samples", "time_unix_nano", b"time_unix_nano"]) -> None: ... - -global___Profile = Profile - -@typing_extensions.final -class Link(google.protobuf.message.Message): - """A pointer from a profile Sample to a trace Span. - Connects a profile sample to a trace span, identified by unique trace and span IDs. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TRACE_ID_FIELD_NUMBER: builtins.int - SPAN_ID_FIELD_NUMBER: builtins.int - trace_id: builtins.bytes - """A unique identifier of a trace that this linked span is part of. The ID is a - 16-byte array. - """ - span_id: builtins.bytes - """A unique identifier for the linked span. The ID is an 8-byte array.""" - def __init__( - self, - *, - trace_id: builtins.bytes = ..., - span_id: builtins.bytes = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["span_id", b"span_id", "trace_id", b"trace_id"]) -> None: ... - -global___Link = Link - -@typing_extensions.final -class ValueType(google.protobuf.message.Message): - """ValueType describes the type and units of a value.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TYPE_STRINDEX_FIELD_NUMBER: builtins.int - UNIT_STRINDEX_FIELD_NUMBER: builtins.int - type_strindex: builtins.int - """Index into ProfilesDictionary.string_table.""" - unit_strindex: builtins.int - """Index into ProfilesDictionary.string_table.""" - def __init__( - self, - *, - type_strindex: builtins.int = ..., - unit_strindex: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["type_strindex", b"type_strindex", "unit_strindex", b"unit_strindex"]) -> None: ... - -global___ValueType = ValueType - -@typing_extensions.final -class Sample(google.protobuf.message.Message): - """Each Sample records values encountered in some program context. The program - context is typically a stack trace, perhaps augmented with auxiliary - information like the thread-id, some indicator of a higher level request - being handled etc. - - A Sample MUST have have at least one values or timestamps_unix_nano entry. If - both fields are populated, they MUST contain the same number of elements, and - the elements at the same index MUST refer to the same event. - - For the purposes of efficiently representing aggregated data observations, a Sample is regarded - as having a shared identity and an associated collection of per-observation data points. - Samples having the same identity SHOULD be combined by inserting timestamps and values to the data arrays. - - Examples of different ways ('shapes') of representing a sample with the total value of 10: - - Report of a stacktrace at 10 timestamps (consumers must assume the value is 1 for each point): - values: [] - timestamps_unix_nano: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - - Report of a stacktrace with an aggregated value without timestamps: - values: [10] - timestamps_unix_nano: [] - - Report of a stacktrace at 4 timestamps where each point records a specific value: - values: [2, 2, 3, 3] - timestamps_unix_nano: [1, 2, 3, 4] - - All Samples for a Profile SHOULD have the same shape, i.e. all data observation series should consistently - adopt the same data recording style. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - STACK_INDEX_FIELD_NUMBER: builtins.int - ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int - LINK_INDEX_FIELD_NUMBER: builtins.int - VALUES_FIELD_NUMBER: builtins.int - TIMESTAMPS_UNIX_NANO_FIELD_NUMBER: builtins.int - stack_index: builtins.int - """A Sample's identity (i.e. 'primary key') is the tuple of {stack_index, set_of(attribute_indices), link_index} - - Reference to stack in ProfilesDictionary.stack_table. - """ - @property - def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """References to attributes in ProfilesDictionary.attribute_table. [optional]""" - link_index: builtins.int - """Reference to link in ProfilesDictionary.link_table. [optional] - It can be unset / set to 0 if no link exists, as link_table[0] is always a 'null' default value. - """ - @property - def values(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """The following fields may contain per-observation data and do not form part of the Sample's identity. - - The type and unit of each value is defined by Profile.sample_type. - """ - @property - def timestamps_unix_nano(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """Timestamps associated with Sample. Value is UNIX Epoch time in nanoseconds - since 00:00:00 UTC on 1 January 1970. The timestamps should fall within the - [Profile.time_unix_nano, Profile.time_unix_nano + Profile.duration_nano) - time range. - """ - def __init__( - self, - *, - stack_index: builtins.int = ..., - attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., - link_index: builtins.int = ..., - values: collections.abc.Iterable[builtins.int] | None = ..., - timestamps_unix_nano: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attribute_indices", b"attribute_indices", "link_index", b"link_index", "stack_index", b"stack_index", "timestamps_unix_nano", b"timestamps_unix_nano", "values", b"values"]) -> None: ... - -global___Sample = Sample - -@typing_extensions.final -class Mapping(google.protobuf.message.Message): - """Describes the mapping of a binary in memory, including its address range, - file offset, and metadata like build ID - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MEMORY_START_FIELD_NUMBER: builtins.int - MEMORY_LIMIT_FIELD_NUMBER: builtins.int - FILE_OFFSET_FIELD_NUMBER: builtins.int - FILENAME_STRINDEX_FIELD_NUMBER: builtins.int - ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int - memory_start: builtins.int - """Address at which the binary (or DLL) is loaded into memory.""" - memory_limit: builtins.int - """The limit of the address range occupied by this mapping.""" - file_offset: builtins.int - """Offset in the binary that corresponds to the first mapped address.""" - filename_strindex: builtins.int - """The object this entry is loaded from. This can be a filename on - disk for the main binary and shared libraries, or virtual - abstractions like "[vdso]". - Index into ProfilesDictionary.string_table. - """ - @property - def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """References to attributes in ProfilesDictionary.attribute_table. [optional]""" - def __init__( - self, - *, - memory_start: builtins.int = ..., - memory_limit: builtins.int = ..., - file_offset: builtins.int = ..., - filename_strindex: builtins.int = ..., - attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attribute_indices", b"attribute_indices", "file_offset", b"file_offset", "filename_strindex", b"filename_strindex", "memory_limit", b"memory_limit", "memory_start", b"memory_start"]) -> None: ... - -global___Mapping = Mapping - -@typing_extensions.final -class Stack(google.protobuf.message.Message): - """A Stack represents a stack trace as a list of locations.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - LOCATION_INDICES_FIELD_NUMBER: builtins.int - @property - def location_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """References to locations in ProfilesDictionary.location_table. - The first location is the leaf frame. - """ - def __init__( - self, - *, - location_indices: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["location_indices", b"location_indices"]) -> None: ... - -global___Stack = Stack - -@typing_extensions.final -class Location(google.protobuf.message.Message): - """Describes function and line table debug information.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - MAPPING_INDEX_FIELD_NUMBER: builtins.int - ADDRESS_FIELD_NUMBER: builtins.int - LINES_FIELD_NUMBER: builtins.int - ATTRIBUTE_INDICES_FIELD_NUMBER: builtins.int - mapping_index: builtins.int - """Reference to mapping in ProfilesDictionary.mapping_table. - It can be unset / set to 0 if the mapping is unknown or not applicable for - this profile type, as mapping_table[0] is always a 'null' default mapping. - """ - address: builtins.int - """The instruction address for this location, if available. It - should be within [Mapping.memory_start...Mapping.memory_limit] - for the corresponding mapping. A non-leaf address may be in the - middle of a call instruction. It is up to display tools to find - the beginning of the instruction if necessary. - """ - @property - def lines(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Line]: - """Multiple line indicates this location has inlined functions, - where the last entry represents the caller into which the - preceding entries were inlined. - - E.g., if memcpy() is inlined into printf: - lines[0].function_name == "memcpy" - lines[1].function_name == "printf" - """ - @property - def attribute_indices(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: - """References to attributes in ProfilesDictionary.attribute_table. [optional]""" - def __init__( - self, - *, - mapping_index: builtins.int = ..., - address: builtins.int = ..., - lines: collections.abc.Iterable[global___Line] | None = ..., - attribute_indices: collections.abc.Iterable[builtins.int] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["address", b"address", "attribute_indices", b"attribute_indices", "lines", b"lines", "mapping_index", b"mapping_index"]) -> None: ... - -global___Location = Location - -@typing_extensions.final -class Line(google.protobuf.message.Message): - """Details a specific line in a source code, linked to a function.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - FUNCTION_INDEX_FIELD_NUMBER: builtins.int - LINE_FIELD_NUMBER: builtins.int - COLUMN_FIELD_NUMBER: builtins.int - function_index: builtins.int - """Reference to function in ProfilesDictionary.function_table.""" - line: builtins.int - """Line number in source code. 0 means unset.""" - column: builtins.int - """Column number in source code. 0 means unset.""" - def __init__( - self, - *, - function_index: builtins.int = ..., - line: builtins.int = ..., - column: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["column", b"column", "function_index", b"function_index", "line", b"line"]) -> None: ... - -global___Line = Line - -@typing_extensions.final -class Function(google.protobuf.message.Message): - """Describes a function, including its human-readable name, system name, - source file, and starting line number in the source. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - NAME_STRINDEX_FIELD_NUMBER: builtins.int - SYSTEM_NAME_STRINDEX_FIELD_NUMBER: builtins.int - FILENAME_STRINDEX_FIELD_NUMBER: builtins.int - START_LINE_FIELD_NUMBER: builtins.int - name_strindex: builtins.int - """The function name. Empty string if not available.""" - system_name_strindex: builtins.int - """Function name, as identified by the system. For instance, - it can be a C++ mangled name. Empty string if not available. - """ - filename_strindex: builtins.int - """Source file containing the function. Empty string if not available.""" - start_line: builtins.int - """Line number in source file. 0 means unset.""" - def __init__( - self, - *, - name_strindex: builtins.int = ..., - system_name_strindex: builtins.int = ..., - filename_strindex: builtins.int = ..., - start_line: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["filename_strindex", b"filename_strindex", "name_strindex", b"name_strindex", "start_line", b"start_line", "system_name_strindex", b"system_name_strindex"]) -> None: ... - -global___Function = Function - -@typing_extensions.final -class KeyValueAndUnit(google.protobuf.message.Message): - """A custom 'dictionary native' style of encoding attributes which is more convenient - for profiles than opentelemetry.proto.common.v1.KeyValue - Specifically, uses the string table for keys and allows optional unit information. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - KEY_STRINDEX_FIELD_NUMBER: builtins.int - VALUE_FIELD_NUMBER: builtins.int - UNIT_STRINDEX_FIELD_NUMBER: builtins.int - key_strindex: builtins.int - """The index into the string table for the attribute's key.""" - @property - def value(self) -> opentelemetry.proto.common.v1.common_pb2.AnyValue: - """The value of the attribute.""" - unit_strindex: builtins.int - """The index into the string table for the attribute's unit. - zero indicates implicit (by semconv) or non-defined unit. - """ - def __init__( - self, - *, - key_strindex: builtins.int = ..., - value: opentelemetry.proto.common.v1.common_pb2.AnyValue | None = ..., - unit_strindex: builtins.int = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["value", b"value"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["key_strindex", b"key_strindex", "unit_strindex", b"unit_strindex", "value", b"value"]) -> None: ... - -global___KeyValueAndUnit = KeyValueAndUnit diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py deleted file mode 100644 index f226d76ea50..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/resource/v1/resource.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.opentelemetry/proto/resource/v1/resource.proto\x12\x1fopentelemetry.proto.resource.v1\x1a*opentelemetry/proto/common/v1/common.proto\"\xa8\x01\n\x08Resource\x12;\n\nattributes\x18\x01 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x02 \x01(\r\x12=\n\x0b\x65ntity_refs\x18\x03 \x03(\x0b\x32(.opentelemetry.proto.common.v1.EntityRefB\x83\x01\n\"io.opentelemetry.proto.resource.v1B\rResourceProtoP\x01Z*go.opentelemetry.io/proto/otlp/resource/v1\xaa\x02\x1fOpenTelemetry.Proto.Resource.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.resource.v1.resource_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\"io.opentelemetry.proto.resource.v1B\rResourceProtoP\001Z*go.opentelemetry.io/proto/otlp/resource/v1\252\002\037OpenTelemetry.Proto.Resource.V1' - _globals['_RESOURCE']._serialized_start=128 - _globals['_RESOURCE']._serialized_end=296 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi deleted file mode 100644 index 61472c538e1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/resource/v1/resource_pb2.pyi +++ /dev/null @@ -1,70 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2019, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.message -import opentelemetry.proto.common.v1.common_pb2 -import sys - -if sys.version_info >= (3, 8): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -@typing_extensions.final -class Resource(google.protobuf.message.Message): - """Resource information.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - ATTRIBUTES_FIELD_NUMBER: builtins.int - DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int - ENTITY_REFS_FIELD_NUMBER: builtins.int - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """Set of attributes that describe the resource. - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - dropped_attributes_count: builtins.int - """The number of dropped attributes. If the value is 0, then - no attributes were dropped. - """ - @property - def entity_refs(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.EntityRef]: - """Set of entities that participate in this Resource. - - Note: keys in the references MUST exist in attributes of this message. - - Status: [Development] - """ - def __init__( - self, - *, - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - dropped_attributes_count: builtins.int = ..., - entity_refs: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.EntityRef] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "entity_refs", b"entity_refs"]) -> None: ... - -global___Resource = Resource diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py deleted file mode 100644 index 534b3a6a522..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: opentelemetry/proto/trace/v1/trace.proto -# Protobuf Python Version: 5.26.1 -"""Generated protocol buffer code.""" -from opentelemetry.agent._vendor.google.protobuf import descriptor as _descriptor -from opentelemetry.agent._vendor.google.protobuf import descriptor_pool as _descriptor_pool -from opentelemetry.agent._vendor.google.protobuf import symbol_database as _symbol_database -from opentelemetry.agent._vendor.google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from opentelemetry.agent._vendor.opentelemetry.proto.common.v1 import common_pb2 as opentelemetry_dot_proto_dot_common_dot_v1_dot_common__pb2 -from opentelemetry.agent._vendor.opentelemetry.proto.resource.v1 import resource_pb2 as opentelemetry_dot_proto_dot_resource_dot_v1_dot_resource__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(opentelemetry/proto/trace/v1/trace.proto\x12\x1copentelemetry.proto.trace.v1\x1a*opentelemetry/proto/common/v1/common.proto\x1a.opentelemetry/proto/resource/v1/resource.proto\"Q\n\nTracesData\x12\x43\n\x0eresource_spans\x18\x01 \x03(\x0b\x32+.opentelemetry.proto.trace.v1.ResourceSpans\"\xa7\x01\n\rResourceSpans\x12;\n\x08resource\x18\x01 \x01(\x0b\x32).opentelemetry.proto.resource.v1.Resource\x12=\n\x0bscope_spans\x18\x02 \x03(\x0b\x32(.opentelemetry.proto.trace.v1.ScopeSpans\x12\x12\n\nschema_url\x18\x03 \x01(\tJ\x06\x08\xe8\x07\x10\xe9\x07\"\x97\x01\n\nScopeSpans\x12\x42\n\x05scope\x18\x01 \x01(\x0b\x32\x33.opentelemetry.proto.common.v1.InstrumentationScope\x12\x31\n\x05spans\x18\x02 \x03(\x0b\x32\".opentelemetry.proto.trace.v1.Span\x12\x12\n\nschema_url\x18\x03 \x01(\t\"\x84\x08\n\x04Span\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\x12\x13\n\x0btrace_state\x18\x03 \x01(\t\x12\x16\n\x0eparent_span_id\x18\x04 \x01(\x0c\x12\r\n\x05\x66lags\x18\x10 \x01(\x07\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x39\n\x04kind\x18\x06 \x01(\x0e\x32+.opentelemetry.proto.trace.v1.Span.SpanKind\x12\x1c\n\x14start_time_unix_nano\x18\x07 \x01(\x06\x12\x1a\n\x12\x65nd_time_unix_nano\x18\x08 \x01(\x06\x12;\n\nattributes\x18\t \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\n \x01(\r\x12\x38\n\x06\x65vents\x18\x0b \x03(\x0b\x32(.opentelemetry.proto.trace.v1.Span.Event\x12\x1c\n\x14\x64ropped_events_count\x18\x0c \x01(\r\x12\x36\n\x05links\x18\r \x03(\x0b\x32\'.opentelemetry.proto.trace.v1.Span.Link\x12\x1b\n\x13\x64ropped_links_count\x18\x0e \x01(\r\x12\x34\n\x06status\x18\x0f \x01(\x0b\x32$.opentelemetry.proto.trace.v1.Status\x1a\x8c\x01\n\x05\x45vent\x12\x16\n\x0etime_unix_nano\x18\x01 \x01(\x06\x12\x0c\n\x04name\x18\x02 \x01(\t\x12;\n\nattributes\x18\x03 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x04 \x01(\r\x1a\xac\x01\n\x04Link\x12\x10\n\x08trace_id\x18\x01 \x01(\x0c\x12\x0f\n\x07span_id\x18\x02 \x01(\x0c\x12\x13\n\x0btrace_state\x18\x03 \x01(\t\x12;\n\nattributes\x18\x04 \x03(\x0b\x32\'.opentelemetry.proto.common.v1.KeyValue\x12 \n\x18\x64ropped_attributes_count\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\x07\"\x99\x01\n\x08SpanKind\x12\x19\n\x15SPAN_KIND_UNSPECIFIED\x10\x00\x12\x16\n\x12SPAN_KIND_INTERNAL\x10\x01\x12\x14\n\x10SPAN_KIND_SERVER\x10\x02\x12\x14\n\x10SPAN_KIND_CLIENT\x10\x03\x12\x16\n\x12SPAN_KIND_PRODUCER\x10\x04\x12\x16\n\x12SPAN_KIND_CONSUMER\x10\x05\"\xae\x01\n\x06Status\x12\x0f\n\x07message\x18\x02 \x01(\t\x12=\n\x04\x63ode\x18\x03 \x01(\x0e\x32/.opentelemetry.proto.trace.v1.Status.StatusCode\"N\n\nStatusCode\x12\x15\n\x11STATUS_CODE_UNSET\x10\x00\x12\x12\n\x0eSTATUS_CODE_OK\x10\x01\x12\x15\n\x11STATUS_CODE_ERROR\x10\x02J\x04\x08\x01\x10\x02*\x9c\x01\n\tSpanFlags\x12\x19\n\x15SPAN_FLAGS_DO_NOT_USE\x10\x00\x12 \n\x1bSPAN_FLAGS_TRACE_FLAGS_MASK\x10\xff\x01\x12*\n%SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK\x10\x80\x02\x12&\n!SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK\x10\x80\x04\x42w\n\x1fio.opentelemetry.proto.trace.v1B\nTraceProtoP\x01Z\'go.opentelemetry.io/proto/otlp/trace/v1\xaa\x02\x1cOpenTelemetry.Proto.Trace.V1b\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'opentelemetry.agent._vendor.opentelemetry.proto.trace.v1.trace_pb2', _globals) -if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'\n\037io.opentelemetry.proto.trace.v1B\nTraceProtoP\001Z\'go.opentelemetry.io/proto/otlp/trace/v1\252\002\034OpenTelemetry.Proto.Trace.V1' - _globals['_SPANFLAGS']._serialized_start=1782 - _globals['_SPANFLAGS']._serialized_end=1938 - _globals['_TRACESDATA']._serialized_start=166 - _globals['_TRACESDATA']._serialized_end=247 - _globals['_RESOURCESPANS']._serialized_start=250 - _globals['_RESOURCESPANS']._serialized_end=417 - _globals['_SCOPESPANS']._serialized_start=420 - _globals['_SCOPESPANS']._serialized_end=571 - _globals['_SPAN']._serialized_start=574 - _globals['_SPAN']._serialized_end=1602 - _globals['_SPAN_EVENT']._serialized_start=1131 - _globals['_SPAN_EVENT']._serialized_end=1271 - _globals['_SPAN_LINK']._serialized_start=1274 - _globals['_SPAN_LINK']._serialized_end=1446 - _globals['_SPAN_SPANKIND']._serialized_start=1449 - _globals['_SPAN_SPANKIND']._serialized_end=1602 - _globals['_STATUS']._serialized_start=1605 - _globals['_STATUS']._serialized_end=1779 - _globals['_STATUS_STATUSCODE']._serialized_start=1695 - _globals['_STATUS_STATUSCODE']._serialized_end=1773 -# @@protoc_insertion_point(module_scope) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi deleted file mode 100644 index e21336f03c6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/trace/v1/trace_pb2.pyi +++ /dev/null @@ -1,586 +0,0 @@ -""" -@generated by mypy-protobuf. Do not edit manually! -isort:skip_file -Copyright 2019, OpenTelemetry Authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import builtins -import collections.abc -import google.protobuf.descriptor -import google.protobuf.internal.containers -import google.protobuf.internal.enum_type_wrapper -import google.protobuf.message -import opentelemetry.proto.common.v1.common_pb2 -import opentelemetry.proto.resource.v1.resource_pb2 -import sys -import typing - -if sys.version_info >= (3, 10): - import typing as typing_extensions -else: - import typing_extensions - -DESCRIPTOR: google.protobuf.descriptor.FileDescriptor - -class _SpanFlags: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - -class _SpanFlagsEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_SpanFlags.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - SPAN_FLAGS_DO_NOT_USE: _SpanFlags.ValueType # 0 - """The zero value for the enum. Should not be used for comparisons. - Instead use bitwise "and" with the appropriate mask as shown above. - """ - SPAN_FLAGS_TRACE_FLAGS_MASK: _SpanFlags.ValueType # 255 - """Bits 0-7 are used for trace flags.""" - SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK: _SpanFlags.ValueType # 256 - """Bits 8 and 9 are used to indicate that the parent span or link span is remote. - Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known. - Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote. - """ - SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK: _SpanFlags.ValueType # 512 - -class SpanFlags(_SpanFlags, metaclass=_SpanFlagsEnumTypeWrapper): - """SpanFlags represents constants used to interpret the - Span.flags field, which is protobuf 'fixed32' type and is to - be used as bit-fields. Each non-zero value defined in this enum is - a bit-mask. To extract the bit-field, for example, use an - expression like: - - (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK) - - See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. - - Note that Span flags were introduced in version 1.1 of the - OpenTelemetry protocol. Older Span producers do not set this - field, consequently consumers should not rely on the absence of a - particular flag bit to indicate the presence of a particular feature. - """ - -SPAN_FLAGS_DO_NOT_USE: SpanFlags.ValueType # 0 -"""The zero value for the enum. Should not be used for comparisons. -Instead use bitwise "and" with the appropriate mask as shown above. -""" -SPAN_FLAGS_TRACE_FLAGS_MASK: SpanFlags.ValueType # 255 -"""Bits 0-7 are used for trace flags.""" -SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK: SpanFlags.ValueType # 256 -"""Bits 8 and 9 are used to indicate that the parent span or link span is remote. -Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known. -Bit 9 (`IS_REMOTE`) indicates whether the span or link is remote. -""" -SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK: SpanFlags.ValueType # 512 -global___SpanFlags = SpanFlags - -@typing_extensions.final -class TracesData(google.protobuf.message.Message): - """TracesData represents the traces data that can be stored in a persistent storage, - OR can be embedded by other protocols that transfer OTLP traces data but do - not implement the OTLP protocol. - - The main difference between this message and collector protocol is that - in this message there will not be any "control" or "metadata" specific to - OTLP protocol. - - When new fields are added into this message, the OTLP request MUST be updated - as well. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_SPANS_FIELD_NUMBER: builtins.int - @property - def resource_spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ResourceSpans]: - """An array of ResourceSpans. - For data coming from a single resource this array will typically contain - one element. Intermediary nodes that receive data from multiple origins - typically batch the data before forwarding further and in that case this - array will contain multiple elements. - """ - def __init__( - self, - *, - resource_spans: collections.abc.Iterable[global___ResourceSpans] | None = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["resource_spans", b"resource_spans"]) -> None: ... - -global___TracesData = TracesData - -@typing_extensions.final -class ResourceSpans(google.protobuf.message.Message): - """A collection of ScopeSpans from a Resource.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - RESOURCE_FIELD_NUMBER: builtins.int - SCOPE_SPANS_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def resource(self) -> opentelemetry.proto.resource.v1.resource_pb2.Resource: - """The resource for the spans in this message. - If this field is not set then no resource info is known. - """ - @property - def scope_spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ScopeSpans]: - """A list of ScopeSpans that originate from a resource.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the resource data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "resource" field. It does not apply - to the data in the "scope_spans" field which have their own schema_url field. - """ - def __init__( - self, - *, - resource: opentelemetry.proto.resource.v1.resource_pb2.Resource | None = ..., - scope_spans: collections.abc.Iterable[global___ScopeSpans] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["resource", b"resource"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["resource", b"resource", "schema_url", b"schema_url", "scope_spans", b"scope_spans"]) -> None: ... - -global___ResourceSpans = ResourceSpans - -@typing_extensions.final -class ScopeSpans(google.protobuf.message.Message): - """A collection of Spans produced by an InstrumentationScope.""" - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - SCOPE_FIELD_NUMBER: builtins.int - SPANS_FIELD_NUMBER: builtins.int - SCHEMA_URL_FIELD_NUMBER: builtins.int - @property - def scope(self) -> opentelemetry.proto.common.v1.common_pb2.InstrumentationScope: - """The instrumentation scope information for the spans in this message. - Semantically when InstrumentationScope isn't set, it is equivalent with - an empty instrumentation scope name (unknown). - """ - @property - def spans(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Span]: - """A list of Spans that originate from an instrumentation scope.""" - schema_url: builtins.str - """The Schema URL, if known. This is the identifier of the Schema that the span data - is recorded in. Notably, the last part of the URL path is the version number of the - schema: http[s]://server[:port]/path/. To learn more about Schema URL see - https://opentelemetry.io/docs/specs/otel/schemas/#schema-url - This schema_url applies to the data in the "scope" field and all spans and span - events in the "spans" field. - """ - def __init__( - self, - *, - scope: opentelemetry.proto.common.v1.common_pb2.InstrumentationScope | None = ..., - spans: collections.abc.Iterable[global___Span] | None = ..., - schema_url: builtins.str = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["scope", b"scope"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["schema_url", b"schema_url", "scope", b"scope", "spans", b"spans"]) -> None: ... - -global___ScopeSpans = ScopeSpans - -@typing_extensions.final -class Span(google.protobuf.message.Message): - """A Span represents a single operation performed by a single component of the system. - - The next available field id is 17. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _SpanKind: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _SpanKindEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Span._SpanKind.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - SPAN_KIND_UNSPECIFIED: Span._SpanKind.ValueType # 0 - """Unspecified. Do NOT use as default. - Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. - """ - SPAN_KIND_INTERNAL: Span._SpanKind.ValueType # 1 - """Indicates that the span represents an internal operation within an application, - as opposed to an operation happening at the boundaries. Default value. - """ - SPAN_KIND_SERVER: Span._SpanKind.ValueType # 2 - """Indicates that the span covers server-side handling of an RPC or other - remote network request. - """ - SPAN_KIND_CLIENT: Span._SpanKind.ValueType # 3 - """Indicates that the span describes a request to some remote service.""" - SPAN_KIND_PRODUCER: Span._SpanKind.ValueType # 4 - """Indicates that the span describes a producer sending a message to a broker. - Unlike CLIENT and SERVER, there is often no direct critical path latency relationship - between producer and consumer spans. A PRODUCER span ends when the message was accepted - by the broker while the logical processing of the message might span a much longer time. - """ - SPAN_KIND_CONSUMER: Span._SpanKind.ValueType # 5 - """Indicates that the span describes consumer receiving a message from a broker. - Like the PRODUCER kind, there is often no direct critical path latency relationship - between producer and consumer spans. - """ - - class SpanKind(_SpanKind, metaclass=_SpanKindEnumTypeWrapper): - """SpanKind is the type of span. Can be used to specify additional relationships between spans - in addition to a parent/child relationship. - """ - - SPAN_KIND_UNSPECIFIED: Span.SpanKind.ValueType # 0 - """Unspecified. Do NOT use as default. - Implementations MAY assume SpanKind to be INTERNAL when receiving UNSPECIFIED. - """ - SPAN_KIND_INTERNAL: Span.SpanKind.ValueType # 1 - """Indicates that the span represents an internal operation within an application, - as opposed to an operation happening at the boundaries. Default value. - """ - SPAN_KIND_SERVER: Span.SpanKind.ValueType # 2 - """Indicates that the span covers server-side handling of an RPC or other - remote network request. - """ - SPAN_KIND_CLIENT: Span.SpanKind.ValueType # 3 - """Indicates that the span describes a request to some remote service.""" - SPAN_KIND_PRODUCER: Span.SpanKind.ValueType # 4 - """Indicates that the span describes a producer sending a message to a broker. - Unlike CLIENT and SERVER, there is often no direct critical path latency relationship - between producer and consumer spans. A PRODUCER span ends when the message was accepted - by the broker while the logical processing of the message might span a much longer time. - """ - SPAN_KIND_CONSUMER: Span.SpanKind.ValueType # 5 - """Indicates that the span describes consumer receiving a message from a broker. - Like the PRODUCER kind, there is often no direct critical path latency relationship - between producer and consumer spans. - """ - - @typing_extensions.final - class Event(google.protobuf.message.Message): - """Event is a time-stamped annotation of the span, consisting of user-supplied - text description and key-value pairs. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - NAME_FIELD_NUMBER: builtins.int - ATTRIBUTES_FIELD_NUMBER: builtins.int - DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int - time_unix_nano: builtins.int - """The time the event occurred.""" - name: builtins.str - """The name of the event. - This field is semantically required to be set to non-empty string. - """ - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """A collection of attribute key/value pairs on the event. - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - dropped_attributes_count: builtins.int - """The number of dropped attributes. If the value is 0, - then no attributes were dropped. - """ - def __init__( - self, - *, - time_unix_nano: builtins.int = ..., - name: builtins.str = ..., - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - dropped_attributes_count: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "name", b"name", "time_unix_nano", b"time_unix_nano"]) -> None: ... - - @typing_extensions.final - class Link(google.protobuf.message.Message): - """A pointer from the current span to another span in the same trace or in a - different trace. For example, this can be used in batching operations, - where a single batch handler processes multiple requests from different - traces or when the handler receives a request from a different project. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - TRACE_ID_FIELD_NUMBER: builtins.int - SPAN_ID_FIELD_NUMBER: builtins.int - TRACE_STATE_FIELD_NUMBER: builtins.int - ATTRIBUTES_FIELD_NUMBER: builtins.int - DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int - FLAGS_FIELD_NUMBER: builtins.int - trace_id: builtins.bytes - """A unique identifier of a trace that this linked span is part of. The ID is a - 16-byte array. - """ - span_id: builtins.bytes - """A unique identifier for the linked span. The ID is an 8-byte array.""" - trace_state: builtins.str - """The trace_state associated with the link.""" - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """A collection of attribute key/value pairs on the link. - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - dropped_attributes_count: builtins.int - """The number of dropped attributes. If the value is 0, - then no attributes were dropped. - """ - flags: builtins.int - """Flags, a bit field. - - Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace - Context specification. To read the 8-bit W3C trace flag, use - `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. - - See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. - - Bits 8 and 9 represent the 3 states of whether the link is remote. - The states are (unknown, is not remote, is remote). - To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. - To read whether the link is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. - - Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. - When creating new spans, bits 10-31 (most-significant 22-bits) MUST be zero. - - [Optional]. - """ - def __init__( - self, - *, - trace_id: builtins.bytes = ..., - span_id: builtins.bytes = ..., - trace_state: builtins.str = ..., - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - dropped_attributes_count: builtins.int = ..., - flags: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "flags", b"flags", "span_id", b"span_id", "trace_id", b"trace_id", "trace_state", b"trace_state"]) -> None: ... - - TRACE_ID_FIELD_NUMBER: builtins.int - SPAN_ID_FIELD_NUMBER: builtins.int - TRACE_STATE_FIELD_NUMBER: builtins.int - PARENT_SPAN_ID_FIELD_NUMBER: builtins.int - FLAGS_FIELD_NUMBER: builtins.int - NAME_FIELD_NUMBER: builtins.int - KIND_FIELD_NUMBER: builtins.int - START_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - END_TIME_UNIX_NANO_FIELD_NUMBER: builtins.int - ATTRIBUTES_FIELD_NUMBER: builtins.int - DROPPED_ATTRIBUTES_COUNT_FIELD_NUMBER: builtins.int - EVENTS_FIELD_NUMBER: builtins.int - DROPPED_EVENTS_COUNT_FIELD_NUMBER: builtins.int - LINKS_FIELD_NUMBER: builtins.int - DROPPED_LINKS_COUNT_FIELD_NUMBER: builtins.int - STATUS_FIELD_NUMBER: builtins.int - trace_id: builtins.bytes - """A unique identifier for a trace. All spans from the same trace share - the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR - of length other than 16 bytes is considered invalid (empty string in OTLP/JSON - is zero-length and thus is also invalid). - - This field is required. - """ - span_id: builtins.bytes - """A unique identifier for a span within a trace, assigned when the span - is created. The ID is an 8-byte array. An ID with all zeroes OR of length - other than 8 bytes is considered invalid (empty string in OTLP/JSON - is zero-length and thus is also invalid). - - This field is required. - """ - trace_state: builtins.str - """trace_state conveys information about request position in multiple distributed tracing graphs. - It is a trace_state in w3c-trace-context format: https://www.w3.org/TR/trace-context/#tracestate-header - See also https://github.com/w3c/distributed-tracing for more details about this field. - """ - parent_span_id: builtins.bytes - """The `span_id` of this span's parent span. If this is a root span, then this - field must be empty. The ID is an 8-byte array. - """ - flags: builtins.int - """Flags, a bit field. - - Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C Trace - Context specification. To read the 8-bit W3C trace flag, use - `flags & SPAN_FLAGS_TRACE_FLAGS_MASK`. - - See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag definitions. - - Bits 8 and 9 represent the 3 states of whether a span's parent - is remote. The states are (unknown, is not remote, is remote). - To read whether the value is known, use `(flags & SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. - To read whether the span is remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. - - When creating span messages, if the message is logically forwarded from another source - with an equivalent flags fields (i.e., usually another OTLP span message), the field SHOULD - be copied as-is. If creating from a source that does not have an equivalent flags field - (such as a runtime representation of an OpenTelemetry span), the high 22 bits MUST - be set to zero. - Readers MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. - - [Optional]. - """ - name: builtins.str - """A description of the span's operation. - - For example, the name can be a qualified method name or a file name - and a line number where the operation is called. A best practice is to use - the same display name at the same call point in an application. - This makes it easier to correlate spans in different traces. - - This field is semantically required to be set to non-empty string. - Empty value is equivalent to an unknown span name. - - This field is required. - """ - kind: global___Span.SpanKind.ValueType - """Distinguishes between spans generated in a particular context. For example, - two spans with the same name may be distinguished using `CLIENT` (caller) - and `SERVER` (callee) to identify queueing latency associated with the span. - """ - start_time_unix_nano: builtins.int - """The start time of the span. On the client side, this is the time - kept by the local machine where the span execution starts. On the server side, this - is the time when the server's application handler starts running. - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - - This field is semantically required and it is expected that end_time >= start_time. - """ - end_time_unix_nano: builtins.int - """The end time of the span. On the client side, this is the time - kept by the local machine where the span execution ends. On the server side, this - is the time when the server application handler stops running. - Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. - - This field is semantically required and it is expected that end_time >= start_time. - """ - @property - def attributes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[opentelemetry.proto.common.v1.common_pb2.KeyValue]: - """A collection of key/value pairs. Note, global attributes - like server name can be set using the resource API. Examples of attributes: - - "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" - "/http/server_latency": 300 - "example.com/myattribute": true - "example.com/score": 10.239 - - Attribute keys MUST be unique (it is not allowed to have more than one - attribute with the same key). - The behavior of software that receives duplicated keys can be unpredictable. - """ - dropped_attributes_count: builtins.int - """The number of attributes that were discarded. Attributes - can be discarded because their keys are too long or because there are too many - attributes. If this value is 0, then no attributes were dropped. - """ - @property - def events(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Span.Event]: - """A collection of Event items.""" - dropped_events_count: builtins.int - """The number of dropped events. If the value is 0, then no - events were dropped. - """ - @property - def links(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Span.Link]: - """A collection of Links, which are references from this span to a span - in the same or different trace. - """ - dropped_links_count: builtins.int - """The number of dropped links after the maximum size was - enforced. If this value is 0, then no links were dropped. - """ - @property - def status(self) -> global___Status: - """An optional final status for this span. Semantically when Status isn't set, it means - span's status code is unset, i.e. assume STATUS_CODE_UNSET (code = 0). - """ - def __init__( - self, - *, - trace_id: builtins.bytes = ..., - span_id: builtins.bytes = ..., - trace_state: builtins.str = ..., - parent_span_id: builtins.bytes = ..., - flags: builtins.int = ..., - name: builtins.str = ..., - kind: global___Span.SpanKind.ValueType = ..., - start_time_unix_nano: builtins.int = ..., - end_time_unix_nano: builtins.int = ..., - attributes: collections.abc.Iterable[opentelemetry.proto.common.v1.common_pb2.KeyValue] | None = ..., - dropped_attributes_count: builtins.int = ..., - events: collections.abc.Iterable[global___Span.Event] | None = ..., - dropped_events_count: builtins.int = ..., - links: collections.abc.Iterable[global___Span.Link] | None = ..., - dropped_links_count: builtins.int = ..., - status: global___Status | None = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["status", b"status"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["attributes", b"attributes", "dropped_attributes_count", b"dropped_attributes_count", "dropped_events_count", b"dropped_events_count", "dropped_links_count", b"dropped_links_count", "end_time_unix_nano", b"end_time_unix_nano", "events", b"events", "flags", b"flags", "kind", b"kind", "links", b"links", "name", b"name", "parent_span_id", b"parent_span_id", "span_id", b"span_id", "start_time_unix_nano", b"start_time_unix_nano", "status", b"status", "trace_id", b"trace_id", "trace_state", b"trace_state"]) -> None: ... - -global___Span = Span - -@typing_extensions.final -class Status(google.protobuf.message.Message): - """The Status type defines a logical error model that is suitable for different - programming environments, including REST APIs and RPC APIs. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - class _StatusCode: - ValueType = typing.NewType("ValueType", builtins.int) - V: typing_extensions.TypeAlias = ValueType - - class _StatusCodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Status._StatusCode.ValueType], builtins.type): - DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor - STATUS_CODE_UNSET: Status._StatusCode.ValueType # 0 - """The default status.""" - STATUS_CODE_OK: Status._StatusCode.ValueType # 1 - """The Span has been validated by an Application developer or Operator to - have completed successfully. - """ - STATUS_CODE_ERROR: Status._StatusCode.ValueType # 2 - """The Span contains an error.""" - - class StatusCode(_StatusCode, metaclass=_StatusCodeEnumTypeWrapper): - """For the semantics of status codes see - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status - """ - - STATUS_CODE_UNSET: Status.StatusCode.ValueType # 0 - """The default status.""" - STATUS_CODE_OK: Status.StatusCode.ValueType # 1 - """The Span has been validated by an Application developer or Operator to - have completed successfully. - """ - STATUS_CODE_ERROR: Status.StatusCode.ValueType # 2 - """The Span contains an error.""" - - MESSAGE_FIELD_NUMBER: builtins.int - CODE_FIELD_NUMBER: builtins.int - message: builtins.str - """A developer-facing human readable error message.""" - code: global___Status.StatusCode.ValueType - """The status code.""" - def __init__( - self, - *, - message: builtins.str = ..., - code: global___Status.StatusCode.ValueType = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["code", b"code", "message", b"message"]) -> None: ... - -global___Status = Status diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py deleted file mode 100644 index 0101c361616..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py deleted file mode 100644 index af4ed5ad0cb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/_json_codec.py +++ /dev/null @@ -1,250 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import abc -import base64 -import collections.abc -import json -import math -import typing - -from opentelemetry.agent._vendor.typing_extensions import Self - -T = typing.TypeVar("T") -M = typing.TypeVar("M", bound="JsonMessage") - - -class JsonMessage(abc.ABC): - """ - Abstract base class for protobuf messages with JSON serialization. - """ - - @abc.abstractmethod - def to_dict(self) -> dict[str, typing.Any]: - """ - Convert this message to a dictionary. - """ - - @classmethod - @abc.abstractmethod - def from_dict(cls: type[M], data: dict[str, typing.Any]) -> M: - """ - Create an instance from a dictionary. - """ - - def to_json(self) -> str: - """ - Serialize this message to a JSON string. - """ - return json.dumps(self.to_dict()) - - @classmethod - def from_json(cls, data: str | bytes) -> Self: - """ - Deserialize from a JSON string or bytes. - """ - return cls.from_dict(json.loads(data)) - - -def encode_hex(value: bytes | None) -> str: - """ - Encode bytes as hex string. - - Args: - value: The bytes to encode. - Returns: - Hex string representation of the input bytes. - """ - return value.hex() if value else "" - - -def encode_base64(value: bytes | None) -> str: - """ - Encode bytes as base64 string. - Standard Proto3 JSON mapping for bytes. - - Args: - value: The bytes to encode. - Returns: - Base64 string representation of the input bytes. - """ - return base64.b64encode(value).decode("utf-8") if value else "" - - -def encode_int64(value: int) -> str: - """ - Encode 64 bit integers as strings. - Required for int64, uint64, fixed64, sfixed64 and sint64 per Proto3 JSON spec. - - Args: - value: The integer to encode. - Returns: - String representation of the input integer. - """ - return str(value) - - -def encode_float(value: float) -> float | str: - """ - Encode float/double values. - - Args: - value: The float to encode. - Returns: - The input value, or a string for special float values (NaN, Infinity). - """ - if math.isnan(value): - return "NaN" - if math.isinf(value): - return "Infinity" if value > 0 else "-Infinity" - return value - - -def encode_repeated( - values: list[T] | None, - map_fn: collections.abc.Callable[[T], typing.Any], -) -> list[typing.Any]: - """ - Helper to serialize repeated fields with a mapping function. - - Args: - values: The list of values to encode. - map_fn: A function that takes a single value and returns its encoded form. - Returns: - A list of encoded values, or an empty list if input is None or empty. - """ - return [map_fn(v) for v in values] if values else [] - - -def decode_hex(value: str | None, field_name: str) -> bytes: - """ - Decode hex string to bytes. - - Args: - value: The hex string to decode. - field_name: The name of the field being decoded (for error messages). - Returns: - The decoded bytes, or empty bytes if input is None or empty. - """ - if not value: - return b"" - validate_type(value, str, field_name) - try: - return bytes.fromhex(value) - except ValueError as error: - raise ValueError( - f"Invalid hex string for field '{field_name}': {error}" - ) from None - - -def decode_base64(value: str | None, field_name: str) -> bytes: - """ - Decode base64 string to bytes. - - Args: - value: The base64 string to decode. - field_name: The name of the field being decoded (for error messages). - Returns: - The decoded bytes, or empty bytes if input is None or empty. - """ - if not value: - return b"" - validate_type(value, str, field_name) - try: - return base64.b64decode(value) - except Exception as error: - raise ValueError( - f"Invalid base64 string for field '{field_name}': {error}" - ) from None - - -def decode_int64(value: int | str | None, field_name: str) -> int: - """ - Parse int64 from number or string. - - Args: - value: The value to decode, which can be an int, a string, or None - field_name: The name of the field being decoded (for error messages). - Returns: - The decoded integer, or 0 if input is None. - """ - if value is None: - return 0 - validate_type(value, (int, str), field_name) - try: - return int(value) - except (ValueError, TypeError): - raise ValueError( - f"Invalid int64 value for field '{field_name}': {value}" - ) from None - - -def decode_float(value: float | str | None, field_name: str) -> float: - """ - Parse float/double from number or string, handling special values. - - Args: - value: The value to decode, which can be a float, int, string, or None - field_name: The name of the field being decoded (for error messages). - Returns: - The decoded float, or 0.0 if input is None. - """ - if value is None: - return 0.0 - validate_type(value, (float, int, str), field_name) - if value == "NaN": - return math.nan - if value == "Infinity": - return math.inf - if value == "-Infinity": - return -math.inf - try: - return float(value) - except (ValueError, TypeError): - raise ValueError( - f"Invalid float value for field '{field_name}': {value}" - ) from None - - -def decode_repeated( - values: list[typing.Any] | None, - item_parser: collections.abc.Callable[[typing.Any], T], - field_name: str, -) -> list[T]: - """ - Parse a list of values using the provided item parser function. - - Args: - values: The list of values to decode, or None. - item_parser: A function that takes a single value and returns the parsed form. - field_name: The name of the field being decoded (for error messages). - Returns: - A list of parsed values, or an empty list if input is None. - """ - if values is None: - return [] - validate_type(values, list, field_name) - return [item_parser(v) for v in values] - - -def validate_type( - value: typing.Any, - expected_types: type | tuple[type, ...], - field_name: str, -) -> None: - """ - Validate that a value is of the expected type(s). - Raises TypeError if validation fails. - - Args: - value: The value to validate. - expected_types: A type or tuple of types that the value is expected to be. - field_name: The name of the field being validated (for error messages). - """ - if not isinstance(value, expected_types): - raise TypeError( - f"Field '{field_name}' expected {expected_types}, " - f"got {type(value).__name__}" - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py deleted file mode 100644 index 0c751b94871..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/logs/v1/logs_service.py +++ /dev/null @@ -1,148 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/collector/logs/v1/logs_service.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.logs.v1.logs -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -@_dataclass -class ExportLogsServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportLogsServiceRequest - """ - - resource_logs: builtins.list[opentelemetry.proto_json.logs.v1.logs.ResourceLogs] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_logs: - _result["resourceLogs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_logs, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportLogsServiceRequest: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportLogsServiceRequest instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceLogs")) is not None: - _args["resource_logs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.logs.v1.logs.ResourceLogs.from_dict(_v), "resource_logs") - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportLogsServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportLogsServiceResponse - """ - - partial_success: ExportLogsPartialSuccess | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.partial_success: - _result["partialSuccess"] = self.partial_success.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportLogsServiceResponse: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportLogsServiceResponse instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("partialSuccess")) is not None: - _args["partial_success"] = ExportLogsPartialSuccess.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportLogsPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportLogsPartialSuccess - """ - - rejected_log_records: builtins.int | None = 0 - error_message: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.rejected_log_records: - _result["rejectedLogRecords"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_log_records) - if self.error_message: - _result["errorMessage"] = self.error_message - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportLogsPartialSuccess: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportLogsPartialSuccess instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("rejectedLogRecords")) is not None: - _args["rejected_log_records"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_log_records") - if (_value := data.get("errorMessage")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") - _args["error_message"] = _value - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py deleted file mode 100644 index b77e752bc46..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/metrics/v1/metrics_service.py +++ /dev/null @@ -1,148 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/collector/metrics/v1/metrics_service.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.metrics.v1.metrics -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -@_dataclass -class ExportMetricsServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportMetricsServiceRequest - """ - - resource_metrics: builtins.list[opentelemetry.proto_json.metrics.v1.metrics.ResourceMetrics] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_metrics: - _result["resourceMetrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_metrics, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportMetricsServiceRequest: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportMetricsServiceRequest instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceMetrics")) is not None: - _args["resource_metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.metrics.v1.metrics.ResourceMetrics.from_dict(_v), "resource_metrics") - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportMetricsServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportMetricsServiceResponse - """ - - partial_success: ExportMetricsPartialSuccess | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.partial_success: - _result["partialSuccess"] = self.partial_success.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportMetricsServiceResponse: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportMetricsServiceResponse instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("partialSuccess")) is not None: - _args["partial_success"] = ExportMetricsPartialSuccess.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportMetricsPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportMetricsPartialSuccess - """ - - rejected_data_points: builtins.int | None = 0 - error_message: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.rejected_data_points: - _result["rejectedDataPoints"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_data_points) - if self.error_message: - _result["errorMessage"] = self.error_message - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportMetricsPartialSuccess: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportMetricsPartialSuccess instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("rejectedDataPoints")) is not None: - _args["rejected_data_points"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_data_points") - if (_value := data.get("errorMessage")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") - _args["error_message"] = _value - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py deleted file mode 100644 index 80e88874693..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/profiles/v1development/profiles_service.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/collector/profiles/v1development/profiles_service.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.profiles.v1development.profiles -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -@_dataclass -class ExportProfilesServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportProfilesServiceRequest - """ - - resource_profiles: builtins.list[opentelemetry.proto_json.profiles.v1development.profiles.ResourceProfiles] = dataclasses.field(default_factory=builtins.list) - dictionary: opentelemetry.proto_json.profiles.v1development.profiles.ProfilesDictionary | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_profiles: - _result["resourceProfiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_profiles, lambda _v: _v.to_dict()) - if self.dictionary: - _result["dictionary"] = self.dictionary.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportProfilesServiceRequest: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportProfilesServiceRequest instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceProfiles")) is not None: - _args["resource_profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.profiles.v1development.profiles.ResourceProfiles.from_dict(_v), "resource_profiles") - if (_value := data.get("dictionary")) is not None: - _args["dictionary"] = opentelemetry.proto_json.profiles.v1development.profiles.ProfilesDictionary.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportProfilesServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportProfilesServiceResponse - """ - - partial_success: ExportProfilesPartialSuccess | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.partial_success: - _result["partialSuccess"] = self.partial_success.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportProfilesServiceResponse: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportProfilesServiceResponse instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("partialSuccess")) is not None: - _args["partial_success"] = ExportProfilesPartialSuccess.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportProfilesPartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportProfilesPartialSuccess - """ - - rejected_profiles: builtins.int | None = 0 - error_message: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.rejected_profiles: - _result["rejectedProfiles"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_profiles) - if self.error_message: - _result["errorMessage"] = self.error_message - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportProfilesPartialSuccess: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportProfilesPartialSuccess instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("rejectedProfiles")) is not None: - _args["rejected_profiles"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_profiles") - if (_value := data.get("errorMessage")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") - _args["error_message"] = _value - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py deleted file mode 100644 index 7043becb62a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/collector/trace/v1/trace_service.py +++ /dev/null @@ -1,148 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/collector/trace/v1/trace_service.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.trace.v1.trace -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -@_dataclass -class ExportTraceServiceRequest(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportTraceServiceRequest - """ - - resource_spans: builtins.list[opentelemetry.proto_json.trace.v1.trace.ResourceSpans] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_spans: - _result["resourceSpans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_spans, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportTraceServiceRequest: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportTraceServiceRequest instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceSpans")) is not None: - _args["resource_spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.trace.v1.trace.ResourceSpans.from_dict(_v), "resource_spans") - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportTraceServiceResponse(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportTraceServiceResponse - """ - - partial_success: ExportTracePartialSuccess | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.partial_success: - _result["partialSuccess"] = self.partial_success.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportTraceServiceResponse: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportTraceServiceResponse instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("partialSuccess")) is not None: - _args["partial_success"] = ExportTracePartialSuccess.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class ExportTracePartialSuccess(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExportTracePartialSuccess - """ - - rejected_spans: builtins.int | None = 0 - error_message: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.rejected_spans: - _result["rejectedSpans"] = opentelemetry.proto_json._json_codec.encode_int64(self.rejected_spans) - if self.error_message: - _result["errorMessage"] = self.error_message - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExportTracePartialSuccess: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExportTracePartialSuccess instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("rejectedSpans")) is not None: - _args["rejected_spans"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "rejected_spans") - if (_value := data.get("errorMessage")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "error_message") - _args["error_message"] = _value - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py deleted file mode 100644 index 0dce42472c4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/common/v1/common.py +++ /dev/null @@ -1,348 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/common/v1/common.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -@_dataclass -class AnyValue(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message AnyValue - """ - - string_value: builtins.str | None = None - bool_value: builtins.bool | None = None - int_value: builtins.int | None = None - double_value: builtins.float | None = None - array_value: ArrayValue | None = None - kvlist_value: KeyValueList | None = None - bytes_value: builtins.bytes | None = None - string_value_strindex: builtins.int | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.string_value_strindex is not None: - _result["stringValueStrindex"] = self.string_value_strindex - elif self.bytes_value is not None: - _result["bytesValue"] = opentelemetry.proto_json._json_codec.encode_base64(self.bytes_value) - elif self.kvlist_value is not None: - _result["kvlistValue"] = self.kvlist_value.to_dict() - elif self.array_value is not None: - _result["arrayValue"] = self.array_value.to_dict() - elif self.double_value is not None: - _result["doubleValue"] = opentelemetry.proto_json._json_codec.encode_float(self.double_value) - elif self.int_value is not None: - _result["intValue"] = opentelemetry.proto_json._json_codec.encode_int64(self.int_value) - elif self.bool_value is not None: - _result["boolValue"] = self.bool_value - elif self.string_value is not None: - _result["stringValue"] = self.string_value - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> AnyValue: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - AnyValue instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("stringValueStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "string_value_strindex") - _args["string_value_strindex"] = _value - elif (_value := data.get("bytesValue")) is not None: - _args["bytes_value"] = opentelemetry.proto_json._json_codec.decode_base64(_value, "bytes_value") - elif (_value := data.get("kvlistValue")) is not None: - _args["kvlist_value"] = KeyValueList.from_dict(_value) - elif (_value := data.get("arrayValue")) is not None: - _args["array_value"] = ArrayValue.from_dict(_value) - elif (_value := data.get("doubleValue")) is not None: - _args["double_value"] = opentelemetry.proto_json._json_codec.decode_float(_value, "double_value") - elif (_value := data.get("intValue")) is not None: - _args["int_value"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "int_value") - elif (_value := data.get("boolValue")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.bool, "bool_value") - _args["bool_value"] = _value - elif (_value := data.get("stringValue")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "string_value") - _args["string_value"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class ArrayValue(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ArrayValue - """ - - values: builtins.list[AnyValue] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.values: - _result["values"] = opentelemetry.proto_json._json_codec.encode_repeated(self.values, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ArrayValue: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ArrayValue instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("values")) is not None: - _args["values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: AnyValue.from_dict(_v), "values") - - return cls(**_args) - - -@typing.final -@_dataclass -class KeyValueList(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message KeyValueList - """ - - values: builtins.list[KeyValue] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.values: - _result["values"] = opentelemetry.proto_json._json_codec.encode_repeated(self.values, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> KeyValueList: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - KeyValueList instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("values")) is not None: - _args["values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: KeyValue.from_dict(_v), "values") - - return cls(**_args) - - -@typing.final -@_dataclass -class KeyValue(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message KeyValue - """ - - key: builtins.str | None = "" - value: AnyValue | None = None - key_strindex: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.key: - _result["key"] = self.key - if self.value: - _result["value"] = self.value.to_dict() - if self.key_strindex: - _result["keyStrindex"] = self.key_strindex - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> KeyValue: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - KeyValue instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("key")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "key") - _args["key"] = _value - if (_value := data.get("value")) is not None: - _args["value"] = AnyValue.from_dict(_value) - if (_value := data.get("keyStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "key_strindex") - _args["key_strindex"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class InstrumentationScope(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message InstrumentationScope - """ - - name: builtins.str | None = "" - version: builtins.str | None = "" - attributes: builtins.list[KeyValue] = dataclasses.field(default_factory=builtins.list) - dropped_attributes_count: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.name: - _result["name"] = self.name - if self.version: - _result["version"] = self.version - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.dropped_attributes_count: - _result["droppedAttributesCount"] = self.dropped_attributes_count - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> InstrumentationScope: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - InstrumentationScope instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("name")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") - _args["name"] = _value - if (_value := data.get("version")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "version") - _args["version"] = _value - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: KeyValue.from_dict(_v), "attributes") - if (_value := data.get("droppedAttributesCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") - _args["dropped_attributes_count"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class EntityRef(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message EntityRef - """ - - schema_url: builtins.str | None = "" - type: builtins.str | None = "" - id_keys: builtins.list[builtins.str] = dataclasses.field(default_factory=builtins.list) - description_keys: builtins.list[builtins.str] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.schema_url: - _result["schemaUrl"] = self.schema_url - if self.type: - _result["type"] = self.type - if self.id_keys: - _result["idKeys"] = self.id_keys - if self.description_keys: - _result["descriptionKeys"] = self.description_keys - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> EntityRef: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - EntityRef instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - if (_value := data.get("type")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "type") - _args["type"] = _value - if (_value := data.get("idKeys")) is not None: - _args["id_keys"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "id_keys") - if (_value := data.get("descriptionKeys")) is not None: - _args["description_keys"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "description_keys") - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py deleted file mode 100644 index cd874620a2b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/logs/v1/logs.py +++ /dev/null @@ -1,304 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/logs/v1/logs.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import enum -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -class SeverityNumber(enum.IntEnum): - """ - Generated from protobuf enum SeverityNumber - """ - - SEVERITY_NUMBER_UNSPECIFIED = 0 - SEVERITY_NUMBER_TRACE = 1 - SEVERITY_NUMBER_TRACE2 = 2 - SEVERITY_NUMBER_TRACE3 = 3 - SEVERITY_NUMBER_TRACE4 = 4 - SEVERITY_NUMBER_DEBUG = 5 - SEVERITY_NUMBER_DEBUG2 = 6 - SEVERITY_NUMBER_DEBUG3 = 7 - SEVERITY_NUMBER_DEBUG4 = 8 - SEVERITY_NUMBER_INFO = 9 - SEVERITY_NUMBER_INFO2 = 10 - SEVERITY_NUMBER_INFO3 = 11 - SEVERITY_NUMBER_INFO4 = 12 - SEVERITY_NUMBER_WARN = 13 - SEVERITY_NUMBER_WARN2 = 14 - SEVERITY_NUMBER_WARN3 = 15 - SEVERITY_NUMBER_WARN4 = 16 - SEVERITY_NUMBER_ERROR = 17 - SEVERITY_NUMBER_ERROR2 = 18 - SEVERITY_NUMBER_ERROR3 = 19 - SEVERITY_NUMBER_ERROR4 = 20 - SEVERITY_NUMBER_FATAL = 21 - SEVERITY_NUMBER_FATAL2 = 22 - SEVERITY_NUMBER_FATAL3 = 23 - SEVERITY_NUMBER_FATAL4 = 24 - -@typing.final -class LogRecordFlags(enum.IntEnum): - """ - Generated from protobuf enum LogRecordFlags - """ - - LOG_RECORD_FLAGS_DO_NOT_USE = 0 - LOG_RECORD_FLAGS_TRACE_FLAGS_MASK = 255 - -@typing.final -@_dataclass -class LogsData(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message LogsData - """ - - resource_logs: builtins.list[ResourceLogs] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_logs: - _result["resourceLogs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_logs, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> LogsData: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - LogsData instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceLogs")) is not None: - _args["resource_logs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceLogs.from_dict(_v), "resource_logs") - - return cls(**_args) - - -@typing.final -@_dataclass -class ResourceLogs(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ResourceLogs - """ - - resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None - scope_logs: builtins.list[ScopeLogs] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource: - _result["resource"] = self.resource.to_dict() - if self.scope_logs: - _result["scopeLogs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_logs, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceLogs: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ResourceLogs instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resource")) is not None: - _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) - if (_value := data.get("scopeLogs")) is not None: - _args["scope_logs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeLogs.from_dict(_v), "scope_logs") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class ScopeLogs(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ScopeLogs - """ - - scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None - log_records: builtins.list[LogRecord] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.scope: - _result["scope"] = self.scope.to_dict() - if self.log_records: - _result["logRecords"] = opentelemetry.proto_json._json_codec.encode_repeated(self.log_records, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeLogs: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ScopeLogs instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("scope")) is not None: - _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) - if (_value := data.get("logRecords")) is not None: - _args["log_records"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: LogRecord.from_dict(_v), "log_records") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class LogRecord(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message LogRecord - """ - - time_unix_nano: builtins.int | None = 0 - observed_time_unix_nano: builtins.int | None = 0 - severity_number: SeverityNumber | builtins.int | None = 0 - severity_text: builtins.str | None = "" - body: opentelemetry.proto_json.common.v1.common.AnyValue | None = None - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - dropped_attributes_count: builtins.int | None = 0 - flags: builtins.int | None = 0 - trace_id: builtins.bytes | None = b"" - span_id: builtins.bytes | None = b"" - event_name: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.observed_time_unix_nano: - _result["observedTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.observed_time_unix_nano) - if self.severity_number: - _result["severityNumber"] = builtins.int(self.severity_number) - if self.severity_text: - _result["severityText"] = self.severity_text - if self.body: - _result["body"] = self.body.to_dict() - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.dropped_attributes_count: - _result["droppedAttributesCount"] = self.dropped_attributes_count - if self.flags: - _result["flags"] = self.flags - if self.trace_id: - _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) - if self.span_id: - _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) - if self.event_name: - _result["eventName"] = self.event_name - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> LogRecord: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - LogRecord instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("observedTimeUnixNano")) is not None: - _args["observed_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "observed_time_unix_nano") - if (_value := data.get("severityNumber")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "severity_number") - _args["severity_number"] = SeverityNumber(_value) - if (_value := data.get("severityText")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "severity_text") - _args["severity_text"] = _value - if (_value := data.get("body")) is not None: - _args["body"] = opentelemetry.proto_json.common.v1.common.AnyValue.from_dict(_value) - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("droppedAttributesCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") - _args["dropped_attributes_count"] = _value - if (_value := data.get("flags")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") - _args["flags"] = _value - if (_value := data.get("traceId")) is not None: - _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") - if (_value := data.get("spanId")) is not None: - _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") - if (_value := data.get("eventName")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "event_name") - _args["event_name"] = _value - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py deleted file mode 100644 index 741794ceccb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/metrics/v1/metrics.py +++ /dev/null @@ -1,1000 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/metrics/v1/metrics.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import enum -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -class AggregationTemporality(enum.IntEnum): - """ - Generated from protobuf enum AggregationTemporality - """ - - AGGREGATION_TEMPORALITY_UNSPECIFIED = 0 - AGGREGATION_TEMPORALITY_DELTA = 1 - AGGREGATION_TEMPORALITY_CUMULATIVE = 2 - -@typing.final -class DataPointFlags(enum.IntEnum): - """ - Generated from protobuf enum DataPointFlags - """ - - DATA_POINT_FLAGS_DO_NOT_USE = 0 - DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK = 1 - -@typing.final -@_dataclass -class MetricsData(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message MetricsData - """ - - resource_metrics: builtins.list[ResourceMetrics] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_metrics: - _result["resourceMetrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_metrics, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> MetricsData: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - MetricsData instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceMetrics")) is not None: - _args["resource_metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceMetrics.from_dict(_v), "resource_metrics") - - return cls(**_args) - - -@typing.final -@_dataclass -class ResourceMetrics(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ResourceMetrics - """ - - resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None - scope_metrics: builtins.list[ScopeMetrics] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource: - _result["resource"] = self.resource.to_dict() - if self.scope_metrics: - _result["scopeMetrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_metrics, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceMetrics: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ResourceMetrics instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resource")) is not None: - _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) - if (_value := data.get("scopeMetrics")) is not None: - _args["scope_metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeMetrics.from_dict(_v), "scope_metrics") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class ScopeMetrics(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ScopeMetrics - """ - - scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None - metrics: builtins.list[Metric] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.scope: - _result["scope"] = self.scope.to_dict() - if self.metrics: - _result["metrics"] = opentelemetry.proto_json._json_codec.encode_repeated(self.metrics, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeMetrics: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ScopeMetrics instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("scope")) is not None: - _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) - if (_value := data.get("metrics")) is not None: - _args["metrics"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Metric.from_dict(_v), "metrics") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class Metric(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Metric - """ - - name: builtins.str | None = "" - description: builtins.str | None = "" - unit: builtins.str | None = "" - gauge: Gauge | None = None - sum: Sum | None = None - histogram: Histogram | None = None - exponential_histogram: ExponentialHistogram | None = None - summary: Summary | None = None - metadata: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.name: - _result["name"] = self.name - if self.description: - _result["description"] = self.description - if self.unit: - _result["unit"] = self.unit - if self.metadata: - _result["metadata"] = opentelemetry.proto_json._json_codec.encode_repeated(self.metadata, lambda _v: _v.to_dict()) - if self.summary is not None: - _result["summary"] = self.summary.to_dict() - elif self.exponential_histogram is not None: - _result["exponentialHistogram"] = self.exponential_histogram.to_dict() - elif self.histogram is not None: - _result["histogram"] = self.histogram.to_dict() - elif self.sum is not None: - _result["sum"] = self.sum.to_dict() - elif self.gauge is not None: - _result["gauge"] = self.gauge.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Metric: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Metric instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("name")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") - _args["name"] = _value - if (_value := data.get("description")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "description") - _args["description"] = _value - if (_value := data.get("unit")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "unit") - _args["unit"] = _value - if (_value := data.get("metadata")) is not None: - _args["metadata"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "metadata") - if (_value := data.get("summary")) is not None: - _args["summary"] = Summary.from_dict(_value) - elif (_value := data.get("exponentialHistogram")) is not None: - _args["exponential_histogram"] = ExponentialHistogram.from_dict(_value) - elif (_value := data.get("histogram")) is not None: - _args["histogram"] = Histogram.from_dict(_value) - elif (_value := data.get("sum")) is not None: - _args["sum"] = Sum.from_dict(_value) - elif (_value := data.get("gauge")) is not None: - _args["gauge"] = Gauge.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class Gauge(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Gauge - """ - - data_points: builtins.list[NumberDataPoint] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.data_points: - _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Gauge: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Gauge instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("dataPoints")) is not None: - _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: NumberDataPoint.from_dict(_v), "data_points") - - return cls(**_args) - - -@typing.final -@_dataclass -class Sum(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Sum - """ - - data_points: builtins.list[NumberDataPoint] = dataclasses.field(default_factory=builtins.list) - aggregation_temporality: AggregationTemporality | builtins.int | None = 0 - is_monotonic: builtins.bool | None = False - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.data_points: - _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) - if self.aggregation_temporality: - _result["aggregationTemporality"] = builtins.int(self.aggregation_temporality) - if self.is_monotonic: - _result["isMonotonic"] = self.is_monotonic - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Sum: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Sum instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("dataPoints")) is not None: - _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: NumberDataPoint.from_dict(_v), "data_points") - if (_value := data.get("aggregationTemporality")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") - _args["aggregation_temporality"] = AggregationTemporality(_value) - if (_value := data.get("isMonotonic")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.bool, "is_monotonic") - _args["is_monotonic"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class Histogram(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Histogram - """ - - data_points: builtins.list[HistogramDataPoint] = dataclasses.field(default_factory=builtins.list) - aggregation_temporality: AggregationTemporality | builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.data_points: - _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) - if self.aggregation_temporality: - _result["aggregationTemporality"] = builtins.int(self.aggregation_temporality) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Histogram: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Histogram instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("dataPoints")) is not None: - _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: HistogramDataPoint.from_dict(_v), "data_points") - if (_value := data.get("aggregationTemporality")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") - _args["aggregation_temporality"] = AggregationTemporality(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class ExponentialHistogram(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExponentialHistogram - """ - - data_points: builtins.list[ExponentialHistogramDataPoint] = dataclasses.field(default_factory=builtins.list) - aggregation_temporality: AggregationTemporality | builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.data_points: - _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) - if self.aggregation_temporality: - _result["aggregationTemporality"] = builtins.int(self.aggregation_temporality) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExponentialHistogram: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExponentialHistogram instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("dataPoints")) is not None: - _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ExponentialHistogramDataPoint.from_dict(_v), "data_points") - if (_value := data.get("aggregationTemporality")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "aggregation_temporality") - _args["aggregation_temporality"] = AggregationTemporality(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class Summary(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Summary - """ - - data_points: builtins.list[SummaryDataPoint] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.data_points: - _result["dataPoints"] = opentelemetry.proto_json._json_codec.encode_repeated(self.data_points, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Summary: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Summary instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("dataPoints")) is not None: - _args["data_points"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: SummaryDataPoint.from_dict(_v), "data_points") - - return cls(**_args) - - -@typing.final -@_dataclass -class NumberDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message NumberDataPoint - """ - - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - start_time_unix_nano: builtins.int | None = 0 - time_unix_nano: builtins.int | None = 0 - as_double: builtins.float | None = None - as_int: builtins.int | None = None - exemplars: builtins.list[Exemplar] = dataclasses.field(default_factory=builtins.list) - flags: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.start_time_unix_nano: - _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.exemplars: - _result["exemplars"] = opentelemetry.proto_json._json_codec.encode_repeated(self.exemplars, lambda _v: _v.to_dict()) - if self.flags: - _result["flags"] = self.flags - if self.as_int is not None: - _result["asInt"] = opentelemetry.proto_json._json_codec.encode_int64(self.as_int) - elif self.as_double is not None: - _result["asDouble"] = opentelemetry.proto_json._json_codec.encode_float(self.as_double) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> NumberDataPoint: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - NumberDataPoint instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("startTimeUnixNano")) is not None: - _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("exemplars")) is not None: - _args["exemplars"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Exemplar.from_dict(_v), "exemplars") - if (_value := data.get("flags")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") - _args["flags"] = _value - if (_value := data.get("asInt")) is not None: - _args["as_int"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "as_int") - elif (_value := data.get("asDouble")) is not None: - _args["as_double"] = opentelemetry.proto_json._json_codec.decode_float(_value, "as_double") - - return cls(**_args) - - -@typing.final -@_dataclass -class HistogramDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message HistogramDataPoint - """ - - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - start_time_unix_nano: builtins.int | None = 0 - time_unix_nano: builtins.int | None = 0 - count: builtins.int | None = 0 - sum: builtins.float | None = None - bucket_counts: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - explicit_bounds: builtins.list[builtins.float] = dataclasses.field(default_factory=builtins.list) - exemplars: builtins.list[Exemplar] = dataclasses.field(default_factory=builtins.list) - flags: builtins.int | None = 0 - min: builtins.float | None = None - max: builtins.float | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.start_time_unix_nano: - _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.count: - _result["count"] = opentelemetry.proto_json._json_codec.encode_int64(self.count) - if self.sum is not None: - _result["sum"] = opentelemetry.proto_json._json_codec.encode_float(self.sum) - if self.bucket_counts: - _result["bucketCounts"] = opentelemetry.proto_json._json_codec.encode_repeated(self.bucket_counts, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) - if self.explicit_bounds: - _result["explicitBounds"] = opentelemetry.proto_json._json_codec.encode_repeated(self.explicit_bounds, lambda _v: opentelemetry.proto_json._json_codec.encode_float(_v)) - if self.exemplars: - _result["exemplars"] = opentelemetry.proto_json._json_codec.encode_repeated(self.exemplars, lambda _v: _v.to_dict()) - if self.flags: - _result["flags"] = self.flags - if self.min is not None: - _result["min"] = opentelemetry.proto_json._json_codec.encode_float(self.min) - if self.max is not None: - _result["max"] = opentelemetry.proto_json._json_codec.encode_float(self.max) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> HistogramDataPoint: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - HistogramDataPoint instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("startTimeUnixNano")) is not None: - _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("count")) is not None: - _args["count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "count") - if (_value := data.get("sum")) is not None: - _args["sum"] = opentelemetry.proto_json._json_codec.decode_float(_value, "sum") - if (_value := data.get("bucketCounts")) is not None: - _args["bucket_counts"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "bucket_counts"), "bucket_counts") - if (_value := data.get("explicitBounds")) is not None: - _args["explicit_bounds"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_float(_v, "explicit_bounds"), "explicit_bounds") - if (_value := data.get("exemplars")) is not None: - _args["exemplars"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Exemplar.from_dict(_v), "exemplars") - if (_value := data.get("flags")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") - _args["flags"] = _value - if (_value := data.get("min")) is not None: - _args["min"] = opentelemetry.proto_json._json_codec.decode_float(_value, "min") - if (_value := data.get("max")) is not None: - _args["max"] = opentelemetry.proto_json._json_codec.decode_float(_value, "max") - - return cls(**_args) - - -@typing.final -@_dataclass -class ExponentialHistogramDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ExponentialHistogramDataPoint - """ - - @typing.final - @_dataclass - class Buckets(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Buckets - """ - - offset: builtins.int | None = 0 - bucket_counts: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.offset: - _result["offset"] = self.offset - if self.bucket_counts: - _result["bucketCounts"] = opentelemetry.proto_json._json_codec.encode_repeated(self.bucket_counts, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExponentialHistogramDataPoint.Buckets: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Buckets instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("offset")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "offset") - _args["offset"] = _value - if (_value := data.get("bucketCounts")) is not None: - _args["bucket_counts"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "bucket_counts"), "bucket_counts") - - return cls(**_args) - - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - start_time_unix_nano: builtins.int | None = 0 - time_unix_nano: builtins.int | None = 0 - count: builtins.int | None = 0 - sum: builtins.float | None = None - scale: builtins.int | None = 0 - zero_count: builtins.int | None = 0 - positive: ExponentialHistogramDataPoint.Buckets | None = None - negative: ExponentialHistogramDataPoint.Buckets | None = None - flags: builtins.int | None = 0 - exemplars: builtins.list[Exemplar] = dataclasses.field(default_factory=builtins.list) - min: builtins.float | None = None - max: builtins.float | None = None - zero_threshold: builtins.float | None = 0.0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.start_time_unix_nano: - _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.count: - _result["count"] = opentelemetry.proto_json._json_codec.encode_int64(self.count) - if self.sum is not None: - _result["sum"] = opentelemetry.proto_json._json_codec.encode_float(self.sum) - if self.scale: - _result["scale"] = self.scale - if self.zero_count: - _result["zeroCount"] = opentelemetry.proto_json._json_codec.encode_int64(self.zero_count) - if self.positive: - _result["positive"] = self.positive.to_dict() - if self.negative: - _result["negative"] = self.negative.to_dict() - if self.flags: - _result["flags"] = self.flags - if self.exemplars: - _result["exemplars"] = opentelemetry.proto_json._json_codec.encode_repeated(self.exemplars, lambda _v: _v.to_dict()) - if self.min is not None: - _result["min"] = opentelemetry.proto_json._json_codec.encode_float(self.min) - if self.max is not None: - _result["max"] = opentelemetry.proto_json._json_codec.encode_float(self.max) - if self.zero_threshold: - _result["zeroThreshold"] = opentelemetry.proto_json._json_codec.encode_float(self.zero_threshold) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ExponentialHistogramDataPoint: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ExponentialHistogramDataPoint instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("startTimeUnixNano")) is not None: - _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("count")) is not None: - _args["count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "count") - if (_value := data.get("sum")) is not None: - _args["sum"] = opentelemetry.proto_json._json_codec.decode_float(_value, "sum") - if (_value := data.get("scale")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "scale") - _args["scale"] = _value - if (_value := data.get("zeroCount")) is not None: - _args["zero_count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "zero_count") - if (_value := data.get("positive")) is not None: - _args["positive"] = ExponentialHistogramDataPoint.Buckets.from_dict(_value) - if (_value := data.get("negative")) is not None: - _args["negative"] = ExponentialHistogramDataPoint.Buckets.from_dict(_value) - if (_value := data.get("flags")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") - _args["flags"] = _value - if (_value := data.get("exemplars")) is not None: - _args["exemplars"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Exemplar.from_dict(_v), "exemplars") - if (_value := data.get("min")) is not None: - _args["min"] = opentelemetry.proto_json._json_codec.decode_float(_value, "min") - if (_value := data.get("max")) is not None: - _args["max"] = opentelemetry.proto_json._json_codec.decode_float(_value, "max") - if (_value := data.get("zeroThreshold")) is not None: - _args["zero_threshold"] = opentelemetry.proto_json._json_codec.decode_float(_value, "zero_threshold") - - return cls(**_args) - - -@typing.final -@_dataclass -class SummaryDataPoint(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message SummaryDataPoint - """ - - @typing.final - @_dataclass - class ValueAtQuantile(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ValueAtQuantile - """ - - quantile: builtins.float | None = 0.0 - value: builtins.float | None = 0.0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.quantile: - _result["quantile"] = opentelemetry.proto_json._json_codec.encode_float(self.quantile) - if self.value: - _result["value"] = opentelemetry.proto_json._json_codec.encode_float(self.value) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> SummaryDataPoint.ValueAtQuantile: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ValueAtQuantile instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("quantile")) is not None: - _args["quantile"] = opentelemetry.proto_json._json_codec.decode_float(_value, "quantile") - if (_value := data.get("value")) is not None: - _args["value"] = opentelemetry.proto_json._json_codec.decode_float(_value, "value") - - return cls(**_args) - - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - start_time_unix_nano: builtins.int | None = 0 - time_unix_nano: builtins.int | None = 0 - count: builtins.int | None = 0 - sum: builtins.float | None = 0.0 - quantile_values: builtins.list[SummaryDataPoint.ValueAtQuantile] = dataclasses.field(default_factory=builtins.list) - flags: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.start_time_unix_nano: - _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.count: - _result["count"] = opentelemetry.proto_json._json_codec.encode_int64(self.count) - if self.sum: - _result["sum"] = opentelemetry.proto_json._json_codec.encode_float(self.sum) - if self.quantile_values: - _result["quantileValues"] = opentelemetry.proto_json._json_codec.encode_repeated(self.quantile_values, lambda _v: _v.to_dict()) - if self.flags: - _result["flags"] = self.flags - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> SummaryDataPoint: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - SummaryDataPoint instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("startTimeUnixNano")) is not None: - _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("count")) is not None: - _args["count"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "count") - if (_value := data.get("sum")) is not None: - _args["sum"] = opentelemetry.proto_json._json_codec.decode_float(_value, "sum") - if (_value := data.get("quantileValues")) is not None: - _args["quantile_values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: SummaryDataPoint.ValueAtQuantile.from_dict(_v), "quantile_values") - if (_value := data.get("flags")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") - _args["flags"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class Exemplar(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Exemplar - """ - - filtered_attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - time_unix_nano: builtins.int | None = 0 - as_double: builtins.float | None = None - as_int: builtins.int | None = None - span_id: builtins.bytes | None = b"" - trace_id: builtins.bytes | None = b"" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.filtered_attributes: - _result["filteredAttributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.filtered_attributes, lambda _v: _v.to_dict()) - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.span_id: - _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) - if self.trace_id: - _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) - if self.as_int is not None: - _result["asInt"] = opentelemetry.proto_json._json_codec.encode_int64(self.as_int) - elif self.as_double is not None: - _result["asDouble"] = opentelemetry.proto_json._json_codec.encode_float(self.as_double) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Exemplar: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Exemplar instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("filteredAttributes")) is not None: - _args["filtered_attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "filtered_attributes") - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("spanId")) is not None: - _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") - if (_value := data.get("traceId")) is not None: - _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") - if (_value := data.get("asInt")) is not None: - _args["as_int"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "as_int") - elif (_value := data.get("asDouble")) is not None: - _args["as_double"] = opentelemetry.proto_json._json_codec.decode_float(_value, "as_double") - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py deleted file mode 100644 index cf5e4f1a7bb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/profiles/v1development/profiles.py +++ /dev/null @@ -1,816 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/profiles/v1development/profiles.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -@_dataclass -class ProfilesDictionary(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ProfilesDictionary - """ - - mapping_table: builtins.list[Mapping] = dataclasses.field(default_factory=builtins.list) - location_table: builtins.list[Location] = dataclasses.field(default_factory=builtins.list) - function_table: builtins.list[Function] = dataclasses.field(default_factory=builtins.list) - link_table: builtins.list[Link] = dataclasses.field(default_factory=builtins.list) - string_table: builtins.list[builtins.str] = dataclasses.field(default_factory=builtins.list) - attribute_table: builtins.list[KeyValueAndUnit] = dataclasses.field(default_factory=builtins.list) - stack_table: builtins.list[Stack] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.mapping_table: - _result["mappingTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.mapping_table, lambda _v: _v.to_dict()) - if self.location_table: - _result["locationTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.location_table, lambda _v: _v.to_dict()) - if self.function_table: - _result["functionTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.function_table, lambda _v: _v.to_dict()) - if self.link_table: - _result["linkTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.link_table, lambda _v: _v.to_dict()) - if self.string_table: - _result["stringTable"] = self.string_table - if self.attribute_table: - _result["attributeTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attribute_table, lambda _v: _v.to_dict()) - if self.stack_table: - _result["stackTable"] = opentelemetry.proto_json._json_codec.encode_repeated(self.stack_table, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ProfilesDictionary: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ProfilesDictionary instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("mappingTable")) is not None: - _args["mapping_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Mapping.from_dict(_v), "mapping_table") - if (_value := data.get("locationTable")) is not None: - _args["location_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Location.from_dict(_v), "location_table") - if (_value := data.get("functionTable")) is not None: - _args["function_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Function.from_dict(_v), "function_table") - if (_value := data.get("linkTable")) is not None: - _args["link_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Link.from_dict(_v), "link_table") - if (_value := data.get("stringTable")) is not None: - _args["string_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "string_table") - if (_value := data.get("attributeTable")) is not None: - _args["attribute_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: KeyValueAndUnit.from_dict(_v), "attribute_table") - if (_value := data.get("stackTable")) is not None: - _args["stack_table"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Stack.from_dict(_v), "stack_table") - - return cls(**_args) - - -@typing.final -@_dataclass -class ProfilesData(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ProfilesData - """ - - resource_profiles: builtins.list[ResourceProfiles] = dataclasses.field(default_factory=builtins.list) - dictionary: ProfilesDictionary | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_profiles: - _result["resourceProfiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_profiles, lambda _v: _v.to_dict()) - if self.dictionary: - _result["dictionary"] = self.dictionary.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ProfilesData: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ProfilesData instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceProfiles")) is not None: - _args["resource_profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceProfiles.from_dict(_v), "resource_profiles") - if (_value := data.get("dictionary")) is not None: - _args["dictionary"] = ProfilesDictionary.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class ResourceProfiles(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ResourceProfiles - """ - - resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None - scope_profiles: builtins.list[ScopeProfiles] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource: - _result["resource"] = self.resource.to_dict() - if self.scope_profiles: - _result["scopeProfiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_profiles, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceProfiles: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ResourceProfiles instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resource")) is not None: - _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) - if (_value := data.get("scopeProfiles")) is not None: - _args["scope_profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeProfiles.from_dict(_v), "scope_profiles") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class ScopeProfiles(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ScopeProfiles - """ - - scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None - profiles: builtins.list[Profile] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.scope: - _result["scope"] = self.scope.to_dict() - if self.profiles: - _result["profiles"] = opentelemetry.proto_json._json_codec.encode_repeated(self.profiles, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeProfiles: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ScopeProfiles instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("scope")) is not None: - _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) - if (_value := data.get("profiles")) is not None: - _args["profiles"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Profile.from_dict(_v), "profiles") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class Profile(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Profile - """ - - sample_type: ValueType | None = None - samples: builtins.list[Sample] = dataclasses.field(default_factory=builtins.list) - time_unix_nano: builtins.int | None = 0 - duration_nano: builtins.int | None = 0 - period_type: ValueType | None = None - period: builtins.int | None = 0 - profile_id: builtins.bytes | None = b"" - dropped_attributes_count: builtins.int | None = 0 - original_payload_format: builtins.str | None = "" - original_payload: builtins.bytes | None = b"" - attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.sample_type: - _result["sampleType"] = self.sample_type.to_dict() - if self.samples: - _result["samples"] = opentelemetry.proto_json._json_codec.encode_repeated(self.samples, lambda _v: _v.to_dict()) - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.duration_nano: - _result["durationNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.duration_nano) - if self.period_type: - _result["periodType"] = self.period_type.to_dict() - if self.period: - _result["period"] = opentelemetry.proto_json._json_codec.encode_int64(self.period) - if self.profile_id: - _result["profileId"] = opentelemetry.proto_json._json_codec.encode_base64(self.profile_id) - if self.dropped_attributes_count: - _result["droppedAttributesCount"] = self.dropped_attributes_count - if self.original_payload_format: - _result["originalPayloadFormat"] = self.original_payload_format - if self.original_payload: - _result["originalPayload"] = opentelemetry.proto_json._json_codec.encode_base64(self.original_payload) - if self.attribute_indices: - _result["attributeIndices"] = self.attribute_indices - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Profile: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Profile instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("sampleType")) is not None: - _args["sample_type"] = ValueType.from_dict(_value) - if (_value := data.get("samples")) is not None: - _args["samples"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Sample.from_dict(_v), "samples") - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("durationNano")) is not None: - _args["duration_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "duration_nano") - if (_value := data.get("periodType")) is not None: - _args["period_type"] = ValueType.from_dict(_value) - if (_value := data.get("period")) is not None: - _args["period"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "period") - if (_value := data.get("profileId")) is not None: - _args["profile_id"] = opentelemetry.proto_json._json_codec.decode_base64(_value, "profile_id") - if (_value := data.get("droppedAttributesCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") - _args["dropped_attributes_count"] = _value - if (_value := data.get("originalPayloadFormat")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "original_payload_format") - _args["original_payload_format"] = _value - if (_value := data.get("originalPayload")) is not None: - _args["original_payload"] = opentelemetry.proto_json._json_codec.decode_base64(_value, "original_payload") - if (_value := data.get("attributeIndices")) is not None: - _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") - - return cls(**_args) - - -@typing.final -@_dataclass -class Link(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Link - """ - - trace_id: builtins.bytes | None = b"" - span_id: builtins.bytes | None = b"" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.trace_id: - _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) - if self.span_id: - _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Link: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Link instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("traceId")) is not None: - _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") - if (_value := data.get("spanId")) is not None: - _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") - - return cls(**_args) - - -@typing.final -@_dataclass -class ValueType(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ValueType - """ - - type_strindex: builtins.int | None = 0 - unit_strindex: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.type_strindex: - _result["typeStrindex"] = self.type_strindex - if self.unit_strindex: - _result["unitStrindex"] = self.unit_strindex - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ValueType: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ValueType instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("typeStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "type_strindex") - _args["type_strindex"] = _value - if (_value := data.get("unitStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "unit_strindex") - _args["unit_strindex"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class Sample(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Sample - """ - - stack_index: builtins.int | None = 0 - attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - link_index: builtins.int | None = 0 - values: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - timestamps_unix_nano: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.stack_index: - _result["stackIndex"] = self.stack_index - if self.attribute_indices: - _result["attributeIndices"] = self.attribute_indices - if self.link_index: - _result["linkIndex"] = self.link_index - if self.values: - _result["values"] = opentelemetry.proto_json._json_codec.encode_repeated(self.values, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) - if self.timestamps_unix_nano: - _result["timestampsUnixNano"] = opentelemetry.proto_json._json_codec.encode_repeated(self.timestamps_unix_nano, lambda _v: opentelemetry.proto_json._json_codec.encode_int64(_v)) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Sample: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Sample instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("stackIndex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "stack_index") - _args["stack_index"] = _value - if (_value := data.get("attributeIndices")) is not None: - _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") - if (_value := data.get("linkIndex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "link_index") - _args["link_index"] = _value - if (_value := data.get("values")) is not None: - _args["values"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "values"), "values") - if (_value := data.get("timestampsUnixNano")) is not None: - _args["timestamps_unix_nano"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json._json_codec.decode_int64(_v, "timestamps_unix_nano"), "timestamps_unix_nano") - - return cls(**_args) - - -@typing.final -@_dataclass -class Mapping(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Mapping - """ - - memory_start: builtins.int | None = 0 - memory_limit: builtins.int | None = 0 - file_offset: builtins.int | None = 0 - filename_strindex: builtins.int | None = 0 - attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.memory_start: - _result["memoryStart"] = opentelemetry.proto_json._json_codec.encode_int64(self.memory_start) - if self.memory_limit: - _result["memoryLimit"] = opentelemetry.proto_json._json_codec.encode_int64(self.memory_limit) - if self.file_offset: - _result["fileOffset"] = opentelemetry.proto_json._json_codec.encode_int64(self.file_offset) - if self.filename_strindex: - _result["filenameStrindex"] = self.filename_strindex - if self.attribute_indices: - _result["attributeIndices"] = self.attribute_indices - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Mapping: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Mapping instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("memoryStart")) is not None: - _args["memory_start"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "memory_start") - if (_value := data.get("memoryLimit")) is not None: - _args["memory_limit"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "memory_limit") - if (_value := data.get("fileOffset")) is not None: - _args["file_offset"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "file_offset") - if (_value := data.get("filenameStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "filename_strindex") - _args["filename_strindex"] = _value - if (_value := data.get("attributeIndices")) is not None: - _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") - - return cls(**_args) - - -@typing.final -@_dataclass -class Stack(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Stack - """ - - location_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.location_indices: - _result["locationIndices"] = self.location_indices - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Stack: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Stack instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("locationIndices")) is not None: - _args["location_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "location_indices") - - return cls(**_args) - - -@typing.final -@_dataclass -class Location(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Location - """ - - mapping_index: builtins.int | None = 0 - address: builtins.int | None = 0 - lines: builtins.list[Line] = dataclasses.field(default_factory=builtins.list) - attribute_indices: builtins.list[builtins.int] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.mapping_index: - _result["mappingIndex"] = self.mapping_index - if self.address: - _result["address"] = opentelemetry.proto_json._json_codec.encode_int64(self.address) - if self.lines: - _result["lines"] = opentelemetry.proto_json._json_codec.encode_repeated(self.lines, lambda _v: _v.to_dict()) - if self.attribute_indices: - _result["attributeIndices"] = self.attribute_indices - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Location: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Location instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("mappingIndex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "mapping_index") - _args["mapping_index"] = _value - if (_value := data.get("address")) is not None: - _args["address"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "address") - if (_value := data.get("lines")) is not None: - _args["lines"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Line.from_dict(_v), "lines") - if (_value := data.get("attributeIndices")) is not None: - _args["attribute_indices"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: _v, "attribute_indices") - - return cls(**_args) - - -@typing.final -@_dataclass -class Line(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Line - """ - - function_index: builtins.int | None = 0 - line: builtins.int | None = 0 - column: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.function_index: - _result["functionIndex"] = self.function_index - if self.line: - _result["line"] = opentelemetry.proto_json._json_codec.encode_int64(self.line) - if self.column: - _result["column"] = opentelemetry.proto_json._json_codec.encode_int64(self.column) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Line: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Line instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("functionIndex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "function_index") - _args["function_index"] = _value - if (_value := data.get("line")) is not None: - _args["line"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "line") - if (_value := data.get("column")) is not None: - _args["column"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "column") - - return cls(**_args) - - -@typing.final -@_dataclass -class Function(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Function - """ - - name_strindex: builtins.int | None = 0 - system_name_strindex: builtins.int | None = 0 - filename_strindex: builtins.int | None = 0 - start_line: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.name_strindex: - _result["nameStrindex"] = self.name_strindex - if self.system_name_strindex: - _result["systemNameStrindex"] = self.system_name_strindex - if self.filename_strindex: - _result["filenameStrindex"] = self.filename_strindex - if self.start_line: - _result["startLine"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_line) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Function: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Function instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("nameStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "name_strindex") - _args["name_strindex"] = _value - if (_value := data.get("systemNameStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "system_name_strindex") - _args["system_name_strindex"] = _value - if (_value := data.get("filenameStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "filename_strindex") - _args["filename_strindex"] = _value - if (_value := data.get("startLine")) is not None: - _args["start_line"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_line") - - return cls(**_args) - - -@typing.final -@_dataclass -class KeyValueAndUnit(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message KeyValueAndUnit - """ - - key_strindex: builtins.int | None = 0 - value: opentelemetry.proto_json.common.v1.common.AnyValue | None = None - unit_strindex: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.key_strindex: - _result["keyStrindex"] = self.key_strindex - if self.value: - _result["value"] = self.value.to_dict() - if self.unit_strindex: - _result["unitStrindex"] = self.unit_strindex - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> KeyValueAndUnit: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - KeyValueAndUnit instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("keyStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "key_strindex") - _args["key_strindex"] = _value - if (_value := data.get("value")) is not None: - _args["value"] = opentelemetry.proto_json.common.v1.common.AnyValue.from_dict(_value) - if (_value := data.get("unitStrindex")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "unit_strindex") - _args["unit_strindex"] = _value - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py deleted file mode 100644 index 247d5169a22..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/resource/v1/resource.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/resource/v1/resource.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -@_dataclass -class Resource(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Resource - """ - - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - dropped_attributes_count: builtins.int | None = 0 - entity_refs: builtins.list[opentelemetry.proto_json.common.v1.common.EntityRef] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.dropped_attributes_count: - _result["droppedAttributesCount"] = self.dropped_attributes_count - if self.entity_refs: - _result["entityRefs"] = opentelemetry.proto_json._json_codec.encode_repeated(self.entity_refs, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Resource: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Resource instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("droppedAttributesCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") - _args["dropped_attributes_count"] = _value - if (_value := data.get("entityRefs")) is not None: - _args["entity_refs"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.EntityRef.from_dict(_v), "entity_refs") - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py deleted file mode 100644 index 18ca440aef2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/trace/v1/trace.py +++ /dev/null @@ -1,497 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# AUTO-GENERATED from "opentelemetry/proto/trace/v1/trace.proto" -# DO NOT EDIT MANUALLY - -from __future__ import annotations - -import builtins -import dataclasses -import enum -import functools -import typing - -_dataclass = functools.partial(dataclasses.dataclass, slots=True) - -import opentelemetry.agent._vendor.opentelemetry.proto_json._json_codec -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.common.v1.common -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.proto_json.resource.v1.resource -from opentelemetry.agent._vendor import opentelemetry - - -@typing.final -class SpanFlags(enum.IntEnum): - """ - Generated from protobuf enum SpanFlags - """ - - SPAN_FLAGS_DO_NOT_USE = 0 - SPAN_FLAGS_TRACE_FLAGS_MASK = 255 - SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK = 256 - SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = 512 - -@typing.final -@_dataclass -class TracesData(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message TracesData - """ - - resource_spans: builtins.list[ResourceSpans] = dataclasses.field(default_factory=builtins.list) - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource_spans: - _result["resourceSpans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.resource_spans, lambda _v: _v.to_dict()) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> TracesData: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - TracesData instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resourceSpans")) is not None: - _args["resource_spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ResourceSpans.from_dict(_v), "resource_spans") - - return cls(**_args) - - -@typing.final -@_dataclass -class ResourceSpans(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ResourceSpans - """ - - resource: opentelemetry.proto_json.resource.v1.resource.Resource | None = None - scope_spans: builtins.list[ScopeSpans] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.resource: - _result["resource"] = self.resource.to_dict() - if self.scope_spans: - _result["scopeSpans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.scope_spans, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ResourceSpans: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ResourceSpans instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("resource")) is not None: - _args["resource"] = opentelemetry.proto_json.resource.v1.resource.Resource.from_dict(_value) - if (_value := data.get("scopeSpans")) is not None: - _args["scope_spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: ScopeSpans.from_dict(_v), "scope_spans") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class ScopeSpans(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message ScopeSpans - """ - - scope: opentelemetry.proto_json.common.v1.common.InstrumentationScope | None = None - spans: builtins.list[Span] = dataclasses.field(default_factory=builtins.list) - schema_url: builtins.str | None = "" - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.scope: - _result["scope"] = self.scope.to_dict() - if self.spans: - _result["spans"] = opentelemetry.proto_json._json_codec.encode_repeated(self.spans, lambda _v: _v.to_dict()) - if self.schema_url: - _result["schemaUrl"] = self.schema_url - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> ScopeSpans: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - ScopeSpans instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("scope")) is not None: - _args["scope"] = opentelemetry.proto_json.common.v1.common.InstrumentationScope.from_dict(_value) - if (_value := data.get("spans")) is not None: - _args["spans"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Span.from_dict(_v), "spans") - if (_value := data.get("schemaUrl")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "schema_url") - _args["schema_url"] = _value - - return cls(**_args) - - -@typing.final -@_dataclass -class Span(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Span - """ - - @typing.final - class SpanKind(enum.IntEnum): - """ - Generated from protobuf enum SpanKind - """ - - SPAN_KIND_UNSPECIFIED = 0 - SPAN_KIND_INTERNAL = 1 - SPAN_KIND_SERVER = 2 - SPAN_KIND_CLIENT = 3 - SPAN_KIND_PRODUCER = 4 - SPAN_KIND_CONSUMER = 5 - - @typing.final - @_dataclass - class Event(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Event - """ - - time_unix_nano: builtins.int | None = 0 - name: builtins.str | None = "" - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - dropped_attributes_count: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.time_unix_nano: - _result["timeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.time_unix_nano) - if self.name: - _result["name"] = self.name - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.dropped_attributes_count: - _result["droppedAttributesCount"] = self.dropped_attributes_count - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Span.Event: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Event instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("timeUnixNano")) is not None: - _args["time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "time_unix_nano") - if (_value := data.get("name")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") - _args["name"] = _value - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("droppedAttributesCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") - _args["dropped_attributes_count"] = _value - - return cls(**_args) - - @typing.final - @_dataclass - class Link(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Link - """ - - trace_id: builtins.bytes | None = b"" - span_id: builtins.bytes | None = b"" - trace_state: builtins.str | None = "" - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - dropped_attributes_count: builtins.int | None = 0 - flags: builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.trace_id: - _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) - if self.span_id: - _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) - if self.trace_state: - _result["traceState"] = self.trace_state - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.dropped_attributes_count: - _result["droppedAttributesCount"] = self.dropped_attributes_count - if self.flags: - _result["flags"] = self.flags - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Span.Link: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Link instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("traceId")) is not None: - _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") - if (_value := data.get("spanId")) is not None: - _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") - if (_value := data.get("traceState")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "trace_state") - _args["trace_state"] = _value - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("droppedAttributesCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") - _args["dropped_attributes_count"] = _value - if (_value := data.get("flags")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") - _args["flags"] = _value - - return cls(**_args) - - trace_id: builtins.bytes | None = b"" - span_id: builtins.bytes | None = b"" - trace_state: builtins.str | None = "" - parent_span_id: builtins.bytes | None = b"" - flags: builtins.int | None = 0 - name: builtins.str | None = "" - kind: Span.SpanKind | builtins.int | None = 0 - start_time_unix_nano: builtins.int | None = 0 - end_time_unix_nano: builtins.int | None = 0 - attributes: builtins.list[opentelemetry.proto_json.common.v1.common.KeyValue] = dataclasses.field(default_factory=builtins.list) - dropped_attributes_count: builtins.int | None = 0 - events: builtins.list[Span.Event] = dataclasses.field(default_factory=builtins.list) - dropped_events_count: builtins.int | None = 0 - links: builtins.list[Span.Link] = dataclasses.field(default_factory=builtins.list) - dropped_links_count: builtins.int | None = 0 - status: Status | None = None - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.trace_id: - _result["traceId"] = opentelemetry.proto_json._json_codec.encode_hex(self.trace_id) - if self.span_id: - _result["spanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.span_id) - if self.trace_state: - _result["traceState"] = self.trace_state - if self.parent_span_id: - _result["parentSpanId"] = opentelemetry.proto_json._json_codec.encode_hex(self.parent_span_id) - if self.flags: - _result["flags"] = self.flags - if self.name: - _result["name"] = self.name - if self.kind: - _result["kind"] = builtins.int(self.kind) - if self.start_time_unix_nano: - _result["startTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.start_time_unix_nano) - if self.end_time_unix_nano: - _result["endTimeUnixNano"] = opentelemetry.proto_json._json_codec.encode_int64(self.end_time_unix_nano) - if self.attributes: - _result["attributes"] = opentelemetry.proto_json._json_codec.encode_repeated(self.attributes, lambda _v: _v.to_dict()) - if self.dropped_attributes_count: - _result["droppedAttributesCount"] = self.dropped_attributes_count - if self.events: - _result["events"] = opentelemetry.proto_json._json_codec.encode_repeated(self.events, lambda _v: _v.to_dict()) - if self.dropped_events_count: - _result["droppedEventsCount"] = self.dropped_events_count - if self.links: - _result["links"] = opentelemetry.proto_json._json_codec.encode_repeated(self.links, lambda _v: _v.to_dict()) - if self.dropped_links_count: - _result["droppedLinksCount"] = self.dropped_links_count - if self.status: - _result["status"] = self.status.to_dict() - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Span: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Span instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("traceId")) is not None: - _args["trace_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "trace_id") - if (_value := data.get("spanId")) is not None: - _args["span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "span_id") - if (_value := data.get("traceState")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "trace_state") - _args["trace_state"] = _value - if (_value := data.get("parentSpanId")) is not None: - _args["parent_span_id"] = opentelemetry.proto_json._json_codec.decode_hex(_value, "parent_span_id") - if (_value := data.get("flags")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "flags") - _args["flags"] = _value - if (_value := data.get("name")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "name") - _args["name"] = _value - if (_value := data.get("kind")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "kind") - _args["kind"] = Span.SpanKind(_value) - if (_value := data.get("startTimeUnixNano")) is not None: - _args["start_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "start_time_unix_nano") - if (_value := data.get("endTimeUnixNano")) is not None: - _args["end_time_unix_nano"] = opentelemetry.proto_json._json_codec.decode_int64(_value, "end_time_unix_nano") - if (_value := data.get("attributes")) is not None: - _args["attributes"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: opentelemetry.proto_json.common.v1.common.KeyValue.from_dict(_v), "attributes") - if (_value := data.get("droppedAttributesCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_attributes_count") - _args["dropped_attributes_count"] = _value - if (_value := data.get("events")) is not None: - _args["events"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Span.Event.from_dict(_v), "events") - if (_value := data.get("droppedEventsCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_events_count") - _args["dropped_events_count"] = _value - if (_value := data.get("links")) is not None: - _args["links"] = opentelemetry.proto_json._json_codec.decode_repeated(_value, lambda _v: Span.Link.from_dict(_v), "links") - if (_value := data.get("droppedLinksCount")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "dropped_links_count") - _args["dropped_links_count"] = _value - if (_value := data.get("status")) is not None: - _args["status"] = Status.from_dict(_value) - - return cls(**_args) - - -@typing.final -@_dataclass -class Status(opentelemetry.proto_json._json_codec.JsonMessage): - """ - Generated from protobuf message Status - """ - - @typing.final - class StatusCode(enum.IntEnum): - """ - Generated from protobuf enum StatusCode - """ - - STATUS_CODE_UNSET = 0 - STATUS_CODE_OK = 1 - STATUS_CODE_ERROR = 2 - - message: builtins.str | None = "" - code: Status.StatusCode | builtins.int | None = 0 - - def to_dict(self) -> builtins.dict[builtins.str, typing.Any]: - """ - Convert this message to a dictionary with lowerCamelCase keys. - - Returns: - Dictionary representation following OTLP JSON encoding - """ - _result = {} - if self.message: - _result["message"] = self.message - if self.code: - _result["code"] = builtins.int(self.code) - return _result - - @builtins.classmethod - def from_dict(cls, data: builtins.dict[builtins.str, typing.Any]) -> Status: - """ - Create from a dictionary with lowerCamelCase keys. - - Args: - data: Dictionary representation following OTLP JSON encoding - - Returns: - Status instance - """ - opentelemetry.proto_json._json_codec.validate_type(data, builtins.dict, "data") - _args = {} - - if (_value := data.get("message")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.str, "message") - _args["message"] = _value - if (_value := data.get("code")) is not None: - opentelemetry.proto_json._json_codec.validate_type(_value, builtins.int, "code") - _args["code"] = Status.StatusCode(_value) - - return cls(**_args) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/proto_json/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi deleted file mode 100644 index e57edc0f58b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/__init__.pyi +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -The OpenTelemetry SDK package is an implementation of the OpenTelemetry -API -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py deleted file mode 100644 index 160f4c1666c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_configuration/__init__.py +++ /dev/null @@ -1,676 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -# - -""" -OpenTelemetry SDK Configurator for Easy Instrumentation with Distros -""" - -from __future__ import annotations - -import logging -import logging.config -import os -import warnings -from abc import ABC, abstractmethod -from collections.abc import Callable, Mapping, Sequence -from os import environ -from typing import Any, Literal, Protocol - -from opentelemetry.agent._vendor.opentelemetry._logs import set_logger_provider -from opentelemetry.agent._vendor.opentelemetry.environment_variables import ( - OTEL_LOGS_EXPORTER, - OTEL_METRICS_EXPORTER, - OTEL_PYTHON_ID_GENERATOR, - OTEL_TRACES_EXPORTER, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import set_meter_provider -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ( - LoggerProvider, - LoggingHandler, - LogRecordProcessor, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal import _LoggerConfiguratorT -from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( - BatchLogRecordProcessor, - LogRecordExporter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - _OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, - OTEL_CONFIG_FILE, - OTEL_EXPORTER_OTLP_LOGS_PROTOCOL, - OTEL_EXPORTER_OTLP_METRICS_PROTOCOL, - OTEL_EXPORTER_OTLP_PROTOCOL, - OTEL_EXPORTER_OTLP_TRACES_PROTOCOL, - OTEL_PYTHON_LOGGER_CONFIGURATOR, - OTEL_PYTHON_METER_CONFIGURATOR, - OTEL_PYTHON_TRACER_CONFIGURATOR, - OTEL_TRACES_SAMPLER, - OTEL_TRACES_SAMPLER_ARG, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import MeterProvider -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import _MeterConfiguratorT -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics.export import ( - MetricExporter, - MetricReader, - PeriodicExportingMetricReader, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Attributes, Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ( - SpanProcessor, - TracerProvider, - _TracerConfiguratorT, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import BatchSpanProcessor, SpanExporter -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator import IdGenerator -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import Sampler -from opentelemetry.agent._vendor.opentelemetry.semconv.resource import ResourceAttributes -from opentelemetry.agent._vendor.opentelemetry.trace import set_tracer_provider -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points - -_EXPORTER_OTLP = "otlp" -_EXPORTER_OTLP_PROTO_GRPC = "otlp_proto_grpc" -_EXPORTER_OTLP_PROTO_HTTP = "otlp_proto_http" - -_EXPORTER_BY_OTLP_PROTOCOL = { - "grpc": _EXPORTER_OTLP_PROTO_GRPC, - "http/protobuf": _EXPORTER_OTLP_PROTO_HTTP, -} - -_EXPORTER_ENV_BY_SIGNAL_TYPE = { - "traces": OTEL_TRACES_EXPORTER, - "metrics": OTEL_METRICS_EXPORTER, - "logs": OTEL_LOGS_EXPORTER, -} - -_PROTOCOL_ENV_BY_SIGNAL_TYPE = { - "traces": OTEL_EXPORTER_OTLP_TRACES_PROTOCOL, - "metrics": OTEL_EXPORTER_OTLP_METRICS_PROTOCOL, - "logs": OTEL_EXPORTER_OTLP_LOGS_PROTOCOL, -} - -_RANDOM_ID_GENERATOR = "random" -_DEFAULT_ID_GENERATOR = _RANDOM_ID_GENERATOR - -_OTEL_SAMPLER_ENTRY_POINT_GROUP = "opentelemetry_traces_sampler" - -_logger = logging.getLogger(__name__) - -ExporterArgsMap = Mapping[ - type[SpanExporter] | type[MetricExporter] | type[MetricReader] | type[LogRecordExporter], - Mapping[str, Any], -] - - -class _ConfigurationExporterSpanProcessorT(Protocol): - def __call__(self, span_exporter: SpanExporter, *args, **kwargs) -> SpanProcessor: ... - - -class _ConfigurationExporterLogRecordProcessorT(Protocol): - def __call__(self, exporter: LogRecordExporter, *args, **kwargs) -> LogRecordProcessor: ... - - -def _import_config_components(selected_components: Sequence[str], entry_point_name: str) -> list[tuple[str, type]]: - component_implementations = [] - - for selected_component in selected_components: - try: - component_implementations.append( - ( - selected_component, - next(iter(entry_points(group=entry_point_name, name=selected_component))).load(), - ) - ) - except KeyError: - raise RuntimeError(f"Requested entry point '{entry_point_name}' not found") - - except StopIteration: - raise RuntimeError( - f"Requested component '{selected_component}' not found in entry point '{entry_point_name}'" - ) - - return component_implementations - - -def _get_sampler() -> str | None: - return environ.get(OTEL_TRACES_SAMPLER, None) - - -def _get_id_generator() -> str: - return environ.get(OTEL_PYTHON_ID_GENERATOR, _DEFAULT_ID_GENERATOR) - - -def _get_tracer_configurator() -> str | None: - return environ.get(OTEL_PYTHON_TRACER_CONFIGURATOR, None) - - -def _get_meter_configurator() -> str | None: - return environ.get(OTEL_PYTHON_METER_CONFIGURATOR, None) - - -def _get_logger_configurator() -> str | None: - return environ.get(OTEL_PYTHON_LOGGER_CONFIGURATOR, None) - - -def _get_exporter_entry_point(exporter_name: str, signal_type: Literal["traces", "metrics", "logs"]): - if exporter_name not in ( - _EXPORTER_OTLP, - _EXPORTER_OTLP_PROTO_GRPC, - _EXPORTER_OTLP_PROTO_HTTP, - ): - return exporter_name - - # Checking env vars for OTLP protocol (grpc/http). - otlp_protocol = environ.get(_PROTOCOL_ENV_BY_SIGNAL_TYPE[signal_type]) or environ.get(OTEL_EXPORTER_OTLP_PROTOCOL) - - if not otlp_protocol: - if exporter_name == _EXPORTER_OTLP: - return _EXPORTER_OTLP_PROTO_GRPC - return exporter_name - - otlp_protocol = otlp_protocol.strip() - - if exporter_name == _EXPORTER_OTLP: - if otlp_protocol not in _EXPORTER_BY_OTLP_PROTOCOL: - # Invalid value was set by the env var - raise RuntimeError(f"Unsupported OTLP protocol '{otlp_protocol}' is configured") - - return _EXPORTER_BY_OTLP_PROTOCOL[otlp_protocol] - - # grpc/http already specified by exporter_name, only add a warning in case - # of a conflict. - exporter_name_by_env = _EXPORTER_BY_OTLP_PROTOCOL.get(otlp_protocol) - if exporter_name_by_env and exporter_name != exporter_name_by_env: - _logger.warning( - "Conflicting values for %s OTLP exporter protocol, using '%s'", - signal_type, - exporter_name, - ) - - return exporter_name - - -def _get_exporter_names( - signal_type: Literal["traces", "metrics", "logs"], -) -> list[str]: - names = environ.get(_EXPORTER_ENV_BY_SIGNAL_TYPE.get(signal_type, "")) - - if not names or names.lower().strip() == "none": - return [] - - return [_get_exporter_entry_point(_exporter.strip(), signal_type) for _exporter in names.split(",")] - - -def _init_tracing( - exporters: dict[str, type[SpanExporter]], - id_generator: IdGenerator | None = None, - sampler: Sampler | None = None, - resource: Resource | None = None, - exporter_args_map: ExporterArgsMap | None = None, - span_processors: Sequence[SpanProcessor] | None = None, - export_span_processor: _ConfigurationExporterSpanProcessorT | None = None, - tracer_configurator: _TracerConfiguratorT | None = None, -): - provider = TracerProvider( - id_generator=id_generator, - sampler=sampler, - resource=resource, - _tracer_configurator=tracer_configurator, - ) - set_tracer_provider(provider) - - exporter_args_map = exporter_args_map or {} - export_processor = export_span_processor or BatchSpanProcessor - - span_processors = span_processors or [] - for span_processor in span_processors: - provider.add_span_processor(span_processor) - - for _, exporter_class in exporters.items(): - exporter_args = exporter_args_map.get(exporter_class, {}) - provider.add_span_processor(export_processor(exporter_class(**exporter_args))) - - -def _init_metrics( - exporters_or_readers: dict[str, type[MetricExporter | MetricReader]], - resource: Resource | None = None, - exporter_args_map: ExporterArgsMap | None = None, - meter_configurator: _MeterConfiguratorT | None = None, -): - metric_readers = [] - - exporter_args_map = exporter_args_map or {} - for _, exporter_or_reader_class in exporters_or_readers.items(): - exporter_args = exporter_args_map.get(exporter_or_reader_class, {}) - if issubclass(exporter_or_reader_class, MetricReader): - metric_readers.append(exporter_or_reader_class(**exporter_args)) - else: - metric_readers.append(PeriodicExportingMetricReader(exporter_or_reader_class(**exporter_args))) - - provider = MeterProvider( - resource=resource, - metric_readers=metric_readers, - _meter_configurator=meter_configurator, - ) - set_meter_provider(provider) - - -# pylint: disable-next=too-many-locals -def _init_logging( - exporters: dict[str, type[LogRecordExporter]], - resource: Resource | None = None, - setup_logging_handler: bool = True, - exporter_args_map: ExporterArgsMap | None = None, - log_record_processors: Sequence[LogRecordProcessor] | None = None, - export_log_record_processor: _ConfigurationExporterLogRecordProcessorT | None = None, - logger_configurator: _LoggerConfiguratorT | None = None, -): - provider = LoggerProvider(resource=resource, _logger_configurator=logger_configurator) - set_logger_provider(provider) - - exporter_args_map = exporter_args_map or {} - export_processor = export_log_record_processor or BatchLogRecordProcessor - - log_record_processors = log_record_processors or [] - for log_record_processor in log_record_processors: - provider.add_log_record_processor(log_record_processor) - - for _, exporter_class in exporters.items(): - exporter_args = exporter_args_map.get(exporter_class, {}) - provider.add_log_record_processor(export_processor(exporter_class(**exporter_args))) - - if setup_logging_handler: - warnings.warn( - "The `OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED` environment variable " - "and the `LoggingHandler` in `opentelemetry-sdk` that it controls are deprecated." - "Install `opentelemetry-instrumentation-logging` package instead.", - DeprecationWarning, - ) - - # Add OTel handler - handler = LoggingHandler(level=logging.NOTSET, logger_provider=provider) - logging.getLogger().addHandler(handler) - _overwrite_logging_config_fns(handler) - - -def _overwrite_logging_config_fns(handler: LoggingHandler) -> None: - root = logging.getLogger() - - def wrapper(config_fn: Callable) -> Callable: - def overwritten_config_fn(*args, **kwargs): - removed_handler = False - # We don't want the OTLP handler to be modified or deleted by the logging config functions. - # So we remove it and then add it back after the function call. - if handler in root.handlers: - removed_handler = True - root.handlers.remove(handler) - try: - config_fn(*args, **kwargs) - finally: - # Ensure handler is added back if logging function throws exception. - if removed_handler: - root.addHandler(handler) - - return overwritten_config_fn - - logging.config.fileConfig = wrapper(logging.config.fileConfig) - logging.config.dictConfig = wrapper(logging.config.dictConfig) - logging.basicConfig = wrapper(logging.basicConfig) - - -def _import_logger_configurator( - logger_configurator_name: str | None, -) -> _LoggerConfiguratorT | None: - if not logger_configurator_name: - return None - - try: - _, logger_configurator_impl = _import_config_components( - [logger_configurator_name.strip()], - "_opentelemetry_logger_configurator", - )[0] - except Exception as exc: # pylint: disable=broad-exception-caught - _logger.warning( - "Using default logger configurator. Failed to load logger configurator, %s: %s", - logger_configurator_name, - exc, - ) - return None - return logger_configurator_impl - - -def _import_tracer_configurator( - tracer_configurator_name: str | None, -) -> _TracerConfiguratorT | None: - if not tracer_configurator_name: - return None - - try: - _, tracer_configurator_impl = _import_config_components( - [tracer_configurator_name.strip()], - "_opentelemetry_tracer_configurator", - )[0] - except Exception as exc: # pylint: disable=broad-exception-caught - _logger.warning( - "Using default tracer configurator. Failed to load tracer configurator, %s: %s", - tracer_configurator_name, - exc, - ) - return None - return tracer_configurator_impl - - -def _import_meter_configurator( - meter_configurator_name: str | None, -) -> _MeterConfiguratorT | None: - if not meter_configurator_name: - return None - - try: - _, meter_configurator_impl = _import_config_components( - [meter_configurator_name.strip()], - "_opentelemetry_meter_configurator", - )[0] - except Exception as exc: # pylint: disable=broad-exception-caught - _logger.warning( - "Using default meter configurator. Failed to load meter configurator, %s: %s", - meter_configurator_name, - exc, - ) - return None - return meter_configurator_impl - - -def _import_exporters( - trace_exporter_names: Sequence[str], - metric_exporter_names: Sequence[str], - log_exporter_names: Sequence[str], -) -> tuple[ - dict[str, type[SpanExporter]], - dict[str, type[MetricExporter | MetricReader]], - dict[str, type[LogRecordExporter]], -]: - trace_exporters = {} - metric_exporters = {} - log_exporters = {} - - for ( - exporter_name, - exporter_impl, - ) in _import_config_components(trace_exporter_names, "opentelemetry_traces_exporter"): - if issubclass(exporter_impl, SpanExporter): - trace_exporters[exporter_name] = exporter_impl - else: - raise RuntimeError(f"{exporter_name} is not a trace exporter") - - for ( - exporter_name, - exporter_impl, - ) in _import_config_components(metric_exporter_names, "opentelemetry_metrics_exporter"): - # The metric exporter components may be push MetricExporter or pull exporters which - # subclass MetricReader directly - if issubclass(exporter_impl, (MetricExporter, MetricReader)): - metric_exporters[exporter_name] = exporter_impl - else: - raise RuntimeError(f"{exporter_name} is not a metric exporter") - - for ( - exporter_name, - exporter_impl, - ) in _import_config_components(log_exporter_names, "opentelemetry_logs_exporter"): - if issubclass(exporter_impl, LogRecordExporter): - log_exporters[exporter_name] = exporter_impl - else: - raise RuntimeError(f"{exporter_name} is not a log exporter") - - return trace_exporters, metric_exporters, log_exporters - - -def _import_sampler_factory( - sampler_name: str, -) -> Callable[[float | str | None], Sampler]: - _, sampler_impl = _import_config_components([sampler_name.strip()], _OTEL_SAMPLER_ENTRY_POINT_GROUP)[0] - return sampler_impl - - -def _import_sampler(sampler_name: str | None) -> Sampler | None: - if not sampler_name: - return None - try: - sampler_factory = _import_sampler_factory(sampler_name) - arg = None - if sampler_name in ("traceidratio", "parentbased_traceidratio"): - try: - rate = float(os.getenv(OTEL_TRACES_SAMPLER_ARG, "")) - except (ValueError, TypeError): - _logger.warning("Could not convert TRACES_SAMPLER_ARG to float. Using default value 1.0.") - rate = 1.0 - arg = rate - else: - arg = os.getenv(OTEL_TRACES_SAMPLER_ARG) - - sampler = sampler_factory(arg) - if not isinstance(sampler, Sampler): - message = f"Sampler factory, {sampler_factory}, produced output, {sampler}, which is not a Sampler." - _logger.warning(message) - raise ValueError(message) - return sampler - except Exception as exc: # pylint: disable=broad-exception-caught - _logger.warning( - "Using default sampler. Failed to initialize sampler, %s: %s", - sampler_name, - exc, - ) - return None - - -def _import_id_generator(id_generator_name: str) -> IdGenerator: - id_generator_name, id_generator_impl = _import_config_components( - [id_generator_name.strip()], "opentelemetry_id_generator" - )[0] - - if issubclass(id_generator_impl, IdGenerator): - return id_generator_impl() - - raise RuntimeError(f"{id_generator_name} is not an IdGenerator") - - -def _import_opamp( - name: Literal["pre_sdk_init_function", "post_sdk_init_function"], -) -> Callable[[Resource], None] | None: - """Helper for OpAMP entry points loading - - This in development, at the moment we are looking for a callable that takes - the resource and instantiate an OpAMP agent. - Since configuration is not specified every implementer may have its own. - Refer to the opentelemetry-opamp-client package on how to setup the OpAMP agent. - """ - entry_point = None - try: - entry_point = next(iter(entry_points(group="_opentelemetry_opamp", name=name))) - return entry_point.load() - except StopIteration: - _logger.debug("No OpAMP init function found") - except AttributeError as exc: - _logger.warning( - "Failed to load OpAMP init function from entry point, %s: %s", - entry_point, - exc, - ) - - return None - - -def _initialize_components( - auto_instrumentation_version: str | None = None, - trace_exporter_names: list[str] | None = None, - metric_exporter_names: list[str] | None = None, - log_exporter_names: list[str] | None = None, - sampler: Sampler | None = None, - resource_attributes: Attributes | None = None, - id_generator: IdGenerator | None = None, - setup_logging_handler: bool | None = None, - exporter_args_map: ExporterArgsMap | None = None, - span_processors: Sequence[SpanProcessor] | None = None, - export_span_processor: _ConfigurationExporterSpanProcessorT | None = None, - log_record_processors: Sequence[LogRecordProcessor] | None = None, - export_log_record_processor: _ConfigurationExporterLogRecordProcessorT | None = None, - tracer_configurator: _TracerConfiguratorT | None = None, - meter_configurator: _MeterConfiguratorT | None = None, - logger_configurator: _LoggerConfiguratorT | None = None, -): - # pylint: disable=too-many-locals,too-many-branches - if resource_attributes is None: - resource_attributes = {} - # populate version if using auto-instrumentation - if auto_instrumentation_version: - resource_attributes[ResourceAttributes.TELEMETRY_AUTO_VERSION] = ( # type: ignore[reportIndexIssue] - auto_instrumentation_version - ) - # if env var OTEL_RESOURCE_ATTRIBUTES is given, it will read the service_name - # from the env variable else defaults to "unknown_service" - resource = Resource.create(resource_attributes) - - # OpAMP is a system created to configure OpenTelemetry SDKs with a remote config. - # This is different than other init helpers because setting up OpAMP requires distro - # provided code as it's not strictly specified. We have two entry points for OpAMP: - # one called early for people that want it blocking to get an updated config before - # setting up the rest of the SDK and the other after for people that want the - # SDK already setup. - _init_opamp = _import_opamp("pre_sdk_init_function") - if _init_opamp is not None: - _init_opamp(resource) - - if trace_exporter_names is None: - trace_exporter_names = [] - if metric_exporter_names is None: - metric_exporter_names = [] - if log_exporter_names is None: - log_exporter_names = [] - span_exporters, metric_exporters, log_exporters = _import_exporters( - trace_exporter_names + _get_exporter_names("traces"), - metric_exporter_names + _get_exporter_names("metrics"), - log_exporter_names + _get_exporter_names("logs"), - ) - if sampler is None: - sampler_name = _get_sampler() - sampler = _import_sampler(sampler_name) - if id_generator is None: - id_generator_name = _get_id_generator() - id_generator = _import_id_generator(id_generator_name) - - if tracer_configurator is None: - tracer_configurator_name = _get_tracer_configurator() - tracer_configurator = _import_tracer_configurator(tracer_configurator_name) - if meter_configurator is None: - meter_configurator_name = _get_meter_configurator() - meter_configurator = _import_meter_configurator(meter_configurator_name) - if logger_configurator is None: - logger_configurator_name = _get_logger_configurator() - logger_configurator = _import_logger_configurator(logger_configurator_name) - - _init_tracing( - exporters=span_exporters, - id_generator=id_generator, - sampler=sampler, - resource=resource, - exporter_args_map=exporter_args_map, - span_processors=span_processors, - export_span_processor=export_span_processor, - tracer_configurator=tracer_configurator, - ) - _init_metrics( - exporters_or_readers=metric_exporters, - resource=resource, - exporter_args_map=exporter_args_map, - meter_configurator=meter_configurator, - ) - if setup_logging_handler is None: - setup_logging_handler = ( - os.getenv(_OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, "false").strip().lower() == "true" - ) - _init_logging( - log_exporters, - resource, - setup_logging_handler, - exporter_args_map=exporter_args_map, - log_record_processors=log_record_processors, - export_log_record_processor=export_log_record_processor, - logger_configurator=logger_configurator, - ) - - _init_opamp = _import_opamp("post_sdk_init_function") - if _init_opamp is not None: - _init_opamp(resource) - - -class _BaseConfigurator(ABC): - """An ABC for configurators - - Configurators are used to configure - SDKs (i.e. TracerProvider, MeterProvider, Processors...) - to reduce the amount of manual configuration required. - """ - - _instance = None - _is_instrumented = False - - def __new__(cls, *args, **kwargs): - if cls._instance is None: - cls._instance = super().__new__(cls) - - return cls._instance - - @abstractmethod - def _configure(self, **kwargs): - """Configure the SDK""" - - def configure(self, **kwargs): - """Configure the SDK""" - self._configure(**kwargs) - - -class _OTelSDKConfigurator(_BaseConfigurator): - """A basic Configurator by OTel Python for initializing OTel SDK components - - Initializes several crucial OTel SDK components (i.e. TracerProvider, - MeterProvider, Processors...) according to a default implementation. Other - Configurators can subclass and slightly alter this initialization. - - NOTE: This class should not be instantiated nor should it become an entry - point on the `opentelemetry-sdk` package. Instead, distros should subclass - this Configurator and enhance it as needed. - """ - - def _configure(self, **kwargs): - if config_file := environ.get(OTEL_CONFIG_FILE): - # Declarative configuration lives in the separate - # ``opentelemetry-configuration`` package. Import lazily so the - # SDK has no runtime dependency on it; users who don't set - # ``OTEL_CONFIG_FILE`` never pay the import cost. - try: - # opentelemetry-configuration is an optional runtime dep - # and is not installed in this package's lint env, so - # silence the static-analysis no-name-in-module on the - # conditional import. - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.configuration import ( # noqa: PLC0415 - configure_sdk, - load_config_file, - ) - except ImportError as exc: - raise RuntimeError( - f"{OTEL_CONFIG_FILE} is set but " - "opentelemetry-configuration is not installed. " - "Install it with: pip install opentelemetry-configuration" - ) from exc - - if kwargs: - _logger.warning( - "%s is set; ignoring configurator kwargs: %s", - OTEL_CONFIG_FILE, - sorted(kwargs), - ) - configure_sdk(load_config_file(config_file)) - return - _initialize_components(**kwargs) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py deleted file mode 100644 index da62c461a91..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal import ( - ConcurrentMultiLogRecordProcessor, - LogDroppedAttributesWarning, - Logger, - LoggerProvider, - LoggingHandler, - LogLimits, - LogRecordDroppedAttributesWarning, - LogRecordLimits, - LogRecordProcessor, - ReadableLogRecord, - ReadWriteLogRecord, - SynchronousMultiLogRecordProcessor, -) - -__all__ = [ - "ConcurrentMultiLogRecordProcessor", - "LogDroppedAttributesWarning", - "LogLimits", - "LogRecordDroppedAttributesWarning", - "LogRecordLimits", - "LogRecordProcessor", - "Logger", - "LoggerProvider", - "LoggingHandler", - "ReadWriteLogRecord", - "ReadableLogRecord", - "SynchronousMultiLogRecordProcessor", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py deleted file mode 100644 index 56c439b6f9c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/__init__.py +++ /dev/null @@ -1,1092 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import abc -import atexit -import base64 -import concurrent.futures -import json -import logging -import os -import threading -import traceback -import warnings -from collections.abc import Callable, Mapping, Sequence -from dataclasses import dataclass, field -from os import environ -from threading import Lock -from time import time_ns -from types import NoneType -from typing import ( # noqa - Any, - Tuple, - Union, - cast, - overload, -) -from weakref import WeakMethod, WeakSet - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry._logs import Logger as APILogger -from opentelemetry.agent._vendor.opentelemetry._logs import LoggerProvider as APILoggerProvider -from opentelemetry.agent._vendor.opentelemetry._logs import ( - LogRecord, - NoOpLogger, - SeverityNumber, - get_logger, - get_logger_provider, -) -from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes -from opentelemetry.agent._vendor.opentelemetry.context import get_current -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal._exceptions import ( - _copy_log_record_with_exception, - _create_log_record_with_exception, - _set_log_record_exception_attributes, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal._logger_metrics import ( - LoggerMetricsT, - create_logger_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_ATTRIBUTE_COUNT_LIMIT, - OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, - OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT, - OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, - OTEL_SDK_DISABLED, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( - parse_boolean_environment_variable, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( - Resource, - _get_process_dependent_resource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.util import ns_to_iso_str -from opentelemetry.agent._vendor.opentelemetry.sdk.util._configurator import RuleBasedConfigurator -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( - InstrumentationScope, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes import ( - code_attributes, - exception_attributes, -) -from opentelemetry.agent._vendor.opentelemetry.trace import ( - format_span_id, - format_trace_id, -) -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes - -# pylint: disable=too-many-lines - -_DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT = 128 -_ENV_VALUE_UNSET = "" - -_logger = logging.getLogger(__name__) - - -class BytesEncoder(json.JSONEncoder): - def default(self, o): - if isinstance(o, bytes): - return base64.b64encode(o).decode() - return super().default(o) - - -class LogRecordDroppedAttributesWarning(UserWarning): - """Custom warning to indicate dropped log attributes due to limits. - - This class is used to filter and handle these specific warnings separately - from other warnings, ensuring that they are only shown once without - interfering with default user warnings. - """ - - -warnings.simplefilter("once", LogRecordDroppedAttributesWarning) - - -@deprecated( - "Use LogRecordDroppedAttributesWarning. Since logs are not stable yet this WILL be removed in future releases." -) -class LogDroppedAttributesWarning(LogRecordDroppedAttributesWarning): - pass - - -class LogRecordLimits: - """This class is based on a SpanLimits class in the Tracing module. - - This class represents the limits that should be enforced on recorded data such as events, links, attributes etc. - - This class does not enforce any limits itself. It only provides a way to read limits from env, - default values and from user provided arguments. - - All limit arguments must be either a non-negative integer, ``None`` or ``LogRecordLimits.UNSET``. - - - All limit arguments are optional. - - If a limit argument is not set, the class will try to read its value from the corresponding - environment variable. - - If the environment variable is not set, the default value, if any, will be used. - - Limit precedence: - - - If a model specific limit is set, it will be used. - - Else if the corresponding global limit is set, it will be used. - - Else if the model specific limit has a default value, the default value will be used. - - Else if the global limit has a default value, the default value will be used. - - Args: - max_attributes: Maximum number of attributes that can be added to a log record (global fallback). - Environment variable: ``OTEL_ATTRIBUTE_COUNT_LIMIT`` - Default: {_DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT} - max_attribute_length: Maximum length an attribute value can have (global fallback). Values - longer than the specified length will be truncated. - max_log_record_attributes: Maximum number of attributes that can be added to a log record. - Environment variable: ``OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT`` - Falls back to ``max_attributes`` when unset. - max_log_record_attribute_length: Maximum length a log record attribute value can have. - Environment variable: ``OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT`` - Falls back to ``max_attribute_length`` when unset. - """ - - UNSET = -1 - - def __init__( - self, - max_attributes: int | None = None, - max_attribute_length: int | None = None, - max_log_record_attributes: int | None = None, - max_log_record_attribute_length: int | None = None, - ): - # global attribute count - global_max_attributes = self._from_env_if_absent(max_attributes, OTEL_ATTRIBUTE_COUNT_LIMIT) - self.max_attributes = ( - global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT - ) - - # global attribute length - self.max_attribute_length = self._from_env_if_absent( - max_attribute_length, - OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, - ) - - self.max_log_record_attributes = self._from_env_if_absent( - max_log_record_attributes, - OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT, - default=self.max_attributes, - ) - - self.max_log_record_attribute_length = self._from_env_if_absent( - max_log_record_attribute_length, - OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT, - default=self.max_attribute_length, - ) - - def __repr__(self): - return ( - f"{type(self).__name__}(" - f"max_attributes={self.max_attributes}, " - f"max_attribute_length={self.max_attribute_length}, " - f"max_log_record_attributes={self.max_log_record_attributes}, " - f"max_log_record_attribute_length={self.max_log_record_attribute_length})" - ) - - @classmethod - def _from_env_if_absent(cls, value: int | None, env_var: str, default: int | None = None) -> int | None: - if value == cls.UNSET: - return None - - err_msg = "{} must be a non-negative integer but got {}" - - # if no value is provided for the limit, try to load it from env - if value is None: - # return default value if env var is not set - if env_var not in environ: - return default - - str_value = environ.get(env_var, "").strip().lower() - if str_value == _ENV_VALUE_UNSET: - return None - - try: - value = int(str_value) - except ValueError: - raise ValueError(err_msg.format(env_var, str_value)) - - if value < 0: - raise ValueError(err_msg.format(env_var, value)) - return value - - -@deprecated("Use LogRecordLimits. Since logs are not stable yet this WILL be removed in future releases.") -class LogLimits(LogRecordLimits): - pass - - -@dataclass(frozen=True) -class ReadableLogRecord: - """Readable LogRecord should be kept exactly in-sync with ReadWriteLogRecord, only difference is the frozen=True param.""" - - log_record: LogRecord - resource: Resource - instrumentation_scope: InstrumentationScope | None = None - limits: LogRecordLimits | None = None - - @property - def dropped_attributes(self) -> int: - if isinstance(self.log_record.attributes, BoundedAttributes): - return self.log_record.attributes.dropped - return 0 - - def to_json(self, indent: int | None = 4) -> str: - return json.dumps( - { - "body": self.log_record.body, - "severity_number": self.log_record.severity_number.value - if self.log_record.severity_number is not None - else None, - "severity_text": self.log_record.severity_text, - "attributes": (dict(self.log_record.attributes) if bool(self.log_record.attributes) else None), - "dropped_attributes": self.dropped_attributes, - "timestamp": ns_to_iso_str(self.log_record.timestamp) - if self.log_record.timestamp is not None - else None, - "observed_timestamp": ns_to_iso_str(self.log_record.observed_timestamp), - "trace_id": ( - f"0x{format_trace_id(self.log_record.trace_id)}" if self.log_record.trace_id is not None else "" - ), - "span_id": ( - f"0x{format_span_id(self.log_record.span_id)}" if self.log_record.span_id is not None else "" - ), - "trace_flags": self.log_record.trace_flags, - "resource": json.loads(self.resource.to_json()), - "event_name": self.log_record.event_name if self.log_record.event_name else "", - }, - indent=indent, - cls=BytesEncoder, - ) - - -@dataclass -class ReadWriteLogRecord: - """A ReadWriteLogRecord instance represents an event being logged. - ReadWriteLogRecord instances are created and emitted via `Logger` - every time something is logged. They contain all the information - pertinent to the event being logged. - """ - - log_record: LogRecord - resource: Resource | None = Resource.create({}) - instrumentation_scope: InstrumentationScope | None = None - limits: LogRecordLimits = field(default_factory=LogRecordLimits) - - def __post_init__(self): - self.log_record.attributes = BoundedAttributes( - maxlen=self.limits.max_log_record_attributes, - attributes=self.log_record.attributes if self.log_record.attributes else None, - immutable=False, - max_value_len=self.limits.max_log_record_attribute_length, - extended_attributes=True, - ) - if self.dropped_attributes > 0: - warnings.warn( - "Log record attributes were dropped due to limits", - LogRecordDroppedAttributesWarning, - stacklevel=2, - ) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, ReadWriteLogRecord): - return NotImplemented - return self.__dict__ == other.__dict__ - - @property - def dropped_attributes(self) -> int: - if isinstance(self.log_record.attributes, BoundedAttributes): - return self.log_record.attributes.dropped - return 0 - - @classmethod - def _from_api_log_record( - cls, - *, - record: LogRecord, - resource: Resource, - instrumentation_scope: InstrumentationScope | None = None, - limits: LogRecordLimits | None = None, - ) -> ReadWriteLogRecord: - return cls( - log_record=record, - resource=resource, - instrumentation_scope=instrumentation_scope, - **({} if limits is None else {"limits": limits}), - ) - - -class LogRecordProcessor(abc.ABC): - """Interface to hook the log record emitting action. - - Log processors can be registered directly using - :func:`LoggerProvider.add_log_record_processor` and they are invoked - in the same order as they were registered. - - Implementers of custom log processors should be aware of the following: - - Error Handling - -------------- - According to the OpenTelemetry error handling principles, the SDK should - not throw unhandled exceptions at runtime. When implementing a custom - ``LogRecordProcessor``, it is the **processor's responsibility** to handle - any exceptions that may be raised by the exporter's ``export()`` method. - - The ``LogRecordExporter.export()`` method may raise exceptions (e.g., - network errors, timeouts). If these exceptions are not caught, they will - propagate up and potentially crash the application. - - Custom processor implementations should wrap exporter calls in a - try/except block. See ``SimpleLogRecordProcessor`` for a reference - implementation:: - - def on_emit(self, log_record: ReadWriteLogRecord): - try: - self._exporter.export((log_record,)) - except Exception: # pylint: disable=broad-exception-caught - logger.exception("Exception while exporting logs.") - - The ``BatchLogRecordProcessor`` handles this implicitly since export - operations occur in a background thread where exceptions cannot bubble - up to the caller. - """ - - @abc.abstractmethod - def on_emit(self, log_record: ReadWriteLogRecord) -> None: - """Emits the ``ReadWriteLogRecord``. - - Implementers should handle any exceptions raised during log processing - to prevent application crashes. See the class docstring for details - on error handling expectations. - """ - - def enabled( # pylint: disable=no-self-use,unused-argument - self, - *, - context: Context | None = None, - instrumentation_scope: InstrumentationScope | None = None, - severity_number: SeverityNumber | None = None, - event_name: str | None = None, - ) -> bool: - """Returns whether this processor would emit a record for the given arguments. - - Processors that support filtering MAY override this method. The default - implementation returns ``True``. - """ - return True - - @abc.abstractmethod - def shutdown(self) -> None: - """Called when a :class:`opentelemetry.sdk._logs.Logger` is shutdown""" - - @abc.abstractmethod - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Export all the received logs to the configured Exporter that have not yet - been exported. - - Args: - timeout_millis: The maximum amount of time to wait for logs to be - exported. - - Returns: - False if the timeout is exceeded, True otherwise. - """ - - -# Temporary fix until https://github.com/PyCQA/pylint/issues/4098 is resolved -# pylint:disable=no-member -class SynchronousMultiLogRecordProcessor(LogRecordProcessor): - """Implementation of class:`LogRecordProcessor` that forwards all received - events to a list of log processors sequentially. - - The underlying log processors are called in sequential order as they were - added. - """ - - def __init__(self): - # use a tuple to avoid race conditions when adding a new log and - # iterating through it on "emit". - self._log_record_processors = () # type: tuple[LogRecordProcessor, ...] - self._lock = threading.Lock() - - def add_log_record_processor(self, log_record_processor: LogRecordProcessor) -> None: - """Adds a Logprocessor to the list of log processors handled by this instance""" - with self._lock: - self._log_record_processors += (log_record_processor,) - - def on_emit(self, log_record: ReadWriteLogRecord) -> None: - for lp in self._log_record_processors: - lp.on_emit(log_record) - - def enabled( - self, - *, - context: Context | None = None, - instrumentation_scope: InstrumentationScope | None = None, - severity_number: SeverityNumber | None = None, - event_name: str | None = None, - ) -> bool: - processors = self._log_record_processors - return any( - lp.enabled( - context=context, - instrumentation_scope=instrumentation_scope, - severity_number=severity_number, - event_name=event_name, - ) - for lp in processors - ) - - def shutdown(self) -> None: - """Shutdown the log processors one by one""" - for lp in self._log_record_processors: - lp.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Force flush the log processors one by one - - Args: - timeout_millis: The maximum amount of time to wait for logs to be - exported. If the first n log processors exceeded the timeout - then remaining log processors will not be flushed. - - Returns: - True if all the log processors flushes the logs within timeout, - False otherwise. - """ - deadline_ns = time_ns() + timeout_millis * 1000000 - all_flushed = True - for lp in self._log_record_processors: - current_ts = time_ns() - if current_ts >= deadline_ns: - return False - - if lp.force_flush((deadline_ns - current_ts) // 1000000) is False: - all_flushed = False - - return all_flushed - - -class ConcurrentMultiLogRecordProcessor(LogRecordProcessor): - """Implementation of :class:`LogRecordProcessor` that forwards all received - events to a list of log processors in parallel. - - Calls to the underlying log processors are forwarded in parallel by - submitting them to a thread pool executor and waiting until each log - processor finished its work. - - Args: - max_workers: The number of threads managed by the thread pool executor - and thus defining how many log processors can work in parallel. - """ - - def __init__(self, max_workers: int = 2): - # use a tuple to avoid race conditions when adding a new log and - # iterating through it on "emit". - self._log_record_processors = () # type: tuple[LogRecordProcessor, ...] - self._lock = threading.Lock() - self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) - - def add_log_record_processor(self, log_record_processor: LogRecordProcessor): - with self._lock: - self._log_record_processors += (log_record_processor,) - - def _submit_and_wait( - self, - func: Callable[[LogRecordProcessor], Callable[..., None]], - *args: Any, - **kwargs: Any, - ): - futures = [] - for lp in self._log_record_processors: - future = self._executor.submit(func(lp), *args, **kwargs) - futures.append(future) - for future in futures: - future.result() - - def on_emit(self, log_record: ReadWriteLogRecord) -> None: - self._submit_and_wait(lambda lp: lp.on_emit, log_record) - - def enabled( - self, - *, - context: Context | None = None, - instrumentation_scope: InstrumentationScope | None = None, - severity_number: SeverityNumber | None = None, - event_name: str | None = None, - ) -> bool: - processors = self._log_record_processors - return any( - lp.enabled( - context=context, - instrumentation_scope=instrumentation_scope, - severity_number=severity_number, - event_name=event_name, - ) - for lp in processors - ) - - def shutdown(self) -> None: - self._submit_and_wait(lambda lp: lp.shutdown) - - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Force flush the log processors in parallel. - - Args: - timeout_millis: The maximum amount of time to wait for logs to be - exported. - - Returns: - True if all the log processors flushes the logs within timeout, - False otherwise. - """ - futures = [] - for lp in self._log_record_processors: - future = self._executor.submit(lp.force_flush, timeout_millis) - futures.append(future) - - done_futures, not_done_futures = concurrent.futures.wait(futures, timeout_millis / 1e3) - - if not_done_futures: - return False - - for future in done_futures: - if future.result() is False: - return False - - return True - - -# skip natural LogRecord attributes -# http://docs.python.org/library/logging.html#logrecord-attributes -_RESERVED_ATTRS = frozenset( - ( - "asctime", - "args", - "created", - "exc_info", - "exc_text", - "filename", - "funcName", - "getMessage", - "message", - "levelname", - "levelno", - "lineno", - "module", - "msecs", - "msg", - "name", - "pathname", - "process", - "processName", - "relativeCreated", - "stack_info", - "thread", - "threadName", - "taskName", - ) -) - - -class LoggingHandler(logging.Handler): - """A handler class which writes logging records, in OTLP format, to - a network destination or file. Supports signals from the `logging` module. - https://docs.python.org/3/library/logging.html - """ - - def __init__( - self, - level: int = logging.NOTSET, - logger_provider: APILoggerProvider | None = None, - ) -> None: - super().__init__(level=level) - self._logger_provider = logger_provider or get_logger_provider() - - warnings.warn( - "`LoggingHandler` in `opentelemetry-sdk` is deprecated. Use the " - "handler from `opentelemetry-instrumentation-logging` instead.", - DeprecationWarning, - ) - - @staticmethod - def _get_attributes(record: logging.LogRecord) -> Attributes: - attributes = {k: v for k, v in vars(record).items() if k not in _RESERVED_ATTRS} - - # Add standard code attributes for logs. - attributes[code_attributes.CODE_FILE_PATH] = record.pathname - attributes[code_attributes.CODE_FUNCTION_NAME] = record.funcName - attributes[code_attributes.CODE_LINE_NUMBER] = record.lineno - - if record.exc_info: - exctype, value, tb = record.exc_info - if exctype is not None: - attributes[exception_attributes.EXCEPTION_TYPE] = exctype.__name__ - if value is not None and value.args: - attributes[exception_attributes.EXCEPTION_MESSAGE] = str(value.args[0]) - if tb is not None: - # https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#stacktrace-representation - attributes[exception_attributes.EXCEPTION_STACKTRACE] = "".join( - traceback.format_exception(*record.exc_info) - ) - return attributes - - def _translate(self, record: logging.LogRecord) -> LogRecord: - timestamp = int(record.created * 1e9) - observered_timestamp = time_ns() - attributes = self._get_attributes(record) - severity_number = std_to_otel(record.levelno) - if self.formatter: - body = self.format(record) - else: - # `record.getMessage()` uses `record.msg` as a template to format - # `record.args` into. There is a special case in `record.getMessage()` - # where it will only attempt formatting if args are provided, - # otherwise, it just stringifies `record.msg`. - # - # Since the OTLP body field has a type of 'any' and the logging module - # is sometimes used in such a way that objects incorrectly end up - # set as record.msg, in those cases we would like to bypass - # `record.getMessage()` completely and set the body to the object - # itself instead of its string representation. - # For more background, see: https://github.com/open-telemetry/opentelemetry-python/pull/4216 - if not record.args and not isinstance(record.msg, str): - # if record.msg is not a value we can export, cast it to string - # TODO: https://github.com/open-telemetry/opentelemetry-python/issues/5304 - do something better - # than just casting to a string. - if not isinstance( - record.msg, - ( - NoneType, - bool, - bytes, - int, - float, - str, - Sequence, - Mapping, - ), - ): - body = str(record.msg) - else: - body = record.msg - else: - body = record.getMessage() - - # Map Python log level names to OTel severity text as defined in - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#displaying-severity - # Python "WARNING" -> OTel "WARN" (see #3548) - # Python "CRITICAL" -> OTel "FATAL" (see #4984) - _python_to_otel_severity_text = { - "WARNING": "WARN", - "CRITICAL": "FATAL", - } - level_name = _python_to_otel_severity_text.get(record.levelname, record.levelname) - - return LogRecord( - timestamp=timestamp, - observed_timestamp=observered_timestamp, - context=get_current() or None, - severity_text=level_name, - severity_number=severity_number, - body=body, - attributes=attributes, - ) - - def emit(self, record: logging.LogRecord) -> None: - """ - Emit a record. Skip emitting if logger is NoOp. - - The record is translated to OTel format, and then sent across the pipeline. - """ - logger = get_logger(record.name, logger_provider=self._logger_provider) - if not isinstance(logger, NoOpLogger): - logger.emit(self._translate(record)) - - def flush(self) -> None: - """ - Flushes the logging output. Skip flushing if logging_provider has no force_flush method. - """ - if hasattr(self._logger_provider, "force_flush") and callable( - self._logger_provider.force_flush # type: ignore[reportAttributeAccessIssue] - ): - # This is done in a separate thread to avoid a potential deadlock, for - # details see https://github.com/open-telemetry/opentelemetry-python/pull/4636. - thread = threading.Thread(target=self._logger_provider.force_flush) # type: ignore[reportAttributeAccessIssue] - thread.start() - - -@dataclass -class _LoggerConfig: - is_enabled: bool = True - - @classmethod - def default(cls) -> _LoggerConfig: - return _LoggerConfig() - - -class Logger(APILogger): - def __init__( - self, - resource: Resource, - multi_log_record_processor: SynchronousMultiLogRecordProcessor | ConcurrentMultiLogRecordProcessor, - instrumentation_scope: InstrumentationScope, - *, - logger_metrics: LoggerMetricsT, - log_record_limits: LogRecordLimits | None = None, - _logger_config: _LoggerConfig, - ): - super().__init__( - instrumentation_scope.name, - instrumentation_scope.version, - instrumentation_scope.schema_url, - instrumentation_scope.attributes, - ) - self._resource = resource - self._multi_log_record_processor = multi_log_record_processor - self._instrumentation_scope = instrumentation_scope - self._logger_metrics = logger_metrics - self._logger_config = _logger_config - self._log_record_limits = log_record_limits or LogRecordLimits() - - def _is_enabled(self) -> bool: - return self._logger_config.is_enabled - - def enabled( - self, - *, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - event_name: str | None = None, - ) -> bool: - if not self._is_enabled(): - return False - return self._multi_log_record_processor.enabled( - context=context, - instrumentation_scope=self._instrumentation_scope, - severity_number=severity_number, - event_name=event_name, - ) - - def _set_logger_config(self, logger_config: _LoggerConfig) -> None: - self._logger_config = logger_config - - def _set_resource(self, resource: Resource) -> None: - self._resource = resource - - @property - def instrumentation_scope(self): - return self._instrumentation_scope - - @property - def resource(self): - return self._resource - - # pylint: disable=arguments-differ - def emit( - self, - record: LogRecord | None = None, - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context: Context | None = None, - severity_number: SeverityNumber | None = None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, - ) -> None: - """Emits the :class:`ReadWriteLogRecord` by setting instrumentation scope - and forwarding to the processor. - """ - if not self._is_enabled(): - return - # If a record is provided, use it directly - if record is not None: - if not isinstance(record, ReadWriteLogRecord): - if record.exception is not None: - record = _copy_log_record_with_exception(record) - # pylint:disable=protected-access - writable_record = ReadWriteLogRecord._from_api_log_record( - record=record, - resource=self._resource, - instrumentation_scope=self._instrumentation_scope, - limits=self._log_record_limits, - ) - else: - _set_log_record_exception_attributes(record.log_record) - writable_record = record - else: - # Create a record from individual parameters - log_record = _create_log_record_with_exception( - timestamp=timestamp, - observed_timestamp=observed_timestamp, - context=context, - severity_number=severity_number, - severity_text=severity_text, - body=body, - attributes=attributes, - event_name=event_name, - exception=exception, - ) - # pylint:disable=protected-access - writable_record = ReadWriteLogRecord._from_api_log_record( - record=log_record, - resource=self._resource, - instrumentation_scope=self._instrumentation_scope, - limits=self._log_record_limits, - ) - - self._logger_metrics.emit_log() - self._multi_log_record_processor.on_emit(writable_record) - - -_LoggerConfiguratorT = Callable[[InstrumentationScope], _LoggerConfig] -_RuleBasedLoggerConfigurator = RuleBasedConfigurator[_LoggerConfig] - - -def _default_logger_configurator( - _logger_scope: InstrumentationScope, -) -> _LoggerConfig: - return _LoggerConfig.default() - - -def _disable_logger_configurator( - _logger_scope: InstrumentationScope, -) -> _LoggerConfig: - return _LoggerConfig(is_enabled=False) - - -class LoggerProvider(APILoggerProvider): - def __init__( - self, - resource: Resource | None = None, - shutdown_on_exit: bool = True, - multi_log_record_processor: SynchronousMultiLogRecordProcessor - | ConcurrentMultiLogRecordProcessor - | None = None, - *, - meter_provider: MeterProvider | None = None, - log_record_limits: LogRecordLimits | None = None, - _logger_configurator: _LoggerConfiguratorT | None = None, - ): - if resource is None: - self._resource = Resource.create({}) - else: - self._resource = resource - self._multi_log_record_processor = multi_log_record_processor or SynchronousMultiLogRecordProcessor() - self._logger_metrics = create_logger_metrics( - meter_provider or get_meter_provider(), - parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ) - disabled = environ.get(OTEL_SDK_DISABLED, "") - self._disabled = disabled.lower().strip() == "true" - self._logger_configurator = _logger_configurator or _default_logger_configurator - self._log_record_limits = log_record_limits or LogRecordLimits() - self._at_exit_handler = None - if shutdown_on_exit: - self._at_exit_handler = atexit.register(self.shutdown) - self._logger_cache = {} - self._logger_cache_lock = Lock() - self._active_loggers: WeakSet[Logger] = WeakSet() - self._active_loggers_lock = Lock() - if hasattr(os, "register_at_fork"): - weak_at_fork = WeakMethod(self._handle_fork) - - def _after_in_child() -> None: - if at_fork := weak_at_fork(): - at_fork() - - os.register_at_fork(after_in_child=_after_in_child) - - def _handle_fork(self) -> None: - self._logger_cache_lock = Lock() - self._active_loggers_lock = Lock() - self._update_resource(_get_process_dependent_resource()) - - @property - def resource(self): - return self._resource - - def _update_resource(self, resource: Resource) -> None: - with self._active_loggers_lock: - self._resource = self._resource.merge(resource) - for logger in list(self._active_loggers): - # pylint: disable-next=protected-access - logger._set_resource(self._resource) - - def _get_logger_no_cache( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> Logger: - scope = InstrumentationScope(name, version, schema_url, attributes) - - return Logger( - self._resource, - self._multi_log_record_processor, - scope, - logger_metrics=self._logger_metrics, - _logger_config=self._apply_logger_configurator(scope), - log_record_limits=self._log_record_limits, - ) - - def _get_logger_cached( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - ) -> Logger: - with self._logger_cache_lock: - key = (name, version, schema_url) - if key in self._logger_cache: - return self._logger_cache[key] - - self._logger_cache[key] = self._get_logger_no_cache(name, version, schema_url) - return self._logger_cache[key] - - def get_logger( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> APILogger: - if self._disabled: - return NoOpLogger( - name, - version=version, - schema_url=schema_url, - attributes=attributes, - ) - logger = ( - self._get_logger_cached(name, version, schema_url) - if attributes is None - else self._get_logger_no_cache(name, version, schema_url, attributes) - ) - with self._active_loggers_lock: - self._active_loggers.add(logger) - return logger - - def add_log_record_processor(self, log_record_processor: LogRecordProcessor): - """Registers a new :class:`LogRecordProcessor` for this `LoggerProvider` instance. - - The log processors are invoked in the same order they are registered. - """ - self._multi_log_record_processor.add_log_record_processor(log_record_processor) - - def _set_logger_configurator(self, *, logger_configurator: _LoggerConfiguratorT): - """Set a new LoggerConfigurator for this LoggerProvider. - - Setting a new LoggerConfigurator will result in the configurator being called - for each outstanding Logger and for any newly created loggers thereafter. - Therefore, it is important that the provided function returns quickly. - """ - self._logger_configurator = logger_configurator - with self._active_loggers_lock: - for logger in list(self._active_loggers): - # pylint: disable-next=protected-access - logger._set_logger_config(self._apply_logger_configurator(logger.instrumentation_scope)) - - def _apply_logger_configurator(self, instrumentation_scope: InstrumentationScope) -> _LoggerConfig: - try: - return self._logger_configurator(instrumentation_scope) - # pylint: disable-next=broad-exception-caught - except Exception: - _logger.exception( - "logger configurator failed for scope '%s', using default config", - instrumentation_scope.name, - ) - return _LoggerConfig.default() - - def shutdown(self) -> None: - """Shuts down the log processors.""" - self._multi_log_record_processor.shutdown() - if self._at_exit_handler is not None: - atexit.unregister(self._at_exit_handler) - self._at_exit_handler = None - - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Force flush the log processors. - - Args: - timeout_millis: The maximum amount of time to wait for logs to be - exported. - - Returns: - True if all the log processors flushes the logs within timeout, - False otherwise. - """ - return self._multi_log_record_processor.force_flush(timeout_millis) - - -_STD_TO_OTEL = { - 10: SeverityNumber.DEBUG, - 11: SeverityNumber.DEBUG2, - 12: SeverityNumber.DEBUG3, - 13: SeverityNumber.DEBUG4, - 14: SeverityNumber.DEBUG4, - 15: SeverityNumber.DEBUG4, - 16: SeverityNumber.DEBUG4, - 17: SeverityNumber.DEBUG4, - 18: SeverityNumber.DEBUG4, - 19: SeverityNumber.DEBUG4, - 20: SeverityNumber.INFO, - 21: SeverityNumber.INFO2, - 22: SeverityNumber.INFO3, - 23: SeverityNumber.INFO4, - 24: SeverityNumber.INFO4, - 25: SeverityNumber.INFO4, - 26: SeverityNumber.INFO4, - 27: SeverityNumber.INFO4, - 28: SeverityNumber.INFO4, - 29: SeverityNumber.INFO4, - 30: SeverityNumber.WARN, - 31: SeverityNumber.WARN2, - 32: SeverityNumber.WARN3, - 33: SeverityNumber.WARN4, - 34: SeverityNumber.WARN4, - 35: SeverityNumber.WARN4, - 36: SeverityNumber.WARN4, - 37: SeverityNumber.WARN4, - 38: SeverityNumber.WARN4, - 39: SeverityNumber.WARN4, - 40: SeverityNumber.ERROR, - 41: SeverityNumber.ERROR2, - 42: SeverityNumber.ERROR3, - 43: SeverityNumber.ERROR4, - 44: SeverityNumber.ERROR4, - 45: SeverityNumber.ERROR4, - 46: SeverityNumber.ERROR4, - 47: SeverityNumber.ERROR4, - 48: SeverityNumber.ERROR4, - 49: SeverityNumber.ERROR4, - 50: SeverityNumber.FATAL, - 51: SeverityNumber.FATAL2, - 52: SeverityNumber.FATAL3, - 53: SeverityNumber.FATAL4, -} - - -def std_to_otel(levelno: int) -> SeverityNumber: - """ - Map python log levelno as defined in https://docs.python.org/3/library/logging.html#logging-levels - to OTel log severity number as defined here: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber - """ - if levelno < 10: - return SeverityNumber.UNSPECIFIED - if levelno > 53: - return SeverityNumber.FATAL4 - return _STD_TO_OTEL[levelno] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py deleted file mode 100644 index de5132e91af..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_exceptions.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import traceback - -from opentelemetry.agent._vendor.opentelemetry._logs import LogRecord -from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes import exception_attributes -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes - - -def _get_exception_attributes( - exception: BaseException, -) -> dict[str, AnyValue]: - stacktrace = "".join(traceback.format_exception(type(exception), value=exception, tb=exception.__traceback__)) - module = type(exception).__module__ - qualname = type(exception).__qualname__ - exception_type = f"{module}.{qualname}" if module and module != "builtins" else qualname - return { - exception_attributes.EXCEPTION_TYPE: exception_type, - exception_attributes.EXCEPTION_MESSAGE: str(exception), - exception_attributes.EXCEPTION_STACKTRACE: stacktrace, - } - - -def _get_attributes_with_exception( - attributes: Attributes, - exception: BaseException | None, -) -> Attributes: - if exception is None: - return attributes - - exception_attributes_map = _get_exception_attributes(exception) - if attributes is None: - attributes_map: Attributes = {} - else: - attributes_map = attributes - - if isinstance(attributes_map, BoundedAttributes): - bounded_attributes = attributes_map - merged = BoundedAttributes( - maxlen=bounded_attributes.maxlen, - attributes=bounded_attributes, - immutable=False, - max_value_len=bounded_attributes.max_value_len, - ) - merged.dropped = bounded_attributes.dropped - for key, value in exception_attributes_map.items(): - if key not in merged: - merged[key] = value - return merged - - return exception_attributes_map | dict(attributes_map.items()) - - -def _copy_log_record( - record: LogRecord, - attributes: Attributes, -) -> LogRecord: - copied_record = LogRecord( - timestamp=record.timestamp, - observed_timestamp=record.observed_timestamp, - context=record.context, - severity_text=record.severity_text, - severity_number=record.severity_number, - body=record.body, - attributes=attributes, - event_name=record.event_name, - exception=getattr(record, "exception", None), - ) - copied_record.trace_id = record.trace_id - copied_record.span_id = record.span_id - copied_record.trace_flags = record.trace_flags - return copied_record - - -def _copy_log_record_with_exception(record: LogRecord) -> LogRecord: - return _copy_log_record( - record, - _get_attributes_with_exception(record.attributes, record.exception), - ) - - -def _set_log_record_exception_attributes(record: LogRecord) -> None: - record.attributes = _get_attributes_with_exception( - record.attributes, - record.exception, - ) - - -def _create_log_record_with_exception( - *, - timestamp: int | None = None, - observed_timestamp: int | None = None, - context=None, - severity_number=None, - severity_text: str | None = None, - body: AnyValue | None = None, - attributes: Attributes = None, - event_name: str | None = None, - exception: BaseException | None = None, -) -> LogRecord: - return LogRecord( - timestamp=timestamp, - observed_timestamp=observed_timestamp, - context=context, - severity_number=severity_number, - severity_text=severity_text, - body=body, - attributes=_get_attributes_with_exception(attributes, exception), - event_name=event_name, - exception=exception, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py deleted file mode 100644 index 3eb224c8565..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/_logger_metrics.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Protocol - -from opentelemetry.agent._vendor.opentelemetry import metrics as metrics_api -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( - create_otel_sdk_log_created, -) - - -class LoggerMetricsT(Protocol): - def emit_log(self) -> None: ... - - -class NoOpLoggerMetrics: - def emit_log(self) -> None: - pass - - -class LoggerMetrics: - def __init__(self, meter_provider: metrics_api.MeterProvider) -> None: - meter = meter_provider.get_meter("opentelemetry-sdk") - self._created_logs = create_otel_sdk_log_created(meter) - - def emit_log(self) -> None: - self._created_logs.add(1) - - -def create_logger_metrics( - meter_provider: metrics_api.MeterProvider, - enabled: bool, -) -> LoggerMetricsT: - if not enabled: - return NoOpLoggerMetrics() - - return LoggerMetrics(meter_provider) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py deleted file mode 100644 index dc790f59b0d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/__init__.py +++ /dev/null @@ -1,392 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import abc -import copy -import enum -import logging -import sys -from collections.abc import Callable, Sequence -from os import environ, linesep -from typing import IO - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry.context import ( - _ON_EMIT_RECURSION_COUNT_KEY, - _SUPPRESS_INSTRUMENTATION_KEY, - Context, - attach, - detach, - get_value, - set_value, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ( - LogRecordProcessor, - ReadableLogRecord, - ReadWriteLogRecord, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import ( - BatchProcessor, - DuplicateFilter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal._processor_metrics import ( - create_processor_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_BLRP_EXPORT_TIMEOUT, - OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, - OTEL_BLRP_MAX_QUEUE_SIZE, - OTEL_BLRP_SCHEDULE_DELAY, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( - parse_boolean_environment_variable, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OtelComponentTypeValues, -) - -_DEFAULT_SCHEDULE_DELAY_MILLIS = 1000 -_DEFAULT_MAX_EXPORT_BATCH_SIZE = 512 -_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 -_DEFAULT_MAX_QUEUE_SIZE = 2048 -_ENV_VAR_INT_VALUE_ERROR_MESSAGE = "Unable to parse value for %s as integer. Defaulting to %s." -_logger = logging.getLogger(__name__) -_logger.addFilter(DuplicateFilter()) - -_propagate_false_logger = logging.getLogger(__name__ + ".propagate.false") -_propagate_false_logger.propagate = False - - -class LogRecordExportResult(enum.Enum): - SUCCESS = 0 - FAILURE = 1 - - -@deprecated("Use LogRecordExportResult. Since logs are not stable yet this WILL be removed in future releases.") -class LogExportResult(enum.Enum): - SUCCESS = 0 - FAILURE = 1 - - -class LogRecordExporter(abc.ABC): - """Interface for exporting logs. - - Interface to be implemented by services that want to export logs received - in their own format. - - To export data this MUST be registered to the :class:`opentelemetry.sdk._logs.Logger` - using a log processor. - - Important - --------- - The ``export()`` method may raise exceptions (e.g., network errors, - timeouts, serialization errors). It is the responsibility of the - ``LogRecordProcessor`` calling this exporter to handle these exceptions - appropriately to prevent application crashes. See ``LogRecordProcessor`` - for guidance on implementing proper error handling. - """ - - @abc.abstractmethod - def export(self, batch: Sequence[ReadableLogRecord]) -> LogRecordExportResult: - """Exports a batch of logs. - - Args: - batch: The list of ``ReadableLogRecord`` objects to be exported. - - Returns: - The result of the export. - - Raises: - Exception: This method may raise exceptions on network errors, - timeouts, or other failures. Callers (i.e., log processors) - should handle these exceptions to comply with OpenTelemetry - error handling principles. - """ - - @abc.abstractmethod - def shutdown(self): - """Shuts down the exporter. - - Called when the SDK is shut down. - """ - - @abc.abstractmethod - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Hint to ensure that the export of any ``ReadableLogRecord`` objects - the exporter has received prior to the call to ``force_flush`` SHOULD be - completed as soon as possible, preferably before returning from this method. - - Args: - timeout_millis: The maximum amount of time to wait for the flush to - complete, in milliseconds. - - Returns: - ``True`` if the flush completed successfully within the timeout, - ``False`` otherwise. - """ - - -@deprecated("Use LogRecordExporter. Since logs are not stable yet this WILL be removed in future releases.") -class LogExporter(LogRecordExporter): - pass - - -class ConsoleLogRecordExporter(LogRecordExporter): - """Implementation of :class:`LogRecordExporter` that prints log records to the - console. - - This class can be used for diagnostic purposes. It prints the exported - log records to the console STDOUT. - """ - - def __init__( - self, - out: IO = sys.stdout, - formatter: Callable[[ReadableLogRecord], str] = lambda record: record.to_json() + linesep, - ): - self.out = out - self.formatter = formatter - - def export(self, batch: Sequence[ReadableLogRecord]): - for log_record in batch: - self.out.write(self.formatter(log_record)) - self.out.flush() - return LogRecordExportResult.SUCCESS - - def shutdown(self): - pass - - def force_flush(self, timeout_millis: int = 30000) -> bool: - return True - - -@deprecated("Use ConsoleLogRecordExporter. Since logs are not stable yet this WILL be removed in future releases.") -class ConsoleLogExporter(ConsoleLogRecordExporter): - pass - - -class SimpleLogRecordProcessor(LogRecordProcessor): - """Implementation of LogRecordProcessor that exports logs synchronously. - - This processor passes received logs directly to the configured - ``LogRecordExporter`` as soon as they are emitted. - - This class serves as a reference implementation for custom log processors, - demonstrating proper error handling. Note how the ``on_emit`` method wraps - the exporter call in a try/except block to prevent exceptions from - propagating to the application. - """ - - def __init__( - self, - exporter: LogRecordExporter, - *, - meter_provider: MeterProvider | None = None, - ): - self._exporter = exporter - self._shutdown = False - self._metrics = create_processor_metrics( - "logs", - OtelComponentTypeValues.SIMPLE_LOG_PROCESSOR, - meter_provider or get_meter_provider(), - enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ) - - def on_emit(self, log_record: ReadWriteLogRecord): - # Prevent entering a recursive loop. - cnt = get_value(_ON_EMIT_RECURSION_COUNT_KEY) or 0 - # Recursive depth of 3 is sort of arbitrary. It's possible that an Exporter.export call - # emits a log which returns us to this function, but when we call Exporter.export again the log - # is no longer emitted and we exit this recursive loop naturally, a depth of >3 allows 3 - # recursive log calls but exits after because it's likely endless. - if cnt > 3: # pyright: ignore[reportOperatorIssue] - _propagate_false_logger.warning( - "SimpleLogRecordProcessor.on_emit has entered a recursive loop. Dropping log and exiting the loop." - ) - return - token = attach( - set_value( - _SUPPRESS_INSTRUMENTATION_KEY, - True, - set_value(_ON_EMIT_RECURSION_COUNT_KEY, cnt + 1), # pyright: ignore[reportOperatorIssue] - ) - ) - try: - if self._shutdown: - _logger.warning("Processor is already shutdown, ignoring call") - self._metrics.drop_items(1, "already_shutdown") - return - # Convert ReadWriteLogRecord to ReadableLogRecord before exporting - # Note: resource should not be None at this point as it's set during Logger.emit() - resource = log_record.resource if log_record.resource is not None else Resource.create({}) - readable_log_record = ReadableLogRecord( - log_record=log_record.log_record, - resource=resource, - instrumentation_scope=log_record.instrumentation_scope, - limits=log_record.limits, - ) - # Record on submission to the exporter. - self._metrics.finish_items(1) - self._exporter.export((readable_log_record,)) - except Exception: # pylint: disable=broad-exception-caught - _logger.exception("Exception while exporting logs.") - finally: - detach(token) - - def shutdown(self): - self._shutdown = True - self._exporter.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: # pylint: disable=no-self-use - return True - - -class BatchLogRecordProcessor(LogRecordProcessor): - """This is an implementation of LogRecordProcessor which creates batches of - received logs and sends them to the configured LogRecordExporter. - - `BatchLogRecordProcessor` is configurable with the following environment - variables which correspond to constructor parameters: - - - :envvar:`OTEL_BLRP_SCHEDULE_DELAY` - - :envvar:`OTEL_BLRP_MAX_QUEUE_SIZE` - - :envvar:`OTEL_BLRP_MAX_EXPORT_BATCH_SIZE` - - :envvar:`OTEL_BLRP_EXPORT_TIMEOUT` - - All the logic for emitting logs, shutting down etc. resides in the BatchProcessor class. - """ - - def __init__( - self, - exporter: LogRecordExporter, - schedule_delay_millis: float | None = None, - max_export_batch_size: int | None = None, - export_timeout_millis: float | None = None, - max_queue_size: int | None = None, - *, - meter_provider: MeterProvider | None = None, - ): - if max_queue_size is None: - max_queue_size = BatchLogRecordProcessor._default_max_queue_size() - - if schedule_delay_millis is None: - schedule_delay_millis = BatchLogRecordProcessor._default_schedule_delay_millis() - - if max_export_batch_size is None: - max_export_batch_size = BatchLogRecordProcessor._default_max_export_batch_size() - # Not used. No way currently to pass timeout to export. - if export_timeout_millis is None: - export_timeout_millis = BatchLogRecordProcessor._default_export_timeout_millis() - - BatchLogRecordProcessor._validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size) - # Initializes BatchProcessor - self._batch_processor = BatchProcessor( - exporter, - schedule_delay_millis, - max_export_batch_size, - export_timeout_millis, - max_queue_size, - "Log", - create_processor_metrics( - "logs", - OtelComponentTypeValues.BATCHING_LOG_PROCESSOR, - meter_provider or get_meter_provider(), - capacity=max_queue_size, - enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ), - ) - - def on_emit(self, log_record: ReadWriteLogRecord) -> None: - # Convert ReadWriteLogRecord to ReadableLogRecord before passing to BatchProcessor - # Note: resource should not be None at this point as it's set during Logger.emit() - resource = log_record.resource if log_record.resource is not None else Resource.create({}) - # Shallow copy the API log record to break the reference to the potentially large context - # while keeping the original context intact for other processors. - api_log_record = copy.copy(log_record.log_record) - api_log_record.context = Context() - - readable_log_record = ReadableLogRecord( - log_record=api_log_record, - resource=resource, - instrumentation_scope=log_record.instrumentation_scope, - limits=log_record.limits, - ) - return self._batch_processor.emit(readable_log_record) - - def shutdown(self): - return self._batch_processor.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: - return self._batch_processor.force_flush(timeout_millis) - - @staticmethod - def _default_max_queue_size(): - try: - return int(environ.get(OTEL_BLRP_MAX_QUEUE_SIZE, _DEFAULT_MAX_QUEUE_SIZE)) - except ValueError: - _logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BLRP_MAX_QUEUE_SIZE, - _DEFAULT_MAX_QUEUE_SIZE, - ) - return _DEFAULT_MAX_QUEUE_SIZE - - @staticmethod - def _default_schedule_delay_millis(): - try: - return int(environ.get(OTEL_BLRP_SCHEDULE_DELAY, _DEFAULT_SCHEDULE_DELAY_MILLIS)) - except ValueError: - _logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BLRP_SCHEDULE_DELAY, - _DEFAULT_SCHEDULE_DELAY_MILLIS, - ) - return _DEFAULT_SCHEDULE_DELAY_MILLIS - - @staticmethod - def _default_max_export_batch_size(): - try: - return int( - environ.get( - OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, - _DEFAULT_MAX_EXPORT_BATCH_SIZE, - ) - ) - except ValueError: - _logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BLRP_MAX_EXPORT_BATCH_SIZE, - _DEFAULT_MAX_EXPORT_BATCH_SIZE, - ) - return _DEFAULT_MAX_EXPORT_BATCH_SIZE - - @staticmethod - def _default_export_timeout_millis(): - try: - return int(environ.get(OTEL_BLRP_EXPORT_TIMEOUT, _DEFAULT_EXPORT_TIMEOUT_MILLIS)) - except ValueError: - _logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BLRP_EXPORT_TIMEOUT, - _DEFAULT_EXPORT_TIMEOUT_MILLIS, - ) - return _DEFAULT_EXPORT_TIMEOUT_MILLIS - - @staticmethod - def _validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size): - if max_queue_size <= 0: - raise ValueError("max_queue_size must be a positive integer.") - - if schedule_delay_millis <= 0: - raise ValueError("schedule_delay_millis must be positive.") - - if max_export_batch_size <= 0: - raise ValueError("max_export_batch_size must be a positive integer.") - - if max_export_batch_size > max_queue_size: - raise ValueError("max_export_batch_size must be less than or equal to max_queue_size.") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py deleted file mode 100644 index 2ece1662393..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/_internal/export/in_memory_log_exporter.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import collections.abc -import threading - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry.sdk._logs import ReadableLogRecord -from opentelemetry.agent._vendor.opentelemetry.sdk._logs.export import ( - LogRecordExporter, - LogRecordExportResult, -) - - -class InMemoryLogRecordExporter(LogRecordExporter): - """Implementation of :class:`.LogRecordExporter` that stores logs in memory. - - This class can be used for testing purposes. It stores the exported logs - in a list in memory that can be retrieved using the - :meth:`.get_finished_logs` method. - """ - - def __init__(self): - self._logs = [] - self._lock = threading.Lock() - self._stopped = False - - def clear(self) -> None: - with self._lock: - self._logs.clear() - - def get_finished_logs(self) -> tuple[ReadableLogRecord, ...]: - with self._lock: - return tuple(self._logs) - - def export(self, batch: collections.abc.Sequence[ReadableLogRecord]) -> LogRecordExportResult: - if self._stopped: - return LogRecordExportResult.FAILURE - with self._lock: - self._logs.extend(batch) - return LogRecordExportResult.SUCCESS - - def shutdown(self) -> None: - self._stopped = True - - def force_flush(self, timeout_millis: int = 30000) -> bool: - return True - - -@deprecated("Use InMemoryLogRecordExporter. Since logs are not stable yet this WILL be removed in future releases.") -class InMemoryLogExporter(InMemoryLogRecordExporter): - pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py deleted file mode 100644 index 323ccbd3ac4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_logs/export/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal.export import ( - BatchLogRecordProcessor, - ConsoleLogExporter, - ConsoleLogRecordExporter, - LogExporter, - LogExportResult, - LogRecordExporter, - LogRecordExportResult, - SimpleLogRecordProcessor, -) - -# The point module is not in the export directory to avoid a circular import. -from opentelemetry.agent._vendor.opentelemetry.sdk._logs._internal.export.in_memory_log_exporter import ( - InMemoryLogExporter, - InMemoryLogRecordExporter, -) - -__all__ = [ - "BatchLogRecordProcessor", - "ConsoleLogExporter", - "ConsoleLogRecordExporter", - "InMemoryLogExporter", - "InMemoryLogRecordExporter", - "LogExportResult", - "LogExporter", - "LogRecordExportResult", - "LogRecordExporter", - "SimpleLogRecordProcessor", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py deleted file mode 100644 index daddc95be68..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/__init__.py +++ /dev/null @@ -1,237 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import collections -import enum -import inspect -import logging -import os -import threading -import time -import weakref -from abc import abstractmethod -from typing import ( - Generic, - Protocol, - TypeVar, -) - -from opentelemetry.agent._vendor.opentelemetry.context import ( - _SUPPRESS_INSTRUMENTATION_KEY, - attach, - detach, - set_value, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal._processor_metrics import ( - ProcessorMetricsT, -) -from opentelemetry.agent._vendor.opentelemetry.util._once import Once - - -class DuplicateFilter(logging.Filter): - """Filter that can be applied to internal `logger`'s. - - Currently applied to `logger`s on the export logs path to prevent endlessly logging the same log - in cases where logging itself is failing.""" - - def filter(self, record): - current_log = ( - record.module, - record.levelno, - record.msg, - # We need to pick a time longer than the OTLP LogExporter timeout - # which defaults to 10 seconds, but not pick something so long that - # it filters out useful logs. - time.time() // 20, - ) - if current_log != getattr(self, "last_log", None): - self.last_log = current_log # pylint: disable=attribute-defined-outside-init - return True - # False means python's `logging` module will no longer process this log. - return False - - -class BatchExportStrategy(enum.Enum): - EXPORT_ALL = 0 - EXPORT_WHILE_BATCH_EXCEEDS_THRESHOLD = 1 - EXPORT_AT_LEAST_ONE_BATCH = 2 - - -Telemetry = TypeVar("Telemetry") - - -class Exporter(Protocol[Telemetry]): - @abstractmethod - def export(self, batch: list[Telemetry], /): - raise NotImplementedError - - @abstractmethod - def shutdown(self): - raise NotImplementedError - - -_logger = logging.getLogger(__name__) -_logger.addFilter(DuplicateFilter()) - - -class BatchProcessor(Generic[Telemetry]): - """This class can be used with exporter's that implement the above - Exporter interface to buffer and send telemetry in batch through - the exporter.""" - - def __init__( - self, - exporter: Exporter[Telemetry], - schedule_delay_millis: float, - max_export_batch_size: int, - export_timeout_millis: float, - max_queue_size: int, - exporting: str, - metrics: ProcessorMetricsT, - ): - self._bsp_reset_once = Once() - self._exporter = exporter - self._max_queue_size = max_queue_size - self._schedule_delay_millis = schedule_delay_millis - self._schedule_delay = schedule_delay_millis / 1e3 - self._max_export_batch_size = max_export_batch_size - # Not used. No way currently to pass timeout to export. - # TODO(https://github.com/open-telemetry/opentelemetry-python/issues/4555): figure out what this should do. - self._export_timeout_millis = export_timeout_millis - # Deque is thread safe. - self._queue = collections.deque([], max_queue_size) - self._worker_thread = threading.Thread( - name=f"OtelBatch{exporting}RecordProcessor", - target=self.worker, - daemon=True, - ) - self._exporting = exporting - - self._shutdown = False - self._shutdown_timeout_exceeded = False - self._export_lock = threading.Lock() - self._worker_awaken = threading.Event() - self._worker_thread.start() - if hasattr(os, "register_at_fork"): - weak_reinit = weakref.WeakMethod(self._at_fork_reinit) - - def _after_in_child() -> None: - if reinit := weak_reinit(): - reinit() - - os.register_at_fork(after_in_child=_after_in_child) - self._pid = os.getpid() - - metrics.register_queue_size(lambda: len(self._queue)) - self._metrics = metrics - - def _should_export_batch(self, batch_strategy: BatchExportStrategy, num_iterations: int) -> bool: - if not self._queue or self._shutdown_timeout_exceeded: - return False - # Always continue to export while queue length exceeds max batch size. - if len(self._queue) >= self._max_export_batch_size: - return True - if batch_strategy is BatchExportStrategy.EXPORT_ALL: - return True - if batch_strategy is BatchExportStrategy.EXPORT_AT_LEAST_ONE_BATCH: - return num_iterations == 0 - return False - - def _at_fork_reinit(self): - self._export_lock = threading.Lock() - self._worker_awaken = threading.Event() - self._queue.clear() - self._worker_thread = threading.Thread( - name=f"OtelBatch{self._exporting}RecordProcessor", - target=self.worker, - daemon=True, - ) - self._worker_thread.start() - self._pid = os.getpid() - - def worker(self): - while not self._shutdown: - # Lots of strategies in the spec for setting next timeout. - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#batching-processor. - # Shutdown will interrupt this sleep. Emit will interrupt this sleep only if the queue is bigger then threshold. - sleep_interrupted = self._worker_awaken.wait(self._schedule_delay) - if self._shutdown: - break - self._export( - BatchExportStrategy.EXPORT_WHILE_BATCH_EXCEEDS_THRESHOLD - if sleep_interrupted - else BatchExportStrategy.EXPORT_AT_LEAST_ONE_BATCH - ) - self._worker_awaken.clear() - self._export(BatchExportStrategy.EXPORT_ALL) - - def _export(self, batch_strategy: BatchExportStrategy) -> None: - with self._export_lock: - iteration = 0 - # We could see concurrent export calls from worker and force_flush. We call _should_export_batch - # once the lock is obtained to see if we still need to make the requested export. - while self._should_export_batch(batch_strategy, iteration): - iteration += 1 - token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) - count = min( - self._max_export_batch_size, - len(self._queue), - ) - # Oldest records are at the back, so pop from there. - batch = [self._queue.pop() for _ in range(count)] - # Record on submission to the exporter. - self._metrics.finish_items(count) - try: - self._exporter.export(batch) - except Exception: # pylint: disable=broad-exception-caught - _logger.exception("Exception while exporting %s.", self._exporting) - detach(token) - - def emit(self, data: Telemetry) -> None: - if self._shutdown: - _logger.info("Shutdown called, ignoring %s.", self._exporting) - self._metrics.drop_items(1, "already_shutdown") - return - if self._pid != os.getpid(): - self._bsp_reset_once.do_once(self._at_fork_reinit) - if len(self._queue) == self._max_queue_size: - _logger.warning("Queue full, dropping %s.", self._exporting) - self._metrics.drop_items(1) - # This will drop a log from the right side if the queue is at _max_queue_size. - self._queue.appendleft(data) - if len(self._queue) >= self._max_export_batch_size and not self._worker_awaken.is_set(): - self._worker_awaken.set() - - def shutdown(self, timeout_millis: int = 30000): - if self._shutdown: - return - shutdown_should_end = time.time() + (timeout_millis / 1000) - # Causes emit to reject telemetry and makes force_flush a no-op. - self._shutdown = True - # Interrupts sleep in the worker if it's sleeping. - self._worker_awaken.set() - self._worker_thread.join(timeout_millis / 1000) - # Stops worker thread from calling export again if queue is still not empty. - self._shutdown_timeout_exceeded = True - # We want to shutdown immediately only if we already waited `timeout_secs`. - # Otherwise we pass the remaining timeout to the exporter. - # Some exporter's shutdown support a timeout param. - if "timeout_millis" in inspect.getfullargspec(self._exporter.shutdown).args: - remaining_millis = (shutdown_should_end - time.time()) * 1000 - self._exporter.shutdown(timeout_millis=max(0, remaining_millis)) # type: ignore - else: - self._exporter.shutdown() - # Worker thread **should** be finished at this point, because we called shutdown on the exporter, - # and set shutdown_is_occuring to prevent further export calls. It's possible that a single export - # call is ongoing and the thread isn't finished. In this case we will return instead of waiting on - # the thread to finish. - - # TODO: Fix force flush so the timeout is used https://github.com/open-telemetry/opentelemetry-python/issues/4568. - def force_flush(self, timeout_millis: int | None = None) -> bool: - if self._shutdown: - return False - # Blocking call to export. - self._export(BatchExportStrategy.EXPORT_ALL) - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py deleted file mode 100644 index 441ccdcafd2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/_shared_internal/_processor_metrics.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections import Counter -from collections.abc import Callable -from typing import Literal, Protocol - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, MeterProvider, Observation -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OTEL_COMPONENT_NAME, - OTEL_COMPONENT_TYPE, - OtelComponentTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( - OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE, - OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE, - create_otel_sdk_processor_log_processed, - create_otel_sdk_processor_log_queue_capacity, - create_otel_sdk_processor_span_processed, - create_otel_sdk_processor_span_queue_capacity, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE - -_component_counter = Counter() - - -class ProcessorMetricsT(Protocol): - def register_queue_size(self, get_queue_size: Callable[[], int]) -> None: ... - - def drop_items(self, count: int, error_type: str = "queue_full") -> None: ... - - def finish_items(self, count: int) -> None: ... - - -class NoOpProcessorMetrics: - def register_queue_size(self, get_queue_size: Callable[[], int]) -> None: - pass - - def drop_items(self, count: int, error_type: str = "queue_full") -> None: - pass - - def finish_items(self, count: int) -> None: - pass - - -class ProcessorMetrics: - def __init__( - self, - signal: Literal["traces", "logs"], - component_type: OtelComponentTypeValues, - meter_provider: MeterProvider, - *, - capacity: int | None = None, - ) -> None: - self._signal = signal - meter = meter_provider.get_meter("opentelemetry-sdk") - self._meter = meter - - count = _component_counter[component_type.value] - _component_counter[component_type.value] = count + 1 - - self._standard_attrs = { - OTEL_COMPONENT_TYPE: component_type.value, - OTEL_COMPONENT_NAME: f"{component_type.value}/{count}", - } - - self._dropped_attrs = { - **self._standard_attrs, - ERROR_TYPE: "queue_full", - } - - self._already_shutdown_attrs = { - **self._standard_attrs, - ERROR_TYPE: "already_shutdown", - } - - if signal == "traces": - create_processed = create_otel_sdk_processor_span_processed - create_queue_capacity = create_otel_sdk_processor_span_queue_capacity - else: - create_processed = create_otel_sdk_processor_log_processed - create_queue_capacity = create_otel_sdk_processor_log_queue_capacity - - self._processed = create_processed(meter) - - if capacity is not None: - self._queue_capacity = create_queue_capacity(meter) - self._queue_capacity.add(capacity, self._standard_attrs) - - def register_queue_size(self, get_queue_size: Callable[[], int]) -> None: - def record_queue_size( - _options: CallbackOptions, - ) -> tuple[Observation]: - return (Observation(get_queue_size(), self._standard_attrs),) - - if self._signal == "traces": - queue_size_name = OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE - queue_size_description = "The number of spans in the queue of a given instance of an SDK span processor." - queue_size_unit = "{span}" - else: - queue_size_name = OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE - queue_size_description = "The number of logs in the queue of a given instance of an SDK log processor." - queue_size_unit = "{log}" - - self._meter.create_observable_up_down_counter( - queue_size_name, - callbacks=(record_queue_size,), - description=queue_size_description, - unit=queue_size_unit, - ) - - def drop_items(self, count: int, error_type: str = "queue_full") -> None: - if error_type == "already_shutdown": - self._processed.add(count, self._already_shutdown_attrs) - else: - self._processed.add(count, self._dropped_attrs) - - def finish_items(self, count: int) -> None: - self._processed.add(count, self._standard_attrs) - - -def create_processor_metrics( - signal: Literal["traces", "logs"], - component_type: OtelComponentTypeValues, - meter_provider: MeterProvider, - *, - capacity: int | None = None, - enabled: bool, -) -> ProcessorMetricsT: - if not enabled: - return NoOpProcessorMetrics() - - return ProcessorMetrics( - signal, - component_type, - meter_provider, - capacity=capacity, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py deleted file mode 100644 index 303f62924bc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/__init__.py +++ /dev/null @@ -1,863 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -OTEL_SDK_DISABLED = "OTEL_SDK_DISABLED" -""" -.. envvar:: OTEL_SDK_DISABLED - -The :envvar:`OTEL_SDK_DISABLED` environment variable disables the SDK for all signals -Default: "false" -""" - -OTEL_CONFIG_FILE = "OTEL_CONFIG_FILE" -""" -.. envvar:: OTEL_CONFIG_FILE - -The :envvar:`OTEL_CONFIG_FILE` environment variable points the SDK at a -declarative configuration file (YAML or JSON). When set, the file is the -sole source for SDK construction. Spec-defined ``OTEL_*`` variables with -schema equivalents are ignored. Env vars may still be read indirectly by -components the file enables (e.g. resource detectors) and via -``${env:VAR}`` substitution inside the file. - -Python-implementation extensions outside the spec (``OTEL_PYTHON_*`` -variables such as ``OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED`` or -:envvar:`OTEL_PYTHON_TRACER_CONFIGURATOR`) are also bypassed when -:envvar:`OTEL_CONFIG_FILE` is set, because the env-var initialisation path -is skipped entirely in favour of the declarative file. Honouring these -alongside a config file is tracked separately. - -See the OpenTelemetry declarative configuration specification for details. -""" - -OTEL_RESOURCE_ATTRIBUTES = "OTEL_RESOURCE_ATTRIBUTES" -""" -.. envvar:: OTEL_RESOURCE_ATTRIBUTES - -The :envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable allows resource -attributes to be passed to the SDK at process invocation. The attributes from -:envvar:`OTEL_RESOURCE_ATTRIBUTES` are merged with those passed to -`Resource.create`, meaning :envvar:`OTEL_RESOURCE_ATTRIBUTES` takes *lower* -priority. Attributes should be in the format ``key1=value1,key2=value2``. -Additional details are available `in the specification -`__. - -.. code-block:: console - - $ OTEL_RESOURCE_ATTRIBUTES="service.name=shoppingcard,will_be_overridden=foo" python - <`__. -""" - -OTEL_EXPORTER_OTLP_TIMEOUT = "OTEL_EXPORTER_OTLP_TIMEOUT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TIMEOUT - -The :envvar:`OTEL_EXPORTER_OTLP_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will wait for each batch export. -Default: 10 -""" - -OTEL_EXPORTER_OTLP_ENDPOINT = "OTEL_EXPORTER_OTLP_ENDPOINT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_ENDPOINT - -The :envvar:`OTEL_EXPORTER_OTLP_ENDPOINT` target to which the exporter is going to send spans or metrics. -The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. -A scheme of https indicates a secure connection and takes precedence over the insecure configuration setting. -Default: "http://localhost:4317" -""" - -OTEL_EXPORTER_OTLP_INSECURE = "OTEL_EXPORTER_OTLP_INSECURE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_INSECURE - -The :envvar:`OTEL_EXPORTER_OTLP_INSECURE` represents whether to enable client transport security for gRPC requests. -A scheme of https takes precedence over this configuration setting. -Default: False -""" - -OTEL_EXPORTER_OTLP_TRACES_INSECURE = "OTEL_EXPORTER_OTLP_TRACES_INSECURE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_INSECURE - -The :envvar:`OTEL_EXPORTER_OTLP_TRACES_INSECURE` represents whether to enable client transport security -for gRPC requests for spans. A scheme of https takes precedence over the this configuration setting. -Default: False -""" - - -OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - -The :envvar:`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` target to which the span exporter is going to send spans. -The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. -A scheme of https indicates a secure connection and takes precedence over this configuration setting. -""" - -OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` target to which the metrics exporter is going to send metrics. -The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. -A scheme of https indicates a secure connection and takes precedence over this configuration setting. -""" - -OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_ENDPOINT - -The :envvar:`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` target to which the log exporter is going to send logs. -The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path. -A scheme of https indicates a secure connection and takes precedence over this configuration setting. -""" - -_OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_LOGS_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` to the grpc OTLP Log exporter, -Entry point providers should implement the following: - -.. code-block:: python - - import grpc - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def channel_credential_provider() -> grpc.ChannelCredentials: - -Note: This environment variable is experimental and subject to change. -""" - -_OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_LOGS_CREDENTIAL_PROVIDER` provides `requests.Session` for the HTTP OTLP Log exporter. -Entry point providers should implement the following: - -.. code-block:: python - - import requests - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def request_session_provder() -> requests.Session: - -Note: This environment variable is experimental and subject to change. -""" -_OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_CREDENTIAL_PROVIDER` provides `requests.Session` for all HTTP OTLP exporters. -Entry point providers should implement the following: - -.. code-block:: python - - import requests - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def request_session_provder() -> requests.Session: - -Note: This environment variable is experimental and subject to change. -""" -_OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` for all GRPC OTLP exporters. -Entry point providers should implement the following: - -.. code-block:: python - - import grpc - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def channel_credential_provider() -> grpc.ChannelCredentials: - -Note: This environment variable is experimental and subject to change. -""" -_OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_TRACES_CREDENTIAL_PROVIDER` provides `requests.Session` to the HTTP OTLP Span exporter. -Entry point providers should implement the following: - -.. code-block:: python - - import requests - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def request_session_provder() -> requests.Session: - -Note: This environment variable is experimental and subject to change. -""" -_OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER" -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_TRACES_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` to the GRPC OTLP Span exporter. -Entry point providers should implement the following: - -.. code-block:: python - - import grpc - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def channel_credential_provider() -> grpc.ChannelCredentials: - -Note: This environment variable is experimental and subject to change. -""" -_OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER = ( - "OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER" -) -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_HTTP_METRICS_CREDENTIAL_PROVIDER` provides `requests.Session` to the HTTP OTLP Metric exporter. -Entry point providers should implement the following: - -.. code-block:: python - - import requests - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def request_session_provder() -> requests.Session: - -Note: This environment variable is experimental and subject to change. -""" -_OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER = ( - "OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER" -) -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_METRICS_CREDENTIAL_PROVIDER` provides `grpc.ChannelCredentials` to the GRPC OTLP Metric exporter. -Entry point providers should implement the following: - -.. code-block:: python - - import grpc - - # Add a reference to this function under the `opentelemetry_otlp_credential_provider` entry point. - def channel_credential_provider() -> grpc.ChannelCredentials: - -Note: This environment variable is experimental and subject to change. -""" - -_OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES = "OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES" -""" -.. envvar:: OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES - -The :envvar:`OTEL_PYTHON_EXPORTER_OTLP_GRPC_RETRYABLE_ERROR_CODES` stores a comma-separated list of human-readable -gRPC error codes that are considered retryable for the OTLP gRPC exporters (e.g. `UNAVAILABLE, DEADLINE_EXCEEDED`). -Supported error codes are defined in `grpc.StatusCode` and are parsed in a case-insensitive manner. - -Note: This environment variable is experimental and subject to change. -""" - -OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE = "OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE - -The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` stores the path to the certificate file for -TLS credentials of gRPC client for traces. Should only be used for a secure connection for tracing. -""" - -OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE = "OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE` stores the path to the certificate file for -TLS credentials of gRPC client for metrics. Should only be used for a secure connection for exporting metrics. -""" - -OTEL_EXPORTER_OTLP_CLIENT_KEY = "OTEL_EXPORTER_OTLP_CLIENT_KEY" -""" -.. envvar:: OTEL_EXPORTER_OTLP_CLIENT_KEY - -The :envvar:`OTEL_EXPORTER_OTLP_CLIENT_KEY` stores the path to the client private key to use -in mTLS communication in PEM format. -""" - -OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY = "OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY - -The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY` stores the path to the client private key to use -in mTLS communication in PEM format for traces. -""" - -OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY = "OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY` stores the path to the client private key to use -in mTLS communication in PEM format for metrics. -""" - -OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY = "OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY - -The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY` stores the path to the client private key to use -in mTLS communication in PEM format for logs. -""" - -OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE - -The :envvar:`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for -clients private key to use in mTLS communication in PEM format. -""" - -OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE - -The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for -clients private key to use in mTLS communication in PEM format for traces. -""" - -OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for -clients private key to use in mTLS communication in PEM format for metrics. -""" - -OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE - -The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for -clients private key to use in mTLS communication in PEM format for logs. -""" - -OTEL_EXPORTER_OTLP_TRACES_HEADERS = "OTEL_EXPORTER_OTLP_TRACES_HEADERS" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_HEADERS - -The :envvar:`OTEL_EXPORTER_OTLP_TRACES_HEADERS` contains the key-value pairs to be used as headers for spans -associated with gRPC or HTTP requests. -""" - -OTEL_EXPORTER_OTLP_METRICS_HEADERS = "OTEL_EXPORTER_OTLP_METRICS_HEADERS" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_HEADERS - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_HEADERS` contains the key-value pairs to be used as headers for metrics -associated with gRPC or HTTP requests. -""" - -OTEL_EXPORTER_OTLP_LOGS_HEADERS = "OTEL_EXPORTER_OTLP_LOGS_HEADERS" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_HEADERS - -The :envvar:`OTEL_EXPORTER_OTLP_LOGS_HEADERS` contains the key-value pairs to be used as headers for logs -associated with gRPC or HTTP requests. -""" - -OTEL_EXPORTER_OTLP_TRACES_COMPRESSION = "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_COMPRESSION - -Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the span -exporter. If both are present, this takes higher precedence. -""" - -OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = "OTEL_EXPORTER_OTLP_METRICS_COMPRESSION" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_COMPRESSION - -Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the metric -exporter. If both are present, this takes higher precedence. -""" - -OTEL_EXPORTER_OTLP_LOGS_COMPRESSION = "OTEL_EXPORTER_OTLP_LOGS_COMPRESSION" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_COMPRESSION - -Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the log -exporter. If both are present, this takes higher precedence. -""" - -OTEL_EXPORTER_OTLP_TRACES_TIMEOUT = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_TRACES_TIMEOUT - -The :envvar:`OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will -wait for each batch export for spans. -Default: 10 -""" - -OTEL_EXPORTER_OTLP_METRICS_TIMEOUT = "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_TIMEOUT - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will -wait for each batch export for metrics. -Default: 10 -""" - -OTEL_EXPORTER_OTLP_METRICS_INSECURE = "OTEL_EXPORTER_OTLP_METRICS_INSECURE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_INSECURE - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_INSECURE` represents whether to enable client transport security -for gRPC requests for metrics. A scheme of https takes precedence over the this configuration setting. -Default: False -""" - -OTEL_EXPORTER_OTLP_LOGS_INSECURE = "OTEL_EXPORTER_OTLP_LOGS_INSECURE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_INSECURE - -The :envvar:`OTEL_EXPORTER_OTLP_LOGS_INSECURE` represents whether to enable client transport security -for gRPC requests for logs. A scheme of https takes precedence over the this configuration setting. -Default: False -""" - -OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = "OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE - -The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE` stores the path to the certificate file for -TLS credentials of gRPC client for logs. Should only be used for a secure connection for logs. -""" - -OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT" -""" -.. envvar:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT - -The :envvar:`OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` is the maximum time (in seconds) the OTLP exporter will -wait for each batch export for logs. -Default: 10 -""" - -OTEL_SERVICE_NAME = "OTEL_SERVICE_NAME" -""" -.. envvar:: OTEL_SERVICE_NAME - -Convenience environment variable for setting the service name resource attribute. -The following two environment variables have the same effect - -.. code-block:: console - - OTEL_SERVICE_NAME=my-python-service - - OTEL_RESOURCE_ATTRIBUTES=service.name=my-python-service - - -If both are set, :envvar:`OTEL_SERVICE_NAME` takes precedence. -""" - - -_OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED = "OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED" -""" -.. envvar:: OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED - -The :envvar:`OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED` environment variable allows users to -enable/disable the auto instrumentation for the python logging module. -Default: False - -Note: Logs SDK and its related settings are experimental. - -.. warning:: - - This option is deprecated, instead you should install `opentelemetry-instrumentation-logging`. -""" - - -OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE = "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment -variable allows users to set the default aggregation temporality policy to use -on the basis of instrument kind. The valid (case-insensitive) values are: - -``CUMULATIVE``: Use ``CUMULATIVE`` aggregation temporality for all instrument kinds. -``DELTA``: Use ``DELTA`` aggregation temporality for ``Counter``, ``Asynchronous Counter`` and ``Histogram``. -Use ``CUMULATIVE`` aggregation temporality for ``UpDownCounter`` and ``Asynchronous UpDownCounter``. -``LOWMEMORY``: Use ``DELTA`` aggregation temporality for ``Counter`` and ``Histogram``. -Use ``CUMULATIVE`` aggregation temporality for ``UpDownCounter``, ``AsynchronousCounter`` and ``Asynchronous UpDownCounter``. -""" - -OTEL_METRIC_EXPORT_INTERVAL = "OTEL_METRIC_EXPORT_INTERVAL" -""" -.. envvar:: OTEL_METRIC_EXPORT_INTERVAL - -The :envvar:`OTEL_METRIC_EXPORT_INTERVAL` is the time interval (in milliseconds) between the start of two export attempts. -""" - -OTEL_METRIC_EXPORT_TIMEOUT = "OTEL_METRIC_EXPORT_TIMEOUT" -""" -.. envvar:: OTEL_METRIC_EXPORT_TIMEOUT - -The :envvar:`OTEL_METRIC_EXPORT_TIMEOUT` is the maximum allowed time (in milliseconds) to export data. -""" - -OTEL_METRICS_EXEMPLAR_FILTER = "OTEL_METRICS_EXEMPLAR_FILTER" -""" -.. envvar:: OTEL_METRICS_EXEMPLAR_FILTER - -The :envvar:`OTEL_METRICS_EXEMPLAR_FILTER` is the filter for which measurements can become Exemplars. -""" - -OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION = "OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION" -""" -.. envvar:: OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION - -The :envvar:`OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` is the default aggregation to use for histogram instruments. -""" - -OTEL_EXPERIMENTAL_RESOURCE_DETECTORS = "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS" -""" -.. envvar:: OTEL_EXPERIMENTAL_RESOURCE_DETECTORS - -The :envvar:`OTEL_EXPERIMENTAL_RESOURCE_DETECTORS` is a comma-separated string -of names of resource detectors. These names must be the same as the names of -entry points for the ```opentelemetry_resource_detector``` entry point. This is an -experimental feature and the name of this variable and its behavior can change -in a non-backwards compatible way. - -Detectors are run in the order they are listed and their attributes are merged -in that order, with later detectors taking precedence over earlier ones on -conflicting keys. The ``otel`` detector (which reads -:envvar:`OTEL_RESOURCE_ATTRIBUTES` and :envvar:`OTEL_SERVICE_NAME`) is always -appended last unless explicitly placed elsewhere in the list, ensuring -environment variable attributes take highest priority among detectors. -""" - -OTEL_EXPORTER_PROMETHEUS_HOST = "OTEL_EXPORTER_PROMETHEUS_HOST" -""" -.. envvar:: OTEL_EXPORTER_PROMETHEUS_HOST - -The :envvar:`OTEL_EXPORTER_PROMETHEUS_HOST` environment variable configures the host used by -the Prometheus exporter. -Default: "localhost" - -This is an experimental environment variable and the name of this variable and its behavior can -change in a non-backwards compatible way. -""" - -OTEL_EXPORTER_PROMETHEUS_PORT = "OTEL_EXPORTER_PROMETHEUS_PORT" -""" -.. envvar:: OTEL_EXPORTER_PROMETHEUS_PORT - -The :envvar:`OTEL_EXPORTER_PROMETHEUS_PORT` environment variable configures the port used by -the Prometheus exporter. -Default: 9464 - -This is an experimental environment variable and the name of this variable and its behavior can -change in a non-backwards compatible way. -""" - -OTEL_PYTHON_TRACER_CONFIGURATOR = "OTEL_PYTHON_TRACER_CONFIGURATOR" -""" -.. envvar:: OTEL_PYTHON_TRACER_CONFIGURATOR - -The :envvar:`OTEL_PYTHON_TRACER_CONFIGURATOR` environment variable allows users to set a -custom Tracer Configurator function. -Default: opentelemetry.sdk.trace._default_tracer_configurator - -This is an experimental environment variable and the name of this variable and its behavior can -change in a non-backwards compatible way. -""" - -OTEL_PYTHON_METER_CONFIGURATOR = "OTEL_PYTHON_METER_CONFIGURATOR" -""" -.. envvar:: OTEL_PYTHON_METER_CONFIGURATOR - -The :envvar:`OTEL_PYTHON_METER_CONFIGURATOR` environment variable allows users to set a -custom Meter Configurator function. -Default: opentelemetry.sdk.metrics._internal._default_meter_configurator - -This is an experimental environment variable and the name of this variable and its behavior can -change in a non-backwards compatible way. -""" - -OTEL_PYTHON_LOGGER_CONFIGURATOR = "OTEL_PYTHON_LOGGER_CONFIGURATOR" -""" -.. envvar:: OTEL_PYTHON_LOGGER_CONFIGURATOR - -The :envvar:`OTEL_PYTHON_LOGGER_CONFIGURATOR` environment variable allows users to set a -custom Logger Configurator function. -Default: opentelemetry.sdk._logs._internal._default_logger_configurator - -This is an experimental environment variable and the name of this variable and its behavior can -change in a non-backwards compatible way. -""" - -OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED = "OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED" -""" -.. envvar:: OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED - -The :envvar:`OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED` environment variable enables -metrics emitted by the SDK about its own internal state. -Default: "false" -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py deleted file mode 100644 index 0f0fa930a62..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/environment_variables/_internal.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from logging import getLogger -from os import environ - -_logger = getLogger(__name__) - - -def parse_boolean_environment_variable(environment_variable: str, default: bool = False) -> bool: - value = environ.get(environment_variable) - if value is None: - return default - - match value.strip().lower(): - case "true": - return True - case "false": - return False - case _: - _logger.warning( - "Invalid value for %s: %r. Expected 'true' or 'false'.", - environment_variable, - value, - ) - return default diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py deleted file mode 100644 index 1a4c037548d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/error_handler/__init__.py +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -Global Error Handler - -This module provides a global error handler and an interface that allows -error handlers to be registered with the global error handler via entry points. -A default error handler is also provided. - -To use this feature, users can create an error handler that is registered -using the ``opentelemetry_error_handler`` entry point. A class is to be -registered in this entry point, this class must inherit from the -``opentelemetry.sdk.error_handler.ErrorHandler`` class and implement the -corresponding ``handle`` method. This method will receive the exception object -that is to be handled. The error handler class should also inherit from the -exception classes it wants to handle. For example, this would be an error -handler that handles ``ZeroDivisionError``: - -.. code:: python - - from opentelemetry.sdk.error_handler import ErrorHandler - from logging import getLogger - - logger = getLogger(__name__) - - - class ErrorHandler0(ErrorHandler, ZeroDivisionError): - - def _handle(self, error: Exception, *args, **kwargs): - - logger.exception("ErrorHandler0 handling a ZeroDivisionError") - -To use the global error handler, just instantiate it as a context manager where -you want exceptions to be handled: - - -.. code:: python - - from opentelemetry.sdk.error_handler import GlobalErrorHandler - - with GlobalErrorHandler(): - 1 / 0 - -If the class of the exception raised in the scope of the ``GlobalErrorHandler`` -object is not parent of any registered error handler, then the default error -handler will handle the exception. This default error handler will only log the -exception to standard logging, the exception won't be raised any further. -""" - -from abc import ABC, abstractmethod -from logging import getLogger - -from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import entry_points - -logger = getLogger(__name__) - - -class ErrorHandler(ABC): - @abstractmethod - def _handle(self, error: Exception, *args, **kwargs): - """ - Handle an exception - """ - - -class _DefaultErrorHandler(ErrorHandler): - """ - Default error handler - - This error handler just logs the exception using standard logging. - """ - - # pylint: disable=useless-return - def _handle(self, error: Exception, *args, **kwargs): - logger.exception("Error handled by default error handler: ") - - -class GlobalErrorHandler: - """ - Global error handler - - This is a singleton class that can be instantiated anywhere to get the - global error handler. This object provides a handle method that receives - an exception object that will be handled by the registered error handlers. - """ - - _instance = None - - def __new__(cls) -> "GlobalErrorHandler": - if cls._instance is None: - cls._instance = super().__new__(cls) - - return cls._instance - - def __enter__(self): - pass - - # pylint: disable=no-self-use - def __exit__(self, exc_type, exc_value, traceback): - if exc_value is None: - return None - - plugin_handled = False - - error_handler_entry_points = entry_points(group="opentelemetry_error_handler") - - for error_handler_entry_point in error_handler_entry_points: - error_handler_class = error_handler_entry_point.load() - - if issubclass(error_handler_class, exc_value.__class__): - try: - error_handler_class()._handle(exc_value) - plugin_handled = True - - # pylint: disable=broad-exception-caught - except Exception as error_handling_error: - logger.exception( - "%s error while handling error %s by error handler %s", - error_handling_error.__class__.__name__, - exc_value.__class__.__name__, - error_handler_class.__name__, - ) - - if not plugin_handled: - _DefaultErrorHandler()._handle(exc_value) - - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py deleted file mode 100644 index f59d0718680..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/__init__.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics import export, view -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import Meter, MeterProvider -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( - AlignedHistogramBucketExemplarReservoir, - AlwaysOffExemplarFilter, - AlwaysOnExemplarFilter, - Exemplar, - ExemplarFilter, - ExemplarReservoir, - SimpleFixedSizeExemplarReservoir, - TraceBasedExemplarFilter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( - Counter, - Histogram, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - UpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import Gauge as _Gauge - -__all__ = [ - "AlignedHistogramBucketExemplarReservoir", - "AlwaysOffExemplarFilter", - "AlwaysOnExemplarFilter", - "Counter", - "Exemplar", - "ExemplarFilter", - "ExemplarReservoir", - "Histogram", - "Meter", - "MeterProvider", - "MetricsTimeoutError", - "ObservableCounter", - "ObservableGauge", - "ObservableUpDownCounter", - "SimpleFixedSizeExemplarReservoir", - "TraceBasedExemplarFilter", - "UpDownCounter", - "_Gauge", - "export", - "view", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py deleted file mode 100644 index 9ca9fbb985a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/__init__.py +++ /dev/null @@ -1,660 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import os -import weakref -from atexit import register, unregister -from collections.abc import Callable, Sequence -from dataclasses import dataclass -from logging import getLogger -from os import environ -from threading import Lock -from time import time_ns - -# This kind of import is needed to avoid Sphinx errors. -import opentelemetry.agent._vendor.opentelemetry.sdk.metrics -from opentelemetry.agent._vendor import opentelemetry -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter as APICounter -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram as APIHistogram -from opentelemetry.agent._vendor.opentelemetry.metrics import Meter as APIMeter -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider as APIMeterProvider -from opentelemetry.agent._vendor.opentelemetry.metrics import NoOpMeter -from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableCounter as APIObservableCounter -from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableGauge as APIObservableGauge -from opentelemetry.agent._vendor.opentelemetry.metrics import ( - ObservableUpDownCounter as APIObservableUpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import UpDownCounter as APIUpDownCounter -from opentelemetry.agent._vendor.opentelemetry.metrics import _Gauge as APIGauge -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_METRICS_EXEMPLAR_FILTER, - OTEL_SDK_DISABLED, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( - AlwaysOffExemplarFilter, - AlwaysOnExemplarFilter, - ExemplarFilter, - TraceBasedExemplarFilter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( - _Counter, - _Gauge, - _Histogram, - _ObservableCounter, - _ObservableGauge, - _ObservableUpDownCounter, - _UpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement_consumer import ( - MeasurementConsumer, - SynchronousMeasurementConsumer, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.sdk_configuration import ( - SdkConfiguration, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( - Resource, - _get_process_dependent_resource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.util._configurator import RuleBasedConfigurator -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( - InstrumentationScope, -) -from opentelemetry.agent._vendor.opentelemetry.util._once import Once -from opentelemetry.agent._vendor.opentelemetry.util.types import ( - Attributes, -) - -_logger = getLogger(__name__) - - -@dataclass -class _MeterConfig: - is_enabled: bool = True - - @classmethod - def default(cls) -> "_MeterConfig": - return _MeterConfig() - - -class _ProxyMeterConfig: - def __init__(self, config: _MeterConfig): - self._config = config - - @property - def is_enabled(self) -> bool: - return self._config.is_enabled - - def update(self, config: _MeterConfig) -> None: - self._config = config - - -class Meter(APIMeter): - """See `opentelemetry.metrics.Meter`.""" - - def __init__( - self, - instrumentation_scope: InstrumentationScope, - measurement_consumer: MeasurementConsumer, - *, - _meter_config: _MeterConfig | None = None, - ): - super().__init__( - name=instrumentation_scope.name, - version=instrumentation_scope.version, - schema_url=instrumentation_scope.schema_url, - ) - self._instrumentation_scope = instrumentation_scope - self._measurement_consumer = measurement_consumer - self._instrument_id_instrument = {} - self._instrument_registration_lock = Lock() - self._meter_config = _ProxyMeterConfig(_meter_config or _MeterConfig.default()) - - def _is_enabled(self) -> bool: - return self._meter_config.is_enabled - - def _set_meter_config(self, meter_config: _MeterConfig) -> None: - self._meter_config.update(meter_config) - - def create_counter(self, name, unit="", description="") -> APICounter: - with self._instrument_registration_lock: - status = self._register_instrument(name, _Counter, unit, description) - if not status.already_registered: - self._instrument_id_instrument[status.instrument_id] = _Counter( - name, - self._instrumentation_scope, - self._measurement_consumer, - unit, - description, - _meter_config=self._meter_config, - ) - instrument = self._instrument_id_instrument[status.instrument_id] - - if status.conflict: - # FIXME #2558 go through all views here and check if this - # instrument registration conflict can be fixed. If it can be, do - # not log the following warning. - self._log_instrument_registration_conflict( - name, - APICounter.__name__, - unit, - description, - status, - ) - return instrument - - def create_up_down_counter(self, name, unit="", description="") -> APIUpDownCounter: - with self._instrument_registration_lock: - status = self._register_instrument(name, _UpDownCounter, unit, description) - if not status.already_registered: - self._instrument_id_instrument[status.instrument_id] = _UpDownCounter( - name, - self._instrumentation_scope, - self._measurement_consumer, - unit, - description, - _meter_config=self._meter_config, - ) - instrument = self._instrument_id_instrument[status.instrument_id] - - if status.conflict: - # FIXME #2558 go through all views here and check if this - # instrument registration conflict can be fixed. If it can be, do - # not log the following warning. - self._log_instrument_registration_conflict( - name, - APIUpDownCounter.__name__, - unit, - description, - status, - ) - return instrument - - def create_observable_counter( - self, - name, - callbacks=None, - unit="", - description="", - ) -> APIObservableCounter: - with self._instrument_registration_lock: - status = self._register_instrument(name, _ObservableCounter, unit, description) - if not status.already_registered: - self._instrument_id_instrument[status.instrument_id] = _ObservableCounter( - name, - self._instrumentation_scope, - self._measurement_consumer, - callbacks, - unit, - description, - _meter_config=self._meter_config, - ) - instrument = self._instrument_id_instrument[status.instrument_id] - - if not status.already_registered: - self._measurement_consumer.register_asynchronous_instrument(instrument) - - if status.conflict: - # FIXME #2558 go through all views here and check if this - # instrument registration conflict can be fixed. If it can be, do - # not log the following warning. - self._log_instrument_registration_conflict( - name, - APIObservableCounter.__name__, - unit, - description, - status, - ) - return instrument - - def create_histogram( - self, - name: str, - unit: str = "", - description: str = "", - *, - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - ) -> APIHistogram: - if explicit_bucket_boundaries_advisory is not None: - invalid_advisory = False - if isinstance(explicit_bucket_boundaries_advisory, Sequence): - try: - invalid_advisory = not ( - all(isinstance(e, (float, int)) for e in explicit_bucket_boundaries_advisory) - ) - except (KeyError, TypeError): - invalid_advisory = True - else: - invalid_advisory = True - - if invalid_advisory: - explicit_bucket_boundaries_advisory = None - _logger.warning("explicit_bucket_boundaries_advisory must be a sequence of numbers") - - with self._instrument_registration_lock: - status = self._register_instrument( - name, - _Histogram, - unit, - description, - explicit_bucket_boundaries_advisory, - ) - if not status.already_registered: - self._instrument_id_instrument[status.instrument_id] = _Histogram( - name, - self._instrumentation_scope, - self._measurement_consumer, - unit, - description, - explicit_bucket_boundaries_advisory, - _meter_config=self._meter_config, - ) - instrument = self._instrument_id_instrument[status.instrument_id] - - if status.conflict: - # FIXME #2558 go through all views here and check if this - # instrument registration conflict can be fixed. If it can be, do - # not log the following warning. - self._log_instrument_registration_conflict( - name, - APIHistogram.__name__, - unit, - description, - status, - ) - return instrument - - def create_gauge(self, name, unit="", description="") -> APIGauge: - with self._instrument_registration_lock: - status = self._register_instrument(name, _Gauge, unit, description) - if not status.already_registered: - self._instrument_id_instrument[status.instrument_id] = _Gauge( - name, - self._instrumentation_scope, - self._measurement_consumer, - unit, - description, - _meter_config=self._meter_config, - ) - instrument = self._instrument_id_instrument[status.instrument_id] - - if status.conflict: - # FIXME #2558 go through all views here and check if this - # instrument registration conflict can be fixed. If it can be, do - # not log the following warning. - self._log_instrument_registration_conflict( - name, - APIGauge.__name__, - unit, - description, - status, - ) - return instrument - - def create_observable_gauge(self, name, callbacks=None, unit="", description="") -> APIObservableGauge: - with self._instrument_registration_lock: - status = self._register_instrument(name, _ObservableGauge, unit, description) - if not status.already_registered: - self._instrument_id_instrument[status.instrument_id] = _ObservableGauge( - name, - self._instrumentation_scope, - self._measurement_consumer, - callbacks, - unit, - description, - _meter_config=self._meter_config, - ) - instrument = self._instrument_id_instrument[status.instrument_id] - - if not status.already_registered: - self._measurement_consumer.register_asynchronous_instrument(instrument) - - if status.conflict: - # FIXME #2558 go through all views here and check if this - # instrument registration conflict can be fixed. If it can be, do - # not log the following warning. - self._log_instrument_registration_conflict( - name, - APIObservableGauge.__name__, - unit, - description, - status, - ) - return instrument - - def create_observable_up_down_counter( - self, name, callbacks=None, unit="", description="" - ) -> APIObservableUpDownCounter: - with self._instrument_registration_lock: - status = self._register_instrument(name, _ObservableUpDownCounter, unit, description) - if not status.already_registered: - self._instrument_id_instrument[status.instrument_id] = _ObservableUpDownCounter( - name, - self._instrumentation_scope, - self._measurement_consumer, - callbacks, - unit, - description, - _meter_config=self._meter_config, - ) - instrument = self._instrument_id_instrument[status.instrument_id] - - if not status.already_registered: - self._measurement_consumer.register_asynchronous_instrument(instrument) - - if status.conflict: - # FIXME #2558 go through all views here and check if this - # instrument registration conflict can be fixed. If it can be, do - # not log the following warning. - self._log_instrument_registration_conflict( - name, - APIObservableUpDownCounter.__name__, - unit, - description, - status, - ) - return instrument - - -def _get_exemplar_filter(exemplar_filter: str) -> ExemplarFilter: - if exemplar_filter == "trace_based": - return TraceBasedExemplarFilter() - if exemplar_filter == "always_on": - return AlwaysOnExemplarFilter() - if exemplar_filter == "always_off": - return AlwaysOffExemplarFilter() - msg = f"Unknown exemplar filter '{exemplar_filter}'." - raise ValueError(msg) - - -_MeterConfiguratorT = Callable[[InstrumentationScope], _MeterConfig] -_RuleBasedMeterConfigurator = RuleBasedConfigurator[_MeterConfig] - - -def _default_meter_configurator( - _meter_scope: InstrumentationScope, -) -> _MeterConfig: - return _MeterConfig.default() - - -def _disable_meter_configurator( - _meter_scope: InstrumentationScope, -) -> _MeterConfig: - return _MeterConfig(is_enabled=False) - - -class MeterProvider(APIMeterProvider): - r"""See `opentelemetry.metrics.MeterProvider`. - - Args: - metric_readers: Register metric readers to collect metrics from the SDK - on demand. Each :class:`opentelemetry.sdk.metrics.export.MetricReader` is - completely independent and will collect separate streams of - metrics. For push-based export, use - :class:`opentelemetry.sdk.metrics.export.PeriodicExportingMetricReader`. - resource: The resource representing what the metrics emitted from the SDK pertain to. - shutdown_on_exit: If true, registers an `atexit` handler to call - `MeterProvider.shutdown` - views: The views to configure the metric output the SDK - - .. code-block:: python - :caption: Push-based export with PeriodicExportingMetricReader - - from opentelemetry.sdk.metrics import MeterProvider - from opentelemetry.sdk.metrics.export import ( - ConsoleMetricExporter, - PeriodicExportingMetricReader, - ) - - reader = PeriodicExportingMetricReader(ConsoleMetricExporter()) - provider = MeterProvider(metric_readers=[reader]) - - By default, instruments which do not match any :class:`opentelemetry.sdk.metrics.view.View` (or if no :class:`opentelemetry.sdk.metrics.view.View`\ s - are provided) will report metrics with the default aggregation for the - instrument's kind. To disable instruments by default, configure a match-all - :class:`opentelemetry.sdk.metrics.view.View` with `DropAggregation` and then create :class:`opentelemetry.sdk.metrics.view.View`\ s to re-enable - individual instruments: - - .. code-block:: python - :caption: Disable default views - - MeterProvider( - views=[ - View(instrument_name="*", aggregation=DropAggregation()), - View(instrument_name="mycounter"), - ], - # ... - ) - """ - - _all_metric_readers_lock = Lock() - _all_metric_readers = weakref.WeakSet() - - def __init__( - self, - metric_readers: Sequence["opentelemetry.sdk.metrics.export.MetricReader"] = (), - resource: Resource | None = None, - exemplar_filter: ExemplarFilter | None = None, - shutdown_on_exit: bool = True, - views: Sequence["opentelemetry.sdk.metrics.view.View"] = (), - *, - _meter_configurator: _MeterConfiguratorT | None = None, - ): - self._lock = Lock() - self._meter_lock = Lock() - self._atexit_handler = None - if resource is None: - resource = Resource.create({}) - self._sdk_config = SdkConfiguration( - exemplar_filter=( - exemplar_filter or _get_exemplar_filter(environ.get(OTEL_METRICS_EXEMPLAR_FILTER, "trace_based")) - ), - resource=resource, - views=views, - ) - self._metric_readers = metric_readers - self._measurement_consumer = SynchronousMeasurementConsumer( - sdk_config=self._sdk_config, - metric_readers=metric_readers, - ) - disabled = environ.get(OTEL_SDK_DISABLED, "") - self._disabled = disabled.lower().strip() == "true" - - if shutdown_on_exit: - self._atexit_handler = register(self.shutdown) - - self._meters: dict[InstrumentationScope, Meter] = {} - self._shutdown_once = Once() - self._shutdown = False - self._meter_configurator = _meter_configurator or _default_meter_configurator - - for metric_reader in self._metric_readers: - with self._all_metric_readers_lock: - if metric_reader in self._all_metric_readers: - # pylint: disable=broad-exception-raised - raise Exception( - f"MetricReader {metric_reader} has been registered already in other MeterProvider instance" - ) - - self._all_metric_readers.add(metric_reader) - - metric_reader._set_collect_callback(self._measurement_consumer.collect) - metric_reader._set_meter_provider(self) - - if hasattr(os, "register_at_fork"): - weak_at_fork = weakref.WeakMethod(self._handle_fork) - - def _after_in_child() -> None: - if at_fork := weak_at_fork(): - at_fork() - - os.register_at_fork(after_in_child=_after_in_child) - - def _handle_fork(self) -> None: - self._lock = Lock() - self._meter_lock = Lock() - type(self)._all_metric_readers_lock = Lock() - self._update_resource(_get_process_dependent_resource()) - - def _set_meter_configurator(self, *, meter_configurator: _MeterConfiguratorT): - """Set a new MeterConfigurator for this MeterProvider. - - Setting a new MeterConfigurator will result in the configurator being called - for each outstanding Meter and for any newly created meters thereafter. - Therefore, it is important that the provided function returns quickly. - """ - with self._meter_lock: - self._meter_configurator = meter_configurator - for instrumentation_scope, meter in self._meters.items(): - # pylint: disable-next=protected-access - meter._set_meter_config(self._apply_meter_configurator(instrumentation_scope)) - - def _update_resource(self, resource: Resource) -> None: - with self._meter_lock: - self._sdk_config.resource = self._sdk_config.resource.merge(resource) - - def _apply_meter_configurator(self, instrumentation_scope: InstrumentationScope) -> _MeterConfig: - try: - return self._meter_configurator(instrumentation_scope) - # pylint: disable-next=broad-exception-caught - except Exception: - _logger.exception( - "meter configurator failed for scope '%s', using default config", - instrumentation_scope.name, - ) - return _MeterConfig.default() - - def force_flush(self, timeout_millis: float = 10_000) -> bool: - deadline_ns = time_ns() + timeout_millis * 10**6 - - metric_reader_error = {} - - for metric_reader in self._metric_readers: - current_ts = time_ns() - try: - if current_ts >= deadline_ns: - raise MetricsTimeoutError("Timed out while flushing metric readers") - metric_reader.force_flush(timeout_millis=(deadline_ns - current_ts) / 10**6) - - # pylint: disable=broad-exception-caught - except Exception as error: - metric_reader_error[metric_reader] = error - - if metric_reader_error: - metric_reader_error_string = "\n".join( - [ - f"{metric_reader.__class__.__name__}: {error!r}" - for metric_reader, error in metric_reader_error.items() - ] - ) - - # pylint: disable=broad-exception-raised - raise Exception( - "MeterProvider.force_flush failed because the following " - "metric readers failed during collect:\n" - f"{metric_reader_error_string}" - ) - return True - - def shutdown(self, timeout_millis: float = 30_000): - deadline_ns = time_ns() + timeout_millis * 10**6 - - def _shutdown(): - self._shutdown = True - - did_shutdown = self._shutdown_once.do_once(_shutdown) - - if not did_shutdown: - _logger.warning("shutdown can only be called once") - return - - metric_reader_error = {} - - for metric_reader in self._metric_readers: - current_ts = time_ns() - try: - if current_ts >= deadline_ns: - # pylint: disable=broad-exception-raised - raise Exception("Didn't get to execute, deadline already exceeded") - metric_reader.shutdown(timeout_millis=(deadline_ns - current_ts) / 10**6) - - # pylint: disable=broad-exception-caught - except Exception as error: - metric_reader_error[metric_reader] = error - - if self._atexit_handler is not None: - unregister(self._atexit_handler) - self._atexit_handler = None - - if metric_reader_error: - metric_reader_error_string = "\n".join( - [ - f"{metric_reader.__class__.__name__}: {error!r}" - for metric_reader, error in metric_reader_error.items() - ] - ) - - # pylint: disable=broad-exception-raised - raise Exception( - "MeterProvider.shutdown failed because the following " - "metric readers failed during shutdown:\n" - f"{metric_reader_error_string}" - ) - - def get_meter( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> APIMeter: - if self._disabled: - return NoOpMeter(name, version=version, schema_url=schema_url) - - if self._shutdown: - _logger.warning("A shutdown `MeterProvider` can not provide a `Meter`") - return NoOpMeter(name, version=version, schema_url=schema_url) - - if not name: - _logger.warning("Meter name cannot be None or empty.") - return NoOpMeter(name, version=version, schema_url=schema_url) - - instrumentation_scope = InstrumentationScope(name, version, schema_url, attributes) - with self._meter_lock: - if not self._meters.get(instrumentation_scope): - # FIXME #2558 pass SDKConfig object to meter so that the meter - # has access to views. - self._meters[instrumentation_scope] = Meter( - instrumentation_scope, - self._measurement_consumer, - _meter_config=self._apply_meter_configurator(instrumentation_scope), - ) - return self._meters[instrumentation_scope] - - def add_metric_reader(self, metric_reader: "opentelemetry.sdk.metrics.export.MetricReader") -> None: - with self._all_metric_readers_lock: - if metric_reader in self._all_metric_readers: - _logger.warning( - "MetricReader '%s' has been registered already!", - metric_reader, - ) - return - self._measurement_consumer.add_metric_reader(metric_reader) - # pylint: disable-next=protected-access - metric_reader._set_collect_callback(self._measurement_consumer.collect) - self._all_metric_readers.add(metric_reader) - - def remove_metric_reader( - self, - metric_reader: "opentelemetry.sdk.metrics.export.MetricReader", - ) -> None: - with self._all_metric_readers_lock: - if metric_reader not in self._all_metric_readers: - _logger.warning("MetricReader '%s' has not been registered!", metric_reader) - return - self._measurement_consumer.remove_metric_reader(metric_reader) - # pylint: disable-next=protected-access - metric_reader._set_collect_callback(None) - metric_reader.shutdown() - self._all_metric_readers.remove(metric_reader) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py deleted file mode 100644 index 7dd0971e4ef..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/_view_instrument_match.py +++ /dev/null @@ -1,217 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from collections.abc import Mapping, Sequence -from logging import getLogger -from threading import Lock -from time import time_ns -from types import NoneType -from typing import TYPE_CHECKING, cast - -from opentelemetry.agent._vendor.typing_extensions import assert_never - -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( - Aggregation, - AggregationTemporality, - DefaultAggregation, - _Aggregation, - _SumAggregation, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import DataPointT -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.view import View -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes - -_logger = getLogger(__name__) - -# Every branch is tagged so that values Python considers equal but the OTel -# data model does not -- True/1/1.0, or a sequence of pairs and the mapping -# it resembles -- produce different aggregation keys. -_HashedAttributes = tuple[ - str, - str - | bool - | int - | float - | bytes - | None - | tuple["_HashedAttributes", ...] - | tuple[tuple[str, "_HashedAttributes"], ...], -] - - -# pylint: disable=inconsistent-return-statements -def _hash_attributes(value: Attributes | AnyValue) -> _HashedAttributes: - # Attributes have been cleaned and validated when Measurement was instantiated, - # so value is guaranteed to match one of the branches below at runtime. - if isinstance(value, (NoneType, str, int, float, bool, bytes)): - # bool is a subclass of int and 1 == 1.0, so the value alone is not - # enough to tell these apart. - return (type(value).__name__, value) - if isinstance(value, Sequence): - return ("sequence", tuple(_hash_attributes(v) for v in value)) - if isinstance(value, Mapping): - return ( - "mapping", - tuple( - (k, _hash_attributes(value[k])) - for k in sorted( - value, - key=lambda item: item if isinstance(item, str) else str(item), - ) - ), - ) - if TYPE_CHECKING: - assert_never(value) - - -_DEFAULT_CARDINALITY_LIMIT = 2000 - -_OVERFLOW_ATTRIBUTES: dict[str, AnyValue] = {"otel.metric.overflow": True} -_OVERFLOW_KEY = _hash_attributes(_OVERFLOW_ATTRIBUTES) - - -class _ViewInstrumentMatch: - def __init__( - self, - view: View, - instrument: _Instrument, - instrument_class_aggregation: dict[type, Aggregation], - cardinality_limit: int = _DEFAULT_CARDINALITY_LIMIT, - reset_on_collect: bool = False, - ): - self._view = view - self._cardinality_limit = cardinality_limit - self._reset_on_collect = reset_on_collect - # Delta aggregations created after a collection continue from it. - self._previous_collection_start_nanos: int | None = None - self._instrument = instrument - self._attributes_aggregation: dict[_HashedAttributes, _Aggregation] = {} - self._lock = Lock() - self._instrument_class_aggregation = instrument_class_aggregation - self._name = self._view._name or self._instrument.name - self._description = self._view._description or self._instrument.description - if not isinstance(self._view._aggregation, DefaultAggregation): - self._aggregation = self._view._aggregation._create_aggregation( - self._instrument, - None, - self._view._exemplar_reservoir_factory, - 0, - ) - else: - self._aggregation = self._instrument_class_aggregation[self._instrument.__class__]._create_aggregation( - self._instrument, - None, - self._view._exemplar_reservoir_factory, - 0, - ) - - def conflicts(self, other: "_ViewInstrumentMatch") -> bool: - # pylint: disable=protected-access - - result = ( - self._name == other._name - and self._instrument.unit == other._instrument.unit - # The aggregation class is being used here instead of data point - # type since they are functionally equivalent. - and self._aggregation.__class__ == other._aggregation.__class__ - ) - if not result: - return result - - if isinstance(self._aggregation, _SumAggregation): - # if result is True the two aggregation are of the same type - self._aggregation = cast(_SumAggregation, self._aggregation) - other._aggregation = cast(_SumAggregation, other._aggregation) - - result = ( - self._aggregation._instrument_is_monotonic == other._aggregation._instrument_is_monotonic - and self._aggregation._instrument_aggregation_temporality - == other._aggregation._instrument_aggregation_temporality - ) - - return result - - # pylint: disable=protected-access - def consume_measurement(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: - attributes = {} - if measurement.attributes: - # Make a shallow copy since the user can mutate the dict after the fact. - # The user can still modify mutable attribute values (lists/dicts) - # leading to unexpected behavior, but deep copying is expensive. - attributes = dict(measurement.attributes) - if self._view._attribute_keys is not None: - attributes = {k: v for k, v in attributes.items() if k in self._view._attribute_keys} - - aggr_key = _hash_attributes(attributes) - - if self._reset_on_collect: - # collect() discards the aggregations, so hold the lock until the - # measurement is aggregated to not lose it. - with self._lock: - self._get_or_create_aggregation(aggr_key, attributes).aggregate(measurement, should_sample_exemplar) - return - - aggregation = self._attributes_aggregation.get(aggr_key) - if aggregation is None: - with self._lock: - aggregation = self._get_or_create_aggregation(aggr_key, attributes) - - aggregation.aggregate(measurement, should_sample_exemplar) - - def _get_or_create_aggregation(self, aggr_key: _HashedAttributes, attributes: Attributes) -> _Aggregation: - """Must be called with ``self._lock`` held.""" - aggregation = self._attributes_aggregation.get(aggr_key) - if aggregation is not None: - return aggregation - - # Overflow is only used once the limit of distinct attribute sets is - # reached, so the overflow point is exported in addition to them. - if len(self._attributes_aggregation) >= self._cardinality_limit: - aggr_key = _OVERFLOW_KEY - attributes = dict(_OVERFLOW_ATTRIBUTES) - aggregation = self._attributes_aggregation.get(aggr_key) - if aggregation is not None: - return aggregation - - start_time_unix_nano = self._previous_collection_start_nanos or time_ns() - # pylint: disable=protected-access - if not isinstance(self._view._aggregation, DefaultAggregation): - aggregation = self._view._aggregation._create_aggregation( - self._instrument, - attributes, - self._view._exemplar_reservoir_factory, - start_time_unix_nano, - ) - else: - aggregation = self._instrument_class_aggregation[self._instrument.__class__]._create_aggregation( - self._instrument, - attributes, - self._view._exemplar_reservoir_factory, - start_time_unix_nano, - ) - self._attributes_aggregation[aggr_key] = aggregation - return aggregation - - def collect( - self, - collection_aggregation_temporality: AggregationTemporality, - collection_start_nanos: int, - ) -> Sequence[DataPointT] | None: - data_points: list[DataPointT] = [] - with self._lock: - aggregations = self._attributes_aggregation - if self._reset_on_collect and collection_aggregation_temporality is AggregationTemporality.DELTA: - self._attributes_aggregation = {} - self._previous_collection_start_nanos = collection_start_nanos - - for aggregation in aggregations.values(): - data_point = aggregation.collect(collection_aggregation_temporality, collection_start_nanos) - if data_point is not None: - data_points.append(data_point) - - # Returning here None instead of an empty list because the caller - # does not consume a sequence and to be consistent with the rest of - # collect methods that also return None. - return data_points or None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py deleted file mode 100644 index 5e307adc444..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/aggregation.py +++ /dev/null @@ -1,1354 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=too-many-lines - -import math -from abc import ABC, abstractmethod -from bisect import bisect_left -from collections.abc import Callable, Sequence -from enum import IntEnum -from functools import partial -from logging import getLogger -from threading import Lock -from typing import ( - Generic, - TypeVar, - cast, -) - -from opentelemetry.agent._vendor.opentelemetry.metrics import ( - Asynchronous, - Counter, - Histogram, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - Synchronous, - UpDownCounter, - _Gauge, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( - Exemplar, - ExemplarReservoirBuilder, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.buckets import ( - Buckets, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping import ( - Mapping, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.exponent_mapping import ( - ExponentMapping, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.logarithm_mapping import ( - LogarithmMapping, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import Buckets as BucketsPoint -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( - ExponentialHistogramDataPoint, - HistogramDataPoint, - NumberDataPoint, - Sum, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import Gauge as GaugePoint -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( - Histogram as HistogramPoint, -) -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -_DataPointVarT = TypeVar("_DataPointVarT", NumberDataPoint, HistogramDataPoint) - -_logger = getLogger(__name__) - - -class AggregationTemporality(IntEnum): - """ - The temporality to use when aggregating data. - - Can be one of the following values: - """ - - UNSPECIFIED = 0 - DELTA = 1 - CUMULATIVE = 2 - - -class _Aggregation(ABC, Generic[_DataPointVarT]): - def __init__( - self, - attributes: Attributes, - reservoir_builder: ExemplarReservoirBuilder, - ): - self._lock = Lock() - self._attributes = attributes - self._reservoir = reservoir_builder() - self._previous_point = None - - @abstractmethod - def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: - """Aggregate a measurement. - - Args: - measurement: Measurement to aggregate - should_sample_exemplar: Whether the measurement should be sampled by the exemplars reservoir or not. - """ - - @abstractmethod - def collect( - self, - collection_aggregation_temporality: AggregationTemporality, - collection_start_nano: int, - ) -> _DataPointVarT | None: - pass - - def _collect_exemplars(self) -> Sequence[Exemplar]: - """Returns the collected exemplars. - - Returns: - The exemplars collected by the reservoir - """ - return self._reservoir.collect(self._attributes) - - def _sample_exemplar(self, measurement: Measurement, should_sample_exemplar: bool) -> None: - """Offer the measurement to the exemplar reservoir for sampling. - - It should be called within the each :ref:`aggregate` call. - - Args: - measurement: The new measurement - should_sample_exemplar: Whether the measurement should be sampled by the exemplars reservoir or not. - """ - if should_sample_exemplar: - self._reservoir.offer( - measurement.value, - measurement.time_unix_nano, - measurement.attributes, - measurement.context, - ) - - -class _DropAggregation(_Aggregation): - def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: - pass - - def collect( - self, - collection_aggregation_temporality: AggregationTemporality, - collection_start_nano: int, - ) -> _DataPointVarT | None: - pass - - -class _SumAggregation(_Aggregation[Sum]): - def __init__( - self, - attributes: Attributes, - instrument_is_monotonic: bool, - instrument_aggregation_temporality: AggregationTemporality, - start_time_unix_nano: int, - reservoir_builder: ExemplarReservoirBuilder, - ): - super().__init__(attributes, reservoir_builder) - - self._start_time_unix_nano = start_time_unix_nano - self._instrument_aggregation_temporality = instrument_aggregation_temporality - self._instrument_is_monotonic = instrument_is_monotonic - - self._value = None - - self._previous_collection_start_nano = self._start_time_unix_nano - self._previous_value = 0 - - def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: - with self._lock: - if self._value is None: - self._value = 0 - - self._value = self._value + measurement.value - - self._sample_exemplar(measurement, should_sample_exemplar) - - def collect( - self, - collection_aggregation_temporality: AggregationTemporality, - collection_start_nano: int, - ) -> NumberDataPoint | None: - """ - Atomically return a point for the current value of the metric and - reset the aggregation value. - - Synchronous instruments have a method which is called directly with - increments for a given quantity: - - For example, an instrument that counts the amount of passengers in - every vehicle that crosses a certain point in a highway: - - synchronous_instrument.add(2) - collect(...) # 2 passengers are counted - synchronous_instrument.add(3) - collect(...) # 3 passengers are counted - synchronous_instrument.add(1) - collect(...) # 1 passenger is counted - - In this case the instrument aggregation temporality is DELTA because - every value represents an increment to the count, - - Asynchronous instruments have a callback which returns the total value - of a given quantity: - - For example, an instrument that measures the amount of bytes written to - a certain hard drive: - - callback() -> 1352 - collect(...) # 1352 bytes have been written so far - callback() -> 2324 - collect(...) # 2324 bytes have been written so far - callback() -> 4542 - collect(...) # 4542 bytes have been written so far - - In this case the instrument aggregation temporality is CUMULATIVE - because every value represents the total of the measurement. - - There is also the collection aggregation temporality, which is passed - to this method. The collection aggregation temporality defines the - nature of the returned value by this aggregation. - - When the collection aggregation temporality matches the - instrument aggregation temporality, then this method returns the - current value directly: - - synchronous_instrument.add(2) - collect(DELTA) -> 2 - synchronous_instrument.add(3) - collect(DELTA) -> 3 - synchronous_instrument.add(1) - collect(DELTA) -> 1 - - callback() -> 1352 - collect(CUMULATIVE) -> 1352 - callback() -> 2324 - collect(CUMULATIVE) -> 2324 - callback() -> 4542 - collect(CUMULATIVE) -> 4542 - - When the collection aggregation temporality does not match the - instrument aggregation temporality, then a conversion is made. For this - purpose, this aggregation keeps a private attribute, - self._previous_value. - - When the instrument is synchronous: - - self._previous_value is the sum of every previously - collected (delta) value. In this case, the returned (cumulative) value - will be: - - self._previous_value + value - - synchronous_instrument.add(2) - collect(CUMULATIVE) -> 2 - synchronous_instrument.add(3) - collect(CUMULATIVE) -> 5 - synchronous_instrument.add(1) - collect(CUMULATIVE) -> 6 - - Also, as a diagram: - - time -> - - self._previous_value - |-------------| - - value (delta) - |----| - - returned value (cumulative) - |------------------| - - When the instrument is asynchronous: - - self._previous_value is the value of the previously - collected (cumulative) value. In this case, the returned (delta) value - will be: - - value - self._previous_value - - callback() -> 1352 - collect(DELTA) -> 1352 - callback() -> 2324 - collect(DELTA) -> 972 - callback() -> 4542 - collect(DELTA) -> 2218 - - Also, as a diagram: - - time -> - - self._previous_value - |-------------| - - value (cumulative) - |------------------| - - returned value (delta) - |----| - """ - - with self._lock: - value = self._value - self._value = None - - if self._instrument_aggregation_temporality is AggregationTemporality.DELTA: - # This happens when the corresponding instrument for this - # aggregation is synchronous. - if collection_aggregation_temporality is AggregationTemporality.DELTA: - previous_collection_start_nano = self._previous_collection_start_nano - self._previous_collection_start_nano = collection_start_nano - - if value is None: - return None - - return NumberDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=previous_collection_start_nano, - time_unix_nano=collection_start_nano, - value=value, - ) - - if value is None: - value = 0 - - self._previous_value = value + self._previous_value - - return NumberDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=self._start_time_unix_nano, - time_unix_nano=collection_start_nano, - value=self._previous_value, - ) - - # This happens when the corresponding instrument for this - # aggregation is asynchronous. - - if value is None: - # This happens when the corresponding instrument callback - # does not produce measurements. - return None - - if collection_aggregation_temporality is AggregationTemporality.DELTA: - result_value = value - self._previous_value - - self._previous_value = value - - previous_collection_start_nano = self._previous_collection_start_nano - self._previous_collection_start_nano = collection_start_nano - - return NumberDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=previous_collection_start_nano, - time_unix_nano=collection_start_nano, - value=result_value, - ) - - return NumberDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=self._start_time_unix_nano, - time_unix_nano=collection_start_nano, - value=value, - ) - - -class _LastValueAggregation(_Aggregation[GaugePoint]): - def __init__( - self, - attributes: Attributes, - reservoir_builder: ExemplarReservoirBuilder, - instrument_is_synchronous: bool, - ): - super().__init__(attributes, reservoir_builder) - self._instrument_is_synchronous = instrument_is_synchronous - self._value = None - - def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True): - with self._lock: - self._value = measurement.value - - self._sample_exemplar(measurement, should_sample_exemplar) - - def collect( - self, - collection_aggregation_temporality: AggregationTemporality, - collection_start_nano: int, - ) -> _DataPointVarT | None: - """ - Atomically return a point for the current value of the metric. - """ - with self._lock: - if self._value is None: - return None - value = self._value - if not ( - self._instrument_is_synchronous - and collection_aggregation_temporality is AggregationTemporality.CUMULATIVE - ): - self._value = None - - exemplars = self._collect_exemplars() - - return NumberDataPoint( - attributes=self._attributes, - exemplars=exemplars, - start_time_unix_nano=None, - time_unix_nano=collection_start_nano, - value=value, - ) - - -_DEFAULT_EXPLICIT_BUCKET_HISTOGRAM_AGGREGATION_BOUNDARIES: Sequence[float] = ( - 0.0, - 5.0, - 10.0, - 25.0, - 50.0, - 75.0, - 100.0, - 250.0, - 500.0, - 750.0, - 1000.0, - 2500.0, - 5000.0, - 7500.0, - 10000.0, -) - - -class _ExplicitBucketHistogramAggregation(_Aggregation[HistogramPoint]): - def __init__( - self, - attributes: Attributes, - instrument_aggregation_temporality: AggregationTemporality, - start_time_unix_nano: int, - reservoir_builder: ExemplarReservoirBuilder, - boundaries: Sequence[float] | None = None, - record_min_max: bool = True, - ): - if boundaries is None: - boundaries = _DEFAULT_EXPLICIT_BUCKET_HISTOGRAM_AGGREGATION_BOUNDARIES - if boundaries: - for idx, bound in enumerate(boundaries): - if not math.isfinite(bound): - raise ValueError(f"invalid boundary: {bound!r}") - if idx and boundaries[idx - 1] >= bound: - raise ValueError("boundaries must be strictly increasing") - super().__init__( - attributes, - reservoir_builder=partial(reservoir_builder, boundaries=boundaries), - ) - - self._instrument_aggregation_temporality = instrument_aggregation_temporality - self._start_time_unix_nano = start_time_unix_nano - self._boundaries = tuple(boundaries) - self._record_min_max = record_min_max - - self._value = None - self._min = math.inf - self._max = -math.inf - self._sum = 0 - - self._previous_value = None - self._previous_min = math.inf - self._previous_max = -math.inf - self._previous_sum = 0 - - self._previous_collection_start_nano = self._start_time_unix_nano - - def _get_empty_bucket_counts(self) -> list[int]: - return [0] * (len(self._boundaries) + 1) - - def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: - with self._lock: - if self._value is None: - self._value = self._get_empty_bucket_counts() - - measurement_value = measurement.value - - self._sum += measurement_value - - if self._record_min_max: - self._min = min(self._min, measurement_value) - self._max = max(self._max, measurement_value) - - self._value[bisect_left(self._boundaries, measurement_value)] += 1 - - self._sample_exemplar(measurement, should_sample_exemplar) - - def collect( - self, - collection_aggregation_temporality: AggregationTemporality, - collection_start_nano: int, - ) -> _DataPointVarT | None: - """ - Atomically return a point for the current value of the metric. - """ - - with self._lock: - value = self._value - sum_ = self._sum - min_ = self._min - max_ = self._max - - self._value = None - self._sum = 0 - self._min = math.inf - self._max = -math.inf - - if self._instrument_aggregation_temporality is AggregationTemporality.DELTA: - # This happens when the corresponding instrument for this - # aggregation is synchronous. - if collection_aggregation_temporality is AggregationTemporality.DELTA: - previous_collection_start_nano = self._previous_collection_start_nano - self._previous_collection_start_nano = collection_start_nano - - if value is None: - return None - - return HistogramDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=previous_collection_start_nano, - time_unix_nano=collection_start_nano, - count=sum(value), - sum=sum_, - bucket_counts=tuple(value), - explicit_bounds=self._boundaries, - min=min_, - max=max_, - ) - - if value is None: - value = self._get_empty_bucket_counts() - - if self._previous_value is None: - self._previous_value = self._get_empty_bucket_counts() - - self._previous_value = [ - value_element + previous_value_element - for ( - value_element, - previous_value_element, - ) in zip(value, self._previous_value) - ] - self._previous_min = min(min_, self._previous_min) - self._previous_max = max(max_, self._previous_max) - self._previous_sum = sum_ + self._previous_sum - - return HistogramDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=self._start_time_unix_nano, - time_unix_nano=collection_start_nano, - count=sum(self._previous_value), - sum=self._previous_sum, - bucket_counts=tuple(self._previous_value), - explicit_bounds=self._boundaries, - min=self._previous_min, - max=self._previous_max, - ) - - return None - - -# pylint: disable=protected-access -class _ExponentialBucketHistogramAggregation(_Aggregation[HistogramPoint]): - # _min_max_size and _max_max_size are the smallest and largest values - # the max_size parameter may have, respectively. - - # _min_max_size is is the smallest reasonable value which is small enough - # to contain the entire normal floating point range at the minimum scale. - _min_max_size = 2 - - # _max_max_size is an arbitrary limit meant to limit accidental creation of - # giant exponential bucket histograms. - _max_max_size = 16384 - - def __init__( - self, - attributes: Attributes, - reservoir_builder: ExemplarReservoirBuilder, - instrument_aggregation_temporality: AggregationTemporality, - start_time_unix_nano: int, - # This is the default maximum number of buckets per positive or - # negative number range. The value 160 is specified by OpenTelemetry. - # See the derivation here: - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exponential-bucket-histogram-aggregation) - max_size: int = 160, - max_scale: int = 20, - record_min_max: bool = True, - ): - # max_size is the maximum capacity of the positive and negative - # buckets. - # _sum is the sum of all the values aggregated by this aggregator. - # _count is the count of all calls to aggregate. - # _zero_count is the count of all the calls to aggregate when the value - # to be aggregated is exactly 0. - # _min is the smallest value aggregated by this aggregator. - # _max is the smallest value aggregated by this aggregator. - # _positive holds the positive values. - # _negative holds the negative values by their absolute value. - if max_size < self._min_max_size: - raise ValueError(f"Buckets max size {max_size} is smaller than minimum max size {self._min_max_size}") - - if max_size > self._max_max_size: - raise ValueError(f"Buckets max size {max_size} is larger than maximum max size {self._max_max_size}") - if max_scale > 20: - _logger.warning( - "max_scale is set to %s which is larger than the recommended value of 20", - max_scale, - ) - - # This aggregation is analogous to _ExplicitBucketHistogramAggregation, - # the only difference is that with every call to aggregate, the size - # and amount of buckets can change (in - # _ExplicitBucketHistogramAggregation both size and amount of buckets - # remain constant once it is instantiated). - - super().__init__( - attributes, - reservoir_builder=partial(reservoir_builder, size=min(20, max_size)), - ) - - self._instrument_aggregation_temporality = instrument_aggregation_temporality - self._start_time_unix_nano = start_time_unix_nano - self._max_size = max_size - self._max_scale = max_scale - self._record_min_max = record_min_max - - self._value_positive = None - self._value_negative = None - self._min = math.inf - self._max = -math.inf - self._sum = 0 - self._count = 0 - self._zero_count = 0 - self._scale = None - - self._previous_value_positive = None - self._previous_value_negative = None - self._previous_min = math.inf - self._previous_max = -math.inf - self._previous_sum = 0 - self._previous_count = 0 - self._previous_zero_count = 0 - self._previous_scale = None - - self._previous_collection_start_nano = self._start_time_unix_nano - - self._mapping = self._new_mapping(self._max_scale) - - def aggregate(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: - # pylint: disable=too-many-branches,too-many-statements, too-many-locals - - with self._lock: - if self._value_positive is None: - self._value_positive = Buckets() - if self._value_negative is None: - self._value_negative = Buckets() - - measurement_value = measurement.value - - self._sum += measurement_value - - if self._record_min_max: - self._min = min(self._min, measurement_value) - self._max = max(self._max, measurement_value) - - self._count += 1 - - if measurement_value == 0: - self._zero_count += 1 - - if self._count == self._zero_count: - self._scale = 0 - - return - - if measurement_value > 0: - value = self._value_positive - - else: - measurement_value = -measurement_value - value = self._value_negative - - # The following code finds out if it is necessary to change the - # buckets to hold the incoming measurement_value, changes them if - # necessary. This process does not exist in - # _ExplicitBucketHistogram aggregation because the buckets there - # are constant in size and amount. - index = self._mapping.map_to_index(measurement_value) - - is_rescaling_needed = False - low, high = 0, 0 - - if len(value) == 0: - value.index_start = index - value.index_end = index - value.index_base = index - - elif index < value.index_start and (value.index_end - index) >= self._max_size: - is_rescaling_needed = True - low = index - high = value.index_end - - elif index > value.index_end and (index - value.index_start) >= self._max_size: - is_rescaling_needed = True - low = value.index_start - high = index - - if is_rescaling_needed: - scale_change = self._get_scale_change(low, high) - self._downscale( - scale_change, - self._value_positive, - self._value_negative, - ) - self._mapping = self._new_mapping(self._mapping.scale - scale_change) - - index = self._mapping.map_to_index(measurement_value) - - self._scale = self._mapping.scale - - if index < value.index_start: - span = value.index_end - index - - if span >= len(value.counts): - value.grow(span + 1, self._max_size) - - value.index_start = index - - elif index > value.index_end: - span = index - value.index_start - - if span >= len(value.counts): - value.grow(span + 1, self._max_size) - - value.index_end = index - - bucket_index = index - value.index_base - - if bucket_index < 0: - bucket_index += len(value.counts) - - # Now the buckets have been changed if needed and bucket_index will - # be used to increment the counter of the bucket that needs to be - # incremented. - - # This is analogous to - # self._value[bisect_left(self._boundaries, measurement_value)] += 1 - # in _ExplicitBucketHistogramAggregation.aggregate - value.increment_bucket(bucket_index) - - self._sample_exemplar(measurement, should_sample_exemplar) - - def collect( - self, - collection_aggregation_temporality: AggregationTemporality, - collection_start_nano: int, - ) -> _DataPointVarT | None: - """ - Atomically return a point for the current value of the metric. - """ - - # pylint: disable=too-many-statements, too-many-locals - with self._lock: - value_positive = self._value_positive - value_negative = self._value_negative - sum_ = self._sum - min_ = self._min - max_ = self._max - count = self._count - zero_count = self._zero_count - scale = self._scale - - self._value_positive = None - self._value_negative = None - self._sum = 0 - self._min = math.inf - self._max = -math.inf - self._count = 0 - self._zero_count = 0 - self._scale = None - - if self._instrument_aggregation_temporality is AggregationTemporality.DELTA: - # This happens when the corresponding instrument for this - # aggregation is synchronous. - if collection_aggregation_temporality is AggregationTemporality.DELTA: - previous_collection_start_nano = self._previous_collection_start_nano - self._previous_collection_start_nano = collection_start_nano - - if value_positive is None and value_negative is None: - return None - - return ExponentialHistogramDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=previous_collection_start_nano, - time_unix_nano=collection_start_nano, - count=count, - sum=sum_, - scale=scale, - zero_count=zero_count, - positive=BucketsPoint( - offset=value_positive.offset, - bucket_counts=(value_positive.get_offset_counts()), - ), - negative=BucketsPoint( - offset=value_negative.offset, - bucket_counts=(value_negative.get_offset_counts()), - ), - # FIXME: Find the right value for flags - flags=0, - min=min_, - max=max_, - ) - - # Here collection_temporality is CUMULATIVE. - # instrument_temporality is always DELTA for the time being. - # Here we need to handle the case where: - # collect is called after at least one other call to collect - # (there is data in previous buckets, a call to merge is needed - # to handle possible differences in bucket sizes). - # collect is called without another call previous call to - # collect was made (there is no previous buckets, previous, - # empty buckets that are the same scale of the current buckets - # need to be made so that they can be cumulatively aggregated - # to the current buckets). - - if value_positive is None and self._previous_value_positive is None: - # This happens if collect is called for the first time - # and aggregate has not yet been called. - value_positive = Buckets() - self._previous_value_positive = value_positive.copy_empty() - if value_negative is None and self._previous_value_negative is None: - value_negative = Buckets() - self._previous_value_negative = value_negative.copy_empty() - if scale is None and self._previous_scale is None: - scale = self._mapping.scale - self._previous_scale = scale - - if value_positive is not None and self._previous_value_positive is None: - # This happens when collect is called the very first time - # and aggregate has been called before. - - # We need previous buckets to add them to the current ones. - # When collect is called for the first time, there are no - # previous buckets, so we need to create empty buckets to - # add them to the current ones. The addition of empty - # buckets to the current ones will result in the current - # ones unchanged. - - # The way the previous buckets are generated here is - # different from the explicit bucket histogram where - # the size and amount of the buckets does not change once - # they are instantiated. Here, the size and amount of the - # buckets can change with every call to aggregate. In order - # to get empty buckets that can be added to the current - # ones resulting in the current ones unchanged we need to - # generate empty buckets that have the same size and amount - # as the current ones, this is what copy_empty does. - self._previous_value_positive = value_positive.copy_empty() - if value_negative is not None and self._previous_value_negative is None: - self._previous_value_negative = value_negative.copy_empty() - if scale is not None and self._previous_scale is None: - self._previous_scale = scale - - if value_positive is None and self._previous_value_positive is not None: - value_positive = self._previous_value_positive.copy_empty() - if value_negative is None and self._previous_value_negative is not None: - value_negative = self._previous_value_negative.copy_empty() - if scale is None and self._previous_scale is not None: - scale = self._previous_scale - - # here self._previous_value_negative and self._previous_value_positive are not Optional anymore - self._previous_value_negative = cast(Buckets, self._previous_value_negative) - self._previous_value_positive = cast(Buckets, self._previous_value_positive) - - min_scale = min(self._previous_scale, scale) - - low_positive, high_positive = self._get_low_high_previous_current( - self._previous_value_positive, - value_positive, - scale, - min_scale, - ) - low_negative, high_negative = self._get_low_high_previous_current( - self._previous_value_negative, - value_negative, - scale, - min_scale, - ) - - min_scale = min( - min_scale - self._get_scale_change(low_positive, high_positive), - min_scale - self._get_scale_change(low_negative, high_negative), - ) - - self._downscale( - self._previous_scale - min_scale, - self._previous_value_positive, - self._previous_value_negative, - ) - - # self._merge adds the values from value to - # self._previous_value, this is analogous to - # self._previous_value = [ - # value_element + previous_value_element - # for ( - # value_element, - # previous_value_element, - # ) in zip(value, self._previous_value) - # ] - # in _ExplicitBucketHistogramAggregation.collect. - self._merge( - self._previous_value_positive, - value_positive, - scale, - min_scale, - collection_aggregation_temporality, - ) - self._merge( - self._previous_value_negative, - value_negative, - scale, - min_scale, - collection_aggregation_temporality, - ) - - self._previous_min = min(min_, self._previous_min) - self._previous_max = max(max_, self._previous_max) - self._previous_sum = sum_ + self._previous_sum - self._previous_count = count + self._previous_count - self._previous_zero_count = zero_count + self._previous_zero_count - self._previous_scale = min_scale - - return ExponentialHistogramDataPoint( - attributes=self._attributes, - exemplars=self._collect_exemplars(), - start_time_unix_nano=self._start_time_unix_nano, - time_unix_nano=collection_start_nano, - count=self._previous_count, - sum=self._previous_sum, - scale=self._previous_scale, - zero_count=self._previous_zero_count, - positive=BucketsPoint( - offset=self._previous_value_positive.offset, - bucket_counts=(self._previous_value_positive.get_offset_counts()), - ), - negative=BucketsPoint( - offset=self._previous_value_negative.offset, - bucket_counts=(self._previous_value_negative.get_offset_counts()), - ), - # FIXME: Find the right value for flags - flags=0, - min=self._previous_min, - max=self._previous_max, - ) - - return None - - def _get_low_high_previous_current( - self, - previous_point_buckets, - current_point_buckets, - current_scale, - min_scale, - ): - (previous_point_low, previous_point_high) = self._get_low_high( - previous_point_buckets, self._previous_scale, min_scale - ) - (current_point_low, current_point_high) = self._get_low_high(current_point_buckets, current_scale, min_scale) - - if current_point_low > current_point_high: - low = previous_point_low - high = previous_point_high - - elif previous_point_low > previous_point_high: - low = current_point_low - high = current_point_high - - else: - low = min(previous_point_low, current_point_low) - high = max(previous_point_high, current_point_high) - - return low, high - - @staticmethod - def _get_low_high(buckets, scale, min_scale): - if buckets.counts == [0]: - return 0, -1 - - shift = scale - min_scale - - return buckets.index_start >> shift, buckets.index_end >> shift - - @staticmethod - def _new_mapping(scale: int) -> Mapping: - if scale <= 0: - return ExponentMapping(scale) - return LogarithmMapping(scale) - - def _get_scale_change(self, low, high): - change = 0 - - while high - low >= self._max_size: - high = high >> 1 - low = low >> 1 - - change += 1 - - return change - - @staticmethod - def _downscale(change: int, positive, negative): - if change == 0: - return - - if change < 0: - # pylint: disable=broad-exception-raised - raise Exception("Invalid change of scale") - - positive.downscale(change) - negative.downscale(change) - - def _merge( - self, - previous_buckets: Buckets, - current_buckets: Buckets, - current_scale, - min_scale, - aggregation_temporality, - ): - current_change = current_scale - min_scale - - for current_bucket_index, current_bucket in enumerate(current_buckets.counts): - if current_bucket == 0: - continue - - # Not considering the case where len(previous_buckets) == 0. This - # would not happen because self._previous_point is only assigned to - # an ExponentialHistogramDataPoint object if self._count != 0. - - current_index = current_buckets.index_base + current_bucket_index - if current_index > current_buckets.index_end: - current_index -= len(current_buckets.counts) - - index = current_index >> current_change - - if index < previous_buckets.index_start: - span = previous_buckets.index_end - index - - if span >= self._max_size: - # pylint: disable=broad-exception-raised - raise Exception("Incorrect merge scale") - - if span >= len(previous_buckets.counts): - previous_buckets.grow(span + 1, self._max_size) - - previous_buckets.index_start = index - - if index > previous_buckets.index_end: - span = index - previous_buckets.index_start - - if span >= self._max_size: - # pylint: disable=broad-exception-raised - raise Exception("Incorrect merge scale") - - if span >= len(previous_buckets.counts): - previous_buckets.grow(span + 1, self._max_size) - - previous_buckets.index_end = index - - bucket_index = index - previous_buckets.index_base - - if bucket_index < 0: - bucket_index += len(previous_buckets.counts) - - if aggregation_temporality is AggregationTemporality.DELTA: - current_bucket = -current_bucket - - previous_buckets.increment_bucket(bucket_index, increment=current_bucket) - - -class Aggregation(ABC): - """ - Base class for all aggregation types. - """ - - @abstractmethod - def _create_aggregation( - self, - instrument: _Instrument, - attributes: Attributes, - reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], - start_time_unix_nano: int, - ) -> _Aggregation: - """Creates an aggregation""" - - -class DefaultAggregation(Aggregation): - """ - The default aggregation to be used in a `View`. - - This aggregation will create an actual aggregation depending on the - instrument type, as specified next: - - ==================================================== ==================================== - Instrument Aggregation - ==================================================== ==================================== - `opentelemetry.sdk.metrics.Counter` `SumAggregation` - `opentelemetry.sdk.metrics.UpDownCounter` `SumAggregation` - `opentelemetry.sdk.metrics.ObservableCounter` `SumAggregation` - `opentelemetry.sdk.metrics.ObservableUpDownCounter` `SumAggregation` - `opentelemetry.sdk.metrics.Histogram` `ExplicitBucketHistogramAggregation` - `opentelemetry.sdk.metrics.ObservableGauge` `LastValueAggregation` - ==================================================== ==================================== - """ - - def _create_aggregation( - self, - instrument: _Instrument, - attributes: Attributes, - reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], - start_time_unix_nano: int, - ) -> _Aggregation: - # pylint: disable=too-many-return-statements - if isinstance(instrument, Counter): - return _SumAggregation( - attributes, - reservoir_builder=reservoir_factory(_SumAggregation), - instrument_is_monotonic=True, - instrument_aggregation_temporality=(AggregationTemporality.DELTA), - start_time_unix_nano=start_time_unix_nano, - ) - if isinstance(instrument, UpDownCounter): - return _SumAggregation( - attributes, - reservoir_builder=reservoir_factory(_SumAggregation), - instrument_is_monotonic=False, - instrument_aggregation_temporality=(AggregationTemporality.DELTA), - start_time_unix_nano=start_time_unix_nano, - ) - - if isinstance(instrument, ObservableCounter): - return _SumAggregation( - attributes, - reservoir_builder=reservoir_factory(_SumAggregation), - instrument_is_monotonic=True, - instrument_aggregation_temporality=(AggregationTemporality.CUMULATIVE), - start_time_unix_nano=start_time_unix_nano, - ) - - if isinstance(instrument, ObservableUpDownCounter): - return _SumAggregation( - attributes, - reservoir_builder=reservoir_factory(_SumAggregation), - instrument_is_monotonic=False, - instrument_aggregation_temporality=(AggregationTemporality.CUMULATIVE), - start_time_unix_nano=start_time_unix_nano, - ) - - if isinstance(instrument, Histogram): - boundaries = instrument._advisory.explicit_bucket_boundaries - return _ExplicitBucketHistogramAggregation( - attributes, - reservoir_builder=reservoir_factory(_ExplicitBucketHistogramAggregation), - instrument_aggregation_temporality=(AggregationTemporality.DELTA), - boundaries=boundaries, - start_time_unix_nano=start_time_unix_nano, - ) - - if isinstance(instrument, ObservableGauge): - return _LastValueAggregation( - attributes, - reservoir_builder=reservoir_factory(_LastValueAggregation), - instrument_is_synchronous=False, - ) - - if isinstance(instrument, _Gauge): - return _LastValueAggregation( - attributes, - reservoir_builder=reservoir_factory(_LastValueAggregation), - instrument_is_synchronous=True, - ) - - # pylint: disable=broad-exception-raised - raise Exception(f"Invalid instrument type {type(instrument)} found") - - -class ExponentialBucketHistogramAggregation(Aggregation): - """This aggregation informs the SDK to collect: - - - Count of Measurement values falling using a base-2 exponential formula. - - Arithmetic sum of Measurement values in population. This SHOULD NOT be collected when used with instruments that record negative measurements, e.g. UpDownCounter or ObservableGauge. - - Min (optional) Measurement value in population. - - Max (optional) Measurement value in population. - - Args: - max_size: Maximum number of buckets in each of the positive and negative ranges, not counting the special zero bucket. - max_scale: Maximum scale factor. - record_min_max: Whether to record min and max. - """ - - def __init__( - self, - max_size: int = 160, - max_scale: int = 20, - record_min_max: bool = True, - ): - self._max_size = max_size - self._max_scale = max_scale - self._record_min_max = record_min_max - - def _create_aggregation( - self, - instrument: _Instrument, - attributes: Attributes, - reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], - start_time_unix_nano: int, - ) -> _Aggregation: - instrument_aggregation_temporality = AggregationTemporality.UNSPECIFIED - if isinstance(instrument, Synchronous): - instrument_aggregation_temporality = AggregationTemporality.DELTA - elif isinstance(instrument, Asynchronous): - instrument_aggregation_temporality = AggregationTemporality.CUMULATIVE - - return _ExponentialBucketHistogramAggregation( - attributes, - reservoir_factory(_ExponentialBucketHistogramAggregation), - instrument_aggregation_temporality, - start_time_unix_nano, - max_size=self._max_size, - max_scale=self._max_scale, - record_min_max=self._record_min_max, - ) - - -class ExplicitBucketHistogramAggregation(Aggregation): - """This aggregation informs the SDK to collect: - - - Count of Measurement values falling within explicit bucket boundaries. - - Arithmetic sum of Measurement values in population. This SHOULD NOT be collected when used with instruments that record negative measurements, e.g. UpDownCounter or ObservableGauge. - - Min (optional) Measurement value in population. - - Max (optional) Measurement value in population. - - - Args: - boundaries: Array of increasing values representing explicit bucket boundary values. - record_min_max: Whether to record min and max. - """ - - def __init__( - self, - boundaries: Sequence[float] | None = None, - record_min_max: bool = True, - ) -> None: - self._boundaries = boundaries - self._record_min_max = record_min_max - - def _create_aggregation( - self, - instrument: _Instrument, - attributes: Attributes, - reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], - start_time_unix_nano: int, - ) -> _Aggregation: - instrument_aggregation_temporality = AggregationTemporality.UNSPECIFIED - if isinstance(instrument, Synchronous): - instrument_aggregation_temporality = AggregationTemporality.DELTA - elif isinstance(instrument, Asynchronous): - instrument_aggregation_temporality = AggregationTemporality.CUMULATIVE - - if self._boundaries is not None: - boundaries = self._boundaries - else: - # guard for usage with instruments without advisory - advisory = getattr(instrument, "_advisory", None) - boundaries = advisory.explicit_bucket_boundaries if advisory is not None else None - - return _ExplicitBucketHistogramAggregation( - attributes, - instrument_aggregation_temporality, - start_time_unix_nano, - reservoir_factory(_ExplicitBucketHistogramAggregation), - boundaries, - self._record_min_max, - ) - - -class SumAggregation(Aggregation): - """This aggregation informs the SDK to collect: - - - The arithmetic sum of Measurement values. - """ - - def _create_aggregation( - self, - instrument: _Instrument, - attributes: Attributes, - reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], - start_time_unix_nano: int, - ) -> _Aggregation: - instrument_aggregation_temporality = AggregationTemporality.UNSPECIFIED - if isinstance(instrument, Synchronous): - instrument_aggregation_temporality = AggregationTemporality.DELTA - elif isinstance(instrument, Asynchronous): - instrument_aggregation_temporality = AggregationTemporality.CUMULATIVE - - return _SumAggregation( - attributes, - isinstance(instrument, (Counter, ObservableCounter)), - instrument_aggregation_temporality, - start_time_unix_nano, - reservoir_factory(_SumAggregation), - ) - - -class LastValueAggregation(Aggregation): - """ - This aggregation informs the SDK to collect: - - - The last Measurement. - - The timestamp of the last Measurement. - """ - - def _create_aggregation( - self, - instrument: _Instrument, - attributes: Attributes, - reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], - start_time_unix_nano: int, - ) -> _Aggregation: - return _LastValueAggregation( - attributes, - reservoir_builder=reservoir_factory(_LastValueAggregation), - instrument_is_synchronous=isinstance(instrument, Synchronous), - ) - - -class DropAggregation(Aggregation): - """Using this aggregation will make all measurements be ignored.""" - - def _create_aggregation( - self, - instrument: _Instrument, - attributes: Attributes, - reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder], - start_time_unix_nano: int, - ) -> _Aggregation: - return _DropAggregation(attributes, reservoir_factory(_DropAggregation)) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py deleted file mode 100644 index 5ae8519eb9a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exceptions.py +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -class MetricsTimeoutError(Exception): - """Raised when a metrics function times out""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py deleted file mode 100644 index 8068406a280..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from .exemplar import Exemplar -from .exemplar_filter import ( - AlwaysOffExemplarFilter, - AlwaysOnExemplarFilter, - ExemplarFilter, - TraceBasedExemplarFilter, -) -from .exemplar_reservoir import ( - AlignedHistogramBucketExemplarReservoir, - ExemplarReservoir, - ExemplarReservoirBuilder, - SimpleFixedSizeExemplarReservoir, -) - -__all__ = [ - "AlignedHistogramBucketExemplarReservoir", - "AlwaysOffExemplarFilter", - "AlwaysOnExemplarFilter", - "Exemplar", - "ExemplarFilter", - "ExemplarReservoir", - "ExemplarReservoirBuilder", - "SimpleFixedSizeExemplarReservoir", - "TraceBasedExemplarFilter", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py deleted file mode 100644 index cb51c4b8a61..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import dataclasses - -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - - -@dataclasses.dataclass(frozen=True) -class Exemplar: - """A representation of an exemplar, which is a sample input measurement. - - Exemplars also hold information about the environment when the measurement - was recorded, for example the span and trace ID of the active span when the - exemplar was recorded. - - Attributes: - trace_id: (optional) The trace associated with a recording - span_id: (optional) The span associated with a recording - time_unix_nano: The time of the observation - value: The recorded value - filtered_attributes: A set of filtered attributes which provide additional insight into the Context when the observation was made. - - References: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#exemplars - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar - """ - - filtered_attributes: Attributes - value: int | float - time_unix_nano: int - span_id: int | None = None - trace_id: int | None = None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py deleted file mode 100644 index 815702c7397..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_filter.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from abc import ABC, abstractmethod - -from opentelemetry.agent._vendor.opentelemetry import trace -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace.span import INVALID_SPAN -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - - -class ExemplarFilter(ABC): - """``ExemplarFilter`` determines which measurements are eligible for becoming an - ``Exemplar``. - - Exemplar filters are used to filter measurements before attempting to store them - in a reservoir. - - Reference: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplarfilter - """ - - @abstractmethod - def should_sample( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> bool: - """Returns whether or not a reservoir should attempt to filter a measurement. - - Args: - value: The value of the measurement - timestamp: A timestamp that best represents when the measurement was taken - attributes: The complete set of measurement attributes - context: The Context of the measurement - """ - raise NotImplementedError("ExemplarFilter.should_sample is not implemented") - - -class AlwaysOnExemplarFilter(ExemplarFilter): - """An ExemplarFilter which makes all measurements eligible for being an Exemplar. - - Reference: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#alwayson - """ - - def should_sample( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> bool: - """Returns whether or not a reservoir should attempt to filter a measurement. - - Args: - value: The value of the measurement - timestamp: A timestamp that best represents when the measurement was taken - attributes: The complete set of measurement attributes - context: The Context of the measurement - """ - return True - - -class AlwaysOffExemplarFilter(ExemplarFilter): - """An ExemplarFilter which makes no measurements eligible for being an Exemplar. - - Using this ExemplarFilter is as good as disabling Exemplar feature. - - Reference: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#alwaysoff - """ - - def should_sample( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> bool: - """Returns whether or not a reservoir should attempt to filter a measurement. - - Args: - value: The value of the measurement - timestamp: A timestamp that best represents when the measurement was taken - attributes: The complete set of measurement attributes - context: The Context of the measurement - """ - return False - - -class TraceBasedExemplarFilter(ExemplarFilter): - """An ExemplarFilter which makes those measurements eligible for being an Exemplar, - which are recorded in the context of a sampled parent span. - - Reference: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#tracebased - """ - - def should_sample( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> bool: - """Returns whether or not a reservoir should attempt to filter a measurement. - - Args: - value: The value of the measurement - timestamp: A timestamp that best represents when the measurement was taken - attributes: The complete set of measurement attributes - context: The Context of the measurement - """ - span = trace.get_current_span(context) - if span == INVALID_SPAN: - return False - return span.get_span_context().trace_flags.sampled diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py deleted file mode 100644 index 0904d2e7c07..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exemplar/exemplar_reservoir.py +++ /dev/null @@ -1,291 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from abc import ABC, abstractmethod -from collections import defaultdict -from collections.abc import Callable, Mapping, Sequence -from random import randrange -from threading import Lock -from typing import ( - Any, -) - -from opentelemetry.agent._vendor.opentelemetry import trace -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace.span import INVALID_SPAN -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -from .exemplar import Exemplar - - -class ExemplarReservoir(ABC): - """ExemplarReservoir provide a method to offer measurements to the reservoir - and another to collect accumulated Exemplars. - - Note: - The constructor MUST accept ``**kwargs`` that may be set from aggregation - parameters. - - Note: - All methods MUST be safe to call concurrently. Measurements are offered - from application threads while a metric reader collects from its own - thread. - - Reference: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplarreservoir - """ - - @abstractmethod - def offer( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> None: - """Offers a measurement to be sampled. - - Args: - value: Measured value - time_unix_nano: Measurement instant - attributes: Measurement attributes - context: Measurement context - """ - raise NotImplementedError("ExemplarReservoir.offer is not implemented") - - @abstractmethod - def collect(self, point_attributes: Attributes) -> list[Exemplar]: - """Returns accumulated Exemplars and also resets the reservoir for the next - sampling period - - Args: - point_attributes: The attributes associated with metric point. - - Returns: - a list of ``opentelemetry.sdk.metrics._internal.exemplar.exemplar.Exemplar`` s. Returned - exemplars contain the attributes that were filtered out by the aggregator, - but recorded alongside the original measurement. - """ - raise NotImplementedError("ExemplarReservoir.collect is not implemented") - - -class ExemplarBucket: - def __init__(self) -> None: - self.__value: int | float = 0 - self.__attributes: Attributes = None - self.__time_unix_nano: int = 0 - self.__span_id: int | None = None - self.__trace_id: int | None = None - self.__offered: bool = False - - def offer( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> None: - """Offers a measurement to be sampled. - - Args: - value: Measured value - time_unix_nano: Measurement instant - attributes: Measurement attributes - context: Measurement context - """ - self.__value = value - self.__time_unix_nano = time_unix_nano - self.__attributes = attributes - span = trace.get_current_span(context) - if span != INVALID_SPAN: - span_context = span.get_span_context() - self.__span_id = span_context.span_id - self.__trace_id = span_context.trace_id - - self.__offered = True - - def collect(self, point_attributes: Attributes) -> Exemplar | None: - """May return an Exemplar and resets the bucket for the next sampling period.""" - if not self.__offered: - return None - - # filters out attributes from the measurement that are already included in the metric data point - # See the specification for more details: - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar - filtered_attributes = ( - {k: v for k, v in self.__attributes.items() if k not in point_attributes} if self.__attributes else None - ) - - exemplar = Exemplar( - filtered_attributes, - self.__value, - self.__time_unix_nano, - self.__span_id, - self.__trace_id, - ) - self.__reset() - return exemplar - - def __reset(self) -> None: - """Reset the bucket state after a collection cycle.""" - self.__value = 0 - self.__attributes = {} - self.__time_unix_nano = 0 - self.__span_id = None - self.__trace_id = None - self.__offered = False - - -class BucketIndexError(ValueError): - """An exception raised when the bucket index cannot be found.""" - - -class FixedSizeExemplarReservoirABC(ExemplarReservoir): - """Abstract class for a reservoir with fixed size.""" - - def __init__(self, size: int, **kwargs) -> None: - super().__init__(**kwargs) - self._size: int = size - self._reservoir_storage: Mapping[int, ExemplarBucket] = defaultdict(ExemplarBucket) - self._lock = Lock() - - def collect(self, point_attributes: Attributes) -> list[Exemplar]: - """Returns accumulated Exemplars and also resets the reservoir for the next - sampling period - - Args: - point_attributes: The attributes associated with metric point. - - Returns: - a list of ``opentelemetry.sdk.metrics._internal.exemplar.exemplar.Exemplar`` s. Returned - exemplars contain the attributes that were filtered out by the aggregator, - but recorded alongside the original measurement. - """ - with self._lock: - exemplars = [ - e - for e in (bucket.collect(point_attributes) for _, bucket in sorted(self._reservoir_storage.items())) - if e is not None - ] - self._reset() - return exemplars - - def offer( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> None: - """Offers a measurement to be sampled. - - Args: - value: Measured value - time_unix_nano: Measurement instant - attributes: Measurement attributes - context: Measurement context - """ - with self._lock: - try: - index = self._find_bucket_index(value, time_unix_nano, attributes, context) - - self._reservoir_storage[index].offer(value, time_unix_nano, attributes, context) - except BucketIndexError: - # Ignore invalid bucket index - pass - - @abstractmethod - def _find_bucket_index( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> int: - """Determines the bucket index for the given measurement. - - It should be implemented by subclasses based on specific strategies. - - Args: - value: Measured value - time_unix_nano: Measurement instant - attributes: Measurement attributes - context: Measurement context - - Returns: - The bucket index - - Raises: - BucketIndexError: If no bucket index can be found. - """ - - def _reset(self) -> None: - """Reset the reservoir by resetting any stateful logic after a collection cycle.""" - - -class SimpleFixedSizeExemplarReservoir(FixedSizeExemplarReservoirABC): - """This reservoir uses an uniformly-weighted sampling algorithm based on the number - of samples the reservoir has seen so far to determine if the offered measurements - should be sampled. - - Reference: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#simplefixedsizeexemplarreservoir - """ - - def __init__(self, size: int = 1, **kwargs) -> None: - super().__init__(size, **kwargs) - self._measurements_seen: int = 0 - - def _reset(self) -> None: - super()._reset() - self._measurements_seen = 0 - - def _find_bucket_index( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> int: - if self._measurements_seen < self._size: - self._measurements_seen += 1 - return self._measurements_seen - 1 - - self._measurements_seen += 1 - index = randrange(0, self._measurements_seen) - if index < self._size: - return index - - raise BucketIndexError("Unable to find the bucket index.") - - -class AlignedHistogramBucketExemplarReservoir(FixedSizeExemplarReservoirABC): - """This Exemplar reservoir takes a configuration parameter that is the - configuration of a Histogram. This implementation keeps the last seen measurement - that falls within a histogram bucket. - - Reference: - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#alignedhistogrambucketexemplarreservoir - """ - - def __init__(self, boundaries: Sequence[float], **kwargs) -> None: - super().__init__(len(boundaries) + 1, **kwargs) - self._boundaries: Sequence[float] = boundaries - - def _find_bucket_index( - self, - value: float, - time_unix_nano: int, - attributes: Attributes, - context: Context, - ) -> int: - for index, boundary in enumerate(self._boundaries): - if value <= boundary: - return index - return len(self._boundaries) - - -# ExemplarReservoirBuilder: A callable that takes Aggregation parameters -# (e.g. boundaries for _ExplicitBucketHistogramAggregation) and returns -# an ExemplarReservoir instance. -ExemplarReservoirBuilder = Callable[[dict[str, Any]], ExemplarReservoir] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py deleted file mode 100644 index a8749700b00..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py +++ /dev/null @@ -1,177 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from math import ceil, log2 - - -class Buckets: - # No method of this class is protected by locks because instances of this - # class are only used in methods that are protected by locks themselves. - - def __init__(self): - self._counts = [0] - - # The term index refers to the number of the exponential histogram bucket - # used to determine its boundaries. The lower boundary of a bucket is - # determined by base ** index and the upper boundary of a bucket is - # determined by base ** (index + 1). index values are signedto account - # for values less than or equal to 1. - - # self._index_* will all have values equal to a certain index that is - # determined by the corresponding mapping _map_to_index function and - # the value of the index depends on the value passed to _map_to_index. - - # Index of the 0th position in self._counts: self._counts[0] is the - # count in the bucket with index self.__index_base. - self.__index_base = 0 - - # self.__index_start is the smallest index value represented in - # self._counts. - self.__index_start = 0 - - # self.__index_start is the largest index value represented in - # self._counts. - self.__index_end = 0 - - @property - def index_start(self) -> int: - return self.__index_start - - @index_start.setter - def index_start(self, value: int) -> None: - self.__index_start = value - - @property - def index_end(self) -> int: - return self.__index_end - - @index_end.setter - def index_end(self, value: int) -> None: - self.__index_end = value - - @property - def index_base(self) -> int: - return self.__index_base - - @index_base.setter - def index_base(self, value: int) -> None: - self.__index_base = value - - @property - def counts(self): - return self._counts - - def get_offset_counts(self): - bias = self.__index_base - self.__index_start - return self._counts[-bias:] + self._counts[:-bias] - - def grow(self, needed: int, max_size: int) -> None: - size = len(self._counts) - bias = self.__index_base - self.__index_start - old_positive_limit = size - bias - - # 2 ** ceil(log2(needed)) finds the smallest power of two that is larger - # or equal than needed: - # 2 ** ceil(log2(1)) == 1 - # 2 ** ceil(log2(2)) == 2 - # 2 ** ceil(log2(3)) == 4 - # 2 ** ceil(log2(4)) == 4 - # 2 ** ceil(log2(5)) == 8 - # 2 ** ceil(log2(6)) == 8 - # 2 ** ceil(log2(7)) == 8 - # 2 ** ceil(log2(8)) == 8 - new_size = min(2 ** ceil(log2(needed)), max_size) - - new_positive_limit = new_size - bias - - tmp = [0] * new_size - tmp[new_positive_limit:] = self._counts[old_positive_limit:] - tmp[0:old_positive_limit] = self._counts[0:old_positive_limit] - self._counts = tmp - - @property - def offset(self) -> int: - return self.__index_start - - def __len__(self) -> int: - if len(self._counts) == 0: - return 0 - - if self.__index_end == self.__index_start and self[0] == 0: - return 0 - - return self.__index_end - self.__index_start + 1 - - def __getitem__(self, key: int) -> int: - bias = self.__index_base - self.__index_start - - if key < bias: - key += len(self._counts) - - key -= bias - - return self._counts[key] - - def downscale(self, amount: int) -> None: - """ - Rotates, then collapses 2 ** amount to 1 buckets. - """ - - bias = self.__index_base - self.__index_start - - if bias != 0: - self.__index_base = self.__index_start - - # [0, 1, 2, 3, 4] Original backing array - - self._counts = self._counts[::-1] - # [4, 3, 2, 1, 0] - - self._counts = self._counts[:bias][::-1] + self._counts[bias:][::-1] - # [3, 4, 0, 1, 2] This is a rotation of the backing array. - - size = 1 + self.__index_end - self.__index_start - each = 1 << amount - inpos = 0 - outpos = 0 - - pos = self.__index_start - - while pos <= self.__index_end: - mod = pos % each - if mod < 0: - mod += each - - index = mod - - while index < each and inpos < size: - if outpos != inpos: - self._counts[outpos] += self._counts[inpos] - self._counts[inpos] = 0 - - inpos += 1 - pos += 1 - index += 1 - - outpos += 1 - - self.__index_start >>= amount - self.__index_end >>= amount - self.__index_base = self.__index_start - - def increment_bucket(self, bucket_index: int, increment: int = 1) -> None: - self._counts[bucket_index] += increment - - def copy_empty(self) -> "Buckets": - copy = Buckets() - - # pylint: disable=no-member - # pylint: disable=protected-access - # pylint: disable=attribute-defined-outside-init - # pylint: disable=invalid-name - copy._Buckets__index_base = self._Buckets__index_base # type: ignore[reportArgumentType] - copy._Buckets__index_start = self._Buckets__index_start # type: ignore[reportArgumentType] - copy._Buckets__index_end = self._Buckets__index_end # type: ignore[reportArgumentType] - copy._counts = [0 for _ in self._counts] - - return copy diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py deleted file mode 100644 index a62a2e6b0df..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/__init__.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from abc import ABC, abstractmethod -from threading import Lock - - -class Mapping(ABC): - """ - Parent class for `LogarithmMapping` and `ExponentialMapping`. - """ - - _mappings: dict[int, "Mapping"] - _mappings_lock: Lock - - _min_scale: int - _max_scale: int - - # pylint: disable=no-member - def __new__(cls, scale: int): - with cls._mappings_lock: - # cls._mappings and cls._mappings_lock are implemented in each of - # the child classes as a dictionary and a lock, respectively. They - # are not instantiated here because that would lead to both child - # classes having the same instance of cls._mappings and - # cls._mappings_lock. - if scale not in cls._mappings: - cls._mappings[scale] = super().__new__(cls) - cls._mappings[scale]._init(scale) - - return cls._mappings[scale] - - @abstractmethod - def _init(self, scale: int) -> None: - # pylint: disable=attribute-defined-outside-init - - if scale > self._get_max_scale(): - # pylint: disable=broad-exception-raised - raise Exception(f"scale is larger than {self._max_scale}") - - if scale < self._get_min_scale(): - # pylint: disable=broad-exception-raised - raise Exception(f"scale is smaller than {self._min_scale}") - - # The size of the exponential histogram buckets is determined by a - # parameter known as scale, larger values of scale will produce smaller - # buckets. Bucket boundaries of the exponential histogram are located - # at integer powers of the base, where: - # - # base = 2 ** (2 ** (-scale)) - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#all-scales-use-the-logarithm-function - self._scale = scale - - @abstractmethod - def _get_min_scale(self) -> int: - """ - Return the smallest possible value for the mapping scale - """ - - @abstractmethod - def _get_max_scale(self) -> int: - """ - Return the largest possible value for the mapping scale - """ - - @abstractmethod - def map_to_index(self, value: float) -> int: - """ - Maps positive floating point values to indexes corresponding to - `Mapping.scale`. Implementations are not expected to handle zeros, - +inf, NaN, or negative values. - """ - - @abstractmethod - def get_lower_boundary(self, index: int) -> float: - """ - Returns the lower boundary of a given bucket index. The index is - expected to map onto a range that is at least partially inside the - range of normal floating point values. If the corresponding - bucket's upper boundary is less than or equal to 2 ** -1022, - :class:`~opentelemetry.sdk.metrics.MappingUnderflowError` - will be raised. If the corresponding bucket's lower boundary is greater - than ``sys.float_info.max``, - :class:`~opentelemetry.sdk.metrics.MappingOverflowError` - will be raised. - """ - - @property - def scale(self) -> int: - """ - Returns the parameter that controls the resolution of this mapping. - See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/datamodel.md#exponential-scale - """ - return self._scale diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py deleted file mode 100644 index 8bf64b28464..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/errors.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -class MappingUnderflowError(Exception): - """ - Raised when computing the lower boundary of an index that maps into a - denormal floating point value. - """ - - -class MappingOverflowError(Exception): - """ - Raised when computing the lower boundary of an index that maps into +inf. - """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py deleted file mode 100644 index 014d28c470b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/exponent_mapping.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from math import ldexp -from threading import Lock - -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping import ( - Mapping, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.errors import ( - MappingOverflowError, - MappingUnderflowError, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.ieee_754 import ( - MANTISSA_WIDTH, - MAX_NORMAL_EXPONENT, - MIN_NORMAL_EXPONENT, - MIN_NORMAL_VALUE, - get_ieee_754_exponent, - get_ieee_754_mantissa, -) - - -class ExponentMapping(Mapping): - # Reference implementation here: - # https://github.com/open-telemetry/opentelemetry-go/blob/0e6f9c29c10d6078e8131418e1d1d166c7195d61/sdk/metric/aggregator/exponential/mapping/exponent/exponent.go - - _mappings = {} - _mappings_lock = Lock() - - _min_scale = -10 - _max_scale = 0 - - def _get_min_scale(self): - # _min_scale defines the point at which the exponential mapping - # function becomes useless for 64-bit floats. With scale -10, ignoring - # subnormal values, bucket indices range from -1 to 1. - return -10 - - def _get_max_scale(self): - # _max_scale is the largest scale supported by exponential mapping. Use - # a logarithm mapping for larger scales. - return 0 - - def _init(self, scale: int): - # pylint: disable=attribute-defined-outside-init - - super()._init(scale) - - # self._min_normal_lower_boundary_index is the largest index such that - # base ** index < MIN_NORMAL_VALUE and - # base ** (index + 1) >= MIN_NORMAL_VALUE. An exponential histogram - # bucket with this index covers the range - # (base ** index, base (index + 1)], including MIN_NORMAL_VALUE. This - # is the smallest valid index that contains at least one normal value. - index = MIN_NORMAL_EXPONENT >> -self._scale - - if -self._scale < 2: - # For scales -1 and 0, the maximum value 2 ** -1022 is a - # power-of-two multiple, meaning base ** index == MIN_NORMAL_VALUE. - # Subtracting 1 so that base ** (index + 1) == MIN_NORMAL_VALUE. - index -= 1 - - self._min_normal_lower_boundary_index = index - - # self._max_normal_lower_boundary_index is the index such that - # base**index equals the greatest representable lower boundary. An - # exponential histogram bucket with this index covers the range - # ((2 ** 1024) / base, 2 ** 1024], which includes opentelemetry.sdk. - # metrics._internal.exponential_histogram.ieee_754.MAX_NORMAL_VALUE. - # This bucket is incomplete, since the upper boundary cannot be - # represented. One greater than this index corresponds with the bucket - # containing values > 2 ** 1024. - self._max_normal_lower_boundary_index = MAX_NORMAL_EXPONENT >> -self._scale - - def map_to_index(self, value: float) -> int: - if value < MIN_NORMAL_VALUE: - return self._min_normal_lower_boundary_index - - exponent = get_ieee_754_exponent(value) - - # Positive integers are represented in binary as having an infinite - # amount of leading zeroes, for example 2 is represented as ...00010. - - # A negative integer -x is represented in binary as the complement of - # (x - 1). For example, -4 is represented as the complement of 4 - 1 - # == 3. 3 is represented as ...00011. Its compliment is ...11100, the - # binary representation of -4. - - # get_ieee_754_mantissa(value) gets the positive integer made up - # from the rightmost MANTISSA_WIDTH bits (the mantissa) of the IEEE - # 754 representation of value. If value is an exact power of 2, all - # these MANTISSA_WIDTH bits would be all zeroes, and when 1 is - # subtracted the resulting value is -1. The binary representation of - # -1 is ...111, so when these bits are right shifted MANTISSA_WIDTH - # places, the resulting value for correction is -1. If value is not an - # exact power of 2, at least one of the rightmost MANTISSA_WIDTH - # bits would be 1 (even for values whose decimal part is 0, like 5.0 - # since the IEEE 754 of such number is too the product of a power of 2 - # (defined in the exponent part of the IEEE 754 representation) and the - # value defined in the mantissa). Having at least one of the rightmost - # MANTISSA_WIDTH bit being 1 means that get_ieee_754(value) will - # always be greater or equal to 1, and when 1 is subtracted, the - # result will be greater or equal to 0, whose representation in binary - # will be of at most MANTISSA_WIDTH ones that have an infinite - # amount of leading zeroes. When those MANTISSA_WIDTH bits are - # shifted to the right MANTISSA_WIDTH places, the resulting value - # will be 0. - - # In summary, correction will be -1 if value is a power of 2, 0 if not. - - # map_to_index requires value to be a finite, positive real number. - # 0, inf, and NaN violate this precondition. - - # Zero is represented in IEEE 754 with all exponent bits set to 0, - # giving get_ieee_754_exponent a result of -1023. Since -1023 is less - # than MIN_NORMAL_EXPONENT (-1022), zero is caught by the guard above - # and returned early. - - # Inf is represented in IEEE 754 with all 11 exponent bits set to 1 - # and a mantissa of 0, giving get_ieee_754_exponent a result of 1024 - # and correction a value of -1. - - # NaN is represented in IEEE 754 with all 11 exponent bits set to 1 - # and a non-zero mantissa of unspecified bit pattern, producing an - # unspecified correction value. - - # Inf and NaN are not caught by the guard above. Callers must ensure - # that only finite, positive values are passed to map_to_index. - correction = (get_ieee_754_mantissa(value) - 1) >> MANTISSA_WIDTH - - return (exponent + correction) >> -self._scale - - def get_lower_boundary(self, index: int) -> float: - if index < self._min_normal_lower_boundary_index: - raise MappingUnderflowError() - - if index > self._max_normal_lower_boundary_index: - raise MappingOverflowError() - - return ldexp(1, index << -self._scale) - - @property - def scale(self) -> int: - return self._scale diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md deleted file mode 100644 index 0cf5c8c59b3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.md +++ /dev/null @@ -1,175 +0,0 @@ -# IEEE 754 Explained - -IEEE 754 is a standard that defines a way to represent certain mathematical -objects using binary numbers. - -## Binary Number Fields - -The binary numbers used in IEEE 754 can have different lengths, the length that -is interesting for the purposes of this project is 64 bits. These binary -numbers are made up of 3 contiguous fields of bits, from left to right: - -1. 1 sign bit -2. 11 exponent bits -3. 52 mantissa bits - -Depending on the values these fields have, the represented mathematical object -can be one of: - -* Floating point number -* Zero -* NaN -* Infinite - -## Floating Point Numbers - -IEEE 754 represents a floating point number $f$ using an exponential -notation with 4 components: $sign$, $mantissa$, $base$ and $exponent$: - -$$f = sign \times mantissa \times base ^ {exponent}$$ - -There are two possible representations of floating point numbers: -_normal_ and _denormal_, which have different valid values for -their $mantissa$ and $exponent$ fields. - -### Binary Representation - -$sign$, $mantissa$, and $exponent$ are represented in binary, the -representation of each component has certain details explained next. - -$base$ is always $2$ and it is not represented in binary. - -#### Sign - -$sign$ can have 2 values: - -1. $1$ if the `sign` bit is `0` -2. $-1$ if the `sign` bit is `1`. - -#### Mantissa - -##### Normal Floating Point Numbers - -$mantissa$ is a positive fractional number whose integer part is $1$, for example -$1.2345 \dots$. The `mantissa` bits represent only the fractional part and the -$mantissa$ value can be calculated as: - -$$mantissa = 1 + \sum_{i=1}^{52} b_{i} \times 2^{-i} = 1 + \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{51}}{2^{51}} + \frac{b_{52}}{2^{52}}$$ - -Where $b_{i}$ is: - -1. $0$ if the bit at the position `i - 1` is `0`. -2. $1$ if the bit at the position `i - 1` is `1`. - -##### Denormal Floating Point Numbers - -$mantissa$ is a positive fractional number whose integer part is $0$, for example -$0.12345 \dots$. The `mantissa` bits represent only the fractional part and the -$mantissa$ value can be calculated as: - -$$mantissa = \sum_{i=1}^{52} b_{i} \times 2^{-i} = \frac{b_{1}}{2^{1}} + \frac{b_{2}}{2^{2}} + \dots + \frac{b_{51}}{2^{51}} + \frac{b_{52}}{2^{52}}$$ - -Where $b_{i}$ is: - -1. $0$ if the bit at the position `i - 1` is `0`. -2. $1$ if the bit at the position `i - 1` is `1`. - -#### Exponent - -##### Normal Floating Point Numbers - -Only the following bit sequences are allowed: `00000000001` to `11111111110`. -That is, there must be at least one `0` and one `1` in the exponent bits. - -The actual value of the $exponent$ can be calculated as: - -$$exponent = v - bias$$ - -where $v$ is the value of the binary number in the exponent bits and $bias$ is $1023$. -Considering the restrictions above, the respective minimum and maximum values for the -exponent are: - -1. `00000000001` = $1$, $1 - 1023 = -1022$ -2. `11111111110` = $2046$, $2046 - 1023 = 1023$ - -So, $exponent$ is an integer in the range $\left[-1022, 1023\right]$. - - -##### Denormal Floating Point Numbers - -$exponent$ is always $-1022$. Nevertheless, it is always represented as `00000000000`. - -### Normal and Denormal Floating Point Numbers - -The smallest absolute value a normal floating point number can have is calculated -like this: - -$$1 \times 1.0\dots0 \times 2^{-1022} = 2.2250738585072014 \times 10^{-308}$$ - -Since normal floating point numbers always have a $1$ as the integer part of the -$mantissa$, then smaller values can be achieved by using the smallest possible exponent -( $-1022$ ) and a $0$ in the integer part of the $mantissa$, but significant digits are lost. - -The smallest absolute value a denormal floating point number can have is calculated -like this: - -$$1 \times 2^{-52} \times 2^{-1022} = 5 \times 10^{-324}$$ - -## Zero - -Zero is represented like this: - -* Sign bit: `X` -* Exponent bits: `00000000000` -* Mantissa bits: `0000000000000000000000000000000000000000000000000000` - -where `X` means `0` or `1`. - -## NaN - -There are 2 kinds of NaNs that are represented: - -1. QNaNs (Quiet NaNs): represent the result of indeterminate operations. -2. SNaNs (Signalling NaNs): represent the result of invalid operations. - -### QNaNs - -QNaNs are represented like this: - -* Sign bit: `X` -* Exponent bits: `11111111111` -* Mantissa bits: `1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` - -where `X` means `0` or `1`. - -### SNaNs - -SNaNs are represented like this: - -* Sign bit: `X` -* Exponent bits: `11111111111` -* Mantissa bits: `0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1` - -where `X` means `0` or `1`. - -## Infinite - -### Positive Infinite - -Positive infinite is represented like this: - -* Sign bit: `0` -* Exponent bits: `11111111111` -* Mantissa bits: `0000000000000000000000000000000000000000000000000000` - -where `X` means `0` or `1`. - -### Negative Infinite - -Negative infinite is represented like this: - -* Sign bit: `1` -* Exponent bits: `11111111111` -* Mantissa bits: `0000000000000000000000000000000000000000000000000000` - -where `X` means `0` or `1`. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py deleted file mode 100644 index b1815c42561..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/ieee_754.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from ctypes import c_double, c_uint64 -from sys import float_info - -# IEEE 754 64-bit floating point numbers use 11 bits for the exponent and 52 -# bits for the mantissa. -MANTISSA_WIDTH = 52 -EXPONENT_WIDTH = 11 - -# This mask is equivalent to 52 "1" bits (there are 13 hexadecimal 4-bit "f"s -# in the mantissa mask, 13 * 4 == 52) or 0xfffffffffffff in hexadecimal. -MANTISSA_MASK = (1 << MANTISSA_WIDTH) - 1 - -# There are 11 bits for the exponent, but the exponent values 0 (11 "0" -# bits) and 2047 (11 "1" bits) have special meanings so the exponent range is -# from 1 to 2046. To calculate the exponent value, 1023 (the bias) is -# subtracted from the exponent, so the exponent value range is from -1022 to -# +1023. -EXPONENT_BIAS = (2 ** (EXPONENT_WIDTH - 1)) - 1 - -# All the exponent mask bits are set to 1 for the 11 exponent bits. -EXPONENT_MASK = ((1 << EXPONENT_WIDTH) - 1) << MANTISSA_WIDTH - -# The sign mask has the first bit set to 1 and the rest to 0. -SIGN_MASK = 1 << (EXPONENT_WIDTH + MANTISSA_WIDTH) - -# For normal floating point numbers, the exponent can have a value in the -# range [-1022, 1023]. -MIN_NORMAL_EXPONENT = -EXPONENT_BIAS + 1 -MAX_NORMAL_EXPONENT = EXPONENT_BIAS - -# The smallest possible normal value is 2.2250738585072014e-308. -# This value is the result of using the smallest possible number in the -# mantissa, 1.0000000000000000000000000000000000000000000000000000 (52 "0"s in -# the fractional part) and a single "1" in the exponent. -# Finally 1 * (2 ** -1022) = 2.2250738585072014e-308. -MIN_NORMAL_VALUE = float_info.min - -# Greatest possible normal value (1.7976931348623157e+308) -# The binary representation of a float in scientific notation uses (for the -# mantissa) one bit for the integer part (which is implicit) and 52 bits for -# the fractional part. Consider a float binary 1.111. It is equal to 1 + 1/2 + -# 1/4 + 1/8. The greatest possible value in the 52-bit binary mantissa would be -# then 1.1111111111111111111111111111111111111111111111111111 (52 "1"s in the -# fractional part) whose decimal value is 1.9999999999999998. Finally, -# 1.9999999999999998 * (2 ** 1023) = 1.7976931348623157e+308. -MAX_NORMAL_VALUE = float_info.max - - -def get_ieee_754_exponent(value: float) -> int: - """ - Gets the exponent of the IEEE 754 representation of a float. - """ - - return ( - ( - # This step gives the integer that corresponds to the IEEE 754 - # representation of a float. For example, consider - # -MAX_NORMAL_VALUE for an example. We choose this value because - # of its binary representation which makes easy to understand the - # subsequent operations. - # - # c_uint64.from_buffer(c_double(-MAX_NORMAL_VALUE)).value == 18442240474082181119 - # bin(18442240474082181119) == '0b1111111111101111111111111111111111111111111111111111111111111111' - # - # The first bit of the previous binary number is the sign bit: 1 (1 means negative, 0 means positive) - # The next 11 bits are the exponent bits: 11111111110 - # The next 52 bits are the mantissa bits: 1111111111111111111111111111111111111111111111111111 - # - # This step isolates the exponent bits, turning every bit outside - # of the exponent field (sign and mantissa bits) to 0. - c_uint64.from_buffer(c_double(value)).value & EXPONENT_MASK - # For the example this means: - # 18442240474082181119 & EXPONENT_MASK == 9214364837600034816 - # bin(9214364837600034816) == '0b111111111100000000000000000000000000000000000000000000000000000' - # Notice that the previous binary representation does not include - # leading zeroes, so the sign bit is not included since it is a - # zero. - ) - # This step moves the exponent bits to the right, removing the - # mantissa bits that were set to 0 by the previous step. This - # leaves the IEEE 754 exponent value, ready for the next step. - >> MANTISSA_WIDTH - # For the example this means: - # 9214364837600034816 >> MANTISSA_WIDTH == 2046 - # bin(2046) == '0b11111111110' - # As shown above, these are the original 11 bits that correspond to the - # exponent. - # This step subtracts the exponent bias from the IEEE 754 value, - # leaving the actual exponent value. - ) - EXPONENT_BIAS - # For the example this means: - # 2046 - EXPONENT_BIAS == 1023 - # As mentioned in a comment above, the largest value for the exponent is - - -def get_ieee_754_mantissa(value: float) -> int: - return ( - c_uint64.from_buffer(c_double(value)).value - # This step isolates the mantissa bits. There is no need to do any - # bit shifting as the mantissa bits are already the rightmost field - # in an IEEE 754 representation. - & MANTISSA_MASK - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py deleted file mode 100644 index 6f88f206bf9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/exponential_histogram/mapping/logarithm_mapping.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from math import exp, floor, ldexp, log -from threading import Lock - -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping import ( - Mapping, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.errors import ( - MappingOverflowError, - MappingUnderflowError, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exponential_histogram.mapping.ieee_754 import ( - MAX_NORMAL_EXPONENT, - MIN_NORMAL_EXPONENT, - MIN_NORMAL_VALUE, - get_ieee_754_exponent, - get_ieee_754_mantissa, -) - - -class LogarithmMapping(Mapping): - # Reference implementation here: - # https://github.com/open-telemetry/opentelemetry-go/blob/0e6f9c29c10d6078e8131418e1d1d166c7195d61/sdk/metric/aggregator/exponential/mapping/logarithm/logarithm.go - - _mappings = {} - _mappings_lock = Lock() - - _min_scale = 1 - _max_scale = 20 - - def _get_min_scale(self): - # _min_scale ensures that ExponentMapping is used for zero and negative - # scale values. - return self._min_scale - - def _get_max_scale(self): - # _max_scale is 20. The OpenTelemetry specification requires that - # bucket indices fit within a signed 32-bit integer. At scale 20, - # the maximum bucket index is ((MAX_NORMAL_EXPONENT + 1) << 20) - 1, - # which fits within this range. At scale 21, the maximum bucket - # index reaches the upper limit of a signed 32-bit integer, making - # it difficult to test correctness. See: - # https://github.com/lightstep/otel-launcher-go/blob/c9ca8483be067a39ab306b09060446e7fda65f35/lightstep/sdk/metric/aggregator/histogram/structure/README.md#mapping-function - # https://github.com/open-telemetry/opentelemetry-go/blob/0e6f9c29c10d6078e8131418e1d1d166c7195d61/sdk/metric/aggregator/exponential/mapping/logarithm/logarithm.go#L32-L45 - return self._max_scale - - def _init(self, scale: int): - # pylint: disable=attribute-defined-outside-init - - super()._init(scale) - - # self._scale_factor is defined as a multiplier because multiplication - # is faster than division. self._scale_factor is defined as: - # index = log(value) * self._scale_factor - # Where: - # index = log(value) / log(base) - # index = log(value) / log(2 ** (2 ** -scale)) - # index = log(value) / ((2 ** -scale) * log(2)) - # index = log(value) * ((1 / log(2)) * (2 ** scale)) - # self._scale_factor = ((1 / log(2)) * (2 ** scale)) - # self._scale_factor = (1 /log(2)) * (2 ** scale) - # self._scale_factor = ldexp(1 / log(2), scale) - # This implementation was copied from a Java prototype. See: - # https://github.com/newrelic-experimental/newrelic-sketch-java/blob/1ce245713603d61ba3a4510f6df930a5479cd3f6/src/main/java/com/newrelic/nrsketch/indexer/LogIndexer.java - # for the equations used here. - self._scale_factor = ldexp(1 / log(2), scale) - - # self._min_normal_lower_boundary_index is the index such that - # base ** index == MIN_NORMAL_VALUE. An exponential histogram bucket - # with this index covers the range - # (MIN_NORMAL_VALUE, MIN_NORMAL_VALUE * base]. One less than this index - # corresponds with the bucket containing values <= MIN_NORMAL_VALUE. - self._min_normal_lower_boundary_index = MIN_NORMAL_EXPONENT << self._scale - - # self._max_normal_lower_boundary_index is the index such that - # base ** index equals the greatest representable lower boundary. An - # exponential histogram bucket with this index covers the range - # ((2 ** 1024) / base, 2 ** 1024], which includes opentelemetry.sdk. - # metrics._internal.exponential_histogram.ieee_754.MAX_NORMAL_VALUE. - # This bucket is incomplete, since the upper boundary cannot be - # represented. One greater than this index corresponds with the bucket - # containing values > 2 ** 1024. - self._max_normal_lower_boundary_index = ((MAX_NORMAL_EXPONENT + 1) << self._scale) - 1 - - def map_to_index(self, value: float) -> int: - """ - Maps positive floating point values to indexes corresponding to scale. - """ - - # value is subnormal - if value <= MIN_NORMAL_VALUE: - return self._min_normal_lower_boundary_index - 1 - - # value is an exact power of two. - if get_ieee_754_mantissa(value) == 0: - exponent = get_ieee_754_exponent(value) - return (exponent << self._scale) - 1 - - return min( - floor(log(value) * self._scale_factor), - self._max_normal_lower_boundary_index, - ) - - def get_lower_boundary(self, index: int) -> float: - if index >= self._max_normal_lower_boundary_index: - if index == self._max_normal_lower_boundary_index: - return 2 * exp((index - (1 << self._scale)) / self._scale_factor) - raise MappingOverflowError() - - if index <= self._min_normal_lower_boundary_index: - if index == self._min_normal_lower_boundary_index: - return MIN_NORMAL_VALUE - if index == self._min_normal_lower_boundary_index - 1: - return exp((index + (1 << self._scale)) / self._scale_factor) / 2 - raise MappingUnderflowError() - - return exp(index / self._scale_factor) - - @property - def scale(self) -> int: - return self._scale diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py deleted file mode 100644 index 25ba8c1b323..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/__init__.py +++ /dev/null @@ -1,608 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import math -import os -import weakref -from abc import ABC, abstractmethod -from collections.abc import Callable, Iterable -from enum import Enum -from logging import getLogger -from os import environ, linesep -from sys import stdout -from threading import Event, Lock, RLock, Thread -from time import perf_counter, time_ns -from typing import IO - -from opentelemetry.agent._vendor.typing_extensions import final - -# This kind of import is needed to avoid Sphinx errors. -import opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal -from opentelemetry.agent._vendor import opentelemetry -from opentelemetry.agent._vendor.opentelemetry.context import ( - _SUPPRESS_INSTRUMENTATION_KEY, - attach, - detach, - set_value, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, NoOpMeterProvider -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_METRIC_EXPORT_INTERVAL, - OTEL_METRIC_EXPORT_TIMEOUT, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( - parse_boolean_environment_variable, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal._view_instrument_match import ( - _DEFAULT_CARDINALITY_LIMIT, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( - AggregationTemporality, - DefaultAggregation, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( - Counter, - Gauge, - Histogram, - ObservableCounter, - ObservableGauge, - ObservableUpDownCounter, - UpDownCounter, - _Counter, - _Gauge, - _Histogram, - _ObservableCounter, - _ObservableGauge, - _ObservableUpDownCounter, - _UpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import MetricsData -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OtelComponentTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.util._once import Once - -from ._metric_reader_metrics import create_metric_reader_metrics - -_logger = getLogger(__name__) - - -class MetricExportResult(Enum): - """Result of exporting a metric - - Can be any of the following values:""" - - SUCCESS = 0 - FAILURE = 1 - - -class MetricExporter(ABC): - """Interface for exporting metrics. - - Interface to be implemented by services that want to export metrics received - in their own format. - - Args: - preferred_temporality: Used by `opentelemetry.sdk.metrics.export.PeriodicExportingMetricReader` to - configure exporter level preferred temporality. See `opentelemetry.sdk.metrics.export.MetricReader` for - more details on what preferred temporality is. - preferred_aggregation: Used by `opentelemetry.sdk.metrics.export.PeriodicExportingMetricReader` to - configure exporter level preferred aggregation. See `opentelemetry.sdk.metrics.export.MetricReader` for - more details on what preferred aggregation is. - """ - - def __init__( - self, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, - ) -> None: - self._preferred_temporality = preferred_temporality - self._preferred_aggregation = preferred_aggregation - - @abstractmethod - def export( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> MetricExportResult: - """Exports a batch of telemetry data. - - Args: - metrics: The list of `opentelemetry.sdk.metrics.export.Metric` objects to be exported - - Returns: - The result of the export - """ - - @abstractmethod - def force_flush(self, timeout_millis: float = 10_000) -> bool: - """ - Ensure that export of any metrics currently received by the exporter - are completed as soon as possible. - """ - - @abstractmethod - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - """Shuts down the exporter. - - Called when the SDK is shut down. - """ - - -class ConsoleMetricExporter(MetricExporter): - """Implementation of :class:`MetricExporter` that prints metrics to the - console. - - This class can be used for diagnostic purposes. It prints the exported - metrics to the console STDOUT. - """ - - def __init__( - self, - out: IO = stdout, - formatter: Callable[[MetricsData], str] = lambda metrics_data: metrics_data.to_json() + linesep, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, - ): - super().__init__( - preferred_temporality=preferred_temporality, - preferred_aggregation=preferred_aggregation, - ) - self.out = out - self.formatter = formatter - - def export( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> MetricExportResult: - self.out.write(self.formatter(metrics_data)) - self.out.flush() - return MetricExportResult.SUCCESS - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - pass - - def force_flush(self, timeout_millis: float = 10_000) -> bool: - return True - - -InstrumentCardinalityKey = ( - type[Counter] - | type[UpDownCounter] - | type[Histogram] - | type[Gauge] - | type[ObservableCounter] - | type[ObservableUpDownCounter] - | type[ObservableGauge] -) - -CardinalityLimits = dict[InstrumentCardinalityKey, int] - -_CARDINALITY_INSTRUMENT_CLASSES: dict[type, type] = { - Counter: _Counter, - UpDownCounter: _UpDownCounter, - Histogram: _Histogram, - Gauge: _Gauge, - ObservableCounter: _ObservableCounter, - ObservableUpDownCounter: _ObservableUpDownCounter, - ObservableGauge: _ObservableGauge, -} - - -def _validate_cardinality_limit(typ: type, limit: int) -> type: - """Return the SDK instrument class for ``typ`` after validating ``limit``.""" - if typ not in _CARDINALITY_INSTRUMENT_CLASSES: - raise ValueError(f"Invalid instrument class found {typ}") - if isinstance(limit, bool) or not isinstance(limit, int) or limit < 1: - raise ValueError(f"Cardinality limit for {typ} must be a positive integer, got {limit!r}") - return _CARDINALITY_INSTRUMENT_CLASSES[typ] - - -class MetricReader(ABC): - # pylint: disable=too-many-branches,broad-exception-raised - """ - Base class for all metric readers - - Args: - preferred_temporality: A mapping between instrument classes and - aggregation temporality. By default uses CUMULATIVE for all instrument - classes. This mapping will be used to define the default aggregation - temporality of every instrument class. If the user wants to make a - change in the default aggregation temporality of an instrument class, - it is enough to pass here a dictionary whose keys are the instrument - classes and the values are the corresponding desired aggregation - temporalities of the classes that the user wants to change, not all of - them. The classes not included in the passed dictionary will retain - their association to their default aggregation temporalities. - preferred_aggregation: A mapping between instrument classes and - aggregation instances. By default maps all instrument classes to an - instance of `DefaultAggregation`. This mapping will be used to - define the default aggregation of every instrument class. If the - user wants to make a change in the default aggregation of an - instrument class, it is enough to pass here a dictionary whose keys - are the instrument classes and the values are the corresponding - desired aggregation for the instrument classes that the user wants - to change, not necessarily all of them. The classes not included in - the passed dictionary will retain their association to their - default aggregations. The aggregation defined here will be - overridden by an aggregation defined by a view that is not - `DefaultAggregation`. - cardinality_limits: A dictionary mapping instrument classes to the - maximum number of distinct attribute sets a metric stream of that - instrument class aggregates per collection cycle. Instrument - classes not included use a limit of 2000. A limit defined by a view - takes precedence. Measurements with further attribute sets are - aggregated into one additional point identified by the attribute - ``otel.metric.overflow=true``. - - .. document protected _receive_metrics which is a intended to be overridden by subclass - .. automethod:: _receive_metrics - """ - - def __init__( - self, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, - cardinality_limits: CardinalityLimits | None = None, - *, - otel_component_type: OtelComponentTypeValues | None = None, - ) -> None: - self._collect: ( - Callable[ - [ - opentelemetry.sdk.metrics.export.MetricReader, - AggregationTemporality, - ], - Iterable[opentelemetry.sdk.metrics.export.Metric], - ] - | None - ) = None - - self._instrument_class_temporality = { - _Counter: AggregationTemporality.CUMULATIVE, - _UpDownCounter: AggregationTemporality.CUMULATIVE, - _Histogram: AggregationTemporality.CUMULATIVE, - _Gauge: AggregationTemporality.CUMULATIVE, - _ObservableCounter: AggregationTemporality.CUMULATIVE, - _ObservableUpDownCounter: AggregationTemporality.CUMULATIVE, - _ObservableGauge: AggregationTemporality.CUMULATIVE, - } - - if preferred_temporality is not None: - for temporality in preferred_temporality.values(): - if temporality not in ( - AggregationTemporality.CUMULATIVE, - AggregationTemporality.DELTA, - ): - raise Exception(f"Invalid temporality value found {temporality}") - - if preferred_temporality is not None: - for typ, temporality in preferred_temporality.items(): - if typ is Counter: - self._instrument_class_temporality[_Counter] = temporality - elif typ is UpDownCounter: - self._instrument_class_temporality[_UpDownCounter] = temporality - elif typ is Histogram: - self._instrument_class_temporality[_Histogram] = temporality - elif typ is Gauge: - self._instrument_class_temporality[_Gauge] = temporality - elif typ is ObservableCounter: - self._instrument_class_temporality[_ObservableCounter] = temporality - elif typ is ObservableUpDownCounter: - self._instrument_class_temporality[_ObservableUpDownCounter] = temporality - elif typ is ObservableGauge: - self._instrument_class_temporality[_ObservableGauge] = temporality - else: - raise Exception(f"Invalid instrument class found {typ}") - - self._preferred_temporality = preferred_temporality - self._instrument_class_aggregation = { - _Counter: DefaultAggregation(), - _UpDownCounter: DefaultAggregation(), - _Histogram: DefaultAggregation(), - _Gauge: DefaultAggregation(), - _ObservableCounter: DefaultAggregation(), - _ObservableUpDownCounter: DefaultAggregation(), - _ObservableGauge: DefaultAggregation(), - } - - if preferred_aggregation is not None: - for typ, aggregation in preferred_aggregation.items(): - if typ is Counter: - self._instrument_class_aggregation[_Counter] = aggregation - elif typ is UpDownCounter: - self._instrument_class_aggregation[_UpDownCounter] = aggregation - elif typ is Histogram: - self._instrument_class_aggregation[_Histogram] = aggregation - elif typ is Gauge: - self._instrument_class_aggregation[_Gauge] = aggregation - elif typ is ObservableCounter: - self._instrument_class_aggregation[_ObservableCounter] = aggregation - elif typ is ObservableUpDownCounter: - self._instrument_class_aggregation[_ObservableUpDownCounter] = aggregation - elif typ is ObservableGauge: - self._instrument_class_aggregation[_ObservableGauge] = aggregation - else: - raise Exception(f"Invalid instrument class found {typ}") - - self._instrument_class_cardinality_limit = { - _Counter: _DEFAULT_CARDINALITY_LIMIT, - _UpDownCounter: _DEFAULT_CARDINALITY_LIMIT, - _Histogram: _DEFAULT_CARDINALITY_LIMIT, - _Gauge: _DEFAULT_CARDINALITY_LIMIT, - _ObservableCounter: _DEFAULT_CARDINALITY_LIMIT, - _ObservableUpDownCounter: _DEFAULT_CARDINALITY_LIMIT, - _ObservableGauge: _DEFAULT_CARDINALITY_LIMIT, - } - - if cardinality_limits is not None: - for typ, limit in cardinality_limits.items(): - self._instrument_class_cardinality_limit[_validate_cardinality_limit(typ, limit)] = limit - - self._otel_component_type = otel_component_type.value if otel_component_type else type(self).__qualname__ - self._metrics = create_metric_reader_metrics( - self._otel_component_type, - NoOpMeterProvider(), - parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ) - - @final - def collect(self, timeout_millis: float = 10_000) -> None: - """Collects the metrics from the internal SDK state and - invokes the `_receive_metrics` with the collection. - - Args: - timeout_millis: Amount of time in milliseconds before this function - raises a timeout error. - - If any of the underlying ``collect`` methods called by this method - fails by any reason (including timeout) an exception will be raised - detailing the individual errors that caused this function to fail. - """ - if self._collect is None: - _logger.warning("Cannot call collect on a MetricReader until it is registered on a MeterProvider") - return - - start_time = perf_counter() - try: - metrics = self._collect(self, timeout_millis=timeout_millis) - finally: - self._metrics.record_collection(perf_counter() - start_time) - - if metrics is not None: - self._receive_metrics( - metrics, - timeout_millis=timeout_millis, - ) - - @final - def _set_collect_callback( - self, - func: Callable[ - [ - opentelemetry.sdk.metrics.export.MetricReader, - AggregationTemporality, - ], - MetricsData, - ] - | None, - ) -> None: - """This function is internal to the SDK. It should not be called or overridden by users""" - self._collect = func - - @abstractmethod - def _receive_metrics( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> None: - """Called by `MetricReader.collect` when it receives a batch of metrics""" - - def _set_meter_provider(self, meter_provider: MeterProvider) -> None: - self._metrics = create_metric_reader_metrics( - self._otel_component_type, - meter_provider, - parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ) - - def force_flush(self, timeout_millis: float = 10_000) -> bool: - self.collect(timeout_millis=timeout_millis) - return True - - @abstractmethod - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - """Shuts down the MetricReader. This method provides a way - for the MetricReader to do any cleanup required. A metric reader can - only be shutdown once, any subsequent calls are ignored and return - failure status. - - When a `MetricReader` is registered on a - :class:`~opentelemetry.sdk.metrics.MeterProvider`, - :meth:`~opentelemetry.sdk.metrics.MeterProvider.shutdown` will invoke this - automatically. - """ - - -class InMemoryMetricReader(MetricReader): - """Implementation of `MetricReader` that returns its metrics from :func:`get_metrics_data`. - - This is useful for e.g. unit tests. - """ - - def __init__( - self, - preferred_temporality: dict[type, AggregationTemporality] | None = None, - preferred_aggregation: dict[type, opentelemetry.sdk.metrics.view.Aggregation] | None = None, - cardinality_limits: CardinalityLimits | None = None, - ) -> None: - super().__init__( - preferred_temporality=preferred_temporality, - preferred_aggregation=preferred_aggregation, - cardinality_limits=cardinality_limits, - ) - self._lock = RLock() - self._metrics_data: MetricsData | None = None - - def get_metrics_data( - self, - ) -> MetricsData | None: - """Reads and returns current metrics from the SDK""" - with self._lock: - self.collect() - metrics_data = self._metrics_data - self._metrics_data = None - return metrics_data - - def _receive_metrics( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> None: - with self._lock: - self._metrics_data = metrics_data - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - pass - - -class PeriodicExportingMetricReader(MetricReader): - """`PeriodicExportingMetricReader` is an implementation of `MetricReader` - that collects metrics based on a user-configurable time interval, and passes the - metrics to the configured exporter. If the time interval is set to `math.inf`, the - reader will not invoke periodic collection. - - The configured exporter's :py:meth:`~MetricExporter.export` method will not be called - concurrently. - """ - - def __init__( - self, - exporter: MetricExporter, - export_interval_millis: float | None = None, - export_timeout_millis: float | None = None, - cardinality_limits: CardinalityLimits | None = None, - ) -> None: - # PeriodicExportingMetricReader defers to exporter for configuration - super().__init__( - preferred_temporality=exporter._preferred_temporality, - preferred_aggregation=exporter._preferred_aggregation, - cardinality_limits=cardinality_limits, - otel_component_type=OtelComponentTypeValues.PERIODIC_METRIC_READER, - ) - - # This lock is held whenever calling self._exporter.export() to prevent concurrent - # execution of MetricExporter.export() - # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exportbatch - self._export_lock = Lock() - - self._exporter = exporter - if export_interval_millis is None: - try: - export_interval_millis = float(environ.get(OTEL_METRIC_EXPORT_INTERVAL, 60000)) - except ValueError: - _logger.warning("Found invalid value for export interval, using default") - export_interval_millis = 60000 - if export_timeout_millis is None: - try: - export_timeout_millis = float(environ.get(OTEL_METRIC_EXPORT_TIMEOUT, 30000)) - except ValueError: - _logger.warning("Found invalid value for export timeout, using default") - export_timeout_millis = 30000 - self._export_interval_millis = export_interval_millis - self._export_timeout_millis = export_timeout_millis - self._shutdown = False - self._shutdown_event = Event() - self._shutdown_once = Once() - self._daemon_thread = None - if self._export_interval_millis > 0 and self._export_interval_millis < math.inf: - self._daemon_thread = Thread( - name="OtelPeriodicExportingMetricReader", - target=self._ticker, - daemon=True, - ) - self._daemon_thread.start() - if hasattr(os, "register_at_fork"): - weak_at_fork = weakref.WeakMethod(self._at_fork_reinit) - - def _after_in_child() -> None: - if at_fork := weak_at_fork(): - at_fork() - - os.register_at_fork(after_in_child=_after_in_child) - elif self._export_interval_millis <= 0: - raise ValueError( - f"interval value {self._export_interval_millis} is invalid \ - and needs to be larger than zero." - ) - - def _at_fork_reinit(self): - self._daemon_thread = Thread( - name="OtelPeriodicExportingMetricReader", - target=self._ticker, - daemon=True, - ) - self._daemon_thread.start() - - def _ticker(self) -> None: - interval_secs = self._export_interval_millis / 1e3 - while not self._shutdown_event.wait(interval_secs): - try: - self.collect(timeout_millis=self._export_timeout_millis) - except MetricsTimeoutError: - _logger.warning( - "Metric collection timed out. Will try again after %s seconds", - interval_secs, - exc_info=True, - ) - # one last collection below before shutting down completely - try: - self.collect(timeout_millis=self._export_interval_millis) - except MetricsTimeoutError: - _logger.warning( - "Metric collection timed out.", - exc_info=True, - ) - - def _receive_metrics( - self, - metrics_data: MetricsData, - timeout_millis: float = 10_000, - **kwargs, - ) -> None: - token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) - # pylint: disable=broad-exception-caught,invalid-name - try: - with self._export_lock: - self._exporter.export(metrics_data, timeout_millis=timeout_millis) - except Exception: - _logger.exception("Exception while exporting metrics") - detach(token) - - def shutdown(self, timeout_millis: float = 30_000, **kwargs) -> None: - deadline_ns = time_ns() + timeout_millis * 10**6 - - def _shutdown(): - self._shutdown = True - - did_set = self._shutdown_once.do_once(_shutdown) - if not did_set: - _logger.warning("Can't shutdown multiple times") - return - - self._shutdown_event.set() - if self._daemon_thread: - self._daemon_thread.join(timeout=(deadline_ns - time_ns()) / 10**9) - self._exporter.shutdown(timeout=(deadline_ns - time_ns()) / 10**6) - - def force_flush(self, timeout_millis: float = 10_000) -> bool: - super().force_flush(timeout_millis=timeout_millis) - self._exporter.force_flush(timeout_millis=timeout_millis) - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py deleted file mode 100644 index 2d5fdb606f1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/export/_metric_reader_metrics.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from collections import Counter -from typing import Protocol - -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OTEL_COMPONENT_NAME, - OTEL_COMPONENT_TYPE, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( - create_otel_sdk_metric_reader_collection_duration, -) - -_component_counter = Counter() - - -class MetricReaderMetricsT(Protocol): - def record_collection(self, duration: float) -> None: ... - - -class NoOpMetricReaderMetrics: - def record_collection(self, duration: float) -> None: - pass - - -class MetricReaderMetrics: - def __init__(self, component_type: str, meter_provider: MeterProvider) -> None: - meter = meter_provider.get_meter("opentelemetry-sdk") - - count = _component_counter[component_type] - _component_counter[component_type] = count + 1 - - self._standard_attrs = { - OTEL_COMPONENT_TYPE: component_type, - OTEL_COMPONENT_NAME: f"{component_type}/{count}", - } - - self._collection_duration = create_otel_sdk_metric_reader_collection_duration(meter) - - def record_collection(self, duration: float) -> None: - self._collection_duration.record(duration, self._standard_attrs) - - -def create_metric_reader_metrics( - component_type: str, - meter_provider: MeterProvider, - enabled: bool, -) -> MetricReaderMetricsT: - if not enabled: - return NoOpMetricReaderMetrics() - - return MetricReaderMetrics(component_type, meter_provider) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py deleted file mode 100644 index de372a8fc8d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/instrument.py +++ /dev/null @@ -1,400 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=too-many-ancestors, unused-import -from __future__ import annotations - -import math -from collections.abc import Generator, Iterable, Sequence -from logging import getLogger -from time import time_ns -from typing import ( - TYPE_CHECKING, - Protocol, - cast, - runtime_checkable, -) - -# This kind of import is needed to avoid Sphinx errors. -from opentelemetry.agent._vendor.opentelemetry.context import Context, get_current -from opentelemetry.agent._vendor.opentelemetry.metrics import Asynchronous, CallbackT, Synchronous -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter as APICounter -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram as APIHistogram -from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableCounter as APIObservableCounter -from opentelemetry.agent._vendor.opentelemetry.metrics import ObservableGauge as APIObservableGauge -from opentelemetry.agent._vendor.opentelemetry.metrics import ( - ObservableUpDownCounter as APIObservableUpDownCounter, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import UpDownCounter as APIUpDownCounter -from opentelemetry.agent._vendor.opentelemetry.metrics import _Gauge as APIGauge -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import ( - CallbackOptions, - _MetricsHistogramAdvisory, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -if TYPE_CHECKING: - from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal import ( - _ProxyMeterConfig, - ) - from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement_consumer import ( - MeasurementConsumer, - ) - from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope - - -_logger = getLogger(__name__) - - -_NAME_ERROR_MESSAGE = "Expected ASCII string of maximum length 255 characters but got {}" -_UNIT_ERROR_MESSAGE = "Expected ASCII string of maximum length 63 characters but got {}" - - -@runtime_checkable -class _Instrument(Protocol): - name: str - unit: str - description: str - instrumentation_scope: InstrumentationScope - - -class _Synchronous(_Instrument, Synchronous): - def __init__( - self, - name: str, - instrumentation_scope: InstrumentationScope, - measurement_consumer: MeasurementConsumer, - unit: str = "", - description: str = "", - *, - _meter_config: _ProxyMeterConfig | None = None, - ): - # pylint: disable=no-member - result = self._check_name_unit_description(name, unit, description) - - if result["name"] is None: - # pylint: disable=broad-exception-raised - raise Exception(_NAME_ERROR_MESSAGE.format(name)) - - if result["unit"] is None: - # pylint: disable=broad-exception-raised - raise Exception(_UNIT_ERROR_MESSAGE.format(unit)) - - name = result["name"] - unit = result["unit"] - description = cast(str, result["description"]) - - self.name = name.lower() - self.unit = unit - self.description = description - self.instrumentation_scope = instrumentation_scope - self._measurement_consumer = measurement_consumer - self._meter_config = _meter_config - super().__init__(name, unit=unit, description=description) - - def _is_enabled(self) -> bool: - return self._meter_config is None or self._meter_config.is_enabled - - -class _Asynchronous(_Instrument, Asynchronous): - def __init__( - self, - name: str, - instrumentation_scope: InstrumentationScope, - measurement_consumer: MeasurementConsumer, - callbacks: Sequence[CallbackT] | None = None, - unit: str = "", - description: str = "", - *, - _meter_config: _ProxyMeterConfig | None = None, - ): - # pylint: disable=no-member - result = self._check_name_unit_description(name, unit, description) - - if result["name"] is None: - # pylint: disable=broad-exception-raised - raise Exception(_NAME_ERROR_MESSAGE.format(name)) - - if result["unit"] is None: - # pylint: disable=broad-exception-raised - raise Exception(_UNIT_ERROR_MESSAGE.format(unit)) - - name = result["name"] - unit = result["unit"] - description = cast(str, result["description"]) - - self.name = name.lower() - self.unit = unit - self.description = description - self.instrumentation_scope = instrumentation_scope - self._measurement_consumer = measurement_consumer - self._meter_config = _meter_config - super().__init__(name, callbacks, unit=unit, description=description) - - self._callbacks: list[CallbackT] = [] - - if callbacks is not None: - for callback in callbacks: - if isinstance(callback, Generator): - # advance generator to it's first yield - next(callback) - - def inner( - options: CallbackOptions, - callback=callback, - ) -> Iterable[Measurement]: - try: - return callback.send(options) - except StopIteration: - return [] - - self._callbacks.append(inner) - else: - self._callbacks.append(callback) - - def _is_enabled(self) -> bool: - return self._meter_config is None or self._meter_config.is_enabled - - def callback(self, callback_options: CallbackOptions) -> Iterable[Measurement]: - if not self._is_enabled(): - return - for callback in self._callbacks: - try: - for api_measurement in callback(callback_options): - if not math.isfinite(api_measurement.value): - _logger.warning( - "Callback returned a non-finite value %s for instrument %s, ignoring measurement.", - api_measurement.value, - self.name, - ) - continue - yield Measurement( - api_measurement.value, - time_unix_nano=time_ns(), - instrument=self, - context=api_measurement.context or get_current(), - attributes=api_measurement.attributes, - ) - except Exception: # pylint: disable=broad-exception-caught - _logger.exception("Callback failed for instrument %s.", self.name) - - -class Counter(_Synchronous, APICounter): - def __new__(cls, *args, **kwargs): - if cls is Counter: - raise TypeError("Counter must be instantiated via a meter.") - return super().__new__(cls) - - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ): - if not self._is_enabled(): - super().add(amount, attributes=attributes, context=context) - return - - if not math.isfinite(amount): - _logger.warning( - "Add amount %s is not finite on Counter %s, ignoring measurement.", - amount, - self.name, - ) - return - if amount < 0: - _logger.warning("Add amount must be non-negative on Counter %s.", self.name) - return - time_unix_nano = time_ns() - self._measurement_consumer.consume_measurement( - Measurement( - amount, - time_unix_nano, - self, - context or get_current(), - attributes, - ) - ) - - -class UpDownCounter(_Synchronous, APIUpDownCounter): - def __new__(cls, *args, **kwargs): - if cls is UpDownCounter: - raise TypeError("UpDownCounter must be instantiated via a meter.") - return super().__new__(cls) - - def add( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ): - if not self._is_enabled(): - super().add(amount, attributes=attributes, context=context) - return - - if not math.isfinite(amount): - _logger.warning( - "Add amount %s is not finite on UpDownCounter %s, ignoring measurement.", - amount, - self.name, - ) - return - time_unix_nano = time_ns() - self._measurement_consumer.consume_measurement( - Measurement( - amount, - time_unix_nano, - self, - context or get_current(), - attributes, - ) - ) - - -class ObservableCounter(_Asynchronous, APIObservableCounter): - def __new__(cls, *args, **kwargs): - if cls is ObservableCounter: - raise TypeError("ObservableCounter must be instantiated via a meter.") - return super().__new__(cls) - - -class ObservableUpDownCounter(_Asynchronous, APIObservableUpDownCounter): - def __new__(cls, *args, **kwargs): - if cls is ObservableUpDownCounter: - raise TypeError("ObservableUpDownCounter must be instantiated via a meter.") - return super().__new__(cls) - - -class Histogram(_Synchronous, APIHistogram): - def __init__( - self, - name: str, - instrumentation_scope: InstrumentationScope, - measurement_consumer: MeasurementConsumer, - unit: str = "", - description: str = "", - explicit_bucket_boundaries_advisory: Sequence[float] | None = None, - *, - _meter_config: _ProxyMeterConfig | None = None, - ): - super().__init__( - name, - unit=unit, - description=description, - instrumentation_scope=instrumentation_scope, - measurement_consumer=measurement_consumer, - _meter_config=_meter_config, - ) - self._advisory = _MetricsHistogramAdvisory(explicit_bucket_boundaries=explicit_bucket_boundaries_advisory) - - def __new__(cls, *args, **kwargs): - if cls is Histogram: - raise TypeError("Histogram must be instantiated via a meter.") - return super().__new__(cls) - - def record( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ): - if not self._is_enabled(): - super().record(amount, attributes=attributes, context=context) - return - - if not math.isfinite(amount): - _logger.warning( - "Record amount %s is not finite on Histogram %s, ignoring measurement.", - amount, - self.name, - ) - return - if amount < 0: - _logger.warning( - "Record amount must be non-negative on Histogram %s.", - self.name, - ) - return - time_unix_nano = time_ns() - self._measurement_consumer.consume_measurement( - Measurement( - amount, - time_unix_nano, - self, - context or get_current(), - attributes, - ) - ) - - -class Gauge(_Synchronous, APIGauge): - def __new__(cls, *args, **kwargs): - if cls is Gauge: - raise TypeError("Gauge must be instantiated via a meter.") - return super().__new__(cls) - - def set( - self, - amount: float, - attributes: Attributes = None, - context: Context | None = None, - ): - if not self._is_enabled(): - super().set(amount, attributes=attributes, context=context) - return - - if not math.isfinite(amount): - _logger.warning( - "Set amount %s is not finite on Gauge %s, ignoring measurement.", - amount, - self.name, - ) - return - time_unix_nano = time_ns() - self._measurement_consumer.consume_measurement( - Measurement( - amount, - time_unix_nano, - self, - context or get_current(), - attributes, - ) - ) - - -class ObservableGauge(_Asynchronous, APIObservableGauge): - def __new__(cls, *args, **kwargs): - if cls is ObservableGauge: - raise TypeError("ObservableGauge must be instantiated via a meter.") - return super().__new__(cls) - - -# Below classes exist to prevent the direct instantiation -class _Counter(Counter): - pass - - -class _UpDownCounter(UpDownCounter): - pass - - -class _ObservableCounter(ObservableCounter): - pass - - -class _ObservableUpDownCounter(ObservableUpDownCounter): - pass - - -class _Histogram(Histogram): - pass - - -class _Gauge(Gauge): - pass - - -class _ObservableGauge(ObservableGauge): - pass diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py deleted file mode 100644 index a95a14aabf0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Mapping -from dataclasses import dataclass -from logging import getLogger -from typing import TYPE_CHECKING - -from opentelemetry.agent._vendor.opentelemetry.attributes import _clean_attribute_value -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -_logger = getLogger(__name__) - -if TYPE_CHECKING: - from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument - - -@dataclass(frozen=True) -class Measurement: - """ - Represents a data point reported via the metrics API to the SDK. - - Attributes: - value: Measured value - time_unix_nano: The time the API call was made to record the Measurement - instrument: The instrument that produced this `Measurement`. - context: The active Context of the Measurement at API call time. - attributes: Measurement attributes. Mutating mutable attribute values (lists or dicts) - outside of the Measurement object can lead to undefined and bad behavior. - """ - - value: int | float - time_unix_nano: int - instrument: _Instrument - context: Context - attributes: Attributes = None - - def __post_init__(self) -> None: - if self.attributes is not None: - if isinstance(self.attributes, Mapping): - object.__setattr__( - self, - "attributes", - _clean_attribute_value(self.attributes, None), - ) - else: - _logger.warning( - "Invalid type '%s' for attributes. Expected a Mapping or None.", - type(self.attributes), - ) - object.__setattr__(self, "attributes", None) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py deleted file mode 100644 index 9bbf1d527c8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/measurement_consumer.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=unused-import - -from abc import ABC, abstractmethod -from collections.abc import Iterable, Mapping -from threading import Lock -from time import time_ns - -# This kind of import is needed to avoid Sphinx errors. -import opentelemetry.agent._vendor.opentelemetry.sdk.metrics -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument -from opentelemetry.agent._vendor import opentelemetry -from opentelemetry.agent._vendor.opentelemetry.metrics._internal.instrument import CallbackOptions -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.metric_reader_storage import ( - MetricReaderStorage, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import MetricsData - - -class MeasurementConsumer(ABC): - @abstractmethod - def consume_measurement(self, measurement: Measurement) -> None: - pass - - @abstractmethod - def register_asynchronous_instrument( - self, - instrument: ("opentelemetry.sdk.metrics._internal.instrument._Asynchronous"), - ): - pass - - @abstractmethod - def collect( - self, - metric_reader: "opentelemetry.sdk.metrics.export.MetricReader", - timeout_millis: float = 10_000, - ) -> MetricsData | None: - pass - - -class SynchronousMeasurementConsumer(MeasurementConsumer): - def __init__( - self, - sdk_config: "opentelemetry.sdk.metrics._internal.sdk_configuration.SdkConfiguration", - metric_readers: Iterable["opentelemetry.sdk.metrics.MetricReader"], - ) -> None: - self._lock = Lock() - self._sdk_config = sdk_config - self._reader_storages: Mapping[opentelemetry.sdk.metrics.export.MetricReader, MetricReaderStorage] = { - reader: MetricReaderStorage( - sdk_config, - reader._instrument_class_temporality, - reader._instrument_class_aggregation, - reader._instrument_class_cardinality_limit, - ) - for reader in metric_readers - } - self._async_instruments: list[opentelemetry.sdk.metrics._internal.instrument._Asynchronous] = [] - - def consume_measurement(self, measurement: Measurement) -> None: - should_sample_exemplar = self._sdk_config.exemplar_filter.should_sample( - measurement.value, - measurement.time_unix_nano, - measurement.attributes, - measurement.context, - ) - # `_reader_storages` is replaced (never mutated in place) by - # `add_metric_reader` and `remove_metric_reader`, so it is safe - # to iterate over without a lock. - for reader_storage in self._reader_storages.values(): - reader_storage.consume_measurement(measurement, should_sample_exemplar) - - def register_asynchronous_instrument( - self, - instrument: ("opentelemetry.sdk.metrics._internal.instrument._Asynchronous"), - ) -> None: - with self._lock: - self._async_instruments.append(instrument) - - def collect( - self, - metric_reader: "opentelemetry.sdk.metrics.export.MetricReader", - timeout_millis: float = 10_000, - ) -> MetricsData | None: - with self._lock: - metric_reader_storage = self._reader_storages[metric_reader] - # for now, just use the defaults - callback_options = CallbackOptions() - deadline_ns = time_ns() + (timeout_millis * 1e6) - - default_timeout_ns = 10000 * 1e6 - - for async_instrument in self._async_instruments: - remaining_time = deadline_ns - time_ns() - - if remaining_time < default_timeout_ns: - callback_options = CallbackOptions(timeout_millis=remaining_time / 1e6) - - measurements = async_instrument.callback(callback_options) - if time_ns() >= deadline_ns: - raise MetricsTimeoutError("Timed out while executing callback") - - for measurement in measurements: - should_sample_exemplar = self._sdk_config.exemplar_filter.should_sample( - measurement.value, - measurement.time_unix_nano, - measurement.attributes, - measurement.context, - ) - metric_reader_storage.consume_measurement(measurement, should_sample_exemplar) - - result = self._reader_storages[metric_reader].collect() - - return result - - def add_metric_reader(self, metric_reader: "opentelemetry.sdk.metrics.MetricReader") -> None: - """Registers a new metric reader.""" - # Build a new mapping and swap it in atomically so that - # a concurrent consume_measurement never iterates a mapping - # that is being mutated in place. - with self._lock: - new_reader_storages = dict(self._reader_storages) - new_reader_storages[metric_reader] = MetricReaderStorage( - self._sdk_config, - # pylint: disable-next=protected-access - metric_reader._instrument_class_temporality, - # pylint: disable-next=protected-access - metric_reader._instrument_class_aggregation, - # pylint: disable-next=protected-access - metric_reader._instrument_class_cardinality_limit, - ) - self._reader_storages = new_reader_storages - - def remove_metric_reader(self, metric_reader: "opentelemetry.sdk.metrics.MetricReader") -> None: - """Unregisters the given metric reader.""" - # Mutate using copy-on-write: see add_metric_reader. - with self._lock: - new_reader_storages = dict(self._reader_storages) - new_reader_storages.pop(metric_reader) - self._reader_storages = new_reader_storages diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py deleted file mode 100644 index 76eb7efd07e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/metric_reader_storage.py +++ /dev/null @@ -1,285 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from logging import getLogger -from threading import RLock -from time import time_ns - -from opentelemetry.agent._vendor.opentelemetry.metrics import ( - Asynchronous, - Counter, - ObservableCounter, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal._view_instrument_match import ( - _DEFAULT_CARDINALITY_LIMIT, - _ViewInstrumentMatch, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( - Aggregation, - AggregationTemporality, - ExplicitBucketHistogramAggregation, - ExponentialBucketHistogramAggregation, - _DropAggregation, - _ExplicitBucketHistogramAggregation, - _ExponentialBucketHistogramAggregation, - _LastValueAggregation, - _SumAggregation, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import ( - _Asynchronous, - _Instrument, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.measurement import Measurement -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( - ExponentialHistogram, - Gauge, - Histogram, - Metric, - MetricsData, - ResourceMetrics, - ScopeMetrics, - Sum, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.sdk_configuration import ( - SdkConfiguration, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.view import View -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope - -_logger = getLogger(__name__) - -_DEFAULT_VIEW = View(instrument_name="") - - -class MetricReaderStorage: - """The SDK's storage for a given reader""" - - def __init__( - self, - sdk_config: SdkConfiguration, - instrument_class_temporality: dict[type, AggregationTemporality], - instrument_class_aggregation: dict[type, Aggregation], - instrument_class_cardinality_limit: dict[type, int] | None = None, - ) -> None: - self._lock = RLock() - self._sdk_config = sdk_config - self._instrument_view_instrument_matches: dict[_Instrument, list[_ViewInstrumentMatch]] = {} - self._instrument_class_temporality = instrument_class_temporality - self._instrument_class_aggregation = instrument_class_aggregation - self._instrument_class_cardinality_limit = instrument_class_cardinality_limit or {} - - def _new_view_instrument_match(self, view: View, instrument: _Instrument) -> _ViewInstrumentMatch: - # pylint: disable=protected-access - cardinality_limit = view._aggregation_cardinality_limit - if cardinality_limit is None: - cardinality_limit = self._instrument_class_cardinality_limit.get( - instrument.__class__, _DEFAULT_CARDINALITY_LIMIT - ) - - # Idle attribute sets of synchronous instruments are only released on - # delta collection, so that the limit applies per collection cycle. - # Asynchronous instruments keep their state, which delta conversion - # relies on. - reset_on_collect = self._instrument_class_temporality[ - instrument.__class__ - ] is AggregationTemporality.DELTA and not isinstance(instrument, _Asynchronous) - - return _ViewInstrumentMatch( - view=view, - instrument=instrument, - instrument_class_aggregation=self._instrument_class_aggregation, - cardinality_limit=cardinality_limit, - reset_on_collect=reset_on_collect, - ) - - def _get_or_init_view_instrument_match(self, instrument: _Instrument) -> list[_ViewInstrumentMatch]: - # Optimistically get the relevant views for the given instrument. Once set for a given - # instrument, the mapping will never change - - if instrument in self._instrument_view_instrument_matches: - return self._instrument_view_instrument_matches[instrument] - - with self._lock: - # double check if it was set before we held the lock - if instrument in self._instrument_view_instrument_matches: - return self._instrument_view_instrument_matches[instrument] - - # not present, hold the lock and add a new mapping - view_instrument_matches = [] - - self._handle_view_instrument_match(instrument, view_instrument_matches) - - # if no view targeted the instrument, use the default - if not view_instrument_matches: - view_instrument_matches.append(self._new_view_instrument_match(_DEFAULT_VIEW, instrument)) - self._instrument_view_instrument_matches[instrument] = view_instrument_matches - - return view_instrument_matches - - def consume_measurement(self, measurement: Measurement, should_sample_exemplar: bool = True) -> None: - for view_instrument_match in self._get_or_init_view_instrument_match(measurement.instrument): - view_instrument_match.consume_measurement(measurement, should_sample_exemplar) - - def collect(self) -> MetricsData | None: - # Use a list instead of yielding to prevent a slow reader from holding - # SDK locks - - # While holding the lock, new _ViewInstrumentMatch can't be added from - # another thread (so we are sure we collect all existing view). - # However, instruments can still send measurements that will make it - # into the individual aggregations; collection will acquire those locks - # iteratively to keep locking as fine-grained as possible. One side - # effect is that end times can be slightly skewed among the metric - # streams produced by the SDK, but we still align the output timestamps - # for a single instrument. - - collection_start_nanos = time_ns() - - with self._lock: - instrumentation_scope_scope_metrics: dict[InstrumentationScope, ScopeMetrics] = {} - - instrument_matches_snapshot = list(self._instrument_view_instrument_matches.items()) - - for ( - instrument, - view_instrument_matches, - ) in instrument_matches_snapshot: - aggregation_temporality = self._instrument_class_temporality[instrument.__class__] - - metrics: list[Metric] = [] - - for view_instrument_match in view_instrument_matches: - data_points = view_instrument_match.collect(aggregation_temporality, collection_start_nanos) - - if data_points is None: - continue - - if isinstance( - # pylint: disable=protected-access - view_instrument_match._aggregation, - _SumAggregation, - ): - data = Sum( - aggregation_temporality=aggregation_temporality, - data_points=data_points, - is_monotonic=isinstance(instrument, (Counter, ObservableCounter)), - ) - elif isinstance( - # pylint: disable=protected-access - view_instrument_match._aggregation, - _LastValueAggregation, - ): - data = Gauge(data_points=data_points) - elif isinstance( - # pylint: disable=protected-access - view_instrument_match._aggregation, - _ExplicitBucketHistogramAggregation, - ): - data = Histogram( - data_points=data_points, - aggregation_temporality=aggregation_temporality, - ) - elif isinstance( - # pylint: disable=protected-access - view_instrument_match._aggregation, - _DropAggregation, - ): - continue - - elif isinstance( - # pylint: disable=protected-access - view_instrument_match._aggregation, - _ExponentialBucketHistogramAggregation, - ): - data = ExponentialHistogram( - data_points=data_points, - aggregation_temporality=aggregation_temporality, - ) - - metrics.append( - Metric( - # pylint: disable=protected-access - # pylint: disable=possibly-used-before-assignment - name=view_instrument_match._name, - description=view_instrument_match._description, - unit=view_instrument_match._instrument.unit, - data=data, - ) - ) - - if metrics: - if instrument.instrumentation_scope not in (instrumentation_scope_scope_metrics): - instrumentation_scope_scope_metrics[instrument.instrumentation_scope] = ScopeMetrics( - scope=instrument.instrumentation_scope, - metrics=metrics, - schema_url=instrument.instrumentation_scope.schema_url, - ) - else: - instrumentation_scope_scope_metrics[instrument.instrumentation_scope].metrics.extend(metrics) - - if instrumentation_scope_scope_metrics: - return MetricsData( - resource_metrics=[ - ResourceMetrics( - resource=self._sdk_config.resource, - scope_metrics=list(instrumentation_scope_scope_metrics.values()), - schema_url=self._sdk_config.resource.schema_url, - ) - ] - ) - - return None - - def _handle_view_instrument_match( - self, - instrument: _Instrument, - view_instrument_matches: list["_ViewInstrumentMatch"], - ) -> None: - for view in self._sdk_config.views: - # pylint: disable=protected-access - if not view._match(instrument): - continue - - if not self._check_view_instrument_compatibility(view, instrument): - continue - - new_view_instrument_match = self._new_view_instrument_match(view, instrument) - - for existing_view_instrument_matches in self._instrument_view_instrument_matches.values(): - for existing_view_instrument_match in existing_view_instrument_matches: - if existing_view_instrument_match.conflicts(new_view_instrument_match): - _logger.warning( - "Views %s and %s will cause conflicting metrics identities", - existing_view_instrument_match._view, - new_view_instrument_match._view, - ) - - view_instrument_matches.append(new_view_instrument_match) - - @staticmethod - def _check_view_instrument_compatibility(view: View, instrument: _Instrument) -> bool: - """ - Checks if a view and an instrument are compatible. - - Returns `true` if they are compatible and a `_ViewInstrumentMatch` - object should be created, `false` otherwise. - """ - - result = True - - # pylint: disable=protected-access - if isinstance(instrument, Asynchronous) and isinstance( - view._aggregation, - ( - ExplicitBucketHistogramAggregation, - ExponentialBucketHistogramAggregation, - ), - ): - _logger.warning( - "View %s and instrument %s will produce semantic errors when matched, the view has not been applied.", - view, - instrument, - ) - result = False - - return result diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py deleted file mode 100644 index 641b55cd4c7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/point.py +++ /dev/null @@ -1,240 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=unused-import - -from collections.abc import Sequence -from dataclasses import asdict, dataclass, field -from json import dumps, loads - -# This kind of import is needed to avoid Sphinx errors. -import opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal -from opentelemetry.agent._vendor import opentelemetry -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import Exemplar -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import Resource -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import InstrumentationScope -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - - -@dataclass(frozen=True) -class NumberDataPoint: - """Single data point in a timeseries that describes the time-varying scalar - value of a metric. - """ - - attributes: Attributes - start_time_unix_nano: int - time_unix_nano: int - value: int | float - exemplars: Sequence[Exemplar] = field(default_factory=list) - - def to_json(self, indent: int | None = 4) -> str: - return dumps(asdict(self), indent=indent) - - -@dataclass(frozen=True) -class HistogramDataPoint: - """Single data point in a timeseries that describes the time-varying scalar - value of a metric. - """ - - attributes: Attributes - start_time_unix_nano: int - time_unix_nano: int - count: int - sum: int | float - bucket_counts: Sequence[int] - explicit_bounds: Sequence[float] - min: float - max: float - exemplars: Sequence[Exemplar] = field(default_factory=list) - - def to_json(self, indent: int | None = 4) -> str: - return dumps(asdict(self), indent=indent) - - -@dataclass(frozen=True) -class Buckets: - offset: int - bucket_counts: Sequence[int] - - -@dataclass(frozen=True) -class ExponentialHistogramDataPoint: - """Single data point in a timeseries whose boundaries are defined by an - exponential function. This timeseries describes the time-varying scalar - value of a metric. - """ - - attributes: Attributes - start_time_unix_nano: int - time_unix_nano: int - count: int - sum: int | float - scale: int - zero_count: int - positive: Buckets - negative: Buckets - flags: int - min: float - max: float - exemplars: Sequence[Exemplar] = field(default_factory=list) - - def to_json(self, indent: int | None = 4) -> str: - return dumps(asdict(self), indent=indent) - - -@dataclass(frozen=True) -class ExponentialHistogram: - """Represents the type of a metric that is calculated by aggregating as an - ExponentialHistogram of all reported measurements over a time interval. - """ - - data_points: Sequence[ExponentialHistogramDataPoint] - aggregation_temporality: "opentelemetry.sdk.metrics.export.AggregationTemporality" - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], - "aggregation_temporality": self.aggregation_temporality, - }, - indent=indent, - ) - - -@dataclass(frozen=True) -class Sum: - """Represents the type of a scalar metric that is calculated as a sum of - all reported measurements over a time interval.""" - - data_points: Sequence[NumberDataPoint] - aggregation_temporality: "opentelemetry.sdk.metrics.export.AggregationTemporality" - is_monotonic: bool - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], - "aggregation_temporality": self.aggregation_temporality, - "is_monotonic": self.is_monotonic, - }, - indent=indent, - ) - - -@dataclass(frozen=True) -class Gauge: - """Represents the type of a scalar metric that always exports the current - value for every data point. It should be used for an unknown - aggregation.""" - - data_points: Sequence[NumberDataPoint] - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], - }, - indent=indent, - ) - - -@dataclass(frozen=True) -class Histogram: - """Represents the type of a metric that is calculated by aggregating as a - histogram of all reported measurements over a time interval.""" - - data_points: Sequence[HistogramDataPoint] - aggregation_temporality: "opentelemetry.sdk.metrics.export.AggregationTemporality" - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "data_points": [loads(data_point.to_json(indent=indent)) for data_point in self.data_points], - "aggregation_temporality": self.aggregation_temporality, - }, - indent=indent, - ) - - -# pylint: disable=invalid-name -DataT = Sum | Gauge | Histogram | ExponentialHistogram -DataPointT = NumberDataPoint | HistogramDataPoint | ExponentialHistogramDataPoint - - -@dataclass(frozen=True) -class Metric: - """Represents a metric point in the OpenTelemetry data model to be - exported.""" - - name: str - description: str | None - unit: str | None - data: DataT - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "name": self.name, - "description": self.description or "", - "unit": self.unit or "", - "data": loads(self.data.to_json(indent=indent)), - }, - indent=indent, - ) - - -@dataclass(frozen=True) -class ScopeMetrics: - """A collection of Metrics produced by a scope""" - - scope: InstrumentationScope - metrics: Sequence[Metric] - schema_url: str - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "scope": loads(self.scope.to_json(indent=indent)), - "metrics": [loads(metric.to_json(indent=indent)) for metric in self.metrics], - "schema_url": self.schema_url, - }, - indent=indent, - ) - - -@dataclass(frozen=True) -class ResourceMetrics: - """A collection of ScopeMetrics from a Resource""" - - resource: Resource - scope_metrics: Sequence[ScopeMetrics] - schema_url: str - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "resource": loads(self.resource.to_json(indent=indent)), - "scope_metrics": [loads(scope_metrics.to_json(indent=indent)) for scope_metrics in self.scope_metrics], - "schema_url": self.schema_url, - }, - indent=indent, - ) - - -@dataclass(frozen=True) -class MetricsData: - """An array of ResourceMetrics""" - - resource_metrics: Sequence[ResourceMetrics] - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "resource_metrics": [ - loads(resource_metrics.to_json(indent=indent)) for resource_metrics in self.resource_metrics - ] - }, - indent=indent, - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py deleted file mode 100644 index 3f372371560..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/sdk_configuration.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=unused-import - -from collections.abc import Sequence -from dataclasses import dataclass - -# This kind of import is needed to avoid Sphinx errors. -import opentelemetry.agent._vendor.opentelemetry.sdk.metrics -from opentelemetry.agent._vendor import opentelemetry -import opentelemetry.agent._vendor.opentelemetry.sdk.resources -from opentelemetry.agent._vendor import opentelemetry - - -@dataclass -class SdkConfiguration: - exemplar_filter: "opentelemetry.sdk.metrics.ExemplarFilter" - resource: "opentelemetry.sdk.resources.Resource" - views: Sequence["opentelemetry.sdk.metrics.view.View"] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py deleted file mode 100644 index b4689bad76d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/_internal/view.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable -from fnmatch import fnmatchcase -from logging import getLogger - -from opentelemetry.agent._vendor.opentelemetry.metrics import Instrument -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( - Aggregation, - DefaultAggregation, - _Aggregation, - _ExplicitBucketHistogramAggregation, - _ExponentialBucketHistogramAggregation, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.exemplar import ( - AlignedHistogramBucketExemplarReservoir, - ExemplarReservoirBuilder, - SimpleFixedSizeExemplarReservoir, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.instrument import _Instrument - -_logger = getLogger(__name__) - - -def _default_reservoir_factory( - aggregation_type: type[_Aggregation], -) -> ExemplarReservoirBuilder: - """Default reservoir factory per aggregation.""" - if issubclass(aggregation_type, _ExplicitBucketHistogramAggregation): - return AlignedHistogramBucketExemplarReservoir - if issubclass(aggregation_type, _ExponentialBucketHistogramAggregation): - return SimpleFixedSizeExemplarReservoir - return SimpleFixedSizeExemplarReservoir - - -class View: - """ - A `View` configuration parameters can be used for the following - purposes: - - 1. Match instruments: When an instrument matches a view, measurements - received by that instrument will be processed. - 2. Customize metric streams: A metric stream is identified by a match - between a view and an instrument and a set of attributes. The metric - stream can be customized by certain attributes of the corresponding view. - - The attributes documented next serve one of the previous two purposes. - - Args: - instrument_type: This is an instrument matching attribute: the class the - instrument must be to match the view. - - instrument_name: This is an instrument matching attribute: the name the - instrument must have to match the view. Wild card characters are supported. Wild - card characters should not be used with this attribute if the view has also a - ``name`` defined. - - meter_name: This is an instrument matching attribute: the name the - instrument meter must have to match the view. - - meter_version: This is an instrument matching attribute: the version - the instrument meter must have to match the view. - - meter_schema_url: This is an instrument matching attribute: the schema - URL the instrument meter must have to match the view. - - name: This is a metric stream customizing attribute: the name of the - metric stream. If `None`, the name of the instrument will be used. - - description: This is a metric stream customizing attribute: the - description of the metric stream. If `None`, the description of the instrument will - be used. - - attribute_keys: This is a metric stream customizing attribute: this is - a set of attribute keys. If not `None` then only the measurement attributes that - are in ``attribute_keys`` will be used to identify the metric stream. - - aggregation: This is a metric stream customizing attribute: the - aggregation instance to use when data is aggregated for the - corresponding metrics stream. If `None` an instance of - `DefaultAggregation` will be used. - - exemplar_reservoir_factory: This is a metric stream customizing attribute: - the exemplar reservoir factory - - instrument_unit: This is an instrument matching attribute: the unit the - instrument must have to match the view. - - aggregation_cardinality_limit: This is a metric stream customizing - attribute: the maximum number of distinct attribute sets the - stream aggregates per collection cycle. Measurements with further - attribute sets are aggregated into one additional point identified - by the attribute ``otel.metric.overflow=true``. If `None` the - cardinality limit of the metric reader is used, which defaults to - 2000. Must be a positive integer. - - This class is not intended to be subclassed by the user. - """ - - _default_aggregation = DefaultAggregation() - - def __init__( - self, - instrument_type: type[Instrument] | None = None, - instrument_name: str | None = None, - meter_name: str | None = None, - meter_version: str | None = None, - meter_schema_url: str | None = None, - name: str | None = None, - description: str | None = None, - attribute_keys: set[str] | None = None, - aggregation: Aggregation | None = None, - exemplar_reservoir_factory: Callable[[type[_Aggregation]], ExemplarReservoirBuilder] | None = None, - instrument_unit: str | None = None, - aggregation_cardinality_limit: int | None = None, - ): - if aggregation_cardinality_limit is not None and ( - isinstance(aggregation_cardinality_limit, bool) - or not isinstance(aggregation_cardinality_limit, int) - or aggregation_cardinality_limit < 1 - ): - raise ValueError( - f"aggregation_cardinality_limit must be a positive integer, got {aggregation_cardinality_limit!r}" - ) - - if ( - instrument_type - is instrument_name - is instrument_unit - is meter_name - is meter_version - is meter_schema_url - is None - ): - # pylint: disable=broad-exception-raised - raise Exception(f"Some instrument selection criteria must be provided for View {name}") - - if name is not None and instrument_name is not None and ("*" in instrument_name or "?" in instrument_name): - # pylint: disable=broad-exception-raised - raise Exception(f"View {name} declared with wildcard characters in instrument_name") - - # _name, _description, _aggregation, _exemplar_reservoir_factory, - # _attribute_keys and _aggregation_cardinality_limit will be accessed - # when instantiating a _ViewInstrumentMatch. - self._name = name - self._instrument_type = instrument_type - self._instrument_name = instrument_name - self._instrument_unit = instrument_unit - self._meter_name = meter_name - self._meter_version = meter_version - self._meter_schema_url = meter_schema_url - - self._description = description - self._attribute_keys = attribute_keys - self._aggregation = aggregation or self._default_aggregation - self._exemplar_reservoir_factory = exemplar_reservoir_factory or _default_reservoir_factory - self._aggregation_cardinality_limit = aggregation_cardinality_limit - - # pylint: disable=too-many-return-statements - # pylint: disable=too-many-branches - def _match(self, instrument: _Instrument) -> bool: - if self._instrument_type is not None: - if not isinstance(instrument, self._instrument_type): - return False - - if self._instrument_name is not None: - # Instrument names are treated case-insensitively and are stored - # lower-cased by the SDK, so the pattern is lower-cased to match. - # fnmatchcase is used instead of fnmatch so it does not rely - # on the host platform's filename case sensitivity (normcase). - if not fnmatchcase(instrument.name, self._instrument_name.lower()): - return False - - if self._instrument_unit is not None: - # Units are case-sensitive; fnmatchcase keeps matching consistent - # across platforms. - if not fnmatchcase(instrument.unit, self._instrument_unit): - return False - - if self._meter_name is not None: - if instrument.instrumentation_scope.name != self._meter_name: - return False - - if self._meter_version is not None: - if instrument.instrumentation_scope.version != self._meter_version: - return False - - if self._meter_schema_url is not None: - if instrument.instrumentation_scope.schema_url != self._meter_schema_url: - return False - - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py deleted file mode 100644 index e8f17f684e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/export/__init__.py +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( - AggregationTemporality, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.export import ( - CardinalityLimits, - ConsoleMetricExporter, - InMemoryMetricReader, - InstrumentCardinalityKey, - MetricExporter, - MetricExportResult, - MetricReader, - PeriodicExportingMetricReader, -) - -# The point module is not in the export directory to avoid a circular import. -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.point import ( - Buckets, - DataPointT, - DataT, - ExponentialHistogram, - ExponentialHistogramDataPoint, - Gauge, - Histogram, - HistogramDataPoint, - Metric, - MetricsData, - NumberDataPoint, - ResourceMetrics, - ScopeMetrics, - Sum, -) - -__all__ = [ - "AggregationTemporality", - "Buckets", - "CardinalityLimits", - "ConsoleMetricExporter", - "DataPointT", - "DataT", - "ExponentialHistogram", - "ExponentialHistogramDataPoint", - "Gauge", - "Histogram", - "HistogramDataPoint", - "InMemoryMetricReader", - "InstrumentCardinalityKey", - "Metric", - "MetricExportResult", - "MetricExporter", - "MetricReader", - "MetricsData", - "NumberDataPoint", - "PeriodicExportingMetricReader", - "ResourceMetrics", - "ScopeMetrics", - "Sum", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py deleted file mode 100644 index 4f661ffd2c4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/metrics/view/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.aggregation import ( - Aggregation, - DefaultAggregation, - DropAggregation, - ExplicitBucketHistogramAggregation, - ExponentialBucketHistogramAggregation, - LastValueAggregation, - SumAggregation, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.metrics._internal.view import View - -__all__ = [ - "Aggregation", - "DefaultAggregation", - "DropAggregation", - "ExplicitBucketHistogramAggregation", - "ExponentialBucketHistogramAggregation", - "LastValueAggregation", - "SumAggregation", - "View", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py deleted file mode 100644 index 3008bcb616f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/resources/__init__.py +++ /dev/null @@ -1,776 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -This package implements `OpenTelemetry Resources -`_: - - *A Resource is an immutable representation of the entity producing - telemetry. For example, a process producing telemetry that is running in - a container on Kubernetes has a Pod name, it is in a namespace and - possibly is part of a Deployment which also has a name. All three of - these attributes can be included in the Resource.* - -Resource objects are created with `Resource.create`, which accepts attributes -(key-values). Resources should NOT be created via constructor except by `ResourceDetector` -instances which can't use `Resource.create` to avoid infinite loops. Working with -`Resource` objects should only be done via the Resource API methods. Resource -attributes can also be passed at process invocation in the -:envvar:`OTEL_RESOURCE_ATTRIBUTES` environment variable. You should register -your resource with the `opentelemetry.sdk.trace.TracerProvider` by passing -them into their constructors. The `Resource` passed to a provider is available -to the exporter, which can send on this information as it sees fit. - -.. code-block:: python - - trace.set_tracer_provider( - TracerProvider( - resource=Resource.create( - { - "service.name": "shoppingcart", - "service.instance.id": "instance-12", - } - ), - ), - ) - print(trace.get_tracer_provider().resource.attributes) - - { - "telemetry.sdk.language": "python", - "telemetry.sdk.name": "opentelemetry", - "telemetry.sdk.version": "0.13.dev0", - "service.name": "shoppingcart", - "service.instance.id": "instance-12", - } - -Note that the OpenTelemetry project documents certain `"standard attributes" -`_ -that have prescribed semantic meanings, for example ``service.name`` in the -above example. -""" - -# ResourceAttributes is deprecated -# pyright: reportDeprecated=false - -import abc -import concurrent.futures -import logging -import os -import platform -import socket -import subprocess -import sys -import threading -import uuid -from collections.abc import Mapping, Sequence -from json import dumps -from os import environ -from types import ModuleType -from urllib import parse - -from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, - OTEL_RESOURCE_ATTRIBUTES, - OTEL_SERVICE_NAME, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.version import ( - __version__ as _OPENTELEMETRY_SDK_VERSION, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.resource import ResourceAttributes -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue - -psutil: ModuleType | None = None - -try: - import psutil as psutil_module - - psutil = psutil_module -except ImportError: - pass - -# Only available on Windows, where it is used to read the MachineGuid for host.id. -winreg: ModuleType | None = None - -try: - import winreg as winreg_module - - winreg = winreg_module -except ImportError: - pass - -LabelValue = AnyValue -Attributes = Mapping[str, LabelValue] -logger = logging.getLogger(__name__) -CLOUD_PROVIDER = ResourceAttributes.CLOUD_PROVIDER -CLOUD_ACCOUNT_ID = ResourceAttributes.CLOUD_ACCOUNT_ID -CLOUD_REGION = ResourceAttributes.CLOUD_REGION -CLOUD_AVAILABILITY_ZONE = ResourceAttributes.CLOUD_AVAILABILITY_ZONE -CONTAINER_NAME = ResourceAttributes.CONTAINER_NAME -CONTAINER_ID = ResourceAttributes.CONTAINER_ID -CONTAINER_IMAGE_NAME = ResourceAttributes.CONTAINER_IMAGE_NAME -CONTAINER_IMAGE_TAG = ResourceAttributes.CONTAINER_IMAGE_TAG -DEPLOYMENT_ENVIRONMENT = ResourceAttributes.DEPLOYMENT_ENVIRONMENT -FAAS_NAME = ResourceAttributes.FAAS_NAME -FAAS_ID = ResourceAttributes.FAAS_ID -FAAS_VERSION = ResourceAttributes.FAAS_VERSION -FAAS_INSTANCE = ResourceAttributes.FAAS_INSTANCE -HOST_NAME = ResourceAttributes.HOST_NAME -HOST_ARCH = ResourceAttributes.HOST_ARCH -HOST_ID = ResourceAttributes.HOST_ID -HOST_TYPE = ResourceAttributes.HOST_TYPE -HOST_IMAGE_NAME = ResourceAttributes.HOST_IMAGE_NAME -HOST_IMAGE_ID = ResourceAttributes.HOST_IMAGE_ID -HOST_IMAGE_VERSION = ResourceAttributes.HOST_IMAGE_VERSION -KUBERNETES_CLUSTER_NAME = ResourceAttributes.K8S_CLUSTER_NAME -KUBERNETES_NAMESPACE_NAME = ResourceAttributes.K8S_NAMESPACE_NAME -KUBERNETES_POD_UID = ResourceAttributes.K8S_POD_UID -KUBERNETES_POD_NAME = ResourceAttributes.K8S_POD_NAME -KUBERNETES_CONTAINER_NAME = ResourceAttributes.K8S_CONTAINER_NAME -KUBERNETES_REPLICA_SET_UID = ResourceAttributes.K8S_REPLICASET_UID -KUBERNETES_REPLICA_SET_NAME = ResourceAttributes.K8S_REPLICASET_NAME -KUBERNETES_DEPLOYMENT_UID = ResourceAttributes.K8S_DEPLOYMENT_UID -KUBERNETES_DEPLOYMENT_NAME = ResourceAttributes.K8S_DEPLOYMENT_NAME -KUBERNETES_STATEFUL_SET_UID = ResourceAttributes.K8S_STATEFULSET_UID -KUBERNETES_STATEFUL_SET_NAME = ResourceAttributes.K8S_STATEFULSET_NAME -KUBERNETES_DAEMON_SET_UID = ResourceAttributes.K8S_DAEMONSET_UID -KUBERNETES_DAEMON_SET_NAME = ResourceAttributes.K8S_DAEMONSET_NAME -KUBERNETES_JOB_UID = ResourceAttributes.K8S_JOB_UID -KUBERNETES_JOB_NAME = ResourceAttributes.K8S_JOB_NAME -KUBERNETES_CRON_JOB_UID = ResourceAttributes.K8S_CRONJOB_UID -KUBERNETES_CRON_JOB_NAME = ResourceAttributes.K8S_CRONJOB_NAME -OS_DESCRIPTION = ResourceAttributes.OS_DESCRIPTION -OS_TYPE = ResourceAttributes.OS_TYPE -OS_VERSION = ResourceAttributes.OS_VERSION -PROCESS_PID = ResourceAttributes.PROCESS_PID -PROCESS_PARENT_PID = ResourceAttributes.PROCESS_PARENT_PID -PROCESS_EXECUTABLE_NAME = ResourceAttributes.PROCESS_EXECUTABLE_NAME -PROCESS_EXECUTABLE_PATH = ResourceAttributes.PROCESS_EXECUTABLE_PATH -PROCESS_COMMAND = ResourceAttributes.PROCESS_COMMAND -PROCESS_COMMAND_LINE = ResourceAttributes.PROCESS_COMMAND_LINE -PROCESS_COMMAND_ARGS = ResourceAttributes.PROCESS_COMMAND_ARGS -PROCESS_OWNER = ResourceAttributes.PROCESS_OWNER -PROCESS_RUNTIME_NAME = ResourceAttributes.PROCESS_RUNTIME_NAME -PROCESS_RUNTIME_VERSION = ResourceAttributes.PROCESS_RUNTIME_VERSION -PROCESS_RUNTIME_DESCRIPTION = ResourceAttributes.PROCESS_RUNTIME_DESCRIPTION -SERVICE_NAME = ResourceAttributes.SERVICE_NAME -SERVICE_NAMESPACE = ResourceAttributes.SERVICE_NAMESPACE -SERVICE_INSTANCE_ID = ResourceAttributes.SERVICE_INSTANCE_ID -SERVICE_VERSION = ResourceAttributes.SERVICE_VERSION -TELEMETRY_SDK_NAME = ResourceAttributes.TELEMETRY_SDK_NAME -TELEMETRY_SDK_VERSION = ResourceAttributes.TELEMETRY_SDK_VERSION -TELEMETRY_AUTO_VERSION = ResourceAttributes.TELEMETRY_AUTO_VERSION -TELEMETRY_SDK_LANGUAGE = ResourceAttributes.TELEMETRY_SDK_LANGUAGE - - -class Resource: - """A Resource is an immutable representation of the entity producing telemetry as Attributes.""" - - _attributes: BoundedAttributes - _schema_url: str - - def __init__(self, attributes: Attributes, schema_url: str | None = None): - # Immutable set to true so attributes cannot be added or removed after creation. - self._attributes = BoundedAttributes(attributes=attributes, immutable=True) - if schema_url is None: - schema_url = "" - self._schema_url = schema_url - - @staticmethod - def create( - attributes: Attributes | None = None, - schema_url: str | None = None, - ) -> "Resource": - """Creates a new `Resource` from attributes. - - `ResourceDetector` instances should not call this method. - - Args: - attributes: Optional zero or more key-value pairs. - schema_url: Optional URL pointing to the schema - - Returns: - The newly-created Resource. - """ - - if not attributes: - attributes = {} - - resource = get_aggregated_resources(_build_resource_detectors(), _DEFAULT_RESOURCE).merge( - Resource(attributes, schema_url) - ) - - if not resource.attributes.get(SERVICE_NAME, None): - default_service_name = "unknown_service" - if sys.executable: - default_service_name += f":{os.path.basename(sys.executable)}" - resource = resource.merge(Resource({SERVICE_NAME: default_service_name}, schema_url)) - return resource - - @staticmethod - def get_empty() -> "Resource": - return _EMPTY_RESOURCE - - @property - def attributes(self) -> Attributes: - return self._attributes - - @property - def schema_url(self) -> str: - return self._schema_url - - def merge(self, other: "Resource") -> "Resource": - """Merges this resource and an updating resource into a new `Resource`. - - If a key exists on both the old and updating resource, the value of the - updating resource will override the old resource value. - - The updating resource's `schema_url` will be used only if the old - `schema_url` is empty. Attempting to merge two resources with - different, non-empty values for `schema_url` will result in an error - and return the old resource. - - Args: - other: The other resource to be merged. - - Returns: - The newly-created Resource. - """ - merged_attributes = dict(self.attributes) - merged_attributes.update(other.attributes) - - if self.schema_url == "": - schema_url = other.schema_url - elif other.schema_url == "": - schema_url = self.schema_url - elif self.schema_url == other.schema_url: - schema_url = other.schema_url - else: - logger.error( - "Failed to merge resources: The two schemas %s and %s are incompatible", - self.schema_url, - other.schema_url, - ) - return self - return Resource(merged_attributes, schema_url) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Resource): - return False - return self._attributes == other._attributes and self._schema_url == other._schema_url - - def __hash__(self) -> int: - return hash(f"{dumps(self._attributes.copy(), sort_keys=True, default=_json_default)}|{self._schema_url}") - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "attributes": dict(self.attributes), - "schema_url": self._schema_url, - }, - indent=indent, - default=_json_default, - ) - - -def _json_default(value: object) -> str: - """Represent attribute values that `json` cannot encode natively. - - `types.AnyValue` admits `bytes`, which `json.dumps` rejects. Rendering it - as hex keeps `to_json` readable and keeps `__hash__` working; `__eq__` - still distinguishes `b"\x01"` from the string `"01"`, so the resulting - hash collision is harmless. - """ - if isinstance(value, (bytes, bytearray)): - return value.hex() - return str(value) - - -_EMPTY_RESOURCE = Resource({}) - -_DEFAULT_RESOURCE = Resource( - { - TELEMETRY_SDK_LANGUAGE: "python", - TELEMETRY_SDK_NAME: "opentelemetry", - TELEMETRY_SDK_VERSION: _OPENTELEMETRY_SDK_VERSION, - } -) - - -_service_instance_id: str | None = None -_service_instance_id_pid: int | None = None -_service_instance_id_lock = threading.Lock() - - -class ResourceDetector(abc.ABC): - def __init__(self, raise_on_error: bool = False) -> None: - self.raise_on_error = raise_on_error - - @abc.abstractmethod - def detect(self) -> "Resource": - """Don't call `Resource.create` here to avoid an infinite loop, instead instantiate `Resource` directly""" - raise NotImplementedError() - - # pylint: disable-next=no-self-use - def is_process_dependent(self) -> bool: - """Return whether this detector depends on the current process identity. - - Process dependent detectors may return resource attributes that become - stale after a process identity change, such as :func:`os.fork`. - Detectors returning ``True`` should be re-run after such changes so the - resulting :class:`Resource` describes the current process. - - Returns: - ``True`` if this detector should be re-run after process identity - changes otherwise ``False``. - """ - return False - - -class OTELResourceDetector(ResourceDetector): - # pylint: disable=no-self-use - def detect(self) -> "Resource": - env_resources_items = environ.get(OTEL_RESOURCE_ATTRIBUTES) - env_resource_map: dict[str, AnyValue] = {} - - if env_resources_items: - for item in env_resources_items.split(","): - try: - key, value = item.split("=", maxsplit=1) - except ValueError as exc: - logger.warning( - "Invalid key value resource attribute pair %s: %s", - item, - exc, - ) - continue - value_url_decoded = parse.unquote(value.strip()) - env_resource_map[key.strip()] = value_url_decoded - - service_name = environ.get(OTEL_SERVICE_NAME) - if service_name: - env_resource_map[SERVICE_NAME] = service_name - return Resource(env_resource_map) - - -class ProcessResourceDetector(ResourceDetector): - """Detect process resource attributes. - - Args: - raise_on_error: Raise errors from detection instead of logging them. - include_command_args: Include ``process.command_args`` and - ``process.command_line``. These attributes can contain sensitive - command-line values, so they are excluded by default. - """ - - def __init__( - self, - raise_on_error: bool = False, - *, - include_command_args: bool = False, - ) -> None: - super().__init__(raise_on_error=raise_on_error) - self._include_command_args = include_command_args - - # pylint: disable=no-self-use - def is_process_dependent(self) -> bool: - return True - - def detect(self) -> "Resource": - _runtime_version = ".".join( - map( - str, - ( - sys.version_info[:3] - if sys.version_info.releaselevel == "final" and not sys.version_info.serial - else sys.version_info - ), - ) - ) - _process_pid = os.getpid() - # Use sys.orig_argv, which preserves the original arguments received - # by the interpreter. This correctly captures ``python -m `` - # invocations where sys.argv is rewritten to the resolved module path - # and the ``-m `` information is lost. Only read argv[0] by - # default because full command arguments are opt-in. - _process_command = sys.orig_argv[0] if sys.orig_argv else "" - executable = sys.executable or "" - resource_info: dict[str, AnyValue] = { - PROCESS_RUNTIME_DESCRIPTION: sys.version, - PROCESS_RUNTIME_NAME: sys.implementation.name, - PROCESS_RUNTIME_VERSION: _runtime_version, - PROCESS_PID: _process_pid, - PROCESS_EXECUTABLE_NAME: os.path.basename(executable), - PROCESS_EXECUTABLE_PATH: executable, - PROCESS_COMMAND: _process_command, - } - if self._include_command_args: - _process_argv = list(sys.orig_argv) - resource_info[PROCESS_COMMAND_LINE] = " ".join(_process_argv) - resource_info[PROCESS_COMMAND_ARGS] = _process_argv - - if hasattr(os, "getppid"): - # pypy3 does not have getppid() - resource_info[PROCESS_PARENT_PID] = os.getppid() - - if psutil is not None: - process = psutil.Process() - username = process.username() - resource_info[PROCESS_OWNER] = username - - return Resource(resource_info) # type: ignore - - -class OsResourceDetector(ResourceDetector): - """Detect os resources based on `Operating System conventions `_.""" - - def detect(self) -> "Resource": - """Returns a resource with with ``os.type`` and ``os.version``. - - Python's platform library - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - To grab this information, Python's ``platform`` does not return what a - user might expect it to. Below is a breakdown of its return values in - different operating systems. - - .. code-block:: python - :caption: Linux - - >>> platform.system() - 'Linux' - >>> platform.release() - '6.5.0-35-generic' - >>> platform.version() - '#35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2' - - .. code-block:: python - :caption: MacOS - - >>> platform.system() - 'Darwin' - >>> platform.release() - '23.0.0' - >>> platform.version() - 'Darwin Kernel Version 23.0.0: Fri Sep 15 14:42:57 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T8112' - - .. code-block:: python - :caption: Windows - - >>> platform.system() - 'Windows' - >>> platform.release() - '2022Server' - >>> platform.version() - '10.0.20348' - - .. code-block:: python - :caption: FreeBSD - - >>> platform.system() - 'FreeBSD' - >>> platform.release() - '14.1-RELEASE' - >>> platform.version() - 'FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC' - - .. code-block:: python - :caption: Solaris - - >>> platform.system() - 'SunOS' - >>> platform.release() - '5.11' - >>> platform.version() - '11.4.0.15.0' - - """ - - os_type = platform.system().lower() - os_version = platform.release() - - # See docstring - if os_type == "windows": - os_version = platform.version() - # Align SunOS with conventions - elif os_type == "sunos": - os_type = "solaris" - os_version = platform.version() - - return Resource( - { - OS_TYPE: os_type, - OS_VERSION: os_version, - } - ) - - -# Non-privileged machine id sources per the semantic conventions: -# https://opentelemetry.io/docs/specs/semconv/resource/host/#non-privileged-machine-id-lookup -_LINUX_MACHINE_ID_PATHS = ("/etc/machine-id", "/var/lib/dbus/machine-id") -_BSD_HOSTID_PATH = "/etc/hostid" -_BSD_KENV_COMMAND = ("/bin/kenv", "-q", "smbios.system.uuid") -_MACOS_IOREG_COMMAND = ("/usr/sbin/ioreg", "-rd1", "-c", "IOPlatformExpertDevice") -_WINDOWS_CRYPTOGRAPHY_KEY = r"SOFTWARE\Microsoft\Cryptography" -_WINDOWS_MACHINE_GUID_VALUE = "MachineGuid" -# Deliberately below get_aggregated_resources' per detector timeout so that a -# hung command still leaves time for host.name and host.arch to be returned. -_COMMAND_TIMEOUT_SECONDS = 2 - - -def _read_machine_id_file(path: str) -> str | None: - try: - with open(path, encoding="utf8") as machine_id_file: - return machine_id_file.read().strip() or None - except OSError as exception: - logger.debug("Failed to read %s: %s", path, exception) - return None - - -def _run_command(command: tuple[str, ...]) -> str: - """Returns the command's stdout, or "" when the source is unavailable here. - - A non-zero exit or a missing binary means this host has no machine id to - offer. - """ - try: - completed = subprocess.run( - command, - capture_output=True, - text=True, - timeout=_COMMAND_TIMEOUT_SECONDS, - check=True, - ) - except (subprocess.CalledProcessError, FileNotFoundError) as exception: - logger.debug("Failed to run %s: %s", command[0], exception) - return "" - return completed.stdout - - -def _get_linux_machine_id() -> str | None: - for path in _LINUX_MACHINE_ID_PATHS: - machine_id = _read_machine_id_file(path) - if machine_id: - return machine_id - return None - - -def _get_bsd_machine_id() -> str | None: - return _read_machine_id_file(_BSD_HOSTID_PATH) or _run_command(_BSD_KENV_COMMAND).strip() or None - - -def _get_macos_machine_id() -> str | None: - for line in _run_command(_MACOS_IOREG_COMMAND).splitlines(): - # The line looks like: ` "IOPlatformUUID" = "AAAAAAAA-BBBB-..."` - key, separator, value = line.partition("=") - if not separator or key.strip().strip('"') != "IOPlatformUUID": - continue - - machine_id = value.strip().strip('"') - if machine_id: - return machine_id - return None - - -def _get_windows_machine_id() -> str | None: - if winreg is None: - logger.debug("winreg is unavailable, cannot detect %s", HOST_ID) - return None - with winreg.OpenKey( - winreg.HKEY_LOCAL_MACHINE, - _WINDOWS_CRYPTOGRAPHY_KEY, - access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY, - ) as key: - machine_guid, _ = winreg.QueryValueEx(key, _WINDOWS_MACHINE_GUID_VALUE) - return str(machine_guid) if machine_guid else None - - -def _get_host_id() -> str | None: - system = platform.system() - if system == "Linux": - return _get_linux_machine_id() - if system == "Darwin": - return _get_macos_machine_id() - if system == "Windows": - return _get_windows_machine_id() - if system == "DragonFly" or system.endswith("BSD"): - return _get_bsd_machine_id() - logger.debug("Unsupported OS type for %s detection: %s", HOST_ID, system) - return None - - -class _HostResourceDetector(ResourceDetector): # type: ignore[reportUnusedClass] - """ - The HostResourceDetector detects the hostname, architecture and host id - attributes. - - ``host.id`` is the non-privileged machine id described by the `Host resource - conventions `_, - and is omitted when it cannot be determined. A failed lookup does not - prevent ``host.name`` and ``host.arch`` from being detected unless - ``raise_on_error=True``. - """ - - def detect(self) -> "Resource": - resource_info: dict[str, AnyValue] = { - HOST_NAME: socket.gethostname(), - HOST_ARCH: platform.machine(), - } - - # A failed host id lookup must not cost the caller the attributes above, - # so it is guarded here rather than relying on the handling in - # get_aggregated_resources: detect() is also called directly. - try: - if host_id := _get_host_id(): - resource_info[HOST_ID] = host_id - # pylint: disable=broad-exception-caught - except Exception as exception: - logger.warning("Failed to detect %s: %s", HOST_ID, exception) - if self.raise_on_error: - raise - - return Resource(resource_info) - - -class ServiceInstanceIdResourceDetector(ResourceDetector): - """Detects service.instance.id as a random UUID v4. - - Per the OpenTelemetry specification, SDKs SHOULD generate a random v1/v4 - UUID for service.instance.id to uniquely identify each service instance. - The ID is shared across all detector instances within the same process and - regenerated automatically when the process PID changes (e.g. after a fork). - - Note: because this detector is process dependent, providers refresh it - automatically after a fork and merge the newly detected value on top of - the existing resource. This means that if a user explicitly sets - `service.instance.id` (e.g. via OTEL_RESOURCE_ATTRIBUTES or - Resource.create(attributes=...)), that value will be overwritten with a - newly generated UUID the next time the process forks. This differs from - Resource.create(), which does preserve user supplied overrides. - """ - - def is_process_dependent(self) -> bool: - return True - - def detect(self) -> "Resource": - # pylint: disable-next=global-statement - global _service_instance_id, _service_instance_id_pid - with _service_instance_id_lock: - current_pid = os.getpid() - if _service_instance_id is None or _service_instance_id_pid != current_pid: - _service_instance_id = str(uuid.uuid4()) - _service_instance_id_pid = current_pid - instance_id = _service_instance_id - return Resource({SERVICE_INSTANCE_ID: instance_id}) - - -def _build_resource_detectors() -> list["ResourceDetector"]: - """Returns the ordered list of resource detectors to use for Resource.create. - - Fast path: if no extra detectors are configured, returns only the two - built-in detectors without scanning entry_points. - - "service_instance" (ServiceInstanceIdResourceDetector) is prepended unless - it is explicitly configured. "otel" (OTELResourceDetector) is last so - that OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME take highest merge - priority, but an explicit position in - OTEL_EXPERIMENTAL_RESOURCE_DETECTORS is respected for either name. - """ - configured_detector_names = [ - name.strip() for name in environ.get(OTEL_EXPERIMENTAL_RESOURCE_DETECTORS, "").split(",") if name.strip() - ] - default_detector_names = [] if "service_instance" in configured_detector_names else ["service_instance"] - detector_names: list[str] = list(dict.fromkeys(default_detector_names + configured_detector_names + ["otel"])) - - # Fast path: only the two built-in detectors — no entry_points scan needed. - if detector_names == ["service_instance", "otel"]: - return [ServiceInstanceIdResourceDetector(), OTELResourceDetector()] - - # pylint: disable=import-outside-toplevel - from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 - entry_points, # type: ignore[reportUnknownVariableType] - ) - - if "*" in detector_names: - registered = set( - name - for name in entry_points(group="opentelemetry_resource_detector").names # type: ignore[reportUnknownArgumentType] - if name != "otel" - ) - expansion = sorted(registered - set(detector_names)) - idx = detector_names.index("*") - detector_names = detector_names[:idx] + expansion + detector_names[idx + 1 :] - - detectors: list[ResourceDetector] = [] - for name in detector_names: - try: - detectors.append( - next( - iter( - entry_points( - group="opentelemetry_resource_detector", - name=name, - ) # type: ignore[reportUnknownArgumentType] - ) - ).load()() - ) - except Exception: # pylint: disable=broad-exception-caught - logger.exception( - "Failed to load resource detector '%s', skipping", - name, - ) - return detectors - - -def _get_process_dependent_resource() -> Resource: # pyright: ignore[reportUnusedFunction] - return get_aggregated_resources( - [detector for detector in _build_resource_detectors() if detector.is_process_dependent()], - Resource.get_empty(), - ) - - -def get_aggregated_resources( - detectors: Sequence["ResourceDetector"], - initial_resource: Resource | None = None, - timeout: int = 5, -) -> "Resource": - """Retrieves resources from detectors in the order that they were passed - - :param detectors: List of resources in order of priority - :param initial_resource: Static resource. This has highest priority - :param timeout: Number of seconds to wait for each detector to return - :return: - """ - detectors_merged_resource = initial_resource or Resource.create() - - # A detector that exceeds `timeout` is skipped, but shutdown still joins - # its worker so no threads outlive this call. A detector that blocks - # indefinitely therefore blocks this call. `cancel_futures=True` drops - # detectors that have not started yet if a `raise_on_error` detector raises. - executor = concurrent.futures.ThreadPoolExecutor(max_workers=4) - try: - futures = [executor.submit(detector.detect) for detector in detectors] - for detector_ind, future in enumerate(futures): - detector = detectors[detector_ind] - detected_resource: Resource = _EMPTY_RESOURCE - try: - detected_resource = future.result(timeout=timeout) - except concurrent.futures.TimeoutError as ex: - if detector.raise_on_error: - raise ex - logger.warning( - "Detector %s took longer than %s seconds, skipping", - detector, - timeout, - ) - # pylint: disable=broad-exception-caught - except Exception as ex: - if detector.raise_on_error: - raise ex - logger.warning("Exception %s in detector %s, ignoring", ex, detector) - finally: - detectors_merged_resource = detectors_merged_resource.merge(detected_resource) - finally: - executor.shutdown(wait=True, cancel_futures=True) - - return detectors_merged_resource diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py deleted file mode 100644 index 1f7ab187dec..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/__init__.py +++ /dev/null @@ -1,1426 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=too-many-lines -import abc -import atexit -import concurrent.futures -import json -import logging -import os -import threading -import traceback -import typing -import weakref -from collections.abc import ( - Callable, - Iterator, - Mapping, - MutableMapping, - Sequence, -) -from dataclasses import dataclass -from os import environ -from time import time_ns -from types import MappingProxyType, TracebackType -from typing import ( - Any, -) -from warnings import filterwarnings - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry import context as context_api -from opentelemetry.agent._vendor.opentelemetry import metrics as metrics_api -from opentelemetry.agent._vendor.opentelemetry import trace as trace_api -from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes -from opentelemetry.agent._vendor.opentelemetry.sdk import util -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_ATTRIBUTE_COUNT_LIMIT, - OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, - OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, - OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, - OTEL_SDK_DISABLED, - OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, - OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, - OTEL_SPAN_EVENT_COUNT_LIMIT, - OTEL_SPAN_LINK_COUNT_LIMIT, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( - parse_boolean_environment_variable, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.resources import ( - Resource, - _get_process_dependent_resource, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import sampling -from opentelemetry.agent._vendor.opentelemetry.sdk.trace._tracer_metrics import create_tracer_metrics -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.id_generator import IdGenerator, RandomIdGenerator -from opentelemetry.agent._vendor.opentelemetry.sdk.util import BoundedList -from opentelemetry.agent._vendor.opentelemetry.sdk.util._configurator import RuleBasedConfigurator -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( - InstrumentationInfo, - InstrumentationScope, -) -from opentelemetry.agent._vendor.opentelemetry.semconv.attributes.exception_attributes import ( - EXCEPTION_ESCAPED, - EXCEPTION_MESSAGE, - EXCEPTION_STACKTRACE, - EXCEPTION_TYPE, -) -from opentelemetry.agent._vendor.opentelemetry.trace import NoOpTracer, SpanContext -from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode -from opentelemetry.agent._vendor.opentelemetry.util import types -from opentelemetry.agent._vendor.opentelemetry.util._decorator import _agnosticcontextmanager - -logger = logging.getLogger(__name__) - -_DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT = 128 -_DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = 128 -_DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT = 128 -_DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT = 128 -_DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT = 128 -_DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT = 128 - - -_ENV_VALUE_UNSET = "" - - -class SpanProcessor: - """Interface which allows hooks for SDK's `Span` start and end method - invocations. - - Span processors can be registered directly using - :func:`TracerProvider.add_span_processor` and they are invoked - in the same order as they were registered. - """ - - def on_start( - self, - span: "Span", - parent_context: context_api.Context | None = None, - ) -> None: - """Called when a :class:`opentelemetry.trace.Span` is started. - - This method is called synchronously on the thread that starts the - span, therefore it should not block or throw an exception. - - Args: - span: The :class:`opentelemetry.trace.Span` that just started. - parent_context: The parent context of the span that just started. - """ - - def _on_ending(self, span: "Span") -> None: - """Called when a :class:`opentelemetry.trace.Span` is ending. - - This method is called synchronously on the thread that ends the - span, therefore it should not block or throw an exception. - - Args: - span: The :class:`opentelemetry.trace.Span` that is ending. - """ - - def on_end(self, span: "ReadableSpan") -> None: - """Called when a :class:`opentelemetry.trace.Span` is ended. - - This method is called synchronously on the thread that ends the - span, therefore it should not block or throw an exception. - - Args: - span: The :class:`opentelemetry.trace.Span` that just ended. - """ - - def shutdown(self) -> None: - """Called when a :class:`opentelemetry.sdk.trace.TracerProvider` is shutdown.""" - - def force_flush(self, timeout_millis: int = 30000) -> bool: # pylint: disable=no-self-use - """Export all ended spans to the configured Exporter that have not yet - been exported. - - Args: - timeout_millis: The maximum amount of time to wait for spans to be - exported. - - Returns: - False if the timeout is exceeded, True otherwise. - """ - return True - - -# Temporary fix until https://github.com/PyCQA/pylint/issues/4098 is resolved -# pylint:disable=no-member -class SynchronousMultiSpanProcessor(SpanProcessor): - """Implementation of class:`SpanProcessor` that forwards all received - events to a list of span processors sequentially. - - The underlying span processors are called in sequential order as they were - added. - """ - - _span_processors: tuple[SpanProcessor, ...] - - def __init__(self): - # use a tuple to avoid race conditions when adding a new span and - # iterating through it on "on_start" and "on_end". - self._span_processors = () - self._lock = threading.Lock() - - def add_span_processor(self, span_processor: SpanProcessor) -> None: - """Adds a SpanProcessor to the list handled by this instance.""" - with self._lock: - self._span_processors += (span_processor,) - - def on_start( - self, - span: "Span", - parent_context: context_api.Context | None = None, - ) -> None: - for sp in self._span_processors: - sp.on_start(span, parent_context=parent_context) - - def _on_ending(self, span: "Span") -> None: - for sp in self._span_processors: - # pylint: disable=protected-access - sp._on_ending(span) - - def on_end(self, span: "ReadableSpan") -> None: - for sp in self._span_processors: - sp.on_end(span) - - def shutdown(self) -> None: - """Sequentially shuts down all underlying span processors.""" - for sp in self._span_processors: - sp.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Sequentially calls force_flush on all underlying - :class:`SpanProcessor` - - Args: - timeout_millis: The maximum amount of time over all span processors - to wait for spans to be exported. In case the first n span - processors exceeded the timeout followup span processors will be - skipped. - - Returns: - True if all span processors flushed their spans within the - given timeout, False otherwise. - """ - deadline_ns = time_ns() + timeout_millis * 1000000 - all_flushed = True - for sp in self._span_processors: - current_time_ns = time_ns() - if current_time_ns >= deadline_ns: - return False - - if sp.force_flush((deadline_ns - current_time_ns) // 1000000) is False: - all_flushed = False - - return all_flushed - - -class ConcurrentMultiSpanProcessor(SpanProcessor): - """Implementation of :class:`SpanProcessor` that forwards all received - events to a list of span processors in parallel. - - Calls to the underlying span processors are forwarded in parallel by - submitting them to a thread pool executor and waiting until each span - processor finished its work. - - Args: - num_threads: The number of threads managed by the thread pool executor - and thus defining how many span processors can work in parallel. - """ - - _span_processors: tuple[SpanProcessor, ...] - - def __init__(self, num_threads: int = 2): - # use a tuple to avoid race conditions when adding a new span and - # iterating through it on "on_start" and "on_end". - self._span_processors = () - self._lock = threading.Lock() - self._init_executor(num_threads) - if hasattr(os, "register_at_fork"): - # Only the main thread is kept in forked processed, the executor - # needs to be re-instantiated to get a fresh pool of threads: - weak_reinit = weakref.WeakMethod(self._init_executor) - - def _after_in_child() -> None: - reinit = weak_reinit() - if reinit is not None: - reinit(num_threads) - - os.register_at_fork(after_in_child=_after_in_child) - - def _init_executor(self, num_threads: int) -> None: - self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) - - def add_span_processor(self, span_processor: SpanProcessor) -> None: - """Adds a SpanProcessor to the list handled by this instance.""" - with self._lock: - self._span_processors += (span_processor,) - - def _submit_and_await( - self, - func: Callable[[SpanProcessor], Callable[..., None]], - *args: Any, - **kwargs: Any, - ): - futures = [] - for sp in self._span_processors: - future = self._executor.submit(func(sp), *args, **kwargs) - futures.append(future) - for future in futures: - future.result() - - def on_start( - self, - span: "Span", - parent_context: context_api.Context | None = None, - ) -> None: - self._submit_and_await(lambda sp: sp.on_start, span, parent_context=parent_context) - - def _on_ending(self, span: "Span") -> None: - # pylint: disable=protected-access - self._submit_and_await(lambda sp: sp._on_ending, span) - - def on_end(self, span: "ReadableSpan") -> None: - self._submit_and_await(lambda sp: sp.on_end, span) - - def shutdown(self) -> None: - """Shuts down all underlying span processors in parallel.""" - self._submit_and_await(lambda sp: sp.shutdown) - - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Calls force_flush on all underlying span processors in parallel. - - Args: - timeout_millis: The maximum amount of time to wait for spans to be - exported. - - Returns: - True if all span processors flushed their spans within the given - timeout, False otherwise. - """ - futures = [] - for sp in self._span_processors: - future = self._executor.submit(sp.force_flush, timeout_millis) - futures.append(future) - - timeout_sec = timeout_millis / 1e3 - done_futures, not_done_futures = concurrent.futures.wait(futures, timeout_sec) - if not_done_futures: - return False - - for future in done_futures: - if future.result() is False: - return False - - return True - - -class EventBase(abc.ABC): - def __init__(self, name: str, timestamp: int | None = None) -> None: - self._name = name - if timestamp is None: - self._timestamp = time_ns() - else: - self._timestamp = timestamp - - @property - def name(self) -> str: - return self._name - - @property - def timestamp(self) -> int: - return self._timestamp - - @property - @abc.abstractmethod - def attributes(self) -> types.Attributes: - pass - - -class Event(EventBase): - """A text annotation with a set of attributes. The attributes of an event - are immutable. - - Args: - name: Name of the event. - attributes: Attributes of the event. - timestamp: Timestamp of the event. If `None` it will filled - automatically. - """ - - def __init__( - self, - name: str, - attributes: types.Attributes = None, - timestamp: int | None = None, - limit: int | None = _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, - ) -> None: - super().__init__(name, timestamp) - self._attributes = attributes - - @property - def attributes(self) -> types.Attributes: - return self._attributes - - @property - def dropped_attributes(self) -> int: - if isinstance(self._attributes, BoundedAttributes): - return self._attributes.dropped - return 0 - - -def _check_span_ended(func): - def wrapper(self, *args, **kwargs): - already_ended = False - with self._lock: # pylint: disable=protected-access - if self._end_time is None: # pylint: disable=protected-access - func(self, *args, **kwargs) - else: - already_ended = True - - if already_ended: - logger.warning("Tried calling %s on an ended span.", func.__name__) - - return wrapper - - -def _is_valid_link(context: SpanContext, attributes: types.Attributes) -> bool: - return bool(context and (context.is_valid or (attributes or context.trace_state))) - - -class ReadableSpan: - """Provides read-only access to span attributes. - - Users should NOT be creating these objects directly. `ReadableSpan`s are created as - a direct result from using the tracing pipeline via the `Tracer`. - - """ - - def __init__( - self, - name: str, - context: trace_api.SpanContext | None = None, - parent: trace_api.SpanContext | None = None, - resource: Resource | None = None, - attributes: types.Attributes = None, - events: Sequence[Event] = (), - links: Sequence[trace_api.Link] = (), - kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, - instrumentation_info: InstrumentationInfo | None = None, - status: Status = Status(StatusCode.UNSET), - start_time: int | None = None, - end_time: int | None = None, - instrumentation_scope: InstrumentationScope | None = None, - ) -> None: - self._name = name - self._context = context - self._kind = kind - self._instrumentation_info = instrumentation_info - self._instrumentation_scope = instrumentation_scope - self._parent = parent - self._start_time = start_time - self._end_time = end_time - self._attributes = attributes - self._events = events - self._links = links - if resource is None: - self._resource = Resource.create({}) - else: - self._resource = resource - self._status = status - - @property - def dropped_attributes(self) -> int: - if isinstance(self._attributes, BoundedAttributes): - return self._attributes.dropped - return 0 - - @property - def dropped_events(self) -> int: - if isinstance(self._events, BoundedList): - return self._events.dropped - return 0 - - @property - def dropped_links(self) -> int: - if isinstance(self._links, BoundedList): - return self._links.dropped - return 0 - - @property - def name(self) -> str: - return self._name - - def get_span_context(self) -> trace_api.SpanContext | None: - return self._context - - @property - def context(self): - return self._context - - @property - def kind(self) -> trace_api.SpanKind: - return self._kind - - @property - def parent(self) -> trace_api.SpanContext | None: - return self._parent - - @property - def start_time(self) -> int | None: - return self._start_time - - @property - def end_time(self) -> int | None: - return self._end_time - - @property - def status(self) -> trace_api.Status: - return self._status - - @property - def attributes(self) -> types.Attributes: - return MappingProxyType(self._attributes or {}) - - @property - def events(self) -> Sequence[Event]: - return tuple(self._events) - - @property - def links(self) -> Sequence[trace_api.Link]: - return tuple(self._links) - - @property - def resource(self) -> Resource: - return self._resource - - @property - @deprecated("You should use instrumentation_scope. Deprecated since version 1.11.1.") - def instrumentation_info(self) -> InstrumentationInfo | None: - return self._instrumentation_info - - @property - def instrumentation_scope(self) -> InstrumentationScope | None: - return self._instrumentation_scope - - def to_json(self, indent: int | None = 4): - parent_id = None - if self.parent is not None: - parent_id = f"0x{trace_api.format_span_id(self.parent.span_id)}" - - start_time = None - if self._start_time: - start_time = util.ns_to_iso_str(self._start_time) - - end_time = None - if self._end_time: - end_time = util.ns_to_iso_str(self._end_time) - - status = { - "status_code": str(self._status.status_code.name), - } - if self._status.description: - status["description"] = self._status.description - - f_span = { - "name": self._name, - "context": (self._format_context(self._context) if self._context else None), - "kind": str(self.kind), - "parent_id": parent_id, - "start_time": start_time, - "end_time": end_time, - "status": status, - "attributes": self._format_attributes(self._attributes), - "events": self._format_events(self._events), - "links": self._format_links(self._links), - "resource": json.loads(self.resource.to_json()), - } - - return json.dumps(f_span, indent=indent) - - @staticmethod - def _format_context(context: SpanContext) -> dict[str, str]: - return { - "trace_id": f"0x{trace_api.format_trace_id(context.trace_id)}", - "span_id": f"0x{trace_api.format_span_id(context.span_id)}", - "trace_state": repr(context.trace_state), - } - - @staticmethod - def _format_attributes( - attributes: types.Attributes, - ) -> dict[str, Any] | None: - if attributes is not None and not isinstance(attributes, dict): - return dict(attributes) - return attributes - - @staticmethod - def _format_events(events: Sequence[Event]) -> list[dict[str, Any]]: - return [ - { - "name": event.name, - "timestamp": util.ns_to_iso_str(event.timestamp), - "attributes": Span._format_attributes( # pylint: disable=protected-access - event.attributes - ), - } - for event in events - ] - - @staticmethod - def _format_links(links: Sequence[trace_api.Link]) -> list[dict[str, Any]]: - return [ - { - "context": Span._format_context( # pylint: disable=protected-access - link.context - ), - "attributes": Span._format_attributes( # pylint: disable=protected-access - link.attributes - ), - } - for link in links - ] - - -class SpanLimits: - """The limits that should be enforced on recorded data such as events, links, attributes etc. - - This class does not enforce any limits itself. It only provides a way to read limits from env, - default values and from user provided arguments. - - All limit arguments must be either a non-negative integer, ``None`` or ``SpanLimits.UNSET``. - - - All limit arguments are optional. - - If a limit argument is not set, the class will try to read its value from the corresponding - environment variable. - - If the environment variable is not set, the default value, if any, will be used. - - Limit precedence: - - - If a model specific limit is set, it will be used. - - Else if the corresponding global limit is set, it will be used. - - Else if the model specific limit has a default value, the default value will be used. - - Else if the global limit has a default value, the default value will be used. - - Args: - max_attributes: Maximum number of attributes that can be added to a span, event, and link. - Environment variable: OTEL_ATTRIBUTE_COUNT_LIMIT - Default: {_DEFAULT_ATTRIBUTE_COUNT_LIMIT} - max_events: Maximum number of events that can be added to a Span. - Environment variable: OTEL_SPAN_EVENT_COUNT_LIMIT - Default: {_DEFAULT_SPAN_EVENT_COUNT_LIMIT} - max_links: Maximum number of links that can be added to a Span. - Environment variable: OTEL_SPAN_LINK_COUNT_LIMIT - Default: {_DEFAULT_SPAN_LINK_COUNT_LIMIT} - max_span_attributes: Maximum number of attributes that can be added to a Span. - Environment variable: OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT - Default: {_DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT} - max_event_attributes: Maximum number of attributes that can be added to an Event. - Default: {_DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT} - max_link_attributes: Maximum number of attributes that can be added to a Link. - Default: {_DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT} - max_attribute_length: Maximum length an attribute value can have. Values longer than - the specified length will be truncated. - max_span_attribute_length: Maximum length a span attribute value can have. Values longer than - the specified length will be truncated. - """ - - UNSET = -1 - - def __init__( - self, - max_attributes: int | None = None, - max_events: int | None = None, - max_links: int | None = None, - max_span_attributes: int | None = None, - max_event_attributes: int | None = None, - max_link_attributes: int | None = None, - max_attribute_length: int | None = None, - max_span_attribute_length: int | None = None, - ): - # span events and links count - self.max_events = self._from_env_if_absent( - max_events, - OTEL_SPAN_EVENT_COUNT_LIMIT, - _DEFAULT_OTEL_SPAN_EVENT_COUNT_LIMIT, - ) - self.max_links = self._from_env_if_absent( - max_links, - OTEL_SPAN_LINK_COUNT_LIMIT, - _DEFAULT_OTEL_SPAN_LINK_COUNT_LIMIT, - ) - - # attribute count - global_max_attributes = self._from_env_if_absent(max_attributes, OTEL_ATTRIBUTE_COUNT_LIMIT) - self.max_attributes = ( - global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_ATTRIBUTE_COUNT_LIMIT - ) - - self.max_span_attributes = self._from_env_if_absent( - max_span_attributes, - OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, - (global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT), - ) - self.max_event_attributes = self._from_env_if_absent( - max_event_attributes, - OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT, - (global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT), - ) - self.max_link_attributes = self._from_env_if_absent( - max_link_attributes, - OTEL_LINK_ATTRIBUTE_COUNT_LIMIT, - (global_max_attributes if global_max_attributes is not None else _DEFAULT_OTEL_LINK_ATTRIBUTE_COUNT_LIMIT), - ) - - # attribute length - self.max_attribute_length = self._from_env_if_absent( - max_attribute_length, - OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, - ) - self.max_span_attribute_length = self._from_env_if_absent( - max_span_attribute_length, - OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, - # use global attribute length limit as default - self.max_attribute_length, - ) - - def __repr__(self): - return f"{type(self).__name__}(max_span_attributes={self.max_span_attributes}, max_events_attributes={self.max_event_attributes}, max_link_attributes={self.max_link_attributes}, max_attributes={self.max_attributes}, max_events={self.max_events}, max_links={self.max_links}, max_attribute_length={self.max_attribute_length})" - - @classmethod - def _from_env_if_absent(cls, value: int | None, env_var: str, default: int | None = None) -> int | None: - if value == cls.UNSET: - return None - - err_msg = "{} must be a non-negative integer but got {}" - - # if no value is provided for the limit, try to load it from env - if value is None: - # return default value if env var is not set - if env_var not in environ: - return default - - str_value = environ.get(env_var, "").strip().lower() - if str_value == _ENV_VALUE_UNSET: - return None - - try: - value = int(str_value) - except ValueError: - raise ValueError(err_msg.format(env_var, str_value)) - - if value < 0: - raise ValueError(err_msg.format(env_var, value)) - return value - - -_UnsetLimits = SpanLimits( - max_attributes=SpanLimits.UNSET, - max_events=SpanLimits.UNSET, - max_links=SpanLimits.UNSET, - max_span_attributes=SpanLimits.UNSET, - max_event_attributes=SpanLimits.UNSET, - max_link_attributes=SpanLimits.UNSET, - max_attribute_length=SpanLimits.UNSET, - max_span_attribute_length=SpanLimits.UNSET, -) - -# not removed for backward compat. please use SpanLimits instead. -SPAN_ATTRIBUTE_COUNT_LIMIT = SpanLimits._from_env_if_absent( # pylint: disable=protected-access - None, - OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, - _DEFAULT_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT, -) - - -class Span(trace_api.Span, ReadableSpan): - """See `opentelemetry.trace.Span`. - - Users should create `Span` objects via the `Tracer` instead of this - constructor. - - Args: - name: The name of the operation this span represents - context: The immutable span context - parent: This span's parent's `opentelemetry.trace.SpanContext`, or - None if this is a root span - sampler: The sampler used to create this span - trace_config: Unused. Originally intended for trace-level configuration - from the OpenTelemetry protocol, but the upstream ``TraceConfig`` - proto was removed. Retained for backwards compatibility. - resource: Entity producing telemetry - attributes: The span's attributes to be exported - events: Timestamped events to be exported - links: Links to other spans to be exported - span_processor: `SpanProcessor` to invoke when starting and ending - this `Span`. - limits: `SpanLimits` instance that was passed to the `TracerProvider` - """ - - def __new__(cls, *args, **kwargs): - if cls is Span: - raise TypeError("Span must be instantiated via a tracer.") - return super().__new__(cls) - - # pylint: disable=too-many-locals - def __init__( - self, - name: str, - context: trace_api.SpanContext, - parent: trace_api.SpanContext | None = None, - sampler: sampling.Sampler | None = None, - trace_config: None = None, - resource: Resource | None = None, - attributes: types.Attributes = None, - events: Sequence[Event] | None = None, - links: Sequence[trace_api.Link] = (), - kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, - span_processor: SpanProcessor = SpanProcessor(), - instrumentation_info: InstrumentationInfo | None = None, - record_exception: bool = True, - set_status_on_exception: bool = True, - limits=_UnsetLimits, - instrumentation_scope: InstrumentationScope | None = None, - *, - record_end_metrics: Callable[[], None] | None = None, - ) -> None: - if resource is None: - resource = Resource.create({}) - super().__init__( - name=name, - context=context, - parent=parent, - kind=kind, - resource=resource, - instrumentation_info=instrumentation_info, - instrumentation_scope=instrumentation_scope, - ) - self._sampler = sampler - self._trace_config = trace_config - self._record_exception = record_exception - self._set_status_on_exception = set_status_on_exception - self._span_processor = span_processor - self._limits = limits - self._lock = threading.Lock() - self._attributes = BoundedAttributes( - self._limits.max_span_attributes, - attributes, - immutable=False, - max_value_len=self._limits.max_span_attribute_length, - ) - self._events = self._new_events() - if events: - for event in events: - # Immutable set to true so attributes cannot be added or removed after creation. - event._attributes = BoundedAttributes( - self._limits.max_event_attributes, - event.attributes, - max_value_len=self._limits.max_attribute_length, - immutable=True, - ) - self._events.append(event) - - self._links = self._new_links(links) - - self._record_end_metrics = record_end_metrics - - def __repr__(self): - return f'{type(self).__name__}(name="{self._name}", context={self._context})' - - def _new_events(self): - return BoundedList(self._limits.max_events) - - def _new_links(self, links: Sequence[trace_api.Link]): - if not links: - return BoundedList(self._limits.max_links) - - valid_links = [] - for link in links: - if link and _is_valid_link(link.context, link.attributes): - # Immutable set to true so attributes cannot be added or removed after creation. - # pylint: disable=protected-access - link._attributes = BoundedAttributes( - self._limits.max_link_attributes, - link.attributes, - max_value_len=self._limits.max_attribute_length, - immutable=True, - ) - valid_links.append(link) - - return BoundedList.from_seq(self._limits.max_links, valid_links) - - def get_span_context(self) -> trace_api.SpanContext: - return typing.cast(trace_api.SpanContext, self._context) - - def set_attributes(self, attributes: Mapping[str, types.AnyValue]) -> None: - with self._lock: - if self._end_time is not None: - logger.warning("Setting attribute on ended span.") - return - - self._attributes._set_items(attributes) # pylint: disable=protected-access - - def set_attribute(self, key: str, value: types.AnyValue) -> None: - with self._lock: - if self._end_time is not None: - logger.warning("Setting attribute on ended span.") - return - - self._attributes[key] = value - - @_check_span_ended - def _add_event(self, event: EventBase) -> None: - self._events.append(event) - - def add_event( - self, - name: str, - attributes: types.Attributes = None, - timestamp: int | None = None, - ) -> None: - # Immutable set to true so attributes cannot be added or removed after creation. - attributes = BoundedAttributes( - self._limits.max_event_attributes, - attributes, - max_value_len=self._limits.max_attribute_length, - immutable=True, - ) - self._add_event( - Event( - name=name, - attributes=attributes, - timestamp=timestamp, - ) - ) - - @_check_span_ended - def _add_link(self, link: trace_api.Link) -> None: - self._links.append(link) - - def add_link( - self, - context: SpanContext, - attributes: types.Attributes = None, - ) -> None: - if not _is_valid_link(context, attributes): - return - # Immutable set to true so attributes cannot be added or removed after creation. - attributes = BoundedAttributes( - self._limits.max_link_attributes, - attributes, - max_value_len=self._limits.max_attribute_length, - immutable=True, - ) - self._add_link( - trace_api.Link( - context=context, - attributes=attributes, - ) - ) - - def _readable_span(self) -> ReadableSpan: - return ReadableSpan( - name=self._name, - context=self._context, - parent=self._parent, - resource=self._resource, - attributes=self._attributes, - events=self._events, - links=self._links, - kind=self.kind, - status=self._status, - start_time=self._start_time, - end_time=self._end_time, - instrumentation_info=self._instrumentation_info, - instrumentation_scope=self._instrumentation_scope, - ) - - def start( - self, - start_time: int | None = None, - parent_context: context_api.Context | None = None, - ) -> None: - with self._lock: - if self._start_time is not None: - logger.warning("Calling start() on a started span.") - return - self._start_time = start_time if start_time is not None else time_ns() - - self._span_processor.on_start(self, parent_context=parent_context) - - def end(self, end_time: int | None = None) -> None: - with self._lock: - if self._start_time is None: - raise RuntimeError("Calling end() on a not started span.") - if self._end_time is not None: - logger.warning("Calling end() on an ended span.") - return - - self._end_time = end_time if end_time is not None else time_ns() - self._attributes._immutable = True # pylint: disable=protected-access - - if self._record_end_metrics: - self._record_end_metrics() - # pylint: disable=protected-access - self._span_processor._on_ending(self) - self._span_processor.on_end(self._readable_span()) - - @_check_span_ended - def update_name(self, name: str) -> None: - self._name = name - - def is_recording(self) -> bool: - return self._end_time is None - - @_check_span_ended - def set_status( - self, - status: Status | StatusCode, - description: str | None = None, - ) -> None: - # Ignore future calls if status is already set to OK - # Ignore calls to set to StatusCode.UNSET - if isinstance(status, Status): - if self._status and self._status.status_code is StatusCode.OK or status.status_code is StatusCode.UNSET: - return - if description is not None: - logger.warning( - "Description %s ignored. Use either `Status` or `(StatusCode, Description)`", - description, - ) - self._status = status - elif isinstance(status, StatusCode): - if self._status and self._status.status_code is StatusCode.OK or status is StatusCode.UNSET: - return - self._status = Status(status, description) - - def __exit__( - self, - exc_type: type[BaseException] | None, - exc_val: BaseException | None, - exc_tb: TracebackType | None, - ) -> None: - """Ends context manager and calls `end` on the `Span`.""" - if exc_val is not None and self.is_recording(): - # Record the exception as an event - # pylint:disable=protected-access - if self._record_exception: - self.record_exception(exception=exc_val, escaped=True) - # Records status if span is used as context manager - # i.e. with tracer.start_span() as span: - if self._set_status_on_exception: - self.set_status( - Status( - status_code=StatusCode.ERROR, - description=(f"{type(exc_val).__name__}: {exc_val}"), - ) - ) - - super().__exit__(exc_type, exc_val, exc_tb) - - def record_exception( - self, - exception: BaseException, - attributes: types.Attributes = None, - timestamp: int | None = None, - escaped: bool = False, - ) -> None: - """Records an exception as a span event.""" - stacktrace = "".join(traceback.format_exception(exception)) - module = type(exception).__module__ - qualname = type(exception).__qualname__ - exception_type = f"{module}.{qualname}" if module and module != "builtins" else qualname - _attributes: MutableMapping[str, types.AnyValue] = { - EXCEPTION_TYPE: exception_type, - EXCEPTION_MESSAGE: str(exception), - EXCEPTION_STACKTRACE: stacktrace, - EXCEPTION_ESCAPED: str(escaped), - } - if attributes: - _attributes.update(attributes) - self.add_event(name="exception", attributes=_attributes, timestamp=timestamp) - - -class _Span(Span): - """Protected implementation of `opentelemetry.trace.Span`. - - This constructor exists to prevent the instantiation of the `Span` class - by other mechanisms than through the `Tracer`. - """ - - -@dataclass -class _TracerConfig: - is_enabled: bool - - @classmethod - def default(cls): - return cls(is_enabled=True) - - -class Tracer(trace_api.Tracer): - """See `opentelemetry.trace.Tracer`.""" - - def __init__( - self, - sampler: sampling.Sampler, - resource: Resource, - span_processor: SynchronousMultiSpanProcessor | ConcurrentMultiSpanProcessor, - id_generator: IdGenerator, - instrumentation_info: InstrumentationInfo, - span_limits: SpanLimits, - instrumentation_scope: InstrumentationScope, - *, - meter_provider: metrics_api.MeterProvider | None = None, - _tracer_config: _TracerConfig | None = None, - ) -> None: - self.sampler = sampler - self.resource = resource - self.span_processor = span_processor - self.id_generator = id_generator - self.instrumentation_info = instrumentation_info - self._span_limits = span_limits - self._instrumentation_scope = instrumentation_scope - self._tracer_config = _tracer_config or _TracerConfig.default() - - meter_provider = meter_provider or metrics_api.get_meter_provider() - self._tracer_metrics = create_tracer_metrics( - meter_provider, - parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ) - - def _set_tracer_config(self, tracer_config: _TracerConfig): - self._tracer_config = tracer_config - - def _set_resource(self, resource: Resource) -> None: - self.resource = resource - - def _is_enabled(self) -> bool: - """If the tracer is not enabled, start_span will create a NonRecordingSpan""" - return self._tracer_config.is_enabled - - @_agnosticcontextmanager # pylint: disable=protected-access - def start_as_current_span( - self, - name: str, - context: context_api.Context | None = None, - kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, - attributes: types.Attributes = None, - links: Sequence[trace_api.Link] | None = (), - start_time: int | None = None, - record_exception: bool = True, - set_status_on_exception: bool = True, - end_on_exit: bool = True, - ) -> Iterator[trace_api.Span]: - span = self.start_span( - name=name, - context=context, - kind=kind, - attributes=attributes, - links=links, - start_time=start_time, - record_exception=record_exception, - set_status_on_exception=set_status_on_exception, - ) - with trace_api.use_span( - span, - end_on_exit=end_on_exit, - record_exception=record_exception, - set_status_on_exception=set_status_on_exception, - ) as span: - yield span - - def start_span( # pylint: disable=too-many-locals - self, - name: str, - context: context_api.Context | None = None, - kind: trace_api.SpanKind = trace_api.SpanKind.INTERNAL, - attributes: types.Attributes = None, - links: Sequence[trace_api.Link] | None = (), - start_time: int | None = None, - record_exception: bool = True, - set_status_on_exception: bool = True, - ) -> trace_api.Span: - links = links or () - parent_span_context = trace_api.get_current_span(context).get_span_context() - - if parent_span_context is not None and not isinstance(parent_span_context, trace_api.SpanContext): - raise TypeError("parent_span_context must be a SpanContext or None.") - - if not self._is_enabled(): - return trace_api.NonRecordingSpan(context=parent_span_context) - - # is_valid determines root span - if parent_span_context is None or not parent_span_context.is_valid: - parent_span_context = None - trace_id = self.id_generator.generate_trace_id() - else: - trace_id = parent_span_context.trace_id - - # The sampler decides whether to create a real or no-op span at the - # time of span creation. No-op spans do not record events, and are not - # exported. - # The sampler may also add attributes to the newly-created span, e.g. - # to include information about the sampling result. - # The sampler may also modify the parent span context's tracestate - sampling_result = self.sampler.should_sample(context, trace_id, name, kind, attributes, links) - - trace_flags = ( - trace_api.TraceFlags(trace_api.TraceFlags.SAMPLED) - if sampling_result.decision.is_sampled() - else trace_api.TraceFlags(trace_api.TraceFlags.DEFAULT) - ) - - if parent_span_context is None: - random_trace_id = self.id_generator.is_trace_id_random() - else: - random_trace_id = parent_span_context.trace_flags.random_trace_id - - if random_trace_id: - trace_flags = trace_api.TraceFlags(trace_flags | trace_api.TraceFlags.RANDOM_TRACE_ID) - - span_context = trace_api.SpanContext( - trace_id, - self.id_generator.generate_span_id(), - is_remote=False, - trace_flags=trace_flags, - trace_state=sampling_result.trace_state, - ) - - record_end_metrics = self._tracer_metrics.start_span(parent_span_context, sampling_result.decision) - - # Only record if is_recording() is true - if sampling_result.decision.is_recording(): - # pylint:disable=protected-access - span = _Span( - name=name, - context=span_context, - parent=parent_span_context, - sampler=self.sampler, - resource=self.resource, - attributes=sampling_result.attributes, - span_processor=self.span_processor, - kind=kind, - links=links, - instrumentation_info=self.instrumentation_info, - record_exception=record_exception, - set_status_on_exception=set_status_on_exception, - limits=self._span_limits, - instrumentation_scope=self._instrumentation_scope, - record_end_metrics=record_end_metrics, - ) - span.start(start_time=start_time, parent_context=context) - else: - span = trace_api.NonRecordingSpan(context=span_context) - return span - - -_TracerConfiguratorT = Callable[[InstrumentationScope], _TracerConfig] -_RuleBasedTracerConfigurator = RuleBasedConfigurator[_TracerConfig] - - -def _default_tracer_configurator( - tracer_scope: InstrumentationScope, -) -> _TracerConfig: - """Default Tracer Configurator implementation - - In order to update Tracers configs you need to call - TracerProvider._set_tracer_configurator with a function - implementing this interface returning a Tracer Config.""" - return _RuleBasedTracerConfigurator( - rules=[], - default_config=_TracerConfig.default(), - )(tracer_scope) - - -def _disable_tracer_configurator( - tracer_scope: InstrumentationScope, -) -> _TracerConfig: - return _RuleBasedTracerConfigurator( - rules=[], - default_config=_TracerConfig(is_enabled=False), - )(tracer_scope) - - -class TracerProvider(trace_api.TracerProvider): - """See `opentelemetry.trace.TracerProvider`.""" - - def __init__( - self, - sampler: sampling.Sampler | None = None, - resource: Resource | None = None, - shutdown_on_exit: bool = True, - active_span_processor: SynchronousMultiSpanProcessor | ConcurrentMultiSpanProcessor | None = None, - id_generator: IdGenerator | None = None, - span_limits: SpanLimits | None = None, - *, - meter_provider: metrics_api.MeterProvider | None = None, - _tracer_configurator: _TracerConfiguratorT | None = None, - ) -> None: - self._active_span_processor = active_span_processor or SynchronousMultiSpanProcessor() - if id_generator is None: - self.id_generator = RandomIdGenerator() - else: - self.id_generator = id_generator - if resource is None: - self._resource = Resource.create({}) - else: - self._resource = resource - if not sampler: - sampler = sampling._get_from_env_or_default() - self.sampler = sampler - self._span_limits = span_limits or SpanLimits() - disabled = environ.get(OTEL_SDK_DISABLED, "") - self._disabled = disabled.lower().strip() == "true" - self._atexit_handler = None - self._meter_provider = meter_provider - - if shutdown_on_exit: - self._atexit_handler = atexit.register(self.shutdown) - - self._tracer_configurator = _tracer_configurator or _default_tracer_configurator - self._tracers_lock = threading.Lock() - self._tracers: dict[InstrumentationScope, Tracer] = {} - if hasattr(os, "register_at_fork"): - weak_at_fork = weakref.WeakMethod(self._handle_fork) - - def _after_in_child() -> None: - if at_fork := weak_at_fork(): - at_fork() - - os.register_at_fork(after_in_child=_after_in_child) - - def _handle_fork(self) -> None: - self._tracers_lock = threading.Lock() - self._update_resource(_get_process_dependent_resource()) - - def _set_tracer_configurator(self, *, tracer_configurator: _TracerConfiguratorT): - """This is the function used to update the TracerProvider TracerConfigurator - - Setting a new TracerConfigurator for a TracerProvider will update the - TracerConfig of all Tracers create by this TracerProvider. - """ - self._tracer_configurator = tracer_configurator - with self._tracers_lock: - for instrumentation_scope, tracer in self._tracers.items(): - tracer_config = self._apply_tracer_configurator(instrumentation_scope) - # pylint: disable-next=protected-access - tracer._set_tracer_config(tracer_config) - - @property - def resource(self) -> Resource: - return self._resource - - def _update_resource(self, resource: Resource) -> None: - with self._tracers_lock: - self._resource = self._resource.merge(resource) - for tracer in self._tracers.values(): - tracer._set_resource(self._resource) # pylint: disable=protected-access - - def _apply_tracer_configurator(self, instrumentation_scope: InstrumentationScope): - try: - return self._tracer_configurator(instrumentation_scope) - except Exception: # pylint: disable=broad-exception-caught - logger.exception( - "Failed to create a Tracer Config for %s, using default Tracer config", - instrumentation_scope, - ) - return _TracerConfig.default() - - def get_tracer( - self, - instrumenting_module_name: str, - instrumenting_library_version: str | None = None, - schema_url: str | None = None, - attributes: types.Attributes = None, - ) -> "trace_api.Tracer": - if self._disabled: - return NoOpTracer() - if not instrumenting_module_name: # Reject empty strings too. - instrumenting_module_name = "" - logger.error("get_tracer called with missing module name.") - if instrumenting_library_version is None: - instrumenting_library_version = "" - - filterwarnings( - "ignore", - message=(r"You should use InstrumentationScope. Deprecated since version 1.11.1."), - category=DeprecationWarning, - # opentelemetry-agent: match this (vendored) module, not the application's SDK. - module=__name__, - ) - - instrumentation_info = InstrumentationInfo( - instrumenting_module_name, - instrumenting_library_version, - schema_url, - ) - - instrumentation_scope = InstrumentationScope( - instrumenting_module_name, - instrumenting_library_version, - schema_url, - attributes, - ) - - with self._tracers_lock: - if instrumentation_scope in self._tracers: - return self._tracers[instrumentation_scope] - - tracer_config = self._apply_tracer_configurator(instrumentation_scope) - tracer = Tracer( - self.sampler, - self.resource, - self._active_span_processor, - self.id_generator, - instrumentation_info, - self._span_limits, - instrumentation_scope, - meter_provider=self._meter_provider, - _tracer_config=tracer_config, - ) - self._tracers[instrumentation_scope] = tracer - - return tracer - - def add_span_processor(self, span_processor: SpanProcessor) -> None: - """Registers a new :class:`SpanProcessor` for this `TracerProvider`. - - The span processors are invoked in the same order they are registered. - """ - - # no lock here because add_span_processor is thread safe for both - # SynchronousMultiSpanProcessor and ConcurrentMultiSpanProcessor. - self._active_span_processor.add_span_processor(span_processor) - - def shutdown(self) -> None: - """Shut down the span processors added to the tracer provider.""" - self._active_span_processor.shutdown() - if self._atexit_handler is not None: - atexit.unregister(self._atexit_handler) - self._atexit_handler = None - - def force_flush(self, timeout_millis: int = 30000) -> bool: - """Requests the active span processor to process all spans that have not - yet been processed. - - By default force flush is called sequentially on all added span - processors. This means that span processors further back in the list - have less time to flush their spans. - To have span processors flush their spans in parallel it is possible to - initialize the tracer provider with an instance of - `ConcurrentMultiSpanProcessor` at the cost of using multiple threads. - - Args: - timeout_millis: The maximum amount of time to wait for spans to be - processed. - - Returns: - False if the timeout is exceeded, True otherwise. - """ - return self._active_span_processor.force_flush(timeout_millis) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py deleted file mode 100644 index e838448490a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__all__ = [ - "ComposableSampler", - "SamplingIntent", - "composable_always_off", - "composable_always_on", - "composable_parent_threshold", - "composable_rule_based", - "composable_traceid_ratio_based", - "composite_sampler", -] - - -from ._always_off import composable_always_off -from ._always_on import composable_always_on -from ._composable import ComposableSampler, SamplingIntent -from ._parent_threshold import composable_parent_threshold -from ._rule_based import composable_rule_based -from ._sampler import composite_sampler -from ._traceid_ratio import composable_traceid_ratio_based diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py deleted file mode 100644 index ab144f65f21..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_off.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Sequence - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -from ._composable import ComposableSampler, SamplingIntent -from ._util import INVALID_THRESHOLD - -_intent = SamplingIntent(threshold=INVALID_THRESHOLD, threshold_reliable=False) - - -class _ComposableAlwaysOffSampler(ComposableSampler): - def sampling_intent( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None = None, - ) -> SamplingIntent: - return _intent - - def get_description(self) -> str: - return "ComposableAlwaysOff" - - -_always_off = _ComposableAlwaysOffSampler() - - -def composable_always_off() -> ComposableSampler: - """Returns a composable sampler that does not sample any span. - - - Always returns a SamplingIntent with no threshold, indicating all spans should be dropped - - Sets threshold_reliable to false - - Does not add any attributes - """ - return _always_off diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py deleted file mode 100644 index bd191817df4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_always_on.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Sequence - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -from ._composable import ComposableSampler, SamplingIntent -from ._util import MIN_THRESHOLD - -_intent = SamplingIntent(threshold=MIN_THRESHOLD) - - -class _ComposableAlwaysOnSampler(ComposableSampler): - def sampling_intent( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None = None, - ) -> SamplingIntent: - return _intent - - def get_description(self) -> str: - return "ComposableAlwaysOn" - - -_always_on = _ComposableAlwaysOnSampler() - - -def composable_always_on() -> ComposableSampler: - """Returns a composable sampler that samples all spans. - - - Always returns a SamplingIntent with threshold set to sample all spans (threshold = 0) - - Sets threshold_reliable to true - - Does not add any attributes - """ - return _always_on diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py deleted file mode 100644 index d6712fe3744..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_composable.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Callable, Sequence -from dataclasses import dataclass, field -from typing import Protocol - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - - -@dataclass(frozen=True) -class SamplingIntent: - """Information to make a consistent sampling decision.""" - - threshold: int - """The sampling threshold value. A lower threshold increases the likelihood of sampling.""" - - threshold_reliable: bool = field(default=True) - """Indicates whether the threshold is reliable for Span-to-Metrics estimation.""" - - attributes: Attributes = field(default=None) - """Any attributes to be added to a sampled span.""" - - update_trace_state: Callable[[TraceState], TraceState] = field(default=lambda ts: ts) - """Any updates to be made to trace state.""" - - -class ComposableSampler(Protocol): - """A sampler that can be composed to make a final sampling decision.""" - - def sampling_intent( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> SamplingIntent: - """Returns information to make a sampling decision.""" - ... # pylint: disable=unnecessary-ellipsis - - def get_description(self) -> str: - """Returns a description of the sampler.""" - ... # pylint: disable=unnecessary-ellipsis diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py deleted file mode 100644 index 456605af8a7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_parent_threshold.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Sequence - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState, get_current_span -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -from ._composable import ComposableSampler, SamplingIntent -from ._trace_state import OtelTraceState -from ._util import ( - INVALID_THRESHOLD, - MIN_THRESHOLD, - is_valid_threshold, -) - - -class _ComposableParentThreshold(ComposableSampler): - def __init__(self, root_sampler: ComposableSampler): - self._root_sampler = root_sampler - self._description = f"ComposableParentThreshold{{root={root_sampler.get_description()}}}" - - def sampling_intent( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None = None, - ) -> SamplingIntent: - parent_span = get_current_span(parent_ctx) - parent_span_ctx = parent_span.get_span_context() - is_root = not parent_span_ctx.is_valid - if is_root: - return self._root_sampler.sampling_intent(parent_ctx, name, span_kind, attributes, links, trace_state) - - ot_trace_state = OtelTraceState.parse(trace_state) - - if is_valid_threshold(ot_trace_state.threshold): - return SamplingIntent( - threshold=ot_trace_state.threshold, - threshold_reliable=True, - ) - - threshold = MIN_THRESHOLD if parent_span_ctx.trace_flags.sampled else INVALID_THRESHOLD - return SamplingIntent(threshold=threshold, threshold_reliable=False) - - def get_description(self) -> str: - return self._description - - -def composable_parent_threshold( - root_sampler: ComposableSampler, -) -> ComposableSampler: - """Returns a consistent sampler that respects the sampling decision of - the parent span or falls-back to the given sampler if it is a root span. - - - For spans without a parent context, delegate to the root sampler - - For spans with a parent context, returns a SamplingIntent that propagates the parent's sampling decision - - Returns the parent's threshold if available; otherwise, if the parent's sampled flag is set, - returns threshold=0; otherwise, if the parent's sampled flag is not set, no threshold is returned. - - Sets threshold_reliable to match the parent’s reliability, which is true if the parent had a threshold. - - Does not add any attributes - - Args: - root_sampler: The root sampler to use for spans without a parent context. - """ - return _ComposableParentThreshold(root_sampler) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py deleted file mode 100644 index 6c45082bf08..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_rule_based.py +++ /dev/null @@ -1,271 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import logging -from collections.abc import Sequence -from fnmatch import fnmatchcase -from typing import Protocol - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace import ( - Link, - SpanKind, - TraceState, - get_current_span, -) -from opentelemetry.agent._vendor.opentelemetry.util.types import AnyValue, Attributes - -from ._composable import ComposableSampler, SamplingIntent -from ._util import INVALID_THRESHOLD - - -class PredicateT(Protocol): - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: ... - - def __str__(self) -> str: ... - - -class AttributePredicate: - """An exact match of an attribute value""" - - def __init__(self, key: str, value: AnyValue): - logging.warning("This is deprecated, use AttributeValuesPredicate instead") - self.key = key - self.value = value - - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: - if not attributes: - return False - return attributes.get(self.key) == self.value - - def __str__(self): - return f"{self.key}={self.value}" - - -class AlwaysMatchPredicate: - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: - return True - - def __str__(self) -> str: - return "AlwaysMatch" - - -class AllPredicate: - def __init__(self, predicates: Sequence[PredicateT]): - self._predicates = tuple(predicates) - - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: - return all( - predicate( - parent_ctx, - name, - span_kind, - attributes, - links, - trace_state, - ) - for predicate in self._predicates - ) - - def __str__(self) -> str: - return " && ".join(str(predicate) for predicate in self._predicates) - - -class AttributeValuesPredicate: - def __init__(self, key: str, values: Sequence[str]): - self._key = key - self._values = frozenset(values) - - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: - if not attributes or self._key not in attributes: - return False - return any(str(value) in self._values for value in _attribute_values(attributes[self._key])) - - def __str__(self) -> str: - values = ",".join(sorted(self._values)) - return f"{self._key} in [{values}]" - - -class AttributePatternsPredicate: - def __init__( - self, - key: str, - included: Sequence[str] | None = None, - excluded: Sequence[str] | None = None, - ): - self._key = key - self._included = tuple(included or ()) - self._excluded = tuple(excluded or ()) - - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: - if not attributes or self._key not in attributes: - return False - return any(self._matches_value(str(value)) for value in _attribute_values(attributes[self._key])) - - def _matches_value(self, value: str) -> bool: - included = not self._included or any(fnmatchcase(value, pattern) for pattern in self._included) - excluded = any(fnmatchcase(value, pattern) for pattern in self._excluded) - return included and not excluded - - def __str__(self) -> str: - return f"{self._key} matches" - - -class SpanKindPredicate: - def __init__(self, span_kinds: Sequence[SpanKind]): - self._span_kinds = frozenset(span_kinds) - - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: - return span_kind in self._span_kinds - - def __str__(self) -> str: - kinds = ",".join(kind.name.lower() for kind in self._span_kinds) - return f"span_kind in [{kinds}]" - - -class ParentPredicate: - def __init__(self, parents: Sequence[str]): - self._parents = frozenset(parents) - - def __call__( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> bool: - parent_span_context = get_current_span(parent_ctx).get_span_context() - if not parent_span_context.is_valid: - parent = "none" - elif parent_span_context.is_remote: - parent = "remote" - else: - parent = "local" - return parent in self._parents - - def __str__(self) -> str: - parents = ",".join(self._parents) - return f"parent in [{parents}]" - - -def _attribute_values(value): - if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)): - return value - return (value,) - - -RulesT = Sequence[tuple[PredicateT, ComposableSampler]] - -_non_sampling_intent = SamplingIntent(threshold=INVALID_THRESHOLD, threshold_reliable=False) - - -class _ComposableRuleBased(ComposableSampler): - def __init__(self, rules: RulesT): - # work on an internal copy of the rules - self._rules = list(rules) - - def sampling_intent( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None = None, - ) -> SamplingIntent: - for predicate, sampler in self._rules: - if predicate( - parent_ctx=parent_ctx, - name=name, - span_kind=span_kind, - attributes=attributes, - links=links, - trace_state=trace_state, - ): - return sampler.sampling_intent( - parent_ctx=parent_ctx, - name=name, - span_kind=span_kind, - attributes=attributes, - links=links, - trace_state=trace_state, - ) - return _non_sampling_intent - - def get_description(self) -> str: - rules_str = ",".join(f"({predicate}:{sampler.get_description()})" for predicate, sampler in self._rules) - return f"ComposableRuleBased{{[{rules_str}]}}" - - -def composable_rule_based( - rules: RulesT, -) -> ComposableSampler: - """Returns a consistent sampler that: - - - Evaluates a series of rules based on predicates and returns the SamplingIntent from the first matching sampler - - If no rules match, returns a non-sampling intent - - Args: - rules: A list of (Predicate, ComposableSampler) pairs, where Predicate is a function that evaluates whether a rule applies - """ - return _ComposableRuleBased(rules) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py deleted file mode 100644 index 17bd9f96b3e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_sampler.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Sequence - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import Decision, Sampler, SamplingResult -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -from ._composable import ComposableSampler, SamplingIntent -from ._trace_state import OTEL_TRACE_STATE_KEY, OtelTraceState -from ._util import INVALID_THRESHOLD, is_valid_random_value, is_valid_threshold - - -class _CompositeSampler(Sampler): - def __init__(self, delegate: ComposableSampler): - self._delegate = delegate - - def should_sample( - self, - parent_context: Context | None, - trace_id: int, - name: str, - kind: SpanKind | None = None, - attributes: Attributes = None, - links: Sequence[Link] | None = None, - trace_state: TraceState | None = None, - ) -> SamplingResult: - ot_trace_state = OtelTraceState.parse(trace_state) - - intent = self._delegate.sampling_intent(parent_context, name, kind, attributes, links, trace_state) - threshold = intent.threshold - - if is_valid_threshold(threshold): - adjusted_count_correct = intent.threshold_reliable - if is_valid_random_value(ot_trace_state.random_value): - randomness = ot_trace_state.random_value - else: - # Use last 56 bits of trace_id as randomness - randomness = trace_id & 0x00FFFFFFFFFFFFFF - sampled = threshold <= randomness - else: - sampled = False - adjusted_count_correct = False - - decision = Decision.RECORD_AND_SAMPLE if sampled else Decision.DROP - if sampled and adjusted_count_correct: - ot_trace_state.threshold = threshold - else: - ot_trace_state.threshold = INVALID_THRESHOLD - - return SamplingResult( - decision, - intent.attributes, - _update_trace_state(trace_state, ot_trace_state, intent), - ) - - def get_description(self) -> str: - return self._delegate.get_description() - - -def _update_trace_state( - trace_state: TraceState | None, - ot_trace_state: OtelTraceState, - intent: SamplingIntent, -) -> TraceState | None: - otts = ot_trace_state.serialize() - if not trace_state: - if otts: - return TraceState(((OTEL_TRACE_STATE_KEY, otts),)) - return None - new_trace_state = intent.update_trace_state(trace_state) - if otts: - return new_trace_state.update(OTEL_TRACE_STATE_KEY, otts) - return new_trace_state - - -def composite_sampler(delegate: ComposableSampler) -> Sampler: - """A sampler that uses a a composable sampler to make its decision while - handling tracestate. - - Args: - delegate: The composable sampler to use for making sampling decisions. - """ - return _CompositeSampler(delegate) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py deleted file mode 100644 index d58bc7c4bb1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_trace_state.py +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Sequence -from dataclasses import dataclass - -from opentelemetry.agent._vendor.opentelemetry.trace import TraceState - -from ._util import ( - INVALID_RANDOM_VALUE, - INVALID_THRESHOLD, - MAX_THRESHOLD, - is_valid_random_value, - is_valid_threshold, -) - -OTEL_TRACE_STATE_KEY = "ot" - -_TRACE_STATE_SIZE_LIMIT = 256 -_MAX_VALUE_LENGTH = 14 # 56 bits, 4 bits per hex digit - - -@dataclass -class OtelTraceState: - """Marshals OpenTelemetry tracestate for sampling parameters. - - https://opentelemetry.io/docs/specs/otel/trace/tracestate-probability-sampling/ - """ - - random_value: int - threshold: int - rest: Sequence[str] - - @staticmethod - def invalid() -> OtelTraceState: - return OtelTraceState(INVALID_RANDOM_VALUE, INVALID_THRESHOLD, ()) - - @staticmethod - def parse(trace_state: TraceState | None) -> OtelTraceState: - if not trace_state: - return OtelTraceState.invalid() - - ot = trace_state.get(OTEL_TRACE_STATE_KEY, "") - - if not ot or len(ot) > _TRACE_STATE_SIZE_LIMIT: - return OtelTraceState.invalid() - - threshold = INVALID_THRESHOLD - random_value = INVALID_RANDOM_VALUE - - members = ot.split(";") - rest: list[str] | None = None - for member in members: - if member.startswith("th:"): - threshold = _parse_th(member[len("th:") :], INVALID_THRESHOLD) - continue - if member.startswith("rv:"): - random_value = _parse_rv(member[len("rv:") :], INVALID_RANDOM_VALUE) - continue - if rest is None: - rest = [member] - else: - rest.append(member) - - return OtelTraceState(random_value=random_value, threshold=threshold, rest=rest or ()) - - def serialize(self) -> str: - if not is_valid_threshold(self.threshold) and not is_valid_random_value(self.random_value) and not self.rest: - return "" - - parts: list[str] = [] - if is_valid_threshold(self.threshold) and self.threshold != MAX_THRESHOLD: - parts.append(f"th:{serialize_th(self.threshold)}") - if is_valid_random_value(self.random_value): - parts.append(f"rv:{_serialize_rv(self.random_value)}") - if self.rest: - parts.extend(self.rest) - res = ";".join(parts) - while len(res) > _TRACE_STATE_SIZE_LIMIT: - delim_idx = res.rfind(";") - if delim_idx == -1: - break - res = res[:delim_idx] - return res - - -def _parse_th(value: str, default: int) -> int: - if not value or len(value) > _MAX_VALUE_LENGTH: - return default - - try: - parsed = int(value, 16) - except ValueError: - return default - - # th value is compressed by removing all trailing zeros, - # so we restore them to get the real value. - trailing_zeros = _MAX_VALUE_LENGTH - len(value) - return parsed << (trailing_zeros * 4) - - -def _parse_rv(value: str, default: int) -> int: - if not value or len(value) != _MAX_VALUE_LENGTH: - return default - - try: - return int(value, 16) - except ValueError: - return default - - -def serialize_th(threshold: int) -> str: - if not threshold: - return "0" - return f"{threshold:014x}".rstrip("0") - - -def _serialize_rv(random_value: int) -> str: - return f"{random_value:014x}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py deleted file mode 100644 index fb1cc40b71f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_traceid_ratio.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Sequence - -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, TraceState -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -from ._composable import ComposableSampler, SamplingIntent -from ._trace_state import serialize_th -from ._util import INVALID_THRESHOLD, MAX_THRESHOLD, calculate_threshold - - -class ComposableTraceIDRatioBased(ComposableSampler): - _threshold: int - _description: str - - def __init__(self, ratio: float): - threshold = calculate_threshold(ratio) - if threshold == MAX_THRESHOLD: - threshold_str = "max" - else: - threshold_str = serialize_th(threshold) - if threshold != MAX_THRESHOLD: - intent = SamplingIntent(threshold=threshold) - else: - intent = SamplingIntent(threshold=INVALID_THRESHOLD, threshold_reliable=False) - self._intent = intent - self._description = f"ComposableTraceIDRatioBased{{threshold={threshold_str}, ratio={ratio}}}" - - def sampling_intent( - self, - parent_ctx: Context | None, - name: str, - span_kind: SpanKind | None, - attributes: Attributes, - links: Sequence[Link] | None, - trace_state: TraceState | None, - ) -> SamplingIntent: - return self._intent - - def get_description(self) -> str: - return self._description - - -def composable_traceid_ratio_based( - ratio: float, -) -> ComposableSampler: - """Returns a composable sampler that samples each span with a fixed ratio. - - - Returns a SamplingIntent with threshold determined by the configured sampling ratio - - Sets threshold_reliable to true - - Does not add any attributes - - Note: - If the ratio is 0, it will behave as an ComposableAlwaysOff sampler instead. - - Args: - ratio: The sampling ratio to use (between 0.0 and 1.0). - """ - if not 0.0 <= ratio <= 1.0: - raise ValueError("Sampling ratio must be between 0.0 and 1.0") - - return ComposableTraceIDRatioBased(ratio) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py deleted file mode 100644 index dc8c10ae40b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_sampling_experimental/_util.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -RANDOM_VALUE_BITS = 56 -MAX_THRESHOLD = 1 << RANDOM_VALUE_BITS # 0% sampling -MIN_THRESHOLD = 0 # 100% sampling -MAX_RANDOM_VALUE = MAX_THRESHOLD - 1 -INVALID_THRESHOLD = -1 -INVALID_RANDOM_VALUE = -1 - -_probability_threshold_scale = float.fromhex("0x1p56") - - -def calculate_threshold(sampling_probability: float) -> int: - return MAX_THRESHOLD - round(sampling_probability * _probability_threshold_scale) - - -def is_valid_threshold(threshold: int) -> bool: - return MIN_THRESHOLD <= threshold <= MAX_THRESHOLD - - -def is_valid_random_value(random_value: int) -> bool: - return 0 <= random_value <= MAX_RANDOM_VALUE diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py deleted file mode 100644 index 852a97f84e5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/_tracer_metrics.py +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Callable -from typing import Protocol - -from opentelemetry.agent._vendor.opentelemetry import metrics as metrics_api -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.sampling import Decision -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OTEL_SPAN_PARENT_ORIGIN, - OTEL_SPAN_SAMPLING_RESULT, - OtelSpanSamplingResultValues, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.metrics.otel_metrics import ( - create_otel_sdk_span_live, - create_otel_sdk_span_started, -) -from opentelemetry.agent._vendor.opentelemetry.trace.span import SpanContext - - -class TracerMetricsT(Protocol): - def start_span( - self, - parent_span_context: SpanContext | None, - sampling_decision: Decision, - ) -> Callable[[], None]: ... - - -# pylint: disable=no-self-use -class NoOpTracerMetrics: - def start_span( - self, - parent_span_context: SpanContext | None, - sampling_decision: Decision, - ) -> Callable[[], None]: - return noop - - -class TracerMetrics: - def __init__(self, meter_provider: metrics_api.MeterProvider) -> None: - meter = meter_provider.get_meter("opentelemetry-sdk") - - self._started_spans = create_otel_sdk_span_started(meter) - self._live_spans = create_otel_sdk_span_live(meter) - - def start_span( - self, - parent_span_context: SpanContext | None, - sampling_decision: Decision, - ) -> Callable[[], None]: - sampling_result_value = sampling_result(sampling_decision) - self._started_spans.add( - 1, - { - OTEL_SPAN_PARENT_ORIGIN: parent_origin(parent_span_context), - OTEL_SPAN_SAMPLING_RESULT: sampling_result_value, - }, - ) - - if not sampling_decision.is_recording(): - return noop - - live_span_attrs = { - OTEL_SPAN_SAMPLING_RESULT: sampling_result_value, - } - self._live_spans.add(1, live_span_attrs) - - def end_span() -> None: - self._live_spans.add(-1, live_span_attrs) - - return end_span - - -def create_tracer_metrics( - meter_provider: metrics_api.MeterProvider, - enabled: bool, -) -> TracerMetricsT: - if not enabled: - return NoOpTracerMetrics() - - return TracerMetrics(meter_provider) - - -def noop() -> None: - pass - - -def parent_origin(span_ctx: SpanContext | None) -> str: - if span_ctx is None: - return "none" - if span_ctx.is_remote: - return "remote" - return "local" - - -def sampling_result(decision: Decision) -> str: - if decision == Decision.RECORD_AND_SAMPLE: - return OtelSpanSamplingResultValues.RECORD_AND_SAMPLE.value - if decision == Decision.RECORD_ONLY: - return OtelSpanSamplingResultValues.RECORD_ONLY.value - return OtelSpanSamplingResultValues.DROP.value diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py deleted file mode 100644 index d0eed223e5f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/__init__.py +++ /dev/null @@ -1,316 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from __future__ import annotations - -import collections.abc -import logging -import sys -import typing -from enum import Enum -from os import environ, linesep - -from opentelemetry.agent._vendor.opentelemetry.context import ( - _SUPPRESS_INSTRUMENTATION_KEY, - Context, - attach, - detach, - set_value, -) -from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider, get_meter_provider -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal import ( - BatchProcessor, -) -from opentelemetry.agent._vendor.opentelemetry.sdk._shared_internal._processor_metrics import ( - create_processor_metrics, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_BSP_EXPORT_TIMEOUT, - OTEL_BSP_MAX_EXPORT_BATCH_SIZE, - OTEL_BSP_MAX_QUEUE_SIZE, - OTEL_BSP_SCHEDULE_DELAY, - OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables._internal import ( - parse_boolean_environment_variable, -) -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.otel_attributes import ( - OtelComponentTypeValues, -) - -_DEFAULT_SCHEDULE_DELAY_MILLIS = 5000 -_DEFAULT_MAX_EXPORT_BATCH_SIZE = 512 -_DEFAULT_EXPORT_TIMEOUT_MILLIS = 30000 -_DEFAULT_MAX_QUEUE_SIZE = 2048 -_ENV_VAR_INT_VALUE_ERROR_MESSAGE = "Unable to parse value for %s as integer. Defaulting to %s." - -logger = logging.getLogger(__name__) - - -class SpanExportResult(Enum): - SUCCESS = 0 - FAILURE = 1 - - -class SpanExporter: - """Interface for exporting spans. - - Interface to be implemented by services that want to export spans recorded - in their own format. - - To export data this MUST be registered to the :class`opentelemetry.sdk.trace.Tracer` using a - `SimpleSpanProcessor` or a `BatchSpanProcessor`. - """ - - def export(self, spans: collections.abc.Sequence[ReadableSpan]) -> SpanExportResult: # pyright: ignore[reportReturnType] - """Exports a batch of telemetry data. - - Args: - spans: The list of `opentelemetry.trace.Span` objects to be exported - - Returns: - The result of the export - """ - - def shutdown(self) -> None: - """Shuts down the exporter. - - Called when the SDK is shut down. - """ - - def force_flush(self, timeout_millis: int = 30000) -> bool: # pyright: ignore[reportReturnType] - """Hint to ensure that the export of any spans the exporter has received - prior to the call to ForceFlush SHOULD be completed as soon as possible, preferably - before returning from this method. - """ - - -class SimpleSpanProcessor(SpanProcessor): - """Simple SpanProcessor implementation. - - SimpleSpanProcessor is an implementation of `SpanProcessor` that - passes ended spans directly to the configured `SpanExporter`. - """ - - def __init__( - self, - span_exporter: SpanExporter, - *, - meter_provider: MeterProvider | None = None, - ): - self.span_exporter = span_exporter - self._shutdown = False - self._metrics = create_processor_metrics( - "traces", - OtelComponentTypeValues.SIMPLE_SPAN_PROCESSOR, - meter_provider or get_meter_provider(), - enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ) - - def on_start(self, span: Span, parent_context: Context | None = None) -> None: - pass - - def _on_ending(self, span: Span) -> None: - pass - - def on_end(self, span: ReadableSpan) -> None: - if not (span.context and span.context.trace_flags.sampled): - return - if self._shutdown: - logger.warning("Processor is already shutdown, ignoring call") - self._metrics.drop_items(1, "already_shutdown") - return - token = attach(set_value(_SUPPRESS_INSTRUMENTATION_KEY, True)) - # Record on submission to the exporter. - self._metrics.finish_items(1) - try: - self.span_exporter.export((span,)) - # pylint: disable=broad-exception-caught - except Exception: - logger.exception("Exception while exporting Span.") - finally: - detach(token) - - def shutdown(self) -> None: - self._shutdown = True - self.span_exporter.shutdown() - - def force_flush(self, timeout_millis: int = 30000) -> bool: - # pylint: disable=unused-argument - return True - - -class BatchSpanProcessor(SpanProcessor): - """Batch span processor implementation. - - `BatchSpanProcessor` is an implementation of `SpanProcessor` that - batches ended spans and pushes them to the configured `SpanExporter`. - - `BatchSpanProcessor` is configurable with the following environment - variables which correspond to constructor parameters: - - - :envvar:`OTEL_BSP_SCHEDULE_DELAY` - - :envvar:`OTEL_BSP_MAX_QUEUE_SIZE` - - :envvar:`OTEL_BSP_MAX_EXPORT_BATCH_SIZE` - - :envvar:`OTEL_BSP_EXPORT_TIMEOUT` - - All the logic for emitting spans, shutting down etc. resides in the `BatchProcessor` class. - """ - - def __init__( - self, - span_exporter: SpanExporter, - max_queue_size: int | None = None, - schedule_delay_millis: float | None = None, - max_export_batch_size: int | None = None, - export_timeout_millis: float | None = None, - *, - meter_provider: MeterProvider | None = None, - ): - if max_queue_size is None: - max_queue_size = BatchSpanProcessor._default_max_queue_size() - - if schedule_delay_millis is None: - schedule_delay_millis = BatchSpanProcessor._default_schedule_delay_millis() - - if max_export_batch_size is None: - max_export_batch_size = BatchSpanProcessor._default_max_export_batch_size() - - # Not used. No way currently to pass timeout to export. - if export_timeout_millis is None: - export_timeout_millis = BatchSpanProcessor._default_export_timeout_millis() - - BatchSpanProcessor._validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size) - - self._batch_processor = BatchProcessor( - span_exporter, - schedule_delay_millis, - max_export_batch_size, - export_timeout_millis, - max_queue_size, - "Span", - create_processor_metrics( - "traces", - OtelComponentTypeValues.BATCHING_SPAN_PROCESSOR, - meter_provider or get_meter_provider(), - capacity=max_queue_size, - enabled=parse_boolean_environment_variable(OTEL_PYTHON_SDK_INTERNAL_METRICS_ENABLED), - ), - ) - - # Added for backward compatibility. Not recommended to directly access/use underlying exporter. - @property - def span_exporter(self): - return self._batch_processor._exporter # pylint: disable=protected-access - - def on_start(self, span: Span, parent_context: Context | None = None) -> None: - pass - - def _on_ending(self, span: Span) -> None: - pass - - def on_end(self, span: ReadableSpan) -> None: - if not (span.context and span.context.trace_flags.sampled): - return - self._batch_processor.emit(span) - - def shutdown(self): - return self._batch_processor.shutdown() - - def force_flush(self, timeout_millis: int | None = None) -> bool: - return self._batch_processor.force_flush(timeout_millis) - - @staticmethod - def _default_max_queue_size(): - try: - return int(environ.get(OTEL_BSP_MAX_QUEUE_SIZE, _DEFAULT_MAX_QUEUE_SIZE)) - except ValueError: - logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BSP_MAX_QUEUE_SIZE, - _DEFAULT_MAX_QUEUE_SIZE, - ) - return _DEFAULT_MAX_QUEUE_SIZE - - @staticmethod - def _default_schedule_delay_millis(): - try: - return int(environ.get(OTEL_BSP_SCHEDULE_DELAY, _DEFAULT_SCHEDULE_DELAY_MILLIS)) - except ValueError: - logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BSP_SCHEDULE_DELAY, - _DEFAULT_SCHEDULE_DELAY_MILLIS, - ) - return _DEFAULT_SCHEDULE_DELAY_MILLIS - - @staticmethod - def _default_max_export_batch_size(): - try: - return int( - environ.get( - OTEL_BSP_MAX_EXPORT_BATCH_SIZE, - _DEFAULT_MAX_EXPORT_BATCH_SIZE, - ) - ) - except ValueError: - logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BSP_MAX_EXPORT_BATCH_SIZE, - _DEFAULT_MAX_EXPORT_BATCH_SIZE, - ) - return _DEFAULT_MAX_EXPORT_BATCH_SIZE - - @staticmethod - def _default_export_timeout_millis(): - try: - return int(environ.get(OTEL_BSP_EXPORT_TIMEOUT, _DEFAULT_EXPORT_TIMEOUT_MILLIS)) - except ValueError: - logger.exception( - _ENV_VAR_INT_VALUE_ERROR_MESSAGE, - OTEL_BSP_EXPORT_TIMEOUT, - _DEFAULT_EXPORT_TIMEOUT_MILLIS, - ) - return _DEFAULT_EXPORT_TIMEOUT_MILLIS - - @staticmethod - def _validate_arguments(max_queue_size, schedule_delay_millis, max_export_batch_size): - if max_queue_size <= 0: - raise ValueError("max_queue_size must be a positive integer.") - - if schedule_delay_millis <= 0: - raise ValueError("schedule_delay_millis must be positive.") - - if max_export_batch_size <= 0: - raise ValueError("max_export_batch_size must be a positive integer.") - - if max_export_batch_size > max_queue_size: - raise ValueError("max_export_batch_size must be less than or equal to max_queue_size.") - - -class ConsoleSpanExporter(SpanExporter): - """Implementation of :class:`SpanExporter` that prints spans to the - console. - - This class can be used for diagnostic purposes. It prints the exported - spans to the console STDOUT. - """ - - def __init__( - self, - service_name: str | None = None, - out: typing.IO = sys.stdout, - formatter: collections.abc.Callable[[ReadableSpan], str] = lambda span: span.to_json() + linesep, - ): - self.out = out - self.formatter = formatter - self.service_name = service_name - - def export(self, spans: collections.abc.Sequence[ReadableSpan]) -> SpanExportResult: - for span in spans: - self.out.write(self.formatter(span)) - self.out.flush() - return SpanExportResult.SUCCESS - - def force_flush(self, timeout_millis: int = 30000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py deleted file mode 100644 index 436143c14f2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/export/in_memory_span_exporter.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import collections.abc -import threading -from collections import deque - -from opentelemetry.agent._vendor.opentelemetry.sdk.trace import ReadableSpan -from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult - - -class InMemorySpanExporter(SpanExporter): - """Implementation of :class:`.SpanExporter` that stores spans in memory. - - This class can be used for testing purposes. It stores the exported spans - in a deque in memory that can be retrieved using the - :func:`.get_finished_spans` method. - - Args: - max_spans: Maximum number of spans to store in memory. When the limit - is reached, the oldest spans are dropped automatically. If ``None`` - (default), there is no limit. - """ - - def __init__(self, max_spans: int | None = None) -> None: - self._finished_spans: deque[ReadableSpan] = deque(maxlen=max_spans) - self._stopped = False - self._lock = threading.Lock() - - def clear(self) -> None: - """Clear list of collected spans.""" - with self._lock: - self._finished_spans.clear() - - def get_finished_spans(self) -> tuple[ReadableSpan, ...]: - """Get list of collected spans.""" - with self._lock: - return tuple(self._finished_spans) - - def export(self, spans: collections.abc.Sequence[ReadableSpan]) -> SpanExportResult: - """Stores a list of spans in memory.""" - if self._stopped: - return SpanExportResult.FAILURE - with self._lock: - self._finished_spans.extend(spans) - return SpanExportResult.SUCCESS - - def shutdown(self) -> None: - """Shut downs the exporter. - - Calls to export after the exporter has been shut down will fail. - """ - self._stopped = True - - def force_flush(self, timeout_millis: int = 30000) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py deleted file mode 100644 index 2484ce7f93c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/id_generator.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import abc -import random - -from opentelemetry.agent._vendor.opentelemetry import trace - - -class IdGenerator(abc.ABC): - @abc.abstractmethod - def generate_span_id(self) -> int: - """Get a new span ID. - - Returns: - A 64-bit int for use as a span ID - """ - - @abc.abstractmethod - def generate_trace_id(self) -> int: - """Get a new trace ID. - - Implementations should at least make the 56 least significant bits - uniformly random. Samplers like the `TraceIdRatioBased` sampler rely on - this randomness to make sampling decisions. - - If the implementation does randomly generate the 56 least significant bits, - it should also implement `is_trace_id_random` to return True. - - See `the specification on TraceIdRatioBased `_. - - Returns: - A 128-bit int for use as a trace ID - """ - - # pylint: disable=no-self-use - def is_trace_id_random(self) -> bool: - """Indicates whether generated trace IDs are random. - - When True, the `trace-id` field will have the `random-trace-id` flag set - in the W3C traceparent header. Per the W3C Trace Context specification, - this indicates that at least the 7 rightmost bytes (56 bits) of the - trace ID were generated randomly with uniform distribution. - - See `the W3C Trace Context specification `_. - - Returns: - True if this generator produces random IDs, False otherwise. - """ - # By default, return False for backwards compatibility. - return False - - -class RandomIdGenerator(IdGenerator): - """The default ID generator for TracerProvider which randomly generates all - bits when generating IDs. - """ - - def generate_span_id(self) -> int: - span_id = random.getrandbits(64) - while span_id == trace.INVALID_SPAN_ID: - span_id = random.getrandbits(64) - return span_id - - def generate_trace_id(self) -> int: - trace_id = random.getrandbits(128) - while trace_id == trace.INVALID_TRACE_ID: - trace_id = random.getrandbits(128) - return trace_id - - def is_trace_id_random(self) -> bool: - return True diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py deleted file mode 100644 index 64d96ae552f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/trace/sampling.py +++ /dev/null @@ -1,488 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -""" -For general information about sampling, see `the specification `_. - -OpenTelemetry provides two types of samplers: - -- `StaticSampler` -- `TraceIdRatioBased` - -A `StaticSampler` always returns the same sampling result regardless of the conditions. Both possible StaticSamplers are already created: - -- Always sample spans: ALWAYS_ON -- Never sample spans: ALWAYS_OFF - -A `TraceIdRatioBased` sampler makes a random sampling result based on the sampling probability given. - -If the span being sampled has a parent, `ParentBased` will respect the parent delegate sampler. Otherwise, it returns the sampling result from the given root sampler. - -Currently, sampling results are always made during the creation of the span. However, this might not always be the case in the future (see `OTEP #115 `_). - -Custom samplers can be created by subclassing `Sampler` and implementing `Sampler.should_sample` as well as `Sampler.get_description`. - -Samplers are able to modify the `opentelemetry.trace.span.TraceState` of the parent of the span being created. For custom samplers, it is suggested to implement `Sampler.should_sample` to utilize the -parent span context's `opentelemetry.trace.span.TraceState` and pass into the `SamplingResult` instead of the explicit trace_state field passed into the parameter of `Sampler.should_sample`. - -To use a sampler, pass it into the tracer provider constructor. For example: - -.. code:: python - - from opentelemetry import trace - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import ( - ConsoleSpanExporter, - SimpleSpanProcessor, - ) - from opentelemetry.sdk.trace.sampling import TraceIdRatioBased - - # sample 1 in every 1000 traces - sampler = TraceIdRatioBased(1/1000) - - # set the sampler onto the global tracer provider - trace.set_tracer_provider(TracerProvider(sampler=sampler)) - - # set up an exporter for sampled spans - trace.get_tracer_provider().add_span_processor( - SimpleSpanProcessor(ConsoleSpanExporter()) - ) - - # created spans will now be sampled by the TraceIdRatioBased sampler - with trace.get_tracer(__name__).start_as_current_span("Test Span"): - ... - -The tracer sampler can also be configured via environment variables ``OTEL_TRACES_SAMPLER`` and ``OTEL_TRACES_SAMPLER_ARG`` (only if applicable). -The list of built-in values for ``OTEL_TRACES_SAMPLER`` are: - - * always_on - Sampler that always samples spans, regardless of the parent span's sampling decision. - * always_off - Sampler that never samples spans, regardless of the parent span's sampling decision. - * traceidratio - Sampler that samples probabilistically based on rate. - * parentbased_always_on - (default) Sampler that respects its parent span's sampling decision, but otherwise always samples. - * parentbased_always_off - Sampler that respects its parent span's sampling decision, but otherwise never samples. - * parentbased_traceidratio - Sampler that respects its parent span's sampling decision, but otherwise samples probabilistically based on rate. - -Sampling probability can be set with ``OTEL_TRACES_SAMPLER_ARG`` if the sampler is traceidratio or parentbased_traceidratio. Rate must be in the range [0.0,1.0]. When not provided rate will be set to -1.0 (maximum rate possible). - -Prev example but with environment variables. Please make sure to set the env ``OTEL_TRACES_SAMPLER=traceidratio`` and ``OTEL_TRACES_SAMPLER_ARG=0.001``. - -.. code:: python - - from opentelemetry import trace - from opentelemetry.sdk.trace import TracerProvider - from opentelemetry.sdk.trace.export import ( - ConsoleSpanExporter, - SimpleSpanProcessor, - ) - - trace.set_tracer_provider(TracerProvider()) - - # set up an exporter for sampled spans - trace.get_tracer_provider().add_span_processor( - SimpleSpanProcessor(ConsoleSpanExporter()) - ) - - # created spans will now be sampled by the TraceIdRatioBased sampler with rate 1/1000. - with trace.get_tracer(__name__).start_as_current_span("Test Span"): - ... - -When utilizing a configurator, you can configure a custom sampler. In order to create a configurable custom sampler, create an entry point for the custom sampler -factory method or function under the entry point group, ``opentelemetry_traces_sampler``. The custom sampler factory method must be of type ``Callable[[str], Sampler]``, taking a single string argument and -returning a Sampler object. The single input will come from the string value of the ``OTEL_TRACES_SAMPLER_ARG`` environment variable. If ``OTEL_TRACES_SAMPLER_ARG`` is not configured, the input will -be an empty string. For example: - -.. code:: python - - setup( - ... - entry_points={ - ... - "opentelemetry_traces_sampler": [ - "custom_sampler_name = path.to.sampler.factory.method:CustomSamplerFactory.get_sampler" - ] - } - ) - # ... - class CustomRatioSampler(Sampler): - def __init__(rate): - # ... - # ... - class CustomSamplerFactory: - @staticmethod - def get_sampler(sampler_argument): - try: - rate = float(sampler_argument) - return CustomSampler(rate) - except ValueError: # In case argument is empty string. - return CustomSampler(0.5) - -In order to configure you application with a custom sampler's entry point, set the ``OTEL_TRACES_SAMPLER`` environment variable to the key name of the entry point. For example, to configured the -above sampler, set ``OTEL_TRACES_SAMPLER=custom_sampler_name`` and ``OTEL_TRACES_SAMPLER_ARG=0.5``. -""" - -from __future__ import annotations - -import abc -import enum -import os -from collections.abc import Sequence -from logging import getLogger -from types import MappingProxyType - -# pylint: disable=unused-import -from opentelemetry.agent._vendor.opentelemetry.context import Context -from opentelemetry.agent._vendor.opentelemetry.sdk.environment_variables import ( - OTEL_TRACES_SAMPLER, - OTEL_TRACES_SAMPLER_ARG, -) -from opentelemetry.agent._vendor.opentelemetry.trace import Link, SpanKind, get_current_span -from opentelemetry.agent._vendor.opentelemetry.trace.span import TraceState -from opentelemetry.agent._vendor.opentelemetry.util.types import Attributes - -_logger = getLogger(__name__) - - -class Decision(enum.Enum): - # IsRecording() == false, span will not be recorded and all events and attributes will be dropped. - DROP = 0 - # IsRecording() == true, but Sampled flag MUST NOT be set. - RECORD_ONLY = 1 - # IsRecording() == true AND Sampled flag` MUST be set. - RECORD_AND_SAMPLE = 2 - - def is_recording(self): - return self in (Decision.RECORD_ONLY, Decision.RECORD_AND_SAMPLE) - - def is_sampled(self): - return self is Decision.RECORD_AND_SAMPLE - - -class SamplingResult: - """A sampling result as applied to a newly-created Span. - - Args: - decision: A sampling decision based off of whether the span is recorded - and the sampled flag in trace flags in the span context. - attributes: Attributes to add to the `opentelemetry.trace.Span`. - trace_state: The tracestate used for the `opentelemetry.trace.Span`. - Could possibly have been modified by the sampler. - """ - - def __repr__(self) -> str: - return f"{type(self).__name__}({self.decision!s}, attributes={self.attributes!s})" - - def __init__( - self, - decision: Decision, - attributes: Attributes = None, - trace_state: TraceState | None = None, - ) -> None: - self.decision = decision - if attributes is None: - self.attributes = MappingProxyType({}) - else: - self.attributes = MappingProxyType(attributes) - self.trace_state = trace_state - - -class Sampler(abc.ABC): - @abc.abstractmethod - def should_sample( - self, - parent_context: Context | None, - trace_id: int, - name: str, - kind: SpanKind | None = None, - attributes: Attributes = None, - links: Sequence[Link] | None = None, - trace_state: TraceState | None = None, - ) -> SamplingResult: - pass - - @abc.abstractmethod - def get_description(self) -> str: - pass - - -class StaticSampler(Sampler): - """Sampler that always returns the same decision.""" - - def __init__(self, decision: Decision) -> None: - self._decision = decision - - def should_sample( - self, - parent_context: Context | None, - trace_id: int, - name: str, - kind: SpanKind | None = None, - attributes: Attributes = None, - links: Sequence[Link] | None = None, - trace_state: TraceState | None = None, - ) -> SamplingResult: - if self._decision is Decision.DROP: - attributes = None - return SamplingResult( - self._decision, - attributes, - _get_parent_trace_state(parent_context), - ) - - def get_description(self) -> str: - if self._decision is Decision.DROP: - return "AlwaysOffSampler" - return "AlwaysOnSampler" - - -ALWAYS_OFF = StaticSampler(Decision.DROP) -"""Sampler that never samples spans, regardless of the parent span's sampling decision.""" - -ALWAYS_ON = StaticSampler(Decision.RECORD_AND_SAMPLE) -"""Sampler that always samples spans, regardless of the parent span's sampling decision.""" - - -class TraceIdRatioBased(Sampler): - """ - Sampler that makes sampling decisions probabilistically based on `rate`. - - Args: - rate: Probability (between 0 and 1) that a span will be sampled - """ - - def __init__(self, rate: float): - if rate < 0.0 or rate > 1.0: - raise ValueError("Probability must be in range [0.0, 1.0].") - self._rate = rate - self._bound = self.get_bound_for_rate(self._rate) - - # For compatibility with 64 bit trace IDs, the sampler checks the 64 - # low-order bits of the trace ID to decide whether to sample a given trace. - TRACE_ID_LIMIT = (1 << 64) - 1 - - @classmethod - def get_bound_for_rate(cls, rate: float) -> int: - return round(rate * (cls.TRACE_ID_LIMIT + 1)) - - @property - def rate(self) -> float: - return self._rate - - @property - def bound(self) -> int: - return self._bound - - def should_sample( - self, - parent_context: Context | None, - trace_id: int, - name: str, - kind: SpanKind | None = None, - attributes: Attributes = None, - links: Sequence[Link] | None = None, - trace_state: TraceState | None = None, - ) -> SamplingResult: - decision = Decision.DROP - if trace_id & self.TRACE_ID_LIMIT < self.bound: - decision = Decision.RECORD_AND_SAMPLE - if decision is Decision.DROP: - attributes = None - return SamplingResult( - decision, - attributes, - _get_parent_trace_state(parent_context), - ) - - def get_description(self) -> str: - return f"TraceIdRatioBased{{{self._rate}}}" - - -class ParentBased(Sampler): - """ - If a parent is set, applies the respective delegate sampler. - Otherwise, uses the root provided at initialization to make a - decision. - - Args: - root: Sampler called for spans with no parent (root spans). - remote_parent_sampled: Sampler called for a remote sampled parent. - remote_parent_not_sampled: Sampler called for a remote parent that is - not sampled. - local_parent_sampled: Sampler called for a local sampled parent. - local_parent_not_sampled: Sampler called for a local parent that is - not sampled. - """ - - def __init__( - self, - root: Sampler, - remote_parent_sampled: Sampler = ALWAYS_ON, - remote_parent_not_sampled: Sampler = ALWAYS_OFF, - local_parent_sampled: Sampler = ALWAYS_ON, - local_parent_not_sampled: Sampler = ALWAYS_OFF, - ): - self._root = root - self._remote_parent_sampled = remote_parent_sampled - self._remote_parent_not_sampled = remote_parent_not_sampled - self._local_parent_sampled = local_parent_sampled - self._local_parent_not_sampled = local_parent_not_sampled - - def should_sample( - self, - parent_context: Context | None, - trace_id: int, - name: str, - kind: SpanKind | None = None, - attributes: Attributes = None, - links: Sequence[Link] | None = None, - trace_state: TraceState | None = None, - ) -> SamplingResult: - parent_span_context = get_current_span(parent_context).get_span_context() - # default to the root sampler - sampler = self._root - # respect the sampling and remote flag of the parent if present - if parent_span_context is not None and parent_span_context.is_valid: - if parent_span_context.is_remote: - if parent_span_context.trace_flags.sampled: - sampler = self._remote_parent_sampled - else: - sampler = self._remote_parent_not_sampled - else: - if parent_span_context.trace_flags.sampled: - sampler = self._local_parent_sampled - else: - sampler = self._local_parent_not_sampled - - return sampler.should_sample( - parent_context=parent_context, - trace_id=trace_id, - name=name, - kind=kind, - attributes=attributes, - links=links, - ) - - def get_description(self): - return f"ParentBased{{root:{self._root.get_description()},remoteParentSampled:{self._remote_parent_sampled.get_description()},remoteParentNotSampled:{self._remote_parent_not_sampled.get_description()},localParentSampled:{self._local_parent_sampled.get_description()},localParentNotSampled:{self._local_parent_not_sampled.get_description()}}}" - - -class AlwaysRecordSampler(Sampler): - """ - This sampler will return the sampling result of the provided `root`, unless the - sampling result contains the sampling decision `Decision.DROP`, in which case, a - new sampling result will be returned that is functionally equivalent to the original, except that - it contains the sampling decision `Decision.RECORD_ONLY`. This ensures that all - spans are recorded, with no change to sampling. - - The intended use case of this sampler is to provide a means of sending all spans to a - processor without having an impact on the sampling rate. This may be desirable if a user wishes - to count or otherwise measure all spans produced in a service, without incurring the cost of 100% - sampling. - """ - - def __init__(self, root: Sampler): - if root is None: - raise ValueError("root must not be None") - self._root = root - - def should_sample( - self, - parent_context: Context | None, - trace_id: int, - name: str, - kind: SpanKind | None = None, - attributes: Attributes = None, - links: Sequence[Link] | None = None, - trace_state: TraceState | None = None, - ) -> SamplingResult: - result: SamplingResult = self._root.should_sample( - parent_context, - trace_id, - name, - kind, - attributes, - links, - trace_state, - ) - if result.decision is Decision.DROP: - result = SamplingResult(Decision.RECORD_ONLY, result.attributes, result.trace_state) - - return result - - def get_description(self): - return f"AlwaysRecordSampler{{{self._root.get_description()}}}" - - -DEFAULT_OFF = ParentBased(ALWAYS_OFF) -"""Sampler that respects its parent span's sampling decision, but otherwise never samples.""" - -DEFAULT_ON = ParentBased(ALWAYS_ON) -"""Sampler that respects its parent span's sampling decision, but otherwise always samples.""" - - -class ParentBasedTraceIdRatio(ParentBased): - """ - Sampler that respects its parent span's sampling decision, but otherwise - samples probabilistically based on `rate`. - """ - - def __init__(self, rate: float): - root = TraceIdRatioBased(rate=rate) - super().__init__(root=root) - - -class _AlwaysOff(StaticSampler): - def __init__(self, _): - super().__init__(Decision.DROP) - - -class _AlwaysOn(StaticSampler): - def __init__(self, _): - super().__init__(Decision.RECORD_AND_SAMPLE) - - -class _ParentBasedAlwaysOff(ParentBased): - def __init__(self, _): - super().__init__(ALWAYS_OFF) - - -class _ParentBasedAlwaysOn(ParentBased): - def __init__(self, _): - super().__init__(ALWAYS_ON) - - -_KNOWN_SAMPLERS = { - "always_on": ALWAYS_ON, - "always_off": ALWAYS_OFF, - "parentbased_always_on": DEFAULT_ON, - "parentbased_always_off": DEFAULT_OFF, - "traceidratio": TraceIdRatioBased, - "parentbased_traceidratio": ParentBasedTraceIdRatio, -} - - -def _get_from_env_or_default() -> Sampler: - trace_sampler = os.getenv(OTEL_TRACES_SAMPLER, "parentbased_always_on").lower() - if trace_sampler not in _KNOWN_SAMPLERS: - _logger.warning("Couldn't recognize sampler %s.", trace_sampler) - trace_sampler = "parentbased_always_on" - - if trace_sampler in ("traceidratio", "parentbased_traceidratio"): - try: - rate = float(os.getenv(OTEL_TRACES_SAMPLER_ARG, "")) - return _KNOWN_SAMPLERS[trace_sampler](rate) - except (ValueError, TypeError): - _logger.warning("Could not convert TRACES_SAMPLER_ARG to float. Using default rate 1.0.") - return _KNOWN_SAMPLERS[trace_sampler](1.0) - - return _KNOWN_SAMPLERS[trace_sampler] - - -def _get_parent_trace_state( - parent_context: Context | None, -) -> TraceState | None: - parent_span_context = get_current_span(parent_context).get_span_context() - if parent_span_context is None or not parent_span_context.is_valid: - return None - return parent_span_context.trace_state diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py deleted file mode 100644 index c762410e3c4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import copy -import datetime -import threading -from collections import deque -from collections.abc import MutableMapping, Sequence - -from opentelemetry.agent._vendor.typing_extensions import deprecated - - -def ns_to_iso_str(nanoseconds): - """Get an ISO 8601 string from time_ns value.""" - ts = datetime.datetime.fromtimestamp(nanoseconds / 1e9, tz=datetime.timezone.utc) - return ts.strftime("%Y-%m-%dT%H:%M:%S.%fZ") - - -def get_dict_as_key(labels): - """Converts a dict to be used as a unique key""" - return tuple( - sorted( - map( - lambda kv: (kv[0], tuple(kv[1])) if isinstance(kv[1], list) else kv, - labels.items(), - ) - ) - ) - - -class BoundedList(Sequence): - """An append only list with a fixed max size. - - Calls to `append` and `extend` will drop the oldest elements if there is - not enough room. - """ - - def __init__(self, maxlen: int | None): - self.dropped = 0 - self._dq = deque(maxlen=maxlen) # type: deque - self._lock = threading.Lock() - - def __deepcopy__(self, memo): - copy_ = BoundedList(0) - memo[id(self)] = copy_ - with self._lock: - copy_.dropped = self.dropped - copy_._dq = copy.deepcopy(self._dq, memo) - return copy_ - - def __repr__(self): - return f"{type(self).__name__}({list(self._dq)}, maxlen={self._dq.maxlen})" - - def __getitem__(self, index): - return self._dq[index] - - def __len__(self): - return len(self._dq) - - def __iter__(self): - with self._lock: - return iter(list(self._dq)) - - def append(self, item): - with self._lock: - if self._dq.maxlen is not None and len(self._dq) == self._dq.maxlen: - self.dropped += 1 - self._dq.append(item) - - def extend(self, seq): - with self._lock: - if self._dq.maxlen is not None: - to_drop = len(seq) + len(self._dq) - self._dq.maxlen - if to_drop > 0: - self.dropped += to_drop - self._dq.extend(seq) - - @classmethod - def from_seq(cls, maxlen, seq): - seq = tuple(seq) - bounded_list = cls(maxlen) - bounded_list.extend(seq) - return bounded_list - - -@deprecated("Deprecated since version 1.4.0.") -class BoundedDict(MutableMapping): - """An ordered dict with a fixed max capacity. - - Oldest elements are dropped when the dict is full and a new element is - added. - """ - - def __init__(self, maxlen: int | None): - if maxlen is not None: - if not isinstance(maxlen, int): - raise ValueError - if maxlen < 0: - raise ValueError - self.maxlen = maxlen - self.dropped = 0 - self._dict = {} # type: dict - self._lock = threading.Lock() # type: threading.Lock - - def __repr__(self): - return f"{type(self).__name__}({dict(self._dict)}, maxlen={self.maxlen})" - - def __getitem__(self, key): - return self._dict[key] - - def __setitem__(self, key, value): - with self._lock: - if self.maxlen is not None and self.maxlen == 0: - self.dropped += 1 - return - - if key in self._dict: - del self._dict[key] - elif self.maxlen is not None and len(self._dict) == self.maxlen: - del self._dict[next(iter(self._dict.keys()))] - self.dropped += 1 - self._dict[key] = value - - def __delitem__(self, key): - del self._dict[key] - - def __iter__(self): - with self._lock: - return iter(self._dict.copy()) - - def __len__(self): - return len(self._dict) - - @classmethod - def from_map(cls, maxlen, mapping): - mapping = dict(mapping) - bounded_dict = cls(maxlen) - for key, value in mapping.items(): - bounded_dict[key] = value - return bounded_dict diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi deleted file mode 100644 index 1b769659492..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/__init__.pyi +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright The OpenTelemetry Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from collections.abc import ( - Iterable, - Iterator, - Mapping, - MutableMapping, - Sequence, -) -from typing import ( - Any, - TypeVar, - overload, -) - -from opentelemetry.util.types import AnyValue, AttributesAsKey - -_T = TypeVar("_T") -_KT = TypeVar("_KT") -_VT = TypeVar("_VT") - -def ns_to_iso_str(nanoseconds: int) -> str: ... -def get_dict_as_key( - labels: Mapping[str, AnyValue], -) -> AttributesAsKey: ... - -# pylint: disable=no-self-use -class BoundedList(Sequence[_T]): - """An append only list with a fixed max size. - - Calls to `append` and `extend` will drop the oldest elements if there is - not enough room. - """ - - dropped: int - def __init__(self, maxlen: int | None): ... - def __deepcopy__(self, memo: dict[int, Any]) -> BoundedList[_T]: ... - def insert(self, index: int, value: _T) -> None: ... - @overload - def __getitem__(self, i: int) -> _T: ... - @overload - def __getitem__(self, s: slice) -> Sequence[_T]: ... - def __len__(self) -> int: ... - def append(self, item: _T) -> None: ... - def extend(self, seq: Sequence[_T]) -> None: ... - @classmethod - def from_seq(cls, maxlen: int | None, seq: Iterable[_T]) -> BoundedList[_T]: ... # pylint: disable=undefined-variable - -class BoundedDict(MutableMapping[_KT, _VT]): - """An ordered dict with a fixed max capacity. - - Oldest elements are dropped when the dict is full and a new element is - added. - """ - - dropped: int - def __init__(self, maxlen: int): ... - def __getitem__(self, k: _KT) -> _VT: ... - def __setitem__(self, k: _KT, v: _VT) -> None: ... - def __delitem__(self, v: _KT) -> None: ... - def __iter__(self) -> Iterator[_KT]: ... - def __len__(self) -> int: ... - @classmethod - def from_map(cls, maxlen: int, mapping: Mapping[_KT, _VT]) -> BoundedDict[_KT, _VT]: ... # pylint: disable=undefined-variable diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py deleted file mode 100644 index 4974fd762c6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/_configurator.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from collections.abc import Sequence -from typing import Generic, TypeVar - -from opentelemetry.agent._vendor.opentelemetry.sdk.util.instrumentation import ( - InstrumentationScope, - _InstrumentationScopePredicateT, -) - -ConfigT = TypeVar("ConfigT") -ConfiguratorRulesT = Sequence[tuple[_InstrumentationScopePredicateT, ConfigT]] - - -class RuleBasedConfigurator(Generic[ConfigT]): - def __init__(self, *, rules: ConfiguratorRulesT, default_config: ConfigT): - self._rules = rules - self._default_config = default_config - - def __call__(self, scope: InstrumentationScope) -> ConfigT: - for predicate, config in self._rules: - if predicate(scope): - return config - # by default return default config - return self._default_config - - def update_rules(self, rules: ConfiguratorRulesT) -> None: - self._rules = rules diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py deleted file mode 100644 index 9cf849129b5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/util/instrumentation.py +++ /dev/null @@ -1,191 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -from collections.abc import Callable -from fnmatch import fnmatchcase -from json import dumps - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes -from opentelemetry.agent._vendor.opentelemetry.util.types import ( # TODO: see if we can remove F401 when using new sphinx version # noqa: F401 # pylint: disable=unused-import - AnyValue, - Attributes, -) - - -# opentelemetry-agent: instrumentations vendored under the agent's namespace name their scope after -# their module (get_tracer(__name__)); report the upstream module name instead, e.g. -# "opentelemetry.instrumentation.aiohttp_client" rather than "opentelemetry.agent._vendor.opentelemetry...". -_VENDOR_PREFIX = __name__.removesuffix("opentelemetry.sdk.util.instrumentation") - - -def _unvendored_name(name: str) -> str: - if isinstance(name, str) and name.startswith(_VENDOR_PREFIX): - return name[len(_VENDOR_PREFIX) :] - return name - - -class InstrumentationInfo: - """Immutable information about an instrumentation library module. - - See `opentelemetry.trace.TracerProvider.get_tracer` for the meaning of these - properties. - """ - - __slots__ = ("_name", "_version", "_schema_url") - - @deprecated("You should use InstrumentationScope. Deprecated since version 1.11.1.") - def __init__( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - ): - self._name = _unvendored_name(name) - self._version = version - if schema_url is None: - schema_url = "" - self._schema_url = schema_url - - def __repr__(self): - return f"{type(self).__name__}({self._name}, {self._version}, {self._schema_url})" - - def __hash__(self): - return hash((self._name, self._version, self._schema_url)) - - def __eq__(self, value): - return type(value) is type(self) and ( - self._name, - self._version, - self._schema_url, - ) == (value._name, value._version, value._schema_url) - - def __lt__(self, value): - if type(value) is not type(self): - return NotImplemented - return (self._name, self._version, self._schema_url) < ( - value._name, - value._version, - value._schema_url, - ) - - @property - def schema_url(self) -> str | None: - return self._schema_url - - @property - def version(self) -> str | None: - return self._version - - @property - def name(self) -> str: - return self._name - - -class InstrumentationScope: - """A logical unit of the application code with which the emitted telemetry can be - associated. - - See `opentelemetry.trace.TracerProvider.get_tracer` for the meaning of these - properties. - """ - - __slots__ = ( - "_name", - "_version", - "_schema_url", - "_attributes", - ) - - def __init__( - self, - name: str, - version: str | None = None, - schema_url: str | None = None, - attributes: Attributes = None, - ) -> None: - self._name = _unvendored_name(name) - self._version = version - if schema_url is None: - schema_url = "" - self._schema_url = schema_url - # Attributes cannot be added/removed after creation. - self._attributes = BoundedAttributes(attributes=attributes, immutable=True) - - def __repr__(self) -> str: - return f"{type(self).__name__}({self._name}, {self._version}, {self._schema_url}, {self._attributes})" - - def __hash__(self) -> int: - return hash((self._name, self._version, self._schema_url)) - - def __eq__(self, value: object) -> bool: - if not isinstance(value, InstrumentationScope): - return NotImplemented - return ( - self._name, - self._version, - self._schema_url, - self._attributes, - ) == ( - value._name, - value._version, - value._schema_url, - value._attributes, - ) - - def __lt__(self, value: object) -> bool: - if not isinstance(value, InstrumentationScope): - return NotImplemented - return ( - self._name, - self._version, - self._schema_url, - self._attributes, - ) < ( - value._name, - value._version, - value._schema_url, - value._attributes, - ) - - @property - def schema_url(self) -> str | None: - return self._schema_url - - @property - def version(self) -> str | None: - return self._version - - @property - def name(self) -> str: - return self._name - - @property - def attributes(self) -> Attributes: - return self._attributes - - def to_json(self, indent: int | None = 4) -> str: - return dumps( - { - "name": self._name, - "version": self._version, - "schema_url": self._schema_url, - "attributes": (dict(self._attributes) if bool(self._attributes) else None), - }, - indent=indent, - ) - - -_InstrumentationScopePredicateT = Callable[[InstrumentationScope], bool] - - -def _scope_name_matches_glob( - glob_pattern: str, -) -> _InstrumentationScopePredicateT: - def inner(scope: InstrumentationScope) -> bool: - # Scope name matching is case-sensitive. fnmatchcase is used instead of - # fnmatch so it does not rely on the host platform's filename case - # sensitivity (normcase), which lower-cases both operands on Windows. - return fnmatchcase(scope.name, glob_pattern) - - return inner diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py deleted file mode 100644 index 0101c361616..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/sdk/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py deleted file mode 100644 index 77289c2536c..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/app_attributes.py +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -APP_BUILD_ID: Final = "app.build_id" -""" -Unique identifier for a particular build or compilation of the application. -""" - -APP_CRASH_ID: Final = "app.crash.id" -""" -A unique identifier representing an instance of an end user facing app crash. -Note: Its value MAY be meaningful and be used as a reference for telemetry and metadata recorded by -the same instrumentation (e.g. it is an ID generated by an external source that captured the crash). -It MAY come from a source external to the instrumentation such that it can be used to look up additional -data from other sources as well as facilitate deduplication. -""" - -APP_INSTALLATION_ID: Final = "app.installation.id" -""" -A unique identifier representing the installation of an application on a specific device. -Note: Its value SHOULD persist across launches of the same application installation, including through application upgrades. -It SHOULD change if the application is uninstalled or if all applications of the vendor are uninstalled. -Additionally, users might be able to reset this value (e.g. by clearing application data). -If an app is installed multiple times on the same device (e.g. in different accounts on Android), each `app.installation.id` SHOULD have a different value. -If multiple OpenTelemetry SDKs are used within the same application, they SHOULD use the same value for `app.installation.id`. -Hardware IDs (e.g. serial number, IMEI, MAC address) MUST NOT be used as the `app.installation.id`. - -For iOS, this value SHOULD be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/identifierforvendor). - -For Android, examples of `app.installation.id` implementations include: - -- [Firebase Installation ID](https://firebase.google.com/docs/projects/manage-installations). -- A globally unique UUID which is persisted across sessions in your application. -- [App set ID](https://developer.android.com/identity/app-set-id). -- [`Settings.getString(Settings.Secure.ANDROID_ID)`](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID). - -More information about Android identifier best practices can be found in the [Android user data IDs guide](https://developer.android.com/training/articles/user-data-ids). -""" - -APP_JANK_FRAME_COUNT: Final = "app.jank.frame_count" -""" -A number of frame renders that experienced jank. -Note: Depending on platform limitations, the value provided MAY be approximation. -""" - -APP_JANK_PERIOD: Final = "app.jank.period" -""" -The time period, in seconds, for which this jank is being reported. -""" - -APP_JANK_THRESHOLD: Final = "app.jank.threshold" -""" -The minimum rendering threshold for this jank, in seconds. -""" - -APP_SCREEN_COORDINATE_X: Final = "app.screen.coordinate.x" -""" -The x (horizontal) coordinate of a screen coordinate, in screen pixels. -""" - -APP_SCREEN_COORDINATE_Y: Final = "app.screen.coordinate.y" -""" -The y (vertical) component of a screen coordinate, in screen pixels. -""" - -APP_SCREEN_ID: Final = "app.screen.id" -""" -An identifier that uniquely differentiates this screen from other screens in the same application. -Note: A screen represents only the part of the device display drawn by the app. It typically contains multiple widgets or UI components and is larger in scope than individual widgets. Multiple screens can coexist on the same display simultaneously (e.g., split view on tablets). -""" - -APP_SCREEN_NAME: Final = "app.screen.name" -""" -The name of an application screen. -Note: A screen represents only the part of the device display drawn by the app. It typically contains multiple widgets or UI components and is larger in scope than individual widgets. Multiple screens can coexist on the same display simultaneously (e.g., split view on tablets). -""" - -APP_WIDGET_ID: Final = "app.widget.id" -""" -An identifier that uniquely differentiates this widget from other widgets in the same application. -Note: A widget is an application component, typically an on-screen visual GUI element. -""" - -APP_WIDGET_NAME: Final = "app.widget.name" -""" -The name of an application widget. -Note: A widget is an application component, typically an on-screen visual GUI element. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py deleted file mode 100644 index ab3dcef5c92..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/artifact_attributes.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -ARTIFACT_ATTESTATION_FILENAME: Final = "artifact.attestation.filename" -""" -The provenance filename of the built attestation which directly relates to the build artifact filename. This filename SHOULD accompany the artifact at publish time. See the [SLSA Relationship](https://slsa.dev/spec/v1.0/distributing-provenance#relationship-between-artifacts-and-attestations) specification for more information. -""" - -ARTIFACT_ATTESTATION_HASH: Final = "artifact.attestation.hash" -""" -The full [hash value (see glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), of the built attestation. Some envelopes in the [software attestation space](https://github.com/in-toto/attestation/tree/main/spec) also refer to this as the **digest**. -""" - -ARTIFACT_ATTESTATION_ID: Final = "artifact.attestation.id" -""" -The ID of the build [software attestation](https://slsa.dev/attestation-model). -""" - -ARTIFACT_FILENAME: Final = "artifact.filename" -""" -The human readable filename of the artifact, typically generated during build and release processes. Often includes the package name and version in the filename. -Note: This filename can also act as the [Package Name](https://slsa.dev/spec/v1.0/terminology#package-model) -in cases where the package ecosystem maps accordingly. -Additionally, the artifact [can be published](https://slsa.dev/spec/v1.0/terminology#software-supply-chain) -for others, but that is not a guarantee. -""" - -ARTIFACT_HASH: Final = "artifact.hash" -""" -The full [hash value (see glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), often found in checksum.txt on a release of the artifact and used to verify package integrity. -Note: The specific algorithm used to create the cryptographic hash value is -not defined. In situations where an artifact has multiple -cryptographic hashes, it is up to the implementer to choose which -hash value to set here; this should be the most secure hash algorithm -that is suitable for the situation and consistent with the -corresponding attestation. The implementer can then provide the other -hash values through an additional set of attribute extensions as they -deem necessary. -""" - -ARTIFACT_PURL: Final = "artifact.purl" -""" -The [Package URL](https://github.com/package-url/purl-spec) of the [package artifact](https://slsa.dev/spec/v1.0/terminology#package-model) provides a standard way to identify and locate the packaged artifact. -""" - -ARTIFACT_VERSION: Final = "artifact.version" -""" -The version of the artifact. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py deleted file mode 100644 index e9113aa9c01..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/aws_attributes.py +++ /dev/null @@ -1,316 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -AWS_BEDROCK_GUARDRAIL_ID: Final = "aws.bedrock.guardrail.id" -""" -The unique identifier of the AWS Bedrock Guardrail. A [guardrail](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) helps safeguard and prevent unwanted behavior from model responses or user messages. -""" - -AWS_BEDROCK_KNOWLEDGE_BASE_ID: Final = "aws.bedrock.knowledge_base.id" -""" -The unique identifier of the AWS Bedrock Knowledge base. A [knowledge base](https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html) is a bank of information that can be queried by models to generate more relevant responses and augment prompts. -""" - -AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS: Final = "aws.dynamodb.attribute_definitions" -""" -The JSON-serialized value of each item in the `AttributeDefinitions` request field. -""" - -AWS_DYNAMODB_ATTRIBUTES_TO_GET: Final = "aws.dynamodb.attributes_to_get" -""" -The value of the `AttributesToGet` request parameter. -""" - -AWS_DYNAMODB_CONSISTENT_READ: Final = "aws.dynamodb.consistent_read" -""" -The value of the `ConsistentRead` request parameter. -""" - -AWS_DYNAMODB_CONSUMED_CAPACITY: Final = "aws.dynamodb.consumed_capacity" -""" -The JSON-serialized value of each item in the `ConsumedCapacity` response field. -""" - -AWS_DYNAMODB_COUNT: Final = "aws.dynamodb.count" -""" -The value of the `Count` response parameter. -""" - -AWS_DYNAMODB_EXCLUSIVE_START_TABLE: Final = "aws.dynamodb.exclusive_start_table" -""" -The value of the `ExclusiveStartTableName` request parameter. -""" - -AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES: Final = "aws.dynamodb.global_secondary_index_updates" -""" -The JSON-serialized value of each item in the `GlobalSecondaryIndexUpdates` request field. -""" - -AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES: Final = "aws.dynamodb.global_secondary_indexes" -""" -The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field. -""" - -AWS_DYNAMODB_INDEX_NAME: Final = "aws.dynamodb.index_name" -""" -The value of the `IndexName` request parameter. -""" - -AWS_DYNAMODB_ITEM_COLLECTION_METRICS: Final = "aws.dynamodb.item_collection_metrics" -""" -The JSON-serialized value of the `ItemCollectionMetrics` response field. -""" - -AWS_DYNAMODB_LIMIT: Final = "aws.dynamodb.limit" -""" -The value of the `Limit` request parameter. -""" - -AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES: Final = "aws.dynamodb.local_secondary_indexes" -""" -The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. -""" - -AWS_DYNAMODB_PROJECTION: Final = "aws.dynamodb.projection" -""" -The value of the `ProjectionExpression` request parameter. -""" - -AWS_DYNAMODB_PROVISIONED_READ_CAPACITY: Final = "aws.dynamodb.provisioned_read_capacity" -""" -The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. -""" - -AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY: Final = "aws.dynamodb.provisioned_write_capacity" -""" -The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. -""" - -AWS_DYNAMODB_SCAN_FORWARD: Final = "aws.dynamodb.scan_forward" -""" -The value of the `ScanIndexForward` request parameter. -""" - -AWS_DYNAMODB_SCANNED_COUNT: Final = "aws.dynamodb.scanned_count" -""" -The value of the `ScannedCount` response parameter. -""" - -AWS_DYNAMODB_SEGMENT: Final = "aws.dynamodb.segment" -""" -The value of the `Segment` request parameter. -""" - -AWS_DYNAMODB_SELECT: Final = "aws.dynamodb.select" -""" -The value of the `Select` request parameter. -""" - -AWS_DYNAMODB_TABLE_COUNT: Final = "aws.dynamodb.table_count" -""" -The number of items in the `TableNames` response parameter. -""" - -AWS_DYNAMODB_TABLE_NAMES: Final = "aws.dynamodb.table_names" -""" -The keys in the `RequestItems` object field. -""" - -AWS_DYNAMODB_TOTAL_SEGMENTS: Final = "aws.dynamodb.total_segments" -""" -The value of the `TotalSegments` request parameter. -""" - -AWS_ECS_CLUSTER_ARN: Final = "aws.ecs.cluster.arn" -""" -The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). -""" - -AWS_ECS_CONTAINER_ARN: Final = "aws.ecs.container.arn" -""" -The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). -""" - -AWS_ECS_LAUNCHTYPE: Final = "aws.ecs.launchtype" -""" -The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. -""" - -AWS_ECS_TASK_ARN: Final = "aws.ecs.task.arn" -""" -The ARN of a running [ECS task](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-account-settings.html#ecs-resource-ids). -""" - -AWS_ECS_TASK_FAMILY: Final = "aws.ecs.task.family" -""" -The family name of the [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html) used to create the ECS task. -""" - -AWS_ECS_TASK_ID: Final = "aws.ecs.task.id" -""" -The ID of a running ECS task. The ID MUST be extracted from `task.arn`. -""" - -AWS_ECS_TASK_REVISION: Final = "aws.ecs.task.revision" -""" -The revision for the task definition used to create the ECS task. -""" - -AWS_EKS_CLUSTER_ARN: Final = "aws.eks.cluster.arn" -""" -The ARN of an EKS cluster. -""" - -AWS_EXTENDED_REQUEST_ID: Final = "aws.extended_request_id" -""" -The AWS extended request ID as returned in the response header `x-amz-id-2`. -""" - -AWS_KINESIS_STREAM_NAME: Final = "aws.kinesis.stream_name" -""" -The name of the AWS Kinesis [stream](https://docs.aws.amazon.com/streams/latest/dev/introduction.html) the request refers to. Corresponds to the `--stream-name` parameter of the Kinesis [describe-stream](https://docs.aws.amazon.com/cli/latest/reference/kinesis/describe-stream.html) operation. -""" - -AWS_LAMBDA_INVOKED_ARN: Final = "aws.lambda.invoked_arn" -""" -The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). -Note: This may be different from `cloud.resource_id` if an alias is involved. -""" - -AWS_LAMBDA_RESOURCE_MAPPING_ID: Final = "aws.lambda.resource_mapping.id" -""" -The UUID of the [AWS Lambda EvenSource Mapping](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html). An event source is mapped to a lambda function. It's contents are read by Lambda and used to trigger a function. This isn't available in the lambda execution context or the lambda runtime environment. This is going to be populated by the AWS SDK for each language when that UUID is present. Some of these operations are Create/Delete/Get/List/Update EventSourceMapping. -""" - -AWS_LOG_GROUP_ARNS: Final = "aws.log.group.arns" -""" -The Amazon Resource Name(s) (ARN) of the AWS log group(s). -Note: See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). -""" - -AWS_LOG_GROUP_NAMES: Final = "aws.log.group.names" -""" -The name(s) of the AWS log group(s) an application is writing to. -Note: Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. -""" - -AWS_LOG_STREAM_ARNS: Final = "aws.log.stream.arns" -""" -The ARN(s) of the AWS log stream(s). -Note: See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. -""" - -AWS_LOG_STREAM_NAMES: Final = "aws.log.stream.names" -""" -The name(s) of the AWS log stream(s) an application is writing to. -""" - -AWS_REQUEST_ID: Final = "aws.request_id" -""" -The AWS request ID as returned in the response headers `x-amzn-requestid`, `x-amzn-request-id` or `x-amz-request-id`. -""" - -AWS_S3_BUCKET: Final = "aws.s3.bucket" -""" -The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. -Note: The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. -This applies to almost all S3 operations except `list-buckets`. -""" - -AWS_S3_COPY_SOURCE: Final = "aws.s3.copy_source" -""" -The source object (in the form `bucket`/`key`) for the copy operation. -Note: The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter -of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). -This applies in particular to the following operations: - -- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) -- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). -""" - -AWS_S3_DELETE: Final = "aws.s3.delete" -""" -The delete request container that specifies the objects to be deleted. -Note: The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. -The `delete` attribute corresponds to the `--delete` parameter of the -[delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). -""" - -AWS_S3_KEY: Final = "aws.s3.key" -""" -The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. -Note: The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. -This applies in particular to the following operations: - -- [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) -- [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) -- [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) -- [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) -- [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) -- [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) -- [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) -- [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) -- [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) -- [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) -- [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) -- [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) -- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). -""" - -AWS_S3_PART_NUMBER: Final = "aws.s3.part_number" -""" -The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. -Note: The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) -and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. -The `part_number` attribute corresponds to the `--part-number` parameter of the -[upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). -""" - -AWS_S3_UPLOAD_ID: Final = "aws.s3.upload_id" -""" -Upload ID that identifies the multipart upload. -Note: The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter -of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. -This applies in particular to the following operations: - -- [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) -- [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) -- [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) -- [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) -- [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). -""" - -AWS_SECRETSMANAGER_SECRET_ARN: Final = "aws.secretsmanager.secret.arn" -""" -The ARN of the Secret stored in the Secrets Manager. -""" - -AWS_SNS_TOPIC_ARN: Final = "aws.sns.topic.arn" -""" -The ARN of the AWS SNS Topic. An Amazon SNS [topic](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html) is a logical access point that acts as a communication channel. -""" - -AWS_SQS_QUEUE_URL: Final = "aws.sqs.queue.url" -""" -The URL of the AWS SQS Queue. It's a unique identifier for a queue in Amazon Simple Queue Service (SQS) and is used to access the queue and perform actions on it. -""" - -AWS_STEP_FUNCTIONS_ACTIVITY_ARN: Final = "aws.step_functions.activity.arn" -""" -The ARN of the AWS Step Functions Activity. -""" - -AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN: Final = "aws.step_functions.state_machine.arn" -""" -The ARN of the AWS Step Functions State Machine. -""" - - -class AwsEcsLaunchtypeValues(Enum): - EC2 = "ec2" - """Amazon EC2.""" - FARGATE = "fargate" - """Amazon Fargate.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py deleted file mode 100644 index 7595d9aa750..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/az_attributes.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -AZ_NAMESPACE: Final = "az.namespace" -""" -Deprecated: Replaced by `azure.resource_provider.namespace`. -""" - -AZ_SERVICE_REQUEST_ID: Final = "az.service_request_id" -""" -Deprecated: Replaced by `azure.service.request.id`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py deleted file mode 100644 index fb1a7f1ed50..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/azure_attributes.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -AZURE_CLIENT_ID: Final = "azure.client.id" -""" -The unique identifier of the client instance. -""" - -AZURE_COSMOSDB_CONNECTION_MODE: Final = "azure.cosmosdb.connection.mode" -""" -Cosmos client connection mode. -""" - -AZURE_COSMOSDB_CONSISTENCY_LEVEL: Final = "azure.cosmosdb.consistency.level" -""" -Account or request [consistency level](https://learn.microsoft.com/azure/cosmos-db/consistency-levels). -""" - -AZURE_COSMOSDB_OPERATION_CONTACTED_REGIONS: Final = "azure.cosmosdb.operation.contacted_regions" -""" -List of regions contacted during operation in the order that they were contacted. If there is more than one region listed, it indicates that the operation was performed on multiple regions i.e. cross-regional call. -Note: Region name matches the format of `displayName` in [Azure Location API](https://learn.microsoft.com/rest/api/resources/subscriptions/list-locations). -""" - -AZURE_COSMOSDB_OPERATION_REQUEST_CHARGE: Final = "azure.cosmosdb.operation.request_charge" -""" -The number of request units consumed by the operation. -""" - -AZURE_COSMOSDB_REQUEST_BODY_SIZE: Final = "azure.cosmosdb.request.body.size" -""" -Request payload size in bytes. -""" - -AZURE_COSMOSDB_RESPONSE_SUB_STATUS_CODE: Final = "azure.cosmosdb.response.sub_status_code" -""" -Cosmos DB sub status code. -""" - -AZURE_RESOURCE_GROUP_NAME: Final = "azure.resource_group.name" -""" -The name of the Azure [resource group](https://learn.microsoft.com/azure/azure-resource-manager/management/manage-resource-groups-portal) the resource belongs to. -""" - -AZURE_RESOURCE_PROVIDER_NAMESPACE: Final = "azure.resource_provider.namespace" -""" -[Azure Resource Provider Namespace](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers) as recognized by the client. -""" - -AZURE_SERVICE_REQUEST_ID: Final = "azure.service.request.id" -""" -The unique identifier of the service request. It's generated by the Azure service and returned with the response. -""" - - -class AzureCosmosdbConnectionModeValues(Enum): - GATEWAY = "gateway" - """Gateway (HTTP) connection.""" - DIRECT = "direct" - """Direct connection.""" - - -class AzureCosmosdbConsistencyLevelValues(Enum): - STRONG = "Strong" - """Strong.""" - BOUNDED_STALENESS = "BoundedStaleness" - """Bounded Staleness.""" - SESSION = "Session" - """Session.""" - EVENTUAL = "Eventual" - """Eventual.""" - CONSISTENT_PREFIX = "ConsistentPrefix" - """Consistent Prefix.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py deleted file mode 100644 index ff96d0ccfdd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/browser_attributes.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -BROWSER_BRANDS: Final = "browser.brands" -""" -Array of brand name and version separated by a space. -Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). -""" - -BROWSER_DOCUMENT_URL_FULL: Final = "browser.document.url.full" -""" -Absolute URL of the current browser document according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). -""" - -BROWSER_LANGUAGE: Final = "browser.language" -""" -Preferred language of the user using the browser. -Note: This value is intended to be taken from the Navigator API `navigator.language`. -""" - -BROWSER_MOBILE: Final = "browser.mobile" -""" -A boolean that is true if the browser is running on a mobile device. -Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset. -""" - -BROWSER_PLATFORM: Final = "browser.platform" -""" -The platform on which the browser is running. -Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. -The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. -""" - -BROWSER_WEB_VITAL_DELTA: Final = "browser.web_vital.delta" -""" -The delta between the current value and the last-reported value. See [delta](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#report-only-the-delta-of-changes). -""" - -BROWSER_WEB_VITAL_ID: Final = "browser.web_vital.id" -""" -A unique ID representing this particular metric instance. -""" - -BROWSER_WEB_VITAL_NAME: Final = "browser.web_vital.name" -""" -Name of the web vital. -""" - -BROWSER_WEB_VITAL_NAVIGATION_TYPE: Final = "browser.web_vital.navigation_type" -""" -The type of navigation, as reported by the [Navigation Timing API](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/type), with additional values reported by the web-vitals library. -""" - -BROWSER_WEB_VITAL_RATING: Final = "browser.web_vital.rating" -""" -The rating of the web vital value against the "good", "needs improvement", and "poor" thresholds defined for the metric. -""" - -BROWSER_WEB_VITAL_VALUE: Final = "browser.web_vital.value" -""" -Value of the web vital. -""" - - -class BrowserWebVitalNameValues(Enum): - CLS = "cls" - """Cumulative Layout Shift. See [cls](https://web.dev/articles/cls).""" - LCP = "lcp" - """Largest Contentful Paint. See [lcp](https://web.dev/articles/lcp).""" - FCP = "fcp" - """First Contentful Paint. See [fcp](https://web.dev/articles/fcp).""" - INP = "inp" - """Interaction to Next Paint. See [inp](https://web.dev/articles/inp).""" - TTFB = "ttfb" - """Time to First Byte. See [ttfb](https://web.dev/articles/ttfb).""" - FID = "fid" - """Deprecated: Replaced by Interaction to Next Paint (`inp`), which became a Core Web Vital in March 2024. See [inp](https://web.dev/articles/inp).""" - - -class BrowserWebVitalNavigationTypeValues(Enum): - NAVIGATE = "navigate" - """Navigation started by clicking a link, entering a URL, form submission, or a script operation.""" - RELOAD = "reload" - """Navigation through a reload operation or a `Location.reload()` call.""" - BACK_FORWARD = "back-forward" - """Navigation through the browser's history traversal (e.g. back/forward buttons).""" - BACK_FORWARD_CACHE = "back-forward-cache" - """Navigation restoring a page from the back/forward cache (bfcache).""" - PRERENDER = "prerender" - """Navigation to a page that was prerendered.""" - RESTORE = "restore" - """Navigation restoring a page that was previously discarded by the browser.""" - - -class BrowserWebVitalRatingValues(Enum): - GOOD = "good" - """The metric value is within the "good" threshold.""" - NEEDS_IMPROVEMENT = "needs-improvement" - """The metric value is within the "needs improvement" threshold.""" - POOR = "poor" - """The metric value is within the "poor" threshold.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py deleted file mode 100644 index 976a5f74fb8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cassandra_attributes.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -CASSANDRA_CONSISTENCY_LEVEL: Final = "cassandra.consistency.level" -""" -The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). -""" - -CASSANDRA_COORDINATOR_DC: Final = "cassandra.coordinator.dc" -""" -The data center of the coordinating node for a query. -""" - -CASSANDRA_COORDINATOR_ID: Final = "cassandra.coordinator.id" -""" -The ID of the coordinating node for a query. -""" - -CASSANDRA_PAGE_SIZE: Final = "cassandra.page.size" -""" -The fetch size used for paging, i.e. how many rows will be returned at once. -""" - -CASSANDRA_QUERY_IDEMPOTENT: Final = "cassandra.query.idempotent" -""" -Whether or not the query is idempotent. -""" - -CASSANDRA_SPECULATIVE_EXECUTION_COUNT: Final = "cassandra.speculative_execution.count" -""" -The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. -""" - - -class CassandraConsistencyLevelValues(Enum): - ALL = "all" - """All.""" - EACH_QUORUM = "each_quorum" - """Each Quorum.""" - QUORUM = "quorum" - """Quorum.""" - LOCAL_QUORUM = "local_quorum" - """Local Quorum.""" - ONE = "one" - """One.""" - TWO = "two" - """Two.""" - THREE = "three" - """Three.""" - LOCAL_ONE = "local_one" - """Local One.""" - ANY = "any" - """Any.""" - SERIAL = "serial" - """Serial.""" - LOCAL_SERIAL = "local_serial" - """Local Serial.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py deleted file mode 100644 index a68690814ef..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cicd_attributes.py +++ /dev/null @@ -1,152 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -CICD_PIPELINE_ACTION_NAME: Final = "cicd.pipeline.action.name" -""" -The kind of action a pipeline run is performing. -""" - -CICD_PIPELINE_NAME: Final = "cicd.pipeline.name" -""" -The human readable name of the pipeline within a CI/CD system. -""" - -CICD_PIPELINE_RESULT: Final = "cicd.pipeline.result" -""" -The result of a pipeline run. -""" - -CICD_PIPELINE_RUN_ID: Final = "cicd.pipeline.run.id" -""" -The unique identifier of a pipeline run within a CI/CD system. -""" - -CICD_PIPELINE_RUN_STATE: Final = "cicd.pipeline.run.state" -""" -The pipeline run goes through these states during its lifecycle. -""" - -CICD_PIPELINE_RUN_URL_FULL: Final = "cicd.pipeline.run.url.full" -""" -The [URL](https://wikipedia.org/wiki/URL) of the pipeline run, providing the complete address in order to locate and identify the pipeline run. -""" - -CICD_PIPELINE_TASK_NAME: Final = "cicd.pipeline.task.name" -""" -The human readable name of a task within a pipeline. Task here most closely aligns with a [computing process](https://wikipedia.org/wiki/Pipeline_(computing)) in a pipeline. Other terms for tasks include commands, steps, and procedures. -""" - -CICD_PIPELINE_TASK_RUN_ID: Final = "cicd.pipeline.task.run.id" -""" -The unique identifier of a task run within a pipeline. -Note: For a given pipeline run and task, the `cicd.pipeline.task.run.id` MUST be unique within that run. For the same task across different runs of the same pipeline, the `cicd.pipeline.task.run.id` MAY remain the same, enabling correlation of `cicd.pipeline.task.run.result` values across multiple pipeline runs. -""" - -CICD_PIPELINE_TASK_RUN_RESULT: Final = "cicd.pipeline.task.run.result" -""" -The result of a task run. -""" - -CICD_PIPELINE_TASK_RUN_URL_FULL: Final = "cicd.pipeline.task.run.url.full" -""" -The [URL](https://wikipedia.org/wiki/URL) of the pipeline task run, providing the complete address in order to locate and identify the pipeline task run. -""" - -CICD_PIPELINE_TASK_TYPE: Final = "cicd.pipeline.task.type" -""" -The type of the task within a pipeline. -""" - -CICD_SYSTEM_COMPONENT: Final = "cicd.system.component" -""" -The name of a component of the CI/CD system. -""" - -CICD_WORKER_ID: Final = "cicd.worker.id" -""" -The unique identifier of a worker within a CI/CD system. -""" - -CICD_WORKER_NAME: Final = "cicd.worker.name" -""" -The name of a worker within a CI/CD system. -""" - -CICD_WORKER_STATE: Final = "cicd.worker.state" -""" -The state of a CI/CD worker / agent. -""" - -CICD_WORKER_URL_FULL: Final = "cicd.worker.url.full" -""" -The [URL](https://wikipedia.org/wiki/URL) of the worker, providing the complete address in order to locate and identify the worker. -""" - - -class CicdPipelineActionNameValues(Enum): - BUILD = "BUILD" - """The pipeline run is executing a build.""" - RUN = "RUN" - """The pipeline run is executing.""" - SYNC = "SYNC" - """The pipeline run is executing a sync.""" - - -class CicdPipelineResultValues(Enum): - SUCCESS = "success" - """The pipeline run finished successfully.""" - FAILURE = "failure" - """The pipeline run did not finish successfully, eg. due to a compile error or a failing test. Such failures are usually detected by non-zero exit codes of the tools executed in the pipeline run.""" - ERROR = "error" - """The pipeline run failed due to an error in the CI/CD system, eg. due to the worker being killed.""" - TIMEOUT = "timeout" - """A timeout caused the pipeline run to be interrupted.""" - CANCELLATION = "cancellation" - """The pipeline run was cancelled, eg. by a user manually cancelling the pipeline run.""" - SKIP = "skip" - """The pipeline run was skipped, eg. due to a precondition not being met.""" - - -class CicdPipelineRunStateValues(Enum): - PENDING = "pending" - """The run pending state spans from the event triggering the pipeline run until the execution of the run starts (eg. time spent in a queue, provisioning agents, creating run resources).""" - EXECUTING = "executing" - """The executing state spans the execution of any run tasks (eg. build, test).""" - FINALIZING = "finalizing" - """The finalizing state spans from when the run has finished executing (eg. cleanup of run resources).""" - - -class CicdPipelineTaskRunResultValues(Enum): - SUCCESS = "success" - """The task run finished successfully.""" - FAILURE = "failure" - """The task run did not finish successfully, eg. due to a compile error or a failing test. Such failures are usually detected by non-zero exit codes of the tools executed in the task run.""" - ERROR = "error" - """The task run failed due to an error in the CI/CD system, eg. due to the worker being killed.""" - TIMEOUT = "timeout" - """A timeout caused the task run to be interrupted.""" - CANCELLATION = "cancellation" - """The task run was cancelled, eg. by a user manually cancelling the task run.""" - SKIP = "skip" - """The task run was skipped, eg. due to a precondition not being met.""" - - -class CicdPipelineTaskTypeValues(Enum): - BUILD = "build" - """build.""" - TEST = "test" - """test.""" - DEPLOY = "deploy" - """deploy.""" - - -class CicdWorkerStateValues(Enum): - AVAILABLE = "available" - """The worker is not performing work for the CI/CD system. It is available to the CI/CD system to perform work on (online / idle).""" - BUSY = "busy" - """The worker is performing work for the CI/CD system.""" - OFFLINE = "offline" - """The worker is not available to the CI/CD system (disconnected / down).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py deleted file mode 100644 index b68dea7203f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/client_attributes.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -CLIENT_ADDRESS: Final = "client.address" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.client_attributes.CLIENT_ADDRESS`. -""" - -CLIENT_PORT: Final = "client.port" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.client_attributes.CLIENT_PORT`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py deleted file mode 100644 index 87570ea4d2b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloud_attributes.py +++ /dev/null @@ -1,156 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -CLOUD_ACCOUNT_ID: Final = "cloud.account.id" -""" -The cloud account ID the resource is assigned to. -Note: For Azure, this is the subscription ID. -""" - -CLOUD_AVAILABILITY_ZONE: Final = "cloud.availability_zone" -""" -Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. -Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud. -""" - -CLOUD_PLATFORM: Final = "cloud.platform" -""" -The cloud platform in use. -Note: The prefix of the service SHOULD match the one specified in `cloud.provider`. -""" - -CLOUD_PROVIDER: Final = "cloud.provider" -""" -Name of the cloud provider. -""" - -CLOUD_REGION: Final = "cloud.region" -""" -The geographical region within a cloud provider. When associated with a resource, this attribute specifies the region where the resource operates. When calling services or APIs deployed on a cloud, this attribute identifies the region where the called destination is deployed. -Note: Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). -""" - -CLOUD_RESOURCE_ID: Final = "cloud.resource_id" -""" -Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://google.aip.dev/122#full-resource-names) on GCP). -Note: On some cloud providers, it may not be possible to determine the full ID at startup, -so it may be necessary to set `cloud.resource_id` as a span attribute instead. - -The exact value to use for `cloud.resource_id` depends on the cloud provider. -The following well-known definitions MUST be used if you set this attribute and they apply: - -- **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). - Take care not to use the "invoked ARN" directly but replace any - [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) - with the resolved function version, as the same runtime instance may be invocable with - multiple different aliases. -- **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) -- **Azure:** The [Fully Qualified Resource ID](https://learn.microsoft.com/rest/api/resources/resources/get-by-id) of the invoked function, - *not* the function app, having the form - `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. - This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share - a TracerProvider. -""" - - -class CloudPlatformValues(Enum): - AKAMAI_CLOUD_COMPUTE = "akamai_cloud.compute" - """Akamai Cloud Compute.""" - ALIBABA_CLOUD_ECS = "alibaba_cloud_ecs" - """Alibaba Cloud Elastic Compute Service.""" - ALIBABA_CLOUD_FC = "alibaba_cloud_fc" - """Alibaba Cloud Function Compute.""" - ALIBABA_CLOUD_OPENSHIFT = "alibaba_cloud_openshift" - """Red Hat OpenShift on Alibaba Cloud.""" - AWS_EC2 = "aws_ec2" - """AWS Elastic Compute Cloud.""" - AWS_ECS = "aws_ecs" - """AWS Elastic Container Service.""" - AWS_EKS = "aws_eks" - """AWS Elastic Kubernetes Service.""" - AWS_LAMBDA = "aws_lambda" - """AWS Lambda.""" - AWS_ELASTIC_BEANSTALK = "aws_elastic_beanstalk" - """AWS Elastic Beanstalk.""" - AWS_APP_RUNNER = "aws_app_runner" - """AWS App Runner.""" - AWS_OPENSHIFT = "aws_openshift" - """Red Hat OpenShift on AWS (ROSA).""" - AZURE_VM = "azure.vm" - """Azure Virtual Machines.""" - AZURE_CONTAINER_APPS = "azure.container_apps" - """Azure Container Apps.""" - AZURE_CONTAINER_INSTANCES = "azure.container_instances" - """Azure Container Instances.""" - AZURE_AKS = "azure.aks" - """Azure Kubernetes Service.""" - AZURE_FUNCTIONS = "azure.functions" - """Azure Functions.""" - AZURE_APP_SERVICE = "azure.app_service" - """Azure App Service.""" - AZURE_OPENSHIFT = "azure.openshift" - """Azure Red Hat OpenShift.""" - GCP_AGENT_ENGINE = "gcp.agent_engine" - """Google Vertex AI Agent Engine.""" - GCP_BARE_METAL_SOLUTION = "gcp_bare_metal_solution" - """Google Bare Metal Solution (BMS).""" - GCP_COMPUTE_ENGINE = "gcp_compute_engine" - """Google Cloud Compute Engine (GCE).""" - GCP_CLOUD_RUN = "gcp_cloud_run" - """Google Cloud Run.""" - GCP_KUBERNETES_ENGINE = "gcp_kubernetes_engine" - """Google Cloud Kubernetes Engine (GKE).""" - GCP_CLOUD_FUNCTIONS = "gcp_cloud_functions" - """Google Cloud Functions (GCF).""" - GCP_APP_ENGINE = "gcp_app_engine" - """Google Cloud App Engine (GAE).""" - GCP_OPENSHIFT = "gcp_openshift" - """Red Hat OpenShift on Google Cloud.""" - HETZNER_CLOUD_SERVER = "hetzner.cloud_server" - """Server on Hetzner Cloud.""" - IBM_CLOUD_OPENSHIFT = "ibm_cloud_openshift" - """Red Hat OpenShift on IBM Cloud.""" - ORACLE_CLOUD_COMPUTE = "oracle_cloud_compute" - """Compute on Oracle Cloud Infrastructure (OCI).""" - ORACLE_CLOUD_OKE = "oracle_cloud_oke" - """Kubernetes Engine (OKE) on Oracle Cloud Infrastructure (OCI).""" - SCALEWAY_CLOUD_COMPUTE = "scaleway_cloud_compute" - """Compute on Scaleway Cloud.""" - TENCENT_CLOUD_CVM = "tencent_cloud_cvm" - """Tencent Cloud Cloud Virtual Machine (CVM).""" - TENCENT_CLOUD_EKS = "tencent_cloud_eks" - """Tencent Cloud Elastic Kubernetes Service (EKS).""" - TENCENT_CLOUD_SCF = "tencent_cloud_scf" - """Tencent Cloud Serverless Cloud Function (SCF).""" - VULTR_CLOUD_COMPUTE = "vultr.cloud_compute" - """Vultr Cloud Compute.""" - - -class CloudProviderValues(Enum): - AKAMAI_CLOUD = "akamai_cloud" - """Akamai Cloud.""" - ALIBABA_CLOUD = "alibaba_cloud" - """Alibaba Cloud.""" - AWS = "aws" - """Amazon Web Services.""" - AZURE = "azure" - """Microsoft Azure.""" - GCP = "gcp" - """Google Cloud Platform.""" - HEROKU = "heroku" - """Heroku Platform as a Service.""" - HETZNER = "hetzner" - """Hetzner.""" - IBM_CLOUD = "ibm_cloud" - """IBM Cloud.""" - ORACLE_CLOUD = "oracle_cloud" - """Oracle Cloud Infrastructure (OCI).""" - SCALEWAY_CLOUD = "scaleway_cloud" - """Scaleway Cloud.""" - TENCENT_CLOUD = "tencent_cloud" - """Tencent Cloud.""" - VULTR = "vultr" - """Vultr.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py deleted file mode 100644 index fe3226a594d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudevents_attributes.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -CLOUDEVENTS_EVENT_ID: Final = "cloudevents.event_id" -""" -The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. -""" - -CLOUDEVENTS_EVENT_SOURCE: Final = "cloudevents.event_source" -""" -The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. -""" - -CLOUDEVENTS_EVENT_SPEC_VERSION: Final = "cloudevents.event_spec_version" -""" -The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. -""" - -CLOUDEVENTS_EVENT_SUBJECT: Final = "cloudevents.event_subject" -""" -The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). -""" - -CLOUDEVENTS_EVENT_TYPE: Final = "cloudevents.event_type" -""" -The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py deleted file mode 100644 index 9ed23c0406d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cloudfoundry_attributes.py +++ /dev/null @@ -1,107 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -CLOUDFOUNDRY_APP_ID: Final = "cloudfoundry.app.id" -""" -The guid of the application. -Note: Application instrumentation should use the value from environment -variable `VCAP_APPLICATION.application_id`. This is the same value as -reported by `cf app --guid`. -""" - -CLOUDFOUNDRY_APP_INSTANCE_ID: Final = "cloudfoundry.app.instance.id" -""" -The index of the application instance. 0 when just one instance is active. -Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). -It is used for logs and metrics emitted by CloudFoundry. It is -supposed to contain the application instance index for applications -deployed on the runtime. - -Application instrumentation should use the value from environment -variable `CF_INSTANCE_INDEX`. -""" - -CLOUDFOUNDRY_APP_NAME: Final = "cloudfoundry.app.name" -""" -The name of the application. -Note: Application instrumentation should use the value from environment -variable `VCAP_APPLICATION.application_name`. This is the same value -as reported by `cf apps`. -""" - -CLOUDFOUNDRY_ORG_ID: Final = "cloudfoundry.org.id" -""" -The guid of the CloudFoundry org the application is running in. -Note: Application instrumentation should use the value from environment -variable `VCAP_APPLICATION.org_id`. This is the same value as -reported by `cf org --guid`. -""" - -CLOUDFOUNDRY_ORG_NAME: Final = "cloudfoundry.org.name" -""" -The name of the CloudFoundry organization the app is running in. -Note: Application instrumentation should use the value from environment -variable `VCAP_APPLICATION.org_name`. This is the same value as -reported by `cf orgs`. -""" - -CLOUDFOUNDRY_PROCESS_ID: Final = "cloudfoundry.process.id" -""" -The UID identifying the process. -Note: Application instrumentation should use the value from environment -variable `VCAP_APPLICATION.process_id`. It is supposed to be equal to -`VCAP_APPLICATION.app_id` for applications deployed to the runtime. -For system components, this could be the actual PID. -""" - -CLOUDFOUNDRY_PROCESS_TYPE: Final = "cloudfoundry.process.type" -""" -The type of process. -Note: CloudFoundry applications can consist of multiple jobs. Usually the -main process will be of type `web`. There can be additional background -tasks or side-cars with different process types. -""" - -CLOUDFOUNDRY_SPACE_ID: Final = "cloudfoundry.space.id" -""" -The guid of the CloudFoundry space the application is running in. -Note: Application instrumentation should use the value from environment -variable `VCAP_APPLICATION.space_id`. This is the same value as -reported by `cf space --guid`. -""" - -CLOUDFOUNDRY_SPACE_NAME: Final = "cloudfoundry.space.name" -""" -The name of the CloudFoundry space the application is running in. -Note: Application instrumentation should use the value from environment -variable `VCAP_APPLICATION.space_name`. This is the same value as -reported by `cf spaces`. -""" - -CLOUDFOUNDRY_SYSTEM_ID: Final = "cloudfoundry.system.id" -""" -A guid or another name describing the event source. -Note: CloudFoundry defines the `source_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). -It is used for logs and metrics emitted by CloudFoundry. It is -supposed to contain the component name, e.g. "gorouter", for -CloudFoundry components. - -When system components are instrumented, values from the -[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) -should be used. The `system.id` should be set to -`spec.deployment/spec.name`. -""" - -CLOUDFOUNDRY_SYSTEM_INSTANCE_ID: Final = "cloudfoundry.system.instance.id" -""" -A guid describing the concrete instance of the event source. -Note: CloudFoundry defines the `instance_id` in the [Loggregator v2 envelope](https://github.com/cloudfoundry/loggregator-api#v2-envelope). -It is used for logs and metrics emitted by CloudFoundry. It is -supposed to contain the vm ID for CloudFoundry components. - -When system components are instrumented, values from the -[Bosh spec](https://bosh.io/docs/jobs/#properties-spec) -should be used. The `system.instance.id` should be set to `spec.id`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py deleted file mode 100644 index 130aebc2c4d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/code_attributes.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -CODE_COLUMN: Final = "code.column" -""" -Deprecated: Replaced by `code.column.number`. -""" - -CODE_COLUMN_NUMBER: Final = "code.column.number" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_COLUMN_NUMBER`. -""" - -CODE_FILE_PATH: Final = "code.file.path" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_FILE_PATH`. -""" - -CODE_FILEPATH: Final = "code.filepath" -""" -Deprecated: Replaced by `code.file.path`. -""" - -CODE_FUNCTION: Final = "code.function" -""" -Deprecated: Value should be included in `code.function.name` which is expected to be a fully-qualified name. -""" - -CODE_FUNCTION_NAME: Final = "code.function.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_FUNCTION_NAME`. -""" - -CODE_LINE_NUMBER: Final = "code.line.number" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_LINE_NUMBER`. -""" - -CODE_LINENO: Final = "code.lineno" -""" -Deprecated: Replaced by `code.line.number`. -""" - -CODE_NAMESPACE: Final = "code.namespace" -""" -Deprecated: Value should be included in `code.function.name` which is expected to be a fully-qualified name. -""" - -CODE_STACKTRACE: Final = "code.stacktrace" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.code_attributes.CODE_STACKTRACE`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py deleted file mode 100644 index ca6c1f06e8a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/container_attributes.py +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -CONTAINER_COMMAND: Final = "container.command" -""" -The command used to run the container (i.e. the command name). -Note: If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. -""" - -CONTAINER_COMMAND_ARGS: Final = "container.command_args" -""" -All the command arguments (including the command/executable itself) run by the container. -""" - -CONTAINER_COMMAND_LINE: Final = "container.command_line" -""" -The full command run by the container as a single string representing the full command. -""" - -CONTAINER_CPU_STATE: Final = "container.cpu.state" -""" -Deprecated: Replaced by `cpu.mode`. -""" - -CONTAINER_CSI_PLUGIN_NAME: Final = "container.csi.plugin.name" -""" -The name of the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin used by the volume. -Note: This can sometimes be referred to as a "driver" in CSI implementations. This should represent the `name` field of the GetPluginInfo RPC. -""" - -CONTAINER_CSI_VOLUME_ID: Final = "container.csi.volume.id" -""" -The unique volume ID returned by the CSI ([Container Storage Interface](https://github.com/container-storage-interface/spec)) plugin. -Note: This can sometimes be referred to as a "volume handle" in CSI implementations. This should represent the `Volume.volume_id` field in CSI spec. -""" - -CONTAINER_ID: Final = "container.id" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_ID`. -""" - -CONTAINER_IMAGE_ID: Final = "container.image.id" -""" -Runtime specific image identifier. Usually a hash algorithm followed by a UUID. -Note: Docker defines a sha256 of the image ID; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Container/operation/ContainerInspect) endpoint. -K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. -The ID is assigned by the container runtime and can vary in different environments. Consider using `oci.manifest.digest` if it is important to identify the same image in different environments/runtimes. -""" - -CONTAINER_IMAGE_NAME: Final = "container.image.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_IMAGE_NAME`. -""" - -CONTAINER_IMAGE_REPO_DIGESTS: Final = "container.image.repo_digests" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_IMAGE_REPO_DIGESTS`. -""" - -CONTAINER_IMAGE_TAGS: Final = "container.image.tags" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.container_attributes.CONTAINER_IMAGE_TAGS`. -""" - -CONTAINER_LABEL_TEMPLATE: Final = "container.label" -""" -Container labels, `` being the label name, the value being the label value. -Note: For example, a Docker container label `app` with value `nginx` SHOULD be recorded as the `container.label.app` attribute with value `"nginx"`. -""" - -CONTAINER_LABELS_TEMPLATE: Final = "container.labels" -""" -Deprecated: Replaced by `container.label`. -""" - -CONTAINER_NAME: Final = "container.name" -""" -Container name used by container runtime. -""" - -CONTAINER_RUNTIME: Final = "container.runtime" -""" -Deprecated: Replaced by `container.runtime.name`. -""" - -CONTAINER_RUNTIME_DESCRIPTION: Final = "container.runtime.description" -""" -A description about the runtime which could include, for example details about the CRI/API version being used or other customizations. -""" - -CONTAINER_RUNTIME_NAME: Final = "container.runtime.name" -""" -The container runtime managing this container. -""" - -CONTAINER_RUNTIME_VERSION: Final = "container.runtime.version" -""" -The version of the runtime of this process, as returned by the runtime without modification. -""" - - -@deprecated("The attribute container.cpu.state is deprecated - Replaced by `cpu.mode`") -class ContainerCpuStateValues(Enum): - USER = "user" - """When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows).""" - SYSTEM = "system" - """When CPU is used by the system (host OS).""" - KERNEL = "kernel" - """When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py deleted file mode 100644 index a2982d549c8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpu_attributes.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -CPU_LOGICAL_NUMBER: Final = "cpu.logical_number" -""" -The logical CPU number [0..n-1]. -""" - -CPU_MODE: Final = "cpu.mode" -""" -The mode of the CPU. -""" - - -class CpuModeValues(Enum): - USER = "user" - """User.""" - SYSTEM = "system" - """System.""" - NICE = "nice" - """Nice.""" - IDLE = "idle" - """Idle.""" - IOWAIT = "iowait" - """IO Wait.""" - INTERRUPT = "interrupt" - """Interrupt.""" - STEAL = "steal" - """Steal.""" - KERNEL = "kernel" - """Deprecated: Replaced by `system`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py deleted file mode 100644 index 90ef20560af..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/cpython_attributes.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -CPYTHON_GC_GENERATION: Final = "cpython.gc.generation" -""" -Value of the garbage collector collection generation. -""" - - -class CPythonGCGenerationValues(Enum): - GENERATION_0 = 0 - """Generation 0.""" - GENERATION_1 = 1 - """Generation 1.""" - GENERATION_2 = 2 - """Generation 2.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py deleted file mode 100644 index a8ced43e028..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/db_attributes.py +++ /dev/null @@ -1,574 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -DB_CASSANDRA_CONSISTENCY_LEVEL: Final = "db.cassandra.consistency_level" -""" -Deprecated: Replaced by `cassandra.consistency.level`. -""" - -DB_CASSANDRA_COORDINATOR_DC: Final = "db.cassandra.coordinator.dc" -""" -Deprecated: Replaced by `cassandra.coordinator.dc`. -""" - -DB_CASSANDRA_COORDINATOR_ID: Final = "db.cassandra.coordinator.id" -""" -Deprecated: Replaced by `cassandra.coordinator.id`. -""" - -DB_CASSANDRA_IDEMPOTENCE: Final = "db.cassandra.idempotence" -""" -Deprecated: Replaced by `cassandra.query.idempotent`. -""" - -DB_CASSANDRA_PAGE_SIZE: Final = "db.cassandra.page_size" -""" -Deprecated: Replaced by `cassandra.page.size`. -""" - -DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT: Final = "db.cassandra.speculative_execution_count" -""" -Deprecated: Replaced by `cassandra.speculative_execution.count`. -""" - -DB_CASSANDRA_TABLE: Final = "db.cassandra.table" -""" -Deprecated: Replaced by `db.collection.name`. -""" - -DB_CLIENT_CONNECTION_POOL_NAME: Final = "db.client.connection.pool.name" -""" -The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation SHOULD use a combination of parameters that would make the name unique, for example, combining attributes `server.address`, `server.port`, and `db.namespace`, formatted as `server.address:server.port/db.namespace`. Instrumentations that generate connection pool name following different patterns SHOULD document it. -""" - -DB_CLIENT_CONNECTION_STATE: Final = "db.client.connection.state" -""" -The state of a connection in the pool. -""" - -DB_CLIENT_CONNECTIONS_POOL_NAME: Final = "db.client.connections.pool.name" -""" -Deprecated: Replaced by `db.client.connection.pool.name`. -""" - -DB_CLIENT_CONNECTIONS_STATE: Final = "db.client.connections.state" -""" -Deprecated: Replaced by `db.client.connection.state`. -""" - -DB_COLLECTION_NAME: Final = "db.collection.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_COLLECTION_NAME`. -""" - -DB_CONNECTION_STRING: Final = "db.connection_string" -""" -Deprecated: Replaced by `server.address` and `server.port`. -""" - -DB_COSMOSDB_CLIENT_ID: Final = "db.cosmosdb.client_id" -""" -Deprecated: Replaced by `azure.client.id`. -""" - -DB_COSMOSDB_CONNECTION_MODE: Final = "db.cosmosdb.connection_mode" -""" -Deprecated: Replaced by `azure.cosmosdb.connection.mode`. -""" - -DB_COSMOSDB_CONSISTENCY_LEVEL: Final = "db.cosmosdb.consistency_level" -""" -Deprecated: Replaced by `azure.cosmosdb.consistency.level`. -""" - -DB_COSMOSDB_CONTAINER: Final = "db.cosmosdb.container" -""" -Deprecated: Replaced by `db.collection.name`. -""" - -DB_COSMOSDB_OPERATION_TYPE: Final = "db.cosmosdb.operation_type" -""" -Deprecated: Removed, no replacement at this time. -""" - -DB_COSMOSDB_REGIONS_CONTACTED: Final = "db.cosmosdb.regions_contacted" -""" -Deprecated: Replaced by `azure.cosmosdb.operation.contacted_regions`. -""" - -DB_COSMOSDB_REQUEST_CHARGE: Final = "db.cosmosdb.request_charge" -""" -Deprecated: Replaced by `azure.cosmosdb.operation.request_charge`. -""" - -DB_COSMOSDB_REQUEST_CONTENT_LENGTH: Final = "db.cosmosdb.request_content_length" -""" -Deprecated: Replaced by `azure.cosmosdb.request.body.size`. -""" - -DB_COSMOSDB_STATUS_CODE: Final = "db.cosmosdb.status_code" -""" -Deprecated: Use `db.response.status_code` instead. -""" - -DB_COSMOSDB_SUB_STATUS_CODE: Final = "db.cosmosdb.sub_status_code" -""" -Deprecated: Replaced by `azure.cosmosdb.response.sub_status_code`. -""" - -DB_ELASTICSEARCH_CLUSTER_NAME: Final = "db.elasticsearch.cluster.name" -""" -Deprecated: Replaced by `db.namespace`. -""" - -DB_ELASTICSEARCH_NODE_NAME: Final = "db.elasticsearch.node.name" -""" -Deprecated: Replaced by `elasticsearch.node.name`. -""" - -DB_ELASTICSEARCH_PATH_PARTS_TEMPLATE: Final = "db.elasticsearch.path_parts" -""" -Deprecated: Replaced by `db.operation.parameter`. -""" - -DB_INSTANCE_ID: Final = "db.instance.id" -""" -Deprecated: Removed, no general replacement at this time. For Elasticsearch, use `db.elasticsearch.node.name` instead. -""" - -DB_JDBC_DRIVER_CLASSNAME: Final = "db.jdbc.driver_classname" -""" -Deprecated: Removed, no replacement at this time. -""" - -DB_MONGODB_COLLECTION: Final = "db.mongodb.collection" -""" -Deprecated: Replaced by `db.collection.name`. -""" - -DB_MSSQL_INSTANCE_NAME: Final = "db.mssql.instance_name" -""" -Deprecated: Removed, no replacement at this time. -""" - -DB_NAME: Final = "db.name" -""" -Deprecated: Replaced by `db.namespace`. -""" - -DB_NAMESPACE: Final = "db.namespace" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_NAMESPACE`. -""" - -DB_OPERATION: Final = "db.operation" -""" -Deprecated: Replaced by `db.operation.name`. -""" - -DB_OPERATION_BATCH_SIZE: Final = "db.operation.batch.size" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_OPERATION_BATCH_SIZE`. -""" - -DB_OPERATION_NAME: Final = "db.operation.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_OPERATION_NAME`. -""" - -DB_OPERATION_PARAMETER_TEMPLATE: Final = "db.operation.parameter" -""" -A database operation parameter, with `` being the parameter name, and the attribute value being a string representation of the parameter value. -Note: For example, a client-side maximum number of rows to read from the database -MAY be recorded as the `db.operation.parameter.max_rows` attribute. - -`db.query.text` parameters SHOULD be captured using `db.query.parameter.` -instead of `db.operation.parameter.`. -""" - -DB_QUERY_PARAMETER_TEMPLATE: Final = "db.query.parameter" -""" -A database query parameter, with `` being the parameter name, and the attribute value being a string representation of the parameter value. -Note: If a query parameter has no name and instead is referenced only by index, -then `` SHOULD be the 0-based index. - -`db.query.parameter.` SHOULD match -up with the parameterized placeholders present in `db.query.text`. - -It is RECOMMENDED to capture the value as provided by the application -without attempting to do any case normalization or sanitization. - -Instrumentations SHOULD NOT capture `db.query.parameter.` by default -since values may contain PII or sensitive details. -Application operators are expected to enable specific keys depending -on their privacy and security considerations. - -`db.query.parameter.` SHOULD NOT be captured on batch operations. - -Examples: - -- For a query `SELECT * FROM users where username = %s` with the parameter `"jdoe"`, - the attribute `db.query.parameter.0` SHOULD be set to `"jdoe"`. - -- For a query `"SELECT * FROM users WHERE username = %(userName)s;` with parameter - `userName = "jdoe"`, the attribute `db.query.parameter.userName` SHOULD be set to `"jdoe"`. -""" - -DB_QUERY_SUMMARY: Final = "db.query.summary" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_QUERY_SUMMARY`. -""" - -DB_QUERY_TEXT: Final = "db.query.text" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_QUERY_TEXT`. -""" - -DB_REDIS_DATABASE_INDEX: Final = "db.redis.database_index" -""" -Deprecated: Replaced by `db.namespace` (string). -""" - -DB_RESPONSE_RETURNED_ROWS: Final = "db.response.returned_rows" -""" -Number of rows returned by the operation. -""" - -DB_RESPONSE_STATUS_CODE: Final = "db.response.status_code" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_RESPONSE_STATUS_CODE`. -""" - -DB_SQL_TABLE: Final = "db.sql.table" -""" -Deprecated: Replaced by `db.collection.name`, but only if not extracting the value from `db.query.text`. -""" - -DB_STATEMENT: Final = "db.statement" -""" -Deprecated: Replaced by `db.query.text`. -""" - -DB_STORED_PROCEDURE_NAME: Final = "db.stored_procedure.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_STORED_PROCEDURE_NAME`. -""" - -DB_SYSTEM: Final = "db.system" -""" -Deprecated: Replaced by `db.system.name`. -""" - -DB_SYSTEM_NAME: Final = "db.system.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DB_SYSTEM_NAME`. -""" - -DB_USER: Final = "db.user" -""" -Deprecated: Removed, no replacement at this time. -""" - - -@deprecated("The attribute db.cassandra.consistency_level is deprecated - Replaced by `cassandra.consistency.level`") -class DbCassandraConsistencyLevelValues(Enum): - ALL = "all" - """all.""" - EACH_QUORUM = "each_quorum" - """each_quorum.""" - QUORUM = "quorum" - """quorum.""" - LOCAL_QUORUM = "local_quorum" - """local_quorum.""" - ONE = "one" - """one.""" - TWO = "two" - """two.""" - THREE = "three" - """three.""" - LOCAL_ONE = "local_one" - """local_one.""" - ANY = "any" - """any.""" - SERIAL = "serial" - """serial.""" - LOCAL_SERIAL = "local_serial" - """local_serial.""" - - -class DbClientConnectionStateValues(Enum): - IDLE = "idle" - """idle.""" - USED = "used" - """used.""" - - -@deprecated("The attribute db.client.connections.state is deprecated - Replaced by `db.client.connection.state`") -class DbClientConnectionsStateValues(Enum): - IDLE = "idle" - """idle.""" - USED = "used" - """used.""" - - -@deprecated("The attribute db.cosmosdb.connection_mode is deprecated - Replaced by `azure.cosmosdb.connection.mode`") -class DbCosmosdbConnectionModeValues(Enum): - GATEWAY = "gateway" - """Gateway (HTTP) connection.""" - DIRECT = "direct" - """Direct connection.""" - - -@deprecated( - "The attribute db.cosmosdb.consistency_level is deprecated - Replaced by `azure.cosmosdb.consistency.level`" -) -class DbCosmosdbConsistencyLevelValues(Enum): - STRONG = "Strong" - """strong.""" - BOUNDED_STALENESS = "BoundedStaleness" - """bounded_staleness.""" - SESSION = "Session" - """session.""" - EVENTUAL = "Eventual" - """eventual.""" - CONSISTENT_PREFIX = "ConsistentPrefix" - """consistent_prefix.""" - - -@deprecated("The attribute db.cosmosdb.operation_type is deprecated - Removed, no replacement at this time") -class DbCosmosdbOperationTypeValues(Enum): - BATCH = "batch" - """batch.""" - CREATE = "create" - """create.""" - DELETE = "delete" - """delete.""" - EXECUTE = "execute" - """execute.""" - EXECUTE_JAVASCRIPT = "execute_javascript" - """execute_javascript.""" - INVALID = "invalid" - """invalid.""" - HEAD = "head" - """head.""" - HEAD_FEED = "head_feed" - """head_feed.""" - PATCH = "patch" - """patch.""" - QUERY = "query" - """query.""" - QUERY_PLAN = "query_plan" - """query_plan.""" - READ = "read" - """read.""" - READ_FEED = "read_feed" - """read_feed.""" - REPLACE = "replace" - """replace.""" - UPSERT = "upsert" - """upsert.""" - - -@deprecated("The attribute db.system is deprecated - Replaced by `db.system.name`") -class DbSystemValues(Enum): - OTHER_SQL = "other_sql" - """Some other SQL database. Fallback only. See notes.""" - ADABAS = "adabas" - """Adabas (Adaptable Database System).""" - CACHE = "cache" - """Deprecated: Replaced by `intersystems_cache`.""" - INTERSYSTEMS_CACHE = "intersystems_cache" - """InterSystems Caché.""" - CASSANDRA = "cassandra" - """Apache Cassandra.""" - CLICKHOUSE = "clickhouse" - """ClickHouse.""" - CLOUDSCAPE = "cloudscape" - """Deprecated: Replaced by `other_sql`.""" - COCKROACHDB = "cockroachdb" - """CockroachDB.""" - COLDFUSION = "coldfusion" - """Deprecated: Obsoleted.""" - COSMOSDB = "cosmosdb" - """Microsoft Azure Cosmos DB.""" - COUCHBASE = "couchbase" - """Couchbase.""" - COUCHDB = "couchdb" - """CouchDB.""" - DB2 = "db2" - """IBM Db2.""" - DERBY = "derby" - """Apache Derby.""" - DYNAMODB = "dynamodb" - """Amazon DynamoDB.""" - EDB = "edb" - """EnterpriseDB.""" - ELASTICSEARCH = "elasticsearch" - """Elasticsearch.""" - FILEMAKER = "filemaker" - """FileMaker.""" - FIREBIRD = "firebird" - """Firebird.""" - FIRSTSQL = "firstsql" - """Deprecated: Replaced by `other_sql`.""" - GEODE = "geode" - """Apache Geode.""" - H2 = "h2" - """H2.""" - HANADB = "hanadb" - """SAP HANA.""" - HBASE = "hbase" - """Apache HBase.""" - HIVE = "hive" - """Apache Hive.""" - HSQLDB = "hsqldb" - """HyperSQL DataBase.""" - INFLUXDB = "influxdb" - """InfluxDB.""" - INFORMIX = "informix" - """Informix.""" - INGRES = "ingres" - """Ingres.""" - INSTANTDB = "instantdb" - """InstantDB.""" - INTERBASE = "interbase" - """InterBase.""" - MARIADB = "mariadb" - """MariaDB.""" - MAXDB = "maxdb" - """SAP MaxDB.""" - MEMCACHED = "memcached" - """Memcached.""" - MONGODB = "mongodb" - """MongoDB.""" - MSSQL = "mssql" - """Microsoft SQL Server.""" - MSSQLCOMPACT = "mssqlcompact" - """Deprecated: Replaced by `other_sql`.""" - MYSQL = "mysql" - """MySQL.""" - NEO4J = "neo4j" - """Neo4j.""" - NETEZZA = "netezza" - """Netezza.""" - OPENSEARCH = "opensearch" - """OpenSearch.""" - ORACLE = "oracle" - """Oracle Database.""" - PERVASIVE = "pervasive" - """Pervasive PSQL.""" - POINTBASE = "pointbase" - """PointBase.""" - POSTGRESQL = "postgresql" - """PostgreSQL.""" - PROGRESS = "progress" - """Progress Database.""" - REDIS = "redis" - """Redis.""" - REDSHIFT = "redshift" - """Amazon Redshift.""" - SPANNER = "spanner" - """Cloud Spanner.""" - SQLITE = "sqlite" - """SQLite.""" - SYBASE = "sybase" - """Sybase.""" - TERADATA = "teradata" - """Teradata.""" - TRINO = "trino" - """Trino.""" - VERTICA = "vertica" - """Vertica.""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues`." -) -class DbSystemNameValues(Enum): - OTHER_SQL = "other_sql" - """Some other SQL database. Fallback only.""" - SOFTWAREAG_ADABAS = "softwareag.adabas" - """[Adabas (Adaptable Database System)](https://documentation.softwareag.com/?pf=adabas).""" - ACTIAN_INGRES = "actian.ingres" - """[Actian Ingres](https://www.actian.com/databases/ingres/).""" - AWS_DYNAMODB = "aws.dynamodb" - """[Amazon DynamoDB](https://aws.amazon.com/pm/dynamodb/).""" - AWS_REDSHIFT = "aws.redshift" - """[Amazon Redshift](https://aws.amazon.com/redshift/).""" - AZURE_COSMOSDB = "azure.cosmosdb" - """[Azure Cosmos DB](https://learn.microsoft.com/azure/cosmos-db).""" - INTERSYSTEMS_CACHE = "intersystems.cache" - """[InterSystems Caché](https://www.intersystems.com/products/cache/).""" - CASSANDRA = "cassandra" - """[Apache Cassandra](https://cassandra.apache.org/).""" - CLICKHOUSE = "clickhouse" - """[ClickHouse](https://clickhouse.com/).""" - COCKROACHDB = "cockroachdb" - """[CockroachDB](https://www.cockroachlabs.com/).""" - COUCHBASE = "couchbase" - """[Couchbase](https://www.couchbase.com/).""" - COUCHDB = "couchdb" - """[Apache CouchDB](https://couchdb.apache.org/).""" - DERBY = "derby" - """[Apache Derby](https://db.apache.org/derby/).""" - ELASTICSEARCH = "elasticsearch" - """[Elasticsearch](https://www.elastic.co/elasticsearch).""" - FIREBIRDSQL = "firebirdsql" - """[Firebird](https://www.firebirdsql.org/).""" - GCP_SPANNER = "gcp.spanner" - """[Google Cloud Spanner](https://cloud.google.com/spanner).""" - GEODE = "geode" - """[Apache Geode](https://geode.apache.org/).""" - H2DATABASE = "h2database" - """[H2 Database](https://h2database.com/).""" - HBASE = "hbase" - """[Apache HBase](https://hbase.apache.org/).""" - HIVE = "hive" - """[Apache Hive](https://hive.apache.org/).""" - HSQLDB = "hsqldb" - """[HyperSQL Database](https://hsqldb.org/).""" - IBM_DB2 = "ibm.db2" - """[IBM Db2](https://www.ibm.com/db2).""" - IBM_INFORMIX = "ibm.informix" - """[IBM Informix](https://www.ibm.com/products/informix).""" - IBM_NETEZZA = "ibm.netezza" - """[IBM Netezza](https://www.ibm.com/products/netezza).""" - INFLUXDB = "influxdb" - """[InfluxDB](https://www.influxdata.com/).""" - INSTANTDB = "instantdb" - """[Instant](https://www.instantdb.com/).""" - MARIADB = "mariadb" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.MARIADB`.""" - MEMCACHED = "memcached" - """[Memcached](https://memcached.org/).""" - MONGODB = "mongodb" - """[MongoDB](https://www.mongodb.com/).""" - MICROSOFT_SQL_SERVER = "microsoft.sql_server" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.MICROSOFT_SQL_SERVER`.""" - MYSQL = "mysql" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.MYSQL`.""" - NEO4J = "neo4j" - """[Neo4j](https://neo4j.com/).""" - OPENSEARCH = "opensearch" - """[OpenSearch](https://opensearch.org/).""" - ORACLE_DB = "oracle.db" - """[Oracle Database](https://www.oracle.com/database/).""" - POSTGRESQL = "postgresql" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.db_attributes.DbSystemNameValues.POSTGRESQL`.""" - REDIS = "redis" - """[Redis](https://redis.io/).""" - SAP_HANA = "sap.hana" - """[SAP HANA](https://www.sap.com/products/technology-platform/hana/what-is-sap-hana.html).""" - SAP_MAXDB = "sap.maxdb" - """[SAP MaxDB](https://maxdb.sap.com/).""" - SQLITE = "sqlite" - """[SQLite](https://www.sqlite.org/).""" - TERADATA = "teradata" - """[Teradata](https://www.teradata.com/).""" - TRINO = "trino" - """[Trino](https://trino.io/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py deleted file mode 100644 index 976ff3f2e09..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/deployment_attributes.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -DEPLOYMENT_ENVIRONMENT: Final = "deployment.environment" -""" -Deprecated: Replaced by `deployment.environment.name`. -""" - -DEPLOYMENT_ENVIRONMENT_NAME: Final = "deployment.environment.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DEPLOYMENT_ENVIRONMENT_NAME`. -""" - -DEPLOYMENT_ID: Final = "deployment.id" -""" -The ID of the deployment. -""" - -DEPLOYMENT_NAME: Final = "deployment.name" -""" -The name of the deployment. -""" - -DEPLOYMENT_STATUS: Final = "deployment.status" -""" -The status of the deployment. -""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues`." -) -class DeploymentEnvironmentNameValues(Enum): - PRODUCTION = "production" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.PRODUCTION`.""" - STAGING = "staging" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.STAGING`.""" - TEST = "test" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.TEST`.""" - DEVELOPMENT = "development" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.deployment_attributes.DeploymentEnvironmentNameValues.DEVELOPMENT`.""" - - -class DeploymentStatusValues(Enum): - FAILED = "failed" - """failed.""" - SUCCEEDED = "succeeded" - """succeeded.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py deleted file mode 100644 index 40f7de949f0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/destination_attributes.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -DESTINATION_ADDRESS: Final = "destination.address" -""" -Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. -Note: When observed from the source side, and when communicating through an intermediary, `destination.address` SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. -""" - -DESTINATION_PORT: Final = "destination.port" -""" -Destination port number. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py deleted file mode 100644 index 87dcaaa0b2d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/device_attributes.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -DEVICE_ID: Final = "device.id" -""" -A unique identifier representing the device. -Note: Its value SHOULD be identical for all apps on a device and it SHOULD NOT change if an app is uninstalled and re-installed. -However, it might be resettable by the user for all apps on a device. -Hardware IDs (e.g. vendor-specific serial number, IMEI or MAC address) MAY be used as values. - -More information about Android identifier best practices can be found in the [Android user data IDs guide](https://developer.android.com/training/articles/user-data-ids). - -> [!WARNING] -> -> This attribute may contain sensitive (PII) information. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, -> ensure you do your own due diligence. -> -> Due to these reasons, this identifier is not recommended for consumer applications and will likely result in rejection from both Google Play and App Store. -> However, it may be appropriate for specific enterprise scenarios, such as kiosk devices or enterprise-managed devices, with appropriate compliance clearance. -> Any instrumentation providing this identifier MUST implement it as an opt-in feature. -> -> See [`app.installation.id`](/docs/registry/attributes/app.md#app-installation-id) for a more privacy-preserving alternative. -""" - -DEVICE_MANUFACTURER: Final = "device.manufacturer" -""" -The name of the device manufacturer. -Note: The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. -""" - -DEVICE_MODEL_IDENTIFIER: Final = "device.model.identifier" -""" -The model identifier for the device. -Note: It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. -""" - -DEVICE_MODEL_NAME: Final = "device.model.name" -""" -The marketing name for the device model. -Note: It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py deleted file mode 100644 index 1e08f412073..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/disk_attributes.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -DISK_IO_DIRECTION: Final = "disk.io.direction" -""" -The disk IO operation direction. -""" - - -class DiskIoDirectionValues(Enum): - READ = "read" - """read.""" - WRITE = "write" - """write.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py deleted file mode 100644 index 83def12b52f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/dns_attributes.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -DNS_ANSWERS: Final = "dns.answers" -""" -The list of IPv4 or IPv6 addresses resolved during DNS lookup. -""" - -DNS_QUESTION_NAME: Final = "dns.question.name" -""" -The name being queried. -Note: The name represents the queried domain name as it appears in the DNS query without any additional normalization. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py deleted file mode 100644 index 86748754ada..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/elasticsearch_attributes.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -ELASTICSEARCH_NODE_NAME: Final = "elasticsearch.node.name" -""" -Represents the human-readable identifier of the node/instance to which a request was routed. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py deleted file mode 100644 index 121a2c0ce26..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/enduser_attributes.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -ENDUSER_ID: Final = "enduser.id" -""" -Unique identifier of an end user in the system. It maybe a username, email address, or other identifier. -Note: Unique identifier of an end user in the system. - -> [!Warning] -> This field contains sensitive (PII) information. -""" - -ENDUSER_PSEUDO_ID: Final = "enduser.pseudo.id" -""" -Pseudonymous identifier of an end user. This identifier should be a random value that is not directly linked or associated with the end user's actual identity. -Note: Pseudonymous identifier of an end user. - -> [!Warning] -> This field contains sensitive (linkable PII) information. -""" - -ENDUSER_ROLE: Final = "enduser.role" -""" -Deprecated: Use `user.roles` instead. -""" - -ENDUSER_SCOPE: Final = "enduser.scope" -""" -Deprecated: Removed, no replacement at this time. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py deleted file mode 100644 index 6b655daf951..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/error_attributes.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -ERROR_MESSAGE: Final = "error.message" -""" -Deprecated: Use domain-specific error message attribute. For example, use `feature_flag.error.message` for feature flag errors. -""" - -ERROR_TYPE: Final = "error.type" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ERROR_TYPE`. -""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ErrorTypeValues`." -) -class ErrorTypeValues(Enum): - OTHER = "_OTHER" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.error_attributes.ErrorTypeValues.OTHER`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py deleted file mode 100644 index 05f481bbb3e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/event_attributes.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -EVENT_NAME: Final = "event.name" -""" -Deprecated: The value of this attribute MUST now be set as the value of the EventName field on the LogRecord to indicate that the LogRecord represents an Event. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py deleted file mode 100644 index efec9363f22..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/exception_attributes.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -EXCEPTION_ESCAPED: Final = "exception.escaped" -""" -Deprecated: It's no longer recommended to record exceptions that are handled and do not escape the scope of a span. -""" - -EXCEPTION_MESSAGE: Final = "exception.message" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_MESSAGE`. -""" - -EXCEPTION_STACKTRACE: Final = "exception.stacktrace" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_STACKTRACE`. -""" - -EXCEPTION_TYPE: Final = "exception.type" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.exception_attributes.EXCEPTION_TYPE`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py deleted file mode 100644 index 21a0b6f91ea..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/faas_attributes.py +++ /dev/null @@ -1,150 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -FAAS_COLDSTART: Final = "faas.coldstart" -""" -A boolean that is true if the serverless function is executed for the first time (aka cold-start). -""" - -FAAS_CRON: Final = "faas.cron" -""" -A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). -""" - -FAAS_DOCUMENT_COLLECTION: Final = "faas.document.collection" -""" -The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. -""" - -FAAS_DOCUMENT_NAME: Final = "faas.document.name" -""" -The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. -""" - -FAAS_DOCUMENT_OPERATION: Final = "faas.document.operation" -""" -Describes the type of the operation that was performed on the data. -""" - -FAAS_DOCUMENT_TIME: Final = "faas.document.time" -""" -A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). -""" - -FAAS_INSTANCE: Final = "faas.instance" -""" -The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. -Note: - **AWS Lambda:** Use the (full) log stream name. -""" - -FAAS_INVOCATION_ID: Final = "faas.invocation_id" -""" -The invocation ID of the current function invocation. -""" - -FAAS_INVOKED_NAME: Final = "faas.invoked_name" -""" -The name of the invoked function. -Note: SHOULD be equal to the `faas.name` resource attribute of the invoked function. -""" - -FAAS_INVOKED_PROVIDER: Final = "faas.invoked_provider" -""" -The cloud provider of the invoked function. -Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked function. -""" - -FAAS_INVOKED_REGION: Final = "faas.invoked_region" -""" -The cloud region of the invoked function. -Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked function. -""" - -FAAS_MAX_MEMORY: Final = "faas.max_memory" -""" -The amount of memory available to the serverless function converted to Bytes. -Note: It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). -""" - -FAAS_NAME: Final = "faas.name" -""" -The name of the single function that this runtime instance executes. -Note: This is the name of the function as configured/deployed on the FaaS -platform and is usually different from the name of the callback -function (which may be stored in the -[`code.namespace`/`code.function.name`](/docs/general/attributes.md#source-code-attributes) -span attributes). - -For some cloud providers, the above definition is ambiguous. The following -definition of function name MUST be used for this attribute -(and consequently the span name) for the listed cloud providers/products: - -- **Azure:** The full name `/`, i.e., function app name - followed by a forward slash followed by the function name (this form - can also be seen in the resource JSON for the function). - This means that a span attribute MUST be used, as an Azure function - app can host multiple functions that would usually share - a TracerProvider (see also the `cloud.resource_id` attribute). -""" - -FAAS_TIME: Final = "faas.time" -""" -A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). -""" - -FAAS_TRIGGER: Final = "faas.trigger" -""" -Type of the trigger which caused this function invocation. -""" - -FAAS_VERSION: Final = "faas.version" -""" -The immutable version of the function being executed. -Note: Depending on the cloud provider and platform, use: - -- **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) - (an integer represented as a decimal string). -- **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) - (i.e., the function name plus the revision suffix). -- **Google Cloud Functions:** The value of the - [`K_REVISION` environment variable](https://cloud.google.com/run/docs/container-contract#services-env-vars). -- **Azure Functions:** Not applicable. Do not set this attribute. -""" - - -class FaasDocumentOperationValues(Enum): - INSERT = "insert" - """When a new object is created.""" - EDIT = "edit" - """When an object is modified.""" - DELETE = "delete" - """When an object is deleted.""" - - -class FaasInvokedProviderValues(Enum): - ALIBABA_CLOUD = "alibaba_cloud" - """Alibaba Cloud.""" - AWS = "aws" - """Amazon Web Services.""" - AZURE = "azure" - """Microsoft Azure.""" - GCP = "gcp" - """Google Cloud Platform.""" - TENCENT_CLOUD = "tencent_cloud" - """Tencent Cloud.""" - - -class FaasTriggerValues(Enum): - DATASOURCE = "datasource" - """A response to some data source operation such as a database or filesystem read/write.""" - HTTP = "http" - """To provide an answer to an inbound HTTP request.""" - PUBSUB = "pubsub" - """A function is set to be executed when messages are sent to a messaging system.""" - TIMER = "timer" - """A function is scheduled to be executed regularly.""" - OTHER = "other" - """If none of the others apply.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py deleted file mode 100644 index 97673108395..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/feature_flag_attributes.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -FEATURE_FLAG_CONTEXT_ID: Final = "feature_flag.context.id" -""" -The unique identifier for the flag evaluation context. For example, the targeting key. -""" - -FEATURE_FLAG_ERROR_MESSAGE: Final = "feature_flag.error.message" -""" -A message providing more detail about an error that occurred during feature flag evaluation in human-readable form. -""" - -FEATURE_FLAG_EVALUATION_ERROR_MESSAGE: Final = "feature_flag.evaluation.error.message" -""" -Deprecated: Replaced by `feature_flag.error.message`. -""" - -FEATURE_FLAG_EVALUATION_REASON: Final = "feature_flag.evaluation.reason" -""" -Deprecated: Replaced by `feature_flag.result.reason`. -""" - -FEATURE_FLAG_KEY: Final = "feature_flag.key" -""" -The lookup key of the feature flag. -""" - -FEATURE_FLAG_PROVIDER_NAME: Final = "feature_flag.provider.name" -""" -Identifies the feature flag provider. -""" - -FEATURE_FLAG_RESULT_REASON: Final = "feature_flag.result.reason" -""" -The reason code which shows how a feature flag value was determined. -""" - -FEATURE_FLAG_RESULT_VALUE: Final = "feature_flag.result.value" -""" -The evaluated value of the feature flag. -Note: With some feature flag providers, feature flag results can be quite large or contain private or sensitive details. -Because of this, `feature_flag.result.variant` is often the preferred attribute if it is available. - -It may be desirable to redact or otherwise limit the size and scope of `feature_flag.result.value` if possible. -Because the evaluated flag value is unstructured and may be any type, it is left to the instrumentation author to determine how best to achieve this. -""" - -FEATURE_FLAG_RESULT_VARIANT: Final = "feature_flag.result.variant" -""" -A semantic identifier for an evaluated flag value. -Note: A semantic identifier, commonly referred to as a variant, provides a means -for referring to a value without including the value itself. This can -provide additional context for understanding the meaning behind a value. -For example, the variant `red` maybe be used for the value `#c05543`. -""" - -FEATURE_FLAG_SET_ID: Final = "feature_flag.set.id" -""" -The identifier of the [flag set](https://openfeature.dev/specification/glossary/#flag-set) to which the feature flag belongs. -""" - -FEATURE_FLAG_VARIANT: Final = "feature_flag.variant" -""" -Deprecated: Replaced by `feature_flag.result.variant`. -""" - -FEATURE_FLAG_VERSION: Final = "feature_flag.version" -""" -The version of the ruleset used during the evaluation. This may be any stable value which uniquely identifies the ruleset. -""" - - -@deprecated("The attribute feature_flag.evaluation.reason is deprecated - Replaced by `feature_flag.result.reason`") -class FeatureFlagEvaluationReasonValues(Enum): - STATIC = "static" - """The resolved value is static (no dynamic evaluation).""" - DEFAULT = "default" - """The resolved value fell back to a pre-configured value (no dynamic evaluation occurred or dynamic evaluation yielded no result).""" - TARGETING_MATCH = "targeting_match" - """The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.""" - SPLIT = "split" - """The resolved value was the result of pseudorandom assignment.""" - CACHED = "cached" - """The resolved value was retrieved from cache.""" - DISABLED = "disabled" - """The resolved value was the result of the flag being disabled in the management system.""" - UNKNOWN = "unknown" - """The reason for the resolved value could not be determined.""" - STALE = "stale" - """The resolved value is non-authoritative or possibly out of date.""" - ERROR = "error" - """The resolved value was the result of an error.""" - - -class FeatureFlagResultReasonValues(Enum): - STATIC = "static" - """The resolved value is static (no dynamic evaluation).""" - DEFAULT = "default" - """The resolved value fell back to a pre-configured value (no dynamic evaluation occurred or dynamic evaluation yielded no result).""" - TARGETING_MATCH = "targeting_match" - """The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.""" - SPLIT = "split" - """The resolved value was the result of pseudorandom assignment.""" - CACHED = "cached" - """The resolved value was retrieved from cache.""" - DISABLED = "disabled" - """The resolved value was the result of the flag being disabled in the management system.""" - UNKNOWN = "unknown" - """The reason for the resolved value could not be determined.""" - STALE = "stale" - """The resolved value is non-authoritative or possibly out of date.""" - ERROR = "error" - """The resolved value was the result of an error.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py deleted file mode 100644 index f84f0ea3616..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/file_attributes.py +++ /dev/null @@ -1,125 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -FILE_ACCESSED: Final = "file.accessed" -""" -Time when the file was last accessed, in ISO 8601 format. -Note: This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. -""" - -FILE_ATTRIBUTES: Final = "file.attributes" -""" -Array of file attributes. -Note: Attributes names depend on the OS or file system. Here’s a non-exhaustive list of values expected for this attribute: `archive`, `compressed`, `directory`, `encrypted`, `execute`, `hidden`, `immutable`, `journaled`, `read`, `readonly`, `symbolic link`, `system`, `temporary`, `write`. -""" - -FILE_CHANGED: Final = "file.changed" -""" -Time when the file attributes or metadata was last changed, in ISO 8601 format. -Note: `file.changed` captures the time when any of the file's properties or attributes (including the content) are changed, while `file.modified` captures the timestamp when the file content is modified. -""" - -FILE_CREATED: Final = "file.created" -""" -Time when the file was created, in ISO 8601 format. -Note: This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. -""" - -FILE_DIRECTORY: Final = "file.directory" -""" -Directory where the file is located. It should include the drive letter, when appropriate. -""" - -FILE_EXTENSION: Final = "file.extension" -""" -File extension, excluding the leading dot. -Note: When the filename has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). -""" - -FILE_FORK_NAME: Final = "file.fork_name" -""" -Name of the fork. A fork is additional data associated with a filesystem object. -Note: On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at least one fork for the data portion, and additional forks may exist. -On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the internet. An ADS is typically of the form: C:\\path\\to\\filename.extension:some_fork_name, and some_fork_name is the value that should populate `fork_name`. `filename.extension` should populate `file.name`, and `extension` should populate `file.extension`. The full path, `file.path`, will include the fork name. -""" - -FILE_GROUP_ID: Final = "file.group.id" -""" -Primary Group ID (GID) of the file. -""" - -FILE_GROUP_NAME: Final = "file.group.name" -""" -Primary group name of the file. -""" - -FILE_INODE: Final = "file.inode" -""" -Inode representing the file in the filesystem. -""" - -FILE_LOCK_MECHANISM: Final = "file.lock.mechanism" -""" -The lock mechanism such as noted by [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html). -""" - -FILE_LOCK_MODE: Final = "file.lock.mode" -""" -Mode of lock or operation such as documented by [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html). -""" - -FILE_LOCK_TYPE: Final = "file.lock.type" -""" -The lock type as represented by i.e. [POSIX](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html)'s l_type. -""" - -FILE_MODE: Final = "file.mode" -""" -Mode of the file in octal representation. -""" - -FILE_MODIFIED: Final = "file.modified" -""" -Time when the file content was last modified, in ISO 8601 format. -""" - -FILE_NAME: Final = "file.name" -""" -Name of the file including the extension, without the directory. -""" - -FILE_OWNER_ID: Final = "file.owner.id" -""" -The user ID (UID) or security identifier (SID) of the file owner. -""" - -FILE_OWNER_NAME: Final = "file.owner.name" -""" -Username of the file owner. -""" - -FILE_PATH: Final = "file.path" -""" -Full path to the file, including the filename. It should include the drive letter, when appropriate. -""" - -FILE_SIZE: Final = "file.size" -""" -File size in bytes. -""" - -FILE_SYMBOLIC_LINK_TARGET_PATH: Final = "file.symbolic_link.target_path" -""" -Path to the target of a symbolic link. -Note: This attribute is only applicable to symbolic links. -""" - - -class FileLockTypeValues(Enum): - READ = "read" - """read.""" - WRITE = "write" - """write.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py deleted file mode 100644 index b472e4cea5b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gcp_attributes.py +++ /dev/null @@ -1,234 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -GCP_APPHUB_APPLICATION_CONTAINER: Final = "gcp.apphub.application.container" -""" -The container within GCP where the AppHub application is defined. -""" - -GCP_APPHUB_APPLICATION_ID: Final = "gcp.apphub.application.id" -""" -The name of the application as configured in AppHub. -""" - -GCP_APPHUB_APPLICATION_LOCATION: Final = "gcp.apphub.application.location" -""" -The GCP zone or region where the application is defined. -""" - -GCP_APPHUB_SERVICE_CRITICALITY_TYPE: Final = "gcp.apphub.service.criticality_type" -""" -Criticality of a service indicates its importance to the business. -Note: [See AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). -""" - -GCP_APPHUB_SERVICE_ENVIRONMENT_TYPE: Final = "gcp.apphub.service.environment_type" -""" -Environment of a service is the stage of a software lifecycle. -Note: [See AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). -""" - -GCP_APPHUB_SERVICE_ID: Final = "gcp.apphub.service.id" -""" -The name of the service as configured in AppHub. -""" - -GCP_APPHUB_WORKLOAD_CRITICALITY_TYPE: Final = "gcp.apphub.workload.criticality_type" -""" -Criticality of a workload indicates its importance to the business. -Note: [See AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). -""" - -GCP_APPHUB_WORKLOAD_ENVIRONMENT_TYPE: Final = "gcp.apphub.workload.environment_type" -""" -Environment of a workload is the stage of a software lifecycle. -Note: [See AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). -""" - -GCP_APPHUB_WORKLOAD_ID: Final = "gcp.apphub.workload.id" -""" -The name of the workload as configured in AppHub. -""" - -GCP_APPHUB_DESTINATION_APPLICATION_CONTAINER: Final = "gcp.apphub_destination.application.container" -""" -The container within GCP where the AppHub destination application is defined. -""" - -GCP_APPHUB_DESTINATION_APPLICATION_ID: Final = "gcp.apphub_destination.application.id" -""" -The name of the destination application as configured in AppHub. -""" - -GCP_APPHUB_DESTINATION_APPLICATION_LOCATION: Final = "gcp.apphub_destination.application.location" -""" -The GCP zone or region where the destination application is defined. -""" - -GCP_APPHUB_DESTINATION_SERVICE_CRITICALITY_TYPE: Final = "gcp.apphub_destination.service.criticality_type" -""" -Criticality of a destination workload indicates its importance to the business as specified in [AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). -""" - -GCP_APPHUB_DESTINATION_SERVICE_ENVIRONMENT_TYPE: Final = "gcp.apphub_destination.service.environment_type" -""" -Software lifecycle stage of a destination service as defined [AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). -""" - -GCP_APPHUB_DESTINATION_SERVICE_ID: Final = "gcp.apphub_destination.service.id" -""" -The name of the destination service as configured in AppHub. -""" - -GCP_APPHUB_DESTINATION_WORKLOAD_CRITICALITY_TYPE: Final = "gcp.apphub_destination.workload.criticality_type" -""" -Criticality of a destination workload indicates its importance to the business as specified in [AppHub type enum](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type). -""" - -GCP_APPHUB_DESTINATION_WORKLOAD_ENVIRONMENT_TYPE: Final = "gcp.apphub_destination.workload.environment_type" -""" -Environment of a destination workload is the stage of a software lifecycle as provided in the [AppHub environment type](https://cloud.google.com/app-hub/docs/reference/rest/v1/Attributes#type_1). -""" - -GCP_APPHUB_DESTINATION_WORKLOAD_ID: Final = "gcp.apphub_destination.workload.id" -""" -The name of the destination workload as configured in AppHub. -""" - -GCP_CLIENT_SERVICE: Final = "gcp.client.service" -""" -Identifies the Google Cloud service for which the official client library is intended. -Note: Intended to be a stable identifier for Google Cloud client libraries that is uniform across implementation languages. The value should be derived from the canonical service domain for the service; for example, 'foo.googleapis.com' should result in a value of 'foo'. -""" - -GCP_CLOUD_RUN_JOB_EXECUTION: Final = "gcp.cloud_run.job.execution" -""" -The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. -""" - -GCP_CLOUD_RUN_JOB_TASK_INDEX: Final = "gcp.cloud_run.job.task_index" -""" -The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. -""" - -GCP_GCE_INSTANCE_HOSTNAME: Final = "gcp.gce.instance.hostname" -""" -The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). -""" - -GCP_GCE_INSTANCE_LABELS_TEMPLATE: Final = "gcp.gce.instance.labels" -""" -GCE instance labels, `` being the label name and the value being the label value. -Note: For example, a GCE instance label `team` with value `observability` SHOULD be recorded as the `gcp.gce.instance.labels.team` attribute with value `"observability"`. The `` MUST be the exact GCE instance label key. -""" - -GCP_GCE_INSTANCE_NAME: Final = "gcp.gce.instance.name" -""" -The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). -""" - -GCP_GCE_INSTANCE_GROUP_MANAGER_NAME: Final = "gcp.gce.instance_group_manager.name" -""" -The name of the Instance Group Manager (IGM) that manages this VM, if any. -""" - -GCP_GCE_INSTANCE_GROUP_MANAGER_REGION: Final = "gcp.gce.instance_group_manager.region" -""" -The region of a **regional** Instance Group Manager (e.g., `us-central1`). Set this **only** when the IGM is regional. -""" - -GCP_GCE_INSTANCE_GROUP_MANAGER_ZONE: Final = "gcp.gce.instance_group_manager.zone" -""" -The zone of a **zonal** Instance Group Manager (e.g., `us-central1-a`). Set this **only** when the IGM is zonal. -""" - - -class GcpApphubServiceCriticalityTypeValues(Enum): - MISSION_CRITICAL = "MISSION_CRITICAL" - """Mission critical service.""" - HIGH = "HIGH" - """High impact.""" - MEDIUM = "MEDIUM" - """Medium impact.""" - LOW = "LOW" - """Low impact.""" - - -class GcpApphubServiceEnvironmentTypeValues(Enum): - PRODUCTION = "PRODUCTION" - """Production environment.""" - STAGING = "STAGING" - """Staging environment.""" - TEST = "TEST" - """Test environment.""" - DEVELOPMENT = "DEVELOPMENT" - """Development environment.""" - - -class GcpApphubWorkloadCriticalityTypeValues(Enum): - MISSION_CRITICAL = "MISSION_CRITICAL" - """Mission critical service.""" - HIGH = "HIGH" - """High impact.""" - MEDIUM = "MEDIUM" - """Medium impact.""" - LOW = "LOW" - """Low impact.""" - - -class GcpApphubWorkloadEnvironmentTypeValues(Enum): - PRODUCTION = "PRODUCTION" - """Production environment.""" - STAGING = "STAGING" - """Staging environment.""" - TEST = "TEST" - """Test environment.""" - DEVELOPMENT = "DEVELOPMENT" - """Development environment.""" - - -class GcpApphubDestinationServiceCriticalityTypeValues(Enum): - MISSION_CRITICAL = "MISSION_CRITICAL" - """Mission critical service.""" - HIGH = "HIGH" - """High impact.""" - MEDIUM = "MEDIUM" - """Medium impact.""" - LOW = "LOW" - """Low impact.""" - - -class GcpApphubDestinationServiceEnvironmentTypeValues(Enum): - PRODUCTION = "PRODUCTION" - """Production environment.""" - STAGING = "STAGING" - """Staging environment.""" - TEST = "TEST" - """Test environment.""" - DEVELOPMENT = "DEVELOPMENT" - """Development environment.""" - - -class GcpApphubDestinationWorkloadCriticalityTypeValues(Enum): - MISSION_CRITICAL = "MISSION_CRITICAL" - """Mission critical service.""" - HIGH = "HIGH" - """High impact.""" - MEDIUM = "MEDIUM" - """Medium impact.""" - LOW = "LOW" - """Low impact.""" - - -class GcpApphubDestinationWorkloadEnvironmentTypeValues(Enum): - PRODUCTION = "PRODUCTION" - """Production environment.""" - STAGING = "STAGING" - """Staging environment.""" - TEST = "TEST" - """Test environment.""" - DEVELOPMENT = "DEVELOPMENT" - """Development environment.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py deleted file mode 100644 index 6bab43dd254..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/gen_ai_attributes.py +++ /dev/null @@ -1,459 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -GEN_AI_AGENT_DESCRIPTION: Final = "gen_ai.agent.description" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_AGENT_ID: Final = "gen_ai.agent.id" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_AGENT_NAME: Final = "gen_ai.agent.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_AGENT_VERSION: Final = "gen_ai.agent.version" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_COMPLETION: Final = "gen_ai.completion" -""" -Deprecated: Removed, no replacement at this time. -""" - -GEN_AI_CONVERSATION_ID: Final = "gen_ai.conversation.id" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_DATA_SOURCE_ID: Final = "gen_ai.data_source.id" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_EMBEDDINGS_DIMENSION_COUNT: Final = "gen_ai.embeddings.dimension.count" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_EVALUATION_EXPLANATION: Final = "gen_ai.evaluation.explanation" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_EVALUATION_NAME: Final = "gen_ai.evaluation.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_EVALUATION_SCORE_LABEL: Final = "gen_ai.evaluation.score.label" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_EVALUATION_SCORE_VALUE: Final = "gen_ai.evaluation.score.value" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_INPUT_MESSAGES: Final = "gen_ai.input.messages" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OPENAI_REQUEST_RESPONSE_FORMAT: Final = "gen_ai.openai.request.response_format" -""" -Deprecated: Replaced by `gen_ai.output.type`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OPENAI_REQUEST_SEED: Final = "gen_ai.openai.request.seed" -""" -Deprecated: Replaced by `gen_ai.request.seed`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OPENAI_REQUEST_SERVICE_TIER: Final = "gen_ai.openai.request.service_tier" -""" -Deprecated: Replaced by `openai.request.service_tier`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OPENAI_RESPONSE_SERVICE_TIER: Final = "gen_ai.openai.response.service_tier" -""" -Deprecated: Replaced by `openai.response.service_tier`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OPENAI_RESPONSE_SYSTEM_FINGERPRINT: Final = "gen_ai.openai.response.system_fingerprint" -""" -Deprecated: Replaced by `openai.response.system_fingerprint`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OPERATION_NAME: Final = "gen_ai.operation.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OUTPUT_MESSAGES: Final = "gen_ai.output.messages" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_OUTPUT_TYPE: Final = "gen_ai.output.type" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_PROMPT: Final = "gen_ai.prompt" -""" -Deprecated: Removed, no replacement at this time. -""" - -GEN_AI_PROMPT_NAME: Final = "gen_ai.prompt.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_PROVIDER_NAME: Final = "gen_ai.provider.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_CHOICE_COUNT: Final = "gen_ai.request.choice.count" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_ENCODING_FORMATS: Final = "gen_ai.request.encoding_formats" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_FREQUENCY_PENALTY: Final = "gen_ai.request.frequency_penalty" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_MAX_TOKENS: Final = "gen_ai.request.max_tokens" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_MODEL: Final = "gen_ai.request.model" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_PRESENCE_PENALTY: Final = "gen_ai.request.presence_penalty" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_SEED: Final = "gen_ai.request.seed" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_STOP_SEQUENCES: Final = "gen_ai.request.stop_sequences" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_STREAM: Final = "gen_ai.request.stream" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_TEMPERATURE: Final = "gen_ai.request.temperature" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_TOP_K: Final = "gen_ai.request.top_k" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_REQUEST_TOP_P: Final = "gen_ai.request.top_p" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_RESPONSE_FINISH_REASONS: Final = "gen_ai.response.finish_reasons" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_RESPONSE_ID: Final = "gen_ai.response.id" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_RESPONSE_MODEL: Final = "gen_ai.response.model" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_RESPONSE_TIME_TO_FIRST_CHUNK: Final = "gen_ai.response.time_to_first_chunk" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_RETRIEVAL_DOCUMENTS: Final = "gen_ai.retrieval.documents" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_RETRIEVAL_QUERY_TEXT: Final = "gen_ai.retrieval.query.text" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_SYSTEM: Final = "gen_ai.system" -""" -Deprecated: Replaced by `gen_ai.provider.name`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_SYSTEM_INSTRUCTIONS: Final = "gen_ai.system_instructions" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOKEN_TYPE: Final = "gen_ai.token.type" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOOL_CALL_ARGUMENTS: Final = "gen_ai.tool.call.arguments" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOOL_CALL_ID: Final = "gen_ai.tool.call.id" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOOL_CALL_RESULT: Final = "gen_ai.tool.call.result" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOOL_DEFINITIONS: Final = "gen_ai.tool.definitions" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOOL_DESCRIPTION: Final = "gen_ai.tool.description" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOOL_NAME: Final = "gen_ai.tool.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_TOOL_TYPE: Final = "gen_ai.tool.type" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS: Final = "gen_ai.usage.cache_creation.input_tokens" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS: Final = "gen_ai.usage.cache_read.input_tokens" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_USAGE_COMPLETION_TOKENS: Final = "gen_ai.usage.completion_tokens" -""" -Deprecated: Replaced by `gen_ai.usage.output_tokens`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_USAGE_INPUT_TOKENS: Final = "gen_ai.usage.input_tokens" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_USAGE_OUTPUT_TOKENS: Final = "gen_ai.usage.output_tokens" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_USAGE_PROMPT_TOKENS: Final = "gen_ai.usage.prompt_tokens" -""" -Deprecated: Replaced by `gen_ai.usage.input_tokens`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_USAGE_REASONING_OUTPUT_TOKENS: Final = "gen_ai.usage.reasoning.output_tokens" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -GEN_AI_WORKFLOW_NAME: Final = "gen_ai.workflow.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -@deprecated( - "The attribute gen_ai.openai.request.response_format is deprecated - Replaced by `gen_ai.output.type`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class GenAiOpenaiRequestResponseFormatValues(Enum): - TEXT = "text" - """Text response format.""" - JSON_OBJECT = "json_object" - """JSON object response format.""" - JSON_SCHEMA = "json_schema" - """JSON schema response format.""" - - -@deprecated( - "The attribute gen_ai.openai.request.service_tier is deprecated - Replaced by `openai.request.service_tier`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class GenAiOpenaiRequestServiceTierValues(Enum): - AUTO = "auto" - """The system will utilize scale tier credits until they are exhausted.""" - DEFAULT = "default" - """The system will utilize the default scale tier.""" - - -@deprecated( - "The attribute gen_ai.operation.name is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class GenAiOperationNameValues(Enum): - CHAT = "chat" - """Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat).""" - GENERATE_CONTENT = "generate_content" - """Multimodal content generation operation such as [Gemini Generate Content](https://ai.google.dev/api/generate-content).""" - TEXT_COMPLETION = "text_completion" - """Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions).""" - EMBEDDINGS = "embeddings" - """Embeddings operation such as [OpenAI Create embeddings API](https://platform.openai.com/docs/api-reference/embeddings/create).""" - RETRIEVAL = "retrieval" - """Retrieval operation such as [OpenAI Search Vector Store API](https://platform.openai.com/docs/api-reference/vector-stores/search).""" - CREATE_AGENT = "create_agent" - """Create GenAI agent.""" - INVOKE_AGENT = "invoke_agent" - """Invoke GenAI agent.""" - EXECUTE_TOOL = "execute_tool" - """Execute a tool.""" - INVOKE_WORKFLOW = "invoke_workflow" - """Invoke GenAI workflow.""" - - -@deprecated( - "The attribute gen_ai.output.type is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class GenAiOutputTypeValues(Enum): - TEXT = "text" - """Plain text.""" - JSON = "json" - """JSON object with known or unknown schema.""" - IMAGE = "image" - """Image.""" - SPEECH = "speech" - """Speech.""" - - -@deprecated( - "The attribute gen_ai.provider.name is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class GenAiProviderNameValues(Enum): - OPENAI = "openai" - """[OpenAI](https://openai.com/).""" - GCP_GEN_AI = "gcp.gen_ai" - """Any Google generative AI endpoint.""" - GCP_VERTEX_AI = "gcp.vertex_ai" - """[Vertex AI](https://cloud.google.com/vertex-ai).""" - GCP_GEMINI = "gcp.gemini" - """[Gemini](https://cloud.google.com/products/gemini).""" - ANTHROPIC = "anthropic" - """[Anthropic](https://www.anthropic.com/).""" - COHERE = "cohere" - """[Cohere](https://cohere.com/).""" - AZURE_AI_INFERENCE = "azure.ai.inference" - """Azure AI Inference.""" - AZURE_AI_OPENAI = "azure.ai.openai" - """[Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/overview).""" - IBM_WATSONX_AI = "ibm.watsonx.ai" - """[IBM Watsonx AI](https://www.ibm.com/products/watsonx-ai).""" - AWS_BEDROCK = "aws.bedrock" - """[AWS Bedrock](https://aws.amazon.com/bedrock).""" - PERPLEXITY = "perplexity" - """[Perplexity](https://www.perplexity.ai/).""" - X_AI = "x_ai" - """[xAI](https://x.ai/).""" - DEEPSEEK = "deepseek" - """[DeepSeek](https://www.deepseek.com/).""" - GROQ = "groq" - """[Groq](https://groq.com/).""" - MISTRAL_AI = "mistral_ai" - """[Mistral AI](https://mistral.ai/).""" - - -@deprecated( - "The attribute gen_ai.system is deprecated - Replaced by `gen_ai.provider.name`, which has moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class GenAiSystemValues(Enum): - OPENAI = "openai" - """OpenAI.""" - GCP_GEN_AI = "gcp.gen_ai" - """Any Google generative AI endpoint.""" - GCP_VERTEX_AI = "gcp.vertex_ai" - """Vertex AI.""" - GCP_GEMINI = "gcp.gemini" - """Gemini.""" - VERTEX_AI = "vertex_ai" - """Deprecated: Replaced by `gcp.vertex_ai`.""" - GEMINI = "gemini" - """Deprecated: Replaced by `gcp.gemini`.""" - ANTHROPIC = "anthropic" - """Anthropic.""" - COHERE = "cohere" - """Cohere.""" - AZ_AI_INFERENCE = "az.ai.inference" - """Deprecated: Replaced by `azure.ai.inference`.""" - AZ_AI_OPENAI = "az.ai.openai" - """Deprecated: Replaced by `azure.ai.openai`.""" - AZURE_AI_INFERENCE = "azure.ai.inference" - """Azure AI Inference.""" - AZURE_AI_OPENAI = "azure.ai.openai" - """Azure OpenAI.""" - IBM_WATSONX_AI = "ibm.watsonx.ai" - """IBM Watsonx AI.""" - AWS_BEDROCK = "aws.bedrock" - """AWS Bedrock.""" - PERPLEXITY = "perplexity" - """Perplexity.""" - XAI = "xai" - """xAI.""" - DEEPSEEK = "deepseek" - """DeepSeek.""" - GROQ = "groq" - """Groq.""" - MISTRAL_AI = "mistral_ai" - """Mistral AI.""" - - -@deprecated( - "The attribute gen_ai.token.type is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class GenAiTokenTypeValues(Enum): - INPUT = "input" - """Input tokens (prompt, input, etc.).""" - COMPLETION = "output" - """Deprecated: Replaced by `output`.""" - OUTPUT = "output" - """Output tokens (completion, response, etc.).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py deleted file mode 100644 index a32cfdda069..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/geo_attributes.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -GEO_CONTINENT_CODE: Final = "geo.continent.code" -""" -Two-letter code representing continent’s name. -""" - -GEO_COUNTRY_ISO_CODE: Final = "geo.country.iso_code" -""" -Two-letter ISO Country Code ([ISO 3166-1 alpha2](https://wikipedia.org/wiki/ISO_3166-1#Codes)). -""" - -GEO_LOCALITY_NAME: Final = "geo.locality.name" -""" -Locality name. Represents the name of a city, town, village, or similar populated place. -""" - -GEO_LOCATION_LAT: Final = "geo.location.lat" -""" -Latitude of the geo location in [WGS84](https://wikipedia.org/wiki/World_Geodetic_System#WGS84). -""" - -GEO_LOCATION_LON: Final = "geo.location.lon" -""" -Longitude of the geo location in [WGS84](https://wikipedia.org/wiki/World_Geodetic_System#WGS84). -""" - -GEO_POSTAL_CODE: Final = "geo.postal_code" -""" -Postal code associated with the location. Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. -""" - -GEO_REGION_ISO_CODE: Final = "geo.region.iso_code" -""" -Region ISO code ([ISO 3166-2](https://wikipedia.org/wiki/ISO_3166-2)). -""" - - -class GeoContinentCodeValues(Enum): - AF = "AF" - """Africa.""" - AN = "AN" - """Antarctica.""" - AS = "AS" - """Asia.""" - EU = "EU" - """Europe.""" - NA = "NA" - """North America.""" - OC = "OC" - """Oceania.""" - SA = "SA" - """South America.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py deleted file mode 100644 index 83c0d672740..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/graphql_attributes.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -GRAPHQL_DOCUMENT: Final = "graphql.document" -""" -The GraphQL document being executed. -Note: If instrumentation can reliably identify and redact sensitive information it SHOULD do it. -""" - -GRAPHQL_OPERATION_NAME: Final = "graphql.operation.name" -""" -The name of the operation being executed. -""" - -GRAPHQL_OPERATION_TYPE: Final = "graphql.operation.type" -""" -The type of the operation being executed. -""" - - -class GraphqlOperationTypeValues(Enum): - QUERY = "query" - """GraphQL query.""" - MUTATION = "mutation" - """GraphQL mutation.""" - SUBSCRIPTION = "subscription" - """GraphQL subscription.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py deleted file mode 100644 index 2de0654dc65..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/heroku_attributes.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -HEROKU_APP_ID: Final = "heroku.app.id" -""" -Unique identifier for the application. -""" - -HEROKU_RELEASE_COMMIT: Final = "heroku.release.commit" -""" -Commit hash for the current release. -""" - -HEROKU_RELEASE_CREATION_TIMESTAMP: Final = "heroku.release.creation_timestamp" -""" -Time and date the release was created. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py deleted file mode 100644 index 0bf5391eac0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/host_attributes.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -HOST_ARCH: Final = "host.arch" -""" -The CPU architecture the host system is running on. -""" - -HOST_CPU_CACHE_L2_SIZE: Final = "host.cpu.cache.l2.size" -""" -The amount of level 2 memory cache available to the processor (in Bytes). -""" - -HOST_CPU_FAMILY: Final = "host.cpu.family" -""" -Family or generation of the CPU. -""" - -HOST_CPU_MODEL_ID: Final = "host.cpu.model.id" -""" -Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. -""" - -HOST_CPU_MODEL_NAME: Final = "host.cpu.model.name" -""" -Model designation of the processor. -""" - -HOST_CPU_STEPPING: Final = "host.cpu.stepping" -""" -Stepping or core revisions. -""" - -HOST_CPU_VENDOR_ID: Final = "host.cpu.vendor.id" -""" -Processor manufacturer identifier. A maximum 12-character string. -Note: [CPUID](https://wiki.osdev.org/CPUID) command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. -""" - -HOST_ID: Final = "host.id" -""" -Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. -""" - -HOST_IMAGE_ID: Final = "host.image.id" -""" -VM image ID or host OS image ID. For Cloud, this value is from the provider. -""" - -HOST_IMAGE_NAME: Final = "host.image.name" -""" -Name of the VM image or OS install the host was instantiated from. -""" - -HOST_IMAGE_VERSION: Final = "host.image.version" -""" -The version string of the VM image or host OS as defined in [Version Attributes](/docs/resource/README.md#version-attributes). -""" - -HOST_IP: Final = "host.ip" -""" -Available IP addresses of the host, excluding loopback interfaces. -Note: IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952.html) format. -""" - -HOST_MAC: Final = "host.mac" -""" -Available MAC addresses of the host, excluding loopback interfaces. -Note: MAC Addresses MUST be represented in [IEEE RA hexadecimal form](https://standards.ieee.org/wp-content/uploads/import/documents/tutorials/eui.pdf): as hyphen-separated octets in uppercase hexadecimal form from most to least significant. -""" - -HOST_NAME: Final = "host.name" -""" -Name of the host. On UNIX systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. -""" - -HOST_TYPE: Final = "host.type" -""" -Type of host. For Cloud, this must be the machine type. -""" - - -class HostArchValues(Enum): - AMD64 = "amd64" - """AMD64.""" - ARM32 = "arm32" - """ARM32.""" - ARM64 = "arm64" - """ARM64.""" - IA64 = "ia64" - """Itanium.""" - PPC32 = "ppc32" - """32-bit PowerPC.""" - PPC64 = "ppc64" - """64-bit PowerPC.""" - S390X = "s390x" - """IBM z/Architecture.""" - X86 = "x86" - """32-bit x86.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py deleted file mode 100644 index 58cfb708bab..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/http_attributes.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -HTTP_CLIENT_IP: Final = "http.client_ip" -""" -Deprecated: Replaced by `client.address`. -""" - -HTTP_CONNECTION_STATE: Final = "http.connection.state" -""" -State of the HTTP connection in the HTTP connection pool. -""" - -HTTP_FLAVOR: Final = "http.flavor" -""" -Deprecated: Split into `network.protocol.name` and `network.protocol.version`. -""" - -HTTP_HOST: Final = "http.host" -""" -Deprecated: Replaced by one of `server.address`, `client.address` or `http.request.header.host`, depending on the usage. -""" - -HTTP_METHOD: Final = "http.method" -""" -Deprecated: Replaced by `http.request.method`. -""" - -HTTP_REQUEST_BODY_SIZE: Final = "http.request.body.size" -""" -The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. -""" - -HTTP_REQUEST_HEADER_TEMPLATE: Final = "http.request.header" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_HEADER_TEMPLATE`. -""" - -HTTP_REQUEST_METHOD: Final = "http.request.method" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_METHOD`. -""" - -HTTP_REQUEST_METHOD_ORIGINAL: Final = "http.request.method_original" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_METHOD_ORIGINAL`. -""" - -HTTP_REQUEST_RESEND_COUNT: Final = "http.request.resend_count" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_REQUEST_RESEND_COUNT`. -""" - -HTTP_REQUEST_SIZE: Final = "http.request.size" -""" -The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. -""" - -HTTP_REQUEST_CONTENT_LENGTH: Final = "http.request_content_length" -""" -Deprecated: Replaced by `http.request.header.content-length`. -""" - -HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED: Final = "http.request_content_length_uncompressed" -""" -Deprecated: Replaced by `http.request.body.size`. -""" - -HTTP_RESPONSE_BODY_SIZE: Final = "http.response.body.size" -""" -The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. -""" - -HTTP_RESPONSE_HEADER_TEMPLATE: Final = "http.response.header" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_RESPONSE_HEADER_TEMPLATE`. -""" - -HTTP_RESPONSE_SIZE: Final = "http.response.size" -""" -The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. -""" - -HTTP_RESPONSE_STATUS_CODE: Final = "http.response.status_code" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_RESPONSE_STATUS_CODE`. -""" - -HTTP_RESPONSE_CONTENT_LENGTH: Final = "http.response_content_length" -""" -Deprecated: Replaced by `http.response.header.content-length`. -""" - -HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED: Final = "http.response_content_length_uncompressed" -""" -Deprecated: Replaced by `http.response.body.size`. -""" - -HTTP_ROUTE: Final = "http.route" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HTTP_ROUTE`. -""" - -HTTP_SCHEME: Final = "http.scheme" -""" -Deprecated: Replaced by `url.scheme`. -""" - -HTTP_SERVER_NAME: Final = "http.server_name" -""" -Deprecated: Replaced by `server.address`. -""" - -HTTP_STATUS_CODE: Final = "http.status_code" -""" -Deprecated: Replaced by `http.response.status_code`. -""" - -HTTP_TARGET: Final = "http.target" -""" -Deprecated: Split to `url.path` and `url.query`. -""" - -HTTP_URL: Final = "http.url" -""" -Deprecated: Replaced by `url.full`. -""" - -HTTP_USER_AGENT: Final = "http.user_agent" -""" -Deprecated: Replaced by `user_agent.original`. -""" - - -class HttpConnectionStateValues(Enum): - ACTIVE = "active" - """active state.""" - IDLE = "idle" - """idle state.""" - - -@deprecated( - "The attribute http.flavor is deprecated - Split into `network.protocol.name` and `network.protocol.version`" -) -class HttpFlavorValues(Enum): - HTTP_1_0 = "1.0" - """HTTP/1.0.""" - HTTP_1_1 = "1.1" - """HTTP/1.1.""" - HTTP_2_0 = "2.0" - """HTTP/2.""" - HTTP_3_0 = "3.0" - """HTTP/3.""" - SPDY = "SPDY" - """SPDY protocol.""" - QUIC = "QUIC" - """QUIC protocol.""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues`." -) -class HttpRequestMethodValues(Enum): - CONNECT = "CONNECT" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.CONNECT`.""" - DELETE = "DELETE" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.DELETE`.""" - GET = "GET" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.GET`.""" - HEAD = "HEAD" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.HEAD`.""" - OPTIONS = "OPTIONS" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.OPTIONS`.""" - PATCH = "PATCH" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.PATCH`.""" - POST = "POST" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.POST`.""" - PUT = "PUT" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.PUT`.""" - TRACE = "TRACE" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.TRACE`.""" - QUERY = "QUERY" - """QUERY method.""" - OTHER = "_OTHER" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.http_attributes.HttpRequestMethodValues.OTHER`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py deleted file mode 100644 index 548e6fdc518..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/hw_attributes.py +++ /dev/null @@ -1,243 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -HW_BATTERY_CAPACITY: Final = "hw.battery.capacity" -""" -Design capacity in Watts-hours or Ampere-hours. -""" - -HW_BATTERY_CHEMISTRY: Final = "hw.battery.chemistry" -""" -Battery [chemistry](https://schemas.dmtf.org/wbem/cim-html/2.31.0/CIM_Battery.html), e.g. Lithium-Ion, Nickel-Cadmium, etc. -""" - -HW_BATTERY_STATE: Final = "hw.battery.state" -""" -The current state of the battery. -""" - -HW_BIOS_VERSION: Final = "hw.bios_version" -""" -BIOS version of the hardware component. -""" - -HW_DRIVER_VERSION: Final = "hw.driver_version" -""" -Driver version for the hardware component. -""" - -HW_ENCLOSURE_TYPE: Final = "hw.enclosure.type" -""" -Type of the enclosure (useful for modular systems). -""" - -HW_FIRMWARE_VERSION: Final = "hw.firmware_version" -""" -Firmware version of the hardware component. -""" - -HW_GPU_TASK: Final = "hw.gpu.task" -""" -Type of task the GPU is performing. -""" - -HW_ID: Final = "hw.id" -""" -An identifier for the hardware component, unique within the monitored host. -""" - -HW_LIMIT_TYPE: Final = "hw.limit_type" -""" -Type of limit for hardware components. -""" - -HW_LOGICAL_DISK_RAID_LEVEL: Final = "hw.logical_disk.raid_level" -""" -RAID Level of the logical disk. -""" - -HW_LOGICAL_DISK_STATE: Final = "hw.logical_disk.state" -""" -State of the logical disk space usage. -""" - -HW_MEMORY_TYPE: Final = "hw.memory.type" -""" -Type of the memory module. -""" - -HW_MODEL: Final = "hw.model" -""" -Descriptive model name of the hardware component. -""" - -HW_NAME: Final = "hw.name" -""" -An easily-recognizable name for the hardware component. -""" - -HW_NETWORK_LOGICAL_ADDRESSES: Final = "hw.network.logical_addresses" -""" -Logical addresses of the adapter (e.g. IP address, or WWPN). -""" - -HW_NETWORK_PHYSICAL_ADDRESS: Final = "hw.network.physical_address" -""" -Physical address of the adapter (e.g. MAC address, or WWNN). -""" - -HW_PARENT: Final = "hw.parent" -""" -Unique identifier of the parent component (typically the `hw.id` attribute of the enclosure, or disk controller). -""" - -HW_PHYSICAL_DISK_SMART_ATTRIBUTE: Final = "hw.physical_disk.smart_attribute" -""" -[S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute of the physical disk. -""" - -HW_PHYSICAL_DISK_STATE: Final = "hw.physical_disk.state" -""" -State of the physical disk endurance utilization. -""" - -HW_PHYSICAL_DISK_TYPE: Final = "hw.physical_disk.type" -""" -Type of the physical disk. -""" - -HW_SENSOR_LOCATION: Final = "hw.sensor_location" -""" -Location of the sensor. -""" - -HW_SERIAL_NUMBER: Final = "hw.serial_number" -""" -Serial number of the hardware component. -""" - -HW_STATE: Final = "hw.state" -""" -The current state of the component. -""" - -HW_TAPE_DRIVE_OPERATION_TYPE: Final = "hw.tape_drive.operation_type" -""" -Type of tape drive operation. -""" - -HW_TYPE: Final = "hw.type" -""" -Type of the component. -Note: Describes the category of the hardware component for which `hw.state` is being reported. For example, `hw.type=temperature` along with `hw.state=degraded` would indicate that the temperature of the hardware component has been reported as `degraded`. -""" - -HW_VENDOR: Final = "hw.vendor" -""" -Vendor name of the hardware component. -""" - - -class HwBatteryStateValues(Enum): - CHARGING = "charging" - """Charging.""" - DISCHARGING = "discharging" - """Discharging.""" - - -class HwGpuTaskValues(Enum): - DECODER = "decoder" - """Decoder.""" - ENCODER = "encoder" - """Encoder.""" - GENERAL = "general" - """General.""" - - -class HwLimitTypeValues(Enum): - CRITICAL = "critical" - """Critical.""" - DEGRADED = "degraded" - """Degraded.""" - HIGH_CRITICAL = "high.critical" - """High Critical.""" - HIGH_DEGRADED = "high.degraded" - """High Degraded.""" - LOW_CRITICAL = "low.critical" - """Low Critical.""" - LOW_DEGRADED = "low.degraded" - """Low Degraded.""" - MAX = "max" - """Maximum.""" - THROTTLED = "throttled" - """Throttled.""" - TURBO = "turbo" - """Turbo.""" - - -class HwLogicalDiskStateValues(Enum): - USED = "used" - """Used.""" - FREE = "free" - """Free.""" - - -class HwPhysicalDiskStateValues(Enum): - REMAINING = "remaining" - """Remaining.""" - - -class HwStateValues(Enum): - DEGRADED = "degraded" - """Degraded.""" - FAILED = "failed" - """Failed.""" - NEEDS_CLEANING = "needs_cleaning" - """Needs Cleaning.""" - OK = "ok" - """OK.""" - PREDICTED_FAILURE = "predicted_failure" - """Predicted Failure.""" - - -class HwTapeDriveOperationTypeValues(Enum): - MOUNT = "mount" - """Mount.""" - UNMOUNT = "unmount" - """Unmount.""" - CLEAN = "clean" - """Clean.""" - - -class HwTypeValues(Enum): - BATTERY = "battery" - """Battery.""" - CPU = "cpu" - """CPU.""" - DISK_CONTROLLER = "disk_controller" - """Disk controller.""" - ENCLOSURE = "enclosure" - """Enclosure.""" - FAN = "fan" - """Fan.""" - GPU = "gpu" - """GPU.""" - LOGICAL_DISK = "logical_disk" - """Logical disk.""" - MEMORY = "memory" - """Memory.""" - NETWORK = "network" - """Network.""" - PHYSICAL_DISK = "physical_disk" - """Physical disk.""" - POWER_SUPPLY = "power_supply" - """Power supply.""" - TAPE_DRIVE = "tape_drive" - """Tape drive.""" - TEMPERATURE = "temperature" - """Temperature.""" - VOLTAGE = "voltage" - """Voltage.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py deleted file mode 100644 index fcea8239f93..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/jsonrpc_attributes.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -JSONRPC_PROTOCOL_VERSION: Final = "jsonrpc.protocol.version" -""" -Protocol version, as specified in the `jsonrpc` property of the request and its corresponding response. -""" - -JSONRPC_REQUEST_ID: Final = "jsonrpc.request.id" -""" -A string representation of the `id` property of the request and its corresponding response. -Note: Under the [JSON-RPC specification](https://www.jsonrpc.org/specification), the `id` property may be a string, number, null, or omitted entirely. When omitted, the request is treated as a notification. Using `null` is not equivalent to omitting the `id`, but it is discouraged. -Instrumentations SHOULD NOT capture this attribute when the `id` is `null` or omitted. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py deleted file mode 100644 index 0b2eed32e52..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/k8s_attributes.py +++ /dev/null @@ -1,721 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -K8S_CLUSTER_NAME: Final = "k8s.cluster.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CLUSTER_NAME`. -""" - -K8S_CLUSTER_UID: Final = "k8s.cluster.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CLUSTER_UID`. -""" - -K8S_CONTAINER_EPHEMERAL_STORAGE_FS_TYPE: Final = "k8s.container.ephemeral_storage.fs_type" -""" -The type of file system component for ephemeral storage. -Note: Eviction decisions based on ephemeral-storage resource limits are made based on the total container usage. -""" - -K8S_CONTAINER_NAME: Final = "k8s.container.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CONTAINER_NAME`. -""" - -K8S_CONTAINER_RESTART_COUNT: Final = "k8s.container.restart_count" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CONTAINER_RESTART_COUNT`. -""" - -K8S_CONTAINER_STATUS_LAST_TERMINATED_REASON: Final = "k8s.container.status.last_terminated_reason" -""" -Last terminated reason of the Container. -""" - -K8S_CONTAINER_STATUS_REASON: Final = "k8s.container.status.reason" -""" -The reason for the container state. Corresponds to the `reason` field of the: [K8s ContainerStateWaiting](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatewaiting-v1-core) or [K8s ContainerStateTerminated](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstateterminated-v1-core). -""" - -K8S_CONTAINER_STATUS_STATE: Final = "k8s.container.status.state" -""" -The state of the container. [K8s ContainerState](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstate-v1-core). -""" - -K8S_CRONJOB_ANNOTATION_TEMPLATE: Final = "k8s.cronjob.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_ANNOTATION_TEMPLATE`. -""" - -K8S_CRONJOB_LABEL_TEMPLATE: Final = "k8s.cronjob.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_LABEL_TEMPLATE`. -""" - -K8S_CRONJOB_NAME: Final = "k8s.cronjob.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_NAME`. -""" - -K8S_CRONJOB_UID: Final = "k8s.cronjob.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_CRONJOB_UID`. -""" - -K8S_DAEMONSET_ANNOTATION_TEMPLATE: Final = "k8s.daemonset.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_ANNOTATION_TEMPLATE`. -""" - -K8S_DAEMONSET_LABEL_TEMPLATE: Final = "k8s.daemonset.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_LABEL_TEMPLATE`. -""" - -K8S_DAEMONSET_NAME: Final = "k8s.daemonset.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_NAME`. -""" - -K8S_DAEMONSET_UID: Final = "k8s.daemonset.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DAEMONSET_UID`. -""" - -K8S_DEPLOYMENT_ANNOTATION_TEMPLATE: Final = "k8s.deployment.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_ANNOTATION_TEMPLATE`. -""" - -K8S_DEPLOYMENT_LABEL_TEMPLATE: Final = "k8s.deployment.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_LABEL_TEMPLATE`. -""" - -K8S_DEPLOYMENT_NAME: Final = "k8s.deployment.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_NAME`. -""" - -K8S_DEPLOYMENT_UID: Final = "k8s.deployment.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_DEPLOYMENT_UID`. -""" - -K8S_HPA_METRIC_TYPE: Final = "k8s.hpa.metric.type" -""" -The type of metric source for the horizontal pod autoscaler. -Note: This attribute reflects the `type` field of spec.metrics[] in the HPA. -""" - -K8S_HPA_NAME: Final = "k8s.hpa.name" -""" -The name of the horizontal pod autoscaler. -""" - -K8S_HPA_SCALETARGETREF_API_VERSION: Final = "k8s.hpa.scaletargetref.api_version" -""" -The API version of the target resource to scale for the HorizontalPodAutoscaler. -Note: This maps to the `apiVersion` field in the `scaleTargetRef` of the HPA spec. -""" - -K8S_HPA_SCALETARGETREF_KIND: Final = "k8s.hpa.scaletargetref.kind" -""" -The kind of the target resource to scale for the HorizontalPodAutoscaler. -Note: This maps to the `kind` field in the `scaleTargetRef` of the HPA spec. -""" - -K8S_HPA_SCALETARGETREF_NAME: Final = "k8s.hpa.scaletargetref.name" -""" -The name of the target resource to scale for the HorizontalPodAutoscaler. -Note: This maps to the `name` field in the `scaleTargetRef` of the HPA spec. -""" - -K8S_HPA_UID: Final = "k8s.hpa.uid" -""" -The UID of the horizontal pod autoscaler. -""" - -K8S_HUGEPAGE_SIZE: Final = "k8s.hugepage.size" -""" -The size (identifier) of the K8s huge page. -""" - -K8S_JOB_ANNOTATION_TEMPLATE: Final = "k8s.job.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_ANNOTATION_TEMPLATE`. -""" - -K8S_JOB_LABEL_TEMPLATE: Final = "k8s.job.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_LABEL_TEMPLATE`. -""" - -K8S_JOB_NAME: Final = "k8s.job.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_NAME`. -""" - -K8S_JOB_UID: Final = "k8s.job.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_JOB_UID`. -""" - -K8S_NAMESPACE_ANNOTATION_TEMPLATE: Final = "k8s.namespace.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NAMESPACE_ANNOTATION_TEMPLATE`. -""" - -K8S_NAMESPACE_LABEL_TEMPLATE: Final = "k8s.namespace.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NAMESPACE_LABEL_TEMPLATE`. -""" - -K8S_NAMESPACE_NAME: Final = "k8s.namespace.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NAMESPACE_NAME`. -""" - -K8S_NAMESPACE_PHASE: Final = "k8s.namespace.phase" -""" -The phase of the K8s namespace. -Note: This attribute aligns with the `phase` field of the -[K8s NamespaceStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#namespacestatus-v1-core). -""" - -K8S_NODE_ANNOTATION_TEMPLATE: Final = "k8s.node.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_ANNOTATION_TEMPLATE`. -""" - -K8S_NODE_CONDITION_STATUS: Final = "k8s.node.condition.status" -""" -The status of the condition, one of True, False, Unknown. -Note: This attribute aligns with the `status` field of the -[NodeCondition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#nodecondition-v1-core). -""" - -K8S_NODE_CONDITION_TYPE: Final = "k8s.node.condition.type" -""" -The condition type of a K8s Node. -Note: K8s Node conditions as described -by [K8s documentation](https://kubernetes.io/docs/reference/node/node-status/#condition). - -This attribute aligns with the `type` field of the -[NodeCondition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#nodecondition-v1-core) - -The set of possible values is not limited to those listed here. Managed Kubernetes environments, -or custom controllers MAY introduce additional node condition types. -When this occurs, the exact value as reported by the Kubernetes API SHOULD be used. -""" - -K8S_NODE_LABEL_TEMPLATE: Final = "k8s.node.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_LABEL_TEMPLATE`. -""" - -K8S_NODE_NAME: Final = "k8s.node.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_NAME`. -""" - -K8S_NODE_SYSTEM_CONTAINER_NAME: Final = "k8s.node.system_container.name" -""" -The name of the system container running on the K8s Node. -""" - -K8S_NODE_UID: Final = "k8s.node.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_NODE_UID`. -""" - -K8S_PERSISTENTVOLUME_ANNOTATION_TEMPLATE: Final = "k8s.persistentvolume.annotation" -""" -The annotation placed on the PersistentVolume, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `pv.kubernetes.io/provisioned-by` with value `kubernetes.io/aws-ebs` SHOULD be recorded as - the `k8s.persistentvolume.annotation.pv.kubernetes.io/provisioned-by` attribute with value `"kubernetes.io/aws-ebs"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.persistentvolume.annotation.data` attribute with value `""`. -""" - -K8S_PERSISTENTVOLUME_LABEL_TEMPLATE: Final = "k8s.persistentvolume.label" -""" -The label placed on the PersistentVolume, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `type` with value `ssd` SHOULD be recorded as - the `k8s.persistentvolume.label.type` attribute with value `"ssd"`. -- A label `data` with empty string value SHOULD be recorded as - the `k8s.persistentvolume.label.data` attribute with value `""`. -""" - -K8S_PERSISTENTVOLUME_NAME: Final = "k8s.persistentvolume.name" -""" -The name of the PersistentVolume. -""" - -K8S_PERSISTENTVOLUME_RECLAIM_POLICY: Final = "k8s.persistentvolume.reclaim_policy" -""" -The reclaim policy of the PersistentVolume. -Note: This attribute aligns with the `persistentVolumeReclaimPolicy` field of the -[K8s PersistentVolumeSpec](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec). -""" - -K8S_PERSISTENTVOLUME_STATUS_PHASE: Final = "k8s.persistentvolume.status.phase" -""" -The phase of the PersistentVolume. -Note: This attribute aligns with the `phase` field of the -[K8s PersistentVolumeStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeStatus). -""" - -K8S_PERSISTENTVOLUME_UID: Final = "k8s.persistentvolume.uid" -""" -The UID of the PersistentVolume. -""" - -K8S_PERSISTENTVOLUMECLAIM_ANNOTATION_TEMPLATE: Final = "k8s.persistentvolumeclaim.annotation" -""" -The annotation placed on the PersistentVolumeClaim, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `volume.beta.kubernetes.io/storage-provisioner` with value `kubernetes.io/aws-ebs` SHOULD be recorded as - the `k8s.persistentvolumeclaim.annotation.volume.beta.kubernetes.io/storage-provisioner` attribute with value `"kubernetes.io/aws-ebs"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.persistentvolumeclaim.annotation.data` attribute with value `""`. -""" - -K8S_PERSISTENTVOLUMECLAIM_LABEL_TEMPLATE: Final = "k8s.persistentvolumeclaim.label" -""" -The label placed on the PersistentVolumeClaim, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `app` with value `my-app` SHOULD be recorded as - the `k8s.persistentvolumeclaim.label.app` attribute with value `"my-app"`. -- A label `data` with empty string value SHOULD be recorded as - the `k8s.persistentvolumeclaim.label.data` attribute with value `""`. -""" - -K8S_PERSISTENTVOLUMECLAIM_NAME: Final = "k8s.persistentvolumeclaim.name" -""" -The name of the PersistentVolumeClaim. -""" - -K8S_PERSISTENTVOLUMECLAIM_STATUS_PHASE: Final = "k8s.persistentvolumeclaim.status.phase" -""" -The phase of the PersistentVolumeClaim. -Note: This attribute aligns with the `phase` field of the -[K8s PersistentVolumeClaimStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus). -""" - -K8S_PERSISTENTVOLUMECLAIM_UID: Final = "k8s.persistentvolumeclaim.uid" -""" -The UID of the PersistentVolumeClaim. -""" - -K8S_POD_ANNOTATION_TEMPLATE: Final = "k8s.pod.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_ANNOTATION_TEMPLATE`. -""" - -K8S_POD_HOSTNAME: Final = "k8s.pod.hostname" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_HOSTNAME`. -""" - -K8S_POD_IP: Final = "k8s.pod.ip" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_IP`. -""" - -K8S_POD_LABEL_TEMPLATE: Final = "k8s.pod.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_LABEL_TEMPLATE`. -""" - -K8S_POD_LABELS_TEMPLATE: Final = "k8s.pod.labels" -""" -Deprecated: Replaced by `k8s.pod.label`. -""" - -K8S_POD_NAME: Final = "k8s.pod.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_NAME`. -""" - -K8S_POD_START_TIME: Final = "k8s.pod.start_time" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_START_TIME`. -""" - -K8S_POD_STATUS_PHASE: Final = "k8s.pod.status.phase" -""" -The phase for the pod. Corresponds to the `phase` field of the: [K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core). -""" - -K8S_POD_STATUS_REASON: Final = "k8s.pod.status.reason" -""" -The reason for the pod state. Corresponds to the `reason` field of the: [K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podstatus-v1-core). -""" - -K8S_POD_UID: Final = "k8s.pod.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_POD_UID`. -""" - -K8S_REPLICASET_ANNOTATION_TEMPLATE: Final = "k8s.replicaset.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_ANNOTATION_TEMPLATE`. -""" - -K8S_REPLICASET_LABEL_TEMPLATE: Final = "k8s.replicaset.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_LABEL_TEMPLATE`. -""" - -K8S_REPLICASET_NAME: Final = "k8s.replicaset.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_NAME`. -""" - -K8S_REPLICASET_UID: Final = "k8s.replicaset.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_REPLICASET_UID`. -""" - -K8S_REPLICATIONCONTROLLER_NAME: Final = "k8s.replicationcontroller.name" -""" -The name of the replication controller. -""" - -K8S_REPLICATIONCONTROLLER_UID: Final = "k8s.replicationcontroller.uid" -""" -The UID of the replication controller. -""" - -K8S_RESOURCEQUOTA_NAME: Final = "k8s.resourcequota.name" -""" -The name of the resource quota. -""" - -K8S_RESOURCEQUOTA_RESOURCE_NAME: Final = "k8s.resourcequota.resource_name" -""" -The name of the K8s resource a resource quota defines. -Note: The value for this attribute can be either the full `count/[.]` string (e.g., count/deployments.apps, count/pods), or, for certain core Kubernetes resources, just the resource name (e.g., pods, services, configmaps). Both forms are supported by Kubernetes for object count quotas. See [Kubernetes Resource Quotas documentation](https://kubernetes.io/docs/concepts/policy/resource-quotas/#quota-on-object-count) for more details. -""" - -K8S_RESOURCEQUOTA_UID: Final = "k8s.resourcequota.uid" -""" -The UID of the resource quota. -""" - -K8S_SERVICE_ANNOTATION_TEMPLATE: Final = "k8s.service.annotation" -""" -The annotation placed on the Service, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `prometheus.io/scrape` with value `true` SHOULD be recorded as - the `k8s.service.annotation.prometheus.io/scrape` attribute with value `"true"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.service.annotation.data` attribute with value `""`. -""" - -K8S_SERVICE_ENDPOINT_ADDRESS_TYPE: Final = "k8s.service.endpoint.address_type" -""" -The address type of the service endpoint. -Note: The network address family or type of the endpoint. -This attribute aligns with the `addressType` field of the -[K8s EndpointSlice](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). -It is used to differentiate metrics when a Service is backed by multiple address types -(e.g., in dual-stack clusters). -""" - -K8S_SERVICE_ENDPOINT_CONDITION: Final = "k8s.service.endpoint.condition" -""" -The condition of the service endpoint. -Note: The current operational condition of the service endpoint. -An endpoint can have multiple conditions set at once (e.g., both `serving` and `terminating` during rollout). -This attribute aligns with the condition fields in the [K8s EndpointSlice](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). -""" - -K8S_SERVICE_ENDPOINT_ZONE: Final = "k8s.service.endpoint.zone" -""" -The zone of the service endpoint. -Note: The zone where the endpoint is located, typically corresponding to a failure domain. -This attribute aligns with the `zone` field of endpoints in the -[K8s EndpointSlice](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). -It enables zone-aware monitoring of service endpoint distribution and supports -features like [Topology Aware Routing](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/). - -If the zone is not populated (e.g., nodes without the `topology.kubernetes.io/zone` label), -the attribute value will be an empty string. -""" - -K8S_SERVICE_LABEL_TEMPLATE: Final = "k8s.service.label" -""" -The label placed on the Service, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `app` with value `my-service` SHOULD be recorded as - the `k8s.service.label.app` attribute with value `"my-service"`. -- A label `data` with empty string value SHOULD be recorded as - the `k8s.service.label.data` attribute with value `""`. -""" - -K8S_SERVICE_NAME: Final = "k8s.service.name" -""" -The name of the Service. -""" - -K8S_SERVICE_PUBLISH_NOT_READY_ADDRESSES: Final = "k8s.service.publish_not_ready_addresses" -""" -Whether the Service publishes not-ready endpoints. -Note: Whether the Service is configured to publish endpoints before the pods are ready. -This attribute is typically used to indicate that a Service (such as a headless -Service for a StatefulSet) allows peer discovery before pods pass their readiness probes. -It aligns with the `publishNotReadyAddresses` field of the -[K8s ServiceSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec). -""" - -K8S_SERVICE_SELECTOR_TEMPLATE: Final = "k8s.service.selector" -""" -The selector key-value pair placed on the Service, the `` being the selector key, the value being the selector value. -Note: These selectors are used to correlate with pod labels. Each selector key-value pair becomes a separate attribute. - -Examples: - -- A selector `app=my-app` SHOULD be recorded as - the `k8s.service.selector.app` attribute with value `"my-app"`. -- A selector `version=v1` SHOULD be recorded as - the `k8s.service.selector.version` attribute with value `"v1"`. -""" - -K8S_SERVICE_TRAFFIC_DISTRIBUTION: Final = "k8s.service.traffic_distribution" -""" -The traffic distribution policy for the Service. -Note: Specifies how traffic is distributed to endpoints for this Service. -This attribute aligns with the `trafficDistribution` field of the -[K8s ServiceSpec](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution). -Known values include `PreferSameZone` (prefer endpoints in the same zone as the client) and -`PreferSameNode` (prefer endpoints on the same node, fallback to same zone, then cluster-wide). -If this field is not set on the Service, the attribute SHOULD NOT be emitted. -When not set, Kubernetes distributes traffic evenly across all endpoints cluster-wide. -""" - -K8S_SERVICE_TYPE: Final = "k8s.service.type" -""" -The type of the Kubernetes Service. -Note: This attribute aligns with the `type` field of the -[K8s ServiceSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec). -""" - -K8S_SERVICE_UID: Final = "k8s.service.uid" -""" -The UID of the Service. -""" - -K8S_STATEFULSET_ANNOTATION_TEMPLATE: Final = "k8s.statefulset.annotation" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_ANNOTATION_TEMPLATE`. -""" - -K8S_STATEFULSET_LABEL_TEMPLATE: Final = "k8s.statefulset.label" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_LABEL_TEMPLATE`. -""" - -K8S_STATEFULSET_NAME: Final = "k8s.statefulset.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_NAME`. -""" - -K8S_STATEFULSET_UID: Final = "k8s.statefulset.uid" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.k8s_attributes.K8S_STATEFULSET_UID`. -""" - -K8S_STORAGECLASS_NAME: Final = "k8s.storageclass.name" -""" -The name of K8s [StorageClass](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#storageclass-v1-storage-k8s-io) object. -""" - -K8S_VOLUME_NAME: Final = "k8s.volume.name" -""" -The name of the K8s volume. -""" - -K8S_VOLUME_TYPE: Final = "k8s.volume.type" -""" -The type of the K8s volume. -""" - - -class K8sContainerEphemeralStorageFsTypeValues(Enum): - ROOTFS = "rootfs" - """For the container's writable layer usage.""" - LOGS = "logs" - """For the container's log files usage (stdout/stderr).""" - - -class K8sContainerStatusReasonValues(Enum): - CONTAINER_CREATING = "ContainerCreating" - """The container is being created.""" - CRASH_LOOP_BACK_OFF = "CrashLoopBackOff" - """The container is in a crash loop back off state.""" - CREATE_CONTAINER_CONFIG_ERROR = "CreateContainerConfigError" - """There was an error creating the container configuration.""" - ERR_IMAGE_PULL = "ErrImagePull" - """There was an error pulling the container image.""" - IMAGE_PULL_BACK_OFF = "ImagePullBackOff" - """The container image pull is in back off state.""" - OOM_KILLED = "OOMKilled" - """The container was killed due to out of memory.""" - COMPLETED = "Completed" - """The container has completed execution.""" - ERROR = "Error" - """There was an error with the container.""" - CONTAINER_CANNOT_RUN = "ContainerCannotRun" - """The container cannot run.""" - - -class K8sContainerStatusStateValues(Enum): - TERMINATED = "terminated" - """The container has terminated.""" - RUNNING = "running" - """The container is running.""" - WAITING = "waiting" - """The container is waiting.""" - - -class K8sNamespacePhaseValues(Enum): - ACTIVE = "active" - """Active namespace phase as described by [K8s API](https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase).""" - TERMINATING = "terminating" - """Terminating namespace phase as described by [K8s API](https://pkg.go.dev/k8s.io/api@v0.31.3/core/v1#NamespacePhase).""" - - -class K8sNodeConditionStatusValues(Enum): - CONDITION_TRUE = "true" - """condition_true.""" - CONDITION_FALSE = "false" - """condition_false.""" - CONDITION_UNKNOWN = "unknown" - """condition_unknown.""" - - -class K8sNodeConditionTypeValues(Enum): - READY = "Ready" - """The node is healthy and ready to accept pods.""" - DISK_PRESSURE = "DiskPressure" - """Pressure exists on the disk size—that is, if the disk capacity is low.""" - MEMORY_PRESSURE = "MemoryPressure" - """Pressure exists on the node memory—that is, if the node memory is low.""" - PID_PRESSURE = "PIDPressure" - """Pressure exists on the processes—that is, if there are too many processes on the node.""" - NETWORK_UNAVAILABLE = "NetworkUnavailable" - """The network for the node is not correctly configured.""" - - -class K8sPersistentvolumeReclaimPolicyValues(Enum): - DELETE = "Delete" - """The volume will be deleted when released from its claim.""" - RECYCLE = "Recycle" - """The volume will be recycled (basic scrub) when released from its claim.""" - RETAIN = "Retain" - """The volume will be retained when released from its claim.""" - - -class K8sPersistentvolumeStatusPhaseValues(Enum): - AVAILABLE = "Available" - """The volume is available and not yet bound to a claim.""" - BOUND = "Bound" - """The volume is bound to a claim.""" - FAILED = "Failed" - """The volume has failed its automatic reclamation.""" - PENDING = "Pending" - """The volume is being provisioned.""" - RELEASED = "Released" - """The claim has been deleted but the volume is not yet available.""" - - -class K8sPersistentvolumeclaimStatusPhaseValues(Enum): - BOUND = "Bound" - """The claim is bound to a volume.""" - LOST = "Lost" - """The claim has lost its underlying volume (the volume does not exist anymore).""" - PENDING = "Pending" - """The claim has not yet been bound to a volume.""" - - -class K8sPodStatusPhaseValues(Enum): - PENDING = "Pending" - """The pod has been accepted by the system, but one or more of the containers has not been started. This includes time before being bound to a node, as well as time spent pulling images onto the host.""" - RUNNING = "Running" - """The pod has been bound to a node and all of the containers have been started. At least one container is still running or is in the process of being restarted.""" - SUCCEEDED = "Succeeded" - """All containers in the pod have voluntarily terminated with a container exit code of 0, and the system is not going to restart any of these containers.""" - FAILED = "Failed" - """All containers in the pod have terminated, and at least one container has terminated in a failure (exited with a non-zero exit code or was stopped by the system).""" - UNKNOWN = "Unknown" - """For some reason the state of the pod could not be obtained, typically due to an error in communicating with the host of the pod.""" - - -class K8sPodStatusReasonValues(Enum): - EVICTED = "Evicted" - """The pod is evicted.""" - NODE_AFFINITY = "NodeAffinity" - """The pod is in a status because of its node affinity.""" - NODE_LOST = "NodeLost" - """The reason on a pod when its state cannot be confirmed as kubelet is unresponsive on the node it is (was) running.""" - SHUTDOWN = "Shutdown" - """The node is shutdown.""" - UNEXPECTED_ADMISSION_ERROR = "UnexpectedAdmissionError" - """The pod was rejected admission to the node because of an error during admission that could not be categorized.""" - - -class K8sServiceEndpointAddressTypeValues(Enum): - IPV4 = "IPv4" - """IPv4 address type.""" - IPV6 = "IPv6" - """IPv6 address type.""" - FQDN = "FQDN" - """FQDN address type.""" - - -class K8sServiceEndpointConditionValues(Enum): - READY = "ready" - """The endpoint is ready to receive new connections.""" - SERVING = "serving" - """The endpoint is currently handling traffic.""" - TERMINATING = "terminating" - """The endpoint is in the process of shutting down.""" - - -class K8sServiceTypeValues(Enum): - CLUSTER_IP = "ClusterIP" - """ClusterIP service type.""" - NODE_PORT = "NodePort" - """NodePort service type.""" - LOAD_BALANCER = "LoadBalancer" - """LoadBalancer service type.""" - EXTERNAL_NAME = "ExternalName" - """ExternalName service type.""" - - -class K8sVolumeTypeValues(Enum): - PERSISTENT_VOLUME_CLAIM = "persistentVolumeClaim" - """A [persistentVolumeClaim](https://kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim) volume.""" - CONFIG_MAP = "configMap" - """A [configMap](https://kubernetes.io/docs/concepts/storage/volumes/#configmap) volume.""" - DOWNWARD_API = "downwardAPI" - """A [downwardAPI](https://kubernetes.io/docs/concepts/storage/volumes/#downwardapi) volume.""" - EMPTY_DIR = "emptyDir" - """An [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) volume.""" - SECRET = "secret" - """A [secret](https://kubernetes.io/docs/concepts/storage/volumes/#secret) volume.""" - LOCAL = "local" - """A [local](https://kubernetes.io/docs/concepts/storage/volumes/#local) volume.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py deleted file mode 100644 index df275c9144f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/linux_attributes.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -LINUX_MEMORY_SLAB_STATE: Final = "linux.memory.slab.state" -""" -Deprecated: Replaced by `system.memory.linux.slab.state`. -""" - - -@deprecated("The attribute linux.memory.slab.state is deprecated - Replaced by `system.memory.linux.slab.state`") -class LinuxMemorySlabStateValues(Enum): - RECLAIMABLE = "reclaimable" - """reclaimable.""" - UNRECLAIMABLE = "unreclaimable" - """unreclaimable.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py deleted file mode 100644 index 30264071c20..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/log_attributes.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -LOG_FILE_NAME: Final = "log.file.name" -""" -The basename of the file. -""" - -LOG_FILE_NAME_RESOLVED: Final = "log.file.name_resolved" -""" -The basename of the file, with symlinks resolved. -""" - -LOG_FILE_PATH: Final = "log.file.path" -""" -The full path to the file. -""" - -LOG_FILE_PATH_RESOLVED: Final = "log.file.path_resolved" -""" -The full path to the file, with symlinks resolved. -""" - -LOG_IOSTREAM: Final = "log.iostream" -""" -The stream associated with the log. See below for a list of well-known values. -""" - -LOG_RECORD_ORIGINAL: Final = "log.record.original" -""" -The complete original Log Record. -Note: This value MAY be added when processing a Log Record which was originally transmitted as a string or equivalent data type AND the Body field of the Log Record does not contain the same value. (e.g. a syslog or a log record read from a file.). -""" - -LOG_RECORD_UID: Final = "log.record.uid" -""" -A unique identifier for the Log Record. -Note: If an ID is provided, other log records with the same ID will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. -The ID MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. -""" - - -class LogIostreamValues(Enum): - STDOUT = "stdout" - """Logs from stdout stream.""" - STDERR = "stderr" - """Events from stderr stream.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py deleted file mode 100644 index bfa8d1969f3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mainframe_attributes.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -MAINFRAME_LPAR_NAME: Final = "mainframe.lpar.name" -""" -Name of the logical partition that hosts a systems with a mainframe operating system. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py deleted file mode 100644 index 28480b6027b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/mcp_attributes.py +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -MCP_METHOD_NAME: Final = "mcp.method.name" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -MCP_PROTOCOL_VERSION: Final = "mcp.protocol.version" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -MCP_RESOURCE_URI: Final = "mcp.resource.uri" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -MCP_SESSION_ID: Final = "mcp.session.id" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -@deprecated( - "The attribute mcp.method.name is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class McpMethodNameValues(Enum): - NOTIFICATIONS_CANCELLED = "notifications/cancelled" - """Notification cancelling a previously-issued request.""" - INITIALIZE = "initialize" - """Request to initialize the MCP client.""" - NOTIFICATIONS_INITIALIZED = "notifications/initialized" - """Notification indicating that the MCP client has been initialized.""" - NOTIFICATIONS_PROGRESS = "notifications/progress" - """Notification indicating the progress for a long-running operation.""" - PING = "ping" - """Request to check that the other party is still alive.""" - RESOURCES_LIST = "resources/list" - """Request to list resources available on server.""" - RESOURCES_TEMPLATES_LIST = "resources/templates/list" - """Request to list resource templates available on server.""" - RESOURCES_READ = "resources/read" - """Request to read a resource.""" - NOTIFICATIONS_RESOURCES_LIST_CHANGED = "notifications/resources/list_changed" - """Notification indicating that the list of resources has changed.""" - RESOURCES_SUBSCRIBE = "resources/subscribe" - """Request to subscribe to a resource.""" - RESOURCES_UNSUBSCRIBE = "resources/unsubscribe" - """Request to unsubscribe from resource updates.""" - NOTIFICATIONS_RESOURCES_UPDATED = "notifications/resources/updated" - """Notification indicating that a resource has been updated.""" - PROMPTS_LIST = "prompts/list" - """Request to list prompts available on server.""" - PROMPTS_GET = "prompts/get" - """Request to get a prompt.""" - NOTIFICATIONS_PROMPTS_LIST_CHANGED = "notifications/prompts/list_changed" - """Notification indicating that the list of prompts has changed.""" - TOOLS_LIST = "tools/list" - """Request to list tools available on server.""" - TOOLS_CALL = "tools/call" - """Request to call a tool.""" - NOTIFICATIONS_TOOLS_LIST_CHANGED = "notifications/tools/list_changed" - """Notification indicating that the list of tools has changed.""" - LOGGING_SET_LEVEL = "logging/setLevel" - """Request to set the logging level.""" - NOTIFICATIONS_MESSAGE = "notifications/message" - """Notification indicating that a message has been received.""" - SAMPLING_CREATE_MESSAGE = "sampling/createMessage" - """Request to create a sampling message.""" - COMPLETION_COMPLETE = "completion/complete" - """Request to complete a prompt.""" - ROOTS_LIST = "roots/list" - """Request to list roots available on server.""" - NOTIFICATIONS_ROOTS_LIST_CHANGED = "notifications/roots/list_changed" - """Notification indicating that the list of roots has changed.""" - ELICITATION_CREATE = "elicitation/create" - """Request from the server to elicit additional information from the user via the client.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py deleted file mode 100644 index 70db48e98cd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/message_attributes.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -MESSAGE_COMPRESSED_SIZE: Final = "message.compressed_size" -""" -Deprecated: Deprecated, no replacement at this time. -""" - -MESSAGE_ID: Final = "message.id" -""" -Deprecated: Deprecated, no replacement at this time. -""" - -MESSAGE_TYPE: Final = "message.type" -""" -Deprecated: Deprecated, no replacement at this time. -""" - -MESSAGE_UNCOMPRESSED_SIZE: Final = "message.uncompressed_size" -""" -Deprecated: Deprecated, no replacement at this time. -""" - - -@deprecated("The attribute message.type is deprecated - Deprecated, no replacement at this time") -class MessageTypeValues(Enum): - SENT = "SENT" - """sent.""" - RECEIVED = "RECEIVED" - """received.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py deleted file mode 100644 index 9f462f39a44..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/messaging_attributes.py +++ /dev/null @@ -1,327 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -MESSAGING_BATCH_MESSAGE_COUNT: Final = "messaging.batch.message_count" -""" -The number of messages sent, received, or processed in the scope of the batching operation. -Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. -""" - -MESSAGING_CLIENT_ID: Final = "messaging.client.id" -""" -A unique identifier for the client that consumes or produces a message. -""" - -MESSAGING_CONSUMER_GROUP_NAME: Final = "messaging.consumer.group.name" -""" -The name of the consumer group with which a consumer is associated. -Note: Semantic conventions for individual messaging systems SHOULD document whether `messaging.consumer.group.name` is applicable and what it means in the context of that system. -""" - -MESSAGING_DESTINATION_ANONYMOUS: Final = "messaging.destination.anonymous" -""" -A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). -""" - -MESSAGING_DESTINATION_NAME: Final = "messaging.destination.name" -""" -The message destination name. -Note: SHOULD uniquely identify a specific queue, topic or other entity within the broker. If -the broker doesn't have such notion, it SHOULD uniquely identify the broker. -""" - -MESSAGING_DESTINATION_PARTITION_ID: Final = "messaging.destination.partition.id" -""" -The identifier of the partition messages are sent to or received from, unique within the `messaging.destination.name`. -""" - -MESSAGING_DESTINATION_SUBSCRIPTION_NAME: Final = "messaging.destination.subscription.name" -""" -The name of the destination subscription from which a message is consumed. -Note: Semantic conventions for individual messaging systems SHOULD document whether `messaging.destination.subscription.name` is applicable and what it means in the context of that system. -""" - -MESSAGING_DESTINATION_TEMPLATE: Final = "messaging.destination.template" -""" -Low cardinality representation of the messaging destination name. -Note: Destination names could be constructed from templates. An example would be a destination name involving a username or product ID. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. -""" - -MESSAGING_DESTINATION_TEMPORARY: Final = "messaging.destination.temporary" -""" -A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. -""" - -MESSAGING_DESTINATION_PUBLISH_ANONYMOUS: Final = "messaging.destination_publish.anonymous" -""" -Deprecated: Removed. No replacement at this time. -""" - -MESSAGING_DESTINATION_PUBLISH_NAME: Final = "messaging.destination_publish.name" -""" -Deprecated: Removed. No replacement at this time. -""" - -MESSAGING_EVENTHUBS_CONSUMER_GROUP: Final = "messaging.eventhubs.consumer.group" -""" -Deprecated: Replaced by `messaging.consumer.group.name`. -""" - -MESSAGING_EVENTHUBS_MESSAGE_ENQUEUED_TIME: Final = "messaging.eventhubs.message.enqueued_time" -""" -The UTC epoch seconds at which the message has been accepted and stored in the entity. -""" - -MESSAGING_GCP_PUBSUB_MESSAGE_ACK_DEADLINE: Final = "messaging.gcp_pubsub.message.ack_deadline" -""" -The ack deadline in seconds set for the modify ack deadline request. -""" - -MESSAGING_GCP_PUBSUB_MESSAGE_ACK_ID: Final = "messaging.gcp_pubsub.message.ack_id" -""" -The ack ID for a given message. -""" - -MESSAGING_GCP_PUBSUB_MESSAGE_DELIVERY_ATTEMPT: Final = "messaging.gcp_pubsub.message.delivery_attempt" -""" -The delivery attempt for a given message. -""" - -MESSAGING_GCP_PUBSUB_MESSAGE_ORDERING_KEY: Final = "messaging.gcp_pubsub.message.ordering_key" -""" -The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. -""" - -MESSAGING_KAFKA_CLUSTER_ID: Final = "messaging.kafka.cluster.id" -""" -The Kafka cluster ID, obtained from the broker metadata exposed through the Kafka client (or AdminClient) API. -Note: The cluster ID is a unique identifier reported by the Kafka broker. It identifies the cluster independently of the individual brokers the client is configured to connect to, and remains stable even if broker hostnames, IP addresses, or ports change. -""" - -MESSAGING_KAFKA_CONSUMER_GROUP: Final = "messaging.kafka.consumer.group" -""" -Deprecated: Replaced by `messaging.consumer.group.name`. -""" - -MESSAGING_KAFKA_DESTINATION_PARTITION: Final = "messaging.kafka.destination.partition" -""" -Deprecated: Record string representation of the partition ID in `messaging.destination.partition.id` attribute. -""" - -MESSAGING_KAFKA_MESSAGE_KEY: Final = "messaging.kafka.message.key" -""" -Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. -Note: If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. -""" - -MESSAGING_KAFKA_MESSAGE_OFFSET: Final = "messaging.kafka.message.offset" -""" -Deprecated: Replaced by `messaging.kafka.offset`. -""" - -MESSAGING_KAFKA_MESSAGE_TOMBSTONE: Final = "messaging.kafka.message.tombstone" -""" -A boolean that is true if the message is a tombstone. -""" - -MESSAGING_KAFKA_OFFSET: Final = "messaging.kafka.offset" -""" -The offset of a record in the corresponding Kafka partition. -""" - -MESSAGING_MESSAGE_BODY_SIZE: Final = "messaging.message.body.size" -""" -The size of the message body in bytes. -Note: This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed -body size should be used. -""" - -MESSAGING_MESSAGE_CONVERSATION_ID: Final = "messaging.message.conversation_id" -""" -The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". -""" - -MESSAGING_MESSAGE_ENVELOPE_SIZE: Final = "messaging.message.envelope.size" -""" -The size of the message body and metadata in bytes. -Note: This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed -size should be used. -""" - -MESSAGING_MESSAGE_ID: Final = "messaging.message.id" -""" -A value used by the messaging system as an identifier for the message, represented as a string. -""" - -MESSAGING_OPERATION: Final = "messaging.operation" -""" -Deprecated: Replaced by `messaging.operation.type`. -""" - -MESSAGING_OPERATION_NAME: Final = "messaging.operation.name" -""" -The system-specific name of the messaging operation. -""" - -MESSAGING_OPERATION_TYPE: Final = "messaging.operation.type" -""" -A string identifying the type of the messaging operation. -Note: If a custom value is used, it MUST be of low cardinality. -""" - -MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY: Final = "messaging.rabbitmq.destination.routing_key" -""" -RabbitMQ message routing key. -""" - -MESSAGING_RABBITMQ_MESSAGE_DELIVERY_TAG: Final = "messaging.rabbitmq.message.delivery_tag" -""" -RabbitMQ message delivery tag. -""" - -MESSAGING_ROCKETMQ_CLIENT_GROUP: Final = "messaging.rocketmq.client_group" -""" -Deprecated: Replaced by `messaging.consumer.group.name` on the consumer spans. No replacement for producer spans. -""" - -MESSAGING_ROCKETMQ_CONSUMPTION_MODEL: Final = "messaging.rocketmq.consumption_model" -""" -Model of message consumption. This only applies to consumer spans. -""" - -MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL: Final = "messaging.rocketmq.message.delay_time_level" -""" -The delay time level for delay message, which determines the message delay time. -""" - -MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP: Final = "messaging.rocketmq.message.delivery_timestamp" -""" -The timestamp in milliseconds that the delay message is expected to be delivered to consumer. -""" - -MESSAGING_ROCKETMQ_MESSAGE_GROUP: Final = "messaging.rocketmq.message.group" -""" -It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. -""" - -MESSAGING_ROCKETMQ_MESSAGE_KEYS: Final = "messaging.rocketmq.message.keys" -""" -Key(s) of message, another way to mark message besides message ID. -""" - -MESSAGING_ROCKETMQ_MESSAGE_TAG: Final = "messaging.rocketmq.message.tag" -""" -The secondary classifier of message besides topic. -""" - -MESSAGING_ROCKETMQ_MESSAGE_TYPE: Final = "messaging.rocketmq.message.type" -""" -Type of message. -""" - -MESSAGING_ROCKETMQ_NAMESPACE: Final = "messaging.rocketmq.namespace" -""" -Namespace of RocketMQ resources, resources in different namespaces are individual. -""" - -MESSAGING_SERVICEBUS_DESTINATION_SUBSCRIPTION_NAME: Final = "messaging.servicebus.destination.subscription_name" -""" -Deprecated: Replaced by `messaging.destination.subscription.name`. -""" - -MESSAGING_SERVICEBUS_DISPOSITION_STATUS: Final = "messaging.servicebus.disposition_status" -""" -Describes the [settlement type](https://learn.microsoft.com/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock). -""" - -MESSAGING_SERVICEBUS_MESSAGE_DELIVERY_COUNT: Final = "messaging.servicebus.message.delivery_count" -""" -Number of deliveries that have been attempted for this message. -""" - -MESSAGING_SERVICEBUS_MESSAGE_ENQUEUED_TIME: Final = "messaging.servicebus.message.enqueued_time" -""" -The UTC epoch seconds at which the message has been accepted and stored in the entity. -""" - -MESSAGING_SYSTEM: Final = "messaging.system" -""" -The messaging system as identified by the client instrumentation. -Note: The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge. -""" - - -class MessagingOperationTypeValues(Enum): - CREATE = "create" - """A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch sending scenarios.""" - SEND = "send" - """One or more messages are provided for sending to an intermediary. If a single message is sent, the context of the "Send" span can be used as the creation context and no "Create" span needs to be created.""" - RECEIVE = "receive" - """One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages.""" - PROCESS = "process" - """One or more messages are processed by a consumer.""" - SETTLE = "settle" - """One or more messages are settled.""" - DELIVER = "deliver" - """Deprecated: Replaced by `process`.""" - PUBLISH = "publish" - """Deprecated: Replaced by `send`.""" - - -class MessagingRocketmqConsumptionModelValues(Enum): - CLUSTERING = "clustering" - """Clustering consumption model.""" - BROADCASTING = "broadcasting" - """Broadcasting consumption model.""" - - -class MessagingRocketmqMessageTypeValues(Enum): - NORMAL = "normal" - """Normal message.""" - FIFO = "fifo" - """FIFO message.""" - DELAY = "delay" - """Delay message.""" - TRANSACTION = "transaction" - """Transaction message.""" - - -class MessagingServicebusDispositionStatusValues(Enum): - COMPLETE = "complete" - """Message is completed.""" - ABANDON = "abandon" - """Message is abandoned.""" - DEAD_LETTER = "dead_letter" - """Message is sent to dead letter queue.""" - DEFER = "defer" - """Message is deferred.""" - - -class MessagingSystemValues(Enum): - ACTIVEMQ = "activemq" - """Apache ActiveMQ.""" - AWS_SNS = "aws.sns" - """Amazon Simple Notification Service (SNS).""" - AWS_SQS = "aws_sqs" - """Amazon Simple Queue Service (SQS).""" - EVENTGRID = "eventgrid" - """Azure Event Grid.""" - EVENTHUBS = "eventhubs" - """Azure Event Hubs.""" - SERVICEBUS = "servicebus" - """Azure Service Bus.""" - GCP_PUBSUB = "gcp_pubsub" - """Google Cloud Pub/Sub.""" - JMS = "jms" - """Java Message Service.""" - KAFKA = "kafka" - """Apache Kafka.""" - RABBITMQ = "rabbitmq" - """RabbitMQ.""" - ROCKETMQ = "rocketmq" - """Apache RocketMQ.""" - PULSAR = "pulsar" - """Apache Pulsar.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py deleted file mode 100644 index fab03d197c0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/net_attributes.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -NET_HOST_IP: Final = "net.host.ip" -""" -Deprecated: Replaced by `network.local.address`. -""" - -NET_HOST_NAME: Final = "net.host.name" -""" -Deprecated: Replaced by `server.address`. -""" - -NET_HOST_PORT: Final = "net.host.port" -""" -Deprecated: Replaced by `server.port`. -""" - -NET_PEER_IP: Final = "net.peer.ip" -""" -Deprecated: Replaced by `network.peer.address`. -""" - -NET_PEER_NAME: Final = "net.peer.name" -""" -Deprecated: Replaced by `server.address` on client spans and `client.address` on server spans. -""" - -NET_PEER_PORT: Final = "net.peer.port" -""" -Deprecated: Replaced by `server.port` on client spans and `client.port` on server spans. -""" - -NET_PROTOCOL_NAME: Final = "net.protocol.name" -""" -Deprecated: Replaced by `network.protocol.name`. -""" - -NET_PROTOCOL_VERSION: Final = "net.protocol.version" -""" -Deprecated: Replaced by `network.protocol.version`. -""" - -NET_SOCK_FAMILY: Final = "net.sock.family" -""" -Deprecated: Split to `network.transport` and `network.type`. -""" - -NET_SOCK_HOST_ADDR: Final = "net.sock.host.addr" -""" -Deprecated: Replaced by `network.local.address`. -""" - -NET_SOCK_HOST_PORT: Final = "net.sock.host.port" -""" -Deprecated: Replaced by `network.local.port`. -""" - -NET_SOCK_PEER_ADDR: Final = "net.sock.peer.addr" -""" -Deprecated: Replaced by `network.peer.address`. -""" - -NET_SOCK_PEER_NAME: Final = "net.sock.peer.name" -""" -Deprecated: Removed. No replacement at this time. -""" - -NET_SOCK_PEER_PORT: Final = "net.sock.peer.port" -""" -Deprecated: Replaced by `network.peer.port`. -""" - -NET_TRANSPORT: Final = "net.transport" -""" -Deprecated: Replaced by `network.transport`. -""" - - -@deprecated("The attribute net.sock.family is deprecated - Split to `network.transport` and `network.type`") -class NetSockFamilyValues(Enum): - INET = "inet" - """IPv4 address.""" - INET6 = "inet6" - """IPv6 address.""" - UNIX = "unix" - """UNIX domain socket path.""" - - -@deprecated("The attribute net.transport is deprecated - Replaced by `network.transport`") -class NetTransportValues(Enum): - IP_TCP = "ip_tcp" - """ip_tcp.""" - IP_UDP = "ip_udp" - """ip_udp.""" - PIPE = "pipe" - """Named or anonymous pipe.""" - INPROC = "inproc" - """In-process communication.""" - OTHER = "other" - """Something else (non IP-based).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py deleted file mode 100644 index 823b46159e3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/network_attributes.py +++ /dev/null @@ -1,209 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -NETWORK_CARRIER_ICC: Final = "network.carrier.icc" -""" -The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. -""" - -NETWORK_CARRIER_MCC: Final = "network.carrier.mcc" -""" -The mobile carrier country code. -""" - -NETWORK_CARRIER_MNC: Final = "network.carrier.mnc" -""" -The mobile carrier network code. -""" - -NETWORK_CARRIER_NAME: Final = "network.carrier.name" -""" -The name of the mobile carrier. -""" - -NETWORK_CONNECTION_STATE: Final = "network.connection.state" -""" -The state of network connection. -Note: Connection states are defined as part of the [rfc9293](https://datatracker.ietf.org/doc/html/rfc9293#section-3.3.2). -""" - -NETWORK_CONNECTION_SUBTYPE: Final = "network.connection.subtype" -""" -This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a Wi-Fi connection. -""" - -NETWORK_CONNECTION_TYPE: Final = "network.connection.type" -""" -The internet connection type. -""" - -NETWORK_INTERFACE_NAME: Final = "network.interface.name" -""" -The network interface name. -""" - -NETWORK_IO_DIRECTION: Final = "network.io.direction" -""" -The direction of traffic from the perspective of the observing host's physical or virtual network interface. It should not be used to represent the logical direction of a stateful connection or network flow. -""" - -NETWORK_LOCAL_ADDRESS: Final = "network.local.address" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_LOCAL_ADDRESS`. -""" - -NETWORK_LOCAL_PORT: Final = "network.local.port" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_LOCAL_PORT`. -""" - -NETWORK_PEER_ADDRESS: Final = "network.peer.address" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PEER_ADDRESS`. -""" - -NETWORK_PEER_PORT: Final = "network.peer.port" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PEER_PORT`. -""" - -NETWORK_PROTOCOL_NAME: Final = "network.protocol.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PROTOCOL_NAME`. -""" - -NETWORK_PROTOCOL_VERSION: Final = "network.protocol.version" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_PROTOCOL_VERSION`. -""" - -NETWORK_TRANSPORT: Final = "network.transport" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_TRANSPORT`. -""" - -NETWORK_TYPE: Final = "network.type" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NETWORK_TYPE`. -""" - - -class NetworkConnectionStateValues(Enum): - CLOSED = "closed" - """closed.""" - CLOSE_WAIT = "close_wait" - """close_wait.""" - CLOSING = "closing" - """closing.""" - ESTABLISHED = "established" - """established.""" - FIN_WAIT_1 = "fin_wait_1" - """fin_wait_1.""" - FIN_WAIT_2 = "fin_wait_2" - """fin_wait_2.""" - LAST_ACK = "last_ack" - """last_ack.""" - LISTEN = "listen" - """listen.""" - SYN_RECEIVED = "syn_received" - """syn_received.""" - SYN_SENT = "syn_sent" - """syn_sent.""" - TIME_WAIT = "time_wait" - """time_wait.""" - - -class NetworkConnectionSubtypeValues(Enum): - GPRS = "gprs" - """GPRS.""" - EDGE = "edge" - """EDGE.""" - UMTS = "umts" - """UMTS.""" - CDMA = "cdma" - """CDMA.""" - EVDO_0 = "evdo_0" - """EVDO Rel. 0.""" - EVDO_A = "evdo_a" - """EVDO Rev. A.""" - CDMA2000_1XRTT = "cdma2000_1xrtt" - """CDMA2000 1XRTT.""" - HSDPA = "hsdpa" - """HSDPA.""" - HSUPA = "hsupa" - """HSUPA.""" - HSPA = "hspa" - """HSPA.""" - IDEN = "iden" - """IDEN.""" - EVDO_B = "evdo_b" - """EVDO Rev. B.""" - LTE = "lte" - """LTE.""" - EHRPD = "ehrpd" - """EHRPD.""" - HSPAP = "hspap" - """HSPAP.""" - GSM = "gsm" - """GSM.""" - TD_SCDMA = "td_scdma" - """TD-SCDMA.""" - IWLAN = "iwlan" - """IWLAN.""" - NR = "nr" - """5G NR (New Radio).""" - NRNSA = "nrnsa" - """5G NRNSA (New Radio Non-Standalone).""" - LTE_CA = "lte_ca" - """LTE CA.""" - - -class NetworkConnectionTypeValues(Enum): - WIFI = "wifi" - """Wi-Fi.""" - WIRED = "wired" - """wired.""" - CELL = "cell" - """cell.""" - UNAVAILABLE = "unavailable" - """unavailable.""" - UNKNOWN = "unknown" - """unknown.""" - - -class NetworkIoDirectionValues(Enum): - TRANSMIT = "transmit" - """transmit.""" - RECEIVE = "receive" - """receive.""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues`." -) -class NetworkTransportValues(Enum): - TCP = "tcp" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.TCP`.""" - UDP = "udp" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.UDP`.""" - PIPE = "pipe" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.PIPE`.""" - UNIX = "unix" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.UNIX`.""" - QUIC = "quic" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTransportValues.QUIC`.""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues`." -) -class NetworkTypeValues(Enum): - IPV4 = "ipv4" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues.IPV4`.""" - IPV6 = "ipv6" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.network_attributes.NetworkTypeValues.IPV6`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py deleted file mode 100644 index 3ef1dd50117..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/nfs_attributes.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -NFS_OPERATION_NAME: Final = "nfs.operation.name" -""" -NFSv4+ operation name. -""" - -NFS_SERVER_REPCACHE_STATUS: Final = "nfs.server.repcache.status" -""" -Linux: one of "hit" (NFSD_STATS_RC_HITS), "miss" (NFSD_STATS_RC_MISSES), or "nocache" (NFSD_STATS_RC_NOCACHE -- uncacheable). -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py deleted file mode 100644 index c3342c0fec1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oci_attributes.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -OCI_MANIFEST_DIGEST: Final = "oci.manifest.digest" -""" -The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. -Note: Follows [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md), and specifically the [Digest property](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests). -An example can be found in [Example Image Manifest](https://github.com/opencontainers/image-spec/blob/main/manifest.md#example-image-manifest). -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py deleted file mode 100644 index eecf84ceae5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/onc_rpc_attributes.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -ONC_RPC_PROCEDURE_NAME: Final = "onc_rpc.procedure.name" -""" -ONC/Sun RPC procedure name. -""" - -ONC_RPC_PROCEDURE_NUMBER: Final = "onc_rpc.procedure.number" -""" -ONC/Sun RPC procedure number. -""" - -ONC_RPC_PROGRAM_NAME: Final = "onc_rpc.program.name" -""" -ONC/Sun RPC program name. -""" - -ONC_RPC_VERSION: Final = "onc_rpc.version" -""" -ONC/Sun RPC program version. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py deleted file mode 100644 index df471c66079..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openai_attributes.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -OPENAI_API_TYPE: Final = "openai.api.type" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -OPENAI_REQUEST_SERVICE_TIER: Final = "openai.request.service_tier" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -OPENAI_RESPONSE_SERVICE_TIER: Final = "openai.response.service_tier" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - -OPENAI_RESPONSE_SYSTEM_FINGERPRINT: Final = "openai.response.system_fingerprint" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -@deprecated( - "The attribute openai.api.type is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class OpenaiApiTypeValues(Enum): - CHAT_COMPLETIONS = "chat_completions" - """The OpenAI [Chat Completions API](https://developers.openai.com/api/reference/chat-completions/overview).""" - RESPONSES = "responses" - """The OpenAI [Responses API](https://developers.openai.com/api/reference/responses/overview).""" - - -@deprecated( - "The attribute openai.request.service_tier is deprecated - Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai)" -) -class OpenaiRequestServiceTierValues(Enum): - AUTO = "auto" - """The system will utilize scale tier credits until they are exhausted.""" - DEFAULT = "default" - """The system will utilize the default scale tier.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py deleted file mode 100644 index db1abf01285..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/openshift_attributes.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -OPENSHIFT_CLUSTERQUOTA_NAME: Final = "openshift.clusterquota.name" -""" -The name of the cluster quota. -""" - -OPENSHIFT_CLUSTERQUOTA_UID: Final = "openshift.clusterquota.uid" -""" -The UID of the cluster quota. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py deleted file mode 100644 index 5237de935fe..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/opentracing_attributes.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -OPENTRACING_REF_TYPE: Final = "opentracing.ref_type" -""" -Parent-child Reference type. -Note: The causal relationship between a child Span and a parent Span. -""" - - -class OpentracingRefTypeValues(Enum): - CHILD_OF = "child_of" - """The parent Span depends on the child Span in some capacity.""" - FOLLOWS_FROM = "follows_from" - """The parent Span doesn't depend in any way on the result of the child Span.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py deleted file mode 100644 index 191be10f98a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_attributes.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -ORACLE_DB_DOMAIN: Final = "oracle.db.domain" -""" -The database domain associated with the connection. -Note: This attribute SHOULD be set to the value of the `DB_DOMAIN` initialization parameter, -as exposed in `v$parameter`. `DB_DOMAIN` defines the domain portion of the global -database name and SHOULD be configured when a database is, or may become, part of a -distributed environment. Its value consists of one or more valid identifiers -(alphanumeric ASCII characters) separated by periods. -""" - -ORACLE_DB_INSTANCE_NAME: Final = "oracle.db.instance.name" -""" -The instance name associated with the connection in an Oracle Real Application Clusters environment. -Note: There can be multiple instances associated with a single database service. It indicates the -unique instance name to which the connection is currently bound. For non-RAC databases, this value -defaults to the `oracle.db.name`. -""" - -ORACLE_DB_NAME: Final = "oracle.db.name" -""" -The database name associated with the connection. -Note: This attribute SHOULD be set to the value of the parameter `DB_NAME` exposed in `v$parameter`. -""" - -ORACLE_DB_PDB: Final = "oracle.db.pdb" -""" -The pluggable database (PDB) name associated with the connection. -Note: This attribute SHOULD reflect the PDB that the session is currently connected to. -If instrumentation cannot reliably obtain the active PDB name for each operation -without issuing an additional query (such as `SELECT SYS_CONTEXT`), it is -RECOMMENDED to fall back to the PDB name specified at connection establishment. -""" - -ORACLE_DB_SERVICE: Final = "oracle.db.service" -""" -The service name currently associated with the database connection. -Note: The effective service name for a connection can change during its lifetime, -for example after executing SQL, `ALTER SESSION`. If an instrumentation cannot reliably -obtain the current service name for each operation without issuing an additional -query (such as `SELECT SYS_CONTEXT`), it is RECOMMENDED to fall back to the -service name originally provided at connection establishment. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py deleted file mode 100644 index a829590b83f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/oracle_cloud_attributes.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -ORACLE_CLOUD_REALM: Final = "oracle_cloud.realm" -""" -The OCI realm identifier that indicates the isolated partition in which the tenancy and its resources reside. -Note: See [OCI documentation on realms](https://docs.oracle.com/iaas/Content/General/Concepts/regions.htm). -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py deleted file mode 100644 index b10d4bdd8d9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/os_attributes.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -OS_BUILD_ID: Final = "os.build_id" -""" -Unique identifier for a particular build or compilation of the operating system. -""" - -OS_DESCRIPTION: Final = "os.description" -""" -Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. -""" - -OS_NAME: Final = "os.name" -""" -Human readable operating system name. -""" - -OS_TYPE: Final = "os.type" -""" -The operating system type. -""" - -OS_VERSION: Final = "os.version" -""" -The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). -""" - - -class OsTypeValues(Enum): - WINDOWS = "windows" - """Microsoft Windows.""" - LINUX = "linux" - """Linux.""" - DARWIN = "darwin" - """Apple Darwin.""" - FREEBSD = "freebsd" - """FreeBSD.""" - NETBSD = "netbsd" - """NetBSD.""" - OPENBSD = "openbsd" - """OpenBSD.""" - DRAGONFLYBSD = "dragonflybsd" - """DragonFly BSD.""" - HPUX = "hpux" - """HP-UX (Hewlett Packard UNIX).""" - AIX = "aix" - """AIX (Advanced Interactive eXecutive).""" - SOLARIS = "solaris" - """SunOS, Oracle Solaris.""" - Z_OS = "z_os" - """Deprecated: Replaced by `zos`.""" - ZOS = "zos" - """IBM z/OS.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py deleted file mode 100644 index 46f98750b24..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/otel_attributes.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -OTEL_COMPONENT_NAME: Final = "otel.component.name" -""" -A name uniquely identifying the instance of the OpenTelemetry component within its containing SDK instance. -Note: Implementations SHOULD ensure a low cardinality for this attribute, even across application or SDK restarts. -E.g. implementations MUST NOT use UUIDs as values for this attribute. - -Implementations MAY achieve these goals by following a `/` pattern, e.g. `batching_span_processor/0`. -Hereby `otel.component.type` refers to the corresponding attribute value of the component. - -The value of `instance-counter` MAY be automatically assigned by the component and uniqueness within the enclosing SDK instance MUST be guaranteed. -For example, `` MAY be implemented by using a monotonically increasing counter (starting with `0`), which is incremented every time an -instance of the given component type is started. - -With this implementation, for example the first Batching Span Processor would have `batching_span_processor/0` -as `otel.component.name`, the second one `batching_span_processor/1` and so on. -These values will therefore be reused in the case of an application restart. -""" - -OTEL_COMPONENT_TYPE: Final = "otel.component.type" -""" -A name identifying the type of the OpenTelemetry component. -Note: If none of the standardized values apply, implementations SHOULD use the language-defined name of the type. -E.g. for Java the fully qualified classname SHOULD be used in this case. -""" - -OTEL_EVENT_NAME: Final = "otel.event.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_EVENT_NAME`. -""" - -OTEL_LIBRARY_NAME: Final = "otel.library.name" -""" -Deprecated: Replaced by `otel.scope.name`. -""" - -OTEL_LIBRARY_VERSION: Final = "otel.library.version" -""" -Deprecated: Replaced by `otel.scope.version`. -""" - -OTEL_SCOPE_NAME: Final = "otel.scope.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_SCOPE_NAME`. -""" - -OTEL_SCOPE_SCHEMA_URL: Final = "otel.scope.schema_url" -""" -The schema URL of the instrumentation scope. -""" - -OTEL_SCOPE_VERSION: Final = "otel.scope.version" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_SCOPE_VERSION`. -""" - -OTEL_SPAN_PARENT_ORIGIN: Final = "otel.span.parent.origin" -""" -Determines whether the span has a parent span, and if so, [whether it is a remote parent](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote). -""" - -OTEL_SPAN_SAMPLING_RESULT: Final = "otel.span.sampling_result" -""" -The result value of the sampler for this span. -""" - -OTEL_STATUS_CODE: Final = "otel.status_code" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_STATUS_CODE`. -""" - -OTEL_STATUS_DESCRIPTION: Final = "otel.status_description" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OTEL_STATUS_DESCRIPTION`. -""" - - -class OtelComponentTypeValues(Enum): - BATCHING_SPAN_PROCESSOR = "batching_span_processor" - """The built-in SDK batching span processor.""" - SIMPLE_SPAN_PROCESSOR = "simple_span_processor" - """The built-in SDK simple span processor.""" - BATCHING_LOG_PROCESSOR = "batching_log_processor" - """The built-in SDK batching log record processor.""" - SIMPLE_LOG_PROCESSOR = "simple_log_processor" - """The built-in SDK simple log record processor.""" - OTLP_GRPC_SPAN_EXPORTER = "otlp_grpc_span_exporter" - """OTLP span exporter over gRPC with protobuf serialization.""" - OTLP_HTTP_SPAN_EXPORTER = "otlp_http_span_exporter" - """OTLP span exporter over HTTP with protobuf serialization.""" - OTLP_HTTP_JSON_SPAN_EXPORTER = "otlp_http_json_span_exporter" - """OTLP span exporter over HTTP with JSON serialization.""" - ZIPKIN_HTTP_SPAN_EXPORTER = "zipkin_http_span_exporter" - """Zipkin span exporter over HTTP.""" - OTLP_GRPC_LOG_EXPORTER = "otlp_grpc_log_exporter" - """OTLP log record exporter over gRPC with protobuf serialization.""" - OTLP_HTTP_LOG_EXPORTER = "otlp_http_log_exporter" - """OTLP log record exporter over HTTP with protobuf serialization.""" - OTLP_HTTP_JSON_LOG_EXPORTER = "otlp_http_json_log_exporter" - """OTLP log record exporter over HTTP with JSON serialization.""" - PERIODIC_METRIC_READER = "periodic_metric_reader" - """The built-in SDK periodically exporting metric reader.""" - OTLP_GRPC_METRIC_EXPORTER = "otlp_grpc_metric_exporter" - """OTLP metric exporter over gRPC with protobuf serialization.""" - OTLP_HTTP_METRIC_EXPORTER = "otlp_http_metric_exporter" - """OTLP metric exporter over HTTP with protobuf serialization.""" - OTLP_HTTP_JSON_METRIC_EXPORTER = "otlp_http_json_metric_exporter" - """OTLP metric exporter over HTTP with JSON serialization.""" - PROMETHEUS_HTTP_TEXT_METRIC_EXPORTER = "prometheus_http_text_metric_exporter" - """Prometheus metric exporter over HTTP with the default text-based format.""" - - -class OtelSpanParentOriginValues(Enum): - NONE = "none" - """The span does not have a parent, it is a root span.""" - LOCAL = "local" - """The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is false.""" - REMOTE = "remote" - """The span has a parent and the parent's span context [isRemote()](https://opentelemetry.io/docs/specs/otel/trace/api/#isremote) is true.""" - - -class OtelSpanSamplingResultValues(Enum): - DROP = "DROP" - """The span is not sampled and not recording.""" - RECORD_ONLY = "RECORD_ONLY" - """The span is not sampled, but recording.""" - RECORD_AND_SAMPLE = "RECORD_AND_SAMPLE" - """The span is sampled and recording.""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues`." -) -class OtelStatusCodeValues(Enum): - OK = "OK" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues.OK`.""" - ERROR = "ERROR" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.otel_attributes.OtelStatusCodeValues.ERROR`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py deleted file mode 100644 index a447aaa6bb4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/other_attributes.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -STATE: Final = "state" -""" -Deprecated: Replaced by `db.client.connection.state`. -""" - - -@deprecated("The attribute state is deprecated - Replaced by `db.client.connection.state`") -class StateValues(Enum): - IDLE = "idle" - """idle.""" - USED = "used" - """used.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py deleted file mode 100644 index 27ff455a696..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/peer_attributes.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -PEER_SERVICE: Final = "peer.service" -""" -Deprecated: Replaced by `service.peer.name`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py deleted file mode 100644 index cd3fa908184..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pool_attributes.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -POOL_NAME: Final = "pool.name" -""" -Deprecated: Replaced by `db.client.connection.pool.name`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py deleted file mode 100644 index f99c8a3b9eb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/pprof_attributes.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -PPROF_LOCATION_IS_FOLDED: Final = "pprof.location.is_folded" -""" -Provides an indication that multiple symbols map to this location's address, for example due to identical code folding by the linker. In that case the line information represents one of the multiple symbols. This field must be recomputed when the symbolization state of the profile changes. -""" - -PPROF_MAPPING_HAS_FILENAMES: Final = "pprof.mapping.has_filenames" -""" -Indicates that there are filenames related to this mapping. -""" - -PPROF_MAPPING_HAS_FUNCTIONS: Final = "pprof.mapping.has_functions" -""" -Indicates that there are functions related to this mapping. -""" - -PPROF_MAPPING_HAS_INLINE_FRAMES: Final = "pprof.mapping.has_inline_frames" -""" -Indicates that there are inline frames related to this mapping. -""" - -PPROF_MAPPING_HAS_LINE_NUMBERS: Final = "pprof.mapping.has_line_numbers" -""" -Indicates that there are line numbers related to this mapping. -""" - -PPROF_PROFILE_COMMENT: Final = "pprof.profile.comment" -""" -Free-form text associated with the profile. This field should not be used to store any machine-readable information, it is only for human-friendly content. -""" - -PPROF_PROFILE_DOC_URL: Final = "pprof.profile.doc_url" -""" -Documentation link for this profile type. -Note: The URL must be absolute and may be missing if the profile was generated by code that did not supply a link. -""" - -PPROF_PROFILE_DROP_FRAMES: Final = "pprof.profile.drop_frames" -""" -Frames with Function.function_name fully matching the regular expression will be dropped from the samples, along with their successors. -""" - -PPROF_PROFILE_KEEP_FRAMES: Final = "pprof.profile.keep_frames" -""" -Frames with Function.function_name fully matching the regular expression will be kept, even if it matches drop_frames. -""" - -PPROF_SCOPE_DEFAULT_SAMPLE_TYPE: Final = "pprof.scope.default_sample_type" -""" -Records the pprof's default_sample_type in the original profile. Not set if the default sample type was missing. -Note: This attribute, if present, MUST be set at the scope level (resource_profiles[].scope_profiles[].scope.attributes[]). -""" - -PPROF_SCOPE_SAMPLE_TYPE_ORDER: Final = "pprof.scope.sample_type_order" -""" -Records the indexes of the sample types in the original profile. -Note: This attribute, if present, MUST be set at the scope level (resource_profiles[].scope_profiles[].scope.attributes[]). -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py deleted file mode 100644 index a548988633a..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/process_attributes.py +++ /dev/null @@ -1,253 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -PROCESS_ARGS_COUNT: Final = "process.args_count" -""" -Length of the process.command_args array. -Note: This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity. -""" - -PROCESS_COMMAND: Final = "process.command" -""" -The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. -""" - -PROCESS_COMMAND_ARGS: Final = "process.command_args" -""" -All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. SHOULD NOT be collected by default unless there is sanitization that excludes sensitive data. -""" - -PROCESS_COMMAND_LINE: Final = "process.command_line" -""" -The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. SHOULD NOT be collected by default unless there is sanitization that excludes sensitive data. -""" - -PROCESS_CONTEXT_SWITCH_TYPE: Final = "process.context_switch.type" -""" -Specifies whether the context switches for this data point were voluntary or involuntary. -""" - -PROCESS_CPU_STATE: Final = "process.cpu.state" -""" -Deprecated: Replaced by `cpu.mode`. -""" - -PROCESS_CREATION_TIME: Final = "process.creation.time" -""" -The date and time the process was created, in ISO 8601 format. -""" - -PROCESS_ENVIRONMENT_VARIABLE_TEMPLATE: Final = "process.environment_variable" -""" -Process environment variables, `` being the environment variable name, the value being the environment variable value. -Note: Examples: - -- an environment variable `USER` with value `"ubuntu"` SHOULD be recorded -as the `process.environment_variable.USER` attribute with value `"ubuntu"`. - -- an environment variable `PATH` with value `"/usr/local/bin:/usr/bin"` -SHOULD be recorded as the `process.environment_variable.PATH` attribute -with value `"/usr/local/bin:/usr/bin"`. -""" - -PROCESS_EXECUTABLE_BUILD_ID_GNU: Final = "process.executable.build_id.gnu" -""" -The GNU build ID as found in the `.note.gnu.build-id` ELF section (hex string). -""" - -PROCESS_EXECUTABLE_BUILD_ID_GO: Final = "process.executable.build_id.go" -""" -The Go build ID as retrieved by `go tool buildid `. -""" - -PROCESS_EXECUTABLE_BUILD_ID_HTLHASH: Final = "process.executable.build_id.htlhash" -""" -Deterministic build ID for executables. -Note: GNU and Go build IDs may be stripped or unavailable in some environments -(e.g., Alpine Linux, Docker images). This attribute provides a deterministic -build ID computed by hashing the first and last 4096 bytes of the file -along with its length: - -``` -Input ← Concat(File[:4096], File[-4096:], BigEndianUInt64(Len(File))) -Digest ← SHA256(Input) -BuildID ← Digest[:16] -``` - -The result is the first 16 bytes (128 bits) of the SHA256 digest, -represented as a hex string. -""" - -PROCESS_EXECUTABLE_BUILD_ID_PROFILING: Final = "process.executable.build_id.profiling" -""" -Deprecated: Replaced by `process.executable.build_id.htlhash`. -""" - -PROCESS_EXECUTABLE_NAME: Final = "process.executable.name" -""" -The name of the process executable. On Linux based systems, this SHOULD be set to the base name of the target of `/proc/[pid]/exe`. On Windows, this SHOULD be set to the base name of `GetProcessImageFileNameW`. -""" - -PROCESS_EXECUTABLE_PATH: Final = "process.executable.path" -""" -The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. -""" - -PROCESS_EXIT_CODE: Final = "process.exit.code" -""" -The exit code of the process. -""" - -PROCESS_EXIT_TIME: Final = "process.exit.time" -""" -The date and time the process exited, in ISO 8601 format. -""" - -PROCESS_GROUP_LEADER_PID: Final = "process.group_leader.pid" -""" -The PID of the process's group leader. This is also the process group ID (PGID) of the process. -""" - -PROCESS_INTERACTIVE: Final = "process.interactive" -""" -Whether the process is connected to an interactive shell. -""" - -PROCESS_LINUX_CGROUP: Final = "process.linux.cgroup" -""" -The control group associated with the process. -Note: Control groups (cgroups) are a kernel feature used to organize and manage process resources. This attribute provides the path(s) to the cgroup(s) associated with the process, which should match the contents of the [/proc/\\[PID\\]/cgroup](https://man7.org/linux/man-pages/man7/cgroups.7.html) file. -""" - -PROCESS_OWNER: Final = "process.owner" -""" -The username of the user that owns the process. -""" - -PROCESS_PAGING_FAULT_TYPE: Final = "process.paging.fault_type" -""" -Deprecated: Replaced by `system.paging.fault.type`. -""" - -PROCESS_PARENT_PID: Final = "process.parent_pid" -""" -Parent Process identifier (PPID). -""" - -PROCESS_PID: Final = "process.pid" -""" -Process identifier (PID). -""" - -PROCESS_REAL_USER_ID: Final = "process.real_user.id" -""" -The real user ID (RUID) of the process. -""" - -PROCESS_REAL_USER_NAME: Final = "process.real_user.name" -""" -The username of the real user of the process. -""" - -PROCESS_RUNTIME_DESCRIPTION: Final = "process.runtime.description" -""" -An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. -""" - -PROCESS_RUNTIME_NAME: Final = "process.runtime.name" -""" -The name of the runtime of this process. -""" - -PROCESS_RUNTIME_VERSION: Final = "process.runtime.version" -""" -The version of the runtime of this process, as returned by the runtime without modification. -""" - -PROCESS_SAVED_USER_ID: Final = "process.saved_user.id" -""" -The saved user ID (SUID) of the process. -""" - -PROCESS_SAVED_USER_NAME: Final = "process.saved_user.name" -""" -The username of the saved user. -""" - -PROCESS_SESSION_LEADER_PID: Final = "process.session_leader.pid" -""" -The PID of the process's session leader. This is also the session ID (SID) of the process. -""" - -PROCESS_STATE: Final = "process.state" -""" -The process state, e.g., [Linux Process State Codes](https://man7.org/linux/man-pages/man1/ps.1.html#PROCESS_STATE_CODES). -""" - -PROCESS_TITLE: Final = "process.title" -""" -Process title (proctitle). -Note: In many Unix-like systems, process title (proctitle), is the string that represents the name or command line of a running process, displayed by system monitoring tools like ps, top, and htop. -""" - -PROCESS_USER_ID: Final = "process.user.id" -""" -The effective user ID (EUID) of the process. -""" - -PROCESS_USER_NAME: Final = "process.user.name" -""" -The username of the effective user of the process. -""" - -PROCESS_VPID: Final = "process.vpid" -""" -Virtual process identifier. -Note: The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. -""" - -PROCESS_WORKING_DIRECTORY: Final = "process.working_directory" -""" -The working directory of the process. -""" - - -class ProcessContextSwitchTypeValues(Enum): - VOLUNTARY = "voluntary" - """voluntary.""" - INVOLUNTARY = "involuntary" - """involuntary.""" - - -@deprecated("The attribute process.cpu.state is deprecated - Replaced by `cpu.mode`") -class ProcessCpuStateValues(Enum): - SYSTEM = "system" - """system.""" - USER = "user" - """user.""" - WAIT = "wait" - """wait.""" - - -@deprecated("The attribute process.paging.fault_type is deprecated - Replaced by `system.paging.fault.type`") -class ProcessPagingFaultTypeValues(Enum): - MAJOR = "major" - """major.""" - MINOR = "minor" - """minor.""" - - -class ProcessStateValues(Enum): - RUNNING = "running" - """running.""" - SLEEPING = "sleeping" - """sleeping.""" - STOPPED = "stopped" - """stopped.""" - DEFUNCT = "defunct" - """defunct.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py deleted file mode 100644 index 7fd6de26520..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/profile_attributes.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -PROFILE_FRAME_TYPE: Final = "profile.frame.type" -""" -Describes the interpreter or compiler of a single frame. -""" - - -class ProfileFrameTypeValues(Enum): - DOTNET = "dotnet" - """[.NET](https://wikipedia.org/wiki/.NET).""" - JVM = "jvm" - """[JVM](https://wikipedia.org/wiki/Java_virtual_machine).""" - KERNEL = "kernel" - """[Kernel](https://wikipedia.org/wiki/Kernel_(operating_system)).""" - NATIVE = "native" - """Can be one of but not limited to [C](https://wikipedia.org/wiki/C_(programming_language)), [C++](https://wikipedia.org/wiki/C%2B%2B), [Go](https://wikipedia.org/wiki/Go_(programming_language)) or [Rust](https://wikipedia.org/wiki/Rust_(programming_language)). If possible, a more precise value MUST be used.""" - PERL = "perl" - """[Perl](https://wikipedia.org/wiki/Perl).""" - PHP = "php" - """[PHP](https://wikipedia.org/wiki/PHP).""" - CPYTHON = "cpython" - """[Python](https://wikipedia.org/wiki/Python_(programming_language)).""" - RUBY = "ruby" - """[Ruby](https://wikipedia.org/wiki/Ruby_(programming_language)).""" - V8JS = "v8js" - """[V8JS](https://wikipedia.org/wiki/V8_(JavaScript_engine)).""" - BEAM = "beam" - """[Erlang](https://en.wikipedia.org/wiki/BEAM_(Erlang_virtual_machine)).""" - GO = "go" - """[Go](https://wikipedia.org/wiki/Go_(programming_language)),.""" - RUST = "rust" - """[Rust](https://wikipedia.org/wiki/Rust_(programming_language)).""" - LUAJIT = "luajit" - """[LuaJIT](https://en.wikipedia.org/wiki/LuaJIT).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py deleted file mode 100644 index 9802b7bdc73..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/rpc_attributes.py +++ /dev/null @@ -1,264 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -RPC_CONNECT_RPC_ERROR_CODE: Final = "rpc.connect_rpc.error_code" -""" -Deprecated: Replaced by `rpc.response.status_code`. -""" - -RPC_CONNECT_RPC_REQUEST_METADATA_TEMPLATE: Final = "rpc.connect_rpc.request.metadata" -""" -Deprecated: Replaced by `rpc.request.metadata`. -""" - -RPC_CONNECT_RPC_RESPONSE_METADATA_TEMPLATE: Final = "rpc.connect_rpc.response.metadata" -""" -Deprecated: Replaced by `rpc.response.metadata`. -""" - -RPC_GRPC_REQUEST_METADATA_TEMPLATE: Final = "rpc.grpc.request.metadata" -""" -Deprecated: Replaced by `rpc.request.metadata`. -""" - -RPC_GRPC_RESPONSE_METADATA_TEMPLATE: Final = "rpc.grpc.response.metadata" -""" -Deprecated: Replaced by `rpc.response.metadata`. -""" - -RPC_GRPC_STATUS_CODE: Final = "rpc.grpc.status_code" -""" -Deprecated: Use string representation of the gRPC status code on the `rpc.response.status_code` attribute. -""" - -RPC_JSONRPC_ERROR_CODE: Final = "rpc.jsonrpc.error_code" -""" -Deprecated: Use string representation of the error code on the `rpc.response.status_code` attribute. -""" - -RPC_JSONRPC_ERROR_MESSAGE: Final = "rpc.jsonrpc.error_message" -""" -Deprecated: Use the span status description when reporting JSON-RPC spans. -""" - -RPC_JSONRPC_REQUEST_ID: Final = "rpc.jsonrpc.request_id" -""" -Deprecated: Replaced by `jsonrpc.request.id`. -""" - -RPC_JSONRPC_VERSION: Final = "rpc.jsonrpc.version" -""" -Deprecated: Replaced by `jsonrpc.protocol.version`. -""" - -RPC_MESSAGE_COMPRESSED_SIZE: Final = "rpc.message.compressed_size" -""" -Deprecated: Deprecated, no replacement at this time. -""" - -RPC_MESSAGE_ID: Final = "rpc.message.id" -""" -Deprecated: Deprecated, no replacement at this time. -""" - -RPC_MESSAGE_TYPE: Final = "rpc.message.type" -""" -Deprecated: Deprecated, no replacement at this time. -""" - -RPC_MESSAGE_UNCOMPRESSED_SIZE: Final = "rpc.message.uncompressed_size" -""" -Deprecated: Deprecated, no replacement at this time. -""" - -RPC_METHOD: Final = "rpc.method" -""" -The fully-qualified logical name of the method from the RPC interface perspective. -Note: The method name MAY have unbounded cardinality in edge or error cases. - -Some RPC frameworks or libraries provide a fixed set of recognized methods -for client stubs and server implementations. Instrumentations for such -frameworks MUST set this attribute to the original method name only -when the method is recognized by the framework or library. - -When the method is not recognized, for example, when the server receives -a request for a method that is not predefined on the server, or when -instrumentation is not able to reliably detect if the method is predefined, -the attribute MUST be set to `_OTHER`. - -If the RPC instrumentation could end up converting valid RPC methods to -`_OTHER`, then it SHOULD provide a way to configure the list of recognized -RPC methods. - -The `rpc.method` can be different from the name of any implementing -method/function. -The `code.function.name` attribute may be used to record the fully-qualified -method actually executing the call on the server side, or the -RPC client stub method on the client side. -""" - -RPC_METHOD_ORIGINAL: Final = "rpc.method_original" -""" -The original name of the method used by the client. -""" - -RPC_REQUEST_METADATA_TEMPLATE: Final = "rpc.request.metadata" -""" -RPC request metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. -Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. -Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - -For example, a property `my-custom-key` with value `["1.2.3.4", "1.2.3.5"]` SHOULD be recorded as -`rpc.request.metadata.my-custom-key` attribute with value `["1.2.3.4", "1.2.3.5"]`. -""" - -RPC_RESPONSE_METADATA_TEMPLATE: Final = "rpc.response.metadata" -""" -RPC response metadata, `` being the normalized RPC metadata key (lowercase), the value being the metadata values. -Note: Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. -Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. - -For example, a property `my-custom-key` with value `["attribute_value"]` SHOULD be recorded as -the `rpc.response.metadata.my-custom-key` attribute with value `["attribute_value"]`. -""" - -RPC_RESPONSE_STATUS_CODE: Final = "rpc.response.status_code" -""" -Status code of the RPC returned by the RPC server or generated by the client. -Note: Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. -Semantic conventions for individual RPC frameworks SHOULD document what `rpc.response.status_code` means in the context of that system and which values are considered to represent errors. -""" - -RPC_SERVICE: Final = "rpc.service" -""" -Deprecated: Value should be included in `rpc.method` which is expected to be a fully-qualified name. -""" - -RPC_SYSTEM: Final = "rpc.system" -""" -Deprecated: Replaced by `rpc.system.name`. -""" - -RPC_SYSTEM_NAME: Final = "rpc.system.name" -""" -The Remote Procedure Call (RPC) system. -Note: The client and server RPC systems may differ for the same RPC interaction. For example, a client may use Apache Dubbo or Connect RPC to communicate with a server that uses gRPC since both protocols provide compatibility with gRPC. -""" - - -@deprecated("The attribute rpc.connect_rpc.error_code is deprecated - Replaced by `rpc.response.status_code`") -class RpcConnectRpcErrorCodeValues(Enum): - CANCELLED = "cancelled" - """cancelled.""" - UNKNOWN = "unknown" - """unknown.""" - INVALID_ARGUMENT = "invalid_argument" - """invalid_argument.""" - DEADLINE_EXCEEDED = "deadline_exceeded" - """deadline_exceeded.""" - NOT_FOUND = "not_found" - """not_found.""" - ALREADY_EXISTS = "already_exists" - """already_exists.""" - PERMISSION_DENIED = "permission_denied" - """permission_denied.""" - RESOURCE_EXHAUSTED = "resource_exhausted" - """resource_exhausted.""" - FAILED_PRECONDITION = "failed_precondition" - """failed_precondition.""" - ABORTED = "aborted" - """aborted.""" - OUT_OF_RANGE = "out_of_range" - """out_of_range.""" - UNIMPLEMENTED = "unimplemented" - """unimplemented.""" - INTERNAL = "internal" - """internal.""" - UNAVAILABLE = "unavailable" - """unavailable.""" - DATA_LOSS = "data_loss" - """data_loss.""" - UNAUTHENTICATED = "unauthenticated" - """unauthenticated.""" - - -@deprecated( - "The attribute rpc.grpc.status_code is deprecated - Use string representation of the gRPC status code on the `rpc.response.status_code` attribute" -) -class RpcGrpcStatusCodeValues(Enum): - OK = 0 - """OK.""" - CANCELLED = 1 - """CANCELLED.""" - UNKNOWN = 2 - """UNKNOWN.""" - INVALID_ARGUMENT = 3 - """INVALID_ARGUMENT.""" - DEADLINE_EXCEEDED = 4 - """DEADLINE_EXCEEDED.""" - NOT_FOUND = 5 - """NOT_FOUND.""" - ALREADY_EXISTS = 6 - """ALREADY_EXISTS.""" - PERMISSION_DENIED = 7 - """PERMISSION_DENIED.""" - RESOURCE_EXHAUSTED = 8 - """RESOURCE_EXHAUSTED.""" - FAILED_PRECONDITION = 9 - """FAILED_PRECONDITION.""" - ABORTED = 10 - """ABORTED.""" - OUT_OF_RANGE = 11 - """OUT_OF_RANGE.""" - UNIMPLEMENTED = 12 - """UNIMPLEMENTED.""" - INTERNAL = 13 - """INTERNAL.""" - UNAVAILABLE = 14 - """UNAVAILABLE.""" - DATA_LOSS = 15 - """DATA_LOSS.""" - UNAUTHENTICATED = 16 - """UNAUTHENTICATED.""" - - -@deprecated("The attribute rpc.message.type is deprecated - Deprecated, no replacement at this time") -class RpcMessageTypeValues(Enum): - SENT = "SENT" - """sent.""" - RECEIVED = "RECEIVED" - """received.""" - - -@deprecated("The attribute rpc.system is deprecated - Replaced by `rpc.system.name`") -class RpcSystemValues(Enum): - GRPC = "grpc" - """gRPC.""" - JAVA_RMI = "java_rmi" - """Java RMI.""" - DOTNET_WCF = "dotnet_wcf" - """.NET WCF.""" - APACHE_DUBBO = "apache_dubbo" - """Apache Dubbo.""" - CONNECT_RPC = "connect_rpc" - """Connect RPC.""" - ONC_RPC = "onc_rpc" - """[ONC RPC (Sun RPC)](https://datatracker.ietf.org/doc/html/rfc5531).""" - JSONRPC = "jsonrpc" - """JSON-RPC.""" - - -class RpcSystemNameValues(Enum): - GRPC = "grpc" - """[gRPC](https://grpc.io/).""" - DUBBO = "dubbo" - """[Apache Dubbo](https://dubbo.apache.org/).""" - CONNECTRPC = "connectrpc" - """[Connect RPC](https://connectrpc.com/).""" - JSONRPC = "jsonrpc" - """[JSON-RPC](https://www.jsonrpc.org/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py deleted file mode 100644 index fa4ec427244..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/security_rule_attributes.py +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -SECURITY_RULE_CATEGORY: Final = "security_rule.category" -""" -A categorization value keyword used by the entity using the rule for detection of this event. -""" - -SECURITY_RULE_DESCRIPTION: Final = "security_rule.description" -""" -The description of the rule generating the event. -""" - -SECURITY_RULE_LICENSE: Final = "security_rule.license" -""" -Name of the license under which the rule used to generate this event is made available. -""" - -SECURITY_RULE_NAME: Final = "security_rule.name" -""" -The name of the rule or signature generating the event. -""" - -SECURITY_RULE_REFERENCE: Final = "security_rule.reference" -""" -Reference URL to additional information about the rule used to generate this event. -Note: The URL can point to the vendor’s documentation about the rule. If that’s not available, it can also be a link to a more general page describing this type of alert. -""" - -SECURITY_RULE_RULESET_NAME: Final = "security_rule.ruleset.name" -""" -Name of the ruleset, policy, group, or parent category in which the rule used to generate this event is a member. -""" - -SECURITY_RULE_UUID: Final = "security_rule.uuid" -""" -A rule ID that is unique within the scope of a set or group of agents, observers, or other entities using the rule for detection of this event. -""" - -SECURITY_RULE_VERSION: Final = "security_rule.version" -""" -The version / revision of the rule being used for analysis. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py deleted file mode 100644 index 865dcde6b08..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/server_attributes.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -SERVER_ADDRESS: Final = "server.address" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.server_attributes.SERVER_ADDRESS`. -""" - -SERVER_PORT: Final = "server.port" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.server_attributes.SERVER_PORT`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py deleted file mode 100644 index eb2dcd6e8a2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/service_attributes.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -SERVICE_CRITICALITY: Final = "service.criticality" -""" -The operational criticality of the service. -Note: Application developers are encouraged to set `service.criticality` to express the operational importance of their services. Telemetry consumers MAY use this attribute to optimize telemetry collection or improve user experience. -""" - -SERVICE_INSTANCE_ID: Final = "service.instance.id" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_INSTANCE_ID`. -""" - -SERVICE_NAME: Final = "service.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_NAME`. -""" - -SERVICE_NAMESPACE: Final = "service.namespace" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_NAMESPACE`. -""" - -SERVICE_PEER_NAME: Final = "service.peer.name" -""" -Logical name of the service on the other side of the connection. SHOULD be equal to the actual [`service.name`](/docs/resource/README.md#service) resource attribute of the remote service if any. -""" - -SERVICE_PEER_NAMESPACE: Final = "service.peer.namespace" -""" -Logical namespace of the service on the other side of the connection. SHOULD be equal to the actual [`service.namespace`](/docs/resource/README.md#service) resource attribute of the remote service if any. -""" - -SERVICE_VERSION: Final = "service.version" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.service_attributes.SERVICE_VERSION`. -""" - - -class ServiceCriticalityValues(Enum): - CRITICAL = "critical" - """Service is business-critical; downtime directly impacts revenue, user experience, or core functionality.""" - HIGH = "high" - """Service is important but has degradation tolerance or fallback mechanisms.""" - MEDIUM = "medium" - """Service provides supplementary functionality; degradation has limited user impact.""" - LOW = "low" - """Service is non-essential to core operations; used for background tasks or internal tools.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py deleted file mode 100644 index db9a5edc417..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/session_attributes.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -SESSION_ID: Final = "session.id" -""" -A unique ID to identify a session. -""" - -SESSION_PREVIOUS_ID: Final = "session.previous_id" -""" -The previous `session.id` for this user, when known. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py deleted file mode 100644 index 1960b24ef64..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/source_attributes.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -SOURCE_ADDRESS: Final = "source.address" -""" -Source address - domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. -Note: When observed from the destination side, and when communicating through an intermediary, `source.address` SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. -""" - -SOURCE_PORT: Final = "source.port" -""" -Source port number. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py deleted file mode 100644 index 93784858e47..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/system_attributes.py +++ /dev/null @@ -1,242 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -SYSTEM_CPU_LOGICAL_NUMBER: Final = "system.cpu.logical_number" -""" -Deprecated: Replaced by `cpu.logical_number`. -""" - -SYSTEM_CPU_STATE: Final = "system.cpu.state" -""" -Deprecated: Replaced by `cpu.mode`. -""" - -SYSTEM_DEVICE: Final = "system.device" -""" -The device identifier. -""" - -SYSTEM_FILESYSTEM_MODE: Final = "system.filesystem.mode" -""" -The filesystem mode. -""" - -SYSTEM_FILESYSTEM_MOUNTPOINT: Final = "system.filesystem.mountpoint" -""" -The filesystem mount path. -""" - -SYSTEM_FILESYSTEM_STATE: Final = "system.filesystem.state" -""" -The filesystem state. -""" - -SYSTEM_FILESYSTEM_TYPE: Final = "system.filesystem.type" -""" -The filesystem type. -""" - -SYSTEM_MEMORY_LINUX_HUGEPAGES_STATE: Final = "system.memory.linux.hugepages.state" -""" -The Linux HugePages memory state. -""" - -SYSTEM_MEMORY_LINUX_SLAB_STATE: Final = "system.memory.linux.slab.state" -""" -The Linux Slab memory state. -""" - -SYSTEM_MEMORY_STATE: Final = "system.memory.state" -""" -The memory state. -""" - -SYSTEM_NETWORK_STATE: Final = "system.network.state" -""" -Deprecated: Replaced by `network.connection.state`. -""" - -SYSTEM_PAGING_DIRECTION: Final = "system.paging.direction" -""" -The paging access direction. -""" - -SYSTEM_PAGING_FAULT_TYPE: Final = "system.paging.fault.type" -""" -The paging fault type. -""" - -SYSTEM_PAGING_STATE: Final = "system.paging.state" -""" -The memory paging state. -""" - -SYSTEM_PAGING_TYPE: Final = "system.paging.type" -""" -Deprecated: Replaced by `system.paging.fault.type`. -""" - -SYSTEM_PROCESS_STATUS: Final = "system.process.status" -""" -Deprecated: Replaced by `process.state`. -""" - -SYSTEM_PROCESSES_STATUS: Final = "system.processes.status" -""" -Deprecated: Replaced by `process.state`. -""" - - -@deprecated("The attribute system.cpu.state is deprecated - Replaced by `cpu.mode`") -class SystemCpuStateValues(Enum): - USER = "user" - """user.""" - SYSTEM = "system" - """system.""" - NICE = "nice" - """nice.""" - IDLE = "idle" - """idle.""" - IOWAIT = "iowait" - """iowait.""" - INTERRUPT = "interrupt" - """interrupt.""" - STEAL = "steal" - """steal.""" - - -class SystemFilesystemStateValues(Enum): - USED = "used" - """used.""" - FREE = "free" - """free.""" - RESERVED = "reserved" - """reserved.""" - - -class SystemFilesystemTypeValues(Enum): - FAT32 = "fat32" - """fat32.""" - EXFAT = "exfat" - """exfat.""" - NTFS = "ntfs" - """ntfs.""" - REFS = "refs" - """refs.""" - HFSPLUS = "hfsplus" - """hfsplus.""" - EXT4 = "ext4" - """ext4.""" - - -class SystemMemoryLinuxHugepagesStateValues(Enum): - FREE = "free" - """free.""" - USED = "used" - """used.""" - - -class SystemMemoryLinuxSlabStateValues(Enum): - RECLAIMABLE = "reclaimable" - """reclaimable.""" - UNRECLAIMABLE = "unreclaimable" - """unreclaimable.""" - - -class SystemMemoryStateValues(Enum): - USED = "used" - """Actual used virtual memory in bytes.""" - FREE = "free" - """free.""" - SHARED = "shared" - """Deprecated: Removed, report shared memory usage with `metric.system.memory.linux.shared` metric.""" - BUFFERS = "buffers" - """buffers.""" - CACHED = "cached" - """cached.""" - - -@deprecated("The attribute system.network.state is deprecated - Replaced by `network.connection.state`") -class SystemNetworkStateValues(Enum): - CLOSE = "close" - """close.""" - CLOSE_WAIT = "close_wait" - """close_wait.""" - CLOSING = "closing" - """closing.""" - DELETE = "delete" - """delete.""" - ESTABLISHED = "established" - """established.""" - FIN_WAIT_1 = "fin_wait_1" - """fin_wait_1.""" - FIN_WAIT_2 = "fin_wait_2" - """fin_wait_2.""" - LAST_ACK = "last_ack" - """last_ack.""" - LISTEN = "listen" - """listen.""" - SYN_RECV = "syn_recv" - """syn_recv.""" - SYN_SENT = "syn_sent" - """syn_sent.""" - TIME_WAIT = "time_wait" - """time_wait.""" - - -class SystemPagingDirectionValues(Enum): - IN = "in" - """in.""" - OUT = "out" - """out.""" - - -class SystemPagingFaultTypeValues(Enum): - MAJOR = "major" - """major.""" - MINOR = "minor" - """minor.""" - - -class SystemPagingStateValues(Enum): - USED = "used" - """used.""" - FREE = "free" - """free.""" - - -@deprecated("The attribute system.paging.type is deprecated - Replaced by `system.paging.fault.type`") -class SystemPagingTypeValues(Enum): - MAJOR = "major" - """major.""" - MINOR = "minor" - """minor.""" - - -@deprecated("The attribute system.process.status is deprecated - Replaced by `process.state`") -class SystemProcessStatusValues(Enum): - RUNNING = "running" - """running.""" - SLEEPING = "sleeping" - """sleeping.""" - STOPPED = "stopped" - """stopped.""" - DEFUNCT = "defunct" - """defunct.""" - - -@deprecated("The attribute system.processes.status is deprecated - Replaced by `process.state`") -class SystemProcessesStatusValues(Enum): - RUNNING = "running" - """running.""" - SLEEPING = "sleeping" - """sleeping.""" - STOPPED = "stopped" - """stopped.""" - DEFUNCT = "defunct" - """defunct.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py deleted file mode 100644 index 4067f433703..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/telemetry_attributes.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -TELEMETRY_DISTRO_NAME: Final = "telemetry.distro.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_DISTRO_NAME`. -""" - -TELEMETRY_DISTRO_VERSION: Final = "telemetry.distro.version" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_DISTRO_VERSION`. -""" - -TELEMETRY_SDK_LANGUAGE: Final = "telemetry.sdk.language" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_LANGUAGE`. -""" - -TELEMETRY_SDK_NAME: Final = "telemetry.sdk.name" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_NAME`. -""" - -TELEMETRY_SDK_VERSION: Final = "telemetry.sdk.version" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TELEMETRY_SDK_VERSION`. -""" - - -@deprecated( - "Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues`." -) -class TelemetrySdkLanguageValues(Enum): - CPP = "cpp" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.CPP`.""" - DOTNET = "dotnet" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.DOTNET`.""" - ERLANG = "erlang" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.ERLANG`.""" - GO = "go" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.GO`.""" - JAVA = "java" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.JAVA`.""" - KOTLIN = "kotlin" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.KOTLIN`.""" - NODEJS = "nodejs" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.NODEJS`.""" - PHP = "php" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.PHP`.""" - PYTHON = "python" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.PYTHON`.""" - RUBY = "ruby" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.RUBY`.""" - RUST = "rust" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.RUST`.""" - SWIFT = "swift" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.SWIFT`.""" - WEBJS = "webjs" - """Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.telemetry_attributes.TelemetrySdkLanguageValues.WEBJS`.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py deleted file mode 100644 index 4a3ef390d88..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/test_attributes.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -TEST_CASE_NAME: Final = "test.case.name" -""" -The fully qualified human readable name of the [test case](https://wikipedia.org/wiki/Test_case). -""" - -TEST_CASE_RESULT_STATUS: Final = "test.case.result.status" -""" -The status of the actual test case result from test execution. -""" - -TEST_SUITE_NAME: Final = "test.suite.name" -""" -The human readable name of a [test suite](https://wikipedia.org/wiki/Test_suite). -""" - -TEST_SUITE_RUN_STATUS: Final = "test.suite.run.status" -""" -The status of the test suite run. -""" - - -class TestCaseResultStatusValues(Enum): - PASS = "pass" - """pass.""" - FAIL = "fail" - """fail.""" - - -class TestSuiteRunStatusValues(Enum): - SUCCESS = "success" - """success.""" - FAILURE = "failure" - """failure.""" - SKIPPED = "skipped" - """skipped.""" - ABORTED = "aborted" - """aborted.""" - TIMED_OUT = "timed_out" - """timed_out.""" - IN_PROGRESS = "in_progress" - """in_progress.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py deleted file mode 100644 index 29c41435fd5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/thread_attributes.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -THREAD_ID: Final = "thread.id" -""" -Current "managed" thread ID (as opposed to OS thread ID). -Note: Examples of where the value can be extracted from: - -| Language or platform | Source | -| --- | --- | -| JVM | `Thread.currentThread().threadId()` | -| .NET | `Thread.CurrentThread.ManagedThreadId` | -| Python | `threading.current_thread().ident` | -| Ruby | `Thread.current.object_id` | -| C++ | `std::this_thread::get_id()` | -| Erlang | `erlang:self()` |. -""" - -THREAD_NAME: Final = "thread.name" -""" -Current thread name. -Note: Examples of where the value can be extracted from: - -| Language or platform | Source | -| --- | --- | -| JVM | `Thread.currentThread().getName()` | -| .NET | `Thread.CurrentThread.Name` | -| Python | `threading.current_thread().name` | -| Ruby | `Thread.current.name` | -| Erlang | `erlang:process_info(self(), registered_name)` |. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py deleted file mode 100644 index 60e722c757e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/tls_attributes.py +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -TLS_CIPHER: Final = "tls.cipher" -""" -String indicating the [cipher](https://datatracker.ietf.org/doc/html/rfc5246#appendix-A.5) used during the current connection. -Note: The values allowed for `tls.cipher` MUST be one of the `Descriptions` of the [registered TLS Cipher Suits](https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#table-tls-parameters-4). -""" - -TLS_CLIENT_CERTIFICATE: Final = "tls.client.certificate" -""" -PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of `client.certificate_chain` since this value also exists in that list. -""" - -TLS_CLIENT_CERTIFICATE_CHAIN: Final = "tls.client.certificate_chain" -""" -Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of `client.certificate` since that value should be the first certificate in the chain. -""" - -TLS_CLIENT_HASH_MD5: Final = "tls.client.hash.md5" -""" -Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. -""" - -TLS_CLIENT_HASH_SHA1: Final = "tls.client.hash.sha1" -""" -Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. -""" - -TLS_CLIENT_HASH_SHA256: Final = "tls.client.hash.sha256" -""" -Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. -""" - -TLS_CLIENT_ISSUER: Final = "tls.client.issuer" -""" -Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. -""" - -TLS_CLIENT_JA3: Final = "tls.client.ja3" -""" -A hash that identifies clients based on how they perform an SSL/TLS handshake. -""" - -TLS_CLIENT_NOT_AFTER: Final = "tls.client.not_after" -""" -Date/Time indicating when client certificate is no longer considered valid. -""" - -TLS_CLIENT_NOT_BEFORE: Final = "tls.client.not_before" -""" -Date/Time indicating when client certificate is first considered valid. -""" - -TLS_CLIENT_SERVER_NAME: Final = "tls.client.server_name" -""" -Deprecated: Replaced by `server.address`. -""" - -TLS_CLIENT_SUBJECT: Final = "tls.client.subject" -""" -Distinguished name of subject of the x.509 certificate presented by the client. -""" - -TLS_CLIENT_SUPPORTED_CIPHERS: Final = "tls.client.supported_ciphers" -""" -Array of ciphers offered by the client during the client hello. -""" - -TLS_CURVE: Final = "tls.curve" -""" -String indicating the curve used for the given cipher, when applicable. -""" - -TLS_ESTABLISHED: Final = "tls.established" -""" -Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. -""" - -TLS_NEXT_PROTOCOL: Final = "tls.next_protocol" -""" -String indicating the protocol being tunneled. Per the values in the [IANA registry](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids), this string should be lower case. -""" - -TLS_PROTOCOL_NAME: Final = "tls.protocol.name" -""" -Normalized lowercase protocol name parsed from original string of the negotiated [SSL/TLS protocol version](https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values). -""" - -TLS_PROTOCOL_VERSION: Final = "tls.protocol.version" -""" -Numeric part of the version parsed from the original string of the negotiated [SSL/TLS protocol version](https://docs.openssl.org/1.1.1/man3/SSL_get_version/#return-values). -""" - -TLS_RESUMED: Final = "tls.resumed" -""" -Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. -""" - -TLS_SERVER_CERTIFICATE: Final = "tls.server.certificate" -""" -PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of `server.certificate_chain` since this value also exists in that list. -""" - -TLS_SERVER_CERTIFICATE_CHAIN: Final = "tls.server.certificate_chain" -""" -Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of `server.certificate` since that value should be the first certificate in the chain. -""" - -TLS_SERVER_HASH_MD5: Final = "tls.server.hash.md5" -""" -Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. -""" - -TLS_SERVER_HASH_SHA1: Final = "tls.server.hash.sha1" -""" -Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. -""" - -TLS_SERVER_HASH_SHA256: Final = "tls.server.hash.sha256" -""" -Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. -""" - -TLS_SERVER_ISSUER: Final = "tls.server.issuer" -""" -Distinguished name of [subject](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) of the issuer of the x.509 certificate presented by the client. -""" - -TLS_SERVER_JA3S: Final = "tls.server.ja3s" -""" -A hash that identifies servers based on how they perform an SSL/TLS handshake. -""" - -TLS_SERVER_NOT_AFTER: Final = "tls.server.not_after" -""" -Date/Time indicating when server certificate is no longer considered valid. -""" - -TLS_SERVER_NOT_BEFORE: Final = "tls.server.not_before" -""" -Date/Time indicating when server certificate is first considered valid. -""" - -TLS_SERVER_SUBJECT: Final = "tls.server.subject" -""" -Distinguished name of subject of the x.509 certificate presented by the server. -""" - - -class TlsProtocolNameValues(Enum): - SSL = "ssl" - """SSL.""" - TLS = "tls" - """TLS.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py deleted file mode 100644 index 345349a45aa..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/url_attributes.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -URL_DOMAIN: Final = "url.domain" -""" -Domain extracted from the `url.full`, such as "opentelemetry.io". -Note: In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a [literal IPv6 address](https://www.rfc-editor.org/rfc/rfc2732#section-2) enclosed by `[` and `]`, the `[` and `]` characters should also be captured in the domain field. -""" - -URL_EXTENSION: Final = "url.extension" -""" -The file extension extracted from the `url.full`, excluding the leading dot. -Note: The file extension is only set if it exists, as not every URL has a file extension. When the filename has multiple extensions `example.tar.gz`, only the last one should be captured `gz`, not `tar.gz`. -""" - -URL_FRAGMENT: Final = "url.fragment" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_FRAGMENT`. -""" - -URL_FULL: Final = "url.full" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_FULL`. -""" - -URL_ORIGINAL: Final = "url.original" -""" -Unmodified original URL as seen in the event source. -Note: In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. -`url.original` might contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same. -""" - -URL_PATH: Final = "url.path" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_PATH`. -""" - -URL_PORT: Final = "url.port" -""" -Port extracted from the `url.full`. -""" - -URL_QUERY: Final = "url.query" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_QUERY`. -""" - -URL_REGISTERED_DOMAIN: Final = "url.registered_domain" -""" -The highest registered URL domain, stripped of the subdomain. -Note: This value can be determined precisely with the [public suffix list](https://publicsuffix.org/). For example, the registered domain for `foo.example.com` is `example.com`. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as `co.uk`. -""" - -URL_SCHEME: Final = "url.scheme" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.url_attributes.URL_SCHEME`. -""" - -URL_SUBDOMAIN: Final = "url.subdomain" -""" -The subdomain portion of a fully qualified domain name includes all of the names except the hostname under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. -Note: The subdomain portion of `www.east.mydomain.co.uk` is `east`. If the domain has multiple levels of subdomain, such as `sub2.sub1.example.com`, the subdomain field should contain `sub2.sub1`, with no trailing period. -""" - -URL_TEMPLATE: Final = "url.template" -""" -The low-cardinality template of an [absolute path reference](https://www.rfc-editor.org/rfc/rfc3986#section-4.2). -""" - -URL_TOP_LEVEL_DOMAIN: Final = "url.top_level_domain" -""" -The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is `com`. -Note: This value can be determined precisely with the [public suffix list](https://publicsuffix.org/). -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py deleted file mode 100644 index bccceba3cba..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_agent_attributes.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -USER_AGENT_NAME: Final = "user_agent.name" -""" -Name of the user-agent extracted from original. Usually refers to the browser's name. -Note: [Example](https://uaparser.dev/#demo) of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant name SHOULD be selected. In such a scenario it should align with `user_agent.version`. -""" - -USER_AGENT_ORIGINAL: Final = "user_agent.original" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.attributes.user_agent_attributes.USER_AGENT_ORIGINAL`. -""" - -USER_AGENT_OS_NAME: Final = "user_agent.os.name" -""" -Human readable operating system name. -Note: For mapping user agent strings to OS names, libraries such as [ua-parser](https://github.com/ua-parser) can be utilized. -""" - -USER_AGENT_OS_VERSION: Final = "user_agent.os.version" -""" -The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). -Note: For mapping user agent strings to OS versions, libraries such as [ua-parser](https://github.com/ua-parser) can be utilized. -""" - -USER_AGENT_SYNTHETIC_TYPE: Final = "user_agent.synthetic.type" -""" -Specifies the category of synthetic traffic, such as tests or bots. -Note: This attribute MAY be derived from the contents of the `user_agent.original` attribute. Components that populate the attribute are responsible for determining what they consider to be synthetic bot or test traffic. This attribute can either be set for self-identification purposes, or on telemetry detected to be generated as a result of a synthetic request. This attribute is useful for distinguishing between genuine client traffic and synthetic traffic generated by bots or tests. -""" - -USER_AGENT_VERSION: Final = "user_agent.version" -""" -Version of the user-agent extracted from original. Usually refers to the browser's version. -Note: [Example](https://uaparser.dev/#demo) of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the `user_agent.original`, the most significant version SHOULD be selected. In such a scenario it should align with `user_agent.name`. -""" - - -class UserAgentSyntheticTypeValues(Enum): - BOT = "bot" - """Bot source.""" - TEST = "test" - """Synthetic test source.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py deleted file mode 100644 index 91d0dbccada..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/user_attributes.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -USER_EMAIL: Final = "user.email" -""" -User email address. -""" - -USER_FULL_NAME: Final = "user.full_name" -""" -User's full name. -""" - -USER_HASH: Final = "user.hash" -""" -Unique user hash to correlate information for a user in anonymized form. -Note: Useful if `user.id` or `user.name` contain confidential information and cannot be used. -""" - -USER_ID: Final = "user.id" -""" -Unique identifier of the user. -""" - -USER_NAME: Final = "user.name" -""" -Short name or login/username of the user. -""" - -USER_ROLES: Final = "user.roles" -""" -Array of user roles at the time of the event. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py deleted file mode 100644 index d0b43bfe6e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/vcs_attributes.py +++ /dev/null @@ -1,218 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -VCS_CHANGE_ID: Final = "vcs.change.id" -""" -The ID of the change (pull request/merge request/changelist) if applicable. This is usually a unique (within repository) identifier generated by the VCS system. -""" - -VCS_CHANGE_STATE: Final = "vcs.change.state" -""" -The state of the change (pull request/merge request/changelist). -""" - -VCS_CHANGE_TITLE: Final = "vcs.change.title" -""" -The human readable title of the change (pull request/merge request/changelist). This title is often a brief summary of the change and may get merged in to a ref as the commit summary. -""" - -VCS_LINE_CHANGE_TYPE: Final = "vcs.line_change.type" -""" -The type of line change being measured on a branch or change. -""" - -VCS_OWNER_NAME: Final = "vcs.owner.name" -""" -The group owner within the version control system. -""" - -VCS_PROVIDER_NAME: Final = "vcs.provider.name" -""" -The name of the version control system provider. -""" - -VCS_REF_BASE_NAME: Final = "vcs.ref.base.name" -""" -The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. -Note: `base` refers to the starting point of a change. For example, `main` -would be the base reference of type branch if you've created a new -reference of type branch from it and created new commits. -""" - -VCS_REF_BASE_REVISION: Final = "vcs.ref.base.revision" -""" -The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. -Note: `base` refers to the starting point of a change. For example, `main` -would be the base reference of type branch if you've created a new -reference of type branch from it and created new commits. The -revision can be a full [hash value (see -glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), -of the recorded change to a ref within a repository pointing to a -commit [commit](https://git-scm.com/docs/git-commit) object. It does -not necessarily have to be a hash; it can simply define a [revision -number](https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html) -which is an integer that is monotonically increasing. In cases where -it is identical to the `ref.base.name`, it SHOULD still be included. -It is up to the implementer to decide which value to set as the -revision based on the VCS system and situational context. -""" - -VCS_REF_BASE_TYPE: Final = "vcs.ref.base.type" -""" -The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. -Note: `base` refers to the starting point of a change. For example, `main` -would be the base reference of type branch if you've created a new -reference of type branch from it and created new commits. -""" - -VCS_REF_HEAD_NAME: Final = "vcs.ref.head.name" -""" -The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. -Note: `head` refers to where you are right now; the current reference at a -given time. -""" - -VCS_REF_HEAD_REVISION: Final = "vcs.ref.head.revision" -""" -The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. -Note: `head` refers to where you are right now; the current reference at a -given time.The revision can be a full [hash value (see -glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf), -of the recorded change to a ref within a repository pointing to a -commit [commit](https://git-scm.com/docs/git-commit) object. It does -not necessarily have to be a hash; it can simply define a [revision -number](https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html) -which is an integer that is monotonically increasing. In cases where -it is identical to the `ref.head.name`, it SHOULD still be included. -It is up to the implementer to decide which value to set as the -revision based on the VCS system and situational context. -""" - -VCS_REF_HEAD_TYPE: Final = "vcs.ref.head.type" -""" -The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. -Note: `head` refers to where you are right now; the current reference at a -given time. -""" - -VCS_REF_TYPE: Final = "vcs.ref.type" -""" -The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. -""" - -VCS_REPOSITORY_CHANGE_ID: Final = "vcs.repository.change.id" -""" -Deprecated: Replaced by `vcs.change.id`. -""" - -VCS_REPOSITORY_CHANGE_TITLE: Final = "vcs.repository.change.title" -""" -Deprecated: Replaced by `vcs.change.title`. -""" - -VCS_REPOSITORY_NAME: Final = "vcs.repository.name" -""" -The human readable name of the repository. It SHOULD NOT include any additional identifier like Group/SubGroup in GitLab or organization in GitHub. -Note: Due to it only being the name, it can clash with forks of the same -repository if collecting telemetry across multiple orgs or groups in -the same backends. -""" - -VCS_REPOSITORY_REF_NAME: Final = "vcs.repository.ref.name" -""" -Deprecated: Replaced by `vcs.ref.head.name`. -""" - -VCS_REPOSITORY_REF_REVISION: Final = "vcs.repository.ref.revision" -""" -Deprecated: Replaced by `vcs.ref.head.revision`. -""" - -VCS_REPOSITORY_REF_TYPE: Final = "vcs.repository.ref.type" -""" -Deprecated: Replaced by `vcs.ref.head.type`. -""" - -VCS_REPOSITORY_URL_FULL: Final = "vcs.repository.url.full" -""" -The [canonical URL](https://support.google.com/webmasters/answer/10347851) of the repository providing the complete HTTP(S) address in order to locate and identify the repository through a browser. -Note: In Git Version Control Systems, the canonical URL SHOULD NOT include -the `.git` extension. -""" - -VCS_REVISION_DELTA_DIRECTION: Final = "vcs.revision_delta.direction" -""" -The type of revision comparison. -""" - - -class VcsChangeStateValues(Enum): - OPEN = "open" - """Open means the change is currently active and under review. It hasn't been merged into the target branch yet, and it's still possible to make changes or add comments.""" - WIP = "wip" - """WIP (work-in-progress, draft) means the change is still in progress and not yet ready for a full review. It might still undergo significant changes.""" - CLOSED = "closed" - """Closed means the merge request has been closed without merging. This can happen for various reasons, such as the changes being deemed unnecessary, the issue being resolved in another way, or the author deciding to withdraw the request.""" - MERGED = "merged" - """Merged indicates that the change has been successfully integrated into the target codebase.""" - - -class VcsLineChangeTypeValues(Enum): - ADDED = "added" - """How many lines were added.""" - REMOVED = "removed" - """How many lines were removed.""" - - -class VcsProviderNameValues(Enum): - GITHUB = "github" - """[GitHub](https://github.com).""" - GITLAB = "gitlab" - """[GitLab](https://gitlab.com).""" - GITTEA = "gittea" - """Deprecated: Replaced by `gitea`.""" - GITEA = "gitea" - """[Gitea](https://gitea.io).""" - BITBUCKET = "bitbucket" - """[Bitbucket](https://bitbucket.org).""" - - -class VcsRefBaseTypeValues(Enum): - BRANCH = "branch" - """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" - TAG = "tag" - """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" - - -class VcsRefHeadTypeValues(Enum): - BRANCH = "branch" - """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" - TAG = "tag" - """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" - - -class VcsRefTypeValues(Enum): - BRANCH = "branch" - """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" - TAG = "tag" - """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" - - -@deprecated("The attribute vcs.repository.ref.type is deprecated - Replaced by `vcs.ref.head.type`") -class VcsRepositoryRefTypeValues(Enum): - BRANCH = "branch" - """[branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch).""" - TAG = "tag" - """[tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag).""" - - -class VcsRevisionDeltaDirectionValues(Enum): - BEHIND = "behind" - """How many revisions the change is behind the target ref.""" - AHEAD = "ahead" - """How many revisions the change is ahead of the target ref.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py deleted file mode 100644 index 0d0bf87feae..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/webengine_attributes.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -WEBENGINE_DESCRIPTION: Final = "webengine.description" -""" -Additional description of the web engine (e.g. detailed version and edition information). -""" - -WEBENGINE_NAME: Final = "webengine.name" -""" -The name of the web engine. -""" - -WEBENGINE_VERSION: Final = "webengine.version" -""" -The version of the web engine. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py deleted file mode 100644 index 3c6571076ff..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/attributes/zos_attributes.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -ZOS_SMF_ID: Final = "zos.smf.id" -""" -The System Management Facility (SMF) Identifier uniquely identified a z/OS system within a SYSPLEX or mainframe environment and is used for system and performance analysis. -""" - -ZOS_SYSPLEX_NAME: Final = "zos.sysplex.name" -""" -The name of the SYSPLEX to which the z/OS system belongs too. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py deleted file mode 100644 index 22123af0174..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/azure_metrics.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter, UpDownCounter - -AZURE_COSMOSDB_CLIENT_ACTIVE_INSTANCE_COUNT: Final = "azure.cosmosdb.client.active_instance.count" -""" -Number of active client instances -Instrument: updowncounter -Unit: {instance} -""" - - -def create_azure_cosmosdb_client_active_instance_count(meter: Meter) -> UpDownCounter: - """Number of active client instances""" - return meter.create_up_down_counter( - name=AZURE_COSMOSDB_CLIENT_ACTIVE_INSTANCE_COUNT, - description="Number of active client instances.", - unit="{instance}", - ) - - -AZURE_COSMOSDB_CLIENT_OPERATION_REQUEST_CHARGE: Final = "azure.cosmosdb.client.operation.request_charge" -""" -[Request units](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation -Instrument: histogram -Unit: {request_unit} -""" - - -def create_azure_cosmosdb_client_operation_request_charge(meter: Meter) -> Histogram: - """[Request units](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation""" - return meter.create_histogram( - name=AZURE_COSMOSDB_CLIENT_OPERATION_REQUEST_CHARGE, - description="[Request units](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation.", - unit="{request_unit}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py deleted file mode 100644 index 1ff810e34a3..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cicd_metrics.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter, UpDownCounter - -CICD_PIPELINE_RUN_ACTIVE: Final = "cicd.pipeline.run.active" -""" -The number of pipeline runs currently active in the system by state -Instrument: updowncounter -Unit: {run} -""" - - -def create_cicd_pipeline_run_active(meter: Meter) -> UpDownCounter: - """The number of pipeline runs currently active in the system by state""" - return meter.create_up_down_counter( - name=CICD_PIPELINE_RUN_ACTIVE, - description="The number of pipeline runs currently active in the system by state.", - unit="{run}", - ) - - -CICD_PIPELINE_RUN_DURATION: Final = "cicd.pipeline.run.duration" -""" -Duration of a pipeline run grouped by pipeline, state and result -Instrument: histogram -Unit: s -""" - - -def create_cicd_pipeline_run_duration(meter: Meter) -> Histogram: - """Duration of a pipeline run grouped by pipeline, state and result""" - return meter.create_histogram( - name=CICD_PIPELINE_RUN_DURATION, - description="Duration of a pipeline run grouped by pipeline, state and result.", - unit="s", - ) - - -CICD_PIPELINE_RUN_ERRORS: Final = "cicd.pipeline.run.errors" -""" -The number of errors encountered in pipeline runs (eg. compile, test failures) -Instrument: counter -Unit: {error} -Note: There might be errors in a pipeline run that are non fatal (eg. they are suppressed) or in a parallel stage multiple stages could have a fatal error. -This means that this error count might not be the same as the count of metric `cicd.pipeline.run.duration` with run result `failure`. -""" - - -def create_cicd_pipeline_run_errors(meter: Meter) -> Counter: - """The number of errors encountered in pipeline runs (eg. compile, test failures)""" - return meter.create_counter( - name=CICD_PIPELINE_RUN_ERRORS, - description="The number of errors encountered in pipeline runs (eg. compile, test failures).", - unit="{error}", - ) - - -CICD_SYSTEM_ERRORS: Final = "cicd.system.errors" -""" -The number of errors in a component of the CI/CD system (eg. controller, scheduler, agent) -Instrument: counter -Unit: {error} -Note: Errors in pipeline run execution are explicitly excluded. Ie a test failure is not counted in this metric. -""" - - -def create_cicd_system_errors(meter: Meter) -> Counter: - """The number of errors in a component of the CI/CD system (eg. controller, scheduler, agent)""" - return meter.create_counter( - name=CICD_SYSTEM_ERRORS, - description="The number of errors in a component of the CI/CD system (eg. controller, scheduler, agent).", - unit="{error}", - ) - - -CICD_WORKER_COUNT: Final = "cicd.worker.count" -""" -The number of workers on the CI/CD system by state -Instrument: updowncounter -Unit: {worker} -""" - - -def create_cicd_worker_count(meter: Meter) -> UpDownCounter: - """The number of workers on the CI/CD system by state""" - return meter.create_up_down_counter( - name=CICD_WORKER_COUNT, - description="The number of workers on the CI/CD system by state.", - unit="{worker}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py deleted file mode 100644 index 0a13944ef78..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/container_metrics.py +++ /dev/null @@ -1,281 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable, Generator, Iterable, Sequence -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter - -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -CONTAINER_CPU_TIME: Final = "container.cpu.time" -""" -Total CPU time consumed -Instrument: counter -Unit: s -Note: CPU time consumed by the specific container on all available CPU cores. -""" - - -def create_container_cpu_time(meter: Meter) -> Counter: - """Total CPU time consumed""" - return meter.create_counter( - name=CONTAINER_CPU_TIME, - description="Total CPU time consumed.", - unit="s", - ) - - -CONTAINER_CPU_USAGE: Final = "container.cpu.usage" -""" -Container's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs -Instrument: gauge -Unit: {cpu} -Note: CPU usage of the specific container on all available CPU cores. It is calculated as the change in cumulative CPU time (container.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. -""" - - -def create_container_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Container's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs""" - return meter.create_observable_gauge( - name=CONTAINER_CPU_USAGE, - callbacks=callbacks, - description="Container's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs.", - unit="{cpu}", - ) - - -CONTAINER_DISK_IO: Final = "container.disk.io" -""" -Disk bytes for the container -Instrument: counter -Unit: By -Note: The total number of bytes read/written successfully (aggregated from all disks). -""" - - -def create_container_disk_io(meter: Meter) -> Counter: - """Disk bytes for the container""" - return meter.create_counter( - name=CONTAINER_DISK_IO, - description="Disk bytes for the container.", - unit="By", - ) - - -CONTAINER_FILESYSTEM_AVAILABLE: Final = "container.filesystem.available" -""" -Container filesystem available bytes -Instrument: updowncounter -Unit: By -Note: In K8s, this metric is derived from the -[FsStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [ContainerStats.Rootfs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#ContainerStats) -of the Kubelet's stats API. -""" - - -def create_container_filesystem_available(meter: Meter) -> UpDownCounter: - """Container filesystem available bytes""" - return meter.create_up_down_counter( - name=CONTAINER_FILESYSTEM_AVAILABLE, - description="Container filesystem available bytes.", - unit="By", - ) - - -CONTAINER_FILESYSTEM_CAPACITY: Final = "container.filesystem.capacity" -""" -Container filesystem capacity -Instrument: updowncounter -Unit: By -Note: In K8s, this metric is derived from the -[FsStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [ContainerStats.Rootfs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#ContainerStats) -of the Kubelet's stats API. -""" - - -def create_container_filesystem_capacity(meter: Meter) -> UpDownCounter: - """Container filesystem capacity""" - return meter.create_up_down_counter( - name=CONTAINER_FILESYSTEM_CAPACITY, - description="Container filesystem capacity.", - unit="By", - ) - - -CONTAINER_FILESYSTEM_USAGE: Final = "container.filesystem.usage" -""" -Container filesystem usage -Instrument: updowncounter -Unit: By -Note: This may not equal capacity - available. - -In K8s, this metric is derived from the -[FsStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [ContainerStats.Rootfs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#ContainerStats) -of the Kubelet's stats API. -""" - - -def create_container_filesystem_usage(meter: Meter) -> UpDownCounter: - """Container filesystem usage""" - return meter.create_up_down_counter( - name=CONTAINER_FILESYSTEM_USAGE, - description="Container filesystem usage.", - unit="By", - ) - - -CONTAINER_MEMORY_AVAILABLE: Final = "container.memory.available" -""" -Container memory available -Instrument: updowncounter -Unit: By -Note: Available memory for use. This is defined as the memory limit - workingSetBytes. If memory limit is undefined, the available bytes is omitted. -In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and by subtracting the `container_memory_working_set_bytes` metric from the `container_spec_memory_limit_bytes` metric. -In K8s, this metric is derived from the [MemoryStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. -""" - - -def create_container_memory_available(meter: Meter) -> UpDownCounter: - """Container memory available""" - return meter.create_up_down_counter( - name=CONTAINER_MEMORY_AVAILABLE, - description="Container memory available.", - unit="By", - ) - - -CONTAINER_MEMORY_PAGING_FAULTS: Final = "container.memory.paging.faults" -""" -Deprecated: Replaced by `container.paging.faults`. -""" - - -def create_container_memory_paging_faults(meter: Meter) -> Counter: - """Deprecated, use `container.paging.faults` instead""" - return meter.create_counter( - name=CONTAINER_MEMORY_PAGING_FAULTS, - description="Deprecated, use `container.paging.faults` instead.", - unit="{fault}", - ) - - -CONTAINER_MEMORY_RSS: Final = "container.memory.rss" -""" -Container memory RSS -Instrument: updowncounter -Unit: By -Note: In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_rss` metric. -In K8s, this metric is derived from the [MemoryStats.RSSBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. -""" - - -def create_container_memory_rss(meter: Meter) -> UpDownCounter: - """Container memory RSS""" - return meter.create_up_down_counter( - name=CONTAINER_MEMORY_RSS, - description="Container memory RSS.", - unit="By", - ) - - -CONTAINER_MEMORY_USAGE: Final = "container.memory.usage" -""" -Memory usage of the container -Instrument: updowncounter -Unit: By -Note: Current memory usage, including all memory regardless of when it was accessed. -In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_usage_bytes` metric. -In K8s, this metric is derived from the [MemoryStats.UsageBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. -""" - - -def create_container_memory_usage(meter: Meter) -> UpDownCounter: - """Memory usage of the container""" - return meter.create_up_down_counter( - name=CONTAINER_MEMORY_USAGE, - description="Memory usage of the container.", - unit="By", - ) - - -CONTAINER_MEMORY_WORKING_SET: Final = "container.memory.working_set" -""" -Container memory working set -Instrument: updowncounter -Unit: By -Note: In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_working_set_bytes` metric. -In K8s, this metric is derived from the [MemoryStats.WorkingSetBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. -""" - - -def create_container_memory_working_set(meter: Meter) -> UpDownCounter: - """Container memory working set""" - return meter.create_up_down_counter( - name=CONTAINER_MEMORY_WORKING_SET, - description="Container memory working set.", - unit="By", - ) - - -CONTAINER_NETWORK_IO: Final = "container.network.io" -""" -Network bytes for the container -Instrument: counter -Unit: By -Note: The number of bytes sent/received on all network interfaces by the container. -""" - - -def create_container_network_io(meter: Meter) -> Counter: - """Network bytes for the container""" - return meter.create_counter( - name=CONTAINER_NETWORK_IO, - description="Network bytes for the container.", - unit="By", - ) - - -CONTAINER_PAGING_FAULTS: Final = "container.paging.faults" -""" -Container memory paging faults -Instrument: counter -Unit: {fault} -Note: In general, this metric can be derived from [cadvisor](https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics) and specifically the `container_memory_failures_total{failure_type=pgfault, scope=container}` and `container_memory_failures_total{failure_type=pgmajfault, scope=container}`metric. -In K8s, this metric is derived from the [MemoryStats.PageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) and [MemoryStats.MajorPageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [ContainerStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#ContainerStats) of the Kubelet's stats API. -""" - - -def create_container_paging_faults(meter: Meter) -> Counter: - """Container memory paging faults""" - return meter.create_counter( - name=CONTAINER_PAGING_FAULTS, - description="Container memory paging faults.", - unit="{fault}", - ) - - -CONTAINER_UPTIME: Final = "container.uptime" -""" -The time the container has been running -Instrument: gauge -Unit: s -Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. -The actual accuracy would depend on the instrumentation and operating system. -""" - - -def create_container_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The time the container has been running""" - return meter.create_observable_gauge( - name=CONTAINER_UPTIME, - callbacks=callbacks, - description="The time the container has been running.", - unit="s", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py deleted file mode 100644 index 286d6dc0ac1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpu_metrics.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable, Generator, Iterable, Sequence -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation - -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -CPU_FREQUENCY: Final = "cpu.frequency" -""" -Deprecated: Replaced by `system.cpu.frequency`. -""" - - -def create_cpu_frequency(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Deprecated. Use `system.cpu.frequency` instead""" - return meter.create_observable_gauge( - name=CPU_FREQUENCY, - callbacks=callbacks, - description="Deprecated. Use `system.cpu.frequency` instead.", - unit="{Hz}", - ) - - -CPU_TIME: Final = "cpu.time" -""" -Deprecated: Replaced by `system.cpu.time`. -""" - - -def create_cpu_time(meter: Meter) -> Counter: - """Deprecated. Use `system.cpu.time` instead""" - return meter.create_counter( - name=CPU_TIME, - description="Deprecated. Use `system.cpu.time` instead.", - unit="s", - ) - - -CPU_UTILIZATION: Final = "cpu.utilization" -""" -Deprecated: Replaced by `system.cpu.utilization`. -""" - - -def create_cpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Deprecated. Use `system.cpu.utilization` instead""" - return meter.create_observable_gauge( - name=CPU_UTILIZATION, - callbacks=callbacks, - description="Deprecated. Use `system.cpu.utilization` instead.", - unit="1", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py deleted file mode 100644 index be242849e2d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/cpython_metrics.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Meter - -CPYTHON_GC_COLLECTED_OBJECTS: Final = "cpython.gc.collected_objects" -""" -The total number of objects collected inside a generation since interpreter start -Instrument: counter -Unit: {object} -Note: This metric reports data from [`gc.stats()`](https://docs.python.org/3/library/gc.html#gc.get_stats). -""" - - -def create_cpython_gc_collected_objects(meter: Meter) -> Counter: - """The total number of objects collected inside a generation since interpreter start""" - return meter.create_counter( - name=CPYTHON_GC_COLLECTED_OBJECTS, - description="The total number of objects collected inside a generation since interpreter start.", - unit="{object}", - ) - - -CPYTHON_GC_COLLECTIONS: Final = "cpython.gc.collections" -""" -The number of times a generation was collected since interpreter start -Instrument: counter -Unit: {collection} -Note: This metric reports data from [`gc.stats()`](https://docs.python.org/3/library/gc.html#gc.get_stats). -""" - - -def create_cpython_gc_collections(meter: Meter) -> Counter: - """The number of times a generation was collected since interpreter start""" - return meter.create_counter( - name=CPYTHON_GC_COLLECTIONS, - description="The number of times a generation was collected since interpreter start.", - unit="{collection}", - ) - - -CPYTHON_GC_UNCOLLECTABLE_OBJECTS: Final = "cpython.gc.uncollectable_objects" -""" -The total number of objects which were found to be uncollectable inside a generation since interpreter start -Instrument: counter -Unit: {object} -Note: This metric reports data from [`gc.stats()`](https://docs.python.org/3/library/gc.html#gc.get_stats). -""" - - -def create_cpython_gc_uncollectable_objects(meter: Meter) -> Counter: - """The total number of objects which were found to be uncollectable inside a generation since interpreter start""" - return meter.create_counter( - name=CPYTHON_GC_UNCOLLECTABLE_OBJECTS, - description="The total number of objects which were found to be uncollectable inside a generation since interpreter start.", - unit="{object}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py deleted file mode 100644 index bbce85bd7d0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/db_metrics.py +++ /dev/null @@ -1,356 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter, UpDownCounter - -DB_CLIENT_CONNECTION_COUNT: Final = "db.client.connection.count" -""" -The number of connections that are currently in state described by the `state` attribute -Instrument: updowncounter -Unit: {connection} -""" - - -def create_db_client_connection_count(meter: Meter) -> UpDownCounter: - """The number of connections that are currently in state described by the `state` attribute""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTION_COUNT, - description="The number of connections that are currently in state described by the `state` attribute.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTION_CREATE_TIME: Final = "db.client.connection.create_time" -""" -The time it took to create a new connection -Instrument: histogram -Unit: s -""" - - -def create_db_client_connection_create_time(meter: Meter) -> Histogram: - """The time it took to create a new connection""" - return meter.create_histogram( - name=DB_CLIENT_CONNECTION_CREATE_TIME, - description="The time it took to create a new connection.", - unit="s", - ) - - -DB_CLIENT_CONNECTION_IDLE_MAX: Final = "db.client.connection.idle.max" -""" -The maximum number of idle open connections allowed -Instrument: updowncounter -Unit: {connection} -""" - - -def create_db_client_connection_idle_max(meter: Meter) -> UpDownCounter: - """The maximum number of idle open connections allowed""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTION_IDLE_MAX, - description="The maximum number of idle open connections allowed.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTION_IDLE_MIN: Final = "db.client.connection.idle.min" -""" -The minimum number of idle open connections allowed -Instrument: updowncounter -Unit: {connection} -""" - - -def create_db_client_connection_idle_min(meter: Meter) -> UpDownCounter: - """The minimum number of idle open connections allowed""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTION_IDLE_MIN, - description="The minimum number of idle open connections allowed.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTION_MAX: Final = "db.client.connection.max" -""" -The maximum number of open connections allowed -Instrument: updowncounter -Unit: {connection} -""" - - -def create_db_client_connection_max(meter: Meter) -> UpDownCounter: - """The maximum number of open connections allowed""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTION_MAX, - description="The maximum number of open connections allowed.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTION_PENDING_REQUESTS: Final = "db.client.connection.pending_requests" -""" -The number of current pending requests for an open connection -Instrument: updowncounter -Unit: {request} -""" - - -def create_db_client_connection_pending_requests(meter: Meter) -> UpDownCounter: - """The number of current pending requests for an open connection""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTION_PENDING_REQUESTS, - description="The number of current pending requests for an open connection.", - unit="{request}", - ) - - -DB_CLIENT_CONNECTION_TIMEOUTS: Final = "db.client.connection.timeouts" -""" -The number of connection timeouts that have occurred trying to obtain a connection from the pool -Instrument: counter -Unit: {timeout} -""" - - -def create_db_client_connection_timeouts(meter: Meter) -> Counter: - """The number of connection timeouts that have occurred trying to obtain a connection from the pool""" - return meter.create_counter( - name=DB_CLIENT_CONNECTION_TIMEOUTS, - description="The number of connection timeouts that have occurred trying to obtain a connection from the pool.", - unit="{timeout}", - ) - - -DB_CLIENT_CONNECTION_USE_TIME: Final = "db.client.connection.use_time" -""" -The time between borrowing a connection and returning it to the pool -Instrument: histogram -Unit: s -""" - - -def create_db_client_connection_use_time(meter: Meter) -> Histogram: - """The time between borrowing a connection and returning it to the pool""" - return meter.create_histogram( - name=DB_CLIENT_CONNECTION_USE_TIME, - description="The time between borrowing a connection and returning it to the pool.", - unit="s", - ) - - -DB_CLIENT_CONNECTION_WAIT_TIME: Final = "db.client.connection.wait_time" -""" -The time it took to obtain an open connection from the pool -Instrument: histogram -Unit: s -""" - - -def create_db_client_connection_wait_time(meter: Meter) -> Histogram: - """The time it took to obtain an open connection from the pool""" - return meter.create_histogram( - name=DB_CLIENT_CONNECTION_WAIT_TIME, - description="The time it took to obtain an open connection from the pool.", - unit="s", - ) - - -DB_CLIENT_CONNECTIONS_CREATE_TIME: Final = "db.client.connections.create_time" -""" -Deprecated: Replaced by `db.client.connection.create_time` with unit `s`. -""" - - -def create_db_client_connections_create_time(meter: Meter) -> Histogram: - """Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`""" - return meter.create_histogram( - name=DB_CLIENT_CONNECTIONS_CREATE_TIME, - description="Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`.", - unit="ms", - ) - - -DB_CLIENT_CONNECTIONS_IDLE_MAX: Final = "db.client.connections.idle.max" -""" -Deprecated: Replaced by `db.client.connection.idle.max`. -""" - - -def create_db_client_connections_idle_max(meter: Meter) -> UpDownCounter: - """Deprecated, use `db.client.connection.idle.max` instead""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTIONS_IDLE_MAX, - description="Deprecated, use `db.client.connection.idle.max` instead.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTIONS_IDLE_MIN: Final = "db.client.connections.idle.min" -""" -Deprecated: Replaced by `db.client.connection.idle.min`. -""" - - -def create_db_client_connections_idle_min(meter: Meter) -> UpDownCounter: - """Deprecated, use `db.client.connection.idle.min` instead""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTIONS_IDLE_MIN, - description="Deprecated, use `db.client.connection.idle.min` instead.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTIONS_MAX: Final = "db.client.connections.max" -""" -Deprecated: Replaced by `db.client.connection.max`. -""" - - -def create_db_client_connections_max(meter: Meter) -> UpDownCounter: - """Deprecated, use `db.client.connection.max` instead""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTIONS_MAX, - description="Deprecated, use `db.client.connection.max` instead.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTIONS_PENDING_REQUESTS: Final = "db.client.connections.pending_requests" -""" -Deprecated: Replaced by `db.client.connection.pending_requests`. -""" - - -def create_db_client_connections_pending_requests(meter: Meter) -> UpDownCounter: - """Deprecated, use `db.client.connection.pending_requests` instead""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTIONS_PENDING_REQUESTS, - description="Deprecated, use `db.client.connection.pending_requests` instead.", - unit="{request}", - ) - - -DB_CLIENT_CONNECTIONS_TIMEOUTS: Final = "db.client.connections.timeouts" -""" -Deprecated: Replaced by `db.client.connection.timeouts`. -""" - - -def create_db_client_connections_timeouts(meter: Meter) -> Counter: - """Deprecated, use `db.client.connection.timeouts` instead""" - return meter.create_counter( - name=DB_CLIENT_CONNECTIONS_TIMEOUTS, - description="Deprecated, use `db.client.connection.timeouts` instead.", - unit="{timeout}", - ) - - -DB_CLIENT_CONNECTIONS_USAGE: Final = "db.client.connections.usage" -""" -Deprecated: Replaced by `db.client.connection.count`. -""" - - -def create_db_client_connections_usage(meter: Meter) -> UpDownCounter: - """Deprecated, use `db.client.connection.count` instead""" - return meter.create_up_down_counter( - name=DB_CLIENT_CONNECTIONS_USAGE, - description="Deprecated, use `db.client.connection.count` instead.", - unit="{connection}", - ) - - -DB_CLIENT_CONNECTIONS_USE_TIME: Final = "db.client.connections.use_time" -""" -Deprecated: Replaced by `db.client.connection.use_time` with unit `s`. -""" - - -def create_db_client_connections_use_time(meter: Meter) -> Histogram: - """Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`""" - return meter.create_histogram( - name=DB_CLIENT_CONNECTIONS_USE_TIME, - description="Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`.", - unit="ms", - ) - - -DB_CLIENT_CONNECTIONS_WAIT_TIME: Final = "db.client.connections.wait_time" -""" -Deprecated: Replaced by `db.client.connection.wait_time` with unit `s`. -""" - - -def create_db_client_connections_wait_time(meter: Meter) -> Histogram: - """Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`""" - return meter.create_histogram( - name=DB_CLIENT_CONNECTIONS_WAIT_TIME, - description="Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`.", - unit="ms", - ) - - -DB_CLIENT_COSMOSDB_ACTIVE_INSTANCE_COUNT: Final = "db.client.cosmosdb.active_instance.count" -""" -Deprecated: Replaced by `azure.cosmosdb.client.active_instance.count`. -""" - - -def create_db_client_cosmosdb_active_instance_count(meter: Meter) -> UpDownCounter: - """Deprecated, use `azure.cosmosdb.client.active_instance.count` instead""" - return meter.create_up_down_counter( - name=DB_CLIENT_COSMOSDB_ACTIVE_INSTANCE_COUNT, - description="Deprecated, use `azure.cosmosdb.client.active_instance.count` instead.", - unit="{instance}", - ) - - -DB_CLIENT_COSMOSDB_OPERATION_REQUEST_CHARGE: Final = "db.client.cosmosdb.operation.request_charge" -""" -Deprecated: Replaced by `azure.cosmosdb.client.operation.request_charge`. -""" - - -def create_db_client_cosmosdb_operation_request_charge(meter: Meter) -> Histogram: - """Deprecated, use `azure.cosmosdb.client.operation.request_charge` instead""" - return meter.create_histogram( - name=DB_CLIENT_COSMOSDB_OPERATION_REQUEST_CHARGE, - description="Deprecated, use `azure.cosmosdb.client.operation.request_charge` instead.", - unit="{request_unit}", - ) - - -DB_CLIENT_OPERATION_DURATION: Final = "db.client.operation.duration" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.db_metrics.DB_CLIENT_OPERATION_DURATION`. -""" - - -def create_db_client_operation_duration(meter: Meter) -> Histogram: - """Duration of database client operations""" - return meter.create_histogram( - name=DB_CLIENT_OPERATION_DURATION, - description="Duration of database client operations.", - unit="s", - ) - - -DB_CLIENT_RESPONSE_RETURNED_ROWS: Final = "db.client.response.returned_rows" -""" -The actual number of records returned by the database operation -Instrument: histogram -Unit: {row} -""" - - -def create_db_client_response_returned_rows(meter: Meter) -> Histogram: - """The actual number of records returned by the database operation""" - return meter.create_histogram( - name=DB_CLIENT_RESPONSE_RETURNED_ROWS, - description="The actual number of records returned by the database operation.", - unit="{row}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py deleted file mode 100644 index 1a2ed99125f..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/dns_metrics.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter - -DNS_LOOKUP_DURATION: Final = "dns.lookup.duration" -""" -Measures the time taken to perform a DNS lookup -Instrument: histogram -Unit: s -""" - - -def create_dns_lookup_duration(meter: Meter) -> Histogram: - """Measures the time taken to perform a DNS lookup""" - return meter.create_histogram( - name=DNS_LOOKUP_DURATION, - description="Measures the time taken to perform a DNS lookup.", - unit="s", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py deleted file mode 100644 index 48bc12c3960..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/faas_metrics.py +++ /dev/null @@ -1,159 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter - -FAAS_COLDSTARTS: Final = "faas.coldstarts" -""" -Number of invocation cold starts -Instrument: counter -Unit: {coldstart} -""" - - -def create_faas_coldstarts(meter: Meter) -> Counter: - """Number of invocation cold starts""" - return meter.create_counter( - name=FAAS_COLDSTARTS, - description="Number of invocation cold starts.", - unit="{coldstart}", - ) - - -FAAS_CPU_USAGE: Final = "faas.cpu_usage" -""" -Distribution of CPU usage per invocation -Instrument: histogram -Unit: s -""" - - -def create_faas_cpu_usage(meter: Meter) -> Histogram: - """Distribution of CPU usage per invocation""" - return meter.create_histogram( - name=FAAS_CPU_USAGE, - description="Distribution of CPU usage per invocation.", - unit="s", - ) - - -FAAS_ERRORS: Final = "faas.errors" -""" -Number of invocation errors -Instrument: counter -Unit: {error} -""" - - -def create_faas_errors(meter: Meter) -> Counter: - """Number of invocation errors""" - return meter.create_counter( - name=FAAS_ERRORS, - description="Number of invocation errors.", - unit="{error}", - ) - - -FAAS_INIT_DURATION: Final = "faas.init_duration" -""" -Measures the duration of the function's initialization, such as a cold start -Instrument: histogram -Unit: s -""" - - -def create_faas_init_duration(meter: Meter) -> Histogram: - """Measures the duration of the function's initialization, such as a cold start""" - return meter.create_histogram( - name=FAAS_INIT_DURATION, - description="Measures the duration of the function's initialization, such as a cold start.", - unit="s", - ) - - -FAAS_INVOCATIONS: Final = "faas.invocations" -""" -Number of successful invocations -Instrument: counter -Unit: {invocation} -""" - - -def create_faas_invocations(meter: Meter) -> Counter: - """Number of successful invocations""" - return meter.create_counter( - name=FAAS_INVOCATIONS, - description="Number of successful invocations.", - unit="{invocation}", - ) - - -FAAS_INVOKE_DURATION: Final = "faas.invoke_duration" -""" -Measures the duration of the function's logic execution -Instrument: histogram -Unit: s -""" - - -def create_faas_invoke_duration(meter: Meter) -> Histogram: - """Measures the duration of the function's logic execution""" - return meter.create_histogram( - name=FAAS_INVOKE_DURATION, - description="Measures the duration of the function's logic execution.", - unit="s", - ) - - -FAAS_MEM_USAGE: Final = "faas.mem_usage" -""" -Distribution of max memory usage per invocation -Instrument: histogram -Unit: By -""" - - -def create_faas_mem_usage(meter: Meter) -> Histogram: - """Distribution of max memory usage per invocation""" - return meter.create_histogram( - name=FAAS_MEM_USAGE, - description="Distribution of max memory usage per invocation.", - unit="By", - ) - - -FAAS_NET_IO: Final = "faas.net_io" -""" -Distribution of net I/O usage per invocation -Instrument: histogram -Unit: By -""" - - -def create_faas_net_io(meter: Meter) -> Histogram: - """Distribution of net I/O usage per invocation""" - return meter.create_histogram( - name=FAAS_NET_IO, - description="Distribution of net I/O usage per invocation.", - unit="By", - ) - - -FAAS_TIMEOUTS: Final = "faas.timeouts" -""" -Number of invocation timeouts -Instrument: counter -Unit: {timeout} -""" - - -def create_faas_timeouts(meter: Meter) -> Counter: - """Number of invocation timeouts""" - return meter.create_counter( - name=FAAS_TIMEOUTS, - description="Number of invocation timeouts.", - unit="{timeout}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py deleted file mode 100644 index 22e6ce6e39d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/gen_ai_metrics.py +++ /dev/null @@ -1,111 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter - -GEN_AI_CLIENT_OPERATION_DURATION: Final = "gen_ai.client.operation.duration" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_gen_ai_client_operation_duration(meter: Meter) -> Histogram: - """GenAI operation duration""" - return meter.create_histogram( - name=GEN_AI_CLIENT_OPERATION_DURATION, - description="GenAI operation duration.", - unit="s", - ) - - -GEN_AI_CLIENT_OPERATION_TIME_PER_OUTPUT_CHUNK: Final = "gen_ai.client.operation.time_per_output_chunk" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_gen_ai_client_operation_time_per_output_chunk(meter: Meter) -> Histogram: - """Time per output chunk, recorded for each chunk received after the first one, measured as the time elapsed from the end of the previous chunk to the end of the current chunk""" - return meter.create_histogram( - name=GEN_AI_CLIENT_OPERATION_TIME_PER_OUTPUT_CHUNK, - description="Time per output chunk, recorded for each chunk received after the first one, measured as the time elapsed from the end of the previous chunk to the end of the current chunk.", - unit="s", - ) - - -GEN_AI_CLIENT_OPERATION_TIME_TO_FIRST_CHUNK: Final = "gen_ai.client.operation.time_to_first_chunk" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_gen_ai_client_operation_time_to_first_chunk(meter: Meter) -> Histogram: - """Time to receive the first chunk, measured from when the client issues the generation request to when the first chunk is received in the response stream""" - return meter.create_histogram( - name=GEN_AI_CLIENT_OPERATION_TIME_TO_FIRST_CHUNK, - description="Time to receive the first chunk, measured from when the client issues the generation request to when the first chunk is received in the response stream.", - unit="s", - ) - - -GEN_AI_CLIENT_TOKEN_USAGE: Final = "gen_ai.client.token.usage" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_gen_ai_client_token_usage(meter: Meter) -> Histogram: - """Number of input and output tokens used""" - return meter.create_histogram( - name=GEN_AI_CLIENT_TOKEN_USAGE, - description="Number of input and output tokens used.", - unit="{token}", - ) - - -GEN_AI_SERVER_REQUEST_DURATION: Final = "gen_ai.server.request.duration" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_gen_ai_server_request_duration(meter: Meter) -> Histogram: - """Generative AI server request duration such as time-to-last byte or last output token""" - return meter.create_histogram( - name=GEN_AI_SERVER_REQUEST_DURATION, - description="Generative AI server request duration such as time-to-last byte or last output token.", - unit="s", - ) - - -GEN_AI_SERVER_TIME_PER_OUTPUT_TOKEN: Final = "gen_ai.server.time_per_output_token" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_gen_ai_server_time_per_output_token(meter: Meter) -> Histogram: - """Time per output token generated after the first token for successful responses""" - return meter.create_histogram( - name=GEN_AI_SERVER_TIME_PER_OUTPUT_TOKEN, - description="Time per output token generated after the first token for successful responses.", - unit="s", - ) - - -GEN_AI_SERVER_TIME_TO_FIRST_TOKEN: Final = "gen_ai.server.time_to_first_token" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_gen_ai_server_time_to_first_token(meter: Meter) -> Histogram: - """Time to generate first token for successful responses""" - return meter.create_histogram( - name=GEN_AI_SERVER_TIME_TO_FIRST_TOKEN, - description="Time to generate first token for successful responses.", - unit="s", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py deleted file mode 100644 index fd7aa61fc94..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/http_metrics.py +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter, UpDownCounter - -HTTP_CLIENT_ACTIVE_REQUESTS: Final = "http.client.active_requests" -""" -Number of active HTTP requests -Instrument: updowncounter -Unit: {request} -""" - - -def create_http_client_active_requests(meter: Meter) -> UpDownCounter: - """Number of active HTTP requests""" - return meter.create_up_down_counter( - name=HTTP_CLIENT_ACTIVE_REQUESTS, - description="Number of active HTTP requests.", - unit="{request}", - ) - - -HTTP_CLIENT_CONNECTION_DURATION: Final = "http.client.connection.duration" -""" -The duration of the successfully established outbound HTTP connections -Instrument: histogram -Unit: s -""" - - -def create_http_client_connection_duration(meter: Meter) -> Histogram: - """The duration of the successfully established outbound HTTP connections""" - return meter.create_histogram( - name=HTTP_CLIENT_CONNECTION_DURATION, - description="The duration of the successfully established outbound HTTP connections.", - unit="s", - ) - - -HTTP_CLIENT_OPEN_CONNECTIONS: Final = "http.client.open_connections" -""" -Number of outbound HTTP connections that are currently active or idle on the client -Instrument: updowncounter -Unit: {connection} -""" - - -def create_http_client_open_connections(meter: Meter) -> UpDownCounter: - """Number of outbound HTTP connections that are currently active or idle on the client""" - return meter.create_up_down_counter( - name=HTTP_CLIENT_OPEN_CONNECTIONS, - description="Number of outbound HTTP connections that are currently active or idle on the client.", - unit="{connection}", - ) - - -HTTP_CLIENT_REQUEST_BODY_SIZE: Final = "http.client.request.body.size" -""" -Size of HTTP client request bodies -Instrument: histogram -Unit: By -Note: The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. -""" - - -def create_http_client_request_body_size(meter: Meter) -> Histogram: - """Size of HTTP client request bodies""" - return meter.create_histogram( - name=HTTP_CLIENT_REQUEST_BODY_SIZE, - description="Size of HTTP client request bodies.", - unit="By", - ) - - -HTTP_CLIENT_REQUEST_DURATION: Final = "http.client.request.duration" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.http_metrics.HTTP_CLIENT_REQUEST_DURATION`. -""" - - -def create_http_client_request_duration(meter: Meter) -> Histogram: - """Duration of HTTP client requests""" - return meter.create_histogram( - name=HTTP_CLIENT_REQUEST_DURATION, - description="Duration of HTTP client requests.", - unit="s", - ) - - -HTTP_CLIENT_RESPONSE_BODY_SIZE: Final = "http.client.response.body.size" -""" -Size of HTTP client response bodies -Instrument: histogram -Unit: By -Note: The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. -""" - - -def create_http_client_response_body_size(meter: Meter) -> Histogram: - """Size of HTTP client response bodies""" - return meter.create_histogram( - name=HTTP_CLIENT_RESPONSE_BODY_SIZE, - description="Size of HTTP client response bodies.", - unit="By", - ) - - -HTTP_SERVER_ACTIVE_REQUESTS: Final = "http.server.active_requests" -""" -Number of active HTTP server requests -Instrument: updowncounter -Unit: {request} -""" - - -def create_http_server_active_requests(meter: Meter) -> UpDownCounter: - """Number of active HTTP server requests""" - return meter.create_up_down_counter( - name=HTTP_SERVER_ACTIVE_REQUESTS, - description="Number of active HTTP server requests.", - unit="{request}", - ) - - -HTTP_SERVER_REQUEST_BODY_SIZE: Final = "http.server.request.body.size" -""" -Size of HTTP server request bodies -Instrument: histogram -Unit: By -Note: The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. -""" - - -def create_http_server_request_body_size(meter: Meter) -> Histogram: - """Size of HTTP server request bodies""" - return meter.create_histogram( - name=HTTP_SERVER_REQUEST_BODY_SIZE, - description="Size of HTTP server request bodies.", - unit="By", - ) - - -HTTP_SERVER_REQUEST_DURATION: Final = "http.server.request.duration" -""" -Deprecated in favor of stable :py:const:`opentelemetry.semconv.metrics.http_metrics.HTTP_SERVER_REQUEST_DURATION`. -""" - - -def create_http_server_request_duration(meter: Meter) -> Histogram: - """Duration of HTTP server requests""" - return meter.create_histogram( - name=HTTP_SERVER_REQUEST_DURATION, - description="Duration of HTTP server requests.", - unit="s", - ) - - -HTTP_SERVER_RESPONSE_BODY_SIZE: Final = "http.server.response.body.size" -""" -Size of HTTP server response bodies -Instrument: histogram -Unit: By -Note: The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. -""" - - -def create_http_server_response_body_size(meter: Meter) -> Histogram: - """Size of HTTP server response bodies""" - return meter.create_histogram( - name=HTTP_SERVER_RESPONSE_BODY_SIZE, - description="Size of HTTP server response bodies.", - unit="By", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py deleted file mode 100644 index f42b0593dee..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/hw_metrics.py +++ /dev/null @@ -1,755 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable, Generator, Iterable, Sequence -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter - -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -HW_BATTERY_CHARGE: Final = "hw.battery.charge" -""" -Remaining fraction of battery charge -Instrument: gauge -Unit: 1 -""" - - -def create_hw_battery_charge(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Remaining fraction of battery charge""" - return meter.create_observable_gauge( - name=HW_BATTERY_CHARGE, - callbacks=callbacks, - description="Remaining fraction of battery charge.", - unit="1", - ) - - -HW_BATTERY_CHARGE_LIMIT: Final = "hw.battery.charge.limit" -""" -Lower limit of battery charge fraction to ensure proper operation -Instrument: gauge -Unit: 1 -""" - - -def create_hw_battery_charge_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Lower limit of battery charge fraction to ensure proper operation""" - return meter.create_observable_gauge( - name=HW_BATTERY_CHARGE_LIMIT, - callbacks=callbacks, - description="Lower limit of battery charge fraction to ensure proper operation.", - unit="1", - ) - - -HW_BATTERY_TIME_LEFT: Final = "hw.battery.time_left" -""" -Time left before battery is completely charged or discharged -Instrument: gauge -Unit: s -""" - - -def create_hw_battery_time_left(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Time left before battery is completely charged or discharged""" - return meter.create_observable_gauge( - name=HW_BATTERY_TIME_LEFT, - callbacks=callbacks, - description="Time left before battery is completely charged or discharged.", - unit="s", - ) - - -HW_CPU_SPEED: Final = "hw.cpu.speed" -""" -CPU current frequency -Instrument: gauge -Unit: Hz -""" - - -def create_hw_cpu_speed(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """CPU current frequency""" - return meter.create_observable_gauge( - name=HW_CPU_SPEED, - callbacks=callbacks, - description="CPU current frequency.", - unit="Hz", - ) - - -HW_CPU_SPEED_LIMIT: Final = "hw.cpu.speed.limit" -""" -CPU maximum frequency -Instrument: gauge -Unit: Hz -""" - - -def create_hw_cpu_speed_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """CPU maximum frequency""" - return meter.create_observable_gauge( - name=HW_CPU_SPEED_LIMIT, - callbacks=callbacks, - description="CPU maximum frequency.", - unit="Hz", - ) - - -HW_ENERGY: Final = "hw.energy" -""" -Energy consumed by the component -Instrument: counter -Unit: J -""" - - -def create_hw_energy(meter: Meter) -> Counter: - """Energy consumed by the component""" - return meter.create_counter( - name=HW_ENERGY, - description="Energy consumed by the component.", - unit="J", - ) - - -HW_ERRORS: Final = "hw.errors" -""" -Number of errors encountered by the component -Instrument: counter -Unit: {error} -""" - - -def create_hw_errors(meter: Meter) -> Counter: - """Number of errors encountered by the component""" - return meter.create_counter( - name=HW_ERRORS, - description="Number of errors encountered by the component.", - unit="{error}", - ) - - -HW_FAN_SPEED: Final = "hw.fan.speed" -""" -Fan speed in revolutions per minute -Instrument: gauge -Unit: rpm -""" - - -def create_hw_fan_speed(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Fan speed in revolutions per minute""" - return meter.create_observable_gauge( - name=HW_FAN_SPEED, - callbacks=callbacks, - description="Fan speed in revolutions per minute.", - unit="rpm", - ) - - -HW_FAN_SPEED_LIMIT: Final = "hw.fan.speed.limit" -""" -Speed limit in rpm -Instrument: gauge -Unit: rpm -""" - - -def create_hw_fan_speed_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Speed limit in rpm""" - return meter.create_observable_gauge( - name=HW_FAN_SPEED_LIMIT, - callbacks=callbacks, - description="Speed limit in rpm.", - unit="rpm", - ) - - -HW_FAN_SPEED_RATIO: Final = "hw.fan.speed_ratio" -""" -Fan speed expressed as a fraction of its maximum speed -Instrument: gauge -Unit: 1 -""" - - -def create_hw_fan_speed_ratio(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Fan speed expressed as a fraction of its maximum speed""" - return meter.create_observable_gauge( - name=HW_FAN_SPEED_RATIO, - callbacks=callbacks, - description="Fan speed expressed as a fraction of its maximum speed.", - unit="1", - ) - - -HW_GPU_IO: Final = "hw.gpu.io" -""" -Received and transmitted bytes by the GPU -Instrument: counter -Unit: By -""" - - -def create_hw_gpu_io(meter: Meter) -> Counter: - """Received and transmitted bytes by the GPU""" - return meter.create_counter( - name=HW_GPU_IO, - description="Received and transmitted bytes by the GPU.", - unit="By", - ) - - -HW_GPU_MEMORY_LIMIT: Final = "hw.gpu.memory.limit" -""" -Size of the GPU memory -Instrument: updowncounter -Unit: By -""" - - -def create_hw_gpu_memory_limit(meter: Meter) -> UpDownCounter: - """Size of the GPU memory""" - return meter.create_up_down_counter( - name=HW_GPU_MEMORY_LIMIT, - description="Size of the GPU memory.", - unit="By", - ) - - -HW_GPU_MEMORY_USAGE: Final = "hw.gpu.memory.usage" -""" -GPU memory used -Instrument: updowncounter -Unit: By -""" - - -def create_hw_gpu_memory_usage(meter: Meter) -> UpDownCounter: - """GPU memory used""" - return meter.create_up_down_counter( - name=HW_GPU_MEMORY_USAGE, - description="GPU memory used.", - unit="By", - ) - - -HW_GPU_MEMORY_UTILIZATION: Final = "hw.gpu.memory.utilization" -""" -Fraction of GPU memory used -Instrument: gauge -Unit: 1 -""" - - -def create_hw_gpu_memory_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Fraction of GPU memory used""" - return meter.create_observable_gauge( - name=HW_GPU_MEMORY_UTILIZATION, - callbacks=callbacks, - description="Fraction of GPU memory used.", - unit="1", - ) - - -HW_GPU_UTILIZATION: Final = "hw.gpu.utilization" -""" -Fraction of time spent in a specific task -Instrument: gauge -Unit: 1 -""" - - -def create_hw_gpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Fraction of time spent in a specific task""" - return meter.create_observable_gauge( - name=HW_GPU_UTILIZATION, - callbacks=callbacks, - description="Fraction of time spent in a specific task.", - unit="1", - ) - - -HW_HOST_AMBIENT_TEMPERATURE: Final = "hw.host.ambient_temperature" -""" -Ambient (external) temperature of the physical host -Instrument: gauge -Unit: Cel -""" - - -def create_hw_host_ambient_temperature(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Ambient (external) temperature of the physical host""" - return meter.create_observable_gauge( - name=HW_HOST_AMBIENT_TEMPERATURE, - callbacks=callbacks, - description="Ambient (external) temperature of the physical host.", - unit="Cel", - ) - - -HW_HOST_ENERGY: Final = "hw.host.energy" -""" -Total energy consumed by the entire physical host, in joules -Instrument: counter -Unit: J -Note: The overall energy usage of a host MUST be reported using the specific `hw.host.energy` and `hw.host.power` metrics **only**, instead of the generic `hw.energy` and `hw.power` described in the previous section, to prevent summing up overlapping values. -""" - - -def create_hw_host_energy(meter: Meter) -> Counter: - """Total energy consumed by the entire physical host, in joules""" - return meter.create_counter( - name=HW_HOST_ENERGY, - description="Total energy consumed by the entire physical host, in joules.", - unit="J", - ) - - -HW_HOST_HEATING_MARGIN: Final = "hw.host.heating_margin" -""" -By how many degrees Celsius the temperature of the physical host can be increased, before reaching a warning threshold on one of the internal sensors -Instrument: gauge -Unit: Cel -""" - - -def create_hw_host_heating_margin(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """By how many degrees Celsius the temperature of the physical host can be increased, before reaching a warning threshold on one of the internal sensors""" - return meter.create_observable_gauge( - name=HW_HOST_HEATING_MARGIN, - callbacks=callbacks, - description="By how many degrees Celsius the temperature of the physical host can be increased, before reaching a warning threshold on one of the internal sensors.", - unit="Cel", - ) - - -HW_HOST_POWER: Final = "hw.host.power" -""" -Instantaneous power consumed by the entire physical host in Watts (`hw.host.energy` is preferred) -Instrument: gauge -Unit: W -Note: The overall energy usage of a host MUST be reported using the specific `hw.host.energy` and `hw.host.power` metrics **only**, instead of the generic `hw.energy` and `hw.power` described in the previous section, to prevent summing up overlapping values. -""" - - -def create_hw_host_power(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Instantaneous power consumed by the entire physical host in Watts (`hw.host.energy` is preferred)""" - return meter.create_observable_gauge( - name=HW_HOST_POWER, - callbacks=callbacks, - description="Instantaneous power consumed by the entire physical host in Watts (`hw.host.energy` is preferred).", - unit="W", - ) - - -HW_LOGICAL_DISK_LIMIT: Final = "hw.logical_disk.limit" -""" -Size of the logical disk -Instrument: updowncounter -Unit: By -""" - - -def create_hw_logical_disk_limit(meter: Meter) -> UpDownCounter: - """Size of the logical disk""" - return meter.create_up_down_counter( - name=HW_LOGICAL_DISK_LIMIT, - description="Size of the logical disk.", - unit="By", - ) - - -HW_LOGICAL_DISK_USAGE: Final = "hw.logical_disk.usage" -""" -Logical disk space usage -Instrument: updowncounter -Unit: By -""" - - -def create_hw_logical_disk_usage(meter: Meter) -> UpDownCounter: - """Logical disk space usage""" - return meter.create_up_down_counter( - name=HW_LOGICAL_DISK_USAGE, - description="Logical disk space usage.", - unit="By", - ) - - -HW_LOGICAL_DISK_UTILIZATION: Final = "hw.logical_disk.utilization" -""" -Logical disk space utilization as a fraction -Instrument: gauge -Unit: 1 -""" - - -def create_hw_logical_disk_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Logical disk space utilization as a fraction""" - return meter.create_observable_gauge( - name=HW_LOGICAL_DISK_UTILIZATION, - callbacks=callbacks, - description="Logical disk space utilization as a fraction.", - unit="1", - ) - - -HW_MEMORY_SIZE: Final = "hw.memory.size" -""" -Size of the memory module -Instrument: updowncounter -Unit: By -""" - - -def create_hw_memory_size(meter: Meter) -> UpDownCounter: - """Size of the memory module""" - return meter.create_up_down_counter( - name=HW_MEMORY_SIZE, - description="Size of the memory module.", - unit="By", - ) - - -HW_NETWORK_BANDWIDTH_LIMIT: Final = "hw.network.bandwidth.limit" -""" -Link speed -Instrument: updowncounter -Unit: By/s -""" - - -def create_hw_network_bandwidth_limit(meter: Meter) -> UpDownCounter: - """Link speed""" - return meter.create_up_down_counter( - name=HW_NETWORK_BANDWIDTH_LIMIT, - description="Link speed.", - unit="By/s", - ) - - -HW_NETWORK_BANDWIDTH_UTILIZATION: Final = "hw.network.bandwidth.utilization" -""" -Utilization of the network bandwidth as a fraction -Instrument: gauge -Unit: 1 -""" - - -def create_hw_network_bandwidth_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Utilization of the network bandwidth as a fraction""" - return meter.create_observable_gauge( - name=HW_NETWORK_BANDWIDTH_UTILIZATION, - callbacks=callbacks, - description="Utilization of the network bandwidth as a fraction.", - unit="1", - ) - - -HW_NETWORK_IO: Final = "hw.network.io" -""" -Received and transmitted network traffic in bytes -Instrument: counter -Unit: By -""" - - -def create_hw_network_io(meter: Meter) -> Counter: - """Received and transmitted network traffic in bytes""" - return meter.create_counter( - name=HW_NETWORK_IO, - description="Received and transmitted network traffic in bytes.", - unit="By", - ) - - -HW_NETWORK_PACKETS: Final = "hw.network.packets" -""" -Received and transmitted network traffic in packets (or frames) -Instrument: counter -Unit: {packet} -""" - - -def create_hw_network_packets(meter: Meter) -> Counter: - """Received and transmitted network traffic in packets (or frames)""" - return meter.create_counter( - name=HW_NETWORK_PACKETS, - description="Received and transmitted network traffic in packets (or frames).", - unit="{packet}", - ) - - -HW_NETWORK_UP: Final = "hw.network.up" -""" -Link status: `1` (up) or `0` (down) -Instrument: updowncounter -Unit: 1 -""" - - -def create_hw_network_up(meter: Meter) -> UpDownCounter: - """Link status: `1` (up) or `0` (down)""" - return meter.create_up_down_counter( - name=HW_NETWORK_UP, - description="Link status: `1` (up) or `0` (down).", - unit="1", - ) - - -HW_PHYSICAL_DISK_ENDURANCE_UTILIZATION: Final = "hw.physical_disk.endurance_utilization" -""" -Endurance remaining for this SSD disk -Instrument: gauge -Unit: 1 -""" - - -def create_hw_physical_disk_endurance_utilization( - meter: Meter, callbacks: Sequence[CallbackT] | None -) -> ObservableGauge: - """Endurance remaining for this SSD disk""" - return meter.create_observable_gauge( - name=HW_PHYSICAL_DISK_ENDURANCE_UTILIZATION, - callbacks=callbacks, - description="Endurance remaining for this SSD disk.", - unit="1", - ) - - -HW_PHYSICAL_DISK_SIZE: Final = "hw.physical_disk.size" -""" -Size of the disk -Instrument: updowncounter -Unit: By -""" - - -def create_hw_physical_disk_size(meter: Meter) -> UpDownCounter: - """Size of the disk""" - return meter.create_up_down_counter( - name=HW_PHYSICAL_DISK_SIZE, - description="Size of the disk.", - unit="By", - ) - - -HW_PHYSICAL_DISK_SMART: Final = "hw.physical_disk.smart" -""" -Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute -Instrument: gauge -Unit: 1 -""" - - -def create_hw_physical_disk_smart(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute""" - return meter.create_observable_gauge( - name=HW_PHYSICAL_DISK_SMART, - callbacks=callbacks, - description="Value of the corresponding [S.M.A.R.T.](https://wikipedia.org/wiki/S.M.A.R.T.) (Self-Monitoring, Analysis, and Reporting Technology) attribute.", - unit="1", - ) - - -HW_POWER: Final = "hw.power" -""" -Instantaneous power consumed by the component -Instrument: gauge -Unit: W -Note: It is recommended to report `hw.energy` instead of `hw.power` when possible. -""" - - -def create_hw_power(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Instantaneous power consumed by the component""" - return meter.create_observable_gauge( - name=HW_POWER, - callbacks=callbacks, - description="Instantaneous power consumed by the component.", - unit="W", - ) - - -HW_POWER_SUPPLY_LIMIT: Final = "hw.power_supply.limit" -""" -Maximum power output of the power supply -Instrument: updowncounter -Unit: W -""" - - -def create_hw_power_supply_limit(meter: Meter) -> UpDownCounter: - """Maximum power output of the power supply""" - return meter.create_up_down_counter( - name=HW_POWER_SUPPLY_LIMIT, - description="Maximum power output of the power supply.", - unit="W", - ) - - -HW_POWER_SUPPLY_USAGE: Final = "hw.power_supply.usage" -""" -Current power output of the power supply -Instrument: updowncounter -Unit: W -""" - - -def create_hw_power_supply_usage(meter: Meter) -> UpDownCounter: - """Current power output of the power supply""" - return meter.create_up_down_counter( - name=HW_POWER_SUPPLY_USAGE, - description="Current power output of the power supply.", - unit="W", - ) - - -HW_POWER_SUPPLY_UTILIZATION: Final = "hw.power_supply.utilization" -""" -Utilization of the power supply as a fraction of its maximum output -Instrument: gauge -Unit: 1 -""" - - -def create_hw_power_supply_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Utilization of the power supply as a fraction of its maximum output""" - return meter.create_observable_gauge( - name=HW_POWER_SUPPLY_UTILIZATION, - callbacks=callbacks, - description="Utilization of the power supply as a fraction of its maximum output.", - unit="1", - ) - - -HW_STATUS: Final = "hw.status" -""" -Operational status: `1` (true) or `0` (false) for each of the possible states -Instrument: updowncounter -Unit: 1 -Note: `hw.status` is currently specified as an *UpDownCounter* but would ideally be represented using a [*StateSet* as defined in OpenMetrics](https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#stateset). This semantic convention will be updated once *StateSet* is specified in OpenTelemetry. This planned change is not expected to have any consequence on the way users query their timeseries backend to retrieve the values of `hw.status` over time. -""" - - -def create_hw_status(meter: Meter) -> UpDownCounter: - """Operational status: `1` (true) or `0` (false) for each of the possible states""" - return meter.create_up_down_counter( - name=HW_STATUS, - description="Operational status: `1` (true) or `0` (false) for each of the possible states.", - unit="1", - ) - - -HW_TAPE_DRIVE_OPERATIONS: Final = "hw.tape_drive.operations" -""" -Operations performed by the tape drive -Instrument: counter -Unit: {operation} -""" - - -def create_hw_tape_drive_operations(meter: Meter) -> Counter: - """Operations performed by the tape drive""" - return meter.create_counter( - name=HW_TAPE_DRIVE_OPERATIONS, - description="Operations performed by the tape drive.", - unit="{operation}", - ) - - -HW_TEMPERATURE: Final = "hw.temperature" -""" -Temperature in degrees Celsius -Instrument: gauge -Unit: Cel -""" - - -def create_hw_temperature(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Temperature in degrees Celsius""" - return meter.create_observable_gauge( - name=HW_TEMPERATURE, - callbacks=callbacks, - description="Temperature in degrees Celsius.", - unit="Cel", - ) - - -HW_TEMPERATURE_LIMIT: Final = "hw.temperature.limit" -""" -Temperature limit in degrees Celsius -Instrument: gauge -Unit: Cel -""" - - -def create_hw_temperature_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Temperature limit in degrees Celsius""" - return meter.create_observable_gauge( - name=HW_TEMPERATURE_LIMIT, - callbacks=callbacks, - description="Temperature limit in degrees Celsius.", - unit="Cel", - ) - - -HW_VOLTAGE: Final = "hw.voltage" -""" -Voltage measured by the sensor -Instrument: gauge -Unit: V -""" - - -def create_hw_voltage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Voltage measured by the sensor""" - return meter.create_observable_gauge( - name=HW_VOLTAGE, - callbacks=callbacks, - description="Voltage measured by the sensor.", - unit="V", - ) - - -HW_VOLTAGE_LIMIT: Final = "hw.voltage.limit" -""" -Voltage limit in Volts -Instrument: gauge -Unit: V -""" - - -def create_hw_voltage_limit(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Voltage limit in Volts""" - return meter.create_observable_gauge( - name=HW_VOLTAGE_LIMIT, - callbacks=callbacks, - description="Voltage limit in Volts.", - unit="V", - ) - - -HW_VOLTAGE_NOMINAL: Final = "hw.voltage.nominal" -""" -Nominal (expected) voltage -Instrument: gauge -Unit: V -""" - - -def create_hw_voltage_nominal(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Nominal (expected) voltage""" - return meter.create_observable_gauge( - name=HW_VOLTAGE_NOMINAL, - callbacks=callbacks, - description="Nominal (expected) voltage.", - unit="V", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py deleted file mode 100644 index 8fdde341f92..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/k8s_metrics.py +++ /dev/null @@ -1,2952 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable, Generator, Iterable, Sequence -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter - -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -K8S_CONTAINER_CPU_LIMIT: Final = "k8s.container.cpu.limit" -""" -Deprecated: Replaced by `k8s.container.cpu.limit.desired`. -""" - - -def create_k8s_container_cpu_limit(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.container.cpu.limit.desired` and `k8s.container.cpu.limit.current` instead""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_CPU_LIMIT, - description="Deprecated, use `k8s.container.cpu.limit.desired` and `k8s.container.cpu.limit.current` instead.", - unit="{cpu}", - ) - - -K8S_CONTAINER_CPU_LIMIT_CURRENT: Final = "k8s.container.cpu.limit.current" -""" -Maximum CPU resource limit currently configured for a running container -Instrument: updowncounter -Unit: {cpu} -Note: This metric aligns with the limit in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) -(status.containerStatuses[*].resources). Also see `Actual Resources` in - for more details. -""" - - -def create_k8s_container_cpu_limit_current(meter: Meter) -> UpDownCounter: - """Maximum CPU resource limit currently configured for a running container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_CPU_LIMIT_CURRENT, - description="Maximum CPU resource limit currently configured for a running container.", - unit="{cpu}", - ) - - -K8S_CONTAINER_CPU_LIMIT_DESIRED: Final = "k8s.container.cpu.limit.desired" -""" -Maximum CPU resource limit as defined by the container spec -Instrument: updowncounter -Unit: {cpu} -Note: This metric aligns with the limit in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) -(spec.containers[*].resources). Also see `Desired Resources` in - for more details. -""" - - -def create_k8s_container_cpu_limit_desired(meter: Meter) -> UpDownCounter: - """Maximum CPU resource limit as defined by the container spec""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_CPU_LIMIT_DESIRED, - description="Maximum CPU resource limit as defined by the container spec.", - unit="{cpu}", - ) - - -K8S_CONTAINER_CPU_LIMIT_UTILIZATION: Final = "k8s.container.cpu.limit.utilization" -""" -The ratio of container CPU usage to its current CPU limit -Instrument: gauge -Unit: 1 -Note: The current CPU limit reflects the actual resources applied to the container, as reported by -[ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core). -The value range is [0.0,1.0]. A value of 1.0 means the container is using 100% of its actual CPU limit. -If the CPU limit is not set, this metric SHOULD NOT be emitted for that container. -""" - - -def create_k8s_container_cpu_limit_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The ratio of container CPU usage to its current CPU limit""" - return meter.create_observable_gauge( - name=K8S_CONTAINER_CPU_LIMIT_UTILIZATION, - callbacks=callbacks, - description="The ratio of container CPU usage to its current CPU limit.", - unit="1", - ) - - -K8S_CONTAINER_CPU_REQUEST: Final = "k8s.container.cpu.request" -""" -Deprecated: Replaced by `k8s.container.cpu.request.desired`. -""" - - -def create_k8s_container_cpu_request(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.container.cpu.request.desired` and `k8s.container.cpu.request.current` instead""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_CPU_REQUEST, - description="Deprecated, use `k8s.container.cpu.request.desired` and `k8s.container.cpu.request.current` instead.", - unit="{cpu}", - ) - - -K8S_CONTAINER_CPU_REQUEST_CURRENT: Final = "k8s.container.cpu.request.current" -""" -CPU resource requested currently configured for a running container -Instrument: updowncounter -Unit: {cpu} -Note: This metric aligns with the request in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) -(status.containerStatuses[*].resources). Also see `Actual Resources` in - for more details. -""" - - -def create_k8s_container_cpu_request_current(meter: Meter) -> UpDownCounter: - """CPU resource requested currently configured for a running container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_CPU_REQUEST_CURRENT, - description="CPU resource requested currently configured for a running container.", - unit="{cpu}", - ) - - -K8S_CONTAINER_CPU_REQUEST_DESIRED: Final = "k8s.container.cpu.request.desired" -""" -CPU resource requested as defined by the container spec -Instrument: updowncounter -Unit: {cpu} -Note: This metric aligns with the request in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) -(spec.containers[*].resources). Also see `Desired Resources` in - for more details. -""" - - -def create_k8s_container_cpu_request_desired(meter: Meter) -> UpDownCounter: - """CPU resource requested as defined by the container spec""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_CPU_REQUEST_DESIRED, - description="CPU resource requested as defined by the container spec.", - unit="{cpu}", - ) - - -K8S_CONTAINER_CPU_REQUEST_UTILIZATION: Final = "k8s.container.cpu.request.utilization" -""" -The ratio of container CPU usage to its current CPU request -Instrument: gauge -Unit: 1 -Note: The current CPU request reflects the request applied to the running container, as reported by -[ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core). -The value range is [0.0,1.0]. A value of 1.0 means the container is using 100% of its actual CPU request. -If the CPU request is not set, this metric SHOULD NOT be emitted for that container. -""" - - -def create_k8s_container_cpu_request_utilization( - meter: Meter, callbacks: Sequence[CallbackT] | None -) -> ObservableGauge: - """The ratio of container CPU usage to its current CPU request""" - return meter.create_observable_gauge( - name=K8S_CONTAINER_CPU_REQUEST_UTILIZATION, - callbacks=callbacks, - description="The ratio of container CPU usage to its current CPU request.", - unit="1", - ) - - -K8S_CONTAINER_EPHEMERAL_STORAGE_LIMIT: Final = "k8s.container.ephemeral_storage.limit" -""" -Maximum ephemeral storage resource limit set for the container -Instrument: updowncounter -Unit: By -Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. -""" - - -def create_k8s_container_ephemeral_storage_limit(meter: Meter) -> UpDownCounter: - """Maximum ephemeral storage resource limit set for the container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_EPHEMERAL_STORAGE_LIMIT, - description="Maximum ephemeral storage resource limit set for the container.", - unit="By", - ) - - -K8S_CONTAINER_EPHEMERAL_STORAGE_REQUEST: Final = "k8s.container.ephemeral_storage.request" -""" -Ephemeral storage resource requested for the container -Instrument: updowncounter -Unit: By -Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. -""" - - -def create_k8s_container_ephemeral_storage_request(meter: Meter) -> UpDownCounter: - """Ephemeral storage resource requested for the container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_EPHEMERAL_STORAGE_REQUEST, - description="Ephemeral storage resource requested for the container.", - unit="By", - ) - - -K8S_CONTAINER_EPHEMERAL_STORAGE_USAGE: Final = "k8s.container.ephemeral_storage.usage" -""" -The ephemeral storage used by a container -Instrument: updowncounter -Unit: By -Note: The value for this metric can be compared against `metric.k8s.container.ephemeral_storage.request` and `metric.k8s.container.ephemeral_storage.limit`. -""" - - -def create_k8s_container_ephemeral_storage_usage(meter: Meter) -> UpDownCounter: - """The ephemeral storage used by a container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_EPHEMERAL_STORAGE_USAGE, - description="The ephemeral storage used by a container.", - unit="By", - ) - - -K8S_CONTAINER_MEMORY_LIMIT: Final = "k8s.container.memory.limit" -""" -Deprecated: Replaced by `k8s.container.memory.limit.desired`. -""" - - -def create_k8s_container_memory_limit(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.container.memory.limit.desired` and `k8s.container.memory.limit.current` instead""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_MEMORY_LIMIT, - description="Deprecated, use `k8s.container.memory.limit.desired` and `k8s.container.memory.limit.current` instead.", - unit="By", - ) - - -K8S_CONTAINER_MEMORY_LIMIT_CURRENT: Final = "k8s.container.memory.limit.current" -""" -Maximum memory resource limit currently configured for a running container -Instrument: updowncounter -Unit: By -Note: This metric aligns with the limit in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) -(status.containerStatuses[*].resources). Also see `Actual Resources` in - for more details. -""" - - -def create_k8s_container_memory_limit_current(meter: Meter) -> UpDownCounter: - """Maximum memory resource limit currently configured for a running container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_MEMORY_LIMIT_CURRENT, - description="Maximum memory resource limit currently configured for a running container.", - unit="By", - ) - - -K8S_CONTAINER_MEMORY_LIMIT_DESIRED: Final = "k8s.container.memory.limit.desired" -""" -Maximum memory resource limit as defined by the container spec -Instrument: updowncounter -Unit: By -Note: This metric aligns with the limit in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) -(spec.containers[*].resources). Also see `Desired Resources` in - for more details. -""" - - -def create_k8s_container_memory_limit_desired(meter: Meter) -> UpDownCounter: - """Maximum memory resource limit as defined by the container spec""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_MEMORY_LIMIT_DESIRED, - description="Maximum memory resource limit as defined by the container spec.", - unit="By", - ) - - -K8S_CONTAINER_MEMORY_REQUEST: Final = "k8s.container.memory.request" -""" -Deprecated: Replaced by `k8s.container.memory.request.desired`. -""" - - -def create_k8s_container_memory_request(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.container.memory.request.desired` and `k8s.container.memory.request.current` instead""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_MEMORY_REQUEST, - description="Deprecated, use `k8s.container.memory.request.desired` and `k8s.container.memory.request.current` instead.", - unit="By", - ) - - -K8S_CONTAINER_MEMORY_REQUEST_CURRENT: Final = "k8s.container.memory.request.current" -""" -Memory resource request currently configured for a running container -Instrument: updowncounter -Unit: By -Note: This metric aligns with the request in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core) -(status.containerStatuses[*].resources). Also see `Actual Resources` in - for more details. -""" - - -def create_k8s_container_memory_request_current(meter: Meter) -> UpDownCounter: - """Memory resource request currently configured for a running container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_MEMORY_REQUEST_CURRENT, - description="Memory resource request currently configured for a running container.", - unit="By", - ) - - -K8S_CONTAINER_MEMORY_REQUEST_DESIRED: Final = "k8s.container.memory.request.desired" -""" -Memory resource requested as defined by the container spec -Instrument: updowncounter -Unit: By -Note: This metric aligns with the request in the -[`resources`](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core) field of -[K8s Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#container-v1-core) -(spec.containers[*].resources). Also see `Desired Resources` in - for more details. -""" - - -def create_k8s_container_memory_request_desired(meter: Meter) -> UpDownCounter: - """Memory resource requested as defined by the container spec""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_MEMORY_REQUEST_DESIRED, - description="Memory resource requested as defined by the container spec.", - unit="By", - ) - - -K8S_CONTAINER_READY: Final = "k8s.container.ready" -""" -Indicates whether the container is currently marked as ready to accept traffic, based on its readiness probe (1 = ready, 0 = not ready) -Instrument: updowncounter -Unit: {container} -Note: This metric SHOULD reflect the value of the `ready` field in the -[K8s ContainerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#containerstatus-v1-core). -""" - - -def create_k8s_container_ready(meter: Meter) -> UpDownCounter: - """Indicates whether the container is currently marked as ready to accept traffic, based on its readiness probe (1 = ready, 0 = not ready)""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_READY, - description="Indicates whether the container is currently marked as ready to accept traffic, based on its readiness probe (1 = ready, 0 = not ready).", - unit="{container}", - ) - - -K8S_CONTAINER_RESTART_COUNT: Final = "k8s.container.restart.count" -""" -Describes how many times the container has restarted (since the last counter reset) -Instrument: updowncounter -Unit: {restart} -Note: This value is pulled directly from the K8s API and the value can go indefinitely high and be reset to 0 -at any time depending on how your kubelet is configured to prune dead containers. -It is best to not depend too much on the exact value but rather look at it as -either == 0, in which case you can conclude there were no restarts in the recent past, or > 0, in which case -you can conclude there were restarts in the recent past, and not try and analyze the value beyond that. -""" - - -def create_k8s_container_restart_count(meter: Meter) -> UpDownCounter: - """Describes how many times the container has restarted (since the last counter reset)""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_RESTART_COUNT, - description="Describes how many times the container has restarted (since the last counter reset).", - unit="{restart}", - ) - - -K8S_CONTAINER_STATUS_REASON: Final = "k8s.container.status.reason" -""" -Describes the number of K8s containers that are currently in a state for a given reason -Instrument: updowncounter -Unit: {container} -Note: All possible container state reasons will be reported at each time interval to avoid missing metrics. -Only the value corresponding to the current state reason will be non-zero. -""" - - -def create_k8s_container_status_reason(meter: Meter) -> UpDownCounter: - """Describes the number of K8s containers that are currently in a state for a given reason""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_STATUS_REASON, - description="Describes the number of K8s containers that are currently in a state for a given reason.", - unit="{container}", - ) - - -K8S_CONTAINER_STATUS_STATE: Final = "k8s.container.status.state" -""" -Describes the number of K8s containers that are currently in a given state -Instrument: updowncounter -Unit: {container} -Note: All possible container states will be reported at each time interval to avoid missing metrics. -Only the value corresponding to the current state will be non-zero. -""" - - -def create_k8s_container_status_state(meter: Meter) -> UpDownCounter: - """Describes the number of K8s containers that are currently in a given state""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_STATUS_STATE, - description="Describes the number of K8s containers that are currently in a given state.", - unit="{container}", - ) - - -K8S_CONTAINER_STORAGE_LIMIT: Final = "k8s.container.storage.limit" -""" -Maximum storage resource limit set for the container -Instrument: updowncounter -Unit: By -Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. -""" - - -def create_k8s_container_storage_limit(meter: Meter) -> UpDownCounter: - """Maximum storage resource limit set for the container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_STORAGE_LIMIT, - description="Maximum storage resource limit set for the container.", - unit="By", - ) - - -K8S_CONTAINER_STORAGE_REQUEST: Final = "k8s.container.storage.request" -""" -Storage resource requested for the container -Instrument: updowncounter -Unit: By -Note: See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcerequirements-v1-core for details. -""" - - -def create_k8s_container_storage_request(meter: Meter) -> UpDownCounter: - """Storage resource requested for the container""" - return meter.create_up_down_counter( - name=K8S_CONTAINER_STORAGE_REQUEST, - description="Storage resource requested for the container.", - unit="By", - ) - - -K8S_CRONJOB_ACTIVE_JOBS: Final = "k8s.cronjob.active_jobs" -""" -Deprecated: Replaced by `k8s.cronjob.job.active`. -""" - - -def create_k8s_cronjob_active_jobs(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.cronjob.job.active` instead""" - return meter.create_up_down_counter( - name=K8S_CRONJOB_ACTIVE_JOBS, - description="Deprecated, use `k8s.cronjob.job.active` instead.", - unit="{job}", - ) - - -K8S_CRONJOB_JOB_ACTIVE: Final = "k8s.cronjob.job.active" -""" -The number of actively running jobs for a cronjob -Instrument: updowncounter -Unit: {job} -Note: This metric aligns with the `active` field of the -[K8s CronJobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#cronjobstatus-v1-batch). -""" - - -def create_k8s_cronjob_job_active(meter: Meter) -> UpDownCounter: - """The number of actively running jobs for a cronjob""" - return meter.create_up_down_counter( - name=K8S_CRONJOB_JOB_ACTIVE, - description="The number of actively running jobs for a cronjob.", - unit="{job}", - ) - - -K8S_DAEMONSET_CURRENT_SCHEDULED_NODES: Final = "k8s.daemonset.current_scheduled_nodes" -""" -Deprecated: Replaced by `k8s.daemonset.node.current_scheduled`. -""" - - -def create_k8s_daemonset_current_scheduled_nodes(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.daemonset.node.current_scheduled` instead""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_CURRENT_SCHEDULED_NODES, - description="Deprecated, use `k8s.daemonset.node.current_scheduled` instead.", - unit="{node}", - ) - - -K8S_DAEMONSET_DESIRED_SCHEDULED_NODES: Final = "k8s.daemonset.desired_scheduled_nodes" -""" -Deprecated: Replaced by `k8s.daemonset.node.desired_scheduled`. -""" - - -def create_k8s_daemonset_desired_scheduled_nodes(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.daemonset.node.desired_scheduled` instead""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_DESIRED_SCHEDULED_NODES, - description="Deprecated, use `k8s.daemonset.node.desired_scheduled` instead.", - unit="{node}", - ) - - -K8S_DAEMONSET_MISSCHEDULED_NODES: Final = "k8s.daemonset.misscheduled_nodes" -""" -Deprecated: Replaced by `k8s.daemonset.node.misscheduled`. -""" - - -def create_k8s_daemonset_misscheduled_nodes(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.daemonset.node.misscheduled` instead""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_MISSCHEDULED_NODES, - description="Deprecated, use `k8s.daemonset.node.misscheduled` instead.", - unit="{node}", - ) - - -K8S_DAEMONSET_NODE_CURRENT_SCHEDULED: Final = "k8s.daemonset.node.current_scheduled" -""" -Number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod -Instrument: updowncounter -Unit: {node} -Note: This metric aligns with the `currentNumberScheduled` field of the -[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). -""" - - -def create_k8s_daemonset_node_current_scheduled(meter: Meter) -> UpDownCounter: - """Number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_NODE_CURRENT_SCHEDULED, - description="Number of nodes that are running at least 1 daemon pod and are supposed to run the daemon pod.", - unit="{node}", - ) - - -K8S_DAEMONSET_NODE_DESIRED_SCHEDULED: Final = "k8s.daemonset.node.desired_scheduled" -""" -Number of nodes that should be running the daemon pod (including nodes currently running the daemon pod) -Instrument: updowncounter -Unit: {node} -Note: This metric aligns with the `desiredNumberScheduled` field of the -[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). -""" - - -def create_k8s_daemonset_node_desired_scheduled(meter: Meter) -> UpDownCounter: - """Number of nodes that should be running the daemon pod (including nodes currently running the daemon pod)""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_NODE_DESIRED_SCHEDULED, - description="Number of nodes that should be running the daemon pod (including nodes currently running the daemon pod).", - unit="{node}", - ) - - -K8S_DAEMONSET_NODE_MISSCHEDULED: Final = "k8s.daemonset.node.misscheduled" -""" -Number of nodes that are running the daemon pod, but are not supposed to run the daemon pod -Instrument: updowncounter -Unit: {node} -Note: This metric aligns with the `numberMisscheduled` field of the -[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). -""" - - -def create_k8s_daemonset_node_misscheduled(meter: Meter) -> UpDownCounter: - """Number of nodes that are running the daemon pod, but are not supposed to run the daemon pod""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_NODE_MISSCHEDULED, - description="Number of nodes that are running the daemon pod, but are not supposed to run the daemon pod.", - unit="{node}", - ) - - -K8S_DAEMONSET_NODE_READY: Final = "k8s.daemonset.node.ready" -""" -Number of nodes that should be running the daemon pod and have one or more of the daemon pod running and ready -Instrument: updowncounter -Unit: {node} -Note: This metric aligns with the `numberReady` field of the -[K8s DaemonSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#daemonsetstatus-v1-apps). -""" - - -def create_k8s_daemonset_node_ready(meter: Meter) -> UpDownCounter: - """Number of nodes that should be running the daemon pod and have one or more of the daemon pod running and ready""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_NODE_READY, - description="Number of nodes that should be running the daemon pod and have one or more of the daemon pod running and ready.", - unit="{node}", - ) - - -K8S_DAEMONSET_READY_NODES: Final = "k8s.daemonset.ready_nodes" -""" -Deprecated: Replaced by `k8s.daemonset.node.ready`. -""" - - -def create_k8s_daemonset_ready_nodes(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.daemonset.node.ready` instead""" - return meter.create_up_down_counter( - name=K8S_DAEMONSET_READY_NODES, - description="Deprecated, use `k8s.daemonset.node.ready` instead.", - unit="{node}", - ) - - -K8S_DEPLOYMENT_AVAILABLE_PODS: Final = "k8s.deployment.available_pods" -""" -Deprecated: Replaced by `k8s.deployment.pod.available`. -""" - - -def create_k8s_deployment_available_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.deployment.pod.available` instead""" - return meter.create_up_down_counter( - name=K8S_DEPLOYMENT_AVAILABLE_PODS, - description="Deprecated, use `k8s.deployment.pod.available` instead.", - unit="{pod}", - ) - - -K8S_DEPLOYMENT_DESIRED_PODS: Final = "k8s.deployment.desired_pods" -""" -Deprecated: Replaced by `k8s.deployment.pod.desired`. -""" - - -def create_k8s_deployment_desired_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.deployment.pod.desired` instead""" - return meter.create_up_down_counter( - name=K8S_DEPLOYMENT_DESIRED_PODS, - description="Deprecated, use `k8s.deployment.pod.desired` instead.", - unit="{pod}", - ) - - -K8S_DEPLOYMENT_POD_AVAILABLE: Final = "k8s.deployment.pod.available" -""" -Total number of available replica pods (ready for at least minReadySeconds) targeted by this deployment -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `availableReplicas` field of the -[K8s DeploymentStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#deploymentstatus-v1-apps). -""" - - -def create_k8s_deployment_pod_available(meter: Meter) -> UpDownCounter: - """Total number of available replica pods (ready for at least minReadySeconds) targeted by this deployment""" - return meter.create_up_down_counter( - name=K8S_DEPLOYMENT_POD_AVAILABLE, - description="Total number of available replica pods (ready for at least minReadySeconds) targeted by this deployment.", - unit="{pod}", - ) - - -K8S_DEPLOYMENT_POD_DESIRED: Final = "k8s.deployment.pod.desired" -""" -Number of desired replica pods in this deployment -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `replicas` field of the -[K8s DeploymentSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#deploymentspec-v1-apps). -""" - - -def create_k8s_deployment_pod_desired(meter: Meter) -> UpDownCounter: - """Number of desired replica pods in this deployment""" - return meter.create_up_down_counter( - name=K8S_DEPLOYMENT_POD_DESIRED, - description="Number of desired replica pods in this deployment.", - unit="{pod}", - ) - - -K8S_HPA_CURRENT_PODS: Final = "k8s.hpa.current_pods" -""" -Deprecated: Replaced by `k8s.hpa.pod.current`. -""" - - -def create_k8s_hpa_current_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.hpa.pod.current` instead""" - return meter.create_up_down_counter( - name=K8S_HPA_CURRENT_PODS, - description="Deprecated, use `k8s.hpa.pod.current` instead.", - unit="{pod}", - ) - - -K8S_HPA_DESIRED_PODS: Final = "k8s.hpa.desired_pods" -""" -Deprecated: Replaced by `k8s.hpa.pod.desired`. -""" - - -def create_k8s_hpa_desired_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.hpa.pod.desired` instead""" - return meter.create_up_down_counter( - name=K8S_HPA_DESIRED_PODS, - description="Deprecated, use `k8s.hpa.pod.desired` instead.", - unit="{pod}", - ) - - -K8S_HPA_MAX_PODS: Final = "k8s.hpa.max_pods" -""" -Deprecated: Replaced by `k8s.hpa.pod.max`. -""" - - -def create_k8s_hpa_max_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.hpa.pod.max` instead""" - return meter.create_up_down_counter( - name=K8S_HPA_MAX_PODS, - description="Deprecated, use `k8s.hpa.pod.max` instead.", - unit="{pod}", - ) - - -K8S_HPA_METRIC_TARGET_CPU_AVERAGE_UTILIZATION: Final = "k8s.hpa.metric.target.cpu.average_utilization" -""" -Target average utilization, in percentage, for CPU resource in HPA config -Instrument: gauge -Unit: 1 -Note: This metric aligns with the `averageUtilization` field of the -[K8s HPA MetricTarget](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#metrictarget-v2-autoscaling). -If the type of the metric is [`ContainerResource`](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis), -the `k8s.container.name` attribute MUST be set to identify the specific container within the pod to which the metric applies. -""" - - -def create_k8s_hpa_metric_target_cpu_average_utilization( - meter: Meter, callbacks: Sequence[CallbackT] | None -) -> ObservableGauge: - """Target average utilization, in percentage, for CPU resource in HPA config""" - return meter.create_observable_gauge( - name=K8S_HPA_METRIC_TARGET_CPU_AVERAGE_UTILIZATION, - callbacks=callbacks, - description="Target average utilization, in percentage, for CPU resource in HPA config.", - unit="1", - ) - - -K8S_HPA_METRIC_TARGET_CPU_AVERAGE_VALUE: Final = "k8s.hpa.metric.target.cpu.average_value" -""" -Target average value for CPU resource in HPA config -Instrument: gauge -Unit: {cpu} -Note: This metric aligns with the `averageValue` field of the -[K8s HPA MetricTarget](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#metrictarget-v2-autoscaling). -If the type of the metric is [`ContainerResource`](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis), -the `k8s.container.name` attribute MUST be set to identify the specific container within the pod to which the metric applies. -""" - - -def create_k8s_hpa_metric_target_cpu_average_value( - meter: Meter, callbacks: Sequence[CallbackT] | None -) -> ObservableGauge: - """Target average value for CPU resource in HPA config""" - return meter.create_observable_gauge( - name=K8S_HPA_METRIC_TARGET_CPU_AVERAGE_VALUE, - callbacks=callbacks, - description="Target average value for CPU resource in HPA config.", - unit="{cpu}", - ) - - -K8S_HPA_METRIC_TARGET_CPU_VALUE: Final = "k8s.hpa.metric.target.cpu.value" -""" -Target value for CPU resource in HPA config -Instrument: gauge -Unit: {cpu} -Note: This metric aligns with the `value` field of the -[K8s HPA MetricTarget](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#metrictarget-v2-autoscaling). -If the type of the metric is [`ContainerResource`](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-metrics-apis), -the `k8s.container.name` attribute MUST be set to identify the specific container within the pod to which the metric applies. -""" - - -def create_k8s_hpa_metric_target_cpu_value(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Target value for CPU resource in HPA config""" - return meter.create_observable_gauge( - name=K8S_HPA_METRIC_TARGET_CPU_VALUE, - callbacks=callbacks, - description="Target value for CPU resource in HPA config.", - unit="{cpu}", - ) - - -K8S_HPA_MIN_PODS: Final = "k8s.hpa.min_pods" -""" -Deprecated: Replaced by `k8s.hpa.pod.min`. -""" - - -def create_k8s_hpa_min_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.hpa.pod.min` instead""" - return meter.create_up_down_counter( - name=K8S_HPA_MIN_PODS, - description="Deprecated, use `k8s.hpa.pod.min` instead.", - unit="{pod}", - ) - - -K8S_HPA_POD_CURRENT: Final = "k8s.hpa.pod.current" -""" -Current number of replica pods managed by this horizontal pod autoscaler, as last seen by the autoscaler -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `currentReplicas` field of the -[K8s HorizontalPodAutoscalerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerstatus-v2-autoscaling). -""" - - -def create_k8s_hpa_pod_current(meter: Meter) -> UpDownCounter: - """Current number of replica pods managed by this horizontal pod autoscaler, as last seen by the autoscaler""" - return meter.create_up_down_counter( - name=K8S_HPA_POD_CURRENT, - description="Current number of replica pods managed by this horizontal pod autoscaler, as last seen by the autoscaler.", - unit="{pod}", - ) - - -K8S_HPA_POD_DESIRED: Final = "k8s.hpa.pod.desired" -""" -Desired number of replica pods managed by this horizontal pod autoscaler, as last calculated by the autoscaler -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `desiredReplicas` field of the -[K8s HorizontalPodAutoscalerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerstatus-v2-autoscaling). -""" - - -def create_k8s_hpa_pod_desired(meter: Meter) -> UpDownCounter: - """Desired number of replica pods managed by this horizontal pod autoscaler, as last calculated by the autoscaler""" - return meter.create_up_down_counter( - name=K8S_HPA_POD_DESIRED, - description="Desired number of replica pods managed by this horizontal pod autoscaler, as last calculated by the autoscaler.", - unit="{pod}", - ) - - -K8S_HPA_POD_MAX: Final = "k8s.hpa.pod.max" -""" -The upper limit for the number of replica pods to which the autoscaler can scale up -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `maxReplicas` field of the -[K8s HorizontalPodAutoscalerSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerspec-v2-autoscaling). -""" - - -def create_k8s_hpa_pod_max(meter: Meter) -> UpDownCounter: - """The upper limit for the number of replica pods to which the autoscaler can scale up""" - return meter.create_up_down_counter( - name=K8S_HPA_POD_MAX, - description="The upper limit for the number of replica pods to which the autoscaler can scale up.", - unit="{pod}", - ) - - -K8S_HPA_POD_MIN: Final = "k8s.hpa.pod.min" -""" -The lower limit for the number of replica pods to which the autoscaler can scale down -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `minReplicas` field of the -[K8s HorizontalPodAutoscalerSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#horizontalpodautoscalerspec-v2-autoscaling). -""" - - -def create_k8s_hpa_pod_min(meter: Meter) -> UpDownCounter: - """The lower limit for the number of replica pods to which the autoscaler can scale down""" - return meter.create_up_down_counter( - name=K8S_HPA_POD_MIN, - description="The lower limit for the number of replica pods to which the autoscaler can scale down.", - unit="{pod}", - ) - - -K8S_JOB_ACTIVE_PODS: Final = "k8s.job.active_pods" -""" -Deprecated: Replaced by `k8s.job.pod.active`. -""" - - -def create_k8s_job_active_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.job.pod.active` instead""" - return meter.create_up_down_counter( - name=K8S_JOB_ACTIVE_PODS, - description="Deprecated, use `k8s.job.pod.active` instead.", - unit="{pod}", - ) - - -K8S_JOB_DESIRED_SUCCESSFUL_PODS: Final = "k8s.job.desired_successful_pods" -""" -Deprecated: Replaced by `k8s.job.pod.desired_successful`. -""" - - -def create_k8s_job_desired_successful_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.job.pod.desired_successful` instead""" - return meter.create_up_down_counter( - name=K8S_JOB_DESIRED_SUCCESSFUL_PODS, - description="Deprecated, use `k8s.job.pod.desired_successful` instead.", - unit="{pod}", - ) - - -K8S_JOB_FAILED_PODS: Final = "k8s.job.failed_pods" -""" -Deprecated: Replaced by `k8s.job.pod.failed`. -""" - - -def create_k8s_job_failed_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.job.pod.failed` instead""" - return meter.create_up_down_counter( - name=K8S_JOB_FAILED_PODS, - description="Deprecated, use `k8s.job.pod.failed` instead.", - unit="{pod}", - ) - - -K8S_JOB_MAX_PARALLEL_PODS: Final = "k8s.job.max_parallel_pods" -""" -Deprecated: Replaced by `k8s.job.pod.max_parallel`. -""" - - -def create_k8s_job_max_parallel_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.job.pod.max_parallel` instead""" - return meter.create_up_down_counter( - name=K8S_JOB_MAX_PARALLEL_PODS, - description="Deprecated, use `k8s.job.pod.max_parallel` instead.", - unit="{pod}", - ) - - -K8S_JOB_POD_ACTIVE: Final = "k8s.job.pod.active" -""" -The number of pending and actively running pods for a job -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `active` field of the -[K8s JobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobstatus-v1-batch). -""" - - -def create_k8s_job_pod_active(meter: Meter) -> UpDownCounter: - """The number of pending and actively running pods for a job""" - return meter.create_up_down_counter( - name=K8S_JOB_POD_ACTIVE, - description="The number of pending and actively running pods for a job.", - unit="{pod}", - ) - - -K8S_JOB_POD_DESIRED_SUCCESSFUL: Final = "k8s.job.pod.desired_successful" -""" -The desired number of successfully finished pods the job should be run with -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `completions` field of the -[K8s JobSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobspec-v1-batch). -""" - - -def create_k8s_job_pod_desired_successful(meter: Meter) -> UpDownCounter: - """The desired number of successfully finished pods the job should be run with""" - return meter.create_up_down_counter( - name=K8S_JOB_POD_DESIRED_SUCCESSFUL, - description="The desired number of successfully finished pods the job should be run with.", - unit="{pod}", - ) - - -K8S_JOB_POD_FAILED: Final = "k8s.job.pod.failed" -""" -The number of pods which reached phase Failed for a job -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `failed` field of the -[K8s JobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobstatus-v1-batch). -""" - - -def create_k8s_job_pod_failed(meter: Meter) -> UpDownCounter: - """The number of pods which reached phase Failed for a job""" - return meter.create_up_down_counter( - name=K8S_JOB_POD_FAILED, - description="The number of pods which reached phase Failed for a job.", - unit="{pod}", - ) - - -K8S_JOB_POD_MAX_PARALLEL: Final = "k8s.job.pod.max_parallel" -""" -The max desired number of pods the job should run at any given time -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `parallelism` field of the -[K8s JobSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobspec-v1-batch). -""" - - -def create_k8s_job_pod_max_parallel(meter: Meter) -> UpDownCounter: - """The max desired number of pods the job should run at any given time""" - return meter.create_up_down_counter( - name=K8S_JOB_POD_MAX_PARALLEL, - description="The max desired number of pods the job should run at any given time.", - unit="{pod}", - ) - - -K8S_JOB_POD_SUCCESSFUL: Final = "k8s.job.pod.successful" -""" -The number of pods which reached phase Succeeded for a job -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `succeeded` field of the -[K8s JobStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#jobstatus-v1-batch). -""" - - -def create_k8s_job_pod_successful(meter: Meter) -> UpDownCounter: - """The number of pods which reached phase Succeeded for a job""" - return meter.create_up_down_counter( - name=K8S_JOB_POD_SUCCESSFUL, - description="The number of pods which reached phase Succeeded for a job.", - unit="{pod}", - ) - - -K8S_JOB_SUCCESSFUL_PODS: Final = "k8s.job.successful_pods" -""" -Deprecated: Replaced by `k8s.job.pod.successful`. -""" - - -def create_k8s_job_successful_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.job.pod.successful` instead""" - return meter.create_up_down_counter( - name=K8S_JOB_SUCCESSFUL_PODS, - description="Deprecated, use `k8s.job.pod.successful` instead.", - unit="{pod}", - ) - - -K8S_NAMESPACE_PHASE: Final = "k8s.namespace.phase" -""" -Describes number of K8s namespaces that are currently in a given phase -Instrument: updowncounter -Unit: {namespace} -""" - - -def create_k8s_namespace_phase(meter: Meter) -> UpDownCounter: - """Describes number of K8s namespaces that are currently in a given phase""" - return meter.create_up_down_counter( - name=K8S_NAMESPACE_PHASE, - description="Describes number of K8s namespaces that are currently in a given phase.", - unit="{namespace}", - ) - - -K8S_NODE_ALLOCATABLE_CPU: Final = "k8s.node.allocatable.cpu" -""" -Deprecated: Replaced by `k8s.node.cpu.allocatable`. -""" - - -def create_k8s_node_allocatable_cpu(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.node.cpu.allocatable` instead""" - return meter.create_up_down_counter( - name=K8S_NODE_ALLOCATABLE_CPU, - description="Deprecated, use `k8s.node.cpu.allocatable` instead.", - unit="{cpu}", - ) - - -K8S_NODE_ALLOCATABLE_EPHEMERAL_STORAGE: Final = "k8s.node.allocatable.ephemeral_storage" -""" -Deprecated: Replaced by `k8s.node.ephemeral_storage.allocatable`. -""" - - -def create_k8s_node_allocatable_ephemeral_storage(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.node.ephemeral_storage.allocatable` instead""" - return meter.create_up_down_counter( - name=K8S_NODE_ALLOCATABLE_EPHEMERAL_STORAGE, - description="Deprecated, use `k8s.node.ephemeral_storage.allocatable` instead.", - unit="By", - ) - - -K8S_NODE_ALLOCATABLE_MEMORY: Final = "k8s.node.allocatable.memory" -""" -Deprecated: Replaced by `k8s.node.memory.allocatable`. -""" - - -def create_k8s_node_allocatable_memory(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.node.memory.allocatable` instead""" - return meter.create_up_down_counter( - name=K8S_NODE_ALLOCATABLE_MEMORY, - description="Deprecated, use `k8s.node.memory.allocatable` instead.", - unit="By", - ) - - -K8S_NODE_ALLOCATABLE_PODS: Final = "k8s.node.allocatable.pods" -""" -Deprecated: Replaced by `k8s.node.pod.allocatable`. -""" - - -def create_k8s_node_allocatable_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.node.pod.allocatable` instead""" - return meter.create_up_down_counter( - name=K8S_NODE_ALLOCATABLE_PODS, - description="Deprecated, use `k8s.node.pod.allocatable` instead.", - unit="{pod}", - ) - - -K8S_NODE_CONDITION_STATUS: Final = "k8s.node.condition.status" -""" -Describes the condition of a particular Node -Instrument: updowncounter -Unit: {node} -Note: All possible node condition pairs (type and status) will be reported at each time interval to avoid missing metrics. Condition pairs corresponding to the current conditions' statuses will be non-zero. -""" - - -def create_k8s_node_condition_status(meter: Meter) -> UpDownCounter: - """Describes the condition of a particular Node""" - return meter.create_up_down_counter( - name=K8S_NODE_CONDITION_STATUS, - description="Describes the condition of a particular Node.", - unit="{node}", - ) - - -K8S_NODE_CPU_ALLOCATABLE: Final = "k8s.node.cpu.allocatable" -""" -Amount of CPU allocatable on the node -Instrument: updowncounter -Unit: {cpu} -""" - - -def create_k8s_node_cpu_allocatable(meter: Meter) -> UpDownCounter: - """Amount of CPU allocatable on the node""" - return meter.create_up_down_counter( - name=K8S_NODE_CPU_ALLOCATABLE, - description="Amount of CPU allocatable on the node.", - unit="{cpu}", - ) - - -K8S_NODE_CPU_TIME: Final = "k8s.node.cpu.time" -""" -Total CPU time consumed -Instrument: counter -Unit: s -Note: Total CPU time consumed by the specific Node on all available CPU cores. -""" - - -def create_k8s_node_cpu_time(meter: Meter) -> Counter: - """Total CPU time consumed""" - return meter.create_counter( - name=K8S_NODE_CPU_TIME, - description="Total CPU time consumed.", - unit="s", - ) - - -K8S_NODE_CPU_USAGE: Final = "k8s.node.cpu.usage" -""" -Node's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs -Instrument: gauge -Unit: {cpu} -Note: CPU usage of the specific Node on all available CPU cores. It is calculated as the change in cumulative CPU time (k8s.node.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. -""" - - -def create_k8s_node_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Node's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs""" - return meter.create_observable_gauge( - name=K8S_NODE_CPU_USAGE, - callbacks=callbacks, - description="Node's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs.", - unit="{cpu}", - ) - - -K8S_NODE_EPHEMERAL_STORAGE_ALLOCATABLE: Final = "k8s.node.ephemeral_storage.allocatable" -""" -Amount of ephemeral-storage allocatable on the node -Instrument: updowncounter -Unit: By -""" - - -def create_k8s_node_ephemeral_storage_allocatable(meter: Meter) -> UpDownCounter: - """Amount of ephemeral-storage allocatable on the node""" - return meter.create_up_down_counter( - name=K8S_NODE_EPHEMERAL_STORAGE_ALLOCATABLE, - description="Amount of ephemeral-storage allocatable on the node.", - unit="By", - ) - - -K8S_NODE_FILESYSTEM_AVAILABLE: Final = "k8s.node.filesystem.available" -""" -Node filesystem available bytes -Instrument: updowncounter -Unit: By -Note: This metric is derived from the -[FsStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) -of the Kubelet's stats API. -""" - - -def create_k8s_node_filesystem_available(meter: Meter) -> UpDownCounter: - """Node filesystem available bytes""" - return meter.create_up_down_counter( - name=K8S_NODE_FILESYSTEM_AVAILABLE, - description="Node filesystem available bytes.", - unit="By", - ) - - -K8S_NODE_FILESYSTEM_CAPACITY: Final = "k8s.node.filesystem.capacity" -""" -Node filesystem capacity -Instrument: updowncounter -Unit: By -Note: This metric is derived from the -[FsStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) -of the Kubelet's stats API. -""" - - -def create_k8s_node_filesystem_capacity(meter: Meter) -> UpDownCounter: - """Node filesystem capacity""" - return meter.create_up_down_counter( - name=K8S_NODE_FILESYSTEM_CAPACITY, - description="Node filesystem capacity.", - unit="By", - ) - - -K8S_NODE_FILESYSTEM_INODE_COUNT: Final = "k8s.node.filesystem.inode.count" -""" -The total inodes in the node's root filesystem -Instrument: updowncounter -Unit: {inode} -Note: This metric is derived from the -[FsStats.Inodes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) -of the Kubelet's stats API. -""" - - -def create_k8s_node_filesystem_inode_count(meter: Meter) -> UpDownCounter: - """The total inodes in the node's root filesystem""" - return meter.create_up_down_counter( - name=K8S_NODE_FILESYSTEM_INODE_COUNT, - description="The total inodes in the node's root filesystem.", - unit="{inode}", - ) - - -K8S_NODE_FILESYSTEM_INODE_FREE: Final = "k8s.node.filesystem.inode.free" -""" -The free inodes in the node's root filesystem -Instrument: updowncounter -Unit: {inode} -Note: This metric is derived from the -[FsStats.InodesFree](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) -of the Kubelet's stats API. -""" - - -def create_k8s_node_filesystem_inode_free(meter: Meter) -> UpDownCounter: - """The free inodes in the node's root filesystem""" - return meter.create_up_down_counter( - name=K8S_NODE_FILESYSTEM_INODE_FREE, - description="The free inodes in the node's root filesystem.", - unit="{inode}", - ) - - -K8S_NODE_FILESYSTEM_USAGE: Final = "k8s.node.filesystem.usage" -""" -Node filesystem usage -Instrument: updowncounter -Unit: By -Note: This may not equal capacity - available. - -This metric is derived from the -[FsStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [NodeStats.Fs](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#NodeStats) -of the Kubelet's stats API. -""" - - -def create_k8s_node_filesystem_usage(meter: Meter) -> UpDownCounter: - """Node filesystem usage""" - return meter.create_up_down_counter( - name=K8S_NODE_FILESYSTEM_USAGE, - description="Node filesystem usage.", - unit="By", - ) - - -K8S_NODE_MEMORY_ALLOCATABLE: Final = "k8s.node.memory.allocatable" -""" -Amount of memory allocatable on the node -Instrument: updowncounter -Unit: By -""" - - -def create_k8s_node_memory_allocatable(meter: Meter) -> UpDownCounter: - """Amount of memory allocatable on the node""" - return meter.create_up_down_counter( - name=K8S_NODE_MEMORY_ALLOCATABLE, - description="Amount of memory allocatable on the node.", - unit="By", - ) - - -K8S_NODE_MEMORY_AVAILABLE: Final = "k8s.node.memory.available" -""" -Node memory available -Instrument: updowncounter -Unit: By -Note: Available memory for use. This is defined as the memory limit - workingSetBytes. If memory limit is undefined, the available bytes is omitted. -This metric is derived from the [MemoryStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. -""" - - -def create_k8s_node_memory_available(meter: Meter) -> UpDownCounter: - """Node memory available""" - return meter.create_up_down_counter( - name=K8S_NODE_MEMORY_AVAILABLE, - description="Node memory available.", - unit="By", - ) - - -K8S_NODE_MEMORY_PAGING_FAULTS: Final = "k8s.node.memory.paging.faults" -""" -Deprecated: Replaced by `k8s.node.paging.faults`. -""" - - -def create_k8s_node_memory_paging_faults(meter: Meter) -> Counter: - """Deprecated, use `k8s.node.paging.faults` instead""" - return meter.create_counter( - name=K8S_NODE_MEMORY_PAGING_FAULTS, - description="Deprecated, use `k8s.node.paging.faults` instead.", - unit="{fault}", - ) - - -K8S_NODE_MEMORY_RSS: Final = "k8s.node.memory.rss" -""" -Node memory RSS -Instrument: updowncounter -Unit: By -Note: The amount of anonymous and swap cache memory (includes transparent hugepages). -This metric is derived from the [MemoryStats.RSSBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. -""" - - -def create_k8s_node_memory_rss(meter: Meter) -> UpDownCounter: - """Node memory RSS""" - return meter.create_up_down_counter( - name=K8S_NODE_MEMORY_RSS, - description="Node memory RSS.", - unit="By", - ) - - -K8S_NODE_MEMORY_USAGE: Final = "k8s.node.memory.usage" -""" -Memory usage of the Node -Instrument: updowncounter -Unit: By -Note: Total memory in use. This includes all memory regardless of when it was accessed. -This metric is derived from the [MemoryStats.UsageBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. -""" - - -def create_k8s_node_memory_usage(meter: Meter) -> UpDownCounter: - """Memory usage of the Node""" - return meter.create_up_down_counter( - name=K8S_NODE_MEMORY_USAGE, - description="Memory usage of the Node.", - unit="By", - ) - - -K8S_NODE_MEMORY_WORKING_SET: Final = "k8s.node.memory.working_set" -""" -Node memory working set -Instrument: updowncounter -Unit: By -Note: The amount of working set memory. This includes recently accessed memory, dirty memory, and kernel memory. WorkingSetBytes is <= UsageBytes. -This metric is derived from the [MemoryStats.WorkingSetBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. -""" - - -def create_k8s_node_memory_working_set(meter: Meter) -> UpDownCounter: - """Node memory working set""" - return meter.create_up_down_counter( - name=K8S_NODE_MEMORY_WORKING_SET, - description="Node memory working set.", - unit="By", - ) - - -K8S_NODE_NETWORK_ERRORS: Final = "k8s.node.network.errors" -""" -Node network errors -Instrument: counter -Unit: {error} -""" - - -def create_k8s_node_network_errors(meter: Meter) -> Counter: - """Node network errors""" - return meter.create_counter( - name=K8S_NODE_NETWORK_ERRORS, - description="Node network errors.", - unit="{error}", - ) - - -K8S_NODE_NETWORK_IO: Final = "k8s.node.network.io" -""" -Network bytes for the Node -Instrument: counter -Unit: By -""" - - -def create_k8s_node_network_io(meter: Meter) -> Counter: - """Network bytes for the Node""" - return meter.create_counter( - name=K8S_NODE_NETWORK_IO, - description="Network bytes for the Node.", - unit="By", - ) - - -K8S_NODE_PAGING_FAULTS: Final = "k8s.node.paging.faults" -""" -Node memory paging faults -Instrument: counter -Unit: {fault} -Note: Cumulative number of major/minor page faults. -This metric is derived from the [MemoryStats.PageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) and [MemoryStats.MajorPageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) fields of the [NodeStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#NodeStats) of the Kubelet's stats API. -""" - - -def create_k8s_node_paging_faults(meter: Meter) -> Counter: - """Node memory paging faults""" - return meter.create_counter( - name=K8S_NODE_PAGING_FAULTS, - description="Node memory paging faults.", - unit="{fault}", - ) - - -K8S_NODE_POD_ALLOCATABLE: Final = "k8s.node.pod.allocatable" -""" -Amount of pods allocatable on the node -Instrument: updowncounter -Unit: {pod} -""" - - -def create_k8s_node_pod_allocatable(meter: Meter) -> UpDownCounter: - """Amount of pods allocatable on the node""" - return meter.create_up_down_counter( - name=K8S_NODE_POD_ALLOCATABLE, - description="Amount of pods allocatable on the node.", - unit="{pod}", - ) - - -K8S_NODE_SYSTEM_CONTAINER_CPU_TIME: Final = "k8s.node.system_container.cpu.time" -""" -Node's system container CPU time -Instrument: counter -Unit: s -Note: This metric is derived from the [CPUStats.UsageCoreNanoSeconds](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L236) field of the [ContainerStats](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L157C6-L157C20) of [Node.SystemContainers](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L40) of the Kubelet's stats API. -""" - - -def create_k8s_node_system_container_cpu_time(meter: Meter) -> Counter: - """Node's system container CPU time""" - return meter.create_counter( - name=K8S_NODE_SYSTEM_CONTAINER_CPU_TIME, - description="Node's system container CPU time.", - unit="s", - ) - - -K8S_NODE_SYSTEM_CONTAINER_CPU_USAGE: Final = "k8s.node.system_container.cpu.usage" -""" -Node's system container CPU usage, measured in CPUs -Instrument: gauge -Unit: {cpu} -Note: CPU usage of the specific System Container on all available CPU cores. It is calculated as the change in cumulative CPU time (k8s.node.system_container.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. -""" - - -def create_k8s_node_system_container_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Node's system container CPU usage, measured in CPUs""" - return meter.create_observable_gauge( - name=K8S_NODE_SYSTEM_CONTAINER_CPU_USAGE, - callbacks=callbacks, - description="Node's system container CPU usage, measured in CPUs.", - unit="{cpu}", - ) - - -K8S_NODE_SYSTEM_CONTAINER_MEMORY_USAGE: Final = "k8s.node.system_container.memory.usage" -""" -Node's system container memory usage -Instrument: updowncounter -Unit: By -Note: This metric is derived from the [MemoryStats.UsageBytes](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L252) field of the [ContainerStats](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L157C6-L157C20) of [Node.SystemContainers](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L40) of the Kubelet's stats API. -""" - - -def create_k8s_node_system_container_memory_usage(meter: Meter) -> UpDownCounter: - """Node's system container memory usage""" - return meter.create_up_down_counter( - name=K8S_NODE_SYSTEM_CONTAINER_MEMORY_USAGE, - description="Node's system container memory usage.", - unit="By", - ) - - -K8S_NODE_SYSTEM_CONTAINER_MEMORY_WORKING_SET: Final = "k8s.node.system_container.memory.working_set" -""" -The amount of working set memory -Instrument: updowncounter -Unit: By -Note: This metric is derived from the [MemoryStats.WorkingSetBytes](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L256) field of the [ContainerStats](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L157C6-L157C20) of [Node.SystemContainers](https://github.com/kubernetes/kubelet/blob/v0.35.2/pkg/apis/stats/v1alpha1/types.go#L40) of the Kubelet's stats API. -""" - - -def create_k8s_node_system_container_memory_working_set(meter: Meter) -> UpDownCounter: - """The amount of working set memory""" - return meter.create_up_down_counter( - name=K8S_NODE_SYSTEM_CONTAINER_MEMORY_WORKING_SET, - description="The amount of working set memory.", - unit="By", - ) - - -K8S_NODE_UPTIME: Final = "k8s.node.uptime" -""" -The time the Node has been running -Instrument: gauge -Unit: s -Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. -The actual accuracy would depend on the instrumentation and operating system. -""" - - -def create_k8s_node_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The time the Node has been running""" - return meter.create_observable_gauge( - name=K8S_NODE_UPTIME, - callbacks=callbacks, - description="The time the Node has been running.", - unit="s", - ) - - -K8S_PERSISTENTVOLUME_STATUS_PHASE: Final = "k8s.persistentvolume.status.phase" -""" -Number of PersistentVolumes in a given phase -Instrument: updowncounter -Unit: {persistentvolume} -Note: All possible phases should be reported at each interval to avoid gaps in the time series. -This metric is derived from the `.status.phase` field of the -[K8s PersistentVolumeStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeStatus). -""" - - -def create_k8s_persistentvolume_status_phase(meter: Meter) -> UpDownCounter: - """Number of PersistentVolumes in a given phase""" - return meter.create_up_down_counter( - name=K8S_PERSISTENTVOLUME_STATUS_PHASE, - description="Number of PersistentVolumes in a given phase.", - unit="{persistentvolume}", - ) - - -K8S_PERSISTENTVOLUME_STORAGE_CAPACITY: Final = "k8s.persistentvolume.storage.capacity" -""" -The storage capacity of the PersistentVolume -Instrument: updowncounter -Unit: By -Note: This metric is derived from the `.spec.capacity.storage` field of the [K8s PersistentVolumeSpec](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-v1/#PersistentVolumeSpec). -""" - - -def create_k8s_persistentvolume_storage_capacity(meter: Meter) -> UpDownCounter: - """The storage capacity of the PersistentVolume""" - return meter.create_up_down_counter( - name=K8S_PERSISTENTVOLUME_STORAGE_CAPACITY, - description="The storage capacity of the PersistentVolume.", - unit="By", - ) - - -K8S_PERSISTENTVOLUMECLAIM_STATUS_PHASE: Final = "k8s.persistentvolumeclaim.status.phase" -""" -Number of PersistentVolumeClaims in a given phase -Instrument: updowncounter -Unit: {persistentvolumeclaim} -Note: All possible phases should be reported at each interval to avoid gaps in the time series. -This metric is derived from the `.status.phase` field of the -[K8s PersistentVolumeClaimStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus). -""" - - -def create_k8s_persistentvolumeclaim_status_phase(meter: Meter) -> UpDownCounter: - """Number of PersistentVolumeClaims in a given phase""" - return meter.create_up_down_counter( - name=K8S_PERSISTENTVOLUMECLAIM_STATUS_PHASE, - description="Number of PersistentVolumeClaims in a given phase.", - unit="{persistentvolumeclaim}", - ) - - -K8S_PERSISTENTVOLUMECLAIM_STORAGE_CAPACITY: Final = "k8s.persistentvolumeclaim.storage.capacity" -""" -The actual storage capacity provisioned for the PersistentVolumeClaim -Instrument: updowncounter -Unit: By -Note: Only available when the PVC is bound. May differ from the requested capacity due to provisioner rounding. -This metric is derived from the `.status.capacity.storage` field of the -[K8s PersistentVolumeClaimStatus](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimStatus). -""" - - -def create_k8s_persistentvolumeclaim_storage_capacity(meter: Meter) -> UpDownCounter: - """The actual storage capacity provisioned for the PersistentVolumeClaim""" - return meter.create_up_down_counter( - name=K8S_PERSISTENTVOLUMECLAIM_STORAGE_CAPACITY, - description="The actual storage capacity provisioned for the PersistentVolumeClaim.", - unit="By", - ) - - -K8S_PERSISTENTVOLUMECLAIM_STORAGE_REQUEST: Final = "k8s.persistentvolumeclaim.storage.request" -""" -The storage requested by the PersistentVolumeClaim -Instrument: updowncounter -Unit: By -Note: This metric is derived from the `.spec.resources.requests.storage` field of the [K8s PersistentVolumeClaimSpec](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/persistent-volume-claim-v1/#PersistentVolumeClaimSpec). -""" - - -def create_k8s_persistentvolumeclaim_storage_request(meter: Meter) -> UpDownCounter: - """The storage requested by the PersistentVolumeClaim""" - return meter.create_up_down_counter( - name=K8S_PERSISTENTVOLUMECLAIM_STORAGE_REQUEST, - description="The storage requested by the PersistentVolumeClaim.", - unit="By", - ) - - -K8S_POD_CPU_TIME: Final = "k8s.pod.cpu.time" -""" -Total CPU time consumed -Instrument: counter -Unit: s -Note: Total CPU time consumed by the specific Pod on all available CPU cores. -""" - - -def create_k8s_pod_cpu_time(meter: Meter) -> Counter: - """Total CPU time consumed""" - return meter.create_counter( - name=K8S_POD_CPU_TIME, - description="Total CPU time consumed.", - unit="s", - ) - - -K8S_POD_CPU_USAGE: Final = "k8s.pod.cpu.usage" -""" -Pod's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs -Instrument: gauge -Unit: {cpu} -Note: CPU usage of the specific Pod on all available CPU cores. It is calculated as the change in cumulative CPU time (k8s.pod.cpu.time) over a measurement interval, divided by the elapsed time: usageCores = (cpuTimeEnd - cpuTimeStart) / elapsedSeconds. -""" - - -def create_k8s_pod_cpu_usage(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Pod's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs""" - return meter.create_observable_gauge( - name=K8S_POD_CPU_USAGE, - callbacks=callbacks, - description="Pod's CPU usage, measured in CPUs. Range from 0 to the number of allocatable CPUs.", - unit="{cpu}", - ) - - -K8S_POD_FILESYSTEM_AVAILABLE: Final = "k8s.pod.filesystem.available" -""" -Pod filesystem available bytes -Instrument: updowncounter -Unit: By -Note: This metric is derived from the -[FsStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [PodStats.EphemeralStorage](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) -of the Kubelet's stats API. -""" - - -def create_k8s_pod_filesystem_available(meter: Meter) -> UpDownCounter: - """Pod filesystem available bytes""" - return meter.create_up_down_counter( - name=K8S_POD_FILESYSTEM_AVAILABLE, - description="Pod filesystem available bytes.", - unit="By", - ) - - -K8S_POD_FILESYSTEM_CAPACITY: Final = "k8s.pod.filesystem.capacity" -""" -Pod filesystem capacity -Instrument: updowncounter -Unit: By -Note: This metric is derived from the -[FsStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [PodStats.EphemeralStorage](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) -of the Kubelet's stats API. -""" - - -def create_k8s_pod_filesystem_capacity(meter: Meter) -> UpDownCounter: - """Pod filesystem capacity""" - return meter.create_up_down_counter( - name=K8S_POD_FILESYSTEM_CAPACITY, - description="Pod filesystem capacity.", - unit="By", - ) - - -K8S_POD_FILESYSTEM_USAGE: Final = "k8s.pod.filesystem.usage" -""" -Pod filesystem usage -Instrument: updowncounter -Unit: By -Note: This may not equal capacity - available. - -This metric is derived from the -[FsStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#FsStats) field -of the [PodStats.EphemeralStorage](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) -of the Kubelet's stats API. -""" - - -def create_k8s_pod_filesystem_usage(meter: Meter) -> UpDownCounter: - """Pod filesystem usage""" - return meter.create_up_down_counter( - name=K8S_POD_FILESYSTEM_USAGE, - description="Pod filesystem usage.", - unit="By", - ) - - -K8S_POD_MEMORY_AVAILABLE: Final = "k8s.pod.memory.available" -""" -Pod memory available -Instrument: updowncounter -Unit: By -Note: Available memory for use. This is defined as the memory limit - workingSetBytes. If memory limit is undefined, the available bytes is omitted. -This metric is derived from the [MemoryStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. -""" - - -def create_k8s_pod_memory_available(meter: Meter) -> UpDownCounter: - """Pod memory available""" - return meter.create_up_down_counter( - name=K8S_POD_MEMORY_AVAILABLE, - description="Pod memory available.", - unit="By", - ) - - -K8S_POD_MEMORY_PAGING_FAULTS: Final = "k8s.pod.memory.paging.faults" -""" -Deprecated: Replaced by `k8s.pod.paging.faults`. -""" - - -def create_k8s_pod_memory_paging_faults(meter: Meter) -> Counter: - """Deprecated, use `k8s.pod.paging.faults` instead""" - return meter.create_counter( - name=K8S_POD_MEMORY_PAGING_FAULTS, - description="Deprecated, use `k8s.pod.paging.faults` instead.", - unit="{fault}", - ) - - -K8S_POD_MEMORY_RSS: Final = "k8s.pod.memory.rss" -""" -Pod memory RSS -Instrument: updowncounter -Unit: By -Note: The amount of anonymous and swap cache memory (includes transparent hugepages). -This metric is derived from the [MemoryStats.RSSBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. -""" - - -def create_k8s_pod_memory_rss(meter: Meter) -> UpDownCounter: - """Pod memory RSS""" - return meter.create_up_down_counter( - name=K8S_POD_MEMORY_RSS, - description="Pod memory RSS.", - unit="By", - ) - - -K8S_POD_MEMORY_USAGE: Final = "k8s.pod.memory.usage" -""" -Memory usage of the Pod -Instrument: updowncounter -Unit: By -Note: Total memory in use. This includes all memory regardless of when it was accessed. -This metric is derived from the [MemoryStats.UsageBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. -""" - - -def create_k8s_pod_memory_usage(meter: Meter) -> UpDownCounter: - """Memory usage of the Pod""" - return meter.create_up_down_counter( - name=K8S_POD_MEMORY_USAGE, - description="Memory usage of the Pod.", - unit="By", - ) - - -K8S_POD_MEMORY_WORKING_SET: Final = "k8s.pod.memory.working_set" -""" -Pod memory working set -Instrument: updowncounter -Unit: By -Note: The amount of working set memory. This includes recently accessed memory, dirty memory, and kernel memory. WorkingSetBytes is <= UsageBytes. -This metric is derived from the [MemoryStats.WorkingSetBytes](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. -""" - - -def create_k8s_pod_memory_working_set(meter: Meter) -> UpDownCounter: - """Pod memory working set""" - return meter.create_up_down_counter( - name=K8S_POD_MEMORY_WORKING_SET, - description="Pod memory working set.", - unit="By", - ) - - -K8S_POD_NETWORK_ERRORS: Final = "k8s.pod.network.errors" -""" -Pod network errors -Instrument: counter -Unit: {error} -""" - - -def create_k8s_pod_network_errors(meter: Meter) -> Counter: - """Pod network errors""" - return meter.create_counter( - name=K8S_POD_NETWORK_ERRORS, - description="Pod network errors.", - unit="{error}", - ) - - -K8S_POD_NETWORK_IO: Final = "k8s.pod.network.io" -""" -Network bytes for the Pod -Instrument: counter -Unit: By -""" - - -def create_k8s_pod_network_io(meter: Meter) -> Counter: - """Network bytes for the Pod""" - return meter.create_counter( - name=K8S_POD_NETWORK_IO, - description="Network bytes for the Pod.", - unit="By", - ) - - -K8S_POD_PAGING_FAULTS: Final = "k8s.pod.paging.faults" -""" -Pod memory paging faults -Instrument: counter -Unit: {fault} -Note: Cumulative number of major/minor page faults. -This metric is derived from the [MemoryStats.PageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) and [MemoryStats.MajorPageFaults](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#MemoryStats) field of the [PodStats.Memory](https://pkg.go.dev/k8s.io/kubelet@v0.34.0/pkg/apis/stats/v1alpha1#PodStats) of the Kubelet's stats API. -""" - - -def create_k8s_pod_paging_faults(meter: Meter) -> Counter: - """Pod memory paging faults""" - return meter.create_counter( - name=K8S_POD_PAGING_FAULTS, - description="Pod memory paging faults.", - unit="{fault}", - ) - - -K8S_POD_STATUS_PHASE: Final = "k8s.pod.status.phase" -""" -Describes number of K8s Pods that are currently in a given phase -Instrument: updowncounter -Unit: {pod} -Note: All possible pod phases will be reported at each time interval to avoid missing metrics. -Only the value corresponding to the current phase will be non-zero. -""" - - -def create_k8s_pod_status_phase(meter: Meter) -> UpDownCounter: - """Describes number of K8s Pods that are currently in a given phase""" - return meter.create_up_down_counter( - name=K8S_POD_STATUS_PHASE, - description="Describes number of K8s Pods that are currently in a given phase.", - unit="{pod}", - ) - - -K8S_POD_STATUS_REASON: Final = "k8s.pod.status.reason" -""" -Describes the number of K8s Pods that are currently in a state for a given reason -Instrument: updowncounter -Unit: {pod} -Note: All possible pod status reasons will be reported at each time interval to avoid missing metrics. -Only the value corresponding to the current reason will be non-zero. -""" - - -def create_k8s_pod_status_reason(meter: Meter) -> UpDownCounter: - """Describes the number of K8s Pods that are currently in a state for a given reason""" - return meter.create_up_down_counter( - name=K8S_POD_STATUS_REASON, - description="Describes the number of K8s Pods that are currently in a state for a given reason.", - unit="{pod}", - ) - - -K8S_POD_UPTIME: Final = "k8s.pod.uptime" -""" -The time the Pod has been running -Instrument: gauge -Unit: s -Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. -The actual accuracy would depend on the instrumentation and operating system. -""" - - -def create_k8s_pod_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The time the Pod has been running""" - return meter.create_observable_gauge( - name=K8S_POD_UPTIME, - callbacks=callbacks, - description="The time the Pod has been running.", - unit="s", - ) - - -K8S_POD_VOLUME_AVAILABLE: Final = "k8s.pod.volume.available" -""" -Pod volume storage space available -Instrument: updowncounter -Unit: By -Note: This metric is derived from the -[VolumeStats.AvailableBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field -of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the -Kubelet's stats API. -""" - - -def create_k8s_pod_volume_available(meter: Meter) -> UpDownCounter: - """Pod volume storage space available""" - return meter.create_up_down_counter( - name=K8S_POD_VOLUME_AVAILABLE, - description="Pod volume storage space available.", - unit="By", - ) - - -K8S_POD_VOLUME_CAPACITY: Final = "k8s.pod.volume.capacity" -""" -Pod volume total capacity -Instrument: updowncounter -Unit: By -Note: This metric is derived from the -[VolumeStats.CapacityBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field -of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the -Kubelet's stats API. -""" - - -def create_k8s_pod_volume_capacity(meter: Meter) -> UpDownCounter: - """Pod volume total capacity""" - return meter.create_up_down_counter( - name=K8S_POD_VOLUME_CAPACITY, - description="Pod volume total capacity.", - unit="By", - ) - - -K8S_POD_VOLUME_INODE_COUNT: Final = "k8s.pod.volume.inode.count" -""" -The total inodes in the filesystem of the Pod's volume -Instrument: updowncounter -Unit: {inode} -Note: This metric is derived from the -[VolumeStats.Inodes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field -of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the -Kubelet's stats API. -""" - - -def create_k8s_pod_volume_inode_count(meter: Meter) -> UpDownCounter: - """The total inodes in the filesystem of the Pod's volume""" - return meter.create_up_down_counter( - name=K8S_POD_VOLUME_INODE_COUNT, - description="The total inodes in the filesystem of the Pod's volume.", - unit="{inode}", - ) - - -K8S_POD_VOLUME_INODE_FREE: Final = "k8s.pod.volume.inode.free" -""" -The free inodes in the filesystem of the Pod's volume -Instrument: updowncounter -Unit: {inode} -Note: This metric is derived from the -[VolumeStats.InodesFree](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field -of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the -Kubelet's stats API. -""" - - -def create_k8s_pod_volume_inode_free(meter: Meter) -> UpDownCounter: - """The free inodes in the filesystem of the Pod's volume""" - return meter.create_up_down_counter( - name=K8S_POD_VOLUME_INODE_FREE, - description="The free inodes in the filesystem of the Pod's volume.", - unit="{inode}", - ) - - -K8S_POD_VOLUME_INODE_USED: Final = "k8s.pod.volume.inode.used" -""" -The inodes used by the filesystem of the Pod's volume -Instrument: updowncounter -Unit: {inode} -Note: This metric is derived from the -[VolumeStats.InodesUsed](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field -of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the -Kubelet's stats API. - -This may not be equal to `inodes - free` because filesystem may share inodes with other filesystems. -""" - - -def create_k8s_pod_volume_inode_used(meter: Meter) -> UpDownCounter: - """The inodes used by the filesystem of the Pod's volume""" - return meter.create_up_down_counter( - name=K8S_POD_VOLUME_INODE_USED, - description="The inodes used by the filesystem of the Pod's volume.", - unit="{inode}", - ) - - -K8S_POD_VOLUME_USAGE: Final = "k8s.pod.volume.usage" -""" -Pod volume usage -Instrument: updowncounter -Unit: By -Note: This may not equal capacity - available. - -This metric is derived from the -[VolumeStats.UsedBytes](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#VolumeStats) field -of the [PodStats](https://pkg.go.dev/k8s.io/kubelet@v0.33.0/pkg/apis/stats/v1alpha1#PodStats) of the -Kubelet's stats API. -""" - - -def create_k8s_pod_volume_usage(meter: Meter) -> UpDownCounter: - """Pod volume usage""" - return meter.create_up_down_counter( - name=K8S_POD_VOLUME_USAGE, - description="Pod volume usage.", - unit="By", - ) - - -K8S_REPLICASET_AVAILABLE_PODS: Final = "k8s.replicaset.available_pods" -""" -Deprecated: Replaced by `k8s.replicaset.pod.available`. -""" - - -def create_k8s_replicaset_available_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.replicaset.pod.available` instead""" - return meter.create_up_down_counter( - name=K8S_REPLICASET_AVAILABLE_PODS, - description="Deprecated, use `k8s.replicaset.pod.available` instead.", - unit="{pod}", - ) - - -K8S_REPLICASET_DESIRED_PODS: Final = "k8s.replicaset.desired_pods" -""" -Deprecated: Replaced by `k8s.replicaset.pod.desired`. -""" - - -def create_k8s_replicaset_desired_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.replicaset.pod.desired` instead""" - return meter.create_up_down_counter( - name=K8S_REPLICASET_DESIRED_PODS, - description="Deprecated, use `k8s.replicaset.pod.desired` instead.", - unit="{pod}", - ) - - -K8S_REPLICASET_POD_AVAILABLE: Final = "k8s.replicaset.pod.available" -""" -Total number of available replica pods (ready for at least minReadySeconds) targeted by this replicaset -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `availableReplicas` field of the -[K8s ReplicaSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicasetstatus-v1-apps). -""" - - -def create_k8s_replicaset_pod_available(meter: Meter) -> UpDownCounter: - """Total number of available replica pods (ready for at least minReadySeconds) targeted by this replicaset""" - return meter.create_up_down_counter( - name=K8S_REPLICASET_POD_AVAILABLE, - description="Total number of available replica pods (ready for at least minReadySeconds) targeted by this replicaset.", - unit="{pod}", - ) - - -K8S_REPLICASET_POD_DESIRED: Final = "k8s.replicaset.pod.desired" -""" -Number of desired replica pods in this replicaset -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `replicas` field of the -[K8s ReplicaSetSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicasetspec-v1-apps). -""" - - -def create_k8s_replicaset_pod_desired(meter: Meter) -> UpDownCounter: - """Number of desired replica pods in this replicaset""" - return meter.create_up_down_counter( - name=K8S_REPLICASET_POD_DESIRED, - description="Number of desired replica pods in this replicaset.", - unit="{pod}", - ) - - -K8S_REPLICATION_CONTROLLER_AVAILABLE_PODS: Final = "k8s.replication_controller.available_pods" -""" -Deprecated: Replaced by `k8s.replicationcontroller.pod.available`. -""" - - -def create_k8s_replication_controller_available_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.replicationcontroller.pod.available` instead""" - return meter.create_up_down_counter( - name=K8S_REPLICATION_CONTROLLER_AVAILABLE_PODS, - description="Deprecated, use `k8s.replicationcontroller.pod.available` instead.", - unit="{pod}", - ) - - -K8S_REPLICATION_CONTROLLER_DESIRED_PODS: Final = "k8s.replication_controller.desired_pods" -""" -Deprecated: Replaced by `k8s.replicationcontroller.pod.desired`. -""" - - -def create_k8s_replication_controller_desired_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.replicationcontroller.pod.desired` instead""" - return meter.create_up_down_counter( - name=K8S_REPLICATION_CONTROLLER_DESIRED_PODS, - description="Deprecated, use `k8s.replicationcontroller.pod.desired` instead.", - unit="{pod}", - ) - - -K8S_REPLICATIONCONTROLLER_AVAILABLE_PODS: Final = "k8s.replicationcontroller.available_pods" -""" -Deprecated: Replaced by `k8s.replicationcontroller.pod.available`. -""" - - -def create_k8s_replicationcontroller_available_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.replicationcontroller.pod.available` instead""" - return meter.create_up_down_counter( - name=K8S_REPLICATIONCONTROLLER_AVAILABLE_PODS, - description="Deprecated, use `k8s.replicationcontroller.pod.available` instead.", - unit="{pod}", - ) - - -K8S_REPLICATIONCONTROLLER_DESIRED_PODS: Final = "k8s.replicationcontroller.desired_pods" -""" -Deprecated: Replaced by `k8s.replicationcontroller.pod.desired`. -""" - - -def create_k8s_replicationcontroller_desired_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.replicationcontroller.pod.desired` instead""" - return meter.create_up_down_counter( - name=K8S_REPLICATIONCONTROLLER_DESIRED_PODS, - description="Deprecated, use `k8s.replicationcontroller.pod.desired` instead.", - unit="{pod}", - ) - - -K8S_REPLICATIONCONTROLLER_POD_AVAILABLE: Final = "k8s.replicationcontroller.pod.available" -""" -Total number of available replica pods (ready for at least minReadySeconds) targeted by this replication controller -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `availableReplicas` field of the -[K8s ReplicationControllerStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicationcontrollerstatus-v1-core). -""" - - -def create_k8s_replicationcontroller_pod_available(meter: Meter) -> UpDownCounter: - """Total number of available replica pods (ready for at least minReadySeconds) targeted by this replication controller""" - return meter.create_up_down_counter( - name=K8S_REPLICATIONCONTROLLER_POD_AVAILABLE, - description="Total number of available replica pods (ready for at least minReadySeconds) targeted by this replication controller.", - unit="{pod}", - ) - - -K8S_REPLICATIONCONTROLLER_POD_DESIRED: Final = "k8s.replicationcontroller.pod.desired" -""" -Number of desired replica pods in this replication controller -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `replicas` field of the -[K8s ReplicationControllerSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#replicationcontrollerspec-v1-core). -""" - - -def create_k8s_replicationcontroller_pod_desired(meter: Meter) -> UpDownCounter: - """Number of desired replica pods in this replication controller""" - return meter.create_up_down_counter( - name=K8S_REPLICATIONCONTROLLER_POD_DESIRED, - description="Number of desired replica pods in this replication controller.", - unit="{pod}", - ) - - -K8S_RESOURCEQUOTA_CPU_LIMIT_HARD: Final = "k8s.resourcequota.cpu.limit.hard" -""" -The CPU limits in a specific namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_cpu_limit_hard(meter: Meter) -> UpDownCounter: - """The CPU limits in a specific namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_CPU_LIMIT_HARD, - description="The CPU limits in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="{cpu}", - ) - - -K8S_RESOURCEQUOTA_CPU_LIMIT_USED: Final = "k8s.resourcequota.cpu.limit.used" -""" -The CPU limits in a specific namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_cpu_limit_used(meter: Meter) -> UpDownCounter: - """The CPU limits in a specific namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_CPU_LIMIT_USED, - description="The CPU limits in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="{cpu}", - ) - - -K8S_RESOURCEQUOTA_CPU_REQUEST_HARD: Final = "k8s.resourcequota.cpu.request.hard" -""" -The CPU requests in a specific namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_cpu_request_hard(meter: Meter) -> UpDownCounter: - """The CPU requests in a specific namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_CPU_REQUEST_HARD, - description="The CPU requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="{cpu}", - ) - - -K8S_RESOURCEQUOTA_CPU_REQUEST_USED: Final = "k8s.resourcequota.cpu.request.used" -""" -The CPU requests in a specific namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_cpu_request_used(meter: Meter) -> UpDownCounter: - """The CPU requests in a specific namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_CPU_REQUEST_USED, - description="The CPU requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="{cpu}", - ) - - -K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD: Final = "k8s.resourcequota.ephemeral_storage.limit.hard" -""" -The sum of local ephemeral storage limits in the namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_ephemeral_storage_limit_hard(meter: Meter) -> UpDownCounter: - """The sum of local ephemeral storage limits in the namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD, - description="The sum of local ephemeral storage limits in the namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_USED: Final = "k8s.resourcequota.ephemeral_storage.limit.used" -""" -The sum of local ephemeral storage limits in the namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_ephemeral_storage_limit_used(meter: Meter) -> UpDownCounter: - """The sum of local ephemeral storage limits in the namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_LIMIT_USED, - description="The sum of local ephemeral storage limits in the namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD: Final = "k8s.resourcequota.ephemeral_storage.request.hard" -""" -The sum of local ephemeral storage requests in the namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_ephemeral_storage_request_hard(meter: Meter) -> UpDownCounter: - """The sum of local ephemeral storage requests in the namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD, - description="The sum of local ephemeral storage requests in the namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_USED: Final = "k8s.resourcequota.ephemeral_storage.request.used" -""" -The sum of local ephemeral storage requests in the namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_ephemeral_storage_request_used(meter: Meter) -> UpDownCounter: - """The sum of local ephemeral storage requests in the namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_EPHEMERAL_STORAGE_REQUEST_USED, - description="The sum of local ephemeral storage requests in the namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_HARD: Final = "k8s.resourcequota.hugepage_count.request.hard" -""" -The huge page requests in a specific namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: {hugepage} -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_hugepage_count_request_hard(meter: Meter) -> UpDownCounter: - """The huge page requests in a specific namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_HARD, - description="The huge page requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="{hugepage}", - ) - - -K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_USED: Final = "k8s.resourcequota.hugepage_count.request.used" -""" -The huge page requests in a specific namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: {hugepage} -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_hugepage_count_request_used(meter: Meter) -> UpDownCounter: - """The huge page requests in a specific namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_HUGEPAGE_COUNT_REQUEST_USED, - description="The huge page requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="{hugepage}", - ) - - -K8S_RESOURCEQUOTA_MEMORY_LIMIT_HARD: Final = "k8s.resourcequota.memory.limit.hard" -""" -The memory limits in a specific namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_memory_limit_hard(meter: Meter) -> UpDownCounter: - """The memory limits in a specific namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_MEMORY_LIMIT_HARD, - description="The memory limits in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_MEMORY_LIMIT_USED: Final = "k8s.resourcequota.memory.limit.used" -""" -The memory limits in a specific namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_memory_limit_used(meter: Meter) -> UpDownCounter: - """The memory limits in a specific namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_MEMORY_LIMIT_USED, - description="The memory limits in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_MEMORY_REQUEST_HARD: Final = "k8s.resourcequota.memory.request.hard" -""" -The memory requests in a specific namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_memory_request_hard(meter: Meter) -> UpDownCounter: - """The memory requests in a specific namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_MEMORY_REQUEST_HARD, - description="The memory requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_MEMORY_REQUEST_USED: Final = "k8s.resourcequota.memory.request.used" -""" -The memory requests in a specific namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_memory_request_used(meter: Meter) -> UpDownCounter: - """The memory requests in a specific namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_MEMORY_REQUEST_USED, - description="The memory requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_OBJECT_COUNT_HARD: Final = "k8s.resourcequota.object_count.hard" -""" -The object count limits in a specific namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: {object} -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_object_count_hard(meter: Meter) -> UpDownCounter: - """The object count limits in a specific namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_OBJECT_COUNT_HARD, - description="The object count limits in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="{object}", - ) - - -K8S_RESOURCEQUOTA_OBJECT_COUNT_USED: Final = "k8s.resourcequota.object_count.used" -""" -The object count limits in a specific namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: {object} -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). -""" - - -def create_k8s_resourcequota_object_count_used(meter: Meter) -> UpDownCounter: - """The object count limits in a specific namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_OBJECT_COUNT_USED, - description="The object count limits in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="{object}", - ) - - -K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD: Final = "k8s.resourcequota.persistentvolumeclaim_count.hard" -""" -The total number of PersistentVolumeClaims that can exist in the namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: {persistentvolumeclaim} -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_k8s_resourcequota_persistentvolumeclaim_count_hard(meter: Meter) -> UpDownCounter: - """The total number of PersistentVolumeClaims that can exist in the namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD, - description="The total number of PersistentVolumeClaims that can exist in the namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="{persistentvolumeclaim}", - ) - - -K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED: Final = "k8s.resourcequota.persistentvolumeclaim_count.used" -""" -The total number of PersistentVolumeClaims that can exist in the namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: {persistentvolumeclaim} -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_k8s_resourcequota_persistentvolumeclaim_count_used(meter: Meter) -> UpDownCounter: - """The total number of PersistentVolumeClaims that can exist in the namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED, - description="The total number of PersistentVolumeClaims that can exist in the namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="{persistentvolumeclaim}", - ) - - -K8S_RESOURCEQUOTA_STORAGE_REQUEST_HARD: Final = "k8s.resourcequota.storage.request.hard" -""" -The storage requests in a specific namespace. -The value represents the configured quota limit of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_k8s_resourcequota_storage_request_hard(meter: Meter) -> UpDownCounter: - """The storage requests in a specific namespace. - The value represents the configured quota limit of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_STORAGE_REQUEST_HARD, - description="The storage requests in a specific namespace. The value represents the configured quota limit of the resource in the namespace.", - unit="By", - ) - - -K8S_RESOURCEQUOTA_STORAGE_REQUEST_USED: Final = "k8s.resourcequota.storage.request.used" -""" -The storage requests in a specific namespace. -The value represents the current observed total usage of the resource in the namespace -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_k8s_resourcequota_storage_request_used(meter: Meter) -> UpDownCounter: - """The storage requests in a specific namespace. - The value represents the current observed total usage of the resource in the namespace""" - return meter.create_up_down_counter( - name=K8S_RESOURCEQUOTA_STORAGE_REQUEST_USED, - description="The storage requests in a specific namespace. The value represents the current observed total usage of the resource in the namespace.", - unit="By", - ) - - -K8S_SERVICE_ENDPOINT_COUNT: Final = "k8s.service.endpoint.count" -""" -Number of endpoints for a service by condition and address type -Instrument: gauge -Unit: {endpoint} -Note: This metric is derived from the Kubernetes [EndpointSlice API](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/). -It reports the number of network endpoints backing a Service, broken down by their condition and address type. - -In dual-stack or multi-protocol clusters, separate counts are reported for each address family (`IPv4`, `IPv6`, `FQDN`). - -When the optional `zone` attribute is enabled, counts are further broken down by availability zone for zone-aware monitoring. - -An endpoint may be reported under multiple conditions simultaneously (e.g., both `serving` and `terminating` during a graceful shutdown). -See [K8s EndpointConditions](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/) for more details. - -The conditions represent: -- `ready`: Endpoints capable of receiving new connections. -- `serving`: Endpoints currently handling traffic. -- `terminating`: Endpoints that are being phased out but may still be handling existing connections. - -For Services with `publishNotReadyAddresses` enabled (common for headless StatefulSets), -this metric will include endpoints that are published despite not being ready. -The `k8s.service.publish_not_ready_addresses` resource attribute indicates this setting. -""" - - -def create_k8s_service_endpoint_count(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Number of endpoints for a service by condition and address type""" - return meter.create_observable_gauge( - name=K8S_SERVICE_ENDPOINT_COUNT, - callbacks=callbacks, - description="Number of endpoints for a service by condition and address type.", - unit="{endpoint}", - ) - - -K8S_SERVICE_LOAD_BALANCER_INGRESS_COUNT: Final = "k8s.service.load_balancer.ingress.count" -""" -Number of load balancer ingress points (external IPs/hostnames) assigned to the service -Instrument: gauge -Unit: {ingress} -Note: This metric reports the number of external ingress points (IP addresses or hostnames) -assigned to a LoadBalancer Service. - -It is only emitted for Services of type `LoadBalancer` and reflects the assignments -made by the underlying infrastructure's load balancer controller in the -[.status.loadBalancer.ingress](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceStatus) field. - -A value of `0` indicates that no ingress points have been assigned yet (e.g., during provisioning). -A value greater than `1` may occur when multiple IPs or hostnames are assigned (e.g., dual-stack configurations). - -This metric signals that external endpoints have been assigned by the load balancer controller, but it does not -guarantee that the load balancer is healthy. -""" - - -def create_k8s_service_load_balancer_ingress_count( - meter: Meter, callbacks: Sequence[CallbackT] | None -) -> ObservableGauge: - """Number of load balancer ingress points (external IPs/hostnames) assigned to the service""" - return meter.create_observable_gauge( - name=K8S_SERVICE_LOAD_BALANCER_INGRESS_COUNT, - callbacks=callbacks, - description="Number of load balancer ingress points (external IPs/hostnames) assigned to the service.", - unit="{ingress}", - ) - - -K8S_STATEFULSET_CURRENT_PODS: Final = "k8s.statefulset.current_pods" -""" -Deprecated: Replaced by `k8s.statefulset.pod.current`. -""" - - -def create_k8s_statefulset_current_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.statefulset.pod.current` instead""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_CURRENT_PODS, - description="Deprecated, use `k8s.statefulset.pod.current` instead.", - unit="{pod}", - ) - - -K8S_STATEFULSET_DESIRED_PODS: Final = "k8s.statefulset.desired_pods" -""" -Deprecated: Replaced by `k8s.statefulset.pod.desired`. -""" - - -def create_k8s_statefulset_desired_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.statefulset.pod.desired` instead""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_DESIRED_PODS, - description="Deprecated, use `k8s.statefulset.pod.desired` instead.", - unit="{pod}", - ) - - -K8S_STATEFULSET_POD_CURRENT: Final = "k8s.statefulset.pod.current" -""" -The number of replica pods created by the statefulset controller from the statefulset version indicated by currentRevision -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `currentReplicas` field of the -[K8s StatefulSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetstatus-v1-apps). -""" - - -def create_k8s_statefulset_pod_current(meter: Meter) -> UpDownCounter: - """The number of replica pods created by the statefulset controller from the statefulset version indicated by currentRevision""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_POD_CURRENT, - description="The number of replica pods created by the statefulset controller from the statefulset version indicated by currentRevision.", - unit="{pod}", - ) - - -K8S_STATEFULSET_POD_DESIRED: Final = "k8s.statefulset.pod.desired" -""" -Number of desired replica pods in this statefulset -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `replicas` field of the -[K8s StatefulSetSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetspec-v1-apps). -""" - - -def create_k8s_statefulset_pod_desired(meter: Meter) -> UpDownCounter: - """Number of desired replica pods in this statefulset""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_POD_DESIRED, - description="Number of desired replica pods in this statefulset.", - unit="{pod}", - ) - - -K8S_STATEFULSET_POD_READY: Final = "k8s.statefulset.pod.ready" -""" -The number of replica pods created for this statefulset with a Ready Condition -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `readyReplicas` field of the -[K8s StatefulSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetstatus-v1-apps). -""" - - -def create_k8s_statefulset_pod_ready(meter: Meter) -> UpDownCounter: - """The number of replica pods created for this statefulset with a Ready Condition""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_POD_READY, - description="The number of replica pods created for this statefulset with a Ready Condition.", - unit="{pod}", - ) - - -K8S_STATEFULSET_POD_UPDATED: Final = "k8s.statefulset.pod.updated" -""" -Number of replica pods created by the statefulset controller from the statefulset version indicated by updateRevision -Instrument: updowncounter -Unit: {pod} -Note: This metric aligns with the `updatedReplicas` field of the -[K8s StatefulSetStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#statefulsetstatus-v1-apps). -""" - - -def create_k8s_statefulset_pod_updated(meter: Meter) -> UpDownCounter: - """Number of replica pods created by the statefulset controller from the statefulset version indicated by updateRevision""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_POD_UPDATED, - description="Number of replica pods created by the statefulset controller from the statefulset version indicated by updateRevision.", - unit="{pod}", - ) - - -K8S_STATEFULSET_READY_PODS: Final = "k8s.statefulset.ready_pods" -""" -Deprecated: Replaced by `k8s.statefulset.pod.ready`. -""" - - -def create_k8s_statefulset_ready_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.statefulset.pod.ready` instead""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_READY_PODS, - description="Deprecated, use `k8s.statefulset.pod.ready` instead.", - unit="{pod}", - ) - - -K8S_STATEFULSET_UPDATED_PODS: Final = "k8s.statefulset.updated_pods" -""" -Deprecated: Replaced by `k8s.statefulset.pod.updated`. -""" - - -def create_k8s_statefulset_updated_pods(meter: Meter) -> UpDownCounter: - """Deprecated, use `k8s.statefulset.pod.updated` instead""" - return meter.create_up_down_counter( - name=K8S_STATEFULSET_UPDATED_PODS, - description="Deprecated, use `k8s.statefulset.pod.updated` instead.", - unit="{pod}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py deleted file mode 100644 index 93bb2e833e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/mcp_metrics.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter - -MCP_CLIENT_OPERATION_DURATION: Final = "mcp.client.operation.duration" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_mcp_client_operation_duration(meter: Meter) -> Histogram: - """The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received""" - return meter.create_histogram( - name=MCP_CLIENT_OPERATION_DURATION, - description="The duration of the MCP request or notification as observed on the sender from the time it was sent until the response or ack is received.", - unit="s", - ) - - -MCP_CLIENT_SESSION_DURATION: Final = "mcp.client.session.duration" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_mcp_client_session_duration(meter: Meter) -> Histogram: - """The duration of the MCP session as observed on the MCP client""" - return meter.create_histogram( - name=MCP_CLIENT_SESSION_DURATION, - description="The duration of the MCP session as observed on the MCP client.", - unit="s", - ) - - -MCP_SERVER_OPERATION_DURATION: Final = "mcp.server.operation.duration" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_mcp_server_operation_duration(meter: Meter) -> Histogram: - """MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent""" - return meter.create_histogram( - name=MCP_SERVER_OPERATION_DURATION, - description="MCP request or notification duration as observed on the receiver from the time it was received until the result or ack is sent.", - unit="s", - ) - - -MCP_SERVER_SESSION_DURATION: Final = "mcp.server.session.duration" -""" -Deprecated: Moved to the [OpenTelemetry GenAI semantic conventions repository](https://github.com/open-telemetry/semantic-conventions-genai). -""" - - -def create_mcp_server_session_duration(meter: Meter) -> Histogram: - """The duration of the MCP session as observed on the MCP server""" - return meter.create_histogram( - name=MCP_SERVER_SESSION_DURATION, - description="The duration of the MCP session as observed on the MCP server.", - unit="s", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py deleted file mode 100644 index 8e7f878f099..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/messaging_metrics.py +++ /dev/null @@ -1,169 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter - -MESSAGING_CLIENT_CONSUMED_MESSAGES: Final = "messaging.client.consumed.messages" -""" -Number of messages that were delivered to the application -Instrument: counter -Unit: {message} -Note: Records the number of messages pulled from the broker or number of messages dispatched to the application in push-based scenarios. -The metric SHOULD be reported once per message delivery. For example, if receiving and processing operations are both instrumented for a single message delivery, this counter is incremented when the message is received and not reported when it is processed. -""" - - -def create_messaging_client_consumed_messages(meter: Meter) -> Counter: - """Number of messages that were delivered to the application""" - return meter.create_counter( - name=MESSAGING_CLIENT_CONSUMED_MESSAGES, - description="Number of messages that were delivered to the application.", - unit="{message}", - ) - - -MESSAGING_CLIENT_OPERATION_DURATION: Final = "messaging.client.operation.duration" -""" -Duration of messaging operation initiated by a producer or consumer client -Instrument: histogram -Unit: s -Note: This metric SHOULD NOT be used to report processing duration - processing duration is reported in `messaging.process.duration` metric. -""" - - -def create_messaging_client_operation_duration(meter: Meter) -> Histogram: - """Duration of messaging operation initiated by a producer or consumer client""" - return meter.create_histogram( - name=MESSAGING_CLIENT_OPERATION_DURATION, - description="Duration of messaging operation initiated by a producer or consumer client.", - unit="s", - ) - - -MESSAGING_CLIENT_PUBLISHED_MESSAGES: Final = "messaging.client.published.messages" -""" -Deprecated: Replaced by `messaging.client.sent.messages`. -""" - - -def create_messaging_client_published_messages(meter: Meter) -> Counter: - """Deprecated. Use `messaging.client.sent.messages` instead""" - return meter.create_counter( - name=MESSAGING_CLIENT_PUBLISHED_MESSAGES, - description="Deprecated. Use `messaging.client.sent.messages` instead.", - unit="{message}", - ) - - -MESSAGING_CLIENT_SENT_MESSAGES: Final = "messaging.client.sent.messages" -""" -Number of messages producer attempted to send to the broker -Instrument: counter -Unit: {message} -Note: This metric MUST NOT count messages that were created but haven't yet been sent. -""" - - -def create_messaging_client_sent_messages(meter: Meter) -> Counter: - """Number of messages producer attempted to send to the broker""" - return meter.create_counter( - name=MESSAGING_CLIENT_SENT_MESSAGES, - description="Number of messages producer attempted to send to the broker.", - unit="{message}", - ) - - -MESSAGING_PROCESS_DURATION: Final = "messaging.process.duration" -""" -Duration of processing operation -Instrument: histogram -Unit: s -Note: This metric MUST be reported for operations with `messaging.operation.type` that matches `process`. -""" - - -def create_messaging_process_duration(meter: Meter) -> Histogram: - """Duration of processing operation""" - return meter.create_histogram( - name=MESSAGING_PROCESS_DURATION, - description="Duration of processing operation.", - unit="s", - ) - - -MESSAGING_PROCESS_MESSAGES: Final = "messaging.process.messages" -""" -Deprecated: Replaced by `messaging.client.consumed.messages`. -""" - - -def create_messaging_process_messages(meter: Meter) -> Counter: - """Deprecated. Use `messaging.client.consumed.messages` instead""" - return meter.create_counter( - name=MESSAGING_PROCESS_MESSAGES, - description="Deprecated. Use `messaging.client.consumed.messages` instead.", - unit="{message}", - ) - - -MESSAGING_PUBLISH_DURATION: Final = "messaging.publish.duration" -""" -Deprecated: Replaced by `messaging.client.operation.duration`. -""" - - -def create_messaging_publish_duration(meter: Meter) -> Histogram: - """Deprecated. Use `messaging.client.operation.duration` instead""" - return meter.create_histogram( - name=MESSAGING_PUBLISH_DURATION, - description="Deprecated. Use `messaging.client.operation.duration` instead.", - unit="s", - ) - - -MESSAGING_PUBLISH_MESSAGES: Final = "messaging.publish.messages" -""" -Deprecated: Replaced by `messaging.client.sent.messages`. -""" - - -def create_messaging_publish_messages(meter: Meter) -> Counter: - """Deprecated. Use `messaging.client.sent.messages` instead""" - return meter.create_counter( - name=MESSAGING_PUBLISH_MESSAGES, - description="Deprecated. Use `messaging.client.sent.messages` instead.", - unit="{message}", - ) - - -MESSAGING_RECEIVE_DURATION: Final = "messaging.receive.duration" -""" -Deprecated: Replaced by `messaging.client.operation.duration`. -""" - - -def create_messaging_receive_duration(meter: Meter) -> Histogram: - """Deprecated. Use `messaging.client.operation.duration` instead""" - return meter.create_histogram( - name=MESSAGING_RECEIVE_DURATION, - description="Deprecated. Use `messaging.client.operation.duration` instead.", - unit="s", - ) - - -MESSAGING_RECEIVE_MESSAGES: Final = "messaging.receive.messages" -""" -Deprecated: Replaced by `messaging.client.consumed.messages`. -""" - - -def create_messaging_receive_messages(meter: Meter) -> Counter: - """Deprecated. Use `messaging.client.consumed.messages` instead""" - return meter.create_counter( - name=MESSAGING_RECEIVE_MESSAGES, - description="Deprecated. Use `messaging.client.consumed.messages` instead.", - unit="{message}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py deleted file mode 100644 index adfadc02083..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/nfs_metrics.py +++ /dev/null @@ -1,290 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Meter, UpDownCounter - -NFS_CLIENT_NET_COUNT: Final = "nfs.client.net.count" -""" -Reports the count of kernel NFS client TCP segments and UDP datagrams handled -Instrument: counter -Unit: {record} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.netudpcnt and svc_stat.nettcpcnt. -""" - - -def create_nfs_client_net_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS client TCP segments and UDP datagrams handled""" - return meter.create_counter( - name=NFS_CLIENT_NET_COUNT, - description="Reports the count of kernel NFS client TCP segments and UDP datagrams handled.", - unit="{record}", - ) - - -NFS_CLIENT_NET_TCP_CONNECTION_ACCEPTED: Final = "nfs.client.net.tcp.connection.accepted" -""" -Reports the count of kernel NFS client TCP connections accepted -Instrument: counter -Unit: {connection} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.nettcpconn. -""" - - -def create_nfs_client_net_tcp_connection_accepted(meter: Meter) -> Counter: - """Reports the count of kernel NFS client TCP connections accepted""" - return meter.create_counter( - name=NFS_CLIENT_NET_TCP_CONNECTION_ACCEPTED, - description="Reports the count of kernel NFS client TCP connections accepted.", - unit="{connection}", - ) - - -NFS_CLIENT_OPERATION_COUNT: Final = "nfs.client.operation.count" -""" -Reports the count of kernel NFSv4+ client operations -Instrument: counter -Unit: {operation} -""" - - -def create_nfs_client_operation_count(meter: Meter) -> Counter: - """Reports the count of kernel NFSv4+ client operations""" - return meter.create_counter( - name=NFS_CLIENT_OPERATION_COUNT, - description="Reports the count of kernel NFSv4+ client operations.", - unit="{operation}", - ) - - -NFS_CLIENT_PROCEDURE_COUNT: Final = "nfs.client.procedure.count" -""" -Reports the count of kernel NFS client procedures -Instrument: counter -Unit: {procedure} -""" - - -def create_nfs_client_procedure_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS client procedures""" - return meter.create_counter( - name=NFS_CLIENT_PROCEDURE_COUNT, - description="Reports the count of kernel NFS client procedures.", - unit="{procedure}", - ) - - -NFS_CLIENT_RPC_AUTHREFRESH_COUNT: Final = "nfs.client.rpc.authrefresh.count" -""" -Reports the count of kernel NFS client RPC authentication refreshes -Instrument: counter -Unit: {authrefresh} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpcauthrefresh. -""" - - -def create_nfs_client_rpc_authrefresh_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS client RPC authentication refreshes""" - return meter.create_counter( - name=NFS_CLIENT_RPC_AUTHREFRESH_COUNT, - description="Reports the count of kernel NFS client RPC authentication refreshes.", - unit="{authrefresh}", - ) - - -NFS_CLIENT_RPC_COUNT: Final = "nfs.client.rpc.count" -""" -Reports the count of kernel NFS client RPCs sent, regardless of whether they're accepted/rejected by the server -Instrument: counter -Unit: {request} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpccnt. -""" - - -def create_nfs_client_rpc_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS client RPCs sent, regardless of whether they're accepted/rejected by the server""" - return meter.create_counter( - name=NFS_CLIENT_RPC_COUNT, - description="Reports the count of kernel NFS client RPCs sent, regardless of whether they're accepted/rejected by the server.", - unit="{request}", - ) - - -NFS_CLIENT_RPC_RETRANSMIT_COUNT: Final = "nfs.client.rpc.retransmit.count" -""" -Reports the count of kernel NFS client RPC retransmits -Instrument: counter -Unit: {retransmit} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpcretrans. -""" - - -def create_nfs_client_rpc_retransmit_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS client RPC retransmits""" - return meter.create_counter( - name=NFS_CLIENT_RPC_RETRANSMIT_COUNT, - description="Reports the count of kernel NFS client RPC retransmits.", - unit="{retransmit}", - ) - - -NFS_SERVER_FH_STALE_COUNT: Final = "nfs.server.fh.stale.count" -""" -Reports the count of kernel NFS server stale file handles -Instrument: counter -Unit: {fh} -Note: Linux: this metric is taken from the Linux kernel NFSD_STATS_FH_STALE counter in the nfsd_net struct. -""" - - -def create_nfs_server_fh_stale_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS server stale file handles""" - return meter.create_counter( - name=NFS_SERVER_FH_STALE_COUNT, - description="Reports the count of kernel NFS server stale file handles.", - unit="{fh}", - ) - - -NFS_SERVER_IO: Final = "nfs.server.io" -""" -Reports the count of kernel NFS server bytes returned to receive and transmit (read and write) requests -Instrument: counter -Unit: By -Note: Linux: this metric is taken from the Linux kernel NFSD_STATS_IO_READ and NFSD_STATS_IO_WRITE counters in the nfsd_net struct. -""" - - -def create_nfs_server_io(meter: Meter) -> Counter: - """Reports the count of kernel NFS server bytes returned to receive and transmit (read and write) requests""" - return meter.create_counter( - name=NFS_SERVER_IO, - description="Reports the count of kernel NFS server bytes returned to receive and transmit (read and write) requests.", - unit="By", - ) - - -NFS_SERVER_NET_COUNT: Final = "nfs.server.net.count" -""" -Reports the count of kernel NFS server TCP segments and UDP datagrams handled -Instrument: counter -Unit: {record} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.nettcpcnt and svc_stat.netudpcnt. -""" - - -def create_nfs_server_net_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS server TCP segments and UDP datagrams handled""" - return meter.create_counter( - name=NFS_SERVER_NET_COUNT, - description="Reports the count of kernel NFS server TCP segments and UDP datagrams handled.", - unit="{record}", - ) - - -NFS_SERVER_NET_TCP_CONNECTION_ACCEPTED: Final = "nfs.server.net.tcp.connection.accepted" -""" -Reports the count of kernel NFS server TCP connections accepted -Instrument: counter -Unit: {connection} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.nettcpconn. -""" - - -def create_nfs_server_net_tcp_connection_accepted(meter: Meter) -> Counter: - """Reports the count of kernel NFS server TCP connections accepted""" - return meter.create_counter( - name=NFS_SERVER_NET_TCP_CONNECTION_ACCEPTED, - description="Reports the count of kernel NFS server TCP connections accepted.", - unit="{connection}", - ) - - -NFS_SERVER_OPERATION_COUNT: Final = "nfs.server.operation.count" -""" -Reports the count of kernel NFSv4+ server operations -Instrument: counter -Unit: {operation} -""" - - -def create_nfs_server_operation_count(meter: Meter) -> Counter: - """Reports the count of kernel NFSv4+ server operations""" - return meter.create_counter( - name=NFS_SERVER_OPERATION_COUNT, - description="Reports the count of kernel NFSv4+ server operations.", - unit="{operation}", - ) - - -NFS_SERVER_PROCEDURE_COUNT: Final = "nfs.server.procedure.count" -""" -Reports the count of kernel NFS server procedures -Instrument: counter -Unit: {procedure} -""" - - -def create_nfs_server_procedure_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS server procedures""" - return meter.create_counter( - name=NFS_SERVER_PROCEDURE_COUNT, - description="Reports the count of kernel NFS server procedures.", - unit="{procedure}", - ) - - -NFS_SERVER_REPCACHE_REQUESTS: Final = "nfs.server.repcache.requests" -""" -Reports the kernel NFS server reply cache request count by cache hit status -Instrument: counter -Unit: {request} -""" - - -def create_nfs_server_repcache_requests(meter: Meter) -> Counter: - """Reports the kernel NFS server reply cache request count by cache hit status""" - return meter.create_counter( - name=NFS_SERVER_REPCACHE_REQUESTS, - description="Reports the kernel NFS server reply cache request count by cache hit status.", - unit="{request}", - ) - - -NFS_SERVER_RPC_COUNT: Final = "nfs.server.rpc.count" -""" -Reports the count of kernel NFS server RPCs handled -Instrument: counter -Unit: {request} -Note: Linux: this metric is taken from the Linux kernel's svc_stat.rpccnt, the count of good RPCs. This metric can have -an error.type of "format", "auth", or "client" for svc_stat.badfmt, svc_stat.badauth, and svc_stat.badclnt. -""" - - -def create_nfs_server_rpc_count(meter: Meter) -> Counter: - """Reports the count of kernel NFS server RPCs handled""" - return meter.create_counter( - name=NFS_SERVER_RPC_COUNT, - description="Reports the count of kernel NFS server RPCs handled.", - unit="{request}", - ) - - -NFS_SERVER_THREAD_COUNT: Final = "nfs.server.thread.count" -""" -Reports the count of kernel NFS server available threads -Instrument: updowncounter -Unit: {thread} -Note: Linux: this metric is taken from the Linux kernel nfsd_th_cnt variable. -""" - - -def create_nfs_server_thread_count(meter: Meter) -> UpDownCounter: - """Reports the count of kernel NFS server available threads""" - return meter.create_up_down_counter( - name=NFS_SERVER_THREAD_COUNT, - description="Reports the count of kernel NFS server available threads.", - unit="{thread}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py deleted file mode 100644 index 6f36f4a48ba..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/openshift_metrics.py +++ /dev/null @@ -1,442 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Meter, UpDownCounter - -OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_HARD: Final = "openshift.clusterquota.cpu.limit.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_cpu_limit_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="{cpu}", - ) - - -OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_USED: Final = "openshift.clusterquota.cpu.limit.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_cpu_limit_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_CPU_LIMIT_USED, - description="The current observed total usage of the resource across all projects.", - unit="{cpu}", - ) - - -OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_HARD: Final = "openshift.clusterquota.cpu.request.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_cpu_request_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="{cpu}", - ) - - -OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_USED: Final = "openshift.clusterquota.cpu.request.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: {cpu} -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_cpu_request_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_CPU_REQUEST_USED, - description="The current observed total usage of the resource across all projects.", - unit="{cpu}", - ) - - -OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD: Final = "openshift.clusterquota.ephemeral_storage.limit.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_ephemeral_storage_limit_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_USED: Final = "openshift.clusterquota.ephemeral_storage.limit.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_ephemeral_storage_limit_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_LIMIT_USED, - description="The current observed total usage of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD: Final = "openshift.clusterquota.ephemeral_storage.request.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_ephemeral_storage_request_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_USED: Final = "openshift.clusterquota.ephemeral_storage.request.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_ephemeral_storage_request_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_EPHEMERAL_STORAGE_REQUEST_USED, - description="The current observed total usage of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_HARD: Final = "openshift.clusterquota.hugepage_count.request.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: {hugepage} -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_hugepage_count_request_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="{hugepage}", - ) - - -OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_USED: Final = "openshift.clusterquota.hugepage_count.request.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: {hugepage} -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_hugepage_count_request_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_HUGEPAGE_COUNT_REQUEST_USED, - description="The current observed total usage of the resource across all projects.", - unit="{hugepage}", - ) - - -OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_HARD: Final = "openshift.clusterquota.memory.limit.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_memory_limit_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_USED: Final = "openshift.clusterquota.memory.limit.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_memory_limit_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_MEMORY_LIMIT_USED, - description="The current observed total usage of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_HARD: Final = "openshift.clusterquota.memory.request.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_memory_request_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_USED: Final = "openshift.clusterquota.memory.request.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_memory_request_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_MEMORY_REQUEST_USED, - description="The current observed total usage of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_HARD: Final = "openshift.clusterquota.object_count.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: {object} -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_object_count_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="{object}", - ) - - -OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_USED: Final = "openshift.clusterquota.object_count.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: {object} -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). -""" - - -def create_openshift_clusterquota_object_count_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_OBJECT_COUNT_USED, - description="The current observed total usage of the resource across all projects.", - unit="{object}", - ) - - -OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD: Final = ( - "openshift.clusterquota.persistentvolumeclaim_count.hard" -) -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: {persistentvolumeclaim} -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_openshift_clusterquota_persistentvolumeclaim_count_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="{persistentvolumeclaim}", - ) - - -OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED: Final = ( - "openshift.clusterquota.persistentvolumeclaim_count.used" -) -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: {persistentvolumeclaim} -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_openshift_clusterquota_persistentvolumeclaim_count_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_PERSISTENTVOLUMECLAIM_COUNT_USED, - description="The current observed total usage of the resource across all projects.", - unit="{persistentvolumeclaim}", - ) - - -OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_HARD: Final = "openshift.clusterquota.storage.request.hard" -""" -The enforced hard limit of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Hard` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_openshift_clusterquota_storage_request_hard(meter: Meter) -> UpDownCounter: - """The enforced hard limit of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_HARD, - description="The enforced hard limit of the resource across all projects.", - unit="By", - ) - - -OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_USED: Final = "openshift.clusterquota.storage.request.used" -""" -The current observed total usage of the resource across all projects -Instrument: updowncounter -Unit: By -Note: This metric is retrieved from the `Status.Total.Used` field of the -[K8s ResourceQuotaStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#resourcequotastatus-v1-core) -of the -[ClusterResourceQuota](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/schedule_and_quota_apis/clusterresourcequota-quota-openshift-io-v1#status-total). - -The `k8s.storageclass.name` should be required when a resource quota is defined for a specific -storage class. -""" - - -def create_openshift_clusterquota_storage_request_used(meter: Meter) -> UpDownCounter: - """The current observed total usage of the resource across all projects""" - return meter.create_up_down_counter( - name=OPENSHIFT_CLUSTERQUOTA_STORAGE_REQUEST_USED, - description="The current observed total usage of the resource across all projects.", - unit="By", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py deleted file mode 100644 index 3acc2edc063..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/otel_metrics.py +++ /dev/null @@ -1,443 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Counter, Histogram, Meter, UpDownCounter - -OTEL_SDK_EXPORTER_LOG_EXPORTED: Final = "otel.sdk.exporter.log.exported" -""" -The number of log records for which the export has finished, either successful or failed -Instrument: counter -Unit: {log_record} -Note: For successful exports, `error.type` MUST NOT be set. For failed exports, `error.type` MUST contain the failure cause. -For exporters with partial success semantics (e.g. OTLP with `rejected_log_records`), rejected log records MUST count as failed and only non-rejected log records count as success. -If no rejection reason is available, `rejected` SHOULD be used as value for `error.type`. -If the exporter retries failed export attempts, the export operation is considered finished only after the final attempt has concluded. -Each log record MUST be counted exactly once per export operation: intermediate failed attempts that are followed by a retry MUST NOT increment the counter, -and `error.type` reflects the cause of the final attempt. -""" - - -def create_otel_sdk_exporter_log_exported(meter: Meter) -> Counter: - """The number of log records for which the export has finished, either successful or failed""" - return meter.create_counter( - name=OTEL_SDK_EXPORTER_LOG_EXPORTED, - description="The number of log records for which the export has finished, either successful or failed.", - unit="{log_record}", - ) - - -OTEL_SDK_EXPORTER_LOG_INFLIGHT: Final = "otel.sdk.exporter.log.inflight" -""" -The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed) -Instrument: updowncounter -Unit: {log_record} -Note: Log records are counted as inflight from when they are passed to the exporter until the export operation has concluded. -If the exporter retries failed export attempts, log records remain inflight across all retry attempts and any backoff between them. -""" - - -def create_otel_sdk_exporter_log_inflight(meter: Meter) -> UpDownCounter: - """The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)""" - return meter.create_up_down_counter( - name=OTEL_SDK_EXPORTER_LOG_INFLIGHT, - description="The number of log records which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).", - unit="{log_record}", - ) - - -OTEL_SDK_EXPORTER_METRIC_DATA_POINT_EXPORTED: Final = "otel.sdk.exporter.metric_data_point.exported" -""" -The number of metric data points for which the export has finished, either successful or failed -Instrument: counter -Unit: {data_point} -Note: For successful exports, `error.type` MUST NOT be set. For failed exports, `error.type` MUST contain the failure cause. -For exporters with partial success semantics (e.g. OTLP with `rejected_data_points`), rejected data points MUST count as failed and only non-rejected data points count as success. -If no rejection reason is available, `rejected` SHOULD be used as value for `error.type`. -If the exporter retries failed export attempts, the export operation is considered finished only after the final attempt has concluded. -Each metric data point MUST be counted exactly once per export operation: intermediate failed attempts that are followed by a retry MUST NOT increment the counter, -and `error.type` reflects the cause of the final attempt. -""" - - -def create_otel_sdk_exporter_metric_data_point_exported(meter: Meter) -> Counter: - """The number of metric data points for which the export has finished, either successful or failed""" - return meter.create_counter( - name=OTEL_SDK_EXPORTER_METRIC_DATA_POINT_EXPORTED, - description="The number of metric data points for which the export has finished, either successful or failed.", - unit="{data_point}", - ) - - -OTEL_SDK_EXPORTER_METRIC_DATA_POINT_INFLIGHT: Final = "otel.sdk.exporter.metric_data_point.inflight" -""" -The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed) -Instrument: updowncounter -Unit: {data_point} -Note: Metric data points are counted as inflight from when they are passed to the exporter until the export operation has concluded. -If the exporter retries failed export attempts, metric data points remain inflight across all retry attempts and any backoff between them. -""" - - -def create_otel_sdk_exporter_metric_data_point_inflight(meter: Meter) -> UpDownCounter: - """The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)""" - return meter.create_up_down_counter( - name=OTEL_SDK_EXPORTER_METRIC_DATA_POINT_INFLIGHT, - description="The number of metric data points which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).", - unit="{data_point}", - ) - - -OTEL_SDK_EXPORTER_OPERATION_DURATION: Final = "otel.sdk.exporter.operation.duration" -""" -The duration of exporting a batch of telemetry records -Instrument: histogram -Unit: s -Note: This metric defines successful operations using the full success definitions for [HTTP](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success-1) -and [gRPC](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.5.0/docs/specification.md#full-success). Anything else is defined as an unsuccessful operation. For successful -operations, `error.type` MUST NOT be set. For unsuccessful export operations, `error.type` MUST contain a relevant failure cause. -If the exporter retries failed export attempts, exactly one observation MUST be recorded per export operation, -covering the wall-clock duration from the start of the first attempt through the conclusion of the final attempt (including any backoff between attempts). -`error.type` reflects the cause of the final attempt. -""" - - -def create_otel_sdk_exporter_operation_duration(meter: Meter) -> Histogram: - """The duration of exporting a batch of telemetry records""" - return meter.create_histogram( - name=OTEL_SDK_EXPORTER_OPERATION_DURATION, - description="The duration of exporting a batch of telemetry records.", - unit="s", - ) - - -OTEL_SDK_EXPORTER_SPAN_EXPORTED: Final = "otel.sdk.exporter.span.exported" -""" -The number of spans for which the export has finished, either successful or failed -Instrument: counter -Unit: {span} -Note: For successful exports, `error.type` MUST NOT be set. For failed exports, `error.type` MUST contain the failure cause. -For exporters with partial success semantics (e.g. OTLP with `rejected_spans`), rejected spans MUST count as failed and only non-rejected spans count as success. -If no rejection reason is available, `rejected` SHOULD be used as value for `error.type`. -If the exporter retries failed export attempts, the export operation is considered finished only after the final attempt has concluded. -Each span MUST be counted exactly once per export operation: intermediate failed attempts that are followed by a retry MUST NOT increment the counter, -and `error.type` reflects the cause of the final attempt. -""" - - -def create_otel_sdk_exporter_span_exported(meter: Meter) -> Counter: - """The number of spans for which the export has finished, either successful or failed""" - return meter.create_counter( - name=OTEL_SDK_EXPORTER_SPAN_EXPORTED, - description="The number of spans for which the export has finished, either successful or failed.", - unit="{span}", - ) - - -OTEL_SDK_EXPORTER_SPAN_EXPORTED_COUNT: Final = "otel.sdk.exporter.span.exported.count" -""" -Deprecated: Replaced by `otel.sdk.exporter.span.exported`. -""" - - -def create_otel_sdk_exporter_span_exported_count(meter: Meter) -> UpDownCounter: - """Deprecated, use `otel.sdk.exporter.span.exported` instead""" - return meter.create_up_down_counter( - name=OTEL_SDK_EXPORTER_SPAN_EXPORTED_COUNT, - description="Deprecated, use `otel.sdk.exporter.span.exported` instead.", - unit="{span}", - ) - - -OTEL_SDK_EXPORTER_SPAN_INFLIGHT: Final = "otel.sdk.exporter.span.inflight" -""" -The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed) -Instrument: updowncounter -Unit: {span} -Note: Spans are counted as inflight from when they are passed to the exporter until the export operation has concluded. -If the exporter retries failed export attempts, spans remain inflight across all retry attempts and any backoff between them. -""" - - -def create_otel_sdk_exporter_span_inflight(meter: Meter) -> UpDownCounter: - """The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed)""" - return meter.create_up_down_counter( - name=OTEL_SDK_EXPORTER_SPAN_INFLIGHT, - description="The number of spans which were passed to the exporter, but that have not been exported yet (neither successful, nor failed).", - unit="{span}", - ) - - -OTEL_SDK_EXPORTER_SPAN_INFLIGHT_COUNT: Final = "otel.sdk.exporter.span.inflight.count" -""" -Deprecated: Replaced by `otel.sdk.exporter.span.inflight`. -""" - - -def create_otel_sdk_exporter_span_inflight_count(meter: Meter) -> UpDownCounter: - """Deprecated, use `otel.sdk.exporter.span.inflight` instead""" - return meter.create_up_down_counter( - name=OTEL_SDK_EXPORTER_SPAN_INFLIGHT_COUNT, - description="Deprecated, use `otel.sdk.exporter.span.inflight` instead.", - unit="{span}", - ) - - -OTEL_SDK_LOG_CREATED: Final = "otel.sdk.log.created" -""" -The number of logs submitted to enabled SDK Loggers -Instrument: counter -Unit: {log_record} -""" - - -def create_otel_sdk_log_created(meter: Meter) -> Counter: - """The number of logs submitted to enabled SDK Loggers""" - return meter.create_counter( - name=OTEL_SDK_LOG_CREATED, - description="The number of logs submitted to enabled SDK Loggers.", - unit="{log_record}", - ) - - -OTEL_SDK_METRIC_READER_COLLECTION_DURATION: Final = "otel.sdk.metric_reader.collection.duration" -""" -The duration of the collect operation of the metric reader -Instrument: histogram -Unit: s -Note: For successful collections, `error.type` MUST NOT be set. For failed collections, `error.type` SHOULD contain the failure cause. -It can happen that metrics collection is successful for some MetricProducers, while others fail. In that case `error.type` SHOULD be set to any of the failure causes. -""" - - -def create_otel_sdk_metric_reader_collection_duration(meter: Meter) -> Histogram: - """The duration of the collect operation of the metric reader""" - return meter.create_histogram( - name=OTEL_SDK_METRIC_READER_COLLECTION_DURATION, - description="The duration of the collect operation of the metric reader.", - unit="s", - ) - - -OTEL_SDK_PROCESSOR_LOG_PROCESSED: Final = "otel.sdk.processor.log.processed" -""" -The number of log records for which the processing has finished, either successful or failed -Instrument: counter -Unit: {log_record} -Note: For successful processing, `error.type` MUST NOT be set. For failed processing, `error.type` MUST contain the failure cause. -SDK Batching Log Record Processors MUST use `queue_full` as the value of `error.type` for log records dropped due to a full queue. -If a processor reports a log record dropped because it has already been shut down, `error.type` MUST be `already_shutdown`. -Whether and when a processor drops such log records is governed by the SDK specification, not by this metric. -For the SDK Simple and Batching Log Record Processors, a log record MUST be counted as successfully processed at the point the -processor invokes the export operation. For batching processors, all log records in the batch passed to the exporter are counted -at that point; log records accepted into the processor's queue but not yet passed to the exporter have not been processed. -Implementations MUST NOT delay this count until the export operation concludes, and the outcome of the export operation, -including an immediate failure of the invocation itself, MUST NOT affect this metric. -Export outcomes are reported by `otel.sdk.exporter.log.exported`. -""" - - -def create_otel_sdk_processor_log_processed(meter: Meter) -> Counter: - """The number of log records for which the processing has finished, either successful or failed""" - return meter.create_counter( - name=OTEL_SDK_PROCESSOR_LOG_PROCESSED, - description="The number of log records for which the processing has finished, either successful or failed.", - unit="{log_record}", - ) - - -OTEL_SDK_PROCESSOR_LOG_QUEUE_CAPACITY: Final = "otel.sdk.processor.log.queue.capacity" -""" -The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold -Instrument: updowncounter -Unit: {log_record} -Note: Only applies to Log Record processors which use a queue, e.g. the SDK Batching Log Record Processor. -""" - - -def create_otel_sdk_processor_log_queue_capacity(meter: Meter) -> UpDownCounter: - """The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold""" - return meter.create_up_down_counter( - name=OTEL_SDK_PROCESSOR_LOG_QUEUE_CAPACITY, - description="The maximum number of log records the queue of a given instance of an SDK Log Record processor can hold.", - unit="{log_record}", - ) - - -OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE: Final = "otel.sdk.processor.log.queue.size" -""" -The number of log records in the queue of a given instance of an SDK log processor -Instrument: updowncounter -Unit: {log_record} -Note: Only applies to log record processors which use a queue, e.g. the SDK Batching Log Record Processor. -""" - - -def create_otel_sdk_processor_log_queue_size(meter: Meter) -> UpDownCounter: - """The number of log records in the queue of a given instance of an SDK log processor""" - return meter.create_up_down_counter( - name=OTEL_SDK_PROCESSOR_LOG_QUEUE_SIZE, - description="The number of log records in the queue of a given instance of an SDK log processor.", - unit="{log_record}", - ) - - -OTEL_SDK_PROCESSOR_SPAN_PROCESSED: Final = "otel.sdk.processor.span.processed" -""" -The number of spans for which the processing has finished, either successful or failed -Instrument: counter -Unit: {span} -Note: For successful processing, `error.type` MUST NOT be set. For failed processing, `error.type` MUST contain the failure cause. -SDK Batching Span Processors MUST use `queue_full` as the value of `error.type` for spans dropped due to a full queue. -If a processor reports a span dropped because it has already been shut down, `error.type` MUST be `already_shutdown`. -Whether and when a processor drops such spans is governed by the SDK specification, not by this metric. -For the SDK Simple and Batching Span Processors, a span MUST be counted as successfully processed at the point the processor -invokes the export operation. For batching processors, all spans in the batch passed to the exporter are counted at that point; -spans accepted into the processor's queue but not yet passed to the exporter have not been processed. -Implementations MUST NOT delay this count until the export operation concludes, and the outcome of the export operation, -including an immediate failure of the invocation itself, MUST NOT affect this metric. -Export outcomes are reported by `otel.sdk.exporter.span.exported`. -""" - - -def create_otel_sdk_processor_span_processed(meter: Meter) -> Counter: - """The number of spans for which the processing has finished, either successful or failed""" - return meter.create_counter( - name=OTEL_SDK_PROCESSOR_SPAN_PROCESSED, - description="The number of spans for which the processing has finished, either successful or failed.", - unit="{span}", - ) - - -OTEL_SDK_PROCESSOR_SPAN_PROCESSED_COUNT: Final = "otel.sdk.processor.span.processed.count" -""" -Deprecated: Replaced by `otel.sdk.processor.span.processed`. -""" - - -def create_otel_sdk_processor_span_processed_count(meter: Meter) -> UpDownCounter: - """Deprecated, use `otel.sdk.processor.span.processed` instead""" - return meter.create_up_down_counter( - name=OTEL_SDK_PROCESSOR_SPAN_PROCESSED_COUNT, - description="Deprecated, use `otel.sdk.processor.span.processed` instead.", - unit="{span}", - ) - - -OTEL_SDK_PROCESSOR_SPAN_QUEUE_CAPACITY: Final = "otel.sdk.processor.span.queue.capacity" -""" -The maximum number of spans the queue of a given instance of an SDK span processor can hold -Instrument: updowncounter -Unit: {span} -Note: Only applies to span processors which use a queue, e.g. the SDK Batching Span Processor. -""" - - -def create_otel_sdk_processor_span_queue_capacity(meter: Meter) -> UpDownCounter: - """The maximum number of spans the queue of a given instance of an SDK span processor can hold""" - return meter.create_up_down_counter( - name=OTEL_SDK_PROCESSOR_SPAN_QUEUE_CAPACITY, - description="The maximum number of spans the queue of a given instance of an SDK span processor can hold.", - unit="{span}", - ) - - -OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE: Final = "otel.sdk.processor.span.queue.size" -""" -The number of spans in the queue of a given instance of an SDK span processor -Instrument: updowncounter -Unit: {span} -Note: Only applies to span processors which use a queue, e.g. the SDK Batching Span Processor. -""" - - -def create_otel_sdk_processor_span_queue_size(meter: Meter) -> UpDownCounter: - """The number of spans in the queue of a given instance of an SDK span processor""" - return meter.create_up_down_counter( - name=OTEL_SDK_PROCESSOR_SPAN_QUEUE_SIZE, - description="The number of spans in the queue of a given instance of an SDK span processor.", - unit="{span}", - ) - - -OTEL_SDK_SPAN_ENDED: Final = "otel.sdk.span.ended" -""" -Deprecated: Obsoleted. -""" - - -def create_otel_sdk_span_ended(meter: Meter) -> Counter: - """Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value""" - return meter.create_counter( - name=OTEL_SDK_SPAN_ENDED, - description="Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value.", - unit="{span}", - ) - - -OTEL_SDK_SPAN_ENDED_COUNT: Final = "otel.sdk.span.ended.count" -""" -Deprecated: Obsoleted. -""" - - -def create_otel_sdk_span_ended_count(meter: Meter) -> Counter: - """Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value""" - return meter.create_counter( - name=OTEL_SDK_SPAN_ENDED_COUNT, - description="Use `otel.sdk.span.started` minus `otel.sdk.span.live` to derive this value.", - unit="{span}", - ) - - -OTEL_SDK_SPAN_LIVE: Final = "otel.sdk.span.live" -""" -The number of created spans with `recording=true` for which the end operation has not been called yet -Instrument: updowncounter -Unit: {span} -Note: Non-recording spans are not counted, hence `otel.span.sampling_result` can only take values `RECORD_ONLY` and `RECORD_AND_SAMPLE`, not `DROP`. -""" - - -def create_otel_sdk_span_live(meter: Meter) -> UpDownCounter: - """The number of created spans with `recording=true` for which the end operation has not been called yet""" - return meter.create_up_down_counter( - name=OTEL_SDK_SPAN_LIVE, - description="The number of created spans with `recording=true` for which the end operation has not been called yet.", - unit="{span}", - ) - - -OTEL_SDK_SPAN_LIVE_COUNT: Final = "otel.sdk.span.live.count" -""" -Deprecated: Replaced by `otel.sdk.span.live`. -""" - - -def create_otel_sdk_span_live_count(meter: Meter) -> UpDownCounter: - """Deprecated, use `otel.sdk.span.live` instead""" - return meter.create_up_down_counter( - name=OTEL_SDK_SPAN_LIVE_COUNT, - description="Deprecated, use `otel.sdk.span.live` instead.", - unit="{span}", - ) - - -OTEL_SDK_SPAN_STARTED: Final = "otel.sdk.span.started" -""" -The number of created spans -Instrument: counter -Unit: {span} -Note: Implementations MUST record this metric for all spans, even for non-recording ones. -""" - - -def create_otel_sdk_span_started(meter: Meter) -> Counter: - """The number of created spans""" - return meter.create_counter( - name=OTEL_SDK_SPAN_STARTED, - description="The number of created spans.", - unit="{span}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py deleted file mode 100644 index bf82d7bf6ee..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/process_metrics.py +++ /dev/null @@ -1,286 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable, Generator, Iterable, Sequence -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter - -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -PROCESS_CONTEXT_SWITCHES: Final = "process.context_switches" -""" -Number of times the process has been context switched -Instrument: counter -Unit: {context_switch} -""" - - -def create_process_context_switches(meter: Meter) -> Counter: - """Number of times the process has been context switched""" - return meter.create_counter( - name=PROCESS_CONTEXT_SWITCHES, - description="Number of times the process has been context switched.", - unit="{context_switch}", - ) - - -PROCESS_CPU_TIME: Final = "process.cpu.time" -""" -Total CPU seconds broken down by different CPU modes -Instrument: counter -Unit: s -""" - - -def create_process_cpu_time(meter: Meter) -> Counter: - """Total CPU seconds broken down by different CPU modes""" - return meter.create_counter( - name=PROCESS_CPU_TIME, - description="Total CPU seconds broken down by different CPU modes.", - unit="s", - ) - - -PROCESS_CPU_UTILIZATION: Final = "process.cpu.utilization" -""" -Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process -Instrument: gauge -Unit: 1 -""" - - -def create_process_cpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process""" - return meter.create_observable_gauge( - name=PROCESS_CPU_UTILIZATION, - callbacks=callbacks, - description="Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process.", - unit="1", - ) - - -PROCESS_DISK_IO: Final = "process.disk.io" -""" -Disk bytes transferred -Instrument: counter -Unit: By -""" - - -def create_process_disk_io(meter: Meter) -> Counter: - """Disk bytes transferred""" - return meter.create_counter( - name=PROCESS_DISK_IO, - description="Disk bytes transferred.", - unit="By", - ) - - -PROCESS_DISK_OPERATIONS: Final = "process.disk.operations" -""" -Number of disk operations performed by the process -Instrument: counter -Unit: {operation} -""" - - -def create_process_disk_operations(meter: Meter) -> Counter: - """Number of disk operations performed by the process""" - return meter.create_counter( - name=PROCESS_DISK_OPERATIONS, - description="Number of disk operations performed by the process.", - unit="{operation}", - ) - - -PROCESS_MEMORY_USAGE: Final = "process.memory.usage" -""" -The amount of physical memory in use -Instrument: updowncounter -Unit: By -""" - - -def create_process_memory_usage(meter: Meter) -> UpDownCounter: - """The amount of physical memory in use""" - return meter.create_up_down_counter( - name=PROCESS_MEMORY_USAGE, - description="The amount of physical memory in use.", - unit="By", - ) - - -PROCESS_MEMORY_UTILIZATION: Final = "process.memory.utilization" -""" -Percentage of total physical memory that is used by the process -Instrument: gauge -Unit: 1 -""" - - -def create_process_memory_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Percentage of total physical memory that is used by the process""" - return meter.create_observable_gauge( - name=PROCESS_MEMORY_UTILIZATION, - callbacks=callbacks, - description="Percentage of total physical memory that is used by the process.", - unit="1", - ) - - -PROCESS_MEMORY_VIRTUAL: Final = "process.memory.virtual" -""" -The amount of committed virtual memory -Instrument: updowncounter -Unit: By -""" - - -def create_process_memory_virtual(meter: Meter) -> UpDownCounter: - """The amount of committed virtual memory""" - return meter.create_up_down_counter( - name=PROCESS_MEMORY_VIRTUAL, - description="The amount of committed virtual memory.", - unit="By", - ) - - -PROCESS_NETWORK_IO: Final = "process.network.io" -""" -Network bytes transferred -Instrument: counter -Unit: By -""" - - -def create_process_network_io(meter: Meter) -> Counter: - """Network bytes transferred""" - return meter.create_counter( - name=PROCESS_NETWORK_IO, - description="Network bytes transferred.", - unit="By", - ) - - -PROCESS_OPEN_FILE_DESCRIPTOR_COUNT: Final = "process.open_file_descriptor.count" -""" -Deprecated: Replaced by `process.unix.file_descriptor.count`. -""" - - -def create_process_open_file_descriptor_count(meter: Meter) -> UpDownCounter: - """Deprecated, use `process.unix.file_descriptor.count` instead""" - return meter.create_up_down_counter( - name=PROCESS_OPEN_FILE_DESCRIPTOR_COUNT, - description="Deprecated, use `process.unix.file_descriptor.count` instead.", - unit="{file_descriptor}", - ) - - -PROCESS_PAGING_FAULTS: Final = "process.paging.faults" -""" -Number of page faults the process has made -Instrument: counter -Unit: {fault} -""" - - -def create_process_paging_faults(meter: Meter) -> Counter: - """Number of page faults the process has made""" - return meter.create_counter( - name=PROCESS_PAGING_FAULTS, - description="Number of page faults the process has made.", - unit="{fault}", - ) - - -PROCESS_SIGNALS_PENDING: Final = "process.signals_pending" -""" -Number of pending signals for the process -Instrument: updowncounter -Unit: {signal} -""" - - -def create_process_signals_pending(meter: Meter) -> UpDownCounter: - """Number of pending signals for the process""" - return meter.create_up_down_counter( - name=PROCESS_SIGNALS_PENDING, - description="Number of pending signals for the process.", - unit="{signal}", - ) - - -PROCESS_THREAD_COUNT: Final = "process.thread.count" -""" -Process threads count -Instrument: updowncounter -Unit: {thread} -""" - - -def create_process_thread_count(meter: Meter) -> UpDownCounter: - """Process threads count""" - return meter.create_up_down_counter( - name=PROCESS_THREAD_COUNT, - description="Process threads count.", - unit="{thread}", - ) - - -PROCESS_UNIX_FILE_DESCRIPTOR_COUNT: Final = "process.unix.file_descriptor.count" -""" -Number of UNIX file descriptors in use by the process -Instrument: updowncounter -Unit: {file_descriptor} -""" - - -def create_process_unix_file_descriptor_count(meter: Meter) -> UpDownCounter: - """Number of UNIX file descriptors in use by the process""" - return meter.create_up_down_counter( - name=PROCESS_UNIX_FILE_DESCRIPTOR_COUNT, - description="Number of UNIX file descriptors in use by the process.", - unit="{file_descriptor}", - ) - - -PROCESS_UPTIME: Final = "process.uptime" -""" -The time the process has been running -Instrument: gauge -Unit: s -Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. -The actual accuracy would depend on the instrumentation and operating system. -""" - - -def create_process_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The time the process has been running""" - return meter.create_observable_gauge( - name=PROCESS_UPTIME, - callbacks=callbacks, - description="The time the process has been running.", - unit="s", - ) - - -PROCESS_WINDOWS_HANDLE_COUNT: Final = "process.windows.handle.count" -""" -Number of handles held by the process -Instrument: updowncounter -Unit: {handle} -""" - - -def create_process_windows_handle_count(meter: Meter) -> UpDownCounter: - """Number of handles held by the process""" - return meter.create_up_down_counter( - name=PROCESS_WINDOWS_HANDLE_COUNT, - description="Number of handles held by the process.", - unit="{handle}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py deleted file mode 100644 index b2c5dfe8c46..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/rpc_metrics.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import Histogram, Meter - -RPC_CLIENT_CALL_DURATION: Final = "rpc.client.call.duration" -""" -Measures the duration of an outgoing Remote Procedure Call (RPC) -Instrument: histogram -Unit: s -Note: When this metric is reported alongside an RPC client span, the metric value -SHOULD be the same as the RPC client span duration. -""" - - -def create_rpc_client_call_duration(meter: Meter) -> Histogram: - """Measures the duration of an outgoing Remote Procedure Call (RPC)""" - return meter.create_histogram( - name=RPC_CLIENT_CALL_DURATION, - description="Measures the duration of an outgoing Remote Procedure Call (RPC).", - unit="s", - ) - - -RPC_CLIENT_DURATION: Final = "rpc.client.duration" -""" -Deprecated: Replaced by `rpc.client.call.duration` with unit `s`. -""" - - -def create_rpc_client_duration(meter: Meter) -> Histogram: - """Deprecated, use `rpc.client.call.duration` instead. Note: the unit also changed from `ms` to `s`""" - return meter.create_histogram( - name=RPC_CLIENT_DURATION, - description="Deprecated, use `rpc.client.call.duration` instead. Note: the unit also changed from `ms` to `s`.", - unit="ms", - ) - - -RPC_CLIENT_REQUEST_SIZE: Final = "rpc.client.request.size" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_client_request_size(meter: Meter) -> Histogram: - """Measures the size of RPC request messages (uncompressed)""" - return meter.create_histogram( - name=RPC_CLIENT_REQUEST_SIZE, - description="Measures the size of RPC request messages (uncompressed).", - unit="By", - ) - - -RPC_CLIENT_REQUESTS_PER_RPC: Final = "rpc.client.requests_per_rpc" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_client_requests_per_rpc(meter: Meter) -> Histogram: - """Measures the number of messages received per RPC""" - return meter.create_histogram( - name=RPC_CLIENT_REQUESTS_PER_RPC, - description="Measures the number of messages received per RPC.", - unit="{count}", - ) - - -RPC_CLIENT_RESPONSE_SIZE: Final = "rpc.client.response.size" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_client_response_size(meter: Meter) -> Histogram: - """Measures the size of RPC response messages (uncompressed)""" - return meter.create_histogram( - name=RPC_CLIENT_RESPONSE_SIZE, - description="Measures the size of RPC response messages (uncompressed).", - unit="By", - ) - - -RPC_CLIENT_RESPONSES_PER_RPC: Final = "rpc.client.responses_per_rpc" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_client_responses_per_rpc(meter: Meter) -> Histogram: - """Measures the number of messages sent per RPC""" - return meter.create_histogram( - name=RPC_CLIENT_RESPONSES_PER_RPC, - description="Measures the number of messages sent per RPC.", - unit="{count}", - ) - - -RPC_SERVER_CALL_DURATION: Final = "rpc.server.call.duration" -""" -Measures the duration of an incoming Remote Procedure Call (RPC) -Instrument: histogram -Unit: s -Note: When this metric is reported alongside an RPC server span, the metric value -SHOULD be the same as the RPC server span duration. -""" - - -def create_rpc_server_call_duration(meter: Meter) -> Histogram: - """Measures the duration of an incoming Remote Procedure Call (RPC)""" - return meter.create_histogram( - name=RPC_SERVER_CALL_DURATION, - description="Measures the duration of an incoming Remote Procedure Call (RPC).", - unit="s", - ) - - -RPC_SERVER_DURATION: Final = "rpc.server.duration" -""" -Deprecated: Replaced by `rpc.server.call.duration` with unit `s`. -""" - - -def create_rpc_server_duration(meter: Meter) -> Histogram: - """Deprecated, use `rpc.server.call.duration` instead. Note: the unit also changed from `ms` to `s`""" - return meter.create_histogram( - name=RPC_SERVER_DURATION, - description="Deprecated, use `rpc.server.call.duration` instead. Note: the unit also changed from `ms` to `s`.", - unit="ms", - ) - - -RPC_SERVER_REQUEST_SIZE: Final = "rpc.server.request.size" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_server_request_size(meter: Meter) -> Histogram: - """Measures the size of RPC request messages (uncompressed)""" - return meter.create_histogram( - name=RPC_SERVER_REQUEST_SIZE, - description="Measures the size of RPC request messages (uncompressed).", - unit="By", - ) - - -RPC_SERVER_REQUESTS_PER_RPC: Final = "rpc.server.requests_per_rpc" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_server_requests_per_rpc(meter: Meter) -> Histogram: - """Measures the number of messages received per RPC""" - return meter.create_histogram( - name=RPC_SERVER_REQUESTS_PER_RPC, - description="Measures the number of messages received per RPC.", - unit="{count}", - ) - - -RPC_SERVER_RESPONSE_SIZE: Final = "rpc.server.response.size" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_server_response_size(meter: Meter) -> Histogram: - """Measures the size of RPC response messages (uncompressed)""" - return meter.create_histogram( - name=RPC_SERVER_RESPONSE_SIZE, - description="Measures the size of RPC response messages (uncompressed).", - unit="By", - ) - - -RPC_SERVER_RESPONSES_PER_RPC: Final = "rpc.server.responses_per_rpc" -""" -Deprecated: Removed, no replacement at this time. -""" - - -def create_rpc_server_responses_per_rpc(meter: Meter) -> Histogram: - """Measures the number of messages sent per RPC""" - return meter.create_histogram( - name=RPC_SERVER_RESPONSES_PER_RPC, - description="Measures the number of messages sent per RPC.", - unit="{count}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py deleted file mode 100644 index f899111910e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/system_metrics.py +++ /dev/null @@ -1,835 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable, Generator, Iterable, Sequence -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Counter, Meter, ObservableGauge, Observation, UpDownCounter - -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -SYSTEM_CPU_FREQUENCY: Final = "system.cpu.frequency" -""" -Operating frequency of the logical CPU in Hertz -Instrument: gauge -Unit: Hz -""" - - -def create_system_cpu_frequency(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Operating frequency of the logical CPU in Hertz""" - return meter.create_observable_gauge( - name=SYSTEM_CPU_FREQUENCY, - callbacks=callbacks, - description="Operating frequency of the logical CPU in Hertz.", - unit="Hz", - ) - - -SYSTEM_CPU_LOGICAL_COUNT: Final = "system.cpu.logical.count" -""" -Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking -Instrument: updowncounter -Unit: {cpu} -Note: Calculated by multiplying the number of sockets by the number of cores per socket, and then by the number of threads per core. -""" - - -def create_system_cpu_logical_count(meter: Meter) -> UpDownCounter: - """Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking""" - return meter.create_up_down_counter( - name=SYSTEM_CPU_LOGICAL_COUNT, - description="Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking.", - unit="{cpu}", - ) - - -SYSTEM_CPU_PHYSICAL_COUNT: Final = "system.cpu.physical.count" -""" -Reports the number of actual physical processor cores on the hardware -Instrument: updowncounter -Unit: {cpu} -Note: Calculated by multiplying the number of sockets by the number of cores per socket. -""" - - -def create_system_cpu_physical_count(meter: Meter) -> UpDownCounter: - """Reports the number of actual physical processor cores on the hardware""" - return meter.create_up_down_counter( - name=SYSTEM_CPU_PHYSICAL_COUNT, - description="Reports the number of actual physical processor cores on the hardware.", - unit="{cpu}", - ) - - -SYSTEM_CPU_TIME: Final = "system.cpu.time" -""" -Seconds each logical CPU spent on each mode -Instrument: counter -Unit: s -""" - - -def create_system_cpu_time(meter: Meter) -> Counter: - """Seconds each logical CPU spent on each mode""" - return meter.create_counter( - name=SYSTEM_CPU_TIME, - description="Seconds each logical CPU spent on each mode.", - unit="s", - ) - - -SYSTEM_CPU_UTILIZATION: Final = "system.cpu.utilization" -""" -For each logical CPU, the utilization is calculated as the change in cumulative CPU time (cpu.time) over a measurement interval, divided by the elapsed time -Instrument: gauge -Unit: 1 -""" - - -def create_system_cpu_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """For each logical CPU, the utilization is calculated as the change in cumulative CPU time (cpu.time) over a measurement interval, divided by the elapsed time""" - return meter.create_observable_gauge( - name=SYSTEM_CPU_UTILIZATION, - callbacks=callbacks, - description="For each logical CPU, the utilization is calculated as the change in cumulative CPU time (cpu.time) over a measurement interval, divided by the elapsed time.", - unit="1", - ) - - -SYSTEM_DISK_IO: Final = "system.disk.io" -""" -Disk bytes transferred -Instrument: counter -Unit: By -""" - - -def create_system_disk_io(meter: Meter) -> Counter: - """Disk bytes transferred""" - return meter.create_counter( - name=SYSTEM_DISK_IO, - description="Disk bytes transferred.", - unit="By", - ) - - -SYSTEM_DISK_IO_TIME: Final = "system.disk.io_time" -""" -Time disk spent activated -Instrument: counter -Unit: s -Note: The real elapsed time ("wall clock") used in the I/O path (time from operations running in parallel are not counted). Measured as: - -- Linux: Field 13 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) -- Windows: The complement of - ["Disk\\% Idle Time"](https://learn.microsoft.com/archive/blogs/askcore/windows-performance-monitor-disk-counters-explained#windows-performance-monitor-disk-counters-explained) - performance counter: `uptime * (100 - "Disk\\% Idle Time") / 100`. -""" - - -def create_system_disk_io_time(meter: Meter) -> Counter: - """Time disk spent activated""" - return meter.create_counter( - name=SYSTEM_DISK_IO_TIME, - description="Time disk spent activated.", - unit="s", - ) - - -SYSTEM_DISK_LIMIT: Final = "system.disk.limit" -""" -The total storage capacity of the disk -Instrument: updowncounter -Unit: By -""" - - -def create_system_disk_limit(meter: Meter) -> UpDownCounter: - """The total storage capacity of the disk""" - return meter.create_up_down_counter( - name=SYSTEM_DISK_LIMIT, - description="The total storage capacity of the disk.", - unit="By", - ) - - -SYSTEM_DISK_MERGED: Final = "system.disk.merged" -""" -The number of disk reads/writes merged into single physical disk access operations -Instrument: counter -Unit: {operation} -""" - - -def create_system_disk_merged(meter: Meter) -> Counter: - """The number of disk reads/writes merged into single physical disk access operations""" - return meter.create_counter( - name=SYSTEM_DISK_MERGED, - description="The number of disk reads/writes merged into single physical disk access operations.", - unit="{operation}", - ) - - -SYSTEM_DISK_OPERATION_TIME: Final = "system.disk.operation_time" -""" -Sum of the time each operation took to complete -Instrument: counter -Unit: s -Note: Because it is the sum of time each request took, parallel-issued requests each contribute to make the count grow. Measured as: - -- Linux: Fields 7 & 11 from [procfs-diskstats](https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats) -- Windows: "Avg. Disk sec/Read" perf counter multiplied by "Disk Reads/sec" perf counter (similar for Writes). -""" - - -def create_system_disk_operation_time(meter: Meter) -> Counter: - """Sum of the time each operation took to complete""" - return meter.create_counter( - name=SYSTEM_DISK_OPERATION_TIME, - description="Sum of the time each operation took to complete.", - unit="s", - ) - - -SYSTEM_DISK_OPERATIONS: Final = "system.disk.operations" -""" -Disk operations count -Instrument: counter -Unit: {operation} -""" - - -def create_system_disk_operations(meter: Meter) -> Counter: - """Disk operations count""" - return meter.create_counter( - name=SYSTEM_DISK_OPERATIONS, - description="Disk operations count.", - unit="{operation}", - ) - - -SYSTEM_FILESYSTEM_LIMIT: Final = "system.filesystem.limit" -""" -The total storage capacity of the filesystem -Instrument: updowncounter -Unit: By -""" - - -def create_system_filesystem_limit(meter: Meter) -> UpDownCounter: - """The total storage capacity of the filesystem""" - return meter.create_up_down_counter( - name=SYSTEM_FILESYSTEM_LIMIT, - description="The total storage capacity of the filesystem.", - unit="By", - ) - - -SYSTEM_FILESYSTEM_LOCK_COUNT: Final = "system.filesystem.lock.count" -""" -Filesystem lock counts -Instrument: updowncounter -Unit: {lock} -""" - - -def create_system_filesystem_lock_count(meter: Meter) -> UpDownCounter: - """Filesystem lock counts""" - return meter.create_up_down_counter( - name=SYSTEM_FILESYSTEM_LOCK_COUNT, - description="Filesystem lock counts.", - unit="{lock}", - ) - - -SYSTEM_FILESYSTEM_USAGE: Final = "system.filesystem.usage" -""" -Reports a filesystem's space usage across different states -Instrument: updowncounter -Unit: By -Note: The sum of all `system.filesystem.usage` values over the different `system.filesystem.state` attributes -SHOULD equal the total storage capacity of the filesystem, that is `system.filesystem.limit`. -""" - - -def create_system_filesystem_usage(meter: Meter) -> UpDownCounter: - """Reports a filesystem's space usage across different states""" - return meter.create_up_down_counter( - name=SYSTEM_FILESYSTEM_USAGE, - description="Reports a filesystem's space usage across different states.", - unit="By", - ) - - -SYSTEM_FILESYSTEM_UTILIZATION: Final = "system.filesystem.utilization" -""" -Fraction of filesystem bytes used -Instrument: gauge -Unit: 1 -""" - - -def create_system_filesystem_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Fraction of filesystem bytes used""" - return meter.create_observable_gauge( - name=SYSTEM_FILESYSTEM_UTILIZATION, - callbacks=callbacks, - description="Fraction of filesystem bytes used.", - unit="1", - ) - - -SYSTEM_LINUX_MEMORY_AVAILABLE: Final = "system.linux.memory.available" -""" -Deprecated: Replaced by `system.memory.linux.available`. -""" - - -def create_system_linux_memory_available(meter: Meter) -> Counter: - """The number of packets transferred""" - return meter.create_counter( - name=SYSTEM_LINUX_MEMORY_AVAILABLE, - description="The number of packets transferred.", - unit="{packet}", - ) - - -SYSTEM_LINUX_MEMORY_SLAB_USAGE: Final = "system.linux.memory.slab.usage" -""" -Deprecated: Replaced by `system.memory.linux.slab.usage`. -""" - - -def create_system_linux_memory_slab_usage(meter: Meter) -> Counter: - """The number of packets transferred""" - return meter.create_counter( - name=SYSTEM_LINUX_MEMORY_SLAB_USAGE, - description="The number of packets transferred.", - unit="{packet}", - ) - - -SYSTEM_MEMORY_LIMIT: Final = "system.memory.limit" -""" -Total virtual memory available in the system -Instrument: updowncounter -Unit: By -""" - - -def create_system_memory_limit(meter: Meter) -> UpDownCounter: - """Total virtual memory available in the system""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LIMIT, - description="Total virtual memory available in the system.", - unit="By", - ) - - -SYSTEM_MEMORY_LINUX_AVAILABLE: Final = "system.memory.linux.available" -""" -An estimate of how much memory is available for starting new applications, without causing swapping -Instrument: updowncounter -Unit: By -Note: This is an alternative to `system.memory.usage` metric with `state=free`. -Linux starting from 3.14 exports "available" memory. It takes "free" memory as a baseline, and then factors in kernel-specific values. -This is supposed to be more accurate than just "free" memory. -For reference, see the calculations [here](https://superuser.com/a/980821). -See also `MemAvailable` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html). -""" - - -def create_system_memory_linux_available(meter: Meter) -> UpDownCounter: - """An estimate of how much memory is available for starting new applications, without causing swapping""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_AVAILABLE, - description="An estimate of how much memory is available for starting new applications, without causing swapping.", - unit="By", - ) - - -SYSTEM_MEMORY_LINUX_HUGEPAGES_LIMIT: Final = "system.memory.linux.hugepages.limit" -""" -Total number of hugepages available -Instrument: updowncounter -Unit: {page} -""" - - -def create_system_memory_linux_hugepages_limit(meter: Meter) -> UpDownCounter: - """Total number of hugepages available""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_HUGEPAGES_LIMIT, - description="Total number of hugepages available.", - unit="{page}", - ) - - -SYSTEM_MEMORY_LINUX_HUGEPAGES_PAGE_SIZE: Final = "system.memory.linux.hugepages.page_size" -""" -System hugepage size in bytes -Instrument: updowncounter -Unit: By -""" - - -def create_system_memory_linux_hugepages_page_size(meter: Meter) -> UpDownCounter: - """System hugepage size in bytes""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_HUGEPAGES_PAGE_SIZE, - description="System hugepage size in bytes.", - unit="By", - ) - - -SYSTEM_MEMORY_LINUX_HUGEPAGES_RESERVED: Final = "system.memory.linux.hugepages.reserved" -""" -Number of reserved hugepages -Instrument: updowncounter -Unit: {page} -Note: Hugepages for which a commitment to allocate has been made, but no allocation has yet been made. -This is reported as a separate metric rather than a `usage` state because reserved pages are already counted in `free` pages. -They represent a subset of free pages that cannot be used for non-reserved allocations. -""" - - -def create_system_memory_linux_hugepages_reserved(meter: Meter) -> UpDownCounter: - """Number of reserved hugepages""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_HUGEPAGES_RESERVED, - description="Number of reserved hugepages.", - unit="{page}", - ) - - -SYSTEM_MEMORY_LINUX_HUGEPAGES_SURPLUS: Final = "system.memory.linux.hugepages.surplus" -""" -Number of surplus hugepages -Instrument: updowncounter -Unit: {page} -Note: Overcommitted hugepages beyond the persistent pool. -This is reported as a separate metric rather than a `usage` state because surplus pages can be in either `used` or `free` state. -Including them in `usage` would break the convention that `usage` states sum to the `limit`. -""" - - -def create_system_memory_linux_hugepages_surplus(meter: Meter) -> UpDownCounter: - """Number of surplus hugepages""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_HUGEPAGES_SURPLUS, - description="Number of surplus hugepages.", - unit="{page}", - ) - - -SYSTEM_MEMORY_LINUX_HUGEPAGES_USAGE: Final = "system.memory.linux.hugepages.usage" -""" -Number of hugepages in use by state -Instrument: updowncounter -Unit: {page} -""" - - -def create_system_memory_linux_hugepages_usage(meter: Meter) -> UpDownCounter: - """Number of hugepages in use by state""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_HUGEPAGES_USAGE, - description="Number of hugepages in use by state.", - unit="{page}", - ) - - -SYSTEM_MEMORY_LINUX_HUGEPAGES_UTILIZATION: Final = "system.memory.linux.hugepages.utilization" -""" -Percentage of hugepages in use by state -Instrument: gauge -Unit: 1 -""" - - -def create_system_memory_linux_hugepages_utilization( - meter: Meter, callbacks: Sequence[CallbackT] | None -) -> ObservableGauge: - """Percentage of hugepages in use by state""" - return meter.create_observable_gauge( - name=SYSTEM_MEMORY_LINUX_HUGEPAGES_UTILIZATION, - callbacks=callbacks, - description="Percentage of hugepages in use by state.", - unit="1", - ) - - -SYSTEM_MEMORY_LINUX_SHARED: Final = "system.memory.linux.shared" -""" -Shared memory used (mostly by tmpfs) -Instrument: updowncounter -Unit: By -Note: Equivalent of `shared` from [`free` command](https://man7.org/linux/man-pages/man1/free.1.html) or -`Shmem` from [`/proc/meminfo`](https://man7.org/linux/man-pages/man5/proc.5.html)". -""" - - -def create_system_memory_linux_shared(meter: Meter) -> UpDownCounter: - """Shared memory used (mostly by tmpfs)""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_SHARED, - description="Shared memory used (mostly by tmpfs).", - unit="By", - ) - - -SYSTEM_MEMORY_LINUX_SLAB_USAGE: Final = "system.memory.linux.slab.usage" -""" -Reports the memory used by the Linux kernel for managing caches of frequently used objects -Instrument: updowncounter -Unit: By -Note: The sum over the `reclaimable` and `unreclaimable` state values in `memory.linux.slab.usage` SHOULD be equal to the total slab memory available on the system. -Note that the total slab memory is not constant and may vary over time. -See also the [Slab allocator](https://blogs.oracle.com/linux/post/understanding-linux-kernel-memory-statistics) and `Slab` in [/proc/meminfo](https://man7.org/linux/man-pages/man5/proc.5.html). -""" - - -def create_system_memory_linux_slab_usage(meter: Meter) -> UpDownCounter: - """Reports the memory used by the Linux kernel for managing caches of frequently used objects""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_LINUX_SLAB_USAGE, - description="Reports the memory used by the Linux kernel for managing caches of frequently used objects.", - unit="By", - ) - - -SYSTEM_MEMORY_SHARED: Final = "system.memory.shared" -""" -Deprecated: Replaced by `system.memory.linux.shared`. -""" - - -def create_system_memory_shared(meter: Meter) -> UpDownCounter: - """Deprecated, use `system.memory.linux.shared` instead""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_SHARED, - description="Deprecated, use `system.memory.linux.shared` instead.", - unit="By", - ) - - -SYSTEM_MEMORY_USAGE: Final = "system.memory.usage" -""" -Reports memory in use by state -Instrument: updowncounter -Unit: By -""" - - -def create_system_memory_usage(meter: Meter) -> UpDownCounter: - """Reports memory in use by state""" - return meter.create_up_down_counter( - name=SYSTEM_MEMORY_USAGE, - description="Reports memory in use by state.", - unit="By", - ) - - -SYSTEM_MEMORY_UTILIZATION: Final = "system.memory.utilization" -""" -Percentage of memory bytes in use -Instrument: gauge -Unit: 1 -""" - - -def create_system_memory_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Percentage of memory bytes in use""" - return meter.create_observable_gauge( - name=SYSTEM_MEMORY_UTILIZATION, - callbacks=callbacks, - description="Percentage of memory bytes in use.", - unit="1", - ) - - -SYSTEM_NETWORK_CONNECTION_COUNT: Final = "system.network.connection.count" -""" -The number of connections -Instrument: updowncounter -Unit: {connection} -""" - - -def create_system_network_connection_count(meter: Meter) -> UpDownCounter: - """The number of connections""" - return meter.create_up_down_counter( - name=SYSTEM_NETWORK_CONNECTION_COUNT, - description="The number of connections.", - unit="{connection}", - ) - - -SYSTEM_NETWORK_CONNECTIONS: Final = "system.network.connections" -""" -Deprecated: Replaced by `system.network.connection.count`. -""" - - -def create_system_network_connections(meter: Meter) -> UpDownCounter: - """Deprecated, use `system.network.connection.count` instead""" - return meter.create_up_down_counter( - name=SYSTEM_NETWORK_CONNECTIONS, - description="Deprecated, use `system.network.connection.count` instead.", - unit="{connection}", - ) - - -SYSTEM_NETWORK_DROPPED: Final = "system.network.dropped" -""" -Deprecated: Replaced by `system.network.packet.dropped`. -""" - - -def create_system_network_dropped(meter: Meter) -> Counter: - """Count of packets that are dropped or discarded even though there was no error""" - return meter.create_counter( - name=SYSTEM_NETWORK_DROPPED, - description="Count of packets that are dropped or discarded even though there was no error.", - unit="{packet}", - ) - - -SYSTEM_NETWORK_ERRORS: Final = "system.network.errors" -""" -Count of network errors detected -Instrument: counter -Unit: {error} -Note: Measured as: - -- Linux: the `errs` column in `/proc/net/dev` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)). -- Windows: [`InErrors`/`OutErrors`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) - from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2). -""" - - -def create_system_network_errors(meter: Meter) -> Counter: - """Count of network errors detected""" - return meter.create_counter( - name=SYSTEM_NETWORK_ERRORS, - description="Count of network errors detected.", - unit="{error}", - ) - - -SYSTEM_NETWORK_IO: Final = "system.network.io" -""" -The number of bytes transmitted and received -Instrument: counter -Unit: By -""" - - -def create_system_network_io(meter: Meter) -> Counter: - """The number of bytes transmitted and received""" - return meter.create_counter( - name=SYSTEM_NETWORK_IO, - description="The number of bytes transmitted and received.", - unit="By", - ) - - -SYSTEM_NETWORK_PACKET_COUNT: Final = "system.network.packet.count" -""" -The number of packets transferred -Instrument: counter -Unit: {packet} -""" - - -def create_system_network_packet_count(meter: Meter) -> Counter: - """The number of packets transferred""" - return meter.create_counter( - name=SYSTEM_NETWORK_PACKET_COUNT, - description="The number of packets transferred.", - unit="{packet}", - ) - - -SYSTEM_NETWORK_PACKET_DROPPED: Final = "system.network.packet.dropped" -""" -Count of packets that are dropped or discarded even though there was no error -Instrument: counter -Unit: {packet} -Note: Measured as: - -- Linux: the `drop` column in `/proc/net/dev` ([source](https://web.archive.org/web/20180321091318/http://www.onlamp.com/pub/a/linux/2000/11/16/LinuxAdmin.html)) -- Windows: [`InDiscards`/`OutDiscards`](https://docs.microsoft.com/windows/win32/api/netioapi/ns-netioapi-mib_if_row2) - from [`GetIfEntry2`](https://docs.microsoft.com/windows/win32/api/netioapi/nf-netioapi-getifentry2). -""" - - -def create_system_network_packet_dropped(meter: Meter) -> Counter: - """Count of packets that are dropped or discarded even though there was no error""" - return meter.create_counter( - name=SYSTEM_NETWORK_PACKET_DROPPED, - description="Count of packets that are dropped or discarded even though there was no error.", - unit="{packet}", - ) - - -SYSTEM_NETWORK_PACKETS: Final = "system.network.packets" -""" -Deprecated: Replaced by `system.network.packet.count`. -""" - - -def create_system_network_packets(meter: Meter) -> Counter: - """The number of packets transferred""" - return meter.create_counter( - name=SYSTEM_NETWORK_PACKETS, - description="The number of packets transferred.", - unit="{packet}", - ) - - -SYSTEM_PAGING_FAULTS: Final = "system.paging.faults" -""" -The number of page faults -Instrument: counter -Unit: {fault} -""" - - -def create_system_paging_faults(meter: Meter) -> Counter: - """The number of page faults""" - return meter.create_counter( - name=SYSTEM_PAGING_FAULTS, - description="The number of page faults.", - unit="{fault}", - ) - - -SYSTEM_PAGING_OPERATIONS: Final = "system.paging.operations" -""" -The number of paging operations -Instrument: counter -Unit: {operation} -""" - - -def create_system_paging_operations(meter: Meter) -> Counter: - """The number of paging operations""" - return meter.create_counter( - name=SYSTEM_PAGING_OPERATIONS, - description="The number of paging operations.", - unit="{operation}", - ) - - -SYSTEM_PAGING_USAGE: Final = "system.paging.usage" -""" -UNIX swap or windows pagefile usage -Instrument: updowncounter -Unit: By -""" - - -def create_system_paging_usage(meter: Meter) -> UpDownCounter: - """UNIX swap or windows pagefile usage""" - return meter.create_up_down_counter( - name=SYSTEM_PAGING_USAGE, - description="UNIX swap or windows pagefile usage.", - unit="By", - ) - - -SYSTEM_PAGING_UTILIZATION: Final = "system.paging.utilization" -""" -Swap (UNIX) or pagefile (windows) utilization -Instrument: gauge -Unit: 1 -""" - - -def create_system_paging_utilization(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Swap (UNIX) or pagefile (windows) utilization""" - return meter.create_observable_gauge( - name=SYSTEM_PAGING_UTILIZATION, - callbacks=callbacks, - description="Swap (UNIX) or pagefile (windows) utilization.", - unit="1", - ) - - -SYSTEM_PROCESS_COUNT: Final = "system.process.count" -""" -Total number of processes in each state -Instrument: updowncounter -Unit: {process} -""" - - -def create_system_process_count(meter: Meter) -> UpDownCounter: - """Total number of processes in each state""" - return meter.create_up_down_counter( - name=SYSTEM_PROCESS_COUNT, - description="Total number of processes in each state.", - unit="{process}", - ) - - -SYSTEM_PROCESS_CREATED: Final = "system.process.created" -""" -Total number of processes created over uptime of the host -Instrument: counter -Unit: {process} -""" - - -def create_system_process_created(meter: Meter) -> Counter: - """Total number of processes created over uptime of the host""" - return meter.create_counter( - name=SYSTEM_PROCESS_CREATED, - description="Total number of processes created over uptime of the host.", - unit="{process}", - ) - - -SYSTEM_PROCESS_LIMIT: Final = "system.process.limit" -""" -The maximum number of concurrent processes/tasks allowed by the operating system -Instrument: updowncounter -Unit: {thread} -Note: On Linux, this corresponds to `/proc/sys/kernel/pid_max` or `/proc/sys/kernel/threads-max`. -A per-user process limit may also be retrieved via `getrlimit(RLIMIT_NPROC)`. -On BSD-like systems, this corresponds to `sysctl kern.maxproc`. This metric is unsupported on Windows systems. -""" - - -def create_system_process_limit(meter: Meter) -> UpDownCounter: - """The maximum number of concurrent processes/tasks allowed by the operating system""" - return meter.create_up_down_counter( - name=SYSTEM_PROCESS_LIMIT, - description="The maximum number of concurrent processes/tasks allowed by the operating system.", - unit="{thread}", - ) - - -SYSTEM_UPTIME: Final = "system.uptime" -""" -The time the system has been running -Instrument: gauge -Unit: s -Note: Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point number with the highest precision available. -The actual accuracy would depend on the instrumentation and operating system. -""" - - -def create_system_uptime(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The time the system has been running""" - return meter.create_observable_gauge( - name=SYSTEM_UPTIME, - callbacks=callbacks, - description="The time the system has been running.", - unit="s", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py deleted file mode 100644 index 53f80512db0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/_incubating/metrics/vcs_metrics.py +++ /dev/null @@ -1,193 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from collections.abc import Callable, Generator, Iterable, Sequence -from typing import Final - -from opentelemetry.agent._vendor.opentelemetry.metrics import CallbackOptions, Meter, ObservableGauge, Observation, UpDownCounter - -# pylint: disable=invalid-name -CallbackT = Callable[[CallbackOptions], Iterable[Observation]] | Generator[Iterable[Observation], CallbackOptions, None] - - -VCS_CHANGE_COUNT: Final = "vcs.change.count" -""" -The number of changes (pull requests/merge requests/changelists) in a repository, categorized by their state (e.g. open or merged) -Instrument: updowncounter -Unit: {change} -""" - - -def create_vcs_change_count(meter: Meter) -> UpDownCounter: - """The number of changes (pull requests/merge requests/changelists) in a repository, categorized by their state (e.g. open or merged)""" - return meter.create_up_down_counter( - name=VCS_CHANGE_COUNT, - description="The number of changes (pull requests/merge requests/changelists) in a repository, categorized by their state (e.g. open or merged).", - unit="{change}", - ) - - -VCS_CHANGE_DURATION: Final = "vcs.change.duration" -""" -The time duration a change (pull request/merge request/changelist) has been in a given state -Instrument: gauge -Unit: s -""" - - -def create_vcs_change_duration(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The time duration a change (pull request/merge request/changelist) has been in a given state""" - return meter.create_observable_gauge( - name=VCS_CHANGE_DURATION, - callbacks=callbacks, - description="The time duration a change (pull request/merge request/changelist) has been in a given state.", - unit="s", - ) - - -VCS_CHANGE_TIME_TO_APPROVAL: Final = "vcs.change.time_to_approval" -""" -The amount of time since its creation it took a change (pull request/merge request/changelist) to get the first approval -Instrument: gauge -Unit: s -""" - - -def create_vcs_change_time_to_approval(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The amount of time since its creation it took a change (pull request/merge request/changelist) to get the first approval""" - return meter.create_observable_gauge( - name=VCS_CHANGE_TIME_TO_APPROVAL, - callbacks=callbacks, - description="The amount of time since its creation it took a change (pull request/merge request/changelist) to get the first approval.", - unit="s", - ) - - -VCS_CHANGE_TIME_TO_MERGE: Final = "vcs.change.time_to_merge" -""" -The amount of time since its creation it took a change (pull request/merge request/changelist) to get merged into the target(base) ref -Instrument: gauge -Unit: s -""" - - -def create_vcs_change_time_to_merge(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The amount of time since its creation it took a change (pull request/merge request/changelist) to get merged into the target(base) ref""" - return meter.create_observable_gauge( - name=VCS_CHANGE_TIME_TO_MERGE, - callbacks=callbacks, - description="The amount of time since its creation it took a change (pull request/merge request/changelist) to get merged into the target(base) ref.", - unit="s", - ) - - -VCS_CONTRIBUTOR_COUNT: Final = "vcs.contributor.count" -""" -The number of unique contributors to a repository -Instrument: gauge -Unit: {contributor} -""" - - -def create_vcs_contributor_count(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The number of unique contributors to a repository""" - return meter.create_observable_gauge( - name=VCS_CONTRIBUTOR_COUNT, - callbacks=callbacks, - description="The number of unique contributors to a repository.", - unit="{contributor}", - ) - - -VCS_REF_COUNT: Final = "vcs.ref.count" -""" -The number of refs of type branch or tag in a repository -Instrument: updowncounter -Unit: {ref} -""" - - -def create_vcs_ref_count(meter: Meter) -> UpDownCounter: - """The number of refs of type branch or tag in a repository""" - return meter.create_up_down_counter( - name=VCS_REF_COUNT, - description="The number of refs of type branch or tag in a repository.", - unit="{ref}", - ) - - -VCS_REF_LINES_DELTA: Final = "vcs.ref.lines_delta" -""" -The number of lines added/removed in a ref (branch) relative to the ref from the `vcs.ref.base.name` attribute -Instrument: gauge -Unit: {line} -Note: This metric should be reported for each `vcs.line_change.type` value. For example if a ref added 3 lines and removed 2 lines, -instrumentation SHOULD report two measurements: 3 and 2 (both positive numbers). -If number of lines added/removed should be calculated from the start of time, then `vcs.ref.base.name` SHOULD be set to an empty string. -""" - - -def create_vcs_ref_lines_delta(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The number of lines added/removed in a ref (branch) relative to the ref from the `vcs.ref.base.name` attribute""" - return meter.create_observable_gauge( - name=VCS_REF_LINES_DELTA, - callbacks=callbacks, - description="The number of lines added/removed in a ref (branch) relative to the ref from the `vcs.ref.base.name` attribute.", - unit="{line}", - ) - - -VCS_REF_REVISIONS_DELTA: Final = "vcs.ref.revisions_delta" -""" -The number of revisions (commits) a ref (branch) is ahead/behind the branch from the `vcs.ref.base.name` attribute -Instrument: gauge -Unit: {revision} -Note: This metric should be reported for each `vcs.revision_delta.direction` value. For example if branch `a` is 3 commits behind and 2 commits ahead of `trunk`, -instrumentation SHOULD report two measurements: 3 and 2 (both positive numbers) and `vcs.ref.base.name` is set to `trunk`. -""" - - -def create_vcs_ref_revisions_delta(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """The number of revisions (commits) a ref (branch) is ahead/behind the branch from the `vcs.ref.base.name` attribute""" - return meter.create_observable_gauge( - name=VCS_REF_REVISIONS_DELTA, - callbacks=callbacks, - description="The number of revisions (commits) a ref (branch) is ahead/behind the branch from the `vcs.ref.base.name` attribute.", - unit="{revision}", - ) - - -VCS_REF_TIME: Final = "vcs.ref.time" -""" -Time a ref (branch) created from the default branch (trunk) has existed. The `ref.type` attribute will always be `branch` -Instrument: gauge -Unit: s -""" - - -def create_vcs_ref_time(meter: Meter, callbacks: Sequence[CallbackT] | None) -> ObservableGauge: - """Time a ref (branch) created from the default branch (trunk) has existed. The `ref.type` attribute will always be `branch`""" - return meter.create_observable_gauge( - name=VCS_REF_TIME, - callbacks=callbacks, - description="Time a ref (branch) created from the default branch (trunk) has existed. The `ref.type` attribute will always be `branch`.", - unit="s", - ) - - -VCS_REPOSITORY_COUNT: Final = "vcs.repository.count" -""" -The number of repositories in an organization -Instrument: updowncounter -Unit: {repository} -""" - - -def create_vcs_repository_count(meter: Meter) -> UpDownCounter: - """The number of repositories in an organization""" - return meter.create_up_down_counter( - name=VCS_REPOSITORY_COUNT, - description="The number of repositories in an organization.", - unit="{repository}", - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py deleted file mode 100644 index cf7bb336294..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/client_attributes.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -CLIENT_ADDRESS: Final = "client.address" -""" -Client address - domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. -Note: When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. -""" - -CLIENT_PORT: Final = "client.port" -""" -Client port number. -Note: When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py deleted file mode 100644 index 142fb957948..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/code_attributes.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -CODE_COLUMN_NUMBER: Final = "code.column.number" -""" -The column number in `code.file.path` best representing the operation. It SHOULD point within the code unit named in `code.function.name`. This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Line'. This constraint is imposed to prevent redundancy and maintain data integrity. -""" - -CODE_FILE_PATH: Final = "code.file.path" -""" -The source code filename that identifies the code unit as uniquely as possible (preferably an absolute file path). This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Function'. This constraint is imposed to prevent redundancy and maintain data integrity. -""" - -CODE_FUNCTION_NAME: Final = "code.function.name" -""" -The method or function fully-qualified name without arguments. The value should fit the natural representation of the language runtime, which is also likely the same used within `code.stacktrace` attribute value. This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Function'. This constraint is imposed to prevent redundancy and maintain data integrity. -Note: Values and format depends on each language runtime, thus it is impossible to provide an exhaustive list of examples. -The values are usually the same (or prefixes of) the ones found in native stack trace representation stored in -`code.stacktrace` without information on arguments. - -Examples: - -* Java method: `com.example.MyHttpService.serveRequest` -* Java anonymous class method: `com.mycompany.Main$1.myMethod` -* Java lambda method: `com.mycompany.Main$$Lambda/0x0000748ae4149c00.myMethod` -* PHP function: `GuzzleHttp\\Client::transfer` -* Go function: `github.com/my/repo/pkg.foo.func5` -* Elixir: `OpenTelemetry.Ctx.new` -* Erlang: `opentelemetry_ctx:new` -* Rust: `playground::my_module::my_cool_func` -* C function: `fopen`. -""" - -CODE_LINE_NUMBER: Final = "code.line.number" -""" -The line number in `code.file.path` best representing the operation. It SHOULD point within the code unit named in `code.function.name`. This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Line'. This constraint is imposed to prevent redundancy and maintain data integrity. -""" - -CODE_STACKTRACE: Final = "code.stacktrace" -""" -A stacktrace as a string in the natural representation for the language runtime. The representation is identical to [`exception.stacktrace`](/docs/exceptions/exceptions-spans.md#stacktrace-representation). This attribute MUST NOT be used on the Profile signal since the data is already captured in 'message Location'. This constraint is imposed to prevent redundancy and maintain data integrity. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py deleted file mode 100644 index cc3739771fb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/container_attributes.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -CONTAINER_ID: Final = "container.id" -""" -Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/containers/run/#container-identification). The UUID might be abbreviated. -""" - -CONTAINER_IMAGE_NAME: Final = "container.image.name" -""" -Name of the image the container was built on. -""" - -CONTAINER_IMAGE_REPO_DIGESTS: Final = "container.image.repo_digests" -""" -Repository digests of the container image as provided by the container runtime. -Note: [Docker](https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect) and [CRI](https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238) report those under the `RepoDigests` field. -""" - -CONTAINER_IMAGE_TAGS: Final = "container.image.tags" -""" -Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect). Should be only the `` section of the full name for example from `registry.example.com/my-org/my-image:`. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py deleted file mode 100644 index 26e7b483a17..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/db_attributes.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -DB_COLLECTION_NAME: Final = "db.collection.name" -""" -The name of a collection (table, container) within the database. -Note: It is RECOMMENDED to capture the value as provided by the application -without attempting to do any case normalization. - -The collection name SHOULD NOT be extracted from `db.query.text`, -when the database system supports query text with multiple collections -in non-batch operations. - -For batch operations, if the individual operations are known to have the same -collection name then that collection name SHOULD be used. -""" - -DB_NAMESPACE: Final = "db.namespace" -""" -The name of the database, fully qualified within the server address and port. -Note: If a database system has multiple namespace components, they SHOULD be concatenated from the most general to the most specific namespace component, using `|` as a separator between the components. Any missing components (and their associated separators) SHOULD be omitted. -Semantic conventions for individual database systems SHOULD document what `db.namespace` means in the context of that system. -It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. -""" - -DB_OPERATION_BATCH_SIZE: Final = "db.operation.batch.size" -""" -The number of database operations included in a batch operation. -Note: Except for empty batch requests described below, a batch operation contains two -or more database operations explicitly submitted as separate operations in a single -client call, protocol message, or database command. - -Requests to batch APIs that contain only one operation SHOULD be modeled as single -operations, not as batch operations. - -A database call is not a batch operation solely because one operation accepts -multiple operands, such as keys, rows, documents, points, or other data elements, -including Redis [`MGET`](https://redis.io/docs/latest/commands/mget/) with -multiple keys. - -In batch APIs that execute the same parameterized operation with parameter sets, -each parameter set represents one database operation for determining whether the -request is a batch operation. Requests with only one parameter set SHOULD be modeled -as single operations, not as batch operations. - -`db.operation.batch.size` SHOULD be set to the number of operations in the batch. -It SHOULD NOT be set for non-batch operations. - -A request to execute a batch operation with no operations SHOULD also be treated -as a batch operation, and `db.operation.batch.size` SHOULD be set to `0`. -""" - -DB_OPERATION_NAME: Final = "db.operation.name" -""" -The name of the operation or command being executed. -Note: It is RECOMMENDED to capture the value as provided by the application -without attempting to do any case normalization. - -The operation name SHOULD NOT be extracted from `db.query.text`, -when the database system supports query text with multiple operations -in non-batch operations. - -If spaces can occur in the operation name, multiple consecutive spaces -SHOULD be normalized to a single space. - -For batch operations, if the individual operations are known to have the same operation name -then that operation name SHOULD be used prepended by `BATCH `, -otherwise `db.operation.name` SHOULD be `BATCH` or some other database -system specific term if more applicable. -""" - -DB_QUERY_SUMMARY: Final = "db.query.summary" -""" -Low cardinality summary of a database query. -Note: The query summary describes a class of database queries and is useful -as a grouping key, especially when analyzing telemetry for database -calls involving complex queries. - -Summary may be available to the instrumentation through -instrumentation hooks or other means. If it is not available, instrumentations -that support query parsing SHOULD generate a summary following -[Generating query summary](/docs/db/database-spans.md#generating-a-summary-of-the-query) -section. - -For batch operations, if the individual operations are known to have the same query summary -then that query summary SHOULD be used prepended by `BATCH `, -otherwise `db.query.summary` SHOULD be `BATCH` or some other database -system specific term if more applicable. -""" - -DB_QUERY_TEXT: Final = "db.query.text" -""" -The database query being executed. -Note: For sanitization see [Sanitization of `db.query.text`](/docs/db/database-spans.md#sanitization-of-dbquerytext). -For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator `; ` or some other database system specific separator if more applicable. -Parameterized query text SHOULD NOT be sanitized. Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. -""" - -DB_RESPONSE_STATUS_CODE: Final = "db.response.status_code" -""" -Database response status code. -Note: The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. -Semantic conventions for individual database systems SHOULD document what `db.response.status_code` means in the context of that system. -""" - -DB_STORED_PROCEDURE_NAME: Final = "db.stored_procedure.name" -""" -The name of a stored procedure within the database. -Note: It is RECOMMENDED to capture the value as provided by the application -without attempting to do any case normalization. - -For batch operations, if the individual operations are known to have the same -stored procedure name then that stored procedure name SHOULD be used. -""" - -DB_SYSTEM_NAME: Final = "db.system.name" -""" -The database management system (DBMS) product as identified by the client instrumentation. -Note: The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the `db.system.name` is set to `postgresql` based on the instrumentation's best knowledge. -""" - - -class DbSystemNameValues(Enum): - MARIADB = "mariadb" - """[MariaDB](https://mariadb.org/).""" - MICROSOFT_SQL_SERVER = "microsoft.sql_server" - """[Microsoft SQL Server](https://www.microsoft.com/sql-server).""" - MYSQL = "mysql" - """[MySQL](https://www.mysql.com/).""" - POSTGRESQL = "postgresql" - """[PostgreSQL](https://www.postgresql.org/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py deleted file mode 100644 index 338f935e74b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/deployment_attributes.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -DEPLOYMENT_ENVIRONMENT_NAME: Final = "deployment.environment.name" -""" -Name of the [deployment environment](https://wikipedia.org/wiki/Deployment_environment) (aka deployment tier). -Note: `deployment.environment.name` does not affect the uniqueness constraints defined through -the `service.namespace`, `service.name` and `service.instance.id` resource attributes. -This implies that resources carrying the following attribute combinations MUST be -considered to be identifying the same service: - -- `service.name=frontend`, `deployment.environment.name=production` -- `service.name=frontend`, `deployment.environment.name=staging`. -""" - - -class DeploymentEnvironmentNameValues(Enum): - PRODUCTION = "production" - """Production environment.""" - STAGING = "staging" - """Staging environment.""" - TEST = "test" - """Testing environment.""" - DEVELOPMENT = "development" - """Development environment.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py deleted file mode 100644 index 9c4efd7d8b4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/error_attributes.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -ERROR_TYPE: Final = "error.type" -""" -Describes a class of error the operation ended with. -Note: The `error.type` SHOULD be predictable, and SHOULD have low cardinality. - -When `error.type` is set to a type (e.g., an exception type), its -canonical class name identifying the type within the artifact SHOULD be used. - -If the recorded error type is a wrapper that is not meaningful for -failure classification, instrumentation MAY use the type of the inner -error instead. For example, in Go, errors created with `fmt.Errorf` -using `%w` MAY be unwrapped when the wrapper type does not help -classify the failure. - -Instrumentations SHOULD document the list of errors they report. - -The cardinality of `error.type` within one instrumentation library SHOULD be low. -Telemetry consumers that aggregate data from multiple instrumentation libraries and applications -should be prepared for `error.type` to have high cardinality at query time when no -additional filters are applied. - -If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`. - -If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes), -it's RECOMMENDED to: - -- Use a domain-specific attribute -- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not. -""" - - -class ErrorTypeValues(Enum): - OTHER = "_OTHER" - """A fallback error value to be used when the instrumentation doesn't define a custom value.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py deleted file mode 100644 index 2d7e748e370..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/exception_attributes.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -EXCEPTION_ESCAPED: Final = "exception.escaped" -""" -Deprecated: It's no longer recommended to record exceptions that are handled and do not escape the scope of a span. -""" - -EXCEPTION_MESSAGE: Final = "exception.message" -""" -The exception message. -Note: > [!WARNING] -> -> This attribute may contain sensitive information. -""" - -EXCEPTION_STACKTRACE: Final = "exception.stacktrace" -""" -A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. -""" - -EXCEPTION_TYPE: Final = "exception.type" -""" -The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. -Note: If the recorded exception type is a wrapper that is not meaningful for -failure classification, instrumentation MAY use the type of the inner -exception instead. For example, in Go, errors created with `fmt.Errorf` -using `%w` MAY be unwrapped when the wrapper type does not help -classify the failure. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py deleted file mode 100644 index 5dbad619dd5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/http_attributes.py +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -HTTP_REQUEST_HEADER_TEMPLATE: Final = "http.request.header" -""" -HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. -Note: Instrumentations SHOULD require an explicit configuration of which headers are to be captured. -Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. - -The `User-Agent` header is already captured in the `user_agent.original` attribute. -Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - -The attribute value MUST consist of either multiple header values as an array of strings -or a single-item array containing a possibly comma-concatenated string, depending on the way -the HTTP library provides access to headers. - -Examples: - -- A header `Content-Type: application/json` SHOULD be recorded as the `http.request.header.content-type` - attribute with value `["application/json"]`. -- A header `X-Forwarded-For: 1.2.3.4, 1.2.3.5` SHOULD be recorded as the `http.request.header.x-forwarded-for` - attribute with value `["1.2.3.4", "1.2.3.5"]` or `["1.2.3.4, 1.2.3.5"]` depending on the HTTP library. -""" - -HTTP_REQUEST_METHOD: Final = "http.request.method" -""" -HTTP request method. -Note: HTTP request method value SHOULD be "known" to the instrumentation. -By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods), -the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html) -and the QUERY method defined in [httpbis-safe-method-w-body](https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/?include_text=1). - -If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. - -If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override -the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named -OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods. - -![Development](https://img.shields.io/badge/-development-blue) -If this override is done via declarative configuration, then the list MUST be configurable via the `known_methods` property -(an array of case-sensitive strings with minimum items 0) under `.instrumentation/development.general.http.client` and/or -`.instrumentation/development.general.http.server`. - -In either case, this list MUST be a full override of the default known methods, -it is not a list of known methods in addition to the defaults. - -HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. -Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. -Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. -""" - -HTTP_REQUEST_METHOD_ORIGINAL: Final = "http.request.method_original" -""" -Original HTTP method sent by the client in the request line. -""" - -HTTP_REQUEST_RESEND_COUNT: Final = "http.request.resend_count" -""" -The ordinal number of request resending attempt (for any reason, including redirects). -Note: The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). -""" - -HTTP_RESPONSE_HEADER_TEMPLATE: Final = "http.response.header" -""" -HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. -Note: Instrumentations SHOULD require an explicit configuration of which headers are to be captured. -Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. - -Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - -The attribute value MUST consist of either multiple header values as an array of strings -or a single-item array containing a possibly comma-concatenated string, depending on the way -the HTTP library provides access to headers. - -Examples: - -- A header `Content-Type: application/json` header SHOULD be recorded as the `http.request.response.content-type` - attribute with value `["application/json"]`. -- A header `My-custom-header: abc, def` header SHOULD be recorded as the `http.response.header.my-custom-header` - attribute with value `["abc", "def"]` or `["abc, def"]` depending on the HTTP library. -""" - -HTTP_RESPONSE_STATUS_CODE: Final = "http.response.status_code" -""" -[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). -""" - -HTTP_ROUTE: Final = "http.route" -""" -The matched route template for the request. This MUST be low-cardinality and include all static path segments, with dynamic path segments represented with placeholders. -Note: MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. -SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. - -A static path segment is a part of the route template with a fixed, low-cardinality value. This includes literal strings like `/users/` and placeholders that -are constrained to a finite, predefined set of values, e.g. `{controller}` or `{action}`. - -A dynamic path segment is a placeholder for a value that can have high cardinality and is not constrained to a predefined list like static path segments. - -Instrumentations SHOULD use routing information provided by the corresponding web framework. They SHOULD pick the most precise source of routing information and MAY -support custom route formatting. Instrumentations SHOULD document the format and the API used to obtain the route string. -""" - - -class HttpRequestMethodValues(Enum): - CONNECT = "CONNECT" - """CONNECT method.""" - DELETE = "DELETE" - """DELETE method.""" - GET = "GET" - """GET method.""" - HEAD = "HEAD" - """HEAD method.""" - OPTIONS = "OPTIONS" - """OPTIONS method.""" - PATCH = "PATCH" - """PATCH method.""" - POST = "POST" - """POST method.""" - PUT = "PUT" - """PUT method.""" - TRACE = "TRACE" - """TRACE method.""" - OTHER = "_OTHER" - """Any HTTP method that the instrumentation has no prior knowledge of.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py deleted file mode 100644 index ca07fadf8a2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/k8s_attributes.py +++ /dev/null @@ -1,362 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -K8S_CLUSTER_NAME: Final = "k8s.cluster.name" -""" -The name of the cluster. -""" - -K8S_CLUSTER_UID: Final = "k8s.cluster.uid" -""" -A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. -Note: K8s doesn't have support for obtaining a cluster ID. If this is ever -added, we will recommend collecting the `k8s.cluster.uid` through the -official APIs. In the meantime, we are able to use the `uid` of the -`kube-system` namespace as a proxy for cluster ID. Read on for the -rationale. - -Every object created in a K8s cluster is assigned a distinct UID. The -`kube-system` namespace is used by Kubernetes itself and will exist -for the lifetime of the cluster. Using the `uid` of the `kube-system` -namespace is a reasonable proxy for the K8s ClusterID as it will only -change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are -UUIDs as standardized by -[ISO/IEC 9834-8 and ITU-T X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). -Which states: - -> If generated according to one of the mechanisms defined in Rec. -> ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be -> different from all other UUIDs generated before 3603 A.D., or is -> extremely likely to be different (depending on the mechanism chosen). - -Therefore, UIDs between clusters should be extremely unlikely to -conflict. -""" - -K8S_CONTAINER_NAME: Final = "k8s.container.name" -""" -The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). -""" - -K8S_CONTAINER_RESTART_COUNT: Final = "k8s.container.restart_count" -""" -Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. -""" - -K8S_CRONJOB_ANNOTATION_TEMPLATE: Final = "k8s.cronjob.annotation" -""" -The cronjob annotation placed on the CronJob, the `` being the annotation name, the value being the annotation value. -Note: Examples: - -- An annotation `retries` with value `4` SHOULD be recorded as the - `k8s.cronjob.annotation.retries` attribute with value `"4"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.cronjob.annotation.data` attribute with value `""`. -""" - -K8S_CRONJOB_LABEL_TEMPLATE: Final = "k8s.cronjob.label" -""" -The label placed on the CronJob, the `` being the label name, the value being the label value. -Note: Examples: - -- A label `type` with value `weekly` SHOULD be recorded as the - `k8s.cronjob.label.type` attribute with value `"weekly"`. -- A label `automated` with empty string value SHOULD be recorded as - the `k8s.cronjob.label.automated` attribute with value `""`. -""" - -K8S_CRONJOB_NAME: Final = "k8s.cronjob.name" -""" -The name of the CronJob. -""" - -K8S_CRONJOB_UID: Final = "k8s.cronjob.uid" -""" -The UID of the CronJob. -""" - -K8S_DAEMONSET_ANNOTATION_TEMPLATE: Final = "k8s.daemonset.annotation" -""" -The annotation placed on the DaemonSet, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `replicas` with value `1` SHOULD be recorded - as the `k8s.daemonset.annotation.replicas` attribute with value `"1"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.daemonset.annotation.data` attribute with value `""`. -""" - -K8S_DAEMONSET_LABEL_TEMPLATE: Final = "k8s.daemonset.label" -""" -The label placed on the DaemonSet, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `app` with value `guestbook` SHOULD be recorded - as the `k8s.daemonset.label.app` attribute with value `"guestbook"`. -- A label `injected` with empty string value SHOULD be recorded as - the `k8s.daemonset.label.injected` attribute with value `""`. -""" - -K8S_DAEMONSET_NAME: Final = "k8s.daemonset.name" -""" -The name of the DaemonSet. -""" - -K8S_DAEMONSET_UID: Final = "k8s.daemonset.uid" -""" -The UID of the DaemonSet. -""" - -K8S_DEPLOYMENT_ANNOTATION_TEMPLATE: Final = "k8s.deployment.annotation" -""" -The annotation placed on the Deployment, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `replicas` with value `1` SHOULD be recorded - as the `k8s.deployment.annotation.replicas` attribute with value `"1"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.deployment.annotation.data` attribute with value `""`. -""" - -K8S_DEPLOYMENT_LABEL_TEMPLATE: Final = "k8s.deployment.label" -""" -The label placed on the Deployment, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `app` with value `guestbook` SHOULD be recorded - as the `k8s.deployment.label.app` attribute with value `"guestbook"`. -- A label `injected` with empty string value SHOULD be recorded as - the `k8s.deployment.label.injected` attribute with value `""`. -""" - -K8S_DEPLOYMENT_NAME: Final = "k8s.deployment.name" -""" -The name of the Deployment. -""" - -K8S_DEPLOYMENT_UID: Final = "k8s.deployment.uid" -""" -The UID of the Deployment. -""" - -K8S_JOB_ANNOTATION_TEMPLATE: Final = "k8s.job.annotation" -""" -The annotation placed on the Job, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `number` with value `1` SHOULD be recorded - as the `k8s.job.annotation.number` attribute with value `"1"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.job.annotation.data` attribute with value `""`. -""" - -K8S_JOB_LABEL_TEMPLATE: Final = "k8s.job.label" -""" -The label placed on the Job, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `jobtype` with value `ci` SHOULD be recorded - as the `k8s.job.label.jobtype` attribute with value `"ci"`. -- A label `automated` with empty string value SHOULD be recorded as - the `k8s.job.label.automated` attribute with value `""`. -""" - -K8S_JOB_NAME: Final = "k8s.job.name" -""" -The name of the Job. -""" - -K8S_JOB_UID: Final = "k8s.job.uid" -""" -The UID of the Job. -""" - -K8S_NAMESPACE_ANNOTATION_TEMPLATE: Final = "k8s.namespace.annotation" -""" -The annotation placed on the Namespace, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `ttl` with value `0` SHOULD be recorded - as the `k8s.namespace.annotation.ttl` attribute with value `"0"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.namespace.annotation.data` attribute with value `""`. -""" - -K8S_NAMESPACE_LABEL_TEMPLATE: Final = "k8s.namespace.label" -""" -The label placed on the Namespace, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `kubernetes.io/metadata.name` with value `default` SHOULD be recorded - as the `k8s.namespace.label.kubernetes.io/metadata.name` attribute with value `"default"`. -- A label `data` with empty string value SHOULD be recorded as - the `k8s.namespace.label.data` attribute with value `""`. -""" - -K8S_NAMESPACE_NAME: Final = "k8s.namespace.name" -""" -The name of the namespace that the pod is running in. -""" - -K8S_NODE_ANNOTATION_TEMPLATE: Final = "k8s.node.annotation" -""" -The annotation placed on the Node, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `node.alpha.kubernetes.io/ttl` with value `0` SHOULD be recorded as - the `k8s.node.annotation.node.alpha.kubernetes.io/ttl` attribute with value `"0"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.node.annotation.data` attribute with value `""`. -""" - -K8S_NODE_LABEL_TEMPLATE: Final = "k8s.node.label" -""" -The label placed on the Node, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `kubernetes.io/arch` with value `arm64` SHOULD be recorded - as the `k8s.node.label.kubernetes.io/arch` attribute with value `"arm64"`. -- A label `data` with empty string value SHOULD be recorded as - the `k8s.node.label.data` attribute with value `""`. -""" - -K8S_NODE_NAME: Final = "k8s.node.name" -""" -The name of the Node. -""" - -K8S_NODE_UID: Final = "k8s.node.uid" -""" -The UID of the Node. -""" - -K8S_POD_ANNOTATION_TEMPLATE: Final = "k8s.pod.annotation" -""" -The annotation placed on the Pod, the `` being the annotation name, the value being the annotation value. -Note: Examples: - -- An annotation `kubernetes.io/enforce-mountable-secrets` with value `true` SHOULD be recorded as - the `k8s.pod.annotation.kubernetes.io/enforce-mountable-secrets` attribute with value `"true"`. -- An annotation `mycompany.io/arch` with value `x64` SHOULD be recorded as - the `k8s.pod.annotation.mycompany.io/arch` attribute with value `"x64"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.pod.annotation.data` attribute with value `""`. -""" - -K8S_POD_HOSTNAME: Final = "k8s.pod.hostname" -""" -Specifies the hostname of the Pod. -Note: The K8s Pod spec has an optional hostname field, which can be used to specify a hostname. -Refer to [K8s docs](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-hostname-and-subdomain-field) -for more information about this field. - -This attribute aligns with the `hostname` field of the -[K8s PodSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podspec-v1-core). -""" - -K8S_POD_IP: Final = "k8s.pod.ip" -""" -IP address allocated to the Pod. -Note: This attribute aligns with the `podIP` field of the -[K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core). -""" - -K8S_POD_LABEL_TEMPLATE: Final = "k8s.pod.label" -""" -The label placed on the Pod, the `` being the label name, the value being the label value. -Note: Examples: - -- A label `app` with value `my-app` SHOULD be recorded as - the `k8s.pod.label.app` attribute with value `"my-app"`. -- A label `mycompany.io/arch` with value `x64` SHOULD be recorded as - the `k8s.pod.label.mycompany.io/arch` attribute with value `"x64"`. -- A label `data` with empty string value SHOULD be recorded as - the `k8s.pod.label.data` attribute with value `""`. -""" - -K8S_POD_NAME: Final = "k8s.pod.name" -""" -The name of the Pod. -""" - -K8S_POD_START_TIME: Final = "k8s.pod.start_time" -""" -The start timestamp of the Pod. -Note: Date and time at which the object was acknowledged by the Kubelet. -This is before the Kubelet pulled the container image(s) for the pod. - -This attribute aligns with the `startTime` field of the -[K8s PodStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.34/#podstatus-v1-core), -in ISO 8601 (RFC 3339 compatible) format. -""" - -K8S_POD_UID: Final = "k8s.pod.uid" -""" -The UID of the Pod. -""" - -K8S_REPLICASET_ANNOTATION_TEMPLATE: Final = "k8s.replicaset.annotation" -""" -The annotation placed on the ReplicaSet, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `replicas` with value `0` SHOULD be recorded - as the `k8s.replicaset.annotation.replicas` attribute with value `"0"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.replicaset.annotation.data` attribute with value `""`. -""" - -K8S_REPLICASET_LABEL_TEMPLATE: Final = "k8s.replicaset.label" -""" -The label placed on the ReplicaSet, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `app` with value `guestbook` SHOULD be recorded - as the `k8s.replicaset.label.app` attribute with value `"guestbook"`. -- A label `injected` with empty string value SHOULD be recorded as - the `k8s.replicaset.label.injected` attribute with value `""`. -""" - -K8S_REPLICASET_NAME: Final = "k8s.replicaset.name" -""" -The name of the ReplicaSet. -""" - -K8S_REPLICASET_UID: Final = "k8s.replicaset.uid" -""" -The UID of the ReplicaSet. -""" - -K8S_STATEFULSET_ANNOTATION_TEMPLATE: Final = "k8s.statefulset.annotation" -""" -The annotation placed on the StatefulSet, the `` being the annotation name, the value being the annotation value, even if the value is empty. -Note: Examples: - -- An annotation `replicas` with value `1` SHOULD be recorded - as the `k8s.statefulset.annotation.replicas` attribute with value `"1"`. -- An annotation `data` with empty string value SHOULD be recorded as - the `k8s.statefulset.annotation.data` attribute with value `""`. -""" - -K8S_STATEFULSET_LABEL_TEMPLATE: Final = "k8s.statefulset.label" -""" -The label placed on the StatefulSet, the `` being the label name, the value being the label value, even if the value is empty. -Note: Examples: - -- A label `app` with value `guestbook` SHOULD be recorded - as the `k8s.statefulset.label.app` attribute with value `"guestbook"`. -- A label `injected` with empty string value SHOULD be recorded as - the `k8s.statefulset.label.injected` attribute with value `""`. -""" - -K8S_STATEFULSET_NAME: Final = "k8s.statefulset.name" -""" -The name of the StatefulSet. -""" - -K8S_STATEFULSET_UID: Final = "k8s.statefulset.uid" -""" -The UID of the StatefulSet. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py deleted file mode 100644 index 7f4cd4aa50d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/network_attributes.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -NETWORK_LOCAL_ADDRESS: Final = "network.local.address" -""" -Local address of the network connection - IP address or UNIX domain socket name. -""" - -NETWORK_LOCAL_PORT: Final = "network.local.port" -""" -Local port number of the network connection. -""" - -NETWORK_PEER_ADDRESS: Final = "network.peer.address" -""" -Peer address of the network connection - IP address or UNIX domain socket name. -""" - -NETWORK_PEER_PORT: Final = "network.peer.port" -""" -Peer port number of the network connection. -""" - -NETWORK_PROTOCOL_NAME: Final = "network.protocol.name" -""" -[OSI application layer](https://wikipedia.org/wiki/Application_layer) or non-OSI equivalent. -Note: The value SHOULD be normalized to lowercase. -""" - -NETWORK_PROTOCOL_VERSION: Final = "network.protocol.version" -""" -The actual version of the protocol used for network communication. -Note: If protocol version is subject to negotiation (for example using [ALPN](https://www.rfc-editor.org/rfc/rfc7301.html)), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. -""" - -NETWORK_TRANSPORT: Final = "network.transport" -""" -[OSI transport layer](https://wikipedia.org/wiki/Transport_layer) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). -Note: The value SHOULD be normalized to lowercase. - -Consider always setting the transport when setting a port number, since -a port number is ambiguous without knowing the transport. For example -different processes could be listening on TCP port 12345 and UDP port 12345. -""" - -NETWORK_TYPE: Final = "network.type" -""" -[OSI network layer](https://wikipedia.org/wiki/Network_layer) or non-OSI equivalent. -Note: The value SHOULD be normalized to lowercase. -""" - - -class NetworkTransportValues(Enum): - TCP = "tcp" - """TCP.""" - UDP = "udp" - """UDP.""" - PIPE = "pipe" - """Named or anonymous pipe.""" - UNIX = "unix" - """UNIX domain socket.""" - QUIC = "quic" - """QUIC.""" - - -class NetworkTypeValues(Enum): - IPV4 = "ipv4" - """IPv4.""" - IPV6 = "ipv6" - """IPv6.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py deleted file mode 100644 index 3bb5747f7dc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/otel_attributes.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -OTEL_EVENT_NAME: Final = "otel.event.name" -""" -Identifies the class / type of event. -Note: This attribute SHOULD be used by non-OTLP exporters when destination does not support `EventName` or equivalent field. This attribute MAY be used by applications using existing logging libraries so that it can be used to set the `EventName` field by Collector or SDK components. -""" - -OTEL_SCOPE_NAME: Final = "otel.scope.name" -""" -The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). -""" - -OTEL_SCOPE_VERSION: Final = "otel.scope.version" -""" -The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). -""" - -OTEL_STATUS_CODE: Final = "otel.status_code" -""" -Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. -""" - -OTEL_STATUS_DESCRIPTION: Final = "otel.status_description" -""" -Description of the Status if it has a value, otherwise not set. -""" - - -class OtelStatusCodeValues(Enum): - OK = "OK" - """The operation has been validated by an Application developer or Operator to have completed successfully.""" - ERROR = "ERROR" - """The operation contains an error.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py deleted file mode 100644 index 1da29204763..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/server_attributes.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -SERVER_ADDRESS: Final = "server.address" -""" -Server domain name if available without reverse DNS lookup; otherwise, IP address or UNIX domain socket name. -Note: When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. -""" - -SERVER_PORT: Final = "server.port" -""" -Server port number. -Note: When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py deleted file mode 100644 index 1ee79b9a917..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/service_attributes.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -SERVICE_INSTANCE_ID: Final = "service.instance.id" -""" -The string ID of the service instance. -Note: MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words -`service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to -distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled -service). - -Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 [RFC -4122](https://www.ietf.org/rfc/rfc4122.txt) UUID, but are free to use an inherent unique ID as the source of -this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and -SHOULD use the following UUID as the namespace: `4d63009a-8d0f-11ee-aad7-4c796ed8e320`. - -UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is -needed. Similar to what can be seen in the man page for the -[`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/latest/machine-id.html) file, the underlying -data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it -or not via another resource attribute. - -For applications running behind an application server (like unicorn), we do not recommend using one identifier -for all processes participating in the application. Instead, it's recommended each division (e.g. a worker -thread in unicorn) to have its own instance.id. - -It's not recommended for a Collector to set `service.instance.id` if it can't unambiguously determine the -service instance that is generating that telemetry. For instance, creating an UUID based on `pod.name` will -likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. -However, Collectors can set the `service.instance.id` if they can unambiguously determine the service instance -for that telemetry. This is typically the case for scraping receivers, as they know the target address and -port. -""" - -SERVICE_NAME: Final = "service.name" -""" -Logical name of the service. -Note: MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with the process executable name, e.g. `unknown_service:bash`. If the process executable name is not available, the value MUST be set to `unknown_service`. -The process executable name is the name of the process executable, the same value as described by the [`process.executable.name`](process.md) resource attribute. -""" - -SERVICE_NAMESPACE: Final = "service.namespace" -""" -A namespace for `service.name`. -Note: A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. -""" - -SERVICE_VERSION: Final = "service.version" -""" -The version string of the service component. The format is not defined by these conventions. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py deleted file mode 100644 index 4d390c4c416..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/telemetry_attributes.py +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum -from typing import Final - -TELEMETRY_DISTRO_NAME: Final = "telemetry.distro.name" -""" -The name of the auto instrumentation agent or distribution, if used. -Note: Official auto instrumentation agents and distributions SHOULD set the `telemetry.distro.name` attribute to -a string starting with `opentelemetry-`, e.g. `opentelemetry-java-instrumentation`. -""" - -TELEMETRY_DISTRO_VERSION: Final = "telemetry.distro.version" -""" -The version string of the auto instrumentation agent or distribution, if used. -""" - -TELEMETRY_SDK_LANGUAGE: Final = "telemetry.sdk.language" -""" -The language of the telemetry SDK. -""" - -TELEMETRY_SDK_NAME: Final = "telemetry.sdk.name" -""" -The name of the telemetry SDK as defined above. -Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. -If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the -`telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point -or another suitable identifier depending on the language. -The identifier `opentelemetry` is reserved and MUST NOT be used in this case. -All custom identifiers SHOULD be stable across different versions of an implementation. -""" - -TELEMETRY_SDK_VERSION: Final = "telemetry.sdk.version" -""" -The version string of the telemetry SDK. -""" - - -class TelemetrySdkLanguageValues(Enum): - CPP = "cpp" - """[C++](https://opentelemetry.io/docs/languages/cpp/).""" - DOTNET = "dotnet" - """[.NET](https://opentelemetry.io/docs/languages/dotnet/).""" - ERLANG = "erlang" - """[Erlang/Elixir](https://opentelemetry.io/docs/languages/erlang/).""" - GO = "go" - """[Go](https://opentelemetry.io/docs/languages/go/).""" - JAVA = "java" - """[Java](https://opentelemetry.io/docs/languages/java/).""" - KOTLIN = "kotlin" - """[Kotlin](https://opentelemetry.io/docs/languages/kotlin/).""" - NODEJS = "nodejs" - """[Node.js](https://opentelemetry.io/docs/languages/js/).""" - PHP = "php" - """[PHP](https://opentelemetry.io/docs/languages/php/).""" - PYTHON = "python" - """[Python](https://opentelemetry.io/docs/languages/python/).""" - RUBY = "ruby" - """[Ruby](https://opentelemetry.io/docs/languages/ruby/).""" - RUST = "rust" - """[Rust](https://opentelemetry.io/docs/languages/rust/).""" - SWIFT = "swift" - """[Swift](https://opentelemetry.io/docs/languages/swift/).""" - WEBJS = "webjs" - """[Browser](https://opentelemetry.io/docs/languages/js/).""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py deleted file mode 100644 index 920de47aafd..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/url_attributes.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -URL_FRAGMENT: Final = "url.fragment" -""" -The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component. -""" - -URL_FULL: Final = "url.full" -""" -Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). -Note: For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment -is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. - -`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. -In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. - -`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed). - -Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can identify it. - -![Development](https://img.shields.io/badge/-development-blue) -Query string values for the following keys SHOULD be redacted by default and replaced by the -value `REDACTED`: - -* [`X-Amz-Signature`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) -* [`X-Amz-Credential`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) -* [`X-Amz-Security-Token`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) -* [`sig`](https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token) -* [`X-Goog-Signature`](https://cloud.google.com/storage/docs/access-control/signed-urls) - -This list is subject to change over time. - -Matching of query parameter keys against the sensitive list SHOULD be case-sensitive. - -![Development](https://img.shields.io/badge/-development-blue) -Instrumentation MAY provide a way to override this list via declarative configuration. -If so, it SHOULD use the `sensitive_query_parameters` property -(an array of case-sensitive strings with minimum items 0) under -`.instrumentation/development.general.sanitization.url`. -This list is a full override of the default sensitive query parameter keys, -it is not a list of keys in addition to the defaults. - -When a query string value is redacted, the query string key SHOULD still be preserved, e.g. -`https://www.example.com/path?color=blue&sig=REDACTED`. -""" - -URL_PATH: Final = "url.path" -""" -The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component. -Note: Sensitive content provided in `url.path` SHOULD be scrubbed when instrumentations can identify it. -""" - -URL_QUERY: Final = "url.query" -""" -The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component. -Note: Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. - -![Development](https://img.shields.io/badge/-development-blue) -Query string values for the following keys SHOULD be redacted by default and replaced by the value `REDACTED`: - -* [`X-Amz-Signature`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) -* [`X-Amz-Credential`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) -* [`X-Amz-Security-Token`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-authentication-methods.html) -* [`sig`](https://learn.microsoft.com/azure/storage/common/storage-sas-overview#sas-token) -* [`X-Goog-Signature`](https://cloud.google.com/storage/docs/access-control/signed-urls) - -This list is subject to change over time. - -Matching of query parameter keys against the sensitive list SHOULD be case-sensitive. - -Instrumentation MAY provide a way to override this list via declarative configuration. -If so, it SHOULD use the `sensitive_query_parameters` property -(an array of case-sensitive strings with minimum items 0) under -`.instrumentation/development.general.sanitization.url`. -This list is a full override of the default sensitive query parameter keys, -it is not a list of keys in addition to the defaults. - -When a query string value is redacted, the query string key SHOULD still be preserved, e.g. -`q=OpenTelemetry&sig=REDACTED`. -""" - -URL_SCHEME: Final = "url.scheme" -""" -The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py deleted file mode 100644 index 6d7e44f2a8d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/attributes/user_agent_attributes.py +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from typing import Final - -USER_AGENT_ORIGINAL: Final = "user_agent.original" -""" -Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py deleted file mode 100644 index 35939f3d263..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/__init__.py +++ /dev/null @@ -1,191 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.typing_extensions import deprecated - - -@deprecated( - "Use metrics defined in the :py:const:`opentelemetry.semconv.metrics` and :py:const:`opentelemetry.semconv._incubating.metrics` modules instead. Deprecated since version 1.25.0.", -) -class MetricInstruments: - SCHEMA_URL = "https://opentelemetry.io/schemas/1.21.0" - """ - The URL of the OpenTelemetry schema for these keys and values. - """ - - HTTP_SERVER_DURATION = "http.server.duration" - """ - Measures the duration of inbound HTTP requests - Instrument: histogram - Unit: s - """ - - HTTP_SERVER_ACTIVE_REQUESTS = "http.server.active_requests" - """ - Measures the number of concurrent HTTP requests that are currently in-flight - Instrument: updowncounter - Unit: {request} - """ - - HTTP_SERVER_REQUEST_SIZE = "http.server.request.size" - """ - Measures the size of HTTP request messages (compressed) - Instrument: histogram - Unit: By - """ - - HTTP_SERVER_RESPONSE_SIZE = "http.server.response.size" - """ - Measures the size of HTTP response messages (compressed) - Instrument: histogram - Unit: By - """ - - HTTP_CLIENT_DURATION = "http.client.duration" - """ - Measures the duration of outbound HTTP requests - Instrument: histogram - Unit: s - """ - - HTTP_CLIENT_REQUEST_SIZE = "http.client.request.size" - """ - Measures the size of HTTP request messages (compressed) - Instrument: histogram - Unit: By - """ - - HTTP_CLIENT_RESPONSE_SIZE = "http.client.response.size" - """ - Measures the size of HTTP response messages (compressed) - Instrument: histogram - Unit: By - """ - - PROCESS_RUNTIME_JVM_MEMORY_INIT = "process.runtime.jvm.memory.init" - """ - Measure of initial memory requested - Instrument: updowncounter - Unit: By - """ - - PROCESS_RUNTIME_JVM_SYSTEM_CPU_UTILIZATION = "process.runtime.jvm.system.cpu.utilization" - """ - Recent CPU utilization for the whole system as reported by the JVM - Instrument: gauge - Unit: 1 - """ - - PROCESS_RUNTIME_JVM_SYSTEM_CPU_LOAD_1M = "process.runtime.jvm.system.cpu.load_1m" - """ - Average CPU load of the whole system for the last minute as reported by the JVM - Instrument: gauge - Unit: 1 - """ - - PROCESS_RUNTIME_JVM_BUFFER_USAGE = "process.runtime.jvm.buffer.usage" - """ - Measure of memory used by buffers - Instrument: updowncounter - Unit: By - """ - - PROCESS_RUNTIME_JVM_BUFFER_LIMIT = "process.runtime.jvm.buffer.limit" - """ - Measure of total memory capacity of buffers - Instrument: updowncounter - Unit: By - """ - - PROCESS_RUNTIME_JVM_BUFFER_COUNT = "process.runtime.jvm.buffer.count" - """ - Number of buffers in the pool - Instrument: updowncounter - Unit: {buffer} - """ - - PROCESS_RUNTIME_JVM_MEMORY_USAGE = "process.runtime.jvm.memory.usage" - """ - Measure of memory used - Instrument: updowncounter - Unit: By - """ - - PROCESS_RUNTIME_JVM_MEMORY_COMMITTED = "process.runtime.jvm.memory.committed" - """ - Measure of memory committed - Instrument: updowncounter - Unit: By - """ - - PROCESS_RUNTIME_JVM_MEMORY_LIMIT = "process.runtime.jvm.memory.limit" - """ - Measure of max obtainable memory - Instrument: updowncounter - Unit: By - """ - - PROCESS_RUNTIME_JVM_MEMORY_USAGE_AFTER_LAST_GC = "process.runtime.jvm.memory.usage_after_last_gc" - """ - Measure of memory used, as measured after the most recent garbage collection event on this pool - Instrument: updowncounter - Unit: By - """ - - PROCESS_RUNTIME_JVM_GC_DURATION = "process.runtime.jvm.gc.duration" - """ - Duration of JVM garbage collection actions - Instrument: histogram - Unit: s - """ - - PROCESS_RUNTIME_JVM_THREADS_COUNT = "process.runtime.jvm.threads.count" - """ - Number of executing platform threads - Instrument: updowncounter - Unit: {thread} - """ - - PROCESS_RUNTIME_JVM_CLASSES_LOADED = "process.runtime.jvm.classes.loaded" - """ - Number of classes loaded since JVM start - Instrument: counter - Unit: {class} - """ - - PROCESS_RUNTIME_JVM_CLASSES_UNLOADED = "process.runtime.jvm.classes.unloaded" - """ - Number of classes unloaded since JVM start - Instrument: counter - Unit: {class} - """ - - PROCESS_RUNTIME_JVM_CLASSES_CURRENT_LOADED = "process.runtime.jvm.classes.current_loaded" - """ - Number of classes currently loaded - Instrument: updowncounter - Unit: {class} - """ - - PROCESS_RUNTIME_JVM_CPU_TIME = "process.runtime.jvm.cpu.time" - """ - CPU time used by the process as reported by the JVM - Instrument: counter - Unit: s - """ - - PROCESS_RUNTIME_JVM_CPU_RECENT_UTILIZATION = "process.runtime.jvm.cpu.recent_utilization" - """ - Recent CPU utilization for the process as reported by the JVM - Instrument: gauge - Unit: 1 - """ - - # Manually defined metrics - - DB_CLIENT_CONNECTIONS_USAGE = "db.client.connections.usage" - """ - The number of connections that are currently in state described by the `state` attribute - Instrument: UpDownCounter - Unit: {connection} - """ diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py deleted file mode 100644 index 60317281ddc..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/db_metrics.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -DB_CLIENT_OPERATION_DURATION: Final = "db.client.operation.duration" -""" -Duration of database client operations -Instrument: histogram -Unit: s -Note: Batch operations SHOULD be recorded as a single operation. -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py deleted file mode 100644 index 924d41d9860..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/metrics/http_metrics.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - - -from typing import Final - -HTTP_CLIENT_REQUEST_DURATION: Final = "http.client.request.duration" -""" -Duration of HTTP client requests -Instrument: histogram -Unit: s -""" - - -HTTP_SERVER_REQUEST_DURATION: Final = "http.server.request.duration" -""" -Duration of HTTP server requests -Instrument: histogram -Unit: s -""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py deleted file mode 100644 index eb12c3e330e..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/resource/__init__.py +++ /dev/null @@ -1,875 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=too-many-lines - -from enum import Enum - -from opentelemetry.agent._vendor.typing_extensions import deprecated - - -@deprecated( - "Use attributes defined in the :py:const:`opentelemetry.semconv.attributes` and :py:const:`opentelemetry.semconv._incubating.attributes` modules instead. Deprecated since version 1.25.0.", -) -class ResourceAttributes: - SCHEMA_URL = "https://opentelemetry.io/schemas/1.21.0" - """ - The URL of the OpenTelemetry schema for these keys and values. - """ - BROWSER_BRANDS = "browser.brands" - """ - Array of brand name and version separated by a space. - Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`). - """ - - BROWSER_PLATFORM = "browser.platform" - """ - The platform on which the browser is running. - Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. - The list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides. - """ - - BROWSER_MOBILE = "browser.mobile" - """ - A boolean that is true if the browser is running on a mobile device. - Note: This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset. - """ - - BROWSER_LANGUAGE = "browser.language" - """ - Preferred language of the user using the browser. - Note: This value is intended to be taken from the Navigator API `navigator.language`. - """ - - USER_AGENT_ORIGINAL = "user_agent.original" - """ - Full user-agent string provided by the browser. - Note: The user-agent value SHOULD be provided only from browsers that do not have a mechanism to retrieve brands and platform individually from the User-Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` API can be used. - """ - - CLOUD_PROVIDER = "cloud.provider" - """ - Name of the cloud provider. - """ - - CLOUD_ACCOUNT_ID = "cloud.account.id" - """ - The cloud account ID the resource is assigned to. - """ - - CLOUD_REGION = "cloud.region" - """ - The geographical region the resource is running. - Note: Refer to your provider's docs to see the available regions, for example [Alibaba Cloud regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), [Google Cloud regions](https://cloud.google.com/about/locations), or [Tencent Cloud regions](https://www.tencentcloud.com/document/product/213/6091). - """ - - CLOUD_RESOURCE_ID = "cloud.resource_id" - """ - Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP). - Note: On some cloud providers, it may not be possible to determine the full ID at startup, - so it may be necessary to set `cloud.resource_id` as a span attribute instead. - - The exact value to use for `cloud.resource_id` depends on the cloud provider. - The following well-known definitions MUST be used if you set this attribute and they apply: - - * **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). - Take care not to use the "invoked ARN" directly but replace any - [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) - with the resolved function version, as the same runtime instance may be invokable with - multiple different aliases. - * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) - * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, - *not* the function app, having the form - `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. - This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share - a TracerProvider. - """ - - CLOUD_AVAILABILITY_ZONE = "cloud.availability_zone" - """ - Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. - Note: Availability zones are called "zones" on Alibaba Cloud and Google Cloud. - """ - - CLOUD_PLATFORM = "cloud.platform" - """ - The cloud platform in use. - Note: The prefix of the service SHOULD match the one specified in `cloud.provider`. - """ - - AWS_ECS_CONTAINER_ARN = "aws.ecs.container.arn" - """ - The Amazon Resource Name (ARN) of an [ECS container instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html). - """ - - AWS_ECS_CLUSTER_ARN = "aws.ecs.cluster.arn" - """ - The ARN of an [ECS cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html). - """ - - AWS_ECS_LAUNCHTYPE = "aws.ecs.launchtype" - """ - The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) for an ECS task. - """ - - AWS_ECS_TASK_ARN = "aws.ecs.task.arn" - """ - The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html). - """ - - AWS_ECS_TASK_FAMILY = "aws.ecs.task.family" - """ - The task definition family this task definition is a member of. - """ - - AWS_ECS_TASK_REVISION = "aws.ecs.task.revision" - """ - The revision for this task definition. - """ - - AWS_EKS_CLUSTER_ARN = "aws.eks.cluster.arn" - """ - The ARN of an EKS cluster. - """ - - AWS_LOG_GROUP_NAMES = "aws.log.group.names" - """ - The name(s) of the AWS log group(s) an application is writing to. - Note: Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. - """ - - AWS_LOG_GROUP_ARNS = "aws.log.group.arns" - """ - The Amazon Resource Name(s) (ARN) of the AWS log group(s). - Note: See the [log group ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). - """ - - AWS_LOG_STREAM_NAMES = "aws.log.stream.names" - """ - The name(s) of the AWS log stream(s) an application is writing to. - """ - - AWS_LOG_STREAM_ARNS = "aws.log.stream.arns" - """ - The ARN(s) of the AWS log stream(s). - Note: See the [log stream ARN format documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format). One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. - """ - - GCP_CLOUD_RUN_JOB_EXECUTION = "gcp.cloud_run.job.execution" - """ - The name of the Cloud Run [execution](https://cloud.google.com/run/docs/managing/job-executions) being run for the Job, as set by the [`CLOUD_RUN_EXECUTION`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. - """ - - GCP_CLOUD_RUN_JOB_TASK_INDEX = "gcp.cloud_run.job.task_index" - """ - The index for a task within an execution as provided by the [`CLOUD_RUN_TASK_INDEX`](https://cloud.google.com/run/docs/container-contract#jobs-env-vars) environment variable. - """ - - GCP_GCE_INSTANCE_NAME = "gcp.gce.instance.name" - """ - The instance name of a GCE instance. This is the value provided by `host.name`, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the [default internal DNS name](https://cloud.google.com/compute/docs/internal-dns#instance-fully-qualified-domain-names). - """ - - GCP_GCE_INSTANCE_HOSTNAME = "gcp.gce.instance.hostname" - """ - The hostname of a GCE instance. This is the full value of the default or [custom hostname](https://cloud.google.com/compute/docs/instances/custom-hostname-vm). - """ - - HEROKU_RELEASE_CREATION_TIMESTAMP = "heroku.release.creation_timestamp" - """ - Time and date the release was created. - """ - - HEROKU_RELEASE_COMMIT = "heroku.release.commit" - """ - Commit hash for the current release. - """ - - HEROKU_APP_ID = "heroku.app.id" - """ - Unique identifier for the application. - """ - - CONTAINER_NAME = "container.name" - """ - Container name used by container runtime. - """ - - CONTAINER_ID = "container.id" - """ - Container ID. Usually a UUID, as for example used to [identify Docker containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID might be abbreviated. - """ - - CONTAINER_RUNTIME = "container.runtime" - """ - The container runtime managing this container. - """ - - CONTAINER_IMAGE_NAME = "container.image.name" - """ - Name of the image the container was built on. - """ - - CONTAINER_IMAGE_TAG = "container.image.tag" - """ - Container image tag. - """ - - CONTAINER_IMAGE_ID = "container.image.id" - """ - Runtime specific image identifier. Usually a hash algorithm followed by a UUID. - Note: Docker defines a sha256 of the image id; `container.image.id` corresponds to the `Image` field from the Docker container inspect [API](https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect) endpoint. - K8s defines a link to the container registry repository with digest `"imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"`. - OCI defines a digest of manifest. - """ - - CONTAINER_COMMAND = "container.command" - """ - The command used to run the container (i.e. the command name). - Note: If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. - """ - - CONTAINER_COMMAND_LINE = "container.command_line" - """ - The full command run by the container as a single string representing the full command. [2]. - """ - - CONTAINER_COMMAND_ARGS = "container.command_args" - """ - All the command arguments (including the command/executable itself) run by the container. [2]. - """ - - DEPLOYMENT_ENVIRONMENT = "deployment.environment" - """ - Name of the [deployment environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka deployment tier). - """ - - DEVICE_ID = "device.id" - """ - A unique identifier representing the device. - Note: The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the [vendor identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor). On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found [here](https://developer.android.com/training/articles/user-data-ids) on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. - """ - - DEVICE_MODEL_IDENTIFIER = "device.model.identifier" - """ - The model identifier for the device. - Note: It's recommended this value represents a machine readable version of the model identifier rather than the market or consumer-friendly name of the device. - """ - - DEVICE_MODEL_NAME = "device.model.name" - """ - The marketing name for the device model. - Note: It's recommended this value represents a human readable version of the device model rather than a machine readable alternative. - """ - - DEVICE_MANUFACTURER = "device.manufacturer" - """ - The name of the device manufacturer. - Note: The Android OS provides this field via [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER). iOS apps SHOULD hardcode the value `Apple`. - """ - - FAAS_NAME = "faas.name" - """ - The name of the single function that this runtime instance executes. - Note: This is the name of the function as configured/deployed on the FaaS - platform and is usually different from the name of the callback - function (which may be stored in the - [`code.namespace`/`code.function`](/docs/general/general-attributes.md#source-code-attributes) - span attributes). - - For some cloud providers, the above definition is ambiguous. The following - definition of function name MUST be used for this attribute - (and consequently the span name) for the listed cloud providers/products: - - * **Azure:** The full name `/`, i.e., function app name - followed by a forward slash followed by the function name (this form - can also be seen in the resource JSON for the function). - This means that a span attribute MUST be used, as an Azure function - app can host multiple functions that would usually share - a TracerProvider (see also the `cloud.resource_id` attribute). - """ - - FAAS_VERSION = "faas.version" - """ - The immutable version of the function being executed. - Note: Depending on the cloud provider and platform, use: - - * **AWS Lambda:** The [function version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html) - (an integer represented as a decimal string). - * **Google Cloud Run (Services):** The [revision](https://cloud.google.com/run/docs/managing/revisions) - (i.e., the function name plus the revision suffix). - * **Google Cloud Functions:** The value of the - [`K_REVISION` environment variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically). - * **Azure Functions:** Not applicable. Do not set this attribute. - """ - - FAAS_INSTANCE = "faas.instance" - """ - The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. - Note: * **AWS Lambda:** Use the (full) log stream name. - """ - - FAAS_MAX_MEMORY = "faas.max_memory" - """ - The amount of memory available to the serverless function converted to Bytes. - Note: It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information (which must be multiplied by 1,048,576). - """ - - HOST_ID = "host.id" - """ - Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the `machine-id`. See the table below for the sources to use to determine the `machine-id` based on operating system. - """ - - HOST_NAME = "host.name" - """ - Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. - """ - - HOST_TYPE = "host.type" - """ - Type of host. For Cloud, this must be the machine type. - """ - - HOST_ARCH = "host.arch" - """ - The CPU architecture the host system is running on. - """ - - HOST_IMAGE_NAME = "host.image.name" - """ - Name of the VM image or OS install the host was instantiated from. - """ - - HOST_IMAGE_ID = "host.image.id" - """ - VM image ID or host OS image ID. For Cloud, this value is from the provider. - """ - - HOST_IMAGE_VERSION = "host.image.version" - """ - The version string of the VM image or host OS as defined in [Version Attributes](README.md#version-attributes). - """ - - K8S_CLUSTER_NAME = "k8s.cluster.name" - """ - The name of the cluster. - """ - - K8S_CLUSTER_UID = "k8s.cluster.uid" - """ - A pseudo-ID for the cluster, set to the UID of the `kube-system` namespace. - Note: K8s does not have support for obtaining a cluster ID. If this is ever - added, we will recommend collecting the `k8s.cluster.uid` through the - official APIs. In the meantime, we are able to use the `uid` of the - `kube-system` namespace as a proxy for cluster ID. Read on for the - rationale. - - Every object created in a K8s cluster is assigned a distinct UID. The - `kube-system` namespace is used by Kubernetes itself and will exist - for the lifetime of the cluster. Using the `uid` of the `kube-system` - namespace is a reasonable proxy for the K8s ClusterID as it will only - change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are - UUIDs as standardized by - [ISO/IEC 9834-8 and ITU-T X.667](https://www.itu.int/ITU-T/studygroups/com17/oid.html). - Which states: - - > If generated according to one of the mechanisms defined in Rec. - ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be - different from all other UUIDs generated before 3603 A.D., or is - extremely likely to be different (depending on the mechanism chosen). - - Therefore, UIDs between clusters should be extremely unlikely to - conflict. - """ - - K8S_NODE_NAME = "k8s.node.name" - """ - The name of the Node. - """ - - K8S_NODE_UID = "k8s.node.uid" - """ - The UID of the Node. - """ - - K8S_NAMESPACE_NAME = "k8s.namespace.name" - """ - The name of the namespace that the pod is running in. - """ - - K8S_POD_UID = "k8s.pod.uid" - """ - The UID of the Pod. - """ - - K8S_POD_NAME = "k8s.pod.name" - """ - The name of the Pod. - """ - - K8S_CONTAINER_NAME = "k8s.container.name" - """ - The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (`container.name`). - """ - - K8S_CONTAINER_RESTART_COUNT = "k8s.container.restart_count" - """ - Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. - """ - - K8S_REPLICASET_UID = "k8s.replicaset.uid" - """ - The UID of the ReplicaSet. - """ - - K8S_REPLICASET_NAME = "k8s.replicaset.name" - """ - The name of the ReplicaSet. - """ - - K8S_DEPLOYMENT_UID = "k8s.deployment.uid" - """ - The UID of the Deployment. - """ - - K8S_DEPLOYMENT_NAME = "k8s.deployment.name" - """ - The name of the Deployment. - """ - - K8S_STATEFULSET_UID = "k8s.statefulset.uid" - """ - The UID of the StatefulSet. - """ - - K8S_STATEFULSET_NAME = "k8s.statefulset.name" - """ - The name of the StatefulSet. - """ - - K8S_DAEMONSET_UID = "k8s.daemonset.uid" - """ - The UID of the DaemonSet. - """ - - K8S_DAEMONSET_NAME = "k8s.daemonset.name" - """ - The name of the DaemonSet. - """ - - K8S_JOB_UID = "k8s.job.uid" - """ - The UID of the Job. - """ - - K8S_JOB_NAME = "k8s.job.name" - """ - The name of the Job. - """ - - K8S_CRONJOB_UID = "k8s.cronjob.uid" - """ - The UID of the CronJob. - """ - - K8S_CRONJOB_NAME = "k8s.cronjob.name" - """ - The name of the CronJob. - """ - - OS_TYPE = "os.type" - """ - The operating system type. - """ - - OS_DESCRIPTION = "os.description" - """ - Human readable (not intended to be parsed) OS version information, like e.g. reported by `ver` or `lsb_release -a` commands. - """ - - OS_NAME = "os.name" - """ - Human readable operating system name. - """ - - OS_VERSION = "os.version" - """ - The version string of the operating system as defined in [Version Attributes](/docs/resource/README.md#version-attributes). - """ - - PROCESS_PID = "process.pid" - """ - Process identifier (PID). - """ - - PROCESS_PARENT_PID = "process.parent_pid" - """ - Parent Process identifier (PID). - """ - - PROCESS_EXECUTABLE_NAME = "process.executable.name" - """ - The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. - """ - - PROCESS_EXECUTABLE_PATH = "process.executable.path" - """ - The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. - """ - - PROCESS_COMMAND = "process.command" - """ - The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. - """ - - PROCESS_COMMAND_LINE = "process.command_line" - """ - The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. - """ - - PROCESS_COMMAND_ARGS = "process.command_args" - """ - All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. - """ - - PROCESS_OWNER = "process.owner" - """ - The username of the user that owns the process. - """ - - PROCESS_RUNTIME_NAME = "process.runtime.name" - """ - The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. - """ - - PROCESS_RUNTIME_VERSION = "process.runtime.version" - """ - The version of the runtime of this process, as returned by the runtime without modification. - """ - - PROCESS_RUNTIME_DESCRIPTION = "process.runtime.description" - """ - An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. - """ - - SERVICE_NAME = "service.name" - """ - Logical name of the service. - Note: MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to `unknown_service:` concatenated with [`process.executable.name`](process.md#process), e.g. `unknown_service:bash`. If `process.executable.name` is not available, the value MUST be set to `unknown_service`. - """ - - SERVICE_VERSION = "service.version" - """ - The version string of the service API or implementation. The format is not defined by these conventions. - """ - - SERVICE_NAMESPACE = "service.namespace" - """ - A namespace for `service.name`. - Note: A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. `service.name` is expected to be unique within the same namespace. If `service.namespace` is not specified in the Resource then `service.name` is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. - """ - - SERVICE_INSTANCE_ID = "service.instance.id" - """ - The string ID of the service instance. - Note: MUST be unique for each instance of the same `service.namespace,service.name` pair (in other words `service.namespace,service.name,service.instance.id` triplet MUST be globally unique). The ID helps to distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled service). It is preferable for the ID to be persistent and stay the same for the lifetime of the service instance, however it is acceptable that the ID is ephemeral and changes during important lifetime events for the service (e.g. service restarts). If the service has no inherent unique ID that can be used as the value of this attribute it is recommended to generate a random Version 1 or Version 4 RFC 4122 UUID (services aiming for reproducible UUIDs may also use Version 5, see RFC 4122 for more recommendations). - """ - - TELEMETRY_SDK_NAME = "telemetry.sdk.name" - """ - The name of the telemetry SDK as defined above. - Note: The OpenTelemetry SDK MUST set the `telemetry.sdk.name` attribute to `opentelemetry`. - If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the - `telemetry.sdk.name` attribute to the fully-qualified class or module name of this SDK's main entry point - or another suitable identifier depending on the language. - The identifier `opentelemetry` is reserved and MUST NOT be used in this case. - All custom identifiers SHOULD be stable across different versions of an implementation. - """ - - TELEMETRY_SDK_LANGUAGE = "telemetry.sdk.language" - """ - The language of the telemetry SDK. - """ - - TELEMETRY_SDK_VERSION = "telemetry.sdk.version" - """ - The version string of the telemetry SDK. - """ - - TELEMETRY_AUTO_VERSION = "telemetry.auto.version" - """ - The version string of the auto instrumentation agent, if used. - """ - - WEBENGINE_NAME = "webengine.name" - """ - The name of the web engine. - """ - - WEBENGINE_VERSION = "webengine.version" - """ - The version of the web engine. - """ - - WEBENGINE_DESCRIPTION = "webengine.description" - """ - Additional description of the web engine (e.g. detailed version and edition information). - """ - - OTEL_SCOPE_NAME = "otel.scope.name" - """ - The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). - """ - - OTEL_SCOPE_VERSION = "otel.scope.version" - """ - The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). - """ - - OTEL_LIBRARY_NAME = "otel.library.name" - """ - Deprecated, use the `otel.scope.name` attribute. - """ - - OTEL_LIBRARY_VERSION = "otel.library.version" - """ - Deprecated, use the `otel.scope.version` attribute. - """ - - # Manually defined deprecated attributes - - FAAS_ID = "faas.id" - """ - Deprecated, use the `cloud.resource.id` attribute. - """ - - -@deprecated( - "Use :py:const:`opentelemetry.semconv._incubating.attributes.CloudProviderValues` instead. Deprecated since version 1.25.0.", -) -class CloudProviderValues(Enum): - ALIBABA_CLOUD = "alibaba_cloud" - """Alibaba Cloud.""" - - AWS = "aws" - """Amazon Web Services.""" - - AZURE = "azure" - """Microsoft Azure.""" - - GCP = "gcp" - """Google Cloud Platform.""" - - HEROKU = "heroku" - """Heroku Platform as a Service.""" - - IBM_CLOUD = "ibm_cloud" - """IBM Cloud.""" - - TENCENT_CLOUD = "tencent_cloud" - """Tencent Cloud.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv._incubating.attributes.CloudPlatformValues` instead. Deprecated since version 1.25.0.", -) -class CloudPlatformValues(Enum): - ALIBABA_CLOUD_ECS = "alibaba_cloud_ecs" - """Alibaba Cloud Elastic Compute Service.""" - - ALIBABA_CLOUD_FC = "alibaba_cloud_fc" - """Alibaba Cloud Function Compute.""" - - ALIBABA_CLOUD_OPENSHIFT = "alibaba_cloud_openshift" - """Red Hat OpenShift on Alibaba Cloud.""" - - AWS_EC2 = "aws_ec2" - """AWS Elastic Compute Cloud.""" - - AWS_ECS = "aws_ecs" - """AWS Elastic Container Service.""" - - AWS_EKS = "aws_eks" - """AWS Elastic Kubernetes Service.""" - - AWS_LAMBDA = "aws_lambda" - """AWS Lambda.""" - - AWS_ELASTIC_BEANSTALK = "aws_elastic_beanstalk" - """AWS Elastic Beanstalk.""" - - AWS_APP_RUNNER = "aws_app_runner" - """AWS App Runner.""" - - AWS_OPENSHIFT = "aws_openshift" - """Red Hat OpenShift on AWS (ROSA).""" - - AZURE_VM = "azure_vm" - """Azure Virtual Machines.""" - - AZURE_CONTAINER_INSTANCES = "azure_container_instances" - """Azure Container Instances.""" - - AZURE_AKS = "azure_aks" - """Azure Kubernetes Service.""" - - AZURE_FUNCTIONS = "azure_functions" - """Azure Functions.""" - - AZURE_APP_SERVICE = "azure_app_service" - """Azure App Service.""" - - AZURE_OPENSHIFT = "azure_openshift" - """Azure Red Hat OpenShift.""" - - GCP_BARE_METAL_SOLUTION = "gcp_bare_metal_solution" - """Google Bare Metal Solution (BMS).""" - - GCP_COMPUTE_ENGINE = "gcp_compute_engine" - """Google Cloud Compute Engine (GCE).""" - - GCP_CLOUD_RUN = "gcp_cloud_run" - """Google Cloud Run.""" - - GCP_KUBERNETES_ENGINE = "gcp_kubernetes_engine" - """Google Cloud Kubernetes Engine (GKE).""" - - GCP_CLOUD_FUNCTIONS = "gcp_cloud_functions" - """Google Cloud Functions (GCF).""" - - GCP_APP_ENGINE = "gcp_app_engine" - """Google Cloud App Engine (GAE).""" - - GCP_OPENSHIFT = "gcp_openshift" - """Red Hat OpenShift on Google Cloud.""" - - IBM_CLOUD_OPENSHIFT = "ibm_cloud_openshift" - """Red Hat OpenShift on IBM Cloud.""" - - TENCENT_CLOUD_CVM = "tencent_cloud_cvm" - """Tencent Cloud Cloud Virtual Machine (CVM).""" - - TENCENT_CLOUD_EKS = "tencent_cloud_eks" - """Tencent Cloud Elastic Kubernetes Service (EKS).""" - - TENCENT_CLOUD_SCF = "tencent_cloud_scf" - """Tencent Cloud Serverless Cloud Function (SCF).""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv._incubating.attributes.AwsEcsLaunchtypeValues` instead. Deprecated since version 1.25.0.", -) -class AwsEcsLaunchtypeValues(Enum): - EC2 = "ec2" - """ec2.""" - - FARGATE = "fargate" - """fargate.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv._incubating.attributes.HostArchValues` instead. Deprecated since version 1.25.0.", -) -class HostArchValues(Enum): - AMD64 = "amd64" - """AMD64.""" - - ARM32 = "arm32" - """ARM32.""" - - ARM64 = "arm64" - """ARM64.""" - - IA64 = "ia64" - """Itanium.""" - - PPC32 = "ppc32" - """32-bit PowerPC.""" - - PPC64 = "ppc64" - """64-bit PowerPC.""" - - S390X = "s390x" - """IBM z/Architecture.""" - - X86 = "x86" - """32-bit x86.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv._incubating.attributes.OsTypeValues` instead. Deprecated since version 1.25.0.", -) -class OsTypeValues(Enum): - WINDOWS = "windows" - """Microsoft Windows.""" - - LINUX = "linux" - """Linux.""" - - DARWIN = "darwin" - """Apple Darwin.""" - - FREEBSD = "freebsd" - """FreeBSD.""" - - NETBSD = "netbsd" - """NetBSD.""" - - OPENBSD = "openbsd" - """OpenBSD.""" - - DRAGONFLYBSD = "dragonflybsd" - """DragonFly BSD.""" - - HPUX = "hpux" - """HP-UX (Hewlett Packard Unix).""" - - AIX = "aix" - """AIX (Advanced Interactive eXecutive).""" - - SOLARIS = "solaris" - """SunOS, Oracle Solaris.""" - - Z_OS = "z_os" - """IBM z/OS.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv.attributes.TelemetrySdkLanguageValues` instead. Deprecated since version 1.25.0.", -) -class TelemetrySdkLanguageValues(Enum): - CPP = "cpp" - """cpp.""" - - DOTNET = "dotnet" - """dotnet.""" - - ERLANG = "erlang" - """erlang.""" - - GO = "go" - """go.""" - - JAVA = "java" - """java.""" - - NODEJS = "nodejs" - """nodejs.""" - - PHP = "php" - """php.""" - - PYTHON = "python" - """python.""" - - RUBY = "ruby" - """ruby.""" - - RUST = "rust" - """rust.""" - - SWIFT = "swift" - """swift.""" - - WEBJS = "webjs" - """webjs.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py deleted file mode 100644 index 01c01f7bd2d..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/schemas.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from enum import Enum - - -class Schemas(Enum): - V1_21_0 = "https://opentelemetry.io/schemas/1.21.0" - """ - The URL of the OpenTelemetry schema version 1.21.0. - """ - - V1_23_1 = "https://opentelemetry.io/schemas/1.23.1" - """ - The URL of the OpenTelemetry schema version 1.23.1. - """ - - V1_25_0 = "https://opentelemetry.io/schemas/1.25.0" - """ - The URL of the OpenTelemetry schema version 1.25.0. - """ - - V1_26_0 = "https://opentelemetry.io/schemas/1.26.0" - """ - The URL of the OpenTelemetry schema version 1.26.0. - """ - - V1_27_0 = "https://opentelemetry.io/schemas/1.27.0" - """ - The URL of the OpenTelemetry schema version 1.27.0. - """ - - V1_28_0 = "https://opentelemetry.io/schemas/1.28.0" - """ - The URL of the OpenTelemetry schema version 1.28.0. - """ - - V1_29_0 = "https://opentelemetry.io/schemas/1.29.0" - """ - The URL of the OpenTelemetry schema version 1.29.0. - """ - - V1_30_0 = "https://opentelemetry.io/schemas/1.30.0" - """ - The URL of the OpenTelemetry schema version 1.30.0. - """ - - V1_31_0 = "https://opentelemetry.io/schemas/1.31.0" - """ - The URL of the OpenTelemetry schema version 1.31.0. - """ - - V1_32_0 = "https://opentelemetry.io/schemas/1.32.0" - """ - The URL of the OpenTelemetry schema version 1.32.0. - """ - - V1_33_0 = "https://opentelemetry.io/schemas/1.33.0" - """ - The URL of the OpenTelemetry schema version 1.33.0. - """ - - V1_34_0 = "https://opentelemetry.io/schemas/1.34.0" - """ - The URL of the OpenTelemetry schema version 1.34.0. - """ - V1_36_0 = "https://opentelemetry.io/schemas/1.36.0" - """ - The URL of the OpenTelemetry schema version 1.36.0. - """ - - V1_37_0 = "https://opentelemetry.io/schemas/1.37.0" - """ - The URL of the OpenTelemetry schema version 1.37.0. - """ - - V1_38_0 = "https://opentelemetry.io/schemas/1.38.0" - """ - The URL of the OpenTelemetry schema version 1.38.0. - """ - - V1_39_0 = "https://opentelemetry.io/schemas/1.39.0" - """ - The URL of the OpenTelemetry schema version 1.39.0. - """ - - V1_40_0 = "https://opentelemetry.io/schemas/1.40.0" - """ - The URL of the OpenTelemetry schema version 1.40.0. - """ - - V1_41_0 = "https://opentelemetry.io/schemas/1.41.0" - """ - The URL of the OpenTelemetry schema version 1.41.0. - """ - - V1_41_1 = "https://opentelemetry.io/schemas/1.41.1" - """ - The URL of the OpenTelemetry schema version 1.41.1. - """ - - V1_42_0 = "https://opentelemetry.io/schemas/1.42.0" - """ - The URL of the OpenTelemetry schema version 1.42.0. - """ - - V1_43_0 = "https://opentelemetry.io/schemas/1.43.0" - """ - The URL of the OpenTelemetry schema version 1.43.0. - """ - - V1_44_0 = "https://opentelemetry.io/schemas/1.44.0" - """ - The URL of the OpenTelemetry schema version 1.44.0. - """ - - # when generating new semantic conventions, - # make sure to add new versions version here. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py deleted file mode 100644 index 48e4ba1be84..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/trace/__init__.py +++ /dev/null @@ -1,2164 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -# pylint: disable=too-many-lines - -from enum import Enum - -from opentelemetry.agent._vendor.typing_extensions import deprecated - - -@deprecated( - "Use attributes defined in the :py:const:`opentelemetry.semconv.attributes` and :py:const:`opentelemetry.semconv._incubating.attributes` modules instead. Deprecated since version 1.25.0.", -) -class SpanAttributes: - SCHEMA_URL = "https://opentelemetry.io/schemas/1.21.0" - """ - The URL of the OpenTelemetry schema for these keys and values. - """ - CLIENT_ADDRESS = "client.address" - """ - Client address - unix domain socket name, IPv4 or IPv6 address. - Note: When observed from the server side, and when communicating through an intermediary, `client.address` SHOULD represent client address behind any intermediaries (e.g. proxies) if it's available. - """ - - CLIENT_PORT = "client.port" - """ - Client port number. - Note: When observed from the server side, and when communicating through an intermediary, `client.port` SHOULD represent client port behind any intermediaries (e.g. proxies) if it's available. - """ - - CLIENT_SOCKET_ADDRESS = "client.socket.address" - """ - Immediate client peer address - unix domain socket name, IPv4 or IPv6 address. - """ - - CLIENT_SOCKET_PORT = "client.socket.port" - """ - Immediate client peer port number. - """ - - HTTP_METHOD = "http.method" - """ - Deprecated, use `http.request.method` instead. - """ - - HTTP_STATUS_CODE = "http.status_code" - """ - Deprecated, use `http.response.status_code` instead. - """ - - HTTP_SCHEME = "http.scheme" - """ - Deprecated, use `url.scheme` instead. - """ - - HTTP_URL = "http.url" - """ - Deprecated, use `url.full` instead. - """ - - HTTP_TARGET = "http.target" - """ - Deprecated, use `url.path` and `url.query` instead. - """ - - HTTP_REQUEST_CONTENT_LENGTH = "http.request_content_length" - """ - Deprecated, use `http.request.body.size` instead. - """ - - HTTP_RESPONSE_CONTENT_LENGTH = "http.response_content_length" - """ - Deprecated, use `http.response.body.size` instead. - """ - - NET_SOCK_PEER_NAME = "net.sock.peer.name" - """ - Deprecated, use `server.socket.domain` on client spans. - """ - - NET_SOCK_PEER_ADDR = "net.sock.peer.addr" - """ - Deprecated, use `server.socket.address` on client spans and `client.socket.address` on server spans. - """ - - NET_SOCK_PEER_PORT = "net.sock.peer.port" - """ - Deprecated, use `server.socket.port` on client spans and `client.socket.port` on server spans. - """ - - NET_PEER_NAME = "net.peer.name" - """ - Deprecated, use `server.address` on client spans and `client.address` on server spans. - """ - - NET_PEER_PORT = "net.peer.port" - """ - Deprecated, use `server.port` on client spans and `client.port` on server spans. - """ - - NET_HOST_NAME = "net.host.name" - """ - Deprecated, use `server.address`. - """ - - NET_HOST_PORT = "net.host.port" - """ - Deprecated, use `server.port`. - """ - - NET_SOCK_HOST_ADDR = "net.sock.host.addr" - """ - Deprecated, use `server.socket.address`. - """ - - NET_SOCK_HOST_PORT = "net.sock.host.port" - """ - Deprecated, use `server.socket.port`. - """ - - NET_TRANSPORT = "net.transport" - """ - Deprecated, use `network.transport`. - """ - - NET_PROTOCOL_NAME = "net.protocol.name" - """ - Deprecated, use `network.protocol.name`. - """ - - NET_PROTOCOL_VERSION = "net.protocol.version" - """ - Deprecated, use `network.protocol.version`. - """ - - NET_SOCK_FAMILY = "net.sock.family" - """ - Deprecated, use `network.transport` and `network.type`. - """ - - DESTINATION_DOMAIN = "destination.domain" - """ - The domain name of the destination system. - Note: This value may be a host name, a fully qualified domain name, or another host naming format. - """ - - DESTINATION_ADDRESS = "destination.address" - """ - Peer address, for example IP address or UNIX socket name. - """ - - DESTINATION_PORT = "destination.port" - """ - Peer port number. - """ - - EXCEPTION_TYPE = "exception.type" - """ - The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. - """ - - EXCEPTION_MESSAGE = "exception.message" - """ - The exception message. - """ - - EXCEPTION_STACKTRACE = "exception.stacktrace" - """ - A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. - """ - - HTTP_REQUEST_METHOD = "http.request.method" - """ - HTTP request method. - Note: HTTP request method value SHOULD be "known" to the instrumentation. - By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) - and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). - - If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER` and, except if reporting a metric, MUST - set the exact method received in the request line as value of the `http.request.method_original` attribute. - - If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override - the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named - OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods - (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). - - HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. - Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. - Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. - """ - - HTTP_RESPONSE_STATUS_CODE = "http.response.status_code" - """ - [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). - """ - - NETWORK_PROTOCOL_NAME = "network.protocol.name" - """ - [OSI Application Layer](https://osi-model.com/application-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. - """ - - NETWORK_PROTOCOL_VERSION = "network.protocol.version" - """ - Version of the application layer protocol used. See note below. - Note: `network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client used has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`. - """ - - SERVER_ADDRESS = "server.address" - """ - Host identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. - Note: Determined by using the first of the following that applies - - - Host identifier of the [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) - if it's sent in absolute-form - - Host identifier of the `Host` header - - SHOULD NOT be set if capturing it would require an extra DNS lookup. - """ - - SERVER_PORT = "server.port" - """ - Port identifier of the ["URI origin"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to. - Note: When [request target](https://www.rfc-editor.org/rfc/rfc9110.html#target.resource) is absolute URI, `server.port` MUST match URI port identifier, otherwise it MUST match `Host` header port identifier. - """ - - HTTP_ROUTE = "http.route" - """ - The matched route (path template in the format used by the respective server framework). See note below. - Note: MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. - SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. - """ - - URL_SCHEME = "url.scheme" - """ - The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. - """ - - EVENT_NAME = "event.name" - """ - The name identifies the event. - """ - - EVENT_DOMAIN = "event.domain" - """ - The domain identifies the business context for the events. - Note: Events across different domains may have same `event.name`, yet be - unrelated events. - """ - - LOG_RECORD_UID = "log.record.uid" - """ - A unique identifier for the Log Record. - Note: If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. - The id MAY be an [Universally Unique Lexicographically Sortable Identifier (ULID)](https://github.com/ulid/spec), but other identifiers (e.g. UUID) may be used as needed. - """ - - FEATURE_FLAG_KEY = "feature_flag.key" - """ - The unique identifier of the feature flag. - """ - - FEATURE_FLAG_PROVIDER_NAME = "feature_flag.provider_name" - """ - The name of the service provider that performs the flag evaluation. - """ - - FEATURE_FLAG_VARIANT = "feature_flag.variant" - """ - SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. - Note: A semantic identifier, commonly referred to as a variant, provides a means - for referring to a value without including the value itself. This can - provide additional context for understanding the meaning behind a value. - For example, the variant `red` maybe be used for the value `#c05543`. - - A stringified version of the value can be used in situations where a - semantic identifier is unavailable. String representation of the value - should be determined by the implementer. - """ - - LOG_IOSTREAM = "log.iostream" - """ - The stream associated with the log. See below for a list of well-known values. - """ - - LOG_FILE_NAME = "log.file.name" - """ - The basename of the file. - """ - - LOG_FILE_PATH = "log.file.path" - """ - The full path to the file. - """ - - LOG_FILE_NAME_RESOLVED = "log.file.name_resolved" - """ - The basename of the file, with symlinks resolved. - """ - - LOG_FILE_PATH_RESOLVED = "log.file.path_resolved" - """ - The full path to the file, with symlinks resolved. - """ - - SERVER_SOCKET_ADDRESS = "server.socket.address" - """ - Physical server IP address or Unix socket address. If set from the client, should simply use the socket's peer address, and not attempt to find any actual server IP (i.e., if set from client, this may represent some proxy server instead of the logical server). - """ - - POOL = "pool" - """ - Name of the buffer pool. - Note: Pool names are generally obtained via [BufferPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/BufferPoolMXBean.html#getName()). - """ - - TYPE = "type" - """ - The type of memory. - """ - - SERVER_SOCKET_DOMAIN = "server.socket.domain" - """ - The domain name of an immediate peer. - Note: Typically observed from the client side, and represents a proxy or other intermediary domain name. - """ - - SERVER_SOCKET_PORT = "server.socket.port" - """ - Physical server port. - """ - - SOURCE_DOMAIN = "source.domain" - """ - The domain name of the source system. - Note: This value may be a host name, a fully qualified domain name, or another host naming format. - """ - - SOURCE_ADDRESS = "source.address" - """ - Source address, for example IP address or Unix socket name. - """ - - SOURCE_PORT = "source.port" - """ - Source port number. - """ - - AWS_LAMBDA_INVOKED_ARN = "aws.lambda.invoked_arn" - """ - The full invoked ARN as provided on the `Context` passed to the function (`Lambda-Runtime-Invoked-Function-Arn` header on the `/runtime/invocation/next` applicable). - Note: This may be different from `cloud.resource_id` if an alias is involved. - """ - - CLOUDEVENTS_EVENT_ID = "cloudevents.event_id" - """ - The [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id) uniquely identifies the event. - """ - - CLOUDEVENTS_EVENT_SOURCE = "cloudevents.event_source" - """ - The [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1) identifies the context in which an event happened. - """ - - CLOUDEVENTS_EVENT_SPEC_VERSION = "cloudevents.event_spec_version" - """ - The [version of the CloudEvents specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion) which the event uses. - """ - - CLOUDEVENTS_EVENT_TYPE = "cloudevents.event_type" - """ - The [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type) contains a value describing the type of event related to the originating occurrence. - """ - - CLOUDEVENTS_EVENT_SUBJECT = "cloudevents.event_subject" - """ - The [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject) of the event in the context of the event producer (identified by source). - """ - - OPENTRACING_REF_TYPE = "opentracing.ref_type" - """ - Parent-child Reference type. - Note: The causal relationship between a child Span and a parent Span. - """ - - DB_SYSTEM = "db.system" - """ - An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. - """ - - DB_CONNECTION_STRING = "db.connection_string" - """ - The connection string used to connect to the database. It is recommended to remove embedded credentials. - """ - - DB_USER = "db.user" - """ - Username for accessing the database. - """ - - DB_JDBC_DRIVER_CLASSNAME = "db.jdbc.driver_classname" - """ - The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect. - """ - - DB_NAME = "db.name" - """ - This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). - Note: In some SQL databases, the database name to be used is called "schema name". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). - """ - - DB_STATEMENT = "db.statement" - """ - The database statement being executed. - """ - - DB_OPERATION = "db.operation" - """ - The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword. - Note: When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. - """ - - NETWORK_TRANSPORT = "network.transport" - """ - [OSI Transport Layer](https://osi-model.com/transport-layer/) or [Inter-process Communication method](https://en.wikipedia.org/wiki/Inter-process_communication). The value SHOULD be normalized to lowercase. - """ - - NETWORK_TYPE = "network.type" - """ - [OSI Network Layer](https://osi-model.com/network-layer/) or non-OSI equivalent. The value SHOULD be normalized to lowercase. - """ - - DB_MSSQL_INSTANCE_NAME = "db.mssql.instance_name" - """ - The Microsoft SQL Server [instance name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance. - Note: If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). - """ - - DB_CASSANDRA_PAGE_SIZE = "db.cassandra.page_size" - """ - The fetch size used for paging, i.e. how many rows will be returned at once. - """ - - DB_CASSANDRA_CONSISTENCY_LEVEL = "db.cassandra.consistency_level" - """ - The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html). - """ - - DB_CASSANDRA_TABLE = "db.cassandra.table" - """ - The name of the primary table that the operation is acting upon, including the keyspace name (if applicable). - Note: This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. - """ - - DB_CASSANDRA_IDEMPOTENCE = "db.cassandra.idempotence" - """ - Whether or not the query is idempotent. - """ - - DB_CASSANDRA_SPECULATIVE_EXECUTION_COUNT = "db.cassandra.speculative_execution_count" - """ - The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. - """ - - DB_CASSANDRA_COORDINATOR_ID = "db.cassandra.coordinator.id" - """ - The ID of the coordinating node for a query. - """ - - DB_CASSANDRA_COORDINATOR_DC = "db.cassandra.coordinator.dc" - """ - The data center of the coordinating node for a query. - """ - - DB_REDIS_DATABASE_INDEX = "db.redis.database_index" - """ - The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute. - """ - - DB_MONGODB_COLLECTION = "db.mongodb.collection" - """ - The collection being accessed within the database stated in `db.name`. - """ - - URL_FULL = "url.full" - """ - Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). - Note: For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. - `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password should be redacted and attribute's value should be `https://REDACTED:REDACTED@www.example.com/`. - `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. - """ - - DB_SQL_TABLE = "db.sql.table" - """ - The name of the primary table that the operation is acting upon, including the database name (if applicable). - Note: It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. - """ - - DB_COSMOSDB_CLIENT_ID = "db.cosmosdb.client_id" - """ - Unique Cosmos client instance id. - """ - - DB_COSMOSDB_OPERATION_TYPE = "db.cosmosdb.operation_type" - """ - CosmosDB Operation Type. - """ - - USER_AGENT_ORIGINAL = "user_agent.original" - """ - Full user-agent string is generated by Cosmos DB SDK. - Note: The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled. - Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). - Default value is "NS". - """ - - DB_COSMOSDB_CONNECTION_MODE = "db.cosmosdb.connection_mode" - """ - Cosmos client connection mode. - """ - - DB_COSMOSDB_CONTAINER = "db.cosmosdb.container" - """ - Cosmos DB container name. - """ - - DB_COSMOSDB_REQUEST_CONTENT_LENGTH = "db.cosmosdb.request_content_length" - """ - Request payload size in bytes. - """ - - DB_COSMOSDB_STATUS_CODE = "db.cosmosdb.status_code" - """ - Cosmos DB status code. - """ - - DB_COSMOSDB_SUB_STATUS_CODE = "db.cosmosdb.sub_status_code" - """ - Cosmos DB sub status code. - """ - - DB_COSMOSDB_REQUEST_CHARGE = "db.cosmosdb.request_charge" - """ - RU consumed for that operation. - """ - - OTEL_STATUS_CODE = "otel.status_code" - """ - Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. - """ - - OTEL_STATUS_DESCRIPTION = "otel.status_description" - """ - Description of the Status if it has a value, otherwise not set. - """ - - FAAS_TRIGGER = "faas.trigger" - """ - Type of the trigger which caused this function invocation. - Note: For the server/consumer span on the incoming side, - `faas.trigger` MUST be set. - - Clients invoking FaaS instances usually cannot set `faas.trigger`, - since they would typically need to look in the payload to determine - the event type. If clients set it, it should be the same as the - trigger that corresponding incoming would have (i.e., this has - nothing to do with the underlying transport used to make the API - call to invoke the lambda, which is often HTTP). - """ - - FAAS_INVOCATION_ID = "faas.invocation_id" - """ - The invocation ID of the current function invocation. - """ - - CLOUD_RESOURCE_ID = "cloud.resource_id" - """ - Cloud provider-specific native identifier of the monitored cloud resource (e.g. an [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) on AWS, a [fully qualified resource ID](https://learn.microsoft.com/en-us/rest/api/resources/resources/get-by-id) on Azure, a [full resource name](https://cloud.google.com/apis/design/resource_names#full_resource_name) on GCP). - Note: On some cloud providers, it may not be possible to determine the full ID at startup, - so it may be necessary to set `cloud.resource_id` as a span attribute instead. - - The exact value to use for `cloud.resource_id` depends on the cloud provider. - The following well-known definitions MUST be used if you set this attribute and they apply: - - * **AWS Lambda:** The function [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). - Take care not to use the "invoked ARN" directly but replace any - [alias suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) - with the resolved function version, as the same runtime instance may be invokable with - multiple different aliases. - * **GCP:** The [URI of the resource](https://cloud.google.com/iam/docs/full-resource-names) - * **Azure:** The [Fully Qualified Resource ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id) of the invoked function, - *not* the function app, having the form - `/subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/`. - This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share - a TracerProvider. - """ - - FAAS_DOCUMENT_COLLECTION = "faas.document.collection" - """ - The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. - """ - - FAAS_DOCUMENT_OPERATION = "faas.document.operation" - """ - Describes the type of the operation that was performed on the data. - """ - - FAAS_DOCUMENT_TIME = "faas.document.time" - """ - A string containing the time when the data was accessed in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). - """ - - FAAS_DOCUMENT_NAME = "faas.document.name" - """ - The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. - """ - - URL_PATH = "url.path" - """ - The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component. - Note: When missing, the value is assumed to be `/`. - """ - - URL_QUERY = "url.query" - """ - The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component. - Note: Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. - """ - - MESSAGING_SYSTEM = "messaging.system" - """ - A string identifying the messaging system. - """ - - MESSAGING_OPERATION = "messaging.operation" - """ - A string identifying the kind of messaging operation as defined in the [Operation names](#operation-names) section above. - Note: If a custom value is used, it MUST be of low cardinality. - """ - - MESSAGING_BATCH_MESSAGE_COUNT = "messaging.batch.message_count" - """ - The number of messages sent, received, or processed in the scope of the batching operation. - Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs. - """ - - MESSAGING_CLIENT_ID = "messaging.client_id" - """ - A unique identifier for the client that consumes or produces a message. - """ - - MESSAGING_DESTINATION_NAME = "messaging.destination.name" - """ - The message destination name. - Note: Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If - the broker does not have such notion, the destination name SHOULD uniquely identify the broker. - """ - - MESSAGING_DESTINATION_TEMPLATE = "messaging.destination.template" - """ - Low cardinality representation of the messaging destination name. - Note: Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. - """ - - MESSAGING_DESTINATION_TEMPORARY = "messaging.destination.temporary" - """ - A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. - """ - - MESSAGING_DESTINATION_ANONYMOUS = "messaging.destination.anonymous" - """ - A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). - """ - - MESSAGING_MESSAGE_ID = "messaging.message.id" - """ - A value used by the messaging system as an identifier for the message, represented as a string. - """ - - MESSAGING_MESSAGE_CONVERSATION_ID = "messaging.message.conversation_id" - """ - The [conversation ID](#conversations) identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". - """ - - MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES = "messaging.message.payload_size_bytes" - """ - The (uncompressed) size of the message payload in bytes. Also use this attribute if it is unknown whether the compressed or uncompressed payload size is reported. - """ - - MESSAGING_MESSAGE_PAYLOAD_COMPRESSED_SIZE_BYTES = "messaging.message.payload_compressed_size_bytes" - """ - The compressed size of the message payload in bytes. - """ - - FAAS_TIME = "faas.time" - """ - A string containing the function invocation time in the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed in [UTC](https://www.w3.org/TR/NOTE-datetime). - """ - - FAAS_CRON = "faas.cron" - """ - A string containing the schedule period as [Cron Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm). - """ - - FAAS_COLDSTART = "faas.coldstart" - """ - A boolean that is true if the serverless function is executed for the first time (aka cold-start). - """ - - FAAS_INVOKED_NAME = "faas.invoked_name" - """ - The name of the invoked function. - Note: SHOULD be equal to the `faas.name` resource attribute of the invoked function. - """ - - FAAS_INVOKED_PROVIDER = "faas.invoked_provider" - """ - The cloud provider of the invoked function. - Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked function. - """ - - FAAS_INVOKED_REGION = "faas.invoked_region" - """ - The cloud region of the invoked function. - Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked function. - """ - - NETWORK_CONNECTION_TYPE = "network.connection.type" - """ - The internet connection type. - """ - - NETWORK_CONNECTION_SUBTYPE = "network.connection.subtype" - """ - This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. - """ - - NETWORK_CARRIER_NAME = "network.carrier.name" - """ - The name of the mobile carrier. - """ - - NETWORK_CARRIER_MCC = "network.carrier.mcc" - """ - The mobile carrier country code. - """ - - NETWORK_CARRIER_MNC = "network.carrier.mnc" - """ - The mobile carrier network code. - """ - - NETWORK_CARRIER_ICC = "network.carrier.icc" - """ - The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. - """ - - PEER_SERVICE = "peer.service" - """ - The [`service.name`](/docs/resource/README.md#service) of the remote service. SHOULD be equal to the actual `service.name` resource attribute of the remote service if any. - """ - - ENDUSER_ID = "enduser.id" - """ - Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. - """ - - ENDUSER_ROLE = "enduser.role" - """ - Actual/assumed role the client is making the request under extracted from token or application security context. - """ - - ENDUSER_SCOPE = "enduser.scope" - """ - Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). - """ - - THREAD_ID = "thread.id" - """ - Current "managed" thread ID (as opposed to OS thread ID). - """ - - THREAD_NAME = "thread.name" - """ - Current thread name. - """ - - CODE_FUNCTION = "code.function" - """ - The method or function name, or equivalent (usually rightmost part of the code unit's name). - """ - - CODE_NAMESPACE = "code.namespace" - """ - The "namespace" within which `code.function` is defined. Usually the qualified class or module name, such that `code.namespace` + some separator + `code.function` form a unique identifier for the code unit. - """ - - CODE_FILEPATH = "code.filepath" - """ - The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). - """ - - CODE_LINENO = "code.lineno" - """ - The line number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. - """ - - CODE_COLUMN = "code.column" - """ - The column number in `code.filepath` best representing the operation. It SHOULD point within the code unit named in `code.function`. - """ - - HTTP_REQUEST_METHOD_ORIGINAL = "http.request.method_original" - """ - Original HTTP method sent by the client in the request line. - """ - - HTTP_REQUEST_BODY_SIZE = "http.request.body.size" - """ - The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. - """ - - HTTP_RESPONSE_BODY_SIZE = "http.response.body.size" - """ - The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size. - """ - - HTTP_RESEND_COUNT = "http.resend_count" - """ - The ordinal number of request resending attempt (for any reason, including redirects). - Note: The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). - """ - - RPC_SYSTEM = "rpc.system" - """ - The value `aws-api`. - """ - - RPC_SERVICE = "rpc.service" - """ - The name of the service to which a request is made, as returned by the AWS SDK. - Note: This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The `code.namespace` attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). - """ - - RPC_METHOD = "rpc.method" - """ - The name of the operation corresponding to the request, as returned by the AWS SDK. - Note: This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The `code.function` attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). - """ - - AWS_REQUEST_ID = "aws.request_id" - """ - The AWS request ID as returned in the response headers `x-amz-request-id` or `x-amz-requestid`. - """ - - AWS_DYNAMODB_TABLE_NAMES = "aws.dynamodb.table_names" - """ - The keys in the `RequestItems` object field. - """ - - AWS_DYNAMODB_CONSUMED_CAPACITY = "aws.dynamodb.consumed_capacity" - """ - The JSON-serialized value of each item in the `ConsumedCapacity` response field. - """ - - AWS_DYNAMODB_ITEM_COLLECTION_METRICS = "aws.dynamodb.item_collection_metrics" - """ - The JSON-serialized value of the `ItemCollectionMetrics` response field. - """ - - AWS_DYNAMODB_PROVISIONED_READ_CAPACITY = "aws.dynamodb.provisioned_read_capacity" - """ - The value of the `ProvisionedThroughput.ReadCapacityUnits` request parameter. - """ - - AWS_DYNAMODB_PROVISIONED_WRITE_CAPACITY = "aws.dynamodb.provisioned_write_capacity" - """ - The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. - """ - - AWS_DYNAMODB_CONSISTENT_READ = "aws.dynamodb.consistent_read" - """ - The value of the `ConsistentRead` request parameter. - """ - - AWS_DYNAMODB_PROJECTION = "aws.dynamodb.projection" - """ - The value of the `ProjectionExpression` request parameter. - """ - - AWS_DYNAMODB_LIMIT = "aws.dynamodb.limit" - """ - The value of the `Limit` request parameter. - """ - - AWS_DYNAMODB_ATTRIBUTES_TO_GET = "aws.dynamodb.attributes_to_get" - """ - The value of the `AttributesToGet` request parameter. - """ - - AWS_DYNAMODB_INDEX_NAME = "aws.dynamodb.index_name" - """ - The value of the `IndexName` request parameter. - """ - - AWS_DYNAMODB_SELECT = "aws.dynamodb.select" - """ - The value of the `Select` request parameter. - """ - - AWS_DYNAMODB_GLOBAL_SECONDARY_INDEXES = "aws.dynamodb.global_secondary_indexes" - """ - The JSON-serialized value of each item of the `GlobalSecondaryIndexes` request field. - """ - - AWS_DYNAMODB_LOCAL_SECONDARY_INDEXES = "aws.dynamodb.local_secondary_indexes" - """ - The JSON-serialized value of each item of the `LocalSecondaryIndexes` request field. - """ - - AWS_DYNAMODB_EXCLUSIVE_START_TABLE = "aws.dynamodb.exclusive_start_table" - """ - The value of the `ExclusiveStartTableName` request parameter. - """ - - AWS_DYNAMODB_TABLE_COUNT = "aws.dynamodb.table_count" - """ - The the number of items in the `TableNames` response parameter. - """ - - AWS_DYNAMODB_SCAN_FORWARD = "aws.dynamodb.scan_forward" - """ - The value of the `ScanIndexForward` request parameter. - """ - - AWS_DYNAMODB_SEGMENT = "aws.dynamodb.segment" - """ - The value of the `Segment` request parameter. - """ - - AWS_DYNAMODB_TOTAL_SEGMENTS = "aws.dynamodb.total_segments" - """ - The value of the `TotalSegments` request parameter. - """ - - AWS_DYNAMODB_COUNT = "aws.dynamodb.count" - """ - The value of the `Count` response parameter. - """ - - AWS_DYNAMODB_SCANNED_COUNT = "aws.dynamodb.scanned_count" - """ - The value of the `ScannedCount` response parameter. - """ - - AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS = "aws.dynamodb.attribute_definitions" - """ - The JSON-serialized value of each item in the `AttributeDefinitions` request field. - """ - - AWS_DYNAMODB_GLOBAL_SECONDARY_INDEX_UPDATES = "aws.dynamodb.global_secondary_index_updates" - """ - The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` request field. - """ - - AWS_S3_BUCKET = "aws.s3.bucket" - """ - The S3 bucket name the request refers to. Corresponds to the `--bucket` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. - Note: The `bucket` attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. - This applies to almost all S3 operations except `list-buckets`. - """ - - AWS_S3_KEY = "aws.s3.key" - """ - The S3 object key the request refers to. Corresponds to the `--key` parameter of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) operations. - Note: The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. - This applies in particular to the following operations: - - - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) - - [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) - - [get-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/get-object.html) - - [head-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/head-object.html) - - [put-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.html) - - [restore-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) - - [select-object-content](https://docs.aws.amazon.com/cli/latest/reference/s3api/select-object-content.html) - - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) - - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) - - [create-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/create-multipart-upload.html) - - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) - - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). - """ - - AWS_S3_COPY_SOURCE = "aws.s3.copy_source" - """ - The source object (in the form `bucket`/`key`) for the copy operation. - Note: The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter - of the [copy-object operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html). - This applies in particular to the following operations: - - - [copy-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/copy-object.html) - - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). - """ - - AWS_S3_UPLOAD_ID = "aws.s3.upload_id" - """ - Upload ID that identifies the multipart upload. - Note: The `upload_id` attribute applies to S3 multipart-upload operations and corresponds to the `--upload-id` parameter - of the [S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/index.html) multipart operations. - This applies in particular to the following operations: - - - [abort-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/abort-multipart-upload.html) - - [complete-multipart-upload](https://docs.aws.amazon.com/cli/latest/reference/s3api/complete-multipart-upload.html) - - [list-parts](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-parts.html) - - [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - - [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html). - """ - - AWS_S3_DELETE = "aws.s3.delete" - """ - The delete request container that specifies the objects to be deleted. - Note: The `delete` attribute is only applicable to the [delete-object](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-object.html) operation. - The `delete` attribute corresponds to the `--delete` parameter of the - [delete-objects operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/delete-objects.html). - """ - - AWS_S3_PART_NUMBER = "aws.s3.part_number" - """ - The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. - Note: The `part_number` attribute is only applicable to the [upload-part](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html) - and [upload-part-copy](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part-copy.html) operations. - The `part_number` attribute corresponds to the `--part-number` parameter of the - [upload-part operation within the S3 API](https://docs.aws.amazon.com/cli/latest/reference/s3api/upload-part.html). - """ - - GRAPHQL_OPERATION_NAME = "graphql.operation.name" - """ - The name of the operation being executed. - """ - - GRAPHQL_OPERATION_TYPE = "graphql.operation.type" - """ - The type of the operation being executed. - """ - - GRAPHQL_DOCUMENT = "graphql.document" - """ - The GraphQL document being executed. - Note: The value may be sanitized to exclude sensitive information. - """ - - MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY = "messaging.rabbitmq.destination.routing_key" - """ - RabbitMQ message routing key. - """ - - MESSAGING_KAFKA_MESSAGE_KEY = "messaging.kafka.message.key" - """ - Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set. - Note: If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. - """ - - MESSAGING_KAFKA_CONSUMER_GROUP = "messaging.kafka.consumer.group" - """ - Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. - """ - - MESSAGING_KAFKA_DESTINATION_PARTITION = "messaging.kafka.destination.partition" - """ - Partition the message is sent to. - """ - - MESSAGING_KAFKA_MESSAGE_OFFSET = "messaging.kafka.message.offset" - """ - The offset of a record in the corresponding Kafka partition. - """ - - MESSAGING_KAFKA_MESSAGE_TOMBSTONE = "messaging.kafka.message.tombstone" - """ - A boolean that is true if the message is a tombstone. - """ - - MESSAGING_ROCKETMQ_NAMESPACE = "messaging.rocketmq.namespace" - """ - Namespace of RocketMQ resources, resources in different namespaces are individual. - """ - - MESSAGING_ROCKETMQ_CLIENT_GROUP = "messaging.rocketmq.client_group" - """ - Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. - """ - - MESSAGING_ROCKETMQ_MESSAGE_DELIVERY_TIMESTAMP = "messaging.rocketmq.message.delivery_timestamp" - """ - The timestamp in milliseconds that the delay message is expected to be delivered to consumer. - """ - - MESSAGING_ROCKETMQ_MESSAGE_DELAY_TIME_LEVEL = "messaging.rocketmq.message.delay_time_level" - """ - The delay time level for delay message, which determines the message delay time. - """ - - MESSAGING_ROCKETMQ_MESSAGE_GROUP = "messaging.rocketmq.message.group" - """ - It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. - """ - - MESSAGING_ROCKETMQ_MESSAGE_TYPE = "messaging.rocketmq.message.type" - """ - Type of message. - """ - - MESSAGING_ROCKETMQ_MESSAGE_TAG = "messaging.rocketmq.message.tag" - """ - The secondary classifier of message besides topic. - """ - - MESSAGING_ROCKETMQ_MESSAGE_KEYS = "messaging.rocketmq.message.keys" - """ - Key(s) of message, another way to mark message besides message id. - """ - - MESSAGING_ROCKETMQ_CONSUMPTION_MODEL = "messaging.rocketmq.consumption_model" - """ - Model of message consumption. This only applies to consumer spans. - """ - - RPC_GRPC_STATUS_CODE = "rpc.grpc.status_code" - """ - The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. - """ - - RPC_JSONRPC_VERSION = "rpc.jsonrpc.version" - """ - Protocol version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0 does not specify this, the value can be omitted. - """ - - RPC_JSONRPC_REQUEST_ID = "rpc.jsonrpc.request_id" - """ - `id` property of request or response. Since protocol allows id to be int, string, `null` or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of `null` value. Omit entirely if this is a notification. - """ - - RPC_JSONRPC_ERROR_CODE = "rpc.jsonrpc.error_code" - """ - `error.code` property of response if it is an error response. - """ - - RPC_JSONRPC_ERROR_MESSAGE = "rpc.jsonrpc.error_message" - """ - `error.message` property of response if it is an error response. - """ - - MESSAGE_TYPE = "message.type" - """ - Whether this is a received or sent message. - """ - - MESSAGE_ID = "message.id" - """ - MUST be calculated as two different counters starting from `1` one for sent messages and one for received message. - Note: This way we guarantee that the values will be consistent between different implementations. - """ - - MESSAGE_COMPRESSED_SIZE = "message.compressed_size" - """ - Compressed size of the message in bytes. - """ - - MESSAGE_UNCOMPRESSED_SIZE = "message.uncompressed_size" - """ - Uncompressed size of the message in bytes. - """ - - RPC_CONNECT_RPC_ERROR_CODE = "rpc.connect_rpc.error_code" - """ - The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. - """ - - EXCEPTION_ESCAPED = "exception.escaped" - """ - SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. - Note: An exception is considered to have escaped (or left) the scope of a span, - if that span is ended while the exception is still logically "in flight". - This may be actually "in flight" in some languages (e.g. if the exception - is passed to a Context manager's `__exit__` method in Python) but will - usually be caught at the point of recording the exception in most languages. - - It is usually not possible to determine at the point where an exception is thrown - whether it will escape the scope of a span. - However, it is trivial to know that an exception - will escape, if one checks for an active exception just before ending the span, - as done in the [example above](#recording-an-exception). - - It follows that an exception may still escape the scope of the span - even if the `exception.escaped` attribute was not set or set to false, - since the event might have been recorded at a time where it was not - clear whether the exception will escape. - """ - - URL_FRAGMENT = "url.fragment" - """ - The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component. - """ - - # Manually defined deprecated attributes - - NET_PEER_IP = "net.peer.ip" - """ - Deprecated, use the `client.socket.address` attribute. - """ - - NET_HOST_IP = "net.host.ip" - """ - Deprecated, use the `server.socket.address` attribute. - """ - - HTTP_SERVER_NAME = "http.server_name" - """ - Deprecated, use the `server.address` attribute. - """ - - HTTP_HOST = "http.host" - """ - Deprecated, use the `server.address` and `server.port` attributes. - """ - - HTTP_RETRY_COUNT = "http.retry_count" - """ - Deprecated, use the `http.resend_count` attribute. - """ - - HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED = "http.request_content_length_uncompressed" - """ - Deprecated, use the `http.request.body.size` attribute. - """ - - HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED = "http.response_content_length_uncompressed" - """ - Deprecated, use the `http.response.body.size` attribute. - """ - - MESSAGING_DESTINATION = "messaging.destination" - """ - Deprecated, use the `messaging.destination.name` attribute. - """ - - MESSAGING_DESTINATION_KIND = "messaging.destination_kind" - """ - Deprecated. - """ - - MESSAGING_TEMP_DESTINATION = "messaging.temp_destination" - """ - Deprecated. Use `messaging.destination.temporary` attribute. - """ - - MESSAGING_PROTOCOL = "messaging.protocol" - """ - Deprecated. Use `network.protocol.name` attribute. - """ - - MESSAGING_PROTOCOL_VERSION = "messaging.protocol_version" - """ - Deprecated. Use `network.protocol.version` attribute. - """ - - MESSAGING_URL = "messaging.url" - """ - Deprecated. Use `server.address` and `server.port` attributes. - """ - - MESSAGING_CONVERSATION_ID = "messaging.conversation_id" - """ - Deprecated. Use `messaging.message.conversation.id` attribute. - """ - - MESSAGING_KAFKA_PARTITION = "messaging.kafka.partition" - """ - Deprecated. Use `messaging.kafka.destination.partition` attribute. - """ - - FAAS_EXECUTION = "faas.execution" - """ - Deprecated. Use `faas.invocation_id` attribute. - """ - - HTTP_USER_AGENT = "http.user_agent" - """ - Deprecated. Use `user_agent.original` attribute. - """ - - MESSAGING_RABBITMQ_ROUTING_KEY = "messaging.rabbitmq.routing_key" - """ - Deprecated. Use `messaging.rabbitmq.destination.routing_key` attribute. - """ - - MESSAGING_KAFKA_TOMBSTONE = "messaging.kafka.tombstone" - """ - Deprecated. Use `messaging.kafka.destination.tombstone` attribute. - """ - - NET_APP_PROTOCOL_NAME = "net.app.protocol.name" - """ - Deprecated. Use `network.protocol.name` attribute. - """ - - NET_APP_PROTOCOL_VERSION = "net.app.protocol.version" - """ - Deprecated. Use `network.protocol.version` attribute. - """ - - HTTP_CLIENT_IP = "http.client_ip" - """ - Deprecated. Use `client.address` attribute. - """ - - HTTP_FLAVOR = "http.flavor" - """ - Deprecated. Use `network.protocol.name` and `network.protocol.version` attributes. - """ - - NET_HOST_CONNECTION_TYPE = "net.host.connection.type" - """ - Deprecated. Use `network.connection.type` attribute. - """ - - NET_HOST_CONNECTION_SUBTYPE = "net.host.connection.subtype" - """ - Deprecated. Use `network.connection.subtype` attribute. - """ - - NET_HOST_CARRIER_NAME = "net.host.carrier.name" - """ - Deprecated. Use `network.carrier.name` attribute. - """ - - NET_HOST_CARRIER_MCC = "net.host.carrier.mcc" - """ - Deprecated. Use `network.carrier.mcc` attribute. - """ - - NET_HOST_CARRIER_MNC = "net.host.carrier.mnc" - """ - Deprecated. Use `network.carrier.mnc` attribute. - """ - - MESSAGING_CONSUMER_ID = "messaging.consumer_id" - """ - Deprecated. Use `messaging.client_id` attribute. - """ - - MESSAGING_KAFKA_CLIENT_ID = "messaging.kafka.client_id" - """ - Deprecated. Use `messaging.client_id` attribute. - """ - - MESSAGING_ROCKETMQ_CLIENT_ID = "messaging.rocketmq.client_id" - """ - Deprecated. Use `messaging.client_id` attribute. - """ - - -@deprecated( - "Removed from the specification in favor of `network.protocol.name` and `network.protocol.version` attributes. Deprecated since version 1.18.0.", -) -class HttpFlavorValues(Enum): - HTTP_1_0 = "1.0" - - HTTP_1_1 = "1.1" - - HTTP_2_0 = "2.0" - - HTTP_3_0 = "3.0" - - SPDY = "SPDY" - - QUIC = "QUIC" - - -@deprecated( - "Removed from the specification. Deprecated since version 1.18.0.", -) -class MessagingDestinationKindValues(Enum): - QUEUE = "queue" - """A message sent to a queue.""" - - TOPIC = "topic" - """A message sent to a topic.""" - - -@deprecated( - "Renamed to NetworkConnectionTypeValues. Deprecated since version 1.21.0.", -) -class NetHostConnectionTypeValues(Enum): - WIFI = "wifi" - """wifi.""" - - WIRED = "wired" - """wired.""" - - CELL = "cell" - """cell.""" - - UNAVAILABLE = "unavailable" - """unavailable.""" - - UNKNOWN = "unknown" - """unknown.""" - - -@deprecated( - "Renamed to NetworkConnectionSubtypeValues. Deprecated since version 1.21.0.", -) -class NetHostConnectionSubtypeValues(Enum): - GPRS = "gprs" - """GPRS.""" - - EDGE = "edge" - """EDGE.""" - - UMTS = "umts" - """UMTS.""" - - CDMA = "cdma" - """CDMA.""" - - EVDO_0 = "evdo_0" - """EVDO Rel. 0.""" - - EVDO_A = "evdo_a" - """EVDO Rev. A.""" - - CDMA2000_1XRTT = "cdma2000_1xrtt" - """CDMA2000 1XRTT.""" - - HSDPA = "hsdpa" - """HSDPA.""" - - HSUPA = "hsupa" - """HSUPA.""" - - HSPA = "hspa" - """HSPA.""" - - IDEN = "iden" - """IDEN.""" - - EVDO_B = "evdo_b" - """EVDO Rev. B.""" - - LTE = "lte" - """LTE.""" - - EHRPD = "ehrpd" - """EHRPD.""" - - HSPAP = "hspap" - """HSPAP.""" - - GSM = "gsm" - """GSM.""" - - TD_SCDMA = "td_scdma" - """TD-SCDMA.""" - - IWLAN = "iwlan" - """IWLAN.""" - - NR = "nr" - """5G NR (New Radio).""" - - NRNSA = "nrnsa" - """5G NRNSA (New Radio Non-Standalone).""" - - LTE_CA = "lte_ca" - """LTE CA.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv.attributes.NetworkTransportValues` instead. Deprecated since version 1.25.0.", -) -class NetTransportValues(Enum): - IP_TCP = "ip_tcp" - """ip_tcp.""" - - IP_UDP = "ip_udp" - """ip_udp.""" - - PIPE = "pipe" - """Named or anonymous pipe.""" - - INPROC = "inproc" - """In-process communication.""" - - OTHER = "other" - """Something else (non IP-based).""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv.attributes.NetworkType` instead. Deprecated since version 1.25.0.", -) -class NetSockFamilyValues(Enum): - INET = "inet" - """IPv4 address.""" - - INET6 = "inet6" - """IPv6 address.""" - - UNIX = "unix" - """Unix domain socket path.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv.attributes.HttpRequestMethodValues` instead. Deprecated since version 1.25.0.", -) -class HttpRequestMethodValues(Enum): - CONNECT = "CONNECT" - """CONNECT method.""" - - DELETE = "DELETE" - """DELETE method.""" - - GET = "GET" - """GET method.""" - - HEAD = "HEAD" - """HEAD method.""" - - OPTIONS = "OPTIONS" - """OPTIONS method.""" - - PATCH = "PATCH" - """PATCH method.""" - - POST = "POST" - """POST method.""" - - PUT = "PUT" - """PUT method.""" - - TRACE = "TRACE" - """TRACE method.""" - - OTHER = "_OTHER" - """Any HTTP method that the instrumentation has no prior knowledge of.""" - - -@deprecated("Removed from the specification. Deprecated since version 1.25.0.") -class EventDomainValues(Enum): - BROWSER = "browser" - """Events from browser apps.""" - - DEVICE = "device" - """Events from mobile apps.""" - - K8S = "k8s" - """Events from Kubernetes.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv._incubating.attributes.LogIostreamValues` instead. Deprecated since version 1.25.0.", -) -class LogIostreamValues(Enum): - STDOUT = "stdout" - """Logs from stdout stream.""" - - STDERR = "stderr" - """Events from stderr stream.""" - - -@deprecated("Removed from the specification. Deprecated since version 1.25.0.") -class TypeValues(Enum): - HEAP = "heap" - """Heap memory.""" - - NON_HEAP = "non_heap" - """Non-heap memory.""" - - -@deprecated( - "Use :py:const:`opentelemetry.semconv._incubating.attributes.OpentracingRefTypeValues` instead. Deprecated since version 1.25.0.", -) -class OpentracingRefTypeValues(Enum): - CHILD_OF = "child_of" - """The parent Span depends on the child Span in some capacity.""" - - FOLLOWS_FROM = "follows_from" - """The parent Span does not depend in any way on the result of the child Span.""" - - -class DbSystemValues(Enum): - OTHER_SQL = "other_sql" - """Some other SQL database. Fallback only. See notes.""" - - MSSQL = "mssql" - """Microsoft SQL Server.""" - - MSSQLCOMPACT = "mssqlcompact" - """Microsoft SQL Server Compact.""" - - MYSQL = "mysql" - """MySQL.""" - - ORACLE = "oracle" - """Oracle Database.""" - - DB2 = "db2" - """IBM Db2.""" - - POSTGRESQL = "postgresql" - """PostgreSQL.""" - - REDSHIFT = "redshift" - """Amazon Redshift.""" - - HIVE = "hive" - """Apache Hive.""" - - CLOUDSCAPE = "cloudscape" - """Cloudscape.""" - - HSQLDB = "hsqldb" - """HyperSQL DataBase.""" - - PROGRESS = "progress" - """Progress Database.""" - - MAXDB = "maxdb" - """SAP MaxDB.""" - - HANADB = "hanadb" - """SAP HANA.""" - - INGRES = "ingres" - """Ingres.""" - - FIRSTSQL = "firstsql" - """FirstSQL.""" - - EDB = "edb" - """EnterpriseDB.""" - - CACHE = "cache" - """InterSystems Caché.""" - - ADABAS = "adabas" - """Adabas (Adaptable Database System).""" - - FIREBIRD = "firebird" - """Firebird.""" - - DERBY = "derby" - """Apache Derby.""" - - FILEMAKER = "filemaker" - """FileMaker.""" - - INFORMIX = "informix" - """Informix.""" - - INSTANTDB = "instantdb" - """InstantDB.""" - - INTERBASE = "interbase" - """InterBase.""" - - MARIADB = "mariadb" - """MariaDB.""" - - NETEZZA = "netezza" - """Netezza.""" - - PERVASIVE = "pervasive" - """Pervasive PSQL.""" - - POINTBASE = "pointbase" - """PointBase.""" - - SQLITE = "sqlite" - """SQLite.""" - - SYBASE = "sybase" - """Sybase.""" - - TERADATA = "teradata" - """Teradata.""" - - VERTICA = "vertica" - """Vertica.""" - - H2 = "h2" - """H2.""" - - COLDFUSION = "coldfusion" - """ColdFusion IMQ.""" - - CASSANDRA = "cassandra" - """Apache Cassandra.""" - - HBASE = "hbase" - """Apache HBase.""" - - MONGODB = "mongodb" - """MongoDB.""" - - REDIS = "redis" - """Redis.""" - - COUCHBASE = "couchbase" - """Couchbase.""" - - COUCHDB = "couchdb" - """CouchDB.""" - - COSMOSDB = "cosmosdb" - """Microsoft Azure Cosmos DB.""" - - DYNAMODB = "dynamodb" - """Amazon DynamoDB.""" - - NEO4J = "neo4j" - """Neo4j.""" - - GEODE = "geode" - """Apache Geode.""" - - ELASTICSEARCH = "elasticsearch" - """Elasticsearch.""" - - MEMCACHED = "memcached" - """Memcached.""" - - COCKROACHDB = "cockroachdb" - """CockroachDB.""" - - OPENSEARCH = "opensearch" - """OpenSearch.""" - - CLICKHOUSE = "clickhouse" - """ClickHouse.""" - - SPANNER = "spanner" - """Cloud Spanner.""" - - TRINO = "trino" - """Trino.""" - - -class NetworkTransportValues(Enum): - TCP = "tcp" - """TCP.""" - - UDP = "udp" - """UDP.""" - - PIPE = "pipe" - """Named or anonymous pipe. See note below.""" - - UNIX = "unix" - """Unix domain socket.""" - - -class NetworkTypeValues(Enum): - IPV4 = "ipv4" - """IPv4.""" - - IPV6 = "ipv6" - """IPv6.""" - - -class DbCassandraConsistencyLevelValues(Enum): - ALL = "all" - """all.""" - - EACH_QUORUM = "each_quorum" - """each_quorum.""" - - QUORUM = "quorum" - """quorum.""" - - LOCAL_QUORUM = "local_quorum" - """local_quorum.""" - - ONE = "one" - """one.""" - - TWO = "two" - """two.""" - - THREE = "three" - """three.""" - - LOCAL_ONE = "local_one" - """local_one.""" - - ANY = "any" - """any.""" - - SERIAL = "serial" - """serial.""" - - LOCAL_SERIAL = "local_serial" - """local_serial.""" - - -class DbCosmosdbOperationTypeValues(Enum): - INVALID = "Invalid" - """invalid.""" - - CREATE = "Create" - """create.""" - - PATCH = "Patch" - """patch.""" - - READ = "Read" - """read.""" - - READ_FEED = "ReadFeed" - """read_feed.""" - - DELETE = "Delete" - """delete.""" - - REPLACE = "Replace" - """replace.""" - - EXECUTE = "Execute" - """execute.""" - - QUERY = "Query" - """query.""" - - HEAD = "Head" - """head.""" - - HEAD_FEED = "HeadFeed" - """head_feed.""" - - UPSERT = "Upsert" - """upsert.""" - - BATCH = "Batch" - """batch.""" - - QUERY_PLAN = "QueryPlan" - """query_plan.""" - - EXECUTE_JAVASCRIPT = "ExecuteJavaScript" - """execute_javascript.""" - - -class DbCosmosdbConnectionModeValues(Enum): - GATEWAY = "gateway" - """Gateway (HTTP) connections mode.""" - - DIRECT = "direct" - """Direct connection.""" - - -class OtelStatusCodeValues(Enum): - OK = "OK" - """The operation has been validated by an Application developer or Operator to have completed successfully.""" - - ERROR = "ERROR" - """The operation contains an error.""" - - -class FaasTriggerValues(Enum): - DATASOURCE = "datasource" - """A response to some data source operation such as a database or filesystem read/write.""" - - HTTP = "http" - """To provide an answer to an inbound HTTP request.""" - - PUBSUB = "pubsub" - """A function is set to be executed when messages are sent to a messaging system.""" - - TIMER = "timer" - """A function is scheduled to be executed regularly.""" - - OTHER = "other" - """If none of the others apply.""" - - -class FaasDocumentOperationValues(Enum): - INSERT = "insert" - """When a new object is created.""" - - EDIT = "edit" - """When an object is modified.""" - - DELETE = "delete" - """When an object is deleted.""" - - -class MessagingOperationValues(Enum): - PUBLISH = "publish" - """publish.""" - - RECEIVE = "receive" - """receive.""" - - PROCESS = "process" - """process.""" - - -class FaasInvokedProviderValues(Enum): - ALIBABA_CLOUD = "alibaba_cloud" - """Alibaba Cloud.""" - - AWS = "aws" - """Amazon Web Services.""" - - AZURE = "azure" - """Microsoft Azure.""" - - GCP = "gcp" - """Google Cloud Platform.""" - - TENCENT_CLOUD = "tencent_cloud" - """Tencent Cloud.""" - - -class NetworkConnectionTypeValues(Enum): - WIFI = "wifi" - """wifi.""" - - WIRED = "wired" - """wired.""" - - CELL = "cell" - """cell.""" - - UNAVAILABLE = "unavailable" - """unavailable.""" - - UNKNOWN = "unknown" - """unknown.""" - - -class NetworkConnectionSubtypeValues(Enum): - GPRS = "gprs" - """GPRS.""" - - EDGE = "edge" - """EDGE.""" - - UMTS = "umts" - """UMTS.""" - - CDMA = "cdma" - """CDMA.""" - - EVDO_0 = "evdo_0" - """EVDO Rel. 0.""" - - EVDO_A = "evdo_a" - """EVDO Rev. A.""" - - CDMA2000_1XRTT = "cdma2000_1xrtt" - """CDMA2000 1XRTT.""" - - HSDPA = "hsdpa" - """HSDPA.""" - - HSUPA = "hsupa" - """HSUPA.""" - - HSPA = "hspa" - """HSPA.""" - - IDEN = "iden" - """IDEN.""" - - EVDO_B = "evdo_b" - """EVDO Rev. B.""" - - LTE = "lte" - """LTE.""" - - EHRPD = "ehrpd" - """EHRPD.""" - - HSPAP = "hspap" - """HSPAP.""" - - GSM = "gsm" - """GSM.""" - - TD_SCDMA = "td_scdma" - """TD-SCDMA.""" - - IWLAN = "iwlan" - """IWLAN.""" - - NR = "nr" - """5G NR (New Radio).""" - - NRNSA = "nrnsa" - """5G NRNSA (New Radio Non-Standalone).""" - - LTE_CA = "lte_ca" - """LTE CA.""" - - -class RpcSystemValues(Enum): - GRPC = "grpc" - """gRPC.""" - - JAVA_RMI = "java_rmi" - """Java RMI.""" - - DOTNET_WCF = "dotnet_wcf" - """.NET WCF.""" - - APACHE_DUBBO = "apache_dubbo" - """Apache Dubbo.""" - - CONNECT_RPC = "connect_rpc" - """Connect RPC.""" - - -class GraphqlOperationTypeValues(Enum): - QUERY = "query" - """GraphQL query.""" - - MUTATION = "mutation" - """GraphQL mutation.""" - - SUBSCRIPTION = "subscription" - """GraphQL subscription.""" - - -class MessagingRocketmqMessageTypeValues(Enum): - NORMAL = "normal" - """Normal message.""" - - FIFO = "fifo" - """FIFO message.""" - - DELAY = "delay" - """Delay message.""" - - TRANSACTION = "transaction" - """Transaction message.""" - - -class MessagingRocketmqConsumptionModelValues(Enum): - CLUSTERING = "clustering" - """Clustering consumption model.""" - - BROADCASTING = "broadcasting" - """Broadcasting consumption model.""" - - -class RpcGrpcStatusCodeValues(Enum): - OK = 0 - """OK.""" - - CANCELLED = 1 - """CANCELLED.""" - - UNKNOWN = 2 - """UNKNOWN.""" - - INVALID_ARGUMENT = 3 - """INVALID_ARGUMENT.""" - - DEADLINE_EXCEEDED = 4 - """DEADLINE_EXCEEDED.""" - - NOT_FOUND = 5 - """NOT_FOUND.""" - - ALREADY_EXISTS = 6 - """ALREADY_EXISTS.""" - - PERMISSION_DENIED = 7 - """PERMISSION_DENIED.""" - - RESOURCE_EXHAUSTED = 8 - """RESOURCE_EXHAUSTED.""" - - FAILED_PRECONDITION = 9 - """FAILED_PRECONDITION.""" - - ABORTED = 10 - """ABORTED.""" - - OUT_OF_RANGE = 11 - """OUT_OF_RANGE.""" - - UNIMPLEMENTED = 12 - """UNIMPLEMENTED.""" - - INTERNAL = 13 - """INTERNAL.""" - - UNAVAILABLE = 14 - """UNAVAILABLE.""" - - DATA_LOSS = 15 - """DATA_LOSS.""" - - UNAUTHENTICATED = 16 - """UNAUTHENTICATED.""" - - -class MessageTypeValues(Enum): - SENT = "SENT" - """sent.""" - - RECEIVED = "RECEIVED" - """received.""" - - -class RpcConnectRpcErrorCodeValues(Enum): - CANCELLED = "cancelled" - """cancelled.""" - - UNKNOWN = "unknown" - """unknown.""" - - INVALID_ARGUMENT = "invalid_argument" - """invalid_argument.""" - - DEADLINE_EXCEEDED = "deadline_exceeded" - """deadline_exceeded.""" - - NOT_FOUND = "not_found" - """not_found.""" - - ALREADY_EXISTS = "already_exists" - """already_exists.""" - - PERMISSION_DENIED = "permission_denied" - """permission_denied.""" - - RESOURCE_EXHAUSTED = "resource_exhausted" - """resource_exhausted.""" - - FAILED_PRECONDITION = "failed_precondition" - """failed_precondition.""" - - ABORTED = "aborted" - """aborted.""" - - OUT_OF_RANGE = "out_of_range" - """out_of_range.""" - - UNIMPLEMENTED = "unimplemented" - """unimplemented.""" - - INTERNAL = "internal" - """internal.""" - - UNAVAILABLE = "unavailable" - """unavailable.""" - - DATA_LOSS = "data_loss" - """data_loss.""" - - UNAUTHENTICATED = "unauthenticated" - """unauthenticated.""" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/semconv/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py deleted file mode 100644 index 9e0fac92eaf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/__init__.py +++ /dev/null @@ -1,661 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -The OpenTelemetry tracing API describes the classes used to generate -distributed traces. - -The :class:`.Tracer` class controls access to the execution context, and -manages span creation. Each operation in a trace is represented by a -:class:`.Span`, which records the start, end time, and metadata associated with -the operation. - -This module provides abstract (i.e. unimplemented) classes required for -tracing, and a concrete no-op :class:`.NonRecordingSpan` that allows applications -to use the API package alone without a supporting implementation. - -To get a tracer, you need to provide the package name from which you are -calling the tracer APIs to OpenTelemetry by calling `TracerProvider.get_tracer` -with the calling module name and the version of your package. - -The tracer supports creating spans that are "attached" or "detached" from the -context. New spans are "attached" to the context in that they are -created as children of the currently active span, and the newly-created span -can optionally become the new active span:: - - from opentelemetry import trace - - tracer = trace.get_tracer(__name__) - - # Create a new root span, set it as the current span in context - with tracer.start_as_current_span("parent"): - # Attach a new child and update the current span - with tracer.start_as_current_span("child"): - do_work(): - # Close child span, set parent as current - # Close parent span, set default span as current - -When creating a span that's "detached" from the context the active span doesn't -change, and the caller is responsible for managing the span's lifetime:: - - # Explicit parent span assignment is done via the Context - from opentelemetry.trace import set_span_in_context - - context = set_span_in_context(parent) - child = tracer.start_span("child", context=context) - - try: - do_work(span=child) - finally: - child.end() - -Applications should generally use a single global TracerProvider, and use -either implicit or explicit context propagation consistently throughout. - -.. versionadded:: 0.1.0 -.. versionchanged:: 0.3.0 - `TracerProvider` was introduced and the global ``tracer`` getter was - replaced by ``tracer_provider``. -.. versionchanged:: 0.5.0 - ``tracer_provider`` was replaced by `get_tracer_provider`, - ``set_preferred_tracer_provider_implementation`` was replaced by - `set_tracer_provider`. -""" - -import os -from abc import ABC, abstractmethod -from collections.abc import Iterator, Sequence -from enum import Enum -from logging import getLogger -from typing import cast - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -from opentelemetry.agent._vendor.opentelemetry import context as context_api -from opentelemetry.agent._vendor.opentelemetry.attributes import BoundedAttributes -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER -from opentelemetry.agent._vendor.opentelemetry.trace.propagation import ( - _SPAN_KEY, - get_current_span, - set_span_in_context, -) -from opentelemetry.agent._vendor.opentelemetry.trace.span import ( - DEFAULT_TRACE_OPTIONS, - DEFAULT_TRACE_STATE, - INVALID_SPAN, - INVALID_SPAN_CONTEXT, - INVALID_SPAN_ID, - INVALID_TRACE_ID, - NonRecordingSpan, - Span, - SpanContext, - TraceFlags, - TraceState, - format_span_id, - format_trace_id, -) -from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode -from opentelemetry.agent._vendor.opentelemetry.util import types -from opentelemetry.agent._vendor.opentelemetry.util._decorator import _agnosticcontextmanager -from opentelemetry.agent._vendor.opentelemetry.util._once import Once -from opentelemetry.agent._vendor.opentelemetry.util._providers import _load_provider - -logger = getLogger(__name__) - - -class _LinkBase(ABC): - def __init__(self, context: "SpanContext") -> None: - self._context = context - - @property - def context(self) -> "SpanContext": - return self._context - - @property - @abstractmethod - def attributes(self) -> types.Attributes: - pass - - -class Link(_LinkBase): - """A link to a `Span`. The attributes of a Link are immutable. - - Args: - context: `SpanContext` of the `Span` to link to. - attributes: Link's attributes. - """ - - def __init__( - self, - context: "SpanContext", - attributes: types.Attributes = None, - ) -> None: - super().__init__(context) - self._attributes = attributes - - @property - def attributes(self) -> types.Attributes: - return self._attributes - - @property - def dropped_attributes(self) -> int: - if isinstance(self._attributes, BoundedAttributes): - return self._attributes.dropped - return 0 - - -_Links = Sequence[Link] | None - - -class SpanKind(Enum): - """Specifies additional details on how this span relates to its parent span. - - Note that this enumeration is experimental and likely to change. See - https://github.com/open-telemetry/opentelemetry-specification/pull/226. - """ - - #: Default value. Indicates that the span is used internally in the - # application. - INTERNAL = 0 - - #: Indicates that the span describes an operation that handles a remote - # request. - SERVER = 1 - - #: Indicates that the span describes a request to some remote service. - CLIENT = 2 - - #: Indicates that the span describes a producer sending a message to a - #: broker. Unlike client and server, there is usually no direct critical - #: path latency relationship between producer and consumer spans. - PRODUCER = 3 - - #: Indicates that the span describes a consumer receiving a message from a - #: broker. Unlike client and server, there is usually no direct critical - #: path latency relationship between producer and consumer spans. - CONSUMER = 4 - - -class TracerProvider(ABC): - @abstractmethod - def get_tracer( - self, - instrumenting_module_name: str, - instrumenting_library_version: str | None = None, - schema_url: str | None = None, - attributes: types.Attributes = None, - ) -> "Tracer": - """Returns a `Tracer` for use by the given instrumentation library. - - For any two calls it is undefined whether the same or different - `Tracer` instances are returned, even for different library names. - - This function may return different `Tracer` types (e.g. a no-op tracer - vs. a functional tracer). - - Args: - instrumenting_module_name: The uniquely identifiable name for instrumentation - scope, such as instrumentation library, package, module or class name. - ``__name__`` should be avoided as this can result in - different tracer names if the tracers are in different files. - It is better to use a fixed string that can be imported where - needed and used consistently as the name of the tracer. - - This should *not* be the name of the module that is - instrumented but the name of the module doing the instrumentation. - E.g., instead of ``"requests"``, use - ``"opentelemetry.instrumentation.requests"``. - - instrumenting_library_version: Optional. The version string of the - instrumenting library. Usually this should be the same as - ``importlib.metadata.version(instrumenting_library_name)``. - - schema_url: Optional. Specifies the Schema URL of the emitted telemetry. - attributes: Optional. Specifies the attributes of the emitted telemetry. - """ - - -class NoOpTracerProvider(TracerProvider): - """The default TracerProvider, used when no implementation is available. - - All operations are no-op. - """ - - def get_tracer( - self, - instrumenting_module_name: str, - instrumenting_library_version: str | None = None, - schema_url: str | None = None, - attributes: types.Attributes = None, - ) -> "Tracer": - # pylint:disable=no-self-use,unused-argument - return NoOpTracer() - - -@deprecated("You should use NoOpTracerProvider. Deprecated since version 1.9.0.") -class _DefaultTracerProvider(NoOpTracerProvider): - """The default TracerProvider, used when no implementation is available. - - All operations are no-op. - """ - - -class ProxyTracerProvider(TracerProvider): - def get_tracer( - self, - instrumenting_module_name: str, - instrumenting_library_version: str | None = None, - schema_url: str | None = None, - attributes: types.Attributes = None, - ) -> "Tracer": - if _TRACER_PROVIDER: - return _TRACER_PROVIDER.get_tracer( - instrumenting_module_name, - instrumenting_library_version, - schema_url, - attributes, - ) - return ProxyTracer( - instrumenting_module_name, - instrumenting_library_version, - schema_url, - attributes, - ) - - -class Tracer(ABC): - """Handles span creation and in-process context propagation. - - This class provides methods for manipulating the context, creating spans, - and controlling spans' lifecycles. - """ - - @abstractmethod - def start_span( - self, - name: str, - context: Context | None = None, - kind: SpanKind = SpanKind.INTERNAL, - attributes: types.Attributes = None, - links: _Links = None, - start_time: int | None = None, - record_exception: bool = True, - set_status_on_exception: bool = True, - ) -> "Span": - """Starts a span. - - Create a new span. Start the span without setting it as the current - span in the context. To start the span and use the context in a single - method, see :meth:`start_as_current_span`. - - By default the current span in the context will be used as parent, but an - explicit context can also be specified, by passing in a `Context` containing - a current `Span`. If there is no current span in the global `Context` or in - the specified context, the created span will be a root span. - - The span can be used as a context manager. On exiting the context manager, - the span's end() method will be called. - - Example:: - - # trace.get_current_span() will be used as the implicit parent. - # If none is found, the created span will be a root instance. - with tracer.start_span("one") as child: - child.add_event("child's event") - - Args: - name: The name of the span to be created. - context: An optional Context containing the span's parent. Defaults to the - global context. - kind: The span's kind (relationship to parent). Note that is - meaningful even if there is no parent. - attributes: The span's attributes. - links: Links span to other spans - start_time: Sets the start time of a span - record_exception: Whether to record any exceptions raised within the - context as error event on the span. - set_status_on_exception: Only relevant if the returned span is used - in a with/context manager. Defines whether the span status will - be automatically set to ERROR when an uncaught exception is - raised in the span with block. The span status won't be set by - this mechanism if it was previously set manually. - - Returns: - The newly-created span. - """ - - @_agnosticcontextmanager - @abstractmethod - def start_as_current_span( - self, - name: str, - context: Context | None = None, - kind: SpanKind = SpanKind.INTERNAL, - attributes: types.Attributes = None, - links: _Links = None, - start_time: int | None = None, - record_exception: bool = True, - set_status_on_exception: bool = True, - end_on_exit: bool = True, - ) -> Iterator["Span"]: - """Context manager for creating a new span and set it - as the current span in this tracer's context. - - Exiting the context manager will call the span's end method, - as well as return the current span to its previous value by - returning to the previous context. - - Example:: - - with tracer.start_as_current_span("one") as parent: - parent.add_event("parent's event") - with tracer.start_as_current_span("two") as child: - child.add_event("child's event") - trace.get_current_span() # returns child - trace.get_current_span() # returns parent - trace.get_current_span() # returns previously active span - - This is a convenience method for creating spans attached to the - tracer's context. Applications that need more control over the span - lifetime should use :meth:`start_span` instead. For example:: - - with tracer.start_as_current_span(name) as span: - do_work() - - is equivalent to:: - - span = tracer.start_span(name) - with opentelemetry.trace.use_span(span, end_on_exit=True): - do_work() - - This can also be used as a decorator:: - - @tracer.start_as_current_span("name") - def function(): ... - - - function() - - Args: - name: The name of the span to be created. - context: An optional Context containing the span's parent. Defaults to the - global context. - kind: The span's kind (relationship to parent). Note that is - meaningful even if there is no parent. - attributes: The span's attributes. - links: Links span to other spans - start_time: Sets the start time of a span - record_exception: Whether to record any exceptions raised within the - context as error event on the span. - set_status_on_exception: Only relevant if the returned span is used - in a with/context manager. Defines whether the span status will - be automatically set to ERROR when an uncaught exception is - raised in the span with block. The span status won't be set by - this mechanism if it was previously set manually. - end_on_exit: Whether to end the span automatically when leaving the - context manager. - - Yields: - The newly-created span. - """ - - -class ProxyTracer(Tracer): - # pylint: disable=W0222,signature-differs - def __init__( - self, - instrumenting_module_name: str, - instrumenting_library_version: str | None = None, - schema_url: str | None = None, - attributes: types.Attributes = None, - ): - self._instrumenting_module_name = instrumenting_module_name - self._instrumenting_library_version = instrumenting_library_version - self._schema_url = schema_url - self._attributes = attributes - self._real_tracer: Tracer | None = None - self._noop_tracer = NoOpTracer() - - @property - def _tracer(self) -> Tracer: - if self._real_tracer: - return self._real_tracer - - if _TRACER_PROVIDER: - self._real_tracer = _TRACER_PROVIDER.get_tracer( - self._instrumenting_module_name, - self._instrumenting_library_version, - self._schema_url, - self._attributes, - ) - return self._real_tracer - return self._noop_tracer - - def start_span(self, *args, **kwargs) -> Span: # type: ignore - return self._tracer.start_span(*args, **kwargs) # type: ignore - - @_agnosticcontextmanager # type: ignore - def start_as_current_span(self, *args, **kwargs) -> Iterator[Span]: - with self._tracer.start_as_current_span(*args, **kwargs) as span: # type: ignore - yield span - - -class NoOpTracer(Tracer): - """The default Tracer, used when no Tracer implementation is available. - - All operations are no-op. - """ - - def start_span( - self, - name: str, - context: Context | None = None, - kind: SpanKind = SpanKind.INTERNAL, - attributes: types.Attributes = None, - links: _Links = None, - start_time: int | None = None, - record_exception: bool = True, - set_status_on_exception: bool = True, - ) -> "Span": - current_span = get_current_span(context) - if isinstance(current_span, NonRecordingSpan): - return current_span - parent_span_context = current_span.get_span_context() - if parent_span_context is not None and not isinstance(parent_span_context, SpanContext): - logger.warning( - "Invalid span context for %s: %s", - current_span, - parent_span_context, - ) - return INVALID_SPAN - - return NonRecordingSpan(context=parent_span_context) - - @_agnosticcontextmanager - def start_as_current_span( - self, - name: str, - context: Context | None = None, - kind: SpanKind = SpanKind.INTERNAL, - attributes: types.Attributes = None, - links: _Links = None, - start_time: int | None = None, - record_exception: bool = True, - set_status_on_exception: bool = True, - end_on_exit: bool = True, - ) -> Iterator["Span"]: - span = self.start_span( - name=name, - context=context, - kind=kind, - attributes=attributes, - links=links, - start_time=start_time, - record_exception=record_exception, - set_status_on_exception=set_status_on_exception, - ) - with use_span( - span, - end_on_exit=end_on_exit, - record_exception=record_exception, - set_status_on_exception=set_status_on_exception, - ) as span: - yield span - - -@deprecated("You should use NoOpTracer. Deprecated since version 1.9.0.") -class _DefaultTracer(NoOpTracer): - """The default Tracer, used when no Tracer implementation is available. - - All operations are no-op. - """ - - -_TRACER_PROVIDER_SET_ONCE = Once() -_TRACER_PROVIDER: TracerProvider | None = None -_PROXY_TRACER_PROVIDER = ProxyTracerProvider() - - -def get_tracer( - instrumenting_module_name: str, - instrumenting_library_version: str | None = None, - tracer_provider: TracerProvider | None = None, - schema_url: str | None = None, - attributes: types.Attributes = None, -) -> "Tracer": - """Returns a `Tracer` for use by the given instrumentation library. - - This function is a convenience wrapper for - opentelemetry.trace.TracerProvider.get_tracer. - - If tracer_provider is omitted the current configured one is used. - """ - if tracer_provider is None: - tracer_provider = get_tracer_provider() - return tracer_provider.get_tracer( - instrumenting_module_name, - instrumenting_library_version, - schema_url, - attributes, - ) - - -def _set_tracer_provider(tracer_provider: TracerProvider, log: bool) -> None: - def set_tp() -> None: - global _TRACER_PROVIDER # pylint: disable=global-statement - _TRACER_PROVIDER = tracer_provider - - did_set = _TRACER_PROVIDER_SET_ONCE.do_once(set_tp) - - if log and not did_set: - logger.warning("Overriding of current TracerProvider is not allowed") - - -def set_tracer_provider(tracer_provider: TracerProvider) -> None: - """Sets the current global :class:`~.TracerProvider` object. - - This can only be done once, a warning will be logged if any further attempt - is made. - """ - _set_tracer_provider(tracer_provider, log=True) - - -def get_tracer_provider() -> TracerProvider: - """Gets the current global :class:`~.TracerProvider` object.""" - if _TRACER_PROVIDER is None: - # if a global tracer provider has not been set either via code or env - # vars, return a proxy tracer provider - if OTEL_PYTHON_TRACER_PROVIDER not in os.environ: - return _PROXY_TRACER_PROVIDER - - tracer_provider: TracerProvider = _load_provider(OTEL_PYTHON_TRACER_PROVIDER, "tracer_provider") - _set_tracer_provider(tracer_provider, log=False) - # _TRACER_PROVIDER will have been set by one thread - return cast("TracerProvider", _TRACER_PROVIDER) - - -@_agnosticcontextmanager -def use_span( - span: Span, - end_on_exit: bool = False, - record_exception: bool = True, - set_status_on_exception: bool = True, -) -> Iterator[Span]: - """Takes a non-active span and activates it in the current context. - - Args: - span: The span that should be activated in the current context. - end_on_exit: Whether to end the span automatically when leaving the - context manager scope. - record_exception: Whether to record any exceptions raised within the - context as error event on the span. - set_status_on_exception: Only relevant if the returned span is used - in a with/context manager. Defines whether the span status will - be automatically set to ERROR when an uncaught exception is - raised in the span with block. The span status won't be set by - this mechanism if it was previously set manually. - """ - try: - token = context_api.attach(context_api.set_value(_SPAN_KEY, span)) - try: - yield span - finally: - context_api.detach(token) - - # Record only exceptions that inherit Exception class but not BaseException, because - # classes that directly inherit BaseException are not technically errors, e.g. GeneratorExit. - # See https://github.com/open-telemetry/opentelemetry-python/issues/4484 - except Exception as exc: # pylint: disable=broad-exception-caught - if isinstance(span, Span) and span.is_recording(): - # Record the exception as an event - if record_exception: - span.record_exception(exc) - - # Set status in case exception was raised - if set_status_on_exception: - span.set_status( - Status( - status_code=StatusCode.ERROR, - description=f"{type(exc).__name__}: {exc}", - ) - ) - - # This causes parent spans to set their status to ERROR and to record - # an exception as an event if a child span raises an exception even if - # such child span was started with both record_exception and - # set_status_on_exception attributes set to False. - raise - - finally: - if end_on_exit: - span.end() - - -__all__ = [ - "DEFAULT_TRACE_OPTIONS", - "DEFAULT_TRACE_STATE", - "INVALID_SPAN", - "INVALID_SPAN_CONTEXT", - "INVALID_SPAN_ID", - "INVALID_TRACE_ID", - "Link", - "NonRecordingSpan", - "Span", - "SpanContext", - "SpanKind", - "Status", - "StatusCode", - "TraceFlags", - "TraceState", - "Tracer", - "TracerProvider", - "format_span_id", - "format_trace_id", - "get_current_span", - "get_tracer", - "get_tracer_provider", - "set_span_in_context", - "set_tracer_provider", - "use_span", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py deleted file mode 100644 index 2f04296b7d4..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from opentelemetry.agent._vendor.opentelemetry.context import create_key, get_value, set_value -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.trace.span import INVALID_SPAN, Span - -SPAN_KEY = "current-span" -_SPAN_KEY = create_key("current-span") - - -def set_span_in_context(span: Span, context: Context | None = None) -> Context: - """Set the span in the given context. - - Args: - span: The Span to set. - context: a Context object. if one is not passed, the - default current context is used instead. - """ - ctx = set_value(_SPAN_KEY, span, context=context) - return ctx - - -def get_current_span(context: Context | None = None) -> Span: - """Retrieve the current span. - - Args: - context: A Context object. If one is not passed, the - default current context is used instead. - - Returns: - The Span set in the context if it exists. INVALID_SPAN otherwise. - """ - span = get_value(_SPAN_KEY, context=context) - if span is None or not isinstance(span, Span): - return INVALID_SPAN - return span diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py deleted file mode 100644 index 2dea2af09cf..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/propagation/tracecontext.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 -# -import logging -import re - -from opentelemetry.agent._vendor.opentelemetry import trace -from opentelemetry.agent._vendor.opentelemetry.context.context import Context -from opentelemetry.agent._vendor.opentelemetry.propagators import textmap -from opentelemetry.agent._vendor.opentelemetry.trace import format_span_id, format_trace_id -from opentelemetry.agent._vendor.opentelemetry.trace.span import ( - _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH, - TraceState, -) - -_logger = logging.getLogger(__name__) - - -class TraceContextTextMapPropagator(textmap.TextMapPropagator): - """Extracts and injects using w3c TraceContext's headers.""" - - _TRACEPARENT_HEADER_NAME = "traceparent" - _TRACESTATE_HEADER_NAME = "tracestate" - _TRACEPARENT_HEADER_FORMAT = ( - "^[ \t]*([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})" + "(?:(-.*)|[ \t]*)$" - ) - _TRACEPARENT_HEADER_FORMAT_RE = re.compile(_TRACEPARENT_HEADER_FORMAT) - _TRACEPARENT_MAXIMUM_LENGTH = 512 - - # pylint: disable-next=too-many-return-statements - def extract( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - getter: textmap.Getter[textmap.CarrierT] = textmap.default_getter, - ) -> Context: - """Extracts SpanContext from the carrier. - - See `opentelemetry.propagators.textmap.TextMapPropagator.extract` - """ - if context is None: - context = Context() - - header = getter.get(carrier, self._TRACEPARENT_HEADER_NAME) - - if not header: - return context - - if len(header[0]) > self._TRACEPARENT_MAXIMUM_LENGTH: - _logger.warning( - "traceparent header exceeded the maximum length of %d characters", - self._TRACEPARENT_MAXIMUM_LENGTH, - ) - return context - - match = re.search(self._TRACEPARENT_HEADER_FORMAT_RE, header[0]) - if not match: - return context - - version: str = match.group(1) - trace_id: str = match.group(2) - span_id: str = match.group(3) - trace_flags: str = match.group(4) - - if trace_id == "0" * 32 or span_id == "0" * 16: - return context - - if version == "00": - if match.group(5): # type: ignore - return context - if version == "ff": - return context - - tracestate_headers = getter.get(carrier, self._TRACESTATE_HEADER_NAME) - if tracestate_headers is None: - tracestate = None - elif ( - # multiple header fields are combined with "," (RFC 9110, section 5.3) - sum(len(header) for header in tracestate_headers) + len(tracestate_headers) - 1 - > _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH - ): - _logger.warning( - "tracestate header exceeded the maximum length of %d characters", - _TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH, - ) - tracestate = None - else: - tracestate = TraceState.from_header(tracestate_headers) - - span_context = trace.SpanContext( - trace_id=int(trace_id, 16), - span_id=int(span_id, 16), - is_remote=True, - trace_flags=trace.TraceFlags(int(trace_flags, 16)), - trace_state=tracestate, - ) - return trace.set_span_in_context(trace.NonRecordingSpan(span_context), context) - - def inject( - self, - carrier: textmap.CarrierT, - context: Context | None = None, - setter: textmap.Setter[textmap.CarrierT] = textmap.default_setter, - ) -> None: - """Injects SpanContext into the carrier. - - See `opentelemetry.propagators.textmap.TextMapPropagator.inject` - """ - span = trace.get_current_span(context) - span_context = span.get_span_context() - if span_context == trace.INVALID_SPAN_CONTEXT: - return - traceparent_string = f"00-{format_trace_id(span_context.trace_id)}-{format_span_id(span_context.span_id)}-{span_context.trace_flags:02x}" - setter.set(carrier, self._TRACEPARENT_HEADER_NAME, traceparent_string) - if span_context.trace_state: - tracestate_string = span_context.trace_state.to_header() - setter.set(carrier, self._TRACESTATE_HEADER_NAME, tracestate_string) - - @property - def fields(self) -> set[str]: - """Returns a set with the fields set in `inject`. - - See - `opentelemetry.propagators.textmap.TextMapPropagator.fields` - """ - return {self._TRACEPARENT_HEADER_NAME, self._TRACESTATE_HEADER_NAME} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py deleted file mode 100644 index 09c712d58a0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/span.py +++ /dev/null @@ -1,616 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -import abc -import logging -import re -import types as python_types -import typing -import warnings -from collections.abc import Iterator, Mapping, Sequence - -from opentelemetry.agent._vendor.opentelemetry.trace.status import Status, StatusCode -from opentelemetry.agent._vendor.opentelemetry.util import types - -# The key MUST begin with a lowercase letter or a digit, -# and can only contain lowercase letters (a-z), digits (0-9), -# underscores (_), dashes (-), asterisks (*), and forward slashes (/). -# For multi-tenant vendor scenarios, an at sign (@) can be used to -# prefix the vendor name. Vendors SHOULD set the tenant ID -# at the beginning of the key. - -# key = ( lcalpha ) 0*255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) -# key = ( lcalpha / DIGIT ) 0*240( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) "@" lcalpha 0*13( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) -# lcalpha = %x61-7A ; a-z - -_KEY_FORMAT = ( - r"[a-z][_0-9a-z\-\*\/]{0,255}|" - r"[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}" -) -_KEY_PATTERN = re.compile(_KEY_FORMAT) - -# The value is an opaque string containing up to 256 printable -# ASCII [RFC0020] characters (i.e., the range 0x20 to 0x7E) -# except comma (,) and (=). -# value = 0*255(chr) nblk-chr -# nblk-chr = %x21-2B / %x2D-3C / %x3E-7E -# chr = %x20 / nblk-chr - -_VALUE_FORMAT = r"[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]" -_VALUE_PATTERN = re.compile(_VALUE_FORMAT) - - -_TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS = 32 -_TRACECONTEXT_MAXIMUM_TRACESTATE_LENGTH = 8192 -_member_pattern = re.compile(f"({_KEY_FORMAT})=({_VALUE_FORMAT})") -_logger = logging.getLogger(__name__) - - -def _is_valid_pair(key: str, value: str) -> bool: - return ( - isinstance(key, str) - and _KEY_PATTERN.fullmatch(key) is not None - and isinstance(value, str) - and _VALUE_PATTERN.fullmatch(value) is not None - ) - - -class Span(abc.ABC): - """A span represents a single operation within a trace.""" - - @abc.abstractmethod - def end(self, end_time: int | None = None) -> None: - """Sets the current time as the span's end time. - - The span's end time is the wall time at which the operation finished. - - Only the first call to `end` should modify the span, and - implementations are free to ignore or raise on further calls. - """ - - @abc.abstractmethod - def get_span_context(self) -> SpanContext: - """Gets the span's SpanContext. - - Get an immutable, serializable identifier for this span that can be - used to create new child spans. - - Returns: - A :class:`opentelemetry.trace.SpanContext` with a copy of this span's immutable state. - """ - - @abc.abstractmethod - def set_attributes(self, attributes: Mapping[str, types.AnyValue]) -> None: - """Sets Attributes. - - Sets Attributes with the key and value passed as arguments dict. - - Note: The behavior of `None` value attributes is undefined, and hence - strongly discouraged. It is also preferred to set attributes at span - creation, instead of calling this method later since samplers can only - consider information already present during span creation. - """ - - @abc.abstractmethod - def set_attribute(self, key: str, value: types.AnyValue) -> None: - """Sets an Attribute. - - Sets a single Attribute with the key and value passed as arguments. - - Note: The behavior of `None` value attributes is undefined, and hence - strongly discouraged. It is also preferred to set attributes at span - creation, instead of calling this method later since samplers can only - consider information already present during span creation. - """ - - @abc.abstractmethod - def add_event( - self, - name: str, - attributes: types.Attributes = None, - timestamp: int | None = None, - ) -> None: - """Adds an `Event`. - - Adds a single `Event` with the name and, optionally, a timestamp and - attributes passed as arguments. Implementations should generate a - timestamp if the `timestamp` argument is omitted. - """ - - def add_link( # pylint: disable=no-self-use - self, - context: SpanContext, - attributes: types.Attributes = None, - ) -> None: - """Adds a `Link`. - - Adds a single `Link` with the `SpanContext` of the span to link to and, - optionally, attributes passed as arguments. Implementations may ignore - calls with an invalid span context if both attributes and TraceState - are empty. - - Note: It is preferred to add links at span creation, instead of calling - this method later since samplers can only consider information already - present during span creation. - """ - warnings.warn( - "Span.add_link() not implemented and will be a no-op. " - "Use opentelemetry-sdk >= 1.23 to add links after span creation" - ) - - @abc.abstractmethod - def update_name(self, name: str) -> None: - """Updates the `Span` name. - - This will override the name provided via :func:`opentelemetry.trace.Tracer.start_span`. - - Upon this update, any sampling behavior based on Span name will depend - on the implementation. - """ - - @abc.abstractmethod - def is_recording(self) -> bool: - """Returns whether this span will be recorded. - - Returns true if this Span is active and recording information like - events with the add_event operation and attributes using set_attribute. - """ - - @abc.abstractmethod - def set_status( - self, - status: Status | StatusCode, - description: str | None = None, - ) -> None: - """Sets the Status of the Span. If used, this will override the default - Span status. - """ - - @abc.abstractmethod - def record_exception( - self, - exception: BaseException, - attributes: types.Attributes = None, - timestamp: int | None = None, - escaped: bool = False, - ) -> None: - """Records an exception as a span event.""" - - def __enter__(self) -> Span: - """Invoked when `Span` is used as a context manager. - - Returns the `Span` itself. - """ - return self - - def __exit__( - self, - exc_type: type[BaseException] | None, - exc_val: BaseException | None, - exc_tb: python_types.TracebackType | None, - ) -> None: - """Ends context manager and calls `end` on the `Span`.""" - - self.end() - - -class TraceFlags(int): - """A bitmask that represents options specific to the trace. - - Supported flags: - - "sampled" (``0x01``): Indicates the trace may have been sampled upstream. - - "random-trace-id" (``0x02``): Indicates the trace ID was generated - randomly, with at least the 7 rightmost bytes (56 bits) selected with - uniform distribution. - - See the `W3C Trace Context - Traceparent`_ spec for details. - - .. _W3C Trace Context - Traceparent: - https://www.w3.org/TR/trace-context-2/#trace-flags - """ - - DEFAULT = 0x00 - SAMPLED = 0x01 - RANDOM_TRACE_ID = 0x02 - - @classmethod - def get_default(cls) -> TraceFlags: - return cls(cls.DEFAULT) - - @property - def sampled(self) -> bool: - return bool(self & TraceFlags.SAMPLED) - - @property - def random_trace_id(self) -> bool: - return bool(self & TraceFlags.RANDOM_TRACE_ID) - - -DEFAULT_TRACE_OPTIONS = TraceFlags.get_default() - - -class TraceState(Mapping[str, str]): - """A list of key-value pairs representing vendor-specific trace info. - - Keys and values are strings of up to 256 printable US-ASCII characters. - Implementations should conform to the `W3C Trace Context - Tracestate`_ - spec, which describes additional restrictions on valid field values. - - .. _W3C Trace Context - Tracestate: - https://www.w3.org/TR/trace-context/#tracestate-field - """ - - def __init__( - self, - entries: Sequence[tuple[str, str]] | None = None, - ) -> None: - self._dict = {} # type: dict[str, str] - if entries is None: - return - if len(entries) > _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS: - _logger.warning( - "There can't be more than %s key/value pairs.", - _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS, - ) - return - - for key, value in entries: - if _is_valid_pair(key, value): - if key in self._dict: - _logger.warning("Duplicate key: %s found.", key) - continue - self._dict[key] = value - else: - _logger.warning("Invalid key/value pair (%s, %s) found.", key, value) - - def __contains__(self, item: object) -> bool: - return item in self._dict - - def __getitem__(self, key: str) -> str: - return self._dict[key] - - def __iter__(self) -> Iterator[str]: - return iter(self._dict) - - def __len__(self) -> int: - return len(self._dict) - - def __repr__(self) -> str: - pairs = [f"{{key={key}, value={value}}}" for key, value in self._dict.items()] - return str(pairs) - - def add(self, key: str, value: str) -> TraceState: - """Adds a key-value pair to tracestate. The provided pair should - adhere to w3c tracestate identifiers format. - - Args: - key: A valid tracestate key to add - value: A valid tracestate value to add - - Returns: - A new TraceState with the modifications applied. - - If the provided key-value pair is invalid or results in tracestate - that violates tracecontext specification, they are discarded and - same tracestate will be returned. - """ - if not _is_valid_pair(key, value): - _logger.warning("Invalid key/value pair (%s, %s) found.", key, value) - return self - # There can be a maximum of 32 pairs - if len(self) >= _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS: - _logger.warning("There can't be more 32 key/value pairs.") - return self - # Duplicate entries are not allowed - if key in self._dict: - _logger.warning("The provided key %s already exists.", key) - return self - new_state = [(key, value)] + list(self._dict.items()) - return TraceState(new_state) - - def update(self, key: str, value: str) -> TraceState: - """Updates a key-value pair in tracestate. The provided pair should - adhere to w3c tracestate identifiers format. - - Note: - This method performs an "upsert": if ``key`` is not already present - it is added (when the tracestate is below the 32-entry limit), - otherwise its value is updated. This upsert behaviour is intentional - but goes beyond what the OpenTelemetry specification defines for - ``update`` (https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#tracestate), - and is kept for backwards compatibility with callers that rely on it. - - Args: - key: A valid tracestate key to update - value: A valid tracestate value to update for key - - Returns: - A new TraceState with the modifications applied. - - If the provided pair is invalid, or adding a new key would exceed - the maximum of 32 key/value pairs, they are discarded and the same - tracestate is returned unchanged. Updating an existing key is always - allowed, even at the maximum. - """ - if not _is_valid_pair(key, value): - _logger.warning("Invalid key/value pair (%s, %s) found.", key, value) - return self - # Adding a new key at the maximum would push the tracestate over the - # limit and cause the constructor to drop every entry. Return unchanged - # instead of silently discarding existing state. - if key not in self._dict and len(self._dict) >= _TRACECONTEXT_MAXIMUM_TRACESTATE_KEYS: - _logger.warning("There can't be more 32 key/value pairs.") - return self - prev_state = self._dict.copy() - prev_state.pop(key, None) - new_state = [(key, value), *prev_state.items()] - return TraceState(new_state) - - def delete(self, key: str) -> TraceState: - """Deletes a key-value from tracestate. - - Args: - key: A valid tracestate key to remove key-value pair from tracestate - - Returns: - A new TraceState with the modifications applied. - - If the provided key-value pair is invalid or results in tracestate - that violates tracecontext specification, they are discarded and - same tracestate will be returned. - """ - if key not in self._dict: - _logger.warning("The provided key %s doesn't exist.", key) - return self - prev_state = self._dict.copy() - prev_state.pop(key) - new_state = list(prev_state.items()) - return TraceState(new_state) - - def to_header(self) -> str: - """Creates a w3c tracestate header from a TraceState. - - Returns: - A string that adheres to the w3c tracestate - header format. - """ - return ",".join(key + "=" + value for key, value in self._dict.items()) - - @classmethod - def from_header(cls, header_list: list[str]) -> TraceState: - """Parses one or more w3c tracestate header into a TraceState. - - Args: - header_list: one or more w3c tracestate headers. - - Returns: - A valid TraceState that contains values extracted from - the tracestate header. - - If the format of one headers is illegal, all values will - be discarded and an empty tracestate will be returned. - - If the number of keys is beyond the maximum, all values - will be discarded and an empty tracestate will be returned. - """ - pairs = {} # type: dict[str, str] - for header in header_list: - for member in header.split(","): - # remove optional whitespace (RFC 9110, section 5.6.3) - member = member.strip(" \t") - # empty members are valid, but no need to process further. - if not member: - continue - match = _member_pattern.fullmatch(member) - if not match: - _logger.warning( - "Member doesn't match the w3c identifiers format %s", - member, - ) - return cls() - key, value = match.groups() - # duplicate keys are not legal in header - if key in pairs: - return cls() - pairs[key] = value - return cls(list(pairs.items())) - - @classmethod - def get_default(cls) -> TraceState: - return cls() - - def keys(self) -> typing.KeysView[str]: - return self._dict.keys() - - def items(self) -> typing.ItemsView[str, str]: - return self._dict.items() - - def values(self) -> typing.ValuesView[str]: - return self._dict.values() - - -DEFAULT_TRACE_STATE = TraceState.get_default() -_TRACE_ID_MAX_VALUE = 2**128 - 1 -_SPAN_ID_MAX_VALUE = 2**64 - 1 - - -class SpanContext(tuple[int, int, bool, "TraceFlags", "TraceState", bool]): - """The state of a Span to propagate between processes. - - This class includes the immutable attributes of a :class:`.Span` that must - be propagated to a span's children and across process boundaries. - - Args: - trace_id: The ID of the trace that this span belongs to. - span_id: This span's ID. - is_remote: True if propagated from a remote parent. - trace_flags: Trace options to propagate. - trace_state: Tracing-system-specific info to propagate. - """ - - def __new__( - cls, - trace_id: int, - span_id: int, - is_remote: bool, - trace_flags: TraceFlags | None = DEFAULT_TRACE_OPTIONS, - trace_state: TraceState | None = DEFAULT_TRACE_STATE, - ) -> SpanContext: - if trace_flags is None: - trace_flags = DEFAULT_TRACE_OPTIONS - if trace_state is None: - trace_state = DEFAULT_TRACE_STATE - - is_valid = ( - INVALID_TRACE_ID < trace_id <= _TRACE_ID_MAX_VALUE and INVALID_SPAN_ID < span_id <= _SPAN_ID_MAX_VALUE - ) - - return tuple.__new__( - cls, - (trace_id, span_id, is_remote, trace_flags, trace_state, is_valid), - ) - - def __getnewargs__( - self, - ) -> tuple[int, int, bool, TraceFlags, TraceState]: - return ( - self.trace_id, - self.span_id, - self.is_remote, - self.trace_flags, - self.trace_state, - ) - - @property - def trace_id(self) -> int: - return self[0] # pylint: disable=unsubscriptable-object - - @property - def span_id(self) -> int: - return self[1] # pylint: disable=unsubscriptable-object - - @property - def is_remote(self) -> bool: - return self[2] # pylint: disable=unsubscriptable-object - - @property - def trace_flags(self) -> TraceFlags: - return self[3] # pylint: disable=unsubscriptable-object - - @property - def trace_state(self) -> TraceState: - return self[4] # pylint: disable=unsubscriptable-object - - @property - def is_valid(self) -> bool: - return self[5] # pylint: disable=unsubscriptable-object - - def __setattr__(self, *args: str) -> None: - _logger.debug("Immutable type, ignoring call to set attribute", stack_info=True) - - def __delattr__(self, *args: str) -> None: - _logger.debug( - "Immutable type, ignoring call to delete attribute", - stack_info=True, - ) - - def __repr__(self) -> str: - return f"{type(self).__name__}(trace_id=0x{format_trace_id(self.trace_id)}, span_id=0x{format_span_id(self.span_id)}, trace_flags=0x{self.trace_flags:02x}, trace_state={self.trace_state!r}, is_remote={self.is_remote})" - - -class NonRecordingSpan(Span): - """The Span that is used when no Span implementation is available. - - All operations are no-op except context propagation. - """ - - def __init__(self, context: SpanContext) -> None: - self._context = context - - def get_span_context(self) -> SpanContext: - return self._context - - def is_recording(self) -> bool: - return False - - def end(self, end_time: int | None = None) -> None: - pass - - def set_attributes(self, attributes: Mapping[str, types.AnyValue]) -> None: - pass - - def set_attribute(self, key: str, value: types.AnyValue) -> None: - pass - - def add_event( - self, - name: str, - attributes: types.Attributes = None, - timestamp: int | None = None, - ) -> None: - pass - - def add_link( - self, - context: SpanContext, - attributes: types.Attributes = None, - ) -> None: - pass - - def update_name(self, name: str) -> None: - pass - - def set_status( - self, - status: Status | StatusCode, - description: str | None = None, - ) -> None: - pass - - def record_exception( - self, - exception: BaseException, - attributes: types.Attributes = None, - timestamp: int | None = None, - escaped: bool = False, - ) -> None: - pass - - def __repr__(self) -> str: - return f"NonRecordingSpan({self._context!r})" - - -INVALID_SPAN_ID = 0x0000000000000000 -INVALID_TRACE_ID = 0x00000000000000000000000000000000 -INVALID_SPAN_CONTEXT = SpanContext( - trace_id=INVALID_TRACE_ID, - span_id=INVALID_SPAN_ID, - is_remote=False, - trace_flags=DEFAULT_TRACE_OPTIONS, - trace_state=DEFAULT_TRACE_STATE, -) -INVALID_SPAN = NonRecordingSpan(INVALID_SPAN_CONTEXT) - - -def format_trace_id(trace_id: int) -> str: - """Convenience trace ID formatting method - Args: - trace_id: Trace ID int - - Returns: - The trace ID (16 bytes) cast to a 32-character hexadecimal string - """ - return format(trace_id, "032x") - - -def format_span_id(span_id: int) -> str: - """Convenience span ID formatting method - Args: - span_id: Span ID int - - Returns: - The span ID (8 bytes) cast to a 16-character hexadecimal string - """ - return format(span_id, "016x") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py deleted file mode 100644 index 88c07a69107..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/trace/status.py +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import enum -import logging - -logger = logging.getLogger(__name__) - - -class StatusCode(enum.Enum): - """Represents the canonical set of status codes of a finished Span.""" - - UNSET = 0 - """The default status.""" - - OK = 1 - """The operation has been validated by an Application developer or Operator to have completed successfully.""" - - ERROR = 2 - """The operation contains an error.""" - - -class Status: - """Represents the status of a finished Span. - - Args: - status_code: The canonical status code that describes the result - status of the operation. - description: An optional description of the status. - """ - - def __init__( - self, - status_code: StatusCode = StatusCode.UNSET, - description: str | None = None, - ): - self._status_code = status_code - self._description = None - - if description: - if not isinstance(description, str): - logger.warning("Invalid status description type, expected str") - return - if status_code is not StatusCode.ERROR: - logger.warning("description should only be set when status_code is set to StatusCode.ERROR") - return - - self._description = description - - @property - def status_code(self) -> StatusCode: - """Represents the canonical status code of a finished Span.""" - return self._status_code - - @property - def description(self) -> str | None: - """Status description""" - return self._description - - @property - def is_ok(self) -> bool: - """Returns false if this represents an error, true otherwise.""" - return self.is_unset or self._status_code is StatusCode.OK - - @property - def is_unset(self) -> bool: - """Returns true if unset, false otherwise.""" - return self._status_code is StatusCode.UNSET diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py deleted file mode 100644 index 98bb55ee011..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_decorator.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -import contextlib -import functools -import inspect -from collections.abc import Callable, Iterator -from typing import TYPE_CHECKING, Generic, TypeVar - -V = TypeVar("V") -R = TypeVar("R") # Return type -Pargs = TypeVar("Pargs") # Generic type for arguments -Pkwargs = TypeVar("Pkwargs") # Generic type for arguments - -# We don't actually depend on typing_extensions but we can use it in CI with this conditional -# import. ParamSpec can be imported directly from typing after python 3.9 is dropped -# https://peps.python.org/pep-0612/. -if TYPE_CHECKING: - from opentelemetry.agent._vendor.typing_extensions import ParamSpec - - P = ParamSpec("P") # Generic type for all arguments - - -class _AgnosticContextManager( - contextlib._GeneratorContextManager[R], - Generic[R], -): # pylint: disable=protected-access - """Context manager that can decorate both async and sync functions. - - This is an overridden version of the contextlib._GeneratorContextManager - class that will decorate async functions with an async context manager - to end the span AFTER the entire async function coroutine finishes. - - Else it will report near zero spans durations for async functions. - - We are overriding the contextlib._GeneratorContextManager class as - reimplementing it is a lot of code to maintain and this class (even if it's - marked as protected) doesn't seems like to be evolving a lot. - - For more information, see: - https://github.com/open-telemetry/opentelemetry-python/pull/3633 - """ - - def __enter__(self) -> R: - """Reimplementing __enter__ to avoid the type error. - - The original __enter__ method returns Any type, but we want to return R. - """ - del self.args, self.kwds, self.func # type: ignore - try: - return next(self.gen) # type: ignore - except StopIteration: - raise RuntimeError("generator didn't yield") from None - - def __call__(self, func: V) -> V: # pyright: ignore [reportIncompatibleMethodOverride] - if inspect.iscoroutinefunction(func): - - @functools.wraps(func) # type: ignore - async def async_wrapper(*args: Pargs, **kwargs: Pkwargs) -> R: # pyright: ignore [reportInvalidTypeVarUse] - with self._recreate_cm(): # type: ignore - return await func(*args, **kwargs) # type: ignore - - return async_wrapper # type: ignore - return super().__call__(func) # type: ignore - - -def _agnosticcontextmanager( - func: "Callable[P, Iterator[R]]", -) -> "Callable[P, _AgnosticContextManager[R]]": - @functools.wraps(func) - def helper(*args: Pargs, **kwargs: Pkwargs) -> _AgnosticContextManager[R]: # pyright: ignore [reportInvalidTypeVarUse] - return _AgnosticContextManager(func, args, kwargs) # pyright: ignore [reportArgumentType] - - # Ignoring the type to keep the original signature of the function - return helper # type: ignore[return-value] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py deleted file mode 100644 index c7c5399c816..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_importlib_metadata.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -Caching and compatibility wrapper for standard library ``importlib.metadata``. - -This module caches ``entry_points()`` to avoid reloading entry points from disk on every call. -It also normalizes minor differences across python versions 3.10+. References to issues: - -- https://github.com/open-telemetry/opentelemetry-python/pull/4735 -- https://github.com/open-telemetry/opentelemetry-python/pull/5203 -""" - -import os -from functools import cache -from importlib.metadata import ( - Distribution, - EntryPoint, - EntryPoints, - PackageNotFoundError, - requires, - version, -) -from importlib.metadata import distributions as _all_distributions -from typing import Any, Iterable - -# opentelemetry-agent: entry points are only looked up in the vendored distributions' metadata -# (written to _vendor/_metadata by opentelemetry-vendor sync), never in the application's, whose -# OpenTelemetry plugins point at un-vendored modules. version() and requires() still see the -# application's distributions: instrumentors check the installed versions of the libraries they patch. -_VENDORED_METADATA_PATH = [ - os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "_metadata") -] - - -def distributions(**kwargs: Any) -> Iterable[Distribution]: - return _all_distributions(path=_VENDORED_METADATA_PATH, **kwargs) - - -@cache -def _original_entry_points_cached() -> EntryPoints: - return EntryPoints(entry_point for dist in distributions() for entry_point in dist.entry_points) - - -def entry_points(**params) -> EntryPoints: - return _original_entry_points_cached().select(**params) - - -__all__ = [ - "Distribution", - "EntryPoint", - "EntryPoints", - "PackageNotFoundError", - "distributions", - "entry_points", - "requires", - "version", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py deleted file mode 100644 index 59f562385e6..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_once.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from collections.abc import Callable -from threading import Lock - - -class Once: - """Execute a function exactly once and block all callers until the function returns - - Same as golang's `sync.Once `_ - """ - - def __init__(self) -> None: - self._lock = Lock() - self._done = False - - def do_once(self, func: Callable[[], None]) -> bool: - """Execute ``func`` if it hasn't been executed or return. - - Will block until ``func`` has been called by one thread. - - Returns: - Whether or not ``func`` was executed in this call - """ - - # fast path, try to avoid locking - if self._done: - return False - - with self._lock: - if not self._done: - func() - self._done = True - return True - return False diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py deleted file mode 100644 index 6475da98ce8..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/_providers.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from logging import getLogger -from os import environ -from typing import TYPE_CHECKING, TypeVar, cast - -if TYPE_CHECKING: - from opentelemetry.agent._vendor.opentelemetry.metrics import MeterProvider - from opentelemetry.agent._vendor.opentelemetry.trace import TracerProvider - -Provider = TypeVar("Provider", "TracerProvider", "MeterProvider") - -logger = getLogger(__name__) - - -def _load_provider(provider_environment_variable: str, provider: str) -> Provider: # type: ignore[type-var] - # pylint: disable=import-outside-toplevel,no-name-in-module - from opentelemetry.agent._vendor.opentelemetry.util._importlib_metadata import ( # noqa: PLC0415 - entry_points, - ) - - try: - provider_name = cast( - str, - environ.get(provider_environment_variable, f"default_{provider}"), - ) - - return cast( - Provider, - next( # type: ignore - iter( # type: ignore - entry_points( # type: ignore - group=f"opentelemetry_{provider}", - name=provider_name, - ) - ) - ).load()(), - ) - except Exception: # pylint: disable=broad-exception-caught - logger.exception("Failed to load configured provider %s", provider) - raise diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py deleted file mode 100644 index c438e965bdb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/__init__.py +++ /dev/null @@ -1,351 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from __future__ import annotations - -from collections.abc import Callable, Iterable, Mapping -from os import environ -from re import IGNORECASE as RE_IGNORECASE -from re import compile as re_compile -from re import search -from typing import overload -from urllib.parse import parse_qs, urlencode, urlparse, urlunparse - -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.http_attributes import ( - HTTP_FLAVOR, - HTTP_HOST, - HTTP_METHOD, - HTTP_SCHEME, - HTTP_SERVER_NAME, - HTTP_STATUS_CODE, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.net_attributes import ( - NET_HOST_NAME, - NET_HOST_PORT, -) -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.user_agent_attributes import ( - UserAgentSyntheticTypeValues, -) -from opentelemetry.agent._vendor.opentelemetry.util.http.constants import BOT_PATTERNS, TEST_PATTERNS - -OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS" -OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST" -OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE" -OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_REQUEST" -OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE = "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_CLIENT_RESPONSE" - -OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS = "OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS" - -# List of recommended metrics attributes -_duration_attrs = { - HTTP_METHOD, - HTTP_HOST, - HTTP_SCHEME, - HTTP_STATUS_CODE, - HTTP_FLAVOR, - HTTP_SERVER_NAME, - NET_HOST_NAME, - NET_HOST_PORT, -} - -_active_requests_count_attrs = { - HTTP_METHOD, - HTTP_HOST, - HTTP_SCHEME, - HTTP_FLAVOR, - HTTP_SERVER_NAME, -} - -PARAMS_TO_REDACT = ["AWSAccessKeyId", "Signature", "sig", "X-Goog-Signature"] - - -class ExcludeList: - """Class to exclude certain paths (given as a list of regexes) from tracing requests""" - - def __init__(self, excluded_urls: Iterable[str]): - self._excluded_urls = excluded_urls - if self._excluded_urls: - self._regex = re_compile("|".join(excluded_urls)) - - def url_disabled(self, url: str) -> bool: - return bool(self._excluded_urls and search(self._regex, url)) - - -class SanitizeValue: - """Class to sanitize (remove sensitive data from) certain headers (given as a list of regexes)""" - - def __init__(self, sanitized_fields: Iterable[str]): - self._sanitized_fields = sanitized_fields - if self._sanitized_fields: - self._regex = re_compile("|".join(sanitized_fields), RE_IGNORECASE) - - def sanitize_header_value(self, header: str, value: str) -> str: - return "[REDACTED]" if (self._sanitized_fields and search(self._regex, header)) else value - - def sanitize_header_values( - self, - headers: Mapping[str, str | list[str]], - header_regexes: list[str], - normalize_function: Callable[[str], str], - ) -> dict[str, list[str]]: - values: dict[str, list[str]] = {} - - if header_regexes: - header_regexes_compiled = re_compile( - "|".join(header_regexes), - RE_IGNORECASE, - ) - - for header_name, header_value in headers.items(): - if header_regexes_compiled.fullmatch(header_name): - key = normalize_function(header_name.lower()) - if isinstance(header_value, str): - values[key] = [self.sanitize_header_value(header_name, header_value)] - else: - values[key] = [self.sanitize_header_value(header_name, value) for value in header_value] - - return values - - -_root = r"OTEL_PYTHON_{}" - - -def get_traced_request_attrs(instrumentation: str) -> list[str]: - traced_request_attrs = environ.get(_root.format(f"{instrumentation}_TRACED_REQUEST_ATTRS")) - if traced_request_attrs: - return [traced_request_attr.strip() for traced_request_attr in traced_request_attrs.split(",")] - return [] - - -def get_excluded_urls(instrumentation: str) -> ExcludeList: - # Get instrumentation-specific excluded URLs. If not set, retrieve them - # from generic variable. - excluded_urls = environ.get( - _root.format(f"{instrumentation}_EXCLUDED_URLS"), - environ.get(_root.format("EXCLUDED_URLS"), ""), - ) - - return parse_excluded_urls(excluded_urls) - - -def parse_excluded_urls(excluded_urls: str) -> ExcludeList: - """ - Small helper to put an arbitrary url list inside an ExcludeList - """ - if excluded_urls: - excluded_url_list = [excluded_url.strip() for excluded_url in excluded_urls.split(",")] - else: - excluded_url_list = [] - - return ExcludeList(excluded_url_list) - - -def remove_url_credentials(url: str) -> str: - """Given a string url, replace the username and password with the keyword `REDACTED` only if it is a valid url""" - try: - parsed = urlparse(url) - if all([parsed.scheme, parsed.netloc]): # checks for valid url - if "@" in parsed.netloc: - _, _, host = parsed.netloc.rpartition("@") - new_netloc = "REDACTED:REDACTED@" + host - return urlunparse( - ( - parsed.scheme, - new_netloc, - parsed.path, - parsed.params, - parsed.query, - parsed.fragment, - ) - ) - except ValueError: # an unparsable url was passed - pass - return url - - -def normalise_request_header_name(header: str) -> str: - key = header.lower().replace("-", "_") - return f"http.request.header.{key}" - - -def normalise_response_header_name(header: str) -> str: - key = header.lower().replace("-", "_") - return f"http.response.header.{key}" - - -@overload -def sanitize_method(method: str) -> str: ... - - -@overload -def sanitize_method(method: None) -> None: ... - - -def sanitize_method(method: str | None) -> str | None: - if method is None: - return None - method = method.upper() - if ( - environ.get(OTEL_PYTHON_INSTRUMENTATION_HTTP_CAPTURE_ALL_METHODS) - or - # Based on https://www.rfc-editor.org/rfc/rfc9110.html#name-methods, https://www.rfc-editor.org/rfc/rfc5789#section-2 - # and https://datatracker.ietf.org/doc/rfc10008/. - method - in [ - "GET", - "HEAD", - "POST", - "PUT", - "DELETE", - "CONNECT", - "OPTIONS", - "TRACE", - "PATCH", - "QUERY", - ] - ): - return method - return "_OTHER" - - -def get_custom_headers(env_var: str) -> list[str]: - custom_headers = environ.get(env_var, None) - if custom_headers: - return [custom_headers.strip() for custom_headers in custom_headers.split(",")] - return [] - - -def get_custom_header_attributes( - headers: Mapping[str, str | list[str]] | None, - captured_headers: list[str] | None, - sensitive_headers: list[str] | None, - normalize_function: Callable[[str], str], -) -> dict[str, list[str]]: - """Extract and sanitize HTTP headers for span attributes. - - Args: - headers: The HTTP headers to process, either from a request or response. - Can be None if no headers are available. - captured_headers: List of header regexes to capture as span attributes. - If None or empty, no headers will be captured. - sensitive_headers: List of header regexes whose values should be sanitized - (redacted). If None, no sanitization is applied. - normalize_function: Function to normalize header names. - - Returns: - Dictionary of normalized header attribute names to their values - as lists of strings. - """ - if not headers or not captured_headers: - return {} - sanitize: SanitizeValue = SanitizeValue(sensitive_headers or ()) - return sanitize.sanitize_header_values(headers, captured_headers, normalize_function) - - -def _parse_active_request_count_attrs(req_attrs): - active_requests_count_attrs = { - key: req_attrs[key] for key in _active_requests_count_attrs.intersection(req_attrs.keys()) - } - return active_requests_count_attrs - - -def _parse_duration_attrs(req_attrs): - duration_attrs = {key: req_attrs[key] for key in _duration_attrs.intersection(req_attrs.keys())} - return duration_attrs - - -def _parse_url_query(url: str) -> tuple[str, str]: - """Split a url into its path and query components. - - Callers may pass request targets that come straight off the request line, - so the url need not be parsable. An unparsable one yields empty components - rather than raising, since instrumentation must never break the request it - is measuring. - - Returns: - The path and the query string, either of which may be empty. - """ - try: - parsed_url = urlparse(url) - except ValueError: # an unparsable url was passed - return "", "" - path = parsed_url.path - query_params = parsed_url.query - return path, query_params - - -def redact_query_parameters(url: str) -> str: - """Given a string url, redact sensitive query parameter values""" - try: - parsed = urlparse(url) - if not parsed.query: # No query parameters to redact - return url - query_params = parse_qs(parsed.query) - if not any(param in query_params for param in PARAMS_TO_REDACT): - return url - for param in PARAMS_TO_REDACT: - if param in query_params: - query_params[param] = ["REDACTED"] - return urlunparse( - ( - parsed.scheme, - parsed.netloc, - parsed.path, - parsed.params, - urlencode(query_params, doseq=True), - parsed.fragment, - ) - ) - except ValueError: # an unparsable url was passed - return url - - -def redact_url(url: str) -> str: - """Redact sensitive data from the URL, including credentials and query parameters.""" - url = remove_url_credentials(url) - url = redact_query_parameters(url) - return url - - -def normalize_user_agent( - user_agent: str | bytes | bytearray | memoryview | None, -) -> str | None: - """Convert user-agent header values into a usable string.""" - # Different servers/frameworks surface headers as str, bytes, bytearray or memoryview; - # keep decoding logic centralized so instrumentation modules just call this helper. - if user_agent is None: - return None - if isinstance(user_agent, str): - return user_agent - if isinstance(user_agent, (bytes, bytearray)): - return user_agent.decode("latin-1") - if isinstance(user_agent, memoryview): - return user_agent.tobytes().decode("latin-1") - return str(user_agent) - - -def detect_synthetic_user_agent(user_agent: str | None) -> str | None: - """ - Detect synthetic user agent type based on user agent string contents. - - Args: - user_agent: The user agent string to analyze - - Returns: - UserAgentSyntheticTypeValues.TEST if user agent contains any pattern from TEST_PATTERNS - UserAgentSyntheticTypeValues.BOT if user agent contains any pattern from BOT_PATTERNS - None otherwise - - Note: Test patterns take priority over bot patterns. - """ - if not user_agent: - return None - - user_agent_lower = user_agent.lower() - - if any(test_pattern in user_agent_lower for test_pattern in TEST_PATTERNS): - return UserAgentSyntheticTypeValues.TEST.value - if any(bot_pattern in user_agent_lower for bot_pattern in BOT_PATTERNS): - return UserAgentSyntheticTypeValues.BOT.value - - return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py deleted file mode 100644 index 7ee751826ef..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/constants.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -Constants for OpenTelemetry HTTP utilities. - -This module contains configuration constants and pattern definitions used -by HTTP instrumentation utilities for various features like synthetic user -agent detection. -""" - -# Test patterns to detect in user agent strings (case-insensitive) -# These patterns indicate synthetic test traffic -TEST_PATTERNS = [ - "alwayson", -] - -# Bot patterns to detect in user agent strings (case-insensitive) -# These patterns indicate automated bot traffic -BOT_PATTERNS = [ - "googlebot", - "bingbot", -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py deleted file mode 100644 index d0360175ea0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/httplib.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -""" -This library provides functionality to enrich HTTP client spans with IPs. It does -not create spans on its own. -""" - -from __future__ import annotations - -import contextlib -import http.client -import logging -import socket # pylint:disable=unused-import # Used for typing -import typing -from collections.abc import Callable, Collection -from typing import Any, TypedDict, cast - -from opentelemetry.agent._vendor import wrapt - -from opentelemetry.agent._vendor.opentelemetry import context -from opentelemetry.agent._vendor.opentelemetry.instrumentation.instrumentor import BaseInstrumentor -from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import unwrap -from opentelemetry.agent._vendor.opentelemetry.semconv._incubating.attributes.net_attributes import ( - NET_PEER_IP, -) -from opentelemetry.agent._vendor.opentelemetry.trace.span import Span - -_STATE_KEY = "httpbase_instrumentation_state" - -logger = logging.getLogger(__name__) - -R = typing.TypeVar("R") - - -class HttpClientInstrumentor(BaseInstrumentor): - def instrumentation_dependencies(self) -> Collection[str]: - return () # This instruments http.client from stdlib; no extra deps. - - def _instrument(self, **kwargs: Any): - """Instruments the http.client module (not creating spans on its own)""" - _instrument() - - def _uninstrument(self, **kwargs: Any): - _uninstrument() - - -def _remove_nonrecording(spanlist: list[Span]) -> bool: - idx = len(spanlist) - 1 - while idx >= 0: - if not spanlist[idx].is_recording(): - logger.debug("Span is not recording: %s", spanlist[idx]) - islast = idx + 1 == len(spanlist) - if not islast: - spanlist[idx] = spanlist[len(spanlist) - 1] - spanlist.pop() - if islast: - if idx == 0: - return False # We removed everything - idx -= 1 - else: - idx -= 1 - return True - - -def trysetip(conn: http.client.HTTPConnection, loglevel: int = logging.DEBUG) -> bool: - """Tries to set the net.peer.ip semantic attribute on the current span from the given - HttpConnection. - - Returns False if the connection is not yet established, False if the IP was captured - or there is no need to capture it. - """ - - state = _getstate() - if not state: - return True - spanlist: list[Span] = state.get("need_ip") - if not spanlist: - return True - - # Remove all non-recording spans from the list. - if not _remove_nonrecording(spanlist): - return True - - sock = "" - ip = None - try: - sock: socket.socket | None = conn.sock - logger.debug("Got socket: %s", sock) - if sock is None: - return False - addr = sock.getpeername() - if addr and addr[0]: - ip = addr[0] - except Exception: # pylint:disable=broad-except - logger.log( - loglevel, - "Failed to get peer address from %s", - sock, - exc_info=True, - stack_info=True, - ) - else: - if ip is not None: - for span in spanlist: - span.set_attribute(NET_PEER_IP, ip) - return True - - -def _instrumented_connect( - wrapped: Callable[..., R], - instance: http.client.HTTPConnection, - args: tuple[Any, ...], - kwargs: dict[str, Any], -) -> R: - result = wrapped(*args, **kwargs) - trysetip(instance, loglevel=logging.WARNING) - return result - - -def instrument_connect(module: type[Any], name: str = "connect"): - """Instrument additional connect() methods, e.g. for derived classes.""" - - wrapt.wrap_function_wrapper( - module, - name, - _instrumented_connect, - ) - - -def _instrument(): - def instrumented_send( - wrapped: Callable[..., R], - instance: http.client.HTTPConnection, - args: tuple[Any, ...], - kwargs: dict[str, Any], - ) -> R: - done = trysetip(instance) - result = wrapped(*args, **kwargs) - if not done: - trysetip(instance, loglevel=logging.WARNING) - return result - - wrapt.wrap_function_wrapper( - http.client.HTTPConnection, - "send", - instrumented_send, - ) - - instrument_connect(http.client.HTTPConnection) - # No need to instrument HTTPSConnection, as it calls super().connect() - - -class _ConnectionState(TypedDict): - need_ip: list[Span] - - -def _getstate() -> _ConnectionState | None: - return cast(_ConnectionState, context.get_value(_STATE_KEY)) - - -@contextlib.contextmanager -def set_ip_on_next_http_connection(span: Span): - state = _getstate() - if not state: - token = context.attach(context.set_value(_STATE_KEY, {"need_ip": [span]})) - try: - yield - finally: - if token: - context.detach(token) - else: - spans = state["need_ip"] - spans.append(span) - try: - yield - finally: - try: - spans.remove(span) - except ValueError: # Span might have become non-recording - pass - - -def _uninstrument(): - unwrap(http.client.HTTPConnection, "send") - unwrap(http.client.HTTPConnection, "connect") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py deleted file mode 100644 index 31dc36b24e9..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/http/version.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "0.66b2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py deleted file mode 100644 index e6aec9697fa..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/re.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from collections.abc import Mapping -from logging import getLogger -from re import compile, split -from urllib.parse import unquote - -from opentelemetry.agent._vendor.typing_extensions import deprecated - -_logger = getLogger(__name__) - -# The following regexes reference this spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#specifying-headers-via-environment-variables - -# Optional whitespace -_OWS = r"[ \t]*" -# A key contains printable US-ASCII characters except: SP and "(),/:;<=>?@[\]{} -_KEY_FORMAT = r"[\x21\x23-\x27\x2a\x2b\x2d\x2e\x30-\x39\x41-\x5a\x5e-\x7a\x7c\x7e]+" -# A value contains a URL-encoded UTF-8 string. The encoded form can contain any -# printable US-ASCII characters (0x20-0x7f) other than SP, DEL, and ",;/ -_VALUE_FORMAT = r"[\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*" -# Like above with SP included -_LIBERAL_VALUE_FORMAT = r"[\x20\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*" -# A key-value is key=value, with optional whitespace surrounding key and value -_KEY_VALUE_FORMAT = rf"{_OWS}{_KEY_FORMAT}{_OWS}={_OWS}{_VALUE_FORMAT}{_OWS}" - -_HEADER_PATTERN = compile(_KEY_VALUE_FORMAT) -_LIBERAL_HEADER_PATTERN = compile(rf"{_OWS}{_KEY_FORMAT}{_OWS}={_OWS}{_LIBERAL_VALUE_FORMAT}{_OWS}") -_DELIMITER_PATTERN = compile(r"[ \t]*,[ \t]*") - -_BAGGAGE_PROPERTY_FORMAT = rf"{_KEY_VALUE_FORMAT}|{_OWS}{_KEY_FORMAT}{_OWS}" - -_INVALID_HEADER_ERROR_MESSAGE_STRICT_TEMPLATE = ( - "Header format invalid! Header values in environment variables must be " - "URL encoded per the OpenTelemetry Protocol Exporter specification: %s" -) - -_INVALID_HEADER_ERROR_MESSAGE_LIBERAL_TEMPLATE = ( - "Header format invalid! Header values in environment variables must be " - "URL encoded per the OpenTelemetry Protocol Exporter specification or " - "a comma separated list of name=value occurrences: %s" -) - -# pylint: disable=invalid-name - - -@deprecated("You should use parse_env_headers. Deprecated since version 1.15.0.") -def parse_headers(s: str) -> Mapping[str, str]: - return parse_env_headers(s) - - -def parse_env_headers(s: str, liberal: bool = False) -> Mapping[str, str]: - """ - Parse ``s``, which is a ``str`` instance containing HTTP headers encoded - for use in ENV variables per the W3C Baggage HTTP header format at - https://www.w3.org/TR/baggage/#baggage-http-header-format, except that - additional semi-colon delimited metadata is not supported. - If ``liberal`` is True we try to parse ``s`` anyway to be more compatible - with other languages SDKs that accept non URL-encoded headers by default. - """ - headers: dict[str, str] = {} - headers_list: list[str] = split(_DELIMITER_PATTERN, s) - for header in headers_list: - if not header: # empty string - continue - header_match = _HEADER_PATTERN.fullmatch(header.strip()) - if not header_match and not liberal: - _logger.warning(_INVALID_HEADER_ERROR_MESSAGE_STRICT_TEMPLATE, header) - continue - - if header_match: - match_string: str = header_match.string - # value may contain any number of `=` - name, value = match_string.split("=", 1) - name = unquote(name).strip().lower() - value = unquote(value).strip() - headers[name] = value - else: - # this is not url-encoded and does not match the spec but we decided to be - # liberal in what we accept to match other languages SDKs behaviour - liberal_header_match = _LIBERAL_HEADER_PATTERN.fullmatch(header.strip()) - if not liberal_header_match: - _logger.warning(_INVALID_HEADER_ERROR_MESSAGE_LIBERAL_TEMPLATE, header) - continue - - liberal_match_string: str = liberal_header_match.string - # value may contain any number of `=` - name, value = liberal_match_string.split("=", 1) - name = name.strip().lower() - value = value.strip() - headers[name] = value - - return headers diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py deleted file mode 100644 index f37d7c99cc1..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/util/types.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -from collections.abc import Mapping, Sequence -from typing import TypeAlias - -# This is the implementation of the "Any" type as specified by the specifications of OpenTelemetry data model for logs. -# For more details, refer to the OTel specification: -# https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#type-any -AnyValue: TypeAlias = str | bool | int | float | bytes | Sequence["AnyValue"] | Mapping[str, "AnyValue"] | None -AttributeValue: TypeAlias = AnyValue -Attributes = Mapping[str, AnyValue] | None - -# Deprecated type, do not use. -AttributesAsKey = tuple[ - tuple[ - str, - str - | bool - | int - | float - | tuple[str | None, ...] - | tuple[bool | None, ...] - | tuple[int | None, ...] - | tuple[float | None, ...], - ], - ..., -] diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py deleted file mode 100644 index 0101c361616..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/opentelemetry/version/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -__version__ = "1.45.2" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE deleted file mode 100644 index 6f62d44e4ef..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE +++ /dev/null @@ -1,3 +0,0 @@ -This software is made available under the terms of *either* of the licenses -found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made -under the terms of *both* these licenses. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE deleted file mode 100644 index f433b1a53f5..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.APACHE +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD deleted file mode 100644 index 42ce7b75c92..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging.LICENSE.BSD +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) Donald Stufft and individual contributors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py deleted file mode 100644 index 5a969154fef..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -__title__ = "packaging" -__summary__ = "Core utilities for Python packages" -__uri__ = "https://github.com/pypa/packaging" - -__version__ = "26.3" - -__author__ = "Donald Stufft and individual contributors" -__email__ = "donald@stufft.io" - -__license__ = "BSD-2-Clause or Apache-2.0" -__copyright__ = f"2014 {__author__}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py deleted file mode 100644 index 1ce081d0d2b..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_elffile.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -ELF file parser. - -This provides a class ``ELFFile`` that parses an ELF executable in a similar -interface to ``ZipFile``. Only the read interface is implemented. - -ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html -""" - -from __future__ import annotations - -import enum -import os -import struct -from typing import IO - - -class ELFInvalid(ValueError): - pass - - -class EIClass(enum.IntEnum): - C32 = 1 - C64 = 2 - - -class EIData(enum.IntEnum): - Lsb = 1 - Msb = 2 - - -class EMachine(enum.IntEnum): - I386 = 3 - S390 = 22 - Arm = 40 - X8664 = 62 - AArch64 = 183 - - -class ELFFile: - """ - Representation of an ELF executable. - """ - - def __init__(self, f: IO[bytes]) -> None: - self._f = f - - try: - ident = self._read("16B") - except struct.error as e: - raise ELFInvalid("unable to parse identification") from e - magic = bytes(ident[:4]) - if magic != b"\x7fELF": - raise ELFInvalid(f"invalid magic: {magic!r}") - - self.capacity = ident[4] # Format for program header (bitness). - self.encoding = ident[5] # Data structure encoding (endianness). - - try: - # e_fmt: Format for the ELF header. - # p_fmt: Format for a program header. - # p_idx: Indexes to find p_type, p_offset, and p_filesz. - e_fmt, self._p_fmt, self._p_idx = { - (1, 1): ("HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB. - (2, 1): ("HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB. - }[(self.capacity, self.encoding)] - except KeyError as e: - raise ELFInvalid( - f"unrecognized capacity ({self.capacity}) or encoding ({self.encoding})" - ) from e - - try: - ( - _, - self.machine, # Architecture type. - _, - _, - self._e_phoff, # Offset of program header. - _, - self.flags, # Processor-specific flags. - _, - self._e_phentsize, # Size of a program header entry. - self._e_phnum, # Number of program headers. - ) = self._read(e_fmt) - except struct.error as e: - raise ELFInvalid("unable to parse machine and section information") from e - - def _read(self, fmt: str) -> tuple[int, ...]: - return struct.unpack(fmt, self._f.read(struct.calcsize(fmt))) - - @property - def interpreter(self) -> str | None: - """ - The path recorded in the ``PT_INTERP`` section header. - """ - for index in range(self._e_phnum): - self._f.seek(self._e_phoff + self._e_phentsize * index) - try: - data = self._read(self._p_fmt) - except struct.error: - continue - if data[self._p_idx[0]] != 3: # Not PT_INTERP. - continue - self._f.seek(data[self._p_idx[1]]) - return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0") - return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py deleted file mode 100644 index 86de1e6d599..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_manylinux.py +++ /dev/null @@ -1,278 +0,0 @@ -from __future__ import annotations - -import collections -import contextlib -import functools -import os -import re -import sys -import warnings -from typing import TYPE_CHECKING, NamedTuple - -from ._elffile import EIClass, EIData, ELFFile, EMachine - -if TYPE_CHECKING: - import types - from collections.abc import Generator, Iterator, Sequence - -EF_ARM_ABIMASK = 0xFF000000 -EF_ARM_ABI_VER5 = 0x05000000 -EF_ARM_ABI_FLOAT_HARD = 0x00000400 - -_ALLOWED_ARCHS = { - "x86_64", - "aarch64", - "ppc64", - "ppc64le", - "s390x", - "loongarch64", - "riscv64", -} - - -@contextlib.contextmanager -def _parse_elf(path: str) -> Generator[ELFFile | None, None, None]: - try: - with open(path, "rb") as f: - yield ELFFile(f) - except (OSError, TypeError, ValueError): - yield None - - -def _is_linux_armhf(executable: str) -> bool: - # hard-float ABI can be detected from the ELF header of the running - # process - # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf - with _parse_elf(executable) as f: - return ( - f is not None - and f.capacity == EIClass.C32 - and f.encoding == EIData.Lsb - and f.machine == EMachine.Arm - and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5 - and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD - ) - - -def _is_linux_i686(executable: str) -> bool: - with _parse_elf(executable) as f: - return ( - f is not None - and f.capacity == EIClass.C32 - and f.encoding == EIData.Lsb - and f.machine == EMachine.I386 - ) - - -def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool: - if "armv7l" in archs: - return _is_linux_armhf(executable) - if "i686" in archs: - return _is_linux_i686(executable) - return any(arch in _ALLOWED_ARCHS for arch in archs) - - -# If glibc ever changes its major version, we need to know what the last -# minor version was, so we can build the complete list of all versions. -# For now, guess what the highest minor version might be, assume it will -# be 50 for testing. Once this actually happens, update the dictionary -# with the actual value. -_LAST_GLIBC_MINOR: dict[int, int] = collections.defaultdict(lambda: 50) - - -class _GLibCVersion(NamedTuple): - major: int - minor: int - - -def _glibc_version_string_confstr() -> str | None: - """ - Primary implementation of glibc_version_string using os.confstr. - """ - # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely - # to be broken or missing. This strategy is used in the standard library - # platform module. - # https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183 - try: - # Should be a string like "glibc 2.17". - version_string: str | None = os.confstr("CS_GNU_LIBC_VERSION") - assert version_string is not None - _, version = version_string.rsplit() - except (AssertionError, AttributeError, OSError, ValueError): - # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... - return None - return version - - -def _glibc_version_string_ctypes() -> str | None: - """ - Fallback implementation of glibc_version_string using ctypes. - """ - try: - import ctypes # noqa: PLC0415 - except ImportError: - return None - - # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen - # manpage says, "If filename is NULL, then the returned handle is for the - # main program". This way we can let the linker do the work to figure out - # which libc our process is actually using. - # - # We must also handle the special case where the executable is not a - # dynamically linked executable. This can occur when using musl libc, - # for example. In this situation, dlopen() will error, leading to an - # OSError. Interestingly, at least in the case of musl, there is no - # errno set on the OSError. The single string argument used to construct - # OSError comes from libc itself and is therefore not portable to - # hard code here. In any case, failure to call dlopen() means we - # can proceed, so we bail on our attempt. - try: - process_namespace = ctypes.CDLL(None) - except OSError: - return None - - try: - gnu_get_libc_version = process_namespace.gnu_get_libc_version - except AttributeError: - # Symbol doesn't exist -> therefore, we are not linked to - # glibc. - return None - - # Call gnu_get_libc_version, which returns a string like "2.5". - gnu_get_libc_version.restype = ctypes.c_char_p - # A c_char_p restype comes back as bytes, so decode to text. - version_str: str | bytes = gnu_get_libc_version() - if isinstance(version_str, bytes): - version_str = version_str.decode("ascii") - - return version_str - - -def _glibc_version_string() -> str | None: - """Returns glibc version string, or None if not using glibc.""" - return _glibc_version_string_confstr() or _glibc_version_string_ctypes() - - -def _parse_glibc_version(version_str: str) -> _GLibCVersion: - """Parse glibc version. - - We use a regexp instead of str.split because we want to discard any - random junk that might come after the minor version -- this might happen - in patched/forked versions of glibc (e.g. Linaro's version of glibc - uses version strings like "2.20-2014.11"). See gh-3588. - """ - m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) - if not m: - warnings.warn( - f"Expected glibc version with 2 components major.minor, got: {version_str}", - RuntimeWarning, - stacklevel=2, - ) - return _GLibCVersion(-1, -1) - return _GLibCVersion(int(m.group("major")), int(m.group("minor"))) - - -@functools.lru_cache -def _get_glibc_version() -> _GLibCVersion: - version_str = _glibc_version_string() - if version_str is None: - return _GLibCVersion(-1, -1) - return _parse_glibc_version(version_str) - - -# From PEP 513, PEP 600 -@functools.lru_cache(maxsize=1) -def _get_manylinux_module() -> types.ModuleType | None: - """Return the ``_manylinux`` C extension module, or None if unavailable. - - The result is cached for the lifetime of the process, since the presence - of the module does not change while running. - """ - try: - return __import__("_manylinux") - except ImportError: - return None - - -def _is_compatible(arch: str, version: _GLibCVersion) -> bool: - sys_glibc = _get_glibc_version() - if sys_glibc < version: - return False - # Check for presence of _manylinux module. - manylinux_mod = _get_manylinux_module() - if manylinux_mod is None: - return True - if hasattr(manylinux_mod, "manylinux_compatible"): - result = manylinux_mod.manylinux_compatible(version[0], version[1], arch) - if result is not None: - return bool(result) - return True - if version == _GLibCVersion(2, 5) and hasattr( - manylinux_mod, "manylinux1_compatible" - ): - return bool(manylinux_mod.manylinux1_compatible) - if version == _GLibCVersion(2, 12) and hasattr( - manylinux_mod, "manylinux2010_compatible" - ): - return bool(manylinux_mod.manylinux2010_compatible) - if version == _GLibCVersion(2, 17) and hasattr( - manylinux_mod, "manylinux2014_compatible" - ): - return bool(manylinux_mod.manylinux2014_compatible) - return True - - -_LEGACY_MANYLINUX_MAP: dict[_GLibCVersion, str] = { - # CentOS 7 w/ glibc 2.17 (PEP 599) - _GLibCVersion(2, 17): "manylinux2014", - # CentOS 6 w/ glibc 2.12 (PEP 571) - _GLibCVersion(2, 12): "manylinux2010", - # CentOS 5 w/ glibc 2.5 (PEP 513) - _GLibCVersion(2, 5): "manylinux1", -} - - -def platform_tags(archs: Sequence[str]) -> Iterator[str]: - """Generate manylinux tags compatible to the current platform. - - :param archs: Sequence of compatible architectures. - The first one shall be the closest to the actual architecture and be the part of - platform tag after the ``linux_`` prefix, e.g. ``x86_64``. - The ``linux_`` prefix is assumed as a prerequisite for the current platform to - be manylinux-compatible. - - :returns: An iterator of compatible manylinux tags. - """ - if not _have_compatible_abi(sys.executable, archs): - return - # Oldest glibc to be supported regardless of architecture is (2, 17). - too_old_glibc2 = _GLibCVersion(2, 16) - if set(archs) & {"x86_64", "i686"}: - # On x86/i686 also oldest glibc to be supported is (2, 5). - too_old_glibc2 = _GLibCVersion(2, 4) - current_glibc = _GLibCVersion(*_get_glibc_version()) - glibc_max_list = [current_glibc] - # We can assume compatibility across glibc major versions. - # https://sourceware.org/bugzilla/show_bug.cgi?id=24636 - # - # Build a list of maximum glibc versions so that we can - # output the canonical list of all glibc from current_glibc - # down to too_old_glibc2, including all intermediary versions. - for glibc_major in range(current_glibc.major - 1, 1, -1): - glibc_minor = _LAST_GLIBC_MINOR[glibc_major] - glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor)) - for arch in archs: - for glibc_max in glibc_max_list: - if glibc_max.major == too_old_glibc2.major: - min_minor = too_old_glibc2.minor - else: - # For other glibc major versions oldest supported is (x, 0). - min_minor = -1 - for glibc_minor in range(glibc_max.minor, min_minor, -1): - glibc_version = _GLibCVersion(glibc_max.major, glibc_minor) - if _is_compatible(arch, glibc_version): - yield "manylinux_{}_{}_{}".format(*glibc_version, arch) - - # Handle the legacy manylinux1, manylinux2010, manylinux2014 tags. - if legacy_tag := _LEGACY_MANYLINUX_MAP.get(glibc_version): - yield f"{legacy_tag}_{arch}" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py deleted file mode 100644 index 74c4136f535..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_musllinux.py +++ /dev/null @@ -1,88 +0,0 @@ -"""PEP 656 support. - -This module implements logic to detect if the currently running Python is -linked against musl, and what musl version is used. -""" - -from __future__ import annotations - -import functools -import re -import subprocess -import sys -from typing import TYPE_CHECKING, NamedTuple - -from ._elffile import ELFFile - -if TYPE_CHECKING: - from collections.abc import Iterator, Sequence - - -class _MuslVersion(NamedTuple): - major: int - minor: int - - -def _parse_musl_version(output: str) -> _MuslVersion | None: - lines = [n for n in (n.strip() for n in output.splitlines()) if n] - if len(lines) < 2 or lines[0][:4] != "musl": - return None - m = re.match(r"Version (\d+)\.(\d+)", lines[1]) - if not m: - return None - return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2))) - - -@functools.lru_cache -def _get_musl_version(executable: str) -> _MuslVersion | None: - """Detect currently-running musl runtime version. - - This is done by checking the specified executable's dynamic linking - information, and invoking the loader to parse its output for a version - string. If the loader is musl, the output would be something like:: - - musl libc (x86_64) - Version 1.2.2 - Dynamic Program Loader - """ - try: - with open(executable, "rb") as f: - ld = ELFFile(f).interpreter - except (OSError, TypeError, ValueError): - return None - if ld is None or "musl" not in ld: - return None - proc = subprocess.run([ld], check=False, stderr=subprocess.PIPE, text=True) - return _parse_musl_version(proc.stderr) - - -def platform_tags(archs: Sequence[str]) -> Iterator[str]: - """Generate musllinux tags compatible to the current platform. - - :param archs: Sequence of compatible architectures. - The first one shall be the closest to the actual architecture and be the part of - platform tag after the ``linux_`` prefix, e.g. ``x86_64``. - The ``linux_`` prefix is assumed as a prerequisite for the current platform to - be musllinux-compatible. - - :returns: An iterator of compatible musllinux tags. - """ - sys_musl = _get_musl_version(sys.executable) - if sys_musl is None: # Python not dynamically linked against musl. - return - for arch in archs: - for minor in range(sys_musl.minor, -1, -1): - yield f"musllinux_{sys_musl.major}_{minor}_{arch}" - - -if __name__ == "__main__": # pragma: no cover - import sysconfig - - plat = sysconfig.get_platform() - assert plat.startswith("linux-"), "not linux" - - print("plat:", plat) - print("musl:", _get_musl_version(sys.executable)) - print("tags:", end=" ") - for t in platform_tags([re.sub(r"[.-]", "_", plat.split("-", 1)[-1])]): - print(t, end="\n ") diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py deleted file mode 100644 index 9331b4b4c01..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_parser.py +++ /dev/null @@ -1,418 +0,0 @@ -"""Handwritten parser of dependency specifiers. - -The docstring for each __parse_* function contains EBNF-inspired grammar representing -the implementation. -""" - -from __future__ import annotations - -import ast -from collections.abc import Sequence -from typing import Literal, NamedTuple, Union - -from ._tokenizer import DEFAULT_RULES, ParserSyntaxError, Tokenizer - - -class Node: - __slots__ = ("value",) - - def __init__(self, value: str) -> None: - self.value = value - - def __str__(self) -> str: - return self.value - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}({self.value!r})>" - - def serialize(self) -> str: - raise NotImplementedError - - def __getstate__(self) -> str: - # Return just the value string for compactness and stability. - return self.value - - def _restore_value(self, value: object) -> None: - if not isinstance(value, str): - raise TypeError( - f"Cannot restore {self.__class__.__name__} value from {value!r}" - ) - self.value = value - - def __setstate__(self, state: object) -> None: - if isinstance(state, str): - # New format (26.2+): just the value string. - self._restore_value(state) - return - if isinstance(state, tuple) and len(state) == 2: - # Old format (packaging <= 26.0, __slots__): (None, {slot: value}). - _, slot_dict = state - if isinstance(slot_dict, dict) and "value" in slot_dict: - self._restore_value(slot_dict["value"]) - return - if isinstance(state, dict) and "value" in state: - # Old format (packaging <= 25.0, no __slots__): plain __dict__. - self._restore_value(state["value"]) - return - raise TypeError(f"Cannot restore {self.__class__.__name__} from {state!r}") - - -class Variable(Node): - __slots__ = () - - def serialize(self) -> str: - return str(self) - - -class Value(Node): - __slots__ = () - - def serialize(self) -> str: - value = str(self) - if '"' not in value: - return f'"{value}"' - if "'" not in value: - return f"'{value}'" - raise ValueError( - "Cannot serialize marker value containing both quote characters" - ) - - -class Op(Node): - __slots__ = () - - def serialize(self) -> str: - return str(self) - - -MarkerLogical = Literal["and", "or"] -MarkerVar = Union[Variable, Value] -MarkerItem = tuple[MarkerVar, Op, MarkerVar] -MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]] -MarkerList = list[Union["MarkerList", MarkerAtom, MarkerLogical]] - - -class ParsedRequirement(NamedTuple): - name: str - url: str - extras: list[str] - specifier: str - marker: MarkerList | None - - -# -------------------------------------------------------------------------------------- -# Recursive descent parser for dependency specifier -# -------------------------------------------------------------------------------------- -def parse_requirement(source: str) -> ParsedRequirement: - return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES)) - - -def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement: - """ - requirement = WS? IDENTIFIER WS? extras WS? requirement_details - """ - tokenizer.consume("WS") - - name_token = tokenizer.expect( - "IDENTIFIER", expected="package name at the start of dependency specifier" - ) - name = name_token.text - tokenizer.consume("WS") - - extras = _parse_extras(tokenizer) - tokenizer.consume("WS") - - url, specifier, marker = _parse_requirement_details(tokenizer) - tokenizer.expect("END", expected="end of dependency specifier") - - return ParsedRequirement(name, url, extras, specifier, marker) - - -def _parse_requirement_details( - tokenizer: Tokenizer, -) -> tuple[str, str, MarkerList | None]: - """ - requirement_details = AT URL (WS requirement_marker?)? - | specifier WS? (requirement_marker)? - """ - - specifier = "" - url = "" - marker = None - - if tokenizer.check("AT"): - tokenizer.read() - tokenizer.consume("WS") - - url_start = tokenizer.position - url = tokenizer.expect("URL", expected="URL after @").text - if tokenizer.check("END", peek=True): - return (url, specifier, marker) - - tokenizer.expect("WS", expected="whitespace after URL") - - # The input might end after whitespace. - if tokenizer.check("END", peek=True): - return (url, specifier, marker) - - marker = _parse_requirement_marker( - tokenizer, - span_start=url_start, - expected="semicolon (after URL and whitespace)", - ) - else: - specifier_start = tokenizer.position - specifier = _parse_specifier(tokenizer) - tokenizer.consume("WS") - - if tokenizer.check("END", peek=True): - return (url, specifier, marker) - - marker = _parse_requirement_marker( - tokenizer, - span_start=specifier_start, - expected=( - "comma (within version specifier), semicolon (after version specifier)" - if specifier - else "semicolon (after name with no version specifier)" - ), - ) - - return (url, specifier, marker) - - -def _parse_requirement_marker( - tokenizer: Tokenizer, *, span_start: int, expected: str -) -> MarkerList: - """ - requirement_marker = SEMICOLON marker WS? - """ - - if not tokenizer.check("SEMICOLON"): - tokenizer.raise_syntax_error( - f"Expected {expected} or end", - span_start=span_start, - span_end=None, - ) - tokenizer.read() - - marker = _parse_marker(tokenizer) - tokenizer.consume("WS") - - return marker - - -def _parse_extras(tokenizer: Tokenizer) -> list[str]: - """ - extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)? - """ - if not tokenizer.check("LEFT_BRACKET", peek=True): - return [] - - with tokenizer.enclosing_tokens( - "LEFT_BRACKET", - "RIGHT_BRACKET", - around="extras", - ): - tokenizer.consume("WS") - extras = _parse_extras_list(tokenizer) - tokenizer.consume("WS") - - return extras - - -def _parse_extras_list(tokenizer: Tokenizer) -> list[str]: - """ - extras_list = identifier (wsp* ',' wsp* identifier)* - """ - extras: list[str] = [] - - if not tokenizer.check("IDENTIFIER"): - return extras - - extras.append(tokenizer.read().text) - - while True: - tokenizer.consume("WS") - if tokenizer.check("IDENTIFIER", peek=True): - tokenizer.raise_syntax_error("Expected comma between extra names") - elif not tokenizer.check("COMMA"): - break - - tokenizer.read() - tokenizer.consume("WS") - - extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma") - extras.append(extra_token.text) - - return extras - - -def _parse_specifier(tokenizer: Tokenizer) -> str: - """ - specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS - | WS? version_many WS? - """ - with tokenizer.enclosing_tokens( - "LEFT_PARENTHESIS", - "RIGHT_PARENTHESIS", - around="version specifier", - ): - tokenizer.consume("WS") - parsed_specifiers = _parse_version_many(tokenizer) - tokenizer.consume("WS") - - return parsed_specifiers - - -def _parse_version_many(tokenizer: Tokenizer) -> str: - """ - version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)? - """ - parsed_specifiers = "" - while tokenizer.check("SPECIFIER"): - span_start = tokenizer.position - specifier = tokenizer.read().text - parsed_specifiers += specifier - if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True): - message = ".* suffix can only be used with `==` or `!=` operators" - if specifier.startswith("!=") or ( - specifier.startswith("==") and not specifier.startswith("===") - ): - message = ( - ".* suffix cannot be used with pre-release, post-release, " - "dev or local versions" - ) - tokenizer.raise_syntax_error( - message, - span_start=span_start, - span_end=tokenizer.position + 1, - ) - if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True): - tokenizer.raise_syntax_error( - "Local version label can only be used with `==` or `!=` operators", - span_start=span_start, - span_end=tokenizer.position, - ) - tokenizer.consume("WS") - if not tokenizer.check("COMMA"): - break - parsed_specifiers += tokenizer.read().text - tokenizer.consume("WS") - - return parsed_specifiers - - -# -------------------------------------------------------------------------------------- -# Recursive descent parser for marker expression -# -------------------------------------------------------------------------------------- -def parse_marker(source: str) -> MarkerList: - return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES)) - - -def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList: - retval = _parse_marker(tokenizer) - tokenizer.expect("END", expected="end of marker expression") - return retval - - -def _parse_marker(tokenizer: Tokenizer) -> MarkerList: - """ - marker = marker_atom (BOOLOP marker_atom)+ - """ - expression = [_parse_marker_atom(tokenizer)] - while tokenizer.check("BOOLOP"): - token = tokenizer.read() - expr_right = _parse_marker_atom(tokenizer) - expression.extend((token.text, expr_right)) - return expression - - -def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom: - """ - marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS? - | WS? marker_item WS? - """ - - tokenizer.consume("WS") - if tokenizer.check("LEFT_PARENTHESIS", peek=True): - with tokenizer.enclosing_tokens( - "LEFT_PARENTHESIS", - "RIGHT_PARENTHESIS", - around="marker expression", - ): - tokenizer.consume("WS") - marker: MarkerAtom = _parse_marker(tokenizer) - tokenizer.consume("WS") - else: - marker = _parse_marker_item(tokenizer) - tokenizer.consume("WS") - return marker - - -def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem: - """ - marker_item = WS? marker_var WS? marker_op WS? marker_var WS? - """ - tokenizer.consume("WS") - marker_var_left = _parse_marker_var(tokenizer) - tokenizer.consume("WS") - marker_op = _parse_marker_op(tokenizer) - tokenizer.consume("WS") - marker_var_right = _parse_marker_var(tokenizer) - tokenizer.consume("WS") - return (marker_var_left, marker_op, marker_var_right) - - -def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar: # noqa: RET503 - """ - marker_var = VARIABLE | QUOTED_STRING - """ - if tokenizer.check("VARIABLE"): - return process_env_var(tokenizer.read().text.replace(".", "_")) - elif tokenizer.check("QUOTED_STRING"): - token = tokenizer.read() - try: - return process_python_str(token.text) - except (SyntaxError, ValueError) as exc: - raise ParserSyntaxError( - "Invalid quoted string", - source=tokenizer.source, - span=(token.position, token.position + len(token.text)), - ) from exc - else: - tokenizer.raise_syntax_error( - message="Expected a marker variable or quoted string" - ) - - -def process_env_var(env_var: str) -> Variable: - if env_var in ("platform_python_implementation", "python_implementation"): - return Variable("platform_python_implementation") - else: - return Variable(env_var) - - -def process_python_str(python_str: str) -> Value: - value = ast.literal_eval(python_str) - return Value(str(value)) - - -def _parse_marker_op(tokenizer: Tokenizer) -> Op: - """ - marker_op = IN | NOT IN | OP - """ - if tokenizer.check("IN"): - tokenizer.read() - return Op("in") - elif tokenizer.check("NOT"): - tokenizer.read() - tokenizer.expect("WS", expected="whitespace after 'not'") - tokenizer.expect("IN", expected="'in' after 'not'") - return Op("not in") - elif tokenizer.check("OP"): - return Op(tokenizer.read().text) - else: - return tokenizer.raise_syntax_error( - "Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in" - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py deleted file mode 100644 index 5370ec87e61..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_ranges.py +++ /dev/null @@ -1,836 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -"""Private version-range helpers used by :mod:`packaging.specifiers`.""" - -from __future__ import annotations - -import enum -import functools -from typing import ( - TYPE_CHECKING, - Any, - Final, -) - -from .version import InvalidVersion, Version - -if TYPE_CHECKING: - from collections.abc import Callable, Iterable, Iterator, Sequence - from typing import Union - - # Total-order key for comparing two boundaries (boundary-vs-boundary only). - # The post slot may be ``_BOUNDARY_INF`` for an AFTER_POSTS boundary. - _BoundaryOrderSuffix = tuple[int, int, int, Union[int, float], int, int] - _BoundaryOrderKey = tuple[int, tuple[int, ...], _BoundaryOrderSuffix, float] - -__all__ = [ - "FULL_RANGE", - "bounds_for_spec", - "coerce_version", - "filter_by_ranges", - "intersect_ranges", - "intersect_specifier_bounds", - "least_version_above", - "matches_bounds_only", - "range_is_empty", - "ranges_are_prerelease_only", - "resolve_prereleases", - "standard_ranges", - "wildcard_ranges", -] - -#: The smallest possible PEP 440 version. No valid version is less than this. -MIN_VERSION: Final[Version] = Version("0.dev0") - -#: The smallest non-pre-release version, i.e. the nearest non-pre-release at or -#: above the ``-inf`` floor. -MIN_RELEASE: Final[Version] = Version("0") - -#: Sorts above any real post number and any local label, so a boundary can be -#: ordered above the version family it covers when two boundaries are compared. -_BOUNDARY_INF: Final[float] = float("inf") - - -class BoundaryKind(enum.Enum): - """Where a boundary marker sits in the version ordering.""" - - AFTER_LOCALS = enum.auto() # after V+local, before V.post0 - AFTER_POSTS = enum.auto() # after V.postN, before next release - - -@functools.total_ordering -class BoundaryVersion: - """A point on the version line between two real PEP 440 versions. - - Relative to a base version V:: - - V < V+local < AFTER_LOCALS(V) < V.post0 < AFTER_POSTS(V) - - AFTER_LOCALS is the upper bound of ``<=V``, ``==V``, ``!=V`` (no - local), and the lower bound of the upper-side range of ``!=V``. - AFTER_POSTS is the lower bound of ``>V`` (V final or pre-release), - excluding V's post-releases per PEP 440. - """ - - __slots__ = ( - "_cached_dev", - "_cached_epoch", - "_cached_post", - "_cached_pre", - "_cached_trimmed_release", - "kind", - "version", - ) - - def __init__(self, version: Version, kind: BoundaryKind) -> None: - self.version = version - self.kind = kind - self._cached_trimmed_release = trim_release(version.release) - self._cached_epoch = version.epoch - self._cached_pre = version.pre - self._cached_post = version.post - self._cached_dev = version.dev - - def _is_family(self, other: Version) -> bool: - """Is ``other`` a version that this boundary sorts above?""" - if other.epoch != self._cached_epoch: - return False - # Inline release-trim comparison: other.release matches the - # trimmed release iff its leading slice is equal and any extra - # components are zero. Avoids trim_release's tuple allocation. - other_release = other.release - trimmed_release = self._cached_trimmed_release - trimmed_length = len(trimmed_release) - if len(other_release) < trimmed_length: - return False - if other_release[:trimmed_length] != trimmed_release: - return False - for i in range(trimmed_length, len(other_release)): - if other_release[i] != 0: - return False - if other.pre != self._cached_pre: - return False - if self.kind == BoundaryKind.AFTER_LOCALS: - # Local family: same public version, any local label. - return other.post == self._cached_post and other.dev == self._cached_dev - # Post family: V itself + any post-release of V. - return other.dev == self._cached_dev or other.post is not None - - def _order_key(self) -> _BoundaryOrderKey: - """Sort key placing this boundary just above the versions it covers. - - It extends ``V``'s comparison key ``(epoch, release, suffix)`` with - a trailing ``_BOUNDARY_INF`` local component, so the key sorts after - ``V`` and every ``V+local`` (whose keys carry a real, finite local - segment). ``suffix`` is the 6-int comparison suffix - ``(pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)``. - - For an AFTER_POSTS boundary the suffix is replaced with one whose - post number is ``_BOUNDARY_INF``, so the key also sorts after every - ``V.postN``. An AFTER_LOCALS boundary uses ``V``'s suffix unchanged. - """ - version_key = self.version._key - suffix: _BoundaryOrderSuffix = version_key[2] - - if self.kind == BoundaryKind.AFTER_POSTS: - suffix = (suffix[0], suffix[1], 1, _BOUNDARY_INF, 1, 0) - - return version_key[0], version_key[1], suffix, _BOUNDARY_INF - - def __eq__(self, other: object) -> bool: - # Key off the order key so equality matches the ``<`` / ``>`` order: - # ``AFTER_POSTS(1.0)`` and ``AFTER_POSTS(1.0.post1)`` are the same point. - if isinstance(other, BoundaryVersion): - return self._order_key() == other._order_key() - return NotImplemented - - def __lt__(self, other: BoundaryVersion | Version) -> bool: - if isinstance(other, BoundaryVersion): - return self._order_key() < other._order_key() - # boundary < other_version iff V < other AND other not in family. - # The cheap V >= other path short-circuits before the family check. - if not (self.version < other): - return False - return not self._is_family(other) - - def __gt__(self, other: BoundaryVersion | Version) -> bool: - # Defined directly to bypass functools.total_ordering's - # NotImplemented round-trip on reflected ``Version < boundary``. - if isinstance(other, BoundaryVersion): - return self._order_key() > other._order_key() - if self.version >= other: - return True - return self._is_family(other) - - def __hash__(self) -> int: - # Keyed to ``__eq__`` (the order key), so equal boundaries hash equal. - return hash(self._order_key()) - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.version!r}, {self.kind.name})" - - -if TYPE_CHECKING: - _VersionOrBoundary = Union[Version, BoundaryVersion, None] - - -@functools.total_ordering -class LowerBound: - """Lower bound of a version range. - - A version *v* of ``None`` means unbounded below (-inf). - At equal versions, ``[v`` sorts before ``(v`` because an inclusive - bound starts earlier. - """ - - __slots__ = ("_above", "inclusive", "version") - - def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None: - self.version = version - self.inclusive = inclusive - # Pre-bind a predicate "is parsed at or above this lower - # bound?" for the hot filter / contains loops. One direct - # call per check, no operator-dispatch chain. - if version is None: - self._above: Callable[[Version], bool] | None = None - elif isinstance(version, BoundaryVersion): - # >V produces an AFTER_POSTS lower bound; the upper-side - # range of !=V produces an AFTER_LOCALS lower bound. - if version.kind == BoundaryKind.AFTER_POSTS: - self._above = _make_above_after_posts(version.version) - else: - self._above = _make_above_after_locals(version.version) - elif inclusive: - self._above = version.__le__ - else: - self._above = version.__lt__ - - def __eq__(self, other: object) -> bool: - if not isinstance(other, LowerBound): - return NotImplemented - return self.version == other.version and self.inclusive == other.inclusive - - def __lt__(self, other: LowerBound) -> bool: - if not isinstance(other, LowerBound): - return NotImplemented - # -inf < anything (except -inf itself). - if self.version is None: - return other.version is not None - if other.version is None: - return False - if self.version != other.version: - return self.version < other.version - # [v < (v: inclusive starts earlier. - return self.inclusive and not other.inclusive - - def __hash__(self) -> int: - return hash((self.version, self.inclusive)) - - def __repr__(self) -> str: - bracket = "[" if self.inclusive else "(" - return f"<{self.__class__.__name__} {bracket}{self.version!r}>" - - -@functools.total_ordering -class UpperBound: - """Upper bound of a version range. - - A version *v* of ``None`` means unbounded above (+inf). - At equal versions, ``v)`` sorts before ``v]`` because an exclusive - bound ends earlier. - """ - - __slots__ = ("_below", "inclusive", "version") - - def __init__(self, version: _VersionOrBoundary, inclusive: bool) -> None: - self.version = version - self.inclusive = inclusive - # Pre-bind a predicate "is parsed at or below this upper - # bound?". See LowerBound for the rationale. - if version is None: - self._below: Callable[[Version], bool] | None = None - elif isinstance(version, BoundaryVersion): - # Standard specifiers only ever produce AFTER_LOCALS upper - # bounds (from <=V / ==V / !=V with no local). - if version.kind == BoundaryKind.AFTER_LOCALS: - self._below = _make_below_after_locals(version.version) - else: - # An AFTER_POSTS upper is not produced by any specifier, but - # range algebra reaches it: complementing ``>V`` flips the - # ``AFTER_POSTS(V)`` lower into this upper bound. - self._below = version.__ge__ - elif inclusive: - self._below = version.__ge__ - else: - self._below = version.__gt__ - - def __eq__(self, other: object) -> bool: - if not isinstance(other, UpperBound): - return NotImplemented - return self.version == other.version and self.inclusive == other.inclusive - - def __lt__(self, other: UpperBound) -> bool: - if not isinstance(other, UpperBound): - return NotImplemented - # Nothing < +inf (except +inf itself). - if self.version is None: - return False - if other.version is None: - return True - if self.version != other.version: - return self.version < other.version - # v) < v]: exclusive ends earlier. - return not self.inclusive and other.inclusive - - def __hash__(self) -> int: - return hash((self.version, self.inclusive)) - - def __repr__(self) -> str: - bracket = "]" if self.inclusive else ")" - return f"<{self.__class__.__name__} {self.version!r}{bracket}>" - - -if TYPE_CHECKING: - #: A single contiguous interval as a (lower, upper) bound pair. - Interval = tuple[LowerBound, UpperBound] - - -NEG_INF: Final[LowerBound] = LowerBound(None, False) -POS_INF: Final[UpperBound] = UpperBound(None, False) -FULL_RANGE: Final[tuple[Interval]] = ((NEG_INF, POS_INF),) - - -def trim_release(release: tuple[int, ...]) -> tuple[int, ...]: - """Strip trailing zeros from a release tuple for normalized comparison.""" - end = len(release) - while end > 1 and release[end - 1] == 0: - end -= 1 - return release if end == len(release) else release[:end] - - -def _next_prefix_dev0(version: Version) -> Version: - """Smallest version in the next prefix: 1.2 -> 1.3.dev0.""" - release = (*version.release[:-1], version.release[-1] + 1) - return Version.from_parts(epoch=version.epoch, release=release, dev=0) - - -def _base_dev0(version: Version) -> Version: - """The .dev0 of a version's base release: 1.2 -> 1.2.dev0.""" - return Version.from_parts(epoch=version.epoch, release=version.release, dev=0) - - -def coerce_version(version: Version | str) -> Version | None: - if not isinstance(version, Version): - try: - version = Version(version) - except InvalidVersion: - return None - return version - - -def _make_above_after_posts(version: Version) -> Callable[[Version], bool]: - """Predicate ``parsed > AFTER_POSTS(V)`` for a lower bound. - - Per PEP 440, ``>V`` excludes V's post-releases unless V is itself - a post-release. AFTER_POSTS sits above V and every V.postN (with - or without local), and just below the next release. - """ - version_ge = version.__ge__ - version_epoch = version.epoch - version_pre = version.pre - version_release_trimmed = trim_release(version.release) - trimmed_length = len(version_release_trimmed) - - def above(parsed: Version) -> bool: - if version_ge(parsed): - return False - # parsed > V cmpkey-wise: above the boundary iff NOT in V's - # post family. - if parsed.epoch != version_epoch: - return True - parsed_release = parsed.release - if len(parsed_release) < trimmed_length: - return True - if parsed_release[:trimmed_length] != version_release_trimmed: - return True - for i in range(trimmed_length, len(parsed_release)): - if parsed_release[i] != 0: - return True - if parsed.pre != version_pre: - return True - - # Same release and pre as V: parsed is in V's post family (V itself, - # V+local, or V.postN), which the boundary sits above. A V.devN - # (different dev, no post) sorts before V and was already caught by - # ``version_ge`` above, so the answer here is always "not above". - return False - - return above - - -def _make_above_after_locals(version: Version) -> Callable[[Version], bool]: - """Predicate ``parsed > AFTER_LOCALS(V)`` for a lower bound. - - Used by the upper-side range of ``!=V`` (when V has no local - segment). AFTER_LOCALS sits above V and every ``V+local`` but - just below ``V.post0``. - """ - version_ge = version.__ge__ - version_epoch = version.epoch - version_pre = version.pre - version_post = version.post - version_dev = version.dev - version_release_trimmed = trim_release(version.release) - trimmed_length = len(version_release_trimmed) - - def above(parsed: Version) -> bool: - if version_ge(parsed): - return False - # parsed > V cmpkey-wise: above the boundary iff NOT in V's - # local family (same public version, any local segment). - if parsed.epoch != version_epoch: - return True - parsed_release = parsed.release - if len(parsed_release) < trimmed_length: - return True - if parsed_release[:trimmed_length] != version_release_trimmed: - return True - for i in range(trimmed_length, len(parsed_release)): - if parsed_release[i] != 0: - return True - if parsed.pre != version_pre: - return True - if parsed.post != version_post: - return True - return parsed.dev != version_dev - - return above - - -def _make_below_after_locals(version: Version) -> Callable[[Version], bool]: - """Predicate ``parsed <= AFTER_LOCALS(V)`` for an upper bound. - - Used by ``<=V``, ``==V``, ``!=V`` (no local). ``parsed`` is at or - below the boundary when it is at or below V cmpkey-wise, or when - it is in V's local family. - """ - version_ge = version.__ge__ - version_epoch = version.epoch - version_pre = version.pre - version_post = version.post - version_dev = version.dev - version_release_trimmed = trim_release(version.release) - trimmed_length = len(version_release_trimmed) - - def below(parsed: Version) -> bool: - if version_ge(parsed): - return True - # parsed > V cmpkey-wise: below the boundary iff in V's local - # family. - if parsed.epoch != version_epoch: - return False - parsed_release = parsed.release - if len(parsed_release) < trimmed_length: - return False - if parsed_release[:trimmed_length] != version_release_trimmed: - return False - for i in range(trimmed_length, len(parsed_release)): - if parsed_release[i] != 0: - return False - if parsed.pre != version_pre: - return False - if parsed.post != version_post: - return False - return parsed.dev == version_dev - - return below - - -def least_version_above(boundary: BoundaryVersion) -> Version | None: - """Smallest real version strictly above *boundary*, or ``None`` if none exists.""" - base = boundary.version - - if boundary.kind == BoundaryKind.AFTER_LOCALS: - # AFTER_LOCALS(V) sits just below V.post0, so its least successor is - # V.post0.dev0 (V.dev(N+1) if V has a dev, V.post(N+1).dev0 if a post). - if base.dev is not None: - return base.__replace__(dev=base.dev + 1, local=None) - next_post = (base.post + 1) if base.post is not None else 0 - return base.__replace__(post=next_post, dev=0, local=None) - - # AFTER_POSTS(V): a pre-release V steps to the next pre-release's .dev0; - # a final-release AFTER_POSTS has no least successor. - if base.pre is not None: - kind, number = base.pre - return base.__replace__(pre=(kind, number + 1), post=None, dev=0, local=None) - - return None - - -def range_is_empty(lower: LowerBound, upper: UpperBound) -> bool: - """True when the range defined by *lower* and *upper* contains no versions. - - A boundary lower sits just below the next real version, so an ordered pair - is still empty when the upper excludes that least successor: - ``(AFTER_POSTS(1.0a1), 1.0a2.dev0)`` holds no version. - """ - if upper.version is None: - return False - - if lower.version is None: - # Nothing sorts below MIN_VERSION, so an exclusive upper at or below it - # leaves an empty floor interval such as ``(-inf, 0.dev0)``. - return ( - not upper.inclusive - and isinstance(upper.version, Version) - and upper.version <= MIN_VERSION - ) - - if isinstance(lower.version, BoundaryVersion): - successor = least_version_above(lower.version) - if successor is not None: - if upper.version == successor: - return not upper.inclusive - return upper.version < successor - - if lower.version == upper.version: - return not (lower.inclusive and upper.inclusive) - - return lower.version > upper.version - - -def intersect_ranges( - left: Sequence[Interval], - right: Sequence[Interval], -) -> list[Interval]: - """Intersect two sorted, non-overlapping range lists (two-pointer merge).""" - result: list[Interval] = [] - left_index = right_index = 0 - while left_index < len(left) and right_index < len(right): - left_lower, left_upper = left[left_index] - right_lower, right_upper = right[right_index] - - lower = max(left_lower, right_lower) - upper = min(left_upper, right_upper) - - if not range_is_empty(lower, upper): - result.append((lower, upper)) - - # Advance whichever side has the smaller upper bound. - if left_upper < right_upper: - left_index += 1 - else: - right_index += 1 - - return result - - -def filter_by_ranges( - ranges: Sequence[Interval], - iterable: Iterable[Any], - key: Callable[[Any], Version | str] | None, - prereleases: bool | None, - region: Sequence[Interval] = (), -) -> Iterator[Any]: - """Filter *iterable* against precomputed version *ranges*. - - With ``prereleases=None``, the PEP 440 default applies: pre-releases are - excluded unless no final matches, in which case buffered pre-releases come - out at the end. A pre-release inside the opt-in ``region`` is the exception: - it is force-admitted in place, as ``prereleases=True`` would yield it. A - force-admitted pre-release is not a final, so it never suppresses the buffer. - """ - if prereleases is None: - prerelease_buffer: list[Any] = [] - found_final = False - - if len(ranges) == 1: - # Hot path: most specifiers and small SpecifierSets reduce to - # a single contiguous range. - lower, upper = ranges[0] - above = lower._above - below = upper._below - for item in iterable: - parsed = coerce_version(item if key is None else key(item)) - if parsed is None: - continue - if above is not None and not above(parsed): - continue - if below is not None and not below(parsed): - continue - if not parsed.is_prerelease: - found_final = True - yield item - elif region and matches_bounds_only(region, parsed): - yield item - elif not found_final: - prerelease_buffer.append(item) - if not found_final: - yield from prerelease_buffer - return - - for item in iterable: - parsed = coerce_version(item if key is None else key(item)) - if parsed is None: - continue - for lower, upper in ranges: - above = lower._above - if above is not None and not above(parsed): - break - below = upper._below - if below is None or below(parsed): - if not parsed.is_prerelease: - found_final = True - yield item - elif region and matches_bounds_only(region, parsed): - yield item - elif not found_final: - prerelease_buffer.append(item) - break - if not found_final: - yield from prerelease_buffer - return - - exclude_prereleases = prereleases is False - - if len(ranges) == 1: - # Hot path: most specifiers and small SpecifierSets reduce to - # a single contiguous range. - lower, upper = ranges[0] - above = lower._above - below = upper._below - for item in iterable: - parsed = coerce_version(item if key is None else key(item)) - if parsed is None: - continue - if exclude_prereleases and parsed.is_prerelease: - continue - if above is not None and not above(parsed): - continue - if below is None or below(parsed): - yield item - return - - for item in iterable: - parsed = coerce_version(item if key is None else key(item)) - if parsed is None: - continue - if exclude_prereleases and parsed.is_prerelease: - continue - for lower, upper in ranges: - above = lower._above - if above is not None and not above(parsed): - break - below = upper._below - if below is None or below(parsed): - yield item - break - - -def _nearest_release_above_prerelease(version: Version) -> Version: - """Smallest non-pre-release at or above a pre-release *version*.""" - if version.pre is not None: - # An a/b/rc pre-release drops to its final release, which outranks - # every post-release of that pre-release (1.0a1.post0 -> 1.0). - return version.__replace__(pre=None, post=None, dev=None, local=None) - - # A dev-only release keeps its post-release (1.0.post0.dev0 -> 1.0.post0, - # whose final 1.0 sorts below it). - return version.__replace__(dev=None, local=None) - - -def _lowest_release_at_or_above(value: Version | BoundaryVersion | None) -> Version: - """Smallest non-pre-release version at or above *value*. - - ``None`` is the ``-inf`` floor, whose nearest non-pre-release is - :data:`MIN_RELEASE`. - """ - if value is None: - return MIN_RELEASE - if isinstance(value, BoundaryVersion): - inner_version = value.version - if inner_version.is_prerelease: - return _nearest_release_above_prerelease(inner_version) - # AFTER_LOCALS(1.0) -> nearest non-pre is 1.0.post0 - # AFTER_LOCALS(1.0.post0) -> nearest non-pre is 1.0.post1 - next_post = (inner_version.post + 1) if inner_version.post is not None else 0 - return inner_version.__replace__(post=next_post, local=None) - - if not value.is_prerelease: - return value - - return _nearest_release_above_prerelease(value) - - -def ranges_are_prerelease_only(ranges: Sequence[Interval]) -> bool: - """True when every range in *ranges* contains only pre-releases. - - Used to detect unsatisfiable specifier sets when ``prereleases=False``: - if every range is pre-release-only, every contained version is excluded. - """ - for lower, upper in ranges: - nearest = _lowest_release_at_or_above(lower.version) - if upper.version is None or nearest < upper.version: - return False - if nearest == upper.version and upper.inclusive: - return False - return True - - -def wildcard_ranges(op: str, base: Version) -> list[Interval]: - """Ranges for ==V.* and !=V.*. - - ==1.2.* -> [1.2.dev0, 1.3.dev0); !=1.2.* -> complement. - """ - lower = _base_dev0(base) - upper = _next_prefix_dev0(base) - if op == "==": - return [(LowerBound(lower, True), UpperBound(upper, False))] - # != - return [ - (NEG_INF, UpperBound(lower, False)), - (LowerBound(upper, True), POS_INF), - ] - - -def standard_ranges(op: str, version: Version, has_local: bool) -> list[Interval]: - """Ranges for the standard PEP 440 operators (no wildcard, no ===). - - *has_local* indicates whether the spec string included a ``+local`` - segment; relevant only for ``==`` / ``!=`` to decide whether the - upper bound includes V's local family. - """ - if op == ">=": - return [(LowerBound(version, True), POS_INF)] - - if op == "<=": - return [ - ( - NEG_INF, - UpperBound(BoundaryVersion(version, BoundaryKind.AFTER_LOCALS), True), - ) - ] - - if op == ">": - if version.dev is not None: - # >V.devN: dev versions have no post-releases, so the - # next real version is V.dev(N+1). - lower_bound = version.__replace__(dev=version.dev + 1, local=None) - return [(LowerBound(lower_bound, True), POS_INF)] - if version.post is not None: - # >V.postN: next real version is V.post(N+1).dev0. - lower_bound = version.__replace__(post=version.post + 1, dev=0, local=None) - return [(LowerBound(lower_bound, True), POS_INF)] - # >V (final or pre-release V): exclude V itself, V+local, and - # every V.postN per PEP 440. - return [ - ( - LowerBound(BoundaryVersion(version, BoundaryKind.AFTER_POSTS), False), - POS_INF, - ) - ] - - if op == "<": - # list[Interval]: - """Ranges for one specifier's ``(op, version_str)``. - - Dispatches between the wildcard and standard builders. ``version`` is the - parsed ``version_str`` (its base, without the trailing ``.*``, for - wildcards). ``===`` is not handled here; its match is a literal string - compared in :mod:`packaging.specifiers`. - """ - if version_str.endswith(".*"): - return wildcard_ranges(op, version) - - return standard_ranges(op, version, "+" in version_str) - - -def intersect_specifier_bounds( - per_specifier_ranges: Iterable[Sequence[Interval]], -) -> Sequence[Interval]: - """Intersect each specifier's ranges into a single sequence. - - Short-circuits once the running intersection is empty, since no later - specifier can revive it. Callers must pass at least one specifier. - """ - result: Sequence[Interval] | None = None - for sub in per_specifier_ranges: - if result is None: - result = sub - else: - result = intersect_ranges(result, sub) - if not result: - break - - if result is None: # pragma: no cover - callers guard non-empty input - raise RuntimeError("intersect_specifier_bounds called with no specifiers") - - return result - - -def matches_bounds_only(ranges: Sequence[Interval], version: Version) -> bool: - """Whether ``version`` falls within any of ``ranges``. - - The pure bounds membership test, for a single already-parsed version with - no pre-release policy applied. ``ranges`` are sorted and non-overlapping, - so a version below one range's lower bound is below every later range too. - """ - for lower, upper in ranges: - above = lower._above - if above is not None and not above(version): - return False - - below = upper._below - if below is None or below(version): - return True - - return False - - -def resolve_prereleases( - configured: bool | None, autodetected: bool | None -) -> bool | None: - """Resolve a specifier's effective default pre-release policy. - - An explicit ``configured`` value wins; otherwise an autodetected ``True`` - propagates and anything else falls back to the PEP 440 default (``None``). - """ - if configured is not None: - return configured - - if autodetected: - return True - - return None diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py deleted file mode 100644 index 4306784d9a2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_structures.py +++ /dev/null @@ -1,33 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -"""Backward-compatibility shim for unpickling Version objects serialized before -packaging 26.1. - -Old pickles reference ``packaging._structures.InfinityType`` and -``packaging._structures.NegativeInfinityType``. This module provides minimal -stand-in classes so that ``pickle.loads()`` can resolve those references. -The deserialized objects are not used for comparisons — ``Version.__setstate__`` -discards the stale ``_key`` cache and recomputes it from the core version fields. -""" - -from __future__ import annotations - - -class InfinityType: - """Stand-in for the removed ``InfinityType`` used in old comparison keys.""" - - def __repr__(self) -> str: - return "Infinity" - - -class NegativeInfinityType: - """Stand-in for the removed ``NegativeInfinityType`` used in old comparison keys.""" - - def __repr__(self) -> str: - return "-Infinity" - - -Infinity = InfinityType() -NegativeInfinity = NegativeInfinityType() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py deleted file mode 100644 index db7cd17fbad..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/_tokenizer.py +++ /dev/null @@ -1,200 +0,0 @@ -from __future__ import annotations - -import contextlib -import re -from dataclasses import dataclass -from typing import TYPE_CHECKING, NoReturn - -from .specifiers import Specifier - -if TYPE_CHECKING: - from collections.abc import Generator, Mapping - - -@dataclass -class Token: - __slots__ = ("name", "position", "text") - - name: str - text: str - position: int - - -class ParserSyntaxError(Exception): - """The provided source text could not be parsed correctly.""" - - def __init__( - self, - message: str, - *, - source: str, - span: tuple[int, int], - ) -> None: - self.span = span - self.message = message - self.source = source - - super().__init__() - - def __str__(self) -> str: - marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^" - return f"{self.message}\n {self.source}\n {marker}" - - -DEFAULT_RULES: dict[str, re.Pattern[str]] = { - "LEFT_PARENTHESIS": re.compile(r"\("), - "RIGHT_PARENTHESIS": re.compile(r"\)"), - "LEFT_BRACKET": re.compile(r"\["), - "RIGHT_BRACKET": re.compile(r"\]"), - "SEMICOLON": re.compile(r";"), - "COMMA": re.compile(r","), - "QUOTED_STRING": re.compile( - r""" - ( - ('[^']*') - | - ("[^"]*") - ) - """, - re.VERBOSE, - ), - "OP": re.compile(r"(===|==|~=|!=|<=|>=|<|>)"), - "BOOLOP": re.compile(r"\b(or|and)\b"), - "IN": re.compile(r"\bin\b"), - "NOT": re.compile(r"\bnot\b"), - "VARIABLE": re.compile( - r""" - \b( - python_version - |python_full_version - |os[._]name - |sys[._]platform - |platform_(release|system) - |platform[._](version|machine|python_implementation) - |python_implementation - |implementation_(name|version) - |extras? - |dependency_groups - )\b - """, - re.VERBOSE, - ), - "SPECIFIER": re.compile( - Specifier._specifier_regex_str, - re.VERBOSE | re.IGNORECASE, - ), - "AT": re.compile(r"\@"), - "URL": re.compile(r"[^ \t]+"), - "IDENTIFIER": re.compile(r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b"), - "VERSION_PREFIX_TRAIL": re.compile(r"\.\*"), - "VERSION_LOCAL_LABEL_TRAIL": re.compile(r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*"), - "WS": re.compile(r"[ \t]+"), - "END": re.compile(r"\Z"), -} - - -class Tokenizer: - """Context-sensitive token parsing. - - Provides methods to examine the input stream to check whether the next token - matches. - """ - - __slots__ = ("next_token", "position", "rules", "source") - - def __init__( - self, - source: str, - *, - rules: Mapping[str, re.Pattern[str]], - ) -> None: - self.source = source - self.rules = rules - self.next_token: Token | None = None - self.position = 0 - - def consume(self, name: str) -> None: - """Move beyond provided token name, if at current position.""" - if self.check(name): - self.read() - - def check(self, name: str, *, peek: bool = False) -> bool: - """Check whether the next token has the provided name. - - By default, if the check succeeds, the token *must* be read before - another check. If `peek` is set to `True`, the token is not loaded and - would need to be checked again. - """ - assert self.next_token is None, ( - f"Cannot check for {name!r}, already have {self.next_token!r}" - ) - assert name in self.rules, f"Unknown token name: {name!r}" - - expression = self.rules[name] - - match = expression.match(self.source, self.position) - if match is None: - return False - if not peek: - self.next_token = Token(name, match[0], self.position) - return True - - def expect(self, name: str, *, expected: str) -> Token: - """Expect a certain token name next, failing with a syntax error otherwise. - - The token is read and returned. - """ - if not self.check(name): - raise self.raise_syntax_error(f"Expected {expected}") - return self.read() - - def read(self) -> Token: - """Consume the next token and return it.""" - token = self.next_token - assert token is not None - - self.position += len(token.text) - self.next_token = None - - return token - - def raise_syntax_error( - self, - message: str, - *, - span_start: int | None = None, - span_end: int | None = None, - ) -> NoReturn: - """Raise ParserSyntaxError at the given position.""" - span = ( - self.position if span_start is None else span_start, - self.position if span_end is None else span_end, - ) - raise ParserSyntaxError( - message, - source=self.source, - span=span, - ) - - @contextlib.contextmanager - def enclosing_tokens( - self, open_token: str, close_token: str, *, around: str - ) -> Generator[None, None, None]: - if self.check(open_token): - open_position = self.position - self.read() - else: - open_position = None - - yield - - if open_position is None: - return - - if not self.check(close_token): - self.raise_syntax_error( - f"Expected matching {close_token} for {open_token}, after {around}", - span_start=open_position, - ) - - self.read() diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py deleted file mode 100644 index 0ad2d013cc2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/dependency_groups.py +++ /dev/null @@ -1,335 +0,0 @@ -from __future__ import annotations - -import re -from collections.abc import Mapping, Sequence - -from .errors import _ErrorCollector -from .requirements import InvalidRequirement, Requirement - -__all__ = [ - "CyclicDependencyGroup", - "DependencyGroupInclude", - "DependencyGroupResolver", - "DuplicateGroupNames", - "InvalidDependencyGroupObject", - "resolve_dependency_groups", -] - - -def __dir__() -> list[str]: - return __all__ - - -# ----------- -# Error Types -# ----------- - - -class DuplicateGroupNames(ValueError): - """ - The same dependency groups were defined twice, with different non-normalized names. - - .. versionadded:: 26.1 - """ - - -class CyclicDependencyGroup(ValueError): - """ - The dependency group includes form a cycle. - - .. versionadded:: 26.1 - """ - - def __init__(self, requested_group: str, group: str, include_group: str) -> None: - self.requested_group = requested_group - self.group = group - self.include_group = include_group - - if include_group == group: - reason = f"{group} includes itself" - else: - reason = f"{include_group} -> {group}, {group} -> {include_group}" - super().__init__( - "Cyclic dependency group include while resolving " - f"{requested_group}: {reason}" - ) - - # Support pickling; ``args`` does not match ``__init__``'s signature. - def __reduce__(self) -> tuple[type[CyclicDependencyGroup], tuple[str, str, str]]: - return (self.__class__, (self.requested_group, self.group, self.include_group)) - - -# in the PEP 735 spec, the tables in dependency group lists were described as -# "Dependency Object Specifiers", but the only defined type of object was a -# "Dependency Group Include" -- hence the naming of this error as "Object" -class InvalidDependencyGroupObject(ValueError): - """ - A member of a dependency group was identified as a dict, but was not in a valid - format. - - .. versionadded:: 26.1 - """ - - -# ------------------------ -# Object Model & Interface -# ------------------------ - - -class DependencyGroupInclude: - """ - A reference to another dependency group by name. - - .. versionadded:: 26.1 - """ - - __slots__ = ("include_group",) - - def __init__(self, include_group: str) -> None: - """ - Initialize a DependencyGroupInclude. - - :param include_group: The name of the group referred to by this include. - """ - self.include_group = include_group - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.include_group!r})" - - -class DependencyGroupResolver: - """ - A resolver for Dependency Group data. - - This class handles caching, name normalization, cycle detection, and other - parsing requirements. There are only two public methods for exploring the data: - ``lookup()`` and ``resolve()``. - - :param dependency_groups: A mapping, as provided via pyproject - ``[dependency-groups]``. - - .. versionadded:: 26.1 - """ - - def __init__( - self, - dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], - ) -> None: - errors = _ErrorCollector() - - self.dependency_groups = _normalize_group_names(dependency_groups, errors) - - # a map of group names to parsed data - self._parsed_groups: dict[ - str, tuple[Requirement | DependencyGroupInclude, ...] - ] = {} - # a map of group names to their ancestors, used for cycle detection - self._include_graph_ancestors: dict[str, tuple[str, ...]] = {} - # a cache of completed resolutions to Requirement lists - self._resolve_cache: dict[str, tuple[Requirement, ...]] = {} - - errors.finalize("[dependency-groups] data was invalid") - - def lookup(self, group: str) -> tuple[Requirement | DependencyGroupInclude, ...]: - """ - Lookup a group name, returning the parsed dependency data for that group. - This will not resolve includes. - - :param group: the name of the group to lookup - """ - group = _normalize_name(group) - - with _ErrorCollector().on_exit( - f"[dependency-groups] data for {group!r} was malformed" - ) as errors: - return self._parse_group(group, errors) - - def resolve(self, group: str) -> tuple[Requirement, ...]: - """ - Resolve a dependency group to a list of requirements. - - :param group: the name of the group to resolve - """ - group = _normalize_name(group) - - with _ErrorCollector().on_exit( - f"[dependency-groups] data for {group!r} was malformed" - ) as errors: - return self._resolve(group, group, errors) - - def _resolve( - self, group: str, requested_group: str, errors: _ErrorCollector - ) -> tuple[Requirement, ...]: - """ - This is a helper for cached resolution to strings. It preserves the name of the - group which the user initially requested in order to present a clearer error in - the event that a cycle is detected. - - :param group: The normalized name of the group to resolve. - :param requested_group: The group which was used in the original, user-facing - request. - """ - if group in self._resolve_cache: - return self._resolve_cache[group] - - parsed = self._parse_group(group, errors) - - resolved_group = [] - - for item in parsed: - if isinstance(item, Requirement): - resolved_group.append(item) - elif isinstance(item, DependencyGroupInclude): - include_group = _normalize_name(item.include_group) - - # if a group is cyclic, record the error - # otherwise, follow the include_group reference - # - # this allows us to examine all includes in a group, even in the - # presence of errors - if include_group in self._include_graph_ancestors.get(group, ()): - errors.error( - CyclicDependencyGroup( - requested_group, group, item.include_group - ) - ) - else: - self._include_graph_ancestors[include_group] = ( - *self._include_graph_ancestors.get(group, ()), - group, - ) - resolved_group.extend( - self._resolve(include_group, requested_group, errors) - ) - else: # pragma: no cover - raise NotImplementedError( - f"Invalid dependency group item after parse: {item}" - ) - - # in the event that errors were detected, present the group as empty and do not - # cache the result - # this ensures that repeated access to a cyclic group will raise multiple errors - if errors.errors: - return () - - self._resolve_cache[group] = tuple(resolved_group) - return self._resolve_cache[group] - - def _parse_group( - self, group: str, errors: _ErrorCollector - ) -> tuple[Requirement | DependencyGroupInclude, ...]: - # short circuit -- never do the work twice - if group in self._parsed_groups: - return self._parsed_groups[group] - - if group not in self.dependency_groups: - errors.error(LookupError(f"Dependency group '{group}' not found")) - return () - - raw_group = self.dependency_groups[group] - if isinstance(raw_group, str): - errors.error( - TypeError( - f"Dependency group {group!r} contained a string rather than a list." - ) - ) - return () - - if not isinstance(raw_group, Sequence): - errors.error( - TypeError(f"Dependency group {group!r} is not a sequence type.") - ) - return () - - elements: list[Requirement | DependencyGroupInclude] = [] - for item in raw_group: - if isinstance(item, str): - # packaging.requirements.Requirement parsing ensures that this is a - # valid PEP 508 Dependency Specifier. Collect InvalidRequirement - # if it throws that. - with errors.collect(InvalidRequirement): - elements.append(Requirement(item)) - elif isinstance(item, Mapping): - if tuple(item.keys()) != ("include-group",): - errors.error( - InvalidDependencyGroupObject( - f"Invalid dependency group item: {item!r}" - ) - ) - else: - include_group = item["include-group"] - if not isinstance(include_group, str): - msg = ( - "Dependency group include-group value is not a string: " - f"{item!r}" - ) - errors.error(TypeError(msg)) - else: - elements.append( - DependencyGroupInclude(include_group=include_group) - ) - else: - errors.error(TypeError(f"Invalid dependency group item: {item!r}")) - - if errors.errors: - return () - - self._parsed_groups[group] = tuple(elements) - return self._parsed_groups[group] - - -# -------------------- -# Functional Interface -# -------------------- - - -def resolve_dependency_groups( - dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], /, *groups: str -) -> tuple[str, ...]: - """ - Resolve a dependency group to a tuple of requirements, as strings. - - :param dependency_groups: the parsed contents of the ``[dependency-groups]`` table - from ``pyproject.toml`` - :param groups: the name of the group(s) to resolve - - .. versionadded:: 26.1 - """ - resolver = DependencyGroupResolver(dependency_groups) - return tuple(str(r) for group in groups for r in resolver.resolve(group)) - - -# ---------------- -# internal helpers -# ---------------- - - -_NORMALIZE_PATTERN = re.compile(r"[-_.]+") - - -def _normalize_name(name: str) -> str: - return _NORMALIZE_PATTERN.sub("-", name).lower() - - -def _normalize_group_names( - dependency_groups: Mapping[str, Sequence[str | Mapping[str, str]]], - errors: _ErrorCollector, -) -> dict[str, Sequence[str | Mapping[str, str]]]: - original_names: dict[str, list[str]] = {} - normalized_groups: dict[str, Sequence[str | Mapping[str, str]]] = {} - - for group_name, value in dependency_groups.items(): - normed_group_name = _normalize_name(group_name) - original_names.setdefault(normed_group_name, []).append(group_name) - normalized_groups[normed_group_name] = value - - for normed_name, names in original_names.items(): - if len(names) > 1: - errors.error( - DuplicateGroupNames( - "Duplicate dependency group names: " - f"{normed_name} ({', '.join(names)})" - ) - ) - - return normalized_groups diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py deleted file mode 100644 index 4090e3d8fd0..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/direct_url.py +++ /dev/null @@ -1,349 +0,0 @@ -from __future__ import annotations - -import dataclasses -import re -import urllib.parse -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, Protocol, TypeVar - -if TYPE_CHECKING: # pragma: no cover - import sys - from collections.abc import Collection - from urllib.parse import SplitResult - - if sys.version_info >= (3, 11): - from typing import Self - else: - from opentelemetry.agent._vendor.typing_extensions import Self - -__all__ = [ - "ArchiveInfo", - "DirInfo", - "DirectUrl", - "DirectUrlValidationError", - "VcsInfo", -] - - -def __dir__() -> list[str]: - return __all__ - - -_T = TypeVar("_T") - - -class _FromMappingProtocol(Protocol): # pragma: no cover - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: ... - - -_FromMappingProtocolT = TypeVar("_FromMappingProtocolT", bound=_FromMappingProtocol) - - -def _json_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]: - return {key: value for key, value in data if value is not None} - - -def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None: - """Get a value from the dictionary and verify it's the expected type.""" - if (value := d.get(key)) is None: - return None - if not isinstance(value, expected_type): - raise DirectUrlValidationError( - f"Unexpected type {type(value).__name__} " - f"(expected {expected_type.__name__})", - context=key, - ) - return value - - -def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T: - """Get a required value from the dictionary and verify it's the expected type.""" - if (value := _get(d, expected_type, key)) is None: - raise _DirectUrlRequiredKeyError(key) - return value - - -def _get_object( - d: Mapping[str, Any], target_type: type[_FromMappingProtocolT], key: str -) -> _FromMappingProtocolT | None: - """Get a dictionary value from the dictionary and convert it to a dataclass.""" - if (value := _get(d, Mapping, key)) is None: # type: ignore[type-abstract] - return None - try: - return target_type._from_dict(value) - except Exception as e: - raise DirectUrlValidationError(e, context=key) from e - - -_PEP610_USER_PASS_ENV_VARS_REGEX = re.compile( - r"^\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?$" -) - - -def _strip_auth_from_netloc(netloc: str, safe_user_passwords: Collection[str]) -> str: - if "@" not in netloc: - return netloc - user_pass, netloc_no_user_pass = netloc.rsplit("@", 1) - if user_pass in safe_user_passwords: - return netloc - if _PEP610_USER_PASS_ENV_VARS_REGEX.match(user_pass): - return netloc - return netloc_no_user_pass - - -def _strip_url(url: str, safe_user_passwords: Collection[str]) -> str: - """url with user:password part removed unless it is formed with - environment variables as specified in PEP 610, or it is a safe user:password - such as `git`. - """ - parsed_url = urllib.parse.urlsplit(url) - netloc = _strip_auth_from_netloc(parsed_url.netloc, safe_user_passwords) - return urllib.parse.urlunsplit( - ( - parsed_url.scheme, - netloc, - parsed_url.path, - parsed_url.query, - parsed_url.fragment, - ) - ) - - -def _file_url_has_absolute_path(parsed_url: SplitResult) -> bool: - return parsed_url.path.startswith("/") - - -class DirectUrlValidationError(Exception): - """Raised when when input data is not spec-compliant. - - .. versionadded:: 26.1 - """ - - context: str | None = None - message: str - - def __init__( - self, - cause: str | Exception, - *, - context: str | None = None, - ) -> None: - if isinstance(cause, DirectUrlValidationError): - if cause.context: - self.context = ( - f"{context}.{cause.context}" if context else cause.context - ) - else: - self.context = context # pragma: no cover - self.message = cause.message - else: - self.context = context - self.message = str(cause) - - def __str__(self) -> str: - if self.context: - return f"{self.message} in {self.context!r}" - return self.message - - -class _DirectUrlRequiredKeyError(DirectUrlValidationError): - def __init__(self, key: str) -> None: - super().__init__("Missing required value", context=key) - - -@dataclasses.dataclass(frozen=True, init=False) -class VcsInfo: - """The version control information of a :class:`DirectUrl`.""" - - vcs: str - commit_id: str - requested_revision: str | None = None - - def __init__( - self, - *, - vcs: str, - commit_id: str, - requested_revision: str | None = None, - ) -> None: - object.__setattr__(self, "vcs", vcs) - object.__setattr__(self, "commit_id", commit_id) - object.__setattr__(self, "requested_revision", requested_revision) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - # We can't validate vcs value because is not closed. - return cls( - vcs=_get_required(d, str, "vcs"), - requested_revision=_get(d, str, "requested_revision"), - commit_id=_get_required(d, str, "commit_id"), - ) - - -@dataclasses.dataclass(frozen=True, init=False) -class ArchiveInfo: - """The archive information of a :class:`DirectUrl`.""" - - hashes: Mapping[str, str] | None = None - - def __init__( - self, - *, - hashes: Mapping[str, str] | None = None, - ) -> None: - object.__setattr__(self, "hashes", hashes) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - hashes = _get(d, Mapping, "hashes") # type: ignore[type-abstract] - if hashes is not None and not all(isinstance(h, str) for h in hashes.values()): - raise DirectUrlValidationError( - "Hash values must be strings", context="hashes" - ) - legacy_hash = _get(d, str, "hash") - if legacy_hash is not None: - if "=" not in legacy_hash: - raise DirectUrlValidationError( - "Invalid hash format (expected '=')", - context="hash", - ) - hash_algorithm, hash_value = legacy_hash.split("=", 1) - if hashes is None: - # if `hashes` are not present, we can derive it from the legacy `hash` - hashes = {hash_algorithm: hash_value} - else: - # if `hashes` are present, the legacy `hash` must match one of them - if hash_algorithm not in hashes: - raise DirectUrlValidationError( - f"Algorithm {hash_algorithm!r} used in hash field " - f"is not present in hashes field", - context="hashes", - ) - if hashes[hash_algorithm] != hash_value: - raise DirectUrlValidationError( - f"Algorithm {hash_algorithm!r} used in hash field " - f"has different value in hashes field", - context="hash", - ) - return cls(hashes=hashes) - - -@dataclasses.dataclass(frozen=True, init=False) -class DirInfo: - """The local directory information of a :class:`DirectUrl`.""" - - editable: bool | None = None - - def __init__( - self, - *, - editable: bool | None = None, - ) -> None: - object.__setattr__(self, "editable", editable) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - return cls( - editable=_get(d, bool, "editable"), - ) - - -@dataclasses.dataclass(frozen=True, init=False) -class DirectUrl: - """A class representing a direct URL. - - .. versionadded:: 26.1 - """ - - url: str - archive_info: ArchiveInfo | None = None - vcs_info: VcsInfo | None = None - dir_info: DirInfo | None = None - subdirectory: str | None = None # XXX Path or str? - - def __init__( - self, - *, - url: str, - archive_info: ArchiveInfo | None = None, - vcs_info: VcsInfo | None = None, - dir_info: DirInfo | None = None, - subdirectory: str | None = None, - ) -> None: - object.__setattr__(self, "url", url) - object.__setattr__(self, "archive_info", archive_info) - object.__setattr__(self, "vcs_info", vcs_info) - object.__setattr__(self, "dir_info", dir_info) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - direct_url = cls( - url=_get_required(d, str, "url"), - archive_info=_get_object(d, ArchiveInfo, "archive_info"), - vcs_info=_get_object(d, VcsInfo, "vcs_info"), - dir_info=_get_object(d, DirInfo, "dir_info"), - subdirectory=_get(d, str, "subdirectory"), - ) - if ( - bool(direct_url.vcs_info) - + bool(direct_url.archive_info) - + bool(direct_url.dir_info) - ) != 1: - raise DirectUrlValidationError( - "Exactly one of vcs_info, archive_info, dir_info must be present" - ) - if direct_url.dir_info is not None: - parsed_url = urllib.parse.urlsplit(direct_url.url) - if parsed_url.scheme != "file": - raise DirectUrlValidationError( - "URL scheme must be file:// when dir_info is present", - context="url", - ) - if not _file_url_has_absolute_path(parsed_url): - raise DirectUrlValidationError( - "File URL must be absolute when dir_info is present", - context="url", - ) - # XXX subdirectory must be relative, can we, should we validate that here? - return direct_url - - @classmethod - def from_dict(cls, d: Mapping[str, Any], /) -> Self: - """Create and validate a DirectUrl instance from a JSON dictionary.""" - return cls._from_dict(d) - - def to_dict( - self, - *, - generate_legacy_hash: bool = False, - strip_user_password: bool = True, - safe_user_passwords: Collection[str] = ("git",), - ) -> Mapping[str, Any]: - """Convert the DirectUrl instance to a JSON dictionary. - - :param generate_legacy_hash: If True, include a legacy `hash` field in - `archive_info` for backward compatibility with tools that don't - support the `hashes` field. - :param strip_user_password: If True, strip user:password from the URL - unless it is formed with environment variables as specified in PEP - 610, or it is a safe user:password such as `git`. - :param safe_user_passwords: A collection of user:password strings that - should not be stripped from the URL even if `strip_user_password` is - True. - """ - res = dataclasses.asdict(self, dict_factory=_json_dict_factory) - if generate_legacy_hash and self.archive_info and self.archive_info.hashes: - hash_algorithm, hash_value = next(iter(self.archive_info.hashes.items())) - res["archive_info"]["hash"] = f"{hash_algorithm}={hash_value}" - if strip_user_password: - res["url"] = _strip_url(self.url, safe_user_passwords) - return res - - def validate(self) -> None: - """Validate the DirectUrl instance against the specification. - - Raises :class:`DirectUrlValidationError` if invalid. - """ - self.from_dict(self.to_dict()) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py deleted file mode 100644 index d1d47cf6c34..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/errors.py +++ /dev/null @@ -1,94 +0,0 @@ -from __future__ import annotations - -import contextlib -import dataclasses -import sys -import typing - -__all__ = ["ExceptionGroup"] - - -def __dir__() -> list[str]: - return __all__ - - -if sys.version_info >= (3, 11): # pragma: no cover - from builtins import ExceptionGroup -else: # pragma: no cover - - class ExceptionGroup(Exception): - """A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11. - - If :external:exc:`ExceptionGroup` is already defined by Python itself, - that version is used instead. - """ - - message: str - exceptions: list[Exception] - - def __init__(self, message: str, exceptions: list[Exception]) -> None: - self.message = message - self.exceptions = exceptions - - def __repr__(self) -> str: - return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})" - - -@dataclasses.dataclass -class _ErrorCollector: - """ - Collect errors into ExceptionGroups. - - Used like this: - - collector = _ErrorCollector() - # Add a single exception - collector.error(ValueError("one")) - - # Supports nesting, including combining ExceptionGroups - with collector.collect(): - raise ValueError("two") - collector.finalize("Found some errors") - - Since making a collector and then calling finalize later is a common pattern, - a convenience method ``on_exit`` is provided. - """ - - errors: list[Exception] = dataclasses.field(default_factory=list, init=False) - - def finalize(self, msg: str) -> None: - """Raise a group exception if there are any errors.""" - if self.errors: - raise ExceptionGroup(msg, self.errors) - - @contextlib.contextmanager - def on_exit(self, msg: str) -> typing.Generator[_ErrorCollector, None, None]: - """ - Calls finalize if no uncollected errors were present. - - Uncollected errors are raised normally. - """ - yield self - self.finalize(msg) - - @contextlib.contextmanager - def collect(self, *err_cls: type[Exception]) -> typing.Generator[None, None, None]: - """ - Context manager to collect errors into the error list. - - Must be inside loops, as only one error can be collected at a time. - """ - error_classes = err_cls or (Exception,) - try: - yield - except ExceptionGroup as error: - self.errors.extend(error.exceptions) - except error_classes as error: - self.errors.append(error) - - def error( - self, - error: Exception, - ) -> None: - """Add an error to the list.""" - self.errors.append(error) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py deleted file mode 100644 index f95ac02e230..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/__init__.py +++ /dev/null @@ -1,198 +0,0 @@ -####################################################################################### -# -# Adapted from: -# https://github.com/pypa/hatch/blob/5352e44/backend/src/hatchling/licenses/parse.py -# -# MIT License -# -# Copyright (c) 2017-present Ofek Lev -# -# Permission is hereby granted, free of charge, to any person obtaining a copy of this -# software and associated documentation files (the "Software"), to deal in the Software -# without restriction, including without limitation the rights to use, copy, modify, -# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to the following -# conditions: -# -# The above copyright notice and this permission notice shall be included in all copies -# or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# -# With additional allowance of arbitrary `LicenseRef-` identifiers, not just -# `LicenseRef-Public-Domain` and `LicenseRef-Proprietary`. -# -####################################################################################### -from __future__ import annotations - -import re -from typing import NewType, cast - -from ._spdx import EXCEPTIONS, LICENSES - -__all__ = [ - "InvalidLicenseExpression", - "NormalizedLicenseExpression", - "canonicalize_license_expression", -] - - -# Simple __dir__ implementation since there are no public submodules -def __dir__() -> list[str]: - return __all__ - - -license_ref_allowed = re.compile("^[A-Za-z0-9.-]+$") - -NormalizedLicenseExpression = NewType("NormalizedLicenseExpression", str) -""" -A :class:`typing.NewType` of :class:`str`, representing a normalized -License-Expression. -""" - - -class InvalidLicenseExpression(ValueError): - """Raised when a license-expression string is invalid - - >>> from packaging.licenses import canonicalize_license_expression - >>> canonicalize_license_expression("invalid") - Traceback (most recent call last): - ... - packaging.licenses.InvalidLicenseExpression: Unknown license: 'invalid' - """ - - -def canonicalize_license_expression( - raw_license_expression: str, -) -> NormalizedLicenseExpression: - """ - This function takes a valid License-Expression, and returns the normalized - form of it. - - The return type is typed as :class:`NormalizedLicenseExpression`. This - allows type checkers to help require that a string has passed through this - function before use. - - :param str raw_license_expression: The License-Expression to canonicalize. - :raises InvalidLicenseExpression: If the License-Expression is invalid due to an - invalid/unknown license identifier or invalid syntax. - - .. doctest:: - - >>> from packaging.licenses import canonicalize_license_expression - >>> canonicalize_license_expression("mit") - 'MIT' - >>> canonicalize_license_expression("mit and (apache-2.0 or bsd-2-clause)") - 'MIT AND (Apache-2.0 OR BSD-2-Clause)' - >>> canonicalize_license_expression("(mit") - Traceback (most recent call last): - ... - InvalidLicenseExpression: Invalid license expression: '(mit' - >>> canonicalize_license_expression("Use-it-after-midnight") - Traceback (most recent call last): - ... - InvalidLicenseExpression: Unknown license: 'Use-it-after-midnight' - """ - if not raw_license_expression: - message = f"Invalid license expression: {raw_license_expression!r}" - raise InvalidLicenseExpression(message) - - # Pad any parentheses so tokenization can be achieved by merely splitting on - # whitespace. - license_expression = raw_license_expression.replace("(", " ( ").replace(")", " ) ") - licenseref_prefix = "LicenseRef-" - license_refs = { - ref.lower(): "LicenseRef-" + ref[len(licenseref_prefix) :] - for ref in license_expression.split() - if ref.lower().startswith(licenseref_prefix.lower()) - } - - # Normalize to lower case so we can look up licenses/exceptions - # and so boolean operators are Python-compatible. - license_expression = license_expression.lower() - - tokens = license_expression.split() - - # Rather than implementing a parenthesis/boolean logic parser, create an - # expression that Python can parse. Everything that is not involved with the - # grammar itself is replaced with the placeholder `False` and the resultant - # expression should become a valid Python expression. - python_tokens = [] - for token in tokens: - if token not in {"or", "and", "with", "(", ")"}: - python_tokens.append("False") - elif token == "with": - python_tokens.append("or") - elif ( - token == "(" - and python_tokens - and python_tokens[-1] not in {"or", "and", "("} - ) or (token == ")" and python_tokens and python_tokens[-1] == "("): - message = f"Invalid license expression: {raw_license_expression!r}" - raise InvalidLicenseExpression(message) - else: - python_tokens.append(token) - - python_expression = " ".join(python_tokens) - try: - compile(python_expression, "", "eval") - except SyntaxError: - message = f"Invalid license expression: {raw_license_expression!r}" - raise InvalidLicenseExpression(message) from None - - # Take a final pass to check for unknown licenses/exceptions. - normalized_tokens = [] - last_license_start = False - for index, token in enumerate(tokens): - if token in {"or", "and", "with", "(", ")"}: - if token == "with" and ( - not last_license_start - or index + 1 == len(tokens) - or tokens[index + 1] in {"or", "and", "with", "(", ")"} - ): - message = f"Invalid license expression: {raw_license_expression!r}" - raise InvalidLicenseExpression(message) - normalized_tokens.append(token.upper()) - last_license_start = False - continue - - if normalized_tokens and normalized_tokens[-1] == "WITH": - if token not in EXCEPTIONS: - message = f"Unknown license exception: {token!r}" - raise InvalidLicenseExpression(message) - - normalized_tokens.append(EXCEPTIONS[token]["id"]) - last_license_start = False - else: - if token.endswith("+"): - final_token = token[:-1] - suffix = "+" - else: - final_token = token - suffix = "" - - if final_token.startswith("licenseref-"): - license_ref_id = final_token[len("licenseref-") :] - if suffix or not license_ref_allowed.match(license_ref_id): - message = f"Invalid licenseref: {token!r}" - raise InvalidLicenseExpression(message) - normalized_tokens.append(license_refs[final_token]) - else: - if final_token not in LICENSES: - message = f"Unknown license: {final_token!r}" - raise InvalidLicenseExpression(message) - normalized_tokens.append(LICENSES[final_token]["id"] + suffix) - last_license_start = True - - normalized_expression = " ".join(normalized_tokens) - - return cast( - "NormalizedLicenseExpression", - normalized_expression.replace("( ", "(").replace(" )", ")"), - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py deleted file mode 100644 index a277af28220..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/licenses/_spdx.py +++ /dev/null @@ -1,799 +0,0 @@ - -from __future__ import annotations - -from typing import TypedDict - -class SPDXLicense(TypedDict): - id: str - deprecated: bool - -class SPDXException(TypedDict): - id: str - deprecated: bool - - -VERSION = '3.27.0' - -LICENSES: dict[str, SPDXLicense] = { - '0bsd': {'id': '0BSD', 'deprecated': False}, - '3d-slicer-1.0': {'id': '3D-Slicer-1.0', 'deprecated': False}, - 'aal': {'id': 'AAL', 'deprecated': False}, - 'abstyles': {'id': 'Abstyles', 'deprecated': False}, - 'adacore-doc': {'id': 'AdaCore-doc', 'deprecated': False}, - 'adobe-2006': {'id': 'Adobe-2006', 'deprecated': False}, - 'adobe-display-postscript': {'id': 'Adobe-Display-PostScript', 'deprecated': False}, - 'adobe-glyph': {'id': 'Adobe-Glyph', 'deprecated': False}, - 'adobe-utopia': {'id': 'Adobe-Utopia', 'deprecated': False}, - 'adsl': {'id': 'ADSL', 'deprecated': False}, - 'afl-1.1': {'id': 'AFL-1.1', 'deprecated': False}, - 'afl-1.2': {'id': 'AFL-1.2', 'deprecated': False}, - 'afl-2.0': {'id': 'AFL-2.0', 'deprecated': False}, - 'afl-2.1': {'id': 'AFL-2.1', 'deprecated': False}, - 'afl-3.0': {'id': 'AFL-3.0', 'deprecated': False}, - 'afmparse': {'id': 'Afmparse', 'deprecated': False}, - 'agpl-1.0': {'id': 'AGPL-1.0', 'deprecated': True}, - 'agpl-1.0-only': {'id': 'AGPL-1.0-only', 'deprecated': False}, - 'agpl-1.0-or-later': {'id': 'AGPL-1.0-or-later', 'deprecated': False}, - 'agpl-3.0': {'id': 'AGPL-3.0', 'deprecated': True}, - 'agpl-3.0-only': {'id': 'AGPL-3.0-only', 'deprecated': False}, - 'agpl-3.0-or-later': {'id': 'AGPL-3.0-or-later', 'deprecated': False}, - 'aladdin': {'id': 'Aladdin', 'deprecated': False}, - 'amd-newlib': {'id': 'AMD-newlib', 'deprecated': False}, - 'amdplpa': {'id': 'AMDPLPA', 'deprecated': False}, - 'aml': {'id': 'AML', 'deprecated': False}, - 'aml-glslang': {'id': 'AML-glslang', 'deprecated': False}, - 'ampas': {'id': 'AMPAS', 'deprecated': False}, - 'antlr-pd': {'id': 'ANTLR-PD', 'deprecated': False}, - 'antlr-pd-fallback': {'id': 'ANTLR-PD-fallback', 'deprecated': False}, - 'any-osi': {'id': 'any-OSI', 'deprecated': False}, - 'any-osi-perl-modules': {'id': 'any-OSI-perl-modules', 'deprecated': False}, - 'apache-1.0': {'id': 'Apache-1.0', 'deprecated': False}, - 'apache-1.1': {'id': 'Apache-1.1', 'deprecated': False}, - 'apache-2.0': {'id': 'Apache-2.0', 'deprecated': False}, - 'apafml': {'id': 'APAFML', 'deprecated': False}, - 'apl-1.0': {'id': 'APL-1.0', 'deprecated': False}, - 'app-s2p': {'id': 'App-s2p', 'deprecated': False}, - 'apsl-1.0': {'id': 'APSL-1.0', 'deprecated': False}, - 'apsl-1.1': {'id': 'APSL-1.1', 'deprecated': False}, - 'apsl-1.2': {'id': 'APSL-1.2', 'deprecated': False}, - 'apsl-2.0': {'id': 'APSL-2.0', 'deprecated': False}, - 'arphic-1999': {'id': 'Arphic-1999', 'deprecated': False}, - 'artistic-1.0': {'id': 'Artistic-1.0', 'deprecated': False}, - 'artistic-1.0-cl8': {'id': 'Artistic-1.0-cl8', 'deprecated': False}, - 'artistic-1.0-perl': {'id': 'Artistic-1.0-Perl', 'deprecated': False}, - 'artistic-2.0': {'id': 'Artistic-2.0', 'deprecated': False}, - 'artistic-dist': {'id': 'Artistic-dist', 'deprecated': False}, - 'aspell-ru': {'id': 'Aspell-RU', 'deprecated': False}, - 'aswf-digital-assets-1.0': {'id': 'ASWF-Digital-Assets-1.0', 'deprecated': False}, - 'aswf-digital-assets-1.1': {'id': 'ASWF-Digital-Assets-1.1', 'deprecated': False}, - 'baekmuk': {'id': 'Baekmuk', 'deprecated': False}, - 'bahyph': {'id': 'Bahyph', 'deprecated': False}, - 'barr': {'id': 'Barr', 'deprecated': False}, - 'bcrypt-solar-designer': {'id': 'bcrypt-Solar-Designer', 'deprecated': False}, - 'beerware': {'id': 'Beerware', 'deprecated': False}, - 'bitstream-charter': {'id': 'Bitstream-Charter', 'deprecated': False}, - 'bitstream-vera': {'id': 'Bitstream-Vera', 'deprecated': False}, - 'bittorrent-1.0': {'id': 'BitTorrent-1.0', 'deprecated': False}, - 'bittorrent-1.1': {'id': 'BitTorrent-1.1', 'deprecated': False}, - 'blessing': {'id': 'blessing', 'deprecated': False}, - 'blueoak-1.0.0': {'id': 'BlueOak-1.0.0', 'deprecated': False}, - 'boehm-gc': {'id': 'Boehm-GC', 'deprecated': False}, - 'boehm-gc-without-fee': {'id': 'Boehm-GC-without-fee', 'deprecated': False}, - 'borceux': {'id': 'Borceux', 'deprecated': False}, - 'brian-gladman-2-clause': {'id': 'Brian-Gladman-2-Clause', 'deprecated': False}, - 'brian-gladman-3-clause': {'id': 'Brian-Gladman-3-Clause', 'deprecated': False}, - 'bsd-1-clause': {'id': 'BSD-1-Clause', 'deprecated': False}, - 'bsd-2-clause': {'id': 'BSD-2-Clause', 'deprecated': False}, - 'bsd-2-clause-darwin': {'id': 'BSD-2-Clause-Darwin', 'deprecated': False}, - 'bsd-2-clause-first-lines': {'id': 'BSD-2-Clause-first-lines', 'deprecated': False}, - 'bsd-2-clause-freebsd': {'id': 'BSD-2-Clause-FreeBSD', 'deprecated': True}, - 'bsd-2-clause-netbsd': {'id': 'BSD-2-Clause-NetBSD', 'deprecated': True}, - 'bsd-2-clause-patent': {'id': 'BSD-2-Clause-Patent', 'deprecated': False}, - 'bsd-2-clause-pkgconf-disclaimer': {'id': 'BSD-2-Clause-pkgconf-disclaimer', 'deprecated': False}, - 'bsd-2-clause-views': {'id': 'BSD-2-Clause-Views', 'deprecated': False}, - 'bsd-3-clause': {'id': 'BSD-3-Clause', 'deprecated': False}, - 'bsd-3-clause-acpica': {'id': 'BSD-3-Clause-acpica', 'deprecated': False}, - 'bsd-3-clause-attribution': {'id': 'BSD-3-Clause-Attribution', 'deprecated': False}, - 'bsd-3-clause-clear': {'id': 'BSD-3-Clause-Clear', 'deprecated': False}, - 'bsd-3-clause-flex': {'id': 'BSD-3-Clause-flex', 'deprecated': False}, - 'bsd-3-clause-hp': {'id': 'BSD-3-Clause-HP', 'deprecated': False}, - 'bsd-3-clause-lbnl': {'id': 'BSD-3-Clause-LBNL', 'deprecated': False}, - 'bsd-3-clause-modification': {'id': 'BSD-3-Clause-Modification', 'deprecated': False}, - 'bsd-3-clause-no-military-license': {'id': 'BSD-3-Clause-No-Military-License', 'deprecated': False}, - 'bsd-3-clause-no-nuclear-license': {'id': 'BSD-3-Clause-No-Nuclear-License', 'deprecated': False}, - 'bsd-3-clause-no-nuclear-license-2014': {'id': 'BSD-3-Clause-No-Nuclear-License-2014', 'deprecated': False}, - 'bsd-3-clause-no-nuclear-warranty': {'id': 'BSD-3-Clause-No-Nuclear-Warranty', 'deprecated': False}, - 'bsd-3-clause-open-mpi': {'id': 'BSD-3-Clause-Open-MPI', 'deprecated': False}, - 'bsd-3-clause-sun': {'id': 'BSD-3-Clause-Sun', 'deprecated': False}, - 'bsd-4-clause': {'id': 'BSD-4-Clause', 'deprecated': False}, - 'bsd-4-clause-shortened': {'id': 'BSD-4-Clause-Shortened', 'deprecated': False}, - 'bsd-4-clause-uc': {'id': 'BSD-4-Clause-UC', 'deprecated': False}, - 'bsd-4.3reno': {'id': 'BSD-4.3RENO', 'deprecated': False}, - 'bsd-4.3tahoe': {'id': 'BSD-4.3TAHOE', 'deprecated': False}, - 'bsd-advertising-acknowledgement': {'id': 'BSD-Advertising-Acknowledgement', 'deprecated': False}, - 'bsd-attribution-hpnd-disclaimer': {'id': 'BSD-Attribution-HPND-disclaimer', 'deprecated': False}, - 'bsd-inferno-nettverk': {'id': 'BSD-Inferno-Nettverk', 'deprecated': False}, - 'bsd-protection': {'id': 'BSD-Protection', 'deprecated': False}, - 'bsd-source-beginning-file': {'id': 'BSD-Source-beginning-file', 'deprecated': False}, - 'bsd-source-code': {'id': 'BSD-Source-Code', 'deprecated': False}, - 'bsd-systemics': {'id': 'BSD-Systemics', 'deprecated': False}, - 'bsd-systemics-w3works': {'id': 'BSD-Systemics-W3Works', 'deprecated': False}, - 'bsl-1.0': {'id': 'BSL-1.0', 'deprecated': False}, - 'busl-1.1': {'id': 'BUSL-1.1', 'deprecated': False}, - 'bzip2-1.0.5': {'id': 'bzip2-1.0.5', 'deprecated': True}, - 'bzip2-1.0.6': {'id': 'bzip2-1.0.6', 'deprecated': False}, - 'c-uda-1.0': {'id': 'C-UDA-1.0', 'deprecated': False}, - 'cal-1.0': {'id': 'CAL-1.0', 'deprecated': False}, - 'cal-1.0-combined-work-exception': {'id': 'CAL-1.0-Combined-Work-Exception', 'deprecated': False}, - 'caldera': {'id': 'Caldera', 'deprecated': False}, - 'caldera-no-preamble': {'id': 'Caldera-no-preamble', 'deprecated': False}, - 'catharon': {'id': 'Catharon', 'deprecated': False}, - 'catosl-1.1': {'id': 'CATOSL-1.1', 'deprecated': False}, - 'cc-by-1.0': {'id': 'CC-BY-1.0', 'deprecated': False}, - 'cc-by-2.0': {'id': 'CC-BY-2.0', 'deprecated': False}, - 'cc-by-2.5': {'id': 'CC-BY-2.5', 'deprecated': False}, - 'cc-by-2.5-au': {'id': 'CC-BY-2.5-AU', 'deprecated': False}, - 'cc-by-3.0': {'id': 'CC-BY-3.0', 'deprecated': False}, - 'cc-by-3.0-at': {'id': 'CC-BY-3.0-AT', 'deprecated': False}, - 'cc-by-3.0-au': {'id': 'CC-BY-3.0-AU', 'deprecated': False}, - 'cc-by-3.0-de': {'id': 'CC-BY-3.0-DE', 'deprecated': False}, - 'cc-by-3.0-igo': {'id': 'CC-BY-3.0-IGO', 'deprecated': False}, - 'cc-by-3.0-nl': {'id': 'CC-BY-3.0-NL', 'deprecated': False}, - 'cc-by-3.0-us': {'id': 'CC-BY-3.0-US', 'deprecated': False}, - 'cc-by-4.0': {'id': 'CC-BY-4.0', 'deprecated': False}, - 'cc-by-nc-1.0': {'id': 'CC-BY-NC-1.0', 'deprecated': False}, - 'cc-by-nc-2.0': {'id': 'CC-BY-NC-2.0', 'deprecated': False}, - 'cc-by-nc-2.5': {'id': 'CC-BY-NC-2.5', 'deprecated': False}, - 'cc-by-nc-3.0': {'id': 'CC-BY-NC-3.0', 'deprecated': False}, - 'cc-by-nc-3.0-de': {'id': 'CC-BY-NC-3.0-DE', 'deprecated': False}, - 'cc-by-nc-4.0': {'id': 'CC-BY-NC-4.0', 'deprecated': False}, - 'cc-by-nc-nd-1.0': {'id': 'CC-BY-NC-ND-1.0', 'deprecated': False}, - 'cc-by-nc-nd-2.0': {'id': 'CC-BY-NC-ND-2.0', 'deprecated': False}, - 'cc-by-nc-nd-2.5': {'id': 'CC-BY-NC-ND-2.5', 'deprecated': False}, - 'cc-by-nc-nd-3.0': {'id': 'CC-BY-NC-ND-3.0', 'deprecated': False}, - 'cc-by-nc-nd-3.0-de': {'id': 'CC-BY-NC-ND-3.0-DE', 'deprecated': False}, - 'cc-by-nc-nd-3.0-igo': {'id': 'CC-BY-NC-ND-3.0-IGO', 'deprecated': False}, - 'cc-by-nc-nd-4.0': {'id': 'CC-BY-NC-ND-4.0', 'deprecated': False}, - 'cc-by-nc-sa-1.0': {'id': 'CC-BY-NC-SA-1.0', 'deprecated': False}, - 'cc-by-nc-sa-2.0': {'id': 'CC-BY-NC-SA-2.0', 'deprecated': False}, - 'cc-by-nc-sa-2.0-de': {'id': 'CC-BY-NC-SA-2.0-DE', 'deprecated': False}, - 'cc-by-nc-sa-2.0-fr': {'id': 'CC-BY-NC-SA-2.0-FR', 'deprecated': False}, - 'cc-by-nc-sa-2.0-uk': {'id': 'CC-BY-NC-SA-2.0-UK', 'deprecated': False}, - 'cc-by-nc-sa-2.5': {'id': 'CC-BY-NC-SA-2.5', 'deprecated': False}, - 'cc-by-nc-sa-3.0': {'id': 'CC-BY-NC-SA-3.0', 'deprecated': False}, - 'cc-by-nc-sa-3.0-de': {'id': 'CC-BY-NC-SA-3.0-DE', 'deprecated': False}, - 'cc-by-nc-sa-3.0-igo': {'id': 'CC-BY-NC-SA-3.0-IGO', 'deprecated': False}, - 'cc-by-nc-sa-4.0': {'id': 'CC-BY-NC-SA-4.0', 'deprecated': False}, - 'cc-by-nd-1.0': {'id': 'CC-BY-ND-1.0', 'deprecated': False}, - 'cc-by-nd-2.0': {'id': 'CC-BY-ND-2.0', 'deprecated': False}, - 'cc-by-nd-2.5': {'id': 'CC-BY-ND-2.5', 'deprecated': False}, - 'cc-by-nd-3.0': {'id': 'CC-BY-ND-3.0', 'deprecated': False}, - 'cc-by-nd-3.0-de': {'id': 'CC-BY-ND-3.0-DE', 'deprecated': False}, - 'cc-by-nd-4.0': {'id': 'CC-BY-ND-4.0', 'deprecated': False}, - 'cc-by-sa-1.0': {'id': 'CC-BY-SA-1.0', 'deprecated': False}, - 'cc-by-sa-2.0': {'id': 'CC-BY-SA-2.0', 'deprecated': False}, - 'cc-by-sa-2.0-uk': {'id': 'CC-BY-SA-2.0-UK', 'deprecated': False}, - 'cc-by-sa-2.1-jp': {'id': 'CC-BY-SA-2.1-JP', 'deprecated': False}, - 'cc-by-sa-2.5': {'id': 'CC-BY-SA-2.5', 'deprecated': False}, - 'cc-by-sa-3.0': {'id': 'CC-BY-SA-3.0', 'deprecated': False}, - 'cc-by-sa-3.0-at': {'id': 'CC-BY-SA-3.0-AT', 'deprecated': False}, - 'cc-by-sa-3.0-de': {'id': 'CC-BY-SA-3.0-DE', 'deprecated': False}, - 'cc-by-sa-3.0-igo': {'id': 'CC-BY-SA-3.0-IGO', 'deprecated': False}, - 'cc-by-sa-4.0': {'id': 'CC-BY-SA-4.0', 'deprecated': False}, - 'cc-pddc': {'id': 'CC-PDDC', 'deprecated': False}, - 'cc-pdm-1.0': {'id': 'CC-PDM-1.0', 'deprecated': False}, - 'cc-sa-1.0': {'id': 'CC-SA-1.0', 'deprecated': False}, - 'cc0-1.0': {'id': 'CC0-1.0', 'deprecated': False}, - 'cddl-1.0': {'id': 'CDDL-1.0', 'deprecated': False}, - 'cddl-1.1': {'id': 'CDDL-1.1', 'deprecated': False}, - 'cdl-1.0': {'id': 'CDL-1.0', 'deprecated': False}, - 'cdla-permissive-1.0': {'id': 'CDLA-Permissive-1.0', 'deprecated': False}, - 'cdla-permissive-2.0': {'id': 'CDLA-Permissive-2.0', 'deprecated': False}, - 'cdla-sharing-1.0': {'id': 'CDLA-Sharing-1.0', 'deprecated': False}, - 'cecill-1.0': {'id': 'CECILL-1.0', 'deprecated': False}, - 'cecill-1.1': {'id': 'CECILL-1.1', 'deprecated': False}, - 'cecill-2.0': {'id': 'CECILL-2.0', 'deprecated': False}, - 'cecill-2.1': {'id': 'CECILL-2.1', 'deprecated': False}, - 'cecill-b': {'id': 'CECILL-B', 'deprecated': False}, - 'cecill-c': {'id': 'CECILL-C', 'deprecated': False}, - 'cern-ohl-1.1': {'id': 'CERN-OHL-1.1', 'deprecated': False}, - 'cern-ohl-1.2': {'id': 'CERN-OHL-1.2', 'deprecated': False}, - 'cern-ohl-p-2.0': {'id': 'CERN-OHL-P-2.0', 'deprecated': False}, - 'cern-ohl-s-2.0': {'id': 'CERN-OHL-S-2.0', 'deprecated': False}, - 'cern-ohl-w-2.0': {'id': 'CERN-OHL-W-2.0', 'deprecated': False}, - 'cfitsio': {'id': 'CFITSIO', 'deprecated': False}, - 'check-cvs': {'id': 'check-cvs', 'deprecated': False}, - 'checkmk': {'id': 'checkmk', 'deprecated': False}, - 'clartistic': {'id': 'ClArtistic', 'deprecated': False}, - 'clips': {'id': 'Clips', 'deprecated': False}, - 'cmu-mach': {'id': 'CMU-Mach', 'deprecated': False}, - 'cmu-mach-nodoc': {'id': 'CMU-Mach-nodoc', 'deprecated': False}, - 'cnri-jython': {'id': 'CNRI-Jython', 'deprecated': False}, - 'cnri-python': {'id': 'CNRI-Python', 'deprecated': False}, - 'cnri-python-gpl-compatible': {'id': 'CNRI-Python-GPL-Compatible', 'deprecated': False}, - 'coil-1.0': {'id': 'COIL-1.0', 'deprecated': False}, - 'community-spec-1.0': {'id': 'Community-Spec-1.0', 'deprecated': False}, - 'condor-1.1': {'id': 'Condor-1.1', 'deprecated': False}, - 'copyleft-next-0.3.0': {'id': 'copyleft-next-0.3.0', 'deprecated': False}, - 'copyleft-next-0.3.1': {'id': 'copyleft-next-0.3.1', 'deprecated': False}, - 'cornell-lossless-jpeg': {'id': 'Cornell-Lossless-JPEG', 'deprecated': False}, - 'cpal-1.0': {'id': 'CPAL-1.0', 'deprecated': False}, - 'cpl-1.0': {'id': 'CPL-1.0', 'deprecated': False}, - 'cpol-1.02': {'id': 'CPOL-1.02', 'deprecated': False}, - 'cronyx': {'id': 'Cronyx', 'deprecated': False}, - 'crossword': {'id': 'Crossword', 'deprecated': False}, - 'cryptoswift': {'id': 'CryptoSwift', 'deprecated': False}, - 'crystalstacker': {'id': 'CrystalStacker', 'deprecated': False}, - 'cua-opl-1.0': {'id': 'CUA-OPL-1.0', 'deprecated': False}, - 'cube': {'id': 'Cube', 'deprecated': False}, - 'curl': {'id': 'curl', 'deprecated': False}, - 'cve-tou': {'id': 'cve-tou', 'deprecated': False}, - 'd-fsl-1.0': {'id': 'D-FSL-1.0', 'deprecated': False}, - 'dec-3-clause': {'id': 'DEC-3-Clause', 'deprecated': False}, - 'diffmark': {'id': 'diffmark', 'deprecated': False}, - 'dl-de-by-2.0': {'id': 'DL-DE-BY-2.0', 'deprecated': False}, - 'dl-de-zero-2.0': {'id': 'DL-DE-ZERO-2.0', 'deprecated': False}, - 'doc': {'id': 'DOC', 'deprecated': False}, - 'docbook-dtd': {'id': 'DocBook-DTD', 'deprecated': False}, - 'docbook-schema': {'id': 'DocBook-Schema', 'deprecated': False}, - 'docbook-stylesheet': {'id': 'DocBook-Stylesheet', 'deprecated': False}, - 'docbook-xml': {'id': 'DocBook-XML', 'deprecated': False}, - 'dotseqn': {'id': 'Dotseqn', 'deprecated': False}, - 'drl-1.0': {'id': 'DRL-1.0', 'deprecated': False}, - 'drl-1.1': {'id': 'DRL-1.1', 'deprecated': False}, - 'dsdp': {'id': 'DSDP', 'deprecated': False}, - 'dtoa': {'id': 'dtoa', 'deprecated': False}, - 'dvipdfm': {'id': 'dvipdfm', 'deprecated': False}, - 'ecl-1.0': {'id': 'ECL-1.0', 'deprecated': False}, - 'ecl-2.0': {'id': 'ECL-2.0', 'deprecated': False}, - 'ecos-2.0': {'id': 'eCos-2.0', 'deprecated': True}, - 'efl-1.0': {'id': 'EFL-1.0', 'deprecated': False}, - 'efl-2.0': {'id': 'EFL-2.0', 'deprecated': False}, - 'egenix': {'id': 'eGenix', 'deprecated': False}, - 'elastic-2.0': {'id': 'Elastic-2.0', 'deprecated': False}, - 'entessa': {'id': 'Entessa', 'deprecated': False}, - 'epics': {'id': 'EPICS', 'deprecated': False}, - 'epl-1.0': {'id': 'EPL-1.0', 'deprecated': False}, - 'epl-2.0': {'id': 'EPL-2.0', 'deprecated': False}, - 'erlpl-1.1': {'id': 'ErlPL-1.1', 'deprecated': False}, - 'etalab-2.0': {'id': 'etalab-2.0', 'deprecated': False}, - 'eudatagrid': {'id': 'EUDatagrid', 'deprecated': False}, - 'eupl-1.0': {'id': 'EUPL-1.0', 'deprecated': False}, - 'eupl-1.1': {'id': 'EUPL-1.1', 'deprecated': False}, - 'eupl-1.2': {'id': 'EUPL-1.2', 'deprecated': False}, - 'eurosym': {'id': 'Eurosym', 'deprecated': False}, - 'fair': {'id': 'Fair', 'deprecated': False}, - 'fbm': {'id': 'FBM', 'deprecated': False}, - 'fdk-aac': {'id': 'FDK-AAC', 'deprecated': False}, - 'ferguson-twofish': {'id': 'Ferguson-Twofish', 'deprecated': False}, - 'frameworx-1.0': {'id': 'Frameworx-1.0', 'deprecated': False}, - 'freebsd-doc': {'id': 'FreeBSD-DOC', 'deprecated': False}, - 'freeimage': {'id': 'FreeImage', 'deprecated': False}, - 'fsfap': {'id': 'FSFAP', 'deprecated': False}, - 'fsfap-no-warranty-disclaimer': {'id': 'FSFAP-no-warranty-disclaimer', 'deprecated': False}, - 'fsful': {'id': 'FSFUL', 'deprecated': False}, - 'fsfullr': {'id': 'FSFULLR', 'deprecated': False}, - 'fsfullrsd': {'id': 'FSFULLRSD', 'deprecated': False}, - 'fsfullrwd': {'id': 'FSFULLRWD', 'deprecated': False}, - 'fsl-1.1-alv2': {'id': 'FSL-1.1-ALv2', 'deprecated': False}, - 'fsl-1.1-mit': {'id': 'FSL-1.1-MIT', 'deprecated': False}, - 'ftl': {'id': 'FTL', 'deprecated': False}, - 'furuseth': {'id': 'Furuseth', 'deprecated': False}, - 'fwlw': {'id': 'fwlw', 'deprecated': False}, - 'game-programming-gems': {'id': 'Game-Programming-Gems', 'deprecated': False}, - 'gcr-docs': {'id': 'GCR-docs', 'deprecated': False}, - 'gd': {'id': 'GD', 'deprecated': False}, - 'generic-xts': {'id': 'generic-xts', 'deprecated': False}, - 'gfdl-1.1': {'id': 'GFDL-1.1', 'deprecated': True}, - 'gfdl-1.1-invariants-only': {'id': 'GFDL-1.1-invariants-only', 'deprecated': False}, - 'gfdl-1.1-invariants-or-later': {'id': 'GFDL-1.1-invariants-or-later', 'deprecated': False}, - 'gfdl-1.1-no-invariants-only': {'id': 'GFDL-1.1-no-invariants-only', 'deprecated': False}, - 'gfdl-1.1-no-invariants-or-later': {'id': 'GFDL-1.1-no-invariants-or-later', 'deprecated': False}, - 'gfdl-1.1-only': {'id': 'GFDL-1.1-only', 'deprecated': False}, - 'gfdl-1.1-or-later': {'id': 'GFDL-1.1-or-later', 'deprecated': False}, - 'gfdl-1.2': {'id': 'GFDL-1.2', 'deprecated': True}, - 'gfdl-1.2-invariants-only': {'id': 'GFDL-1.2-invariants-only', 'deprecated': False}, - 'gfdl-1.2-invariants-or-later': {'id': 'GFDL-1.2-invariants-or-later', 'deprecated': False}, - 'gfdl-1.2-no-invariants-only': {'id': 'GFDL-1.2-no-invariants-only', 'deprecated': False}, - 'gfdl-1.2-no-invariants-or-later': {'id': 'GFDL-1.2-no-invariants-or-later', 'deprecated': False}, - 'gfdl-1.2-only': {'id': 'GFDL-1.2-only', 'deprecated': False}, - 'gfdl-1.2-or-later': {'id': 'GFDL-1.2-or-later', 'deprecated': False}, - 'gfdl-1.3': {'id': 'GFDL-1.3', 'deprecated': True}, - 'gfdl-1.3-invariants-only': {'id': 'GFDL-1.3-invariants-only', 'deprecated': False}, - 'gfdl-1.3-invariants-or-later': {'id': 'GFDL-1.3-invariants-or-later', 'deprecated': False}, - 'gfdl-1.3-no-invariants-only': {'id': 'GFDL-1.3-no-invariants-only', 'deprecated': False}, - 'gfdl-1.3-no-invariants-or-later': {'id': 'GFDL-1.3-no-invariants-or-later', 'deprecated': False}, - 'gfdl-1.3-only': {'id': 'GFDL-1.3-only', 'deprecated': False}, - 'gfdl-1.3-or-later': {'id': 'GFDL-1.3-or-later', 'deprecated': False}, - 'giftware': {'id': 'Giftware', 'deprecated': False}, - 'gl2ps': {'id': 'GL2PS', 'deprecated': False}, - 'glide': {'id': 'Glide', 'deprecated': False}, - 'glulxe': {'id': 'Glulxe', 'deprecated': False}, - 'glwtpl': {'id': 'GLWTPL', 'deprecated': False}, - 'gnuplot': {'id': 'gnuplot', 'deprecated': False}, - 'gpl-1.0': {'id': 'GPL-1.0', 'deprecated': True}, - 'gpl-1.0+': {'id': 'GPL-1.0+', 'deprecated': True}, - 'gpl-1.0-only': {'id': 'GPL-1.0-only', 'deprecated': False}, - 'gpl-1.0-or-later': {'id': 'GPL-1.0-or-later', 'deprecated': False}, - 'gpl-2.0': {'id': 'GPL-2.0', 'deprecated': True}, - 'gpl-2.0+': {'id': 'GPL-2.0+', 'deprecated': True}, - 'gpl-2.0-only': {'id': 'GPL-2.0-only', 'deprecated': False}, - 'gpl-2.0-or-later': {'id': 'GPL-2.0-or-later', 'deprecated': False}, - 'gpl-2.0-with-autoconf-exception': {'id': 'GPL-2.0-with-autoconf-exception', 'deprecated': True}, - 'gpl-2.0-with-bison-exception': {'id': 'GPL-2.0-with-bison-exception', 'deprecated': True}, - 'gpl-2.0-with-classpath-exception': {'id': 'GPL-2.0-with-classpath-exception', 'deprecated': True}, - 'gpl-2.0-with-font-exception': {'id': 'GPL-2.0-with-font-exception', 'deprecated': True}, - 'gpl-2.0-with-gcc-exception': {'id': 'GPL-2.0-with-GCC-exception', 'deprecated': True}, - 'gpl-3.0': {'id': 'GPL-3.0', 'deprecated': True}, - 'gpl-3.0+': {'id': 'GPL-3.0+', 'deprecated': True}, - 'gpl-3.0-only': {'id': 'GPL-3.0-only', 'deprecated': False}, - 'gpl-3.0-or-later': {'id': 'GPL-3.0-or-later', 'deprecated': False}, - 'gpl-3.0-with-autoconf-exception': {'id': 'GPL-3.0-with-autoconf-exception', 'deprecated': True}, - 'gpl-3.0-with-gcc-exception': {'id': 'GPL-3.0-with-GCC-exception', 'deprecated': True}, - 'graphics-gems': {'id': 'Graphics-Gems', 'deprecated': False}, - 'gsoap-1.3b': {'id': 'gSOAP-1.3b', 'deprecated': False}, - 'gtkbook': {'id': 'gtkbook', 'deprecated': False}, - 'gutmann': {'id': 'Gutmann', 'deprecated': False}, - 'haskellreport': {'id': 'HaskellReport', 'deprecated': False}, - 'hdf5': {'id': 'HDF5', 'deprecated': False}, - 'hdparm': {'id': 'hdparm', 'deprecated': False}, - 'hidapi': {'id': 'HIDAPI', 'deprecated': False}, - 'hippocratic-2.1': {'id': 'Hippocratic-2.1', 'deprecated': False}, - 'hp-1986': {'id': 'HP-1986', 'deprecated': False}, - 'hp-1989': {'id': 'HP-1989', 'deprecated': False}, - 'hpnd': {'id': 'HPND', 'deprecated': False}, - 'hpnd-dec': {'id': 'HPND-DEC', 'deprecated': False}, - 'hpnd-doc': {'id': 'HPND-doc', 'deprecated': False}, - 'hpnd-doc-sell': {'id': 'HPND-doc-sell', 'deprecated': False}, - 'hpnd-export-us': {'id': 'HPND-export-US', 'deprecated': False}, - 'hpnd-export-us-acknowledgement': {'id': 'HPND-export-US-acknowledgement', 'deprecated': False}, - 'hpnd-export-us-modify': {'id': 'HPND-export-US-modify', 'deprecated': False}, - 'hpnd-export2-us': {'id': 'HPND-export2-US', 'deprecated': False}, - 'hpnd-fenneberg-livingston': {'id': 'HPND-Fenneberg-Livingston', 'deprecated': False}, - 'hpnd-inria-imag': {'id': 'HPND-INRIA-IMAG', 'deprecated': False}, - 'hpnd-intel': {'id': 'HPND-Intel', 'deprecated': False}, - 'hpnd-kevlin-henney': {'id': 'HPND-Kevlin-Henney', 'deprecated': False}, - 'hpnd-markus-kuhn': {'id': 'HPND-Markus-Kuhn', 'deprecated': False}, - 'hpnd-merchantability-variant': {'id': 'HPND-merchantability-variant', 'deprecated': False}, - 'hpnd-mit-disclaimer': {'id': 'HPND-MIT-disclaimer', 'deprecated': False}, - 'hpnd-netrek': {'id': 'HPND-Netrek', 'deprecated': False}, - 'hpnd-pbmplus': {'id': 'HPND-Pbmplus', 'deprecated': False}, - 'hpnd-sell-mit-disclaimer-xserver': {'id': 'HPND-sell-MIT-disclaimer-xserver', 'deprecated': False}, - 'hpnd-sell-regexpr': {'id': 'HPND-sell-regexpr', 'deprecated': False}, - 'hpnd-sell-variant': {'id': 'HPND-sell-variant', 'deprecated': False}, - 'hpnd-sell-variant-mit-disclaimer': {'id': 'HPND-sell-variant-MIT-disclaimer', 'deprecated': False}, - 'hpnd-sell-variant-mit-disclaimer-rev': {'id': 'HPND-sell-variant-MIT-disclaimer-rev', 'deprecated': False}, - 'hpnd-uc': {'id': 'HPND-UC', 'deprecated': False}, - 'hpnd-uc-export-us': {'id': 'HPND-UC-export-US', 'deprecated': False}, - 'htmltidy': {'id': 'HTMLTIDY', 'deprecated': False}, - 'ibm-pibs': {'id': 'IBM-pibs', 'deprecated': False}, - 'icu': {'id': 'ICU', 'deprecated': False}, - 'iec-code-components-eula': {'id': 'IEC-Code-Components-EULA', 'deprecated': False}, - 'ijg': {'id': 'IJG', 'deprecated': False}, - 'ijg-short': {'id': 'IJG-short', 'deprecated': False}, - 'imagemagick': {'id': 'ImageMagick', 'deprecated': False}, - 'imatix': {'id': 'iMatix', 'deprecated': False}, - 'imlib2': {'id': 'Imlib2', 'deprecated': False}, - 'info-zip': {'id': 'Info-ZIP', 'deprecated': False}, - 'inner-net-2.0': {'id': 'Inner-Net-2.0', 'deprecated': False}, - 'innosetup': {'id': 'InnoSetup', 'deprecated': False}, - 'intel': {'id': 'Intel', 'deprecated': False}, - 'intel-acpi': {'id': 'Intel-ACPI', 'deprecated': False}, - 'interbase-1.0': {'id': 'Interbase-1.0', 'deprecated': False}, - 'ipa': {'id': 'IPA', 'deprecated': False}, - 'ipl-1.0': {'id': 'IPL-1.0', 'deprecated': False}, - 'isc': {'id': 'ISC', 'deprecated': False}, - 'isc-veillard': {'id': 'ISC-Veillard', 'deprecated': False}, - 'jam': {'id': 'Jam', 'deprecated': False}, - 'jasper-2.0': {'id': 'JasPer-2.0', 'deprecated': False}, - 'jove': {'id': 'jove', 'deprecated': False}, - 'jpl-image': {'id': 'JPL-image', 'deprecated': False}, - 'jpnic': {'id': 'JPNIC', 'deprecated': False}, - 'json': {'id': 'JSON', 'deprecated': False}, - 'kastrup': {'id': 'Kastrup', 'deprecated': False}, - 'kazlib': {'id': 'Kazlib', 'deprecated': False}, - 'knuth-ctan': {'id': 'Knuth-CTAN', 'deprecated': False}, - 'lal-1.2': {'id': 'LAL-1.2', 'deprecated': False}, - 'lal-1.3': {'id': 'LAL-1.3', 'deprecated': False}, - 'latex2e': {'id': 'Latex2e', 'deprecated': False}, - 'latex2e-translated-notice': {'id': 'Latex2e-translated-notice', 'deprecated': False}, - 'leptonica': {'id': 'Leptonica', 'deprecated': False}, - 'lgpl-2.0': {'id': 'LGPL-2.0', 'deprecated': True}, - 'lgpl-2.0+': {'id': 'LGPL-2.0+', 'deprecated': True}, - 'lgpl-2.0-only': {'id': 'LGPL-2.0-only', 'deprecated': False}, - 'lgpl-2.0-or-later': {'id': 'LGPL-2.0-or-later', 'deprecated': False}, - 'lgpl-2.1': {'id': 'LGPL-2.1', 'deprecated': True}, - 'lgpl-2.1+': {'id': 'LGPL-2.1+', 'deprecated': True}, - 'lgpl-2.1-only': {'id': 'LGPL-2.1-only', 'deprecated': False}, - 'lgpl-2.1-or-later': {'id': 'LGPL-2.1-or-later', 'deprecated': False}, - 'lgpl-3.0': {'id': 'LGPL-3.0', 'deprecated': True}, - 'lgpl-3.0+': {'id': 'LGPL-3.0+', 'deprecated': True}, - 'lgpl-3.0-only': {'id': 'LGPL-3.0-only', 'deprecated': False}, - 'lgpl-3.0-or-later': {'id': 'LGPL-3.0-or-later', 'deprecated': False}, - 'lgpllr': {'id': 'LGPLLR', 'deprecated': False}, - 'libpng': {'id': 'Libpng', 'deprecated': False}, - 'libpng-1.6.35': {'id': 'libpng-1.6.35', 'deprecated': False}, - 'libpng-2.0': {'id': 'libpng-2.0', 'deprecated': False}, - 'libselinux-1.0': {'id': 'libselinux-1.0', 'deprecated': False}, - 'libtiff': {'id': 'libtiff', 'deprecated': False}, - 'libutil-david-nugent': {'id': 'libutil-David-Nugent', 'deprecated': False}, - 'liliq-p-1.1': {'id': 'LiLiQ-P-1.1', 'deprecated': False}, - 'liliq-r-1.1': {'id': 'LiLiQ-R-1.1', 'deprecated': False}, - 'liliq-rplus-1.1': {'id': 'LiLiQ-Rplus-1.1', 'deprecated': False}, - 'linux-man-pages-1-para': {'id': 'Linux-man-pages-1-para', 'deprecated': False}, - 'linux-man-pages-copyleft': {'id': 'Linux-man-pages-copyleft', 'deprecated': False}, - 'linux-man-pages-copyleft-2-para': {'id': 'Linux-man-pages-copyleft-2-para', 'deprecated': False}, - 'linux-man-pages-copyleft-var': {'id': 'Linux-man-pages-copyleft-var', 'deprecated': False}, - 'linux-openib': {'id': 'Linux-OpenIB', 'deprecated': False}, - 'loop': {'id': 'LOOP', 'deprecated': False}, - 'lpd-document': {'id': 'LPD-document', 'deprecated': False}, - 'lpl-1.0': {'id': 'LPL-1.0', 'deprecated': False}, - 'lpl-1.02': {'id': 'LPL-1.02', 'deprecated': False}, - 'lppl-1.0': {'id': 'LPPL-1.0', 'deprecated': False}, - 'lppl-1.1': {'id': 'LPPL-1.1', 'deprecated': False}, - 'lppl-1.2': {'id': 'LPPL-1.2', 'deprecated': False}, - 'lppl-1.3a': {'id': 'LPPL-1.3a', 'deprecated': False}, - 'lppl-1.3c': {'id': 'LPPL-1.3c', 'deprecated': False}, - 'lsof': {'id': 'lsof', 'deprecated': False}, - 'lucida-bitmap-fonts': {'id': 'Lucida-Bitmap-Fonts', 'deprecated': False}, - 'lzma-sdk-9.11-to-9.20': {'id': 'LZMA-SDK-9.11-to-9.20', 'deprecated': False}, - 'lzma-sdk-9.22': {'id': 'LZMA-SDK-9.22', 'deprecated': False}, - 'mackerras-3-clause': {'id': 'Mackerras-3-Clause', 'deprecated': False}, - 'mackerras-3-clause-acknowledgment': {'id': 'Mackerras-3-Clause-acknowledgment', 'deprecated': False}, - 'magaz': {'id': 'magaz', 'deprecated': False}, - 'mailprio': {'id': 'mailprio', 'deprecated': False}, - 'makeindex': {'id': 'MakeIndex', 'deprecated': False}, - 'man2html': {'id': 'man2html', 'deprecated': False}, - 'martin-birgmeier': {'id': 'Martin-Birgmeier', 'deprecated': False}, - 'mcphee-slideshow': {'id': 'McPhee-slideshow', 'deprecated': False}, - 'metamail': {'id': 'metamail', 'deprecated': False}, - 'minpack': {'id': 'Minpack', 'deprecated': False}, - 'mips': {'id': 'MIPS', 'deprecated': False}, - 'miros': {'id': 'MirOS', 'deprecated': False}, - 'mit': {'id': 'MIT', 'deprecated': False}, - 'mit-0': {'id': 'MIT-0', 'deprecated': False}, - 'mit-advertising': {'id': 'MIT-advertising', 'deprecated': False}, - 'mit-click': {'id': 'MIT-Click', 'deprecated': False}, - 'mit-cmu': {'id': 'MIT-CMU', 'deprecated': False}, - 'mit-enna': {'id': 'MIT-enna', 'deprecated': False}, - 'mit-feh': {'id': 'MIT-feh', 'deprecated': False}, - 'mit-festival': {'id': 'MIT-Festival', 'deprecated': False}, - 'mit-khronos-old': {'id': 'MIT-Khronos-old', 'deprecated': False}, - 'mit-modern-variant': {'id': 'MIT-Modern-Variant', 'deprecated': False}, - 'mit-open-group': {'id': 'MIT-open-group', 'deprecated': False}, - 'mit-testregex': {'id': 'MIT-testregex', 'deprecated': False}, - 'mit-wu': {'id': 'MIT-Wu', 'deprecated': False}, - 'mitnfa': {'id': 'MITNFA', 'deprecated': False}, - 'mmixware': {'id': 'MMIXware', 'deprecated': False}, - 'motosoto': {'id': 'Motosoto', 'deprecated': False}, - 'mpeg-ssg': {'id': 'MPEG-SSG', 'deprecated': False}, - 'mpi-permissive': {'id': 'mpi-permissive', 'deprecated': False}, - 'mpich2': {'id': 'mpich2', 'deprecated': False}, - 'mpl-1.0': {'id': 'MPL-1.0', 'deprecated': False}, - 'mpl-1.1': {'id': 'MPL-1.1', 'deprecated': False}, - 'mpl-2.0': {'id': 'MPL-2.0', 'deprecated': False}, - 'mpl-2.0-no-copyleft-exception': {'id': 'MPL-2.0-no-copyleft-exception', 'deprecated': False}, - 'mplus': {'id': 'mplus', 'deprecated': False}, - 'ms-lpl': {'id': 'MS-LPL', 'deprecated': False}, - 'ms-pl': {'id': 'MS-PL', 'deprecated': False}, - 'ms-rl': {'id': 'MS-RL', 'deprecated': False}, - 'mtll': {'id': 'MTLL', 'deprecated': False}, - 'mulanpsl-1.0': {'id': 'MulanPSL-1.0', 'deprecated': False}, - 'mulanpsl-2.0': {'id': 'MulanPSL-2.0', 'deprecated': False}, - 'multics': {'id': 'Multics', 'deprecated': False}, - 'mup': {'id': 'Mup', 'deprecated': False}, - 'naist-2003': {'id': 'NAIST-2003', 'deprecated': False}, - 'nasa-1.3': {'id': 'NASA-1.3', 'deprecated': False}, - 'naumen': {'id': 'Naumen', 'deprecated': False}, - 'nbpl-1.0': {'id': 'NBPL-1.0', 'deprecated': False}, - 'ncbi-pd': {'id': 'NCBI-PD', 'deprecated': False}, - 'ncgl-uk-2.0': {'id': 'NCGL-UK-2.0', 'deprecated': False}, - 'ncl': {'id': 'NCL', 'deprecated': False}, - 'ncsa': {'id': 'NCSA', 'deprecated': False}, - 'net-snmp': {'id': 'Net-SNMP', 'deprecated': True}, - 'netcdf': {'id': 'NetCDF', 'deprecated': False}, - 'newsletr': {'id': 'Newsletr', 'deprecated': False}, - 'ngpl': {'id': 'NGPL', 'deprecated': False}, - 'ngrep': {'id': 'ngrep', 'deprecated': False}, - 'nicta-1.0': {'id': 'NICTA-1.0', 'deprecated': False}, - 'nist-pd': {'id': 'NIST-PD', 'deprecated': False}, - 'nist-pd-fallback': {'id': 'NIST-PD-fallback', 'deprecated': False}, - 'nist-software': {'id': 'NIST-Software', 'deprecated': False}, - 'nlod-1.0': {'id': 'NLOD-1.0', 'deprecated': False}, - 'nlod-2.0': {'id': 'NLOD-2.0', 'deprecated': False}, - 'nlpl': {'id': 'NLPL', 'deprecated': False}, - 'nokia': {'id': 'Nokia', 'deprecated': False}, - 'nosl': {'id': 'NOSL', 'deprecated': False}, - 'noweb': {'id': 'Noweb', 'deprecated': False}, - 'npl-1.0': {'id': 'NPL-1.0', 'deprecated': False}, - 'npl-1.1': {'id': 'NPL-1.1', 'deprecated': False}, - 'nposl-3.0': {'id': 'NPOSL-3.0', 'deprecated': False}, - 'nrl': {'id': 'NRL', 'deprecated': False}, - 'ntia-pd': {'id': 'NTIA-PD', 'deprecated': False}, - 'ntp': {'id': 'NTP', 'deprecated': False}, - 'ntp-0': {'id': 'NTP-0', 'deprecated': False}, - 'nunit': {'id': 'Nunit', 'deprecated': True}, - 'o-uda-1.0': {'id': 'O-UDA-1.0', 'deprecated': False}, - 'oar': {'id': 'OAR', 'deprecated': False}, - 'occt-pl': {'id': 'OCCT-PL', 'deprecated': False}, - 'oclc-2.0': {'id': 'OCLC-2.0', 'deprecated': False}, - 'odbl-1.0': {'id': 'ODbL-1.0', 'deprecated': False}, - 'odc-by-1.0': {'id': 'ODC-By-1.0', 'deprecated': False}, - 'offis': {'id': 'OFFIS', 'deprecated': False}, - 'ofl-1.0': {'id': 'OFL-1.0', 'deprecated': False}, - 'ofl-1.0-no-rfn': {'id': 'OFL-1.0-no-RFN', 'deprecated': False}, - 'ofl-1.0-rfn': {'id': 'OFL-1.0-RFN', 'deprecated': False}, - 'ofl-1.1': {'id': 'OFL-1.1', 'deprecated': False}, - 'ofl-1.1-no-rfn': {'id': 'OFL-1.1-no-RFN', 'deprecated': False}, - 'ofl-1.1-rfn': {'id': 'OFL-1.1-RFN', 'deprecated': False}, - 'ogc-1.0': {'id': 'OGC-1.0', 'deprecated': False}, - 'ogdl-taiwan-1.0': {'id': 'OGDL-Taiwan-1.0', 'deprecated': False}, - 'ogl-canada-2.0': {'id': 'OGL-Canada-2.0', 'deprecated': False}, - 'ogl-uk-1.0': {'id': 'OGL-UK-1.0', 'deprecated': False}, - 'ogl-uk-2.0': {'id': 'OGL-UK-2.0', 'deprecated': False}, - 'ogl-uk-3.0': {'id': 'OGL-UK-3.0', 'deprecated': False}, - 'ogtsl': {'id': 'OGTSL', 'deprecated': False}, - 'oldap-1.1': {'id': 'OLDAP-1.1', 'deprecated': False}, - 'oldap-1.2': {'id': 'OLDAP-1.2', 'deprecated': False}, - 'oldap-1.3': {'id': 'OLDAP-1.3', 'deprecated': False}, - 'oldap-1.4': {'id': 'OLDAP-1.4', 'deprecated': False}, - 'oldap-2.0': {'id': 'OLDAP-2.0', 'deprecated': False}, - 'oldap-2.0.1': {'id': 'OLDAP-2.0.1', 'deprecated': False}, - 'oldap-2.1': {'id': 'OLDAP-2.1', 'deprecated': False}, - 'oldap-2.2': {'id': 'OLDAP-2.2', 'deprecated': False}, - 'oldap-2.2.1': {'id': 'OLDAP-2.2.1', 'deprecated': False}, - 'oldap-2.2.2': {'id': 'OLDAP-2.2.2', 'deprecated': False}, - 'oldap-2.3': {'id': 'OLDAP-2.3', 'deprecated': False}, - 'oldap-2.4': {'id': 'OLDAP-2.4', 'deprecated': False}, - 'oldap-2.5': {'id': 'OLDAP-2.5', 'deprecated': False}, - 'oldap-2.6': {'id': 'OLDAP-2.6', 'deprecated': False}, - 'oldap-2.7': {'id': 'OLDAP-2.7', 'deprecated': False}, - 'oldap-2.8': {'id': 'OLDAP-2.8', 'deprecated': False}, - 'olfl-1.3': {'id': 'OLFL-1.3', 'deprecated': False}, - 'oml': {'id': 'OML', 'deprecated': False}, - 'openpbs-2.3': {'id': 'OpenPBS-2.3', 'deprecated': False}, - 'openssl': {'id': 'OpenSSL', 'deprecated': False}, - 'openssl-standalone': {'id': 'OpenSSL-standalone', 'deprecated': False}, - 'openvision': {'id': 'OpenVision', 'deprecated': False}, - 'opl-1.0': {'id': 'OPL-1.0', 'deprecated': False}, - 'opl-uk-3.0': {'id': 'OPL-UK-3.0', 'deprecated': False}, - 'opubl-1.0': {'id': 'OPUBL-1.0', 'deprecated': False}, - 'oset-pl-2.1': {'id': 'OSET-PL-2.1', 'deprecated': False}, - 'osl-1.0': {'id': 'OSL-1.0', 'deprecated': False}, - 'osl-1.1': {'id': 'OSL-1.1', 'deprecated': False}, - 'osl-2.0': {'id': 'OSL-2.0', 'deprecated': False}, - 'osl-2.1': {'id': 'OSL-2.1', 'deprecated': False}, - 'osl-3.0': {'id': 'OSL-3.0', 'deprecated': False}, - 'padl': {'id': 'PADL', 'deprecated': False}, - 'parity-6.0.0': {'id': 'Parity-6.0.0', 'deprecated': False}, - 'parity-7.0.0': {'id': 'Parity-7.0.0', 'deprecated': False}, - 'pddl-1.0': {'id': 'PDDL-1.0', 'deprecated': False}, - 'php-3.0': {'id': 'PHP-3.0', 'deprecated': False}, - 'php-3.01': {'id': 'PHP-3.01', 'deprecated': False}, - 'pixar': {'id': 'Pixar', 'deprecated': False}, - 'pkgconf': {'id': 'pkgconf', 'deprecated': False}, - 'plexus': {'id': 'Plexus', 'deprecated': False}, - 'pnmstitch': {'id': 'pnmstitch', 'deprecated': False}, - 'polyform-noncommercial-1.0.0': {'id': 'PolyForm-Noncommercial-1.0.0', 'deprecated': False}, - 'polyform-small-business-1.0.0': {'id': 'PolyForm-Small-Business-1.0.0', 'deprecated': False}, - 'postgresql': {'id': 'PostgreSQL', 'deprecated': False}, - 'ppl': {'id': 'PPL', 'deprecated': False}, - 'psf-2.0': {'id': 'PSF-2.0', 'deprecated': False}, - 'psfrag': {'id': 'psfrag', 'deprecated': False}, - 'psutils': {'id': 'psutils', 'deprecated': False}, - 'python-2.0': {'id': 'Python-2.0', 'deprecated': False}, - 'python-2.0.1': {'id': 'Python-2.0.1', 'deprecated': False}, - 'python-ldap': {'id': 'python-ldap', 'deprecated': False}, - 'qhull': {'id': 'Qhull', 'deprecated': False}, - 'qpl-1.0': {'id': 'QPL-1.0', 'deprecated': False}, - 'qpl-1.0-inria-2004': {'id': 'QPL-1.0-INRIA-2004', 'deprecated': False}, - 'radvd': {'id': 'radvd', 'deprecated': False}, - 'rdisc': {'id': 'Rdisc', 'deprecated': False}, - 'rhecos-1.1': {'id': 'RHeCos-1.1', 'deprecated': False}, - 'rpl-1.1': {'id': 'RPL-1.1', 'deprecated': False}, - 'rpl-1.5': {'id': 'RPL-1.5', 'deprecated': False}, - 'rpsl-1.0': {'id': 'RPSL-1.0', 'deprecated': False}, - 'rsa-md': {'id': 'RSA-MD', 'deprecated': False}, - 'rscpl': {'id': 'RSCPL', 'deprecated': False}, - 'ruby': {'id': 'Ruby', 'deprecated': False}, - 'ruby-pty': {'id': 'Ruby-pty', 'deprecated': False}, - 'sax-pd': {'id': 'SAX-PD', 'deprecated': False}, - 'sax-pd-2.0': {'id': 'SAX-PD-2.0', 'deprecated': False}, - 'saxpath': {'id': 'Saxpath', 'deprecated': False}, - 'scea': {'id': 'SCEA', 'deprecated': False}, - 'schemereport': {'id': 'SchemeReport', 'deprecated': False}, - 'sendmail': {'id': 'Sendmail', 'deprecated': False}, - 'sendmail-8.23': {'id': 'Sendmail-8.23', 'deprecated': False}, - 'sendmail-open-source-1.1': {'id': 'Sendmail-Open-Source-1.1', 'deprecated': False}, - 'sgi-b-1.0': {'id': 'SGI-B-1.0', 'deprecated': False}, - 'sgi-b-1.1': {'id': 'SGI-B-1.1', 'deprecated': False}, - 'sgi-b-2.0': {'id': 'SGI-B-2.0', 'deprecated': False}, - 'sgi-opengl': {'id': 'SGI-OpenGL', 'deprecated': False}, - 'sgp4': {'id': 'SGP4', 'deprecated': False}, - 'shl-0.5': {'id': 'SHL-0.5', 'deprecated': False}, - 'shl-0.51': {'id': 'SHL-0.51', 'deprecated': False}, - 'simpl-2.0': {'id': 'SimPL-2.0', 'deprecated': False}, - 'sissl': {'id': 'SISSL', 'deprecated': False}, - 'sissl-1.2': {'id': 'SISSL-1.2', 'deprecated': False}, - 'sl': {'id': 'SL', 'deprecated': False}, - 'sleepycat': {'id': 'Sleepycat', 'deprecated': False}, - 'smail-gpl': {'id': 'SMAIL-GPL', 'deprecated': False}, - 'smlnj': {'id': 'SMLNJ', 'deprecated': False}, - 'smppl': {'id': 'SMPPL', 'deprecated': False}, - 'snia': {'id': 'SNIA', 'deprecated': False}, - 'snprintf': {'id': 'snprintf', 'deprecated': False}, - 'sofa': {'id': 'SOFA', 'deprecated': False}, - 'softsurfer': {'id': 'softSurfer', 'deprecated': False}, - 'soundex': {'id': 'Soundex', 'deprecated': False}, - 'spencer-86': {'id': 'Spencer-86', 'deprecated': False}, - 'spencer-94': {'id': 'Spencer-94', 'deprecated': False}, - 'spencer-99': {'id': 'Spencer-99', 'deprecated': False}, - 'spl-1.0': {'id': 'SPL-1.0', 'deprecated': False}, - 'ssh-keyscan': {'id': 'ssh-keyscan', 'deprecated': False}, - 'ssh-openssh': {'id': 'SSH-OpenSSH', 'deprecated': False}, - 'ssh-short': {'id': 'SSH-short', 'deprecated': False}, - 'ssleay-standalone': {'id': 'SSLeay-standalone', 'deprecated': False}, - 'sspl-1.0': {'id': 'SSPL-1.0', 'deprecated': False}, - 'standardml-nj': {'id': 'StandardML-NJ', 'deprecated': True}, - 'sugarcrm-1.1.3': {'id': 'SugarCRM-1.1.3', 'deprecated': False}, - 'sul-1.0': {'id': 'SUL-1.0', 'deprecated': False}, - 'sun-ppp': {'id': 'Sun-PPP', 'deprecated': False}, - 'sun-ppp-2000': {'id': 'Sun-PPP-2000', 'deprecated': False}, - 'sunpro': {'id': 'SunPro', 'deprecated': False}, - 'swl': {'id': 'SWL', 'deprecated': False}, - 'swrule': {'id': 'swrule', 'deprecated': False}, - 'symlinks': {'id': 'Symlinks', 'deprecated': False}, - 'tapr-ohl-1.0': {'id': 'TAPR-OHL-1.0', 'deprecated': False}, - 'tcl': {'id': 'TCL', 'deprecated': False}, - 'tcp-wrappers': {'id': 'TCP-wrappers', 'deprecated': False}, - 'termreadkey': {'id': 'TermReadKey', 'deprecated': False}, - 'tgppl-1.0': {'id': 'TGPPL-1.0', 'deprecated': False}, - 'thirdeye': {'id': 'ThirdEye', 'deprecated': False}, - 'threeparttable': {'id': 'threeparttable', 'deprecated': False}, - 'tmate': {'id': 'TMate', 'deprecated': False}, - 'torque-1.1': {'id': 'TORQUE-1.1', 'deprecated': False}, - 'tosl': {'id': 'TOSL', 'deprecated': False}, - 'tpdl': {'id': 'TPDL', 'deprecated': False}, - 'tpl-1.0': {'id': 'TPL-1.0', 'deprecated': False}, - 'trustedqsl': {'id': 'TrustedQSL', 'deprecated': False}, - 'ttwl': {'id': 'TTWL', 'deprecated': False}, - 'ttyp0': {'id': 'TTYP0', 'deprecated': False}, - 'tu-berlin-1.0': {'id': 'TU-Berlin-1.0', 'deprecated': False}, - 'tu-berlin-2.0': {'id': 'TU-Berlin-2.0', 'deprecated': False}, - 'ubuntu-font-1.0': {'id': 'Ubuntu-font-1.0', 'deprecated': False}, - 'ucar': {'id': 'UCAR', 'deprecated': False}, - 'ucl-1.0': {'id': 'UCL-1.0', 'deprecated': False}, - 'ulem': {'id': 'ulem', 'deprecated': False}, - 'umich-merit': {'id': 'UMich-Merit', 'deprecated': False}, - 'unicode-3.0': {'id': 'Unicode-3.0', 'deprecated': False}, - 'unicode-dfs-2015': {'id': 'Unicode-DFS-2015', 'deprecated': False}, - 'unicode-dfs-2016': {'id': 'Unicode-DFS-2016', 'deprecated': False}, - 'unicode-tou': {'id': 'Unicode-TOU', 'deprecated': False}, - 'unixcrypt': {'id': 'UnixCrypt', 'deprecated': False}, - 'unlicense': {'id': 'Unlicense', 'deprecated': False}, - 'unlicense-libtelnet': {'id': 'Unlicense-libtelnet', 'deprecated': False}, - 'unlicense-libwhirlpool': {'id': 'Unlicense-libwhirlpool', 'deprecated': False}, - 'upl-1.0': {'id': 'UPL-1.0', 'deprecated': False}, - 'urt-rle': {'id': 'URT-RLE', 'deprecated': False}, - 'vim': {'id': 'Vim', 'deprecated': False}, - 'vostrom': {'id': 'VOSTROM', 'deprecated': False}, - 'vsl-1.0': {'id': 'VSL-1.0', 'deprecated': False}, - 'w3c': {'id': 'W3C', 'deprecated': False}, - 'w3c-19980720': {'id': 'W3C-19980720', 'deprecated': False}, - 'w3c-20150513': {'id': 'W3C-20150513', 'deprecated': False}, - 'w3m': {'id': 'w3m', 'deprecated': False}, - 'watcom-1.0': {'id': 'Watcom-1.0', 'deprecated': False}, - 'widget-workshop': {'id': 'Widget-Workshop', 'deprecated': False}, - 'wsuipa': {'id': 'Wsuipa', 'deprecated': False}, - 'wtfpl': {'id': 'WTFPL', 'deprecated': False}, - 'wwl': {'id': 'wwl', 'deprecated': False}, - 'wxwindows': {'id': 'wxWindows', 'deprecated': True}, - 'x11': {'id': 'X11', 'deprecated': False}, - 'x11-distribute-modifications-variant': {'id': 'X11-distribute-modifications-variant', 'deprecated': False}, - 'x11-swapped': {'id': 'X11-swapped', 'deprecated': False}, - 'xdebug-1.03': {'id': 'Xdebug-1.03', 'deprecated': False}, - 'xerox': {'id': 'Xerox', 'deprecated': False}, - 'xfig': {'id': 'Xfig', 'deprecated': False}, - 'xfree86-1.1': {'id': 'XFree86-1.1', 'deprecated': False}, - 'xinetd': {'id': 'xinetd', 'deprecated': False}, - 'xkeyboard-config-zinoviev': {'id': 'xkeyboard-config-Zinoviev', 'deprecated': False}, - 'xlock': {'id': 'xlock', 'deprecated': False}, - 'xnet': {'id': 'Xnet', 'deprecated': False}, - 'xpp': {'id': 'xpp', 'deprecated': False}, - 'xskat': {'id': 'XSkat', 'deprecated': False}, - 'xzoom': {'id': 'xzoom', 'deprecated': False}, - 'ypl-1.0': {'id': 'YPL-1.0', 'deprecated': False}, - 'ypl-1.1': {'id': 'YPL-1.1', 'deprecated': False}, - 'zed': {'id': 'Zed', 'deprecated': False}, - 'zeeff': {'id': 'Zeeff', 'deprecated': False}, - 'zend-2.0': {'id': 'Zend-2.0', 'deprecated': False}, - 'zimbra-1.3': {'id': 'Zimbra-1.3', 'deprecated': False}, - 'zimbra-1.4': {'id': 'Zimbra-1.4', 'deprecated': False}, - 'zlib': {'id': 'Zlib', 'deprecated': False}, - 'zlib-acknowledgement': {'id': 'zlib-acknowledgement', 'deprecated': False}, - 'zpl-1.1': {'id': 'ZPL-1.1', 'deprecated': False}, - 'zpl-2.0': {'id': 'ZPL-2.0', 'deprecated': False}, - 'zpl-2.1': {'id': 'ZPL-2.1', 'deprecated': False}, -} - -EXCEPTIONS: dict[str, SPDXException] = { - '389-exception': {'id': '389-exception', 'deprecated': False}, - 'asterisk-exception': {'id': 'Asterisk-exception', 'deprecated': False}, - 'asterisk-linking-protocols-exception': {'id': 'Asterisk-linking-protocols-exception', 'deprecated': False}, - 'autoconf-exception-2.0': {'id': 'Autoconf-exception-2.0', 'deprecated': False}, - 'autoconf-exception-3.0': {'id': 'Autoconf-exception-3.0', 'deprecated': False}, - 'autoconf-exception-generic': {'id': 'Autoconf-exception-generic', 'deprecated': False}, - 'autoconf-exception-generic-3.0': {'id': 'Autoconf-exception-generic-3.0', 'deprecated': False}, - 'autoconf-exception-macro': {'id': 'Autoconf-exception-macro', 'deprecated': False}, - 'bison-exception-1.24': {'id': 'Bison-exception-1.24', 'deprecated': False}, - 'bison-exception-2.2': {'id': 'Bison-exception-2.2', 'deprecated': False}, - 'bootloader-exception': {'id': 'Bootloader-exception', 'deprecated': False}, - 'cgal-linking-exception': {'id': 'CGAL-linking-exception', 'deprecated': False}, - 'classpath-exception-2.0': {'id': 'Classpath-exception-2.0', 'deprecated': False}, - 'clisp-exception-2.0': {'id': 'CLISP-exception-2.0', 'deprecated': False}, - 'cryptsetup-openssl-exception': {'id': 'cryptsetup-OpenSSL-exception', 'deprecated': False}, - 'digia-qt-lgpl-exception-1.1': {'id': 'Digia-Qt-LGPL-exception-1.1', 'deprecated': False}, - 'digirule-foss-exception': {'id': 'DigiRule-FOSS-exception', 'deprecated': False}, - 'ecos-exception-2.0': {'id': 'eCos-exception-2.0', 'deprecated': False}, - 'erlang-otp-linking-exception': {'id': 'erlang-otp-linking-exception', 'deprecated': False}, - 'fawkes-runtime-exception': {'id': 'Fawkes-Runtime-exception', 'deprecated': False}, - 'fltk-exception': {'id': 'FLTK-exception', 'deprecated': False}, - 'fmt-exception': {'id': 'fmt-exception', 'deprecated': False}, - 'font-exception-2.0': {'id': 'Font-exception-2.0', 'deprecated': False}, - 'freertos-exception-2.0': {'id': 'freertos-exception-2.0', 'deprecated': False}, - 'gcc-exception-2.0': {'id': 'GCC-exception-2.0', 'deprecated': False}, - 'gcc-exception-2.0-note': {'id': 'GCC-exception-2.0-note', 'deprecated': False}, - 'gcc-exception-3.1': {'id': 'GCC-exception-3.1', 'deprecated': False}, - 'gmsh-exception': {'id': 'Gmsh-exception', 'deprecated': False}, - 'gnat-exception': {'id': 'GNAT-exception', 'deprecated': False}, - 'gnome-examples-exception': {'id': 'GNOME-examples-exception', 'deprecated': False}, - 'gnu-compiler-exception': {'id': 'GNU-compiler-exception', 'deprecated': False}, - 'gnu-javamail-exception': {'id': 'gnu-javamail-exception', 'deprecated': False}, - 'gpl-3.0-389-ds-base-exception': {'id': 'GPL-3.0-389-ds-base-exception', 'deprecated': False}, - 'gpl-3.0-interface-exception': {'id': 'GPL-3.0-interface-exception', 'deprecated': False}, - 'gpl-3.0-linking-exception': {'id': 'GPL-3.0-linking-exception', 'deprecated': False}, - 'gpl-3.0-linking-source-exception': {'id': 'GPL-3.0-linking-source-exception', 'deprecated': False}, - 'gpl-cc-1.0': {'id': 'GPL-CC-1.0', 'deprecated': False}, - 'gstreamer-exception-2005': {'id': 'GStreamer-exception-2005', 'deprecated': False}, - 'gstreamer-exception-2008': {'id': 'GStreamer-exception-2008', 'deprecated': False}, - 'harbour-exception': {'id': 'harbour-exception', 'deprecated': False}, - 'i2p-gpl-java-exception': {'id': 'i2p-gpl-java-exception', 'deprecated': False}, - 'independent-modules-exception': {'id': 'Independent-modules-exception', 'deprecated': False}, - 'kicad-libraries-exception': {'id': 'KiCad-libraries-exception', 'deprecated': False}, - 'lgpl-3.0-linking-exception': {'id': 'LGPL-3.0-linking-exception', 'deprecated': False}, - 'libpri-openh323-exception': {'id': 'libpri-OpenH323-exception', 'deprecated': False}, - 'libtool-exception': {'id': 'Libtool-exception', 'deprecated': False}, - 'linux-syscall-note': {'id': 'Linux-syscall-note', 'deprecated': False}, - 'llgpl': {'id': 'LLGPL', 'deprecated': False}, - 'llvm-exception': {'id': 'LLVM-exception', 'deprecated': False}, - 'lzma-exception': {'id': 'LZMA-exception', 'deprecated': False}, - 'mif-exception': {'id': 'mif-exception', 'deprecated': False}, - 'mxml-exception': {'id': 'mxml-exception', 'deprecated': False}, - 'nokia-qt-exception-1.1': {'id': 'Nokia-Qt-exception-1.1', 'deprecated': True}, - 'ocaml-lgpl-linking-exception': {'id': 'OCaml-LGPL-linking-exception', 'deprecated': False}, - 'occt-exception-1.0': {'id': 'OCCT-exception-1.0', 'deprecated': False}, - 'openjdk-assembly-exception-1.0': {'id': 'OpenJDK-assembly-exception-1.0', 'deprecated': False}, - 'openvpn-openssl-exception': {'id': 'openvpn-openssl-exception', 'deprecated': False}, - 'pcre2-exception': {'id': 'PCRE2-exception', 'deprecated': False}, - 'polyparse-exception': {'id': 'polyparse-exception', 'deprecated': False}, - 'ps-or-pdf-font-exception-20170817': {'id': 'PS-or-PDF-font-exception-20170817', 'deprecated': False}, - 'qpl-1.0-inria-2004-exception': {'id': 'QPL-1.0-INRIA-2004-exception', 'deprecated': False}, - 'qt-gpl-exception-1.0': {'id': 'Qt-GPL-exception-1.0', 'deprecated': False}, - 'qt-lgpl-exception-1.1': {'id': 'Qt-LGPL-exception-1.1', 'deprecated': False}, - 'qwt-exception-1.0': {'id': 'Qwt-exception-1.0', 'deprecated': False}, - 'romic-exception': {'id': 'romic-exception', 'deprecated': False}, - 'rrdtool-floss-exception-2.0': {'id': 'RRDtool-FLOSS-exception-2.0', 'deprecated': False}, - 'sane-exception': {'id': 'SANE-exception', 'deprecated': False}, - 'shl-2.0': {'id': 'SHL-2.0', 'deprecated': False}, - 'shl-2.1': {'id': 'SHL-2.1', 'deprecated': False}, - 'stunnel-exception': {'id': 'stunnel-exception', 'deprecated': False}, - 'swi-exception': {'id': 'SWI-exception', 'deprecated': False}, - 'swift-exception': {'id': 'Swift-exception', 'deprecated': False}, - 'texinfo-exception': {'id': 'Texinfo-exception', 'deprecated': False}, - 'u-boot-exception-2.0': {'id': 'u-boot-exception-2.0', 'deprecated': False}, - 'ubdl-exception': {'id': 'UBDL-exception', 'deprecated': False}, - 'universal-foss-exception-1.0': {'id': 'Universal-FOSS-exception-1.0', 'deprecated': False}, - 'vsftpd-openssl-exception': {'id': 'vsftpd-openssl-exception', 'deprecated': False}, - 'wxwindows-exception-3.1': {'id': 'WxWindows-exception-3.1', 'deprecated': False}, - 'x11vnc-openssl-exception': {'id': 'x11vnc-openssl-exception', 'deprecated': False}, -} diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py deleted file mode 100644 index 51b60364603..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/markers.py +++ /dev/null @@ -1,576 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import annotations - -import functools -import operator -import os -import platform -import sys -from collections.abc import Set as AbstractSet -from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union, cast - -from ._parser import MarkerAtom, MarkerList, Op, Value, Variable -from ._parser import parse_marker as _parse_marker -from ._tokenizer import ParserSyntaxError -from .specifiers import InvalidSpecifier, Specifier -from .utils import canonicalize_name - -if TYPE_CHECKING: - from collections.abc import Mapping - -__all__ = [ - "Environment", - "EvaluateContext", - "InvalidMarker", - "Marker", - "UndefinedComparison", - "UndefinedEnvironmentName", - "default_environment", -] - - -def __dir__() -> list[str]: - return __all__ - - -Operator = Callable[[str, Union[str, AbstractSet[str]]], bool] -EvaluateContext = Literal["metadata", "lock_file", "requirement"] -"""A ``typing.Literal`` enumerating valid marker evaluation contexts. - -Valid values for the ``context`` passed to :meth:`Marker.evaluate` are: - -* ``"metadata"`` (for core metadata; default) -* ``"lock_file"`` (for lock files) -* ``"requirement"`` (i.e. all other situations) - -.. versionadded:: 25.0 -""" - -MARKERS_ALLOWING_SET = {"extras", "dependency_groups"} -MARKERS_REQUIRING_VERSION = { - "implementation_version", - "platform_release", - "python_full_version", - "python_version", -} - - -class InvalidMarker(ValueError): - """Raised when attempting to create a :class:`Marker` from invalid input. - - This error indicates that the given marker string does not conform to the - :ref:`specification of dependency specifiers `. - """ - - -class UndefinedComparison(ValueError): - """Raised when evaluating an unsupported marker comparison. - - This can happen when marker values are compared as versions but do not - conform to the :ref:`specification of version specifiers - `. - """ - - -class UndefinedEnvironmentName(KeyError): - """Raised when evaluating a marker that references a missing environment key. - - Subclasses :class:`KeyError` so that code catching the bare ``KeyError`` that - a missing environment lookup historically produced keeps working. - - .. versionchanged:: 26.3 - Now subclasses :class:`KeyError` (was :class:`ValueError`) and is raised by - :meth:`Marker.evaluate` for missing environment keys, where a bare - ``KeyError`` was raised before. - """ - - -class Environment(TypedDict): - """ - A dictionary that represents a Python environment as captured by - :func:`default_environment`. All fields are required. - """ - - implementation_name: str - """The implementation's identifier, e.g. ``'cpython'``.""" - - implementation_version: str - """ - The implementation's version, e.g. ``'3.13.0a2'`` for CPython 3.13.0a2, or - ``'7.3.13'`` for PyPy3.10 v7.3.13. - """ - - os_name: str - """ - The value of :py:data:`os.name`. The name of the operating system dependent module - imported, e.g. ``'posix'``. - """ - - platform_machine: str - """ - Returns the machine type, e.g. ``'i386'``. - - An empty string if the value cannot be determined. - """ - - platform_release: str - """ - The system's release, e.g. ``'2.2.0'`` or ``'NT'``. - - An empty string if the value cannot be determined. - """ - - platform_system: str - """ - The system/OS name, e.g. ``'Linux'``, ``'Windows'`` or ``'Java'``. - - An empty string if the value cannot be determined. - """ - - platform_version: str - """ - The system's release version, e.g. ``'#3 on degas'``. - - An empty string if the value cannot be determined. - """ - - python_full_version: str - """ - The Python version as string ``'major.minor.patchlevel'``. - - Note that unlike the Python :py:data:`sys.version`, this value will always include - the patchlevel (it defaults to 0). - """ - - platform_python_implementation: str - """ - A string identifying the Python implementation, e.g. ``'CPython'``. - """ - - python_version: str - """The Python version as string ``'major.minor'``.""" - - sys_platform: str - """ - This string contains a platform identifier that can be used to append - platform-specific components to :py:data:`sys.path`, for instance. - - For Unix systems, except on Linux and AIX, this is the lowercased OS name as - returned by ``uname -s`` with the first part of the version as returned by - ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, at the time when Python - was built. - """ - - -def _normalize_extras( - result: MarkerList | MarkerAtom | str, -) -> MarkerList | MarkerAtom | str: - if isinstance(result, list): - return [_normalize_extras(r) for r in result] - if not isinstance(result, tuple): - return result - - lhs, op, rhs = result - if isinstance(lhs, Variable) and lhs.value == "extra" and isinstance(rhs, Value): - normalized_extra = canonicalize_name(rhs.value) - rhs = Value(normalized_extra) - elif isinstance(rhs, Variable) and rhs.value == "extra" and isinstance(lhs, Value): - normalized_extra = canonicalize_name(lhs.value) - lhs = Value(normalized_extra) - elif ( - isinstance(rhs, Variable) - and rhs.value in MARKERS_ALLOWING_SET - and isinstance(lhs, Value) - ): - # PEP 685 (extras) / PEP 735 (dependency_groups): the set-valued membership - # literal must also be normalized. evaluate() already canonicalizes both - # operands for these keys (see _normalize), so normalizing the literal at - # parse time keeps __str__/__eq__/__hash__ consistent with evaluate() -- e.g. - # Marker('"Foo" in extras') and Marker('"foo" in extras') must compare and - # hash equal (the membership variable is always the right-hand operand). - lhs = Value(canonicalize_name(lhs.value)) - return lhs, op, rhs - - -def _normalize_extra_values(results: MarkerList) -> MarkerList: - """ - Normalize extra values. - """ - - return [_normalize_extras(r) for r in results] - - -def _format_marker( - marker: list[str] | MarkerAtom | str, first: bool | None = True -) -> str: - assert isinstance(marker, (list, tuple, str)) - - # Unwrap a redundant [[...]] wrapper, but keep the nesting context so a - # nested group keeps the parentheses its and/or precedence needs. - if ( - isinstance(marker, list) - and len(marker) == 1 - and isinstance(marker[0], (list, tuple)) - ): - return _format_marker(marker[0], first=first) - - if isinstance(marker, list): - inner = (_format_marker(m, first=False) for m in marker) - if first: - return " ".join(inner) - else: - return "(" + " ".join(inner) + ")" - elif isinstance(marker, tuple): - return " ".join([m.serialize() for m in marker]) - else: - return marker - - -_operators: dict[str, Operator] = { - "in": lambda lhs, rhs: lhs in rhs, - "not in": lambda lhs, rhs: lhs not in rhs, - "<": lambda _lhs, _rhs: False, - "<=": operator.eq, - "==": operator.eq, - "!=": operator.ne, - ">=": operator.eq, - ">": lambda _lhs, _rhs: False, -} - - -def _eval_op(lhs: str, op: Op, rhs: str | AbstractSet[str], *, key: str) -> bool: - op_str = op.serialize() - if key in MARKERS_REQUIRING_VERSION: - try: - spec = Specifier(f"{op_str}{rhs}") - except InvalidSpecifier: - pass - else: - return spec.contains(lhs, prereleases=True) - - oper: Operator | None = _operators.get(op_str) - if oper is None: - raise UndefinedComparison(f"Undefined {op!r} on {lhs!r} and {rhs!r}.") - - return oper(lhs, rhs) - - -def _normalize( - lhs: str, rhs: str | AbstractSet[str], key: str -) -> tuple[str, str | AbstractSet[str]]: - # PEP 685 - Comparison of extra names for optional distribution dependencies - # https://peps.python.org/pep-0685/ - # > When comparing extra names, tools MUST normalize the names being - # > compared using the semantics outlined in PEP 503 for names - if key == "extra": - assert isinstance(rhs, str), "extra value must be a string" - # Both sides are normalized at this point already - return (lhs, rhs) - if key in MARKERS_ALLOWING_SET: - if isinstance(rhs, str): # pragma: no cover - return (canonicalize_name(lhs), canonicalize_name(rhs)) - else: - return (canonicalize_name(lhs), {canonicalize_name(v) for v in rhs}) - - # other environment markers don't have such standards - return lhs, rhs - - -def _lookup_environment( - environment: dict[str, str | AbstractSet[str]], key: str -) -> str | AbstractSet[str]: - try: - return environment[key] - except KeyError: - raise UndefinedEnvironmentName(key) from None - - -def _evaluate_markers( - markers: MarkerList, environment: dict[str, str | AbstractSet[str]] -) -> bool: - groups: list[list[bool]] = [[]] - - for marker in markers: - if isinstance(marker, list): - groups[-1].append(_evaluate_markers(marker, environment)) - elif isinstance(marker, tuple): - lhs, op, rhs = marker - - if isinstance(lhs, Variable): - environment_key = lhs.value - lhs_value = _lookup_environment(environment, environment_key) - rhs_value = rhs.value - else: - lhs_value = lhs.value - environment_key = rhs.value - rhs_value = _lookup_environment(environment, environment_key) - - if not isinstance(lhs_value, str): - raise UndefinedComparison( - f"Set-valued marker {environment_key!r} can only be used " - f'with the membership form (e.g. "" in ' - f"{environment_key}); it cannot appear on the left-hand " - f"side of {op.serialize()!r}." - ) - lhs_value, rhs_value = _normalize(lhs_value, rhs_value, key=environment_key) - groups[-1].append(_eval_op(lhs_value, op, rhs_value, key=environment_key)) - elif marker == "or": - groups.append([]) - elif marker == "and": - pass - else: # pragma: nocover - raise TypeError(f"Unexpected marker {marker!r}") - - return any(all(item) for item in groups) - - -def _format_full_version(info: sys._version_info) -> str: - version = f"{info.major}.{info.minor}.{info.micro}" - kind = info.releaselevel - if kind != "final": - version += kind[0] + str(info.serial) - return version - - -@functools.cache -def _cached_default_environment() -> Environment: - """Build the default marker environment for the current Python process. - - The values are derived from process-constant data (the running interpreter - and the host platform), so this is cached and built only once. The result is - shared between callers and must never be mutated; :func:`default_environment` - returns a fresh copy. - """ - iver = _format_full_version(sys.implementation.version) - implementation_name = sys.implementation.name - return { - "implementation_name": implementation_name, - "implementation_version": iver, - "os_name": os.name, - "platform_machine": platform.machine(), - "platform_release": platform.release(), - "platform_system": platform.system(), - "platform_version": platform.version(), - "python_full_version": platform.python_version(), - "platform_python_implementation": platform.python_implementation(), - "python_version": ".".join(platform.python_version_tuple()[:2]), - "sys_platform": sys.platform, - } - - -def default_environment() -> Environment: - """Return the default marker environment for the current Python process. - - This is the base environment used by :meth:`Marker.evaluate`. A fresh copy - is returned on every call so callers may freely mutate the result; a shallow - copy suffices because all values are immutable strings. - - .. versionchanged:: 26.3 - The environment is computed once per process and cached, since it is - derived from process-constant data. Patching ``platform``/``sys``/``os`` - after the first call has no effect; pass an explicit ``environment`` to - :meth:`Marker.evaluate` to evaluate against different values. - """ - return cast("Environment", dict(_cached_default_environment())) - - -class Marker: - """Represents a parsed dependency marker expression. - - Marker expressions are parsed according to the - :ref:`specification of dependency specifiers `. - - :param marker: The string representation of a marker expression. - :raises InvalidMarker: If ``marker`` cannot be parsed. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ("_markers",) - - def __init__(self, marker: str) -> None: - # Note: We create a Marker object without calling this constructor in - # packaging.requirements.Requirement. If any additional logic is - # added here, make sure to mirror/adapt Requirement. - - # If this fails and throws an error, the repr still expects _markers to - # be defined. - self._markers: MarkerList = [] - - try: - self._markers = _normalize_extra_values(_parse_marker(marker)) - # The attribute `_markers` can be described in terms of a recursive type: - # MarkerList = List[Union[Tuple[Node, ...], str, MarkerList]] - # - # For example, the following expression: - # python_version > "3.6" or (python_version == "3.6" and os_name == "unix") - # - # is parsed into: - # [ - # (, ')>, ), - # 'and', - # [ - # (, , ), - # 'or', - # (, , ) - # ] - # ] - except ParserSyntaxError as e: - raise InvalidMarker(str(e)) from e - - @classmethod - def _from_markers(cls, markers: MarkerList) -> Marker: - """Create a Marker instance from a pre-parsed marker tree. - - This avoids re-parsing serialised marker strings when combining markers. - """ - new = cls.__new__(cls) - new._markers = markers - return new - - def __str__(self) -> str: - return _format_marker(self._markers) - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}({str(self)!r})>" - - def __hash__(self) -> int: - return hash(str(self)) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Marker): - return NotImplemented - - return str(self) == str(other) - - def __getstate__(self) -> str: - # Return the marker expression string for compactness and stability. - # Internal Node objects are excluded; the string is re-parsed on load. - return str(self) - - def __setstate__(self, state: object) -> None: - if isinstance(state, str): - # New format (26.2+): just the marker expression string. - try: - self._markers = _normalize_extra_values(_parse_marker(state)) - except ParserSyntaxError as exc: - raise TypeError(f"Cannot restore Marker from {state!r}") from exc - return - if isinstance(state, dict) and "_markers" in state: - # Old format (packaging <= 26.1, no __slots__): plain __dict__. - markers = state["_markers"] - if isinstance(markers, list): - self._markers = markers - return - if isinstance(state, tuple) and len(state) == 2: - # Old format (packaging <= 26.1, __slots__): (None, {slot: value}). - _, slot_dict = state - if isinstance(slot_dict, dict) and "_markers" in slot_dict: - markers = slot_dict["_markers"] - if isinstance(markers, list): - self._markers = markers - return - raise TypeError(f"Cannot restore Marker from {state!r}") - - def __and__(self, other: Marker) -> Marker: - """Combine this marker with another using ``and``. - - .. versionadded:: 26.1 - """ - if not isinstance(other, Marker): - return NotImplemented - return self._from_markers([self._markers, "and", other._markers]) - - def __or__(self, other: Marker) -> Marker: - """Combine this marker with another using ``or``. - - .. versionadded:: 26.1 - """ - if not isinstance(other, Marker): - return NotImplemented - return self._from_markers([self._markers, "or", other._markers]) - - def evaluate( - self, - environment: Mapping[str, str | AbstractSet[str]] | None = None, - context: EvaluateContext = "metadata", - ) -> bool: - """Evaluate a marker. - - Return the boolean from evaluating this marker against the environment. - The environment is determined from the current Python process unless - passed in explicitly. - - :param environment: Mapping containing keys and values to override the - detected environment. - :param EvaluateContext context: The context in which the marker is - evaluated, which influences what marker names are considered valid. - Accepted values are ``"metadata"`` (for core metadata; default), - ``"lock_file"``, and ``"requirement"`` (i.e. all other situations). - :raises UndefinedComparison: If the marker uses a comparison on values - that are not valid versions per the :ref:`specification of version - specifiers `. - :raises UndefinedEnvironmentName: If the marker references a value that - is missing from the evaluation environment. - :returns: ``True`` if the marker matches, otherwise ``False``. - - .. versionchanged:: 25.0 - Added the ``context`` parameter, which influences which marker names - are considered valid. - """ - current_environment = cast( - "dict[str, str | AbstractSet[str]]", default_environment() - ) - if context == "lock_file": - current_environment |= { - "extras": frozenset(), - "dependency_groups": frozenset(), - } - elif context == "metadata": - current_environment["extra"] = "" - - if environment is not None: - current_environment |= environment - if "extra" in current_environment: - # The API used to allow setting extra to None. We need to handle - # this case for backwards compatibility. Also skip running - # normalize name if extra is empty. - extra = cast("str | None", current_environment["extra"]) - current_environment["extra"] = canonicalize_name(extra) if extra else "" - - return _evaluate_markers( - self._markers, _repair_python_full_version(current_environment) - ) - - -def _pep440_python_full_version(python_full_version: str) -> str: - """ - Work around platform.python_version() returning something that is not PEP 440 - compliant for non-tagged Python builds. - """ - if python_full_version.endswith("+"): - return f"{python_full_version}local" - return python_full_version - - -def _repair_python_full_version( - env: dict[str, str | AbstractSet[str]], -) -> dict[str, str | AbstractSet[str]]: - """ - Work around platform.python_version() returning something that is not PEP 440 - compliant for non-tagged Python builds. - """ - python_full_version = cast("str", env["python_full_version"]) - env["python_full_version"] = _pep440_python_full_version(python_full_version) - return env diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py deleted file mode 100644 index 10611050051..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/metadata.py +++ /dev/null @@ -1,1054 +0,0 @@ -from __future__ import annotations - -import email.header -import email.message -import email.parser -import email.policy -import keyword -import pathlib -import re -import typing -from typing import ( - Any, - Callable, - Generic, - Literal, - TypedDict, - cast, -) - -from . import licenses, requirements, specifiers, utils -from . import version as version_module -from .errors import ExceptionGroup, _ErrorCollector - -if typing.TYPE_CHECKING: - from .licenses import NormalizedLicenseExpression - from .version import Version - -T = typing.TypeVar("T") - - -__all__ = [ - "ExceptionGroup", # Keep this for a bit (makes mypy happy w/ 26.0 compat) - "InvalidMetadata", - "Metadata", - "RFC822Message", - "RFC822Policy", - "RawMetadata", - "parse_email", -] - - -def __dir__() -> list[str]: - return __all__ - - -class InvalidMetadata(ValueError): - """A metadata field contains invalid data. - - .. versionadded:: 23.2 - """ - - field: str - """The name of the field that contains invalid data.""" - - def __init__(self, field: str, message: str) -> None: - self.field = field - super().__init__(message) - - # Support pickling; ``args`` does not match ``__init__``'s signature. - def __reduce__(self) -> tuple[type[InvalidMetadata], tuple[str, str]]: - return (self.__class__, (self.field, self.args[0])) - - -# The RawMetadata class attempts to make as few assumptions about the underlying -# serialization formats as possible. The idea is that as long as a serialization -# formats offer some very basic primitives in *some* way then we can support -# serializing to and from that format. -class RawMetadata(TypedDict, total=False): - """A dictionary of raw core metadata. - - Each field in core metadata maps to a key of this dictionary (when data is - provided). The key is lower-case and underscores are used instead of dashes - compared to the equivalent core metadata field. Any core metadata field that - can be specified multiple times or can hold multiple values in a single - field have a key with a plural name. See :class:`Metadata` whose attributes - match the keys of this dictionary. - - Core metadata fields that can be specified multiple times are stored as a - list or dict depending on which is appropriate for the field. Any fields - which hold multiple values in a single field are stored as a list. All fields - are considered optional. - """ - - # Metadata 1.0 - PEP 241 - metadata_version: str - name: str - version: str - platforms: list[str] - summary: str - description: str - keywords: list[str] - home_page: str - author: str - author_email: str - license: str - - # Metadata 1.1 - PEP 314 - supported_platforms: list[str] - download_url: str - classifiers: list[str] - requires: list[str] - provides: list[str] - obsoletes: list[str] - - # Metadata 1.2 - PEP 345 - maintainer: str - maintainer_email: str - requires_dist: list[str] - provides_dist: list[str] - obsoletes_dist: list[str] - requires_python: str - requires_external: list[str] - project_urls: dict[str, str] - - # Metadata 2.0 - # PEP 426 attempted to completely revamp the metadata format - # but got stuck without ever being able to build consensus on - # it and ultimately ended up withdrawn. - # - # However, a number of tools had started emitting METADATA with - # `2.0` Metadata-Version, so for historical reasons, this version - # was skipped. - - # Metadata 2.1 - PEP 566 - description_content_type: str - provides_extra: list[str] - - # Metadata 2.2 - PEP 643 - dynamic: list[str] - - # Metadata 2.3 - PEP 685 - # No new fields were added in PEP 685, just some edge case were - # tightened up to provide better interoperability. - - # Metadata 2.4 - PEP 639 - license_expression: str - """.. versionadded:: 24.2""" - license_files: list[str] - """.. versionadded:: 24.2""" - - # Metadata 2.5 - PEP 794 - import_names: list[str] - """.. versionadded:: 26.0""" - import_namespaces: list[str] - """.. versionadded:: 26.0""" - - # Metadata 2.6 - PEP 808 (no new fields, behavior change for Dynamic) - - -# 'keywords' is special as it's a string in the core metadata spec, but we -# represent it as a list. -_STRING_FIELDS = { - "author", - "author_email", - "description", - "description_content_type", - "download_url", - "home_page", - "license", - "license_expression", - "maintainer", - "maintainer_email", - "metadata_version", - "name", - "requires_python", - "summary", - "version", -} - -_LIST_FIELDS = { - "classifiers", - "dynamic", - "license_files", - "obsoletes", - "obsoletes_dist", - "platforms", - "provides", - "provides_dist", - "provides_extra", - "requires", - "requires_dist", - "requires_external", - "supported_platforms", - "import_names", - "import_namespaces", -} - -_DICT_FIELDS = { - "project_urls", -} - - -def _parse_keywords(data: str) -> list[str]: - """Split a string of comma-separated keywords into a list of keywords.""" - return [k.strip() for k in data.split(",")] - - -def _parse_project_urls(data: list[str]) -> dict[str, str]: - """Parse a list of label/URL string pairings separated by a comma.""" - urls = {} - for pair in data: - # Our logic is slightly tricky here as we want to try and do - # *something* reasonable with malformed data. - # - # The main thing that we have to worry about, is data that does - # not have a ',' at all to split the label from the Value. There - # isn't a singular right answer here, and we will fail validation - # later on (if the caller is validating) so it doesn't *really* - # matter, but since the missing value has to be an empty str - # and our return value is dict[str, str], if we let the key - # be the missing value, then they'd have multiple '' values that - # overwrite each other in a accumulating dict. - # - # The other potential issue is that it's possible to have the - # same label multiple times in the metadata, with no solid "right" - # answer with what to do in that case. As such, we'll do the only - # thing we can, which is treat the field as unparsable and add it - # to our list of unparsed fields. - # - # TODO: The spec doesn't say anything about if the keys should be - # considered case sensitive or not... logically they should - # be case-preserving and case-insensitive, but doing that - # would open up more cases where we might have duplicate - # entries. - label, _, url = (s.strip() for s in pair.partition(",")) - - if label in urls: - # The label already exists in our set of urls, so this field - # is unparsable, and we can just add the whole thing to our - # unparsable data and stop processing it. - raise KeyError("duplicate labels in project urls") - urls[label] = url - - return urls - - -def _get_payload(msg: email.message.Message, source: bytes | str) -> str: - """Get the body of the message.""" - # If our source is a str, then our caller has managed encodings for us, - # and we don't need to deal with it. - if isinstance(source, str): - payload = msg.get_payload() - # A multipart payload makes get_payload() return a list of messages - # rather than a str; route it to ``unparsed``. - if not isinstance(payload, str): - raise ValueError("payload is not a string") # noqa: TRY004 - return payload - # If our source is a bytes, then we're managing the encoding and we need - # to deal with it. - else: - bpayload = msg.get_payload(decode=True) - # A multipart payload makes get_payload(decode=True) return None; - # route it to ``unparsed``. - if not isinstance(bpayload, bytes): - raise ValueError("payload in an invalid encoding") # noqa: TRY004 - try: - return bpayload.decode("utf8", "strict") - except UnicodeDecodeError as exc: - raise ValueError("payload in an invalid encoding") from exc - - -# The various parse_FORMAT functions here are intended to be as lenient as -# possible in their parsing, while still returning a correctly typed -# RawMetadata. -# -# To aid in this, we also generally want to do as little touching of the -# data as possible, except where there are possibly some historic holdovers -# that make valid data awkward to work with. -# -# While this is a lower level, intermediate format than our ``Metadata`` -# class, some light touch ups can make a massive difference in usability. - -# Map METADATA fields to RawMetadata. -_EMAIL_TO_RAW_MAPPING = { - "author": "author", - "author-email": "author_email", - "classifier": "classifiers", - "description": "description", - "description-content-type": "description_content_type", - "download-url": "download_url", - "dynamic": "dynamic", - "home-page": "home_page", - "import-name": "import_names", - "import-namespace": "import_namespaces", - "keywords": "keywords", - "license": "license", - "license-expression": "license_expression", - "license-file": "license_files", - "maintainer": "maintainer", - "maintainer-email": "maintainer_email", - "metadata-version": "metadata_version", - "name": "name", - "obsoletes": "obsoletes", - "obsoletes-dist": "obsoletes_dist", - "platform": "platforms", - "project-url": "project_urls", - "provides": "provides", - "provides-dist": "provides_dist", - "provides-extra": "provides_extra", - "requires": "requires", - "requires-dist": "requires_dist", - "requires-external": "requires_external", - "requires-python": "requires_python", - "summary": "summary", - "supported-platform": "supported_platforms", - "version": "version", -} -_RAW_TO_EMAIL_MAPPING = {raw: email for email, raw in _EMAIL_TO_RAW_MAPPING.items()} - - -# A bare "\r" makes the email generator raise ``HeaderWriteError``, and on -# CPython releases without the CVE-2024-6923 fix any ``str.splitlines`` -# boundary ends the header line, so fold all of them, not just "\n". -_LINE_BOUNDARY_RE = re.compile(r"\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]") - - -# This class is for writing RFC822 messages -class RFC822Policy(email.policy.EmailPolicy): - """ - This is :class:`email.policy.EmailPolicy`, but with a simple ``header_store_parse`` - implementation that handles multi-line values, and some nice defaults. - - .. versionadded:: 26.0 - """ - - utf8 = True - mangle_from_ = False - max_line_length = 0 - - def header_store_parse(self, name: str, value: str) -> tuple[str, str]: - size = len(name) + 2 - value = _LINE_BOUNDARY_RE.sub("\n" + " " * size, value) - return (name, value) - - -# This class is for writing RFC822 messages -class RFC822Message(email.message.EmailMessage): - """ - This is :class:`email.message.EmailMessage` with two small changes: it defaults to - our `RFC822Policy`, and it correctly writes unicode when being called - with `bytes()`. - - .. versionadded:: 26.0 - """ - - def __init__(self) -> None: - super().__init__(policy=RFC822Policy()) - - def as_bytes( - self, unixfrom: bool = False, policy: email.policy.Policy | None = None - ) -> bytes: - """ - Return the bytes representation of the message. - - This handles unicode encoding. - """ - return self.as_string(unixfrom, policy=policy).encode("utf-8") - - -def parse_email(data: bytes | str) -> tuple[RawMetadata, dict[str, list[str]]]: - """Parse a distribution's metadata stored as email headers (e.g. from ``METADATA``). - - This function returns a two-item tuple of dicts. The first dict is of - recognized fields from the core metadata specification. Fields that can be - parsed and translated into Python's built-in types are converted - appropriately. All other fields are left as-is. Fields that are allowed to - appear multiple times are stored as lists. - - The second dict contains all other fields from the metadata. This includes - any unrecognized fields. It also includes any fields which are expected to - be parsed into a built-in type but were not formatted appropriately. Finally, - any fields that are expected to appear only once but are repeated are - included in this dict. - - """ - raw: dict[str, str | list[str] | dict[str, str]] = {} - unparsed: dict[str, list[str]] = {} - - if isinstance(data, str): - parsed = email.parser.Parser(policy=email.policy.compat32).parsestr(data) - else: - parsed = email.parser.BytesParser(policy=email.policy.compat32).parsebytes(data) - - # We have to wrap parsed.keys() in a set, because in the case of multiple - # values for a key (a list), the key will appear multiple times in the - # list of keys, but we're avoiding that by using get_all(). - for name_with_case in frozenset(parsed.keys()): - # Header names in RFC are case insensitive, so we'll normalize to all - # lower case to make comparisons easier. - name = name_with_case.lower() - - # We use get_all() here, even for fields that aren't multiple use, - # because otherwise someone could have e.g. two Name fields, and we - # would just silently ignore it rather than doing something about it. - headers = parsed.get_all(name) or [] - - # The way the email module works when parsing bytes is that it - # unconditionally decodes the bytes as ascii using the surrogateescape - # handler. When you pull that data back out (such as with get_all() ), - # it looks to see if the str has any surrogate escapes, and if it does - # it wraps it in a Header object instead of returning the string. - # - # As such, we'll look for those Header objects, and fix up the encoding. - value = [] - # Flag if we have run into any issues processing the headers, thus - # signalling that the data belongs in 'unparsed'. - valid_encoding = True - for h in headers: - # It's unclear if this can return more types than just a Header or - # a str, so we'll just assert here to make sure. - assert isinstance(h, (email.header.Header, str)) - - # If it's a header object, we need to do our little dance to get - # the real data out of it. In cases where there is invalid data - # we're going to end up with mojibake, but there's no obvious, good - # way around that without reimplementing parts of the Header object - # ourselves. - # - # That should be fine since, if mojibacked happens, this key is - # going into the unparsed dict anyways. - if isinstance(h, email.header.Header): - # The Header object stores it's data as chunks, and each chunk - # can be independently encoded, so we'll need to check each - # of them. - chunks: list[tuple[bytes, str | None]] = [] - for binary, _encoding in email.header.decode_header(h): - try: - binary.decode("utf8", "strict") - except UnicodeDecodeError: - # Enable mojibake. - encoding = "latin1" - valid_encoding = False - else: - encoding = "utf8" - chunks.append((binary, encoding)) - - # Turn our chunks back into a Header object, then let that - # Header object do the right thing to turn them into a - # string for us. - value.append(str(email.header.make_header(chunks))) - # This is already a string, so just add it. - else: - value.append(h) - - # We've processed all of our values to get them into a list of str, - # but we may have mojibake data, in which case this is an unparsed - # field. - if not valid_encoding: - unparsed[name] = value - continue - - raw_name = _EMAIL_TO_RAW_MAPPING.get(name) - if raw_name is None: - # This is a bit of a weird situation, we've encountered a key that - # we don't know what it means, so we don't know whether it's meant - # to be a list or not. - # - # Since we can't really tell one way or another, we'll just leave it - # as a list, even though it may be a single item list, because that's - # what makes the most sense for email headers. - unparsed[name] = value - continue - - # If this is one of our string fields, then we'll check to see if our - # value is a list of a single item. If it is then we'll assume that - # it was emitted as a single string, and unwrap the str from inside - # the list. - # - # If it's any other kind of data, then we haven't the faintest clue - # what we should parse it as, and we have to just add it to our list - # of unparsed stuff. - if raw_name in _STRING_FIELDS and len(value) == 1: - raw[raw_name] = value[0] - # If this is import_names, we need to special case the empty field - # case, which converts to an empty list instead of None. We can't let - # the empty case slip through, as it will fail validation. - elif raw_name == "import_names" and value == [""]: - raw[raw_name] = [] - # If this is one of our list of string fields, then we can just assign - # the value, since email *only* has strings, and our get_all() call - # above ensures that this is a list. - elif raw_name in _LIST_FIELDS: - raw[raw_name] = value - # Special Case: Keywords - # The keywords field is implemented in the metadata spec as a str, - # but it conceptually is a list of strings, and is serialized using - # ", ".join(keywords), so we'll do some light data massaging to turn - # this into what it logically is. - elif raw_name == "keywords" and len(value) == 1: - raw[raw_name] = _parse_keywords(value[0]) - # Special Case: Project-URL - # The project urls is implemented in the metadata spec as a list of - # specially-formatted strings that represent a key and a value, which - # is fundamentally a mapping, however the email format doesn't support - # mappings in a sane way, so it was crammed into a list of strings - # instead. - # - # We will do a little light data massaging to turn this into a map as - # it logically should be. - elif raw_name == "project_urls": - try: - raw[raw_name] = _parse_project_urls(value) - except KeyError: - unparsed[name] = value - # Nothing that we've done has managed to parse this, so it'll just - # throw it in our unparsable data and move on. - else: - unparsed[name] = value - - # We need to support getting the Description from the message payload in - # addition to getting it from the the headers. This does mean, though, there - # is the possibility of it being set both ways, in which case we put both - # in 'unparsed' since we don't know which is right. - try: - payload = _get_payload(parsed, data) - except ValueError: - unparsed.setdefault("description", []).append( - parsed.get_payload(decode=isinstance(data, bytes)) # type: ignore[call-overload] - ) - else: - if payload: - # Check to see if we've already got a description, if so then both - # it, and this body move to unparsable. - if "description" in raw: - description_header = cast("str", raw.pop("description")) - unparsed.setdefault("description", []).extend( - [description_header, payload] - ) - elif "description" in unparsed: - unparsed["description"].append(payload) - else: - raw["description"] = payload - - # We need to cast our `raw` to a metadata, because a TypedDict only support - # literal key names, but we're computing our key names on purpose, but the - # way this function is implemented, our `TypedDict` can only have valid key - # names. - return cast("RawMetadata", raw), unparsed - - -_NOT_FOUND = object() - - -# Keep the two values in sync. -_VALID_METADATA_VERSIONS = [ - "1.0", - "1.1", - "1.2", - "2.1", - "2.2", - "2.3", - "2.4", - "2.5", - "2.6", -] -_MetadataVersion = Literal[ - "1.0", "1.1", "1.2", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6" -] - -_REQUIRED_ATTRS = frozenset(["metadata_version", "name", "version"]) - - -class _Validator(Generic[T]): - """Validate a metadata field. - - All _process_*() methods correspond to a core metadata field. The method is - called with the field's raw value. If the raw value is valid it is returned - in its "enriched" form (e.g. ``version.Version`` for the ``Version`` field). - If the raw value is invalid, :exc:`InvalidMetadata` is raised (with a cause - as appropriate). - """ - - name: str - raw_name: str - added: _MetadataVersion - - def __init__( - self, - *, - added: _MetadataVersion = "1.0", - ) -> None: - self.added = added - - def __set_name__(self, _owner: Metadata, name: str) -> None: - self.name = name - self.raw_name = _RAW_TO_EMAIL_MAPPING[name] - - def __get__(self, instance: Metadata, _owner: type[Metadata]) -> T: - # With Python 3.8, the caching can be replaced with functools.cached_property(). - # No need to check the cache as attribute lookup will resolve into the - # instance's __dict__ before __get__ is called. - cache = instance.__dict__ - value = instance._raw.get(self.name) - - # To make the _process_* methods easier, we'll check if the value is None - # and if this field is NOT a required attribute, and if both of those - # things are true, we'll skip the the converter. This will mean that the - # converters never have to deal with the None union. - if self.name in _REQUIRED_ATTRS or value is not None: - try: - converter: Callable[[Any], T] = getattr(self, f"_process_{self.name}") - except AttributeError: - pass - else: - value = converter(value) - - cache[self.name] = value - try: - del instance._raw[self.name] # type: ignore[misc] - except KeyError: - pass - - return cast("T", value) - - def _invalid_metadata( - self, msg: str, cause: Exception | None = None - ) -> InvalidMetadata: - exc = InvalidMetadata(self.raw_name, msg) - exc.__cause__ = cause - return exc - - def _process_metadata_version(self, value: str) -> _MetadataVersion: - # Implicitly makes Metadata-Version required. - if value not in _VALID_METADATA_VERSIONS: - raise self._invalid_metadata(f"{value!r} is not a valid metadata version") - return cast("_MetadataVersion", value) - - def _process_name(self, value: str) -> str: - if not value: - raise self._invalid_metadata(f"{self.raw_name!r} is a required field") - # Validate the name as a side-effect. - try: - utils.canonicalize_name(value, validate=True) - except utils.InvalidName as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {self.raw_name!r}", cause=exc - ) from exc - else: - return value - - def _process_version(self, value: str) -> Version: - if not value: - raise self._invalid_metadata(f"{self.raw_name!r} is a required field") - try: - return version_module.parse(value) - except version_module.InvalidVersion as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {self.raw_name!r}", cause=exc - ) from exc - - def _process_summary(self, value: str) -> str: - """Check the field contains no line breaks.""" - if _LINE_BOUNDARY_RE.search(value): - raise self._invalid_metadata(f"{self.raw_name!r} must be a single line") - return value - - def _process_description_content_type(self, value: str) -> str: - content_types = {"text/plain", "text/x-rst", "text/markdown"} - invalid_msg = ( - f"{self.raw_name!r} must be one of {list(content_types)}, not {value!r}" - ) - message = email.message.EmailMessage() - try: - message["content-type"] = value - # The email parser can raise IndexError on malformed RFC 2231 - # parameters such as "text/plain; x*". - except (ValueError, IndexError) as exc: - msg = f"{value!r} is not a valid content type for {self.raw_name!r}" - raise self._invalid_metadata(msg, cause=exc) from exc - content_type_header = message["content-type"] - if content_type_header.defects: - defect = content_type_header.defects[0] - msg = ( - f"{value!r} is not a valid content type for {self.raw_name!r}: {defect}" - ) - raise self._invalid_metadata(msg, cause=defect) from defect - - content_type, parameters = ( - # Defaults to `text/plain` if parsing failed. - message.get_content_type().lower(), - content_type_header.params, - ) - # Check if content-type is valid or defaulted to `text/plain` and thus was - # not parseable. - if content_type not in content_types or content_type not in value.lower(): - raise self._invalid_metadata(invalid_msg) - - charset = parameters.get("charset", "UTF-8") - if charset.lower() != "utf-8": - raise self._invalid_metadata( - f"{self.raw_name!r} can only specify the UTF-8 charset, not {charset!r}" - ) - - markdown_variants = {"GFM", "CommonMark"} - variant = parameters.get("variant", "GFM") # Use an acceptable default. - if content_type == "text/markdown" and variant not in markdown_variants: - raise self._invalid_metadata( - f"valid Markdown variants for {self.raw_name!r} are " - f"{list(markdown_variants)}, not {variant!r}", - ) - return value - - def _process_dynamic(self, value: list[str]) -> list[str]: - dynamic_fields = list(map(str.lower, value)) - for dynamic_field in dynamic_fields: - if dynamic_field in {"name", "version", "metadata-version"}: - raise self._invalid_metadata( - f"{dynamic_field!r} is not allowed as a dynamic field" - ) - elif dynamic_field not in _EMAIL_TO_RAW_MAPPING: - raise self._invalid_metadata( - f"{dynamic_field!r} is not a valid dynamic field" - ) - return dynamic_fields - - def _process_provides_extra( - self, - value: list[str], - ) -> list[utils.NormalizedName]: - normalized_names = [] - try: - for name in value: - normalized_names.append(utils.canonicalize_name(name, validate=True)) - except utils.InvalidName as exc: - raise self._invalid_metadata( - f"{name!r} is invalid for {self.raw_name!r}", cause=exc - ) from exc - else: - return normalized_names - - def _process_requires_python(self, value: str) -> specifiers.SpecifierSet: - try: - return specifiers.SpecifierSet(value) - except specifiers.InvalidSpecifier as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {self.raw_name!r}", cause=exc - ) from exc - - def _process_requires_dist( - self, - value: list[str], - ) -> list[requirements.Requirement]: - reqs = [] - try: - for req in value: - reqs.append(requirements.Requirement(req)) - except requirements.InvalidRequirement as exc: - raise self._invalid_metadata( - f"{req!r} is invalid for {self.raw_name!r}", cause=exc - ) from exc - else: - return reqs - - def _process_license_expression(self, value: str) -> NormalizedLicenseExpression: - try: - return licenses.canonicalize_license_expression(value) - except ValueError as exc: - raise self._invalid_metadata( - f"{value!r} is invalid for {self.raw_name!r}", cause=exc - ) from exc - - def _process_license_files(self, value: list[str]) -> list[str]: - paths = [] - for path in value: - if ".." in path: - raise self._invalid_metadata( - f"{path!r} is invalid for {self.raw_name!r}, " - "parent directory indicators are not allowed" - ) - if "*" in path: - raise self._invalid_metadata( - f"{path!r} is invalid for {self.raw_name!r}, paths must be resolved" - ) - if ( - pathlib.PurePosixPath(path).is_absolute() - or pathlib.PureWindowsPath(path).is_absolute() - ): - raise self._invalid_metadata( - f"{path!r} is invalid for {self.raw_name!r}, paths must be relative" - ) - if pathlib.PureWindowsPath(path).as_posix() != path: - raise self._invalid_metadata( - f"{path!r} is invalid for {self.raw_name!r}, " - "paths must use '/' delimiter" - ) - paths.append(path) - return paths - - def _process_import_names(self, value: list[str]) -> list[str]: - for import_name in value: - name, semicolon, private = import_name.partition(";") - name = name.rstrip() - for identifier in name.split("."): - if not identifier.isidentifier(): - raise self._invalid_metadata( - f"{name!r} is invalid for {self.raw_name!r}; " - f"{identifier!r} is not a valid identifier" - ) - elif keyword.iskeyword(identifier): - raise self._invalid_metadata( - f"{name!r} is invalid for {self.raw_name!r}; " - f"{identifier!r} is a keyword" - ) - if semicolon and private.lstrip() != "private": - raise self._invalid_metadata( - f"{import_name!r} is invalid for {self.raw_name!r}; " - "the only valid option is 'private'" - ) - return value - - _process_import_namespaces = _process_import_names - - -class Metadata: - """Representation of distribution metadata. - - Compared to :class:`RawMetadata`, this class provides objects representing - metadata fields instead of only using built-in types. Any invalid metadata - will cause :exc:`InvalidMetadata` to be raised (with a - :py:attr:`~BaseException.__cause__` attribute as appropriate). - - .. versionadded:: 23.2 - - .. versionchanged:: 24.0 - Optional attributes now return None when the field is absent instead of - raising. - """ - - _raw: RawMetadata - - @classmethod - def from_raw(cls, data: RawMetadata, *, validate: bool = True) -> Metadata: - """Create an instance from :class:`RawMetadata`. - - If *validate* is true, all metadata will be validated and all related - exceptions will be gathered and raised as an :class:`ExceptionGroup`; - otherwise, validation happens per attribute when it is accessed. - """ - ins = cls() - ins._raw = data.copy() # Mutations occur due to caching enriched values. - - if validate: - collector = _ErrorCollector() - metadata_version = None - with collector.collect(InvalidMetadata): - metadata_version = ins.metadata_version - metadata_age = _VALID_METADATA_VERSIONS.index(metadata_version) - - # Make sure to check for the fields that are present, the required - # fields (so their absence can be reported). - fields_to_check = frozenset(ins._raw) | _REQUIRED_ATTRS - # Remove fields that have already been checked. - fields_to_check -= {"metadata_version"} - - for key in fields_to_check: - try: - if metadata_version: - # Can't use getattr() as that triggers descriptor protocol which - # will fail due to no value for the instance argument. - try: - field_metadata_version = cls.__dict__[key].added - except KeyError: - exc = InvalidMetadata(key, f"unrecognized field: {key!r}") - collector.error(exc) - continue - field_age = _VALID_METADATA_VERSIONS.index( - field_metadata_version - ) - if field_age > metadata_age: - field = _RAW_TO_EMAIL_MAPPING[key] - exc = InvalidMetadata( - field, - f"{field} introduced in metadata version " - f"{field_metadata_version}, not {metadata_version}", - ) - collector.error(exc) - continue - getattr(ins, key) - except InvalidMetadata as exc: - collector.error(exc) - - collector.finalize("invalid metadata") - - return ins - - @classmethod - def from_email(cls, data: bytes | str, *, validate: bool = True) -> Metadata: - """Parse metadata from email headers. - - If *validate* is true, the metadata will be validated. All exceptions - related to validation will be gathered and raised as an :class:`ExceptionGroup`. - """ - raw, unparsed = parse_email(data) - - if validate: - with _ErrorCollector().on_exit("invalid or unparsed metadata") as collector: - for unparsed_key in unparsed: - if unparsed_key in _EMAIL_TO_RAW_MAPPING: - message = f"{unparsed_key!r} has invalid data" - else: - message = f"unrecognized field: {unparsed_key!r}" - collector.error(InvalidMetadata(unparsed_key, message)) - try: - validated = cls.from_raw(raw, validate=validate) - except ExceptionGroup as exc_group: - # The no-branch pragmas cover arcs only seen by Python 3.9. - for exc in exc_group.exceptions: # pragma: no branch - # A required field reported above as unparsed is absent - # from `raw`, so skip from_raw's duplicate "missing" - # complaint. - if not ( - isinstance(exc, InvalidMetadata) - and exc.field in unparsed - and _EMAIL_TO_RAW_MAPPING.get(exc.field) not in raw - ): - collector.error(exc) - else: - if not collector.errors: # pragma: no branch - return validated - - return cls.from_raw(raw, validate=validate) - - metadata_version: _Validator[_MetadataVersion] = _Validator() - """:external:ref:`core-metadata-metadata-version` - (required; validated to be a valid metadata version)""" - # `name` is not normalized/typed to NormalizedName so as to provide access to - # the original/raw name. - name: _Validator[str] = _Validator() - """:external:ref:`core-metadata-name` - (required; validated using :func:`~packaging.utils.canonicalize_name` and its - *validate* parameter)""" - version: _Validator[Version] = _Validator() - """:external:ref:`core-metadata-version` (required)""" - dynamic: _Validator[list[str] | None] = _Validator( - added="2.2", - ) - """:external:ref:`core-metadata-dynamic` - (validated against core metadata field names and lowercased)""" - platforms: _Validator[list[str] | None] = _Validator() - """:external:ref:`core-metadata-platform`""" - supported_platforms: _Validator[list[str] | None] = _Validator(added="1.1") - """:external:ref:`core-metadata-supported-platform`""" - summary: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-summary` (validated to contain no newlines)""" - description: _Validator[str | None] = _Validator() # TODO 2.1: can be in body - """:external:ref:`core-metadata-description`""" - description_content_type: _Validator[str | None] = _Validator(added="2.1") - """:external:ref:`core-metadata-description-content-type` (validated)""" - keywords: _Validator[list[str] | None] = _Validator() - """:external:ref:`core-metadata-keywords`""" - home_page: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-home-page`""" - download_url: _Validator[str | None] = _Validator(added="1.1") - """:external:ref:`core-metadata-download-url`""" - author: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-author`""" - author_email: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-author-email`""" - maintainer: _Validator[str | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-maintainer`""" - maintainer_email: _Validator[str | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-maintainer-email`""" - license: _Validator[str | None] = _Validator() - """:external:ref:`core-metadata-license`""" - license_expression: _Validator[NormalizedLicenseExpression | None] = _Validator( - added="2.4" - ) - """:external:ref:`core-metadata-license-expression` - - .. versionadded:: 24.2 - """ - license_files: _Validator[list[str] | None] = _Validator(added="2.4") - """:external:ref:`core-metadata-license-file` - - .. versionadded:: 24.2 - """ - classifiers: _Validator[list[str] | None] = _Validator(added="1.1") - """:external:ref:`core-metadata-classifier`""" - requires_dist: _Validator[list[requirements.Requirement] | None] = _Validator( - added="1.2" - ) - """:external:ref:`core-metadata-requires-dist`""" - requires_python: _Validator[specifiers.SpecifierSet | None] = _Validator( - added="1.2" - ) - """:external:ref:`core-metadata-requires-python`""" - # Because `Requires-External` allows for non-PEP 440 version specifiers, we - # don't do any processing on the values. - requires_external: _Validator[list[str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-requires-external`""" - project_urls: _Validator[dict[str, str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-project-url`""" - # PEP 685 lets us raise an error if an extra doesn't pass `Name` validation - # regardless of metadata version. - provides_extra: _Validator[list[utils.NormalizedName] | None] = _Validator( - added="2.1", - ) - """:external:ref:`core-metadata-provides-extra`""" - provides_dist: _Validator[list[str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-provides-dist`""" - obsoletes_dist: _Validator[list[str] | None] = _Validator(added="1.2") - """:external:ref:`core-metadata-obsoletes-dist`""" - import_names: _Validator[list[str] | None] = _Validator(added="2.5") - """:external:ref:`core-metadata-import-name` - - .. versionadded:: 26.0 - """ - import_namespaces: _Validator[list[str] | None] = _Validator(added="2.5") - """:external:ref:`core-metadata-import-namespace` - - .. versionadded:: 26.0 - """ - requires: _Validator[list[str] | None] = _Validator(added="1.1") - """``Requires`` (deprecated)""" - provides: _Validator[list[str] | None] = _Validator(added="1.1") - """``Provides`` (deprecated)""" - obsoletes: _Validator[list[str] | None] = _Validator(added="1.1") - """``Obsoletes`` (deprecated)""" - - def as_rfc822(self) -> RFC822Message: - """ - Return an RFC822 message with the metadata. - - .. versionadded:: 26.0 - """ - message = RFC822Message() - self._write_metadata(message) - return message - - def _write_metadata(self, message: RFC822Message) -> None: - """ - Return an RFC822 message with the metadata. - """ - for name, validator in self.__class__.__dict__.items(): - if isinstance(validator, _Validator) and name != "description": - value = getattr(self, name) - email_name = _RAW_TO_EMAIL_MAPPING[name] - if value is not None: - if email_name == "project-url": - for label, url in value.items(): - message[email_name] = f"{label}, {url}" - elif email_name == "keywords": - message[email_name] = ",".join(value) - elif email_name == "import-name" and value == []: - message[email_name] = "" - elif isinstance(value, list): - for item in value: - message[email_name] = str(item) - else: - message[email_name] = str(value) - - # The description is a special case because it is in the body of the message. - if self.description is not None: - message.set_payload(self.description) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py deleted file mode 100644 index 5e774e4f0bb..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/pylock.py +++ /dev/null @@ -1,943 +0,0 @@ -from __future__ import annotations - -import dataclasses -import logging -import re -from collections.abc import Mapping, Sequence -from dataclasses import dataclass -from datetime import datetime -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Protocol, - TypeVar, - cast, -) -from urllib.parse import unquote, urlparse - -from .markers import ( - Environment, - Marker, - _pep440_python_full_version, - default_environment, -) -from .specifiers import SpecifierSet -from .tags import create_compatible_tags_selector, sys_tags -from .utils import ( - NormalizedName, - is_normalized_name, - parse_sdist_filename, - parse_wheel_filename, -) -from .version import Version - -if TYPE_CHECKING: # pragma: no cover - from collections.abc import Collection, Iterator - from pathlib import Path - - from opentelemetry.agent._vendor.typing_extensions import Self - - from .tags import Tag - -_logger = logging.getLogger(__name__) - -__all__ = [ - "Package", - "PackageArchive", - "PackageDirectory", - "PackageSdist", - "PackageVcs", - "PackageWheel", - "Pylock", - "PylockSelectError", - "PylockUnsupportedVersionError", - "PylockValidationError", - "is_valid_pylock_path", -] - - -def __dir__() -> list[str]: - return __all__ - - -_T = TypeVar("_T") -_T2 = TypeVar("_T2") - - -class _FromMappingProtocol(Protocol): # pragma: no cover - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: ... - - -_FromMappingProtocolT = TypeVar("_FromMappingProtocolT", bound=_FromMappingProtocol) - - -_PYLOCK_FILE_NAME_RE = re.compile(r"^pylock\.([^.]+)\.toml$") - - -def is_valid_pylock_path(path: Path) -> bool: - """Check if the given path is a valid pylock file path.""" - return path.name == "pylock.toml" or bool(_PYLOCK_FILE_NAME_RE.match(path.name)) - - -def _toml_key(key: str) -> str: - return key.replace("_", "-") - - -def _toml_value(key: str, value: Any) -> Any: # noqa: ANN401 - if isinstance(value, (Version, Marker, SpecifierSet)): - return str(value) - if isinstance(value, Sequence) and key == "environments": - return [str(v) for v in value] - return value - - -def _toml_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]: - return { - _toml_key(key): _toml_value(key, value) - for key, value in data - if value is not None - } - - -def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None: - """Get a value from the dictionary and verify it's the expected type.""" - if (value := d.get(key)) is None: - return None - if not isinstance(value, expected_type) or ( - # Special case: bool is a subclass of int, but TOML distinguishes the two - expected_type is int and isinstance(value, bool) - ): - raise PylockValidationError( - f"Unexpected type {type(value).__name__} " - f"(expected {expected_type.__name__})", - context=key, - ) - return value - - -def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T: - """Get a required value from the dictionary and verify it's the expected type.""" - if (value := _get(d, expected_type, key)) is None: - raise _PylockRequiredKeyError(key) - return value - - -def _get_sequence( - d: Mapping[str, Any], expected_item_type: type[_T], key: str -) -> Sequence[_T] | None: - """Get a list value from the dictionary and verify it's the expected items type.""" - if (value := _get(d, Sequence, key)) is None: # type: ignore[type-abstract] - return None - if isinstance(value, (str, bytes)): - # special case: str and bytes are Sequences, but we want to reject it - raise PylockValidationError( - f"Unexpected type {type(value).__name__} (expected Sequence)", - context=key, - ) - for i, item in enumerate(value): - if not isinstance(item, expected_item_type): - raise PylockValidationError( - f"Unexpected type {type(item).__name__} " - f"(expected {expected_item_type.__name__})", - context=f"{key}[{i}]", - ) - return value - - -def _get_as( - d: Mapping[str, Any], - expected_type: type[_T], - target_type: Callable[[_T], _T2], - key: str, -) -> _T2 | None: - """Get a value from the dictionary, verify it's the expected type, - and convert to the target type. - - This assumes the target_type constructor accepts the value. - """ - if (value := _get(d, expected_type, key)) is None: - return None - try: - return target_type(value) - except Exception as e: - raise PylockValidationError(e, context=key) from e - - -def _get_required_as( - d: Mapping[str, Any], - expected_type: type[_T], - target_type: Callable[[_T], _T2], - key: str, -) -> _T2: - """Get a required value from the dict, verify it's the expected type, - and convert to the target type.""" - if (value := _get_as(d, expected_type, target_type, key)) is None: - raise _PylockRequiredKeyError(key) - return value - - -def _get_sequence_as( - d: Mapping[str, Any], - expected_item_type: type[_T], - target_item_type: Callable[[_T], _T2], - key: str, -) -> list[_T2] | None: - """Get list value from dictionary and verify expected items type.""" - if (value := _get_sequence(d, expected_item_type, key)) is None: - return None - result = [] - try: - for item in value: - typed_item = target_item_type(item) - result.append(typed_item) - except Exception as e: - raise PylockValidationError(e, context=f"{key}[{len(result)}]") from e - return result - - -def _get_object( - d: Mapping[str, Any], target_type: type[_FromMappingProtocolT], key: str -) -> _FromMappingProtocolT | None: - """Get a dictionary value from the dictionary and convert it to a dataclass.""" - if (value := _get(d, Mapping, key)) is None: # type: ignore[type-abstract] - return None - try: - return target_type._from_dict(value) - except Exception as e: - raise PylockValidationError(e, context=key) from e - - -def _get_sequence_of_objects( - d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str -) -> list[_FromMappingProtocolT] | None: - """Get a list value from the dictionary and convert its items to a dataclass.""" - if (value := _get_sequence(d, Mapping, key)) is None: # type: ignore[type-abstract] - return None - result: list[_FromMappingProtocolT] = [] - try: - for item in value: - typed_item = target_item_type._from_dict(item) - result.append(typed_item) - except Exception as e: - raise PylockValidationError(e, context=f"{key}[{len(result)}]") from e - return result - - -def _get_required_sequence_of_objects( - d: Mapping[str, Any], target_item_type: type[_FromMappingProtocolT], key: str -) -> Sequence[_FromMappingProtocolT]: - """Get a required list value from the dictionary and convert its items to a - dataclass.""" - if (result := _get_sequence_of_objects(d, target_item_type, key)) is None: - raise _PylockRequiredKeyError(key) - return result - - -def _validate_normalized_name(name: str) -> NormalizedName: - """Validate that a string is a NormalizedName.""" - if not is_normalized_name(name): - raise PylockValidationError(f"Name {name!r} is not normalized") - return NormalizedName(name) - - -def _validate_path_url(path: str | None, url: str | None) -> None: - if not path and not url: - raise PylockValidationError("path or url must be provided") - - -def _path_name(path: str | None) -> str | None: - if not path: - return None - # If the path is relative it MAY use POSIX-style path separators explicitly - # for portability - if "/" in path: - return path.rsplit("/", 1)[-1] - elif "\\" in path: - return path.rsplit("\\", 1)[-1] - else: - return path - - -def _url_name(url: str | None) -> str | None: - if not url: - return None - url_path = urlparse(url).path - # The last path component is percent-encoded, so decode it to the file name - return unquote(url_path.rsplit("/", 1)[-1]) - - -def _validate_hashes(hashes: Mapping[str, Any]) -> Mapping[str, Any]: - if not hashes: - raise PylockValidationError("At least one hash must be provided") - if not all(isinstance(hash_val, str) for hash_val in hashes.values()): - raise PylockValidationError("Hash values must be strings") - return hashes - - -class PylockValidationError(Exception): - """Raised when when input data is not spec-compliant.""" - - context: str | None = None - message: str - - def __init__( - self, - cause: str | Exception, - *, - context: str | None = None, - ) -> None: - if isinstance(cause, PylockValidationError): - if cause.context: - self.context = ( - f"{context}.{cause.context}" if context else cause.context - ) - else: - self.context = context - self.message = cause.message - else: - self.context = context - self.message = str(cause) - - def __str__(self) -> str: - if self.context: - return f"{self.message} in {self.context!r}" - return self.message - - -class _PylockRequiredKeyError(PylockValidationError): - def __init__(self, key: str) -> None: - super().__init__("Missing required value", context=key) - - -class PylockUnsupportedVersionError(PylockValidationError): - """Raised when encountering an unsupported `lock_version`.""" - - -class PylockSelectError(Exception): - """Base exception for errors raised by :meth:`Pylock.select`. - - .. versionadded:: 26.1 - """ - - -@dataclass(frozen=True, init=False) -class PackageVcs: - type: str - url: str | None = None - path: str | None = None - requested_revision: str | None = None - commit_id: str # type: ignore[misc] - subdirectory: str | None = None - - def __init__( - self, - *, - type: str, - url: str | None = None, - path: str | None = None, - requested_revision: str | None = None, - commit_id: str, - subdirectory: str | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "type", type) - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "requested_revision", requested_revision) - object.__setattr__(self, "commit_id", commit_id) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_vcs = cls( - type=_get_required(d, str, "type"), - url=_get(d, str, "url"), - path=_get(d, str, "path"), - requested_revision=_get(d, str, "requested-revision"), - commit_id=_get_required(d, str, "commit-id"), - subdirectory=_get(d, str, "subdirectory"), - ) - _validate_path_url(package_vcs.path, package_vcs.url) - return package_vcs - - -@dataclass(frozen=True, init=False) -class PackageDirectory: - path: str - editable: bool | None = None - subdirectory: str | None = None - - def __init__( - self, - *, - path: str, - editable: bool | None = None, - subdirectory: str | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "path", path) - object.__setattr__(self, "editable", editable) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - return cls( - path=_get_required(d, str, "path"), - editable=_get(d, bool, "editable"), - subdirectory=_get(d, str, "subdirectory"), - ) - - -@dataclass(frozen=True, init=False) -class PackageArchive: - url: str | None = None - path: str | None = None - size: int | None = None - upload_time: datetime | None = None - hashes: Mapping[str, str] # type: ignore[misc] - subdirectory: str | None = None - - def __init__( - self, - *, - url: str | None = None, - path: str | None = None, - size: int | None = None, - upload_time: datetime | None = None, - hashes: Mapping[str, str], - subdirectory: str | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "size", size) - object.__setattr__(self, "upload_time", upload_time) - object.__setattr__(self, "hashes", hashes) - object.__setattr__(self, "subdirectory", subdirectory) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_archive = cls( - url=_get(d, str, "url"), - path=_get(d, str, "path"), - size=_get(d, int, "size"), - upload_time=_get(d, datetime, "upload-time"), - hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] - subdirectory=_get(d, str, "subdirectory"), - ) - _validate_path_url(package_archive.path, package_archive.url) - return package_archive - - -@dataclass(frozen=True, init=False) -class PackageSdist: - name: str | None = None - upload_time: datetime | None = None - url: str | None = None - path: str | None = None - size: int | None = None - hashes: Mapping[str, str] # type: ignore[misc] - - def __init__( - self, - *, - name: str | None = None, - upload_time: datetime | None = None, - url: str | None = None, - path: str | None = None, - size: int | None = None, - hashes: Mapping[str, str], - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "name", name) - object.__setattr__(self, "upload_time", upload_time) - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "size", size) - object.__setattr__(self, "hashes", hashes) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_sdist = cls( - name=_get(d, str, "name"), - upload_time=_get(d, datetime, "upload-time"), - url=_get(d, str, "url"), - path=_get(d, str, "path"), - size=_get(d, int, "size"), - hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] - ) - _validate_path_url(package_sdist.path, package_sdist.url) - return package_sdist - - @property - def filename(self) -> str: - """Get the filename of the sdist. - - .. versionadded:: 26.1 - """ - filename = self.name or _path_name(self.path) or _url_name(self.url) - if not filename: - raise PylockValidationError("Cannot determine sdist filename") - return filename - - -@dataclass(frozen=True, init=False) -class PackageWheel: - name: str | None = None - upload_time: datetime | None = None - url: str | None = None - path: str | None = None - size: int | None = None - hashes: Mapping[str, str] # type: ignore[misc] - - def __init__( - self, - *, - name: str | None = None, - upload_time: datetime | None = None, - url: str | None = None, - path: str | None = None, - size: int | None = None, - hashes: Mapping[str, str], - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "name", name) - object.__setattr__(self, "upload_time", upload_time) - object.__setattr__(self, "url", url) - object.__setattr__(self, "path", path) - object.__setattr__(self, "size", size) - object.__setattr__(self, "hashes", hashes) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package_wheel = cls( - name=_get(d, str, "name"), - upload_time=_get(d, datetime, "upload-time"), - url=_get(d, str, "url"), - path=_get(d, str, "path"), - size=_get(d, int, "size"), - hashes=_get_required_as(d, Mapping, _validate_hashes, "hashes"), # type: ignore[type-abstract] - ) - _validate_path_url(package_wheel.path, package_wheel.url) - return package_wheel - - @property - def filename(self) -> str: - """Get the filename of the wheel.""" - filename = self.name or _path_name(self.path) or _url_name(self.url) - if not filename: - raise PylockValidationError("Cannot determine wheel filename") - return filename - - -@dataclass(frozen=True, init=False) -class Package: - name: NormalizedName - version: Version | None = None - marker: Marker | None = None - requires_python: SpecifierSet | None = None - dependencies: Sequence[Mapping[str, Any]] | None = None - vcs: PackageVcs | None = None - directory: PackageDirectory | None = None - archive: PackageArchive | None = None - index: str | None = None - sdist: PackageSdist | None = None - wheels: Sequence[PackageWheel] | None = None - attestation_identities: Sequence[Mapping[str, Any]] | None = None - tool: Mapping[str, Any] | None = None - - def __init__( - self, - *, - name: NormalizedName, - version: Version | None = None, - marker: Marker | None = None, - requires_python: SpecifierSet | None = None, - dependencies: Sequence[Mapping[str, Any]] | None = None, - vcs: PackageVcs | None = None, - directory: PackageDirectory | None = None, - archive: PackageArchive | None = None, - index: str | None = None, - sdist: PackageSdist | None = None, - wheels: Sequence[PackageWheel] | None = None, - attestation_identities: Sequence[Mapping[str, Any]] | None = None, - tool: Mapping[str, Any] | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "name", name) - object.__setattr__(self, "version", version) - object.__setattr__(self, "marker", marker) - object.__setattr__(self, "requires_python", requires_python) - object.__setattr__(self, "dependencies", dependencies) - object.__setattr__(self, "vcs", vcs) - object.__setattr__(self, "directory", directory) - object.__setattr__(self, "archive", archive) - object.__setattr__(self, "index", index) - object.__setattr__(self, "sdist", sdist) - object.__setattr__(self, "wheels", wheels) - object.__setattr__(self, "attestation_identities", attestation_identities) - object.__setattr__(self, "tool", tool) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - package = cls( - name=_get_required_as(d, str, _validate_normalized_name, "name"), - version=_get_as(d, str, Version, "version"), - requires_python=_get_as(d, str, SpecifierSet, "requires-python"), - dependencies=_get_sequence(d, Mapping, "dependencies"), # type: ignore[type-abstract] - marker=_get_as(d, str, Marker, "marker"), - vcs=_get_object(d, PackageVcs, "vcs"), - directory=_get_object(d, PackageDirectory, "directory"), - archive=_get_object(d, PackageArchive, "archive"), - index=_get(d, str, "index"), - sdist=_get_object(d, PackageSdist, "sdist"), - wheels=_get_sequence_of_objects(d, PackageWheel, "wheels"), - attestation_identities=_get_sequence(d, Mapping, "attestation-identities"), # type: ignore[type-abstract] - tool=_get(d, Mapping, "tool"), # type: ignore[type-abstract] - ) - distributions = bool(package.sdist) + len(package.wheels or []) - direct_urls = ( - bool(package.vcs) + bool(package.directory) + bool(package.archive) - ) - if distributions > 0 and direct_urls > 0: - raise PylockValidationError( - "None of vcs, directory, archive must be set if sdist or wheels are set" - ) - if distributions == 0 and direct_urls != 1: - raise PylockValidationError( - "Exactly one of vcs, directory, archive must be set " - "if sdist and wheels are not set" - ) - for i, wheel in enumerate(package.wheels or []): - try: - (name, version, _, _) = parse_wheel_filename(wheel.filename) - except Exception as e: - raise PylockValidationError( - f"Invalid wheel filename {wheel.filename!r}", - context=f"wheels[{i}]", - ) from e - if name != package.name: - raise PylockValidationError( - f"Name in {wheel.filename!r} is not consistent with " - f"package name {package.name!r}", - context=f"wheels[{i}]", - ) - if package.version and version != package.version: - raise PylockValidationError( - f"Version in {wheel.filename!r} is not consistent with " - f"package version {str(package.version)!r}", - context=f"wheels[{i}]", - ) - if package.sdist: - try: - name, version = parse_sdist_filename(package.sdist.filename) - except Exception as e: - raise PylockValidationError( - f"Invalid sdist filename {package.sdist.filename!r}", - context="sdist", - ) from e - if name != package.name: - raise PylockValidationError( - f"Name in {package.sdist.filename!r} is not consistent with " - f"package name {package.name!r}", - context="sdist", - ) - if package.version and version != package.version: - raise PylockValidationError( - f"Version in {package.sdist.filename!r} is not consistent with " - f"package version {str(package.version)!r}", - context="sdist", - ) - try: - for i, attestation_identity in enumerate( # noqa: B007 - package.attestation_identities or [] - ): - _get_required(attestation_identity, str, "kind") - except Exception as e: - raise PylockValidationError( - e, context=f"attestation-identities[{i}]" - ) from e - return package - - @property - def is_direct(self) -> bool: - return not (self.sdist or self.wheels) - - -@dataclass(frozen=True, init=False) -class Pylock: - """A class representing a pylock file.""" - - lock_version: Version - environments: Sequence[Marker] | None = None - requires_python: SpecifierSet | None = None - extras: Sequence[NormalizedName] | None = None - dependency_groups: Sequence[str] | None = None - default_groups: Sequence[str] | None = None - created_by: str # type: ignore[misc] - packages: Sequence[Package] # type: ignore[misc] - tool: Mapping[str, Any] | None = None - - def __init__( - self, - *, - lock_version: Version, - environments: Sequence[Marker] | None = None, - requires_python: SpecifierSet | None = None, - extras: Sequence[NormalizedName] | None = None, - dependency_groups: Sequence[str] | None = None, - default_groups: Sequence[str] | None = None, - created_by: str, - packages: Sequence[Package], - tool: Mapping[str, Any] | None = None, - ) -> None: - # In Python 3.10+ make dataclass kw_only=True and remove __init__ - object.__setattr__(self, "lock_version", lock_version) - object.__setattr__(self, "environments", environments) - object.__setattr__(self, "requires_python", requires_python) - object.__setattr__(self, "extras", extras) - object.__setattr__(self, "dependency_groups", dependency_groups) - object.__setattr__(self, "default_groups", default_groups) - object.__setattr__(self, "created_by", created_by) - object.__setattr__(self, "packages", packages) - object.__setattr__(self, "tool", tool) - - @classmethod - def _from_dict(cls, d: Mapping[str, Any]) -> Self: - pylock = cls( - lock_version=_get_required_as(d, str, Version, "lock-version"), - environments=_get_sequence_as(d, str, Marker, "environments"), - extras=_get_sequence_as(d, str, _validate_normalized_name, "extras"), - dependency_groups=_get_sequence(d, str, "dependency-groups"), - default_groups=_get_sequence(d, str, "default-groups"), - created_by=_get_required(d, str, "created-by"), - requires_python=_get_as(d, str, SpecifierSet, "requires-python"), - packages=_get_required_sequence_of_objects(d, Package, "packages"), - tool=_get(d, Mapping, "tool"), # type: ignore[type-abstract] - ) - if not Version("1") <= pylock.lock_version < Version("2"): - raise PylockUnsupportedVersionError( - f"pylock version {pylock.lock_version} is not supported" - ) - if pylock.lock_version > Version("1.0"): - _logger.warning( - "pylock minor version %s is not supported", pylock.lock_version - ) - return pylock - - @classmethod - def from_dict(cls, d: Mapping[str, Any], /) -> Self: - """Create and validate a Pylock instance from a TOML dictionary. - - Raises :class:`PylockValidationError` if the input data is not - spec-compliant. - """ - return cls._from_dict(d) - - def to_dict(self) -> Mapping[str, Any]: - """Convert the Pylock instance to a TOML dictionary.""" - return dataclasses.asdict(self, dict_factory=_toml_dict_factory) - - def validate(self) -> None: - """Validate the Pylock instance against the specification. - - Raises :class:`PylockValidationError` otherwise.""" - self.from_dict(self.to_dict()) - - def select( - self, - *, - environment: Environment | None = None, - tags: Sequence[Tag] | None = None, - extras: Collection[str] | None = None, - dependency_groups: Collection[str] | None = None, - prefer_sdist_predicate: Callable[[NormalizedName], bool] | None = None, - ) -> Iterator[ - tuple[ - Package, - PackageVcs - | PackageDirectory - | PackageArchive - | PackageWheel - | PackageSdist, - ] - ]: - """Select what to install from the lock file. - - The *environment* and *tags* parameters represent the environment being - selected for. If unspecified, ``packaging.markers.default_environment()`` and - ``packaging.tags.sys_tags()`` are used. - - The *extras* parameter represents the extras to install. - - The *dependency_groups* parameter represents the groups to install. If - unspecified, the default groups are used. - - The *prefer_sdist_predicate* parameter is called for packages with a source - distribution. If it returns ``True``, the source distribution is selected - before attempting wheel compatibility. If no source distribution is - available, wheel selection proceeds as usual without calling the predicate. - - This method must be used on valid Pylock instances (i.e. one obtained - from :meth:`Pylock.from_dict` or if constructed manually, after calling - :meth:`Pylock.validate`). - - .. versionadded:: 26.1 - - .. versionchanged:: 26.3 - Added the *prefer_sdist_predicate* parameter. - """ - compatible_tags_selector = create_compatible_tags_selector( - tags if tags is not None else sys_tags() - ) - - # #. Gather the extras and dependency groups to install and set ``extras`` and - # ``dependency_groups`` for marker evaluation, respectively. - # - # #. ``extras`` SHOULD be set to the empty set by default. - # #. ``dependency_groups`` SHOULD be the set created from - # :ref:`pylock-default-groups` by default. - env = cast( - "dict[str, str | frozenset[str]]", - dict( - environment or {}, # Marker.evaluate will fill-up - extras=frozenset(extras or []), - dependency_groups=frozenset( - (self.default_groups or []) - if dependency_groups is None # to allow selecting no group - else dependency_groups - ), - ), - ) - env_python_full_version = _pep440_python_full_version( - environment["python_full_version"] - if environment - else default_environment()["python_full_version"] - ) - - # #. Check if the metadata version specified by :ref:`pylock-lock-version` is - # supported; an error or warning MUST be raised as appropriate. - # Covered by lock.validate() which is a precondition for this method. - - # #. If :ref:`pylock-requires-python` is specified, check that the environment - # being installed for meets the requirement; an error MUST be raised if it is - # not met. - if self.requires_python and not self.requires_python.contains( - env_python_full_version, - ): - raise PylockSelectError( - f"python_full_version {env_python_full_version!r} " - f"in provided environment does not satisfy the Python version " - f"requirement {str(self.requires_python)!r}" - ) - - # #. If :ref:`pylock-environments` is specified, check that at least one of the - # environment marker expressions is satisfied; an error MUST be raised if no - # expression is satisfied. - if self.environments: - for env_marker in self.environments: - if env_marker.evaluate( - cast("dict[str, str]", environment or {}), context="requirement" - ): - break - else: - raise PylockSelectError( - "Provided environment does not satisfy any of the " - "environments specified in the lock file" - ) - - # #. For each package listed in :ref:`pylock-packages`: - selected_packages_by_name: dict[str, tuple[int, Package]] = {} - for package_index, package in enumerate(self.packages): - # #. If :ref:`pylock-packages-marker` is specified, check if it is - # satisfied;if it isn't, skip to the next package. - if package.marker and not package.marker.evaluate(env, context="lock_file"): - continue - - # #. If :ref:`pylock-packages-requires-python` is specified, check if it is - # satisfied; an error MUST be raised if it isn't. - if package.requires_python and not package.requires_python.contains( - env_python_full_version, - ): - raise PylockSelectError( - f"python_full_version {env_python_full_version!r} " - f"in provided environment does not satisfy the Python version " - f"requirement {str(package.requires_python)!r} for package " - f"{package.name!r} at packages[{package_index}]" - ) - - # #. Check that no other conflicting instance of the package has been slated - # to be installed; an error about the ambiguity MUST be raised otherwise. - if package.name in selected_packages_by_name: - raise PylockSelectError( - f"Multiple packages with the name {package.name!r} are " - f"selected at packages[{package_index}] and " - f"packages[{selected_packages_by_name[package.name][0]}]" - ) - - # #. Check that the source of the package is specified appropriately (i.e. - # there are no conflicting sources in the package entry); - # an error MUST be raised if any issues are found. - # Covered by lock.validate() which is a precondition for this method. - - # #. Add the package to the set of packages to install. - selected_packages_by_name[package.name] = (package_index, package) - - # #. For each package to be installed: - for package_index, package in selected_packages_by_name.values(): - # - If :ref:`pylock-packages-vcs` is set: - if package.vcs is not None: - yield package, package.vcs - - # - Else if :ref:`pylock-packages-directory` is set: - elif package.directory is not None: - yield package, package.directory - - # - Else if :ref:`pylock-packages-archive` is set: - elif package.archive is not None: - yield package, package.archive - - # - Else if source preference selects an available - # :ref:`pylock-packages-sdist`: - elif ( - package.sdist is not None - and prefer_sdist_predicate is not None - and prefer_sdist_predicate(package.name) - ): - yield package, package.sdist - - # - Else if there are entries for :ref:`pylock-packages-wheels`: - elif package.wheels: - # #. Look for the appropriate wheel file based on - # :ref:`pylock-packages-wheels-name`; if one is not found then move - # on to :ref:`pylock-packages-sdist` or an error MUST be raised about - # a lack of source for the project. - best_wheel = next( - compatible_tags_selector( - (wheel, parse_wheel_filename(wheel.filename)[-1]) - for wheel in package.wheels - ), - None, - ) - if best_wheel: - yield package, best_wheel - elif package.sdist is not None: - yield package, package.sdist - else: - raise PylockSelectError( - f"No wheel found matching the provided tags " - f"for package {package.name!r} " - f"at packages[{package_index}], " - f"and no sdist available as a fallback" - ) - - # - Else if no :ref:`pylock-packages-wheels` file is found or - # :ref:`pylock-packages-sdist` is solely set: - elif package.sdist is not None: - yield package, package.sdist - - else: - # Covered by lock.validate() which is a precondition for this method. - raise NotImplementedError # pragma: no cover diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py deleted file mode 100644 index 8144a65c4d2..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/ranges.py +++ /dev/null @@ -1,2067 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -"""Public :class:`VersionRange` API. - -A set-algebra view of the versions accepted by a -:class:`~packaging.specifiers.SpecifierSet`. Ranges support intersection, -union, complement, and difference; membership and filtering match the -originating specifier set; and conversion back to a -:class:`~packaging.specifiers.SpecifierSet` is available where a PEP 440 form -exists. - -.. testsetup:: - - from packaging.ranges import VersionRange - from packaging.specifiers import SpecifierSet - from packaging.version import Version -""" - -from __future__ import annotations - -import enum -import typing -from typing import ( - TYPE_CHECKING, - Any, - TypeVar, - Union, -) - -from ._ranges import ( - FULL_RANGE, - MIN_VERSION, - NEG_INF, - POS_INF, - BoundaryKind, - BoundaryVersion, - LowerBound, - UpperBound, - coerce_version, - filter_by_ranges, - intersect_ranges, - least_version_above, - matches_bounds_only, - range_is_empty, - ranges_are_prerelease_only, - trim_release, -) -from .version import Version - -if TYPE_CHECKING: - from collections.abc import Callable, Iterable, Iterator, Sequence - - from ._ranges import Interval - from .specifiers import SpecifierSet - - -__all__ = ["VersionRange"] - -T = TypeVar("T") -UnparsedVersion = Union[Version, str] -UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion) - -#: The most ``!=`` exclusion fragments (``!=V`` points or ``!=P.*`` prefixes) -#: that :meth:`VersionRange.to_specifier_set` will materialize to spell a -#: single gap or run. Every site that expands a version-number-driven chain -#: charges it against this cap, and chains that spell one gap together share -#: it (see :func:`_decompose_dev0_gap` and :func:`_encode_gap`), -#: so no gap ever materializes more than this many exclusions. Past the cap -#: the recovery returns ``None`` rather than emit the unbounded chain a range -#: such as ``==5.* | ==1000000.*`` would otherwise drive. -_MAX_EXCLUSION_RUN = 128 - - -class _SetOp(enum.Enum): - """The binary set operation ``_combine_literals`` resolves over ``===`` literals.""" - - INTERSECTION = enum.auto() - UNION = enum.auto() - DIFFERENCE = enum.auto() - - -def __dir__() -> list[str]: - return __all__ - - -# Range algebra: intersection and the empty-interval test live in the engine -# (``intersect_ranges`` / ``range_is_empty``); union and complement are only -# needed here, so they live in this module. - - -def _union_ranges( - left: Sequence[Interval], - right: Sequence[Interval], -) -> list[Interval]: - """Union two sorted, non-overlapping interval lists. - - A linear merge over the two pre-sorted inputs followed by a single - coalescing pass: adjacent or overlapping intervals collapse so the result - is itself sorted and non-overlapping. - """ - if not left: - return list(right) - if not right: - return list(left) - - merged_input: list[Interval] = [] - left_index = right_index = 0 - while left_index < len(left) and right_index < len(right): - if left[left_index][0] <= right[right_index][0]: - merged_input.append(left[left_index]) - left_index += 1 - else: - merged_input.append(right[right_index]) - right_index += 1 - merged_input.extend(left[left_index:]) - merged_input.extend(right[right_index:]) - - merged: list[Interval] = [merged_input[0]] - for lower, upper in merged_input[1:]: - prev_lower, prev_upper = merged[-1] - - if ( - prev_upper.version is None - or lower.version is None - or prev_upper.version > lower.version - ): - overlaps = True - elif prev_upper.version == lower.version: - overlaps = prev_upper.inclusive or lower.inclusive - else: - # An ordering gap may still hold no version when the two bounds - # straddle a synthetic boundary; merge across an empty gap to - # stay canonical. - gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive) - gap_upper = UpperBound(lower.version, not lower.inclusive) - overlaps = range_is_empty(gap_lower, gap_upper) - - if overlaps: - merged[-1] = (prev_lower, max(prev_upper, upper)) - else: - merged.append((lower, upper)) - - return merged - - -def _complement_ranges(ranges: Sequence[Interval]) -> list[Interval]: - """Complement a sorted, non-overlapping interval list. - - Yields the gaps between intervals plus a leading gap before the first and - a trailing gap after the last. Bound inclusivity flips so that - complement-of-complement round-trips back to the input. - """ - if not ranges: - return list(FULL_RANGE) - - result: list[Interval] = [] - prev_upper: UpperBound | None = None - - for lower, upper in ranges: - if prev_upper is None: - # Leading gap below the first interval. Every range reaching here is - # floor-canonical: ``_canonical_floor`` has already folded an - # inclusive lower at or below ``0.dev0`` into ``-inf``. So a finite - # first lower always leaves a non-empty gap down to ``-inf``, while a - # ``-inf`` lower leaves no leading gap at all. - if lower.version is not None: - gap_upper = UpperBound(lower.version, not lower.inclusive) - result.append((NEG_INF, gap_upper)) - else: - gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive) - gap_upper = UpperBound(lower.version, not lower.inclusive) - # Input intervals are canonical (sorted, disjoint, non-touching), - # so the gap between two of them always holds at least one version. - result.append((gap_lower, gap_upper)) - prev_upper = upper - - # The empty-input early return guarantees the loop ran. - assert prev_upper is not None - if prev_upper.version is not None: - gap_lower = LowerBound(prev_upper.version, not prev_upper.inclusive) - result.append((gap_lower, POS_INF)) - - return result - - -def _canonical_floor(bounds: tuple[Interval, ...]) -> tuple[Interval, ...]: - """Collapse the PEP 440 floor in a sorted interval list. - - Only the first interval can touch ``0.dev0`` (the minimum version). An - inclusive lower at or below it admits everything below, the same as - ``-inf``, so ``>=0.dev0`` becomes the one canonical full range. An - exclusive upper at or below it leaves the interval empty, so it is dropped. - """ - if not bounds: - return bounds - - lower, upper = bounds[0] - if range_is_empty(NEG_INF, upper): - return bounds[1:] - - if ( - lower.inclusive - and isinstance(lower.version, Version) - and lower.version <= MIN_VERSION - ): - return ((NEG_INF, upper), *bounds[1:]) - - return bounds - - -def _predecessor_boundary(version: Version) -> BoundaryVersion | None: - """The boundary whose least successor is *version*, or ``None``. - - Inverse of :func:`~packaging._ranges.least_version_above`. A plain version - that is exactly such a successor (``1.0a2.dev0`` sits just above - ``AFTER_POSTS(1.0a1)``) folds back to that boundary, so ``>=1.0a2.dev0`` and - ``>1.0a1`` share one form. The proposed boundary is confirmed by - round-tripping through ``least_version_above``. - """ - # Only a least successor carries a dev segment, so nothing else can fold. - if version.dev is None: - return None - - candidate: BoundaryVersion | None = None - if version.pre is not None and version.dev == 0 and version.post is None: - # 1.0a2.dev0 -> AFTER_POSTS(1.0a1) - kind, number = version.pre - if number >= 1: - candidate = BoundaryVersion( - version.__replace__(pre=(kind, number - 1), dev=None), - BoundaryKind.AFTER_POSTS, - ) - elif version.dev >= 1: - # 1.0.dev3 -> AFTER_LOCALS(1.0.dev2) - candidate = BoundaryVersion( - version.__replace__(dev=version.dev - 1), BoundaryKind.AFTER_LOCALS - ) - elif version.dev == 0 and version.post is not None: - # 1.0.post1.dev0 -> AFTER_LOCALS(1.0.post0); 1.0.post0.dev0 -> AFTER_LOCALS(1.0) - base = ( - version.__replace__(post=None, dev=None) - if version.post == 0 - else version.__replace__(post=version.post - 1, dev=None) - ) - candidate = BoundaryVersion(base, BoundaryKind.AFTER_LOCALS) - - if candidate is not None and least_version_above(candidate) == version: - return candidate - return None - - -def _canonicalize(bounds: tuple[Interval, ...]) -> tuple[Interval, ...]: - """Fold least-successor bounds to their boundary form. - - ``>=1.0a2.dev0`` and ``>1.0a1`` denote the same set, so both must reduce to - one representation for ``==`` and ``hash`` to agree. An inclusive lower or - exclusive upper sitting on a boundary's least successor becomes that - boundary; the engine's emptiness check has already dropped the synthetic - gaps such intervals would otherwise leave. - """ - result: list[Interval] = [] - for lower, upper in bounds: - new_lower, new_upper = lower, upper - - if isinstance(lower.version, Version) and lower.inclusive: - boundary = _predecessor_boundary(lower.version) - if boundary is not None: - new_lower = LowerBound(boundary, inclusive=False) - - if isinstance(upper.version, Version) and not upper.inclusive: - boundary = _predecessor_boundary(upper.version) - if boundary is not None: - new_upper = UpperBound(boundary, inclusive=True) - - result.append((new_lower, new_upper)) - return tuple(result) - - -def _struct_admits( - bounds: tuple[Interval, ...], admit_arbitrary: bool, literal: str -) -> bool: - """True when the bounds (plus arbitrary admission) admit ``literal``. - - Skips the explicit admit/reject sets, which the caller layers on top. A - non-version string matches via ``admit_arbitrary`` only on full bounds; - on narrower bounds the flag is metadata only. - """ - parsed = coerce_version(literal) - if parsed is None: - return admit_arbitrary and bounds == FULL_RANGE - - return matches_bounds_only(bounds, parsed) - - -# Repr helpers: - - -def _bound_version_str(value: BoundaryVersion | Version) -> str: - """Printout for a bound's inner value, kind-tagged for boundaries.""" - if isinstance(value, BoundaryVersion): - return f"{value.version}[{value.kind.name}]" - return str(value) - - -def _format_lower(bound: LowerBound) -> str: - if bound.version is None: - return "(-inf" - bracket = "[" if bound.inclusive else "(" - return f"{bracket}{_bound_version_str(bound.version)}" - - -def _format_upper(bound: UpperBound) -> str: - if bound.version is None: - return "+inf)" - bracket = "]" if bound.inclusive else ")" - return f"{_bound_version_str(bound.version)}{bracket}" - - -def _format_intervals(intervals: Sequence[Interval]) -> str: - """Render a sorted interval list as ``lower, upper | lower, upper``.""" - return " | ".join( - f"{_format_lower(lower)}, {_format_upper(upper)}" for lower, upper in intervals - ) - - -# ``to_specifier_set`` recovery: encode a range's interval list back into -# specifier fragments. Each helper returns ``None`` when its shape has no -# PEP 440 form. The ``keep_dev0`` argument threaded through is a spelling -# mode, not a pre-release policy: false emits a prerelease-free form (no -# synthetic ``.dev0``, so the recovered range has an empty opt-in region), -# true keeps the ``.dev0`` markers (so the range opts its bounds in). -# ``to_specifier_set`` encodes in both modes and keeps whichever round-trips. -# -# Bound and interval encoding: turn one interval's bounds into fragments. - - -def _is_dev0_version(version: Version) -> bool: - """True when version is exactly ``X[.Y]*.dev0`` (the shape `` list[str] | None: - """A prerelease-free spelling for an inclusive ``[version`` lower, or ``None``. - - Several ``[V`` lowers come from an operator whose own spelling carries no - synthetic ``.dev0``. Recovering that spelling gives the range an empty opt-in - region, so it is offered in the prerelease-free spelling mode (see - :meth:`VersionRange.to_specifier_set`). - """ - if version.dev != 0 or version.pre is not None or version.local is not None: - return None - - # ``[B.post(k).dev0`` is the lower ``>B.post(k-1)`` builds (k >= 1). - if version.post is not None: - if version.post < 1: - return None - return [f">{version.__replace__(post=version.post - 1, dev=None)}"] - - # ``[F.dev0`` is family F's base. The prefix P just below F has - # ``==P.* == [P.dev0, F.dev0)``, so ``>=P,!=P.*`` lands exactly on ``[F.dev0``. - family = trim_release(version.release) - last = family[-1] - if last < 1: - return None - - below_release = (*family[:-1], last - 1) - below = Version.from_parts(epoch=version.epoch, release=below_release) - - # At the epoch-0 floor ``==P.*`` already reaches ``0.dev0``, so the ``>=P`` - # half is redundant: ``[1.dev0, +inf)`` is plain ``!=0.*``. - if version.epoch == 0 and not any(below_release): - return [f"!={below}.*"] - - return [f">={below}", f"!={below}.*"] - - -def _epoch_floor_lower( - lower: LowerBound, upper: UpperBound -) -> tuple[Version, int, bool] | None: - """The ``E!0`` family of a lower sitting on an epoch>0 zero-family floor. - - An epoch>0 zero-family base such as ``1!0.dev0`` has no ``>=P,!=P.*`` spelling - since no version sorts below ``E!0`` within the epoch. While the interval - stays within ``==E!0.*`` it is that wildcard, trimmed by the upper and with a - leading ``.dev`` run excluded: an ``AFTER_LOCALS(E!0.dev(k))`` lower drops - ``E!0.dev0..E!0.dev(k)``, a plain inclusive ``E!0.dev0`` lower drops none. - Returns the ``E!0`` family, how many leading ``.dev`` releases to exclude, and - whether the upper sits at the family cap (so ``==E!0.*`` needs no upper), else - ``None``. - """ - version = lower.version - if isinstance(version, BoundaryVersion): - if version.kind != BoundaryKind.AFTER_LOCALS: - return None - version = version.version - if version.dev is None: - return None - excluded_devs = version.dev + 1 - elif isinstance(version, Version) and lower.inclusive: - # A plain inclusive lower only reaches the floor as ``>=E!0.dev0``; - # higher ``.dev`` would have canonicalized to an AFTER_LOCALS boundary. - if version.dev != 0: - return None - excluded_devs = 0 - else: - return None - - # Only the bare ``E!0`` floor of a non-zero epoch qualifies. - if version.epoch == 0: - return None - if version.pre is not None or version.post is not None or version.local is not None: - return None - if any(trim_release(version.release)): - return None - - # ``==E!0.*`` spans ``[E!0.dev0, E!1.dev0)``; it fits only below that cap. - next_family = Version.from_parts(epoch=version.epoch, release=(1,), dev=0) - cap = UpperBound(next_family, False) - if upper > cap: - return None - - family = Version.from_parts(epoch=version.epoch, release=(0,)) - return family, excluded_devs, upper == cap - - -def _dev_family_anchor(family: Version) -> list[str] | None: - """Prerelease-free fragments for ``[family, ..)``, or ``None`` if it has none. - - ``family`` is an ``X.dev0``. The floor gives ``[]`` (every version); a release - base its ``_clean_lower`` family-floor spelling (``!=0.*`` ...); an ``X.post0`` - base ``>=X,!=X``. A pre-release base has no prerelease-free spelling. - """ - if family <= MIN_VERSION: - return [] - clean = _clean_lower(family) - if clean is not None: - return clean - if family.pre is None and family.post == 0: - base = family.__replace__(post=None, dev=None) - return [f">={base}", f"!={base}"] - return None - - -def _encode_lower(lower: LowerBound, keep_dev0: bool) -> list[str] | None: - """Encode a lower bound as specifier fragments, or ``None``. - - ``[]`` for ``-inf``. An ``AFTER_POSTS(V)`` lower is ``>V``. An - ``AFTER_LOCALS(V)`` lower is the set ``[successor, ..)`` and emits ``>=V,!=V``, - except in the prerelease-free spelling mode (``keep_dev0`` false), where it - recovers a spelling with no synthetic ``.dev0`` when one exists: - ``>3.8.post1`` for a post release, or a dev family's anchor plus the dev run - up to V for a ``.dev`` release. - """ - lower_version = lower.version - if lower_version is None: - return [] - - if isinstance(lower_version, BoundaryVersion): - if lower_version.kind == BoundaryKind.AFTER_POSTS: - # AFTER_POSTS only ever appears as an exclusive ``>V`` lower. - return [f">{lower_version.version}"] - inner = lower_version.version - if inner <= MIN_VERSION: - # The ``(-inf, V)`` side was dropped at the floor, so the lone - # ``(AFTER_LOCALS(0.dev0), +inf)`` interval is exactly ``!=0.dev0``. - return [f"!={inner}"] - # An ``(AFTER_LOCALS(V), ..)`` lower is the set ``[successor, ..)``. In - # the prerelease-free mode, recover a spelling with no synthetic ``.dev0`` - # so the range's opt-in region stays empty. - if not keep_dev0: - if inner.dev is not None: - # A ``.dev`` V makes ``[successor, ..)`` its dev family's - # prerelease-free anchor minus the finite dev run up to ``V`` - # (e.g. ``>=1.0,!=1.0,!=1.0.post0.dev0``), carrying no synthetic - # ``.dev0``. - family = inner.__replace__(dev=0) - anchor = _dev_family_anchor(family) - if anchor is not None: - if inner.dev + 1 > _MAX_EXCLUSION_RUN: - return None - run = [ - f"!={family.__replace__(dev=d)}" for d in range(inner.dev + 1) - ] - return anchor + run - else: - # A ``.post`` release recovers its prerelease-free ``>`` spelling - # from the successor (``>3.8.post1`` for ``AFTER_LOCALS(3.8.post1)``). - successor = least_version_above(lower_version) - clean = _clean_lower(successor) if successor is not None else None - if clean is not None: - return clean - # Otherwise it is ``[V, ..)`` minus V's local family, i.e. ``>=V,!=V``. - # The prerelease-free recoveries above have already returned in that mode; - # a residual ``.dev`` V here opts pre-releases in, so this spelling round - # trips only for a range whose opt-in region wants it. - return [f">={inner}", f"!={inner}"] - - if not lower.inclusive: - return None - - # In the prerelease-free mode a ``.dev0`` lower prefers its clean spelling. - if not keep_dev0: - clean = _clean_lower(lower_version) - if clean is not None: - return clean - return [f">={lower_version}"] - - -def _encode_upper(upper: UpperBound, keep_dev0: bool) -> list[str] | None: - """Encode an upper bound as specifier fragments, or ``None``. - - ``[]`` for ``+inf``. In the prerelease-free spelling mode (``keep_dev0`` - false) the `` Version | None: - """If ``[lower, upper)`` is the ``==V.*`` shape, return ``V``.""" - if isinstance(lower.version, BoundaryVersion) or isinstance( - upper.version, BoundaryVersion - ): - return None - if lower.version is None or upper.version is None: - return None - if not lower.inclusive or upper.inclusive: - return None - if not (_is_dev0_version(lower.version) and _is_dev0_version(upper.version)): - return None - if lower.version.epoch != upper.version.epoch: - return None - - lower_release = trim_release(lower.version.release) - upper_release = trim_release(upper.version.release) - padded_length = max(len(lower_release), len(upper_release)) - assert padded_length > 0 - lower_release += (0,) * (padded_length - len(lower_release)) - upper_release += (0,) * (padded_length - len(upper_release)) - - if lower_release[:-1] != upper_release[:-1]: - return None - - # A genuine ``==V.*`` spans one family: the upper is exactly the next prefix. - # A wider span like ``[3.8.dev0, 3.14.dev0)`` shares the prefix but is not a - # single wildcard, so it falls through to the generic ``>=...,<...`` form. - if upper_release[-1] != lower_release[-1] + 1: - return None - - return lower.version.__replace__(release=lower_release, dev=None) - - -def _encode_interval( - lower: LowerBound, upper: UpperBound, keep_dev0: bool -) -> list[str] | None: - """Encode one interval as specifier fragments, or ``None``. - - Special-cases the ``==V`` singleton (``[V, AFTER_LOCALS(V)]`` for a plain - ``V``, and ``[V+local, V+local]`` for a local one) and the ``==V.*`` shape - so the fragment is one equality rather than a bound pair. - """ - # ``[V+local, V+local]`` (an inclusive local point) is the singleton ``==V+local``. - if ( - lower.version is not None - and upper.version is not None - and not isinstance(lower.version, BoundaryVersion) - and not isinstance(upper.version, BoundaryVersion) - and lower.inclusive - and upper.inclusive - and lower.version == upper.version - and lower.version.local is not None - ): - return [f"=={lower.version}"] - - # ``[V, AFTER_LOCALS(V)]`` (V without a local) is the singleton ``==V``, - # which also matches V's local family: one equality, not ``>=V,<=V``. - if ( - isinstance(lower.version, Version) - and lower.inclusive - and upper.inclusive - and isinstance(upper.version, BoundaryVersion) - and upper.version.kind == BoundaryKind.AFTER_LOCALS - and upper.version.version == lower.version - ): - return [f"=={lower.version}"] - - wildcard = _detect_equal_wildcard(lower, upper) - if wildcard is not None: - return [f"=={wildcard}.*"] - - # A ``[E!0.dev0`` lower has no prerelease-free ``>=`` spelling; within its own - # family it is ``==E!0.*`` trimmed by the upper. - floor = _epoch_floor_lower(lower, upper) if not keep_dev0 else None - if floor is not None: - family, excluded_devs, upper_at_cap = floor - if excluded_devs > _MAX_EXCLUSION_RUN: - return None - parts = [f"=={family}.*"] - parts.extend(f"!={family.__replace__(dev=d)}" for d in range(excluded_devs)) - - # ``==E!0.*`` already caps at the next family; add the upper only if tighter. - if not upper_at_cap: - upper_parts = _encode_upper(upper, keep_dev0) - if upper_parts is None: - return None - parts.extend(upper_parts) - - return parts - - lower_parts = _encode_lower(lower, keep_dev0) - if lower_parts is None: - return None - - upper_parts = _encode_upper(upper, keep_dev0) - if upper_parts is None: - return None - - return lower_parts + upper_parts - - -# Gap encoding: spell the gap between two adjacent intervals as exclusions. - - -def _detect_not_equal( - left_upper: UpperBound, right_lower: LowerBound -) -> list[Version] | None: - """If the gap between two intervals is a ``!=V`` chain, list its points. - - A plain exclusive left upper names the first excluded V directly; an inclusive - boundary left upper names it via its least successor. Adjacent exclusions - (``V`` and its immediate successors) share a single gap spanning a contiguous - dev run, so one gap can name a short chain: ``!=1.0,!=1.0.post0.dev0`` is one - gap from ``1.0`` up to ``AFTER_LOCALS(1.0.post0.dev0)``. - """ - if isinstance(left_upper.version, BoundaryVersion): - # A boundary upper is always inclusive; its least successor is the first - # excluded V (``None`` for a final AFTER_POSTS, which names no point). - first = least_version_above(left_upper.version) - if first is None: - return None - elif left_upper.version is None or left_upper.inclusive: - return None - else: - first = left_upper.version - - if not isinstance(right_lower.version, BoundaryVersion): - if ( - right_lower.version is not None - and not right_lower.inclusive - and right_lower.version == first - and first.local is not None - ): - return [first] - return None - - if right_lower.version.kind != BoundaryKind.AFTER_LOCALS: - return None - - # The right interval resumes just above the last excluded V and its locals. - last = right_lower.version.version - if first == last: - return [first] - - # Adjacent exclusions: the successor of ``first`` opens a ``.dev`` family and - # every later point is a higher ``.dev`` in that same family, so the gap is - # exactly ``first`` plus a contiguous dev run up to ``last``. Any other gap - # (e.g. ``2.3`` to ``AFTER_LOCALS(2.7)`` from complementing ``>=2.3,<=2.7``) - # spans a whole interval and fails this test. - second = least_version_above(BoundaryVersion(first, BoundaryKind.AFTER_LOCALS)) - if ( - second is not None - and second.dev is not None - and last.dev is not None - and last.dev >= second.dev - and last.__replace__(dev=second.dev) == second - ): - # ``first`` and the run spell this gap together, so they share the cap. - if last.dev - second.dev + 2 > _MAX_EXCLUSION_RUN: - return None - run = (second.__replace__(dev=d) for d in range(second.dev, last.dev + 1)) - return [first, *run] - return None - - -def _decompose_dev0_gap( - lower_trim: tuple[int, ...], - upper_trim: tuple[int, ...], - epoch: int, - budget: int = _MAX_EXCLUSION_RUN, -) -> list[Version] | None: - """Decompose the gap ``[L.dev0, U.dev0)`` into wildcard prefixes. - - ``lower_trim``/``upper_trim`` are trimmed release tuples with - ``lower_trim < upper_trim`` lexicographically. The chain sweeps at the - first differing level. The gap is undecomposable when L has trailing - components below that level (the chain cannot escape L's subtree), or when - the chain, summed across levels, would exceed ``budget`` prefixes. - """ - diff = 0 - while ( - diff < len(lower_trim) - and diff < len(upper_trim) - and lower_trim[diff] == upper_trim[diff] - ): - diff += 1 - - if len(lower_trim) > diff + 1: - return None - - common = lower_trim[:diff] - lower_val = lower_trim[diff] if len(lower_trim) > diff else 0 - upper_val = upper_trim[diff] - - span = upper_val - lower_val - if span > budget: - return None - - fragments = [ - Version.from_parts(epoch=epoch, release=(*common, segment)) - for segment in range(lower_val, upper_val) - ] - - if len(upper_trim) == diff + 1: - return fragments - - # Recurse into the next release component, charging at least one to the budget - # per level (not just the span), so a run of zero-span levels (a release with - # many trailing components) exhausts the budget and returns None instead of - # recursing past the interpreter's stack limit. - tail = _decompose_dev0_gap( - (*common, upper_val), upper_trim, epoch, budget - max(span, 1) - ) - if tail is None: - return None - return fragments + tail - - -def _encode_gap(left_upper: UpperBound, right_lower: LowerBound) -> list[str] | None: - """Encode the gap between two adjacent intervals as ``!=`` fragments. - - A point chain becomes ``!=V`` fragments and a dev0 family span becomes - ``!=P.*`` prefixes, followed by a leading dev run in the last family when - the gap ends inside it. Any other gap has no exclusion form and returns - ``None``. - """ - # Cheapest first: a plain ``!=V`` chain never pays for the budgeted - # wildcard sweep below. - points = _detect_not_equal(left_upper, right_lower) - if points is not None: - return [f"!={point}" for point in points] - - # Both wildcard shapes start at an exclusive family base ``L.dev0``. - left_v = left_upper.version - if ( - not isinstance(left_v, Version) - or left_upper.inclusive - or not _is_dev0_version(left_v) - ): - return None - - right_v = right_lower.version - if isinstance(right_v, Version) and right_lower.inclusive: - # ``[L.dev0, U.dev0)`` is a pure ``!=P.*`` chain up to U's family. - upper_dev0 = right_v - run_length = 0 - budget = _MAX_EXCLUSION_RUN - elif ( - isinstance(right_v, BoundaryVersion) - and right_v.kind == BoundaryKind.AFTER_LOCALS - and not right_lower.inclusive - ): - # ``[L.dev0, AFTER_LOCALS(U.dev(k))]`` ends inside U's family: the - # ``!=P.*`` chain, then the ``U.dev0..U.dev(k)`` run. Both spell the - # gap together, so they share one ``_MAX_EXCLUSION_RUN`` budget. - upper = right_v.version - if upper.dev is None or upper.dev + 1 > _MAX_EXCLUSION_RUN: - return None - upper_dev0 = upper.__replace__(dev=0) - run_length = upper.dev + 1 - budget = _MAX_EXCLUSION_RUN - run_length - else: - return None - - # ``U`` must be a plain release base in L's epoch, above L. - # ``_is_dev0_version`` on ``U.dev0`` rejects any pre/post/local on ``U``. - if not _is_dev0_version(upper_dev0): - return None - if left_v.epoch != upper_dev0.epoch or left_v >= upper_dev0: - return None - - prefixes = _decompose_dev0_gap( - trim_release(left_v.release), - trim_release(upper_dev0.release), - left_v.epoch, - budget, - ) - if prefixes is None: - return None - - exclusions = [f"!={prefix}.*" for prefix in prefixes] - exclusions.extend(f"!={upper_dev0.__replace__(dev=d)}" for d in range(run_length)) - return exclusions - - -def _encode_gaps(bounds: Sequence[Interval]) -> list[str] | None: - """Encode every between-interval gap as ``!=`` fragments, or ``None``. - - When each gap has an exclusion spelling, the intervals fuse into one - contiguous span (``==1.* | ==3.*`` is ``!=0.*,!=2.*,<4``): the outer - interval across all the bounds plus these exclusions. A gap with no - exclusion spelling makes the bounds a disjoint union, which no single - set expresses. - """ - exclusions: list[str] = [] - - for index in range(1, len(bounds)): - gap = _encode_gap(bounds[index - 1][1], bounds[index][0]) - if gap is None: - return None - exclusions.extend(gap) - - return exclusions - - -def _tighten_no_prereleases(bounds: tuple[Interval, ...]) -> tuple[Interval, ...]: - """Snap the range's final upper out of the pre-release band ``False`` drops. - - An exclusive upper at a final ``V`` admits the versions in ``[V.dev0, V)`` at - the bounds level, but a ``prereleases=False`` policy filters them all out, so - it accepts the same releases as ``>> r = SpecifierSet(">=1.0,<2.0").to_range() - >>> "1.5" in r - True - >>> "2.0" in r - False - >>> SpecifierSet(">=2.0,<1.0").to_range().is_empty - True - - PEP 440's ``===`` operator matches a candidate string verbatim - (case-insensitive) rather than a set of versions. Ranges built from - ``===`` specifiers still support membership, set operations, and conversion - back to a :class:`~packaging.specifiers.SpecifierSet`; matching follows the - literal-equality rule. A ``===`` literal that names a pre-release is - admitted under the default policy by both :meth:`contains` and - :meth:`filter`, since it was named outright. - - .. versionadded:: 26.3 - """ - - __slots__ = ( - "_admit", - "_admit_arbitrary", - "_bounds", - "_pre_region", - "_prereleases_configured", - "_reject", - ) - - #: The disjoint, sorted, non-overlapping interval list. - _bounds: tuple[Interval, ...] - - #: Whether this range matches non-version strings as well as versions. - #: True only by construction on ``SpecifierSet("")`` / :meth:`full`. The flag - #: rides set algebra but is inert except at full bounds (see - #: :meth:`_arbitrary_active`). An intersection or difference that shrinks - #: the bounds drops it (``full() & ~full()`` is plain empty, and - #: ``full() - r == full() & ~r``); :meth:`complement` and a union of - #: empty-bounds operands keep it, so ``~~full() == full()`` and - #: ``~full() | ~full() == ~full()``. Part of equality, since membership - #: reads it. - _admit_arbitrary: bool - - #: Case-folded strings the range admits in addition to its bounds. - #: ``===wat`` produces ``_admit = {"wat"}``. - _admit: frozenset[str] - - #: Case-folded strings the range rejects (overrides ``_admit`` and the - #: bounds). Populated by :meth:`complement` of an admit-bearing range and by - #: literal resolution in :meth:`_combine_literals`. - _reject: frozenset[str] - - #: Sorted, disjoint intervals where pre-releases are force-admitted under - #: the PEP 440 default policy (a ``None`` ``prereleases`` argument and no - #: configured override). The opt-in flows only from the pre-release-naming - #: specifiers that built the range. :meth:`_build` clips the region to the - #: bounds, so it is always a subset of them: an opt-in that overflowed its - #: own cap cannot ride a later union into versions no specifier asked for. - #: :meth:`union` and :meth:`intersection` accumulate the operands' clipped - #: regions and re-clip to the result bounds; :meth:`difference` keeps only - #: the minuend's; and :meth:`complement` drops it, since an exclusion grants - #: no opt-in. Equality keys on the clipped region, so it stays a congruence. - _pre_region: tuple[Interval, ...] - - #: Raw configured pre-release override of the originating specifier set - #: (an explicit ``True`` / ``False``, else ``None``). When set, :meth:`_build` - #: forces ``_pre_region`` empty since the policy governs globally. - #: :meth:`intersection` and :meth:`union` require it to match on both - #: operands. Part of equality. - _prereleases_configured: bool | None - - def __new__(cls, *args: object, **kwargs: object) -> VersionRange: # noqa: PYI034 - raise TypeError( - "cannot create 'VersionRange' instances directly; use " - "SpecifierSet.to_range(), VersionRange.full(), " - "VersionRange.empty(), or VersionRange.singleton() instead" - ) - - @classmethod - def _build( - cls, - bounds: tuple[Interval, ...], - admit: frozenset[str] = frozenset(), - reject: frozenset[str] = frozenset(), - admit_arbitrary: bool = False, - *, - pre_region: tuple[Interval, ...] = (), - prereleases_configured: bool | None = None, - ) -> VersionRange: - """Internal factory; bypasses :meth:`__new__`. - - Canonicalizes the bounds so equal version sets share one representation, - then drops admit literals the bounds already admit and reject literals - the bounds do not match anyway. Reject wins over admit on overlap. The - pre-release policy is set here and never reassigned afterwards; - ``pre_region`` is canonicalized like the bounds and clipped to them, - or dropped when a configured policy makes it inert. - """ - bounds = _canonicalize(bounds) - - if admit and reject: - admit = admit - reject - if admit: - admit = frozenset( - literal - for literal in admit - if not _struct_admits(bounds, admit_arbitrary, literal) - ) - if reject: - reject = frozenset( - literal - for literal in reject - if _struct_admits(bounds, admit_arbitrary, literal) - ) - - instance = object.__new__(cls) - instance._bounds = bounds - instance._admit = admit - instance._reject = reject - instance._admit_arbitrary = admit_arbitrary - instance._prereleases_configured = prereleases_configured - - # A configured policy makes the region inert, so drop it. Otherwise fold - # least-successor bounds (_from_specifier_set passes the region unfolded), - # so ``>1.0a1`` and ``>=1.0a2.dev0`` carry the same region, then clip it - # to the bounds so the opt-in never reaches past the range's own versions. - if prereleases_configured is not None or not pre_region: - instance._pre_region = () - else: - instance._pre_region = tuple( - intersect_ranges(_canonicalize(pre_region), bounds) - ) - - return instance - - def _has_literals(self) -> bool: - return bool(self._admit) or bool(self._reject) - - def _arbitrary_active(self) -> bool: - """True when ``_admit_arbitrary`` actually admits non-version strings. - - The flag rides through set algebra but only fires admission on full - bounds. Intersection and difference drop it when the bounds shrink, so - away from full bounds it survives only on empty-bounds ranges, where - it keeps ``~~full() == full()`` and union idempotent. - """ - return self._admit_arbitrary and self._bounds == FULL_RANGE - - def _is_plain(self) -> bool: - """True when membership is decided by ``_bounds`` alone, enabling the - bounds-only fast paths in :meth:`is_subset` and :meth:`is_disjoint`. - """ - return ( - not self._has_literals() - and not self._admit_arbitrary - and self._prereleases_configured is not False - ) - - def _check_policy_compat(self, other: VersionRange) -> None: - """Refuse combining ranges with different pre-release policies.""" - if not isinstance(other, VersionRange): - raise TypeError(f"expected VersionRange, got {type(other).__name__}") - if self._prereleases_configured != other._prereleases_configured: - raise ValueError( - "Cannot combine VersionRange operands with different " - f"pre-release policies: {self._prereleases_configured!r} " - f"and {other._prereleases_configured!r}" - ) - - def _merged_region(self, other: VersionRange) -> tuple[Interval, ...]: - """Union of ``self`` and ``other``'s opt-in regions. - - Used by :meth:`union` and :meth:`intersection`; :meth:`_build` clips the - merge to the result bounds. A configured operand carries an empty region, - so it contributes nothing to the merge. - """ - # Reuse an operand's canonical tuple when only one side has a region; - # an empty side contributes nothing to the union. - if not other._pre_region: - return self._pre_region - if not self._pre_region: - return other._pre_region - - # Both sides carry a region; merge them. _build re-canonicalizes and - # clips, so the plain union is fine here. - return tuple(_union_ranges(self._pre_region, other._pre_region)) - - def _with_policy( - self, *, pre_region: tuple[Interval, ...], configured: bool | None - ) -> VersionRange: - """A structural copy of this range carrying the given pre-release policy.""" - return self._build( - self._bounds, - admit=self._admit, - reject=self._reject, - admit_arbitrary=self._admit_arbitrary, - pre_region=pre_region, - prereleases_configured=configured, - ) - - @classmethod - def empty(cls, *, prereleases: bool | None = None) -> VersionRange: - """Return the empty range. No version satisfies it. - - >>> VersionRange.empty().is_empty - True - >>> "1.0" in VersionRange.empty() - False - """ - return cls._build((), prereleases_configured=prereleases) - - @classmethod - def full( - cls, *, admit_arbitrary: bool = True, prereleases: bool | None = None - ) -> VersionRange: - """Return the full range. Every PEP 440 version satisfies it. - - ``admit_arbitrary=False`` restricts the range to PEP 440 versions only - (matching the same versions as ``SpecifierSet(">=0.dev0").to_range()``); - its complement is :meth:`empty`. The flag propagates through set algebra - and is part of equality. Default ``True`` so that ``r & full()`` - preserves ``r``'s own flag structurally. - - >>> "1.0" in VersionRange.full() - True - >>> "wat" in VersionRange.full() - True - >>> "wat" in VersionRange.full(admit_arbitrary=False) - False - """ - return cls._build( - FULL_RANGE, - admit_arbitrary=admit_arbitrary, - prereleases_configured=prereleases, - ) - - @classmethod - def singleton( - cls, version: Version | str, *, prereleases: bool | None = None - ) -> VersionRange: - """Return the strict singleton range ``{version}``. - - Built as the closed interval ``[version, version]`` with strict - equality. ``Specifier("==V")`` matches ``V+local`` too, so the strict - singleton is narrower: - - >>> "1.0+local" in VersionRange.singleton("1.0") - False - >>> "1.0+local" in SpecifierSet("==1.0").to_range() - True - - :raises packaging.version.InvalidVersion: if version is a string that - does not parse as a PEP 440 version. - """ - if not isinstance(version, Version): - version = Version(version) - - lower = LowerBound(version, True) - upper = UpperBound(version, True) - - # Collapse the floor: nothing sorts below ``MIN_VERSION``, so the - # ``0.dev0`` singleton is ``(-inf, 0.dev0]`` in canonical form. - return cls._build( - _canonical_floor(((lower, upper),)), - prereleases_configured=prereleases, - ) - - def intersection(self, other: VersionRange) -> VersionRange: - """Range containing exactly the versions in both self and other. - - Both operands must share the same configured pre-release policy; - otherwise :exc:`ValueError` is raised. - - >>> a = SpecifierSet(">=1.0").to_range() - >>> b = SpecifierSet("<2.0").to_range() - >>> a.intersection(b) == SpecifierSet(">=1.0,<2.0").to_range() - True - """ - self._check_policy_compat(other) - - configured = self._prereleases_configured - new_bounds = tuple(intersect_ranges(self._bounds, other._bounds)) - new_region = self._merged_region(other) - - # An empty intersection (e.g. ``full() & ~full()``) is the empty range, - # so it drops the arbitrary flag, agreeing with difference when the - # subtrahend consumes the bounds. - combined_arb = ( - self._admit_arbitrary and other._admit_arbitrary and bool(new_bounds) - ) - - if not self._has_literals() and not other._has_literals(): - return self._build( - new_bounds, - admit_arbitrary=combined_arb, - pre_region=new_region, - prereleases_configured=configured, - ) - - return self._combine_literals( - other, - new_bounds, - op=_SetOp.INTERSECTION, - admit_arbitrary=combined_arb, - pre_region=new_region, - prereleases_configured=configured, - ) - - def union(self, other: VersionRange) -> VersionRange: - """Range containing every version in self or other. - - Both operands must share the same configured pre-release policy; - otherwise :exc:`ValueError` is raised. - - >>> a = VersionRange.singleton("1.0") - >>> b = VersionRange.singleton("2.0") - >>> "1.0" in a.union(b) and "2.0" in a.union(b) - True - >>> "1.5" in a.union(b) - False - """ - self._check_policy_compat(other) - - configured = self._prereleases_configured - new_bounds = tuple(_union_ranges(self._bounds, other._bounds)) - new_region = self._merged_region(other) - - # An empty-bounds operand (e.g. ``~full()``) carries an inert arbitrary - # flag only to keep complement an involution; it admits nothing, so it - # must not revive arbitrary admission as the union re-widens the bounds. - if new_bounds: - combined_arb = (self._admit_arbitrary and bool(self._bounds)) or ( - other._admit_arbitrary and bool(other._bounds) - ) - else: - # Nothing widened, so keeping the flags keeps ``r | r == r``. - combined_arb = self._admit_arbitrary or other._admit_arbitrary - - if not self._has_literals() and not other._has_literals(): - return self._build( - new_bounds, - admit_arbitrary=combined_arb, - pre_region=new_region, - prereleases_configured=configured, - ) - - return self._combine_literals( - other, - new_bounds, - op=_SetOp.UNION, - admit_arbitrary=combined_arb, - pre_region=new_region, - prereleases_configured=configured, - ) - - def complement(self) -> VersionRange: - """Range containing every version not in self. - - Preserves the configured pre-release policy. On the version set, double - negation holds for a range with no ``===`` literals (the arbitrary-string - flag round-trips, so ``~~full() == full()``); for ``===`` ranges - complement is one-way. The opt-in region is not restored (see below). - - The opt-in region is dropped: a complement is an exclusion, and an - exclusion expresses no pre-release preference. This is what lets - ``a & ~b`` shed ``b``'s opt-in, so an excluded ``b`` never force-admits a - pre-release into the result. Complement stays involutive on the version - set, but not on the opt-in region: ``~~r`` covers the same versions as - ``r`` yet force-admits none of its pre-releases. - - >>> r = SpecifierSet(">=1.0").to_range() - >>> "0.5" in r.complement() - True - >>> "1.5" in r.complement() - False - >>> r.complement().complement() == r - True - """ - # Complement swaps literal admission: what the range rejects, its - # complement admits. - return self._build( - tuple(_complement_ranges(self._bounds)), - admit=self._reject, - reject=self._admit, - admit_arbitrary=self._admit_arbitrary, - pre_region=(), - prereleases_configured=self._prereleases_configured, - ) - - def difference(self, other: VersionRange) -> VersionRange: - """Range containing the versions in self but not in other. - - Matches ``self & ~other`` on the version set and the opt-in region; - ``other`` acts as a bounds-only exclusion that grants no opt-in. The - arbitrary-string flag survives only when ``other`` removed no versions: - a difference that shrinks the bounds forgets it, as ``self & ~other`` - would, so no later widening union can revive it. They still part on - ``===`` literals, whose complement is one-way: a ``===`` literal stays - when ``self`` admits it and ``other`` does not. Both operands must - share the same configured pre-release policy (as :meth:`intersection` - and :meth:`union` require); otherwise :exc:`ValueError` is raised. - ``a - empty()`` returns a range equal to ``a``. - - >>> a = SpecifierSet(">=1.0").to_range() - >>> b = SpecifierSet(">=2.0").to_range() - >>> "1.5" in a.difference(b) - True - >>> "2.0" in a.difference(b) - False - >>> a.difference(VersionRange.empty()) == a - True - """ - self._check_policy_compat(other) - - # Subtracting a nothing-admitting set is a no-op; return self unchanged. - if not other._bounds and not other._admit: - return self - - # Bound complement is two-way, so subtracting other's versions is an - # intersection with its gaps. - new_bounds = tuple( - intersect_ranges(self._bounds, _complement_ranges(other._bounds)) - ) - - # Match ``self & ~other`` on the opt-in region: a complement carries no - # opt-in, so only ``self``'s region survives. ``other`` acts as a - # bounds-only exclusion. A configured ``self`` keeps no region. - new_region: tuple[Interval, ...] = () - if self._prereleases_configured is None: - new_region = self._pre_region - - # Keep self's arbitrary admission only when subtracting removed no - # versions. A difference that shrinks the bounds forgets the flag, as - # ``self & ~other`` would, so no later widening union can revive an - # admission neither operand had. - combined_arb = self._admit_arbitrary and new_bounds == self._bounds - - if not self._has_literals() and not other._has_literals(): - return self._build( - new_bounds, - admit_arbitrary=combined_arb, - pre_region=new_region, - prereleases_configured=self._prereleases_configured, - ) - - return self._combine_literals( - other, - new_bounds, - op=_SetOp.DIFFERENCE, - admit_arbitrary=combined_arb, - pre_region=new_region, - prereleases_configured=self._prereleases_configured, - ) - - def _combine_literals( - self, - other: VersionRange, - new_bounds: tuple[Interval, ...], - *, - op: _SetOp, - admit_arbitrary: bool, - pre_region: tuple[Interval, ...], - prereleases_configured: bool | None, - ) -> VersionRange: - """Resolve admit/reject for ``self`` ``op`` ``other`` over their literals.""" - admits: set[str] = set() - rejects: set[str] = set() - - # Each literal is decided independently of the others. - for literal in self._admit | self._reject | other._admit | other._reject: - self_in = self._matches_literal(literal) - other_in = other._matches_literal(literal) - - if op is _SetOp.INTERSECTION: - want = self_in and other_in - elif op is _SetOp.UNION: - want = self_in or other_in - else: - want = self_in and not other_in - - if want: - admits.add(literal) - else: - rejects.add(literal) - - return self._build( - new_bounds, - admit=frozenset(admits), - reject=frozenset(rejects), - admit_arbitrary=admit_arbitrary, - pre_region=pre_region, - prereleases_configured=prereleases_configured, - ) - - def _matches_literal(self, literal: str) -> bool: - """Whether literal (case-folded) matches this range's predicate.""" - if literal in self._reject: - return False - if literal in self._admit: - return True - - parsed = coerce_version(literal) - if parsed is None: - return self._arbitrary_active() - return matches_bounds_only(self._bounds, parsed) - - def __and__(self, other: object) -> VersionRange: - """Operator alias for :meth:`intersection`.""" - if not isinstance(other, VersionRange): - return NotImplemented - return self.intersection(other) - - def __or__(self, other: object) -> VersionRange: - """Operator alias for :meth:`union`.""" - if not isinstance(other, VersionRange): - return NotImplemented - return self.union(other) - - def __invert__(self) -> VersionRange: - """Operator alias for :meth:`complement`.""" - return self.complement() - - def __sub__(self, other: object) -> VersionRange: - """Operator alias for :meth:`difference`.""" - if not isinstance(other, VersionRange): - return NotImplemented - return self.difference(other) - - def is_subset(self, other: VersionRange) -> bool: - """Return whether every member of self is also a member of other. - - On versions and ``===`` literals this is - ``self.difference(other).is_empty``: subtracting other leaves nothing - behind. A live arbitrary admission (the flag at full bounds) is only a - subset of another live one. - - Both operands must share the same configured pre-release policy; - otherwise :exc:`ValueError` is raised. - - >>> inner = SpecifierSet(">=1.5,<1.8").to_range() - >>> outer = SpecifierSet(">=1.0,<2.0").to_range() - >>> inner.is_subset(outer) - True - >>> outer.is_subset(inner) - False - >>> VersionRange.empty().is_subset(outer) - True - """ - self._check_policy_compat(other) - - # A live arbitrary admission has non-version strings as members, which - # no bounds cover; only another live admission contains them. - if self._arbitrary_active() and not other._arbitrary_active(): - return False - - # Plain ranges: subset reduces to bounds containment, no algebra needed. - if self._is_plain() and other._is_plain(): - return not intersect_ranges(self._bounds, _complement_ranges(other._bounds)) - - # difference (unlike intersection with the one-way complement) resolves - # ``===`` literals against both operands, so it stays correct for them. - return self.difference(other).is_empty - - def is_superset(self, other: VersionRange) -> bool: - """Return whether every member of other is also a member of self. - - The mirror of :meth:`is_subset`: ``a.is_superset(b)`` is - ``b.is_subset(a)``. - - Both operands must share the same configured pre-release policy; - otherwise :exc:`ValueError` is raised. - - >>> outer = SpecifierSet(">=1.0,<2.0").to_range() - >>> outer.is_superset(SpecifierSet(">=1.5,<1.8").to_range()) - True - """ - # Type-guards a non-VersionRange other before delegating to is_subset. - self._check_policy_compat(other) - return other.is_subset(self) - - def is_disjoint(self, other: VersionRange) -> bool: - """Return whether self and other share no member. - - Equivalent to ``(self & other).is_empty``. - - Both operands must share the same configured pre-release policy; - otherwise :exc:`ValueError` is raised. - - >>> a = SpecifierSet(">=1.0,<2.0").to_range() - >>> a.is_disjoint(SpecifierSet(">=2.0,<3.0").to_range()) - True - >>> a.is_disjoint(SpecifierSet(">=1.5,<2.5").to_range()) - False - """ - self._check_policy_compat(other) - - # Plain ranges: disjointness is an empty bounds intersection. - if self._is_plain() and other._is_plain(): - return not intersect_ranges(self._bounds, other._bounds) - return self.intersection(other).is_empty - - def _same_releases(self, other: VersionRange) -> bool: - """Whether self and other admit the same non-pre-release versions. - - Used by :meth:`to_specifier_set` under a ``prereleases=False`` policy, - where pre-releases are unobservable: the symmetric difference is empty - exactly when the two ranges accept the same releases. Both operands - carry that policy, so the difference below reads emptiness through it. - """ - return self.difference(other).is_empty and other.difference(self).is_empty - - @typing.overload - def filter( - self, - iterable: Iterable[UnparsedVersionVar], - prereleases: bool | None = None, - key: None = ..., - ) -> Iterator[UnparsedVersionVar]: ... - - @typing.overload - def filter( - self, - iterable: Iterable[T], - prereleases: bool | None = None, - key: Callable[[T], UnparsedVersion] = ..., - ) -> Iterator[T]: ... - - def filter( - self, - iterable: Iterable[Any], - prereleases: bool | None = None, - key: Callable[[Any], Version | str] | None = None, - ) -> Iterator[Any]: - """Yield items from iterable whose version falls inside the range. - - With prereleases ``None`` the PEP 440 default applies: pre-releases are - buffered and only emitted if no final release in iterable is in range, - except that a pre-release inside the autodetected opt-in region, or named - outright by a ``===`` literal, is force-admitted in place (as - ``prereleases=True`` would yield it). A flushed buffer comes after - every in-place yield, so the output is not version-sorted. - - The signature mirrors - :meth:`~packaging.specifiers.SpecifierSet.filter`. - - >>> r = SpecifierSet(">=1.0,<2.0").to_range() - >>> list(r.filter(["0.9", "1.5", "2.0"])) - ['1.5'] - """ - region: tuple[Interval, ...] = () - if prereleases is None: - # The region applies only under the autodetect default; a configured - # policy governs instead (and then ``_pre_region`` is already empty). - prereleases = self._prereleases_configured - region = self._pre_region - - arbitrary_active = self._arbitrary_active() - if not self._admit and not self._reject and not arbitrary_active: - # A region spanning the whole bounds force-admits every in-bounds - # pre-release, i.e. ``prereleases=True``; take the cheaper no-buffer - # path. (Confined to this branch: the admission path orders arbitrary - # strings differently under True than under the region.) - if region and region == self._bounds: - return filter_by_ranges(self._bounds, iterable, key, True) - return filter_by_ranges(self._bounds, iterable, key, prereleases, region) - return self._filter_with_admission( - iterable, key, prereleases, arbitrary_active, region - ) - - def _filter_with_admission( - self, - iterable: Iterable[Any], - key: Callable[[Any], Version | str] | None, - prereleases: bool | None, - arbitrary_active: bool, - region: tuple[Interval, ...], - ) -> Iterator[Any]: - """Filter for ranges with admit/reject literals or live arbitrary - admission (including the universal ``SpecifierSet("")`` range).""" - admit_set = self._admit - reject_set = self._reject - - def admit(item: Any) -> tuple[bool, Version | None, bool]: # noqa: ANN401 - raw: Version | str = item if key is None else key(item) - raw_lower = str(raw).lower() - - if reject_set and raw_lower in reject_set: - return False, None, False - if admit_set and raw_lower in admit_set: - # An explicit ``===`` literal names this version outright. - return True, coerce_version(raw), True - - parsed = coerce_version(raw) - if parsed is None: - return arbitrary_active, None, False - if not matches_bounds_only(self._bounds, parsed): - return False, None, False - return True, parsed, False - - if prereleases is True: - for item in iterable: - ok, _, _ = admit(item) - if ok: - yield item - return - - if prereleases is False: - for item in iterable: - ok, parsed, _ = admit(item) - if not ok: - continue - if parsed is not None and parsed.is_prerelease: - continue - yield item - return - - # PEP 440 default: emit finals eagerly and buffer the other pre-releases, - # releasing the buffer only if no final ever matches. - all_nonfinal: list[Any] = [] - arbitrary_strings: list[Any] = [] - found_final = False - - for item in iterable: - ok, parsed, by_literal = admit(item) - if not ok: - continue - - if parsed is None: - if found_final: - yield item - else: - arbitrary_strings.append(item) - all_nonfinal.append(item) - continue - - if not parsed.is_prerelease: - if not found_final: - yield from arbitrary_strings - arbitrary_strings.clear() - found_final = True - yield item - continue - - # A pre-release is force-admitted when it is named outright by a - # ``===`` literal or falls in the opt-in region, as ``prereleases=True`` - # would yield it; otherwise the PEP 440 default buffers it. - if by_literal or (region and matches_bounds_only(region, parsed)): - yield item - continue - - if not found_final: - all_nonfinal.append(item) - - if not found_final: - yield from all_nonfinal - - @classmethod - def _from_specifier_set(cls, specifier_set: SpecifierSet) -> VersionRange: - """Build the range accepted by ``specifier_set``. - - Friend constructor for :meth:`~packaging.specifiers.SpecifierSet.to_range`. - The intersection of every specifier in the set: an empty set yields the - full range, an unsatisfiable set yields the empty range, and ``===`` - specifiers contribute literal-string admission. - """ - if not specifier_set: - result = cls.full() - elif not specifier_set._has_arbitrary: - result = cls._build( - bounds=_canonical_floor(tuple(specifier_set._get_ranges())) - ) - else: - result = cls.full() - for spec in specifier_set: - if spec.operator == "===": - operand = cls._build( - bounds=(), admit=frozenset({spec.version.lower()}) - ) - else: - operand = cls._build( - bounds=_canonical_floor(tuple(spec._to_ranges())) - ) - result = result.intersection(operand) - - # Each pre-release-naming specifier opts its own versions in; their union, - # clipped to the set's bounds by _build, is the region. Clipping refolds - # under intersection, so a set built directly equals one built by - # intersecting its specifiers one at a time. - region: list[Interval] = [] - if specifier_set._prereleases is None: # a configured policy has no region - for spec in specifier_set: - # ``===`` literals are not a range; filter force-admits them. - if spec.operator != "===" and spec.prereleases: - spec_bounds = _canonical_floor(tuple(spec._to_ranges())) - region = _union_ranges(region, spec_bounds) - - return result._with_policy( - pre_region=tuple(region), - configured=specifier_set._prereleases, - ) - - def to_specifier_set(self) -> SpecifierSet | None: - """Return a :class:`~packaging.specifiers.SpecifierSet` matching the same - versions as self, or ``None`` if no single set expresses it. - - PEP 440 has no syntax for the strict singleton ``{V}`` (an exclusive - plain-version bound), a disjoint union of two or more intervals, or a - partial pre-release opt-in region, so ranges built by set algebra often - return ``None``. A gap that takes more than ``_MAX_EXCLUSION_RUN`` - contiguous ``!=`` exclusions to spell returns ``None`` too, - rather than a pathologically long chain; reaching that cap takes either - set algebra or a specifier set that already spells the gap out with - over a hundred contiguous ``!=N.*`` exclusions. An empty range maps to - ``SpecifierSet("<0")``, unless it still carries the arbitrary-string - flag (which no set reproduces), and a full range that admits arbitrary - strings maps to ``SpecifierSet("")``. - - A range built from a :class:`~packaging.specifiers.SpecifierSet` - re-encodes, short of that exclusion cap. The result is the simplest - candidate whose own - :meth:`~packaging.specifiers.SpecifierSet.to_range` reproduces self - exactly (bounds, ``===`` literals, and the opt-in region are all part of - equality), so it filters the same versions. Two cases relax that - exactness without changing what is filtered: an empty range recovers as - the canonical empty range (same versions, none, but not self's bounds), - and under a ``prereleases=False`` policy the result need only match self's - releases, so ``(-inf, 3.14)`` recovers as the tighter ``<3.14`` rather - than ``!=3.14,<=3.14``. - - Each call encodes a handful of candidate spellings and keeps the - simplest one that verifies, where verifying means parsing the candidate - and round-tripping it through - :meth:`~packaging.specifiers.SpecifierSet.to_range`. The work grows - with the number of intervals and exclusions in the range, and the - result is not cached, so convert once and reuse the returned set rather - than converting per candidate version in a hot loop. - - >>> str(SpecifierSet(">=1.0,<2.0").to_range().to_specifier_set()) - '<2.0,>=1.0' - >>> str(SpecifierSet("==1.0").to_range().to_specifier_set()) - '==1.0' - >>> VersionRange.singleton("1.5").to_specifier_set() is None - True - """ - from .specifiers import InvalidSpecifier, SpecifierSet # noqa: PLC0415 - - configured = self._prereleases_configured - - if self._reject: - return None - if self._admit_arbitrary and self._bounds != FULL_RANGE: - return None - if self.is_empty: - # Every member-free spelling accepts the same versions (none), so the - # canonical ``<0`` stands in for all of them; a configured policy - # rides along it. - return SpecifierSet("<0", prereleases=configured) - - if not self._bounds: - # Pure ``===`` literals; only a single literal has a single-set form. - if len(self._admit) != 1: - return None - (literal,) = self._admit - bases = [f"==={literal}"] - elif self._admit: - # Bounds plus literals cannot be one set. - return None - elif self._bounds == FULL_RANGE: - bases = ["" if self._admit_arbitrary else ">=0.dev0"] - else: - # Under ``prereleases=False`` an exclusive final upper admits the same - # releases as ``=0.dev0`` floor restores a ``True`` opt-in that - # rode on a floor the clean encoding dropped (e.g. ``>=0.dev0,!=1.0``). - # It always recovers the whole bounds as the opt-in region, so it can - # only round-trip when self opts everything in. - add_floor = configured is None and self._pre_region == self._bounds - - # Keep the simplest candidate that recovers self. ``==`` compares bounds, - # literals, and the opt-in region, so a candidate that would filter - # differently, or an op-built range with no single-set form, is rejected - # below. Under ``prereleases=False`` a candidate need only match self's - # releases (policies never mix, so the excluded pre-releases are - # unobservable), which admits the tightened spellings above. - best: SpecifierSet | None = None - best_key = (0, 0) - - for base in bases: - candidates = [base] - if add_floor: - candidates.append(f"{base},>=0.dev0" if base else ">=0.dev0") - - for spec_str in candidates: - # A ``===`` literal can hold a comma (its arbitrary version - # excludes only whitespace, ``;`` and ``)``), which the set - # string splits on. Such a literal has no single specifier-set - # spelling, so drop the unparsable candidate and let the range - # fall through to ``None`` rather than raise. - try: - recovered = SpecifierSet(spec_str, prereleases=configured) - except InvalidSpecifier: - continue - # Fewest fragments, then shortest string. Rank before the round - # trip so a candidate that cannot beat the best skips the check - # (its ``==`` and, under ``False``, two ``difference`` calls). - key = (len(recovered), len(str(recovered))) - if best is not None and key >= best_key: - continue - - # Accept an exact round trip, or (under ``False``) one that only - # matches the releases the policy leaves observable. - candidate = recovered.to_range() - matches = candidate == self or ( - configured is False and self._same_releases(candidate) - ) - if matches: - best, best_key = recovered, key - - return best - - @property - def is_empty(self) -> bool: - """``True`` if no version or string satisfies this range. - - Agrees with :meth:`~packaging.specifiers.SpecifierSet.is_unsatisfiable`, - including the pre-release policy: a range whose only members are - pre-releases is empty when that policy excludes them. - - >>> SpecifierSet(">=2,<1").to_range().is_empty - True - >>> SpecifierSet(">=1,<2").to_range().is_empty - False - >>> SpecifierSet("==1.0a1", prereleases=False).to_range().is_empty - True - """ - # An arbitrary-string admission or a surviving ``===`` literal is a - # member; a literal that is a pre-release is dropped when the policy is. - if self._arbitrary_active(): - return False - - excludes_prereleases = self._prereleases_configured is False - for literal in self._admit: - if excludes_prereleases: - parsed = coerce_version(literal) - if parsed is not None and parsed.is_prerelease: - continue - return False - - if not self._bounds: - return True - - return excludes_prereleases and ranges_are_prerelease_only(self._bounds) - - def contains( - self, - item: Version | str, - prereleases: bool | None = None, - installed: bool | None = None, - ) -> bool: - """Return whether item is contained in this range. - - :param item: a version string or :class:`~packaging.version.Version`. - :param prereleases: whether to match pre-releases. ``None`` (default) - uses the range's own policy. - :param installed: when ``True``, accept a pre-release item even if the - range would not otherwise allow it. - - Unlike :meth:`filter`, this does not consult the autodetected pre-release - opt-in region; it reads only the configured policy. This mirrors - :meth:`~packaging.specifiers.SpecifierSet.contains` versus - :meth:`~packaging.specifiers.SpecifierSet.filter`. - - Unparsable strings do not match, except where the full - ``SpecifierSet`` would also match: the full range admits any string, - and a ``===`` range admits items equal to the literal - case-insensitively. - - >>> r = SpecifierSet(">=1.0,<2.0").to_range() - >>> r.contains("1.5") - True - >>> r.contains("2.0") - False - - :raises TypeError: if item is not a str or Version. - """ - if not isinstance(item, (str, Version)): - raise TypeError( - f"VersionRange.contains() expected str or Version, " - f"got {type(item).__name__}" - ) - - parsed: Version | None = item if isinstance(item, Version) else None - if installed and parsed is None: - parsed = coerce_version(item) - if installed and parsed is not None and parsed.is_prerelease: - prereleases = True - - effective_pre = ( - self._prereleases_configured if prereleases is None else prereleases - ) - - if self._admit or self._reject: - item_str = str(item).lower() - if item_str in self._reject: - return False - if item_str in self._admit: - if effective_pre is False: - literal_parsed = coerce_version(item_str) - if literal_parsed is not None and literal_parsed.is_prerelease: - return False - return True - - if not isinstance(item, Version): - if parsed is None: - parsed = coerce_version(item) - if parsed is None: - return self._arbitrary_active() - item = parsed - - if effective_pre is False and item.is_prerelease: - return False - return matches_bounds_only(self._bounds, item) - - def __contains__(self, item: Version | str) -> bool: - """Return whether item is contained in this range. - - Forwards to :meth:`contains` with default arguments. - - >>> "1.5" in SpecifierSet(">=1.0,<2.0").to_range() - True - """ - return self.contains(item) - - def __eq__(self, other: object) -> bool: - """Structural equality. - - Compares the bounds, the ``===`` admit/reject literals, the - arbitrary-string flag, the configured pre-release policy, and the - opt-in region, not just the version set. Keying on the region makes - equality a congruence (equal ranges stay equal under further operations), - so equal implies same :meth:`contains` and :meth:`filter`, but not the - converse: an empty range keeps the flag it was built with, so two empty - ranges need not be equal. - - Different specifiers for the same range fold to one canonical form: - - >>> SpecifierSet(">1.0a1").to_range() == SpecifierSet(">=1.0a2.dev0").to_range() - True - - The opt-in region is part of equality, so ``<=1.0`` (no pre-releases) and - ``<1.0.post0.dev0`` (autodetects a ``.dev`` opt-in) cover the same - versions yet compare unequal: - - >>> le, lt = SpecifierSet("<=1.0"), SpecifierSet("<1.0.post0.dev0") - >>> le.to_range() == lt.to_range() - False - - >>> r = SpecifierSet(">=1.0,<2.0").to_range() - >>> r == SpecifierSet(">=1.0,<2.0").to_range() - True - """ - if not isinstance(other, VersionRange): - return NotImplemented - return ( - self._bounds == other._bounds - and self._admit == other._admit - and self._reject == other._reject - and self._admit_arbitrary == other._admit_arbitrary - and self._prereleases_configured == other._prereleases_configured - and self._pre_region == other._pre_region - ) - - def __hash__(self) -> int: - return hash( - ( - self._bounds, - self._admit, - self._reject, - self._admit_arbitrary, - self._prereleases_configured, - self._pre_region, - ) - ) - - def __repr__(self) -> str: - """Human-readable representation for debugging. - - >>> SpecifierSet(">=1.0,<2.0").to_range() - - >>> SpecifierSet("").to_range() - - >>> SpecifierSet(">=2.0,<1.0").to_range() - - """ - # Body: the bounds and any ``===``-admitted literals. - parts: list[str] = [] - if self._bounds: - parts.append(_format_intervals(self._bounds)) - if self._admit: - parts.append("{" + ", ".join(sorted(self._admit)) + "}") - body = " | ".join(parts) if parts else "(empty)" - - # Rejected literals subtract from the body. - if self._reject: - body = f"{body} \\ {{{', '.join(sorted(self._reject))}}}" - - # Tail: the policy flags carried alongside the version set. - tail = "" - if self._admit_arbitrary: - tail += " arbitrary" - if self._prereleases_configured is not None: - tail += f" pre={self._prereleases_configured}" - if self._pre_region: - tail += f" pre-region={_format_intervals(self._pre_region)!r}" - - return f"<{self.__class__.__name__} {body!r}{tail}>" diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py deleted file mode 100644 index adcc8adbb74..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/requirements.py +++ /dev/null @@ -1,192 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -from __future__ import annotations - -from typing import TYPE_CHECKING - -from ._parser import parse_requirement as _parse_requirement -from ._tokenizer import ParserSyntaxError -from .markers import Marker, _normalize_extra_values -from .specifiers import InvalidSpecifier, SpecifierSet -from .utils import canonicalize_name - -if TYPE_CHECKING: - from collections.abc import Iterator - -__all__ = [ - "InvalidRequirement", - "Requirement", -] - - -def __dir__() -> list[str]: - return __all__ - - -class InvalidRequirement(ValueError): - """ - An invalid requirement was found, users should refer to PEP 508. - - .. versionadded:: 16.1 - """ - - -class Requirement: - """Parse a requirement. - - Parse a given requirement string into its parts, such as name, specifier, - URL, and extras. Raises InvalidRequirement on a badly-formed requirement - string. - - .. versionadded:: 16.1 - - .. versionchanged:: 22.0 - Added equality (``__eq__``) and hashing (``__hash__``) so requirements - can be compared and stored in sets / dicts. - - .. versionchanged:: 23.2 - Equality and hashing began canonicalizing requirement names, so - requirements whose names differ only by normalization (e.g. - ``Requirement("Foo")`` vs ``Requirement("foo")``) now compare and hash - equal. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from packaging < 26.2 is supported but may be removed in a future - release. - - .. versionchanged:: 26.3 - - The dedicated pickle support introduced in 26.2 did not preserve the - specifier's explicit :attr:`~packaging.specifiers.SpecifierSet.prereleases` - override; it is now included again. - - Equality and hashing normalize requirement names, extras, and - equivalent specifiers. The string representation still preserves the - parsed name and extras spelling. - """ - - # TODO: Can we test whether something is contained within a requirement? - # If so how do we do that? Do we need to test against the _name_ of - # the thing as well as the version? What about the markers? - # TODO: Can we normalize the name and extra name? - - __slots__ = ("extras", "marker", "name", "specifier", "url") - - def __init__(self, requirement_string: str) -> None: - try: - parsed = _parse_requirement(requirement_string) - except ParserSyntaxError as e: - raise InvalidRequirement(str(e)) from e - - self.name: str = parsed.name - self.url: str | None = parsed.url or None - self.extras: set[str] = set(parsed.extras) - try: - self.specifier: SpecifierSet = SpecifierSet(parsed.specifier) - except InvalidSpecifier as e: - raise InvalidRequirement(str(e)) from e - self.marker: Marker | None = None - if parsed.marker is not None: - self.marker = Marker.__new__(Marker) - self.marker._markers = _normalize_extra_values(parsed.marker) - - def _iter_parts(self, name: str) -> Iterator[str]: - yield name - - if self.extras: - formatted_extras = ",".join(sorted(self.extras)) - yield f"[{formatted_extras}]" - - if self.specifier: - yield str(self.specifier) - - if self.url: - yield f" @ {self.url}" - if self.marker: - yield " " - - if self.marker: - yield f"; {self.marker}" - - def __getstate__(self) -> tuple[str, bool | None]: - # Return the requirement string for compactness and stability, paired - # with the specifier's explicit prereleases override, which is not - # captured by the string form. Re-parsed on load to reconstruct all - # other fields. - return (str(self), self.specifier._prereleases) - - def __setstate__(self, state: object) -> None: - if isinstance(state, str): - # Format (26.2): just the requirement string. - requirement_string: str = state - prereleases: bool | None = None - elif ( - isinstance(state, tuple) - and len(state) == 2 - and isinstance(state[0], str) - and (state[1] is None or isinstance(state[1], bool)) - ): - # New format (26.3+): (requirement string, specifier prereleases). - requirement_string, prereleases = state - elif isinstance(state, dict) and state.keys() >= set(self.__slots__): - # Old format (packaging <= 26.1, no __slots__): plain __dict__. - for key in self.__slots__: - setattr(self, key, state[key]) - return - else: - raise TypeError(f"Cannot restore Requirement from {state!r}") - - try: - tmp = Requirement(requirement_string) - except InvalidRequirement as exc: - raise TypeError(f"Cannot restore Requirement from {state!r}") from exc - self.name = tmp.name - self.url = tmp.url - self.extras = tmp.extras - self.specifier = tmp.specifier - self.specifier._prereleases = prereleases - self.marker = tmp.marker - - def __str__(self) -> str: - return "".join(self._iter_parts(self.name)) - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}({str(self)!r})>" - - def __hash__(self) -> int: - # Mirror __eq__ by hashing the canonical specifier object rather than - # its raw string. ``_iter_parts`` yields ``str(self.specifier)``, which - # is non-canonical, so trailing-zero-equivalent requirements such as - # ``foo==1.0.0`` and ``foo==1.0.0.0`` (which compare equal) would - # otherwise hash differently, breaking the hash/__eq__ invariant. - return hash( - ( - canonicalize_name(self.name), - frozenset(canonicalize_name(e) for e in self.extras), - self.specifier, - self.url, - self.marker, - ) - ) - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Requirement): - return NotImplemented - - # Extras must be normalized before comparison as per PEP 685. - self_extras = frozenset(canonicalize_name(e) for e in self.extras) - other_extras = frozenset(canonicalize_name(e) for e in other.extras) - return ( - canonicalize_name(self.name) == canonicalize_name(other.name) - and self_extras == other_extras - and self.specifier == other.specifier - and self.url == other.url - and self.marker == other.marker - ) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py deleted file mode 100644 index 5128e306e47..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/specifiers.py +++ /dev/null @@ -1,1457 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -""" -.. testsetup:: - - from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier - from packaging.version import Version -""" - -from __future__ import annotations - -import abc -import re -import typing -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Final, - TypeVar, - Union, -) - -from ._ranges import ( - FULL_RANGE, - bounds_for_spec, - coerce_version, - filter_by_ranges, - intersect_specifier_bounds, - matches_bounds_only, - ranges_are_prerelease_only, - resolve_prereleases, - trim_release, -) -from .utils import canonicalize_version -from .version import Version - -if TYPE_CHECKING: - import sys - from collections.abc import Iterable, Iterator, Sequence - - if sys.version_info >= (3, 10): - from typing import TypeGuard - else: - from opentelemetry.agent._vendor.typing_extensions import TypeGuard - - from . import ranges - from ._ranges import Interval - - -__all__ = [ - "BaseSpecifier", - "InvalidSpecifier", - "Specifier", - "SpecifierSet", -] - - -def __dir__() -> list[str]: - return __all__ - - -def _validate_spec(spec: object, /) -> TypeGuard[tuple[str, str]]: - return ( - isinstance(spec, tuple) - and len(spec) == 2 - and isinstance(spec[0], str) - and isinstance(spec[1], str) - ) - - -def _validate_pre(pre: object, /) -> TypeGuard[bool | None]: - return pre is None or isinstance(pre, bool) - - -T = TypeVar("T") -UnparsedVersion = Union[Version, str] -UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion) - - -# Operators whose result is just a direct Version comparison, given a parsed -# item with no local. ``<=``/``==``/``!=`` need that no-local guard because -# PEP 440 strips locals on those; ``>=`` works regardless. -_DIRECT_COMPARE_OPS: dict[str, Callable[[Version, Version], bool]] = { - ">=": Version.__ge__, - "<=": Version.__le__, - "==": Version.__eq__, - "!=": Version.__ne__, -} - - -def _fast_match(specifier: Specifier, parsed: Version) -> bool | None: - """Match ``parsed`` against ``specifier`` without building a range. - - Handles ``>=``, ``<=``, ``==``, ``!=``, ``<``, ``>`` when the spec is - not a wildcard and ``parsed`` has no local. Returns ``None`` when the - range path must be used. Pre-release policy is left to the caller. - """ - op_str, ver_str = specifier._spec - if ver_str.endswith(".*") or parsed.local is not None: - return None - - direct_compare = _DIRECT_COMPARE_OPS.get(op_str) - if direct_compare is not None: - return direct_compare(parsed, specifier._require_spec_version(ver_str)) - - if op_str in ("<", ">"): - spec_v = specifier._require_spec_version(ver_str) - # ``V`` carve out V's family (pre/dev/post); that only - # matters when parsed shares V's epoch and trimmed release. - # Otherwise a direct cmpkey comparison is correct. - if parsed.epoch != spec_v.epoch or trim_release(parsed.release) != trim_release( - spec_v.release - ): - return parsed < spec_v if op_str == "<" else parsed > spec_v - return None - - return None - - -class InvalidSpecifier(ValueError): - """ - Raised when attempting to create a :class:`Specifier` with a specifier - string that is invalid. - - >>> Specifier("lolwat") - Traceback (most recent call last): - ... - packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat' - """ - - -class BaseSpecifier(metaclass=abc.ABCMeta): - """ - Abstract base class for :class:`Specifier` and :class:`SpecifierSet`. - """ - - __slots__ = () - __match_args__ = ("_str",) - - @property - def _str(self) -> str: - """Internal property for match_args""" - return str(self) - - @abc.abstractmethod - def __str__(self) -> str: - """ - Returns the str representation of this Specifier-like object. This - should be representative of the Specifier itself. - """ - - @abc.abstractmethod - def __hash__(self) -> int: - """ - Returns a hash value for this Specifier-like object. - """ - - @abc.abstractmethod - def __eq__(self, other: object) -> bool: - """ - Returns a boolean representing whether or not the two Specifier-like - objects are equal. - - :param other: The other object to check against. - """ - - @property - @abc.abstractmethod - def prereleases(self) -> bool | None: - """Whether or not pre-releases as a whole are allowed. - - This can be set to either ``True`` or ``False`` to explicitly enable or disable - prereleases or it can be set to ``None`` (the default) to use default semantics. - """ - - @prereleases.setter # noqa: B027 - def prereleases(self, value: bool) -> None: - """Setter for :attr:`prereleases`. - - :param value: The value to set. - """ - - @abc.abstractmethod - def contains(self, item: str, prereleases: bool | None = None) -> bool: - """ - Determines if the given item is contained within this specifier. - """ - - @typing.overload - def filter( - self, - iterable: Iterable[UnparsedVersionVar], - prereleases: bool | None = None, - key: None = ..., - ) -> Iterator[UnparsedVersionVar]: ... - - @typing.overload - def filter( - self, - iterable: Iterable[T], - prereleases: bool | None = None, - key: Callable[[T], UnparsedVersion] = ..., - ) -> Iterator[T]: ... - - @abc.abstractmethod - def filter( - self, - iterable: Iterable[Any], - prereleases: bool | None = None, - key: Callable[[Any], UnparsedVersion] | None = None, - ) -> Iterator[Any]: - """ - Takes an iterable of items and filters them so that only items which - are contained within this specifier are allowed in it. - """ - - -class Specifier(BaseSpecifier): - """This class abstracts handling of version specifiers. - - .. tip:: - - It is generally not required to instantiate this manually. You should instead - prefer to work with :class:`SpecifierSet` instead, which can parse - comma-separated version specifiers (which is what package metadata contains). - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ( - "_prereleases", - "_ranges", - "_spec", - "_spec_version", - ) - - _specifier_regex_str = r""" - (?: - (?: - # The identity operators allow for an escape hatch that will - # do an exact string match of the version you wish to install. - # This will not be parsed by PEP 440 and we cannot determine - # any semantic meaning from it. This operator is discouraged - # but included entirely as an escape hatch. - === # Only match for the identity operator - \s* - [^\s;)]* # The arbitrary version can be just about anything, - # we match everything except for whitespace, a - # semi-colon for marker support, and a closing paren - # since versions can be enclosed in them. - ) - | - (?: - # The (non)equality operators allow for wild card and local - # versions to be specified so we have to define these two - # operators separately to enable that. - (?:==|!=) # Only match for equals and not equals - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)* # release - - # You cannot use a wild card and a pre-release, post-release, a dev or - # local version together so group them with a | and make them optional. - (?: - \.\* # Wild card syntax of .* - | - (?a: # pre release - [-_\.]? - (alpha|beta|preview|pre|a|b|c|rc) - [-_\.]? - [0-9]* - )? - (?a: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?a:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - (?a:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local - )? - ) - | - (?: - # The compatible operator requires at least two digits in the - # release segment. - (?:~=) # Only match for the compatible operator - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) - (?: # pre release - [-_\.]? - (alpha|beta|preview|pre|a|b|c|rc) - [-_\.]? - [0-9]* - )? - (?: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - ) - | - (?: - # All other operators only allow a sub set of what the - # (non)equality operators do. Specifically they do not allow - # local versions to be specified nor do they allow the prefix - # matching wild cards. - (?:<=|>=|<|>) - - \s* - v? - (?:[0-9]+!)? # epoch - [0-9]+(?:\.[0-9]+)* # release - (?a: # pre release - [-_\.]? - (alpha|beta|preview|pre|a|b|c|rc) - [-_\.]? - [0-9]* - )? - (?a: # post release - (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) - )? - (?a:[-_\.]?dev[-_\.]?[0-9]*)? # dev release - ) - ) - """ - - _regex = re.compile( - r"\s*" + _specifier_regex_str + r"\s*", re.VERBOSE | re.IGNORECASE - ) - - # Legacy unused attribute, kept for backward compatibility - _operators: Final = { - "~=": "compatible", - "==": "equal", - "!=": "not_equal", - "<=": "less_than_equal", - ">=": "greater_than_equal", - "<": "less_than", - ">": "greater_than", - "===": "arbitrary", - } - - def __init__(self, spec: str = "", prereleases: bool | None = None) -> None: - """Initialize a Specifier instance. - - :param spec: - The string representation of a specifier which will be parsed and - normalized before use. - :param prereleases: - This tells the specifier if it should accept prerelease versions if - applicable or not. The default of ``None`` will autodetect it from the - given specifiers. - :raises InvalidSpecifier: - If the given specifier is invalid (i.e. bad syntax). - """ - if not self._regex.fullmatch(spec): - raise InvalidSpecifier(f"Invalid specifier: {spec!r}") - - spec = spec.strip() - if spec.startswith("==="): - operator, version = spec[:3], spec[3:].strip() - elif spec.startswith(("~=", "==", "!=", "<=", ">=")): - operator, version = spec[:2], spec[2:].strip() - else: - operator, version = spec[:1], spec[1:].strip() - - self._spec: tuple[str, str] = (operator, version) - - # Store whether or not this Specifier should accept prereleases - self._prereleases = prereleases - - # Specifier version cache - self._spec_version: tuple[str, Version] | None = None - - # Version range cache (populated by _to_ranges) - self._ranges: Sequence[Interval] | None = None - - def _get_spec_version(self, version: str) -> Version | None: - """One element cache, as only one spec Version is needed per Specifier.""" - if self._spec_version is not None and self._spec_version[0] == version: - return self._spec_version[1] - - version_specifier = coerce_version(version) - if version_specifier is None: - return None - - self._spec_version = (version, version_specifier) - return version_specifier - - def _require_spec_version(self, version: str) -> Version: - """Get spec version, asserting it's valid (not for === operator). - - This method should only be called for operators where version - strings are guaranteed to be valid PEP 440 versions (not ===). - """ - spec_version = self._get_spec_version(version) - assert spec_version is not None - return spec_version - - def _to_ranges(self) -> Sequence[Interval]: - """Convert this specifier to sorted, non-overlapping version ranges. - - Each standard operator maps to one or two ranges. ``===`` is - modeled as full range (actual check done separately). Cached. - """ - if self._ranges is not None: - return self._ranges - - op = self.operator - ver_str = self.version - - if op == "===": - result: Sequence[Interval] = FULL_RANGE - else: - version = self._require_spec_version(ver_str.removesuffix(".*")) - result = bounds_for_spec(op, ver_str, version) - - self._ranges = result - return result - - @property - def prereleases(self) -> bool | None: - # If there is an explicit prereleases set for this, then we'll just - # blindly use that. - if self._prereleases is not None: - return self._prereleases - - # Only the "!=" operator does not imply prereleases when - # the version in the specifier is a prerelease. - operator, version_str = self._spec - if operator == "!=": - return False - - # The == specifier with trailing .* cannot include prereleases - # e.g. "==1.0a1.*" is not valid. - if operator == "==" and version_str.endswith(".*"): - return False - - # "===" can have arbitrary string versions, so we cannot parse - # those, we take prereleases as unknown (None) for those. - version = self._get_spec_version(version_str) - if version is None: - return None - - # For all other operators, use the check if spec Version - # object implies pre-releases. - return version.is_prerelease - - @prereleases.setter - def prereleases(self, value: bool | None) -> None: - self._prereleases = value - - def __getstate__(self) -> tuple[tuple[str, str], bool | None]: - # Return state as a 2-item tuple for compactness: - # ((operator, version), prereleases) - # Cache members are excluded and will be recomputed on demand. - return (self._spec, self._prereleases) - - def __setstate__(self, state: object) -> None: - # Always discard cached values - they will be recomputed on demand. - self._spec_version = None - self._ranges = None - - if isinstance(state, tuple): - if len(state) == 2: - # New format (26.2+): ((operator, version), prereleases) - spec, prereleases = state - if _validate_spec(spec) and _validate_pre(prereleases): - self._spec = spec - self._prereleases = prereleases - return - if len(state) == 2 and isinstance(state[1], dict): - # Format (packaging 26.0-26.1): (None, {slot: value}). - _, slot_dict = state - spec = slot_dict.get("_spec") - prereleases = slot_dict.get("_prereleases", "invalid") - if _validate_spec(spec) and _validate_pre(prereleases): - self._spec = spec - self._prereleases = prereleases - return - if isinstance(state, dict): - # Old format (packaging <= 25.x, no __slots__): state is a plain dict. - spec = state.get("_spec") - prereleases = state.get("_prereleases", "invalid") - if _validate_spec(spec) and _validate_pre(prereleases): - self._spec = spec - self._prereleases = prereleases - return - - raise TypeError(f"Cannot restore Specifier from {state!r}") - - @property - def operator(self) -> str: - """The operator of this specifier. - - >>> Specifier("==1.2.3").operator - '==' - """ - return self._spec[0] - - @property - def version(self) -> str: - """The version of this specifier. - - >>> Specifier("==1.2.3").version - '1.2.3' - """ - return self._spec[1] - - def __repr__(self) -> str: - """A representation of the Specifier that shows all internal state. - - >>> Specifier('>=1.0.0') - =1.0.0')> - >>> Specifier('>=1.0.0', prereleases=False) - =1.0.0', prereleases=False)> - >>> Specifier('>=1.0.0', prereleases=True) - =1.0.0', prereleases=True)> - """ - pre = ( - f", prereleases={self.prereleases!r}" - if self._prereleases is not None - else "" - ) - - return f"<{self.__class__.__name__}({str(self)!r}{pre})>" - - def __str__(self) -> str: - """A string representation of the Specifier that can be round-tripped. - - >>> str(Specifier('>=1.0.0')) - '>=1.0.0' - >>> str(Specifier('>=1.0.0', prereleases=False)) - '>=1.0.0' - """ - return "{}{}".format(*self._spec) - - @property - def _canonical_spec(self) -> tuple[str, str]: - operator, version = self._spec - if operator == "===" or version.endswith(".*"): - return operator, version - - spec_version = self._require_spec_version(version) - - canonical_version = canonicalize_version( - spec_version, strip_trailing_zero=(operator != "~=") - ) - - return operator, canonical_version - - def __hash__(self) -> int: - return hash(self._canonical_spec) - - def __eq__(self, other: object) -> bool: - """Whether or not the two Specifier-like objects are equal. - - :param other: The other object to check against. - - The value of :attr:`prereleases` is ignored. - - >>> Specifier("==1.2.3") == Specifier("== 1.2.3.0") - True - >>> (Specifier("==1.2.3", prereleases=False) == - ... Specifier("==1.2.3", prereleases=True)) - True - >>> Specifier("==1.2.3") == "==1.2.3" - True - >>> Specifier("==1.2.3") == Specifier("==1.2.4") - False - >>> Specifier("==1.2.3") == Specifier("~=1.2.3") - False - """ - if isinstance(other, str): - try: - other = self.__class__(str(other)) - except InvalidSpecifier: - return NotImplemented - elif not isinstance(other, self.__class__): - return NotImplemented - - return self._canonical_spec == other._canonical_spec - - def __contains__(self, item: str | Version) -> bool: - """Return whether or not the item is contained in this specifier. - - :param item: The item to check for. - - This is used for the ``in`` operator and behaves the same as - :meth:`contains` with no ``prereleases`` argument passed. - - >>> "1.2.3" in Specifier(">=1.2.3") - True - >>> Version("1.2.3") in Specifier(">=1.2.3") - True - >>> "1.0.0" in Specifier(">=1.2.3") - False - >>> "1.3.0a1" in Specifier(">=1.2.3") - True - >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True) - True - """ - return self.contains(item) - - def contains(self, item: UnparsedVersion, prereleases: bool | None = None) -> bool: - """Return whether or not the item is contained in this specifier. - - :param item: - The item to check for, which can be a version string or a - :class:`~packaging.version.Version` instance. - :param prereleases: - Whether or not to match prereleases with this Specifier. If set to - ``None`` (the default), it will follow the recommendation from - :pep:`440` and match prereleases, as there are no other versions. - - >>> Specifier(">=1.2.3").contains("1.2.3") - True - >>> Specifier(">=1.2.3").contains(Version("1.2.3")) - True - >>> Specifier(">=1.2.3").contains("1.0.0") - False - >>> Specifier(">=1.2.3").contains("1.3.0a1") - True - >>> Specifier(">=1.2.3", prereleases=False).contains("1.3.0a1") - False - >>> Specifier(">=1.2.3").contains("1.3.0a1") - True - - .. versionchanged:: 26.0 - - With ``prereleases=None``, a prerelease now matches. A single - version has no alternatives, so the :pep:`440` rule to accept - prereleases when nothing else satisfies the specifier applies. - Earlier versions rejected it. An unparsable version now returns - ``False`` instead of raising :exc:`~packaging.version.InvalidVersion`. - """ - # ``===`` compares the raw string, so a Version parse here would - # be wasted. - if self._spec[0] == "===": - return bool(list(self.filter([item], prereleases=prereleases))) - - parsed = coerce_version(item) - if parsed is None: - # Standard operators never match an unparsable input. - return False - - if prereleases is None: - prereleases = resolve_prereleases(self._prereleases, self.prereleases) - - if prereleases is False and parsed.is_prerelease: - return False - - # ``_fast_match`` answers the simple operators without building a - # range; otherwise fall back to the engine's bounds membership. - match = _fast_match(self, parsed) - if match is not None: - return match - - return matches_bounds_only(self._to_ranges(), parsed) - - @typing.overload - def filter( - self, - iterable: Iterable[UnparsedVersionVar], - prereleases: bool | None = None, - key: None = ..., - ) -> Iterator[UnparsedVersionVar]: ... - - @typing.overload - def filter( - self, - iterable: Iterable[T], - prereleases: bool | None = None, - key: Callable[[T], UnparsedVersion] = ..., - ) -> Iterator[T]: ... - - def filter( - self, - iterable: Iterable[Any], - prereleases: bool | None = None, - key: Callable[[Any], UnparsedVersion] | None = None, - ) -> Iterator[Any]: - """Filter items in the given iterable, that match the specifier. - - :param iterable: - An iterable that can contain version strings and - :class:`~packaging.version.Version` instances. The items in the - iterable will be filtered according to the specifier. - :param prereleases: - Whether or not to allow prereleases in the returned iterator. If set to - ``None`` (the default), it will follow the recommendation from :pep:`440` - and match prereleases if there are no other versions. - :param key: - A callable that takes a single argument (an item from the iterable) and - returns a version string or :class:`~packaging.version.Version` - instance to be used for filtering. - - >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) - ['1.3'] - >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")])) - ['1.2.3', '1.3', ] - >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"])) - ['1.5a1'] - >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) - ['1.3', '1.5a1'] - >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) - ['1.3', '1.5a1'] - >>> list(Specifier(">=1.2.3").filter( - ... [{"ver": "1.2"}, {"ver": "1.3"}], - ... key=lambda x: x["ver"])) - [{'ver': '1.3'}] - - .. versionchanged:: 26.1 - - Added the ``key`` parameter. - """ - if prereleases is None: - prereleases = resolve_prereleases(self._prereleases, self.prereleases) - - if self.operator == "===": - spec_lower = self.version.lower() - matches = ( - item - for item in iterable - if str(item if key is None else key(item)).lower() == spec_lower - ) - return _apply_prereleases_filter(matches, key, prereleases) - - return filter_by_ranges(self._to_ranges(), iterable, key, prereleases) - - -def _apply_prereleases_filter( - matches: Iterable[Any], - key: Callable[[Any], UnparsedVersion] | None, - prereleases: bool | None, -) -> Iterator[Any]: - """Apply ``prereleases=`` handling to an already-matched iterable. - - ``None`` means PEP 440 default (buffer pre-releases until a final - appears); ``True`` yields everything; ``False`` drops pre-releases. - """ - if prereleases is None: - return _pep440_filter_prereleases(matches, key) - if prereleases: - return iter(matches) - return ( - item - for item in matches - if (parsed := coerce_version(item if key is None else key(item))) is None - or not parsed.is_prerelease - ) - - -class SpecifierSet(BaseSpecifier): - """This class abstracts handling of a set of version specifiers. - - It can be passed a single specifier (``>=3.0``), a comma-separated list of - specifiers (``>=3.0,!=3.1``), or no specifier at all. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging - releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with - packaging 26.2+ can be unpickled with future releases. - Backward compatibility with pickles from - packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ( - "_canonicalized", - "_has_arbitrary", - "_is_unsatisfiable", - "_prereleases", - "_ranges", - "_specs", - ) - - def __init__( - self, - specifiers: str | Iterable[Specifier] = "", - prereleases: bool | None = None, - ) -> None: - """Initialize a SpecifierSet instance. - - :param specifiers: - The string representation of a specifier or a comma-separated list of - specifiers which will be parsed and normalized before use. - May also be an iterable of ``Specifier`` instances, which will be used - as is. - :param prereleases: - This tells the SpecifierSet if it should accept prerelease versions if - applicable or not. The default of ``None`` will autodetect it from the - given specifiers. - - :raises InvalidSpecifier: - If the given ``specifiers`` are not parseable than this exception will be - raised. - """ - - if isinstance(specifiers, str): - # Split on `,` to break each individual specifier into its own item, and - # strip each item to remove leading/trailing whitespace. - split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] - - self._specs: tuple[Specifier, ...] = tuple(map(Specifier, split_specifiers)) - # Fast substring check; avoids iterating parsed specs. - self._has_arbitrary = "===" in specifiers - else: - self._specs = tuple(specifiers) - # Substring check works for both Specifier objects and plain - # strings (setuptools passes lists of strings). - self._has_arbitrary = any("===" in str(s) for s in self._specs) - - self._canonicalized = len(self._specs) <= 1 - self._is_unsatisfiable: bool | None = None - self._ranges: Sequence[Interval] | None = None - - # Store our prereleases value so we can use it later to determine if - # we accept prereleases or not. - self._prereleases = prereleases - - def _canonical_specs(self) -> tuple[Specifier, ...]: - """Deduplicate, sort, and cache specs for order-sensitive operations.""" - if not self._canonicalized: - self._specs = tuple(dict.fromkeys(sorted(self._specs, key=str))) - self._canonicalized = True - return self._specs - - @property - def prereleases(self) -> bool | None: - # If we have been given an explicit prerelease modifier, then we'll - # pass that through here. - if self._prereleases is not None: - return self._prereleases - - # If we don't have any specifiers, and we don't have a forced value, - # then we'll just return None since we don't know if this should have - # pre-releases or not. - if not self._specs: - return None - - # Otherwise we'll see if any of the given specifiers accept - # prereleases, if any of them do we'll return True, otherwise False. - if any(s.prereleases for s in self._specs): - return True - - return None - - @prereleases.setter - def prereleases(self, value: bool | None) -> None: - self._prereleases = value - self._is_unsatisfiable = None - - def __getstate__(self) -> tuple[tuple[Specifier, ...], bool | None]: - # Return state as a 2-item tuple for compactness: - # (specs, prereleases) - # Cache members are excluded and will be recomputed on demand. - return (self._specs, self._prereleases) - - def __setstate__(self, state: object) -> None: - # Always discard cached values - they will be recomputed on demand. - self._ranges = None - self._is_unsatisfiable = None - - if isinstance(state, tuple): - if len(state) == 2: - # New format (26.2+): (specs, prereleases) - specs, prereleases = state - if ( - isinstance(specs, tuple) - and all(isinstance(s, Specifier) for s in specs) - and _validate_pre(prereleases) - ): - self._specs = specs - self._prereleases = prereleases - self._canonicalized = len(specs) <= 1 - self._has_arbitrary = any("===" in str(s) for s in specs) - return - if len(state) == 2 and isinstance(state[1], dict): - # Format (packaging 26.0-26.1): (None, {slot: value}). - _, slot_dict = state - specs = slot_dict.get("_specs", ()) - prereleases = slot_dict.get("_prereleases") - # Convert frozenset to tuple (26.0 stored as frozenset) - if isinstance(specs, frozenset): - specs = tuple(sorted(specs, key=str)) - if ( - isinstance(specs, tuple) - and all(isinstance(s, Specifier) for s in specs) - and _validate_pre(prereleases) - ): - self._specs = specs - self._prereleases = prereleases - self._canonicalized = len(self._specs) <= 1 - self._has_arbitrary = any("===" in str(s) for s in self._specs) - return - if isinstance(state, dict): - # Old format (packaging <= 25.x, no __slots__): state is a plain dict. - specs = state.get("_specs", ()) - prereleases = state.get("_prereleases") - # Convert frozenset to tuple (26.0 stored as frozenset) - if isinstance(specs, frozenset): - specs = tuple(sorted(specs, key=str)) - if ( - isinstance(specs, tuple) - and all(isinstance(s, Specifier) for s in specs) - and _validate_pre(prereleases) - ): - self._specs = specs - self._prereleases = prereleases - self._canonicalized = len(self._specs) <= 1 - self._has_arbitrary = any("===" in str(s) for s in self._specs) - return - - raise TypeError(f"Cannot restore SpecifierSet from {state!r}") - - def __repr__(self) -> str: - """A representation of the specifier set that shows all internal state. - - Note that the ordering of the individual specifiers within the set may not - match the input string. - - >>> SpecifierSet('>=1.0.0,!=2.0.0') - =1.0.0')> - >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False) - =1.0.0', prereleases=False)> - >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True) - =1.0.0', prereleases=True)> - """ - pre = ( - f", prereleases={self.prereleases!r}" - if self._prereleases is not None - else "" - ) - - return f"<{self.__class__.__name__}({str(self)!r}{pre})>" - - def __str__(self) -> str: - """A string representation of the specifier set that can be round-tripped. - - Note that the ordering of the individual specifiers within the set may not - match the input string. - - >>> str(SpecifierSet(">=1.0.0,!=1.0.1")) - '!=1.0.1,>=1.0.0' - >>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False)) - '!=1.0.1,>=1.0.0' - """ - return ",".join(str(s) for s in self._canonical_specs()) - - def __hash__(self) -> int: - return hash(self._canonical_specs()) - - def __and__(self, other: SpecifierSet | str) -> SpecifierSet: - """Return a SpecifierSet which is a combination of the two sets. - - :param other: The other object to combine with. - - >>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1' - =1.0.0')> - >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1') - =1.0.0')> - """ - if isinstance(other, str): - other = SpecifierSet(other) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - specifier = SpecifierSet() - specifier._specs = self._specs + other._specs - specifier._canonicalized = len(specifier._specs) <= 1 - specifier._has_arbitrary = self._has_arbitrary or other._has_arbitrary - - # Combine prerelease settings: use common or non-None value - if self._prereleases is None or self._prereleases == other._prereleases: - specifier._prereleases = other._prereleases - elif other._prereleases is None: - specifier._prereleases = self._prereleases - else: - raise ValueError( - "Cannot combine SpecifierSets with True and False prerelease overrides." - ) - - return specifier - - def __eq__(self, other: object) -> bool: - """Whether or not the two SpecifierSet-like objects are equal. - - :param other: The other object to check against. - - The value of :attr:`prereleases` is ignored. - - >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) == - ... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)) - True - >>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1" - True - >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0") - False - >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2") - False - """ - if isinstance(other, (str, Specifier)): - other = SpecifierSet(str(other)) - elif not isinstance(other, SpecifierSet): - return NotImplemented - - return self._canonical_specs() == other._canonical_specs() - - def __len__(self) -> int: - """Returns the number of specifiers in this specifier set.""" - return len(self._specs) - - def __iter__(self) -> Iterator[Specifier]: - """ - Returns an iterator over all the underlying :class:`Specifier` instances - in this specifier set. - - >>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str) - [, =1.0.0')>] - """ - return iter(self._specs) - - def _get_ranges(self) -> Sequence[Interval]: - """Intersect all specifiers into a single sequence of version ranges. - - Empty when unsatisfiable. Callers must ensure ``self._specs`` - is non-empty. - """ - if self._ranges is not None: - return self._ranges - - self._ranges = intersect_specifier_bounds(s._to_ranges() for s in self._specs) - return self._ranges - - def is_unsatisfiable(self) -> bool: - """Check whether this specifier set can never be satisfied. - - Returns True if no version can satisfy all specifiers simultaneously. - - >>> SpecifierSet(">=2.0,<1.0").is_unsatisfiable() - True - >>> SpecifierSet(">=1.0,<2.0").is_unsatisfiable() - False - >>> SpecifierSet("").is_unsatisfiable() - False - >>> SpecifierSet("==1.0,!=1.0").is_unsatisfiable() - True - - .. versionadded:: 26.1 - """ - cached = self._is_unsatisfiable - if cached is not None: - return cached - - if not self._specs: - self._is_unsatisfiable = False - return False - - result = not self._get_ranges() - - if not result: - result = self._check_arbitrary_unsatisfiable() - - if not result and self.prereleases is False: - result = ranges_are_prerelease_only(self._get_ranges()) - - self._is_unsatisfiable = result - return result - - def _check_arbitrary_unsatisfiable(self) -> bool: - """Check === (arbitrary equality) specs for unsatisfiability. - - === uses case-insensitive string comparison, so the only candidate - that can match ``===V`` is the literal string V. This method - checks whether that candidate is excluded by other specifiers. - """ - arbitrary = [s for s in self._specs if s.operator == "==="] - if not arbitrary: - return False - - # Multiple === must agree on the same string (case-insensitive). - first = arbitrary[0].version.lower() - if any(s.version.lower() != first for s in arbitrary[1:]): - return True - - # The sole candidate is the === version string. Check whether - # it can satisfy every standard spec. - candidate = coerce_version(arbitrary[0].version) - - # With prereleases=False, a prerelease candidate is excluded - # by contains() before the === string check even runs. - if ( - self.prereleases is False - and candidate is not None - and candidate.is_prerelease - ): - return True - - standard = [s for s in self._specs if s.operator != "==="] - if not standard: - return False - - if candidate is None: - # Unparsable string cannot satisfy any standard spec. - return True - - return not all(s.contains(candidate) for s in standard) - - def to_range(self) -> ranges.VersionRange: - """Return the :class:`~packaging.ranges.VersionRange` this set accepts. - - An empty set yields the full range; an unsatisfiable set yields the - empty range. ``===`` specifiers contribute literal-string admission. - - >>> SpecifierSet(">=1.0,<2.0").to_range() - - - .. versionadded:: 26.3 - """ - from .ranges import VersionRange # noqa: PLC0415 - - return VersionRange._from_specifier_set(self) - - def _check_relation_operand(self, other: object) -> None: - if not isinstance(other, SpecifierSet): - raise TypeError("expected a SpecifierSet") - if self._has_arbitrary or other._has_arbitrary: - raise ValueError("set relations do not support === specifiers") - - def is_subset(self, other: SpecifierSet) -> bool: - """Return whether every version matching this set also matches other. - - :raises ValueError: - If either set uses ``===`` specifiers, or the two sets were - given different ``prereleases`` arguments (unset on one side - counts as different). - :raises TypeError: - If other is not a :class:`SpecifierSet`. - - >>> SpecifierSet(">=3.12,<3.13").is_subset(SpecifierSet(">=3.12")) - True - >>> SpecifierSet(">=3.12").is_subset(SpecifierSet(">=3.12,<3.13")) - False - - .. versionadded:: 26.3 - """ - self._check_relation_operand(other) - return self.to_range().is_subset(other.to_range()) - - def is_superset(self, other: SpecifierSet) -> bool: - """Return whether every version matching other also matches this set. - - :raises ValueError: - If either set uses ``===`` specifiers, or the two sets were - given different ``prereleases`` arguments (unset on one side - counts as different). - :raises TypeError: - If other is not a :class:`SpecifierSet`. - - >>> SpecifierSet(">=3.12").is_superset(SpecifierSet(">=3.12,<3.13")) - True - - .. versionadded:: 26.3 - """ - self._check_relation_operand(other) - return self.to_range().is_superset(other.to_range()) - - def is_disjoint(self, other: SpecifierSet) -> bool: - """Return whether this set and other share no matching versions. - - :raises ValueError: - If either set uses ``===`` specifiers, or the two sets were - given different ``prereleases`` arguments (unset on one side - counts as different). - :raises TypeError: - If other is not a :class:`SpecifierSet`. - - >>> SpecifierSet("<3.12").is_disjoint(SpecifierSet(">=3.12")) - True - >>> SpecifierSet("<3.12").is_disjoint(SpecifierSet(">=3.11")) - False - - .. versionadded:: 26.3 - """ - self._check_relation_operand(other) - return self.to_range().is_disjoint(other.to_range()) - - def __contains__(self, item: UnparsedVersion) -> bool: - """Return whether or not the item is contained in this specifier. - - :param item: The item to check for. - - This is used for the ``in`` operator and behaves the same as - :meth:`contains` with no ``prereleases`` argument passed. - - >>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1") - False - >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1") - True - >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True) - True - """ - return self.contains(item) - - def contains( - self, - item: UnparsedVersion, - prereleases: bool | None = None, - installed: bool | None = None, - ) -> bool: - """Return whether or not the item is contained in this SpecifierSet. - - :param item: - The item to check for, which can be a version string or a - :class:`~packaging.version.Version` instance. - :param prereleases: - Whether or not to match prereleases with this SpecifierSet. If set to - ``None`` (the default), it will follow the recommendation from :pep:`440` - and match prereleases, as there are no other versions. - :param installed: - Whether or not the item is installed. If set to ``True``, it will - accept prerelease versions even if the specifier does not allow them. - - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3") - True - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3")) - True - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1") - False - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1") - True - >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False).contains("1.3.0a1") - False - >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True) - True - - .. versionchanged:: 26.0 - - With ``prereleases=None``, a prerelease now matches. A single - version has no alternatives, so the :pep:`440` rule to accept - prereleases when nothing else satisfies the specifiers applies. - Earlier versions rejected it. An unparsable version now returns - ``False`` instead of raising :exc:`~packaging.version.InvalidVersion`. - """ - version = coerce_version(item) - - if version is not None and installed and version.is_prerelease: - prereleases = True - - # When item is a string and === is involved, keep it as-is - # so the comparison isn't done against the normalized form. - if version is None or (self._has_arbitrary and not isinstance(item, Version)): - check_item = item - else: - check_item = version - - # Fast path: a parseable, local-free version against a rangelike set. - # A local on ``version`` needs PEP 440 stripping that the range path - # applies. - if ( - version is not None - and not self._has_arbitrary - and version.local is None - and self._specs - ): - if version.is_prerelease and ( - prereleases is False - or (prereleases is None and self._prereleases is False) - ): - return False - - bounds = self._ranges - if bounds is None: - # Per-spec ``_fast_match`` answers a set of simple specifiers - # without folding anything. If a spec needs the range path, - # fold the intersected bounds once and cache them so repeated - # checks on the same set stay cheap. - for spec in self._specs: - match = _fast_match(spec, version) - if match is None: - break - if not match: - return False - else: - return True - - bounds = self._ranges = self._get_ranges() - - return matches_bounds_only(bounds, version) - - return bool(list(self.filter([check_item], prereleases=prereleases))) - - @typing.overload - def filter( - self, - iterable: Iterable[UnparsedVersionVar], - prereleases: bool | None = None, - key: None = ..., - ) -> Iterator[UnparsedVersionVar]: ... - - @typing.overload - def filter( - self, - iterable: Iterable[T], - prereleases: bool | None = None, - key: Callable[[T], UnparsedVersion] = ..., - ) -> Iterator[T]: ... - - def filter( - self, - iterable: Iterable[Any], - prereleases: bool | None = None, - key: Callable[[Any], UnparsedVersion] | None = None, - ) -> Iterator[Any]: - """Filter items in the given iterable, that match the specifiers in this set. - - :param iterable: - An iterable that can contain version strings and - :class:`~packaging.version.Version` instances. The items in the - iterable will be filtered according to the specifier. - :param prereleases: - Whether or not to allow prereleases in the returned iterator. If set to - ``None`` (the default), it will follow the recommendation from :pep:`440` - and match prereleases if there are no other versions. - :param key: - A callable that takes a single argument (an item from the iterable) and - returns a version string or :class:`~packaging.version.Version` - instance to be used for filtering. - - >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"])) - ['1.3'] - >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")])) - ['1.3', ] - >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"])) - ['1.5a1'] - >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True)) - ['1.3', '1.5a1'] - >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"])) - ['1.3', '1.5a1'] - >>> list(SpecifierSet(">=1.2.3").filter( - ... [{"ver": "1.2"}, {"ver": "1.3"}], - ... key=lambda x: x["ver"])) - [{'ver': '1.3'}] - - An "empty" SpecifierSet will filter items based on the presence of prerelease - versions in the set. - - >>> list(SpecifierSet("").filter(["1.3", "1.5a1"])) - ['1.3'] - >>> list(SpecifierSet("").filter(["1.5a1"])) - ['1.5a1'] - >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"])) - ['1.3', '1.5a1'] - >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True)) - ['1.3', '1.5a1'] - - .. versionchanged:: 26.0 - - Prerelease filtering now follows the PEP 440 recommendation of - yielding prereleases only when no final release is present. - - .. versionchanged:: 26.1 - - Added the ``key`` parameter. - """ - # Determine if we're forcing a prerelease or not, if we're not forcing - # one for this particular filter call, then we'll use whatever the - # SpecifierSet thinks for whether or not we should support prereleases. - if prereleases is None and self.prereleases is not None: - prereleases = self.prereleases - - if self._specs: - if self._has_arbitrary: - # Slow path for === - specs = self._specs - matches = ( - item - for item in iterable - if all( - s.contains(item if key is None else key(item), prereleases=True) - for s in specs - ) - ) - return _apply_prereleases_filter(matches, key, prereleases) - - ranges = self._ranges - if ranges is None: - ranges = self._get_ranges() - return filter_by_ranges(ranges, iterable, key, prereleases) - - # Empty SpecifierSet. - return _apply_prereleases_filter(iterable, key, prereleases) - - -def _pep440_filter_prereleases( - iterable: Iterable[Any], key: Callable[[Any], UnparsedVersion] | None -) -> Iterator[Any]: - """Filter per PEP 440: exclude prereleases unless no finals exist.""" - # Two lists used: - # * all_nonfinal to preserve order if no finals exist - # * arbitrary_strings for streaming when first final found - all_nonfinal: list[Any] = [] - arbitrary_strings: list[Any] = [] - - found_final = False - for item in iterable: - parsed = coerce_version(item if key is None else key(item)) - - if parsed is None: - # Arbitrary strings are always included as it is not - # possible to determine if they are prereleases, - # and they have already passed all specifiers. - if found_final: - yield item - else: - arbitrary_strings.append(item) - all_nonfinal.append(item) - continue - - if not parsed.is_prerelease: - # Final release found - flush arbitrary strings, then yield - if not found_final: - yield from arbitrary_strings - found_final = True - yield item - continue - - # Prerelease - buffer if no finals yet, otherwise skip - if not found_final: - all_nonfinal.append(item) - - # No finals found - yield all buffered items - if not found_final: - yield from all_nonfinal diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py deleted file mode 100644 index dd1ea911e17..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/tags.py +++ /dev/null @@ -1,1053 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import annotations - -import logging -import operator -import platform -import re -import struct -import subprocess -import sys -import sysconfig -from collections.abc import Iterable, Iterator, Sequence -from importlib.machinery import EXTENSION_SUFFIXES -from typing import ( - TYPE_CHECKING, - TypeVar, - cast, -) - -from . import _manylinux, _musllinux - -if TYPE_CHECKING: - from collections.abc import Callable - from collections.abc import Set as AbstractSet - - -__all__ = [ - "INTERPRETER_SHORT_NAMES", - "AppleVersion", - "InvalidTag", - "PythonVersion", - "Tag", - "TooManyTagsError", - "UnsortedTagsError", - "android_platforms", - "compatible_tags", - "cpython_tags", - "create_compatible_tags_selector", - "generic_tags", - "interpreter_name", - "interpreter_version", - "ios_platforms", - "mac_platforms", - "parse_tag", - "platform_tags", - "pure_python_tags", - "sys_tags", -] - - -def __dir__() -> list[str]: - return __all__ - - -logger = logging.getLogger(__name__) - -PythonVersion = Sequence[int] -""" -A sequence of integers describing a Python version, e.g. ``(3, 13)``. - -.. versionadded:: 20.0 -""" - -AppleVersion = tuple[int, int] -""" -A ``(major, minor)`` integer pair describing an Apple OS version. - -.. versionadded:: 24.2 -""" -_T = TypeVar("_T") - -INTERPRETER_SHORT_NAMES: dict[str, str] = { - "python": "py", # Generic. - "cpython": "cp", - "pypy": "pp", - "ironpython": "ip", - "jython": "jy", -} - - -# This function can be unit tested without reloading the module -# (Unlike _32_BIT_INTERPRETER) -def _compute_32_bit_interpreter() -> bool: - return struct.calcsize("P") == 4 - - -_32_BIT_INTERPRETER = _compute_32_bit_interpreter() - - -class UnsortedTagsError(ValueError): - """ - Raised when a tag component is not in sorted order per PEP 425. - - .. versionadded:: 26.1 - """ - - -class InvalidTag(ValueError): - """ - Raised when an interpreter component is not an identifier, a tag component - is empty, or a tag does not have exactly three components. - - .. versionadded:: 26.3 - """ - - -class TooManyTagsError(ValueError): - """ - Raised when a compressed tag set exceeds the configured limit. - - .. versionadded:: 26.3 - """ - - -class Tag: - """ - A representation of the tag triple for a wheel. - - Instances are considered immutable and thus are hashable. Equality checking - is also supported. - - Instances are safe to serialize with :mod:`pickle`. They use a stable - format so the same pickle can be loaded in future packaging releases. - - .. versionchanged:: 26.2 - - Added a stable pickle format. Pickles created with packaging 26.2+ can - be unpickled with future releases. Backward compatibility with pickles - from packaging < 26.2 is supported but may be removed in a future - release. - """ - - __slots__ = ["_abi", "_hash", "_interpreter", "_platform"] - - def __init__(self, interpreter: str, abi: str, platform: str) -> None: - """ - :param str interpreter: The interpreter name, e.g. ``"py"`` - (see :attr:`INTERPRETER_SHORT_NAMES` for mapping - well-known interpreter names to their short names). - :param str abi: The ABI that a wheel supports, e.g. ``"cp37m"``. - :param str platform: The OS/platform the wheel supports, - e.g. ``"win_amd64"``. - """ - self._interpreter = interpreter.lower() - self._abi = abi.lower() - self._platform = platform.lower() - # The __hash__ of every single element in a Set[Tag] will be evaluated each time - # that a set calls its `.disjoint()` method, which may be called hundreds of - # times when scanning a page of links for packages with tags matching that - # Set[Tag]. Pre-computing the value here produces significant speedups for - # downstream consumers. - self._hash = hash((self._interpreter, self._abi, self._platform)) - - @property - def interpreter(self) -> str: - """ - The interpreter name, e.g. ``"py"`` (see - :attr:`INTERPRETER_SHORT_NAMES` for mapping well-known interpreter - names to their short names). - """ - return self._interpreter - - @property - def abi(self) -> str: - """ - The supported ABI. - """ - return self._abi - - @property - def platform(self) -> str: - """ - The OS/platform. - """ - return self._platform - - def __eq__(self, other: object) -> bool: - if not isinstance(other, Tag): - return NotImplemented - - return ( - (self._hash == other._hash) # Short-circuit ASAP for perf reasons. - and (self._platform == other._platform) - and (self._abi == other._abi) - and (self._interpreter == other._interpreter) - ) - - def __hash__(self) -> int: - return self._hash - - def __str__(self) -> str: - return f"{self._interpreter}-{self._abi}-{self._platform}" - - def __repr__(self) -> str: - return f"<{self} @ {id(self)}>" - - def __getstate__(self) -> tuple[str, str, str]: - # Return state as a 3-item tuple: (interpreter, abi, platform). - # Cache member _hash is excluded and will be recomputed. - return (self._interpreter, self._abi, self._platform) - - def __setstate__(self, state: object) -> None: - if isinstance(state, tuple): - if len(state) == 3 and all(isinstance(s, str) for s in state): - # New format (26.2+): (interpreter, abi, platform) - self._interpreter, self._abi, self._platform = state - self._hash = hash((self._interpreter, self._abi, self._platform)) - return - if len(state) == 2 and isinstance(state[1], dict): - # Old format (packaging <= 26.1, __slots__): (None, {slot: value}). - _, slots = state - try: - interpreter = slots["_interpreter"] - abi = slots["_abi"] - platform = slots["_platform"] - except KeyError: - raise TypeError(f"Cannot restore Tag from {state!r}") from None - if not all( - isinstance(value, str) for value in (interpreter, abi, platform) - ): - raise TypeError(f"Cannot restore Tag from {state!r}") - self._interpreter = interpreter.lower() - self._abi = abi.lower() - self._platform = platform.lower() - self._hash = hash((self._interpreter, self._abi, self._platform)) - return - raise TypeError(f"Cannot restore Tag from {state!r}") - - -def parse_tag( - tag: str, *, validate_order: bool = False, limit: int | None = None -) -> frozenset[Tag]: - """ - Parses the provided tag (e.g. `py3-none-any`) into a frozenset of - :class:`Tag` instances. - - Returning a set is required due to the possibility that the tag is a - `compressed tag set`_, e.g. ``"py2.py3-none-any"`` which supports both - Python 2 and Python 3. - - If **validate_order** is true, compressed tag set components are checked - to be in sorted order as required by PEP 425. - - If **limit** is not ``None``, the compressed tag set can generate at most - that many tags. - - :param str tag: The tag to parse, e.g. ``"py3-none-any"``. - :param bool validate_order: Check whether compressed tag set components - are in sorted order. - :param int | None limit: The maximum number of tags to parse. - :raises UnsortedTagsError: If **validate_order** is true and any compressed tag - set component is not in sorted order. - :raises InvalidTag: If the interpreter field is not an identifier; if the - interpreter, ABI, or platform field (or any member of a compressed tag - set) is empty; or if the tag does not have exactly three components. - :raises TooManyTagsError: If **limit** is not ``None`` and the compressed tag - set would generate more than **limit** tags. - :raises ValueError: If **limit** is negative. - - .. versionadded:: 26.1 - The *validate_order* parameter. - - .. versionadded:: 26.3 - Raises :class:`InvalidTag` when an interpreter component is not an - identifier, a tag component is empty, or a tag does not have exactly - three components. - Added the *limit* parameter. Raises :class:`TooManyTagsError` if the compressed - tag set would generate more than *limit* tags. - """ - - if limit is not None and limit < 0: - raise ValueError("limit must be non-negative") - - component_parts = [component.split(".") for component in tag.split("-")] - for parts in component_parts: - if "" in parts: - component = ".".join(parts) - raise InvalidTag(f"Tag {tag!r} has an empty component: {component!r}") - if validate_order and parts != sorted(parts): - component = ".".join(parts) - raise UnsortedTagsError( - f"Tag component {component!r} is not in sorted order per PEP 425" - ) - - tag_count = 1 - for parts in component_parts: - tag_count *= len(parts) - - if limit is not None and tag_count > limit: - raise TooManyTagsError( - f"Compressed tag set would generate {tag_count} tags, exceeding " - f"limit {limit}" - ) - - try: - interpreters, abis, platforms = component_parts - except ValueError as exc: - raise InvalidTag(f"Tag {tag!r} must have exactly three components") from exc - for interpreter in interpreters: - if not interpreter.isidentifier(): - raise InvalidTag(f"Tag {tag!r} has an invalid interpreter: {interpreter!r}") - return frozenset( - Tag(interpreter, abi, platform_) - for interpreter in interpreters - for abi in abis - for platform_ in platforms - ) - - -def _get_config_var(name: str, warn: bool = False) -> int | str | None: - value: int | str | None = sysconfig.get_config_var(name) - if value is None and warn: - logger.debug( - "Config variable '%s' is unset, Python ABI tag may be incorrect", name - ) - return value - - -def _normalize_string(string: str) -> str: - return string.replace(".", "_").replace("-", "_").replace(" ", "_") - - -def _is_threaded_cpython(abis: list[str]) -> bool: - """ - Determine if the ABI corresponds to a threaded (`--disable-gil`) build. - - The threaded builds are indicated by a "t" in the abiflags. - """ - if len(abis) == 0: - return False - # expect e.g., cp313 - m = re.match(r"cp\d+(.*)", abis[0]) - if not m: - return False - abiflags = m.group(1) - return "t" in abiflags - - -def _abi3_applies(python_version: PythonVersion, threading: bool) -> bool: - """ - Determine if the Python version supports abi3. - - PEP 384 was first implemented in Python 3.2. The free-threaded - builds do not support abi3. - """ - return len(python_version) > 1 and tuple(python_version) >= (3, 2) and not threading - - -def _abi3t_applies(python_version: PythonVersion, threading: bool) -> bool: - """ - Determine if the Python version supports abi3t. - - PEP 803 was first implemented in Python 3.15 but, per PEP 803, this - returns tags going back to Python 3.2 to mirror the abi3 - implementation and leave open the possibility of abi3t wheels - supporting older Python versions. - - """ - return len(python_version) > 1 and tuple(python_version) >= (3, 2) and threading - - -def _cpython_abis(py_version: PythonVersion, warn: bool = False) -> list[str]: - py_version = tuple(py_version) # To allow for version comparison. - abis = [] - version = _version_nodot(py_version[:2]) - threading = debug = pymalloc = ucs4 = "" - with_debug = _get_config_var("Py_DEBUG", warn) - has_refcount = hasattr(sys, "gettotalrefcount") - # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled - # extension modules is the best option. - # https://github.com/pypa/pip/issues/3383#issuecomment-173267692 - has_ext = "_d.pyd" in EXTENSION_SUFFIXES - if with_debug or (with_debug is None and (has_refcount or has_ext)): - debug = "d" - if py_version >= (3, 13) and _get_config_var("Py_GIL_DISABLED", warn): - threading = "t" - if py_version < (3, 8): - with_pymalloc = _get_config_var("WITH_PYMALLOC", warn) - if with_pymalloc or with_pymalloc is None: - pymalloc = "m" - if py_version < (3, 3): - unicode_size = _get_config_var("Py_UNICODE_SIZE", warn) - if unicode_size == 4 or ( - unicode_size is None and sys.maxunicode == 0x10FFFF - ): - ucs4 = "u" - elif debug: - # Debug builds can also load "normal" extension modules. - # We can also assume no UCS-4 or pymalloc requirement. - abis.append(f"cp{version}{threading}") - abis.insert(0, f"cp{version}{threading}{debug}{pymalloc}{ucs4}") - return abis - - -def cpython_tags( - python_version: PythonVersion | None = None, - abis: Iterable[str] | None = None, - platforms: Iterable[str] | None = None, - *, - warn: bool = False, -) -> Iterator[Tag]: - """ - Yields the tags for the CPython interpreter. - - The specific tags generated are: - - - ``cp--`` - - ``cp--`` - - ``cp-none-`` - - ``cp--`` where "older version" is all older - minor versions down to Python 3.2 (when ``abi3`` was introduced) - - If ``python_version`` only provides a major-only version then only - user-provided ABIs via ``abis`` and the ``none`` ABI will be used. - - The ``stable_abi`` will be either ``abi3`` or ``abi3t`` if `abi` is a - GIL-enabled ABI like `"cp315"` or a free-threaded ABI like `"cp315t"`, - respectively. - - :param Sequence python_version: A one- or two-item sequence representing the - targeted Python version. Defaults to - ``sys.version_info[:2]``. - :param Iterable abis: Iterable of compatible ABIs. Defaults to the ABIs - compatible with the current system. - :param Iterable platforms: Iterable of compatible platforms. Defaults to the - platforms compatible with the current system. - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - - .. versionadded:: 20.0 - """ - if not python_version: - python_version = sys.version_info[:2] - - interpreter = f"cp{_version_nodot(python_version[:2])}" - - if abis is None: - abis = _cpython_abis(python_version, warn) if len(python_version) > 1 else [] - abis = list(abis) - threading = _is_threaded_cpython(abis) - # Stable ABIs and 'none' are explicitly handled later. - explicit_abis = ("abi3", "abi3t", "none") if threading else ("abi3", "none") - for explicit_abi in explicit_abis: - try: - abis.remove(explicit_abi) - except ValueError: # noqa: PERF203 - pass - - platforms = list(platforms or platform_tags()) - for abi in abis: - for platform_ in platforms: - yield Tag(interpreter, abi, platform_) - - use_abi3 = _abi3_applies(python_version, threading) - use_abi3t = _abi3t_applies(python_version, threading) - if use_abi3: - yield from (Tag(interpreter, "abi3", platform_) for platform_ in platforms) - if use_abi3t: - yield from (Tag(interpreter, "abi3t", platform_) for platform_ in platforms) - - yield from (Tag(interpreter, "none", platform_) for platform_ in platforms) - - if use_abi3 or use_abi3t: - for minor_version in range(python_version[1] - 1, 1, -1): - for platform_ in platforms: - version = _version_nodot((python_version[0], minor_version)) - interpreter = f"cp{version}" - if use_abi3: - yield Tag(interpreter, "abi3", platform_) - if use_abi3t: - # Support for abi3t was introduced in Python 3.15, but in - # principle abi3t wheels are possible for older limited API - # versions, so allow things like ("cp37", "abi3t", "platform") - yield Tag(interpreter, "abi3t", platform_) - - -def _generic_abi() -> list[str]: - """ - Return the ABI tag based on EXT_SUFFIX. - """ - # The following are examples of `EXT_SUFFIX`. - # We want to keep the parts which are related to the ABI and remove the - # parts which are related to the platform: - # - linux: '.cpython-310-x86_64-linux-gnu.so' => cp310 - # - mac: '.cpython-310-darwin.so' => cp310 - # - win: '.cp310-win_amd64.pyd' => cp310 - # - win: '.pyd' => cp37 (uses _cpython_abis()) - # - pypy: '.pypy38-pp73-x86_64-linux-gnu.so' => pypy38_pp73 - # - graalpy: '.graalpy-38-native-x86_64-darwin.dylib' - # => graalpy_38_native - - ext_suffix = _get_config_var("EXT_SUFFIX", warn=True) - if not isinstance(ext_suffix, str) or not ext_suffix.startswith("."): - raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')") - parts = ext_suffix.split(".") - if len(parts) < 3: - # CPython3.7 and earlier uses ".pyd" on Windows. - return _cpython_abis(sys.version_info[:2]) - soabi = parts[1] - if soabi.startswith("cpython"): - # non-windows - cpython_parts = soabi.split("-") - if len(cpython_parts) < 2 or not cpython_parts[1]: - raise SystemError("invalid sysconfig.get_config_var('EXT_SUFFIX')") - abi = "cp" + cpython_parts[1] - elif soabi.startswith("cp"): - # windows - abi = soabi.split("-")[0] - elif soabi.startswith("pypy"): - abi = "-".join(soabi.split("-")[:2]) - elif soabi.startswith("graalpy"): - abi = "-".join(soabi.split("-")[:3]) - elif soabi: - # pyston, ironpython, others? - abi = soabi - else: - return [] - return [_normalize_string(abi)] - - -def generic_tags( - interpreter: str | None = None, - abis: Iterable[str] | None = None, - platforms: Iterable[str] | None = None, - *, - warn: bool = False, -) -> Iterator[Tag]: - """ - Yields the tags for an interpreter which requires no specialization. - - This function should be used if one of the other interpreter-specific - functions provided by this module is not appropriate (i.e. not calculating - tags for a CPython interpreter). - - The specific tags generated are: - - - ``--`` - - The ``"none"`` ABI will be added if it was not explicitly provided. - - :param str interpreter: The name of the interpreter. Defaults to being - calculated. - :param Iterable abis: Iterable of compatible ABIs. Defaults to the ABIs - compatible with the current system. - :param Iterable platforms: Iterable of compatible platforms. Defaults to the - platforms compatible with the current system. - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - - .. versionadded:: 20.0 - """ - if not interpreter: - interp_name = interpreter_name() - interp_version = interpreter_version(warn=warn) - interpreter = f"{interp_name}{interp_version}" - abis = _generic_abi() if abis is None else list(abis) - platforms = list(platforms or platform_tags()) - if "none" not in abis: - abis.append("none") - for abi in abis: - for platform_ in platforms: - yield Tag(interpreter, abi, platform_) - - -def _py_interpreter_range(py_version: PythonVersion) -> Iterator[str]: - """ - Yields Python versions in descending order. - - After the latest version, the major-only version will be yielded, and then - all previous versions of that major version. - """ - if len(py_version) > 1: - yield f"py{_version_nodot(py_version[:2])}" - yield f"py{py_version[0]}" - if len(py_version) > 1: - for minor in range(py_version[1] - 1, -1, -1): - yield f"py{_version_nodot((py_version[0], minor))}" - - -def pure_python_tags( - python_version: PythonVersion | None = None, -) -> Iterator[Tag]: - """ - Yields the pure-Python tags compatible with ``python_version``. - - The tags use the ``"none"`` ABI and ``"any"`` platform, so their - generation does not depend on the running platform. - - .. versionadded:: 26.3 - - :param Sequence python_version: A one- or two-item sequence representing the - compatible version of Python. Defaults to - ``sys.version_info[:2]``. - :raises ValueError: If ``python_version`` is an empty sequence. - """ - if python_version is None: - python_version = sys.version_info[:2] - elif not python_version: - raise ValueError("python_version must contain at least one item") - for version in _py_interpreter_range(python_version): - yield Tag(version, "none", "any") - - -def compatible_tags( - python_version: PythonVersion | None = None, - interpreter: str | None = None, - platforms: Iterable[str] | None = None, -) -> Iterator[Tag]: - """ - Yields the tags for an interpreter compatible with the Python version - specified by ``python_version``. - - The specific tags generated are: - - - ``py*-none-`` - - ``-none-any`` if ``interpreter`` is provided - - ``py*-none-any`` - - :param Sequence python_version: A one- or two-item sequence representing the - compatible version of Python. Defaults to - ``sys.version_info[:2]``. - :param str interpreter: The name of the interpreter (if known), e.g. - ``"cp38"``. Defaults to the current interpreter. - :param Iterable platforms: Iterable of compatible platforms. Defaults to the - platforms compatible with the current system. - - .. versionadded:: 20.0 - """ - if not python_version: - python_version = sys.version_info[:2] - platforms = list(platforms or platform_tags()) - for version in _py_interpreter_range(python_version): - for platform_ in platforms: - yield Tag(version, "none", platform_) - if interpreter: - yield Tag(interpreter, "none", "any") - yield from pure_python_tags(python_version) - - -def _mac_arch(arch: str, is_32bit: bool = _32_BIT_INTERPRETER) -> str: - if not is_32bit: - return arch - - if arch.startswith("ppc"): - return "ppc" - - return "i386" - - -def _mac_binary_formats(version: AppleVersion, cpu_arch: str) -> list[str]: - formats = [cpu_arch] - if cpu_arch == "x86_64": - if version < (10, 4): - return [] - formats.extend(["intel", "fat64", "fat3"]) - - elif cpu_arch == "i386": - if version < (10, 4): - return [] - formats.extend(["intel", "fat3", "fat"]) - - elif cpu_arch == "ppc64": - # TODO: Need to care about 32-bit PPC for ppc64 through 10.2? - if version > (10, 5) or version < (10, 4): - return [] - formats.append("fat64") - - elif cpu_arch == "ppc": - if version > (10, 6): - return [] - formats.extend(["fat3", "fat"]) - - if cpu_arch in {"arm64", "x86_64"}: - formats.append("universal2") - - if cpu_arch in {"x86_64", "i386", "ppc64", "ppc", "intel"}: - formats.append("universal") - - return formats - - -def mac_platforms( - version: AppleVersion | None = None, arch: str | None = None -) -> Iterator[str]: - """ - Yields the :attr:`~Tag.platform` tags for macOS. - - The `version` parameter is a two-item tuple specifying the macOS version to - generate platform tags for. The `arch` parameter is the CPU architecture to - generate platform tags for. Both parameters default to the appropriate value - for the current system. - - :param tuple version: A two-item tuple representing the version of macOS. - Defaults to the current system's version. - :param str arch: The CPU architecture. Defaults to the architecture of the - current system, e.g. ``"x86_64"``. - - .. note:: - Equivalent support for the other major platforms is purposefully not - provided: - - - On Windows, platform compatibility is statically specified - - On Linux, code must be run on the system itself to determine - compatibility - - .. versionadded:: 20.0 - """ - if version is None or arch is None: - version_str, _, cpu_arch = platform.mac_ver() - if version is None: - version = cast("AppleVersion", tuple(map(int, version_str.split(".")[:2]))) - if version == (10, 16): - # When built against an older macOS SDK, Python will report macOS 10.16 - # instead of the real version. - version_str = subprocess.run( - [ - sys.executable, - "-sS", - "-c", - "import platform; print(platform.mac_ver()[0])", - ], - check=True, - env={"SYSTEM_VERSION_COMPAT": "0"}, - stdout=subprocess.PIPE, - text=True, - ).stdout - version = cast( - "AppleVersion", tuple(map(int, version_str.split(".")[:2])) - ) - if arch is None: - arch = _mac_arch(cpu_arch) - - if (10, 0) <= version < (11, 0): - # Prior to Mac OS 11, each yearly release of Mac OS bumped the - # "minor" version number. The major version was always 10. - major_version = 10 - for minor_version in range(version[1], -1, -1): - compat_version = major_version, minor_version - binary_formats = _mac_binary_formats(compat_version, arch) - for binary_format in binary_formats: - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - - if version >= (11, 0): - # Starting with Mac OS 11, each yearly release bumps the major version - # number. The minor versions are now the midyear updates. - minor_version = 0 - for major_version in range(version[0], 10, -1): - compat_version = major_version, minor_version - binary_formats = _mac_binary_formats(compat_version, arch) - for binary_format in binary_formats: - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - - # Mac OS 11 on x86_64 is compatible with binaries from previous releases. - # Arm64 support was introduced in 11.0, so no Arm binaries from previous - # releases exist. - # - # However, the "universal2" binary format can have a - # macOS version earlier than 11.0 when the x86_64 part of the binary supports - # that version of macOS. - major_version = 10 - if arch == "x86_64": - for minor_version in range(16, 3, -1): - compat_version = major_version, minor_version - binary_formats = _mac_binary_formats(compat_version, arch) - for binary_format in binary_formats: - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - else: - for minor_version in range(16, 3, -1): - compat_version = major_version, minor_version - binary_format = "universal2" - yield f"macosx_{major_version}_{minor_version}_{binary_format}" - - -def ios_platforms( - version: AppleVersion | None = None, multiarch: str | None = None -) -> Iterator[str]: - """ - - Yields the :attr:`~Tag.platform` tags for iOS. - - :param tuple version: A two-item tuple representing the version of iOS. - Defaults to the current system's version. - :param str multiarch: The CPU architecture+ABI to be used. This should be in - the format by ``sys.implementation._multiarch`` (e.g., - ``arm64_iphoneos`` or ``x86_64_iphonesimulator``). - Defaults to the current system's multiarch value. - - .. note:: - Behavior of this method is undefined if invoked on non-iOS platforms - without providing explicit version and multiarch arguments. - - .. versionadded:: 24.2 - """ - if version is None: - # if iOS is the current platform, ios_ver *must* be defined. However, - # it won't exist for CPython versions before 3.13, which causes a mypy - # error. - _, release, _, _ = platform.ios_ver() # type: ignore[attr-defined, unused-ignore] - version = cast("AppleVersion", tuple(map(int, release.split(".")[:2]))) - - if multiarch is None: - multiarch = sys.implementation._multiarch - multiarch = multiarch.replace("-", "_") - - ios_platform_template = "ios_{major}_{minor}_{multiarch}" - - # Consider any iOS major.minor version from the version requested, down to - # 12.0. 12.0 is the first iOS version that is known to have enough features - # to support CPython. Consider every possible minor release up to X.9. There - # highest the minor has ever gone is 8 (14.8 and 15.8) but having some extra - # candidates that won't ever match doesn't really hurt, and it saves us from - # having to keep an explicit list of known iOS versions in the code. Return - # the results descending order of version number. - - # If the requested major version is less than 12, there won't be any matches. - if version[0] < 12: - return - - # Consider the actual X.Y version that was requested. - yield ios_platform_template.format( - major=version[0], minor=version[1], multiarch=multiarch - ) - - # Consider every minor version from X.0 to the minor version prior to the - # version requested by the platform. - for minor in range(version[1] - 1, -1, -1): - yield ios_platform_template.format( - major=version[0], minor=minor, multiarch=multiarch - ) - - for major in range(version[0] - 1, 11, -1): - for minor in range(9, -1, -1): - yield ios_platform_template.format( - major=major, minor=minor, multiarch=multiarch - ) - - -def android_platforms( - api_level: int | None = None, abi: str | None = None -) -> Iterator[str]: - """ - Yields the :attr:`~Tag.platform` tags for Android. If this function is invoked on - non-Android platforms, the ``api_level`` and ``abi`` arguments are required. - - :param int api_level: The maximum `API level - `__ to return. Defaults - to the current system's version, as returned by ``platform.android_ver``. - :param str abi: The `Android ABI `__, - e.g. ``arm64_v8a``. Defaults to the current system's ABI , as returned by - ``sysconfig.get_platform``. Hyphens and periods will be replaced with - underscores. - - .. versionadded:: 25.0 - """ - if platform.system() != "Android" and (api_level is None or abi is None): - raise TypeError( - "on non-Android platforms, the api_level and abi arguments are required" - ) - - if api_level is None: - # Python 3.13 was the first version to return platform.system() == "Android", - # and also the first version to define platform.android_ver(). - api_level = platform.android_ver().api_level # type: ignore[attr-defined] - - if abi is None: - abi = sysconfig.get_platform().split("-")[-1] - abi = _normalize_string(abi) - - # 16 is the minimum API level known to have enough features to support CPython - # without major patching. Yield every API level from the maximum down to the - # minimum, inclusive. - min_api_level = 16 - for ver in range(api_level, min_api_level - 1, -1): - yield f"android_{ver}_{abi}" - - -def _linux_platforms(is_32bit: bool = _32_BIT_INTERPRETER) -> Iterator[str]: - linux = _normalize_string(sysconfig.get_platform()) - if not linux.startswith("linux_"): - # we should never be here, just yield the sysconfig one and return - yield linux - return - if is_32bit: - if linux == "linux_x86_64": - linux = "linux_i686" - elif linux == "linux_aarch64": - linux = "linux_armv8l" - _, arch = linux.split("_", 1) - archs = {"armv8l": ["armv8l", "armv7l"]}.get(arch, [arch]) - for arch in archs: - yield f"linux_{arch}" - yield from _manylinux.platform_tags(archs) - yield from _musllinux.platform_tags(archs) - - -def _emscripten_platforms() -> Iterator[str]: - pyemscripten_platform_version = sysconfig.get_config_var( - "PYEMSCRIPTEN_PLATFORM_VERSION" - ) - if pyemscripten_platform_version: - yield f"pyemscripten_{pyemscripten_platform_version}_wasm32" - yield from _generic_platforms() - - -def _generic_platforms() -> Iterator[str]: - yield _normalize_string(sysconfig.get_platform()) - - -def platform_tags() -> Iterator[str]: - """ - Yields the :attr:`~Tag.platform` tags for the running interpreter. - - .. versionadded:: 21.1 - """ - if platform.system() == "Darwin": - return mac_platforms() - elif platform.system() == "iOS": - return ios_platforms() - elif platform.system() == "Android": - return android_platforms() - elif platform.system() == "Linux": - return _linux_platforms() - elif platform.system() == "Emscripten": - return _emscripten_platforms() - else: - return _generic_platforms() - - -def interpreter_name() -> str: - """ - Returns the name of the running interpreter. - - Some implementations have a reserved, two-letter abbreviation which will - be returned when appropriate. - - This typically acts as the prefix to the :attr:`~Tag.interpreter` tag. - - .. versionadded:: 20.0 - """ - name = sys.implementation.name - return INTERPRETER_SHORT_NAMES.get(name) or name - - -def interpreter_version(*, warn: bool = False) -> str: - """ - Returns the running interpreter's version. - - This typically acts as the suffix to the :attr:`~Tag.interpreter` tag. - - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - - .. versionadded:: 20.0 - """ - version = _get_config_var("py_version_nodot", warn=warn) - return str(version) if version else _version_nodot(sys.version_info[:2]) - - -def _version_nodot(version: PythonVersion) -> str: - return "".join(map(str, version)) - - -def sys_tags(*, warn: bool = False) -> Iterator[Tag]: - """ - Yields the sequence of tag triples that the running interpreter supports. - - The iterable is ordered so that the best-matching tag is first in the - sequence. The exact preferential order to tags is interpreter-specific, but - in general the tag importance is in the order of: - - 1. Interpreter - 2. Platform - 3. ABI - - This order is due to the fact that an ABI is inherently tied to the - platform, but platform-specific code is not necessarily tied to the ABI. The - interpreter is the most important tag as it dictates basic support for any - wheel. - - The function returns an iterable in order to allow for the possible - short-circuiting of tag generation if the entire sequence is not necessary - and tag calculation happens to be expensive. - - :param bool warn: Whether warnings should be logged. Defaults to ``False``. - - .. versionchanged:: 21.3 - Added the `pp3-none-any` tag (:issue:`311`). - .. versionchanged:: 26.1 - Added the `abi3t` tag (:issue:`1099`). - .. versionchanged:: 26.3 - Native ``linux_*`` platform tags are now ordered before ``manylinux`` - and ``musllinux`` tags (:issue:`160`). - """ - - interp_name = interpreter_name() - if interp_name == "cp": - yield from cpython_tags(warn=warn) - else: - yield from generic_tags(warn=warn) - - if interp_name == "pp": - interp = "pp3" - elif interp_name == "cp": - interp = "cp" + interpreter_version(warn=warn) - else: - interp = None - yield from compatible_tags(interpreter=interp) - - -def create_compatible_tags_selector( - tags: Iterable[Tag], -) -> Callable[[Iterable[tuple[_T, AbstractSet[Tag]]]], Iterator[_T]]: - """Create a callable to select things compatible with supported tags. - - This function accepts an ordered sequence of tags, with the preferred - tags first. - - The returned callable accepts an iterable of tuples (thing, set[Tag]), - and returns an iterator of things, with the things with the best - matching tags first. - - Example to select compatible wheel filenames: - - >>> from packaging import tags - >>> from packaging.utils import parse_wheel_filename - >>> selector = tags.create_compatible_tags_selector(tags.sys_tags()) - >>> filenames = ["foo-1.0-py3-none-any.whl", "foo-1.0-py2-none-any.whl"] - >>> list(selector([ - ... (filename, parse_wheel_filename(filename)[-1]) for filename in filenames - ... ])) - ['foo-1.0-py3-none-any.whl'] - - .. versionadded:: 26.1 - """ - tag_ranks: dict[Tag, int] = {} - for rank, tag in enumerate(tags): - tag_ranks.setdefault(tag, rank) # ignore duplicate tags, keep first - supported_tags = tag_ranks.keys() - - def selector( - tagged_things: Iterable[tuple[_T, AbstractSet[Tag]]], - ) -> Iterator[_T]: - ranked_things: list[tuple[_T, int]] = [] - for thing, thing_tags in tagged_things: - supported_thing_tags = thing_tags & supported_tags - if supported_thing_tags: - thing_rank = min(tag_ranks[t] for t in supported_thing_tags) - ranked_things.append((thing, thing_rank)) - return iter( - thing for thing, _ in sorted(ranked_things, key=operator.itemgetter(1)) - ) - - return selector diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py deleted file mode 100644 index 2f0ce207447..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/utils.py +++ /dev/null @@ -1,370 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. - -from __future__ import annotations - -import re -from typing import NewType, Union, cast - -from .tags import InvalidTag, Tag, UnsortedTagsError, parse_tag -from .version import InvalidVersion, Version, _TrimmedRelease - -__all__ = [ - "BuildTag", - "InvalidName", - "InvalidSdistFilename", - "InvalidWheelFilename", - "NormalizedName", - "canonicalize_name", - "canonicalize_version", - "is_normalized_name", - "parse_sdist_filename", - "parse_wheel_filename", -] - - -def __dir__() -> list[str]: - return __all__ - - -BuildTag = Union[tuple[()], tuple[int, str]] -""" -A wheel build tag: an empty tuple, or a ``(build number, build tag suffix)`` pair. - -.. versionadded:: 20.9 -""" - -NormalizedName = NewType("NormalizedName", str) -""" -A :class:`typing.NewType` of :class:`str`, representing a normalized name. - -.. versionadded:: 20.4 -""" - - -class InvalidName(ValueError): - """ - An invalid distribution name; users should refer to the packaging user guide. - - .. versionadded:: 23.2 - """ - - -class InvalidWheelFilename(ValueError): - """ - An invalid wheel filename was found, users should refer to PEP 427. - - .. versionadded:: 20.9 - """ - - -class InvalidSdistFilename(ValueError): - """ - An invalid sdist filename was found, users should refer to the packaging user guide. - - .. versionadded:: 20.9 - """ - - -# Core metadata spec for `Name` -_validate_regex = re.compile( - r"[a-z0-9]|[a-z0-9][a-z0-9._-]*[a-z0-9]", re.IGNORECASE | re.ASCII -) -_normalized_regex = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*", re.ASCII) -# PEP 427: The build number must start with a digit. -_build_tag_regex = re.compile(r"(\d+)(.*)", re.ASCII) -# PEP 427: Valid characters for an escaped project name in a wheel filename. -# Requires at least one character so an empty project name is rejected. -_wheel_name_regex = re.compile(r"^[\w._]+\Z", re.UNICODE) - - -def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName: - """ - This function takes a valid Python package or extra name, and returns the - normalized form of it. - - The return type is typed as :class:`NormalizedName`. This allows type - checkers to help require that a string has passed through this function - before use. - - If **validate** is true, then the function will check if **name** is a valid - distribution name before normalizing. - - :param str name: The name to normalize. - :param bool validate: Check whether the name is a valid distribution name. - :raises InvalidName: If **validate** is true and the name is not an - acceptable distribution name. - - >>> from packaging.utils import canonicalize_name - >>> canonicalize_name("Django") - 'django' - >>> canonicalize_name("oslo.concurrency") - 'oslo-concurrency' - >>> canonicalize_name("requests") - 'requests' - - .. versionadded:: 16.2 - - .. versionchanged:: 20.4 - The return type was changed to :class:`NormalizedName`. - - .. versionchanged:: 23.2 - Added the *validate* keyword parameter. - """ - if validate and not _validate_regex.fullmatch(name): - raise InvalidName(f"name is invalid: {name!r}") - # Ensure all ``.`` and ``_`` are ``-`` - # Emulates ``re.sub(r"[-_.]+", "-", name).lower()`` from PEP 503 - # Much faster than re, and even faster than str.translate - value = name.lower().replace("_", "-").replace(".", "-") - # Condense repeats (faster than regex) - while "--" in value: - value = value.replace("--", "-") - return cast("NormalizedName", value) - - -def is_normalized_name(name: str) -> bool: - """ - Check if a name is a normalized project name (i.e. a valid name that - :func:`canonicalize_name` would roundtrip to the same value). - - The roundtrip only characterizes normalized names for *valid* names. A name - must start and end with an ASCII letter or digit, which - :func:`canonicalize_name` does not enforce: it leaves a leading or trailing - hyphen in place, so such a name roundtrips without being normalized. - - :param str name: The name to check. - - >>> from packaging.utils import canonicalize_name, is_normalized_name - >>> is_normalized_name("requests") - True - >>> is_normalized_name("Django") - False - >>> canonicalize_name("_not_legal") - '-not-legal' - >>> is_normalized_name("-not-legal") # roundtrips, but not a valid name - False - - .. versionadded:: 23.2 - """ - return _normalized_regex.fullmatch(name) is not None - - -def canonicalize_version( - version: Version | str, *, strip_trailing_zero: bool = True -) -> str: - """Return a canonical form of a version as a string. - - This function takes a string representing a package version (or a - :class:`~packaging.version.Version` instance), and returns the - normalized form of it. By default, it strips trailing zeros from - the release segment. - - >>> from packaging.utils import canonicalize_version - >>> canonicalize_version('1.0.1') - '1.0.1' - - Per PEP 625, versions may have multiple canonical forms, differing - only by trailing zeros. - - >>> canonicalize_version('1.0.0') - '1' - >>> canonicalize_version('1.0.0', strip_trailing_zero=False) - '1.0.0' - - Invalid versions are returned unaltered. - - >>> canonicalize_version('foo bar baz') - 'foo bar baz' - - >>> canonicalize_version('1.4.0.0.0') - '1.4' - - .. versionadded:: 17.1 - - .. versionchanged:: 21.0 - The return type was narrowed to :class:`str`. - - .. versionchanged:: 22.0 - Added the *strip_trailing_zero* keyword parameter. - """ - if isinstance(version, str): - try: - version = Version(version) - except InvalidVersion: - return str(version) - return str(_TrimmedRelease(version) if strip_trailing_zero else version) - - -def parse_wheel_filename( - filename: str, - *, - validate_order: bool = False, -) -> tuple[NormalizedName, Version, BuildTag, frozenset[Tag]]: - """ - This function takes the filename of a wheel file, and parses it, - returning a tuple of name, version, build number, and tags. - - The name part of the tuple is normalized and typed as - :class:`NormalizedName`. The version portion is an instance of - :class:`~packaging.version.Version`. The build number is ``()`` if - there is no build number in the wheel filename, otherwise a - two-item tuple of an integer for the leading digits and - a string for the rest of the build number. The tags portion is a - frozen set of :class:`~packaging.tags.Tag` instances (as the tag - string format allows multiple tags to be combined into a single - string). - - If **validate_order** is true, compressed tag set components are - checked to be in sorted order as required by PEP 425. - - :param str filename: The name of the wheel file. - :param bool validate_order: Check whether compressed tag set components - are in sorted order. - :raises InvalidWheelFilename: If the filename in question - does not follow the :ref:`wheel specification - `. - - >>> from packaging.utils import parse_wheel_filename - >>> from packaging.tags import Tag - >>> from packaging.version import Version - >>> name, ver, build, tags = parse_wheel_filename("foo-1.0-py3-none-any.whl") - >>> name - 'foo' - >>> ver == Version('1.0') - True - >>> tags == {Tag("py3", "none", "any")} - True - >>> not build - True - - .. versionadded:: 20.9 - - .. versionchanged:: 23.2 - Raises :class:`InvalidWheelFilename` when the version component is invalid. - - .. versionadded:: 26.1 - The *validate_order* parameter. - - .. versionchanged:: 26.3 - Raises :class:`InvalidWheelFilename` when an interpreter component is - not an identifier, a tag set component is empty, or the project name is - empty. - """ - if not filename.endswith(".whl"): - raise InvalidWheelFilename( - f"Invalid wheel filename (extension must be '.whl'): {filename!r}" - ) - - filename = filename[:-4] - dashes = filename.count("-") - if dashes not in (4, 5): - raise InvalidWheelFilename( - f"Invalid wheel filename (wrong number of parts): {filename!r}" - ) - - parts = filename.split("-", dashes - 2) - name_part = parts[0] - # See PEP 427 for the rules on escaping the project name. - if "__" in name_part or _wheel_name_regex.match(name_part) is None: - raise InvalidWheelFilename(f"Invalid project name: {filename!r}") - name = canonicalize_name(name_part) - - try: - version = Version(parts[1]) - except InvalidVersion as e: - raise InvalidWheelFilename( - f"Invalid wheel filename (invalid version): {filename!r}" - ) from e - - if dashes == 5: - build_part = parts[2] - build_match = _build_tag_regex.match(build_part) - if build_match is None: - raise InvalidWheelFilename( - f"Invalid build number: {build_part} in {filename!r}" - ) - build = cast("BuildTag", (int(build_match.group(1)), build_match.group(2))) - else: - build = () - tag_str = parts[-1] - try: - tags = parse_tag(tag_str, validate_order=validate_order) - except UnsortedTagsError: - raise InvalidWheelFilename( - f"Invalid wheel filename (compressed tag set components must be in " - f"sorted order per PEP 425): {filename!r}" - ) from None - except InvalidTag: - raise InvalidWheelFilename( - f"Invalid wheel filename (invalid tag component): {filename!r}" - ) from None - return (name, version, build, tags) - - -def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]: - """ - This function takes the filename of a sdist file (as specified - in the `Source distribution format`_ documentation), and parses - it, returning a tuple of the normalized name and version as - represented by an instance of :class:`~packaging.version.Version`. - - :param str filename: The name of the sdist file. - :raises InvalidSdistFilename: If the filename does not end - with an sdist extension (``.zip`` or ``.tar.gz``), if it does not - contain a dash separating the name and the version of the distribution, - if the project name is empty, or if the version portion is not a valid - version. - - >>> from packaging.utils import parse_sdist_filename - >>> from packaging.version import Version - >>> name, ver = parse_sdist_filename("foo-1.0.tar.gz") - >>> name - 'foo' - >>> ver == Version('1.0') - True - - .. versionadded:: 20.9 - - .. versionchanged:: 21.0 - Added support for ``.zip`` source distributions. - - .. versionchanged:: 23.2 - Raises :class:`InvalidSdistFilename` when the version component is invalid. - - .. versionchanged:: 26.3 - Raises :class:`InvalidSdistFilename` on an empty project name. - - .. _Source distribution format: https://packaging.python.org/specifications/source-distribution-format/#source-distribution-file-name - """ - if filename.endswith(".tar.gz"): - file_stem = filename[: -len(".tar.gz")] - elif filename.endswith(".zip"): - file_stem = filename[: -len(".zip")] - else: - raise InvalidSdistFilename( - f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):" - f" {filename!r}" - ) - - # We are requiring a PEP 440 version, which cannot contain dashes, - # so we split on the last dash. - name_part, sep, version_part = file_stem.rpartition("-") - if not sep: - raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}") - if not name_part: - raise InvalidSdistFilename( - f"Invalid sdist filename (empty project name): {filename!r}" - ) - - name = canonicalize_name(name_part) - - try: - version = Version(version_part) - except InvalidVersion as e: - raise InvalidSdistFilename( - f"Invalid sdist filename (invalid version): {filename!r}" - ) from e - - return (name, version) diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py deleted file mode 100644 index 48e214004c7..00000000000 --- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/packaging/version.py +++ /dev/null @@ -1,1252 +0,0 @@ -# This file is dual licensed under the terms of the Apache License, Version -# 2.0, and the BSD License. See the LICENSE file in the root of this repository -# for complete details. -""" -.. testsetup:: - - from packaging.version import parse, normalize_pre, Version, _cmpkey -""" - -from __future__ import annotations - -import re -import sys -import typing -from typing import ( - Any, - Callable, - Literal, - NamedTuple, - SupportsInt, - TypedDict, - Union, -) - -if typing.TYPE_CHECKING: - from opentelemetry.agent._vendor.typing_extensions import Self, Unpack - -if sys.version_info >= (3, 13): # pragma: no cover - from warnings import deprecated as _deprecated -elif typing.TYPE_CHECKING: - from opentelemetry.agent._vendor.typing_extensions import deprecated as _deprecated -else: # pragma: no cover - import functools - import warnings - - def _deprecated(message: str) -> object: - def decorator(func: Callable[[...], object]) -> object: - @functools.wraps(func) - def wrapper(*args: object, **kwargs: object) -> object: - warnings.warn( - message, - category=DeprecationWarning, - stacklevel=2, - ) - return func(*args, **kwargs) - - return wrapper - - return decorator - - -_LETTER_NORMALIZATION = { - "alpha": "a", - "beta": "b", - "c": "rc", - "pre": "rc", - "preview": "rc", - "rev": "post", - "r": "post", -} - -__all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "normalize_pre", "parse"] - - -def __dir__() -> list[str]: - return __all__ - - -LocalType = tuple[Union[int, str], ...] - -CmpLocalType = tuple[tuple[int, str], ...] -CmpSuffix = tuple[int, int, int, int, int, int] -CmpKey = Union[ - tuple[int, tuple[int, ...], CmpSuffix], - tuple[int, tuple[int, ...], CmpSuffix, CmpLocalType], -] -VersionComparisonMethod = Callable[[CmpKey, CmpKey], bool] - - -class _VersionReplace(TypedDict, total=False): - epoch: int | None - release: tuple[int, ...] | None - pre: tuple[str, int] | None - post: int | None - dev: int | None - local: str | None - - -def normalize_pre(letter: str, /) -> str: - """Normalize the pre-release segment of a version string. - - Returns a lowercase version of the string if not a known pre-release - identifier. - - >>> normalize_pre('alpha') - 'a' - >>> normalize_pre('BETA') - 'b' - >>> normalize_pre('rc') - 'rc' - - :param letter: - - .. versionadded:: 26.1 - """ - letter = letter.lower() - return _LETTER_NORMALIZATION.get(letter, letter) - - -def parse(version: str) -> Version: - """Parse the given version string. - - This is identical to the :class:`Version` constructor. - - >>> parse('1.0.dev1') - - - :param version: The version string to parse. - :raises InvalidVersion: When the version string is not a valid version. - """ - return Version(version) - - -class InvalidVersion(ValueError): - """Raised when a version string is not a valid version. - - >>> Version("invalid") - Traceback (most recent call last): - ... - packaging.version.InvalidVersion: Invalid version: 'invalid' - """ - - -class _BaseVersion: - __slots__ = () - - # This can also be a normal member (see the packaging_legacy package); - # we are just requiring it to be readable. Actually defining a property - # has runtime effect on subclasses, so it's typing only. - if typing.TYPE_CHECKING: - - @property - def _key(self) -> tuple[Any, ...]: ... - - def __hash__(self) -> int: - return hash(self._key) - - # Please keep the duplicated `isinstance` check - # in the six comparisons hereunder - # unless you find a way to avoid adding overhead function calls. - def __lt__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key < other._key - - def __le__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key <= other._key - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key == other._key - - def __ge__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key >= other._key - - def __gt__(self, other: _BaseVersion) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key > other._key - - def __ne__(self, other: object) -> bool: - if not isinstance(other, _BaseVersion): - return NotImplemented - - return self._key != other._key - - -# Deliberately not anchored to the start and end of the string, to make it -# easier for 3rd party code to reuse - -# Note that ++ doesn't behave identically on CPython and PyPy, so not using it here -_VERSION_PATTERN = r""" - v?+ # optional leading v - (?a: - (?:(?P[0-9]+)!)?+ # epoch - (?P[0-9]+(?:\.[0-9]+)*+) # release segment - (?P
                                          # pre-release
-            [._-]?+
-            (?Palpha|a|beta|b|preview|pre|c|rc)
-            [._-]?+
-            (?P[0-9]+)?
-        )?+
-        (?P                                         # post release
-            (?:-(?P[0-9]+))
-            |
-            (?:
-                [._-]?
-                (?Ppost|rev|r)
-                [._-]?
-                (?P[0-9]+)?
-            )
-        )?+
-        (?P                                          # dev release
-            [._-]?+
-            (?Pdev)
-            [._-]?+
-            (?P[0-9]+)?
-        )?+
-    )
-    (?a:\+
-        (?P                                        # local version
-            [a-z0-9]+
-            (?:[._-][a-z0-9]+)*+
-        )
-    )?+
-"""
-
-_VERSION_PATTERN_OLD = _VERSION_PATTERN.replace("*+", "*").replace("?+", "?")
-
-# Possessive qualifiers were added in Python 3.11.
-# CPython 3.11.0-3.11.4 had a bug: https://github.com/python/cpython/pull/107795
-# Older PyPy also had a bug.
-VERSION_PATTERN = (
-    _VERSION_PATTERN_OLD
-    if (sys.implementation.name == "cpython" and sys.version_info < (3, 11, 5))
-    or (sys.implementation.name == "pypy" and sys.version_info < (3, 11, 13))
-    or sys.version_info < (3, 11)
-    else _VERSION_PATTERN
-)
-"""
-A string containing the regular expression used to match a valid version.
-
-The pattern is not anchored at either end, and is intended for embedding in larger
-expressions (for example, matching a version number as part of a file name). The
-regular expression should be compiled with the ``re.VERBOSE`` and ``re.IGNORECASE``
-flags set.
-
-.. versionchanged:: 26.0
-
-   The regex now uses possessive qualifiers on Python 3.11 if they are
-   supported (CPython 3.11.5+, PyPy 3.11.13+).
-
-:meta hide-value:
-"""
-
-
-# Validation pattern for local version in replace()
-_LOCAL_PATTERN = re.compile(r"[a-z0-9]+(?:[._-][a-z0-9]+)*", re.IGNORECASE | re.ASCII)
-
-# Fast path: If a version has only digits and dots then we
-# can skip the regex and parse it as a release segment
-_SIMPLE_VERSION_INDICATORS = frozenset(".0123456789")
-
-
-def _validate_epoch(value: object, /) -> int:
-    epoch = value or 0
-    if isinstance(epoch, int) and epoch >= 0:
-        return epoch
-    msg = f"epoch must be non-negative integer, got {epoch}"
-    raise InvalidVersion(msg)
-
-
-def _validate_release(value: object, /) -> tuple[int, ...]:
-    release = (0,) if value is None else value
-    if (
-        isinstance(release, tuple)
-        and len(release) > 0
-        and all(isinstance(i, int) and i >= 0 for i in release)
-    ):
-        return release
-    msg = f"release must be a non-empty tuple of non-negative integers, got {release}"
-    raise InvalidVersion(msg)
-
-
-def _validate_pre(value: object, /) -> tuple[Literal["a", "b", "rc"], int] | None:
-    if value is None:
-        return value
-    if isinstance(value, tuple) and len(value) == 2:
-        letter, number = value
-        # The letter must be a string before it can be normalized.
-        if (
-            isinstance(letter, str)
-            and (normalized := normalize_pre(letter)) in {"a", "b", "rc"}
-            and isinstance(number, int)
-            and number >= 0
-        ):
-            # type checkers can't infer the Literal type here on letter
-            return (normalized, number)  # type: ignore[return-value]
-    msg = f"pre must be a tuple of ('a'|'b'|'rc', non-negative int), got {value}"
-    raise InvalidVersion(msg)
-
-
-def _validate_post(value: object, /) -> tuple[Literal["post"], int] | None:
-    if value is None:
-        return value
-    if isinstance(value, int) and value >= 0:
-        return ("post", value)
-    msg = f"post must be non-negative integer, got {value}"
-    raise InvalidVersion(msg)
-
-
-def _validate_dev(value: object, /) -> tuple[Literal["dev"], int] | None:
-    if value is None:
-        return value
-    if isinstance(value, int) and value >= 0:
-        return ("dev", value)
-    msg = f"dev must be non-negative integer, got {value}"
-    raise InvalidVersion(msg)
-
-
-def _validate_local(value: object, /) -> LocalType | None:
-    if value is None:
-        return value
-    if isinstance(value, str) and _LOCAL_PATTERN.fullmatch(value):
-        return _parse_local_version(value)
-    msg = f"local must be a valid version string, got {value!r}"
-    raise InvalidVersion(msg)
-
-
-# Backward compatibility for internals before 26.0. Do not use.
-class _Version(NamedTuple):
-    epoch: int
-    release: tuple[int, ...]
-    dev: tuple[Literal["dev"], int] | None
-    pre: tuple[Literal["a", "b", "rc"], int] | None
-    post: tuple[Literal["post"], int] | None
-    local: LocalType | None
-
-
-class Version(_BaseVersion):
-    """This class abstracts handling of a project's versions.
-
-    A :class:`Version` instance is comparison aware and can be compared and
-    sorted using the standard Python interfaces.
-
-    >>> v1 = Version("1.0a5")
-    >>> v2 = Version("1.0")
-    >>> v1
-    
-    >>> v2
-    
-    >>> v1 < v2
-    True
-    >>> v1 == v2
-    False
-    >>> v1 > v2
-    False
-    >>> v1 >= v2
-    False
-    >>> v1 <= v2
-    True
-
-    :class:`Version` is immutable; use :meth:`__replace__` to change
-    part of a version.
-
-    Instances are safe to serialize with :mod:`pickle`. They use a stable
-    format so the same pickle can be loaded in future packaging releases.
-
-    .. versionchanged:: 26.2
-
-        Added a stable pickle format. Pickles created with packaging 26.2+ can
-        be unpickled with future releases.  Backward compatibility with pickles
-        from packaging < 26.2 is supported but may be removed in a future
-        release.
-    """
-
-    __slots__ = (
-        "_dev",
-        "_epoch",
-        "_hash_cache",
-        "_key_cache",
-        "_local",
-        "_post",
-        "_pre",
-        "_release",
-    )
-    __match_args__ = ("_str",)
-    """
-    Pattern matching is supported on Python 3.10+.
-
-    .. versionadded:: 26.0
-
-    :meta hide-value:
-    """
-
-    _regex = re.compile(r"\s*" + VERSION_PATTERN + r"\s*", re.VERBOSE | re.IGNORECASE)
-
-    _epoch: int
-    _release: tuple[int, ...]
-    _dev: tuple[Literal["dev"], int] | None
-    _pre: tuple[Literal["a", "b", "rc"], int] | None
-    _post: tuple[Literal["post"], int] | None
-    _local: LocalType | None
-
-    _hash_cache: int | None
-    _key_cache: CmpKey | None
-
-    def __init__(self, version: str) -> None:
-        """Initialize a Version object.
-
-        :param version:
-            The string representation of a version which will be parsed and normalized
-            before use.
-        :raises InvalidVersion:
-            If the ``version`` does not conform to PEP 440 in any way then this
-            exception will be raised.
-        """
-        try:
-            is_simple = _SIMPLE_VERSION_INDICATORS.issuperset(version)
-        except TypeError:
-            raise InvalidVersion(f"Invalid version: {version!r}") from None
-
-        if is_simple:
-            try:
-                self._release = tuple(map(int, version.split(".")))
-            except AttributeError:
-                raise InvalidVersion(f"Invalid version: {version!r}") from None
-            except ValueError:
-                # Empty parts (from "1..2", ".1", etc.) are invalid versions.
-                # Any other ValueError (e.g. int str-digits limit) should
-                # propagate to the caller.
-                if "" in version.split("."):
-                    raise InvalidVersion(f"Invalid version: {version!r}") from None
-                # TODO: remove "no cover" when Python 3.9 is dropped.
-                raise  # pragma: no cover
-
-            self._epoch = 0
-            self._pre = None
-            self._post = None
-            self._dev = None
-            self._local = None
-            self._key_cache = None
-            self._hash_cache = None
-            return
-
-        # Validate the version and parse it into pieces
-        try:
-            match = self._regex.fullmatch(version)
-        except TypeError:
-            raise InvalidVersion(f"Invalid version: {version!r}") from None
-        if not match:
-            raise InvalidVersion(f"Invalid version: {version!r}")
-        self._epoch = int(match.group("epoch")) if match.group("epoch") else 0
-        self._release = tuple(map(int, match.group("release").split(".")))
-        # We can type ignore the assignments below because the regex guarantees
-        # the correct strings
-        self._pre = _parse_letter_version(match.group("pre_l"), match.group("pre_n"))  # type: ignore[assignment]
-        self._post = _parse_letter_version(  # type: ignore[assignment]
-            match.group("post_l"), match.group("post_n1") or match.group("post_n2")
-        )
-        self._dev = _parse_letter_version(match.group("dev_l"), match.group("dev_n"))  # type: ignore[assignment]
-        self._local = _parse_local_version(match.group("local"))
-
-        # Key which will be used for sorting
-        self._key_cache = None
-        self._hash_cache = None
-
-    @classmethod
-    def from_parts(
-        cls,
-        *,
-        epoch: int = 0,
-        release: tuple[int, ...],
-        pre: tuple[str, int] | None = None,
-        post: int | None = None,
-        dev: int | None = None,
-        local: str | None = None,
-    ) -> Self:
-        """
-        Return a new version composed of the various parts.
-
-        This allows you to build a version without going though a string and
-        running a regular expression. It normalizes pre-release strings. The
-        ``release=`` keyword argument is required.
-
-        >>> Version.from_parts(release=(1,2,3))
-        
-        >>> Version.from_parts(release=(0,1,0), pre=("b", 1))
-        
-
-        :param epoch:
-        :param release: This version tuple is required
-
-        .. versionadded:: 26.1
-        """
-        _epoch = _validate_epoch(epoch)
-        _release = _validate_release(release)
-        _pre = _validate_pre(pre) if pre is not None else None
-        _post = _validate_post(post) if post is not None else None
-        _dev = _validate_dev(dev) if dev is not None else None
-        _local = _validate_local(local) if local is not None else None
-
-        new_version = cls.__new__(cls)
-        new_version._key_cache = None
-        new_version._hash_cache = None
-        new_version._epoch = _epoch
-        new_version._release = _release
-        new_version._pre = _pre
-        new_version._post = _post
-        new_version._dev = _dev
-        new_version._local = _local
-
-        return new_version
-
-    def __replace__(self, **kwargs: Unpack[_VersionReplace]) -> Self:
-        """
-        __replace__(*, epoch=..., release=..., pre=..., post=..., dev=..., local=...)
-
-        Return a new version with parts replaced.
-
-        This returns a new version (unless no parts were changed). The
-        pre-release is normalized. Setting a value to ``None`` clears it.
-
-        >>> v = Version("1.2.3")
-        >>> v.__replace__(pre=("a", 1))
-        
-
-        :param int | None epoch:
-        :param tuple[int, ...] | None release:
-        :param tuple[str, int] | None pre:
-        :param int | None post:
-        :param int | None dev:
-        :param str | None local:
-
-        .. versionadded:: 26.0
-        .. versionchanged:: 26.1
-
-           The pre-release portion is now normalized.
-        """
-        epoch = _validate_epoch(kwargs["epoch"]) if "epoch" in kwargs else self._epoch
-        release = (
-            _validate_release(kwargs["release"])
-            if "release" in kwargs
-            else self._release
-        )
-        pre = _validate_pre(kwargs["pre"]) if "pre" in kwargs else self._pre
-        post = _validate_post(kwargs["post"]) if "post" in kwargs else self._post
-        dev = _validate_dev(kwargs["dev"]) if "dev" in kwargs else self._dev
-        local = _validate_local(kwargs["local"]) if "local" in kwargs else self._local
-
-        if (
-            epoch == self._epoch
-            and release == self._release
-            and pre == self._pre
-            and post == self._post
-            and dev == self._dev
-            and local == self._local
-        ):
-            return self
-
-        new_version = self.__class__.__new__(self.__class__)
-        new_version._key_cache = None
-        new_version._hash_cache = None
-        new_version._epoch = epoch
-        new_version._release = release
-        new_version._pre = pre
-        new_version._post = post
-        new_version._dev = dev
-        new_version._local = local
-
-        return new_version
-
-    @property
-    def _key(self) -> CmpKey:
-        if self._key_cache is None:
-            self._key_cache = _cmpkey(
-                self._epoch,
-                self._release,
-                self._pre,
-                self._post,
-                self._dev,
-                self._local,
-            )
-        return self._key_cache
-
-    # __hash__ must be defined when __eq__ is overridden,
-    # otherwise Python sets __hash__ to None.
-    def __hash__(self) -> int:
-        if (cached_hash := self._hash_cache) is not None:
-            return cached_hash
-
-        if (key := self._key_cache) is None:
-            self._key_cache = key = _cmpkey(
-                self._epoch,
-                self._release,
-                self._pre,
-                self._post,
-                self._dev,
-                self._local,
-            )
-        self._hash_cache = cached_hash = hash(key)
-        return cached_hash
-
-    # Override comparison methods to use direct _key_cache access
-    # This is faster than property access, especially before Python 3.12
-    def __lt__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache < other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__lt__(other)
-
-    def __le__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache <= other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__le__(other)
-
-    def __eq__(self, other: object) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache == other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__eq__(other)
-
-    def __ge__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache >= other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__ge__(other)
-
-    def __gt__(self, other: _BaseVersion) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache > other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__gt__(other)
-
-    def __ne__(self, other: object) -> bool:
-        if isinstance(other, Version):
-            if self._key_cache is None:
-                self._key_cache = _cmpkey(
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                )
-            if other._key_cache is None:
-                other._key_cache = _cmpkey(
-                    other._epoch,
-                    other._release,
-                    other._pre,
-                    other._post,
-                    other._dev,
-                    other._local,
-                )
-            return self._key_cache != other._key_cache
-
-        if not isinstance(other, _BaseVersion):
-            return NotImplemented
-
-        return super().__ne__(other)
-
-    def __getstate__(
-        self,
-    ) -> tuple[
-        int,
-        tuple[int, ...],
-        tuple[str, int] | None,
-        tuple[str, int] | None,
-        tuple[str, int] | None,
-        LocalType | None,
-    ]:
-        # Return state as a 6-item tuple for compactness:
-        #   (epoch, release, pre, post, dev, local)
-        # Cache members are excluded and will be recomputed on demand
-        return (
-            self._epoch,
-            self._release,
-            self._pre,
-            self._post,
-            self._dev,
-            self._local,
-        )
-
-    def __setstate__(self, state: object) -> None:
-        # Always discard cached values — they may contain stale references
-        # (e.g. packaging._structures.InfinityType from pre-26.1 pickles)
-        # and will be recomputed on demand from the core fields above.
-        self._key_cache = None
-        self._hash_cache = None
-
-        if isinstance(state, tuple):
-            if len(state) == 6:
-                # New format (26.2+): (epoch, release, pre, post, dev, local)
-                (
-                    self._epoch,
-                    self._release,
-                    self._pre,
-                    self._post,
-                    self._dev,
-                    self._local,
-                ) = state
-                return
-            if len(state) == 2:
-                # Format (packaging 26.0-26.1): (None, {slot: value}).
-                _, slot_dict = state
-                if isinstance(slot_dict, dict):
-                    self._epoch = slot_dict["_epoch"]
-                    self._release = slot_dict["_release"]
-                    self._pre = slot_dict.get("_pre")
-                    self._post = slot_dict.get("_post")
-                    self._dev = slot_dict.get("_dev")
-                    self._local = slot_dict.get("_local")
-                    return
-        if isinstance(state, dict):
-            # Old format (packaging <= 25.x, no __slots__): state is a plain
-            # dict with "_version" (_Version NamedTuple) and "_key" entries.
-            version_nt = state.get("_version")
-            if version_nt is not None:
-                self._epoch = version_nt.epoch
-                self._release = version_nt.release
-                self._pre = version_nt.pre
-                self._post = version_nt.post
-                self._dev = version_nt.dev
-                self._local = version_nt.local
-                return
-
-        raise TypeError(f"Cannot restore Version from {state!r}")
-
-    @property
-    @_deprecated("Version._version is private and will be removed soon")
-    def _version(self) -> _Version:
-        return _Version(
-            self._epoch, self._release, self._dev, self._pre, self._post, self._local
-        )
-
-    @_version.setter
-    @_deprecated("Version._version is private and will be removed soon")
-    def _version(self, value: _Version) -> None:
-        self._epoch = value.epoch
-        self._release = value.release
-        self._dev = value.dev
-        self._pre = value.pre
-        self._post = value.post
-        self._local = value.local
-        self._key_cache = None
-        self._hash_cache = None
-
-    def __repr__(self) -> str:
-        """A representation of the Version that shows all internal state.
-
-        >>> Version('1.0.0')
-        
-        """
-        return f"<{self.__class__.__name__}({str(self)!r})>"
-
-    def __str__(self) -> str:
-        """A string representation of the version that can be round-tripped.
-
-        >>> str(Version("1.0a5"))
-        '1.0a5'
-        """
-        # This is a hot function, so not calling self.base_version
-        version = ".".join(map(str, self.release))
-
-        # Epoch
-        if self.epoch:
-            version = f"{self.epoch}!{version}"
-
-        # Pre-release
-        if self.pre is not None:
-            version += "".join(map(str, self.pre))
-
-        # Post-release
-        if self.post is not None:
-            version += f".post{self.post}"
-
-        # Development release
-        if self.dev is not None:
-            version += f".dev{self.dev}"
-
-        # Local version segment
-        if self.local is not None:
-            version += f"+{self.local}"
-
-        return version
-
-    @property
-    def _str(self) -> str:
-        """Internal property for match_args"""
-        return str(self)
-
-    @property
-    def epoch(self) -> int:
-        """The epoch of the version.
-
-        >>> Version("2.0.0").epoch
-        0
-        >>> Version("1!2.0.0").epoch
-        1
-        """
-        return self._epoch
-
-    @property
-    def release(self) -> tuple[int, ...]:
-        """The components of the "release" segment of the version.
-
-        >>> Version("1.2.3").release
-        (1, 2, 3)
-        >>> Version("2.0.0").release
-        (2, 0, 0)
-        >>> Version("1!2.0.0.post0").release
-        (2, 0, 0)
-
-        Includes trailing zeroes but not the epoch or any pre-release / development /
-        post-release suffixes.
-        """
-        return self._release
-
-    @property
-    def pre(self) -> tuple[Literal["a", "b", "rc"], int] | None:
-        """The pre-release segment of the version.
-
-        >>> print(Version("1.2.3").pre)
-        None
-        >>> Version("1.2.3a1").pre
-        ('a', 1)
-        >>> Version("1.2.3b1").pre
-        ('b', 1)
-        >>> Version("1.2.3rc1").pre
-        ('rc', 1)
-        """
-        return self._pre
-
-    @property
-    def post(self) -> int | None:
-        """The post-release number of the version.
-
-        >>> print(Version("1.2.3").post)
-        None
-        >>> Version("1.2.3.post1").post
-        1
-        """
-        return self._post[1] if self._post else None
-
-    @property
-    def dev(self) -> int | None:
-        """The development number of the version.
-
-        >>> print(Version("1.2.3").dev)
-        None
-        >>> Version("1.2.3.dev1").dev
-        1
-        """
-        return self._dev[1] if self._dev else None
-
-    @property
-    def local(self) -> str | None:
-        """The local version segment of the version.
-
-        >>> print(Version("1.2.3").local)
-        None
-        >>> Version("1.2.3+abc").local
-        'abc'
-        """
-        if self._local:
-            return ".".join(str(x) for x in self._local)
-        else:
-            return None
-
-    @property
-    def public(self) -> str:
-        """The public portion of the version.
-
-        This returns a string. If you want a :class:`Version` again and care
-        about performance, use ``v.__replace__(local=None)`` instead.
-
-        >>> Version("1.2.3").public
-        '1.2.3'
-        >>> Version("1.2.3+abc").public
-        '1.2.3'
-        >>> Version("1!1.2.3dev1+abc").public
-        '1!1.2.3.dev1'
-        """
-        return str(self).split("+", 1)[0]
-
-    @property
-    def base_version(self) -> str:
-        """The "base version" of the version.
-
-        This returns a string. If you want a :class:`Version` again and care
-        about performance, use
-        ``v.__replace__(pre=None, post=None, dev=None, local=None)`` instead.
-
-        >>> Version("1.2.3").base_version
-        '1.2.3'
-        >>> Version("1.2.3+abc").base_version
-        '1.2.3'
-        >>> Version("1!1.2.3dev1+abc").base_version
-        '1!1.2.3'
-
-        The "base version" is the public version of the project without any pre or post
-        release markers.
-        """
-        release_segment = ".".join(map(str, self.release))
-        return f"{self.epoch}!{release_segment}" if self.epoch else release_segment
-
-    @property
-    def is_prerelease(self) -> bool:
-        """Whether this version is a pre-release.
-
-        >>> Version("1.2.3").is_prerelease
-        False
-        >>> Version("1.2.3a1").is_prerelease
-        True
-        >>> Version("1.2.3b1").is_prerelease
-        True
-        >>> Version("1.2.3rc1").is_prerelease
-        True
-        >>> Version("1.2.3dev1").is_prerelease
-        True
-        """
-        return self.dev is not None or self.pre is not None
-
-    @property
-    def is_postrelease(self) -> bool:
-        """Whether this version is a post-release.
-
-        >>> Version("1.2.3").is_postrelease
-        False
-        >>> Version("1.2.3.post1").is_postrelease
-        True
-        """
-        return self.post is not None
-
-    @property
-    def is_devrelease(self) -> bool:
-        """Whether this version is a development release.
-
-        >>> Version("1.2.3").is_devrelease
-        False
-        >>> Version("1.2.3.dev1").is_devrelease
-        True
-        """
-        return self.dev is not None
-
-    @property
-    def major(self) -> int:
-        """The first item of :attr:`release` or ``0`` if unavailable.
-
-        >>> Version("1.2.3").major
-        1
-
-        .. versionadded:: 20.0
-        """
-        return self.release[0] if len(self.release) >= 1 else 0
-
-    @property
-    def minor(self) -> int:
-        """The second item of :attr:`release` or ``0`` if unavailable.
-
-        >>> Version("1.2.3").minor
-        2
-        >>> Version("1").minor
-        0
-
-        .. versionadded:: 20.0
-        """
-        return self.release[1] if len(self.release) >= 2 else 0
-
-    @property
-    def micro(self) -> int:
-        """The third item of :attr:`release` or ``0`` if unavailable.
-
-        >>> Version("1.2.3").micro
-        3
-        >>> Version("1").micro
-        0
-
-        .. versionadded:: 20.0
-        """
-        return self.release[2] if len(self.release) >= 3 else 0
-
-
-class _TrimmedRelease(Version):
-    __slots__ = ()
-
-    def __init__(self, version: str | Version) -> None:
-        if isinstance(version, Version):
-            self._epoch = version._epoch
-            self._release = version._release
-            self._dev = version._dev
-            self._pre = version._pre
-            self._post = version._post
-            self._local = version._local
-            self._key_cache = version._key_cache
-            self._hash_cache = version._hash_cache
-            return
-        super().__init__(version)  # pragma: no cover
-
-    @property
-    def release(self) -> tuple[int, ...]:
-        """
-        Release segment without any trailing zeros.
-
-        >>> _TrimmedRelease('1.0.0').release
-        (1,)
-        >>> _TrimmedRelease('0.0').release
-        (0,)
-        """
-        # This leaves one 0.
-        rel = super().release
-        len_release = len(rel)
-        i = len_release
-        while i > 1 and rel[i - 1] == 0:
-            i -= 1
-        return rel if i == len_release else rel[:i]
-
-
-def _parse_letter_version(
-    letter: str | None, number: str | bytes | SupportsInt | None
-) -> tuple[str, int] | None:
-    if letter:
-        # We normalize any letters to their lower case form
-        letter = letter.lower()
-
-        # We consider some words to be alternate spellings of other words and
-        # in those cases we want to normalize the spellings to our preferred
-        # spelling.
-        letter = _LETTER_NORMALIZATION.get(letter, letter)
-
-        # We consider there to be an implicit 0 in a pre-release if there is
-        # not a numeral associated with it.
-        return letter, int(number or 0)
-
-    if number:
-        # We assume if we are given a number, but we are not given a letter
-        # then this is using the implicit post release syntax (e.g. 1.0-1)
-        return "post", int(number)
-
-    return None
-
-
-_local_version_separators = re.compile(r"[\._-]")
-
-
-def _parse_local_version(local: str | None) -> LocalType | None:
-    """
-    Takes a string like ``"abc.1.twelve"`` and turns it into
-    ``("abc", 1, "twelve")``.
-    """
-    if local is not None:
-        return tuple(
-            part.lower() if not part.isdigit() else int(part)
-            for part in _local_version_separators.split(local)
-        )
-    return None
-
-
-# Sort ranks for pre-release: dev-only < a < b < rc < stable (no pre-release).
-_PRE_RANK = {"a": 0, "b": 1, "rc": 2}
-_PRE_RANK_DEV_ONLY = -1  # sorts before a(0)
-_PRE_RANK_STABLE = 3  # sorts after rc(2)
-
-# In local version segments, strings sort before ints per PEP 440.
-_LOCAL_STR_RANK = -1  # sorts before all non-negative ints
-
-# Pre-computed suffix for stable releases (no pre, post, or dev segments).
-# See _cmpkey() for the suffix layout.
-_STABLE_SUFFIX = (_PRE_RANK_STABLE, 0, 0, 0, 1, 0)
-
-
-def _cmpkey(
-    epoch: int,
-    release: tuple[int, ...],
-    pre: tuple[str, int] | None,
-    post: tuple[str, int] | None,
-    dev: tuple[str, int] | None,
-    local: LocalType | None,
-) -> CmpKey:
-    """Build a comparison key for PEP 440 ordering.
-
-    Returns ``(epoch, release, suffix)`` or
-    ``(epoch, release, suffix, local)`` so that plain tuple
-    comparison gives the correct order.
-
-    Trailing zeros are stripped from the release so that ``1.0.0 == 1``.
-
-    The suffix is a flat 6-int tuple that encodes pre/post/dev:
-    ``(pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)``
-
-    pre_rank: dev-only=-1, a=0, b=1, rc=2, no-pre=3
-        Dev-only releases (no pre or post) get -1 so they sort before
-        any alpha/beta/rc.  Releases without a pre-release tag get 3
-        so they sort after rc.
-    post_rank: no-post=0, post=1
-        Releases without a post segment sort before those with one.
-    dev_rank: dev=0, no-dev=1
-        Releases without a dev segment sort after those with one.
-
-    Local segments use ``(n, "")`` for ints and ``(-1, s)`` for strings,
-    following PEP 440: strings sort before ints, strings compare
-    lexicographically, ints compare numerically, and shorter segments
-    sort before longer when prefixes match.  Versions without a local
-    segment sort before those with one (3-tuple < 4-tuple).
-
-    >>> _cmpkey(0, (1, 0, 0), None, None, None, None)
-    (0, (1,), (3, 0, 0, 0, 1, 0))
-    >>> _cmpkey(0, (1,), ("a", 1), None, None, None)
-    (0, (1,), (0, 1, 0, 0, 1, 0))
-    >>> _cmpkey(0, (1,), None, None, None, ("ubuntu", 1))
-    (0, (1,), (3, 0, 0, 0, 1, 0), ((-1, 'ubuntu'), (1, '')))
-    """
-    # Strip trailing zeros: 1.0.0 compares equal to 1.
-    len_release = len(release)
-    i = len_release
-    while i and release[i - 1] == 0:
-        i -= 1
-    trimmed = release if i == len_release else release[:i]
-
-    # Fast path: stable release with no local segment.
-    if pre is None and post is None and dev is None and local is None:
-        return epoch, trimmed, _STABLE_SUFFIX
-
-    if pre is None and post is None and dev is not None:
-        # dev-only (e.g. 1.0.dev1) sorts before all pre-releases.
-        pre_rank, pre_n = _PRE_RANK_DEV_ONLY, 0
-    elif pre is None:
-        pre_rank, pre_n = _PRE_RANK_STABLE, 0
-    else:
-        pre_rank, pre_n = _PRE_RANK[pre[0]], pre[1]
-
-    post_rank = 0 if post is None else 1
-    post_n = 0 if post is None else post[1]
-
-    dev_rank = 1 if dev is None else 0
-    dev_n = 0 if dev is None else dev[1]
-
-    suffix = (pre_rank, pre_n, post_rank, post_n, dev_rank, dev_n)
-
-    if local is None:
-        return epoch, trimmed, suffix
-
-    cmp_local: CmpLocalType = tuple(
-        (seg, "") if isinstance(seg, int) else (_LOCAL_STR_RANK, seg) for seg in local
-    )
-    return epoch, trimmed, suffix, cmp_local
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE
deleted file mode 100644
index 261eeb9e9f8..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE
deleted file mode 100644
index 59efb6c783b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus-client.NOTICE
+++ /dev/null
@@ -1,5 +0,0 @@
-Prometheus instrumentation library for Python applications
-Copyright 2015 The Prometheus Authors
-
-This product bundles decorator 4.0.10 which is available under a "2-clause BSD"
-license. For details, see prometheus_client/decorator.py.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py
deleted file mode 100644
index 221ad273972..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/__init__.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env python
-
-from . import (
-    exposition, gc_collector, metrics, metrics_core, platform_collector,
-    process_collector, registry,
-)
-from .exposition import (
-    CONTENT_TYPE_LATEST, CONTENT_TYPE_PLAIN_0_0_4, CONTENT_TYPE_PLAIN_1_0_0,
-    delete_from_gateway, generate_latest, instance_ip_grouping_key,
-    make_asgi_app, make_wsgi_app, MetricsHandler, push_to_gateway,
-    pushadd_to_gateway, start_http_server, start_wsgi_server,
-    write_to_textfile,
-)
-from .gc_collector import GC_COLLECTOR, GCCollector
-from .metrics import (
-    Counter, disable_created_metrics, enable_created_metrics, Enum, Gauge,
-    Histogram, Info, Summary,
-)
-from .metrics_core import Metric
-from .platform_collector import PLATFORM_COLLECTOR, PlatformCollector
-from .process_collector import PROCESS_COLLECTOR, ProcessCollector
-from .registry import CollectorRegistry, REGISTRY
-
-__all__ = (
-    'CollectorRegistry',
-    'REGISTRY',
-    'Metric',
-    'Counter',
-    'Gauge',
-    'Summary',
-    'Histogram',
-    'Info',
-    'Enum',
-    'enable_created_metrics',
-    'disable_created_metrics',
-    'CONTENT_TYPE_LATEST',
-    'CONTENT_TYPE_PLAIN_0_0_4',
-    'CONTENT_TYPE_PLAIN_1_0_0',
-    'generate_latest',
-    'MetricsHandler',
-    'make_wsgi_app',
-    'make_asgi_app',
-    'start_http_server',
-    'start_wsgi_server',
-    'write_to_textfile',
-    'push_to_gateway',
-    'pushadd_to_gateway',
-    'delete_from_gateway',
-    'instance_ip_grouping_key',
-    'ProcessCollector',
-    'PROCESS_COLLECTOR',
-    'PlatformCollector',
-    'PLATFORM_COLLECTOR',
-    'GCCollector',
-    'GC_COLLECTOR',
-)
-
-if __name__ == '__main__':
-    c = Counter('cc', 'A counter')
-    c.inc()
-
-    g = Gauge('gg', 'A gauge')
-    g.set(17)
-
-    s = Summary('ss', 'A summary', ['a', 'b'])
-    s.labels('c', 'd').observe(17)
-
-    h = Histogram('hh', 'A histogram')
-    h.observe(.6)
-
-    start_http_server(8000)
-    import time
-
-    while True:
-        time.sleep(1)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py
deleted file mode 100644
index 6e527ca960e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/asgi.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from typing import Callable
-from urllib.parse import parse_qs
-
-from .exposition import _bake_output
-from .registry import Collector, REGISTRY
-
-
-def make_asgi_app(registry: Collector = REGISTRY, disable_compression: bool = False) -> Callable:
-    """Create a ASGI app which serves the metrics from a registry."""
-
-    async def prometheus_app(scope, receive, send):
-        assert scope.get("type") == "http"
-        # Prepare parameters
-        params = parse_qs(scope.get('query_string', b'').decode("utf8"))
-        accept_header = ",".join([
-            value.decode("utf8") for (name, value) in scope.get('headers')
-            if name.decode("utf8").lower() == 'accept'
-        ])
-        accept_encoding_header = ",".join([
-            value.decode("utf8") for (name, value) in scope.get('headers')
-            if name.decode("utf8").lower() == 'accept-encoding'
-        ])
-        # Bake output
-        status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression)
-        formatted_headers = []
-        for header in headers:
-            formatted_headers.append(tuple(x.encode('utf8') for x in header))
-        # Return output
-        payload = await receive()
-        if payload.get("type") == "http.request":
-            await send(
-                {
-                    "type": "http.response.start",
-                    "status": int(status.split(' ')[0]),
-                    "headers": formatted_headers,
-                }
-            )
-            await send({"type": "http.response.body", "body": output})
-
-    return prometheus_app
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py
deleted file mode 100644
index 235324b2a41..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/bridge/graphite.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-
-import logging
-import re
-import socket
-import threading
-import time
-from timeit import default_timer
-from typing import Callable, Tuple
-
-from ..registry import Collector, REGISTRY
-
-# Roughly, have to keep to what works as a file name.
-# We also remove periods, so labels can be distinguished.
-
-_INVALID_GRAPHITE_CHARS = re.compile(r"[^a-zA-Z0-9_-]")
-
-
-def _sanitize(s):
-    return _INVALID_GRAPHITE_CHARS.sub('_', s)
-
-
-class _RegularPush(threading.Thread):
-    def __init__(self, pusher, interval, prefix):
-        super().__init__()
-        self._pusher = pusher
-        self._interval = interval
-        self._prefix = prefix
-
-    def run(self):
-        wait_until = default_timer()
-        while True:
-            while True:
-                now = default_timer()
-                if now >= wait_until:
-                    # May need to skip some pushes.
-                    while wait_until < now:
-                        wait_until += self._interval
-                    break
-                # time.sleep can return early.
-                time.sleep(wait_until - now)
-            try:
-                self._pusher.push(prefix=self._prefix)
-            except OSError:
-                logging.exception("Push failed")
-
-
-class GraphiteBridge:
-    def __init__(self,
-                 address: Tuple[str, int],
-                 registry: Collector = REGISTRY,
-                 timeout_seconds: float = 30,
-                 _timer: Callable[[], float] = time.time,
-                 tags: bool = False,
-                 ):
-        self._address = address
-        self._registry = registry
-        self._tags = tags
-        self._timeout = timeout_seconds
-        self._timer = _timer
-
-    def push(self, prefix: str = '') -> None:
-        now = int(self._timer())
-        output = []
-
-        prefixstr = ''
-        if prefix:
-            prefixstr = prefix + '.'
-
-        for metric in self._registry.collect():
-            for s in metric.samples:
-                if s.labels:
-                    if self._tags:
-                        sep = ';'
-                        fmt = '{0}={1}'
-                    else:
-                        sep = '.'
-                        fmt = '{0}.{1}'
-                    labelstr = sep + sep.join(
-                        [fmt.format(
-                            _sanitize(k), _sanitize(v))
-                            for k, v in sorted(s.labels.items())])
-                else:
-                    labelstr = ''
-                output.append(f'{prefixstr}{_sanitize(s.name)}{labelstr} {float(s.value)} {now}\n')
-
-        conn = socket.create_connection(self._address, self._timeout)
-        conn.sendall(''.join(output).encode('ascii'))
-        conn.close()
-
-    def start(self, interval: float = 60.0, prefix: str = '') -> None:
-        t = _RegularPush(self, interval, prefix)
-        t.daemon = True
-        t.start()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py
deleted file mode 100644
index 3e8d7ced549..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/context_managers.py
+++ /dev/null
@@ -1,83 +0,0 @@
-from timeit import default_timer
-from types import TracebackType
-from typing import (
-    Any, Callable, Literal, Optional, Tuple, Type, TYPE_CHECKING, TypeVar,
-    Union,
-)
-
-from .decorator import decorate
-
-if TYPE_CHECKING:
-    from . import Counter
-    F = TypeVar("F", bound=Callable[..., Any])
-
-
-class ExceptionCounter:
-    def __init__(self, counter: "Counter", exception: Union[Type[BaseException], Tuple[Type[BaseException], ...]]) -> None:
-        self._counter = counter
-        self._exception = exception
-
-    def __enter__(self) -> None:
-        pass
-
-    def __exit__(self, typ: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> Literal[False]:
-        if isinstance(value, self._exception):
-            self._counter.inc()
-        return False
-
-    def __call__(self, f: "F") -> "F":
-        def wrapped(func, *args, **kwargs):
-            with self:
-                return func(*args, **kwargs)
-
-        return decorate(f, wrapped)
-
-
-class InprogressTracker:
-    def __init__(self, gauge):
-        self._gauge = gauge
-
-    def __enter__(self):
-        self._gauge.inc()
-
-    def __exit__(self, typ, value, traceback):
-        self._gauge.dec()
-
-    def __call__(self, f: "F") -> "F":
-        def wrapped(func, *args, **kwargs):
-            with self:
-                return func(*args, **kwargs)
-
-        return decorate(f, wrapped)
-
-
-class Timer:
-    def __init__(self, metric, callback_name):
-        self._metric = metric
-        self._callback_name = callback_name
-        self.duration = None
-
-    def _new_timer(self):
-        return self.__class__(self._metric, self._callback_name)
-
-    def __enter__(self):
-        self._start = default_timer()
-        return self
-
-    def __exit__(self, typ, value, traceback):
-        # Time can go backwards.
-        self.duration = max(default_timer() - self._start, 0)
-        callback = getattr(self._metric, self._callback_name)
-        callback(self.duration)
-
-    def labels(self, *args, **kw):
-        self._metric = self._metric.labels(*args, **kw)
-
-    def __call__(self, f: "F") -> "F":
-        def wrapped(func, *args, **kwargs):
-            # Obtaining new instance of timer every time
-            # ensures thread safety and reentrancy.
-            with self._new_timer():
-                return func(*args, **kwargs)
-
-        return decorate(f, wrapped)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py
deleted file mode 100644
index 045e90ab9b7..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/core.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from .metrics import Counter, Enum, Gauge, Histogram, Info, Summary
-from .metrics_core import (
-    CounterMetricFamily, GaugeHistogramMetricFamily, GaugeMetricFamily,
-    HistogramMetricFamily, InfoMetricFamily, Metric, StateSetMetricFamily,
-    SummaryMetricFamily, UnknownMetricFamily, UntypedMetricFamily,
-)
-from .registry import CollectorRegistry, DuplicateTimeseries, REGISTRY
-from .samples import BucketSpan, Exemplar, NativeHistogram, Sample, Timestamp
-
-__all__ = (
-    'BucketSpan',
-    'CollectorRegistry',
-    'Counter',
-    'CounterMetricFamily',
-    'DuplicateTimeseries',
-    'Enum',
-    'Exemplar',
-    'Gauge',
-    'GaugeHistogramMetricFamily',
-    'GaugeMetricFamily',
-    'Histogram',
-    'HistogramMetricFamily',
-    'Info',
-    'InfoMetricFamily',
-    'Metric',
-    'NativeHistogram',
-    'REGISTRY',
-    'Sample',
-    'StateSetMetricFamily',
-    'Summary',
-    'SummaryMetricFamily',
-    'Timestamp',
-    'UnknownMetricFamily',
-    'UntypedMetricFamily',
-)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py
deleted file mode 100644
index 1ad2c9770ec..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/decorator.py
+++ /dev/null
@@ -1,427 +0,0 @@
-# #########################     LICENSE     ############################ #
-
-# Copyright (c) 2005-2016, Michele Simionato
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-
-#   Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-#   Redistributions in bytecode form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in
-#   the documentation and/or other materials provided with the
-#   distribution.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-# DAMAGE.
-
-"""
-Decorator module, see http://pypi.python.org/pypi/decorator
-for the documentation.
-"""
-from __future__ import print_function
-
-import collections
-import inspect
-import itertools
-import operator
-import re
-import sys
-
-__version__ = '4.0.10'
-
-if sys.version_info >= (3,):
-    from inspect import getfullargspec
-
-
-    def get_init(cls):
-        return cls.__init__
-else:
-    class getfullargspec(object):
-        "A quick and dirty replacement for getfullargspec for Python 2.X"
-
-        def __init__(self, f):
-            self.args, self.varargs, self.varkw, self.defaults = \
-                inspect.getargspec(f)
-            self.kwonlyargs = []
-            self.kwonlydefaults = None
-
-        def __iter__(self):
-            yield self.args
-            yield self.varargs
-            yield self.varkw
-            yield self.defaults
-
-        getargspec = inspect.getargspec
-
-
-    def get_init(cls):
-        return cls.__init__.__func__
-
-# getargspec has been deprecated in Python 3.5
-ArgSpec = collections.namedtuple(
-    'ArgSpec', 'args varargs varkw defaults')
-
-
-def getargspec(f):
-    """A replacement for inspect.getargspec"""
-    spec = getfullargspec(f)
-    return ArgSpec(spec.args, spec.varargs, spec.varkw, spec.defaults)
-
-
-DEF = re.compile(r'\s*def\s*([_\w][_\w\d]*)\s*\(')
-
-
-# basic functionality
-class FunctionMaker(object):
-    """
-    An object with the ability to create functions with a given signature.
-    It has attributes name, doc, module, signature, defaults, dict and
-    methods update and make.
-    """
-
-    # Atomic get-and-increment provided by the GIL
-    _compile_count = itertools.count()
-
-    def __init__(self, func=None, name=None, signature=None,
-                 defaults=None, doc=None, module=None, funcdict=None):
-        self.shortsignature = signature
-        if func:
-            # func can be a class or a callable, but not an instance method
-            self.name = func.__name__
-            if self.name == '':  # small hack for lambda functions
-                self.name = '_lambda_'
-            self.doc = func.__doc__
-            self.module = func.__module__
-            if inspect.isfunction(func):
-                argspec = getfullargspec(func)
-                self.annotations = getattr(func, '__annotations__', {})
-                for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs',
-                          'kwonlydefaults'):
-                    setattr(self, a, getattr(argspec, a))
-                for i, arg in enumerate(self.args):
-                    setattr(self, 'arg%d' % i, arg)
-                if sys.version_info < (3,):  # easy way
-                    self.shortsignature = self.signature = (
-                        inspect.formatargspec(
-                            formatvalue=lambda val: "", *argspec)[1:-1])
-                else:  # Python 3 way
-                    allargs = list(self.args)
-                    allshortargs = list(self.args)
-                    if self.varargs:
-                        allargs.append('*' + self.varargs)
-                        allshortargs.append('*' + self.varargs)
-                    elif self.kwonlyargs:
-                        allargs.append('*')  # single star syntax
-                    for a in self.kwonlyargs:
-                        allargs.append('%s=None' % a)
-                        allshortargs.append('%s=%s' % (a, a))
-                    if self.varkw:
-                        allargs.append('**' + self.varkw)
-                        allshortargs.append('**' + self.varkw)
-                    self.signature = ', '.join(allargs)
-                    self.shortsignature = ', '.join(allshortargs)
-                self.dict = func.__dict__.copy()
-        # func=None happens when decorating a caller
-        if name:
-            self.name = name
-        if signature is not None:
-            self.signature = signature
-        if defaults:
-            self.defaults = defaults
-        if doc:
-            self.doc = doc
-        if module:
-            self.module = module
-        if funcdict:
-            self.dict = funcdict
-        # check existence required attributes
-        assert hasattr(self, 'name')
-        if not hasattr(self, 'signature'):
-            raise TypeError('You are decorating a non function: %s' % func)
-
-    def update(self, func, **kw):
-        "Update the signature of func with the data in self"
-        func.__name__ = self.name
-        func.__doc__ = getattr(self, 'doc', None)
-        func.__dict__ = getattr(self, 'dict', {})
-        func.__defaults__ = getattr(self, 'defaults', ())
-        func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
-        func.__annotations__ = getattr(self, 'annotations', None)
-        try:
-            frame = sys._getframe(3)
-        except AttributeError:  # for IronPython and similar implementations
-            callermodule = '?'
-        else:
-            callermodule = frame.f_globals.get('__name__', '?')
-        func.__module__ = getattr(self, 'module', callermodule)
-        func.__dict__.update(kw)
-
-    def make(self, src_templ, evaldict=None, addsource=False, **attrs):
-        "Make a new function from a given template and update the signature"
-        src = src_templ % vars(self)  # expand name and signature
-        evaldict = evaldict or {}
-        mo = DEF.match(src)
-        if mo is None:
-            raise SyntaxError('not a valid function template\n%s' % src)
-        name = mo.group(1)  # extract the function name
-        names = set([name] + [arg.strip(' *') for arg in
-                              self.shortsignature.split(',')])
-        for n in names:
-            if n in ('_func_', '_call_'):
-                raise NameError('%s is overridden in\n%s' % (n, src))
-
-        if not src.endswith('\n'):  # add a newline for old Pythons
-            src += '\n'
-
-        # Ensure each generated function has a unique filename for profilers
-        # (such as cProfile) that depend on the tuple of (,
-        # , ) being unique.
-        filename = '' % (next(self._compile_count),)
-        try:
-            code = compile(src, filename, 'single')
-            exec(code, evaldict)
-        except:
-            print('Error in generated code:', file=sys.stderr)
-            print(src, file=sys.stderr)
-            raise
-        func = evaldict[name]
-        if addsource:
-            attrs['__source__'] = src
-        self.update(func, **attrs)
-        return func
-
-    @classmethod
-    def create(cls, obj, body, evaldict, defaults=None,
-               doc=None, module=None, addsource=True, **attrs):
-        """
-        Create a function from the strings name, signature and body.
-        evaldict is the evaluation dictionary. If addsource is true an
-        attribute __source__ is added to the result. The attributes attrs
-        are added, if any.
-        """
-        if isinstance(obj, str):  # "name(signature)"
-            name, rest = obj.strip().split('(', 1)
-            signature = rest[:-1]  # strip a right parens
-            func = None
-        else:  # a function
-            name = None
-            signature = None
-            func = obj
-        self = cls(func, name, signature, defaults, doc, module)
-        ibody = '\n'.join('    ' + line for line in body.splitlines())
-        return self.make('def %(name)s(%(signature)s):\n' + ibody,
-                         evaldict, addsource, **attrs)
-
-
-def decorate(func, caller):
-    """
-    decorate(func, caller) decorates a function using a caller.
-    """
-    evaldict = dict(_call_=caller, _func_=func)
-    fun = FunctionMaker.create(
-        func, "return _call_(_func_, %(shortsignature)s)",
-        evaldict, __wrapped__=func)
-    if hasattr(func, '__qualname__'):
-        fun.__qualname__ = func.__qualname__
-    return fun
-
-
-def decorator(caller, _func=None):
-    """decorator(caller) converts a caller function into a decorator"""
-    if _func is not None:  # return a decorated function
-        # this is obsolete behavior; you should use decorate instead
-        return decorate(_func, caller)
-    # else return a decorator function
-    if inspect.isclass(caller):
-        name = caller.__name__.lower()
-        doc = 'decorator(%s) converts functions/generators into ' \
-              'factories of %s objects' % (caller.__name__, caller.__name__)
-    elif inspect.isfunction(caller):
-        if caller.__name__ == '':
-            name = '_lambda_'
-        else:
-            name = caller.__name__
-        doc = caller.__doc__
-    else:  # assume caller is an object with a __call__ method
-        name = caller.__class__.__name__.lower()
-        doc = caller.__call__.__doc__
-    evaldict = dict(_call_=caller, _decorate_=decorate)
-    return FunctionMaker.create(
-        '%s(func)' % name, 'return _decorate_(func, _call_)',
-        evaldict, doc=doc, module=caller.__module__,
-        __wrapped__=caller)
-
-
-# ####################### contextmanager ####################### #
-
-try:  # Python >= 3.2
-    from contextlib import _GeneratorContextManager
-except ImportError:  # Python >= 2.5
-    from contextlib import GeneratorContextManager as _GeneratorContextManager
-
-
-class ContextManager(_GeneratorContextManager):
-    def __call__(self, func):
-        """Context manager decorator"""
-        return FunctionMaker.create(
-            func, "with _self_: return _func_(%(shortsignature)s)",
-            dict(_self_=self, _func_=func), __wrapped__=func)
-
-
-init = getfullargspec(_GeneratorContextManager.__init__)
-n_args = len(init.args)
-if n_args == 2 and not init.varargs:  # (self, genobj) Python 2.7
-    def __init__(self, g, *a, **k):
-        return _GeneratorContextManager.__init__(self, g(*a, **k))
-
-
-    ContextManager.__init__ = __init__
-elif n_args == 2 and init.varargs:  # (self, gen, *a, **k) Python 3.4
-    pass
-elif n_args == 4:  # (self, gen, args, kwds) Python 3.5
-    def __init__(self, g, *a, **k):
-        return _GeneratorContextManager.__init__(self, g, a, k)
-
-
-    ContextManager.__init__ = __init__
-
-contextmanager = decorator(ContextManager)
-
-
-# ############################ dispatch_on ############################ #
-
-def append(a, vancestors):
-    """
-    Append ``a`` to the list of the virtual ancestors, unless it is already
-    included.
-    """
-    add = True
-    for j, va in enumerate(vancestors):
-        if issubclass(va, a):
-            add = False
-            break
-        if issubclass(a, va):
-            vancestors[j] = a
-            add = False
-    if add:
-        vancestors.append(a)
-
-
-# inspired from simplegeneric by P.J. Eby and functools.singledispatch
-def dispatch_on(*dispatch_args):
-    """
-    Factory of decorators turning a function into a generic function
-    dispatching on the given arguments.
-    """
-    assert dispatch_args, 'No dispatch args passed'
-    dispatch_str = '(%s,)' % ', '.join(dispatch_args)
-
-    def check(arguments, wrong=operator.ne, msg=''):
-        """Make sure one passes the expected number of arguments"""
-        if wrong(len(arguments), len(dispatch_args)):
-            raise TypeError('Expected %d arguments, got %d%s' %
-                            (len(dispatch_args), len(arguments), msg))
-
-    def gen_func_dec(func):
-        """Decorator turning a function into a generic function"""
-
-        # first check the dispatch arguments
-        argset = set(getfullargspec(func).args)
-        if not set(dispatch_args) <= argset:
-            raise NameError('Unknown dispatch arguments %s' % dispatch_str)
-
-        typemap = {}
-
-        def vancestors(*types):
-            """
-            Get a list of sets of virtual ancestors for the given types
-            """
-            check(types)
-            ras = [[] for _ in range(len(dispatch_args))]
-            for types_ in typemap:
-                for t, type_, ra in zip(types, types_, ras):
-                    if issubclass(t, type_) and type_ not in t.__mro__:
-                        append(type_, ra)
-            return [set(ra) for ra in ras]
-
-        def ancestors(*types):
-            """
-            Get a list of virtual MROs, one for each type
-            """
-            check(types)
-            lists = []
-            for t, vas in zip(types, vancestors(*types)):
-                n_vas = len(vas)
-                if n_vas > 1:
-                    raise RuntimeError(
-                        'Ambiguous dispatch for %s: %s' % (t, vas))
-                elif n_vas == 1:
-                    va, = vas
-                    mro = type('t', (t, va), {}).__mro__[1:]
-                else:
-                    mro = t.__mro__
-                lists.append(mro[:-1])  # discard t and object
-            return lists
-
-        def register(*types):
-            """
-            Decorator to register an implementation for the given types
-            """
-            check(types)
-
-            def dec(f):
-                check(getfullargspec(f).args, operator.lt, ' in ' + f.__name__)
-                typemap[types] = f
-                return f
-
-            return dec
-
-        def dispatch_info(*types):
-            """
-            An utility to introspect the dispatch algorithm
-            """
-            check(types)
-            lst = []
-            for anc in itertools.product(*ancestors(*types)):
-                lst.append(tuple(a.__name__ for a in anc))
-            return lst
-
-        def _dispatch(dispatch_args, *args, **kw):
-            types = tuple(type(arg) for arg in dispatch_args)
-            try:  # fast path
-                f = typemap[types]
-            except KeyError:
-                pass
-            else:
-                return f(*args, **kw)
-            combinations = itertools.product(*ancestors(*types))
-            next(combinations)  # the first one has been already tried
-            for types_ in combinations:
-                f = typemap.get(types_)
-                if f is not None:
-                    return f(*args, **kw)
-
-            # else call the default implementation
-            return func(*args, **kw)
-
-        return FunctionMaker.create(
-            func, 'return _f_(%s, %%(shortsignature)s)' % dispatch_str,
-            dict(_f_=_dispatch), register=register, default=func,
-            typemap=typemap, vancestors=vancestors, ancestors=ancestors,
-            dispatch_info=dispatch_info, __wrapped__=func)
-
-    gen_func_dec.__name__ = 'dispatch_on' + dispatch_str
-    return gen_func_dec
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py
deleted file mode 100644
index 0b63f6f6efb..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/exposition.py
+++ /dev/null
@@ -1,828 +0,0 @@
-import base64
-from contextlib import closing
-from functools import partial
-import gzip
-from http.server import BaseHTTPRequestHandler
-import os
-import socket
-from socketserver import ThreadingMixIn
-import ssl
-import sys
-import threading
-from typing import (
-    Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union,
-)
-from urllib.error import HTTPError
-from urllib.parse import parse_qs, quote_plus, urlparse
-from urllib.request import (
-    BaseHandler, build_opener, HTTPHandler, HTTPRedirectHandler, HTTPSHandler,
-    Request,
-)
-from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer
-
-from .openmetrics import exposition as openmetrics
-from .registry import Collector, REGISTRY
-from .utils import floatToGoString, parse_version
-
-try:
-    import snappy  # type: ignore
-    SNAPPY_AVAILABLE = True
-except ImportError:
-    snappy = None  # type: ignore
-    SNAPPY_AVAILABLE = False
-
-__all__ = (
-    'CONTENT_TYPE_LATEST',
-    'CONTENT_TYPE_PLAIN_0_0_4',
-    'CONTENT_TYPE_PLAIN_1_0_0',
-    'delete_from_gateway',
-    'generate_latest',
-    'instance_ip_grouping_key',
-    'make_asgi_app',
-    'make_wsgi_app',
-    'MetricsHandler',
-    'push_to_gateway',
-    'pushadd_to_gateway',
-    'start_http_server',
-    'start_wsgi_server',
-    'write_to_textfile',
-)
-
-CONTENT_TYPE_PLAIN_0_0_4 = 'text/plain; version=0.0.4; charset=utf-8'
-"""Content type of the compatibility format"""
-
-CONTENT_TYPE_PLAIN_1_0_0 = 'text/plain; version=1.0.0; charset=utf-8'
-"""Content type of the latest format"""
-
-CONTENT_TYPE_LATEST = CONTENT_TYPE_PLAIN_1_0_0
-CompressionType = Optional[Literal['gzip', 'snappy']]
-
-
-class _PrometheusRedirectHandler(HTTPRedirectHandler):
-    """
-    Allow additional methods (e.g. PUT) and data forwarding in redirects.
-
-    Use of this class constitute a user's explicit agreement to the
-    redirect responses the Prometheus client will receive when using it.
-    You should only use this class if you control or otherwise trust the
-    redirect behavior involved and are certain it is safe to full transfer
-    the original request (method and data) to the redirected URL. For
-    example, if you know there is a cosmetic URL redirect in front of a
-    local deployment of a Prometheus server, and all redirects are safe,
-    this is the class to use to handle redirects in that case.
-
-    The standard HTTPRedirectHandler does not forward request data nor
-    does it allow redirected PUT requests (which Prometheus uses for some
-    operations, for example `push_to_gateway`) because these cannot
-    generically guarantee no violations of HTTP RFC 2616 requirements for
-    the user to explicitly confirm redirects that could have unexpected
-    side effects (such as rendering a PUT request non-idempotent or
-    creating multiple resources not named in the original request).
-    """
-
-    def redirect_request(self, req, fp, code, msg, headers, newurl):
-        """
-        Apply redirect logic to a request.
-
-        See parent HTTPRedirectHandler.redirect_request for parameter info.
-
-        If the redirect is disallowed, this raises the corresponding HTTP error.
-        If the redirect can't be determined, return None to allow other handlers
-        to try. If the redirect is allowed, return the new request.
-
-        This method specialized for the case when (a) the user knows that the
-        redirect will not cause unacceptable side effects for any request method,
-        and (b) the user knows that any request data should be passed through to
-        the redirect. If either condition is not met, this should not be used.
-        """
-        # note that requests being provided by a handler will use get_method to
-        # indicate the method, by monkeypatching this, instead of setting the
-        # Request object's method attribute.
-        m = getattr(req, "method", req.get_method())
-        if not (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
-                or code in (301, 302, 303) and m in ("POST", "PUT")):
-            raise HTTPError(req.full_url, code, msg, headers, fp)
-        new_request = Request(
-            newurl.replace(' ', '%20'),  # space escaping in new url if needed.
-            headers=req.headers,
-            origin_req_host=req.origin_req_host,
-            unverifiable=True,
-            data=req.data,
-        )
-        new_request.method = m
-        return new_request
-
-
-def _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression):
-    """Bake output for metrics output."""
-    # Choose the correct plain text format of the output.
-    encoder, content_type = choose_encoder(accept_header)
-    if 'name[]' in params:
-        registry = registry.restricted_registry(params['name[]'])
-    output = encoder(registry)
-    headers = [('Content-Type', content_type)]
-    # If gzip encoding required, gzip the output.
-    if not disable_compression and gzip_accepted(accept_encoding_header):
-        output = gzip.compress(output)
-        headers.append(('Content-Encoding', 'gzip'))
-    return '200 OK', headers, output
-
-
-def make_wsgi_app(registry: Collector = REGISTRY, disable_compression: bool = False) -> Callable:
-    """Create a WSGI app which serves the metrics from a registry."""
-
-    def prometheus_app(environ, start_response):
-        # Prepare parameters
-        accept_header = environ.get('HTTP_ACCEPT')
-        accept_encoding_header = environ.get('HTTP_ACCEPT_ENCODING')
-        params = parse_qs(environ.get('QUERY_STRING', ''))
-        method = environ['REQUEST_METHOD']
-
-        if method == 'OPTIONS':
-            status = '200 OK'
-            headers = [('Allow', 'OPTIONS,GET')]
-            output = b''
-        elif method != 'GET':
-            status = '405 Method Not Allowed'
-            headers = [('Allow', 'OPTIONS,GET')]
-            output = '# HTTP {}: {}; use OPTIONS or GET\n'.format(status, method).encode()
-        elif environ['PATH_INFO'] == '/favicon.ico':
-            # Serve empty response for browsers
-            status = '200 OK'
-            headers = []
-            output = b''
-        else:
-            # Note: For backwards compatibility, the URI path for GET is not
-            # constrained to the documented /metrics, but any path is allowed.
-            # Bake output
-            status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, disable_compression)
-        # Return output
-        start_response(status, headers)
-        return [output]
-
-    return prometheus_app
-
-
-class _SilentHandler(WSGIRequestHandler):
-    """WSGI handler that does not log requests."""
-
-    def log_message(self, format, *args):
-        """Log nothing."""
-
-
-class ThreadingWSGIServer(ThreadingMixIn, WSGIServer):
-    """Thread per request HTTP server."""
-    # Make worker threads "fire and forget". Beginning with Python 3.7 this
-    # prevents a memory leak because ``ThreadingMixIn`` starts to gather all
-    # non-daemon threads in a list in order to join on them at server close.
-    daemon_threads = True
-
-
-def _get_best_family(address, port):
-    """Automatically select address family depending on address"""
-    # HTTPServer defaults to AF_INET, which will not start properly if
-    # binding an ipv6 address is requested.
-    # This function is based on what upstream python did for http.server
-    # in https://github.com/python/cpython/pull/11767
-    infos = socket.getaddrinfo(address, port, type=socket.SOCK_STREAM, flags=socket.AI_PASSIVE)
-    family, _, _, _, sockaddr = next(iter(infos))
-    return family, sockaddr[0]
-
-
-def _get_ssl_ctx(
-        certfile: str,
-        keyfile: str,
-        protocol: int,
-        cafile: Optional[str] = None,
-        capath: Optional[str] = None,
-        client_auth_required: bool = False,
-        tls_min_version: Optional[ssl.TLSVersion] = None,
-        tls_max_version: Optional[ssl.TLSVersion] = None
-) -> ssl.SSLContext:
-    """Load context supports SSL."""
-    ssl_cxt = ssl.SSLContext(protocol=protocol)
-
-    if cafile is not None or capath is not None:
-        try:
-            ssl_cxt.load_verify_locations(cafile, capath)
-        except IOError as exc:
-            exc_type = type(exc)
-            msg = str(exc)
-            raise exc_type(f"Cannot load CA certificate chain from file "
-                           f"{cafile!r} or directory {capath!r}: {msg}")
-    else:
-        try:
-            ssl_cxt.load_default_certs(purpose=ssl.Purpose.CLIENT_AUTH)
-        except IOError as exc:
-            exc_type = type(exc)
-            msg = str(exc)
-            raise exc_type(f"Cannot load default CA certificate chain: {msg}")
-
-    if client_auth_required:
-        ssl_cxt.verify_mode = ssl.CERT_REQUIRED
-
-    try:
-        ssl_cxt.load_cert_chain(certfile=certfile, keyfile=keyfile)
-    except IOError as exc:
-        exc_type = type(exc)
-        msg = str(exc)
-        raise exc_type(f"Cannot load server certificate file {certfile!r} or "
-                       f"its private key file {keyfile!r}: {msg}")
-
-    if tls_min_version is not None:
-        ssl_cxt.minimum_version = tls_min_version
-    if tls_max_version is not None:
-        ssl_cxt.maximum_version = tls_max_version
-
-    return ssl_cxt
-
-
-def start_wsgi_server(
-        port: int,
-        addr: str = '0.0.0.0',
-        registry: Collector = REGISTRY,
-        certfile: Optional[str] = None,
-        keyfile: Optional[str] = None,
-        client_cafile: Optional[str] = None,
-        client_capath: Optional[str] = None,
-        protocol: int = ssl.PROTOCOL_TLS_SERVER,
-        client_auth_required: bool = False,
-        tls_min_version: Optional[ssl.TLSVersion] = None,
-        tls_max_version: Optional[ssl.TLSVersion] = None
-) -> Tuple[WSGIServer, threading.Thread]:
-    """Starts a WSGI server for prometheus metrics as a daemon thread."""
-
-    class TmpServer(ThreadingWSGIServer):
-        """Copy of ThreadingWSGIServer to update address_family locally"""
-
-    TmpServer.address_family, addr = _get_best_family(addr, port)
-    app = make_wsgi_app(registry)
-    httpd = make_server(addr, port, app, TmpServer, handler_class=_SilentHandler)
-    if certfile and keyfile:
-        context = _get_ssl_ctx(
-            certfile,
-            keyfile,
-            protocol,
-            client_cafile,
-            client_capath,
-            client_auth_required,
-            tls_min_version,
-            tls_max_version
-        )
-        httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
-    t = threading.Thread(target=httpd.serve_forever)
-    t.daemon = True
-    t.start()
-
-    return httpd, t
-
-
-start_http_server = start_wsgi_server
-
-
-def generate_latest(registry: Collector = REGISTRY, escaping: str = openmetrics.UNDERSCORES) -> bytes:
-    """
-    Generates the exposition format using the basic Prometheus text format.
-
-    Params:
-        registry: Collector to export data from.
-        escaping: Escaping scheme used for metric and label names.
-
-    Returns: UTF-8 encoded string containing the metrics in text format.
-    """
-
-    def sample_line(samples):
-        if samples.labels:
-            labelstr = '{0}'.format(','.join(
-                # Label values always support UTF-8
-                ['{}="{}"'.format(
-                    openmetrics.escape_label_name(k, escaping), openmetrics._escape(v, openmetrics.ALLOWUTF8, False))
-                    for k, v in sorted(samples.labels.items())]))
-        else:
-            labelstr = ''
-        timestamp = ''
-        if samples.timestamp is not None:
-            # Convert to milliseconds.
-            timestamp = f' {int(float(samples.timestamp) * 1000):d}'
-        if escaping != openmetrics.ALLOWUTF8 or openmetrics._is_valid_legacy_metric_name(samples.name):
-            if labelstr:
-                labelstr = '{{{0}}}'.format(labelstr)
-            return f'{openmetrics.escape_metric_name(samples.name, escaping)}{labelstr} {floatToGoString(samples.value)}{timestamp}\n'
-        maybe_comma = ''
-        if labelstr:
-            maybe_comma = ','
-        return f'{{{openmetrics.escape_metric_name(samples.name, escaping)}{maybe_comma}{labelstr}}} {floatToGoString(samples.value)}{timestamp}\n'
-
-    output = []
-    for metric in registry.collect():
-        try:
-            mname = metric.name
-            mtype = metric.type
-            # Munging from OpenMetrics into Prometheus format.
-            if mtype == 'counter':
-                mname = mname + '_total'
-            elif mtype == 'info':
-                mname = mname + '_info'
-                mtype = 'gauge'
-            elif mtype == 'stateset':
-                mtype = 'gauge'
-            elif mtype == 'gaugehistogram':
-                # A gauge histogram is really a gauge,
-                # but this captures the structure better.
-                mtype = 'histogram'
-            elif mtype == 'unknown':
-                mtype = 'untyped'
-
-            output.append('# HELP {} {}\n'.format(
-                openmetrics.escape_metric_name(mname, escaping), metric.documentation.replace('\\', r'\\').replace('\n', r'\n')))
-            output.append(f'# TYPE {openmetrics.escape_metric_name(mname, escaping)} {mtype}\n')
-
-            om_samples: Dict[str, List[str]] = {}
-            for s in metric.samples:
-                for suffix in ['_created', '_gsum', '_gcount']:
-                    if s.name == metric.name + suffix:
-                        # OpenMetrics specific sample, put in a gauge at the end.
-                        om_samples.setdefault(suffix, []).append(sample_line(s))
-                        break
-                else:
-                    output.append(sample_line(s))
-        except Exception as exception:
-            exception.args = (exception.args or ('',)) + (metric,)
-            raise
-
-        for suffix, lines in sorted(om_samples.items()):
-            output.append('# HELP {} {}\n'.format(openmetrics.escape_metric_name(metric.name + suffix, escaping),
-                                                  metric.documentation.replace('\\', r'\\').replace('\n', r'\n')))
-            output.append(f'# TYPE {openmetrics.escape_metric_name(metric.name + suffix, escaping)} gauge\n')
-            output.extend(lines)
-    return ''.join(output).encode('utf-8')
-
-
-def choose_encoder(accept_header: str) -> Tuple[Callable[[Collector], bytes], str]:
-    # Python client library accepts a narrower range of content-types than
-    # Prometheus does.
-    accept_header = accept_header or ''
-    escaping = openmetrics.UNDERSCORES
-    for accepted in accept_header.split(','):
-        if accepted.split(';')[0].strip() == 'application/openmetrics-text':
-            toks = accepted.split(';')
-            version = _get_version(toks)
-            escaping = _get_escaping(toks)
-            # Only return an escaping header if we have a good version and
-            # mimetype.
-            if not version:
-                return (partial(openmetrics.generate_latest, escaping=openmetrics.UNDERSCORES, version="1.0.0"), openmetrics.CONTENT_TYPE_LATEST)
-            if version and parse_version(version) >= (1, 0, 0):
-                return (partial(openmetrics.generate_latest, escaping=escaping, version=version),
-                        f'application/openmetrics-text; version={version}; charset=utf-8; escaping=' + str(escaping))
-        elif accepted.split(';')[0].strip() == 'text/plain':
-            toks = accepted.split(';')
-            version = _get_version(toks)
-            escaping = _get_escaping(toks)
-            # Only return an escaping header if we have a good version and
-            # mimetype.
-            if version and parse_version(version) >= (1, 0, 0):
-                return (partial(generate_latest, escaping=escaping),
-                        CONTENT_TYPE_LATEST + '; escaping=' + str(escaping))
-    return generate_latest, CONTENT_TYPE_PLAIN_0_0_4
-
-
-def _get_version(accept_header: List[str]) -> str:
-    """Return the version tag from the Accept header.
-
-    If no version is specified, returns empty string."""
-
-    for tok in accept_header:
-        if '=' not in tok:
-            continue
-        key, value = tok.strip().split('=', 1)
-        if key == 'version':
-            return value
-    return ""
-
-
-def _get_escaping(accept_header: List[str]) -> str:
-    """Return the escaping scheme from the Accept header.
-
-    If no escaping scheme is specified or the scheme is not one of the allowed
-    strings, defaults to UNDERSCORES."""
-
-    for tok in accept_header:
-        if '=' not in tok:
-            continue
-        key, value = tok.strip().split('=', 1)
-        if key != 'escaping':
-            continue
-        if value == openmetrics.ALLOWUTF8:
-            return openmetrics.ALLOWUTF8
-        elif value == openmetrics.UNDERSCORES:
-            return openmetrics.UNDERSCORES
-        elif value == openmetrics.DOTS:
-            return openmetrics.DOTS
-        elif value == openmetrics.VALUES:
-            return openmetrics.VALUES
-        else:
-            return openmetrics.UNDERSCORES
-    return openmetrics.UNDERSCORES
-
-
-def gzip_accepted(accept_encoding_header: str) -> bool:
-    accept_encoding_header = accept_encoding_header or ''
-    for accepted in accept_encoding_header.split(','):
-        if accepted.split(';')[0].strip().lower() == 'gzip':
-            return True
-    return False
-
-
-class MetricsHandler(BaseHTTPRequestHandler):
-    """HTTP handler that gives metrics from ``REGISTRY``."""
-    registry: Collector = REGISTRY
-
-    def do_GET(self) -> None:
-        # Prepare parameters
-        registry = self.registry
-        accept_header = self.headers.get('Accept')
-        accept_encoding_header = self.headers.get('Accept-Encoding')
-        params = parse_qs(urlparse(self.path).query)
-        # Bake output
-        status, headers, output = _bake_output(registry, accept_header, accept_encoding_header, params, False)
-        # Return output
-        self.send_response(int(status.split(' ')[0]))
-        for header in headers:
-            self.send_header(*header)
-        self.end_headers()
-        self.wfile.write(output)
-
-    def log_message(self, format: str, *args: Any) -> None:
-        """Log nothing."""
-
-    @classmethod
-    def factory(cls, registry: Collector) -> type:
-        """Returns a dynamic MetricsHandler class tied
-           to the passed registry.
-        """
-        # This implementation relies on MetricsHandler.registry
-        #  (defined above and defaulted to REGISTRY).
-
-        # As we have unicode_literals, we need to create a str()
-        #  object for type().
-        cls_name = str(cls.__name__)
-        MyMetricsHandler = type(cls_name, (cls, object),
-                                {"registry": registry})
-        return MyMetricsHandler
-
-
-def write_to_textfile(path: str, registry: Collector, escaping: str = openmetrics.ALLOWUTF8, tmpdir: Optional[str] = None) -> None:
-    """Write metrics to the given path.
-
-    This is intended for use with the Node exporter textfile collector.
-    The path must end in .prom for the textfile collector to process it.
-
-    An optional tmpdir parameter can be set to determine where the
-    metrics will be temporarily written to. If not set, it will be in
-    the same directory as the .prom file. If provided, the path MUST be
-    on the same filesystem."""
-    if tmpdir is not None:
-        filename = os.path.basename(path)
-        tmppath = f'{os.path.join(tmpdir, filename)}.{os.getpid()}.{threading.current_thread().ident}'
-    else:
-        tmppath = f'{path}.{os.getpid()}.{threading.current_thread().ident}'
-    try:
-        with open(tmppath, 'wb') as f:
-            f.write(generate_latest(registry, escaping))
-
-        # rename(2) is atomic but fails on Windows if the destination file exists
-        if os.name == 'nt':
-            os.replace(tmppath, path)
-        else:
-            os.rename(tmppath, path)
-    except Exception:
-        if os.path.exists(tmppath):
-            os.remove(tmppath)
-        raise
-
-
-def _make_handler(
-        url: str,
-        method: str,
-        timeout: Optional[float],
-        headers: Sequence[Tuple[str, str]],
-        data: bytes,
-        base_handler: Union[BaseHandler, type],
-) -> Callable[[], None]:
-    def handle() -> None:
-        request = Request(url, data=data)
-        request.get_method = lambda: method  # type: ignore
-        for k, v in headers:
-            request.add_header(k, v)
-        resp = build_opener(base_handler).open(request, timeout=timeout)
-        if resp.code >= 400:
-            raise OSError(f"error talking to pushgateway: {resp.code} {resp.msg}")
-
-    return handle
-
-
-def default_handler(
-        url: str,
-        method: str,
-        timeout: Optional[float],
-        headers: List[Tuple[str, str]],
-        data: bytes,
-) -> Callable[[], None]:
-    """Default handler that implements HTTP/HTTPS connections.
-
-    Used by the push_to_gateway functions. Can be re-used by other handlers."""
-
-    return _make_handler(url, method, timeout, headers, data, HTTPHandler)
-
-
-def passthrough_redirect_handler(
-        url: str,
-        method: str,
-        timeout: Optional[float],
-        headers: List[Tuple[str, str]],
-        data: bytes,
-) -> Callable[[], None]:
-    """
-    Handler that automatically trusts redirect responses for all HTTP methods.
-
-    Augments standard HTTPRedirectHandler capability by permitting PUT requests,
-    preserving the method upon redirect, and passing through all headers and
-    data from the original request. Only use this handler if you control or
-    trust the source of redirect responses you encounter when making requests
-    via the Prometheus client. This handler will simply repeat the identical
-    request, including same method and data, to the new redirect URL."""
-
-    return _make_handler(url, method, timeout, headers, data, _PrometheusRedirectHandler)
-
-
-def basic_auth_handler(
-        url: str,
-        method: str,
-        timeout: Optional[float],
-        headers: List[Tuple[str, str]],
-        data: bytes,
-        username: Optional[str] = None,
-        password: Optional[str] = None,
-) -> Callable[[], None]:
-    """Handler that implements HTTP/HTTPS connections with Basic Auth.
-
-    Sets auth headers using supplied 'username' and 'password', if set.
-    Used by the push_to_gateway functions. Can be re-used by other handlers."""
-
-    def handle():
-        """Handler that implements HTTP Basic Auth.
-        """
-        if username is not None and password is not None:
-            auth_value = f'{username}:{password}'.encode()
-            auth_token = base64.b64encode(auth_value)
-            auth_header = b'Basic ' + auth_token
-            headers.append(('Authorization', auth_header))
-        default_handler(url, method, timeout, headers, data)()
-
-    return handle
-
-
-def tls_auth_handler(
-        url: str,
-        method: str,
-        timeout: Optional[float],
-        headers: List[Tuple[str, str]],
-        data: bytes,
-        certfile: str,
-        keyfile: str,
-        cafile: Optional[str] = None,
-        protocol: int = ssl.PROTOCOL_TLS_CLIENT,
-        insecure_skip_verify: bool = False,
-) -> Callable[[], None]:
-    """Handler that implements an HTTPS connection with TLS Auth.
-
-    The default protocol (ssl.PROTOCOL_TLS_CLIENT) will also enable
-    ssl.CERT_REQUIRED and SSLContext.check_hostname by default. This can be
-    disabled by setting insecure_skip_verify to True.
-
-    Both this handler and the TLS feature on pushgateay are experimental."""
-    context = ssl.SSLContext(protocol=protocol)
-    if cafile is not None:
-        context.load_verify_locations(cafile)
-    else:
-        context.load_default_certs()
-
-    if insecure_skip_verify:
-        context.check_hostname = False
-        context.verify_mode = ssl.CERT_NONE
-
-    context.load_cert_chain(certfile=certfile, keyfile=keyfile)
-    handler = HTTPSHandler(context=context)
-    return _make_handler(url, method, timeout, headers, data, handler)
-
-
-def push_to_gateway(
-        gateway: str,
-        job: str,
-        registry: Collector,
-        grouping_key: Optional[Dict[str, Any]] = None,
-        timeout: Optional[float] = 30,
-        handler: Callable = default_handler,
-        compression: CompressionType = None,
-) -> None:
-    """Push metrics to the given pushgateway.
-
-    `gateway` the url for your push gateway. Either of the form
-              'http://pushgateway.local', or 'pushgateway.local'.
-              Scheme defaults to 'http' if none is provided
-    `job` is the job label to be attached to all pushed metrics
-    `registry` is a Collector, normally an instance of CollectorRegistry
-    `grouping_key` please see the pushgateway documentation for details.
-                   Defaults to None
-    `timeout` is how long push will attempt to connect before giving up.
-              Defaults to 30s, can be set to None for no timeout.
-    `handler` is an optional function which can be provided to perform
-              requests to the 'gateway'.
-              Defaults to None, in which case an http or https request
-              will be carried out by a default handler.
-              If not None, the argument must be a function which accepts
-              the following arguments:
-              url, method, timeout, headers, and content
-              May be used to implement additional functionality not
-              supported by the built-in default handler (such as SSL
-              client certicates, and HTTP authentication mechanisms).
-              'url' is the URL for the request, the 'gateway' argument
-              described earlier will form the basis of this URL.
-              'method' is the HTTP method which should be used when
-              carrying out the request.
-              'timeout' requests not successfully completed after this
-              many seconds should be aborted.  If timeout is None, then
-              the handler should not set a timeout.
-              'headers' is a list of ("header-name","header-value") tuples
-              which must be passed to the pushgateway in the form of HTTP
-              request headers.
-              The function should raise an exception (e.g. IOError) on
-              failure.
-              'content' is the data which should be used to form the HTTP
-              Message Body.
-    `compression` selects the payload compression. Supported values are 'gzip'
-                  and 'snappy'. Defaults to None (no compression).
-
-    This overwrites all metrics with the same job and grouping_key.
-    This uses the PUT HTTP method."""
-    _use_gateway('PUT', gateway, job, registry, grouping_key, timeout, handler, compression)
-
-
-def pushadd_to_gateway(
-        gateway: str,
-        job: str,
-        registry: Optional[Collector],
-        grouping_key: Optional[Dict[str, Any]] = None,
-        timeout: Optional[float] = 30,
-        handler: Callable = default_handler,
-        compression: CompressionType = None,
-) -> None:
-    """PushAdd metrics to the given pushgateway.
-
-    `gateway` the url for your push gateway. Either of the form
-              'http://pushgateway.local', or 'pushgateway.local'.
-              Scheme defaults to 'http' if none is provided
-    `job` is the job label to be attached to all pushed metrics
-    `registry` is a Collector, normally an instance of CollectorRegistry
-    `grouping_key` please see the pushgateway documentation for details.
-                   Defaults to None
-    `timeout` is how long push will attempt to connect before giving up.
-              Defaults to 30s, can be set to None for no timeout.
-    `handler` is an optional function which can be provided to perform
-              requests to the 'gateway'.
-              Defaults to None, in which case an http or https request
-              will be carried out by a default handler.
-              See the 'prometheus_client.push_to_gateway' documentation
-              for implementation requirements.
-    `compression` selects the payload compression. Supported values are 'gzip'
-                  and 'snappy'. Defaults to None (no compression).
-
-    This replaces metrics with the same name, job and grouping_key.
-    This uses the POST HTTP method."""
-    _use_gateway('POST', gateway, job, registry, grouping_key, timeout, handler, compression)
-
-
-def delete_from_gateway(
-        gateway: str,
-        job: str,
-        grouping_key: Optional[Dict[str, Any]] = None,
-        timeout: Optional[float] = 30,
-        handler: Callable = default_handler,
-) -> None:
-    """Delete metrics from the given pushgateway.
-
-    `gateway` the url for your push gateway. Either of the form
-              'http://pushgateway.local', or 'pushgateway.local'.
-              Scheme defaults to 'http' if none is provided
-    `job` is the job label to be attached to all pushed metrics
-    `grouping_key` please see the pushgateway documentation for details.
-                   Defaults to None
-    `timeout` is how long delete will attempt to connect before giving up.
-              Defaults to 30s, can be set to None for no timeout.
-    `handler` is an optional function which can be provided to perform
-              requests to the 'gateway'.
-              Defaults to None, in which case an http or https request
-              will be carried out by a default handler.
-              See the 'prometheus_client.push_to_gateway' documentation
-              for implementation requirements.
-
-    This deletes metrics with the given job and grouping_key.
-    This uses the DELETE HTTP method."""
-    _use_gateway('DELETE', gateway, job, None, grouping_key, timeout, handler)
-
-
-def _use_gateway(
-        method: str,
-        gateway: str,
-        job: str,
-        registry: Optional[Collector],
-        grouping_key: Optional[Dict[str, Any]],
-        timeout: Optional[float],
-        handler: Callable,
-        compression: CompressionType = None,
-) -> None:
-    gateway_url = urlparse(gateway)
-    # See https://bugs.python.org/issue27657 for details on urlparse in py>=3.7.6.
-    if not gateway_url.scheme or gateway_url.scheme not in ['http', 'https']:
-        gateway = f'http://{gateway}'
-
-    gateway = gateway.rstrip('/')
-    url = '{}/metrics/{}/{}'.format(gateway, *_escape_grouping_key("job", job))
-
-    if grouping_key is None:
-        grouping_key = {}
-    url += ''.join(
-        '/{}/{}'.format(*_escape_grouping_key(str(k), str(v)))
-        for k, v in sorted(grouping_key.items()))
-
-    data = b''
-    headers: List[Tuple[str, str]] = []
-    if method != 'DELETE':
-        if registry is None:
-            registry = REGISTRY
-        data = generate_latest(registry)
-        data, headers = _compress_payload(data, compression)
-    else:
-        # DELETE requests still need Content-Type header per test expectations
-        headers = [('Content-Type', CONTENT_TYPE_PLAIN_0_0_4)]
-        if compression is not None:
-            raise ValueError('Compression is not supported for DELETE requests.')
-
-    handler(
-        url=url, method=method, timeout=timeout,
-        headers=headers, data=data,
-    )()
-
-
-def _compress_payload(data: bytes, compression: CompressionType) -> Tuple[bytes, List[Tuple[str, str]]]:
-    headers = [('Content-Type', CONTENT_TYPE_PLAIN_0_0_4)]
-    if compression is None:
-        return data, headers
-
-    encoding = compression.lower()
-    if encoding == 'gzip':
-        headers.append(('Content-Encoding', 'gzip'))
-        return gzip.compress(data), headers
-    if encoding == 'snappy':
-        if not SNAPPY_AVAILABLE:
-            raise RuntimeError('Snappy compression requires the python-snappy package to be installed.')
-        headers.append(('Content-Encoding', 'snappy'))
-        compressor = snappy.StreamCompressor()
-        compressed = compressor.compress(data)
-        flush = getattr(compressor, 'flush', None)
-        if callable(flush):
-            compressed += flush()
-        return compressed, headers
-    raise ValueError(f"Unsupported compression type: {compression}")
-
-
-def _escape_grouping_key(k, v):
-    if v == "":
-        # Per https://github.com/prometheus/pushgateway/pull/346.
-        return k + "@base64", "="
-    elif '/' in v or ' ' in v:
-        # Added in Pushgateway 0.9.0.
-        # Use base64 encoding for values containing slashes or spaces
-        return k + "@base64", base64.urlsafe_b64encode(v.encode("utf-8")).decode("utf-8")
-    else:
-        return k, quote_plus(v)
-
-
-def instance_ip_grouping_key() -> Dict[str, Any]:
-    """Grouping key with instance set to the IP Address of this host."""
-    with closing(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) as s:
-        if sys.platform == 'darwin':
-            # This check is done this way only on MacOS devices
-            # it is done this way because the localhost method does
-            # not work.
-            # This method was adapted from this StackOverflow answer:
-            # https://stackoverflow.com/a/28950776
-            s.connect(('10.255.255.255', 1))
-        else:
-            s.connect(('localhost', 0))
-
-        return {'instance': s.getsockname()[0]}
-
-
-from .asgi import make_asgi_app  # noqa
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py
deleted file mode 100644
index 06e52dfc3c8..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/gc_collector.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import gc
-import platform
-from typing import Iterable
-
-from .metrics_core import CounterMetricFamily, Metric
-from .registry import Collector, CollectorRegistry, REGISTRY
-
-
-class GCCollector(Collector):
-    """Collector for Garbage collection statistics."""
-
-    def __init__(self, registry: CollectorRegistry = REGISTRY):
-        if not hasattr(gc, 'get_stats') or platform.python_implementation() != 'CPython':
-            return
-        registry.register(self)
-
-    def collect(self) -> Iterable[Metric]:
-        collected = CounterMetricFamily(
-            'python_gc_objects_collected',
-            'Objects collected during gc',
-            labels=['generation'],
-        )
-        uncollectable = CounterMetricFamily(
-            'python_gc_objects_uncollectable',
-            'Uncollectable objects found during GC',
-            labels=['generation'],
-        )
-
-        collections = CounterMetricFamily(
-            'python_gc_collections',
-            'Number of times this generation was collected',
-            labels=['generation'],
-        )
-
-        for gen, stat in enumerate(gc.get_stats()):
-            generation = str(gen)
-            collected.add_metric([generation], value=stat['collected'])
-            uncollectable.add_metric([generation], value=stat['uncollectable'])
-            collections.add_metric([generation], value=stat['collections'])
-
-        return [collected, uncollectable, collections]
-
-
-GC_COLLECTOR = GCCollector()
-"""Default GCCollector in default Registry REGISTRY."""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py
deleted file mode 100644
index e3fe5323104..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics.py
+++ /dev/null
@@ -1,804 +0,0 @@
-import os
-from threading import Lock
-import time
-import types
-from typing import (
-    Any, Callable, Dict, Iterable, List, Literal, Optional, Sequence, Tuple,
-    Type, TypeVar, Union,
-)
-import warnings
-
-from . import values  # retain this import style for testability
-from .context_managers import ExceptionCounter, InprogressTracker, Timer
-from .metrics_core import Metric
-from .registry import Collector, CollectorRegistry, REGISTRY
-from .samples import Exemplar, Sample
-from .utils import floatToGoString, INF
-from .validation import (
-    _validate_exemplar, _validate_labelnames, _validate_metric_name,
-)
-
-T = TypeVar('T', bound='MetricWrapperBase')
-F = TypeVar("F", bound=Callable[..., Any])
-
-
-def _build_full_name(metric_type, name, namespace, subsystem, unit):
-    if not name:
-        raise ValueError('Metric name should not be empty')
-    full_name = ''
-    if namespace:
-        full_name += namespace + '_'
-    if subsystem:
-        full_name += subsystem + '_'
-    full_name += name
-    if metric_type == 'counter' and full_name.endswith('_total'):
-        full_name = full_name[:-6]  # Munge to OpenMetrics.
-    if unit and not full_name.endswith("_" + unit):
-        full_name += "_" + unit
-    if unit and metric_type in ('info', 'stateset'):
-        raise ValueError('Metric name is of a type that cannot have a unit: ' + full_name)
-    return full_name
-
-
-
-def _get_use_created() -> bool:
-    return os.environ.get("PROMETHEUS_DISABLE_CREATED_SERIES", 'False').lower() not in ('true', '1', 't')
-
-
-_use_created = _get_use_created()
-
-
-def disable_created_metrics():
-    """Disable exporting _created metrics on counters, histograms, and summaries."""
-    global _use_created
-    _use_created = False
-
-
-def enable_created_metrics():
-    """Enable exporting _created metrics on counters, histograms, and summaries."""
-    global _use_created
-    _use_created = True
-
-
-class MetricWrapperBase(Collector):
-    _type: Optional[str] = None
-    _reserved_labelnames: Sequence[str] = ()
-
-    def _is_observable(self):
-        # Whether this metric is observable, i.e.
-        # * a metric without label names and values, or
-        # * the child of a labelled metric.
-        return not self._labelnames or (self._labelnames and self._labelvalues)
-
-    def _raise_if_not_observable(self):
-        # Functions that mutate the state of the metric, for example incrementing
-        # a counter, will fail if the metric is not observable, because only if a
-        # metric is observable will the value be initialized.
-        if not self._is_observable():
-            raise ValueError('%s metric is missing label values' % str(self._type))
-
-    def _is_parent(self):
-        return self._labelnames and not self._labelvalues
-
-    def _get_metric(self):
-        return Metric(self._name, self._documentation, self._type, self._unit)
-
-    def describe(self) -> Iterable[Metric]:
-        return [self._get_metric()]
-
-    def collect(self) -> Iterable[Metric]:
-        metric = self._get_metric()
-        for suffix, labels, value, timestamp, exemplar, native_histogram_value in self._samples():
-            metric.add_sample(self._name + suffix, labels, value, timestamp, exemplar, native_histogram_value)
-        return [metric]
-
-    def __str__(self) -> str:
-        return f"{self._type}:{self._name}"
-
-    def __repr__(self) -> str:
-        metric_type = type(self)
-        return f"{metric_type.__module__}.{metric_type.__name__}({self._name})"
-
-    def __init__(self: T,
-                 name: str,
-                 documentation: str,
-                 labelnames: Iterable[str] = (),
-                 namespace: str = '',
-                 subsystem: str = '',
-                 unit: str = '',
-                 registry: Optional[CollectorRegistry] = REGISTRY,
-                 _labelvalues: Optional[Sequence[str]] = None,
-                 ) -> None:
-
-        self._original_name = name
-        self._namespace = namespace
-        self._subsystem = subsystem
-        self._name = _build_full_name(self._type, name, namespace, subsystem, unit)
-        self._labelnames = _validate_labelnames(self, labelnames)
-        self._labelvalues = tuple(_labelvalues or ())
-        self._kwargs: Dict[str, Any] = {}
-        self._documentation = documentation
-        self._unit = unit
-
-        _validate_metric_name(self._name)
-
-        if self._is_parent():
-            # Prepare the fields needed for child metrics.
-            self._lock = Lock()
-            self._metrics: Dict[Sequence[str], T] = {}
-
-        if self._is_observable():
-            self._metric_init()
-
-        if not self._labelvalues:
-            # Register the multi-wrapper parent metric, or if a label-less metric, the whole shebang.
-            if registry:
-                registry.register(self)
-
-    def labels(self: T, *labelvalues: object, **labelkwargs: object) -> T:
-        """Return the child for the given labelset.
-
-        All metrics can have labels, allowing grouping of related time series.
-        Taking a counter as an example:
-
-            from prometheus_client import Counter
-
-            c = Counter('my_requests_total', 'HTTP Failures', ['method', 'endpoint'])
-            c.labels('get', '/').inc()
-            c.labels('post', '/submit').inc()
-
-        Labels can also be provided as keyword arguments:
-
-            from prometheus_client import Counter
-
-            c = Counter('my_requests_total', 'HTTP Failures', ['method', 'endpoint'])
-            c.labels(method='get', endpoint='/').inc()
-            c.labels(method='post', endpoint='/submit').inc()
-
-        See the best practices on [naming](http://prometheus.io/docs/practices/naming/)
-        and [labels](http://prometheus.io/docs/practices/instrumentation/#use-labels).
-        """
-        if not self._labelnames:
-            raise ValueError('No label names were set when constructing %s' % self)
-
-        if self._labelvalues:
-            raise ValueError('{} already has labels set ({}); can not chain calls to .labels()'.format(
-                self,
-                dict(zip(self._labelnames, self._labelvalues))
-            ))
-
-        if labelvalues and labelkwargs:
-            raise ValueError("Can't pass both *args and **kwargs")
-
-        if labelkwargs:
-            if sorted(labelkwargs) != sorted(self._labelnames):
-                raise ValueError('Incorrect label names')
-            str_labelvalues = tuple(str(labelkwargs[l]) for l in self._labelnames)
-        else:
-            if len(labelvalues) != len(self._labelnames):
-                raise ValueError('Incorrect label count')
-            str_labelvalues = tuple(str(l) for l in labelvalues)
-        with self._lock:
-            if str_labelvalues not in self._metrics:
-
-                original_name = getattr(self, '_original_name', self._name)
-                namespace = getattr(self, '_namespace', '')
-                subsystem = getattr(self, '_subsystem', '')
-                unit = getattr(self, '_unit', '')
-
-                child_kwargs = dict(self._kwargs) if self._kwargs else {}
-                for k in ('namespace', 'subsystem', 'unit'):
-                    child_kwargs.pop(k, None)
-
-                self._metrics[str_labelvalues] = self.__class__(
-                    original_name,
-                    documentation=self._documentation,
-                    labelnames=self._labelnames,
-                    namespace=namespace,
-                    subsystem=subsystem,
-                    unit=unit,
-                    _labelvalues=str_labelvalues,
-                    **child_kwargs
-                )
-            return self._metrics[str_labelvalues]
-
-    def remove(self, *labelvalues: Any) -> None:
-        if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
-            warnings.warn(
-                "Removal of labels has not been implemented in  multi-process mode yet.",
-                UserWarning)
-
-        if not self._labelnames:
-            raise ValueError('No label names were set when constructing %s' % self)
-
-        """Remove the given labelset from the metric."""
-        if len(labelvalues) != len(self._labelnames):
-            raise ValueError('Incorrect label count (expected %d, got %s)' % (len(self._labelnames), labelvalues))
-        labelvalues = tuple(str(l) for l in labelvalues)
-        with self._lock:
-            if labelvalues in self._metrics:
-                del self._metrics[labelvalues]
-
-    def remove_by_labels(self, labels: dict[str, str]) -> None:
-        """Remove all series whose labelset partially matches the given labels."""
-        if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
-            warnings.warn(
-                "Removal of labels has not been implemented in  multi-process mode yet.",
-                UserWarning
-            )
-
-        if not self._labelnames:
-            raise ValueError('No label names were set when constructing %s' % self)
-        
-        if not isinstance(labels, dict):
-            raise TypeError("labels must be a dict of {label_name: label_value}")
-    
-        if not labels:
-            return  # no operation
-    
-        invalid = [k for k in labels.keys() if k not in self._labelnames]
-        if invalid:
-            raise ValueError(
-                'Unknown label names: %s; expected %s' % (invalid, self._labelnames)
-            )
-        
-        pos_filter = {self._labelnames.index(k): str(v) for k, v in labels.items()}
-
-        with self._lock:
-            # list(...) to avoid "dictionary changed size during iteration"
-            for lv in list(self._metrics.keys()):
-                if all(lv[pos] == want for pos, want in pos_filter.items()):
-                    # pop with default avoids KeyError if concurrently removed
-                    self._metrics.pop(lv, None)
-        
-
-    def clear(self) -> None:
-        """Remove all labelsets from the metric"""
-        if not self._labelnames:
-            return
-        if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
-            warnings.warn(
-                "Clearing labels has not been implemented in multi-process mode yet",
-                UserWarning)
-        with self._lock:
-            self._metrics = {}
-
-    def _samples(self) -> Iterable[Sample]:
-        if self._is_parent():
-            return self._multi_samples()
-        else:
-            return self._child_samples()
-
-    def _multi_samples(self) -> Iterable[Sample]:
-        with self._lock:
-            metrics = self._metrics.copy()
-        for labels, metric in metrics.items():
-            series_labels = list(zip(self._labelnames, labels))
-            for suffix, sample_labels, value, timestamp, exemplar, native_histogram_value in metric._samples():
-                yield Sample(suffix, dict(series_labels + list(sample_labels.items())), value, timestamp, exemplar, native_histogram_value)
-
-    def _child_samples(self) -> Iterable[Sample]:  # pragma: no cover
-        raise NotImplementedError('_child_samples() must be implemented by %r' % self)
-
-    def _metric_init(self):  # pragma: no cover
-        """
-        Initialize the metric object as a child, i.e. when it has labels (if any) set.
-
-        This is factored as a separate function to allow for deferred initialization.
-        """
-        raise NotImplementedError('_metric_init() must be implemented by %r' % self)
-
-
-class Counter(MetricWrapperBase):
-    """A Counter tracks counts of events or running totals.
-
-    Example use cases for Counters:
-    - Number of requests processed
-    - Number of items that were inserted into a queue
-    - Total amount of data that a system has processed
-
-    Counters can only go up (and be reset when the process restarts). If your use case can go down,
-    you should use a Gauge instead.
-
-    An example for a Counter:
-
-        from prometheus_client import Counter
-
-        c = Counter('my_failures_total', 'Description of counter')
-        c.inc()     # Increment by 1
-        c.inc(1.6)  # Increment by given value
-
-    There are utilities to count exceptions raised:
-
-        @c.count_exceptions()
-        def f():
-            pass
-
-        with c.count_exceptions():
-            pass
-
-        # Count only one type of exception
-        with c.count_exceptions(ValueError):
-            pass
-            
-    You can also reset the counter to zero in case your logical "process" restarts
-    without restarting the actual python process.
-
-       c.reset()
-
-    """
-    _type = 'counter'
-
-    def _metric_init(self) -> None:
-        self._value = values.ValueClass(self._type, self._name, self._name + '_total', self._labelnames,
-                                        self._labelvalues, self._documentation)
-        self._created = time.time()
-
-    def inc(self, amount: float = 1, exemplar: Optional[Dict[str, str]] = None) -> None:
-        """Increment counter by the given amount."""
-        self._raise_if_not_observable()
-        if amount < 0:
-            raise ValueError('Counters can only be incremented by non-negative amounts.')
-        self._value.inc(amount)
-        if exemplar:
-            _validate_exemplar(exemplar)
-            self._value.set_exemplar(Exemplar(exemplar, amount, time.time()))
-
-    def reset(self) -> None:
-        """Reset the counter to zero. Use this when a logical process restarts without restarting the actual python process."""
-        self._value.set(0)
-        self._created = time.time()
-
-    def count_exceptions(self, exception: Union[Type[BaseException], Tuple[Type[BaseException], ...]] = Exception) -> ExceptionCounter:
-        """Count exceptions in a block of code or function.
-
-        Can be used as a function decorator or context manager.
-        Increments the counter when an exception of the given
-        type is raised up out of the code.
-        """
-        self._raise_if_not_observable()
-        return ExceptionCounter(self, exception)
-
-    def _child_samples(self) -> Iterable[Sample]:
-        sample = Sample('_total', {}, self._value.get(), None, self._value.get_exemplar())
-        if _use_created:
-            return (
-                sample,
-                Sample('_created', {}, self._created, None, None)
-            )
-        return (sample,)
-
-
-class Gauge(MetricWrapperBase):
-    """Gauge metric, to report instantaneous values.
-
-     Examples of Gauges include:
-        - Inprogress requests
-        - Number of items in a queue
-        - Free memory
-        - Total memory
-        - Temperature
-
-     Gauges can go both up and down.
-
-        from prometheus_client import Gauge
-
-        g = Gauge('my_inprogress_requests', 'Description of gauge')
-        g.inc()      # Increment by 1
-        g.dec(10)    # Decrement by given value
-        g.set(4.2)   # Set to a given value
-
-     There are utilities for common use cases:
-
-        g.set_to_current_time()   # Set to current unixtime
-
-        # Increment when entered, decrement when exited.
-        @g.track_inprogress()
-        def f():
-            pass
-
-        with g.track_inprogress():
-            pass
-
-     A Gauge can also take its value from a callback:
-
-        d = Gauge('data_objects', 'Number of objects')
-        my_dict = {}
-        d.set_function(lambda: len(my_dict))
-    """
-    _type = 'gauge'
-    _MULTIPROC_MODES = frozenset(('all', 'liveall', 'min', 'livemin', 'max', 'livemax', 'sum', 'livesum', 'mostrecent', 'livemostrecent'))
-    _MOST_RECENT_MODES = frozenset(('mostrecent', 'livemostrecent'))
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 labelnames: Iterable[str] = (),
-                 namespace: str = '',
-                 subsystem: str = '',
-                 unit: str = '',
-                 registry: Optional[CollectorRegistry] = REGISTRY,
-                 _labelvalues: Optional[Sequence[str]] = None,
-                 multiprocess_mode: Literal['all', 'liveall', 'min', 'livemin', 'max', 'livemax', 'sum', 'livesum', 'mostrecent', 'livemostrecent'] = 'all',
-                 ):
-        self._multiprocess_mode = multiprocess_mode
-        if multiprocess_mode not in self._MULTIPROC_MODES:
-            raise ValueError('Invalid multiprocess mode: ' + multiprocess_mode)
-        super().__init__(
-            name=name,
-            documentation=documentation,
-            labelnames=labelnames,
-            namespace=namespace,
-            subsystem=subsystem,
-            unit=unit,
-            registry=registry,
-            _labelvalues=_labelvalues,
-        )
-        self._kwargs['multiprocess_mode'] = self._multiprocess_mode
-        self._is_most_recent = self._multiprocess_mode in self._MOST_RECENT_MODES
-
-    def _metric_init(self) -> None:
-        self._value = values.ValueClass(
-            self._type, self._name, self._name, self._labelnames, self._labelvalues,
-            self._documentation, multiprocess_mode=self._multiprocess_mode
-        )
-
-    def inc(self, amount: float = 1) -> None:
-        """Increment gauge by the given amount."""
-        if self._is_most_recent:
-            raise RuntimeError("inc must not be used with the mostrecent mode")
-        self._raise_if_not_observable()
-        self._value.inc(amount)
-
-    def dec(self, amount: float = 1) -> None:
-        """Decrement gauge by the given amount."""
-        if self._is_most_recent:
-            raise RuntimeError("dec must not be used with the mostrecent mode")
-        self._raise_if_not_observable()
-        self._value.inc(-amount)
-
-    def set(self, value: float) -> None:
-        """Set gauge to the given value."""
-        self._raise_if_not_observable()
-        if self._is_most_recent:
-            self._value.set(float(value), timestamp=time.time())
-        else:
-            self._value.set(float(value))
-
-    def set_to_current_time(self) -> None:
-        """Set gauge to the current unixtime."""
-        self.set(time.time())
-
-    def track_inprogress(self) -> InprogressTracker:
-        """Track inprogress blocks of code or functions.
-
-        Can be used as a function decorator or context manager.
-        Increments the gauge when the code is entered,
-        and decrements when it is exited.
-        """
-        self._raise_if_not_observable()
-        return InprogressTracker(self)
-
-    def time(self) -> Timer:
-        """Time a block of code or function, and set the duration in seconds.
-
-        Can be used as a function decorator or context manager.
-        """
-        return Timer(self, 'set')
-
-    def set_function(self, f: Callable[[], float]) -> None:
-        """Call the provided function to return the Gauge value.
-
-        The function must return a float, and may be called from
-        multiple threads. All other methods of the Gauge become NOOPs.
-        """
-
-        self._raise_if_not_observable()
-
-        def samples(_: Gauge) -> Iterable[Sample]:
-            return (Sample('', {}, float(f()), None, None),)
-
-        self._child_samples = types.MethodType(samples, self)  # type: ignore
-
-    def _child_samples(self) -> Iterable[Sample]:
-        return (Sample('', {}, self._value.get(), None, None),)
-
-
-class Summary(MetricWrapperBase):
-    """A Summary tracks the size and number of events.
-
-    Example use cases for Summaries:
-    - Response latency
-    - Request size
-
-    Example for a Summary:
-
-        from prometheus_client import Summary
-
-        s = Summary('request_size_bytes', 'Request size (bytes)')
-        s.observe(512)  # Observe 512 (bytes)
-
-    Example for a Summary using time:
-
-        from prometheus_client import Summary
-
-        REQUEST_TIME = Summary('response_latency_seconds', 'Response latency (seconds)')
-
-        @REQUEST_TIME.time()
-        def create_response(request):
-          '''A dummy function'''
-          time.sleep(1)
-
-    Example for using the same Summary object as a context manager:
-
-        with REQUEST_TIME.time():
-            pass  # Logic to be timed
-    """
-    _type = 'summary'
-    _reserved_labelnames = ['quantile']
-
-    def _metric_init(self) -> None:
-        self._count = values.ValueClass(self._type, self._name, self._name + '_count', self._labelnames,
-                                        self._labelvalues, self._documentation)
-        self._sum = values.ValueClass(self._type, self._name, self._name + '_sum', self._labelnames, self._labelvalues, self._documentation)
-        self._created = time.time()
-
-    def observe(self, amount: float) -> None:
-        """Observe the given amount.
-
-        The amount is usually positive or zero. Negative values are
-        accepted but prevent current versions of Prometheus from
-        properly detecting counter resets in the sum of
-        observations. See
-        https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
-        for details.
-        """
-        self._raise_if_not_observable()
-        self._count.inc(1)
-        self._sum.inc(amount)
-
-    def time(self) -> Timer:
-        """Time a block of code or function, and observe the duration in seconds.
-
-        Can be used as a function decorator or context manager.
-        """
-        return Timer(self, 'observe')
-
-    def _child_samples(self) -> Iterable[Sample]:
-        samples = [
-            Sample('_count', {}, self._count.get(), None, None),
-            Sample('_sum', {}, self._sum.get(), None, None),
-        ]
-        if _use_created:
-            samples.append(Sample('_created', {}, self._created, None, None))
-        return tuple(samples)
-
-
-class Histogram(MetricWrapperBase):
-    """A Histogram tracks the size and number of events in buckets.
-
-    You can use Histograms for aggregatable calculation of quantiles.
-
-    Example use cases:
-    - Response latency
-    - Request size
-
-    Example for a Histogram:
-
-        from prometheus_client import Histogram
-
-        h = Histogram('request_size_bytes', 'Request size (bytes)')
-        h.observe(512)  # Observe 512 (bytes)
-
-    Example for a Histogram using time:
-
-        from prometheus_client import Histogram
-
-        REQUEST_TIME = Histogram('response_latency_seconds', 'Response latency (seconds)')
-
-        @REQUEST_TIME.time()
-        def create_response(request):
-          '''A dummy function'''
-          time.sleep(1)
-
-    Example of using the same Histogram object as a context manager:
-
-        with REQUEST_TIME.time():
-            pass  # Logic to be timed
-
-    The default buckets are intended to cover a typical web/rpc request from milliseconds to seconds.
-    They can be overridden by passing `buckets` keyword argument to `Histogram`.
-    """
-    _type = 'histogram'
-    _reserved_labelnames = ['le']
-    DEFAULT_BUCKETS = (.005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, 2.5, 5.0, 7.5, 10.0, INF)
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 labelnames: Iterable[str] = (),
-                 namespace: str = '',
-                 subsystem: str = '',
-                 unit: str = '',
-                 registry: Optional[CollectorRegistry] = REGISTRY,
-                 _labelvalues: Optional[Sequence[str]] = None,
-                 buckets: Sequence[Union[float, str]] = DEFAULT_BUCKETS,
-                 ):
-        self._prepare_buckets(buckets)
-        super().__init__(
-            name=name,
-            documentation=documentation,
-            labelnames=labelnames,
-            namespace=namespace,
-            subsystem=subsystem,
-            unit=unit,
-            registry=registry,
-            _labelvalues=_labelvalues,
-        )
-        self._kwargs['buckets'] = buckets
-
-    def _prepare_buckets(self, source_buckets: Sequence[Union[float, str]]) -> None:
-        buckets = [float(b) for b in source_buckets]
-        if buckets != sorted(buckets):
-            # This is probably an error on the part of the user,
-            # so raise rather than sorting for them.
-            raise ValueError('Buckets not in sorted order')
-        if buckets and buckets[-1] != INF:
-            buckets.append(INF)
-        if len(buckets) < 2:
-            raise ValueError('Must have at least two buckets')
-        self._upper_bounds = buckets
-
-    def _metric_init(self) -> None:
-        self._buckets: List[values.ValueClass] = []
-        self._created = time.time()
-        bucket_labelnames = self._labelnames + ('le',)
-        self._sum = values.ValueClass(self._type, self._name, self._name + '_sum', self._labelnames, self._labelvalues, self._documentation)
-        for b in self._upper_bounds:
-            self._buckets.append(values.ValueClass(
-                self._type,
-                self._name,
-                self._name + '_bucket',
-                bucket_labelnames,
-                self._labelvalues + (floatToGoString(b),),
-                self._documentation)
-            )
-
-    def observe(self, amount: float, exemplar: Optional[Dict[str, str]] = None) -> None:
-        """Observe the given amount.
-
-        The amount is usually positive or zero. Negative values are
-        accepted but prevent current versions of Prometheus from
-        properly detecting counter resets in the sum of
-        observations. See
-        https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations
-        for details.
-        """
-        self._raise_if_not_observable()
-        self._sum.inc(amount)
-        for i, bound in enumerate(self._upper_bounds):
-            if amount <= bound:
-                self._buckets[i].inc(1)
-                if exemplar:
-                    _validate_exemplar(exemplar)
-                    self._buckets[i].set_exemplar(Exemplar(exemplar, amount, time.time()))
-                break
-
-    def time(self) -> Timer:
-        """Time a block of code or function, and observe the duration in seconds.
-
-        Can be used as a function decorator or context manager.
-        """
-        return Timer(self, 'observe')
-
-    def _child_samples(self) -> Iterable[Sample]:
-        samples = []
-        acc = 0.0
-        for i, bound in enumerate(self._upper_bounds):
-            acc += self._buckets[i].get()
-            samples.append(Sample('_bucket', {'le': floatToGoString(bound)}, acc, None, self._buckets[i].get_exemplar()))
-        samples.append(Sample('_count', {}, acc, None, None))
-        if self._upper_bounds[0] >= 0:
-            samples.append(Sample('_sum', {}, self._sum.get(), None, None))
-        if _use_created:
-            samples.append(Sample('_created', {}, self._created, None, None))
-        return tuple(samples)
-
-
-class Info(MetricWrapperBase):
-    """Info metric, key-value pairs.
-
-     Examples of Info include:
-        - Build information
-        - Version information
-        - Potential target metadata
-
-     Example usage:
-        from prometheus_client import Info
-
-        i = Info('my_build', 'Description of info')
-        i.info({'version': '1.2.3', 'buildhost': 'foo@bar'})
-
-     Info metrics do not work in multiprocess mode.
-    """
-    _type = 'info'
-
-    def _metric_init(self):
-        self._labelname_set = set(self._labelnames)
-        self._lock = Lock()
-        self._value = {}
-
-    def info(self, val: Dict[str, str]) -> None:
-        """Set info metric."""
-        if self._labelname_set.intersection(val.keys()):
-            raise ValueError('Overlapping labels for Info metric, metric: {} child: {}'.format(
-                self._labelnames, val))
-        if any(i is None for i in val.values()):
-            raise ValueError('Label value cannot be None')
-        with self._lock:
-            self._value = dict(val)
-
-    def _child_samples(self) -> Iterable[Sample]:
-        with self._lock:
-            return (Sample('_info', self._value, 1.0, None, None),)
-
-
-class Enum(MetricWrapperBase):
-    """Enum metric, which of a set of states is true.
-
-     Example usage:
-        from prometheus_client import Enum
-
-        e = Enum('task_state', 'Description of enum',
-          states=['starting', 'running', 'stopped'])
-        e.state('running')
-
-     The first listed state will be the default.
-     Enum metrics do not work in multiprocess mode.
-    """
-    _type = 'stateset'
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 labelnames: Sequence[str] = (),
-                 namespace: str = '',
-                 subsystem: str = '',
-                 unit: str = '',
-                 registry: Optional[CollectorRegistry] = REGISTRY,
-                 _labelvalues: Optional[Sequence[str]] = None,
-                 states: Optional[Sequence[str]] = None,
-                 ):
-        if name in labelnames:
-            raise ValueError(f'Overlapping labels for Enum metric: {name}')
-        if not states:
-            raise ValueError(f'No states provided for Enum metric: {name}')
-        super().__init__(
-            name=name,
-            documentation=documentation,
-            labelnames=labelnames,
-            namespace=namespace,
-            subsystem=subsystem,
-            unit=unit,
-            registry=registry,
-            _labelvalues=_labelvalues,
-        )
-        self._kwargs['states'] = self._states = states
-
-    def _metric_init(self) -> None:
-        self._value = 0
-        self._lock = Lock()
-
-    def state(self, state: str) -> None:
-        """Set enum metric state."""
-        self._raise_if_not_observable()
-        with self._lock:
-            self._value = self._states.index(state)
-
-    def _child_samples(self) -> Iterable[Sample]:
-        with self._lock:
-            return [
-                Sample('', {self._name: s}, 1 if i == self._value else 0, None, None)
-                for i, s
-                in enumerate(self._states)
-            ]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py
deleted file mode 100644
index 27d1712ddaa..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/metrics_core.py
+++ /dev/null
@@ -1,415 +0,0 @@
-from typing import Dict, List, Optional, Sequence, Tuple, Union
-
-from .samples import Exemplar, NativeHistogram, Sample, Timestamp
-from .validation import _validate_metric_name
-
-METRIC_TYPES = (
-    'counter', 'gauge', 'summary', 'histogram',
-    'gaugehistogram', 'unknown', 'info', 'stateset',
-)
-
-
-class Metric:
-    """A single metric family and its samples.
-
-    This is intended only for internal use by the instrumentation client.
-
-    Custom collectors should use GaugeMetricFamily, CounterMetricFamily
-    and SummaryMetricFamily instead.
-    """
-
-    def __init__(self, name: str, documentation: str, typ: str, unit: str = ''):
-        if unit and not name.endswith("_" + unit):
-            name += "_" + unit
-        _validate_metric_name(name)
-        self.name: str = name
-        self.documentation: str = documentation
-        self.unit: str = unit
-        if typ == 'untyped':
-            typ = 'unknown'
-        if typ not in METRIC_TYPES:
-            raise ValueError('Invalid metric type: ' + typ)
-        self.type: str = typ
-        self.samples: List[Sample] = []
-
-    def add_sample(self, name: str, labels: Dict[str, str], value: float, timestamp: Optional[Union[Timestamp, float]] = None, exemplar: Optional[Exemplar] = None, native_histogram: Optional[NativeHistogram] = None) -> None:
-        """Add a sample to the metric.
-
-        Internal-only, do not use."""
-        self.samples.append(Sample(name, labels, value, timestamp, exemplar, native_histogram))
-
-    def __eq__(self, other: object) -> bool:
-        return (isinstance(other, Metric)
-                and self.name == other.name
-                and self.documentation == other.documentation
-                and self.type == other.type
-                and self.unit == other.unit
-                and self.samples == other.samples)
-
-    def __repr__(self) -> str:
-        return "Metric({}, {}, {}, {}, {})".format(
-            self.name,
-            self.documentation,
-            self.type,
-            self.unit,
-            self.samples,
-        )
-
-    def _restricted_metric(self, names):
-        """Build a snapshot of a metric with samples restricted to a given set of names."""
-        samples = [s for s in self.samples if s[0] in names]
-        if samples:
-            m = Metric(self.name, self.documentation, self.type)
-            m.samples = samples
-            return m
-        return None
-
-
-class UnknownMetricFamily(Metric):
-    """A single unknown metric and its samples.
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 value: Optional[float] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 unit: str = '',
-                 ):
-        Metric.__init__(self, name, documentation, 'unknown', unit)
-        if labels is not None and value is not None:
-            raise ValueError('Can only specify at most one of value and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        if value is not None:
-            self.add_metric([], value)
-
-    def add_metric(self, labels: Sequence[str], value: float, timestamp: Optional[Union[Timestamp, float]] = None) -> None:
-        """Add a metric to the metric family.
-        Args:
-        labels: A list of label values
-        value: The value of the metric.
-        """
-        self.samples.append(Sample(self.name, dict(zip(self._labelnames, labels)), value, timestamp))
-
-
-# For backward compatibility.
-UntypedMetricFamily = UnknownMetricFamily
-
-
-class CounterMetricFamily(Metric):
-    """A single counter and its samples.
-
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 value: Optional[float] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 created: Optional[float] = None,
-                 unit: str = '',
-                 exemplar: Optional[Exemplar] = None,
-                 ):
-        # Glue code for pre-OpenMetrics metrics.
-        if name.endswith('_total'):
-            name = name[:-6]
-        Metric.__init__(self, name, documentation, 'counter', unit)
-        if labels is not None and value is not None:
-            raise ValueError('Can only specify at most one of value and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        if value is not None:
-            self.add_metric([], value, created, exemplar=exemplar)
-
-    def add_metric(self,
-                   labels: Sequence[str],
-                   value: float,
-                   created: Optional[float] = None,
-                   timestamp: Optional[Union[Timestamp, float]] = None,
-                   exemplar: Optional[Exemplar] = None,
-                   ) -> None:
-        """Add a metric to the metric family.
-
-        Args:
-          labels: A list of label values
-          value: The value of the metric
-          created: Optional unix timestamp the child was created at.
-        """
-        self.samples.append(Sample(self.name + '_total', dict(zip(self._labelnames, labels)), value, timestamp, exemplar))
-        if created is not None:
-            self.samples.append(Sample(self.name + '_created', dict(zip(self._labelnames, labels)), created, timestamp))
-
-
-class GaugeMetricFamily(Metric):
-    """A single gauge and its samples.
-
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 value: Optional[float] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 unit: str = '',
-                 ):
-        Metric.__init__(self, name, documentation, 'gauge', unit)
-        if labels is not None and value is not None:
-            raise ValueError('Can only specify at most one of value and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        if value is not None:
-            self.add_metric([], value)
-
-    def add_metric(self, labels: Sequence[str], value: float, timestamp: Optional[Union[Timestamp, float]] = None) -> None:
-        """Add a metric to the metric family.
-
-        Args:
-          labels: A list of label values
-          value: A float
-        """
-        self.samples.append(Sample(self.name, dict(zip(self._labelnames, labels)), value, timestamp))
-
-
-class SummaryMetricFamily(Metric):
-    """A single summary and its samples.
-
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 count_value: Optional[int] = None,
-                 sum_value: Optional[float] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 unit: str = '',
-                 ):
-        Metric.__init__(self, name, documentation, 'summary', unit)
-        if (sum_value is None) != (count_value is None):
-            raise ValueError('count_value and sum_value must be provided together.')
-        if labels is not None and count_value is not None:
-            raise ValueError('Can only specify at most one of value and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        # The and clause is necessary only for typing, the above ValueError will raise if only one is set.
-        if count_value is not None and sum_value is not None:
-            self.add_metric([], count_value, sum_value)
-
-    def add_metric(self,
-                   labels: Sequence[str],
-                   count_value: int,
-                   sum_value: float,
-                   timestamp:
-                   Optional[Union[float, Timestamp]] = None
-                   ) -> None:
-        """Add a metric to the metric family.
-
-        Args:
-          labels: A list of label values
-          count_value: The count value of the metric.
-          sum_value: The sum value of the metric.
-        """
-        self.samples.append(Sample(self.name + '_count', dict(zip(self._labelnames, labels)), count_value, timestamp))
-        self.samples.append(Sample(self.name + '_sum', dict(zip(self._labelnames, labels)), sum_value, timestamp))
-
-
-class HistogramMetricFamily(Metric):
-    """A single histogram and its samples.
-
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 buckets: Optional[Sequence[Union[Tuple[str, float], Tuple[str, float, Exemplar]]]] = None,
-                 sum_value: Optional[float] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 unit: str = '',
-                 ):
-        Metric.__init__(self, name, documentation, 'histogram', unit)
-        if sum_value is not None and buckets is None:
-            raise ValueError('sum value cannot be provided without buckets.')
-        if labels is not None and buckets is not None:
-            raise ValueError('Can only specify at most one of buckets and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        if buckets is not None:
-            self.add_metric([], buckets, sum_value)
-
-    def add_metric(self,
-                   labels: Sequence[str],
-                   buckets: Sequence[Union[Tuple[str, float], Tuple[str, float, Exemplar]]],
-                   sum_value: Optional[float],
-                   timestamp: Optional[Union[Timestamp, float]] = None) -> None:
-        """Add a metric to the metric family.
-
-        Args:
-          labels: A list of label values
-          buckets: A list of lists.
-              Each inner list can be a pair of bucket name and value,
-              or a triple of bucket name, value, and exemplar.
-              The buckets must be sorted, and +Inf present.
-          sum_value: The sum value of the metric.
-        """
-        for b in buckets:
-            bucket, value = b[:2]
-            exemplar = None
-            if len(b) == 3:
-                exemplar = b[2]  # type: ignore
-            self.samples.append(Sample(
-                self.name + '_bucket',
-                dict(list(zip(self._labelnames, labels)) + [('le', bucket)]),
-                value,
-                timestamp,
-                exemplar,
-            ))
-        # Don't include sum and thus count if there's negative buckets.
-        if float(buckets[0][0]) >= 0 and sum_value is not None:
-            # +Inf is last and provides the count value.
-            self.samples.append(
-                Sample(self.name + '_count', dict(zip(self._labelnames, labels)), buckets[-1][1], timestamp))
-            self.samples.append(
-                Sample(self.name + '_sum', dict(zip(self._labelnames, labels)), sum_value, timestamp))
-
-
-class GaugeHistogramMetricFamily(Metric):
-    """A single gauge histogram and its samples.
-
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 buckets: Optional[Sequence[Tuple[str, float]]] = None,
-                 gsum_value: Optional[float] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 unit: str = '',
-                 ):
-        Metric.__init__(self, name, documentation, 'gaugehistogram', unit)
-        if labels is not None and buckets is not None:
-            raise ValueError('Can only specify at most one of buckets and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        if buckets is not None:
-            self.add_metric([], buckets, gsum_value)
-
-    def add_metric(self,
-                   labels: Sequence[str],
-                   buckets: Sequence[Tuple[str, float]],
-                   gsum_value: Optional[float],
-                   timestamp: Optional[Union[float, Timestamp]] = None,
-                   ) -> None:
-        """Add a metric to the metric family.
-
-        Args:
-          labels: A list of label values
-          buckets: A list of pairs of bucket names and values.
-              The buckets must be sorted, and +Inf present.
-          gsum_value: The sum value of the metric.
-        """
-        for bucket, value in buckets:
-            self.samples.append(Sample(
-                self.name + '_bucket',
-                dict(list(zip(self._labelnames, labels)) + [('le', bucket)]),
-                value, timestamp))
-        # +Inf is last and provides the count value.
-        self.samples.extend([
-            Sample(self.name + '_gcount', dict(zip(self._labelnames, labels)), buckets[-1][1], timestamp),
-            # TODO: Handle None gsum_value correctly. Currently a None will fail exposition but is allowed here.
-            Sample(self.name + '_gsum', dict(zip(self._labelnames, labels)), gsum_value, timestamp),  # type: ignore
-        ])
-
-
-class InfoMetricFamily(Metric):
-    """A single info and its samples.
-
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 value: Optional[Dict[str, str]] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 ):
-        Metric.__init__(self, name, documentation, 'info')
-        if labels is not None and value is not None:
-            raise ValueError('Can only specify at most one of value and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        if value is not None:
-            self.add_metric([], value)
-
-    def add_metric(self,
-                   labels: Sequence[str],
-                   value: Dict[str, str],
-                   timestamp: Optional[Union[Timestamp, float]] = None,
-                   ) -> None:
-        """Add a metric to the metric family.
-
-        Args:
-          labels: A list of label values
-          value: A dict of labels
-        """
-        self.samples.append(Sample(
-            self.name + '_info',
-            dict(dict(zip(self._labelnames, labels)), **value),
-            1,
-            timestamp,
-        ))
-
-
-class StateSetMetricFamily(Metric):
-    """A single stateset and its samples.
-
-    For use by custom collectors.
-    """
-
-    def __init__(self,
-                 name: str,
-                 documentation: str,
-                 value: Optional[Dict[str, bool]] = None,
-                 labels: Optional[Sequence[str]] = None,
-                 ):
-        Metric.__init__(self, name, documentation, 'stateset')
-        if labels is not None and value is not None:
-            raise ValueError('Can only specify at most one of value and labels.')
-        if labels is None:
-            labels = []
-        self._labelnames = tuple(labels)
-        if value is not None:
-            self.add_metric([], value)
-
-    def add_metric(self,
-                   labels: Sequence[str],
-                   value: Dict[str, bool],
-                   timestamp: Optional[Union[Timestamp, float]] = None,
-                   ) -> None:
-        """Add a metric to the metric family.
-
-        Args:
-          labels: A list of label values
-          value: A dict of string state names to booleans
-        """
-        labels = tuple(labels)
-        for state, enabled in sorted(value.items()):
-            v = (1 if enabled else 0)
-            self.samples.append(Sample(
-                self.name,
-                dict(zip(self._labelnames + (self.name,), labels + (state,))),
-                v,
-                timestamp,
-            ))
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py
deleted file mode 100644
index edd895cda9d..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/mmap_dict.py
+++ /dev/null
@@ -1,145 +0,0 @@
-import json
-import mmap
-import os
-import struct
-from typing import List
-
-_INITIAL_MMAP_SIZE = 1 << 16
-_pack_integer_func = struct.Struct(b'i').pack
-_pack_two_doubles_func = struct.Struct(b'dd').pack
-_unpack_integer = struct.Struct(b'i').unpack_from
-_unpack_two_doubles = struct.Struct(b'dd').unpack_from
-
-
-# struct.pack_into has atomicity issues because it will temporarily write 0 into
-# the mmap, resulting in false reads to 0 when experiencing a lot of writes.
-# Using direct assignment solves this issue.
-
-
-def _pack_two_doubles(data, pos, value, timestamp):
-    data[pos:pos + 16] = _pack_two_doubles_func(value, timestamp)
-
-
-def _pack_integer(data, pos, value):
-    data[pos:pos + 4] = _pack_integer_func(value)
-
-
-def _read_all_values(data, used=0):
-    """Yield (key, value, timestamp, pos). No locking is performed."""
-
-    if used <= 0:
-        # If not valid `used` value is passed in, read it from the file.
-        used = _unpack_integer(data, 0)[0]
-
-    pos = 8
-
-    while pos < used:
-        encoded_len = _unpack_integer(data, pos)[0]
-        # check we are not reading beyond bounds
-        if encoded_len + pos > used:
-            raise RuntimeError('Read beyond file size detected, file is corrupted.')
-        pos += 4
-        encoded_key = data[pos:pos + encoded_len]
-        padded_len = encoded_len + (8 - (encoded_len + 4) % 8)
-        pos += padded_len
-        value, timestamp = _unpack_two_doubles(data, pos)
-        yield encoded_key.decode('utf-8'), value, timestamp, pos
-        pos += 16
-
-
-class MmapedDict:
-    """A dict of doubles, backed by an mmapped file.
-
-    The file starts with a 4 byte int, indicating how much of it is used.
-    Then 4 bytes of padding.
-    There's then a number of entries, consisting of a 4 byte int which is the
-    size of the next field, a utf-8 encoded string key, padding to a 8 byte
-    alignment, and then a 8 byte float which is the value and a 8 byte float
-    which is a UNIX timestamp in seconds.
-
-    Not thread safe.
-    """
-
-    def __init__(self, filename, read_mode=False):
-        self._f = open(filename, 'rb' if read_mode else 'a+b')
-        self._fname = filename
-        capacity = os.fstat(self._f.fileno()).st_size
-        if capacity == 0:
-            self._f.truncate(_INITIAL_MMAP_SIZE)
-            capacity = _INITIAL_MMAP_SIZE
-        self._capacity = capacity
-        self._m = mmap.mmap(self._f.fileno(), self._capacity,
-                            access=mmap.ACCESS_READ if read_mode else mmap.ACCESS_WRITE)
-
-        self._positions = {}
-        self._used = _unpack_integer(self._m, 0)[0]
-        if self._used == 0:
-            self._used = 8
-            _pack_integer(self._m, 0, self._used)
-        else:
-            if not read_mode:
-                for key, _, _, pos in self._read_all_values():
-                    self._positions[key] = pos
-
-    @staticmethod
-    def read_all_values_from_file(filename):
-        with open(filename, 'rb') as infp:
-            # Read the first block of data, including the first 4 bytes which tell us
-            # how much of the file (which is preallocated to _INITIAL_MMAP_SIZE bytes) is occupied.
-            data = infp.read(mmap.PAGESIZE)
-            used = _unpack_integer(data, 0)[0]
-            if used > len(data):  # Then read in the rest, if needed.
-                data += infp.read(used - len(data))
-        return _read_all_values(data, used)
-
-    def _init_value(self, key):
-        """Initialize a value. Lock must be held by caller."""
-        encoded = key.encode('utf-8')
-        # Pad to be 8-byte aligned.
-        padded = encoded + (b' ' * (8 - (len(encoded) + 4) % 8))
-        value = struct.pack(f'i{len(padded)}sdd'.encode(), len(encoded), padded, 0.0, 0.0)
-        while self._used + len(value) > self._capacity:
-            self._capacity *= 2
-            self._f.truncate(self._capacity)
-            self._m = mmap.mmap(self._f.fileno(), self._capacity)
-        self._m[self._used:self._used + len(value)] = value
-
-        # Update how much space we've used.
-        self._used += len(value)
-        _pack_integer(self._m, 0, self._used)
-        self._positions[key] = self._used - 16
-
-    def _read_all_values(self):
-        """Yield (key, value, pos). No locking is performed."""
-        return _read_all_values(data=self._m, used=self._used)
-
-    def read_all_values(self):
-        """Yield (key, value, timestamp). No locking is performed."""
-        for k, v, ts, _ in self._read_all_values():
-            yield k, v, ts
-
-    def read_value(self, key):
-        if key not in self._positions:
-            self._init_value(key)
-        pos = self._positions[key]
-        return _unpack_two_doubles(self._m, pos)
-
-    def write_value(self, key, value, timestamp):
-        if key not in self._positions:
-            self._init_value(key)
-        pos = self._positions[key]
-        _pack_two_doubles(self._m, pos, value, timestamp)
-
-    def close(self):
-        if self._f:
-            self._m.close()
-            self._m = None
-            self._f.close()
-            self._f = None
-
-
-def mmap_key(metric_name: str, name: str, labelnames: List[str], labelvalues: List[str], help_text: str) -> str:
-    """Format a key for use in the mmap file."""
-    # ensure labels are in consistent order for identity
-    labels = dict(zip(labelnames, labelvalues))
-    return json.dumps([metric_name, name, labels, help_text], sort_keys=True)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py
deleted file mode 100644
index db55874e0b8..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/multiprocess.py
+++ /dev/null
@@ -1,183 +0,0 @@
-from collections import defaultdict
-import glob
-import json
-import os
-import warnings
-
-from .metrics import Gauge
-from .metrics_core import Metric
-from .mmap_dict import MmapedDict
-from .samples import Sample
-from .utils import floatToGoString
-
-try:  # Python3
-    FileNotFoundError
-except NameError:  # Python >= 2.5
-    FileNotFoundError = IOError
-
-
-class MultiProcessCollector:
-    """Collector for files for multi-process mode."""
-
-    def __init__(self, registry, path=None):
-        if path is None:
-            # This deprecation warning can go away in a few releases when removing the compatibility
-            if 'prometheus_multiproc_dir' in os.environ and 'PROMETHEUS_MULTIPROC_DIR' not in os.environ:
-                os.environ['PROMETHEUS_MULTIPROC_DIR'] = os.environ['prometheus_multiproc_dir']
-                warnings.warn("prometheus_multiproc_dir variable has been deprecated in favor of the upper case naming PROMETHEUS_MULTIPROC_DIR", DeprecationWarning)
-            path = os.environ.get('PROMETHEUS_MULTIPROC_DIR')
-        if not path or not os.path.isdir(path):
-            raise ValueError('env PROMETHEUS_MULTIPROC_DIR is not set or not a directory')
-        self._path = path
-        if registry:
-            registry.register(self)
-
-    @staticmethod
-    def merge(files, accumulate=True):
-        """Merge metrics from given mmap files.
-
-        By default, histograms are accumulated, as per prometheus wire format.
-        But if writing the merged data back to mmap files, use
-        accumulate=False to avoid compound accumulation.
-        """
-        metrics = MultiProcessCollector._read_metrics(files)
-        return MultiProcessCollector._accumulate_metrics(metrics, accumulate)
-
-    @staticmethod
-    def _read_metrics(files):
-        metrics = {}
-        key_cache = {}
-
-        def _parse_key(key):
-            val = key_cache.get(key)
-            if not val:
-                metric_name, name, labels, help_text = json.loads(key)
-                labels_key = tuple(sorted(labels.items()))
-                val = key_cache[key] = (metric_name, name, labels, labels_key, help_text)
-            return val
-
-        for f in files:
-            parts = os.path.basename(f).split('_')
-            typ = parts[0]
-            try:
-                file_values = MmapedDict.read_all_values_from_file(f)
-            except FileNotFoundError:
-                if typ == 'gauge' and parts[1].startswith('live'):
-                    # Files for 'live*' gauges can be deleted between the glob of collect
-                    # and now (via a mark_process_dead call) so don't fail if
-                    # the file is missing
-                    continue
-                raise
-            for key, value, timestamp, _ in file_values:
-                metric_name, name, labels, labels_key, help_text = _parse_key(key)
-
-                metric = metrics.get(metric_name)
-                if metric is None:
-                    metric = Metric(metric_name, help_text, typ)
-                    metrics[metric_name] = metric
-
-                if typ == 'gauge':
-                    pid = parts[2][:-3]
-                    metric._multiprocess_mode = parts[1]
-                    metric.add_sample(name, labels_key + (('pid', pid),), value, timestamp)
-                else:
-                    # The duplicates and labels are fixed in the next for.
-                    metric.add_sample(name, labels_key, value)
-        return metrics
-
-    @staticmethod
-    def _accumulate_metrics(metrics, accumulate):
-        for metric in metrics.values():
-            samples = defaultdict(lambda: defaultdict(float))
-            sample_timestamps = defaultdict(lambda: defaultdict(float))
-            buckets = defaultdict(lambda: defaultdict(float))
-            for s in metric.samples:
-                name, labels, value, timestamp, exemplar, native_histogram_value = s
-
-                if (
-                    metric.type == 'gauge'
-                    and metric._multiprocess_mode in (
-                        'min', 'livemin',
-                        'max', 'livemax',
-                        'sum', 'livesum',
-                        'mostrecent', 'livemostrecent',
-                    )
-                ):
-                    labels = tuple(l for l in labels if l[0] != 'pid')
-
-                if metric.type == 'gauge':
-                    if metric._multiprocess_mode in ('min', 'livemin'):
-                        current = samples[labels].setdefault((name, labels), value)
-                        if value < current:
-                            samples[labels][(name, labels)] = value
-                    elif metric._multiprocess_mode in ('max', 'livemax'):
-                        current = samples[labels].setdefault((name, labels), value)
-                        if value > current:
-                            samples[labels][(name, labels)] = value
-                    elif metric._multiprocess_mode in ('sum', 'livesum'):
-                        samples[labels][(name, labels)] += value
-                    elif metric._multiprocess_mode in ('mostrecent', 'livemostrecent'):
-                        current_timestamp = sample_timestamps[labels][name]
-                        timestamp = float(timestamp or 0)
-                        if current_timestamp < timestamp:
-                            samples[labels][(name, labels)] = value
-                            sample_timestamps[labels][name] = timestamp
-                    else:  # all/liveall
-                        samples[labels][(name, labels)] = value
-
-                elif metric.type == 'histogram':
-                    # A for loop with early exit is faster than a genexpr
-                    # or a listcomp that ends up building unnecessary things
-                    for l in labels:
-                        if l[0] == 'le':
-                            bucket_value = float(l[1])
-                            # _bucket
-                            without_le = tuple(l for l in labels if l[0] != 'le')
-                            buckets[without_le][bucket_value] += value
-                            break
-                    else:  # did not find the `le` key
-                        # _sum/_count
-                        samples[labels][(name, labels)] += value
-                else:
-                    # Counter and Summary.
-                    samples[labels][(name, labels)] += value
-
-            # Accumulate bucket values.
-            if metric.type == 'histogram':
-                for labels, values in buckets.items():
-                    acc = 0.0
-                    for bucket, value in sorted(values.items()):
-                        sample_key = (
-                            metric.name + '_bucket',
-                            labels + (('le', floatToGoString(bucket)),),
-                        )
-                        if accumulate:
-                            acc += value
-                            samples[labels][sample_key] = acc
-                        else:
-                            samples[labels][sample_key] = value
-                    if accumulate:
-                        samples[labels][(metric.name + '_count', labels)] = acc
-
-            # Convert to correct sample format.
-            metric.samples = []
-            for _, samples_by_labels in samples.items():
-                for (name_, labels), value in samples_by_labels.items():
-                    metric.samples.append(Sample(name_, dict(labels), value))
-        return metrics.values()
-
-    def collect(self):
-        files = glob.glob(os.path.join(self._path, '*.db'))
-        return self.merge(files, accumulate=True)
-
-
-_LIVE_GAUGE_MULTIPROCESS_MODES = {m for m in Gauge._MULTIPROC_MODES if m.startswith('live')}
-
-
-def mark_process_dead(pid, path=None):
-    """Do bookkeeping for when one process dies in a multi-process setup."""
-    if path is None:
-        path = os.environ.get('PROMETHEUS_MULTIPROC_DIR', os.environ.get('prometheus_multiproc_dir'))
-    for mode in _LIVE_GAUGE_MULTIPROCESS_MODES:
-        for f in glob.glob(os.path.join(path, f'gauge_{mode}_{pid}.db')):
-            os.remove(f)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py
deleted file mode 100644
index 5a7711b027b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/exposition.py
+++ /dev/null
@@ -1,287 +0,0 @@
-#!/usr/bin/env python
-
-from io import StringIO
-from sys import maxunicode
-from typing import Callable
-
-from ..utils import floatToGoString, parse_version
-from ..validation import (
-    _is_valid_legacy_labelname, _is_valid_legacy_metric_name,
-)
-
-CONTENT_TYPE_LATEST = 'application/openmetrics-text; version=1.0.0; charset=utf-8'
-"""Content type of the latest OpenMetrics 1.0 text format"""
-CONTENT_TYPE_LATEST_2_0 = 'application/openmetrics-text; version=2.0.0; charset=utf-8'
-"""Content type of the OpenMetrics 2.0 text format"""
-ESCAPING_HEADER_TAG = 'escaping'
-
-
-ALLOWUTF8 = 'allow-utf-8'
-UNDERSCORES = 'underscores'
-DOTS = 'dots'
-VALUES = 'values'
-
-
-def _is_valid_exemplar_metric(metric, sample):
-    if metric.type == 'counter' and sample.name.endswith('_total'):
-        return True
-    if metric.type == 'gaugehistogram' and sample.name.endswith('_bucket'):
-        return True
-    if metric.type == 'histogram' and (sample.name.endswith('_bucket') or sample.name == metric.name):
-        return True
-    return False
-
-
-def _compose_exemplar_string(metric, sample, exemplar):
-    """Constructs an exemplar string."""
-    if not _is_valid_exemplar_metric(metric, sample):
-        raise ValueError(f"Metric {metric.name} has exemplars, but is not a histogram bucket or counter")
-    labels = '{{{0}}}'.format(','.join(
-        ['{}="{}"'.format(
-            k, v.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"'))
-            for k, v in sorted(exemplar.labels.items())]))
-    if exemplar.timestamp is not None:
-        exemplarstr = ' # {} {} {}'.format(
-            labels,
-            floatToGoString(exemplar.value),
-            exemplar.timestamp,
-        )
-    else:
-        exemplarstr = ' # {} {}'.format(
-            labels,
-            floatToGoString(exemplar.value),
-        )
-
-    return exemplarstr
-
-
-def generate_latest(registry, escaping=UNDERSCORES, version="1.0.0"):
-    '''Returns the metrics from the registry in latest text format as a string.'''
-    output = []
-    for metric in registry.collect():
-        try:
-            mname = metric.name
-            output.append('# HELP {} {}\n'.format(
-                escape_metric_name(mname, escaping), _escape(metric.documentation, ALLOWUTF8, _is_legacy_labelname_rune)))
-            output.append(f'# TYPE {escape_metric_name(mname, escaping)} {metric.type}\n')
-            if metric.unit:
-                output.append(f'# UNIT {escape_metric_name(mname, escaping)} {metric.unit}\n')
-            for s in metric.samples:
-                if escaping == ALLOWUTF8 and not _is_valid_legacy_metric_name(s.name):
-                    labelstr = escape_metric_name(s.name, escaping)
-                    if s.labels:
-                        labelstr += ','
-                else:
-                    labelstr = ''
-
-                if s.labels:
-                    items = sorted(s.labels.items())
-                    # Label values always support UTF-8
-                    labelstr += ','.join(
-                        ['{}="{}"'.format(
-                            escape_label_name(k, escaping), _escape(v, ALLOWUTF8, _is_legacy_labelname_rune))
-                            for k, v in items])
-                if labelstr:
-                    labelstr = "{" + labelstr + "}"
-                if s.exemplar:
-                    exemplarstr = _compose_exemplar_string(metric, s, s.exemplar)
-                else:
-                    exemplarstr = ''
-                timestamp = ''
-                if s.timestamp is not None:
-                    timestamp = f' {s.timestamp}'
-                
-                # Skip native histogram samples entirely if version < 2.0.0
-                if s.native_histogram and parse_version(version) < (2, 0, 0):
-                    continue
-                
-                native_histogram = ''
-                negative_spans = ''
-                negative_deltas = ''
-                positive_spans = ''
-                positive_deltas = ''
-                     
-                if s.native_histogram:
-                    # Initialize basic nh template
-                    nh_sample_template = '{{count:{},sum:{},schema:{},zero_threshold:{},zero_count:{}'
-
-                    args = [
-                        s.native_histogram.count_value,
-                        s.native_histogram.sum_value,
-                        s.native_histogram.schema,
-                        s.native_histogram.zero_threshold,
-                        s.native_histogram.zero_count,
-                    ]
-                  
-                    # If there are neg spans, append them and the neg deltas to the template and args
-                    if s.native_histogram.neg_spans:
-                        negative_spans = ','.join([f'{ns[0]}:{ns[1]}' for ns in s.native_histogram.neg_spans])
-                        negative_deltas = ','.join(str(nd) for nd in s.native_histogram.neg_deltas)
-                        nh_sample_template += ',negative_spans:[{}]'
-                        args.append(negative_spans)
-                        nh_sample_template += ',negative_deltas:[{}]'
-                        args.append(negative_deltas)
-
-                    # If there are pos spans, append them and the pos spans to the template and args
-                    if s.native_histogram.pos_spans:
-                        positive_spans = ','.join([f'{ps[0]}:{ps[1]}' for ps in s.native_histogram.pos_spans])
-                        positive_deltas = ','.join(f'{pd}' for pd in s.native_histogram.pos_deltas)
-                        nh_sample_template += ',positive_spans:[{}]'
-                        args.append(positive_spans)
-                        nh_sample_template += ',positive_deltas:[{}]'
-                        args.append(positive_deltas)                       
-                                                  
-                    # Add closing brace
-                    nh_sample_template += '}}'
-
-                    # Format the template with the args
-                    native_histogram = nh_sample_template.format(*args)
-                    
-                    if s.native_histogram.nh_exemplars:
-                        for nh_ex in s.native_histogram.nh_exemplars:
-                            nh_exemplarstr = _compose_exemplar_string(metric, s, nh_ex)
-                            exemplarstr += nh_exemplarstr
-
-                value = ''
-                if s.native_histogram:
-                    value = native_histogram
-                elif s.value is not None:
-                    value = floatToGoString(s.value)
-                if (escaping != ALLOWUTF8) or _is_valid_legacy_metric_name(s.name):
-                    output.append('{}{} {}{}{}\n'.format(
-                        _escape(s.name, escaping, _is_legacy_labelname_rune),
-                        labelstr,
-                        value,
-                        timestamp,
-                        exemplarstr
-                    ))
-                else:
-                    output.append('{} {}{}{}\n'.format(
-                        labelstr,
-                        value,
-                        timestamp,
-                        exemplarstr
-                    ))
-        except Exception as exception:
-            exception.args = (exception.args or ('',)) + (metric,)
-            raise
-
-    output.append('# EOF\n')
-    return ''.join(output).encode('utf-8')
-
-
-def escape_metric_name(s: str, escaping: str = UNDERSCORES) -> str:
-    """Escapes the metric name and puts it in quotes iff the name does not
-    conform to the legacy Prometheus character set.
-    """
-    if len(s) == 0:
-        return s
-    if escaping == ALLOWUTF8:
-        if not _is_valid_legacy_metric_name(s):
-            return '"{}"'.format(_escape(s, escaping, _is_legacy_metric_rune))
-        return _escape(s, escaping, _is_legacy_metric_rune)
-    elif escaping == UNDERSCORES:
-        if _is_valid_legacy_metric_name(s):
-            return s
-        return _escape(s, escaping, _is_legacy_metric_rune)
-    elif escaping == DOTS:
-        return _escape(s, escaping, _is_legacy_metric_rune)
-    elif escaping == VALUES:
-        if _is_valid_legacy_metric_name(s):
-            return s
-        return _escape(s, escaping, _is_legacy_metric_rune)
-    return s
-
-
-def escape_label_name(s: str, escaping: str = UNDERSCORES) -> str:
-    """Escapes the label name and puts it in quotes iff the name does not
-    conform to the legacy Prometheus character set.
-    """
-    if len(s) == 0:
-        return s
-    if escaping == ALLOWUTF8:
-        if not _is_valid_legacy_labelname(s):
-            return '"{}"'.format(_escape(s, escaping, _is_legacy_labelname_rune))
-        return _escape(s, escaping, _is_legacy_labelname_rune)
-    elif escaping == UNDERSCORES:
-        if _is_valid_legacy_labelname(s):
-            return s
-        return _escape(s, escaping, _is_legacy_labelname_rune)
-    elif escaping == DOTS:
-        return _escape(s, escaping, _is_legacy_labelname_rune)
-    elif escaping == VALUES:
-        if _is_valid_legacy_labelname(s):
-            return s
-        return _escape(s, escaping, _is_legacy_labelname_rune)
-    return s
-
-
-def _escape(s: str, escaping: str, valid_rune_fn: Callable[[str, int], bool]) -> str:
-    """Performs backslash escaping on backslash, newline, and double-quote characters.
-
-    valid_rune_fn takes the input character and its index in the containing string."""
-    if escaping == ALLOWUTF8:
-        return s.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"')
-    elif escaping == UNDERSCORES:
-        escaped = StringIO()
-        for i, b in enumerate(s):
-            if valid_rune_fn(b, i):
-                escaped.write(b)
-            else:
-                escaped.write('_')
-        return escaped.getvalue()
-    elif escaping == DOTS:
-        escaped = StringIO()
-        for i, b in enumerate(s):
-            if b == '_':
-                escaped.write('__')
-            elif b == '.':
-                escaped.write('_dot_')
-            elif valid_rune_fn(b, i):
-                escaped.write(b)
-            else:
-                escaped.write('__')
-        return escaped.getvalue()
-    elif escaping == VALUES:
-        escaped = StringIO()
-        escaped.write("U__")
-        for i, b in enumerate(s):
-            if b == '_':
-                escaped.write("__")
-            elif valid_rune_fn(b, i):
-                escaped.write(b)
-            elif not _is_valid_utf8(b):
-                escaped.write("_FFFD_")
-            else:
-                escaped.write('_')
-                escaped.write(format(ord(b), 'x'))
-                escaped.write('_')
-        return escaped.getvalue()
-    return s
-
-
-def _is_legacy_metric_rune(b: str, i: int) -> bool:
-    return _is_legacy_labelname_rune(b, i) or b == ':'
-
-
-def _is_legacy_labelname_rune(b: str, i: int) -> bool:
-    if len(b) != 1:
-        raise ValueError("Input 'b' must be a single character.")
-    return (
-        ('a' <= b <= 'z')
-        or ('A' <= b <= 'Z')
-        or (b == '_')
-        or ('0' <= b <= '9' and i > 0)
-    )
-
-
-_SURROGATE_MIN = 0xD800
-_SURROGATE_MAX = 0xDFFF
-
-
-def _is_valid_utf8(s: str) -> bool:
-    if 0 <= ord(s) < _SURROGATE_MIN:
-        return True
-    if _SURROGATE_MAX < ord(s) <= maxunicode:
-        return True
-    return False
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py
deleted file mode 100644
index 0c5c9c414ce..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/openmetrics/parser.py
+++ /dev/null
@@ -1,653 +0,0 @@
-#!/usr/bin/env python
-
-
-import io as StringIO
-import math
-import re
-
-from ..metrics_core import Metric
-from ..parser import (
-    _last_unquoted_char, _next_unquoted_char, _parse_value, _split_quoted,
-    _unquote_unescape, parse_labels,
-)
-from ..samples import BucketSpan, Exemplar, NativeHistogram, Sample, Timestamp
-from ..utils import floatToGoString
-from ..validation import _is_valid_legacy_metric_name, _validate_metric_name
-
-
-def text_string_to_metric_families(text):
-    """Parse Openmetrics text format from a unicode string.
-
-    See text_fd_to_metric_families.
-    """
-    yield from text_fd_to_metric_families(StringIO.StringIO(text))
-
-
-_CANONICAL_NUMBERS = {float("inf")}
-
-
-def _isUncanonicalNumber(s):
-    f = float(s)
-    if f not in _CANONICAL_NUMBERS:
-        return False  # Only the canonical numbers are required to be canonical.
-    return s != floatToGoString(f)
-
-
-ESCAPE_SEQUENCES = {
-    '\\\\': '\\',
-    '\\n': '\n',
-    '\\"': '"',
-}
-
-
-def _replace_escape_sequence(match):
-    return ESCAPE_SEQUENCES[match.group(0)]
-
-
-ESCAPING_RE = re.compile(r'\\[\\n"]')
-
-
-def _replace_escaping(s):
-    return ESCAPING_RE.sub(_replace_escape_sequence, s)
-
-
-def _unescape_help(text):
-    result = []
-    slash = False
-
-    for char in text:
-        if slash:
-            if char == '\\':
-                result.append('\\')
-            elif char == '"':
-                result.append('"')
-            elif char == 'n':
-                result.append('\n')
-            else:
-                result.append('\\' + char)
-            slash = False
-        else:
-            if char == '\\':
-                slash = True
-            else:
-                result.append(char)
-
-    if slash:
-        result.append('\\')
-
-    return ''.join(result)
-
-
-def _parse_timestamp(timestamp):
-    timestamp = ''.join(timestamp)
-    if not timestamp:
-        return None
-    if timestamp != timestamp.strip() or '_' in timestamp:
-        raise ValueError(f"Invalid timestamp: {timestamp!r}")
-    try:
-        # Simple int.
-        return Timestamp(int(timestamp), 0)
-    except ValueError:
-        try:
-            # aaaa.bbbb. Nanosecond resolution supported.
-            parts = timestamp.split('.', 1)
-            return Timestamp(int(parts[0]), int(parts[1][:9].ljust(9, "0")))
-        except ValueError:
-            # Float.
-            ts = float(timestamp)
-            if math.isnan(ts) or math.isinf(ts):
-                raise ValueError(f"Invalid timestamp: {timestamp!r}")
-            return ts
-
-
-def _is_character_escaped(s, charpos):
-    num_bslashes = 0
-    while (charpos > num_bslashes
-           and s[charpos - 1 - num_bslashes] == '\\'):
-        num_bslashes += 1
-    return num_bslashes % 2 == 1
-
-
-def _parse_sample(text):
-    separator = " # "
-    # Detect the labels in the text
-    label_start = _next_unquoted_char(text, '{')
-    if label_start == -1 or separator in text[:label_start]:
-        # We don't have labels, but there could be an exemplar.
-        name_end = _next_unquoted_char(text, ' ')
-        name = text[:name_end]
-        if not _is_valid_legacy_metric_name(name):
-            raise ValueError("invalid metric name:" + text)
-        # Parse the remaining text after the name
-        remaining_text = text[name_end + 1:]
-        value, timestamp, exemplar = _parse_remaining_text(remaining_text)
-        return Sample(name, {}, value, timestamp, exemplar)
-    name = text[:label_start]
-    label_end = _next_unquoted_char(text, '}')
-    labels = parse_labels(text[label_start + 1:label_end], True)
-    if not name:
-        # Name might be in the labels
-        if '__name__' not in labels:
-            raise ValueError
-        name = labels['__name__']
-        del labels['__name__']
-    elif '__name__' in labels:
-        raise ValueError("metric name specified more than once")
-    # Parsing labels succeeded, continue parsing the remaining text
-    remaining_text = text[label_end + 2:]
-    value, timestamp, exemplar = _parse_remaining_text(remaining_text)
-    return Sample(name, labels, value, timestamp, exemplar)
-
-
-def _parse_remaining_text(text):
-    split_text = text.split(" ", 1)
-    val = _parse_value(split_text[0])
-    if len(split_text) == 1:
-        # We don't have timestamp or exemplar
-        return val, None, None  
-
-    timestamp = []
-    exemplar_value = []
-    exemplar_timestamp = []
-    exemplar_labels = None
-
-    state = 'timestamp'
-    text = split_text[1]
-
-    it = iter(text)
-    in_quotes = False
-    for char in it:
-        if char == '"':
-            in_quotes = not in_quotes
-        if in_quotes:
-            continue
-        if state == 'timestamp':
-            if char == '#' and not timestamp:
-                state = 'exemplarspace'
-            elif char == ' ':
-                state = 'exemplarhash'
-            else:
-                timestamp.append(char)
-        elif state == 'exemplarhash':
-            if char == '#':
-                state = 'exemplarspace'
-            else:
-                raise ValueError("Invalid line: " + text)
-        elif state == 'exemplarspace':
-            if char == ' ':
-                state = 'exemplarstartoflabels'
-            else:
-                raise ValueError("Invalid line: " + text)
-        elif state == 'exemplarstartoflabels':
-            if char == '{':
-                label_start = _next_unquoted_char(text, '{')
-                label_end = _last_unquoted_char(text, '}')
-                exemplar_labels = parse_labels(text[label_start + 1:label_end], True)
-                state = 'exemplarparsedlabels'
-            else:
-                raise ValueError("Invalid line: " + text)
-        elif state == 'exemplarparsedlabels':
-            if char == '}':
-                state = 'exemplarvaluespace'
-        elif state == 'exemplarvaluespace':
-            if char == ' ':
-                state = 'exemplarvalue'
-            else:
-                raise ValueError("Invalid line: " + text)
-        elif state == 'exemplarvalue':
-            if char == ' ' and not exemplar_value:
-                raise ValueError("Invalid line: " + text)
-            elif char == ' ':
-                state = 'exemplartimestamp'
-            else:
-                exemplar_value.append(char)
-        elif state == 'exemplartimestamp':
-            exemplar_timestamp.append(char)
-
-    # Trailing space after value.
-    if state == 'timestamp' and not timestamp:
-        raise ValueError("Invalid line: " + text)
-
-    # Trailing space after value.
-    if state == 'exemplartimestamp' and not exemplar_timestamp:
-        raise ValueError("Invalid line: " + text)
-
-    # Incomplete exemplar.
-    if state in ['exemplarhash', 'exemplarspace', 'exemplarstartoflabels', 'exemplarparsedlabels']:
-        raise ValueError("Invalid line: " + text)
-
-    ts = _parse_timestamp(timestamp)
-    exemplar = None
-    if exemplar_labels is not None:
-        exemplar_length = sum(len(k) + len(v) for k, v in exemplar_labels.items())
-        if exemplar_length > 128:
-            raise ValueError("Exemplar labels are too long: " + text)
-        exemplar = Exemplar(
-            exemplar_labels,
-            _parse_value(exemplar_value),
-            _parse_timestamp(exemplar_timestamp),
-        )
-
-    return val, ts, exemplar
-
-
-def _parse_nh_sample(text, suffixes):
-    """Determines if the line has a native histogram sample, and parses it if so."""
-    labels_start = _next_unquoted_char(text, '{')
-    labels_end = -1
-
-    # Finding a native histogram sample requires careful parsing of
-    # possibly-quoted text, which can appear in metric names, label names, and
-    # values.
-    # 
-    # First, we need to determine if there are metric labels. Find the space
-    # between the metric definition and the rest of the line. Look for unquoted
-    # space or {.
-    i = 0
-    has_metric_labels = False
-    i = _next_unquoted_char(text, ' {')
-    if i == -1:
-        return
-
-    # If the first unquoted char was a {, then that is the metric labels (which
-    # could contain a UTF-8 metric name).
-    if text[i] == '{':
-        has_metric_labels = True
-        # Consume the labels -- jump ahead to the close bracket.
-        labels_end = i = _next_unquoted_char(text, '}', i)
-        if labels_end == -1:
-            raise ValueError
-    
-    # If there is no subsequent unquoted {, then it's definitely not a nh.
-    nh_value_start = _next_unquoted_char(text, '{', i + 1)
-    if nh_value_start == -1:
-        return
-    
-    # Edge case: if there is an unquoted # between the metric definition and the {,
-    # then this is actually an exemplar
-    exemplar = _next_unquoted_char(text, '#', i + 1)
-    if exemplar != -1 and exemplar < nh_value_start:
-        return
-    
-    nh_value_end = _next_unquoted_char(text, '}', nh_value_start)
-    if nh_value_end == -1:
-        raise ValueError
-    
-    if has_metric_labels:
-        labelstext = text[labels_start + 1:labels_end]
-        labels = parse_labels(labelstext, True)
-        name_end = labels_start
-        name = text[:name_end]
-        if name.endswith(suffixes):
-            raise ValueError("the sample name of a native histogram with labels should have no suffixes", name)
-        if not name:
-            # Name might be in the labels
-            if '__name__' not in labels:
-                raise ValueError
-            name = labels['__name__']
-            del labels['__name__']
-            # Edge case: the only "label" is the name definition.
-            if not labels:
-                labels = None
-             
-        nh_value = text[nh_value_start:]
-        nat_hist_value = _parse_nh_struct(nh_value)
-        return Sample(name, labels, None, None, None, nat_hist_value)
-    # check if it's a native histogram
-    else:
-        nh_value = text[nh_value_start:]
-        name_end = nh_value_start - 1
-        name = text[:name_end]
-        if name.endswith(suffixes):
-            raise ValueError("the sample name of a native histogram should have no suffixes", name)
-        # Not possible for UTF-8 name here, that would have been caught as having a labelset.
-        nat_hist_value = _parse_nh_struct(nh_value)
-        return Sample(name, None, None, None, None, nat_hist_value)      
-
-
-def _parse_nh_struct(text):
-    pattern = r'(\w+):\s*([^,}]+)'
-    re_spans = re.compile(r'(positive_spans|negative_spans):\[(\d+:\d+(,\d+:\d+)*)\]')
-    re_deltas = re.compile(r'(positive_deltas|negative_deltas):\[(-?\d+(?:,-?\d+)*)\]')
-
-    items = dict(re.findall(pattern, text))
-    span_matches = re_spans.findall(text)
-    deltas = dict(re_deltas.findall(text))
-
-    count_value = int(items['count'])
-    sum_value = float(items['sum'])
-    schema = int(items['schema'])
-    zero_threshold = float(items['zero_threshold'])
-    zero_count = int(items['zero_count'])
-
-    pos_spans = _compose_spans(span_matches, 'positive_spans')
-    neg_spans = _compose_spans(span_matches, 'negative_spans')
-    pos_deltas = _compose_deltas(deltas, 'positive_deltas')
-    neg_deltas = _compose_deltas(deltas, 'negative_deltas')
-      
-    return NativeHistogram(
-        count_value=count_value,
-        sum_value=sum_value,
-        schema=schema,
-        zero_threshold=zero_threshold,
-        zero_count=zero_count,
-        pos_spans=pos_spans,
-        neg_spans=neg_spans,
-        pos_deltas=pos_deltas,
-        neg_deltas=neg_deltas
-    )
-  
-
-def _compose_spans(span_matches, spans_name):
-    """Takes a list of span matches (expected to be a list of tuples) and a string 
-    (the expected span list name) and processes the list so that the values extracted 
-    from the span matches can be used to compose a tuple of BucketSpan objects"""
-    spans = {}
-    for match in span_matches:
-        # Extract the key from the match (first element of the tuple).
-        key = match[0]
-        # Extract the value from the match (second element of the tuple).
-        # Split the value string by commas to get individual pairs, 
-        # split each pair by ':' to get start and end, and convert them to integers.
-        value = [tuple(map(int, pair.split(':'))) for pair in match[1].split(',')]
-        # Store the processed value in the spans dictionary with the key.
-        spans[key] = value
-    if spans_name not in spans:
-        return None
-    out_spans = []
-    # Iterate over each start and end tuple in the list of tuples for the specified spans_name.
-    for start, end in spans[spans_name]:
-        # Compose a BucketSpan object with the start and end values 
-        # and append it to the out_spans list.
-        out_spans.append(BucketSpan(start, end))
-        # Convert to tuple
-    out_spans_tuple = tuple(out_spans)
-    return out_spans_tuple
-
-
-def _compose_deltas(deltas, deltas_name):
-    """Takes a list of deltas matches (a dictionary) and a string (the expected delta list name),
-    and processes its elements to compose a tuple of integers representing the deltas"""
-    if deltas_name not in deltas:
-        return None
-    out_deltas = deltas.get(deltas_name)
-    if out_deltas is not None and out_deltas.strip():
-        elems = out_deltas.split(',')
-    # Convert each element in the list elems to an integer 
-    # after stripping whitespace and create a tuple from these integers.
-    out_deltas_tuple = tuple(int(x.strip()) for x in elems)
-    return out_deltas_tuple
-        
-
-def _group_for_sample(sample, name, typ):
-    if typ == 'info':
-        # We can't distinguish between groups for info metrics.
-        return {}
-    if typ == 'summary' and sample.name == name:
-        d = sample.labels.copy()
-        del d['quantile']
-        return d
-    if typ == 'stateset':
-        d = sample.labels.copy()
-        del d[name]
-        return d
-    if typ in ['histogram', 'gaugehistogram'] and sample.name == name + '_bucket':
-        d = sample.labels.copy()
-        del d['le']
-        return d
-    return sample.labels
-
-
-def _check_histogram(samples, name):
-    group = None
-    timestamp = None
-
-    def do_checks():
-        if bucket != float('+Inf'):
-            raise ValueError("+Inf bucket missing: " + name)
-        if count is not None and value != count:
-            raise ValueError("Count does not match +Inf value: " + name)
-        if has_sum and count is None:
-            raise ValueError("_count must be present if _sum is present: " + name)
-        if has_gsum and count is None:
-            raise ValueError("_gcount must be present if _gsum is present: " + name)
-        if not (has_sum or has_gsum) and count is not None:
-            raise ValueError("_sum/_gsum must be present if _count is present: " + name)
-        if has_negative_buckets and has_sum:
-            raise ValueError("Cannot have _sum with negative buckets: " + name)
-        if not has_negative_buckets and has_negative_gsum:
-            raise ValueError("Cannot have negative _gsum with non-negative buckets: " + name)
-
-    for s in samples:
-        suffix = s.name[len(name):]
-        g = _group_for_sample(s, name, 'histogram')
-        if len(suffix) == 0:
-            continue
-        if g != group or s.timestamp != timestamp:
-            if group is not None:
-                do_checks()
-            count = None
-            bucket = None
-            has_negative_buckets = False
-            has_sum = False
-            has_gsum = False
-            has_negative_gsum = False
-            value = 0
-        group = g
-        timestamp = s.timestamp
-
-        if suffix == '_bucket':
-            b = float(s.labels['le'])
-            if b < 0:
-                has_negative_buckets = True
-            if bucket is not None and b <= bucket:
-                raise ValueError("Buckets out of order: " + name)
-            if s.value < value:
-                raise ValueError("Bucket values out of order: " + name)
-            bucket = b
-            value = s.value
-        elif suffix in ['_count', '_gcount']:
-            count = s.value
-        elif suffix in ['_sum']:
-            has_sum = True
-        elif suffix in ['_gsum']:
-            has_gsum = True
-            if s.value < 0:
-                has_negative_gsum = True
-
-    if group is not None:
-        do_checks()
-
-
-def text_fd_to_metric_families(fd):
-    """Parse Prometheus text format from a file descriptor.
-
-    This is a laxer parser than the main Go parser,
-    so successful parsing does not imply that the parsed
-    text meets the specification.
-
-    Yields Metric's.
-    """
-    name = None
-    allowed_names = []
-    eof = False
-
-    seen_names = set()
-    type_suffixes = {
-        'counter': ['_total', '_created'],
-        'summary': ['', '_count', '_sum', '_created'],
-        'histogram': ['_count', '_sum', '_bucket', '_created'],
-        'gaugehistogram': ['_gcount', '_gsum', '_bucket'],
-        'info': ['_info'],
-    }
-
-    def build_metric(name, documentation, typ, unit, samples):
-        if typ is None:
-            typ = 'unknown'
-        for suffix in set(type_suffixes.get(typ, []) + [""]):
-            if name + suffix in seen_names:
-                raise ValueError("Clashing name: " + name + suffix)
-            seen_names.add(name + suffix)
-        if documentation is None:
-            documentation = ''
-        if unit is None:
-            unit = ''
-        if unit and not name.endswith("_" + unit):
-            raise ValueError("Unit does not match metric name: " + name)
-        if unit and typ in ['info', 'stateset']:
-            raise ValueError("Units not allowed for this metric type: " + name)
-        if typ in ['histogram', 'gaugehistogram']:
-            _check_histogram(samples, name)
-        _validate_metric_name(name)
-        metric = Metric(name, documentation, typ, unit)
-        # TODO: check labelvalues are valid utf8
-        metric.samples = samples
-        return metric
-
-    is_nh = False
-    typ = None
-    for line in fd:
-        if line[-1] == '\n':
-            line = line[:-1]
-
-        if eof:
-            raise ValueError("Received line after # EOF: " + line)
-
-        if not line:
-            raise ValueError("Received blank line")
-
-        if line == '# EOF':
-            eof = True
-        elif line.startswith('#'):
-            parts = _split_quoted(line, ' ', 3)
-            if len(parts) < 4:
-                raise ValueError("Invalid line: " + line)
-            candidate_name, quoted = _unquote_unescape(parts[2])
-            if not quoted and not _is_valid_legacy_metric_name(candidate_name):
-                raise ValueError
-            if candidate_name == name and samples:
-                raise ValueError("Received metadata after samples: " + line)
-            if candidate_name != name:
-                if name is not None:
-                    yield build_metric(name, documentation, typ, unit, samples)
-                # New metric
-                name = candidate_name
-                unit = None
-                typ = None
-                documentation = None
-                group = None
-                seen_groups = set()
-                group_timestamp = None
-                group_timestamp_samples = set()
-                samples = []
-                allowed_names = [candidate_name]
-            
-            if parts[1] == 'HELP':
-                if documentation is not None:
-                    raise ValueError("More than one HELP for metric: " + line)
-                documentation = _unescape_help(parts[3])
-            elif parts[1] == 'TYPE':
-                if typ is not None:
-                    raise ValueError("More than one TYPE for metric: " + line)
-                typ = parts[3]
-                if typ == 'untyped':
-                    raise ValueError("Invalid TYPE for metric: " + line)
-                allowed_names = [name + n for n in type_suffixes.get(typ, [''])]
-            elif parts[1] == 'UNIT':
-                if unit is not None:
-                    raise ValueError("More than one UNIT for metric: " + line)
-                unit = parts[3]
-            else:
-                raise ValueError("Invalid line: " + line)
-        else:
-            if typ == 'histogram':
-                # set to true to account for native histograms naming exceptions/sanitizing differences
-                is_nh = True
-                sample = _parse_nh_sample(line, tuple(type_suffixes['histogram']))
-                # It's not a native histogram
-                if sample is None:
-                    is_nh = False
-                    sample = _parse_sample(line)              
-            else:
-                is_nh = False
-                sample = _parse_sample(line)
-            if sample.name not in allowed_names and not is_nh:
-                if name is not None:
-                    yield build_metric(name, documentation, typ, unit, samples)
-                # Start an unknown metric.
-                candidate_name, quoted = _unquote_unescape(sample.name)
-                if not quoted and not _is_valid_legacy_metric_name(candidate_name):
-                    raise ValueError
-                name = candidate_name
-                documentation = None
-                unit = None
-                typ = 'unknown'
-                samples = []
-                group = None
-                group_timestamp = None
-                group_timestamp_samples = set()
-                seen_groups = set()
-                allowed_names = [sample.name]
-
-            if typ == 'stateset' and name not in sample.labels:
-                raise ValueError("Stateset missing label: " + line)
-            if (name + '_bucket' == sample.name
-                    and (sample.labels.get('le', "NaN") == "NaN"
-                         or _isUncanonicalNumber(sample.labels['le']))):
-                raise ValueError("Invalid le label: " + line)
-            if (name + '_bucket' == sample.name
-                    and (not isinstance(sample.value, int) and not sample.value.is_integer())):
-                raise ValueError("Bucket value must be an integer: " + line)
-            if ((name + '_count' == sample.name or name + '_gcount' == sample.name)
-                    and (not isinstance(sample.value, int) and not sample.value.is_integer())):
-                raise ValueError("Count value must be an integer: " + line)
-            if (typ == 'summary' and name == sample.name
-                    and (not (0 <= float(sample.labels.get('quantile', -1)) <= 1)
-                         or _isUncanonicalNumber(sample.labels['quantile']))):
-                raise ValueError("Invalid quantile label: " + line)
-
-            if not is_nh:
-                g = tuple(sorted(_group_for_sample(sample, name, typ).items()))
-                if group is not None and g != group and g in seen_groups:
-                    raise ValueError("Invalid metric grouping: " + line)
-                if group is not None and g == group:
-                    if (sample.timestamp is None) != (group_timestamp is None):
-                        raise ValueError("Mix of timestamp presence within a group: " + line)
-                    if group_timestamp is not None and group_timestamp > sample.timestamp and typ != 'info':
-                        raise ValueError("Timestamps went backwards within a group: " + line)
-                else:
-                    group_timestamp_samples = set()
-
-                series_id = (sample.name, tuple(sorted(sample.labels.items())))
-                if sample.timestamp != group_timestamp or series_id not in group_timestamp_samples:
-                    # Not a duplicate due to timestamp truncation.
-                    samples.append(sample)
-                group_timestamp_samples.add(series_id)
-
-                group = g
-                group_timestamp = sample.timestamp
-                seen_groups.add(g)
-            else:
-                samples.append(sample)
-
-            if typ == 'stateset' and sample.value not in [0, 1]:
-                raise ValueError("Stateset samples can only have values zero and one: " + line)
-            if typ == 'info' and sample.value != 1:
-                raise ValueError("Info samples can only have value one: " + line)
-            if typ == 'summary' and name == sample.name and sample.value < 0:
-                raise ValueError("Quantile values cannot be negative: " + line)
-            if sample.name[len(name):] in ['_total', '_sum', '_count', '_bucket', '_gcount', '_gsum'] and math.isnan(
-                    sample.value):
-                raise ValueError("Counter-like samples cannot be NaN: " + line)
-            if sample.name[len(name):] in ['_total', '_sum', '_count', '_bucket', '_gcount'] and sample.value < 0:
-                raise ValueError("Counter-like samples cannot be negative: " + line)
-            if sample.exemplar and not (
-                    (typ in ['histogram', 'gaugehistogram'] and sample.name.endswith('_bucket'))
-                    or (typ in ['counter'] and sample.name.endswith('_total'))):
-                raise ValueError("Invalid line only histogram/gaugehistogram buckets and counters can have exemplars: " + line)
-    
-    if name is not None:
-        yield build_metric(name, documentation, typ, unit, samples)
-
-    if not eof:
-        raise ValueError("Missing # EOF at end")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py
deleted file mode 100644
index ceca273b42e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/parser.py
+++ /dev/null
@@ -1,370 +0,0 @@
-import io as StringIO
-import re
-import string
-from typing import Dict, Iterable, List, Match, Optional, TextIO, Tuple
-
-from .metrics_core import Metric
-from .samples import Sample
-from .validation import (
-    _is_valid_legacy_metric_name, _validate_labelname, _validate_metric_name,
-)
-
-
-def text_string_to_metric_families(text: str) -> Iterable[Metric]:
-    """Parse Prometheus text format from a unicode string.
-
-    See text_fd_to_metric_families.
-    """
-    yield from text_fd_to_metric_families(StringIO.StringIO(text))
-
-
-ESCAPE_SEQUENCES = {
-    '\\\\': '\\',
-    '\\n': '\n',
-    '\\"': '"',
-}
-
-
-def replace_escape_sequence(match: Match[str]) -> str:
-    return ESCAPE_SEQUENCES[match.group(0)]
-
-
-HELP_ESCAPING_RE = re.compile(r'\\[\\n]')
-ESCAPING_RE = re.compile(r'\\[\\n"]')
-
-
-def _replace_help_escaping(s: str) -> str:
-    return HELP_ESCAPING_RE.sub(replace_escape_sequence, s)
-
-
-def _replace_escaping(s: str) -> str:
-    return ESCAPING_RE.sub(replace_escape_sequence, s)
-
-
-def _is_character_escaped(s: str, charpos: int) -> bool:
-    num_bslashes = 0
-    while (charpos > num_bslashes
-           and s[charpos - 1 - num_bslashes] == '\\'):
-        num_bslashes += 1
-    return num_bslashes % 2 == 1
-
-
-def parse_labels(labels_string: str, openmetrics: bool = False) -> Dict[str, str]:
-    labels: Dict[str, str] = {}
-
-    # Copy original labels
-    sub_labels = labels_string.strip()
-    if openmetrics and sub_labels and sub_labels[0] == ',':
-        raise ValueError("leading comma: " + labels_string)
-    try:
-        # Process one label at a time
-        while sub_labels:
-            # The label name is before the equal, or if there's no equal, that's the
-            # metric name.
-            
-            name_term, value_term, sub_labels = _next_term(sub_labels, openmetrics)
-            if not value_term:
-                if openmetrics:
-                    raise ValueError("empty term in line: " + labels_string)
-                continue
-            
-            label_name, quoted_name = _unquote_unescape(name_term)
-                
-            if not quoted_name and not _is_valid_legacy_metric_name(label_name):
-                raise ValueError("unquoted UTF-8 metric name")
-                
-            # Check for missing quotes 
-            if not value_term or value_term[0] != '"':
-                raise ValueError
-
-            # The first quote is guaranteed to be after the equal.
-            # Make sure that the next unescaped quote is the last character.
-            i = 1
-            while i < len(value_term):
-                i = value_term.index('"', i)
-                if not _is_character_escaped(value_term[:i], i):
-                    break
-                i += 1
-            # The label value is between the first and last quote
-            quote_end = i + 1
-            if quote_end != len(value_term):
-                raise ValueError("unexpected text after quote: " + labels_string)
-
-            label_value, _ = _unquote_unescape(value_term)
-            if label_name == '__name__':
-                _validate_metric_name(label_name)
-            else:
-                _validate_labelname(label_name)
-            if label_name in labels:
-                raise ValueError("invalid line, duplicate label name: " + labels_string)
-            labels[label_name] = label_value
-        return labels
-    except ValueError:
-        raise ValueError("Invalid labels: " + labels_string)
-    
-
-def _next_term(text: str, openmetrics: bool) -> Tuple[str, str, str]:
-    """Extract the next comma-separated label term from the text. The results
-    are stripped terms for the label name, label value, and then the remainder
-    of the string including the final , or }.
-    
-    Raises ValueError if the term is empty and we're in openmetrics mode.
-    """
-    
-    # There may be a leading comma, which is fine here.
-    if text[0] == ',':
-        text = text[1:]
-        if not text:
-            return "", "", ""
-        if text[0] == ',':
-            raise ValueError("multiple commas")
-
-    splitpos = _next_unquoted_char(text, '=,}')
-    if splitpos >= 0 and text[splitpos] == "=":
-        labelname = text[:splitpos]
-        text = text[splitpos + 1:]
-        splitpos = _next_unquoted_char(text, ',}')
-    else:
-        labelname = "__name__"
-
-    if splitpos == -1:
-        splitpos = len(text)
-    term = text[:splitpos]
-    if not term and openmetrics:
-        raise ValueError("empty term:", term)
-    
-    rest = text[splitpos:]
-    return labelname, term.strip(), rest.strip()
-
-
-def _next_unquoted_char(text: str, chs: Optional[str], startidx: int = 0) -> int:
-    """Return position of next unquoted character in tuple, or -1 if not found.
-    
-    It is always assumed that the first character being checked is not already
-    inside quotes.
-    """
-    in_quotes = False
-    if chs is None:
-        chs = string.whitespace
-
-    for i, c in enumerate(text[startidx:]):
-        if c == '"' and not _is_character_escaped(text, startidx + i):
-            in_quotes = not in_quotes
-        if not in_quotes:
-            if c in chs:
-                return startidx + i
-    return -1
-
-
-def _last_unquoted_char(text: str, chs: Optional[str]) -> int:
-    """Return position of last unquoted character in list, or -1 if not found."""
-    i = len(text) - 1
-    in_quotes = False
-    if chs is None:
-        chs = string.whitespace
-    while i > 0:
-        if text[i] == '"' and not _is_character_escaped(text, i):
-            in_quotes = not in_quotes
-            
-        if not in_quotes:
-            if text[i] in chs:
-                return i
-        i -= 1
-    return -1
-
-
-def _split_quoted(text, separator, maxsplit=0):
-    """Splits on split_ch similarly to strings.split, skipping separators if
-    they are inside quotes.
-    """
-
-    tokens = ['']
-    x = 0
-    while x < len(text):
-        split_pos = _next_unquoted_char(text, separator, x)
-        if split_pos == -1:
-            tokens[-1] = text[x:]
-            x = len(text)
-            continue
-        # If the first character is the separator keep going. This happens when
-        # there are double whitespace characters separating symbols.
-        if split_pos == x:
-            x += 1
-            continue
-
-        if maxsplit > 0 and len(tokens) > maxsplit:
-            tokens[-1] = text[x:]
-            break
-        tokens[-1] = text[x:split_pos]
-        x = split_pos + 1
-        tokens.append('')
-    return tokens
-
-
-def _unquote_unescape(text):
-    """Returns the string, and true if it was quoted."""
-    if not text:
-        return text, False
-    quoted = False
-    text = text.strip()
-    if text[0] == '"':
-        if len(text) == 1 or text[-1] != '"':
-            raise ValueError("missing close quote")
-        text = text[1:-1]
-        quoted = True
-    if "\\" in text:
-        text = _replace_escaping(text)
-    return text, quoted
-
-
-# If we have multiple values only consider the first
-def _parse_value_and_timestamp(s: str) -> Tuple[float, Optional[float]]:
-    s = s.lstrip()
-    separator = " "
-    if separator not in s:
-        separator = "\t"
-    values = [value.strip() for value in s.split(separator) if value.strip()]
-    if not values:
-        return float(s), None
-    value = _parse_value(values[0])
-    timestamp = (_parse_value(values[-1]) / 1000) if len(values) > 1 else None
-    return value, timestamp
-
-
-def _parse_value(value):
-    value = ''.join(value)
-    if value != value.strip() or '_' in value:
-        raise ValueError(f"Invalid value: {value!r}")
-    try:
-        return int(value)
-    except ValueError:
-        return float(value)
-    
-
-def _parse_sample(text):
-    separator = " # "
-    # Detect the labels in the text
-    label_start = _next_unquoted_char(text, '{')
-    if label_start == -1 or separator in text[:label_start]:
-        # We don't have labels, but there could be an exemplar.
-        name_end = _next_unquoted_char(text, ' \t')
-        name = text[:name_end].strip()
-        if not _is_valid_legacy_metric_name(name):
-            raise ValueError("invalid metric name:" + text)
-        # Parse the remaining text after the name
-        remaining_text = text[name_end + 1:]
-        value, timestamp = _parse_value_and_timestamp(remaining_text)
-        return Sample(name, {}, value, timestamp)
-    name = text[:label_start].strip()
-    label_end = _next_unquoted_char(text[label_start:], '}') + label_start
-    labels = parse_labels(text[label_start + 1:label_end], False)
-    if not name:
-        # Name might be in the labels
-        if '__name__' not in labels:
-            raise ValueError
-        name = labels['__name__']
-        del labels['__name__']
-    elif '__name__' in labels:
-        raise ValueError("metric name specified more than once")
-    # Parsing labels succeeded, continue parsing the remaining text
-    remaining_text = text[label_end + 1:]
-    value, timestamp = _parse_value_and_timestamp(remaining_text)
-    return Sample(name, labels, value, timestamp)
-
-
-def text_fd_to_metric_families(fd: TextIO) -> Iterable[Metric]:
-    """Parse Prometheus text format from a file descriptor.
-
-    This is a laxer parser than the main Go parser,
-    so successful parsing does not imply that the parsed
-    text meets the specification.
-
-    Yields Metric's.
-    """
-    name = ''
-    documentation = ''
-    typ = 'untyped'
-    samples: List[Sample] = []
-    allowed_names = []
-
-    def build_metric(name: str, documentation: str, typ: str, samples: List[Sample]) -> Metric:
-        # Munge counters into OpenMetrics representation
-        # used internally.
-        if typ == 'counter':
-            if name.endswith('_total'):
-                name = name[:-6]
-            else:
-                new_samples = []
-                for s in samples:
-                    new_samples.append(Sample(s[0] + '_total', *s[1:]))
-                    samples = new_samples
-        metric = Metric(name, documentation, typ)
-        metric.samples = samples
-        return metric
-
-    for line in fd:
-        line = line.strip()
-
-        if line.startswith('#'):
-            parts = _split_quoted(line, None, 3)
-            if len(parts) < 2:
-                continue
-            candidate_name, quoted = '', False
-            if len(parts) > 2:
-                # Ignore comment tokens
-                if parts[1] != 'TYPE' and parts[1] != 'HELP':
-                    continue
-                candidate_name, quoted = _unquote_unescape(parts[2])
-                if not quoted and not _is_valid_legacy_metric_name(candidate_name):
-                    raise ValueError
-            if parts[1] == 'HELP':
-                if candidate_name != name:
-                    if name != '':
-                        yield build_metric(name, documentation, typ, samples)
-                    # New metric
-                    name = candidate_name
-                    typ = 'untyped'
-                    samples = []
-                    allowed_names = [candidate_name]
-                if len(parts) == 4:
-                    documentation = _replace_help_escaping(parts[3])
-                else:
-                    documentation = ''
-            elif parts[1] == 'TYPE':
-                if len(parts) < 4:
-                    raise ValueError
-                if candidate_name != name:
-                    if name != '':
-                        yield build_metric(name, documentation, typ, samples)
-                    # New metric
-                    name = candidate_name
-                    documentation = ''
-                    samples = []
-                typ = parts[3]
-                allowed_names = {
-                    'counter': [''],
-                    'gauge': [''],
-                    'summary': ['_count', '_sum', ''],
-                    'histogram': ['_count', '_sum', '_bucket'],
-                }.get(typ, [''])
-                allowed_names = [name + n for n in allowed_names]
-        elif line == '':
-            # Ignore blank lines
-            pass
-        else:
-            sample = _parse_sample(line)
-            if sample.name not in allowed_names:
-                if name != '':
-                    yield build_metric(name, documentation, typ, samples)
-                # New metric, yield immediately as untyped singleton
-                name = ''
-                documentation = ''
-                typ = 'untyped'
-                samples = []
-                allowed_names = []
-                yield build_metric(sample[0], documentation, typ, [sample])
-            else:
-                samples.append(sample)
-
-    if name != '':
-        yield build_metric(name, documentation, typ, samples)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py
deleted file mode 100644
index 6040fcce622..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/platform_collector.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import platform as pf
-from typing import Any, Iterable, Optional
-
-from .metrics_core import GaugeMetricFamily, Metric
-from .registry import Collector, CollectorRegistry, REGISTRY
-
-
-class PlatformCollector(Collector):
-    """Collector for python platform information"""
-
-    def __init__(self,
-                 registry: Optional[CollectorRegistry] = REGISTRY,
-                 platform: Optional[Any] = None,
-                 ):
-        self._platform = pf if platform is None else platform
-        info = self._info()
-        system = self._platform.system()
-        if system == "Java":
-            info.update(self._java())
-        self._metrics = [
-            self._add_metric("python_info", "Python platform information", info)
-        ]
-        if registry:
-            registry.register(self)
-
-    def collect(self) -> Iterable[Metric]:
-        return self._metrics
-
-    @staticmethod
-    def _add_metric(name, documentation, data):
-        labels = data.keys()
-        values = [data[k] for k in labels]
-        g = GaugeMetricFamily(name, documentation, labels=labels)
-        g.add_metric(values, 1)
-        return g
-
-    def _info(self):
-        major, minor, patchlevel = self._platform.python_version_tuple()
-        return {
-            "version": self._platform.python_version(),
-            "implementation": self._platform.python_implementation(),
-            "major": major,
-            "minor": minor,
-            "patchlevel": patchlevel
-        }
-
-    def _java(self):
-        java_version, _, vminfo, osinfo = self._platform.java_ver()
-        vm_name, vm_release, vm_vendor = vminfo
-        return {
-            "jvm_version": java_version,
-            "jvm_release": vm_release,
-            "jvm_vendor": vm_vendor,
-            "jvm_name": vm_name
-        }
-
-
-PLATFORM_COLLECTOR = PlatformCollector()
-"""PlatformCollector in default Registry REGISTRY"""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py
deleted file mode 100644
index 2894e874502..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/process_collector.py
+++ /dev/null
@@ -1,101 +0,0 @@
-import os
-from typing import Callable, Iterable, Optional, Union
-
-from .metrics_core import CounterMetricFamily, GaugeMetricFamily, Metric
-from .registry import Collector, CollectorRegistry, REGISTRY
-
-try:
-    import resource
-
-    _PAGESIZE = resource.getpagesize()
-except ImportError:
-    # Not Unix
-    _PAGESIZE = 4096
-
-
-class ProcessCollector(Collector):
-    """Collector for Standard Exports such as cpu and memory."""
-
-    def __init__(self,
-                 namespace: str = '',
-                 pid: Callable[[], Union[int, str]] = lambda: 'self',
-                 proc: str = '/proc',
-                 registry: Optional[CollectorRegistry] = REGISTRY):
-        self._namespace = namespace
-        self._pid = pid
-        self._proc = proc
-        if namespace:
-            self._prefix = namespace + '_process_'
-        else:
-            self._prefix = 'process_'
-        self._ticks = 100.0
-        try:
-            self._ticks = os.sysconf('SC_CLK_TCK')
-        except (ValueError, TypeError, AttributeError, OSError):
-            pass
-
-        self._pagesize = _PAGESIZE
-
-        # This is used to test if we can access /proc.
-        self._btime = 0
-        try:
-            self._btime = self._boot_time()
-        except OSError:
-            pass
-        if registry:
-            registry.register(self)
-
-    def _boot_time(self):
-        with open(os.path.join(self._proc, 'stat'), 'rb') as stat:
-            for line in stat:
-                if line.startswith(b'btime '):
-                    return float(line.split()[1])
-
-    def collect(self) -> Iterable[Metric]:
-        if not self._btime:
-            return []
-
-        pid = os.path.join(self._proc, str(self._pid()).strip())
-
-        result = []
-        try:
-            with open(os.path.join(pid, 'stat'), 'rb') as stat:
-                parts = (stat.read().split(b')')[-1].split())
-
-            vmem = GaugeMetricFamily(self._prefix + 'virtual_memory_bytes',
-                                     'Virtual memory size in bytes.', value=float(parts[20]))
-            rss = GaugeMetricFamily(self._prefix + 'resident_memory_bytes', 'Resident memory size in bytes.',
-                                    value=float(parts[21]) * self._pagesize)
-            start_time_secs = float(parts[19]) / self._ticks
-            start_time = GaugeMetricFamily(self._prefix + 'start_time_seconds',
-                                           'Start time of the process since unix epoch in seconds.',
-                                           value=start_time_secs + self._btime)
-            utime = float(parts[11]) / self._ticks
-            stime = float(parts[12]) / self._ticks
-            cpu = CounterMetricFamily(self._prefix + 'cpu_seconds_total',
-                                      'Total user and system CPU time spent in seconds.',
-                                      value=utime + stime)
-            result.extend([vmem, rss, start_time, cpu])
-        except OSError:
-            pass
-
-        try:
-            with open(os.path.join(pid, 'limits'), 'rb') as limits:
-                for line in limits:
-                    if line.startswith(b'Max open file'):
-                        max_fds = GaugeMetricFamily(self._prefix + 'max_fds',
-                                                    'Maximum number of open file descriptors.',
-                                                    value=float(line.split()[3]))
-                        break
-            open_fds = GaugeMetricFamily(self._prefix + 'open_fds',
-                                         'Number of open file descriptors.',
-                                         len(os.listdir(os.path.join(pid, 'fd'))))
-            result.extend([open_fds, max_fds])
-        except OSError:
-            pass
-
-        return result
-
-
-PROCESS_COLLECTOR = ProcessCollector()
-"""Default ProcessCollector in default Registry REGISTRY."""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py
deleted file mode 100644
index 63f8ab03abe..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/registry.py
+++ /dev/null
@@ -1,178 +0,0 @@
-import copy
-from threading import Lock
-from typing import Dict, Iterable, List, Optional, Protocol, Set
-
-from .metrics_core import Metric
-
-
-class Collector(Protocol):
-    def collect(self) -> Iterable[Metric]:
-        """Collect metrics."""
-
-
-class _EmptyCollector:
-    def collect(self) -> Iterable[Metric]:
-        return []
-
-
-class DuplicateTimeseries(ValueError):
-    def __init__(self, duplicates: Set[str]):
-        msg = 'Duplicated timeseries in CollectorRegistry: {}'.format(
-            duplicates)
-        super().__init__(msg)
-        self.duplicates: Set[str] = duplicates
-
-
-class CollectorRegistry:
-    """Metric collector registry.
-
-    Collectors must have a no-argument method 'collect' that returns a list of
-    Metric objects. The returned metrics should be consistent with the Prometheus
-    exposition formats.
-    """
-
-    def __init__(self, auto_describe: bool = False, target_info: Optional[Dict[str, str]] = None,
-                 support_collectors_without_names: bool = False):
-        self._collector_to_names: Dict[Collector, List[str]] = {}
-        self._names_to_collectors: Dict[str, Collector] = {}
-        self._auto_describe = auto_describe
-        self._lock = Lock()
-        self._target_info: Optional[Dict[str, str]] = {}
-        self._support_collectors_without_names = support_collectors_without_names
-        self._collectors_without_names: List[Collector] = []
-        self.set_target_info(target_info)
-
-    def register(self, collector: Collector) -> None:
-        """Add a collector to the registry."""
-        with self._lock:
-            names = self._get_names(collector)
-            duplicates = set(self._names_to_collectors).intersection(names)
-            if duplicates:
-                raise DuplicateTimeseries(duplicates)
-            for name in names:
-                self._names_to_collectors[name] = collector
-            self._collector_to_names[collector] = names
-            if self._support_collectors_without_names and not names:
-                self._collectors_without_names.append(collector)
-
-    def unregister(self, collector: Collector) -> None:
-        """Remove a collector from the registry."""
-        with self._lock:
-            for name in self._collector_to_names[collector]:
-                del self._names_to_collectors[name]
-            del self._collector_to_names[collector]
-            if collector in self._collectors_without_names:
-                self._collectors_without_names.remove(collector)
-
-    def _get_names(self, collector):
-        """Get names of timeseries the collector produces and clashes with."""
-        desc_func = None
-        # If there's a describe function, use it.
-        try:
-            desc_func = collector.describe
-        except AttributeError:
-            pass
-        # Otherwise, if auto describe is enabled use the collect function.
-        if not desc_func and self._auto_describe:
-            desc_func = collector.collect
-
-        if not desc_func:
-            return []
-
-        result = []
-        type_suffixes = {
-            'counter': ['_total', '_created'],
-            'summary': ['_sum', '_count', '_created'],
-            'histogram': ['_bucket', '_sum', '_count', '_created'],
-            'gaugehistogram': ['_bucket', '_gsum', '_gcount'],
-            'info': ['_info'],
-        }
-        for metric in desc_func():
-            result.append(metric.name)
-            for suffix in type_suffixes.get(metric.type, []):
-                result.append(metric.name + suffix)
-        return result
-
-    def collect(self) -> Iterable[Metric]:
-        """Yields metrics from the collectors in the registry."""
-        collectors = None
-        ti = None
-        with self._lock:
-            collectors = copy.copy(self._collector_to_names)
-            if self._target_info:
-                ti = self._target_info_metric()
-        if ti:
-            yield ti
-        for collector in collectors:
-            yield from collector.collect()
-
-    def restricted_registry(self, names: Iterable[str]) -> "RestrictedRegistry":
-        """Returns object that only collects some metrics.
-
-        Returns an object which upon collect() will return
-        only samples with the given names.
-
-        Intended usage is:
-            generate_latest(REGISTRY.restricted_registry(['a_timeseries']), escaping)
-
-        Experimental."""
-        names = set(names)
-        return RestrictedRegistry(names, self)
-
-    def set_target_info(self, labels: Optional[Dict[str, str]]) -> None:
-        with self._lock:
-            if labels:
-                if not self._target_info and 'target_info' in self._names_to_collectors:
-                    raise ValueError('CollectorRegistry already contains a target_info metric')
-                self._names_to_collectors['target_info'] = _EmptyCollector()
-            elif self._target_info:
-                self._names_to_collectors.pop('target_info', None)
-            self._target_info = labels
-
-    def get_target_info(self) -> Optional[Dict[str, str]]:
-        with self._lock:
-            return self._target_info
-
-    def _target_info_metric(self):
-        m = Metric('target', 'Target metadata', 'info')
-        m.add_sample('target_info', self._target_info, 1)
-        return m
-
-    def get_sample_value(self, name: str, labels: Optional[Dict[str, str]] = None) -> Optional[float]:
-        """Returns the sample value, or None if not found.
-
-        This is inefficient, and intended only for use in unittests.
-        """
-        if labels is None:
-            labels = {}
-        for metric in self.collect():
-            for s in metric.samples:
-                if s.name == name and s.labels == labels:
-                    return s.value
-        return None
-
-
-class RestrictedRegistry:
-    def __init__(self, names: Iterable[str], registry: CollectorRegistry):
-        self._name_set = set(names)
-        self._registry = registry
-
-    def collect(self) -> Iterable[Metric]:
-        collectors = set(self._registry._collectors_without_names)
-        target_info_metric = None
-        with self._registry._lock:
-            if 'target_info' in self._name_set and self._registry._target_info:
-                target_info_metric = self._registry._target_info_metric()
-            for name in self._name_set:
-                if name != 'target_info' and name in self._registry._names_to_collectors:
-                    collectors.add(self._registry._names_to_collectors[name])
-        if target_info_metric:
-            yield target_info_metric
-        for collector in collectors:
-            for metric in collector.collect():
-                m = metric._restricted_metric(self._name_set)
-                if m:
-                    yield m
-
-
-REGISTRY = CollectorRegistry(auto_describe=True)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py
deleted file mode 100644
index 994d12817ac..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/samples.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from typing import Dict, NamedTuple, Optional, Sequence, Union
-
-
-class Timestamp:
-    """A nanosecond-resolution timestamp."""
-
-    def __init__(self, sec: float, nsec: float) -> None:
-        if nsec < 0 or nsec >= 1e9:
-            raise ValueError(f"Invalid value for nanoseconds in Timestamp: {nsec}")
-        if sec < 0:
-            nsec = -nsec
-        self.sec: int = int(sec)
-        self.nsec: int = int(nsec)
-
-    def __str__(self) -> str:
-        return f"{self.sec}.{self.nsec:09d}"
-
-    def __repr__(self) -> str:
-        return f"Timestamp({self.sec}, {self.nsec})"
-
-    def __float__(self) -> float:
-        return float(self.sec) + float(self.nsec) / 1e9
-
-    def __eq__(self, other: object) -> bool:
-        return isinstance(other, Timestamp) and self.sec == other.sec and self.nsec == other.nsec
-
-    def __ne__(self, other: object) -> bool:
-        return not self == other
-
-    def __gt__(self, other: "Timestamp") -> bool:
-        return self.nsec > other.nsec if self.sec == other.sec else self.sec > other.sec
-
-    def __lt__(self, other: "Timestamp") -> bool:
-        return self.nsec < other.nsec if self.sec == other.sec else self.sec < other.sec
-
-
-# BucketSpan is experimental and subject to change at any time.
-class BucketSpan(NamedTuple):
-    offset: int
-    length: int
-
-
-# Timestamp and exemplar are optional.
-# Value can be an int or a float.
-# Timestamp can be a float containing a unixtime in seconds,
-# a Timestamp object, or None.
-# Exemplar can be an Exemplar object, or None.
-class Exemplar(NamedTuple):
-    labels: Dict[str, str]
-    value: float
-    timestamp: Optional[Union[float, Timestamp]] = None
-
-
-# NativeHistogram is experimental and subject to change at any time.
-class NativeHistogram(NamedTuple):
-    count_value: float
-    sum_value: float
-    schema: int
-    zero_threshold: float
-    zero_count: float
-    pos_spans: Optional[Sequence[BucketSpan]] = None
-    neg_spans: Optional[Sequence[BucketSpan]] = None
-    pos_deltas: Optional[Sequence[int]] = None
-    neg_deltas: Optional[Sequence[int]] = None
-    nh_exemplars: Optional[Sequence[Exemplar]] = None
-
-
-class Sample(NamedTuple):
-    name: str
-    labels: Dict[str, str]
-    value: float
-    timestamp: Optional[Union[float, Timestamp]] = None
-    exemplar: Optional[Exemplar] = None
-    native_histogram: Optional[NativeHistogram] = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py
deleted file mode 100644
index 52c852ab813..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/utils.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import math
-from typing import Union
-
-INF = float("inf")
-MINUS_INF = float("-inf")
-NaN = float("NaN")
-
-
-def floatToGoString(d):
-    d = float(d)
-    if d == INF:
-        return '+Inf'
-    elif d == MINUS_INF:
-        return '-Inf'
-    elif math.isnan(d):
-        return 'NaN'
-    else:
-        s = repr(d)
-        dot = s.find('.')
-        # Go switches to exponents sooner than Python.
-        # We only need to care about positive values for le/quantile.
-        if d > 0 and dot > 6:
-            mantissa = f'{s[0]}.{s[1:dot]}{s[dot + 1:]}'.rstrip('0.')
-            return f'{mantissa}e+{dot - 1:02d}'
-        return s
-
-
-def parse_version(version_str: str) -> tuple[Union[int, str], ...]:
-    version: list[Union[int, str]] = []
-    for part in version_str.split('.'):
-        try:
-            version.append(int(part))
-        except ValueError:
-            version.append(part)
-
-    return tuple(version)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py
deleted file mode 100644
index 6fcc80183a2..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/validation.py
+++ /dev/null
@@ -1,124 +0,0 @@
-import os
-import re
-
-METRIC_NAME_RE = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$')
-METRIC_LABEL_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
-RESERVED_METRIC_LABEL_NAME_RE = re.compile(r'^__.*$')
-
-
-def _init_legacy_validation() -> bool:
-    """Retrieve name validation setting from environment."""
-    return os.environ.get("PROMETHEUS_LEGACY_NAME_VALIDATION", 'False').lower() in ('true', '1', 't')
-
-
-_legacy_validation = _init_legacy_validation()
-
-
-def get_legacy_validation() -> bool:
-    """Return the current status of the legacy validation setting."""
-    return _legacy_validation
-
-
-def disable_legacy_validation():
-    """Disable legacy name validation, instead allowing all UTF8 characters."""
-    global _legacy_validation
-    _legacy_validation = False
-
-
-def enable_legacy_validation():
-    """Enable legacy name validation instead of allowing all UTF8 characters."""
-    global _legacy_validation
-    _legacy_validation = True
-
-
-def _validate_metric_name(name: str) -> None:
-    """Raises ValueError if the provided name is not a valid metric name.
-    
-    This check uses the global legacy validation setting to determine the validation scheme.
-    """
-    if not name:
-        raise ValueError("metric name cannot be empty")
-    if _legacy_validation:
-        if not METRIC_NAME_RE.match(name):
-            raise ValueError("invalid metric name " + name)
-    try:
-        name.encode('utf-8')
-    except UnicodeDecodeError:
-        raise ValueError("invalid metric name " + name)
-
-
-def _is_valid_legacy_metric_name(name: str) -> bool:
-    """Returns true if the provided metric name conforms to the legacy validation scheme."""
-    if len(name) == 0:
-        return False
-    return METRIC_NAME_RE.match(name) is not None
-
-
-def _validate_metric_label_name_token(tok: str) -> None:
-    """Raises ValueError if a parsed label name token is invalid. 
-    
-    UTF-8 names must be quoted.
-    """
-    if not tok:
-        raise ValueError("invalid label name token " + tok)
-    quoted = tok[0] == '"' and tok[-1] == '"'
-    if not quoted or _legacy_validation:
-        if not METRIC_LABEL_NAME_RE.match(tok):
-            raise ValueError("invalid label name token " + tok)
-        return
-    try:
-        tok.encode('utf-8')
-    except UnicodeDecodeError:
-        raise ValueError("invalid label name token " + tok)
-
-
-def _validate_labelname(l):
-    """Raises ValueError if the provided name is not a valid label name.
-    
-    This check uses the global legacy validation setting to determine the validation scheme.
-    """
-    if get_legacy_validation():
-        if not METRIC_LABEL_NAME_RE.match(l):
-            raise ValueError('Invalid label metric name: ' + l)
-        if RESERVED_METRIC_LABEL_NAME_RE.match(l):
-            raise ValueError('Reserved label metric name: ' + l)
-    else:
-        try:
-            l.encode('utf-8')
-        except UnicodeDecodeError:
-            raise ValueError('Invalid label metric name: ' + l)
-        if RESERVED_METRIC_LABEL_NAME_RE.match(l):
-            raise ValueError('Reserved label metric name: ' + l)
-        
-
-def _is_valid_legacy_labelname(l: str) -> bool:
-    """Returns true if the provided label name conforms to the legacy validation scheme."""
-    if len(l) == 0:
-        return False
-    if METRIC_LABEL_NAME_RE.match(l) is None:
-        return False
-    return RESERVED_METRIC_LABEL_NAME_RE.match(l) is None
-
-
-def _validate_labelnames(cls, labelnames):
-    """Raises ValueError if any of the provided names is not a valid label name.
-    
-    This check uses the global legacy validation setting to determine the validation scheme.
-    """
-    labelnames = tuple(labelnames)
-    for l in labelnames:
-        _validate_labelname(l)
-        if l in cls._reserved_labelnames:
-            raise ValueError('Reserved label methe fric name: ' + l)
-    return labelnames
-
-
-def _validate_exemplar(exemplar):
-    """Raises ValueError if the exemplar is invalid."""
-    runes = 0
-    for k, v in exemplar.items():
-        _validate_labelname(k)
-        runes += len(k)
-        runes += len(v)
-    if runes > 128:
-        raise ValueError('Exemplar labels have %d UTF-8 characters, exceeding the limit of 128')
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py
deleted file mode 100644
index 16c745ed65a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/prometheus_client/values.py
+++ /dev/null
@@ -1,163 +0,0 @@
-import os
-from threading import Lock
-from typing import Callable, List
-import warnings
-
-from .mmap_dict import mmap_key, MmapedDict
-
-_multi_process_cleanups: List[Callable[[], None]] = []
-
-
-def close_all_multiprocess_files():
-    for cleanup in _multi_process_cleanups:
-        cleanup()
-    _multi_process_cleanups.clear()
-
-
-class MutexValue:
-    """A float protected by a mutex."""
-
-    _multiprocess = False
-
-    def __init__(self, typ, metric_name, name, labelnames, labelvalues, help_text, **kwargs):
-        self._value = 0.0
-        self._exemplar = None
-        self._lock = Lock()
-
-    def inc(self, amount):
-        with self._lock:
-            self._value += amount
-
-    def set(self, value, timestamp=None):
-        with self._lock:
-            self._value = value
-
-    def set_exemplar(self, exemplar):
-        with self._lock:
-            self._exemplar = exemplar
-
-    def get(self):
-        with self._lock:
-            return self._value
-
-    def get_exemplar(self):
-        with self._lock:
-            return self._exemplar
-
-
-def MultiProcessValue(process_identifier=os.getpid):
-    """Returns a MmapedValue class based on a process_identifier function.
-
-    The 'process_identifier' function MUST comply with this simple rule:
-    when called in simultaneously running processes it MUST return distinct values.
-
-    Using a different function than the default 'os.getpid' is at your own risk.
-    """
-    files = {}
-    values = []
-    pid = {'value': process_identifier()}
-    # Use a single global lock when in multi-processing mode
-    # as we presume this means there is no threading going on.
-    # This avoids the need to also have mutexes in __MmapDict.
-    lock = Lock()
-
-    def cleanup():
-        for f in files.values():
-            f.close()
-        files.clear()
-        values.clear()
-    _multi_process_cleanups.append(cleanup)
-
-    class MmapedValue:
-        """A float protected by a mutex backed by a per-process mmaped file."""
-
-        _multiprocess = True
-
-        def __init__(self, typ, metric_name, name, labelnames, labelvalues, help_text, multiprocess_mode='', **kwargs):
-            self._params = typ, metric_name, name, labelnames, labelvalues, help_text, multiprocess_mode
-            # This deprecation warning can go away in a few releases when removing the compatibility
-            if 'prometheus_multiproc_dir' in os.environ and 'PROMETHEUS_MULTIPROC_DIR' not in os.environ:
-                os.environ['PROMETHEUS_MULTIPROC_DIR'] = os.environ['prometheus_multiproc_dir']
-                warnings.warn("prometheus_multiproc_dir variable has been deprecated in favor of the upper case naming PROMETHEUS_MULTIPROC_DIR", DeprecationWarning)
-            with lock:
-                self.__check_for_pid_change()
-                self.__reset()
-                values.append(self)
-
-        def __reset(self):
-            typ, metric_name, name, labelnames, labelvalues, help_text, multiprocess_mode = self._params
-            if typ == 'gauge':
-                file_prefix = typ + '_' + multiprocess_mode
-            else:
-                file_prefix = typ
-            if file_prefix not in files:
-                filename = os.path.join(
-                    os.environ.get('PROMETHEUS_MULTIPROC_DIR'),
-                    '{}_{}.db'.format(file_prefix, pid['value']))
-
-                files[file_prefix] = MmapedDict(filename)
-            self._file = files[file_prefix]
-            self._key = mmap_key(metric_name, name, labelnames, labelvalues, help_text)
-            self._value, self._timestamp = self._file.read_value(self._key)
-
-        def __check_for_pid_change(self):
-            actual_pid = process_identifier()
-            if pid['value'] != actual_pid:
-                pid['value'] = actual_pid
-                # There has been a fork(), reset all the values.
-                for f in files.values():
-                    f.close()
-                files.clear()
-                for value in values:
-                    value.__reset()
-
-        def inc(self, amount):
-            with lock:
-                self.__check_for_pid_change()
-                self._value += amount
-                self._timestamp = 0.0
-                self._file.write_value(self._key, self._value, self._timestamp)
-
-        def set(self, value, timestamp=None):
-            with lock:
-                self.__check_for_pid_change()
-                self._value = value
-                self._timestamp = timestamp or 0.0
-                self._file.write_value(self._key, self._value, self._timestamp)
-
-        def set_exemplar(self, exemplar):
-            # TODO: Implement exemplars for multiprocess mode.
-            return
-
-        def get(self):
-            with lock:
-                self.__check_for_pid_change()
-                return self._value
-
-        def get_exemplar(self):
-            # TODO: Implement exemplars for multiprocess mode.
-            return None
-
-        @classmethod
-        def close_all_files(cls):
-            with lock:
-                for f in files.values():
-                    f.close()
-                files.clear()
-                values.clear()
-
-    return MmapedValue
-
-
-def get_value_class():
-    # Should we enable multi-process mode?
-    # This needs to be chosen before the first metric is constructed,
-    # and as that may be in some arbitrary library the user/admin has
-    # no control over we use an environment variable.
-    if 'prometheus_multiproc_dir' in os.environ or 'PROMETHEUS_MULTIPROC_DIR' in os.environ:
-        return MultiProcessValue()
-    else:
-        return MutexValue
-
-
-ValueClass = get_value_class()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE
deleted file mode 100644
index 19b305b0006..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/protobuf.LICENSE
+++ /dev/null
@@ -1,32 +0,0 @@
-Copyright 2008 Google Inc.  All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Code generated by the Protocol Buffer compiler is owned by the owner
-of the input file used when generating it.  This code is not
-standalone and requires a support library to be linked with it.  This
-support library is itself covered by the above license.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE
deleted file mode 100644
index 67db8588217..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.LICENSE
+++ /dev/null
@@ -1,175 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE
deleted file mode 100644
index 1ff62db6882..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests.NOTICE
+++ /dev/null
@@ -1,2 +0,0 @@
-Requests
-Copyright 2019 Kenneth Reitz
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py
deleted file mode 100644
index 84d8c88a6a0..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__init__.py
+++ /dev/null
@@ -1,217 +0,0 @@
-#   __
-#  /__)  _  _     _   _ _/   _
-# / (   (- (/ (/ (- _)  /  _)
-#          /
-
-"""
-Requests HTTP Library
-~~~~~~~~~~~~~~~~~~~~~
-
-Requests is an HTTP library, written in Python, for human beings.
-Basic GET usage:
-
-   >>> import requests
-   >>> r = requests.get('https://www.python.org')
-   >>> r.status_code
-   200
-   >>> b'Python is a programming language' in r.content
-   True
-
-... or POST:
-
-   >>> payload = dict(key1='value1', key2='value2')
-   >>> r = requests.post('https://httpbin.org/post', data=payload)
-   >>> print(r.text)
-   {
-     ...
-     "form": {
-       "key1": "value1",
-       "key2": "value2"
-     },
-     ...
-   }
-
-The other HTTP methods are supported - see `requests.api`. Full documentation
-is at .
-
-:copyright: (c) 2017 by Kenneth Reitz.
-:license: Apache 2.0, see LICENSE for more details.
-"""
-
-from __future__ import annotations
-
-import warnings
-
-from opentelemetry.agent._vendor import urllib3
-
-from .exceptions import RequestsDependencyWarning
-
-try:
-    from opentelemetry.agent._vendor.charset_normalizer import __version__ as charset_normalizer_version
-except ImportError:
-    charset_normalizer_version = None
-
-# Only the vendored charset_normalizer is used, never the application's chardet.
-chardet_version = None
-
-
-def check_compatibility(
-    urllib3_version: str,
-    chardet_version: str | None,
-    charset_normalizer_version: str | None,
-) -> None:
-    urllib3_version_list = urllib3_version.split(".")[:3]
-    assert urllib3_version_list != ["dev"]  # Verify urllib3 isn't installed from git.
-
-    # Sometimes, urllib3 only reports its version as 16.1.
-    if len(urllib3_version_list) == 2:
-        urllib3_version_list.append("0")
-
-    # Check urllib3 for compatibility.
-    major, minor, patch = urllib3_version_list  # noqa: F811
-    major, minor, patch = int(major), int(minor), int(patch)
-    # urllib3 >= 1.21.1
-    assert major >= 1
-    if major == 1:
-        assert minor >= 21
-
-    # Check charset_normalizer for compatibility.
-    if chardet_version:
-        major, minor, patch = chardet_version.split(".")[:3]
-        major, minor, patch = int(major), int(minor), int(patch)
-        # chardet_version >= 3.0.2, < 8.0.0
-        assert (3, 0, 2) <= (major, minor, patch) < (8, 0, 0)
-    elif charset_normalizer_version:
-        major, minor, patch = charset_normalizer_version.split(".")[:3]
-        major, minor, patch = int(major), int(minor), int(patch)
-        # charset_normalizer >= 2.0.0 < 4.0.0
-        assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0)
-    else:
-        warnings.warn(
-            "Unable to find acceptable character detection dependency "
-            "(chardet or charset_normalizer).",
-            RequestsDependencyWarning,
-        )
-
-
-def _check_cryptography(cryptography_version: str) -> None:
-    # cryptography < 1.3.4
-    try:
-        cryptography_version_list = list(map(int, cryptography_version.split(".")))
-    except ValueError:
-        return
-
-    if cryptography_version_list < [1, 3, 4]:
-        warning = f"Old version of cryptography ({cryptography_version_list}) may cause slowdown."
-        warnings.warn(warning, RequestsDependencyWarning)
-
-
-# Check imported dependencies for compatibility.
-try:
-    check_compatibility(
-        urllib3.__version__,  # type: ignore[reportPrivateImportUsage]
-        chardet_version,  # type: ignore[reportUnknownArgumentType]
-        charset_normalizer_version,
-    )
-except (AssertionError, ValueError):
-    warnings.warn(
-        f"urllib3 ({urllib3.__version__}) or chardet "  # type: ignore[reportPrivateImportUsage]
-        f"({chardet_version})/charset_normalizer ({charset_normalizer_version}) "
-        "doesn't match a supported version!",
-        RequestsDependencyWarning,
-    )
-
-# Attempt to enable urllib3's fallback for SNI support
-# if the standard library doesn't support SNI or the
-# 'ssl' library isn't available.
-try:
-    try:
-        import ssl
-    except ImportError:
-        ssl = None
-
-    if not getattr(ssl, "HAS_SNI", False):
-        from opentelemetry.agent._vendor.urllib3.contrib import pyopenssl
-
-        pyopenssl.inject_into_urllib3()
-
-        # Check cryptography version
-        from cryptography import (  # type: ignore[reportMissingImports]
-            __version__ as cryptography_version,  # type: ignore[reportUnknownVariableType]
-        )
-
-        _check_cryptography(cryptography_version)  # type: ignore[reportUnknownArgumentType]
-except ImportError:
-    pass
-
-# urllib3's DependencyWarnings should be silenced.
-from opentelemetry.agent._vendor.urllib3.exceptions import DependencyWarning
-
-warnings.simplefilter("ignore", DependencyWarning)
-
-# Set default logging handler to avoid "No handler found" warnings.
-import logging
-from logging import NullHandler
-
-from . import packages, utils
-from .__version__ import (
-    __author__,
-    __author_email__,
-    __build__,
-    __cake__,
-    __copyright__,
-    __description__,
-    __license__,
-    __title__,
-    __url__,
-    __version__,
-)
-from .api import delete, get, head, options, patch, post, put, request
-from .exceptions import (
-    ConnectionError,
-    ConnectTimeout,
-    FileModeWarning,
-    HTTPError,
-    JSONDecodeError,
-    ReadTimeout,
-    RequestException,
-    Timeout,
-    TooManyRedirects,
-    URLRequired,
-)
-from .models import PreparedRequest, Request, Response
-from .sessions import Session, session
-from .status_codes import codes
-
-__all__ = (
-    "ConnectionError",
-    "ConnectTimeout",
-    "HTTPError",
-    "JSONDecodeError",
-    "PreparedRequest",
-    "ReadTimeout",
-    "Request",
-    "RequestException",
-    "Response",
-    "Session",
-    "Timeout",
-    "TooManyRedirects",
-    "URLRequired",
-    "codes",
-    "delete",
-    "get",
-    "head",
-    "options",
-    "packages",
-    "patch",
-    "post",
-    "put",
-    "request",
-    "session",
-    "utils",
-)
-
-logging.getLogger(__name__).addHandler(NullHandler())
-
-# FileModeWarnings go off per the default.
-warnings.simplefilter("default", FileModeWarning, append=True)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py
deleted file mode 100644
index fea814e5827..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/__version__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# .-. .-. .-. . . .-. .-. .-. .-.
-# |(  |-  |.| | | |-  `-.  |  `-.
-# ' ' `-' `-`.`-' `-' `-'  '  `-'
-
-__title__ = "requests"
-__description__ = "Python HTTP for Humans."
-__url__ = "https://requests.readthedocs.io"
-__version__ = "2.34.2"
-__build__ = 0x023402
-__author__ = "Kenneth Reitz"
-__author_email__ = "me@kennethreitz.org"
-__license__ = "Apache-2.0"
-__copyright__ = "Copyright Kenneth Reitz"
-__cake__ = "\u2728 \U0001f370 \u2728"
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py
deleted file mode 100644
index 0466a7d347d..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_internal_utils.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""
-requests._internal_utils
-~~~~~~~~~~~~~~
-
-Provides utility functions that are consumed internally by Requests
-which depend on extremely few external helpers (such as compat)
-"""
-
-import re
-
-from .compat import builtin_str
-
-_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*\Z")
-_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*\Z")
-_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*\Z|^\Z")
-_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*\Z|^\Z")
-
-_HEADER_VALIDATORS_STR = (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR)
-_HEADER_VALIDATORS_BYTE = (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE)
-HEADER_VALIDATORS = {
-    bytes: _HEADER_VALIDATORS_BYTE,
-    str: _HEADER_VALIDATORS_STR,
-}
-
-
-def to_native_string(string: str | bytes, encoding: str = "ascii") -> str:
-    """Given a string object, regardless of type, returns a representation of
-    that string in the native string type, encoding and decoding where
-    necessary. This assumes ASCII unless told otherwise.
-    """
-    if isinstance(string, builtin_str):
-        out = string
-    else:
-        out = string.decode(encoding)
-
-    return out
-
-
-def unicode_is_ascii(u_string: str) -> bool:
-    """Determine if unicode string only contains ASCII characters.
-
-    :param str u_string: unicode string to check. Must be unicode
-        and not Python 2 `str`.
-    :rtype: bool
-    """
-    assert isinstance(u_string, str)
-    try:
-        u_string.encode("ascii")
-        return True
-    except UnicodeEncodeError:
-        return False
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py
deleted file mode 100644
index 48ddfaafcf3..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/_types.py
+++ /dev/null
@@ -1,183 +0,0 @@
-"""
-requests._types
-~~~~~~~~~~~~~~~
-
-This module contains type aliases used internally by the Requests library.
-These types are not part of the public API and must not be relied upon
-by external code.
-"""
-
-from __future__ import annotations
-
-from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence
-from typing import (
-    TYPE_CHECKING,
-    Any,
-    Protocol,
-    TypeAlias,
-    TypeVar,
-    runtime_checkable,
-)
-
-_T_co = TypeVar("_T_co", covariant=True)
-_KT_co = TypeVar("_KT_co", covariant=True)
-_VT_co = TypeVar("_VT_co", covariant=True)
-
-
-@runtime_checkable
-class SupportsRead(Protocol[_T_co]):
-    def read(self, length: int = ..., /) -> _T_co: ...
-
-
-@runtime_checkable
-class SupportsItems(Protocol[_KT_co, _VT_co]):
-    def items(self) -> Iterable[tuple[_KT_co, _VT_co]]: ...
-
-
-# These are needed at runtime for default_hooks() return type
-HookType: TypeAlias = Callable[["Response"], Any]
-HooksInputType: TypeAlias = Mapping[str, Iterable[HookType] | HookType]
-
-
-def is_prepared(request: PreparedRequest) -> TypeIs[_ValidatedRequest]:
-    """Verify a PreparedRequest has been fully prepared."""
-    if TYPE_CHECKING:
-        return request.url is not None and request.method is not None
-    # noop at runtime to avoid AssertionError
-    return True
-
-
-if TYPE_CHECKING:
-    from http.cookiejar import CookieJar
-    from typing import TypeAlias, TypedDict
-
-    from opentelemetry.agent._vendor.typing_extensions import (
-        Buffer,  # TODO: move to collections.abc when Python >= 3.12
-        TypeIs,  # TODO: move to typing when Python >= 3.13
-    )
-
-    from .auth import AuthBase
-    from .cookies import RequestsCookieJar
-    from .models import PreparedRequest, Response
-    from .structures import CaseInsensitiveDict
-
-    class _ValidatedRequest(PreparedRequest):
-        """Subtype asserting a PreparedRequest has been fully prepared before calling.
-
-        The override suppression is required because mutable attribute types are
-        invariant (Liskov), but we only narrow after preparation is complete. This
-        is the explicit contract for Requests but Python's typing doesn't have a
-        better way to represent the requirement.
-        """
-
-        url: str  # type: ignore[reportIncompatibleVariableOverride]
-        method: str  # type: ignore[reportIncompatibleVariableOverride]
-
-    # Type aliases for core API concepts (ordered by request() signature)
-    UriType: TypeAlias = str | bytes
-
-    _ParamsMappingKeyType: TypeAlias = str | bytes | int | float
-    _ParamsMappingValueType: TypeAlias = (
-        str | bytes | int | float | Iterable[str | bytes | int | float] | None
-    )
-    ParamsType: TypeAlias = (
-        SupportsItems[_ParamsMappingKeyType, _ParamsMappingValueType]
-        | tuple[tuple[_ParamsMappingKeyType, _ParamsMappingValueType], ...]
-        | Iterable[tuple[_ParamsMappingKeyType, _ParamsMappingValueType]]
-        | str
-        | bytes
-        | None
-    )
-
-    KVDataType: TypeAlias = Iterable[tuple[Any, Any]] | SupportsItems[Any, Any]
-
-    RawDataType: TypeAlias = KVDataType | str | bytes
-    StreamDataType: TypeAlias = SupportsRead[str | bytes]
-    EncodableDataType: TypeAlias = RawDataType | StreamDataType
-
-    DataType: TypeAlias = (
-        KVDataType
-        | Iterable[bytes | str]
-        | str
-        | bytes
-        | Buffer
-        | SupportsRead[str | bytes]
-        | None
-    )
-
-    BodyType: TypeAlias = (
-        bytes | str | Iterable[bytes | str] | SupportsRead[bytes | str] | None
-    )
-
-    HeadersType: TypeAlias = Mapping[str, str | bytes] | None
-
-    CookiesType: TypeAlias = RequestsCookieJar | Mapping[str, str]
-
-    # Building blocks for FilesType
-    _FileName: TypeAlias = str | None
-    _FileContent: TypeAlias = SupportsRead[str | bytes] | str | bytes
-    _FileSpecBasic: TypeAlias = tuple[_FileName, _FileContent]
-    _FileSpecWithContentType: TypeAlias = tuple[_FileName, _FileContent, str]
-    _FileSpecWithHeaders: TypeAlias = tuple[
-        _FileName, _FileContent, str, CaseInsensitiveDict[str] | Mapping[str, str]
-    ]
-    _FileSpec: TypeAlias = (
-        _FileContent | _FileSpecBasic | _FileSpecWithContentType | _FileSpecWithHeaders
-    )
-    FilesType: TypeAlias = (
-        Mapping[str, _FileSpec] | Iterable[tuple[str, _FileSpec]] | None
-    )
-
-    AuthType: TypeAlias = (
-        tuple[str, str] | AuthBase | Callable[[PreparedRequest], PreparedRequest] | None
-    )
-
-    TimeoutType: TypeAlias = float | tuple[float | None, float | None] | None
-    ProxiesType: TypeAlias = MutableMapping[str, str]
-    HooksType: TypeAlias = dict[str, list[HookType]] | None
-    VerifyType: TypeAlias = bool | str
-    CertType: TypeAlias = str | tuple[str, str] | None
-    JsonType: TypeAlias = (
-        None
-        | bool
-        | int
-        | float
-        | str
-        | Sequence["JsonType"]
-        | Mapping[str, "JsonType"]
-    )
-
-    # TypedDicts for Unpack kwargs (PEP 692)
-
-    class BaseRequestKwargs(TypedDict, total=False):
-        headers: HeadersType
-        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
-        files: FilesType
-        auth: AuthType
-        timeout: TimeoutType
-        allow_redirects: bool
-        proxies: dict[str, str] | None
-        hooks: HooksInputType | None
-        stream: bool | None
-        verify: VerifyType | None
-        cert: CertType
-
-    class RequestKwargs(BaseRequestKwargs, total=False):
-        """kwargs for request(), options(), head(), delete()."""
-
-        params: ParamsType
-        data: DataType
-        json: JsonType
-
-    class GetKwargs(BaseRequestKwargs, total=False):
-        data: DataType
-        json: JsonType
-
-    class PostKwargs(BaseRequestKwargs, total=False):
-        params: ParamsType
-
-    class DataKwargs(BaseRequestKwargs, total=False):
-        """kwargs for put(), patch()."""
-
-        params: ParamsType
-        json: JsonType
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py
deleted file mode 100644
index 03bf43137e7..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/adapters.py
+++ /dev/null
@@ -1,748 +0,0 @@
-"""
-requests.adapters
-~~~~~~~~~~~~~~~~~
-
-This module contains the transport adapters that Requests uses to define
-and maintain connections.
-"""
-
-from __future__ import annotations
-
-import os.path
-import socket  # noqa: F401  # type: ignore[reportUnusedImport]
-import typing
-import warnings
-from typing import Any
-
-from opentelemetry.agent._vendor.urllib3.exceptions import (
-    ClosedPoolError,
-    ConnectTimeoutError,
-    LocationValueError,
-    MaxRetryError,
-    NewConnectionError,
-    ProtocolError,
-    ReadTimeoutError,
-    ResponseError,
-)
-from opentelemetry.agent._vendor.urllib3.exceptions import HTTPError as _HTTPError
-from opentelemetry.agent._vendor.urllib3.exceptions import InvalidHeader as _InvalidHeader
-from opentelemetry.agent._vendor.urllib3.exceptions import ProxyError as _ProxyError
-from opentelemetry.agent._vendor.urllib3.exceptions import SSLError as _SSLError
-from opentelemetry.agent._vendor.urllib3.poolmanager import PoolManager, proxy_from_url
-from opentelemetry.agent._vendor.urllib3.util import Timeout as TimeoutSauce
-from opentelemetry.agent._vendor.urllib3.util import parse_url
-from opentelemetry.agent._vendor.urllib3.util.retry import Retry
-
-from .auth import _basic_auth_str  # type: ignore[reportPrivateUsage]
-from .compat import basestring, urlparse
-from .cookies import extract_cookies_to_jar
-from .exceptions import (
-    ConnectionError,
-    ConnectTimeout,
-    InvalidHeader,
-    InvalidProxyURL,
-    InvalidSchema,
-    InvalidURL,
-    ProxyError,
-    ReadTimeout,
-    RetryError,
-    SSLError,
-)
-from .models import Response
-from .structures import CaseInsensitiveDict
-from .utils import (
-    DEFAULT_CA_BUNDLE_PATH,
-    get_auth_from_url,
-    get_encoding_from_headers,
-    prepend_scheme_if_needed,
-    select_proxy,
-    urldefragauth,
-)
-
-try:
-    from opentelemetry.agent._vendor.urllib3.contrib.socks import SOCKSProxyManager  # type: ignore[assignment]
-except ImportError:
-
-    def SOCKSProxyManager(*args: Any, **kwargs: Any) -> None:
-        raise InvalidSchema("Missing dependencies for SOCKS support.")
-
-
-if typing.TYPE_CHECKING:
-    from opentelemetry.agent._vendor.urllib3.connectionpool import HTTPConnectionPool
-    from opentelemetry.agent._vendor.urllib3.poolmanager import PoolManager as _PoolManager
-
-    from . import _types as _t
-    from .models import PreparedRequest
-
-from ._types import is_prepared as _is_prepared
-
-DEFAULT_POOLBLOCK = False
-DEFAULT_POOLSIZE = 10
-DEFAULT_RETRIES = 0
-DEFAULT_POOL_TIMEOUT = None
-
-
-def _urllib3_request_context(
-    request: PreparedRequest,
-    verify: bool | str | None,
-    client_cert: tuple[str, str] | str | None,
-    poolmanager: PoolManager,
-) -> tuple[dict[str, Any], dict[str, Any]]:
-    host_params: dict[str, Any] = {}
-    pool_kwargs: dict[str, Any] = {}
-    parsed_request_url = urlparse(request.url)
-    scheme = parsed_request_url.scheme.lower()
-    port = parsed_request_url.port
-
-    cert_reqs = "CERT_REQUIRED"
-    if verify is False:
-        cert_reqs = "CERT_NONE"
-    elif isinstance(verify, str):
-        if not os.path.isdir(verify):
-            pool_kwargs["ca_certs"] = verify
-        else:
-            pool_kwargs["ca_cert_dir"] = verify
-    pool_kwargs["cert_reqs"] = cert_reqs
-    if client_cert is not None:
-        if isinstance(client_cert, tuple) and len(client_cert) == 2:
-            pool_kwargs["cert_file"] = client_cert[0]
-            pool_kwargs["key_file"] = client_cert[1]
-        else:
-            # According to our docs, we allow users to specify just the client
-            # cert path
-            pool_kwargs["cert_file"] = client_cert
-    host_params = {
-        "scheme": scheme,
-        "host": parsed_request_url.hostname,
-        "port": port,
-    }
-    return host_params, pool_kwargs
-
-
-class BaseAdapter:
-    """The Base Transport Adapter"""
-
-    def __init__(self) -> None:
-        super().__init__()
-
-    def send(
-        self,
-        request: PreparedRequest,
-        stream: bool = False,
-        timeout: _t.TimeoutType = None,
-        verify: _t.VerifyType = True,
-        cert: _t.CertType = None,
-        proxies: dict[str, str] | None = None,
-    ) -> Response:
-        """Sends PreparedRequest object. Returns Response object.
-
-        :param request: The :class:`PreparedRequest ` being sent.
-        :param stream: (optional) Whether to stream the request content.
-        :param timeout: (optional) How long to wait for the server to send
-            data before giving up, as a float, or a :ref:`(connect timeout,
-            read timeout) ` tuple.
-        :type timeout: float or tuple
-        :param verify: (optional) Either a boolean, in which case it controls whether we verify
-            the server's TLS certificate, or a string, in which case it must be a path
-            to a CA bundle to use
-        :param cert: (optional) Any user-provided SSL certificate to be trusted.
-        :param proxies: (optional) The proxies dictionary to apply to the request.
-        """
-        raise NotImplementedError
-
-    def close(self) -> None:
-        """Cleans up adapter specific items."""
-        raise NotImplementedError
-
-
-class HTTPAdapter(BaseAdapter):
-    """The built-in HTTP Adapter for urllib3.
-
-    Provides a general-case interface for Requests sessions to contact HTTP and
-    HTTPS urls by implementing the Transport Adapter interface. This class will
-    usually be created by the :class:`Session ` class under the
-    covers.
-
-    :param pool_connections: The number of urllib3 connection pools to cache.
-    :param pool_maxsize: The maximum number of connections to save in the pool.
-    :param max_retries: The maximum number of retries each connection
-        should attempt. Note, this applies only to failed DNS lookups, socket
-        connections and connection timeouts, never to requests where data has
-        made it to the server. By default, Requests does not retry failed
-        connections. If you need granular control over the conditions under
-        which we retry a request, import urllib3's ``Retry`` class and pass
-        that instead.
-    :param pool_block: Whether the connection pool should block for connections.
-
-    Usage::
-
-      >>> import requests
-      >>> s = requests.Session()
-      >>> a = requests.adapters.HTTPAdapter(max_retries=3)
-      >>> s.mount('http://', a)
-    """
-
-    __attrs__: list[str] = [
-        "max_retries",
-        "config",
-        "_pool_connections",
-        "_pool_maxsize",
-        "_pool_block",
-    ]
-
-    max_retries: Retry
-    config: dict[str, Any]
-    proxy_manager: dict[str, Any]
-    _pool_connections: int
-    _pool_maxsize: int
-    _pool_block: bool
-    poolmanager: _PoolManager
-
-    def __init__(
-        self,
-        pool_connections: int = DEFAULT_POOLSIZE,
-        pool_maxsize: int = DEFAULT_POOLSIZE,
-        max_retries: int | Retry = DEFAULT_RETRIES,
-        pool_block: bool = DEFAULT_POOLBLOCK,
-    ) -> None:
-        if max_retries == DEFAULT_RETRIES:
-            self.max_retries = Retry(0, read=False)
-        else:
-            self.max_retries = Retry.from_int(max_retries)
-        self.config = {}
-        self.proxy_manager = {}
-
-        super().__init__()
-
-        self._pool_connections = pool_connections
-        self._pool_maxsize = pool_maxsize
-        self._pool_block = pool_block
-
-        self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
-
-    def __getstate__(self) -> dict[str, Any]:
-        return {attr: getattr(self, attr, None) for attr in self.__attrs__}
-
-    def __setstate__(self, state: dict[str, Any]) -> None:
-        # Can't handle by adding 'proxy_manager' to self.__attrs__ because
-        # self.poolmanager uses a lambda function, which isn't pickleable.
-        self.proxy_manager = {}
-        self.config = {}
-
-        for attr, value in state.items():
-            setattr(self, attr, value)
-
-        self.init_poolmanager(
-            self._pool_connections, self._pool_maxsize, block=self._pool_block
-        )
-
-    def init_poolmanager(
-        self,
-        connections: int,
-        maxsize: int,
-        block: bool = DEFAULT_POOLBLOCK,
-        **pool_kwargs: Any,
-    ) -> None:
-        """Initializes a urllib3 PoolManager.
-
-        This method should not be called from user code, and is only
-        exposed for use when subclassing the
-        :class:`HTTPAdapter `.
-
-        :param connections: The number of urllib3 connection pools to cache.
-        :param maxsize: The maximum number of connections to save in the pool.
-        :param block: Block when no free connections are available.
-        :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
-        """
-        # save these values for pickling
-        self._pool_connections = connections
-        self._pool_maxsize = maxsize
-        self._pool_block = block
-
-        self.poolmanager = PoolManager(
-            num_pools=connections,
-            maxsize=maxsize,
-            block=block,
-            **pool_kwargs,
-        )
-
-    def proxy_manager_for(self, proxy: str, **proxy_kwargs: Any) -> Any:
-        """Return urllib3 ProxyManager for the given proxy.
-
-        This method should not be called from user code, and is only
-        exposed for use when subclassing the
-        :class:`HTTPAdapter `.
-
-        :param proxy: The proxy to return a urllib3 ProxyManager for.
-        :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
-        :returns: ProxyManager
-        :rtype: urllib3.ProxyManager
-        """
-        if proxy in self.proxy_manager:
-            manager = self.proxy_manager[proxy]
-        elif proxy.lower().startswith("socks"):
-            username, password = get_auth_from_url(proxy)
-            manager = self.proxy_manager[proxy] = SOCKSProxyManager(
-                proxy,
-                username=username,
-                password=password,
-                num_pools=self._pool_connections,
-                maxsize=self._pool_maxsize,
-                block=self._pool_block,
-                **proxy_kwargs,
-            )
-        else:
-            proxy_headers = self.proxy_headers(proxy)
-            manager = self.proxy_manager[proxy] = proxy_from_url(
-                proxy,
-                proxy_headers=proxy_headers,
-                num_pools=self._pool_connections,
-                maxsize=self._pool_maxsize,
-                block=self._pool_block,
-                **proxy_kwargs,
-            )
-
-        return manager
-
-    def cert_verify(
-        self, conn: Any, url: str, verify: _t.VerifyType, cert: _t.CertType
-    ) -> None:
-        """Verify a SSL certificate. This method should not be called from user
-        code, and is only exposed for use when subclassing the
-        :class:`HTTPAdapter `.
-
-        :param conn: The urllib3 connection object associated with the cert.
-        :param url: The requested URL.
-        :param verify: Either a boolean, in which case it controls whether we verify
-            the server's TLS certificate, or a string, in which case it must be a path
-            to a CA bundle to use
-        :param cert: The SSL certificate to verify.
-        """
-        if url.lower().startswith("https") and verify:
-            cert_loc = None
-
-            # Allow self-specified cert location.
-            if verify is not True:
-                cert_loc = verify
-
-            if not cert_loc:
-                cert_loc = DEFAULT_CA_BUNDLE_PATH
-
-            if not cert_loc or not os.path.exists(cert_loc):
-                raise OSError(
-                    f"Could not find a suitable TLS CA certificate bundle, "
-                    f"invalid path: {cert_loc}"
-                )
-
-            conn.cert_reqs = "CERT_REQUIRED"
-
-            if not os.path.isdir(cert_loc):
-                conn.ca_certs = cert_loc
-            else:
-                conn.ca_cert_dir = cert_loc
-        else:
-            conn.cert_reqs = "CERT_NONE"
-            conn.ca_certs = None
-            conn.ca_cert_dir = None
-
-        if cert:
-            if not isinstance(cert, basestring):
-                conn.cert_file = cert[0]
-                conn.key_file = cert[1]
-            else:
-                conn.cert_file = cert
-                conn.key_file = None
-            if conn.cert_file and not os.path.exists(conn.cert_file):
-                raise OSError(
-                    f"Could not find the TLS certificate file, "
-                    f"invalid path: {conn.cert_file}"
-                )
-            if conn.key_file and not os.path.exists(conn.key_file):
-                raise OSError(
-                    f"Could not find the TLS key file, invalid path: {conn.key_file}"
-                )
-
-    def build_response(self, req: PreparedRequest, resp: Any) -> Response:
-        """Builds a :class:`Response ` object from a urllib3
-        response. This should not be called from user code, and is only exposed
-        for use when subclassing the
-        :class:`HTTPAdapter `
-
-        :param req: The :class:`PreparedRequest ` used to generate the response.
-        :param resp: The urllib3 response object.
-        :rtype: requests.Response
-        """
-        assert _is_prepared(req)
-        response = Response()
-
-        # Fallback to None if there's no status_code, for whatever reason.
-        response.status_code = getattr(resp, "status", None)  # type: ignore[assignment]
-
-        # Make headers case-insensitive.
-        response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
-
-        # Set encoding.
-        response.encoding = get_encoding_from_headers(response.headers)
-        response.raw = resp
-        response.reason = response.raw.reason
-
-        if isinstance(req.url, bytes):
-            response.url = req.url.decode("utf-8")
-        else:
-            response.url = req.url
-
-        # Add new cookies from the server.
-        extract_cookies_to_jar(response.cookies, req, resp)
-
-        # Give the Response some context.
-        response.request = req
-        response.connection = self
-
-        return response
-
-    def build_connection_pool_key_attributes(
-        self, request: PreparedRequest, verify: _t.VerifyType, cert: _t.CertType = None
-    ) -> tuple[dict[str, Any], dict[str, Any]]:
-        """Build the PoolKey attributes used by urllib3 to return a connection.
-
-        This looks at the PreparedRequest, the user-specified verify value,
-        and the value of the cert parameter to determine what PoolKey values
-        to use to select a connection from a given urllib3 Connection Pool.
-
-        The SSL related pool key arguments are not consistently set. As of
-        this writing, use the following to determine what keys may be in that
-        dictionary:
-
-        * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the
-          default Requests SSL Context
-        * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but
-          ``"cert_reqs"`` will be set
-        * If ``verify`` is a string, (i.e., it is a user-specified trust bundle)
-          ``"ca_certs"`` will be set if the string is not a directory recognized
-          by :py:func:`os.path.isdir`, otherwise ``"ca_cert_dir"`` will be
-          set.
-        * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If
-          ``"cert"`` is a tuple with a second item, ``"key_file"`` will also
-          be present
-
-        To override these settings, one may subclass this class, call this
-        method and use the above logic to change parameters as desired. For
-        example, if one wishes to use a custom :py:class:`ssl.SSLContext` one
-        must both set ``"ssl_context"`` and based on what else they require,
-        alter the other keys to ensure the desired behaviour.
-
-        :param request:
-            The PreparedRequest being sent over the connection.
-        :type request:
-            :class:`~requests.models.PreparedRequest`
-        :param verify:
-            Either a boolean, in which case it controls whether
-            we verify the server's TLS certificate, or a string, in which case it
-            must be a path to a CA bundle to use.
-        :param cert:
-            (optional) Any user-provided SSL certificate for client
-            authentication (a.k.a., mTLS). This may be a string (i.e., just
-            the path to a file which holds both certificate and key) or a
-            tuple of length 2 with the certificate file path and key file
-            path.
-        :returns:
-            A tuple of two dictionaries. The first is the "host parameters"
-            portion of the Pool Key including scheme, hostname, and port. The
-            second is a dictionary of SSLContext related parameters.
-        """
-        return _urllib3_request_context(request, verify, cert, self.poolmanager)
-
-    def get_connection_with_tls_context(
-        self,
-        request: PreparedRequest,
-        verify: _t.VerifyType,
-        proxies: dict[str, str] | None = None,
-        cert: _t.CertType = None,
-    ) -> HTTPConnectionPool:
-        """Returns a urllib3 connection for the given request and TLS settings.
-        This should not be called from user code, and is only exposed for use
-        when subclassing the :class:`HTTPAdapter `.
-
-        :param request:
-            The :class:`PreparedRequest ` object to be sent
-            over the connection.
-        :param verify:
-            Either a boolean, in which case it controls whether we verify the
-            server's TLS certificate, or a string, in which case it must be a
-            path to a CA bundle to use.
-        :param proxies:
-            (optional) The proxies dictionary to apply to the request.
-        :param cert:
-            (optional) Any user-provided SSL certificate to be used for client
-            authentication (a.k.a., mTLS).
-        :rtype:
-            urllib3.HTTPConnectionPool
-        """
-        assert _is_prepared(request)
-
-        proxy = select_proxy(request.url, proxies)
-        try:
-            host_params, pool_kwargs = self.build_connection_pool_key_attributes(
-                request,
-                verify,
-                cert,
-            )
-        except ValueError as e:
-            raise InvalidURL(e, request=request)
-        if proxy:
-            proxy = prepend_scheme_if_needed(proxy, "http")
-            proxy_url = parse_url(proxy)
-            if not proxy_url.host:
-                raise InvalidProxyURL(
-                    "Please check proxy URL. It is malformed "
-                    "and could be missing the host."
-                )
-            proxy_manager = self.proxy_manager_for(proxy)
-            conn = proxy_manager.connection_from_host(
-                **host_params, pool_kwargs=pool_kwargs
-            )
-        else:
-            # Only scheme should be lower case
-            conn = self.poolmanager.connection_from_host(
-                **host_params, pool_kwargs=pool_kwargs
-            )
-
-        return conn
-
-    def get_connection(
-        self, url: str, proxies: dict[str, str] | None = None
-    ) -> HTTPConnectionPool:
-        """DEPRECATED: Users should move to `get_connection_with_tls_context`
-        for all subclasses of HTTPAdapter using Requests>=2.32.2.
-
-        Returns a urllib3 connection for the given URL. This should not be
-        called from user code, and is only exposed for use when subclassing the
-        :class:`HTTPAdapter `.
-
-        :param url: The URL to connect to.
-        :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
-        :rtype: urllib3.HTTPConnectionPool
-        """
-        warnings.warn(
-            (
-                "`get_connection` has been deprecated in favor of "
-                "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses "
-                "will need to migrate for Requests>=2.32.2. Please see "
-                "https://github.com/psf/requests/pull/6710 for more details."
-            ),
-            DeprecationWarning,
-        )
-        proxy = select_proxy(url, proxies)
-
-        if proxy:
-            proxy = prepend_scheme_if_needed(proxy, "http")
-            proxy_url = parse_url(proxy)
-            if not proxy_url.host:
-                raise InvalidProxyURL(
-                    "Please check proxy URL. It is malformed "
-                    "and could be missing the host."
-                )
-            proxy_manager = self.proxy_manager_for(proxy)
-            conn = proxy_manager.connection_from_url(url)
-        else:
-            # Only scheme should be lower case
-            parsed = urlparse(url)
-            url = parsed.geturl()
-            conn = self.poolmanager.connection_from_url(url)
-
-        return conn
-
-    def close(self) -> None:
-        """Disposes of any internal state.
-
-        Currently, this closes the PoolManager and any active ProxyManager,
-        which closes any pooled connections.
-        """
-        self.poolmanager.clear()
-        for proxy in self.proxy_manager.values():
-            proxy.clear()
-
-    def request_url(
-        self, request: PreparedRequest, proxies: dict[str, str] | None
-    ) -> str:
-        """Obtain the url to use when making the final request.
-
-        If the message is being sent through a HTTP proxy, the full URL has to
-        be used. Otherwise, we should only use the path portion of the URL.
-
-        This should not be called from user code, and is only exposed for use
-        when subclassing the
-        :class:`HTTPAdapter `.
-
-        :param request: The :class:`PreparedRequest ` being sent.
-        :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
-        :rtype: str
-        """
-        assert _is_prepared(request)
-
-        proxy = select_proxy(request.url, proxies)
-        scheme = urlparse(request.url).scheme
-
-        is_proxied_http_request = proxy and scheme != "https"
-        using_socks_proxy = False
-        if proxy:
-            proxy_scheme = urlparse(proxy).scheme.lower()
-            using_socks_proxy = proxy_scheme.startswith("socks")
-
-        url = request.path_url
-
-        if is_proxied_http_request and not using_socks_proxy:
-            url = urldefragauth(request.url)
-
-        return url
-
-    def add_headers(self, request: PreparedRequest, **kwargs: Any) -> None:
-        """Add any headers needed by the connection. As of v2.0 this does
-        nothing by default, but is left for overriding by users that subclass
-        the :class:`HTTPAdapter `.
-
-        This should not be called from user code, and is only exposed for use
-        when subclassing the
-        :class:`HTTPAdapter `.
-
-        :param request: The :class:`PreparedRequest ` to add headers to.
-        :param kwargs: The keyword arguments from the call to send().
-        """
-        pass
-
-    def proxy_headers(self, proxy: str) -> dict[str, str]:
-        """Returns a dictionary of the headers to add to any request sent
-        through a proxy. This works with urllib3 magic to ensure that they are
-        correctly sent to the proxy, rather than in a tunnelled request if
-        CONNECT is being used.
-
-        This should not be called from user code, and is only exposed for use
-        when subclassing the
-        :class:`HTTPAdapter `.
-
-        :param proxy: The url of the proxy being used for this request.
-        :rtype: dict
-        """
-        headers: dict[str, str] = {}
-        username, password = get_auth_from_url(proxy)
-
-        if username:
-            headers["Proxy-Authorization"] = _basic_auth_str(username, password)
-
-        return headers
-
-    def send(
-        self,
-        request: PreparedRequest,
-        stream: bool = False,
-        timeout: _t.TimeoutType = None,
-        verify: _t.VerifyType = True,
-        cert: _t.CertType = None,
-        proxies: dict[str, str] | None = None,
-    ) -> Response:
-        """Sends PreparedRequest object. Returns Response object.
-
-        :param request: The :class:`PreparedRequest ` being sent.
-        :param stream: (optional) Whether to stream the request content.
-        :param timeout: (optional) How long to wait for the server to send
-            data before giving up, as a float, or a :ref:`(connect timeout,
-            read timeout) ` tuple.
-        :type timeout: float or tuple or urllib3 Timeout object
-        :param verify: (optional) Either a boolean, in which case it controls whether
-            we verify the server's TLS certificate, or a string, in which case it
-            must be a path to a CA bundle to use
-        :param cert: (optional) Any user-provided SSL certificate to be trusted.
-        :param proxies: (optional) The proxies dictionary to apply to the request.
-        :rtype: requests.Response
-        """
-
-        assert _is_prepared(request)
-
-        try:
-            conn = self.get_connection_with_tls_context(
-                request, verify, proxies=proxies, cert=cert
-            )
-        except LocationValueError as e:
-            raise InvalidURL(e, request=request)
-
-        self.cert_verify(conn, request.url, verify, cert)
-        url = self.request_url(request, proxies)
-        self.add_headers(
-            request,
-            stream=stream,
-            timeout=timeout,
-            verify=verify,
-            cert=cert,
-            proxies=proxies,
-        )
-
-        chunked = not (request.body is None or "Content-Length" in request.headers)
-
-        if isinstance(timeout, tuple):
-            try:
-                connect, read = timeout
-                resolved_timeout = TimeoutSauce(connect=connect, read=read)
-            except ValueError:
-                raise ValueError(
-                    f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
-                    f"or a single float to set both timeouts to the same value."
-                )
-        elif isinstance(timeout, TimeoutSauce):
-            resolved_timeout = timeout
-        else:
-            resolved_timeout = TimeoutSauce(connect=timeout, read=timeout)
-
-        try:
-            resp = conn.urlopen(
-                method=request.method,
-                url=url,
-                body=request.body,  # type: ignore[arg-type]  # urllib3 stubs don't accept Iterable[bytes | str]
-                headers=request.headers,  # type: ignore[arg-type]  # urllib3#3072
-                redirect=False,
-                assert_same_host=False,
-                preload_content=False,
-                decode_content=False,
-                retries=self.max_retries,
-                timeout=resolved_timeout,
-                chunked=chunked,
-            )
-
-        except (ProtocolError, OSError) as err:
-            raise ConnectionError(err, request=request)
-
-        except MaxRetryError as e:
-            if isinstance(e.reason, ConnectTimeoutError):
-                # TODO: Remove this in 3.0.0: see #2811
-                if not isinstance(e.reason, NewConnectionError):
-                    raise ConnectTimeout(e, request=request)
-
-            if isinstance(e.reason, ResponseError):
-                raise RetryError(e, request=request)
-
-            if isinstance(e.reason, _ProxyError):
-                raise ProxyError(e, request=request)
-
-            if isinstance(e.reason, _SSLError):
-                # This branch is for urllib3 v1.22 and later.
-                raise SSLError(e, request=request)
-
-            raise ConnectionError(e, request=request)
-
-        except ClosedPoolError as e:
-            raise ConnectionError(e, request=request)
-
-        except _ProxyError as e:
-            raise ProxyError(e)
-
-        except (_SSLError, _HTTPError) as e:
-            if isinstance(e, _SSLError):
-                # This branch is for urllib3 versions earlier than v1.22
-                raise SSLError(e, request=request)
-            elif isinstance(e, ReadTimeoutError):
-                raise ReadTimeout(e, request=request)
-            elif isinstance(e, _InvalidHeader):
-                raise InvalidHeader(e, request=request)
-            else:
-                raise
-
-        return self.build_response(request, resp)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py
deleted file mode 100644
index 5b3cf13f4b9..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/api.py
+++ /dev/null
@@ -1,180 +0,0 @@
-"""
-requests.api
-~~~~~~~~~~~~
-
-This module implements the Requests API.
-
-:copyright: (c) 2012 by Kenneth Reitz.
-:license: Apache2, see LICENSE for more details.
-"""
-
-from __future__ import annotations
-
-from typing import TYPE_CHECKING
-
-from . import sessions
-from .models import Response
-
-if TYPE_CHECKING:
-    from opentelemetry.agent._vendor.typing_extensions import Unpack
-
-    from . import _types as _t
-
-
-def request(
-    method: str, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]
-) -> Response:
-    """Constructs and sends a :class:`Request `.
-
-    :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
-    :param url: URL for the new :class:`Request` object.
-    :param params: (optional) Dictionary, list of tuples or bytes to send
-        in the query string for the :class:`Request`.
-    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-        object to send in the body of the :class:`Request`.
-    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
-    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
-    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
-    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
-        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
-        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content_type'`` is a string
-        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
-        to add for the file.
-    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
-    :param timeout: (optional) How many seconds to wait for the server to send data
-        before giving up, as a float, or a :ref:`(connect timeout, read
-        timeout) ` tuple.
-    :type timeout: float or tuple
-    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
-    :type allow_redirects: bool
-    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
-    :param verify: (optional) Either a boolean, in which case it controls whether we verify
-            the server's TLS certificate, or a string, in which case it must be a path
-            to a CA bundle to use. Defaults to ``True``.
-    :param stream: (optional) if ``False``, the response content will be immediately downloaded.
-    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-
-    Usage::
-
-      >>> import requests
-      >>> req = requests.request('GET', 'https://httpbin.org/get')
-      >>> req
-      
-    """
-
-    # By using the 'with' statement we are sure the session is closed, thus we
-    # avoid leaving sockets open which can trigger a ResourceWarning in some
-    # cases, and look like a memory leak in others.
-    with sessions.Session() as session:
-        return session.request(method=method, url=url, **kwargs)
-
-
-def get(
-    url: _t.UriType, params: _t.ParamsType = None, **kwargs: Unpack[_t.GetKwargs]
-) -> Response:
-    r"""Sends a GET request.
-
-    :param url: URL for the new :class:`Request` object.
-    :param params: (optional) Dictionary, list of tuples or bytes to send
-        in the query string for the :class:`Request`.
-    :param \*\*kwargs: Optional arguments that ``request`` takes.
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-    """
-
-    return request("get", url, params=params, **kwargs)
-
-
-def options(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
-    r"""Sends an OPTIONS request.
-
-    :param url: URL for the new :class:`Request` object.
-    :param \*\*kwargs: Optional arguments that ``request`` takes.
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-    """
-
-    return request("options", url, **kwargs)
-
-
-def head(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
-    r"""Sends a HEAD request.
-
-    :param url: URL for the new :class:`Request` object.
-    :param \*\*kwargs: Optional arguments that ``request`` takes. If
-        `allow_redirects` is not provided, it will be set to `False` (as
-        opposed to the default :meth:`request` behavior).
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-    """
-
-    kwargs.setdefault("allow_redirects", False)
-    return request("head", url, **kwargs)
-
-
-def post(
-    url: _t.UriType,
-    data: _t.DataType = None,
-    json: _t.JsonType = None,
-    **kwargs: Unpack[_t.PostKwargs],
-) -> Response:
-    r"""Sends a POST request.
-
-    :param url: URL for the new :class:`Request` object.
-    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-        object to send in the body of the :class:`Request`.
-    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
-    :param \*\*kwargs: Optional arguments that ``request`` takes.
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-    """
-
-    return request("post", url, data=data, json=json, **kwargs)
-
-
-def put(
-    url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
-) -> Response:
-    r"""Sends a PUT request.
-
-    :param url: URL for the new :class:`Request` object.
-    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-        object to send in the body of the :class:`Request`.
-    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
-    :param \*\*kwargs: Optional arguments that ``request`` takes.
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-    """
-
-    return request("put", url, data=data, **kwargs)
-
-
-def patch(
-    url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
-) -> Response:
-    r"""Sends a PATCH request.
-
-    :param url: URL for the new :class:`Request` object.
-    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-        object to send in the body of the :class:`Request`.
-    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
-    :param \*\*kwargs: Optional arguments that ``request`` takes.
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-    """
-
-    return request("patch", url, data=data, **kwargs)
-
-
-def delete(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
-    r"""Sends a DELETE request.
-
-    :param url: URL for the new :class:`Request` object.
-    :param \*\*kwargs: Optional arguments that ``request`` takes.
-    :return: :class:`Response ` object
-    :rtype: requests.Response
-    """
-
-    return request("delete", url, **kwargs)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py
deleted file mode 100644
index 2af481dbf59..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/auth.py
+++ /dev/null
@@ -1,354 +0,0 @@
-"""
-requests.auth
-~~~~~~~~~~~~~
-
-This module contains the authentication handlers for Requests.
-"""
-
-from __future__ import annotations
-
-import hashlib
-import os
-import re
-import threading
-import time
-import warnings
-from base64 import b64encode
-from typing import TYPE_CHECKING, Any, Final, cast, overload
-
-from ._internal_utils import to_native_string
-from .compat import basestring, str, urlparse
-from .cookies import extract_cookies_to_jar
-from .utils import parse_dict_header
-
-if TYPE_CHECKING:
-    from http.cookiejar import CookieJar
-    from typing import Any
-
-    from .models import PreparedRequest, Response
-
-CONTENT_TYPE_FORM_URLENCODED: Final = "application/x-www-form-urlencoded"
-CONTENT_TYPE_MULTI_PART: Final = "multipart/form-data"
-
-
-def _basic_auth_str(username: bytes | str, password: bytes | str) -> str:
-    """Returns a Basic Auth string."""
-
-    # "I want us to put a big-ol' comment on top of it that
-    # says that this behaviour is dumb but we need to preserve
-    # it because people are relying on it."
-    #    - Lukasa
-    #
-    # These are here solely to maintain backwards compatibility
-    # for things like ints. This will be removed in 3.0.0.
-    if not isinstance(username, basestring):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard for non-str/bytes
-        warnings.warn(
-            "Non-string usernames will no longer be supported in Requests "
-            f"3.0.0. Please convert the object you've passed in ({username!r}) to "
-            "a string or bytes object in the near future to avoid "
-            "problems.",
-            category=DeprecationWarning,
-        )
-        username = str(username)
-
-    if not isinstance(password, basestring):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard for non-str/bytes
-        warnings.warn(
-            "Non-string passwords will no longer be supported in Requests "
-            f"3.0.0. Please convert the object you've passed in ({type(password)!r}) to "
-            "a string or bytes object in the near future to avoid "
-            "problems.",
-            category=DeprecationWarning,
-        )
-        password = str(password)
-    # -- End Removal --
-
-    if isinstance(username, str):
-        username = username.encode("latin1")
-
-    if isinstance(password, str):
-        password = password.encode("latin1")
-
-    authstr = "Basic " + to_native_string(
-        b64encode(b":".join((username, password))).strip()
-    )
-
-    return authstr
-
-
-class AuthBase:
-    """Base class that all auth implementations derive from"""
-
-    def __call__(self, r: PreparedRequest) -> PreparedRequest:
-        raise NotImplementedError("Auth hooks must be callable.")
-
-
-class HTTPBasicAuth(AuthBase):
-    """Attaches HTTP Basic Authentication to the given Request object."""
-
-    username: bytes | str
-    password: bytes | str
-
-    @overload
-    def __init__(self, username: str, password: str) -> None: ...
-    @overload
-    def __init__(self, username: bytes, password: bytes) -> None: ...
-
-    def __init__(self, username: bytes | str, password: bytes | str) -> None:
-        self.username = username
-        self.password = password
-
-    def __eq__(self, other: object) -> bool:
-        return all(
-            [
-                self.username == getattr(other, "username", None),
-                self.password == getattr(other, "password", None),
-            ]
-        )
-
-    def __ne__(self, other: Any) -> bool:
-        return not self == other
-
-    def __call__(self, r: PreparedRequest) -> PreparedRequest:
-        r.headers["Authorization"] = _basic_auth_str(self.username, self.password)
-        return r
-
-
-class HTTPProxyAuth(HTTPBasicAuth):
-    """Attaches HTTP Proxy Authentication to a given Request object."""
-
-    def __call__(self, r: PreparedRequest) -> PreparedRequest:
-        r.headers["Proxy-Authorization"] = _basic_auth_str(self.username, self.password)
-        return r
-
-
-class HTTPDigestAuth(AuthBase):
-    """Attaches HTTP Digest Authentication to the given Request object."""
-
-    username: bytes | str
-    password: bytes | str
-    _thread_local: threading.local
-    last_nonce: str
-    nonce_count: int
-    chal: dict[str, str]
-    pos: int | None
-    num_401_calls: int | None
-
-    @overload
-    def __init__(self, username: str, password: str) -> None: ...
-    @overload
-    def __init__(self, username: bytes, password: bytes) -> None: ...
-
-    def __init__(self, username: bytes | str, password: bytes | str) -> None:
-        self.username = username
-        self.password = password
-        # Keep state in per-thread local storage
-        self._thread_local = threading.local()
-
-    def init_per_thread_state(self) -> None:
-        # Ensure state is initialized just once per-thread
-        if not hasattr(self._thread_local, "init"):
-            self._thread_local.init = True
-            self._thread_local.last_nonce = ""
-            self._thread_local.nonce_count = 0
-            self._thread_local.chal = {}
-            self._thread_local.pos = None
-            self._thread_local.num_401_calls = None
-
-    def build_digest_header(self, method: str, url: str) -> str | None:
-        """
-        :rtype: str
-        """
-
-        realm = self._thread_local.chal["realm"]
-        nonce = self._thread_local.chal["nonce"]
-        qop = self._thread_local.chal.get("qop")
-        algorithm = self._thread_local.chal.get("algorithm")
-        opaque = self._thread_local.chal.get("opaque")
-        hash_utf8 = None
-
-        if algorithm is None:
-            _algorithm = "MD5"
-        else:
-            _algorithm = algorithm.upper()
-        # lambdas assume digest modules are imported at the top level
-        if _algorithm == "MD5" or _algorithm == "MD5-SESS":
-
-            def md5_utf8(x: str | bytes) -> str:
-                if isinstance(x, str):
-                    x = x.encode("utf-8")
-                return hashlib.md5(x, usedforsecurity=False).hexdigest()
-
-            hash_utf8 = md5_utf8
-        elif _algorithm == "SHA":
-
-            def sha_utf8(x: str | bytes) -> str:
-                if isinstance(x, str):
-                    x = x.encode("utf-8")
-                return hashlib.sha1(x, usedforsecurity=False).hexdigest()
-
-            hash_utf8 = sha_utf8
-        elif _algorithm == "SHA-256":
-
-            def sha256_utf8(x: str | bytes) -> str:
-                if isinstance(x, str):
-                    x = x.encode("utf-8")
-                return hashlib.sha256(x, usedforsecurity=False).hexdigest()
-
-            hash_utf8 = sha256_utf8
-        elif _algorithm == "SHA-512":
-
-            def sha512_utf8(x: str | bytes) -> str:
-                if isinstance(x, str):
-                    x = x.encode("utf-8")
-                return hashlib.sha512(x, usedforsecurity=False).hexdigest()
-
-            hash_utf8 = sha512_utf8
-
-        if hash_utf8 is None:
-            return None
-
-        def KD(s: str, d: str) -> str:
-            return hash_utf8(f"{s}:{d}")
-
-        # XXX not implemented yet
-        entdig = None
-        p_parsed = urlparse(url)
-        #: path is request-uri defined in RFC 2616 which should not be empty
-        path = p_parsed.path or "/"
-        if p_parsed.query:
-            path += f"?{p_parsed.query}"
-
-        A1 = f"{self.username}:{realm}:{self.password}"
-        A2 = f"{method}:{path}"
-
-        HA1 = hash_utf8(A1)
-        HA2 = hash_utf8(A2)
-
-        if nonce == self._thread_local.last_nonce:
-            self._thread_local.nonce_count += 1
-        else:
-            self._thread_local.nonce_count = 1
-        ncvalue = f"{self._thread_local.nonce_count:08x}"
-        s = str(self._thread_local.nonce_count).encode("utf-8")
-        s += nonce.encode("utf-8")
-        s += time.ctime().encode("utf-8")
-        s += os.urandom(8)
-
-        cnonce = hashlib.sha1(s, usedforsecurity=False).hexdigest()[:16]
-        if _algorithm == "MD5-SESS":
-            HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}")  # type: ignore[reportConstantRedefinition]  # RFC 2617 terminology
-
-        if not qop:
-            respdig = KD(HA1, f"{nonce}:{HA2}")
-        elif qop == "auth" or "auth" in qop.split(","):
-            noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}"
-            respdig = KD(HA1, noncebit)
-        else:
-            # XXX handle auth-int.
-            return None
-
-        self._thread_local.last_nonce = nonce
-
-        # XXX should the partial digests be encoded too?
-        base = (
-            f'username="{self.username}", realm="{realm}", nonce="{nonce}", '
-            f'uri="{path}", response="{respdig}"'
-        )
-        if opaque:
-            base += f', opaque="{opaque}"'
-        if algorithm:
-            base += f', algorithm="{algorithm}"'
-        if entdig:
-            base += f', digest="{entdig}"'
-        if qop:
-            base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"'
-
-        return f"Digest {base}"
-
-    def handle_redirect(self, r: Response, **kwargs: Any) -> None:
-        """Reset num_401_calls counter on redirects."""
-        if r.is_redirect:
-            self._thread_local.num_401_calls = 1
-
-    def handle_401(self, r: Response, **kwargs: Any) -> Response:
-        """
-        Takes the given response and tries digest-auth, if needed.
-
-        :rtype: requests.Response
-        """
-
-        # If response is not 4xx, do not auth
-        # See https://github.com/psf/requests/issues/3772
-        if not 400 <= r.status_code < 500:
-            self._thread_local.num_401_calls = 1
-            return r
-
-        if self._thread_local.pos is not None:
-            # Rewind the file position indicator of the body to where
-            # it was to resend the request.
-            if (seek := getattr(r.request.body, "seek", None)) is not None:
-                seek(self._thread_local.pos)
-        s_auth = r.headers.get("www-authenticate", "")
-
-        if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2:
-            self._thread_local.num_401_calls += 1
-            pat = re.compile(r"digest ", flags=re.IGNORECASE)
-            self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1))
-
-            # Consume content and release the original connection
-            # to allow our new request to reuse the same one.
-            r.content
-            r.close()
-            prep = r.request.copy()
-            cookie_jar = cast("CookieJar", prep._cookies)  # type: ignore[reportPrivateUsage]
-            extract_cookies_to_jar(cookie_jar, r.request, r.raw)
-            prep.prepare_cookies(cookie_jar)
-
-            _digest_auth = self.build_digest_header(
-                cast(str, prep.method), cast(str, prep.url)
-            )
-            if _digest_auth:
-                prep.headers["Authorization"] = _digest_auth
-            _r = r.connection.send(prep, **kwargs)
-            _r.history.append(r)
-            _r.request = prep
-
-            return _r
-
-        self._thread_local.num_401_calls = 1
-        return r
-
-    def __call__(self, r: PreparedRequest) -> PreparedRequest:
-        # Initialize per-thread state, if needed
-        self.init_per_thread_state()
-        # If we have a saved nonce, skip the 401
-        if self._thread_local.last_nonce:
-            _digest_auth = self.build_digest_header(
-                cast(str, r.method), cast(str, r.url)
-            )
-            if _digest_auth:
-                r.headers["Authorization"] = _digest_auth
-        if (tell := getattr(r.body, "tell", None)) is not None:
-            self._thread_local.pos = tell()
-        else:
-            # In the case of HTTPDigestAuth being reused and the body of
-            # the previous request was a file-like object, pos has the
-            # file position of the previous body. Ensure it's set to
-            # None.
-            self._thread_local.pos = None
-        r.register_hook("response", self.handle_401)
-        r.register_hook("response", self.handle_redirect)
-        self._thread_local.num_401_calls = 1
-
-        return r
-
-    def __eq__(self, other: object) -> bool:
-        return all(
-            [
-                self.username == getattr(other, "username", None),
-                self.password == getattr(other, "password", None),
-            ]
-        )
-
-    def __ne__(self, other: Any) -> bool:
-        return not self == other
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py
deleted file mode 100644
index 15262c79c60..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/certs.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-
-"""
-requests.certs
-~~~~~~~~~~~~~~
-
-This module returns the preferred default CA certificate bundle. There is
-only one — the one from the certifi package.
-
-If you are packaging Requests, e.g., for a Linux distribution or a managed
-environment, you can change the definition of where() to return a separately
-packaged CA bundle.
-"""
-
-from opentelemetry.agent._vendor.certifi import where
-
-if __name__ == "__main__":
-    print(where())
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py
deleted file mode 100644
index 28899bea391..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/compat.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-requests.compat
-~~~~~~~~~~~~~~~
-
-This module previously handled import compatibility issues
-between Python 2 and Python 3. It remains for backwards
-compatibility until the next major version.
-"""
-
-# pyright: reportUnusedImport=false
-
-from __future__ import annotations
-
-import importlib
-import sys
-from types import ModuleType
-
-# -------
-# urllib3
-# -------
-from opentelemetry.agent._vendor.urllib3 import (
-    __version__ as urllib3_version,  # type: ignore[reportPrivateImportUsage]
-)
-
-# Detect which major version of urllib3 is being used.
-try:
-    is_urllib3_1 = int(urllib3_version.split(".")[0]) == 1
-except (TypeError, AttributeError):
-    # If we can't discern a version, prefer old functionality.
-    is_urllib3_1 = True
-
-# -------------------
-# Character Detection
-# -------------------
-
-
-# Always use the vendored charset_normalizer, never the application's chardet.
-from opentelemetry.agent._vendor import charset_normalizer as chardet
-
-# -------
-# Pythons
-# -------
-
-# Syntax sugar.
-_ver = sys.version_info
-
-#: Python 2.x?
-is_py2 = _ver[0] == 2
-
-#: Python 3.x?
-is_py3 = _ver[0] == 3
-
-# json/simplejson module import resolution
-has_simplejson = False
-try:
-    import simplejson as json  # type: ignore[import-not-found]
-
-    has_simplejson = True
-except ImportError:
-    import json
-
-if has_simplejson:
-    from simplejson import JSONDecodeError  # type: ignore[import-not-found]
-else:
-    from json import JSONDecodeError
-
-# Keep OrderedDict for backwards compatibility.
-from collections import OrderedDict
-from collections.abc import Callable, Mapping, MutableMapping
-from http import cookiejar as cookielib
-from http.cookies import Morsel
-from io import StringIO
-
-# --------------
-# Legacy Imports
-# --------------
-from urllib.parse import (
-    quote,
-    quote_plus,
-    unquote,
-    unquote_plus,
-    urldefrag,
-    urlencode,
-    urljoin,
-    urlparse,
-    urlsplit,
-    urlunparse,
-)
-from urllib.request import (
-    getproxies,
-    getproxies_environment,
-    parse_http_list,
-    proxy_bypass,
-    proxy_bypass_environment,  # type: ignore[attr-defined]  # https://github.com/python/cpython/issues/145331
-)
-
-builtin_str = str
-str = str
-bytes = bytes
-basestring = (str, bytes)
-numeric_types = (int, float)
-integer_types = (int,)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py
deleted file mode 100644
index 2e3fc215095..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/cookies.py
+++ /dev/null
@@ -1,625 +0,0 @@
-"""
-requests.cookies
-~~~~~~~~~~~~~~~~
-
-Compatibility code to be able to use `http.cookiejar.CookieJar` with requests.
-
-requests.utils imports from here, so be careful with imports.
-"""
-
-from __future__ import annotations
-
-import calendar
-import copy
-import time
-from collections.abc import Iterator, MutableMapping
-from http.cookiejar import Cookie, CookieJar, CookiePolicy
-from typing import TYPE_CHECKING, Any, TypeVar, overload
-
-from ._internal_utils import to_native_string
-from ._types import is_prepared as _is_prepared
-from .compat import Morsel, cookielib, urlparse, urlunparse
-
-if TYPE_CHECKING:
-    from _typeshed import SupportsKeysAndGetItem
-
-    from .models import PreparedRequest
-
-import threading
-
-
-class MockRequest:
-    """Wraps a `requests.PreparedRequest` to mimic a `urllib2.Request`.
-
-    The code in `http.cookiejar.CookieJar` expects this interface in order to correctly
-    manage cookie policies, i.e., determine whether a cookie can be set, given the
-    domains of the request and the cookie.
-
-    The original request object is read-only. The client is responsible for collecting
-    the new headers via `get_new_headers()` and interpreting them appropriately. You
-    probably want `get_cookie_header`, defined below.
-    """
-
-    type: str
-
-    def __init__(self, request: PreparedRequest) -> None:
-        assert _is_prepared(request)
-        self._r = request
-        self._new_headers: dict[str, str] = {}
-        self.type = urlparse(self._r.url).scheme
-
-    def get_type(self) -> str:
-        return self.type
-
-    def get_host(self) -> str:
-        return urlparse(self._r.url).netloc
-
-    def get_origin_req_host(self) -> str:
-        return self.get_host()
-
-    def get_full_url(self) -> str:
-        # Only return the response's URL if the user hadn't set the Host
-        # header
-        if not self._r.headers.get("Host"):
-            return self._r.url
-        # If they did set it, retrieve it and reconstruct the expected domain
-        host = to_native_string(self._r.headers["Host"], encoding="utf-8")
-        parsed = urlparse(self._r.url)
-        # Reconstruct the URL as we expect it
-        return urlunparse(
-            [
-                parsed.scheme,
-                host,
-                parsed.path,
-                parsed.params,
-                parsed.query,
-                parsed.fragment,
-            ]
-        )
-
-    def is_unverifiable(self) -> bool:
-        return True
-
-    def has_header(self, name: str) -> bool:
-        return name in self._r.headers or name in self._new_headers
-
-    def get_header(self, name: str, default: str | None = None) -> str | None:
-        return self._r.headers.get(name, self._new_headers.get(name, default))  # type: ignore[return-value]
-
-    def add_header(self, key: str, val: str) -> None:
-        """cookiejar has no legitimate use for this method; add it back if you find one."""
-        raise NotImplementedError(
-            "Cookie headers should be added with add_unredirected_header()"
-        )
-
-    def add_unredirected_header(self, name: str, value: str) -> None:
-        self._new_headers[name] = value
-
-    def get_new_headers(self) -> dict[str, str]:
-        return self._new_headers
-
-    @property
-    def unverifiable(self) -> bool:
-        return self.is_unverifiable()
-
-    @property
-    def origin_req_host(self) -> str:
-        return self.get_origin_req_host()
-
-    @property
-    def host(self) -> str:
-        return self.get_host()
-
-
-class MockResponse:
-    """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
-
-    ...what? Basically, expose the parsed HTTP headers from the server response
-    the way `http.cookiejar` expects to see them.
-    """
-
-    def __init__(self, headers: Any) -> None:
-        """Make a MockResponse for `cookiejar` to read.
-
-        :param headers: a httplib.HTTPMessage or analogous carrying the headers
-        """
-        self._headers = headers
-
-    def info(self) -> Any:
-        return self._headers
-
-    def getheaders(self, name: str) -> Any:
-        self._headers.getheaders(name)
-
-
-def extract_cookies_to_jar(
-    jar: CookieJar, request: PreparedRequest, response: Any
-) -> None:
-    """Extract the cookies from the response into a CookieJar.
-
-    :param jar: http.cookiejar.CookieJar (not necessarily a RequestsCookieJar)
-    :param request: our own requests.Request object
-    :param response: urllib3.HTTPResponse object
-    """
-    if not (hasattr(response, "_original_response") and response._original_response):
-        return
-    # the _original_response field is the wrapped httplib.HTTPResponse object,
-    req = MockRequest(request)
-    # pull out the HTTPMessage with the headers and put it in the mock:
-    res = MockResponse(response._original_response.msg)
-    jar.extract_cookies(res, req)  # type: ignore[arg-type]
-
-
-def get_cookie_header(jar: CookieJar, request: PreparedRequest) -> str | None:
-    """
-    Produce an appropriate Cookie header string to be sent with `request`, or None.
-
-    :rtype: str
-    """
-    r = MockRequest(request)
-    jar.add_cookie_header(r)  # type: ignore[arg-type]
-    return r.get_new_headers().get("Cookie")
-
-
-def remove_cookie_by_name(
-    cookiejar: CookieJar, name: str, domain: str | None = None, path: str | None = None
-) -> None:
-    """Unsets a cookie by name, by default over all domains and paths.
-
-    Wraps CookieJar.clear(), is O(n).
-    """
-    clearables: list[tuple[str, str, str]] = []
-    for cookie in cookiejar:
-        if cookie.name != name:
-            continue
-        if domain is not None and domain != cookie.domain:
-            continue
-        if path is not None and path != cookie.path:
-            continue
-        clearables.append((cookie.domain, cookie.path, cookie.name))
-
-    for domain, path, name in clearables:
-        cookiejar.clear(domain, path, name)
-
-
-class CookieConflictError(RuntimeError):
-    """There are two cookies that meet the criteria specified in the cookie jar.
-    Use .get and .set and include domain and path args in order to be more specific.
-    """
-
-
-class RequestsCookieJar(CookieJar, MutableMapping[str, str | None]):  # type: ignore[misc]
-    """Compatibility class; is a http.cookiejar.CookieJar, but exposes a dict
-    interface.
-
-    This is the CookieJar we create by default for requests and sessions that
-    don't specify one, since some clients may expect response.cookies and
-    session.cookies to support dict operations.
-
-    Requests does not use the dict interface internally; it's just for
-    compatibility with external client code. All requests code should work
-    out of the box with externally provided instances of ``CookieJar``, e.g.
-    ``LWPCookieJar`` and ``FileCookieJar``.
-
-    Unlike a regular CookieJar, this class is pickleable.
-
-    .. warning:: dictionary operations that are normally O(1) may be O(n).
-    """
-
-    _policy: CookiePolicy
-
-    def get(  # type: ignore[override]
-        self,
-        name: str,
-        default: str | None = None,
-        domain: str | None = None,
-        path: str | None = None,
-    ) -> str | None:
-        """Dict-like get() that also supports optional domain and path args in
-        order to resolve naming collisions from using one cookie jar over
-        multiple domains.
-
-        .. warning:: operation is O(n), not O(1).
-        """
-        try:
-            return self._find_no_duplicates(name, domain, path)
-        except KeyError:
-            return default
-
-    def set(
-        self, name: str, value: str | Morsel[dict[str, str]] | None, **kwargs: Any
-    ) -> Cookie | None:
-        """Dict-like set() that also supports optional domain and path args in
-        order to resolve naming collisions from using one cookie jar over
-        multiple domains.
-        """
-        # support client code that unsets cookies by assignment of a None value:
-        if value is None:
-            remove_cookie_by_name(
-                self, name, domain=kwargs.get("domain"), path=kwargs.get("path")
-            )
-            return
-
-        if isinstance(value, Morsel):
-            c = morsel_to_cookie(value)
-        else:
-            c = create_cookie(name, value, **kwargs)
-        self.set_cookie(c)
-        return c
-
-    def iterkeys(self) -> Iterator[str]:
-        """Dict-like iterkeys() that returns an iterator of names of cookies
-        from the jar.
-
-        .. seealso:: itervalues() and iteritems().
-        """
-        for cookie in iter(self):
-            yield cookie.name
-
-    def keys(self) -> list[str]:  # type: ignore[override]
-        """Dict-like keys() that returns a list of names of cookies from the
-        jar.
-
-        .. seealso:: values() and items().
-        """
-        return list(self.iterkeys())
-
-    def itervalues(self) -> Iterator[str | None]:
-        """Dict-like itervalues() that returns an iterator of values of cookies
-        from the jar.
-
-        .. seealso:: iterkeys() and iteritems().
-        """
-        for cookie in iter(self):
-            yield cookie.value
-
-    def values(self) -> list[str | None]:  # type: ignore[override]
-        """Dict-like values() that returns a list of values of cookies from the
-        jar.
-
-        .. seealso:: keys() and items().
-        """
-        return list(self.itervalues())
-
-    def iteritems(self) -> Iterator[tuple[str, str | None]]:
-        """Dict-like iteritems() that returns an iterator of name-value tuples
-        from the jar.
-
-        .. seealso:: iterkeys() and itervalues().
-        """
-        for cookie in iter(self):
-            yield cookie.name, cookie.value
-
-    def items(self) -> list[tuple[str, str | None]]:  # type: ignore[override]
-        """Dict-like items() that returns a list of name-value tuples from the
-        jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a
-        vanilla python dict of key value pairs.
-
-        .. seealso:: keys() and values().
-        """
-        return list(self.iteritems())
-
-    def list_domains(self) -> list[str]:
-        """Utility method to list all the domains in the jar."""
-        domains: list[str] = []
-        for cookie in iter(self):
-            if cookie.domain not in domains:
-                domains.append(cookie.domain)
-        return domains
-
-    def list_paths(self) -> list[str]:
-        """Utility method to list all the paths in the jar."""
-        paths: list[str] = []
-        for cookie in iter(self):
-            if cookie.path not in paths:
-                paths.append(cookie.path)
-        return paths
-
-    def multiple_domains(self) -> bool:
-        """Returns True if there are multiple domains in the jar.
-        Returns False otherwise.
-
-        :rtype: bool
-        """
-        domains: list[str] = []
-        for cookie in iter(self):
-            if cookie.domain is not None and cookie.domain in domains:  # type: ignore[reportUnnecessaryComparison]  # defensive check
-                return True
-            domains.append(cookie.domain)
-        return False  # there is only one domain in jar
-
-    def get_dict(
-        self, domain: str | None = None, path: str | None = None
-    ) -> dict[str, str | None]:
-        """Takes as an argument an optional domain and path and returns a plain
-        old Python dict of name-value pairs of cookies that meet the
-        requirements.
-
-        :rtype: dict
-        """
-        dictionary: dict[str, str | None] = {}
-        for cookie in iter(self):
-            if (domain is None or cookie.domain == domain) and (
-                path is None or cookie.path == path
-            ):
-                dictionary[cookie.name] = cookie.value
-        return dictionary
-
-    def __iter__(self) -> Iterator[Cookie]:  # type: ignore[override]
-        """RequestCookieJar's __iter__ comes from CookieJar not MutableMapping."""
-        return super().__iter__()
-
-    def __contains__(self, name: object) -> bool:
-        try:
-            return super().__contains__(name)
-        except CookieConflictError:
-            return True
-
-    def __getitem__(self, name: str) -> str | None:
-        """Dict-like __getitem__() for compatibility with client code. Throws
-        exception if there are more than one cookie with name. In that case,
-        use the more explicit get() method instead.
-
-        .. warning:: operation is O(n), not O(1).
-        """
-        return self._find_no_duplicates(name)
-
-    def __setitem__(
-        self, name: str, value: str | Morsel[dict[str, str]] | None
-    ) -> None:
-        """Dict-like __setitem__ for compatibility with client code. Throws
-        exception if there is already a cookie of that name in the jar. In that
-        case, use the more explicit set() method instead.
-        """
-        self.set(name, value)
-
-    def __delitem__(self, name: str) -> None:
-        """Deletes a cookie given a name. Wraps ``http.cookiejar.CookieJar``'s
-        ``remove_cookie_by_name()``.
-        """
-        remove_cookie_by_name(self, name)
-
-    def set_cookie(self, cookie: Cookie, *args: Any, **kwargs: Any) -> None:
-        if (
-            (value := cookie.value) is not None
-            and value.startswith('"')
-            and value.endswith('"')
-        ):
-            cookie.value = value.replace('\\"', "")
-        return super().set_cookie(cookie, *args, **kwargs)
-
-    def update(  # type: ignore[override]
-        self, other: CookieJar | SupportsKeysAndGetItem[str, str]
-    ) -> None:
-        """Updates this jar with cookies from another CookieJar or dict-like"""
-        if isinstance(other, cookielib.CookieJar):
-            for cookie in other:
-                self.set_cookie(copy.copy(cookie))
-        else:
-            super().update(other)
-
-    def _find(
-        self, name: str, domain: str | None = None, path: str | None = None
-    ) -> str | None:
-        """Requests uses this method internally to get cookie values.
-
-        If there are conflicting cookies, _find arbitrarily chooses one.
-        See _find_no_duplicates if you want an exception thrown if there are
-        conflicting cookies.
-
-        :param name: a string containing name of cookie
-        :param domain: (optional) string containing domain of cookie
-        :param path: (optional) string containing path of cookie
-        :return: cookie.value
-        """
-        for cookie in iter(self):
-            if cookie.name == name:
-                if domain is None or cookie.domain == domain:
-                    if path is None or cookie.path == path:
-                        return cookie.value
-
-        raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
-
-    def _find_no_duplicates(
-        self, name: str, domain: str | None = None, path: str | None = None
-    ) -> str:
-        """Both ``__get_item__`` and ``get`` call this function: it's never
-        used elsewhere in Requests.
-
-        :param name: a string containing name of cookie
-        :param domain: (optional) string containing domain of cookie
-        :param path: (optional) string containing path of cookie
-        :raises KeyError: if cookie is not found
-        :raises CookieConflictError: if there are multiple cookies
-            that match name and optionally domain and path
-        :return: cookie.value
-        """
-        toReturn = None
-        for cookie in iter(self):
-            if cookie.name == name:
-                if domain is None or cookie.domain == domain:
-                    if path is None or cookie.path == path:
-                        if toReturn is not None:
-                            # if there are multiple cookies that meet passed in criteria
-                            raise CookieConflictError(
-                                f"There are multiple cookies with name, {name!r}"
-                            )
-                        # we will eventually return this as long as no cookie conflict
-                        toReturn = cookie.value
-
-        if toReturn is not None:
-            return toReturn
-        raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
-
-    def __getstate__(self) -> dict[str, Any]:
-        """Unlike a normal CookieJar, this class is pickleable."""
-        state = self.__dict__.copy()
-        # remove the unpickleable RLock object
-        state.pop("_cookies_lock")
-        return state
-
-    def __setstate__(self, state: dict[str, Any]) -> None:
-        """Unlike a normal CookieJar, this class is pickleable."""
-        self.__dict__.update(state)
-        if "_cookies_lock" not in self.__dict__:
-            self._cookies_lock = threading.RLock()
-
-    def copy(self) -> RequestsCookieJar:
-        """Return a copy of this RequestsCookieJar."""
-        new_cj = RequestsCookieJar()
-        new_cj.set_policy(self.get_policy())
-        new_cj.update(self)
-        return new_cj
-
-    def get_policy(self) -> CookiePolicy:
-        """Return the CookiePolicy instance used."""
-        return self._policy
-
-
-def _copy_cookie_jar(jar: CookieJar | None) -> CookieJar | None:  # type: ignore[reportUnusedFunction]  # cross-module usage in models.py
-    if jar is None:
-        return None
-
-    if copy_method := getattr(jar, "copy", None):
-        # We're dealing with an instance of RequestsCookieJar
-        return copy_method()
-    # We're dealing with a generic CookieJar instance
-    new_jar = copy.copy(jar)
-    new_jar.clear()
-    for cookie in jar:
-        new_jar.set_cookie(copy.copy(cookie))
-    return new_jar
-
-
-def create_cookie(name: str, value: str, **kwargs: Any) -> Cookie:
-    """Make a cookie from underspecified parameters.
-
-    By default, the pair of `name` and `value` will be set for the domain ''
-    and sent on every request (this is sometimes called a "supercookie").
-    """
-    result: dict[str, Any] = {
-        "version": 0,
-        "name": name,
-        "value": value,
-        "port": None,
-        "domain": "",
-        "path": "/",
-        "secure": False,
-        "expires": None,
-        "discard": True,
-        "comment": None,
-        "comment_url": None,
-        "rest": {"HttpOnly": None},
-        "rfc2109": False,
-    }
-
-    badargs = set(kwargs) - set(result)
-    if badargs:
-        raise TypeError(
-            f"create_cookie() got unexpected keyword arguments: {list(badargs)}"
-        )
-
-    result.update(kwargs)
-    result["port_specified"] = bool(result["port"])
-    result["domain_specified"] = bool(result["domain"])
-    result["domain_initial_dot"] = result["domain"].startswith(".")
-    result["path_specified"] = bool(result["path"])
-
-    return cookielib.Cookie(**result)
-
-
-def morsel_to_cookie(morsel: Morsel[Any]) -> Cookie:
-    """Convert a Morsel object into a Cookie containing the one k/v pair."""
-
-    expires: int | None = None
-    if morsel["max-age"]:
-        try:
-            expires = int(time.time() + int(morsel["max-age"]))
-        except ValueError:
-            raise TypeError(f"max-age: {morsel['max-age']} must be integer")
-    elif morsel["expires"]:
-        time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
-        expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
-    return create_cookie(
-        comment=morsel["comment"],
-        comment_url=bool(morsel["comment"]),
-        discard=False,
-        domain=morsel["domain"],
-        expires=expires,
-        name=morsel.key,
-        path=morsel["path"],
-        port=None,
-        rest={"HttpOnly": morsel["httponly"]},
-        rfc2109=False,
-        secure=bool(morsel["secure"]),
-        value=morsel.value,
-        version=morsel["version"] or 0,
-    )
-
-
-_CookieJarT = TypeVar("_CookieJarT", bound=CookieJar)
-
-
-@overload
-def cookiejar_from_dict(
-    cookie_dict: dict[str, str] | None,
-    cookiejar: None = None,
-    overwrite: bool = True,
-) -> RequestsCookieJar: ...
-
-
-@overload
-def cookiejar_from_dict(
-    cookie_dict: dict[str, str] | None,
-    cookiejar: _CookieJarT,
-    overwrite: bool = True,
-) -> _CookieJarT: ...
-
-
-def cookiejar_from_dict(
-    cookie_dict: dict[str, str] | None,
-    cookiejar: CookieJar | None = None,
-    overwrite: bool = True,
-) -> CookieJar:
-    """Returns a CookieJar from a key/value dictionary.
-
-    :param cookie_dict: Dict of key/values to insert into CookieJar.
-    :param cookiejar: (optional) A cookiejar to add the cookies to.
-    :param overwrite: (optional) If False, will not replace cookies
-        already in the jar with new ones.
-    :rtype: CookieJar
-    """
-    if cookiejar is None:
-        cookiejar = RequestsCookieJar()
-
-    if cookie_dict is not None:
-        names_from_jar = [cookie.name for cookie in cookiejar]
-        for name in cookie_dict:
-            if overwrite or (name not in names_from_jar):
-                cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
-
-    return cookiejar
-
-
-def merge_cookies(
-    cookiejar: CookieJar, cookies: dict[str, str] | CookieJar | None
-) -> CookieJar:
-    """Add cookies to cookiejar and returns a merged CookieJar.
-
-    :param cookiejar: CookieJar object to add the cookies to.
-    :param cookies: Dictionary or CookieJar object to be added.
-    :rtype: CookieJar
-    """
-    if not isinstance(cookiejar, cookielib.CookieJar):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard
-        raise ValueError("You can only merge into CookieJar")
-
-    if isinstance(cookies, dict):
-        cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False)
-    elif isinstance(cookies, cookielib.CookieJar):
-        if update_method := getattr(cookiejar, "update", None):
-            update_method(cookies)
-        else:
-            for cookie_in_jar in cookies:
-                cookiejar.set_cookie(cookie_in_jar)
-
-    return cookiejar
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py
deleted file mode 100644
index 936d7987a68..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/exceptions.py
+++ /dev/null
@@ -1,162 +0,0 @@
-"""
-requests.exceptions
-~~~~~~~~~~~~~~~~~~~
-
-This module contains the set of Requests' exceptions.
-"""
-
-from __future__ import annotations
-
-from typing import TYPE_CHECKING, Any
-
-from opentelemetry.agent._vendor.urllib3.exceptions import HTTPError as BaseHTTPError
-
-from .compat import JSONDecodeError as CompatJSONDecodeError
-
-if TYPE_CHECKING:
-    from .models import PreparedRequest, Request, Response
-
-
-class RequestException(IOError):
-    """There was an ambiguous exception that occurred while handling your
-    request.
-    """
-
-    response: Response | None
-    request: Request | PreparedRequest | None
-
-    def __init__(self, *args: Any, **kwargs: Any) -> None:
-        """Initialize RequestException with `request` and `response` objects."""
-        response: Response | None = kwargs.pop("response", None)
-        self.response = response
-        self.request = kwargs.pop("request", None)
-        if response is not None and not self.request and hasattr(response, "request"):
-            self.request = response.request
-        super().__init__(*args, **kwargs)
-
-
-class InvalidJSONError(RequestException):
-    """A JSON error occurred."""
-
-
-class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
-    """Couldn't decode the text into json"""
-
-    def __init__(self, *args: Any, **kwargs: Any) -> None:
-        """
-        Construct the JSONDecodeError instance first with all
-        args. Then use it's args to construct the IOError so that
-        the json specific args aren't used as IOError specific args
-        and the error message from JSONDecodeError is preserved.
-        """
-        CompatJSONDecodeError.__init__(self, *args)
-        InvalidJSONError.__init__(self, *self.args, **kwargs)
-
-    def __reduce__(self) -> tuple[Any, ...] | str:
-        """
-        The __reduce__ method called when pickling the object must
-        be the one from the JSONDecodeError (be it json/simplejson)
-        as it expects all the arguments for instantiation, not just
-        one like the IOError, and the MRO would by default call the
-        __reduce__ method from the IOError due to the inheritance order.
-        """
-        return CompatJSONDecodeError.__reduce__(self)
-
-
-class HTTPError(RequestException):
-    """An HTTP error occurred."""
-
-
-class ConnectionError(RequestException):
-    """A Connection error occurred."""
-
-
-class ProxyError(ConnectionError):
-    """A proxy error occurred."""
-
-
-class SSLError(ConnectionError):
-    """An SSL error occurred."""
-
-
-class Timeout(RequestException):
-    """The request timed out.
-
-    Catching this error will catch both
-    :exc:`~requests.exceptions.ConnectTimeout` and
-    :exc:`~requests.exceptions.ReadTimeout` errors.
-    """
-
-
-class ConnectTimeout(ConnectionError, Timeout):
-    """The request timed out while trying to connect to the remote server.
-
-    Requests that produced this error are safe to retry.
-    """
-
-
-class ReadTimeout(Timeout):
-    """The server did not send any data in the allotted amount of time."""
-
-
-class URLRequired(RequestException):
-    """A valid URL is required to make a request."""
-
-
-class TooManyRedirects(RequestException):
-    """Too many redirects."""
-
-
-class MissingSchema(RequestException, ValueError):
-    """The URL scheme (e.g. http or https) is missing."""
-
-
-class InvalidSchema(RequestException, ValueError):
-    """The URL scheme provided is either invalid or unsupported."""
-
-
-class InvalidURL(RequestException, ValueError):
-    """The URL provided was somehow invalid."""
-
-
-class InvalidHeader(RequestException, ValueError):
-    """The header value provided was somehow invalid."""
-
-
-class InvalidProxyURL(InvalidURL):
-    """The proxy URL provided is invalid."""
-
-
-class ChunkedEncodingError(RequestException):
-    """The server declared chunked encoding but sent an invalid chunk."""
-
-
-class ContentDecodingError(RequestException, BaseHTTPError):
-    """Failed to decode response content."""
-
-
-class StreamConsumedError(RequestException, TypeError):
-    """The content for this response was already consumed."""
-
-
-class RetryError(RequestException):
-    """Custom retries logic failed"""
-
-
-class UnrewindableBodyError(RequestException):
-    """Requests encountered an error when trying to rewind a body."""
-
-
-# Warnings
-
-
-class RequestsWarning(Warning):
-    """Base warning for Requests."""
-
-
-class FileModeWarning(RequestsWarning, DeprecationWarning):
-    """A file was opened in text mode, but Requests determined its binary length."""
-
-
-class RequestsDependencyWarning(RequestsWarning):
-    """An imported dependency doesn't match the expected version range."""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py
deleted file mode 100644
index 11ff9e9f27e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/hooks.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-requests.hooks
-~~~~~~~~~~~~~~
-
-This module provides the capabilities for the Requests hooks system.
-
-Available hooks:
-
-``response``:
-    The response generated from a Request.
-"""
-
-from __future__ import annotations
-
-from collections.abc import Callable, Iterable
-from typing import TYPE_CHECKING, Any
-
-if TYPE_CHECKING:
-    from . import _types as _t
-    from .models import Response
-
-HOOKS: list[str] = ["response"]
-
-
-def default_hooks() -> dict[str, list[_t.HookType]]:
-    return {event: [] for event in HOOKS}
-
-
-# TODO: response is the only one
-
-
-def dispatch_hook(
-    key: str,
-    hooks: _t.HooksInputType | None,
-    hook_data: Response,
-    **kwargs: Any,
-) -> Response:
-    """Dispatches a hook dictionary on a given piece of data."""
-    hooks_dict = hooks or {}
-    hook_list: Iterable[_t.HookType] | _t.HookType | None = hooks_dict.get(key)
-    if hook_list:
-        if isinstance(hook_list, Callable):
-            hook_list = [hook_list]
-        for hook in hook_list:
-            _hook_data = hook(hook_data, **kwargs)
-            if _hook_data is not None:
-                hook_data = _hook_data
-    return hook_data
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py
deleted file mode 100644
index 2e0ae54a07f..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/models.py
+++ /dev/null
@@ -1,1180 +0,0 @@
-"""
-requests.models
-~~~~~~~~~~~~~~~
-
-This module contains the primary objects that power Requests.
-"""
-
-from __future__ import annotations
-
-import datetime
-
-# Import encoding now, to avoid implicit import later.
-# Implicit import within threads may cause LookupError when standard library is in a ZIP,
-# such as in Embedded Python. See https://github.com/psf/requests/issues/3578.
-import encodings.idna  # noqa: F401  # type: ignore[reportUnusedImport]
-from collections.abc import Callable, Generator, Iterable, Iterator, Mapping
-from io import UnsupportedOperation
-from typing import (
-    TYPE_CHECKING,
-    Any,
-    Final,
-    Literal,
-    cast,
-    overload,
-)
-
-from opentelemetry.agent._vendor.urllib3.exceptions import (
-    DecodeError,
-    LocationParseError,
-    ProtocolError,
-    ReadTimeoutError,
-    SSLError,
-)
-from opentelemetry.agent._vendor.urllib3.fields import RequestField
-from opentelemetry.agent._vendor.urllib3.filepost import encode_multipart_formdata
-from opentelemetry.agent._vendor.urllib3.util import parse_url
-
-from ._internal_utils import to_native_string, unicode_is_ascii
-from ._types import SupportsRead as _SupportsRead
-from .auth import HTTPBasicAuth
-from .compat import (
-    JSONDecodeError,
-    basestring,
-    builtin_str,
-    chardet,
-    cookielib,
-    urlencode,
-    urlsplit,
-    urlunparse,
-)
-from .compat import json as complexjson
-from .cookies import (
-    _copy_cookie_jar,  # type: ignore[reportPrivateUsage]
-    cookiejar_from_dict,
-    get_cookie_header,
-)
-from .exceptions import (
-    ChunkedEncodingError,
-    ConnectionError,
-    ContentDecodingError,
-    HTTPError,
-    InvalidJSONError,
-    InvalidURL,
-    MissingSchema,
-    StreamConsumedError,
-)
-from .exceptions import JSONDecodeError as RequestsJSONDecodeError
-from .exceptions import SSLError as RequestsSSLError
-from .hooks import default_hooks
-from .status_codes import codes
-from .structures import CaseInsensitiveDict
-from .utils import (
-    check_header_validity,
-    get_auth_from_url,
-    guess_filename,
-    guess_json_utf,
-    iter_slices,
-    parse_header_links,
-    requote_uri,
-    stream_decode_response_unicode,
-    super_len,
-    to_key_val_list,
-)
-
-if TYPE_CHECKING:
-    from http.cookiejar import CookieJar
-
-    from opentelemetry.agent._vendor.typing_extensions import Self
-
-    from . import _types as _t
-    from .adapters import HTTPAdapter
-    from .cookies import RequestsCookieJar
-
-#: The set of HTTP status codes that indicate an automatically
-#: processable redirect.
-REDIRECT_STATI: Final[tuple[int, ...]] = (  # type: ignore[assignment]
-    codes.moved,  # 301
-    codes.found,  # 302
-    codes.other,  # 303
-    codes.temporary_redirect,  # 307
-    codes.permanent_redirect,  # 308
-)
-
-DEFAULT_REDIRECT_LIMIT: int = 30
-CONTENT_CHUNK_SIZE: int = 10 * 1024
-ITER_CHUNK_SIZE: int = 512
-
-
-class RequestEncodingMixin:
-    url: str | None
-
-    @property
-    def path_url(self) -> str:
-        """Build the path URL to use."""
-
-        url: list[str] = []
-
-        p = urlsplit(cast(str, self.url))
-
-        path = p.path
-        if not path:
-            path = "/"
-
-        url.append(path)
-
-        query = p.query
-        if query:
-            url.append("?")
-            url.append(query)
-
-        return "".join(url)
-
-    @overload
-    @staticmethod
-    def _encode_params(data: str) -> str: ...
-
-    @overload
-    @staticmethod
-    def _encode_params(data: bytes) -> bytes: ...
-
-    @overload
-    @staticmethod
-    def _encode_params(
-        data: _t.SupportsRead[str | bytes],
-    ) -> _t.SupportsRead[str | bytes]: ...
-
-    @overload
-    @staticmethod
-    def _encode_params(data: _t.KVDataType) -> str: ...
-
-    @staticmethod
-    def _encode_params(
-        data: _t.EncodableDataType,
-    ) -> str | bytes | _t.SupportsRead[str | bytes]:
-        """Encode parameters in a piece of data.
-
-        Will successfully encode parameters when passed as a dict or a list of
-        2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
-        if parameters are supplied as a dict.
-        """
-
-        if isinstance(data, (str, bytes)):
-            return data
-        elif isinstance(data, _SupportsRead):
-            return data
-        elif hasattr(data, "__iter__"):
-            result: list[tuple[bytes, bytes]] = []
-            for k, vs in to_key_val_list(data):
-                if isinstance(vs, basestring) or not hasattr(vs, "__iter__"):
-                    vs = [vs]
-                for v in vs:
-                    if v is not None:
-                        result.append(
-                            (
-                                k.encode("utf-8") if isinstance(k, str) else k,
-                                v.encode("utf-8") if isinstance(v, str) else v,
-                            )
-                        )
-            return urlencode(result, doseq=True)
-        else:
-            return data  # type: ignore[return-value]  # unreachable for valid _t.DataType
-
-    @staticmethod
-    def _encode_files(
-        files: _t.FilesType, data: _t.RawDataType | None
-    ) -> tuple[bytes, str]:
-        """Build the body for a multipart/form-data request.
-
-        Will successfully encode files when passed as a dict or a list of
-        tuples. Order is retained if data is a list of tuples but arbitrary
-        if parameters are supplied as a dict.
-        The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
-        or 4-tuples (filename, fileobj, contentype, custom_headers).
-        """
-        if not files:
-            raise ValueError("Files must be provided.")
-        elif isinstance(data, basestring):
-            raise ValueError("Data must not be a string.")
-
-        new_fields: list[RequestField | tuple[str, bytes]] = []
-        fields = to_key_val_list(data or {})
-        files = to_key_val_list(files or {})
-
-        for field, val in fields:
-            if isinstance(val, basestring) or not hasattr(val, "__iter__"):
-                val = [val]
-            for v in val:
-                if v is not None:
-                    # Don't call str() on bytestrings: in Py3 it all goes wrong.
-                    if not isinstance(v, bytes):
-                        v = str(v)
-
-                    new_fields.append(
-                        (
-                            field.decode("utf-8")
-                            if isinstance(field, bytes)
-                            else field,
-                            v.encode("utf-8") if isinstance(v, str) else v,
-                        )
-                    )
-
-        for k, v in files:
-            # support for explicit filename
-            ft = None
-            fh = None
-            if isinstance(v, (tuple, list)):
-                if len(v) == 2:
-                    fn, fp = v
-                elif len(v) == 3:
-                    fn, fp, ft = v
-                else:
-                    fn, fp, ft, fh = v
-            else:
-                fn = guess_filename(v) or k
-                fp = v
-
-            if isinstance(fp, (str, bytes, bytearray)):
-                fdata = fp
-            elif isinstance(fp, _SupportsRead):  # type: ignore[reportUnnecessaryIsInstance]  # defensive check for untyped callers
-                fdata = fp.read()
-            elif fp is None:  # type: ignore[reportUnnecessaryComparison]  # defensive check for untyped callers
-                continue
-            else:
-                fdata = fp
-
-            rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
-            rf.make_multipart(content_type=ft)
-            new_fields.append(rf)
-
-        body, content_type = encode_multipart_formdata(new_fields)
-
-        return body, content_type
-
-
-class RequestHooksMixin:
-    hooks: dict[str, list[_t.HookType]]
-
-    def register_hook(
-        self, event: str, hook: Iterable[_t.HookType] | _t.HookType
-    ) -> None:
-        """Properly register a hook."""
-
-        if event not in self.hooks:
-            raise ValueError(f'Unsupported event specified, with event name "{event}"')
-
-        if isinstance(hook, Callable):
-            self.hooks[event].append(hook)
-        elif hasattr(hook, "__iter__"):
-            self.hooks[event].extend(h for h in hook if isinstance(h, Callable))  # type: ignore[reportUnnecessaryIsInstance]  # defensive runtime filter
-
-    def deregister_hook(self, event: str, hook: _t.HookType) -> bool:
-        """Deregister a previously registered hook.
-        Returns True if the hook existed, False if not.
-        """
-
-        try:
-            self.hooks[event].remove(hook)
-            return True
-        except ValueError:
-            return False
-
-
-class Request(RequestHooksMixin):
-    """A user-created :class:`Request ` object.
-
-    Used to prepare a :class:`PreparedRequest `, which is sent to the server.
-
-    :param method: HTTP method to use.
-    :param url: URL to send.
-    :param headers: dictionary of headers to send.
-    :param files: dictionary of {filename: fileobject} files to multipart upload.
-    :param data: the body to attach to the request. If a dictionary or
-        list of tuples ``[(key, value)]`` is provided, form-encoding will
-        take place.
-    :param json: json for the body to attach to the request (if files or data is not specified).
-    :param params: URL parameters to append to the URL. If a dictionary or
-        list of tuples ``[(key, value)]`` is provided, form-encoding will
-        take place.
-    :param auth: Auth handler or (user, pass) tuple.
-    :param cookies: dictionary or CookieJar of cookies to attach to this request.
-    :param hooks: dictionary of callback hooks, for internal usage.
-
-    Usage::
-
-      >>> import requests
-      >>> req = requests.Request('GET', 'https://httpbin.org/get')
-      >>> req.prepare()
-      
-    """
-
-    method: str | None
-    url: _t.UriType | None
-    headers: Mapping[str, str | bytes]
-    files: _t.FilesType
-    data: _t.DataType
-    json: _t.JsonType
-    params: _t.ParamsType
-    auth: _t.AuthType
-    cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
-
-    def __init__(
-        self,
-        method: str | None = None,
-        url: _t.UriType | None = None,
-        headers: _t.HeadersType = None,
-        files: _t.FilesType = None,
-        data: _t.DataType = None,
-        params: _t.ParamsType = None,
-        auth: _t.AuthType = None,
-        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
-        hooks: _t.HooksInputType | None = None,
-        json: _t.JsonType = None,
-    ) -> None:
-        # Default empty dicts for dict params.
-        data = [] if data is None else data
-        files = [] if files is None else files
-        headers = {} if headers is None else headers
-        params = {} if params is None else params
-        hooks = {} if hooks is None else hooks
-
-        self.hooks = default_hooks()
-        for k, v in list(hooks.items()):
-            self.register_hook(event=k, hook=v)
-
-        self.method = method
-        self.url = url
-        self.headers = headers
-        self.files = files
-        self.data = data
-        self.json = json
-        self.params = params
-        self.auth = auth
-        self.cookies = cookies
-
-    def __repr__(self) -> str:
-        return f""
-
-    def prepare(self) -> PreparedRequest:
-        """Constructs a :class:`PreparedRequest ` for transmission and returns it."""
-        p = PreparedRequest()
-        p.prepare(
-            method=self.method,
-            url=self.url,
-            headers=self.headers,
-            files=self.files,
-            data=self.data,
-            json=self.json,
-            params=self.params,
-            auth=self.auth,
-            cookies=self.cookies,
-            hooks=self.hooks,
-        )
-        return p
-
-
-class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
-    """The fully mutable :class:`PreparedRequest ` object,
-    containing the exact bytes that will be sent to the server.
-
-    Instances are generated from a :class:`Request ` object, and
-    should not be instantiated manually; doing so may produce undesirable
-    effects.
-
-    Usage::
-
-      >>> import requests
-      >>> req = requests.Request('GET', 'https://httpbin.org/get')
-      >>> r = req.prepare()
-      >>> r
-      
-
-      >>> s = requests.Session()
-      >>> s.send(r)
-      
-    """
-
-    method: str | None
-    url: str | None
-    headers: CaseInsensitiveDict[str | bytes]
-    _cookies: RequestsCookieJar | CookieJar | None
-    body: _t.BodyType
-    hooks: dict[str, list[_t.HookType]]
-    _body_position: int | object | None
-
-    def __init__(self) -> None:
-        #: HTTP verb to send to the server.
-        self.method = None
-        #: HTTP URL to send the request to.
-        self.url = None
-        #: dictionary of HTTP headers.
-        self.headers = None  # type: ignore[assignment]
-        # The `CookieJar` used to create the Cookie header will be stored here
-        # after prepare_cookies is called
-        self._cookies = None
-        #: request body to send to the server.
-        self.body = None
-        #: dictionary of callback hooks, for internal usage.
-        self.hooks = default_hooks()
-        #: integer denoting starting position of a readable file-like body.
-        self._body_position = None
-
-    def prepare(
-        self,
-        method: str | None = None,
-        url: _t.UriType | None = None,
-        headers: Mapping[str, str | bytes] | None = None,
-        files: _t.FilesType = None,
-        data: _t.DataType = None,
-        params: _t.ParamsType = None,
-        auth: _t.AuthType = None,
-        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
-        hooks: _t.HooksInputType | None = None,
-        json: _t.JsonType = None,
-    ) -> None:
-        """Prepares the entire request with the given parameters."""
-
-        url = cast("_t.UriType", url)
-        self.prepare_method(method)
-        self.prepare_url(url, params)
-        self.prepare_headers(headers)
-        self.prepare_cookies(cookies)
-        self.prepare_body(data, files, json)
-        self.prepare_auth(auth, url)
-
-        # Note that prepare_auth must be last to enable authentication schemes
-        # such as OAuth to work on a fully prepared request.
-
-        # This MUST go after prepare_auth. Authenticators could add a hook
-        self.prepare_hooks(hooks)
-
-    def __repr__(self) -> str:
-        return f""
-
-    def copy(self) -> PreparedRequest:
-        p = PreparedRequest()
-        p.method = self.method
-        p.url = self.url
-        p.headers = self.headers.copy() if self.headers is not None else None  # type: ignore[assignment]
-        p._cookies = _copy_cookie_jar(self._cookies)
-        p.body = self.body
-        p.hooks = self.hooks
-        p._body_position = self._body_position
-        return p
-
-    def prepare_method(self, method: str | None) -> None:
-        """Prepares the given HTTP method."""
-        self.method = method
-        if self.method is not None:
-            self.method = to_native_string(self.method.upper())
-
-    @staticmethod
-    def _get_idna_encoded_host(host: str) -> str:
-        from opentelemetry.agent._vendor import idna
-
-        try:
-            host = idna.encode(host, uts46=True).decode("utf-8")
-        except idna.IDNAError:
-            raise UnicodeError
-        return host
-
-    def prepare_url(
-        self,
-        url: _t.UriType,
-        params: _t.ParamsType,
-    ) -> None:
-        """Prepares the given HTTP URL."""
-        #: Accept objects that have string representations.
-        #: We're unable to blindly call unicode/str functions
-        #: as this will include the bytestring indicator (b'')
-        #: on python 3.x.
-        #: https://github.com/psf/requests/pull/2238
-        if isinstance(url, bytes):
-            url = url.decode("utf8")
-        else:
-            url = str(url)
-
-        # Remove leading whitespaces from url
-        url = url.lstrip()
-
-        # Don't do any URL preparation for non-HTTP schemes like `mailto`,
-        # `data` etc to work around exceptions from `url_parse`, which
-        # handles RFC 3986 only.
-        if ":" in url and not url.lower().startswith("http"):
-            self.url = url
-            return
-
-        # Support for unicode domain names and paths.
-        try:
-            scheme, auth, host, port, path, query, fragment = parse_url(url)
-        except LocationParseError as e:
-            raise InvalidURL(*e.args)
-
-        if not scheme:
-            raise MissingSchema(
-                f"Invalid URL {url!r}: No scheme supplied. "
-                f"Perhaps you meant https://{url}?"
-            )
-
-        if not host:
-            raise InvalidURL(f"Invalid URL {url!r}: No host supplied")
-
-        # In general, we want to try IDNA encoding the hostname if the string contains
-        # non-ASCII characters. This allows users to automatically get the correct IDNA
-        # behaviour. For strings containing only ASCII characters, we need to also verify
-        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
-        if not unicode_is_ascii(host):
-            try:
-                host = self._get_idna_encoded_host(host)
-            except UnicodeError:
-                raise InvalidURL("URL has an invalid label.")
-        elif host.startswith(("*", ".")):
-            raise InvalidURL("URL has an invalid label.")
-
-        # Carefully reconstruct the network location
-        netloc = auth or ""
-        if netloc:
-            netloc += "@"
-        netloc += host
-        if port:
-            netloc += f":{port}"
-
-        # Bare domains aren't valid URLs.
-        if not path:
-            path = "/"
-
-        if isinstance(params, (str, bytes)):
-            params = to_native_string(params)
-
-        if params is not None:
-            enc_params = self._encode_params(params)
-        else:
-            enc_params = ""
-
-        if enc_params:
-            if query:
-                query = f"{query}&{enc_params}"
-            else:
-                query = enc_params
-
-        url = requote_uri(urlunparse((scheme, netloc, path, "", query, fragment)))
-        self.url = url
-
-    def prepare_headers(self, headers: Mapping[str, str | bytes] | None) -> None:
-        """Prepares the given HTTP headers."""
-
-        self.headers = CaseInsensitiveDict()
-        if headers:
-            for header in headers.items():
-                # Raise exception on invalid header value.
-                check_header_validity(header)
-                name, value = header
-                self.headers[to_native_string(name)] = value
-
-    def prepare_body(
-        self, data: _t.DataType, files: _t.FilesType, json: _t.JsonType = None
-    ) -> None:
-        """Prepares the given HTTP body data."""
-
-        # Check if file, fo, generator, iterator.
-        # If not, run through normal process.
-
-        # Nottin' on you.
-        body = None
-        content_type = None
-
-        if not data and json is not None:
-            # urllib3 requires a bytes-like body. Python 2's json.dumps
-            # provides this natively, but Python 3 gives a Unicode string.
-            content_type = "application/json"
-
-            try:
-                body = complexjson.dumps(json, allow_nan=False)
-            except ValueError as ve:
-                raise InvalidJSONError(ve, request=self)
-
-            if not isinstance(body, bytes):
-                body = body.encode("utf-8")
-
-        # data that proxies attributes to underlying objects needs hasattr
-        is_iterable = isinstance(data, Iterable) or hasattr(data, "__iter__")
-        if is_iterable and not isinstance(data, (str, bytes, list, tuple, Mapping)):
-            try:
-                length = super_len(data)
-            except (TypeError, AttributeError, UnsupportedOperation):
-                length = None
-
-            body = data
-
-            if getattr(body, "tell", None) is not None:
-                # Record the current file position before reading.
-                # This will allow us to rewind a file in the event
-                # of a redirect.
-                try:
-                    self._body_position = body.tell()  # type: ignore[union-attr]  # guarded by getattr check
-                except OSError:
-                    # This differentiates from None, allowing us to catch
-                    # a failed `tell()` later when trying to rewind the body
-                    self._body_position = object()
-
-            if files:
-                raise NotImplementedError(
-                    "Streamed bodies and files are mutually exclusive."
-                )
-
-            if length:
-                self.headers["Content-Length"] = builtin_str(length)
-            else:
-                self.headers["Transfer-Encoding"] = "chunked"
-        else:
-            # After is_stream filtering, remaining data is raw (not streamed)
-            raw_data = cast("_t.RawDataType | None", data)
-
-            # Multi-part file uploads.
-            if files:
-                (body, content_type) = self._encode_files(files, raw_data)
-            else:
-                if raw_data:
-                    body = self._encode_params(raw_data)
-                    if isinstance(data, basestring) or isinstance(data, _SupportsRead):
-                        content_type = None
-                    else:
-                        content_type = "application/x-www-form-urlencoded"
-
-            self.prepare_content_length(body)
-
-            # Add content-type if it wasn't explicitly provided.
-            if content_type and ("content-type" not in self.headers):
-                self.headers["Content-Type"] = content_type
-
-        self.body = body  # type: ignore[assignment]  # body transforms from DataType to BodyType
-
-    def prepare_content_length(self, body: _t.BodyType) -> None:
-        """Prepare Content-Length header based on request method and body"""
-        if body is not None:
-            length = super_len(body)
-            if length:
-                # If length exists, set it. Otherwise, we fallback
-                # to Transfer-Encoding: chunked.
-                self.headers["Content-Length"] = builtin_str(length)
-        elif (
-            self.method not in ("GET", "HEAD")
-            and self.headers.get("Content-Length") is None
-        ):
-            # Set Content-Length to 0 for methods that can have a body
-            # but don't provide one. (i.e. not GET or HEAD)
-            self.headers["Content-Length"] = "0"
-
-    def prepare_auth(
-        self,
-        auth: _t.AuthType,
-        url: _t.UriType = "",
-    ) -> None:
-        """Prepares the given HTTP auth data."""
-
-        # If no Auth is explicitly provided, extract it from the URL first.
-        if auth is None:
-            url_auth = get_auth_from_url(cast(str, self.url))
-            auth = url_auth if any(url_auth) else None
-
-        if auth:
-            if isinstance(auth, tuple) and len(auth) == 2:  # type: ignore[arg-type]  # pyright widens tuple from Callable in AuthType
-                # special-case basic HTTP auth
-                auth_handler = HTTPBasicAuth(*auth)  # type: ignore[arg-type]  # pyright widens tuple from Callable in AuthType
-            else:
-                # TODO: can be fixed by flipping the conditionals
-                auth_handler = cast("Callable[..., PreparedRequest]", auth)
-
-            # Allow auth to make its changes.
-            r = auth_handler(self)
-
-            # Update self to reflect the auth changes.
-            self.__dict__.update(r.__dict__)
-
-            # Recompute Content-Length
-            self.prepare_content_length(self.body)
-
-    def prepare_cookies(
-        self, cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
-    ) -> None:
-        """Prepares the given HTTP cookie data.
-
-        This function eventually generates a ``Cookie`` header from the
-        given cookies using cookielib. Due to cookielib's design, the header
-        will not be regenerated if it already exists, meaning this function
-        can only be called once for the life of the
-        :class:`PreparedRequest ` object. Any subsequent calls
-        to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
-        header is removed beforehand.
-        """
-        if isinstance(cookies, cookielib.CookieJar):
-            self._cookies = cookies
-        else:
-            self._cookies = cookiejar_from_dict(cookies)
-
-        cookies_jar = cast("CookieJar", self._cookies)
-        cookie_header = get_cookie_header(cookies_jar, self)
-        if cookie_header is not None:
-            self.headers["Cookie"] = cookie_header
-
-    def prepare_hooks(self, hooks: _t.HooksInputType | None) -> None:
-        """Prepares the given hooks."""
-        # hooks can be passed as None to the prepare method and to this
-        # method. To prevent iterating over None, simply use an empty list
-        # if hooks is False-y
-        hooks = hooks or {}
-        for event in hooks:
-            self.register_hook(event, hooks[event])
-
-
-class Response:
-    """The :class:`Response ` object, which contains a
-    server's response to an HTTP request.
-    """
-
-    _content: bytes | Literal[False] | None
-    _content_consumed: bool
-    _next: PreparedRequest | None
-    status_code: int
-    headers: CaseInsensitiveDict[str]
-    raw: Any
-    url: str
-    encoding: str | None
-    history: list[Response]
-    reason: str
-    cookies: RequestsCookieJar
-    elapsed: datetime.timedelta
-    request: PreparedRequest
-    connection: HTTPAdapter
-
-    __attrs__: list[str] = [
-        "_content",
-        "status_code",
-        "headers",
-        "url",
-        "history",
-        "encoding",
-        "reason",
-        "cookies",
-        "elapsed",
-        "request",
-    ]
-
-    def __init__(self) -> None:
-        self._content = False
-        self._content_consumed = False
-        self._next = None
-
-        #: Integer Code of responded HTTP Status, e.g. 404 or 200.
-        self.status_code = None  # type: ignore[assignment]
-
-        #: Case-insensitive Dictionary of Response Headers.
-        #: For example, ``headers['content-encoding']`` will return the
-        #: value of a ``'Content-Encoding'`` response header.
-        self.headers = CaseInsensitiveDict()
-
-        #: File-like object representation of response (for advanced usage).
-        #: Use of ``raw`` requires that ``stream=True`` be set on the request.
-        #: This requirement does not apply for use internally to Requests.
-        self.raw = None
-
-        #: Final URL location of Response.
-        self.url = None  # type: ignore[assignment]
-
-        #: Encoding to decode with when accessing r.text.
-        self.encoding = None
-
-        #: A list of :class:`Response ` objects from
-        #: the history of the Request. Any redirect responses will end
-        #: up here. The list is sorted from the oldest to the most recent request.
-        self.history = []
-
-        #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK".
-        self.reason = None  # type: ignore[assignment]
-
-        #: A CookieJar of Cookies the server sent back.
-        self.cookies = cookiejar_from_dict({})
-
-        #: The amount of time elapsed between sending the request
-        #: and the arrival of the response (as a timedelta).
-        #: This property specifically measures the time taken between sending
-        #: the first byte of the request and finishing parsing the headers. It
-        #: is therefore unaffected by consuming the response content or the
-        #: value of the ``stream`` keyword argument.
-        self.elapsed = datetime.timedelta(0)
-
-        #: The :class:`PreparedRequest ` object to which this
-        #: is a response.
-        self.request = None  # type: ignore[assignment]
-
-    def __enter__(self) -> Self:
-        return self
-
-    def __exit__(self, *args: Any) -> None:
-        self.close()
-
-    def __getstate__(self) -> dict[str, Any]:
-        # Consume everything; accessing the content attribute makes
-        # sure the content has been fully read.
-        if not self._content_consumed:
-            self.content
-
-        return {attr: getattr(self, attr, None) for attr in self.__attrs__}
-
-    def __setstate__(self, state: dict[str, Any]) -> None:
-        for name, value in state.items():
-            setattr(self, name, value)
-
-        # pickled objects do not have .raw
-        setattr(self, "_content_consumed", True)
-        setattr(self, "raw", None)
-
-    def __repr__(self) -> str:
-        return f""
-
-    def __bool__(self) -> bool:
-        """Returns True if :attr:`status_code` is less than 400.
-
-        This attribute checks if the status code of the response is between
-        400 and 600 to see if there was a client error or a server error. If
-        the status code, is between 200 and 400, this will return True. This
-        is **not** a check to see if the response code is ``200 OK``.
-        """
-        return self.ok
-
-    def __nonzero__(self) -> bool:
-        """Returns True if :attr:`status_code` is less than 400.
-
-        This attribute checks if the status code of the response is between
-        400 and 600 to see if there was a client error or a server error. If
-        the status code, is between 200 and 400, this will return True. This
-        is **not** a check to see if the response code is ``200 OK``.
-        """
-        return self.ok
-
-    def __iter__(self) -> Iterator[bytes]:
-        """Allows you to use a response as an iterator."""
-        return self.iter_content(128)
-
-    @property
-    def ok(self) -> bool:
-        """Returns True if :attr:`status_code` is less than 400, False if not.
-
-        This attribute checks if the status code of the response is between
-        400 and 600 to see if there was a client error or a server error. If
-        the status code is between 200 and 400, this will return True. This
-        is **not** a check to see if the response code is ``200 OK``.
-        """
-        try:
-            self.raise_for_status()
-        except HTTPError:
-            return False
-        return True
-
-    @property
-    def is_redirect(self) -> bool:
-        """True if this Response is a well-formed HTTP redirect that could have
-        been processed automatically (by :meth:`Session.resolve_redirects`).
-        """
-        return "location" in self.headers and self.status_code in REDIRECT_STATI
-
-    @property
-    def is_permanent_redirect(self) -> bool:
-        """True if this Response one of the permanent versions of redirect."""
-        return "location" in self.headers and self.status_code in (
-            codes.moved_permanently,
-            codes.permanent_redirect,
-        )
-
-    @property
-    def next(self) -> PreparedRequest | None:
-        """Returns a PreparedRequest for the next request in a redirect chain, if there is one."""
-        return self._next
-
-    @property
-    def apparent_encoding(self) -> str | None:
-        """The apparent encoding, provided by the charset_normalizer or chardet libraries."""
-        if chardet is not None:
-            return chardet.detect(self.content)["encoding"]
-        else:
-            # If no character detection library is available, we'll fall back
-            # to a standard Python utf-8 str.
-            return "utf-8"
-
-    @overload
-    def iter_content(
-        self, chunk_size: int | None = 1, decode_unicode: Literal[False] = False
-    ) -> Iterator[bytes]: ...
-    @overload
-    def iter_content(
-        self, chunk_size: int | None = 1, *, decode_unicode: Literal[True]
-    ) -> Iterator[str | bytes]: ...
-    def iter_content(
-        self, chunk_size: int | None = 1, decode_unicode: bool = False
-    ) -> Iterator[str | bytes]:
-        """Iterates over the response data.  When stream=True is set on the
-        request, this avoids reading the content at once into memory for
-        large responses.  The chunk size is the number of bytes it should
-        read into memory.  This is not necessarily the length of each item
-        returned as decoding can take place.
-
-        chunk_size must be of type int or None. A value of None will
-        function differently depending on the value of `stream`.
-        stream=True will read data as it arrives in whatever size the
-        chunks are received. If stream=False, data is returned as
-        a single chunk.
-
-        If decode_unicode is True, content will be decoded using encoding
-        information from the response. If no encoding information is available,
-        bytes will be returned. This can be bypassed by manually setting
-        `encoding` on the response.
-        """
-
-        def generate() -> Generator[bytes, None, None]:
-            # Special case for urllib3.
-            if hasattr(self.raw, "stream"):
-                try:
-                    yield from self.raw.stream(chunk_size, decode_content=True)
-                except ProtocolError as e:
-                    raise ChunkedEncodingError(e)
-                except DecodeError as e:
-                    raise ContentDecodingError(e)
-                except ReadTimeoutError as e:
-                    raise ConnectionError(e)
-                except SSLError as e:
-                    raise RequestsSSLError(e)
-            else:
-                # Standard file-like object.
-                while True:
-                    chunk = self.raw.read(chunk_size)
-                    if not chunk:
-                        break
-                    yield chunk
-
-            self._content_consumed = True
-
-        if self._content_consumed and isinstance(self._content, bool):
-            raise StreamConsumedError()
-        elif chunk_size is not None and not isinstance(chunk_size, int):  # type: ignore[reportUnnecessaryIsInstance]  # runtime guard for untyped callers
-            raise TypeError(
-                f"chunk_size must be an int, it is instead a {type(chunk_size)}."
-            )
-
-        if self._content_consumed:
-            # simulate reading small chunks of the content
-            content = cast(bytes, self._content)
-            chunks = iter_slices(content, chunk_size)
-        else:
-            chunks = generate()
-
-        if decode_unicode:
-            chunks = stream_decode_response_unicode(chunks, self)
-
-        return chunks
-
-    @overload
-    def iter_lines(
-        self,
-        chunk_size: int = ITER_CHUNK_SIZE,
-        decode_unicode: Literal[False] = False,
-        delimiter: bytes | None = None,
-    ) -> Iterator[bytes]: ...
-    @overload
-    def iter_lines(
-        self,
-        chunk_size: int = ITER_CHUNK_SIZE,
-        *,
-        decode_unicode: Literal[True],
-        delimiter: str | bytes | None = None,
-    ) -> Iterator[str | bytes]: ...
-    def iter_lines(
-        self,
-        chunk_size: int = ITER_CHUNK_SIZE,
-        decode_unicode: bool = False,
-        delimiter: str | bytes | None = None,
-    ) -> Iterator[str | bytes]:
-        """Iterates over the response data, one line at a time.  When
-        stream=True is set on the request, this avoids reading the
-        content at once into memory for large responses.
-
-        The decode_unicode param works the same as in `iter_content`, with the
-        same caveats.
-
-        .. note:: This method is not reentrant safe.
-        """
-
-        pending: str | bytes | None = None
-
-        for chunk in self.iter_content(
-            chunk_size=chunk_size, decode_unicode=decode_unicode
-        ):
-            if pending is not None:
-                # TODO: remove cast after iter_lines rewrite
-                chunk = cast("str | bytes", pending + chunk)  # type: ignore[operator]
-
-            if delimiter:
-                lines = chunk.split(delimiter)  # type: ignore[arg-type]
-            else:
-                lines = chunk.splitlines()
-
-            if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
-                pending = lines.pop()
-            else:
-                pending = None
-
-            yield from lines
-
-        if pending is not None:
-            yield pending
-
-    @property
-    def content(self) -> bytes:
-        """Content of the response, in bytes."""
-
-        if self._content is False:
-            # Read the contents.
-            if self._content_consumed:
-                raise RuntimeError("The content for this response was already consumed")
-
-            if self.status_code == 0 or self.raw is None:
-                self._content = None
-            else:
-                self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
-
-        self._content_consumed = True
-        # don't need to release the connection; that's been handled by urllib3
-        # since we exhausted the data.
-        return self._content  # type: ignore[return-value]
-
-    @property
-    def text(self) -> str:
-        """Content of the response, in unicode.
-
-        If Response.encoding is None, encoding will be guessed using
-        ``charset_normalizer`` or ``chardet``.
-
-        The encoding of the response content is determined based solely on HTTP
-        headers, following RFC 2616 to the letter. If you can take advantage of
-        non-HTTP knowledge to make a better guess at the encoding, you should
-        set ``r.encoding`` appropriately before accessing this property.
-        """
-
-        # Try charset from content-type
-        content = None
-        encoding = self.encoding
-
-        if not self.content:
-            return ""
-
-        # Fallback to auto-detected encoding.
-        if self.encoding is None:
-            encoding = self.apparent_encoding
-
-        # Decode unicode from given encoding.
-        try:
-            content = str(self.content, encoding or "utf-8", errors="replace")
-        except (LookupError, TypeError):
-            # A LookupError is raised if the encoding was not found which could
-            # indicate a misspelling or similar mistake.
-            #
-            # A TypeError can be raised if encoding is None
-            #
-            # So we try blindly encoding.
-            content = str(self.content, errors="replace")
-
-        return content
-
-    def json(self, **kwargs: Any) -> Any:
-        r"""Decodes the JSON response body (if any) as a Python object.
-
-        This may return a dictionary, list, etc. depending on what is in the response.
-
-        :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
-        :raises requests.exceptions.JSONDecodeError: If the response body does not
-            contain valid json.
-        """
-
-        if not self.encoding and self.content and len(self.content) > 3:
-            # No encoding set. JSON RFC 4627 section 3 states we should expect
-            # UTF-8, -16 or -32. Detect which one to use; If the detection or
-            # decoding fails, fall back to `self.text` (using charset_normalizer to make
-            # a best guess).
-            encoding = guess_json_utf(self.content)
-            if encoding is not None:
-                try:
-                    return complexjson.loads(self.content.decode(encoding), **kwargs)
-                except UnicodeDecodeError:
-                    # Wrong UTF codec detected; usually because it's not UTF-8
-                    # but some other 8-bit codec.  This is an RFC violation,
-                    # and the server didn't bother to tell us what codec *was*
-                    # used.
-                    pass
-                except JSONDecodeError as e:
-                    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
-
-        try:
-            return complexjson.loads(self.text, **kwargs)
-        except JSONDecodeError as e:
-            # Catch JSON-related errors and raise as requests.JSONDecodeError
-            # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
-            raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
-
-    @property
-    def links(self) -> dict[str, dict[str, str]]:
-        """Returns the parsed header links of the response, if any."""
-
-        header = self.headers.get("link")
-
-        resolved_links: dict[str, dict[str, str]] = {}
-
-        if header:
-            links = parse_header_links(header)
-
-            for link in links:
-                key = link.get("rel") or link.get("url")
-                if key is not None:
-                    resolved_links[key] = link
-
-        return resolved_links
-
-    def raise_for_status(self) -> None:
-        """Raises :class:`HTTPError`, if one occurred."""
-
-        http_error_msg = ""
-        if isinstance(self.reason, bytes):
-            # We attempt to decode utf-8 first because some servers
-            # choose to localize their reason strings. If the string
-            # isn't utf-8, we fall back to iso-8859-1 for all other
-            # encodings. (See PR #3538)
-            try:
-                reason = self.reason.decode("utf-8")
-            except UnicodeDecodeError:
-                reason = self.reason.decode("iso-8859-1")
-        else:
-            reason = self.reason
-
-        if 400 <= self.status_code < 500:
-            http_error_msg = (
-                f"{self.status_code} Client Error: {reason} for url: {self.url}"
-            )
-
-        elif 500 <= self.status_code < 600:
-            http_error_msg = (
-                f"{self.status_code} Server Error: {reason} for url: {self.url}"
-            )
-
-        if http_error_msg:
-            raise HTTPError(http_error_msg, response=self)
-
-    def close(self) -> None:
-        """Releases the connection back to the pool. Once this method has been
-        called the underlying ``raw`` object must not be accessed again.
-
-        *Note: Should not normally need to be called explicitly.*
-        """
-        if not self._content_consumed:
-            self.raw.close()
-
-        release_conn = getattr(self.raw, "release_conn", None)
-        if release_conn is not None:
-            release_conn()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py
deleted file mode 100644
index e183060ee4b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/packages.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# The upstream module imports urllib3, idna and chardet by their top-level names and
-# registers them as `requests.packages.*` in the global sys.modules. In the vendored copy
-# that would load (and alias) the application's own packages, so the backwards
-# compatibility aliases are disabled.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py
deleted file mode 100644
index d0e28e39d4a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/sessions.py
+++ /dev/null
@@ -1,920 +0,0 @@
-"""
-requests.sessions
-~~~~~~~~~~~~~~~~~
-
-This module provides a Session object to manage and persist settings across
-requests (cookies, auth, proxies).
-"""
-
-from __future__ import annotations
-
-import os
-import sys
-import time
-from collections import OrderedDict
-from collections.abc import Generator, Mapping, MutableMapping
-from datetime import timedelta
-from typing import TYPE_CHECKING, Any, cast
-
-from ._internal_utils import to_native_string
-from ._types import is_prepared as _is_prepared
-from .adapters import HTTPAdapter
-from .auth import _basic_auth_str  # type: ignore[reportPrivateUsage]
-from .compat import cookielib, urljoin, urlparse
-from .cookies import (
-    RequestsCookieJar,
-    cookiejar_from_dict,
-    extract_cookies_to_jar,
-    merge_cookies,
-)
-from .exceptions import (
-    ChunkedEncodingError,
-    ContentDecodingError,
-    InvalidSchema,
-    TooManyRedirects,
-)
-from .hooks import default_hooks, dispatch_hook
-
-# formerly defined here, reexposed here for backward compatibility
-from .models import (  # noqa: F401
-    DEFAULT_REDIRECT_LIMIT,
-    REDIRECT_STATI,  # type: ignore[reportUnusedImport]
-    PreparedRequest,
-    Request,
-    Response,
-)
-from .status_codes import codes
-from .structures import CaseInsensitiveDict
-from .utils import (  # noqa: F401
-    DEFAULT_PORTS,
-    default_headers,
-    get_auth_from_url,
-    get_environ_proxies,
-    get_netrc_auth,
-    requote_uri,
-    resolve_proxies,
-    rewind_body,
-    should_bypass_proxies,  # type: ignore[reportUnusedImport]  # re-export for external consumers
-    to_key_val_list,
-)
-
-if TYPE_CHECKING:
-    from http.cookiejar import CookieJar
-
-    from opentelemetry.agent._vendor.typing_extensions import Self, Unpack
-
-    from . import _types as _t
-    from .adapters import BaseAdapter
-
-# Preferred clock, based on which one is more accurate on a given system.
-if sys.platform == "win32":
-    preferred_clock = time.perf_counter
-else:
-    preferred_clock = time.time
-
-
-def merge_setting(
-    request_setting: Any, session_setting: Any, dict_class: type = OrderedDict
-) -> Any:
-    """Determines appropriate setting for a given request, taking into account
-    the explicit setting on that request, and the setting in the session. If a
-    setting is a dictionary, they will be merged together using `dict_class`
-    """
-
-    if session_setting is None:
-        return request_setting
-
-    if request_setting is None:
-        return session_setting
-
-    # Bypass if not a dictionary (e.g. verify)
-    if not (
-        isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
-    ):
-        return request_setting
-
-    merged_setting = dict_class(to_key_val_list(session_setting))  # type: ignore[arg-type]  # isinstance narrows Any to Mapping[Unknown]
-    merged_setting.update(to_key_val_list(request_setting))  # type: ignore[arg-type]
-
-    # Remove keys that are set to None. Extract keys first to avoid altering
-    # the dictionary during iteration.
-    none_keys = [k for (k, v) in merged_setting.items() if v is None]
-    for key in none_keys:
-        del merged_setting[key]
-
-    return merged_setting
-
-
-def merge_hooks(
-    request_hooks: _t.HooksType,
-    session_hooks: _t.HooksType,
-    dict_class: type = OrderedDict,
-) -> _t.HooksType:
-    """Properly merges both requests and session hooks.
-
-    This is necessary because when request_hooks == {'response': []}, the
-    merge breaks Session hooks entirely.
-    """
-    if session_hooks is None or session_hooks.get("response") == []:
-        return request_hooks
-
-    if request_hooks is None or request_hooks.get("response") == []:
-        return session_hooks
-
-    return merge_setting(request_hooks, session_hooks, dict_class)
-
-
-class SessionRedirectMixin:
-    max_redirects: int
-    trust_env: bool
-    cookies: RequestsCookieJar
-
-    def send(self, request: PreparedRequest, **kwargs: Any) -> Response: ...
-
-    def get_redirect_target(self, resp: Response) -> str | None:
-        """Receives a Response. Returns a redirect URI or ``None``"""
-        # Due to the nature of how requests processes redirects this method will
-        # be called at least once upon the original response and at least twice
-        # on each subsequent redirect response (if any).
-        # If a custom mixin is used to handle this logic, it may be advantageous
-        # to cache the redirect location onto the response object as a private
-        # attribute.
-        if resp.is_redirect:
-            location = resp.headers["location"]
-            # Currently the underlying http module on py3 decode headers
-            # in latin1, but empirical evidence suggests that latin1 is very
-            # rarely used with non-ASCII characters in HTTP headers.
-            # It is more likely to get UTF8 header rather than latin1.
-            # This causes incorrect handling of UTF8 encoded location headers.
-            # To solve this, we re-encode the location in latin1.
-            location = location.encode("latin1")
-            return to_native_string(location, "utf8")
-        return None
-
-    def should_strip_auth(self, old_url: str, new_url: str) -> bool:
-        """Decide whether Authorization header should be removed when redirecting"""
-        old_parsed = urlparse(old_url)
-        new_parsed = urlparse(new_url)
-        if old_parsed.hostname != new_parsed.hostname:
-            return True
-        # Special case: allow http -> https redirect when using the standard
-        # ports. This isn't specified by RFC 7235, but is kept to avoid
-        # breaking backwards compatibility with older versions of requests
-        # that allowed any redirects on the same host.
-        if (
-            old_parsed.scheme == "http"
-            and old_parsed.port in (80, None)
-            and new_parsed.scheme == "https"
-            and new_parsed.port in (443, None)
-        ):
-            return False
-
-        # Handle default port usage corresponding to scheme.
-        changed_port = old_parsed.port != new_parsed.port
-        changed_scheme = old_parsed.scheme != new_parsed.scheme
-        default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)
-        if (
-            not changed_scheme
-            and old_parsed.port in default_port
-            and new_parsed.port in default_port
-        ):
-            return False
-
-        # Standard case: root URI must match
-        return changed_port or changed_scheme
-
-    def resolve_redirects(
-        self,
-        resp: Response,
-        req: PreparedRequest,
-        stream: bool = False,
-        timeout: _t.TimeoutType = None,
-        verify: _t.VerifyType = True,
-        cert: _t.CertType = None,
-        proxies: dict[str, str] | None = None,
-        yield_requests: bool = False,
-        **adapter_kwargs: Any,
-    ) -> Generator[Response, None, None]:
-        """Receives a Response. Returns a generator of Responses or Requests."""
-
-        hist: list[Response] = []  # keep track of history
-
-        url = self.get_redirect_target(resp)
-        previous_fragment = urlparse(req.url).fragment
-        while url:
-            prepared_request = req.copy()
-
-            # Update history and keep track of redirects.
-            resp.history = hist[:]
-            hist.append(resp)
-
-            try:
-                resp.content  # Consume socket so it can be released
-            except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
-                resp.raw.read(decode_content=False)
-
-            if len(resp.history) >= self.max_redirects:
-                raise TooManyRedirects(
-                    f"Exceeded {self.max_redirects} redirects.", response=resp
-                )
-
-            # Release the connection back into the pool.
-            resp.close()
-
-            # Handle redirection without scheme (see: RFC 1808 Section 4)
-            if url.startswith("//"):
-                parsed_rurl = urlparse(resp.url)
-                url = ":".join([to_native_string(parsed_rurl.scheme), url])
-
-            # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
-            parsed = urlparse(url)
-            if parsed.fragment == "" and previous_fragment:
-                parsed = parsed._replace(fragment=previous_fragment)
-            elif parsed.fragment:
-                previous_fragment = parsed.fragment
-            url = parsed.geturl()
-
-            # Facilitate relative 'location' headers, as allowed by RFC 7231.
-            # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
-            # Compliant with RFC3986, we percent encode the url.
-            if not parsed.netloc:
-                url = urljoin(resp.url, requote_uri(url))
-            else:
-                url = requote_uri(url)
-
-            prepared_request.url = to_native_string(url)
-
-            self.rebuild_method(prepared_request, resp)
-
-            # https://github.com/psf/requests/issues/1084
-            if resp.status_code not in (
-                codes.temporary_redirect,
-                codes.permanent_redirect,
-            ):
-                # https://github.com/psf/requests/issues/3490
-                purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding")
-                for header in purged_headers:
-                    prepared_request.headers.pop(header, None)
-                prepared_request.body = None
-
-            headers = prepared_request.headers
-            headers.pop("Cookie", None)
-
-            # Extract any cookies sent on the response to the cookiejar
-            # in the new request. Because we've mutated our copied prepared
-            # request, use the old one that we haven't yet touched.
-            cookie_jar = cast("CookieJar", prepared_request._cookies)  # type: ignore[reportPrivateUsage]
-            extract_cookies_to_jar(cookie_jar, req, resp.raw)
-            merge_cookies(cookie_jar, self.cookies)
-            prepared_request.prepare_cookies(cookie_jar)
-
-            # Rebuild auth and proxy information.
-            proxies = self.rebuild_proxies(prepared_request, proxies)
-            self.rebuild_auth(prepared_request, resp)
-
-            # A failed tell() sets `_body_position` to `object()`. This non-None
-            # value ensures `rewindable` will be True, allowing us to raise an
-            # UnrewindableBodyError, instead of hanging the connection.
-            rewindable = prepared_request._body_position is not None and (  # type: ignore[reportPrivateUsage]
-                "Content-Length" in headers or "Transfer-Encoding" in headers
-            )
-
-            # Attempt to rewind consumed file-like object.
-            if rewindable:
-                rewind_body(prepared_request)
-
-            # Override the original request.
-            req = prepared_request
-
-            if yield_requests:
-                yield req  # type: ignore[misc]  # Internal use only, returns PreparedRequest
-            else:
-                resp = self.send(
-                    req,
-                    stream=stream,
-                    timeout=timeout,
-                    verify=verify,
-                    cert=cert,
-                    proxies=proxies,
-                    allow_redirects=False,
-                    **adapter_kwargs,
-                )
-
-                extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
-
-                # extract redirect url, if any, for the next loop
-                url = self.get_redirect_target(resp)
-                yield resp
-
-    def rebuild_auth(
-        self, prepared_request: PreparedRequest, response: Response
-    ) -> None:
-        """When being redirected we may want to strip authentication from the
-        request to avoid leaking credentials. This method intelligently removes
-        and reapplies authentication where possible to avoid credential loss.
-        """
-        original_request = response.request
-        assert _is_prepared(original_request)
-        assert _is_prepared(prepared_request)
-
-        headers = prepared_request.headers
-        original_url = original_request.url
-        url = prepared_request.url
-
-        if "Authorization" in headers and self.should_strip_auth(original_url, url):
-            # If we get redirected to a new host, we should strip out any
-            # authentication headers.
-            del headers["Authorization"]
-
-        # .netrc might have more auth for us on our new host.
-        new_auth = get_netrc_auth(url) if self.trust_env else None
-        if new_auth is not None:
-            prepared_request.prepare_auth(new_auth)
-
-    def rebuild_proxies(
-        self,
-        prepared_request: PreparedRequest,
-        proxies: dict[str, str] | None,
-    ) -> dict[str, str]:
-        """This method re-evaluates the proxy configuration by considering the
-        environment variables. If we are redirected to a URL covered by
-        NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
-        proxy keys for this URL (in case they were stripped by a previous
-        redirect).
-
-        This method also replaces the Proxy-Authorization header where
-        necessary.
-
-        :rtype: dict
-        """
-        assert _is_prepared(prepared_request)
-        headers = prepared_request.headers
-        scheme = urlparse(prepared_request.url).scheme
-        new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
-
-        if "Proxy-Authorization" in headers:
-            del headers["Proxy-Authorization"]
-
-        try:
-            username, password = get_auth_from_url(new_proxies[scheme])
-        except KeyError:
-            username, password = None, None
-
-        # urllib3 handles proxy authorization for us in the standard adapter.
-        # Avoid appending this to TLS tunneled requests where it may be leaked.
-        if not scheme.startswith("https") and username and password:
-            headers["Proxy-Authorization"] = _basic_auth_str(username, password)
-
-        return new_proxies
-
-    def rebuild_method(
-        self, prepared_request: PreparedRequest, response: Response
-    ) -> None:
-        """When being redirected we may want to change the method of the request
-        based on certain specs or browser behavior.
-        """
-        method = prepared_request.method
-
-        # https://tools.ietf.org/html/rfc7231#section-6.4.4
-        if response.status_code == codes.see_other and method != "HEAD":
-            method = "GET"
-
-        # Do what the browsers do, despite standards...
-        # First, turn 302s into GETs.
-        if response.status_code == codes.found and method != "HEAD":
-            method = "GET"
-
-        # Second, if a POST is responded to with a 301, turn it into a GET.
-        # This bizarre behaviour is explained in Issue 1704.
-        if response.status_code == codes.moved and method == "POST":
-            method = "GET"
-
-        prepared_request.method = method
-
-
-class Session(SessionRedirectMixin):
-    """A Requests session.
-
-    Provides cookie persistence, connection-pooling, and configuration.
-
-    Basic Usage::
-
-      >>> import requests
-      >>> s = requests.Session()
-      >>> s.get('https://httpbin.org/get')
-      
-
-    Or as a context manager::
-
-      >>> with requests.Session() as s:
-      ...     s.get('https://httpbin.org/get')
-      
-    """
-
-    headers: CaseInsensitiveDict[str]
-    auth: _t.AuthType
-    proxies: dict[str, str]
-    hooks: dict[str, list[_t.HookType]]
-    params: MutableMapping[str, Any]
-    stream: bool
-    verify: _t.VerifyType
-    cert: _t.CertType
-    max_redirects: int
-    trust_env: bool
-    cookies: RequestsCookieJar
-    adapters: MutableMapping[str, BaseAdapter]
-
-    __attrs__: list[str] = [
-        "headers",
-        "cookies",
-        "auth",
-        "proxies",
-        "hooks",
-        "params",
-        "verify",
-        "cert",
-        "adapters",
-        "stream",
-        "trust_env",
-        "max_redirects",
-    ]
-
-    def __init__(self) -> None:
-        #: A case-insensitive dictionary of headers to be sent on each
-        #: :class:`Request ` sent from this
-        #: :class:`Session `.
-        self.headers = default_headers()
-
-        #: Default Authentication tuple or object to attach to
-        #: :class:`Request `.
-        self.auth = None
-
-        #: Dictionary mapping protocol or protocol and host to the URL of the proxy
-        #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to
-        #: be used on each :class:`Request `.
-        self.proxies = {}
-
-        #: Event-handling hooks.
-        self.hooks = default_hooks()
-
-        #: Dictionary of querystring data to attach to each
-        #: :class:`Request `. The dictionary values may be lists for
-        #: representing multivalued query parameters.
-        self.params = {}
-
-        #: Stream response content default.
-        self.stream = False
-
-        #: SSL Verification default.
-        #: Defaults to `True`, requiring requests to verify the TLS certificate at the
-        #: remote end.
-        #: If verify is set to `False`, requests will accept any TLS certificate
-        #: presented by the server, and will ignore hostname mismatches and/or
-        #: expired certificates, which will make your application vulnerable to
-        #: man-in-the-middle (MitM) attacks.
-        #: Only set this to `False` for testing.
-        #: If verify is set to a string, it must be the path to a CA bundle file
-        #: that will be used to verify the TLS certificate.
-        self.verify = True
-
-        #: SSL client certificate default, if String, path to ssl client
-        #: cert file (.pem). If Tuple, ('cert', 'key') pair.
-        self.cert = None
-
-        #: Maximum number of redirects allowed. If the request exceeds this
-        #: limit, a :class:`TooManyRedirects` exception is raised.
-        #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is
-        #: 30.
-        self.max_redirects = DEFAULT_REDIRECT_LIMIT
-
-        #: Trust environment settings for proxy configuration, default
-        #: authentication and similar.
-        self.trust_env = True
-
-        #: A CookieJar containing all currently outstanding cookies set on this
-        #: session. By default it is a
-        #: :class:`RequestsCookieJar `, but
-        #: may be any other ``cookielib.CookieJar`` compatible object.
-        self.cookies = cookiejar_from_dict({})
-
-        # Default connection adapters.
-        self.adapters = OrderedDict()
-        self.mount("https://", HTTPAdapter())
-        self.mount("http://", HTTPAdapter())
-
-    def __enter__(self) -> Self:
-        return self
-
-    def __exit__(self, *args: Any) -> None:
-        self.close()
-
-    def prepare_request(self, request: Request) -> PreparedRequest:
-        """Constructs a :class:`PreparedRequest ` for
-        transmission and returns it. The :class:`PreparedRequest` has settings
-        merged from the :class:`Request ` instance and those of the
-        :class:`Session`.
-
-        :param request: :class:`Request` instance to prepare with this
-            session's settings.
-        :rtype: requests.PreparedRequest
-        """
-        url = cast("_t.UriType", request.url)
-        method = cast(str, request.method)
-
-        cookies = request.cookies or {}
-
-        # Bootstrap CookieJar.
-        if not isinstance(cookies, cookielib.CookieJar):
-            cookies = cookiejar_from_dict(cookies)
-
-        # Merge with session cookies
-        merged_cookies = merge_cookies(
-            merge_cookies(RequestsCookieJar(), self.cookies), cookies
-        )
-
-        # Set environment's basic authentication if not explicitly set.
-        auth = request.auth
-        if self.trust_env and not auth and not self.auth:
-            auth = get_netrc_auth(url)
-
-        p = PreparedRequest()
-        p.prepare(
-            method=method.upper(),
-            url=url,
-            files=request.files,
-            data=request.data,
-            json=request.json,
-            headers=merge_setting(
-                request.headers, self.headers, dict_class=CaseInsensitiveDict
-            ),
-            params=merge_setting(request.params, self.params),
-            auth=merge_setting(auth, self.auth),
-            cookies=merged_cookies,
-            hooks=merge_hooks(request.hooks, self.hooks),
-        )
-        return p
-
-    def request(
-        self,
-        method: str,
-        url: _t.UriType,
-        params: _t.ParamsType = None,
-        data: _t.DataType = None,
-        headers: _t.HeadersType = None,
-        cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
-        files: _t.FilesType = None,
-        auth: _t.AuthType = None,
-        timeout: _t.TimeoutType = None,
-        allow_redirects: bool = True,
-        proxies: dict[str, str] | None = None,
-        hooks: _t.HooksInputType | None = None,
-        stream: bool | None = None,
-        verify: _t.VerifyType | None = None,
-        cert: _t.CertType = None,
-        json: _t.JsonType = None,
-    ) -> Response:
-        """Constructs a :class:`Request `, prepares it and sends it.
-        Returns :class:`Response ` object.
-
-        :param method: method for the new :class:`Request` object.
-        :param url: URL for the new :class:`Request` object.
-        :param params: (optional) Dictionary or bytes to be sent in the query
-            string for the :class:`Request`.
-        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-            object to send in the body of the :class:`Request`.
-        :param json: (optional) json to send in the body of the
-            :class:`Request`.
-        :param headers: (optional) Dictionary of HTTP Headers to send with the
-            :class:`Request`.
-        :param cookies: (optional) Dict or CookieJar object to send with the
-            :class:`Request`.
-        :param files: (optional) Dictionary of ``'filename': file-like-objects``
-            for multipart encoding upload.
-        :param auth: (optional) Auth tuple or callable to enable
-            Basic/Digest/Custom HTTP Auth.
-        :param timeout: (optional) How many seconds to wait for the server to send
-            data before giving up, as a float, or a :ref:`(connect timeout,
-            read timeout) ` tuple.
-        :type timeout: float or tuple
-        :param allow_redirects: (optional) Set to True by default.
-        :type allow_redirects: bool
-        :param proxies: (optional) Dictionary mapping protocol or protocol and
-            hostname to the URL of the proxy.
-        :param hooks: (optional) Dictionary mapping hook name to one event or
-            list of events, event must be callable.
-        :param stream: (optional) whether to immediately download the response
-            content. Defaults to ``False``.
-        :param verify: (optional) Either a boolean, in which case it controls whether we verify
-            the server's TLS certificate, or a string, in which case it must be a path
-            to a CA bundle to use. Defaults to ``True``. When set to
-            ``False``, requests will accept any TLS certificate presented by
-            the server, and will ignore hostname mismatches and/or expired
-            certificates, which will make your application vulnerable to
-            man-in-the-middle (MitM) attacks. Setting verify to ``False``
-            may be useful during local development or testing.
-        :param cert: (optional) if String, path to ssl client cert file (.pem).
-            If Tuple, ('cert', 'key') pair.
-        :rtype: requests.Response
-        """
-        if isinstance(url, bytes):
-            url = url.decode("utf-8")
-
-        # Create the Request.
-        req = Request(
-            method=method.upper(),
-            url=url,
-            headers=headers,
-            files=files,
-            data=data or {},
-            json=json,
-            params=params or {},
-            auth=auth,
-            cookies=cookies,
-            hooks=hooks,
-        )
-        prep = self.prepare_request(req)
-
-        assert _is_prepared(prep)
-
-        proxies = proxies or {}
-
-        settings = self.merge_environment_settings(
-            prep.url, proxies, stream, verify, cert
-        )
-
-        # Send the request.
-        send_kwargs = {
-            "timeout": timeout,
-            "allow_redirects": allow_redirects,
-        }
-        send_kwargs.update(settings)
-        resp = self.send(prep, **send_kwargs)
-
-        return resp
-
-    def get(
-        self,
-        url: _t.UriType,
-        params: _t.ParamsType = None,
-        **kwargs: Unpack[_t.GetKwargs],
-    ) -> Response:
-        r"""Sends a GET request. Returns :class:`Response` object.
-
-        :param url: URL for the new :class:`Request` object.
-        :param params: (optional) Dictionary, list of tuples or bytes to send
-        in the query string for the :class:`Request`.
-        :param \*\*kwargs: Optional arguments that ``request`` takes.
-        :rtype: requests.Response
-        """
-
-        kwargs.setdefault("allow_redirects", True)
-        return self.request("GET", url, params=params, **kwargs)
-
-    def options(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
-        r"""Sends a OPTIONS request. Returns :class:`Response` object.
-
-        :param url: URL for the new :class:`Request` object.
-        :param \*\*kwargs: Optional arguments that ``request`` takes.
-        :rtype: requests.Response
-        """
-
-        kwargs.setdefault("allow_redirects", True)
-        return self.request("OPTIONS", url, **kwargs)
-
-    def head(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
-        r"""Sends a HEAD request. Returns :class:`Response` object.
-
-        :param url: URL for the new :class:`Request` object.
-        :param \*\*kwargs: Optional arguments that ``request`` takes.
-        :rtype: requests.Response
-        """
-
-        kwargs.setdefault("allow_redirects", False)
-        return self.request("HEAD", url, **kwargs)
-
-    def post(
-        self,
-        url: _t.UriType,
-        data: _t.DataType = None,
-        json: _t.JsonType = None,
-        **kwargs: Unpack[_t.PostKwargs],
-    ) -> Response:
-        r"""Sends a POST request. Returns :class:`Response` object.
-
-        :param url: URL for the new :class:`Request` object.
-        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-            object to send in the body of the :class:`Request`.
-        :param json: (optional) json to send in the body of the :class:`Request`.
-        :param \*\*kwargs: Optional arguments that ``request`` takes.
-        :rtype: requests.Response
-        """
-
-        return self.request("POST", url, data=data, json=json, **kwargs)
-
-    def put(
-        self, url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
-    ) -> Response:
-        r"""Sends a PUT request. Returns :class:`Response` object.
-
-        :param url: URL for the new :class:`Request` object.
-        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-            object to send in the body of the :class:`Request`.
-        :param \*\*kwargs: Optional arguments that ``request`` takes.
-        :rtype: requests.Response
-        """
-
-        return self.request("PUT", url, data=data, **kwargs)
-
-    def patch(
-        self, url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]
-    ) -> Response:
-        r"""Sends a PATCH request. Returns :class:`Response` object.
-
-        :param url: URL for the new :class:`Request` object.
-        :param data: (optional) Dictionary, list of tuples, bytes, or file-like
-            object to send in the body of the :class:`Request`.
-        :param \*\*kwargs: Optional arguments that ``request`` takes.
-        :rtype: requests.Response
-        """
-
-        return self.request("PATCH", url, data=data, **kwargs)
-
-    def delete(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response:
-        r"""Sends a DELETE request. Returns :class:`Response` object.
-
-        :param url: URL for the new :class:`Request` object.
-        :param \*\*kwargs: Optional arguments that ``request`` takes.
-        :rtype: requests.Response
-        """
-
-        return self.request("DELETE", url, **kwargs)
-
-    def send(self, request: PreparedRequest, **kwargs: Any) -> Response:
-        """Send a given PreparedRequest.
-
-        :rtype: requests.Response
-        """
-        # Set defaults that the hooks can utilize to ensure they always have
-        # the correct parameters to reproduce the previous request.
-        kwargs.setdefault("stream", self.stream)
-        kwargs.setdefault("verify", self.verify)
-        kwargs.setdefault("cert", self.cert)
-        if "proxies" not in kwargs:
-            kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env)
-
-        # It's possible that users might accidentally send a Request object.
-        # Guard against that specific failure case.
-        if isinstance(request, Request):
-            raise ValueError("You can only send PreparedRequests.")
-
-        assert _is_prepared(request)
-
-        # Set up variables needed for resolve_redirects and dispatching of hooks
-        allow_redirects = kwargs.pop("allow_redirects", True)
-        stream = kwargs.get("stream")
-        hooks = request.hooks
-
-        # Get the appropriate adapter to use
-        adapter = self.get_adapter(url=request.url)
-
-        # Start time (approximately) of the request
-        start = preferred_clock()
-
-        # Send the request
-        r = adapter.send(request, **kwargs)
-
-        # Total elapsed time of the request (approximately)
-        elapsed = preferred_clock() - start
-        r.elapsed = timedelta(seconds=elapsed)
-
-        # Response manipulation hooks
-        r = dispatch_hook("response", hooks, r, **kwargs)
-
-        # Persist cookies
-        if r.history:
-            # If the hooks create history then we want those cookies too
-            for resp in r.history:
-                extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
-
-        extract_cookies_to_jar(self.cookies, request, r.raw)
-
-        # Resolve redirects if allowed.
-        if allow_redirects:
-            # Redirect resolving generator.
-            gen = self.resolve_redirects(r, request, **kwargs)
-            history = [resp for resp in gen]
-        else:
-            history = []
-
-        # Shuffle things around if there's history.
-        if history:
-            # Insert the first (original) request at the start
-            history.insert(0, r)
-            # Get the last request made
-            r = history.pop()
-            r.history = history
-
-        # If redirects aren't being followed, store the response on the Request for Response.next().
-        if not allow_redirects:
-            try:
-                r._next = next(  # type: ignore[assignment]  # yield_requests=True returns PreparedRequest
-                    self.resolve_redirects(r, request, yield_requests=True, **kwargs)
-                )
-            except StopIteration:
-                pass
-
-        if not stream:
-            r.content
-
-        return r
-
-    def merge_environment_settings(
-        self,
-        url: str,
-        proxies: dict[str, str] | None,
-        stream: bool | None,
-        verify: _t.VerifyType | None,
-        cert: _t.CertType,
-    ) -> dict[str, Any]:
-        """
-        Check the environment and merge it with some settings.
-
-        :rtype: dict
-        """
-        # Gather clues from the surrounding environment.
-        if self.trust_env:
-            # Set environment's proxies.
-            no_proxy = proxies.get("no_proxy") if proxies is not None else None
-            env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
-            if proxies is not None:
-                for k, v in env_proxies.items():
-                    proxies.setdefault(k, v)
-
-            # Look for requests environment configuration
-            # and be compatible with cURL.
-            if verify is True or verify is None:
-                verify = (
-                    os.environ.get("REQUESTS_CA_BUNDLE")
-                    or os.environ.get("CURL_CA_BUNDLE")
-                    or verify
-                )
-
-        # Merge all the kwargs.
-        proxies = merge_setting(proxies, self.proxies)
-        stream = merge_setting(stream, self.stream)
-        verify = merge_setting(verify, self.verify)
-        cert = merge_setting(cert, self.cert)
-
-        return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
-
-    def get_adapter(self, url: str) -> BaseAdapter:
-        """
-        Returns the appropriate connection adapter for the given URL.
-
-        :rtype: requests.adapters.BaseAdapter
-        """
-        for prefix, adapter in self.adapters.items():
-            if url.lower().startswith(prefix.lower()):
-                return adapter
-
-        # Nothing matches :-/
-        raise InvalidSchema(f"No connection adapters were found for {url!r}")
-
-    def close(self) -> None:
-        """Closes all adapters and as such the session"""
-        for v in self.adapters.values():
-            v.close()
-
-    def mount(self, prefix: str, adapter: BaseAdapter) -> None:
-        """Registers a connection adapter to a prefix.
-
-        Adapters are sorted in descending order by prefix length.
-        """
-        self.adapters[prefix] = adapter
-        keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
-
-        for key in keys_to_move:
-            self.adapters[key] = self.adapters.pop(key)
-
-    def __getstate__(self) -> dict[str, Any]:
-        state = {attr: getattr(self, attr, None) for attr in self.__attrs__}
-        return state
-
-    def __setstate__(self, state: dict[str, Any]) -> None:
-        for attr, value in state.items():
-            setattr(self, attr, value)
-
-
-def session() -> Session:
-    """
-    Returns a :class:`Session` for context-management.
-
-    .. deprecated:: 1.0.0
-
-        This method has been deprecated since version 1.0.0 and is only kept for
-        backwards compatibility. New code should use :class:`~requests.sessions.Session`
-        to create a session. This may be removed at a future date.
-
-    :rtype: Session
-    """
-    return Session()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py
deleted file mode 100644
index 6c59d6baec8..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/status_codes.py
+++ /dev/null
@@ -1,128 +0,0 @@
-r"""
-The ``codes`` object defines a mapping from common names for HTTP statuses
-to their numerical codes, accessible either as attributes or as dictionary
-items.
-
-Example::
-
-    >>> import requests
-    >>> requests.codes['temporary_redirect']
-    307
-    >>> requests.codes.teapot
-    418
-    >>> requests.codes['\o/']
-    200
-
-Some codes have multiple names, and both upper- and lower-case versions of
-the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
-``codes.okay`` all correspond to the HTTP status code 200.
-"""
-
-from .structures import LookupDict
-
-_codes = {
-    # Informational.
-    100: ("continue",),
-    101: ("switching_protocols",),
-    102: ("processing", "early-hints"),
-    103: ("checkpoint",),
-    122: ("uri_too_long", "request_uri_too_long"),
-    200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", "✓"),
-    201: ("created",),
-    202: ("accepted",),
-    203: ("non_authoritative_info", "non_authoritative_information"),
-    204: ("no_content",),
-    205: ("reset_content", "reset"),
-    206: ("partial_content", "partial"),
-    207: ("multi_status", "multiple_status", "multi_stati", "multiple_stati"),
-    208: ("already_reported",),
-    226: ("im_used",),
-    # Redirection.
-    300: ("multiple_choices",),
-    301: ("moved_permanently", "moved", "\\o-"),
-    302: ("found",),
-    303: ("see_other", "other"),
-    304: ("not_modified",),
-    305: ("use_proxy",),
-    306: ("switch_proxy",),
-    307: ("temporary_redirect", "temporary_moved", "temporary"),
-    308: (
-        "permanent_redirect",
-        "resume_incomplete",
-        "resume",
-    ),  # "resume" and "resume_incomplete" to be removed in 3.0
-    # Client Error.
-    400: ("bad_request", "bad"),
-    401: ("unauthorized",),
-    402: ("payment_required", "payment"),
-    403: ("forbidden",),
-    404: ("not_found", "-o-"),
-    405: ("method_not_allowed", "not_allowed"),
-    406: ("not_acceptable",),
-    407: ("proxy_authentication_required", "proxy_auth", "proxy_authentication"),
-    408: ("request_timeout", "timeout"),
-    409: ("conflict",),
-    410: ("gone",),
-    411: ("length_required",),
-    412: ("precondition_failed", "precondition"),
-    413: ("request_entity_too_large", "content_too_large"),
-    414: ("request_uri_too_large", "uri_too_long"),
-    415: ("unsupported_media_type", "unsupported_media", "media_type"),
-    416: (
-        "requested_range_not_satisfiable",
-        "requested_range",
-        "range_not_satisfiable",
-    ),
-    417: ("expectation_failed",),
-    418: ("im_a_teapot", "teapot", "i_am_a_teapot"),
-    421: ("misdirected_request",),
-    422: ("unprocessable_entity", "unprocessable", "unprocessable_content"),
-    423: ("locked",),
-    424: ("failed_dependency", "dependency"),
-    425: ("unordered_collection", "unordered", "too_early"),
-    426: ("upgrade_required", "upgrade"),
-    428: ("precondition_required", "precondition"),
-    429: ("too_many_requests", "too_many"),
-    431: ("header_fields_too_large", "fields_too_large"),
-    444: ("no_response", "none"),
-    449: ("retry_with", "retry"),
-    450: ("blocked_by_windows_parental_controls", "parental_controls"),
-    451: ("unavailable_for_legal_reasons", "legal_reasons"),
-    499: ("client_closed_request",),
-    # Server Error.
-    500: ("internal_server_error", "server_error", "/o\\", "✗"),
-    501: ("not_implemented",),
-    502: ("bad_gateway",),
-    503: ("service_unavailable", "unavailable"),
-    504: ("gateway_timeout",),
-    505: ("http_version_not_supported", "http_version"),
-    506: ("variant_also_negotiates",),
-    507: ("insufficient_storage",),
-    509: ("bandwidth_limit_exceeded", "bandwidth"),
-    510: ("not_extended",),
-    511: ("network_authentication_required", "network_auth", "network_authentication"),
-}
-
-codes: LookupDict[int] = LookupDict(name="status_codes")
-
-
-def _init():
-    for code, titles in _codes.items():
-        for title in titles:
-            setattr(codes, title, code)
-            if not title.startswith(("\\", "/")):
-                setattr(codes, title.upper(), code)
-
-    def doc(code: int) -> str:
-        names = ", ".join(f"``{n}``" for n in _codes[code])
-        return "* %d: %s" % (code, names)
-
-    global __doc__
-    __doc__ = (
-        __doc__ + "\n" + "\n".join(doc(code) for code in sorted(_codes))
-        if __doc__ is not None
-        else None
-    )
-
-
-_init()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py
deleted file mode 100644
index 7675eaf15a1..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/structures.py
+++ /dev/null
@@ -1,130 +0,0 @@
-"""
-requests.structures
-~~~~~~~~~~~~~~~~~~~
-
-Data structures that power Requests.
-"""
-
-from __future__ import annotations
-
-from collections import OrderedDict
-from collections.abc import Iterable, Iterator, Mapping
-from typing import Any, Generic, TypeVar, overload
-
-from .compat import MutableMapping
-
-_VT = TypeVar("_VT")
-_D = TypeVar("_D")
-
-
-class CaseInsensitiveDict(MutableMapping[str, _VT], Generic[_VT]):
-    """A case-insensitive ``dict``-like object.
-
-    Implements all methods and operations of
-    ``MutableMapping`` as well as dict's ``copy``. Also
-    provides ``lower_items``.
-
-    All keys are expected to be strings. The structure remembers the
-    case of the last key to be set, and ``iter(instance)``,
-    ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
-    will contain case-sensitive keys. However, querying and contains
-    testing is case insensitive::
-
-        cid = CaseInsensitiveDict()
-        cid['Accept'] = 'application/json'
-        cid['aCCEPT'] == 'application/json'  # True
-        list(cid) == ['Accept']  # True
-
-    For example, ``headers['content-encoding']`` will return the
-    value of a ``'Content-Encoding'`` response header, regardless
-    of how the header name was originally stored.
-
-    If the constructor, ``.update``, or equality comparison
-    operations are given keys that have equal ``.lower()``s, the
-    behavior is undefined.
-    """
-
-    _store: OrderedDict[str, tuple[str, _VT]]
-
-    def __init__(
-        self,
-        data: Mapping[str, _VT] | Iterable[tuple[str, _VT]] | None = None,
-        **kwargs: _VT,
-    ) -> None:
-        self._store = OrderedDict()
-        if data is None:
-            data = {}
-        self.update(data, **kwargs)
-
-    def __setitem__(self, key: str, value: _VT) -> None:
-        # Use the lowercased key for lookups, but store the actual
-        # key alongside the value.
-        self._store[key.lower()] = (key, value)
-
-    def __getitem__(self, key: str) -> _VT:
-        return self._store[key.lower()][1]
-
-    def __delitem__(self, key: str) -> None:
-        del self._store[key.lower()]
-
-    def __iter__(self) -> Iterator[str]:
-        return (casedkey for casedkey, _ in self._store.values())
-
-    def __len__(self) -> int:
-        return len(self._store)
-
-    def lower_items(self) -> Iterator[tuple[str, _VT]]:
-        """Like iteritems(), but with all lowercase keys."""
-        return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
-
-    def __eq__(self, other: object) -> bool:
-        if isinstance(other, Mapping):
-            other_dict: CaseInsensitiveDict[Any] = CaseInsensitiveDict(other)  # type: ignore[reportUnknownArgumentType]
-        else:
-            return NotImplemented
-        # Compare insensitively
-        return dict(self.lower_items()) == dict(other_dict.lower_items())
-
-    # Copy is required
-    def copy(self) -> CaseInsensitiveDict[_VT]:
-        return CaseInsensitiveDict(self._store.values())
-
-    def __repr__(self) -> str:
-        return str(dict(self.items()))
-
-
-class LookupDict(dict[str, _VT]):
-    """Dictionary lookup object."""
-
-    name: Any
-
-    def __init__(self, name: Any = None) -> None:
-        self.name = name
-        super().__init__()
-
-    def __repr__(self) -> str:
-        return f""
-
-    def __getattr__(self, key: str) -> _VT | None:
-        # We need this for type checkers to infer typing
-        # on attribute access with status_codes.py
-        if key in self.__dict__:
-            return self.__dict__[key]
-        else:
-            raise AttributeError(
-                f"'{type(self).__name__}' object has no attribute '{key}'"
-            )
-
-    def __getitem__(self, key: str) -> _VT | None:  # type: ignore[override]
-        # We allow fall-through here, so values default to None
-
-        return self.__dict__.get(key, None)
-
-    @overload
-    def get(self, key: str, default: None = None) -> _VT | None: ...
-
-    @overload
-    def get(self, key: str, default: _D | _VT) -> _D | _VT: ...
-
-    def get(self, key: str, default: _D | None = None) -> _VT | _D | None:
-        return self.__dict__.get(key, default)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py
deleted file mode 100644
index c3e50de429c..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/requests/utils.py
+++ /dev/null
@@ -1,1155 +0,0 @@
-"""
-requests.utils
-~~~~~~~~~~~~~~
-
-This module provides utility functions that are used within Requests
-that are also useful for external consumption.
-"""
-
-from __future__ import annotations
-
-import codecs
-import contextlib
-import io
-import os
-import re
-import socket
-import struct
-import sys
-import tempfile
-import warnings
-import zipfile
-from collections import OrderedDict
-from collections.abc import Generator, Iterable
-from typing import (
-    TYPE_CHECKING,
-    Any,
-    Final,
-    TypeVar,
-    cast,
-    overload,
-)
-
-from opentelemetry.agent._vendor.urllib3.util import make_headers, parse_url
-
-from . import certs
-from .__version__ import __version__
-
-# to_native_string is unused here, but imported here for backwards compatibility
-from ._internal_utils import (  # noqa: F401
-    _HEADER_VALIDATORS_BYTE,  # type: ignore[reportPrivateUsage]
-    _HEADER_VALIDATORS_STR,  # type: ignore[reportPrivateUsage]
-    HEADER_VALIDATORS,  # type: ignore[reportUnusedImport]
-    to_native_string,  # type: ignore[reportUnusedImport]
-)
-from ._types import SupportsItems as _SupportsItems
-from .compat import (
-    Mapping,
-    bytes,
-    getproxies,
-    getproxies_environment,
-    integer_types,
-    is_urllib3_1,
-    proxy_bypass,
-    proxy_bypass_environment,  # type: ignore[attr-defined]  # https://github.com/python/cpython/issues/145331
-    quote,
-    str,
-    unquote,
-    urlparse,
-    urlunparse,
-)
-from .compat import parse_http_list as _parse_list_header
-from .cookies import cookiejar_from_dict
-from .exceptions import (
-    FileModeWarning,
-    InvalidHeader,
-    InvalidURL,
-    UnrewindableBodyError,
-)
-from .structures import CaseInsensitiveDict
-
-if TYPE_CHECKING:
-    from http.cookiejar import CookieJar
-    from io import BufferedWriter
-
-    from . import _types as _t
-    from .models import PreparedRequest, Request, Response
-
-NETRC_FILES: Final = (".netrc", "_netrc")
-
-
-# Certificate is extracted by certifi when needed.
-DEFAULT_CA_BUNDLE_PATH: str = certs.where()
-
-
-DEFAULT_PORTS: Final = {"http": 80, "https": 443}
-
-_KT = TypeVar("_KT")
-_VT = TypeVar("_VT")
-
-# Ensure that ', ' is used to preserve previous delimiter behavior.
-DEFAULT_ACCEPT_ENCODING: Final = ", ".join(
-    re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"])
-)
-
-
-if sys.platform == "win32":
-    # provide a proxy_bypass version on Windows without DNS lookups
-
-    def proxy_bypass_registry(host: str) -> bool:
-        try:
-            import winreg
-        except ImportError:
-            return False
-
-        try:
-            internetSettings = winreg.OpenKey(
-                winreg.HKEY_CURRENT_USER,
-                r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",
-            )
-            # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it
-            proxyEnable = int(winreg.QueryValueEx(internetSettings, "ProxyEnable")[0])
-            # ProxyOverride is almost always a string
-            proxyOverride = winreg.QueryValueEx(internetSettings, "ProxyOverride")[0]
-        except (OSError, ValueError):
-            return False
-        if not proxyEnable or not proxyOverride:
-            return False
-
-        # make a check value list from the registry entry: replace the
-        # '' string by the localhost entry and the corresponding
-        # canonical entry.
-        proxyOverride = proxyOverride.split(";")
-        # filter out empty strings to avoid re.match return true in the following code.
-        proxyOverride = filter(None, proxyOverride)
-        # now check if we match one of the registry values.
-        for test in proxyOverride:
-            if test == "":
-                if "." not in host:
-                    return True
-            test = test.replace(".", r"\.")  # mask dots
-            test = test.replace("*", r".*")  # change glob sequence
-            test = test.replace("?", r".")  # change glob char
-            if re.match(test, host, re.I):
-                return True
-        return False
-
-    def proxy_bypass(host: str) -> bool:  # noqa
-        """Return True, if the host should be bypassed.
-
-        Checks proxy settings gathered from the environment, if specified,
-        or the registry.
-        """
-        if getproxies_environment():
-            return proxy_bypass_environment(host)
-        else:
-            return proxy_bypass_registry(host)
-
-
-def dict_to_sequence(
-    d: _t.SupportsItems[Any, Any] | Iterable[tuple[Any, Any]],
-) -> Iterable[tuple[Any, Any]]:
-    """Returns an internal sequence dictionary update."""
-
-    if isinstance(d, _SupportsItems):
-        return d.items()
-
-    return d
-
-
-def super_len(o: Any) -> int:
-    total_length = None
-    current_position = 0
-
-    if not is_urllib3_1 and isinstance(o, str):
-        # urllib3 2.x+ treats all strings as utf-8 instead
-        # of latin-1 (iso-8859-1) like http.client.
-        o = o.encode("utf-8")
-
-    if hasattr(o, "__len__"):
-        total_length = len(o)
-
-    elif hasattr(o, "len"):
-        total_length = o.len
-
-    elif hasattr(o, "fileno"):
-        try:
-            fileno = o.fileno()
-        except (io.UnsupportedOperation, AttributeError):
-            # AttributeError is a surprising exception, seeing as how we've just checked
-            # that `hasattr(o, 'fileno')`.  It happens for objects obtained via
-            # `Tarfile.extractfile()`, per issue 5229.
-            pass
-        else:
-            total_length = os.fstat(fileno).st_size
-
-            # Having used fstat to determine the file length, we need to
-            # confirm that this file was opened up in binary mode.
-            if "b" not in o.mode:
-                warnings.warn(
-                    (
-                        "Requests has determined the content-length for this "
-                        "request using the binary size of the file: however, the "
-                        "file has been opened in text mode (i.e. without the 'b' "
-                        "flag in the mode). This may lead to an incorrect "
-                        "content-length. In Requests 3.0, support will be removed "
-                        "for files in text mode."
-                    ),
-                    FileModeWarning,
-                )
-
-    if hasattr(o, "tell"):
-        try:
-            current_position = o.tell()
-        except OSError:
-            # This can happen in some weird situations, such as when the file
-            # is actually a special file descriptor like stdin. In this
-            # instance, we don't know what the length is, so set it to zero and
-            # let requests chunk it instead.
-            if total_length is not None:
-                current_position = total_length
-        else:
-            if hasattr(o, "seek") and total_length is None:
-                # StringIO and BytesIO have seek but no usable fileno
-                try:
-                    # seek to end of file
-                    o.seek(0, 2)
-                    total_length = o.tell()
-
-                    # seek back to current position to support
-                    # partially read file-like objects
-                    o.seek(current_position or 0)
-                except OSError:
-                    total_length = 0
-
-    if total_length is None:
-        total_length = 0
-
-    return max(0, total_length - current_position)
-
-
-def get_netrc_auth(
-    url: _t.UriType, raise_errors: bool = False
-) -> tuple[str, str] | None:
-    """Returns the Requests tuple auth for a given url from netrc."""
-
-    if isinstance(url, bytes):
-        url = url.decode("utf-8")
-
-    netrc_file = os.environ.get("NETRC")
-    if netrc_file is not None:
-        netrc_locations = (netrc_file,)
-    else:
-        netrc_locations = (f"~/{f}" for f in NETRC_FILES)
-
-    try:
-        from netrc import NetrcParseError, netrc
-
-        netrc_path = None
-
-        for f in netrc_locations:
-            loc = os.path.expanduser(f)
-            if os.path.exists(loc):
-                netrc_path = loc
-                break
-
-        # Abort early if there isn't one.
-        if netrc_path is None:
-            return
-
-        ri = urlparse(url)
-        host = ri.hostname
-
-        if host is None:
-            return
-
-        try:
-            _netrc = netrc(netrc_path).authenticators(host)
-            if _netrc and any(_netrc):
-                # Return with login / password
-                login_i = 0 if _netrc[0] else 1
-                return (_netrc[login_i] or "", _netrc[2] or "")
-        except (NetrcParseError, OSError):
-            # If there was a parsing error or a permissions issue reading the file,
-            # we'll just skip netrc auth unless explicitly asked to raise errors.
-            if raise_errors:
-                raise
-
-    # App Engine hackiness.
-    except (ImportError, AttributeError):
-        pass
-
-
-def guess_filename(obj: Any) -> str | None:
-    """Tries to guess the filename of the given object."""
-    name = getattr(obj, "name", None)
-    if name and isinstance(name, (str, bytes)) and name[0] != "<" and name[-1] != ">":
-        return os.path.basename(name)  # type: ignore[return-value]  # urllib3 accepts bytes but types str only
-
-
-def extract_zipped_paths(path: str) -> str:
-    """Replace nonexistent paths that look like they refer to a member of a zip
-    archive with the location of an extracted copy of the target, or else
-    just return the provided path unchanged.
-    """
-    if os.path.exists(path):
-        # this is already a valid path, no need to do anything further
-        return path
-
-    # find the first valid part of the provided path and treat that as a zip archive
-    # assume the rest of the path is the name of a member in the archive
-    archive, member = os.path.split(path)
-    while archive and not os.path.exists(archive):
-        archive, prefix = os.path.split(archive)
-        if not prefix:
-            # If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split),
-            # we _can_ end up in an infinite loop on a rare corner case affecting a small number of users
-            break
-        member = "/".join([prefix, member])
-
-    if not zipfile.is_zipfile(archive):
-        return path
-
-    zip_file = zipfile.ZipFile(archive)
-    if member not in zip_file.namelist():
-        return path
-
-    # we have a valid zip archive and a valid member of that archive
-    suffix = os.path.splitext(member.split("/")[-1])[-1]
-    fd, extracted_path = tempfile.mkstemp(suffix=suffix)
-    try:
-        os.write(fd, zip_file.read(member))
-    finally:
-        os.close(fd)
-
-    return extracted_path
-
-
-@contextlib.contextmanager
-def atomic_open(filename: str) -> Generator[BufferedWriter, None, None]:
-    """Write a file to the disk in an atomic fashion"""
-    tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
-    try:
-        with os.fdopen(tmp_descriptor, "wb") as tmp_handler:
-            yield tmp_handler
-        os.replace(tmp_name, filename)
-    except BaseException:
-        os.remove(tmp_name)
-        raise
-
-
-def from_key_val_list(
-    value: Mapping[Any, Any] | Iterable[tuple[Any, Any]] | None,
-) -> dict[Any, Any] | None:
-    """Take an object and test to see if it can be represented as a
-    dictionary. Unless it can not be represented as such, return an
-    OrderedDict, e.g.,
-
-    ::
-
-        >>> from_key_val_list([('key', 'val')])
-        OrderedDict([('key', 'val')])
-        >>> from_key_val_list('string')
-        Traceback (most recent call last):
-        ...
-        ValueError: cannot encode objects that are not 2-tuples
-        >>> from_key_val_list({'key': 'val'})
-        OrderedDict([('key', 'val')])
-
-    :rtype: OrderedDict
-    """
-    if value is None:
-        return None
-
-    if isinstance(value, (str, bytes, bool, int)):
-        raise ValueError("cannot encode objects that are not 2-tuples")
-
-    return OrderedDict(value)
-
-
-@overload
-def to_key_val_list(value: None) -> None: ...
-@overload
-def to_key_val_list(
-    value: _t.SupportsItems[_KT, _VT] | Iterable[tuple[_KT, _VT]],
-) -> list[tuple[_KT, _VT]]: ...
-def to_key_val_list(
-    value: _t.SupportsItems[_KT, _VT] | Iterable[tuple[_KT, _VT]] | None,
-) -> list[tuple[_KT, _VT]] | None:
-    """Take an object and test to see if it can be represented as a
-    dictionary. If it can be, return a list of tuples, e.g.,
-
-    ::
-
-        >>> to_key_val_list([('key', 'val')])
-        [('key', 'val')]
-        >>> to_key_val_list({'key': 'val'})
-        [('key', 'val')]
-        >>> to_key_val_list('string')
-        Traceback (most recent call last):
-        ...
-        ValueError: cannot encode objects that are not 2-tuples
-
-    :rtype: list
-    """
-    if value is None:
-        return None
-
-    if isinstance(value, (str, bytes, bool, int)):
-        raise ValueError("cannot encode objects that are not 2-tuples")
-
-    if isinstance(value, _SupportsItems):
-        return list(value.items())
-
-    return list(value)
-
-
-# From mitsuhiko/werkzeug (used with permission).
-def parse_list_header(value: str) -> list[str]:
-    """Parse lists as described by RFC 2068 Section 2.
-
-    In particular, parse comma-separated lists where the elements of
-    the list may include quoted-strings.  A quoted-string could
-    contain a comma.  A non-quoted string could have quotes in the
-    middle.  Quotes are removed automatically after parsing.
-
-    It basically works like :func:`parse_set_header` just that items
-    may appear multiple times and case sensitivity is preserved.
-
-    The return value is a standard :class:`list`:
-
-    >>> parse_list_header('token, "quoted value"')
-    ['token', 'quoted value']
-
-    To create a header from the :class:`list` again, use the
-    :func:`dump_header` function.
-
-    :param value: a string with a list header.
-    :return: :class:`list`
-    :rtype: list
-    """
-    result: list[str] = []
-    for item in _parse_list_header(value):
-        if item[:1] == item[-1:] == '"':
-            item = unquote_header_value(item[1:-1])
-        result.append(item)
-    return result
-
-
-# From mitsuhiko/werkzeug (used with permission).
-def parse_dict_header(value: str) -> dict[str, str | None]:
-    """Parse lists of key, value pairs as described by RFC 2068 Section 2 and
-    convert them into a python dict:
-
-    >>> d = parse_dict_header('foo="is a fish", bar="as well"')
-    >>> type(d) is dict
-    True
-    >>> sorted(d.items())
-    [('bar', 'as well'), ('foo', 'is a fish')]
-
-    If there is no value for a key it will be `None`:
-
-    >>> parse_dict_header('key_without_value')
-    {'key_without_value': None}
-
-    To create a header from the :class:`dict` again, use the
-    :func:`dump_header` function.
-
-    :param value: a string with a dict header.
-    :return: :class:`dict`
-    :rtype: dict
-    """
-    result: dict[str, str | None] = {}
-    for item in _parse_list_header(value):
-        if "=" not in item:
-            result[item] = None
-            continue
-        name, value = item.split("=", 1)
-        if value[:1] == value[-1:] == '"':
-            value = unquote_header_value(value[1:-1])
-        result[name] = value
-    return result
-
-
-# From mitsuhiko/werkzeug (used with permission).
-def unquote_header_value(value: str, is_filename: bool = False) -> str:
-    r"""Unquotes a header value.  (Reversal of :func:`quote_header_value`).
-    This does not use the real unquoting but what browsers are actually
-    using for quoting.
-
-    :param value: the header value to unquote.
-    :rtype: str
-    """
-    if value and value[0] == value[-1] == '"':
-        # this is not the real unquoting, but fixing this so that the
-        # RFC is met will result in bugs with internet explorer and
-        # probably some other browsers as well.  IE for example is
-        # uploading files with "C:\foo\bar.txt" as filename
-        value = value[1:-1]
-
-        # if this is a filename and the starting characters look like
-        # a UNC path, then just return the value without quotes.  Using the
-        # replace sequence below on a UNC path has the effect of turning
-        # the leading double slash into a single slash and then
-        # _fix_ie_filename() doesn't work correctly.  See #458.
-        if not is_filename or value[:2] != "\\\\":
-            return value.replace("\\\\", "\\").replace('\\"', '"')
-    return value
-
-
-def dict_from_cookiejar(cj: CookieJar) -> dict[str, str | None]:
-    """Returns a key/value dictionary from a CookieJar.
-
-    :param cj: CookieJar object to extract cookies from.
-    :rtype: dict
-    """
-
-    cookie_dict = {cookie.name: cookie.value for cookie in cj}
-    return cookie_dict
-
-
-def add_dict_to_cookiejar(cj: CookieJar, cookie_dict: dict[str, str]) -> CookieJar:
-    """Returns a CookieJar from a key/value dictionary.
-
-    :param cj: CookieJar to insert cookies into.
-    :param cookie_dict: Dict of key/values to insert into CookieJar.
-    :rtype: CookieJar
-    """
-
-    return cookiejar_from_dict(cookie_dict, cj)
-
-
-def get_encodings_from_content(content: str) -> list[str]:
-    """Returns encodings from given content string.
-
-    :param content: bytestring to extract encodings from.
-    """
-    warnings.warn(
-        (
-            "In requests 3.0, get_encodings_from_content will be removed. For "
-            "more information, please see the discussion on issue #2266. (This"
-            " warning should only appear once.)"
-        ),
-        DeprecationWarning,
-    )
-
-    charset_re = re.compile(r']', flags=re.I)
-    pragma_re = re.compile(r']', flags=re.I)
-    xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]')
-
-    return (
-        charset_re.findall(content)
-        + pragma_re.findall(content)
-        + xml_re.findall(content)
-    )
-
-
-def _parse_content_type_header(header: str) -> tuple[str, dict[str, Any]]:
-    """Returns content type and parameters from given header.
-
-    :param header: string
-    :return: tuple containing content type and dictionary of
-         parameters.
-    """
-
-    tokens = header.split(";")
-    content_type, params = tokens[0].strip(), tokens[1:]
-    params_dict: dict[str, str | bool] = {}
-    strip_chars = "\"' "
-
-    for param in params:
-        param = param.strip()
-        if param and (idx := param.find("=")) != -1:
-            key = param[:idx].strip(strip_chars)
-            value = param[idx + 1 :].strip(strip_chars)
-            params_dict[key.lower()] = value
-    return content_type, params_dict
-
-
-def get_encoding_from_headers(headers: CaseInsensitiveDict[str]) -> str | None:
-    """Returns encodings from given HTTP Header Dict.
-
-    :param headers: dictionary to extract encoding from.
-    :rtype: str
-    """
-
-    content_type = headers.get("content-type")
-
-    if not content_type:
-        return None
-
-    content_type, params = _parse_content_type_header(content_type)
-
-    if "charset" in params:
-        return params["charset"].strip("'\"")
-
-    if "text" in content_type:
-        return "ISO-8859-1"
-
-    if "application/json" in content_type:
-        # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset
-        return "utf-8"
-
-
-def stream_decode_response_unicode(
-    iterator: Iterable[bytes], r: Response
-) -> Generator[str | bytes, None, None]:
-    """Stream decodes an iterator."""
-
-    if r.encoding is None:
-        yield from iterator
-        return
-
-    decoder = codecs.getincrementaldecoder(r.encoding)(errors="replace")
-    for chunk in iterator:
-        rv = decoder.decode(chunk)
-        if rv:
-            yield rv
-    rv = decoder.decode(b"", final=True)
-    if rv:
-        yield rv
-
-
-@overload
-def iter_slices(
-    string: bytes, slice_length: int | None
-) -> Generator[bytes, None, None]: ...
-@overload
-def iter_slices(
-    string: str, slice_length: int | None
-) -> Generator[str, None, None]: ...
-def iter_slices(
-    string: bytes | str, slice_length: int | None
-) -> Generator[bytes | str, None, None]:
-    """Iterate over slices of a string."""
-    pos = 0
-    if slice_length is None or slice_length <= 0:
-        slice_length = len(string)
-    while pos < len(string):
-        yield string[pos : pos + slice_length]
-        pos += slice_length
-
-
-def get_unicode_from_response(r: Response) -> str | bytes | None:
-    """Returns the requested content back in unicode.
-
-    :param r: Response object to get unicode content from.
-
-    Tried:
-
-    1. charset from content-type
-    2. fall back and replace all unicode characters
-
-    :rtype: str
-    """
-    warnings.warn(
-        (
-            "In requests 3.0, get_unicode_from_response will be removed. For "
-            "more information, please see the discussion on issue #2266. (This"
-            " warning should only appear once.)"
-        ),
-        DeprecationWarning,
-    )
-    if r.content is None:  # type: ignore[reportUnnecessaryComparison]
-        return None
-
-    tried_encodings: list[str] = []
-
-    # Try charset from content-type
-    encoding = get_encoding_from_headers(r.headers)
-
-    if encoding:
-        try:
-            return str(r.content, encoding)
-        except UnicodeError:
-            tried_encodings.append(encoding)
-
-    # Fall back:
-    try:
-        return str(r.content, encoding or "utf-8", errors="replace")
-    except TypeError:
-        return r.content
-
-
-# The unreserved URI characters (RFC 3986)
-UNRESERVED_SET: Final = frozenset(
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~"
-)
-
-
-def unquote_unreserved(uri: str) -> str:
-    """Un-escape any percent-escape sequences in a URI that are unreserved
-    characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
-
-    :rtype: str
-    """
-    parts = uri.split("%")
-    for i in range(1, len(parts)):
-        h = parts[i][0:2]
-        if len(h) == 2 and h.isalnum():
-            try:
-                c = chr(int(h, 16))
-            except ValueError:
-                raise InvalidURL(f"Invalid percent-escape sequence: '{h}'")
-
-            if c in UNRESERVED_SET:
-                parts[i] = c + parts[i][2:]
-            else:
-                parts[i] = f"%{parts[i]}"
-        else:
-            parts[i] = f"%{parts[i]}"
-    return "".join(parts)
-
-
-def requote_uri(uri: str) -> str:
-    """Re-quote the given URI.
-
-    This function passes the given URI through an unquote/quote cycle to
-    ensure that it is fully and consistently quoted.
-
-    :rtype: str
-    """
-    safe_with_percent = "!#$%&'()*+,/:;=?@[]~"
-    safe_without_percent = "!#$&'()*+,/:;=?@[]~"
-    try:
-        # Unquote only the unreserved characters
-        # Then quote only illegal characters (do not quote reserved,
-        # unreserved, or '%')
-        return quote(unquote_unreserved(uri), safe=safe_with_percent)
-    except InvalidURL:
-        # We couldn't unquote the given URI, so let's try quoting it, but
-        # there may be unquoted '%'s in the URI. We need to make sure they're
-        # properly quoted so they do not cause issues elsewhere.
-        return quote(uri, safe=safe_without_percent)
-
-
-def address_in_network(ip: str, net: str) -> bool:
-    """This function allows you to check if an IP belongs to a network subnet
-
-    Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
-             returns False if ip = 192.168.1.1 and net = 192.168.100.0/24
-
-    :rtype: bool
-    """
-    ipaddr = struct.unpack("=L", socket.inet_aton(ip))[0]
-    netaddr, bits = net.split("/")
-    netmask = struct.unpack("=L", socket.inet_aton(dotted_netmask(int(bits))))[0]
-    network = struct.unpack("=L", socket.inet_aton(netaddr))[0] & netmask
-    return (ipaddr & netmask) == (network & netmask)
-
-
-def dotted_netmask(mask: int) -> str:
-    """Converts mask from /xx format to xxx.xxx.xxx.xxx
-
-    Example: if mask is 24 function returns 255.255.255.0
-
-    :rtype: str
-    """
-    bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1
-    return socket.inet_ntoa(struct.pack(">I", bits))
-
-
-def is_ipv4_address(string_ip: str) -> bool:
-    """
-    :rtype: bool
-    """
-    try:
-        socket.inet_aton(string_ip)
-    except OSError:
-        return False
-    return True
-
-
-def is_valid_cidr(string_network: str) -> bool:
-    """
-    Very simple check of the cidr format in no_proxy variable.
-
-    :rtype: bool
-    """
-    if string_network.count("/") == 1:
-        try:
-            mask = int(string_network.split("/")[1])
-        except ValueError:
-            return False
-
-        if mask < 1 or mask > 32:
-            return False
-
-        try:
-            socket.inet_aton(string_network.split("/")[0])
-        except OSError:
-            return False
-    else:
-        return False
-    return True
-
-
-@contextlib.contextmanager
-def set_environ(env_name: str, value: str | None) -> Generator[None, None, None]:
-    """Set the environment variable 'env_name' to 'value'
-
-    Save previous value, yield, and then restore the previous value stored in
-    the environment variable 'env_name'.
-
-    If 'value' is None, do nothing"""
-    value_changed = value is not None
-    old_value: str | None = None
-    if value_changed:
-        old_value = os.environ.get(env_name)
-        os.environ[env_name] = value
-    try:
-        yield
-    finally:
-        if value_changed:
-            if old_value is None:
-                del os.environ[env_name]
-            else:
-                os.environ[env_name] = old_value
-
-
-def should_bypass_proxies(url: str, no_proxy: str | None) -> bool:
-    """
-    Returns whether we should bypass proxies or not.
-
-    :rtype: bool
-    """
-
-    # Prioritize lowercase environment variables over uppercase
-    # to keep a consistent behaviour with other http projects (curl, wget).
-    def get_proxy(key: str) -> str | None:
-        return os.environ.get(key) or os.environ.get(key.upper())
-
-    # First check whether no_proxy is defined. If it is, check that the URL
-    # we're getting isn't in the no_proxy list.
-    no_proxy_arg = no_proxy
-    if no_proxy is None:
-        no_proxy = get_proxy("no_proxy")
-    parsed = urlparse(url)
-    hostname = parsed.hostname
-
-    if hostname is None:
-        # URLs don't always have hostnames, e.g. file:/// urls.
-        return True
-
-    if no_proxy:
-        # We need to check whether we match here. We need to see if we match
-        # the end of the hostname, both with and without the port.
-        no_proxy_hosts = (host for host in no_proxy.replace(" ", "").split(",") if host)
-
-        if is_ipv4_address(hostname):
-            for proxy_ip in no_proxy_hosts:
-                if is_valid_cidr(proxy_ip):
-                    if address_in_network(hostname, proxy_ip):
-                        return True
-                elif hostname == proxy_ip:
-                    # If no_proxy ip was defined in plain IP notation instead of cidr notation &
-                    # matches the IP of the index
-                    return True
-        else:
-            host_with_port = hostname
-            if parsed.port:
-                host_with_port += f":{parsed.port}"
-
-            for host in no_proxy_hosts:
-                host = host.lstrip(".")
-                if hostname == host or host_with_port == host:
-                    return True
-                host = "." + host
-                if hostname.endswith(host) or host_with_port.endswith(host):
-                    return True
-
-    with set_environ("no_proxy", no_proxy_arg):
-        try:
-            bypass = proxy_bypass(hostname)
-        except (TypeError, socket.gaierror):
-            bypass = False
-
-    if bypass:
-        return True
-
-    return False
-
-
-def get_environ_proxies(url: str, no_proxy: str | None = None) -> dict[str, str]:
-    """
-    Return a dict of environment proxies.
-
-    :rtype: dict
-    """
-    if should_bypass_proxies(url, no_proxy=no_proxy):
-        return {}
-    else:
-        return getproxies()
-
-
-def select_proxy(url: str, proxies: dict[str, str] | None) -> str | None:
-    """Select a proxy for the url, if applicable.
-
-    :param url: The url being for the request
-    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
-    """
-    proxies = proxies or {}
-    urlparts = urlparse(url)
-    if urlparts.hostname is None:
-        return proxies.get(urlparts.scheme, proxies.get("all"))
-
-    proxy_keys = [
-        urlparts.scheme + "://" + urlparts.hostname,
-        urlparts.scheme,
-        "all://" + urlparts.hostname,
-        "all",
-    ]
-    proxy = None
-    for proxy_key in proxy_keys:
-        if proxy_key in proxies:
-            proxy = proxies[proxy_key]
-            break
-
-    return proxy
-
-
-def resolve_proxies(
-    request: Request | PreparedRequest,
-    proxies: dict[str, str] | None,
-    trust_env: bool = True,
-) -> dict[str, str]:
-    """This method takes proxy information from a request and configuration
-    input to resolve a mapping of target proxies. This will consider settings
-    such as NO_PROXY to strip proxy configurations.
-
-    :param request: Request or PreparedRequest
-    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
-    :param trust_env: Boolean declaring whether to trust environment configs
-
-    :rtype: dict
-    """
-    proxies = proxies if proxies is not None else {}
-    url = cast(str, request.url)
-    scheme = urlparse(url).scheme
-    no_proxy = proxies.get("no_proxy")
-    new_proxies = proxies.copy()
-
-    if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
-        environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
-
-        proxy = environ_proxies.get(scheme, environ_proxies.get("all"))
-
-        if proxy:
-            new_proxies.setdefault(scheme, proxy)
-    return new_proxies
-
-
-def default_user_agent(name: str = "python-requests") -> str:
-    """
-    Return a string representing the default user agent.
-
-    :rtype: str
-    """
-    return f"{name}/{__version__}"
-
-
-def default_headers() -> CaseInsensitiveDict[str]:
-    """
-    :rtype: requests.structures.CaseInsensitiveDict
-    """
-    return CaseInsensitiveDict(
-        {
-            "User-Agent": default_user_agent(),
-            "Accept-Encoding": DEFAULT_ACCEPT_ENCODING,
-            "Accept": "*/*",
-            "Connection": "keep-alive",
-        }
-    )
-
-
-def parse_header_links(value: str) -> list[dict[str, str]]:
-    """Return a list of parsed link headers proxies.
-
-    i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg"
-
-    :rtype: list
-    """
-
-    links: list[dict[str, str]] = []
-
-    replace_chars = " '\""
-
-    value = value.strip(replace_chars)
-    if not value:
-        return links
-
-    for val in re.split(", *<", value):
-        try:
-            url, params = val.split(";", 1)
-        except ValueError:
-            url, params = val, ""
-
-        link: dict[str, str] = {"url": url.strip("<> '\"")}
-
-        for param in params.split(";"):
-            try:
-                key, value = param.split("=")
-            except ValueError:
-                break
-
-            link[key.strip(replace_chars)] = value.strip(replace_chars)
-
-        links.append(link)
-
-    return links
-
-
-# Null bytes; no need to recreate these on each call to guess_json_utf
-_null = "\x00".encode("ascii")  # encoding to ASCII for Python 3
-_null2 = _null * 2
-_null3 = _null * 3
-
-
-def guess_json_utf(data: bytes) -> str | None:
-    """
-    :rtype: str
-    """
-    # JSON always starts with two ASCII characters, so detection is as
-    # easy as counting the nulls and from their location and count
-    # determine the encoding. Also detect a BOM, if present.
-    sample = data[:4]
-    if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):
-        return "utf-32"  # BOM included
-    if sample[:3] == codecs.BOM_UTF8:
-        return "utf-8-sig"  # BOM included, MS style (discouraged)
-    if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):
-        return "utf-16"  # BOM included
-    nullcount = sample.count(_null)
-    if nullcount == 0:
-        return "utf-8"
-    if nullcount == 2:
-        if sample[::2] == _null2:  # 1st and 3rd are null
-            return "utf-16-be"
-        if sample[1::2] == _null2:  # 2nd and 4th are null
-            return "utf-16-le"
-        # Did not detect 2 valid UTF-16 ascii-range characters
-    if nullcount == 3:
-        if sample[:3] == _null3:
-            return "utf-32-be"
-        if sample[1:] == _null3:
-            return "utf-32-le"
-        # Did not detect a valid UTF-32 ascii-range character
-    return None
-
-
-def prepend_scheme_if_needed(url: str, new_scheme: str) -> str:
-    """Given a URL that may or may not have a scheme, prepend the given scheme.
-    Does not replace a present scheme with the one provided as an argument.
-
-    :rtype: str
-    """
-    parsed = parse_url(url)
-    scheme, auth, _host, _port, path, query, fragment = parsed
-
-    # A defect in urlparse determines that there isn't a netloc present in some
-    # urls. We previously assumed parsing was overly cautious, and swapped the
-    # netloc and path. Due to a lack of tests on the original defect, this is
-    # maintained with parse_url for backwards compatibility.
-    netloc = parsed.netloc
-    if not netloc:
-        netloc, path = path, netloc
-
-    if auth:
-        # parse_url doesn't provide the netloc with auth
-        # so we'll add it ourselves.
-        netloc = cast(str, netloc)
-        netloc = "@".join([auth, netloc])
-    if scheme is None:
-        scheme = new_scheme
-    if path is None:
-        path = ""
-
-    return urlunparse((scheme, netloc, path, "", query, fragment))
-
-
-def get_auth_from_url(url: str) -> tuple[str, str]:
-    """Given a url with authentication components, extract them into a tuple of
-    username,password.
-
-    :rtype: (str,str)
-    """
-    parsed = urlparse(url)
-
-    try:
-        # except handles parsed.username/password being None
-        auth = (unquote(parsed.username), unquote(parsed.password))  # type: ignore[arg-type]
-    except (AttributeError, TypeError):
-        auth = ("", "")
-
-    return auth
-
-
-def check_header_validity(header: tuple[str | bytes, str | bytes]) -> None:
-    """Verifies that header parts don't contain leading whitespace
-    reserved characters, or return characters.
-
-    :param header: tuple, in the format (name, value).
-    """
-    name, value = header
-    _validate_header_part(header, name, 0)
-    _validate_header_part(header, value, 1)
-
-
-def _validate_header_part(
-    header: tuple[str | bytes, str | bytes],
-    header_part: str | bytes,
-    header_validator_index: int,
-) -> None:
-    if isinstance(header_part, str):
-        validator = _HEADER_VALIDATORS_STR[header_validator_index]
-    elif isinstance(header_part, bytes):  # type: ignore[reportUnnecessaryIsInstance]
-        # runtime guard for non-str/bytes input
-        validator = _HEADER_VALIDATORS_BYTE[header_validator_index]
-    else:
-        raise InvalidHeader(
-            f"Header part ({header_part!r}) from {header} "
-            f"must be of type str or bytes, not {type(header_part)}"
-        )
-
-    if not validator.match(header_part):  # type: ignore[arg-type]
-        header_kind = "name" if header_validator_index == 0 else "value"
-        raise InvalidHeader(
-            f"Invalid leading whitespace, reserved character(s), or return "
-            f"character(s) in header {header_kind}: {header_part!r}"
-        )
-
-
-def urldefragauth(url: str) -> str:
-    """
-    Given a url remove the fragment and the authentication part.
-
-    :rtype: str
-    """
-    scheme, netloc, path, params, query, _fragment = urlparse(url)
-
-    # see func:`prepend_scheme_if_needed`
-    if not netloc:
-        netloc, path = path, netloc
-
-    netloc = netloc.rsplit("@", 1)[-1]
-
-    return urlunparse((scheme, netloc, path, params, query, ""))
-
-
-def rewind_body(prepared_request: PreparedRequest) -> None:
-    """Move file pointer back to its recorded starting position
-    so it can be read again on redirect.
-    """
-    body_seek = getattr(prepared_request.body, "seek", None)
-    if body_seek is not None and isinstance(
-        prepared_request._body_position,  # type: ignore[reportPrivateUsage]
-        integer_types,
-    ):
-        try:
-            body_seek(prepared_request._body_position)  # type: ignore[reportPrivateUsage]
-        except OSError:
-            raise UnrewindableBodyError(
-                "An error occurred when rewinding request body for redirect."
-            )
-    else:
-        raise UnrewindableBodyError("Unable to rewind request body for redirect.")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE
deleted file mode 100644
index c781ecbf698..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel-yaml.LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
- The MIT License (MIT)
-
- Copyright (c) 2014-2026 Anthon van der Neut, Ruamel bvba
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py
deleted file mode 100644
index bd6df7d3858..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/__init__.py
+++ /dev/null
@@ -1,51 +0,0 @@
-
-from __future__ import annotations
-
-if False:  # MYPY
-    from typing import Dict, Any  # NOQA
-
-_package_data = dict(
-    full_package_name='ruamel.yaml',
-    version_info=(0, 19, 1),
-    __version__='0.19.1',
-    version_timestamp='2026-01-02 17:17:31',
-    author='Anthon van der Neut',
-    author_email='a.van.der.neut@ruamel.eu',
-    description='ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order',  # NOQA
-    entry_points=None,
-    since=2014,
-    extras_require={
-        'oldlibyaml' : ['ruamel.yaml.clib; platform_python_implementation=="CPython"'],  # NOQA
-        'libyaml' : ['ruamel.yaml.clibz>=0.3.7; platform_python_implementation=="CPython"'],  # NOQA
-        'jinja2': ['ruamel.yaml.jinja2>=0.2'],
-        'docs': ['ryd', 'mercurial>5.7'],
-    },
-    classifiers=[
-        'Programming Language :: Python :: Implementation :: CPython',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-        'Topic :: Text Processing :: Markup',
-        'Typing :: Typed',
-    ],
-    keywords='yaml 1.2 parser round-trip preserve quotes order config',
-    url_doc='https://yaml.dev/doc/{full_package_name}',
-    tox=dict(
-        env='*',
-        fl8excl='_test/lib,branch_default',
-    ),
-    # universal=True,
-    supported=[(3, 9)],  # minimum
-)  # type: Dict[Any, Any]
-
-
-version_info = _package_data['version_info']
-__version__ = _package_data['__version__']
-
-try:
-    from .cyaml import *  # NOQA
-
-    __with_libyaml__ = True
-except (ImportError, ValueError):  # for Jython
-    __with_libyaml__ = False
-    __yaml_lib = None
-
-from opentelemetry.agent._vendor.ruamel.yaml.main import *  # NOQA
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py
deleted file mode 100644
index 4f342f3e0b9..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/anchor.py
+++ /dev/null
@@ -1,20 +0,0 @@
-
-from __future__ import annotations
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Union, Iterator  # NOQA
-
-anchor_attrib = '_yaml_anchor'
-
-
-class Anchor:
-    __slots__ = 'value', 'always_dump'
-    attrib = anchor_attrib
-
-    def __init__(self) -> None:
-        self.value = None
-        self.always_dump = False
-
-    def __repr__(self) -> Any:
-        ad = ', (always dump)' if self.always_dump else ""
-        return f'Anchor({self.value!r}{ad})'
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py
deleted file mode 100644
index fe652fc449c..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/comments.py
+++ /dev/null
@@ -1,1208 +0,0 @@
-
-from __future__ import annotations
-
-"""
-stuff to deal with comments and formatting on dict/list/ordereddict/set
-these are not really related, formatting could be factored out as
-a separate base
-"""
-
-import sys
-import copy
-
-
-from opentelemetry.agent._vendor.ruamel.yaml.compat import ordereddict
-from opentelemetry.agent._vendor.ruamel.yaml.compat import MutableSliceableSequence, nprintf  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.scalarstring import ScalarString
-from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
-from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
-
-from collections.abc import MutableSet, Sized, Set, Mapping
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Union, Iterator  # NOQA
-
-# fmt: off
-__all__ = ['CommentedSeq', 'CommentedKeySeq',
-           'CommentedMap', 'CommentedOrderedMap',
-           'CommentedSet', 'comment_attrib', 'merge_attrib',
-           'TaggedScalar',
-           'C_POST', 'C_PRE', 'C_SPLIT_ON_FIRST_BLANK', 'C_BLANK_LINE_PRESERVE_SPACE',
-           ]
-# fmt: on
-
-# splitting of comments by the scanner
-# an EOLC (End-Of-Line Comment) is preceded by some token
-# an FLC (Full Line Comment) is a comment not preceded by a token, i.e. # is
-#   the first non-blank on line
-# a BL is a blank line i.e. empty or spaces/tabs only
-# bits 0 and 1 are combined, you can choose only one
-C_POST = 0b00
-C_PRE = 0b01
-C_SPLIT_ON_FIRST_BLANK = 0b10  # as C_POST, but if blank line then C_PRE all lines before
-# first blank goes to POST even if no following real FLC
-# (first blank -> first of post)
-# 0b11 -> reserved for future use
-C_BLANK_LINE_PRESERVE_SPACE = 0b100
-# C_EOL_PRESERVE_SPACE2 = 0b1000
-
-
-class IDX:
-    # temporary auto increment, so rearranging is easier
-    def __init__(self) -> None:
-        self._idx = 0
-
-    def __call__(self) -> Any:
-        x = self._idx
-        self._idx += 1
-        return x
-
-    def __str__(self) -> Any:
-        return str(self._idx)
-
-
-cidx = IDX()
-
-# more or less in order of subjective expected likelyhood
-# the _POST and _PRE ones are lists themselves
-C_VALUE_EOL = C_ELEM_EOL = cidx()
-C_KEY_EOL = cidx()
-C_KEY_PRE = C_ELEM_PRE = cidx()  # not this is not value
-C_VALUE_POST = C_ELEM_POST = cidx()  # not this is not value
-C_VALUE_PRE = cidx()
-C_KEY_POST = cidx()
-C_TAG_EOL = cidx()
-C_TAG_POST = cidx()
-C_TAG_PRE = cidx()
-C_ANCHOR_EOL = cidx()
-C_ANCHOR_POST = cidx()
-C_ANCHOR_PRE = cidx()
-
-
-comment_attrib = '_yaml_comment'
-format_attrib = '_yaml_format'
-line_col_attrib = '_yaml_line_col'
-merge_attrib = '_yaml_merge'
-
-
-class Comment:
-    # using sys.getsize tested the Comment objects, __slots__ makes them bigger
-    # and adding self.end did not matter
-    __slots__ = 'comment', '_items', '_post', '_pre'
-    attrib = comment_attrib
-
-    def __init__(self, old: bool = True) -> None:
-        self._pre = None if old else []  # type: ignore
-        self.comment = None  # [post, [pre]]
-        # map key (mapping/omap/dict) or index (sequence/list) to a  list of
-        # dict: post_key, pre_key, post_value, pre_value
-        # list: pre item, post item
-        self._items: Dict[Any, Any] = {}
-        # self._start = [] # should not put these on first item
-        self._post: List[Any] = []  # end of document comments
-
-    def __str__(self) -> str:
-        if bool(self._post):
-            end = ',\n  end=' + str(self._post)
-        else:
-            end = ""
-        return f'Comment(comment={self.comment},\n  items={self._items}{end})'
-
-    def _old__repr__(self) -> str:
-        if bool(self._post):
-            end = ',\n  end=' + str(self._post)
-        else:
-            end = ""
-        try:
-            ln = max([len(str(k)) for k in self._items]) + 1
-        except ValueError:
-            ln = ''  # type: ignore
-        it = '    '.join([f'{str(k) + ":":{ln}} {v}\n' for k, v in self._items.items()])
-        if it:
-            it = '\n    ' + it + '  '
-        return f'Comment(\n  start={self.comment},\n  items={{{it}}}{end})'
-
-    def __repr__(self) -> str:
-        if self._pre is None:
-            return self._old__repr__()
-        if bool(self._post):
-            end = ',\n  end=' + repr(self._post)
-        else:
-            end = ""
-        try:
-            ln = max([len(str(k)) for k in self._items]) + 1
-        except ValueError:
-            ln = ''  # type: ignore
-        it = '    '.join([f'{str(k) + ":":{ln}} {v}\n' for k, v in self._items.items()])
-        if it:
-            it = '\n    ' + it + '  '
-        return f'Comment(\n  pre={self.pre},\n  items={{{it}}}{end})'
-
-    @property
-    def items(self) -> Any:
-        return self._items
-
-    @property
-    def end(self) -> Any:
-        return self._post
-
-    @end.setter
-    def end(self, value: Any) -> None:
-        self._post = value
-
-    @property
-    def pre(self) -> Any:
-        return self._pre
-
-    @pre.setter
-    def pre(self, value: Any) -> None:
-        self._pre = value
-
-    def get(self, item: Any, pos: Any) -> Any:
-        x = self._items.get(item)
-        if x is None or len(x) < pos:
-            return None
-        return x[pos]  # can be None
-
-    def set(self, item: Any, pos: Any, value: Any) -> Any:
-        x = self._items.get(item)
-        if x is None:
-            self._items[item] = x = [None] * (pos + 1)
-        else:
-            while len(x) <= pos:
-                x.append(None)
-        assert x[pos] is None
-        x[pos] = value
-
-    def __contains__(self, x: Any) -> Any:
-        # test if a substring is in any of the attached comments
-        if self.comment:
-            if self.comment[0] and x in self.comment[0].value:
-                return True
-            if self.comment[1]:
-                for c in self.comment[1]:
-                    if x in c.value:
-                        return True
-        for value in self.items.values():
-            if not value:
-                continue
-            for c in value:
-                if c and x in c.value:
-                    return True
-        if self.end:
-            for c in self.end:
-                if x in c.value:
-                    return True
-        return False
-
-
-# to distinguish key from None
-class NotNone:
-    pass  # NOQA
-
-
-class Format:
-    __slots__ = ('_flow_style',)
-    attrib = format_attrib
-
-    def __init__(self) -> None:
-        self._flow_style: Any = None
-
-    def set_flow_style(self) -> None:
-        self._flow_style = True
-
-    def set_block_style(self) -> None:
-        self._flow_style = False
-
-    def flow_style(self, default: Optional[Any] = None) -> Any:
-        """if default (the flow_style) is None, the flow style tacked on to
-        the object explicitly will be taken. If that is None as well the
-        default flow style rules the format down the line, or the type
-        of the constituent values (simple -> flow, map/list -> block)"""
-        if self._flow_style is None:
-            return default
-        return self._flow_style
-
-    def __repr__(self) -> str:
-        return f'Format({self._flow_style})'
-
-
-class LineCol:
-    """
-    line and column information wrt document, values start at zero (0)
-    """
-
-    attrib = line_col_attrib
-
-    def __init__(self) -> None:
-        self.line = None
-        self.col = None
-        self.data: Optional[Dict[Any, Any]] = None
-
-    def add_kv_line_col(self, key: Any, data: Any) -> None:
-        if self.data is None:
-            self.data = {}
-        self.data[key] = data
-
-    def key(self, k: Any) -> Any:
-        return self._kv(k, 0, 1)
-
-    def value(self, k: Any) -> Any:
-        return self._kv(k, 2, 3)
-
-    def _kv(self, k: Any, x0: Any, x1: Any) -> Any:
-        if self.data is None:
-            return None
-        data = self.data[k]
-        return data[x0], data[x1]
-
-    def item(self, idx: Any) -> Any:
-        if self.data is None:
-            return None
-        return self.data[idx][0], self.data[idx][1]
-
-    def add_idx_line_col(self, key: Any, data: Any) -> None:
-        if self.data is None:
-            self.data = {}
-        self.data[key] = data
-
-    def __repr__(self) -> str:
-        return f'LineCol({self.line}, {self.col})'
-
-
-class CommentedBase:
-    @property
-    def ca(self):
-        # type: () -> Any
-        if not hasattr(self, Comment.attrib):
-            setattr(self, Comment.attrib, Comment())
-        return getattr(self, Comment.attrib)
-
-    def yaml_end_comment_extend(self, comment: Any, clear: bool = False) -> None:
-        if comment is None:
-            return
-        if clear or self.ca.end is None:
-            self.ca.end = []
-        self.ca.end.extend(comment)
-
-    def yaml_key_comment_extend(self, key: Any, comment: Any, clear: bool = False) -> None:
-        r = self.ca._items.setdefault(key, [None, None, None, None])
-        if clear or r[1] is None:
-            if comment[1] is not None:
-                assert isinstance(comment[1], list)
-            r[1] = comment[1]
-        else:
-            r[1].extend(comment[0])
-        r[0] = comment[0]
-
-    def yaml_value_comment_extend(self, key: Any, comment: Any, clear: bool = False) -> None:
-        r = self.ca._items.setdefault(key, [None, None, None, None])
-        if clear or r[3] is None:
-            if comment[1] is not None:
-                assert isinstance(comment[1], list)
-            r[3] = comment[1]
-        else:
-            r[3].extend(comment[0])
-        r[2] = comment[0]
-
-    def yaml_set_start_comment(self, comment: Any, indent: Any = 0) -> None:
-        """overwrites any preceding comment lines on an object
-        expects comment to be without `#` and possible have multiple lines
-        """
-        from .error import CommentMark
-        from .tokens import CommentToken
-
-        pre_comments = self._yaml_clear_pre_comment()  # type: ignore
-        if comment[-1] == '\n':
-            comment = comment[:-1]  # strip final newline if there
-        start_mark = CommentMark(indent)
-        for com in comment.split('\n'):
-            c = com.strip()
-            if len(c) > 0 and c[0] != '#':
-                com = '# ' + com
-            pre_comments.append(CommentToken(com + '\n', start_mark))
-
-    def yaml_set_comment_before_after_key(
-        self,
-        key: Any,
-        before: Any = None,
-        indent: Any = 0,
-        after: Any = None,
-        after_indent: Any = None,
-    ) -> None:
-        """
-        expects comment (before/after) to be without `#` and possible have multiple lines
-        """
-        from opentelemetry.agent._vendor.ruamel.yaml.error import CommentMark
-        from opentelemetry.agent._vendor.ruamel.yaml.tokens import CommentToken
-
-        def comment_token(s: Any, mark: Any) -> Any:
-            # handle empty lines as having no comment
-            return CommentToken(('# ' if s else "") + s + '\n', mark)
-
-        if after_indent is None:
-            after_indent = indent + 2
-        if before and (len(before) > 1) and before[-1] == '\n':
-            before = before[:-1]  # strip final newline if there
-        if after and after[-1] == '\n':
-            after = after[:-1]  # strip final newline if there
-        start_mark = CommentMark(indent)
-        c = self.ca.items.setdefault(key, [None, [], None, None])
-        if before is not None:
-            if c[1] is None:
-                c[1] = []
-            if before == '\n':
-                c[1].append(comment_token("", start_mark))  # type: ignore
-            else:
-                for com in before.split('\n'):
-                    c[1].append(comment_token(com, start_mark))  # type: ignore
-        if after:
-            start_mark = CommentMark(after_indent)
-            if c[3] is None:
-                c[3] = []
-            for com in after.split('\n'):
-                c[3].append(comment_token(com, start_mark))  # type: ignore
-
-    @property
-    def fa(self) -> Any:
-        """format attribute
-
-        set_flow_style()/set_block_style()"""
-        if not hasattr(self, Format.attrib):
-            setattr(self, Format.attrib, Format())
-        return getattr(self, Format.attrib)
-
-    def yaml_add_eol_comment(
-        self, comment: Any, key: Optional[Any] = NotNone, column: Optional[Any] = None,
-    ) -> None:
-        """
-        there is a problem as eol comments should start with ' #'
-        (but at the beginning of the line the space doesn't have to be before
-        the #. The column index is for the # mark
-        """
-        from .tokens import CommentToken
-        from .error import CommentMark
-
-        if column is None:
-            try:
-                column = self._yaml_get_column(key)
-            except AttributeError:
-                column = 0
-        if comment[0] != '#':
-            comment = '# ' + comment
-        if column is None:
-            if comment[0] == '#':
-                comment = ' ' + comment
-                column = 0
-        start_mark = CommentMark(column)
-        ct = [CommentToken(comment, start_mark), None]
-        self._yaml_add_eol_comment(ct, key=key)
-
-    @property
-    def lc(self) -> Any:
-        if not hasattr(self, LineCol.attrib):
-            setattr(self, LineCol.attrib, LineCol())
-        return getattr(self, LineCol.attrib)
-
-    def _yaml_set_line_col(self, line: Any, col: Any) -> None:
-        self.lc.line = line
-        self.lc.col = col
-
-    def _yaml_set_kv_line_col(self, key: Any, data: Any) -> None:
-        self.lc.add_kv_line_col(key, data)
-
-    def _yaml_set_idx_line_col(self, key: Any, data: Any) -> None:
-        self.lc.add_idx_line_col(key, data)
-
-    @property
-    def anchor(self) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            setattr(self, Anchor.attrib, Anchor())
-        return getattr(self, Anchor.attrib)
-
-    def yaml_anchor(self) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            return None
-        return self.anchor
-
-    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
-        self.anchor.value = value
-        self.anchor.always_dump = always_dump
-
-    @property
-    def tag(self) -> Any:
-        if not hasattr(self, Tag.attrib):
-            setattr(self, Tag.attrib, Tag())
-        return getattr(self, Tag.attrib)
-
-    def yaml_set_ctag(self, value: Tag) -> None:
-        setattr(self, Tag.attrib, value)
-
-    def copy_attributes(self, t: Any, memo: Any = None) -> Any:
-        """
-        copies the YAML related attributes, not e.g. .values
-        returns target
-        """
-        # fmt: off
-        for a in [Comment.attrib, Format.attrib, LineCol.attrib, Anchor.attrib,
-                  Tag.attrib, merge_attrib]:
-            if hasattr(self, a):
-                if memo is not None:
-                    setattr(t, a, copy.deepcopy(getattr(self, a, memo)))
-                else:
-                    setattr(t, a, getattr(self, a))
-        return t
-        # fmt: on
-
-    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
-        raise NotImplementedError
-
-    def _yaml_get_pre_comment(self) -> Any:
-        raise NotImplementedError
-
-    def _yaml_get_column(self, key: Any) -> Any:
-        raise NotImplementedError
-
-
-class CommentedSeq(MutableSliceableSequence, list, CommentedBase):  # type: ignore
-    __slots__ = (Comment.attrib, '_lst')
-
-    def __init__(self, *args: Any, **kw: Any) -> None:
-        list.__init__(self, *args, **kw)
-
-    def __getsingleitem__(self, idx: Any) -> Any:
-        return list.__getitem__(self, idx)
-
-    def __setsingleitem__(self, idx: Any, value: Any) -> None:
-        # try to preserve the scalarstring type if setting an existing key to a new value
-        if idx < len(self):
-            if (
-                isinstance(value, str)
-                and not isinstance(value, ScalarString)
-                and isinstance(self[idx], ScalarString)
-            ):
-                value = type(self[idx])(value)
-        list.__setitem__(self, idx, value)
-
-    def __delsingleitem__(self, idx: Any = None) -> Any:
-        list.__delitem__(self, idx)
-        self.ca.items.pop(idx, None)  # might not be there -> default value
-        for list_index in sorted(self.ca.items):
-            if list_index < idx:
-                continue
-            self.ca.items[list_index - 1] = self.ca.items.pop(list_index)
-
-    def __len__(self) -> int:
-        return list.__len__(self)
-
-    def insert(self, idx: Any, val: Any) -> None:
-        """the comments after the insertion have to move forward"""
-        list.insert(self, idx, val)
-        for list_index in sorted(self.ca.items, reverse=True):
-            if list_index < idx:
-                break
-            self.ca.items[list_index + 1] = self.ca.items.pop(list_index)
-
-    def extend(self, val: Any) -> None:
-        list.extend(self, val)
-
-    def __eq__(self, other: Any) -> bool:
-        return list.__eq__(self, other)
-
-    def _yaml_add_comment(self, comment: Any, key: Optional[Any] = NotNone) -> None:
-        if key is not NotNone:
-            self.yaml_key_comment_extend(key, comment)
-        else:
-            self.ca.comment = comment
-
-    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
-        self._yaml_add_comment(comment, key=key)
-
-    def _yaml_get_columnX(self, key: Any) -> Any:
-        return self.ca.items[key][0].start_mark.column
-
-    def _yaml_get_column(self, key: Any) -> Any:
-        column = None
-        sel_idx = None
-        pre, post = key - 1, key + 1
-        if pre in self.ca.items:
-            sel_idx = pre
-        elif post in self.ca.items:
-            sel_idx = post
-        else:
-            # self.ca.items is not ordered
-            for row_idx, _k1 in enumerate(self):
-                if row_idx >= key:
-                    break
-                if row_idx not in self.ca.items:
-                    continue
-                sel_idx = row_idx
-        if sel_idx is not None:
-            column = self._yaml_get_columnX(sel_idx)
-        return column
-
-    def _yaml_get_pre_comment(self) -> Any:
-        pre_comments: List[Any] = []
-        if self.ca.comment is None:
-            self.ca.comment = [None, pre_comments]
-        else:
-            pre_comments = self.ca.comment[1]
-        return pre_comments
-
-    def _yaml_clear_pre_comment(self) -> Any:
-        pre_comments: List[Any] = []
-        if self.ca.comment is None:
-            self.ca.comment = [None, pre_comments]
-        else:
-            self.ca.comment[1] = pre_comments
-        return pre_comments
-
-    def __deepcopy__(self, memo: Any) -> Any:
-        res = self.__class__()
-        memo[id(self)] = res
-        for k in self:
-            res.append(copy.deepcopy(k, memo))
-            self.copy_attributes(res, memo=memo)
-        return res
-
-    def __add__(self, other: Any) -> Any:
-        return list.__add__(self, other)
-
-    def sort(self, key: Any = None, reverse: bool = False) -> None:
-        if key is None:
-            tmp_lst = sorted(zip(self, range(len(self))), reverse=reverse)
-            list.__init__(self, [x[0] for x in tmp_lst])
-        else:
-            tmp_lst = sorted(
-                zip(map(key, list.__iter__(self)), range(len(self))), reverse=reverse,
-            )
-            list.__init__(self, [list.__getitem__(self, x[1]) for x in tmp_lst])
-        itm = self.ca.items
-        self.ca._items = {}
-        for idx, x in enumerate(tmp_lst):
-            old_index = x[1]
-            if old_index in itm:
-                self.ca.items[idx] = itm[old_index]
-
-    def __repr__(self) -> Any:
-        return list.__repr__(self)
-
-
-class CommentedKeySeq(tuple, CommentedBase):  # type: ignore
-    """This primarily exists to be able to roundtrip keys that are sequences"""
-
-    def _yaml_add_comment(self, comment: Any, key: Optional[Any] = NotNone) -> None:
-        if key is not NotNone:
-            self.yaml_key_comment_extend(key, comment)
-        else:
-            self.ca.comment = comment
-
-    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
-        self._yaml_add_comment(comment, key=key)
-
-    def _yaml_get_columnX(self, key: Any) -> Any:
-        return self.ca.items[key][0].start_mark.column
-
-    def _yaml_get_column(self, key: Any) -> Any:
-        column = None
-        sel_idx = None
-        pre, post = key - 1, key + 1
-        if pre in self.ca.items:
-            sel_idx = pre
-        elif post in self.ca.items:
-            sel_idx = post
-        else:
-            # self.ca.items is not ordered
-            for row_idx, _k1 in enumerate(self):
-                if row_idx >= key:
-                    break
-                if row_idx not in self.ca.items:
-                    continue
-                sel_idx = row_idx
-        if sel_idx is not None:
-            column = self._yaml_get_columnX(sel_idx)
-        return column
-
-    def _yaml_get_pre_comment(self) -> Any:
-        pre_comments: List[Any] = []
-        if self.ca.comment is None:
-            self.ca.comment = [None, pre_comments]
-        else:
-            pre_comments = self.ca.comment[1]
-        return pre_comments
-
-    def _yaml_clear_pre_comment(self) -> Any:
-        pre_comments: List[Any] = []
-        if self.ca.comment is None:
-            self.ca.comment = [None, pre_comments]
-        else:
-            self.ca.comment[1] = pre_comments
-        return pre_comments
-
-
-class CommentedMapView(Sized):
-    __slots__ = ('_mapping',)
-
-    def __init__(self, mapping: Any) -> None:
-        self._mapping = mapping
-
-    def __len__(self) -> int:
-        count = len(self._mapping)
-        return count
-
-
-class CommentedMapKeysView(CommentedMapView, Set):  # type: ignore
-    __slots__ = ()
-
-    @classmethod
-    def _from_iterable(self, it: Any) -> Any:
-        return set(it)
-
-    def __contains__(self, key: Any) -> Any:
-        return key in self._mapping
-
-    def __iter__(self) -> Any:
-        # yield from self._mapping  # not in py27, pypy
-        # for x in self._mapping._keys():
-        for x in self._mapping:
-            yield x
-
-
-class CommentedMapItemsView(CommentedMapView, Set):  # type: ignore
-    __slots__ = ()
-
-    @classmethod
-    def _from_iterable(self, it: Any) -> Any:
-        return set(it)
-
-    def __contains__(self, item: Any) -> Any:
-        key, value = item
-        try:
-            v = self._mapping[key]
-        except KeyError:
-            return False
-        else:
-            return v == value
-
-    def __iter__(self) -> Any:
-        for key in self._mapping._keys():
-            yield (key, self._mapping[key])
-
-
-class CommentedMapValuesView(CommentedMapView):
-    __slots__ = ()
-
-    def __contains__(self, value: Any) -> Any:
-        for key in self._mapping:
-            if value == self._mapping[key]:
-                return True
-        return False
-
-    def __iter__(self) -> Any:
-        for key in self._mapping._keys():
-            yield self._mapping[key]
-
-
-class CommentedMap(ordereddict, CommentedBase):
-    __slots__ = (Comment.attrib, '_ok', '_ref')
-
-    def __init__(self, *args: Any, **kw: Any) -> None:
-        self._ok: MutableSet[Any] = set()  # own keys
-        self._ref: List[CommentedMap] = []
-        ordereddict.__init__(self, *args, **kw)
-
-    def _yaml_add_comment(
-        self, comment: Any, key: Optional[Any] = NotNone, value: Optional[Any] = NotNone,
-    ) -> None:
-        """values is set to key to indicate a value attachment of comment"""
-        if key is not NotNone:
-            self.yaml_key_comment_extend(key, comment)
-            return
-        if value is not NotNone:
-            self.yaml_value_comment_extend(value, comment)
-        else:
-            self.ca.comment = comment
-
-    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
-        """add on the value line, with value specified by the key"""
-        self._yaml_add_comment(comment, value=key)
-
-    def _yaml_get_columnX(self, key: Any) -> Any:
-        return self.ca.items[key][2].start_mark.column
-
-    def _yaml_get_column(self, key: Any) -> Any:
-        column = None
-        sel_idx = None
-        pre, post, last = None, None, None
-        for x in self:
-            if pre is not None and x != key:
-                post = x
-                break
-            if x == key:
-                pre = last
-            last = x
-        if pre in self.ca.items:
-            sel_idx = pre
-        elif post in self.ca.items:
-            sel_idx = post
-        else:
-            # self.ca.items is not ordered
-            for k1 in self:
-                if k1 >= key:
-                    break
-                if k1 not in self.ca.items:
-                    continue
-                sel_idx = k1
-        if sel_idx is not None:
-            column = self._yaml_get_columnX(sel_idx)
-        return column
-
-    def _yaml_get_pre_comment(self) -> Any:
-        pre_comments: List[Any] = []
-        if self.ca.comment is None:
-            self.ca.comment = [None, pre_comments]
-        else:
-            pre_comments = self.ca.comment[1]
-        return pre_comments
-
-    def _yaml_clear_pre_comment(self) -> Any:
-        pre_comments: List[Any] = []
-        if self.ca.comment is None:
-            self.ca.comment = [None, pre_comments]
-        else:
-            self.ca.comment[1] = pre_comments
-        return pre_comments
-
-    def update(self, *vals: Any, **kw: Any) -> None:
-        try:
-            ordereddict.update(self, *vals, **kw)
-        except TypeError:
-            # probably a dict that is used
-            for x in vals[0]:
-                self[x] = vals[0][x]
-        if vals:
-            try:
-                self._ok.update(vals[0].keys())  # type: ignore
-            except AttributeError:
-                # assume one argument that is a list/tuple of two element lists/tuples
-                for x in vals[0]:
-                    self._ok.add(x[0])
-        if kw:
-            self._ok.update(*kw.keys())  # type: ignore
-
-    def insert(self, pos: Any, key: Any, value: Any, comment: Optional[Any] = None) -> None:
-        """insert key value into given position, as defined by source YAML
-        attach comment if provided
-        """
-        if key in self._ok:
-            del self[key]
-        keys = [k for k in self.keys() if k in self._ok]
-        try:
-            merge_value = getattr(self, merge_attrib)
-            merge_pos = merge_value.merge_pos
-        except (AttributeError, IndexError):
-            merge_pos = -1
-        if merge_pos >= 0:
-            if merge_pos >= pos:
-                # getattr(self, merge_attrib)[0] = (merge_pos + 1, ma0[1])
-                merge_value.merge_pos += 1
-                idx_min = pos
-                idx_max = len(self._ok)
-            else:
-                idx_min = pos - 1
-                idx_max = len(self._ok)
-        else:
-            idx_min = pos
-            idx_max = len(self._ok)
-        self[key] = value  # at the end
-        # print(f'{idx_min=} {idx_max=}')
-        for idx in range(idx_min, idx_max):
-            self.move_to_end(keys[idx])
-        self._ok.add(key)
-        # for referer in self._ref:
-        #     for keytmp in keys:
-        #         referer.update_key_value(keytmp)
-        if comment is not None:
-            self.yaml_add_eol_comment(comment, key=key)
-
-    def mlget(self, key: Any, default: Any = None, list_ok: Any = False) -> Any:
-        """multi-level get that expects dicts within dicts"""
-        if not isinstance(key, list):
-            return self.get(key, default)
-        # assume that the key is a list of recursively accessible dicts
-
-        def get_one_level(key_list: Any, level: Any, d: Any) -> Any:
-            if not list_ok:
-                assert isinstance(d, dict)
-            if level >= len(key_list):
-                if level > len(key_list):
-                    raise IndexError
-                return d[key_list[level - 1]]
-            return get_one_level(key_list, level + 1, d[key_list[level - 1]])
-
-        try:
-            return get_one_level(key, 1, self)
-        except KeyError:
-            return default
-        except (TypeError, IndexError):
-            if not list_ok:
-                raise
-            return default
-
-    def __getitem__(self, key: Any) -> Any:
-        try:
-            return ordereddict.__getitem__(self, key)
-        except KeyError:
-            for merged in getattr(self, merge_attrib, []):
-                # if isinstance(merged, tuple):
-                #     if key in merged[1]:
-                #         return merged[1][key]
-                # else:
-                if True:
-                    if key in merged:
-                        return merged[key]
-            raise
-
-    def __setitem__(self, key: Any, value: Any) -> None:
-        # try to preserve the scalarstring type if setting an existing key to a new value
-        if key in self:
-            if (
-                isinstance(value, str)
-                and not isinstance(value, ScalarString)
-                and isinstance(self[key], ScalarString)
-            ):
-                value = type(self[key])(value)
-        ordereddict.__setitem__(self, key, value)
-        self._ok.add(key)
-
-    def _unmerged_contains(self, key: Any) -> Any:
-        if key in self._ok:
-            return True
-        return None
-
-    def __contains__(self, key: Any) -> bool:
-        return bool(ordereddict.__contains__(self, key))
-
-    def get(self, key: Any, default: Any = None) -> Any:
-        try:
-            return self.__getitem__(key)
-        except:  # NOQA
-            return default
-
-    def __repr__(self) -> Any:
-        res = '{'
-        sep = ''
-        for k, v in self.items():
-            res += f'{sep}{k!r}: {v!r}'
-            if not sep:
-                sep = ', '
-        res += '}'
-        return res
-
-    def non_merged_items(self) -> Any:
-        for x in ordereddict.__iter__(self):
-            if x in self._ok:
-                yield x, ordereddict.__getitem__(self, x)
-
-    def __delitem__(self, key: Any) -> None:
-        # for merged in getattr(self, merge_attrib, []):
-        #     if key in merged[1]:
-        #         value = merged[1][key]
-        #         break
-        # else:
-        #     # not found in merged in stuff
-        #     ordereddict.__delitem__(self, key)
-        #    for referer in self._ref:
-        #        referer.update=_key_value(key)
-        #    return
-        #
-        # ordereddict.__setitem__(self, key, value)  # merge might have different value
-        # self._ok.discard(key)
-
-        try:
-            merge_value = getattr(self, merge_attrib)
-            merge_pos = merge_value.merge_pos
-        except AttributeError:
-            merge_pos = -1
-        if merge_pos >= 0:
-            try:
-                pos = list(ordereddict.keys(self)).index(key)
-                # the merge is not in the dict, so don't use >=
-                if merge_pos > pos:
-                    merge_value.merge_pos -= 1
-            except ValueError:
-                pass  # let the removal of the key throw a "normal" error
-        self._ok.discard(key)
-        ordereddict.__delitem__(self, key)
-        for referer in self._ref:
-            referer.update_key_value(key)
-
-    def __iter__(self) -> Any:
-        for x in ordereddict.__iter__(self):
-            yield x
-
-    def pop(self, key: Any, default: Any = NotNone) -> Any:
-        try:
-            result = self[key]
-        except KeyError:
-            if default is NotNone:
-                raise
-            return default
-        del self[key]
-        return result
-
-    def _keys(self) -> Any:
-        for x in ordereddict.__iter__(self):
-            yield x
-
-    def __len__(self) -> int:
-        return int(ordereddict.__len__(self))
-
-    def __eq__(self, other: Any) -> bool:
-        return bool(dict(self) == other)
-
-    def keys(self) -> Any:
-        return CommentedMapKeysView(self)
-
-    def values(self) -> Any:
-        return CommentedMapValuesView(self)
-
-    def _items(self) -> Any:
-        for x in ordereddict.__iter__(self):
-            yield x, ordereddict.__getitem__(self, x)
-
-    def items(self) -> Any:
-        return CommentedMapItemsView(self)
-
-    @property
-    def merge(self) -> Any:
-        if not hasattr(self, merge_attrib):
-            setattr(self, merge_attrib, [])
-        return getattr(self, merge_attrib)
-
-    def copy(self) -> Any:
-        x = type(self)()  # update doesn't work
-        for k, v in self._items():
-            x[k] = v
-        self.copy_attributes(x)
-        return x
-
-    def add_referent(self, cm: Any) -> None:
-        if cm not in self._ref:
-            self._ref.append(cm)
-
-    def add_yaml_merge(self, value: Any) -> None:
-        assert not hasattr(self, merge_attrib)
-        setattr(self, merge_attrib, value)
-        for v in value:
-            # if isinstance(v, tuple):
-            #     assert len(v) == 2
-            #     # print('vvv', v, type(v[1]))
-            #     v[1].add_referent(self)
-            #     for k1, v1 in v[1].items():
-            #         if ordereddict.__contains__(self, k1):
-            #             continue
-            #         ordereddict.__setitem__(self, k1, v1)
-            # else:
-            if True:
-                v.add_referent(self)
-                for k1, v1 in v.items():
-                    if ordereddict.__contains__(self, k1):
-                        continue
-                    ordereddict.__setitem__(self, k1, v1)
-
-    def update_key_value(self, key: Any) -> None:
-        if key in self._ok:
-            return
-        for v in self.merge:
-            if key in v[1]:
-                ordereddict.__setitem__(self, key, v[1][key])
-                return
-        ordereddict.__delitem__(self, key)
-
-    def __deepcopy__(self, memo: Any) -> Any:
-        res = self.__class__()
-        memo[id(self)] = res
-        for k in self:
-            res[k] = copy.deepcopy(self[k], memo)
-        self.copy_attributes(res, memo=memo)
-        return res
-
-
-# based on brownie mappings
-@classmethod  # type: ignore
-def raise_immutable(cls: Any, *args: Any, **kwargs: Any) -> None:
-    raise TypeError(f'{cls.__name__} objects are immutable')
-
-
-class CommentedKeyMap(CommentedBase, Mapping):  # type: ignore
-    __slots__ = Comment.attrib, '_od'
-    """This primarily exists to be able to roundtrip keys that are mappings"""
-
-    def __init__(self, *args: Any, **kw: Any) -> None:
-        if hasattr(self, '_od'):
-            raise_immutable(self)
-        try:
-            self._od = ordereddict(*args, **kw)
-        except TypeError:
-            raise
-
-    __delitem__ = __setitem__ = clear = pop = popitem = setdefault = update = raise_immutable
-
-    # need to implement __getitem__, __iter__ and __len__
-    def __getitem__(self, index: Any) -> Any:
-        return self._od[index]
-
-    def __iter__(self) -> Iterator[Any]:
-        for x in self._od.__iter__():
-            yield x
-
-    def __len__(self) -> int:
-        return len(self._od)
-
-    def __hash__(self) -> Any:
-        return hash(tuple(self.items()))
-
-    def __repr__(self) -> Any:
-        if not hasattr(self, merge_attrib):
-            return self._od.__repr__()
-        return 'ordereddict(' + repr(list(self._od.items())) + ')'
-
-    @classmethod
-    def fromkeys(keys: Any, v: Any = None) -> Any:
-        return CommentedKeyMap(dict.fromkeys(keys, v))
-
-    def _yaml_add_comment(self, comment: Any, key: Optional[Any] = NotNone) -> None:
-        if key is not NotNone:
-            self.yaml_key_comment_extend(key, comment)
-        else:
-            self.ca.comment = comment
-
-    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
-        self._yaml_add_comment(comment, key=key)
-
-    def _yaml_get_columnX(self, key: Any) -> Any:
-        return self.ca.items[key][0].start_mark.column
-
-    def _yaml_get_column(self, key: Any) -> Any:
-        column = None
-        sel_idx = None
-        pre, post = key - 1, key + 1
-        if pre in self.ca.items:
-            sel_idx = pre
-        elif post in self.ca.items:
-            sel_idx = post
-        else:
-            # self.ca.items is not ordered
-            for row_idx, _k1 in enumerate(self):
-                if row_idx >= key:
-                    break
-                if row_idx not in self.ca.items:
-                    continue
-                sel_idx = row_idx
-        if sel_idx is not None:
-            column = self._yaml_get_columnX(sel_idx)
-        return column
-
-    def _yaml_get_pre_comment(self) -> Any:
-        pre_comments: List[Any] = []
-        if self.ca.comment is None:
-            self.ca.comment = [None, pre_comments]
-        else:
-            self.ca.comment[1] = pre_comments
-        return pre_comments
-
-
-class CommentedOrderedMap(CommentedMap):
-    __slots__ = (Comment.attrib,)
-
-
-class CommentedSet(MutableSet, CommentedBase):  # type: ignore  # NOQA
-    __slots__ = Comment.attrib, 'odict'
-
-    def __init__(self, values: Any = None) -> None:
-        self.odict = ordereddict()
-        MutableSet.__init__(self)
-        if values is not None:
-            self |= values
-
-    def _yaml_add_comment(
-        self, comment: Any, key: Optional[Any] = NotNone, value: Optional[Any] = NotNone,
-    ) -> None:
-        """values is set to key to indicate a value attachment of comment"""
-        if key is not NotNone:
-            self.yaml_key_comment_extend(key, comment)
-            return
-        if value is not NotNone:
-            self.yaml_value_comment_extend(value, comment)
-        else:
-            self.ca.comment = comment
-
-    def _yaml_add_eol_comment(self, comment: Any, key: Any) -> None:
-        """add on the value line, with value specified by the key"""
-        self._yaml_add_comment(comment, value=key)
-
-    def add(self, value: Any) -> None:
-        """Add an element."""
-        self.odict[value] = None
-
-    def discard(self, value: Any) -> None:
-        """Remove an element.  Do not raise an exception if absent."""
-        del self.odict[value]
-
-    def __contains__(self, x: Any) -> Any:
-        return x in self.odict
-
-    def __iter__(self) -> Any:
-        for x in self.odict:
-            yield x
-
-    def __len__(self) -> int:
-        return len(self.odict)
-
-    def __repr__(self) -> str:
-        return f'set({self.odict.keys()!r})'
-
-
-class TaggedScalar(CommentedBase):
-    # the value and style attributes are set during roundtrip construction
-    def __init__(self, value: Any = None, style: Any = None, tag: Any = None) -> None:
-        self.value = value
-        self.style = style
-        if tag is not None:
-            if isinstance(tag, str):
-                tag = Tag(suffix=tag)
-            self.yaml_set_ctag(tag)
-
-    def __str__(self) -> Any:
-        return self.value
-
-    def count(self, s: str, start: Optional[int] = None, end: Optional[int] = None) -> Any:
-        return self.value.count(s, start, end)
-
-    def __getitem__(self, pos: int) -> Any:
-        return self.value[pos]
-
-    def __repr__(self) -> str:
-        return f'TaggedScalar(value={self.value!r}, style={self.style!r}, tag={self.tag!r})'
-
-
-def dump_comments(d: Any, name: str = "", sep: str = '.', out: Any = sys.stdout) -> None:
-    """
-    recursively dump comments, all but the toplevel preceded by the path
-    in dotted form x.0.a
-    """
-    if isinstance(d, dict) and hasattr(d, 'ca'):
-        if name:
-            out.write(f'{name} {type(d)}\n')
-        out.write(f'{d.ca!r}\n')
-        for k in d:
-            dump_comments(d[k], name=(name + sep + str(k)) if name else k, sep=sep, out=out)
-    elif isinstance(d, list) and hasattr(d, 'ca'):
-        if name:
-            out.write(f'{name} {type(d)}\n')
-        out.write(f'{d.ca!r}\n')
-        for idx, k in enumerate(d):
-            dump_comments(
-                k, name=(name + sep + str(idx)) if name else str(idx), sep=sep, out=out,
-            )
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py
deleted file mode 100644
index 3dfbdbe39bd..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/compat.py
+++ /dev/null
@@ -1,236 +0,0 @@
-
-from __future__ import annotations
-
-# partially from package six by Benjamin Peterson
-
-import sys
-import os
-import io
-from abc import abstractmethod
-import collections.abc
-
-
-from opentelemetry.agent._vendor.ruamel.yaml.docinfo import Version  # NOQA
-# fmt: off
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Union, BinaryIO, IO, Text, Tuple  # NOQA
-    from typing import Optional  # NOQA
-    try:
-        from typing import SupportsIndex as SupportsIndex  # in order to reexport for mypy
-    except ImportError:
-        SupportsIndex = int  # type: ignore
-
-    StreamType = Any
-    StreamTextType = StreamType
-    VersionType = Union[str , Tuple[int, int] , List[int] , Version , None]
-# fmt: on
-
-_DEFAULT_YAML_VERSION = (1, 2)
-
-try:
-    from collections import OrderedDict
-except ImportError:
-    from ordereddict import OrderedDict  # type: ignore
-
-    # to get the right name import ... as ordereddict doesn't do that
-
-
-class ordereddict(OrderedDict):  # type: ignore
-    if not hasattr(OrderedDict, 'insert'):
-
-        def insert(self, pos: int, key: Any, value: Any) -> None:
-            if pos >= len(self):
-                self[key] = value
-                return
-            od = ordereddict()
-            od.update(self)
-            for k in od:
-                del self[k]
-            for index, old_key in enumerate(od):
-                if pos == index:
-                    self[key] = value
-                self[old_key] = od[old_key]
-
-
-StringIO = io.StringIO
-BytesIO = io.BytesIO
-
-
-builtins_module = 'builtins'
-
-
-def with_metaclass(meta: Any, *bases: Any) -> Any:
-    """Create a base class with a metaclass."""
-    return meta('NewBase', bases, {})
-
-
-DBG_TOKEN = 1
-DBG_EVENT = 2
-DBG_NODE = 4
-
-
-_debug: Optional[int] = None
-if 'RUAMEL_DEBUG' in os.environ:
-    _debugx = os.environ.get('RUAMEL_DEBUG')
-    if _debugx is None:
-        _debug = 0
-    else:
-        _debug = int(_debugx)
-
-
-if bool(_debug):
-
-    class ObjectCounter:
-        def __init__(self) -> None:
-            self.map: Dict[Any, Any] = {}
-
-        def __call__(self, k: Any) -> None:
-            self.map[k] = self.map.get(k, 0) + 1
-
-        def dump(self) -> None:
-            for k in sorted(self.map):
-                sys.stdout.write(f'{k} -> {self.map[k]}')
-
-    object_counter = ObjectCounter()
-
-
-# used from yaml util when testing
-def dbg(val: Any = None) -> Any:
-    debug = _debug
-    if debug is None:
-        # set to true or false
-        _debugx = os.environ.get('YAMLDEBUG')
-        if _debugx is None:
-            debug = 0
-        else:
-            debug = int(_debugx)
-    if val is None:
-        return debug
-    return debug & val
-
-
-class Nprint:
-    def __init__(self, file_name: Any = None) -> None:
-        self._max_print: Any = None
-        self._count: Any = None
-        self._file_name = file_name
-
-    def __call__(self, *args: Any, **kw: Any) -> None:
-        if not bool(_debug):
-            return
-        import traceback
-
-        out = sys.stdout if self._file_name is None else open(self._file_name, 'a')
-        dbgprint = print  # to fool checking for print statements by dv utility
-        kw1 = kw.copy()
-        kw1['file'] = out
-        dbgprint(*args, **kw1)
-        out.flush()
-        if self._max_print is not None:
-            if self._count is None:
-                self._count = self._max_print
-            self._count -= 1
-            if self._count == 0:
-                dbgprint('forced exit\n')
-                traceback.print_stack()
-                out.flush()
-                sys.exit(0)
-        if self._file_name:
-            out.close()
-
-    def set_max_print(self, i: int) -> None:
-        self._max_print = i
-        self._count = None
-
-    def fp(self, mode: str = 'a') -> Any:
-        out = sys.stdout if self._file_name is None else open(self._file_name, mode)
-        return out
-
-
-nprint = Nprint()
-nprintf = Nprint('/var/tmp/ruamel.yaml.log')
-
-# char checkers following production rules
-
-
-def check_namespace_char(ch: Any) -> bool:
-    if '\x21' <= ch <= '\x7E':  # ! to ~
-        return True
-    if '\xA0' <= ch <= '\uD7FF':
-        return True
-    if ('\uE000' <= ch <= '\uFFFD') and ch != '\uFEFF':  # excl. byte order mark
-        return True
-    if '\U00010000' <= ch <= '\U0010FFFF':
-        return True
-    return False
-
-
-def check_anchorname_char(ch: Any) -> bool:
-    if ch in ',[]{}':
-        return False
-    return check_namespace_char(ch)
-
-
-def version_tnf(t1: Any, t2: Any = None) -> Any:
-    """
-    return True if ruamel.yaml version_info < t1, None if t2 is specified and bigger else False
-    """
-    from opentelemetry.agent._vendor.ruamel.yaml import version_info  # NOQA
-
-    if version_info < t1:
-        return True
-    if t2 is not None and version_info < t2:
-        return None
-    return False
-
-
-class MutableSliceableSequence(collections.abc.MutableSequence):  # type: ignore
-    __slots__ = ()
-
-    def __getitem__(self, index: Any) -> Any:
-        if not isinstance(index, slice):
-            return self.__getsingleitem__(index)
-        return type(self)([self[i] for i in range(*index.indices(len(self)))])  # type: ignore
-
-    def __setitem__(self, index: Any, value: Any) -> None:
-        if not isinstance(index, slice):
-            return self.__setsingleitem__(index, value)
-        assert iter(value)
-        # nprint(index.start, index.stop, index.step, index.indices(len(self)))
-        if index.step is None:
-            del self[index.start : index.stop]
-            for elem in reversed(value):
-                self.insert(0 if index.start is None else index.start, elem)
-        else:
-            range_parms = index.indices(len(self))
-            nr_assigned_items = (range_parms[1] - range_parms[0] - 1) // range_parms[2] + 1
-            # need to test before changing, in case TypeError is caught
-            if nr_assigned_items < len(value):
-                raise TypeError(
-                    f'too many elements in value {nr_assigned_items} < {len(value)}',
-                )
-            elif nr_assigned_items > len(value):
-                raise TypeError(
-                    f'not enough elements in value {nr_assigned_items} > {len(value)}',
-                )
-            for idx, i in enumerate(range(*range_parms)):
-                self[i] = value[idx]
-
-    def __delitem__(self, index: Any) -> None:
-        if not isinstance(index, slice):
-            return self.__delsingleitem__(index)
-        # nprint(index.start, index.stop, index.step, index.indices(len(self)))
-        for i in reversed(range(*index.indices(len(self)))):
-            del self[i]
-
-    @abstractmethod
-    def __getsingleitem__(self, index: Any) -> Any:
-        raise IndexError
-
-    @abstractmethod
-    def __setsingleitem__(self, index: Any, value: Any) -> None:
-        raise IndexError
-
-    @abstractmethod
-    def __delsingleitem__(self, index: Any) -> None:
-        raise IndexError
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py
deleted file mode 100644
index d60de8f42e5..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/composer.py
+++ /dev/null
@@ -1,246 +0,0 @@
-
-from __future__ import annotations
-
-import warnings
-
-from opentelemetry.agent._vendor.ruamel.yaml.error import MarkedYAMLError, ReusedAnchorWarning
-from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, nprintf  # NOQA
-
-from opentelemetry.agent._vendor.ruamel.yaml.events import (
-    StreamStartEvent,
-    StreamEndEvent,
-    MappingStartEvent,
-    MappingEndEvent,
-    SequenceStartEvent,
-    SequenceEndEvent,
-    AliasEvent,
-    ScalarEvent,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List  # NOQA
-
-__all__ = ['Composer', 'ComposerError', 'MaxDepthExceededError']
-
-
-class ComposerError(MarkedYAMLError):
-    pass
-
-
-class MaxDepthExceededError(MarkedYAMLError):
-    pass
-
-
-class Composer:
-    def __init__(self, loader: Any = None) -> None:
-        self.loader = loader
-        if self.loader is not None and getattr(self.loader, '_composer', None) is None:
-            self.loader._composer = self
-        self.anchors: Dict[Any, Any] = {}
-        self.warn_double_anchors = True
-        self.depth = 0
-
-    @property
-    def parser(self) -> Any:
-        if hasattr(self.loader, 'typ'):
-            self.loader.parser
-        return self.loader._parser
-
-    @property
-    def resolver(self) -> Any:
-        # assert self.loader._resolver is not None
-        if hasattr(self.loader, 'typ'):
-            self.loader.resolver
-        return self.loader._resolver
-
-    def check_node(self) -> Any:
-        # Drop the STREAM-START event.
-        if self.parser.check_event(StreamStartEvent):
-            self.parser.get_event()
-
-        # If there are more documents available?
-        return not self.parser.check_event(StreamEndEvent)
-
-    def get_node(self) -> Any:
-        # Get the root node of the next document.
-        if not self.parser.check_event(StreamEndEvent):
-            return self.compose_document()
-
-    def get_single_node(self) -> Any:
-        # Drop the STREAM-START event.
-        self.parser.get_event()
-
-        # Compose a document if the stream is not empty.
-        document: Any = None
-        if not self.parser.check_event(StreamEndEvent):
-            document = self.compose_document()
-
-        # Ensure that the stream contains no more documents.
-        if not self.parser.check_event(StreamEndEvent):
-            event = self.parser.get_event()
-            raise ComposerError(
-                'expected a single document in the stream',
-                document.start_mark,
-                'but found another document',
-                event.start_mark,
-            )
-
-        # Drop the STREAM-END event.
-        self.parser.get_event()
-
-        return document
-
-    def compose_document(self: Any) -> Any:
-        self.anchors = {}
-        # Drop the DOCUMENT-START event.
-        self.parser.get_event()
-
-        # Compose the root node.
-        node = self.compose_node(None, None)
-
-        # Drop the DOCUMENT-END event.
-        self.parser.get_event()
-
-        return node
-
-    def return_alias(self, a: Any) -> Any:
-        return a
-
-    def compose_node(self, parent: Any, index: Any) -> Any:
-        if self.parser.check_event(AliasEvent):
-            event = self.parser.get_event()
-            alias = event.anchor
-            if alias not in self.anchors:
-                raise ComposerError(
-                    None, None, f'found undefined alias {alias!r}', event.start_mark,
-                )
-            return self.return_alias(self.anchors[alias])
-        self.depth += 1
-        event = self.parser.peek_event()
-        if self.loader.max_depth and self.depth > self.loader.max_depth:
-            raise MaxDepthExceededError(
-                None,
-                None,
-                f'maximum depth of data structure exceeded ({self.depth}), '
-                'if necessary increase YAML().max_depth',
-                event.start_mark,
-            )
-        anchor = event.anchor
-        if anchor is not None:  # have an anchor
-            if self.warn_double_anchors and anchor in self.anchors:
-                ws = (
-                    f'\nfound duplicate anchor {anchor!r}\n'
-                    f'first occurrence {self.anchors[anchor].start_mark}\n'
-                    f'second occurrence {event.start_mark}'
-                )
-                warnings.warn(ws, ReusedAnchorWarning, stacklevel=2)
-        self.resolver.descend_resolver(parent, index)
-        if self.parser.check_event(ScalarEvent):
-            node = self.compose_scalar_node(anchor)
-        elif self.parser.check_event(SequenceStartEvent):
-            node = self.compose_sequence_node(anchor)
-        elif self.parser.check_event(MappingStartEvent):
-            node = self.compose_mapping_node(anchor)
-        self.resolver.ascend_resolver()
-        self.depth -= 1
-        return node
-
-    def compose_scalar_node(self, anchor: Any) -> Any:
-        event = self.parser.get_event()
-        tag = event.ctag
-        if tag is None or str(tag) == '!':
-            tag = self.resolver.resolve(ScalarNode, event.value, event.implicit)
-            assert not isinstance(tag, str)
-            # e.g tag.yaml.org,2002:str
-        node = ScalarNode(
-            tag,
-            event.value,
-            event.start_mark,
-            event.end_mark,
-            style=event.style,
-            comment=event.comment,
-            anchor=anchor,
-        )
-        if anchor is not None:
-            self.anchors[anchor] = node
-        return node
-
-    def compose_sequence_node(self, anchor: Any) -> Any:
-        start_event = self.parser.get_event()
-        tag = start_event.ctag
-        if tag is None or str(tag) == '!':
-            tag = self.resolver.resolve(SequenceNode, None, start_event.implicit)
-            assert not isinstance(tag, str)
-        node = SequenceNode(
-            tag,
-            [],
-            start_event.start_mark,
-            None,
-            flow_style=start_event.flow_style,
-            comment=start_event.comment,
-            anchor=anchor,
-        )
-        if anchor is not None:
-            self.anchors[anchor] = node
-        index = 0
-        while not self.parser.check_event(SequenceEndEvent):
-            node.value.append(self.compose_node(node, index))
-            index += 1
-        end_event = self.parser.get_event()
-        if node.flow_style is True and end_event.comment is not None:
-            if node.comment is not None:
-                x = node.flow_style
-                nprint(
-                    f'Warning: unexpected end_event commment in sequence node {x}\n',
-                    '    if possible, please report an issue with reproducable data/code',
-                )
-            node.comment = end_event.comment
-        node.end_mark = end_event.end_mark
-        self.check_end_doc_comment(end_event, node)
-        return node
-
-    def compose_mapping_node(self, anchor: Any) -> Any:
-        start_event = self.parser.get_event()
-        tag = start_event.ctag
-        if tag is None or str(tag) == '!':
-            tag = self.resolver.resolve(MappingNode, None, start_event.implicit)
-            assert not isinstance(tag, str)
-        node = MappingNode(
-            tag,
-            [],
-            start_event.start_mark,
-            None,
-            flow_style=start_event.flow_style,
-            comment=start_event.comment,
-            anchor=anchor,
-        )
-        if anchor is not None:
-            self.anchors[anchor] = node
-        while not self.parser.check_event(MappingEndEvent):
-            # key_event = self.parser.peek_event()
-            item_key = self.compose_node(node, None)
-            # if item_key in node.value:
-            #     raise ComposerError("while composing a mapping",
-            #             start_event.start_mark,
-            #             "found duplicate key", key_event.start_mark)
-            item_value = self.compose_node(node, item_key)
-            # node.value[item_key] = item_value
-            node.value.append((item_key, item_value))
-        end_event = self.parser.get_event()
-        if node.flow_style is True and end_event.comment is not None:
-            node.comment = end_event.comment
-        node.end_mark = end_event.end_mark
-        self.check_end_doc_comment(end_event, node)
-        return node
-
-    def check_end_doc_comment(self, end_event: Any, node: Any) -> None:
-        if end_event.comment and end_event.comment[1]:
-            # pre comments on an end_event, no following to move to
-            if node.comment is None:
-                node.comment = [None, None]
-            assert not isinstance(node, ScalarEvent)
-            # this is a post comment on a mapping node, add as third element
-            # in the list
-            node.comment.append(end_event.comment[1])
-            end_event.comment[1] = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py
deleted file mode 100644
index 0b6de66d1fb..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/configobjwalker.py
+++ /dev/null
@@ -1,17 +0,0 @@
-
-from __future__ import annotations
-
-import warnings
-
-from opentelemetry.agent._vendor.ruamel.yaml.util import configobj_walker as new_configobj_walker
-
-if False:  # MYPY
-    from typing import Any
-
-
-def configobj_walker(cfg: Any) -> Any:
-    warnings.warn(
-        'configobj_walker has moved to ruamel.yaml.util, please update your code',
-        stacklevel=2,
-    )
-    return new_configobj_walker(cfg)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py
deleted file mode 100644
index b20ae25d56a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/constructor.py
+++ /dev/null
@@ -1,1724 +0,0 @@
-
-from __future__ import annotations
-
-import datetime
-from datetime import timedelta as TimeDelta
-import binascii
-import sys
-import types
-import warnings
-from collections.abc import Hashable, MutableSequence, MutableMapping
-
-# fmt: off
-from opentelemetry.agent._vendor.ruamel.yaml.error import (MarkedYAMLError, MarkedYAMLFutureWarning,
-                               MantissaNoDotYAML1_1Warning)
-from opentelemetry.agent._vendor.ruamel.yaml.nodes import *                               # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.nodes import (SequenceNode, MappingNode, ScalarNode)
-from opentelemetry.agent._vendor.ruamel.yaml.compat import (builtins_module, # NOQA
-                                nprint, nprintf, version_tnf)
-from opentelemetry.agent._vendor.ruamel.yaml.compat import ordereddict
-
-from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
-from opentelemetry.agent._vendor.ruamel.yaml.comments import *                               # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.comments import (CommentedMap, CommentedOrderedMap, CommentedSet,
-                                  CommentedKeySeq, CommentedSeq, TaggedScalar,
-                                  CommentedKeyMap,
-                                  C_KEY_PRE, C_KEY_EOL, C_KEY_POST,
-                                  C_VALUE_PRE, C_VALUE_EOL, C_VALUE_POST,
-                                  )
-from opentelemetry.agent._vendor.ruamel.yaml.scalarstring import (SingleQuotedScalarString, DoubleQuotedScalarString,
-                                      LiteralScalarString, FoldedScalarString,
-                                      PlainScalarString, ScalarString)
-from opentelemetry.agent._vendor.ruamel.yaml.scalarint import ScalarInt, BinaryInt, OctalInt, HexInt, HexCapsInt
-from opentelemetry.agent._vendor.ruamel.yaml.scalarfloat import ScalarFloat
-from opentelemetry.agent._vendor.ruamel.yaml.scalarbool import ScalarBoolean
-from opentelemetry.agent._vendor.ruamel.yaml.timestamp import TimeStamp
-from opentelemetry.agent._vendor.ruamel.yaml.util import timestamp_regexp, create_timestamp
-
-if False:  # MYPY
-    from typing import Any, Dict, List, Set, Iterator, Union, Optional  # NOQA
-
-
-__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
-           'ConstructorError', 'RoundTripConstructor']
-# fmt: on
-
-
-class ConstructorError(MarkedYAMLError):
-    pass
-
-
-class DuplicateKeyFutureWarning(MarkedYAMLFutureWarning):
-    pass
-
-
-DUPKEY_URL = 'https://yaml.dev/doc/ruamel.yaml/api/#Duplicate_keys'
-
-
-class DuplicateKeyError(MarkedYAMLError):
-    pass
-
-
-class BaseConstructor:
-
-    yaml_constructors = {}  # type: Dict[Any, Any]
-    yaml_multi_constructors = {}  # type: Dict[Any, Any]
-
-    def __init__(self, preserve_quotes: Optional[bool] = None, loader: Any = None) -> None:
-        self.loader = loader
-        if self.loader is not None and getattr(self.loader, '_constructor', None) is None:
-            self.loader._constructor = self
-        self.loader = loader
-        self.yaml_base_dict_type = dict
-        self.yaml_base_list_type = list
-        self.constructed_objects: Dict[Any, Any] = {}
-        self.recursive_objects: Dict[Any, Any] = {}
-        self.state_generators: List[Any] = []
-        self.deep_construct = False
-        self._preserve_quotes = preserve_quotes
-        self.allow_duplicate_keys = version_tnf((0, 15, 1), (0, 16))
-
-    @property
-    def composer(self) -> Any:
-        if hasattr(self.loader, 'typ'):
-            return self.loader.composer
-        try:
-            return self.loader._composer
-        except AttributeError:
-            sys.stdout.write(f'slt {type(self)}\n')
-            sys.stdout.write(f'slc {self.loader._composer}\n')
-            sys.stdout.write(f'{dir(self)}\n')
-            raise
-
-    @property
-    def resolver(self) -> Any:
-        if hasattr(self.loader, 'typ'):
-            return self.loader.resolver
-        return self.loader._resolver
-
-    @property
-    def scanner(self) -> Any:
-        # needed to get to the expanded comments
-        if hasattr(self.loader, 'typ'):
-            return self.loader.scanner
-        return self.loader._scanner
-
-    def check_data(self) -> Any:
-        # If there are more documents available?
-        return self.composer.check_node()
-
-    def get_data(self) -> Any:
-        # Construct and return the next document.
-        if self.composer.check_node():
-            return self.construct_document(self.composer.get_node())
-
-    def get_single_data(self) -> Any:
-        # Ensure that the stream contains a single document and construct it.
-        node = self.composer.get_single_node()
-        if node is not None:
-            return self.construct_document(node)
-        return None
-
-    def construct_document(self, node: Any) -> Any:
-        data = self.construct_object(node)
-        while bool(self.state_generators):
-            state_generators = self.state_generators
-            self.state_generators = []
-            for generator in state_generators:
-                for _dummy in generator:
-                    pass
-        self.constructed_objects = {}
-        self.recursive_objects = {}
-        self.deep_construct = False
-        return data
-
-    def construct_object(self, node: Any, deep: bool = False) -> Any:
-        """deep is True when creating an object/mapping recursively,
-        in that case want the underlying elements available during construction
-        """
-        if node in self.constructed_objects:
-            return self.constructed_objects[node]
-        if deep:
-            old_deep = self.deep_construct
-            self.deep_construct = True
-        if node in self.recursive_objects:
-            return self.recursive_objects[node]
-            # raise ConstructorError(
-            #     None, None, 'found unconstructable recursive node', node.start_mark
-            # )
-        self.recursive_objects[node] = None
-        data = self.construct_non_recursive_object(node)
-
-        self.constructed_objects[node] = data
-        del self.recursive_objects[node]
-        if deep:
-            self.deep_construct = old_deep
-        return data
-
-    def construct_non_recursive_object(self, node: Any, tag: Optional[str] = None) -> Any:
-        constructor: Any = None
-        tag_suffix = None
-        if tag is None:
-            tag = node.tag
-        if tag in self.yaml_constructors:
-            constructor = self.yaml_constructors[tag]
-        else:
-            for tag_prefix in self.yaml_multi_constructors:
-                if tag.startswith(tag_prefix):
-                    tag_suffix = tag[len(tag_prefix) :]
-                    constructor = self.yaml_multi_constructors[tag_prefix]
-                    break
-            else:
-                if None in self.yaml_multi_constructors:
-                    tag_suffix = tag
-                    constructor = self.yaml_multi_constructors[None]
-                elif None in self.yaml_constructors:
-                    constructor = self.yaml_constructors[None]
-                elif isinstance(node, ScalarNode):
-                    constructor = self.__class__.construct_scalar
-                elif isinstance(node, SequenceNode):
-                    constructor = self.__class__.construct_sequence
-                elif isinstance(node, MappingNode):
-                    constructor = self.__class__.construct_mapping
-        if tag_suffix is None:
-            data = constructor(self, node)
-        else:
-            data = constructor(self, tag_suffix, node)
-        if isinstance(data, types.GeneratorType):
-            generator = data
-            data = next(generator)
-            if self.deep_construct:
-                for _dummy in generator:
-                    pass
-            else:
-                self.state_generators.append(generator)
-        return data
-
-    def construct_scalar(self, node: Any) -> Any:
-        if not isinstance(node, ScalarNode):
-            raise ConstructorError(
-                None, None, f'expected a scalar node, but found {node.id!s}', node.start_mark,
-            )
-        return node.value
-
-    def construct_sequence(self, node: Any, deep: bool = False) -> Any:
-        """deep is True when creating an object/mapping recursively,
-        in that case want the underlying elements available during construction
-        """
-        if not isinstance(node, SequenceNode):
-            raise ConstructorError(
-                None,
-                None,
-                f'expected a sequence node, but found {node.id!s}',
-                node.start_mark,
-            )
-        return [self.construct_object(child, deep=deep) for child in node.value]
-
-    def construct_mapping(self, node: Any, deep: bool = False) -> Any:
-        """deep is True when creating an object/mapping recursively,
-        in that case want the underlying elements available during construction
-        """
-        if not isinstance(node, MappingNode):
-            raise ConstructorError(
-                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
-            )
-        total_mapping = self.yaml_base_dict_type()
-        if getattr(node, 'merge', None) is not None:
-            todo = [(node.merge, False), (node.value, False)]
-        else:
-            todo = [(node.value, True)]
-        for values, check in todo:
-            mapping: Dict[Any, Any] = self.yaml_base_dict_type()
-            for key_node, value_node in values:
-                # keys can be list -> deep
-                key = self.construct_object(key_node, deep=True)
-                # lists are not hashable, but tuples are
-                if not isinstance(key, Hashable):
-                    if isinstance(key, list):
-                        key = tuple(key)
-                if not isinstance(key, Hashable):
-                    raise ConstructorError(
-                        'while constructing a mapping',
-                        node.start_mark,
-                        'found unhashable key',
-                        key_node.start_mark,
-                    )
-
-                value = self.construct_object(value_node, deep=deep)
-                if check:
-                    if self.check_mapping_key(node, key_node, mapping, key, value):
-                        mapping[key] = value
-                else:
-                    mapping[key] = value
-            total_mapping.update(mapping)
-        return total_mapping
-
-    def check_mapping_key(
-        self, node: Any, key_node: Any, mapping: Any, key: Any, value: Any,
-    ) -> bool:
-        """return True if key is unique"""
-        if key in mapping:
-            if not self.allow_duplicate_keys:
-                mk = mapping.get(key)
-                args = [
-                    'while constructing a mapping',
-                    node.start_mark,
-                    f'found duplicate key "{key}" with value "{value}" '
-                    f'(original value: "{mk}")',
-                    key_node.start_mark,
-                    f"""
-                    To suppress this check see:
-                        {DUPKEY_URL}
-                    """,
-                    """\
-                    Duplicate keys will become an error in future releases, and are errors
-                    by default when using the new API.
-                    """,
-                ]
-                if self.allow_duplicate_keys is None:
-                    warnings.warn(DuplicateKeyFutureWarning(*args), stacklevel=1)
-                else:
-                    raise DuplicateKeyError(*args)
-            return False
-        return True
-
-    def check_set_key(self: Any, node: Any, key_node: Any, setting: Any, key: Any) -> None:
-        if key in setting:
-            if not self.allow_duplicate_keys:
-                args = [
-                    'while constructing a set',
-                    node.start_mark,
-                    f'found duplicate key "{key}"',
-                    key_node.start_mark,
-                    f"""
-                    To suppress this check see:
-                        {DUPKEY_URL}
-                    """,
-                    """\
-                    Duplicate keys will become an error in future releases, and are errors
-                    by default when using the new API.
-                    """,
-                ]
-                if self.allow_duplicate_keys is None:
-                    warnings.warn(DuplicateKeyFutureWarning(*args), stacklevel=1)
-                else:
-                    raise DuplicateKeyError(*args)
-
-    def construct_pairs(self, node: Any, deep: bool = False) -> Any:
-        if not isinstance(node, MappingNode):
-            raise ConstructorError(
-                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
-            )
-        pairs = []
-        for key_node, value_node in node.value:
-            key = self.construct_object(key_node, deep=deep)
-            value = self.construct_object(value_node, deep=deep)
-            pairs.append((key, value))
-        return pairs
-
-    # ToDo: putting stuff on the class makes it global, consider making this to work on an
-    # instance variable once function load is dropped.
-    @classmethod
-    def add_constructor(cls, tag: Any, constructor: Any) -> Any:
-        if isinstance(tag, Tag):
-            tag = str(tag)
-        if 'yaml_constructors' not in cls.__dict__:
-            cls.yaml_constructors = cls.yaml_constructors.copy()
-        ret_val = cls.yaml_constructors.get(tag, None)
-        cls.yaml_constructors[tag] = constructor
-        return ret_val
-
-    @classmethod
-    def add_multi_constructor(cls, tag_prefix: Any, multi_constructor: Any) -> None:
-        if 'yaml_multi_constructors' not in cls.__dict__:
-            cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
-        cls.yaml_multi_constructors[tag_prefix] = multi_constructor
-
-    @classmethod
-    def add_default_constructor(
-        cls, tag: str, method: Any = None, tag_base: str = 'tag:yaml.org,2002:',
-    ) -> None:
-        if not tag.startswith('tag:'):
-            if method is None:
-                method = 'construct_yaml_' + tag
-            tag = tag_base + tag
-        cls.add_constructor(tag, getattr(cls, method))
-
-
-class SafeConstructor(BaseConstructor):
-    def construct_scalar(self, node: Any) -> Any:
-        if isinstance(node, MappingNode):
-            for key_node, value_node in node.value:
-                if key_node.tag == 'tag:yaml.org,2002:value':
-                    return self.construct_scalar(value_node)
-        return BaseConstructor.construct_scalar(self, node)
-
-    def flatten_mapping(self, node: Any) -> Any:  # SafeConstructor
-        """
-        This implements the merge key feature http://yaml.org/type/merge.html
-        by inserting keys from the merge dict/list of dicts if not yet
-        available in this node
-        """
-        merge: List[Any] = []
-        index = 0
-        while index < len(node.value):
-            key_node, value_node = node.value[index]
-            if key_node.tag == 'tag:yaml.org,2002:merge':
-                if merge:  # double << key
-                    if self.allow_duplicate_keys:
-                        del node.value[index]
-                        index += 1
-                        continue
-                    args = [
-                        'while constructing a mapping',
-                        node.start_mark,
-                        'found duplicate merge key "<<"',
-                        key_node.start_mark,
-                        """\
-                        Duplicate merge keys are never allowed, not even when
-                        `.allow_duplicate_keys` is set to True
-                        """,
-                    ]
-                    raise DuplicateKeyError(*args)
-                del node.value[index]
-                if isinstance(value_node, MappingNode):
-                    self.flatten_mapping(value_node)
-                    merge.extend(value_node.value)
-                elif isinstance(value_node, SequenceNode):
-                    submerge = []
-                    for subnode in value_node.value:
-                        if not isinstance(subnode, MappingNode):
-                            raise ConstructorError(
-                                'while constructing a mapping',
-                                node.start_mark,
-                                f'expected a mapping for merging, but found {subnode.id!s}',
-                                subnode.start_mark,
-                            )
-                        self.flatten_mapping(subnode)
-                        submerge.append(subnode.value)
-                    submerge.reverse()
-                    for value in submerge:
-                        merge.extend(value)
-                else:
-                    raise ConstructorError(
-                        'while constructing a mapping',
-                        node.start_mark,
-                        'expected a mapping or list of mappings for merging, '
-                        f'but found {value_node.id!s}',
-                        value_node.start_mark,
-                    )
-            elif key_node.tag == 'tag:yaml.org,2002:value':
-                key_node.tag = 'tag:yaml.org,2002:str'
-                index += 1
-            else:
-                index += 1
-        if bool(merge):
-            node.merge = merge  # separate merge keys to be able to update without duplicate
-            node.value = merge + node.value
-
-    def construct_mapping(self, node: Any, deep: bool = False) -> Any:
-        """deep is True when creating an object/mapping recursively,
-        in that case want the underlying elements available during construction
-        """
-        if isinstance(node, MappingNode):
-            self.flatten_mapping(node)
-        return BaseConstructor.construct_mapping(self, node, deep=deep)
-
-    def construct_yaml_null(self, node: Any) -> Any:
-        self.construct_scalar(node)
-        return None
-
-    # YAML 1.2 spec doesn't mention yes/no etc any more, 1.1 does
-    bool_values = {
-        'yes': True,
-        'no': False,
-        'y': True,
-        'n': False,
-        'true': True,
-        'false': False,
-        'on': True,
-        'off': False,
-    }
-
-    def construct_yaml_bool(self, node: Any) -> bool:
-        value = self.construct_scalar(node)
-        return self.bool_values[value.lower()]
-
-    def construct_yaml_int(self, node: Any) -> int:
-        value_s = self.construct_scalar(node)
-        value_s = value_s.replace('_', "")
-        sign = +1
-        if value_s[0] == '-':
-            sign = -1
-        if value_s[0] in '+-':
-            value_s = value_s[1:]
-        if value_s == '0':
-            return 0
-        elif value_s.startswith('0b'):
-            return sign * int(value_s[2:], 2)
-        elif value_s.startswith('0x'):
-            return sign * int(value_s[2:], 16)
-        elif value_s.startswith('0o'):
-            return sign * int(value_s[2:], 8)
-        elif self.resolver.processing_version == (1, 1) and value_s[0] == '0':
-            return sign * int(value_s, 8)
-        elif self.resolver.processing_version == (1, 1) and ':' in value_s:
-            digits = [int(part) for part in value_s.split(':')]
-            digits.reverse()
-            base = 1
-            value = 0
-            for digit in digits:
-                value += digit * base
-                base *= 60
-            return sign * value
-        else:
-            return sign * int(value_s)
-
-    inf_value = 1e300
-    while inf_value != inf_value * inf_value:
-        inf_value *= inf_value
-    nan_value = -inf_value / inf_value  # Trying to make a quiet NaN (like C99).
-
-    def construct_yaml_float(self, node: Any) -> float:
-        value_so = self.construct_scalar(node)
-        value_s = value_so.replace('_', "").lower()
-        sign = +1
-        if value_s[0] == '-':
-            sign = -1
-        if value_s[0] in '+-':
-            value_s = value_s[1:]
-        if value_s == '.inf':
-            return sign * self.inf_value
-        elif value_s == '.nan':
-            return self.nan_value
-        elif self.resolver.processing_version != (1, 2) and ':' in value_s:
-            digits = [float(part) for part in value_s.split(':')]
-            digits.reverse()
-            base = 1
-            value = 0.0
-            for digit in digits:
-                value += digit * base
-                base *= 60
-            return sign * value
-        else:
-            if self.resolver.processing_version != (1, 2) and 'e' in value_s:
-                # value_s is lower case independent of input
-                mantissa, exponent = value_s.split('e')
-                if '.' not in mantissa:
-                    warnings.warn(MantissaNoDotYAML1_1Warning(node, value_so), stacklevel=1)
-            return sign * float(value_s)
-
-    def construct_yaml_binary(self, node: Any) -> Any:
-        import base64
-
-        try:
-            value = self.construct_scalar(node).encode('ascii')
-        except UnicodeEncodeError as exc:
-            raise ConstructorError(
-                None,
-                None,
-                f'failed to convert base64 data into ascii: {exc!s}',
-                node.start_mark,
-            )
-        try:
-            return base64.decodebytes(value)
-        except binascii.Error as exc:
-            raise ConstructorError(
-                None, None, f'failed to decode base64 data: {exc!s}', node.start_mark,
-            )
-
-    timestamp_regexp = timestamp_regexp  # moved to util 0.17.17
-
-    def construct_yaml_timestamp(self, node: Any, values: Any = None) -> Any:
-        if values is None:
-            try:
-                match = self.timestamp_regexp.match(node.value)
-            except TypeError:
-                match = None
-            if match is None:
-                raise ConstructorError(
-                    None,
-                    None,
-                    f'failed to construct timestamp from "{node.value}"',
-                    node.start_mark,
-                )
-            values = match.groupdict()
-        return create_timestamp(**values)
-
-    def construct_yaml_omap(self, node: Any) -> Any:
-        # Note: we do now check for duplicate keys
-        omap = ordereddict()
-        yield omap
-        if not isinstance(node, SequenceNode):
-            raise ConstructorError(
-                'while constructing an ordered map',
-                node.start_mark,
-                f'expected a sequence, but found {node.id!s}',
-                node.start_mark,
-            )
-        for subnode in node.value:
-            if not isinstance(subnode, MappingNode):
-                raise ConstructorError(
-                    'while constructing an ordered map',
-                    node.start_mark,
-                    f'expected a mapping of length 1, but found {subnode.id!s}',
-                    subnode.start_mark,
-                )
-            if len(subnode.value) != 1:
-                raise ConstructorError(
-                    'while constructing an ordered map',
-                    node.start_mark,
-                    f'expected a single mapping item, but found {len(subnode.value):d} items',
-                    subnode.start_mark,
-                )
-            key_node, value_node = subnode.value[0]
-            key = self.construct_object(key_node)
-            assert key not in omap
-            value = self.construct_object(value_node)
-            omap[key] = value
-
-    def construct_yaml_pairs(self, node: Any) -> Any:
-        # Note: the same code as `construct_yaml_omap`.
-        pairs: List[Any] = []
-        yield pairs
-        if not isinstance(node, SequenceNode):
-            raise ConstructorError(
-                'while constructing pairs',
-                node.start_mark,
-                f'expected a sequence, but found {node.id!s}',
-                node.start_mark,
-            )
-        for subnode in node.value:
-            if not isinstance(subnode, MappingNode):
-                raise ConstructorError(
-                    'while constructing pairs',
-                    node.start_mark,
-                    f'expected a mapping of length 1, but found {subnode.id!s}',
-                    subnode.start_mark,
-                )
-            if len(subnode.value) != 1:
-                raise ConstructorError(
-                    'while constructing pairs',
-                    node.start_mark,
-                    f'expected a single mapping item, but found {len(subnode.value):d} items',
-                    subnode.start_mark,
-                )
-            key_node, value_node = subnode.value[0]
-            key = self.construct_object(key_node)
-            value = self.construct_object(value_node)
-            pairs.append((key, value))
-
-    def construct_yaml_set(self, node: Any) -> Any:
-        data: Set[Any] = set()
-        yield data
-        value = self.construct_mapping(node)
-        data.update(value)
-
-    def construct_yaml_str(self, node: Any) -> Any:
-        value = self.construct_scalar(node)
-        return value
-
-    def construct_yaml_seq(self, node: Any) -> Any:
-        data: List[Any] = self.yaml_base_list_type()
-        yield data
-        data.extend(self.construct_sequence(node))
-
-    def construct_yaml_map(self, node: Any) -> Any:
-        data: Dict[Any, Any] = self.yaml_base_dict_type()
-        yield data
-        value = self.construct_mapping(node)
-        data.update(value)
-
-    def construct_yaml_object(self, node: Any, cls: Any) -> Any:
-        data = cls.__new__(cls)
-        yield data
-        if hasattr(data, '__setstate__'):
-            state = self.construct_mapping(node, deep=True)
-            data.__setstate__(state)
-        else:
-            state = self.construct_mapping(node)
-            data.__dict__.update(state)
-
-    def construct_undefined(self, node: Any) -> None:
-        raise ConstructorError(
-            None,
-            None,
-            f'could not determine a constructor for the tag {node.tag!r}',
-            node.start_mark,
-        )
-
-
-for tag in 'null bool int float binary timestamp omap pairs set str seq map'.split():
-    SafeConstructor.add_default_constructor(tag)
-
-SafeConstructor.add_constructor(None, SafeConstructor.construct_undefined)
-
-
-class Constructor(SafeConstructor):
-    def construct_python_str(self, node: Any) -> Any:
-        return self.construct_scalar(node)
-
-    def construct_python_unicode(self, node: Any) -> Any:
-        return self.construct_scalar(node)
-
-    def construct_python_bytes(self, node: Any) -> Any:
-        import base64
-
-        try:
-            value = self.construct_scalar(node).encode('ascii')
-        except UnicodeEncodeError as exc:
-            raise ConstructorError(
-                None,
-                None,
-                f'failed to convert base64 data into ascii: {exc!s}',
-                node.start_mark,
-            )
-        try:
-            return base64.decodebytes(value)
-        except binascii.Error as exc:
-            raise ConstructorError(
-                None, None, f'failed to decode base64 data: {exc!s}', node.start_mark,
-            )
-
-    def construct_python_long(self, node: Any) -> int:
-        val = self.construct_yaml_int(node)
-        return val
-
-    def construct_python_complex(self, node: Any) -> Any:
-        return complex(self.construct_scalar(node))
-
-    def construct_python_tuple(self, node: Any) -> Any:
-        return tuple(self.construct_sequence(node))
-
-    def find_python_module(self, name: Any, mark: Any) -> Any:
-        if not name:
-            raise ConstructorError(
-                'while constructing a Python module',
-                mark,
-                'expected non-empty name appended to the tag',
-                mark,
-            )
-        try:
-            __import__(name)
-        except ImportError as exc:
-            raise ConstructorError(
-                'while constructing a Python module',
-                mark,
-                f'cannot find module {name!r} ({exc!s})',
-                mark,
-            )
-        return sys.modules[name]
-
-    def find_python_name(self, name: Any, mark: Any) -> Any:
-        if not name:
-            raise ConstructorError(
-                'while constructing a Python object',
-                mark,
-                'expected non-empty name appended to the tag',
-                mark,
-            )
-        if '.' in name:
-            lname = name.split('.')
-            lmodule_name = lname
-            lobject_name: List[Any] = []
-            while len(lmodule_name) > 1:
-                lobject_name.insert(0, lmodule_name.pop())
-                module_name = '.'.join(lmodule_name)
-                try:
-                    __import__(module_name)
-                    # object_name = '.'.join(object_name)
-                    break
-                except ImportError:
-                    continue
-        else:
-            module_name = builtins_module
-            lobject_name = [name]
-        try:
-            __import__(module_name)
-        except ImportError as exc:
-            raise ConstructorError(
-                'while constructing a Python object',
-                mark,
-                f'cannot find module {module_name!r} ({exc!s})',
-                mark,
-            )
-        module = sys.modules[module_name]
-        object_name = '.'.join(lobject_name)
-        obj = module
-        while lobject_name:
-            if not hasattr(obj, lobject_name[0]):
-
-                raise ConstructorError(
-                    'while constructing a Python object',
-                    mark,
-                    f'cannot find {object_name!r} in the module {module.__name__!r}',
-                    mark,
-                )
-            obj = getattr(obj, lobject_name.pop(0))
-        return obj
-
-    def construct_python_name(self, suffix: Any, node: Any) -> Any:
-        value = self.construct_scalar(node)
-        if value:
-            raise ConstructorError(
-                'while constructing a Python name',
-                node.start_mark,
-                f'expected the empty value, but found {value!r}',
-                node.start_mark,
-            )
-        return self.find_python_name(suffix, node.start_mark)
-
-    def construct_python_module(self, suffix: Any, node: Any) -> Any:
-        value = self.construct_scalar(node)
-        if value:
-            raise ConstructorError(
-                'while constructing a Python module',
-                node.start_mark,
-                f'expected the empty value, but found {value!r}',
-                node.start_mark,
-            )
-        return self.find_python_module(suffix, node.start_mark)
-
-    def make_python_instance(
-        self, suffix: Any, node: Any, args: Any = None, kwds: Any = None, newobj: bool = False,
-    ) -> Any:
-        if not args:
-            args = []
-        if not kwds:
-            kwds = {}
-        cls = self.find_python_name(suffix, node.start_mark)
-        if newobj and isinstance(cls, type):
-            return cls.__new__(cls, *args, **kwds)
-        else:
-            return cls(*args, **kwds)
-
-    def set_python_instance_state(self, instance: Any, state: Any) -> None:
-        if hasattr(instance, '__setstate__'):
-            instance.__setstate__(state)
-        else:
-            slotstate: Dict[Any, Any] = {}
-            if isinstance(state, tuple) and len(state) == 2:
-                state, slotstate = state
-            if hasattr(instance, '__dict__'):
-                instance.__dict__.update(state)
-            elif state:
-                slotstate.update(state)
-            for key, value in slotstate.items():
-                setattr(instance, key, value)
-
-    def construct_python_object(self, suffix: Any, node: Any) -> Any:
-        # Format:
-        #   !!python/object:module.name { ... state ... }
-        instance = self.make_python_instance(suffix, node, newobj=True)
-        self.recursive_objects[node] = instance
-        yield instance
-        deep = hasattr(instance, '__setstate__')
-        state = self.construct_mapping(node, deep=deep)
-        self.set_python_instance_state(instance, state)
-
-    def construct_python_object_apply(
-        self, suffix: Any, node: Any, newobj: bool = False,
-    ) -> Any:
-        # Format:
-        #   !!python/object/apply       # (or !!python/object/new)
-        #   args: [ ... arguments ... ]
-        #   kwds: { ... keywords ... }
-        #   state: ... state ...
-        #   listitems: [ ... listitems ... ]
-        #   dictitems: { ... dictitems ... }
-        # or short format:
-        #   !!python/object/apply [ ... arguments ... ]
-        # The difference between !!python/object/apply and !!python/object/new
-        # is how an object is created, check make_python_instance for details.
-        if isinstance(node, SequenceNode):
-            args = self.construct_sequence(node, deep=True)
-            kwds: Dict[Any, Any] = {}
-            state: Dict[Any, Any] = {}
-            listitems: List[Any] = []
-            dictitems: Dict[Any, Any] = {}
-        else:
-            value = self.construct_mapping(node, deep=True)
-            args = value.get('args', [])
-            kwds = value.get('kwds', {})
-            state = value.get('state', {})
-            listitems = value.get('listitems', [])
-            dictitems = value.get('dictitems', {})
-        instance = self.make_python_instance(suffix, node, args, kwds, newobj)
-        if bool(state):
-            self.set_python_instance_state(instance, state)
-        if bool(listitems):
-            instance.extend(listitems)
-        if bool(dictitems):
-            for key in dictitems:
-                instance[key] = dictitems[key]
-        return instance
-
-    def construct_python_object_new(self, suffix: Any, node: Any) -> Any:
-        return self.construct_python_object_apply(suffix, node, newobj=True)
-
-    @classmethod
-    def add_default_constructor(
-        cls, tag: str, method: Any = None, tag_base: str = 'tag:yaml.org,2002:python/',
-    ) -> None:
-        if not tag.startswith('tag:'):
-            if method is None:
-                method = 'construct_yaml_' + tag
-            tag = tag_base + tag
-        cls.add_constructor(tag, getattr(cls, method))
-
-
-Constructor.add_constructor('tag:yaml.org,2002:python/none', Constructor.construct_yaml_null)
-
-Constructor.add_constructor('tag:yaml.org,2002:python/bool', Constructor.construct_yaml_bool)
-
-Constructor.add_constructor('tag:yaml.org,2002:python/str', Constructor.construct_python_str)
-
-Constructor.add_constructor(
-    'tag:yaml.org,2002:python/unicode', Constructor.construct_python_unicode,
-)
-
-Constructor.add_constructor(
-    'tag:yaml.org,2002:python/bytes', Constructor.construct_python_bytes,
-)
-
-Constructor.add_constructor('tag:yaml.org,2002:python/int', Constructor.construct_yaml_int)
-
-Constructor.add_constructor('tag:yaml.org,2002:python/long', Constructor.construct_python_long)
-
-Constructor.add_constructor('tag:yaml.org,2002:python/float', Constructor.construct_yaml_float)
-
-Constructor.add_constructor(
-    'tag:yaml.org,2002:python/complex', Constructor.construct_python_complex,
-)
-
-Constructor.add_constructor('tag:yaml.org,2002:python/list', Constructor.construct_yaml_seq)
-
-Constructor.add_constructor(
-    'tag:yaml.org,2002:python/tuple', Constructor.construct_python_tuple,
-)
-# for tag in 'bool str unicode bytes int long float complex tuple'.split():
-#    Constructor.add_default_constructor(tag)
-
-Constructor.add_constructor('tag:yaml.org,2002:python/dict', Constructor.construct_yaml_map)
-
-Constructor.add_multi_constructor(
-    'tag:yaml.org,2002:python/name:', Constructor.construct_python_name,
-)
-
-Constructor.add_multi_constructor(
-    'tag:yaml.org,2002:python/module:', Constructor.construct_python_module,
-)
-
-Constructor.add_multi_constructor(
-    'tag:yaml.org,2002:python/object:', Constructor.construct_python_object,
-)
-
-Constructor.add_multi_constructor(
-    'tag:yaml.org,2002:python/object/apply:', Constructor.construct_python_object_apply,
-)
-
-Constructor.add_multi_constructor(
-    'tag:yaml.org,2002:python/object/new:', Constructor.construct_python_object_new,
-)
-
-
-class RoundTripConstructor(SafeConstructor):
-    """need to store the comments on the node itself,
-    as well as on the items
-    """
-
-    def comment(self, idx: Any) -> Any:
-        assert self.loader.comment_handling is not None
-        x = self.scanner.comments[idx]
-        x.set_assigned()
-        return x
-
-    def comments(self, list_of_comments: Any, idx: Optional[Any] = None) -> Any:
-        # hand in the comment and optional pre, eol, post segment
-        if list_of_comments is None:
-            return []
-        if idx is not None:
-            if list_of_comments[idx] is None:
-                return []
-            list_of_comments = list_of_comments[idx]
-        for x in list_of_comments:
-            yield self.comment(x)
-
-    def construct_scalar(self, node: Any) -> Any:
-        if not isinstance(node, ScalarNode):
-            raise ConstructorError(
-                None, None, f'expected a scalar node, but found {node.id!s}', node.start_mark,
-            )
-
-        if node.style == '|' and isinstance(node.value, str):
-            lss = LiteralScalarString(node.value, anchor=node.anchor)
-            if self.loader and self.loader.comment_handling is None:
-                if node.comment and node.comment[1]:
-                    lss.comment = node.comment[1][0]  # type: ignore
-            else:
-                # NEWCMNT
-                if node.comment is not None and node.comment[1]:
-                    # nprintf('>>>>nc1', node.comment)
-                    # EOL comment after |
-                    lss.comment = self.comment(node.comment[1][0])  # type: ignore
-            return lss
-        if node.style == '>' and isinstance(node.value, str):
-            fold_positions: List[int] = []
-            idx = -1
-            while True:
-                idx = node.value.find('\a', idx + 1)
-                if idx < 0:
-                    break
-                fold_positions.append(idx - len(fold_positions))
-            fss = FoldedScalarString(node.value.replace('\a', ''), anchor=node.anchor)
-            if self.loader and self.loader.comment_handling is None:
-                if node.comment and node.comment[1]:
-                    fss.comment = node.comment[1][0]  # type: ignore
-            else:
-                # NEWCMNT
-                if node.comment is not None and node.comment[1]:
-                    # nprintf('>>>>nc2', node.comment)
-                    # EOL comment after >
-                    fss.comment = self.comment(node.comment[1][0])  # type: ignore
-            if fold_positions:
-                fss.fold_pos = fold_positions  # type: ignore
-            return fss
-        elif bool(self._preserve_quotes) and isinstance(node.value, str):
-            if node.style == "'":
-                return SingleQuotedScalarString(node.value, anchor=node.anchor)
-            if node.style == '"':
-                return DoubleQuotedScalarString(node.value, anchor=node.anchor)
-        # if node.ctag:
-        #     data2 = TaggedScalar()
-        #     data2.value = node.value
-        #     data2.style = node.style
-        #     data2.yaml_set_ctag(node.ctag)
-        #     if node.anchor:
-        #         from ruamel.yaml.serializer import templated_id
-
-        #         if not templated_id(node.anchor):
-        #             data2.yaml_set_anchor(node.anchor, always_dump=True)
-        #     return data2
-        if node.anchor:
-            return PlainScalarString(node.value, anchor=node.anchor)
-        return node.value
-
-    def construct_yaml_int(self, node: Any) -> Any:
-        width: Any = None
-        value_su = self.construct_scalar(node)
-        try:
-            sx = value_su.rstrip('_')
-            underscore: Any = [len(sx) - sx.rindex('_') - 1, False, False]
-        except ValueError:
-            underscore = None
-        except IndexError:
-            underscore = None
-        value_s = value_su.replace('_', "")
-        sign = +1
-        if value_s[0] in '+-':
-            if value_s[0] == '-':
-                sign = -1
-            value_s = value_s[1:]
-        if value_s.startswith('0b'):
-            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
-                width = len(value_s[2:])
-            if underscore is not None:
-                underscore[1] = value_su[2] == '_'
-                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
-            return BinaryInt(
-                sign * int(value_s[2:], 2),
-                width=width,
-                underscore=underscore,
-                anchor=node.anchor,
-            )
-        elif value_s.startswith('0x'):
-            # default to lower-case if no a-fA-F in string
-            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
-                width = len(value_s[2:])
-            hex_fun: Any = HexInt
-            for ch in value_s[2:]:
-                if ch in 'ABCDEF':  # first non-digit is capital
-                    hex_fun = HexCapsInt
-                    break
-                if ch in 'abcdef':
-                    break
-            if underscore is not None:
-                underscore[1] = value_su[2] == '_'
-                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
-            return hex_fun(
-                sign * int(value_s[2:], 16),
-                width=width,
-                underscore=underscore,
-                anchor=node.anchor,
-            )
-        elif value_s.startswith('0o'):
-            if self.resolver.processing_version > (1, 1) and value_s[2] == '0':
-                width = len(value_s[2:])
-            if underscore is not None:
-                underscore[1] = value_su[2] == '_'
-                underscore[2] = len(value_su[2:]) > 1 and value_su[-1] == '_'
-            return OctalInt(
-                sign * int(value_s[2:], 8),
-                width=width,
-                underscore=underscore,
-                anchor=node.anchor,
-            )
-        elif (
-            self.resolver.processing_version != (1, 2)
-            and len(value_s) > 1
-            and value_s[0] == '0'
-        ):
-            return OctalInt(
-                sign * int(value_s, 8), width=width, underscore=underscore, anchor=node.anchor,
-            )
-        elif self.resolver.processing_version != (1, 2) and ':' in value_s:
-            digits = [int(part) for part in value_s.split(':')]
-            digits.reverse()
-            base = 1
-            value = 0
-            for digit in digits:
-                value += digit * base
-                base *= 60
-            return sign * value
-        elif self.resolver.processing_version > (1, 1) and value_s[0] == '0':
-            # not an octal, an integer with leading zero(s)
-            if underscore is not None:
-                # cannot have a leading underscore
-                underscore[2] = len(value_su) > 1 and value_su[-1] == '_'
-            return ScalarInt(
-                sign * int(value_s),
-                width=len(value_s),
-                underscore=underscore,
-                anchor=node.anchor,
-            )
-        elif underscore:
-            # cannot have a leading underscore
-            underscore[2] = len(value_su) > 1 and value_su[-1] == '_'
-            return ScalarInt(
-                sign * int(value_s), width=None, underscore=underscore, anchor=node.anchor,
-            )
-        elif node.anchor:
-            return ScalarInt(sign * int(value_s), width=None, anchor=node.anchor)
-        else:
-            return sign * int(value_s)
-
-    def construct_yaml_float(self, node: Any) -> Any:
-        def leading_zeros(v: Any) -> int:
-            lead0 = 0
-            idx = 0
-            while idx < len(v) and v[idx] in '0.':
-                if v[idx] == '0':
-                    lead0 += 1
-                idx += 1
-            return lead0
-
-        # underscore = None
-        m_sign: Any = False
-        value_so = self.construct_scalar(node)
-        value_s = value_so.replace('_', "").lower()
-        sign = +1
-        if value_s[0] == '-':
-            sign = -1
-        if value_s[0] in '+-':
-            m_sign = value_s[0]
-            value_s = value_s[1:]
-        if value_s == '.inf':
-            return sign * self.inf_value
-        if value_s == '.nan':
-            return self.nan_value
-        if self.resolver.processing_version != (1, 2) and ':' in value_s:
-            digits = [float(part) for part in value_s.split(':')]
-            digits.reverse()
-            base = 1
-            value = 0.0
-            for digit in digits:
-                value += digit * base
-                base *= 60
-            return sign * value
-        if 'e' in value_s:
-            try:
-                mantissa, exponent = value_so.split('e')
-                exp = 'e'
-            except ValueError:
-                mantissa, exponent = value_so.split('E')
-                exp = 'E'
-            if self.resolver.processing_version != (1, 2):
-                # value_s is lower case independent of input
-                if '.' not in mantissa:
-                    warnings.warn(MantissaNoDotYAML1_1Warning(node, value_so), stacklevel=1)
-            lead0 = leading_zeros(mantissa)
-            width = len(mantissa)
-            prec = mantissa.find('.')
-            if m_sign:
-                width -= 1
-            e_width = len(exponent)
-            e_sign = exponent[0] in '+-'
-            # nprint('sf', width, prec, m_sign, exp, e_width, e_sign)
-            return ScalarFloat(
-                sign * float(value_s),
-                width=width,
-                prec=prec,
-                m_sign=m_sign,
-                m_lead0=lead0,
-                exp=exp,
-                e_width=e_width,
-                e_sign=e_sign,
-                anchor=node.anchor,
-            )
-        width = len(value_so)
-        # you can't use index, !!float 42 would be a float without a dot
-        prec = value_so.find('.')
-        lead0 = leading_zeros(value_so)
-        return ScalarFloat(
-            sign * float(value_s),
-            width=width,
-            prec=prec,
-            m_sign=m_sign,
-            m_lead0=lead0,
-            anchor=node.anchor,
-        )
-
-    def construct_yaml_str(self, node: Any) -> Any:
-        if node.ctag.handle:
-            value = self.construct_unknown(node)
-        else:
-            value = self.construct_scalar(node)
-        if isinstance(value, ScalarString):
-            return value
-        return value
-
-    def construct_rt_sequence(self, node: Any, seqtyp: Any, deep: bool = False) -> Any:
-        if not isinstance(node, SequenceNode):
-            raise ConstructorError(
-                None,
-                None,
-                f'expected a sequence node, but found {node.id!s}',
-                node.start_mark,
-            )
-        ret_val = []
-        if self.loader and self.loader.comment_handling is None:
-            if node.comment:
-                seqtyp._yaml_add_comment(node.comment[:2])
-                if len(node.comment) > 2:
-                    # this happens e.g. if you have a sequence element that is a flow-style
-                    # mapping and that has no EOL comment but a following commentline or
-                    # empty line
-                    seqtyp.yaml_end_comment_extend(node.comment[2], clear=True)
-        else:
-            # NEWCMNT
-            if node.comment:
-                nprintf('nc3', node.comment)
-        if node.anchor:
-            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
-
-            if not templated_id(node.anchor):
-                seqtyp.yaml_set_anchor(node.anchor)
-        for idx, child in enumerate(node.value):
-            if child.comment:
-                seqtyp._yaml_add_comment(child.comment, key=idx)
-                child.comment = None  # if moved to sequence remove from child
-            ret_val.append(self.construct_object(child, deep=deep))
-            seqtyp._yaml_set_idx_line_col(
-                idx, [child.start_mark.line, child.start_mark.column],
-            )
-        return ret_val
-
-    def flatten_mapping(self, node: Any) -> Any:  # RTConstructor
-        """
-        This implements the merge key feature http://yaml.org/type/merge.html
-        by referencing the merge dict/list of dicts
-        """
-        from opentelemetry.agent._vendor.ruamel.yaml.mergevalue import MergeValue
-
-        def constructed(value_node: Any) -> Any:
-            # If the contents of a merge are defined within the
-            # merge marker, then they won't have been constructed
-            # yet. But if they were already constructed, we need to use
-            # the existing object.
-            if value_node in self.constructed_objects:
-                value = self.constructed_objects[value_node]
-            else:
-                value = self.construct_object(value_node, deep=True)
-            return value
-
-        # merge = []
-        # merge_map_list: List[Any] = []
-        merge_map_list = MergeValue()
-        index = 0
-        while index < len(node.value):
-            key_node, value_node = node.value[index]
-            if key_node.tag == 'tag:yaml.org,2002:merge':
-                if len(merge_map_list):  # double << key
-                    args = [
-                        'while constructing a mapping',
-                        node.start_mark,
-                        'found duplicate merge key "<<"',
-                        key_node.start_mark,
-                        """\
-                        Duplicate merge keys are never allowed, not even when
-                        `.allow_duplicate_keys` is set to True
-                        """,
-                    ]
-                    raise DuplicateKeyError(*args)
-                del node.value[index]
-                merge_map_list.merge_pos = index
-                if isinstance(value_node, MappingNode):
-                    merge_map_list.append(constructed(value_node))
-                elif isinstance(value_node, SequenceNode):
-                    # submerge = []
-                    merge_map_list.set_sequence(constructed(value_node))
-                    for subnode in value_node.value:
-                        if not isinstance(subnode, MappingNode):
-                            raise ConstructorError(
-                                'while constructing a mapping',
-                                node.start_mark,
-                                f'expected a mapping for merging, but found {subnode.id!s}',
-                                subnode.start_mark,
-                            )
-                        merge_map_list.append(constructed(subnode))
-                else:
-                    raise ConstructorError(
-                        'while constructing a mapping',
-                        node.start_mark,
-                        'expected a mapping or list of mappings for merging, '
-                        f'but found {value_node.id!s}',
-                        value_node.start_mark,
-                    )
-            elif key_node.tag == 'tag:yaml.org,2002:value':
-                key_node.tag = 'tag:yaml.org,2002:str'
-                index += 1
-            else:
-                index += 1
-        return merge_map_list
-        # if merge:
-        #     node.value = merge + node.value
-
-    def _sentinel(self) -> None:
-        pass
-
-    # RoundTrip
-    def construct_mapping(self, node: Any, maptyp: Any, deep: bool = False) -> Any:  # type: ignore # NOQA
-        if not isinstance(node, MappingNode):
-            raise ConstructorError(
-                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
-            )
-        merge_map = self.flatten_mapping(node)
-        # mapping = {}
-        if self.loader and self.loader.comment_handling is None:
-            if node.comment:
-                maptyp._yaml_add_comment(node.comment[:2])
-                if len(node.comment) > 2:
-                    maptyp.yaml_end_comment_extend(node.comment[2], clear=True)
-        else:
-            # NEWCMNT
-            if node.comment:
-                # nprintf('nc4', node.comment, node.start_mark)
-                if maptyp.ca.pre is None:
-                    maptyp.ca.pre = []
-                for cmnt in self.comments(node.comment, 0):
-                    maptyp.ca.pre.append(cmnt)
-        if node.anchor:
-            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
-
-            if not templated_id(node.anchor):
-                maptyp.yaml_set_anchor(node.anchor)
-        last_key, last_value = None, self._sentinel
-        for key_node, value_node in node.value:
-            # keys can be list -> deep
-            key = self.construct_object(key_node, deep=True)
-            # lists are not hashable, but tuples are
-            if not isinstance(key, Hashable):
-                if isinstance(key, MutableSequence):
-                    key_s = CommentedKeySeq(key)
-                    if key_node.flow_style is True:
-                        key_s.fa.set_flow_style()
-                    elif key_node.flow_style is False:
-                        key_s.fa.set_block_style()
-                    key_s._yaml_set_line_col(key.lc.line, key.lc.col)  # type: ignore
-                    key = key_s
-                elif isinstance(key, MutableMapping):
-                    key_m = CommentedKeyMap(key)
-                    if key_node.flow_style is True:
-                        key_m.fa.set_flow_style()
-                    elif key_node.flow_style is False:
-                        key_m.fa.set_block_style()
-                    key_m._yaml_set_line_col(key.lc.line, key.lc.col)  # type: ignore
-                    key = key_m
-            if not isinstance(key, Hashable):
-                raise ConstructorError(
-                    'while constructing a mapping',
-                    node.start_mark,
-                    'found unhashable key',
-                    key_node.start_mark,
-                )
-            value = self.construct_object(value_node, deep=deep)
-            if self.check_mapping_key(node, key_node, maptyp, key, value):
-                if self.loader and self.loader.comment_handling is None:
-                    if key_node.comment and len(key_node.comment) > 4 and key_node.comment[4]:
-                        if last_value is None:
-                            key_node.comment[0] = key_node.comment.pop(4)
-                            maptyp._yaml_add_comment(key_node.comment, value=last_key)
-                        else:
-                            key_node.comment[2] = key_node.comment.pop(4)
-                            maptyp._yaml_add_comment(key_node.comment, key=key)
-                        key_node.comment = None
-                    if key_node.comment:
-                        maptyp._yaml_add_comment(key_node.comment, key=key)
-                    if value_node.comment:
-                        maptyp._yaml_add_comment(value_node.comment, value=key)
-                else:
-                    # NEWCMNT
-                    if key_node.comment:
-                        # nprintf('nc5a', key, key_node.comment)
-                        if key_node.comment[0]:
-                            maptyp.ca.set(key, C_KEY_PRE, key_node.comment[0])
-                        if key_node.comment[1]:
-                            maptyp.ca.set(key, C_KEY_EOL, key_node.comment[1])
-                        if key_node.comment[2]:
-                            maptyp.ca.set(key, C_KEY_POST, key_node.comment[2])
-                    if value_node.comment:
-                        nprintf('nc5b', key, value_node.comment)
-                        if value_node.comment[0]:
-                            maptyp.ca.set(key, C_VALUE_PRE, value_node.comment[0])
-                        if value_node.comment[1]:
-                            maptyp.ca.set(key, C_VALUE_EOL, value_node.comment[1])
-                        if value_node.comment[2]:
-                            maptyp.ca.set(key, C_VALUE_POST, value_node.comment[2])
-                maptyp._yaml_set_kv_line_col(
-                    key,
-                    [
-                        key_node.start_mark.line,
-                        key_node.start_mark.column,
-                        value_node.start_mark.line,
-                        value_node.start_mark.column,
-                    ],
-                )
-                maptyp[key] = value
-                last_key, last_value = key, value  # could use indexing
-        # do this last, or <<: before a key will prevent insertion in instances
-        # of collections.OrderedDict (as they have no __contains__
-        if merge_map:
-            maptyp.add_yaml_merge(merge_map)
-
-    def construct_setting(self, node: Any, typ: Any, deep: bool = False) -> Any:
-        if not isinstance(node, MappingNode):
-            raise ConstructorError(
-                None, None, f'expected a mapping node, but found {node.id!s}', node.start_mark,
-            )
-        if self.loader and self.loader.comment_handling is None:
-            if node.comment:
-                typ._yaml_add_comment(node.comment[:2])
-                if len(node.comment) > 2:
-                    typ.yaml_end_comment_extend(node.comment[2], clear=True)
-        else:
-            # NEWCMNT
-            if node.comment:
-                nprintf('nc6', node.comment)
-        if node.anchor:
-            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
-
-            if not templated_id(node.anchor):
-                typ.yaml_set_anchor(node.anchor)
-        for key_node, value_node in node.value:
-            # keys can be list -> deep
-            key = self.construct_object(key_node, deep=True)
-            # lists are not hashable, but tuples are
-            if not isinstance(key, Hashable):
-                if isinstance(key, list):
-                    key = tuple(key)
-            if not isinstance(key, Hashable):
-                raise ConstructorError(
-                    'while constructing a mapping',
-                    node.start_mark,
-                    'found unhashable key',
-                    key_node.start_mark,
-                )
-            # construct but should be null
-            value = self.construct_object(value_node, deep=deep)  # NOQA
-            self.check_set_key(node, key_node, typ, key)
-            if self.loader and self.loader.comment_handling is None:
-                if key_node.comment:
-                    typ._yaml_add_comment(key_node.comment, key=key)
-                if value_node.comment:
-                    typ._yaml_add_comment(value_node.comment, value=key)
-            else:
-                # NEWCMNT
-                if key_node.comment:
-                    nprintf('nc7a', key_node.comment)
-                if value_node.comment:
-                    nprintf('nc7b', value_node.comment)
-            typ.add(key)
-
-    def construct_yaml_seq(self, node: Any) -> Iterator[CommentedSeq]:
-        data = CommentedSeq()
-        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
-        # if node.comment:
-        #    data._yaml_add_comment(node.comment)
-        yield data
-        data.extend(self.construct_rt_sequence(node, data))
-        self.set_collection_style(data, node)
-
-    def construct_yaml_map(self, node: Any) -> Iterator[CommentedMap]:
-        data = CommentedMap()
-        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
-        yield data
-        self.construct_mapping(node, data, deep=True)
-        self.set_collection_style(data, node)
-
-    def set_collection_style(self, data: Any, node: Any) -> None:
-        if len(data) == 0:
-            return
-        if node.flow_style is True:
-            data.fa.set_flow_style()
-        elif node.flow_style is False:
-            data.fa.set_block_style()
-
-    def construct_yaml_object(self, node: Any, cls: Any) -> Any:
-        from dataclasses import is_dataclass, InitVar, MISSING
-
-        data = cls.__new__(cls)
-        yield data
-        if hasattr(data, '__setstate__'):
-            state = SafeConstructor.construct_mapping(self, node, deep=True)
-            data.__setstate__(state)
-        elif is_dataclass(data):
-            mapping = SafeConstructor.construct_mapping(self, node, deep=True)
-            init_var_defaults = {}
-            for field in data.__dataclass_fields__.values():
-                # nprintf('field', field, field.default is MISSING, isinstance(field.type, InitVar))  # NOQA
-                # in 3.7, InitVar is a singleton
-                if (
-                    isinstance(field.type, InitVar)
-                    or field.type is InitVar
-                    # this following is for handling from __future__ import allocations
-                    or (isinstance(field.type, str) and field.type.startswith('InitVar'))
-                ) and field.default is not MISSING:
-                    init_var_defaults[field.name] = field.default
-            for attr, value in mapping.items():
-                if attr not in init_var_defaults:
-                    setattr(data, attr, value)
-            post_init = getattr(data, '__post_init__', None)
-            if post_init is not None:
-                kw = {}
-                for name, default in init_var_defaults.items():
-                    kw[name] = mapping.get(name, default)
-                post_init(**kw)
-            for field in data.__dataclass_fields__.values():
-                if field.name not in mapping and field.default_factory is not MISSING:
-                    setattr(data, field.name, field.default_factory())
-        else:
-            state = SafeConstructor.construct_mapping(self, node)
-            if hasattr(data, '__attrs_attrs__'):  # issue 394
-                data.__init__(**state)
-            else:
-                data.__dict__.update(state)
-        if node.anchor:
-            from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
-            from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
-
-            if not templated_id(node.anchor):
-                if not hasattr(data, Anchor.attrib):
-                    a = Anchor()
-                    setattr(data, Anchor.attrib, a)
-                else:
-                    a = getattr(data, Anchor.attrib)
-                a.value = node.anchor
-
-    def construct_yaml_omap(self, node: Any) -> Iterator[CommentedOrderedMap]:
-        # Note: we do now check for duplicate keys
-        omap = CommentedOrderedMap()
-        omap._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
-        if node.flow_style is True:
-            omap.fa.set_flow_style()
-        elif node.flow_style is False:
-            omap.fa.set_block_style()
-        yield omap
-        if self.loader and self.loader.comment_handling is None:
-            if node.comment:
-                omap._yaml_add_comment(node.comment[:2])
-                if len(node.comment) > 2:
-                    omap.yaml_end_comment_extend(node.comment[2], clear=True)
-        else:
-            # NEWCMNT
-            if node.comment:
-                nprintf('nc8', node.comment)
-        if not isinstance(node, SequenceNode):
-            raise ConstructorError(
-                'while constructing an ordered map',
-                node.start_mark,
-                f'expected a sequence, but found {node.id!s}',
-                node.start_mark,
-            )
-        for subnode in node.value:
-            if not isinstance(subnode, MappingNode):
-                raise ConstructorError(
-                    'while constructing an ordered map',
-                    node.start_mark,
-                    f'expected a mapping of length 1, but found {subnode.id!s}',
-                    subnode.start_mark,
-                )
-            if len(subnode.value) != 1:
-                raise ConstructorError(
-                    'while constructing an ordered map',
-                    node.start_mark,
-                    f'expected a single mapping item, but found {len(subnode.value):d} items',
-                    subnode.start_mark,
-                )
-            key_node, value_node = subnode.value[0]
-            key = self.construct_object(key_node)
-            assert key not in omap
-            value = self.construct_object(value_node)
-            if self.loader and self.loader.comment_handling is None:
-                if key_node.comment:
-                    omap._yaml_add_comment(key_node.comment, key=key)
-                if subnode.comment:
-                    omap._yaml_add_comment(subnode.comment, key=key)
-                if value_node.comment:
-                    omap._yaml_add_comment(value_node.comment, value=key)
-            else:
-                # NEWCMNT
-                if key_node.comment:
-                    nprintf('nc9a', key_node.comment)
-                if subnode.comment:
-                    nprintf('nc9b', subnode.comment)
-                if value_node.comment:
-                    nprintf('nc9c', value_node.comment)
-            omap[key] = value
-
-    def construct_yaml_set(self, node: Any) -> Iterator[CommentedSet]:
-        data = CommentedSet()
-        data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
-        if node.flow_style is True:
-            data.fa.set_flow_style()
-        elif node.flow_style is False:
-            data.fa.set_block_style()
-        yield data
-        self.construct_setting(node, data)
-
-    def construct_unknown(
-        self, node: Any,
-    ) -> Iterator[Union[CommentedMap, TaggedScalar, CommentedSeq]]:
-        try:
-            if isinstance(node, MappingNode):
-                data = CommentedMap()
-                data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
-                if node.flow_style is True:
-                    data.fa.set_flow_style()
-                elif node.flow_style is False:
-                    data.fa.set_block_style()
-                data.yaml_set_ctag(node.ctag)
-                yield data
-                if node.anchor:
-                    from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
-
-                    if not templated_id(node.anchor):
-                        data.yaml_set_anchor(node.anchor)
-                self.construct_mapping(node, data)
-                return
-            elif isinstance(node, ScalarNode):
-                data2 = TaggedScalar()
-                data2.value = self.construct_scalar(node)
-                data2.style = node.style
-                data2.yaml_set_ctag(node.ctag)
-                yield data2
-                if node.anchor:
-                    from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
-
-                    if not templated_id(node.anchor):
-                        data2.yaml_set_anchor(node.anchor, always_dump=True)
-                return
-            elif isinstance(node, SequenceNode):
-                data3 = CommentedSeq()
-                data3._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
-                if node.flow_style is True:
-                    data3.fa.set_flow_style()
-                elif node.flow_style is False:
-                    data3.fa.set_block_style()
-                data3.yaml_set_ctag(node.ctag)
-                yield data3
-                if node.anchor:
-                    from opentelemetry.agent._vendor.ruamel.yaml.serializer import templated_id
-
-                    if not templated_id(node.anchor):
-                        data3.yaml_set_anchor(node.anchor)
-                data3.extend(self.construct_sequence(node))
-                return
-        except:  # NOQA
-            pass
-        raise ConstructorError(
-            None,
-            None,
-            f'could not determine a constructor for the tag {node.tag!r}',
-            node.start_mark,
-        )
-
-    def construct_yaml_timestamp(
-        self, node: Any, values: Any = None,
-    ) -> Union[datetime.date, datetime.datetime, TimeStamp]:
-        try:
-            match = self.timestamp_regexp.match(node.value)
-        except TypeError:
-            match = None
-        if match is None:
-            raise ConstructorError(
-                None,
-                None,
-                f'failed to construct timestamp from "{node.value}"',
-                node.start_mark,
-            )
-        values = match.groupdict()
-        if not values['hour']:
-            return create_timestamp(**values)
-            # return SafeConstructor.construct_yaml_timestamp(self, node, values)
-        for part in ['t', 'tz_sign', 'tz_hour', 'tz_minute']:
-            if values[part]:
-                break
-        else:
-            return create_timestamp(**values)
-            # return SafeConstructor.construct_yaml_timestamp(self, node, values)
-        # print('>>>>>>>> here', values)
-        dd = create_timestamp(**values)  # this has tzinfo
-        delta = None
-        if values['tz_sign']:
-            hours = values['tz_hour']
-            tz_hour = int(hours)
-            minutes = values['tz_minute']
-            tz_minute = int(minutes) if minutes else 0
-            # ToDo: double work, replace with extraction from dd.tzinfo
-            delta = TimeDelta(hours=tz_hour, minutes=tz_minute)
-            if values['tz_sign'] == '-':
-                delta = -delta
-        if isinstance(dd, datetime.datetime):
-            data = TimeStamp(
-                dd.year, dd.month, dd.day, dd.hour, dd.minute, dd.second, dd.microsecond, dd.tzinfo,  # NOQA
-            )
-        else:
-            # ToDo: make this into a DateStamp?
-            data = TimeStamp(dd.year, dd.month, dd.day, 0, 0, 0, 0)
-            return data
-        if delta:
-            data._yaml['delta'] = delta
-            tz = values['tz_sign'] + values['tz_hour']
-            if values['tz_minute']:
-                tz += ':' + values['tz_minute']
-            data._yaml['tz'] = tz
-        else:
-            if values['tz']:  # no delta
-                data._yaml['tz'] = values['tz']
-        if values['t']:
-            data._yaml['t'] = True
-        return data
-
-    def construct_yaml_sbool(self, node: Any) -> Union[bool, ScalarBoolean]:
-        b = SafeConstructor.construct_yaml_bool(self, node)
-        if node.anchor:
-            return ScalarBoolean(b, anchor=node.anchor)
-        return b
-
-
-RoundTripConstructor.add_default_constructor('bool', method='construct_yaml_sbool')
-
-for tag in 'null int float binary timestamp omap pairs set str seq map'.split():
-    RoundTripConstructor.add_default_constructor(tag)
-
-RoundTripConstructor.add_constructor(None, RoundTripConstructor.construct_unknown)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py
deleted file mode 100644
index 1c9254bc14e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/docinfo.py
+++ /dev/null
@@ -1,130 +0,0 @@
-
-from __future__ import annotations
-
-"""
-DocInfo
-
-Although it was possible to read tag directives before this, all handle/prefix
-pairs for all documents in all streams were stored in one dictionary per
-YAML instance, making it impossible to distinguish where such a pair came
-from without sublassing the scanner.
-
-ToDo:
-DocInfo can be used by a yaml dumper to dump a class
-- if connected to the root of a data structure
-- if provided to the dumper?
-"""
-
-if False:  # MYPY
-    from typing import Optional, Tuple, Any
-
-# from dataclasses import dataclass, field, MISSING  # NOQA
-
-
-# @dataclass(order=True, frozen=True)
-class Version:
-    # major: int
-    # minor: int
-    def __init__(self, major: int, minor: int) -> None:
-        self._major = major
-        self._minor = minor
-
-    @property
-    def major(self) -> int:
-        return self._major
-
-    @property
-    def minor(self) -> int:
-        return self._minor
-
-    def __eq__(self, v: Any) -> bool:
-        if not isinstance(v, Version):
-            return False
-        return self._major == v._major and self._minor == v._minor
-
-    def __lt__(self, v: Version) -> bool:
-        if self._major < v._major:
-            return True
-        if self._major > v._major:
-            return False
-        return self._minor < v._minor
-
-    def __le__(self, v: Version) -> bool:
-        if self._major < v._major:
-            return True
-        if self._major > v._major:
-            return False
-        return self._minor <= v._minor
-
-    def __gt__(self, v: Version) -> bool:
-        if self._major > v._major:
-            return True
-        if self._major < v._major:
-            return False
-        return self._minor > v._minor
-
-    def __ge__(self, v: Version) -> bool:
-        if self._major > v._major:
-            return True
-        if self._major < v._major:
-            return False
-        return self._minor >= v._minor
-
-
-def version(
-    major: int | str | Tuple[int, int] | None,
-    minor: Optional[int] = None,
-) -> Optional[Version]:
-    if major is None:
-        assert minor is None
-        return None
-    if isinstance(major, str):
-        assert minor is None
-        parts = major.split('.')
-        assert len(parts) == 2
-        return Version(int(parts[0]), int(parts[1]))
-    elif isinstance(major, tuple):
-        assert minor is None
-        assert len(major) == 2
-        major, minor = major
-    assert minor is not None
-    return Version(major, minor)
-
-
-# @dataclass(frozen=True)
-class Tag:
-    # handle: str
-    # prefix: str
-    def __init__(self, handle: str, prefix: str) -> None:
-        self._handle = handle
-        self._prefix = prefix
-
-    @property
-    def handle(self) -> str:
-        return self._handle
-
-    @property
-    def prefix(self) -> str:
-        return self._prefix
-
-
-# @dataclass
-class DocInfo:
-    """
-    Store document information, can be used for analysis of a loaded YAML document
-    requested_version: if explicitly set before load
-    doc_version: from %YAML directive
-    tags: from %TAG directives in scanned order
-    """
-    # requested_version: Optional[Version] = None
-    # doc_version: Optional[Version] = None
-    # tags: list[Tag] = field(default_factory=list)
-    def __init__(
-        self,
-        requested_version: Optional[Version] = None,
-        doc_version: Optional[Version] = None,
-        tags: Optional[list[Tag]] = None,
-    ):
-        self.requested_version = requested_version
-        self.doc_version = doc_version
-        self.tags = [] if tags is None else tags
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py
deleted file mode 100644
index ef11237a173..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/dumper.py
+++ /dev/null
@@ -1,220 +0,0 @@
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.emitter import Emitter
-from opentelemetry.agent._vendor.ruamel.yaml.serializer import Serializer
-from opentelemetry.agent._vendor.ruamel.yaml.representer import (
-    Representer,
-    SafeRepresenter,
-    BaseRepresenter,
-    RoundTripRepresenter,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.resolver import Resolver, BaseResolver, VersionedResolver
-
-if False:  # MYPY
-    from typing import Any, Dict, List, Union, Optional  # NOQA
-    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamType, VersionType  # NOQA
-
-__all__ = ['BaseDumper', 'SafeDumper', 'Dumper', 'RoundTripDumper']
-
-
-class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
-    def __init__(
-        self: Any,
-        stream: StreamType,
-        default_style: Any = None,
-        default_flow_style: Any = None,
-        canonical: Optional[bool] = None,
-        indent: Optional[int] = None,
-        width: Optional[int] = None,
-        allow_unicode: Optional[bool] = None,
-        line_break: Any = None,
-        encoding: Any = None,
-        explicit_start: Optional[bool] = None,
-        explicit_end: Optional[bool] = None,
-        version: Any = None,
-        tags: Any = None,
-        block_seq_indent: Any = None,
-        top_level_colon_align: Any = None,
-        prefix_colon: Any = None,
-    ) -> None:
-        # NOQA
-        Emitter.__init__(
-            self,
-            stream,
-            canonical=canonical,
-            indent=indent,
-            width=width,
-            allow_unicode=allow_unicode,
-            line_break=line_break,
-            block_seq_indent=block_seq_indent,
-            dumper=self,
-        )
-        Serializer.__init__(
-            self,
-            encoding=encoding,
-            explicit_start=explicit_start,
-            explicit_end=explicit_end,
-            version=version,
-            tags=tags,
-            dumper=self,
-        )
-        BaseRepresenter.__init__(
-            self,
-            default_style=default_style,
-            default_flow_style=default_flow_style,
-            dumper=self,
-        )
-        BaseResolver.__init__(self, loadumper=self)
-
-
-class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver):
-    def __init__(
-        self,
-        stream: StreamType,
-        default_style: Any = None,
-        default_flow_style: Any = None,
-        canonical: Optional[bool] = None,
-        indent: Optional[int] = None,
-        width: Optional[int] = None,
-        allow_unicode: Optional[bool] = None,
-        line_break: Any = None,
-        encoding: Any = None,
-        explicit_start: Optional[bool] = None,
-        explicit_end: Optional[bool] = None,
-        version: Any = None,
-        tags: Any = None,
-        block_seq_indent: Any = None,
-        top_level_colon_align: Any = None,
-        prefix_colon: Any = None,
-    ) -> None:
-        # NOQA
-        Emitter.__init__(
-            self,
-            stream,
-            canonical=canonical,
-            indent=indent,
-            width=width,
-            allow_unicode=allow_unicode,
-            line_break=line_break,
-            block_seq_indent=block_seq_indent,
-            dumper=self,
-        )
-        Serializer.__init__(
-            self,
-            encoding=encoding,
-            explicit_start=explicit_start,
-            explicit_end=explicit_end,
-            version=version,
-            tags=tags,
-            dumper=self,
-        )
-        SafeRepresenter.__init__(
-            self,
-            default_style=default_style,
-            default_flow_style=default_flow_style,
-            dumper=self,
-        )
-        Resolver.__init__(self, loadumper=self)
-
-
-class Dumper(Emitter, Serializer, Representer, Resolver):
-    def __init__(
-        self,
-        stream: StreamType,
-        default_style: Any = None,
-        default_flow_style: Any = None,
-        canonical: Optional[bool] = None,
-        indent: Optional[int] = None,
-        width: Optional[int] = None,
-        allow_unicode: Optional[bool] = None,
-        line_break: Any = None,
-        encoding: Any = None,
-        explicit_start: Optional[bool] = None,
-        explicit_end: Optional[bool] = None,
-        version: Any = None,
-        tags: Any = None,
-        block_seq_indent: Any = None,
-        top_level_colon_align: Any = None,
-        prefix_colon: Any = None,
-    ) -> None:
-        # NOQA
-        Emitter.__init__(
-            self,
-            stream,
-            canonical=canonical,
-            indent=indent,
-            width=width,
-            allow_unicode=allow_unicode,
-            line_break=line_break,
-            block_seq_indent=block_seq_indent,
-            dumper=self,
-        )
-        Serializer.__init__(
-            self,
-            encoding=encoding,
-            explicit_start=explicit_start,
-            explicit_end=explicit_end,
-            version=version,
-            tags=tags,
-            dumper=self,
-        )
-        Representer.__init__(
-            self,
-            default_style=default_style,
-            default_flow_style=default_flow_style,
-            dumper=self,
-        )
-        Resolver.__init__(self, loadumper=self)
-
-
-class RoundTripDumper(Emitter, Serializer, RoundTripRepresenter, VersionedResolver):
-    def __init__(
-        self,
-        stream: StreamType,
-        default_style: Any = None,
-        default_flow_style: Optional[bool] = None,
-        canonical: Optional[int] = None,
-        indent: Optional[int] = None,
-        width: Optional[int] = None,
-        allow_unicode: Optional[bool] = None,
-        line_break: Any = None,
-        encoding: Any = None,
-        explicit_start: Optional[bool] = None,
-        explicit_end: Optional[bool] = None,
-        version: Any = None,
-        tags: Any = None,
-        block_seq_indent: Any = None,
-        top_level_colon_align: Any = None,
-        prefix_colon: Any = None,
-    ) -> None:
-        # NOQA
-        Emitter.__init__(
-            self,
-            stream,
-            canonical=canonical,
-            indent=indent,
-            width=width,
-            allow_unicode=allow_unicode,
-            line_break=line_break,
-            block_seq_indent=block_seq_indent,
-            top_level_colon_align=top_level_colon_align,
-            prefix_colon=prefix_colon,
-            dumper=self,
-        )
-        Serializer.__init__(
-            self,
-            encoding=encoding,
-            explicit_start=explicit_start,
-            explicit_end=explicit_end,
-            version=version,
-            tags=tags,
-            dumper=self,
-        )
-        RoundTripRepresenter.__init__(
-            self,
-            default_style=default_style,
-            default_flow_style=default_flow_style,
-            dumper=self,
-        )
-        VersionedResolver.__init__(self, loader=self)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py
deleted file mode 100644
index 6e422a1e362..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/emitter.py
+++ /dev/null
@@ -1,1802 +0,0 @@
-
-from __future__ import annotations
-
-# Emitter expects events obeying the following grammar:
-# stream ::= STREAM-START document* STREAM-END
-# document ::= DOCUMENT-START node DOCUMENT-END
-# node ::= SCALAR | sequence | mapping
-# sequence ::= SEQUENCE-START node* SEQUENCE-END
-# mapping ::= MAPPING-START (node node)* MAPPING-END
-
-import sys
-from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError, YAMLStreamError
-from opentelemetry.agent._vendor.ruamel.yaml.events import *  # NOQA
-
-# fmt: off
-from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, dbg, DBG_EVENT, \
-    check_anchorname_char, nprintf  # NOQA
-# fmt: on
-
-
-if False:  # MYPY
-    from typing import Any, Dict, List, Union, Text, Tuple, Optional  # NOQA
-    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamType  # NOQA
-
-__all__ = ['Emitter', 'EmitterError']
-
-
-class EmitterError(YAMLError):
-    pass
-
-
-class ScalarAnalysis:
-    def __init__(
-        self,
-        scalar: Any,
-        empty: Any,
-        multiline: Any,
-        allow_flow_plain: bool,
-        allow_block_plain: bool,
-        allow_single_quoted: bool,
-        allow_double_quoted: bool,
-        allow_block: bool,
-    ) -> None:
-        self.scalar = scalar
-        self.empty = empty
-        self.multiline = multiline
-        self.allow_flow_plain = allow_flow_plain
-        self.allow_block_plain = allow_block_plain
-        self.allow_single_quoted = allow_single_quoted
-        self.allow_double_quoted = allow_double_quoted
-        self.allow_block = allow_block
-
-    def __repr__(self) -> str:
-        return f'scalar={self.scalar!r}, empty={self.empty}, multiline={self.multiline}, allow_flow_plain={self.allow_flow_plain}, allow_block_plain={self.allow_block_plain}, allow_single_quoted={self.allow_single_quoted}, allow_double_quoted={self.allow_double_quoted}, allow_block={self.allow_block}'  # NOQA
-
-
-class Indents:
-    # replacement for the list based stack of None/int
-    def __init__(self) -> None:
-        self.values: List[Tuple[Any, bool]] = []
-
-    def append(self, val: Any, seq: Any) -> None:
-        self.values.append((val, seq))
-
-    def pop(self) -> Any:
-        return self.values.pop()[0]
-
-    def seq_seq(self) -> bool:
-        try:
-            if self.values[-2][1] and self.values[-1][1]:
-                return True
-        except IndexError:
-            pass
-        return False
-
-    def last_seq(self) -> bool:
-        # return the seq(uence) value for the element added before the last one
-        # in increase_indent()
-        try:
-            return self.values[-2][1]
-        except IndexError:
-            return False
-
-    def seq_flow_align(
-        self, seq_indent: int, column: int, pre_comment: Optional[bool] = False,
-    ) -> int:
-        # extra spaces because of dash
-        # nprint('seq_flow_align', self.values, pre_comment)
-        if len(self.values) < 2 or not self.values[-1][1]:
-            if len(self.values) == 0 or not pre_comment:
-                return 0
-        base = self.values[-1][0] if self.values[-1][0] is not None else 0
-        if pre_comment:
-            return base + seq_indent  # type: ignore
-            # return (len(self.values)) * seq_indent
-        # -1 for the dash
-        return base + seq_indent - column - 1  # type: ignore
-
-    def __len__(self) -> int:
-        return len(self.values)
-
-
-class Emitter:
-    # fmt: off
-    DEFAULT_TAG_PREFIXES = {
-        '!': '!',
-        'tag:yaml.org,2002:': '!!',
-        '!!': '!!',
-    }
-    # fmt: on
-
-    MAX_SIMPLE_KEY_LENGTH = 128
-    flow_seq_start = '['
-    flow_seq_end = ']'
-    flow_seq_separator = ','
-    flow_map_start = '{'
-    flow_map_end = '}'
-    flow_map_separator = ','
-
-    def __init__(
-        self,
-        stream: StreamType,
-        canonical: Any = None,
-        indent: Optional[int] = None,
-        width: Optional[int] = None,
-        allow_unicode: Optional[bool] = None,
-        line_break: Any = None,
-        block_seq_indent: Optional[int] = None,
-        top_level_colon_align: Optional[bool] = None,
-        prefix_colon: Any = None,
-        brace_single_entry_mapping_in_flow_sequence: Optional[bool] = None,
-        dumper: Any = None,
-    ) -> None:
-        # NOQA
-        self.dumper = dumper
-        if self.dumper is not None and getattr(self.dumper, '_emitter', None) is None:
-            self.dumper._emitter = self
-        self.stream = stream
-
-        # Encoding can be overriden by STREAM-START.
-        self.encoding: Optional[Text] = None
-        self.allow_space_break = None
-
-        # Emitter is a state machine with a stack of states to handle nested
-        # structures.
-        self.states: List[Any] = []
-        self.state: Any = self.expect_stream_start
-
-        # Current event and the event queue.
-        self.events: List[Any] = []
-        self.event: Any = None
-
-        # The current indentation level and the stack of previous indents.
-        self.indents = Indents()
-        self.indent: Optional[int] = None
-
-        # flow_context is an expanding/shrinking list consisting of '{' and '['
-        # for each unclosed flow context. If empty list that means block context
-        self.flow_context: List[Text] = []
-
-        # Contexts.
-        self.root_context = False
-        self.sequence_context = False
-        self.mapping_context = False
-        self.simple_key_context = False
-
-        # Characteristics of the last emitted character:
-        #  - current position.
-        #  - is it a whitespace?
-        #  - is it an indention character
-        #    (indentation space, '-', '?', or ':')?
-        self.line = 0
-        self.column = 0
-        self.whitespace = True
-        self.indention = True
-        self.compact_seq_seq = True  # dash after dash
-        self.compact_seq_map = True  # key after dash
-        # self.compact_ms = False   # dash after key, only when excplicit key with ?
-        self.no_newline: Optional[bool] = None  # set if directly after `- `
-
-        # Whether the document requires an explicit document end indicator
-        self.open_ended = False
-
-        # colon handling
-        self.colon = ':'
-        self.prefixed_colon = self.colon if prefix_colon is None else prefix_colon + self.colon
-        # single entry mappings in flow sequence
-        self.brace_single_entry_mapping_in_flow_sequence = (
-            brace_single_entry_mapping_in_flow_sequence  # NOQA
-        )
-
-        # Formatting details.
-        self.canonical = canonical
-        self.allow_unicode = allow_unicode
-        # set to False to get "\Uxxxxxxxx" for non-basic unicode like emojis
-        self.unicode_supplementary = sys.maxunicode > 0xFFFF
-        self.sequence_dash_offset = block_seq_indent if block_seq_indent else 0
-        self.top_level_colon_align = top_level_colon_align
-        self.best_sequence_indent = 2
-        self.requested_indent = indent  # specific for literal zero indent
-        if indent and 1 < indent < 10:
-            self.best_sequence_indent = indent
-        self.best_map_indent = self.best_sequence_indent
-        # if self.best_sequence_indent < self.sequence_dash_offset + 1:
-        #     self.best_sequence_indent = self.sequence_dash_offset + 1
-        self.best_width = 80
-        if width and width > self.best_sequence_indent * 2:
-            self.best_width = width
-        self.best_line_break: Any = '\n'
-        if line_break in ['\r', '\n', '\r\n']:
-            self.best_line_break = line_break
-
-        # Tag prefixes.
-        self.tag_prefixes: Any = None
-
-        # Prepared anchor and tag.
-        self.prepared_anchor: Any = None
-        self.prepared_tag: Any = None
-
-        # Scalar analysis and style.
-        self.analysis: Any = None
-        self.style: Any = None
-
-        self.scalar_after_indicator = True  # write a scalar on the same line as `---`
-
-        self.alt_null = 'null'
-
-    @property
-    def stream(self) -> Any:
-        try:
-            return self._stream
-        except AttributeError:
-            raise YAMLStreamError('output stream needs to be specified')
-
-    @stream.setter
-    def stream(self, val: Any) -> None:
-        if val is None:
-            return
-        if not hasattr(val, 'write'):
-            raise YAMLStreamError('stream argument needs to have a write() method')
-        self._stream = val
-
-    @property
-    def serializer(self) -> Any:
-        try:
-            if hasattr(self.dumper, 'typ'):
-                return self.dumper.serializer
-            return self.dumper._serializer
-        except AttributeError:
-            return self  # cyaml
-
-    @property
-    def flow_level(self) -> int:
-        return len(self.flow_context)
-
-    def dispose(self) -> None:
-        # Reset the state attributes (to clear self-references)
-        self.states = []
-        self.state = None
-
-    def emit(self, event: Any) -> None:
-        if dbg(DBG_EVENT):
-            nprint(event)
-        self.events.append(event)
-        while not self.need_more_events():
-            self.event = self.events.pop(0)
-            self.state()
-            self.event = None
-
-    # In some cases, we wait for a few next events before emitting.
-
-    def need_more_events(self) -> bool:
-        if not self.events:
-            return True
-        event = self.events[0]
-        if isinstance(event, DocumentStartEvent):
-            return self.need_events(1)
-        elif isinstance(event, SequenceStartEvent):
-            return self.need_events(2)
-        elif isinstance(event, MappingStartEvent):
-            return self.need_events(3)
-        else:
-            return False
-
-    def need_events(self, count: int) -> bool:
-        level = 0
-        for event in self.events[1:]:
-            if isinstance(event, (DocumentStartEvent, CollectionStartEvent)):
-                level += 1
-            elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)):
-                level -= 1
-            elif isinstance(event, StreamEndEvent):
-                level = -1
-            if level < 0:
-                return False
-        return len(self.events) < count + 1
-
-    def increase_indent(
-        self, flow: bool = False, sequence: Optional[bool] = None, indentless: bool = False,
-    ) -> None:
-        self.indents.append(self.indent, sequence)
-        if self.indent is None:  # top level
-            if flow:
-                # self.indent = self.best_sequence_indent if self.indents.last_seq() else \
-                #              self.best_map_indent
-                # self.indent = self.best_sequence_indent
-                self.indent = self.requested_indent
-            else:
-                self.indent = 0
-        elif not indentless:
-            self.indent += (
-                self.best_sequence_indent if self.indents.last_seq() else self.best_map_indent
-            )
-            # if self.indents.last_seq():
-            #     if self.indent == 0: # top level block sequence
-            #         self.indent = self.best_sequence_indent - self.sequence_dash_offset
-            #     else:
-            #         self.indent += self.best_sequence_indent
-            # else:
-            #     self.indent += self.best_map_indent
-
-    # States.
-
-    # Stream handlers.
-
-    def expect_stream_start(self) -> None:
-        if isinstance(self.event, StreamStartEvent):
-            if self.event.encoding and not hasattr(self.stream, 'encoding'):
-                self.encoding = self.event.encoding
-            self.write_stream_start()
-            self.state = self.expect_first_document_start
-        else:
-            raise EmitterError(f'expected StreamStartEvent, but got {self.event!s}')
-
-    def expect_nothing(self) -> None:
-        raise EmitterError(f'expected nothing, but got {self.event!s}')
-
-    # Document handlers.
-
-    def expect_first_document_start(self) -> Any:
-        return self.expect_document_start(first=True)
-
-    def expect_document_start(self, first: bool = False) -> None:
-        if isinstance(self.event, DocumentStartEvent):
-            if (self.event.version or self.event.tags) and self.open_ended:
-                self.write_indicator('...', True)
-                self.write_indent()
-            if self.event.version:
-                version_text = self.prepare_version(self.event.version)
-                self.write_version_directive(version_text)
-            self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy()
-            if self.event.tags:
-                handles = sorted(self.event.tags.keys())
-                for handle in handles:
-                    prefix = self.event.tags[handle]
-                    self.tag_prefixes[prefix] = handle
-                    handle_text = self.prepare_tag_handle(handle)
-                    prefix_text = self.prepare_tag_prefix(prefix)
-                    self.write_tag_directive(handle_text, prefix_text)
-            implicit = (
-                first
-                and not self.event.explicit
-                and not self.canonical
-                and not self.event.version
-                and not self.event.tags
-                and not self.check_empty_document()
-            )
-            if not implicit:
-                self.write_indent()
-                self.write_indicator('---', True)
-                if self.canonical:
-                    self.write_indent()
-            self.state = self.expect_document_root
-        elif isinstance(self.event, StreamEndEvent):
-            if self.open_ended:
-                self.write_indicator('...', True)
-                self.write_indent()
-            self.write_stream_end()
-            self.state = self.expect_nothing
-        else:
-            raise EmitterError(f'expected DocumentStartEvent, but got {self.event!s}')
-
-    def expect_document_end(self) -> None:
-        if isinstance(self.event, DocumentEndEvent):
-            self.write_indent()
-            if self.event.explicit:
-                self.write_indicator('...', True)
-                self.write_indent()
-            self.flush_stream()
-            self.state = self.expect_document_start
-        else:
-            raise EmitterError(f'expected DocumentEndEvent, but got {self.event!s}')
-
-    def expect_document_root(self) -> None:
-        self.states.append(self.expect_document_end)
-        self.expect_node(root=True)
-
-    # Node handlers.
-
-    def expect_node(
-        self,
-        root: bool = False,
-        sequence: bool = False,
-        mapping: bool = False,
-        simple_key: bool = False,
-    ) -> None:
-        self.root_context = root
-        self.sequence_context = sequence  # not used in PyYAML
-        force_flow_indent = False
-        self.mapping_context = mapping
-        self.simple_key_context = simple_key
-        if isinstance(self.event, AliasEvent):
-            self.expect_alias()
-        elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)):
-            if (
-                self.process_anchor('&')
-                and isinstance(self.event, ScalarEvent)
-                and self.sequence_context
-            ):
-                self.sequence_context = False
-            if (
-                root
-                and isinstance(self.event, ScalarEvent)
-                and not self.scalar_after_indicator
-            ):
-                self.write_indent()
-            self.process_tag()
-            if isinstance(self.event, ScalarEvent):
-                # nprint('@', self.indention, self.no_newline, self.column)
-                self.expect_scalar()
-            elif isinstance(self.event, SequenceStartEvent):
-                i2, n2 = self.indention, self.no_newline  # NOQA
-                if self.event.comment:
-                    if self.event.flow_style is False:
-                        if self.write_post_comment(self.event):
-                            self.indention = False
-                            self.no_newline = True
-                    if self.event.flow_style:
-                        column = self.column
-                    if self.write_pre_comment(self.event):
-                        if self.event.flow_style:
-                            # force_flow_indent = True
-                            force_flow_indent = not self.indents.values[-1][1]
-                        self.indention = i2
-                        self.no_newline = not self.indention
-                    if self.event.flow_style:
-                        self.column = column
-                if (
-                    self.flow_level
-                    or self.canonical
-                    or self.event.flow_style
-                    or self.check_empty_sequence()
-                ):
-                    self.expect_flow_sequence(force_flow_indent)
-                else:
-                    self.expect_block_sequence()
-                if self.indents.seq_seq():
-                    # - -
-                    self.indention = True
-                    self.no_newline = False
-            elif isinstance(self.event, MappingStartEvent):
-                if self.event.flow_style is False and self.event.comment:
-                    self.write_post_comment(self.event)
-                if self.event.comment and self.event.comment[1]:
-                    self.write_pre_comment(self.event)
-                    if self.event.flow_style and self.indents.values:
-                        force_flow_indent = not self.indents.values[-1][1]
-                if (
-                    self.flow_level
-                    or self.canonical
-                    or self.event.flow_style
-                    or self.check_empty_mapping()
-                ):
-                    self.expect_flow_mapping(
-                        single=self.event.nr_items == 1, force_flow_indent=force_flow_indent,
-                    )
-                else:
-                    self.expect_block_mapping()
-        else:
-            raise EmitterError(f'expected NodeEvent, but got {self.event!s}')
-
-    def expect_alias(self) -> None:
-        if self.event.anchor is None:
-            raise EmitterError('anchor is not specified for alias')
-        self.process_anchor('*')
-        self.state = self.states.pop()
-
-    def expect_scalar(self) -> None:
-        self.increase_indent(flow=True)
-        self.process_scalar()
-        self.indent = self.indents.pop()
-        self.state = self.states.pop()
-
-    # Flow sequence handlers.
-
-    def expect_flow_sequence(self, force_flow_indent: Optional[bool] = False) -> None:
-        if force_flow_indent:
-            self.increase_indent(flow=True, sequence=True)
-        ind = self.indents.seq_flow_align(
-            self.best_sequence_indent, self.column, force_flow_indent,
-        )
-        self.write_indicator(' ' * ind + self.flow_seq_start, True, whitespace=True)
-        if not force_flow_indent:
-            self.increase_indent(flow=True, sequence=True)
-        self.flow_context.append('[')
-        self.state = self.expect_first_flow_sequence_item
-
-    def expect_first_flow_sequence_item(self) -> None:
-        if isinstance(self.event, SequenceEndEvent):
-            self.indent = self.indents.pop()
-            popped = self.flow_context.pop()
-            assert popped == '['
-            self.write_indicator(self.flow_seq_end, False)
-            if self.event.comment and self.event.comment[0]:
-                # eol comment on empty flow sequence
-                self.write_post_comment(self.event)
-            elif self.flow_level == 0:
-                self.write_line_break()
-            self.state = self.states.pop()
-        else:
-            if self.canonical or self.column > self.best_width:
-                self.write_indent()
-            self.states.append(self.expect_flow_sequence_item)
-            self.expect_node(sequence=True)
-
-    def expect_flow_sequence_item(self) -> None:
-        if isinstance(self.event, SequenceEndEvent):
-            self.indent = self.indents.pop()
-            popped = self.flow_context.pop()
-            assert popped == '['
-            if self.canonical:
-                # ToDo: so-39595807, maybe add a space to the flow_seq_separator
-                # and strip the last space, if space then indent, else do not
-                # not sure that [1,2,3] is a valid YAML seq
-                self.write_indicator(self.flow_seq_separator, False)
-                self.write_indent()
-            self.write_indicator(self.flow_seq_end, False)
-            if self.event.comment and self.event.comment[0]:
-                # eol comment on flow sequence
-                self.write_post_comment(self.event)
-            else:
-                self.no_newline = False
-            self.state = self.states.pop()
-        else:
-            self.write_indicator(self.flow_seq_separator, False)
-            if self.canonical or self.column > self.best_width:
-                self.write_indent()
-            self.states.append(self.expect_flow_sequence_item)
-            self.expect_node(sequence=True)
-
-    # Flow mapping handlers.
-
-    def expect_flow_mapping(
-        self, single: Optional[bool] = False, force_flow_indent: Optional[bool] = False,
-    ) -> None:
-        if force_flow_indent:
-            self.increase_indent(flow=True, sequence=False)
-        ind = self.indents.seq_flow_align(
-            self.best_sequence_indent, self.column, force_flow_indent,
-        )
-        map_init = self.flow_map_start
-        if (
-            single
-            and self.flow_level
-            and self.flow_context[-1] == '['
-            and not self.canonical
-            and not self.brace_single_entry_mapping_in_flow_sequence
-        ):
-            # single map item with flow context, no curly braces necessary
-            map_init = ''
-        self.write_indicator(' ' * ind + map_init, True, whitespace=True)
-        self.flow_context.append(map_init)
-        if not force_flow_indent:
-            self.increase_indent(flow=True, sequence=False)
-        self.state = self.expect_first_flow_mapping_key
-
-    def expect_first_flow_mapping_key(self) -> None:
-        if isinstance(self.event, MappingEndEvent):
-            self.indent = self.indents.pop()
-            popped = self.flow_context.pop()
-            assert popped == '{'  # empty flow mapping
-            self.write_indicator(self.flow_map_end, False)
-            if self.event.comment and self.event.comment[0]:
-                # eol comment on empty mapping
-                self.write_post_comment(self.event)
-            elif self.flow_level == 0:
-                self.write_line_break()
-            self.state = self.states.pop()
-        else:
-            if self.canonical or self.column > self.best_width:
-                self.write_indent()
-            if not self.canonical and self.check_simple_key():
-                self.states.append(self.expect_flow_mapping_simple_value)
-                self.expect_node(mapping=True, simple_key=True)
-            else:
-                self.write_indicator('?', True)
-                self.states.append(self.expect_flow_mapping_value)
-                self.expect_node(mapping=True)
-
-    def expect_flow_mapping_key(self) -> None:
-        if isinstance(self.event, MappingEndEvent):
-            # if self.event.comment and self.event.comment[1]:
-            #     self.write_pre_comment(self.event)
-            self.indent = self.indents.pop()
-            popped = self.flow_context.pop()
-            assert popped in ['{', '']
-            if self.canonical:
-                self.write_indicator(self.flow_map_separator, False)
-                self.write_indent()
-            if popped != '':
-                self.write_indicator(self.flow_map_end, False)
-            if self.event.comment and self.event.comment[0]:
-                # eol comment on flow mapping, never reached on empty mappings
-                self.write_post_comment(self.event)
-            else:
-                self.no_newline = False
-            self.state = self.states.pop()
-        else:
-            self.write_indicator(self.flow_map_separator, False)
-            if self.canonical or self.column > self.best_width:
-                self.write_indent()
-            if not self.canonical and self.check_simple_key():
-                self.states.append(self.expect_flow_mapping_simple_value)
-                self.expect_node(mapping=True, simple_key=True)
-            else:
-                self.write_indicator('?', True)
-                self.states.append(self.expect_flow_mapping_value)
-                self.expect_node(mapping=True)
-
-    def expect_flow_mapping_simple_value(self) -> None:
-        if getattr(self.event, 'style', '?') != '-':  # suppress for flow style sets
-            self.write_indicator(self.prefixed_colon, False)
-        self.states.append(self.expect_flow_mapping_key)
-        self.expect_node(mapping=True)
-
-    def expect_flow_mapping_value(self) -> None:
-        if self.canonical or self.column > self.best_width:
-            self.write_indent()
-        self.write_indicator(self.prefixed_colon, True)
-        self.states.append(self.expect_flow_mapping_key)
-        self.expect_node(mapping=True)
-
-    # Block sequence handlers.
-
-    def expect_block_sequence(self) -> None:
-        if self.mapping_context:
-            indentless = not self.indention
-        else:
-            indentless = False
-            if not self.compact_seq_seq and self.column != 0:
-                self.write_line_break()
-        self.increase_indent(flow=False, sequence=True, indentless=indentless)
-        self.state = self.expect_first_block_sequence_item
-
-    def expect_first_block_sequence_item(self) -> Any:
-        return self.expect_block_sequence_item(first=True)
-
-    def expect_block_sequence_item(self, first: bool = False) -> None:
-        if not first and isinstance(self.event, SequenceEndEvent):
-            if self.event.comment and self.event.comment[1]:
-                # final comments on a block list e.g. empty line
-                self.write_pre_comment(self.event)
-            self.indent = self.indents.pop()
-            self.state = self.states.pop()
-            self.no_newline = False
-        else:
-            if self.event.comment and self.event.comment[1]:
-                self.write_pre_comment(self.event)
-            nonl = self.no_newline if self.column == 0 else False
-            self.write_indent()
-            ind = self.sequence_dash_offset  # if  len(self.indents) > 1 else 0
-            self.write_indicator(' ' * ind + '-', True, indention=True)
-            if nonl or self.sequence_dash_offset + 2 > self.best_sequence_indent:
-                self.no_newline = True
-            self.states.append(self.expect_block_sequence_item)
-            self.expect_node(sequence=True)
-
-    # Block mapping handlers.
-
-    def expect_block_mapping(self) -> None:
-        if not self.mapping_context and not (self.compact_seq_map or self.column == 0):
-            self.write_line_break()
-        self.increase_indent(flow=False, sequence=False)
-        self.state = self.expect_first_block_mapping_key
-
-    def expect_first_block_mapping_key(self) -> None:
-        return self.expect_block_mapping_key(first=True)
-
-    def expect_block_mapping_key(self, first: Any = False) -> None:
-        if not first and isinstance(self.event, MappingEndEvent):
-            if self.event.comment and self.event.comment[1]:
-                # final comments from a doc
-                self.write_pre_comment(self.event)
-            self.indent = self.indents.pop()
-            self.state = self.states.pop()
-        else:
-            if self.event.comment and self.event.comment[1]:
-                # final comments from a doc
-                self.write_pre_comment(self.event)
-            self.write_indent()
-            if self.check_simple_key():
-                if not isinstance(
-                    self.event, (SequenceStartEvent, MappingStartEvent),
-                ):  # sequence keys
-                    try:
-                        if self.event.style == '?':
-                            self.write_indicator('?', True, indention=True)
-                    except AttributeError:  # aliases have no style
-                        pass
-                self.states.append(self.expect_block_mapping_simple_value)
-                self.expect_node(mapping=True, simple_key=True)
-                # test on style for alias in !!set
-                if isinstance(self.event, AliasEvent) and not self.event.style == '?':
-                    self.stream.write(' ')
-            else:
-                self.write_indicator('?', True, indention=True)
-                self.states.append(self.expect_block_mapping_value)
-                self.expect_node(mapping=True)
-
-    def expect_block_mapping_simple_value(self) -> None:
-        if getattr(self.event, 'style', None) != '?':
-            # prefix = ''
-            if self.indent == 0 and self.top_level_colon_align is not None:
-                # write non-prefixed colon
-                c = ' ' * (self.top_level_colon_align - self.column) + self.colon
-            else:
-                c = self.prefixed_colon
-            self.write_indicator(c, False)
-        self.states.append(self.expect_block_mapping_key)
-        self.expect_node(mapping=True)
-
-    def expect_block_mapping_value(self) -> None:
-        self.write_indent()
-        self.write_indicator(self.prefixed_colon, True, indention=True)
-        self.states.append(self.expect_block_mapping_key)
-        self.expect_node(mapping=True)
-
-    # Checkers.
-
-    def check_empty_sequence(self) -> bool:
-        return (
-            isinstance(self.event, SequenceStartEvent)
-            and bool(self.events)
-            and isinstance(self.events[0], SequenceEndEvent)
-        )
-
-    def check_empty_mapping(self) -> bool:
-        return (
-            isinstance(self.event, MappingStartEvent)
-            and bool(self.events)
-            and isinstance(self.events[0], MappingEndEvent)
-        )
-
-    def check_empty_document(self) -> bool:
-        if not isinstance(self.event, DocumentStartEvent) or not self.events:
-            return False
-        event = self.events[0]
-        return (
-            isinstance(event, ScalarEvent)
-            and event.anchor is None
-            and event.tag is None
-            and event.implicit
-            and event.value == ""
-        )
-
-    def check_simple_key(self) -> bool:
-        length = 0
-        if isinstance(self.event, NodeEvent) and self.event.anchor is not None:
-            if self.prepared_anchor is None:
-                self.prepared_anchor = self.prepare_anchor(self.event.anchor)
-            length += len(self.prepared_anchor)
-        if (
-            isinstance(self.event, (ScalarEvent, CollectionStartEvent))
-            and self.event.tag is not None
-        ):
-            if self.prepared_tag is None:
-                self.prepared_tag = self.prepare_tag(self.event.ctag)
-            length += len(self.prepared_tag)
-        if isinstance(self.event, ScalarEvent):
-            if self.analysis is None:
-                self.analysis = self.analyze_scalar(self.event.value)
-            length += len(self.analysis.scalar)
-        return length < self.MAX_SIMPLE_KEY_LENGTH and (
-            isinstance(self.event, AliasEvent)
-            or (isinstance(self.event, SequenceStartEvent) and self.event.flow_style is True)
-            or (isinstance(self.event, MappingStartEvent) and self.event.flow_style is True)
-            or (
-                isinstance(self.event, ScalarEvent)
-                # if there is an explicit style for an empty string, it is a simple key
-                and not (self.analysis.empty and self.style and self.style not in '\'"')
-                and not self.analysis.multiline
-            )
-            or self.check_empty_sequence()
-            or self.check_empty_mapping()
-        )
-
-    # Anchor, Tag, and Scalar processors.
-
-    def process_anchor(self, indicator: Any) -> bool:
-        if self.event.anchor is None:
-            self.prepared_anchor = None
-            return False
-        if self.prepared_anchor is None:
-            self.prepared_anchor = self.prepare_anchor(self.event.anchor)
-        if self.prepared_anchor:
-            self.write_indicator(indicator + self.prepared_anchor, True)
-            # issue 288
-            self.no_newline = False
-        self.prepared_anchor = None
-        return True
-
-    def process_tag(self) -> None:
-        tag = self.event.tag
-        if isinstance(self.event, ScalarEvent):
-            if self.style is None:
-                self.style = self.choose_scalar_style()
-                if (
-                    self.event.value == ''
-                    and self.style == "'"
-                    and tag == 'tag:yaml.org,2002:null'
-                    and self.alt_null is not None
-                ):
-                    self.event.value = self.alt_null
-                    self.analysis = None
-                    self.style = self.choose_scalar_style()
-            if (not self.canonical or tag is None) and (
-                (self.style == "" and self.event.implicit[0])
-                or (self.style != "" and self.event.implicit[1])
-            ):
-                self.prepared_tag = None
-                return
-            if self.event.implicit[0] and tag is None:
-                tag = '!'
-                self.prepared_tag = None
-        else:
-            if (not self.canonical or tag is None) and self.event.implicit:
-                self.prepared_tag = None
-                return
-        if tag is None:
-            raise EmitterError('tag is not specified')
-        if self.prepared_tag is None:
-            self.prepared_tag = self.prepare_tag(self.event.ctag)
-        if self.prepared_tag:
-            self.write_indicator(self.prepared_tag, True)
-            if (
-                self.sequence_context
-                and not self.flow_level
-                and isinstance(self.event, ScalarEvent)
-            ):
-                self.no_newline = True
-        self.prepared_tag = None
-
-    def choose_scalar_style(self) -> Any:
-        # issue 449 needs this otherwise emits single quoted empty string
-        if self.event.value == '' and self.event.ctag.handle == '!!':
-            return None
-        if self.analysis is None:
-            self.analysis = self.analyze_scalar(self.event.value)
-        if self.event.style == '"' or self.canonical:
-            return '"'
-        if (not self.event.style or self.event.style == '?' or self.event.style == '-') and (
-            self.event.implicit[0] or not self.event.implicit[2]
-        ):
-            if not (
-                self.simple_key_context and (self.analysis.empty or self.analysis.multiline)
-            ) and (
-                self.flow_level
-                and self.analysis.allow_flow_plain
-                or (not self.flow_level and self.analysis.allow_block_plain)
-            ):
-                return ""
-            if self.event.style == '-':
-                return ""
-        self.analysis.allow_block = True
-        if self.event.style and self.event.style in '|>':
-            if (
-                not self.flow_level
-                and not self.simple_key_context
-                and self.analysis.allow_block
-            ):
-                return self.event.style
-        if not self.event.style and self.analysis.allow_double_quoted:
-            if "'" in self.event.value or '\n' in self.event.value:
-                return '"'
-        if not self.event.style or self.event.style == "'":
-            if self.analysis.allow_single_quoted and not (
-                self.simple_key_context and self.analysis.multiline
-            ):
-                return "'"
-        return '"'
-
-    def process_scalar(self) -> None:
-        if self.analysis is None:
-            self.analysis = self.analyze_scalar(self.event.value)
-        if self.style is None:
-            self.style = self.choose_scalar_style()
-        split = not self.simple_key_context
-        # if self.analysis.multiline and split    \
-        #         and (not self.style or self.style in '\'\"'):
-        #     self.write_indent()
-        # nprint('xx', self.sequence_context, self.flow_level)
-        if self.sequence_context and not self.flow_level:
-            self.write_indent()
-        if self.style == '"':
-            self.write_double_quoted(self.analysis.scalar, split)
-        elif self.style == "'":
-            self.write_single_quoted(self.analysis.scalar, split)
-        elif self.style == '>':
-            try:
-                cmx = self.event.comment[1][0]
-            except (IndexError, TypeError) as e:  # NOQA
-                cmx = ""
-            self.write_folded(self.analysis.scalar, cmx)
-            if (
-                self.event.comment
-                and self.event.comment[0]
-                and self.event.comment[0].column >= self.indent
-            ):
-                # comment following a folded scalar must dedent (issue 376)
-                self.event.comment[0].column = self.indent - 1  # type: ignore
-        elif self.style == '|':
-            # self.write_literal(self.analysis.scalar, self.event.comment)
-            try:
-                cmx = self.event.comment[1][0]
-            except (IndexError, TypeError):
-                cmx = ""
-            self.write_literal(self.analysis.scalar, cmx)
-            if (
-                self.event.comment
-                and self.event.comment[0]
-                and self.event.comment[0].column >= self.indent
-            ):
-                # comment following a literal scalar must dedent (issue 376)
-                self.event.comment[0].column = self.indent - 1  # type: ignore
-        else:
-            self.write_plain(self.analysis.scalar, split)
-        self.analysis = None
-        self.style = None
-        if self.event.comment:
-            self.write_post_comment(self.event)
-
-    # Analyzers.
-
-    def prepare_version(self, version: Any) -> Any:
-        major, minor = version
-        if major != 1:
-            raise EmitterError(f'unsupported YAML version: {major:d}.{minor:d}')
-        return f'{major:d}.{minor:d}'
-
-    def prepare_tag_handle(self, handle: Any) -> Any:
-        if not handle:
-            raise EmitterError('tag handle must not be empty')
-        if handle[0] != '!' or handle[-1] != '!':
-            raise EmitterError(f"tag handle must start and end with '!': {handle!r}")
-        for ch in handle[1:-1]:
-            if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in '-_'):
-                raise EmitterError(f'invalid character {ch!r} in the tag handle: {handle!r}')
-        return handle
-
-    def prepare_tag_prefix(self, prefix: Any) -> Any:
-        if not prefix:
-            raise EmitterError('tag prefix must not be empty')
-        chunks: List[Any] = []
-        start = end = 0
-        if prefix[0] == '!':
-            end = 1
-        ch_set = "-;/?:@&=+$,_.~*'()[]"
-        if self.dumper:
-            version = getattr(self.dumper, 'version', (1, 2))
-            if version is None or version >= (1, 2):
-                ch_set += '#'
-        while end < len(prefix):
-            ch = prefix[end]
-            if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in ch_set:
-                end += 1
-            else:
-                if start < end:
-                    chunks.append(prefix[start:end])
-                start = end = end + 1
-                data = ch
-                for ch in data:
-                    chunks.append(f'%{ord(ch):02X}')
-        if start < end:
-            chunks.append(prefix[start:end])
-        return "".join(chunks)
-
-    def prepare_tag(self, tag: Any) -> Any:
-        if not tag:
-            raise EmitterError('tag must not be empty')
-        tag = str(tag)
-        if tag == '!' or tag == '!!':
-            return tag
-        handle = None
-        suffix = tag
-        prefixes = sorted(self.tag_prefixes.keys())
-        for prefix in prefixes:
-            if tag.startswith(prefix) and (prefix == '!' or len(prefix) < len(tag)):
-                handle = self.tag_prefixes[prefix]
-                suffix = tag[len(prefix) :]
-        chunks: List[Any] = []
-        start = end = 0
-        ch_set = "-;/?:@&=+$,_.~*'()[]"
-        if self.dumper:
-            version = getattr(self.dumper, 'version', (1, 2))
-            if version is None or version >= (1, 2):
-                ch_set += '#'
-        while end < len(suffix):
-            ch = suffix[end]
-            if (
-                '0' <= ch <= '9'
-                or 'A' <= ch <= 'Z'
-                or 'a' <= ch <= 'z'
-                or ch in ch_set
-                or (ch == '!' and handle != '!')
-            ):
-                end += 1
-            else:
-                if start < end:
-                    chunks.append(suffix[start:end])
-                start = end = end + 1
-                data = ch
-                for ch in data:
-                    chunks.append(f'%{ord(ch):02X}')
-        if start < end:
-            chunks.append(suffix[start:end])
-        suffix_text = "".join(chunks)
-        if handle:
-            return f'{handle!s}{suffix_text!s}'
-        else:
-            return f'!<{suffix_text!s}>'
-
-    def prepare_anchor(self, anchor: Any) -> Any:
-        if not anchor:
-            raise EmitterError('anchor must not be empty')
-        for ch in anchor:
-            if not check_anchorname_char(ch):
-                raise EmitterError(f'invalid character {ch!r} in the anchor: {anchor!r}')
-        return anchor
-
-    def analyze_scalar(self, scalar: Any) -> Any:
-        # Empty scalar is a special case.
-        if not scalar:
-            return ScalarAnalysis(
-                scalar=scalar,
-                empty=True,
-                multiline=False,
-                allow_flow_plain=False,
-                allow_block_plain=True,
-                allow_single_quoted=True,
-                allow_double_quoted=True,
-                allow_block=False,
-            )
-
-        # Indicators and special characters.
-        block_indicators = False
-        flow_indicators = False
-        line_breaks = False
-        special_characters = False
-
-        # Important whitespace combinations.
-        leading_space = False
-        leading_break = False
-        trailing_space = False
-        trailing_break = False
-        break_space = False
-        space_break = False
-
-        # Check document indicators.
-        if scalar.startswith('---') or scalar.startswith('...'):
-            block_indicators = True
-            flow_indicators = True
-
-        # First character or preceded by a whitespace.
-        preceeded_by_whitespace = True
-
-        # Last character or followed by a whitespace.
-        followed_by_whitespace = len(scalar) == 1 or scalar[1] in '\0 \t\r\n\x85\u2028\u2029'
-
-        # The previous character is a space.
-        previous_space = False
-
-        # The previous character is a break.
-        previous_break = False
-
-        index = 0
-        while index < len(scalar):
-            ch = scalar[index]
-
-            # Check for indicators.
-            if index == 0:
-                # Leading indicators are special characters.
-                if ch in '#,[]{}&*!|>\'"%@`':
-                    flow_indicators = True
-                    block_indicators = True
-                if ch in '?:':  # ToDo
-                    if self.serializer.use_version == (1, 1):
-                        flow_indicators = True
-                    elif len(scalar) == 1:  # single character
-                        flow_indicators = True
-                    if followed_by_whitespace:
-                        block_indicators = True
-                if ch == '-' and followed_by_whitespace:
-                    flow_indicators = True
-                    block_indicators = True
-            else:
-                # Some indicators cannot appear within a scalar as well.
-                if ch in ',[]{}':  # http://yaml.org/spec/1.2/spec.html#id2788859
-                    flow_indicators = True
-                if ch == '?' and self.serializer.use_version == (1, 1):
-                    flow_indicators = True
-                if ch == ':':
-                    if followed_by_whitespace:
-                        flow_indicators = True
-                        block_indicators = True
-                if ch == '#' and preceeded_by_whitespace:
-                    flow_indicators = True
-                    block_indicators = True
-
-            # Check for line breaks, special, and unicode characters.
-            if ch in '\n\x85\u2028\u2029':
-                line_breaks = True
-            if not (ch == '\n' or '\x20' <= ch <= '\x7E'):
-                if (
-                    ch == '\x85'
-                    or '\xA0' <= ch <= '\uD7FF'
-                    or '\uE000' <= ch <= '\uFFFD'
-                    or (self.unicode_supplementary and ('\U00010000' <= ch <= '\U0010FFFF'))
-                ) and ch != '\uFEFF':
-                    # unicode_characters = True
-                    if not self.allow_unicode:
-                        special_characters = True
-                else:
-                    special_characters = True
-
-            # Detect important whitespace combinations.
-            if ch == ' ':
-                if index == 0:
-                    leading_space = True
-                if index == len(scalar) - 1:
-                    trailing_space = True
-                if previous_break:
-                    break_space = True
-                previous_space = True
-                previous_break = False
-            elif ch in '\n\x85\u2028\u2029':
-                if index == 0:
-                    leading_break = True
-                if index == len(scalar) - 1:
-                    trailing_break = True
-                if previous_space:
-                    space_break = True
-                previous_space = False
-                previous_break = True
-            else:
-                previous_space = False
-                previous_break = False
-
-            # Prepare for the next character.
-            index += 1
-            preceeded_by_whitespace = ch in '\0 \t\r\n\x85\u2028\u2029'
-            followed_by_whitespace = (
-                index + 1 >= len(scalar) or scalar[index + 1] in '\0 \t\r\n\x85\u2028\u2029'
-            )
-
-        # Let's decide what styles are allowed.
-        allow_flow_plain = True
-        allow_block_plain = True
-        allow_single_quoted = True
-        allow_double_quoted = True
-        allow_block = True
-
-        # Leading and trailing whitespaces are bad for plain scalars.
-        if leading_space or leading_break or trailing_space or trailing_break:
-            allow_flow_plain = allow_block_plain = False
-
-        # We do not permit trailing spaces for block scalars.
-        if trailing_space:
-            allow_block = False
-
-        # Spaces at the beginning of a new line are only acceptable for block
-        # scalars.
-        if break_space:
-            allow_flow_plain = allow_block_plain = allow_single_quoted = False
-
-        # Spaces followed by breaks, as well as special character are only
-        # allowed for double quoted scalars.
-        if special_characters:
-            allow_flow_plain = allow_block_plain = allow_single_quoted = allow_block = False
-        elif space_break:
-            allow_flow_plain = allow_block_plain = allow_single_quoted = False
-            if not self.allow_space_break:
-                allow_block = False
-
-        # Although the plain scalar writer supports breaks, we never emit
-        # multiline plain scalars.
-        if line_breaks:
-            allow_flow_plain = allow_block_plain = False
-
-        # Flow indicators are forbidden for flow plain scalars.
-        if flow_indicators:
-            allow_flow_plain = False
-
-        # Block indicators are forbidden for block plain scalars.
-        if block_indicators:
-            allow_block_plain = False
-
-        return ScalarAnalysis(
-            scalar=scalar,
-            empty=False,
-            multiline=line_breaks,
-            allow_flow_plain=allow_flow_plain,
-            allow_block_plain=allow_block_plain,
-            allow_single_quoted=allow_single_quoted,
-            allow_double_quoted=allow_double_quoted,
-            allow_block=allow_block,
-        )
-
-    # Writers.
-
-    def flush_stream(self) -> None:
-        if hasattr(self.stream, 'flush'):
-            self.stream.flush()
-
-    def write_stream_start(self) -> None:
-        # Write BOM if needed.
-        if self.encoding and self.encoding.startswith('utf-16'):
-            self.stream.write('\uFEFF'.encode(self.encoding))
-
-    def write_stream_end(self) -> None:
-        self.flush_stream()
-
-    def write_indicator(
-        self,
-        indicator: Any,
-        need_whitespace: Any,
-        whitespace: bool = False,
-        indention: bool = False,
-    ) -> None:
-        if self.whitespace or not need_whitespace:
-            data = indicator
-        else:
-            data = ' ' + indicator
-        self.whitespace = whitespace
-        self.indention = self.indention and indention
-        self.column += len(data)
-        self.open_ended = False
-        if bool(self.encoding):
-            data = data.encode(self.encoding)
-        self.stream.write(data)
-
-    def write_indent(self) -> None:
-        indent = self.indent or 0
-        if (
-            not self.indention
-            or self.column > indent
-            or (self.column == indent and not self.whitespace)
-        ):
-            if bool(self.no_newline):
-                self.no_newline = False
-            else:
-                self.write_line_break()
-        if self.column < indent:
-            self.whitespace = True
-            data = ' ' * (indent - self.column)
-            self.column = indent
-            if self.encoding:
-                data = data.encode(self.encoding)  # type: ignore
-            self.stream.write(data)
-
-    def write_line_break(self, data: Any = None) -> None:
-        if data is None:
-            data = self.best_line_break
-        self.whitespace = True
-        self.indention = True
-        self.line += 1
-        self.column = 0
-        if bool(self.encoding):
-            data = data.encode(self.encoding)
-        self.stream.write(data)
-
-    def write_version_directive(self, version_text: Any) -> None:
-        data: Any = f'%YAML {version_text!s}'
-        if self.encoding:
-            data = data.encode(self.encoding)
-        self.stream.write(data)
-        self.write_line_break()
-
-    def write_tag_directive(self, handle_text: Any, prefix_text: Any) -> None:
-        data: Any = f'%TAG {handle_text!s} {prefix_text!s}'
-        if self.encoding:
-            data = data.encode(self.encoding)
-        self.stream.write(data)
-        self.write_line_break()
-
-    # Scalar streams.
-
-    def write_single_quoted(self, text: Any, split: Any = True) -> None:
-        if self.root_context:
-            if self.requested_indent is not None:
-                self.write_line_break()
-                if self.requested_indent != 0:
-                    self.write_indent()
-        self.write_indicator("'", True)
-        spaces = False
-        breaks = False
-        start = end = 0
-        while end <= len(text):
-            ch = None
-            if end < len(text):
-                ch = text[end]
-            if spaces:
-                if ch is None or ch != ' ':
-                    if (
-                        start + 1 == end
-                        and self.column > self.best_width
-                        and split
-                        and start != 0
-                        and end != len(text)
-                    ):
-                        self.write_indent()
-                    else:
-                        data = text[start:end]
-                        self.column += len(data)
-                        if bool(self.encoding):
-                            data = data.encode(self.encoding)
-                        self.stream.write(data)
-                    start = end
-            elif breaks:
-                if ch is None or ch not in '\n\x85\u2028\u2029':
-                    if text[start] == '\n':
-                        self.write_line_break()
-                    for br in text[start:end]:
-                        if br == '\n':
-                            self.write_line_break()
-                        else:
-                            self.write_line_break(br)
-                    self.write_indent()
-                    start = end
-            else:
-                if ch is None or ch in ' \n\x85\u2028\u2029' or ch == "'":
-                    if start < end:
-                        data = text[start:end]
-                        self.column += len(data)
-                        if bool(self.encoding):
-                            data = data.encode(self.encoding)
-                        self.stream.write(data)
-                        start = end
-            if ch == "'":
-                data = "''"
-                self.column += 2
-                if bool(self.encoding):
-                    data = data.encode(self.encoding)
-                self.stream.write(data)
-                start = end + 1
-            if ch is not None:
-                spaces = ch == ' '
-                breaks = ch in '\n\x85\u2028\u2029'
-            end += 1
-        self.write_indicator("'", False)
-
-    ESCAPE_REPLACEMENTS = {
-        '\0': '0',
-        '\x07': 'a',
-        '\x08': 'b',
-        '\x09': 't',
-        '\x0A': 'n',
-        '\x0B': 'v',
-        '\x0C': 'f',
-        '\x0D': 'r',
-        '\x1B': 'e',
-        '"': '"',
-        '\\': '\\',
-        '\x85': 'N',
-        '\xA0': '_',
-        '\u2028': 'L',
-        '\u2029': 'P',
-    }
-
-    def write_double_quoted(self, text: Any, split: Any = True) -> None:
-        """
-        a newline, as written by self.write_indent(), might need to be escaped with a backslash
-        as on reading this will produce a possibly unwanted space.
-        """
-        if self.root_context:
-            if self.requested_indent is not None:
-                self.write_line_break()
-                if self.requested_indent != 0:
-                    self.write_indent()
-        self.write_indicator('"', True)
-        start = end = 0
-        while end <= len(text):
-            ch = None
-            if end < len(text):
-                ch = text[end]
-            if (
-                ch is None
-                or ch in '"\\\x85\u2028\u2029\uFEFF'
-                or not (
-                    '\x20' <= ch <= '\x7E'
-                    or (
-                        self.allow_unicode
-                        and (
-                            ('\xA0' <= ch <= '\uD7FF')
-                            or ('\uE000' <= ch <= '\uFFFD')
-                            or ('\U00010000' <= ch <= '\U0010FFFF')
-                        )
-                    )
-                )
-            ):
-                if start < end:
-                    data = text[start:end]
-                    self.column += len(data)
-                    if bool(self.encoding):
-                        data = data.encode(self.encoding)
-                    self.stream.write(data)
-                    start = end
-                if ch is not None:
-                    if ch in self.ESCAPE_REPLACEMENTS:
-                        data = '\\' + self.ESCAPE_REPLACEMENTS[ch]
-                    elif ch <= '\xFF':
-                        data = '\\x%02X' % ord(ch)
-                    elif ch <= '\uFFFF':
-                        data = '\\u%04X' % ord(ch)
-                    else:
-                        data = '\\U%08X' % ord(ch)
-                    self.column += len(data)
-                    if bool(self.encoding):
-                        data = data.encode(self.encoding)
-                    self.stream.write(data)
-                    start = end + 1
-            if (
-                0 < end < len(text) - 1
-                and (ch == ' ' or start >= end)
-                and self.column + (end - start) > self.best_width
-                and split
-            ):
-                # SO https://stackoverflow.com/a/75634614/1307905
-                # data = text[start:end] + u'\\'  # <<< replaced with following lines
-                need_backslash = True
-                if len(text) > end:
-                    try:
-                        space_pos = text.index(' ', end)
-                        try:
-                            space_pos = text.index('\n', end, space_pos)
-                        except (ValueError, IndexError):
-                            pass
-                        # nprint('backslash?', space_pos, repr(text[:space_pos]), repr(text[space_pos:]), (text[space_pos] == '\n' and text[space_pos+1] == ' '))  # NOQA
-                        if (text[space_pos] == '\n' and text[space_pos + 1] != ' '):
-                            pass
-                        elif (
-                            '"' not in text[end:space_pos]
-                            and "'" not in text[end:space_pos]
-                            # and text[space_pos + 1] != ' '
-                            and text[space_pos + 1] not in ' \n'
-                            and text[end - 1 : end + 1] != '  '
-                            and start != end
-                        ):
-                            need_backslash = False
-                    except (ValueError, IndexError):
-                        pass
-                data = text[start:end] + ('\\' if need_backslash else '')
-                if start < end:
-                    start = end
-                self.column += len(data)
-                if bool(self.encoding):
-                    data = data.encode(self.encoding)
-                self.stream.write(data)
-                self.write_indent()
-                self.whitespace = False
-                self.indention = False
-                if text[start] == ' ':
-                    if not need_backslash:
-                        # remove leading space it will load from the newline
-                        start += 1
-                    # data = u'\\'    # <<< replaced with following line
-                    data = '\\' if need_backslash else ''
-                    self.column += len(data)
-                    if bool(self.encoding):
-                        data = data.encode(self.encoding)
-                    self.stream.write(data)
-            end += 1
-        self.write_indicator('"', False)
-
-    def determine_block_hints(self, text: Any) -> Any:
-        indent = 0
-        indicator = ''
-        hints = ''
-        if text:
-            if text[0] in ' \n\x85\u2028\u2029':
-                indent = 2
-                hints += str(indent)
-            elif self.root_context:
-                for end in ['---', '...']:
-                    position = -1
-                    pos = 0
-                    while position == -1:
-                        pos = text.find(end, pos)
-                        if pos == -1:
-                            break
-                        if pos != 0:
-                            if text[pos - 1] != '\n':
-                                pos += 1
-                                continue
-                        try:
-                            if text[pos + len(end)] in ' \r\n':
-                                position = pos
-                                break
-                        except IndexError:
-                            pass
-                        pos += 1
-                    if position != -1:
-                        break
-                if position != -1:
-                    indent = 2
-            if text[-1] not in '\n\x85\u2028\u2029':
-                indicator = '-'
-            elif len(text) == 1 or text[-2] in '\n\x85\u2028\u2029':
-                indicator = '+'
-        hints += indicator
-        return hints, indent, indicator
-
-    def write_folded(self, text: Any, comment: Any) -> None:
-        hints, _indent, _indicator = self.determine_block_hints(text)
-        if not isinstance(comment, str):
-            comment = ''
-        self.write_indicator('>' + hints + comment, True)
-        if _indicator == '+':
-            self.open_ended = True
-        self.write_line_break()
-        leading_space = True
-        spaces = False
-        breaks = True
-        start = end = 0
-        while end <= len(text):
-            ch = None
-            if end < len(text):
-                ch = text[end]
-            if breaks:
-                if ch is None or ch not in '\n\x85\u2028\u2029\a':
-                    if (
-                        not leading_space
-                        and ch is not None
-                        and ch != ' '
-                        and text[start] == '\n'
-                    ):
-                        self.write_line_break()
-                    leading_space = ch == ' '
-                    for br in text[start:end]:
-                        if br == '\n':
-                            self.write_line_break()
-                        else:
-                            self.write_line_break(br)
-                    if ch is not None:
-                        self.write_indent()
-                    start = end
-            elif spaces:
-                if ch != ' ':
-                    if start + 1 == end and self.column > self.best_width:
-                        self.write_indent()
-                    else:
-                        data = text[start:end]
-                        self.column += len(data)
-                        if bool(self.encoding):
-                            data = data.encode(self.encoding)
-                        self.stream.write(data)
-                    start = end
-            else:
-                if ch is None or ch in ' \n\x85\u2028\u2029\a':
-                    data = text[start:end]
-                    self.column += len(data)
-                    if bool(self.encoding):
-                        data = data.encode(self.encoding)
-                    self.stream.write(data)
-                    if ch == '\a':
-                        if end < (len(text) - 1) and not text[end + 2].isspace():
-                            self.write_line_break()
-                            self.write_indent()
-                            end += 2  # \a and the space that is inserted on the fold
-                        else:
-                            raise EmitterError('unexcpected fold indicator \\a before space')
-                    if ch is None:
-                        self.write_line_break()
-                    start = end
-            if ch is not None:
-                breaks = ch in '\n\x85\u2028\u2029'
-                spaces = ch == ' '
-            end += 1
-
-    def write_literal(self, text: Any, comment: Any = None) -> None:
-        hints, _indent, _indicator = self.determine_block_hints(text)
-        # if comment is not None:
-        #    try:
-        #        hints += comment[1][0]
-        #    except (TypeError, IndexError) as e:
-        #        pass
-        if not isinstance(comment, str):
-            comment = ''
-        self.write_indicator('|' + hints + comment, True)
-        # try:
-        #    nprintf('selfev', comment)
-        #    cmx = comment[1][0]
-        #    if cmx:
-        #        self.stream.write(cmx)
-        # except (TypeError, IndexError) as e:
-        #    pass
-        if _indicator == '+':
-            self.open_ended = True
-        self.write_line_break()
-        breaks = True
-        start = end = 0
-        while end <= len(text):
-            ch = None
-            if end < len(text):
-                ch = text[end]
-            if breaks:
-                if ch is None or ch not in '\n\x85\u2028\u2029':
-                    for br in text[start:end]:
-                        if br == '\n':
-                            self.write_line_break()
-                        else:
-                            self.write_line_break(br)
-                    if ch is not None:
-                        if self.root_context:
-                            idnx = self.indent if self.indent is not None else 0
-                            self.stream.write(' ' * (_indent + idnx))
-                        else:
-                            self.write_indent()
-                    start = end
-            else:
-                if ch is None or ch in '\n\x85\u2028\u2029':
-                    data = text[start:end]
-                    if bool(self.encoding):
-                        data = data.encode(self.encoding)
-                    self.stream.write(data)
-                    if ch is None:
-                        self.write_line_break()
-                    start = end
-            if ch is not None:
-                breaks = ch in '\n\x85\u2028\u2029'
-            end += 1
-
-    def write_plain(self, text: Any, split: Any = True) -> None:
-        if self.root_context:
-            if self.requested_indent is not None:
-                self.write_line_break()
-                if self.requested_indent != 0:
-                    self.write_indent()
-            else:
-                self.open_ended = True
-        if not text:
-            return
-        if not self.whitespace:
-            data = ' '
-            self.column += len(data)
-            if self.encoding:
-                data = data.encode(self.encoding)  # type: ignore
-            self.stream.write(data)
-        self.whitespace = False
-        self.indention = False
-        spaces = False
-        breaks = False
-        start = end = 0
-        while end <= len(text):
-            # ToDo: there is an empty space at the end of the wrapped line, if that line
-            # does not exceed self.best_width, that space is superfluous if wrapping is on
-            ch = None
-            if end < len(text):
-                ch = text[end]
-            if spaces:
-                if ch != ' ':
-                    if start + 1 == end and self.column >= self.best_width and split:
-                        self.write_indent()
-                        self.whitespace = False
-                        self.indention = False
-                    else:
-                        data = text[start:end]
-                        self.column += len(data)
-                        if self.encoding:
-                            data = data.encode(self.encoding)  # type: ignore
-                        self.stream.write(data)
-                    start = end
-            elif breaks:
-                if ch not in '\n\x85\u2028\u2029':  # type: ignore
-                    if text[start] == '\n':
-                        self.write_line_break()
-                    for br in text[start:end]:
-                        if br == '\n':
-                            self.write_line_break()
-                        else:
-                            self.write_line_break(br)
-                    self.write_indent()
-                    self.whitespace = False
-                    self.indention = False
-                    start = end
-            else:
-                if ch is None or ch in ' \n\x85\u2028\u2029':
-                    data = text[start:end]
-                    if (
-                        (len(data) + self.column) > self.best_width
-                        and self.indent is not None
-                        and self.column > self.indent
-                    ):
-                        # words longer than line length get a line of their own
-                        self.write_indent()
-                    self.column += len(data)
-                    if self.encoding:
-                        data = data.encode(self.encoding)  # type: ignore
-                    try:
-                        self.stream.write(data)
-                    except:  # NOQA
-                        sys.stdout.write(repr(data) + '\n')
-                        raise
-                    start = end
-            if ch is not None:
-                spaces = ch == ' '
-                breaks = ch in '\n\x85\u2028\u2029'
-            end += 1
-
-    def write_comment(self, comment: Any, pre: bool = False) -> None:
-        value = comment.value
-        # nprintf(f'{self.column:02d} {comment.start_mark.column:02d} {value!r}')
-        if not pre and value[-1] == '\n':
-            value = value[:-1]
-        try:
-            # get original column position
-            col = comment.start_mark.column
-            if comment.value and comment.value.startswith('\n'):
-                # never inject extra spaces if the comment starts with a newline
-                # and not a real comment (e.g. if you have an empty line following a key-value
-                col = self.column
-            elif col < self.column + 1:
-                ValueError
-        except ValueError:
-            col = self.column + 1
-        # nprint('post_comment', self.line, self.column, value)
-        try:
-            # at least one space if the current column >= the start column of the comment
-            # but not at the start of a line
-            nr_spaces = col - self.column
-            if self.column and value.strip() and nr_spaces < 1 and value[0] != '\n':
-                nr_spaces = 1
-            value = ' ' * nr_spaces + value
-            try:
-                if bool(self.encoding):
-                    value = value.encode(self.encoding)
-            except UnicodeDecodeError:
-                pass
-            self.stream.write(value)
-        except TypeError:
-            raise
-        if not pre:
-            self.write_line_break()
-
-    def write_pre_comment(self, event: Any) -> bool:
-        if event.comment is None:
-            return False
-        comments = event.comment[1]
-        if comments is None:
-            return False
-        try:
-            start_events = (MappingStartEvent, SequenceStartEvent)
-            for comment in comments:
-                if isinstance(event, start_events) and getattr(comment, 'pre_done', None):
-                    continue
-                if self.column != 0:
-                    self.write_line_break()
-                self.write_comment(comment, pre=True)
-                if isinstance(event, start_events):
-                    comment.pre_done = True
-        except TypeError:
-            sys.stdout.write(f'eventtt {type(event)} {event}')
-            raise
-        return True
-
-    def write_post_comment(self, event: Any) -> bool:
-        if self.event.comment[0] is None:
-            return False
-        comment = event.comment[0]
-        self.write_comment(comment)
-        return True
-
-
-class RoundTripEmitter(Emitter):
-    def prepare_tag(self, ctag: Any) -> Any:
-        if not ctag:
-            raise EmitterError('tag must not be empty')
-        tag = str(ctag)
-        if tag == '!' or tag == '!!':
-            return tag
-        handle = ctag.handle
-        suffix = ctag.suffix
-        prefixes = sorted(self.tag_prefixes.keys())
-        # print('handling', repr(tag), repr(suffix), repr(handle))
-        if handle is None:
-            for prefix in prefixes:
-                if tag.startswith(prefix) and (prefix == '!' or len(prefix) < len(tag)):
-                    handle = self.tag_prefixes[prefix]
-                    suffix = suffix[len(prefix) :]
-        if handle:
-            return f'{handle!s}{suffix!s}'
-        else:
-            return f'!<{suffix!s}>'
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py
deleted file mode 100644
index 1f1e1f5b6b8..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/error.py
+++ /dev/null
@@ -1,328 +0,0 @@
-
-from __future__ import annotations
-
-import warnings
-# import textwrap
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Text  # NOQA
-
-
-__all__ = [
-    'FileMark',
-    'StringMark',
-    'CommentMark',
-    'YAMLError',
-    'MarkedYAMLError',
-    'ReusedAnchorWarning',
-    'UnsafeLoaderWarning',
-    'MarkedYAMLWarning',
-    'MarkedYAMLFutureWarning',
-]
-
-
-class StreamMark:
-    __slots__ = 'name', 'index', 'line', 'column'
-
-    def __init__(self, name: Any, index: int, line: int, column: int) -> None:
-        self.name = name
-        self.index = index
-        self.line = line
-        self.column = column
-
-    def __str__(self) -> Any:
-        where = f'  in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
-        return where
-
-    def __eq__(self, other: Any) -> bool:
-        if self.line != other.line or self.column != other.column:
-            return False
-        if self.name != other.name or self.index != other.index:
-            return False
-        return True
-
-    def __ne__(self, other: Any) -> bool:
-        return not self.__eq__(other)
-
-
-class FileMark(StreamMark):
-    __slots__ = ()
-
-
-class StringMark(StreamMark):
-    __slots__ = 'name', 'index', 'line', 'column', 'buffer', 'pointer'
-
-    def __init__(
-        self, name: Any, index: int, line: int, column: int, buffer: Any, pointer: Any,
-    ) -> None:
-        StreamMark.__init__(self, name, index, line, column)
-        self.buffer = buffer
-        self.pointer = pointer
-
-    def get_snippet(self, indent: int = 4, max_length: int = 75) -> Any:
-        if self.buffer is None:  # always False
-            return None
-        head = ""
-        start = self.pointer
-        while start > 0 and self.buffer[start - 1] not in '\0\r\n\x85\u2028\u2029':
-            start -= 1
-            if self.pointer - start > max_length / 2 - 1:
-                head = ' ... '
-                start += 5
-                break
-        tail = ""
-        end = self.pointer
-        while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029':
-            end += 1
-            if end - self.pointer > max_length / 2 - 1:
-                tail = ' ... '
-                end -= 5
-                break
-        snippet = self.buffer[start:end]
-        caret = '^'
-        caret = f'^ (line: {self.line + 1})'
-        return (
-            ' ' * indent
-            + head
-            + snippet
-            + tail
-            + '\n'
-            + ' ' * (indent + self.pointer - start + len(head))
-            + caret
-        )
-
-    def __str__(self) -> Any:
-        snippet = self.get_snippet()
-        where = f'  in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
-        if snippet is not None:
-            where += ':\n' + snippet
-        return where
-
-    def __repr__(self) -> Any:
-        snippet = self.get_snippet()
-        where = f'  in "{self.name!s}", line {self.line + 1:d}, column {self.column + 1:d}'
-        if snippet is not None:
-            where += ':\n' + snippet
-        return where
-
-
-class CommentMark:
-    __slots__ = ('column',)
-
-    def __init__(self, column: Any) -> None:
-        self.column = column
-
-
-class YAMLError(Exception):
-    pass
-
-
-class MarkedYAMLError(YAMLError):
-    def __init__(  # NOQA
-        self,
-        context: Any = None,
-        context_mark: Any = None,
-        problem: Any = None,
-        problem_mark: Any = None,
-        note: Any = None,
-        warn: Any = None,
-    ) -> None:
-        self.context = context
-        self.context_mark = context_mark
-        self.problem = problem
-        self.problem_mark = problem_mark
-        self.note = note
-        # warn is ignored
-
-    def __str__(self) -> Any:
-        lines: list[str] = []
-        if self.context is not None:
-            lines.append(self.context)
-        if self.context_mark is not None and (
-            self.problem is None
-            or self.problem_mark is None
-            or self.context_mark.name != self.problem_mark.name
-            or self.context_mark.line != self.problem_mark.line
-            or self.context_mark.column != self.problem_mark.column
-        ):
-            lines.append(str(self.context_mark))
-        if self.problem is not None:
-            lines.append(self.problem)
-        if self.problem_mark is not None:
-            lines.append(str(self.problem_mark))
-        # if self.note is not None and self.note:
-        #     note = textwrap.dedent(self.note)
-        #     lines.append(note)
-        self.check_append(lines, self.note)
-        return '\n'.join(lines)
-
-    def check_append(self, lines: list[str], val: Optional[str]) -> None:
-        if val is None or not val:
-            return
-        import textwrap
-
-        note = textwrap.dedent(val)
-        lines.append(note)
-
-
-class YAMLStreamError(Exception):
-    pass
-
-
-class YAMLWarning(Warning):
-    pass
-
-
-class MarkedYAMLWarning(YAMLWarning):
-    def __init__(  # NOQA
-        self,
-        context: Any = None,
-        context_mark: Any = None,
-        problem: Any = None,
-        problem_mark: Any = None,
-        note: Any = None,
-        warn: Any = None,
-    ) -> None:
-        self.context = context
-        self.context_mark = context_mark
-        self.problem = problem
-        self.problem_mark = problem_mark
-        self.note = note
-        self.warn = warn
-
-    def __str__(self) -> Any:
-        lines: List[str] = []
-        if self.context is not None:
-            lines.append(self.context)
-        if self.context_mark is not None and (
-            self.problem is None
-            or self.problem_mark is None
-            or self.context_mark.name != self.problem_mark.name
-            or self.context_mark.line != self.problem_mark.line
-            or self.context_mark.column != self.problem_mark.column
-        ):
-            lines.append(str(self.context_mark))
-        if self.problem is not None:
-            lines.append(self.problem)
-        if self.problem_mark is not None:
-            lines.append(str(self.problem_mark))
-        # if self.note is not None and self.note:
-        #     note = textwrap.dedent(self.note)
-        #     lines.append(note)
-        self.check_append(lines, self.note)
-        # if self.warn is not None and self.warn:
-        #     warn = textwrap.dedent(self.warn)
-        #     lines.append(warn)
-        self.check_append(lines, self.warn)
-        return '\n'.join(lines)
-
-    def check_append(self, lines: list[str], val: Optional[str]) -> None:
-        if val is None or not val:
-            return
-        import textwrap
-
-        note = textwrap.dedent(val)
-        lines.append(note)
-
-
-class ReusedAnchorWarning(YAMLWarning):
-    pass
-
-
-class UnsafeLoaderWarning(YAMLWarning):
-    text = """
-The default 'Loader' for 'load(stream)' without further arguments can be unsafe.
-Use 'load(stream, Loader=ruamel.yaml.Loader)' explicitly if that is OK.
-Alternatively include the following in your code:
-
-  import warnings
-  warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)
-
-In most other cases you should consider using 'safe_load(stream)'"""
-    pass
-
-
-warnings.simplefilter('once', UnsafeLoaderWarning)
-
-
-class MantissaNoDotYAML1_1Warning(YAMLWarning):
-    def __init__(self, node: Any, flt_str: Any) -> None:  # NOQA
-        self.node = node
-        self.flt = flt_str
-
-    def __str__(self) -> Any:
-        line = self.node.start_mark.line
-        col = self.node.start_mark.column
-        return f"""
-In YAML 1.1 floating point values should have a dot ('.') in their mantissa.
-See the Floating-Point Language-Independent Type for YAML™ Version 1.1 specification
-( http://yaml.org/type/float.html ). This dot is not required for JSON nor for YAML 1.2
-
-Correct your float: "{self.flt}" on line: {line}, column: {col}
-
-or alternatively include the following in your code:
-
-  import warnings
-  warnings.simplefilter('ignore', ruamel.yaml.error.MantissaNoDotYAML1_1Warning)
-
-"""
-
-
-warnings.simplefilter('once', MantissaNoDotYAML1_1Warning)
-
-
-class YAMLFutureWarning(Warning):
-    pass
-
-
-class MarkedYAMLFutureWarning(YAMLFutureWarning):
-    def __init__(  # NOQA
-        self,
-        context: Any = None,
-        context_mark: Any = None,
-        problem: Any = None,
-        problem_mark: Any = None,
-        note: Any = None,
-        warn: Any = None,
-    ) -> None:
-        self.context = context
-        self.context_mark = context_mark
-        self.problem = problem
-        self.problem_mark = problem_mark
-        self.note = note
-        self.warn = warn
-
-    def __str__(self) -> Any:
-        lines: List[str] = []
-        if self.context is not None:
-            lines.append(self.context)
-
-        if self.context_mark is not None and (
-            self.problem is None
-            or self.problem_mark is None
-            or self.context_mark.name != self.problem_mark.name
-            or self.context_mark.line != self.problem_mark.line
-            or self.context_mark.column != self.problem_mark.column
-        ):
-            lines.append(str(self.context_mark))
-        if self.problem is not None:
-            lines.append(self.problem)
-        if self.problem_mark is not None:
-            lines.append(str(self.problem_mark))
-        # if self.note is not None and self.note:
-        #     note = textwrap.dedent(self.note)
-        #     lines.append(note)
-        self.check_append(lines, self.note)
-        # if self.warn is not None and self.warn:
-        #     warn = textwrap.dedent(self.warn)
-        #     lines.append(warn)
-        self.check_append(lines, self.warn)
-        return '\n'.join(lines)
-
-    def check_append(self, lines: list[str], val: Optional[str]) -> None:
-        if val is None or not val:
-            return
-        import textwrap
-
-        note = textwrap.dedent(val)
-        lines.append(note)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py
deleted file mode 100644
index cc61c9ea50b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/events.py
+++ /dev/null
@@ -1,266 +0,0 @@
-
-from __future__ import annotations
-
-# Abstract classes.
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
-
-SHOW_LINES = False
-
-
-def CommentCheck() -> None:
-    pass
-
-
-class Event:
-    __slots__ = 'start_mark', 'end_mark', 'comment'
-    crepr = 'Unspecified Event'
-
-    def __init__(
-        self, start_mark: Any = None, end_mark: Any = None, comment: Any = CommentCheck,
-    ) -> None:
-        self.start_mark = start_mark
-        self.end_mark = end_mark
-        # assert comment is not CommentCheck
-        if comment is CommentCheck:
-            comment = None
-        self.comment = comment
-
-    def __repr__(self) -> Any:
-        if True:
-            arguments = []
-            if hasattr(self, 'value'):
-                # if you use repr(getattr(self, 'value')) then flake8 complains about
-                # abuse of getattr with a constant. When you change to self.value
-                # then mypy throws an error
-                arguments.append(repr(self.value))
-            for key in ['anchor', 'tag', 'implicit', 'flow_style', 'style']:
-                v = getattr(self, key, None)
-                if v is not None:
-                    arguments.append(f'{key!s}={v!r}')
-            if self.comment not in [None, CommentCheck]:
-                arguments.append(f'comment={self.comment!r}')
-            if SHOW_LINES:
-                arguments.append(
-                    f'({self.start_mark.line}:{self.start_mark.column}/'
-                    f'{self.end_mark.line}:{self.end_mark.column})',
-                )
-            arguments = ', '.join(arguments)  # type: ignore
-        else:
-            attributes = [
-                key
-                for key in ['anchor', 'tag', 'implicit', 'value', 'flow_style', 'style']
-                if hasattr(self, key)
-            ]
-            arguments = ', '.join([f'{key!s}={getattr(self, key)!r}' for key in attributes])
-            if self.comment not in [None, CommentCheck]:
-                arguments += f', comment={self.comment!r}'
-        return f'{self.__class__.__name__!s}({arguments!s})'
-
-    def compact_repr(self) -> str:
-        return f'{self.crepr}'
-
-
-class NodeEvent(Event):
-    __slots__ = ('anchor',)
-
-    def __init__(
-        self, anchor: Any, start_mark: Any = None, end_mark: Any = None, comment: Any = None,
-    ) -> None:
-        Event.__init__(self, start_mark, end_mark, comment)
-        self.anchor = anchor
-
-
-class CollectionStartEvent(NodeEvent):
-    __slots__ = 'ctag', 'implicit', 'flow_style', 'nr_items'
-
-    def __init__(
-        self,
-        anchor: Any,
-        tag: Any,
-        implicit: Any,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        flow_style: Any = None,
-        comment: Any = None,
-        nr_items: Optional[int] = None,
-    ) -> None:
-        NodeEvent.__init__(self, anchor, start_mark, end_mark, comment)
-        self.ctag = tag
-        self.implicit = implicit
-        self.flow_style = flow_style
-        self.nr_items = nr_items
-
-    @property
-    def tag(self) -> Optional[str]:
-        return None if self.ctag is None else str(self.ctag)
-
-
-class CollectionEndEvent(Event):
-    __slots__ = ()
-
-
-# Implementations.
-
-
-class StreamStartEvent(Event):
-    __slots__ = ('encoding',)
-    crepr = '+STR'
-
-    def __init__(
-        self,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        encoding: Any = None,
-        comment: Any = None,
-    ) -> None:
-        Event.__init__(self, start_mark, end_mark, comment)
-        self.encoding = encoding
-
-
-class StreamEndEvent(Event):
-    __slots__ = ()
-    crepr = '-STR'
-
-
-class DocumentStartEvent(Event):
-    __slots__ = 'explicit', 'version', 'tags'
-    crepr = '+DOC'
-
-    def __init__(
-        self,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        explicit: Any = None,
-        version: Any = None,
-        tags: Any = None,
-        comment: Any = None,
-    ) -> None:
-        Event.__init__(self, start_mark, end_mark, comment)
-        self.explicit = explicit
-        self.version = version
-        self.tags = tags
-
-    def compact_repr(self) -> str:
-        start = ' ---' if self.explicit else ''
-        return f'{self.crepr}{start}'
-
-
-class DocumentEndEvent(Event):
-    __slots__ = ('explicit',)
-    crepr = '-DOC'
-
-    def __init__(
-        self,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        explicit: Any = None,
-        comment: Any = None,
-    ) -> None:
-        Event.__init__(self, start_mark, end_mark, comment)
-        self.explicit = explicit
-
-    def compact_repr(self) -> str:
-        end = ' ...' if self.explicit else ''
-        return f'{self.crepr}{end}'
-
-
-class AliasEvent(NodeEvent):
-    __slots__ = 'style'
-    crepr = '=ALI'
-
-    def __init__(
-        self,
-        anchor: Any,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        style: Any = None,
-        comment: Any = None,
-    ) -> None:
-        NodeEvent.__init__(self, anchor, start_mark, end_mark, comment)
-        self.style = style
-
-    def compact_repr(self) -> str:
-        return f'{self.crepr} *{self.anchor}'
-
-
-class ScalarEvent(NodeEvent):
-    __slots__ = 'ctag', 'implicit', 'value', 'style'
-    crepr = '=VAL'
-
-    def __init__(
-        self,
-        anchor: Any,
-        tag: Any,
-        implicit: Any,
-        value: Any,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        style: Any = None,
-        comment: Any = None,
-    ) -> None:
-        NodeEvent.__init__(self, anchor, start_mark, end_mark, comment)
-        self.ctag = tag
-        self.implicit = implicit
-        self.value = value
-        self.style = style
-
-    @property
-    def tag(self) -> Optional[str]:
-        return None if self.ctag is None else str(self.ctag)
-
-    @tag.setter
-    def tag(self, val: Any) -> None:
-        if isinstance(val, str):
-            val = Tag(suffix=val)
-        self.ctag = val
-
-    def compact_repr(self) -> str:
-        style = ':' if self.style is None else self.style
-        anchor = f'&{self.anchor} ' if self.anchor else ''
-        tag = f'<{self.tag!s}> ' if self.tag else ''
-        value = self.value
-        for ch, rep in [
-            ('\\', '\\\\'),
-            ('\t', '\\t'),
-            ('\n', '\\n'),
-            ('\a', ''),  # remove from folded
-            ('\r', '\\r'),
-            ('\b', '\\b'),
-        ]:
-            value = value.replace(ch, rep)
-        return f'{self.crepr} {anchor}{tag}{style}{value}'
-
-
-class SequenceStartEvent(CollectionStartEvent):
-    __slots__ = ()
-    crepr = '+SEQ'
-
-    def compact_repr(self) -> str:
-        flow = ' []' if self.flow_style else ''
-        anchor = f' &{self.anchor}' if self.anchor else ''
-        tag = f' <{self.tag!s}>' if self.tag else ''
-        return f'{self.crepr}{flow}{anchor}{tag}'
-
-
-class SequenceEndEvent(CollectionEndEvent):
-    __slots__ = ()
-    crepr = '-SEQ'
-
-
-class MappingStartEvent(CollectionStartEvent):
-    __slots__ = ()
-    crepr = '+MAP'
-
-    def compact_repr(self) -> str:
-        flow = ' {}' if self.flow_style else ''
-        anchor = f' &{self.anchor}' if self.anchor else ''
-        tag = f' <{self.tag!s}>' if self.tag else ''
-        return f'{self.crepr}{flow}{anchor}{tag}'
-
-
-class MappingEndEvent(CollectionEndEvent):
-    __slots__ = ()
-    crepr = '-MAP'
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py
deleted file mode 100644
index 07c6febc0e7..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/loader.py
+++ /dev/null
@@ -1,92 +0,0 @@
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.reader import Reader
-from opentelemetry.agent._vendor.ruamel.yaml.scanner import Scanner, RoundTripScanner
-from opentelemetry.agent._vendor.ruamel.yaml.parser import Parser, RoundTripParser
-from opentelemetry.agent._vendor.ruamel.yaml.composer import Composer
-from opentelemetry.agent._vendor.ruamel.yaml.constructor import (
-    BaseConstructor,
-    SafeConstructor,
-    Constructor,
-    RoundTripConstructor,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.resolver import VersionedResolver
-
-if False:  # MYPY
-    from typing import Any, Dict, List, Union, Optional  # NOQA
-    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamTextType, VersionType  # NOQA
-
-__all__ = ['BaseLoader', 'SafeLoader', 'Loader', 'RoundTripLoader']
-
-
-class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, VersionedResolver):
-    def __init__(
-        self,
-        stream: StreamTextType,
-        version: Optional[VersionType] = None,
-        preserve_quotes: Optional[bool] = None,
-    ) -> None:
-        self.comment_handling = None
-        Reader.__init__(self, stream, loader=self)
-        Scanner.__init__(self, loader=self)
-        Parser.__init__(self, loader=self)
-        Composer.__init__(self, loader=self)
-        BaseConstructor.__init__(self, loader=self)
-        VersionedResolver.__init__(self, version, loader=self)
-
-
-class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, VersionedResolver):
-    def __init__(
-        self,
-        stream: StreamTextType,
-        version: Optional[VersionType] = None,
-        preserve_quotes: Optional[bool] = None,
-    ) -> None:
-        self.comment_handling = None
-        Reader.__init__(self, stream, loader=self)
-        Scanner.__init__(self, loader=self)
-        Parser.__init__(self, loader=self)
-        Composer.__init__(self, loader=self)
-        SafeConstructor.__init__(self, loader=self)
-        VersionedResolver.__init__(self, version, loader=self)
-
-
-class Loader(Reader, Scanner, Parser, Composer, Constructor, VersionedResolver):
-    def __init__(
-        self,
-        stream: StreamTextType,
-        version: Optional[VersionType] = None,
-        preserve_quotes: Optional[bool] = None,
-    ) -> None:
-        self.comment_handling = None
-        Reader.__init__(self, stream, loader=self)
-        Scanner.__init__(self, loader=self)
-        Parser.__init__(self, loader=self)
-        Composer.__init__(self, loader=self)
-        Constructor.__init__(self, loader=self)
-        VersionedResolver.__init__(self, version, loader=self)
-
-
-class RoundTripLoader(
-    Reader,
-    RoundTripScanner,
-    RoundTripParser,
-    Composer,
-    RoundTripConstructor,
-    VersionedResolver,
-):
-    def __init__(
-        self,
-        stream: StreamTextType,
-        version: Optional[VersionType] = None,
-        preserve_quotes: Optional[bool] = None,
-    ) -> None:
-        # self.reader = Reader.__init__(self, stream)
-        self.comment_handling = None  # issue 385
-        Reader.__init__(self, stream, loader=self)
-        RoundTripScanner.__init__(self, loader=self)
-        RoundTripParser.__init__(self, loader=self)
-        Composer.__init__(self, loader=self)
-        RoundTripConstructor.__init__(self, preserve_quotes=preserve_quotes, loader=self)
-        VersionedResolver.__init__(self, version, loader=self)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py
deleted file mode 100644
index 34bce4458f9..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/main.py
+++ /dev/null
@@ -1,1519 +0,0 @@
-
-from __future__ import annotations
-
-import sys
-import os
-import warnings
-import glob
-from importlib import import_module
-
-
-import opentelemetry.agent._vendor.ruamel.yaml
-from opentelemetry.agent._vendor import ruamel
-from opentelemetry.agent._vendor import opentelemetry
-from opentelemetry.agent._vendor.ruamel.yaml.error import UnsafeLoaderWarning, YAMLError  # NOQA
-
-from opentelemetry.agent._vendor.ruamel.yaml.tokens import *  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.events import *  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.nodes import *  # NOQA
-
-from opentelemetry.agent._vendor.ruamel.yaml.loader import BaseLoader, SafeLoader, Loader, RoundTripLoader  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.dumper import BaseDumper, SafeDumper, Dumper, RoundTripDumper  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.compat import StringIO, BytesIO, with_metaclass, nprint, nprintf  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.resolver import VersionedResolver, Resolver  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.representer import (
-    BaseRepresenter,
-    SafeRepresenter,
-    Representer,
-    RoundTripRepresenter,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.constructor import (
-    BaseConstructor,
-    SafeConstructor,
-    Constructor,
-    RoundTripConstructor,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.loader import Loader as UnsafeLoader  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.comments import CommentedMap, CommentedSeq, C_PRE
-from opentelemetry.agent._vendor.ruamel.yaml.docinfo import DocInfo, version, Version
-
-from typing import List, Set, Dict, Tuple, Union, Any, Callable, Optional, Text, Type  # NOQA
-if False:  # MYPY
-    from opentelemetry.agent._vendor.ruamel.yaml.compat import StreamType, StreamTextType, VersionType  # NOQA
-    from types import TracebackType
-    from pathlib import Path
-
-# opentelemetry-agent: always use the pure-Python parser and emitter; the libyaml binding
-# (_ruamel_yaml) would be the application's, not vendored.
-CParser = CEmitter = None
-
-# import io
-
-
-# YAML is an acronym, i.e. spoken: rhymes with "camel". And thus a
-# subset of abbreviations, which should be all caps according to PEP8
-
-
-class YAML:
-    def __init__(
-        self: Any,
-        *,
-        typ: Optional[Union[List[Text], Text]] = None,
-        pure: Any = False,
-        output: Any = None,
-        plug_ins: Any = None,
-    ) -> None:  # input=None,
-        """
-        typ: 'rt'/None -> RoundTripLoader/RoundTripDumper,  (default)
-             'safe'    -> SafeLoader/SafeDumper,
-             'unsafe'  -> normal/unsafe Loader/Dumper (pending deprecation)
-             'full'    -> full Dumper only, including python built-ins that are
-                          potentially unsafe to load
-             'base'    -> baseloader
-        pure: if True only use Python modules
-        input/output: needed to work as context manager
-        plug_ins: a list of plug-in files
-        """
-
-        self.typ = ['rt'] if typ is None else (typ if isinstance(typ, list) else [typ])
-        self.pure = pure
-
-        # self._input = input
-        self._output = output
-        self._context_manager: Any = None
-
-        self.plug_ins: List[Any] = []
-        for pu in ([] if plug_ins is None else plug_ins) + self.official_plug_ins():
-            file_name = pu.replace(os.sep, '.')
-            self.plug_ins.append(import_module(file_name))
-        self.Resolver: Any = ruamel.yaml.resolver.VersionedResolver
-        self.allow_unicode = True
-        self.Reader: Any = None
-        self.Representer: Any = None
-        self.Constructor: Any = None
-        self.Scanner: Any = None
-        self.Serializer: Any = None
-        self.default_flow_style: Any = None
-        self.comment_handling = None
-        self.max_depth = 0
-        typ_found = 1
-        setup_rt = False
-        if 'rt' in self.typ:
-            setup_rt = True
-        elif 'safe' in self.typ:
-            self.Emitter = (
-                ruamel.yaml.emitter.Emitter if pure or CEmitter is None else CEmitter
-            )
-            self.Representer = ruamel.yaml.representer.SafeRepresenter
-            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
-            self.Composer = ruamel.yaml.composer.Composer
-            self.Constructor = ruamel.yaml.constructor.SafeConstructor
-        elif 'base' in self.typ:
-            self.Emitter = ruamel.yaml.emitter.Emitter
-            self.Representer = ruamel.yaml.representer.BaseRepresenter
-            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
-            self.Composer = ruamel.yaml.composer.Composer
-            self.Constructor = ruamel.yaml.constructor.BaseConstructor
-        elif 'unsafe' in self.typ:
-            warnings.warn(
-                "\nyou should no longer specify 'unsafe'.\nFor **dumping only** use yaml=YAML(typ='full')\n",  # NOQA
-                PendingDeprecationWarning,
-                stacklevel=2,
-            )
-            self.Emitter = (
-                ruamel.yaml.emitter.Emitter if pure or CEmitter is None else CEmitter
-            )
-            self.Representer = ruamel.yaml.representer.Representer
-            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
-            self.Composer = ruamel.yaml.composer.Composer
-            self.Constructor = ruamel.yaml.constructor.Constructor
-        elif 'full' in self.typ:
-            self.Emitter = (
-                ruamel.yaml.emitter.Emitter if pure or CEmitter is None else CEmitter
-            )
-            self.Representer = ruamel.yaml.representer.Representer
-            self.Parser = ruamel.yaml.parser.Parser if pure or CParser is None else CParser
-            # self.Composer = ruamel.yaml.composer.Composer
-            # self.Constructor = ruamel.yaml.constructor.Constructor
-        elif 'rtsc' in self.typ:
-            self.default_flow_style = False
-            # no optimized rt-dumper yet
-            self.Emitter = ruamel.yaml.emitter.RoundTripEmitter
-            self.Serializer = ruamel.yaml.serializer.Serializer
-            self.Representer = ruamel.yaml.representer.RoundTripRepresenter
-            self.Scanner = ruamel.yaml.scanner.RoundTripScannerSC
-            # no optimized rt-parser yet
-            self.Parser = ruamel.yaml.parser.RoundTripParserSC
-            self.Composer = ruamel.yaml.composer.Composer
-            self.Constructor = ruamel.yaml.constructor.RoundTripConstructor
-            self.comment_handling = C_PRE
-        else:
-            setup_rt = True
-            typ_found = 0
-        if setup_rt:
-            self.default_flow_style = False
-            # no optimized rt-dumper yet
-            self.Emitter = ruamel.yaml.emitter.RoundTripEmitter
-            self.Serializer = ruamel.yaml.serializer.Serializer
-            self.Representer = ruamel.yaml.representer.RoundTripRepresenter
-            self.Scanner = ruamel.yaml.scanner.RoundTripScanner
-            # no optimized rt-parser yet
-            self.Parser = ruamel.yaml.parser.RoundTripParser
-            self.Composer = ruamel.yaml.composer.Composer
-            self.Constructor = ruamel.yaml.constructor.RoundTripConstructor
-        del setup_rt
-        self.stream = None
-        self.canonical = None
-        self.old_indent = None
-        self.width: Union[int, None] = None
-        self.line_break = None
-
-        self.map_indent: Union[int, None] = None
-        self.sequence_indent: Union[int, None] = None
-        self.sequence_dash_offset: int = 0
-        self.compact_seq_seq = None
-        self.compact_seq_map = None
-        self.sort_base_mapping_type_on_output = None  # default: sort
-
-        self.top_level_colon_align = None
-        self.prefix_colon = None
-        self._version: Optional[Any] = None
-        self.preserve_quotes: Optional[bool] = None
-        self.allow_duplicate_keys = False  # duplicate keys in map, set
-        self.encoding = 'utf-8'
-        self.explicit_start: Union[bool, None] = None
-        self.explicit_end: Union[bool, None] = None
-        self._tags = None
-        self.doc_infos: List[DocInfo] = []
-        self.default_style = None
-        self.top_level_block_style_scalar_no_indent_error_1_1 = False
-        # directives end indicator with single scalar document
-        self.scalar_after_indicator: Optional[bool] = None
-        # [a, b: 1, c: {d: 2}]  vs. [a, {b: 1}, {c: {d: 2}}]
-        self.brace_single_entry_mapping_in_flow_sequence = False
-        for module in self.plug_ins:
-            if getattr(module, 'typ', None) in self.typ:
-                typ_found += 1
-                module.init_typ(self)
-                break
-        if typ_found == 0:
-            raise NotImplementedError(
-                f'typ "{self.typ}" not recognised (need to install plug-in?)',
-            )
-
-    @property
-    def reader(self) -> Any:
-        try:
-            return self._reader  # type: ignore
-        except AttributeError:
-            self._reader = self.Reader(None, loader=self)
-            return self._reader
-
-    @property
-    def scanner(self) -> Any:
-        try:
-            return self._scanner  # type: ignore
-        except AttributeError:
-            if self.Scanner is None:
-                raise
-            self._scanner = self.Scanner(loader=self)
-            return self._scanner
-
-    @property
-    def parser(self) -> Any:
-        attr = '_' + sys._getframe().f_code.co_name
-        if not hasattr(self, attr):
-            if self.Parser is not CParser:
-                setattr(self, attr, self.Parser(loader=self))
-            else:
-                if getattr(self, '_stream', None) is None:
-                    # wait for the stream
-                    return None
-                else:
-                    # if not hasattr(self._stream, 'read') and hasattr(self._stream, 'open'):
-                    #     # pathlib.Path() instance
-                    #     setattr(self, attr, CParser(self._stream))
-                    # else:
-                    setattr(self, attr, CParser(self._stream))
-                    # self._parser = self._composer = self
-                    # nprint('scanner', self.loader.scanner)
-
-        return getattr(self, attr)
-
-    @property
-    def composer(self) -> Any:
-        attr = '_' + sys._getframe().f_code.co_name
-        if not hasattr(self, attr):
-            setattr(self, attr, self.Composer(loader=self))
-        return getattr(self, attr)
-
-    @property
-    def constructor(self) -> Any:
-        attr = '_' + sys._getframe().f_code.co_name
-        if not hasattr(self, attr):
-            if self.Constructor is None:
-                if 'full' in self.typ:
-                    raise YAMLError(
-                        "\nyou can only use yaml=YAML(typ='full') for dumping\n",  # NOQA
-                    )
-            cnst = self.Constructor(preserve_quotes=self.preserve_quotes, loader=self)  # type: ignore # NOQA
-            cnst.allow_duplicate_keys = self.allow_duplicate_keys
-            setattr(self, attr, cnst)
-        return getattr(self, attr)
-
-    @property
-    def resolver(self) -> Any:
-        try:
-            rslvr = self._resolver  # type: ignore
-        except AttributeError:
-            rslvr = None
-        if rslvr is None or rslvr._loader_version != self.version:
-            rslvr = self._resolver = self.Resolver(version=self.version, loader=self)
-        return rslvr
-
-    @property
-    def emitter(self) -> Any:
-        attr = '_' + sys._getframe().f_code.co_name
-        if not hasattr(self, attr):
-            if self.Emitter is not CEmitter:
-                _emitter = self.Emitter(
-                    None,
-                    canonical=self.canonical,
-                    indent=self.old_indent,
-                    width=self.width,
-                    allow_unicode=self.allow_unicode,
-                    line_break=self.line_break,
-                    prefix_colon=self.prefix_colon,
-                    brace_single_entry_mapping_in_flow_sequence=self.brace_single_entry_mapping_in_flow_sequence,  # NOQA
-                    dumper=self,
-                )
-                setattr(self, attr, _emitter)
-                if self.map_indent is not None:
-                    _emitter.best_map_indent = self.map_indent
-                if self.sequence_indent is not None:
-                    _emitter.best_sequence_indent = self.sequence_indent
-                if self.sequence_dash_offset is not None:
-                    _emitter.sequence_dash_offset = self.sequence_dash_offset
-                    # _emitter.block_seq_indent = self.sequence_dash_offset
-                if self.compact_seq_seq is not None:
-                    _emitter.compact_seq_seq = self.compact_seq_seq
-                if self.compact_seq_map is not None:
-                    _emitter.compact_seq_map = self.compact_seq_map
-            else:
-                if getattr(self, '_stream', None) is None:
-                    # wait for the stream
-                    return None
-                return None
-        return getattr(self, attr)
-
-    @property
-    def serializer(self) -> Any:
-        attr = '_' + sys._getframe().f_code.co_name
-        if not hasattr(self, attr):
-            setattr(
-                self,
-                attr,
-                self.Serializer(
-                    encoding=self.encoding,
-                    explicit_start=self.explicit_start,
-                    explicit_end=self.explicit_end,
-                    version=self.version,
-                    tags=self.tags,
-                    dumper=self,
-                ),
-            )
-        return getattr(self, attr)
-
-    @property
-    def representer(self) -> Any:
-        attr = '_' + sys._getframe().f_code.co_name
-        if not hasattr(self, attr):
-            repres = self.Representer(
-                default_style=self.default_style,
-                default_flow_style=self.default_flow_style,
-                dumper=self,
-            )
-            if self.sort_base_mapping_type_on_output is not None:
-                repres.sort_base_mapping_type_on_output = self.sort_base_mapping_type_on_output
-            setattr(self, attr, repres)
-        return getattr(self, attr)
-
-    def scan(self, stream: StreamTextType) -> Any:
-        """
-        Scan a YAML stream and produce scanning tokens.
-        """
-        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
-            # pathlib.Path() instance
-            with stream.open('rb') as fp:
-                return self.scan(fp)
-        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
-        self.tags = {}
-        _, parser = self.get_constructor_parser(stream)
-        try:
-            while self.scanner.check_token():
-                yield self.scanner.get_token()
-        finally:
-            parser.dispose()
-            for comp in ('reader', 'scanner'):
-                try:
-                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
-                except AttributeError:
-                    pass
-
-    def parse(self, stream: StreamTextType) -> Any:
-        """
-        Parse a YAML stream and produce parsing events.
-        """
-        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
-            # pathlib.Path() instance
-            with stream.open('rb') as fp:
-                return self.parse(fp)
-        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
-        self.tags = {}
-        _, parser = self.get_constructor_parser(stream)
-        try:
-            while parser.check_event():
-                yield parser.get_event()
-        finally:
-            parser.dispose()
-            for comp in ('reader', 'scanner'):
-                try:
-                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
-                except AttributeError:
-                    pass
-
-    def compose(self, stream: Union[Path, StreamTextType]) -> Any:
-        """
-        Parse the first YAML document in a stream
-        and produce the corresponding representation tree.
-        """
-        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
-            # pathlib.Path() instance
-            with stream.open('rb') as fp:
-                return self.compose(fp)
-        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
-        self.tags = {}
-        constructor, parser = self.get_constructor_parser(stream)
-        try:
-            return constructor.composer.get_single_node()
-        finally:
-            parser.dispose()
-            for comp in ('reader', 'scanner'):
-                try:
-                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
-                except AttributeError:
-                    pass
-
-    def compose_all(self, stream: Union[Path, StreamTextType]) -> Any:
-        """
-        Parse all YAML documents in a stream
-        and produce corresponding representation trees.
-        """
-        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
-        self.tags = {}
-        constructor, parser = self.get_constructor_parser(stream)
-        try:
-            while constructor.composer.check_node():
-                yield constructor.composer.get_node()
-        finally:
-            parser.dispose()
-            for comp in ('reader', 'scanner'):
-                try:
-                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
-                except AttributeError:
-                    pass
-
-    # separate output resolver?
-
-    # def load(self, stream=None):
-    #     if self._context_manager:
-    #        if not self._input:
-    #             raise TypeError("Missing input stream while dumping from context manager")
-    #         for data in self._context_manager.load():
-    #             yield data
-    #         return
-    #     if stream is None:
-    #         raise TypeError("Need a stream argument when not loading from context manager")
-    #     return self.load_one(stream)
-
-    def load(self, stream: Union[Path, StreamTextType]) -> Any:
-        """
-        at this point you either have the non-pure Parser (which has its own reader and
-        scanner) or you have the pure Parser.
-        If the pure Parser is set, then set the Reader and Scanner, if not already set.
-        If either the Scanner or Reader are set, you cannot use the non-pure Parser,
-            so reset it to the pure parser and set the Reader resp. Scanner if necessary
-        """
-        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
-            # pathlib.Path() instance
-            with stream.open('rb') as fp:
-                return self.load(fp)
-        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
-        self.tags = {}
-        constructor, parser = self.get_constructor_parser(stream)
-        try:
-            return constructor.get_single_data()
-        finally:
-            parser.dispose()
-            for comp in ('reader', 'scanner'):
-                try:
-                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
-                except AttributeError:
-                    pass
-
-    def load_all(self, stream: Union[Path, StreamTextType]) -> Any:  # *, skip=None):
-        if not hasattr(stream, 'read') and hasattr(stream, 'open'):
-            # pathlib.Path() instance
-            with stream.open('r') as fp:
-                for d in self.load_all(fp):
-                    yield d
-                return
-        # if skip is None:
-        #     skip = []
-        # elif isinstance(skip, int):
-        #     skip = [skip]
-        self.doc_infos.append(DocInfo(requested_version=version(self.version)))
-        self.tags = {}
-        constructor, parser = self.get_constructor_parser(stream)
-        try:
-            while constructor.check_data():
-                yield constructor.get_data()
-                self.doc_infos.append(DocInfo(requested_version=version(self.version)))
-        finally:
-            parser.dispose()
-            for comp in ('reader', 'scanner'):
-                try:
-                    getattr(getattr(self, '_' + comp), f'reset_{comp}')()
-                except AttributeError:
-                    pass
-
-    def get_constructor_parser(self, stream: StreamTextType) -> Any:
-        """
-        the old cyaml needs special setup, and therefore the stream
-        """
-        if self.Constructor is None:
-            if 'full' in self.typ:
-                raise YAMLError(
-                     "\nyou can only use yaml=YAML(typ='full') for dumping\n",  # NOQA
-                )
-        if self.Parser is not CParser:
-            if self.Reader is None:
-                self.Reader = ruamel.yaml.reader.Reader
-            if self.Scanner is None:
-                self.Scanner = ruamel.yaml.scanner.Scanner
-            self.reader.stream = stream
-        else:
-            if self.Reader is not None:
-                if self.Scanner is None:
-                    self.Scanner = ruamel.yaml.scanner.Scanner
-                self.Parser = ruamel.yaml.parser.Parser
-                self.reader.stream = stream
-            elif self.Scanner is not None:
-                if self.Reader is None:
-                    self.Reader = ruamel.yaml.reader.Reader
-                self.Parser = ruamel.yaml.parser.Parser
-                self.reader.stream = stream
-            else:
-                # combined C level reader>scanner>parser
-                # does some calls to the resolver, e.g. BaseResolver.descend_resolver
-                # if you just initialise the CParser, too much of resolver.py
-                # is actually used
-                rslvr = self.Resolver
-                # if rslvr is ruamel.yaml.resolver.VersionedResolver:
-                #     rslvr = ruamel.yaml.resolver.Resolver
-
-                class XLoader(self.Parser, self.Constructor, rslvr):  # type: ignore
-                    def __init__(
-                        selfx,
-                        stream: StreamTextType,
-                        version: Optional[VersionType] = self.version,
-                        preserve_quotes: Optional[bool] = None,
-                    ) -> None:
-                        # NOQA
-                        CParser.__init__(selfx, stream)
-                        selfx._parser = selfx._composer = selfx
-                        self.Constructor.__init__(selfx, loader=selfx)
-                        selfx.allow_duplicate_keys = self.allow_duplicate_keys
-                        rslvr.__init__(selfx, version=version, loadumper=selfx)
-
-                self._stream = stream
-                loader = XLoader(stream)
-                self._scanner = loader
-                return loader, loader
-        return self.constructor, self.parser
-
-    def emit(self, events: Any, stream: Any) -> None:
-        """
-        Emit YAML parsing events into a stream.
-        If stream is None, return the produced string instead.
-        """
-        _, _, emitter = self.get_serializer_representer_emitter(stream, None)
-        try:
-            for event in events:
-                emitter.emit(event)
-        finally:
-            try:
-                emitter.dispose()
-            except AttributeError:
-                raise
-
-    def serialize(self, node: Any, stream: Optional[StreamType]) -> Any:
-        """
-        Serialize a representation tree into a YAML stream.
-        If stream is None, return the produced string instead.
-        """
-        self.serialize_all([node], stream)
-
-    def serialize_all(self, nodes: Any, stream: Optional[StreamType]) -> Any:
-        """
-        Serialize a sequence of representation trees into a YAML stream.
-        If stream is None, return the produced string instead.
-        """
-        serializer, _, emitter = self.get_serializer_representer_emitter(stream, None)
-        try:
-            serializer.open()
-            for node in nodes:
-                serializer.serialize(node)
-            serializer.close()
-        finally:
-            try:
-                emitter.dispose()
-            except AttributeError:
-                raise
-
-    def dump(
-        self: Any, data: Union[Path, StreamType], stream: Any = None, *, transform: Any = None,
-    ) -> Any:
-        if self._context_manager:
-            if not self._output:
-                raise TypeError('Missing output stream while dumping from context manager')
-            if transform is not None:
-                x = self.__class__.__name__
-                raise TypeError(
-                    f'{x}.dump() in the context manager cannot have transform keyword',
-                )
-            self._context_manager.dump(data)
-        else:  # old style
-            if stream is None:
-                raise TypeError('Need a stream argument when not dumping from context manager')
-            return self.dump_all([data], stream, transform=transform)
-
-    def dump_all(
-        self, documents: Any, stream: Union[Path, StreamType], *, transform: Any = None,
-    ) -> Any:
-        if self._context_manager:
-            raise NotImplementedError
-        self._output = stream
-        self._context_manager = YAMLContextManager(self, transform=transform)
-        for data in documents:
-            self._context_manager.dump(data)
-        self._context_manager.teardown_output()
-        self._output = None
-        self._context_manager = None
-
-    def Xdump_all(self, documents: Any, stream: Any, *, transform: Any = None) -> Any:
-        """
-        Serialize a sequence of Python objects into a YAML stream.
-        """
-        if not hasattr(stream, 'write') and hasattr(stream, 'open'):
-            # pathlib.Path() instance
-            with stream.open('w') as fp:
-                return self.dump_all(documents, fp, transform=transform)
-        # The stream should have the methods `write` and possibly `flush`.
-        if self.top_level_colon_align is True:
-            tlca: Any = max([len(str(x)) for x in documents[0]])
-        else:
-            tlca = self.top_level_colon_align
-        if transform is not None:
-            fstream = stream
-            if self.encoding is None:
-                stream = StringIO()
-            else:
-                stream = BytesIO()
-        serializer, representer, emitter = self.get_serializer_representer_emitter(
-            stream, tlca,
-        )
-        try:
-            self.serializer.open()
-            for data in documents:
-                try:
-                    self.representer.represent(data)
-                except AttributeError:
-                    # nprint(dir(dumper._representer))
-                    raise
-            self.serializer.close()
-        finally:
-            try:
-                self.emitter.dispose()
-            except AttributeError:
-                raise
-                # self.dumper.dispose()  # cyaml
-            delattr(self, '_serializer')  # NOQA
-            delattr(self, '_emitter')  # NOQA
-        if transform:
-            val = stream.getvalue()
-            if self.encoding:
-                val = val.decode(self.encoding)
-            if fstream is None:
-                transform(val)
-            else:
-                fstream.write(transform(val))
-        return None
-
-    def get_serializer_representer_emitter(self, stream: StreamType, tlca: Any) -> Any:
-        # we have only .Serializer to deal with (vs .Reader & .Scanner), much simpler
-        if self.Emitter is not CEmitter:
-            if self.Serializer is None:
-                self.Serializer = ruamel.yaml.serializer.Serializer
-            self.emitter.stream = stream
-            self.emitter.top_level_colon_align = tlca
-            if self.scalar_after_indicator is not None:
-                self.emitter.scalar_after_indicator = self.scalar_after_indicator
-            return self.serializer, self.representer, self.emitter
-        if self.Serializer is not None:
-            # cannot set serializer with CEmitter
-            self.Emitter = ruamel.yaml.emitter.Emitter
-            self.emitter.stream = stream
-            self.emitter.top_level_colon_align = tlca
-            if self.scalar_after_indicator is not None:
-                self.emitter.scalar_after_indicator = self.scalar_after_indicator
-            return self.serializer, self.representer, self.emitter
-        # C routines
-
-        rslvr = (
-            ruamel.yaml.resolver.BaseResolver
-            if 'base' in self.typ
-            else ruamel.yaml.resolver.Resolver
-        )
-
-        class XDumper(CEmitter, self.Representer, rslvr):  # type: ignore
-            def __init__(
-                selfx: StreamType,
-                stream: Any,
-                default_style: Any = None,
-                default_flow_style: Any = None,
-                canonical: Optional[bool] = None,
-                indent: Optional[int] = None,
-                width: Optional[int] = None,
-                allow_unicode: Optional[bool] = None,
-                line_break: Any = None,
-                encoding: Any = None,
-                explicit_start: Optional[bool] = None,
-                explicit_end: Optional[bool] = None,
-                version: Any = None,
-                tags: Any = None,
-                block_seq_indent: Any = None,
-                top_level_colon_align: Any = None,
-                prefix_colon: Any = None,
-            ) -> None:
-                # NOQA
-                CEmitter.__init__(
-                    selfx,
-                    stream,
-                    canonical=canonical,
-                    indent=indent,
-                    width=width,
-                    encoding=encoding,
-                    allow_unicode=allow_unicode,
-                    line_break=line_break,
-                    explicit_start=explicit_start,
-                    explicit_end=explicit_end,
-                    version=version,
-                    tags=tags,
-                )
-                selfx._emitter = selfx._serializer = selfx._representer = selfx
-                self.Representer.__init__(
-                    selfx, default_style=default_style, default_flow_style=default_flow_style,
-                )
-                rslvr.__init__(selfx)
-
-        self._stream = stream
-        dumper = XDumper(
-            stream,
-            default_style=self.default_style,
-            default_flow_style=self.default_flow_style,
-            canonical=self.canonical,
-            indent=self.old_indent,
-            width=self.width,
-            allow_unicode=self.allow_unicode,
-            line_break=self.line_break,
-            encoding=self.encoding,
-            explicit_start=self.explicit_start,
-            explicit_end=self.explicit_end,
-            version=self.version,
-            tags=self.tags,
-        )
-        self._emitter = self._serializer = dumper
-        return dumper, dumper, dumper
-
-    # basic types
-    def map(self, **kw: Any) -> Any:
-        if 'rt' in self.typ:
-            return CommentedMap(**kw)
-        else:
-            return dict(**kw)
-
-    def seq(self, *args: Any) -> Any:
-        if 'rt' in self.typ:
-            return CommentedSeq(*args)
-        else:
-            return list(*args)
-
-    # helpers
-    def official_plug_ins(self) -> Any:
-        """search for list of subdirs that are plug-ins, if __file__ is not available, e.g.
-        single file installers that are not properly emulating a file-system (issue 324)
-        no plug-ins will be found. If any are packaged, you know which file that are
-        and you can explicitly provide it during instantiation:
-            yaml = ruamel.yaml.YAML(plug_ins=['ruamel/yaml/jinja2/__plug_in__'])
-        """
-        try:
-            bd = os.path.dirname(__file__)
-        except NameError:
-            return []
-        gpbd = os.path.dirname(os.path.dirname(bd))
-        res = [x.replace(gpbd, "")[1:-3] for x in glob.glob(bd + '/*/__plug_in__.py')]
-        return res
-
-    def register_class(self, cls: Any) -> Any:
-        """
-        register a class for dumping/loading
-        - if it has attribute yaml_tag use that to register, else use class name
-        - if it has methods to_yaml/from_yaml use those to dump/load else dump attributes
-          as mapping
-        """
-        tag = getattr(cls, 'yaml_tag', '!' + cls.__name__)
-        try:
-            self.representer.add_representer(cls, cls.to_yaml)
-        except AttributeError:
-
-            def t_y(representer: Any, data: Any) -> Any:
-                return representer.represent_yaml_object(
-                    tag, data, cls, flow_style=representer.default_flow_style,
-                )
-
-            self.representer.add_representer(cls, t_y)
-        try:
-            self.constructor.add_constructor(tag, cls.from_yaml)
-        except AttributeError:
-
-            def f_y(constructor: Any, node: Any) -> Any:
-                return constructor.construct_yaml_object(node, cls)
-
-            self.constructor.add_constructor(tag, f_y)
-        return cls
-
-    # ### context manager
-
-    def __enter__(self) -> Any:
-        self._context_manager = YAMLContextManager(self)
-        return self
-
-    def __exit__(
-        self,
-        typ: Optional[Type[BaseException]],
-        value: Optional[BaseException],
-        traceback: Optional[TracebackType],
-    ) -> None:
-        if typ:
-            nprint('typ', typ)
-        self._context_manager.teardown_output()
-        # self._context_manager.teardown_input()
-        self._context_manager = None
-
-    # ### backwards compatibility
-    def _indent(self, mapping: Any = None, sequence: Any = None, offset: Any = None) -> None:
-        if mapping is not None:
-            self.map_indent = mapping
-        if sequence is not None:
-            self.sequence_indent = sequence
-        if offset is not None:
-            self.sequence_dash_offset = offset
-
-    @property
-    def version(self) -> Optional[Tuple[int, int]]:
-        return self._version
-
-    @version.setter
-    def version(self, val: VersionType) -> None:
-        if val is None:
-            self._version = val
-            return
-        elif isinstance(val, str):
-            sval = tuple(int(x) for x in val.split('.'))
-        elif isinstance(val, (list, tuple)):
-            sval = tuple(int(x) for x in val)
-        elif isinstance(val, Version):
-            sval = (val.major, val.minor)
-        else:
-            raise TypeError(f'unknown version type {type(val)}')
-        assert len(sval) == 2, f'version can only have major.minor, got {val}'
-        assert sval[0] == 1, f'version major part can only be 1, got {val}'
-        assert sval[1] in [1, 2], f'version minor part can only be 2 or 1, got {val}'
-        self._version = sval
-
-    @property
-    def tags(self) -> Any:
-        return self._tags
-
-    @tags.setter
-    def tags(self, val: Any) -> None:
-        self._tags = val
-
-    @property
-    def indent(self) -> Any:
-        return self._indent
-
-    @indent.setter
-    def indent(self, val: Any) -> None:
-        self.old_indent = val
-
-    @property
-    def block_seq_indent(self) -> Any:
-        return self.sequence_dash_offset
-
-    @block_seq_indent.setter
-    def block_seq_indent(self, val: Any) -> None:
-        self.sequence_dash_offset = val
-
-    def compact(self, seq_seq: Any = None, seq_map: Any = None) -> None:
-        self.compact_seq_seq = seq_seq
-        self.compact_seq_map = seq_map
-
-
-class YAMLContextManager:
-    def __init__(self, yaml: Any, transform: Any = None) -> None:
-        # used to be: (Any, Optional[Callable]) -> None
-        self._yaml = yaml
-        self._output_inited = False
-        self._output_path = None
-        self._output = self._yaml._output
-        self._transform = transform
-
-        # self._input_inited = False
-        # self._input = input
-        # self._input_path = None
-        # self._transform = yaml.transform
-        # self._fstream = None
-
-        if not hasattr(self._output, 'write') and hasattr(self._output, 'open'):
-            # pathlib.Path() instance, open with the same mode
-            self._output_path = self._output
-            self._output = self._output_path.open('w')
-
-        # if not hasattr(self._stream, 'write') and hasattr(stream, 'open'):
-        # if not hasattr(self._input, 'read') and hasattr(self._input, 'open'):
-        #    # pathlib.Path() instance, open with the same mode
-        #    self._input_path = self._input
-        #    self._input = self._input_path.open('r')
-
-        if self._transform is not None:
-            self._fstream = self._output
-            if self._yaml.encoding is None:
-                self._output = StringIO()
-            else:
-                self._output = BytesIO()
-
-    def teardown_output(self) -> None:
-        if self._output_inited:
-            self._yaml.serializer.close()
-        else:
-            return
-        try:
-            self._yaml.emitter.dispose()
-        except AttributeError:
-            raise
-            # self.dumper.dispose()  # cyaml
-        try:
-            delattr(self._yaml, '_serializer')  # NOQA
-            delattr(self._yaml, '_emitter')  # NOQA
-        except AttributeError:
-            raise
-        if self._transform:
-            val = self._output.getvalue()
-            if self._yaml.encoding:
-                val = val.decode(self._yaml.encoding)
-            if self._fstream is None:
-                self._transform(val)
-            else:
-                self._fstream.write(self._transform(val))
-                self._fstream.flush()
-                self._output = self._fstream  # maybe not necessary
-        if self._output_path is not None:
-            self._output.close()
-
-    def init_output(self, first_data: Any) -> None:
-        if self._yaml.top_level_colon_align is True:
-            tlca: Any = max([len(str(x)) for x in first_data])
-        else:
-            tlca = self._yaml.top_level_colon_align
-        self._yaml.get_serializer_representer_emitter(self._output, tlca)
-        self._yaml.serializer.open()
-        self._output_inited = True
-
-    def dump(self, data: Any) -> None:
-        if not self._output_inited:
-            self.init_output(data)
-        try:
-            self._yaml.representer.represent(data)
-        except AttributeError:
-            # nprint(dir(dumper._representer))
-            raise
-
-    # def teardown_input(self):
-    #     pass
-    #
-    # def init_input(self):
-    #     # set the constructor and parser on YAML() instance
-    #     self._yaml.get_constructor_parser(stream)
-    #
-    # def load(self):
-    #     if not self._input_inited:
-    #         self.init_input()
-    #     try:
-    #         while self._yaml.constructor.check_data():
-    #             yield self._yaml.constructor.get_data()
-    #     finally:
-    #         parser.dispose()
-    #         try:
-    #             self._reader.reset_reader()  # type: ignore
-    #         except AttributeError:
-    #             pass
-    #         try:
-    #             self._scanner.reset_scanner()  # type: ignore
-    #         except AttributeError:
-    #             pass
-
-
-def yaml_object(yml: Any) -> Any:
-    """ decorator for classes that needs to dump/load objects
-    The tag for such objects is taken from the class attribute yaml_tag (or the
-    class name in lowercase in case unavailable)
-    If methods to_yaml and/or from_yaml are available, these are called for dumping resp.
-    loading, default routines (dumping a mapping of the attributes) used otherwise.
-    """
-
-    def yo_deco(cls: Any) -> Any:
-        tag = getattr(cls, 'yaml_tag', '!' + cls.__name__)
-        try:
-            yml.representer.add_representer(cls, cls.to_yaml)
-        except AttributeError:
-
-            def t_y(representer: Any, data: Any) -> Any:
-                return representer.represent_yaml_object(
-                    tag, data, cls, flow_style=representer.default_flow_style,
-                )
-
-            yml.representer.add_representer(cls, t_y)
-        try:
-            yml.constructor.add_constructor(tag, cls.from_yaml)
-        except AttributeError:
-
-            def f_y(constructor: Any, node: Any) -> Any:
-                return constructor.construct_yaml_object(node, cls)
-
-            yml.constructor.add_constructor(tag, f_y)
-        return cls
-
-    return yo_deco
-
-
-########################################################################################
-def warn_deprecation(fun: Any, method: Any, arg: str = '') -> None:
-    warnings.warn(
-        f'\n{fun} will be removed, use\n\n  yaml=YAML({arg})\n  yaml.{method}(...)\n\ninstead',  # NOQA
-        PendingDeprecationWarning,  # this will show when testing with pytest/tox
-        stacklevel=3,
-    )
-
-
-def error_deprecation(fun: Any, method: Any, arg: str = '', comment: str = 'instead of') -> None:  # NOQA
-    import inspect
-
-    s = f'\n"{fun}()" has been removed, use\n\n  yaml = YAML({arg})\n  yaml.{method}(...)\n\n{comment}'  # NOQA
-    try:
-        info = inspect.getframeinfo(inspect.stack()[2][0])
-        context = '' if info.code_context is None else "".join(info.code_context)
-        s += f' file "{info.filename}", line {info.lineno}\n\n{context}'
-    except Exception as e:
-        _ = e
-    s += '\n'
-    if sys.version_info < (3, 10):
-        raise AttributeError(s)
-    else:
-        raise AttributeError(s, name=None)
-
-
-_error_dep_arg = "typ='rt'"
-_error_dep_comment = "and register any classes that you use, or check the tag attribute on the loaded data,\ninstead of"  # NOQA
-
-########################################################################################
-
-
-def scan(stream: StreamTextType, Loader: Any = Loader) -> Any:
-    """
-    Scan a YAML stream and produce scanning tokens.
-    """
-    error_deprecation('scan', 'scan', arg=_error_dep_arg, comment=_error_dep_comment)
-
-
-def parse(stream: StreamTextType, Loader: Any = Loader) -> Any:
-    """
-    Parse a YAML stream and produce parsing events.
-    """
-    error_deprecation('parse', 'parse', arg=_error_dep_arg, comment=_error_dep_comment)
-
-
-def compose(stream: StreamTextType, Loader: Any = Loader) -> Any:
-    """
-    Parse the first YAML document in a stream
-    and produce the corresponding representation tree.
-    """
-    error_deprecation('compose', 'compose', arg=_error_dep_arg, comment=_error_dep_comment)
-
-
-def compose_all(stream: StreamTextType, Loader: Any = Loader) -> Any:
-    """
-    Parse all YAML documents in a stream
-    and produce corresponding representation trees.
-    """
-    error_deprecation('compose', 'compose', arg=_error_dep_arg, comment=_error_dep_comment)
-
-
-def load(
-    stream: Any, Loader: Any = None, version: Any = None, preserve_quotes: Any = None,
-) -> Any:
-    """
-    Parse the first YAML document in a stream
-    and produce the corresponding Python object.
-    """
-    error_deprecation('load', 'load', arg=_error_dep_arg, comment=_error_dep_comment)
-
-
-def load_all(
-    stream: Any, Loader: Any = None, version: Any = None, preserve_quotes: Any = None,
-) -> Any:
-    # NOQA
-    """
-    Parse all YAML documents in a stream
-    and produce corresponding Python objects.
-    """
-    error_deprecation('load_all', 'load_all', arg=_error_dep_arg, comment=_error_dep_comment)
-
-
-def safe_load(stream: StreamTextType, version: Optional[VersionType] = None) -> Any:
-    """
-    Parse the first YAML document in a stream
-    and produce the corresponding Python object.
-    Resolve only basic YAML tags.
-    """
-    error_deprecation('safe_load', 'load', arg="typ='safe', pure=True")
-
-
-def safe_load_all(stream: StreamTextType, version: Optional[VersionType] = None) -> Any:
-    """
-    Parse all YAML documents in a stream
-    and produce corresponding Python objects.
-    Resolve only basic YAML tags.
-    """
-    error_deprecation('safe_load_all', 'load_all', arg="typ='safe', pure=True")
-
-
-def round_trip_load(
-    stream: StreamTextType,
-    version: Optional[VersionType] = None,
-    preserve_quotes: Optional[bool] = None,
-) -> Any:
-    """
-    Parse the first YAML document in a stream
-    and produce the corresponding Python object.
-    Resolve only basic YAML tags.
-    """
-    error_deprecation('round_trip_load_all', 'load')
-
-
-def round_trip_load_all(
-    stream: StreamTextType,
-    version: Optional[VersionType] = None,
-    preserve_quotes: Optional[bool] = None,
-) -> Any:
-    """
-    Parse all YAML documents in a stream
-    and produce corresponding Python objects.
-    Resolve only basic YAML tags.
-    """
-    error_deprecation('round_trip_load_all', 'load_all')
-
-
-def emit(
-    events: Any,
-    stream: Optional[StreamType] = None,
-    Dumper: Any = Dumper,
-    canonical: Optional[bool] = None,
-    indent: Union[int, None] = None,
-    width: Optional[int] = None,
-    allow_unicode: Optional[bool] = None,
-    line_break: Any = None,
-) -> Any:
-    # NOQA
-    """
-    Emit YAML parsing events into a stream.
-    If stream is None, return the produced string instead.
-    """
-    error_deprecation('emit', 'emit', arg="typ='safe', pure=True")
-
-
-enc = None
-
-
-def serialize_all(
-    nodes: Any,
-    stream: Optional[StreamType] = None,
-    Dumper: Any = Dumper,
-    canonical: Any = None,
-    indent: Optional[int] = None,
-    width: Optional[int] = None,
-    allow_unicode: Optional[bool] = None,
-    line_break: Any = None,
-    encoding: Any = enc,
-    explicit_start: Optional[bool] = None,
-    explicit_end: Optional[bool] = None,
-    version: Optional[VersionType] = None,
-    tags: Any = None,
-) -> Any:
-    # NOQA
-    """
-    Serialize a sequence of representation trees into a YAML stream.
-    If stream is None, return the produced string instead.
-    """
-    error_deprecation('serialize_all', 'serialize_all', arg="typ='safe', pure=True")
-
-
-def serialize(
-    node: Any, stream: Optional[StreamType] = None, Dumper: Any = Dumper, **kwds: Any,
-) -> Any:
-    """
-    Serialize a representation tree into a YAML stream.
-    If stream is None, return the produced string instead.
-    """
-    error_deprecation('serialize', 'serialize', arg="typ='safe', pure=True")
-
-
-def dump_all(
-    documents: Any,
-    stream: Optional[StreamType] = None,
-    Dumper: Any = Dumper,
-    default_style: Any = None,
-    default_flow_style: Any = None,
-    canonical: Optional[bool] = None,
-    indent: Optional[int] = None,
-    width: Optional[int] = None,
-    allow_unicode: Optional[bool] = None,
-    line_break: Any = None,
-    encoding: Any = enc,
-    explicit_start: Optional[bool] = None,
-    explicit_end: Optional[bool] = None,
-    version: Any = None,
-    tags: Any = None,
-    block_seq_indent: Any = None,
-    top_level_colon_align: Any = None,
-    prefix_colon: Any = None,
-) -> Any:
-    # NOQA
-    """
-    Serialize a sequence of Python objects into a YAML stream.
-    If stream is None, return the produced string instead.
-    """
-    error_deprecation('dump_all', 'dump_all', arg="typ='unsafe', pure=True")
-
-
-def dump(
-    data: Any,
-    stream: Optional[StreamType] = None,
-    Dumper: Any = Dumper,
-    default_style: Any = None,
-    default_flow_style: Any = None,
-    canonical: Optional[bool] = None,
-    indent: Optional[int] = None,
-    width: Optional[int] = None,
-    allow_unicode: Optional[bool] = None,
-    line_break: Any = None,
-    encoding: Any = enc,
-    explicit_start: Optional[bool] = None,
-    explicit_end: Optional[bool] = None,
-    version: Optional[VersionType] = None,
-    tags: Any = None,
-    block_seq_indent: Any = None,
-) -> Any:
-    # NOQA
-    """
-    Serialize a Python object into a YAML stream.
-    If stream is None, return the produced string instead.
-
-    default_style ∈ None, '', '"', "'", '|', '>'
-
-    """
-    error_deprecation('dump', 'dump', arg="typ='unsafe', pure=True")
-
-
-def safe_dump(data: Any, stream: Optional[StreamType] = None, **kwds: Any) -> Any:
-    """
-    Serialize a Python object into a YAML stream.
-    Produce only basic YAML tags.
-    If stream is None, return the produced string instead.
-    """
-    error_deprecation('safe_dump', 'dump', arg="typ='safe', pure=True")
-
-
-def round_trip_dump(
-    data: Any,
-    stream: Optional[StreamType] = None,
-    Dumper: Any = RoundTripDumper,
-    default_style: Any = None,
-    default_flow_style: Any = None,
-    canonical: Optional[bool] = None,
-    indent: Optional[int] = None,
-    width: Optional[int] = None,
-    allow_unicode: Optional[bool] = None,
-    line_break: Any = None,
-    encoding: Any = enc,
-    explicit_start: Optional[bool] = None,
-    explicit_end: Optional[bool] = None,
-    version: Optional[VersionType] = None,
-    tags: Any = None,
-    block_seq_indent: Any = None,
-    top_level_colon_align: Any = None,
-    prefix_colon: Any = None,
-) -> Any:
-    allow_unicode = True if allow_unicode is None else allow_unicode
-    error_deprecation('round_trip_dump', 'dump')
-
-
-# Loader/Dumper are no longer composites, to get to the associated
-# Resolver()/Representer(), etc., you need to instantiate the class
-
-
-def add_implicit_resolver(
-    tag: Any,
-    regexp: Any,
-    first: Any = None,
-    Loader: Any = None,
-    Dumper: Any = None,
-    resolver: Any = Resolver,
-) -> None:
-    """
-    Add an implicit scalar detector.
-    If an implicit scalar value matches the given regexp,
-    the corresponding tag is assigned to the scalar.
-    first is a sequence of possible initial characters or None.
-    """
-    if Loader is None and Dumper is None:
-        resolver.add_implicit_resolver(tag, regexp, first)
-        return
-    if Loader:
-        if hasattr(Loader, 'add_implicit_resolver'):
-            Loader.add_implicit_resolver(tag, regexp, first)
-        elif issubclass(
-            Loader, (BaseLoader, SafeLoader, ruamel.yaml.loader.Loader, RoundTripLoader),
-        ):
-            Resolver.add_implicit_resolver(tag, regexp, first)
-        else:
-            raise NotImplementedError
-    if Dumper:
-        if hasattr(Dumper, 'add_implicit_resolver'):
-            Dumper.add_implicit_resolver(tag, regexp, first)
-        elif issubclass(
-            Dumper, (BaseDumper, SafeDumper, ruamel.yaml.dumper.Dumper, RoundTripDumper),
-        ):
-            Resolver.add_implicit_resolver(tag, regexp, first)
-        else:
-            raise NotImplementedError
-
-
-# this code currently not tested
-def add_path_resolver(
-    tag: Any,
-    path: Any,
-    kind: Any = None,
-    Loader: Any = None,
-    Dumper: Any = None,
-    resolver: Any = Resolver,
-) -> None:
-    """
-    Add a path based resolver for the given tag.
-    A path is a list of keys that forms a path
-    to a node in the representation tree.
-    Keys can be string values, integers, or None.
-    """
-    if Loader is None and Dumper is None:
-        resolver.add_path_resolver(tag, path, kind)
-        return
-    if Loader:
-        if hasattr(Loader, 'add_path_resolver'):
-            Loader.add_path_resolver(tag, path, kind)
-        elif issubclass(
-            Loader, (BaseLoader, SafeLoader, ruamel.yaml.loader.Loader, RoundTripLoader),
-        ):
-            Resolver.add_path_resolver(tag, path, kind)
-        else:
-            raise NotImplementedError
-    if Dumper:
-        if hasattr(Dumper, 'add_path_resolver'):
-            Dumper.add_path_resolver(tag, path, kind)
-        elif issubclass(
-            Dumper, (BaseDumper, SafeDumper, ruamel.yaml.dumper.Dumper, RoundTripDumper),
-        ):
-            Resolver.add_path_resolver(tag, path, kind)
-        else:
-            raise NotImplementedError
-
-
-def add_constructor(
-    tag: Any, object_constructor: Any, Loader: Any = None, constructor: Any = Constructor,
-) -> None:
-    """
-    Add an object constructor for the given tag.
-    object_onstructor is a function that accepts a Loader instance
-    and a node object and produces the corresponding Python object.
-    """
-    if Loader is None:
-        constructor.add_constructor(tag, object_constructor)
-    else:
-        if hasattr(Loader, 'add_constructor'):
-            Loader.add_constructor(tag, object_constructor)
-            return
-        if issubclass(Loader, BaseLoader):
-            BaseConstructor.add_constructor(tag, object_constructor)
-        elif issubclass(Loader, SafeLoader):
-            SafeConstructor.add_constructor(tag, object_constructor)
-        elif issubclass(Loader, Loader):
-            Constructor.add_constructor(tag, object_constructor)
-        elif issubclass(Loader, RoundTripLoader):
-            RoundTripConstructor.add_constructor(tag, object_constructor)
-        else:
-            raise NotImplementedError
-
-
-def add_multi_constructor(
-    tag_prefix: Any, multi_constructor: Any, Loader: Any = None, constructor: Any = Constructor,  # NOQA
-) -> None:
-    """
-    Add a multi-constructor for the given tag prefix.
-    Multi-constructor is called for a node if its tag starts with tag_prefix.
-    Multi-constructor accepts a Loader instance, a tag suffix,
-    and a node object and produces the corresponding Python object.
-    """
-    if Loader is None:
-        constructor.add_multi_constructor(tag_prefix, multi_constructor)
-    else:
-        if False and hasattr(Loader, 'add_multi_constructor'):
-            Loader.add_multi_constructor(tag_prefix, constructor)
-            return
-        if issubclass(Loader, BaseLoader):
-            BaseConstructor.add_multi_constructor(tag_prefix, multi_constructor)
-        elif issubclass(Loader, SafeLoader):
-            SafeConstructor.add_multi_constructor(tag_prefix, multi_constructor)
-        elif issubclass(Loader, ruamel.yaml.loader.Loader):
-            Constructor.add_multi_constructor(tag_prefix, multi_constructor)
-        elif issubclass(Loader, RoundTripLoader):
-            RoundTripConstructor.add_multi_constructor(tag_prefix, multi_constructor)
-        else:
-            raise NotImplementedError
-
-
-def add_representer(
-    data_type: Any, object_representer: Any, Dumper: Any = None, representer: Any = Representer,  # NOQA
-) -> None:
-    """
-    Add a representer for the given type.
-    object_representer is a function accepting a Dumper instance
-    and an instance of the given data type
-    and producing the corresponding representation node.
-    """
-    if Dumper is None:
-        representer.add_representer(data_type, object_representer)
-    else:
-        if hasattr(Dumper, 'add_representer'):
-            Dumper.add_representer(data_type, object_representer)
-            return
-        if issubclass(Dumper, BaseDumper):
-            BaseRepresenter.add_representer(data_type, object_representer)
-        elif issubclass(Dumper, SafeDumper):
-            SafeRepresenter.add_representer(data_type, object_representer)
-        elif issubclass(Dumper, Dumper):
-            Representer.add_representer(data_type, object_representer)
-        elif issubclass(Dumper, RoundTripDumper):
-            RoundTripRepresenter.add_representer(data_type, object_representer)
-        else:
-            raise NotImplementedError
-
-
-# this code currently not tested
-def add_multi_representer(
-    data_type: Any, multi_representer: Any, Dumper: Any = None, representer: Any = Representer,
-) -> None:
-    """
-    Add a representer for the given type.
-    multi_representer is a function accepting a Dumper instance
-    and an instance of the given data type or subtype
-    and producing the corresponding representation node.
-    """
-    if Dumper is None:
-        representer.add_multi_representer(data_type, multi_representer)
-    else:
-        if hasattr(Dumper, 'add_multi_representer'):
-            Dumper.add_multi_representer(data_type, multi_representer)
-            return
-        if issubclass(Dumper, BaseDumper):
-            BaseRepresenter.add_multi_representer(data_type, multi_representer)
-        elif issubclass(Dumper, SafeDumper):
-            SafeRepresenter.add_multi_representer(data_type, multi_representer)
-        elif issubclass(Dumper, Dumper):
-            Representer.add_multi_representer(data_type, multi_representer)
-        elif issubclass(Dumper, RoundTripDumper):
-            RoundTripRepresenter.add_multi_representer(data_type, multi_representer)
-        else:
-            raise NotImplementedError
-
-
-class YAMLObjectMetaclass(type):
-    """
-    The metaclass for YAMLObject.
-    """
-
-    def __init__(cls, name: Any, bases: Any, kwds: Any) -> None:
-        super().__init__(name, bases, kwds)
-        if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
-            cls.yaml_constructor.add_constructor(cls.yaml_tag, cls.from_yaml)  # type: ignore
-            cls.yaml_representer.add_representer(cls, cls.to_yaml)  # type: ignore
-
-
-class YAMLObject(with_metaclass(YAMLObjectMetaclass)):  # type: ignore
-    """
-    An object that can dump itself to a YAML stream
-    and load itself from a YAML stream.
-    """
-
-    __slots__ = ()  # no direct instantiation, so allow immutable subclasses
-
-    yaml_constructor = Constructor
-    yaml_representer = Representer
-
-    yaml_tag: Any = None
-    yaml_flow_style: Any = None
-
-    @classmethod
-    def from_yaml(cls, constructor: Any, node: Any) -> Any:
-        """
-        Convert a representation node to a Python object.
-        """
-        return constructor.construct_yaml_object(node, cls)
-
-    @classmethod
-    def to_yaml(cls, representer: Any, data: Any) -> Any:
-        """
-        Convert a Python object to a representation node.
-        """
-        return representer.represent_yaml_object(
-            cls.yaml_tag, data, cls, flow_style=cls.yaml_flow_style,
-        )
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py
deleted file mode 100644
index 742d9dab23a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/mergevalue.py
+++ /dev/null
@@ -1,39 +0,0 @@
-
-from __future__ import annotations
-
-if False:  # MYPY
-    from typing import Any, Dict, List, Union, Optional, Iterator  # NOQA
-
-
-merge_attrib = '_yaml_merge'
-
-
-class MergeValue:
-    attrib = merge_attrib
-
-    def __init__(self) -> None:
-        self.value: List[Any] = []
-        self.sequence = None
-        self.merge_pos: Optional[int] = None  # position of merge in the mapping
-
-    def __getitem__(self, index: Any) -> Any:
-        return self.value[index]
-
-    def __setitem__(self, index: Any, val: Any) -> None:
-        self.value[index] = val
-
-    def __repr__(self) -> Any:
-        return f'MergeValue({self.value!r})'
-
-    def __len__(self) -> Any:
-        return len(self.value)
-
-    def append(self, elem: Any) -> Any:
-        self.value.append(elem)
-
-    def extend(self, elements: Any) -> None:
-        self.value.extend(elements)
-
-    def set_sequence(self, seq: Any) -> None:
-        # print('mergevalue.set_sequence node', node.anchor)
-        self.sequence = seq
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py
deleted file mode 100644
index fb6d60fed68..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/nodes.py
+++ /dev/null
@@ -1,149 +0,0 @@
-
-from __future__ import annotations
-
-import sys
-
-if False:  # MYPY
-    from typing import Dict, Any, Text, Optional  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
-
-
-class Node:
-    __slots__ = 'ctag', 'value', 'start_mark', 'end_mark', 'comment', 'anchor'
-
-    def __init__(
-        self,
-        tag: Any,
-        value: Any,
-        start_mark: Any,
-        end_mark: Any,
-        comment: Any = None,
-        anchor: Any = None,
-    ) -> None:
-        # you can still get a string from the serializer
-        self.ctag = tag if isinstance(tag, Tag) else Tag(suffix=tag)
-        self.value = value
-        self.start_mark = start_mark
-        self.end_mark = end_mark
-        self.comment = comment
-        self.anchor = anchor
-
-    @property
-    def tag(self) -> Optional[str]:
-        return None if self.ctag is None else str(self.ctag)
-
-    @tag.setter
-    def tag(self, val: Any) -> None:
-        if isinstance(val, str):
-            val = Tag(suffix=val)
-        self.ctag = val
-
-    def __repr__(self) -> Any:
-        value = self.value
-        # if isinstance(value, list):
-        #     if len(value) == 0:
-        #         value = ''
-        #     elif len(value) == 1:
-        #         value = '<1 item>'
-        #     else:
-        #         value = f'<{len(value)} items>'
-        # else:
-        #     if len(value) > 75:
-        #         value = repr(value[:70]+' ... ')
-        #     else:
-        #         value = repr(value)
-        value = repr(value)
-        if self.anchor is not None:
-            return f'{self.__class__.__name__!s}(tag={self.tag!r}, anchor={self.anchor!r}, value={value!s})'  # NOQA
-        return f'{self.__class__.__name__!s}(tag={self.tag!r}, value={value!s})'
-
-    def dump(self, indent: int = 0) -> None:
-        xx = self.__class__.__name__
-        xi = '  ' * indent
-        if isinstance(self.value, str):
-            sys.stdout.write(f'{xi}{xx}(tag={self.tag!r}, value={self.value!r})\n')
-            if self.comment:
-                sys.stdout.write(f'    {xi}comment: {self.comment})\n')
-            return
-        sys.stdout.write(f'{xi}{xx}(tag={self.tag!r})\n')
-        if self.comment:
-            sys.stdout.write(f'    {xi}comment: {self.comment})\n')
-        for v in self.value:
-            if isinstance(v, tuple):
-                for v1 in v:
-                    v1.dump(indent + 1)
-            elif isinstance(v, Node):
-                v.dump(indent + 1)
-            else:
-                sys.stdout.write(f'Node value type? {type(v)}\n')
-
-
-class ScalarNode(Node):
-    """
-    styles:
-      ? -> set() ? key, no value
-      - -> suppressable null value in set
-      " -> double quoted
-      ' -> single quoted
-      | -> literal style
-      > -> folding style
-    """
-
-    __slots__ = ('style',)
-    id = 'scalar'
-
-    def __init__(
-        self,
-        tag: Any,
-        value: Any,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        style: Any = None,
-        comment: Any = None,
-        anchor: Any = None,
-    ) -> None:
-        Node.__init__(self, tag, value, start_mark, end_mark, comment=comment, anchor=anchor)
-        self.style = style
-
-
-class CollectionNode(Node):
-    __slots__ = ('flow_style',)
-
-    def __init__(
-        self,
-        tag: Any,
-        value: Any,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        flow_style: Any = None,
-        comment: Any = None,
-        anchor: Any = None,
-    ) -> None:
-        Node.__init__(self, tag, value, start_mark, end_mark, comment=comment)
-        self.flow_style = flow_style
-        self.anchor = anchor
-
-
-class SequenceNode(CollectionNode):
-    __slots__ = ()
-    id = 'sequence'
-
-
-class MappingNode(CollectionNode):
-    __slots__ = ('merge',)
-    id = 'mapping'
-
-    def __init__(
-        self,
-        tag: Any,
-        value: Any,
-        start_mark: Any = None,
-        end_mark: Any = None,
-        flow_style: Any = None,
-        comment: Any = None,
-        anchor: Any = None,
-    ) -> None:
-        CollectionNode.__init__(
-            self, tag, value, start_mark, end_mark, flow_style, comment, anchor,
-        )
-        self.merge = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py
deleted file mode 100644
index 06c43c3a1aa..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/parser.py
+++ /dev/null
@@ -1,862 +0,0 @@
-
-from __future__ import annotations
-
-# The following YAML grammar is LL(1) and is parsed by a recursive descent
-# parser.
-#
-# stream            ::= STREAM-START implicit_document? explicit_document*
-#                                                                   STREAM-END
-# implicit_document ::= block_node DOCUMENT-END*
-# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-# block_node_or_indentless_sequence ::=
-#                       ALIAS
-#                       | properties (block_content |
-#                                                   indentless_block_sequence)?
-#                       | block_content
-#                       | indentless_block_sequence
-# block_node        ::= ALIAS
-#                       | properties block_content?
-#                       | block_content
-# flow_node         ::= ALIAS
-#                       | properties flow_content?
-#                       | flow_content
-# properties        ::= TAG ANCHOR? | ANCHOR TAG?
-# block_content     ::= block_collection | flow_collection | SCALAR
-# flow_content      ::= flow_collection | SCALAR
-# block_collection  ::= block_sequence | block_mapping
-# flow_collection   ::= flow_sequence | flow_mapping
-# block_sequence    ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)*
-#                                                                   BLOCK-END
-# indentless_sequence   ::= (BLOCK-ENTRY block_node?)+
-# block_mapping     ::= BLOCK-MAPPING_START
-#                       ((KEY block_node_or_indentless_sequence?)?
-#                       (VALUE block_node_or_indentless_sequence?)?)*
-#                       BLOCK-END
-# flow_sequence     ::= FLOW-SEQUENCE-START
-#                       (flow_sequence_entry FLOW-ENTRY)*
-#                       flow_sequence_entry?
-#                       FLOW-SEQUENCE-END
-# flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-# flow_mapping      ::= FLOW-MAPPING-START
-#                       (flow_mapping_entry FLOW-ENTRY)*
-#                       flow_mapping_entry?
-#                       FLOW-MAPPING-END
-# flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-#
-# FIRST sets:
-#
-# stream: { STREAM-START <}
-# explicit_document: { DIRECTIVE DOCUMENT-START }
-# implicit_document: FIRST(block_node)
-# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START
-#                  BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START }
-# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START }
-# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START
-#                               FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
-# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
-# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START }
-# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
-# block_sequence: { BLOCK-SEQUENCE-START }
-# block_mapping: { BLOCK-MAPPING-START }
-# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR
-#               BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START
-#               FLOW-MAPPING-START BLOCK-ENTRY }
-# indentless_sequence: { ENTRY }
-# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
-# flow_sequence: { FLOW-SEQUENCE-START }
-# flow_mapping: { FLOW-MAPPING-START }
-# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START
-#                                                    FLOW-MAPPING-START KEY }
-# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START
-#                                                    FLOW-MAPPING-START KEY }
-
-# need to have full path with import, as pkg_resources tries to load parser.py in __init__.py
-# only to not do anything with the package afterwards
-# and for Jython too
-
-
-from opentelemetry.agent._vendor.ruamel.yaml.error import MarkedYAMLError
-from opentelemetry.agent._vendor.ruamel.yaml.tokens import *  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.events import *  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.scanner import Scanner, RoundTripScanner, ScannerError  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.scanner import BlankLineComment
-from opentelemetry.agent._vendor.ruamel.yaml.comments import C_PRE, C_POST, C_SPLIT_ON_FIRST_BLANK
-from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, nprintf  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Optional  # NOQA
-
-__all__ = ['Parser', 'RoundTripParser', 'ParserError']
-
-
-def xprintf(*args: Any, **kw: Any) -> Any:
-    return nprintf(*args, **kw)
-    pass
-
-
-class ParserError(MarkedYAMLError):
-    pass
-
-
-class Parser:
-    # Since writing a recursive-descendant parser is a straightforward task, we
-    # do not give many comments here.
-
-    DEFAULT_TAGS = {'!': '!', '!!': 'tag:yaml.org,2002:'}
-
-    def __init__(self, loader: Any) -> None:
-        self.loader = loader
-        if self.loader is not None and getattr(self.loader, '_parser', None) is None:
-            self.loader._parser = self
-        self.reset_parser()
-
-    def reset_parser(self) -> None:
-        # Reset the state attributes (to clear self-references)
-        self.current_event = self.last_event = None
-        self.tag_handles: Dict[Any, Any] = {}
-        self.states: List[Any] = []
-        self.marks: List[Any] = []
-        self.state: Any = self.parse_stream_start
-
-    def dispose(self) -> None:
-        self.reset_parser()
-
-    @property
-    def scanner(self) -> Any:
-        if hasattr(self.loader, 'typ'):
-            return self.loader.scanner
-        return self.loader._scanner
-
-    @property
-    def resolver(self) -> Any:
-        if hasattr(self.loader, 'typ'):
-            return self.loader.resolver
-        return self.loader._resolver
-
-    def check_event(self, *choices: Any) -> bool:
-        # Check the type of the next event.
-        if self.current_event is None:
-            if self.state:
-                self.current_event = self.state()
-        if self.current_event is not None:
-            if not choices:
-                return True
-            for choice in choices:
-                if isinstance(self.current_event, choice):
-                    return True
-        return False
-
-    def peek_event(self) -> Any:
-        # Get the next event.
-        if self.current_event is None:
-            if self.state:
-                self.current_event = self.state()
-        return self.current_event
-
-    def get_event(self) -> Any:
-        # Get the next event and proceed further.
-        if self.current_event is None:
-            if self.state:
-                self.current_event = self.state()
-        # assert self.current_event is not None
-        # if self.current_event.end_mark.line != self.peek_event().start_mark.line:
-        # xprintf('get_event', repr(self.current_event), self.peek_event().start_mark.line)
-        self.last_event = value = self.current_event
-        self.current_event = None
-        return value
-
-    # stream    ::= STREAM-START implicit_document? explicit_document*
-    #                                                               STREAM-END
-    # implicit_document ::= block_node DOCUMENT-END*
-    # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
-
-    def parse_stream_start(self) -> Any:
-        # Parse the stream start.
-        token = self.scanner.get_token()
-        self.move_token_comment(token)
-        event = StreamStartEvent(token.start_mark, token.end_mark, encoding=token.encoding)
-
-        # Prepare the next state.
-        self.state = self.parse_implicit_document_start
-
-        return event
-
-    def parse_implicit_document_start(self) -> Any:
-        # Parse an implicit document.
-        if not self.scanner.check_token(DirectiveToken, DocumentStartToken, StreamEndToken):
-            # don't need copy, as an implicit tag doesn't add tag_handles
-            self.tag_handles = self.DEFAULT_TAGS
-            token = self.scanner.peek_token()
-            start_mark = end_mark = token.start_mark
-            event = DocumentStartEvent(start_mark, end_mark, explicit=False)
-
-            # Prepare the next state.
-            self.states.append(self.parse_document_end)
-            self.state = self.parse_block_node
-
-            return event
-
-        else:
-            return self.parse_document_start()
-
-    def parse_document_start(self) -> Any:
-        # Parse any extra document end indicators.
-        while self.scanner.check_token(DocumentEndToken):
-            self.scanner.get_token()
-        # Parse an explicit document.
-        if not self.scanner.check_token(StreamEndToken):
-            version, tags = self.process_directives()
-            if not self.scanner.check_token(DocumentStartToken):
-                raise ParserError(
-                    None,
-                    None,
-                    "expected '', "
-                    f'but found {self.scanner.peek_token().id,!r}',
-                    self.scanner.peek_token().start_mark,
-                )
-            token = self.scanner.get_token()
-            start_mark = token.start_mark
-            end_mark = token.end_mark
-            # if self.loader is not None and \
-            #    end_mark.line != self.scanner.peek_token().start_mark.line:
-            #     self.loader.scalar_after_indicator = False
-            event: Any = DocumentStartEvent(
-                start_mark,
-                end_mark,
-                explicit=True,
-                version=version,
-                tags=tags,
-                comment=token.comment,
-            )
-            self.states.append(self.parse_document_end)
-            self.state = self.parse_document_content
-        else:
-            # Parse the end of the stream.
-            token = self.scanner.get_token()
-            event = StreamEndEvent(token.start_mark, token.end_mark, comment=token.comment)
-            assert not self.states
-            assert not self.marks
-            self.state = None
-        return event
-
-    def parse_document_end(self) -> Any:
-        # Parse the document end.
-        token = self.scanner.peek_token()
-        start_mark = end_mark = token.start_mark
-        explicit = False
-        if self.scanner.check_token(DocumentEndToken):
-            token = self.scanner.get_token()
-            # if token.end_mark.line != self.peek_event().start_mark.line:
-            pt = self.scanner.peek_token()
-            if not isinstance(pt, StreamEndToken) and (
-                token.end_mark.line == pt.start_mark.line
-            ):
-                raise ParserError(
-                    None,
-                    None,
-                    'found non-comment content after document end marker, '
-                    f'{self.scanner.peek_token().id,!r}',
-                    self.scanner.peek_token().start_mark,
-                )
-            end_mark = token.end_mark
-            explicit = True
-        event = DocumentEndEvent(start_mark, end_mark, explicit=explicit)
-
-        # Prepare the next state.
-        if self.resolver.processing_version == (1, 1):
-            self.state = self.parse_document_start
-        else:
-            if explicit:
-                # found a document end marker, can be followed by implicit document
-                self.state = self.parse_implicit_document_start
-            else:
-                self.state = self.parse_document_start
-
-        return event
-
-    def parse_document_content(self) -> Any:
-        if self.scanner.check_token(
-            DirectiveToken, DocumentStartToken, DocumentEndToken, StreamEndToken,
-        ):
-            event = self.process_empty_scalar(self.scanner.peek_token().start_mark)
-            self.state = self.states.pop()
-            return event
-        else:
-            return self.parse_block_node()
-
-    def process_directives(self) -> Any:
-        yaml_version = None
-        self.tag_handles = {}
-        while self.scanner.check_token(DirectiveToken):
-            token = self.scanner.get_token()
-            if token.name == 'YAML':
-                if yaml_version is not None:
-                    raise ParserError(
-                        None, None, 'found duplicate YAML directive', token.start_mark,
-                    )
-                major, minor = token.value
-                if major != 1:
-                    raise ParserError(
-                        None,
-                        None,
-                        'found incompatible YAML document (version 1.* is required)',
-                        token.start_mark,
-                    )
-                yaml_version = token.value
-            elif token.name == 'TAG':
-                handle, prefix = token.value
-                if handle in self.tag_handles:
-                    raise ParserError(
-                        None, None, f'duplicate tag handle {handle!r}', token.start_mark,
-                    )
-                self.tag_handles[handle] = prefix
-        if bool(self.tag_handles):
-            value: Any = (yaml_version, self.tag_handles.copy())
-        else:
-            value = yaml_version, None
-        if self.loader is not None and hasattr(self.loader, 'tags'):
-            # ToDo: this is used to keep a single loaded file from losing its version
-            # info, but  it affects following versions that have no explicit directive
-            self.loader.version = yaml_version
-            if self.loader.tags is None:
-                self.loader.tags = {}
-            for k in self.tag_handles:
-                self.loader.tags[k] = self.tag_handles[k]
-                self.loader.doc_infos[-1].tags.append((k, self.tag_handles[k]))
-        for key in self.DEFAULT_TAGS:
-            if key not in self.tag_handles:
-                self.tag_handles[key] = self.DEFAULT_TAGS[key]
-        return value
-
-    # block_node_or_indentless_sequence ::= ALIAS
-    #               | properties (block_content | indentless_block_sequence)?
-    #               | block_content
-    #               | indentless_block_sequence
-    # block_node    ::= ALIAS
-    #                   | properties block_content?
-    #                   | block_content
-    # flow_node     ::= ALIAS
-    #                   | properties flow_content?
-    #                   | flow_content
-    # properties    ::= TAG ANCHOR? | ANCHOR TAG?
-    # block_content     ::= block_collection | flow_collection | SCALAR
-    # flow_content      ::= flow_collection | SCALAR
-    # block_collection  ::= block_sequence | block_mapping
-    # flow_collection   ::= flow_sequence | flow_mapping
-
-    def parse_block_node(self) -> Any:
-        return self.parse_node(block=True)
-
-    def parse_flow_node(self) -> Any:
-        return self.parse_node()
-
-    def parse_block_node_or_indentless_sequence(self) -> Any:
-        return self.parse_node(block=True, indentless_sequence=True)
-
-    # def transform_tag(self, handle: Any, suffix: Any) -> Any:
-    #     return self.tag_handles[handle] + suffix
-
-    def select_tag_transform(self, tag: Tag) -> None:
-        if tag is None:
-            return
-        tag.select_transform(False)
-
-    def parse_node(self, block: bool = False, indentless_sequence: bool = False) -> Any:
-        if self.scanner.check_token(AliasToken):
-            token = self.scanner.get_token()
-            event: Any = AliasEvent(token.value, token.start_mark, token.end_mark)
-            self.state = self.states.pop()
-            return event
-
-        anchor = None
-        tag = None
-        start_mark = end_mark = tag_mark = None
-        if self.scanner.check_token(AnchorToken):
-            token = self.scanner.get_token()
-            self.move_token_comment(token)
-            start_mark = token.start_mark
-            end_mark = token.end_mark
-            anchor = token.value
-            if self.scanner.check_token(TagToken):
-                token = self.scanner.get_token()
-                tag_mark = token.start_mark
-                end_mark = token.end_mark
-                # tag = token.value
-                tag = Tag(
-                    handle=token.value[0], suffix=token.value[1], handles=self.tag_handles,
-                )
-        elif self.scanner.check_token(TagToken):
-            token = self.scanner.get_token()
-            try:
-                self.move_token_comment(token)
-            except NotImplementedError:
-                pass
-            start_mark = tag_mark = token.start_mark
-            end_mark = token.end_mark
-            # tag = token.value
-            tag = Tag(handle=token.value[0], suffix=token.value[1], handles=self.tag_handles)
-            if self.scanner.check_token(AnchorToken):
-                token = self.scanner.get_token()
-                start_mark = tag_mark = token.start_mark
-                end_mark = token.end_mark
-                anchor = token.value
-        if tag is not None:
-            self.select_tag_transform(tag)
-            if tag.check_handle():
-                raise ParserError(
-                    'while parsing a node',
-                    start_mark,
-                    f'found undefined tag handle {tag.handle!r}',
-                    tag_mark,
-                )
-        if start_mark is None:
-            start_mark = end_mark = self.scanner.peek_token().start_mark
-        event = None
-        implicit = tag is None or str(tag) == '!'
-        if indentless_sequence and self.scanner.check_token(BlockEntryToken):
-            comment = None
-            pt = self.scanner.peek_token()
-            if self.loader and self.loader.comment_handling is None:
-                if pt.comment and pt.comment[0]:
-                    comment = [pt.comment[0], []]
-                    pt.comment[0] = None
-                elif pt.comment and pt.comment[0] is None and pt.comment[1]:
-                    comment = [None, pt.comment[1]]
-                    pt.comment[1] = None
-            elif self.loader:
-                if pt.comment:
-                    comment = pt.comment
-            end_mark = self.scanner.peek_token().end_mark
-            event = SequenceStartEvent(
-                anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment,
-            )
-            self.state = self.parse_indentless_sequence_entry
-            return event
-
-        if self.scanner.check_token(ScalarToken):
-            token = self.scanner.get_token()
-            # self.scanner.peek_token_same_line_comment(token)
-            end_mark = token.end_mark
-            if (token.plain and tag is None) or str(tag) == '!':
-                dimplicit = (True, False)
-            elif tag is None:
-                dimplicit = (False, True)
-            else:
-                dimplicit = (False, False)
-            event = ScalarEvent(
-                anchor,
-                tag,
-                dimplicit,
-                token.value,
-                start_mark,
-                end_mark,
-                style=token.style,
-                comment=token.comment,
-            )
-            self.state = self.states.pop()
-        elif self.scanner.check_token(FlowSequenceStartToken):
-            pt = self.scanner.peek_token()
-            end_mark = pt.end_mark
-            event = SequenceStartEvent(
-                anchor,
-                tag,
-                implicit,
-                start_mark,
-                end_mark,
-                flow_style=True,
-                comment=pt.comment,
-            )
-            self.state = self.parse_flow_sequence_first_entry
-        elif self.scanner.check_token(FlowMappingStartToken):
-            pt = self.scanner.peek_token()
-            end_mark = pt.end_mark
-            event = MappingStartEvent(
-                anchor,
-                tag,
-                implicit,
-                start_mark,
-                end_mark,
-                flow_style=True,
-                comment=pt.comment,
-            )
-            self.state = self.parse_flow_mapping_first_key
-        elif block and self.scanner.check_token(BlockSequenceStartToken):
-            end_mark = self.scanner.peek_token().start_mark
-            # should inserting the comment be dependent on the
-            # indentation?
-            pt = self.scanner.peek_token()
-            comment = pt.comment
-            # nprint('pt0', type(pt))
-            if comment is None or comment[1] is None:
-                comment = pt.split_old_comment()
-            # nprint('pt1', comment)
-            event = SequenceStartEvent(
-                anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment,
-            )
-            self.state = self.parse_block_sequence_first_entry
-        elif block and self.scanner.check_token(BlockMappingStartToken):
-            end_mark = self.scanner.peek_token().start_mark
-            comment = self.scanner.peek_token().comment
-            event = MappingStartEvent(
-                anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment,
-            )
-            self.state = self.parse_block_mapping_first_key
-        elif anchor is not None or tag is not None:
-            # Empty scalars are allowed even if a tag or an anchor is
-            # specified.
-            event = ScalarEvent(anchor, tag, (implicit, False), "", start_mark, end_mark)
-            self.state = self.states.pop()
-        else:
-            if block:
-                node = 'block'
-            else:
-                node = 'flow'
-            token = self.scanner.peek_token()
-            raise ParserError(
-                f'while parsing a {node!s} node',
-                start_mark,
-                f'expected the node content, but found {token.id!r}',
-                token.start_mark,
-            )
-        return event
-
-    # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)*
-    #                                                               BLOCK-END
-
-    def parse_block_sequence_first_entry(self) -> Any:
-        token = self.scanner.get_token()
-        # move any comment from start token
-        # self.move_token_comment(token)
-        self.marks.append(token.start_mark)
-        return self.parse_block_sequence_entry()
-
-    def parse_block_sequence_entry(self) -> Any:
-        if self.scanner.check_token(BlockEntryToken):
-            token = self.scanner.get_token()
-            self.move_token_comment(token)
-            if not self.scanner.check_token(BlockEntryToken, BlockEndToken):
-                self.states.append(self.parse_block_sequence_entry)
-                return self.parse_block_node()
-            else:
-                self.state = self.parse_block_sequence_entry
-                return self.process_empty_scalar(token.end_mark)
-        if not self.scanner.check_token(BlockEndToken):
-            token = self.scanner.peek_token()
-            raise ParserError(
-                'while parsing a block collection',
-                self.marks[-1],
-                f'expected , but found {token.id!r}',
-                token.start_mark,
-            )
-        token = self.scanner.get_token()  # BlockEndToken
-        event = SequenceEndEvent(token.start_mark, token.end_mark, comment=token.comment)
-        self.state = self.states.pop()
-        self.marks.pop()
-        return event
-
-    # indentless_sequence ::= (BLOCK-ENTRY block_node?)+
-
-    # indentless_sequence?
-    # sequence:
-    # - entry
-    #  - nested
-
-    def parse_indentless_sequence_entry(self) -> Any:
-        if self.scanner.check_token(BlockEntryToken):
-            token = self.scanner.get_token()
-            self.move_token_comment(token)
-            if not self.scanner.check_token(
-                BlockEntryToken, KeyToken, ValueToken, BlockEndToken,
-            ):
-                self.states.append(self.parse_indentless_sequence_entry)
-                return self.parse_block_node()
-            else:
-                self.state = self.parse_indentless_sequence_entry
-                return self.process_empty_scalar(token.end_mark)
-        token = self.scanner.peek_token()
-        c = None
-        if self.loader and self.loader.comment_handling is None:
-            c = token.comment
-            start_mark = token.start_mark
-        else:
-            start_mark = self.last_event.end_mark  # type: ignore
-            c = self.distribute_comment(token.comment, start_mark.line)  # type: ignore
-        event = SequenceEndEvent(start_mark, start_mark, comment=c)
-        self.state = self.states.pop()
-        return event
-
-    # block_mapping     ::= BLOCK-MAPPING_START
-    #                       ((KEY block_node_or_indentless_sequence?)?
-    #                       (VALUE block_node_or_indentless_sequence?)?)*
-    #                       BLOCK-END
-
-    def parse_block_mapping_first_key(self) -> Any:
-        token = self.scanner.get_token()
-        self.marks.append(token.start_mark)
-        return self.parse_block_mapping_key()
-
-    def parse_block_mapping_key(self) -> Any:
-        if self.scanner.check_token(KeyToken):
-            token = self.scanner.get_token()
-            self.move_token_comment(token)
-            if not self.scanner.check_token(KeyToken, ValueToken, BlockEndToken):
-                self.states.append(self.parse_block_mapping_value)
-                return self.parse_block_node_or_indentless_sequence()
-            else:
-                self.state = self.parse_block_mapping_value
-                return self.process_empty_scalar(token.end_mark)
-        if self.resolver.processing_version > (1, 1) and self.scanner.check_token(ValueToken):
-            self.state = self.parse_block_mapping_value
-            return self.process_empty_scalar(self.scanner.peek_token().start_mark)
-        if not self.scanner.check_token(BlockEndToken):
-            token = self.scanner.peek_token()
-            raise ParserError(
-                'while parsing a block mapping',
-                self.marks[-1],
-                f'expected , but found {token.id!r}',
-                token.start_mark,
-            )
-        token = self.scanner.get_token()
-        self.move_token_comment(token)
-        event = MappingEndEvent(token.start_mark, token.end_mark, comment=token.comment)
-        self.state = self.states.pop()
-        self.marks.pop()
-        return event
-
-    def parse_block_mapping_value(self) -> Any:
-        if self.scanner.check_token(ValueToken):
-            token = self.scanner.get_token()
-            # value token might have post comment move it to e.g. block
-            if self.scanner.check_token(ValueToken):
-                self.move_token_comment(token)
-            else:
-                if not self.scanner.check_token(KeyToken):
-                    self.move_token_comment(token, empty=True)
-                # else: empty value for this key cannot move token.comment
-            if not self.scanner.check_token(KeyToken, ValueToken, BlockEndToken):
-                self.states.append(self.parse_block_mapping_key)
-                return self.parse_block_node_or_indentless_sequence()
-            else:
-                self.state = self.parse_block_mapping_key
-                comment = token.comment
-                if comment is None:
-                    token = self.scanner.peek_token()
-                    comment = token.comment
-                    if comment:
-                        token._comment = [None, comment[1]]
-                        comment = [comment[0], None]
-                return self.process_empty_scalar(token.end_mark, comment=comment)
-        else:
-            self.state = self.parse_block_mapping_key
-            token = self.scanner.peek_token()
-            return self.process_empty_scalar(token.start_mark)
-
-    # flow_sequence     ::= FLOW-SEQUENCE-START
-    #                       (flow_sequence_entry FLOW-ENTRY)*
-    #                       flow_sequence_entry?
-    #                       FLOW-SEQUENCE-END
-    # flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-    #
-    # Note that while production rules for both flow_sequence_entry and
-    # flow_mapping_entry are equal, their interpretations are different.
-    # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?`
-    # generate an inline mapping (set syntax).
-
-    def parse_flow_sequence_first_entry(self) -> Any:
-        token = self.scanner.get_token()
-        self.marks.append(token.start_mark)
-        return self.parse_flow_sequence_entry(first=True)
-
-    def parse_flow_sequence_entry(self, first: bool = False) -> Any:
-        if not self.scanner.check_token(FlowSequenceEndToken):
-            if not first:
-                if self.scanner.check_token(FlowEntryToken):
-                    self.scanner.get_token()
-                else:
-                    token = self.scanner.peek_token()
-                    raise ParserError(
-                        'while parsing a flow sequence',
-                        self.marks[-1],
-                        f"expected ',' or ']', but got {token.id!r}",
-                        token.start_mark,
-                    )
-
-            if self.scanner.check_token(KeyToken):
-                token = self.scanner.peek_token()
-                event: Any = MappingStartEvent(
-                    None, None, True, token.start_mark, token.end_mark, flow_style=True,
-                )
-                self.state = self.parse_flow_sequence_entry_mapping_key
-                return event
-            elif not self.scanner.check_token(FlowSequenceEndToken):
-                self.states.append(self.parse_flow_sequence_entry)
-                return self.parse_flow_node()
-        token = self.scanner.get_token()
-        event = SequenceEndEvent(token.start_mark, token.end_mark, comment=token.comment)
-        self.state = self.states.pop()
-        self.marks.pop()
-        return event
-
-    def parse_flow_sequence_entry_mapping_key(self) -> Any:
-        token = self.scanner.get_token()
-        if not self.scanner.check_token(ValueToken, FlowEntryToken, FlowSequenceEndToken):
-            self.states.append(self.parse_flow_sequence_entry_mapping_value)
-            return self.parse_flow_node()
-        else:
-            self.state = self.parse_flow_sequence_entry_mapping_value
-            return self.process_empty_scalar(token.end_mark)
-
-    def parse_flow_sequence_entry_mapping_value(self) -> Any:
-        if self.scanner.check_token(ValueToken):
-            token = self.scanner.get_token()
-            if not self.scanner.check_token(FlowEntryToken, FlowSequenceEndToken):
-                self.states.append(self.parse_flow_sequence_entry_mapping_end)
-                return self.parse_flow_node()
-            else:
-                self.state = self.parse_flow_sequence_entry_mapping_end
-                return self.process_empty_scalar(token.end_mark)
-        else:
-            self.state = self.parse_flow_sequence_entry_mapping_end
-            token = self.scanner.peek_token()
-            return self.process_empty_scalar(token.start_mark)
-
-    def parse_flow_sequence_entry_mapping_end(self) -> Any:
-        self.state = self.parse_flow_sequence_entry
-        token = self.scanner.peek_token()
-        return MappingEndEvent(token.start_mark, token.start_mark)
-
-    # flow_mapping  ::= FLOW-MAPPING-START
-    #                   (flow_mapping_entry FLOW-ENTRY)*
-    #                   flow_mapping_entry?
-    #                   FLOW-MAPPING-END
-    # flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)?
-
-    def parse_flow_mapping_first_key(self) -> Any:
-        token = self.scanner.get_token()
-        self.marks.append(token.start_mark)
-        return self.parse_flow_mapping_key(first=True)
-
-    def parse_flow_mapping_key(self, first: Any = False) -> Any:
-        if not self.scanner.check_token(FlowMappingEndToken):
-            if not first:
-                if self.scanner.check_token(FlowEntryToken):
-                    self.scanner.get_token()
-                else:
-                    token = self.scanner.peek_token()
-                    raise ParserError(
-                        'while parsing a flow mapping',
-                        self.marks[-1],
-                        f"expected ',' or '}}', but got {token.id!r}",
-                        token.start_mark,
-                    )
-            if self.scanner.check_token(KeyToken):
-                token = self.scanner.get_token()
-                if not self.scanner.check_token(
-                    ValueToken, FlowEntryToken, FlowMappingEndToken,
-                ):
-                    self.states.append(self.parse_flow_mapping_value)
-                    return self.parse_flow_node()
-                else:
-                    self.state = self.parse_flow_mapping_value
-                    return self.process_empty_scalar(token.end_mark)
-            elif self.resolver.processing_version > (1, 1) and self.scanner.check_token(
-                ValueToken,
-            ):
-                self.state = self.parse_flow_mapping_value
-                return self.process_empty_scalar(self.scanner.peek_token().end_mark)
-            elif not self.scanner.check_token(FlowMappingEndToken):
-                self.states.append(self.parse_flow_mapping_empty_value)
-                return self.parse_flow_node()
-        token = self.scanner.get_token()
-        event = MappingEndEvent(token.start_mark, token.end_mark, comment=token.comment)
-        self.state = self.states.pop()
-        self.marks.pop()
-        return event
-
-    def parse_flow_mapping_value(self) -> Any:
-        if self.scanner.check_token(ValueToken):
-            token = self.scanner.get_token()
-            if not self.scanner.check_token(FlowEntryToken, FlowMappingEndToken):
-                self.states.append(self.parse_flow_mapping_key)
-                return self.parse_flow_node()
-            else:
-                self.state = self.parse_flow_mapping_key
-                return self.process_empty_scalar(token.end_mark)
-        else:
-            self.state = self.parse_flow_mapping_key
-            token = self.scanner.peek_token()
-            return self.process_empty_scalar(token.start_mark)
-
-    def parse_flow_mapping_empty_value(self) -> Any:
-        self.state = self.parse_flow_mapping_key
-        return self.process_empty_scalar(self.scanner.peek_token().start_mark)
-
-    def process_empty_scalar(self, mark: Any, comment: Any = None) -> Any:
-        return ScalarEvent(None, None, (True, False), "", mark, mark, comment=comment)
-
-    def move_token_comment(
-        self, token: Any, nt: Optional[Any] = None, empty: Optional[bool] = False,
-    ) -> Any:
-        pass
-
-
-class RoundTripParser(Parser):
-    """roundtrip is a safe loader, that wants to see the unmangled tag"""
-
-    def select_tag_transform(self, tag: Tag) -> None:
-        if tag is None:
-            return
-        tag.select_transform(True)
-
-    def move_token_comment(
-        self, token: Any, nt: Optional[Any] = None, empty: Optional[bool] = False,
-    ) -> Any:
-        token.move_old_comment(self.scanner.peek_token() if nt is None else nt, empty=empty)
-
-
-class RoundTripParserSC(RoundTripParser):
-    """roundtrip is a safe loader, that wants to see the unmangled tag"""
-
-    # some of the differences are based on the superclass testing
-    # if self.loader.comment_handling is not None
-
-    def move_token_comment(
-        self: Any, token: Any, nt: Any = None, empty: Optional[bool] = False,
-    ) -> None:
-        token.move_new_comment(self.scanner.peek_token() if nt is None else nt, empty=empty)
-
-    def distribute_comment(self, comment: Any, line: Any) -> Any:
-        # ToDo, look at indentation of the comment to determine attachment
-        if comment is None:
-            return None
-        if not comment[0]:
-            return None
-        # if comment[0][0] != line + 1:
-        #     nprintf('>>>dcxxx', comment, line)
-        assert comment[0][0] == line + 1
-        # if comment[0] - line > 1:
-        #     return
-        typ = self.loader.comment_handling & 0b11
-        # nprintf('>>>dca', comment, line, typ)
-        if typ == C_POST:
-            return None
-        if typ == C_PRE:
-            c = [None, None, comment[0]]
-            comment[0] = None
-            return c
-        # nprintf('>>>dcb', comment[0])
-        for _idx, cmntidx in enumerate(comment[0]):
-            # nprintf('>>>dcb', cmntidx)
-            if isinstance(self.scanner.comments[cmntidx], BlankLineComment):
-                break
-        else:
-            return None  # no space found
-        if _idx == 0:
-            return None  # first line was blank
-        # nprintf('>>>dcc', idx)
-        if typ == C_SPLIT_ON_FIRST_BLANK:
-            c = [None, None, comment[0][:_idx]]
-            comment[0] = comment[0][_idx:]
-            return c
-        raise NotImplementedError  # reserved
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py
deleted file mode 100644
index beee35826ad..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/reader.py
+++ /dev/null
@@ -1,277 +0,0 @@
-
-from __future__ import annotations
-
-# This module contains abstractions for the input stream. You don't have to
-# looks further, there are no pretty code.
-#
-# We define two classes here.
-#
-#   Mark(source, line, column)
-# It's just a record and its only use is producing nice error messages.
-# Parser does not use it for any other purposes.
-#
-#   Reader(source, data)
-# Reader determines the encoding of `data` and converts it to unicode.
-# Reader provides the following methods and attributes:
-#   reader.peek(length=1) - return the next `length` characters
-#   reader.forward(length=1) - move the current position to `length`
-#      characters.
-#   reader.index - the number of the current character.
-#   reader.line, stream.column - the line and the column of the current
-#      character.
-
-import codecs
-
-from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError, FileMark, StringMark, YAMLStreamError
-from opentelemetry.agent._vendor.ruamel.yaml.util import RegExp
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Union, Text, Tuple, Optional  # NOQA
-# from ruamel.yaml.compat import StreamTextType  # NOQA
-
-__all__ = ['Reader', 'ReaderError']
-
-
-class ReaderError(YAMLError):
-    def __init__(  # NOQA
-        self, name: Any, position: Any, character: Any, encoding: Any, reason: Any,
-    ) -> None:
-        self.name = name
-        self.character = character
-        self.position = position
-        self.encoding = encoding
-        self.reason = reason
-
-    def __str__(self) -> Any:
-        if isinstance(self.character, bytes):
-            return (
-                f"'{self.encoding!s}' codec can't decode byte #x{ord(self.character):02x}: "
-                f'{self.reason!s}\n'
-                f'  in "{self.name!s}", position {self.position:d}'
-            )
-        else:
-            return (
-                f'unacceptable character #x{self.character:04x}: {self.reason!s}\n'
-                f'  in "{self.name!s}", position {self.position:d}'
-            )
-
-
-class Reader:
-    # Reader:
-    # - determines the data encoding and converts it to a unicode string,
-    # - checks if characters are in allowed range,
-    # - adds '\0' to the end.
-
-    # Reader accepts
-    #  - a `bytes` object,
-    #  - a `str` object,
-    #  - a file-like object with its `read` method returning `str`,
-    #  - a file-like object with its `read` method returning `unicode`.
-
-    # Yeah, it's ugly and slow.
-
-    def __init__(self, stream: Any, loader: Any = None) -> None:
-        self.loader = loader
-        if self.loader is not None and getattr(self.loader, '_reader', None) is None:
-            self.loader._reader = self
-        self.reset_reader()
-        self.stream: Any = stream  # as .read is called
-
-    def reset_reader(self) -> None:
-        self.name: Any = None
-        self.stream_pointer = 0
-        self.eof = True
-        self.buffer = ""
-        self.pointer = 0
-        self.raw_buffer: Any = None
-        self.raw_decode = None
-        self.encoding: Optional[Text] = None
-        self.index = 0
-        self.line = 0
-        self.column = 0
-
-    @property
-    def stream(self) -> Any:
-        try:
-            return self._stream
-        except AttributeError:
-            raise YAMLStreamError('input stream needs to be specified')
-
-    @stream.setter
-    def stream(self, val: Any) -> None:
-        if val is None:
-            return
-        self._stream = None
-        if isinstance(val, str):
-            self.name = ''
-            self.check_printable(val)
-            self.buffer = val + '\0'
-        elif isinstance(val, bytes):
-            self.name = ''
-            self.raw_buffer = val
-            self.determine_encoding()
-        else:
-            if not hasattr(val, 'read'):
-                raise YAMLStreamError('stream argument needs to have a read() method')
-            self._stream = val
-            self.name = getattr(self.stream, 'name', '')
-            self.eof = False
-            self.raw_buffer = None
-            self.determine_encoding()
-
-    def peek(self, index: int = 0) -> Text:
-        try:
-            return self.buffer[self.pointer + index]
-        except IndexError:
-            self.update(index + 1)
-            return self.buffer[self.pointer + index]
-
-    def prefix(self, length: int = 1) -> Any:
-        if self.pointer + length >= len(self.buffer):
-            self.update(length)
-        return self.buffer[self.pointer : self.pointer + length]
-
-    def forward_1_1(self, length: int = 1) -> None:
-        if self.pointer + length + 1 >= len(self.buffer):
-            self.update(length + 1)
-        while length != 0:
-            ch = self.buffer[self.pointer]
-            self.pointer += 1
-            self.index += 1
-            if ch in '\n\x85\u2028\u2029' or (
-                ch == '\r' and self.buffer[self.pointer] != '\n'
-            ):
-                self.line += 1
-                self.column = 0
-            elif ch != '\uFEFF':
-                self.column += 1
-            length -= 1
-
-    def forward(self, length: int = 1) -> None:
-        if self.pointer + length + 1 >= len(self.buffer):
-            self.update(length + 1)
-        while length != 0:
-            ch = self.buffer[self.pointer]
-            self.pointer += 1
-            self.index += 1
-            if ch == '\n' or (ch == '\r' and self.buffer[self.pointer] != '\n'):
-                self.line += 1
-                self.column = 0
-            elif ch != '\uFEFF':
-                self.column += 1
-            length -= 1
-
-    def get_mark(self) -> Any:
-        if self.stream is None:
-            return StringMark(
-                self.name, self.index, self.line, self.column, self.buffer, self.pointer,
-            )
-        else:
-            return FileMark(self.name, self.index, self.line, self.column)
-
-    def determine_encoding(self) -> None:
-        while not self.eof and (self.raw_buffer is None or len(self.raw_buffer) < 2):
-            self.update_raw()
-        if isinstance(self.raw_buffer, bytes):
-            if self.raw_buffer.startswith(codecs.BOM_UTF16_LE):
-                self.raw_decode = codecs.utf_16_le_decode  # type: ignore
-                self.encoding = 'utf-16-le'
-            elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE):
-                self.raw_decode = codecs.utf_16_be_decode  # type: ignore
-                self.encoding = 'utf-16-be'
-            else:
-                self.raw_decode = codecs.utf_8_decode  # type: ignore
-                self.encoding = 'utf-8'
-        self.update(1)
-
-    NON_PRINTABLE = RegExp(
-        '[^\x09\x0A\x0D\x20-\x7E\x85' '\xA0-\uD7FF' '\uE000-\uFFFD' '\U00010000-\U0010FFFF' ']'  # NOQA
-    )
-
-    _printable_ascii = ('\x09\x0A\x0D' + "".join(map(chr, range(0x20, 0x7F)))).encode('ascii')
-
-    @classmethod
-    def _get_non_printable_ascii(cls: Text, data: bytes) -> Optional[Tuple[int, Text]]:  # type: ignore # NOQA
-        ascii_bytes = data.encode('ascii')  # type: ignore
-        non_printables = ascii_bytes.translate(None, cls._printable_ascii)  # type: ignore
-        if not non_printables:
-            return None
-        non_printable = non_printables[:1]
-        return ascii_bytes.index(non_printable), non_printable.decode('ascii')
-
-    @classmethod
-    def _get_non_printable_regex(cls, data: Text) -> Optional[Tuple[int, Text]]:
-        match = cls.NON_PRINTABLE.search(data)
-        if not bool(match):
-            return None
-        return match.start(), match.group()
-
-    @classmethod
-    def _get_non_printable(cls, data: Text) -> Optional[Tuple[int, Text]]:
-        try:
-            return cls._get_non_printable_ascii(data)  # type: ignore
-        except UnicodeEncodeError:
-            return cls._get_non_printable_regex(data)
-
-    def check_printable(self, data: Any) -> None:
-        non_printable_match = self._get_non_printable(data)
-        if non_printable_match is not None:
-            start, character = non_printable_match
-            position = self.index + (len(self.buffer) - self.pointer) + start
-            raise ReaderError(
-                self.name,
-                position,
-                ord(character),
-                'unicode',
-                'special characters are not allowed',
-            )
-
-    def update(self, length: int) -> None:
-        if self.raw_buffer is None:
-            return
-        self.buffer = self.buffer[self.pointer :]
-        self.pointer = 0
-        while len(self.buffer) < length:
-            if not self.eof:
-                self.update_raw()
-            if self.raw_decode is not None:
-                try:
-                    data, converted = self.raw_decode(self.raw_buffer, 'strict', self.eof)
-                except UnicodeDecodeError as exc:
-                    character = self.raw_buffer[exc.start]
-                    if self.stream is not None:
-                        position = self.stream_pointer - len(self.raw_buffer) + exc.start
-                    elif self.stream is not None:
-                        position = self.stream_pointer - len(self.raw_buffer) + exc.start
-                    else:
-                        position = exc.start
-                    raise ReaderError(self.name, position, character, exc.encoding, exc.reason)
-            else:
-                data = self.raw_buffer
-                converted = len(data)
-            self.check_printable(data)
-            self.buffer += data
-            self.raw_buffer = self.raw_buffer[converted:]
-            if self.eof:
-                self.buffer += '\0'
-                self.raw_buffer = None
-                break
-
-    def update_raw(self, size: Optional[int] = None) -> None:
-        if size is None:
-            size = 4096
-        data = self.stream.read(size)
-        if self.raw_buffer is None:
-            self.raw_buffer = data
-        else:
-            self.raw_buffer += data
-        self.stream_pointer += len(data)
-        if not data:
-            self.eof = True
-
-
-# try:
-#     import psyco
-#     psyco.bind(Reader)
-# except ImportError:
-#     pass
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py
deleted file mode 100644
index 28e2a10607c..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/representer.py
+++ /dev/null
@@ -1,1139 +0,0 @@
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.error import *  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.nodes import *  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.compat import ordereddict
-from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, nprintf  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.scalarstring import (
-    LiteralScalarString,
-    FoldedScalarString,
-    SingleQuotedScalarString,
-    DoubleQuotedScalarString,
-    PlainScalarString,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.comments import (
-    CommentedMap,
-    CommentedOrderedMap,
-    CommentedSeq,
-    CommentedKeySeq,
-    CommentedKeyMap,
-    CommentedSet,
-    comment_attrib,
-    merge_attrib,
-    TaggedScalar,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.scalarint import ScalarInt, BinaryInt, OctalInt, HexInt, HexCapsInt
-from opentelemetry.agent._vendor.ruamel.yaml.scalarfloat import ScalarFloat
-from opentelemetry.agent._vendor.ruamel.yaml.scalarbool import ScalarBoolean
-from opentelemetry.agent._vendor.ruamel.yaml.timestamp import TimeStamp
-from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
-
-import collections
-import datetime
-import types
-
-import copyreg
-import base64
-
-if False:  # MYPY
-    from typing import Dict, List, Any, Union, Text, Optional  # NOQA
-
-# fmt: off
-__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
-           'RepresenterError', 'RoundTripRepresenter']
-# fmt: on
-
-
-class RepresenterError(YAMLError):
-    pass
-
-
-class BaseRepresenter:
-
-    yaml_representers: Dict[Any, Any] = {}
-    yaml_multi_representers: Dict[Any, Any] = {}
-
-    def __init__(
-        self: Any,
-        default_style: Any = None,
-        default_flow_style: Any = None,
-        dumper: Any = None,
-    ) -> None:
-        self.dumper = dumper
-        if self.dumper is not None:
-            self.dumper._representer = self
-        self.default_style = default_style
-        self.default_flow_style = default_flow_style
-        self.represented_objects: Dict[Any, Any] = {}
-        self.object_keeper: List[Any] = []
-        self.alias_key: Optional[int] = None
-        self.sort_base_mapping_type_on_output = True
-
-    @property
-    def serializer(self) -> Any:
-        try:
-            if hasattr(self.dumper, 'typ'):
-                return self.dumper.serializer
-            return self.dumper._serializer
-        except AttributeError:
-            return self  # cyaml
-
-    def represent(self, data: Any) -> None:
-        node = self.represent_data(data)
-        self.serializer.serialize(node)
-        self.represented_objects = {}
-        self.object_keeper = []
-        self.alias_key = None
-
-    def represent_data(self, data: Any) -> Any:
-        if self.ignore_aliases(data):
-            self.alias_key = None
-        else:
-            self.alias_key = id(data)
-        if self.alias_key is not None:
-            if self.alias_key in self.represented_objects:
-                node = self.represented_objects[self.alias_key]
-                # if node is None:
-                #     raise RepresenterError(
-                #          f"recursive objects are not allowed: {data!r}")
-                return node
-            # self.represented_objects[alias_key] = None
-            self.object_keeper.append(data)
-        data_types = type(data).__mro__
-        if data_types[0] in self.yaml_representers:
-            node = self.yaml_representers[data_types[0]](self, data)
-        else:
-            for data_type in data_types:
-                if data_type in self.yaml_multi_representers:
-                    node = self.yaml_multi_representers[data_type](self, data)
-                    break
-            else:
-                if None in self.yaml_multi_representers:
-                    node = self.yaml_multi_representers[None](self, data)
-                elif None in self.yaml_representers:
-                    node = self.yaml_representers[None](self, data)
-                else:
-                    node = ScalarNode(None, str(data))
-        # if alias_key is not None:
-        #     self.represented_objects[alias_key] = node
-        return node
-
-    def represent_key(self, data: Any) -> Any:
-        """
-        David Fraser: Extract a method to represent keys in mappings, so that
-        a subclass can choose not to quote them (for example)
-        used in represent_mapping
-        https://bitbucket.org/davidfraser/pyyaml/commits/d81df6eb95f20cac4a79eed95ae553b5c6f77b8c
-        """
-        return self.represent_data(data)
-
-    @classmethod
-    def add_representer(cls, data_type: Any, representer: Any) -> None:
-        if 'yaml_representers' not in cls.__dict__:
-            cls.yaml_representers = cls.yaml_representers.copy()
-        cls.yaml_representers[data_type] = representer
-
-    @classmethod
-    def add_multi_representer(cls, data_type: Any, representer: Any) -> None:
-        if 'yaml_multi_representers' not in cls.__dict__:
-            cls.yaml_multi_representers = cls.yaml_multi_representers.copy()
-        cls.yaml_multi_representers[data_type] = representer
-
-    def represent_scalar(
-        self, tag: Any, value: Any, style: Any = None, anchor: Any = None,
-    ) -> ScalarNode:
-        if style is None:
-            style = self.default_style
-        comment = None
-        if style and style[0] in '|>':
-            comment = getattr(value, 'comment', None)
-            if comment:
-                comment = [None, [comment]]
-        if isinstance(tag, str):
-            tag = Tag(suffix=tag)
-        node = ScalarNode(tag, value, style=style, comment=comment, anchor=anchor)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        return node
-
-    def represent_sequence(
-        self, tag: Any, sequence: Any, flow_style: Any = None,
-    ) -> SequenceNode:
-        value: List[Any] = []
-        if isinstance(tag, str):
-            tag = Tag(suffix=tag)
-        node = SequenceNode(tag, value, flow_style=flow_style)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        best_style = True
-        for item in sequence:
-            node_item = self.represent_data(item)
-            if not (isinstance(node_item, ScalarNode) and not node_item.style):
-                best_style = False
-            value.append(node_item)
-        if flow_style is None:
-            if self.default_flow_style is not None:
-                node.flow_style = self.default_flow_style
-            else:
-                node.flow_style = best_style
-        return node
-
-    def represent_omap(self, tag: Any, omap: Any, flow_style: Any = None) -> SequenceNode:
-        value: List[Any] = []
-        if isinstance(tag, str):
-            tag = Tag(suffix=tag)
-        node = SequenceNode(tag, value, flow_style=flow_style)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        best_style = True
-        for item_key in omap:
-            item_val = omap[item_key]
-            node_item = self.represent_data({item_key: item_val})
-            # if not (isinstance(node_item, ScalarNode) \
-            #    and not node_item.style):
-            #     best_style = False
-            value.append(node_item)
-        if flow_style is None:
-            if self.default_flow_style is not None:
-                node.flow_style = self.default_flow_style
-            else:
-                node.flow_style = best_style
-        return node
-
-    def represent_mapping(self, tag: Any, mapping: Any, flow_style: Any = None) -> MappingNode:
-        value: List[Any] = []
-        if isinstance(tag, str):
-            tag = Tag(suffix=tag)
-        node = MappingNode(tag, value, flow_style=flow_style)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        best_style = True
-        if hasattr(mapping, 'items'):
-            mapping = list(mapping.items())
-            if self.sort_base_mapping_type_on_output:
-                try:
-                    mapping = sorted(mapping)
-                except TypeError:
-                    pass
-        for item_key, item_value in mapping:
-            node_key = self.represent_key(item_key)
-            node_value = self.represent_data(item_value)
-            if not (isinstance(node_key, ScalarNode) and not node_key.style):
-                best_style = False
-            if not (isinstance(node_value, ScalarNode) and not node_value.style):
-                best_style = False
-            value.append((node_key, node_value))
-        if flow_style is None:
-            if self.default_flow_style is not None:
-                node.flow_style = self.default_flow_style
-            else:
-                node.flow_style = best_style
-        return node
-
-    def ignore_aliases(self, data: Any) -> bool:
-        return False
-
-
-class SafeRepresenter(BaseRepresenter):
-    def ignore_aliases(self, data: Any) -> bool:
-        # https://docs.python.org/3/reference/expressions.html#parenthesized-forms :
-        # "i.e. two occurrences of the empty tuple may or may not yield the same object"
-        # so "data is ()" should not be used
-        if data is None or (isinstance(data, tuple) and data == ()):
-            return True
-        if isinstance(data, (bytes, str, bool, int, float)):
-            return True
-        return False
-
-    def represent_none(self, data: Any) -> ScalarNode:
-        return self.represent_scalar('tag:yaml.org,2002:null', 'null')
-
-    def represent_str(self, data: Any) -> Any:
-        return self.represent_scalar('tag:yaml.org,2002:str', data)
-
-    def represent_binary(self, data: Any) -> ScalarNode:
-        if hasattr(base64, 'encodebytes'):
-            data = base64.encodebytes(data).decode('ascii')
-        else:
-            # check py2 only?
-            data = base64.encodestring(data).decode('ascii')  # type: ignore
-        return self.represent_scalar('tag:yaml.org,2002:binary', data, style='|')
-
-    def represent_bool(self, data: Any, anchor: Optional[Any] = None) -> ScalarNode:
-        try:
-            value = self.dumper.boolean_representation[bool(data)]
-        except AttributeError:
-            if data:
-                value = 'true'
-            else:
-                value = 'false'
-        return self.represent_scalar('tag:yaml.org,2002:bool', value, anchor=anchor)
-
-    def represent_int(self, data: Any) -> ScalarNode:
-        return self.represent_scalar('tag:yaml.org,2002:int', str(data))
-
-    inf_value = 1e300
-    while repr(inf_value) != repr(inf_value * inf_value):
-        inf_value *= inf_value
-
-    def represent_float(self, data: Any) -> ScalarNode:
-        if data != data or (data == 0.0 and data == 1.0):
-            value = '.nan'
-        elif data == self.inf_value:
-            value = '.inf'
-        elif data == -self.inf_value:
-            value = '-.inf'
-        else:
-            value = repr(data).lower()
-            if getattr(self.serializer, 'use_version', None) == (1, 1):
-                if '.' not in value and 'e' in value:
-                    # Note that in some cases `repr(data)` represents a float number
-                    # without the decimal parts.  For instance:
-                    #   >>> repr(1e17)
-                    #   '1e17'
-                    # Unfortunately, this is not a valid float representation according
-                    # to the definition of the `!!float` tag in YAML 1.1.  We fix
-                    # this by adding '.0' before the 'e' symbol.
-                    value = value.replace('e', '.0e', 1)
-        return self.represent_scalar('tag:yaml.org,2002:float', value)
-
-    def represent_list(self, data: Any) -> SequenceNode:
-        # pairs = (len(data) > 0 and isinstance(data, list))
-        # if pairs:
-        #     for item in data:
-        #         if not isinstance(item, tuple) or len(item) != 2:
-        #             pairs = False
-        #             break
-        # if not pairs:
-        return self.represent_sequence('tag:yaml.org,2002:seq', data)
-
-    # value = []
-    # for item_key, item_value in data:
-    #     value.append(self.represent_mapping('tag:yaml.org,2002:map',
-    #         [(item_key, item_value)]))
-    # return SequenceNode('tag:yaml.org,2002:pairs', value)
-
-    def represent_dict(self, data: Any) -> MappingNode:
-        return self.represent_mapping('tag:yaml.org,2002:map', data)
-
-    def represent_ordereddict(self, data: Any) -> SequenceNode:
-        return self.represent_omap('tag:yaml.org,2002:omap', data)
-
-    def represent_set(self, data: Any) -> MappingNode:
-        value: Dict[Any, None] = {}
-        for key in data:
-            value[key] = None
-        return self.represent_mapping('tag:yaml.org,2002:set', value)
-
-    def represent_date(self, data: Any) -> ScalarNode:
-        value = data.isoformat()
-        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
-
-    def represent_datetime(self, data: Any) -> ScalarNode:
-        value = data.isoformat(' ')
-        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
-
-    def represent_yaml_object(
-        self, tag: Any, data: Any, cls: Any, flow_style: Any = None,
-    ) -> MappingNode:
-        if hasattr(data, '__getstate__'):
-            state = data.__getstate__()
-        else:
-            state = data.__dict__.copy()
-        return self.represent_mapping(tag, state, flow_style=flow_style)
-
-    def represent_undefined(self, data: Any) -> None:
-        raise RepresenterError(f'cannot represent an object: {data!r}')
-
-
-SafeRepresenter.add_representer(type(None), SafeRepresenter.represent_none)
-
-SafeRepresenter.add_representer(str, SafeRepresenter.represent_str)
-
-SafeRepresenter.add_representer(bytes, SafeRepresenter.represent_binary)
-
-SafeRepresenter.add_representer(bool, SafeRepresenter.represent_bool)
-
-SafeRepresenter.add_representer(int, SafeRepresenter.represent_int)
-
-SafeRepresenter.add_representer(float, SafeRepresenter.represent_float)
-
-SafeRepresenter.add_representer(list, SafeRepresenter.represent_list)
-
-SafeRepresenter.add_representer(tuple, SafeRepresenter.represent_list)
-
-SafeRepresenter.add_representer(dict, SafeRepresenter.represent_dict)
-
-SafeRepresenter.add_representer(set, SafeRepresenter.represent_set)
-
-SafeRepresenter.add_representer(ordereddict, SafeRepresenter.represent_ordereddict)
-
-SafeRepresenter.add_representer(
-    collections.OrderedDict, SafeRepresenter.represent_ordereddict,
-)
-
-SafeRepresenter.add_representer(datetime.date, SafeRepresenter.represent_date)
-
-SafeRepresenter.add_representer(datetime.datetime, SafeRepresenter.represent_datetime)
-
-SafeRepresenter.add_representer(None, SafeRepresenter.represent_undefined)
-
-
-class Representer(SafeRepresenter):
-    def represent_complex(self, data: Any) -> Any:
-        if data.imag == 0.0:
-            data = repr(data.real)
-        elif data.real == 0.0:
-            data = f'{data.imag!r}j'
-        elif data.imag > 0:
-            data = f'{data.real!r}+{data.imag!r}j'
-        else:
-            data = f'{data.real!r}{data.imag!r}j'
-        return self.represent_scalar('tag:yaml.org,2002:python/complex', data)
-
-    def represent_tuple(self, data: Any) -> SequenceNode:
-        return self.represent_sequence('tag:yaml.org,2002:python/tuple', data)
-
-    def represent_name(self, data: Any) -> ScalarNode:
-        try:
-            name = f'{data.__module__!s}.{data.__qualname__!s}'
-        except AttributeError:
-            # ToDo: check if this can be reached in Py3
-            name = f'{data.__module__!s}.{data.__name__!s}'
-        return self.represent_scalar('tag:yaml.org,2002:python/name:' + name, "")
-
-    def represent_module(self, data: Any) -> ScalarNode:
-        return self.represent_scalar('tag:yaml.org,2002:python/module:' + data.__name__, "")
-
-    def represent_object(self, data: Any) -> Union[SequenceNode, MappingNode]:
-        # We use __reduce__ API to save the data. data.__reduce__ returns
-        # a tuple of length 2-5:
-        #   (function, args, state, listitems, dictitems)
-
-        # For reconstructing, we calls function(*args), then set its state,
-        # listitems, and dictitems if they are not None.
-
-        # A special case is when function.__name__ == '__newobj__'. In this
-        # case we create the object with args[0].__new__(*args).
-
-        # Another special case is when __reduce__ returns a string - we don't
-        # support it.
-
-        # We produce a !!python/object, !!python/object/new or
-        # !!python/object/apply node.
-
-        cls = type(data)
-        if cls in copyreg.dispatch_table:
-            reduce: Any = copyreg.dispatch_table[cls](data)
-        elif hasattr(data, '__reduce_ex__'):
-            reduce = data.__reduce_ex__(2)
-        elif hasattr(data, '__reduce__'):
-            reduce = data.__reduce__()
-        else:
-            raise RepresenterError(f'cannot represent object: {data!r}')
-        reduce = (list(reduce) + [None] * 5)[:5]
-        function, args, state, listitems, dictitems = reduce
-        args = list(args)
-        if state is None:
-            state = {}
-        if listitems is not None:
-            listitems = list(listitems)
-        if dictitems is not None:
-            dictitems = dict(dictitems)
-        if function.__name__ == '__newobj__':
-            function = args[0]
-            args = args[1:]
-            tag = 'tag:yaml.org,2002:python/object/new:'
-            newobj = True
-        else:
-            tag = 'tag:yaml.org,2002:python/object/apply:'
-            newobj = False
-        try:
-            function_name = f'{function.__module__!s}.{function.__qualname__!s}'
-        except AttributeError:
-            # ToDo: check if this can be reached in Py3
-            function_name = f'{function.__module__!s}.{function.__name__!s}'
-        if not args and not listitems and not dictitems and isinstance(state, dict) and newobj:
-            return self.represent_mapping(
-                'tag:yaml.org,2002:python/object:' + function_name, state,
-            )
-        if not listitems and not dictitems and isinstance(state, dict) and not state:
-            return self.represent_sequence(tag + function_name, args)
-        value = {}
-        if args:
-            value['args'] = args
-        if state or not isinstance(state, dict):
-            value['state'] = state
-        if listitems:
-            value['listitems'] = listitems
-        if dictitems:
-            value['dictitems'] = dictitems
-        return self.represent_mapping(tag + function_name, value)
-
-
-Representer.add_representer(complex, Representer.represent_complex)
-
-Representer.add_representer(tuple, Representer.represent_tuple)
-
-Representer.add_representer(type, Representer.represent_name)
-
-Representer.add_representer(types.FunctionType, Representer.represent_name)
-
-Representer.add_representer(types.BuiltinFunctionType, Representer.represent_name)
-
-Representer.add_representer(types.ModuleType, Representer.represent_module)
-
-Representer.add_multi_representer(object, Representer.represent_object)
-
-Representer.add_multi_representer(type, Representer.represent_name)
-
-
-class RoundTripRepresenter(SafeRepresenter):
-    # need to add type here and write out the .comment
-    # in serializer and emitter
-
-    def __init__(
-        self, default_style: Any = None, default_flow_style: Any = None, dumper: Any = None,
-    ) -> None:
-        if not hasattr(dumper, 'typ') and default_flow_style is None:
-            default_flow_style = False
-        SafeRepresenter.__init__(
-            self,
-            default_style=default_style,
-            default_flow_style=default_flow_style,
-            dumper=dumper,
-        )
-
-    def ignore_aliases(self, data: Any) -> bool:
-        try:
-            if data.anchor is not None and data.anchor.value is not None:
-                return False
-        except AttributeError:
-            pass
-        return SafeRepresenter.ignore_aliases(self, data)
-
-    def represent_none(self, data: Any) -> ScalarNode:
-        if len(self.represented_objects) == 0 and not self.serializer.use_explicit_start:
-            # this will be open ended (although it is not yet)
-            return self.represent_scalar('tag:yaml.org,2002:null', 'null')
-        return self.represent_scalar('tag:yaml.org,2002:null', "")
-
-    def represent_literal_scalarstring(self, data: Any) -> ScalarNode:
-        tag = None
-        style = '|'
-        anchor = data.yaml_anchor(any=True)
-        tag = 'tag:yaml.org,2002:str'
-        return self.represent_scalar(tag, data, style=style, anchor=anchor)
-
-    represent_preserved_scalarstring = represent_literal_scalarstring
-
-    def represent_folded_scalarstring(self, data: Any) -> ScalarNode:
-        tag = None
-        style = '>'
-        anchor = data.yaml_anchor(any=True)
-        for fold_pos in reversed(getattr(data, 'fold_pos', [])):
-            if (
-                data[fold_pos] == ' '
-                and (fold_pos > 0 and not data[fold_pos - 1].isspace())
-                and (fold_pos < len(data) and not data[fold_pos + 1].isspace())
-            ):
-                data = data[:fold_pos] + '\a' + data[fold_pos:]
-        tag = 'tag:yaml.org,2002:str'
-        return self.represent_scalar(tag, data, style=style, anchor=anchor)
-
-    def represent_single_quoted_scalarstring(self, data: Any) -> ScalarNode:
-        tag = None
-        style = "'"
-        anchor = data.yaml_anchor(any=True)
-        tag = 'tag:yaml.org,2002:str'
-        return self.represent_scalar(tag, data, style=style, anchor=anchor)
-
-    def represent_double_quoted_scalarstring(self, data: Any) -> ScalarNode:
-        tag = None
-        style = '"'
-        anchor = data.yaml_anchor(any=True)
-        tag = 'tag:yaml.org,2002:str'
-        return self.represent_scalar(tag, data, style=style, anchor=anchor)
-
-    def represent_plain_scalarstring(self, data: Any) -> ScalarNode:
-        tag = None
-        style = ''
-        anchor = data.yaml_anchor(any=True)
-        tag = 'tag:yaml.org,2002:str'
-        return self.represent_scalar(tag, data, style=style, anchor=anchor)
-
-    def insert_underscore(
-        self, prefix: Any, s: Any, underscore: Any, anchor: Any = None,
-    ) -> ScalarNode:
-        if underscore is None:
-            return self.represent_scalar('tag:yaml.org,2002:int', prefix + s, anchor=anchor)
-        if underscore[0]:
-            sl = list(s)
-            pos = len(s) - underscore[0]
-            while pos > 0:
-                sl.insert(pos, '_')
-                pos -= underscore[0]
-            s = "".join(sl)
-        if underscore[1]:
-            s = '_' + s
-        if underscore[2]:
-            s += '_'
-        return self.represent_scalar('tag:yaml.org,2002:int', prefix + s, anchor=anchor)
-
-    def represent_scalar_int(self, data: Any) -> ScalarNode:
-        if data._width is not None:
-            s = f'{data:0{data._width}d}'
-        else:
-            s = format(data, 'd')
-        anchor = data.yaml_anchor(any=True)
-        return self.insert_underscore("", s, data._underscore, anchor=anchor)
-
-    def represent_binary_int(self, data: Any) -> ScalarNode:
-        if data._width is not None:
-            # cannot use '{:#0{}b}', that strips the zeros
-            s = f'{data:0{data._width}b}'
-        else:
-            s = format(data, 'b')
-        anchor = data.yaml_anchor(any=True)
-        return self.insert_underscore('0b', s, data._underscore, anchor=anchor)
-
-    def represent_octal_int(self, data: Any) -> ScalarNode:
-        if data._width is not None:
-            # cannot use '{:#0{}o}', that strips the zeros
-            s = f'{data:0{data._width}o}'
-        else:
-            s = format(data, 'o')
-        anchor = data.yaml_anchor(any=True)
-        prefix = '0o'
-        if getattr(self.serializer, 'use_version', None) == (1, 1):
-            prefix = '0'
-        return self.insert_underscore(prefix, s, data._underscore, anchor=anchor)
-
-    def represent_hex_int(self, data: Any) -> ScalarNode:
-        if data._width is not None:
-            # cannot use '{:#0{}x}', that strips the zeros
-            s = f'{data:0{data._width}x}'
-        else:
-            s = format(data, 'x')
-        anchor = data.yaml_anchor(any=True)
-        return self.insert_underscore('0x', s, data._underscore, anchor=anchor)
-
-    def represent_hex_caps_int(self, data: Any) -> ScalarNode:
-        if data._width is not None:
-            # cannot use '{:#0{}X}', that strips the zeros
-            s = f'{data:0{data._width}X}'
-        else:
-            s = format(data, 'X')
-        anchor = data.yaml_anchor(any=True)
-        return self.insert_underscore('0x', s, data._underscore, anchor=anchor)
-
-    def represent_scalar_float(self, data: Any) -> ScalarNode:
-        """ this is way more complicated """
-        value = None
-        anchor = data.yaml_anchor(any=True)
-        if data != data or (data == 0.0 and data == 1.0):
-            value = '.nan'
-        elif data == self.inf_value:
-            value = '.inf'
-        elif data == -self.inf_value:
-            value = '-.inf'
-        if value:
-            return self.represent_scalar('tag:yaml.org,2002:float', value, anchor=anchor)
-        if data._exp is None and data._prec > 0 and data._prec == data._width - 1:
-            # no exponent, but trailing dot
-            value = f'{data._m_sign if data._m_sign else ""}{abs(int(data)):d}.'
-        elif data._exp is None:
-            # no exponent, "normal" dot
-            prec = data._prec
-            ms = data._m_sign if data._m_sign else ""
-            if prec < 0:
-                value = f'{ms}{abs(int(data)):0{data._width - len(ms)}d}'
-            else:
-                # -1 for the dot
-                value = f'{ms}{abs(data):0{data._width - len(ms)}.{data._width - prec - 1}f}'
-                if prec == 0 or (prec == 1 and ms != ""):
-                    value = value.replace('0.', '.')
-            while len(value) < data._width:
-                value += '0'
-        else:
-            # exponent
-            (
-                m,
-                es,
-            ) = f'{data:{data._width}.{data._width + (1 if data._m_sign else 0)}e}'.split('e')
-            w = data._width if data._prec > 0 else (data._width + 1)
-            if data < 0:
-                w += 1
-            m = m[:w]
-            e = int(es)
-            m1, m2 = m.split('.')  # always second?
-            while len(m1) + len(m2) < data._width - (1 if data._prec >= 0 else 0):
-                m2 += '0'
-            if data._m_sign and data > 0:
-                m1 = '+' + m1
-            esgn = '+' if data._e_sign else ""
-            if data._prec < 0:  # mantissa without dot
-                if m2 != '0':
-                    e -= len(m2)
-                else:
-                    m2 = ""
-                while (len(m1) + len(m2) - (1 if data._m_sign else 0)) < data._width:
-                    m2 += '0'
-                    e -= 1
-                value = m1 + m2 + data._exp + f'{e:{esgn}0{data._e_width}d}'
-            elif data._prec == 0:  # mantissa with trailing dot
-                e -= len(m2)
-                value = m1 + m2 + '.' + data._exp + f'{e:{esgn}0{data._e_width}d}'
-            else:
-                if data._m_lead0 > 0:
-                    m2 = '0' * (data._m_lead0 - 1) + m1 + m2
-                    m1 = '0'
-                    m2 = m2[: -data._m_lead0]  # these should be zeros
-                    e += data._m_lead0
-                while len(m1) < data._prec:
-                    m1 += m2[0]
-                    m2 = m2[1:]
-                    e -= 1
-                value = m1 + '.' + m2 + data._exp + f'{e:{esgn}0{data._e_width}d}'
-
-        if value is None:
-            value = repr(data).lower()
-        return self.represent_scalar('tag:yaml.org,2002:float', value, anchor=anchor)
-
-    def represent_sequence(
-        self, tag: Any, sequence: Any, flow_style: Any = None,
-    ) -> SequenceNode:
-        value: List[Any] = []
-        # if the flow_style is None, the flow style tacked on to the object
-        # explicitly will be taken. If that is None as well the default flow
-        # style rules
-        try:
-            flow_style = sequence.fa.flow_style(flow_style)
-        except AttributeError:
-            flow_style = flow_style
-        try:
-            anchor = sequence.yaml_anchor()
-        except AttributeError:
-            anchor = None
-        if isinstance(tag, str):
-            tag = Tag(suffix=tag)
-        node = SequenceNode(tag, value, flow_style=flow_style, anchor=anchor)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        best_style = True
-        try:
-            comment = getattr(sequence, comment_attrib)
-            node.comment = comment.comment
-            # reset any comment already printed information
-            if node.comment and node.comment[1]:
-                for ct in node.comment[1]:
-                    ct.reset()
-            item_comments = comment.items
-            for v in item_comments.values():
-                if v and v[1]:
-                    for ct in v[1]:
-                        ct.reset()
-            item_comments = comment.items
-            if node.comment is None:
-                node.comment = comment.comment
-            else:
-                # as we are potentially going to extend this, make a new list
-                node.comment = comment.comment[:]
-            try:
-                node.comment.append(comment.end)
-            except AttributeError:
-                pass
-        except AttributeError:
-            item_comments = {}
-        for idx, item in enumerate(sequence):
-            node_item = self.represent_data(item)
-            self.merge_comments(node_item, item_comments.get(idx))
-            if not (isinstance(node_item, ScalarNode) and not node_item.style):
-                best_style = False
-            value.append(node_item)
-        if flow_style is None:
-            if len(sequence) != 0 and self.default_flow_style is not None:
-                node.flow_style = self.default_flow_style
-            else:
-                node.flow_style = best_style
-        return node
-
-    def merge_comments(self, node: Any, comments: Any) -> Any:
-        if comments is None:
-            assert hasattr(node, 'comment')
-            return node
-        if getattr(node, 'comment', None) is not None:
-            for idx, val in enumerate(comments):
-                if idx >= len(node.comment):
-                    continue
-                nc = node.comment[idx]
-                if nc is not None:
-                    assert val is None or val == nc
-                    comments[idx] = nc
-        node.comment = comments
-        return node
-
-    def represent_key(self, data: Any) -> Any:
-        if isinstance(data, CommentedKeySeq):
-            self.alias_key = None
-            return self.represent_sequence('tag:yaml.org,2002:seq', data, flow_style=True)
-        if isinstance(data, CommentedKeyMap):
-            self.alias_key = None
-            return self.represent_mapping('tag:yaml.org,2002:map', data, flow_style=True)
-        return SafeRepresenter.represent_key(self, data)
-
-    def represent_mapping(self, tag: Any, mapping: Any, flow_style: Any = None) -> MappingNode:
-        value: List[Any] = []
-        try:
-            flow_style = mapping.fa.flow_style(flow_style)
-        except AttributeError:
-            flow_style = flow_style
-        try:
-            anchor = mapping.yaml_anchor()
-        except AttributeError:
-            anchor = None
-        if isinstance(tag, str):
-            tag = Tag(suffix=tag)
-        node = MappingNode(tag, value, flow_style=flow_style, anchor=anchor)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        best_style = True
-        # no sorting! !!
-        try:
-            comment = getattr(mapping, comment_attrib)
-            if node.comment is None:
-                node.comment = comment.comment
-            else:
-                # as we are potentially going to extend this, make a new list
-                node.comment = comment.comment[:]
-            if node.comment and node.comment[1]:
-                for ct in node.comment[1]:
-                    ct.reset()
-            item_comments = comment.items
-            if self.dumper.comment_handling is None:
-                for v in item_comments.values():
-                    if v and v[1]:
-                        for ct in v[1]:
-                            ct.reset()
-                try:
-                    node.comment.append(comment.end)
-                except AttributeError:
-                    pass
-            else:
-                # NEWCMNT
-                pass
-        except AttributeError:
-            item_comments = {}
-        merge_value = getattr(mapping, merge_attrib, [])
-        # merge_list = [m[1] for m in merge_value]
-        # merge_list = [m for m in merge_value]
-        try:
-            # merge_pos = getattr(mapping, merge_attrib, [[0]])[0][0]
-            # print('merge_pos', merge_pos, merge_value.merge_pos)
-            merge_pos = merge_value.merge_pos  # type: ignore
-        except (AttributeError, IndexError):
-            merge_pos = 0
-        item_count = 0
-        # if bool(merge_list):
-        if len(merge_value) > 0:
-            items = mapping.non_merged_items()
-        else:
-            items = mapping.items()
-        for item_key, item_value in items:
-            item_count += 1
-            node_key = self.represent_key(item_key)
-            node_value = self.represent_data(item_value)
-            item_comment = item_comments.get(item_key)
-            if item_comment:
-                # assert getattr(node_key, 'comment', None) is None
-                # issue 351 did throw this because the comment from the list item was
-                # moved to the dict
-                node_key.comment = item_comment[:2]
-                nvc = getattr(node_value, 'comment', None)
-                if nvc is not None:  # end comment already there
-                    nvc[0] = item_comment[2]
-                    nvc[1] = item_comment[3]
-                else:
-                    node_value.comment = item_comment[2:]
-            if not (isinstance(node_key, ScalarNode) and not node_key.style):
-                best_style = False
-            if not (isinstance(node_value, ScalarNode) and not node_value.style):
-                best_style = False
-            value.append((node_key, node_value))
-        if flow_style is None:
-            if ((item_count != 0) or (len(merge_value) > 0)) and self.default_flow_style is not None:  # NOQA
-                node.flow_style = self.default_flow_style
-            else:
-                node.flow_style = best_style
-        if len(merge_value) > 0:
-            # because of the call to represent_data here, the anchors
-            # are marked as being used and thereby created
-            # if len(merge_list) == 1:
-            if merge_value.sequence is None:  # type: ignore
-                arg = self.represent_data(merge_value[0])
-            else:
-                # arg = self.represent_data(merge_list)
-                # arg.flow_style = True
-                arg = self.represent_data(merge_value.sequence)  # type: ignore
-            value.insert(
-                merge_pos, (ScalarNode(Tag(suffix='tag:yaml.org,2002:merge'), '<<'), arg),
-            )
-        return node
-
-    def represent_omap(self, tag: Any, omap: Any, flow_style: Any = None) -> SequenceNode:
-        value: List[Any] = []
-        try:
-            flow_style = omap.fa.flow_style(flow_style)
-        except AttributeError:
-            flow_style = flow_style
-        try:
-            anchor = omap.yaml_anchor()
-        except AttributeError:
-            anchor = None
-        if isinstance(tag, str):
-            tag = Tag(suffix=tag)
-        node = SequenceNode(tag, value, flow_style=flow_style, anchor=anchor)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        best_style = True
-        try:
-            comment = getattr(omap, comment_attrib)
-            if node.comment is None:
-                node.comment = comment.comment
-            else:
-                # as we are potentially going to extend this, make a new list
-                node.comment = comment.comment[:]
-            if node.comment and node.comment[1]:
-                for ct in node.comment[1]:
-                    ct.reset()
-            item_comments = comment.items
-            for v in item_comments.values():
-                if v and v[1]:
-                    for ct in v[1]:
-                        ct.reset()
-            try:
-                node.comment.append(comment.end)
-            except AttributeError:
-                pass
-        except AttributeError:
-            item_comments = {}
-        for item_key in omap:
-            item_val = omap[item_key]
-            node_item = self.represent_data({item_key: item_val})
-            # node_item.flow_style = False
-            # node item has two scalars in value: node_key and node_value
-            item_comment = item_comments.get(item_key)
-            if item_comment:
-                if item_comment[1]:
-                    node_item.comment = [None, item_comment[1]]
-                assert getattr(node_item.value[0][0], 'comment', None) is None
-                node_item.value[0][0].comment = [item_comment[0], None]
-                nvc = getattr(node_item.value[0][1], 'comment', None)
-                if nvc is not None:  # end comment already there
-                    nvc[0] = item_comment[2]
-                    nvc[1] = item_comment[3]
-                else:
-                    node_item.value[0][1].comment = item_comment[2:]
-            # if not (isinstance(node_item, ScalarNode) \
-            #    and not node_item.style):
-            #     best_style = False
-            value.append(node_item)
-        if flow_style is None:
-            if self.default_flow_style is not None:
-                node.flow_style = self.default_flow_style
-            else:
-                node.flow_style = best_style
-        return node
-
-    def represent_set(self, setting: Any) -> MappingNode:
-        flow_style = False
-        tag = Tag(suffix='tag:yaml.org,2002:set')
-        # return self.represent_mapping(tag, value)
-        value: List[Any] = []
-        flow_style = setting.fa.flow_style(flow_style)
-        try:
-            anchor = setting.yaml_anchor()
-        except AttributeError:
-            anchor = None
-        node = MappingNode(tag, value, flow_style=flow_style, anchor=anchor)
-        if self.alias_key is not None:
-            self.represented_objects[self.alias_key] = node
-        best_style = True
-        # no sorting! !!
-        try:
-            comment = getattr(setting, comment_attrib)
-            if node.comment is None:
-                node.comment = comment.comment
-            else:
-                # as we are potentially going to extend this, make a new list
-                node.comment = comment.comment[:]
-            if node.comment and node.comment[1]:
-                for ct in node.comment[1]:
-                    ct.reset()
-            item_comments = comment.items
-            for v in item_comments.values():
-                if v and v[1]:
-                    for ct in v[1]:
-                        ct.reset()
-            try:
-                node.comment.append(comment.end)
-            except AttributeError:
-                pass
-        except AttributeError:
-            item_comments = {}
-        for item_key in setting.odict:
-            node_key = self.represent_key(item_key)
-            node_value = self.represent_data(None)
-            item_comment = item_comments.get(item_key)
-            if item_comment:
-                assert getattr(node_key, 'comment', None) is None
-                node_key.comment = item_comment[:2]
-            node_key.style = '?'
-            node_value.style = '-' if flow_style else '?'
-            if not (isinstance(node_key, ScalarNode) and not node_key.style):
-                best_style = False
-            if not (isinstance(node_value, ScalarNode) and not node_value.style):
-                best_style = False
-            value.append((node_key, node_value))
-        best_style = best_style
-        return node
-
-    def represent_dict(self, data: Any) -> MappingNode:
-        """write out tag if saved on loading"""
-        try:
-            _ = data.tag
-        except AttributeError:
-            tag = Tag(suffix='tag:yaml.org,2002:map')
-        else:
-            if data.tag.trval:
-                if data.tag.startswith('!!'):
-                    tag = Tag(suffix='tag:yaml.org,2002:' + data.tag.trval[2:])
-                else:
-                    tag = data.tag
-            else:
-                tag = Tag(suffix='tag:yaml.org,2002:map')
-        return self.represent_mapping(tag, data)
-
-    def represent_list(self, data: Any) -> SequenceNode:
-        try:
-            _ = data.tag
-        except AttributeError:
-            tag = Tag(suffix='tag:yaml.org,2002:seq')
-        else:
-            if data.tag.trval:
-                if data.tag.startswith('!!'):
-                    tag = Tag(suffix='tag:yaml.org,2002:' + data.tag.trval[2:])
-                else:
-                    tag = data.tag
-            else:
-                tag = Tag(suffix='tag:yaml.org,2002:seq')
-        return self.represent_sequence(tag, data)
-
-    def represent_datetime(self, data: Any) -> ScalarNode:
-        inter = 'T' if data._yaml['t'] else ' '
-        _yaml = data._yaml
-        if False and _yaml['delta']:
-            data += _yaml['delta']
-            value = data.isoformat(inter)
-        else:
-            value = data.isoformat(inter).strip()
-        if False and _yaml['tz']:
-            value += _yaml['tz']
-        if data.tzinfo and str(data.tzinfo):
-            if value[-6] in '+-':
-                value = value[:-6] + str(data.tzinfo)
-        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
-
-    def represent_tagged_scalar(self, data: Any) -> ScalarNode:
-        try:
-            if data.tag.handle == '!!':
-                tag = f'{data.tag.handle} {data.tag.suffix}'
-            else:
-                tag = data.tag
-        except AttributeError:
-            tag = None
-        try:
-            anchor = data.yaml_anchor()
-        except AttributeError:
-            anchor = None
-        return self.represent_scalar(tag, data.value, style=data.style, anchor=anchor)
-
-    def represent_scalar_bool(self, data: Any) -> ScalarNode:
-        try:
-            anchor = data.yaml_anchor()
-        except AttributeError:
-            anchor = None
-        return SafeRepresenter.represent_bool(self, data, anchor=anchor)
-
-    def represent_yaml_object(
-        self, tag: Any, data: Any, cls: Any, flow_style: Optional[Any] = None,
-    ) -> MappingNode:
-        if hasattr(data, '__getstate__'):
-            state = data.__getstate__()
-        else:
-            state = data.__dict__.copy()
-        anchor = state.pop(Anchor.attrib, None)
-        res = self.represent_mapping(tag, state, flow_style=flow_style)
-        if anchor is not None:
-            res.anchor = anchor
-        return res
-
-
-RoundTripRepresenter.add_representer(type(None), RoundTripRepresenter.represent_none)
-
-RoundTripRepresenter.add_representer(
-    LiteralScalarString, RoundTripRepresenter.represent_literal_scalarstring,
-)
-
-RoundTripRepresenter.add_representer(
-    FoldedScalarString, RoundTripRepresenter.represent_folded_scalarstring,
-)
-
-RoundTripRepresenter.add_representer(
-    SingleQuotedScalarString, RoundTripRepresenter.represent_single_quoted_scalarstring,
-)
-
-RoundTripRepresenter.add_representer(
-    DoubleQuotedScalarString, RoundTripRepresenter.represent_double_quoted_scalarstring,
-)
-
-RoundTripRepresenter.add_representer(
-    PlainScalarString, RoundTripRepresenter.represent_plain_scalarstring,
-)
-
-# RoundTripRepresenter.add_representer(tuple, Representer.represent_tuple)
-
-RoundTripRepresenter.add_representer(ScalarInt, RoundTripRepresenter.represent_scalar_int)
-
-RoundTripRepresenter.add_representer(BinaryInt, RoundTripRepresenter.represent_binary_int)
-
-RoundTripRepresenter.add_representer(OctalInt, RoundTripRepresenter.represent_octal_int)
-
-RoundTripRepresenter.add_representer(HexInt, RoundTripRepresenter.represent_hex_int)
-
-RoundTripRepresenter.add_representer(HexCapsInt, RoundTripRepresenter.represent_hex_caps_int)
-
-RoundTripRepresenter.add_representer(ScalarFloat, RoundTripRepresenter.represent_scalar_float)
-
-RoundTripRepresenter.add_representer(ScalarBoolean, RoundTripRepresenter.represent_scalar_bool)
-
-RoundTripRepresenter.add_representer(CommentedSeq, RoundTripRepresenter.represent_list)
-
-RoundTripRepresenter.add_representer(CommentedMap, RoundTripRepresenter.represent_dict)
-
-RoundTripRepresenter.add_representer(
-    CommentedOrderedMap, RoundTripRepresenter.represent_ordereddict,
-)
-
-RoundTripRepresenter.add_representer(
-    collections.OrderedDict, RoundTripRepresenter.represent_ordereddict,
-)
-
-RoundTripRepresenter.add_representer(CommentedSet, RoundTripRepresenter.represent_set)
-
-RoundTripRepresenter.add_representer(
-    TaggedScalar, RoundTripRepresenter.represent_tagged_scalar,
-)
-
-RoundTripRepresenter.add_representer(TimeStamp, RoundTripRepresenter.represent_datetime)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py
deleted file mode 100644
index 0365cfce84d..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/resolver.py
+++ /dev/null
@@ -1,392 +0,0 @@
-
-from __future__ import annotations
-
-import re
-
-if False:  # MYPY
-    from typing import Any, Dict, List, Union, Text, Optional  # NOQA
-    from opentelemetry.agent._vendor.ruamel.yaml.compat import VersionType  # NOQA
-
-from opentelemetry.agent._vendor.ruamel.yaml.tag import Tag
-from opentelemetry.agent._vendor.ruamel.yaml.compat import _DEFAULT_YAML_VERSION  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.error import *  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.util import RegExp  # NOQA
-
-__all__ = ['BaseResolver', 'Resolver', 'VersionedResolver']
-
-
-# fmt: off
-# resolvers consist of
-# - a list of applicable version
-# - a tag
-# - a regexp
-# - a list of first characters to match
-implicit_resolvers = [
-    ([(1, 2)],
-        'tag:yaml.org,2002:bool',
-        RegExp('''^(?:true|True|TRUE|false|False|FALSE)$''', re.X),
-        list('tTfF')),
-    ([(1, 1)],
-        'tag:yaml.org,2002:bool',
-        RegExp('''^(?:y|Y|yes|Yes|YES|n|N|no|No|NO
-        |true|True|TRUE|false|False|FALSE
-        |on|On|ON|off|Off|OFF)$''', re.X),
-        list('yYnNtTfFoO')),
-    ([(1, 2)],
-        'tag:yaml.org,2002:float',
-        RegExp('''^(?:
-         [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
-        |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
-        |[-+]?\\.[0-9_]+(?:[eE][-+][0-9]+)?
-        |[-+]?\\.(?:inf|Inf|INF)
-        |\\.(?:nan|NaN|NAN))$''', re.X),
-        list('-+0123456789.')),
-    ([(1, 1)],
-        'tag:yaml.org,2002:float',
-        RegExp('''^(?:
-         [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
-        |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
-        |\\.[0-9_]+(?:[eE][-+][0-9]+)?
-        |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*  # sexagesimal float
-        |[-+]?\\.(?:inf|Inf|INF)
-        |\\.(?:nan|NaN|NAN))$''', re.X),
-        list('-+0123456789.')),
-    ([(1, 2)],
-        'tag:yaml.org,2002:int',
-        RegExp('''^(?:[-+]?0b[0-1_]+
-        |[-+]?0o?[0-7_]+
-        |[-+]?[0-9_]+
-        |[-+]?0x[0-9a-fA-F_]+)$''', re.X),
-        list('-+0123456789')),
-    ([(1, 1)],
-        'tag:yaml.org,2002:int',
-        RegExp('''^(?:[-+]?0b[0-1_]+
-        |[-+]?0?[0-7_]+
-        |[-+]?(?:0|[1-9][0-9_]*)
-        |[-+]?0x[0-9a-fA-F_]+
-        |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),  # sexagesimal int
-        list('-+0123456789')),
-    ([(1, 2), (1, 1)],
-        'tag:yaml.org,2002:merge',
-        RegExp('^(?:<<)$'),
-        ['<']),
-    ([(1, 2), (1, 1)],
-        'tag:yaml.org,2002:null',
-        RegExp('''^(?: ~
-        |null|Null|NULL
-        | )$''', re.X),
-        ['~', 'n', 'N', '']),
-    ([(1, 2), (1, 1)],
-        'tag:yaml.org,2002:timestamp',
-        RegExp('''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
-        |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
-        (?:[Tt]|[ \\t]+)[0-9][0-9]?
-        :[0-9][0-9] :[0-9][0-9] (?:\\.[0-9]*)?
-        (?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
-        list('0123456789')),
-    ([(1, 2), (1, 1)],
-        'tag:yaml.org,2002:value',
-        RegExp('^(?:=)$'),
-        ['=']),
-    # The following resolver is only for documentation purposes. It cannot work
-    # because plain scalars cannot start with '!', '&', or '*'.
-    ([(1, 2), (1, 1)],
-        'tag:yaml.org,2002:yaml',
-        RegExp('^(?:!|&|\\*)$'),
-        list('!&*')),
-]
-# fmt: on
-
-
-class ResolverError(YAMLError):
-    pass
-
-
-class BaseResolver:
-
-    DEFAULT_SCALAR_TAG = Tag(suffix='tag:yaml.org,2002:str')
-    DEFAULT_SEQUENCE_TAG = Tag(suffix='tag:yaml.org,2002:seq')
-    DEFAULT_MAPPING_TAG = Tag(suffix='tag:yaml.org,2002:map')
-
-    yaml_implicit_resolvers: Dict[Any, Any] = {}
-    yaml_path_resolvers: Dict[Any, Any] = {}
-
-    def __init__(self: Any, loadumper: Any = None) -> None:
-        self.loadumper = loadumper
-        if self.loadumper is not None and getattr(self.loadumper, '_resolver', None) is None:
-            self.loadumper._resolver = self.loadumper
-        self._loader_version: Any = None
-        self.resolver_exact_paths: List[Any] = []
-        self.resolver_prefix_paths: List[Any] = []
-
-    @property
-    def parser(self) -> Any:
-        if self.loadumper is not None:
-            if hasattr(self.loadumper, 'typ'):
-                return self.loadumper.parser
-            return self.loadumper._parser
-        return None
-
-    @classmethod
-    def add_implicit_resolver_base(cls, tag: Any, regexp: Any, first: Any) -> None:
-        if 'yaml_implicit_resolvers' not in cls.__dict__:
-            # deepcopy doesn't work here
-            cls.yaml_implicit_resolvers = {
-                k: cls.yaml_implicit_resolvers[k][:] for k in cls.yaml_implicit_resolvers
-            }
-        if first is None:
-            first = [None]
-        for ch in first:
-            cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
-
-    @classmethod
-    def add_implicit_resolver(cls, tag: Any, regexp: Any, first: Any) -> None:
-        if 'yaml_implicit_resolvers' not in cls.__dict__:
-            # deepcopy doesn't work here
-            cls.yaml_implicit_resolvers = {
-                k: cls.yaml_implicit_resolvers[k][:] for k in cls.yaml_implicit_resolvers
-            }
-        if first is None:
-            first = [None]
-        for ch in first:
-            cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
-        implicit_resolvers.append(([(1, 2), (1, 1)], tag, regexp, first))
-
-    # @classmethod
-    # def add_implicit_resolver(cls, tag, regexp, first):
-
-    @classmethod
-    def add_path_resolver(cls, tag: Any, path: Any, kind: Any = None) -> None:
-        # Note: `add_path_resolver` is experimental.  The API could be changed.
-        # `new_path` is a pattern that is matched against the path from the
-        # root to the node that is being considered.  `node_path` elements are
-        # tuples `(node_check, index_check)`.  `node_check` is a node class:
-        # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`.  `None`
-        # matches any kind of a node.  `index_check` could be `None`, a boolean
-        # value, a string value, or a number.  `None` and `False` match against
-        # any _value_ of sequence and mapping nodes.  `True` matches against
-        # any _key_ of a mapping node.  A string `index_check` matches against
-        # a mapping value that corresponds to a scalar key which content is
-        # equal to the `index_check` value.  An integer `index_check` matches
-        # against a sequence value with the index equal to `index_check`.
-        if 'yaml_path_resolvers' not in cls.__dict__:
-            cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy()
-        new_path: List[Any] = []
-        for element in path:
-            if isinstance(element, (list, tuple)):
-                if len(element) == 2:
-                    node_check, index_check = element
-                elif len(element) == 1:
-                    node_check = element[0]
-                    index_check = True
-                else:
-                    raise ResolverError(f'Invalid path element: {element!s}')
-            else:
-                node_check = None
-                index_check = element
-            if node_check is str:
-                node_check = ScalarNode
-            elif node_check is list:
-                node_check = SequenceNode
-            elif node_check is dict:
-                node_check = MappingNode
-            elif (
-                node_check not in [ScalarNode, SequenceNode, MappingNode]
-                and not isinstance(node_check, str)
-                and node_check is not None
-            ):
-                raise ResolverError(f'Invalid node checker: {node_check!s}')
-            if not isinstance(index_check, (str, int)) and index_check is not None:
-                raise ResolverError(f'Invalid index checker: {index_check!s}')
-            new_path.append((node_check, index_check))
-        if kind is str:
-            kind = ScalarNode
-        elif kind is list:
-            kind = SequenceNode
-        elif kind is dict:
-            kind = MappingNode
-        elif kind not in [ScalarNode, SequenceNode, MappingNode] and kind is not None:
-            raise ResolverError(f'Invalid node kind: {kind!s}')
-        cls.yaml_path_resolvers[tuple(new_path), kind] = tag
-
-    def descend_resolver(self, current_node: Any, current_index: Any) -> None:
-        if not self.yaml_path_resolvers:
-            return
-        exact_paths = {}
-        prefix_paths = []
-        if current_node:
-            depth = len(self.resolver_prefix_paths)
-            for path, kind in self.resolver_prefix_paths[-1]:
-                if self.check_resolver_prefix(depth, path, kind, current_node, current_index):
-                    if len(path) > depth:
-                        prefix_paths.append((path, kind))
-                    else:
-                        exact_paths[kind] = self.yaml_path_resolvers[path, kind]
-        else:
-            for path, kind in self.yaml_path_resolvers:
-                if not path:
-                    exact_paths[kind] = self.yaml_path_resolvers[path, kind]
-                else:
-                    prefix_paths.append((path, kind))
-        self.resolver_exact_paths.append(exact_paths)
-        self.resolver_prefix_paths.append(prefix_paths)
-
-    def ascend_resolver(self) -> None:
-        if not self.yaml_path_resolvers:
-            return
-        self.resolver_exact_paths.pop()
-        self.resolver_prefix_paths.pop()
-
-    def check_resolver_prefix(
-        self, depth: int, path: Any, kind: Any, current_node: Any, current_index: Any,
-    ) -> bool:
-        node_check, index_check = path[depth - 1]
-        if isinstance(node_check, str):
-            if current_node.tag != node_check:
-                return False
-        elif node_check is not None:
-            if not isinstance(current_node, node_check):
-                return False
-        if index_check is True and current_index is not None:
-            return False
-        if (index_check is False or index_check is None) and current_index is None:
-            return False
-        if isinstance(index_check, str):
-            if not (
-                isinstance(current_index, ScalarNode) and index_check == current_index.value
-            ):
-                return False
-        elif isinstance(index_check, int) and not isinstance(index_check, bool):
-            if index_check != current_index:
-                return False
-        return True
-
-    def resolve(self, kind: Any, value: Any, implicit: Any) -> Any:
-        if kind is ScalarNode and implicit[0]:
-            if value == "":
-                resolvers = self.yaml_implicit_resolvers.get("", [])
-            else:
-                resolvers = self.yaml_implicit_resolvers.get(value[0], [])
-            resolvers += self.yaml_implicit_resolvers.get(None, [])
-            for tag, regexp in resolvers:
-                if regexp.match(value):
-                    return Tag(suffix=tag)
-            implicit = implicit[1]
-        if bool(self.yaml_path_resolvers):
-            exact_paths = self.resolver_exact_paths[-1]
-            if kind in exact_paths:
-                return Tag(suffix=exact_paths[kind])
-            if None in exact_paths:
-                return Tag(suffix=exact_paths[None])
-        if kind is ScalarNode:
-            return self.DEFAULT_SCALAR_TAG
-        elif kind is SequenceNode:
-            return self.DEFAULT_SEQUENCE_TAG
-        elif kind is MappingNode:
-            return self.DEFAULT_MAPPING_TAG
-
-    @property
-    def processing_version(self) -> Any:
-        return None
-
-
-class Resolver(BaseResolver):
-    pass
-
-
-for ir in implicit_resolvers:
-    if (1, 2) in ir[0]:
-        Resolver.add_implicit_resolver_base(*ir[1:])
-
-
-class VersionedResolver(BaseResolver):
-    """
-    contrary to the "normal" resolver, the smart resolver delays loading
-    the pattern matching rules. That way it can decide to load 1.1 rules
-    or the (default) 1.2 rules, that no longer support octal without 0o, sexagesimals
-    and Yes/No/On/Off booleans.
-    """
-
-    def __init__(
-        self, version: Optional[VersionType] = None, loader: Any = None, loadumper: Any = None,
-    ) -> None:
-        if loader is None and loadumper is not None:
-            loader = loadumper
-        BaseResolver.__init__(self, loader)
-        self._loader_version = self.get_loader_version(version)
-        self._version_implicit_resolver: Dict[Any, Any] = {}
-
-    def add_version_implicit_resolver(
-        self, version: VersionType, tag: Any, regexp: Any, first: Any,
-    ) -> None:
-        if first is None:
-            first = [None]
-        impl_resolver = self._version_implicit_resolver.setdefault(version, {})
-        for ch in first:
-            impl_resolver.setdefault(ch, []).append((tag, regexp))
-
-    def get_loader_version(self, version: Optional[VersionType]) -> Any:
-        if version is None or isinstance(version, tuple):
-            return version
-        if isinstance(version, list):
-            return tuple(version)
-        # assume string
-        assert isinstance(version, str)
-        return tuple(map(int, version.split('.')))
-
-    @property
-    def versioned_resolver(self) -> Any:
-        """
-        select the resolver based on the version we are parsing
-        """
-        version = self.processing_version
-        if isinstance(version, str):
-            version = tuple(map(int, version.split('.')))
-        if version not in self._version_implicit_resolver:
-            for x in implicit_resolvers:
-                if version in x[0]:
-                    self.add_version_implicit_resolver(version, x[1], x[2], x[3])
-        return self._version_implicit_resolver[version]
-
-    def resolve(self, kind: Any, value: Any, implicit: Any) -> Any:
-        if kind is ScalarNode and implicit[0]:
-            if value == "":
-                resolvers = self.versioned_resolver.get("", [])
-            else:
-                resolvers = self.versioned_resolver.get(value[0], [])
-            resolvers += self.versioned_resolver.get(None, [])
-            for tag, regexp in resolvers:
-                if regexp.match(value):
-                    return Tag(suffix=tag)
-            implicit = implicit[1]
-        if bool(self.yaml_path_resolvers):
-            exact_paths = self.resolver_exact_paths[-1]
-            if kind in exact_paths:
-                return Tag(suffix=exact_paths[kind])
-            if None in exact_paths:
-                return Tag(suffix=exact_paths[None])
-        if kind is ScalarNode:
-            return self.DEFAULT_SCALAR_TAG
-        elif kind is SequenceNode:
-            return self.DEFAULT_SEQUENCE_TAG
-        elif kind is MappingNode:
-            return self.DEFAULT_MAPPING_TAG
-
-    @property
-    def processing_version(self) -> Any:
-        try:
-            version = self.loadumper._scanner.yaml_version
-        except AttributeError:
-            try:
-                if hasattr(self.loadumper, 'typ'):
-                    version = self.loadumper.version
-                else:
-                    version = self.loadumper._serializer.use_version  # dumping
-            except AttributeError:
-                version = None
-        if version is None:
-            version = self._loader_version
-            if version is None:
-                version = _DEFAULT_YAML_VERSION
-        return version
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py
deleted file mode 100644
index e834f89ca8f..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarbool.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""
-You cannot subclass bool, and this is necessary for round-tripping anchored
-bool values (and also if you want to preserve the original way of writing)
-
-bool.__bases__ is type 'int', so that is what is used as the basis for ScalarBoolean as well.
-
-You can use these in an if statement, but not when testing equivalence
-"""
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
-
-if False:  # MYPY
-    from typing import Text, Any, Dict, List  # NOQA
-
-__all__ = ['ScalarBoolean']
-
-
-class ScalarBoolean(int):
-    def __new__(cls: Any, *args: Any, **kw: Any) -> Any:
-        anchor = kw.pop('anchor', None)
-        b = int.__new__(cls, *args, **kw)
-        if anchor is not None:
-            b.yaml_set_anchor(anchor, always_dump=True)
-        return b
-
-    @property
-    def anchor(self) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            setattr(self, Anchor.attrib, Anchor())
-        return getattr(self, Anchor.attrib)
-
-    def yaml_anchor(self, any: bool = False) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            return None
-        if any or self.anchor.always_dump:
-            return self.anchor
-        return None
-
-    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
-        self.anchor.value = value
-        self.anchor.always_dump = always_dump
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py
deleted file mode 100644
index aaad4627d7f..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarfloat.py
+++ /dev/null
@@ -1,105 +0,0 @@
-
-from __future__ import annotations
-
-import sys
-from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
-
-if False:  # MYPY
-    from typing import Text, Any, Dict, List  # NOQA
-
-__all__ = ['ScalarFloat', 'ExponentialFloat', 'ExponentialCapsFloat']
-
-
-class ScalarFloat(float):
-    def __new__(cls: Any, *args: Any, **kw: Any) -> Any:
-        width = kw.pop('width', None)
-        prec = kw.pop('prec', None)
-        m_sign = kw.pop('m_sign', None)
-        m_lead0 = kw.pop('m_lead0', 0)
-        exp = kw.pop('exp', None)
-        e_width = kw.pop('e_width', None)
-        e_sign = kw.pop('e_sign', None)
-        underscore = kw.pop('underscore', None)
-        anchor = kw.pop('anchor', None)
-        v = float.__new__(cls, *args, **kw)
-        v._width = width
-        v._prec = prec
-        v._m_sign = m_sign
-        v._m_lead0 = m_lead0
-        v._exp = exp
-        v._e_width = e_width
-        v._e_sign = e_sign
-        v._underscore = underscore
-        if anchor is not None:
-            v.yaml_set_anchor(anchor, always_dump=True)
-        return v
-
-    def __iadd__(self, a: Any) -> Any:  # type: ignore
-        return float(self) + a
-        x = type(self)(self + a)
-        x._width = self._width
-        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
-        return x
-
-    def __ifloordiv__(self, a: Any) -> Any:  # type: ignore
-        return float(self) // a
-        x = type(self)(self // a)
-        x._width = self._width
-        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
-        return x
-
-    def __imul__(self, a: Any) -> Any:  # type: ignore
-        return float(self) * a
-        x = type(self)(self * a)
-        x._width = self._width
-        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
-        x._prec = self._prec  # check for others
-        return x
-
-    def __ipow__(self, a: Any) -> Any:  # type: ignore
-        return float(self) ** a
-        x = type(self)(self ** a)
-        x._width = self._width
-        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
-        return x
-
-    def __isub__(self, a: Any) -> Any:  # type: ignore
-        return float(self) - a
-        x = type(self)(self - a)
-        x._width = self._width
-        x._underscore = self._underscore[:] if self._underscore is not None else None  # NOQA
-        return x
-
-    @property
-    def anchor(self) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            setattr(self, Anchor.attrib, Anchor())
-        return getattr(self, Anchor.attrib)
-
-    def yaml_anchor(self, any: bool = False) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            return None
-        if any or self.anchor.always_dump:
-            return self.anchor
-        return None
-
-    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
-        self.anchor.value = value
-        self.anchor.always_dump = always_dump
-
-    def dump(self, out: Any = sys.stdout) -> None:
-        out.write(
-            f'ScalarFloat({self}| w:{self._width}, p:{self._prec}, '  # type: ignore
-            f's:{self._m_sign}, lz:{self._m_lead0}, _:{self._underscore}|{self._exp}'
-            f', w:{self._e_width}, s:{self._e_sign})\n',
-        )
-
-
-class ExponentialFloat(ScalarFloat):
-    def __new__(cls, value: Any, width: Any = None, underscore: Any = None) -> Any:
-        return ScalarFloat.__new__(cls, value, width=width, underscore=underscore)
-
-
-class ExponentialCapsFloat(ScalarFloat):
-    def __new__(cls, value: Any, width: Any = None, underscore: Any = None) -> Any:
-        return ScalarFloat.__new__(cls, value, width=width, underscore=underscore)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py
deleted file mode 100644
index bb0d1681d66..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarint.py
+++ /dev/null
@@ -1,124 +0,0 @@
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
-
-if False:  # MYPY
-    from typing import Text, Any, Dict, List  # NOQA
-
-__all__ = ['ScalarInt', 'BinaryInt', 'OctalInt', 'HexInt', 'HexCapsInt', 'DecimalInt']
-
-
-class ScalarInt(int):
-    def __new__(cls: Any, *args: Any, **kw: Any) -> Any:
-        width = kw.pop('width', None)
-        underscore = kw.pop('underscore', None)
-        anchor = kw.pop('anchor', None)
-        v = int.__new__(cls, *args, **kw)
-        v._width = width
-        v._underscore = underscore
-        if anchor is not None:
-            v.yaml_set_anchor(anchor, always_dump=True)
-        return v
-
-    def __iadd__(self, a: Any) -> Any:  # type: ignore
-        x = type(self)(self + a)
-        x._width = self._width  # type: ignore
-        x._underscore = (  # type: ignore
-            self._underscore[:] if self._underscore is not None else None  # type: ignore
-        )  # NOQA
-        return x
-
-    def __ifloordiv__(self, a: Any) -> Any:  # type: ignore
-        x = type(self)(self // a)
-        x._width = self._width  # type: ignore
-        x._underscore = (  # type: ignore
-            self._underscore[:] if self._underscore is not None else None  # type: ignore
-        )  # NOQA
-        return x
-
-    def __imul__(self, a: Any) -> Any:  # type: ignore
-        x = type(self)(self * a)
-        x._width = self._width  # type: ignore
-        x._underscore = (  # type: ignore
-            self._underscore[:] if self._underscore is not None else None  # type: ignore
-        )  # NOQA
-        return x
-
-    def __ipow__(self, a: Any) -> Any:  # type: ignore
-        x = type(self)(self ** a)
-        x._width = self._width  # type: ignore
-        x._underscore = (  # type: ignore
-            self._underscore[:] if self._underscore is not None else None  # type: ignore
-        )  # NOQA
-        return x
-
-    def __isub__(self, a: Any) -> Any:  # type: ignore
-        x = type(self)(self - a)
-        x._width = self._width  # type: ignore
-        x._underscore = (  # type: ignore
-            self._underscore[:] if self._underscore is not None else None  # type: ignore
-        )  # NOQA
-        return x
-
-    @property
-    def anchor(self) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            setattr(self, Anchor.attrib, Anchor())
-        return getattr(self, Anchor.attrib)
-
-    def yaml_anchor(self, any: bool = False) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            return None
-        if any or self.anchor.always_dump:
-            return self.anchor
-        return None
-
-    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
-        self.anchor.value = value
-        self.anchor.always_dump = always_dump
-
-
-class BinaryInt(ScalarInt):
-    def __new__(
-        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
-    ) -> Any:
-        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
-
-
-class OctalInt(ScalarInt):
-    def __new__(
-        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
-    ) -> Any:
-        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
-
-
-# mixed casing of A-F is not supported, when loading the first non digit
-# determines the case
-
-
-class HexInt(ScalarInt):
-    """uses lower case (a-f)"""
-
-    def __new__(
-        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
-    ) -> Any:
-        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
-
-
-class HexCapsInt(ScalarInt):
-    """uses upper case (A-F)"""
-
-    def __new__(
-        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
-    ) -> Any:
-        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
-
-
-class DecimalInt(ScalarInt):
-    """needed if anchor"""
-
-    def __new__(
-        cls, value: Any, width: Any = None, underscore: Any = None, anchor: Any = None,
-    ) -> Any:
-        return ScalarInt.__new__(cls, value, width=width, underscore=underscore, anchor=anchor)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py
deleted file mode 100644
index 4c7d2248fa7..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scalarstring.py
+++ /dev/null
@@ -1,142 +0,0 @@
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.anchor import Anchor
-
-if False:  # MYPY
-    from typing import Text, Any, Dict, List  # NOQA
-    from opentelemetry.agent._vendor.ruamel.yaml.compat import SupportsIndex
-
-__all__ = [
-    'ScalarString',
-    'LiteralScalarString',
-    'FoldedScalarString',
-    'SingleQuotedScalarString',
-    'DoubleQuotedScalarString',
-    'PlainScalarString',
-    # PreservedScalarString is the old name, as it was the first to be preserved on rt,
-    # use LiteralScalarString instead
-    'PreservedScalarString',
-]
-
-
-class ScalarString(str):
-    __slots__ = Anchor.attrib
-
-    def __new__(cls, *args: Any, **kw: Any) -> Any:
-        anchor = kw.pop('anchor', None)
-        ret_val = str.__new__(cls, *args, **kw)
-        if anchor is not None:
-            ret_val.yaml_set_anchor(anchor, always_dump=True)
-        return ret_val
-
-    def replace(self, old: Any, new: Any, maxreplace: SupportsIndex = -1) -> Any:
-        return type(self)((str.replace(self, old, new, maxreplace)))
-
-    @property
-    def anchor(self) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            setattr(self, Anchor.attrib, Anchor())
-        return getattr(self, Anchor.attrib)
-
-    def yaml_anchor(self, any: bool = False) -> Any:
-        if not hasattr(self, Anchor.attrib):
-            return None
-        if any or self.anchor.always_dump:
-            return self.anchor
-        return None
-
-    def yaml_set_anchor(self, value: Any, always_dump: bool = False) -> None:
-        self.anchor.value = value
-        self.anchor.always_dump = always_dump
-
-
-class LiteralScalarString(ScalarString):
-    __slots__ = 'comment'  # the comment after the | on the first line
-
-    style = '|'
-
-    def __new__(cls, value: Text, anchor: Any = None) -> Any:
-        return ScalarString.__new__(cls, value, anchor=anchor)
-
-
-PreservedScalarString = LiteralScalarString
-
-
-class FoldedScalarString(ScalarString):
-    __slots__ = ('fold_pos', 'comment')  # the comment after the > on the first line
-
-    style = '>'
-
-    def __new__(cls, value: Text, anchor: Any = None) -> Any:
-        return ScalarString.__new__(cls, value, anchor=anchor)
-
-
-class SingleQuotedScalarString(ScalarString):
-    __slots__ = ()
-
-    style = "'"
-
-    def __new__(cls, value: Text, anchor: Any = None) -> Any:
-        return ScalarString.__new__(cls, value, anchor=anchor)
-
-
-class DoubleQuotedScalarString(ScalarString):
-    __slots__ = ()
-
-    style = '"'
-
-    def __new__(cls, value: Text, anchor: Any = None) -> Any:
-        return ScalarString.__new__(cls, value, anchor=anchor)
-
-
-class PlainScalarString(ScalarString):
-    __slots__ = ()
-
-    style = ''
-
-    def __new__(cls, value: Text, anchor: Any = None) -> Any:
-        return ScalarString.__new__(cls, value, anchor=anchor)
-
-
-def preserve_literal(s: Text) -> Text:
-    return LiteralScalarString(s.replace('\r\n', '\n').replace('\r', '\n'))
-
-
-def walk_tree(base: Any, map: Any = None) -> None:
-    """
-    the routine here walks over a simple yaml tree (recursing in
-    dict values and list items) and converts strings that
-    have multiple lines to literal scalars
-
-    You can also provide an explicit (ordered) mapping for multiple transforms
-    (first of which is executed):
-        map = ruamel.yaml.compat.ordereddict
-        map['\n'] = preserve_literal
-        map[':'] = SingleQuotedScalarString
-        walk_tree(data, map=map)
-    """
-    from collections.abc import MutableMapping, MutableSequence
-
-    if map is None:
-        map = {'\n': preserve_literal}
-
-    if isinstance(base, MutableMapping):
-        for k in base:
-            v: Text = base[k]
-            if isinstance(v, str):
-                for ch in map:
-                    if ch in v:
-                        base[k] = map[ch](v)
-                        break
-            else:
-                walk_tree(v, map=map)
-    elif isinstance(base, MutableSequence):
-        for idx, elem in enumerate(base):
-            if isinstance(elem, str):
-                for ch in map:
-                    if ch in elem:
-                        base[idx] = map[ch](elem)
-                        break
-            else:
-                walk_tree(elem, map=map)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py
deleted file mode 100644
index 3a8cfcd3f5e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/scanner.py
+++ /dev/null
@@ -1,2390 +0,0 @@
-
-from __future__ import annotations
-
-# Scanner produces tokens of the following types:
-# STREAM-START
-# STREAM-END
-# DIRECTIVE(name, value)
-# DOCUMENT-START
-# DOCUMENT-END
-# BLOCK-SEQUENCE-START
-# BLOCK-MAPPING-START
-# BLOCK-END
-# FLOW-SEQUENCE-START
-# FLOW-MAPPING-START
-# FLOW-SEQUENCE-END
-# FLOW-MAPPING-END
-# BLOCK-ENTRY
-# FLOW-ENTRY
-# KEY
-# VALUE
-# ALIAS(value)
-# ANCHOR(value)
-# TAG(value)
-# SCALAR(value, plain, style)
-#
-# RoundTripScanner
-# COMMENT(value)
-#
-# Read comments in the Scanner code for more details.
-#
-
-from opentelemetry.agent._vendor.ruamel.yaml.error import MarkedYAMLError
-from opentelemetry.agent._vendor.ruamel.yaml import tokens as tokens
-from opentelemetry.agent._vendor.ruamel.yaml.docinfo import Version  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.compat import check_anchorname_char, _debug, nprint, nprintf  # NOQA
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Union, Text, Tuple  # NOQA
-
-__all__ = ['Scanner', 'RoundTripScanner', 'ScannerError']
-
-
-_THE_END = '\n\0\r\x85\u2028\u2029'
-_THE_END_SPACE_TAB = ' \n\0\t\r\x85\u2028\u2029'
-_SPACE_TAB = ' \t'
-
-
-if _debug != 0:
-    def xprintf(*args: Any, **kw: Any) -> Any:
-        return nprintf(*args, **kw)
-
-
-class ScannerError(MarkedYAMLError):
-    pass
-
-
-class SimpleKey:
-    # See below simple keys treatment.
-
-    def __init__(
-        self, token_number: Any, required: Any, index: int, line: int, column: int, mark: Any,
-    ) -> None:
-        self.token_number = token_number
-        self.required = required
-        self.index = index
-        self.line = line
-        self.column = column
-        self.mark = mark
-
-
-class Scanner:
-    def __init__(self, loader: Any = None) -> None:
-        """Initialize the scanner."""
-        # It is assumed that Scanner and Reader will have a common descendant.
-        # Reader do the dirty work of checking for BOM and converting the
-        # input data to Unicode. It also adds NUL to the end.
-        #
-        # Reader supports the following methods
-        #   self.peek(i=0)    # peek the next i-th character
-        #   self.prefix(l=1)  # peek the next l characters
-        #   self.forward(l=1) # read the next l characters and move the pointer
-
-        self.loader = loader
-        if self.loader is not None and getattr(self.loader, '_scanner', None) is None:
-            self.loader._scanner = self
-        self.reset_scanner()
-        self.first_time = False
-
-    @property
-    def flow_level(self) -> int:
-        return len(self.flow_context)
-
-    def reset_scanner(self) -> None:
-        # Had we reached the end of the stream?
-        self.done = False
-
-        # flow_context is an expanding/shrinking list consisting of '{' and '['
-        # for each unclosed flow context. If empty list that means block context
-        self.flow_context: List[Text] = []
-
-        # List of processed tokens that are not yet emitted.
-        self.tokens: List[Any] = []
-
-        # Add the STREAM-START token.
-        self.fetch_stream_start()
-
-        # Number of tokens that were emitted through the `get_token` method.
-        self.tokens_taken = 0
-
-        # The current indentation level.
-        self.indent = -1
-
-        # Past indentation levels.
-        self.indents: List[int] = []
-
-        # Variables related to simple keys treatment.
-
-        # A simple key is a key that is not denoted by the '?' indicator.
-        # Example of simple keys:
-        #   ---
-        #   block simple key: value
-        #   ? not a simple key:
-        #   : { flow simple key: value }
-        # We emit the KEY token before all keys, so when we find a potential
-        # simple key, we try to locate the corresponding ':' indicator.
-        # Simple keys should be limited to a single line and 1024 characters.
-
-        # Can a simple key start at the current position? A simple key may
-        # start:
-        # - at the beginning of the line, not counting indentation spaces
-        #       (in block context),
-        # - after '{', '[', ',' (in the flow context),
-        # - after '?', ':', '-' (in the block context).
-        # In the block context, this flag also signifies if a block collection
-        # may start at the current position.
-        self.allow_simple_key = True
-
-        # Keep track of possible simple keys. This is a dictionary. The key
-        # is `flow_level`; there can be no more that one possible simple key
-        # for each level. The value is a SimpleKey record:
-        #   (token_number, required, index, line, column, mark)
-        # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow),
-        # '[', or '{' tokens.
-        self.possible_simple_keys: Dict[Any, Any] = {}
-        self.yaml_version: Any = None
-        self.tag_directives: List[Tuple[Any, Any]] = []
-
-    @property
-    def reader(self) -> Any:
-        try:
-            return self._scanner_reader  # type: ignore
-        except AttributeError:
-            if hasattr(self.loader, 'typ'):
-                self._scanner_reader = self.loader.reader
-            else:
-                self._scanner_reader = self.loader._reader
-            return self._scanner_reader
-
-    @property
-    def scanner_processing_version(self) -> Any:  # prefix until un-composited
-        if hasattr(self.loader, 'typ'):
-            return self.loader.resolver.processing_version
-        return self.loader.processing_version
-
-    # Public methods.
-
-    def check_token(self, *choices: Any) -> bool:
-        # Check if the next token is one of the given types.
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-        if len(self.tokens) > 0:
-            if not choices:
-                return True
-            for choice in choices:
-                if isinstance(self.tokens[0], choice):
-                    return True
-        return False
-
-    def peek_token(self) -> Any:
-        # Return the next token, but do not delete if from the queue.
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-        if len(self.tokens) > 0:
-            return self.tokens[0]
-
-    def get_token(self) -> Any:
-        # Return the next token.
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-        if len(self.tokens) > 0:
-            self.tokens_taken += 1
-            return self.tokens.pop(0)
-
-    # Private methods.
-
-    def need_more_tokens(self) -> bool:
-        if self.done:
-            return False
-        if len(self.tokens) == 0:
-            return True
-        # The current token may be a potential simple key, so we
-        # need to look further.
-        self.stale_possible_simple_keys()
-        if self.next_possible_simple_key() == self.tokens_taken:
-            return True
-        return False
-
-    def fetch_comment(self, comment: Any) -> None:
-        raise NotImplementedError
-
-    def fetch_more_tokens(self) -> Any:
-        # Eat whitespaces and comments until we reach the next token.
-        comment = self.scan_to_next_token()
-        if comment is not None:  # never happens for base scanner
-            return self.fetch_comment(comment)
-        # Remove obsolete possible simple keys.
-        self.stale_possible_simple_keys()
-
-        # Compare the current indentation and column. It may add some tokens
-        # and decrease the current indentation level.
-        self.unwind_indent(self.reader.column)
-
-        # Peek the next character.
-        ch = self.reader.peek()
-
-        # Is it the end of stream?
-        if ch == '\0':
-            return self.fetch_stream_end()
-
-        # Is it a directive?
-        if ch == '%' and self.check_directive():
-            return self.fetch_directive()
-
-        # Is it the document start?
-        if ch == '-' and self.check_document_start():
-            return self.fetch_document_start()
-
-        # Is it the document end?
-        if ch == '.' and self.check_document_end():
-            return self.fetch_document_end()
-
-        # TODO: support for BOM within a stream.
-        # if ch == '\uFEFF':
-        #     return self.fetch_bom()    <-- issue BOMToken
-
-        # Note: the order of the following checks is NOT significant.
-
-        # Is it the flow sequence start indicator?
-        if ch == '[':
-            return self.fetch_flow_sequence_start()
-
-        # Is it the flow mapping start indicator?
-        if ch == '{':
-            return self.fetch_flow_mapping_start()
-
-        # Is it the flow sequence end indicator?
-        if ch == ']':
-            return self.fetch_flow_sequence_end()
-
-        # Is it the flow mapping end indicator?
-        if ch == '}':
-            return self.fetch_flow_mapping_end()
-
-        # Is it the flow entry indicator?
-        if ch == ',':
-            return self.fetch_flow_entry()
-
-        # Is it the block entry indicator?
-        if ch == '-' and self.check_block_entry():
-            return self.fetch_block_entry()
-
-        # Is it the key indicator?
-        if ch == '?' and self.check_key():
-            return self.fetch_key()
-
-        # Is it the value indicator?
-        if ch == ':' and self.check_value():
-            return self.fetch_value()
-
-        # Is it an alias?
-        if ch == '*':
-            return self.fetch_alias()
-
-        # Is it an anchor?
-        if ch == '&':
-            return self.fetch_anchor()
-
-        # Is it a tag?
-        if ch == '!':
-            return self.fetch_tag()
-
-        # Is it a literal scalar?
-        if ch == '|' and not self.flow_level:
-            return self.fetch_literal()
-
-        # Is it a folded scalar?
-        if ch == '>' and not self.flow_level:
-            return self.fetch_folded()
-
-        # Is it a single quoted scalar?
-        if ch == "'":
-            return self.fetch_single()
-
-        # Is it a double quoted scalar?
-        if ch == '"':
-            return self.fetch_double()
-
-        # It must be a plain scalar then.
-        if self.check_plain():
-            return self.fetch_plain()
-
-        # No? It's an error. Let's produce a nice error message.
-        raise ScannerError(
-            'while scanning for the next token',
-            None,
-            f'found character {ch!r} that cannot start any token',
-            self.reader.get_mark(),
-        )
-
-    # Simple keys treatment.
-
-    def next_possible_simple_key(self) -> Any:
-        # Return the number of the nearest possible simple key. Actually we
-        # don't need to loop through the whole dictionary. We may replace it
-        # with the following code:
-        #   if not self.possible_simple_keys:
-        #       return None
-        #   return self.possible_simple_keys[
-        #           min(self.possible_simple_keys.keys())].token_number
-        min_token_number = None
-        for level in self.possible_simple_keys:
-            key = self.possible_simple_keys[level]
-            if min_token_number is None or key.token_number < min_token_number:
-                min_token_number = key.token_number
-        return min_token_number
-
-    def stale_possible_simple_keys(self) -> None:
-        # Remove entries that are no longer possible simple keys. According to
-        # the YAML specification, simple keys
-        # - should be limited to a single line,
-        # - should be no longer than 1024 characters.
-        # Disabling this procedure will allow simple keys of any length and
-        # height (may cause problems if indentation is broken though).
-        for level in list(self.possible_simple_keys):
-            key = self.possible_simple_keys[level]
-            if key.line != self.reader.line or self.reader.index - key.index > 1024:
-                if key.required:
-                    raise ScannerError(
-                        'while scanning a simple key',
-                        key.mark,
-                        "could not find expected ':'",
-                        self.reader.get_mark(),
-                    )
-                del self.possible_simple_keys[level]
-
-    def save_possible_simple_key(self) -> None:
-        # The next token may start a simple key. We check if it's possible
-        # and save its position. This function is called for
-        #   ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'.
-
-        # Check if a simple key is required at the current position.
-        required = not self.flow_level and self.indent == self.reader.column
-
-        # The next token might be a simple key. Let's save it's number and
-        # position.
-        if self.allow_simple_key:
-            self.remove_possible_simple_key()
-            token_number = self.tokens_taken + len(self.tokens)
-            key = SimpleKey(
-                token_number,
-                required,
-                self.reader.index,
-                self.reader.line,
-                self.reader.column,
-                self.reader.get_mark(),
-            )
-            self.possible_simple_keys[self.flow_level] = key
-
-    def remove_possible_simple_key(self) -> None:
-        # Remove the saved possible key position at the current flow level.
-        if self.flow_level in self.possible_simple_keys:
-            key = self.possible_simple_keys[self.flow_level]
-
-            if key.required:
-                raise ScannerError(
-                    'while scanning a simple key',
-                    key.mark,
-                    "could not find expected ':'",
-                    self.reader.get_mark(),
-                )
-
-            del self.possible_simple_keys[self.flow_level]
-
-    # Indentation functions.
-
-    def unwind_indent(self, column: Any) -> None:
-        # In flow context, tokens should respect indentation.
-        # Actually the condition should be `self.indent >= column` according to
-        # the spec. But this condition will prohibit intuitively correct
-        # constructions such as
-        # key : {
-        # }
-        # ####
-        # if self.flow_level and self.indent > column:
-        #     raise ScannerError(None, None,
-        #             "invalid intendation or unclosed '[' or '{'",
-        #             self.reader.get_mark())
-
-        # In the flow context, indentation is ignored. We make the scanner less
-        # restrictive then specification requires.
-        if bool(self.flow_level):
-            return
-
-        # In block context, we may need to issue the BLOCK-END tokens.
-        while self.indent > column:
-            mark = self.reader.get_mark()
-            self.indent = self.indents.pop()
-            self.tokens.append(tokens.BlockEndToken(mark, mark))
-
-    def add_indent(self, column: int) -> bool:
-        # Check if we need to increase indentation.
-        if self.indent < column:
-            self.indents.append(self.indent)
-            self.indent = column
-            return True
-        return False
-
-    # Fetchers.
-
-    def fetch_stream_start(self) -> None:
-        # We always add STREAM-START as the first token and STREAM-END as the
-        # last token.
-        # Read the token.
-        mark = self.reader.get_mark()
-        # Add STREAM-START.
-        self.tokens.append(tokens.StreamStartToken(mark, mark, encoding=self.reader.encoding))
-
-    def fetch_stream_end(self) -> None:
-        # Set the current intendation to -1.
-        self.unwind_indent(-1)
-        # Reset simple keys.
-        self.remove_possible_simple_key()
-        self.allow_simple_key = False
-        self.possible_simple_keys = {}
-        # Read the token.
-        mark = self.reader.get_mark()
-        # Add STREAM-END.
-        self.tokens.append(tokens.StreamEndToken(mark, mark))
-        # The steam is finished.
-        self.done = True
-
-    def fetch_directive(self) -> None:
-        # Set the current intendation to -1.
-        self.unwind_indent(-1)
-
-        # Reset simple keys.
-        self.remove_possible_simple_key()
-        self.allow_simple_key = False
-
-        # Scan and add DIRECTIVE.
-        self.tokens.append(self.scan_directive())
-
-    def fetch_document_start(self) -> None:
-        self.fetch_document_indicator(tokens.DocumentStartToken)
-
-    def fetch_document_end(self) -> None:
-        self.fetch_document_indicator(tokens.DocumentEndToken)
-
-    def fetch_document_indicator(self, TokenClass: Any) -> None:
-        # Set the current intendation to -1.
-        self.unwind_indent(-1)
-
-        # Reset simple keys. Note that there could not be a block collection
-        # after '---'.
-        self.remove_possible_simple_key()
-        self.allow_simple_key = False
-
-        # Add DOCUMENT-START or DOCUMENT-END.
-        start_mark = self.reader.get_mark()
-        self.reader.forward(3)
-        end_mark = self.reader.get_mark()
-        self.tokens.append(TokenClass(start_mark, end_mark))
-
-    def fetch_flow_sequence_start(self) -> None:
-        self.fetch_flow_collection_start(tokens.FlowSequenceStartToken, to_push='[')
-
-    def fetch_flow_mapping_start(self) -> None:
-        self.fetch_flow_collection_start(tokens.FlowMappingStartToken, to_push='{')
-
-    def fetch_flow_collection_start(self, TokenClass: Any, to_push: Text) -> None:
-        # '[' and '{' may start a simple key.
-        self.save_possible_simple_key()
-        # Increase the flow level.
-        self.flow_context.append(to_push)
-        # Simple keys are allowed after '[' and '{'.
-        self.allow_simple_key = True
-        # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START.
-        start_mark = self.reader.get_mark()
-        self.reader.forward()
-        end_mark = self.reader.get_mark()
-        self.tokens.append(TokenClass(start_mark, end_mark))
-
-    def fetch_flow_sequence_end(self) -> None:
-        self.fetch_flow_collection_end(tokens.FlowSequenceEndToken)
-
-    def fetch_flow_mapping_end(self) -> None:
-        self.fetch_flow_collection_end(tokens.FlowMappingEndToken)
-
-    def fetch_flow_collection_end(self, TokenClass: Any) -> None:
-        # Reset possible simple key on the current level.
-        self.remove_possible_simple_key()
-        # Decrease the flow level.
-        try:
-            popped = self.flow_context.pop()  # NOQA
-        except IndexError:
-            # We must not be in a list or object.
-            # Defer error handling to the parser.
-            pass
-        # No simple keys after ']' or '}'.
-        self.allow_simple_key = False
-        # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END.
-        start_mark = self.reader.get_mark()
-        self.reader.forward()
-        end_mark = self.reader.get_mark()
-        self.tokens.append(TokenClass(start_mark, end_mark))
-
-    def fetch_flow_entry(self) -> None:
-        # Simple keys are allowed after ','.
-        self.allow_simple_key = True
-        # Reset possible simple key on the current level.
-        self.remove_possible_simple_key()
-        # Add FLOW-ENTRY.
-        start_mark = self.reader.get_mark()
-        self.reader.forward()
-        end_mark = self.reader.get_mark()
-        self.tokens.append(tokens.FlowEntryToken(start_mark, end_mark))
-
-    def fetch_block_entry(self) -> None:
-        # Block context needs additional checks.
-        if not self.flow_level:
-            # Are we allowed to start a new entry?
-            if not self.allow_simple_key:
-                raise ScannerError(
-                    None,
-                    None,
-                    'sequence entries are not allowed here',
-                    self.reader.get_mark(),
-                )
-            # We may need to add BLOCK-SEQUENCE-START.
-            if self.add_indent(self.reader.column):
-                mark = self.reader.get_mark()
-                self.tokens.append(tokens.BlockSequenceStartToken(mark, mark))
-        # It's an error for the block entry to occur in the flow context,
-        # but we let the parser detect this.
-        else:
-            pass
-        # Simple keys are allowed after '-'.
-        self.allow_simple_key = True
-        # Reset possible simple key on the current level.
-        self.remove_possible_simple_key()
-
-        # Add BLOCK-ENTRY.
-        start_mark = self.reader.get_mark()
-        self.reader.forward()
-        end_mark = self.reader.get_mark()
-        self.tokens.append(tokens.BlockEntryToken(start_mark, end_mark))
-
-    def fetch_key(self) -> None:
-        # Block context needs additional checks.
-        if not self.flow_level:
-
-            # Are we allowed to start a key (not nessesary a simple)?
-            if not self.allow_simple_key:
-                raise ScannerError(
-                    None, None, 'mapping keys are not allowed here', self.reader.get_mark(),
-                )
-
-            # We may need to add BLOCK-MAPPING-START.
-            if self.add_indent(self.reader.column):
-                mark = self.reader.get_mark()
-                self.tokens.append(tokens.BlockMappingStartToken(mark, mark))
-
-        # Simple keys are allowed after '?' in the block context.
-        self.allow_simple_key = not self.flow_level
-
-        # Reset possible simple key on the current level.
-        self.remove_possible_simple_key()
-
-        # Add KEY.
-        start_mark = self.reader.get_mark()
-        self.reader.forward()
-        end_mark = self.reader.get_mark()
-        self.tokens.append(tokens.KeyToken(start_mark, end_mark))
-
-    def fetch_value(self) -> None:
-        # Do we determine a simple key?
-        if self.flow_level in self.possible_simple_keys:
-            # Add KEY.
-            key = self.possible_simple_keys[self.flow_level]
-            del self.possible_simple_keys[self.flow_level]
-            self.tokens.insert(
-                key.token_number - self.tokens_taken, tokens.KeyToken(key.mark, key.mark),
-            )
-
-            # If this key starts a new block mapping, we need to add
-            # BLOCK-MAPPING-START.
-            if not self.flow_level:
-                if self.add_indent(key.column):
-                    self.tokens.insert(
-                        key.token_number - self.tokens_taken,
-                        tokens.BlockMappingStartToken(key.mark, key.mark),
-                    )
-
-            # There cannot be two simple keys one after another.
-            self.allow_simple_key = False
-
-        # It must be a part of a complex key.
-        else:
-
-            # Block context needs additional checks.
-            # (Do we really need them? They will be caught by the parser
-            # anyway.)
-            if not self.flow_level:
-
-                # We are allowed to start a complex value if and only if
-                # we can start a simple key.
-                if not self.allow_simple_key:
-                    raise ScannerError(
-                        None,
-                        None,
-                        'mapping values are not allowed here',
-                        self.reader.get_mark(),
-                    )
-
-            # If this value starts a new block mapping, we need to add
-            # BLOCK-MAPPING-START.  It will be detected as an error later by
-            # the parser.
-            if not self.flow_level:
-                if self.add_indent(self.reader.column):
-                    mark = self.reader.get_mark()
-                    self.tokens.append(tokens.BlockMappingStartToken(mark, mark))
-
-            # Simple keys are allowed after ':' in the block context.
-            self.allow_simple_key = not self.flow_level
-
-            # Reset possible simple key on the current level.
-            self.remove_possible_simple_key()
-
-        # Add VALUE.
-        start_mark = self.reader.get_mark()
-        self.reader.forward()
-        end_mark = self.reader.get_mark()
-        self.tokens.append(tokens.ValueToken(start_mark, end_mark))
-
-    def fetch_alias(self) -> None:
-        # ALIAS could be a simple key.
-        self.save_possible_simple_key()
-        # No simple keys after ALIAS.
-        self.allow_simple_key = False
-        # Scan and add ALIAS.
-        self.tokens.append(self.scan_anchor(tokens.AliasToken))
-
-    def fetch_anchor(self) -> None:
-        # ANCHOR could start a simple key.
-        self.save_possible_simple_key()
-        # No simple keys after ANCHOR.
-        self.allow_simple_key = False
-        # Scan and add ANCHOR.
-        self.tokens.append(self.scan_anchor(tokens.AnchorToken))
-
-    def fetch_tag(self) -> None:
-        # TAG could start a simple key.
-        self.save_possible_simple_key()
-        # No simple keys after TAG.
-        self.allow_simple_key = False
-        # Scan and add TAG.
-        self.tokens.append(self.scan_tag())
-
-    def fetch_literal(self) -> None:
-        self.fetch_block_scalar(style='|')
-
-    def fetch_folded(self) -> None:
-        self.fetch_block_scalar(style='>')
-
-    def fetch_block_scalar(self, style: Any) -> None:
-        # A simple key may follow a block scalar.
-        self.allow_simple_key = True
-        # Reset possible simple key on the current level.
-        self.remove_possible_simple_key()
-        # Scan and add SCALAR.
-        self.tokens.append(self.scan_block_scalar(style))
-
-    def fetch_single(self) -> None:
-        self.fetch_flow_scalar(style="'")
-
-    def fetch_double(self) -> None:
-        self.fetch_flow_scalar(style='"')
-
-    def fetch_flow_scalar(self, style: Any) -> None:
-        # A flow scalar could be a simple key.
-        self.save_possible_simple_key()
-        # No simple keys after flow scalars.
-        self.allow_simple_key = False
-        # Scan and add SCALAR.
-        self.tokens.append(self.scan_flow_scalar(style))
-
-    def fetch_plain(self) -> None:
-        # A plain scalar could be a simple key.
-        self.save_possible_simple_key()
-        # No simple keys after plain scalars. But note that `scan_plain` will
-        # change this flag if the scan is finished at the beginning of the
-        # line.
-        self.allow_simple_key = False
-        # Scan and add SCALAR. May change `allow_simple_key`.
-        self.tokens.append(self.scan_plain())
-
-    # Checkers.
-
-    def check_directive(self) -> Any:
-        # DIRECTIVE:        ^ '%' ...
-        # The '%' indicator is already checked.
-        if self.reader.column == 0:
-            return True
-        return None
-
-    def check_document_start(self) -> Any:
-        # DOCUMENT-START:   ^ '---' (' '|'\n')
-        if self.reader.column == 0:
-            if self.reader.prefix(3) == '---' and self.reader.peek(3) in _THE_END_SPACE_TAB:
-                return True
-        return None
-
-    def check_document_end(self) -> Any:
-        # DOCUMENT-END:     ^ '...' (' '|'\n')
-        if self.reader.column == 0:
-            if self.reader.prefix(3) == '...' and self.reader.peek(3) in _THE_END_SPACE_TAB:
-                return True
-        return None
-
-    def check_block_entry(self) -> Any:
-        # BLOCK-ENTRY:      '-' (' '|'\n')
-        return self.reader.peek(1) in _THE_END_SPACE_TAB
-
-    def check_key(self) -> Any:
-        # KEY(flow context):    '?'
-        if bool(self.flow_level):
-            return True
-        # KEY(block context):   '?' (' '|'\n')
-        return self.reader.peek(1) in _THE_END_SPACE_TAB
-
-    def check_value(self) -> Any:
-        # VALUE(flow context):  ':'
-        if self.scanner_processing_version == (1, 1):
-            if bool(self.flow_level):
-                return True
-        else:
-            if bool(self.flow_level):
-                if self.flow_context[-1] == '[':
-                    if self.reader.peek(1) not in _THE_END_SPACE_TAB:
-                        return False
-                elif self.tokens and isinstance(self.tokens[-1], tokens.ValueToken):
-                    # mapping flow context scanning a value token
-                    if self.reader.peek(1) not in _THE_END_SPACE_TAB:
-                        return False
-                return True
-        # VALUE(block context): ':' (' '|'\n')
-        return self.reader.peek(1) in _THE_END_SPACE_TAB
-
-    def check_plain(self) -> Any:
-        # A plain scalar may start with any non-space character except:
-        #   '-', '?', ':', ',', '[', ']', '{', '}',
-        #   '#', '&', '*', '!', '|', '>', '\'', '\"',
-        #   '%', '@', '`'.
-        #
-        # It may also start with
-        #   '-', '?', ':'
-        # if it is followed by a non-space character.
-        #
-        # Note that we limit the last rule to the block context (except the
-        # '-' character) because we want the flow context to be space
-        # independent.
-        srp = self.reader.peek
-        ch = srp()
-        if self.scanner_processing_version == (1, 1):
-            return ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'"%@`' or (
-                srp(1) not in _THE_END_SPACE_TAB
-                and (ch == '-' or (not self.flow_level and ch in '?:'))
-            )
-        # YAML 1.2
-        if ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'"%@`':
-            # ###################                ^ ???
-            return True
-        ch1 = srp(1)
-        if ch == '-' and ch1 not in _THE_END_SPACE_TAB:
-            return True
-        if ch == ':' and bool(self.flow_level) and ch1 not in _SPACE_TAB:
-            return True
-
-        return srp(1) not in _THE_END_SPACE_TAB and (
-            ch == '-' or (not self.flow_level and ch in '?:')
-        )
-
-    # Scanners.
-
-    def scan_to_next_token(self) -> Any:
-        # We ignore spaces, line breaks and comments.
-        # If we find a line break in the block context, we set the flag
-        # `allow_simple_key` on.
-        # The byte order mark is stripped if it's the first character in the
-        # stream. We do not yet support BOM inside the stream as the
-        # specification requires. Any such mark will be considered as a part
-        # of the document.
-        #
-        # TODO: We need to make tab handling rules more sane. A good rule is
-        #   Tabs cannot precede tokens
-        #   BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END,
-        #   KEY(block), VALUE(block), BLOCK-ENTRY
-        # So the checking code is
-        #   if :
-        #       self.allow_simple_keys = False
-        # We also need to add the check for `allow_simple_keys == True` to
-        # `unwind_indent` before issuing BLOCK-END.
-        # Scanners for block, flow, and plain scalars need to be modified.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        if self.reader.index == 0 and srp() == '\uFEFF':
-            srf()
-        found = False
-        _the_end = _THE_END
-        white_space = ' \t' if self.flow_level > 0 else ' '
-        while not found:
-            while srp() in white_space:
-                srf()
-            if srp() == '#':
-                while srp() not in _the_end:
-                    srf()
-            if self.scan_line_break():
-                if not self.flow_level:
-                    self.allow_simple_key = True
-            else:
-                found = True
-        return None
-
-    def scan_directive(self) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        start_mark = self.reader.get_mark()
-        srf()
-        name = self.scan_directive_name(start_mark)
-        value = None
-        if name == 'YAML':
-            value = self.scan_yaml_directive_value(start_mark)
-            end_mark = self.reader.get_mark()
-        elif name == 'TAG':
-            value = self.scan_tag_directive_value(start_mark)
-            end_mark = self.reader.get_mark()
-        else:
-            end_mark = self.reader.get_mark()
-            while srp() not in _THE_END:
-                srf()
-        self.scan_directive_ignored_line(start_mark)
-        return tokens.DirectiveToken(name, value, start_mark, end_mark)
-
-    def scan_directive_name(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        length = 0
-        srp = self.reader.peek
-        ch = srp(length)
-        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in '-_:.':
-            length += 1
-            ch = srp(length)
-        if not length:
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f'expected alphabetic or numeric character, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        value = self.reader.prefix(length)
-        self.reader.forward(length)
-        ch = srp()
-        if ch not in '\0 \r\n\x85\u2028\u2029':
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f'expected alphabetic or numeric character, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        return value
-
-    def scan_yaml_directive_value(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        while srp() == ' ':
-            srf()
-        major = self.scan_yaml_directive_number(start_mark)
-        if srp() != '.':
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f"expected a digit or '.', but found {srp()!r}",
-                self.reader.get_mark(),
-            )
-        srf()
-        minor = self.scan_yaml_directive_number(start_mark)
-        if srp() not in '\0 \r\n\x85\u2028\u2029':
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f"expected a digit or '.', but found {srp()!r}",
-                self.reader.get_mark(),
-            )
-        self.yaml_version = (major, minor)
-        self.loader.doc_infos[-1].doc_version = Version(major, minor)
-        return self.yaml_version
-
-    def scan_yaml_directive_number(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        ch = srp()
-        if not ('0' <= ch <= '9'):
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f'expected a digit, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        length = 0
-        while '0' <= srp(length) <= '9':
-            length += 1
-        value = int(self.reader.prefix(length))
-        srf(length)
-        return value
-
-    def scan_tag_directive_value(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        while srp() == ' ':
-            srf()
-        handle = self.scan_tag_directive_handle(start_mark)
-        while srp() == ' ':
-            srf()
-        prefix = self.scan_tag_directive_prefix(start_mark)
-        ret_val = (handle, prefix)
-        self.tag_directives.append(ret_val)
-        return ret_val
-
-    def scan_tag_directive_handle(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        value = self.scan_tag_handle('directive', start_mark)
-        ch = self.reader.peek()
-        if ch != ' ':
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f"expected ' ', but found {ch!r}",
-                self.reader.get_mark(),
-            )
-        return value
-
-    def scan_tag_directive_prefix(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        value = self.scan_tag_uri('directive', start_mark)
-        ch = self.reader.peek()
-        if ch not in '\0 \r\n\x85\u2028\u2029':
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f"expected ' ', but found {ch!r}",
-                self.reader.get_mark(),
-            )
-        return value
-
-    def scan_directive_ignored_line(self, start_mark: Any) -> None:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        while srp() == ' ':
-            srf()
-        if srp() == '#':
-            while srp() not in _THE_END:
-                srf()
-        ch = srp()
-        if ch not in _THE_END:
-            raise ScannerError(
-                'while scanning a directive',
-                start_mark,
-                f'expected a comment or a line break, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        self.scan_line_break()
-
-    def scan_anchor(self, TokenClass: Any) -> Any:
-        # The specification does not restrict characters for anchors and
-        # aliases. This may lead to problems, for instance, the document:
-        #   [ *alias, value ]
-        # can be interpteted in two ways, as
-        #   [ "value" ]
-        # and
-        #   [ *alias , "value" ]
-        # Therefore we restrict aliases to numbers and ASCII letters.
-        srp = self.reader.peek
-        start_mark = self.reader.get_mark()
-        indicator = srp()
-        if indicator == '*':
-            name = 'alias'
-        else:
-            name = 'anchor'
-        self.reader.forward()
-        length = 0
-        ch = srp(length)
-        # while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \
-        #         or ch in '-_':
-        while check_anchorname_char(ch):
-            length += 1
-            ch = srp(length)
-        if not length:
-            raise ScannerError(
-                f'while scanning an {name!s}',
-                start_mark,
-                f'expected alphabetic or numeric character, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        value = self.reader.prefix(length)
-        self.reader.forward(length)
-        # ch1 = ch
-        # ch = srp()   # no need to peek, ch is already set
-        # assert ch1 == ch
-        if ch not in '\0 \t\r\n\x85\u2028\u2029?:,[]{}%@`':
-            raise ScannerError(
-                f'while scanning an {name!s}',
-                start_mark,
-                f'expected alphabetic or numeric character, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        end_mark = self.reader.get_mark()
-        return TokenClass(value, start_mark, end_mark)
-
-    def scan_tag(self) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        start_mark = self.reader.get_mark()
-        ch = srp(1)
-        short_handle = '!'
-        if ch == '!':
-            short_handle = '!!'
-            self.reader.forward()
-            srp = self.reader.peek
-            ch = srp(1)
-
-        if ch == '<':
-            handle = None
-            self.reader.forward(2)
-            suffix = self.scan_tag_uri('tag', start_mark)
-            if srp() != '>':
-                raise ScannerError(
-                    'while parsing a tag',
-                    start_mark,
-                    f"expected '>' but found {srp()!r}",
-                    self.reader.get_mark(),
-                )
-            self.reader.forward()
-        elif ch in _THE_END_SPACE_TAB:
-            handle = None
-            suffix = short_handle
-            self.reader.forward()
-        else:
-            length = 1
-            use_handle = False
-            while ch not in '\0 \r\n\x85\u2028\u2029':
-                if ch == '!':
-                    use_handle = True
-                    break
-                length += 1
-                ch = srp(length)
-            handle = short_handle
-            if use_handle:
-                handle = self.scan_tag_handle('tag', start_mark)
-            else:
-                handle = short_handle
-                self.reader.forward()
-            suffix = self.scan_tag_uri('tag', start_mark)
-        ch = srp()
-        if ch not in '\0 \r\n\x85\u2028\u2029':
-            raise ScannerError(
-                'while scanning a tag',
-                start_mark,
-                f"expected ' ', but found {ch!r}",
-                self.reader.get_mark(),
-            )
-        value = (handle, suffix)
-        end_mark = self.reader.get_mark()
-        return tokens.TagToken(value, start_mark, end_mark)
-
-    def scan_block_scalar(self, style: Any, rt: Optional[bool] = False) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        if style == '>':
-            folded = True
-        else:
-            folded = False
-
-        chunks: List[Any] = []
-        start_mark = self.reader.get_mark()
-
-        # Scan the header.
-        self.reader.forward()
-        chomping, increment = self.scan_block_scalar_indicators(start_mark)
-        # block scalar comment e.g. : |+  # comment text
-        block_scalar_comment = self.scan_block_scalar_ignored_line(start_mark)
-
-        # Determine the indentation level and go to the first non-empty line.
-        min_indent = self.indent + 1
-        if increment is None:
-            # no increment and top level, min_indent could be 0
-            if min_indent < 1 and (
-                style not in '|>'
-                or (self.scanner_processing_version == (1, 1))
-                and getattr(
-                    self.loader, 'top_level_block_style_scalar_no_indent_error_1_1', False,
-                )
-            ):
-                min_indent = 1
-            breaks, max_indent, end_mark = self.scan_block_scalar_indentation()
-            indent = max(min_indent, max_indent)
-        else:
-            if min_indent < 1:
-                min_indent = 1
-            indent = min_indent + increment - 1
-            breaks, end_mark = self.scan_block_scalar_breaks(indent)
-        line_break = ""
-
-        # Scan the inner part of the block scalar.
-        while self.reader.column == indent and srp() != '\0':
-            chunks.extend(breaks)
-            leading_non_space = srp() not in ' \t'
-            length = 0
-            while srp(length) not in _THE_END:
-                length += 1
-            chunks.append(self.reader.prefix(length))
-            self.reader.forward(length)
-            line_break = self.scan_line_break()
-            breaks, end_mark = self.scan_block_scalar_breaks(indent)
-            if style in '|>' and min_indent == 0:
-                # at the beginning of a line, if in block style see if
-                # end of document/start_new_document
-                if self.check_document_start() or self.check_document_end():
-                    break
-            if self.reader.column == indent and srp() != '\0':
-
-                # Unfortunately, folding rules are ambiguous.
-                #
-                # This is the folding according to the specification:
-
-                if rt and folded and line_break == '\n':
-                    chunks.append('\a')
-                if folded and line_break == '\n' and leading_non_space and srp() not in ' \t':
-                    if not breaks:
-                        chunks.append(' ')
-                else:
-                    chunks.append(line_break)
-
-                # This is Clark Evans's interpretation (also in the spec
-                # examples):
-                #
-                # if folded and line_break == '\n':
-                #     if not breaks:
-                #         if srp() not in ' \t':
-                #             chunks.append(' ')
-                #         else:
-                #             chunks.append(line_break)
-                # else:
-                #     chunks.append(line_break)
-            else:
-                break
-
-        # Process trailing line breaks. The 'chomping' setting determines
-        # whether they are included in the value.
-        trailing: List[Any] = []
-        if chomping in [None, True]:
-            chunks.append(line_break)
-        if chomping is True:
-            chunks.extend(breaks)
-        elif chomping in [None, False]:
-            trailing.extend(breaks)
-
-        # We are done.
-        token = tokens.ScalarToken("".join(chunks), False, start_mark, end_mark, style)
-        if self.loader is not None:
-            comment_handler = getattr(self.loader, 'comment_handling', False)
-            if comment_handler is None:
-                if block_scalar_comment is not None:
-                    token.add_pre_comments([block_scalar_comment])
-        if len(trailing) > 0:
-            # Eat whitespaces and comments until we reach the next token.
-            if self.loader is not None:
-                comment_handler = getattr(self.loader, 'comment_handling', None)
-                if comment_handler is not None:
-                    line = end_mark.line - len(trailing)
-                    for x in trailing:
-                        assert x[-1] == '\n'
-                        self.comments.add_blank_line(x, 0, line)  # type: ignore
-                        line += 1
-            comment = self.scan_to_next_token()
-            while comment:
-                trailing.append(' ' * comment[1].column + comment[0])
-                comment = self.scan_to_next_token()
-            if self.loader is not None:
-                comment_handler = getattr(self.loader, 'comment_handling', False)
-                if comment_handler is None:
-                    # Keep track of the trailing whitespace and following comments
-                    # as a comment token, if isn't all included in the actual value.
-                    comment_end_mark = self.reader.get_mark()
-                    comment = tokens.CommentToken("".join(trailing),
-                                                  end_mark,
-                                                  comment_end_mark)
-                    token.add_post_comment(comment)
-        return token
-
-    def scan_block_scalar_indicators(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        chomping = None
-        increment = None
-        ch = srp()
-        if ch in '+-':
-            if ch == '+':
-                chomping = True
-            else:
-                chomping = False
-            self.reader.forward()
-            ch = srp()
-            if ch in '0123456789':
-                increment = int(ch)
-                if increment == 0:
-                    raise ScannerError(
-                        'while scanning a block scalar',
-                        start_mark,
-                        'expected indentation indicator in the range 1-9, ' 'but found 0',
-                        self.reader.get_mark(),
-                    )
-                self.reader.forward()
-        elif ch in '0123456789':
-            increment = int(ch)
-            if increment == 0:
-                raise ScannerError(
-                    'while scanning a block scalar',
-                    start_mark,
-                    'expected indentation indicator in the range 1-9, ' 'but found 0',
-                    self.reader.get_mark(),
-                )
-            self.reader.forward()
-            ch = srp()
-            if ch in '+-':
-                if ch == '+':
-                    chomping = True
-                else:
-                    chomping = False
-                self.reader.forward()
-        ch = srp()
-        if ch not in '\0 \r\n\x85\u2028\u2029':
-            raise ScannerError(
-                'while scanning a block scalar',
-                start_mark,
-                f'expected chomping or indentation indicators, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        return chomping, increment
-
-    def scan_block_scalar_ignored_line(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        prefix = ''
-        comment = None
-        while srp() == ' ':
-            prefix += srp()
-            srf()
-        if srp() == '#':
-            comment = prefix
-            while srp() not in _THE_END:
-                comment += srp()
-                srf()
-        ch = srp()
-        if ch not in _THE_END:
-            raise ScannerError(
-                'while scanning a block scalar',
-                start_mark,
-                f'expected a comment or a line break, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        self.scan_line_break()
-        return comment
-
-    def scan_block_scalar_indentation(self) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        chunks = []
-        first_indent = -1
-        max_indent = 0
-        end_mark = self.reader.get_mark()
-        while srp() in ' \r\n\x85\u2028\u2029':
-            if srp() != ' ':
-                if first_indent < 0:
-                    first_indent = self.reader.column
-                chunks.append(self.scan_line_break())
-                end_mark = self.reader.get_mark()
-            else:
-                srf()
-                if self.reader.column > max_indent:
-                    max_indent = self.reader.column
-        if first_indent > 0 and max_indent > first_indent:
-            start_mark = self.reader.get_mark()
-            raise ScannerError(
-                'more indented follow up line than first in a block scalar', start_mark,
-            )
-        return chunks, max_indent, end_mark
-
-    def scan_block_scalar_breaks(self, indent: int) -> Any:
-        # See the specification for details.
-        chunks = []
-        srp = self.reader.peek
-        srf = self.reader.forward
-        end_mark = self.reader.get_mark()
-        while self.reader.column < indent and srp() == ' ':
-            srf()
-        while srp() in '\r\n\x85\u2028\u2029':
-            chunks.append(self.scan_line_break())
-            end_mark = self.reader.get_mark()
-            while self.reader.column < indent and srp() == ' ':
-                srf()
-        return chunks, end_mark
-
-    def scan_flow_scalar(self, style: Any) -> Any:
-        # See the specification for details.
-        # Note that we loose indentation rules for quoted scalars. Quoted
-        # scalars don't need to adhere indentation because " and ' clearly
-        # mark the beginning and the end of them. Therefore we are less
-        # restrictive then the specification requires. We only need to check
-        # that document separators are not included in scalars.
-        if style == '"':
-            double = True
-        else:
-            double = False
-        srp = self.reader.peek
-        chunks: List[Any] = []
-        start_mark = self.reader.get_mark()
-        quote = srp()
-        self.reader.forward()
-        chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
-        while srp() != quote:
-            chunks.extend(self.scan_flow_scalar_spaces(double, start_mark))
-            chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
-        self.reader.forward()
-        end_mark = self.reader.get_mark()
-        return tokens.ScalarToken("".join(chunks), False, start_mark, end_mark, style)
-
-    ESCAPE_REPLACEMENTS = {
-        '0': '\0',
-        'a': '\x07',
-        'b': '\x08',
-        't': '\x09',
-        '\t': '\x09',
-        'n': '\x0A',
-        'v': '\x0B',
-        'f': '\x0C',
-        'r': '\x0D',
-        'e': '\x1B',
-        ' ': '\x20',
-        '"': '"',
-        '/': '/',  # as per http://www.json.org/
-        '\\': '\\',
-        'N': '\x85',
-        '_': '\xA0',
-        'L': '\u2028',
-        'P': '\u2029',
-    }
-
-    ESCAPE_CODES = {'x': 2, 'u': 4, 'U': 8}
-
-    def scan_flow_scalar_non_spaces(self, double: Any, start_mark: Any) -> Any:
-        # See the specification for details.
-        chunks: List[Any] = []
-        srp = self.reader.peek
-        srf = self.reader.forward
-        while True:
-            length = 0
-            while srp(length) not in ' \n\'"\\\0\t\r\x85\u2028\u2029':
-                length += 1
-            if length != 0:
-                chunks.append(self.reader.prefix(length))
-                srf(length)
-            ch = srp()
-            if not double and ch == "'" and srp(1) == "'":
-                chunks.append("'")
-                srf(2)
-            elif (double and ch == "'") or (not double and ch in '"\\'):
-                chunks.append(ch)
-                srf()
-            elif double and ch == '\\':
-                srf()
-                ch = srp()
-                if ch in self.ESCAPE_REPLACEMENTS:
-                    chunks.append(self.ESCAPE_REPLACEMENTS[ch])
-                    srf()
-                elif ch in self.ESCAPE_CODES:
-                    length = self.ESCAPE_CODES[ch]
-                    srf()
-                    for k in range(length):
-                        if srp(k) not in '0123456789ABCDEFabcdef':
-                            raise ScannerError(
-                                'while scanning a double-quoted scalar',
-                                start_mark,
-                                f'expected escape sequence of {length:d} '
-                                f'hexdecimal numbers, but found {srp(k)!r}',
-                                self.reader.get_mark(),
-                            )
-                    code = int(self.reader.prefix(length), 16)
-                    chunks.append(chr(code))
-                    srf(length)
-                elif ch in '\n\r\x85\u2028\u2029':
-                    self.scan_line_break()
-                    chunks.extend(self.scan_flow_scalar_breaks(double, start_mark))
-                else:
-                    raise ScannerError(
-                        'while scanning a double-quoted scalar',
-                        start_mark,
-                        f'found unknown escape character {ch!r}',
-                        self.reader.get_mark(),
-                    )
-            else:
-                return chunks
-
-    def scan_flow_scalar_spaces(self, double: Any, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        chunks = []
-        length = 0
-        while srp(length) in ' \t':
-            length += 1
-        whitespaces = self.reader.prefix(length)
-        self.reader.forward(length)
-        ch = srp()
-        if ch == '\0':
-            raise ScannerError(
-                'while scanning a quoted scalar',
-                start_mark,
-                'found unexpected end of stream',
-                self.reader.get_mark(),
-            )
-        elif ch in '\r\n\x85\u2028\u2029':
-            line_break = self.scan_line_break()
-            breaks = self.scan_flow_scalar_breaks(double, start_mark)
-            if line_break != '\n':
-                chunks.append(line_break)
-            elif not breaks:
-                chunks.append(' ')
-            chunks.extend(breaks)
-        else:
-            chunks.append(whitespaces)
-        return chunks
-
-    def scan_flow_scalar_breaks(self, double: Any, start_mark: Any) -> Any:
-        # See the specification for details.
-        chunks: List[Any] = []
-        srp = self.reader.peek
-        srf = self.reader.forward
-        while True:
-            # Instead of checking indentation, we check for document
-            # separators.
-            prefix = self.reader.prefix(3)
-            if (prefix == '---' or prefix == '...') and srp(3) in _THE_END_SPACE_TAB:
-                raise ScannerError(
-                    'while scanning a quoted scalar',
-                    start_mark,
-                    'found unexpected document separator',
-                    self.reader.get_mark(),
-                )
-            while srp() in ' \t':
-                srf()
-            if srp() in '\r\n\x85\u2028\u2029':
-                chunks.append(self.scan_line_break())
-            else:
-                return chunks
-
-    def scan_plain(self) -> Any:
-        # See the specification for details.
-        # We add an additional restriction for the flow context:
-        #   plain scalars in the flow context cannot contain ',', ': '  and '?'.
-        # We also keep track of the `allow_simple_key` flag here.
-        # Indentation rules are loosed for the flow context.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        chunks: List[Any] = []
-        start_mark = self.reader.get_mark()
-        end_mark = start_mark
-        indent = self.indent + 1
-        # We allow zero indentation for scalars, but then we need to check for
-        # document separators at the beginning of the line.
-        # if indent == 0:
-        #     indent = 1
-        spaces: List[Any] = []
-        while True:
-            length = 0
-            if srp() == '#':
-                break
-            while True:
-                ch = srp(length)
-                if False and ch == ':' and srp(length + 1) == ',':
-                    break
-                elif ch == ':' and srp(length + 1) not in _THE_END_SPACE_TAB:
-                    pass
-                elif ch == '?' and self.scanner_processing_version != (1, 1):
-                    pass
-                elif (
-                    ch in _THE_END_SPACE_TAB
-                    or (
-                        not self.flow_level
-                        and ch == ':'
-                        and srp(length + 1) in _THE_END_SPACE_TAB
-                    )
-                    or (self.flow_level and ch in ',:?[]{}')
-                ):
-                    break
-                length += 1
-            # It's not clear what we should do with ':' in the flow context.
-            if (
-                self.flow_level
-                and ch == ':'
-                and srp(length + 1) not in '\0 \t\r\n\x85\u2028\u2029,[]{}'
-            ):
-                srf(length)
-                raise ScannerError(
-                    'while scanning a plain scalar',
-                    start_mark,
-                    "found unexpected ':'",
-                    self.reader.get_mark(),
-                    'Please check '
-                    'http://pyyaml.org/wiki/YAMLColonInFlowContext '
-                    'for details.',
-                )
-            if length == 0:
-                break
-            self.allow_simple_key = False
-            chunks.extend(spaces)
-            chunks.append(self.reader.prefix(length))
-            srf(length)
-            end_mark = self.reader.get_mark()
-            spaces = self.scan_plain_spaces(indent, start_mark)
-            if (
-                not spaces
-                or srp() == '#'
-                or (not self.flow_level and self.reader.column < indent)
-            ):
-                break
-
-        token = tokens.ScalarToken("".join(chunks), True, start_mark, end_mark)
-        # getattr provides True so C type loader, which cannot handle comment,
-        # will not make CommentToken
-        if self.loader is not None:
-            comment_handler = getattr(self.loader, 'comment_handling', False)
-            if comment_handler is None:
-                if spaces and spaces[0] == '\n':
-                    # Create a comment token to preserve the trailing line breaks.
-                    comment = tokens.CommentToken("".join(spaces) + '\n', start_mark, end_mark)
-                    token.add_post_comment(comment)
-            elif comment_handler is not False:
-                line = start_mark.line + 1
-                for ch in spaces:
-                    if ch == '\n':
-                        self.comments.add_blank_line('\n', 0, line)  # type: ignore
-                        line += 1
-
-        return token
-
-    def scan_plain_spaces(self, indent: Any, start_mark: Any) -> Any:
-        # See the specification for details.
-        # The specification is really confusing about tabs in plain scalars.
-        # We just forbid them completely. Do not use tabs in YAML!
-        srp = self.reader.peek
-        srf = self.reader.forward
-        chunks = []
-        length = 0
-        while srp(length) in ' ':
-            length += 1
-        whitespaces = self.reader.prefix(length)
-        self.reader.forward(length)
-        ch = srp()
-        if ch in '\r\n\x85\u2028\u2029':
-            line_break = self.scan_line_break()
-            self.allow_simple_key = True
-            prefix = self.reader.prefix(3)
-            if (prefix == '---' or prefix == '...') and srp(3) in _THE_END_SPACE_TAB:
-                return
-            breaks = []
-            while srp() in ' \r\n\x85\u2028\u2029':
-                if srp() == ' ':
-                    srf()
-                else:
-                    breaks.append(self.scan_line_break())
-                    prefix = self.reader.prefix(3)
-                    if (prefix == '---' or prefix == '...') and srp(3) in _THE_END_SPACE_TAB:
-                        return
-            if line_break != '\n':
-                chunks.append(line_break)
-            elif not breaks:
-                chunks.append(' ')
-            chunks.extend(breaks)
-        elif whitespaces:
-            chunks.append(whitespaces)
-        return chunks
-
-    def scan_tag_handle(self, name: Any, start_mark: Any) -> Any:
-        # See the specification for details.
-        # For some strange reasons, the specification does not allow '_' in
-        # tag handles. I have allowed it anyway.
-        srp = self.reader.peek
-        ch = srp()
-        if ch != '!':
-            raise ScannerError(
-                f'while scanning an {name!s}',
-                start_mark,
-                f"expected '!', but found {ch!r}",
-                self.reader.get_mark(),
-            )
-        length = 1
-        ch = srp(length)
-        if ch != ' ':
-            while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in '-_':
-                length += 1
-                ch = srp(length)
-            if ch != '!':
-                self.reader.forward(length)
-                raise ScannerError(
-                    f'while scanning an {name!s}',
-                    start_mark,
-                    f"expected '!' but found {ch!r}",
-                    self.reader.get_mark(),
-                )
-            length += 1
-        value = self.reader.prefix(length)
-        self.reader.forward(length)
-        return value
-
-    def scan_tag_uri(self, name: Any, start_mark: Any) -> Any:
-        # See the specification for details.
-        # Note: we do not check if URI is well-formed.
-        srp = self.reader.peek
-        chunks = []
-        length = 0
-        ch = srp(length)
-        while (
-            '0' <= ch <= '9'
-            or 'A' <= ch <= 'Z'
-            or 'a' <= ch <= 'z'
-            or ch in "-;/?:@&=+$,_.!~*'()[]%"
-            or ((self.scanner_processing_version > (1, 1)) and ch == '#')
-        ):
-            if ch == '%':
-                chunks.append(self.reader.prefix(length))
-                self.reader.forward(length)
-                length = 0
-                chunks.append(self.scan_uri_escapes(name, start_mark))
-            else:
-                length += 1
-            ch = srp(length)
-        if length != 0:
-            chunks.append(self.reader.prefix(length))
-            self.reader.forward(length)
-            length = 0
-        if not chunks:
-            raise ScannerError(
-                f'while parsing an {name!s}',
-                start_mark,
-                f'expected URI, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        return "".join(chunks)
-
-    def scan_uri_escapes(self, name: Any, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        code_bytes: List[Any] = []
-        mark = self.reader.get_mark()
-        while srp() == '%':
-            srf()
-            for k in range(2):
-                if srp(k) not in '0123456789ABCDEFabcdef':
-                    raise ScannerError(
-                        f'while scanning an {name!s}',
-                        start_mark,
-                        f'expected URI escape sequence of 2 hexdecimal numbers, '
-                        f'but found {srp(k)!r}',
-                        self.reader.get_mark(),
-                    )
-            code_bytes.append(int(self.reader.prefix(2), 16))
-            srf(2)
-        try:
-            value = bytes(code_bytes).decode('utf-8')
-        except UnicodeDecodeError as exc:
-            raise ScannerError(f'while scanning an {name!s}', start_mark, str(exc), mark)
-        return value
-
-    def scan_line_break(self) -> Any:
-        # Transforms:
-        #   '\r\n'      :   '\n'
-        #   '\r'        :   '\n'
-        #   '\n'        :   '\n'
-        #   '\x85'      :   '\n'
-        #   '\u2028'    :   '\u2028'
-        #   '\u2029     :   '\u2029'
-        #   default     :   ''
-        ch = self.reader.peek()
-        if ch in '\r\n\x85':
-            if self.reader.prefix(2) == '\r\n':
-                self.reader.forward(2)
-            else:
-                self.reader.forward()
-            return '\n'
-        elif ch in '\u2028\u2029':
-            self.reader.forward()
-            return ch
-        return ""
-
-
-class RoundTripScanner(Scanner):
-    def check_token(self, *choices: Any) -> bool:
-        # Check if the next token is one of the given types.
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-        self._gather_comments()
-        if len(self.tokens) > 0:
-            if not choices:
-                return True
-            for choice in choices:
-                if isinstance(self.tokens[0], choice):
-                    return True
-        return False
-
-    def peek_token(self) -> Any:
-        # Return the next token, but do not delete if from the queue.
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-        self._gather_comments()
-        if len(self.tokens) > 0:
-            return self.tokens[0]
-        return None
-
-    def _gather_comments(self) -> Any:
-        """combine multiple comment lines and assign to next non-comment-token"""
-        comments: List[Any] = []
-        if not self.tokens:
-            return comments
-        if isinstance(self.tokens[0], tokens.CommentToken):
-            comment = self.tokens.pop(0)
-            self.tokens_taken += 1
-            comments.append(comment)
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-            if not self.tokens:
-                return comments
-            if isinstance(self.tokens[0], tokens.CommentToken):
-                self.tokens_taken += 1
-                comment = self.tokens.pop(0)
-                # nprint('dropping2', comment)
-                comments.append(comment)
-        if len(comments) >= 1:
-            self.tokens[0].add_pre_comments(comments)
-        # pull in post comment on e.g. ':'
-        if not self.done and len(self.tokens) < 2:
-            self.fetch_more_tokens()
-
-    def get_token(self) -> Any:
-        # Return the next token.
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-        self._gather_comments()
-        if len(self.tokens) > 0:
-            # nprint('tk', self.tokens)
-            # only add post comment to single line tokens:
-            # scalar, value token. FlowXEndToken, otherwise
-            # hidden streamtokens could get them (leave them and they will be
-            # pre comments for the next map/seq
-            if (
-                len(self.tokens) > 1
-                and isinstance(
-                    self.tokens[0],
-                    (tokens.ScalarToken, tokens.ValueToken, tokens.FlowSequenceEndToken,
-                     tokens.FlowMappingEndToken),
-                )
-                and isinstance(self.tokens[1], tokens.CommentToken)
-                and self.tokens[0].end_mark.line == self.tokens[1].start_mark.line
-            ):
-                self.tokens_taken += 1
-                c = self.tokens.pop(1)
-                self.fetch_more_tokens()
-                while len(self.tokens) > 1 and isinstance(self.tokens[1], tokens.CommentToken):
-                    self.tokens_taken += 1
-                    c1 = self.tokens.pop(1)
-                    c.value = c.value + (' ' * c1.start_mark.column) + c1.value
-                    self.fetch_more_tokens()
-                self.tokens[0].add_post_comment(c)
-            elif (
-                len(self.tokens) > 1
-                and isinstance(self.tokens[0], tokens.ScalarToken)
-                and isinstance(self.tokens[1], tokens.CommentToken)
-                and self.tokens[0].end_mark.line != self.tokens[1].start_mark.line
-            ):
-                self.tokens_taken += 1
-                c = self.tokens.pop(1)
-                c.value = (
-                    '\n' * (c.start_mark.line - self.tokens[0].end_mark.line)
-                    + (' ' * c.start_mark.column)
-                    + c.value
-                )
-                self.tokens[0].add_post_comment(c)
-                self.fetch_more_tokens()
-                while len(self.tokens) > 1 and isinstance(self.tokens[1], tokens.CommentToken):
-                    self.tokens_taken += 1
-                    c1 = self.tokens.pop(1)
-                    c.value = c.value + (' ' * c1.start_mark.column) + c1.value
-                    self.fetch_more_tokens()
-            self.tokens_taken += 1
-            return self.tokens.pop(0)
-        return None
-
-    def fetch_comment(self, comment: Any) -> None:
-        value, start_mark, end_mark = comment
-        while value and value[-1] == ' ':
-            # empty line within indented key context
-            # no need to update end-mark, that is not used
-            value = value[:-1]
-        self.tokens.append(tokens.CommentToken(value, start_mark, end_mark))
-
-    # scanner
-
-    def scan_to_next_token(self) -> Any:
-        # We ignore spaces, line breaks and comments.
-        # If we find a line break in the block context, we set the flag
-        # `allow_simple_key` on.
-        # The byte order mark is stripped if it's the first character in the
-        # stream. We do not yet support BOM inside the stream as the
-        # specification requires. Any such mark will be considered as a part
-        # of the document.
-        #
-        # TODO: We need to make tab handling rules more sane. A good rule is
-        #   Tabs cannot precede tokens
-        #   BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END,
-        #   KEY(block), VALUE(block), BLOCK-ENTRY
-        # So the checking code is
-        #   if :
-        #       self.allow_simple_keys = False
-        # We also need to add the check for `allow_simple_keys == True` to
-        # `unwind_indent` before issuing BLOCK-END.
-        # Scanners for block, flow, and plain scalars need to be modified.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        if self.reader.index == 0 and srp() == '\uFEFF':
-            srf()
-        found = False
-        white_space = ' \t' if self.flow_level > 0 else ' '
-        while not found:
-            while srp() in white_space:
-                srf()
-            ch = srp()
-            if ch == '#':
-                start_mark = self.reader.get_mark()
-                comment = ch
-                srf()
-                while ch not in _THE_END:
-                    ch = srp()
-                    if ch == '\0':  # don't gobble the end-of-stream character
-                        # but add an explicit newline as "YAML processors should terminate
-                        # the stream with an explicit line break
-                        # https://yaml.org/spec/1.2/spec.html#id2780069
-                        comment += '\n'
-                        break
-                    comment += ch
-                    srf()
-                # gather any blank lines following the comment
-                ch = self.scan_line_break()
-                while len(ch) > 0:
-                    comment += ch
-                    ch = self.scan_line_break()
-                end_mark = self.reader.get_mark()
-                if not self.flow_level:
-                    self.allow_simple_key = True
-                return comment, start_mark, end_mark
-            if self.scan_line_break() != '':
-                start_mark = self.reader.get_mark()
-                if not self.flow_level:
-                    self.allow_simple_key = True
-                ch = srp()
-                if ch == '\n':  # empty toplevel lines
-                    start_mark = self.reader.get_mark()
-                    comment = ""
-                    while ch:
-                        ch = self.scan_line_break(empty_line=True)
-                        comment += ch
-                    if srp() == '#':
-                        # empty line followed by indented real comment
-                        comment = comment.rsplit('\n', 1)[0] + '\n'
-                    end_mark = self.reader.get_mark()
-                    return comment, start_mark, end_mark
-            else:
-                found = True
-        return None
-
-    def scan_line_break(self, empty_line: bool = False) -> Text:
-        # Transforms:
-        #   '\r\n'      :   '\n'
-        #   '\r'        :   '\n'
-        #   '\n'        :   '\n'
-        #   '\x85'      :   '\n'
-        #   '\u2028'    :   '\u2028'
-        #   '\u2029     :   '\u2029'
-        #   default     :   ''
-        ch: Text = self.reader.peek()
-        if ch in '\r\n\x85':
-            if self.reader.prefix(2) == '\r\n':
-                self.reader.forward(2)
-            else:
-                self.reader.forward()
-            return '\n'
-        elif ch in '\u2028\u2029':
-            self.reader.forward()
-            return ch
-        elif empty_line and ch in '\t ':
-            self.reader.forward()
-            return ch
-        return ""
-
-    def scan_block_scalar(self, style: Any, rt: Optional[bool] = True) -> Any:
-        return Scanner.scan_block_scalar(self, style, rt=rt)
-
-    def scan_uri_escapes(self, name: Any, start_mark: Any) -> Any:
-        """
-        The roundtripscanner doesn't do URI escaping
-        """
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        code_bytes: List[Any] = []
-        chunk = ''
-        mark = self.reader.get_mark()
-        while srp() == '%':
-            chunk += '%'
-            srf()
-            for k in range(2):
-                if srp(k) not in '0123456789ABCDEFabcdef':
-                    raise ScannerError(
-                        f'while scanning an {name!s}',
-                        start_mark,
-                        f'expected URI escape sequence of 2 hexdecimal numbers, '
-                        f'but found {srp(k)!r}',
-                        self.reader.get_mark(),
-                    )
-            code_bytes.append(int(self.reader.prefix(2), 16))
-            chunk += self.reader.prefix(2)
-            srf(2)
-        try:
-            _ = bytes(code_bytes).decode('utf-8')
-        except UnicodeDecodeError as exc:
-            raise ScannerError(f'while scanning an {name!s}', start_mark, str(exc), mark)
-        return chunk
-
-
-# commenthandling 2021, differentiatiation not needed
-
-VALUECMNT = 0
-KEYCMNT = 0  # 1
-# TAGCMNT = 2
-# ANCHORCMNT = 3
-
-
-class CommentBase:
-    __slots__ = ('value', 'line', 'column', 'used', 'function', 'fline', 'ufun', 'uline')
-
-    def __init__(self, value: Any, line: Any, column: Any) -> None:
-        self.value = value
-        self.line = line
-        self.column = column
-        self.used = ' '
-        if _debug != 0:
-            import inspect
-
-            info = inspect.getframeinfo(inspect.stack()[3][0])
-            self.function = info.function
-            self.fline = info.lineno
-            self.ufun = None
-            self.uline = None
-
-    def set_used(self, v: Any = '+') -> None:
-        self.used = v
-        if _debug != 0:
-            import inspect
-
-            info = inspect.getframeinfo(inspect.stack()[1][0])
-            self.ufun = info.function  # type: ignore
-            self.uline = info.lineno  # type: ignore
-
-    def set_assigned(self) -> None:
-        self.used = '|'
-
-    def __str__(self) -> str:
-        return f'{self.value}'
-
-    def __repr__(self) -> str:
-        return f'{self.value!r}'
-
-    def info(self) -> str:
-        xv = self.value + '"'
-        name = self.name  # type: ignore
-        return (
-            f'{name}{self.used} {self.line:2}:{self.column:<2} "{xv:40s} '
-            f'{self.function}:{self.fline} {self.ufun}:{self.uline}'
-        )
-
-
-class EOLComment(CommentBase):
-    name = 'EOLC'
-
-    def __init__(self, value: Any, line: Any, column: Any) -> None:
-        super().__init__(value, line, column)
-
-
-class FullLineComment(CommentBase):
-    name = 'FULL'
-
-    def __init__(self, value: Any, line: Any, column: Any) -> None:
-        super().__init__(value, line, column)
-
-
-class BlankLineComment(CommentBase):
-    name = 'BLNK'
-
-    def __init__(self, value: Any, line: Any, column: Any) -> None:
-        super().__init__(value, line, column)
-
-
-class ScannedComments:
-    def __init__(self: Any) -> None:
-        self.comments = {}  # type: ignore
-        self.unused = []  # type: ignore
-
-    def add_eol_comment(self, comment: Any, column: Any, line: Any) -> Any:
-        # info = inspect.getframeinfo(inspect.stack()[1][0])
-        if comment.count('\n') == 1:
-            assert comment[-1] == '\n'
-        else:
-            assert '\n' not in comment
-        self.comments[line] = retval = EOLComment(comment[:-1], line, column)
-        self.unused.append(line)
-        return retval
-
-    def add_blank_line(self, comment: Any, column: Any, line: Any) -> Any:
-        # info = inspect.getframeinfo(inspect.stack()[1][0])
-        assert comment.count('\n') == 1 and comment[-1] == '\n'
-        assert line not in self.comments
-        self.comments[line] = retval = BlankLineComment(comment[:-1], line, column)
-        self.unused.append(line)
-        return retval
-
-    def add_full_line_comment(self, comment: Any, column: Any, line: Any) -> Any:
-        # info = inspect.getframeinfo(inspect.stack()[1][0])
-        assert comment.count('\n') == 1 and comment[-1] == '\n'
-        # if comment.startswith('# C12'):
-        #    raise
-        # this raises in line 2127 fro 330
-        self.comments[line] = retval = FullLineComment(comment[:-1], line, column)
-        self.unused.append(line)
-        return retval
-
-    def __getitem__(self, idx: Any) -> Any:
-        return self.comments[idx]
-
-    def __str__(self) -> Any:
-        return (
-            'ParsedComments:\n  '
-            + '\n  '.join((f'{lineno:2} {x.info()}' for lineno, x in self.comments.items()))
-            + '\n'
-        )
-
-    def last(self) -> str:
-        lineno, x = list(self.comments.items())[-1]
-        return f'{lineno:2} {x.info()}\n'
-
-    def any_unprocessed(self) -> bool:
-        # ToDo: might want to differentiate based on lineno
-        return len(self.unused) > 0
-        # for lno, comment in reversed(self.comments.items()):
-        #    if comment.used == ' ':
-        #        return True
-        # return False
-
-    def unprocessed(self, use: Any = False) -> Any:
-        while len(self.unused) > 0:
-            if _debug != 0:
-                import inspect
-
-                first = self.unused.pop(0) if use else self.unused[0]
-                info = inspect.getframeinfo(inspect.stack()[1][0])
-                xprintf('using', first, self.comments[first].value, info.function, info.lineno)
-            yield first, self.comments[first]
-            if use:
-                self.comments[first].set_used()
-
-    def assign_pre(self, token: Any) -> Any:
-        token_line = token.start_mark.line
-        if _debug != 0:
-            import inspect
-
-            info = inspect.getframeinfo(inspect.stack()[1][0])
-            xprintf('assign_pre', token_line, self.unused, info.function, info.lineno)
-        gobbled = False
-        while self.unused and self.unused[0] < token_line:
-            gobbled = True
-            first = self.unused.pop(0)
-            if _debug != 0:
-                xprintf('assign_pre < ', first)
-            self.comments[first].set_used()
-            token.add_comment_pre(first)
-        return gobbled
-
-    def assign_eol(self, tokens: Any) -> Any:
-        try:
-            comment_line = self.unused[0]
-        except IndexError:
-            return
-        if not isinstance(self.comments[comment_line], EOLComment):
-            return
-        idx = 1
-        while tokens[-idx].start_mark.line > comment_line or isinstance(
-            tokens[-idx], tokens.ValueToken,
-        ):
-            idx += 1
-        if _debug != 0:
-            xprintf('idx1', idx)
-        if (
-            len(tokens) > idx
-            and isinstance(tokens[-idx], tokens.ScalarToken)
-            and isinstance(tokens[-(idx + 1)], tokens.ScalarToken)
-        ):
-            return
-        try:
-            if isinstance(tokens[-idx], tokens.ScalarToken) and isinstance(
-                tokens[-(idx + 1)], tokens.KeyToken,
-            ):
-                try:
-                    eol_idx = self.unused.pop(0)
-                    self.comments[eol_idx].set_used()
-                    if _debug != 0:
-                        xprintf('>>>>>a', idx, eol_idx, KEYCMNT)
-                    tokens[-idx].add_comment_eol(eol_idx, KEYCMNT)
-                except IndexError:
-                    raise NotImplementedError
-                return
-        except IndexError:
-            if _debug != 0:
-                xprintf('IndexError1')
-            pass
-        try:
-            if isinstance(tokens[-idx], tokens.ScalarToken) and isinstance(
-                tokens[-(idx + 1)], (tokens.ValueToken, tokens.BlockEntryToken),
-            ):
-                try:
-                    eol_idx = self.unused.pop(0)
-                    self.comments[eol_idx].set_used()
-                    tokens[-idx].add_comment_eol(eol_idx, VALUECMNT)
-                except IndexError:
-                    raise NotImplementedError
-                return
-        except IndexError:
-            if _debug != 0:
-                xprintf('IndexError2')
-            pass
-        for t in tokens:
-            xprintf('tt-', t)
-        if _debug != 0:
-            xprintf('not implemented EOL', type(tokens[-idx]))
-        import sys
-
-        sys.exit(0)
-
-    def assign_post(self, token: Any) -> Any:
-        token_line = token.start_mark.line
-        if _debug != 0:
-            import inspect
-
-            info = inspect.getframeinfo(inspect.stack()[1][0])
-            xprintf('assign_post', token_line, self.unused, info.function, info.lineno)
-        gobbled = False
-        while self.unused and self.unused[0] < token_line:
-            gobbled = True
-            first = self.unused.pop(0)
-            if _debug != 0:
-                xprintf('assign_post < ', first)
-            self.comments[first].set_used()
-            token.add_comment_post(first)
-        return gobbled
-
-    def str_unprocessed(self) -> Any:
-        return ''.join(
-            (f'  {ind:2} {x.info()}\n' for ind, x in self.comments.items() if x.used == ' '),
-        )
-
-
-class RoundTripScannerSC(Scanner):  # RoundTripScanner Split Comments
-    def __init__(self, *arg: Any, **kw: Any) -> None:
-        super().__init__(*arg, **kw)
-        assert self.loader is not None
-        # comments isinitialised on .need_more_tokens and persist on
-        # self.loader.parsed_comments
-        self.comments = None
-
-    def get_token(self) -> Any:
-        # Return the next token.
-        while self.need_more_tokens():
-            self.fetch_more_tokens()
-        if len(self.tokens) > 0:
-            if isinstance(self.tokens[0], tokens.BlockEndToken):
-                self.comments.assign_post(self.tokens[0])  # type: ignore
-            else:
-                self.comments.assign_pre(self.tokens[0])  # type: ignore
-            self.tokens_taken += 1
-            return self.tokens.pop(0)
-
-    def need_more_tokens(self) -> bool:
-        if self.comments is None:
-            self.loader.parsed_comments = self.comments = ScannedComments()  # type: ignore
-        if self.done:
-            return False
-        if len(self.tokens) == 0:
-            return True
-        # The current token may be a potential simple key, so we
-        # need to look further.
-        self.stale_possible_simple_keys()
-        if self.next_possible_simple_key() == self.tokens_taken:
-            return True
-        if len(self.tokens) < 2:
-            return True
-        if self.tokens[0].start_mark.line == self.tokens[-1].start_mark.line:
-            return True
-        if True:
-            if _debug != 0:
-                xprintf('-x--', len(self.tokens))
-                for t in self.tokens:
-                    xprintf(t)
-                # xprintf(self.comments.last())
-                xprintf(self.comments.str_unprocessed())  # type: ignore
-        self.comments.assign_pre(self.tokens[0])  # type: ignore
-        self.comments.assign_eol(self.tokens)  # type: ignore
-        return False
-
-    def scan_to_next_token(self) -> None:
-        srp = self.reader.peek
-        srf = self.reader.forward
-        if self.reader.index == 0 and srp() == '\uFEFF':
-            srf()
-        start_mark = self.reader.get_mark()
-        # xprintf('current_mark', start_mark.line, start_mark.column)
-        found = False
-        while not found:
-            while srp() == ' ':
-                srf()
-            ch = srp()
-            if ch == '#':
-                comment_start_mark = self.reader.get_mark()
-                comment = ch
-                srf()  # skipt the '#'
-                while ch not in _THE_END:
-                    ch = srp()
-                    if ch == '\0':  # don't gobble the end-of-stream character
-                        # but add an explicit newline as "YAML processors should terminate
-                        # the stream with an explicit line break
-                        # https://yaml.org/spec/1.2/spec.html#id2780069
-                        comment += '\n'
-                        break
-                    comment += ch
-                    srf()
-                # we have a comment
-                if start_mark.column == 0:
-                    self.comments.add_full_line_comment(  # type: ignore
-                        comment, comment_start_mark.column, comment_start_mark.line,
-                    )
-                else:
-                    self.comments.add_eol_comment(  # type: ignore
-                        comment, comment_start_mark.column, comment_start_mark.line,
-                    )
-                    comment = ""
-                # gather any blank lines or full line comments following the comment as well
-                self.scan_empty_or_full_line_comments()
-                if not self.flow_level:
-                    self.allow_simple_key = True
-                return
-            if bool(self.scan_line_break()):
-                # start_mark = self.reader.get_mark()
-                if not self.flow_level:
-                    self.allow_simple_key = True
-                self.scan_empty_or_full_line_comments()
-                return None
-                ch = srp()
-                if ch == '\n':  # empty toplevel lines
-                    start_mark = self.reader.get_mark()
-                    comment = ""
-                    while ch:
-                        ch = self.scan_line_break(empty_line=True)
-                        comment += ch
-                    if srp() == '#':
-                        # empty line followed by indented real comment
-                        comment = comment.rsplit('\n', 1)[0] + '\n'
-                    _ = self.reader.get_mark()  # gobble end_mark
-                    return None
-            else:
-                found = True
-        return None
-
-    def scan_empty_or_full_line_comments(self) -> None:
-        blmark = self.reader.get_mark()
-        assert blmark.column == 0
-        blanks = ""
-        comment = None
-        mark = None
-        ch = self.reader.peek()
-        while True:
-            # nprint('ch', repr(ch), self.reader.get_mark().column)
-            if ch in '\r\n\x85\u2028\u2029':
-                if self.reader.prefix(2) == '\r\n':
-                    self.reader.forward(2)
-                else:
-                    self.reader.forward()
-                if comment is not None:
-                    comment += '\n'
-                    self.comments.add_full_line_comment(comment, mark.column, mark.line)
-                    comment = None
-                else:
-                    blanks += '\n'
-                    self.comments.add_blank_line(blanks, blmark.column, blmark.line)  # type: ignore # NOQA
-                blanks = ""
-                blmark = self.reader.get_mark()
-                ch = self.reader.peek()
-                continue
-            if comment is None:
-                if ch in ' \t':
-                    blanks += ch
-                elif ch == '#':
-                    mark = self.reader.get_mark()
-                    comment = '#'
-                else:
-                    # xprintf('breaking on', repr(ch))
-                    break
-            else:
-                comment += ch
-            self.reader.forward()
-            ch = self.reader.peek()
-
-    def scan_block_scalar_ignored_line(self, start_mark: Any) -> Any:
-        # See the specification for details.
-        srp = self.reader.peek
-        srf = self.reader.forward
-        prefix = ''
-        comment = None
-        while srp() == ' ':
-            prefix += srp()
-            srf()
-        if srp() == '#':
-            comment = ''
-            mark = self.reader.get_mark()
-            while srp() not in _THE_END:
-                comment += srp()
-                srf()
-            comment += '\n'  # type: ignore
-        ch = srp()
-        if ch not in _THE_END:
-            raise ScannerError(
-                'while scanning a block scalar',
-                start_mark,
-                f'expected a comment or a line break, but found {ch!r}',
-                self.reader.get_mark(),
-            )
-        if comment is not None:
-            self.comments.add_eol_comment(comment, mark.column, mark.line)  # type: ignore
-        self.scan_line_break()
-        return None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py
deleted file mode 100644
index 7ca2d75ca0e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/serializer.py
+++ /dev/null
@@ -1,233 +0,0 @@
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.error import YAMLError
-from opentelemetry.agent._vendor.ruamel.yaml.compat import nprint, DBG_NODE, dbg, nprintf  # NOQA
-from opentelemetry.agent._vendor.ruamel.yaml.util import RegExp
-
-from opentelemetry.agent._vendor.ruamel.yaml.events import (
-    StreamStartEvent,
-    StreamEndEvent,
-    MappingStartEvent,
-    MappingEndEvent,
-    SequenceStartEvent,
-    SequenceEndEvent,
-    AliasEvent,
-    ScalarEvent,
-    DocumentStartEvent,
-    DocumentEndEvent,
-)
-from opentelemetry.agent._vendor.ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode
-
-if False:  # MYPY
-    from typing import Any, Dict, Union, Text, Optional  # NOQA
-    from opentelemetry.agent._vendor.ruamel.yaml.compat import VersionType  # NOQA
-
-__all__ = ['Serializer', 'SerializerError']
-
-
-class SerializerError(YAMLError):
-    pass
-
-
-class Serializer:
-
-    # 'id' and 3+ numbers, but not 000
-    ANCHOR_TEMPLATE = 'id{:03d}'
-    ANCHOR_RE = RegExp('id(?!000$)\\d{3,}')
-
-    def __init__(
-        self,
-        encoding: Any = None,
-        explicit_start: Optional[bool] = None,
-        explicit_end: Optional[bool] = None,
-        version: Optional[VersionType] = None,
-        tags: Any = None,
-        dumper: Any = None,
-    ) -> None:
-        # NOQA
-        self.dumper = dumper
-        if self.dumper is not None:
-            self.dumper._serializer = self
-        self.use_encoding = encoding
-        self.use_explicit_start = explicit_start
-        self.use_explicit_end = explicit_end
-        if isinstance(version, str):
-            self.use_version = tuple(map(int, version.split('.')))
-        else:
-            self.use_version = version  # type: ignore
-        self.use_tags = tags
-        self.serialized_nodes: Dict[Any, Any] = {}
-        self.anchors: Dict[Any, Any] = {}
-        self.last_anchor_id = 0
-        self.closed: Optional[bool] = None
-        self._templated_id = None
-
-    @property
-    def emitter(self) -> Any:
-        if hasattr(self.dumper, 'typ'):
-            return self.dumper.emitter
-        return self.dumper._emitter
-
-    @property
-    def resolver(self) -> Any:
-        if hasattr(self.dumper, 'typ'):
-            self.dumper.resolver
-        return self.dumper._resolver
-
-    def open(self) -> None:
-        if self.closed is None:
-            self.emitter.emit(StreamStartEvent(encoding=self.use_encoding))
-            self.closed = False
-        elif self.closed:
-            raise SerializerError('serializer is closed')
-        else:
-            raise SerializerError('serializer is already opened')
-
-    def close(self) -> None:
-        if self.closed is None:
-            raise SerializerError('serializer is not opened')
-        elif not self.closed:
-            self.emitter.emit(StreamEndEvent())
-            self.closed = True
-
-    # def __del__(self):
-    #     self.close()
-
-    def serialize(self, node: Any) -> None:
-        if dbg(DBG_NODE):
-            nprint('Serializing nodes')
-            node.dump()
-        if self.closed is None:
-            raise SerializerError('serializer is not opened')
-        elif self.closed:
-            raise SerializerError('serializer is closed')
-        self.emitter.emit(
-            DocumentStartEvent(
-                explicit=self.use_explicit_start, version=self.use_version, tags=self.use_tags,
-            ),
-        )
-        self.anchor_node(node)
-        self.serialize_node(node, None, None)
-        self.emitter.emit(DocumentEndEvent(explicit=self.use_explicit_end))
-        self.serialized_nodes = {}
-        self.anchors = {}
-        self.last_anchor_id = 0
-
-    def anchor_node(self, node: Any) -> None:
-        if node in self.anchors:
-            if self.anchors[node] is None:
-                self.anchors[node] = self.generate_anchor(node)
-        else:
-            anchor = None
-            try:
-                if node.anchor.always_dump:
-                    anchor = node.anchor.value
-            except:  # NOQA
-                pass
-            self.anchors[node] = anchor
-            if isinstance(node, SequenceNode):
-                for item in node.value:
-                    self.anchor_node(item)
-            elif isinstance(node, MappingNode):
-                for key, value in node.value:
-                    self.anchor_node(key)
-                    self.anchor_node(value)
-
-    def generate_anchor(self, node: Any) -> Any:
-        try:
-            anchor = node.anchor.value
-        except:  # NOQA
-            anchor = None
-        if anchor is None:
-            self.last_anchor_id += 1
-            return self.ANCHOR_TEMPLATE.format(self.last_anchor_id)
-        return anchor
-
-    def serialize_node(self, node: Any, parent: Any, index: Any) -> None:
-        alias = self.anchors[node]
-        if node in self.serialized_nodes:
-            node_style = getattr(node, 'style', None)
-            if node_style != '?':
-                node_style = None
-            self.emitter.emit(AliasEvent(alias, style=node_style))
-        else:
-            self.serialized_nodes[node] = True
-            self.resolver.descend_resolver(parent, index)
-            if isinstance(node, ScalarNode):
-                # here check if the node.tag equals the one that would result from parsing
-                # if not equal quoting is necessary for strings
-                detected_tag = self.resolver.resolve(ScalarNode, node.value, (True, False))
-                default_tag = self.resolver.resolve(ScalarNode, node.value, (False, True))
-                implicit = (
-                    (node.ctag == detected_tag),
-                    (node.ctag == default_tag),
-                    node.tag.startswith('tag:yaml.org,2002:'),  # type: ignore
-                )
-                self.emitter.emit(
-                    ScalarEvent(
-                        alias,
-                        node.ctag,
-                        implicit,
-                        node.value,
-                        style=node.style,
-                        comment=node.comment,
-                    ),
-                )
-            elif isinstance(node, SequenceNode):
-                implicit = node.ctag == self.resolver.resolve(SequenceNode, node.value, True)
-                comment = node.comment
-                end_comment = None
-                seq_comment = None
-                if node.flow_style is True:
-                    if comment:  # eol comment on flow style sequence
-                        seq_comment = comment[0]
-                        # comment[0] = None
-                if comment and len(comment) > 2:
-                    end_comment = comment[2]
-                else:
-                    end_comment = None
-                self.emitter.emit(
-                    SequenceStartEvent(
-                        alias,
-                        node.ctag,
-                        implicit,
-                        flow_style=node.flow_style,
-                        comment=node.comment,
-                    ),
-                )
-                index = 0
-                for item in node.value:
-                    self.serialize_node(item, node, index)
-                    index += 1
-                self.emitter.emit(SequenceEndEvent(comment=[seq_comment, end_comment]))
-            elif isinstance(node, MappingNode):
-                implicit = node.ctag == self.resolver.resolve(MappingNode, node.value, True)
-                comment = node.comment
-                end_comment = None
-                map_comment = None
-                if node.flow_style is True:
-                    if comment:  # eol comment on flow style sequence
-                        map_comment = comment[0]
-                        # comment[0] = None
-                if comment and len(comment) > 2:
-                    end_comment = comment[2]
-                self.emitter.emit(
-                    MappingStartEvent(
-                        alias,
-                        node.ctag,
-                        implicit,
-                        flow_style=node.flow_style,
-                        comment=node.comment,
-                        nr_items=len(node.value),
-                    ),
-                )
-                for key, value in node.value:
-                    self.serialize_node(key, node, None)
-                    self.serialize_node(value, node, key)
-                self.emitter.emit(MappingEndEvent(comment=[map_comment, end_comment]))
-            self.resolver.ascend_resolver()
-
-
-def templated_id(s: Text) -> Any:
-    return Serializer.ANCHOR_RE.match(s)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py
deleted file mode 100644
index f85dd031185..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tag.py
+++ /dev/null
@@ -1,126 +0,0 @@
-
-from __future__ import annotations
-
-"""
-In round-trip mode the original tag needs to be preserved, but the tag
-transformed based on the directives needs to be available as well.
-
-A Tag that is created during loading has a handle and a suffix.
-Not all objects loaded currently have a Tag, that .tag attribute can be None
-A Tag that is created for dumping only (on an object loaded without a tag) has a suffix
-only.
-"""
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Union, Iterator  # NOQA
-
-tag_attrib = '_yaml_tag'
-
-
-class Tag:
-    """store original tag information for roundtripping"""
-
-    attrib = tag_attrib
-
-    def __init__(self, handle: Any = None, suffix: Any = None, handles: Any = None) -> None:
-        self.handle = handle
-        self.suffix = suffix
-        self.handles = handles
-        self._transform_type: Optional[bool] = None
-
-    def __repr__(self) -> str:
-        return f'{self.__class__.__name__}({self.trval!r})'
-
-    def __str__(self) -> str:
-        return f'{self.trval}'
-
-    def __hash__(self) -> int:
-        try:
-            return self._hash_id  # type: ignore
-        except AttributeError:
-            self._hash_id = res = hash((self.handle, self.suffix))
-            return res
-
-    def __eq__(self, other: Any) -> bool:
-        # other should not be a string, but the serializer sometimes provides these
-        if isinstance(other, str):
-            return self.trval == other
-        return bool(self.trval == other.trval)
-
-    def startswith(self, x: str) -> bool:
-        if self.trval is not None:
-            return self.trval.startswith(x)
-        return False
-
-    @property
-    def trval(self) -> Optional[str]:
-        try:
-            return self._trval
-        except AttributeError:
-            pass
-        if self.handle is None:
-            self._trval: Optional[str] = self.uri_decoded_suffix
-            return self._trval
-        assert self._transform_type is not None
-        if not self._transform_type:
-            # the non-round-trip case
-            self._trval = self.handles[self.handle] + self.uri_decoded_suffix
-            return self._trval
-        # round-trip case
-        if self.handle == '!!' and self.suffix in (
-            'null',
-            'bool',
-            'int',
-            'float',
-            'binary',
-            'timestamp',
-            'omap',
-            'pairs',
-            'set',
-            'str',
-            'seq',
-            'map',
-        ):
-            self._trval = self.handles[self.handle] + self.uri_decoded_suffix
-        else:
-            # self._trval = self.handle + self.suffix
-            self._trval = self.handles[self.handle] + self.uri_decoded_suffix
-        return self._trval
-
-    value = trval
-
-    @property
-    def uri_decoded_suffix(self) -> Optional[str]:
-        try:
-            return self._uri_decoded_suffix
-        except AttributeError:
-            pass
-        if self.suffix is None:
-            self._uri_decoded_suffix: Optional[str] = None
-            return None
-        res = ''
-        # don't have to check for scanner errors here
-        idx = 0
-        while idx < len(self.suffix):
-            ch = self.suffix[idx]
-            idx += 1
-            if ch != '%':
-                res += ch
-            else:
-                res += chr(int(self.suffix[idx : idx + 2], 16))
-                idx += 2
-        self._uri_decoded_suffix = res
-        return res
-
-    def select_transform(self, val: bool) -> None:
-        """
-        val: False -> non-round-trip
-             True -> round-trip
-        """
-        assert self._transform_type is None
-        self._transform_type = val
-
-    def check_handle(self) -> bool:
-        if self.handle is None:
-            return False
-        return self.handle not in self.handles
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py
deleted file mode 100644
index 55efa0a45f1..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/timestamp.py
+++ /dev/null
@@ -1,63 +0,0 @@
-
-from __future__ import annotations
-
-import copy
-import datetime
-
-# ToDo: at least on PY3 you could probably attach the tzinfo correctly to the object
-#       a more complete datetime might be used by safe loading as well
-#
-#       add type information (iso8601, spaced)
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List  # NOQA
-
-
-class TimeStamp(datetime.datetime):
-    def __init__(self, *args: Any, **kw: Any) -> None:
-        self._yaml: Dict[str, Any] = dict(t=False, tz=None, delta=0)
-
-    def __new__(cls, *args: Any, **kw: Any) -> Any:  # datetime is immutable
-        return datetime.datetime.__new__(cls, *args, **kw)
-
-    def __deepcopy__(self, memo: Any) -> Any:
-        ts = TimeStamp(self.year, self.month, self.day, self.hour, self.minute, self.second)
-        ts._yaml = copy.deepcopy(self._yaml)
-        return ts
-
-    def replace(
-        self,
-        year: Any = None,
-        month: Any = None,
-        day: Any = None,
-        hour: Any = None,
-        minute: Any = None,
-        second: Any = None,
-        microsecond: Any = None,
-        tzinfo: Any = True,
-        fold: Any = None,
-    ) -> Any:
-        if year is None:
-            year = self.year
-        if month is None:
-            month = self.month
-        if day is None:
-            day = self.day
-        if hour is None:
-            hour = self.hour
-        if minute is None:
-            minute = self.minute
-        if second is None:
-            second = self.second
-        if microsecond is None:
-            microsecond = self.microsecond
-        if tzinfo is True:
-            tzinfo = self.tzinfo
-        if fold is None:
-            fold = self.fold
-        ts = type(self)(year, month, day, hour, minute, second, microsecond, tzinfo, fold=fold)
-        ts._yaml = copy.deepcopy(self._yaml)
-        return ts
-
-    def __str__(self) -> str:
-        return self.isoformat('T' if self._yaml['t'] else ' ')
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py
deleted file mode 100644
index 5c23c19e56d..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/tokens.py
+++ /dev/null
@@ -1,384 +0,0 @@
-
-from __future__ import annotations
-
-from opentelemetry.agent._vendor.ruamel.yaml.compat import nprintf  # NOQA
-
-if False:  # MYPY
-    from typing import Text, Any, Dict, Optional, List  # NOQA
-from .error import StreamMark  # NOQA
-
-SHOW_LINES = True
-
-
-class Token:
-    __slots__ = 'start_mark', 'end_mark', '_comment'
-
-    def __init__(self, start_mark: StreamMark, end_mark: StreamMark) -> None:
-        self.start_mark = start_mark
-        self.end_mark = end_mark
-
-    def __repr__(self) -> Any:
-        # attributes = [key for key in self.__slots__ if not key.endswith('_mark') and
-        #               hasattr('self', key)]
-        attributes = [key for key in self.__slots__ if not key.endswith('_mark')]
-        attributes.sort()
-        # arguments = ', '.join(
-        #  [f'{key!s}={getattr(self, key)!r})' for key in attributes]
-        # )
-        arguments = [f'{key!s}={getattr(self, key)!r}' for key in attributes]
-        if SHOW_LINES:
-            try:
-                arguments.append('line: ' + str(self.start_mark.line))
-            except:  # NOQA
-                pass
-        try:
-            arguments.append('comment: ' + str(self._comment))
-        except:  # NOQA
-            pass
-        return f'{self.__class__.__name__}({", ".join(arguments)})'
-
-    @property
-    def column(self) -> int:
-        return self.start_mark.column
-
-    @column.setter
-    def column(self, pos: Any) -> None:
-        self.start_mark.column = pos
-
-    # old style ( <= 0.17) is a TWO element list with first being the EOL
-    # comment concatenated with following FLC/BLNK; and second being a list of FLC/BLNK
-    # preceding the token
-    # new style ( >= 0.17 ) is a THREE element list with the first being a list of
-    # preceding FLC/BLNK, the second EOL and the third following FLC/BLNK
-    # note that new style has differing order, and does not consist of CommentToken(s)
-    # but of CommentInfo instances
-    # any non-assigned values in new style are None, but first and last can be empty list
-    # new style routines add one comment at a time
-
-    # going to be deprecated in favour of add_comment_eol/post
-    def add_post_comment(self, comment: Any) -> None:
-        if not hasattr(self, '_comment'):
-            self._comment = [None, None]
-        else:
-            assert len(self._comment) in [2, 5]  # make sure it is version 0
-        # if isinstance(comment, CommentToken):
-        #    if comment.value.startswith('# C09'):
-        #        raise
-        self._comment[0] = comment
-
-    # going to be deprecated in favour of add_comment_pre
-    def add_pre_comments(self, comments: Any) -> None:
-        if not hasattr(self, '_comment'):
-            self._comment = [None, None]
-        else:
-            assert len(self._comment) == 2  # make sure it is version 0
-        assert self._comment[1] is None
-        self._comment[1] = comments
-        return
-
-    # new style
-    def add_comment_pre(self, comment: Any) -> None:
-        if not hasattr(self, '_comment'):
-            self._comment = [[], None, None]  # type: ignore
-        else:
-            assert len(self._comment) == 3
-            if self._comment[0] is None:
-                self._comment[0] = []  # type: ignore
-        self._comment[0].append(comment)  # type: ignore
-
-    def add_comment_eol(self, comment: Any, comment_type: Any) -> None:
-        if not hasattr(self, '_comment'):
-            self._comment = [None, None, None]
-        else:
-            assert len(self._comment) == 3
-            assert self._comment[1] is None
-        if self.comment[1] is None:
-            self._comment[1] = []  # type: ignore
-        self._comment[1].extend([None] * (comment_type + 1 - len(self.comment[1])))  # type: ignore # NOQA
-        # nprintf('commy', self.comment, comment_type)
-        self._comment[1][comment_type] = comment  # type: ignore
-
-    def add_comment_post(self, comment: Any) -> None:
-        if not hasattr(self, '_comment'):
-            self._comment = [None, None, []]  # type: ignore
-        else:
-            assert len(self._comment) == 3
-            if self._comment[2] is None:
-                self._comment[2] = []  # type: ignore
-        self._comment[2].append(comment)  # type: ignore
-
-    # def get_comment(self) -> Any:
-    #     return getattr(self, '_comment', None)
-
-    @property
-    def comment(self) -> Any:
-        return getattr(self, '_comment', None)
-
-    def move_old_comment(self, target: Any, empty: bool = False) -> Any:
-        """move a comment from this token to target (normally next token)
-        used to combine e.g. comments before a BlockEntryToken to the
-        ScalarToken that follows it
-        empty is a special for empty values -> comment after key
-        """
-        c = self.comment
-        if c is None:
-            return
-        # don't push beyond last element
-        if isinstance(target, (StreamEndToken, DocumentStartToken)):
-            return
-        delattr(self, '_comment')  # NOQA
-        tc = target.comment
-        if not tc:  # target comment, just insert
-            # special for empty value in key: value issue 25
-            if empty:
-                c = [c[0], c[1], None, None, c[0]]
-            target._comment = c
-            # nprint('mco2:', self, target, target.comment, empty)
-            return self
-        if c[0] and tc[0] or c[1] and tc[1]:
-            if isinstance(c[1], list) and isinstance(tc[1], list):
-                c[1].extend(tc[1])
-            else:
-                raise NotImplementedError(f'overlap in comment {c!r} {tc!r}')
-        if c[0]:
-            tc[0] = c[0]
-        if c[1]:
-            tc[1] = c[1]
-        return self
-
-    def split_old_comment(self) -> Any:
-        """ split the post part of a comment, and return it
-        as comment to be added. Delete second part if [None, None]
-         abc:  # this goes to sequence
-           # this goes to first element
-           - first element
-        """
-        comment = self.comment
-        if comment is None or comment[0] is None:
-            return None  # nothing to do
-        ret_val = [comment[0], None]
-        if comment[1] is None:
-            delattr(self, '_comment')  # NOQA
-        return ret_val
-
-    def move_new_comment(self, target: Any, empty: bool = False) -> Any:
-        """move a comment from this token to target (normally next token)
-        used to combine e.g. comments before a BlockEntryToken to the
-        ScalarToken that follows it
-        empty is a special for empty values -> comment after key
-        """
-        c = self.comment
-        if c is None:
-            return
-        # don't push beyond last element
-        if isinstance(target, (StreamEndToken, DocumentStartToken)):
-            return
-        delattr(self, '_comment')  # NOQA
-        tc = target.comment
-        if not tc:  # target comment, just insert
-            # special for empty value in key: value issue 25
-            if empty:
-                c = [c[0], c[1], c[2]]
-            target._comment = c
-            # nprint('mco2:', self, target, target.comment, empty)
-            return self
-        # if self and target have both pre, eol or post comments, something seems wrong
-        for idx in range(3):
-            if c[idx] is not None and tc[idx] is not None:
-                raise NotImplementedError(f'overlap in comment {c!r} {tc!r}')
-        # move the comment parts
-        for idx in range(3):
-            if c[idx]:
-                tc[idx] = c[idx]
-        return self
-
-
-# class BOMToken(Token):
-#     id = ''
-
-
-class DirectiveToken(Token):
-    __slots__ = 'name', 'value'
-    id = ''
-
-    def __init__(self, name: Any, value: Any, start_mark: Any, end_mark: Any) -> None:
-        Token.__init__(self, start_mark, end_mark)
-        self.name = name
-        self.value = value
-
-
-class DocumentStartToken(Token):
-    __slots__ = ()
-    id = ''
-
-
-class DocumentEndToken(Token):
-    __slots__ = ()
-    id = ''
-
-
-class StreamStartToken(Token):
-    __slots__ = ('encoding',)
-    id = ''
-
-    def __init__(
-        self, start_mark: Any = None, end_mark: Any = None, encoding: Any = None,
-    ) -> None:
-        Token.__init__(self, start_mark, end_mark)
-        self.encoding = encoding
-
-
-class StreamEndToken(Token):
-    __slots__ = ()
-    id = ''
-
-
-class BlockSequenceStartToken(Token):
-    __slots__ = ()
-    id = ''
-
-
-class BlockMappingStartToken(Token):
-    __slots__ = ()
-    id = ''
-
-
-class BlockEndToken(Token):
-    __slots__ = ()
-    id = ''
-
-
-class FlowSequenceStartToken(Token):
-    __slots__ = ()
-    id = '['
-
-
-class FlowMappingStartToken(Token):
-    __slots__ = ()
-    id = '{'
-
-
-class FlowSequenceEndToken(Token):
-    __slots__ = ()
-    id = ']'
-
-
-class FlowMappingEndToken(Token):
-    __slots__ = ()
-    id = '}'
-
-
-class KeyToken(Token):
-    __slots__ = ()
-    id = '?'
-
-#   def x__repr__(self):
-#       return f'KeyToken({self.start_mark.buffer[self.start_mark.index:].split(None, 1)[0]})'
-
-
-class ValueToken(Token):
-    __slots__ = ()
-    id = ':'
-
-
-class BlockEntryToken(Token):
-    __slots__ = ()
-    id = '-'
-
-
-class FlowEntryToken(Token):
-    __slots__ = ()
-    id = ','
-
-
-class AliasToken(Token):
-    __slots__ = ('value',)
-    id = ''
-
-    def __init__(self, value: Any, start_mark: Any, end_mark: Any) -> None:
-        Token.__init__(self, start_mark, end_mark)
-        self.value = value
-
-
-class AnchorToken(Token):
-    __slots__ = ('value',)
-    id = ''
-
-    def __init__(self, value: Any, start_mark: Any, end_mark: Any) -> None:
-        Token.__init__(self, start_mark, end_mark)
-        self.value = value
-
-
-class TagToken(Token):
-    __slots__ = ('value',)
-    id = ''
-
-    def __init__(self, value: Any, start_mark: Any, end_mark: Any) -> None:
-        Token.__init__(self, start_mark, end_mark)
-        self.value = value
-
-
-class ScalarToken(Token):
-    __slots__ = 'value', 'plain', 'style'
-    id = ''
-
-    def __init__(
-        self, value: Any, plain: Any, start_mark: Any, end_mark: Any, style: Any = None,
-    ) -> None:
-        Token.__init__(self, start_mark, end_mark)
-        self.value = value
-        self.plain = plain
-        self.style = style
-
-
-class CommentToken(Token):
-    __slots__ = '_value', '_column', 'pre_done'
-    id = ''
-
-    def __init__(
-        self, value: Any, start_mark: Any = None, end_mark: Any = None, column: Any = None,
-    ) -> None:
-        if start_mark is None:
-            assert column is not None
-            self._column = column
-        Token.__init__(self, start_mark, end_mark)
-        self._value = value
-
-    @property
-    def value(self) -> str:
-        if isinstance(self._value, str):
-            return self._value
-        return "".join(self._value)
-
-    @value.setter
-    def value(self, val: Any) -> None:
-        self._value = val
-
-    def reset(self) -> None:
-        if hasattr(self, 'pre_done'):
-            delattr(self, 'pre_done')  # NOQA
-
-    def __repr__(self) -> Any:
-        v = f'{self.value!r}'
-        if SHOW_LINES:
-            try:
-                v += ', line: ' + str(self.start_mark.line)
-            except:  # NOQA
-                pass
-            try:
-                v += ', col: ' + str(self.start_mark.column)
-            except:  # NOQA
-                pass
-        return f'CommentToken({v})'
-
-    def __eq__(self, other: Any) -> bool:
-        if self.start_mark != other.start_mark:
-            return False
-        if self.end_mark != other.end_mark:
-            return False
-        if self.value != other.value:
-            return False
-        return True
-
-    def __ne__(self, other: Any) -> bool:
-        return not self.__eq__(other)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py
deleted file mode 100644
index 398e0e9cf75..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/ruamel/yaml/util.py
+++ /dev/null
@@ -1,264 +0,0 @@
-
-
-"""
-some helper functions that might be generally useful
-"""
-
-from __future__ import annotations
-
-import datetime
-from functools import partial
-import re
-
-
-if False:  # MYPY
-    from typing import Any, Dict, Optional, List, Text, Callable, Union  # NOQA
-    from .compat import StreamTextType  # NOQA
-
-
-class LazyEval:
-    """
-    Lightweight wrapper around lazily evaluated func(*args, **kwargs).
-
-    func is only evaluated when any attribute of its return value is accessed.
-    Every attribute access is passed through to the wrapped value.
-    (This only excludes special cases like method-wrappers, e.g., __hash__.)
-    The sole additional attribute is the lazy_self function which holds the
-    return value (or, prior to evaluation, func and arguments), in its closure.
-    """
-
-    def __init__(self, func: Callable[..., Any], *args: Any, **kwargs: Any) -> None:
-        def lazy_self() -> Any:
-            return_value = func(*args, **kwargs)
-            object.__setattr__(self, 'lazy_self', lambda: return_value)
-            return return_value
-
-        object.__setattr__(self, 'lazy_self', lazy_self)
-
-    def __getattribute__(self, name: str) -> Any:
-        lazy_self = object.__getattribute__(self, 'lazy_self')
-        if name == 'lazy_self':
-            return lazy_self
-        return getattr(lazy_self(), name)
-
-    def __setattr__(self, name: str, value: Any) -> None:
-        setattr(self.lazy_self(), name, value)
-
-
-RegExp = partial(LazyEval, re.compile)
-
-timestamp_regexp = RegExp(
-    """^(?P[0-9][0-9][0-9][0-9])
-       -(?P[0-9][0-9]?)
-       -(?P[0-9][0-9]?)
-       (?:((?P[Tt])|[ \\t]+)   # explictly not retaining extra spaces
-       (?P[0-9][0-9]?)
-       :(?P[0-9][0-9])
-       :(?P[0-9][0-9])
-       (?:\\.(?P[0-9]*))?
-        (?:[ \\t]*(?PZ|(?P[-+])(?P[0-9][0-9]?)
-       (?::(?P[0-9][0-9]))?))?)?$""",
-    re.X,
-)
-
-
-def create_timestamp(
-    year: Any,
-    month: Any,
-    day: Any,
-    t: Any,
-    hour: Any,
-    minute: Any,
-    second: Any,
-    fraction: Any,
-    tz: Any,
-    tz_sign: Any,
-    tz_hour: Any,
-    tz_minute: Any,
-) -> Union[datetime.datetime, datetime.date]:
-    # create a timestamp from matching against timestamp_regexp
-    MAX_FRAC = 999999
-    year = int(year)
-    month = int(month)
-    day = int(day)
-    if hour is None:
-        return datetime.date(year, month, day)
-    hour = int(hour)
-    minute = int(minute)
-    second = int(second)
-    frac = 0
-    if fraction:
-        frac_s = fraction[:6]
-        while len(frac_s) < 6:
-            frac_s += '0'
-        frac = int(frac_s)
-        if len(fraction) > 6 and int(fraction[6]) > 4:
-            frac += 1
-        if frac > MAX_FRAC:
-            fraction = 0
-        else:
-            fraction = frac
-    else:
-        fraction = 0
-    tzinfo = None
-    delta = None
-    if tz_sign:
-        tz_hour = int(tz_hour)
-        tz_minute = int(tz_minute) if tz_minute else 0
-        td = datetime.timedelta(
-            hours=tz_hour, minutes=tz_minute,
-        )
-        if tz_sign == '-':
-            td = -td
-        tzinfo = datetime.timezone(td, name=tz)
-    elif tz == 'Z':
-        tzinfo = datetime.timezone(datetime.timedelta(hours=0), name=tz)
-    if frac > MAX_FRAC:
-        delta = -datetime.timedelta(seconds=1)
-    # should do something else instead (or hook this up to the preceding if statement
-    # in reverse
-    #  if delta is None:
-    #      return datetime.datetime(year, month, day, hour, minute, second, fraction)
-    #  return datetime.datetime(year, month, day, hour, minute, second, fraction,
-    #                           datetime.timezone.utc)
-    # the above is not good enough though, should provide tzinfo. In Python3 that is easily
-    # doable drop that kind of support for Python2 as it has not native tzinfo
-    data = datetime.datetime(year, month, day, hour, minute, second, fraction, tzinfo)
-    if delta:
-        data -= delta
-    return data
-
-
-# originally as comment
-# https://github.com/pre-commit/pre-commit/pull/211#issuecomment-186466605
-# if you use this in your code, I suggest adding a test in your test suite
-# that check this routines output against a known piece of your YAML
-# before upgrades to this code break your round-tripped YAML
-def load_yaml_guess_indent(stream: StreamTextType, **kw: Any) -> Any:
-    """guess the indent and block sequence indent of yaml stream/string
-
-    returns round_trip_loaded stream, indent level, block sequence indent
-    - block sequence indent is the number of spaces before a dash relative to previous indent
-    - if there are no block sequences, indent is taken from nested mappings, block sequence
-      indent is unset (None) in that case
-    """
-    from .main import YAML
-
-    # load a YAML document, guess the indentation, if you use TABs you are on your own
-    def leading_spaces(line: Any) -> int:
-        idx = 0
-        while idx < len(line) and line[idx] == ' ':
-            idx += 1
-        return idx
-
-    if isinstance(stream, str):
-        yaml_str: Any = stream
-    elif isinstance(stream, bytes):
-        # most likely, but the Reader checks BOM for this
-        yaml_str = stream.decode('utf-8')
-    else:
-        yaml_str = stream.read()
-    map_indent = None
-    indent = None  # default if not found for some reason
-    block_seq_indent = None
-    prev_line_key_only = None
-    key_indent = 0
-    for line in yaml_str.splitlines():
-        rline = line.rstrip()
-        lline = rline.lstrip()
-        if lline.startswith('- '):
-            l_s = leading_spaces(line)
-            block_seq_indent = l_s - key_indent
-            idx = l_s + 1
-            while line[idx] == ' ':  # this will end as we rstripped
-                idx += 1
-            if line[idx] == '#':  # comment after -
-                continue
-            indent = idx - key_indent
-            break
-        if map_indent is None and prev_line_key_only is not None and rline:
-            idx = 0
-            while line[idx] in ' -':
-                idx += 1
-            if idx > prev_line_key_only:
-                map_indent = idx - prev_line_key_only
-        if rline.endswith(':'):
-            key_indent = leading_spaces(line)
-            idx = 0
-            while line[idx] == ' ':  # this will end on ':'
-                idx += 1
-            prev_line_key_only = idx
-            continue
-        prev_line_key_only = None
-    if indent is None and map_indent is not None:
-        indent = map_indent
-    yaml = YAML() if 'yaml' not in kw else kw.pop('yaml')
-    return yaml.load(yaml_str, **kw), indent, block_seq_indent
-
-
-def configobj_walker(cfg: Any) -> Any:
-    """
-    walks over a ConfigObj (INI file with comments) generating
-    corresponding YAML output (including comments
-    """
-    from configobj import ConfigObj  # type: ignore
-
-    assert isinstance(cfg, ConfigObj)
-    for c in cfg.initial_comment:
-        if c.strip():
-            yield c
-    for s in _walk_section(cfg):
-        if s.strip():
-            yield s
-    for c in cfg.final_comment:
-        if c.strip():
-            yield c
-
-
-def _walk_section(s: Any, level: int = 0) -> Any:
-    from configobj import Section
-
-    assert isinstance(s, Section)
-    indent = '  ' * level
-    for name in s.scalars:
-        for c in s.comments[name]:
-            yield indent + c.strip()
-        x = s[name]
-        if '\n' in x:
-            i = indent + '  '
-            x = '|\n' + i + x.strip().replace('\n', '\n' + i)
-        elif ':' in x:
-            x = "'" + x.replace("'", "''") + "'"
-        line = f'{indent}{name}: {x}'
-        c = s.inline_comments[name]
-        if c:
-            line += ' ' + c
-        yield line
-    for name in s.sections:
-        for c in s.comments[name]:
-            yield indent + c.strip()
-        line = f'{indent}{name}:'
-        c = s.inline_comments[name]
-        if c:
-            line += ' ' + c
-        yield line
-        for val in _walk_section(s[name], level=level + 1):
-            yield val
-
-
-# def config_obj_2_rt_yaml(cfg):
-#     from .comments import CommentedMap, CommentedSeq
-#     from configobj import ConfigObj
-#     assert isinstance(cfg, ConfigObj)
-#     #for c in cfg.initial_comment:
-#     #    if c.strip():
-#     #        pass
-#     cm = CommentedMap()
-#     for name in s.sections:
-#         cm[name] = d = CommentedMap()
-#
-#
-#     #for c in cfg.final_comment:
-#     #    if c.strip():
-#     #        yield c
-#     return cm
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE
deleted file mode 100644
index f26bcf4d2de..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing-extensions.LICENSE
+++ /dev/null
@@ -1,279 +0,0 @@
-A. HISTORY OF THE SOFTWARE
-==========================
-
-Python was created in the early 1990s by Guido van Rossum at Stichting
-Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands
-as a successor of a language called ABC.  Guido remains Python's
-principal author, although it includes many contributions from others.
-
-In 1995, Guido continued his work on Python at the Corporation for
-National Research Initiatives (CNRI, see https://www.cnri.reston.va.us)
-in Reston, Virginia where he released several versions of the
-software.
-
-In May 2000, Guido and the Python core development team moved to
-BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
-year, the PythonLabs team moved to Digital Creations, which became
-Zope Corporation.  In 2001, the Python Software Foundation (PSF, see
-https://www.python.org/psf/) was formed, a non-profit organization
-created specifically to own Python-related Intellectual Property.
-Zope Corporation was a sponsoring member of the PSF.
-
-All Python releases are Open Source (see https://opensource.org for
-the Open Source Definition).  Historically, most, but not all, Python
-releases have also been GPL-compatible; the table below summarizes
-the various releases.
-
-    Release         Derived     Year        Owner       GPL-
-                    from                                compatible? (1)
-
-    0.9.0 thru 1.2              1991-1995   CWI         yes
-    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
-    1.6             1.5.2       2000        CNRI        no
-    2.0             1.6         2000        BeOpen.com  no
-    1.6.1           1.6         2001        CNRI        yes (2)
-    2.1             2.0+1.6.1   2001        PSF         no
-    2.0.1           2.0+1.6.1   2001        PSF         yes
-    2.1.1           2.1+2.0.1   2001        PSF         yes
-    2.1.2           2.1.1       2002        PSF         yes
-    2.1.3           2.1.2       2002        PSF         yes
-    2.2 and above   2.1.1       2001-now    PSF         yes
-
-Footnotes:
-
-(1) GPL-compatible doesn't mean that we're distributing Python under
-    the GPL.  All Python licenses, unlike the GPL, let you distribute
-    a modified version without making your changes open source.  The
-    GPL-compatible licenses make it possible to combine Python with
-    other software that is released under the GPL; the others don't.
-
-(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
-    because its license has a choice of law clause.  According to
-    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
-    is "not incompatible" with the GPL.
-
-Thanks to the many outside volunteers who have worked under Guido's
-direction to make these releases possible.
-
-
-B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
-===============================================================
-
-Python software and documentation are licensed under the
-Python Software Foundation License Version 2.
-
-Starting with Python 3.8.6, examples, recipes, and other code in
-the documentation are dual licensed under the PSF License Version 2
-and the Zero-Clause BSD license.
-
-Some software incorporated into Python is under different licenses.
-The licenses are listed with code falling under that license.
-
-
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF hereby
-grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
-analyze, test, perform and/or display publicly, prepare derivative works,
-distribute, and otherwise use Python alone or in any derivative version,
-provided, however, that PSF's License Agreement and PSF's notice of copyright,
-i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation;
-All Rights Reserved" are retained in Python alone or in any derivative version
-prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee.  This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
--------------------------------------------
-
-BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
-
-1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
-office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
-Individual or Organization ("Licensee") accessing and otherwise using
-this software in source or binary form and its associated
-documentation ("the Software").
-
-2. Subject to the terms and conditions of this BeOpen Python License
-Agreement, BeOpen hereby grants Licensee a non-exclusive,
-royalty-free, world-wide license to reproduce, analyze, test, perform
-and/or display publicly, prepare derivative works, distribute, and
-otherwise use the Software alone or in any derivative version,
-provided, however, that the BeOpen Python License is retained in the
-Software, alone or in any derivative version prepared by Licensee.
-
-3. BeOpen is making the Software available to Licensee on an "AS IS"
-basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
-SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
-AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
-DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-5. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-6. This License Agreement shall be governed by and interpreted in all
-respects by the law of the State of California, excluding conflict of
-law provisions.  Nothing in this License Agreement shall be deemed to
-create any relationship of agency, partnership, or joint venture
-between BeOpen and Licensee.  This License Agreement does not grant
-permission to use BeOpen trademarks or trade names in a trademark
-sense to endorse or promote products or services of Licensee, or any
-third party.  As an exception, the "BeOpen Python" logos available at
-http://www.pythonlabs.com/logos.html may be used according to the
-permissions granted on that web page.
-
-7. By copying, installing or otherwise using the software, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
----------------------------------------
-
-1. This LICENSE AGREEMENT is between the Corporation for National
-Research Initiatives, having an office at 1895 Preston White Drive,
-Reston, VA 20191 ("CNRI"), and the Individual or Organization
-("Licensee") accessing and otherwise using Python 1.6.1 software in
-source or binary form and its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, CNRI
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python 1.6.1
-alone or in any derivative version, provided, however, that CNRI's
-License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
-1995-2001 Corporation for National Research Initiatives; All Rights
-Reserved" are retained in Python 1.6.1 alone or in any derivative
-version prepared by Licensee.  Alternately, in lieu of CNRI's License
-Agreement, Licensee may substitute the following text (omitting the
-quotes): "Python 1.6.1 is made available subject to the terms and
-conditions in CNRI's License Agreement.  This Agreement together with
-Python 1.6.1 may be located on the internet using the following
-unique, persistent identifier (known as a handle): 1895.22/1013.  This
-Agreement may also be obtained from a proxy server on the internet
-using the following URL: http://hdl.handle.net/1895.22/1013".
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python 1.6.1 or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python 1.6.1.
-
-4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
-basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. This License Agreement shall be governed by the federal
-intellectual property law of the United States, including without
-limitation the federal copyright law, and, to the extent such
-U.S. federal law does not apply, by the law of the Commonwealth of
-Virginia, excluding Virginia's conflict of law provisions.
-Notwithstanding the foregoing, with regard to derivative works based
-on Python 1.6.1 that incorporate non-separable material that was
-previously distributed under the GNU General Public License (GPL), the
-law of the Commonwealth of Virginia shall govern this License
-Agreement only as to issues arising under or with respect to
-Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
-License Agreement shall be deemed to create any relationship of
-agency, partnership, or joint venture between CNRI and Licensee.  This
-License Agreement does not grant permission to use CNRI trademarks or
-trade name in a trademark sense to endorse or promote products or
-services of Licensee, or any third party.
-
-8. By clicking on the "ACCEPT" button where indicated, or by copying,
-installing or otherwise using Python 1.6.1, Licensee agrees to be
-bound by the terms and conditions of this License Agreement.
-
-        ACCEPT
-
-
-CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
---------------------------------------------------
-
-Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
-The Netherlands.  All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Stichting Mathematisch
-Centrum or CWI not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION
-----------------------------------------------------------------------
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py
deleted file mode 100644
index ced78373258..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/typing_extensions.py
+++ /dev/null
@@ -1,4422 +0,0 @@
-import abc
-import builtins
-import collections
-import collections.abc
-import contextlib
-import enum
-import functools
-import inspect
-import io
-import keyword
-import operator
-import sys
-import types as _types
-import typing
-import warnings
-
-# Breakpoint: https://github.com/python/cpython/pull/119891
-if sys.version_info >= (3, 14):
-    import annotationlib
-
-__all__ = [
-    # Super-special typing primitives.
-    'Any',
-    'ClassVar',
-    'Concatenate',
-    'Final',
-    'LiteralString',
-    'ParamSpec',
-    'ParamSpecArgs',
-    'ParamSpecKwargs',
-    'Self',
-    'Type',
-    'TypeVar',
-    'TypeVarTuple',
-    'Unpack',
-
-    # ABCs (from collections.abc).
-    'Awaitable',
-    'AsyncIterator',
-    'AsyncIterable',
-    'Coroutine',
-    'AsyncGenerator',
-    'AsyncContextManager',
-    'Buffer',
-    'ChainMap',
-
-    # Concrete collection types.
-    'ContextManager',
-    'Counter',
-    'Deque',
-    'DefaultDict',
-    'NamedTuple',
-    'OrderedDict',
-    'TypedDict',
-
-    # Structural checks, a.k.a. protocols.
-    'SupportsAbs',
-    'SupportsBytes',
-    'SupportsComplex',
-    'SupportsFloat',
-    'SupportsIndex',
-    'SupportsInt',
-    'SupportsRound',
-    'Reader',
-    'Writer',
-
-    # One-off things.
-    'Annotated',
-    'assert_never',
-    'assert_type',
-    'clear_overloads',
-    'dataclass_transform',
-    'deprecated',
-    'disjoint_base',
-    'Doc',
-    'evaluate_forward_ref',
-    'get_overloads',
-    'final',
-    'Format',
-    'get_annotations',
-    'get_args',
-    'get_origin',
-    'get_original_bases',
-    'get_protocol_members',
-    'get_type_hints',
-    'IntVar',
-    'is_protocol',
-    'is_typeddict',
-    'Literal',
-    'NewType',
-    'overload',
-    'override',
-    'Protocol',
-    'sentinel',
-    'Sentinel',
-    'reveal_type',
-    'runtime',
-    'runtime_checkable',
-    'Text',
-    'TypeAlias',
-    'TypeAliasType',
-    'TypeForm',
-    'TypeGuard',
-    'TypeIs',
-    'TYPE_CHECKING',
-    'type_repr',
-    'Never',
-    'NoReturn',
-    'ReadOnly',
-    'Required',
-    'NotRequired',
-    'NoDefault',
-    'NoExtraItems',
-
-    # Pure aliases, have always been in typing
-    'AbstractSet',
-    'AnyStr',
-    'BinaryIO',
-    'Callable',
-    'Collection',
-    'Container',
-    'Dict',
-    'ForwardRef',
-    'FrozenSet',
-    'Generator',
-    'Generic',
-    'Hashable',
-    'IO',
-    'ItemsView',
-    'Iterable',
-    'Iterator',
-    'KeysView',
-    'List',
-    'Mapping',
-    'MappingView',
-    'Match',
-    'MutableMapping',
-    'MutableSequence',
-    'MutableSet',
-    'Optional',
-    'Pattern',
-    'Reversible',
-    'Sequence',
-    'Set',
-    'Sized',
-    'TextIO',
-    'Tuple',
-    'Union',
-    'ValuesView',
-    'cast',
-    'no_type_check',
-]
-
-# for backward compatibility
-PEP_560 = True
-GenericMeta = type
-# Breakpoint: https://github.com/python/cpython/pull/116129
-_PEP_696_IMPLEMENTED = sys.version_info >= (3, 13, 0, "beta")
-
-# Added with bpo-45166 to 3.10.1+ and some 3.9 versions
-_FORWARD_REF_HAS_CLASS = "__forward_is_class__" in typing.ForwardRef.__slots__
-
-
-def _caller(depth=1, default='__main__'):
-    try:
-        return sys._getframemodulename(depth + 1) or default
-    except AttributeError:  # For platforms without _getframemodulename()
-        pass
-    try:
-        return sys._getframe(depth + 1).f_globals.get('__name__', default)
-    except (AttributeError, ValueError):  # For platforms without _getframe()
-        pass
-    return None
-
-
-# Placeholder for sentinel methods, because sentinels can not have their own sentinels
-_sentinel_placeholder = object()
-
-if hasattr(builtins, "sentinel"):  # 3.15+
-    sentinel = builtins.sentinel
-else:
-    class sentinel:
-        """Create a unique sentinel object.
-
-        *name* should be the name of the variable to which the return value
-        shall be assigned.
-        """
-
-        def __init__(
-            self,
-            __name: str = _sentinel_placeholder,
-            __repr: typing.Optional[str] = _sentinel_placeholder,
-            /,
-            *,
-            repr: typing.Optional[str] = None,
-            name: str = _sentinel_placeholder,
-        ) -> None:
-            if name is not _sentinel_placeholder:
-                warnings.warn(
-                    "Passing 'name' as a keyword argument is deprecated; "
-                    "pass it positionally instead.",
-                    DeprecationWarning,
-                    stacklevel=2,
-                )
-                __name = name
-            if __name is _sentinel_placeholder:
-                raise TypeError("First parameter 'name' is required")
-            if __repr is not _sentinel_placeholder:
-                warnings.warn(
-                    "Passing 'repr' as a positional argument is deprecated; "
-                    "pass it by keyword instead.",
-                    DeprecationWarning,
-                    stacklevel=2,
-                )
-                repr = __repr
-
-            self._name = __name
-            self._repr = repr if repr is not None else __name
-
-            # For pickling as a singleton:
-            self.__module__ = _caller()
-
-        def __init_subclass__(cls):
-            warnings.warn(
-                "Subclassing sentinel is deprecated "
-                "and will be disallowed in Python 3.15",
-                DeprecationWarning,
-                stacklevel=2,
-            )
-            super().__init_subclass__()
-
-        def __setattr__(self, attr: str, value: object) -> None:
-            if attr not in {"_name", "_repr", "__module__"}:
-                warnings.warn(
-                    f"Setting attribute {attr!r} on sentinel objects is deprecated "
-                    "and will be disallowed in Python 3.15.",
-                    DeprecationWarning,
-                    stacklevel=2,
-                )
-            super().__setattr__(attr, value)
-
-        @property
-        def __name__(self) -> str:
-            return self._name
-
-        @__name__.setter
-        def __name__(self, value: str) -> None:
-            self._name = value
-
-        def __repr__(self) -> str:
-            return self._repr
-
-        if sys.version_info < (3, 11):
-            # The presence of this method convinces typing._type_check
-            # that Sentinels are types.
-            def __call__(self, *args, **kwargs):
-                raise TypeError(f"{type(self).__name__!r} object is not callable")
-
-        # Breakpoint: https://github.com/python/cpython/pull/21515
-        if sys.version_info >= (3, 10):
-            def __or__(self, other):
-                return typing.Union[self, other]
-
-            def __ror__(self, other):
-                return typing.Union[other, self]
-
-        def __reduce__(self) -> str:
-            """Reduce this sentinel to a singleton."""
-            return self.__name__  # Module is taken from the __module__ attribute
-
-Sentinel = sentinel
-
-_marker = sentinel("sentinel")
-
-
-# The functions below are modified copies of typing internal helpers.
-# They are needed by _ProtocolMeta and they provide support for PEP 646.
-
-# Breakpoint: https://github.com/python/cpython/pull/27342
-if sys.version_info >= (3, 10):
-    def _should_collect_from_parameters(t):
-        return isinstance(
-            t, (typing._GenericAlias, _types.GenericAlias, _types.UnionType)
-        )
-else:
-    def _should_collect_from_parameters(t):
-        return isinstance(t, (typing._GenericAlias, _types.GenericAlias))
-
-
-NoReturn = typing.NoReturn
-
-# Some unconstrained type variables.  These are used by the container types.
-# (These are not for export.)
-T = typing.TypeVar('T')  # Any type.
-KT = typing.TypeVar('KT')  # Key type.
-VT = typing.TypeVar('VT')  # Value type.
-T_co = typing.TypeVar('T_co', covariant=True)  # Any type covariant containers.
-T_contra = typing.TypeVar('T_contra', contravariant=True)  # Ditto contravariant.
-
-
-# Breakpoint: https://github.com/python/cpython/pull/31841
-if sys.version_info >= (3, 11):
-    from typing import Any
-else:
-
-    class _AnyMeta(type):
-        def __instancecheck__(self, obj):
-            if self is Any:
-                raise TypeError("typing_extensions.Any cannot be used with isinstance()")
-            return super().__instancecheck__(obj)
-
-        def __repr__(self):
-            if self is Any:
-                return "typing_extensions.Any"
-            return super().__repr__()
-
-    class Any(metaclass=_AnyMeta):
-        """Special type indicating an unconstrained type.
-        - Any is compatible with every type.
-        - Any assumed to have all methods.
-        - All values assumed to be instances of Any.
-        Note that all the above statements are true from the point of view of
-        static type checkers. At runtime, Any should not be used with instance
-        checks.
-        """
-        def __new__(cls, *args, **kwargs):
-            if cls is Any:
-                raise TypeError("Any cannot be instantiated")
-            return super().__new__(cls, *args, **kwargs)
-
-
-ClassVar = typing.ClassVar
-
-# Vendored from cpython typing._SpecialFrom
-# Having a separate class means that instances will not be rejected by
-# typing._type_check.
-class _SpecialForm(typing._Final, _root=True):
-    __slots__ = ('_name', '__doc__', '_getitem')
-
-    def __init__(self, getitem):
-        self._getitem = getitem
-        self._name = getitem.__name__
-        self.__doc__ = getitem.__doc__
-
-    def __getattr__(self, item):
-        if item in {'__name__', '__qualname__'}:
-            return self._name
-
-        raise AttributeError(item)
-
-    def __mro_entries__(self, bases):
-        raise TypeError(f"Cannot subclass {self!r}")
-
-    def __repr__(self):
-        return f'typing_extensions.{self._name}'
-
-    def __reduce__(self):
-        return self._name
-
-    def __call__(self, *args, **kwds):
-        raise TypeError(f"Cannot instantiate {self!r}")
-
-    def __or__(self, other):
-        return typing.Union[self, other]
-
-    def __ror__(self, other):
-        return typing.Union[other, self]
-
-    def __instancecheck__(self, obj):
-        raise TypeError(f"{self} cannot be used with isinstance()")
-
-    def __subclasscheck__(self, cls):
-        raise TypeError(f"{self} cannot be used with issubclass()")
-
-    @typing._tp_cache
-    def __getitem__(self, parameters):
-        return self._getitem(self, parameters)
-
-
-# Note that inheriting from this class means that the object will be
-# rejected by typing._type_check, so do not use it if the special form
-# is arguably valid as a type by itself.
-class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
-    def __repr__(self):
-        return 'typing_extensions.' + self._name
-
-
-Final = typing.Final
-
-# Breakpoint: https://github.com/python/cpython/pull/30530
-if sys.version_info >= (3, 11):
-    final = typing.final
-else:
-    # @final exists in 3.8+, but we backport it for all versions
-    # before 3.11 to keep support for the __final__ attribute.
-    # See https://bugs.python.org/issue46342
-    def final(f):
-        """This decorator can be used to indicate to type checkers that
-        the decorated method cannot be overridden, and decorated class
-        cannot be subclassed. For example:
-
-            class Base:
-                @final
-                def done(self) -> None:
-                    ...
-            class Sub(Base):
-                def done(self) -> None:  # Error reported by type checker
-                    ...
-            @final
-            class Leaf:
-                ...
-            class Other(Leaf):  # Error reported by type checker
-                ...
-
-        There is no runtime checking of these properties. The decorator
-        sets the ``__final__`` attribute to ``True`` on the decorated object
-        to allow runtime introspection.
-        """
-        try:
-            f.__final__ = True
-        except (AttributeError, TypeError):
-            # Skip the attribute silently if it is not writable.
-            # AttributeError happens if the object has __slots__ or a
-            # read-only property, TypeError if it's a builtin class.
-            pass
-        return f
-
-
-if hasattr(typing, "disjoint_base"):  # 3.15
-    disjoint_base = typing.disjoint_base
-else:
-    def disjoint_base(cls):
-        """This decorator marks a class as a disjoint base.
-
-        Child classes of a disjoint base cannot inherit from other disjoint bases that are
-        not parent classes of the disjoint base.
-
-        For example:
-
-            @disjoint_base
-            class Disjoint1: pass
-
-            @disjoint_base
-            class Disjoint2: pass
-
-            class Disjoint3(Disjoint1, Disjoint2): pass  # Type checker error
-
-        Type checkers can use knowledge of disjoint bases to detect unreachable code
-        and determine when two types can overlap.
-
-        See PEP 800."""
-        cls.__disjoint_base__ = True
-        return cls
-
-
-def IntVar(name):
-    return typing.TypeVar(name)
-
-
-# A Literal bug was fixed in 3.11.0, 3.10.1 and 3.9.8
-# Breakpoint: https://github.com/python/cpython/pull/29334
-if sys.version_info >= (3, 10, 1):
-    Literal = typing.Literal
-else:
-    def _flatten_literal_params(parameters):
-        """An internal helper for Literal creation: flatten Literals among parameters"""
-        params = []
-        for p in parameters:
-            if isinstance(p, _LiteralGenericAlias):
-                params.extend(p.__args__)
-            else:
-                params.append(p)
-        return tuple(params)
-
-    def _value_and_type_iter(params):
-        for p in params:
-            yield p, type(p)
-
-    class _LiteralGenericAlias(typing._GenericAlias, _root=True):
-        def __eq__(self, other):
-            if not isinstance(other, _LiteralGenericAlias):
-                return NotImplemented
-            these_args_deduped = set(_value_and_type_iter(self.__args__))
-            other_args_deduped = set(_value_and_type_iter(other.__args__))
-            return these_args_deduped == other_args_deduped
-
-        def __hash__(self):
-            return hash(frozenset(_value_and_type_iter(self.__args__)))
-
-    class _LiteralForm(_ExtensionsSpecialForm, _root=True):
-        def __init__(self, doc: str):
-            self._name = 'Literal'
-            self._doc = self.__doc__ = doc
-
-        def __getitem__(self, parameters):
-            if not isinstance(parameters, tuple):
-                parameters = (parameters,)
-
-            parameters = _flatten_literal_params(parameters)
-
-            val_type_pairs = list(_value_and_type_iter(parameters))
-            try:
-                deduped_pairs = set(val_type_pairs)
-            except TypeError:
-                # unhashable parameters
-                pass
-            else:
-                # similar logic to typing._deduplicate on Python 3.9+
-                if len(deduped_pairs) < len(val_type_pairs):
-                    new_parameters = []
-                    for pair in val_type_pairs:
-                        if pair in deduped_pairs:
-                            new_parameters.append(pair[0])
-                            deduped_pairs.remove(pair)
-                    assert not deduped_pairs, deduped_pairs
-                    parameters = tuple(new_parameters)
-
-            return _LiteralGenericAlias(self, parameters)
-
-    Literal = _LiteralForm(doc="""\
-                           A type that can be used to indicate to type checkers
-                           that the corresponding value has a value literally equivalent
-                           to the provided parameter. For example:
-
-                               var: Literal[4] = 4
-
-                           The type checker understands that 'var' is literally equal to
-                           the value 4 and no other value.
-
-                           Literal[...] cannot be subclassed. There is no runtime
-                           checking verifying that the parameter is actually a value
-                           instead of a type.""")
-
-
-_overload_dummy = typing._overload_dummy
-
-
-if hasattr(typing, "get_overloads"):  # 3.11+
-    overload = typing.overload
-    get_overloads = typing.get_overloads
-    clear_overloads = typing.clear_overloads
-else:
-    # {module: {qualname: {firstlineno: func}}}
-    _overload_registry = collections.defaultdict(
-        functools.partial(collections.defaultdict, dict)
-    )
-
-    def overload(func):
-        """Decorator for overloaded functions/methods.
-
-        In a stub file, place two or more stub definitions for the same
-        function in a row, each decorated with @overload.  For example:
-
-        @overload
-        def utf8(value: None) -> None: ...
-        @overload
-        def utf8(value: bytes) -> bytes: ...
-        @overload
-        def utf8(value: str) -> bytes: ...
-
-        In a non-stub file (i.e. a regular .py file), do the same but
-        follow it with an implementation.  The implementation should *not*
-        be decorated with @overload.  For example:
-
-        @overload
-        def utf8(value: None) -> None: ...
-        @overload
-        def utf8(value: bytes) -> bytes: ...
-        @overload
-        def utf8(value: str) -> bytes: ...
-        def utf8(value):
-            # implementation goes here
-
-        The overloads for a function can be retrieved at runtime using the
-        get_overloads() function.
-        """
-        # classmethod and staticmethod
-        f = getattr(func, "__func__", func)
-        try:
-            _overload_registry[f.__module__][f.__qualname__][
-                f.__code__.co_firstlineno
-            ] = func
-        except AttributeError:
-            # Not a normal function; ignore.
-            pass
-        return _overload_dummy
-
-    def get_overloads(func):
-        """Return all defined overloads for *func* as a sequence."""
-        # classmethod and staticmethod
-        f = getattr(func, "__func__", func)
-        if f.__module__ not in _overload_registry:
-            return []
-        mod_dict = _overload_registry[f.__module__]
-        if f.__qualname__ not in mod_dict:
-            return []
-        return list(mod_dict[f.__qualname__].values())
-
-    def clear_overloads():
-        """Clear all overloads in the registry."""
-        _overload_registry.clear()
-
-
-# This is not a real generic class.  Don't use outside annotations.
-Type = typing.Type
-
-# Various ABCs mimicking those in collections.abc.
-# A few are simply re-exported for completeness.
-Awaitable = typing.Awaitable
-Coroutine = typing.Coroutine
-AsyncIterable = typing.AsyncIterable
-AsyncIterator = typing.AsyncIterator
-Deque = typing.Deque
-DefaultDict = typing.DefaultDict
-OrderedDict = typing.OrderedDict
-Counter = typing.Counter
-ChainMap = typing.ChainMap
-Text = typing.Text
-TYPE_CHECKING = typing.TYPE_CHECKING
-
-
-# Breakpoint: https://github.com/python/cpython/pull/118681
-if sys.version_info >= (3, 13, 0, "beta"):
-    from typing import AsyncContextManager, AsyncGenerator, ContextManager, Generator
-else:
-    def _is_dunder(attr):
-        return attr.startswith('__') and attr.endswith('__')
-
-
-    class _SpecialGenericAlias(typing._SpecialGenericAlias, _root=True):
-        def __init__(self, origin, nparams, *, defaults, inst=True, name=None):
-            assert nparams > 0, "`nparams` must be a positive integer"
-            assert defaults, "Must always specify a non-empty sequence for `defaults`"
-            super().__init__(origin, nparams, inst=inst, name=name)
-            self._defaults = defaults
-
-        def __setattr__(self, attr, val):
-            allowed_attrs = {'_name', '_inst', '_nparams', '_defaults'}
-            if _is_dunder(attr) or attr in allowed_attrs:
-                object.__setattr__(self, attr, val)
-            else:
-                setattr(self.__origin__, attr, val)
-
-        @typing._tp_cache
-        def __getitem__(self, params):
-            if not isinstance(params, tuple):
-                params = (params,)
-            msg = "Parameters to generic types must be types."
-            params = tuple(typing._type_check(p, msg) for p in params)
-            if (
-                len(params) < self._nparams
-                and len(params) + len(self._defaults) >= self._nparams
-            ):
-                params = (*params, *self._defaults[len(params) - self._nparams:])
-            actual_len = len(params)
-
-            if actual_len != self._nparams:
-                expected = f"at least {self._nparams - len(self._defaults)}"
-                raise TypeError(
-                    f"Too {'many' if actual_len > self._nparams else 'few'}"
-                    f" arguments for {self};"
-                    f" actual {actual_len}, expected {expected}"
-                )
-            return self.copy_with(params)
-
-    _NoneType = type(None)
-    Generator = _SpecialGenericAlias(
-        collections.abc.Generator, 3, defaults=(_NoneType, _NoneType)
-    )
-    AsyncGenerator = _SpecialGenericAlias(
-        collections.abc.AsyncGenerator, 2, defaults=(_NoneType,)
-    )
-    ContextManager = _SpecialGenericAlias(
-        contextlib.AbstractContextManager,
-        2,
-        name="ContextManager",
-        defaults=(typing.Optional[bool],)
-    )
-    AsyncContextManager = _SpecialGenericAlias(
-        contextlib.AbstractAsyncContextManager,
-        2,
-        name="AsyncContextManager",
-        defaults=(typing.Optional[bool],)
-    )
-
-
-_PROTO_ALLOWLIST = {
-    'collections.abc': [
-        'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable',
-        'AsyncIterator', 'Hashable', 'Sized', 'Container', 'Collection',
-        'Reversible', 'Buffer',
-    ],
-    'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'],
-    'io': ['Reader', 'Writer'],
-    'typing_extensions': ['Buffer'],
-    'os': ['PathLike'],
-}
-
-
-_EXCLUDED_ATTRS = frozenset(typing.EXCLUDED_ATTRIBUTES) | {
-    "__match_args__", "__protocol_attrs__", "__non_callable_proto_members__",
-    "__final__",
-}
-
-
-def _get_protocol_attrs(cls):
-    attrs = set()
-    for base in cls.__mro__[:-1]:  # without object
-        if base.__name__ in {'Protocol', 'Generic'}:
-            continue
-        annotations = getattr(base, '__annotations__', {})
-        for attr in (*base.__dict__, *annotations):
-            if (not attr.startswith('_abc_') and attr not in _EXCLUDED_ATTRS):
-                attrs.add(attr)
-    return attrs
-
-
-# `__match_args__` attribute was removed from protocol members in 3.13,
-# we want to backport this change to older Python versions.
-# 3.14 additionally added `io.Reader`, `io.Writer` and `os.PathLike` to
-# the list of allowed protocol allowlist.
-# https://github.com/python/cpython/issues/127647
-if sys.version_info >= (3, 14):
-    Protocol = typing.Protocol
-else:
-    def _allow_reckless_class_checks(depth=2):
-        """Allow instance and class checks for special stdlib modules.
-        The abc and functools modules indiscriminately call isinstance() and
-        issubclass() on the whole MRO of a user class, which may contain protocols.
-        """
-        return _caller(depth) in {'abc', 'functools', None}
-
-    def _no_init(self, *args, **kwargs):
-        if type(self)._is_protocol:
-            raise TypeError('Protocols cannot be instantiated')
-
-    def _type_check_issubclass_arg_1(arg):
-        """Raise TypeError if `arg` is not an instance of `type`
-        in `issubclass(arg, )`.
-
-        In most cases, this is verified by type.__subclasscheck__.
-        Checking it again unnecessarily would slow down issubclass() checks,
-        so, we don't perform this check unless we absolutely have to.
-
-        For various error paths, however,
-        we want to ensure that *this* error message is shown to the user
-        where relevant, rather than a typing.py-specific error message.
-        """
-        if not isinstance(arg, type):
-            # Same error message as for issubclass(1, int).
-            raise TypeError('issubclass() arg 1 must be a class')
-
-    # Inheriting from typing._ProtocolMeta isn't actually desirable,
-    # but is necessary to allow typing.Protocol and typing_extensions.Protocol
-    # to mix without getting TypeErrors about "metaclass conflict"
-    class _ProtocolMeta(type(typing.Protocol)):
-        # This metaclass is somewhat unfortunate,
-        # but is necessary for several reasons...
-        #
-        # NOTE: DO NOT call super() in any methods in this class
-        # That would call the methods on typing._ProtocolMeta on Python <=3.11
-        # and those are slow
-        def __new__(mcls, name, bases, namespace, **kwargs):
-            if name == "Protocol" and len(bases) < 2:
-                pass
-            elif {Protocol, typing.Protocol} & set(bases):
-                for base in bases:
-                    if not (
-                        base in {object, typing.Generic, Protocol, typing.Protocol}
-                        or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, [])
-                        or is_protocol(base)
-                    ):
-                        raise TypeError(
-                            f"Protocols can only inherit from other protocols, "
-                            f"got {base!r}"
-                        )
-            return abc.ABCMeta.__new__(mcls, name, bases, namespace, **kwargs)
-
-        def __init__(cls, *args, **kwargs):
-            abc.ABCMeta.__init__(cls, *args, **kwargs)
-            if getattr(cls, "_is_protocol", False):
-                cls.__protocol_attrs__ = _get_protocol_attrs(cls)
-
-        def __subclasscheck__(cls, other):
-            if cls is Protocol:
-                return type.__subclasscheck__(cls, other)
-            if (
-                getattr(cls, '_is_protocol', False)
-                and not _allow_reckless_class_checks()
-            ):
-                if not getattr(cls, '_is_runtime_protocol', False):
-                    _type_check_issubclass_arg_1(other)
-                    raise TypeError(
-                        "Instance and class checks can only be used with "
-                        "@runtime_checkable protocols"
-                    )
-                if (
-                    # this attribute is set by @runtime_checkable:
-                    cls.__non_callable_proto_members__
-                    and cls.__dict__.get("__subclasshook__") is _proto_hook
-                ):
-                    _type_check_issubclass_arg_1(other)
-                    non_method_attrs = sorted(cls.__non_callable_proto_members__)
-                    raise TypeError(
-                        "Protocols with non-method members don't support issubclass()."
-                        f" Non-method members: {str(non_method_attrs)[1:-1]}."
-                    )
-            return abc.ABCMeta.__subclasscheck__(cls, other)
-
-        def __instancecheck__(cls, instance):
-            # We need this method for situations where attributes are
-            # assigned in __init__.
-            if cls is Protocol:
-                return type.__instancecheck__(cls, instance)
-            if not getattr(cls, "_is_protocol", False):
-                # i.e., it's a concrete subclass of a protocol
-                return abc.ABCMeta.__instancecheck__(cls, instance)
-
-            if (
-                not getattr(cls, '_is_runtime_protocol', False) and
-                not _allow_reckless_class_checks()
-            ):
-                raise TypeError("Instance and class checks can only be used with"
-                                " @runtime_checkable protocols")
-
-            if abc.ABCMeta.__instancecheck__(cls, instance):
-                return True
-
-            for attr in cls.__protocol_attrs__:
-                try:
-                    val = inspect.getattr_static(instance, attr)
-                except AttributeError:
-                    break
-                # this attribute is set by @runtime_checkable:
-                if val is None and attr not in cls.__non_callable_proto_members__:
-                    break
-            else:
-                return True
-
-            return False
-
-        def __eq__(cls, other):
-            # Hack so that typing.Generic.__class_getitem__
-            # treats typing_extensions.Protocol
-            # as equivalent to typing.Protocol
-            if abc.ABCMeta.__eq__(cls, other) is True:
-                return True
-            return cls is Protocol and other is typing.Protocol
-
-        # This has to be defined, or the abc-module cache
-        # complains about classes with this metaclass being unhashable,
-        # if we define only __eq__!
-        def __hash__(cls) -> int:
-            return type.__hash__(cls)
-
-    @classmethod
-    def _proto_hook(cls, other):
-        if not cls.__dict__.get('_is_protocol', False):
-            return NotImplemented
-
-        for attr in cls.__protocol_attrs__:
-            for base in other.__mro__:
-                # Check if the members appears in the class dictionary...
-                if attr in base.__dict__:
-                    if base.__dict__[attr] is None:
-                        return NotImplemented
-                    break
-
-                # ...or in annotations, if it is a sub-protocol.
-                annotations = getattr(base, '__annotations__', {})
-                if (
-                    isinstance(annotations, collections.abc.Mapping)
-                    and attr in annotations
-                    and is_protocol(other)
-                ):
-                    break
-            else:
-                return NotImplemented
-        return True
-
-    class Protocol(typing.Generic, metaclass=_ProtocolMeta):
-        __doc__ = typing.Protocol.__doc__
-        __slots__ = ()
-        _is_protocol = True
-        _is_runtime_protocol = False
-
-        def __init_subclass__(cls, *args, **kwargs):
-            super().__init_subclass__(*args, **kwargs)
-
-            # Determine if this is a protocol or a concrete subclass.
-            if not cls.__dict__.get('_is_protocol', False):
-                cls._is_protocol = any(b is Protocol for b in cls.__bases__)
-
-            # Set (or override) the protocol subclass hook.
-            if '__subclasshook__' not in cls.__dict__:
-                cls.__subclasshook__ = _proto_hook
-
-            # Prohibit instantiation for protocol classes
-            if cls._is_protocol and cls.__init__ is Protocol.__init__:
-                cls.__init__ = _no_init
-
-
-# Breakpoint: https://github.com/python/cpython/pull/113401
-if sys.version_info >= (3, 13):
-    runtime_checkable = typing.runtime_checkable
-else:
-    def runtime_checkable(cls):
-        """Mark a protocol class as a runtime protocol.
-
-        Such protocol can be used with isinstance() and issubclass().
-        Raise TypeError if applied to a non-protocol class.
-        This allows a simple-minded structural check very similar to
-        one trick ponies in collections.abc such as Iterable.
-
-        For example::
-
-            @runtime_checkable
-            class Closable(Protocol):
-                def close(self): ...
-
-            assert isinstance(open('/some/file'), Closable)
-
-        Warning: this will check only the presence of the required methods,
-        not their type signatures!
-        """
-        if not issubclass(cls, typing.Generic) or not getattr(cls, '_is_protocol', False):
-            raise TypeError(f'@runtime_checkable can be only applied to protocol classes,'
-                            f' got {cls!r}')
-        cls._is_runtime_protocol = True
-
-        # typing.Protocol classes on <=3.11 break if we execute this block,
-        # because typing.Protocol classes on <=3.11 don't have a
-        # `__protocol_attrs__` attribute, and this block relies on the
-        # `__protocol_attrs__` attribute. Meanwhile, typing.Protocol classes on 3.12.2+
-        # break if we *don't* execute this block, because *they* assume that all
-        # protocol classes have a `__non_callable_proto_members__` attribute
-        # (which this block sets)
-        if isinstance(cls, _ProtocolMeta) or sys.version_info >= (3, 12, 2):
-            # PEP 544 prohibits using issubclass()
-            # with protocols that have non-method members.
-            # See gh-113320 for why we compute this attribute here,
-            # rather than in `_ProtocolMeta.__init__`
-            cls.__non_callable_proto_members__ = set()
-            for attr in cls.__protocol_attrs__:
-                try:
-                    is_callable = callable(getattr(cls, attr, None))
-                except Exception as e:
-                    raise TypeError(
-                        f"Failed to determine whether protocol member {attr!r} "
-                        "is a method member"
-                    ) from e
-                else:
-                    if not is_callable:
-                        cls.__non_callable_proto_members__.add(attr)
-
-        return cls
-
-
-# The "runtime" alias exists for backwards compatibility.
-runtime = runtime_checkable
-
-
-# Our version of runtime-checkable protocols is faster on Python <=3.11
-# Breakpoint: https://github.com/python/cpython/pull/112717
-if sys.version_info >= (3, 12):
-    SupportsInt = typing.SupportsInt
-    SupportsFloat = typing.SupportsFloat
-    SupportsComplex = typing.SupportsComplex
-    SupportsBytes = typing.SupportsBytes
-    SupportsIndex = typing.SupportsIndex
-    SupportsAbs = typing.SupportsAbs
-    SupportsRound = typing.SupportsRound
-else:
-    @runtime_checkable
-    class SupportsInt(Protocol):
-        """An ABC with one abstract method __int__."""
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def __int__(self) -> int:
-            pass
-
-    @runtime_checkable
-    class SupportsFloat(Protocol):
-        """An ABC with one abstract method __float__."""
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def __float__(self) -> float:
-            pass
-
-    @runtime_checkable
-    class SupportsComplex(Protocol):
-        """An ABC with one abstract method __complex__."""
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def __complex__(self) -> complex:
-            pass
-
-    @runtime_checkable
-    class SupportsBytes(Protocol):
-        """An ABC with one abstract method __bytes__."""
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def __bytes__(self) -> bytes:
-            pass
-
-    @runtime_checkable
-    class SupportsIndex(Protocol):
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def __index__(self) -> int:
-            pass
-
-    @runtime_checkable
-    class SupportsAbs(Protocol[T_co]):
-        """
-        An ABC with one abstract method __abs__ that is covariant in its return type.
-        """
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def __abs__(self) -> T_co:
-            pass
-
-    @runtime_checkable
-    class SupportsRound(Protocol[T_co]):
-        """
-        An ABC with one abstract method __round__ that is covariant in its return type.
-        """
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def __round__(self, ndigits: int = 0) -> T_co:
-            pass
-
-
-if hasattr(io, "Reader") and hasattr(io, "Writer"):
-    Reader = io.Reader
-    Writer = io.Writer
-else:
-    @runtime_checkable
-    class Reader(Protocol[T_co]):
-        """Protocol for simple I/O reader instances.
-
-        This protocol only supports blocking I/O.
-        """
-
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def read(self, size: int = ..., /) -> T_co:
-            """Read data from the input stream and return it.
-
-            If *size* is specified, at most *size* items (bytes/characters) will be
-            read.
-            """
-
-    @runtime_checkable
-    class Writer(Protocol[T_contra]):
-        """Protocol for simple I/O writer instances.
-
-        This protocol only supports blocking I/O.
-        """
-
-        __slots__ = ()
-
-        @abc.abstractmethod
-        def write(self, data: T_contra, /) -> int:
-            """Write *data* to the output stream and return the number of items written."""  # noqa: E501
-
-
-_NEEDS_SINGLETONMETA = (
-    not hasattr(typing, "NoDefault") or not hasattr(typing, "NoExtraItems")
-)
-
-if _NEEDS_SINGLETONMETA:
-    class SingletonMeta(type):
-        def __setattr__(cls, attr, value):
-            # TypeError is consistent with the behavior of NoneType
-            raise TypeError(
-                f"cannot set {attr!r} attribute of immutable type {cls.__name__!r}"
-            )
-
-
-if hasattr(typing, "NoDefault"):
-    NoDefault = typing.NoDefault
-else:
-    class NoDefaultType(metaclass=SingletonMeta):
-        """The type of the NoDefault singleton."""
-
-        __slots__ = ()
-
-        def __new__(cls):
-            return globals().get("NoDefault") or object.__new__(cls)
-
-        def __repr__(self):
-            return "typing_extensions.NoDefault"
-
-        def __reduce__(self):
-            return "NoDefault"
-
-    NoDefault = NoDefaultType()
-    del NoDefaultType
-
-if hasattr(typing, "NoExtraItems"):
-    NoExtraItems = typing.NoExtraItems
-else:
-    class NoExtraItemsType(metaclass=SingletonMeta):
-        """The type of the NoExtraItems singleton."""
-
-        __slots__ = ()
-
-        def __new__(cls):
-            return globals().get("NoExtraItems") or object.__new__(cls)
-
-        def __repr__(self):
-            return "typing_extensions.NoExtraItems"
-
-        def __reduce__(self):
-            return "NoExtraItems"
-
-    NoExtraItems = NoExtraItemsType()
-    del NoExtraItemsType
-
-if _NEEDS_SINGLETONMETA:
-    del SingletonMeta
-
-
-# Update this to something like >=3.13.0b1 if and when
-# PEP 764 is implemented in CPython
-_PEP_764_IMPLEMENTED = False
-
-if _PEP_764_IMPLEMENTED:
-    # The standard library TypedDict in Python 3.9.0/1 does not honour the "total"
-    # keyword with old-style TypedDict().  See https://bugs.python.org/issue42059
-    # The standard library TypedDict below Python 3.11 does not store runtime
-    # information about optional and required keys when using Required or NotRequired.
-    # Generic TypedDicts are also impossible using typing.TypedDict on Python <3.11.
-    # Aaaand on 3.12 we add __orig_bases__ to TypedDict
-    # to enable better runtime introspection.
-    # On 3.13 we deprecate some odd ways of creating TypedDicts.
-    # Also on 3.13, PEP 705 adds the ReadOnly[] qualifier.
-    # PEP 728 (Python 3.15+) adds the `extra_items` and `closed` keywords.
-    # PEP 764 (still pending) allows the `TypedDict` special form to be subscripted.
-    TypedDict = typing.TypedDict
-    _TypedDictMeta = typing._TypedDictMeta
-    is_typeddict = typing.is_typeddict
-else:
-    # 3.10.0 and later
-    _TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters
-
-    def _get_typeddict_qualifiers(annotation_type):
-        while True:
-            annotation_origin = get_origin(annotation_type)
-            if annotation_origin is Annotated:
-                annotation_args = get_args(annotation_type)
-                if annotation_args:
-                    annotation_type = annotation_args[0]
-                else:
-                    break
-            elif annotation_origin is Required:
-                yield Required
-                annotation_type, = get_args(annotation_type)
-            elif annotation_origin is NotRequired:
-                yield NotRequired
-                annotation_type, = get_args(annotation_type)
-            elif annotation_origin is ReadOnly:
-                yield ReadOnly
-                annotation_type, = get_args(annotation_type)
-            else:
-                break
-
-    class _TypedDictMeta(type):
-
-        def __new__(cls, name, bases, ns, *, total=True, closed=None,
-                    extra_items=NoExtraItems):
-            """Create new typed dict class object.
-
-            This method is called when TypedDict is subclassed,
-            or when TypedDict is instantiated. This way
-            TypedDict supports all three syntax forms described in its docstring.
-            Subclasses and instances of TypedDict return actual dictionaries.
-            """
-            for base in bases:
-                if type(base) is not _TypedDictMeta and base is not typing.Generic:
-                    raise TypeError('cannot inherit from both a TypedDict type '
-                                    'and a non-TypedDict base class')
-            if closed is not None and extra_items is not NoExtraItems:
-                raise TypeError(f"Cannot combine closed={closed!r} and extra_items")
-
-            if any(issubclass(b, typing.Generic) for b in bases):
-                generic_base = (typing.Generic,)
-            else:
-                generic_base = ()
-
-            ns_annotations = ns.pop('__annotations__', None)
-
-            # typing.py generally doesn't let you inherit from plain Generic, unless
-            # the name of the class happens to be "Protocol"
-            tp_dict = type.__new__(_TypedDictMeta, "Protocol", (*generic_base, dict), ns)
-            tp_dict.__name__ = name
-            if tp_dict.__qualname__ == "Protocol":
-                tp_dict.__qualname__ = name
-
-            if not hasattr(tp_dict, '__orig_bases__'):
-                tp_dict.__orig_bases__ = bases
-
-            annotations = {}
-            own_annotate = None
-            if ns_annotations is not None:
-                own_annotations = ns_annotations
-            elif sys.version_info >= (3, 14):
-                if hasattr(annotationlib, "get_annotate_from_class_namespace"):
-                    own_annotate = annotationlib.get_annotate_from_class_namespace(ns)
-                else:
-                    # 3.14.0a7 and earlier
-                    own_annotate = ns.get("__annotate__")
-                if own_annotate is not None:
-                    own_annotations = annotationlib.call_annotate_function(
-                        own_annotate, Format.FORWARDREF, owner=tp_dict
-                    )
-                else:
-                    own_annotations = {}
-            else:
-                own_annotations = {}
-            msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
-            if _TAKES_MODULE:
-                own_checked_annotations = {
-                    n: typing._type_check(tp, msg, module=tp_dict.__module__)
-                    for n, tp in own_annotations.items()
-                }
-            else:
-                own_checked_annotations = {
-                    n: typing._type_check(tp, msg)
-                    for n, tp in own_annotations.items()
-                }
-            required_keys = set()
-            optional_keys = set()
-            readonly_keys = set()
-            mutable_keys = set()
-            extra_items_type = extra_items
-
-            for base in bases:
-                base_dict = base.__dict__
-
-                if sys.version_info <= (3, 14):
-                    annotations.update(base_dict.get('__annotations__', {}))
-                base_required = base_dict.get('__required_keys__', set())
-                required_keys |= base_required
-                optional_keys -= base_required
-
-                base_optional = base_dict.get('__optional_keys__', set())
-                required_keys -= base_optional
-                optional_keys |= base_optional
-
-                readonly_keys.update(base_dict.get('__readonly_keys__', ()))
-                mutable_keys.update(base_dict.get('__mutable_keys__', ()))
-
-            # This was specified in an earlier version of PEP 728. Support
-            # is retained for backwards compatibility, but only for Python
-            # 3.13 and lower.
-            if (closed and sys.version_info < (3, 14)
-                       and "__extra_items__" in own_checked_annotations):
-                annotation_type = own_checked_annotations.pop("__extra_items__")
-                qualifiers = set(_get_typeddict_qualifiers(annotation_type))
-                if Required in qualifiers:
-                    raise TypeError(
-                        "Special key __extra_items__ does not support "
-                        "Required"
-                    )
-                if NotRequired in qualifiers:
-                    raise TypeError(
-                        "Special key __extra_items__ does not support "
-                        "NotRequired"
-                    )
-                extra_items_type = annotation_type
-
-            annotations.update(own_checked_annotations)
-            for annotation_key, annotation_type in own_checked_annotations.items():
-                qualifiers = set(_get_typeddict_qualifiers(annotation_type))
-
-                if Required in qualifiers:
-                    is_required = True
-                elif NotRequired in qualifiers:
-                    is_required = False
-                else:
-                    is_required = total
-
-                if is_required:
-                    required_keys.add(annotation_key)
-                    optional_keys.discard(annotation_key)
-                else:
-                    optional_keys.add(annotation_key)
-                    required_keys.discard(annotation_key)
-
-                if ReadOnly in qualifiers:
-                    mutable_keys.discard(annotation_key)
-                    readonly_keys.add(annotation_key)
-                else:
-                    mutable_keys.add(annotation_key)
-                    readonly_keys.discard(annotation_key)
-
-            # Breakpoint: https://github.com/python/cpython/pull/119891
-            if sys.version_info >= (3, 14):
-                def __annotate__(format):
-                    annos = {}
-                    for base in bases:
-                        if base is Generic:
-                            continue
-                        base_annotate = base.__annotate__
-                        if base_annotate is None:
-                            continue
-                        base_annos = annotationlib.call_annotate_function(
-                            base_annotate, format, owner=base)
-                        annos.update(base_annos)
-                    if own_annotate is not None:
-                        own = annotationlib.call_annotate_function(
-                            own_annotate, format, owner=tp_dict)
-                        if format != Format.STRING:
-                            own = {
-                                n: typing._type_check(tp, msg, module=tp_dict.__module__)
-                                for n, tp in own.items()
-                            }
-                    elif format == Format.STRING:
-                        own = annotationlib.annotations_to_string(own_annotations)
-                    elif format in (Format.FORWARDREF, Format.VALUE):
-                        own = own_checked_annotations
-                    else:
-                        raise NotImplementedError(format)
-                    annos.update(own)
-                    return annos
-
-                tp_dict.__annotate__ = __annotate__
-            else:
-                tp_dict.__annotations__ = annotations
-            tp_dict.__required_keys__ = frozenset(required_keys)
-            tp_dict.__optional_keys__ = frozenset(optional_keys)
-            tp_dict.__readonly_keys__ = frozenset(readonly_keys)
-            tp_dict.__mutable_keys__ = frozenset(mutable_keys)
-            tp_dict.__total__ = total
-            tp_dict.__closed__ = closed
-            tp_dict.__extra_items__ = extra_items_type
-            return tp_dict
-
-        __call__ = dict  # static method
-
-        def __subclasscheck__(cls, other):
-            # Typed dicts are only for static structural subtyping.
-            raise TypeError('TypedDict does not support instance and class checks')
-
-        __instancecheck__ = __subclasscheck__
-
-    _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
-
-    def _create_typeddict(
-        typename,
-        fields,
-        /,
-        *,
-        typing_is_inline,
-        total,
-        closed,
-        extra_items,
-        **kwargs,
-    ):
-        if fields is _marker or fields is None:
-            if fields is _marker:
-                deprecated_thing = (
-                    "Failing to pass a value for the 'fields' parameter"
-                )
-            else:
-                deprecated_thing = "Passing `None` as the 'fields' parameter"
-
-            example = f"`{typename} = TypedDict({typename!r}, {{}})`"
-            deprecation_msg = (
-                f"{deprecated_thing} is deprecated and will be disallowed in "
-                "Python 3.15. To create a TypedDict class with 0 fields "
-                "using the functional syntax, pass an empty dictionary, e.g. "
-            ) + example + "."
-            warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2)
-            # Support a field called "closed"
-            if closed is not False and closed is not True and closed is not None:
-                kwargs["closed"] = closed
-                closed = None
-            # Or "extra_items"
-            if extra_items is not NoExtraItems:
-                kwargs["extra_items"] = extra_items
-                extra_items = NoExtraItems
-            fields = kwargs
-        elif kwargs:
-            raise TypeError("TypedDict takes either a dict or keyword arguments,"
-                            " but not both")
-        if kwargs:
-            # Breakpoint: https://github.com/python/cpython/pull/104891
-            if sys.version_info >= (3, 13):
-                raise TypeError("TypedDict takes no keyword arguments")
-            warnings.warn(
-                "The kwargs-based syntax for TypedDict definitions is deprecated "
-                "in Python 3.11, will be removed in Python 3.13, and may not be "
-                "understood by third-party type checkers.",
-                DeprecationWarning,
-                stacklevel=2,
-            )
-
-        ns = {'__annotations__': dict(fields)}
-        module = _caller(depth=4 if typing_is_inline else 2)
-        if module is not None:
-            # Setting correct module is necessary to make typed dict classes
-            # pickleable.
-            ns['__module__'] = module
-
-        td = _TypedDictMeta(typename, (), ns, total=total, closed=closed,
-                            extra_items=extra_items)
-        td.__orig_bases__ = (TypedDict,)
-        return td
-
-    class _TypedDictSpecialForm(_SpecialForm, _root=True):
-        def __call__(
-            self,
-            typename,
-            fields=_marker,
-            /,
-            *,
-            total=True,
-            closed=None,
-            extra_items=NoExtraItems,
-            **kwargs
-        ):
-            return _create_typeddict(
-                typename,
-                fields,
-                typing_is_inline=False,
-                total=total,
-                closed=closed,
-                extra_items=extra_items,
-                **kwargs,
-            )
-
-        def __mro_entries__(self, bases):
-            return (_TypedDict,)
-
-    @_TypedDictSpecialForm
-    def TypedDict(self, args):
-        """A simple typed namespace. At runtime it is equivalent to a plain dict.
-
-        TypedDict creates a dictionary type such that a type checker will expect all
-        instances to have a certain set of keys, where each key is
-        associated with a value of a consistent type. This expectation
-        is not checked at runtime.
-
-        Usage::
-
-            class Point2D(TypedDict):
-                x: int
-                y: int
-                label: str
-
-            a: Point2D = {'x': 1, 'y': 2, 'label': 'good'}  # OK
-            b: Point2D = {'z': 3, 'label': 'bad'}           # Fails type check
-
-            assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
-
-        The type info can be accessed via the Point2D.__annotations__ dict, and
-        the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets.
-        TypedDict supports an additional equivalent form::
-
-            Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
-
-        By default, all keys must be present in a TypedDict. It is possible
-        to override this by specifying totality::
-
-            class Point2D(TypedDict, total=False):
-                x: int
-                y: int
-
-        This means that a Point2D TypedDict can have any of the keys omitted. A type
-        checker is only expected to support a literal False or True as the value of
-        the total argument. True is the default, and makes all items defined in the
-        class body be required.
-
-        The Required and NotRequired special forms can also be used to mark
-        individual keys as being required or not required::
-
-            class Point2D(TypedDict):
-                x: int  # the "x" key must always be present (Required is the default)
-                y: NotRequired[int]  # the "y" key can be omitted
-
-        See PEP 655 for more details on Required and NotRequired.
-        """
-        # This runs when creating inline TypedDicts:
-        if not isinstance(args, dict):
-            raise TypeError(
-                "TypedDict[...] should be used with a single dict argument"
-            )
-
-        return _create_typeddict(
-            "",
-            args,
-            typing_is_inline=True,
-            total=True,
-            closed=True,
-            extra_items=NoExtraItems,
-        )
-
-    _TYPEDDICT_TYPES = (typing._TypedDictMeta, _TypedDictMeta)
-
-    def is_typeddict(tp):
-        """Check if an annotation is a TypedDict class
-
-        For example::
-            class Film(TypedDict):
-                title: str
-                year: int
-
-            is_typeddict(Film)  # => True
-            is_typeddict(Union[list, str])  # => False
-        """
-        return isinstance(tp, _TYPEDDICT_TYPES)
-
-
-if hasattr(typing, "assert_type"):
-    assert_type = typing.assert_type
-
-else:
-    def assert_type(val, typ, /):
-        """Assert (to the type checker) that the value is of the given type.
-
-        When the type checker encounters a call to assert_type(), it
-        emits an error if the value is not of the specified type::
-
-            def greet(name: str) -> None:
-                assert_type(name, str)  # ok
-                assert_type(name, int)  # type checker error
-
-        At runtime this returns the first argument unchanged and otherwise
-        does nothing.
-        """
-        return val
-
-
-if hasattr(typing, "ReadOnly"):  # 3.13+
-    get_type_hints = typing.get_type_hints
-else:  # <=3.13
-    # replaces _strip_annotations()
-    def _strip_extras(t):
-        """Strips Annotated, Required and NotRequired from a given type."""
-        if isinstance(t, typing._AnnotatedAlias):
-            return _strip_extras(t.__origin__)
-        if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired, ReadOnly):
-            return _strip_extras(t.__args__[0])
-        if isinstance(t, typing._GenericAlias):
-            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
-            if stripped_args == t.__args__:
-                return t
-            return t.copy_with(stripped_args)
-        if hasattr(_types, "GenericAlias") and isinstance(t, _types.GenericAlias):
-            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
-            if stripped_args == t.__args__:
-                return t
-            return _types.GenericAlias(t.__origin__, stripped_args)
-        if hasattr(_types, "UnionType") and isinstance(t, _types.UnionType):
-            stripped_args = tuple(_strip_extras(a) for a in t.__args__)
-            if stripped_args == t.__args__:
-                return t
-            return functools.reduce(operator.or_, stripped_args)
-
-        return t
-
-    def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
-        """Return type hints for an object.
-
-        This is often the same as obj.__annotations__, but it handles
-        forward references encoded as string literals, adds Optional[t] if a
-        default value equal to None is set and recursively replaces all
-        'Annotated[T, ...]', 'Required[T]' or 'NotRequired[T]' with 'T'
-        (unless 'include_extras=True').
-
-        The argument may be a module, class, method, or function. The annotations
-        are returned as a dictionary. For classes, annotations include also
-        inherited members.
-
-        TypeError is raised if the argument is not of a type that can contain
-        annotations, and an empty dictionary is returned if no annotations are
-        present.
-
-        BEWARE -- the behavior of globalns and localns is counterintuitive
-        (unless you are familiar with how eval() and exec() work).  The
-        search order is locals first, then globals.
-
-        - If no dict arguments are passed, an attempt is made to use the
-          globals from obj (or the respective module's globals for classes),
-          and these are also used as the locals.  If the object does not appear
-          to have globals, an empty dictionary is used.
-
-        - If one dict argument is passed, it is used for both globals and
-          locals.
-
-        - If two dict arguments are passed, they specify globals and
-          locals, respectively.
-        """
-        hint = typing.get_type_hints(
-            obj, globalns=globalns, localns=localns, include_extras=True
-        )
-        # Breakpoint: https://github.com/python/cpython/pull/30304
-        if sys.version_info < (3, 11):
-            _clean_optional(obj, hint, globalns, localns)
-        if include_extras:
-            return hint
-        return {k: _strip_extras(t) for k, t in hint.items()}
-
-    _NoneType = type(None)
-
-    def _could_be_inserted_optional(t):
-        """detects Union[..., None] pattern"""
-        if not isinstance(t, typing._UnionGenericAlias):
-            return False
-        # Assume if last argument is not None they are user defined
-        if t.__args__[-1] is not _NoneType:
-            return False
-        return True
-
-    # < 3.11
-    def _clean_optional(obj, hints, globalns=None, localns=None):
-        # reverts injected Union[..., None] cases from typing.get_type_hints
-        # when a None default value is used.
-        # see https://github.com/python/typing_extensions/issues/310
-        if not hints or isinstance(obj, type):
-            return
-        defaults = typing._get_defaults(obj)  # avoid accessing __annotations___
-        if not defaults:
-            return
-        original_hints = obj.__annotations__
-        for name, value in hints.items():
-            # Not a Union[..., None] or replacement conditions not fullfilled
-            if (not _could_be_inserted_optional(value)
-                or name not in defaults
-                or defaults[name] is not None
-            ):
-                continue
-            original_value = original_hints[name]
-            # value=NoneType should have caused a skip above but check for safety
-            if original_value is None:
-                original_value = _NoneType
-            # Forward reference
-            if isinstance(original_value, str):
-                if globalns is None:
-                    if isinstance(obj, _types.ModuleType):
-                        globalns = obj.__dict__
-                    else:
-                        nsobj = obj
-                        # Find globalns for the unwrapped object.
-                        while hasattr(nsobj, '__wrapped__'):
-                            nsobj = nsobj.__wrapped__
-                        globalns = getattr(nsobj, '__globals__', {})
-                    if localns is None:
-                        localns = globalns
-                elif localns is None:
-                    localns = globalns
-
-                original_value = ForwardRef(
-                    original_value,
-                    is_argument=not isinstance(obj, _types.ModuleType)
-                )
-            original_evaluated = typing._eval_type(original_value, globalns, localns)
-            # Compare if values differ. Note that even if equal
-            # value might be cached by typing._tp_cache contrary to original_evaluated
-            if original_evaluated != value or (
-                # 3.10: ForwardRefs of UnionType might be turned into _UnionGenericAlias
-                hasattr(_types, "UnionType")
-                and isinstance(original_evaluated, _types.UnionType)
-                and not isinstance(value, _types.UnionType)
-            ):
-                hints[name] = original_evaluated
-
-# Python 3.9 has get_origin() and get_args() but those implementations don't support
-# ParamSpecArgs and ParamSpecKwargs, so only Python 3.10's versions will do.
-# Breakpoint: https://github.com/python/cpython/pull/25298
-if sys.version_info >= (3, 10):
-    get_origin = typing.get_origin
-    get_args = typing.get_args
-# 3.9
-else:
-    def get_origin(tp):
-        """Get the unsubscripted version of a type.
-
-        This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
-        and Annotated. Return None for unsupported types. Examples::
-
-            get_origin(Literal[42]) is Literal
-            get_origin(int) is None
-            get_origin(ClassVar[int]) is ClassVar
-            get_origin(Generic) is Generic
-            get_origin(Generic[T]) is Generic
-            get_origin(Union[T, int]) is Union
-            get_origin(List[Tuple[T, T]][int]) == list
-            get_origin(P.args) is P
-        """
-        if isinstance(tp, typing._AnnotatedAlias):
-            return Annotated
-        if isinstance(tp, (typing._BaseGenericAlias, _types.GenericAlias,
-                           ParamSpecArgs, ParamSpecKwargs)):
-            return tp.__origin__
-        if tp is typing.Generic:
-            return typing.Generic
-        return None
-
-    def get_args(tp):
-        """Get type arguments with all substitutions performed.
-
-        For unions, basic simplifications used by Union constructor are performed.
-        Examples::
-            get_args(Dict[str, int]) == (str, int)
-            get_args(int) == ()
-            get_args(Union[int, Union[T, int], str][int]) == (int, str)
-            get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
-            get_args(Callable[[], T][int]) == ([], int)
-        """
-        if isinstance(tp, typing._AnnotatedAlias):
-            return (tp.__origin__, *tp.__metadata__)
-        if isinstance(tp, (typing._GenericAlias, _types.GenericAlias)):
-            res = tp.__args__
-            if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis:
-                res = (list(res[:-1]), res[-1])
-            return res
-        return ()
-
-
-# 3.10+
-if hasattr(typing, 'TypeAlias'):
-    TypeAlias = typing.TypeAlias
-# 3.9
-else:
-    @_ExtensionsSpecialForm
-    def TypeAlias(self, parameters):
-        """Special marker indicating that an assignment should
-        be recognized as a proper type alias definition by type
-        checkers.
-
-        For example::
-
-            Predicate: TypeAlias = Callable[..., bool]
-
-        It's invalid when used anywhere except as in the example above.
-        """
-        raise TypeError(f"{self} is not subscriptable")
-
-
-def _set_default(type_param, default):
-    type_param.has_default = lambda: default is not NoDefault
-    type_param.__default__ = default
-
-
-def _set_module(typevarlike):
-    # for pickling:
-    def_mod = _caller(depth=2)
-    if def_mod != 'typing_extensions':
-        typevarlike.__module__ = def_mod
-
-
-class _DefaultMixin:
-    """Mixin for TypeVarLike defaults."""
-
-    __slots__ = ()
-    __init__ = _set_default
-
-
-# Classes using this metaclass must provide a _backported_typevarlike ClassVar
-class _TypeVarLikeMeta(type):
-    def __instancecheck__(cls, __instance: Any) -> bool:
-        return isinstance(__instance, cls._backported_typevarlike)
-
-
-if _PEP_696_IMPLEMENTED:
-    from typing import TypeVar
-else:
-    # Add default and infer_variance parameters from PEP 696 and 695
-    class TypeVar(metaclass=_TypeVarLikeMeta):
-        """Type variable."""
-
-        _backported_typevarlike = typing.TypeVar
-
-        def __new__(cls, name, *constraints, bound=None,
-                    covariant=False, contravariant=False,
-                    default=NoDefault, infer_variance=False):
-            if hasattr(typing, "TypeAliasType"):
-                # PEP 695 implemented (3.12+), can pass infer_variance to typing.TypeVar
-                typevar = typing.TypeVar(name, *constraints, bound=bound,
-                                         covariant=covariant, contravariant=contravariant,
-                                         infer_variance=infer_variance)
-            else:
-                typevar = typing.TypeVar(name, *constraints, bound=bound,
-                                         covariant=covariant, contravariant=contravariant)
-                if infer_variance and (covariant or contravariant):
-                    raise ValueError("Variance cannot be specified with infer_variance.")
-                typevar.__infer_variance__ = infer_variance
-
-            _set_default(typevar, default)
-            _set_module(typevar)
-
-            def _tvar_prepare_subst(alias, args):
-                if (
-                    typevar.has_default()
-                    and alias.__parameters__.index(typevar) == len(args)
-                ):
-                    args += (typevar.__default__,)
-                return args
-
-            typevar.__typing_prepare_subst__ = _tvar_prepare_subst
-            return typevar
-
-        def __init_subclass__(cls) -> None:
-            raise TypeError(f"type '{__name__}.TypeVar' is not an acceptable base type")
-
-
-# Python 3.10+ has PEP 612
-if hasattr(typing, 'ParamSpecArgs'):
-    ParamSpecArgs = typing.ParamSpecArgs
-    ParamSpecKwargs = typing.ParamSpecKwargs
-# 3.9
-else:
-    class _Immutable:
-        """Mixin to indicate that object should not be copied."""
-        __slots__ = ()
-
-        def __copy__(self):
-            return self
-
-        def __deepcopy__(self, memo):
-            return self
-
-    class ParamSpecArgs(_Immutable):
-        """The args for a ParamSpec object.
-
-        Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.
-
-        ParamSpecArgs objects have a reference back to their ParamSpec:
-
-        P.args.__origin__ is P
-
-        This type is meant for runtime introspection and has no special meaning to
-        static type checkers.
-        """
-        def __init__(self, origin):
-            self.__origin__ = origin
-
-        def __repr__(self):
-            return f"{self.__origin__.__name__}.args"
-
-        def __eq__(self, other):
-            if not isinstance(other, ParamSpecArgs):
-                return NotImplemented
-            return self.__origin__ == other.__origin__
-
-    class ParamSpecKwargs(_Immutable):
-        """The kwargs for a ParamSpec object.
-
-        Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.
-
-        ParamSpecKwargs objects have a reference back to their ParamSpec:
-
-        P.kwargs.__origin__ is P
-
-        This type is meant for runtime introspection and has no special meaning to
-        static type checkers.
-        """
-        def __init__(self, origin):
-            self.__origin__ = origin
-
-        def __repr__(self):
-            return f"{self.__origin__.__name__}.kwargs"
-
-        def __eq__(self, other):
-            if not isinstance(other, ParamSpecKwargs):
-                return NotImplemented
-            return self.__origin__ == other.__origin__
-
-
-if _PEP_696_IMPLEMENTED:
-    from typing import ParamSpec
-
-# 3.10+
-elif hasattr(typing, 'ParamSpec'):
-
-    # Add default parameter - PEP 696
-    class ParamSpec(metaclass=_TypeVarLikeMeta):
-        """Parameter specification."""
-
-        _backported_typevarlike = typing.ParamSpec
-
-        def __new__(cls, name, *, bound=None,
-                    covariant=False, contravariant=False,
-                    infer_variance=False, default=NoDefault):
-            if hasattr(typing, "TypeAliasType"):
-                # PEP 695 implemented, can pass infer_variance to typing.TypeVar
-                paramspec = typing.ParamSpec(name, bound=bound,
-                                             covariant=covariant,
-                                             contravariant=contravariant,
-                                             infer_variance=infer_variance)
-            else:
-                paramspec = typing.ParamSpec(name, bound=bound,
-                                             covariant=covariant,
-                                             contravariant=contravariant)
-                paramspec.__infer_variance__ = bool(infer_variance)
-
-            _set_default(paramspec, default)
-            _set_module(paramspec)
-
-            def _paramspec_prepare_subst(alias, args):
-                params = alias.__parameters__
-                i = params.index(paramspec)
-                if i == len(args) and paramspec.has_default():
-                    args = [*args, paramspec.__default__]
-                if i >= len(args):
-                    raise TypeError(f"Too few arguments for {alias}")
-                # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.
-                if len(params) == 1 and not typing._is_param_expr(args[0]):
-                    assert i == 0
-                    args = (args,)
-                # Convert lists to tuples to help other libraries cache the results.
-                elif isinstance(args[i], list):
-                    args = (*args[:i], tuple(args[i]), *args[i + 1:])
-                return args
-
-            paramspec.__typing_prepare_subst__ = _paramspec_prepare_subst
-            return paramspec
-
-        def __init_subclass__(cls) -> None:
-            raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type")
-
-# 3.9
-else:
-
-    # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
-    class ParamSpec(list, _DefaultMixin):
-        """Parameter specification variable.
-
-        Usage::
-
-           P = ParamSpec('P')
-
-        Parameter specification variables exist primarily for the benefit of static
-        type checkers.  They are used to forward the parameter types of one
-        callable to another callable, a pattern commonly found in higher order
-        functions and decorators.  They are only valid when used in ``Concatenate``,
-        or s the first argument to ``Callable``. In Python 3.10 and higher,
-        they are also supported in user-defined Generics at runtime.
-        See class Generic for more information on generic types.  An
-        example for annotating a decorator::
-
-           T = TypeVar('T')
-           P = ParamSpec('P')
-
-           def add_logging(f: Callable[P, T]) -> Callable[P, T]:
-               '''A type-safe decorator to add logging to a function.'''
-               def inner(*args: P.args, **kwargs: P.kwargs) -> T:
-                   logging.info(f'{f.__name__} was called')
-                   return f(*args, **kwargs)
-               return inner
-
-           @add_logging
-           def add_two(x: float, y: float) -> float:
-               '''Add two numbers together.'''
-               return x + y
-
-        Parameter specification variables defined with covariant=True or
-        contravariant=True can be used to declare covariant or contravariant
-        generic types.  These keyword arguments are valid, but their actual semantics
-        are yet to be decided.  See PEP 612 for details.
-
-        Parameter specification variables can be introspected. e.g.:
-
-           P.__name__ == 'T'
-           P.__bound__ == None
-           P.__covariant__ == False
-           P.__contravariant__ == False
-
-        Note that only parameter specification variables defined in global scope can
-        be pickled.
-        """
-
-        # Trick Generic __parameters__.
-        __class__ = typing.TypeVar
-
-        @property
-        def args(self):
-            return ParamSpecArgs(self)
-
-        @property
-        def kwargs(self):
-            return ParamSpecKwargs(self)
-
-        def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
-                     infer_variance=False, default=NoDefault):
-            list.__init__(self, [self])
-            self.__name__ = name
-            self.__covariant__ = bool(covariant)
-            self.__contravariant__ = bool(contravariant)
-            self.__infer_variance__ = bool(infer_variance)
-            self.__bound__ = bound
-            _DefaultMixin.__init__(self, default)
-
-            # for pickling:
-            def_mod = _caller()
-            if def_mod != 'typing_extensions':
-                self.__module__ = def_mod
-
-        def __repr__(self):
-            if self.__infer_variance__:
-                prefix = ''
-            elif self.__covariant__:
-                prefix = '+'
-            elif self.__contravariant__:
-                prefix = '-'
-            else:
-                prefix = '~'
-            return prefix + self.__name__
-
-        def __hash__(self):
-            return object.__hash__(self)
-
-        def __eq__(self, other):
-            return self is other
-
-        def __reduce__(self):
-            return self.__name__
-
-        # Hack to get typing._type_check to pass.
-        def __call__(self, *args, **kwargs):
-            pass
-
-        def __init_subclass__(cls) -> None:
-            raise TypeError(f"type '{__name__}.ParamSpec' is not an acceptable base type")
-
-
-# 3.9
-if not hasattr(typing, 'Concatenate'):
-    # Inherits from list as a workaround for Callable checks in Python < 3.9.2.
-
-    # 3.9.0-1
-    if not hasattr(typing, '_type_convert'):
-        def _type_convert(arg, module=None, *, allow_special_forms=False):
-            """For converting None to type(None), and strings to ForwardRef."""
-            if arg is None:
-                return type(None)
-            if isinstance(arg, str):
-                if sys.version_info <= (3, 9, 6):
-                    return ForwardRef(arg)
-                if sys.version_info <= (3, 9, 7):
-                    return ForwardRef(arg, module=module)
-                return ForwardRef(arg, module=module, is_class=allow_special_forms)
-            return arg
-    else:
-        _type_convert = typing._type_convert
-
-    class _ConcatenateGenericAlias(list):
-
-        # Trick Generic into looking into this for __parameters__.
-        __class__ = typing._GenericAlias
-
-        def __init__(self, origin, args):
-            # Cannot use `super().__init__` here because of the `__class__` assignment
-            # in the class body (https://github.com/python/typing_extensions/issues/661)
-            list.__init__(self, args)
-            self.__origin__ = origin
-            self.__args__ = args
-
-        def __repr__(self):
-            _type_repr = typing._type_repr
-            return (f'{_type_repr(self.__origin__)}'
-                    f'[{", ".join(_type_repr(arg) for arg in self.__args__)}]')
-
-        def __hash__(self):
-            return hash((self.__origin__, self.__args__))
-
-        # Hack to get typing._type_check to pass in Generic.
-        def __call__(self, *args, **kwargs):
-            pass
-
-        @property
-        def __parameters__(self):
-            return tuple(
-                tp for tp in self.__args__ if isinstance(tp, (typing.TypeVar, ParamSpec))
-            )
-
-        # 3.9 used by __getitem__ below
-        def copy_with(self, params):
-            if isinstance(params[-1], _ConcatenateGenericAlias):
-                params = (*params[:-1], *params[-1].__args__)
-            elif isinstance(params[-1], (list, tuple)):
-                return (*params[:-1], *params[-1])
-            elif (not (params[-1] is ... or isinstance(params[-1], ParamSpec))):
-                raise TypeError("The last parameter to Concatenate should be a "
-                        "ParamSpec variable or ellipsis.")
-            return self.__class__(self.__origin__, params)
-
-        # 3.9; accessed during GenericAlias.__getitem__ when substituting
-        def __getitem__(self, args):
-            if self.__origin__ in (Generic, Protocol):
-                # Can't subscript Generic[...] or Protocol[...].
-                raise TypeError(f"Cannot subscript already-subscripted {self}")
-            if not self.__parameters__:
-                raise TypeError(f"{self} is not a generic class")
-
-            if not isinstance(args, tuple):
-                args = (args,)
-            args = _unpack_args(*(_type_convert(p) for p in args))
-            params = self.__parameters__
-            for param in params:
-                prepare = getattr(param, "__typing_prepare_subst__", None)
-                if prepare is not None:
-                    args = prepare(self, args)
-                # 3.9 & typing.ParamSpec
-                elif isinstance(param, ParamSpec):
-                    i = params.index(param)
-                    if (
-                        i == len(args)
-                        and getattr(param, '__default__', NoDefault) is not NoDefault
-                    ):
-                        args = [*args, param.__default__]
-                    if i >= len(args):
-                        raise TypeError(f"Too few arguments for {self}")
-                    # Special case for Z[[int, str, bool]] == Z[int, str, bool]
-                    if len(params) == 1 and not _is_param_expr(args[0]):
-                        assert i == 0
-                        args = (args,)
-                    elif (
-                        isinstance(args[i], list)
-                        # 3.9
-                        # This class inherits from list do not convert
-                        and not isinstance(args[i], _ConcatenateGenericAlias)
-                    ):
-                        args = (*args[:i], tuple(args[i]), *args[i + 1:])
-
-            alen = len(args)
-            plen = len(params)
-            if alen != plen:
-                raise TypeError(
-                    f"Too {'many' if alen > plen else 'few'} arguments for {self};"
-                    f" actual {alen}, expected {plen}"
-                )
-
-            subst = dict(zip(self.__parameters__, args))
-            # determine new args
-            new_args = []
-            for arg in self.__args__:
-                if isinstance(arg, type):
-                    new_args.append(arg)
-                    continue
-                if isinstance(arg, TypeVar):
-                    arg = subst[arg]
-                    if (
-                        (isinstance(arg, typing._GenericAlias) and _is_unpack(arg))
-                        or (
-                            hasattr(_types, "GenericAlias")
-                            and isinstance(arg, _types.GenericAlias)
-                            and getattr(arg, "__unpacked__", False)
-                        )
-                    ):
-                        raise TypeError(f"{arg} is not valid as type argument")
-
-                elif isinstance(arg,
-                    typing._GenericAlias
-                    if not hasattr(_types, "GenericAlias") else
-                    (typing._GenericAlias, _types.GenericAlias)
-                ):
-                    subparams = arg.__parameters__
-                    if subparams:
-                        subargs = tuple(subst[x] for x in subparams)
-                        arg = arg[subargs]
-                new_args.append(arg)
-            return self.copy_with(tuple(new_args))
-
-# 3.10+
-else:
-    _ConcatenateGenericAlias = typing._ConcatenateGenericAlias
-
-    # 3.10
-    if sys.version_info < (3, 11):
-
-        class _ConcatenateGenericAlias(typing._ConcatenateGenericAlias, _root=True):
-            # needed for checks in collections.abc.Callable to accept this class
-            __module__ = "typing"
-
-            def copy_with(self, params):
-                if isinstance(params[-1], (list, tuple)):
-                    return (*params[:-1], *params[-1])
-                if isinstance(params[-1], typing._ConcatenateGenericAlias):
-                    params = (*params[:-1], *params[-1].__args__)
-                elif not (params[-1] is ... or isinstance(params[-1], ParamSpec)):
-                    raise TypeError("The last parameter to Concatenate should be a "
-                            "ParamSpec variable or ellipsis.")
-                return super(typing._ConcatenateGenericAlias, self).copy_with(params)
-
-            def __getitem__(self, args):
-                value = super().__getitem__(args)
-                if isinstance(value, tuple) and any(_is_unpack(t) for t in value):
-                    return tuple(_unpack_args(*(n for n in value)))
-                return value
-
-
-# 3.9.2
-class _EllipsisDummy: ...
-
-
-# <=3.10
-def _create_concatenate_alias(origin, parameters):
-    if parameters[-1] is ... and sys.version_info < (3, 9, 2):
-        # Hack: Arguments must be types, replace it with one.
-        parameters = (*parameters[:-1], _EllipsisDummy)
-    if sys.version_info >= (3, 10, 3):
-        concatenate = _ConcatenateGenericAlias(origin, parameters,
-                                        _typevar_types=(TypeVar, ParamSpec),
-                                        _paramspec_tvars=True)
-    else:
-        concatenate = _ConcatenateGenericAlias(origin, parameters)
-    if parameters[-1] is not _EllipsisDummy:
-        return concatenate
-    # Remove dummy again
-    concatenate.__args__ = tuple(p if p is not _EllipsisDummy else ...
-                                    for p in concatenate.__args__)
-    if sys.version_info < (3, 10):
-        # backport needs __args__ adjustment only
-        return concatenate
-    concatenate.__parameters__ = tuple(p for p in concatenate.__parameters__
-                                        if p is not _EllipsisDummy)
-    return concatenate
-
-
-# <=3.10
-@typing._tp_cache
-def _concatenate_getitem(self, parameters):
-    if parameters == ():
-        raise TypeError("Cannot take a Concatenate of no types.")
-    if not isinstance(parameters, tuple):
-        parameters = (parameters,)
-    if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)):
-        raise TypeError("The last parameter to Concatenate should be a "
-                        "ParamSpec variable or ellipsis.")
-    msg = "Concatenate[arg, ...]: each arg must be a type."
-    parameters = (*(typing._type_check(p, msg) for p in parameters[:-1]),
-                    parameters[-1])
-    return _create_concatenate_alias(self, parameters)
-
-
-# 3.11+; Concatenate does not accept ellipsis in 3.10
-# Breakpoint: https://github.com/python/cpython/pull/30969
-if sys.version_info >= (3, 11):
-    Concatenate = typing.Concatenate
-# <=3.10
-else:
-    @_ExtensionsSpecialForm
-    def Concatenate(self, parameters):
-        """Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a
-        higher order function which adds, removes or transforms parameters of a
-        callable.
-
-        For example::
-
-           Callable[Concatenate[int, P], int]
-
-        See PEP 612 for detailed information.
-        """
-        return _concatenate_getitem(self, parameters)
-
-
-# 3.10+
-if hasattr(typing, 'TypeGuard'):
-    TypeGuard = typing.TypeGuard
-# 3.9
-else:
-    @_ExtensionsSpecialForm
-    def TypeGuard(self, parameters):
-        """Special typing form used to annotate the return type of a user-defined
-        type guard function.  ``TypeGuard`` only accepts a single type argument.
-        At runtime, functions marked this way should return a boolean.
-
-        ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static
-        type checkers to determine a more precise type of an expression within a
-        program's code flow.  Usually type narrowing is done by analyzing
-        conditional code flow and applying the narrowing to a block of code.  The
-        conditional expression here is sometimes referred to as a "type guard".
-
-        Sometimes it would be convenient to use a user-defined boolean function
-        as a type guard.  Such a function should use ``TypeGuard[...]`` as its
-        return type to alert static type checkers to this intention.
-
-        Using  ``-> TypeGuard`` tells the static type checker that for a given
-        function:
-
-        1. The return value is a boolean.
-        2. If the return value is ``True``, the type of its argument
-        is the type inside ``TypeGuard``.
-
-        For example::
-
-            def is_str(val: Union[str, float]):
-                # "isinstance" type guard
-                if isinstance(val, str):
-                    # Type of ``val`` is narrowed to ``str``
-                    ...
-                else:
-                    # Else, type of ``val`` is narrowed to ``float``.
-                    ...
-
-        Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower
-        form of ``TypeA`` (it can even be a wider form) and this may lead to
-        type-unsafe results.  The main reason is to allow for things like
-        narrowing ``List[object]`` to ``List[str]`` even though the latter is not
-        a subtype of the former, since ``List`` is invariant.  The responsibility of
-        writing type-safe type guards is left to the user.
-
-        ``TypeGuard`` also works with type variables.  For more information, see
-        PEP 647 (User-Defined Type Guards).
-        """
-        item = typing._type_check(parameters, f'{self} accepts only a single type.')
-        return typing._GenericAlias(self, (item,))
-
-
-# 3.13+
-if hasattr(typing, 'TypeIs'):
-    TypeIs = typing.TypeIs
-# <=3.12
-else:
-    @_ExtensionsSpecialForm
-    def TypeIs(self, parameters):
-        """Special typing form used to annotate the return type of a user-defined
-        type narrower function.  ``TypeIs`` only accepts a single type argument.
-        At runtime, functions marked this way should return a boolean.
-
-        ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static
-        type checkers to determine a more precise type of an expression within a
-        program's code flow.  Usually type narrowing is done by analyzing
-        conditional code flow and applying the narrowing to a block of code.  The
-        conditional expression here is sometimes referred to as a "type guard".
-
-        Sometimes it would be convenient to use a user-defined boolean function
-        as a type guard.  Such a function should use ``TypeIs[...]`` as its
-        return type to alert static type checkers to this intention.
-
-        Using  ``-> TypeIs`` tells the static type checker that for a given
-        function:
-
-        1. The return value is a boolean.
-        2. If the return value is ``True``, the type of its argument
-        is the intersection of the type inside ``TypeIs`` and the argument's
-        previously known type.
-
-        For example::
-
-            def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]:
-                return hasattr(val, '__await__')
-
-            def f(val: Union[int, Awaitable[int]]) -> int:
-                if is_awaitable(val):
-                    assert_type(val, Awaitable[int])
-                else:
-                    assert_type(val, int)
-
-        ``TypeIs`` also works with type variables.  For more information, see
-        PEP 742 (Narrowing types with TypeIs).
-        """
-        item = typing._type_check(parameters, f'{self} accepts only a single type.')
-        return typing._GenericAlias(self, (item,))
-
-
-# 3.15+?
-if hasattr(typing, 'TypeForm'):
-    TypeForm = typing.TypeForm
-# <=3.14
-else:
-    class _TypeFormForm(_ExtensionsSpecialForm, _root=True):
-        # TypeForm(X) is equivalent to X but indicates to the type checker
-        # that the object is a TypeForm.
-        def __call__(self, obj, /):
-            return obj
-
-    @_TypeFormForm
-    def TypeForm(self, parameters):
-        """A special form representing the value that results from the evaluation
-        of a type expression. This value encodes the information supplied in the
-        type expression, and it represents the type described by that type expression.
-
-        When used in a type expression, TypeForm describes a set of type form objects.
-        It accepts a single type argument, which must be a valid type expression.
-        ``TypeForm[T]`` describes the set of all type form objects that represent
-        the type T or types that are assignable to T.
-
-        Usage:
-
-            def cast[T](typ: TypeForm[T], value: Any) -> T: ...
-
-            reveal_type(cast(int, "x"))  # int
-
-        See PEP 747 for more information.
-        """
-        item = typing._type_check(parameters, f'{self} accepts only a single type.')
-        return typing._GenericAlias(self, (item,))
-
-
-
-
-if hasattr(typing, "LiteralString"):  # 3.11+
-    LiteralString = typing.LiteralString
-else:
-    @_SpecialForm
-    def LiteralString(self, params):
-        """Represents an arbitrary literal string.
-
-        Example::
-
-          from typing_extensions import LiteralString
-
-          def query(sql: LiteralString) -> ...:
-              ...
-
-          query("SELECT * FROM table")  # ok
-          query(f"SELECT * FROM {input()}")  # not ok
-
-        See PEP 675 for details.
-
-        """
-        raise TypeError(f"{self} is not subscriptable")
-
-
-if hasattr(typing, "Self"):  # 3.11+
-    Self = typing.Self
-else:
-    @_SpecialForm
-    def Self(self, params):
-        """Used to spell the type of "self" in classes.
-
-        Example::
-
-          from typing import Self
-
-          class ReturnsSelf:
-              def parse(self, data: bytes) -> Self:
-                  ...
-                  return self
-
-        """
-
-        raise TypeError(f"{self} is not subscriptable")
-
-
-if hasattr(typing, "Never"):  # 3.11+
-    Never = typing.Never
-else:
-    @_SpecialForm
-    def Never(self, params):
-        """The bottom type, a type that has no members.
-
-        This can be used to define a function that should never be
-        called, or a function that never returns::
-
-            from typing_extensions import Never
-
-            def never_call_me(arg: Never) -> None:
-                pass
-
-            def int_or_str(arg: int | str) -> None:
-                never_call_me(arg)  # type checker error
-                match arg:
-                    case int():
-                        print("It's an int")
-                    case str():
-                        print("It's a str")
-                    case _:
-                        never_call_me(arg)  # ok, arg is of type Never
-
-        """
-
-        raise TypeError(f"{self} is not subscriptable")
-
-
-if hasattr(typing, 'Required'):  # 3.11+
-    Required = typing.Required
-    NotRequired = typing.NotRequired
-else:  # <=3.10
-    @_ExtensionsSpecialForm
-    def Required(self, parameters):
-        """A special typing construct to mark a key of a total=False TypedDict
-        as required. For example:
-
-            class Movie(TypedDict, total=False):
-                title: Required[str]
-                year: int
-
-            m = Movie(
-                title='The Matrix',  # typechecker error if key is omitted
-                year=1999,
-            )
-
-        There is no runtime checking that a required key is actually provided
-        when instantiating a related TypedDict.
-        """
-        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
-        return typing._GenericAlias(self, (item,))
-
-    @_ExtensionsSpecialForm
-    def NotRequired(self, parameters):
-        """A special typing construct to mark a key of a TypedDict as
-        potentially missing. For example:
-
-            class Movie(TypedDict):
-                title: str
-                year: NotRequired[int]
-
-            m = Movie(
-                title='The Matrix',  # typechecker error if key is omitted
-                year=1999,
-            )
-        """
-        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
-        return typing._GenericAlias(self, (item,))
-
-
-if hasattr(typing, 'ReadOnly'):
-    ReadOnly = typing.ReadOnly
-else:  # <=3.12
-    @_ExtensionsSpecialForm
-    def ReadOnly(self, parameters):
-        """A special typing construct to mark an item of a TypedDict as read-only.
-
-        For example:
-
-            class Movie(TypedDict):
-                title: ReadOnly[str]
-                year: int
-
-            def mutate_movie(m: Movie) -> None:
-                m["year"] = 1992  # allowed
-                m["title"] = "The Matrix"  # typechecker error
-
-        There is no runtime checking for this property.
-        """
-        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
-        return typing._GenericAlias(self, (item,))
-
-
-_UNPACK_DOC = """\
-Type unpack operator.
-
-The type unpack operator takes the child types from some container type,
-such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For
-example:
-
-  # For some generic class `Foo`:
-  Foo[Unpack[tuple[int, str]]]  # Equivalent to Foo[int, str]
-
-  Ts = TypeVarTuple('Ts')
-  # Specifies that `Bar` is generic in an arbitrary number of types.
-  # (Think of `Ts` as a tuple of an arbitrary number of individual
-  #  `TypeVar`s, which the `Unpack` is 'pulling out' directly into the
-  #  `Generic[]`.)
-  class Bar(Generic[Unpack[Ts]]): ...
-  Bar[int]  # Valid
-  Bar[int, str]  # Also valid
-
-From Python 3.11, this can also be done using the `*` operator:
-
-    Foo[*tuple[int, str]]
-    class Bar(Generic[*Ts]): ...
-
-The operator can also be used along with a `TypedDict` to annotate
-`**kwargs` in a function signature. For instance:
-
-  class Movie(TypedDict):
-    name: str
-    year: int
-
-  # This function expects two keyword arguments - *name* of type `str` and
-  # *year* of type `int`.
-  def foo(**kwargs: Unpack[Movie]): ...
-
-Note that there is only some runtime checking of this operator. Not
-everything the runtime allows may be accepted by static type checkers.
-
-For more information, see PEP 646 and PEP 692.
-"""
-
-
-# PEP 692 changed the repr of Unpack[]
-# Breakpoint: https://github.com/python/cpython/pull/104048
-if sys.version_info >= (3, 12):
-    Unpack = typing.Unpack
-
-    def _is_unpack(obj):
-        return get_origin(obj) is Unpack
-
-else:  # <=3.11
-    class _UnpackSpecialForm(_ExtensionsSpecialForm, _root=True):
-        def __init__(self, getitem):
-            super().__init__(getitem)
-            self.__doc__ = _UNPACK_DOC
-
-    class _UnpackAlias(typing._GenericAlias, _root=True):
-        if sys.version_info < (3, 11):
-            # needed for compatibility with Generic[Unpack[Ts]]
-            __class__ = typing.TypeVar
-
-        @property
-        def __typing_unpacked_tuple_args__(self):
-            assert self.__origin__ is Unpack
-            assert len(self.__args__) == 1
-            arg, = self.__args__
-            if isinstance(arg, (typing._GenericAlias, _types.GenericAlias)):
-                if arg.__origin__ is not tuple:
-                    raise TypeError("Unpack[...] must be used with a tuple type")
-                return arg.__args__
-            return None
-
-        @property
-        def __typing_is_unpacked_typevartuple__(self):
-            assert self.__origin__ is Unpack
-            assert len(self.__args__) == 1
-            return isinstance(self.__args__[0], TypeVarTuple)
-
-        def __getitem__(self, args):
-            if self.__typing_is_unpacked_typevartuple__:
-                return args
-            # Cannot use `super().__getitem__` here because of the `__class__` assignment
-            # in the class body on Python <=3.11
-            # (https://github.com/python/typing_extensions/issues/661)
-            return typing._GenericAlias.__getitem__(self, args)
-
-    @_UnpackSpecialForm
-    def Unpack(self, parameters):
-        item = typing._type_check(parameters, f'{self._name} accepts only a single type.')
-        return _UnpackAlias(self, (item,))
-
-    def _is_unpack(obj):
-        return isinstance(obj, _UnpackAlias)
-
-
-def _unpack_args(*args):
-    newargs = []
-    for arg in args:
-        subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
-        if subargs is not None and (not (subargs and subargs[-1] is ...)):
-            newargs.extend(subargs)
-        else:
-            newargs.append(arg)
-    return newargs
-
-
-if sys.version_info >= (3, 15):
-    from typing import TypeVarTuple
-
-elif hasattr(typing, "TypeVarTuple"):  # 3.11+
-
-    # Add default parameter - PEP 696 and bound/variance parameters
-    class TypeVarTuple(metaclass=_TypeVarLikeMeta):
-        """Type variable tuple."""
-
-        _backported_typevarlike = typing.TypeVarTuple
-
-        def __new__(cls, name, *, bound=None,
-                    covariant=False, contravariant=False,
-                    infer_variance=False, default=NoDefault):
-
-            if _PEP_696_IMPLEMENTED:
-                # can pass default argument
-                tvt = typing.TypeVarTuple(name, default=default)
-            else:
-                tvt = typing.TypeVarTuple(name)
-                _set_default(tvt, default)
-
-            tvt.__bound__ = bound
-            tvt.__covariant__ = bool(covariant)
-            tvt.__contravariant__ = bool(contravariant)
-            tvt.__infer_variance__ = bool(infer_variance)
-
-            _set_module(tvt)
-
-            def _typevartuple_prepare_subst(alias, args):
-                params = alias.__parameters__
-                typevartuple_index = params.index(tvt)
-                for param in params[typevartuple_index + 1:]:
-                    if isinstance(param, TypeVarTuple):
-                        raise TypeError(
-                            f"More than one TypeVarTuple parameter in {alias}"
-                        )
-
-                alen = len(args)
-                plen = len(params)
-                left = typevartuple_index
-                right = plen - typevartuple_index - 1
-                var_tuple_index = None
-                fillarg = None
-                for k, arg in enumerate(args):
-                    if not isinstance(arg, type):
-                        subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
-                        if subargs and len(subargs) == 2 and subargs[-1] is ...:
-                            if var_tuple_index is not None:
-                                raise TypeError(
-                                    "More than one unpacked "
-                                    "arbitrary-length tuple argument"
-                                )
-                            var_tuple_index = k
-                            fillarg = subargs[0]
-                if var_tuple_index is not None:
-                    left = min(left, var_tuple_index)
-                    right = min(right, alen - var_tuple_index - 1)
-                elif left + right > alen:
-                    raise TypeError(f"Too few arguments for {alias};"
-                                    f" actual {alen}, expected at least {plen - 1}")
-                if left == alen - right and tvt.has_default():
-                    replacement = _unpack_args(tvt.__default__)
-                else:
-                    replacement = args[left: alen - right]
-
-                return (
-                    *args[:left],
-                    *([fillarg] * (typevartuple_index - left)),
-                    replacement,
-                    *([fillarg] * (plen - right - left - typevartuple_index - 1)),
-                    *args[alen - right:],
-                )
-
-            tvt.__typing_prepare_subst__ = _typevartuple_prepare_subst
-            return tvt
-
-        def __init_subclass__(self, *args, **kwds):
-            raise TypeError("Cannot subclass special typing classes")
-
-else:  # <=3.10
-    class TypeVarTuple(_DefaultMixin):
-        """Type variable tuple.
-
-        Usage::
-
-            Ts = TypeVarTuple('Ts')
-
-        In the same way that a normal type variable is a stand-in for a single
-        type such as ``int``, a type variable *tuple* is a stand-in for a *tuple*
-        type such as ``Tuple[int, str]``.
-
-        Type variable tuples can be used in ``Generic`` declarations.
-        Consider the following example::
-
-            class Array(Generic[*Ts]): ...
-
-        The ``Ts`` type variable tuple here behaves like ``tuple[T1, T2]``,
-        where ``T1`` and ``T2`` are type variables. To use these type variables
-        as type parameters of ``Array``, we must *unpack* the type variable tuple using
-        the star operator: ``*Ts``. The signature of ``Array`` then behaves
-        as if we had simply written ``class Array(Generic[T1, T2]): ...``.
-        In contrast to ``Generic[T1, T2]``, however, ``Generic[*Shape]`` allows
-        us to parameterise the class with an *arbitrary* number of type parameters.
-
-        Type variable tuples can be used anywhere a normal ``TypeVar`` can.
-        This includes class definitions, as shown above, as well as function
-        signatures and variable annotations::
-
-            class Array(Generic[*Ts]):
-
-                def __init__(self, shape: Tuple[*Ts]):
-                    self._shape: Tuple[*Ts] = shape
-
-                def get_shape(self) -> Tuple[*Ts]:
-                    return self._shape
-
-            shape = (Height(480), Width(640))
-            x: Array[Height, Width] = Array(shape)
-            y = abs(x)  # Inferred type is Array[Height, Width]
-            z = x + x   #        ...    is Array[Height, Width]
-            x.get_shape()  #     ...    is tuple[Height, Width]
-
-        """
-
-        # Trick Generic __parameters__.
-        __class__ = typing.TypeVar
-
-        def __iter__(self):
-            yield self.__unpacked__
-
-        def __init__(self, name, *, bound=None, covariant=False, contravariant=False,
-                     infer_variance=False, default=NoDefault):
-            self.__name__ = name
-            self.__covariant__ = bool(covariant)
-            self.__contravariant__ = bool(contravariant)
-            self.__infer_variance__ = bool(infer_variance)
-            self.__bound__ = bound
-            _DefaultMixin.__init__(self, default)
-
-            # for pickling:
-            def_mod = _caller()
-            if def_mod != 'typing_extensions':
-                self.__module__ = def_mod
-
-            self.__unpacked__ = Unpack[self]
-
-        def __repr__(self):
-            if self.__infer_variance__:
-                prefix = ''
-            elif self.__covariant__:
-                prefix = '+'
-            elif self.__contravariant__:
-                prefix = '-'
-            else:
-                prefix = '~'
-            return prefix + self.__name__
-
-        def __hash__(self):
-            return object.__hash__(self)
-
-        def __eq__(self, other):
-            return self is other
-
-        def __reduce__(self):
-            return self.__name__
-
-        def __init_subclass__(self, *args, **kwds):
-            if '_root' not in kwds:
-                raise TypeError("Cannot subclass special typing classes")
-
-
-if hasattr(typing, "reveal_type"):  # 3.11+
-    reveal_type = typing.reveal_type
-else:  # <=3.10
-    def reveal_type(obj: T, /) -> T:
-        """Reveal the inferred type of a variable.
-
-        When a static type checker encounters a call to ``reveal_type()``,
-        it will emit the inferred type of the argument::
-
-            x: int = 1
-            reveal_type(x)
-
-        Running a static type checker (e.g., ``mypy``) on this example
-        will produce output similar to 'Revealed type is "builtins.int"'.
-
-        At runtime, the function prints the runtime type of the
-        argument and returns it unchanged.
-
-        """
-        print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr)
-        return obj
-
-
-if hasattr(typing, "_ASSERT_NEVER_REPR_MAX_LENGTH"):  # 3.11+
-    _ASSERT_NEVER_REPR_MAX_LENGTH = typing._ASSERT_NEVER_REPR_MAX_LENGTH
-else:  # <=3.10
-    _ASSERT_NEVER_REPR_MAX_LENGTH = 100
-
-
-if hasattr(typing, "assert_never"):  # 3.11+
-    assert_never = typing.assert_never
-else:  # <=3.10
-    def assert_never(arg: Never, /) -> Never:
-        """Assert to the type checker that a line of code is unreachable.
-
-        Example::
-
-            def int_or_str(arg: int | str) -> None:
-                match arg:
-                    case int():
-                        print("It's an int")
-                    case str():
-                        print("It's a str")
-                    case _:
-                        assert_never(arg)
-
-        If a type checker finds that a call to assert_never() is
-        reachable, it will emit an error.
-
-        At runtime, this throws an exception when called.
-
-        """
-        value = repr(arg)
-        if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH:
-            value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...'
-        raise AssertionError(f"Expected code to be unreachable, but got: {value}")
-
-
-# dataclass_transform exists in 3.11 but lacks the frozen_default parameter
-# Breakpoint: https://github.com/python/cpython/pull/99958
-if sys.version_info >= (3, 12):  # 3.12+
-    dataclass_transform = typing.dataclass_transform
-else:  # <=3.11
-    def dataclass_transform(
-        *,
-        eq_default: bool = True,
-        order_default: bool = False,
-        kw_only_default: bool = False,
-        frozen_default: bool = False,
-        field_specifiers: typing.Tuple[
-            typing.Union[typing.Type[typing.Any], typing.Callable[..., typing.Any]],
-            ...
-        ] = (),
-        **kwargs: typing.Any,
-    ) -> typing.Callable[[T], T]:
-        """Decorator that marks a function, class, or metaclass as providing
-        dataclass-like behavior.
-
-        Example:
-
-            from typing_extensions import dataclass_transform
-
-            _T = TypeVar("_T")
-
-            # Used on a decorator function
-            @dataclass_transform()
-            def create_model(cls: type[_T]) -> type[_T]:
-                ...
-                return cls
-
-            @create_model
-            class CustomerModel:
-                id: int
-                name: str
-
-            # Used on a base class
-            @dataclass_transform()
-            class ModelBase: ...
-
-            class CustomerModel(ModelBase):
-                id: int
-                name: str
-
-            # Used on a metaclass
-            @dataclass_transform()
-            class ModelMeta(type): ...
-
-            class ModelBase(metaclass=ModelMeta): ...
-
-            class CustomerModel(ModelBase):
-                id: int
-                name: str
-
-        Each of the ``CustomerModel`` classes defined in this example will now
-        behave similarly to a dataclass created with the ``@dataclasses.dataclass``
-        decorator. For example, the type checker will synthesize an ``__init__``
-        method.
-
-        The arguments to this decorator can be used to customize this behavior:
-        - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be
-          True or False if it is omitted by the caller.
-        - ``order_default`` indicates whether the ``order`` parameter is
-          assumed to be True or False if it is omitted by the caller.
-        - ``kw_only_default`` indicates whether the ``kw_only`` parameter is
-          assumed to be True or False if it is omitted by the caller.
-        - ``frozen_default`` indicates whether the ``frozen`` parameter is
-          assumed to be True or False if it is omitted by the caller.
-        - ``field_specifiers`` specifies a static list of supported classes
-          or functions that describe fields, similar to ``dataclasses.field()``.
-
-        At runtime, this decorator records its arguments in the
-        ``__dataclass_transform__`` attribute on the decorated object.
-
-        See PEP 681 for details.
-
-        """
-        def decorator(cls_or_fn):
-            cls_or_fn.__dataclass_transform__ = {
-                "eq_default": eq_default,
-                "order_default": order_default,
-                "kw_only_default": kw_only_default,
-                "frozen_default": frozen_default,
-                "field_specifiers": field_specifiers,
-                "kwargs": kwargs,
-            }
-            return cls_or_fn
-        return decorator
-
-
-if hasattr(typing, "override"):  # 3.12+
-    override = typing.override
-else:  # <=3.11
-    _F = typing.TypeVar("_F", bound=typing.Callable[..., typing.Any])
-
-    def override(arg: _F, /) -> _F:
-        """Indicate that a method is intended to override a method in a base class.
-
-        Usage:
-
-            class Base:
-                def method(self) -> None:
-                    pass
-
-            class Child(Base):
-                @override
-                def method(self) -> None:
-                    super().method()
-
-        When this decorator is applied to a method, the type checker will
-        validate that it overrides a method with the same name on a base class.
-        This helps prevent bugs that may occur when a base class is changed
-        without an equivalent change to a child class.
-
-        There is no runtime checking of these properties. The decorator
-        sets the ``__override__`` attribute to ``True`` on the decorated object
-        to allow runtime introspection.
-
-        See PEP 698 for details.
-
-        """
-        try:
-            arg.__override__ = True
-        except (AttributeError, TypeError):
-            # Skip the attribute silently if it is not writable.
-            # AttributeError happens if the object has __slots__ or a
-            # read-only property, TypeError if it's a builtin class.
-            pass
-        return arg
-
-
-# Python 3.13.8+ and 3.14.1+ contain a fix for the wrapped __init_subclass__
-# Breakpoint: https://github.com/python/cpython/pull/138210
-if ((3, 13, 8) <= sys.version_info < (3, 14)) or sys.version_info >= (3, 14, 1):
-    deprecated = warnings.deprecated
-else:
-    _T = typing.TypeVar("_T")
-
-    class deprecated:
-        """Indicate that a class, function or overload is deprecated.
-
-        When this decorator is applied to an object, the type checker
-        will generate a diagnostic on usage of the deprecated object.
-
-        Usage:
-
-            @deprecated("Use B instead")
-            class A:
-                pass
-
-            @deprecated("Use g instead")
-            def f():
-                pass
-
-            @overload
-            @deprecated("int support is deprecated")
-            def g(x: int) -> int: ...
-            @overload
-            def g(x: str) -> int: ...
-
-        The warning specified by *category* will be emitted at runtime
-        on use of deprecated objects. For functions, that happens on calls;
-        for classes, on instantiation and on creation of subclasses.
-        If the *category* is ``None``, no warning is emitted at runtime.
-        The *stacklevel* determines where the
-        warning is emitted. If it is ``1`` (the default), the warning
-        is emitted at the direct caller of the deprecated object; if it
-        is higher, it is emitted further up the stack.
-        Static type checker behavior is not affected by the *category*
-        and *stacklevel* arguments.
-
-        The deprecation message passed to the decorator is saved in the
-        ``__deprecated__`` attribute on the decorated object.
-        If applied to an overload, the decorator
-        must be after the ``@overload`` decorator for the attribute to
-        exist on the overload as returned by ``get_overloads()``.
-
-        See PEP 702 for details.
-
-        """
-        def __init__(
-            self,
-            message: str,
-            /,
-            *,
-            category: typing.Optional[typing.Type[Warning]] = DeprecationWarning,
-            stacklevel: int = 1,
-        ) -> None:
-            if not isinstance(message, str):
-                raise TypeError(
-                    "Expected an object of type str for 'message', not "
-                    f"{type(message).__name__!r}"
-                )
-            self.message = message
-            self.category = category
-            self.stacklevel = stacklevel
-
-        def __call__(self, arg: _T, /) -> _T:
-            # Make sure the inner functions created below don't
-            # retain a reference to self.
-            msg = self.message
-            category = self.category
-            stacklevel = self.stacklevel
-            if category is None:
-                arg.__deprecated__ = msg
-                return arg
-            elif isinstance(arg, type):
-                import functools
-                from types import MethodType
-
-                original_new = arg.__new__
-
-                @functools.wraps(original_new)
-                def __new__(cls, /, *args, **kwargs):
-                    if cls is arg:
-                        warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
-                    if original_new is not object.__new__:
-                        return original_new(cls, *args, **kwargs)
-                    # Mirrors a similar check in object.__new__.
-                    elif cls.__init__ is object.__init__ and (args or kwargs):
-                        raise TypeError(f"{cls.__name__}() takes no arguments")
-                    else:
-                        return original_new(cls)
-
-                arg.__new__ = staticmethod(__new__)
-
-                if "__init_subclass__" in arg.__dict__:
-                    # __init_subclass__ is directly present on the decorated class.
-                    # Synthesize a wrapper that calls this method directly.
-                    original_init_subclass = arg.__init_subclass__
-                    # We need slightly different behavior if __init_subclass__
-                    # is a bound method (likely if it was implemented in Python).
-                    # Otherwise, it likely means it's a builtin such as
-                    # object's implementation of __init_subclass__.
-                    if isinstance(original_init_subclass, MethodType):
-                        original_init_subclass = original_init_subclass.__func__
-
-                    @functools.wraps(original_init_subclass)
-                    def __init_subclass__(*args, **kwargs):
-                        warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
-                        return original_init_subclass(*args, **kwargs)
-                else:
-                    def __init_subclass__(cls, *args, **kwargs):
-                        warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
-                        return super(arg, cls).__init_subclass__(*args, **kwargs)
-
-                arg.__init_subclass__ = classmethod(__init_subclass__)
-
-                arg.__deprecated__ = __new__.__deprecated__ = msg
-                __init_subclass__.__deprecated__ = msg
-                return arg
-            elif callable(arg):
-                import functools
-                import inspect
-
-                @functools.wraps(arg)
-                def wrapper(*args, **kwargs):
-                    warnings.warn(msg, category=category, stacklevel=stacklevel + 1)
-                    return arg(*args, **kwargs)
-
-                if inspect.iscoroutinefunction(arg):
-                    # Breakpoint: https://github.com/python/cpython/pull/99247
-                    if sys.version_info >= (3, 12):
-                        wrapper = inspect.markcoroutinefunction(wrapper)
-                    else:
-                        import asyncio.coroutines
-
-                        wrapper._is_coroutine = asyncio.coroutines._is_coroutine
-
-                arg.__deprecated__ = wrapper.__deprecated__ = msg
-                return wrapper
-            else:
-                raise TypeError(
-                    "@deprecated decorator with non-None category must be applied to "
-                    f"a class or callable, not {arg!r}"
-                )
-
-# Breakpoint: https://github.com/python/cpython/pull/23702
-if sys.version_info < (3, 10):
-    def _is_param_expr(arg):
-        return arg is ... or isinstance(
-            arg, (tuple, list, ParamSpec, _ConcatenateGenericAlias)
-        )
-else:
-    def _is_param_expr(arg):
-        return arg is ... or isinstance(
-            arg,
-            (
-                tuple,
-                list,
-                ParamSpec,
-                _ConcatenateGenericAlias,
-                typing._ConcatenateGenericAlias,
-            ),
-        )
-
-
-# We have to do some monkey patching to deal with the dual nature of
-# Unpack/TypeVarTuple:
-# - We want Unpack to be a kind of TypeVar so it gets accepted in
-#   Generic[Unpack[Ts]]
-# - We want it to *not* be treated as a TypeVar for the purposes of
-#   counting generic parameters, so that when we subscript a generic,
-#   the runtime doesn't try to substitute the Unpack with the subscripted type.
-if not hasattr(typing, "TypeVarTuple"):
-    def _check_generic(cls, parameters, elen=_marker):
-        """Check correct count for parameters of a generic cls (internal helper).
-
-        This gives a nice error message in case of count mismatch.
-        """
-        # If substituting a single ParamSpec with multiple arguments
-        # we do not check the count
-        if (inspect.isclass(cls) and issubclass(cls, typing.Generic)
-            and len(cls.__parameters__) == 1
-            and isinstance(cls.__parameters__[0], ParamSpec)
-            and parameters
-            and not _is_param_expr(parameters[0])
-        ):
-            # Generic modifies parameters variable, but here we cannot do this
-            return
-
-        if not elen:
-            raise TypeError(f"{cls} is not a generic class")
-        if elen is _marker:
-            if not hasattr(cls, "__parameters__") or not cls.__parameters__:
-                raise TypeError(f"{cls} is not a generic class")
-            elen = len(cls.__parameters__)
-        alen = len(parameters)
-        if alen != elen:
-            expect_val = elen
-            if hasattr(cls, "__parameters__"):
-                parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
-                num_tv_tuples = sum(isinstance(p, TypeVarTuple) for p in parameters)
-                if (num_tv_tuples > 0) and (alen >= elen - num_tv_tuples):
-                    return
-
-                # deal with TypeVarLike defaults
-                # required TypeVarLikes cannot appear after a defaulted one.
-                if alen < elen:
-                    # since we validate TypeVarLike default in _collect_type_vars
-                    # or _collect_parameters we can safely check parameters[alen]
-                    if (
-                        getattr(parameters[alen], '__default__', NoDefault)
-                        is not NoDefault
-                    ):
-                        return
-
-                    num_default_tv = sum(getattr(p, '__default__', NoDefault)
-                                         is not NoDefault for p in parameters)
-
-                    elen -= num_default_tv
-
-                    expect_val = f"at least {elen}"
-
-            # Breakpoint: https://github.com/python/cpython/pull/27515
-            things = "arguments" if sys.version_info >= (3, 10) else "parameters"
-            raise TypeError(f"Too {'many' if alen > elen else 'few'} {things}"
-                            f" for {cls}; actual {alen}, expected {expect_val}")
-else:
-    # Python 3.11+
-
-    def _check_generic(cls, parameters, elen):
-        """Check correct count for parameters of a generic cls (internal helper).
-
-        This gives a nice error message in case of count mismatch.
-        """
-        if not elen:
-            raise TypeError(f"{cls} is not a generic class")
-        alen = len(parameters)
-        if alen != elen:
-            expect_val = elen
-            if hasattr(cls, "__parameters__"):
-                parameters = [p for p in cls.__parameters__ if not _is_unpack(p)]
-
-                # deal with TypeVarLike defaults
-                # required TypeVarLikes cannot appear after a defaulted one.
-                if alen < elen:
-                    # since we validate TypeVarLike default in _collect_type_vars
-                    # or _collect_parameters we can safely check parameters[alen]
-                    if (
-                        getattr(parameters[alen], '__default__', NoDefault)
-                        is not NoDefault
-                    ):
-                        return
-
-                    num_default_tv = sum(getattr(p, '__default__', NoDefault)
-                                         is not NoDefault for p in parameters)
-
-                    elen -= num_default_tv
-
-                    expect_val = f"at least {elen}"
-
-            raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments"
-                            f" for {cls}; actual {alen}, expected {expect_val}")
-
-if not _PEP_696_IMPLEMENTED:
-    typing._check_generic = _check_generic
-
-
-def _has_generic_or_protocol_as_origin() -> bool:
-    try:
-        frame = sys._getframe(2)
-    # - Catch AttributeError: not all Python implementations have sys._getframe()
-    # - Catch ValueError: maybe we're called from an unexpected module
-    #   and the call stack isn't deep enough
-    except (AttributeError, ValueError):
-        return False  # err on the side of leniency
-    else:
-        # If we somehow get invoked from outside typing.py,
-        # also err on the side of leniency
-        if frame.f_globals.get("__name__") != "typing":
-            return False
-        origin = frame.f_locals.get("origin")
-        # Cannot use "in" because origin may be an object with a buggy __eq__ that
-        # throws an error.
-        return origin is typing.Generic or origin is Protocol or origin is typing.Protocol
-
-
-_TYPEVARTUPLE_TYPES = {TypeVarTuple, getattr(typing, "TypeVarTuple", None)}
-
-
-def _is_unpacked_typevartuple(x) -> bool:
-    if get_origin(x) is not Unpack:
-        return False
-    args = get_args(x)
-    return (
-        bool(args)
-        and len(args) == 1
-        and type(args[0]) in _TYPEVARTUPLE_TYPES
-    )
-
-
-# Python 3.11+ _collect_type_vars was renamed to _collect_parameters
-if hasattr(typing, '_collect_type_vars'):
-    def _collect_type_vars(types, typevar_types=None):
-        """Collect all type variable contained in types in order of
-        first appearance (lexicographic order). For example::
-
-            _collect_type_vars((T, List[S, T])) == (T, S)
-        """
-        if typevar_types is None:
-            typevar_types = typing.TypeVar
-        tvars = []
-
-        # A required TypeVarLike cannot appear after a TypeVarLike with a default
-        # if it was a direct call to `Generic[]` or `Protocol[]`
-        enforce_default_ordering = _has_generic_or_protocol_as_origin()
-        default_encountered = False
-
-        # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
-        type_var_tuple_encountered = False
-
-        for t in types:
-            if _is_unpacked_typevartuple(t):
-                type_var_tuple_encountered = True
-            elif (
-                isinstance(t, typevar_types) and not isinstance(t, _UnpackAlias)
-                and t not in tvars
-            ):
-                if enforce_default_ordering:
-                    has_default = getattr(t, '__default__', NoDefault) is not NoDefault
-                    if has_default:
-                        if type_var_tuple_encountered:
-                            raise TypeError('Type parameter with a default'
-                                            ' follows TypeVarTuple')
-                        default_encountered = True
-                    elif default_encountered:
-                        raise TypeError(f'Type parameter {t!r} without a default'
-                                        ' follows type parameter with a default')
-
-                tvars.append(t)
-            if _should_collect_from_parameters(t):
-                tvars.extend([t for t in t.__parameters__ if t not in tvars])
-            elif isinstance(t, tuple):
-                # Collect nested type_vars
-                # tuple wrapped by  _prepare_paramspec_params(cls, params)
-                for x in t:
-                    for collected in _collect_type_vars([x]):
-                        if collected not in tvars:
-                            tvars.append(collected)
-        return tuple(tvars)
-
-    typing._collect_type_vars = _collect_type_vars
-else:
-    def _collect_parameters(args):
-        """Collect all type variables and parameter specifications in args
-        in order of first appearance (lexicographic order).
-
-        For example::
-
-            assert _collect_parameters((T, Callable[P, T])) == (T, P)
-        """
-        parameters = []
-
-        # A required TypeVarLike cannot appear after a TypeVarLike with default
-        # if it was a direct call to `Generic[]` or `Protocol[]`
-        enforce_default_ordering = _has_generic_or_protocol_as_origin()
-        default_encountered = False
-
-        # Also, a TypeVarLike with a default cannot appear after a TypeVarTuple
-        type_var_tuple_encountered = False
-
-        for t in args:
-            if isinstance(t, type):
-                # We don't want __parameters__ descriptor of a bare Python class.
-                pass
-            elif isinstance(t, tuple):
-                # `t` might be a tuple, when `ParamSpec` is substituted with
-                # `[T, int]`, or `[int, *Ts]`, etc.
-                for x in t:
-                    for collected in _collect_parameters([x]):
-                        if collected not in parameters:
-                            parameters.append(collected)
-            elif hasattr(t, '__typing_subst__'):
-                if t not in parameters:
-                    if enforce_default_ordering:
-                        has_default = (
-                            getattr(t, '__default__', NoDefault) is not NoDefault
-                        )
-
-                        if type_var_tuple_encountered and has_default:
-                            raise TypeError('Type parameter with a default'
-                                            ' follows TypeVarTuple')
-
-                        if has_default:
-                            default_encountered = True
-                        elif default_encountered:
-                            raise TypeError(f'Type parameter {t!r} without a default'
-                                            ' follows type parameter with a default')
-
-                    parameters.append(t)
-            else:
-                if _is_unpacked_typevartuple(t):
-                    type_var_tuple_encountered = True
-                for x in getattr(t, '__parameters__', ()):
-                    if x not in parameters:
-                        parameters.append(x)
-
-        return tuple(parameters)
-
-    if not _PEP_696_IMPLEMENTED:
-        typing._collect_parameters = _collect_parameters
-
-# Backport typing.NamedTuple as it exists in Python 3.13.
-# In 3.11, the ability to define generic `NamedTuple`s was supported.
-# This was explicitly disallowed in 3.9-3.10, and only half-worked in <=3.8.
-# On 3.12, we added __orig_bases__ to call-based NamedTuples
-# On 3.13, we deprecated kwargs-based NamedTuples
-# Breakpoint: https://github.com/python/cpython/pull/105609
-if sys.version_info >= (3, 13):
-    NamedTuple = typing.NamedTuple
-else:
-    def _make_nmtuple(name, types, module, defaults=()):
-        fields = [n for n, t in types]
-        annotations = {n: typing._type_check(t, f"field {n} annotation must be a type")
-                       for n, t in types}
-        nm_tpl = collections.namedtuple(name, fields,
-                                        defaults=defaults, module=module)
-        nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = annotations
-        return nm_tpl
-
-    _prohibited_namedtuple_fields = typing._prohibited
-    _special_namedtuple_fields = frozenset({'__module__', '__name__', '__annotations__'})
-
-    class _NamedTupleMeta(type):
-        def __new__(cls, typename, bases, ns):
-            assert _NamedTuple in bases
-            for base in bases:
-                if base is not _NamedTuple and base is not typing.Generic:
-                    raise TypeError(
-                        'can only inherit from a NamedTuple type and Generic')
-            bases = tuple(tuple if base is _NamedTuple else base for base in bases)
-            if "__annotations__" in ns:
-                types = ns["__annotations__"]
-            elif "__annotate__" in ns:
-                # TODO: Use inspect.VALUE here, and make the annotations lazily evaluated
-                types = ns["__annotate__"](1)
-            else:
-                types = {}
-            default_names = []
-            for field_name in types:
-                if field_name in ns:
-                    default_names.append(field_name)
-                elif default_names:
-                    raise TypeError(f"Non-default namedtuple field {field_name} "
-                                    f"cannot follow default field"
-                                    f"{'s' if len(default_names) > 1 else ''} "
-                                    f"{', '.join(default_names)}")
-            nm_tpl = _make_nmtuple(
-                typename, types.items(),
-                defaults=[ns[n] for n in default_names],
-                module=ns['__module__']
-            )
-            nm_tpl.__bases__ = bases
-            if typing.Generic in bases:
-                if hasattr(typing, '_generic_class_getitem'):  # 3.12+
-                    nm_tpl.__class_getitem__ = classmethod(typing._generic_class_getitem)
-                else:
-                    class_getitem = typing.Generic.__class_getitem__.__func__
-                    nm_tpl.__class_getitem__ = classmethod(class_getitem)
-            # update from user namespace without overriding special namedtuple attributes
-            for key, val in ns.items():
-                if key in _prohibited_namedtuple_fields:
-                    raise AttributeError("Cannot overwrite NamedTuple attribute " + key)
-                elif key not in _special_namedtuple_fields:
-                    if key not in nm_tpl._fields:
-                        setattr(nm_tpl, key, ns[key])
-                    try:
-                        set_name = type(val).__set_name__
-                    except AttributeError:
-                        pass
-                    else:
-                        try:
-                            set_name(val, nm_tpl, key)
-                        except BaseException as e:
-                            msg = (
-                                f"Error calling __set_name__ on {type(val).__name__!r} "
-                                f"instance {key!r} in {typename!r}"
-                            )
-                            # BaseException.add_note() existed on py311,
-                            # but the __set_name__ machinery didn't start
-                            # using add_note() until py312.
-                            # Making sure exceptions are raised in the same way
-                            # as in "normal" classes seems most important here.
-                            # Breakpoint: https://github.com/python/cpython/pull/95915
-                            if sys.version_info >= (3, 12):
-                                e.add_note(msg)
-                                raise
-                            else:
-                                raise RuntimeError(msg) from e
-
-            if typing.Generic in bases:
-                nm_tpl.__init_subclass__()
-            return nm_tpl
-
-    _NamedTuple = type.__new__(_NamedTupleMeta, 'NamedTuple', (), {})
-
-    def _namedtuple_mro_entries(bases):
-        assert NamedTuple in bases
-        return (_NamedTuple,)
-
-    def NamedTuple(typename, fields=_marker, /, **kwargs):
-        """Typed version of namedtuple.
-
-        Usage::
-
-            class Employee(NamedTuple):
-                name: str
-                id: int
-
-        This is equivalent to::
-
-            Employee = collections.namedtuple('Employee', ['name', 'id'])
-
-        The resulting class has an extra __annotations__ attribute, giving a
-        dict that maps field names to types.  (The field names are also in
-        the _fields attribute, which is part of the namedtuple API.)
-        An alternative equivalent functional syntax is also accepted::
-
-            Employee = NamedTuple('Employee', [('name', str), ('id', int)])
-        """
-        if fields is _marker:
-            if kwargs:
-                deprecated_thing = "Creating NamedTuple classes using keyword arguments"
-                deprecation_msg = (
-                    "{name} is deprecated and will be disallowed in Python {remove}. "
-                    "Use the class-based or functional syntax instead."
-                )
-            else:
-                deprecated_thing = "Failing to pass a value for the 'fields' parameter"
-                example = f"`{typename} = NamedTuple({typename!r}, [])`"
-                deprecation_msg = (
-                    "{name} is deprecated and will be disallowed in Python {remove}. "
-                    "To create a NamedTuple class with 0 fields "
-                    "using the functional syntax, "
-                    "pass an empty list, e.g. "
-                ) + example + "."
-        elif fields is None:
-            if kwargs:
-                raise TypeError(
-                    "Cannot pass `None` as the 'fields' parameter "
-                    "and also specify fields using keyword arguments"
-                )
-            else:
-                deprecated_thing = "Passing `None` as the 'fields' parameter"
-                example = f"`{typename} = NamedTuple({typename!r}, [])`"
-                deprecation_msg = (
-                    "{name} is deprecated and will be disallowed in Python {remove}. "
-                    "To create a NamedTuple class with 0 fields "
-                    "using the functional syntax, "
-                    "pass an empty list, e.g. "
-                ) + example + "."
-        elif kwargs:
-            raise TypeError("Either list of fields or keywords"
-                            " can be provided to NamedTuple, not both")
-        if fields is _marker or fields is None:
-            warnings.warn(
-                deprecation_msg.format(name=deprecated_thing, remove="3.15"),
-                DeprecationWarning,
-                stacklevel=2,
-            )
-            fields = kwargs.items()
-        nt = _make_nmtuple(typename, fields, module=_caller())
-        nt.__orig_bases__ = (NamedTuple,)
-        return nt
-
-    NamedTuple.__mro_entries__ = _namedtuple_mro_entries
-
-
-if hasattr(collections.abc, "Buffer"):
-    Buffer = collections.abc.Buffer
-else:
-    class Buffer(abc.ABC):  # noqa: B024
-        """Base class for classes that implement the buffer protocol.
-
-        The buffer protocol allows Python objects to expose a low-level
-        memory buffer interface. Before Python 3.12, it is not possible
-        to implement the buffer protocol in pure Python code, or even
-        to check whether a class implements the buffer protocol. In
-        Python 3.12 and higher, the ``__buffer__`` method allows access
-        to the buffer protocol from Python code, and the
-        ``collections.abc.Buffer`` ABC allows checking whether a class
-        implements the buffer protocol.
-
-        To indicate support for the buffer protocol in earlier versions,
-        inherit from this ABC, either in a stub file or at runtime,
-        or use ABC registration. This ABC provides no methods, because
-        there is no Python-accessible methods shared by pre-3.12 buffer
-        classes. It is useful primarily for static checks.
-
-        """
-
-    # As a courtesy, register the most common stdlib buffer classes.
-    Buffer.register(memoryview)
-    Buffer.register(bytearray)
-    Buffer.register(bytes)
-
-
-# Backport of types.get_original_bases, available on 3.12+ in CPython
-if hasattr(_types, "get_original_bases"):
-    get_original_bases = _types.get_original_bases
-else:
-    def get_original_bases(cls, /):
-        """Return the class's "original" bases prior to modification by `__mro_entries__`.
-
-        Examples::
-
-            from typing import TypeVar, Generic
-            from typing_extensions import NamedTuple, TypedDict
-
-            T = TypeVar("T")
-            class Foo(Generic[T]): ...
-            class Bar(Foo[int], float): ...
-            class Baz(list[str]): ...
-            Eggs = NamedTuple("Eggs", [("a", int), ("b", str)])
-            Spam = TypedDict("Spam", {"a": int, "b": str})
-
-            assert get_original_bases(Bar) == (Foo[int], float)
-            assert get_original_bases(Baz) == (list[str],)
-            assert get_original_bases(Eggs) == (NamedTuple,)
-            assert get_original_bases(Spam) == (TypedDict,)
-            assert get_original_bases(int) == (object,)
-        """
-        try:
-            return cls.__dict__.get("__orig_bases__", cls.__bases__)
-        except AttributeError:
-            raise TypeError(
-                f'Expected an instance of type, not {type(cls).__name__!r}'
-            ) from None
-
-
-# NewType is a class on Python 3.10+, making it pickleable
-# The error message for subclassing instances of NewType was improved on 3.11+
-# Breakpoint: https://github.com/python/cpython/pull/30268
-if sys.version_info >= (3, 11):
-    NewType = typing.NewType
-else:
-    class NewType:
-        """NewType creates simple unique types with almost zero
-        runtime overhead. NewType(name, tp) is considered a subtype of tp
-        by static type checkers. At runtime, NewType(name, tp) returns
-        a dummy callable that simply returns its argument. Usage::
-            UserId = NewType('UserId', int)
-            def name_by_id(user_id: UserId) -> str:
-                ...
-            UserId('user')          # Fails type check
-            name_by_id(42)          # Fails type check
-            name_by_id(UserId(42))  # OK
-            num = UserId(5) + 1     # type: int
-        """
-
-        def __call__(self, obj, /):
-            return obj
-
-        def __init__(self, name, tp):
-            self.__qualname__ = name
-            if '.' in name:
-                name = name.rpartition('.')[-1]
-            self.__name__ = name
-            self.__supertype__ = tp
-            def_mod = _caller()
-            if def_mod != 'typing_extensions':
-                self.__module__ = def_mod
-
-        def __mro_entries__(self, bases):
-            # We defined __mro_entries__ to get a better error message
-            # if a user attempts to subclass a NewType instance. bpo-46170
-            supercls_name = self.__name__
-
-            class Dummy:
-                def __init_subclass__(cls):
-                    subcls_name = cls.__name__
-                    raise TypeError(
-                        f"Cannot subclass an instance of NewType. "
-                        f"Perhaps you were looking for: "
-                        f"`{subcls_name} = NewType({subcls_name!r}, {supercls_name})`"
-                    )
-
-            return (Dummy,)
-
-        def __repr__(self):
-            return f'{self.__module__}.{self.__qualname__}'
-
-        def __reduce__(self):
-            return self.__qualname__
-
-        # Breakpoint: https://github.com/python/cpython/pull/21515
-        if sys.version_info >= (3, 10):
-            # PEP 604 methods
-            # It doesn't make sense to have these methods on Python <3.10
-
-            def __or__(self, other):
-                return typing.Union[self, other]
-
-            def __ror__(self, other):
-                return typing.Union[other, self]
-
-
-# Breakpoint: https://github.com/python/cpython/pull/149172
-if sys.version_info >= (3, 15):
-    TypeAliasType = typing.TypeAliasType
-# <=3.14
-else:
-    # Breakpoint: https://github.com/python/cpython/pull/103764
-    if sys.version_info >= (3, 12):
-        # 3.12-3.14
-        def _is_unionable(obj):
-            """Corresponds to is_unionable() in unionobject.c in CPython."""
-            return obj is None or isinstance(obj, (
-                type,
-                _types.GenericAlias,
-                _types.UnionType,
-                typing.TypeAliasType,
-                TypeAliasType,
-            ))
-    else:
-        # <=3.11
-        def _is_unionable(obj):
-            """Corresponds to is_unionable() in unionobject.c in CPython."""
-            return obj is None or isinstance(obj, (
-                type,
-                _types.GenericAlias,
-                _types.UnionType,
-                TypeAliasType,
-            ))
-
-    if sys.version_info < (3, 10):
-        # Copied and pasted from https://github.com/python/cpython/blob/986a4e1b6fcae7fe7a1d0a26aea446107dd58dd2/Objects/genericaliasobject.c#L568-L582,
-        # so that we emulate the behaviour of `types.GenericAlias`
-        # on the latest versions of CPython
-        _ATTRIBUTE_DELEGATION_EXCLUSIONS = frozenset({
-            "__class__",
-            "__bases__",
-            "__origin__",
-            "__args__",
-            "__unpacked__",
-            "__parameters__",
-            "__typing_unpacked_tuple_args__",
-            "__mro_entries__",
-            "__reduce_ex__",
-            "__reduce__",
-            "__copy__",
-            "__deepcopy__",
-        })
-
-        class _TypeAliasGenericAlias(typing._GenericAlias, _root=True):
-            def __getattr__(self, attr):
-                if attr in _ATTRIBUTE_DELEGATION_EXCLUSIONS:
-                    return object.__getattr__(self, attr)
-                return getattr(self.__origin__, attr)
-
-
-    class TypeAliasType:
-        """Create named, parameterized type aliases.
-
-        This provides a backport of the new `type` statement in Python 3.12:
-
-            type ListOrSet[T] = list[T] | set[T]
-
-        is equivalent to:
-
-            T = TypeVar("T")
-            ListOrSet = TypeAliasType("ListOrSet", list[T] | set[T], type_params=(T,))
-
-        The name ListOrSet can then be used as an alias for the type it refers to.
-
-        The type_params argument should contain all the type parameters used
-        in the value of the type alias. If the alias is not generic, this
-        argument is omitted.
-
-        Static type checkers should only support type aliases declared using
-        TypeAliasType that follow these rules:
-
-        - The first argument (the name) must be a string literal.
-        - The TypeAliasType instance must be immediately assigned to a variable
-          of the same name. (For example, 'X = TypeAliasType("Y", int)' is invalid,
-          as is 'X, Y = TypeAliasType("X", int), TypeAliasType("Y", int)').
-
-        """
-
-        def __init__(self, name: str, value, *, type_params=()):
-            if not isinstance(name, str):
-                raise TypeError("TypeAliasType name must be a string")
-            if not isinstance(type_params, tuple):
-                raise TypeError("type_params must be a tuple")
-            self.__value__ = value
-            self.__type_params__ = type_params
-
-            default_value_encountered = False
-            parameters = []
-            for type_param in type_params:
-                if (
-                    not isinstance(type_param, (TypeVar, TypeVarTuple, ParamSpec))
-                    # <=3.11
-                    # Unpack Backport passes isinstance(type_param, TypeVar)
-                    or _is_unpack(type_param)
-                ):
-                    raise TypeError(f"Expected a type param, got {type_param!r}")
-                has_default = (
-                    getattr(type_param, '__default__', NoDefault) is not NoDefault
-                )
-                if default_value_encountered and not has_default:
-                    raise TypeError(f"non-default type parameter '{type_param!r}'"
-                                    " follows default type parameter")
-                if has_default:
-                    default_value_encountered = True
-                if isinstance(type_param, TypeVarTuple):
-                    parameters.extend(type_param)
-                else:
-                    parameters.append(type_param)
-            self.__parameters__ = tuple(parameters)
-            def_mod = _caller()
-            if def_mod != 'typing_extensions':
-                self.__module__ = def_mod
-            # Setting this attribute closes the TypeAliasType from further modification
-            self.__name__ = name
-
-        def __setattr__(self, name: str, value: object, /) -> None:
-            if hasattr(self, "__name__") and name != "__module__":
-                self._raise_attribute_error(name)
-            super().__setattr__(name, value)
-
-        def __delattr__(self, name: str, /) -> Never:
-            self._raise_attribute_error(name)
-
-        def _raise_attribute_error(self, name: str) -> Never:
-            # Match the Python 3.12 error messages exactly
-            if name == "__name__":
-                raise AttributeError("readonly attribute")
-            elif name in {"__value__", "__type_params__", "__parameters__"}:
-                raise AttributeError(
-                    f"attribute '{name}' of 'typing.TypeAliasType' objects "
-                    "is not writable"
-                )
-            else:
-                raise AttributeError(
-                    f"'typing.TypeAliasType' object has no attribute '{name}'"
-                )
-
-        def __repr__(self) -> str:
-            return self.__name__
-
-        if sys.version_info < (3, 11):
-            def _check_single_param(self, param, recursion=0):
-                # Allow [], [int], [int, str], [int, ...], [int, T]
-                if param is ...:
-                    return ...
-                if param is None:
-                    return None
-                # Note in <= 3.9 _ConcatenateGenericAlias inherits from list
-                if isinstance(param, list) and recursion == 0:
-                    return [self._check_single_param(arg, recursion+1)
-                            for arg in param]
-                return typing._type_check(
-                        param, f'Subscripting {self.__name__} requires a type.'
-                    )
-
-        def _check_parameters(self, parameters):
-            if sys.version_info < (3, 11):
-                return tuple(
-                    self._check_single_param(item)
-                    for item in parameters
-                )
-            return tuple(typing._type_check(
-                        item, f'Subscripting {self.__name__} requires a type.'
-                    )
-                    for item in parameters
-            )
-
-        def __getitem__(self, parameters):
-            if not self.__type_params__:
-                raise TypeError("Only generic type aliases are subscriptable")
-            if not isinstance(parameters, tuple):
-                parameters = (parameters,)
-            # Using 3.9 here will create problems with Concatenate
-            if sys.version_info >= (3, 10):
-                return _types.GenericAlias(self, parameters)
-            type_vars = _collect_type_vars(parameters)
-            parameters = self._check_parameters(parameters)
-            alias = _TypeAliasGenericAlias(self, parameters)
-            # alias.__parameters__ is not complete if Concatenate is present
-            # as it is converted to a list from which no parameters are extracted.
-            if alias.__parameters__ != type_vars:
-                alias.__parameters__ = type_vars
-            return alias
-
-        def __reduce__(self):
-            return self.__name__
-
-        def __init_subclass__(cls, *args, **kwargs):
-            raise TypeError(
-                "type 'typing_extensions.TypeAliasType' is not an acceptable base type"
-            )
-
-        # The presence of this method convinces typing._type_check
-        # that TypeAliasTypes are types.
-        def __call__(self):
-            raise TypeError("Type alias is not callable")
-
-        # Breakpoint: https://github.com/python/cpython/pull/21515
-        if sys.version_info >= (3, 10):
-            def __or__(self, right):
-                # For forward compatibility with 3.12, reject Unions
-                # that are not accepted by the built-in Union.
-                if not _is_unionable(right):
-                    return NotImplemented
-                return typing.Union[self, right]
-
-            def __ror__(self, left):
-                if not _is_unionable(left):
-                    return NotImplemented
-                return typing.Union[left, self]
-
-
-if hasattr(typing, "is_protocol"):
-    is_protocol = typing.is_protocol
-    get_protocol_members = typing.get_protocol_members
-else:
-    def is_protocol(tp: type, /) -> bool:
-        """Return True if the given type is a Protocol.
-
-        Example::
-
-            >>> from typing_extensions import Protocol, is_protocol
-            >>> class P(Protocol):
-            ...     def a(self) -> str: ...
-            ...     b: int
-            >>> is_protocol(P)
-            True
-            >>> is_protocol(int)
-            False
-        """
-        return (
-            isinstance(tp, type)
-            and getattr(tp, '_is_protocol', False)
-            and tp is not Protocol
-            and tp is not typing.Protocol
-        )
-
-    def get_protocol_members(tp: type, /) -> typing.FrozenSet[str]:
-        """Return the set of members defined in a Protocol.
-
-        Example::
-
-            >>> from typing_extensions import Protocol, get_protocol_members
-            >>> class P(Protocol):
-            ...     def a(self) -> str: ...
-            ...     b: int
-            >>> get_protocol_members(P) == frozenset({'a', 'b'})
-            True
-
-        Raise a TypeError for arguments that are not Protocols.
-        """
-        if not is_protocol(tp):
-            raise TypeError(f'{tp!r} is not a Protocol')
-        if hasattr(tp, '__protocol_attrs__'):
-            return frozenset(tp.__protocol_attrs__)
-        return frozenset(_get_protocol_attrs(tp))
-
-
-if hasattr(typing, "Doc"):
-    Doc = typing.Doc
-else:
-    class Doc:
-        """Define the documentation of a type annotation using ``Annotated``, to be
-         used in class attributes, function and method parameters, return values,
-         and variables.
-
-        The value should be a positional-only string literal to allow static tools
-        like editors and documentation generators to use it.
-
-        This complements docstrings.
-
-        The string value passed is available in the attribute ``documentation``.
-
-        Example::
-
-            >>> from typing_extensions import Annotated, Doc
-            >>> def hi(to: Annotated[str, Doc("Who to say hi to")]) -> None: ...
-        """
-        def __init__(self, documentation: str, /) -> None:
-            self.documentation = documentation
-
-        def __repr__(self) -> str:
-            return f"Doc({self.documentation!r})"
-
-        def __hash__(self) -> int:
-            return hash(self.documentation)
-
-        def __eq__(self, other: object) -> bool:
-            if not isinstance(other, Doc):
-                return NotImplemented
-            return self.documentation == other.documentation
-
-
-_CapsuleType = getattr(_types, "CapsuleType", None)
-
-if _CapsuleType is None:
-    try:
-        import _socket
-    except ImportError:
-        pass
-    else:
-        _CAPI = getattr(_socket, "CAPI", None)
-        if _CAPI is not None:
-            _CapsuleType = type(_CAPI)
-
-if _CapsuleType is not None:
-    CapsuleType = _CapsuleType
-    __all__.append("CapsuleType")
-
-
-if sys.version_info >= (3, 14):
-    from annotationlib import Format, get_annotations
-else:
-    # Available since Python 3.14.0a3
-    # PR: https://github.com/python/cpython/pull/124415
-    class Format(enum.IntEnum):
-        VALUE = 1
-        VALUE_WITH_FAKE_GLOBALS = 2
-        FORWARDREF = 3
-        STRING = 4
-
-    # Available since Python 3.14.0a1
-    # PR: https://github.com/python/cpython/pull/119891
-    def get_annotations(obj, *, globals=None, locals=None, eval_str=False,
-                        format=Format.VALUE):
-        """Compute the annotations dict for an object.
-
-        obj may be a callable, class, or module.
-        Passing in an object of any other type raises TypeError.
-
-        Returns a dict.  get_annotations() returns a new dict every time
-        it's called; calling it twice on the same object will return two
-        different but equivalent dicts.
-
-        This is a backport of `inspect.get_annotations`, which has been
-        in the standard library since Python 3.10. See the standard library
-        documentation for more:
-
-            https://docs.python.org/3/library/inspect.html#inspect.get_annotations
-
-        This backport adds the *format* argument introduced by PEP 649. The
-        three formats supported are:
-        * VALUE: the annotations are returned as-is. This is the default and
-          it is compatible with the behavior on previous Python versions.
-        * FORWARDREF: return annotations as-is if possible, but replace any
-          undefined names with ForwardRef objects. The implementation proposed by
-          PEP 649 relies on language changes that cannot be backported; the
-          typing-extensions implementation simply returns the same result as VALUE.
-        * STRING: return annotations as strings, in a format close to the original
-          source. Again, this behavior cannot be replicated directly in a backport.
-          As an approximation, typing-extensions retrieves the annotations under
-          VALUE semantics and then stringifies them.
-
-        The purpose of this backport is to allow users who would like to use
-        FORWARDREF or STRING semantics once PEP 649 is implemented, but who also
-        want to support earlier Python versions, to simply write:
-
-            typing_extensions.get_annotations(obj, format=Format.FORWARDREF)
-
-        """
-        format = Format(format)
-        if format is Format.VALUE_WITH_FAKE_GLOBALS:
-            raise ValueError(
-                "The VALUE_WITH_FAKE_GLOBALS format is for internal use only"
-            )
-
-        if eval_str and format is not Format.VALUE:
-            raise ValueError("eval_str=True is only supported with format=Format.VALUE")
-
-        if isinstance(obj, type):
-            # class
-            obj_dict = getattr(obj, '__dict__', None)
-            if obj_dict and hasattr(obj_dict, 'get'):
-                ann = obj_dict.get('__annotations__', None)
-                if isinstance(ann, _types.GetSetDescriptorType):
-                    ann = None
-            else:
-                ann = None
-
-            obj_globals = None
-            module_name = getattr(obj, '__module__', None)
-            if module_name:
-                module = sys.modules.get(module_name, None)
-                if module:
-                    obj_globals = getattr(module, '__dict__', None)
-            obj_locals = dict(vars(obj))
-            unwrap = obj
-        elif isinstance(obj, _types.ModuleType):
-            # module
-            ann = getattr(obj, '__annotations__', None)
-            obj_globals = obj.__dict__
-            obj_locals = None
-            unwrap = None
-        elif callable(obj):
-            # this includes types.Function, types.BuiltinFunctionType,
-            # types.BuiltinMethodType, functools.partial, functools.singledispatch,
-            # "class funclike" from Lib/test/test_inspect... on and on it goes.
-            ann = getattr(obj, '__annotations__', None)
-            obj_globals = getattr(obj, '__globals__', None)
-            obj_locals = None
-            unwrap = obj
-        elif hasattr(obj, '__annotations__'):
-            ann = obj.__annotations__
-            obj_globals = obj_locals = unwrap = None
-        else:
-            raise TypeError(f"{obj!r} is not a module, class, or callable.")
-
-        if ann is None:
-            return {}
-
-        if not isinstance(ann, dict):
-            raise ValueError(f"{obj!r}.__annotations__ is neither a dict nor None")
-
-        if not ann:
-            return {}
-
-        if not eval_str:
-            if format is Format.STRING:
-                return {
-                    key: value if isinstance(value, str) else typing._type_repr(value)
-                    for key, value in ann.items()
-                }
-            return dict(ann)
-
-        if unwrap is not None:
-            while True:
-                if hasattr(unwrap, '__wrapped__'):
-                    unwrap = unwrap.__wrapped__
-                    continue
-                if isinstance(unwrap, functools.partial):
-                    unwrap = unwrap.func
-                    continue
-                break
-            if hasattr(unwrap, "__globals__"):
-                obj_globals = unwrap.__globals__
-
-        if globals is None:
-            globals = obj_globals
-        if locals is None:
-            locals = obj_locals or {}
-
-        # "Inject" type parameters into the local namespace
-        # (unless they are shadowed by assignments *in* the local namespace),
-        # as a way of emulating annotation scopes when calling `eval()`
-        if type_params := getattr(obj, "__type_params__", ()):
-            locals = {param.__name__: param for param in type_params} | locals
-
-        return_value = {key:
-            value if not isinstance(value, str) else eval(value, globals, locals)
-            for key, value in ann.items() }
-        return return_value
-
-
-if hasattr(typing, "evaluate_forward_ref"):
-    evaluate_forward_ref = typing.evaluate_forward_ref
-else:
-    # Implements annotationlib.ForwardRef.evaluate
-    def _eval_with_owner(
-        forward_ref, *, owner=None, globals=None, locals=None, type_params=None
-    ):
-        if forward_ref.__forward_evaluated__:
-            return forward_ref.__forward_value__
-        if getattr(forward_ref, "__cell__", None) is not None:
-            try:
-                value = forward_ref.__cell__.cell_contents
-            except ValueError:
-                pass
-            else:
-                forward_ref.__forward_evaluated__ = True
-                forward_ref.__forward_value__ = value
-                return value
-        if owner is None:
-            owner = getattr(forward_ref, "__owner__", None)
-
-        if (
-            globals is None
-            and getattr(forward_ref, "__forward_module__", None) is not None
-        ):
-            globals = getattr(
-                sys.modules.get(forward_ref.__forward_module__, None), "__dict__", None
-            )
-        if globals is None:
-            globals = getattr(forward_ref, "__globals__", None)
-        if globals is None:
-            if isinstance(owner, type):
-                module_name = getattr(owner, "__module__", None)
-                if module_name:
-                    module = sys.modules.get(module_name, None)
-                    if module:
-                        globals = getattr(module, "__dict__", None)
-            elif isinstance(owner, _types.ModuleType):
-                globals = getattr(owner, "__dict__", None)
-            elif callable(owner):
-                globals = getattr(owner, "__globals__", None)
-
-        # If we pass None to eval() below, the globals of this module are used.
-        if globals is None:
-            globals = {}
-
-        if locals is None:
-            locals = {}
-            if isinstance(owner, type):
-                locals.update(vars(owner))
-
-        if type_params is None and owner is not None:
-            # "Inject" type parameters into the local namespace
-            # (unless they are shadowed by assignments *in* the local namespace),
-            # as a way of emulating annotation scopes when calling `eval()`
-            type_params = getattr(owner, "__type_params__", None)
-
-        # Type parameters exist in their own scope, which is logically
-        # between the locals and the globals. We simulate this by adding
-        # them to the globals.
-        if type_params is not None:
-            globals = dict(globals)
-            for param in type_params:
-                globals[param.__name__] = param
-
-        arg = forward_ref.__forward_arg__
-        if arg.isidentifier() and not keyword.iskeyword(arg):
-            if arg in locals:
-                value = locals[arg]
-            elif arg in globals:
-                value = globals[arg]
-            elif hasattr(builtins, arg):
-                return getattr(builtins, arg)
-            else:
-                raise NameError(arg)
-        else:
-            code = forward_ref.__forward_code__
-            value = eval(code, globals, locals)
-        forward_ref.__forward_evaluated__ = True
-        forward_ref.__forward_value__ = value
-        return value
-
-    def evaluate_forward_ref(
-        forward_ref,
-        *,
-        owner=None,
-        globals=None,
-        locals=None,
-        type_params=None,
-        format=None,
-        _recursive_guard=frozenset(),
-    ):
-        """Evaluate a forward reference as a type hint.
-
-        This is similar to calling the ForwardRef.evaluate() method,
-        but unlike that method, evaluate_forward_ref() also:
-
-        * Recursively evaluates forward references nested within the type hint.
-        * Rejects certain objects that are not valid type hints.
-        * Replaces type hints that evaluate to None with types.NoneType.
-        * Supports the *FORWARDREF* and *STRING* formats.
-
-        *forward_ref* must be an instance of ForwardRef. *owner*, if given,
-        should be the object that holds the annotations that the forward reference
-        derived from, such as a module, class object, or function. It is used to
-        infer the namespaces to use for looking up names. *globals* and *locals*
-        can also be explicitly given to provide the global and local namespaces.
-        *type_params* is a tuple of type parameters that are in scope when
-        evaluating the forward reference. This parameter must be provided (though
-        it may be an empty tuple) if *owner* is not given and the forward reference
-        does not already have an owner set. *format* specifies the format of the
-        annotation and is a member of the annotationlib.Format enum.
-
-        """
-        if format == Format.STRING:
-            return forward_ref.__forward_arg__
-        if forward_ref.__forward_arg__ in _recursive_guard:
-            return forward_ref
-
-        # Evaluate the forward reference
-        try:
-            value = _eval_with_owner(
-                forward_ref,
-                owner=owner,
-                globals=globals,
-                locals=locals,
-                type_params=type_params,
-            )
-        except NameError:
-            if format == Format.FORWARDREF:
-                return forward_ref
-            else:
-                raise
-
-        if isinstance(value, str):
-            value = ForwardRef(value)
-
-        # Recursively evaluate the type
-        if isinstance(value, ForwardRef):
-            if getattr(value, "__forward_module__", True) is not None:
-                globals = None
-            return evaluate_forward_ref(
-                value,
-                globals=globals,
-                locals=locals,
-                 type_params=type_params, owner=owner,
-                _recursive_guard=_recursive_guard, format=format
-            )
-        if sys.version_info < (3, 12, 5) and type_params:
-            # Make use of type_params
-            locals = dict(locals) if locals else {}
-            for tvar in type_params:
-                if tvar.__name__ not in locals:  # lets not overwrite something present
-                    locals[tvar.__name__] = tvar
-        if sys.version_info < (3, 12, 5):
-            return typing._eval_type(
-                value,
-                globals,
-                locals,
-                recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
-            )
-        else:
-            return typing._eval_type(
-                value,
-                globals,
-                locals,
-                type_params,
-                recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},
-            )
-
-
-if sys.version_info >= (3, 14, 0, "beta"):
-    type_repr = annotationlib.type_repr
-else:
-    def type_repr(value):
-        """Convert a Python value to a format suitable for use with the STRING format.
-
-        This is intended as a helper for tools that support the STRING format but do
-        not have access to the code that originally produced the annotations. It uses
-        repr() for most objects.
-
-        """
-        if isinstance(value, (type, _types.FunctionType, _types.BuiltinFunctionType)):
-            if value.__module__ == "builtins":
-                return value.__qualname__
-            return f"{value.__module__}.{value.__qualname__}"
-        if value is ...:
-            return "..."
-        return repr(value)
-
-
-# Aliases for items that are in typing in all supported versions.
-# We use hasattr() checks so this library will continue to import on
-# future versions of Python that may remove these names.
-_typing_names = [
-    "AbstractSet",
-    "AnyStr",
-    "BinaryIO",
-    "Callable",
-    "Collection",
-    "Container",
-    "Dict",
-    "FrozenSet",
-    "Hashable",
-    "IO",
-    "ItemsView",
-    "Iterable",
-    "Iterator",
-    "KeysView",
-    "List",
-    "Mapping",
-    "MappingView",
-    "Match",
-    "MutableMapping",
-    "MutableSequence",
-    "MutableSet",
-    "Optional",
-    "Pattern",
-    "Reversible",
-    "Sequence",
-    "Set",
-    "Sized",
-    "TextIO",
-    "Tuple",
-    "Union",
-    "ValuesView",
-    "cast",
-    "no_type_check",
-    # This is private, but it was defined by typing_extensions for a long time
-    # and some users rely on it.
-    "_AnnotatedAlias",
-]
-
-# Breakpoint: https://github.com/python/cpython/pull/133602
-if sys.version_info < (3, 15, 0):
-    _typing_names.append("no_type_check_decorator")
-    __all__.append("no_type_check_decorator")
-
-globals().update(
-    {name: getattr(typing, name) for name in _typing_names if hasattr(typing, name)}
-)
-# These are defined unconditionally because they are used in
-# typing-extensions itself.
-Generic = typing.Generic
-ForwardRef = typing.ForwardRef
-Annotated = typing.Annotated
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt
deleted file mode 100644
index e6183d0276b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3.LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2008-2020 Andrey Petrov and contributors.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py
deleted file mode 100644
index 3fe782c8a45..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/__init__.py
+++ /dev/null
@@ -1,211 +0,0 @@
-"""
-Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
-"""
-
-from __future__ import annotations
-
-# Set default logging handler to avoid "No handler found" warnings.
-import logging
-import sys
-import typing
-import warnings
-from logging import NullHandler
-
-from . import exceptions
-from ._base_connection import _TYPE_BODY
-from ._collections import HTTPHeaderDict
-from ._version import __version__
-from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url
-from .filepost import _TYPE_FIELDS, encode_multipart_formdata
-from .poolmanager import PoolManager, ProxyManager, proxy_from_url
-from .response import BaseHTTPResponse, HTTPResponse
-from .util.request import make_headers
-from .util.retry import Retry
-from .util.timeout import Timeout
-
-# Ensure that Python is compiled with OpenSSL 1.1.1+
-# If the 'ssl' module isn't available at all that's
-# fine, we only care if the module is available.
-try:
-    import ssl
-except ImportError:
-    pass
-else:
-    if not ssl.OPENSSL_VERSION.startswith("OpenSSL "):  # Defensive:
-        warnings.warn(
-            "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
-            f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
-            "See: https://github.com/urllib3/urllib3/issues/3020",
-            exceptions.NotOpenSSLWarning,
-        )
-    elif ssl.OPENSSL_VERSION_INFO < (1, 1, 1):  # Defensive:
-        raise ImportError(
-            "urllib3 v2 only supports OpenSSL 1.1.1+, currently "
-            f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. "
-            "See: https://github.com/urllib3/urllib3/issues/2168"
-        )
-
-__author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
-__license__ = "MIT"
-__version__ = __version__
-
-__all__ = (
-    "HTTPConnectionPool",
-    "HTTPHeaderDict",
-    "HTTPSConnectionPool",
-    "PoolManager",
-    "ProxyManager",
-    "HTTPResponse",
-    "Retry",
-    "Timeout",
-    "add_stderr_logger",
-    "connection_from_url",
-    "disable_warnings",
-    "encode_multipart_formdata",
-    "make_headers",
-    "proxy_from_url",
-    "request",
-    "BaseHTTPResponse",
-)
-
-logging.getLogger(__name__).addHandler(NullHandler())
-
-
-def add_stderr_logger(
-    level: int = logging.DEBUG,
-) -> logging.StreamHandler[typing.TextIO]:
-    """
-    Helper for quickly adding a StreamHandler to the logger. Useful for
-    debugging.
-
-    Returns the handler after adding it.
-    """
-    # This method needs to be in this __init__.py to get the __name__ correct
-    # even if urllib3 is vendored within another package.
-    logger = logging.getLogger(__name__)
-    handler = logging.StreamHandler()
-    handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
-    logger.addHandler(handler)
-    logger.setLevel(level)
-    logger.debug("Added a stderr logging handler to logger: %s", __name__)
-    return handler
-
-
-# ... Clean up.
-del NullHandler
-
-
-# All warning filters *must* be appended unless you're really certain that they
-# shouldn't be: otherwise, it's very hard for users to use most Python
-# mechanisms to silence them.
-# SecurityWarning's always go off by default.
-warnings.simplefilter("always", exceptions.SecurityWarning, append=True)
-# InsecurePlatformWarning's don't vary between requests, so we keep it default.
-warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True)
-
-
-def disable_warnings(category: type[Warning] = exceptions.HTTPWarning) -> None:
-    """
-    Helper for quickly disabling all urllib3 warnings.
-    """
-    warnings.simplefilter("ignore", category)
-
-
-_DEFAULT_POOL = PoolManager()
-
-
-def request(
-    method: str,
-    url: str,
-    *,
-    body: _TYPE_BODY | None = None,
-    fields: _TYPE_FIELDS | None = None,
-    headers: typing.Mapping[str, str] | None = None,
-    preload_content: bool | None = True,
-    decode_content: bool | None = True,
-    redirect: bool | None = True,
-    retries: Retry | bool | int | None = None,
-    timeout: Timeout | float | int | None = 3,
-    json: typing.Any | None = None,
-) -> BaseHTTPResponse:
-    """
-    A convenience, top-level request method. It uses a module-global ``PoolManager`` instance.
-    Therefore, its side effects could be shared across dependencies relying on it.
-    To avoid side effects create a new ``PoolManager`` instance and use it instead.
-    The method does not accept low-level ``**urlopen_kw`` keyword arguments.
-
-    :param method:
-        HTTP request method (such as GET, POST, PUT, etc.)
-
-    :param url:
-        The URL to perform the request on.
-
-    :param body:
-        Data to send in the request body, either :class:`str`, :class:`bytes`,
-        an iterable of :class:`str`/:class:`bytes`, or a file-like object.
-
-    :param fields:
-        Data to encode and send in the request body.
-
-    :param headers:
-        Dictionary of custom headers to send, such as User-Agent,
-        If-None-Match, etc.
-
-    :param bool preload_content:
-        If True, the response's body will be preloaded into memory.
-
-    :param bool decode_content:
-        If True, will attempt to decode the body based on the
-        'content-encoding' header.
-
-    :param redirect:
-        If True, automatically handle redirects (status codes 301, 302,
-        303, 307, 308). Each redirect counts as a retry. Disabling retries
-        will disable redirect, too.
-
-    :param retries:
-        Configure the number of retries to allow before raising a
-        :class:`~urllib3.exceptions.MaxRetryError` exception.
-
-        If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a
-        :class:`~urllib3.util.retry.Retry` object for fine-grained control
-        over different types of retries.
-        Pass an integer number to retry connection errors that many times,
-        but no other types of errors. Pass zero to never retry.
-
-        If ``False``, then retries are disabled and any exception is raised
-        immediately. Also, instead of raising a MaxRetryError on redirects,
-        the redirect response will be returned.
-
-    :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
-
-    :param timeout:
-        If specified, overrides the default timeout for this one
-        request. It may be a float (in seconds) or an instance of
-        :class:`urllib3.util.Timeout`.
-
-    :param json:
-        Data to encode and send as JSON with UTF-encoded in the request body.
-        The ``"Content-Type"`` header will be set to ``"application/json"``
-        unless specified otherwise.
-    """
-
-    return _DEFAULT_POOL.request(
-        method,
-        url,
-        body=body,
-        fields=fields,
-        headers=headers,
-        preload_content=preload_content,
-        decode_content=decode_content,
-        redirect=redirect,
-        retries=retries,
-        timeout=timeout,
-        json=json,
-    )
-
-
-if sys.platform == "emscripten":
-    from .contrib.emscripten import inject_into_urllib3  # noqa: 401
-
-    inject_into_urllib3()
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py
deleted file mode 100644
index 992ec1657a9..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_base_connection.py
+++ /dev/null
@@ -1,167 +0,0 @@
-from __future__ import annotations
-
-import typing
-
-from .util.connection import _TYPE_SOCKET_OPTIONS
-from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT
-from .util.url import Url
-
-_TYPE_BODY = typing.Union[
-    bytes, typing.IO[typing.Any], typing.Iterable[bytes | str], str
-]
-
-
-class ProxyConfig(typing.NamedTuple):
-    ssl_context: ssl.SSLContext | None
-    use_forwarding_for_https: bool
-    assert_hostname: None | str | typing.Literal[False]
-    assert_fingerprint: str | None
-
-
-class _ResponseOptions(typing.NamedTuple):
-    # TODO: Remove this in favor of a better
-    # HTTP request/response lifecycle tracking.
-    request_method: str
-    request_url: str
-    preload_content: bool
-    decode_content: bool
-    enforce_content_length: bool
-
-
-if typing.TYPE_CHECKING:
-    import ssl
-    from typing import Protocol
-
-    from .response import BaseHTTPResponse
-
-    class BaseHTTPConnection(Protocol):
-        default_port: typing.ClassVar[int]
-        default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
-
-        host: str
-        port: int
-        timeout: None | (
-            float
-        )  # Instance doesn't store _DEFAULT_TIMEOUT, must be resolved.
-        blocksize: int
-        source_address: tuple[str, int] | None
-        socket_options: _TYPE_SOCKET_OPTIONS | None
-
-        proxy: Url | None
-        proxy_config: ProxyConfig | None
-
-        is_verified: bool
-        proxy_is_verified: bool | None
-
-        def __init__(
-            self,
-            host: str,
-            port: int | None = None,
-            *,
-            timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-            source_address: tuple[str, int] | None = None,
-            blocksize: int = 8192,
-            socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
-            proxy: Url | None = None,
-            proxy_config: ProxyConfig | None = None,
-        ) -> None: ...
-
-        def set_tunnel(
-            self,
-            host: str,
-            port: int | None = None,
-            headers: typing.Mapping[str, str] | None = None,
-            scheme: str = "http",
-        ) -> None: ...
-
-        def connect(self) -> None: ...
-
-        def request(
-            self,
-            method: str,
-            url: str,
-            body: _TYPE_BODY | None = None,
-            headers: typing.Mapping[str, str] | None = None,
-            # We know *at least* botocore is depending on the order of the
-            # first 3 parameters so to be safe we only mark the later ones
-            # as keyword-only to ensure we have space to extend.
-            *,
-            chunked: bool = False,
-            preload_content: bool = True,
-            decode_content: bool = True,
-            enforce_content_length: bool = True,
-        ) -> None: ...
-
-        def getresponse(self) -> BaseHTTPResponse: ...
-
-        def close(self) -> None: ...
-
-        @property
-        def is_closed(self) -> bool:
-            """Whether the connection either is brand new or has been previously closed.
-            If this property is True then both ``is_connected`` and ``has_connected_to_proxy``
-            properties must be False.
-            """
-
-        @property
-        def is_connected(self) -> bool:
-            """Whether the connection is actively connected to any origin (proxy or target)"""
-
-        @property
-        def has_connected_to_proxy(self) -> bool:
-            """Whether the connection has successfully connected to its proxy.
-            This returns False if no proxy is in use. Used to determine whether
-            errors are coming from the proxy layer or from tunnelling to the target origin.
-            """
-
-    class BaseHTTPSConnection(BaseHTTPConnection, Protocol):
-        default_port: typing.ClassVar[int]
-        default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS]
-
-        # Certificate verification methods
-        cert_reqs: int | str | None
-        assert_hostname: None | str | typing.Literal[False]
-        assert_fingerprint: str | None
-        ssl_context: ssl.SSLContext | None
-
-        # Trusted CAs
-        ca_certs: str | None
-        ca_cert_dir: str | None
-        ca_cert_data: None | str | bytes
-
-        # TLS version
-        ssl_minimum_version: int | None
-        ssl_maximum_version: int | None
-        ssl_version: int | str | None  # Deprecated
-
-        # Client certificates
-        cert_file: str | None
-        key_file: str | None
-        key_password: str | None
-
-        def __init__(
-            self,
-            host: str,
-            port: int | None = None,
-            *,
-            timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-            source_address: tuple[str, int] | None = None,
-            blocksize: int = 16384,
-            socket_options: _TYPE_SOCKET_OPTIONS | None = ...,
-            proxy: Url | None = None,
-            proxy_config: ProxyConfig | None = None,
-            cert_reqs: int | str | None = None,
-            assert_hostname: None | str | typing.Literal[False] = None,
-            assert_fingerprint: str | None = None,
-            server_hostname: str | None = None,
-            ssl_context: ssl.SSLContext | None = None,
-            ca_certs: str | None = None,
-            ca_cert_dir: str | None = None,
-            ca_cert_data: None | str | bytes = None,
-            ssl_minimum_version: int | None = None,
-            ssl_maximum_version: int | None = None,
-            ssl_version: int | str | None = None,  # Deprecated
-            cert_file: str | None = None,
-            key_file: str | None = None,
-            key_password: str | None = None,
-        ) -> None: ...
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py
deleted file mode 100644
index b62abb5ffcd..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_collections.py
+++ /dev/null
@@ -1,490 +0,0 @@
-from __future__ import annotations
-
-import typing
-from collections import OrderedDict
-from enum import Enum, auto
-from threading import RLock
-
-if typing.TYPE_CHECKING:
-    # We can only import Protocol if TYPE_CHECKING because it's a development
-    # dependency, and is not available at runtime.
-    from typing import Protocol
-
-    from opentelemetry.agent._vendor.typing_extensions import Self
-
-    class HasGettableStringKeys(Protocol):
-        def keys(self) -> typing.Iterator[str]: ...
-
-        def __getitem__(self, key: str) -> str: ...
-
-
-__all__ = ["RecentlyUsedContainer", "HTTPHeaderDict"]
-
-
-# Key type
-_KT = typing.TypeVar("_KT")
-# Value type
-_VT = typing.TypeVar("_VT")
-# Default type
-_DT = typing.TypeVar("_DT")
-
-ValidHTTPHeaderSource = typing.Union[
-    "HTTPHeaderDict",
-    typing.Mapping[str, str],
-    typing.Iterable[tuple[str, str]],
-    "HasGettableStringKeys",
-]
-
-
-class _Sentinel(Enum):
-    not_passed = auto()
-
-
-def ensure_can_construct_http_header_dict(
-    potential: object,
-) -> ValidHTTPHeaderSource | None:
-    if isinstance(potential, HTTPHeaderDict):
-        return potential
-    elif isinstance(potential, typing.Mapping):
-        # Full runtime checking of the contents of a Mapping is expensive, so for the
-        # purposes of typechecking, we assume that any Mapping is the right shape.
-        return typing.cast(typing.Mapping[str, str], potential)
-    elif isinstance(potential, typing.Iterable):
-        # Similarly to Mapping, full runtime checking of the contents of an Iterable is
-        # expensive, so for the purposes of typechecking, we assume that any Iterable
-        # is the right shape.
-        return typing.cast(typing.Iterable[tuple[str, str]], potential)
-    elif hasattr(potential, "keys") and hasattr(potential, "__getitem__"):
-        return typing.cast("HasGettableStringKeys", potential)
-    else:
-        return None
-
-
-class RecentlyUsedContainer(typing.Generic[_KT, _VT], typing.MutableMapping[_KT, _VT]):
-    """
-    Provides a thread-safe dict-like container which maintains up to
-    ``maxsize`` keys while throwing away the least-recently-used keys beyond
-    ``maxsize``.
-
-    :param maxsize:
-        Maximum number of recent elements to retain.
-
-    :param dispose_func:
-        Every time an item is evicted from the container,
-        ``dispose_func(value)`` is called.  Callback which will get called
-    """
-
-    _container: typing.OrderedDict[_KT, _VT]
-    _maxsize: int
-    dispose_func: typing.Callable[[_VT], None] | None
-    lock: RLock
-
-    def __init__(
-        self,
-        maxsize: int = 10,
-        dispose_func: typing.Callable[[_VT], None] | None = None,
-    ) -> None:
-        super().__init__()
-        self._maxsize = maxsize
-        self.dispose_func = dispose_func
-        self._container = OrderedDict()
-        self.lock = RLock()
-
-    def __getitem__(self, key: _KT) -> _VT:
-        # Re-insert the item, moving it to the end of the eviction line.
-        with self.lock:
-            item = self._container.pop(key)
-            self._container[key] = item
-            return item
-
-    def __setitem__(self, key: _KT, value: _VT) -> None:
-        evicted_item = None
-        with self.lock:
-            # Possibly evict the existing value of 'key'
-            try:
-                # If the key exists, we'll overwrite it, which won't change the
-                # size of the pool. Because accessing a key should move it to
-                # the end of the eviction line, we pop it out first.
-                evicted_item = key, self._container.pop(key)
-                self._container[key] = value
-            except KeyError:
-                # When the key does not exist, we insert the value first so that
-                # evicting works in all cases, including when self._maxsize is 0
-                self._container[key] = value
-                if len(self._container) > self._maxsize:
-                    # If we didn't evict an existing value, and we've hit our maximum
-                    # size, then we have to evict the least recently used item from
-                    # the beginning of the container.
-                    evicted_item = self._container.popitem(last=False)
-
-        # After releasing the lock on the pool, dispose of any evicted value.
-        if evicted_item is not None and self.dispose_func:
-            _, evicted_value = evicted_item
-            self.dispose_func(evicted_value)
-
-    def __delitem__(self, key: _KT) -> None:
-        with self.lock:
-            value = self._container.pop(key)
-
-        if self.dispose_func:
-            self.dispose_func(value)
-
-    def __len__(self) -> int:
-        with self.lock:
-            return len(self._container)
-
-    def __iter__(self) -> typing.NoReturn:
-        raise NotImplementedError(
-            "Iteration over this class is unlikely to be threadsafe."
-        )
-
-    def clear(self) -> None:
-        with self.lock:
-            # Copy pointers to all values, then wipe the mapping
-            values = list(self._container.values())
-            self._container.clear()
-
-        if self.dispose_func:
-            for value in values:
-                self.dispose_func(value)
-
-    def keys(self) -> set[_KT]:  # type: ignore[override]
-        with self.lock:
-            return set(self._container.keys())
-
-
-class HTTPHeaderDictItemView(set[tuple[str, str]]):
-    """
-    HTTPHeaderDict is unusual for a Mapping[str, str] in that it has two modes of
-    address.
-
-    If we directly try to get an item with a particular name, we will get a string
-    back that is the concatenated version of all the values:
-
-    >>> d['X-Header-Name']
-    'Value1, Value2, Value3'
-
-    However, if we iterate over an HTTPHeaderDict's items, we will optionally combine
-    these values based on whether combine=True was called when building up the dictionary
-
-    >>> d = HTTPHeaderDict({"A": "1", "B": "foo"})
-    >>> d.add("A", "2", combine=True)
-    >>> d.add("B", "bar")
-    >>> list(d.items())
-    [
-        ('A', '1, 2'),
-        ('B', 'foo'),
-        ('B', 'bar'),
-    ]
-
-    This class conforms to the interface required by the MutableMapping ABC while
-    also giving us the nonstandard iteration behavior we want; items with duplicate
-    keys, ordered by time of first insertion.
-    """
-
-    _headers: HTTPHeaderDict
-
-    def __init__(self, headers: HTTPHeaderDict) -> None:
-        self._headers = headers
-
-    def __len__(self) -> int:
-        return len(list(self._headers.iteritems()))
-
-    def __iter__(self) -> typing.Iterator[tuple[str, str]]:
-        return self._headers.iteritems()
-
-    def __contains__(self, item: object) -> bool:
-        if isinstance(item, tuple) and len(item) == 2:
-            passed_key, passed_val = item
-            if isinstance(passed_key, str) and isinstance(passed_val, str):
-                return self._headers._has_value_for_header(passed_key, passed_val)
-        return False
-
-
-class HTTPHeaderDict(typing.MutableMapping[str, str]):
-    """
-    :param headers:
-        An iterable of field-value pairs. Must not contain multiple field names
-        when compared case-insensitively.
-
-    :param kwargs:
-        Additional field-value pairs to pass in to ``dict.update``.
-
-    A ``dict`` like container for storing HTTP Headers.
-
-    Field names are stored and compared case-insensitively in compliance with
-    RFC 7230. Iteration provides the first case-sensitive key seen for each
-    case-insensitive pair.
-
-    Using ``__setitem__`` syntax overwrites fields that compare equal
-    case-insensitively in order to maintain ``dict``'s api. For fields that
-    compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
-    in a loop.
-
-    If multiple fields that are equal case-insensitively are passed to the
-    constructor or ``.update``, the behavior is undefined and some will be
-    lost.
-
-    >>> headers = HTTPHeaderDict()
-    >>> headers.add('Set-Cookie', 'foo=bar')
-    >>> headers.add('set-cookie', 'baz=quxx')
-    >>> headers['content-length'] = '7'
-    >>> headers['SET-cookie']
-    'foo=bar, baz=quxx'
-    >>> headers['Content-Length']
-    '7'
-    """
-
-    _container: typing.MutableMapping[str, list[str]]
-
-    def __init__(self, headers: ValidHTTPHeaderSource | None = None, **kwargs: str):
-        super().__init__()
-        self._container = {}  # 'dict' is insert-ordered
-        if headers is not None:
-            if isinstance(headers, HTTPHeaderDict):
-                self._copy_from(headers)
-            else:
-                self.extend(headers)
-        if kwargs:
-            self.extend(kwargs)
-
-    def __setitem__(self, key: str, val: str) -> None:
-        # avoid a bytes/str comparison by decoding before httplib
-        if isinstance(key, bytes):
-            key = key.decode("latin-1")
-        self._container[key.lower()] = [key, val]
-
-    def __getitem__(self, key: str) -> str:
-        if isinstance(key, bytes):
-            key = key.decode("latin-1")
-        val = self._container[key.lower()]
-        return ", ".join(val[1:])
-
-    def __delitem__(self, key: str) -> None:
-        if isinstance(key, bytes):
-            key = key.decode("latin-1")
-        del self._container[key.lower()]
-
-    def __contains__(self, key: object) -> bool:
-        if isinstance(key, bytes):
-            key = key.decode("latin-1")
-        if isinstance(key, str):
-            return key.lower() in self._container
-        return False
-
-    def setdefault(self, key: str, default: str = "") -> str:
-        return super().setdefault(key, default)
-
-    def __eq__(self, other: object) -> bool:
-        maybe_constructable = ensure_can_construct_http_header_dict(other)
-        if maybe_constructable is None:
-            return False
-        else:
-            other_as_http_header_dict = type(self)(maybe_constructable)
-
-        return {k.lower(): v for k, v in self.itermerged()} == {
-            k.lower(): v for k, v in other_as_http_header_dict.itermerged()
-        }
-
-    def __ne__(self, other: object) -> bool:
-        return not self.__eq__(other)
-
-    def __len__(self) -> int:
-        return len(self._container)
-
-    def __iter__(self) -> typing.Iterator[str]:
-        # Only provide the originally cased names
-        for vals in self._container.values():
-            yield vals[0]
-
-    def discard(self, key: str) -> None:
-        try:
-            del self[key]
-        except KeyError:
-            pass
-
-    def add(self, key: str, val: str, *, combine: bool = False) -> None:
-        """Adds a (name, value) pair, doesn't overwrite the value if it already
-        exists.
-
-        If this is called with combine=True, instead of adding a new header value
-        as a distinct item during iteration, this will instead append the value to
-        any existing header value with a comma. If no existing header value exists
-        for the key, then the value will simply be added, ignoring the combine parameter.
-
-        >>> headers = HTTPHeaderDict(foo='bar')
-        >>> headers.add('Foo', 'baz')
-        >>> headers['foo']
-        'bar, baz'
-        >>> list(headers.items())
-        [('foo', 'bar'), ('foo', 'baz')]
-        >>> headers.add('foo', 'quz', combine=True)
-        >>> list(headers.items())
-        [('foo', 'bar, baz, quz')]
-        """
-        # avoid a bytes/str comparison by decoding before httplib
-        if isinstance(key, bytes):
-            key = key.decode("latin-1")
-        key_lower = key.lower()
-        new_vals = [key, val]
-        # Keep the common case aka no item present as fast as possible
-        vals = self._container.setdefault(key_lower, new_vals)
-        if new_vals is not vals:
-            # if there are values here, then there is at least the initial
-            # key/value pair
-            assert len(vals) >= 2
-            if combine:
-                vals[-1] = vals[-1] + ", " + val
-            else:
-                vals.append(val)
-
-    def extend(self, *args: ValidHTTPHeaderSource, **kwargs: str) -> None:
-        """Generic import function for any type of header-like object.
-        Adapted version of MutableMapping.update in order to insert items
-        with self.add instead of self.__setitem__
-        """
-        if len(args) > 1:
-            raise TypeError(
-                f"extend() takes at most 1 positional arguments ({len(args)} given)"
-            )
-        other = args[0] if len(args) >= 1 else ()
-
-        if isinstance(other, HTTPHeaderDict):
-            for key, val in other.iteritems():
-                self.add(key, val)
-        elif isinstance(other, typing.Mapping):
-            for key, val in other.items():
-                self.add(key, val)
-        elif isinstance(other, typing.Iterable):
-            for key, value in other:
-                self.add(key, value)
-        elif hasattr(other, "keys") and hasattr(other, "__getitem__"):
-            # THIS IS NOT A TYPESAFE BRANCH
-            # In this branch, the object has a `keys` attr but is not a Mapping or any of
-            # the other types indicated in the method signature. We do some stuff with
-            # it as though it partially implements the Mapping interface, but we're not
-            # doing that stuff safely AT ALL.
-            for key in other.keys():
-                self.add(key, other[key])
-
-        for key, value in kwargs.items():
-            self.add(key, value)
-
-    @typing.overload
-    def getlist(self, key: str) -> list[str]: ...
-
-    @typing.overload
-    def getlist(self, key: str, default: _DT) -> list[str] | _DT: ...
-
-    def getlist(
-        self, key: str, default: _Sentinel | _DT = _Sentinel.not_passed
-    ) -> list[str] | _DT:
-        """Returns a list of all the values for the named field. Returns an
-        empty list if the key doesn't exist."""
-        if isinstance(key, bytes):
-            key = key.decode("latin-1")
-        try:
-            vals = self._container[key.lower()]
-        except KeyError:
-            if default is _Sentinel.not_passed:
-                # _DT is unbound; empty list is instance of List[str]
-                return []
-            # _DT is bound; default is instance of _DT
-            return default
-        else:
-            # _DT may or may not be bound; vals[1:] is instance of List[str], which
-            # meets our external interface requirement of `Union[List[str], _DT]`.
-            return vals[1:]
-
-    def _prepare_for_method_change(self) -> Self:
-        """
-        Remove content-specific header fields before changing the request
-        method to GET or HEAD according to RFC 9110, Section 15.4.
-
-        ``Transfer-Encoding`` goes as well: it frames a request body that is
-        no longer going to be sent.
-        """
-        content_specific_headers = [
-            "Content-Encoding",
-            "Content-Language",
-            "Content-Location",
-            "Content-Type",
-            "Content-Length",
-            "Digest",
-            "Last-Modified",
-            "Transfer-Encoding",
-        ]
-        for header in content_specific_headers:
-            self.discard(header)
-        return self
-
-    # Backwards compatibility for httplib
-    getheaders = getlist
-    getallmatchingheaders = getlist
-    iget = getlist
-
-    # Backwards compatibility for http.cookiejar
-    get_all = getlist
-
-    def __repr__(self) -> str:
-        return f"{type(self).__name__}({dict(self.itermerged())})"
-
-    def _copy_from(self, other: HTTPHeaderDict) -> None:
-        for key in other:
-            val = other.getlist(key)
-            self._container[key.lower()] = [key, *val]
-
-    def copy(self) -> Self:
-        clone = type(self)()
-        clone._copy_from(self)
-        return clone
-
-    def iteritems(self) -> typing.Iterator[tuple[str, str]]:
-        """Iterate over all header lines, including duplicate ones."""
-        for key in self:
-            vals = self._container[key.lower()]
-            for val in vals[1:]:
-                yield vals[0], val
-
-    def itermerged(self) -> typing.Iterator[tuple[str, str]]:
-        """Iterate over all headers, merging duplicate ones together."""
-        for key in self:
-            val = self._container[key.lower()]
-            yield val[0], ", ".join(val[1:])
-
-    def items(self) -> HTTPHeaderDictItemView:  # type: ignore[override]
-        return HTTPHeaderDictItemView(self)
-
-    def _has_value_for_header(self, header_name: str, potential_value: str) -> bool:
-        if header_name in self:
-            return potential_value in self._container[header_name.lower()][1:]
-        return False
-
-    def __ior__(self, other: object) -> HTTPHeaderDict:
-        # Supports extending a header dict in-place using operator |=
-        # combining items with add instead of __setitem__
-        maybe_constructable = ensure_can_construct_http_header_dict(other)
-        if maybe_constructable is None:
-            return NotImplemented
-        self.extend(maybe_constructable)
-        return self
-
-    def __or__(self, other: object) -> Self:
-        # Supports merging header dicts using operator |
-        # combining items with add instead of __setitem__
-        maybe_constructable = ensure_can_construct_http_header_dict(other)
-        if maybe_constructable is None:
-            return NotImplemented
-        result = self.copy()
-        result.extend(maybe_constructable)
-        return result
-
-    def __ror__(self, other: object) -> Self:
-        # Supports merging header dicts using operator | when other is on left side
-        # combining items with add instead of __setitem__
-        maybe_constructable = ensure_can_construct_http_header_dict(other)
-        if maybe_constructable is None:
-            return NotImplemented
-        result = type(self)(maybe_constructable)
-        result.extend(self)
-        return result
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py
deleted file mode 100644
index 297c271bf40..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_request_methods.py
+++ /dev/null
@@ -1,278 +0,0 @@
-from __future__ import annotations
-
-import json as _json
-import typing
-from urllib.parse import urlencode
-
-from ._base_connection import _TYPE_BODY
-from ._collections import HTTPHeaderDict
-from .filepost import _TYPE_FIELDS, encode_multipart_formdata
-from .response import BaseHTTPResponse
-
-__all__ = ["RequestMethods"]
-
-_TYPE_ENCODE_URL_FIELDS = typing.Union[
-    typing.Sequence[tuple[str, typing.Union[str, bytes]]],
-    typing.Mapping[str, typing.Union[str, bytes]],
-]
-
-
-class RequestMethods:
-    """
-    Convenience mixin for classes who implement a :meth:`urlopen` method, such
-    as :class:`urllib3.HTTPConnectionPool` and
-    :class:`urllib3.PoolManager`.
-
-    Provides behavior for making common types of HTTP request methods and
-    decides which type of request field encoding to use.
-
-    Specifically,
-
-    :meth:`.request_encode_url` is for sending requests whose fields are
-    encoded in the URL (such as GET, HEAD, DELETE).
-
-    :meth:`.request_encode_body` is for sending requests whose fields are
-    encoded in the *body* of the request using multipart or www-form-urlencoded
-    (such as for POST, PUT, PATCH).
-
-    :meth:`.request` is for making any kind of request, it will look up the
-    appropriate encoding format and use one of the above two methods to make
-    the request.
-
-    Initializer parameters:
-
-    :param headers:
-        Headers to include with all requests, unless other headers are given
-        explicitly.
-    """
-
-    _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"}
-
-    def __init__(self, headers: typing.Mapping[str, str] | None = None) -> None:
-        self.headers = headers or {}
-
-    def urlopen(
-        self,
-        method: str,
-        url: str,
-        body: _TYPE_BODY | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        encode_multipart: bool = True,
-        multipart_boundary: str | None = None,
-        **kw: typing.Any,
-    ) -> BaseHTTPResponse:  # Abstract
-        raise NotImplementedError(
-            "Classes extending RequestMethods must implement "
-            "their own ``urlopen`` method."
-        )
-
-    def request(
-        self,
-        method: str,
-        url: str,
-        body: _TYPE_BODY | None = None,
-        fields: _TYPE_FIELDS | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        json: typing.Any | None = None,
-        **urlopen_kw: typing.Any,
-    ) -> BaseHTTPResponse:
-        """
-        Make a request using :meth:`urlopen` with the appropriate encoding of
-        ``fields`` based on the ``method`` used.
-
-        This is a convenience method that requires the least amount of manual
-        effort. It can be used in most situations, while still having the
-        option to drop down to more specific methods when necessary, such as
-        :meth:`request_encode_url`, :meth:`request_encode_body`,
-        or even the lowest level :meth:`urlopen`.
-
-        :param method:
-            HTTP request method (such as GET, POST, PUT, etc.)
-
-        :param url:
-            The URL to perform the request on.
-
-        :param body:
-            Data to send in the request body, either :class:`str`, :class:`bytes`,
-            an iterable of :class:`str`/:class:`bytes`, or a file-like object.
-
-        :param fields:
-            Data to encode and send in the URL or request body, depending on ``method``.
-
-        :param headers:
-            Dictionary of custom headers to send, such as User-Agent,
-            If-None-Match, etc. If None, pool headers are used. If provided,
-            these headers completely replace any pool-specific headers.
-
-        :param json:
-            Data to encode and send as JSON with UTF-encoded in the request body.
-            The ``"Content-Type"`` header will be set to ``"application/json"``
-            unless specified otherwise.
-        """
-        method = method.upper()
-
-        if json is not None and body is not None:
-            raise TypeError(
-                "request got values for both 'body' and 'json' parameters which are mutually exclusive"
-            )
-
-        if json is not None:
-            if headers is None:
-                headers = self.headers
-
-            if not ("content-type" in map(str.lower, headers.keys())):
-                headers = HTTPHeaderDict(headers)
-                headers["Content-Type"] = "application/json"
-
-            body = _json.dumps(json, separators=(",", ":"), ensure_ascii=False).encode(
-                "utf-8"
-            )
-
-        if body is not None:
-            urlopen_kw["body"] = body
-
-        if method in self._encode_url_methods:
-            return self.request_encode_url(
-                method,
-                url,
-                fields=fields,  # type: ignore[arg-type]
-                headers=headers,
-                **urlopen_kw,
-            )
-        else:
-            return self.request_encode_body(
-                method, url, fields=fields, headers=headers, **urlopen_kw
-            )
-
-    def request_encode_url(
-        self,
-        method: str,
-        url: str,
-        fields: _TYPE_ENCODE_URL_FIELDS | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        **urlopen_kw: str,
-    ) -> BaseHTTPResponse:
-        """
-        Make a request using :meth:`urlopen` with the ``fields`` encoded in
-        the url. This is useful for request methods like GET, HEAD, DELETE, etc.
-
-        :param method:
-            HTTP request method (such as GET, POST, PUT, etc.)
-
-        :param url:
-            The URL to perform the request on.
-
-        :param fields:
-            Data to encode and send in the URL.
-
-        :param headers:
-            Dictionary of custom headers to send, such as User-Agent,
-            If-None-Match, etc. If None, pool headers are used. If provided,
-            these headers completely replace any pool-specific headers.
-        """
-        if headers is None:
-            headers = self.headers
-
-        extra_kw: dict[str, typing.Any] = {"headers": headers}
-        extra_kw.update(urlopen_kw)
-
-        if fields:
-            url += "?" + urlencode(fields)
-
-        return self.urlopen(method, url, **extra_kw)
-
-    def request_encode_body(
-        self,
-        method: str,
-        url: str,
-        fields: _TYPE_FIELDS | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        encode_multipart: bool = True,
-        multipart_boundary: str | None = None,
-        **urlopen_kw: str,
-    ) -> BaseHTTPResponse:
-        """
-        Make a request using :meth:`urlopen` with the ``fields`` encoded in
-        the body. This is useful for request methods like POST, PUT, PATCH, etc.
-
-        When ``encode_multipart=True`` (default), then
-        :func:`urllib3.encode_multipart_formdata` is used to encode
-        the payload with the appropriate content type. Otherwise
-        :func:`urllib.parse.urlencode` is used with the
-        'application/x-www-form-urlencoded' content type.
-
-        Multipart encoding must be used when posting files, and it's reasonably
-        safe to use it in other times too. However, it may break request
-        signing, such as with OAuth.
-
-        Supports an optional ``fields`` parameter of key/value strings AND
-        key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
-        the MIME type is optional. For example::
-
-            fields = {
-                'foo': 'bar',
-                'fakefile': ('foofile.txt', 'contents of foofile'),
-                'realfile': ('barfile.txt', open('realfile').read()),
-                'typedfile': ('bazfile.bin', open('bazfile').read(),
-                              'image/jpeg'),
-                'nonamefile': 'contents of nonamefile field',
-            }
-
-        When uploading a file, providing a filename (the first parameter of the
-        tuple) is optional but recommended to best mimic behavior of browsers.
-
-        Note that if ``headers`` are supplied, the 'Content-Type' header will
-        be overwritten because it depends on the dynamic random boundary string
-        which is used to compose the body of the request. The random boundary
-        string can be explicitly set with the ``multipart_boundary`` parameter.
-
-        :param method:
-            HTTP request method (such as GET, POST, PUT, etc.)
-
-        :param url:
-            The URL to perform the request on.
-
-        :param fields:
-            Data to encode and send in the request body.
-
-        :param headers:
-            Dictionary of custom headers to send, such as User-Agent,
-            If-None-Match, etc. If None, pool headers are used. If provided,
-            these headers completely replace any pool-specific headers.
-
-        :param encode_multipart:
-            If True, encode the ``fields`` using the multipart/form-data MIME
-            format.
-
-        :param multipart_boundary:
-            If not specified, then a random boundary will be generated using
-            :func:`urllib3.filepost.choose_boundary`.
-        """
-        if headers is None:
-            headers = self.headers
-
-        extra_kw: dict[str, typing.Any] = {"headers": HTTPHeaderDict(headers)}
-        body: bytes | str
-
-        if fields:
-            if "body" in urlopen_kw:
-                raise TypeError(
-                    "request got values for both 'fields' and 'body', can only specify one."
-                )
-
-            if encode_multipart:
-                body, content_type = encode_multipart_formdata(
-                    fields, boundary=multipart_boundary
-                )
-            else:
-                body, content_type = (
-                    urlencode(fields),  # type: ignore[arg-type]
-                    "application/x-www-form-urlencoded",
-                )
-
-            extra_kw["body"] = body
-            extra_kw["headers"].setdefault("Content-Type", content_type)
-
-        extra_kw.update(urlopen_kw)
-
-        return self.urlopen(method, url, **extra_kw)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py
deleted file mode 100644
index 319b966f20a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/_version.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# file generated by vcs-versioning
-# don't change, don't track in version control
-from __future__ import annotations
-
-__all__ = [
-    "__version__",
-    "__version_tuple__",
-    "version",
-    "version_tuple",
-    "__commit_id__",
-    "commit_id",
-]
-
-version: str
-__version__: str
-__version_tuple__: tuple[int | str, ...]
-version_tuple: tuple[int | str, ...]
-commit_id: str | None
-__commit_id__: str | None
-
-__version__ = version = '2.8.0'
-__version_tuple__ = version_tuple = (2, 8, 0)
-
-__commit_id__ = commit_id = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py
deleted file mode 100644
index 3bf3f57ac77..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connection.py
+++ /dev/null
@@ -1,1204 +0,0 @@
-from __future__ import annotations
-
-import datetime
-import http.client
-import logging
-import os
-import re
-import socket
-import sys
-import threading
-import typing
-import warnings
-from http.client import HTTPConnection as _HTTPConnection
-from http.client import HTTPException as HTTPException  # noqa: F401
-from http.client import ResponseNotReady
-from socket import timeout as SocketTimeout
-
-if typing.TYPE_CHECKING:
-    from .response import HTTPResponse
-    from .util.ssl_ import _TYPE_PEER_CERT_RET_DICT
-    from .util.ssltransport import SSLTransport
-
-from ._collections import HTTPHeaderDict
-from .http2 import probe as http2_probe
-from .util.response import assert_header_parsing
-from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT, Timeout
-from .util.util import to_str
-from .util.wait import wait_for_read
-
-try:  # Compiled with SSL?
-    import ssl
-
-    BaseSSLError = ssl.SSLError
-except (ImportError, AttributeError):
-    ssl = None  # type: ignore[assignment]
-
-    class BaseSSLError(BaseException):  # type: ignore[no-redef]
-        pass
-
-
-from ._base_connection import _TYPE_BODY
-from ._base_connection import ProxyConfig as ProxyConfig
-from ._base_connection import _ResponseOptions as _ResponseOptions
-from ._version import __version__
-from .exceptions import (
-    ConnectTimeoutError,
-    HeaderParsingError,
-    NameResolutionError,
-    NewConnectionError,
-    ProxyError,
-    SystemTimeWarning,
-)
-from .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection, ssl_
-from .util.request import body_to_chunks
-from .util.ssl_ import assert_fingerprint as _assert_fingerprint
-from .util.ssl_ import (
-    create_urllib3_context,
-    is_ipaddress,
-    resolve_cert_reqs,
-    resolve_ssl_version,
-    ssl_wrap_socket,
-)
-from .util.ssl_match_hostname import CertificateError, match_hostname
-from .util.url import Url
-
-# Not a no-op, we're adding this to the namespace so it can be imported.
-ConnectionError = ConnectionError
-BrokenPipeError = BrokenPipeError
-
-
-log = logging.getLogger(__name__)
-
-port_by_scheme = {"http": 80, "https": 443}
-
-# When it comes time to update this value as a part of regular maintenance
-# (ie test_recent_date is failing) update it to ~6 months before the current date.
-RECENT_DATE = datetime.date(2025, 1, 1)
-
-_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")
-# Starting the optional OWS match at the beginning of a whitespace run avoids
-# quadratic backtracking for long header values.
-_OBSOLETE_FOLD_RE = re.compile(r"(?:(? str:
-    if "\r\n" not in value:
-        return value
-    return _OBSOLETE_FOLD_RE.sub(" ", value)
-
-
-def _normalize_header_values(
-    message: http.client.HTTPMessage,
-) -> list[tuple[str, str]]:
-    header_items = message.items()
-    headers_changed = False
-    for index, (name, value) in enumerate(header_items):
-        normalized_value = _normalize_header_value(value)
-        if normalized_value != value:
-            header_items[index] = (name, normalized_value)
-            headers_changed = True
-
-    if headers_changed:
-        # Keep the original message in sync for downstream consumers such as
-        # cookie jars while preserving its identity and header ordering.
-        for name, _ in header_items:
-            del message[name]
-        for name, value in header_items:
-            message[name] = value
-
-    return header_items
-
-
-class HTTPConnection(_HTTPConnection):
-    """
-    Based on :class:`http.client.HTTPConnection` but provides an extra constructor
-    backwards-compatibility layer between older and newer Pythons.
-
-    Additional keyword parameters are used to configure attributes of the connection.
-    Accepted parameters include:
-
-    - ``source_address``: Set the source address for the current connection.
-    - ``socket_options``: Set specific options on the underlying socket. If not specified, then
-      defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
-      Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
-
-      For example, if you wish to enable TCP Keep Alive in addition to the defaults,
-      you might pass:
-
-      .. code-block:: python
-
-         HTTPConnection.default_socket_options + [
-             (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
-         ]
-
-      Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).
-    """
-
-    default_port: typing.ClassVar[int] = port_by_scheme["http"]  # type: ignore[misc]
-
-    #: Disable Nagle's algorithm by default.
-    #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]``
-    #:
-    #: Use the ``socket_options`` parameter of :class:`~urllib3.PoolManager`,
-    #: :class:`~urllib3.ProxyManager`, or :class:`~urllib3.HTTPConnectionPool`
-    #: to change this behavior.
-    default_socket_options: typing.ClassVar[
-        typing.Final[connection._TYPE_SOCKET_OPTIONS]
-    ] = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
-
-    #: Whether this connection verifies the host's certificate.
-    is_verified: bool = False
-
-    #: Whether this proxy connection verified the proxy host's certificate.
-    # If no proxy is currently connected to the value will be ``None``.
-    proxy_is_verified: bool | None = None
-
-    blocksize: int
-    source_address: tuple[str, int] | None
-    socket_options: connection._TYPE_SOCKET_OPTIONS | None
-
-    _has_connected_to_proxy: bool
-    _response_options: _ResponseOptions | None
-    _tunnel_host: str | None
-    _tunnel_port: int | None
-    _tunnel_scheme: str | None
-
-    def __init__(
-        self,
-        host: str,
-        port: int | None = None,
-        *,
-        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-        source_address: tuple[str, int] | None = None,
-        blocksize: int = 16384,
-        socket_options: None | (
-            connection._TYPE_SOCKET_OPTIONS
-        ) = default_socket_options,
-        proxy: Url | None = None,
-        proxy_config: ProxyConfig | None = None,
-    ) -> None:
-        super().__init__(
-            host=host,
-            port=port,
-            timeout=Timeout.resolve_default_timeout(timeout),
-            source_address=source_address,
-            blocksize=blocksize,
-        )
-        self.socket_options = socket_options
-        self.proxy = proxy
-        self.proxy_config = proxy_config
-
-        self._has_connected_to_proxy = False
-        self._response_options = None
-        self._tunnel_host: str | None = None
-        self._tunnel_port: int | None = None
-        self._tunnel_scheme: str | None = None
-
-    def __str__(self) -> str:
-        return f"{type(self).__name__}(host={self.host!r}, port={self.port!r})"
-
-    def __repr__(self) -> str:
-        return f"<{self} at {id(self):#x}>"
-
-    @property
-    def host(self) -> str:
-        """
-        Getter method to remove any trailing dots that indicate the hostname is an FQDN.
-
-        In general, SSL certificates don't include the trailing dot indicating a
-        fully-qualified domain name, and thus, they don't validate properly when
-        checked against a domain name that includes the dot. In addition, some
-        servers may not expect to receive the trailing dot when provided.
-
-        However, the hostname with trailing dot is critical to DNS resolution; doing a
-        lookup with the trailing dot will properly only resolve the appropriate FQDN,
-        whereas a lookup without a trailing dot will search the system's search domain
-        list. Thus, it's important to keep the original host around for use only in
-        those cases where it's appropriate (i.e., when doing DNS lookup to establish the
-        actual TCP connection across which we're going to send HTTP requests).
-        """
-        return self._dns_host.rstrip(".")
-
-    @host.setter
-    def host(self, value: str) -> None:
-        """
-        Setter for the `host` property.
-
-        We assume that only urllib3 uses the _dns_host attribute; httplib itself
-        only uses `host`, and it seems reasonable that other libraries follow suit.
-        """
-        self._dns_host = value
-
-    def _new_conn(self) -> socket.socket:
-        """Establish a socket connection and set nodelay settings on it.
-
-        :return: New socket connection.
-        """
-        try:
-            sock = connection.create_connection(
-                (self._dns_host, self.port),
-                self.timeout,
-                source_address=self.source_address,
-                socket_options=self.socket_options,
-            )
-        except socket.gaierror as e:
-            raise NameResolutionError(self.host, self, e) from e
-        except SocketTimeout as e:
-            raise ConnectTimeoutError(
-                self,
-                f"Connection to {self.host} timed out. (connect timeout={self.timeout})",
-            ) from e
-
-        except OSError as e:
-            raise NewConnectionError(
-                self, f"Failed to establish a new connection: {e}"
-            ) from e
-
-        sys.audit("http.client.connect", self, self.host, self.port)
-
-        return sock
-
-    def set_tunnel(
-        self,
-        host: str,
-        port: int | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        scheme: str = "http",
-    ) -> None:
-        if scheme not in ("http", "https"):
-            raise ValueError(
-                f"Invalid proxy scheme for tunneling: {scheme!r}, must be either 'http' or 'https'"
-            )
-        super().set_tunnel(host, port=port, headers=headers)
-        self._tunnel_scheme = scheme
-
-    if sys.version_info < (3, 11, 16) or ((3, 12) <= sys.version_info < (3, 12, 14)):
-        # Taken from python/cpython#100986 which was backported in 3.11.9 and 3.12.3.
-        # When using connection_from_host, host will come without brackets.
-        # With a security patch from python/cpython#146211.
-        def _wrap_ipv6(self, ip: bytes) -> bytes:
-            if b":" in ip and ip[0] != b"["[0]:
-                return b"[" + ip + b"]"
-            return ip
-
-        # Copied from CPython 3.12.13 Lib/http/client.py
-        _is_legal_header_name = staticmethod(re.compile(rb"[^:\s][^:\r\n]*").fullmatch)
-        _is_illegal_header_value = staticmethod(
-            re.compile(rb"\n(?![ \t])|\r(?![ \t\n])").search
-        )
-        _contains_disallowed_url_pchar_re = re.compile("[\x00-\x20\x7f]")
-
-        if sys.version_info < (3, 11, 16):
-            # `_tunnel` copied from 3.11.15 backporting
-            # https://github.com/python/cpython/commit/0d4026432591d43185568dd31cef6a034c4b9261
-            # and https://github.com/python/cpython/commit/6fbc61070fda2ffb8889e77e3b24bca4249ab4d1
-            # plus a fix from https://github.com/python/cpython/commit/56b7100b04e44ea27989242b176beb8f016b2c53
-            def _tunnel(self) -> None:
-                if self._contains_disallowed_url_pchar_re.search(self._tunnel_host):  # type: ignore[arg-type]
-                    raise ValueError(
-                        "Tunnel host can't contain control characters %r"
-                        % (self._tunnel_host,)
-                    )
-                _MAXLINE = http.client._MAXLINE  # type: ignore[attr-defined]
-                connect = b"CONNECT %s:%d HTTP/1.0\r\n" % (  # type: ignore[str-format]
-                    self._wrap_ipv6(self._tunnel_host.encode("ascii")),  # type: ignore[union-attr]
-                    self._tunnel_port,
-                )
-                headers = [connect]
-                for header, value in self._tunnel_headers.items():  # type: ignore[attr-defined]
-                    header_bytes = header.encode("latin-1")
-                    value_bytes = value.encode("latin-1")
-                    if not self._is_legal_header_name(header_bytes):
-                        raise ValueError(f"Invalid header name {header_bytes!r}")
-                    if self._is_illegal_header_value(value_bytes):
-                        raise ValueError(f"Invalid header value {value_bytes!r}")
-                    headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes))
-                headers.append(b"\r\n")
-                # Making a single send() call instead of one per line encourages
-                # the host OS to use a more optimal packet size instead of
-                # potentially emitting a series of small packets.
-                self.send(b"".join(headers))
-                del headers
-
-                response = self.response_class(self.sock, method=self._method)  # type: ignore[attr-defined]
-                try:
-                    version, code, message = response._read_status()  # type: ignore[attr-defined]
-
-                    if code != http.HTTPStatus.OK:
-                        self.close()
-                        raise OSError(
-                            f"Tunnel connection failed: {code} {message.strip()}"
-                        )
-                    while True:
-                        line = response.fp.readline(_MAXLINE + 1)
-                        if len(line) > _MAXLINE:
-                            raise http.client.LineTooLong("header line")
-                        if not line:
-                            # for sites which EOF without sending a trailer
-                            break
-                        if line in (b"\r\n", b"\n", b""):
-                            break
-
-                        if self.debuglevel > 0:
-                            print("header:", line.decode())
-                finally:
-                    response.close()
-
-        elif (3, 12) <= sys.version_info < (3, 12, 14):
-            # `_tunnel` copied from 3.12.13 backporting
-            # https://github.com/python/cpython/commit/23aef575c7629abcd4aaf028ebd226fb41a4b3c8
-            # plus a fix from https://github.com/python/cpython/commit/c00c386faa579ad71196d33408644478488e43ec
-            def _tunnel(self) -> None:  # noqa: F811
-                if self._contains_disallowed_url_pchar_re.search(self._tunnel_host):  # type: ignore[arg-type]
-                    raise ValueError(
-                        "Tunnel host can't contain control characters %r"
-                        % (self._tunnel_host,)
-                    )
-                connect = b"CONNECT %s:%d HTTP/1.1\r\n" % (  # type: ignore[str-format]
-                    self._wrap_ipv6(self._tunnel_host.encode("idna")),  # type: ignore[union-attr]
-                    self._tunnel_port,
-                )
-                headers = [connect]
-                for header, value in self._tunnel_headers.items():  # type: ignore[attr-defined]
-                    header_bytes = header.encode("latin-1")
-                    value_bytes = value.encode("latin-1")
-                    if not self._is_legal_header_name(header_bytes):
-                        raise ValueError(f"Invalid header name {header_bytes!r}")
-                    if self._is_illegal_header_value(value_bytes):
-                        raise ValueError(f"Invalid header value {value_bytes!r}")
-                    headers.append(b"%s: %s\r\n" % (header_bytes, value_bytes))
-                headers.append(b"\r\n")
-                # Making a single send() call instead of one per line encourages
-                # the host OS to use a more optimal packet size instead of
-                # potentially emitting a series of small packets.
-                self.send(b"".join(headers))
-                del headers
-
-                response = self.response_class(self.sock, method=self._method)  # type: ignore[attr-defined]
-                try:
-                    version, code, message = response._read_status()  # type: ignore[attr-defined]
-
-                    self._raw_proxy_headers = http.client._read_headers(response.fp)  # type: ignore[attr-defined]
-
-                    if self.debuglevel > 0:
-                        for header in self._raw_proxy_headers:
-                            print("header:", header.decode())
-
-                    if code != http.HTTPStatus.OK:
-                        self.close()
-                        raise OSError(
-                            f"Tunnel connection failed: {code} {message.strip()}"
-                        )
-
-                finally:
-                    response.close()
-
-    def connect(self) -> None:
-        self.sock = self._new_conn()
-        if self._tunnel_host:
-            # If we're tunneling it means we're connected to our proxy.
-            self._has_connected_to_proxy = True
-
-            # TODO: Fix tunnel so it doesn't depend on self.sock state.
-            self._tunnel()
-
-        # If there's a proxy to be connected to we are fully connected.
-        # This is set twice (once above and here) due to forwarding proxies
-        # not using tunnelling.
-        self._has_connected_to_proxy = bool(self.proxy)
-
-        if self._has_connected_to_proxy:
-            self.proxy_is_verified = False
-
-    @property
-    def is_closed(self) -> bool:
-        return self.sock is None
-
-    @property
-    def is_connected(self) -> bool:
-        if self.sock is None:
-            return False
-        return not wait_for_read(self.sock, timeout=0.0)
-
-    @property
-    def has_connected_to_proxy(self) -> bool:
-        return self._has_connected_to_proxy
-
-    @property
-    def proxy_is_forwarding(self) -> bool:
-        """
-        Return True if a forwarding proxy is configured, else return False
-        """
-        return bool(self.proxy) and self._tunnel_host is None
-
-    @property
-    def proxy_is_tunneling(self) -> bool:
-        """
-        Return True if a tunneling proxy is configured, else return False
-        """
-        return self._tunnel_host is not None
-
-    def close(self) -> None:
-        try:
-            super().close()
-        finally:
-            # Reset all stateful properties so connection
-            # can be re-used without leaking prior configs.
-            self.sock = None
-            self.is_verified = False
-            self.proxy_is_verified = None
-            self._has_connected_to_proxy = False
-            self._response_options = None
-            self._tunnel_host = None
-            self._tunnel_port = None
-            self._tunnel_scheme = None
-
-    def putrequest(
-        self,
-        method: str,
-        url: str,
-        skip_host: bool = False,
-        skip_accept_encoding: bool = False,
-    ) -> None:
-        """"""
-        # Empty docstring because the indentation of CPython's implementation
-        # is broken but we don't want this method in our documentation.
-        match = _CONTAINS_CONTROL_CHAR_RE.search(method)
-        if match:
-            raise ValueError(
-                f"Method cannot contain non-token characters {method!r} (found at least {match.group()!r})"
-            )
-
-        return super().putrequest(
-            method, url, skip_host=skip_host, skip_accept_encoding=skip_accept_encoding
-        )
-
-    def putheader(self, header: str, *values: str) -> None:  # type: ignore[override]
-        """"""
-        if not any(isinstance(v, str) and v == SKIP_HEADER for v in values):
-            super().putheader(header, *values)
-        elif to_str(header.lower()) not in SKIPPABLE_HEADERS:
-            skippable_headers = "', '".join(
-                [str.title(header) for header in sorted(SKIPPABLE_HEADERS)]
-            )
-            raise ValueError(
-                f"urllib3.util.SKIP_HEADER only supports '{skippable_headers}'"
-            )
-
-    # `request` method's signature intentionally violates LSP.
-    # urllib3's API is different from `http.client.HTTPConnection` and the subclassing is only incidental.
-    def request(  # type: ignore[override]
-        self,
-        method: str,
-        url: str,
-        body: _TYPE_BODY | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        *,
-        chunked: bool = False,
-        preload_content: bool = True,
-        decode_content: bool = True,
-        enforce_content_length: bool = True,
-    ) -> None:
-        # Update the inner socket's timeout value to send the request.
-        # This only triggers if the connection is re-used.
-        if self.sock is not None:
-            self.sock.settimeout(self.timeout)
-
-        # Store these values to be fed into the HTTPResponse
-        # object later. TODO: Remove this in favor of a real
-        # HTTP lifecycle mechanism.
-
-        # We have to store these before we call .request()
-        # because sometimes we can still salvage a response
-        # off the wire even if we aren't able to completely
-        # send the request body.
-        self._response_options = _ResponseOptions(
-            request_method=method,
-            request_url=url,
-            preload_content=preload_content,
-            decode_content=decode_content,
-            enforce_content_length=enforce_content_length,
-        )
-
-        if headers is None:
-            headers = {}
-        header_keys = frozenset(to_str(k.lower()) for k in headers)
-        skip_accept_encoding = "accept-encoding" in header_keys
-        skip_host = "host" in header_keys
-        self.putrequest(
-            method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host
-        )
-
-        # Transform the body into an iterable of sendall()-able chunks
-        # and detect if an explicit Content-Length is doable.
-        chunks_and_cl = body_to_chunks(body, method=method, blocksize=self.blocksize)
-        chunks = chunks_and_cl.chunks
-        content_length = chunks_and_cl.content_length
-
-        # When chunked is explicit set to 'True' we respect that.
-        if chunked:
-            if "transfer-encoding" not in header_keys:
-                self.putheader("Transfer-Encoding", "chunked")
-        else:
-            # Detect whether a framing mechanism is already in use. If so
-            # we respect that value, otherwise we pick chunked vs content-length
-            # depending on the type of 'body'.
-            if "content-length" in header_keys:
-                chunked = False
-            elif "transfer-encoding" in header_keys:
-                chunked = True
-
-            # Otherwise we go off the recommendation of 'body_to_chunks()'.
-            else:
-                chunked = False
-                if content_length is None:
-                    if chunks is not None:
-                        chunked = True
-                        self.putheader("Transfer-Encoding", "chunked")
-                else:
-                    self.putheader("Content-Length", str(content_length))
-
-        # Now that framing headers are out of the way we send all the other headers.
-        if "user-agent" not in header_keys:
-            self.putheader("User-Agent", _get_default_user_agent())
-        for header, value in headers.items():
-            self.putheader(header, value)
-        self.endheaders()
-
-        # If we're given a body we start sending that in chunks.
-        if chunks is not None:
-            for chunk in chunks:
-                # Sending empty chunks isn't allowed for TE: chunked
-                # as it indicates the end of the body.
-                if not chunk:
-                    continue
-                if isinstance(chunk, str):
-                    chunk = chunk.encode("utf-8")
-                if chunked:
-                    self.send(b"%x\r\n%b\r\n" % (len(chunk), chunk))
-                else:
-                    self.send(chunk)
-
-        # Regardless of whether we have a body or not, if we're in
-        # chunked mode we want to send an explicit empty chunk.
-        if chunked:
-            self.send(b"0\r\n\r\n")
-
-    def request_chunked(
-        self,
-        method: str,
-        url: str,
-        body: _TYPE_BODY | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-    ) -> None:
-        """
-        Alternative to the common request method, which sends the
-        body with chunked encoding and not as one block
-        """
-        warnings.warn(
-            "HTTPConnection.request_chunked() is deprecated and will be removed "
-            "in urllib3 v3.0. Instead use HTTPConnection.request(..., chunked=True).",
-            category=FutureWarning,
-            stacklevel=2,
-        )
-        self.request(method, url, body=body, headers=headers, chunked=True)
-
-    def getresponse(  # type: ignore[override]
-        self,
-    ) -> HTTPResponse:
-        """
-        Get the response from the server.
-
-        If the HTTPConnection is in the correct state, returns an instance of HTTPResponse or of whatever object is returned by the response_class variable.
-
-        If a request has not been sent or if a previous response has not be handled, ResponseNotReady is raised. If the HTTP response indicates that the connection should be closed, then it will be closed before the response is returned. When the connection is closed, the underlying socket is closed.
-        """
-        # Raise the same error as http.client.HTTPConnection
-        if self._response_options is None:
-            raise ResponseNotReady()
-
-        # Reset this attribute for being used again.
-        resp_options = self._response_options
-        self._response_options = None
-
-        # Since the connection's timeout value may have been updated
-        # we need to set the timeout on the socket.
-        self.sock.settimeout(self.timeout)
-
-        # This is needed here to avoid circular import errors
-        from .response import HTTPResponse
-
-        # Save a reference to the shutdown function before ownership is passed
-        # to httplib_response
-        # TODO should we implement it everywhere?
-        _shutdown = getattr(self.sock, "shutdown", None)
-
-        # Get the response from http.client.HTTPConnection
-        httplib_response = super().getresponse()
-
-        try:
-            assert_header_parsing(httplib_response.msg)
-        except (HeaderParsingError, TypeError) as hpe:
-            log.warning(
-                "Failed to parse headers (url=%s): %s",
-                _url_from_connection(self, resp_options.request_url),
-                hpe,
-                exc_info=True,
-            )
-
-        header_items = _normalize_header_values(httplib_response.msg)
-        headers = HTTPHeaderDict(header_items)
-
-        response = HTTPResponse(
-            body=httplib_response,
-            headers=headers,
-            status=httplib_response.status,
-            version=httplib_response.version,
-            version_string=getattr(self, "_http_vsn_str", "HTTP/?"),
-            reason=httplib_response.reason,
-            preload_content=resp_options.preload_content,
-            decode_content=resp_options.decode_content,
-            original_response=httplib_response,
-            enforce_content_length=resp_options.enforce_content_length,
-            request_method=resp_options.request_method,
-            request_url=resp_options.request_url,
-            sock_shutdown=_shutdown,
-        )
-        return response
-
-
-class HTTPSConnection(HTTPConnection):
-    """
-    Many of the parameters to this constructor are passed to the underlying SSL
-    socket by means of :py:func:`urllib3.util.ssl_wrap_socket`.
-    """
-
-    default_port = port_by_scheme["https"]  # type: ignore[misc]
-
-    cert_reqs: int | str | None = None
-    ca_certs: str | None = None
-    ca_cert_dir: str | None = None
-    ca_cert_data: None | str | bytes = None
-    ssl_version: int | str | None = None
-    ssl_minimum_version: int | None = None
-    ssl_maximum_version: int | None = None
-    assert_fingerprint: str | None = None
-    _connect_callback: typing.Callable[..., None] | None = None
-
-    def __init__(
-        self,
-        host: str,
-        port: int | None = None,
-        *,
-        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-        source_address: tuple[str, int] | None = None,
-        blocksize: int = 16384,
-        socket_options: None | (
-            connection._TYPE_SOCKET_OPTIONS
-        ) = HTTPConnection.default_socket_options,
-        proxy: Url | None = None,
-        proxy_config: ProxyConfig | None = None,
-        cert_reqs: int | str | None = None,
-        assert_hostname: None | str | typing.Literal[False] = None,
-        assert_fingerprint: str | None = None,
-        server_hostname: str | None = None,
-        ssl_context: ssl.SSLContext | None = None,
-        ca_certs: str | None = None,
-        ca_cert_dir: str | None = None,
-        ca_cert_data: None | str | bytes = None,
-        ssl_minimum_version: int | None = None,
-        ssl_maximum_version: int | None = None,
-        ssl_version: int | str | None = None,  # Deprecated
-        cert_file: str | None = None,
-        key_file: str | None = None,
-        key_password: str | None = None,
-    ) -> None:
-        super().__init__(
-            host,
-            port=port,
-            timeout=timeout,
-            source_address=source_address,
-            blocksize=blocksize,
-            socket_options=socket_options,
-            proxy=proxy,
-            proxy_config=proxy_config,
-        )
-
-        self.key_file = key_file
-        self.cert_file = cert_file
-        self.key_password = key_password
-        self.ssl_context = ssl_context
-        self.server_hostname = server_hostname
-        self.assert_hostname = assert_hostname
-        self.assert_fingerprint = assert_fingerprint
-        self.ssl_version = ssl_version
-        self.ssl_minimum_version = ssl_minimum_version
-        self.ssl_maximum_version = ssl_maximum_version
-        self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
-        self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
-        self.ca_cert_data = ca_cert_data
-
-        # cert_reqs depends on ssl_context so calculate last.
-        if cert_reqs is None:
-            if self.ssl_context is not None:
-                cert_reqs = self.ssl_context.verify_mode
-            else:
-                cert_reqs = resolve_cert_reqs(None)
-        self.cert_reqs = cert_reqs
-        self._connect_callback = None
-
-    def set_cert(
-        self,
-        key_file: str | None = None,
-        cert_file: str | None = None,
-        cert_reqs: int | str | None = None,
-        key_password: str | None = None,
-        ca_certs: str | None = None,
-        assert_hostname: None | str | typing.Literal[False] = None,
-        assert_fingerprint: str | None = None,
-        ca_cert_dir: str | None = None,
-        ca_cert_data: None | str | bytes = None,
-    ) -> None:
-        """
-        This method should only be called once, before the connection is used.
-        """
-        warnings.warn(
-            "HTTPSConnection.set_cert() is deprecated and will be removed "
-            "in urllib3 v3.0. Instead provide the parameters to the "
-            "HTTPSConnection constructor.",
-            category=FutureWarning,
-            stacklevel=2,
-        )
-
-        # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also
-        # have an SSLContext object in which case we'll use its verify_mode.
-        if cert_reqs is None:
-            if self.ssl_context is not None:
-                cert_reqs = self.ssl_context.verify_mode
-            else:
-                cert_reqs = resolve_cert_reqs(None)
-
-        self.key_file = key_file
-        self.cert_file = cert_file
-        self.cert_reqs = cert_reqs
-        self.key_password = key_password
-        self.assert_hostname = assert_hostname
-        self.assert_fingerprint = assert_fingerprint
-        self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
-        self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
-        self.ca_cert_data = ca_cert_data
-
-    def connect(self) -> None:
-        # Today we don't need to be doing this step before the /actual/ socket
-        # connection, however in the future we'll need to decide whether to
-        # create a new socket or re-use an existing "shared" socket as a part
-        # of the HTTP/2 handshake dance.
-        if self._tunnel_host is not None and self._tunnel_port is not None:
-            probe_http2_host = self._tunnel_host
-            probe_http2_port = self._tunnel_port
-        else:
-            probe_http2_host = self.host
-            probe_http2_port = self.port
-
-        # Check if the target origin supports HTTP/2.
-        # If the value comes back as 'None' it means that the current thread
-        # is probing for HTTP/2 support. Otherwise, we're waiting for another
-        # probe to complete, or we get a value right away.
-        target_supports_http2: bool | None
-        if "h2" in ssl_.ALPN_PROTOCOLS:
-            target_supports_http2 = http2_probe.acquire_and_get(
-                host=probe_http2_host, port=probe_http2_port
-            )
-        else:
-            # If HTTP/2 isn't going to be offered it doesn't matter if
-            # the target supports HTTP/2. Don't want to make a probe.
-            target_supports_http2 = False
-
-        if self._connect_callback is not None:
-            self._connect_callback(
-                "before connect",
-                thread_id=threading.get_ident(),
-                target_supports_http2=target_supports_http2,
-            )
-
-        try:
-            sock: socket.socket | ssl.SSLSocket
-            self.sock = sock = self._new_conn()
-            server_hostname: str = self.host
-            tls_in_tls = False
-
-            # Do we need to establish a tunnel?
-            if self.proxy_is_tunneling:
-                # We're tunneling to an HTTPS origin so need to do TLS-in-TLS.
-                if self._tunnel_scheme == "https":
-                    # _connect_tls_proxy will verify and assign proxy_is_verified
-                    self.sock = sock = self._connect_tls_proxy(self.host, sock)
-                    tls_in_tls = True
-                elif self._tunnel_scheme == "http":
-                    self.proxy_is_verified = False
-
-                # If we're tunneling it means we're connected to our proxy.
-                self._has_connected_to_proxy = True
-
-                self._tunnel()
-                # Override the host with the one we're requesting data from.
-                server_hostname = typing.cast(str, self._tunnel_host)
-
-            if self.server_hostname is not None:
-                server_hostname = self.server_hostname
-
-            is_time_off = datetime.date.today() < RECENT_DATE
-            if is_time_off:
-                warnings.warn(
-                    (
-                        f"System time is way off (before {RECENT_DATE}). This will probably "
-                        "lead to SSL verification errors"
-                    ),
-                    SystemTimeWarning,
-                )
-
-            # Remove trailing '.' from fqdn hostnames to allow certificate validation
-            server_hostname_rm_dot = server_hostname.rstrip(".")
-
-            # Forwarding proxies should use proxy SSL context for
-            # wrapping since that's the connection being established,
-            # whereas tunneling proxies should use the connection's SSL
-            # context.
-            # However, for backwards compatibility reasons, if the proxy
-            # is forwarding but no proxy SSL context is provided, we
-            # fall back to using the connection's SSL context until
-            # urllib3 v3.0. Appropriate warning is emitted in
-            # ``ProxyManager.__init__``.
-            wrapped_socket: ssl.SSLSocket | SSLTransport
-            if self.proxy_is_forwarding and self.proxy_config is not None:
-                wrapped_socket = self._connect_tls_proxy(self.host, sock)
-                is_verified = self.proxy_is_verified is True
-            else:
-                wrapped_socket, is_verified = _ssl_wrap_socket_and_match_hostname(
-                    sock=sock,
-                    cert_reqs=self.cert_reqs,
-                    ssl_version=self.ssl_version,
-                    ssl_minimum_version=self.ssl_minimum_version,
-                    ssl_maximum_version=self.ssl_maximum_version,
-                    ca_certs=self.ca_certs,
-                    ca_cert_dir=self.ca_cert_dir,
-                    ca_cert_data=self.ca_cert_data,
-                    cert_file=self.cert_file,
-                    key_file=self.key_file,
-                    key_password=self.key_password,
-                    server_hostname=server_hostname_rm_dot,
-                    ssl_context=self.ssl_context,
-                    tls_in_tls=tls_in_tls,
-                    assert_hostname=self.assert_hostname,
-                    assert_fingerprint=self.assert_fingerprint,
-                )
-            self.sock = wrapped_socket
-
-        # If an error occurs during connection/handshake we may need to release
-        # our lock so another connection can probe the origin.
-        except BaseException:
-            if self._connect_callback is not None:
-                self._connect_callback(
-                    "after connect failure",
-                    thread_id=threading.get_ident(),
-                    target_supports_http2=target_supports_http2,
-                )
-
-            if target_supports_http2 is None:
-                http2_probe.set_and_release(
-                    host=probe_http2_host, port=probe_http2_port, supports_http2=None
-                )
-            raise
-
-        # If this connection doesn't know if the origin supports HTTP/2
-        # we report back to the HTTP/2 probe our result.
-        if target_supports_http2 is None:
-            supports_http2 = wrapped_socket.selected_alpn_protocol() == "h2"
-            http2_probe.set_and_release(
-                host=probe_http2_host,
-                port=probe_http2_port,
-                supports_http2=supports_http2,
-            )
-
-        # Forwarding proxies can never have a verified target since
-        # the proxy is the one doing the verification. Should instead
-        # use a CONNECT tunnel in order to verify the target.
-        # See: https://github.com/urllib3/urllib3/issues/3267.
-        if self.proxy_is_forwarding:
-            self.is_verified = False
-        else:
-            self.is_verified = is_verified
-
-        # If there's a proxy to be connected to we are fully connected.
-        # This is set twice (once above and here) due to forwarding proxies
-        # not using tunnelling.
-        self._has_connected_to_proxy = bool(self.proxy)
-
-        # Set `self.proxy_is_verified` unless it's already set while
-        # establishing a tunnel.
-        if self._has_connected_to_proxy and self.proxy_is_verified is None:
-            self.proxy_is_verified = is_verified
-
-    def _connect_tls_proxy(self, hostname: str, sock: socket.socket) -> ssl.SSLSocket:
-        """
-        Establish a TLS connection to the proxy using proxy-specific policy.
-        """
-        proxy_config = typing.cast(ProxyConfig, self.proxy_config)
-        proxy_ssl_context = proxy_config.ssl_context
-
-        ssl_context: ssl.SSLContext | None
-        cert_reqs: int | str | None
-        if proxy_ssl_context is not None:
-            # Prefer the proxy's cert policy for the proxy connection
-            ssl_context = proxy_ssl_context
-            cert_reqs = proxy_ssl_context.verify_mode
-            ca_certs = None
-            ca_cert_dir = None
-            ca_cert_data = None
-            ssl_version = None
-            ssl_minimum_version = None
-            ssl_maximum_version = None
-        else:
-            # Otherwise we inherit the pool's cert policies
-            ssl_context = self.ssl_context if self.proxy_is_forwarding else None
-            cert_reqs = self.cert_reqs
-            ca_certs = self.ca_certs
-            ca_cert_dir = self.ca_cert_dir
-            ca_cert_data = self.ca_cert_data
-            ssl_version = self.ssl_version
-            ssl_minimum_version = self.ssl_minimum_version
-            ssl_maximum_version = self.ssl_maximum_version
-
-        sock_and_verified = _ssl_wrap_socket_and_match_hostname(
-            sock,
-            cert_reqs=cert_reqs,
-            ssl_version=ssl_version,
-            ssl_minimum_version=ssl_minimum_version,
-            ssl_maximum_version=ssl_maximum_version,
-            ca_certs=ca_certs,
-            ca_cert_dir=ca_cert_dir,
-            ca_cert_data=ca_cert_data,
-            server_hostname=hostname,
-            ssl_context=ssl_context,
-            assert_hostname=proxy_config.assert_hostname,
-            assert_fingerprint=proxy_config.assert_fingerprint,
-            # Features that aren't implemented for proxies yet:
-            cert_file=None,
-            key_file=None,
-            key_password=None,
-            tls_in_tls=False,
-        )
-        self.proxy_is_verified = sock_and_verified.is_verified
-        return sock_and_verified.socket  # type: ignore[return-value]
-
-
-class _WrappedAndVerifiedSocket(typing.NamedTuple):
-    """
-    Wrapped socket and whether the connection is
-    verified after the TLS handshake
-    """
-
-    socket: ssl.SSLSocket | SSLTransport
-    is_verified: bool
-
-
-def _ssl_wrap_socket_and_match_hostname(
-    sock: socket.socket,
-    *,
-    cert_reqs: None | str | int,
-    ssl_version: None | str | int,
-    ssl_minimum_version: int | None,
-    ssl_maximum_version: int | None,
-    cert_file: str | None,
-    key_file: str | None,
-    key_password: str | None,
-    ca_certs: str | None,
-    ca_cert_dir: str | None,
-    ca_cert_data: None | str | bytes,
-    assert_hostname: None | str | typing.Literal[False],
-    assert_fingerprint: str | None,
-    server_hostname: str | None,
-    ssl_context: ssl.SSLContext | None,
-    tls_in_tls: bool = False,
-) -> _WrappedAndVerifiedSocket:
-    """Logic for constructing an SSLContext from all TLS parameters, passing
-    that down into ssl_wrap_socket, and then doing certificate verification
-    either via hostname or fingerprint. This function exists to guarantee
-    that both proxies and targets have the same behavior when connecting via TLS.
-    """
-    default_ssl_context = False
-    if ssl_context is None:
-        default_ssl_context = True
-        context = create_urllib3_context(
-            ssl_version=resolve_ssl_version(ssl_version),
-            ssl_minimum_version=ssl_minimum_version,
-            ssl_maximum_version=ssl_maximum_version,
-            cert_reqs=resolve_cert_reqs(cert_reqs),
-        )
-    else:
-        context = ssl_context
-
-    context.verify_mode = resolve_cert_reqs(cert_reqs)
-
-    # In some cases, we want to verify hostnames ourselves
-    if (
-        # `ssl` can't verify fingerprints or alternate hostnames
-        assert_fingerprint
-        or assert_hostname
-        # assert_hostname can be set to False to disable hostname checking
-        or assert_hostname is False
-        # We still support OpenSSL 1.0.2, which prevents us from verifying
-        # hostnames easily: https://github.com/pyca/pyopenssl/pull/933
-        or ssl_.IS_PYOPENSSL
-        or not ssl_.HAS_NEVER_CHECK_COMMON_NAME
-    ):
-        context.check_hostname = False
-
-    # Try to load OS default certs if none are given. We need to do the hasattr() check
-    # for custom pyOpenSSL SSLContext objects because they don't support
-    # load_default_certs().
-    if (
-        not ca_certs
-        and not ca_cert_dir
-        and not ca_cert_data
-        and default_ssl_context
-        and hasattr(context, "load_default_certs")
-    ):
-        context.load_default_certs()
-
-    # Ensure that IPv6 addresses are in the proper format and don't have a
-    # scope ID. Python's SSL module fails to recognize scoped IPv6 addresses
-    # and interprets them as DNS hostnames.
-    if server_hostname is not None:
-        normalized = server_hostname.strip("[]")
-        if "%" in normalized:
-            normalized = normalized[: normalized.rfind("%")]
-        if is_ipaddress(normalized):
-            server_hostname = normalized
-
-    ssl_sock = ssl_wrap_socket(
-        sock=sock,
-        keyfile=key_file,
-        certfile=cert_file,
-        key_password=key_password,
-        ca_certs=ca_certs,
-        ca_cert_dir=ca_cert_dir,
-        ca_cert_data=ca_cert_data,
-        server_hostname=server_hostname,
-        ssl_context=context,
-        tls_in_tls=tls_in_tls,
-    )
-
-    try:
-        if assert_fingerprint:
-            _assert_fingerprint(
-                ssl_sock.getpeercert(binary_form=True), assert_fingerprint
-            )
-        elif (
-            context.verify_mode != ssl.CERT_NONE
-            and not context.check_hostname
-            and assert_hostname is not False
-        ):
-            cert: _TYPE_PEER_CERT_RET_DICT = ssl_sock.getpeercert()  # type: ignore[assignment]
-
-            # Need to signal to our match_hostname whether to use 'commonName' or not.
-            # If we're using our own constructed SSLContext we explicitly set 'False'
-            # because PyPy hard-codes 'True' from SSLContext.hostname_checks_common_name.
-            if default_ssl_context:
-                hostname_checks_common_name = False
-            else:
-                hostname_checks_common_name = (
-                    getattr(context, "hostname_checks_common_name", False) or False
-                )
-
-            _match_hostname(
-                cert,
-                assert_hostname or server_hostname,  # type: ignore[arg-type]
-                hostname_checks_common_name,
-            )
-
-        return _WrappedAndVerifiedSocket(
-            socket=ssl_sock,
-            is_verified=context.verify_mode == ssl.CERT_REQUIRED
-            or bool(assert_fingerprint),
-        )
-    except BaseException:
-        ssl_sock.close()
-        raise
-
-
-def _match_hostname(
-    cert: _TYPE_PEER_CERT_RET_DICT | None,
-    asserted_hostname: str,
-    hostname_checks_common_name: bool = False,
-) -> None:
-    # Our upstream implementation of ssl.match_hostname()
-    # only applies this normalization to IP addresses so it doesn't
-    # match DNS SANs so we do the same thing!
-    stripped_hostname = asserted_hostname.strip("[]")
-    if is_ipaddress(stripped_hostname):
-        asserted_hostname = stripped_hostname
-
-    try:
-        match_hostname(cert, asserted_hostname, hostname_checks_common_name)
-    except CertificateError as e:
-        log.warning(
-            "Certificate did not match expected hostname: %s. Certificate: %s",
-            asserted_hostname,
-            cert,
-        )
-        # Add cert to exception and reraise so client code can inspect
-        # the cert when catching the exception, if they want to
-        e._peer_cert = cert  # type: ignore[attr-defined]
-        raise
-
-
-def _wrap_proxy_error(err: Exception, proxy_scheme: str | None) -> ProxyError:
-    # Look for the phrase 'wrong version number', if found
-    # then we should warn the user that we're very sure that
-    # this proxy is HTTP-only and they have a configuration issue.
-    error_normalized = " ".join(re.split("[^a-z]", str(err).lower()))
-    is_likely_http_proxy = (
-        "wrong version number" in error_normalized
-        or "unknown protocol" in error_normalized
-        or "record layer failure" in error_normalized
-    )
-    http_proxy_warning = (
-        ". Your proxy appears to only use HTTP and not HTTPS, "
-        "try changing your proxy URL to be HTTP. See: "
-        "https://urllib3.readthedocs.io/en/latest/advanced-usage.html"
-        "#https-proxy-error-http-proxy"
-    )
-    new_err = ProxyError(
-        f"Unable to connect to proxy"
-        f"{http_proxy_warning if is_likely_http_proxy and proxy_scheme == 'https' else ''}",
-        err,
-    )
-    new_err.__cause__ = err
-    return new_err
-
-
-def _get_default_user_agent() -> str:
-    return f"python-urllib3/{__version__}"
-
-
-class DummyConnection:
-    """Used to detect a failed ConnectionCls import."""
-
-
-if not ssl:
-    HTTPSConnection = DummyConnection  # type: ignore[misc, assignment] # noqa: F811
-
-
-VerifiedHTTPSConnection = HTTPSConnection
-
-
-def _url_from_connection(
-    conn: HTTPConnection | HTTPSConnection, path: str | None = None
-) -> str:
-    """Returns the URL from a given connection. This is mainly used for testing and logging."""
-
-    scheme = "https" if isinstance(conn, HTTPSConnection) else "http"
-
-    return Url(scheme=scheme, host=conn.host, port=conn.port, path=path).url
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py
deleted file mode 100644
index dd1a1e05c55..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/connectionpool.py
+++ /dev/null
@@ -1,1211 +0,0 @@
-from __future__ import annotations
-
-import errno
-import logging
-import queue
-import sys
-import typing
-import warnings
-import weakref
-from socket import timeout as SocketTimeout
-from types import TracebackType
-
-from ._base_connection import _TYPE_BODY
-from ._collections import HTTPHeaderDict
-from ._request_methods import RequestMethods
-from .connection import (
-    BaseSSLError,
-    BrokenPipeError,
-    DummyConnection,
-    HTTPConnection,
-    HTTPException,
-    HTTPSConnection,
-    ProxyConfig,
-    _wrap_proxy_error,
-)
-from .connection import port_by_scheme as port_by_scheme
-from .exceptions import (
-    ClosedPoolError,
-    EmptyPoolError,
-    FullPoolError,
-    HostChangedError,
-    InsecureRequestWarning,
-    LocationValueError,
-    MaxRetryError,
-    NewConnectionError,
-    ProtocolError,
-    ProxyError,
-    ReadTimeoutError,
-    SSLError,
-    TimeoutError,
-)
-from .response import BaseHTTPResponse
-from .util.connection import is_connection_dropped
-from .util.proxy import connection_requires_http_tunnel
-from .util.request import _TYPE_BODY_POSITION, set_file_position
-from .util.retry import Retry
-from .util.ssl_match_hostname import CertificateError
-from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_DEFAULT, Timeout
-from .util.url import Url, _encode_target
-from .util.url import _normalize_host as normalize_host
-from .util.url import parse_url
-from .util.util import to_str
-
-if typing.TYPE_CHECKING:
-    import ssl
-
-    from opentelemetry.agent._vendor.typing_extensions import Self
-
-    from ._base_connection import BaseHTTPConnection, BaseHTTPSConnection
-
-log = logging.getLogger(__name__)
-
-_TYPE_TIMEOUT = typing.Union[Timeout, float, _TYPE_DEFAULT, None]
-_DEFAULT_QUEUE_CLASS = queue.LifoQueue
-
-
-# Pool objects
-class ConnectionPool:
-    """
-    Base class for all connection pools, such as
-    :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`.
-
-    .. note::
-       ConnectionPool.urlopen() does not normalize or percent-encode target URIs
-       which is useful if your target server doesn't support percent-encoded
-       target URIs.
-    """
-
-    scheme: str | None = None
-    QueueCls = _DEFAULT_QUEUE_CLASS
-
-    def __init__(self, host: str, port: int | None = None) -> None:
-        if not host:
-            raise LocationValueError("No host specified.")
-
-        self.host = _normalize_host(host, scheme=self.scheme)
-        self.port = port
-
-        # This property uses 'normalize_host()' (not '_normalize_host()')
-        # to avoid removing square braces around IPv6 addresses.
-        # This value is sent to `HTTPConnection.set_tunnel()` if called
-        # because square braces are required for HTTP CONNECT tunneling.
-        self._tunnel_host = normalize_host(host, scheme=self.scheme).lower()
-
-    def __str__(self) -> str:
-        return f"{type(self).__name__}(host={self.host!r}, port={self.port!r})"
-
-    def __enter__(self) -> Self:
-        return self
-
-    def __exit__(
-        self,
-        exc_type: type[BaseException] | None,
-        exc_val: BaseException | None,
-        exc_tb: TracebackType | None,
-    ) -> typing.Literal[False]:
-        self.close()
-        # Return False to re-raise any potential exceptions
-        return False
-
-    def close(self) -> None:
-        """
-        Close all pooled connections and disable the pool.
-        """
-
-    def _new_pool_queue(self, maxsize: int) -> queue.LifoQueue[typing.Any]:
-        if self.QueueCls is _DEFAULT_QUEUE_CLASS:
-            return queue.LifoQueue(maxsize)
-        return self.QueueCls(maxsize)
-
-
-# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
-_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}
-
-
-class HTTPConnectionPool(ConnectionPool, RequestMethods):
-    """
-    Thread-safe connection pool for one host.
-
-    :param host:
-        Host used for this HTTP Connection (e.g. "localhost"), passed into
-        :class:`http.client.HTTPConnection`.
-
-    :param port:
-        Port used for this HTTP Connection (None is equivalent to 80), passed
-        into :class:`http.client.HTTPConnection`.
-
-    :param timeout:
-        Socket timeout in seconds for each individual connection. This can
-        be a float or integer, which sets the timeout for the HTTP request,
-        or an instance of :class:`urllib3.util.Timeout` which gives you more
-        fine-grained control over request timeouts. After the constructor has
-        been parsed, this is always a `urllib3.util.Timeout` object.
-
-    :param maxsize:
-        Number of connections to save that can be reused. More than 1 is useful
-        in multithreaded situations. If ``block`` is set to False, more
-        connections will be created but they will not be saved once they've
-        been used.
-
-    :param block:
-        If set to True, no more than ``maxsize`` connections will be used at
-        a time. When no free connections are available, the call will block
-        until a connection has been released. This is a useful side effect for
-        particular multithreaded situations where one does not want to use more
-        than maxsize connections per host to prevent flooding.
-
-    :param headers:
-        Headers to include with all requests, unless other headers are given
-        explicitly.
-
-    :param retries:
-        Retry configuration to use by default with requests in this pool.
-
-    :param _proxy:
-        Parsed proxy URL, should not be used directly, instead, see
-        :class:`urllib3.ProxyManager`
-
-    :param _proxy_headers:
-        A dictionary with proxy headers, should not be used directly,
-        instead, see :class:`urllib3.ProxyManager`
-
-    :param \\**conn_kw:
-        Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`,
-        :class:`urllib3.connection.HTTPSConnection` instances.
-    """
-
-    scheme = "http"
-    ConnectionCls: type[BaseHTTPConnection] | type[BaseHTTPSConnection] = HTTPConnection
-
-    def __init__(
-        self,
-        host: str,
-        port: int | None = None,
-        timeout: _TYPE_TIMEOUT | None = _DEFAULT_TIMEOUT,
-        maxsize: int = 1,
-        block: bool = False,
-        headers: typing.Mapping[str, str] | None = None,
-        retries: Retry | bool | int | None = None,
-        _proxy: Url | None = None,
-        _proxy_headers: typing.Mapping[str, str] | None = None,
-        _proxy_config: ProxyConfig | None = None,
-        **conn_kw: typing.Any,
-    ):
-        ConnectionPool.__init__(self, host, port)
-        RequestMethods.__init__(self, headers)
-
-        if not isinstance(timeout, Timeout):
-            timeout = Timeout.from_float(timeout)
-
-        if retries is None:
-            retries = Retry.DEFAULT
-
-        self.timeout = timeout
-        self.retries = retries
-
-        self.pool: queue.LifoQueue[typing.Any] | None = self._new_pool_queue(maxsize)
-        self.block = block
-
-        self.proxy = _proxy
-        self.proxy_headers = _proxy_headers or {}
-        self.proxy_config = _proxy_config
-
-        # Fill the queue up so that doing get() on it will block properly
-        for _ in range(maxsize):
-            self.pool.put(None)
-
-        # These are mostly for testing and debugging purposes.
-        self.num_connections = 0
-        self.num_requests = 0
-        self.conn_kw = conn_kw
-
-        if self.proxy:
-            # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.
-            # Defaulting `socket_options` to an empty list avoids it defaulting to
-            # ``HTTPConnection.default_socket_options``.
-            self.conn_kw.setdefault("socket_options", [])
-
-            self.conn_kw["proxy"] = self.proxy
-            self.conn_kw["proxy_config"] = self.proxy_config
-
-        # Do not pass 'self' as callback to 'finalize'.
-        # Then the 'finalize' would keep an endless living (leak) to self.
-        # By just passing a reference to the pool allows the garbage collector
-        # to free self if nobody else has a reference to it.
-        pool = self.pool
-
-        # Close all the HTTPConnections in the pool before the
-        # HTTPConnectionPool object is garbage collected.
-        weakref.finalize(self, _close_pool_connections, pool)
-
-    def _new_conn(self) -> BaseHTTPConnection:
-        """
-        Return a fresh :class:`HTTPConnection`.
-        """
-        self.num_connections += 1
-        log.debug(
-            "Starting new HTTP connection (%d): %s:%s",
-            self.num_connections,
-            self.host,
-            self.port or "80",
-        )
-
-        conn = self.ConnectionCls(
-            host=self.host,
-            port=self.port,
-            timeout=self.timeout.connect_timeout,
-            **self.conn_kw,
-        )
-        return conn
-
-    def _get_conn(self, timeout: float | None = None) -> BaseHTTPConnection:
-        """
-        Get a connection. Will return a pooled connection if one is available.
-
-        If no connections are available and :prop:`.block` is ``False``, then a
-        fresh connection is returned.
-
-        :param timeout:
-            Seconds to wait before giving up and raising
-            :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and
-            :prop:`.block` is ``True``.
-        """
-        conn = None
-
-        if self.pool is None:
-            raise ClosedPoolError(self, "Pool is closed.")
-
-        try:
-            conn = self.pool.get(block=self.block, timeout=timeout)
-
-        except AttributeError:  # self.pool is None
-            raise ClosedPoolError(self, "Pool is closed.") from None  # Defensive:
-
-        except queue.Empty:
-            if self.block:
-                raise EmptyPoolError(
-                    self,
-                    "Pool is empty and a new connection can't be opened due to blocking mode.",
-                ) from None
-            pass  # Oh well, we'll create a new connection then
-
-        # If this is a persistent connection, check if it got disconnected
-        if conn and is_connection_dropped(conn):
-            log.debug("Resetting dropped connection: %s", self.host)
-            conn.close()
-
-        return conn or self._new_conn()
-
-    def _put_conn(self, conn: BaseHTTPConnection | None) -> None:
-        """
-        Put a connection back into the pool.
-
-        :param conn:
-            Connection object for the current host and port as returned by
-            :meth:`._new_conn` or :meth:`._get_conn`.
-
-        If the pool is already full, the connection is closed and discarded
-        because we exceeded maxsize. If connections are discarded frequently,
-        then maxsize should be increased.
-
-        If the pool is closed, then the connection will be closed and discarded.
-        """
-        if self.pool is not None:
-            try:
-                self.pool.put(conn, block=False)
-                return  # Everything is dandy, done.
-            except AttributeError:
-                # self.pool is None.
-                pass
-            except queue.Full:
-                # Connection never got put back into the pool, close it.
-                if conn:
-                    conn.close()
-
-                if self.block:
-                    # This should never happen if you got the conn from self._get_conn
-                    raise FullPoolError(
-                        self,
-                        "Pool reached maximum size and no more connections are allowed.",
-                    ) from None
-
-                log.warning(
-                    "Connection pool is full, discarding connection: %s. Connection pool size: %s",
-                    self.host,
-                    self.pool.qsize(),
-                )
-
-        # Connection never got put back into the pool, close it.
-        if conn:
-            conn.close()
-
-    def _validate_conn(self, conn: BaseHTTPConnection) -> None:
-        """
-        Called right before a request is made, after the socket is created.
-        """
-
-    def _prepare_proxy(self, conn: BaseHTTPConnection) -> None:
-        # Nothing to do for HTTP connections.
-        pass
-
-    def _get_timeout(self, timeout: _TYPE_TIMEOUT) -> Timeout:
-        """Helper that always returns a :class:`urllib3.util.Timeout`"""
-        if timeout is _DEFAULT_TIMEOUT:
-            return self.timeout.clone()
-
-        if isinstance(timeout, Timeout):
-            return timeout.clone()
-        else:
-            # User passed us an int/float. This is for backwards compatibility,
-            # can be removed later
-            return Timeout.from_float(timeout)
-
-    def _raise_timeout(
-        self,
-        err: BaseSSLError | OSError | SocketTimeout,
-        url: str,
-        timeout_value: _TYPE_TIMEOUT | None,
-    ) -> None:
-        """Is the error actually a timeout? Will raise a ReadTimeout or pass"""
-
-        if isinstance(err, SocketTimeout):
-            raise ReadTimeoutError(
-                self, url, f"Read timed out. (read timeout={timeout_value})"
-            ) from err
-
-        # See the above comment about EAGAIN in Python 3.
-        if hasattr(err, "errno") and err.errno in _blocking_errnos:
-            raise ReadTimeoutError(
-                self, url, f"Read timed out. (read timeout={timeout_value})"
-            ) from err
-
-    def _make_request(
-        self,
-        conn: BaseHTTPConnection,
-        method: str,
-        url: str,
-        body: _TYPE_BODY | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        retries: Retry | None = None,
-        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-        chunked: bool = False,
-        response_conn: BaseHTTPConnection | None = None,
-        preload_content: bool = True,
-        decode_content: bool = True,
-        enforce_content_length: bool = True,
-    ) -> BaseHTTPResponse:
-        """
-        Perform a request on a given urllib connection object taken from our
-        pool.
-
-        :param conn:
-            a connection from one of our connection pools
-
-        :param method:
-            HTTP request method (such as GET, POST, PUT, etc.)
-
-        :param url:
-            The URL to perform the request on.
-
-        :param body:
-            Data to send in the request body, either :class:`str`, :class:`bytes`,
-            an iterable of :class:`str`/:class:`bytes`, or a file-like object.
-
-        :param headers:
-            Dictionary of custom headers to send, such as User-Agent,
-            If-None-Match, etc. If None, pool headers are used. If provided,
-            these headers completely replace any pool-specific headers.
-
-        :param retries:
-            Configure the number of retries to allow before raising a
-            :class:`~urllib3.exceptions.MaxRetryError` exception.
-
-            Pass ``None`` to retry until you receive a response. Pass a
-            :class:`~urllib3.util.retry.Retry` object for fine-grained control
-            over different types of retries.
-            Pass an integer number to retry connection errors that many times,
-            but no other types of errors. Pass zero to never retry.
-
-            If ``False``, then retries are disabled and any exception is raised
-            immediately. Also, instead of raising a MaxRetryError on redirects,
-            the redirect response will be returned.
-
-        :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
-
-        :param timeout:
-            If specified, overrides the default timeout for this one
-            request. It may be a float (in seconds) or an instance of
-            :class:`urllib3.util.Timeout`.
-
-        :param chunked:
-            If True, urllib3 will send the body using chunked transfer
-            encoding. Otherwise, urllib3 will send the body using the standard
-            content-length form. Defaults to False.
-
-        :param response_conn:
-            Set this to ``None`` if you will handle releasing the connection or
-            set the connection to have the response release it.
-
-        :param preload_content:
-          If True, the response's body will be preloaded during construction.
-
-        :param decode_content:
-            If True, will attempt to decode the body based on the
-            'content-encoding' header.
-
-        :param enforce_content_length:
-            Enforce content length checking. Body returned by server must match
-            value of Content-Length header, if present. Otherwise, raise error.
-        """
-        self.num_requests += 1
-
-        timeout_obj = self._get_timeout(timeout)
-        timeout_obj.start_connect()
-        conn.timeout = Timeout.resolve_default_timeout(timeout_obj.connect_timeout)
-
-        try:
-            # Trigger any extra validation we need to do.
-            try:
-                self._validate_conn(conn)
-            except (SocketTimeout, BaseSSLError) as e:
-                self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
-                raise
-
-        # _validate_conn() starts the connection to an HTTPS proxy
-        # so we need to wrap errors with 'ProxyError' here too.
-        except (
-            OSError,
-            NewConnectionError,
-            TimeoutError,
-            BaseSSLError,
-            CertificateError,
-            SSLError,
-        ) as e:
-            new_e: Exception = e
-            if isinstance(e, (BaseSSLError, CertificateError)):
-                new_e = SSLError(e)
-            # If the connection didn't successfully connect to it's proxy
-            # then there
-            if isinstance(
-                new_e, (OSError, NewConnectionError, TimeoutError, SSLError)
-            ) and (conn and conn.proxy and not conn.has_connected_to_proxy):
-                new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
-            raise new_e
-
-        # conn.request() calls http.client.*.request, not the method in
-        # urllib3.request. It also calls makefile (recv) on the socket.
-        try:
-            conn.request(
-                method,
-                url,
-                body=body,
-                headers=headers,
-                chunked=chunked,
-                preload_content=preload_content,
-                decode_content=decode_content,
-                enforce_content_length=enforce_content_length,
-            )
-
-        # We are swallowing BrokenPipeError (errno.EPIPE) since the server is
-        # legitimately able to close the connection after sending a valid response.
-        # With this behaviour, the received response is still readable.
-        except BrokenPipeError:
-            pass
-        except OSError as e:
-            # MacOS/Linux
-            # EPROTOTYPE and ECONNRESET are needed on macOS
-            # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/
-            # Condition changed later to emit ECONNRESET instead of only EPROTOTYPE.
-            if e.errno != errno.EPROTOTYPE and e.errno != errno.ECONNRESET:
-                raise
-
-        # Reset the timeout for the recv() on the socket
-        read_timeout = timeout_obj.read_timeout
-
-        if not conn.is_closed:
-            # In Python 3 socket.py will catch EAGAIN and return None when you
-            # try and read into the file pointer created by http.client, which
-            # instead raises a BadStatusLine exception. Instead of catching
-            # the exception and assuming all BadStatusLine exceptions are read
-            # timeouts, check for a zero timeout before making the request.
-            if read_timeout == 0:
-                raise ReadTimeoutError(
-                    self, url, f"Read timed out. (read timeout={read_timeout})"
-                )
-            conn.timeout = read_timeout
-
-        # Receive the response from the server
-        try:
-            response = conn.getresponse()
-        except (BaseSSLError, OSError) as e:
-            self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
-            raise
-
-        # Set properties that are used by the pooling layer.
-        response.retries = retries
-        response._connection = response_conn  # type: ignore[attr-defined]
-        response._pool = self  # type: ignore[attr-defined]
-
-        log.debug(
-            '%s://%s:%s "%s %s %s" %s %s',
-            self.scheme,
-            self.host,
-            self.port,
-            method,
-            url,
-            response.version_string,
-            response.status,
-            response.length_remaining,
-        )
-
-        return response
-
-    def close(self) -> None:
-        """
-        Close all pooled connections and disable the pool.
-        """
-        if self.pool is None:
-            return
-        # Disable access to the pool
-        old_pool, self.pool = self.pool, None
-
-        # Close all the HTTPConnections in the pool.
-        _close_pool_connections(old_pool)
-
-    def is_same_host(self, url: str) -> bool:
-        """
-        Check if the given ``url`` is a member of the same host as this
-        connection pool.
-        """
-        if url.startswith("/"):
-            return True
-
-        # TODO: Add optional support for socket.gethostbyname checking.
-        scheme, _, host, port, *_ = parse_url(url)
-        scheme = scheme or "http"
-        if host is not None:
-            host = _normalize_host(host, scheme=scheme)
-
-        # Use explicit default port for comparison when none is given
-        if self.port is not None and port is None:
-            port = port_by_scheme.get(scheme)
-        elif self.port is None and port == port_by_scheme.get(scheme):
-            port = None
-
-        return (scheme, host, port) == (self.scheme, self.host, self.port)
-
-    def urlopen(  # type: ignore[override]
-        self,
-        method: str,
-        url: str,
-        body: _TYPE_BODY | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        retries: Retry | bool | int | None = None,
-        redirect: bool = True,
-        assert_same_host: bool = True,
-        timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-        pool_timeout: int | None = None,
-        release_conn: bool | None = None,
-        chunked: bool = False,
-        body_pos: _TYPE_BODY_POSITION | None = None,
-        preload_content: bool = True,
-        decode_content: bool = True,
-        **response_kw: typing.Any,
-    ) -> BaseHTTPResponse:
-        """
-        Get a connection from the pool and perform an HTTP request. This is the
-        lowest level call for making a request, so you'll need to specify all
-        the raw details.
-
-        .. note::
-
-           More commonly, it's appropriate to use a convenience method
-           such as :meth:`request`.
-
-        .. note::
-
-           `release_conn` will only behave as expected if
-           `preload_content=False` because we want to make
-           `preload_content=False` the default behaviour someday soon without
-           breaking backwards compatibility.
-
-        :param method:
-            HTTP request method (such as GET, POST, PUT, etc.)
-
-        :param url:
-            The URL to perform the request on.
-
-        :param body:
-            Data to send in the request body, either :class:`str`, :class:`bytes`,
-            an iterable of :class:`str`/:class:`bytes`, or a file-like object.
-
-        :param headers:
-            Dictionary of custom headers to send, such as User-Agent,
-            If-None-Match, etc. If None, pool headers are used. If provided,
-            these headers completely replace any pool-specific headers.
-
-        :param retries:
-            Configure the number of retries to allow before raising a
-            :class:`~urllib3.exceptions.MaxRetryError` exception.
-
-            If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. Pass a
-            :class:`~urllib3.util.retry.Retry` object for fine-grained control
-            over different types of retries.
-            Pass an integer number to retry connection errors that many times,
-            but no other types of errors. Pass zero to never retry.
-
-            If ``False``, then retries are disabled and any exception is raised
-            immediately. Also, instead of raising a MaxRetryError on redirects,
-            the redirect response will be returned.
-
-        :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
-
-        :param redirect:
-            If True, automatically handle redirects (status codes 301, 302,
-            303, 307, 308). Each redirect counts as a retry. Disabling retries
-            will disable redirect, too.
-
-        :param assert_same_host:
-            If ``True``, will make sure that the host of the pool requests is
-            consistent else will raise HostChangedError. When ``False``, you can
-            use the pool on an HTTP proxy and request foreign hosts.
-
-        :param timeout:
-            If specified, overrides the default timeout for this one
-            request. It may be a float (in seconds) or an instance of
-            :class:`urllib3.util.Timeout`.
-
-        :param pool_timeout:
-            If set and the pool is set to block=True, then this method will
-            block for ``pool_timeout`` seconds and raise EmptyPoolError if no
-            connection is available within the time period.
-
-        :param bool preload_content:
-            If True, the response's body will be preloaded into memory.
-
-        :param bool decode_content:
-            If True, will attempt to decode the body based on the
-            'content-encoding' header.
-
-        :param release_conn:
-            If False, then the urlopen call will not release the connection
-            back into the pool once a response is received (but will release if
-            you read the entire contents of the response such as when
-            `preload_content=True`). This is useful if you're not preloading
-            the response's content immediately. You will need to call
-            ``r.release_conn()`` on the response ``r`` to return the connection
-            back into the pool. If None, it takes the value of ``preload_content``
-            which defaults to ``True``.
-
-        :param bool chunked:
-            If True, urllib3 will send the body using chunked transfer
-            encoding. Otherwise, urllib3 will send the body using the standard
-            content-length form. Defaults to False.
-
-        :param int body_pos:
-            Position to seek to in file-like body in the event of a retry or
-            redirect. Typically this won't need to be set because urllib3 will
-            auto-populate the value when needed.
-        """
-        # Ensure that the URL we're connecting to is properly encoded
-        if url.startswith("/"):
-            # URLs starting with / are inherently schemeless.
-            url = to_str(_encode_target(url))
-            destination_scheme = None
-        else:
-            parsed_url = parse_url(url)
-            destination_scheme = parsed_url.scheme
-            url = to_str(parsed_url._replace(fragment=None).url)
-
-        if headers is None:
-            headers = self.headers
-
-        if not isinstance(retries, Retry):
-            retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
-
-        if release_conn is None:
-            release_conn = preload_content
-
-        # Check host
-        if assert_same_host and not self.is_same_host(url):
-            raise HostChangedError(self, url, retries)
-
-        conn = None
-
-        # Track whether `conn` needs to be released before
-        # returning/raising/recursing. Update this variable if necessary, and
-        # leave `release_conn` constant throughout the function. That way, if
-        # the function recurses, the original value of `release_conn` will be
-        # passed down into the recursive call, and its value will be respected.
-        #
-        # See issue #651 [1] for details.
-        #
-        # [1] 
-        release_this_conn = release_conn
-
-        http_tunnel_required = connection_requires_http_tunnel(
-            self.proxy, self.proxy_config, destination_scheme
-        )
-
-        # Merge the proxy headers. Only done when not using HTTP CONNECT. We
-        # have to copy the headers dict so we can safely change it without those
-        # changes being reflected in anyone else's copy.
-        if not http_tunnel_required:
-            headers = headers.copy()  # type: ignore[attr-defined]
-            headers.update(self.proxy_headers)  # type: ignore[union-attr]
-
-        # Must keep the exception bound to a separate variable or else Python 3
-        # complains about UnboundLocalError.
-        err = None
-
-        # Keep track of whether we cleanly exited the except block. This
-        # ensures we do proper cleanup in finally.
-        clean_exit = False
-
-        # Rewind body position, if needed. Record current position
-        # for future rewinds in the event of a redirect/retry.
-        body_pos = set_file_position(body, body_pos)
-
-        timeout_obj = self._get_timeout(timeout)
-        try:
-            # Request a connection from the queue.
-            conn = self._get_conn(timeout=pool_timeout)
-            conn.timeout = timeout_obj.connect_timeout  # type: ignore[assignment]
-
-            # Is this a closed/new connection that requires CONNECT tunnelling?
-            if self.proxy is not None and http_tunnel_required and conn.is_closed:
-                try:
-                    self._prepare_proxy(conn)
-                except (BaseSSLError, OSError, SocketTimeout) as e:
-                    self._raise_timeout(
-                        err=e, url=self.proxy.url, timeout_value=conn.timeout
-                    )
-                    raise
-
-            # If we're going to release the connection in ``finally:``, then
-            # the response doesn't need to know about the connection. Otherwise
-            # it will also try to release it and we'll have a double-release
-            # mess.
-            response_conn = conn if not release_conn else None
-
-            # Make the request on the HTTPConnection object
-            response = self._make_request(
-                conn,
-                method,
-                url,
-                timeout=timeout_obj,
-                body=body,
-                headers=headers,
-                chunked=chunked,
-                retries=retries,
-                response_conn=response_conn,
-                preload_content=preload_content,
-                decode_content=decode_content,
-                **response_kw,
-            )
-
-            # Everything went great!
-            clean_exit = True
-
-        except EmptyPoolError:
-            # Didn't get a connection from the pool, no need to clean up
-            clean_exit = True
-            release_this_conn = False
-            raise
-
-        except (
-            TimeoutError,
-            HTTPException,
-            OSError,
-            ProtocolError,
-            BaseSSLError,
-            SSLError,
-            CertificateError,
-            ProxyError,
-        ) as e:
-            # Discard the connection for these exceptions. It will be
-            # replaced during the next _get_conn() call.
-            clean_exit = False
-            new_e: Exception = e
-            if isinstance(e, (BaseSSLError, CertificateError)):
-                new_e = SSLError(e)
-            if isinstance(
-                new_e,
-                (
-                    OSError,
-                    NewConnectionError,
-                    TimeoutError,
-                    SSLError,
-                    HTTPException,
-                ),
-            ) and (conn and conn.proxy and not conn.has_connected_to_proxy):
-                new_e = _wrap_proxy_error(new_e, conn.proxy.scheme)
-            elif isinstance(new_e, (OSError, HTTPException)):
-                new_e = ProtocolError("Connection aborted.", new_e)
-
-            retries = retries.increment(
-                method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]
-            )
-            retries.sleep()
-
-            # Keep track of the error for the retry warning.
-            err = e
-
-        finally:
-            if not clean_exit:
-                # We hit some kind of exception, handled or otherwise. We need
-                # to throw the connection away unless explicitly told not to.
-                # Close the connection, set the variable to None, and make sure
-                # we put the None back in the pool to avoid leaking it.
-                if conn:
-                    conn.close()
-                    conn = None
-                release_this_conn = True
-
-            if release_this_conn:
-                # Put the connection back to be reused. If the connection is
-                # expired then it will be None, which will get replaced with a
-                # fresh connection during _get_conn.
-                self._put_conn(conn)
-
-        if not conn:
-            # Try again
-            log.warning(
-                "Retrying (%r) after connection broken by '%r': %s",
-                retries,
-                err,
-                url,
-                # Provide an unique attribute with the host needed by pip to
-                # rewrite this warning. Ideally, we'd go with a better solution,
-                # but backwards compatibility and other constraints make those
-                # unfeasible, so this is the least bad option.
-                # See also: https://github.com/urllib3/urllib3/issues/2580.
-                extra={"__urllib3-retry-warning": {"host": self.host}},
-            )
-            return self.urlopen(
-                method,
-                url,
-                body,
-                headers,
-                retries,
-                redirect,
-                assert_same_host,
-                timeout=timeout,
-                pool_timeout=pool_timeout,
-                release_conn=release_conn,
-                chunked=chunked,
-                body_pos=body_pos,
-                preload_content=preload_content,
-                decode_content=decode_content,
-                **response_kw,
-            )
-
-        # Handle redirect?
-        redirect_location = redirect and response.get_redirect_location()
-        if redirect_location:
-            if response.status == 303:
-                # Change the method according to RFC 9110, Section 15.4.4.
-                method = "GET"
-                # And lose the body not to transfer anything sensitive.
-                body = None
-                # The body is gone, so the state that describes it has to go
-                # too: there is nothing left to frame with chunked transfer
-                # encoding, and nothing left to rewind.
-                chunked = False
-                body_pos = None
-                headers = HTTPHeaderDict(headers)._prepare_for_method_change()
-
-            # Strip headers marked as unsafe to forward to the redirected location.
-            # Check remove_headers_on_redirect to avoid a potential network call within
-            # self.is_same_host() which may use socket.gethostbyname() in the future.
-            if retries.remove_headers_on_redirect and not self.is_same_host(
-                redirect_location
-            ):
-                new_headers = headers.copy()  # type: ignore[union-attr]
-                for header in headers:
-                    if header.lower() in retries.remove_headers_on_redirect:
-                        new_headers.pop(header, None)
-                headers = new_headers
-
-            try:
-                retries = retries.increment(method, url, response=response, _pool=self)
-            except MaxRetryError:
-                if retries.raise_on_redirect:
-                    response.drain_conn()
-                    raise
-                return response
-
-            response.drain_conn()
-            retries.sleep_for_retry(response)
-            log.debug("Redirecting %s -> %s", url, redirect_location)
-            return self.urlopen(
-                method,
-                redirect_location,
-                body,
-                headers,
-                retries=retries,
-                redirect=redirect,
-                assert_same_host=assert_same_host,
-                timeout=timeout,
-                pool_timeout=pool_timeout,
-                release_conn=release_conn,
-                chunked=chunked,
-                body_pos=body_pos,
-                preload_content=preload_content,
-                decode_content=decode_content,
-                **response_kw,
-            )
-
-        # Check if we should retry the HTTP response.
-        has_retry_after = bool(response.headers.get("Retry-After"))
-        if retries.is_retry(method, response.status, has_retry_after):
-            try:
-                retries = retries.increment(method, url, response=response, _pool=self)
-            except MaxRetryError:
-                if retries.raise_on_status:
-                    response.drain_conn()
-                    raise
-                return response
-
-            response.drain_conn()
-            retries.sleep(response)
-            log.debug("Retry: %s", url)
-            return self.urlopen(
-                method,
-                url,
-                body,
-                headers,
-                retries=retries,
-                redirect=redirect,
-                assert_same_host=assert_same_host,
-                timeout=timeout,
-                pool_timeout=pool_timeout,
-                release_conn=release_conn,
-                chunked=chunked,
-                body_pos=body_pos,
-                preload_content=preload_content,
-                decode_content=decode_content,
-                **response_kw,
-            )
-
-        return response
-
-
-class HTTPSConnectionPool(HTTPConnectionPool):
-    """
-    Same as :class:`.HTTPConnectionPool`, but HTTPS.
-
-    :class:`.HTTPSConnection` uses one of ``assert_fingerprint``,
-    ``assert_hostname`` and ``host`` in this order to verify connections.
-    If ``assert_hostname`` is False, no verification is done.
-
-    The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``,
-    ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl`
-    is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade
-    the connection socket into an SSL socket.
-    """
-
-    scheme = "https"
-    ConnectionCls: type[BaseHTTPSConnection] = HTTPSConnection
-
-    def __init__(
-        self,
-        host: str,
-        port: int | None = None,
-        timeout: _TYPE_TIMEOUT | None = _DEFAULT_TIMEOUT,
-        maxsize: int = 1,
-        block: bool = False,
-        headers: typing.Mapping[str, str] | None = None,
-        retries: Retry | bool | int | None = None,
-        _proxy: Url | None = None,
-        _proxy_headers: typing.Mapping[str, str] | None = None,
-        key_file: str | None = None,
-        cert_file: str | None = None,
-        cert_reqs: int | str | None = None,
-        key_password: str | None = None,
-        ca_certs: str | None = None,
-        ssl_version: int | str | None = None,
-        ssl_minimum_version: ssl.TLSVersion | None = None,
-        ssl_maximum_version: ssl.TLSVersion | None = None,
-        assert_hostname: str | typing.Literal[False] | None = None,
-        assert_fingerprint: str | None = None,
-        ca_cert_dir: str | None = None,
-        **conn_kw: typing.Any,
-    ) -> None:
-        super().__init__(
-            host,
-            port,
-            timeout,
-            maxsize,
-            block,
-            headers,
-            retries,
-            _proxy,
-            _proxy_headers,
-            **conn_kw,
-        )
-
-        self.key_file = key_file
-        self.cert_file = cert_file
-        self.cert_reqs = cert_reqs
-        self.key_password = key_password
-        self.ca_certs = ca_certs
-        self.ca_cert_dir = ca_cert_dir
-        self.ssl_version = ssl_version
-        self.ssl_minimum_version = ssl_minimum_version
-        self.ssl_maximum_version = ssl_maximum_version
-        self.assert_hostname = assert_hostname
-        self.assert_fingerprint = assert_fingerprint
-
-    def _prepare_proxy(self, conn: HTTPSConnection) -> None:  # type: ignore[override]
-        """Establishes a tunnel connection through HTTP CONNECT."""
-        if self.proxy and self.proxy.scheme == "https":
-            tunnel_scheme = "https"
-        else:
-            tunnel_scheme = "http"
-
-        conn.set_tunnel(
-            scheme=tunnel_scheme,
-            host=self._tunnel_host,
-            port=self.port,
-            headers=self.proxy_headers,
-        )
-        conn.connect()
-
-    def _new_conn(self) -> BaseHTTPSConnection:
-        """
-        Return a fresh :class:`urllib3.connection.HTTPConnection`.
-        """
-        self.num_connections += 1
-        log.debug(
-            "Starting new HTTPS connection (%d): %s:%s",
-            self.num_connections,
-            self.host,
-            self.port or "443",
-        )
-
-        if not self.ConnectionCls or self.ConnectionCls is DummyConnection:  # type: ignore[comparison-overlap]
-            raise ImportError(
-                "Can't connect to HTTPS URL because the SSL module is not available."
-            )
-
-        actual_host: str = self.host
-        actual_port = self.port
-        if self.proxy is not None and self.proxy.host is not None:
-            actual_host = self.proxy.host
-            actual_port = self.proxy.port
-
-        return self.ConnectionCls(
-            host=actual_host,
-            port=actual_port,
-            timeout=self.timeout.connect_timeout,
-            cert_file=self.cert_file,
-            key_file=self.key_file,
-            key_password=self.key_password,
-            cert_reqs=self.cert_reqs,
-            ca_certs=self.ca_certs,
-            ca_cert_dir=self.ca_cert_dir,
-            assert_hostname=self.assert_hostname,
-            assert_fingerprint=self.assert_fingerprint,
-            ssl_version=self.ssl_version,
-            ssl_minimum_version=self.ssl_minimum_version,
-            ssl_maximum_version=self.ssl_maximum_version,
-            **self.conn_kw,
-        )
-
-    def _validate_conn(self, conn: BaseHTTPConnection) -> None:
-        """
-        Called right before a request is made, after the socket is created.
-        """
-        super()._validate_conn(conn)
-
-        # Force connect early to allow us to validate the connection.
-        if conn.is_closed:
-            conn.connect()
-
-        # TODO revise this, see https://github.com/urllib3/urllib3/issues/2791
-        if not conn.is_verified and not conn.proxy_is_verified:
-            warnings.warn(
-                (
-                    f"Unverified HTTPS request is being made to host '{conn.host}'. "
-                    "Adding certificate verification is strongly advised. See: "
-                    "https://urllib3.readthedocs.io/en/latest/advanced-usage.html"
-                    "#tls-warnings"
-                ),
-                InsecureRequestWarning,
-            )
-
-
-def connection_from_url(url: str, **kw: typing.Any) -> HTTPConnectionPool:
-    """
-    Given a url, return an :class:`.ConnectionPool` instance of its host.
-
-    This is a shortcut for not having to parse out the scheme, host, and port
-    of the url before creating an :class:`.ConnectionPool` instance.
-
-    :param url:
-        Absolute URL string that must include the scheme. Port is optional.
-
-    :param \\**kw:
-        Passes additional parameters to the constructor of the appropriate
-        :class:`.ConnectionPool`. Useful for specifying things like
-        timeout, maxsize, headers, etc.
-
-    Example::
-
-        >>> conn = connection_from_url('http://google.com/')
-        >>> r = conn.request('GET', '/')
-    """
-    scheme, _, host, port, *_ = parse_url(url)
-    scheme = scheme or "http"
-    if port is None:
-        port = port_by_scheme.get(scheme, 80)
-    if scheme == "https":
-        return HTTPSConnectionPool(host, port=port, **kw)  # type: ignore[arg-type]
-    else:
-        return HTTPConnectionPool(host, port=port, **kw)  # type: ignore[arg-type]
-
-
-@typing.overload
-def _normalize_host(host: None, scheme: str | None) -> None: ...
-
-
-@typing.overload
-def _normalize_host(host: str, scheme: str | None) -> str: ...
-
-
-def _normalize_host(host: str | None, scheme: str | None) -> str | None:
-    """
-    Normalize hosts for comparisons and use with sockets.
-    """
-
-    host = normalize_host(host, scheme)
-
-    # httplib doesn't like it when we include brackets in IPv6 addresses
-    # Specifically, if we include brackets but also pass the port then
-    # httplib crazily doubles up the square brackets on the Host header.
-    # Instead, we need to make sure we never pass ``None`` as the port.
-    # However, for backward compatibility reasons we can't actually
-    # *assert* that.  See http://bugs.python.org/issue28539
-    if host and host.startswith("[") and host.endswith("]"):
-        host = host[1:-1]
-    return host
-
-
-def _url_from_pool(
-    pool: HTTPConnectionPool | HTTPSConnectionPool, path: str | None = None
-) -> str:
-    """Returns the URL from a given connection pool. This is mainly used for testing and logging."""
-    return Url(scheme=pool.scheme, host=pool.host, port=pool.port, path=path).url
-
-
-def _close_pool_connections(pool: queue.LifoQueue[typing.Any]) -> None:
-    """Drains a queue of connections and closes each one."""
-    try:
-        while True:
-            conn = pool.get(block=False)
-            if conn:
-                conn.close()
-    except queue.Empty:
-        pass  # Done.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/contrib/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/contrib/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py
deleted file mode 100644
index 3d7e9b93d30..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/exceptions.py
+++ /dev/null
@@ -1,335 +0,0 @@
-from __future__ import annotations
-
-import socket
-import typing
-import warnings
-from email.errors import MessageDefect
-from http.client import IncompleteRead as httplib_IncompleteRead
-
-if typing.TYPE_CHECKING:
-    from .connection import HTTPConnection
-    from .connectionpool import ConnectionPool
-    from .response import HTTPResponse
-    from .util.retry import Retry
-
-# Base Exceptions
-
-
-class HTTPError(Exception):
-    """Base exception used by this module."""
-
-
-class HTTPWarning(Warning):
-    """Base warning used by this module."""
-
-
-_TYPE_REDUCE_RESULT = tuple[typing.Callable[..., object], tuple[object, ...]]
-
-
-class PoolError(HTTPError):
-    """Base exception for errors caused within a pool."""
-
-    def __init__(self, pool: ConnectionPool, message: str) -> None:
-        self.pool = pool
-        self._message = message
-        super().__init__(f"{pool}: {message}")
-
-    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
-        # For pickling purposes.
-        return self.__class__, (None, self._message)
-
-
-class RequestError(PoolError):
-    """Base exception for PoolErrors that have associated URLs."""
-
-    def __init__(self, pool: ConnectionPool, url: str | None, message: str) -> None:
-        self.url = url
-        super().__init__(pool, message)
-
-    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
-        # For pickling purposes.
-        return self.__class__, (None, self.url, self._message)
-
-
-class SSLError(HTTPError):
-    """Raised when SSL certificate fails in an HTTPS connection."""
-
-
-class ProxyError(HTTPError):
-    """Raised when the connection to a proxy fails."""
-
-    # The original error is also available as __cause__.
-    original_error: Exception
-
-    def __init__(self, message: str, error: Exception) -> None:
-        super().__init__(message, error)
-        self.original_error = error
-
-
-class DecodeError(HTTPError):
-    """Raised when automatic decoding based on Content-Type fails."""
-
-
-class ProtocolError(HTTPError):
-    """Raised when something unexpected happens mid-request/response."""
-
-
-#: Renamed to ProtocolError but aliased for backwards compatibility.
-ConnectionError = ProtocolError
-
-
-# Leaf Exceptions
-
-
-class MaxRetryError(RequestError):
-    """Raised when the maximum number of retries is exceeded.
-
-    :param pool: The connection pool
-    :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool`
-    :param str url: The requested Url
-    :param reason: The underlying error
-    :type reason: :class:`Exception`
-
-    """
-
-    def __init__(
-        self, pool: ConnectionPool, url: str | None, reason: Exception | None = None
-    ) -> None:
-        self.reason = reason
-
-        message = f"Max retries exceeded with url: {url} (Caused by {reason!r})"
-
-        super().__init__(pool, url, message)
-
-    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
-        # For pickling purposes.
-        return self.__class__, (None, self.url, self.reason)
-
-
-class HostChangedError(RequestError):
-    """Raised when an existing pool gets a request for a foreign host."""
-
-    def __init__(
-        self, pool: ConnectionPool, url: str, retries: Retry | int = 3
-    ) -> None:
-        message = f"Tried to open a foreign host with url: {url}"
-        super().__init__(pool, url, message)
-        self.retries = retries
-
-
-class TimeoutStateError(HTTPError):
-    """Raised when passing an invalid state to a timeout"""
-
-
-class TimeoutError(HTTPError):
-    """Raised when a socket timeout error occurs.
-
-    Catching this error will catch both :exc:`ReadTimeoutErrors
-    ` and :exc:`ConnectTimeoutErrors `.
-    """
-
-
-class ReadTimeoutError(TimeoutError, RequestError):
-    """Raised when a socket timeout occurs while receiving data from a server"""
-
-
-# This timeout error does not have a URL attached and needs to inherit from the
-# base HTTPError
-class ConnectTimeoutError(TimeoutError):
-    """Raised when a socket timeout occurs while connecting to a server"""
-
-
-class NewConnectionError(ConnectTimeoutError, HTTPError):
-    """Raised when we fail to establish a new connection. Usually ECONNREFUSED."""
-
-    def __init__(self, conn: HTTPConnection, message: str) -> None:
-        self.conn = conn
-        self._message = message
-        super().__init__(f"{conn}: {message}")
-
-    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
-        # For pickling purposes.
-        return self.__class__, (None, self._message)
-
-    @property
-    def pool(self) -> HTTPConnection:
-        warnings.warn(
-            "The 'pool' property is deprecated and will be removed "
-            "in urllib3 v3.0. Use 'conn' instead.",
-            FutureWarning,
-            stacklevel=2,
-        )
-
-        return self.conn
-
-
-class NameResolutionError(NewConnectionError):
-    """Raised when host name resolution fails."""
-
-    def __init__(self, host: str, conn: HTTPConnection, reason: socket.gaierror):
-        message = f"Failed to resolve '{host}' ({reason})"
-        self._host = host
-        self._reason = reason
-        super().__init__(conn, message)
-
-    def __reduce__(self) -> _TYPE_REDUCE_RESULT:
-        # For pickling purposes.
-        return self.__class__, (self._host, None, self._reason)
-
-
-class EmptyPoolError(PoolError):
-    """Raised when a pool runs out of connections and no more are allowed."""
-
-
-class FullPoolError(PoolError):
-    """Raised when we try to add a connection to a full pool in blocking mode."""
-
-
-class ClosedPoolError(PoolError):
-    """Raised when a request enters a pool after the pool has been closed."""
-
-
-class LocationValueError(ValueError, HTTPError):
-    """Raised when there is something wrong with a given URL input."""
-
-
-class LocationParseError(LocationValueError):
-    """Raised when get_host or similar fails to parse the URL input."""
-
-    def __init__(self, location: str) -> None:
-        message = f"Failed to parse: {location}"
-        super().__init__(message)
-
-        self.location = location
-
-
-class URLSchemeUnknown(LocationValueError):
-    """Raised when a URL input has an unsupported scheme."""
-
-    def __init__(self, scheme: str):
-        message = f"Not supported URL scheme {scheme}"
-        super().__init__(message)
-
-        self.scheme = scheme
-
-
-class ResponseError(HTTPError):
-    """Used as a container for an error reason supplied in a MaxRetryError."""
-
-    GENERIC_ERROR = "too many error responses"
-    SPECIFIC_ERROR = "too many {status_code} error responses"
-
-
-class SecurityWarning(HTTPWarning):
-    """Warned when performing security reducing actions"""
-
-
-class InsecureRequestWarning(SecurityWarning):
-    """Warned when making an unverified HTTPS request."""
-
-
-class NotOpenSSLWarning(SecurityWarning):
-    """Warned when using unsupported SSL library"""
-
-
-class SystemTimeWarning(SecurityWarning):
-    """Warned when system time is suspected to be wrong"""
-
-
-class InsecurePlatformWarning(SecurityWarning):
-    """Warned when certain TLS/SSL configuration is not available on a platform."""
-
-
-class DependencyWarning(HTTPWarning):
-    """
-    Warned when an attempt is made to import a module with missing optional
-    dependencies.
-    """
-
-
-class ResponseNotChunked(ProtocolError, ValueError):
-    """Response needs to be chunked in order to read it as chunks."""
-
-
-class BodyNotHttplibCompatible(HTTPError):
-    """
-    Body should be :class:`http.client.HTTPResponse` like
-    (have an fp attribute which returns raw chunks) for read_chunked().
-    """
-
-
-class IncompleteRead(HTTPError, httplib_IncompleteRead):
-    """
-    Response length doesn't match expected Content-Length
-
-    Subclass of :class:`http.client.IncompleteRead` to allow int value
-    for ``partial`` to avoid creating large objects on streamed reads.
-    """
-
-    partial: int  # type: ignore[assignment]
-    expected: int
-
-    def __init__(self, partial: int, expected: int) -> None:
-        self.partial = partial
-        self.expected = expected
-
-    def __repr__(self) -> str:
-        return "IncompleteRead(%i bytes read, %i more expected)" % (
-            self.partial,
-            self.expected,
-        )
-
-
-class InvalidChunkLength(HTTPError, httplib_IncompleteRead):
-    """Invalid chunk length in a chunked response."""
-
-    def __init__(self, response: HTTPResponse, length: bytes) -> None:
-        self.partial: int = response.tell()  # type: ignore[assignment]
-        self.expected: int | None = response.length_remaining
-        self.response = response
-        self.length = length
-
-    def __repr__(self) -> str:
-        return "InvalidChunkLength(got length %r, %i bytes read)" % (
-            self.length,
-            self.partial,
-        )
-
-
-class InvalidHeader(HTTPError):
-    """The header provided was somehow invalid."""
-
-
-class ProxySchemeUnknown(AssertionError, URLSchemeUnknown):
-    """ProxyManager does not support the supplied scheme"""
-
-    # TODO(t-8ch): Stop inheriting from AssertionError in v2.0.
-
-    def __init__(self, scheme: str | None) -> None:
-        # 'localhost' is here because our URL parser parses
-        # localhost:8080 -> scheme=localhost, remove if we fix this.
-        if scheme == "localhost":
-            scheme = None
-        if scheme is None:
-            message = "Proxy URL had no scheme, should start with http:// or https://"
-        else:
-            message = f"Proxy URL had unsupported scheme {scheme}, should use http:// or https://"
-        super().__init__(message)
-
-
-class ProxySchemeUnsupported(ValueError):
-    """Fetching HTTPS resources through HTTPS proxies is unsupported"""
-
-
-class HeaderParsingError(HTTPError):
-    """Raised by assert_header_parsing, but we convert it to a log.warning statement."""
-
-    def __init__(
-        self, defects: list[MessageDefect], unparsed_data: bytes | str | None
-    ) -> None:
-        message = f"{defects or 'Unknown'}, unparsed data: {unparsed_data!r}"
-        super().__init__(message)
-
-
-class UnrewindableBodyError(HTTPError):
-    """urllib3 encountered an error when trying to rewind a body"""
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py
deleted file mode 100644
index fe68e177324..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/fields.py
+++ /dev/null
@@ -1,341 +0,0 @@
-from __future__ import annotations
-
-import email.utils
-import mimetypes
-import typing
-
-_TYPE_FIELD_VALUE = typing.Union[str, bytes]
-_TYPE_FIELD_VALUE_TUPLE = typing.Union[
-    _TYPE_FIELD_VALUE,
-    tuple[str, _TYPE_FIELD_VALUE],
-    tuple[str, _TYPE_FIELD_VALUE, str],
-]
-
-
-def guess_content_type(
-    filename: str | None, default: str = "application/octet-stream"
-) -> str:
-    """
-    Guess the "Content-Type" of a file.
-
-    :param filename:
-        The filename to guess the "Content-Type" of using :mod:`mimetypes`.
-    :param default:
-        If no "Content-Type" can be guessed, default to `default`.
-    """
-    if filename:
-        return mimetypes.guess_type(filename)[0] or default
-    return default
-
-
-def format_header_param_rfc2231(name: str, value: _TYPE_FIELD_VALUE) -> str:
-    """
-    Helper function to format and quote a single header parameter using the
-    strategy defined in RFC 2231.
-
-    Particularly useful for header parameters which might contain
-    non-ASCII values, like file names. This follows
-    `RFC 2388 Section 4.4 `_.
-
-    :param name:
-        The name of the parameter, a string expected to be ASCII only.
-    :param value:
-        The value of the parameter, provided as ``bytes`` or `str``.
-    :returns:
-        An RFC-2231-formatted unicode string.
-
-    .. deprecated:: 2.0.0
-        Will be removed in urllib3 v3.0. This is not valid for
-        ``multipart/form-data`` header parameters.
-    """
-    import warnings
-
-    warnings.warn(
-        "'format_header_param_rfc2231' is insecure, deprecated and will be "
-        "removed in urllib3 v3.0. This is not valid for "
-        "multipart/form-data header parameters.",
-        FutureWarning,
-        stacklevel=2,
-    )
-
-    if isinstance(value, bytes):
-        value = value.decode("utf-8")
-
-    if not any(ch in value for ch in '"\\\r\n'):
-        result = f'{name}="{value}"'
-        try:
-            result.encode("ascii")
-        except (UnicodeEncodeError, UnicodeDecodeError):
-            pass
-        else:
-            return result
-
-    value = email.utils.encode_rfc2231(value, "utf-8")
-    value = f"{name}*={value}"
-
-    return value
-
-
-def format_multipart_header_param(name: str, value: _TYPE_FIELD_VALUE) -> str:
-    """
-    Format and quote a single multipart header parameter.
-
-    This follows the `WHATWG HTML Standard`_ as of 2021/06/10, matching
-    the behavior of current browser and curl versions. Values are
-    assumed to be UTF-8. The ``\\n``, ``\\r``, and ``"`` characters are
-    percent encoded.
-
-    .. _WHATWG HTML Standard:
-        https://html.spec.whatwg.org/multipage/
-        form-control-infrastructure.html#multipart-form-data
-
-    :param name:
-        The name of the parameter, an ASCII-only ``str``.
-    :param value:
-        The value of the parameter, a ``str`` or UTF-8 encoded
-        ``bytes``.
-    :returns:
-        A string ``name="value"`` with the escaped value.
-
-    .. versionchanged:: 2.0.0
-        Matches the WHATWG HTML Standard as of 2021/06/10. Control
-        characters are no longer percent encoded.
-
-    .. versionchanged:: 2.0.0
-        Renamed from ``format_header_param_html5`` and
-        ``format_header_param``. The old names will be removed in
-        urllib3 v3.0.
-    """
-    if isinstance(value, bytes):
-        value = value.decode("utf-8")
-
-    # percent encode \n \r "
-    value = value.translate({10: "%0A", 13: "%0D", 34: "%22"})
-    return f'{name}="{value}"'
-
-
-def format_header_param_html5(name: str, value: _TYPE_FIELD_VALUE) -> str:
-    """
-    .. deprecated:: 2.0.0
-        Renamed to :func:`format_multipart_header_param`. Will be
-        removed in urllib3 v3.0.
-    """
-    import warnings
-
-    warnings.warn(
-        "'format_header_param_html5' has been renamed to "
-        "'format_multipart_header_param'. The old name will be "
-        "removed in urllib3 v3.0.",
-        FutureWarning,
-        stacklevel=2,
-    )
-    return format_multipart_header_param(name, value)
-
-
-def format_header_param(name: str, value: _TYPE_FIELD_VALUE) -> str:
-    """
-    .. deprecated:: 2.0.0
-        Renamed to :func:`format_multipart_header_param`. Will be
-        removed in urllib3 v3.0.
-    """
-    import warnings
-
-    warnings.warn(
-        "'format_header_param' has been renamed to "
-        "'format_multipart_header_param'. The old name will be "
-        "removed in urllib3 v3.0.",
-        FutureWarning,
-        stacklevel=2,
-    )
-    return format_multipart_header_param(name, value)
-
-
-class RequestField:
-    """
-    A data container for request body parameters.
-
-    :param name:
-        The name of this request field. Must be unicode.
-    :param data:
-        The data/value body.
-    :param filename:
-        An optional filename of the request field. Must be unicode.
-    :param headers:
-        An optional dict-like object of headers to initially use for the field.
-
-    .. versionchanged:: 2.0.0
-        The ``header_formatter`` parameter is deprecated and will
-        be removed in urllib3 v3.0.
-    """
-
-    def __init__(
-        self,
-        name: str,
-        data: _TYPE_FIELD_VALUE,
-        filename: str | None = None,
-        headers: typing.Mapping[str, str] | None = None,
-        header_formatter: typing.Callable[[str, _TYPE_FIELD_VALUE], str] | None = None,
-    ):
-        self._name = name
-        self._filename = filename
-        self.data = data
-        self.headers: dict[str, str | None] = {}
-        if headers:
-            self.headers = dict(headers)
-
-        if header_formatter is not None:
-            import warnings
-
-            warnings.warn(
-                "The 'header_formatter' parameter is deprecated and "
-                "will be removed in urllib3 v3.0.",
-                FutureWarning,
-                stacklevel=2,
-            )
-            self.header_formatter = header_formatter
-        else:
-            self.header_formatter = format_multipart_header_param
-
-    @classmethod
-    def from_tuples(
-        cls,
-        fieldname: str,
-        value: _TYPE_FIELD_VALUE_TUPLE,
-        header_formatter: typing.Callable[[str, _TYPE_FIELD_VALUE], str] | None = None,
-    ) -> RequestField:
-        """
-        A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters.
-
-        Supports constructing :class:`~urllib3.fields.RequestField` from
-        parameter of key/value strings AND key/filetuple. A filetuple is a
-        (filename, data, MIME type) tuple where the MIME type is optional.
-        For example::
-
-            'foo': 'bar',
-            'fakefile': ('foofile.txt', 'contents of foofile'),
-            'realfile': ('barfile.txt', open('realfile').read()),
-            'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'),
-            'nonamefile': 'contents of nonamefile field',
-
-        Field names and filenames must be unicode.
-        """
-        filename: str | None
-        content_type: str | None
-        data: _TYPE_FIELD_VALUE
-
-        if isinstance(value, tuple):
-            if len(value) == 3:
-                filename, data, content_type = value
-            else:
-                filename, data = value
-                content_type = guess_content_type(filename)
-        else:
-            filename = None
-            content_type = None
-            data = value
-
-        request_param = cls(
-            fieldname, data, filename=filename, header_formatter=header_formatter
-        )
-        request_param.make_multipart(content_type=content_type)
-
-        return request_param
-
-    def _render_part(self, name: str, value: _TYPE_FIELD_VALUE) -> str:
-        """
-        Override this method to change how each multipart header
-        parameter is formatted. By default, this calls
-        :func:`format_multipart_header_param`.
-
-        :param name:
-            The name of the parameter, an ASCII-only ``str``.
-        :param value:
-            The value of the parameter, a ``str`` or UTF-8 encoded
-            ``bytes``.
-
-        :meta public:
-        """
-        return self.header_formatter(name, value)
-
-    def _render_parts(
-        self,
-        header_parts: (
-            dict[str, _TYPE_FIELD_VALUE | None]
-            | typing.Sequence[tuple[str, _TYPE_FIELD_VALUE | None]]
-        ),
-    ) -> str:
-        """
-        Helper function to format and quote a single header.
-
-        Useful for single headers that are composed of multiple items. E.g.,
-        'Content-Disposition' fields.
-
-        :param header_parts:
-            A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format
-            as `k1="v1"; k2="v2"; ...`.
-        """
-        iterable: typing.Iterable[tuple[str, _TYPE_FIELD_VALUE | None]]
-
-        parts = []
-        if isinstance(header_parts, dict):
-            iterable = header_parts.items()
-        else:
-            iterable = header_parts
-
-        for name, value in iterable:
-            if value is not None:
-                parts.append(self._render_part(name, value))
-
-        return "; ".join(parts)
-
-    def render_headers(self) -> str:
-        """
-        Renders the headers for this request field.
-        """
-        lines = []
-
-        sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"]
-        for sort_key in sort_keys:
-            if self.headers.get(sort_key, False):
-                lines.append(f"{sort_key}: {self.headers[sort_key]}")
-
-        for header_name, header_value in self.headers.items():
-            if header_name not in sort_keys:
-                if header_value:
-                    lines.append(f"{header_name}: {header_value}")
-
-        lines.append("\r\n")
-        return "\r\n".join(lines)
-
-    def make_multipart(
-        self,
-        content_disposition: str | None = None,
-        content_type: str | None = None,
-        content_location: str | None = None,
-    ) -> None:
-        """
-        Makes this request field into a multipart request field.
-
-        This method overrides "Content-Disposition", "Content-Type" and
-        "Content-Location" headers to the request parameter.
-
-        :param content_disposition:
-            The 'Content-Disposition' of the request body. Defaults to 'form-data'
-        :param content_type:
-            The 'Content-Type' of the request body.
-        :param content_location:
-            The 'Content-Location' of the request body.
-
-        """
-        content_disposition = (content_disposition or "form-data") + "; ".join(
-            [
-                "",
-                self._render_parts(
-                    (("name", self._name), ("filename", self._filename))
-                ),
-            ]
-        )
-
-        self.headers["Content-Disposition"] = content_disposition
-        self.headers["Content-Type"] = content_type
-        self.headers["Content-Location"] = content_location
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py
deleted file mode 100644
index 14f70b05b47..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/filepost.py
+++ /dev/null
@@ -1,89 +0,0 @@
-from __future__ import annotations
-
-import binascii
-import codecs
-import os
-import typing
-from io import BytesIO
-
-from .fields import _TYPE_FIELD_VALUE_TUPLE, RequestField
-
-writer = codecs.lookup("utf-8")[3]
-
-_TYPE_FIELDS_SEQUENCE = typing.Sequence[
-    typing.Union[tuple[str, _TYPE_FIELD_VALUE_TUPLE], RequestField]
-]
-_TYPE_FIELDS = typing.Union[
-    _TYPE_FIELDS_SEQUENCE,
-    typing.Mapping[str, _TYPE_FIELD_VALUE_TUPLE],
-]
-
-
-def choose_boundary() -> str:
-    """
-    Our embarrassingly-simple replacement for mimetools.choose_boundary.
-    """
-    return binascii.hexlify(os.urandom(16)).decode()
-
-
-def iter_field_objects(fields: _TYPE_FIELDS) -> typing.Iterable[RequestField]:
-    """
-    Iterate over fields.
-
-    Supports list of (k, v) tuples and dicts, and lists of
-    :class:`~urllib3.fields.RequestField`.
-
-    """
-    iterable: typing.Iterable[RequestField | tuple[str, _TYPE_FIELD_VALUE_TUPLE]]
-
-    if isinstance(fields, typing.Mapping):
-        iterable = fields.items()
-    else:
-        iterable = fields
-
-    for field in iterable:
-        if isinstance(field, RequestField):
-            yield field
-        else:
-            yield RequestField.from_tuples(*field)
-
-
-def encode_multipart_formdata(
-    fields: _TYPE_FIELDS, boundary: str | None = None
-) -> tuple[bytes, str]:
-    """
-    Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
-
-    :param fields:
-        Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
-        Values are processed by :func:`urllib3.fields.RequestField.from_tuples`.
-
-    :param boundary:
-        If not specified, then a random boundary will be generated using
-        :func:`urllib3.filepost.choose_boundary`.
-    """
-    body = BytesIO()
-    if boundary is None:
-        boundary = choose_boundary()
-
-    for field in iter_field_objects(fields):
-        body.write(f"--{boundary}\r\n".encode("latin-1"))
-
-        writer(body).write(field.render_headers())
-        data = field.data
-
-        if isinstance(data, int):
-            data = str(data)  # Backwards compatibility
-
-        if isinstance(data, str):
-            writer(body).write(data)
-        else:
-            body.write(data)
-
-        body.write(b"\r\n")
-
-    body.write(f"--{boundary}--\r\n".encode("latin-1"))
-
-    content_type = f"multipart/form-data; boundary={boundary}"
-
-    return body.getvalue(), content_type
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py
deleted file mode 100644
index 133e1d8f237..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/__init__.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from __future__ import annotations
-
-from importlib.metadata import version
-
-__all__ = [
-    "inject_into_urllib3",
-    "extract_from_urllib3",
-]
-
-import typing
-
-orig_HTTPSConnection: typing.Any = None
-
-
-def inject_into_urllib3() -> None:
-    # First check if h2 version is valid
-    h2_version = version("h2")
-    if not h2_version.startswith("4."):
-        raise ImportError(
-            "urllib3 v2 supports h2 version 4.x.x, currently "
-            f"the 'h2' module is compiled with {h2_version!r}. "
-            "See: https://github.com/urllib3/urllib3/issues/3290"
-        )
-
-    # Import here to avoid circular dependencies.
-    from .. import connection as urllib3_connection
-    from .. import util as urllib3_util
-    from ..connectionpool import HTTPSConnectionPool
-    from ..util import ssl_ as urllib3_util_ssl
-    from .connection import HTTP2Connection
-
-    global orig_HTTPSConnection
-    orig_HTTPSConnection = urllib3_connection.HTTPSConnection
-
-    HTTPSConnectionPool.ConnectionCls = HTTP2Connection
-    urllib3_connection.HTTPSConnection = HTTP2Connection  # type: ignore[misc]
-
-    # TODO: Offer 'http/1.1' as well, but for testing purposes this is handy.
-    urllib3_util.ALPN_PROTOCOLS = ["h2"]
-    urllib3_util_ssl.ALPN_PROTOCOLS = ["h2"]
-
-
-def extract_from_urllib3() -> None:
-    from .. import connection as urllib3_connection
-    from .. import util as urllib3_util
-    from ..connectionpool import HTTPSConnectionPool
-    from ..util import ssl_ as urllib3_util_ssl
-
-    HTTPSConnectionPool.ConnectionCls = orig_HTTPSConnection
-    urllib3_connection.HTTPSConnection = orig_HTTPSConnection  # type: ignore[misc]
-
-    urllib3_util.ALPN_PROTOCOLS = ["http/1.1"]
-    urllib3_util_ssl.ALPN_PROTOCOLS = ["http/1.1"]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py
deleted file mode 100644
index 9ea900764f0..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/http2/probe.py
+++ /dev/null
@@ -1,87 +0,0 @@
-from __future__ import annotations
-
-import threading
-
-
-class _HTTP2ProbeCache:
-    __slots__ = (
-        "_lock",
-        "_cache_locks",
-        "_cache_values",
-    )
-
-    def __init__(self) -> None:
-        self._lock = threading.Lock()
-        self._cache_locks: dict[tuple[str, int], threading.RLock] = {}
-        self._cache_values: dict[tuple[str, int], bool | None] = {}
-
-    def acquire_and_get(self, host: str, port: int) -> bool | None:
-        # By the end of this block we know that
-        # _cache_[values,locks] is available.
-        value = None
-        with self._lock:
-            key = (host, port)
-            try:
-                value = self._cache_values[key]
-                # If it's a known value we return right away.
-                if value is not None:
-                    return value
-            except KeyError:
-                self._cache_locks[key] = threading.RLock()
-                self._cache_values[key] = None
-
-        # If the value is unknown, we acquire the lock to signal
-        # to the requesting thread that the probe is in progress
-        # or that the current thread needs to return their findings.
-        key_lock = self._cache_locks[key]
-        key_lock.acquire()
-        try:
-            # If the by the time we get the lock the value has been
-            # updated we want to return the updated value.
-            value = self._cache_values[key]
-
-        # In case an exception like KeyboardInterrupt is raised here.
-        except BaseException as e:  # Defensive:
-            assert not isinstance(e, KeyError)  # KeyError shouldn't be possible.
-            key_lock.release()
-            raise
-
-        return value
-
-    def set_and_release(
-        self, host: str, port: int, supports_http2: bool | None
-    ) -> None:
-        key = (host, port)
-        key_lock = self._cache_locks[key]
-        with key_lock:  # Uses an RLock, so can be locked again from same thread.
-            if supports_http2 is None and self._cache_values[key] is not None:
-                raise ValueError(
-                    "Cannot reset HTTP/2 support for origin after value has been set."
-                )  # Defensive: not expected in normal usage
-
-        self._cache_values[key] = supports_http2
-        key_lock.release()
-
-    def _values(self) -> dict[tuple[str, int], bool | None]:
-        """This function is for testing purposes only. Gets the current state of the probe cache"""
-        with self._lock:
-            return {k: v for k, v in self._cache_values.items()}
-
-    def _reset(self) -> None:
-        """This function is for testing purposes only. Reset the cache values"""
-        with self._lock:
-            self._cache_locks = {}
-            self._cache_values = {}
-
-
-_HTTP2_PROBE_CACHE = _HTTP2ProbeCache()
-
-set_and_release = _HTTP2_PROBE_CACHE.set_and_release
-acquire_and_get = _HTTP2_PROBE_CACHE.acquire_and_get
-_values = _HTTP2_PROBE_CACHE._values
-_reset = _HTTP2_PROBE_CACHE._reset
-
-__all__ = [
-    "set_and_release",
-    "acquire_and_get",
-]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py
deleted file mode 100644
index 83157e8d66a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/poolmanager.py
+++ /dev/null
@@ -1,677 +0,0 @@
-from __future__ import annotations
-
-import functools
-import logging
-import typing
-import warnings
-from types import TracebackType
-from urllib.parse import urljoin
-
-from ._collections import HTTPHeaderDict, RecentlyUsedContainer
-from ._request_methods import RequestMethods
-from .connection import ProxyConfig
-from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
-from .exceptions import (
-    LocationValueError,
-    MaxRetryError,
-    ProxySchemeUnknown,
-    URLSchemeUnknown,
-)
-from .response import BaseHTTPResponse
-from .util.connection import _TYPE_SOCKET_OPTIONS
-from .util.proxy import connection_requires_http_tunnel
-from .util.retry import Retry
-from .util.timeout import Timeout
-from .util.url import Url, parse_url
-
-if typing.TYPE_CHECKING:
-    import ssl
-
-    from opentelemetry.agent._vendor.typing_extensions import Self
-
-__all__ = ["PoolManager", "ProxyManager", "proxy_from_url"]
-
-
-log = logging.getLogger(__name__)
-
-SSL_KEYWORDS = (
-    "key_file",
-    "cert_file",
-    "cert_reqs",
-    "ca_certs",
-    "ca_cert_data",
-    "ssl_version",
-    "ssl_minimum_version",
-    "ssl_maximum_version",
-    "ca_cert_dir",
-    "ssl_context",
-    "key_password",
-    "server_hostname",
-    "assert_hostname",
-    "assert_fingerprint",
-)
-# Default value for `blocksize` - a new parameter introduced to
-# http.client.HTTPConnection & http.client.HTTPSConnection in Python 3.7
-_DEFAULT_BLOCKSIZE = 16384
-
-
-class PoolKey(typing.NamedTuple):
-    """
-    All known keyword arguments that could be provided to the pool manager, its
-    pools, or the underlying connections.
-
-    All custom key schemes should include the fields in this key at a minimum.
-    """
-
-    key_scheme: str
-    key_host: str
-    key_port: int | None
-    key_timeout: Timeout | float | int | None
-    key_retries: Retry | bool | int | None
-    key_block: bool | None
-    key_source_address: tuple[str, int] | None
-    key_key_file: str | None
-    key_key_password: str | None
-    key_cert_file: str | None
-    key_cert_reqs: str | None
-    key_ca_certs: str | None
-    key_ca_cert_data: str | bytes | None
-    key_ssl_version: int | str | None
-    key_ssl_minimum_version: ssl.TLSVersion | None
-    key_ssl_maximum_version: ssl.TLSVersion | None
-    key_ca_cert_dir: str | None
-    key_ssl_context: ssl.SSLContext | None
-    key_maxsize: int | None
-    key_headers: frozenset[tuple[str, str]] | None
-    key__proxy: Url | None
-    key__proxy_headers: frozenset[tuple[str, str]] | None
-    key__proxy_config: ProxyConfig | None
-    key_socket_options: _TYPE_SOCKET_OPTIONS | None
-    key__socks_options: frozenset[tuple[str, str]] | None
-    key_assert_hostname: bool | str | None
-    key_assert_fingerprint: str | None
-    key_server_hostname: str | None
-    key_blocksize: int | None
-
-
-def _default_key_normalizer(
-    key_class: type[PoolKey], request_context: dict[str, typing.Any]
-) -> PoolKey:
-    """
-    Create a pool key out of a request context dictionary.
-
-    According to RFC 3986, both the scheme and host are case-insensitive.
-    Therefore, this function normalizes both before constructing the pool
-    key for an HTTPS request. If you wish to change this behaviour, provide
-    alternate callables to ``key_fn_by_scheme``.
-
-    :param key_class:
-        The class to use when constructing the key. This should be a namedtuple
-        with the ``scheme`` and ``host`` keys at a minimum.
-    :type  key_class: namedtuple
-    :param request_context:
-        A dictionary-like object that contain the context for a request.
-    :type  request_context: dict
-
-    :return: A namedtuple that can be used as a connection pool key.
-    :rtype:  PoolKey
-    """
-    # Since we mutate the dictionary, make a copy first
-    context = request_context.copy()
-    context["scheme"] = context["scheme"].lower()
-    context["host"] = context["host"].lower()
-
-    # These are both dictionaries and need to be transformed into frozensets
-    for key in ("headers", "_proxy_headers", "_socks_options"):
-        if key in context and context[key] is not None:
-            context[key] = frozenset(context[key].items())
-
-    # The socket_options key may be a list and needs to be transformed into a
-    # tuple.
-    socket_opts = context.get("socket_options")
-    if socket_opts is not None:
-        context["socket_options"] = tuple(socket_opts)
-
-    # Map the kwargs to the names in the namedtuple - this is necessary since
-    # namedtuples can't have fields starting with '_'.
-    for key in list(context.keys()):
-        context["key_" + key] = context.pop(key)
-
-    # Default to ``None`` for keys missing from the context
-    for field in key_class._fields:
-        if field not in context:
-            context[field] = None
-
-    # Default key_blocksize to _DEFAULT_BLOCKSIZE if missing from the context
-    if context.get("key_blocksize") is None:
-        context["key_blocksize"] = _DEFAULT_BLOCKSIZE
-
-    return key_class(**context)
-
-
-#: A dictionary that maps a scheme to a callable that creates a pool key.
-#: This can be used to alter the way pool keys are constructed, if desired.
-#: Each PoolManager makes a copy of this dictionary so they can be configured
-#: globally here, or individually on the instance.
-key_fn_by_scheme = {
-    "http": functools.partial(_default_key_normalizer, PoolKey),
-    "https": functools.partial(_default_key_normalizer, PoolKey),
-}
-
-pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool}
-
-
-class PoolManager(RequestMethods):
-    """
-    Allows for arbitrary requests while transparently keeping track of
-    necessary connection pools for you.
-
-    :param num_pools:
-        Number of connection pools to cache before discarding the least
-        recently used pool.
-
-    :param headers:
-        Headers to include with all requests, unless other headers are given
-        explicitly.
-
-    :param \\**connection_pool_kw:
-        Additional parameters are used to create fresh
-        :class:`urllib3.connectionpool.ConnectionPool` instances.
-
-    Example:
-
-    .. code-block:: python
-
-        import urllib3
-
-        http = urllib3.PoolManager(num_pools=2)
-
-        resp1 = http.request("GET", "https://google.com/")
-        resp2 = http.request("GET", "https://google.com/mail")
-        resp3 = http.request("GET", "https://yahoo.com/")
-
-        print(len(http.pools))
-        # 2
-
-    """
-
-    proxy: Url | None = None
-    proxy_config: ProxyConfig | None = None
-
-    def __init__(
-        self,
-        num_pools: int = 10,
-        headers: typing.Mapping[str, str] | None = None,
-        **connection_pool_kw: typing.Any,
-    ) -> None:
-        super().__init__(headers)
-        # PoolManager handles redirects itself in PoolManager.urlopen().
-        # It always passes redirect=False to the underlying connection pool to
-        # suppress per-pool redirect handling. If the user supplied a non-Retry
-        # value (int/bool/etc) for retries and we let the pool normalize it
-        # while redirect=False, the resulting Retry object would have redirect
-        # handling disabled, which can interfere with PoolManager's own
-        # redirect logic. Normalize here so redirects remain governed solely by
-        # PoolManager logic.
-        if "retries" in connection_pool_kw:
-            retries = connection_pool_kw["retries"]
-            if not isinstance(retries, Retry):
-                retries = Retry.from_int(retries)
-                connection_pool_kw = connection_pool_kw.copy()
-                connection_pool_kw["retries"] = retries
-        self.connection_pool_kw = connection_pool_kw
-
-        self.pools: RecentlyUsedContainer[PoolKey, HTTPConnectionPool]
-        self.pools = RecentlyUsedContainer(num_pools)
-
-        # Locally set the pool classes and keys so other PoolManagers can
-        # override them.
-        self.pool_classes_by_scheme = pool_classes_by_scheme
-        self.key_fn_by_scheme = key_fn_by_scheme.copy()
-
-    def __enter__(self) -> Self:
-        return self
-
-    def __exit__(
-        self,
-        exc_type: type[BaseException] | None,
-        exc_val: BaseException | None,
-        exc_tb: TracebackType | None,
-    ) -> typing.Literal[False]:
-        self.clear()
-        # Return False to re-raise any potential exceptions
-        return False
-
-    def _new_pool(
-        self,
-        scheme: str,
-        host: str,
-        port: int,
-        request_context: dict[str, typing.Any] | None = None,
-    ) -> HTTPConnectionPool:
-        """
-        Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and
-        any additional pool keyword arguments.
-
-        If ``request_context`` is provided, it is provided as keyword arguments
-        to the pool class used. This method is used to actually create the
-        connection pools handed out by :meth:`connection_from_url` and
-        companion methods. It is intended to be overridden for customization.
-        """
-        pool_cls: type[HTTPConnectionPool] = self.pool_classes_by_scheme[scheme]
-        if request_context is None:
-            request_context = self.connection_pool_kw.copy()
-
-        # Default blocksize to _DEFAULT_BLOCKSIZE if missing or explicitly
-        # set to 'None' in the request_context.
-        if request_context.get("blocksize") is None:
-            request_context["blocksize"] = _DEFAULT_BLOCKSIZE
-
-        # Although the context has everything necessary to create the pool,
-        # this function has historically only used the scheme, host, and port
-        # in the positional args. When an API change is acceptable these can
-        # be removed.
-        for key in ("scheme", "host", "port"):
-            request_context.pop(key, None)
-
-        if scheme == "http":
-            for kw in SSL_KEYWORDS:
-                request_context.pop(kw, None)
-
-        return pool_cls(host, port, **request_context)
-
-    def clear(self) -> None:
-        """
-        Empty our store of pools and direct them all to close.
-
-        This will not affect in-flight connections, but they will not be
-        re-used after completion.
-        """
-        self.pools.clear()
-
-    def connection_from_host(
-        self,
-        host: str | None,
-        port: int | None = None,
-        scheme: str | None = "http",
-        pool_kwargs: dict[str, typing.Any] | None = None,
-    ) -> HTTPConnectionPool:
-        """
-        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
-
-        If ``port`` isn't given, it will be derived from the ``scheme`` using
-        ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
-        provided, it is merged with the instance's ``connection_pool_kw``
-        variable and used to create the new connection pool, if one is
-        needed.
-        """
-
-        if not host:
-            raise LocationValueError("No host specified.")
-
-        request_context = self._merge_pool_kwargs(pool_kwargs)
-        request_context["scheme"] = scheme or "http"
-        if port is None:
-            port = port_by_scheme.get(request_context["scheme"].lower(), 80)
-        request_context["port"] = port
-        request_context["host"] = host
-
-        return self.connection_from_context(request_context)
-
-    def connection_from_context(
-        self, request_context: dict[str, typing.Any]
-    ) -> HTTPConnectionPool:
-        """
-        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context.
-
-        ``request_context`` must at least contain the ``scheme`` key and its
-        value must be a key in ``key_fn_by_scheme`` instance variable.
-        """
-        if "strict" in request_context:
-            warnings.warn(
-                "The 'strict' parameter is no longer needed on Python 3+. "
-                "This will raise an error in urllib3 v3.0.",
-                FutureWarning,
-            )
-            request_context.pop("strict")
-
-        scheme = request_context["scheme"].lower()
-        pool_key_constructor = self.key_fn_by_scheme.get(scheme)
-        if not pool_key_constructor:
-            raise URLSchemeUnknown(scheme)
-        pool_key = pool_key_constructor(request_context)
-
-        return self.connection_from_pool_key(pool_key, request_context=request_context)
-
-    def connection_from_pool_key(
-        self, pool_key: PoolKey, request_context: dict[str, typing.Any]
-    ) -> HTTPConnectionPool:
-        """
-        Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key.
-
-        ``pool_key`` should be a namedtuple that only contains immutable
-        objects. At a minimum it must have the ``scheme``, ``host``, and
-        ``port`` fields.
-        """
-        with self.pools.lock:
-            # If the scheme, host, or port doesn't match existing open
-            # connections, open a new ConnectionPool.
-            pool = self.pools.get(pool_key)
-            if pool:
-                return pool
-
-            # Make a fresh ConnectionPool of the desired type
-            scheme = request_context["scheme"]
-            host = request_context["host"]
-            port = request_context["port"]
-            pool = self._new_pool(scheme, host, port, request_context=request_context)
-            self.pools[pool_key] = pool
-
-        return pool
-
-    def connection_from_url(
-        self, url: str, pool_kwargs: dict[str, typing.Any] | None = None
-    ) -> HTTPConnectionPool:
-        """
-        Similar to :func:`urllib3.connectionpool.connection_from_url`.
-
-        If ``pool_kwargs`` is not provided and a new pool needs to be
-        constructed, ``self.connection_pool_kw`` is used to initialize
-        the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
-        is provided, it is used instead. Note that if a new pool does not
-        need to be created for the request, the provided ``pool_kwargs`` are
-        not used.
-        """
-        u = parse_url(url)
-        return self.connection_from_host(
-            u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs
-        )
-
-    def _merge_pool_kwargs(
-        self, override: dict[str, typing.Any] | None
-    ) -> dict[str, typing.Any]:
-        """
-        Merge a dictionary of override values for self.connection_pool_kw.
-
-        This does not modify self.connection_pool_kw and returns a new dict.
-        Any keys in the override dictionary with a value of ``None`` are
-        removed from the merged dictionary.
-        """
-        base_pool_kwargs = self.connection_pool_kw.copy()
-        if override:
-            for key, value in override.items():
-                if value is None:
-                    try:
-                        del base_pool_kwargs[key]
-                    except KeyError:
-                        pass
-                else:
-                    base_pool_kwargs[key] = value
-        return base_pool_kwargs
-
-    def _proxy_requires_url_absolute_form(self, parsed_url: Url) -> bool:
-        """
-        Indicates if the proxy requires the complete destination URL in the
-        request.  Normally this is only needed when not using an HTTP CONNECT
-        tunnel.
-        """
-        if self.proxy is None:
-            return False
-
-        return not connection_requires_http_tunnel(
-            self.proxy, self.proxy_config, parsed_url.scheme
-        )
-
-    def urlopen(  # type: ignore[override]
-        self, method: str, url: str, redirect: bool = True, **kw: typing.Any
-    ) -> BaseHTTPResponse:
-        """
-        Same as :meth:`urllib3.HTTPConnectionPool.urlopen`
-        with custom cross-host redirect logic and only sends the request-uri
-        portion of the ``url``.
-
-        The given ``url`` parameter must be absolute, such that an appropriate
-        :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
-        """
-        u = parse_url(url)
-
-        if u.scheme is None:
-            warnings.warn(
-                "URLs without a scheme (ie 'https://') are deprecated and will raise an error "
-                "in urllib3 v3.0. To avoid this FutureWarning ensure all URLs "
-                "start with 'https://' or 'http://'. Read more in this issue: "
-                "https://github.com/urllib3/urllib3/issues/2920",
-                category=FutureWarning,
-                stacklevel=2,
-            )
-
-        conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
-
-        kw["assert_same_host"] = False
-        kw["redirect"] = False
-
-        if "headers" not in kw:
-            kw["headers"] = self.headers
-
-        if self._proxy_requires_url_absolute_form(u):
-            response = conn.urlopen(method, u._replace(fragment=None).url, **kw)
-        else:
-            response = conn.urlopen(method, u.request_uri, **kw)
-
-        redirect_location = redirect and response.get_redirect_location()
-        if not redirect_location:
-            return response
-
-        # Support relative URLs for redirecting.
-        redirect_location = urljoin(url, redirect_location)
-
-        if response.status == 303:
-            # Change the method according to RFC 9110, Section 15.4.4.
-            method = "GET"
-            # And lose the body not to transfer anything sensitive.
-            kw["body"] = None
-            # The body is gone, so the state that describes it has to go too:
-            # there is nothing left to frame with chunked transfer encoding,
-            # and nothing left to rewind.
-            kw["chunked"] = False
-            kw["body_pos"] = None
-            kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()
-
-        retries = kw.get("retries", response.retries)
-        if not isinstance(retries, Retry):
-            retries = Retry.from_int(retries, redirect=redirect)
-
-        # Strip headers marked as unsafe to forward to the redirected location.
-        # Check remove_headers_on_redirect to avoid a potential network call within
-        # conn.is_same_host() which may use socket.gethostbyname() in the future.
-        if retries.remove_headers_on_redirect and not conn.is_same_host(
-            redirect_location
-        ):
-            new_headers = kw["headers"].copy()
-            for header in kw["headers"]:
-                if header.lower() in retries.remove_headers_on_redirect:
-                    new_headers.pop(header, None)
-            kw["headers"] = new_headers
-
-        try:
-            retries = retries.increment(method, url, response=response, _pool=conn)
-        except MaxRetryError:
-            if retries.raise_on_redirect:
-                response.drain_conn()
-                raise
-            return response
-
-        kw["retries"] = retries
-        kw["redirect"] = redirect
-
-        log.info("Redirecting %s -> %s", url, redirect_location)
-
-        response.drain_conn()
-        return self.urlopen(method, redirect_location, **kw)
-
-
-class ProxyManager(PoolManager):
-    """
-    Behaves just like :class:`PoolManager`, but sends all requests through
-    the defined proxy, using the CONNECT method for HTTPS URLs.
-
-    :param proxy_url:
-        The URL of the proxy to be used.
-
-    :param proxy_headers:
-        A dictionary containing headers that will be sent to the proxy. In case
-        of HTTP they are being sent with each request, while in the
-        HTTPS/CONNECT case they are sent only once. Could be used for proxy
-        authentication.
-
-    :param proxy_ssl_context:
-        The proxy SSL context is used to establish the TLS connection to the
-        proxy when using HTTPS proxies.
-
-    :param use_forwarding_for_https:
-        (Defaults to False) If set to True will forward requests to the HTTPS
-        proxy to be made on behalf of the client instead of creating a TLS
-        tunnel via the CONNECT method. **Enabling this flag means that request
-        and response headers and content will be visible from the HTTPS proxy**
-        whereas tunneling keeps request and response headers and content
-        private.  IP address, target hostname, SNI, and port are always visible
-        to an HTTPS proxy even when this flag is disabled.
-
-    :param proxy_assert_hostname:
-        The hostname of the certificate to verify against.
-
-    :param proxy_assert_fingerprint:
-        The fingerprint of the certificate to verify against.
-
-    Example:
-
-    .. code-block:: python
-
-        import urllib3
-
-        proxy = urllib3.ProxyManager("https://localhost:3128/")
-
-        resp1 = proxy.request("GET", "http://google.com/")
-        resp2 = proxy.request("GET", "http://httpbin.org/")
-
-        # One pool was shared by both plain HTTP requests.
-        print(len(proxy.pools))
-        # 1
-
-        resp3 = proxy.request("GET", "https://httpbin.org/")
-        resp4 = proxy.request("GET", "https://twitter.com/")
-
-        # A separate pool was added for each HTTPS target.
-        print(len(proxy.pools))
-        # 3
-
-    """
-
-    def __init__(
-        self,
-        proxy_url: str,
-        num_pools: int = 10,
-        headers: typing.Mapping[str, str] | None = None,
-        proxy_headers: typing.Mapping[str, str] | None = None,
-        proxy_ssl_context: ssl.SSLContext | None = None,
-        use_forwarding_for_https: bool = False,
-        proxy_assert_hostname: None | str | typing.Literal[False] = None,
-        proxy_assert_fingerprint: str | None = None,
-        **connection_pool_kw: typing.Any,
-    ) -> None:
-        if isinstance(proxy_url, HTTPConnectionPool):
-            str_proxy_url = f"{proxy_url.scheme}://{proxy_url.host}:{proxy_url.port}"
-        else:
-            str_proxy_url = proxy_url
-        proxy = parse_url(str_proxy_url)
-
-        if proxy.scheme not in ("http", "https"):
-            raise ProxySchemeUnknown(proxy.scheme)
-
-        # Keep the deprecated ssl_context fallback on the manager for
-        # compatibility, while passing only explicit proxy policy to connections.
-        self.proxy_ssl_context = proxy_ssl_context
-        if (
-            use_forwarding_for_https
-            and proxy.scheme == "https"
-            and connection_pool_kw.get("ssl_context") is not None
-        ):
-            warnings.warn(
-                "Passing ssl_context when use_forwarding_for_https=True is deprecated "
-                "and will raise an error in urllib3 v3.0. "
-                "Use proxy_ssl_context to configure the TLS connection to the proxy.",
-                FutureWarning,
-                stacklevel=2,
-            )
-            if self.proxy_ssl_context is None:
-                self.proxy_ssl_context = connection_pool_kw.get("ssl_context")
-
-        if proxy.port is None:
-            port = port_by_scheme.get(proxy.scheme, 80)
-            proxy = proxy._replace(port=port)
-
-        self.proxy = proxy
-        self.proxy_headers = proxy_headers or {}
-        self.proxy_config = ProxyConfig(
-            proxy_ssl_context,
-            use_forwarding_for_https,
-            proxy_assert_hostname,
-            proxy_assert_fingerprint,
-        )
-
-        connection_pool_kw["_proxy"] = self.proxy
-        connection_pool_kw["_proxy_headers"] = self.proxy_headers
-        connection_pool_kw["_proxy_config"] = self.proxy_config
-
-        super().__init__(num_pools, headers, **connection_pool_kw)
-
-    def connection_from_host(
-        self,
-        host: str | None,
-        port: int | None = None,
-        scheme: str | None = "http",
-        pool_kwargs: dict[str, typing.Any] | None = None,
-    ) -> HTTPConnectionPool:
-        if scheme == "https":
-            return super().connection_from_host(
-                host, port, scheme, pool_kwargs=pool_kwargs
-            )
-
-        return super().connection_from_host(
-            self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs  # type: ignore[union-attr]
-        )
-
-    def _set_proxy_headers(
-        self, url: str, headers: typing.Mapping[str, str] | None = None
-    ) -> typing.Mapping[str, str]:
-        """
-        Sets headers needed by proxies: specifically, the Accept and Host
-        headers. Only sets headers not provided by the user.
-        """
-        headers_ = {"Accept": "*/*"}
-
-        netloc = parse_url(url).netloc
-        if netloc:
-            headers_["Host"] = netloc
-
-        if headers:
-            headers_.update(headers)
-        return headers_
-
-    def urlopen(  # type: ignore[override]
-        self, method: str, url: str, redirect: bool = True, **kw: typing.Any
-    ) -> BaseHTTPResponse:
-        "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
-        u = parse_url(url)
-        if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme):
-            # For connections using HTTP CONNECT, httplib sets the necessary
-            # headers on the CONNECT to the proxy. If we're not using CONNECT,
-            # we'll definitely need to set 'Host' at the very least.
-            headers = kw.get("headers", self.headers)
-            kw["headers"] = self._set_proxy_headers(url, headers)
-
-        return super().urlopen(method, url, redirect=redirect, **kw)
-
-
-def proxy_from_url(url: str, **kw: typing.Any) -> ProxyManager:
-    return ProxyManager(proxy_url=url, **kw)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py
deleted file mode 100644
index ec7d3083307..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/response.py
+++ /dev/null
@@ -1,1526 +0,0 @@
-from __future__ import annotations
-
-import collections
-import io
-import json as _json
-import logging
-import socket
-import sys
-import typing
-import warnings
-import zlib
-from contextlib import contextmanager
-from http.client import HTTPMessage as _HttplibHTTPMessage
-from http.client import HTTPResponse as _HttplibHTTPResponse
-from socket import timeout as SocketTimeout
-
-if typing.TYPE_CHECKING:
-    from ._base_connection import BaseHTTPConnection
-
-try:
-    try:
-        import brotlicffi as brotli  # type: ignore[import-not-found]
-    except ImportError:
-        import brotli  # type: ignore[import-not-found]
-except ImportError:
-    brotli = None
-
-from . import util
-from ._base_connection import _TYPE_BODY
-from ._collections import HTTPHeaderDict
-from .connection import BaseSSLError, HTTPConnection, HTTPException
-from .exceptions import (
-    BodyNotHttplibCompatible,
-    DecodeError,
-    DependencyWarning,
-    HTTPError,
-    IncompleteRead,
-    InvalidChunkLength,
-    InvalidHeader,
-    ProtocolError,
-    ReadTimeoutError,
-    ResponseNotChunked,
-    SSLError,
-)
-from .util.response import is_fp_closed, is_response_to_head
-from .util.retry import Retry
-
-if typing.TYPE_CHECKING:
-    from .connectionpool import HTTPConnectionPool
-
-log = logging.getLogger(__name__)
-
-# Read in 64 KiB chunks
-_READ_CHUNK_SIZE = 2**16
-
-# Maximum length of a chunk-size line (and the trailing CRLF line) when reading a
-# chunked-transfer-encoded response. Matches ``http.client._MAXLINE`` so urllib3's
-# streaming path bounds these reads exactly like the stdlib ``.read()`` path does,
-# preventing a malicious server from forcing unbounded buffering (memory exhaustion)
-# via an unterminated chunk-size line.
-_MAX_CHUNK_LINE_LENGTH = 2**16
-
-
-class ContentDecoder:
-    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
-        raise NotImplementedError()
-
-    @property
-    def has_unconsumed_tail(self) -> bool:
-        raise NotImplementedError()
-
-    def flush(self) -> bytes:
-        raise NotImplementedError()
-
-
-class DeflateDecoder(ContentDecoder):
-    def __init__(self) -> None:
-        self._first_try = True
-        self._first_try_data = b""
-        self._unfed_data = b""
-        self._obj = zlib.decompressobj()
-
-    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
-        data = self._unfed_data + data
-        self._unfed_data = b""
-        # Data received after EOF cannot produce more output from this
-        # Deflate stream.
-        if self._obj.eof:
-            return b""
-        if not data and not self._obj.unconsumed_tail:
-            return data
-        original_max_length = max_length
-        if original_max_length < 0:
-            max_length = 0
-        elif original_max_length == 0:
-            # We should not pass 0 to the zlib decompressor because 0 is
-            # the default value that will make zlib decompress without a
-            # length limit.
-            # Data should be stored for subsequent calls.
-            self._unfed_data = data
-            return b""
-
-        # Subsequent calls always reuse `self._obj`. zlib requires
-        # passing the unconsumed tail if decompression is to continue.
-        if not self._first_try:
-            return self._obj.decompress(
-                self._obj.unconsumed_tail + data, max_length=max_length
-            )
-
-        # First call tries with RFC 1950 ZLIB format.
-        self._first_try_data += data
-        try:
-            decompressed = self._obj.decompress(data, max_length=max_length)
-            if decompressed:
-                self._first_try = False
-                self._first_try_data = b""
-            return decompressed
-        # On failure, it falls back to RFC 1951 DEFLATE format.
-        except zlib.error:
-            self._first_try = False
-            self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
-            try:
-                return self.decompress(
-                    self._first_try_data, max_length=original_max_length
-                )
-            finally:
-                self._first_try_data = b""
-
-    @property
-    def has_unconsumed_tail(self) -> bool:
-        return bool(self._unfed_data) or (
-            bool(self._obj.unconsumed_tail)
-            and not self._first_try
-            and not self._obj.eof
-        )
-
-    def flush(self) -> bytes:
-        return self._obj.flush()
-
-
-class GzipDecoderState:
-    FIRST_MEMBER = 0
-    OTHER_MEMBERS = 1
-    SWALLOW_DATA = 2
-
-
-class GzipDecoder(ContentDecoder):
-    def __init__(self) -> None:
-        self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
-        self._state = GzipDecoderState.FIRST_MEMBER
-        self._unconsumed_tail = b""
-
-    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
-        ret = bytearray()
-        if self._state == GzipDecoderState.SWALLOW_DATA:
-            return bytes(ret)
-
-        if max_length == 0:
-            # We should not pass 0 to the zlib decompressor because 0 is
-            # the default value that will make zlib decompress without a
-            # length limit.
-            # Data should be stored for subsequent calls.
-            self._unconsumed_tail += data
-            return b""
-
-        # zlib requires passing the unconsumed tail to the subsequent
-        # call if decompression is to continue.
-        data = self._unconsumed_tail + data
-        if not data and self._obj.eof:
-            return bytes(ret)
-
-        while True:
-            try:
-                ret += self._obj.decompress(
-                    data, max_length=max(max_length - len(ret), 0)
-                )
-            except zlib.error:
-                previous_state = self._state
-                # Ignore data after the first error
-                self._state = GzipDecoderState.SWALLOW_DATA
-                self._unconsumed_tail = b""
-                if previous_state == GzipDecoderState.OTHER_MEMBERS:
-                    # Allow trailing garbage acceptable in other gzip clients
-                    return bytes(ret)
-                raise
-
-            self._unconsumed_tail = data = (
-                self._obj.unconsumed_tail or self._obj.unused_data
-            )
-            if max_length > 0 and len(ret) >= max_length:
-                break
-
-            if not data:
-                return bytes(ret)
-            # When the end of a gzip member is reached, a new decompressor
-            # must be created for unused (possibly future) data.
-            if self._obj.eof:
-                self._state = GzipDecoderState.OTHER_MEMBERS
-                self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
-
-        return bytes(ret)
-
-    @property
-    def has_unconsumed_tail(self) -> bool:
-        return bool(self._unconsumed_tail)
-
-    def flush(self) -> bytes:
-        return self._obj.flush()
-
-
-if brotli is not None:
-
-    class BrotliDecoder(ContentDecoder):
-        # Supports both 'brotlipy' and 'Brotli' packages
-        # since they share an import name. The top branches
-        # are for 'brotlipy' and bottom branches for 'Brotli'
-        def __init__(self) -> None:
-            self._obj = brotli.Decompressor()
-            if hasattr(self._obj, "decompress"):
-                setattr(self, "_decompress", self._obj.decompress)
-            else:
-                setattr(self, "_decompress", self._obj.process)
-
-        # Requires Brotli >= 1.2.0 for `output_buffer_limit`.
-        def _decompress(self, data: bytes, output_buffer_limit: int = -1) -> bytes:
-            raise NotImplementedError()
-
-        def decompress(self, data: bytes, max_length: int = -1) -> bytes:
-            try:
-                if max_length > 0:
-                    return self._decompress(data, output_buffer_limit=max_length)
-                else:
-                    return self._decompress(data)
-            except TypeError:
-                # Fallback for Brotli/brotlicffi/brotlipy versions without
-                # the `output_buffer_limit` parameter.
-                warnings.warn(
-                    "Brotli >= 1.2.0 is required to prevent decompression bombs.",
-                    DependencyWarning,
-                )
-                return self._decompress(data)
-
-        @property
-        def has_unconsumed_tail(self) -> bool:
-            try:
-                return not self._obj.can_accept_more_data()
-            except AttributeError:
-                return False
-
-        def flush(self) -> bytes:
-            if hasattr(self._obj, "flush"):
-                return self._obj.flush()  # type: ignore[no-any-return]
-            return b""
-
-
-try:
-    if sys.version_info >= (3, 14):
-        from compression import zstd
-    else:
-        from backports import zstd
-except ImportError:
-    HAS_ZSTD = False
-else:
-    HAS_ZSTD = True
-
-    class ZstdDecoder(ContentDecoder):
-        def __init__(self) -> None:
-            self._obj = zstd.ZstdDecompressor()
-
-        def decompress(self, data: bytes, max_length: int = -1) -> bytes:
-            if not data and not self.has_unconsumed_tail:
-                return b""
-            if self._obj.eof:
-                data = self._obj.unused_data + data
-                self._obj = zstd.ZstdDecompressor()
-            part = self._obj.decompress(data, max_length=max_length)
-            length = len(part)
-            data_parts = [part]
-            # Every loop iteration is supposed to read data from a separate frame.
-            # The loop breaks when:
-            #   - enough data is read;
-            #   - no more unused data is available;
-            #   - end of the last read frame has not been reached (i.e.,
-            #     more data has to be fed).
-            while (
-                self._obj.eof
-                and self._obj.unused_data
-                and (max_length < 0 or length < max_length)
-            ):
-                unused_data = self._obj.unused_data
-                if not self._obj.needs_input:
-                    self._obj = zstd.ZstdDecompressor()
-                part = self._obj.decompress(
-                    unused_data,
-                    max_length=(max_length - length) if max_length > 0 else -1,
-                )
-                if part_length := len(part):
-                    data_parts.append(part)
-                    length += part_length
-                elif self._obj.needs_input:
-                    break
-            return b"".join(data_parts)
-
-        @property
-        def has_unconsumed_tail(self) -> bool:
-            return not (self._obj.needs_input or self._obj.eof) or bool(
-                self._obj.unused_data
-            )
-
-        def flush(self) -> bytes:
-            if not self._obj.eof:
-                raise DecodeError("Zstandard data is incomplete")
-            return b""
-
-
-class MultiDecoder(ContentDecoder):
-    """
-    From RFC7231:
-        If one or more encodings have been applied to a representation, the
-        sender that applied the encodings MUST generate a Content-Encoding
-        header field that lists the content codings in the order in which
-        they were applied.
-    """
-
-    # Maximum allowed number of chained HTTP encodings in the
-    # Content-Encoding header.
-    max_decode_links = 5
-
-    def __init__(self, modes: str) -> None:
-        encodings = [m.strip() for m in modes.split(",")]
-        if len(encodings) > self.max_decode_links:
-            raise DecodeError(
-                "Too many content encodings in the chain: "
-                f"{len(encodings)} > {self.max_decode_links}"
-            )
-        self._decoders = [_get_decoder(e) for e in encodings]
-
-    def flush(self) -> bytes:
-        return self._decoders[0].flush()
-
-    def decompress(self, data: bytes, max_length: int = -1) -> bytes:
-        if max_length <= 0:
-            for d in reversed(self._decoders):
-                data = d.decompress(data)
-            return data
-
-        ret = bytearray()
-        # Every while loop iteration goes through all decoders once.
-        # It exits when enough data is read or no more data can be read.
-        # It is possible that the while loop iteration does not produce
-        # any data because we retrieve up to `max_length` from every
-        # decoder, and the amount of bytes may be insufficient for the
-        # next decoder to produce enough/any output.
-        while True:
-            any_data = False
-            for d in reversed(self._decoders):
-                data = d.decompress(data, max_length=max_length - len(ret))
-                if data:
-                    any_data = True
-                # We should not break when no data is returned because
-                # next decoders may produce data even with empty input.
-            ret += data
-            if not any_data or len(ret) >= max_length:
-                return bytes(ret)
-            data = b""
-
-    @property
-    def has_unconsumed_tail(self) -> bool:
-        return any(d.has_unconsumed_tail for d in self._decoders)
-
-
-def _get_decoder(mode: str) -> ContentDecoder:
-    if "," in mode:
-        return MultiDecoder(mode)
-
-    # According to RFC 9110 section 8.4.1.3, recipients should
-    # consider x-gzip equivalent to gzip
-    if mode in ("gzip", "x-gzip"):
-        return GzipDecoder()
-
-    if brotli is not None and mode == "br":
-        return BrotliDecoder()
-
-    if HAS_ZSTD and mode == "zstd":
-        return ZstdDecoder()
-
-    return DeflateDecoder()
-
-
-class BytesQueueBuffer:
-    """Memory-efficient bytes buffer
-
-    To return decoded data in read() and still follow the BufferedIOBase API, we need a
-    buffer to always return the correct amount of bytes.
-
-    This buffer should be filled using calls to put()
-
-    Our maximum memory usage is determined by the sum of the size of:
-
-     * self.buffer, which contains the full data
-     * the largest chunk that we will copy in get()
-    """
-
-    def __init__(self) -> None:
-        self.buffer: typing.Deque[bytes | memoryview[bytes]] = collections.deque()
-        self._size: int = 0
-
-    def __len__(self) -> int:
-        return self._size
-
-    def put(self, data: bytes) -> None:
-        self.buffer.append(data)
-        self._size += len(data)
-
-    def get(self, n: int) -> bytes:
-        if n == 0:
-            return b""
-        elif not self.buffer:
-            raise RuntimeError("buffer is empty")
-        elif n < 0:
-            raise ValueError("n should be > 0")
-
-        if len(self.buffer[0]) == n and isinstance(self.buffer[0], bytes):
-            self._size -= n
-            return self.buffer.popleft()
-
-        fetched = 0
-        ret = io.BytesIO()
-        while fetched < n:
-            remaining = n - fetched
-            chunk = self.buffer.popleft()
-            chunk_length = len(chunk)
-            if remaining < chunk_length:
-                chunk = memoryview(chunk)
-                left_chunk, right_chunk = chunk[:remaining], chunk[remaining:]
-                ret.write(left_chunk)
-                self.buffer.appendleft(right_chunk)
-                self._size -= remaining
-                break
-            else:
-                ret.write(chunk)
-                self._size -= chunk_length
-            fetched += chunk_length
-
-            if not self.buffer:
-                break
-
-        return ret.getvalue()
-
-    def get_all(self) -> bytes:
-        buffer = self.buffer
-        if not buffer:
-            assert self._size == 0
-            return b""
-        if len(buffer) == 1:
-            result = buffer.pop()
-            if isinstance(result, memoryview):
-                result = result.tobytes()
-        else:
-            ret = io.BytesIO()
-            ret.writelines(buffer.popleft() for _ in range(len(buffer)))
-            result = ret.getvalue()
-        self._size = 0
-        return result
-
-
-class BaseHTTPResponse(io.IOBase):
-    CONTENT_DECODERS = ["gzip", "x-gzip", "deflate"]
-    if brotli is not None:
-        CONTENT_DECODERS += ["br"]
-    if HAS_ZSTD:
-        CONTENT_DECODERS += ["zstd"]
-    REDIRECT_STATUSES = [301, 302, 303, 307, 308]
-
-    DECODER_ERROR_CLASSES: tuple[type[Exception], ...] = (IOError, zlib.error)
-    if brotli is not None:
-        DECODER_ERROR_CLASSES += (brotli.error,)
-
-    if HAS_ZSTD:
-        DECODER_ERROR_CLASSES += (zstd.ZstdError,)
-
-    def __init__(
-        self,
-        *,
-        headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None,
-        status: int,
-        version: int,
-        version_string: str,
-        reason: str | None,
-        decode_content: bool,
-        request_url: str | None,
-        retries: Retry | None = None,
-    ) -> None:
-        if isinstance(headers, HTTPHeaderDict):
-            self.headers = headers
-        else:
-            self.headers = HTTPHeaderDict(headers)  # type: ignore[arg-type]
-        self.status = status
-        self.version = version
-        self.version_string = version_string
-        self.reason = reason
-        self.decode_content = decode_content
-        self._has_decoded_content = False
-        self._request_url: str | None = request_url
-        self.retries = retries
-
-        self.chunked = False
-        tr_enc = self.headers.get("transfer-encoding", "").lower()
-        # Don't incur the penalty of creating a list and then discarding it
-        encodings = (enc.strip() for enc in tr_enc.split(","))
-        if "chunked" in encodings:
-            self.chunked = True
-
-        self._decoder: ContentDecoder | None = None
-        # Distinguish an uninitialized decoder from a response needing no decoder.
-        self._decoder_initialized = False
-        self.length_remaining: int | None
-
-    def get_redirect_location(self) -> str | None | typing.Literal[False]:
-        """
-        Should we redirect and where to?
-
-        :returns: Truthy redirect location string if we got a redirect status
-            code and valid location. ``None`` if redirect status and no
-            location. ``False`` if not a redirect status code.
-        """
-        if self.status in self.REDIRECT_STATUSES:
-            return self.headers.get("location")
-        return False
-
-    @property
-    def data(self) -> bytes:
-        raise NotImplementedError()
-
-    def json(self) -> typing.Any:
-        """
-        Deserializes the body of the HTTP response as a Python object.
-
-        The body of the HTTP response must be encoded using UTF-8, as per
-        `RFC 8529 Section 8.1 `_.
-
-        To use a custom JSON decoder pass the result of :attr:`HTTPResponse.data` to
-        your custom decoder instead.
-
-        If the body of the HTTP response is not decodable to UTF-8, a
-        `UnicodeDecodeError` will be raised. If the body of the HTTP response is not a
-        valid JSON document, a `json.JSONDecodeError` will be raised.
-
-        Read more :ref:`here `.
-
-        :returns: The body of the HTTP response as a Python object.
-        """
-        data = self.data.decode("utf-8")
-        return _json.loads(data)
-
-    @property
-    def url(self) -> str | None:
-        raise NotImplementedError()
-
-    @url.setter
-    def url(self, url: str | None) -> None:
-        raise NotImplementedError()
-
-    @property
-    def connection(self) -> BaseHTTPConnection | None:
-        raise NotImplementedError()
-
-    @property
-    def retries(self) -> Retry | None:
-        return self._retries
-
-    @retries.setter
-    def retries(self, retries: Retry | None) -> None:
-        # Override the request_url if retries has a redirect location.
-        if retries is not None and retries.history:
-            self.url = retries.history[-1].redirect_location
-        self._retries = retries
-
-    def stream(
-        self, amt: int | None = _READ_CHUNK_SIZE, decode_content: bool | None = None
-    ) -> typing.Iterator[bytes]:
-        raise NotImplementedError()
-
-    def read(
-        self,
-        amt: int | None = None,
-        decode_content: bool | None = None,
-        cache_content: bool = False,
-    ) -> bytes:
-        raise NotImplementedError()
-
-    def read1(
-        self,
-        amt: int | None = None,
-        decode_content: bool | None = None,
-    ) -> bytes:
-        raise NotImplementedError()
-
-    def read_chunked(
-        self,
-        amt: int | None = None,
-        decode_content: bool | None = None,
-    ) -> typing.Iterator[bytes]:
-        raise NotImplementedError()
-
-    def release_conn(self) -> None:
-        raise NotImplementedError()
-
-    def drain_conn(self) -> None:
-        raise NotImplementedError()
-
-    def shutdown(self) -> None:
-        raise NotImplementedError()
-
-    def close(self) -> None:
-        raise NotImplementedError()
-
-    def _init_decoder(self) -> None:
-        """
-        Set-up the _decoder attribute if necessary.
-        """
-        if self._decoder_initialized:
-            return
-
-        if self._decoder is None:
-            # Note: content-encoding value should be case-insensitive, per RFC 7230
-            # Section 3.2
-            content_encoding = self.headers.get("content-encoding", "").lower()
-            if content_encoding in self.CONTENT_DECODERS:
-                self._decoder = _get_decoder(content_encoding)
-            elif "," in content_encoding:
-                encodings = [
-                    e.strip()
-                    for e in content_encoding.split(",")
-                    if e.strip() in self.CONTENT_DECODERS
-                ]
-                if encodings:
-                    self._decoder = _get_decoder(content_encoding)
-
-        self._decoder_initialized = True
-
-    def _decode(
-        self,
-        data: bytes,
-        decode_content: bool | None,
-        flush_decoder: bool,
-        max_length: int | None = None,
-    ) -> bytes:
-        """
-        Decode the data passed in and potentially flush the decoder.
-        """
-        if not decode_content:
-            if self._has_decoded_content:
-                raise RuntimeError(
-                    "Calling read(decode_content=False) is not supported after "
-                    "read(decode_content=True) was called."
-                )
-            return data
-
-        if max_length is None or flush_decoder:
-            max_length = -1
-
-        try:
-            if self._decoder:
-                data = self._decoder.decompress(data, max_length=max_length)
-                self._has_decoded_content = True
-        except self.DECODER_ERROR_CLASSES as e:
-            content_encoding = self.headers.get("content-encoding", "").lower()
-            raise DecodeError(
-                "Received response with content-encoding: %s, but "
-                "failed to decode it." % content_encoding,
-                e,
-            ) from e
-        if flush_decoder:
-            data += self._flush_decoder()
-
-        return data
-
-    def _flush_decoder(self) -> bytes:
-        """
-        Flushes the decoder. Should only be called if the decoder is actually
-        being used.
-        """
-        if self._decoder:
-            return self._decoder.decompress(b"") + self._decoder.flush()
-        return b""
-
-    # Compatibility methods for `io` module
-    def readinto(self, b: bytearray | memoryview[int]) -> int:
-        temp = self.read(len(b))
-        if len(temp) == 0:
-            return 0
-        else:
-            b[: len(temp)] = temp
-            return len(temp)
-
-    # Methods used by dependent libraries
-    def getheaders(self) -> HTTPHeaderDict:
-        return self.headers
-
-    def getheader(self, name: str, default: str | None = None) -> str | None:
-        return self.headers.get(name, default)
-
-    # Compatibility method for http.cookiejar
-    def info(self) -> HTTPHeaderDict:
-        return self.headers
-
-    def geturl(self) -> str | None:
-        return self.url
-
-
-class HTTPResponse(BaseHTTPResponse):
-    """
-    HTTP Response container.
-
-    Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is
-    loaded and decoded on-demand when the ``data`` property is accessed.  This
-    class is also compatible with the Python standard library's :mod:`io`
-    module, and can hence be treated as a readable object in the context of that
-    framework.
-
-    Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`:
-
-    :param preload_content:
-        If True, the response's body will be preloaded during construction.
-
-    :param decode_content:
-        If True, will attempt to decode the body based on the
-        'content-encoding' header.
-
-    :param original_response:
-        When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse`
-        object, it's convenient to include the original for debug purposes. It's
-        otherwise unused.
-
-    :param retries:
-        The retries contains the last :class:`~urllib3.util.retry.Retry` that
-        was used during the request.
-
-    :param enforce_content_length:
-        Enforce content length checking. Body returned by server must match
-        value of Content-Length header, if present. Otherwise, raise error.
-    """
-
-    def __init__(
-        self,
-        body: _TYPE_BODY = "",
-        headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None,
-        status: int = 0,
-        version: int = 0,
-        version_string: str = "HTTP/?",
-        reason: str | None = None,
-        preload_content: bool = True,
-        decode_content: bool = True,
-        original_response: _HttplibHTTPResponse | None = None,
-        pool: HTTPConnectionPool | None = None,
-        connection: HTTPConnection | None = None,
-        msg: _HttplibHTTPMessage | None = None,
-        retries: Retry | None = None,
-        enforce_content_length: bool = True,
-        request_method: str | None = None,
-        request_url: str | None = None,
-        auto_close: bool = True,
-        sock_shutdown: typing.Callable[[int], None] | None = None,
-    ) -> None:
-        super().__init__(
-            headers=headers,
-            status=status,
-            version=version,
-            version_string=version_string,
-            reason=reason,
-            decode_content=decode_content,
-            request_url=request_url,
-            retries=retries,
-        )
-
-        self.enforce_content_length = enforce_content_length
-        self.auto_close = auto_close
-
-        self._body = None
-        self._uncached_read_occurred = False
-        self._fp: _HttplibHTTPResponse | None = None
-        self._original_response = original_response
-        self._fp_bytes_read = 0
-        self.msg = msg
-
-        if body and isinstance(body, (str, bytes)):
-            self._body = body
-
-        self._pool = pool
-        self._connection = connection
-
-        if hasattr(body, "read"):
-            self._fp = body  # type: ignore[assignment]
-        self._sock_shutdown = sock_shutdown
-
-        # Are we using the chunked-style of transfer encoding?
-        self.chunk_left: int | None = None
-
-        # Determine length of response
-        self.length_remaining = self._init_length(request_method)
-
-        # Used to return the correct amount of bytes for partial read()s
-        self._decoded_buffer = BytesQueueBuffer()
-
-        # If requested, preload the body.
-        if preload_content and not self._body:
-            self._body = self.read(decode_content=decode_content)
-
-    def release_conn(self) -> None:
-        if not self._pool or not self._connection:
-            return None
-
-        self._pool._put_conn(self._connection)
-        self._connection = None
-
-    def drain_conn(self) -> None:
-        """
-        Read and discard any remaining HTTP response data in the response connection.
-
-        Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
-        """
-        try:
-            while self._raw_read(_READ_CHUNK_SIZE):
-                pass
-        except (HTTPError, OSError, BaseSSLError, HTTPException):
-            pass
-        if self._has_decoded_content:
-            # `_raw_read` skips decompression, so we should clean up the
-            # decoder to avoid keeping unnecessary data in memory.
-            self._decoded_buffer = BytesQueueBuffer()
-            self._decoder = None
-
-    @property
-    def data(self) -> bytes:
-        # For backwards-compat with earlier urllib3 0.4 and earlier.
-        if self._body:
-            return self._body  # type: ignore[return-value]
-
-        if self._fp:
-            return self.read(cache_content=True)
-
-        return None  # type: ignore[return-value]
-
-    @property
-    def connection(self) -> HTTPConnection | None:
-        return self._connection
-
-    def isclosed(self) -> bool:
-        return is_fp_closed(self._fp)
-
-    def tell(self) -> int:
-        """
-        Obtain the number of bytes pulled over the wire so far. May differ from
-        the amount of content returned by :meth:`HTTPResponse.read`
-        if bytes are encoded on the wire (e.g, compressed).
-        """
-        return self._fp_bytes_read
-
-    def _init_length(self, request_method: str | None) -> int | None:
-        """
-        Set initial length value for Response content if available.
-        """
-        length: int | None
-        content_length: str | None = self.headers.get("content-length")
-
-        if content_length is not None:
-            if self.chunked:
-                # This Response will fail with an IncompleteRead if it can't be
-                # received as chunked. This method falls back to attempt reading
-                # the response before raising an exception.
-                log.warning(
-                    "Received response with both Content-Length and "
-                    "Transfer-Encoding set. This is expressly forbidden "
-                    "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
-                    "attempting to process response as Transfer-Encoding: "
-                    "chunked."
-                )
-                return None
-
-            try:
-                # RFC 7230 section 3.3.2 specifies multiple content lengths can
-                # be sent in a single Content-Length header
-                # (e.g. Content-Length: 42, 42). This line ensures the values
-                # are all valid ints and that as long as the `set` length is 1,
-                # all values are the same. Otherwise, the header is invalid.
-                lengths = {int(val) for val in content_length.split(",")}
-                if len(lengths) > 1:
-                    raise InvalidHeader(
-                        "Content-Length contained multiple "
-                        "unmatching values (%s)" % content_length
-                    )
-                length = lengths.pop()
-            except ValueError:
-                length = None
-            else:
-                if length < 0:
-                    length = None
-
-        else:  # if content_length is None
-            length = None
-
-        # Convert status to int for comparison
-        # In some cases, httplib returns a status of "_UNKNOWN"
-        try:
-            status = int(self.status)
-        except ValueError:
-            status = 0
-
-        # Check for responses that shouldn't include a body
-        if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD":
-            length = 0
-
-        return length
-
-    @contextmanager
-    def _error_catcher(self) -> typing.Generator[None]:
-        """
-        Catch low-level python exceptions, instead re-raising urllib3
-        variants, so that low-level exceptions are not leaked in the
-        high-level api.
-
-        On exit, release the connection back to the pool.
-        """
-        clean_exit = False
-
-        try:
-            try:
-                yield
-
-            except SocketTimeout as e:
-                # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
-                # there is yet no clean way to get at it from this context.
-                raise ReadTimeoutError(self._pool, None, "Read timed out.") from e  # type: ignore[arg-type]
-
-            except BaseSSLError as e:
-                # SSL errors related to framing/MAC get wrapped and reraised here
-                raise SSLError(e) from e
-
-            except IncompleteRead as e:
-                if (
-                    e.expected is not None
-                    and e.partial is not None
-                    and e.expected == -e.partial
-                ):
-                    arg = "Response may not contain content."
-                else:
-                    arg = f"Connection broken: {e!r}"
-                raise ProtocolError(arg, e) from e
-
-            except (HTTPException, OSError) as e:
-                raise ProtocolError(f"Connection broken: {e!r}", e) from e
-
-            # If no exception is thrown, we should avoid cleaning up
-            # unnecessarily.
-            clean_exit = True
-        finally:
-            # If we didn't terminate cleanly, we need to throw away our
-            # connection.
-            if not clean_exit:
-                # The response may not be closed but we're not going to use it
-                # anymore so close it now to ensure that the connection is
-                # released back to the pool.
-                if self._original_response:
-                    self._original_response.close()
-
-                # Closing the response may not actually be sufficient to close
-                # everything, so if we have a hold of the connection close that
-                # too.
-                if self._connection:
-                    self._connection.close()
-
-            # If we hold the original response but it's closed now, we should
-            # return the connection back to the pool.
-            if self._original_response and self._original_response.isclosed():
-                self.release_conn()
-
-    def _fp_read(
-        self,
-        amt: int | None = None,
-        *,
-        read1: bool = False,
-    ) -> bytes:
-        """
-        Read a response with the thought that reading the number of bytes
-        larger than can fit in a 32-bit int at a time via SSL in some
-        known cases leads to an overflow error that has to be prevented
-        if `amt` or `self.length_remaining` indicate that a problem may
-        happen.
-
-        This happens to urllib3 injected with pyOpenSSL-backed SSL-support.
-        """
-        assert self._fp
-        c_int_max = 2**31 - 1
-        if (
-            (amt and amt > c_int_max)
-            or (
-                amt is None
-                and self.length_remaining
-                and self.length_remaining > c_int_max
-            )
-        ) and util.IS_PYOPENSSL:
-            if read1:
-                return self._fp.read1(c_int_max)
-            buffer = io.BytesIO()
-            # Besides `max_chunk_amt` being a maximum chunk size, it
-            # affects memory overhead of reading a response by this
-            # method in CPython.
-            # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum
-            # chunk size that does not lead to an overflow error, but
-            # 256 MiB is a compromise.
-            max_chunk_amt = 2**28
-            while amt is None or amt != 0:
-                if amt is not None:
-                    chunk_amt = min(amt, max_chunk_amt)
-                    amt -= chunk_amt
-                else:
-                    chunk_amt = max_chunk_amt
-                data = self._fp.read(chunk_amt)
-                if not data:
-                    break
-                buffer.write(data)
-                del data  # to reduce peak memory usage by `max_chunk_amt`.
-            return buffer.getvalue()
-        elif read1:
-            return self._fp.read1(amt) if amt is not None else self._fp.read1()
-        else:
-            # StringIO doesn't like amt=None
-            return self._fp.read(amt) if amt is not None else self._fp.read()
-
-    def _raw_read(
-        self,
-        amt: int | None = None,
-        *,
-        read1: bool = False,
-    ) -> bytes:
-        """
-        Reads `amt` of bytes from the socket.
-        """
-        if self._fp is None:
-            return None  # type: ignore[return-value]
-
-        fp_closed = getattr(self._fp, "closed", False)
-
-        with self._error_catcher():
-            data = self._fp_read(amt, read1=read1) if not fp_closed else b""
-            if amt is not None and amt != 0 and not data:
-                # Platform-specific: Buggy versions of Python.
-                # Close the connection when no data is returned
-                #
-                # This is redundant to what httplib/http.client _should_
-                # already do.  However, versions of python released before
-                # December 15, 2012 (http://bugs.python.org/issue16298) do
-                # not properly close the connection in all cases. There is
-                # no harm in redundantly calling close.
-                self._fp.close()
-                if (
-                    self.enforce_content_length
-                    and self.length_remaining is not None
-                    and self.length_remaining != 0
-                ):
-                    # This is an edge case that httplib failed to cover due
-                    # to concerns of backward compatibility. We're
-                    # addressing it here to make sure IncompleteRead is
-                    # raised during streaming, so all calls with incorrect
-                    # Content-Length are caught.
-                    raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
-            elif read1 and (
-                (amt != 0 and not data) or self.length_remaining == len(data)
-            ):
-                # All data has been read, but `self._fp.read1` in
-                # CPython 3.12 and older doesn't always close
-                # `http.client.HTTPResponse`, so we close it here.
-                # See https://github.com/python/cpython/issues/113199
-                self._fp.close()
-
-        if data:
-            self._fp_bytes_read += len(data)
-            if self.length_remaining is not None:
-                self.length_remaining -= len(data)
-        return data
-
-    def read(
-        self,
-        amt: int | None = None,
-        decode_content: bool | None = None,
-        cache_content: bool = False,
-    ) -> bytes:
-        """
-        Similar to :meth:`http.client.HTTPResponse.read`, but with two additional
-        parameters: ``decode_content`` and ``cache_content``.
-
-        :param amt:
-            How much of the content to read. If specified, caching is skipped
-            because it doesn't make sense to cache partial content as the full
-            response.
-
-        :param decode_content:
-            If True, will attempt to decode the body based on the
-            'content-encoding' header.
-
-        :param cache_content:
-            If True, will save the returned data such that the same result is
-            returned despite of the state of the underlying file object. This
-            is useful if you want the ``.data`` property to continue working
-            after having ``.read()`` the file object. (Overridden if ``amt`` is
-            set.)
-        """
-        self._init_decoder()
-        if decode_content is None:
-            decode_content = self.decode_content
-
-        if amt and amt < 0:
-            # Negative numbers and `None` should be treated the same.
-            amt = None
-        elif amt is not None:
-            cache_content = False
-
-            if (
-                self._decoder
-                and self._decoder.has_unconsumed_tail
-                and len(self._decoded_buffer) < amt
-            ):
-                decoded_data = self._decode(
-                    b"",
-                    decode_content,
-                    flush_decoder=False,
-                    max_length=amt - len(self._decoded_buffer),
-                )
-                self._decoded_buffer.put(decoded_data)
-            if len(self._decoded_buffer) >= amt:
-                return self._decoded_buffer.get(amt)
-
-        data = self._raw_read(amt)
-        if not cache_content:
-            self._uncached_read_occurred = True
-
-        flush_decoder = amt is None or (amt != 0 and not data)
-
-        if (
-            not data
-            and len(self._decoded_buffer) == 0
-            and not (self._decoder and self._decoder.has_unconsumed_tail)
-        ):
-            return data
-
-        if amt is None:
-            data = self._decode(data, decode_content, flush_decoder)
-            # It's possible that there is buffered decoded data after a
-            # partial read.
-            if decode_content and len(self._decoded_buffer) > 0:
-                self._decoded_buffer.put(data)
-                data = self._decoded_buffer.get_all()
-
-            if cache_content and not self._uncached_read_occurred:
-                self._body = data
-        else:
-            # do not waste memory on buffer when not decoding
-            if not decode_content:
-                if self._has_decoded_content:
-                    raise RuntimeError(
-                        "Calling read(decode_content=False) is not supported after "
-                        "read(decode_content=True) was called."
-                    )
-                return data
-
-            decoded_data = self._decode(
-                data,
-                decode_content,
-                flush_decoder,
-                max_length=amt - len(self._decoded_buffer),
-            )
-            self._decoded_buffer.put(decoded_data)
-
-            while len(self._decoded_buffer) < amt and data:
-                # TODO make sure to initially read enough data to get past the headers
-                # For example, the GZ file header takes 10 bytes, we don't want to read
-                # it one byte at a time
-                data = self._raw_read(amt)
-                decoded_data = self._decode(
-                    data,
-                    decode_content,
-                    flush_decoder,
-                    max_length=amt - len(self._decoded_buffer),
-                )
-                self._decoded_buffer.put(decoded_data)
-            data = self._decoded_buffer.get(amt)
-
-        return data
-
-    def read1(
-        self,
-        amt: int | None = None,
-        decode_content: bool | None = None,
-    ) -> bytes:
-        """
-        Similar to ``http.client.HTTPResponse.read1`` and documented
-        in :meth:`io.BufferedReader.read1`, but with an additional parameter:
-        ``decode_content``.
-
-        :param amt:
-            How much of the content to read.
-
-        :param decode_content:
-            If True, will attempt to decode the body based on the
-            'content-encoding' header.
-        """
-        if decode_content is None:
-            decode_content = self.decode_content
-        if amt and amt < 0:
-            # Negative numbers and `None` should be treated the same.
-            amt = None
-        # try and respond without going to the network
-        if self._has_decoded_content:
-            if not decode_content:
-                raise RuntimeError(
-                    "Calling read1(decode_content=False) is not supported after "
-                    "read1(decode_content=True) was called."
-                )
-            if (
-                self._decoder
-                and self._decoder.has_unconsumed_tail
-                and (amt is None or len(self._decoded_buffer) < amt)
-            ):
-                decoded_data = self._decode(
-                    b"",
-                    decode_content,
-                    flush_decoder=False,
-                    max_length=(
-                        amt - len(self._decoded_buffer) if amt is not None else None
-                    ),
-                )
-                self._decoded_buffer.put(decoded_data)
-            if len(self._decoded_buffer) > 0:
-                if amt is None:
-                    return self._decoded_buffer.get_all()
-                return self._decoded_buffer.get(amt)
-        if amt == 0:
-            return b""
-
-        # FIXME, this method's type doesn't say returning None is possible
-        data = self._raw_read(amt, read1=True)
-        self._uncached_read_occurred = True
-        if not decode_content or data is None:
-            return data
-
-        self._init_decoder()
-        while True:
-            flush_decoder = not data
-            decoded_data = self._decode(
-                data, decode_content, flush_decoder, max_length=amt
-            )
-            self._decoded_buffer.put(decoded_data)
-            if decoded_data or flush_decoder:
-                break
-            data = self._raw_read(8192, read1=True)
-
-        if amt is None:
-            return self._decoded_buffer.get_all()
-        return self._decoded_buffer.get(amt)
-
-    def stream(
-        self, amt: int | None = _READ_CHUNK_SIZE, decode_content: bool | None = None
-    ) -> typing.Generator[bytes]:
-        """
-        A generator wrapper for the read() method. A call will block until
-        ``amt`` bytes have been read from the connection or until the
-        connection is closed.
-
-        :param amt:
-            How much of the content to read. The generator will return up to
-            much data per iteration, but may return less. This is particularly
-            likely when using compressed data. However, the empty string will
-            never be returned.
-
-        :param decode_content:
-            If True, will attempt to decode the body based on the
-            'content-encoding' header.
-        """
-        if amt == 0:
-            return
-
-        if self.chunked and self.supports_chunked_reads():
-            yield from self.read_chunked(amt, decode_content=decode_content)
-        else:
-            while (
-                not is_fp_closed(self._fp)
-                or len(self._decoded_buffer) > 0
-                or (self._decoder and self._decoder.has_unconsumed_tail)
-            ):
-                data = self.read(amt=amt, decode_content=decode_content)
-
-                if data:
-                    yield data
-
-    # Overrides from io.IOBase
-    def readable(self) -> bool:
-        return True
-
-    def shutdown(self) -> None:
-        if not self._sock_shutdown:
-            raise ValueError("Cannot shutdown socket as self._sock_shutdown is not set")
-        if self._connection is None:
-            raise RuntimeError(
-                "Cannot shutdown as connection has already been released to the pool"
-            )
-        self._sock_shutdown(socket.SHUT_RD)
-
-    def close(self) -> None:
-        self._sock_shutdown = None
-
-        if not self.closed and self._fp:
-            self._fp.close()
-
-        if self._connection:
-            self._connection.close()
-
-        if not self.auto_close:
-            io.IOBase.close(self)
-
-    @property
-    def closed(self) -> bool:
-        if not self.auto_close:
-            return io.IOBase.closed.__get__(self)  # type: ignore[no-any-return]
-        elif self._fp is None:
-            return True
-        elif hasattr(self._fp, "isclosed"):
-            return self._fp.isclosed()
-        elif hasattr(self._fp, "closed"):
-            return self._fp.closed
-        else:
-            return True
-
-    def fileno(self) -> int:
-        if self._fp is None:
-            raise OSError("HTTPResponse has no file to get a fileno from")
-        elif hasattr(self._fp, "fileno"):
-            return self._fp.fileno()
-        else:
-            raise OSError(
-                "The file-like object this HTTPResponse is wrapped "
-                "around has no file descriptor"
-            )
-
-    def flush(self) -> None:
-        if (
-            self._fp is not None
-            and hasattr(self._fp, "flush")
-            and not getattr(self._fp, "closed", False)
-        ):
-            return self._fp.flush()
-
-    def supports_chunked_reads(self) -> bool:
-        """
-        Checks if the underlying file-like object looks like a
-        :class:`http.client.HTTPResponse` object. We do this by testing for
-        the fp attribute. If it is present we assume it returns raw chunks as
-        processed by read_chunked().
-        """
-        return hasattr(self._fp, "fp")
-
-    def _update_chunk_length(self) -> None:
-        # First, we'll figure out length of a chunk and then
-        # we'll try to read it from socket.
-        if self.chunk_left is not None:
-            return None
-        line = self._fp.fp.readline(_MAX_CHUNK_LINE_LENGTH + 1)  # type: ignore[union-attr]
-        if len(line) > _MAX_CHUNK_LINE_LENGTH:
-            self.close()
-            raise ProtocolError(
-                "Response chunk size line exceeded maximum allowed length"
-            ) from None
-        line = line.split(b";", 1)[0]
-        try:
-            self.chunk_left = int(line, 16)
-        except ValueError:
-            self.close()
-            if line:
-                # Invalid chunked protocol response, abort.
-                raise InvalidChunkLength(self, line) from None
-            else:
-                # Truncated at start of next chunk
-                raise ProtocolError("Response ended prematurely") from None
-
-    def _handle_chunk(self, amt: int | None) -> bytes:
-        returned_chunk = None
-        if amt is None:
-            chunk = self._fp._safe_read(self.chunk_left)  # type: ignore[union-attr]
-            returned_chunk = chunk
-            self._fp._safe_read(2)  # type: ignore[union-attr] # Toss the CRLF at the end of the chunk.
-            self.chunk_left = None
-        elif self.chunk_left is not None and amt < self.chunk_left:
-            value = self._fp._safe_read(amt)  # type: ignore[union-attr]
-            self.chunk_left = self.chunk_left - amt
-            returned_chunk = value
-        elif amt == self.chunk_left:
-            value = self._fp._safe_read(amt)  # type: ignore[union-attr]
-            self._fp._safe_read(2)  # type: ignore[union-attr] # Toss the CRLF at the end of the chunk.
-            self.chunk_left = None
-            returned_chunk = value
-        else:  # amt > self.chunk_left
-            returned_chunk = self._fp._safe_read(self.chunk_left)  # type: ignore[union-attr]
-            self._fp._safe_read(2)  # type: ignore[union-attr] # Toss the CRLF at the end of the chunk.
-            self.chunk_left = None
-        return returned_chunk  # type: ignore[no-any-return]
-
-    def read_chunked(
-        self, amt: int | None = None, decode_content: bool | None = None
-    ) -> typing.Generator[bytes]:
-        """
-        Similar to :meth:`HTTPResponse.read`, but with an additional
-        parameter: ``decode_content``.
-
-        :param amt:
-            How much of the content to read. If specified, caching is skipped
-            because it doesn't make sense to cache partial content as the full
-            response.
-
-        :param decode_content:
-            If True, will attempt to decode the body based on the
-            'content-encoding' header.
-        """
-        self._init_decoder()
-        # FIXME: Rewrite this method and make it a class with a better structured logic.
-        if not self.chunked:
-            raise ResponseNotChunked(
-                "Response is not chunked. "
-                "Header 'transfer-encoding: chunked' is missing."
-            )
-        if not self.supports_chunked_reads():
-            raise BodyNotHttplibCompatible(
-                "Body should be http.client.HTTPResponse like. "
-                "It should have have an fp attribute which returns raw chunks."
-            )
-
-        with self._error_catcher():
-            # Don't bother reading the body of a HEAD request.
-            if self._original_response and is_response_to_head(self._original_response):
-                self._original_response.close()
-                return None
-
-            # If a response is already read and closed
-            # then return immediately.
-            if self._fp.fp is None:  # type: ignore[union-attr]
-                return None
-
-            if amt == 0:
-                return
-            elif amt and amt < 0:
-                # Negative numbers and `None` should be treated the same,
-                # but httplib handles only `None` correctly.
-                amt = None
-
-            while True:
-                # First, check if any data is left in the decoder's buffer.
-                if self._decoder and self._decoder.has_unconsumed_tail:
-                    chunk = b""
-                else:
-                    self._update_chunk_length()
-                    self._uncached_read_occurred = True
-                    if self.chunk_left == 0:
-                        break
-                    chunk = self._handle_chunk(amt)
-                decoded = self._decode(
-                    chunk,
-                    decode_content=decode_content,
-                    flush_decoder=False,
-                    max_length=amt,
-                )
-                if decoded:
-                    yield decoded
-
-            if decode_content:
-                # On CPython and PyPy, we should never need to flush the
-                # decoder. However, on Jython we *might* need to, so
-                # lets defensively do it anyway.
-                decoded = self._flush_decoder()
-                if decoded:  # Platform-specific: Jython.
-                    yield decoded
-
-            # Chunk content ends with \r\n: discard it.
-            while self._fp is not None:
-                line = self._fp.fp.readline(_MAX_CHUNK_LINE_LENGTH + 1)
-                if len(line) > _MAX_CHUNK_LINE_LENGTH:
-                    raise ProtocolError(
-                        "Response chunk trailer line exceeded maximum allowed length"
-                    )
-                if not line:
-                    # Some sites may not end with '\r\n'.
-                    break
-                if line == b"\r\n":
-                    break
-
-            # We read everything; close the "file".
-            if self._original_response:
-                self._original_response.close()
-
-    @property
-    def url(self) -> str | None:
-        """
-        Returns the URL that was the source of this response.
-        If the request that generated this response redirected, this method
-        will return the final redirect location.
-        """
-        return self._request_url
-
-    @url.setter
-    def url(self, url: str | None) -> None:
-        self._request_url = url
-
-    def __iter__(self) -> typing.Iterator[bytes]:
-        buffer: list[bytes] = []
-        for chunk in self.stream(decode_content=True):
-            if b"\n" in chunk:
-                chunks = chunk.split(b"\n")
-                yield b"".join(buffer) + chunks[0] + b"\n"
-                for x in chunks[1:-1]:
-                    yield x + b"\n"
-                if chunks[-1]:
-                    buffer = [chunks[-1]]
-                else:
-                    buffer = []
-            else:
-                buffer.append(chunk)
-        if buffer:
-            yield b"".join(buffer)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py
deleted file mode 100644
index 534126033c0..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/__init__.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# For backwards compatibility, provide imports that used to be here.
-from __future__ import annotations
-
-from .connection import is_connection_dropped
-from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers
-from .response import is_fp_closed
-from .retry import Retry
-from .ssl_ import (
-    ALPN_PROTOCOLS,
-    IS_PYOPENSSL,
-    SSLContext,
-    assert_fingerprint,
-    create_urllib3_context,
-    resolve_cert_reqs,
-    resolve_ssl_version,
-    ssl_wrap_socket,
-)
-from .timeout import Timeout
-from .url import Url, parse_url
-from .wait import wait_for_read, wait_for_write
-
-__all__ = (
-    "IS_PYOPENSSL",
-    "SSLContext",
-    "ALPN_PROTOCOLS",
-    "Retry",
-    "Timeout",
-    "Url",
-    "assert_fingerprint",
-    "create_urllib3_context",
-    "is_connection_dropped",
-    "is_fp_closed",
-    "parse_url",
-    "make_headers",
-    "resolve_cert_reqs",
-    "resolve_ssl_version",
-    "ssl_wrap_socket",
-    "wait_for_read",
-    "wait_for_write",
-    "SKIP_HEADER",
-    "SKIPPABLE_HEADERS",
-)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py
deleted file mode 100644
index f92519ee912..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/connection.py
+++ /dev/null
@@ -1,137 +0,0 @@
-from __future__ import annotations
-
-import socket
-import typing
-
-from ..exceptions import LocationParseError
-from .timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT
-
-_TYPE_SOCKET_OPTIONS = list[tuple[int, int, typing.Union[int, bytes]]]
-
-if typing.TYPE_CHECKING:
-    from .._base_connection import BaseHTTPConnection
-
-
-def is_connection_dropped(conn: BaseHTTPConnection) -> bool:  # Platform-specific
-    """
-    Returns True if the connection is dropped and should be closed.
-    :param conn: :class:`urllib3.connection.HTTPConnection` object.
-    """
-    return not conn.is_connected
-
-
-# This function is copied from socket.py in the Python 2.7 standard
-# library test suite. Added to its signature is only `socket_options`.
-# One additional modification is that we avoid binding to IPv6 servers
-# discovered in DNS if the system doesn't have IPv6 functionality.
-def create_connection(
-    address: tuple[str, int],
-    timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-    source_address: tuple[str, int] | None = None,
-    socket_options: _TYPE_SOCKET_OPTIONS | None = None,
-) -> socket.socket:
-    """Connect to *address* and return the socket object.
-
-    Convenience function.  Connect to *address* (a 2-tuple ``(host,
-    port)``) and return the socket object.  Passing the optional
-    *timeout* parameter will set the timeout on the socket instance
-    before attempting to connect.  If no *timeout* is supplied, the
-    global default timeout setting returned by :func:`socket.getdefaulttimeout`
-    is used.  If *source_address* is set it must be a tuple of (host, port)
-    for the socket to bind as a source address before making the connection.
-    An host of '' or port 0 tells the OS to use the default.
-    """
-
-    host, port = address
-    if host.startswith("["):
-        host = host.strip("[]")
-    err = None
-
-    # Using the value from allowed_gai_family() in the context of getaddrinfo lets
-    # us select whether to work with IPv4 DNS records, IPv6 records, or both.
-    # The original create_connection function always returns all records.
-    family = allowed_gai_family()
-
-    try:
-        host.encode("idna")
-    except UnicodeError:
-        raise LocationParseError(f"'{host}', label empty or too long") from None
-
-    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
-        af, socktype, proto, canonname, sa = res
-        sock = None
-        try:
-            sock = socket.socket(af, socktype, proto)
-
-            # If provided, set socket level options before connecting.
-            _set_socket_options(sock, socket_options)
-
-            if timeout is not _DEFAULT_TIMEOUT:
-                sock.settimeout(timeout)
-            if source_address:
-                sock.bind(source_address)
-            sock.connect(sa)
-            # Break explicitly a reference cycle
-            err = None
-            return sock
-
-        except OSError as _:
-            err = _
-            if sock is not None:
-                sock.close()
-
-    if err is not None:
-        try:
-            raise err
-        finally:
-            # Break explicitly a reference cycle
-            err = None
-    else:
-        raise OSError("getaddrinfo returns an empty list")
-
-
-def _set_socket_options(
-    sock: socket.socket, options: _TYPE_SOCKET_OPTIONS | None
-) -> None:
-    if options is None:
-        return
-
-    for opt in options:
-        sock.setsockopt(*opt)
-
-
-def allowed_gai_family() -> socket.AddressFamily:
-    """This function is designed to work in the context of
-    getaddrinfo, where family=socket.AF_UNSPEC is the default and
-    will perform a DNS search for both IPv6 and IPv4 records."""
-
-    family = socket.AF_INET
-    if HAS_IPV6:
-        family = socket.AF_UNSPEC
-    return family
-
-
-def _has_ipv6(host: str) -> bool:
-    """Returns True if the system can bind an IPv6 address."""
-    sock = None
-    has_ipv6 = False
-
-    if socket.has_ipv6:
-        # has_ipv6 returns true if cPython was compiled with IPv6 support.
-        # It does not tell us if the system has IPv6 support enabled. To
-        # determine that we must bind to an IPv6 address.
-        # https://github.com/urllib3/urllib3/pull/611
-        # https://bugs.python.org/issue658327
-        try:
-            sock = socket.socket(socket.AF_INET6)
-            sock.bind((host, 0))
-            has_ipv6 = True
-        except Exception:
-            pass
-
-    if sock:
-        sock.close()
-    return has_ipv6
-
-
-HAS_IPV6 = _has_ipv6("::1")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py
deleted file mode 100644
index 908fc6621d0..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/proxy.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from __future__ import annotations
-
-import typing
-
-from .url import Url
-
-if typing.TYPE_CHECKING:
-    from ..connection import ProxyConfig
-
-
-def connection_requires_http_tunnel(
-    proxy_url: Url | None = None,
-    proxy_config: ProxyConfig | None = None,
-    destination_scheme: str | None = None,
-) -> bool:
-    """
-    Returns True if the connection requires an HTTP CONNECT through the proxy.
-
-    :param URL proxy_url:
-        URL of the proxy.
-    :param ProxyConfig proxy_config:
-        Proxy configuration from poolmanager.py
-    :param str destination_scheme:
-        The scheme of the destination. (i.e https, http, etc)
-    """
-    # If we're not using a proxy, no way to use a tunnel.
-    if proxy_url is None:
-        return False
-
-    # HTTP destinations never require tunneling, we always forward.
-    if destination_scheme == "http":
-        return False
-
-    # Support for forwarding with HTTPS proxies and HTTPS destinations.
-    if (
-        proxy_url.scheme == "https"
-        and proxy_config
-        and proxy_config.use_forwarding_for_https
-    ):
-        return False
-
-    # Otherwise always use a tunnel.
-    return True
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py
deleted file mode 100644
index 8c6c7fbdcfd..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/request.py
+++ /dev/null
@@ -1,299 +0,0 @@
-from __future__ import annotations
-
-import io
-import sys
-import typing
-from base64 import b64encode
-from enum import Enum
-
-from ..exceptions import UnrewindableBodyError
-from .util import to_bytes
-
-if typing.TYPE_CHECKING:
-    from typing import Final
-
-# Pass as a value within ``headers`` to skip
-# emitting some HTTP headers that are added automatically.
-# The only headers that are supported are ``Accept-Encoding``,
-# ``Host``, and ``User-Agent``.
-SKIP_HEADER = "@@@SKIP_HEADER@@@"
-SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"])
-
-ACCEPT_ENCODING = "gzip,deflate"
-try:
-    try:
-        import brotlicffi as _unused_module_brotli  # type: ignore[import-not-found] # noqa: F401
-    except ImportError:
-        import brotli as _unused_module_brotli  # type: ignore[import-not-found] # noqa: F401
-except ImportError:
-    pass
-else:
-    ACCEPT_ENCODING += ",br"
-
-try:
-    if sys.version_info >= (3, 14):
-        from compression import zstd as _unused_module_zstd  # noqa: F401
-    else:
-        from backports import zstd as _unused_module_zstd  # noqa: F401
-except ImportError:
-    pass
-else:
-    ACCEPT_ENCODING += ",zstd"
-
-
-class _TYPE_FAILEDTELL(Enum):
-    token = 0
-
-
-_FAILEDTELL: Final[_TYPE_FAILEDTELL] = _TYPE_FAILEDTELL.token
-
-_TYPE_BODY_POSITION = typing.Union[int, _TYPE_FAILEDTELL]
-
-# When sending a request with these methods we aren't expecting
-# a body so don't need to set an explicit 'Content-Length: 0'
-# The reason we do this in the negative instead of tracking methods
-# which 'should' have a body is because unknown methods should be
-# treated as if they were 'POST' which *does* expect a body.
-_METHODS_NOT_EXPECTING_BODY = {"GET", "HEAD", "DELETE", "TRACE", "OPTIONS", "CONNECT"}
-
-
-def make_headers(
-    keep_alive: bool | None = None,
-    accept_encoding: bool | list[str] | str | None = None,
-    user_agent: str | None = None,
-    basic_auth: str | None = None,
-    proxy_basic_auth: str | None = None,
-    disable_cache: bool | None = None,
-    *,
-    basic_auth_encoding: str = "latin-1",
-    proxy_basic_auth_encoding: str = "latin-1",
-) -> dict[str, str]:
-    """
-    Shortcuts for generating request headers.
-
-    :param keep_alive:
-        If ``True``, adds 'connection: keep-alive' header.
-
-    :param accept_encoding:
-        Can be a boolean, list, or string.
-        ``True`` translates to 'gzip,deflate'.  If the dependencies for
-        Brotli (either the ``brotli`` or ``brotlicffi`` package) and/or
-        Zstandard (the ``backports.zstd`` package for Python before 3.14)
-        algorithms are installed, then their encodings are
-        included in the string ('br' and 'zstd', respectively).
-        List will get joined by comma.
-        String will be used as provided.
-
-    :param user_agent:
-        String representing the user-agent you want, such as
-        "python-urllib3/0.6"
-
-    :param basic_auth:
-        Colon-separated username:password string for 'authorization: basic ...'
-        auth header. Basic authentication transmits Base64-encoded bytes, not
-        Unicode text, so the string is encoded with ``basic_auth_encoding``
-        before Base64 encoding.
-
-        Must contain decoded credentials (not percent-encoded).
-        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
-        to get the properly formatted string.
-
-    :param basic_auth_encoding:
-        Text encoding used to encode ``basic_auth`` before Base64 encoding.
-        Defaults to "latin-1" for backward compatibility. Use "utf-8" only
-        when the peer expects UTF-8 Basic authentication credentials.
-
-        Must contain decoded credentials (not percent-encoded).
-        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
-        to get the properly formatted string.
-
-    :param proxy_basic_auth:
-        Colon-separated username:password string for 'proxy-authorization: basic ...'
-        auth header. Basic authentication transmits Base64-encoded bytes, not
-        Unicode text, so the string is encoded with ``proxy_basic_auth_encoding``
-        before Base64 encoding.
-
-        Must contain decoded credentials (not percent-encoded).
-        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
-        to get the properly formatted string.
-
-    :param proxy_basic_auth_encoding:
-        Text encoding used to encode ``proxy_basic_auth`` before Base64
-        encoding. Defaults to "latin-1" for backward compatibility. Use
-        "utf-8" only when the proxy expects UTF-8 Basic authentication
-        credentials.
-
-        Must contain decoded credentials (not percent-encoded).
-        For URLs parsed with :func:`parse_url`, use :attr:`Url.auth_decoded_joined`
-        to get the properly formatted string.
-
-    :param disable_cache:
-        If ``True``, adds 'cache-control: no-cache' header.
-
-    Example:
-
-    .. code-block:: python
-
-        import urllib3
-
-        print(urllib3.util.make_headers(keep_alive=True, user_agent="Batman/1.0"))
-        # {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'}
-        print(urllib3.util.make_headers(accept_encoding=True))
-        # {'accept-encoding': 'gzip,deflate'}
-    """
-    headers: dict[str, str] = {}
-    if accept_encoding:
-        if isinstance(accept_encoding, str):
-            pass
-        elif isinstance(accept_encoding, list):
-            accept_encoding = ",".join(accept_encoding)
-        else:
-            accept_encoding = ACCEPT_ENCODING
-        headers["accept-encoding"] = accept_encoding
-
-    if user_agent:
-        headers["user-agent"] = user_agent
-
-    if keep_alive:
-        headers["connection"] = "keep-alive"
-
-    if basic_auth:
-        headers["authorization"] = (
-            f"Basic {b64encode(basic_auth.encode(basic_auth_encoding)).decode()}"
-        )
-
-    if proxy_basic_auth:
-        headers["proxy-authorization"] = (
-            f"Basic {b64encode(proxy_basic_auth.encode(proxy_basic_auth_encoding)).decode()}"
-        )
-
-    if disable_cache:
-        headers["cache-control"] = "no-cache"
-
-    return headers
-
-
-def set_file_position(
-    body: typing.Any, pos: _TYPE_BODY_POSITION | None
-) -> _TYPE_BODY_POSITION | None:
-    """
-    If a position is provided, move file to that point.
-    Otherwise, we'll attempt to record a position for future use.
-    """
-    if pos is not None:
-        rewind_body(body, pos)
-    elif getattr(body, "tell", None) is not None:
-        try:
-            pos = body.tell()
-        except OSError:
-            # This differentiates from None, allowing us to catch
-            # a failed `tell()` later when trying to rewind the body.
-            pos = _FAILEDTELL
-
-    return pos
-
-
-def rewind_body(body: typing.IO[typing.AnyStr], body_pos: _TYPE_BODY_POSITION) -> None:
-    """
-    Attempt to rewind body to a certain position.
-    Primarily used for request redirects and retries.
-
-    :param body:
-        File-like object that supports seek.
-
-    :param int pos:
-        Position to seek to in file.
-    """
-    body_seek = getattr(body, "seek", None)
-    if body_seek is not None and isinstance(body_pos, int):
-        try:
-            body_seek(body_pos)
-        except OSError as e:
-            raise UnrewindableBodyError(
-                "An error occurred when rewinding request body for redirect/retry."
-            ) from e
-    elif body_pos is _FAILEDTELL:
-        raise UnrewindableBodyError(
-            "Unable to record file position for rewinding "
-            "request body during a redirect/retry."
-        )
-    elif body_seek is None:
-        raise UnrewindableBodyError("body does not implement seek.")
-    else:
-        raise ValueError(
-            f"body_pos must be of type integer, instead it was {type(body_pos)}."
-        )
-
-
-class ChunksAndContentLength(typing.NamedTuple):
-    chunks: typing.Iterable[bytes] | None
-    content_length: int | None
-
-
-def body_to_chunks(
-    body: typing.Any | None, method: str, blocksize: int
-) -> ChunksAndContentLength:
-    """Takes the HTTP request method, body, and blocksize and
-    transforms them into an iterable of chunks to pass to
-    socket.sendall() and an optional 'Content-Length' header.
-
-    A 'Content-Length' of 'None' indicates the length of the body
-    can't be determined so should use 'Transfer-Encoding: chunked'
-    for framing instead.
-    """
-
-    chunks: typing.Iterable[bytes] | None
-    content_length: int | None
-
-    # No body, we need to make a recommendation on 'Content-Length'
-    # based on whether that request method is expected to have
-    # a body or not.
-    if body is None:
-        chunks = None
-        if method.upper() not in _METHODS_NOT_EXPECTING_BODY:
-            content_length = 0
-        else:
-            content_length = None
-
-    # Bytes or strings become bytes
-    elif isinstance(body, (str, bytes)):
-        chunks = (to_bytes(body),)
-        content_length = len(chunks[0])
-
-    # File-like object, TODO: use seek() and tell() for length?
-    elif hasattr(body, "read"):
-
-        def chunk_readable() -> typing.Iterable[bytes]:
-            encode = isinstance(body, io.TextIOBase)
-            while True:
-                datablock = body.read(blocksize)
-                if not datablock:
-                    break
-                if encode:
-                    datablock = datablock.encode("utf-8")
-                yield datablock
-
-        chunks = chunk_readable()
-        content_length = None
-
-    # Otherwise we need to start checking via duck-typing.
-    else:
-        try:
-            # Check if the body implements the buffer API.
-            mv = memoryview(body)
-        except TypeError:
-            try:
-                # Check if the body is an iterable
-                chunks = iter(body)
-                content_length = None
-            except TypeError:
-                raise TypeError(
-                    f"'body' must be a bytes-like object, file-like "
-                    f"object, or iterable. Instead was {body!r}"
-                ) from None
-        else:
-            # Since it implements the buffer API can be passed directly to socket.sendall()
-            chunks = (body,)
-            content_length = mv.nbytes
-
-    return ChunksAndContentLength(chunks=chunks, content_length=content_length)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py
deleted file mode 100644
index 0f4578696fa..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/response.py
+++ /dev/null
@@ -1,101 +0,0 @@
-from __future__ import annotations
-
-import http.client as httplib
-from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect
-
-from ..exceptions import HeaderParsingError
-
-
-def is_fp_closed(obj: object) -> bool:
-    """
-    Checks whether a given file-like object is closed.
-
-    :param obj:
-        The file-like object to check.
-    """
-
-    try:
-        # Check `isclosed()` first, in case Python3 doesn't set `closed`.
-        # GH Issue #928
-        return obj.isclosed()  # type: ignore[no-any-return, attr-defined]
-    except AttributeError:
-        pass
-
-    try:
-        # Check via the official file-like-object way.
-        return obj.closed  # type: ignore[no-any-return, attr-defined]
-    except AttributeError:
-        pass
-
-    try:
-        # Check if the object is a container for another file-like object that
-        # gets released on exhaustion (e.g. HTTPResponse).
-        return obj.fp is None  # type: ignore[attr-defined]
-    except AttributeError:
-        pass
-
-    raise ValueError("Unable to determine whether fp is closed.")
-
-
-def assert_header_parsing(headers: httplib.HTTPMessage) -> None:
-    """
-    Asserts whether all headers have been successfully parsed.
-    Extracts encountered errors from the result of parsing headers.
-
-    Only works on Python 3.
-
-    :param http.client.HTTPMessage headers: Headers to verify.
-
-    :raises urllib3.exceptions.HeaderParsingError:
-        If parsing errors are found.
-    """
-
-    # This will fail silently if we pass in the wrong kind of parameter.
-    # To make debugging easier add an explicit check.
-    if not isinstance(headers, httplib.HTTPMessage):
-        raise TypeError(f"expected httplib.Message, got {type(headers)}.")
-
-    unparsed_data = None
-
-    # get_payload is actually email.message.Message.get_payload;
-    # we're only interested in the result if it's not a multipart message
-    if not headers.is_multipart():
-        payload = headers.get_payload()
-
-        if isinstance(payload, (bytes, str)):
-            unparsed_data = payload
-
-    # httplib is assuming a response body is available
-    # when parsing headers even when httplib only sends
-    # header data to parse_headers() This results in
-    # defects on multipart responses in particular.
-    # See: https://github.com/urllib3/urllib3/issues/800
-
-    # So we ignore the following defects:
-    # - StartBoundaryNotFoundDefect:
-    #     The claimed start boundary was never found.
-    # - MultipartInvariantViolationDefect:
-    #     A message claimed to be a multipart but no subparts were found.
-    defects = [
-        defect
-        for defect in headers.defects
-        if not isinstance(
-            defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect)
-        )
-    ]
-
-    if defects or unparsed_data:
-        raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
-
-
-def is_response_to_head(response: httplib.HTTPResponse) -> bool:
-    """
-    Checks whether the request of a response has been a HEAD-request.
-
-    :param http.client.HTTPResponse response:
-        Response to check if the originating request
-        used 'HEAD' as a method.
-    """
-    # FIXME: Can we do this somehow without accessing private httplib _method?
-    method_str = response._method  # type: str  # type: ignore[attr-defined]
-    return method_str.upper() == "HEAD"
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py
deleted file mode 100644
index 42fa6fdd9c1..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/retry.py
+++ /dev/null
@@ -1,569 +0,0 @@
-from __future__ import annotations
-
-import email
-import logging
-import random
-import re
-import time
-import typing
-import warnings
-from collections.abc import Collection
-from itertools import takewhile
-from types import TracebackType
-
-from ..exceptions import (
-    ConnectTimeoutError,
-    InvalidHeader,
-    MaxRetryError,
-    ProtocolError,
-    ProxyError,
-    ReadTimeoutError,
-    ResponseError,
-)
-from .util import reraise
-
-if typing.TYPE_CHECKING:
-    from opentelemetry.agent._vendor.typing_extensions import Self
-
-    from ..connectionpool import ConnectionPool
-    from ..response import BaseHTTPResponse
-
-log = logging.getLogger(__name__)
-
-
-# Data structure for representing the metadata of requests that result in a retry.
-class RequestHistory(typing.NamedTuple):
-    method: str | None
-    url: str | None
-    error: Exception | None
-    status: int | None
-    redirect_location: str | None
-
-
-class Retry:
-    """Retry configuration.
-
-    Each retry attempt will create a new Retry object with updated values, so
-    they can be safely reused.
-
-    Retries can be defined as a default for a pool:
-
-    .. code-block:: python
-
-        retries = Retry(connect=5, read=2, redirect=5)
-        http = PoolManager(retries=retries)
-        response = http.request("GET", "https://example.com/")
-
-    Or per-request (which overrides the default for the pool):
-
-    .. code-block:: python
-
-        response = http.request("GET", "https://example.com/", retries=Retry(10))
-
-    Retries can be disabled by passing ``False``:
-
-    .. code-block:: python
-
-        response = http.request("GET", "https://example.com/", retries=False)
-
-    Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless
-    retries are disabled, in which case the causing exception will be raised.
-
-    :param int total:
-        Total number of retries to allow. Takes precedence over other counts.
-
-        Set to ``None`` to remove this constraint and fall back on other
-        counts.
-
-        Set to ``0`` to fail on the first retry.
-
-        Set to ``False`` to disable and imply ``raise_on_redirect=False``.
-
-    :param int connect:
-        How many connection-related errors to retry on.
-
-        These are errors raised before the request is sent to the remote server,
-        which we assume has not triggered the server to process the request.
-
-        Set to ``0`` to fail on the first retry of this type.
-
-    :param int read:
-        How many times to retry on read errors.
-
-        These errors are raised after the request was sent to the server, so the
-        request may have side-effects.
-
-        Set to ``0`` to fail on the first retry of this type.
-
-    :param int redirect:
-        How many redirects to perform. Limit this to avoid infinite redirect
-        loops.
-
-        A redirect is a HTTP response with a status code 301, 302, 303, 307 or
-        308.
-
-        Set to ``0`` to fail on the first retry of this type.
-
-        Set to ``False`` to disable and imply ``raise_on_redirect=False``.
-
-    :param int status:
-        How many times to retry on bad status codes.
-
-        These are retries made on responses, where status code matches
-        ``status_forcelist``.
-
-        Set to ``0`` to fail on the first retry of this type.
-
-    :param int other:
-        How many times to retry on other errors.
-
-        Other errors are errors that are not connect, read, redirect or status errors.
-        These errors might be raised after the request was sent to the server, so the
-        request might have side-effects.
-
-        Set to ``0`` to fail on the first retry of this type.
-
-        If ``total`` is not set, it's a good idea to set this to 0 to account
-        for unexpected edge cases and avoid infinite retry loops.
-
-    :param Collection allowed_methods:
-        Set of uppercased HTTP method verbs that we should retry on.
-
-        By default, we only retry on methods which are considered to be
-        idempotent (multiple requests with the same parameters end with the
-        same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`.
-
-        Set to a ``None`` value to retry on any verb.
-
-    :param Collection status_forcelist:
-        A set of integer HTTP status codes that we should force a retry on.
-        A retry is initiated if the request method is in ``allowed_methods``
-        and the response status code is in ``status_forcelist``.
-
-        By default, this is disabled with ``None``.
-
-    :param float backoff_factor:
-        A backoff factor to apply between attempts after the second try
-        (most errors are resolved immediately by a second try without a
-        delay). urllib3 will sleep for::
-
-            {backoff factor} * (2 ** ({number of previous retries}))
-
-        seconds. If `backoff_jitter` is non-zero, this sleep is extended by::
-
-            random.uniform(0, {backoff jitter})
-
-        seconds. For example, if the backoff_factor is 0.1, then :func:`Retry.sleep` will
-        sleep for [0.0s, 0.2s, 0.4s, 0.8s, ...] between retries. No backoff will ever
-        be longer than `backoff_max`.
-
-        By default, backoff is disabled (factor set to 0).
-
-    :param float backoff_max:
-        The maximum backoff time (in seconds) between retry attempts.
-        This value caps the computed backoff from `backoff_factor`.
-
-    :param float backoff_jitter:
-        Random jitter amount (in seconds) added to the computed backoff.
-        Jitter is sampled uniformly from `0` to `backoff_jitter`.
-
-    :param bool raise_on_redirect: Whether, if the number of redirects is
-        exhausted, to raise a MaxRetryError, or to return a response with a
-        response code in the 3xx range.
-
-    :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
-        whether we should raise an exception, or return a response,
-        if status falls in ``status_forcelist`` range and retries have
-        been exhausted.
-
-    :param tuple history: The history of the request encountered during
-        each call to :meth:`~Retry.increment`. The list is in the order
-        the requests occurred. Each list item is of class :class:`RequestHistory`.
-
-    :param bool respect_retry_after_header:
-        Whether to respect Retry-After header on status codes defined as
-        :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
-
-    :param Collection remove_headers_on_redirect:
-        Sequence of headers to remove from the request when a response
-        indicating a redirect is returned before firing off the redirected
-        request.
-
-    :param int retry_after_max: Number of seconds to allow as the maximum for
-        Retry-After headers. Defaults to :attr:`Retry.DEFAULT_RETRY_AFTER_MAX`.
-        Any Retry-After headers larger than this value will be limited to this
-        value.
-    """
-
-    #: Default methods to be used for ``allowed_methods``
-    DEFAULT_ALLOWED_METHODS = frozenset(
-        ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"]
-    )
-
-    #: Default status codes that trigger a retry when a Retry-After header is
-    #: present and ``respect_retry_after_header`` is enabled.
-    RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
-
-    #: Default headers to be used for ``remove_headers_on_redirect``
-    DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(
-        ["Cookie", "Authorization", "Proxy-Authorization"]
-    )
-
-    #: Default maximum backoff time.
-    DEFAULT_BACKOFF_MAX = 120
-
-    # This is undocumented in the RFC. Setting to 6 hours matches other popular libraries.
-    #: Default maximum allowed value for Retry-After headers in seconds
-    DEFAULT_RETRY_AFTER_MAX: typing.Final[int] = 21600
-
-    # Backward compatibility; assigned outside of the class.
-    DEFAULT: typing.ClassVar[Retry]
-
-    def __init__(
-        self,
-        total: bool | int | None = 10,
-        connect: int | None = None,
-        read: int | None = None,
-        redirect: bool | int | None = None,
-        status: int | None = None,
-        other: int | None = None,
-        allowed_methods: typing.Collection[str] | None = DEFAULT_ALLOWED_METHODS,
-        status_forcelist: typing.Collection[int] | None = None,
-        backoff_factor: float = 0,
-        backoff_max: float = DEFAULT_BACKOFF_MAX,
-        raise_on_redirect: bool = True,
-        raise_on_status: bool = True,
-        history: tuple[RequestHistory, ...] | None = None,
-        respect_retry_after_header: bool = True,
-        remove_headers_on_redirect: typing.Collection[
-            str
-        ] = DEFAULT_REMOVE_HEADERS_ON_REDIRECT,
-        backoff_jitter: float = 0.0,
-        retry_after_max: int = DEFAULT_RETRY_AFTER_MAX,
-    ) -> None:
-        self.total = total
-        self.connect = connect
-        self.read = read
-        self.status = status
-        self.other = other
-
-        if redirect is False or total is False:
-            redirect = 0
-            raise_on_redirect = False
-
-        self.redirect = redirect
-        self.status_forcelist = status_forcelist or set()
-        if not allowed_methods and isinstance(allowed_methods, Collection):
-            warnings.warn(
-                "Using an empty collection for 'allowed_methods' option to "
-                "retry on any verb is deprecated and will skip retries for "
-                "all verbs in urllib3 v3.0. Instead use "
-                "Retry(..., allowed_methods=None).",
-                FutureWarning,
-                stacklevel=2,
-            )
-        self.allowed_methods = allowed_methods
-        self.backoff_factor = backoff_factor
-        self.backoff_max = backoff_max
-        self.retry_after_max = retry_after_max
-        self.raise_on_redirect = raise_on_redirect
-        self.raise_on_status = raise_on_status
-        self.history = history or ()
-        self.respect_retry_after_header = respect_retry_after_header
-        self.remove_headers_on_redirect = frozenset(
-            h.lower() for h in remove_headers_on_redirect
-        )
-        self.backoff_jitter = backoff_jitter
-
-    def new(self, **kw: typing.Any) -> Self:
-        params = dict(
-            total=self.total,
-            connect=self.connect,
-            read=self.read,
-            redirect=self.redirect,
-            status=self.status,
-            other=self.other,
-            allowed_methods=self.allowed_methods,
-            status_forcelist=self.status_forcelist,
-            backoff_factor=self.backoff_factor,
-            backoff_max=self.backoff_max,
-            retry_after_max=self.retry_after_max,
-            raise_on_redirect=self.raise_on_redirect,
-            raise_on_status=self.raise_on_status,
-            history=self.history,
-            remove_headers_on_redirect=self.remove_headers_on_redirect,
-            respect_retry_after_header=self.respect_retry_after_header,
-            backoff_jitter=self.backoff_jitter,
-        )
-
-        params.update(kw)
-        return type(self)(**params)  # type: ignore[arg-type]
-
-    @classmethod
-    def from_int(
-        cls,
-        retries: Retry | bool | int | None,
-        redirect: bool | int | None = True,
-        default: Retry | bool | int | None = None,
-    ) -> Retry:
-        """Backwards-compatibility for the old retries format."""
-        if retries is None:
-            retries = default if default is not None else cls.DEFAULT
-
-        if isinstance(retries, Retry):
-            return retries
-
-        redirect = bool(redirect) and None
-        new_retries = cls(retries, redirect=redirect)
-        log.debug("Converted retries value: %r -> %r", retries, new_retries)
-        return new_retries
-
-    def get_backoff_time(self) -> float:
-        """Formula for computing the current backoff
-
-        :rtype: float
-        """
-        # We want to consider only the last consecutive errors sequence (Ignore redirects).
-        consecutive_errors_len = len(
-            list(
-                takewhile(lambda x: x.redirect_location is None, reversed(self.history))
-            )
-        )
-        if consecutive_errors_len <= 1:
-            return 0
-
-        backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
-        if self.backoff_jitter != 0.0:
-            backoff_value += random.random() * self.backoff_jitter
-        return float(max(0, min(self.backoff_max, backoff_value)))
-
-    def parse_retry_after(self, retry_after: str) -> float:
-        seconds: float
-        # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4
-        if re.match(r"^\s*[0-9]+\s*$", retry_after):
-            seconds = int(retry_after)
-        else:
-            retry_date_tuple = email.utils.parsedate_tz(retry_after)
-            if retry_date_tuple is None:
-                raise InvalidHeader(f"Invalid Retry-After header: {retry_after}")
-
-            retry_date = email.utils.mktime_tz(retry_date_tuple)
-            seconds = retry_date - time.time()
-
-        seconds = max(seconds, 0)
-
-        # Check the seconds do not exceed the specified maximum
-        if seconds > self.retry_after_max:
-            seconds = self.retry_after_max
-
-        return seconds
-
-    def get_retry_after(self, response: BaseHTTPResponse) -> float | None:
-        """Get the value of Retry-After in seconds."""
-
-        retry_after = response.headers.get("Retry-After")
-
-        if retry_after is None:
-            return None
-
-        return self.parse_retry_after(retry_after)
-
-    def sleep_for_retry(self, response: BaseHTTPResponse) -> bool:
-        retry_after = self.get_retry_after(response)
-        if retry_after:
-            time.sleep(retry_after)
-            return True
-
-        return False
-
-    def _sleep_backoff(self) -> None:
-        backoff = self.get_backoff_time()
-        if backoff <= 0:
-            return
-        time.sleep(backoff)
-
-    def sleep(self, response: BaseHTTPResponse | None = None) -> None:
-        """Sleep between retry attempts.
-
-        This method will respect a server's ``Retry-After`` response header
-        and sleep the duration of the time requested. If that is not present, it
-        will use an exponential backoff. By default, the backoff factor is 0 and
-        this method will return immediately.
-        """
-
-        if self.respect_retry_after_header and response:
-            slept = self.sleep_for_retry(response)
-            if slept:
-                return
-
-        self._sleep_backoff()
-
-    def _is_connection_error(self, err: Exception) -> bool:
-        """Errors when we're fairly sure that the server did not receive the
-        request, so it should be safe to retry.
-        """
-        if isinstance(err, ProxyError):
-            err = err.original_error
-        return isinstance(err, ConnectTimeoutError)
-
-    def _is_read_error(self, err: Exception) -> bool:
-        """Errors that occur after the request has been started, so we should
-        assume that the server began processing it.
-        """
-        return isinstance(err, (ReadTimeoutError, ProtocolError))
-
-    def _is_method_retryable(self, method: str) -> bool:
-        """Checks if a given HTTP method should be retried upon, depending if
-        it is included in the allowed_methods
-        """
-        if self.allowed_methods and method.upper() not in self.allowed_methods:
-            return False
-        return True
-
-    def is_retry(
-        self, method: str, status_code: int, has_retry_after: bool = False
-    ) -> bool:
-        """Is this method/status code retryable? (Based on allowlists and control
-        variables such as the number of total retries to allow, whether to
-        respect the Retry-After header, whether this header is present, and
-        whether the returned status code is on the list of status codes to
-        be retried upon on the presence of the aforementioned header)
-        """
-        if not self._is_method_retryable(method):
-            return False
-
-        if self.status_forcelist and status_code in self.status_forcelist:
-            return True
-
-        return bool(
-            self.total
-            and self.respect_retry_after_header
-            and has_retry_after
-            and (status_code in self.RETRY_AFTER_STATUS_CODES)
-        )
-
-    def is_exhausted(self) -> bool:
-        """Are we out of retries?"""
-        retry_counts = [
-            x
-            for x in (
-                self.total,
-                self.connect,
-                self.read,
-                self.redirect,
-                self.status,
-                self.other,
-            )
-            if x
-        ]
-        if not retry_counts:
-            return False
-
-        return min(retry_counts) < 0
-
-    def increment(
-        self,
-        method: str | None = None,
-        url: str | None = None,
-        response: BaseHTTPResponse | None = None,
-        error: Exception | None = None,
-        _pool: ConnectionPool | None = None,
-        _stacktrace: TracebackType | None = None,
-    ) -> Self:
-        """Return a new Retry object with incremented retry counters.
-
-        :param response: A response object, or None, if the server did not
-            return a response.
-        :type response: :class:`~urllib3.response.BaseHTTPResponse`
-        :param Exception error: An error encountered during the request, or
-            None if the response was received successfully.
-
-        :return: A new ``Retry`` object.
-        """
-        if self.total is False and error:
-            # Disabled, indicate to re-raise the error.
-            raise reraise(type(error), error, _stacktrace)
-
-        total = self.total
-        if total is not None:
-            total -= 1
-
-        connect = self.connect
-        read = self.read
-        redirect = self.redirect
-        status_count = self.status
-        other = self.other
-        cause = "unknown"
-        status = None
-        redirect_location = None
-
-        if error and self._is_connection_error(error):
-            # Connect retry?
-            if connect is False:
-                raise reraise(type(error), error, _stacktrace)
-            elif connect is not None:
-                connect -= 1
-
-        elif error and self._is_read_error(error):
-            # Read retry?
-            if read is False or method is None or not self._is_method_retryable(method):
-                raise reraise(type(error), error, _stacktrace)
-            elif read is not None:
-                read -= 1
-
-        elif error:
-            # Other retry?
-            if other is not None:
-                other -= 1
-
-        elif response and response.get_redirect_location():
-            # Redirect retry?
-            if redirect is not None:
-                redirect -= 1
-            cause = "too many redirects"
-            response_redirect_location = response.get_redirect_location()
-            if response_redirect_location:
-                redirect_location = response_redirect_location
-            status = response.status
-
-        else:
-            # Incrementing because of a server error like a 500 in
-            # status_forcelist and the given method is in the allowed_methods
-            cause = ResponseError.GENERIC_ERROR
-            if response and response.status:
-                if status_count is not None:
-                    status_count -= 1
-                cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status)
-                status = response.status
-
-        history = self.history + (
-            RequestHistory(method, url, error, status, redirect_location),
-        )
-
-        new_retry = self.new(
-            total=total,
-            connect=connect,
-            read=read,
-            redirect=redirect,
-            status=status_count,
-            other=other,
-            history=history,
-        )
-
-        if new_retry.is_exhausted():
-            reason = error or ResponseError(cause)
-            raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
-
-        log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
-
-        return new_retry
-
-    def __repr__(self) -> str:
-        return (
-            f"{type(self).__name__}(total={self.total}, connect={self.connect}, "
-            f"read={self.read}, redirect={self.redirect}, status={self.status})"
-        )
-
-
-# For backwards compatibility (equivalent to pre-v1.9):
-Retry.DEFAULT = Retry(3)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py
deleted file mode 100644
index f6445a41dae..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_.py
+++ /dev/null
@@ -1,481 +0,0 @@
-from __future__ import annotations
-
-import hashlib
-import hmac
-import os
-import socket
-import sys
-import typing
-import warnings
-from binascii import Error as BinasciiError
-from binascii import unhexlify
-
-from ..exceptions import ProxySchemeUnsupported, SSLError
-from .url import _BRACELESS_IPV6_ADDRZ_RE, _IPV4_RE
-
-SSLContext = None
-SSLTransport = None
-HAS_NEVER_CHECK_COMMON_NAME = False
-IS_PYOPENSSL = False
-ALPN_PROTOCOLS = ["http/1.1"]
-
-_TYPE_VERSION_INFO = tuple[int, int, int, str, int]
-
-# Maps the length of a digest to a possible hash function producing this digest
-HASHFUNC_MAP = {
-    length: getattr(hashlib, algorithm, None)
-    for length, algorithm in ((32, "md5"), (40, "sha1"), (64, "sha256"))
-}
-
-
-def _is_has_never_check_common_name_reliable(
-    openssl_version: str,
-) -> bool:
-    # As of May 2023, all released versions of LibreSSL fail to reject certificates with
-    # only common names, see https://github.com/urllib3/urllib3/pull/3024
-    is_openssl = openssl_version.startswith("OpenSSL ")
-
-    return is_openssl
-
-
-if typing.TYPE_CHECKING:
-    from ssl import VerifyMode
-    from typing import TypedDict
-
-    from .ssltransport import SSLTransport as SSLTransportType
-
-    class _TYPE_PEER_CERT_RET_DICT(TypedDict, total=False):
-        subjectAltName: tuple[tuple[str, str], ...]
-        subject: tuple[tuple[tuple[str, str], ...], ...]
-        serialNumber: str
-
-
-# Mapping from 'ssl.PROTOCOL_TLSX' to 'TLSVersion.X'
-_SSL_VERSION_TO_TLS_VERSION: dict[int, int] = {}
-
-try:  # Do we have ssl at all?
-    import ssl
-    from ssl import (  # type: ignore[assignment]
-        CERT_REQUIRED,
-        HAS_NEVER_CHECK_COMMON_NAME,
-        OP_NO_COMPRESSION,
-        OP_NO_TICKET,
-        OPENSSL_VERSION,
-        PROTOCOL_TLS,
-        PROTOCOL_TLS_CLIENT,
-        VERIFY_X509_PARTIAL_CHAIN,
-        VERIFY_X509_STRICT,
-        OP_NO_SSLv2,
-        OP_NO_SSLv3,
-        SSLContext,
-        TLSVersion,
-    )
-
-    PROTOCOL_SSLv23 = PROTOCOL_TLS
-
-    # Setting SSLContext.hostname_checks_common_name = False didn't work with
-    # LibreSSL, check details in the used function.
-    if HAS_NEVER_CHECK_COMMON_NAME and not _is_has_never_check_common_name_reliable(
-        OPENSSL_VERSION,
-    ):  # Defensive:
-        HAS_NEVER_CHECK_COMMON_NAME = False
-
-    # Need to be careful here in case old TLS versions get
-    # removed in future 'ssl' module implementations.
-    for attr in ("TLSv1", "TLSv1_1", "TLSv1_2"):
-        try:
-            _SSL_VERSION_TO_TLS_VERSION[getattr(ssl, f"PROTOCOL_{attr}")] = getattr(
-                TLSVersion, attr
-            )
-        except AttributeError:  # Defensive:
-            continue
-
-    from .ssltransport import SSLTransport  # type: ignore[assignment]
-except ImportError:
-    OP_NO_COMPRESSION = 0x20000  # type: ignore[assignment,misc]
-    OP_NO_TICKET = 0x4000  # type: ignore[assignment,misc]
-    OP_NO_SSLv2 = 0x1000000  # type: ignore[assignment,misc]
-    OP_NO_SSLv3 = 0x2000000  # type: ignore[assignment,misc]
-    PROTOCOL_SSLv23 = PROTOCOL_TLS = 2  # type: ignore[assignment,misc]
-    PROTOCOL_TLS_CLIENT = 16  # type: ignore[assignment,misc]
-    VERIFY_X509_PARTIAL_CHAIN = 0x80000  # type: ignore[assignment,misc]
-    VERIFY_X509_STRICT = 0x20  # type: ignore[assignment,misc]
-
-
-_TYPE_PEER_CERT_RET = typing.Union["_TYPE_PEER_CERT_RET_DICT", bytes, None]
-
-
-def assert_fingerprint(cert: bytes | None, fingerprint: str) -> None:
-    """
-    Checks if given fingerprint matches the supplied certificate.
-
-    :param cert:
-        Certificate as bytes object.
-    :param fingerprint:
-        Fingerprint as string of hexdigits, can be interspersed by colons.
-    """
-
-    if cert is None:
-        raise SSLError("No certificate for the peer.")
-
-    fingerprint = fingerprint.replace(":", "").lower()
-    digest_length = len(fingerprint)
-    if digest_length not in HASHFUNC_MAP:
-        raise SSLError(f"Fingerprint of invalid length: {fingerprint}")
-    hashfunc = HASHFUNC_MAP.get(digest_length)
-    if hashfunc is None:
-        raise SSLError(
-            f"Hash function implementation unavailable for fingerprint length: {digest_length}"
-        )
-
-    # We need encode() here for py32; works on py2 and p33.
-    try:
-        fingerprint_bytes = unhexlify(fingerprint.encode())
-    except BinasciiError as e:
-        raise SSLError(e) from e
-
-    cert_digest = hashfunc(cert).digest()
-
-    if not hmac.compare_digest(cert_digest, fingerprint_bytes):
-        raise SSLError(
-            f'Fingerprints did not match. Expected "{fingerprint}", got "{cert_digest.hex()}"'
-        )
-
-
-def resolve_cert_reqs(candidate: None | int | str) -> VerifyMode:
-    """
-    Resolves the argument to a numeric constant, which can be passed to
-    the wrap_socket function/method from the ssl module.
-    Defaults to :data:`ssl.CERT_REQUIRED`.
-    If given a string it is assumed to be the name of the constant in the
-    :mod:`ssl` module or its abbreviation.
-    (So you can specify `REQUIRED` instead of `CERT_REQUIRED`.
-    If it's neither `None` nor a string we assume it is already the numeric
-    constant which can directly be passed to wrap_socket.
-    """
-    if candidate is None:
-        return CERT_REQUIRED
-
-    if isinstance(candidate, str):
-        res = getattr(ssl, candidate, None)
-        if res is None:
-            res = getattr(ssl, "CERT_" + candidate)
-        return res  # type: ignore[no-any-return]
-
-    return candidate  # type: ignore[return-value]
-
-
-def resolve_ssl_version(candidate: None | int | str) -> int:
-    """
-    like resolve_cert_reqs
-    """
-    if candidate is None:
-        return PROTOCOL_TLS
-
-    if isinstance(candidate, str):
-        res = getattr(ssl, candidate, None)
-        if res is None:
-            res = getattr(ssl, "PROTOCOL_" + candidate)
-        return typing.cast(int, res)
-
-    return candidate
-
-
-def create_urllib3_context(
-    ssl_version: int | None = None,
-    cert_reqs: int | None = None,
-    options: int | None = None,
-    ciphers: str | None = None,
-    ssl_minimum_version: int | None = None,
-    ssl_maximum_version: int | None = None,
-    verify_flags: int | None = None,
-) -> ssl.SSLContext:
-    """Creates and configures an :class:`ssl.SSLContext` instance for use with urllib3.
-
-    :param ssl_version:
-        The desired protocol version to use. This will default to
-        PROTOCOL_SSLv23 which will negotiate the highest protocol that both
-        the server and your installation of OpenSSL support.
-
-        This parameter is deprecated instead use 'ssl_minimum_version'.
-    :param ssl_minimum_version:
-        The minimum version of TLS to be used. Use the 'ssl.TLSVersion' enum for specifying the value.
-    :param ssl_maximum_version:
-        The maximum version of TLS to be used. Use the 'ssl.TLSVersion' enum for specifying the value.
-        Not recommended to set to anything other than 'ssl.TLSVersion.MAXIMUM_SUPPORTED' which is the
-        default value.
-    :param cert_reqs:
-        Whether to require the certificate verification. This defaults to
-        ``ssl.CERT_REQUIRED``.
-    :param options:
-        Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
-        ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
-    :param ciphers:
-        Which cipher suites to allow the server to select. Defaults to either system configured
-        ciphers if OpenSSL 1.1.1+, otherwise uses a secure default set of ciphers.
-    :param verify_flags:
-        The flags for certificate verification operations. These default to
-        ``ssl.VERIFY_X509_PARTIAL_CHAIN`` and ``ssl.VERIFY_X509_STRICT`` for Python 3.13+.
-    :returns:
-        Constructed SSLContext object with specified options
-    :rtype: SSLContext
-    """
-    if SSLContext is None:
-        raise TypeError("Can't create an SSLContext object without an ssl module")
-
-    # This means 'ssl_version' was specified as an exact value.
-    if ssl_version not in (None, PROTOCOL_TLS, PROTOCOL_TLS_CLIENT):
-        # Disallow setting 'ssl_version' and 'ssl_minimum|maximum_version'
-        # to avoid conflicts.
-        if ssl_minimum_version is not None or ssl_maximum_version is not None:
-            raise ValueError(
-                "Can't specify both 'ssl_version' and either "
-                "'ssl_minimum_version' or 'ssl_maximum_version'"
-            )
-
-        # 'ssl_version' is deprecated and will be removed in the future.
-        else:
-            # Use 'ssl_minimum_version' and 'ssl_maximum_version' instead.
-            ssl_minimum_version = _SSL_VERSION_TO_TLS_VERSION.get(
-                ssl_version, TLSVersion.MINIMUM_SUPPORTED
-            )
-            ssl_maximum_version = _SSL_VERSION_TO_TLS_VERSION.get(
-                ssl_version, TLSVersion.MAXIMUM_SUPPORTED
-            )
-
-            # This warning message is pushing users to use 'ssl_minimum_version'
-            # instead of both min/max. Best practice is to only set the minimum version and
-            # keep the maximum version to be it's default value: 'TLSVersion.MAXIMUM_SUPPORTED'
-            warnings.warn(
-                "'ssl_version' option is deprecated and will be "
-                "removed in urllib3 v3.0. Instead use 'ssl_minimum_version'",
-                category=FutureWarning,
-                stacklevel=2,
-            )
-
-    context = SSLContext(PROTOCOL_TLS_CLIENT)
-    if ssl_minimum_version is not None:
-        context.minimum_version = ssl_minimum_version
-    else:  # pyOpenSSL defaults to 'MINIMUM_SUPPORTED' so explicitly set TLSv1.2 here
-        context.minimum_version = TLSVersion.TLSv1_2
-
-    if ssl_maximum_version is not None:
-        context.maximum_version = ssl_maximum_version
-
-    # Unless we're given ciphers defer to either system ciphers in
-    # the case of OpenSSL 1.1.1+ or use our own secure default ciphers.
-    if ciphers:
-        context.set_ciphers(ciphers)
-
-    # Setting the default here, as we may have no ssl module on import
-    cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
-
-    if options is None:
-        options = 0
-        # SSLv2 is easily broken and is considered harmful and dangerous
-        options |= OP_NO_SSLv2
-        # SSLv3 has several problems and is now dangerous
-        options |= OP_NO_SSLv3
-        # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
-        # (issue #309)
-        options |= OP_NO_COMPRESSION
-        # TLSv1.2 only. Unless set explicitly, do not request tickets.
-        # This may save some bandwidth on wire, and although the ticket is encrypted,
-        # there is a risk associated with it being on wire,
-        # if the server is not rotating its ticketing keys properly.
-        options |= OP_NO_TICKET
-
-    context.options |= options
-
-    if verify_flags is None:
-        verify_flags = 0
-        # In Python 3.13+ ssl.create_default_context() sets VERIFY_X509_PARTIAL_CHAIN
-        # and VERIFY_X509_STRICT so we do the same
-        if sys.version_info >= (3, 13):
-            verify_flags |= VERIFY_X509_PARTIAL_CHAIN
-            verify_flags |= VERIFY_X509_STRICT
-
-    context.verify_flags |= verify_flags
-
-    # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
-    # necessary for conditional client cert authentication with TLS 1.3.
-    # The attribute is None for OpenSSL <= 1.1.0 or does not exist when using
-    # an SSLContext created by pyOpenSSL.
-    if getattr(context, "post_handshake_auth", None) is not None:
-        context.post_handshake_auth = True
-
-    # The order of the below lines setting verify_mode and check_hostname
-    # matter due to safe-guards SSLContext has to prevent an SSLContext with
-    # check_hostname=True, verify_mode=NONE/OPTIONAL.
-    # We always set 'check_hostname=False' for pyOpenSSL so we rely on our own
-    # 'ssl.match_hostname()' implementation.
-    if cert_reqs == ssl.CERT_REQUIRED and not IS_PYOPENSSL:
-        context.verify_mode = cert_reqs
-        context.check_hostname = True
-    else:
-        context.check_hostname = False
-        context.verify_mode = cert_reqs
-
-    context.hostname_checks_common_name = False
-
-    if "SSLKEYLOGFILE" in os.environ:
-        sslkeylogfile = os.path.expandvars(os.environ.get("SSLKEYLOGFILE"))
-    else:
-        sslkeylogfile = None
-    if sslkeylogfile:
-        context.keylog_filename = sslkeylogfile
-
-    return context
-
-
-@typing.overload
-def ssl_wrap_socket(
-    sock: socket.socket,
-    keyfile: str | None = ...,
-    certfile: str | None = ...,
-    cert_reqs: int | None = ...,
-    ca_certs: str | None = ...,
-    server_hostname: str | None = ...,
-    ssl_version: int | None = ...,
-    ciphers: str | None = ...,
-    ssl_context: ssl.SSLContext | None = ...,
-    ca_cert_dir: str | None = ...,
-    key_password: str | None = ...,
-    ca_cert_data: None | str | bytes = ...,
-    tls_in_tls: typing.Literal[False] = ...,
-) -> ssl.SSLSocket: ...
-
-
-@typing.overload
-def ssl_wrap_socket(
-    sock: socket.socket,
-    keyfile: str | None = ...,
-    certfile: str | None = ...,
-    cert_reqs: int | None = ...,
-    ca_certs: str | None = ...,
-    server_hostname: str | None = ...,
-    ssl_version: int | None = ...,
-    ciphers: str | None = ...,
-    ssl_context: ssl.SSLContext | None = ...,
-    ca_cert_dir: str | None = ...,
-    key_password: str | None = ...,
-    ca_cert_data: None | str | bytes = ...,
-    tls_in_tls: bool = ...,
-) -> ssl.SSLSocket | SSLTransportType: ...
-
-
-def ssl_wrap_socket(
-    sock: socket.socket,
-    keyfile: str | None = None,
-    certfile: str | None = None,
-    cert_reqs: int | None = None,
-    ca_certs: str | None = None,
-    server_hostname: str | None = None,
-    ssl_version: int | None = None,
-    ciphers: str | None = None,
-    ssl_context: ssl.SSLContext | None = None,
-    ca_cert_dir: str | None = None,
-    key_password: str | None = None,
-    ca_cert_data: None | str | bytes = None,
-    tls_in_tls: bool = False,
-) -> ssl.SSLSocket | SSLTransportType:
-    """
-    All arguments except for server_hostname, ssl_context, tls_in_tls, ca_cert_data and
-    ca_cert_dir have the same meaning as they do when using
-    :func:`ssl.create_default_context`, :meth:`ssl.SSLContext.load_cert_chain`,
-    :meth:`ssl.SSLContext.set_ciphers` and :meth:`ssl.SSLContext.wrap_socket`.
-
-    :param server_hostname:
-        When SNI is supported, the expected hostname of the certificate
-    :param ssl_context:
-        A pre-made :class:`SSLContext` object. If none is provided, one will
-        be created using :func:`create_urllib3_context`.
-    :param ciphers:
-        A string of ciphers we wish the client to support.
-    :param ca_cert_dir:
-        A directory containing CA certificates in multiple separate files, as
-        supported by OpenSSL's -CApath flag or the capath argument to
-        SSLContext.load_verify_locations().
-    :param key_password:
-        Optional password if the keyfile is encrypted.
-    :param ca_cert_data:
-        Optional string containing CA certificates in PEM format suitable for
-        passing as the cadata parameter to SSLContext.load_verify_locations()
-    :param tls_in_tls:
-        Use SSLTransport to wrap the existing socket.
-    """
-    context = ssl_context
-    if context is None:
-        # Note: This branch of code and all the variables in it are only used in tests.
-        # We should consider deprecating and removing this code.
-        context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers)
-
-    if ca_certs or ca_cert_dir or ca_cert_data:
-        try:
-            context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data)
-        except OSError as e:
-            raise SSLError(e) from e
-
-    elif ssl_context is None and hasattr(context, "load_default_certs"):
-        # try to load OS default certs; works well on Windows.
-        context.load_default_certs()
-
-    # Attempt to detect if we get the goofy behavior of the
-    # keyfile being encrypted and OpenSSL asking for the
-    # passphrase via the terminal and instead error out.
-    if keyfile and key_password is None and _is_key_file_encrypted(keyfile):
-        raise SSLError("Client private key is encrypted, password is required")
-
-    if certfile:
-        if key_password is None:
-            context.load_cert_chain(certfile, keyfile)
-        else:
-            context.load_cert_chain(certfile, keyfile, key_password)
-
-    context.set_alpn_protocols(ALPN_PROTOCOLS)
-
-    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
-    return ssl_sock
-
-
-def is_ipaddress(hostname: str | bytes) -> bool:
-    """Detects whether the hostname given is an IPv4 or IPv6 address.
-    Also detects IPv6 addresses with Zone IDs.
-
-    :param str hostname: Hostname to examine.
-    :return: True if the hostname is an IP address, False otherwise.
-    """
-    if isinstance(hostname, bytes):
-        # IDN A-label bytes are ASCII compatible.
-        hostname = hostname.decode("ascii")
-    return bool(_IPV4_RE.match(hostname) or _BRACELESS_IPV6_ADDRZ_RE.match(hostname))
-
-
-def _is_key_file_encrypted(key_file: str) -> bool:
-    """Detects if a key file is encrypted or not."""
-    with open(key_file) as f:
-        for line in f:
-            # Look for Proc-Type: 4,ENCRYPTED
-            if "ENCRYPTED" in line:
-                return True
-
-    return False
-
-
-def _ssl_wrap_socket_impl(
-    sock: socket.socket,
-    ssl_context: ssl.SSLContext,
-    tls_in_tls: bool,
-    server_hostname: str | None = None,
-) -> ssl.SSLSocket | SSLTransportType:
-    if tls_in_tls:
-        if not SSLTransport:
-            # Import error, ssl is not available.
-            raise ProxySchemeUnsupported(
-                "TLS in TLS requires support for the 'ssl' module"
-            )
-
-        SSLTransport._validate_ssl_context_for_tls_in_tls(ssl_context)
-        return SSLTransport(sock, ssl_context, server_hostname)
-
-    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py
deleted file mode 100644
index 94994f25ae1..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssl_match_hostname.py
+++ /dev/null
@@ -1,153 +0,0 @@
-"""The match_hostname() function from Python 3.5, essential when using SSL."""
-
-# Note: This file is under the PSF license as the code comes from the python
-# stdlib.   http://docs.python.org/3/license.html
-# It is modified to remove commonName support.
-
-from __future__ import annotations
-
-import ipaddress
-import re
-import typing
-from ipaddress import IPv4Address, IPv6Address
-
-if typing.TYPE_CHECKING:
-    from .ssl_ import _TYPE_PEER_CERT_RET_DICT
-
-__version__ = "3.5.0.1"
-
-
-class CertificateError(ValueError):
-    pass
-
-
-def _dnsname_match(
-    dn: typing.Any, hostname: str, max_wildcards: int = 1
-) -> typing.Match[str] | None | bool:
-    """Matching according to RFC 6125, section 6.4.3
-
-    http://tools.ietf.org/html/rfc6125#section-6.4.3
-    """
-    pats = []
-    if not dn:
-        return False
-
-    # Ported from python3-syntax:
-    # leftmost, *remainder = dn.split(r'.')
-    parts = dn.split(r".")
-    leftmost = parts[0]
-    remainder = parts[1:]
-
-    wildcards = leftmost.count("*")
-    if wildcards > max_wildcards:
-        # Issue #17980: avoid denials of service by refusing more
-        # than one wildcard per fragment.  A survey of established
-        # policy among SSL implementations showed it to be a
-        # reasonable choice.
-        raise CertificateError(
-            "too many wildcards in certificate DNS name: " + repr(dn)
-        )
-
-    # speed up common case w/o wildcards
-    if not wildcards:
-        return bool(dn.lower() == hostname.lower())
-
-    # RFC 6125, section 6.4.3, subitem 1.
-    # The client SHOULD NOT attempt to match a presented identifier in which
-    # the wildcard character comprises a label other than the left-most label.
-    if leftmost == "*":
-        # When '*' is a fragment by itself, it matches a non-empty dotless
-        # fragment.
-        pats.append("[^.]+")
-    elif leftmost.startswith("xn--") or hostname.startswith("xn--"):
-        # RFC 6125, section 6.4.3, subitem 3.
-        # The client SHOULD NOT attempt to match a presented identifier
-        # where the wildcard character is embedded within an A-label or
-        # U-label of an internationalized domain name.
-        pats.append(re.escape(leftmost))
-    else:
-        # Otherwise, '*' matches any dotless string, e.g. www*
-        pats.append(re.escape(leftmost).replace(r"\*", "[^.]*"))
-
-    # add the remaining fragments, ignore any wildcards
-    for frag in remainder:
-        pats.append(re.escape(frag))
-
-    pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE)
-    return pat.match(hostname)
-
-
-def _ipaddress_match(ipname: str, host_ip: IPv4Address | IPv6Address) -> bool:
-    """Exact matching of IP addresses.
-
-    RFC 9110 section 4.3.5: "A reference identity of IP-ID contains the decoded
-    bytes of the IP address. An IP version 4 address is 4 octets, and an IP
-    version 6 address is 16 octets. [...] A reference identity of type IP-ID
-    matches if the address is identical to an iPAddress value of the
-    subjectAltName extension of the certificate."
-    """
-    # OpenSSL may add a trailing newline to a subjectAltName's IP address
-    # Divergence from upstream: ipaddress can't handle byte str
-    ip = ipaddress.ip_address(ipname.rstrip())
-    return bool(ip.packed == host_ip.packed)
-
-
-def match_hostname(
-    cert: _TYPE_PEER_CERT_RET_DICT | None,
-    hostname: str,
-    hostname_checks_common_name: bool = False,
-) -> None:
-    """Verify that *cert* (in decoded format as returned by
-    SSLSocket.getpeercert()) matches the *hostname*.  RFC 2818 and RFC 6125
-    rules are followed, but IP addresses are not accepted for *hostname*.
-
-    CertificateError is raised on failure. On success, the function
-    returns nothing.
-    """
-    if not cert:
-        raise ValueError(
-            "empty or no certificate, match_hostname needs a "
-            "SSL socket or SSL context with either "
-            "CERT_OPTIONAL or CERT_REQUIRED"
-        )
-
-    try:
-        host_ip = ipaddress.ip_address(hostname)
-    except ValueError:
-        # Not an IP address (common case)
-        host_ip = None
-    dnsnames = []
-    san: tuple[tuple[str, str], ...] = cert.get("subjectAltName", ())
-    key: str
-    value: str
-    for key, value in san:
-        if key == "DNS":
-            if host_ip is None and _dnsname_match(value, hostname):
-                return
-            dnsnames.append(value)
-        elif key == "IP Address":
-            if host_ip is not None and _ipaddress_match(value, host_ip):
-                return
-            dnsnames.append(value)
-
-    # We only check 'commonName' if it's enabled and we're not verifying
-    # an IP address. IP addresses aren't valid within 'commonName'.
-    if hostname_checks_common_name and host_ip is None and not dnsnames:
-        for sub in cert.get("subject", ()):
-            for key, value in sub:
-                if key == "commonName":
-                    if _dnsname_match(value, hostname):
-                        return
-                    dnsnames.append(
-                        value
-                    )  # Defensive: for older PyPy and OpenSSL versions
-
-    if len(dnsnames) > 1:
-        raise CertificateError(
-            "hostname %r "
-            "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames)))
-        )
-    elif len(dnsnames) == 1:
-        raise CertificateError(f"hostname {hostname!r} doesn't match {dnsnames[0]!r}")
-    else:
-        raise CertificateError("no appropriate subjectAltName fields were found")
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py
deleted file mode 100644
index 3e3132f8ca0..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/ssltransport.py
+++ /dev/null
@@ -1,271 +0,0 @@
-from __future__ import annotations
-
-import io
-import socket
-import ssl
-import typing
-
-from ..exceptions import ProxySchemeUnsupported
-
-if typing.TYPE_CHECKING:
-    from opentelemetry.agent._vendor.typing_extensions import Self
-
-    from .ssl_ import _TYPE_PEER_CERT_RET, _TYPE_PEER_CERT_RET_DICT
-
-
-_WriteBuffer = typing.Union[bytearray, memoryview]
-_ReturnValue = typing.TypeVar("_ReturnValue")
-
-SSL_BLOCKSIZE = 16384
-
-
-class SSLTransport:
-    """
-    The SSLTransport wraps an existing socket and establishes an SSL connection.
-
-    Contrary to Python's implementation of SSLSocket, it allows you to chain
-    multiple TLS connections together. It's particularly useful if you need to
-    implement TLS within TLS.
-
-    The class supports most of the socket API operations.
-    """
-
-    @staticmethod
-    def _validate_ssl_context_for_tls_in_tls(ssl_context: ssl.SSLContext) -> None:
-        """
-        Raises a ProxySchemeUnsupported if the provided ssl_context can't be used
-        for TLS in TLS.
-
-        The only requirement is that the ssl_context provides the 'wrap_bio'
-        methods.
-        """
-
-        if not hasattr(ssl_context, "wrap_bio"):
-            raise ProxySchemeUnsupported(
-                "TLS in TLS requires SSLContext.wrap_bio() which isn't "
-                "available on non-native SSLContext"
-            )
-
-    def __init__(
-        self,
-        socket: socket.socket,
-        ssl_context: ssl.SSLContext,
-        server_hostname: str | None = None,
-        suppress_ragged_eofs: bool = True,
-    ) -> None:
-        """
-        Create an SSLTransport around socket using the provided ssl_context.
-        """
-        self.incoming = ssl.MemoryBIO()
-        self.outgoing = ssl.MemoryBIO()
-
-        self.suppress_ragged_eofs = suppress_ragged_eofs
-        self.socket = socket
-
-        self.sslobj = ssl_context.wrap_bio(
-            self.incoming, self.outgoing, server_hostname=server_hostname
-        )
-
-        # Perform initial handshake.
-        self._ssl_io_loop(self.sslobj.do_handshake)
-
-    def __enter__(self) -> Self:
-        return self
-
-    def __exit__(self, *_: typing.Any) -> None:
-        self.close()
-
-    def fileno(self) -> int:
-        return self.socket.fileno()
-
-    def read(self, len: int = 1024, buffer: typing.Any | None = None) -> int | bytes:
-        return self._wrap_ssl_read(len, buffer)
-
-    def recv(self, buflen: int = 1024, flags: int = 0) -> int | bytes:
-        if flags != 0:
-            raise ValueError("non-zero flags not allowed in calls to recv")
-        return self._wrap_ssl_read(buflen)
-
-    def recv_into(
-        self,
-        buffer: _WriteBuffer,
-        nbytes: int | None = None,
-        flags: int = 0,
-    ) -> None | int | bytes:
-        if flags != 0:
-            raise ValueError("non-zero flags not allowed in calls to recv_into")
-        if nbytes is None:
-            nbytes = len(buffer)
-        return self.read(nbytes, buffer)
-
-    def sendall(self, data: bytes, flags: int = 0) -> None:
-        if flags != 0:
-            raise ValueError("non-zero flags not allowed in calls to sendall")
-        count = 0
-        with memoryview(data) as view, view.cast("B") as byte_view:
-            amount = len(byte_view)
-            while count < amount:
-                v = self.send(byte_view[count:])
-                count += v
-
-    def send(self, data: bytes, flags: int = 0) -> int:
-        if flags != 0:
-            raise ValueError("non-zero flags not allowed in calls to send")
-        return self._ssl_io_loop(self.sslobj.write, data)
-
-    def makefile(
-        self,
-        mode: str,
-        buffering: int | None = None,
-        *,
-        encoding: str | None = None,
-        errors: str | None = None,
-        newline: str | None = None,
-    ) -> typing.BinaryIO | typing.TextIO | socket.SocketIO:
-        """
-        Python's httpclient uses makefile and buffered io when reading HTTP
-        messages and we need to support it.
-
-        This is unfortunately a copy and paste of socket.py makefile with small
-        changes to point to the socket directly.
-        """
-        if not set(mode) <= {"r", "w", "b"}:
-            raise ValueError(f"invalid mode {mode!r} (only r, w, b allowed)")
-
-        writing = "w" in mode
-        reading = "r" in mode or not writing
-        assert reading or writing
-        binary = "b" in mode
-        rawmode = ""
-        if reading:
-            rawmode += "r"
-        if writing:
-            rawmode += "w"
-        raw = socket.SocketIO(self, rawmode)  # type: ignore[arg-type]
-        self.socket._io_refs += 1  # type: ignore[attr-defined]
-        if buffering is None:
-            buffering = -1
-        if buffering < 0:
-            buffering = io.DEFAULT_BUFFER_SIZE
-        if buffering == 0:
-            if not binary:
-                raise ValueError("unbuffered streams must be binary")
-            return raw
-        buffer: typing.BinaryIO
-        if reading and writing:
-            buffer = io.BufferedRWPair(raw, raw, buffering)  # type: ignore[assignment]
-        elif reading:
-            buffer = io.BufferedReader(raw, buffering)
-        else:
-            assert writing
-            buffer = io.BufferedWriter(raw, buffering)
-        if binary:
-            return buffer
-        text = io.TextIOWrapper(buffer, encoding, errors, newline)
-        text.mode = mode  # type: ignore[misc]
-        return text
-
-    def unwrap(self) -> None:
-        self._ssl_io_loop(self.sslobj.unwrap)
-
-    def close(self) -> None:
-        self.socket.close()
-
-    @typing.overload
-    def getpeercert(
-        self, binary_form: typing.Literal[False] = ...
-    ) -> _TYPE_PEER_CERT_RET_DICT | None: ...
-
-    @typing.overload
-    def getpeercert(self, binary_form: typing.Literal[True]) -> bytes | None: ...
-
-    def getpeercert(self, binary_form: bool = False) -> _TYPE_PEER_CERT_RET:
-        return self.sslobj.getpeercert(binary_form)  # type: ignore[return-value]
-
-    def version(self) -> str | None:
-        return self.sslobj.version()
-
-    def cipher(self) -> tuple[str, str, int] | None:
-        return self.sslobj.cipher()
-
-    def selected_alpn_protocol(self) -> str | None:
-        return self.sslobj.selected_alpn_protocol()
-
-    def shared_ciphers(self) -> list[tuple[str, str, int]] | None:
-        return self.sslobj.shared_ciphers()
-
-    def compression(self) -> str | None:
-        return self.sslobj.compression()
-
-    def settimeout(self, value: float | None) -> None:
-        self.socket.settimeout(value)
-
-    def gettimeout(self) -> float | None:
-        return self.socket.gettimeout()
-
-    def _decref_socketios(self) -> None:
-        self.socket._decref_socketios()  # type: ignore[attr-defined]
-
-    def _wrap_ssl_read(self, len: int, buffer: bytearray | None = None) -> int | bytes:
-        try:
-            return self._ssl_io_loop(self.sslobj.read, len, buffer)
-        except ssl.SSLError as e:
-            if e.errno == ssl.SSL_ERROR_EOF and self.suppress_ragged_eofs:
-                return 0  # eof, return 0.
-            else:
-                raise
-
-    # func is sslobj.do_handshake or sslobj.unwrap
-    @typing.overload
-    def _ssl_io_loop(self, func: typing.Callable[[], None]) -> None: ...
-
-    # func is sslobj.write, arg1 is data
-    @typing.overload
-    def _ssl_io_loop(self, func: typing.Callable[[bytes], int], arg1: bytes) -> int: ...
-
-    # func is sslobj.read, arg1 is len, arg2 is buffer
-    @typing.overload
-    def _ssl_io_loop(
-        self,
-        func: typing.Callable[[int, bytearray | None], bytes],
-        arg1: int,
-        arg2: bytearray | None,
-    ) -> bytes: ...
-
-    def _ssl_io_loop(
-        self,
-        func: typing.Callable[..., _ReturnValue],
-        arg1: None | bytes | int = None,
-        arg2: bytearray | None = None,
-    ) -> _ReturnValue:
-        """Performs an I/O loop between incoming/outgoing and the socket."""
-        should_loop = True
-        ret = None
-
-        while should_loop:
-            errno = None
-            try:
-                if arg1 is None and arg2 is None:
-                    ret = func()
-                elif arg2 is None:
-                    ret = func(arg1)
-                else:
-                    ret = func(arg1, arg2)
-            except ssl.SSLError as e:
-                if e.errno not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
-                    # WANT_READ, and WANT_WRITE are expected, others are not.
-                    raise e
-                errno = e.errno
-
-            buf = self.outgoing.read()
-            self.socket.sendall(buf)
-
-            if errno is None:
-                should_loop = False
-            elif errno == ssl.SSL_ERROR_WANT_READ:
-                buf = self.socket.recv(SSL_BLOCKSIZE)
-                if buf:
-                    self.incoming.write(buf)
-                else:
-                    self.incoming.write_eof()
-        return typing.cast(_ReturnValue, ret)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py
deleted file mode 100644
index 4bb1be11d9c..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/timeout.py
+++ /dev/null
@@ -1,275 +0,0 @@
-from __future__ import annotations
-
-import time
-import typing
-from enum import Enum
-from socket import getdefaulttimeout
-
-from ..exceptions import TimeoutStateError
-
-if typing.TYPE_CHECKING:
-    from typing import Final
-
-
-class _TYPE_DEFAULT(Enum):
-    # This value should never be passed to socket.settimeout() so for safety we use a -1.
-    # socket.settimout() raises a ValueError for negative values.
-    token = -1
-
-
-_DEFAULT_TIMEOUT: Final[_TYPE_DEFAULT] = _TYPE_DEFAULT.token
-
-_TYPE_TIMEOUT = typing.Optional[typing.Union[float, _TYPE_DEFAULT]]
-
-
-class Timeout:
-    """Timeout configuration.
-
-    Timeouts can be defined as a default for a pool:
-
-    .. code-block:: python
-
-        import urllib3
-
-        timeout = urllib3.util.Timeout(connect=2.0, read=7.0)
-
-        http = urllib3.PoolManager(timeout=timeout)
-
-        resp = http.request("GET", "https://example.com/")
-
-        print(resp.status)
-
-    Or per-request (which overrides the default for the pool):
-
-    .. code-block:: python
-
-       response = http.request("GET", "https://example.com/", timeout=Timeout(10))
-
-    Timeouts can be disabled by setting all the parameters to ``None``:
-
-    .. code-block:: python
-
-       no_timeout = Timeout(connect=None, read=None)
-       response = http.request("GET", "https://example.com/", timeout=no_timeout)
-
-
-    :param total:
-        This combines the connect and read timeouts into one; the read timeout
-        will be set to the time leftover from the connect attempt. In the
-        event that both a connect timeout and a total are specified, or a read
-        timeout and a total are specified, the shorter timeout will be applied.
-
-        Defaults to None.
-
-    :type total: int, float, or None
-
-    :param connect:
-        The maximum amount of time (in seconds) to wait for a connection
-        attempt to a server to succeed. Omitting the parameter will default the
-        connect timeout to the system default, probably `the global default
-        timeout in socket.py
-        `_.
-        None will set an infinite timeout for connection attempts.
-
-    :type connect: int, float, or None
-
-    :param read:
-        The maximum amount of time (in seconds) to wait between consecutive
-        read operations for a response from the server. Omitting the parameter
-        will default the read timeout to the system default, probably `the
-        global default timeout in socket.py
-        `_.
-        None will set an infinite timeout.
-
-    :type read: int, float, or None
-
-    .. note::
-
-        Many factors can affect the total amount of time for urllib3 to return
-        an HTTP response.
-
-        For example, Python's DNS resolver does not obey the timeout specified
-        on the socket. Other factors that can affect total request time include
-        high CPU load, high swap, the program running at a low priority level,
-        or other behaviors.
-
-        In addition, the read and total timeouts only measure the time between
-        read operations on the socket connecting the client and the server,
-        not the total amount of time for the request to return a complete
-        response. For most requests, the timeout is raised because the server
-        has not sent the first byte in the specified time. This is not always
-        the case; if a server streams one byte every fifteen seconds, a timeout
-        of 20 seconds will not trigger, even though the request will take
-        several minutes to complete.
-    """
-
-    #: A sentinel object representing the default timeout value
-    DEFAULT_TIMEOUT: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT
-
-    def __init__(
-        self,
-        total: _TYPE_TIMEOUT = None,
-        connect: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-        read: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT,
-    ) -> None:
-        self._connect = self._validate_timeout(connect, "connect")
-        self._read = self._validate_timeout(read, "read")
-        self.total = self._validate_timeout(total, "total")
-        self._start_connect: float | None = None
-
-    def __repr__(self) -> str:
-        return f"{type(self).__name__}(connect={self._connect!r}, read={self._read!r}, total={self.total!r})"
-
-    # __str__ provided for backwards compatibility
-    __str__ = __repr__
-
-    @staticmethod
-    def resolve_default_timeout(timeout: _TYPE_TIMEOUT) -> float | None:
-        return getdefaulttimeout() if timeout is _DEFAULT_TIMEOUT else timeout
-
-    @classmethod
-    def _validate_timeout(cls, value: _TYPE_TIMEOUT, name: str) -> _TYPE_TIMEOUT:
-        """Check that a timeout attribute is valid.
-
-        :param value: The timeout value to validate
-        :param name: The name of the timeout attribute to validate. This is
-            used to specify in error messages.
-        :return: The validated and casted version of the given value.
-        :raises ValueError: If it is a numeric value less than or equal to
-            zero, or the type is not an integer, float, or None.
-        """
-        if value is None or value is _DEFAULT_TIMEOUT:
-            return value
-
-        if isinstance(value, bool):
-            raise ValueError(
-                "Timeout cannot be a boolean value. It must "
-                "be an int, float or None."
-            )
-        try:
-            float(value)
-        except (TypeError, ValueError):
-            raise ValueError(
-                "Timeout value %s was %s, but it must be an "
-                "int, float or None." % (name, value)
-            ) from None
-
-        try:
-            if value <= 0:
-                raise ValueError(
-                    "Attempted to set %s timeout to %s, but the "
-                    "timeout cannot be set to a value less "
-                    "than or equal to 0." % (name, value)
-                )
-        except TypeError:
-            raise ValueError(
-                "Timeout value %s was %s, but it must be an "
-                "int, float or None." % (name, value)
-            ) from None
-
-        return value
-
-    @classmethod
-    def from_float(cls, timeout: _TYPE_TIMEOUT) -> Timeout:
-        """Create a new Timeout from a legacy timeout value.
-
-        The timeout value used by httplib.py sets the same timeout on the
-        connect(), and recv() socket requests. This creates a :class:`Timeout`
-        object that sets the individual timeouts to the ``timeout`` value
-        passed to this function.
-
-        :param timeout: The legacy timeout value.
-        :type timeout: integer, float, :attr:`urllib3.util.Timeout.DEFAULT_TIMEOUT`, or None
-        :return: Timeout object
-        :rtype: :class:`Timeout`
-        """
-        return Timeout(read=timeout, connect=timeout)
-
-    def clone(self) -> Timeout:
-        """Create a copy of the timeout object
-
-        Timeout properties are stored per-pool but each request needs a fresh
-        Timeout object to ensure each one has its own start/stop configured.
-
-        :return: a copy of the timeout object
-        :rtype: :class:`Timeout`
-        """
-        # We can't use copy.deepcopy because that will also create a new object
-        # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to
-        # detect the user default.
-        return Timeout(connect=self._connect, read=self._read, total=self.total)
-
-    def start_connect(self) -> float:
-        """Start the timeout clock, used during a connect() attempt
-
-        :raises urllib3.exceptions.TimeoutStateError: if you attempt
-            to start a timer that has been started already.
-        """
-        if self._start_connect is not None:
-            raise TimeoutStateError("Timeout timer has already been started.")
-        self._start_connect = time.monotonic()
-        return self._start_connect
-
-    def get_connect_duration(self) -> float:
-        """Gets the time elapsed since the call to :meth:`start_connect`.
-
-        :return: Elapsed time in seconds.
-        :rtype: float
-        :raises urllib3.exceptions.TimeoutStateError: if you attempt
-            to get duration for a timer that hasn't been started.
-        """
-        if self._start_connect is None:
-            raise TimeoutStateError(
-                "Can't get connect duration for timer that has not started."
-            )
-        return time.monotonic() - self._start_connect
-
-    @property
-    def connect_timeout(self) -> _TYPE_TIMEOUT:
-        """Get the value to use when setting a connection timeout.
-
-        This will be a positive float or integer, the value None
-        (never timeout), or the default system timeout.
-
-        :return: Connect timeout.
-        :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
-        """
-        if self.total is None:
-            return self._connect
-
-        if self._connect is None or self._connect is _DEFAULT_TIMEOUT:
-            return self.total
-
-        return min(self._connect, self.total)  # type: ignore[type-var]
-
-    @property
-    def read_timeout(self) -> float | None:
-        """Get the value for the read timeout.
-
-        This assumes some time has elapsed in the connection timeout and
-        computes the read timeout appropriately.
-
-        If self.total is set, the read timeout is dependent on the amount of
-        time taken by the connect timeout. If the connection time has not been
-        established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be
-        raised.
-
-        :return: Value to use for the read timeout.
-        :rtype: int, float or None
-        :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect`
-            has not yet been called on this object.
-        """
-        if (
-            self.total is not None
-            and self.total is not _DEFAULT_TIMEOUT
-            and self._read is not None
-            and self._read is not _DEFAULT_TIMEOUT
-        ):
-            # In case the connect timeout has not yet been established.
-            if self._start_connect is None:
-                return self._read
-            return max(0, min(self.total - self.get_connect_duration(), self._read))
-        elif self.total is not None and self.total is not _DEFAULT_TIMEOUT:
-            return max(0, self.total - self.get_connect_duration())
-        else:
-            return self.resolve_default_timeout(self._read)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py
deleted file mode 100644
index c635cddc9d0..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/url.py
+++ /dev/null
@@ -1,577 +0,0 @@
-from __future__ import annotations
-
-import re
-import typing
-from functools import partial
-from urllib.parse import unquote as _unquote
-
-from ..exceptions import LocationParseError
-from .util import to_str
-
-# We only want to normalize urls with an HTTP(S) scheme.
-# urllib3 infers URLs without a scheme (None) to be http.
-_NORMALIZABLE_SCHEMES = ("http", "https", None)
-
-# Almost all of these patterns were derived from the
-# 'rfc3986' module: https://github.com/python-hyper/rfc3986
-_PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}")
-_HOST_PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}|%")
-_SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)")
-_HOST_INVALID_CHAR_RE = re.compile(r"[\x00-\x20\x7f]")
-_URI_RE = re.compile(
-    r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?"
-    r"(?://([^\\/?#]*))?"
-    r"([^?#]*)"
-    r"(?:\?([^#]*))?"
-    r"(?:#(.*))?$",
-    re.UNICODE | re.DOTALL,
-)
-
-_IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}"
-_HEX_PAT = "[0-9A-Fa-f]{1,4}"
-_LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=_HEX_PAT, ipv4=_IPV4_PAT)
-_subs = {"hex": _HEX_PAT, "ls32": _LS32_PAT}
-_variations = [
-    #                            6( h16 ":" ) ls32
-    "(?:%(hex)s:){6}%(ls32)s",
-    #                       "::" 5( h16 ":" ) ls32
-    "::(?:%(hex)s:){5}%(ls32)s",
-    # [               h16 ] "::" 4( h16 ":" ) ls32
-    "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s",
-    # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
-    "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s",
-    # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
-    "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s",
-    # [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
-    "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s",
-    # [ *4( h16 ":" ) h16 ] "::"              ls32
-    "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s",
-    # [ *5( h16 ":" ) h16 ] "::"              h16
-    "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s",
-    # [ *6( h16 ":" ) h16 ] "::"
-    "(?:(?:%(hex)s:){0,6}%(hex)s)?::",
-]
-
-_UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._\-~"
-_IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")"
-_ZONE_ID_PAT = "(?:%25|%)(?:[" + _UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+"
-_IPV6_ADDRZ_PAT = r"\[" + _IPV6_PAT + r"(?:" + _ZONE_ID_PAT + r")?\]"
-_REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*"
-_TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$")
-
-_IPV4_RE = re.compile(
-    r"^(?:0[xX][0-9a-fA-F]+|[0-9]+)(?:\.(?:0[xX][0-9a-fA-F]+|[0-9]+)){0,3}$"
-)
-_IPV6_RE = re.compile("^" + _IPV6_PAT + "$")
-_IPV6_ADDRZ_RE = re.compile("^" + _IPV6_ADDRZ_PAT + "$")
-_BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + _IPV6_ADDRZ_PAT[2:-2] + "$")
-_ZONE_ID_RE = re.compile("(" + _ZONE_ID_PAT + r")\]$")
-
-_HOST_PORT_PAT = ("^(%s|%s|%s)(?::0*?(|0|[1-9][0-9]{0,4}))?$") % (
-    _REG_NAME_PAT,
-    _IPV4_PAT,
-    _IPV6_ADDRZ_PAT,
-)
-_HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL)
-
-_UNRESERVED_CHARS = set(
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~"
-)
-_SUB_DELIM_CHARS = set("!$&'()*+,;=")
-_USERINFO_CHARS = _UNRESERVED_CHARS | _SUB_DELIM_CHARS | {":"}
-_PATH_CHARS = _USERINFO_CHARS | {"@", "/"}
-_QUERY_CHARS = _FRAGMENT_CHARS = _PATH_CHARS | {"?"}
-
-
-class Url(
-    typing.NamedTuple(
-        "Url",
-        [
-            ("scheme", typing.Optional[str]),
-            ("auth", typing.Optional[str]),
-            ("host", typing.Optional[str]),
-            ("port", typing.Optional[int]),
-            ("path", typing.Optional[str]),
-            ("query", typing.Optional[str]),
-            ("fragment", typing.Optional[str]),
-        ],
-    )
-):
-    """
-    Data structure for representing an HTTP URL. Used as a return value for
-    :func:`parse_url`. Both the scheme and host are normalized as they are
-    both case-insensitive according to RFC 3986.
-
-    :param auth: User information as defined in RFC 3986 3.2.1. This
-        component is kept percent-encoded. Use :attr:`auth_decoded` or
-        :attr:`auth_decoded_joined` to get the decoded form.
-    """
-
-    def __new__(  # type: ignore[no-untyped-def]
-        cls,
-        scheme: str | None = None,
-        auth: str | None = None,
-        host: str | None = None,
-        port: int | None = None,
-        path: str | None = None,
-        query: str | None = None,
-        fragment: str | None = None,
-    ):
-        if path and not path.startswith("/"):
-            path = "/" + path
-        if scheme is not None:
-            scheme = scheme.lower()
-        return super().__new__(cls, scheme, auth, host, port, path, query, fragment)
-
-    @property
-    def auth_decoded(self) -> tuple[None, None] | tuple[str, str | None]:
-        """
-        User information with %-escapes decoded as UTF-8, returned as a
-        ``(username, password)`` tuple.
-
-        Both values are ``None`` if ``auth`` is ``None``.
-        ``password`` is ``None`` if not present in the auth component.
-        """
-        if self.auth is None:
-            return None, None
-        username, sep, password = self.auth.partition(":")
-        return (
-            _unquote(username, encoding="utf-8"),
-            _unquote(password, encoding="utf-8") if sep else None,
-        )
-
-    @property
-    def auth_decoded_joined(self) -> str | None:
-        """
-        User information with %-escapes decoded as UTF-8, as a string
-        prepared for encoding into an 'authorization: basic ...' header.
-
-        This property does not choose the encoding used for an
-        'authorization: basic ...' header. Use the ``basic_auth_encoding`` or
-        ``proxy_basic_auth_encoding`` parameters of
-        :func:`urllib3.util.make_headers` when converting the returned string
-        into Basic authentication bytes.
-
-        This is a convenience property that joins the username and
-        password with a colon, if both are present.
-        If only the username is present, a trailing colon is still
-        appended.
-        If ``auth`` is ``None``, this returns ``None``.
-        """
-        username, password = self.auth_decoded
-        if username is None:
-            return None
-        return f"{username}:{password or ''}"
-
-    @property
-    def hostname(self) -> str | None:
-        """For backwards-compatibility with urlparse. We're nice like that."""
-        return self.host
-
-    @property
-    def request_uri(self) -> str:
-        """Absolute path including the query string."""
-        uri = self.path or "/"
-
-        if self.query is not None:
-            uri += "?" + self.query
-
-        return uri
-
-    @property
-    def authority(self) -> str | None:
-        """
-        Authority component as defined in RFC 3986 3.2.
-        This includes userinfo (auth), host and port.
-
-        i.e.
-            userinfo@host:port
-        """
-        userinfo = self.auth
-        netloc = self.netloc
-        if netloc is None or userinfo is None:
-            return netloc
-        else:
-            return f"{userinfo}@{netloc}"
-
-    @property
-    def netloc(self) -> str | None:
-        """
-        Network location including host and port.
-
-        If you need the equivalent of urllib.parse's ``netloc``,
-        use the ``authority`` property instead.
-        """
-        if self.host is None:
-            return None
-        if self.port is not None:
-            return f"{self.host}:{self.port}"
-        return self.host
-
-    @property
-    def url(self) -> str:
-        """
-        Convert self into a url
-
-        This function should more or less round-trip with :func:`.parse_url`. The
-        returned url may not be exactly the same as the url inputted to
-        :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls
-        with a blank port will have : removed).
-
-        Example:
-
-        .. code-block:: python
-
-            import urllib3
-
-            U = urllib3.util.parse_url("https://google.com/mail/")
-
-            print(U.url)
-            # "https://google.com/mail/"
-
-            print( urllib3.util.Url("https", "username:password",
-                                    "host.com", 80, "/path", "query", "fragment"
-                                    ).url
-                )
-            # "https://username:password@host.com:80/path?query#fragment"
-        """
-        scheme, auth, host, port, path, query, fragment = self
-        url = ""
-
-        # We use "is not None" we want things to happen with empty strings (or 0 port)
-        if scheme is not None:
-            url += scheme + "://"
-        if auth is not None:
-            url += auth + "@"
-        if host is not None:
-            url += host
-        if port is not None:
-            url += ":" + str(port)
-        if path is not None:
-            url += path
-        if query is not None:
-            url += "?" + query
-        if fragment is not None:
-            url += "#" + fragment
-
-        return url
-
-    def __str__(self) -> str:
-        return self.url
-
-
-@typing.overload
-def _encode_invalid_chars(
-    component: str, allowed_chars: typing.Container[str]
-) -> str:  # Abstract
-    ...
-
-
-@typing.overload
-def _encode_invalid_chars(
-    component: None, allowed_chars: typing.Container[str]
-) -> None:  # Abstract
-    ...
-
-
-def _encode_invalid_chars(
-    component: str | None, allowed_chars: typing.Container[str]
-) -> str | None:
-    """Percent-encodes a URI component without reapplying
-    onto an already percent-encoded component.
-    """
-    if component is None:
-        return component
-
-    component = to_str(component)
-
-    # Fast path: an ASCII component that consists only of allowed characters
-    # and contains no '%' needs neither encoding nor percent-normalization.
-    # Components containing '%' always take the general path below because
-    # how '%' is treated depends on whether the whole component is already
-    # percent-encoded.
-    if (
-        "%" not in component
-        and component.isascii()
-        and all(map(allowed_chars.__contains__, component))
-    ):
-        return component
-
-    # Normalize existing percent-encoded bytes.
-    # Try to see if the component we're encoding is already percent-encoded
-    # so we can skip all '%' characters but still encode all others.
-    component, percent_encodings = _PERCENT_RE.subn(
-        lambda match: match.group(0).upper(), component
-    )
-
-    uri_bytes = component.encode("utf-8", "surrogatepass")
-    is_percent_encoded = percent_encodings == uri_bytes.count(b"%")
-    encoded_component = bytearray()
-
-    # Iterating over bytes yields integers; 0x25 is '%'.
-    for byte_ord in uri_bytes:
-        if (is_percent_encoded and byte_ord == 0x25) or (
-            byte_ord < 128 and chr(byte_ord) in allowed_chars
-        ):
-            encoded_component.append(byte_ord)
-        else:
-            encoded_component += b"%%%02X" % byte_ord
-
-    return encoded_component.decode()
-
-
-def _remove_path_dot_segments(path: str) -> str:
-    # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
-    segments = path.split("/")  # Turn the path into a list of segments
-    output = []  # Initialize the variable to use to store output
-
-    for segment in segments:
-        # '.' is the current directory, so ignore it, it is superfluous
-        if segment == ".":
-            continue
-        # Anything other than '..', should be appended to the output
-        if segment != "..":
-            output.append(segment)
-        # In this case segment == '..', if we can, we should pop the last
-        # element
-        elif output:
-            output.pop()
-
-    # If the path starts with '/' and the output is empty or the first string
-    # is non-empty
-    if path.startswith("/") and (not output or output[0]):
-        output.insert(0, "")
-
-    # If the path starts with '/.' or '/..' ensure we add one more empty
-    # string to add a trailing '/'
-    if path.endswith(("/.", "/..")):
-        output.append("")
-
-    return "/".join(output)
-
-
-@typing.overload
-def _normalize_host(host: None, scheme: str | None) -> None: ...
-
-
-@typing.overload
-def _normalize_host(host: str, scheme: str | None) -> str: ...
-
-
-def _normalize_host(host: str | None, scheme: str | None) -> str | None:
-    if host:
-        invalid_host_char = _HOST_INVALID_CHAR_RE.search(host)
-        if invalid_host_char:
-            raise LocationParseError(
-                f"Host {host!r} contains invalid character "
-                f"{invalid_host_char.group()!r}"
-            )
-        if scheme in _NORMALIZABLE_SCHEMES:
-            is_ipv6 = _IPV6_ADDRZ_RE.match(host)
-            if is_ipv6:
-                # IPv6 hosts of the form 'a::b%zone' are encoded in a URL as
-                # such per RFC 6874: 'a::b%25zone'. Unquote the ZoneID
-                # separator as necessary to return a valid RFC 4007 scoped IP.
-                match = _ZONE_ID_RE.search(host)
-                if match:
-                    start, end = match.span(1)
-                    zone_id = host[start:end]
-
-                    if zone_id.startswith("%25") and zone_id != "%25":
-                        zone_id = zone_id[3:]
-                    else:
-                        zone_id = zone_id[1:]
-                    zone_id = _PERCENT_RE.sub(
-                        partial(_normalize_zone_id_percent_encoding, error_host=host),
-                        zone_id,
-                    )
-                    zone_id = _encode_invalid_chars(zone_id, _UNRESERVED_CHARS)
-                    return f"{host[:start].lower()}%{zone_id}{host[end:]}"
-                else:
-                    return host.lower()
-            elif not _IPV4_RE.match(host):
-                if "%" in host:
-                    host = _HOST_PERCENT_RE.sub(_normalize_host_percent_encoding, host)
-                return to_str(
-                    b".".join([_idna_encode(label) for label in host.split(".")]),
-                    "ascii",
-                )
-    return host
-
-
-def _decode_percent_encoding(match: re.Match[str], *, error_host: str) -> str:
-    percent_encoded_octet = match.group(0)
-    decoded_octet = chr(int(percent_encoded_octet[1:], 16))
-    # Keep this narrower than _HOST_INVALID_CHAR_RE because "%20" is valid
-    # percent-encoding and remains encoded.
-    if decoded_octet < "\x20" or decoded_octet == "\x7f":
-        raise LocationParseError(
-            f"Host {error_host!r} contains invalid percent-encoded "
-            f"control character {percent_encoded_octet!r}"
-        )
-    return decoded_octet
-
-
-def _normalize_host_percent_encoding(match: re.Match[str]) -> str:
-    # Reject invalid percent encodings
-    if match.group(0) == "%":
-        raise LocationParseError(f"{match.string!r} is not a valid host")
-    decoded_octet = _decode_percent_encoding(match, error_host=match.string)
-    if decoded_octet in _UNRESERVED_CHARS:
-        return decoded_octet
-    return match.group(0).upper()
-
-
-def _normalize_zone_id_percent_encoding(
-    match: re.Match[str], *, error_host: str
-) -> str:
-    _decode_percent_encoding(match, error_host=error_host)
-    return match.group(0).upper()
-
-
-def _idna_encode(name: str) -> bytes:
-    if not name.isascii():
-        try:
-            from opentelemetry.agent._vendor import idna
-        except ImportError:
-            raise LocationParseError(
-                "Unable to parse URL without the 'idna' module"
-            ) from None
-
-        try:
-            return idna.encode(name.lower(), strict=True, std3_rules=True)
-        except idna.IDNAError:
-            raise LocationParseError(
-                f"Name '{name}' is not a valid IDNA label"
-            ) from None
-
-    return _PERCENT_RE.sub(lambda match: match.group(0).upper(), name.lower()).encode(
-        "ascii"
-    )
-
-
-def _encode_target(target: str) -> str:
-    """Percent-encodes a request target so that there are no invalid characters
-
-    Pre-condition for this function is that 'target' must start with '/'.
-    If that is the case then _TARGET_RE will always produce a match.
-    """
-    match = _TARGET_RE.match(target)
-    if not match:  # Defensive:
-        raise LocationParseError(f"{target!r} is not a valid request URI")
-
-    path, query = match.groups()
-    encoded_target = _encode_invalid_chars(path, _PATH_CHARS)
-    if query is not None:
-        query = _encode_invalid_chars(query, _QUERY_CHARS)
-        encoded_target += "?" + query
-    return encoded_target
-
-
-def parse_url(url: str) -> Url:
-    """
-    Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
-    performed to parse incomplete urls. Fields not provided will be None.
-    This parser is RFC 3986 and RFC 6874 compliant.
-
-    The parser logic and helper functions are based heavily on
-    work done in the ``rfc3986`` module.
-
-    :param str url: URL to parse into a :class:`.Url` namedtuple.
-
-    Partly backwards-compatible with :mod:`urllib.parse`.
-
-    Example:
-
-    .. code-block:: python
-
-        import urllib3
-
-        print( urllib3.util.parse_url('http://google.com/mail/'))
-        # Url(scheme='http', host='google.com', port=None, path='/mail/', ...)
-
-        print( urllib3.util.parse_url('google.com:80'))
-        # Url(scheme=None, host='google.com', port=80, path=None, ...)
-
-        print( urllib3.util.parse_url('/foo?bar'))
-        # Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
-    """
-    if not url:
-        # Empty
-        return Url()
-
-    if not _SCHEME_RE.search(url):
-        url = "//" + url
-
-    scheme: str | None
-    authority: str | None
-    auth: str | None
-    host: str | None
-    port: str | None
-    port_int: int | None
-    path: str | None
-    query: str | None
-    fragment: str | None
-
-    scheme, authority, path, query, fragment = _URI_RE.match(url).groups()  # type: ignore[union-attr]
-    normalize_uri = scheme is None or scheme.lower() in _NORMALIZABLE_SCHEMES
-
-    if scheme:
-        scheme = scheme.lower()
-
-    if authority:
-        auth, _, host_port = authority.rpartition("@")
-        auth = auth or None
-        host_port_match = _HOST_PORT_RE.fullmatch(host_port)
-        if not host_port_match:
-            invalid_host_char = _HOST_INVALID_CHAR_RE.search(host_port)
-            if invalid_host_char:
-                raise LocationParseError(
-                    f"Host {host_port!r} contains invalid character "
-                    f"{invalid_host_char.group()!r}"
-                )
-            raise LocationParseError(f"{host_port!r} is not a valid host or port")
-        host, port = host_port_match.groups()
-        if auth and normalize_uri:
-            auth = _encode_invalid_chars(auth, _USERINFO_CHARS)
-        if port == "":
-            port = None
-    else:
-        auth, host, port = None, None, None
-
-    if port is not None:
-        port_int = int(port)
-        if not (0 <= port_int <= 65535):
-            raise LocationParseError(url)
-    else:
-        port_int = None
-
-    host = _normalize_host(host, scheme)
-
-    if normalize_uri and path:
-        path = _remove_path_dot_segments(path)
-        path = _encode_invalid_chars(path, _PATH_CHARS)
-    if normalize_uri and query:
-        query = _encode_invalid_chars(query, _QUERY_CHARS)
-    if normalize_uri and fragment:
-        fragment = _encode_invalid_chars(fragment, _FRAGMENT_CHARS)
-
-    # For the sake of backwards compatibility we put empty
-    # string values for path if there are any defined values
-    # beyond the path in the URL.
-    # TODO: Remove this when we break backwards compatibility.
-    if not path:
-        if query is not None or fragment is not None:
-            path = ""
-        else:
-            path = None
-
-    return Url(
-        scheme=scheme,
-        auth=auth,
-        host=host,
-        port=port_int,
-        path=path,
-        query=query,
-        fragment=fragment,
-    )
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py
deleted file mode 100644
index 35c77e40258..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/util.py
+++ /dev/null
@@ -1,42 +0,0 @@
-from __future__ import annotations
-
-import typing
-from types import TracebackType
-
-
-def to_bytes(
-    x: str | bytes, encoding: str | None = None, errors: str | None = None
-) -> bytes:
-    if isinstance(x, bytes):
-        return x
-    elif not isinstance(x, str):
-        raise TypeError(f"not expecting type {type(x).__name__}")
-    if encoding or errors:
-        return x.encode(encoding or "utf-8", errors=errors or "strict")
-    return x.encode()
-
-
-def to_str(
-    x: str | bytes, encoding: str | None = None, errors: str | None = None
-) -> str:
-    if isinstance(x, str):
-        return x
-    elif not isinstance(x, bytes):
-        raise TypeError(f"not expecting type {type(x).__name__}")
-    if encoding or errors:
-        return x.decode(encoding or "utf-8", errors=errors or "strict")
-    return x.decode()
-
-
-def reraise(
-    tp: type[BaseException] | None,
-    value: BaseException,
-    tb: TracebackType | None = None,
-) -> typing.NoReturn:
-    try:
-        if value.__traceback__ is not tb:
-            raise value.with_traceback(tb)
-        raise value
-    finally:
-        value = None  # type: ignore[assignment]
-        tb = None
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py
deleted file mode 100644
index aeca0c7ad5b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/urllib3/util/wait.py
+++ /dev/null
@@ -1,124 +0,0 @@
-from __future__ import annotations
-
-import select
-import socket
-from functools import partial
-
-__all__ = ["wait_for_read", "wait_for_write"]
-
-
-# How should we wait on sockets?
-#
-# There are two types of APIs you can use for waiting on sockets: the fancy
-# modern stateful APIs like epoll/kqueue, and the older stateless APIs like
-# select/poll. The stateful APIs are more efficient when you have a lots of
-# sockets to keep track of, because you can set them up once and then use them
-# lots of times. But we only ever want to wait on a single socket at a time
-# and don't want to keep track of state, so the stateless APIs are actually
-# more efficient. So we want to use select() or poll().
-#
-# Now, how do we choose between select() and poll()? On traditional Unixes,
-# select() has a strange calling convention that makes it slow, or fail
-# altogether, for high-numbered file descriptors. The point of poll() is to fix
-# that, so on Unixes, we prefer poll().
-#
-# On Windows, there is no poll() (or at least Python doesn't provide a wrapper
-# for it), but that's OK, because on Windows, select() doesn't have this
-# strange calling convention; plain select() works fine.
-#
-# So: on Windows we use select(), and everywhere else we use poll(). We also
-# fall back to select() in case poll() is somehow broken or missing.
-
-
-def select_wait_for_socket(
-    sock: socket.socket,
-    read: bool = False,
-    write: bool = False,
-    timeout: float | None = None,
-) -> bool:
-    if not read and not write:
-        raise RuntimeError("must specify at least one of read=True, write=True")
-    rcheck = []
-    wcheck = []
-    if read:
-        rcheck.append(sock)
-    if write:
-        wcheck.append(sock)
-    # When doing a non-blocking connect, most systems signal success by
-    # marking the socket writable. Windows, though, signals success by marked
-    # it as "exceptional". We paper over the difference by checking the write
-    # sockets for both conditions. (The stdlib selectors module does the same
-    # thing.)
-    fn = partial(select.select, rcheck, wcheck, wcheck)
-    rready, wready, xready = fn(timeout)
-    return bool(rready or wready or xready)
-
-
-def poll_wait_for_socket(
-    sock: socket.socket,
-    read: bool = False,
-    write: bool = False,
-    timeout: float | None = None,
-) -> bool:
-    if not read and not write:
-        raise RuntimeError("must specify at least one of read=True, write=True")
-    mask = 0
-    if read:
-        mask |= select.POLLIN
-    if write:
-        mask |= select.POLLOUT
-    poll_obj = select.poll()
-    poll_obj.register(sock, mask)
-
-    # For some reason, poll() takes timeout in milliseconds
-    def do_poll(t: float | None) -> list[tuple[int, int]]:
-        if t is not None:
-            t *= 1000
-        return poll_obj.poll(t)
-
-    return bool(do_poll(timeout))
-
-
-def _have_working_poll() -> bool:
-    # Apparently some systems have a select.poll that fails as soon as you try
-    # to use it, either due to strange configuration or broken monkeypatching
-    # from libraries like eventlet/greenlet.
-    try:
-        poll_obj = select.poll()
-        poll_obj.poll(0)
-    except (AttributeError, OSError):
-        return False
-    else:
-        return True
-
-
-def wait_for_socket(
-    sock: socket.socket,
-    read: bool = False,
-    write: bool = False,
-    timeout: float | None = None,
-) -> bool:
-    # We delay choosing which implementation to use until the first time we're
-    # called. We could do it at import time, but then we might make the wrong
-    # decision if someone goes wild with monkeypatching select.poll after
-    # we're imported.
-    global wait_for_socket
-    if _have_working_poll():
-        wait_for_socket = poll_wait_for_socket
-    elif hasattr(select, "select"):
-        wait_for_socket = select_wait_for_socket
-    return wait_for_socket(sock, read, write, timeout)
-
-
-def wait_for_read(sock: socket.socket, timeout: float | None = None) -> bool:
-    """Waits for reading to be available on a given socket.
-    Returns True if the socket is readable, or False if the timeout expired.
-    """
-    return wait_for_socket(sock, read=True, timeout=timeout)
-
-
-def wait_for_write(sock: socket.socket, timeout: float | None = None) -> bool:
-    """Waits for writing to be available on a given socket.
-    Returns True if the socket is readable, or False if the timeout expired.
-    """
-    return wait_for_socket(sock, write=True, timeout=timeout)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi
deleted file mode 100644
index 75febda8309..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt-stubs/__init__.pyi
+++ /dev/null
@@ -1,841 +0,0 @@
-import sys
-
-if sys.version_info >= (3, 10):
-    from contextlib import AbstractContextManager
-    from inspect import FullArgSpec, Signature
-    from types import GenericAlias, ModuleType, TracebackType
-    from typing import (
-        Any,
-        AsyncIterator,
-        Callable,
-        Concatenate,
-        Final,
-        Generator,
-        Generic,
-        Iterator,
-        ParamSpec,
-        Protocol,
-        TypeVar,
-        final,
-        overload,
-    )
-
-    # Self is only in typing from Python 3.11 and the stubs support 3.10.
-    from typing_extensions import Self
-
-    # Mirrors wrapt.__all__ at runtime (src/wrapt/__init__.py). Anything not
-    # listed here is a private stub-internal helper (TypeVar, Protocol,
-    # type alias) and is prefixed with a leading underscore.
-    __all__ = (
-        "AutoObjectProxy",
-        "BaseObjectProxy",
-        "BoundFunctionWrapper",
-        "CallableObjectProxy",
-        "FunctionWrapper",
-        "LazyObjectProxy",
-        "ObjectProxy",
-        "PartialCallableObjectProxy",
-        "PathResolutionError",
-        "TargetModuleNotFoundError",
-        "WrapperChainTooDeepError",
-        "WrapperNotFoundError",
-        "WrapperNotInitializedError",
-        "WrapperNotOutermostError",
-        "partial",
-        "AdapterFactory",
-        "adapter_factory",
-        "bind_state_to_wrapper",
-        "async_to_sync",
-        "decorator",
-        "lru_cache",
-        "mark_as_async",
-        "mark_as_sync",
-        "sync_to_async",
-        "synchronized",
-        "with_doc",
-        "with_signature",
-        "discover_post_import_hooks",
-        "notify_module_loaded",
-        "register_post_import_hook",
-        "when_imported",
-        "MISSING",
-        "AttributeWrapper",
-        "apply_patch",
-        "find_wrapper",
-        "function_wrapper",
-        "is_wrapped_by",
-        "lazy_import",
-        "patch_function_wrapper",
-        "resolve_owner",
-        "resolve_path",
-        "scoped_function_wrapper",
-        "transient_function_wrapper",
-        "unwrap_object",
-        "unwrapped",
-        "wrap_function_wrapper",
-        "wrap_object",
-        "wrap_object_attribute",
-        "wrapper_chain",
-        "WeakFunctionProxy",
-    )
-
-    _P = ParamSpec("_P")
-    _R = TypeVar("_R", covariant=True)
-
-    _T = TypeVar("_T", bound=Any)
-
-    # Need two sets of ParamSpec/TypeVar for generics in some cases to ensure
-    # that mypy, pyrefly and ty all work correctly. More specifically need a
-    # separate set for cases where extracting the type or instance from the
-    # first argument of a callable where binding is involved.
-
-    _P1 = ParamSpec("_P1")
-    _R1 = TypeVar("_R1", covariant=True)
-
-    _T1 = TypeVar("_T1", bound=Any)
-
-    _P2 = ParamSpec("_P2")
-    _R2 = TypeVar("_R2", covariant=True)
-
-    _T2 = TypeVar("_T2", bound=Any)
-
-    class _Boolean(Protocol):
-        def __bool__(self) -> bool: ...
-
-    # ObjectProxy
-    #
-    # BaseObjectProxy mirrors the dunder surface of the runtime class
-    # (wrappers.ObjectProxy / _wrappers.ObjectProxy). Every protocol/operator
-    # dunder that the runtime defines unconditionally is declared here so
-    # static type checkers accept `len(proxy)`, `with proxy: ...`,
-    # `proxy + x`, etc. without complaint. Dunders that the runtime only
-    # attaches dynamically per wrapped object (__iter__ lives on
-    # ObjectProxy for backward compatibility; __next__, __aiter__,
-    # __anext__, __await__ and __length_hint__ are added per-instance by
-    # AutoObjectProxy based on the wrapped interface) are intentionally
-    # NOT claimed statically on BaseObjectProxy.
-    #
-    # `__enter__`/`__aenter__` return `Any` because the runtime forwards to
-    # the wrapped object's `__enter__`, which may return a value of any type
-    # (for example, `threading.Lock.__enter__` returns `bool`, not the lock
-    # itself). Returning `_T` would be a false claim that the value bound by
-    # `with proxy as x` is the wrapped type, which is only sometimes true.
-    # Other operator dunders return `Any` for the same reason: the result
-    # depends on the wrapped type.
-
-    class BaseObjectProxy(Generic[_T]):
-        __wrapped__: _T
-
-        __name__: str
-        __qualname__: str
-
-        # __new__ accepts and ignores any arguments, so a subclass may add
-        # arguments to __init__ or pass its own arguments through from an
-        # overridden __new__. Returns Self so such an override type checks.
-        def __new__(cls, *args: Any, **kwargs: Any) -> Self: ...
-        def __init__(self, wrapped: _T) -> None: ...
-        def __getattr__(self, name: str) -> Any: ...
-        def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
-        def __mro_entries__(self, bases: tuple[type, ...]) -> tuple[type, ...]: ...
-
-        # Context managers.
-        def __enter__(self) -> Any: ...
-        def __exit__(
-            self,
-            exc_type: type[BaseException] | None,
-            exc_value: BaseException | None,
-            traceback: TracebackType | None,
-        ) -> bool | None: ...
-        async def __aenter__(self) -> Any: ...
-        async def __aexit__(
-            self,
-            exc_type: type[BaseException] | None,
-            exc_value: BaseException | None,
-            traceback: TracebackType | None,
-        ) -> bool | None: ...
-
-        # Container protocol.
-        def __len__(self) -> int: ...
-        def __contains__(self, key: object, /) -> bool: ...
-        def __getitem__(self, key: Any, /) -> Any: ...
-        def __setitem__(self, key: Any, value: Any, /) -> None: ...
-        def __delitem__(self, key: Any, /) -> None: ...
-        def __reversed__(self) -> Iterator[Any]: ...
-
-        # Rich comparisons.
-        def __lt__(self, other: object, /) -> bool: ...
-        def __le__(self, other: object, /) -> bool: ...
-        def __gt__(self, other: object, /) -> bool: ...
-        def __ge__(self, other: object, /) -> bool: ...
-
-        # Numeric conversions.
-        def __bool__(self) -> bool: ...
-        def __int__(self) -> int: ...
-        def __float__(self) -> float: ...
-        def __complex__(self) -> complex: ...
-        def __bytes__(self) -> bytes: ...
-        def __index__(self) -> int: ...
-        def __round__(self, ndigits: int | None = ..., /) -> Any: ...
-        def __trunc__(self) -> Any: ...
-        def __floor__(self) -> Any: ...
-        def __ceil__(self) -> Any: ...
-
-        # Unary arithmetic.
-        def __neg__(self) -> Any: ...
-        def __pos__(self) -> Any: ...
-        def __abs__(self) -> Any: ...
-        def __invert__(self) -> Any: ...
-
-        # Binary arithmetic.
-        def __add__(self, other: Any, /) -> Any: ...
-        def __sub__(self, other: Any, /) -> Any: ...
-        def __mul__(self, other: Any, /) -> Any: ...
-        def __matmul__(self, other: Any, /) -> Any: ...
-        def __truediv__(self, other: Any, /) -> Any: ...
-        def __floordiv__(self, other: Any, /) -> Any: ...
-        def __mod__(self, other: Any, /) -> Any: ...
-        def __divmod__(self, other: Any, /) -> Any: ...
-        def __pow__(self, other: Any, modulo: Any = ..., /) -> Any: ...
-        def __lshift__(self, other: Any, /) -> Any: ...
-        def __rshift__(self, other: Any, /) -> Any: ...
-        def __and__(self, other: Any, /) -> Any: ...
-        def __or__(self, other: Any, /) -> Any: ...
-        def __xor__(self, other: Any, /) -> Any: ...
-
-        # Reflected binary arithmetic.
-        def __radd__(self, other: Any, /) -> Any: ...
-        def __rsub__(self, other: Any, /) -> Any: ...
-        def __rmul__(self, other: Any, /) -> Any: ...
-        def __rmatmul__(self, other: Any, /) -> Any: ...
-        def __rtruediv__(self, other: Any, /) -> Any: ...
-        def __rfloordiv__(self, other: Any, /) -> Any: ...
-        def __rmod__(self, other: Any, /) -> Any: ...
-        def __rdivmod__(self, other: Any, /) -> Any: ...
-        def __rpow__(self, other: Any, modulo: Any = ..., /) -> Any: ...
-        def __rlshift__(self, other: Any, /) -> Any: ...
-        def __rrshift__(self, other: Any, /) -> Any: ...
-        def __rand__(self, other: Any, /) -> Any: ...
-        def __ror__(self, other: Any, /) -> Any: ...
-        def __rxor__(self, other: Any, /) -> Any: ...
-
-        # In-place arithmetic.
-        def __iadd__(self, other: Any, /) -> Any: ...
-        def __isub__(self, other: Any, /) -> Any: ...
-        def __imul__(self, other: Any, /) -> Any: ...
-        def __imatmul__(self, other: Any, /) -> Any: ...
-        def __itruediv__(self, other: Any, /) -> Any: ...
-        def __ifloordiv__(self, other: Any, /) -> Any: ...
-        def __imod__(self, other: Any, /) -> Any: ...
-        def __ipow__(self, other: Any, /) -> Any: ...  # type: ignore[misc]
-        def __ilshift__(self, other: Any, /) -> Any: ...
-        def __irshift__(self, other: Any, /) -> Any: ...
-        def __iand__(self, other: Any, /) -> Any: ...
-        def __ior__(self, other: Any, /) -> Any: ...
-        def __ixor__(self, other: Any, /) -> Any: ...
-
-        # Copy / pickle.
-        def __copy__(self) -> Any: ...
-        def __deepcopy__(self, memo: dict[int, Any], /) -> Any: ...
-        def __reduce__(self) -> Any: ...
-
-        # wrapt-specific escape hatches (not Python-language dunders despite
-        # the dunder-shaped names). Ordinary attribute access, __setattr__
-        # and arithmetic operations all forward to the wrapped object; these
-        # hooks let subclasses and wrapt-aware callers reach around the
-        # forwarding layer when they need to.
-        #
-        # __self_dict__: the proxy's own instance dict (since __dict__ is
-        # overridden to delegate to the wrapped object).
-        #
-        # __self_setattr__: set an attribute directly on the proxy, bypassing
-        # the forwarding __setattr__. Used for stashing state onto a wrapper.
-        #
-        # __object_proxy__: the class used to re-wrap results of arithmetic
-        # and bitwise operations (e.g. __add__ returns
-        # ``self.__object_proxy__(self.__wrapped__ + other)``). Subclasses
-        # override it to control the type of proxy produced from operations.
-        @property
-        def __self_dict__(self) -> dict[str, Any]: ...
-        @property
-        def __object_proxy__(self) -> type[BaseObjectProxy[Any]]: ...
-        def __self_setattr__(self, name: str, value: Any) -> None: ...
-
-    class ObjectProxy(BaseObjectProxy[_T]):
-        def __init__(self, wrapped: _T) -> None: ...
-        def __iter__(self) -> Iterator[Any]: ...
-
-    class AutoObjectProxy(BaseObjectProxy[_T]):
-        # AutoObjectProxy attaches the dunders below to a per-instance
-        # subclass at construction time, based on what the wrapped object
-        # exposes (see proxies.AutoObjectProxy.__new__). We statically
-        # claim all of them here so type checkers accept code that uses
-        # them -- AutoObjectProxy's contract is "take on the interface
-        # of the wrapped object", so the stub reflects that intent at
-        # the cost of being permissive for proxies whose wrapped value
-        # doesn't actually support a given dunder (a runtime
-        # AttributeError, which mirrors the wrapt design).
-
-        def __new__(cls, wrapped: _T, *args: Any, **kwargs: Any) -> Self: ...
-        def __init__(self, wrapped: _T) -> None: ...
-
-        # Hook called by BaseObjectProxy.__setattr__ whenever __wrapped__
-        # is reassigned. AutoObjectProxy's implementation re-wires the
-        # interface-conditional dunders below to match the new wrapped
-        # object; subclasses may override it to run additional fixup logic
-        # when the wrapped object changes.
-        def __wrapped_setattr_fixups__(self) -> None: ...
-        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
-        def __iter__(self) -> Iterator[Any]: ...
-        def __next__(self) -> Any: ...
-        def __aiter__(self) -> AsyncIterator[Any]: ...
-        async def __anext__(self) -> Any: ...
-        def __length_hint__(self) -> int: ...
-        def __fspath__(self) -> str | bytes: ...
-        def __await__(self) -> Generator[Any, Any, Any]: ...
-
-    # LazyObjectProxy
-
-    class LazyObjectProxy(AutoObjectProxy[_T]):
-        def __new__(
-            cls,
-            callback: Callable[[], _T] | None = None,
-            *args: Any,
-            interface: Any = ...,
-            **kwargs: Any,
-        ) -> Self: ...
-        def __init__(
-            self,
-            callback: Callable[[], _T] | None = None,
-            *,
-            interface: Any = ...,
-        ) -> None: ...
-
-    @overload
-    def lazy_import(name: str) -> LazyObjectProxy[ModuleType]: ...
-    @overload
-    def lazy_import(
-        name: str, attribute: str, *, interface: Any = ...
-    ) -> LazyObjectProxy[Any]: ...
-
-    # CallableObjectProxy
-
-    class CallableObjectProxy(BaseObjectProxy[_T]):
-        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
-
-    # PartialCallableObjectProxy
-
-    class PartialCallableObjectProxy(BaseObjectProxy[Callable[..., Any]]):
-        _self_args: tuple[Any, ...]
-        _self_kwargs: dict[str, Any]
-        @property
-        def __signature__(self) -> Signature: ...
-        def __init__(
-            self, func: Callable[..., Any], *args: Any, **kwargs: Any
-        ) -> None: ...
-        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
-
-    def partial(
-        func: Callable[..., Any], /, *args: Any, **kwargs: Any
-    ) -> Callable[..., Any]: ...
-
-    # WeakFunctionProxy
-
-    class WeakFunctionProxy(BaseObjectProxy[Callable[..., Any]]):
-        def __init__(
-            self,
-            wrapped: Callable[..., Any],
-            callback: Callable[..., Any] | None = None,
-        ) -> None: ...
-        def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
-
-    # FunctionWrapper
-
-    _WrappedFunction = Callable[_P, _R]
-
-    _GenericCallableWrapperFunction = Callable[
-        [_WrappedFunction[_P, _R], Any, tuple[Any, ...], dict[str, Any]], _R
-    ]
-
-    _ClassMethodWrapperFunction = Callable[
-        [type[Any], _WrappedFunction[_P, _R], Any, tuple[Any, ...], dict[str, Any]], _R
-    ]
-
-    _InstanceMethodWrapperFunction = Callable[
-        [Any, _WrappedFunction[_P, _R], Any, tuple[Any, ...], dict[str, Any]], _R
-    ]
-
-    _WrapperFunction = (
-        _GenericCallableWrapperFunction[_P, _R]
-        | _ClassMethodWrapperFunction[_P, _R]
-        | _InstanceMethodWrapperFunction[_P, _R]
-    )
-
-    class _FunctionWrapperBase(BaseObjectProxy[_WrappedFunction[_P, _R]]):
-        _self_instance: Any
-        _self_wrapper: _WrapperFunction[_P, _R]
-        _self_enabled: bool | _Boolean | Callable[[], bool] | None
-        _self_binding: str
-        _self_parent: Any
-        _self_owner: Any
-
-    class BoundFunctionWrapper(_FunctionWrapperBase[_P1, _R1]):
-        def __call__(self, *args: _P1.args, **kwargs: _P1.kwargs) -> _R1: ...
-
-        # Note that for following overloads, testing with mypy and ty they still do
-        # not handle static methods being decorated but to best knowledge this is
-        # a limitation in those type checkers. Testing with pyrefly fails on any
-        # type of bound method. Testing with pyright handles case correctly.
-        #
-        # Also, note that use of _T2, _P2 and _R2 in first two cases is also required
-        # to ensure correct handling by mypy and ty, so do not change to use of _T1,
-        # _P1 and _R1.
-
-        @overload
-        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
-            self: BoundFunctionWrapper[Concatenate[_T2, _P2], _R2],
-            instance: _T2,
-            owner: type[_T2] | None = None,
-            /,
-        ) -> BoundFunctionWrapper[_P2, _R2]: ...
-        @overload
-        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
-            self: BoundFunctionWrapper[Concatenate[_T2, _P2], _R2],
-            instance: _T2,
-            owner: type[Any] | None = None,
-            /,
-        ) -> BoundFunctionWrapper[_P2, _R2]: ...
-        @overload
-        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
-            self, instance: None, owner: type[_T1] | None = None, /
-        ) -> BoundFunctionWrapper[_P1, _R1]: ...
-        @overload
-        def __get__(  # Required to ensure pyright works correctly
-            self, instance: _T1, owner: type[_T1] | None = None, /
-        ) -> BoundFunctionWrapper[_P1, _R1]: ...
-
-    class FunctionWrapper(_FunctionWrapperBase[_P1, _R1]):
-        # The class used to construct the bound wrapper when the function
-        # wrapper is bound to an instance via the descriptor protocol.
-        # Subclasses override it to control the type of bound wrapper
-        # produced.
-        __bound_function_wrapper__: type[BoundFunctionWrapper[_P1, _R1]]
-
-        def __init__(
-            self,
-            wrapped: _WrappedFunction[_P1, _R1],
-            wrapper: _WrapperFunction[_P1, _R1],
-            enabled: bool | _Boolean | Callable[[], bool] | None = None,
-        ) -> None: ...
-        def __call__(self, *args: _P1.args, **kwargs: _P1.kwargs) -> _R1: ...
-
-        # Note that for following overloads, testing with mypy and ty they still do
-        # not handle static methods being decorated but to best knowledge this is
-        # a limitation in those type checkers. Testing with pyrefly fails on any
-        # type of bound method. Testing with pyright handles case correctly.
-        #
-        # Also, note that use of _T2, _P2 and _R2 in first two cases is also required
-        # to ensure correct handling by mypy and ty, so do not change to use of _T1,
-        # _P1 and _R1.
-
-        @overload
-        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
-            self: FunctionWrapper[Concatenate[_T2, _P2], _R2],
-            instance: _T2,
-            owner: type[Any] | None = None,
-            /,
-        ) -> BoundFunctionWrapper[_P2, _R2]: ...
-        @overload
-        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
-            self: FunctionWrapper[Concatenate[_T2, _P2], _R2],
-            instance: _T2,
-            owner: type[_T2] | None = None,
-            /,
-        ) -> BoundFunctionWrapper[_P2, _R2]: ...
-        @overload
-        def __get__(  # Required to ensure mypy, pyrefly and ty works correctly
-            self, instance: None, owner: type[_T1] | None = None, /
-        ) -> BoundFunctionWrapper[_P1, _R1]: ...
-        @overload
-        def __get__(  # Required to ensure pyright works correctly
-            self, instance: _T1, owner: type[_T1] | None = None, /
-        ) -> BoundFunctionWrapper[_P1, _R1]: ...
-
-    # AdapterFactory/adapter_factory()
-
-    class AdapterFactory:
-        def __call__(
-            self, wrapped: Callable[..., Any]
-        ) -> str | FullArgSpec | Callable[..., Any]: ...
-
-    class _DelegatedAdapterFactory(AdapterFactory):
-        def __init__(self, factory: Callable[..., Any]) -> None: ...
-
-    adapter_factory = _DelegatedAdapterFactory
-
-    # decorator()
-
-    class _Descriptor(Protocol):
-        def __get__(self, instance: Any, owner: type[Any] | None = None) -> Any: ...
-
-    class _FunctionDecorator:
-        @overload
-        def __call__(
-            self,
-            callable: (
-                Callable[_P, _R]
-                | Callable[Concatenate[type[_T], _P], _R]  # Required for pylance
-                # | Callable[Concatenate[Any, _P], _R]  # Breaks mypy, pyrefly and ty
-                | Callable[[type[_T]], _R]  # Required for pylance
-            ),
-        ) -> FunctionWrapper[_P, _R]: ...
-        @overload
-        def __call__(self, callable: _Descriptor) -> FunctionWrapper[_P, Any]: ...
-
-    class _PartialFunctionDecorator:
-        @overload
-        def __call__(
-            self, wrapper: _GenericCallableWrapperFunction[_P, _R], /
-        ) -> _FunctionDecorator: ...
-        @overload
-        def __call__(
-            self, wrapper: _ClassMethodWrapperFunction[_P, _R], /
-        ) -> _FunctionDecorator: ...
-        @overload
-        def __call__(
-            self, wrapper: _InstanceMethodWrapperFunction[_P, _R], /
-        ) -> _FunctionDecorator: ...
-
-    # ... Decorator applied to class type.
-
-    @overload
-    def decorator(wrapper: type[_T], /) -> _FunctionDecorator: ...
-
-    # ... Decorator applied to function or method.
-
-    @overload
-    def decorator(
-        wrapper: _GenericCallableWrapperFunction[_P, _R], /
-    ) -> _FunctionDecorator: ...
-    @overload
-    def decorator(
-        wrapper: _ClassMethodWrapperFunction[_P, _R], /
-    ) -> _FunctionDecorator: ...
-    @overload
-    def decorator(
-        wrapper: _InstanceMethodWrapperFunction[_P, _R], /
-    ) -> _FunctionDecorator: ...
-
-    # ... Positional arguments.
-
-    @overload
-    def decorator(
-        *,
-        enabled: bool | _Boolean | Callable[[], bool] | None = None,
-        adapter: str | FullArgSpec | AdapterFactory | Callable[..., Any] | None = None,
-        proxy: type[FunctionWrapper[Any, Any]] | None = None,
-    ) -> _PartialFunctionDecorator: ...
-
-    # function_wrapper()
-
-    @overload
-    def function_wrapper(wrapper: type[Any]) -> _FunctionDecorator: ...
-    @overload
-    def function_wrapper(
-        wrapper: _GenericCallableWrapperFunction[_P, _R],
-    ) -> _FunctionDecorator: ...
-    @overload
-    def function_wrapper(
-        wrapper: _ClassMethodWrapperFunction[_P, _R],
-    ) -> _FunctionDecorator: ...
-    @overload
-    def function_wrapper(
-        wrapper: _InstanceMethodWrapperFunction[_P, _R],
-    ) -> _FunctionDecorator: ...
-    # @overload
-    # def function_wrapper(wrapper: Any) -> _FunctionDecorator: ... # Don't use, breaks stuff.
-
-    # wrap_function_wrapper()
-
-    def wrap_function_wrapper(
-        target: ModuleType | type[Any] | Any | str,
-        name: str,
-        wrapper: _WrapperFunction[_P, _R],
-    ) -> FunctionWrapper[_P, _R]: ...
-
-    # patch_function_wrapper()
-
-    class _WrapperDecorator:
-        def __call__(
-            self, wrapper: _WrapperFunction[_P, _R]
-        ) -> FunctionWrapper[_P, _R]: ...
-
-    def patch_function_wrapper(
-        target: ModuleType | type[Any] | Any | str,
-        name: str,
-        *,
-        enabled: bool | _Boolean | Callable[[], bool] | None | _MissingType = ...,
-    ) -> _WrapperDecorator: ...
-
-    # transient_function_wrapper()
-
-    class _TransientDecorator:
-        def __call__(self, wrapper: _WrapperFunction[_P, _R]) -> _FunctionDecorator: ...
-
-    def transient_function_wrapper(
-        target: ModuleType | type[Any] | Any | str, name: str
-    ) -> _TransientDecorator: ...
-
-    # scoped_function_wrapper()
-
-    def scoped_function_wrapper(
-        target: ModuleType | type[Any] | Any | str,
-        name: str,
-        wrapper: _WrapperFunction[_P, _R],
-    ) -> AbstractContextManager[None]: ...
-
-    # Exceptions.
-
-    class WrapperNotInitializedError(ValueError): ...
-
-    class PathResolutionError(AttributeError): ...
-
-    class TargetModuleNotFoundError(ModuleNotFoundError): ...
-
-    class WrapperChainTooDeepError(RuntimeError): ...
-
-    class WrapperNotFoundError(ValueError): ...
-
-    class WrapperNotOutermostError(ValueError): ...
-
-    # MISSING sentinel. The class stays private, matching the runtime
-    # (the dataclasses.MISSING/_MISSING_TYPE arrangement): signatures
-    # reference _MissingType while callers only ever write wrapt.MISSING.
-
-    @final
-    class _MissingType: ...
-
-    MISSING: Final[_MissingType]
-
-    # resolve_path()
-
-    def resolve_path(
-        target: ModuleType | type[Any] | Any | str, name: str
-    ) -> tuple[ModuleType | type[Any] | Any, str, Callable[..., Any]]: ...
-
-    # resolve_owner()
-
-    def resolve_owner(
-        target: ModuleType | type[Any] | Any | str, name: str
-    ) -> tuple[ModuleType | type[Any] | Any, str, Callable[..., Any]]: ...
-
-    # apply_patch()
-
-    def apply_patch(
-        parent: ModuleType | type[Any] | Any,
-        attribute: str,
-        replacement: Any,
-    ) -> None: ...
-
-    # wrap_object()
-
-    _WrapperFactory = Callable[
-        [Callable[..., Any], tuple[Any, ...], dict[str, Any]],
-        BaseObjectProxy[Any],
-    ]
-
-    def wrap_object(
-        target: ModuleType | type[Any] | Any | str,
-        name: str,
-        factory: _WrapperFactory | type[BaseObjectProxy[Any]],
-        args: tuple[Any, ...] = (),
-        kwargs: dict[str, Any] | None = None,
-    ) -> Any: ...
-
-    # wrap_object_attribute()
-
-    class AttributeWrapper(BaseObjectProxy[Any]):
-        _self_attribute: str
-        _self_factory: Callable[..., Any]
-        _self_args: tuple[Any, ...]
-        _self_kwargs: dict[str, Any]
-        def __init__(
-            self,
-            wrapped: Any,
-            attribute: str,
-            factory: Callable[..., Any],
-            args: tuple[Any, ...] = (),
-            kwargs: dict[str, Any] | None = None,
-        ) -> None: ...
-        def __get__(self, instance: Any, owner: type[Any] | None = None) -> Any: ...
-        def __set__(self, instance: Any, value: Any) -> None: ...
-        def __delete__(self, instance: Any) -> None: ...
-
-    def wrap_object_attribute(
-        module: ModuleType | type[Any] | Any | str,
-        name: str,
-        factory: _WrapperFactory | type[BaseObjectProxy[Any]],
-        args: tuple[Any, ...] = (),
-        kwargs: dict[str, Any] | None = None,
-    ) -> AttributeWrapper: ...
-
-    # wrapper_chain()
-
-    def wrapper_chain(obj: Any, *, limit: int = 64) -> Iterator[Any]: ...
-
-    # unwrapped()
-
-    def unwrapped(obj: Any, *, limit: int = 64) -> Any: ...
-
-    # find_wrapper()
-
-    def find_wrapper(
-        obj: Any,
-        handle: Any | None = None,
-        *,
-        predicate: Callable[[Any], bool] | None = None,
-        limit: int = 64,
-    ) -> Any | None: ...
-
-    # is_wrapped_by()
-
-    def is_wrapped_by(
-        obj: Any,
-        handle: Any | None = None,
-        *,
-        predicate: Callable[[Any], bool] | None = None,
-        limit: int = 64,
-    ) -> bool: ...
-
-    # unwrap_object()
-
-    def unwrap_object(
-        target: ModuleType | type[Any] | Any | str,
-        name: str,
-        handle: Any,
-        *,
-        missing_ok: bool = False,
-    ) -> Any | None: ...
-
-    # register_post_import_hook()
-
-    def register_post_import_hook(
-        hook: Callable[[ModuleType], Any] | str, name: str
-    ) -> None: ...
-
-    # discover_post_import_hooks()
-
-    def discover_post_import_hooks(group: str) -> None: ...
-
-    # notify_module_loaded()
-
-    def notify_module_loaded(module: ModuleType) -> None: ...
-
-    # when_imported()
-
-    class _ImportHookDecorator:
-        def __call__(self, hook: Callable[[ModuleType], Any]) -> Callable[..., Any]: ...
-
-    def when_imported(name: str) -> _ImportHookDecorator: ...
-
-    # synchronized()
-
-    class _SynchronizedObject:
-        def __call__(self, wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
-        def __enter__(self) -> Any: ...
-        def __exit__(
-            self,
-            exc_type: type[BaseException] | None,
-            exc_value: BaseException | None,
-            traceback: TracebackType | None,
-        ) -> bool | None: ...
-        async def __aenter__(self) -> Any: ...
-        async def __aexit__(
-            self,
-            exc_type: type[BaseException] | None,
-            exc_value: BaseException | None,
-            traceback: TracebackType | None,
-        ) -> bool | None: ...
-
-    @overload
-    def synchronized(wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
-    @overload
-    def synchronized(wrapped: Any) -> _SynchronizedObject: ...
-
-    # mark_as_sync(), mark_as_async(), async_to_sync(), sync_to_async()
-
-    @overload
-    def mark_as_sync(wrapped: Callable[_P, _R], /) -> Callable[_P, _R]: ...
-    @overload
-    def mark_as_sync(
-        *, generator: bool | None = None
-    ) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-    @overload
-    def mark_as_async(wrapped: Callable[_P, _R], /) -> Callable[_P, _R]: ...
-    @overload
-    def mark_as_async(
-        *, generator: bool | None = None
-    ) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-    def async_to_sync(wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
-    def sync_to_async(wrapped: Callable[_P, _R]) -> Callable[_P, _R]: ...
-
-    # bind_state_to_wrapper()
-
-    class _StateBindingWrapper(BaseObjectProxy[Any]):
-        name: str
-        wrapper_factory: _Descriptor | None
-        def __init__(self, *, name: str = "state") -> None: ...
-        def __call__(self, wrapper_factory: _Descriptor) -> _StateBindingWrapper: ...
-        def __get__(
-            self, instance: Any, owner: type[Any]
-        ) -> (
-            _StateBindingWrapper
-            | Callable[[Callable[..., Any]], FunctionWrapper[..., Any]]
-        ): ...
-
-    bind_state_to_wrapper = _StateBindingWrapper
-
-    # lru_cache()
-
-    class _BoundLRUCacheFunctionWrapper(BoundFunctionWrapper[_P1, _R1]):
-        def cache_info(self) -> Any | None: ...
-        def cache_clear(self) -> None: ...
-        def cache_parameters(self) -> dict[str, Any] | None: ...
-
-    class _LRUCacheFunctionWrapper(FunctionWrapper[_P1, _R1]):
-        __bound_function_wrapper__: type[_BoundLRUCacheFunctionWrapper[_P1, _R1]]
-        def cache_info(self) -> Any | None: ...
-        def cache_clear(self) -> None: ...
-        def cache_parameters(self) -> dict[str, Any] | None: ...
-
-    @overload
-    def lru_cache(func: Callable[_P, _R], /) -> _LRUCacheFunctionWrapper[_P, _R]: ...
-    @overload
-    def lru_cache(
-        func: None = None, /, **kwargs: Any
-    ) -> Callable[[Callable[_P, _R]], _LRUCacheFunctionWrapper[_P, _R]]: ...
-
-    # with_signature()
-
-    def with_signature(
-        *,
-        prototype: Callable[..., Any] | None = None,
-        signature: Signature | None = None,
-        factory: (
-            Callable[
-                [Callable[..., Any]],
-                Signature
-                | Callable[..., Any]
-                | tuple[Signature | Callable[..., Any], str | None],
-            ]
-            | None
-        ) = None,
-        doc: str | None = None,
-    ) -> Callable[[Callable[_P, _R]], FunctionWrapper[_P, _R]]: ...
-
-    # with_doc()
-
-    def with_doc(
-        *,
-        doc: str | None = None,
-        factory: Callable[[Callable[..., Any]], str | None] | None = None,
-    ) -> Callable[[Callable[_P, _R]], FunctionWrapper[_P, _R]]: ...
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE
deleted file mode 100644
index 58dfb5c737e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt.LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright (c) 2013-2026, Graham Dumpleton
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py
deleted file mode 100644
index 5a91a9120e6..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__init__.py
+++ /dev/null
@@ -1,130 +0,0 @@
-"""
-Wrapt is a library for decorators, wrappers and monkey patching.
-"""
-
-
-def _format_version(parts):
-    base = ".".join(parts[:3])
-    if len(parts) == 3:
-        return base
-    suffix = parts[3]
-    return (
-        f"{base}.{suffix}" if suffix.startswith(("dev", "post")) else f"{base}{suffix}"
-    )
-
-
-__version_info__ = ("2", "5", "2")
-__version__ = _format_version(__version_info__)
-
-from .__wrapt__ import (
-    BaseObjectProxy,
-    BoundFunctionWrapper,
-    CallableObjectProxy,
-    FunctionWrapper,
-    PartialCallableObjectProxy,
-    partial,
-)
-from .caching import lru_cache
-from .decorators import (
-    AdapterFactory,
-    adapter_factory,
-    bind_state_to_wrapper,
-    decorator,
-)
-from .doc import with_doc
-from .exceptions import (
-    PathResolutionError,
-    TargetModuleNotFoundError,
-    WrapperChainTooDeepError,
-    WrapperNotFoundError,
-    WrapperNotInitializedError,
-    WrapperNotOutermostError,
-)
-from .importer import (
-    discover_post_import_hooks,
-    notify_module_loaded,
-    register_post_import_hook,
-    when_imported,
-)
-from .patches import (
-    MISSING,
-    AttributeWrapper,
-    apply_patch,
-    find_wrapper,
-    function_wrapper,
-    is_wrapped_by,
-    patch_function_wrapper,
-    resolve_owner,
-    resolve_path,
-    scoped_function_wrapper,
-    transient_function_wrapper,
-    unwrap_object,
-    unwrapped,
-    wrap_function_wrapper,
-    wrap_object,
-    wrap_object_attribute,
-    wrapper_chain,
-)
-from .proxies import AutoObjectProxy, LazyObjectProxy, ObjectProxy, lazy_import
-from .signature import with_signature
-from .synchronization import (
-    async_to_sync,
-    mark_as_async,
-    mark_as_sync,
-    sync_to_async,
-    synchronized,
-)
-from .weakrefs import WeakFunctionProxy
-
-__all__ = (
-    "AutoObjectProxy",
-    "BaseObjectProxy",
-    "BoundFunctionWrapper",
-    "CallableObjectProxy",
-    "FunctionWrapper",
-    "LazyObjectProxy",
-    "ObjectProxy",
-    "PartialCallableObjectProxy",
-    "PathResolutionError",
-    "TargetModuleNotFoundError",
-    "WrapperChainTooDeepError",
-    "WrapperNotFoundError",
-    "WrapperNotInitializedError",
-    "WrapperNotOutermostError",
-    "partial",
-    "AdapterFactory",
-    "adapter_factory",
-    "bind_state_to_wrapper",
-    "async_to_sync",
-    "decorator",
-    "lru_cache",
-    "mark_as_async",
-    "mark_as_sync",
-    "sync_to_async",
-    "synchronized",
-    "with_doc",
-    "with_signature",
-    "discover_post_import_hooks",
-    "notify_module_loaded",
-    "register_post_import_hook",
-    "when_imported",
-    "MISSING",
-    "AttributeWrapper",
-    "apply_patch",
-    "find_wrapper",
-    "function_wrapper",
-    "is_wrapped_by",
-    "lazy_import",
-    "patch_function_wrapper",
-    "resolve_owner",
-    "resolve_path",
-    "scoped_function_wrapper",
-    "transient_function_wrapper",
-    "unwrap_object",
-    "unwrapped",
-    "wrap_function_wrapper",
-    "wrap_object",
-    "wrap_object_attribute",
-    "wrapper_chain",
-    "WeakFunctionProxy",
-)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py
deleted file mode 100644
index f633aa98558..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/__wrapt__.py
+++ /dev/null
@@ -1,42 +0,0 @@
-"""This module is used to switch between C and Python implementations of the
-wrappers.
-"""
-
-import os
-
-from .wrappers import BoundFunctionWrapper, CallableObjectProxy, FunctionWrapper
-from .wrappers import ObjectProxy as BaseObjectProxy
-from .wrappers import PartialCallableObjectProxy, _FunctionWrapperBase
-
-# Try to use C extensions if not disabled.
-
-_using_c_extension = False
-
-_use_extensions = not os.environ.get("WRAPT_DISABLE_EXTENSIONS")
-
-if _use_extensions:
-    try:
-        from ._wrappers import (  # type: ignore[no-redef,import-not-found,import-untyped]
-            BoundFunctionWrapper,
-            CallableObjectProxy,
-            FunctionWrapper,
-        )
-        from ._wrappers import ObjectProxy as BaseObjectProxy  # type: ignore[no-redef,import-untyped]
-        from ._wrappers import (  # type: ignore[no-redef,import-not-found,import-untyped]
-            PartialCallableObjectProxy,
-            _FunctionWrapperBase,
-        )
-
-        _using_c_extension = True
-    except ImportError:
-        # C extensions not available, using Python implementations
-        pass
-
-
-def partial(*args, **kwargs):
-    """Create a callable object proxy with partial application of the given
-    arguments and keywords. This behaves the same as `functools.partial`, but
-    implemented using the `ObjectProxy` class to provide better support for
-    introspection.
-    """
-    return PartialCallableObjectProxy(*args, **kwargs)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c
deleted file mode 100644
index af1868de6e0..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/_wrappers.c
+++ /dev/null
@@ -1,5892 +0,0 @@
-/* ------------------------------------------------------------------------- */
-
-#include "Python.h"
-
-#include "structmember.h"
-
-/* ------------------------------------------------------------------------- */
-
-typedef struct
-{
-  PyObject_HEAD
-
-      PyObject *dict;
-  PyObject *wrapped;
-  PyObject *weakreflist;
-  int init_called;
-} WraptObjectProxyObject;
-
-typedef struct
-{
-  WraptObjectProxyObject object_proxy;
-
-  PyObject *args;
-  PyObject *kwargs;
-} WraptPartialCallableObjectProxyObject;
-
-typedef struct
-{
-  WraptObjectProxyObject object_proxy;
-
-  PyObject *instance;
-  PyObject *wrapper;
-  PyObject *enabled;
-  PyObject *binding;
-  PyObject *parent;
-  PyObject *owner;
-} WraptFunctionWrapperObject;
-
-/* ------------------------------------------------------------------------- */
-
-/* Forward declaration of moduledef so module-state helpers can reference it. */
-
-static struct PyModuleDef moduledef;
-
-/* Per-interpreter module state. Holds the heap type objects so that methods
- * can reach them via PyType_GetModuleByDef without using static globals,
- * along with the cached interned strings and exception type below. */
-
-typedef struct
-{
-  PyTypeObject *ObjectProxy_Type;
-  PyTypeObject *CallableObjectProxy_Type;
-  PyTypeObject *PartialCallableObjectProxy_Type;
-  PyTypeObject *FunctionWrapperBase_Type;
-  PyTypeObject *BoundFunctionWrapper_Type;
-  PyTypeObject *FunctionWrapper_Type;
-
-  /* Cached interned attribute / argument names. Initialized eagerly in
-   * wrapt_exec, released in wrapt_clear. Per-interpreter so they remain
-   * sub-interpreter safe; eager init makes them free-threading safe by
-   * eliminating the lazy-init data race that the previous static-local
-   * string pattern had. */
-
-  PyObject *str_wrapped;                /* "__wrapped__" */
-  PyObject *str_wrapped_factory;        /* "__wrapped_factory__" */
-  PyObject *str_wrapped_get;            /* "__wrapped_get__" */
-  PyObject *str_module;                 /* "__module__" */
-  PyObject *str_doc;                    /* "__doc__" */
-  PyObject *str_setattr_fixups;         /* "__wrapped_setattr_fixups__" */
-  PyObject *str_getattr;                /* "__getattr__" */
-  PyObject *str_self_;                  /* "_self_" */
-  PyObject *str_callable;               /* "callable" */
-  PyObject *str_bound_function_wrapper; /* "__bound_function_wrapper__" */
-  PyObject *str_function;               /* "function" */
-  PyObject *str_classmethod;            /* "classmethod" */
-  PyObject *str_staticmethod;           /* "staticmethod" */
-  PyObject *str_builtin;                /* "builtin" */
-  PyObject *str_class;                  /* "class" */
-  PyObject *str_instancemethod;         /* "instancemethod" */
-  PyObject *str_object_proxy;           /* "__object_proxy__" */
-  PyObject *str_enter;                  /* "__enter__" */
-  PyObject *str_exit;                   /* "__exit__" */
-  PyObject *str_aenter;                 /* "__aenter__" */
-  PyObject *str_aexit;                  /* "__aexit__" */
-  PyObject *str_mro_entries;            /* "__mro_entries__" */
-  PyObject *str_name;                   /* "__name__" */
-  PyObject *str_qualname;               /* "__qualname__" */
-  PyObject *str_annotations;            /* "__annotations__" */
-  PyObject *str_dunder_class;           /* "__class__" */
-  PyObject *str_self;                   /* "__self__" */
-  PyObject *str_set_name;               /* "__set_name__" */
-  PyObject *str_self_binding;           /* "_self_binding" */
-  PyObject *str_dict;                   /* "__dict__" */
-  PyObject *str_signature;              /* "__signature__" */
-
-  /* Cached exception type from wrapt.wrappers. Initialized eagerly in
-   * wrapt_exec after type creation. The wrapt.wrappers module is guaranteed
-   * to be imported before _wrappers because __wrapt__.py imports it first. */
-
-  PyObject *WrapperNotInitializedError;
-} wrapt_module_state;
-
-static inline wrapt_module_state *wrapt_get_state(PyObject *module)
-{
-  return (wrapt_module_state *)PyModule_GetState(module);
-}
-
-/* Polyfill PyType_GetModuleByDef for Python < 3.11. The borrowed-reference
- * contract matches the real API so callers are version-agnostic. */
-
-#if PY_VERSION_HEX < 0x030B0000
-static PyObject *PyType_GetModuleByDef(PyTypeObject *type,
-                                       struct PyModuleDef *def)
-{
-  PyObject *mro = type->tp_mro;
-  Py_ssize_t i, n;
-
-  if (mro == NULL)
-    return NULL;
-
-  n = PyTuple_GET_SIZE(mro);
-
-  for (i = 0; i < n; i++)
-  {
-    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
-    PyObject *m;
-
-    if (!PyType_HasFeature(t, Py_TPFLAGS_HEAPTYPE))
-      continue;
-
-    m = PyType_GetModule(t);
-
-    if (m != NULL && PyModule_GetDef(m) == def)
-      return m;
-
-    if (m == NULL)
-    {
-      /* PyType_GetModule only raises TypeError here (no module
-       * association on heap type); no other failure mode is expected.
-       * Guard with WriteUnraisable for completeness. */
-      if (!PyErr_ExceptionMatches(PyExc_TypeError))
-        PyErr_WriteUnraisable((PyObject *)t);
-      PyErr_Clear();
-    }
-  }
-
-  PyErr_Format(PyExc_TypeError,
-               "PyType_GetModuleByDef: No superclass of '%s' has the given "
-               "module",
-               type->tp_name);
-  return NULL;
-}
-#endif
-
-/* Polyfill the critical section API for Python < 3.13. Free-threaded
- * builds only exist on 3.13+, where the real macros are provided (and are
- * no-ops on GIL builds), so expanding to plain blocks here is safe. */
-
-#if PY_VERSION_HEX < 0x030D0000
-#define Py_BEGIN_CRITICAL_SECTION(op) {
-#define Py_END_CRITICAL_SECTION() }
-#endif
-
-/* Polyfill PyObject_GetOptionalAttrString for Python < 3.13. Matches the
- * 3.13+ semantics: returns 1 if found, 0 if not found (AttributeError
- * only), -1 on other errors with exception set. */
-
-#if PY_VERSION_HEX < 0x030d0000
-static inline int
-PyObject_GetOptionalAttrString(PyObject *obj, const char *name, PyObject **result)
-{
-  *result = PyObject_GetAttrString(obj, name);
-  if (*result)
-    return 1;
-  if (PyErr_ExceptionMatches(PyExc_AttributeError))
-  {
-    PyErr_Clear();
-    return 0;
-  }
-  return -1;
-}
-#endif
-
-/* Atomically read a PyObject field of an instance and return a new
- * reference to it, or NULL if the field is NULL (no exception is set).
- * The read and the incref are performed together inside the owning
- * object's critical section so the incref cannot race a writer which
- * has swapped in a new value and is releasing the old one. On builds
- * with the GIL the critical section is a no-op and this reduces to a
- * plain load and incref. This is deliberately used on all builds rather
- * than only free-threaded ones, so that both build variants exercise
- * the same reference lifetimes, and so that a field value can never be
- * freed while still in use when code invoked while operating on the
- * field mutates the instance. */
-
-static inline PyObject *wrapt_acquire_field(PyObject *owner, PyObject **field)
-{
-  PyObject *value = NULL;
-
-  Py_BEGIN_CRITICAL_SECTION(owner);
-  value = *field;
-  Py_XINCREF(value);
-  Py_END_CRITICAL_SECTION();
-
-  return value;
-}
-
-/* Test whether an attribute name matches one of the interned strings held
- * in module state. Attribute names arriving from Python code are interned
- * by the compiler, so a pointer comparison against the interned string is
- * nearly always sufficient and is the fast path. A name constructed at
- * runtime, for example by string concatenation or decoding, is not
- * interned and would never match by pointer, so fall back to a value
- * comparison. That comparison is guarded by a length check so that the
- * cost for the overwhelming majority of non matching names is a single
- * integer comparison. This mirrors the pattern used by CPython itself in
- * super_getattro() for __class__.
- *
- * The name must be a str. This holds for the attribute get and set slots
- * where this is used, since PyObject_GetAttr() and PyObject_SetAttr()
- * reject any other type before the slot is reached. */
-
-static inline int wrapt_name_equals(PyObject *name, PyObject *interned)
-{
-  if (name == interned)
-    return 1;
-
-  if (!PyUnicode_Check(name))
-    return 0;
-
-  if (PyUnicode_GET_LENGTH(name) != PyUnicode_GET_LENGTH(interned))
-    return 0;
-
-  return PyUnicode_Compare(name, interned) == 0;
-}
-
-/* Convenience form for the common case of the wrapped object field. */
-
-static inline PyObject *wrapt_acquire_wrapped(WraptObjectProxyObject *self)
-{
-  return wrapt_acquire_field((PyObject *)self, &self->wrapped);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Get module state for the wrapt module given any type whose MRO includes
- * one of our heap types. Returns NULL and sets an exception on miss. */
-
-static wrapt_module_state *wrapt_state_from_type(PyTypeObject *type)
-{
-  PyObject *m = PyType_GetModuleByDef(type, &moduledef);
-  return m ? wrapt_get_state(m) : NULL;
-}
-
-/* Walk type's MRO checking each tp_dict directly for the named attribute.
- * Does not invoke type's tp_getattro, so it does NOT trigger Python's lazy
- * creation of class-level attributes such as __annotations__. Used by
- * setattro to decide "is this a local attribute on the proxy type" without
- * shadowing our getset descriptors via lazy class-dict mutation. */
-
-static int wrapt_type_has_attr(PyTypeObject *type, PyObject *name)
-{
-  PyObject *mro = type->tp_mro;
-  Py_ssize_t i, n;
-
-  if (mro == NULL)
-    return 0;
-
-  n = PyTuple_GET_SIZE(mro);
-
-  for (i = 0; i < n; i++)
-  {
-    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
-    PyObject *dict = t->tp_dict;
-    int contains;
-
-    if (dict == NULL)
-      continue;
-
-    contains = PyDict_Contains(dict, name);
-    if (contains < 0)
-    {
-      /* PyDict_Contains cannot fail with string keys against a
-       * string-keyed tp_dict; no failure is expected here. Guard
-       * with WriteUnraisable for completeness. */
-      PyErr_WriteUnraisable((PyObject *)t);
-      PyErr_Clear();
-      continue;
-    }
-    if (contains > 0)
-      return 1;
-  }
-
-  return 0;
-}
-
-/* Look for a __doc__ descriptor defined by a derived class. Walks the MRO
- * of the type checking each tp_dict directly for __doc__, skipping the
- * plain docstring entries which every class carries, being a string or
- * None for a class without a docstring. The proxy base types hold a plain
- * string docstring, so any descriptor found must come from a derived
- * class, which is taken to mean it wants to control what __doc__ reports
- * for its instances in place of the default delegation to the wrapped
- * object. Only __doc__ is treated this way, __module__ always delegates.
- * The descriptor is invoked directly rather than falling back to the
- * generic attribute lookup, since that would stop at the None or docstring
- * entry of a derived class which inherits the descriptor from its base.
- * Returns a new reference, or NULL without an exception set if there is
- * no such descriptor. */
-
-static PyObject *wrapt_lookup_doc_descriptor(PyTypeObject *type,
-                                             PyObject *name)
-{
-  PyObject *mro = type->tp_mro;
-  Py_ssize_t i, n;
-
-  if (mro == NULL)
-    return NULL;
-
-  n = PyTuple_GET_SIZE(mro);
-
-  for (i = 0; i < n; i++)
-  {
-    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
-    PyObject *dict = t->tp_dict;
-    PyObject *entry = NULL;
-
-    if (dict == NULL)
-      continue;
-
-#if PY_VERSION_HEX >= 0x030D0000
-    if (PyDict_GetItemRef(dict, name, &entry) < 0)
-    {
-      PyErr_WriteUnraisable((PyObject *)t);
-      PyErr_Clear();
-      continue;
-    }
-#else
-    entry = PyDict_GetItemWithError(dict, name);
-    if (entry == NULL && PyErr_Occurred())
-    {
-      PyErr_WriteUnraisable((PyObject *)t);
-      PyErr_Clear();
-      continue;
-    }
-    Py_XINCREF(entry);
-#endif
-
-    if (entry == NULL)
-      continue;
-
-    if (entry == Py_None || PyUnicode_Check(entry))
-    {
-      Py_DECREF(entry);
-      continue;
-    }
-
-    if (Py_TYPE(entry)->tp_descr_get)
-      return entry;
-
-    Py_DECREF(entry);
-    return NULL;
-  }
-
-  return NULL;
-}
-
-/* Non-error-setting predicate: is this object an instance of any wrapt
- * proxy type? Walks the MRO directly. PyType_GetModule sets an exception
- * for heap types that lack a module association (e.g. pure-Python user
- * subclasses), so we save/restore exception state to keep this predicate
- * side-effect-free for the caller. */
-
-static int wrapt_is_proxy(PyObject *o)
-{
-  PyTypeObject *type = Py_TYPE(o);
-  PyObject *mro = type->tp_mro;
-  Py_ssize_t i, n;
-  PyObject *saved_type = NULL, *saved_value = NULL, *saved_tb = NULL;
-  int had_error = PyErr_Occurred() != NULL;
-  int result = 0;
-
-  if (had_error)
-    PyErr_Fetch(&saved_type, &saved_value, &saved_tb);
-
-  if (mro == NULL)
-    goto done;
-
-  n = PyTuple_GET_SIZE(mro);
-
-  for (i = 0; i < n; i++)
-  {
-    PyTypeObject *t = (PyTypeObject *)PyTuple_GET_ITEM(mro, i);
-    PyObject *m;
-
-    if (!PyType_HasFeature(t, Py_TPFLAGS_HEAPTYPE))
-      continue;
-
-    m = PyType_GetModule(t);
-
-    if (m == NULL)
-    {
-      /* PyType_GetModule only raises TypeError here (no module
-       * association on heap type); no other failure mode is expected.
-       * Guard with WriteUnraisable for completeness. */
-      if (!PyErr_ExceptionMatches(PyExc_TypeError))
-        PyErr_WriteUnraisable((PyObject *)t);
-      PyErr_Clear();
-      continue;
-    }
-
-    if (PyModule_GetDef(m) == &moduledef)
-    {
-      result = 1;
-      break;
-    }
-  }
-
-done:
-  if (had_error)
-    PyErr_Restore(saved_type, saved_value, saved_tb);
-  else
-    PyErr_Clear();
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int raise_uninitialized_wrapper_error(WraptObjectProxyObject *object)
-{
-  // Before raising an exception we need to first check whether this is a lazy
-  // proxy object and attempt to intialize the wrapped object using the supplied
-  // callback if so. If the callback is not present then we can proceed to raise
-  // the exception, but if the callback is present and returns a value, we set
-  // that as the wrapped object and continue and return without raising an error.
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(object));
-  if (!state)
-    return -1;
-
-  PyObject *wrapped_str = state->str_wrapped;
-  PyObject *wrapped_factory_str = state->str_wrapped_factory;
-  PyObject *wrapped_get_str = state->str_wrapped_get;
-
-  PyObject *callback = NULL;
-  PyObject *value = NULL;
-
-  // Note that we use existance of __wrapped_factory__ to gate whether we can
-  // attempt to initialize the wrapped object lazily, but it is __wrapped_get__
-  // that we actually call to do the initialization. This is so that we can
-  // handle multithreading correctly by having __wrapped_get__ use a lock to
-  // protect against multiple threads trying to initialize the wrapped object
-  // at the same time.
-
-  callback = PyObject_GenericGetAttr((PyObject *)object, wrapped_factory_str);
-
-  if (callback)
-  {
-    if (callback != Py_None)
-    {
-      Py_DECREF(callback);
-
-      callback = PyObject_GenericGetAttr((PyObject *)object, wrapped_get_str);
-
-      if (!callback)
-        return -1;
-
-      value = PyObject_CallObject(callback, NULL);
-
-      Py_DECREF(callback);
-
-      if (value)
-      {
-        // We use setattr so that special dunder methods will be properly set.
-
-        if (PyObject_SetAttr((PyObject *)object, wrapped_str, value) == -1)
-        {
-          Py_DECREF(value);
-          return -1;
-        }
-
-        Py_DECREF(value);
-
-        return 0;
-      }
-      else
-      {
-        return -1;
-      }
-    }
-    else
-    {
-      Py_DECREF(callback);
-    }
-  }
-  else
-  {
-    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-      return -1;
-    PyErr_Clear();
-  }
-
-  if (object->init_called)
-  {
-    PyErr_SetString(state->WrapperNotInitializedError,
-                    "wrapper is in an inconsistent state: __wrapped__ is not set");
-  }
-  else
-  {
-    PyErr_Format(PyExc_AttributeError,
-                 "'%.100s' object has no attribute '__wrapped__'",
-                 Py_TYPE(object)->tp_name);
-  }
-
-  return -1;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Check that a wrapper specific field, as acquired by the caller, is not
- * NULL, raising an error if it is. The additional fields of a partial or
- * function wrapper are only ever set by __init__(), and together, so one
- * being NULL means __init__() was never called, or did not complete. That
- * is possible where a derived class overrides __init__() without calling
- * that of the base class, or where an instance is created using __new__()
- * alone, and __wrapped__ is then assigned directly such that the check for
- * an uninitialized wrapper passes. An AttributeError naming the attribute
- * by which the field is exposed is raised, that being what the pure Python
- * implementation yields, since it holds the same state as instance
- * attributes, which in this situation do not exist. */
-
-static inline int wrapt_require_field(PyObject *object, PyObject *value,
-                                      const char *name)
-{
-  if (value)
-    return 0;
-
-  PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%s'",
-               Py_TYPE(object)->tp_name, name);
-
-  return -1;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Replace *op with a strong reference to the value to actually operate
- * on: the wrapped object if *op is a wrapt proxy, else *op itself. On
- * success the caller owns a reference to the replacement value and must
- * release it after use. Returns -1 with an exception set, and *op
- * unchanged, if *op is an uninitialized proxy which could not be
- * lazily initialized. */
-
-static int wrapt_unwrap_operand(PyObject **op)
-{
-  WraptObjectProxyObject *proxy;
-  PyObject *wrapped;
-
-  if (!wrapt_is_proxy(*op))
-  {
-    Py_INCREF(*op);
-    return 0;
-  }
-
-  proxy = (WraptObjectProxyObject *)*op;
-
-  if (!proxy->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(proxy) == -1)
-      return -1;
-  }
-
-  wrapped = wrapt_acquire_wrapped(proxy);
-
-  if (!wrapped)
-  {
-    PyErr_Format(PyExc_AttributeError,
-                 "'%.100s' object has no attribute '__wrapped__'",
-                 Py_TYPE(proxy)->tp_name);
-    return -1;
-  }
-
-  *op = wrapped;
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_new(PyTypeObject *type, PyObject *args,
-                                      PyObject *kwds)
-{
-  WraptObjectProxyObject *self;
-
-  self = (WraptObjectProxyObject *)type->tp_alloc(type, 0);
-
-  if (!self)
-    return NULL;
-
-  self->dict = PyDict_New();
-
-  if (!self->dict)
-  {
-    Py_DECREF(self);
-    return NULL;
-  }
-
-  self->wrapped = NULL;
-  self->weakreflist = NULL;
-  self->init_called = 0;
-
-  return (PyObject *)self;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_raw_init(WraptObjectProxyObject *self,
-                                     PyObject *wrapped)
-{
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *module_str = state->str_module;
-  PyObject *doc_str = state->str_doc;
-  PyObject *wrapped_factory_str = state->str_wrapped_factory;
-
-  PyObject *object = NULL;
-
-  // If wrapped is Py_None and we have a __wrapped_factory__ attribute
-  // then we defer initialization of the wrapped object until it is first needed.
-
-  if (wrapped == Py_None)
-  {
-    PyObject *callback = NULL;
-
-    callback = PyObject_GenericGetAttr((PyObject *)self, wrapped_factory_str);
-
-    if (callback)
-    {
-      if (callback != Py_None)
-      {
-        Py_DECREF(callback);
-        self->init_called = 1;
-        return 0;
-      }
-      else
-      {
-        Py_DECREF(callback);
-      }
-    }
-    else
-    {
-      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-        return -1;
-      PyErr_Clear();
-    }
-  }
-
-  /* Serialise the swap for the same reason as in the __wrapped__ setter.
-   * Normally __init__ runs before the proxy is shared, but it can be
-   * re-invoked on an already published proxy, in which case concurrent
-   * callers on a free-threaded build could otherwise decref the same old
-   * wrapped object twice. */
-
-  Py_INCREF(wrapped);
-  Py_BEGIN_CRITICAL_SECTION(self);
-  Py_XSETREF(self->wrapped, wrapped);
-  Py_END_CRITICAL_SECTION();
-
-  self->init_called = 1;
-
-  object = PyObject_GetAttr(wrapped, module_str);
-
-  if (object)
-  {
-    if (PyDict_SetItem(self->dict, module_str, object) == -1)
-    {
-      Py_DECREF(object);
-      return -1;
-    }
-    Py_DECREF(object);
-  }
-  else
-  {
-    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-      return -1;
-    PyErr_Clear();
-  }
-
-  object = PyObject_GetAttr(wrapped, doc_str);
-
-  if (object)
-  {
-    if (PyDict_SetItem(self->dict, doc_str, object) == -1)
-    {
-      Py_DECREF(object);
-      return -1;
-    }
-    Py_DECREF(object);
-  }
-  else
-  {
-    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-      return -1;
-    PyErr_Clear();
-  }
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_init(WraptObjectProxyObject *self, PyObject *args,
-                                 PyObject *kwds)
-{
-  PyObject *wrapped = NULL;
-
-  char *const kwlist[] = {"wrapped", NULL};
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:ObjectProxy", kwlist,
-                                   &wrapped))
-  {
-    return -1;
-  }
-
-  return WraptObjectProxy_raw_init(self, wrapped);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_traverse(WraptObjectProxyObject *self,
-                                     visitproc visit, void *arg)
-{
-  Py_VISIT(Py_TYPE(self));
-  Py_VISIT(self->dict);
-  Py_VISIT(self->wrapped);
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_clear(WraptObjectProxyObject *self)
-{
-  Py_CLEAR(self->dict);
-  Py_CLEAR(self->wrapped);
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void WraptObjectProxy_dealloc(WraptObjectProxyObject *self)
-{
-  PyTypeObject *tp = Py_TYPE(self);
-
-  PyObject_GC_UnTrack(self);
-
-  if (self->weakreflist != NULL)
-    PyObject_ClearWeakRefs((PyObject *)self);
-
-  WraptObjectProxy_clear(self);
-
-  tp->tp_free(self);
-
-#if PY_VERSION_HEX >= 0x030C0000
-  PyObject *exc = PyErr_GetRaisedException();
-  Py_DECREF(tp);
-  PyErr_SetRaisedException(exc);
-#else
-  PyObject *exc_type, *exc_value, *exc_tb;
-  PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
-  Py_DECREF(tp);
-  PyErr_Restore(exc_type, exc_value, exc_tb);
-#endif
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_repr(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  char self_addr[24], wrapped_addr[24];
-  snprintf(self_addr, sizeof(self_addr), "0x%zx", (Py_uintptr_t)self);
-  snprintf(wrapped_addr, sizeof(wrapped_addr), "0x%zx",
-           (Py_uintptr_t)wrapped);
-  PyObject *result = PyUnicode_FromFormat("<%s at %s for %s at %s>",
-                                          Py_TYPE(self)->tp_name, self_addr,
-                                          Py_TYPE(wrapped)->tp_name,
-                                          wrapped_addr);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static Py_hash_t WraptObjectProxy_hash(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  Py_hash_t result = PyObject_Hash(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_str(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_Str(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_add(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Add(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_subtract(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Subtract(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_multiply(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Multiply(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_remainder(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Remainder(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_divmod(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Divmod(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_power(PyObject *o1, PyObject *o2,
-                                        PyObject *modulo)
-{
-  /*
-   * If modulo is a proxy we cannot call PyNumber_Power with it, otherwise
-   * we would recurse back into this slot via CPython's ternary_op fallback
-   * and blow the C stack. Return NotImplemented so a TypeError is raised,
-   * matching the pure Python implementation which does not unwrap modulo.
-   */
-
-  if (wrapt_is_proxy(modulo))
-  {
-    Py_RETURN_NOTIMPLEMENTED;
-  }
-
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Power(o1, o2, modulo);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_negative(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyNumber_Negative(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_positive(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyNumber_Positive(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_absolute(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyNumber_Absolute(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_bool(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result = PyObject_IsTrue(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_invert(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyNumber_Invert(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_lshift(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Lshift(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_rshift(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Rshift(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_and(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_And(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_xor(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Xor(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_or(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_Or(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_long(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyNumber_Long(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_float(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyNumber_Float(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_add(WraptObjectProxyObject *self,
-                                              PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__iadd__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceAdd(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    /* As in the __wrapped__ setter, serialise the swap so that concurrent
-     * in-place operations on the same proxy cannot decref the same old
-     * wrapped object twice on a free-threaded build. The wrapped object
-     * was read before the operation ran, so a concurrent mutation can
-     * still be lost, matching pure Python semantics. The same applies to
-     * all of the in-place operators which follow. */
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Add(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_subtract(WraptObjectProxyObject *self,
-                                                   PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__isub__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceSubtract(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Subtract(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_multiply(WraptObjectProxyObject *self,
-                                                   PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__imul__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceMultiply(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Multiply(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptObjectProxy_inplace_remainder(WraptObjectProxyObject *self,
-                                   PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__imod__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceRemainder(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Remainder(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_power(WraptObjectProxyObject *self,
-                                                PyObject *other,
-                                                PyObject *modulo)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__ipow__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlacePower(wrapped, other, modulo);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Power(wrapped, other, modulo);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_lshift(WraptObjectProxyObject *self,
-                                                 PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__ilshift__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceLshift(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Lshift(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_rshift(WraptObjectProxyObject *self,
-                                                 PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__irshift__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceRshift(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Rshift(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_and(WraptObjectProxyObject *self,
-                                              PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__iand__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceAnd(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_And(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_xor(WraptObjectProxyObject *self,
-                                              PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__ixor__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceXor(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Xor(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_or(WraptObjectProxyObject *self,
-                                             PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__ior__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceOr(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_Or(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_floor_divide(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_FloorDivide(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_true_divide(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_TrueDivide(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptObjectProxy_inplace_floor_divide(WraptObjectProxyObject *self,
-                                      PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__ifloordiv__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceFloorDivide(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_FloorDivide(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptObjectProxy_inplace_true_divide(WraptObjectProxyObject *self,
-                                     PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__itruediv__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceTrueDivide(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_TrueDivide(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_index(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyNumber_Index(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_matrix_multiply(PyObject *o1, PyObject *o2)
-{
-  if (wrapt_unwrap_operand(&o1) == -1)
-    return NULL;
-
-  if (wrapt_unwrap_operand(&o2) == -1)
-  {
-    Py_DECREF(o1);
-    return NULL;
-  }
-
-  PyObject *result = PyNumber_MatrixMultiply(o1, o2);
-
-  Py_DECREF(o1);
-  Py_DECREF(o2);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_inplace_matrix_multiply(
-    WraptObjectProxyObject *self, PyObject *other)
-{
-  PyObject *object = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (wrapt_unwrap_operand(&other) == -1)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *attr;
-  int rc = PyObject_GetOptionalAttrString(wrapped, "__imatmul__", &attr);
-  Py_XDECREF(attr);
-  if (rc < 0)
-  {
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-    return NULL;
-  }
-  if (rc)
-  {
-    object = PyNumber_InPlaceMatrixMultiply(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!object)
-      return NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_SETREF(self->wrapped, object);
-    Py_END_CRITICAL_SECTION();
-
-    Py_INCREF(self);
-    return (PyObject *)self;
-  }
-  else
-  {
-    PyObject *result = PyNumber_MatrixMultiply(wrapped, other);
-
-    Py_DECREF(wrapped);
-    Py_DECREF(other);
-
-    if (!result)
-      return NULL;
-
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_type = PyObject_GetAttr((PyObject *)self, state->str_object_proxy);
-
-    if (!proxy_type)
-    {
-      Py_DECREF(result);
-      return NULL;
-    }
-
-    PyObject *proxy_args = PyTuple_Pack(1, result);
-
-    Py_DECREF(result);
-
-    if (!proxy_args)
-    {
-      Py_DECREF(proxy_type);
-      return NULL;
-    }
-
-    PyObject *proxy_instance = PyObject_Call(proxy_type, proxy_args, NULL);
-
-    Py_DECREF(proxy_type);
-    Py_DECREF(proxy_args);
-
-    return proxy_instance;
-  }
-}
-
-/* ------------------------------------------------------------------------- */
-
-static Py_ssize_t WraptObjectProxy_length(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  Py_ssize_t result = PyObject_Length(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_contains(WraptObjectProxyObject *self,
-                                     PyObject *value)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result = PySequence_Contains(wrapped, value);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_getitem(WraptObjectProxyObject *self,
-                                          PyObject *key)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetItem(wrapped, key);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_setitem(WraptObjectProxyObject *self, PyObject *key,
-                                    PyObject *value)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result;
-
-  if (value == NULL)
-    result = PyObject_DelItem(wrapped, key);
-  else
-    result = PyObject_SetItem(wrapped, key, value);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_self_setattr(WraptObjectProxyObject *self,
-                                               PyObject *args)
-{
-  PyObject *name = NULL;
-  PyObject *value = NULL;
-
-  if (!PyArg_ParseTuple(args, "UO:__self_setattr__", &name, &value))
-    return NULL;
-
-  if (PyObject_GenericSetAttr((PyObject *)self, name, value) != 0)
-  {
-    return NULL;
-  }
-
-  Py_RETURN_NONE;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_dir(WraptObjectProxyObject *self,
-                                      PyObject *args)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_Dir(wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_enter(WraptObjectProxyObject *self,
-                                        PyObject *args, PyObject *kwds)
-{
-  PyObject *method = NULL;
-  PyObject *result = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  method = PyObject_GetAttr(wrapped, state->str_enter);
-
-  Py_DECREF(wrapped);
-
-  if (!method)
-    return NULL;
-
-  result = PyObject_Call(method, args, kwds);
-
-  Py_DECREF(method);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_exit(WraptObjectProxyObject *self,
-                                       PyObject *args, PyObject *kwds)
-{
-  PyObject *method = NULL;
-  PyObject *result = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  method = PyObject_GetAttr(wrapped, state->str_exit);
-
-  Py_DECREF(wrapped);
-
-  if (!method)
-    return NULL;
-
-  result = PyObject_Call(method, args, kwds);
-
-  Py_DECREF(method);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_aenter(WraptObjectProxyObject *self,
-                                         PyObject *args, PyObject *kwds)
-{
-  PyObject *method = NULL;
-  PyObject *result = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  method = PyObject_GetAttr(wrapped, state->str_aenter);
-
-  Py_DECREF(wrapped);
-
-  if (!method)
-    return NULL;
-
-  result = PyObject_Call(method, args, kwds);
-
-  Py_DECREF(method);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_aexit(WraptObjectProxyObject *self,
-                                        PyObject *args, PyObject *kwds)
-{
-  PyObject *method = NULL;
-  PyObject *result = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  method = PyObject_GetAttr(wrapped, state->str_aexit);
-
-  Py_DECREF(wrapped);
-
-  if (!method)
-    return NULL;
-
-  result = PyObject_Call(method, args, kwds);
-
-  Py_DECREF(method);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_copy(WraptObjectProxyObject *self,
-                                       PyObject *Py_UNUSED(ignored))
-{
-  PyErr_SetString(PyExc_NotImplementedError,
-                  "object proxy must define __copy__()");
-
-  return NULL;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_deepcopy(WraptObjectProxyObject *self,
-                                           PyObject *args, PyObject *kwds)
-{
-  PyErr_SetString(PyExc_NotImplementedError,
-                  "object proxy must define __deepcopy__()");
-
-  return NULL;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_reduce(WraptObjectProxyObject *self,
-                                         PyObject *Py_UNUSED(ignored))
-{
-  PyErr_SetString(PyExc_NotImplementedError,
-                  "object proxy must define __reduce__()");
-
-  return NULL;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_bytes(WraptObjectProxyObject *self,
-                                        PyObject *args)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_CallFunctionObjArgs((PyObject *)&PyBytes_Type,
-                                                  wrapped, NULL);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_format(WraptObjectProxyObject *self,
-                                         PyObject *args)
-{
-  PyObject *format_spec = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (!PyArg_ParseTuple(args, "O:format", &format_spec))
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_Format(wrapped, format_spec);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_reversed(WraptObjectProxyObject *self,
-                                           PyObject *args)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_CallFunctionObjArgs((PyObject *)&PyReversed_Type,
-                                                  wrapped, NULL);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_round(WraptObjectProxyObject *self,
-                                        PyObject *args, PyObject *kwds)
-{
-  PyObject *ndigits = NULL;
-
-  PyObject *module = NULL;
-  PyObject *round = NULL;
-
-  PyObject *result = NULL;
-
-  char *const kwlist[] = {"ndigits", NULL};
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:ObjectProxy", kwlist,
-                                   &ndigits))
-  {
-    return NULL;
-  }
-
-  module = PyImport_ImportModule("builtins");
-
-  if (!module)
-    return NULL;
-
-  round = PyObject_GetAttrString(module, "round");
-
-  if (!round)
-  {
-    Py_DECREF(module);
-    return NULL;
-  }
-
-  Py_DECREF(module);
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  result = PyObject_CallFunctionObjArgs(round, wrapped, ndigits, NULL);
-
-  Py_DECREF(wrapped);
-  Py_DECREF(round);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *wrapt_call_math_unary(WraptObjectProxyObject *self,
-                                       const char *name)
-{
-  PyObject *module = NULL;
-  PyObject *function = NULL;
-  PyObject *result = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  module = PyImport_ImportModule("math");
-
-  if (!module)
-    return NULL;
-
-  function = PyObject_GetAttrString(module, name);
-
-  if (!function)
-  {
-    Py_DECREF(module);
-    return NULL;
-  }
-
-  Py_DECREF(module);
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  result = PyObject_CallFunctionObjArgs(function, wrapped, NULL);
-
-  Py_DECREF(wrapped);
-  Py_DECREF(function);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_trunc(WraptObjectProxyObject *self,
-                                        PyObject *Py_UNUSED(ignored))
-{
-  return wrapt_call_math_unary(self, "trunc");
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_floor(WraptObjectProxyObject *self,
-                                        PyObject *Py_UNUSED(ignored))
-{
-  return wrapt_call_math_unary(self, "floor");
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_ceil(WraptObjectProxyObject *self,
-                                       PyObject *Py_UNUSED(ignored))
-{
-  return wrapt_call_math_unary(self, "ceil");
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_complex(WraptObjectProxyObject *self,
-                                          PyObject *args)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_CallFunctionObjArgs((PyObject *)&PyComplex_Type,
-                                                  wrapped, NULL);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_mro_entries(WraptObjectProxyObject *self,
-                                              PyObject *args, PyObject *kwds)
-{
-  PyObject *wrapped = NULL;
-  PyObject *mro_entries_method = NULL;
-  PyObject *result = NULL;
-  int is_type = 0;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapped = wrapt_acquire_wrapped(self);
-
-  // Check if wrapped is a type (class).
-
-  is_type = PyType_Check(wrapped);
-
-  // If wrapped is not a type and has __mro_entries__, forward to it.
-
-  if (!is_type)
-  {
-    wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-    if (!state)
-    {
-      Py_DECREF(wrapped);
-      return NULL;
-    }
-
-    mro_entries_method = PyObject_GetAttr(wrapped, state->str_mro_entries);
-
-    if (mro_entries_method)
-    {
-      // Call wrapped.__mro_entries__(bases).
-
-      result = PyObject_Call(mro_entries_method, args, kwds);
-
-      Py_DECREF(mro_entries_method);
-      Py_DECREF(wrapped);
-
-      return result;
-    }
-    else
-    {
-      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-      {
-        Py_DECREF(wrapped);
-        return NULL;
-      }
-      PyErr_Clear();
-    }
-  }
-
-  result = Py_BuildValue("(O)", wrapped);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_name(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetAttr(wrapped, state->str_name);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_set_name(WraptObjectProxyObject *self,
-                                     PyObject *value)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result = PyObject_SetAttr(wrapped, state->str_name, value);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_qualname(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetAttr(wrapped, state->str_qualname);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_set_qualname(WraptObjectProxyObject *self,
-                                         PyObject *value)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result = PyObject_SetAttr(wrapped, state->str_qualname, value);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_module(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetAttr(wrapped, state->str_module);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Refresh the copy of __module__ or __doc__ held in the proxy's own dict
- * after the attribute has been deleted from the wrapped object. Deleting
- * __doc__ from a function, for example, leaves the attribute present with
- * a value of None, whereas on other objects it may be gone entirely. Record
- * what __init__ would have for a fresh proxy over the wrapped object in its
- * current state: the value if the attribute still exists, otherwise no
- * entry at all. */
-
-static int WraptObjectProxy_refresh_cached_attr(WraptObjectProxyObject *self,
-                                                PyObject *wrapped,
-                                                PyObject *name)
-{
-  PyObject *object = PyObject_GetAttr(wrapped, name);
-
-  if (object)
-  {
-    int result = PyDict_SetItem(self->dict, name, object);
-    Py_DECREF(object);
-    return result;
-  }
-
-  if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-    return -1;
-
-  PyErr_Clear();
-
-  if (PyDict_DelItem(self->dict, name) == -1)
-  {
-    if (!PyErr_ExceptionMatches(PyExc_KeyError))
-      return -1;
-    PyErr_Clear();
-  }
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* The setters for __module__ and __doc__ are called with a NULL value when
- * the attribute is being deleted. PyObject_SetAttr() forwards a deletion to
- * the wrapped object, but the copy held in the proxy's own dict must then be
- * refreshed rather than stored, as the dict API rejects a NULL value. */
-
-static int WraptObjectProxy_set_module(WraptObjectProxyObject *self,
-                                       PyObject *value)
-{
-  int result;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  if (PyObject_SetAttr(wrapped, state->str_module, value) == -1)
-    result = -1;
-  else if (value)
-    result = PyDict_SetItem(self->dict, state->str_module, value);
-  else
-    result = WraptObjectProxy_refresh_cached_attr(self, wrapped,
-                                                  state->str_module);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_doc(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetAttr(wrapped, state->str_doc);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_set_doc(WraptObjectProxyObject *self,
-                                    PyObject *value)
-{
-  int result;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  if (PyObject_SetAttr(wrapped, state->str_doc, value) == -1)
-    result = -1;
-  else if (value)
-    result = PyDict_SetItem(self->dict, state->str_doc, value);
-  else
-    result = WraptObjectProxy_refresh_cached_attr(self, wrapped,
-                                                  state->str_doc);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_class(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetAttr(wrapped, state->str_dunder_class);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_set_class(WraptObjectProxyObject *self,
-                                      PyObject *value)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result = PyObject_SetAttr(wrapped, state->str_dunder_class, value);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptObjectProxy_get_annotations(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetAttr(wrapped, state->str_annotations);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_set_annotations(WraptObjectProxyObject *self,
-                                            PyObject *value)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result = PyObject_SetAttr(wrapped, state->str_annotations, value);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_dict(WraptObjectProxyObject *self)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_GetAttr(wrapped, state->str_dict);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_set_dict(WraptObjectProxyObject *self,
-                                     PyObject *value)
-{
-  if (!value)
-  {
-    PyErr_SetString(PyExc_AttributeError,
-                    "property '__dict__' of 'ObjectProxy' object has no deleter");
-    return -1;
-  }
-
-  PyErr_SetString(PyExc_AttributeError,
-                  "property '__dict__' of 'ObjectProxy' object has no setter");
-  return -1;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_self_dict(WraptObjectProxyObject *self)
-{
-  PyObject *result = NULL;
-
-  /* self->dict is only NULL after tp_clear has run. Perform the lazy
-   * recreation and the reference acquisition inside a critical section
-   * so that two threads racing here on a free-threaded build cannot both
-   * create a dict, leaking one of them, or return a dict which the other
-   * thread has already replaced. */
-
-  Py_BEGIN_CRITICAL_SECTION(self);
-  if (!self->dict)
-    self->dict = PyDict_New();
-  result = self->dict;
-  Py_XINCREF(result);
-  Py_END_CRITICAL_SECTION();
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_wrapped(WraptObjectProxyObject *self)
-{
-  PyObject *value = NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  value = wrapt_acquire_wrapped(self);
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_get_object_proxy(WraptObjectProxyObject *self)
-{
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-  Py_INCREF(state->ObjectProxy_Type);
-  return (PyObject *)state->ObjectProxy_Type;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_set_wrapped(WraptObjectProxyObject *self,
-                                        PyObject *value)
-{
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *fixups = NULL;
-
-  if (!value)
-  {
-    PyErr_SetString(PyExc_TypeError, "can't delete __wrapped__ attribute");
-    return -1;
-  }
-
-  /* On free-threaded builds the swap must be serialised, otherwise two
-   * threads assigning __wrapped__ on the same proxy can both read the same
-   * old value and both decref it, releasing it twice. The critical section
-   * covers only the swap; __wrapped_setattr_fixups__ below runs arbitrary
-   * Python code and must stay outside it. */
-
-  Py_INCREF(value);
-  Py_BEGIN_CRITICAL_SECTION(self);
-  Py_XSETREF(self->wrapped, value);
-  Py_END_CRITICAL_SECTION();
-
-  fixups = PyObject_GetAttr((PyObject *)self, state->str_setattr_fixups);
-
-  if (fixups)
-  {
-    PyObject *result = NULL;
-
-    result = PyObject_CallObject(fixups, NULL);
-    Py_DECREF(fixups);
-
-    if (!result)
-      return -1;
-
-    Py_DECREF(result);
-  }
-  else
-  {
-    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-      return -1;
-    PyErr_Clear();
-  }
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_getattro(WraptObjectProxyObject *self,
-                                           PyObject *name)
-{
-  PyObject *object = NULL;
-  PyObject *result = NULL;
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  /* Intercept __module__ and __doc__ so they proxy to the wrapped object.
-   * These cannot be getset descriptors on heap types because that would
-   * place a descriptor object in tp_dict, shadowing the type-level
-   * __module__/__doc__ strings that type.__module__ reads via raw dict
-   * lookup. */
-
-  if (wrapt_name_equals(name, state->str_module))
-    return WraptObjectProxy_get_module(self);
-  if (wrapt_name_equals(name, state->str_doc))
-  {
-    /* A derived class may define its own __doc__ descriptor, in which
-     * case that is consulted in place of the wrapped object. */
-
-    PyObject *descriptor = wrapt_lookup_doc_descriptor(Py_TYPE(self), name);
-
-    if (descriptor)
-    {
-      result = (Py_TYPE(descriptor)->tp_descr_get)(
-          descriptor, (PyObject *)self, (PyObject *)Py_TYPE(self));
-      Py_DECREF(descriptor);
-      return result;
-    }
-
-    return WraptObjectProxy_get_doc(self);
-  }
-
-  object = PyObject_GenericGetAttr((PyObject *)self, name);
-
-  if (object)
-    return object;
-
-  if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-    return NULL;
-
-  PyErr_Clear();
-
-  object = PyObject_GenericGetAttr((PyObject *)self, state->str_getattr);
-
-  if (!object)
-    return NULL;
-
-  result = PyObject_CallFunctionObjArgs(object, name, NULL);
-
-  Py_DECREF(object);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_getattr(WraptObjectProxyObject *self,
-                                          PyObject *args)
-{
-  PyObject *name = NULL;
-  PyObject *wrapped = NULL;
-  PyObject *result = NULL;
-
-  if (!PyArg_ParseTuple(args, "U:__getattr__", &name))
-    return NULL;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  /* Hold a strong reference across the attribute lookup so a concurrent
-   * swap of the wrapped object cannot release it mid lookup. Note this
-   * path is reached from the __wrapped__ setter itself via the lookup
-   * of __wrapped_setattr_fixups__, so even a workload consisting purely
-   * of writers performs this read. */
-
-  wrapped = wrapt_acquire_wrapped(self);
-
-  result = PyObject_GetAttr(wrapped, name);
-
-  Py_XDECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptObjectProxy_setattro(WraptObjectProxyObject *self,
-                                     PyObject *name, PyObject *value)
-{
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  int match = PyUnicode_Tailmatch(name, state->str_self_, 0, PY_SSIZE_T_MAX, -1);
-
-  if (match < 0)
-    return -1;
-
-  if (match)
-    return PyObject_GenericSetAttr((PyObject *)self, name, value);
-
-  /* Intercept __module__ and __doc__ so they forward to the wrapped
-   * object rather than being stored locally. Without this, the string
-   * values in the type dict (from PyType_FromModuleAndSpec) would cause
-   * wrapt_type_has_attr to match and GenericSetAttr to store locally. */
-
-  if (wrapt_name_equals(name, state->str_module))
-    return WraptObjectProxy_set_module(self, value);
-  if (wrapt_name_equals(name, state->str_doc))
-  {
-    /* A derived class may define its own __doc__ descriptor, in which
-     * case assignment and deletion go to it rather than being forwarded
-     * to the wrapped object. A descriptor without __set__ is stored
-     * against the instance as generic attribute assignment would. */
-
-    PyObject *descriptor = wrapt_lookup_doc_descriptor(Py_TYPE(self), name);
-
-    if (descriptor)
-    {
-      int result;
-
-      if (Py_TYPE(descriptor)->tp_descr_set)
-        result = (Py_TYPE(descriptor)->tp_descr_set)(descriptor,
-                                                     (PyObject *)self, value);
-      else
-        result = PyObject_GenericSetAttr((PyObject *)self, name, value);
-
-      Py_DECREF(descriptor);
-      return result;
-    }
-
-    return WraptObjectProxy_set_doc(self, value);
-  }
-
-  if (wrapt_type_has_attr(Py_TYPE(self), name))
-    return PyObject_GenericSetAttr((PyObject *)self, name, value);
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return -1;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  int result = PyObject_SetAttr(wrapped, name, value);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptObjectProxy_richcompare(WraptObjectProxyObject *self,
-                                              PyObject *other, int opcode)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_RichCompare(wrapped, other, opcode);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptObjectProxy_instancecheck(WraptObjectProxyObject *self,
-                               PyObject *instance)
-{
-  int check = 0;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  check = PyObject_IsInstance(instance, wrapped);
-
-  Py_DECREF(wrapped);
-
-  if (check < 0)
-  {
-    return NULL;
-  }
-
-  return PyBool_FromLong(check);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptObjectProxy_subclasscheck(WraptObjectProxyObject *self,
-                               PyObject *args)
-{
-  PyObject *subclass = NULL;
-  PyObject *object = NULL;
-
-  int check = 0;
-
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  if (!PyArg_ParseTuple(args, "O", &subclass))
-    return NULL;
-
-  wrapt_module_state *state =
-      wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  object = PyObject_GetAttr(subclass, state->str_wrapped);
-
-  if (!object)
-  {
-    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-      return NULL;
-    PyErr_Clear();
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  check = PyObject_IsSubclass(object ? object : subclass, wrapped);
-
-  Py_DECREF(wrapped);
-  Py_XDECREF(object);
-
-  if (check == -1)
-    return NULL;
-
-  return PyBool_FromLong(check);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyMethodDef WraptObjectProxy_methods[] = {
-    {"__self_setattr__", (PyCFunction)WraptObjectProxy_self_setattr,
-     METH_VARARGS, 0},
-    {"__dir__", (PyCFunction)WraptObjectProxy_dir, METH_NOARGS, 0},
-    {"__enter__", (PyCFunction)WraptObjectProxy_enter,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {"__exit__", (PyCFunction)WraptObjectProxy_exit,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {"__aenter__", (PyCFunction)WraptObjectProxy_aenter,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {"__aexit__", (PyCFunction)WraptObjectProxy_aexit,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {"__copy__", (PyCFunction)WraptObjectProxy_copy, METH_NOARGS, 0},
-    {"__deepcopy__", (PyCFunction)WraptObjectProxy_deepcopy,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {"__reduce__", (PyCFunction)WraptObjectProxy_reduce, METH_NOARGS, 0},
-    {"__getattr__", (PyCFunction)WraptObjectProxy_getattr, METH_VARARGS, 0},
-    {"__bytes__", (PyCFunction)WraptObjectProxy_bytes, METH_NOARGS, 0},
-    {"__format__", (PyCFunction)WraptObjectProxy_format, METH_VARARGS, 0},
-    {"__reversed__", (PyCFunction)WraptObjectProxy_reversed, METH_NOARGS, 0},
-    {"__round__", (PyCFunction)WraptObjectProxy_round,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {"__trunc__", (PyCFunction)WraptObjectProxy_trunc, METH_NOARGS, 0},
-    {"__floor__", (PyCFunction)WraptObjectProxy_floor, METH_NOARGS, 0},
-    {"__ceil__", (PyCFunction)WraptObjectProxy_ceil, METH_NOARGS, 0},
-    {"__complex__", (PyCFunction)WraptObjectProxy_complex, METH_NOARGS, 0},
-    {"__mro_entries__", (PyCFunction)WraptObjectProxy_mro_entries,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {"__instancecheck__", (PyCFunction)WraptObjectProxy_instancecheck,
-     METH_O, 0},
-    {"__subclasscheck__", (PyCFunction)WraptObjectProxy_subclasscheck,
-     METH_VARARGS, 0},
-    {"__class_getitem__", Py_GenericAlias, METH_O | METH_CLASS, 0},
-    {NULL, NULL},
-};
-
-static PyGetSetDef WraptObjectProxy_getset[] = {
-    {"__name__", (getter)WraptObjectProxy_get_name,
-     (setter)WraptObjectProxy_set_name, 0},
-    {"__qualname__", (getter)WraptObjectProxy_get_qualname,
-     (setter)WraptObjectProxy_set_qualname, 0},
-    {"__class__", (getter)WraptObjectProxy_get_class,
-     (setter)WraptObjectProxy_set_class, 0},
-    {"__annotations__", (getter)WraptObjectProxy_get_annotations,
-     (setter)WraptObjectProxy_set_annotations, 0},
-    {"__dict__", (getter)WraptObjectProxy_get_dict,
-     (setter)WraptObjectProxy_set_dict, 0},
-    {"__self_dict__", (getter)WraptObjectProxy_get_self_dict, 0, 0},
-    {"__wrapped__", (getter)WraptObjectProxy_get_wrapped,
-     (setter)WraptObjectProxy_set_wrapped, 0},
-    {"__object_proxy__", (getter)WraptObjectProxy_get_object_proxy, 0, 0},
-    {NULL},
-};
-
-static PyMemberDef WraptObjectProxy_members[] = {
-    {"__dictoffset__", T_PYSSIZET,
-     offsetof(WraptObjectProxyObject, dict), READONLY, NULL},
-    {"__weaklistoffset__", T_PYSSIZET,
-     offsetof(WraptObjectProxyObject, weakreflist), READONLY, NULL},
-    {NULL},
-};
-
-static PyType_Slot WraptObjectProxy_slots[] = {
-    {Py_tp_dealloc, WraptObjectProxy_dealloc},
-    {Py_tp_repr, WraptObjectProxy_repr},
-    {Py_tp_hash, WraptObjectProxy_hash},
-    {Py_tp_str, WraptObjectProxy_str},
-    {Py_tp_getattro, WraptObjectProxy_getattro},
-    {Py_tp_setattro, WraptObjectProxy_setattro},
-    {Py_tp_traverse, WraptObjectProxy_traverse},
-    {Py_tp_clear, WraptObjectProxy_clear},
-    {Py_tp_richcompare, WraptObjectProxy_richcompare},
-    {Py_tp_methods, WraptObjectProxy_methods},
-    {Py_tp_members, WraptObjectProxy_members},
-    {Py_tp_getset, WraptObjectProxy_getset},
-    {Py_tp_init, WraptObjectProxy_init},
-    {Py_tp_alloc, PyType_GenericAlloc},
-    {Py_tp_new, WraptObjectProxy_new},
-    {Py_tp_free, PyObject_GC_Del},
-    /* PyNumberMethods */
-    {Py_nb_add, WraptObjectProxy_add},
-    {Py_nb_subtract, WraptObjectProxy_subtract},
-    {Py_nb_multiply, WraptObjectProxy_multiply},
-    {Py_nb_remainder, WraptObjectProxy_remainder},
-    {Py_nb_divmod, WraptObjectProxy_divmod},
-    {Py_nb_power, WraptObjectProxy_power},
-    {Py_nb_negative, WraptObjectProxy_negative},
-    {Py_nb_positive, WraptObjectProxy_positive},
-    {Py_nb_absolute, WraptObjectProxy_absolute},
-    {Py_nb_bool, WraptObjectProxy_bool},
-    {Py_nb_invert, WraptObjectProxy_invert},
-    {Py_nb_lshift, WraptObjectProxy_lshift},
-    {Py_nb_rshift, WraptObjectProxy_rshift},
-    {Py_nb_and, WraptObjectProxy_and},
-    {Py_nb_xor, WraptObjectProxy_xor},
-    {Py_nb_or, WraptObjectProxy_or},
-    {Py_nb_int, WraptObjectProxy_long},
-    {Py_nb_float, WraptObjectProxy_float},
-    {Py_nb_inplace_add, WraptObjectProxy_inplace_add},
-    {Py_nb_inplace_subtract, WraptObjectProxy_inplace_subtract},
-    {Py_nb_inplace_multiply, WraptObjectProxy_inplace_multiply},
-    {Py_nb_inplace_remainder, WraptObjectProxy_inplace_remainder},
-    {Py_nb_inplace_power, WraptObjectProxy_inplace_power},
-    {Py_nb_inplace_lshift, WraptObjectProxy_inplace_lshift},
-    {Py_nb_inplace_rshift, WraptObjectProxy_inplace_rshift},
-    {Py_nb_inplace_and, WraptObjectProxy_inplace_and},
-    {Py_nb_inplace_xor, WraptObjectProxy_inplace_xor},
-    {Py_nb_inplace_or, WraptObjectProxy_inplace_or},
-    {Py_nb_floor_divide, WraptObjectProxy_floor_divide},
-    {Py_nb_true_divide, WraptObjectProxy_true_divide},
-    {Py_nb_inplace_floor_divide, WraptObjectProxy_inplace_floor_divide},
-    {Py_nb_inplace_true_divide, WraptObjectProxy_inplace_true_divide},
-    {Py_nb_index, WraptObjectProxy_index},
-    {Py_nb_matrix_multiply, WraptObjectProxy_matrix_multiply},
-    {Py_nb_inplace_matrix_multiply, WraptObjectProxy_inplace_matrix_multiply},
-    /* PySequenceMethods */
-    {Py_sq_length, WraptObjectProxy_length},
-    {Py_sq_contains, WraptObjectProxy_contains},
-    /* PyMappingMethods */
-    {Py_mp_length, WraptObjectProxy_length},
-    {Py_mp_subscript, WraptObjectProxy_getitem},
-    {Py_mp_ass_subscript, WraptObjectProxy_setitem},
-    {0, NULL},
-};
-
-static PyType_Spec WraptObjectProxy_spec = {
-    .name = "_wrappers.ObjectProxy",
-    .basicsize = sizeof(WraptObjectProxyObject),
-    .itemsize = 0,
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    .slots = WraptObjectProxy_slots,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptCallableObjectProxy_call(WraptObjectProxyObject *self,
-                                               PyObject *args, PyObject *kwds)
-{
-  if (!self->wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(self) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(self);
-
-  PyObject *result = PyObject_Call(wrapped, args, kwds);
-
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */;
-
-static PyType_Slot WraptCallableObjectProxy_slots[] = {
-    {Py_tp_dealloc, WraptObjectProxy_dealloc},
-    {Py_tp_traverse, WraptObjectProxy_traverse},
-    {Py_tp_clear, WraptObjectProxy_clear},
-    {Py_tp_call, WraptCallableObjectProxy_call},
-    {Py_tp_init, WraptObjectProxy_init},
-    {0, NULL},
-};
-
-static PyType_Spec WraptCallableObjectProxy_spec = {
-    .name = "_wrappers.CallableObjectProxy",
-    .basicsize = sizeof(WraptObjectProxyObject),
-    .itemsize = 0,
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    .slots = WraptCallableObjectProxy_slots,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptPartialCallableObjectProxy_new(PyTypeObject *type,
-                                                     PyObject *args,
-                                                     PyObject *kwds)
-{
-  WraptPartialCallableObjectProxyObject *self;
-
-  self = (WraptPartialCallableObjectProxyObject *)WraptObjectProxy_new(
-      type, args, kwds);
-
-  if (!self)
-    return NULL;
-
-  self->args = NULL;
-  self->kwargs = NULL;
-
-  return (PyObject *)self;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptPartialCallableObjectProxy_raw_init(
-    WraptPartialCallableObjectProxyObject *self, PyObject *wrapped,
-    PyObject *args, PyObject *kwargs)
-{
-  int result = 0;
-
-  result = WraptObjectProxy_raw_init((WraptObjectProxyObject *)self, wrapped);
-
-  if (result == 0)
-  {
-    /* Serialise the swaps for the same reason as in the __wrapped__
-     * setter. Initialisation normally happens before the proxy is shared,
-     * but __init__ can be re-invoked on an already published proxy, in
-     * which case concurrent callers on a free-threaded build could
-     * otherwise decref the same old args or kwargs twice. */
-
-    Py_INCREF(args);
-    Py_XINCREF(kwargs);
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_XSETREF(self->args, args);
-    Py_XSETREF(self->kwargs, kwargs);
-    Py_END_CRITICAL_SECTION();
-  }
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptPartialCallableObjectProxy_init(
-    WraptPartialCallableObjectProxyObject *self, PyObject *args,
-    PyObject *kwds)
-{
-  PyObject *wrapped = NULL;
-  PyObject *fnargs = NULL;
-
-  int result = 0;
-
-  if (PyTuple_GET_SIZE(args) < 1)
-  {
-    PyErr_SetString(PyExc_TypeError, "__init__ of partial needs an argument");
-    return -1;
-  }
-
-  wrapped = PyTuple_GetItem(args, 0);
-
-  if (!PyCallable_Check(wrapped))
-  {
-    PyErr_SetString(PyExc_TypeError, "the first argument must be callable");
-    return -1;
-  }
-
-  fnargs = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
-
-  if (!fnargs)
-    return -1;
-
-  result =
-      WraptPartialCallableObjectProxy_raw_init(self, wrapped, fnargs, kwds);
-
-  Py_DECREF(fnargs);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptPartialCallableObjectProxy_traverse(
-    WraptPartialCallableObjectProxyObject *self, visitproc visit, void *arg)
-{
-  int err = WraptObjectProxy_traverse((WraptObjectProxyObject *)self, visit, arg);
-  if (err)
-    return err;
-
-  Py_VISIT(self->args);
-  Py_VISIT(self->kwargs);
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptPartialCallableObjectProxy_clear(
-    WraptPartialCallableObjectProxyObject *self)
-{
-  WraptObjectProxy_clear((WraptObjectProxyObject *)self);
-
-  Py_CLEAR(self->args);
-  Py_CLEAR(self->kwargs);
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void WraptPartialCallableObjectProxy_dealloc(
-    WraptPartialCallableObjectProxyObject *self)
-{
-  PyTypeObject *tp = Py_TYPE(self);
-
-  PyObject_GC_UnTrack(self);
-
-  if (self->object_proxy.weakreflist != NULL)
-    PyObject_ClearWeakRefs((PyObject *)self);
-
-  WraptPartialCallableObjectProxy_clear(self);
-
-  tp->tp_free(self);
-
-#if PY_VERSION_HEX >= 0x030C0000
-  PyObject *exc = PyErr_GetRaisedException();
-  Py_DECREF(tp);
-  PyErr_SetRaisedException(exc);
-#else
-  PyObject *exc_type, *exc_value, *exc_tb;
-  PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
-  Py_DECREF(tp);
-  PyErr_Restore(exc_type, exc_value, exc_tb);
-#endif
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptPartialCallableObjectProxy_call(
-    WraptPartialCallableObjectProxyObject *self, PyObject *args,
-    PyObject *kwds)
-{
-  PyObject *fnargs = NULL;
-  PyObject *fnkwargs = NULL;
-
-  PyObject *result = NULL;
-
-  long i;
-  long offset;
-
-  if (!self->object_proxy.wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
-      return NULL;
-  }
-
-  /* Hold strong references to the wrapped object and the captured
-   * arguments across the call so a concurrent re-initialization of the
-   * partial cannot release them while they are in use. */
-
-  PyObject *wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-  PyObject *cargs = wrapt_acquire_field((PyObject *)self, &self->args);
-  PyObject *ckwargs = wrapt_acquire_field((PyObject *)self, &self->kwargs);
-
-  /* The captured keyword arguments are legitimately NULL when none were
-   * supplied, so only the captured positional arguments are required. */
-
-  if (wrapt_require_field((PyObject *)self, cargs, "_self_args") == -1)
-    goto finally;
-
-  fnargs = PyTuple_New(PyTuple_GET_SIZE(cargs) + PyTuple_GET_SIZE(args));
-
-  if (!fnargs)
-    goto finally;
-
-  for (i = 0; i < PyTuple_GET_SIZE(cargs); i++)
-  {
-    PyObject *item;
-    item = PyTuple_GetItem(cargs, i);
-    Py_INCREF(item);
-    PyTuple_SetItem(fnargs, i, item);
-  }
-
-  offset = PyTuple_GET_SIZE(cargs);
-
-  for (i = 0; i < PyTuple_GET_SIZE(args); i++)
-  {
-    PyObject *item;
-    item = PyTuple_GetItem(args, i);
-    Py_INCREF(item);
-    PyTuple_SetItem(fnargs, offset + i, item);
-  }
-
-  fnkwargs = PyDict_New();
-
-  if (!fnkwargs)
-    goto finally;
-
-  if (ckwargs && PyDict_Update(fnkwargs, ckwargs) == -1)
-    goto finally;
-
-  if (kwds && PyDict_Update(fnkwargs, kwds) == -1)
-    goto finally;
-
-  result = PyObject_Call(wrapped, fnargs, fnkwargs);
-
-finally:
-  Py_XDECREF(fnargs);
-  Py_XDECREF(fnkwargs);
-
-  Py_DECREF(wrapped);
-  Py_XDECREF(cargs);
-  Py_XDECREF(ckwargs);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */;
-
-static PyObject *WraptPartialCallableObjectProxy_get_self_args(
-    WraptPartialCallableObjectProxyObject *self, void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->args);
-
-  /* See the comment for the equivalent getters of the function wrapper
-   * as to why this fails rather than substituting an empty tuple. */
-
-  if (wrapt_require_field((PyObject *)self, value, "_self_args") == -1)
-    return NULL;
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptPartialCallableObjectProxy_get_self_kwargs(
-    WraptPartialCallableObjectProxyObject *self, void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->kwargs);
-
-  if (!value)
-  {
-    /* The captured keyword arguments are legitimately NULL when none were
-     * supplied, in which case an empty dictionary stands in for them. That
-     * must be distinguished from __init__() never having been called, for
-     * which the captured positional arguments, which are always set by
-     * __init__(), will be NULL as well. */
-
-    PyObject *args = wrapt_acquire_field((PyObject *)self, &self->args);
-
-    if (wrapt_require_field((PyObject *)self, args, "_self_kwargs") == -1)
-      return NULL;
-
-    Py_DECREF(args);
-
-    return PyDict_New();
-  }
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* Report the signature of the wrapped callable with the bound positional
- * and keyword arguments removed, matching what inspect.signature() reports
- * for functools.partial. This is done by constructing an equivalent
- * functools.partial and asking inspect for its signature, so that the
- * result, including any ValueError for excess bound arguments, is exactly
- * what functools.partial would give. */
-
-static PyObject *WraptPartialCallableObjectProxy_get_signature(
-    WraptPartialCallableObjectProxyObject *self)
-{
-  PyObject *module = NULL;
-  PyObject *function = NULL;
-  PyObject *fnargs = NULL;
-  PyObject *partial = NULL;
-  PyObject *result = NULL;
-
-  Py_ssize_t nargs = 0;
-  Py_ssize_t i;
-
-  if (!self->object_proxy.wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
-      return NULL;
-  }
-
-  PyObject *wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-  PyObject *cargs = wrapt_acquire_field((PyObject *)self, &self->args);
-  PyObject *ckwargs = wrapt_acquire_field((PyObject *)self, &self->kwargs);
-
-  if (cargs)
-    nargs = PyTuple_GET_SIZE(cargs);
-
-  /* Build the tuple (wrapped, *args) to pass to functools.partial(). */
-
-  fnargs = PyTuple_New(nargs + 1);
-
-  if (!fnargs)
-    goto finally;
-
-  Py_INCREF(wrapped);
-  PyTuple_SET_ITEM(fnargs, 0, wrapped);
-
-  for (i = 0; i < nargs; i++)
-  {
-    PyObject *item = PyTuple_GET_ITEM(cargs, i);
-    Py_INCREF(item);
-    PyTuple_SET_ITEM(fnargs, i + 1, item);
-  }
-
-  module = PyImport_ImportModule("functools");
-
-  if (!module)
-    goto finally;
-
-  function = PyObject_GetAttrString(module, "partial");
-
-  Py_CLEAR(module);
-
-  if (!function)
-    goto finally;
-
-  partial = PyObject_Call(function, fnargs, ckwargs);
-
-  Py_CLEAR(function);
-
-  if (!partial)
-    goto finally;
-
-  module = PyImport_ImportModule("inspect");
-
-  if (!module)
-    goto finally;
-
-  function = PyObject_GetAttrString(module, "signature");
-
-  Py_CLEAR(module);
-
-  if (!function)
-    goto finally;
-
-  result = PyObject_CallFunctionObjArgs(function, partial, NULL);
-
-finally:
-  Py_XDECREF(function);
-  Py_XDECREF(partial);
-  Py_XDECREF(fnargs);
-
-  Py_XDECREF(ckwargs);
-  Py_XDECREF(cargs);
-  Py_DECREF(wrapped);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* The __signature__ attribute is intercepted here rather than being a
- * getset descriptor for the same reason as __module__ and __doc__ on the
- * base object proxy. A descriptor would be visible on the type itself and
- * inspect.signature() applied to the type would then fail on finding a
- * descriptor object where it expects a Signature. Handling it in getattro
- * makes it visible on instances only, which is all that inspect needs. */
-
-static PyObject *WraptPartialCallableObjectProxy_getattro(
-    WraptPartialCallableObjectProxyObject *self, PyObject *name)
-{
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  if (wrapt_name_equals(name, state->str_signature))
-    return WraptPartialCallableObjectProxy_get_signature(self);
-
-  return WraptObjectProxy_getattro((WraptObjectProxyObject *)self, name);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyGetSetDef WraptPartialCallableObjectProxy_getset[] = {
-    {"_self_args", (getter)WraptPartialCallableObjectProxy_get_self_args, NULL,
-     0},
-    {"_self_kwargs", (getter)WraptPartialCallableObjectProxy_get_self_kwargs,
-     NULL, 0},
-    {NULL},
-};
-
-static PyType_Slot WraptPartialCallableObjectProxy_slots[] = {
-    {Py_tp_dealloc, WraptPartialCallableObjectProxy_dealloc},
-    {Py_tp_call, WraptPartialCallableObjectProxy_call},
-    {Py_tp_traverse, WraptPartialCallableObjectProxy_traverse},
-    {Py_tp_clear, WraptPartialCallableObjectProxy_clear},
-    {Py_tp_getset, WraptPartialCallableObjectProxy_getset},
-    {Py_tp_getattro, WraptPartialCallableObjectProxy_getattro},
-    {Py_tp_init, WraptPartialCallableObjectProxy_init},
-    {Py_tp_new, WraptPartialCallableObjectProxy_new},
-    {0, NULL},
-};
-
-static PyType_Spec WraptPartialCallableObjectProxy_spec = {
-    .name = "_wrappers.PartialCallableObjectProxy",
-    .basicsize = sizeof(WraptPartialCallableObjectProxyObject),
-    .itemsize = 0,
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    .slots = WraptPartialCallableObjectProxy_slots,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptFunctionWrapperBase_new(PyTypeObject *type,
-                                              PyObject *args, PyObject *kwds)
-{
-  WraptFunctionWrapperObject *self;
-
-  self = (WraptFunctionWrapperObject *)WraptObjectProxy_new(type, args, kwds);
-
-  if (!self)
-    return NULL;
-
-  self->instance = NULL;
-  self->wrapper = NULL;
-  self->enabled = NULL;
-  self->binding = NULL;
-  self->parent = NULL;
-  self->owner = NULL;
-
-  return (PyObject *)self;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptFunctionWrapperBase_raw_init(
-    WraptFunctionWrapperObject *self, PyObject *wrapped, PyObject *instance,
-    PyObject *wrapper, PyObject *enabled, PyObject *binding, PyObject *parent,
-    PyObject *owner)
-{
-  int result = 0;
-
-  result = WraptObjectProxy_raw_init((WraptObjectProxyObject *)self, wrapped);
-
-  if (result == 0)
-  {
-    /* Serialise the swaps for the same reason as in the __wrapped__
-     * setter. These fields have no setters, so re-invocation of __init__
-     * on an already published wrapper is the only path by which
-     * concurrent callers on a free-threaded build could otherwise decref
-     * the same old field values twice. */
-
-    Py_INCREF(instance);
-    Py_INCREF(wrapper);
-    Py_INCREF(enabled);
-    Py_INCREF(binding);
-    Py_INCREF(parent);
-    Py_INCREF(owner);
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    Py_XSETREF(self->instance, instance);
-    Py_XSETREF(self->wrapper, wrapper);
-    Py_XSETREF(self->enabled, enabled);
-    Py_XSETREF(self->binding, binding);
-    Py_XSETREF(self->parent, parent);
-    Py_XSETREF(self->owner, owner);
-    Py_END_CRITICAL_SECTION();
-  }
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptFunctionWrapperBase_init(WraptFunctionWrapperObject *self,
-                                         PyObject *args, PyObject *kwds)
-{
-  PyObject *wrapped = NULL;
-  PyObject *instance = NULL;
-  PyObject *wrapper = NULL;
-  PyObject *enabled = Py_None;
-  PyObject *binding = NULL;
-  PyObject *parent = Py_None;
-  PyObject *owner = Py_None;
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  char *const kwlist[] = {"wrapped", "instance", "wrapper", "enabled",
-                          "binding", "parent", "owner", NULL};
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|OOOO:FunctionWrapperBase",
-                                   kwlist, &wrapped, &instance, &wrapper,
-                                   &enabled, &binding, &parent, &owner))
-  {
-    return -1;
-  }
-
-  if (!binding)
-    binding = state->str_callable;
-
-  return WraptFunctionWrapperBase_raw_init(self, wrapped, instance, wrapper,
-                                           enabled, binding, parent, owner);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptFunctionWrapperBase_traverse(WraptFunctionWrapperObject *self,
-                                             visitproc visit, void *arg)
-{
-  int err = WraptObjectProxy_traverse((WraptObjectProxyObject *)self, visit, arg);
-  if (err)
-    return err;
-
-  Py_VISIT(self->instance);
-  Py_VISIT(self->wrapper);
-  Py_VISIT(self->enabled);
-  Py_VISIT(self->binding);
-  Py_VISIT(self->parent);
-  Py_VISIT(self->owner);
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptFunctionWrapperBase_clear(WraptFunctionWrapperObject *self)
-{
-  WraptObjectProxy_clear((WraptObjectProxyObject *)self);
-
-  Py_CLEAR(self->instance);
-  Py_CLEAR(self->wrapper);
-  Py_CLEAR(self->enabled);
-  Py_CLEAR(self->binding);
-  Py_CLEAR(self->parent);
-  Py_CLEAR(self->owner);
-
-  return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void WraptFunctionWrapperBase_dealloc(WraptFunctionWrapperObject *self)
-{
-  PyTypeObject *tp = Py_TYPE(self);
-
-  PyObject_GC_UnTrack(self);
-
-  if (self->object_proxy.weakreflist != NULL)
-    PyObject_ClearWeakRefs((PyObject *)self);
-
-  WraptFunctionWrapperBase_clear(self);
-
-  tp->tp_free(self);
-
-#if PY_VERSION_HEX >= 0x030C0000
-  PyObject *exc = PyErr_GetRaisedException();
-  Py_DECREF(tp);
-  PyErr_SetRaisedException(exc);
-#else
-  PyObject *exc_type, *exc_value, *exc_tb;
-  PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
-  Py_DECREF(tp);
-  PyErr_Restore(exc_type, exc_value, exc_tb);
-#endif
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptFunctionWrapperBase_call(WraptFunctionWrapperObject *self,
-                                               PyObject *args, PyObject *kwds)
-{
-  PyObject *param_kwds = NULL;
-
-  PyObject *wrapped = NULL;
-  PyObject *instance = NULL;
-  PyObject *wrapper = NULL;
-  PyObject *enabled = NULL;
-  PyObject *binding = NULL;
-
-  PyObject *result = NULL;
-
-  if (!self->object_proxy.wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  /* Hold strong references to the fields used across the call so a
-   * concurrent re-initialization of the wrapper cannot release them
-   * while in use. Fields are acquired independently, so a consistent
-   * snapshot across all of them is not guaranteed, as documented. */
-
-  wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-  instance = wrapt_acquire_field((PyObject *)self, &self->instance);
-  wrapper = wrapt_acquire_field((PyObject *)self, &self->wrapper);
-  enabled = wrapt_acquire_field((PyObject *)self, &self->enabled);
-  binding = wrapt_acquire_field((PyObject *)self, &self->binding);
-
-  if (wrapt_require_field((PyObject *)self, instance, "_self_instance") == -1 ||
-      wrapt_require_field((PyObject *)self, wrapper, "_self_wrapper") == -1 ||
-      wrapt_require_field((PyObject *)self, enabled, "_self_enabled") == -1 ||
-      wrapt_require_field((PyObject *)self, binding, "_self_binding") == -1)
-    goto finally;
-
-  if (enabled != Py_None)
-  {
-    if (PyCallable_Check(enabled))
-    {
-      PyObject *object = NULL;
-      int is_false;
-
-      object = PyObject_CallFunctionObjArgs(enabled, NULL);
-
-      if (!object)
-        goto finally;
-
-      is_false = PyObject_Not(object);
-      Py_DECREF(object);
-
-      if (is_false < 0)
-        goto finally;
-
-      if (is_false)
-      {
-        result = PyObject_Call(wrapped, args, kwds);
-        goto finally;
-      }
-    }
-    else
-    {
-      int is_false = PyObject_Not(enabled);
-
-      if (is_false < 0)
-        goto finally;
-
-      if (is_false)
-      {
-        result = PyObject_Call(wrapped, args, kwds);
-        goto finally;
-      }
-    }
-  }
-
-  if (!kwds)
-  {
-    param_kwds = PyDict_New();
-    if (!param_kwds)
-      goto finally;
-    kwds = param_kwds;
-  }
-
-  if (instance == Py_None)
-  {
-    int matched =
-        PyUnicode_CompareWithASCIIString(binding, "function") == 0 ||
-        PyUnicode_CompareWithASCIIString(binding, "instancemethod") == 0 ||
-        PyUnicode_CompareWithASCIIString(binding, "callable") == 0 ||
-        PyUnicode_CompareWithASCIIString(binding, "classmethod") == 0;
-
-    if (matched)
-    {
-      PyObject *bound_instance = NULL;
-
-      bound_instance = PyObject_GetAttr(wrapped, state->str_self);
-
-      if (bound_instance)
-      {
-        result = PyObject_CallFunctionObjArgs(wrapper, wrapped, bound_instance,
-                                              args, kwds, NULL);
-
-        Py_DECREF(bound_instance);
-
-        goto finally;
-      }
-      else
-      {
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-          goto finally;
-        PyErr_Clear();
-      }
-    }
-  }
-
-  result = PyObject_CallFunctionObjArgs(wrapper, wrapped, instance, args, kwds,
-                                        NULL);
-
-finally:
-  Py_XDECREF(param_kwds);
-
-  Py_DECREF(wrapped);
-  Py_XDECREF(instance);
-  Py_XDECREF(wrapper);
-  Py_XDECREF(enabled);
-  Py_XDECREF(binding);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptFunctionWrapperBase_descr_get(WraptFunctionWrapperObject *self,
-                                   PyObject *obj, PyObject *type)
-{
-  PyObject *bound_type = NULL;
-  PyObject *descriptor = NULL;
-
-  PyObject *wrapped = NULL;
-  PyObject *instance = NULL;
-  PyObject *wrapper = NULL;
-  PyObject *enabled = NULL;
-  PyObject *binding = NULL;
-  PyObject *parent = NULL;
-
-  PyObject *result = NULL;
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *bound_type_str = state->str_bound_function_wrapper;
-
-  if (!self->object_proxy.wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
-      return NULL;
-  }
-
-  /* Hold strong references to the fields used across the binding so a
-   * concurrent re-initialization of the wrapper cannot release them
-   * while in use. Fields are acquired independently, so a consistent
-   * snapshot across all of them is not guaranteed, as documented. */
-
-  wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-  instance = wrapt_acquire_field((PyObject *)self, &self->instance);
-  wrapper = wrapt_acquire_field((PyObject *)self, &self->wrapper);
-  enabled = wrapt_acquire_field((PyObject *)self, &self->enabled);
-  binding = wrapt_acquire_field((PyObject *)self, &self->binding);
-  parent = wrapt_acquire_field((PyObject *)self, &self->parent);
-
-  if (wrapt_require_field((PyObject *)self, instance, "_self_instance") == -1 ||
-      wrapt_require_field((PyObject *)self, wrapper, "_self_wrapper") == -1 ||
-      wrapt_require_field((PyObject *)self, enabled, "_self_enabled") == -1 ||
-      wrapt_require_field((PyObject *)self, binding, "_self_binding") == -1 ||
-      wrapt_require_field((PyObject *)self, parent, "_self_parent") == -1)
-    goto finally;
-
-  if (parent == Py_None)
-  {
-    if (PyUnicode_CompareWithASCIIString(binding, "builtin") == 0)
-    {
-      Py_INCREF(self);
-      result = (PyObject *)self;
-      goto finally;
-    }
-
-    if (PyUnicode_CompareWithASCIIString(binding, "class") == 0)
-    {
-      Py_INCREF(self);
-      result = (PyObject *)self;
-      goto finally;
-    }
-
-    if (Py_TYPE(wrapped)->tp_descr_get == NULL)
-    {
-      Py_INCREF(self);
-      result = (PyObject *)self;
-      goto finally;
-    }
-
-    descriptor = (Py_TYPE(wrapped)->tp_descr_get)(wrapped, obj, type);
-
-    if (!descriptor)
-      goto finally;
-
-    if (Py_TYPE(self) != state->FunctionWrapper_Type)
-    {
-      bound_type = PyObject_GenericGetAttr((PyObject *)self, bound_type_str);
-
-      if (!bound_type)
-      {
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-          goto finally;
-        PyErr_Clear();
-      }
-    }
-
-    if (obj == NULL)
-      obj = Py_None;
-
-    result = PyObject_CallFunctionObjArgs(
-        bound_type ? bound_type : (PyObject *)state->BoundFunctionWrapper_Type,
-        descriptor, obj, wrapper, enabled, binding, self, type, NULL);
-
-    goto finally;
-  }
-
-  if (instance == Py_None)
-  {
-    int matched =
-        PyUnicode_CompareWithASCIIString(binding, "function") == 0 ||
-        PyUnicode_CompareWithASCIIString(binding, "instancemethod") == 0 ||
-        PyUnicode_CompareWithASCIIString(binding, "callable") == 0;
-
-    if (matched)
-    {
-      PyObject *parent_wrapped = NULL;
-
-      if (PyObject_TypeCheck(parent, state->ObjectProxy_Type))
-      {
-        WraptObjectProxyObject *parent_proxy = (WraptObjectProxyObject *)parent;
-
-        if (!parent_proxy->wrapped)
-        {
-          if (raise_uninitialized_wrapper_error(parent_proxy) == -1)
-            goto finally;
-        }
-
-        parent_wrapped = wrapt_acquire_wrapped(parent_proxy);
-      }
-      else
-      {
-        /* Fallback for the unusual case where parent is not a wrapt proxy. */
-        parent_wrapped = PyObject_GetAttr(parent, state->str_wrapped);
-
-        if (!parent_wrapped)
-          goto finally;
-      }
-
-      if (Py_TYPE(parent_wrapped)->tp_descr_get == NULL)
-      {
-        PyErr_Format(PyExc_AttributeError,
-                     "'%s' object has no attribute '__get__'",
-                     Py_TYPE(parent_wrapped)->tp_name);
-        Py_DECREF(parent_wrapped);
-        goto finally;
-      }
-
-      descriptor =
-          (Py_TYPE(parent_wrapped)->tp_descr_get)(parent_wrapped, obj, type);
-
-      Py_DECREF(parent_wrapped);
-
-      if (!descriptor)
-        goto finally;
-
-      if (Py_TYPE(parent) != state->FunctionWrapper_Type)
-      {
-        bound_type = PyObject_GenericGetAttr(parent, bound_type_str);
-
-        if (!bound_type)
-        {
-          if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-            goto finally;
-          PyErr_Clear();
-        }
-      }
-
-      if (obj == NULL)
-        obj = Py_None;
-
-      result = PyObject_CallFunctionObjArgs(
-          bound_type ? bound_type : (PyObject *)state->BoundFunctionWrapper_Type,
-          descriptor, obj, wrapper, enabled, binding, parent, type, NULL);
-
-      goto finally;
-    }
-  }
-
-  Py_INCREF(self);
-  result = (PyObject *)self;
-
-finally:
-  Py_XDECREF(bound_type);
-  Py_XDECREF(descriptor);
-
-  Py_DECREF(wrapped);
-  Py_XDECREF(instance);
-  Py_XDECREF(wrapper);
-  Py_XDECREF(enabled);
-  Py_XDECREF(binding);
-  Py_XDECREF(parent);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptFunctionWrapperBase_set_name(WraptFunctionWrapperObject *self,
-                                  PyObject *args, PyObject *kwds)
-{
-  PyObject *method = NULL;
-  PyObject *result = NULL;
-
-  if (!self->object_proxy.wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state =
-      wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  PyObject *wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-
-  method = PyObject_GetAttr(wrapped, state->str_set_name);
-
-  Py_DECREF(wrapped);
-
-  if (!method)
-  {
-    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-      return NULL;
-    PyErr_Clear();
-    Py_RETURN_NONE;
-  }
-
-  result = PyObject_Call(method, args, kwds);
-
-  Py_DECREF(method);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* The getters for the wrapper specific fields fail with AttributeError if
- * the field was never set, which means __init__() was not called. The
- * attribute lookup then falls through to __getattr__() and so on to the
- * wrapped object, which is the same outcome as for the pure Python
- * implementation, where these are instance attributes which in that case
- * do not exist. A value of None is not substituted, as that is a valid
- * value for most of these fields and so would be indistinguishable from
- * the state of a wrapper which had been initialized. */
-
-static PyObject *
-WraptFunctionWrapperBase_get_self_instance(WraptFunctionWrapperObject *self,
-                                           void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->instance);
-
-  if (wrapt_require_field((PyObject *)self, value, "_self_instance") == -1)
-    return NULL;
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptFunctionWrapperBase_get_self_wrapper(WraptFunctionWrapperObject *self,
-                                          void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->wrapper);
-
-  if (wrapt_require_field((PyObject *)self, value, "_self_wrapper") == -1)
-    return NULL;
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptFunctionWrapperBase_get_self_enabled(WraptFunctionWrapperObject *self,
-                                          void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->enabled);
-
-  if (wrapt_require_field((PyObject *)self, value, "_self_enabled") == -1)
-    return NULL;
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptFunctionWrapperBase_get_self_binding(WraptFunctionWrapperObject *self,
-                                          void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->binding);
-
-  if (wrapt_require_field((PyObject *)self, value, "_self_binding") == -1)
-    return NULL;
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptFunctionWrapperBase_get_self_parent(WraptFunctionWrapperObject *self,
-                                         void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->parent);
-
-  if (wrapt_require_field((PyObject *)self, value, "_self_parent") == -1)
-    return NULL;
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptFunctionWrapperBase_get_self_owner(WraptFunctionWrapperObject *self,
-                                        void *closure)
-{
-  PyObject *value = NULL;
-
-  value = wrapt_acquire_field((PyObject *)self, &self->owner);
-
-  if (wrapt_require_field((PyObject *)self, value, "_self_owner") == -1)
-    return NULL;
-
-  return value;
-}
-
-/* ------------------------------------------------------------------------- */;
-
-static PyMethodDef WraptFunctionWrapperBase_methods[] = {
-    {"__set_name__", (PyCFunction)WraptFunctionWrapperBase_set_name,
-     METH_VARARGS | METH_KEYWORDS, 0},
-    {NULL, NULL},
-};
-
-/* ------------------------------------------------------------------------- */;
-
-static PyGetSetDef WraptFunctionWrapperBase_getset[] = {
-    {"_self_instance", (getter)WraptFunctionWrapperBase_get_self_instance, NULL,
-     0},
-    {"_self_wrapper", (getter)WraptFunctionWrapperBase_get_self_wrapper, NULL,
-     0},
-    {"_self_enabled", (getter)WraptFunctionWrapperBase_get_self_enabled, NULL,
-     0},
-    {"_self_binding", (getter)WraptFunctionWrapperBase_get_self_binding, NULL,
-     0},
-    {"_self_parent", (getter)WraptFunctionWrapperBase_get_self_parent, NULL, 0},
-    {"_self_owner", (getter)WraptFunctionWrapperBase_get_self_owner, NULL, 0},
-    {NULL},
-};
-
-static PyType_Slot WraptFunctionWrapperBase_slots[] = {
-    {Py_tp_dealloc, WraptFunctionWrapperBase_dealloc},
-    {Py_tp_call, WraptFunctionWrapperBase_call},
-    {Py_tp_traverse, WraptFunctionWrapperBase_traverse},
-    {Py_tp_clear, WraptFunctionWrapperBase_clear},
-    {Py_tp_methods, WraptFunctionWrapperBase_methods},
-    {Py_tp_getset, WraptFunctionWrapperBase_getset},
-    {Py_tp_descr_get, WraptFunctionWrapperBase_descr_get},
-    {Py_tp_init, WraptFunctionWrapperBase_init},
-    {Py_tp_new, WraptFunctionWrapperBase_new},
-    {0, NULL},
-};
-
-static PyType_Spec WraptFunctionWrapperBase_spec = {
-    .name = "_wrappers._FunctionWrapperBase",
-    .basicsize = sizeof(WraptFunctionWrapperObject),
-    .itemsize = 0,
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    .slots = WraptFunctionWrapperBase_slots,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *
-WraptBoundFunctionWrapper_call(WraptFunctionWrapperObject *self, PyObject *args,
-                               PyObject *kwds)
-{
-  PyObject *param_args = NULL;
-  PyObject *param_kwds = NULL;
-
-  PyObject *wrapped = NULL;
-  PyObject *instance = NULL;
-  PyObject *wrapper = NULL;
-  PyObject *enabled = NULL;
-  PyObject *binding = NULL;
-  PyObject *owner = NULL;
-
-  PyObject *call_instance = NULL;
-
-  PyObject *result = NULL;
-
-  int matched;
-
-  if (!self->object_proxy.wrapped)
-  {
-    if (raise_uninitialized_wrapper_error(&self->object_proxy) == -1)
-      return NULL;
-  }
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return NULL;
-
-  /* Hold strong references to the fields used across the call so a
-   * concurrent re-initialization of the wrapper cannot release them
-   * while in use. Fields are acquired independently, so a consistent
-   * snapshot across all of them is not guaranteed, as documented. The
-   * call_instance local always holds an owned reference to whichever
-   * instance value is passed through to the wrapper. */
-
-  instance = wrapt_acquire_field((PyObject *)self, &self->instance);
-  wrapper = wrapt_acquire_field((PyObject *)self, &self->wrapper);
-  enabled = wrapt_acquire_field((PyObject *)self, &self->enabled);
-  binding = wrapt_acquire_field((PyObject *)self, &self->binding);
-  owner = wrapt_acquire_field((PyObject *)self, &self->owner);
-
-  if (wrapt_require_field((PyObject *)self, instance, "_self_instance") == -1 ||
-      wrapt_require_field((PyObject *)self, wrapper, "_self_wrapper") == -1 ||
-      wrapt_require_field((PyObject *)self, enabled, "_self_enabled") == -1 ||
-      wrapt_require_field((PyObject *)self, binding, "_self_binding") == -1 ||
-      wrapt_require_field((PyObject *)self, owner, "_self_owner") == -1)
-    goto finally;
-
-  if (enabled != Py_None)
-  {
-    if (PyCallable_Check(enabled))
-    {
-      PyObject *object = NULL;
-      int is_false;
-
-      object = PyObject_CallFunctionObjArgs(enabled, NULL);
-
-      if (!object)
-        goto finally;
-
-      is_false = PyObject_Not(object);
-      Py_DECREF(object);
-
-      if (is_false < 0)
-        goto finally;
-
-      if (is_false)
-      {
-        wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-        result = PyObject_Call(wrapped, args, kwds);
-        goto finally;
-      }
-    }
-    else
-    {
-      int is_false = PyObject_Not(enabled);
-
-      if (is_false < 0)
-        goto finally;
-
-      if (is_false)
-      {
-        wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-        result = PyObject_Call(wrapped, args, kwds);
-        goto finally;
-      }
-    }
-  }
-
-  /*
-   * We need to do things different depending on whether we are likely
-   * wrapping an instance method vs a static method or class method.
-   */
-
-  matched =
-      PyUnicode_CompareWithASCIIString(binding, "function") == 0 ||
-      PyUnicode_CompareWithASCIIString(binding, "callable") == 0;
-
-  if (matched)
-  {
-
-    if (instance == Py_None && PyTuple_GET_SIZE(args) != 0)
-    {
-      /*
-       * This situation can occur where someone is calling the
-       * instancemethod via the class type and passing the
-       * instance as the first argument. We need to shift the args
-       * before making the call to the wrapper and effectively
-       * bind the instance to the wrapped function using a partial
-       * so the wrapper doesn't see anything as being different.
-       */
-
-      call_instance = PyTuple_GetItem(args, 0);
-
-      if (!call_instance)
-        goto finally;
-
-      Py_INCREF(call_instance);
-
-      int check = PyObject_IsInstance(call_instance, owner);
-
-      if (check < 0)
-        goto finally;
-
-      if (check)
-      {
-        PyObject *inner_wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-
-        wrapped = PyObject_CallFunctionObjArgs(
-            (PyObject *)state->PartialCallableObjectProxy_Type,
-            inner_wrapped, call_instance, NULL);
-
-        Py_DECREF(inner_wrapped);
-
-        if (!wrapped)
-          goto finally;
-
-        param_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));
-
-        if (!param_args)
-          goto finally;
-
-        args = param_args;
-      }
-      else
-      {
-        Py_DECREF(call_instance);
-        call_instance = instance;
-        Py_XINCREF(call_instance);
-      }
-    }
-    else
-    {
-      call_instance = instance;
-      Py_XINCREF(call_instance);
-    }
-
-    if (!wrapped)
-    {
-      wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-    }
-
-    if (!kwds)
-    {
-      param_kwds = PyDict_New();
-      if (!param_kwds)
-        goto finally;
-      kwds = param_kwds;
-    }
-
-    result = PyObject_CallFunctionObjArgs(wrapper, wrapped, call_instance,
-                                          args, kwds, NULL);
-  }
-  else
-  {
-    /*
-     * As in this case we would be dealing with a classmethod or
-     * staticmethod, then _self_instance will only tell us whether
-     * when calling the classmethod or staticmethod they did it via
-     * an instance of the class it is bound to and not the case
-     * where done by the class type itself. We thus ignore
-     * _self_instance and use the __self__ attribute of the bound
-     * function instead. For a classmethod, this means instance will
-     * be the class type and for a staticmethod it will be None.
-     * This is probably the more useful thing we can pass through
-     * even though we loose knowledge of whether they were called on
-     * the instance vs the class type, as it reflects what they have
-     * available in the decoratored function.
-     */
-
-    wrapped = wrapt_acquire_wrapped(&self->object_proxy);
-
-    call_instance = PyObject_GetAttr(wrapped, state->str_self);
-
-    if (!call_instance)
-    {
-      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-        goto finally;
-      PyErr_Clear();
-      Py_INCREF(Py_None);
-      call_instance = Py_None;
-    }
-
-    if (!kwds)
-    {
-      param_kwds = PyDict_New();
-      if (!param_kwds)
-        goto finally;
-      kwds = param_kwds;
-    }
-
-    result = PyObject_CallFunctionObjArgs(wrapper, wrapped, call_instance,
-                                          args, kwds, NULL);
-  }
-
-finally:
-  Py_XDECREF(param_args);
-  Py_XDECREF(param_kwds);
-
-  Py_XDECREF(call_instance);
-
-  Py_XDECREF(wrapped);
-  Py_XDECREF(instance);
-  Py_XDECREF(wrapper);
-  Py_XDECREF(enabled);
-  Py_XDECREF(binding);
-  Py_XDECREF(owner);
-
-  return result;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyObject *WraptBoundFunctionWrapper_getattr(
-    WraptFunctionWrapperObject *self, PyObject *args)
-{
-  PyObject *name = NULL;
-
-  if (!PyArg_ParseTuple(args, "U:__getattr__", &name))
-    return NULL;
-
-  PyObject *parent = wrapt_acquire_field((PyObject *)self, &self->parent);
-
-  if (parent && parent != Py_None)
-  {
-    PyObject *result = PyObject_GetAttr(parent, name);
-
-    if (result)
-    {
-      Py_DECREF(parent);
-      return result;
-    }
-
-    if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-    {
-      Py_DECREF(parent);
-      return NULL;
-    }
-
-    PyErr_Clear();
-  }
-
-  Py_XDECREF(parent);
-
-  return WraptObjectProxy_getattr((WraptObjectProxyObject *)self, args);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptBoundFunctionWrapper_setattro(
-    WraptFunctionWrapperObject *self, PyObject *name, PyObject *value)
-{
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  int match = PyUnicode_Tailmatch(name, state->str_self_, 0, PY_SSIZE_T_MAX, -1);
-
-  if (match < 0)
-    return -1;
-
-  if (match)
-  {
-    /* Check if this is an internal slot (has a getset descriptor on the type) */
-    if (wrapt_type_has_attr(Py_TYPE(self), name))
-      return PyObject_GenericSetAttr((PyObject *)self, name, value);
-
-    /* User-defined _self_ attribute — delegate to parent */
-    PyObject *parent = wrapt_acquire_field((PyObject *)self, &self->parent);
-
-    if (parent && parent != Py_None)
-    {
-      int result = PyObject_GenericSetAttr(parent, name, value);
-
-      Py_DECREF(parent);
-
-      return result;
-    }
-
-    Py_XDECREF(parent);
-  }
-
-  /* Fall through to base ObjectProxy setattro for everything else */
-  return WraptObjectProxy_setattro((WraptObjectProxyObject *)self, name, value);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyMethodDef WraptBoundFunctionWrapper_methods[] = {
-    {"__getattr__", (PyCFunction)WraptBoundFunctionWrapper_getattr, METH_VARARGS,
-     0},
-    {NULL, NULL},
-};
-
-/* ------------------------------------------------------------------------- */
-
-static PyType_Slot WraptBoundFunctionWrapper_slots[] = {
-    {Py_tp_dealloc, WraptFunctionWrapperBase_dealloc},
-    {Py_tp_traverse, WraptFunctionWrapperBase_traverse},
-    {Py_tp_clear, WraptFunctionWrapperBase_clear},
-    {Py_tp_call, WraptBoundFunctionWrapper_call},
-    {Py_tp_setattro, WraptBoundFunctionWrapper_setattro},
-    {Py_tp_methods, WraptBoundFunctionWrapper_methods},
-    {0, NULL},
-};
-
-static PyType_Spec WraptBoundFunctionWrapper_spec = {
-    .name = "_wrappers.BoundFunctionWrapper",
-    .basicsize = sizeof(WraptFunctionWrapperObject),
-    .itemsize = 0,
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    .slots = WraptBoundFunctionWrapper_slots,
-};
-
-/* ------------------------------------------------------------------------- */
-
-static int WraptFunctionWrapper_init(WraptFunctionWrapperObject *self,
-                                     PyObject *args, PyObject *kwds)
-{
-  PyObject *wrapped = NULL;
-  PyObject *wrapper = NULL;
-  PyObject *enabled = Py_None;
-  PyObject *binding = NULL;
-  PyObject *binding_owned = NULL;
-  PyObject *instance = NULL;
-
-  wrapt_module_state *state = wrapt_state_from_type(Py_TYPE(self));
-  if (!state)
-    return -1;
-
-  PyObject *function_str = state->str_function;
-  PyObject *classmethod_str = state->str_classmethod;
-  PyObject *staticmethod_str = state->str_staticmethod;
-  PyObject *callable_str = state->str_callable;
-  PyObject *builtin_str = state->str_builtin;
-  PyObject *class_str = state->str_class;
-  PyObject *instancemethod_str = state->str_instancemethod;
-
-  int result = 0;
-
-  char *const kwlist[] = {"wrapped", "wrapper", "enabled", NULL};
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:FunctionWrapper", kwlist,
-                                   &wrapped, &wrapper, &enabled))
-  {
-    return -1;
-  }
-
-  if (PyObject_TypeCheck(wrapped, state->FunctionWrapperBase_Type))
-  {
-    binding_owned = PyObject_GetAttr(wrapped, state->str_self_binding);
-    if (!binding_owned)
-    {
-      if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-        return -1;
-      PyErr_Clear();
-    }
-    else
-    {
-      binding = binding_owned;
-    }
-  }
-
-  if (!binding)
-  {
-    int check;
-
-    if (PyCFunction_Check(wrapped))
-    {
-      binding = builtin_str;
-    }
-    else
-    {
-      check = PyObject_IsInstance(wrapped, (PyObject *)&PyFunction_Type);
-      if (check < 0)
-        goto error;
-      if (check)
-        binding = function_str;
-    }
-
-    if (!binding)
-    {
-      check = PyObject_IsInstance(wrapped, (PyObject *)&PyType_Type);
-      if (check < 0)
-        goto error;
-      if (check)
-        binding = class_str;
-    }
-
-    if (!binding)
-    {
-      check = PyObject_IsInstance(wrapped, (PyObject *)&PyClassMethod_Type);
-      if (check < 0)
-        goto error;
-      if (check)
-        binding = classmethod_str;
-    }
-
-    if (!binding)
-    {
-      check = PyObject_IsInstance(wrapped, (PyObject *)&PyStaticMethod_Type);
-      if (check < 0)
-        goto error;
-      if (check)
-        binding = staticmethod_str;
-    }
-
-    if (!binding)
-    {
-      instance = PyObject_GetAttr(wrapped, state->str_self);
-      if (instance != NULL)
-      {
-        check = PyObject_IsInstance(instance, (PyObject *)&PyType_Type);
-        if (check < 0)
-        {
-          Py_DECREF(instance);
-          goto error;
-        }
-        if (check)
-        {
-          binding = classmethod_str;
-        }
-        else
-        {
-          check = PyObject_IsInstance(wrapped, (PyObject *)&PyMethod_Type);
-          if (check < 0)
-          {
-            Py_DECREF(instance);
-            goto error;
-          }
-          if (check)
-            binding = instancemethod_str;
-          else
-            binding = callable_str;
-        }
-
-        Py_DECREF(instance);
-      }
-      else
-      {
-        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
-          goto error;
-        PyErr_Clear();
-
-        binding = callable_str;
-      }
-    }
-  }
-
-  result = WraptFunctionWrapperBase_raw_init(
-      self, wrapped, Py_None, wrapper, enabled, binding, Py_None, Py_None);
-
-  Py_XDECREF(binding_owned);
-
-  return result;
-
-error:
-  Py_XDECREF(binding_owned);
-  return -1;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static PyType_Slot WraptFunctionWrapper_slots[] = {
-    {Py_tp_dealloc, WraptFunctionWrapperBase_dealloc},
-    {Py_tp_traverse, WraptFunctionWrapperBase_traverse},
-    {Py_tp_clear, WraptFunctionWrapperBase_clear},
-    {Py_tp_init, WraptFunctionWrapper_init},
-    {0, NULL},
-};
-
-static PyType_Spec WraptFunctionWrapper_spec = {
-    .name = "_wrappers.FunctionWrapper",
-    .basicsize = sizeof(WraptFunctionWrapperObject),
-    .itemsize = 0,
-    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    .slots = WraptFunctionWrapper_slots,
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* PyModule_AddObjectRef polyfill for Python 3.9. */
-#if PY_VERSION_HEX >= 0x030A0000
-#define WRAPT_ADD_TYPE(mod, name, type)                               \
-  do                                                                  \
-  {                                                                   \
-    if (PyModule_AddObjectRef((mod), (name), (PyObject *)(type)) < 0) \
-      return -1;                                                      \
-  } while (0)
-#else
-#define WRAPT_ADD_TYPE(mod, name, type)                            \
-  do                                                               \
-  {                                                                \
-    Py_INCREF((PyObject *)(type));                                 \
-    if (PyModule_AddObject((mod), (name), (PyObject *)(type)) < 0) \
-    {                                                              \
-      Py_DECREF((PyObject *)(type));                               \
-      return -1;                                                   \
-    }                                                              \
-  } while (0)
-#endif
-
-/* Helper to create a heap type via PyType_FromModuleAndSpecWithBases and
- * store it on the module. Returns 0 on success, -1 on failure. */
-
-static int wrapt_create_type(PyObject *module, PyTypeObject **out,
-                             PyType_Spec *spec, PyObject *bases,
-                             const char *name)
-{
-  PyObject *type;
-
-  type = PyType_FromModuleAndSpec(module, spec, bases);
-  if (type == NULL)
-    return -1;
-
-  /* PyType_FromModuleAndSpec returns a new reference. Add the type to
-   * the module dict first (WRAPT_ADD_TYPE adds another ref via
-   * PyModule_AddObjectRef on 3.10+, or via manual incref +
-   * PyModule_AddObject on 3.9). Only then store the owned reference
-   * in module state so that *out is never populated on failure. */
-
-  WRAPT_ADD_TYPE(module, name, type);
-
-  *out = (PyTypeObject *)type;
-
-  return 0;
-}
-
-/* Helper: intern a C string into the given module-state slot. Returns 0
- * on success, -1 on failure (with PyErr set). */
-
-static int wrapt_intern_string(PyObject **slot, const char *s)
-{
-  PyObject *o = PyUnicode_InternFromString(s);
-  if (o == NULL)
-    return -1;
-  *slot = o;
-  return 0;
-}
-
-static int wrapt_init_strings(wrapt_module_state *state)
-{
-  if (wrapt_intern_string(&state->str_wrapped, "__wrapped__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_wrapped_factory,
-                          "__wrapped_factory__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_wrapped_get, "__wrapped_get__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_module, "__module__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_doc, "__doc__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_setattr_fixups,
-                          "__wrapped_setattr_fixups__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_getattr, "__getattr__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_self_, "_self_") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_callable, "callable") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_bound_function_wrapper,
-                          "__bound_function_wrapper__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_function, "function") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_classmethod, "classmethod") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_staticmethod, "staticmethod") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_builtin, "builtin") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_class, "class") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_instancemethod, "instancemethod") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_object_proxy, "__object_proxy__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_enter, "__enter__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_exit, "__exit__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_aenter, "__aenter__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_aexit, "__aexit__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_mro_entries, "__mro_entries__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_name, "__name__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_qualname, "__qualname__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_annotations, "__annotations__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_dunder_class, "__class__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_self, "__self__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_set_name, "__set_name__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_signature, "__signature__") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_self_binding, "_self_binding") < 0)
-    return -1;
-  if (wrapt_intern_string(&state->str_dict, "__dict__") < 0)
-    return -1;
-  return 0;
-}
-
-static int wrapt_exec(PyObject *module)
-{
-  wrapt_module_state *state = wrapt_get_state(module);
-  PyObject *bases = NULL;
-
-  /* Eagerly intern all cached strings. m_clear releases anything that
-   * was set before a failure, so we can return -1 on the first error. */
-  if (wrapt_init_strings(state) < 0)
-    return -1;
-
-  /* ObjectProxy: base = object (default). */
-  if (wrapt_create_type(module, &state->ObjectProxy_Type,
-                        &WraptObjectProxy_spec, NULL, "ObjectProxy") < 0)
-    return -1;
-
-  /* CallableObjectProxy: base = ObjectProxy. */
-  bases = PyTuple_Pack(1, (PyObject *)state->ObjectProxy_Type);
-  if (!bases)
-    return -1;
-  if (wrapt_create_type(module, &state->CallableObjectProxy_Type,
-                        &WraptCallableObjectProxy_spec, bases,
-                        "CallableObjectProxy") < 0)
-  {
-    Py_DECREF(bases);
-    return -1;
-  }
-  Py_DECREF(bases);
-
-  /* PartialCallableObjectProxy: base = ObjectProxy. */
-  bases = PyTuple_Pack(1, (PyObject *)state->ObjectProxy_Type);
-  if (!bases)
-    return -1;
-  if (wrapt_create_type(module, &state->PartialCallableObjectProxy_Type,
-                        &WraptPartialCallableObjectProxy_spec, bases,
-                        "PartialCallableObjectProxy") < 0)
-  {
-    Py_DECREF(bases);
-    return -1;
-  }
-  Py_DECREF(bases);
-
-  /* _FunctionWrapperBase: base = ObjectProxy. */
-  bases = PyTuple_Pack(1, (PyObject *)state->ObjectProxy_Type);
-  if (!bases)
-    return -1;
-  if (wrapt_create_type(module, &state->FunctionWrapperBase_Type,
-                        &WraptFunctionWrapperBase_spec, bases,
-                        "_FunctionWrapperBase") < 0)
-  {
-    Py_DECREF(bases);
-    return -1;
-  }
-  Py_DECREF(bases);
-
-  /* BoundFunctionWrapper: base = _FunctionWrapperBase. */
-  bases = PyTuple_Pack(1, (PyObject *)state->FunctionWrapperBase_Type);
-  if (!bases)
-    return -1;
-  if (wrapt_create_type(module, &state->BoundFunctionWrapper_Type,
-                        &WraptBoundFunctionWrapper_spec, bases,
-                        "BoundFunctionWrapper") < 0)
-  {
-    Py_DECREF(bases);
-    return -1;
-  }
-  Py_DECREF(bases);
-
-  /* FunctionWrapper: base = _FunctionWrapperBase. */
-  bases = PyTuple_Pack(1, (PyObject *)state->FunctionWrapperBase_Type);
-  if (!bases)
-    return -1;
-  if (wrapt_create_type(module, &state->FunctionWrapper_Type,
-                        &WraptFunctionWrapper_spec, bases,
-                        "FunctionWrapper") < 0)
-  {
-    Py_DECREF(bases);
-    return -1;
-  }
-  Py_DECREF(bases);
-
-  /* Cache WrapperNotInitializedError from wrapt.exceptions. The module is
-   * already in sys.modules because wrapt.wrappers imports it before
-   * __wrapt__.py imports us. */
-
-  {
-    PyObject *wrapt_exceptions_module =
-        PyImport_ImportModule("wrapt.exceptions");
-    if (!wrapt_exceptions_module)
-      return -1;
-
-    state->WrapperNotInitializedError = PyObject_GetAttrString(
-        wrapt_exceptions_module, "WrapperNotInitializedError");
-
-    Py_DECREF(wrapt_exceptions_module);
-
-    if (!state->WrapperNotInitializedError)
-      return -1;
-  }
-
-  return 0;
-}
-
-static int wrapt_traverse(PyObject *module, visitproc visit, void *arg)
-{
-  wrapt_module_state *state = wrapt_get_state(module);
-  if (state == NULL)
-    return 0;
-  Py_VISIT(state->ObjectProxy_Type);
-  Py_VISIT(state->CallableObjectProxy_Type);
-  Py_VISIT(state->PartialCallableObjectProxy_Type);
-  Py_VISIT(state->FunctionWrapperBase_Type);
-  Py_VISIT(state->BoundFunctionWrapper_Type);
-  Py_VISIT(state->FunctionWrapper_Type);
-  Py_VISIT(state->str_wrapped);
-  Py_VISIT(state->str_wrapped_factory);
-  Py_VISIT(state->str_wrapped_get);
-  Py_VISIT(state->str_module);
-  Py_VISIT(state->str_doc);
-  Py_VISIT(state->str_setattr_fixups);
-  Py_VISIT(state->str_getattr);
-  Py_VISIT(state->str_self_);
-  Py_VISIT(state->str_callable);
-  Py_VISIT(state->str_bound_function_wrapper);
-  Py_VISIT(state->str_function);
-  Py_VISIT(state->str_classmethod);
-  Py_VISIT(state->str_staticmethod);
-  Py_VISIT(state->str_builtin);
-  Py_VISIT(state->str_class);
-  Py_VISIT(state->str_instancemethod);
-  Py_VISIT(state->str_object_proxy);
-  Py_VISIT(state->str_enter);
-  Py_VISIT(state->str_exit);
-  Py_VISIT(state->str_aenter);
-  Py_VISIT(state->str_aexit);
-  Py_VISIT(state->str_mro_entries);
-  Py_VISIT(state->str_name);
-  Py_VISIT(state->str_qualname);
-  Py_VISIT(state->str_annotations);
-  Py_VISIT(state->str_dunder_class);
-  Py_VISIT(state->str_self);
-  Py_VISIT(state->str_set_name);
-  Py_VISIT(state->str_self_binding);
-  Py_VISIT(state->str_signature);
-  Py_VISIT(state->str_dict);
-  Py_VISIT(state->WrapperNotInitializedError);
-  return 0;
-}
-
-static int wrapt_clear(PyObject *module)
-{
-  wrapt_module_state *state = wrapt_get_state(module);
-  if (state == NULL)
-    return 0;
-  Py_CLEAR(state->ObjectProxy_Type);
-  Py_CLEAR(state->CallableObjectProxy_Type);
-  Py_CLEAR(state->PartialCallableObjectProxy_Type);
-  Py_CLEAR(state->FunctionWrapperBase_Type);
-  Py_CLEAR(state->BoundFunctionWrapper_Type);
-  Py_CLEAR(state->FunctionWrapper_Type);
-  Py_CLEAR(state->str_wrapped);
-  Py_CLEAR(state->str_wrapped_factory);
-  Py_CLEAR(state->str_wrapped_get);
-  Py_CLEAR(state->str_module);
-  Py_CLEAR(state->str_doc);
-  Py_CLEAR(state->str_setattr_fixups);
-  Py_CLEAR(state->str_getattr);
-  Py_CLEAR(state->str_self_);
-  Py_CLEAR(state->str_callable);
-  Py_CLEAR(state->str_bound_function_wrapper);
-  Py_CLEAR(state->str_function);
-  Py_CLEAR(state->str_classmethod);
-  Py_CLEAR(state->str_staticmethod);
-  Py_CLEAR(state->str_builtin);
-  Py_CLEAR(state->str_class);
-  Py_CLEAR(state->str_instancemethod);
-  Py_CLEAR(state->str_object_proxy);
-  Py_CLEAR(state->str_enter);
-  Py_CLEAR(state->str_exit);
-  Py_CLEAR(state->str_aenter);
-  Py_CLEAR(state->str_aexit);
-  Py_CLEAR(state->str_mro_entries);
-  Py_CLEAR(state->str_name);
-  Py_CLEAR(state->str_qualname);
-  Py_CLEAR(state->str_annotations);
-  Py_CLEAR(state->str_dunder_class);
-  Py_CLEAR(state->str_self);
-  Py_CLEAR(state->str_set_name);
-  Py_CLEAR(state->str_self_binding);
-  Py_CLEAR(state->str_signature);
-  Py_CLEAR(state->str_dict);
-  Py_CLEAR(state->WrapperNotInitializedError);
-  return 0;
-}
-
-static void wrapt_free(void *module)
-{
-  (void)wrapt_clear((PyObject *)module);
-}
-
-static PyModuleDef_Slot wrapt_slots[] = {
-    {Py_mod_exec, wrapt_exec},
-#if PY_VERSION_HEX >= 0x030C0000
-    /* Per-interpreter GIL support (PEP 684, 3.12+). All process-wide
-     * mutable state has been removed: types are heap types created per
-     * interpreter via PyType_FromModuleAndSpec, cached strings live in
-     * per-interpreter module state, and there are no static PyObject *
-     * globals. */
-    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
-#endif
-#if PY_VERSION_HEX >= 0x030D0000
-    /* Free-threading support (3.13+). The previous Py_MOD_GIL_NOT_USED
-     * declaration via PyUnstable_Module_SetGIL was unsound because the
-     * 19 cached interned strings were lazily initialized via racy
-     * static locals. With eager init in wrapt_exec the declaration is
-     * now actually correct. */
-    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
-#endif
-    {0, NULL},
-};
-
-static struct PyModuleDef moduledef = {
-    PyModuleDef_HEAD_INIT,
-    .m_name = "_wrappers",
-    .m_doc = NULL,
-    .m_size = sizeof(wrapt_module_state),
-    .m_methods = NULL,
-    .m_slots = wrapt_slots,
-    .m_traverse = wrapt_traverse,
-    .m_clear = wrapt_clear,
-    .m_free = wrapt_free,
-};
-
-PyMODINIT_FUNC PyInit__wrappers(void)
-{
-  return PyModuleDef_Init(&moduledef);
-}
-
-/* ------------------------------------------------------------------------- */
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py
deleted file mode 100644
index 2ded470d25f..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/arguments.py
+++ /dev/null
@@ -1,55 +0,0 @@
-"""The inspect.formatargspec() function was dropped in Python 3.11 but we need
-it for when constructing signature changing decorators based on result of
-inspect.getfullargspec(). The code here implements inspect.formatargspec() based
-on Parameter and Signature from inspect module, which were added in Python 3.6.
-Thanks to Cyril Jouve for the implementation.
-"""
-
-from inspect import Parameter, Signature
-from typing import Any, Callable, List, Mapping, Optional, Sequence, Tuple
-
-
-def formatargspec(
-    args: List[str],
-    varargs: Optional[str] = None,
-    varkw: Optional[str] = None,
-    defaults: Optional[Tuple[Any, ...]] = None,
-    kwonlyargs: Optional[Sequence[str]] = None,
-    kwonlydefaults: Optional[Mapping[str, Any]] = None,
-    annotations: Mapping[str, Any] = {},
-    formatarg: Callable[[str], str] = str,
-    formatvarargs: Callable[[str], str] = lambda name: "*" + name,
-    formatvarkw: Callable[[str], str] = lambda name: "**" + name,
-    formatvalue: Callable[[Any], str] = lambda value: "=" + repr(value),
-    formatreturns: Callable[[Any], str] = lambda text: " -> " + text,
-    formatannotation: Callable[[Any], str] = lambda annot: " -> " + repr(annot),
-) -> str:
-    if kwonlyargs is None:
-        kwonlyargs = ()
-    if kwonlydefaults is None:
-        kwonlydefaults = {}
-    ndefaults = len(defaults) if defaults else 0
-    parameters = [
-        Parameter(
-            arg,
-            Parameter.POSITIONAL_OR_KEYWORD,
-            default=defaults[i] if defaults and i >= 0 else Parameter.empty,
-            annotation=annotations.get(arg, Parameter.empty),
-        )
-        for i, arg in enumerate(args, ndefaults - len(args))
-    ]
-    if varargs:
-        parameters.append(Parameter(varargs, Parameter.VAR_POSITIONAL))
-    parameters.extend(
-        Parameter(
-            kwonlyarg,
-            Parameter.KEYWORD_ONLY,
-            default=kwonlydefaults.get(kwonlyarg, Parameter.empty),
-            annotation=annotations.get(kwonlyarg, Parameter.empty),
-        )
-        for kwonlyarg in kwonlyargs
-    )
-    if varkw:
-        parameters.append(Parameter(varkw, Parameter.VAR_KEYWORD))
-    return_annotation = annotations.get("return", Signature.empty)
-    return str(Signature(parameters, return_annotation=return_annotation))
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py
deleted file mode 100644
index 4ef0e19be49..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/caching.py
+++ /dev/null
@@ -1,234 +0,0 @@
-"""Caching decorators. Currently provides ``lru_cache``, a drop-in
-replacement for ``functools.lru_cache`` with correct handling of instance
-methods: a separate cache is maintained per instance, stored as an
-attribute on the instance itself so it is cleaned up with the instance
-by the garbage collector. For plain functions, class methods, and static
-methods a single shared cache is used, matching ``functools.lru_cache``.
-"""
-
-from functools import lru_cache as _functools_lru_cache
-from functools import partial
-
-from .__wrapt__ import BaseObjectProxy, BoundFunctionWrapper, FunctionWrapper
-from .decorators import decorator
-from .synchronization import synchronized
-
-# Decorator that applies functools.lru_cache to the wrapped function.
-# Unlike using functools.lru_cache directly, this works correctly with
-# instance methods and class methods by maintaining a separate cache
-# per instance or class. Each per-instance cache is stored as an
-# attribute on the instance itself, so it is automatically cleaned up
-# when the instance is garbage collected. For plain functions and
-# static methods, a single cache is stored on the wrapper itself.
-# The underlying caches are created lazily on first call, with
-# double-checked locking via synchronized to avoid races in
-# multi-threaded code.
-#
-# Custom FunctionWrapper and BoundFunctionWrapper subclasses are used
-# so that cache_info() and cache_clear() are available directly on
-# the decorated function. For bound methods, the BoundFunctionWrapper
-# uses _self_instance to locate the per-instance cache.
-
-
-class _BoundLRUCacheFunctionWrapper(BoundFunctionWrapper):
-
-    def _is_instance_method(self):
-        return self._self_binding == "function"
-
-    def __call__(self, *args, **kwargs):
-        parent = self._self_parent
-
-        # For class methods and static methods, use a single shared
-        # cache stored on the parent wrapper. The cache is created
-        # from the bound __wrapped__ since the parent's __wrapped__
-        # is the raw classmethod/staticmethod descriptor.
-
-        if not self._is_instance_method():
-            if parent._self_cache is None:
-                with synchronized(parent):
-                    if parent._self_cache is None:
-                        parent._self_cache = _functools_lru_cache(
-                            **parent._self_lru_kwargs
-                        )(self.__wrapped__)
-
-            return parent._self_cache(*args, **kwargs)
-
-        # Instance method — per-instance cache stored as an attribute
-        # on the instance so it is cleaned up with the instance by the
-        # garbage collector.
-
-        instance = self._self_instance
-        cache_attr = parent._self_cache_attr
-
-        cache = getattr(instance, cache_attr, None)
-
-        if cache is None:
-            with synchronized(parent):
-                cache = getattr(instance, cache_attr, None)
-
-                if cache is None:
-                    cache = _functools_lru_cache(**parent._self_lru_kwargs)(
-                        self.__wrapped__
-                    )
-
-                    # If the instance the method is bound to is a wrapt
-                    # object proxy, a plain setattr() would fall through and
-                    # store the cache on the wrapped object rather than the
-                    # proxy. Use type() rather than isinstance() so the check
-                    # sees the real proxy type and is not fooled by the proxy
-                    # overriding __class__ to report the wrapped object's
-                    # type. Proxies expose __self_setattr__() which stores the
-                    # attribute on the proxy itself.
-
-                    if issubclass(type(instance), BaseObjectProxy):
-                        instance.__self_setattr__(cache_attr, cache)
-                    else:
-                        setattr(instance, cache_attr, cache)
-
-        return cache(*args, **kwargs)
-
-    def cache_info(self):
-        """Return the cache statistics for this binding's cache, or
-        ``None`` if the cache has not yet been created.
-        """
-
-        if not self._is_instance_method():
-            return self._self_parent.cache_info()
-
-        cache = getattr(self._self_instance, self._self_parent._self_cache_attr, None)
-
-        if cache is not None:
-            return cache.cache_info()
-
-        return None
-
-    def cache_clear(self):
-        """Clear this binding's cache."""
-
-        if not self._is_instance_method():
-            self._self_parent.cache_clear()
-            return
-
-        cache = getattr(self._self_instance, self._self_parent._self_cache_attr, None)
-
-        if cache is not None:
-            cache.cache_clear()
-
-    def cache_parameters(self):
-        """Return the parameters used to create the cache."""
-
-        if not self._is_instance_method():
-            return self._self_parent.cache_parameters()
-
-        cache = getattr(self._self_instance, self._self_parent._self_cache_attr, None)
-
-        if cache is not None:
-            return cache.cache_parameters()
-
-        return None
-
-
-class _LRUCacheFunctionWrapper(FunctionWrapper):
-
-    __bound_function_wrapper__ = _BoundLRUCacheFunctionWrapper
-
-    def __init__(self, wrapped, wrapper, **kwargs):
-        super().__init__(wrapped, wrapper, **kwargs)
-
-        # Extract the LRU cache configuration that was attached to the
-        # wrapper function before it was passed to the decorator.
-
-        self._self_lru_kwargs = wrapper._self_lru_kwargs
-        self._self_cache = None
-
-        # Use __func__ to get the name for classmethod/staticmethod
-        # descriptors which lack __name__ on Python < 3.10.
-
-        name = getattr(wrapped, "__name__", None)
-
-        if name is None:
-            name = wrapped.__func__.__name__
-
-        # The cache attribute name must be unique per decorated method so
-        # that a method overridden in a subclass does not share the same
-        # per-instance cache slot as the method it overrides. If they shared
-        # a slot, a subclass method calling super() would find the subclass
-        # cache and re-enter its own body, recursing forever. The owning
-        # class is not known here, since the decorator runs on the raw
-        # function before the class exists, but each decorated method has its
-        # own wrapper instance, so id(self) is a stable discriminator unique
-        # to this method definition.
-
-        self._self_cache_attr = "_lru_cache_" + name + "_" + str(id(self))
-
-    def __call__(self, *args, **kwargs):
-        # Plain function or static method — single cache stored
-        # on the wrapper itself.
-
-        if self._self_cache is None:
-            with synchronized(self):
-                if self._self_cache is None:
-                    self._self_cache = _functools_lru_cache(**self._self_lru_kwargs)(
-                        self.__wrapped__
-                    )
-
-        return self._self_cache(*args, **kwargs)
-
-    def cache_info(self):
-        """Return the cache statistics, or ``None`` if the cache has
-        not yet been created.
-        """
-
-        if self._self_cache is not None:
-            return self._self_cache.cache_info()
-
-        return None
-
-    def cache_clear(self):
-        """Clear the cache and reset the statistics."""
-
-        if self._self_cache is not None:
-            self._self_cache.cache_clear()
-
-    def cache_parameters(self):
-        """Return the parameters used to create the cache, or ``None``
-        if the cache has not yet been created.
-        """
-
-        if self._self_cache is not None:
-            return self._self_cache.cache_parameters()
-
-        return None
-
-
-def lru_cache(func=None, /, **kwargs):
-    """A decorator that applies ``functools.lru_cache`` to the wrapped
-    function, with correct handling for instance methods, class methods,
-    and static methods.
-
-    For instance methods, a separate ``functools.lru_cache`` is
-    maintained per instance. The cache is stored as an attribute on the
-    instance itself, so it is automatically cleaned up when the instance
-    is garbage collected. This means instances do not need to be
-    hashable, each instance gets its own full ``maxsize`` budget, and
-    no external mapping prevents garbage collection.
-
-    For plain functions, class methods, and static methods, a single
-    shared cache is used.
-
-    All keyword arguments are passed through to ``functools.lru_cache``.
-
-    Cache management methods ``cache_info()`` and ``cache_clear()`` are
-    available directly on the decorated function. For bound methods,
-    these operate on the per-instance cache for the bound instance.
-    """
-
-    if func is None:
-        return partial(lru_cache, **kwargs)
-
-    def _wrapper(wrapped, instance, args, _kwargs):
-        return wrapped(*args, **_kwargs)
-
-    _wrapper._self_lru_kwargs = kwargs
-
-    return decorator(_wrapper, proxy=_LRUCacheFunctionWrapper)(func)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py
deleted file mode 100644
index 4c52b5d294b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/decorators.py
+++ /dev/null
@@ -1,488 +0,0 @@
-"""This module implements decorators for implementing other decorators
-as well as some commonly used decorators.
-
-"""
-
-from functools import partial
-from inspect import isclass, signature
-
-from .__wrapt__ import (
-    BaseObjectProxy,
-    BoundFunctionWrapper,
-    CallableObjectProxy,
-    FunctionWrapper,
-)
-from .arguments import formatargspec
-
-# Adapter wrapper for the wrapped function which will overlay certain
-# properties from the adapter function onto the wrapped function so that
-# functions such as inspect.getfullargspec(), inspect.signature() and
-# inspect.getsource() return the correct results one would expect.
-
-
-class _AdapterFunctionCode(CallableObjectProxy):
-
-    def __init__(self, wrapped_code, adapter_code):
-        # Explicit class in super() is used because the proxy overrides
-        # __class__ and MRO-related methods to delegate to the wrapped
-        # object, which can interfere with bare super().
-        super(_AdapterFunctionCode, self).__init__(wrapped_code)
-        self._self_adapter_code = adapter_code
-
-    @property
-    def co_argcount(self):
-        return self._self_adapter_code.co_argcount
-
-    @property
-    def co_code(self):
-        return self._self_adapter_code.co_code
-
-    @property
-    def co_flags(self):
-        return self._self_adapter_code.co_flags
-
-    @property
-    def co_kwonlyargcount(self):
-        return self._self_adapter_code.co_kwonlyargcount
-
-    @property
-    def co_varnames(self):
-        return self._self_adapter_code.co_varnames
-
-
-class _AdapterFunctionSurrogate(CallableObjectProxy):
-
-    def __init__(self, wrapped, adapter):
-        # Explicit class in super() is used because the proxy overrides
-        # __class__ and MRO-related methods to delegate to the wrapped
-        # object, which can interfere with bare super().
-        super(_AdapterFunctionSurrogate, self).__init__(wrapped)
-        self._self_adapter = adapter
-
-    @property
-    def __code__(self):
-        return _AdapterFunctionCode(
-            self.__wrapped__.__code__, self._self_adapter.__code__
-        )
-
-    @property
-    def __defaults__(self):
-        return self._self_adapter.__defaults__
-
-    @property
-    def __kwdefaults__(self):
-        return self._self_adapter.__kwdefaults__
-
-    @property
-    def __signature__(self):
-        return signature(self._self_adapter)
-
-
-class _BoundAdapterFunctionWrapper(BoundFunctionWrapper):
-
-    @property
-    def __func__(self):
-        return _AdapterFunctionSurrogate(
-            self.__wrapped__.__func__, self._self_parent._self_adapter
-        )
-
-    @property
-    def __signature__(self):
-        return signature(self._self_parent._self_adapter)
-
-
-class _AdapterFunctionWrapper(FunctionWrapper):
-
-    __bound_function_wrapper__ = _BoundAdapterFunctionWrapper
-
-    def __init__(self, *args, **kwargs):
-        adapter = kwargs.pop("adapter")
-        # Explicit class in super() is used because the proxy overrides
-        # __class__ and MRO-related methods to delegate to the wrapped
-        # object, which can interfere with bare super().
-        super(_AdapterFunctionWrapper, self).__init__(*args, **kwargs)
-        self._self_surrogate = _AdapterFunctionSurrogate(self.__wrapped__, adapter)
-        self._self_adapter = adapter
-
-    @property
-    def __code__(self):
-        return self._self_surrogate.__code__
-
-    @property
-    def __defaults__(self):
-        return self._self_surrogate.__defaults__
-
-    @property
-    def __kwdefaults__(self):
-        return self._self_surrogate.__kwdefaults__
-
-    @property
-    def __signature__(self):
-        return self._self_surrogate.__signature__
-
-
-class AdapterFactory:
-    def __call__(self, wrapped):
-        raise NotImplementedError()
-
-
-class _DelegatedAdapterFactory(AdapterFactory):
-    def __init__(self, factory):
-        # Explicit class in super() for consistency with proxy subclasses.
-        super(_DelegatedAdapterFactory, self).__init__()
-        self.factory = factory
-
-    def __call__(self, wrapped):
-        return self.factory(wrapped)
-
-
-adapter_factory = _DelegatedAdapterFactory
-
-# Decorator for creating other decorators. This decorator and the
-# wrappers which they use are designed to properly preserve any name
-# attributes, function signatures etc, in addition to the wrappers
-# themselves acting like a transparent proxy for the original wrapped
-# function so the wrapper is effectively indistinguishable from the
-# original wrapped function.
-
-
-def decorator(wrapper=None, /, *, enabled=None, adapter=None, proxy=FunctionWrapper):
-    """
-    The decorator should be supplied with a single positional argument
-    which is the `wrapper` function to be used to implement the
-    decorator. This may be preceded by a step whereby the keyword
-    arguments are supplied to customise the behaviour of the
-    decorator. The `adapter` argument is used to optionally denote a
-    separate function which is notionally used by an adapter
-    decorator. In that case parts of the function `__code__` and
-    `__defaults__` attributes are used from the adapter function
-    rather than those of the wrapped function. This allows for the
-    argument specification from `inspect.getfullargspec()` and similar
-    functions to be overridden with a prototype for a different
-    function than what was wrapped. The `enabled` argument provides a
-    way to enable/disable the use of the decorator. If the type of
-    `enabled` is a boolean, then it is evaluated immediately and the
-    wrapper not even applied if it is `False`. If not a boolean, it will
-    be evaluated when the wrapper is called for an unbound wrapper,
-    and when binding occurs for a bound wrapper. When being evaluated,
-    if `enabled` is callable it will be called to obtain the value to
-    be checked. If `False`, the wrapper will not be called and instead
-    the original wrapped function will be called directly instead.
-    The `proxy` argument provides a way of passing a custom version of
-    the `FunctionWrapper` class used in decorating the function.
-    """
-
-    if wrapper is not None:
-        # Helper function for creating wrapper of the appropriate
-        # time when we need it down below.
-
-        def _build(wrapped, wrapper, enabled=None, adapter=None):
-            # Where the adapter is a factory, call it to obtain the actual
-            # adapter before testing whether an adapter was supplied at
-            # all. The factory check is done first and by type, rather
-            # than relying on the truth value of the adapter, as a factory
-            # instance may evaluate as false if it defines `__bool__()` or
-            # `__len__()`. A factory which returns `None` or some other
-            # false value is treated as there being no adapter.
-
-            if isinstance(adapter, AdapterFactory):
-                adapter = adapter(wrapped)
-
-            if adapter:
-                if not callable(adapter):
-                    ns = {}
-
-                    # Check if the signature argument specification has
-                    # annotations. If it does then we need to remember
-                    # it but also drop it when attempting to manufacture
-                    # a standin adapter function. This is necessary else
-                    # it will try and look up any types referenced in
-                    # the annotations in the empty namespace we use,
-                    # which will fail.
-
-                    annotations = {}
-
-                    if not isinstance(adapter, str):
-                        if len(adapter) == 7:
-                            annotations = adapter[-1]
-                            adapter = adapter[:-1]
-                        adapter = formatargspec(*adapter)
-
-                    exec(f"def adapter{adapter}: pass", ns, ns)
-                    adapter = ns["adapter"]
-
-                    # Override the annotations for the manufactured
-                    # adapter function so they match the original
-                    # adapter signature argument specification.
-
-                    if annotations:
-                        adapter.__annotations__ = annotations
-
-                return _AdapterFunctionWrapper(
-                    wrapped=wrapped, wrapper=wrapper, enabled=enabled, adapter=adapter
-                )
-
-            return proxy(wrapped=wrapped, wrapper=wrapper, enabled=enabled)
-
-        # The wrapper has been provided so return the final decorator.
-        # The decorator is itself one of our function wrappers so we
-        # can determine when it is applied to functions, instance methods
-        # or class methods. This allows us to bind the instance or class
-        # method so the appropriate self or cls attribute is supplied
-        # when it is finally called.
-
-        def _wrapper(wrapped, instance, args, kwargs):
-            # We first check for the case where the decorator was applied
-            # to a class type.
-            #
-            #     @decorator
-            #     class mydecoratorclass:
-            #         def __init__(self, arg=None):
-            #             self.arg = arg
-            #         def __call__(self, wrapped, instance, args, kwargs):
-            #             return wrapped(*args, **kwargs)
-            #
-            #     @mydecoratorclass(arg=1)
-            #     def function():
-            #         pass
-            #
-            # In this case an instance of the class is to be used as the
-            # decorator wrapper function. If args was empty at this point,
-            # then it means that there were optional keyword arguments
-            # supplied to be used when creating an instance of the class
-            # to be used as the wrapper function.
-
-            if instance is None and isclass(wrapped) and not args:
-                # We still need to be passed the target function to be
-                # wrapped as yet, so we need to return a further function
-                # to be able to capture it.
-
-                def _capture(target_wrapped):
-                    # Now have the target function to be wrapped and need
-                    # to create an instance of the class which is to act
-                    # as the decorator wrapper function. Before we do that,
-                    # we need to first check that use of the decorator
-                    # hadn't been disabled by a simple boolean. If it was,
-                    # the target function to be wrapped is returned instead.
-
-                    _enabled = enabled
-                    if type(_enabled) is bool:
-                        if not _enabled:
-                            return target_wrapped
-                        _enabled = None
-
-                    # Now create an instance of the class which is to act
-                    # as the decorator wrapper function. Any arguments had
-                    # to be supplied as keyword only arguments so that is
-                    # all we pass when creating it.
-
-                    target_wrapper = wrapped(**kwargs)
-
-                    # Finally build the wrapper itself and return it.
-
-                    return _build(target_wrapped, target_wrapper, _enabled, adapter)
-
-                return _capture
-
-            # We should always have the target function to be wrapped at
-            # this point as the first (and only) value in args.
-
-            target_wrapped = args[0]
-
-            # Need to now check that use of the decorator hadn't been
-            # disabled by a simple boolean. If it was, then target
-            # function to be wrapped is returned instead.
-
-            _enabled = enabled
-            if type(_enabled) is bool:
-                if not _enabled:
-                    return target_wrapped
-                _enabled = None
-
-            # We now need to build the wrapper, but there are a couple of
-            # different cases we need to consider.
-
-            if instance is None:
-                if isclass(wrapped):
-                    # In this case the decorator was applied to a class
-                    # type but optional keyword arguments were not supplied
-                    # for initialising an instance of the class to be used
-                    # as the decorator wrapper function.
-                    #
-                    #     @decorator
-                    #     class mydecoratorclass:
-                    #         def __init__(self, arg=None):
-                    #             self.arg = arg
-                    #         def __call__(self, wrapped, instance,
-                    #                 args, kwargs):
-                    #             return wrapped(*args, **kwargs)
-                    #
-                    #     @mydecoratorclass
-                    #     def function():
-                    #         pass
-                    #
-                    # We still need to create an instance of the class to
-                    # be used as the decorator wrapper function, but no
-                    # arguments are pass.
-
-                    target_wrapper = wrapped()
-
-                else:
-                    # In this case the decorator was applied to a normal
-                    # function, or possibly a static method of a class.
-                    #
-                    #     @decorator
-                    #     def mydecoratorfuntion(wrapped, instance,
-                    #             args, kwargs):
-                    #         return wrapped(*args, **kwargs)
-                    #
-                    #     @mydecoratorfunction
-                    #     def function():
-                    #         pass
-                    #
-                    # That normal function becomes the decorator wrapper
-                    # function.
-
-                    target_wrapper = wrapper
-
-            else:
-                if isclass(instance):
-                    # In this case the decorator was applied to a class
-                    # method.
-                    #
-                    #     class myclass:
-                    #         @decorator
-                    #         @classmethod
-                    #         def decoratorclassmethod(cls, wrapped,
-                    #                 instance, args, kwargs):
-                    #             return wrapped(*args, **kwargs)
-                    #
-                    #     instance = myclass()
-                    #
-                    #     @instance.decoratorclassmethod
-                    #     def function():
-                    #         pass
-                    #
-                    # This one is a bit strange because binding was actually
-                    # performed on the wrapper created by our decorator
-                    # factory. We need to apply that binding to the decorator
-                    # wrapper function that the decorator factory
-                    # was applied to.
-
-                    target_wrapper = wrapper.__get__(None, instance)
-
-                else:
-                    # In this case the decorator was applied to an instance
-                    # method.
-                    #
-                    #     class myclass:
-                    #         @decorator
-                    #         def decoratorclassmethod(self, wrapped,
-                    #                 instance, args, kwargs):
-                    #             return wrapped(*args, **kwargs)
-                    #
-                    #     instance = myclass()
-                    #
-                    #     @instance.decoratorclassmethod
-                    #     def function():
-                    #         pass
-                    #
-                    # This one is a bit strange because binding was actually
-                    # performed on the wrapper created by our decorator
-                    # factory. We need to apply that binding to the decorator
-                    # wrapper function that the decorator factory
-                    # was applied to.
-
-                    target_wrapper = wrapper.__get__(instance, type(instance))
-
-            # Finally build the wrapper itself and return it.
-
-            return _build(target_wrapped, target_wrapper, _enabled, adapter)
-
-        # We first return our magic function wrapper here so we can
-        # determine in what context the decorator factory was used. In
-        # other words, it is itself a universal decorator. The decorator
-        # function is used as the adapter so that linters see a signature
-        # corresponding to the decorator and not the wrapper it is being
-        # applied to.
-
-        return _build(wrapper, _wrapper, adapter=decorator)
-
-    else:
-        # The wrapper still has not been provided, so we are just
-        # collecting the optional keyword arguments. Return the
-        # decorator again wrapped in a partial using the collected
-        # arguments.
-
-        return partial(decorator, enabled=enabled, adapter=adapter, proxy=proxy)
-
-
-# Descriptor decorator for automatically binding state to a wrapper.
-# When applied to a method decorated with function_wrapper or decorator,
-# it intercepts descriptor access so that when the method is accessed
-# via an instance, the instance is automatically attached to the
-# resulting wrapper using __self_setattr__. This is useful when you
-# want the wrapper to carry a reference back to the object that owns
-# the wrapper factory method, making state accessible through the
-# decorated function without manual setup.
-
-
-class _StateBindingWrapper(BaseObjectProxy):
-    """A descriptor decorator that binds the owner instance to wrappers
-    produced by a wrapper factory method.
-
-    When applied on top of a method decorated with ``function_wrapper``
-    or ``decorator``, it intercepts the descriptor ``__get__`` so that
-    when the method is accessed through an instance, the owner instance
-    is automatically attached as an attribute on the resulting wrapper
-    via ``__self_setattr__``.
-
-    The *name* keyword argument controls the attribute name under which
-    the owner instance is stored on the wrapper (default ``"state"``).
-    """
-
-    def __init__(self, *, name="state"):
-        # Initialise the proxy with a placeholder. The actual wrapper
-        # factory is set later when __call__ is invoked as a decorator.
-
-        super().__init__(None)
-
-        self._self_attr_name = name
-
-    def __call__(self, wrapper_factory):
-        # Called when used as a decorator, receiving the wrapper factory
-        # (the function_wrapper or decorator-decorated method) to wrap.
-
-        self.__wrapped__ = wrapper_factory
-
-        return self
-
-    def __get__(self, instance, owner):
-        # When accessed via the class rather than an instance, return
-        # the descriptor itself unchanged. This preserves introspection
-        # of the underlying wrapper factory via the object proxy.
-
-        if instance is None:
-            return self
-
-        # Bind the underlying wrapper factory to the instance so it
-        # receives the correct self/cls when called.
-
-        wrapper_factory = self.__wrapped__.__get__(instance, owner)
-
-        name = self._self_attr_name
-
-        def _bind(func):
-            wrapper = wrapper_factory(func)
-
-            # Attach the owner instance to the wrapper so it can be
-            # accessed as an attribute of the decorated function.
-
-            wrapper.__self_setattr__(name, instance)
-
-            return wrapper
-
-        return _bind
-
-
-bind_state_to_wrapper = _StateBindingWrapper
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py
deleted file mode 100644
index 9dc24065c5b..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/doc.py
+++ /dev/null
@@ -1,128 +0,0 @@
-"""The `with_doc` decorator: override the docstring that introspection tools
-see for a wrapped callable without mutating the wrapped function itself.
-Accepts the docstring directly, or a factory that derives it from the
-wrapped function at decoration time.
-
-This is the companion of `with_signature`, which overrides the signature in
-the same way. Assigning to `__doc__` on an ordinary wrapt wrapper writes
-through to the wrapped function, because `__doc__` on every proxy delegates
-to the wrapped object, so a wrapper carrying its own docstring is the only
-way to change what is reported without touching the wrapped function.
-"""
-
-from .__wrapt__ import BoundFunctionWrapper, FunctionWrapper
-
-# Marker for a wrapper which carries no docstring override, so that `__doc__`
-# keeps delegating to the wrapped function. Distinct from None, which is a
-# legitimate docstring override.
-
-_NO_DOC_OVERRIDE = object()
-
-# The `__doc__` property for a function wrapper which may carry a docstring
-# override in its `_self_doc` slot. The wrapper class must assign this to
-# `__doc__` in its own class body, rather than inherit it from a mixin, and
-# set `_self_doc` in its `__init__()`, to `_NO_DOC_OVERRIDE` when there is
-# none.
-#
-# Both the pure Python metaclass and the C extension attribute hooks
-# recognise a `__doc__` descriptor defined by a derived class and consult it
-# in place of the default delegation to the wrapped object. It has to be in
-# the class dictionary of the wrapper class itself though, because `pydoc`
-# reads `__doc__` using `object.__getattribute__()` to avoid inherited
-# docstrings, and with the C extension that bypasses the attribute hooks and
-# would otherwise find the copy of the wrapped function's docstring which is
-# held in the instance dictionary.
-#
-# Without an override, assignment and deletion write through to the wrapped
-# function as they do for any other wrapt wrapper. With one, assignment
-# replaces the override and deletion removes it, restoring delegation to the
-# wrapped function.
-
-
-def _get_doc(self):
-    doc = self._self_doc
-    if doc is _NO_DOC_OVERRIDE:
-        return self.__wrapped__.__doc__
-    return doc
-
-
-def _set_doc(self, value):
-    if self._self_doc is _NO_DOC_OVERRIDE:
-        self.__wrapped__.__doc__ = value
-    else:
-        self._self_doc = value
-
-
-def _del_doc(self):
-    if self._self_doc is _NO_DOC_OVERRIDE:
-        del self.__wrapped__.__doc__
-    else:
-        self._self_doc = _NO_DOC_OVERRIDE
-
-
-_DOC_PROPERTY = property(_get_doc, _set_doc, _del_doc)
-
-# The `__doc__` property for the bound wrapper of a function wrapper which
-# may carry a docstring override, reading it from the parent. A bound
-# wrapper is read only, as `__doc__` of a bound method is.
-
-
-def _get_bound_doc(self):
-    doc = self._self_parent._self_doc
-    if doc is _NO_DOC_OVERRIDE:
-        return self.__wrapped__.__doc__
-    return doc
-
-
-_BOUND_DOC_PROPERTY = property(_get_bound_doc)
-
-
-class _BoundDocFunctionWrapper(BoundFunctionWrapper):
-    __doc__ = _BOUND_DOC_PROPERTY
-
-
-class _DocFunctionWrapper(FunctionWrapper):
-    __doc__ = _DOC_PROPERTY
-
-    __bound_function_wrapper__ = _BoundDocFunctionWrapper
-
-    def __init__(self, wrapped, wrapper, doc):
-        super().__init__(wrapped, wrapper)
-        self._self_doc = doc
-
-
-def with_doc(wrapped=None, /, *, doc=None, factory=None):
-    """Override the docstring of a wrapped callable.
-
-    Exactly one of `doc` or `factory` must be supplied:
-
-    - `doc`: the docstring to report.
-    - `factory`: a callable `factory(wrapped)` invoked at decoration time
-      that returns the docstring to report.
-
-    The resulting wrapper reports the override as its `__doc__`, and so it
-    is what `help()` and `pydoc` display. The wrapped function is not
-    mutated, and assigning to `__doc__` on the wrapper replaces the override
-    rather than writing through to the wrapped function. Calling behaviour
-    is unchanged.
-    """
-
-    if doc is None and factory is None:
-        raise TypeError("with_doc requires one of doc= or factory=")
-    if doc is not None and factory is not None:
-        raise TypeError("with_doc accepts only one of doc= or factory=")
-
-    def _decorator(wrapped):
-        def _wrapper(wrapped, instance, args, kwargs):
-            return wrapped(*args, **kwargs)
-
-        if factory is not None:
-            resolved = factory(wrapped)
-        else:
-            resolved = doc
-
-        return _DocFunctionWrapper(wrapped, _wrapper, resolved)
-
-    if wrapped is None:
-        return _decorator
-    return _decorator(wrapped)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py
deleted file mode 100644
index 35efecebdd7..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/exceptions.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""Exception types raised by wrapt."""
-
-
-class WrapperNotInitializedError(ValueError):
-    """
-    Exception raised when a wrapper is in an inconsistent state: __init__ was
-    called but __wrapped__ is not set. Inherits from ValueError only, so it is
-    not silently swallowed by hasattr/getattr/except AttributeError patterns.
-    """
-
-    pass
-
-
-class PathResolutionError(AttributeError):
-    """
-    Exception raised when the dotted attribute path supplied for a patch
-    target could not be resolved. Inherits from AttributeError so existing
-    code catching that continues to work, while the message carries the
-    target, the full dotted path, and the failing segment, and the low-level
-    error is preserved as __cause__.
-    """
-
-    pass
-
-
-class TargetModuleNotFoundError(ModuleNotFoundError):
-    """
-    Exception raised when a patch target supplied as a string named a module
-    that could not be imported. Inherits from ModuleNotFoundError so existing
-    code catching that, or ImportError, continues to work, while the message
-    names the module and the attribute path being resolved, and the low-level
-    error is preserved as __cause__.
-    """
-
-    pass
-
-
-class WrapperChainTooDeepError(RuntimeError):
-    """
-    Exception raised when a scan of a chain of wrappers reached the traversal
-    limit with a further link still pending, so the result of the scan would
-    be indeterminate. Inherits from RuntimeError, following the precedent of
-    RecursionError for exhaustion of a depth limit, as it reports an
-    execution limit rather than a contract violation.
-    """
-
-    pass
-
-
-class WrapperNotFoundError(ValueError):
-    """
-    Exception raised when the wrapper to be removed was not found in the
-    chain of wrappers of the attribute, meaning nothing of the caller's is
-    installed there: it was never wrapped, was already removed, or the
-    attribute was replaced wholesale by a third party.
-    """
-
-    pass
-
-
-class WrapperNotOutermostError(ValueError):
-    """
-    Exception raised when the wrapper to be removed was found but cannot be
-    removed, because what sits directly above it in the chain is not a wrapt
-    wrapper whose link to it can be updated in place, or because the
-    attribute is served dynamically and has no owning location to restore.
-    """
-
-    pass
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py
deleted file mode 100644
index 4c1ea5f629a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/importer.py
+++ /dev/null
@@ -1,314 +0,0 @@
-"""This module implements a post import hook mechanism styled after what is
-described in PEP-369. Note that it doesn't cope with modules being reloaded.
-
-"""
-
-import importlib.metadata
-import sys
-import threading
-from collections.abc import Callable
-from importlib.util import find_spec
-
-from .__wrapt__ import BaseObjectProxy
-
-# The dictionary registering any post import hooks to be triggered once
-# the target module has been imported. Once a module has been imported
-# and the hooks fired, the list of hooks recorded against the target
-# module will be truncated but the list left in the dictionary. This
-# acts as a flag to indicate that the module had already been imported.
-
-_post_import_hooks: dict[str, list[Callable]] = {}
-_post_import_hooks_init = False
-_post_import_hooks_lock = threading.RLock()
-
-# Register a new post import hook for the target module name. This
-# differs from the PEP-369 implementation in that it also allows the
-# hook function to be specified as a string consisting of the name of
-# the callback in the form 'module:function'. This will result in a
-# proxy callback being registered which will defer loading of the
-# specified module containing the callback function until required.
-
-
-def _create_import_hook_from_string(name):
-    def import_hook(module):
-        module_name, function = name.split(":")
-        attrs = function.split(".")
-
-        # Use importlib.import_module() rather than __import__() as the
-        # latter fails for a module registered in sys.modules whose parent
-        # package is not importable. See resolve_path() in patches.py.
-
-        callback = importlib.import_module(module_name)
-        for attr in attrs:
-            callback = getattr(callback, attr)
-        return callback(module)
-
-    return import_hook
-
-
-def register_post_import_hook(hook, name):
-    """
-    Register a post import hook for the target module `name`. The `hook`
-    function will be called once the module is imported and will be passed the
-    module as argument. If the module is already imported, the `hook` will be
-    called immediately. If you also want to defer loading of the module containing
-    the `hook` function until required, you can specify the `hook` as a string in
-    the form 'module:function'. This will result in a proxy hook function being
-    registered which will defer loading of the specified module containing the
-    callback function until required.
-    """
-
-    # Create a deferred import hook if hook is a string name rather than
-    # a callable function.
-
-    if isinstance(hook, str):
-        hook = _create_import_hook_from_string(hook)
-
-    with _post_import_hooks_lock:
-        # Automatically install the import hook finder if it has not already
-        # been installed.
-
-        global _post_import_hooks_init
-
-        if not _post_import_hooks_init:
-            _post_import_hooks_init = True
-            sys.meta_path.insert(0, ImportHookFinder())
-
-        # Check if the module is already imported. If not, register the hook
-        # to be called after import.
-
-        module = sys.modules.get(name, None)
-
-        if module is None:
-            _post_import_hooks.setdefault(name, []).append(hook)
-
-    # If the module is already imported, we fire the hook right away. Note that
-    # the hook is called outside of the lock to avoid deadlocks if code run as a
-    # consequence of calling the module import hook in turn triggers a separate
-    # thread which tries to register an import hook.
-
-    if module is not None:
-        hook(module)
-
-
-# Register post import hooks defined as package entry points.
-
-
-def discover_post_import_hooks(group):
-    """
-    Discover and register post import hooks defined as package entry points
-    in the specified `group`. The group should be a string that matches the
-    entry point group name used in the package metadata.
-    """
-
-    try:
-        # Python 3.10+ style with select parameter
-        entrypoints = importlib.metadata.entry_points(group=group)
-    except TypeError:
-        # Python 3.8-3.9 style that returns a dict
-        entrypoints = importlib.metadata.entry_points().get(group, ())
-
-    for entrypoint in entrypoints:
-        callback = entrypoint.load()  # Use the loaded callback directly
-        register_post_import_hook(callback, entrypoint.name)
-
-
-# Indicate that a module has been loaded. Any post import hooks which
-# were registered against the target module will be invoked. If an
-# exception is raised in any of the post import hooks, that will cause
-# the import of the target module to fail.
-
-
-def notify_module_loaded(module):
-    """
-    Notify that a `module` has been loaded and invoke any post import hooks
-    registered against the module. If the module is not registered, this
-    function does nothing.
-    """
-
-    name = getattr(module, "__name__", None)
-
-    with _post_import_hooks_lock:
-        hooks = _post_import_hooks.pop(name, ())
-
-    # Note that the hook is called outside of the lock to avoid deadlocks if
-    # code run as a consequence of calling the module import hook in turn
-    # triggers a separate thread which tries to register an import hook.
-
-    for hook in hooks:
-        hook(module)
-
-
-# A custom module import finder. This intercepts attempts to import
-# modules and watches out for attempts to import target modules of
-# interest. When a module of interest is imported, then any post import
-# hooks which are registered will be invoked.
-
-
-class _ImportHookChainedLoader(BaseObjectProxy):
-
-    def __init__(self, loader):
-        # Explicit class in super() is used because the proxy overrides
-        # __class__ and MRO-related methods to delegate to the wrapped
-        # object, which can interfere with bare super().
-        super(_ImportHookChainedLoader, self).__init__(loader)
-
-        if hasattr(loader, "load_module"):
-            self.__self_setattr__("load_module", self._self_load_module)
-        if hasattr(loader, "create_module"):
-            self.__self_setattr__("create_module", self._self_create_module)
-        if hasattr(loader, "exec_module"):
-            self.__self_setattr__("exec_module", self._self_exec_module)
-
-    def _self_set_loader(self, module):
-        # Set module's loader to self.__wrapped__ unless it's already set to
-        # something else. Import machinery will set it to spec.loader if it is
-        # None, so handle None as well. The module may not support attribute
-        # assignment, in which case we simply skip it. Note that we also deal
-        # with __loader__ not existing at all. This is to future proof things
-        # due to proposal to remove the attribute as described in the GitHub
-        # issue at https://github.com/python/cpython/issues/77458. Also prior
-        # to Python 3.3, the __loader__ attribute was only set if a custom
-        # module loader was used. It isn't clear whether the attribute still
-        # existed in that case or was set to None.
-
-        class UNDEFINED:
-            pass
-
-        if getattr(module, "__loader__", UNDEFINED) in (None, self):
-            try:
-                module.__loader__ = self.__wrapped__
-            except AttributeError:
-                pass
-
-        if (
-            getattr(module, "__spec__", None) is not None
-            and getattr(module.__spec__, "loader", None) is self
-        ):
-            module.__spec__.loader = self.__wrapped__
-
-    def _self_load_module(self, fullname):
-        module = self.__wrapped__.load_module(fullname)
-        self._self_set_loader(module)
-        notify_module_loaded(module)
-
-        return module
-
-    # Python 3.4 introduced create_module() and exec_module() instead of
-    # load_module() alone. Splitting the two steps.
-
-    def _self_create_module(self, spec):
-        return self.__wrapped__.create_module(spec)
-
-    def _self_exec_module(self, module):
-        self._self_set_loader(module)
-        self.__wrapped__.exec_module(module)
-        notify_module_loaded(module)
-
-
-class ImportHookFinder:
-
-    def __init__(self):
-        self.in_progress = {}
-
-    def find_module(self, fullname, path=None):
-        with _post_import_hooks_lock:
-            # If the module being imported is not one we have registered
-            # post import hooks for, we can return immediately. We will
-            # take no further part in the importing of this module.
-
-            if fullname not in _post_import_hooks:
-                return None
-
-            # When we are interested in a specific module, we will call back
-            # into the import system a second time to defer to the import
-            # finder that is supposed to handle the importing of the module.
-            # We set an in progress flag for the target module so that on
-            # the second time through we don't trigger another call back
-            # into the import system and cause a infinite loop.
-
-            if fullname in self.in_progress:
-                return None
-
-            self.in_progress[fullname] = True
-
-        # Now call back into the import system again.
-
-        try:
-            # For Python 3 we need to use find_spec().loader
-            # from the importlib.util module. It doesn't actually
-            # import the target module and only finds the
-            # loader. If a loader is found, we need to return
-            # our own loader which will then in turn call the
-            # real loader to import the module and invoke the
-            # post import hooks.
-
-            loader = getattr(find_spec(fullname), "loader", None)
-
-            if loader and not isinstance(loader, _ImportHookChainedLoader):
-                return _ImportHookChainedLoader(loader)
-
-        finally:
-            del self.in_progress[fullname]
-
-    def find_spec(self, fullname, path=None, target=None):
-        # Since Python 3.4, you are meant to implement find_spec() method
-        # instead of find_module() and since Python 3.10 you get deprecation
-        # warnings if you don't define find_spec().
-
-        with _post_import_hooks_lock:
-            # If the module being imported is not one we have registered
-            # post import hooks for, we can return immediately. We will
-            # take no further part in the importing of this module.
-
-            if fullname not in _post_import_hooks:
-                return None
-
-            # When we are interested in a specific module, we will call back
-            # into the import system a second time to defer to the import
-            # finder that is supposed to handle the importing of the module.
-            # We set an in progress flag for the target module so that on
-            # the second time through we don't trigger another call back
-            # into the import system and cause a infinite loop.
-
-            if fullname in self.in_progress:
-                return None
-
-            self.in_progress[fullname] = True
-
-        # Now call back into the import system again.
-
-        try:
-            # This should only be Python 3 so find_spec() should always
-            # exist so don't need to check.
-
-            spec = find_spec(fullname)
-            loader = getattr(spec, "loader", None)
-
-            if loader and not isinstance(loader, _ImportHookChainedLoader):
-                spec.loader = _ImportHookChainedLoader(loader)
-
-            return spec
-
-        finally:
-            del self.in_progress[fullname]
-
-
-# Decorator for marking that a function should be called as a post
-# import hook when the target module is imported.
-
-
-def when_imported(name):
-    """
-    Returns a decorator that registers the decorated function as a post import
-    hook for the module specified by `name`. The function will be called once
-    the module with the specified name is imported, and will be passed the
-    module as argument. If the module is already imported, the function will
-    be called immediately.
-    """
-
-    def register(hook):
-        register_post_import_hook(hook, name)
-        return hook
-
-    return register
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py
deleted file mode 100644
index aa8727de580..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/patches.py
+++ /dev/null
@@ -1,851 +0,0 @@
-"""Utilities for monkey patching and wrapping object attributes."""
-
-import contextlib
-import importlib
-import inspect
-import sys
-import warnings
-
-from .__wrapt__ import BaseObjectProxy, FunctionWrapper
-from .exceptions import (
-    PathResolutionError,
-    TargetModuleNotFoundError,
-    WrapperChainTooDeepError,
-    WrapperNotFoundError,
-    WrapperNotOutermostError,
-)
-from .importer import register_post_import_hook
-
-# Sentinel used where the absence of a value must be distinguishable from
-# None being supplied, or where an attribute having had no prior definition
-# must be represented as a value. Exposed as public API since code walking
-# wrapper chains needs to be able to test for it by identity, but only
-# meaningful where wrapt itself checks for it.
-
-
-class _MissingType:
-    """The type of the MISSING sentinel, which marks the absence of a value
-    or attribute definition where None is itself meaningful."""
-
-    _instance = None
-
-    def __new__(cls):
-        if cls._instance is None:
-            cls._instance = super().__new__(cls)
-        return cls._instance
-
-    def __repr__(self):
-        return ""
-
-    def __reduce__(self):
-        # Pickle and copy resolve back to the singleton so identity
-        # comparison against MISSING survives a round trip.
-        return (_MissingType, ())
-
-
-MISSING = _MissingType()
-
-# Helper functions for applying wrappers to existing functions.
-
-
-def resolve_path(target, name):
-    """
-    Resolves the dotted path supplied as `name` to an attribute on a target
-    object. The `target` can be a module, class, or instance of a class. If the
-    `target` argument is a string, it is assumed to be the name of a module,
-    which will be imported if necessary and then used as the target object.
-    Returns a tuple containing the parent object holding the attribute lookup
-    resolved to, the attribute name (path prefix removed if present), and the
-    original attribute value. If the module cannot be imported, raises
-    `TargetModuleNotFoundError`, and if the attribute path cannot be resolved,
-    raises `PathResolutionError`, in both cases with the original exception
-    preserved as the `__cause__` attribute.
-    """
-
-    if isinstance(target, str):
-        # Use importlib.import_module() rather than __import__() as the
-        # latter, even though it imports a dotted module name successfully
-        # from the sys.modules cache, computes its return value by importing
-        # the top level package, which fails for a module registered in
-        # sys.modules whose parent package is not importable.
-
-        try:
-            target = importlib.import_module(target)
-        except ModuleNotFoundError as exc:
-            raise TargetModuleNotFoundError(
-                f"unable to import module {target!r} while resolving "
-                f"the target for {name!r}"
-            ) from exc
-
-    parent = target
-
-    path = name.split(".")
-    attribute = path[0]
-
-    # We can't just always use getattr() because in doing
-    # that on a class it will cause binding to occur which
-    # will complicate things later and cause some things not
-    # to work. For the case of a class we therefore access
-    # the __dict__ directly. To cope though with the wrong
-    # class being given to us, or a method being moved into
-    # a base class, we need to walk the class hierarchy to
-    # work out exactly which __dict__ the method was defined
-    # in, as accessing it from __dict__ will fail if it was
-    # not actually on the class given. Fallback to using
-    # getattr() if we can't find it. If it truly doesn't
-    # exist, then that will fail.
-
-    def lookup_attribute(parent, attribute):
-        try:
-            if inspect.isclass(parent):
-                for cls in inspect.getmro(parent):
-                    if attribute in vars(cls):
-                        return vars(cls)[attribute]
-                else:
-                    return getattr(parent, attribute)
-            else:
-                return getattr(parent, attribute)
-        except AttributeError as exc:
-            raise PathResolutionError(
-                f"unable to resolve attribute {attribute!r} in path "
-                f"{name!r} on {target!r}"
-            ) from exc
-
-    original = lookup_attribute(parent, attribute)
-
-    for attribute in path[1:]:
-        parent = original
-        original = lookup_attribute(parent, attribute)
-
-    return (parent, attribute, original)
-
-
-def resolve_owner(target, name):
-    """
-    Sibling of the `resolve_path()` function, resolving the dotted path
-    supplied as `name` on a target object in the same way and returning a
-    tuple of the same shape, with one difference: the first element is the
-    object whose `__dict__` actually defines the attribute, rather than
-    the object the path resolved to. The two answer different questions.
-    `resolve_path()` answers where to write so that lookups through the
-    named object are affected, which is the correct location for
-    installing a wrapper, and shadowing an inherited definition is
-    legitimate there. `resolve_owner()` answers where the attribute
-    physically lives, which is the correct location for removing a
-    wrapper, since restoring anywhere other than the defining location
-    would leave a shadowing copy behind. For a class target the owner is
-    the defining class found by walking the MRO, for an instance target
-    it is the instance itself if the attribute is in its `__dict__` and
-    otherwise the defining class, and for a module target it is the
-    module. For dotted paths the owner logic applies to the final segment
-    only. An attribute served dynamically, such as by a module level or
-    metaclass `__getattr__`, exists in no `__dict__`, and rather than
-    guess, `PathResolutionError` is raised, where `resolve_path()` would
-    return the value happily. Failures resolving the path itself raise
-    exactly as for `resolve_path()`.
-    """
-
-    parent, attribute, original = resolve_path(target, name)
-
-    if inspect.isclass(parent):
-        candidates = inspect.getmro(parent)
-    elif inspect.ismodule(parent):
-        candidates = (parent,)
-    else:
-        candidates = (parent,) + tuple(inspect.getmro(type(parent)))
-
-    for candidate in candidates:
-        try:
-            if attribute in vars(candidate):
-                return (candidate, attribute, original)
-        except TypeError:
-            continue
-
-    raise PathResolutionError(
-        f"attribute {attribute!r} of {parent!r} is not defined in any "
-        f"__dict__; it is served dynamically, so there is no owning "
-        f"location to patch"
-    )
-
-
-def apply_patch(parent, attribute, replacement):
-    """
-    Convenience function for applying a patch to an attribute. This maps to
-    the standard setattr() function.
-    """
-
-    setattr(parent, attribute, replacement)
-
-
-def wrap_object(target, name, factory, args=(), kwargs=None):
-    """
-    Wraps an object which is the attribute of a target object with a wrapper
-    object created by the `factory` function. The `target` can be a module,
-    class, or instance of a class. In the special case of `target` being a
-    string, it is assumed to be the name of a module, with the module being
-    imported if necessary and then used as the target object. The `name` is a
-    string representing the dotted path to the attribute. The `factory` function
-    should accept the original object and may accept additional positional and
-    keyword arguments which will be set by unpacking input arguments using
-    `*args` and `**kwargs` calling conventions. The factory function should
-    return a new object that will replace the original object, and should
-    ordinarily be a `BaseObjectProxy` subclass or return an instance of
-    one, so that the replacement can carry the installation details which
-    `unwrap_object()` later relies upon to restore things faithfully.
-    """
-
-    if kwargs is None:
-        kwargs = {}
-
-    parent, attribute, original = resolve_path(target, name)
-
-    # Record whether applying the patch creates the attribute slot on the
-    # parent, or overwrites one which already existed. When the value was
-    # being served from somewhere else, such as a base class via the MRO,
-    # the class of an instance, or a dynamic __getattr__, the patch
-    # creates a shadowing slot, and faithful removal is deleting that
-    # slot again rather than assigning the original into it. This fact
-    # only exists at installation time, so it is stashed on the wrapper
-    # itself, in the local state of the proxy where lookups cannot be
-    # confused with anything of the wrapped object's, for
-    # unwrap_object() to consult. A factory result which is not a wrapt
-    # proxy cannot carry it and unwrap_object() falls back to what can
-    # be determined at removal time.
-
-    try:
-        created = attribute not in vars(parent)
-    except TypeError:
-        created = False
-
-    wrapper = factory(original, *args, **kwargs)
-
-    try:
-        wrapper.__self_setattr__("__wrapt_wrap_object_created_slot__", created)
-    except AttributeError:
-        pass
-
-    apply_patch(parent, attribute, wrapper)
-
-    return wrapper
-
-
-# Function for applying a proxy object to an attribute of a class
-# instance. The wrapper works by defining an attribute of the same name
-# on the class which is a descriptor and which intercepts access to the
-# instance attribute. The descriptor is itself an object proxy wrapping
-# whatever previously occupied the class attribute, be that another
-# AttributeWrapper, some other descriptor such as a property, a plain
-# class default, or the MISSING sentinel when nothing was defined, so
-# stacked applications compose rather than replace one another and the
-# prior definition keeps working beneath the interception.
-
-
-class AttributeWrapper(BaseObjectProxy):
-    """A descriptor that intercepts access to an instance attribute to apply
-    a wrapper factory. The descriptor is an object proxy whose wrapped object
-    is whatever previously occupied the class attribute, or the MISSING
-    sentinel when nothing did, so stacked applications compose and a prior
-    descriptor keeps executing its own logic beneath the interception."""
-
-    def __init__(self, wrapped, attribute, factory, args=(), kwargs=None):
-        super(AttributeWrapper, self).__init__(wrapped)
-        self._self_attribute = attribute
-        self._self_factory = factory
-        self._self_args = args
-        self._self_kwargs = kwargs if kwargs is not None else {}
-
-    def __get__(self, instance, owner=None):
-        # Class level access returns the descriptor itself. Being a
-        # transparent proxy, introspection of the prior definition then
-        # works through delegation.
-
-        if instance is None:
-            return self
-
-        # Reads follow the standard attribute lookup precedence: a data
-        # descriptor prior takes precedence over the instance
-        # dictionary, a non-data descriptor prior yields to it, and a
-        # plain class default is the fallback when no instance value
-        # exists. Only when the prior is the MISSING sentinel, meaning
-        # no definition of any sort existed, is AttributeError raised.
-
-        prior = self.__wrapped__
-        prior_type = type(prior)
-
-        if hasattr(prior_type, "__get__") and (
-            hasattr(prior_type, "__set__") or hasattr(prior_type, "__delete__")
-        ):
-            value = prior.__get__(instance, owner)
-        elif self._self_attribute in instance.__dict__:
-            value = instance.__dict__[self._self_attribute]
-        elif hasattr(prior_type, "__get__"):
-            value = prior.__get__(instance, owner)
-        elif prior is not MISSING:
-            value = prior
-        else:
-            raise AttributeError(
-                f"{type(instance).__name__!r} object has no attribute "
-                f"{self._self_attribute!r}"
-            )
-
-        return self._self_factory(value, *self._self_args, **self._self_kwargs)
-
-    def __set__(self, instance, value):
-        # Writes delegate to a prior descriptor which implements
-        # __set__, so its validation and storage are honoured, and
-        # otherwise store into the instance dictionary.
-
-        prior = self.__wrapped__
-
-        if hasattr(type(prior), "__set__"):
-            prior.__set__(instance, value)
-        else:
-            instance.__dict__[self._self_attribute] = value
-
-    def __delete__(self, instance):
-        prior = self.__wrapped__
-
-        if hasattr(type(prior), "__delete__"):
-            prior.__delete__(instance)
-        else:
-            # Match the exception deleting the attribute would raise if
-            # the wrapper had not been applied, which is AttributeError
-            # rather than the KeyError of the raw dictionary lookup.
-
-            try:
-                del instance.__dict__[self._self_attribute]
-            except KeyError:
-                raise AttributeError(
-                    f"{type(instance).__name__!r} object has no attribute "
-                    f"{self._self_attribute!r}"
-                ) from None
-
-
-def wrap_object_attribute(module, name, factory, args=(), kwargs=None):
-    """
-    Wraps an object which is the attribute of a class instance with a wrapper
-    object created by the `factory` function. It does this by patching the
-    class, not the instance, with a descriptor that intercepts access to the
-    instance attribute. The `module` can be a module, class, or instance of a
-    class. In the special case of `module` being a string, it is assumed to be
-    the name of a module, with the module being imported if necessary and then
-    used as the target object. The `name` is a string representing the dotted
-    path to the attribute. The `factory` function should accept the original
-    object and may accept additional positional and keyword arguments which will
-    be set by unpacking input arguments using `*args` and `**kwargs` calling
-    conventions. The factory function should return a new object that will
-    replace the original object. Returns the `AttributeWrapper` descriptor
-    installed on the class, which wraps whatever previously occupied the
-    class attribute, or the `MISSING` sentinel when nothing did, so repeated
-    applications compose rather than replace one another.
-    """
-
-    if kwargs is None:
-        kwargs = {}
-
-    path, attribute = name.rsplit(".", 1)
-    parent = resolve_path(module, path)[2]
-    prior = vars(parent).get(attribute, MISSING)
-    wrapper = AttributeWrapper(prior, attribute, factory, args, kwargs)
-    apply_patch(parent, attribute, wrapper)
-    return wrapper
-
-
-# Functions for creating a simple decorator using a FunctionWrapper,
-# plus short cut functions for applying wrappers to functions. These are
-# for use when doing monkey patching. For a more featured way of
-# creating decorators see the decorator decorator instead.
-
-
-def function_wrapper(wrapper):
-    """
-    Creates a decorator for wrapping a function with a `wrapper` function.
-    The decorator which is returned may also be applied to any other callable
-    objects such as lambda functions, methods, classmethods, and staticmethods,
-    or objects which implement the `__call__()` method. The `wrapper` function
-    should accept the `wrapped` function, `instance`, `args`, and `kwargs`,
-    arguments and return the result of calling the wrapped function or some
-    other appropriate value.
-    """
-
-    def _wrapper(wrapped, instance, args, kwargs):
-        target_wrapped = args[0]
-        if instance is None:
-            target_wrapper = wrapper
-        elif inspect.isclass(instance):
-            target_wrapper = wrapper.__get__(None, instance)
-        else:
-            target_wrapper = wrapper.__get__(instance, type(instance))
-        return FunctionWrapper(target_wrapped, target_wrapper)
-
-    return FunctionWrapper(wrapper, _wrapper)
-
-
-def wrap_function_wrapper(target, name, wrapper):
-    """
-    Wraps a function which is the attribute of a target object with a `wrapper`
-    function. The `target` can be a module, class, or instance of a class. In
-    the special case of `target` being a string, it is assumed to be the name
-    of a module, with the module being imported if necessary. If the `target`
-    is a string with a trailing ``?``, the wrapping will be deferred until the
-    module is imported. If the module is already imported, the wrapping will be
-    applied immediately. The `name` is a string representing the dotted path to
-    the attribute. The `wrapper` function should accept the `wrapped` function,
-    `instance`, `args`, and `kwargs` arguments, and would return the result of
-    calling the wrapped attribute or some other appropriate value. Returns the
-    wrapped target function if the wrapping was applied immediately, or ``None``
-    if the wrapping was deferred.
-    """
-
-    if isinstance(target, str) and target.endswith("?"):
-        target = target[:-1]
-
-        if target in sys.modules:
-            return wrap_object(sys.modules[target], name, FunctionWrapper, (wrapper,))
-
-        def callback(module):
-            wrap_object(module, name, FunctionWrapper, (wrapper,))
-
-        register_post_import_hook(callback, target)
-        return None
-
-    return wrap_object(target, name, FunctionWrapper, (wrapper,))
-
-
-def patch_function_wrapper(target, name, _enabled=MISSING, *, enabled=MISSING):
-    """
-    Creates a decorator which can be applied to a wrapper function, where the
-    wrapper function will be used to wrap a function which is the attribute of
-    a target object. The decorator returns the original wrapper function. The
-    `target` can be a module, class, or instance of a class. In the special case
-    of `target` being a string, it is assumed to be the name of a module, with
-    the module being imported if necessary. If the `target` is a string with a
-    trailing ``?``, the wrapping will be deferred until the module is imported.
-    If the module is already imported, the wrapping will be applied immediately.
-    The `name` is a string representing the dotted path to the attribute. The
-    `enabled` argument is keyword only and can be a boolean or a callable that
-    returns a boolean. When a callable is provided, it will be called each time
-    the wrapper is invoked to determine if the wrapper function should be
-    executed or whether the wrapped function should be called directly. If
-    `enabled` is not provided, or an explicit value of `None` is supplied,
-    the wrapper is enabled by default.
-    """
-
-    if _enabled is not MISSING:
-        if enabled is not MISSING:
-            raise TypeError(
-                "patch_function_wrapper() got multiple values for " "argument 'enabled'"
-            )
-        warnings.warn(
-            "Passing 'enabled' positionally to patch_function_wrapper() is "
-            "deprecated and will be an error in a future version of wrapt; "
-            "pass it as a keyword argument.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        enabled = _enabled
-
-    if enabled is MISSING:
-        enabled = None
-
-    def _wrapper(wrapper):
-        if isinstance(target, str) and target.endswith("?"):
-            _target = target[:-1]
-
-            if _target in sys.modules:
-                wrap_object(
-                    sys.modules[_target], name, FunctionWrapper, (wrapper, enabled)
-                )
-                return wrapper
-
-            def callback(module):
-                wrap_object(module, name, FunctionWrapper, (wrapper, enabled))
-
-            register_post_import_hook(callback, _target)
-            return wrapper
-
-        wrap_object(target, name, FunctionWrapper, (wrapper, enabled))
-        return wrapper
-
-    return _wrapper
-
-
-def transient_function_wrapper(target, name):
-    """Creates a decorator that patches a target function with a wrapper
-    function, but only for the duration of the call that the decorator was
-    applied to. The `target` can be a module, class, or instance of a class.
-    In the special case of `target` being a string, it is assumed to be the name
-    of a module, with the module being imported if necessary. The `name` is a
-    string representing the dotted path to the attribute. The patch is applied
-    to the object the path resolves to, so patching an attribute reached
-    through inheritance, or through an instance, only affects lookups made
-    through that object and not the class where the attribute is defined. In
-    that case the temporary attribute which shadowed the inherited definition
-    is removed again when the call exits, restoring the original lookup.
-
-    The temporary wrapper is removed using `unwrap_object()`, so if code
-    called within the scope of the patch wrapped over the top of the
-    temporary wrapper with a wrapt wrapper and left it there, the temporary
-    wrapper is spliced out beneath it, with the other wrapper left in
-    place. If something removed or replaced the temporary wrapper during
-    the call, `WrapperNotFoundError` is raised, and if what was applied on
-    top of it is not a wrapt wrapper and so cannot be spliced past,
-    `WrapperNotOutermostError` is raised. Both are loud deliberately, as
-    they indicate the surrounding code, typically a test harness, is not
-    managing its own patches properly, and the leaked patch state would
-    otherwise surface as hard to diagnose failures later.
-    """
-
-    def _decorator(wrapper):
-        def _wrapper(wrapped, instance, args, kwargs):
-            target_wrapped = args[0]
-            if instance is None:
-                target_wrapper = wrapper
-            elif inspect.isclass(instance):
-                target_wrapper = wrapper.__get__(None, instance)
-            else:
-                target_wrapper = wrapper.__get__(instance, type(instance))
-
-            def _execute(wrapped, instance, args, kwargs):
-                # The wrap and unwrap functions handle all the details:
-                # wrap_object() records whether applying the patch created
-                # a shadowing attribute slot, and unwrap_object() consults
-                # that record to restore or remove the attribute
-                # faithfully, splices the temporary wrapper out from
-                # beneath any wrapt wrapper left applied on top of it, and
-                # raises if the temporary wrapper was removed, replaced,
-                # or pinned beneath a non wrapt wrapper. An exception
-                # raised on exit supersedes any in-flight exception from
-                # the wrapped call, which remains visible as the chained
-                # __context__.
-
-                replacement = wrap_object(
-                    target, name, FunctionWrapper, (target_wrapper,)
-                )
-
-                try:
-                    return wrapped(*args, **kwargs)
-                finally:
-                    unwrap_object(target, name, replacement)
-
-            return FunctionWrapper(target_wrapped, _execute)
-
-        return FunctionWrapper(wrapper, _wrapper)
-
-    return _decorator
-
-
-@contextlib.contextmanager
-def scoped_function_wrapper(target, name, wrapper):
-    """Returns a context manager which patches a target function with a
-    wrapper function for the duration of a with statement, the block scoped
-    counterpart of the `transient_function_wrapper()` decorator. The
-    arguments take the same form as for `wrap_function_wrapper()`: the
-    `target` can be a module, class, or instance of a class, or the name of
-    a module as a string, the `name` is a string representing the dotted
-    path to the attribute, and the `wrapper` function should accept the
-    `wrapped`, `instance`, `args`, and `kwargs` arguments. The deferred
-    form of the `target` with a trailing ``?`` is not supported, since the
-    patch must be applied at the point the with statement is entered. The
-    context manager yields nothing, is single use, and removes the wrapper
-    using `unwrap_object()` when the block exits, with the same behaviour
-    as `transient_function_wrapper()` when something interfered with the
-    patch during the block: a wrapt wrapper applied on top of the temporary
-    wrapper and left there is tolerated, with the temporary wrapper spliced
-    out beneath it, while the temporary wrapper having been removed or
-    replaced raises `WrapperNotFoundError`, and a non wrapt wrapper left
-    applied on top raises `WrapperNotOutermostError`.
-    """
-
-    if isinstance(target, str) and target.endswith("?"):
-        raise ValueError(
-            "deferred wrapping using a target with a trailing '?' cannot "
-            "be used with scoped_function_wrapper()"
-        )
-
-    handle = wrap_function_wrapper(target, name, wrapper)
-
-    try:
-        yield
-    finally:
-        unwrap_object(target, name, handle)
-
-
-# Functions for introspecting chains of wrappers, linked by each wrapper
-# holding the object it wraps as the __wrapped__ attribute. The chain
-# protocol is shared by wrapt proxies and wrappers, functions decorated
-# using functools.wraps(), and anything else honouring the convention.
-
-
-def wrapper_chain(obj, *, limit=64):
-    """
-    Returns an iterator yielding `obj`, then each successive object found
-    by following the `__wrapped__` attribute, outermost wrapper first. The
-    final item yielded is the innermost object of the chain, which is not
-    itself a wrapper. Traversal ends cleanly at an object with no
-    `__wrapped__` attribute, or upon returning to an object already seen.
-    If the `limit` on the number of items yielded is reached with a further
-    chain link still pending, `WrapperChainTooDeepError` is raised, as a
-    truncated scan would otherwise be indistinguishable from a complete
-    one. A chain of exactly `limit` items which ends naturally is not an
-    error. Note that reading `__wrapped__` from a lazy object proxy will
-    cause it to materialize, and an exception raised by a broken proxy or
-    a lazy object factory will propagate to the caller.
-    """
-
-    # Cycle detection must use identity, not equality or a set of the
-    # objects themselves, since proxies delegate __eq__ and __hash__ to
-    # the wrapped object. Objects seen are therefore tracked by id(),
-    # with strong references also held so no visited object can be
-    # garbage collected and have its id reused while the scan runs, ids
-    # being unique among simultaneously live objects.
-
-    seen = []
-    seen_ids = set()
-
-    current = obj
-
-    while True:
-        if id(current) in seen_ids:
-            return
-
-        if len(seen) >= limit:
-            raise WrapperChainTooDeepError(
-                f"wrapper chain of {obj!r} exceeded {limit} levels"
-            )
-
-        seen.append(current)
-        seen_ids.add(id(current))
-
-        yield current
-
-        try:
-            current = current.__wrapped__
-        except AttributeError:
-            return
-
-
-def unwrapped(obj, *, limit=64):
-    """
-    Returns the innermost object of the chain of wrappers followed from
-    `obj` by the `wrapper_chain()` function, or `obj` itself when it is not
-    wrapped. Shares the full contract of `wrapper_chain()`, including
-    raising `WrapperChainTooDeepError` when the scan is indeterminate,
-    rather than returning a mid chain wrapper as if it were the innermost
-    object.
-    """
-
-    result = obj
-
-    for result in wrapper_chain(obj, limit=limit):
-        pass
-
-    return result
-
-
-def find_wrapper(obj, handle=None, *, predicate=None, limit=64):
-    """
-    Scans the chain of wrappers followed from `obj` by the
-    `wrapper_chain()` function for a specific wrapper and returns it, or
-    `None` when it is not present. The `handle` argument is the wrapper
-    object to look for, as returned by the wrap functions when the wrapper
-    was installed, and is matched by object identity only, never equality,
-    which proxies delegate to the wrapped object. Alternatively a
-    `predicate` function may be supplied, in which case the first chain
-    entry for which it returns true is returned, and is itself usable as a
-    handle thereafter. When both are supplied, both must match. At least
-    one of the two must be supplied, since testing for the mere presence
-    of any wrapper is fragile: were the target library to adopt wrapt for
-    its own purposes, such a test would wrongly conclude a wrapper of
-    yours was installed. Shares the full contract of `wrapper_chain()`,
-    including raising `WrapperChainTooDeepError` when the scan is
-    indeterminate, rather than returning `None` as a false negative.
-    """
-
-    if handle is None and predicate is None:
-        raise TypeError(
-            "find_wrapper() requires a wrapper handle or a predicate"
-        )
-
-    for entry in wrapper_chain(obj, limit=limit):
-        if handle is not None and entry is not handle:
-            continue
-        if predicate is not None and not predicate(entry):
-            continue
-        return entry
-
-    return None
-
-
-def is_wrapped_by(obj, handle=None, *, predicate=None, limit=64):
-    """
-    Boolean convenience form of the `find_wrapper()` function, returning
-    whether the wrapper is present in the chain of wrappers followed from
-    `obj`. With a `handle`, this answers whether the wrapper it was
-    returned for when installed is still in place, which is the check to
-    run when a third party may have replaced the attribute wholesale.
-    Shares the full contract of `find_wrapper()`, including raising
-    `WrapperChainTooDeepError` when the scan is indeterminate, rather
-    than returning `False` as a false negative.
-    """
-
-    return find_wrapper(obj, handle, predicate=predicate, limit=limit) is not None
-
-
-def unwrap_object(target, name, handle, *, missing_ok=False):
-    """
-    Removes a wrapper which was installed on an attribute of a target
-    object, the inverse of the `wrap_object()` function and the removal
-    call for every wrap form, `wrap_function_wrapper()` and
-    `wrap_object_attribute()` included. The `target` and `name` arguments
-    take the same form as for `resolve_path()`. The `handle` argument is
-    the wrapper object which was returned when the wrapper was installed,
-    and is matched by object identity only. Note that it is not the
-    wrapper function: passing the wrapper function surfaces immediately
-    as `WrapperNotFoundError`, since a function is never a chain entry.
-
-    When the wrapper is found and is outermost, the attribute is restored
-    to the object the wrapper wrapped, at the location where the attribute
-    is actually defined per `resolve_owner()`, so removal through a
-    subclass restores the defining base class rather than leaving a
-    shadowing copy. If restoring would merely shadow the identical object
-    already reachable through the MRO, or the wrapper was installed where
-    no prior definition existed (a `MISSING` terminal), the attribute is
-    instead removed so no residue is left behind. When the wrapper is
-    found buried beneath other wrapt wrappers, it is spliced out of the
-    chain in place, without touching the attribute or disturbing the
-    wrappers above it. When what sits directly above it is not a wrapt
-    wrapper, such as a plain `functools.wraps()` closure whose
-    `__wrapped__` is only metadata, `WrapperNotOutermostError` is raised
-    naming what is above, since splicing there would silently not take
-    effect.
-
-    When the wrapper is not found, because the attribute was never
-    wrapped, the wrapper was already removed, or a third party replaced
-    the attribute wholesale, `WrapperNotFoundError` is raised by default.
-    Passing `missing_ok=True` returns `None` instead, for shutdown paths
-    which must tolerate third party interference. In either case nothing
-    is mutated. The wrapper which was removed is returned. Note that
-    `missing_ok` does not suppress `WrapperChainTooDeepError` from the
-    underlying scan, since an indeterminate scan is not the same thing as
-    the wrapper being gone.
-    """
-
-    try:
-        owner, attribute, current = resolve_owner(target, name)
-    except PathResolutionError as exc:
-        # The attribute is either wholly absent or served dynamically
-        # with no owning location. In neither case is anything of the
-        # caller's statically installed, so both are the not-found
-        # case, except when the wrapper is present in the dynamically
-        # served value, where removal is simply not possible.
-
-        try:
-            current = resolve_path(target, name)[2]
-        except PathResolutionError:
-            current = None
-
-        if current is not None and find_wrapper(current, handle) is not None:
-            raise WrapperNotOutermostError(
-                f"cannot remove {type(handle).__name__} from "
-                f"{target!r}.{name}: the attribute is served dynamically "
-                f"and has no owning location to restore"
-            ) from exc
-
-        if missing_ok:
-            return None
-
-        raise WrapperNotFoundError(
-            f"handle {handle!r} not found on {target!r}.{name}"
-        ) from exc
-
-    found = find_wrapper(current, handle)
-
-    if found is not None:
-        try:
-            restored = found.__wrapped__
-        except AttributeError:
-            # The terminal original object was matched, which the chain
-            # also yields; not being a wrapper, it is not a legitimate
-            # handle.
-            found = None
-
-    if found is None:
-        if missing_ok:
-            return None
-        raise WrapperNotFoundError(
-            f"handle {handle!r} not found on {target!r}.{name}"
-        )
-
-    if found is not current:
-        chain = list(wrapper_chain(current))
-
-        # The scan must use identity, since list.index() would use
-        # __eq__, which proxies delegate to the wrapped object.
-
-        position = next(
-            index for index, entry in enumerate(chain) if entry is found
-        )
-        neighbour = chain[position - 1]
-
-        if not issubclass(type(neighbour), BaseObjectProxy):
-            above = [type(entry).__name__ for entry in chain[:position]]
-            raise WrapperNotOutermostError(
-                f"cannot remove {type(found).__name__} from "
-                f"{target!r}.{name}: wrapped by {above}"
-            )
-
-        neighbour.__wrapped__ = restored
-        return found
-
-    if restored is MISSING:
-        # The wrapper was installed where no prior definition existed.
-        delattr(owner, attribute)
-        return found
-
-    # When wrap_object() installed the wrapper, it recorded on the
-    # wrapper itself whether applying the patch created the attribute
-    # slot. That fact is authoritative: since the wrapper is still
-    # installed and outermost here, the slot cannot have been touched
-    # since it was recorded. It must be read from the proxy's own local
-    # state only, since ordinary attribute access would delegate a
-    # missing entry to the wrapped object and could answer with an
-    # inner wrapper's record instead.
-
-    try:
-        created = found.__self_dict__.get("__wrapt_wrap_object_created_slot__")
-    except AttributeError:
-        created = None
-
-    if created is not None:
-        if created:
-            # Installing the wrapper created a shadowing slot, so
-            # removing the attribute reinstates the original lookup,
-            # be that through the MRO, the class of an instance, or a
-            # dynamic __getattr__, rather than leaving a permanent
-            # copy of the original behind.
-            delattr(owner, attribute)
-        else:
-            apply_patch(owner, attribute, restored)
-        return found
-
-    # The wrapper does not carry the installation record, so fall back
-    # to what can be determined at removal time: if removing the
-    # attribute from a class would re-expose the identical restored
-    # object through the MRO, the wrap must have created a shadow.
-
-    if inspect.isclass(owner):
-        inherited = next(
-            (
-                vars(cls)[attribute]
-                for cls in inspect.getmro(owner)[1:]
-                if attribute in vars(cls)
-            ),
-            None,
-        )
-        if inherited is restored:
-            delattr(owner, attribute)
-            return found
-
-    apply_patch(owner, attribute, restored)
-    return found
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py
deleted file mode 100644
index 18c80e0523e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/proxies.py
+++ /dev/null
@@ -1,386 +0,0 @@
-"""Variants of ObjectProxy for different use cases."""
-
-from collections.abc import Callable
-from types import ModuleType
-
-from .__wrapt__ import BaseObjectProxy
-from .synchronization import synchronized
-
-# Define ObjectProxy which for compatibility adds `__iter__()` support which
-# has been removed from `BaseObjectProxy`.
-
-
-class ObjectProxy(BaseObjectProxy):
-    """A generic object proxy which forwards special methods as needed.
-    For backwards compatibility this class adds support for `__iter__()`. If
-    you don't need backward compatibility for `__iter__()` support then it is
-    preferable to use `BaseObjectProxy` directly. If you want automatic
-    support for special dunder methods for callables, iterators, and async,
-    then use `AutoObjectProxy`."""
-
-    @property
-    def __object_proxy__(self):
-        return ObjectProxy
-
-    def __iter__(self):
-        return iter(self.__wrapped__)
-
-
-# Define variant of ObjectProxy which can automatically adjust to the wrapped
-# object and add special dunder methods.
-
-
-def __wrapper_call__(*args, **kwargs):
-    def _unpack_self(self, *args):
-        return self, args
-
-    self, args = _unpack_self(*args)
-
-    return self.__wrapped__(*args, **kwargs)
-
-
-def __wrapper_iter__(self):
-    return iter(self.__wrapped__)
-
-
-def __wrapper_next__(self):
-    return self.__wrapped__.__next__()
-
-
-def __wrapper_aiter__(self):
-    return self.__wrapped__.__aiter__()
-
-
-async def __wrapper_anext__(self):
-    return await self.__wrapped__.__anext__()
-
-
-def __wrapper_length_hint__(self):
-    return self.__wrapped__.__length_hint__()
-
-
-def __wrapper_fspath__(self):
-    return self.__wrapped__.__fspath__()
-
-
-def __wrapper_await__(self):
-    return (yield from self.__wrapped__.__await__())
-
-
-def __wrapper_get__(self, instance, owner=None):
-    return self.__wrapped__.__get__(instance, owner)
-
-
-def __wrapper_set__(self, instance, value):
-    return self.__wrapped__.__set__(instance, value)
-
-
-def __wrapper_delete__(self, instance):
-    return self.__wrapped__.__delete__(instance)
-
-
-def __wrapper_set_name__(self, owner, name):
-    return self.__wrapped__.__set_name__(owner, name)
-
-
-class AutoObjectProxy(BaseObjectProxy):
-    """An object proxy which can automatically adjust to the wrapped object
-    and add special dunder methods as needed. Note that this creates a new
-    class for each instance, so it has much higher memory overhead than using
-    `BaseObjectProxy` directly. If you know what special dunder methods you need
-    then it is preferable to use `BaseObjectProxy` directly and add them to a
-    subclass as needed. If you only need `__iter__()` support for backwards
-    compatibility then use `ObjectProxy` instead.
-    """
-
-    def __new__(cls, wrapped, *args, **kwargs):
-        """Injects special dunder methods into a dynamically created subclass
-        as needed based on the wrapped object. Any further arguments are
-        those a derived class has added to `__init__()` and are ignored.
-        """
-
-        namespace = {}
-
-        # Special methods are only ever looked up on the type of the wrapped
-        # object, never on the instance itself, so the special methods to add
-        # are determined from dir() of the type of the wrapped object. For a
-        # class the type is its metaclass, as the special methods a class
-        # defines in its body apply to its instances, not to the class
-        # itself.
-
-        wrapped_attrs = dir(type(wrapped))
-        class_attrs = set(dir(cls))
-
-        if callable(wrapped) and "__call__" not in class_attrs:
-            namespace["__call__"] = __wrapper_call__
-
-        if "__iter__" in wrapped_attrs and "__iter__" not in class_attrs:
-            namespace["__iter__"] = __wrapper_iter__
-
-        if "__next__" in wrapped_attrs and "__next__" not in class_attrs:
-            namespace["__next__"] = __wrapper_next__
-
-        if "__aiter__" in wrapped_attrs and "__aiter__" not in class_attrs:
-            namespace["__aiter__"] = __wrapper_aiter__
-
-        if "__anext__" in wrapped_attrs and "__anext__" not in class_attrs:
-            namespace["__anext__"] = __wrapper_anext__
-
-        if "__length_hint__" in wrapped_attrs and "__length_hint__" not in class_attrs:
-            namespace["__length_hint__"] = __wrapper_length_hint__
-
-        if "__fspath__" in wrapped_attrs and "__fspath__" not in class_attrs:
-            namespace["__fspath__"] = __wrapper_fspath__
-
-        # Note that not providing compatibility with generator-based coroutines
-        # (PEP 342) here as they are removed in Python 3.11+ and were deprecated
-        # in 3.8.
-
-        if "__await__" in wrapped_attrs and "__await__" not in class_attrs:
-            namespace["__await__"] = __wrapper_await__
-
-        if "__get__" in wrapped_attrs and "__get__" not in class_attrs:
-            namespace["__get__"] = __wrapper_get__
-
-        if "__set__" in wrapped_attrs and "__set__" not in class_attrs:
-            namespace["__set__"] = __wrapper_set__
-
-        if "__delete__" in wrapped_attrs and "__delete__" not in class_attrs:
-            namespace["__delete__"] = __wrapper_delete__
-
-        if "__set_name__" in wrapped_attrs and "__set_name__" not in class_attrs:
-            namespace["__set_name__"] = __wrapper_set_name__
-
-        name = cls.__name__
-
-        if cls is AutoObjectProxy:
-            name = BaseObjectProxy.__name__
-
-        # Explicit class in super() is required here to ensure __new__
-        # is called on the parent of AutoObjectProxy, not the dynamically
-        # created subclass.
-        return super(AutoObjectProxy, cls).__new__(type(name, (cls,), namespace))
-
-    def __wrapped_setattr_fixups__(self):
-        """Adjusts special dunder methods on the class as needed based on the
-        wrapped object, when `__wrapped__` is changed.
-        """
-
-        cls = type(self)
-        class_attrs = set(dir(cls))
-
-        # As for __new__() above, special methods are only ever looked up on
-        # the type of the wrapped object, never on the instance itself, so
-        # check for them on the type of the wrapped object.
-
-        wrapped_type = type(self.__wrapped__)
-
-        if callable(self.__wrapped__):
-            if "__call__" not in class_attrs:
-                cls.__call__ = __wrapper_call__
-        elif getattr(cls, "__call__", None) is __wrapper_call__:
-            delattr(cls, "__call__")
-
-        if hasattr(wrapped_type, "__iter__"):
-            if "__iter__" not in class_attrs:
-                cls.__iter__ = __wrapper_iter__
-        elif getattr(cls, "__iter__", None) is __wrapper_iter__:
-            delattr(cls, "__iter__")
-
-        if hasattr(wrapped_type, "__next__"):
-            if "__next__" not in class_attrs:
-                cls.__next__ = __wrapper_next__
-        elif getattr(cls, "__next__", None) is __wrapper_next__:
-            delattr(cls, "__next__")
-
-        if hasattr(wrapped_type, "__aiter__"):
-            if "__aiter__" not in class_attrs:
-                cls.__aiter__ = __wrapper_aiter__
-        elif getattr(cls, "__aiter__", None) is __wrapper_aiter__:
-            delattr(cls, "__aiter__")
-
-        if hasattr(wrapped_type, "__anext__"):
-            if "__anext__" not in class_attrs:
-                cls.__anext__ = __wrapper_anext__
-        elif getattr(cls, "__anext__", None) is __wrapper_anext__:
-            delattr(cls, "__anext__")
-
-        if hasattr(wrapped_type, "__length_hint__"):
-            if "__length_hint__" not in class_attrs:
-                cls.__length_hint__ = __wrapper_length_hint__
-        elif getattr(cls, "__length_hint__", None) is __wrapper_length_hint__:
-            delattr(cls, "__length_hint__")
-
-        if hasattr(wrapped_type, "__fspath__"):
-            if "__fspath__" not in class_attrs:
-                cls.__fspath__ = __wrapper_fspath__
-        elif getattr(cls, "__fspath__", None) is __wrapper_fspath__:
-            delattr(cls, "__fspath__")
-
-        if hasattr(wrapped_type, "__await__"):
-            if "__await__" not in class_attrs:
-                cls.__await__ = __wrapper_await__
-        elif getattr(cls, "__await__", None) is __wrapper_await__:
-            delattr(cls, "__await__")
-
-        if hasattr(wrapped_type, "__get__"):
-            if "__get__" not in class_attrs:
-                cls.__get__ = __wrapper_get__
-        elif getattr(cls, "__get__", None) is __wrapper_get__:
-            delattr(cls, "__get__")
-
-        if hasattr(wrapped_type, "__set__"):
-            if "__set__" not in class_attrs:
-                cls.__set__ = __wrapper_set__
-        elif getattr(cls, "__set__", None) is __wrapper_set__:
-            delattr(cls, "__set__")
-
-        if hasattr(wrapped_type, "__delete__"):
-            if "__delete__" not in class_attrs:
-                cls.__delete__ = __wrapper_delete__
-        elif getattr(cls, "__delete__", None) is __wrapper_delete__:
-            delattr(cls, "__delete__")
-
-        if hasattr(wrapped_type, "__set_name__"):
-            if "__set_name__" not in class_attrs:
-                cls.__set_name__ = __wrapper_set_name__
-        elif getattr(cls, "__set_name__", None) is __wrapper_set_name__:
-            delattr(cls, "__set_name__")
-
-
-class LazyObjectProxy(AutoObjectProxy):
-    """An object proxy which can generate/create the wrapped object on demand
-    when it is first needed.
-    """
-
-    def __new__(cls, callback=None, *args, interface=..., **kwargs):
-        """Injects special dunder methods into a dynamically created subclass
-        as needed based on the declared interface of the wrapped object. Any
-        further arguments are those a derived class has added to `__init__()`
-        and are ignored.
-        """
-
-        if interface is ...:
-            interface = type(None)
-
-        namespace = {}
-
-        interface_attrs = dir(interface)
-        class_attrs = set(dir(cls))
-
-        if "__call__" in interface_attrs and "__call__" not in class_attrs:
-            namespace["__call__"] = __wrapper_call__
-
-        if "__iter__" in interface_attrs and "__iter__" not in class_attrs:
-            namespace["__iter__"] = __wrapper_iter__
-
-        if "__next__" in interface_attrs and "__next__" not in class_attrs:
-            namespace["__next__"] = __wrapper_next__
-
-        if "__aiter__" in interface_attrs and "__aiter__" not in class_attrs:
-            namespace["__aiter__"] = __wrapper_aiter__
-
-        if "__anext__" in interface_attrs and "__anext__" not in class_attrs:
-            namespace["__anext__"] = __wrapper_anext__
-
-        if (
-            "__length_hint__" in interface_attrs
-            and "__length_hint__" not in class_attrs
-        ):
-            namespace["__length_hint__"] = __wrapper_length_hint__
-
-        if "__fspath__" in interface_attrs and "__fspath__" not in class_attrs:
-            namespace["__fspath__"] = __wrapper_fspath__
-
-        # Note that not providing compatibility with generator-based coroutines
-        # (PEP 342) here as they are removed in Python 3.11+ and were deprecated
-        # in 3.8.
-
-        if "__await__" in interface_attrs and "__await__" not in class_attrs:
-            namespace["__await__"] = __wrapper_await__
-
-        if "__get__" in interface_attrs and "__get__" not in class_attrs:
-            namespace["__get__"] = __wrapper_get__
-
-        if "__set__" in interface_attrs and "__set__" not in class_attrs:
-            namespace["__set__"] = __wrapper_set__
-
-        if "__delete__" in interface_attrs and "__delete__" not in class_attrs:
-            namespace["__delete__"] = __wrapper_delete__
-
-        if "__set_name__" in interface_attrs and "__set_name__" not in class_attrs:
-            namespace["__set_name__"] = __wrapper_set_name__
-
-        name = cls.__name__
-
-        # Explicit class in super() is required here to ensure __new__
-        # is called on the parent of AutoObjectProxy, not the dynamically
-        # created subclass.
-        return super(AutoObjectProxy, cls).__new__(type(name, (cls,), namespace))
-
-    def __init__(self, callback=None, *, interface=...):
-        """Initialize the object proxy with wrapped object as `None` but due
-        to presence of special `__wrapped_factory__` attribute addded first,
-        this will actually trigger the deferred creation of the wrapped object
-        when first needed.
-        """
-
-        if callback is not None:
-            self.__wrapped_factory__ = callback
-
-        super().__init__(None)
-
-    __wrapped_get_called__ = False
-
-    def __wrapped_factory__(self):
-        return None
-
-    def __wrapped_get__(self):
-        """Gets the wrapped object, creating it if necessary."""
-
-        # We synchronize on the class type, which will be unique to this instance
-        # since we inherit from `AutoObjectProxy` which creates a new class
-        # for each instance. If we synchronize on `self` or the method then
-        # we can end up in infinite recursion via `__getattr__()`.
-
-        with synchronized(type(self)):
-            # We were called because `__wrapped__` was not set, but because of
-            # multiple threads we may find that it has been set by the time
-            # we get the lock. So check again now whether `__wrapped__` is set.
-            # If it is then just return it, otherwise call the factory to
-            # create it.
-
-            if self.__wrapped_get_called__:
-                return self.__wrapped__
-
-            self.__wrapped__ = self.__wrapped_factory__()
-
-            self.__wrapped_get_called__ = True
-
-            return self.__wrapped__
-
-
-def lazy_import(name, attribute=None, *, interface=...):
-    """Lazily imports the module `name`, returning a `LazyObjectProxy` which
-    will import the module when it is first needed. When `name is a dotted name,
-    then the full dotted name is imported and the last module is taken as the
-    target. If `attribute` is provided then it is used to retrieve an attribute
-    from the module.
-    """
-
-    if attribute is not None:
-        if interface is ...:
-            interface = Callable
-    else:
-        if interface is ...:
-            interface = ModuleType
-
-    def _import():
-        module = __import__(name, fromlist=[""])
-
-        if attribute is not None:
-            return getattr(module, attribute)
-
-        return module
-
-    return LazyObjectProxy(_import, interface=interface)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py
deleted file mode 100644
index a0a7e6e4ce8..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/signature.py
+++ /dev/null
@@ -1,270 +0,0 @@
-"""The `with_signature` decorator: override the signature (and related
-introspection attributes) of a wrapped callable without mutating the wrapped
-function itself. Accepts a prototype callable, a prebuilt `inspect.Signature`,
-or a factory that derives a signature from the wrapped function at decoration
-time.
-
-This replaces the need for the `adapter=` argument of `wrapt.decorator`,
-which is planned for deprecation.
-"""
-
-from inspect import CO_VARARGS, CO_VARKEYWORDS, Parameter, Signature
-from inspect import signature as _inspect_signature
-
-from .__wrapt__ import (
-    BaseObjectProxy,
-    BoundFunctionWrapper,
-    CallableObjectProxy,
-    FunctionWrapper,
-)
-from .doc import _BOUND_DOC_PROPERTY, _DOC_PROPERTY, _NO_DOC_OVERRIDE
-
-_MISSING = object()
-
-
-def _cached(attr):
-    """Read-only property that memoizes its derivation in a `_self_*` slot.
-
-    `functools.cached_property` is unusable on ObjectProxy subclasses: wrapt
-    overrides `__dict__` with a property returning the wrapped object's dict,
-    so cached_property's `instance.__dict__[name] = value` would mutate the
-    wrapped function. Storing under a `_self_*` name routes through wrapt's
-    own setattr handling and lands in the proxy's real instance dict. Using
-    a `@property` (data descriptor) also ensures we win over any value
-    copied into the instance dict by `FunctionWrapper.__init__`.
-    """
-    slot = f"_self_cached_{attr.lstrip('_')}"
-
-    def getter(self):
-        value = getattr(self, slot, _MISSING)
-        if value is _MISSING:
-            value = self._derive(attr)
-            self.__self_setattr__(slot, value)
-        return value
-
-    return property(getter)
-
-
-def _derive_annotations(sig):
-    ann = {
-        p.name: p.annotation
-        for p in sig.parameters.values()
-        if p.annotation is not Parameter.empty
-    }
-    if sig.return_annotation is not Signature.empty:
-        ann["return"] = sig.return_annotation
-    return ann
-
-
-def _derive_defaults(sig):
-    defaults = tuple(
-        p.default
-        for p in sig.parameters.values()
-        if p.kind in (Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD)
-        and p.default is not Parameter.empty
-    )
-    return defaults or None
-
-
-def _derive_kwdefaults(sig):
-    kwdefaults = {
-        p.name: p.default
-        for p in sig.parameters.values()
-        if p.kind is Parameter.KEYWORD_ONLY and p.default is not Parameter.empty
-    }
-    return kwdefaults or None
-
-
-def _derive_varnames(sig):
-    pos_only, pos_or_kw, kw_only = [], [], []
-    var_pos = var_kw = None
-    for p in sig.parameters.values():
-        if p.kind is Parameter.POSITIONAL_ONLY:
-            pos_only.append(p.name)
-        elif p.kind is Parameter.POSITIONAL_OR_KEYWORD:
-            pos_or_kw.append(p.name)
-        elif p.kind is Parameter.VAR_POSITIONAL:
-            var_pos = p.name
-        elif p.kind is Parameter.KEYWORD_ONLY:
-            kw_only.append(p.name)
-        elif p.kind is Parameter.VAR_KEYWORD:
-            var_kw = p.name
-    names = pos_only + pos_or_kw + kw_only
-    if var_pos:
-        names.append(var_pos)
-    if var_kw:
-        names.append(var_kw)
-    return tuple(names)
-
-
-class _SignatureCode(BaseObjectProxy):
-    """Code-object proxy deriving argument-related co_* attrs from a Signature.
-
-    Non-argument bits (co_flags for coroutine/generator, co_filename, etc.)
-    fall through to the wrapped function's real __code__.
-    """
-
-    def __init__(self, wrapped, signature):
-        super().__init__(wrapped)
-        self._self_signature = signature
-
-    def _derive(self, attr):
-        sig = self._self_signature
-        if attr == "co_argcount":
-            kinds = (Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD)
-            return sum(p.kind in kinds for p in sig.parameters.values())
-        if attr == "co_posonlyargcount":
-            return sum(
-                p.kind is Parameter.POSITIONAL_ONLY for p in sig.parameters.values()
-            )
-        if attr == "co_kwonlyargcount":
-            return sum(
-                p.kind is Parameter.KEYWORD_ONLY for p in sig.parameters.values()
-            )
-        if attr == "co_varnames":
-            return _derive_varnames(sig)
-        if attr == "co_flags":
-            kinds = {p.kind for p in sig.parameters.values()}
-            flags = self.__wrapped__.co_flags & ~(CO_VARARGS | CO_VARKEYWORDS)
-            if Parameter.VAR_POSITIONAL in kinds:
-                flags |= CO_VARARGS
-            if Parameter.VAR_KEYWORD in kinds:
-                flags |= CO_VARKEYWORDS
-            return flags
-        raise AttributeError(attr)
-
-    co_argcount = _cached("co_argcount")
-    co_posonlyargcount = _cached("co_posonlyargcount")
-    co_kwonlyargcount = _cached("co_kwonlyargcount")
-    co_varnames = _cached("co_varnames")
-    co_flags = _cached("co_flags")
-
-
-class _SignatureMixin:
-    """Shared Signature-derived introspection attrs for wrapper + surrogate."""
-
-    def _derive(self, attr):
-        sig = self._self_signature
-        if attr == "__annotations__":
-            return _derive_annotations(sig)
-        if attr == "__defaults__":
-            return _derive_defaults(sig)
-        if attr == "__kwdefaults__":
-            return _derive_kwdefaults(sig)
-        if attr == "__code__":
-            return _SignatureCode(self.__wrapped__.__code__, sig)
-        raise AttributeError(attr)
-
-    @property
-    def __signature__(self):
-        return self._self_signature
-
-    __annotations__ = _cached("__annotations__")
-    __defaults__ = _cached("__defaults__")
-    __kwdefaults__ = _cached("__kwdefaults__")
-    __code__ = _cached("__code__")
-
-
-class _SignatureFunctionSurrogate(_SignatureMixin, CallableObjectProxy):
-    """Function surrogate exposing Signature-derived introspection attrs.
-
-    Used as __func__ of a bound wrapper so that inspect.signature -- which
-    treats the bound wrapper as a MethodType and consults __func__ -- sees
-    our override and strips self/cls correctly.
-    """
-
-    def __init__(self, wrapped, signature):
-        super().__init__(wrapped)
-        self._self_signature = signature
-
-
-class _BoundSignatureFunctionWrapper(BoundFunctionWrapper):
-    __doc__ = _BOUND_DOC_PROPERTY
-
-    @property
-    def __func__(self):
-        return _SignatureFunctionSurrogate(
-            self.__wrapped__.__func__, self._self_parent._self_signature
-        )
-
-    @property
-    def __signature__(self):
-        return self._self_parent._self_signature
-
-
-class _SignatureFunctionWrapper(_SignatureMixin, FunctionWrapper):
-    __doc__ = _DOC_PROPERTY
-
-    __bound_function_wrapper__ = _BoundSignatureFunctionWrapper
-
-    def __init__(self, wrapped, wrapper, signature, doc=_NO_DOC_OVERRIDE):
-        super().__init__(wrapped, wrapper)
-        self._self_signature = signature
-        self._self_doc = doc
-
-    @property
-    def __func__(self):
-        return _SignatureFunctionSurrogate(self.__wrapped__, self._self_signature)
-
-
-def with_signature(
-    wrapped=None, /, *, prototype=None, signature=None, factory=None, doc=None
-):
-    """Override the signature of a wrapped callable.
-
-    Exactly one of `prototype`, `signature`, or `factory` must be supplied:
-
-    - `prototype`: a callable whose signature will be used.
-    - `signature`: a prebuilt `inspect.Signature` object.
-    - `factory`: a callable `factory(wrapped)` invoked at decoration time
-      that returns either a `Signature` or a prototype callable, or a
-      tuple of `(signature_or_prototype, docstring)` to override the
-      docstring at the same time.
-
-    The docstring may also be overridden by supplying `doc`, in which case
-    a docstring from the factory is ignored. When neither is supplied the
-    wrapper reports the docstring of the wrapped function as normal.
-
-    The resulting wrapper exposes the override via `__signature__`, and
-    derives `__annotations__`, `__defaults__`, `__kwdefaults__`, and the
-    argument-related attributes of `__code__` from the same source. The
-    wrapped function is not mutated. Calling behaviour is unchanged.
-    """
-
-    specified = sum(x is not None for x in (prototype, signature, factory))
-    if specified == 0:
-        raise TypeError(
-            "with_signature requires one of prototype=, signature=, or factory="
-        )
-    if specified > 1:
-        raise TypeError(
-            "with_signature accepts only one of prototype=, signature=, or factory="
-        )
-
-    def _decorator(wrapped):
-        def _wrapper(wrapped, instance, args, kwargs):
-            return wrapped(*args, **kwargs)
-
-        resolved_doc = _NO_DOC_OVERRIDE if doc is None else doc
-
-        if signature is not None:
-            resolved = signature
-        elif prototype is not None:
-            resolved = _inspect_signature(prototype)
-        else:
-            produced = factory(wrapped)
-            if isinstance(produced, tuple):
-                produced, produced_doc = produced
-                if doc is None:
-                    resolved_doc = produced_doc
-            resolved = (
-                produced
-                if isinstance(produced, Signature)
-                else _inspect_signature(produced)
-            )
-
-        return _SignatureFunctionWrapper(wrapped, _wrapper, resolved, resolved_doc)
-
-    if wrapped is None:
-        return _decorator
-    return _decorator(wrapped)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py
deleted file mode 100644
index d51704b494e..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/synchronization.py
+++ /dev/null
@@ -1,540 +0,0 @@
-"""Synchronization decorators and calling-convention markers/bridges.
-
-Provides ``synchronized`` for thread and async locking, ``mark_as_sync``
-and ``mark_as_async`` for declaring the effective calling convention of a
-wrapped callable (without converting it), and ``async_to_sync`` /
-``sync_to_async`` for bridging between the two.
-"""
-
-import asyncio
-import sys
-import warnings
-from functools import partial
-from inspect import (
-    CO_ASYNC_GENERATOR,
-    CO_COROUTINE,
-    CO_GENERATOR,
-    CO_ITERABLE_COROUTINE,
-    isasyncgenfunction,
-    iscoroutinefunction,
-    isgeneratorfunction,
-)
-from threading import Lock, RLock
-
-from .__wrapt__ import BoundFunctionWrapper, CallableObjectProxy, FunctionWrapper
-from .decorators import decorator
-
-# Calling-convention marker wrappers. These manipulate __code__.co_flags
-# so that inspect.iscoroutinefunction() reports the intended calling
-# convention, which lets stdlib code and the synchronized() decorator
-# auto-select the correct sync or async wrapping behaviour even when
-# stacked decorators change the effective convention (for example an
-# inner decorator that invokes an async def via asyncio.run()).
-
-
-class _SyncCodeProxy(CallableObjectProxy):
-
-    def __init__(self, wrapped, generator=None):
-        super().__init__(wrapped)
-        self._self_generator = generator
-
-    @property
-    def co_flags(self):
-        original = self.__wrapped__.co_flags
-        # Strip async-axis and iterable-coroutine bits; sync means neither
-        # coroutine function nor async generator nor types.coroutine-style.
-        flags = original & ~(CO_COROUTINE | CO_ASYNC_GENERATOR | CO_ITERABLE_COROUTINE)
-        if self._self_generator is True:
-            flags |= CO_GENERATOR
-        elif self._self_generator is False:
-            flags &= ~CO_GENERATOR
-        else:
-            # Auto: if input was an async generator, preserve generator-ness
-            # on the sync side by setting CO_GENERATOR. Otherwise leave
-            # CO_GENERATOR as-is (already copied from the wrapped flags).
-            if original & CO_ASYNC_GENERATOR:
-                flags |= CO_GENERATOR
-        return flags
-
-
-class _SyncFunctionSurrogate(CallableObjectProxy):
-
-    def __init__(self, wrapped, generator=None):
-        super().__init__(wrapped)
-        self._self_generator = generator
-
-    @property
-    def __code__(self):
-        return _SyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
-
-
-class _BoundSyncFunctionWrapper(BoundFunctionWrapper):
-
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-        self._self_is_not_coroutine = True
-
-    @property
-    def __func__(self):
-        return _SyncFunctionSurrogate(
-            self.__wrapped__.__func__, self._self_parent._self_generator
-        )
-
-
-class _SyncFunctionWrapper(FunctionWrapper):
-
-    __bound_function_wrapper__ = _BoundSyncFunctionWrapper
-
-    def __init__(self, wrapped, wrapper, generator=None):
-        super().__init__(wrapped, wrapper)
-        self._self_is_not_coroutine = True
-        self._self_generator = generator
-
-    @property
-    def __code__(self):
-        return _SyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
-
-
-class _AsyncCodeProxy(CallableObjectProxy):
-
-    def __init__(self, wrapped, generator=None):
-        super().__init__(wrapped)
-        self._self_generator = generator
-
-    @property
-    def co_flags(self):
-        original = self.__wrapped__.co_flags
-        # Strip all four convention bits; we reassert the right ones below.
-        flags = original & ~(
-            CO_GENERATOR | CO_COROUTINE | CO_ITERABLE_COROUTINE | CO_ASYNC_GENERATOR
-        )
-        if self._self_generator is True:
-            flags |= CO_ASYNC_GENERATOR
-        elif self._self_generator is False:
-            flags |= CO_COROUTINE
-        else:
-            # Auto: if input was a generator (sync or async), produce an
-            # async generator; otherwise produce a coroutine function.
-            if original & (CO_GENERATOR | CO_ASYNC_GENERATOR):
-                flags |= CO_ASYNC_GENERATOR
-            else:
-                flags |= CO_COROUTINE
-        return flags
-
-
-class _AsyncFunctionSurrogate(CallableObjectProxy):
-
-    def __init__(self, wrapped, generator=None):
-        super().__init__(wrapped)
-        self._self_generator = generator
-
-    @property
-    def __code__(self):
-        return _AsyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
-
-
-class _BoundAsyncFunctionWrapper(BoundFunctionWrapper):
-
-    @property
-    def __func__(self):
-        return _AsyncFunctionSurrogate(
-            self.__wrapped__.__func__, self._self_parent._self_generator
-        )
-
-
-class _AsyncFunctionWrapper(FunctionWrapper):
-
-    __bound_function_wrapper__ = _BoundAsyncFunctionWrapper
-
-    def __init__(self, wrapped, wrapper, generator=None):
-        super().__init__(wrapped, wrapper)
-        self._self_generator = generator
-
-    @property
-    def __code__(self):
-        return _AsyncCodeProxy(self.__wrapped__.__code__, self._self_generator)
-
-
-def mark_as_sync(wrapped=None, /, *, generator=None):
-    """Mark a callable as synchronous from the perspective of calling
-    convention detection. The returned wrapper is a pass-through that
-    reports `inspect.iscoroutinefunction()` as False regardless of
-    whether the underlying callable is declared `async def`. Useful
-    when a stacked decorator has already collapsed an async function
-    into a synchronous one (for example by using `asyncio.run()`).
-
-    The `generator` keyword toggles the sync generator bit
-    (`CO_GENERATOR`) on the resulting wrapper. Tri-state:
-
-    - `None` (default): auto. Preserve generator-ness from the input --
-      if the input was an async generator, the wrapper reports as a sync
-      generator; otherwise CO_GENERATOR is copied through unchanged.
-    - `True`: force CO_GENERATOR on. Wrapper reports as a sync generator.
-    - `False`: force CO_GENERATOR off. Wrapper reports as a plain sync
-      function even if the input had CO_GENERATOR set.
-
-    Regardless of `generator`, CO_COROUTINE, CO_ASYNC_GENERATOR, and
-    CO_ITERABLE_COROUTINE are all cleared (sync means none of those).
-    """
-
-    def _decorator(wrapped):
-        def _wrapper(wrapped, instance, args, kwargs):
-            return wrapped(*args, **kwargs)
-
-        return _SyncFunctionWrapper(wrapped, _wrapper, generator=generator)
-
-    if wrapped is None:
-        return _decorator
-    return _decorator(wrapped)
-
-
-def mark_as_async(wrapped=None, /, *, generator=None):
-    """Mark a callable as asynchronous from the perspective of calling
-    convention detection. The returned wrapper reports
-    `inspect.iscoroutinefunction()` as True regardless of whether the
-    underlying callable is declared `async def`. Useful when a stacked
-    decorator returns a coroutine from a plain `def` wrapper.
-
-    The `generator` keyword chooses between coroutine function and
-    async generator reporting. Tri-state:
-
-    - `None` (default): auto. If the input was a sync or async
-      generator, the wrapper reports as an async generator
-      (`CO_ASYNC_GENERATOR`); otherwise it reports as a coroutine
-      function (`CO_COROUTINE`).
-    - `True`: force async generator reporting (`CO_ASYNC_GENERATOR` set,
-      `CO_COROUTINE` cleared). These two flags are mutually exclusive at
-      the CPython code-object level.
-    - `False`: force coroutine function reporting (`CO_COROUTINE` set,
-      `CO_ASYNC_GENERATOR` cleared).
-
-    CO_GENERATOR and CO_ITERABLE_COROUTINE are always cleared (the
-    async path does not use either).
-    """
-
-    def _decorator(wrapped):
-        def _wrapper(wrapped, instance, args, kwargs):
-            return wrapped(*args, **kwargs)
-
-        return _AsyncFunctionWrapper(wrapped, _wrapper, generator=generator)
-
-    if wrapped is None:
-        return _decorator
-    return _decorator(wrapped)
-
-
-def async_to_sync(wrapped):
-    """Adapt an async callable so it can be called synchronously. Each
-    call runs the coroutine to completion via `asyncio.run()`. The
-    returned wrapper reports as synchronous under
-    `inspect.iscoroutinefunction()`. Naming follows the asgiref
-    convention.
-
-    Generator functions of either convention are rejected with a
-    `TypeError`: `asyncio.run()` cannot run an async generator, and a
-    sync generator has nothing to run to completion. A callable not
-    reporting as a coroutine function produces a `UserWarning` rather
-    than an error, since convention detection has false negatives such
-    as a plain function wrapper which returns a coroutine; if the
-    callable really is asynchronous in behaviour, apply
-    `mark_as_async` to it first so it reports as such."""
-
-    if isasyncgenfunction(wrapped):
-        raise TypeError(
-            "async_to_sync cannot be applied to an async generator "
-            "function; asyncio.run() cannot run an async generator."
-        )
-
-    if isgeneratorfunction(wrapped):
-        raise TypeError(
-            "async_to_sync cannot be applied to a generator function; "
-            "there is no coroutine to run to completion. If the callable "
-            "is misreported and actually asynchronous in behaviour, apply "
-            "mark_as_async to it first."
-        )
-
-    if not iscoroutinefunction(wrapped):
-        # Detection has false negatives, such as a plain def wrapper
-        # which returns a coroutine, so this cannot be an error. Such a
-        # callable works here regardless, but marking it first also
-        # corrects what introspection reports elsewhere.
-        warnings.warn(
-            "async_to_sync was applied to a callable not reporting as a "
-            "coroutine function. If it is asynchronous in behaviour, "
-            "apply mark_as_async to it first so it reports as such.",
-            UserWarning,
-            stacklevel=2,
-        )
-
-    def wrapper(wrapped, instance, args, kwargs):
-        return asyncio.run(wrapped(*args, **kwargs))
-
-    return _SyncFunctionWrapper(wrapped, wrapper, generator=False)
-
-
-def sync_to_async(wrapped):
-    """Adapt a sync callable so it can be awaited. Each call dispatches
-    the synchronous work to the default executor via
-    `loop.run_in_executor()`. The returned wrapper reports as
-    asynchronous under `inspect.iscoroutinefunction()`. Naming follows
-    the asgiref convention.
-
-    Callables reporting as coroutine functions or generator functions
-    of either convention are rejected with a `TypeError`. For a
-    generator function the adaptation would be an illusion: only
-    creation of the generator would be dispatched to the executor,
-    which executes no body code, while each iteration would still block
-    the event loop. A callable misreported as asynchronous but
-    synchronous in behaviour can have `mark_as_sync` applied to it
-    first so it reports as such."""
-
-    if iscoroutinefunction(wrapped) or isasyncgenfunction(wrapped):
-        # Mirrors the equivalent check in asgiref. A callable which is
-        # misreported, such as a wrapper which runs an inner async def
-        # to completion, can be corrected with mark_as_sync first.
-        raise TypeError(
-            "sync_to_async can only be applied to a synchronous "
-            "callable. If the callable is misreported and actually "
-            "synchronous in behaviour, apply mark_as_sync to it first."
-        )
-
-    if isgeneratorfunction(wrapped):
-        raise TypeError(
-            "sync_to_async cannot be applied to a generator function; "
-            "creating the generator executes no code, and iterating it "
-            "would still block the event loop."
-        )
-
-    async def wrapper(wrapped, instance, args, kwargs):
-        loop = asyncio.get_running_loop()
-        return await loop.run_in_executor(None, partial(wrapped, *args, **kwargs))
-
-    return _AsyncFunctionWrapper(wrapped, wrapper, generator=False)
-
-
-def _synchronized_is_async_lock(obj):
-    return iscoroutinefunction(getattr(obj, "acquire", None))
-
-
-def _synchronized_is_async_callable(obj):
-    # Walk the __wrapped__ chain, returning True as soon as any layer
-    # declares itself a coroutine function. A sync marker wrapper can
-    # carry an authoritative `_self_is_not_coroutine` attribute that
-    # short-circuits the walk before it descends into a genuinely
-    # async inner layer. Cycle / runaway-chain protection modelled on
-    # inspect.unwrap().
-
-    memo = {id(obj): obj}
-    recursion_limit = sys.getrecursionlimit()
-    target = obj
-
-    while True:
-        if isinstance(target, (classmethod, staticmethod)):
-            inner = getattr(target, "__wrapped__", None)
-            if inner is None:
-                inner = target.__func__
-            target = inner
-            id_target = id(target)
-            if id_target in memo or len(memo) >= recursion_limit:
-                raise ValueError("wrapper loop when unwrapping {!r}".format(obj))
-            memo[id_target] = target
-            continue
-
-        if getattr(target, "_self_is_not_coroutine", False):
-            return False
-
-        if iscoroutinefunction(target):
-            return True
-
-        next_target = getattr(target, "__wrapped__", None)
-        if next_target is None or next_target is target:
-            return False
-        target = next_target
-        id_target = id(target)
-        if id_target in memo or len(memo) >= recursion_limit:
-            raise ValueError("wrapper loop when unwrapping {!r}".format(obj))
-        memo[id_target] = target
-
-
-# Decorator for implementing thread synchronization. It can be used as a
-# decorator, in which case the synchronization context is determined by
-# what type of function is wrapped, or it can also be used as a context
-# manager, where the user needs to supply the correct synchronization
-# context. It is also possible to supply an object which appears to be a
-# synchronization primitive of some sort, by virtue of having release()
-# and acquire() methods. In that case that will be used directly as the
-# synchronization primitive without creating a separate lock against the
-# derived or supplied context.
-
-
-def synchronized(wrapped):
-    """Depending on the nature of the `wrapped` object, will either return a
-    decorator which can be used to wrap a function or method, or a context
-    manager, both of which will act accordingly depending on how used, to
-    synchronize access to calling of the wrapped function, or the block of
-    code within the context manager. If it is an object which is a
-    synchronization primitive, such as a threading Lock, RLock, Semaphore,
-    Condition, or Event, then it is assumed that the object is to be used
-    directly as the synchronization primitive, otherwise a lock is created
-    automatically and attached to the wrapped object and used as the
-    synchronization primitive.
-
-    Async functions are supported: if the wrapped callable is an async
-    function, an `asyncio.Lock` is created for the context and the wrapper
-    awaits the lock. The returned object also exposes `__aenter__` and
-    `__aexit__` so it can be used with `async with` to synchronise a block
-    of code using an independent per-context `asyncio.Lock`. If an object
-    with coroutine `acquire`/`release` methods (such as an `asyncio.Lock`)
-    is supplied directly, the returned decorator and context manager will
-    use it via the async protocol.
-    """
-
-    # Determine if being passed an object which is a synchronization
-    # primitive. We can't check by type for Lock, RLock, Semaphore etc,
-    # as the means of creating them isn't the type. Therefore use the
-    # existence of acquire() and release() methods. This is more
-    # extensible anyway as it allows custom synchronization mechanisms.
-
-    if hasattr(wrapped, "acquire") and hasattr(wrapped, "release"):
-        # We remember what the original lock is and then return a new
-        # decorator which accesses and locks it. When returning the new
-        # decorator we wrap it with an object proxy so we can override
-        # the context manager methods in case it is being used to wrap
-        # synchronized statements with a 'with' statement.
-
-        lock = wrapped
-
-        if _synchronized_is_async_lock(lock):
-
-            @decorator
-            async def _synchronized(wrapped, instance, args, kwargs):
-                async with lock:
-                    return await wrapped(*args, **kwargs)
-
-            class _AsyncSynchronizedLockProxy(CallableObjectProxy):
-
-                async def __aenter__(self):
-                    await lock.acquire()
-                    return lock
-
-                async def __aexit__(self, *args):
-                    lock.release()
-
-            return _AsyncSynchronizedLockProxy(wrapped=_synchronized)
-
-        @decorator
-        def _synchronized(wrapped, instance, args, kwargs):
-            # Execute the wrapped function while the original supplied
-            # lock is held.
-
-            with lock:
-                return wrapped(*args, **kwargs)
-
-        class _SynchronizedLockProxy(CallableObjectProxy):
-
-            def __enter__(self):
-                lock.acquire()
-                return lock
-
-            def __exit__(self, *args):
-                lock.release()
-
-        return _SynchronizedLockProxy(wrapped=_synchronized)
-
-    # Following only apply when the lock is being created automatically
-    # based on the context of what was supplied. In this case we supply
-    # a final decorator, but need to use FunctionWrapper directly as we
-    # want to derive from it to add context manager methods in case it is
-    # being used to wrap synchronized statements with a 'with' statement.
-
-    def _synchronized_lock(context):
-        # Attempt to retrieve the lock for the specific context.
-
-        lock = vars(context).get("_synchronized_lock", None)
-
-        if lock is None:
-            # There is no existing lock defined for the context we
-            # are dealing with so we need to create one. This needs
-            # to be done in a way to guarantee there is only one
-            # created, even if multiple threads try and create it at
-            # the same time. We can't always use the setdefault()
-            # method on the __dict__ for the context. This is the
-            # case where the context is a class, as __dict__ is
-            # actually a dictproxy. What we therefore do is use a
-            # meta lock on this wrapper itself, to control the
-            # creation and assignment of the lock attribute against
-            # the context.
-
-            with synchronized._synchronized_meta_lock:
-                # We need to check again for whether the lock we want
-                # exists in case two threads were trying to create it
-                # at the same time and were competing to create the
-                # meta lock.
-
-                lock = vars(context).get("_synchronized_lock", None)
-
-                if lock is None:
-                    lock = RLock()
-                    setattr(context, "_synchronized_lock", lock)
-
-        return lock
-
-    def _synchronized_async_lock(context):
-        # Per-context asyncio.Lock, created lazily on first use. Created
-        # under the shared meta lock so creation is safe across threads;
-        # the meta lock is never held across an await. asyncio.Lock is
-        # not reentrant.
-
-        lock = vars(context).get("_synchronized_async_lock", None)
-
-        if lock is None:
-            with synchronized._synchronized_meta_lock:
-                lock = vars(context).get("_synchronized_async_lock", None)
-
-                if lock is None:
-                    lock = asyncio.Lock()
-                    setattr(context, "_synchronized_async_lock", lock)
-
-        return lock
-
-    def _synchronized_wrapper(wrapped, instance, args, kwargs):
-        # Execute the wrapped function while the lock for the
-        # desired context is held. If instance is None then the
-        # wrapped function is used as the context.
-
-        with _synchronized_lock(instance if instance is not None else wrapped):
-            return wrapped(*args, **kwargs)
-
-    async def _synchronized_async_wrapper(wrapped, instance, args, kwargs):
-        async with _synchronized_async_lock(
-            instance if instance is not None else wrapped
-        ):
-            return await wrapped(*args, **kwargs)
-
-    class _SynchronizedFunctionWrapper(FunctionWrapper):
-
-        def __enter__(self):
-            self._self_lock = _synchronized_lock(self.__wrapped__)
-            self._self_lock.acquire()
-            return self._self_lock
-
-        def __exit__(self, *args):
-            self._self_lock.release()
-
-        async def __aenter__(self):
-            self._self_async_lock = _synchronized_async_lock(self.__wrapped__)
-            await self._self_async_lock.acquire()
-            return self._self_async_lock
-
-        async def __aexit__(self, *args):
-            self._self_async_lock.release()
-
-    if _synchronized_is_async_callable(wrapped):
-        return _SynchronizedFunctionWrapper(
-            wrapped=wrapped, wrapper=_synchronized_async_wrapper
-        )
-
-    return _SynchronizedFunctionWrapper(wrapped=wrapped, wrapper=_synchronized_wrapper)
-
-
-synchronized._synchronized_meta_lock = Lock()  # type: ignore[attr-defined]
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py
deleted file mode 100644
index a4ae1f5503a..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/weakrefs.py
+++ /dev/null
@@ -1,170 +0,0 @@
-"""Weak reference proxy for functions and bound methods."""
-
-import functools
-import weakref
-
-from .__wrapt__ import BaseObjectProxy, _FunctionWrapperBase
-
-# A weak function proxy. This will work on instance methods, class
-# methods, static methods and regular functions. Special treatment is
-# needed for the method types because the bound method is effectively a
-# transient object and applying a weak reference to one will immediately
-# result in it being destroyed and the weakref callback called. The weak
-# reference is therefore applied to the instance the method is bound to
-# and the original function. The function is then rebound at the point
-# of a call via the weak function proxy.
-#
-# Where the function is a wrapt function wrapper, such as results from
-# applying a decorator, the same applies but there may be no instance,
-# either because the wrapper was never bound, as for a decorated free
-# function, or because the method was accessed via the class rather
-# than an instance. In that case a weak reference to the class the
-# wrapper was accessed through, the owner, is retained as well so that
-# the function can still be rebound correctly at the point of a call.
-
-
-def _weak_function_proxy_callback(ref, proxy, callback):
-    if proxy._self_expired:
-        return
-
-    proxy._self_expired = True
-
-    # This could raise an exception. We let it propagate back and let
-    # the weakref.proxy() deal with it, at which point it generally
-    # prints out a short error message direct to stderr and keeps going.
-    # Note that the callback can never actually be None here, as the
-    # partial which invokes this function is only created when a
-    # callback was supplied, but check anyway as a safeguard.
-
-    if callback is not None:
-        callback(proxy)
-
-
-class WeakFunctionProxy(BaseObjectProxy):
-    """A weak function proxy."""
-
-    def __init__(self, wrapped, callback=None):
-        """Create a proxy to object which uses a weak reference. This is
-        similar to the `weakref.proxy` but is designed to work with functions
-        and methods. It will automatically rebind the function to the instance
-        when called if the function was originally a bound method. This is
-        necessary because bound methods are transient objects and applying a
-        weak reference to one will immediately result in it being destroyed
-        and the weakref callback called. The weak reference is therefore
-        applied to the instance the method is bound to and the original
-        function. The function is then rebound at the point of a call via the
-        weak function proxy.
-        """
-
-        # We need to determine if the wrapped function is actually a
-        # bound method. In the case of a bound method, we need to keep a
-        # reference to the original unbound function and the instance.
-        # This is necessary because if we hold a reference to the bound
-        # function, it will be the only reference and given it is a
-        # temporary object, it will almost immediately expire and
-        # the weakref callback triggered. So what is done is that we
-        # hold a reference to the instance and unbound function and
-        # when called bind the function to the instance once again and
-        # then call it. Note that we avoid using a nested function for
-        # the callback here so as not to cause any odd reference cycles.
-
-        _callback = None
-        if callback is not None:
-            _callback = functools.partial(
-                _weak_function_proxy_callback, proxy=self, callback=callback
-            )
-
-        self._self_expired = False
-        self._self_owner = None
-
-        if isinstance(wrapped, _FunctionWrapperBase):
-            # A function wrapper may have no instance, either because it
-            # was never bound, as for a decorated free function, or
-            # because the method was accessed via the class rather than
-            # an instance. Only take a weak reference to the instance
-            # where there is one. The owner is the class the wrapper was
-            # accessed through, and is retained so the function can be
-            # rebound with it when called. Without it a classmethod
-            # accessed via the class could not be rebound at all, and an
-            # instance method accessed via the class would not be able
-            # to identify an instance passed as the first argument.
-
-            instance = wrapped._self_instance
-            self._self_instance = (
-                weakref.ref(instance, _callback) if instance is not None else None
-            )
-            owner = wrapped._self_owner
-            if owner is not None:
-                self._self_owner = weakref.ref(owner, _callback)
-
-            if wrapped._self_parent is not None:
-                # Explicit class in super() is used because the proxy
-                # overrides __class__ and MRO-related methods to delegate
-                # to the wrapped object, which can interfere with bare
-                # super().
-                super(WeakFunctionProxy, self).__init__(
-                    weakref.proxy(wrapped._self_parent, _callback)
-                )
-
-            else:
-                super(WeakFunctionProxy, self).__init__(
-                    weakref.proxy(wrapped, _callback)
-                )
-
-            return
-
-        try:
-            self._self_instance = weakref.ref(wrapped.__self__, _callback)
-
-            super(WeakFunctionProxy, self).__init__(
-                weakref.proxy(wrapped.__func__, _callback)
-            )
-
-        except AttributeError:
-            self._self_instance = None
-
-            super(WeakFunctionProxy, self).__init__(weakref.proxy(wrapped, _callback))
-
-    def __call__(*args, **kwargs):
-        def _unpack_self(self, *args):
-            return self, args
-
-        self, args = _unpack_self(*args)
-
-        # We perform a boolean check here on the instance and wrapped
-        # function as that will trigger the reference error prior to
-        # calling if the reference had expired.
-
-        instance = self._self_instance and self._self_instance()
-        function = self.__wrapped__ and self.__wrapped__
-
-        # If the wrapped function was originally a bound method but the
-        # instance it was bound to has been garbage collected, raise a
-        # ReferenceError rather than silently calling it as unbound.
-
-        if self._self_instance is not None and instance is None:
-            raise ReferenceError("weakly-referenced object no longer exists")
-
-        # If the wrapped function was a function wrapper for which the
-        # owner was retained, rebind the function against the instance,
-        # which may be None, and that owner. This is what a classmethod
-        # accessed via the class needs to be rebound at all, and what an
-        # instance method accessed via the class needs to recognise an
-        # instance passed as the first argument. If the owner has been
-        # garbage collected, raise a ReferenceError as for the instance.
-
-        if self._self_owner is not None:
-            owner = self._self_owner()
-            if owner is None:
-                raise ReferenceError("weakly-referenced object no longer exists")
-            return function.__get__(instance, owner)(*args, **kwargs)
-
-        # Otherwise, if the wrapped function was originally a bound
-        # function, for which we retained a reference to the instance and
-        # the unbound function, we need to rebind the function and then
-        # call it. If not just call the wrapped function.
-
-        if instance is None:
-            return self.__wrapped__(*args, **kwargs)
-
-        return function.__get__(instance, type(instance))(*args, **kwargs)
diff --git a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py b/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py
deleted file mode 100644
index 83d3bc25022..00000000000
--- a/agent/opentelemetry-agent/src/opentelemetry/agent/_vendor/wrapt/wrappers.py
+++ /dev/null
@@ -1,1287 +0,0 @@
-"""Core object proxy and function wrapper implementations."""
-
-import functools
-import inspect
-import math
-import operator
-import sys
-import types
-
-from .exceptions import WrapperNotInitializedError
-
-
-class _ObjectProxyMethods:
-
-    # We use properties to override the values of __module__ and
-    # __doc__. If we add these in ObjectProxy, the derived class
-    # __dict__ will still be setup to have string variants of these
-    # attributes and the rules of descriptors means that they appear to
-    # take precedence over the properties in the base class. To avoid
-    # that, we copy the properties into the derived class type itself
-    # via a meta class. In that way the properties will always take
-    # precedence.
-    #
-    # Note that because these properties end up in the class __dict__,
-    # type-level access (e.g. ObjectProxy.__module__) would return the
-    # property object rather than a string, since CPython's
-    # type.__module__ getter does a raw dict lookup without invoking the
-    # descriptor protocol. The metaclass has its own __module__ and
-    # __doc__ properties to handle type-level access correctly.
-
-    @property
-    def __module__(self):
-        return self.__wrapped__.__module__
-
-    @__module__.setter
-    def __module__(self, value):
-        self.__wrapped__.__module__ = value
-
-    @__module__.deleter
-    def __module__(self):
-        del self.__wrapped__.__module__
-
-    @property
-    def __doc__(self):
-        return self.__wrapped__.__doc__
-
-    @__doc__.setter
-    def __doc__(self, value):
-        self.__wrapped__.__doc__ = value
-
-    @__doc__.deleter
-    def __doc__(self):
-        del self.__wrapped__.__doc__
-
-    # We similar use a property for __dict__. We need __dict__ to be
-    # explicit to ensure that vars() works as expected.
-
-    @property
-    def __dict__(self):
-        return self.__wrapped__.__dict__
-
-    # Need to also propagate the special __weakref__ attribute for case
-    # where decorating classes which will define this. If do not define
-    # it and use a function like inspect.getmembers() on a decorator
-    # class it will fail. This can't be in the derived classes.
-
-    @property
-    def __weakref__(self):
-        return self.__wrapped__.__weakref__
-
-
-class _ObjectProxyDictBase:
-    """Base class whose sole purpose is to provide a ``getset_descriptor``
-    for ``__dict__`` that is valid for all ``ObjectProxy`` subclasses.
-    The metaclass installs this descriptor as ``__self_dict__`` so that
-    the real instance dictionary of the proxy can always be accessed,
-    even though ``ObjectProxy`` replaces ``__dict__`` with a property
-    that delegates to the wrapped object."""
-
-    pass
-
-
-_REAL_DICT_DESCRIPTOR = type.__dict__["__dict__"].__get__(_ObjectProxyDictBase)[
-    "__dict__"
-]
-
-
-def _get_self_dict(self):
-    return _REAL_DICT_DESCRIPTOR.__get__(self)
-
-
-# Wrapping the descriptor in a read-only property ensures that
-# ``proxy.__self_dict__ = value`` raises AttributeError rather than
-# replacing the real instance dictionary (which would break the proxy).
-
-_SELF_DICT_PROPERTY = property(_get_self_dict)
-
-# The default __doc__ property which delegates to the wrapped object. A
-# derived class may define its own __doc__ descriptor in its class body
-# to take control of what __doc__ reports for its instances, and that is
-# preserved by the metaclass in place of this default.
-
-_DEFAULT_DOC_PROPERTY = vars(_ObjectProxyMethods)["__doc__"]
-
-
-def _is_doc_descriptor(entry):
-    # Every class carries a __doc__ entry in its dict, being the docstring
-    # or None when there is none. Only a descriptor is taken to be a
-    # deliberate override of the instance level __doc__ property.
-
-    if entry is None or isinstance(entry, str):
-        return False
-    return hasattr(type(entry), "__get__")
-
-
-def _inherited_doc_descriptor(bases):
-    # Find a custom __doc__ descriptor inherited from a base class. The
-    # search stops at the first class which holds the default delegating
-    # property, since a derived class of that should delegate as well. The
-    # C extension performs the equivalent walk of the MRO at the time
-    # __doc__ is accessed.
-
-    for base in bases:
-        for klass in base.__mro__:
-            entry = vars(klass).get("__doc__")
-            if entry is _DEFAULT_DOC_PROPERTY:
-                return None
-            if _is_doc_descriptor(entry):
-                return entry
-    return None
-
-
-class _ObjectProxyMetaType(type):
-    # Properties on the metaclass control type-level access to __module__
-    # and __doc__ (e.g. ObjectProxy.__module__). Without these, the
-    # instance-level properties copied from _ObjectProxyMethods into each
-    # class dict would shadow the string values that type.__new__ sets,
-    # causing type.__module__ to return a property object instead of a
-    # string. The metaclass properties read from internal keys where the
-    # real values are saved.
-
-    @property
-    def __module__(cls):
-        return cls.__dict__.get("_cls_real_module", "builtins")
-
-    @__module__.setter
-    def __module__(cls, value):
-        type.__setattr__(cls, "_cls_real_module", value)
-
-    @property
-    def __doc__(cls):
-        return cls.__dict__.get("_cls_real_doc")
-
-    @__doc__.setter
-    def __doc__(cls, value):
-        type.__setattr__(cls, "_cls_real_doc", value)
-
-    def __new__(cls, name, bases, dictionary):
-        # Copy our special properties into the class so that they
-        # always take precedence over attributes of the same name added
-        # during construction of a derived class. This is to save
-        # duplicating the implementation for them in all derived classes.
-        #
-        # Because this overwrites the __module__ and __doc__ strings
-        # that would normally be in the class dict with property objects,
-        # we save the original values first and store them under internal
-        # keys. The metaclass properties above read from these keys to
-        # ensure type-level access (e.g. MyProxy.__module__) returns a
-        # string rather than a property object.
-
-        real_module = dictionary.get("__module__")
-        real_doc = dictionary.get("__doc__")
-
-        # If the subclass defines its own __dict__ property, preserve it
-        # rather than overwriting it with the default delegating property
-        # from _ObjectProxyMethods. When __dict__ is not explicitly
-        # defined in the class body, it will not be present in the
-        # dictionary at this point.
-
-        custom_dict = dictionary.get("__dict__")
-
-        # Similarly, if the subclass defines __doc__ as a descriptor rather
-        # than as a docstring, preserve it so the subclass controls what
-        # __doc__ reports for its instances. Such a descriptor is not the
-        # class docstring, so it is not recorded as one. A descriptor
-        # defined by a base class is inherited, as it would be for any
-        # class not using this metaclass, by copying it into the class
-        # dictionary where it takes precedence over the None or docstring
-        # entry the class body provides.
-
-        if _is_doc_descriptor(real_doc):
-            custom_doc = real_doc
-            real_doc = None
-        else:
-            custom_doc = _inherited_doc_descriptor(bases)
-
-        dictionary.update(vars(_ObjectProxyMethods))
-
-        if custom_dict is not None:
-            dictionary["__dict__"] = custom_dict
-
-        if custom_doc is not None:
-            dictionary["__doc__"] = custom_doc
-
-        dictionary.setdefault("__self_dict__", _SELF_DICT_PROPERTY)
-
-        klass = type.__new__(cls, name, bases, dictionary)
-
-        if real_module is not None:
-            type.__setattr__(klass, "_cls_real_module", real_module)
-        if real_doc is not None:
-            type.__setattr__(klass, "_cls_real_doc", real_doc)
-
-        return klass
-
-
-def _unwrap_operand(other):
-    # When the other operand of a binary operator is itself a proxy, apply
-    # the operator to the two wrapped objects rather than passing the proxy
-    # through to the wrapped object's own operator method. This mirrors
-    # wrapt_unwrap_operand() in the C extension. Without it, a wrapped
-    # type which raises TypeError for an unrecognised operand, rather
-    # than returning NotImplemented, would never give the proxy on the
-    # right hand side the chance to unwrap itself via the reflected
-    # method, and Python would not see the real types of the operands
-    # when deciding whether the reflected method of a subclass on the
-    # right hand side takes priority. The real type is checked, and not
-    # __class__, which the proxy reports as that of the wrapped object.
-
-    if issubclass(type(other), ObjectProxy):
-        return other.__wrapped__
-    return other
-
-
-class ObjectProxy(_ObjectProxyDictBase, metaclass=_ObjectProxyMetaType):
-    """A transparent object proxy that delegates attribute access to a
-    wrapped object."""
-
-    @classmethod
-    def __class_getitem__(cls, item, /):
-        return types.GenericAlias(cls, item)
-
-    def __new__(cls, *args, **kwargs):
-        # Accept and ignore any arguments. A derived class which adds
-        # arguments to __init__() has the same arguments passed to
-        # __new__(), and a derived class which overrides __new__() may
-        # pass through whatever it was given, as it must when deriving
-        # from AutoObjectProxy which needs the wrapped object in __new__().
-        # Without this, once __new__() is overridden anywhere in the class
-        # hierarchy, the call falls through to object.__new__() which
-        # rejects extra arguments. The C extension already ignores the
-        # arguments in its tp_new slot, so this keeps the two consistent.
-
-        return super().__new__(cls)
-
-    def __init__(self, wrapped):
-        """Create an object proxy around the given object."""
-
-        if wrapped is None:
-            try:
-                callback = object.__getattribute__(self, "__wrapped_factory__")
-            except AttributeError:
-                callback = None
-
-            if callback is not None:
-                # If wrapped is none and class has a __wrapped_factory__
-                # method, then we don't set __wrapped__ yet and instead will
-                # defer creation of the wrapped object until it is first
-                # needed.
-
-                pass
-
-            else:
-                object.__setattr__(self, "__wrapped__", wrapped)
-        else:
-            object.__setattr__(self, "__wrapped__", wrapped)
-
-        object.__setattr__(self, "__init_called__", True)
-
-        # Python 3.2+ has the __qualname__ attribute, but it does not
-        # allow it to be overridden using a property and it must instead
-        # be an actual string object instead.
-
-        try:
-            object.__setattr__(self, "__qualname__", wrapped.__qualname__)
-        except AttributeError:
-            pass
-
-        # Python 3.10 onwards also does not allow itself to be overridden
-        # using a property and it must instead be set explicitly. Python
-        # 3.14 onwards uses deferred evaluation of annotations via the
-        # __annotate__ attribute, so we copy that instead to avoid
-        # triggering eager evaluation which can fail if names referenced
-        # in annotations have been shadowed.
-
-        if sys.version_info >= (3, 14):
-            try:
-                object.__setattr__(self, "__annotate__", wrapped.__annotate__)
-            except AttributeError:
-                pass
-        else:
-            try:
-                object.__setattr__(self, "__annotations__", wrapped.__annotations__)
-            except AttributeError:
-                pass
-
-    @property
-    def __object_proxy__(self):
-        return ObjectProxy
-
-    def __self_setattr__(self, name, value):
-        object.__setattr__(self, name, value)
-
-    @property
-    def __name__(self):
-        return self.__wrapped__.__name__
-
-    @__name__.setter
-    def __name__(self, value):
-        self.__wrapped__.__name__ = value
-
-    @property
-    def __class__(self):
-        return self.__wrapped__.__class__
-
-    @__class__.setter
-    def __class__(self, value):
-        self.__wrapped__.__class__ = value
-
-    def __dir__(self):
-        return dir(self.__wrapped__)
-
-    def __str__(self):
-        return str(self.__wrapped__)
-
-    def __bytes__(self):
-        return bytes(self.__wrapped__)
-
-    def __repr__(self):
-        return f"<{type(self).__name__} at 0x{id(self):x} for {type(self.__wrapped__).__name__} at 0x{id(self.__wrapped__):x}>"
-
-    def __format__(self, format_spec):
-        return format(self.__wrapped__, format_spec)
-
-    def __reversed__(self):
-        return reversed(self.__wrapped__)
-
-    def __round__(self, ndigits=None):
-        return round(self.__wrapped__, ndigits)
-
-    def __trunc__(self):
-        return math.trunc(self.__wrapped__)
-
-    def __floor__(self):
-        return math.floor(self.__wrapped__)
-
-    def __ceil__(self):
-        return math.ceil(self.__wrapped__)
-
-    def __mro_entries__(self, bases):
-        if not isinstance(self.__wrapped__, type) and hasattr(
-            self.__wrapped__, "__mro_entries__"
-        ):
-            return self.__wrapped__.__mro_entries__(bases)
-        return (self.__wrapped__,)
-
-    def __lt__(self, other):
-        return self.__wrapped__ < other
-
-    def __le__(self, other):
-        return self.__wrapped__ <= other
-
-    def __eq__(self, other):
-        return self.__wrapped__ == other
-
-    def __ne__(self, other):
-        return self.__wrapped__ != other
-
-    def __gt__(self, other):
-        return self.__wrapped__ > other
-
-    def __ge__(self, other):
-        return self.__wrapped__ >= other
-
-    def __hash__(self):
-        return hash(self.__wrapped__)
-
-    def __bool__(self):
-        return bool(self.__wrapped__)
-
-    def __setattr__(self, name, value):
-        if name.startswith("_self_"):
-            object.__setattr__(self, name, value)
-
-        elif name == "__wrapped__":
-            object.__setattr__(self, name, value)
-
-            try:
-                object.__delattr__(self, "__qualname__")
-            except AttributeError:
-                pass
-            try:
-                object.__setattr__(self, "__qualname__", value.__qualname__)
-            except AttributeError:
-                pass
-            if sys.version_info >= (3, 14):
-                try:
-                    object.__delattr__(self, "__annotate__")
-                except AttributeError:
-                    pass
-                try:
-                    object.__setattr__(self, "__annotate__", value.__annotate__)
-                except AttributeError:
-                    pass
-            else:
-                try:
-                    object.__delattr__(self, "__annotations__")
-                except AttributeError:
-                    pass
-                try:
-                    object.__setattr__(self, "__annotations__", value.__annotations__)
-                except AttributeError:
-                    pass
-
-            __wrapped_setattr_fixups__ = getattr(
-                self, "__wrapped_setattr_fixups__", None
-            )
-
-            if __wrapped_setattr_fixups__ is not None:
-                __wrapped_setattr_fixups__()
-
-        elif name == "__qualname__":
-            setattr(self.__wrapped__, name, value)
-            object.__setattr__(self, name, value)
-
-        elif name == "__annotations__":
-            setattr(self.__wrapped__, name, value)
-            object.__setattr__(self, name, value)
-
-        elif name == "__annotate__":
-            setattr(self.__wrapped__, name, value)
-            object.__setattr__(self, name, value)
-
-        elif hasattr(type(self), name):
-            object.__setattr__(self, name, value)
-
-        else:
-            setattr(self.__wrapped__, name, value)
-
-    def __getattr__(self, name):
-        # If we need to lookup `__wrapped__` then the `__init__()` method
-        # cannot have been called, or this is a lazy object proxy which is
-        # deferring creation of the wrapped object until it is first needed.
-
-        if name == "__wrapped__":
-            # Note that we use existance of `__wrapped_factory__` to gate whether
-            # we can attempt to initialize the wrapped object lazily, but it is
-            # `__wrapped_get__` that we actually call to do the initialization.
-            # This is so that we can handle multithreading correctly by having
-            # `__wrapped_get__` use a lock to protect against multiple threads
-            # trying to initialize the wrapped object at the same time.
-
-            try:
-                object.__getattribute__(self, "__wrapped_factory__")
-            except AttributeError:
-                pass
-            else:
-                return object.__getattribute__(self, "__wrapped_get__")()
-
-            # If __init__ was called but __wrapped__ is not set, the wrapper
-            # is in an inconsistent state. Raise WrapperNotInitializedError
-            # (a ValueError, not AttributeError) so it is not silently
-            # swallowed by hasattr/getattr patterns.
-
-            try:
-                object.__getattribute__(self, "__init_called__")
-            except AttributeError:
-                raise AttributeError(
-                    f"'{type(self).__name__}' object has no attribute " f"'__wrapped__'"
-                )
-
-            raise WrapperNotInitializedError(
-                "wrapper is in an inconsistent state: __wrapped__ is not set"
-            )
-
-        return getattr(self.__wrapped__, name)
-
-    def __delattr__(self, name):
-        if name.startswith("_self_"):
-            object.__delattr__(self, name)
-
-        elif name == "__wrapped__":
-            raise TypeError("can't delete __wrapped__ attribute")
-
-        elif name == "__qualname__":
-            object.__delattr__(self, name)
-            delattr(self.__wrapped__, name)
-
-        elif name == "__annotations__":
-            try:
-                object.__delattr__(self, name)
-            except AttributeError:
-                pass
-            delattr(self.__wrapped__, name)
-
-        elif name == "__annotate__":
-            try:
-                object.__delattr__(self, name)
-            except AttributeError:
-                pass
-            delattr(self.__wrapped__, name)
-
-        elif hasattr(type(self), name):
-            object.__delattr__(self, name)
-
-        else:
-            delattr(self.__wrapped__, name)
-
-    def __add__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ + other
-
-    def __sub__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ - other
-
-    def __mul__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ * other
-
-    def __truediv__(self, other):
-        other = _unwrap_operand(other)
-        return operator.truediv(self.__wrapped__, other)
-
-    def __floordiv__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ // other
-
-    def __mod__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ % other
-
-    def __divmod__(self, other):
-        other = _unwrap_operand(other)
-        return divmod(self.__wrapped__, other)
-
-    def __pow__(self, other, *args):
-        other = _unwrap_operand(other)
-        return pow(self.__wrapped__, other, *args)
-
-    def __lshift__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ << other
-
-    def __rshift__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ >> other
-
-    def __and__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ & other
-
-    def __xor__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ ^ other
-
-    def __or__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ | other
-
-    def __radd__(self, other):
-        other = _unwrap_operand(other)
-        return other + self.__wrapped__
-
-    def __rsub__(self, other):
-        other = _unwrap_operand(other)
-        return other - self.__wrapped__
-
-    def __rmul__(self, other):
-        other = _unwrap_operand(other)
-        return other * self.__wrapped__
-
-    def __rtruediv__(self, other):
-        other = _unwrap_operand(other)
-        return operator.truediv(other, self.__wrapped__)
-
-    def __rfloordiv__(self, other):
-        other = _unwrap_operand(other)
-        return other // self.__wrapped__
-
-    def __rmod__(self, other):
-        other = _unwrap_operand(other)
-        return other % self.__wrapped__
-
-    def __rdivmod__(self, other):
-        other = _unwrap_operand(other)
-        return divmod(other, self.__wrapped__)
-
-    def __rpow__(self, other, *args):
-        other = _unwrap_operand(other)
-        return pow(other, self.__wrapped__, *args)
-
-    def __rlshift__(self, other):
-        other = _unwrap_operand(other)
-        return other << self.__wrapped__
-
-    def __rrshift__(self, other):
-        other = _unwrap_operand(other)
-        return other >> self.__wrapped__
-
-    def __rand__(self, other):
-        other = _unwrap_operand(other)
-        return other & self.__wrapped__
-
-    def __rxor__(self, other):
-        other = _unwrap_operand(other)
-        return other ^ self.__wrapped__
-
-    def __ror__(self, other):
-        other = _unwrap_operand(other)
-        return other | self.__wrapped__
-
-    def __iadd__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__iadd__"):
-            self.__wrapped__ += other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ + other)
-
-    def __isub__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__isub__"):
-            self.__wrapped__ -= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ - other)
-
-    def __imul__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__imul__"):
-            self.__wrapped__ *= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ * other)
-
-    def __itruediv__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__itruediv__"):
-            self.__wrapped__ /= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ / other)
-
-    def __ifloordiv__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__ifloordiv__"):
-            self.__wrapped__ //= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ // other)
-
-    def __imod__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__imod__"):
-            self.__wrapped__ %= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ % other)
-
-    def __ipow__(self, other):  # type: ignore[misc]
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__ipow__"):
-            self.__wrapped__ **= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__**other)
-
-    def __ilshift__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__ilshift__"):
-            self.__wrapped__ <<= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ << other)
-
-    def __irshift__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__irshift__"):
-            self.__wrapped__ >>= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ >> other)
-
-    def __iand__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__iand__"):
-            self.__wrapped__ &= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ & other)
-
-    def __ixor__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__ixor__"):
-            self.__wrapped__ ^= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ ^ other)
-
-    def __ior__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__ior__"):
-            self.__wrapped__ |= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ | other)
-
-    def __neg__(self):
-        return -self.__wrapped__
-
-    def __pos__(self):
-        return +self.__wrapped__
-
-    def __abs__(self):
-        return abs(self.__wrapped__)
-
-    def __invert__(self):
-        return ~self.__wrapped__
-
-    def __int__(self):
-        return int(self.__wrapped__)
-
-    def __float__(self):
-        return float(self.__wrapped__)
-
-    def __complex__(self):
-        return complex(self.__wrapped__)
-
-    def __index__(self):
-        return operator.index(self.__wrapped__)
-
-    def __matmul__(self, other):
-        other = _unwrap_operand(other)
-        return self.__wrapped__ @ other
-
-    def __rmatmul__(self, other):
-        other = _unwrap_operand(other)
-        return other @ self.__wrapped__
-
-    def __imatmul__(self, other):
-        other = _unwrap_operand(other)
-        if hasattr(self.__wrapped__, "__imatmul__"):
-            self.__wrapped__ @= other
-            return self
-        else:
-            return self.__object_proxy__(self.__wrapped__ @ other)
-
-    def __len__(self):
-        return len(self.__wrapped__)
-
-    def __contains__(self, value):
-        return value in self.__wrapped__
-
-    def __getitem__(self, key):
-        return self.__wrapped__[key]
-
-    def __setitem__(self, key, value):
-        self.__wrapped__[key] = value
-
-    def __delitem__(self, key):
-        del self.__wrapped__[key]
-
-    def __enter__(self):
-        return self.__wrapped__.__enter__()
-
-    def __exit__(self, *args, **kwargs):
-        return self.__wrapped__.__exit__(*args, **kwargs)
-
-    def __aenter__(self):
-        return self.__wrapped__.__aenter__()
-
-    def __aexit__(self, *args, **kwargs):
-        return self.__wrapped__.__aexit__(*args, **kwargs)
-
-    def __copy__(self):
-        raise NotImplementedError("object proxy must define __copy__()")
-
-    def __deepcopy__(self, memo):
-        raise NotImplementedError("object proxy must define __deepcopy__()")
-
-    def __reduce__(self):
-        raise NotImplementedError("object proxy must define __reduce__()")
-
-    def __instancecheck__(self, instance):
-        return isinstance(instance, self.__wrapped__)
-
-    def __subclasscheck__(self, subclass):
-        if hasattr(subclass, "__wrapped__"):
-            return issubclass(subclass.__wrapped__, self.__wrapped__)
-        else:
-            return issubclass(subclass, self.__wrapped__)
-
-
-class CallableObjectProxy(ObjectProxy):
-    """An object proxy for callable objects that also forwards calls."""
-
-    def __call__(*args, **kwargs):
-        def _unpack_self(self, *args):
-            return self, args
-
-        self, args = _unpack_self(*args)
-
-        return self.__wrapped__(*args, **kwargs)
-
-
-class _PartialSignatureDescriptor:
-    """Descriptor providing the ``__signature__`` attribute of instances of
-    ``PartialCallableObjectProxy``.
-
-    The signature reported is that of the wrapped callable with the bound
-    positional and keyword arguments removed, matching what ``inspect``
-    reports for ``functools.partial``. It must be defined on the proxy type
-    itself, since attribute lookup on the proxy would otherwise be forwarded
-    to the wrapped callable, and ``inspect.signature()`` stops following
-    ``__wrapped__`` at the first object which has a ``__signature__``
-    attribute.
-
-    A plain property cannot be used because it would also be visible when
-    accessed on the class, and ``inspect.signature()`` applied to the class
-    itself would then fail on finding a property object rather than a
-    ``Signature``. Raising ``AttributeError`` on class access leaves the
-    signature of the class unchanged.
-    """
-
-    def __get__(self, instance, owner=None):
-        if instance is None:
-            raise AttributeError("__signature__")
-
-        partial = functools.partial(
-            instance.__wrapped__, *instance._self_args, **instance._self_kwargs
-        )
-
-        return inspect.signature(partial)
-
-
-class PartialCallableObjectProxy(ObjectProxy):
-    """A callable object proxy that supports partial application of arguments
-    and keywords.
-    """
-
-    __signature__ = _PartialSignatureDescriptor()
-
-    def __init__(*args, **kwargs):
-        """Create a callable object proxy with partial application of the given
-        arguments and keywords. This behaves the same as `functools.partial`, but
-        implemented using the `ObjectProxy` class to provide better support for
-        introspection.
-        """
-
-        def _unpack_self(self, *args):
-            return self, args
-
-        self, args = _unpack_self(*args)
-
-        if len(args) < 1:
-            raise TypeError("partial type takes at least one argument")
-
-        wrapped, args = args[0], args[1:]
-
-        if not callable(wrapped):
-            raise TypeError("the first argument must be callable")
-
-        # Explicit class in super() is used because the proxy overrides
-        # __class__ and MRO-related methods to delegate to the wrapped
-        # object, which can interfere with bare super().
-        super(PartialCallableObjectProxy, self).__init__(wrapped)
-
-        self._self_args = args
-        self._self_kwargs = kwargs
-
-    def __call__(*args, **kwargs):
-        def _unpack_self(self, *args):
-            return self, args
-
-        self, args = _unpack_self(*args)
-
-        _args = self._self_args + args
-
-        _kwargs = dict(self._self_kwargs)
-        _kwargs.update(kwargs)
-
-        return self.__wrapped__(*_args, **_kwargs)
-
-
-class _FunctionWrapperBase(ObjectProxy):
-
-    def __init__(
-        self,
-        wrapped,
-        instance,
-        wrapper,
-        enabled=None,
-        binding="callable",
-        parent=None,
-        owner=None,
-    ):
-
-        # Explicit class in super() is used because the proxy overrides
-        # __class__ and MRO-related methods to delegate to the wrapped
-        # object, which can interfere with bare super().
-        super(_FunctionWrapperBase, self).__init__(wrapped)
-
-        object.__setattr__(self, "_self_instance", instance)
-        object.__setattr__(self, "_self_wrapper", wrapper)
-        object.__setattr__(self, "_self_enabled", enabled)
-        object.__setattr__(self, "_self_binding", binding)
-        object.__setattr__(self, "_self_parent", parent)
-        object.__setattr__(self, "_self_owner", owner)
-
-    def __get__(self, instance, owner=None):
-        # This method handles both unbound and bound derived wrapper classes.
-        # It is kept in the base class as the amount of common code makes it
-        # impractical to split into the derived classes.
-        #
-        # The distinguishing attribute which determines whether we are being
-        # called in an unbound or bound wrapper is the parent attribute. If
-        # binding has never occurred, then the parent will be None.
-        #
-        # First therefore, is if we are called in an unbound wrapper. In this
-        # case we perform the binding.
-        #
-        # We have two special cases to worry about here. These are where we are
-        # decorating a class or builtin function as neither provide a __get__()
-        # method to call. In this case we simply return self.
-        #
-        # Note that we otherwise still do binding even if instance is None and
-        # accessing an unbound instance method from a class. This is because we
-        # need to be able to later detect that specific case as we will need to
-        # extract the instance from the first argument of those passed in.
-
-        if self._self_parent is None:
-            # Technically can probably just check for existence of __get__ on
-            # the wrapped object, but this is more explicit.
-
-            if self._self_binding == "builtin":
-                return self
-
-            if self._self_binding == "class":
-                return self
-
-            binder = getattr(self.__wrapped__, "__get__", None)
-
-            if binder is None:
-                return self
-
-            descriptor = binder(instance, owner)
-
-            return self.__bound_function_wrapper__(
-                descriptor,
-                instance,
-                self._self_wrapper,
-                self._self_enabled,
-                self._self_binding,
-                self,
-                owner,
-            )
-
-        # Now we have the case of binding occurring a second time on what was
-        # already a bound function. In this case we would usually return
-        # ourselves again. This mirrors what Python does.
-        #
-        # The special case this time is where we were originally bound with an
-        # instance of None and we were likely an instance method. In that case
-        # we rebind against the original wrapped function from the parent again.
-
-        if self._self_instance is None and self._self_binding in (
-            "function",
-            "instancemethod",
-            "callable",
-        ):
-            descriptor = self._self_parent.__wrapped__.__get__(instance, owner)
-
-            return self._self_parent.__bound_function_wrapper__(
-                descriptor,
-                instance,
-                self._self_wrapper,
-                self._self_enabled,
-                self._self_binding,
-                self._self_parent,
-                owner,
-            )
-
-        return self
-
-    def __call__(*args, **kwargs):
-        def _unpack_self(self, *args):
-            return self, args
-
-        self, args = _unpack_self(*args)
-
-        # If enabled has been specified, then evaluate it at this point
-        # and if the wrapper is not to be executed, then simply return
-        # the bound function rather than a bound wrapper for the bound
-        # function. When evaluating enabled, if it is callable we call
-        # it, otherwise we evaluate it as a boolean.
-
-        if self._self_enabled is not None:
-            if callable(self._self_enabled):
-                if not self._self_enabled():
-                    return self.__wrapped__(*args, **kwargs)
-            elif not self._self_enabled:
-                return self.__wrapped__(*args, **kwargs)
-
-        # This can occur where initial function wrapper was applied to
-        # a function that was already bound to an instance. In that case
-        # we want to extract the instance from the function and use it.
-
-        if self._self_binding in (
-            "function",
-            "instancemethod",
-            "classmethod",
-            "callable",
-        ):
-            if self._self_instance is None:
-                instance = getattr(self.__wrapped__, "__self__", None)
-                if instance is not None:
-                    return self._self_wrapper(self.__wrapped__, instance, args, kwargs)
-
-        # This is generally invoked when the wrapped function is being
-        # called as a normal function and is not bound to a class as an
-        # instance method. This is also invoked in the case where the
-        # wrapped function was a method, but this wrapper was in turn
-        # wrapped using the staticmethod decorator.
-
-        return self._self_wrapper(self.__wrapped__, self._self_instance, args, kwargs)
-
-    def __set_name__(self, owner, name):
-        # This is a special method use to supply information to
-        # descriptors about what the name of variable in a class
-        # definition is. Not wanting to add this to ObjectProxy as not
-        # sure of broader implications of doing that. Thus restrict to
-        # FunctionWrapper used by decorators.
-
-        if hasattr(self.__wrapped__, "__set_name__"):
-            self.__wrapped__.__set_name__(owner, name)
-
-
-_FUNCTION_WRAPPER_SLOTS = frozenset(
-    (
-        "_self_instance",
-        "_self_wrapper",
-        "_self_enabled",
-        "_self_binding",
-        "_self_parent",
-        "_self_owner",
-    )
-)
-
-
-class BoundFunctionWrapper(_FunctionWrapperBase):
-    """A wrapper for bound methods, classmethods, and staticmethods."""
-
-    def __setattr__(self, name, value):
-        if name.startswith("_self_") and name not in _FUNCTION_WRAPPER_SLOTS:
-            if self._self_parent is not None:
-                object.__setattr__(self._self_parent, name, value)
-                return
-        super().__setattr__(name, value)
-
-    def __getattr__(self, name):
-        # This is only reached for _self_parent when that attribute was
-        # never set, which means __init__() was not called. It has to fail
-        # here, as the lookup of it below would otherwise come straight
-        # back in and recurse without end.
-
-        if name == "_self_parent":
-            raise AttributeError(
-                f"'{type(self).__name__}' object has no attribute '{name}'"
-            )
-
-        if self._self_parent is not None:
-            try:
-                return getattr(self._self_parent, name)
-            except AttributeError:
-                pass
-        return super().__getattr__(name)
-
-    def __call__(*args, **kwargs):
-        def _unpack_self(self, *args):
-            return self, args
-
-        self, args = _unpack_self(*args)
-
-        # If enabled has been specified, then evaluate it at this point and if
-        # the wrapper is not to be executed, then simply return the bound
-        # function rather than a bound wrapper for the bound function. When
-        # evaluating enabled, if it is callable we call it, otherwise we
-        # evaluate it as a boolean.
-
-        if self._self_enabled is not None:
-            if callable(self._self_enabled):
-                if not self._self_enabled():
-                    return self.__wrapped__(*args, **kwargs)
-            elif not self._self_enabled:
-                return self.__wrapped__(*args, **kwargs)
-
-        # We need to do things different depending on whether we are likely
-        # wrapping an instance method vs a static method or class method.
-
-        if self._self_binding == "function":
-            if self._self_instance is None and args:
-                instance, newargs = args[0], args[1:]
-                if isinstance(instance, self._self_owner):
-                    wrapped = PartialCallableObjectProxy(self.__wrapped__, instance)
-                    return self._self_wrapper(wrapped, instance, newargs, kwargs)
-
-            return self._self_wrapper(
-                self.__wrapped__, self._self_instance, args, kwargs
-            )
-
-        elif self._self_binding == "callable":
-            if self._self_instance is None and args:
-                # This situation can occur where someone is calling the
-                # instancemethod via the class type and passing the instance as
-                # the first argument. We need to shift the args before making
-                # the call to the wrapper and effectively bind the instance to
-                # the wrapped function using a partial so the wrapper doesn't
-                # see anything as being different.
-
-                instance, newargs = args[0], args[1:]
-                if isinstance(instance, self._self_owner):
-                    wrapped = PartialCallableObjectProxy(self.__wrapped__, instance)
-                    return self._self_wrapper(wrapped, instance, newargs, kwargs)
-
-            return self._self_wrapper(
-                self.__wrapped__, self._self_instance, args, kwargs
-            )
-
-        else:
-            # As in this case we would be dealing with a classmethod or
-            # staticmethod, then _self_instance will only tell us whether
-            # when calling the classmethod or staticmethod they did it via an
-            # instance of the class it is bound to and not the case where
-            # done by the class type itself. We thus ignore _self_instance
-            # and use the __self__ attribute of the bound function instead.
-            # For a classmethod, this means instance will be the class type
-            # and for a staticmethod it will be None. This is probably the
-            # more useful thing we can pass through even though we loose
-            # knowledge of whether they were called on the instance vs the
-            # class type, as it reflects what they have available in the
-            # decoratored function.
-
-            instance = getattr(self.__wrapped__, "__self__", None)
-
-            return self._self_wrapper(self.__wrapped__, instance, args, kwargs)
-
-
-class FunctionWrapper(_FunctionWrapperBase):
-    """
-    A wrapper for callable objects that can be used to apply decorators to
-    functions, methods, classmethods, and staticmethods, or any other callable.
-    It handles binding and unbinding of methods, and allows for the wrapper to
-    be enabled or disabled.
-    """
-
-    __bound_function_wrapper__ = BoundFunctionWrapper
-
-    def __init__(self, wrapped, wrapper, enabled=None):
-        """
-        Initialize the `FunctionWrapper` with the `wrapped` callable, the
-        `wrapper` function, and an optional `enabled` argument. The `enabled`
-        argument can be a boolean or a callable that returns a boolean. When a
-        callable is provided, it will be called each time the wrapper is
-        invoked to determine if the wrapper function should be executed or
-        whether the wrapped function should be called directly. If `enabled`
-        is not provided, the wrapper is enabled by default.
-        """
-
-        # What it is we are wrapping here could be anything. We need to
-        # try and detect specific cases though. In particular, we need
-        # to detect when we are given something that is a method of a
-        # class. Further, we need to know when it is likely an instance
-        # method, as opposed to a class or static method. This can
-        # become problematic though as there isn't strictly a fool proof
-        # method of knowing.
-        #
-        # The situations we could encounter when wrapping a method are:
-        #
-        # 1. The wrapper is being applied as part of a decorator which
-        # is a part of the class definition. In this case what we are
-        # given is the raw unbound function, classmethod or staticmethod
-        # wrapper objects.
-        #
-        # The problem here is that we will not know we are being applied
-        # in the context of the class being set up. This becomes
-        # important later for the case of an instance method, because in
-        # that case we just see it as a raw function and can't
-        # distinguish it from wrapping a normal function outside of
-        # a class context.
-        #
-        # 2. The wrapper is being applied when performing monkey
-        # patching of the class type afterwards and the method to be
-        # wrapped was retrieved direct from the __dict__ of the class
-        # type. This is effectively the same as (1) above.
-        #
-        # 3. The wrapper is being applied when performing monkey
-        # patching of the class type afterwards and the method to be
-        # wrapped was retrieved from the class type. In this case
-        # binding will have been performed where the instance against
-        # which the method is bound will be None at that point.
-        #
-        # This case is a problem because we can no longer tell if the
-        # method was a static method, plus if using Python3, we cannot
-        # tell if it was an instance method as the concept of an
-        # unnbound method no longer exists.
-        #
-        # 4. The wrapper is being applied when performing monkey
-        # patching of an instance of a class. In this case binding will
-        # have been performed where the instance was not None.
-        #
-        # This case is a problem because we can no longer tell if the
-        # method was a static method.
-        #
-        # Overall, the best we can do is look at the original type of the
-        # object which was wrapped prior to any binding being done and
-        # see if it is an instance of classmethod or staticmethod. In
-        # the case where other decorators are between us and them, if
-        # they do not propagate the __class__  attribute so that the
-        # isinstance() checks works, then likely this will do the wrong
-        # thing where classmethod and staticmethod are used.
-        #
-        # Since it is likely to be very rare that anyone even puts
-        # decorators around classmethod and staticmethod, likelihood of
-        # that being an issue is very small, so we accept it and suggest
-        # that those other decorators be fixed. It is also only an issue
-        # if a decorator wants to actually do things with the arguments.
-        #
-        # As to not being able to identify static methods properly, we
-        # just hope that that isn't something people are going to want
-        # to wrap, or if they do suggest they do it the correct way by
-        # ensuring that it is decorated in the class definition itself,
-        # or patch it in the __dict__ of the class type.
-        #
-        # So to get the best outcome we can, whenever we aren't sure what
-        # it is, we label it as a 'callable'. If it was already bound and
-        # that is rebound later, we assume that it will be an instance
-        # method and try and cope with the possibility that the 'self'
-        # argument it being passed as an explicit argument and shuffle
-        # the arguments around to extract 'self' for use as the instance.
-
-        binding = None
-
-        if isinstance(wrapped, _FunctionWrapperBase):
-            binding = wrapped._self_binding
-
-        if not binding:
-            if inspect.isbuiltin(wrapped):
-                binding = "builtin"
-
-            elif inspect.isfunction(wrapped):
-                binding = "function"
-
-            elif inspect.isclass(wrapped):
-                binding = "class"
-
-            elif isinstance(wrapped, classmethod):
-                binding = "classmethod"
-
-            elif isinstance(wrapped, staticmethod):
-                binding = "staticmethod"
-
-            elif hasattr(wrapped, "__self__"):
-                if inspect.isclass(wrapped.__self__):
-                    binding = "classmethod"
-                elif inspect.ismethod(wrapped):
-                    binding = "instancemethod"
-                else:
-                    binding = "callable"
-
-            else:
-                binding = "callable"
-
-        # Explicit class in super() is used because the proxy overrides
-        # __class__ and MRO-related methods to delegate to the wrapped
-        # object, which can interfere with bare super().
-        super(FunctionWrapper, self).__init__(wrapped, None, wrapper, enabled, binding)
diff --git a/agent/opentelemetry-agent/tests/requirements.latest.txt b/agent/opentelemetry-agent/tests/requirements.latest.txt
new file mode 100644
index 00000000000..a026febbf69
--- /dev/null
+++ b/agent/opentelemetry-agent/tests/requirements.latest.txt
@@ -0,0 +1,5 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+# The application's opentelemetry-api (and SDK) come from the core repository ([testenv] test_deps).
+pytest==7.4.4
diff --git a/agent/opentelemetry-agent/tests/requirements.oldest.txt b/agent/opentelemetry-agent/tests/requirements.oldest.txt
new file mode 100644
index 00000000000..917e81947b4
--- /dev/null
+++ b/agent/opentelemetry-agent/tests/requirements.oldest.txt
@@ -0,0 +1,7 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+# The oldest opentelemetry-api the bridge is tested with, as the application's API: older versions
+# load entry points with pkg_resources, which recent setuptools versions don't include.
+opentelemetry-api==1.16.0
+pytest==7.4.4
diff --git a/agent/opentelemetry-agent/tests/test_bridge.py b/agent/opentelemetry-agent/tests/test_bridge.py
new file mode 100644
index 00000000000..1ed7c2c71a6
--- /dev/null
+++ b/agent/opentelemetry-agent/tests/test_bridge.py
@@ -0,0 +1,337 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+"""The bridge from the application's opentelemetry-api (installed in the test environment) to the vendored SDK.
+
+The application's API selects the bridge through environment variables when it's imported, and keeps global
+state: each test runs a script in a new interpreter. Its spans are exported in memory by the vendored SDK and
+printed as JSON.
+"""
+
+from __future__ import annotations
+
+import json
+import os
+import subprocess
+import sys
+import textwrap
+from pathlib import Path
+from typing import Any
+
+import pytest
+
+from opentelemetry.agent._vendor.opentelemetry.environment_variables import (
+    _AGENT_BRIDGE,
+    OTEL_PYTHON_CONTEXT,
+    OTEL_PYTHON_TRACER_PROVIDER,
+)
+
+_BRIDGE_ENVIRONMENT = {OTEL_PYTHON_CONTEXT: _AGENT_BRIDGE, OTEL_PYTHON_TRACER_PROVIDER: _AGENT_BRIDGE}
+
+_PRELUDE = """
+import json
+
+from opentelemetry.agent._vendor.opentelemetry import trace as agent_trace
+from opentelemetry.agent._vendor.opentelemetry.sdk.trace import TracerProvider
+from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export import SimpleSpanProcessor
+from opentelemetry.agent._vendor.opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
+
+exporter = InMemorySpanExporter()
+agent_provider = TracerProvider()
+agent_provider.add_span_processor(SimpleSpanProcessor(exporter))
+agent_trace.set_tracer_provider(agent_provider)
+results = {}
+"""
+
+_EPILOGUE = """
+results["spans"] = [
+    {
+        "name": span.name,
+        "kind": span.kind.name,
+        "trace_id": span.context.trace_id,
+        "span_id": span.context.span_id,
+        "parent_id": span.parent.span_id if span.parent else None,
+        "status": [span.status.status_code.name, span.status.description],
+        "attributes": dict(span.attributes),
+        "events": [[event.name, dict(event.attributes)] for event in span.events],
+        "links": [[link.context.span_id, dict(link.attributes)] for link in span.links],
+    }
+    for span in exporter.get_finished_spans()
+]
+print(json.dumps(results))
+"""
+
+
+def _run(script: str, environment: dict[str, str] | None = None, prelude: bool = True) -> Any:
+    env = {
+        key: value
+        for key, value in os.environ.items()
+        if key not in (OTEL_PYTHON_CONTEXT, OTEL_PYTHON_TRACER_PROVIDER, "PYTHONPATH")
+    }
+    env |= _BRIDGE_ENVIRONMENT if environment is None else environment
+    source = textwrap.dedent(script)
+    if prelude:
+        source = _PRELUDE + source + _EPILOGUE
+    result = subprocess.run(
+        [sys.executable, "-c", source], env=env, capture_output=True, text=True, check=False, timeout=60
+    )
+    assert result.returncode == 0, result.stderr
+    assert "Traceback" not in result.stderr, result.stderr
+    return json.loads(result.stdout.splitlines()[-1])
+
+
+def _spans_by_name(results: dict[str, Any]) -> dict[str, dict[str, Any]]:
+    return {span["name"]: span for span in results["spans"]}
+
+
+def test_app_spans_are_exported_by_the_vendored_sdk() -> None:
+    results = _run(
+        """
+        from opentelemetry import trace
+
+        results["provider"] = type(trace.get_tracer_provider()).__name__
+        tracer = trace.get_tracer("app")
+        with tracer.start_as_current_span("parent", kind=trace.SpanKind.SERVER, attributes={"a": 1}) as parent:
+            results["is_app_span"] = isinstance(trace.get_current_span(), trace.Span)
+            results["current_is_parent"] = trace.get_current_span() == parent
+            with tracer.start_as_current_span("child", links=[trace.Link(parent.get_span_context(), {"l": "v"})]) as child:
+                child.set_attribute("b", "x")
+                child.add_event("event", {"c": 2.5})
+                child.set_status(trace.Status(trace.StatusCode.ERROR, "failed"))
+        span = tracer.start_span("status-code")
+        span.set_status(trace.StatusCode.OK)
+        span.end()
+        """
+    )
+
+    spans = _spans_by_name(results)
+    assert results["provider"] == "BridgeTracerProvider"
+    assert results["is_app_span"] is True
+    assert results["current_is_parent"] is True
+    parent, child = spans["parent"], spans["child"]
+    assert parent["kind"] == "SERVER"
+    assert parent["parent_id"] is None
+    assert parent["attributes"] == {"a": 1}
+    assert child["kind"] == "INTERNAL"
+    assert child["trace_id"] == parent["trace_id"]
+    assert child["parent_id"] == parent["span_id"]
+    assert child["attributes"] == {"b": "x"}
+    assert child["events"] == [["event", {"c": 2.5}]]
+    assert child["links"] == [[parent["span_id"], {"l": "v"}]]
+    assert child["status"] == ["ERROR", "failed"]
+    assert spans["status-code"]["status"] == ["OK", None]
+
+
+def test_exception_in_app_span() -> None:
+    results = _run(
+        """
+        from opentelemetry import trace
+
+        tracer = trace.get_tracer("app")
+        try:
+            with tracer.start_as_current_span("failing"):
+                raise ValueError("boom")
+        except ValueError:
+            pass
+        try:
+            with tracer.start_span("failing-span"):
+                raise KeyError("key")
+        except KeyError:
+            pass
+        """
+    )
+
+    spans = _spans_by_name(results)
+    for name, description in (("failing", "ValueError: boom"), ("failing-span", "KeyError: 'key'")):
+        assert spans[name]["status"] == ["ERROR", description]
+        [(event_name, attributes)] = spans[name]["events"]
+        assert event_name == "exception"
+        assert attributes["exception.type"] in ("ValueError", "KeyError")
+
+
+def test_vendored_and_app_spans_parent_each_other() -> None:
+    results = _run(
+        """
+        from opentelemetry import trace
+
+        tracer = trace.get_tracer("app")
+        agent_tracer = agent_trace.get_tracer("instrumentation")
+        with tracer.start_as_current_span("app-outer"):
+            results["agent_current"] = agent_trace.get_current_span().name
+            with agent_tracer.start_as_current_span("instrumentation"):
+                with tracer.start_as_current_span("app-inner"):
+                    pass
+        """
+    )
+
+    spans = _spans_by_name(results)
+    assert results["agent_current"] == "app-outer"
+    assert spans["instrumentation"]["parent_id"] == spans["app-outer"]["span_id"]
+    assert spans["app-inner"]["parent_id"] == spans["instrumentation"]["span_id"]
+
+
+def test_explicit_parent_context() -> None:
+    results = _run(
+        """
+        from opentelemetry import trace
+
+        tracer = trace.get_tracer("app")
+        root = tracer.start_span("root")
+        child = tracer.start_span("child", context=trace.set_span_in_context(root))
+        child.end()
+        root.end()
+        orphan = tracer.start_span("orphan", context=trace.set_span_in_context(trace.INVALID_SPAN))
+        orphan.end()
+        """
+    )
+
+    spans = _spans_by_name(results)
+    assert spans["child"]["parent_id"] == spans["root"]["span_id"]
+    assert spans["orphan"]["parent_id"] is None
+
+
+def test_app_propagators_use_bridged_spans() -> None:
+    trace_id = 0x0AF7651916CD43DD8448EB211C80319C
+    results = _run(
+        """
+        from opentelemetry import propagate, trace
+
+        tracer = trace.get_tracer("app")
+        context = propagate.extract({"traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"})
+        with tracer.start_as_current_span("remote-child", context=context) as span:
+            carrier = {}
+            propagate.inject(carrier)
+            results["traceparent"] = carrier["traceparent"]
+            results["span_id"] = span.get_span_context().span_id
+        """
+    )
+
+    [span] = results["spans"]
+    assert span["trace_id"] == trace_id
+    assert span["parent_id"] == 0xB7AD6B7169203331
+    assert results["traceparent"].startswith(f"00-{trace_id:032x}-{results['span_id']:016x}-")
+
+
+def test_extracted_span_round_trips() -> None:
+    results = _run(
+        """
+        from opentelemetry import context, propagate, trace
+
+        extracted = trace.get_current_span(propagate.extract({"traceparent": "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"}))
+        token = context.attach(trace.set_span_in_context(extracted))
+        results["same_span"] = trace.get_current_span() is extracted
+        context.detach(token)
+        results["detached"] = trace.get_current_span() is trace.INVALID_SPAN
+        """
+    )
+
+    assert results["same_span"] is True
+    assert results["detached"] is True
+
+
+def test_baggage_and_suppression_are_shared() -> None:
+    results = _run(
+        """
+        from opentelemetry import baggage, context
+        from opentelemetry.agent._vendor.opentelemetry import baggage as agent_baggage
+        from opentelemetry.agent._vendor.opentelemetry import context as agent_context
+        from opentelemetry.agent._vendor.opentelemetry.instrumentation.utils import is_instrumentation_enabled
+
+        token = context.attach(baggage.set_baggage("app", "1"))
+        results["agent_baggage"] = agent_baggage.get_baggage("app")
+        agent_token = agent_context.attach(agent_baggage.set_baggage("agent", "2"))
+        results["app_baggage"] = dict(baggage.get_all())
+        agent_context.detach(agent_token)
+        context.detach(token)
+
+        token = context.attach(context.set_value(context._SUPPRESS_INSTRUMENTATION_KEY, True))
+        results["suppressed"] = not is_instrumentation_enabled()
+        context.detach(token)
+        results["enabled"] = is_instrumentation_enabled()
+        """
+    )
+
+    assert results["agent_baggage"] == "1"
+    assert results["app_baggage"] == {"app": "1", "agent": "2"}
+    assert results["suppressed"] is True
+    assert results["enabled"] is True
+
+
+def test_app_provider_set_first_is_kept() -> None:
+    results = _run(
+        """
+        from opentelemetry import trace
+
+        trace.set_tracer_provider(trace.NoOpTracerProvider())
+        with trace.get_tracer("app").start_as_current_span("not-bridged"):
+            pass
+        results["provider"] = type(trace.get_tracer_provider()).__name__
+        """
+    )
+
+    assert results["provider"] == "NoOpTracerProvider"
+    assert results["spans"] == []
+
+
+def test_environment_is_released_once_loaded() -> None:
+    results = _run(
+        f"""
+        import os
+        from opentelemetry import context, trace
+
+        context.get_current()
+        trace.get_tracer_provider()
+        results["environment"] = [os.environ.get({OTEL_PYTHON_CONTEXT!r}), os.environ.get({OTEL_PYTHON_TRACER_PROVIDER!r})]
+        """
+    )
+
+    assert results["environment"] == [None, None]
+
+
+def test_vendored_api_ignores_the_bridge_selection() -> None:
+    results = _run(
+        """
+        import json
+        from opentelemetry.agent._vendor.opentelemetry import context, trace
+
+        print(json.dumps({
+            "runtime_context": type(context._RUNTIME_CONTEXT).__name__,
+            "provider": type(trace.get_tracer_provider()).__name__,
+        }))
+        """,
+        prelude=False,
+    )
+
+    assert results == {"runtime_context": "ContextVarsRuntimeContext", "provider": "ProxyTracerProvider"}
+
+
+_SITECUSTOMIZE_DIR = (
+    Path(__file__).parents[1] / "src/opentelemetry/agent/_vendor/opentelemetry/instrumentation/auto_instrumentation"
+)
+
+
+@pytest.mark.parametrize(
+    ("environment", "expected"),
+    [
+        ({}, [_AGENT_BRIDGE, _AGENT_BRIDGE]),
+        ({OTEL_PYTHON_CONTEXT: "contextvars_context"}, ["contextvars_context", _AGENT_BRIDGE]),
+    ],
+)
+def test_sitecustomize_selects_the_bridge(environment: dict[str, str], expected: list[str]) -> None:
+    results = _run(
+        f"""
+        import json, os
+
+        print(json.dumps([os.environ.get({OTEL_PYTHON_CONTEXT!r}), os.environ.get({OTEL_PYTHON_TRACER_PROVIDER!r})]))
+        """,
+        environment={
+            "PYTHONPATH": str(_SITECUSTOMIZE_DIR),
+            "OTEL_TRACES_EXPORTER": "none",
+            "OTEL_METRICS_EXPORTER": "none",
+            "OTEL_LOGS_EXPORTER": "none",
+        }
+        | environment,
+        prelude=False,
+    )
+
+    assert results == expected
diff --git a/tox.ini b/tox.ini
index a9726bc0837..b89b87dffbd 100644
--- a/tox.ini
+++ b/tox.ini
@@ -355,6 +355,9 @@ envlist =
     pypy3-test-util-http
     lint-util-http
 
+    ; opentelemetry-agent
+    py3{10,11,12,13,14}-test-agent-{oldest,latest}
+
     ; opentelemetry-exporter-credential-provider-gcp
     py3{10,11,12,13,14}-test-exporter-credential-provider-gcp
     lint-exporter-credential-provider-gcp
@@ -759,6 +762,12 @@ deps =
   util-http: -r {toxinidir}/util/opentelemetry-util-http/test-requirements.txt
   util-http: {toxinidir}/util/opentelemetry-util-http
 
+  ; The application's opentelemetry-api, bridged to the agent's vendored SDK.
+  agent-oldest: -r {toxinidir}/agent/opentelemetry-agent/tests/requirements.oldest.txt
+  agent-latest: {[testenv]test_deps}
+  agent-latest: -r {toxinidir}/agent/opentelemetry-agent/tests/requirements.latest.txt
+  agent: {toxinidir}/agent/opentelemetry-agent
+
   exporter-credential-provider-gcp: -r {toxinidir}/exporter/opentelemetry-exporter-credential-provider-gcp/test-requirements.txt
   exporter-credential-provider-gcp: {toxinidir}/exporter/opentelemetry-exporter-credential-provider-gcp
 
@@ -968,6 +977,8 @@ commands =
   test-util-http: pytest {toxinidir}/util/opentelemetry-util-http/tests {posargs}
   lint-util-http: sh -c "cd util && pylint --rcfile ../.pylintrc opentelemetry-util-http"
 
+  test-agent: pytest {toxinidir}/agent/opentelemetry-agent/tests {posargs}
+
   test-exporter-credential-provider-gcp: pytest {toxinidir}/exporter/opentelemetry-exporter-credential-provider-gcp/tests {posargs}
   lint-exporter-credential-provider-gcp: sh -c "cd exporter && pylint --rcfile ../.pylintrc opentelemetry-exporter-credential-provider-gcp"